summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
Diffstat (limited to 'linux')
-rw-r--r--linux/collie-kernel-24-8_2.4.18-rmk7-pxa3-embedix20030509.bb10
-rw-r--r--linux/collie-kernel-32-0_2.4.18-rmk7-pxa3-embedix20030509.bb10
-rw-r--r--linux/collie-kernel-32-32_2.4.18-rmk7-pxa3-embedix20030509.bb10
-rw-r--r--linux/collie-kernel-40-24_2.4.18-rmk7-pxa3-embedix20030509.bb10
-rw-r--r--linux/collie-kernel-48-16_2.4.18-rmk7-pxa3-embedix20030509.bb10
-rw-r--r--linux/collie-kernel-58-6_2.4.18-rmk7-pxa3-embedix20030509.bb10
-rw-r--r--linux/collie-kernel-64-0_2.4.18-rmk7-pxa3-embedix20030509.bb10
-rw-r--r--linux/collie-kernel-all_2.4.18-rmk7-pxa3-embedix20030509.bb0
-rw-r--r--linux/files/ipaq-hal.init14
-rw-r--r--linux/files/linux-2.4-cpufreq.patch20
-rw-r--r--linux/files/linux-2.4-no-short-loads.patch18
-rw-r--r--linux/files/linux-2.4.18-list_move.patch32
-rw-r--r--linux/files/mipv6-1.1-v2.4.25.patch19832
-rw-r--r--linux/gumstix-2.6.5-gnalm1-gum0/defconfig777
-rw-r--r--linux/gumstix-2.6.5-gnalm1-gum0/linux-2.6.5-gnalm1.patch20991
-rw-r--r--linux/gumstix_2.6.5-gnalm1-gum0.bb0
-rw-r--r--linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh36.12/defconfig-ipaqpxa1575
-rw-r--r--linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh36.12/ipsec.patch1446
-rw-r--r--linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh36.13/defconfig-ipaqpxa1577
-rw-r--r--linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh36.14/defconfig-ipaqpxa1578
-rw-r--r--linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh37.1/defconfig-ipaqpxa1578
-rw-r--r--linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh37.4/defconfig-ipaqpxa0
-rw-r--r--linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh37.4/mmc_h5400.patch0
-rw-r--r--linux/handhelds-pxa-2.6/defconfig1328
-rw-r--r--linux/handhelds-pxa-2.6/defconfig-ipaq-pxa-2.61304
-rw-r--r--linux/handhelds-pxa-2.6/defconfig-ipaq-pxa-2.6_2.6.8.1-hh01382
-rw-r--r--linux/handhelds-pxa-2.6_2.6.6-hh0.bb0
-rw-r--r--linux/handhelds-pxa-2.6_2.6.8.1-hh0.bb0
-rw-r--r--linux/handhelds-pxa-2.6_cvs.bb0
-rw-r--r--linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh36.12.bb0
-rw-r--r--linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh36.13.bb0
-rw-r--r--linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh36.14.bb0
-rw-r--r--linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh37.1.bb0
-rw-r--r--linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh37.4.bb0
-rw-r--r--linux/handhelds-sa-2.4.19-rmk6-pxa1-hh36.12/defconfig-ipaqsa1505
-rw-r--r--linux/handhelds-sa-2.4.19-rmk6-pxa1-hh36.12/disable-pcmcia-probe.patch17
-rw-r--r--linux/handhelds-sa-2.4.19-rmk6-pxa1-hh36.12/ipsec.patch1446
-rw-r--r--linux/handhelds-sa-2.4.19-rmk6-pxa1-hh36.12/mkdep.patch16
-rw-r--r--linux/handhelds-sa-2.4.19-rmk6-pxa1-hh37.1/defconfig-ipaqsa1508
-rw-r--r--linux/handhelds-sa-2.4.19-rmk6-pxa1-hh37.4/defconfig-ipaqsa0
-rw-r--r--linux/handhelds-sa-2.6/defconfig-jornada56x877
-rw-r--r--linux/handhelds-sa-2.6_cvs.bb0
-rw-r--r--linux/handhelds-sa_2.4.19-rmk6-pxa1-hh36.12.bb0
-rw-r--r--linux/handhelds-sa_2.4.19-rmk6-pxa1-hh37.1.bb0
-rw-r--r--linux/handhelds-sa_2.4.19-rmk6-pxa1-hh37.4.bb0
-rw-r--r--linux/ipod_2.4.24-ipod0.bb0
-rw-r--r--linux/linux-bast-2.4.25-vrs1-bast1/defconfig1115
-rw-r--r--linux/linux-bast-2.4.25-vrs1-bast1/mkdep.patch16
-rw-r--r--linux/linux-bast_2.4.25-vrs1-bast1.bb0
-rw-r--r--linux/linux-colinux-2.4.28/colinux-0.6.1.patch0
-rw-r--r--linux/linux-colinux-2.4.28/defconfig0
-rw-r--r--linux/linux-colinux-2.4.28/gcc-registerparanoia.patch0
-rw-r--r--linux/linux-colinux-2.4.28/gcc340-fixes-v2.4.26-try3.patch0
-rw-r--r--linux/linux-colinux-2.4.28/linux-2.4.24-attribute-used.patch0
-rw-r--r--linux/linux-colinux-2.4.28/nofpu.patch0
-rw-r--r--linux/linux-colinux-2.4.28/shortloadbytes.patch0
-rw-r--r--linux/linux-colinux_2.4.28.bb0
-rw-r--r--linux/linux-epia-2.6.8.1/epia_defconfig1480
-rw-r--r--linux/linux-epia_2.6.8.1.bb0
-rw-r--r--linux/linux-mtx-1-2.4.24/01-mtd-2004-01-27.diff51462
-rw-r--r--linux/linux-mtx-1-2.4.24/02-mtd-mtx-1-map.diff248
-rw-r--r--linux/linux-mtx-1-2.4.24/03-mtd-erase-compiler-bug.diff21
-rw-r--r--linux/linux-mtx-1-2.4.24/04-zboot-2.4.24.patch5286
-rw-r--r--linux/linux-mtx-1-2.4.24/05-zboot-cflags.diff15
-rw-r--r--linux/linux-mtx-1-2.4.24/06-zboot-mtx.diff27
-rw-r--r--linux/linux-mtx-1-2.4.24/07-zimage-flash-bin.patch11
-rw-r--r--linux/linux-mtx-1-2.4.24/08-usb-nonpci-2.4.24.patch173
-rw-r--r--linux/linux-mtx-1-2.4.24/09-iw-max-spy-32.diff11
-rw-r--r--linux/linux-mtx-1-2.4.24/10-mtx-pci-slots.diff23
-rw-r--r--linux/linux-mtx-1-2.4.24/11-mtx-extraversion.diff11
-rw-r--r--linux/linux-mtx-1-2.4.24/12-openswan-2.2.0-nat-t.diff143
-rw-r--r--linux/linux-mtx-1-2.4.24/13-openswan-2.2.0.patch61573
-rw-r--r--linux/linux-mtx-1-2.4.24/14-au1000-eth-vlan.diff10
-rw-r--r--linux/linux-mtx-1-2.4.24/15-mtd-proc-partition-rw.diff173
-rw-r--r--linux/linux-mtx-1-2.4.24/defconfig-mtx-11176
-rw-r--r--linux/linux-mtx-1-2.4.27/01-mtd-2004-01-27.diff51503
-rw-r--r--linux/linux-mtx-1-2.4.27/02-mtd-mtx-1-map.diff248
-rw-r--r--linux/linux-mtx-1-2.4.27/03-mtd-erase-compiler-bug.diff21
-rw-r--r--linux/linux-mtx-1-2.4.27/04-mtx-1-board-reset.diff15
-rw-r--r--linux/linux-mtx-1-2.4.27/05-mtx-1-pci-irq.diff18
-rw-r--r--linux/linux-mtx-1-2.4.27/06-zboot-2.4.26.patch5308
-rw-r--r--linux/linux-mtx-1-2.4.27/07-zboot-zimage-flash-bin.diff11
-rw-r--r--linux/linux-mtx-1-2.4.27/08-usb-nonpci-2.4.24.patch3185
-rw-r--r--linux/linux-mtx-1-2.4.27/09-au1000-eth-vlan.diff10
-rw-r--r--linux/linux-mtx-1-2.4.27/10-iw-max-spy-32.diff11
-rw-r--r--linux/linux-mtx-1-2.4.27/11-mtd-proc-partition-rw.diff173
-rw-r--r--linux/linux-mtx-1-2.4.27/12-openswan-2.2.0-nat-t.diff143
-rw-r--r--linux/linux-mtx-1-2.4.27/13-openswan-2.2.0.patch61573
-rw-r--r--linux/linux-mtx-1-2.4.27/14-au1000-eth-link-beat.diff64
-rw-r--r--linux/linux-mtx-1-2.4.27/15-au1000-pci-fixup-non-coherent-pre-ac.diff0
-rw-r--r--linux/linux-mtx-1-2.4.27/defconfig-mtx-11200
-rw-r--r--linux/linux-mtx-1-2.4.27/mtx-1-board-reset.diff15
-rw-r--r--linux/linux-mtx-1-2.4.27/zimage-flash-bin.patch11
-rw-r--r--linux/linux-mtx-1_2.4.24.bb0
-rw-r--r--linux/linux-mtx-1_2.4.27.bb0
-rw-r--r--linux/linux-netvista-2.4.27/netvista_defconfig0
-rw-r--r--linux/linux-netvista_2.4.27.bb0
-rw-r--r--linux/linux-omap-2.6-2.6.9-omap1/omap1610h2/defconfig840
-rw-r--r--linux/linux-omap-2.6-2.6.9-omap1/schedstats-arm.patch26
-rw-r--r--linux/linux-omap-2.6_2.6.9-omap1.bb0
-rw-r--r--linux/linux-sun4cdm-2.4.26/defconfig473
-rw-r--r--linux/linux-sun4cdm-2.6.8.1/sun4c_defconfig689
-rw-r--r--linux/linux-sun4cdm_2.4.26.bb0
-rw-r--r--linux/linux-sun4cdm_2.6.8.1.bb0
-rw-r--r--linux/linux-xxs1500-2.4.21/Makefile756
-rw-r--r--linux/linux-xxs1500-2.4.21/defconfig-xxs15001199
-rw-r--r--linux/linux-xxs1500-2.4.21/zboot-Makefile-flags.diff11
-rw-r--r--linux/linux-xxs1500_2.4.21.bb0
-rw-r--r--linux/mnci-ramses-2.4.21-rmk2-pxa1.bb0
-rw-r--r--linux/mnci-ramses-2.4.21-rmk2-pxa1/diff-2.4.21-rmk2-pxa1.gz0
-rw-r--r--linux/mnci-ramses-2.4.21-rmk2-pxa1/mnci-combined.patch19914
-rw-r--r--linux/mnci-ramses_2.4.21-rmk2-pxa1.bb0
-rw-r--r--linux/montavista-sa-2.4.17-mvl21/apm-hh-merge.patch561
-rw-r--r--linux/montavista-sa-2.4.17-mvl21/beagle-sound.patch57
-rw-r--r--linux/montavista-sa-2.4.17-mvl21/defconfig-beagle1152
-rw-r--r--linux/montavista-sa-2.4.17-mvl21/disable-pcmcia-probe.patch17
-rw-r--r--linux/montavista-sa-2.4.17-mvl21/flash-for-beagle-iii.patch21
-rw-r--r--linux/montavista-sa-2.4.17-mvl21/iw240_we15-6.diff399
-rw-r--r--linux/montavista-sa-2.4.17-mvl21/iw_handlers.w13-5.diff1513
-rw-r--r--linux/montavista-sa-2.4.17-mvl21/iw_handlers.w14-5.diff838
-rw-r--r--linux/montavista-sa-2.4.17-mvl21/machine_name.patch19
-rw-r--r--linux/montavista-sa-2.4.17-mvl21/mkdep.patch16
-rw-r--r--linux/montavista-sa-2.4.17-mvl21/opie-logo.patch10936
-rw-r--r--linux/montavista-sa-2.4.17-mvl21/pcmcia_preempt.patch180
-rw-r--r--linux/montavista-sa-2.4.17-mvl21/remove-montavista-init-stupidity.patch23
-rw-r--r--linux/montavista-sa-2.4.17-mvl21/ucb1x_kill-zombie.patch15
-rw-r--r--linux/montavista-sa_2.4.17-mvl21.bb0
-rw-r--r--linux/nslu2-linksys-kernel-2.4.22/config-fixes.patch0
-rw-r--r--linux/nslu2-linksys-kernel-2.4.22/gcc-registerparanoia.patch0
-rw-r--r--linux/nslu2-linksys-kernel-2.4.22/gcc3-userfuncs.patch0
-rw-r--r--linux/nslu2-linksys-kernel-2.4.22/linux-2.4.24-attribute-used.patch0
-rw-r--r--linux/nslu2-linksys-kernel-2.4.22/nofpu.patch0
-rw-r--r--linux/nslu2-linksys-kernel-2.4.22/nslu2/defconfig0
-rw-r--r--linux/nslu2-linksys-kernel-2.4.22/short_loadbytes.patch0
-rw-r--r--linux/nslu2-linksys-kernel_2.4.22.bb50
-rw-r--r--linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/2.4.25-vrs2-pxa1-jpm1.patch8760
-rw-r--r--linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/2.4.25-vrs2-pxa1.patch39937
-rw-r--r--linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/2.4.25-vrs2.patch86979
-rw-r--r--linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/defconfig-simpad1285
-rw-r--r--linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/disable-pcmcia-probe.patch17
-rw-r--r--linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/keymap.patch0
-rw-r--r--linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/mkdep.patch16
-rw-r--r--linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/mppe-20040216.patch1225
-rw-r--r--linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/scrolling-area.patch18
-rw-r--r--linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-apm.diff799
-rw-r--r--linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-backlight-if.diff97
-rw-r--r--linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-pm-updates.patch47
-rw-r--r--linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-switches-input.diff126
-rw-r--r--linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-switches-input2.diff52
-rw-r--r--linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-ts-noninput.diff11
-rw-r--r--linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/sound-volume-reversed.patch16
-rw-r--r--linux/opensimpad-64+0_2.4.25-vrs2-pxa1-jpm1.bb5
-rw-r--r--linux/opensimpad_2.4.25-vrs2-pxa1-jpm1.bb70
-rw-r--r--linux/openslug-kernel-2.6.7/arm-Makefile.patch0
-rw-r--r--linux/openslug-kernel-2.6.7/arm-timer.patch0
-rw-r--r--linux/openslug-kernel-2.6.7/defconfig0
-rw-r--r--linux/openslug-kernel-2.6.7/ipx4xx-pci.patch0
-rw-r--r--linux/openslug-kernel-2.6.7/x1205-rtc.patch0
-rw-r--r--linux/openslug-kernel-2.6.9/defconfig1112
-rw-r--r--linux/openslug-kernel-2.6.9/nslu2-io.c748
-rw-r--r--linux/openslug-kernel-2.6.9/nslu2-part.c120
-rw-r--r--linux/openslug-kernel-2.6.9/nslu2-pci.c87
-rw-r--r--linux/openslug-kernel-2.6.9/nslu2-setup.c132
-rw-r--r--linux/openslug-kernel-2.6.9/nslu2.h43
-rw-r--r--linux/openslug-kernel-2.6.9/nslu2_2.6.9.patch312
-rw-r--r--linux/openslug-kernel-2.6.9/x1205-rtc.c548
-rw-r--r--linux/openslug-kernel_2.6.7.bb0
-rw-r--r--linux/openslug-kernel_2.6.9.bb58
-rw-r--r--linux/openzaurus-2.6.10-rc2/defconfig-collie0
-rw-r--r--linux/openzaurus-2.6.10-rc2/defconfig-husky893
-rw-r--r--linux/openzaurus-2.6.10-rc2/defconfig-poodle0
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/1764-1.patch16
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bluecard_cs.patch11
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bluetooth-2.4.18-mh11.patch31393
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bluetooth-2.4.18-mh15.patch32759
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bt950_cs.patch1174
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/buffered-fbmem.patch19
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/compile.patch14
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/corgi-fbcon-logo.patch281
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-corgi1304
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-husky1304
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-poodle1110
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-shepherd1303
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-tosa1377
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/deviceinfo.patch26
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/disable-pcmcia-probe.patch17
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/enable-sysrq.patch61
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/idecs.patch77
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/initsh.patch14
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/irda-qos.patch108
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/iw240_we15-6.diff399
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/iw_handlers.w13-5.diff1513
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/iw_handlers.w14-5.diff838
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/keyboard-ctrl+alt.patch79
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/keymap-more-sane.patch23
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/logo.patch2598
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/mkdep.patch16
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/module_licence.patch96
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/piro.patch75444
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/sharpsl_battery.patch346
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/smallfonts.diff2453
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/swap-performance.patch19
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/tosa-power-key-off.patch127
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/tosa_map.patch889
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/tosa_ts.patch207
-rw-r--r--linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/usb-storage.patch3433
-rw-r--r--linux/openzaurus-pxa_2.4.18-rmk7-pxa3-embedix20031107.bb104
-rw-r--r--linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/1764-1.patch16
-rw-r--r--linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/battery.patch326
-rw-r--r--linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/bluetooth-2.4.18-mh15.patch32759
-rw-r--r--linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/bluetooth-patch-2.4.18-mh9.diff30831
-rw-r--r--linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/cacko.patch0
-rw-r--r--linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/defconfig-collie1283
-rw-r--r--linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/disable-pcmcia-probe.patch17
-rw-r--r--linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/idecs.patch77
-rw-r--r--linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/initsh.patch14
-rw-r--r--linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/iw240_we15-6.diff399
-rw-r--r--linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/iw_handlers.w13-5.diff1513
-rw-r--r--linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/iw_handlers.w14-5.diff838
-rw-r--r--linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/keymap-more-sane.patch19
-rw-r--r--linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/logo.patch2598
-rw-r--r--linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/mkdep.patch16
-rw-r--r--linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/module_licence.patch81
-rw-r--r--linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/sound-2.4.18r2.patch5602
-rw-r--r--linux/openzaurus-sa_2.4.18-rmk7-pxa3-embedix20030509.bb95
-rw-r--r--linux/openzaurus_2.6.10-rc2.bb0
-rw-r--r--linux/unslung-able-kernel_2.3r25.bb8
-rw-r--r--linux/unslung-kernel-2.3r25/able/defconfig976
-rw-r--r--linux/unslung-kernel-2.3r25/defconfig973
-rw-r--r--linux/unslung-kernel-2.3r25/ext3flash-on-disk1.patch41
-rw-r--r--linux/unslung-kernel-2.3r25/ext3flash.patch0
-rw-r--r--linux/unslung-kernel-2.3r25/gl811e.patch0
-rw-r--r--linux/unslung-kernel-2.3r25/limit1gb.patch0
-rw-r--r--linux/unslung-kernel-2.3r25/missing-usb-ioctls.patch0
-rw-r--r--linux/unslung-kernel-2.3r25/usbnet.patch0
-rw-r--r--linux/unslung-standard-kernel_2.3r25.bb29
236 files changed, 0 insertions, 728055 deletions
diff --git a/linux/collie-kernel-24-8_2.4.18-rmk7-pxa3-embedix20030509.bb b/linux/collie-kernel-24-8_2.4.18-rmk7-pxa3-embedix20030509.bb
deleted file mode 100644
index 02b68a038f..0000000000
--- a/linux/collie-kernel-24-8_2.4.18-rmk7-pxa3-embedix20030509.bb
+++ /dev/null
@@ -1,10 +0,0 @@
-SECTION = "kernel"
-COLLIE_MEMORY_SIZE=24
-COLLIE_RAMDISK_SIZE=8
-
-include ../linux/openzaurus-sa_2.4.18-rmk7-pxa3-embedix20030509.bb
-
-do_deploy_append() {
- ! test -d ${DEPLOY_DIR}/images/collie/kernel && mkdir -p ${DEPLOY_DIR}/images/collie/kernel
- mv ${DEPLOY_DIR}/images/${KERNEL_IMAGETYPE}-${DATETIME} ${DEPLOY_DIR}/images/collie/kernel/${KERNEL_IMAGETYPE}_collie-${COLLIE_MEMORY_SIZE}-${COLLIE_RAMDISK_SIZE}
-}
diff --git a/linux/collie-kernel-32-0_2.4.18-rmk7-pxa3-embedix20030509.bb b/linux/collie-kernel-32-0_2.4.18-rmk7-pxa3-embedix20030509.bb
deleted file mode 100644
index 1bd0519ce0..0000000000
--- a/linux/collie-kernel-32-0_2.4.18-rmk7-pxa3-embedix20030509.bb
+++ /dev/null
@@ -1,10 +0,0 @@
-SECTION = "kernel"
-COLLIE_MEMORY_SIZE=32
-COLLIE_RAMDISK_SIZE=0
-
-include ../linux/openzaurus-sa_2.4.18-rmk7-pxa3-embedix20030509.bb
-
-do_deploy_append() {
- ! test -d ${DEPLOY_DIR}/images/collie/kernel && mkdir -p ${DEPLOY_DIR}/images/collie/kernel
- mv ${DEPLOY_DIR}/images/${KERNEL_IMAGETYPE}-${DATETIME} ${DEPLOY_DIR}/images/collie/kernel/${KERNEL_IMAGETYPE}_collie-${COLLIE_MEMORY_SIZE}-${COLLIE_RAMDISK_SIZE}
-}
diff --git a/linux/collie-kernel-32-32_2.4.18-rmk7-pxa3-embedix20030509.bb b/linux/collie-kernel-32-32_2.4.18-rmk7-pxa3-embedix20030509.bb
deleted file mode 100644
index a254eb4a6e..0000000000
--- a/linux/collie-kernel-32-32_2.4.18-rmk7-pxa3-embedix20030509.bb
+++ /dev/null
@@ -1,10 +0,0 @@
-SECTION = "kernel"
-COLLIE_MEMORY_SIZE=32
-COLLIE_RAMDISK_SIZE=32
-
-include ../linux/openzaurus-sa_2.4.18-rmk7-pxa3-embedix20030509.bb
-
-do_deploy_append() {
- ! test -d ${DEPLOY_DIR}/images/collie/kernel && mkdir -p ${DEPLOY_DIR}/images/collie/kernel
- mv ${DEPLOY_DIR}/images/${KERNEL_IMAGETYPE}-${DATETIME} ${DEPLOY_DIR}/images/collie/kernel/${KERNEL_IMAGETYPE}_collie-${COLLIE_MEMORY_SIZE}-${COLLIE_RAMDISK_SIZE}
-}
diff --git a/linux/collie-kernel-40-24_2.4.18-rmk7-pxa3-embedix20030509.bb b/linux/collie-kernel-40-24_2.4.18-rmk7-pxa3-embedix20030509.bb
deleted file mode 100644
index 2e3a9676be..0000000000
--- a/linux/collie-kernel-40-24_2.4.18-rmk7-pxa3-embedix20030509.bb
+++ /dev/null
@@ -1,10 +0,0 @@
-SECTION = "kernel"
-COLLIE_MEMORY_SIZE=40
-COLLIE_RAMDISK_SIZE=24
-
-include ../linux/openzaurus-sa_2.4.18-rmk7-pxa3-embedix20030509.bb
-
-do_deploy_append() {
- ! test -d ${DEPLOY_DIR}/images/collie/kernel && mkdir -p ${DEPLOY_DIR}/images/collie/kernel
- mv ${DEPLOY_DIR}/images/${KERNEL_IMAGETYPE}-${DATETIME} ${DEPLOY_DIR}/images/collie/kernel/${KERNEL_IMAGETYPE}_collie-${COLLIE_MEMORY_SIZE}-${COLLIE_RAMDISK_SIZE}
-}
diff --git a/linux/collie-kernel-48-16_2.4.18-rmk7-pxa3-embedix20030509.bb b/linux/collie-kernel-48-16_2.4.18-rmk7-pxa3-embedix20030509.bb
deleted file mode 100644
index ea6981f4af..0000000000
--- a/linux/collie-kernel-48-16_2.4.18-rmk7-pxa3-embedix20030509.bb
+++ /dev/null
@@ -1,10 +0,0 @@
-SECTION = "kernel"
-COLLIE_MEMORY_SIZE=48
-COLLIE_RAMDISK_SIZE=16
-
-include ../linux/openzaurus-sa_2.4.18-rmk7-pxa3-embedix20030509.bb
-
-do_deploy_append() {
- ! test -d ${DEPLOY_DIR}/images/collie/kernel && mkdir -p ${DEPLOY_DIR}/images/collie/kernel
- mv ${DEPLOY_DIR}/images/${KERNEL_IMAGETYPE}-${DATETIME} ${DEPLOY_DIR}/images/collie/kernel/${KERNEL_IMAGETYPE}_collie-${COLLIE_MEMORY_SIZE}-${COLLIE_RAMDISK_SIZE}
-}
diff --git a/linux/collie-kernel-58-6_2.4.18-rmk7-pxa3-embedix20030509.bb b/linux/collie-kernel-58-6_2.4.18-rmk7-pxa3-embedix20030509.bb
deleted file mode 100644
index c25f61bf42..0000000000
--- a/linux/collie-kernel-58-6_2.4.18-rmk7-pxa3-embedix20030509.bb
+++ /dev/null
@@ -1,10 +0,0 @@
-SECTION = "kernel"
-COLLIE_MEMORY_SIZE=58
-COLLIE_RAMDISK_SIZE=6
-
-include ../linux/openzaurus-sa_2.4.18-rmk7-pxa3-embedix20030509.bb
-
-do_deploy_append() {
- ! test -d ${DEPLOY_DIR}/images/collie/kernel && mkdir -p ${DEPLOY_DIR}/images/collie/kernel
- mv ${DEPLOY_DIR}/images/${KERNEL_IMAGETYPE}-${DATETIME} ${DEPLOY_DIR}/images/collie/kernel/${KERNEL_IMAGETYPE}_collie-${COLLIE_MEMORY_SIZE}-${COLLIE_RAMDISK_SIZE}
-}
diff --git a/linux/collie-kernel-64-0_2.4.18-rmk7-pxa3-embedix20030509.bb b/linux/collie-kernel-64-0_2.4.18-rmk7-pxa3-embedix20030509.bb
deleted file mode 100644
index a91a145d47..0000000000
--- a/linux/collie-kernel-64-0_2.4.18-rmk7-pxa3-embedix20030509.bb
+++ /dev/null
@@ -1,10 +0,0 @@
-SECTION = "kernel"
-COLLIE_MEMORY_SIZE=64
-COLLIE_RAMDISK_SIZE=0
-
-include ../linux/openzaurus-sa_2.4.18-rmk7-pxa3-embedix20030509.bb
-
-do_deploy_append() {
- ! test -d ${DEPLOY_DIR}/images/collie/kernel && mkdir -p ${DEPLOY_DIR}/images/collie/kernel
- mv ${DEPLOY_DIR}/images/${KERNEL_IMAGETYPE}-${DATETIME} ${DEPLOY_DIR}/images/collie/kernel/${KERNEL_IMAGETYPE}_collie-${COLLIE_MEMORY_SIZE}-${COLLIE_RAMDISK_SIZE}
-}
diff --git a/linux/collie-kernel-all_2.4.18-rmk7-pxa3-embedix20030509.bb b/linux/collie-kernel-all_2.4.18-rmk7-pxa3-embedix20030509.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/collie-kernel-all_2.4.18-rmk7-pxa3-embedix20030509.bb
+++ /dev/null
diff --git a/linux/files/ipaq-hal.init b/linux/files/ipaq-hal.init
deleted file mode 100644
index 4efb52ec97..0000000000
--- a/linux/files/ipaq-hal.init
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-
-# make sure update-modules has been run
-# since the calls below depend on aliases...
-if [ ! -f /etc/modules.conf ]; then
- update-modules || true
-fi
-
-modprobe ipaq_hal || exit 0
-
-if [ -d /proc/hal ]; then
- model=`cat /proc/hal/model`
- modprobe ipaq_hal_$model
-fi
diff --git a/linux/files/linux-2.4-cpufreq.patch b/linux/files/linux-2.4-cpufreq.patch
deleted file mode 100644
index c3526bb30d..0000000000
--- a/linux/files/linux-2.4-cpufreq.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-Index: include/linux/cpufreq.h
-===================================================================
-RCS file: /cvs/linux/kernel/include/linux/cpufreq.h,v
-retrieving revision 1.4
-diff -u -r1.4 cpufreq.h
---- linux/include/linux/cpufreq.h 23 Aug 2002 22:18:47 -0000 1.4
-+++ linux/include/linux/cpufreq.h 29 Apr 2004 08:44:18 -0000
-@@ -16,9 +16,9 @@
- #include <linux/notifier.h>
-
- #ifndef CONFIG_SMP
--#define cpufreq_current(cpu) ((void)(cpu), __cpufreq_cur)
--#define cpufreq_max(cpu) ((void)(cpu), __cpufreq_max)
--#define cpufreq_min(cpu) ((void)(cpu), __cpufreq_min)
-+#define cpufreq_current(cpu) (__cpufreq_cur)
-+#define cpufreq_max(cpu) (__cpufreq_max)
-+#define cpufreq_min(cpu) (__cpufreq_min)
- #else
- /*
- * Should be something like:
diff --git a/linux/files/linux-2.4-no-short-loads.patch b/linux/files/linux-2.4-no-short-loads.patch
deleted file mode 100644
index f2d6c74224..0000000000
--- a/linux/files/linux-2.4-no-short-loads.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-Index: arch/arm/Makefile
-===================================================================
-RCS file: /cvs/linux/kernel/arch/arm/Makefile,v
-retrieving revision 1.47
-diff -u -r1.47 Makefile
---- linux/arch/arm/Makefile 9 Jul 2003 14:10:56 -0000 1.47
-+++ linux/arch/arm/Makefile 28 Apr 2004 21:11:04 -0000
-@@ -60,8 +60,8 @@
- tune-$(CONFIG_CPU_XSCALE) :=-mtune=xscale
- #tune-$(CONFIG_CPU_XSCALE) :=-mtune=strongarm
-
--CFLAGS_BOOT :=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Uarm
--CFLAGS +=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Uarm
-+CFLAGS_BOOT :=$(apcs-y) $(arch-y) $(tune-y) -msoft-float -Uarm
-+CFLAGS +=$(apcs-y) $(arch-y) $(tune-y) -msoft-float -Uarm
- AFLAGS +=$(apcs-y) $(arch-y) -msoft-float
-
- ifeq ($(CONFIG_CPU_26),y)
diff --git a/linux/files/linux-2.4.18-list_move.patch b/linux/files/linux-2.4.18-list_move.patch
deleted file mode 100644
index faec56330b..0000000000
--- a/linux/files/linux-2.4.18-list_move.patch
+++ /dev/null
@@ -1,32 +0,0 @@
---- linux/include/linux/list.h~ 2001-12-21 17:42:03.000000000 +0000
-+++ linux/include/linux/list.h 2004-06-14 23:41:33.000000000 +0100
-@@ -105,6 +105,29 @@
- }
-
- /**
-+ * list_move - delete from one list and add as another's head
-+ * @list: the entry to move
-+ * @head: the head that will precede our entry
-+ */
-+static inline void list_move(struct list_head *list, struct list_head *head)
-+{
-+ __list_del(list->prev, list->next);
-+ list_add(list, head);
-+}
-+
-+/**
-+ * list_move_tail - delete from one list and add as another's tail
-+ * @list: the entry to move
-+ * @head: the head that will follow our entry
-+ */
-+static inline void list_move_tail(struct list_head *list,
-+ struct list_head *head)
-+{
-+ __list_del(list->prev, list->next);
-+ list_add_tail(list, head);
-+}
-+
-+/**
- * list_empty - tests whether a list is empty
- * @head: the list to test.
- */
diff --git a/linux/files/mipv6-1.1-v2.4.25.patch b/linux/files/mipv6-1.1-v2.4.25.patch
deleted file mode 100644
index c5f32b6416..0000000000
--- a/linux/files/mipv6-1.1-v2.4.25.patch
+++ /dev/null
@@ -1,19832 +0,0 @@
-diff -uprN linux-2.4.25.old/Documentation/Configure.help linux-2.4.25/Documentation/Configure.help
---- linux-2.4.25.old/Documentation/Configure.help 2004-06-26 11:22:00.000000000 +0100
-+++ linux-2.4.25/Documentation/Configure.help 2004-06-26 11:29:29.000000000 +0100
-@@ -6204,6 +6204,57 @@ CONFIG_IPV6
-
- It is safe to say N here for now.
-
-+IPv6: IPv6 over IPv6 Tunneling (EXPERIMENTAL)
-+CONFIG_IPV6_TUNNEL
-+ Experimental IP6-IP6 tunneling. You must select this, if you want
-+ to use CONFIG_IPV6_MOBILITY. More information in MIPL Mobile IPv6
-+ instructions.
-+
-+ If you don't want IP6-IP6 tunnels and Mobile IPv6, say N.
-+
-+IPv6: Mobility Support (EXPERIMENTAL)
-+CONFIG_IPV6_MOBILITY
-+ This is experimental support for the upcoming specification of
-+ Mobile IPv6. Mobile IPv6 allows nodes to seamlessly move between
-+ networks without changing their IP addresses, thus allowing them to
-+ maintain upper layer connections (e.g. TCP). Selecting this option
-+ allows your computer to act as a Correspondent Node (CN). A MIPv6
-+ Mobile Node will be able to communicate with the CN and use route
-+ optimization.
-+
-+ For more information and configuration details, see
-+ http://www.mipl.mediapoli.com/.
-+
-+ If unsure, say N.
-+
-+MIPv6: Mobile Node Support
-+CONFIG_IPV6_MOBILITY_MN
-+ If you want your computer to be a MIPv6 Mobile Node (MN), select
-+ this option. You must configure MN using the userspace tools
-+ available at http://www.mipl.mediapoli.com/download/mipv6-tools/.
-+
-+ If your computer is stationary, or you are unsure if you need this,
-+ say N. Note that you will need a properly configured MIPv6 Home
-+ Agent to use any Mobile Nodes.
-+
-+MIPv6: Home Agent Support
-+CONFIG_IPV6_MOBILITY_HA
-+ If you want your router to serve as a MIPv6 Home Agent (HA), select
-+ this option. You must configure HA using the userspace tools
-+ available at http://www.mipl.mediapoli.com/download/mipv6-tools/.
-+
-+ If your computer is not a router, or you are unsure if you need
-+ this, say N.
-+
-+MIPv6: Debug messages
-+CONFIG_IPV6_MOBILITY_DEBUG
-+ MIPL Mobile IPv6 can produce a lot of debugging messages. There are
-+ eight debug levels (0 through 7) and the level is controlled via
-+ /proc/sys/net/ipv6/mobility/debuglevel. Since MIPL is still
-+ experimental, you might want to say Y here.
-+
-+ Be sure to say Y and record debug messages when submitting a bug
-+ report.
- The SCTP Protocol (EXPERIMENTAL)
- CONFIG_IP_SCTP
- Stream Control Transmission Protocol
-diff -uprN linux-2.4.25.old/Documentation/DocBook/Makefile linux-2.4.25/Documentation/DocBook/Makefile
---- linux-2.4.25.old/Documentation/DocBook/Makefile 2002-11-28 23:53:08.000000000 +0000
-+++ linux-2.4.25/Documentation/DocBook/Makefile 2004-06-26 11:29:29.000000000 +0100
-@@ -2,7 +2,7 @@ BOOKS := wanbook.sgml z8530book.sgml mca
- kernel-api.sgml parportbook.sgml kernel-hacking.sgml \
- kernel-locking.sgml via-audio.sgml mousedrivers.sgml sis900.sgml \
- deviceiobook.sgml procfs-guide.sgml tulip-user.sgml \
-- journal-api.sgml
-+ journal-api.sgml mip6-func.sgml
-
- PS := $(patsubst %.sgml, %.ps, $(BOOKS))
- PDF := $(patsubst %.sgml, %.pdf, $(BOOKS))
-@@ -86,6 +86,9 @@ videobook.sgml: videobook.tmpl $(TOPDIR)
- procfs-guide.sgml: procfs-guide.tmpl procfs_example.sgml
- $(TOPDIR)/scripts/docgen < procfs-guide.tmpl >$@
-
-+mip6-func.sgml: mip6-func.tmpl
-+ $(TOPDIR)/scripts/docgen <$< >$@
-+
- APISOURCES := $(TOPDIR)/drivers/media/video/videodev.c \
- $(TOPDIR)/arch/i386/kernel/irq.c \
- $(TOPDIR)/arch/i386/kernel/mca.c \
-diff -uprN linux-2.4.25.old/Documentation/DocBook/mip6-func.tmpl linux-2.4.25/Documentation/DocBook/mip6-func.tmpl
---- linux-2.4.25.old/Documentation/DocBook/mip6-func.tmpl 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/Documentation/DocBook/mip6-func.tmpl 2004-06-26 11:29:29.000000000 +0100
-@@ -0,0 +1,756 @@
-+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V3.1//EN"[]>
-+<book id="LinuxMobileIPv6">
-+ <bookinfo>
-+ <title>MIPL Mobile IPv6 Function Reference Guide</title>
-+
-+ <authorgroup>
-+ <author>
-+ <othername>MIPL Mobile IPv6 for Linux Team</othername>
-+ <affiliation>
-+ <orgname>Helsinki University of Technology</orgname>
-+ <orgdiv>Telecommunications Software and Multimedia Lab</orgdiv>
-+ <address>
-+ <pob>PO BOX 9201</pob>
-+ <postcode>FIN-02015 HUT</postcode>
-+ <country>Finland</country>
-+ <email>mipl@list.mipl.mediapoli.com</email>
-+ </address>
-+ </affiliation>
-+ </author>
-+ </authorgroup>
-+
-+ <copyright>
-+ <year>2000-2001</year>
-+ <holder>Helsinki University of Technology</holder>
-+ </copyright>
-+
-+ <legalnotice>
-+ <para>
-+ Copyright (c) 2001, 2002 MIPL Mobile IPv6 for Linux Team.
-+ </para>
-+ <para>
-+ Permission is granted to copy, distribute and/or modify this
-+ document under the terms of the GNU Free Documentation License,
-+ Version 1.1 published by the Free Software Foundation; with the
-+ Invariant Sections being "Introduction", with the Front-Cover
-+ Texts being "MIPL Mobile IPv6 Function Reference Guide", "MIPL
-+ Mobile IPv6 for Linux Team" and "Helsinki University of
-+ Technology". A copy of the license is included in <xref
-+ linkend="gfdl">.
-+ </para>
-+
-+ </legalnotice>
-+ </bookinfo>
-+
-+<toc></toc>
-+
-+ <preface id="intro">
-+ <title>Introduction</title>
-+
-+ <para>
-+ MIPL Mobile IPv6 for Linux is an implementation of Mobility
-+ Support in IPv6 IETF mobile-ip working groups Internet-Draft
-+ (draft-ietf-mobileip-ipv6). This implementation has been
-+ developed in the Telecommunications Software and Multimedia
-+ Laboratory at Helsinki University of Technology.
-+ </para>
-+
-+ <para>
-+ MIPL is fully open source, licensed under the GNU General
-+ Public License. Latest source for MIPL can be downloaded from
-+ the MIPL website at:
-+ </para>
-+ <programlisting>
-+ http://www.mipl.mediapoli.com/.
-+ </programlisting>
-+ <para>
-+ Developers and users interested in MIPL can subscribe to the
-+ MIPL mailing list by sending e-mail to
-+ <email>majordomo@list.mipl.mediapoli.com</email> with
-+ </para>
-+ <programlisting>
-+ subscribe mipl
-+ </programlisting>
-+ <para>
-+ in the body of the message.
-+ </para>
-+
-+ <para>
-+ This document is a reference guide to MIPL functions. Intended
-+ audience is developers wishing to contribute to the project.
-+ Hopefully this document will make it easier and quicker to
-+ understand and adopt the inner workings of MIPL Mobile IPv6.
-+ </para>
-+
-+ <para>
-+ MIPL Mobile IPv6 for Linux Team members (past and present):
-+
-+ <itemizedlist>
-+ <listitem>
-+ <address>
-+ Sami Kivisaari <email>Sami.Kivisaari@hut.fi</email>
-+ </address>
-+ </listitem>
-+ <listitem>
-+ <address>
-+ Niklas Kampe <email>Niklas.Kampe@hut.fi</email>
-+ </address>
-+ </listitem>
-+ <listitem>
-+ <address>
-+ Juha Mynttinen <email>Juha.Mynttinen@hut.fi</email>
-+ </address>
-+ </listitem>
-+ <listitem>
-+ <address>
-+ Toni Nykanen <email>Toni.Nykanen@iki.fi</email>
-+ </address>
-+ </listitem>
-+ <listitem>
-+ <address>
-+ Henrik Petander <email>Henrik.Petander@hut.fi</email>
-+ </address>
-+ </listitem>
-+ <listitem>
-+ <address>
-+ Antti Tuominen <email>ajtuomin@tml.hut.fi</email>
-+ </address>
-+ </listitem>
-+ </itemizedlist>
-+
-+ <itemizedlist>
-+ <listitem>
-+ <address>
-+ Marko Myllynen
-+ </address>
-+ </listitem>
-+ <listitem>
-+ <address>
-+ Ville Nuorvala <email>vnuorval@tcs.hut.fi</email>
-+ </address>
-+ </listitem>
-+ <listitem>
-+ <address>
-+ Jaakko Laine <email>Jaakko.Laine@hut.fi</email>
-+ </address>
-+ </listitem>
-+ </itemizedlist>
-+ </para>
-+
-+ </preface>
-+
-+ <chapter id="common">
-+ <title>Common functions for all entities</title>
-+
-+ <sect1><title>Low-level functions</title>
-+ <para>
-+ These functions implement memory allocation used by others.
-+ Hashlist functions implement a linked list with hash lookup,
-+ which is used with Binding Update List, Binding Cache, Home
-+ Agents List etc.
-+ </para>
-+!Inet/ipv6/mobile_ip6/mempool.h
-+!Inet/ipv6/mobile_ip6/hashlist.h
-+ </sect1>
-+
-+ <sect1><title>Debug functions</title>
-+ <para>
-+ Debug and utility functions. These functions are available if
-+ <constant>CONFIG_IPV6_MOBILITY_DEBUG</constant> is set.
-+ Otherwise macros expand to no operation.
-+ </para>
-+!Inet/ipv6/mobile_ip6/debug.h
-+!Inet/ipv6/mobile_ip6/mipv6.c
-+ </sect1>
-+
-+ <sect1><title>Extension Header functions</title>
-+ <para>
-+ These functions create and handle extension headers that are
-+ specific to MIPv6.
-+ </para>
-+!Inet/ipv6/mobile_ip6/exthdrs.c
-+ </sect1>
-+
-+ <sect1><title>Mobility Header functions</title>
-+ <para>
-+ MIPv6 specifies a new protocol called Mobility Header.
-+ Mobility Header has several message types. Messages may also
-+ carry Mobility Options. These functions are used to create and
-+ handle Mobility Headers and Mobility Options.
-+ </para>
-+!Inet/ipv6/mobile_ip6/sendopts.c
-+!Inet/ipv6/mobile_ip6/mh_recv.c
-+!Inet/ipv6/mobile_ip6/auth_subopt.c
-+ </sect1>
-+
-+ <sect1><title>Binding Cache</title>
-+ <para>
-+ All Mobile IPv6 entities have a binding cache. These functions
-+ provide easy manipulation of the binding cache.
-+ </para>
-+!Inet/ipv6/mobile_ip6/bcache.c
-+ </sect1>
-+
-+ <sect1><title>Security</title>
-+
-+ <para>
-+ These functions are common authentication functions and
-+ implement Draft 13 style IPSec AH support for Binding Updates.
-+ </para>
-+!Inet/ipv6/mobile_ip6/ah_algo.c
-+!Inet/ipv6/mobile_ip6/sadb.c
-+!Inet/ipv6/mobile_ip6/ah.c
-+ </sect1>
-+
-+ <sect1><title>Utility functions</title>
-+
-+ <para>
-+ These functions are general utility functions commonly used by
-+ all entities.
-+ </para>
-+!Inet/ipv6/mobile_ip6/util.c
-+ </sect1>
-+
-+ </chapter>
-+
-+ <chapter id="mn">
-+ <title>Mobile Node functions</title>
-+ <sect1><title>General functions</title>
-+ <para>
-+ </para>
-+!Inet/ipv6/mobile_ip6/mn.c
-+ </sect1>
-+
-+ <sect1><title>Binding Update List</title>
-+ <para>
-+ Mobile Node keeps track of sent binding updates in Binding
-+ Update List.
-+ </para>
-+!Inet/ipv6/mobile_ip6/bul.c
-+ </sect1>
-+
-+ <sect1><title>Movement detection</title>
-+
-+ <para>
-+ These functions are used by the mobile node for movement
-+ detection.
-+ </para>
-+!Inet/ipv6/mobile_ip6/mdetect.c
-+ </sect1>
-+ </chapter>
-+
-+ <chapter id="ha">
-+ <title>Home Agent functions</title>
-+ <sect1><title>General functions</title>
-+ <para>
-+ </para>
-+!Inet/ipv6/mobile_ip6/ha.c
-+ </sect1>
-+
-+ <sect1><title>Duplicate Address Detection functions</title>
-+ <para>
-+ Home Agent does Duplicate Address Detection for Mobile Nodes'
-+ addresses. These functions implement MIPv6 specific DAD
-+ functionality.
-+ </para>
-+!Inet/ipv6/mobile_ip6/dad.c
-+ </sect1>
-+
-+ </chapter>
-+ <appendix id="gfdl">
-+ <title>GNU Free Documentation License</title>
-+
-+ <para>
-+ Version 1.1, March 2000
-+ </para>
-+
-+ <programlisting>
-+ Copyright (C) 2000 Free Software Foundation, Inc.
-+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ Everyone is permitted to copy and distribute verbatim copies
-+ of this license document, but changing it is not allowed.
-+ </programlisting>
-+
-+ <sect1><title>0. PREAMBLE</title>
-+
-+ <para>
-+ The purpose of this License is to make a manual, textbook, or
-+ other written document "free" in the sense of freedom: to
-+ assure everyone the effective freedom to copy and redistribute
-+ it, with or without modifying it, either commercially or
-+ noncommercially. Secondarily, this License preserves for the
-+ author and publisher a way to get credit for their work, while
-+ not being considered responsible for modifications made by
-+ others.
-+ </para>
-+
-+ <para>
-+ This License is a kind of "copyleft", which means that
-+ derivative works of the document must themselves be free in the
-+ same sense. It complements the GNU General Public License,
-+ which is a copyleft license designed for free software.
-+ </para>
-+
-+ <para>
-+ We have designed this License in order to use it for manuals
-+ for free software, because free software needs free
-+ documentation: a free program should come with manuals
-+ providing the same freedoms that the software does. But this
-+ License is not limited to software manuals; it can be used for
-+ any textual work, regardless of subject matter or whether it is
-+ published as a printed book. We recommend this License
-+ principally for works whose purpose is instruction or
-+ reference.
-+ </para>
-+
-+ </sect1>
-+ <sect1><title>1. APPLICABILITY AND DEFINITIONS</title>
-+
-+ <para>
-+ This License applies to any manual or other work that contains
-+ a notice placed by the copyright holder saying it can be
-+ distributed under the terms of this License. The "Document",
-+ below, refers to any such manual or work. Any member of the
-+ public is a licensee, and is addressed as "you".
-+ </para>
-+
-+ <para>
-+ A "Modified Version" of the Document means any work containing
-+ the Document or a portion of it, either copied verbatim, or
-+ with modifications and/or translated into another language.
-+ </para>
-+
-+ <para>
-+ A "Secondary Section" is a named appendix or a front-matter
-+ section of the Document that deals exclusively with the
-+ relationship of the publishers or authors of the Document to
-+ the Document's overall subject (or to related matters) and
-+ contains nothing that could fall directly within that overall
-+ subject. (For example, if the Document is in part a textbook of
-+ mathematics, a Secondary Section may not explain any
-+ mathematics.) The relationship could be a matter of historical
-+ connection with the subject or with related matters, or of
-+ legal, commercial, philosophical, ethical or political position
-+ regarding them.
-+ </para>
-+
-+ <para>
-+ The "Invariant Sections" are certain Secondary Sections whose
-+ titles are designated, as being those of Invariant Sections, in
-+ the notice that says that the Document is released under this
-+ License.
-+ </para>
-+
-+ <para>
-+ The "Cover Texts" are certain short passages of text that are
-+ listed, as Front-Cover Texts or Back-Cover Texts, in the notice
-+ that says that the Document is released under this License.
-+ </para>
-+
-+ <para>
-+ A "Transparent" copy of the Document means a machine-readable
-+ copy, represented in a format whose specification is available
-+ to the general public, whose contents can be viewed and edited
-+ directly and straightforwardly with generic text editors or
-+ (for images composed of pixels) generic paint programs or (for
-+ drawings) some widely available drawing editor, and that is
-+ suitable for input to text formatters or for automatic
-+ translation to a variety of formats suitable for input to text
-+ formatters. A copy made in an otherwise Transparent file format
-+ whose markup has been designed to thwart or discourage
-+ subsequent modification by readers is not Transparent. A copy
-+ that is not "Transparent" is called "Opaque".
-+ </para>
-+
-+ <para>
-+ Examples of suitable formats for Transparent copies include
-+ plain ASCII without markup, Texinfo input format, LaTeX input
-+ format, SGML or XML using a publicly available DTD, and
-+ standard-conforming simple HTML designed for human
-+ modification. Opaque formats include PostScript, PDF,
-+ proprietary formats that can be read and edited only by
-+ proprietary word processors, SGML or XML for which the DTD
-+ and/or processing tools are not generally available, and the
-+ machine-generated HTML produced by some word processors for
-+ output purposes only.
-+ </para>
-+
-+ <para>
-+ The "Title Page" means, for a printed book, the title page
-+ itself, plus such following pages as are needed to hold,
-+ legibly, the material this License requires to appear in the
-+ title page. For works in formats which do not have any title
-+ page as such, "Title Page" means the text near the most
-+ prominent appearance of the work's title, preceding the
-+ beginning of the body of the text.
-+ </para>
-+
-+ </sect1>
-+ <sect1><title>2. VERBATIM COPYING</title>
-+
-+ <para>
-+ You may copy and distribute the Document in any medium, either
-+ commercially or noncommercially, provided that this License,
-+ the copyright notices, and the license notice saying this
-+ License applies to the Document are reproduced in all copies,
-+ and that you add no other conditions whatsoever to those of
-+ this License. You may not use technical measures to obstruct or
-+ control the reading or further copying of the copies you make
-+ or distribute. However, you may accept compensation in exchange
-+ for copies. If you distribute a large enough number of copies
-+ you must also follow the conditions in section 3.
-+ </para>
-+
-+ <para>
-+ You may also lend copies, under the same conditions stated
-+ above, and you may publicly display copies.
-+ </para>
-+
-+ </sect1>
-+ <sect1><title>3. COPYING IN QUANTITY</title>
-+
-+ <para>
-+ If you publish printed copies of the Document numbering more
-+ than 100, and the Document's license notice requires Cover
-+ Texts, you must enclose the copies in covers that carry,
-+ clearly and legibly, all these Cover Texts: Front-Cover Texts
-+ on the front cover, and Back-Cover Texts on the back
-+ cover. Both covers must also clearly and legibly identify you
-+ as the publisher of these copies. The front cover must present
-+ the full title with all words of the title equally prominent
-+ and visible. You may add other material on the covers in
-+ addition. Copying with changes limited to the covers, as long
-+ as they preserve the title of the Document and satisfy these
-+ conditions, can be treated as verbatim copying in other
-+ respects.
-+ </para>
-+
-+ <para>
-+ If the required texts for either cover are too voluminous to
-+ fit legibly, you should put the first ones listed (as many as
-+ fit reasonably) on the actual cover, and continue the rest onto
-+ adjacent pages.
-+ </para>
-+
-+ <para>
-+ If you publish or distribute Opaque copies of the Document
-+ numbering more than 100, you must either include a
-+ machine-readable Transparent copy along with each Opaque copy,
-+ or state in or with each Opaque copy a publicly-accessible
-+ computer-network location containing a complete Transparent
-+ copy of the Document, free of added material, which the general
-+ network-using public has access to download anonymously at no
-+ charge using public-standard network protocols. If you use the
-+ latter option, you must take reasonably prudent steps, when you
-+ begin distribution of Opaque copies in quantity, to ensure that
-+ this Transparent copy will remain thus accessible at the stated
-+ location until at least one year after the last time you
-+ distribute an Opaque copy (directly or through your agents or
-+ retailers) of that edition to the public.
-+ </para>
-+
-+ <para>
-+ It is requested, but not required, that you contact the authors
-+ of the Document well before redistributing any large number of
-+ copies, to give them a chance to provide you with an updated
-+ version of the Document.
-+ </para>
-+
-+ </sect1>
-+ <sect1><title>4. MODIFICATIONS</title>
-+
-+ <para>
-+ You may copy and distribute a Modified Version of the Document
-+ under the conditions of sections 2 and 3 above, provided that
-+ you release the Modified Version under precisely this License,
-+ with the Modified Version filling the role of the Document,
-+ thus licensing distribution and modification of the Modified
-+ Version to whoever possesses a copy of it. In addition, you
-+ must do these things in the Modified Version:
-+ </para>
-+
-+ <para>
-+ <itemizedlist spacing=compact>
-+ <listitem>
-+ <para>
-+ A. Use in the Title Page (and on the covers, if any) a title
-+ distinct from that of the Document, and from those of previous
-+ versions (which should, if there were any, be listed in the
-+ History section of the Document). You may use the same title
-+ as a previous version if the original publisher of that
-+ version gives permission.
-+ </para>
-+ </listitem>
-+ <listitem>
-+ <para>
-+ B. List on the Title Page, as authors, one or more persons
-+ or entities responsible for authorship of the modifications in
-+ the Modified Version, together with at least five of the
-+ principal authors of the Document (all of its principal
-+ authors, if it has less than five).
-+ </para>
-+ </listitem>
-+ <listitem>
-+ <para>
-+ C. State on the Title page the name of the publisher of the
-+ Modified Version, as the publisher.
-+ </para>
-+ </listitem>
-+ <listitem>
-+ <para>
-+ D. Preserve all the copyright notices of the Document.
-+ </para>
-+ </listitem>
-+ <listitem>
-+ <para>
-+ E. Add an appropriate copyright notice for your
-+ modifications adjacent to the other copyright notices.
-+ </para>
-+ </listitem>
-+ <listitem>
-+ <para>
-+ F. Include, immediately after the copyright notices, a
-+ license notice giving the public permission to use the
-+ Modified Version under the terms of this License, in the form
-+ shown in the Addendum below.
-+ </para>
-+ </listitem>
-+ <listitem>
-+ <para>
-+ G. Preserve in that license notice the full lists of
-+ Invariant Sections and required Cover Texts given in the
-+ Document's license notice.
-+ </para>
-+ </listitem>
-+ <listitem>
-+ <para>
-+ H. Include an unaltered copy of this License.
-+ </para>
-+ </listitem>
-+ <listitem>
-+ <para>
-+ I. Preserve the section entitled "History", and its title,
-+ and add to it an item stating at least the title, year, new
-+ authors, and publisher of the Modified Version as given on the
-+ Title Page. If there is no section entitled "History" in the
-+ Document, create one stating the title, year, authors, and
-+ publisher of the Document as given on its Title Page, then add
-+ an item describing the Modified Version as stated in the
-+ previous sentence.
-+ </para>
-+ </listitem>
-+ <listitem>
-+ <para>
-+ J. Preserve the network location, if any, given in the
-+ Document for public access to a Transparent copy of the
-+ Document, and likewise the network locations given in the
-+ Document for previous versions it was based on. These may be
-+ placed in the "History" section. You may omit a network
-+ location for a work that was published at least four years
-+ before the Document itself, or if the original publisher of
-+ the version it refers to gives permission.
-+ </para>
-+ </listitem>
-+ <listitem>
-+ <para>
-+ K. In any section entitled "Acknowledgements" or
-+ "Dedications", preserve the section's title, and preserve in
-+ the section all the substance and tone of each of the
-+ contributor acknowledgements and/or dedications given therein.
-+ </para>
-+ </listitem>
-+ <listitem>
-+ <para>
-+ L. Preserve all the Invariant Sections of the Document,
-+ unaltered in their text and in their titles. Section numbers
-+ or the equivalent are not considered part of the section
-+ titles.
-+ </para>
-+ </listitem>
-+ <listitem>
-+ <para>
-+ M. Delete any section entitled "Endorsements". Such a
-+ section may not be included in the Modified Version.
-+ </para>
-+ </listitem>
-+ <listitem>
-+ <para>
-+ N. Do not retitle any existing section as "Endorsements" or
-+ to conflict in title with any Invariant Section.
-+ </para>
-+ </listitem>
-+ </itemizedlist>
-+ </para>
-+
-+ <para>
-+ If the Modified Version includes new front-matter sections or
-+ appendices that qualify as Secondary Sections and contain no
-+ material copied from the Document, you may at your option
-+ designate some or all of these sections as invariant. To do
-+ this, add their titles to the list of Invariant Sections in the
-+ Modified Version's license notice. These titles must be
-+ distinct from any other section titles.
-+ </para>
-+
-+ <para>
-+ You may add a section entitled "Endorsements", provided it
-+ contains nothing but endorsements of your Modified Version by
-+ various parties--for example, statements of peer review or that
-+ the text has been approved by an organization as the
-+ authoritative definition of a standard.
-+ </para>
-+
-+ <para>
-+ You may add a passage of up to five words as a Front-Cover
-+ Text, and a passage of up to 25 words as a Back-Cover Text, to
-+ the end of the list of Cover Texts in the Modified
-+ Version. Only one passage of Front-Cover Text and one of
-+ Back-Cover Text may be added by (or through arrangements made
-+ by) any one entity. If the Document already includes a cover
-+ text for the same cover, previously added by you or by
-+ arrangement made by the same entity you are acting on behalf
-+ of, you may not add another; but you may replace the old one,
-+ on explicit permission from the previous publisher that added
-+ the old one.
-+ </para>
-+
-+ <para>
-+ The author(s) and publisher(s) of the Document do not by this
-+ License give permission to use their names for publicity for or
-+ to assert or imply endorsement of any Modified Version.
-+ </para>
-+
-+ </sect1>
-+ <sect1><title>5. COMBINING DOCUMENTS</title>
-+
-+ <para>
-+ You may combine the Document with other documents released
-+ under this License, under the terms defined in section 4 above
-+ for modified versions, provided that you include in the
-+ combination all of the Invariant Sections of all of the
-+ original documents, unmodified, and list them all as Invariant
-+ Sections of your combined work in its license notice.
-+ </para>
-+
-+ <para>
-+ The combined work need only contain one copy of this License,
-+ and multiple identical Invariant Sections may be replaced with
-+ a single copy. If there are multiple Invariant Sections with
-+ the same name but different contents, make the title of each
-+ such section unique by adding at the end of it, in parentheses,
-+ the name of the original author or publisher of that section if
-+ known, or else a unique number. Make the same adjustment to the
-+ section titles in the list of Invariant Sections in the license
-+ notice of the combined work.
-+ </para>
-+
-+ <para>
-+ In the combination, you must combine any sections entitled
-+ "History" in the various original documents, forming one
-+ section entitled "History"; likewise combine any sections
-+ entitled "Acknowledgements", and any sections entitled
-+ "Dedications". You must delete all sections entitled
-+ "Endorsements."
-+ </para>
-+
-+ </sect1>
-+ <sect1><title>6. COLLECTIONS OF DOCUMENTS</title>
-+
-+ <para>
-+ You may make a collection consisting of the Document and other
-+ documents released under this License, and replace the
-+ individual copies of this License in the various documents with
-+ a single copy that is included in the collection, provided that
-+ you follow the rules of this License for verbatim copying of
-+ each of the documents in all other respects.
-+ </para>
-+
-+ <para>
-+ You may extract a single document from such a collection, and
-+ distribute it individually under this License, provided you
-+ insert a copy of this License into the extracted document, and
-+ follow this License in all other respects regarding verbatim
-+ copying of that document.
-+ </para>
-+
-+ </sect1>
-+ <sect1><title>7. AGGREGATION WITH INDEPENDENT WORKS</title>
-+
-+ <para>
-+ A compilation of the Document or its derivatives with other
-+ separate and independent documents or works, in or on a volume
-+ of a storage or distribution medium, does not as a whole count
-+ as a Modified Version of the Document, provided no compilation
-+ copyright is claimed for the compilation. Such a compilation is
-+ called an "aggregate", and this License does not apply to the
-+ other self-contained works thus compiled with the Document, on
-+ account of their being thus compiled, if they are not
-+ themselves derivative works of the Document.
-+ </para>
-+
-+ <para>
-+ If the Cover Text requirement of section 3 is applicable to
-+ these copies of the Document, then if the Document is less than
-+ one quarter of the entire aggregate, the Document's Cover Texts
-+ may be placed on covers that surround only the Document within
-+ the aggregate. Otherwise they must appear on covers around the
-+ whole aggregate.
-+ </para>
-+
-+ </sect1>
-+ <sect1><title>8. TRANSLATION</title>
-+
-+ <para>
-+ Translation is considered a kind of modification, so you may
-+ distribute translations of the Document under the terms of
-+ section 4. Replacing Invariant Sections with translations
-+ requires special permission from their copyright holders, but
-+ you may include translations of some or all Invariant Sections
-+ in addition to the original versions of these Invariant
-+ Sections. You may include a translation of this License
-+ provided that you also include the original English version of
-+ this License. In case of a disagreement between the translation
-+ and the original English version of this License, the original
-+ English version will prevail.
-+ </para>
-+
-+ </sect1>
-+ <sect1><title>9. TERMINATION</title>
-+
-+ <para>
-+ You may not copy, modify, sublicense, or distribute the
-+ Document except as expressly provided for under this
-+ License. Any other attempt to copy, modify, sublicense or
-+ distribute the Document is void, and will automatically
-+ terminate your rights under this License. However, parties who
-+ have received copies, or rights, from you under this License
-+ will not have their licenses terminated so long as such parties
-+ remain in full compliance.
-+ </para>
-+
-+ </sect1>
-+ <sect1><title>10. FUTURE REVISIONS OF THIS LICENSE</title>
-+
-+ <para>
-+ The Free Software Foundation may publish new, revised versions
-+ of the GNU Free Documentation License from time to time. Such
-+ new versions will be similar in spirit to the present version,
-+ but may differ in detail to address new problems or
-+ concerns. See http://www.gnu.org/copyleft/.
-+ </para>
-+
-+ <para>
-+ Each version of the License is given a distinguishing version
-+ number. If the Document specifies that a particular numbered
-+ version of this License "or any later version" applies to it,
-+ you have the option of following the terms and conditions
-+ either of that specified version or of any later version that
-+ has been published (not as a draft) by the Free Software
-+ Foundation. If the Document does not specify a version number
-+ of this License, you may choose any version ever published (not
-+ as a draft) by the Free Software Foundation.
-+ </para>
-+
-+ </sect1>
-+ </appendix>
-+</book>
-diff -uprN linux-2.4.25.old/include/linux/icmpv6.h linux-2.4.25/include/linux/icmpv6.h
---- linux-2.4.25.old/include/linux/icmpv6.h 2003-08-25 12:44:44.000000000 +0100
-+++ linux-2.4.25/include/linux/icmpv6.h 2004-06-26 11:29:29.000000000 +0100
-@@ -40,14 +40,16 @@ struct icmp6hdr {
- struct icmpv6_nd_ra {
- __u8 hop_limit;
- #if defined(__LITTLE_ENDIAN_BITFIELD)
-- __u8 reserved:6,
-+ __u8 reserved:5,
-+ home_agent:1,
- other:1,
- managed:1;
-
- #elif defined(__BIG_ENDIAN_BITFIELD)
- __u8 managed:1,
- other:1,
-- reserved:6;
-+ home_agent:1,
-+ reserved:5;
- #else
- #error "Please fix <asm/byteorder.h>"
- #endif
-@@ -70,6 +72,7 @@ struct icmp6hdr {
- #define icmp6_addrconf_managed icmp6_dataun.u_nd_ra.managed
- #define icmp6_addrconf_other icmp6_dataun.u_nd_ra.other
- #define icmp6_rt_lifetime icmp6_dataun.u_nd_ra.rt_lifetime
-+#define icmp6_home_agent icmp6_dataun.u_nd_ra.home_agent
- };
-
-
-diff -uprN linux-2.4.25.old/include/linux/if_arp.h linux-2.4.25/include/linux/if_arp.h
---- linux-2.4.25.old/include/linux/if_arp.h 2002-02-25 19:38:13.000000000 +0000
-+++ linux-2.4.25/include/linux/if_arp.h 2004-06-26 11:29:29.000000000 +0100
-@@ -59,7 +59,7 @@
- #define ARPHRD_RAWHDLC 518 /* Raw HDLC */
-
- #define ARPHRD_TUNNEL 768 /* IPIP tunnel */
--#define ARPHRD_TUNNEL6 769 /* IPIP6 tunnel */
-+#define ARPHRD_TUNNEL6 769 /* IP6IP6 tunnel */
- #define ARPHRD_FRAD 770 /* Frame Relay Access Device */
- #define ARPHRD_SKIP 771 /* SKIP vif */
- #define ARPHRD_LOOPBACK 772 /* Loopback device */
-diff -uprN linux-2.4.25.old/include/linux/in6.h linux-2.4.25/include/linux/in6.h
---- linux-2.4.25.old/include/linux/in6.h 2003-06-13 15:51:38.000000000 +0100
-+++ linux-2.4.25/include/linux/in6.h 2004-06-26 11:29:29.000000000 +0100
-@@ -142,6 +142,11 @@ struct in6_flowlabel_req
- #define IPV6_TLV_JUMBO 194
-
- /*
-+ * Mobile IPv6 TLV options.
-+ */
-+#define MIPV6_TLV_HOMEADDR 201
-+
-+/*
- * IPV6 socket options
- */
-
-diff -uprN linux-2.4.25.old/include/linux/ipv6.h linux-2.4.25/include/linux/ipv6.h
---- linux-2.4.25.old/include/linux/ipv6.h 2003-11-28 18:26:21.000000000 +0000
-+++ linux-2.4.25/include/linux/ipv6.h 2004-06-26 11:29:29.000000000 +0100
-@@ -29,6 +29,7 @@ struct in6_ifreq {
-
- #define IPV6_SRCRT_STRICT 0x01 /* this hop must be a neighbor */
- #define IPV6_SRCRT_TYPE_0 0 /* IPv6 type 0 Routing Header */
-+#define IPV6_SRCRT_TYPE_2 2 /* type 2 for Mobile IPv6 */
-
- /*
- * routing header
-@@ -71,6 +72,19 @@ struct rt0_hdr {
- struct in6_addr addr[0];
-
- #define rt0_type rt_hdr.type
-+
-+};
-+
-+/*
-+ * routing header type 2
-+ */
-+
-+struct rt2_hdr {
-+ struct ipv6_rt_hdr rt_hdr;
-+ __u32 reserved;
-+ struct in6_addr addr;
-+
-+#define rt2_type rt_hdr.type;
- };
-
- /*
-@@ -156,12 +170,16 @@ enum {
- struct inet6_skb_parm
- {
- int iif;
-+ __u8 mipv6_flags;
- __u16 ra;
- __u16 hop;
- __u16 auth;
- __u16 dst0;
- __u16 srcrt;
-+ __u16 srcrt2;
-+ __u16 hao;
- __u16 dst1;
-+ struct in6_addr hoa;
- };
-
- #endif
-diff -uprN linux-2.4.25.old/include/linux/ipv6_route.h linux-2.4.25/include/linux/ipv6_route.h
---- linux-2.4.25.old/include/linux/ipv6_route.h 2003-11-28 18:26:21.000000000 +0000
-+++ linux-2.4.25/include/linux/ipv6_route.h 2004-06-26 11:29:29.000000000 +0100
-@@ -33,6 +33,7 @@ enum
- #define RTF_CACHE 0x01000000 /* cache entry */
- #define RTF_FLOW 0x02000000 /* flow significant route */
- #define RTF_POLICY 0x04000000 /* policy route */
-+#define RTF_MOBILENODE 0x10000000 /* for routing to Mobile Node */
-
- #define RTF_LOCAL 0x80000000
-
-diff -uprN linux-2.4.25.old/include/linux/ipv6_tunnel.h linux-2.4.25/include/linux/ipv6_tunnel.h
---- linux-2.4.25.old/include/linux/ipv6_tunnel.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/include/linux/ipv6_tunnel.h 2004-06-26 11:29:29.000000000 +0100
-@@ -0,0 +1,34 @@
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef _IPV6_TUNNEL_H
-+#define _IPV6_TUNNEL_H
-+
-+#define IPV6_TLV_TNL_ENCAP_LIMIT 4
-+#define IPV6_DEFAULT_TNL_ENCAP_LIMIT 4
-+
-+/* don't add encapsulation limit if one isn't present in inner packet */
-+#define IP6_TNL_F_IGN_ENCAP_LIMIT 0x1
-+/* copy the traffic class field from the inner packet */
-+#define IP6_TNL_F_USE_ORIG_TCLASS 0x2
-+/* copy the flowlabel from the inner packet */
-+#define IP6_TNL_F_USE_ORIG_FLOWLABEL 0x4
-+/* created and maintained from within the kernel */
-+#define IP6_TNL_F_KERNEL_DEV 0x8
-+/* being used for Mobile IPv6 */
-+#define IP6_TNL_F_MIP6_DEV 0x10
-+
-+struct ip6_tnl_parm {
-+ char name[IFNAMSIZ]; /* name of tunnel device */
-+ int link; /* ifindex of underlying L2 interface */
-+ __u8 proto; /* tunnel protocol */
-+ __u8 encap_limit; /* encapsulation limit for tunnel */
-+ __u8 hop_limit; /* hop limit for tunnel */
-+ __u32 flowinfo; /* traffic class and flowlabel for tunnel */
-+ __u32 flags; /* tunnel flags */
-+ struct in6_addr laddr; /* local tunnel end-point address */
-+ struct in6_addr raddr; /* remote tunnel end-point address */
-+};
-+
-+#endif
-diff -uprN linux-2.4.25.old/include/linux/rtnetlink.h linux-2.4.25/include/linux/rtnetlink.h
---- linux-2.4.25.old/include/linux/rtnetlink.h 2004-02-18 13:36:32.000000000 +0000
-+++ linux-2.4.25/include/linux/rtnetlink.h 2004-06-26 11:29:29.000000000 +0100
-@@ -309,15 +309,17 @@ enum
- IFA_LABEL,
- IFA_BROADCAST,
- IFA_ANYCAST,
-- IFA_CACHEINFO
-+ IFA_CACHEINFO,
-+ IFA_HOMEAGENT
- };
-
--#define IFA_MAX IFA_CACHEINFO
-+#define IFA_MAX IFA_HOMEAGENT
-
- /* ifa_flags */
-
- #define IFA_F_SECONDARY 0x01
-
-+#define IFA_F_HOMEADDR 0x10
- #define IFA_F_DEPRECATED 0x20
- #define IFA_F_TENTATIVE 0x40
- #define IFA_F_PERMANENT 0x80
-diff -uprN linux-2.4.25.old/include/linux/skbuff.h linux-2.4.25/include/linux/skbuff.h
---- linux-2.4.25.old/include/linux/skbuff.h 2003-08-25 12:44:44.000000000 +0100
-+++ linux-2.4.25/include/linux/skbuff.h 2004-06-26 11:29:29.000000000 +0100
-@@ -177,7 +177,7 @@ struct sk_buff {
- * want to keep them across layers you have to do a skb_clone()
- * first. This is owned by whoever has the skb queued ATM.
- */
-- char cb[48];
-+ char cb[64];
-
- unsigned int len; /* Length of actual data */
- unsigned int data_len;
-diff -uprN linux-2.4.25.old/include/linux/sysctl.h linux-2.4.25/include/linux/sysctl.h
---- linux-2.4.25.old/include/linux/sysctl.h 2004-02-18 13:36:32.000000000 +0000
-+++ linux-2.4.25/include/linux/sysctl.h 2004-06-26 11:29:29.000000000 +0100
-@@ -387,7 +387,24 @@ enum {
- NET_IPV6_NEIGH=17,
- NET_IPV6_ROUTE=18,
- NET_IPV6_ICMP=19,
-- NET_IPV6_BINDV6ONLY=20
-+ NET_IPV6_BINDV6ONLY=20,
-+ NET_IPV6_MOBILITY=26
-+};
-+
-+/* /proc/sys/net/ipv6/mobility */
-+enum {
-+ NET_IPV6_MOBILITY_DEBUG=1,
-+ NET_IPV6_MOBILITY_TUNNEL_SITELOCAL=2,
-+ NET_IPV6_MOBILITY_ROUTER_SOLICITATION_MAX_SENDTIME=3,
-+ NET_IPV6_MOBILITY_ROUTER_REACH=4,
-+ NET_IPV6_MOBILITY_MDETECT_MECHANISM=5,
-+ NET_IPV6_MOBILITY_RETROUT=6,
-+ NET_IPV6_MOBILITY_MAX_TNLS=7,
-+ NET_IPV6_MOBILITY_MIN_TNLS=8,
-+ NET_IPV6_MOBILITY_BINDING_REFRESH=9,
-+ NET_IPV6_MOBILITY_BU_F_LLADDR=10,
-+ NET_IPV6_MOBILITY_BU_F_KEYMGM=11,
-+ NET_IPV6_MOBILITY_BU_F_CN_ACK=12
- };
-
- enum {
-diff -uprN linux-2.4.25.old/include/net/addrconf.h linux-2.4.25/include/net/addrconf.h
---- linux-2.4.25.old/include/net/addrconf.h 2003-08-25 12:44:44.000000000 +0100
-+++ linux-2.4.25/include/net/addrconf.h 2004-06-26 11:29:29.000000000 +0100
-@@ -16,9 +16,11 @@ struct prefix_info {
- #if defined(__BIG_ENDIAN_BITFIELD)
- __u8 onlink : 1,
- autoconf : 1,
-- reserved : 6;
-+ router_address : 1,
-+ reserved : 5;
- #elif defined(__LITTLE_ENDIAN_BITFIELD)
-- __u8 reserved : 6,
-+ __u8 reserved : 5,
-+ router_address : 1,
- autoconf : 1,
- onlink : 1;
- #else
-@@ -55,6 +57,7 @@ extern int ipv6_chk_addr(struct in6_ad
- struct net_device *dev);
- extern struct inet6_ifaddr * ipv6_get_ifaddr(struct in6_addr *addr,
- struct net_device *dev);
-+extern void ipv6_del_addr(struct inet6_ifaddr *ifp);
- extern int ipv6_get_saddr(struct dst_entry *dst,
- struct in6_addr *daddr,
- struct in6_addr *saddr);
-@@ -85,7 +88,9 @@ extern void ipv6_mc_up(struct inet6_dev
- extern void ipv6_mc_down(struct inet6_dev *idev);
- extern void ipv6_mc_init_dev(struct inet6_dev *idev);
- extern void ipv6_mc_destroy_dev(struct inet6_dev *idev);
-+extern void addrconf_dad_start(struct inet6_ifaddr *ifp, int flags);
- extern void addrconf_dad_failure(struct inet6_ifaddr *ifp);
-+extern void addrconf_dad_completed(struct inet6_ifaddr *ifp);
-
- extern int ipv6_chk_mcast_addr(struct net_device *dev, struct in6_addr *group,
- struct in6_addr *src_addr);
-@@ -116,6 +121,9 @@ extern int ipv6_chk_acast_addr(struct
- extern int register_inet6addr_notifier(struct notifier_block *nb);
- extern int unregister_inet6addr_notifier(struct notifier_block *nb);
-
-+extern int ipv6_generate_eui64(u8 *eui, struct net_device *dev);
-+extern int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev);
-+
- static inline struct inet6_dev *
- __in6_dev_get(struct net_device *dev)
- {
-diff -uprN linux-2.4.25.old/include/net/ip6_route.h linux-2.4.25/include/net/ip6_route.h
---- linux-2.4.25.old/include/net/ip6_route.h 2003-06-13 15:51:39.000000000 +0100
-+++ linux-2.4.25/include/net/ip6_route.h 2004-06-26 11:29:29.000000000 +0100
-@@ -2,6 +2,7 @@
- #define _NET_IP6_ROUTE_H
-
- #define IP6_RT_PRIO_FW 16
-+#define IP6_RT_PRIO_MIPV6 64
- #define IP6_RT_PRIO_USER 1024
- #define IP6_RT_PRIO_ADDRCONF 256
- #define IP6_RT_PRIO_KERN 512
-@@ -40,6 +41,9 @@ extern int ipv6_route_ioctl(unsigned i
-
- extern int ip6_route_add(struct in6_rtmsg *rtmsg,
- struct nlmsghdr *);
-+
-+extern int ip6_route_del(struct in6_rtmsg *rtmsg,
-+ struct nlmsghdr *);
- extern int ip6_del_rt(struct rt6_info *,
- struct nlmsghdr *);
-
-@@ -99,7 +103,8 @@ extern rwlock_t rt6_lock;
- */
-
- static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
-- struct in6_addr *daddr)
-+ struct in6_addr *daddr,
-+ struct in6_addr *saddr)
- {
- struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
- struct rt6_info *rt = (struct rt6_info *) dst;
-@@ -107,6 +112,9 @@ static inline void ip6_dst_store(struct
- write_lock(&sk->dst_lock);
- __sk_dst_set(sk, dst);
- np->daddr_cache = daddr;
-+#ifdef CONFIG_IPV6_SUBTREES
-+ np->saddr_cache = saddr;
-+#endif
- np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
- write_unlock(&sk->dst_lock);
- }
-diff -uprN linux-2.4.25.old/include/net/ipv6.h linux-2.4.25/include/net/ipv6.h
---- linux-2.4.25.old/include/net/ipv6.h 2003-11-28 18:26:21.000000000 +0000
-+++ linux-2.4.25/include/net/ipv6.h 2004-06-26 11:29:29.000000000 +0100
-@@ -37,6 +37,7 @@
- #define NEXTHDR_ICMP 58 /* ICMP for IPv6. */
- #define NEXTHDR_NONE 59 /* No next header */
- #define NEXTHDR_DEST 60 /* Destination options header. */
-+#define NEXTHDR_MH 135 /* Mobility header, RFC 3775 */
-
- #define NEXTHDR_MAX 255
-
-@@ -145,9 +146,12 @@ struct ipv6_txoptions
- __u16 opt_flen; /* after fragment hdr */
- __u16 opt_nflen; /* before fragment hdr */
-
-+ __u8 mipv6_flags; /* flags set by MIPv6 */
-+
- struct ipv6_opt_hdr *hopopt;
- struct ipv6_opt_hdr *dst0opt;
-- struct ipv6_rt_hdr *srcrt; /* Routing Header */
-+ struct ipv6_rt_hdr *srcrt; /* Routing Header Type 0 */
-+ struct ipv6_rt_hdr *srcrt2; /* Routing Header Type 2 */
- struct ipv6_opt_hdr *auth;
- struct ipv6_opt_hdr *dst1opt;
-
-@@ -256,6 +260,38 @@ static inline int ipv6_addr_any(const st
- a->s6_addr32[2] | a->s6_addr32[3] ) == 0);
- }
-
-+static inline void ipv6_addr_prefix(struct in6_addr *pfx,
-+ const struct in6_addr *addr, int plen)
-+{
-+ /* caller must guarantee 0 <= plen <= 128 */
-+ int o = plen >> 3,
-+ b = plen & 0x7;
-+
-+ memcpy(pfx->s6_addr, addr, o);
-+ if (b != 0) {
-+ pfx->s6_addr[o] = addr->s6_addr[o] & (0xff00 >> b);
-+ o++;
-+ }
-+ if (o < 16)
-+ memset(pfx->s6_addr + o, 0, 16 - o);
-+}
-+
-+static inline int ipv6_prefix_cmp(const struct in6_addr *p1,
-+ const struct in6_addr *p2, int plen)
-+{
-+ int b = plen&0x7;
-+ int o = plen>>3;
-+ int res = 0;
-+
-+ if (o > 0)
-+ res = memcmp(&p1->s6_addr[0], &p2->s6_addr[0], o);
-+ if (res == 0 && b > 0) {
-+ __u8 m = (0xff00 >> b) & 0xff;
-+ res = (p1->s6_addr[o] & m) - (p2->s6_addr[o] & m);
-+ }
-+ return res;
-+}
-+
- /*
- * Prototypes exported by ipv6
- */
-diff -uprN linux-2.4.25.old/include/net/ipv6_tunnel.h linux-2.4.25/include/net/ipv6_tunnel.h
---- linux-2.4.25.old/include/net/ipv6_tunnel.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/include/net/ipv6_tunnel.h 2004-06-26 11:29:29.000000000 +0100
-@@ -0,0 +1,92 @@
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef _NET_IPV6_TUNNEL_H
-+#define _NET_IPV6_TUNNEL_H
-+
-+#include <linux/ipv6.h>
-+#include <linux/netdevice.h>
-+#include <linux/ipv6_tunnel.h>
-+#include <linux/skbuff.h>
-+#include <asm/atomic.h>
-+
-+/* capable of sending packets */
-+#define IP6_TNL_F_CAP_XMIT 0x10000
-+/* capable of receiving packets */
-+#define IP6_TNL_F_CAP_RCV 0x20000
-+
-+#define IP6_TNL_MAX 128
-+
-+/* IPv6 tunnel */
-+
-+struct ip6_tnl {
-+ struct ip6_tnl *next; /* next tunnel in list */
-+ struct net_device *dev; /* virtual device associated with tunnel */
-+ struct net_device_stats stat; /* statistics for tunnel device */
-+ int recursion; /* depth of hard_start_xmit recursion */
-+ struct ip6_tnl_parm parms; /* tunnel configuration paramters */
-+ struct flowi fl; /* flowi template for xmit */
-+ atomic_t refcnt; /* nr of identical tunnels used by kernel */
-+ struct socket *sock;
-+};
-+
-+#define IP6_TNL_PRE_ENCAP 0
-+#define IP6_TNL_PRE_DECAP 1
-+#define IP6_TNL_MAXHOOKS 2
-+
-+#define IP6_TNL_DROP 0
-+#define IP6_TNL_ACCEPT 1
-+
-+typedef int ip6_tnl_hookfn(struct ip6_tnl *t, struct sk_buff *skb);
-+
-+struct ip6_tnl_hook_ops {
-+ struct list_head list;
-+ unsigned int hooknum;
-+ int priority;
-+ ip6_tnl_hookfn *hook;
-+};
-+
-+enum ip6_tnl_hook_priorities {
-+ IP6_TNL_PRI_FIRST = INT_MIN,
-+ IP6_TNL_PRI_LAST = INT_MAX
-+};
-+
-+/* Tunnel encapsulation limit destination sub-option */
-+
-+struct ipv6_tlv_tnl_enc_lim {
-+ __u8 type; /* type-code for option */
-+ __u8 length; /* option length */
-+ __u8 encap_limit; /* tunnel encapsulation limit */
-+} __attribute__ ((packed));
-+
-+#ifdef __KERNEL__
-+extern int ip6ip6_tnl_create(struct ip6_tnl_parm *p, struct ip6_tnl **pt);
-+
-+extern struct ip6_tnl *ip6ip6_tnl_lookup(struct in6_addr *remote,
-+ struct in6_addr *local);
-+
-+void ip6ip6_tnl_change(struct ip6_tnl *t, struct ip6_tnl_parm *p);
-+
-+extern int ip6ip6_kernel_tnl_add(struct ip6_tnl_parm *p);
-+
-+extern int ip6ip6_kernel_tnl_del(struct ip6_tnl *t);
-+
-+extern unsigned int ip6ip6_tnl_inc_max_kdev_count(unsigned int n);
-+
-+extern unsigned int ip6ip6_tnl_dec_max_kdev_count(unsigned int n);
-+
-+extern unsigned int ip6ip6_tnl_inc_min_kdev_count(unsigned int n);
-+
-+extern unsigned int ip6ip6_tnl_dec_min_kdev_count(unsigned int n);
-+
-+extern void ip6ip6_tnl_register_hook(struct ip6_tnl_hook_ops *reg);
-+
-+extern void ip6ip6_tnl_unregister_hook(struct ip6_tnl_hook_ops *reg);
-+
-+#ifdef CONFIG_IPV6_TUNNEL
-+extern int __init ip6_tunnel_init(void);
-+extern void ip6_tunnel_cleanup(void);
-+#endif
-+#endif
-+#endif
-diff -uprN linux-2.4.25.old/include/net/mipglue.h linux-2.4.25/include/net/mipglue.h
---- linux-2.4.25.old/include/net/mipglue.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/include/net/mipglue.h 2004-06-26 11:29:29.000000000 +0100
-@@ -0,0 +1,266 @@
-+/*
-+ * Glue for Mobility support integration to IPv6
-+ *
-+ * Authors:
-+ * Antti Tuominen <ajtuomin@cc.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ *
-+ */
-+
-+#ifndef _NET_MIPGLUE_H
-+#define _NET_MIPGLUE_H
-+
-+#ifndef USE_IPV6_MOBILITY
-+#if defined(CONFIG_IPV6_MOBILITY) || defined(CONFIG_IPV6_MOBILITY_MODULE)
-+#define USE_IPV6_MOBILITY
-+#endif
-+#endif
-+
-+/* symbols to indicate whether destination options received should take
-+ * effect or not (see exthdrs.c, procrcv.c)
-+ */
-+#define MIPV6_DSTOPTS_ACCEPT 1
-+#define MIPV6_DSTOPTS_DISCARD 0
-+
-+#define MIPV6_IGN_RTR 0
-+#define MIPV6_ADD_RTR 1
-+#define MIPV6_CHG_RTR 2
-+
-+/* MIPV6: Approximate maximum for mobile IPv6 options and headers */
-+#define MIPV6_HEADERS 48
-+
-+#ifdef __KERNEL__
-+#include <net/mipv6.h>
-+#include <linux/slab.h>
-+#include <net/ipv6.h>
-+
-+struct sk_buff;
-+struct ndisc_options;
-+struct sock;
-+struct ipv6_txoptions;
-+struct flowi;
-+struct dst_entry;
-+struct in6_addr;
-+struct inet6_ifaddr;
-+
-+#ifdef USE_IPV6_MOBILITY
-+
-+/* calls a procedure from mipv6-module */
-+#define MIPV6_CALLPROC(X) if(mipv6_functions.X) mipv6_functions.X
-+
-+/* calls a function from mipv6-module, default-value if function not defined
-+ */
-+#define MIPV6_CALLFUNC(X,Y) (!mipv6_functions.X)?(Y):mipv6_functions.X
-+
-+/* sets a handler-function to process a call */
-+#define MIPV6_SETCALL(X,Y) if(mipv6_functions.X) printk("mipv6: Warning, function assigned twice!\n"); \
-+ mipv6_functions.X = Y
-+#define MIPV6_RESETCALL(X) mipv6_functions.X = NULL
-+
-+/* pointers to mipv6 callable functions */
-+struct mipv6_callable_functions {
-+ void (*mipv6_initialize_dstopt_rcv) (struct sk_buff *skb);
-+ int (*mipv6_finalize_dstopt_rcv) (int process);
-+ int (*mipv6_handle_homeaddr) (struct sk_buff *skb, int optoff);
-+ int (*mipv6_ra_rcv) (struct sk_buff *skb,
-+ struct ndisc_options *ndopts);
-+ void (*mipv6_icmp_rcv) (struct sk_buff *skb);
-+ struct ipv6_txoptions * (*mipv6_modify_txoptions) (
-+ struct sock *sk,
-+ struct sk_buff *skb,
-+ struct ipv6_txoptions *opt,
-+ struct flowi *fl,
-+ struct dst_entry **dst);
-+ void (*mipv6_set_home) (int ifindex, struct in6_addr *homeaddr,
-+ int plen, struct in6_addr *homeagent,
-+ int plen2);
-+ void (*mipv6_get_home_address) (struct in6_addr *home_addr);
-+ void (*mipv6_get_care_of_address)(struct in6_addr *homeaddr,
-+ struct in6_addr *coa);
-+ int (*mipv6_is_home_addr)(struct in6_addr *addr);
-+ void (*mipv6_change_router)(void);
-+ void (*mipv6_check_dad)(struct in6_addr *home_addr);
-+ void (*mipv6_icmp_swap_addrs)(struct sk_buff *skb);
-+ int (*mipv6_forward)(struct sk_buff *skb);
-+ int (*mipv6_mn_ha_probe)(struct inet6_ifaddr *ifp, u8 *lladdr);
-+};
-+
-+extern struct mipv6_callable_functions mipv6_functions;
-+
-+extern void mipv6_invalidate_calls(void);
-+
-+extern int mipv6_handle_dstopt(struct sk_buff *skb, int optoff);
-+
-+static inline int
-+ndisc_mip_mn_ha_probe(struct inet6_ifaddr *ifp, u8 *lladdr)
-+{
-+ return MIPV6_CALLFUNC(mipv6_mn_ha_probe, 0)(ifp, lladdr);
-+}
-+
-+/* Must only be called for HA, no checks here */
-+static inline int ip6_mipv6_forward(struct sk_buff *skb)
-+{
-+ return MIPV6_CALLFUNC(mipv6_forward, 0)(skb);
-+}
-+
-+/*
-+ * Avoid adding new default routers if the old one is still in use
-+ */
-+
-+static inline int ndisc_mipv6_ra_rcv(struct sk_buff *skb,
-+ struct ndisc_options *ndopts)
-+{
-+ return MIPV6_CALLFUNC(mipv6_ra_rcv, MIPV6_ADD_RTR)(skb, ndopts);
-+}
-+
-+static inline int ipv6_chk_mip_home_addr(struct in6_addr *addr)
-+{
-+ return MIPV6_CALLFUNC(mipv6_is_home_addr, 0)(addr);
-+}
-+
-+static inline void ndisc_mipv6_change_router(int change_rtr)
-+{
-+ if (change_rtr == MIPV6_CHG_RTR)
-+ MIPV6_CALLPROC(mipv6_change_router)();
-+}
-+
-+static inline void ndisc_check_mipv6_dad(struct in6_addr *target)
-+{
-+ MIPV6_CALLPROC(mipv6_check_dad)(target);
-+}
-+
-+static inline void icmpv6_swap_mipv6_addrs(struct sk_buff *skb)
-+{
-+ MIPV6_CALLPROC(mipv6_icmp_swap_addrs)(skb);
-+}
-+
-+static inline void mipv6_icmp_rcv(struct sk_buff *skb)
-+{
-+ MIPV6_CALLPROC(mipv6_icmp_rcv)(skb);
-+}
-+
-+static inline int tcp_v6_get_mipv6_header_len(void)
-+{
-+ return MIPV6_HEADERS;
-+}
-+
-+static inline struct in6_addr *
-+mipv6_get_fake_hdr_daddr(struct in6_addr *hdaddr, struct in6_addr *daddr)
-+{
-+ return daddr;
-+}
-+
-+static inline void
-+addrconf_set_mipv6_mn_home(int ifindex, struct in6_addr *homeaddr, int plen,
-+ struct in6_addr *homeagent, int plen2)
-+{
-+ MIPV6_CALLPROC(mipv6_set_home)(ifindex, homeaddr, plen, homeagent, plen2);
-+}
-+
-+static inline void addrconf_get_mipv6_home_address(struct in6_addr *saddr)
-+{
-+ MIPV6_CALLPROC(mipv6_get_home_address)(saddr);
-+}
-+
-+static inline struct ipv6_txoptions *
-+ip6_add_mipv6_txoptions(struct sock *sk, struct sk_buff *skb,
-+ struct ipv6_txoptions *opt, struct flowi *fl,
-+ struct dst_entry **dst)
-+{
-+ return MIPV6_CALLFUNC(mipv6_modify_txoptions, opt)(sk, skb, opt, fl, dst);
-+
-+}
-+
-+static inline void
-+ip6_mark_mipv6_packet(struct ipv6_txoptions *txopt, struct sk_buff *skb)
-+{
-+ struct inet6_skb_parm *opt;
-+ if (txopt) {
-+ opt = (struct inet6_skb_parm *)skb->cb;
-+ opt->mipv6_flags = txopt->mipv6_flags;
-+ }
-+}
-+
-+static inline void
-+ip6_free_mipv6_txoptions(struct ipv6_txoptions *opt,
-+ struct ipv6_txoptions *orig_opt)
-+{
-+ if (opt && opt != orig_opt)
-+ kfree(opt);
-+}
-+
-+#else /* USE_IPV6_MOBILITY */
-+
-+#define mipv6_handle_dstopt ip6_tlvopt_unknown
-+
-+static inline int
-+ndisc_mip_mn_ha_probe(struct inet6_ifaddr *ifp, u8 *lladdr)
-+{
-+ return 0;
-+}
-+
-+static inline int ip6_mipv6_forward(struct sk_buff *skb)
-+{
-+ return 0;
-+}
-+
-+static inline int ndisc_mipv6_ra_rcv(struct sk_buff *skb,
-+ struct ndisc_options *ndopts)
-+{
-+ return MIPV6_ADD_RTR;
-+}
-+
-+static inline int ipv6_chk_mip_home_addr(struct in6_addr *addr)
-+{
-+ return 0;
-+}
-+
-+static inline void ndisc_mipv6_change_router(int change_rtr) {}
-+
-+static inline void ndisc_check_mipv6_dad(struct in6_addr *target) {}
-+
-+static inline void icmpv6_swap_mipv6_addrs(struct sk_buff *skb) {}
-+
-+static inline void mipv6_icmp_rcv(struct sk_buff *skb) {}
-+
-+static inline int tcp_v6_get_mipv6_header_len(void)
-+{
-+ return 0;
-+}
-+
-+static inline struct in6_addr *
-+mipv6_get_fake_hdr_daddr(struct in6_addr *hdaddr, struct in6_addr *daddr)
-+{
-+ return hdaddr;
-+}
-+
-+static inline void
-+addrconf_set_mipv6_mn_home(int ifindex, struct in6_addr *homeaddr, int plen,
-+ struct in6_addr *homeagent, int plen2) {}
-+
-+static inline void addrconf_get_mipv6_home_address(struct in6_addr *saddr) {}
-+
-+static inline struct ipv6_txoptions *
-+ip6_add_mipv6_txoptions(struct sock *sk, struct sk_buff *skb,
-+ struct ipv6_txoptions *opt, struct flowi *fl,
-+ struct dst_entry **dst)
-+{
-+ return opt;
-+}
-+
-+static inline void
-+ip6_mark_mipv6_packet(struct ipv6_txoptions *txopt, struct sk_buff *skb) {}
-+
-+static inline void
-+ip6_free_mipv6_txoptions(struct ipv6_txoptions *opt,
-+ struct ipv6_txoptions *orig_opt) {}
-+
-+#endif /* USE_IPV6_MOBILITY */
-+#endif /* __KERNEL__ */
-+#endif /* _NET_MIPGLUE_H */
-diff -uprN linux-2.4.25.old/include/net/mipv6.h linux-2.4.25/include/net/mipv6.h
---- linux-2.4.25.old/include/net/mipv6.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/include/net/mipv6.h 2004-06-26 11:29:29.000000000 +0100
-@@ -0,0 +1,258 @@
-+/*
-+ * Mobile IPv6 header-file
-+ *
-+ * Authors:
-+ * Sami Kivisaari <skivisaa@cc.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ *
-+ */
-+
-+#ifndef _NET_MIPV6_H
-+#define _NET_MIPV6_H
-+
-+#include <linux/types.h>
-+#include <asm/byteorder.h>
-+#include <linux/in6.h>
-+
-+/*
-+ *
-+ * Mobile IPv6 Protocol constants
-+ *
-+ */
-+#define DHAAD_RETRIES 4 /* transmissions */
-+#define INITIAL_BINDACK_TIMEOUT 1 /* seconds */
-+#define INITIAL_DHAAD_TIMEOUT 3 /* seconds */
-+#define INITIAL_SOLICIT_TIMER 3 /* seconds */
-+#define MAX_BINDACK_TIMEOUT 32 /* seconds */
-+#define MAX_NONCE_LIFE 240 /* seconds */
-+#define MAX_TOKEN_LIFE 210 /* seconds */
-+#define MAX_RR_BINDING_LIFE 420 /* seconds */
-+#define MAX_UPDATE_RATE 3 /* 1/s (min delay=1s) */
-+#define PREFIX_ADV_RETRIES 3 /* transmissions */
-+#define PREFIX_ADV_TIMEOUT 3 /* seconds */
-+
-+#define MAX_FAST_UPDATES 5 /* transmissions */
-+#define MAX_PFX_ADV_DELAY 1000 /* seconds */
-+#define SLOW_UPDATE_RATE 10 /* 1/10s (max delay=10s)*/
-+#define INITIAL_BINDACK_DAD_TIMEOUT 2 /* seconds */
-+
-+/*
-+ *
-+ * Mobile IPv6 (RFC 3775) Protocol configuration variable defaults
-+ *
-+ */
-+#define DefHomeRtrAdvInterval 1000 /* seconds */
-+#define DefMaxMobPfxAdvInterval 86400 /* seconds */
-+#define DefMinDelayBetweenRAs 3 /* seconds (min 0.03) */
-+#define DefMinMobPfxAdvInterval 600 /* seconds */
-+#define DefInitialBindackTimeoutFirstReg 1.5 /* seconds */
-+
-+/* This is not actually specified in the draft, but is needed to avoid
-+ * prefix solicitation storm when valid lifetime of a prefix is smaller
-+ * than MAX_PFX_ADV_DELAY
-+ */
-+#define MIN_PFX_SOL_DELAY 5 /* seconds */
-+
-+/* Mobile IPv6 ICMP types */
-+/*
-+ * Official numbers from RFC 3775
-+ */
-+#define MIPV6_DHAAD_REQUEST 144
-+#define MIPV6_DHAAD_REPLY 145
-+#define MIPV6_PREFIX_SOLICIT 146
-+#define MIPV6_PREFIX_ADV 147
-+
-+/* Binding update flag codes */
-+#define MIPV6_BU_F_ACK 0x80
-+#define MIPV6_BU_F_HOME 0x40
-+#define MIPV6_BU_F_LLADDR 0x20
-+#define MIPV6_BU_F_KEYMGM 0x10
-+
-+/* Binding ackknowledgment flag codes */
-+#define MIPV6_BA_F_KEYMGM 0x80
-+
-+/* Binding error status */
-+#define MIPV6_BE_HAO_WO_BINDING 1
-+#define MIPV6_BE_UNKNOWN_MH_TYPE 2
-+
-+/* Mobility Header */
-+struct mipv6_mh
-+{
-+ __u8 payload; /* Payload Protocol */
-+ __u8 length; /* MH Length */
-+ __u8 type; /* MH Type */
-+ __u8 reserved; /* Reserved */
-+ __u16 checksum; /* Checksum */
-+ __u8 data[0]; /* Message specific data */
-+} __attribute__ ((packed));
-+
-+/* Mobility Header type */
-+#define IPPROTO_MOBILITY 135 /* RFC 3775*/
-+/* Mobility Header Message Types */
-+
-+#define MIPV6_MH_BRR 0
-+#define MIPV6_MH_HOTI 1
-+#define MIPV6_MH_COTI 2
-+#define MIPV6_MH_HOT 3
-+#define MIPV6_MH_COT 4
-+#define MIPV6_MH_BU 5
-+#define MIPV6_MH_BA 6
-+#define MIPV6_MH_BE 7
-+
-+/*
-+ * Status codes for Binding Acknowledgements
-+ */
-+#define SUCCESS 0
-+#define REASON_UNSPECIFIED 128
-+#define ADMINISTRATIVELY_PROHIBITED 129
-+#define INSUFFICIENT_RESOURCES 130
-+#define HOME_REGISTRATION_NOT_SUPPORTED 131
-+#define NOT_HOME_SUBNET 132
-+#define NOT_HA_FOR_MN 133
-+#define DUPLICATE_ADDR_DETECT_FAIL 134
-+#define SEQUENCE_NUMBER_OUT_OF_WINDOW 135
-+#define EXPIRED_HOME_NONCE_INDEX 136
-+#define EXPIRED_CAREOF_NONCE_INDEX 137
-+#define EXPIRED_NONCES 138
-+#define REG_TYPE_CHANGE_FORBIDDEN 139
-+/*
-+ * Values for mipv6_flags in struct inet6_skb_parm
-+ */
-+
-+#define MIPV6_RCV_TUNNEL 0x1
-+#define MIPV6_SND_HAO 0x2
-+#define MIPV6_SND_BU 0x4
-+
-+/*
-+ * Mobility Header Message structures
-+ */
-+
-+struct mipv6_mh_brr
-+{
-+ __u16 reserved;
-+ /* Mobility options */
-+} __attribute__ ((packed));
-+
-+struct mipv6_mh_bu
-+{
-+ __u16 sequence; /* sequence number of BU */
-+ __u8 flags; /* flags */
-+ __u8 reserved; /* reserved bits */
-+ __u16 lifetime; /* lifetime of BU */
-+ /* Mobility options */
-+} __attribute__ ((packed));
-+
-+struct mipv6_mh_ba
-+{
-+ __u8 status; /* statuscode */
-+ __u8 reserved; /* reserved bits */
-+ __u16 sequence; /* sequence number of BA */
-+ __u16 lifetime; /* lifetime in CN's bcache */
-+ /* Mobility options */
-+} __attribute__ ((packed));
-+
-+struct mipv6_mh_be
-+{
-+ __u8 status;
-+ __u8 reserved;
-+ struct in6_addr home_addr;
-+ /* Mobility options */
-+} __attribute__ ((packed));
-+
-+struct mipv6_mh_addr_ti
-+{
-+ __u16 reserved; /* Reserved */
-+ u_int8_t init_cookie[8]; /* HoT/CoT Init Cookie */
-+ /* Mobility options */
-+} __attribute__ ((packed));
-+
-+struct mipv6_mh_addr_test
-+{
-+ __u16 nonce_index; /* Home/Care-of Nonce Index */
-+ u_int8_t init_cookie[8]; /* HoT/CoT Init Cookie */
-+ u_int8_t kgen_token[8]; /* Home/Care-of key generation token */
-+ /* Mobility options */
-+} __attribute__ ((packed));
-+
-+/*
-+ * Mobility Options for various MH types.
-+ */
-+#define MIPV6_OPT_PAD1 0x00
-+#define MIPV6_OPT_PADN 0x01
-+#define MIPV6_OPT_BIND_REFRESH_ADVICE 0x02
-+#define MIPV6_OPT_ALTERNATE_COA 0x03
-+#define MIPV6_OPT_NONCE_INDICES 0x04
-+#define MIPV6_OPT_AUTH_DATA 0x05
-+
-+#define MIPV6_SEQ_GT(x,y) \
-+ ((short int)(((__u16)(x)) - ((__u16)(y))) > 0)
-+
-+/*
-+ * Mobility Option structures
-+ */
-+
-+struct mipv6_mo
-+{
-+ __u8 type;
-+ __u8 length;
-+ __u8 value[0]; /* type specific data */
-+} __attribute__ ((packed));
-+
-+struct mipv6_mo_pad1
-+{
-+ __u8 type;
-+} __attribute__ ((packed));
-+
-+struct mipv6_mo_padn
-+{
-+ __u8 type;
-+ __u8 length;
-+ __u8 data[0];
-+} __attribute__ ((packed));
-+
-+struct mipv6_mo_alt_coa
-+{
-+ __u8 type;
-+ __u8 length;
-+ struct in6_addr addr; /* alternate care-of-address */
-+} __attribute__ ((packed));
-+
-+struct mipv6_mo_nonce_indices
-+{
-+ __u8 type;
-+ __u8 length;
-+ __u16 home_nonce_i; /* Home Nonce Index */
-+ __u16 careof_nonce_i; /* Careof Nonce Index */
-+} __attribute__ ((packed));
-+
-+struct mipv6_mo_bauth_data
-+{
-+ __u8 type;
-+ __u8 length;
-+ __u8 data[0];
-+} __attribute__ ((packed));
-+
-+struct mipv6_mo_br_advice
-+{
-+ __u8 type;
-+ __u8 length;
-+ __u16 refresh_interval; /* Refresh Interval */
-+} __attribute__ ((packed));
-+
-+/*
-+ * Home Address Destination Option structure
-+ */
-+struct mipv6_dstopt_homeaddr
-+{
-+ __u8 type; /* type-code for option */
-+ __u8 length; /* option length */
-+ struct in6_addr addr; /* home address */
-+} __attribute__ ((packed));
-+
-+#endif /* _NET_MIPV6_H */
-diff -uprN linux-2.4.25.old/include/net/ndisc.h linux-2.4.25/include/net/ndisc.h
---- linux-2.4.25.old/include/net/ndisc.h 2002-11-28 23:53:15.000000000 +0000
-+++ linux-2.4.25/include/net/ndisc.h 2004-06-26 11:29:29.000000000 +0100
-@@ -21,6 +21,10 @@
- #define ND_OPT_REDIRECT_HDR 4
- #define ND_OPT_MTU 5
-
-+/* Mobile IPv6 specific ndisc options */
-+#define ND_OPT_RTR_ADV_INTERVAL 7
-+#define ND_OPT_HOME_AGENT_INFO 8
-+
- #define MAX_RTR_SOLICITATION_DELAY HZ
-
- #define ND_REACHABLE_TIME (30*HZ)
-@@ -57,7 +61,7 @@ struct nd_opt_hdr {
- } __attribute__((__packed__));
-
- struct ndisc_options {
-- struct nd_opt_hdr *nd_opt_array[7];
-+ struct nd_opt_hdr *nd_opt_array[10];
- struct nd_opt_hdr *nd_opt_piend;
- };
-
-@@ -67,6 +71,8 @@ struct ndisc_options {
- #define nd_opts_pi_end nd_opt_piend
- #define nd_opts_rh nd_opt_array[ND_OPT_REDIRECT_HDR]
- #define nd_opts_mtu nd_opt_array[ND_OPT_MTU]
-+#define nd_opts_rai nd_opt_array[ND_OPT_RTR_ADV_INTERVAL]
-+#define nd_opts_hai nd_opt_array[ND_OPT_HOME_AGENT_INFO]
-
- extern struct nd_opt_hdr *ndisc_next_option(struct nd_opt_hdr *cur, struct nd_opt_hdr *end);
- extern struct ndisc_options *ndisc_parse_options(u8 *opt, int opt_len, struct ndisc_options *ndopts);
-@@ -83,6 +89,15 @@ extern void ndisc_send_ns(struct net_d
- struct in6_addr *daddr,
- struct in6_addr *saddr);
-
-+extern void ndisc_send_na(struct net_device *dev,
-+ struct neighbour *neigh,
-+ struct in6_addr *daddr,
-+ struct in6_addr *solicited_addr,
-+ int router,
-+ int solicited,
-+ int override,
-+ int inc_opt);
-+
- extern void ndisc_send_rs(struct net_device *dev,
- struct in6_addr *saddr,
- struct in6_addr *daddr);
-diff -uprN linux-2.4.25.old/include/net/sock.h linux-2.4.25/include/net/sock.h
---- linux-2.4.25.old/include/net/sock.h 2004-02-18 13:36:32.000000000 +0000
-+++ linux-2.4.25/include/net/sock.h 2004-06-26 11:29:30.000000000 +0100
-@@ -149,7 +149,9 @@ struct ipv6_pinfo {
- struct in6_addr rcv_saddr;
- struct in6_addr daddr;
- struct in6_addr *daddr_cache;
--
-+#if defined(CONFIG_IPV6_SUBTREES)
-+ struct in6_addr *saddr_cache;
-+#endif
- __u32 flow_label;
- __u32 frag_size;
- int hop_limit;
-diff -uprN linux-2.4.25.old/net/Makefile linux-2.4.25/net/Makefile
---- linux-2.4.25.old/net/Makefile 2004-06-26 11:22:00.000000000 +0100
-+++ linux-2.4.25/net/Makefile 2004-06-26 11:29:30.000000000 +0100
-@@ -7,7 +7,7 @@
-
- O_TARGET := network.o
-
--mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda bluetooth atm netlink sched core sctp
-+mod-subdirs := ipv4/netfilter ipv6/netfilter ipx irda bluetooth atm netlink sched core sctp ipv6
- export-objs := netsyms.o
-
- subdir-y := core ethernet
-@@ -25,6 +25,7 @@ subdir-$(CONFIG_IP_SCTP) += sctp
- ifneq ($(CONFIG_IPV6),n)
- ifneq ($(CONFIG_IPV6),)
- subdir-$(CONFIG_NETFILTER) += ipv6/netfilter
-+subdir-$(CONFIG_IPV6_MOBILITY) += ipv6/mobile_ip6
- endif
- endif
-
-diff -uprN linux-2.4.25.old/net/core/neighbour.c linux-2.4.25/net/core/neighbour.c
---- linux-2.4.25.old/net/core/neighbour.c 2004-02-18 13:36:32.000000000 +0000
-+++ linux-2.4.25/net/core/neighbour.c 2004-06-26 11:29:30.000000000 +0100
-@@ -386,7 +386,7 @@ struct pneigh_entry * pneigh_lookup(stru
- if (!creat)
- return NULL;
-
-- n = kmalloc(sizeof(*n) + key_len, GFP_KERNEL);
-+ n = kmalloc(sizeof(*n) + key_len, GFP_ATOMIC);
- if (n == NULL)
- return NULL;
-
-diff -uprN linux-2.4.25.old/net/ipv6/Config.in linux-2.4.25/net/ipv6/Config.in
---- linux-2.4.25.old/net/ipv6/Config.in 2001-12-21 17:42:05.000000000 +0000
-+++ linux-2.4.25/net/ipv6/Config.in 2004-06-26 11:29:30.000000000 +0100
-@@ -1,10 +1,16 @@
- #
- # IPv6 configuration
- #
--
-+bool ' IPv6: routing by source address (EXPERIMENTAL)' CONFIG_IPV6_SUBTREES
- #bool ' IPv6: flow policy support' CONFIG_RT6_POLICY
- #bool ' IPv6: firewall support' CONFIG_IPV6_FIREWALL
-
-+if [ "$CONFIG_IPV6" != "n" ]; then
-+ dep_tristate ' IPv6: IPv6 over IPv6 Tunneling (EXPERIMENTAL)' CONFIG_IPV6_TUNNEL $CONFIG_IPV6
-+fi
-+
-+source net/ipv6/mobile_ip6/Config.in
-+
- if [ "$CONFIG_NETFILTER" != "n" ]; then
- source net/ipv6/netfilter/Config.in
- fi
-diff -uprN linux-2.4.25.old/net/ipv6/Makefile linux-2.4.25/net/ipv6/Makefile
---- linux-2.4.25.old/net/ipv6/Makefile 2003-11-28 18:26:21.000000000 +0000
-+++ linux-2.4.25/net/ipv6/Makefile 2004-06-26 11:29:30.000000000 +0100
-@@ -6,18 +6,28 @@
- # unless it's something special (ie not a .c file).
- #
-
-+export-objs := ipv6_syms.o ipv6_tunnel.o
-
--O_TARGET := ipv6.o
-+#list-multi := ipv6.o ipv6_tunnel.o
-
--obj-y := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o sit.o \
-- route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \
-- protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
-- exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \
-- ip6_flowlabel.o ipv6_syms.o
-+ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \
-+ sit.o route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o \
-+ raw.o protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
-+ exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \
-+ ip6_flowlabel.o ipv6_syms.o
-+
-+ifneq ($(CONFIG_IPV6_MOBILITY),n)
-+ifneq ($(CONFIG_IPV6_MOBILITY),)
-+ipv6-objs += mipglue.o
-+endif
-+endif
-
--export-objs := ipv6_syms.o
-+obj-$(CONFIG_IPV6) += ipv6.o
-+obj-$(CONFIG_IPV6_TUNNEL) += ipv6_tunnel.o
-+
-+ipv6.o: $(ipv6-objs)
-+ $(LD) -r -o $@ $(ipv6-objs)
-
--obj-m := $(O_TARGET)
-
- #obj-$(CONFIG_IPV6_FIREWALL) += ip6_fw.o
-
-diff -uprN linux-2.4.25.old/net/ipv6/addrconf.c linux-2.4.25/net/ipv6/addrconf.c
---- linux-2.4.25.old/net/ipv6/addrconf.c 2003-11-28 18:26:21.000000000 +0000
-+++ linux-2.4.25/net/ipv6/addrconf.c 2004-06-26 11:29:30.000000000 +0100
-@@ -68,6 +68,8 @@
-
- #include <asm/uaccess.h>
-
-+#include <net/mipglue.h>
-+
- #define IPV6_MAX_ADDRESSES 16
-
- /* Set to 3 to get tracing... */
-@@ -103,9 +105,9 @@ static spinlock_t addrconf_verify_lock =
-
- static int addrconf_ifdown(struct net_device *dev, int how);
-
--static void addrconf_dad_start(struct inet6_ifaddr *ifp, int flags);
-+void addrconf_dad_start(struct inet6_ifaddr *ifp, int flags);
- static void addrconf_dad_timer(unsigned long data);
--static void addrconf_dad_completed(struct inet6_ifaddr *ifp);
-+void addrconf_dad_completed(struct inet6_ifaddr *ifp);
- static void addrconf_rs_timer(unsigned long data);
- static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
-
-@@ -330,38 +332,6 @@ static struct inet6_dev * ipv6_find_idev
- return idev;
- }
-
--void ipv6_addr_prefix(struct in6_addr *prefix,
-- struct in6_addr *addr, int prefix_len)
--{
-- unsigned long mask;
-- int ncopy, nbits;
--
-- memset(prefix, 0, sizeof(*prefix));
--
-- if (prefix_len <= 0)
-- return;
-- if (prefix_len > 128)
-- prefix_len = 128;
--
-- ncopy = prefix_len / 32;
-- switch (ncopy) {
-- case 4: prefix->s6_addr32[3] = addr->s6_addr32[3];
-- case 3: prefix->s6_addr32[2] = addr->s6_addr32[2];
-- case 2: prefix->s6_addr32[1] = addr->s6_addr32[1];
-- case 1: prefix->s6_addr32[0] = addr->s6_addr32[0];
-- case 0: break;
-- }
-- nbits = prefix_len % 32;
-- if (nbits == 0)
-- return;
--
-- mask = ~((1 << (32 - nbits)) - 1);
-- mask = htonl(mask);
--
-- prefix->s6_addr32[ncopy] = addr->s6_addr32[ncopy] & mask;
--}
--
--
- static void dev_forward_change(struct inet6_dev *idev)
- {
- struct net_device *dev;
-@@ -513,7 +483,7 @@ ipv6_add_addr(struct inet6_dev *idev, co
-
- /* This function wants to get referenced ifp and releases it before return */
-
--static void ipv6_del_addr(struct inet6_ifaddr *ifp)
-+void ipv6_del_addr(struct inet6_ifaddr *ifp)
- {
- struct inet6_ifaddr *ifa, **ifap;
- struct inet6_dev *idev = ifp->idev;
-@@ -662,6 +632,12 @@ out:
- if (match)
- in6_ifa_put(match);
-
-+ /* The home address is always used as source address in
-+ * MIPL mobile IPv6
-+ */
-+ if (scope != IFA_HOST && scope != IFA_LINK)
-+ addrconf_get_mipv6_home_address(saddr);
-+
- return err;
- }
-
-@@ -815,7 +791,7 @@ void addrconf_leave_solict(struct net_de
- }
-
-
--static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
-+int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
- {
- switch (dev->type) {
- case ARPHRD_ETHER:
-@@ -840,7 +816,7 @@ static int ipv6_generate_eui64(u8 *eui,
- return -1;
- }
-
--static int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev)
-+int ipv6_inherit_eui64(u8 *eui, struct inet6_dev *idev)
- {
- int err = -1;
- struct inet6_ifaddr *ifp;
-@@ -1407,6 +1383,24 @@ static void addrconf_sit_config(struct n
- sit_route_add(dev);
- }
-
-+/**
-+ * addrconf_ipv6_tunnel_config - configure IPv6 tunnel device
-+ * @dev: tunnel device
-+ **/
-+
-+static void addrconf_ipv6_tunnel_config(struct net_device *dev)
-+{
-+ struct inet6_dev *idev;
-+
-+ ASSERT_RTNL();
-+
-+ /* Assign inet6_dev structure to tunnel device */
-+ if ((idev = ipv6_find_idev(dev)) == NULL) {
-+ printk(KERN_DEBUG "init ipv6 tunnel: add_dev failed\n");
-+ return;
-+ }
-+}
-+
-
- int addrconf_notify(struct notifier_block *this, unsigned long event,
- void * data)
-@@ -1421,6 +1415,10 @@ int addrconf_notify(struct notifier_bloc
- addrconf_sit_config(dev);
- break;
-
-+ case ARPHRD_TUNNEL6:
-+ addrconf_ipv6_tunnel_config(dev);
-+ break;
-+
- case ARPHRD_LOOPBACK:
- init_loopback(dev);
- break;
-@@ -1602,7 +1600,7 @@ out:
- /*
- * Duplicate Address Detection
- */
--static void addrconf_dad_start(struct inet6_ifaddr *ifp, int flags)
-+void addrconf_dad_start(struct inet6_ifaddr *ifp, int flags)
- {
- struct net_device *dev;
- unsigned long rand_num;
-@@ -1667,7 +1665,7 @@ static void addrconf_dad_timer(unsigned
- in6_ifa_put(ifp);
- }
-
--static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
-+void addrconf_dad_completed(struct inet6_ifaddr *ifp)
- {
- struct net_device * dev = ifp->idev->dev;
-
-@@ -1676,7 +1674,7 @@ static void addrconf_dad_completed(struc
- */
-
- ipv6_ifa_notify(RTM_NEWADDR, ifp);
--
-+ notifier_call_chain(&inet6addr_chain,NETDEV_UP,ifp);
- /* If added prefix is link local and forwarding is off,
- start sending router solicitations.
- */
-@@ -1877,8 +1875,20 @@ inet6_rtm_newaddr(struct sk_buff *skb, s
- if (rta[IFA_LOCAL-1]) {
- if (pfx && memcmp(pfx, RTA_DATA(rta[IFA_LOCAL-1]), sizeof(*pfx)))
- return -EINVAL;
-+ if (ifm->ifa_flags & IFA_F_HOMEADDR && !rta[IFA_HOMEAGENT-1])
-+ return -EINVAL;
- pfx = RTA_DATA(rta[IFA_LOCAL-1]);
- }
-+ if (rta[IFA_HOMEAGENT-1]) {
-+ struct in6_addr *ha;
-+ if (pfx == NULL || !(ifm->ifa_flags & IFA_F_HOMEADDR))
-+ return -EINVAL;
-+ if (RTA_PAYLOAD(rta[IFA_HOMEAGENT-1]) < sizeof(*ha))
-+ return -EINVAL;
-+ ha = RTA_DATA(rta[IFA_HOMEAGENT-1]);
-+ addrconf_set_mipv6_mn_home(ifm->ifa_index, pfx, ifm->ifa_prefixlen,
-+ ha, ifm->ifa_prefixlen);
-+ }
- if (pfx == NULL)
- return -EINVAL;
-
-diff -uprN linux-2.4.25.old/net/ipv6/af_inet6.c linux-2.4.25/net/ipv6/af_inet6.c
---- linux-2.4.25.old/net/ipv6/af_inet6.c 2003-11-28 18:26:21.000000000 +0000
-+++ linux-2.4.25/net/ipv6/af_inet6.c 2004-06-26 11:29:30.000000000 +0100
-@@ -58,6 +58,9 @@
- #include <net/transp_v6.h>
- #include <net/ip6_route.h>
- #include <net/addrconf.h>
-+#ifdef CONFIG_IPV6_TUNNEL
-+#include <net/ipv6_tunnel.h>
-+#endif
-
- #include <asm/uaccess.h>
- #include <asm/system.h>
-@@ -646,6 +649,11 @@ static int __init inet6_init(void)
- err = ndisc_init(&inet6_family_ops);
- if (err)
- goto ndisc_fail;
-+#ifdef CONFIG_IPV6_TUNNEL
-+ err = ip6_tunnel_init();
-+ if (err)
-+ goto ip6_tunnel_fail;
-+#endif
- err = igmp6_init(&inet6_family_ops);
- if (err)
- goto igmp_fail;
-@@ -698,6 +706,10 @@ proc_raw6_fail:
- #endif
- igmp_fail:
- ndisc_cleanup();
-+#ifdef CONFIG_IPV6_TUNNEL
-+ ip6_tunnel_cleanup();
-+ip6_tunnel_fail:
-+#endif
- ndisc_fail:
- icmpv6_cleanup();
- icmp_fail:
-@@ -730,6 +742,9 @@ static void inet6_exit(void)
- ip6_route_cleanup();
- ipv6_packet_cleanup();
- igmp6_cleanup();
-+#ifdef CONFIG_IPV6_TUNNEL
-+ ip6_tunnel_cleanup();
-+#endif
- ndisc_cleanup();
- icmpv6_cleanup();
- #ifdef CONFIG_SYSCTL
-diff -uprN linux-2.4.25.old/net/ipv6/exthdrs.c linux-2.4.25/net/ipv6/exthdrs.c
---- linux-2.4.25.old/net/ipv6/exthdrs.c 2003-08-25 12:44:44.000000000 +0100
-+++ linux-2.4.25/net/ipv6/exthdrs.c 2004-06-26 11:29:30.000000000 +0100
-@@ -41,6 +41,9 @@
- #include <net/ip6_route.h>
- #include <net/addrconf.h>
-
-+#include <net/mipglue.h>
-+#include <net/mipv6.h>
-+
- #include <asm/uaccess.h>
-
- /*
-@@ -160,7 +163,8 @@ bad:
- *****************************/
-
- struct tlvtype_proc tlvprocdestopt_lst[] = {
-- /* No destination options are defined now */
-+ /* Mobility Support destination options */
-+ {MIPV6_TLV_HOMEADDR, mipv6_handle_dstopt},
- {-1, NULL}
- };
-
-@@ -210,6 +214,7 @@ static int ipv6_routing_header(struct sk
-
- struct ipv6_rt_hdr *hdr;
- struct rt0_hdr *rthdr;
-+ struct rt2_hdr *rt2hdr;
-
- if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
- !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
-@@ -225,17 +230,25 @@ static int ipv6_routing_header(struct sk
- kfree_skb(skb);
- return -1;
- }
--
-+ /* Silently discard invalid packets containing RTH type 2 */
-+ if (hdr->type == IPV6_SRCRT_TYPE_2 &&
-+ (hdr->hdrlen != 2 || hdr->segments_left != 1)) {
-+ kfree_skb(skb);
-+ return -1;
-+ }
- looped_back:
- if (hdr->segments_left == 0) {
-- opt->srcrt = skb->h.raw - skb->nh.raw;
-+ if (hdr->type == IPV6_SRCRT_TYPE_0)
-+ opt->srcrt = skb->h.raw - skb->nh.raw;
-+ else if (hdr->type == IPV6_SRCRT_TYPE_2)
-+ opt->srcrt2 = skb->h.raw - skb->nh.raw;
- skb->h.raw += (hdr->hdrlen + 1) << 3;
- opt->dst0 = opt->dst1;
- opt->dst1 = 0;
- return (&hdr->nexthdr) - skb->nh.raw;
- }
-
-- if (hdr->type != IPV6_SRCRT_TYPE_0) {
-+ if (hdr->type != IPV6_SRCRT_TYPE_0 && hdr->type != IPV6_SRCRT_TYPE_2) {
- icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
- return -1;
- }
-@@ -275,9 +288,20 @@ looped_back:
-
- i = n - --hdr->segments_left;
-
-- rthdr = (struct rt0_hdr *) hdr;
-- addr = rthdr->addr;
-- addr += i - 1;
-+ if (hdr->type == IPV6_SRCRT_TYPE_0) {
-+ rthdr = (struct rt0_hdr *) hdr;
-+ addr = rthdr->addr;
-+ addr += i - 1;
-+ } else {
-+ /* check that address is this node's home address */
-+ rt2hdr = (struct rt2_hdr *) hdr;
-+ addr = &rt2hdr->addr;
-+ if (!ipv6_chk_addr(addr, NULL) ||
-+ !ipv6_chk_mip_home_addr(addr)) {
-+ kfree_skb(skb);
-+ return -1;
-+ }
-+ }
-
- addr_type = ipv6_addr_type(addr);
-
-@@ -330,6 +354,10 @@ looped_back:
- temporary (or permanent) backdoor.
- If listening socket set IPV6_RTHDR to 2, then we invert header.
- --ANK (980729)
-+
-+ By the Mobile IPv6 specification Type 2 routing header MUST NOT be
-+ inverted.
-+ --AJT (20020917)
- */
-
- struct ipv6_txoptions *
-@@ -352,6 +380,18 @@ ipv6_invert_rthdr(struct sock *sk, struc
- struct ipv6_txoptions *opt;
- int hdrlen = ipv6_optlen(hdr);
-
-+ if (hdr->type == IPV6_SRCRT_TYPE_2) {
-+ opt = sock_kmalloc(sk, sizeof(*opt) + hdrlen, GFP_ATOMIC);
-+ if (opt == NULL)
-+ return NULL;
-+ memset(opt, 0, sizeof(*opt));
-+ opt->tot_len = sizeof(*opt) + hdrlen;
-+ opt->srcrt = (void*)(opt+1);
-+ opt->opt_nflen = hdrlen;
-+ memcpy(opt->srcrt, hdr, sizeof(struct rt2_hdr));
-+ return opt;
-+ }
-+
- if (hdr->segments_left ||
- hdr->type != IPV6_SRCRT_TYPE_0 ||
- hdr->hdrlen & 0x01)
-@@ -622,8 +662,18 @@ u8 *ipv6_build_nfrag_opts(struct sk_buff
- if (opt) {
- if (opt->dst0opt)
- prev_hdr = ipv6_build_exthdr(skb, prev_hdr, NEXTHDR_DEST, opt->dst0opt);
-- if (opt->srcrt)
-- prev_hdr = ipv6_build_rthdr(skb, prev_hdr, opt->srcrt, daddr);
-+ if (opt->srcrt) {
-+ if (opt->srcrt2) {
-+ struct in6_addr *rt2_hop = &((struct rt2_hdr *)opt->srcrt2)->addr;
-+ prev_hdr = ipv6_build_rthdr(skb, prev_hdr, opt->srcrt, rt2_hop);
-+ } else
-+ prev_hdr = ipv6_build_rthdr(skb, prev_hdr, opt->srcrt, daddr);
-+ }
-+ if (opt->srcrt2) {
-+ struct inet6_skb_parm *parm = (struct inet6_skb_parm *)skb->cb;
-+ ipv6_addr_copy(&parm->hoa, daddr);
-+ prev_hdr = ipv6_build_rthdr(skb, prev_hdr, opt->srcrt2, daddr);
-+ }
- }
- return prev_hdr;
- }
-@@ -684,6 +734,11 @@ void ipv6_push_nfrag_opts(struct sk_buff
- u8 *proto,
- struct in6_addr **daddr)
- {
-+ if (opt->srcrt2) {
-+ struct inet6_skb_parm *parm = (struct inet6_skb_parm *)skb->cb;
-+ ipv6_addr_copy(&parm->hoa, *daddr);
-+ ipv6_push_rthdr(skb, proto, opt->srcrt2, daddr);
-+ }
- if (opt->srcrt)
- ipv6_push_rthdr(skb, proto, opt->srcrt, daddr);
- if (opt->dst0opt)
-@@ -719,6 +774,8 @@ ipv6_dup_options(struct sock *sk, struct
- *((char**)&opt2->auth) += dif;
- if (opt2->srcrt)
- *((char**)&opt2->srcrt) += dif;
-+ if (opt2->srcrt2)
-+ *((char**)&opt2->srcrt2) += dif;
- }
- return opt2;
- }
-diff -uprN linux-2.4.25.old/net/ipv6/icmp.c linux-2.4.25/net/ipv6/icmp.c
---- linux-2.4.25.old/net/ipv6/icmp.c 2003-11-28 18:26:21.000000000 +0000
-+++ linux-2.4.25/net/ipv6/icmp.c 2004-06-26 11:29:30.000000000 +0100
-@@ -61,6 +61,8 @@
- #include <net/addrconf.h>
- #include <net/icmp.h>
-
-+#include <net/mipglue.h>
-+
- #include <asm/uaccess.h>
- #include <asm/system.h>
-
-@@ -364,6 +366,8 @@ void icmpv6_send(struct sk_buff *skb, in
-
- msg.len = len;
-
-+ icmpv6_swap_mipv6_addrs(skb);
-+
- ip6_build_xmit(sk, icmpv6_getfrag, &msg, &fl, len, NULL, -1,
- MSG_DONTWAIT);
- if (type >= ICMPV6_DEST_UNREACH && type <= ICMPV6_PARAMPROB)
-@@ -562,13 +566,13 @@ int icmpv6_rcv(struct sk_buff *skb)
- rt6_pmtu_discovery(&orig_hdr->daddr, &orig_hdr->saddr, dev,
- ntohl(hdr->icmp6_mtu));
-
-- /*
-- * Drop through to notify
-- */
-+ icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
-+ break;
-
- case ICMPV6_DEST_UNREACH:
-- case ICMPV6_TIME_EXCEED:
- case ICMPV6_PARAMPROB:
-+ mipv6_icmp_rcv(skb);
-+ case ICMPV6_TIME_EXCEED:
- icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
- break;
-
-@@ -597,6 +601,13 @@ int icmpv6_rcv(struct sk_buff *skb)
- case ICMPV6_MGM_REDUCTION:
- break;
-
-+ case MIPV6_DHAAD_REQUEST:
-+ case MIPV6_DHAAD_REPLY:
-+ case MIPV6_PREFIX_SOLICIT:
-+ case MIPV6_PREFIX_ADV:
-+ mipv6_icmp_rcv(skb);
-+ break;
-+
- default:
- if (net_ratelimit())
- printk(KERN_DEBUG "icmpv6: msg of unkown type\n");
-diff -uprN linux-2.4.25.old/net/ipv6/ip6_fib.c linux-2.4.25/net/ipv6/ip6_fib.c
---- linux-2.4.25.old/net/ipv6/ip6_fib.c 2003-08-25 12:44:44.000000000 +0100
-+++ linux-2.4.25/net/ipv6/ip6_fib.c 2004-06-26 11:29:30.000000000 +0100
-@@ -18,6 +18,7 @@
- * Yuji SEKIYA @USAGI: Support default route on router node;
- * remove ip6_null_entry from the top of
- * routing table.
-+ * Ville Nuorvala: Fixes to source address based routing
- */
- #include <linux/config.h>
- #include <linux/errno.h>
-@@ -40,7 +41,6 @@
- #include <net/ip6_route.h>
-
- #define RT6_DEBUG 2
--#undef CONFIG_IPV6_SUBTREES
-
- #if RT6_DEBUG >= 3
- #define RT6_TRACE(x...) printk(KERN_DEBUG x)
-@@ -500,6 +500,8 @@ static __inline__ void fib6_start_gc(str
- mod_timer(&ip6_fib_timer, jiffies + ip6_rt_gc_interval);
- }
-
-+static struct rt6_info * fib6_find_prefix(struct fib6_node *fn);
-+
- /*
- * Add routing information to the routing tree.
- * <destination addr>/<source addr>
-@@ -508,17 +510,19 @@ static __inline__ void fib6_start_gc(str
-
- int fib6_add(struct fib6_node *root, struct rt6_info *rt, struct nlmsghdr *nlh)
- {
-- struct fib6_node *fn;
-+ struct fib6_node *fn = root;
- int err = -ENOMEM;
-
-- fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr),
-- rt->rt6i_dst.plen, (u8*) &rt->rt6i_dst - (u8*) rt);
-+#ifdef CONFIG_IPV6_SUBTREES
-+ struct fib6_node *pn = NULL;
-
-+ fn = fib6_add_1(root, &rt->rt6i_src.addr, sizeof(struct in6_addr),
-+ rt->rt6i_src.plen, (u8*) &rt->rt6i_src - (u8*) rt);
-+
- if (fn == NULL)
- goto out;
-
--#ifdef CONFIG_IPV6_SUBTREES
-- if (rt->rt6i_src.plen) {
-+ if (rt->rt6i_dst.plen) {
- struct fib6_node *sn;
-
- if (fn->subtree == NULL) {
-@@ -546,9 +550,9 @@ int fib6_add(struct fib6_node *root, str
-
- /* Now add the first leaf node to new subtree */
-
-- sn = fib6_add_1(sfn, &rt->rt6i_src.addr,
-- sizeof(struct in6_addr), rt->rt6i_src.plen,
-- (u8*) &rt->rt6i_src - (u8*) rt);
-+ sn = fib6_add_1(sfn, &rt->rt6i_dst.addr,
-+ sizeof(struct in6_addr), rt->rt6i_dst.plen,
-+ (u8*) &rt->rt6i_dst - (u8*) rt);
-
- if (sn == NULL) {
- /* If it is failed, discard just allocated
-@@ -562,21 +566,30 @@ int fib6_add(struct fib6_node *root, str
- /* Now link new subtree to main tree */
- sfn->parent = fn;
- fn->subtree = sfn;
-- if (fn->leaf == NULL) {
-- fn->leaf = rt;
-- atomic_inc(&rt->rt6i_ref);
-- }
- } else {
-- sn = fib6_add_1(fn->subtree, &rt->rt6i_src.addr,
-- sizeof(struct in6_addr), rt->rt6i_src.plen,
-- (u8*) &rt->rt6i_src - (u8*) rt);
-+ sn = fib6_add_1(fn->subtree, &rt->rt6i_dst.addr,
-+ sizeof(struct in6_addr), rt->rt6i_dst.plen,
-+ (u8*) &rt->rt6i_dst - (u8*) rt);
-
- if (sn == NULL)
- goto st_failure;
- }
-
-+ /* fib6_add_1 might have cleared the old leaf pointer */
-+ if (fn->leaf == NULL) {
-+ fn->leaf = rt;
-+ atomic_inc(&rt->rt6i_ref);
-+ }
-+
-+ pn = fn;
- fn = sn;
- }
-+#else
-+ fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr),
-+ rt->rt6i_dst.plen, (u8*) &rt->rt6i_dst - (u8*) rt);
-+
-+ if (fn == NULL)
-+ goto out;
- #endif
-
- err = fib6_add_rt2node(fn, rt, nlh);
-@@ -588,8 +601,30 @@ int fib6_add(struct fib6_node *root, str
- }
-
- out:
-- if (err)
-+ if (err) {
-+#ifdef CONFIG_IPV6_SUBTREES
-+
-+ /* If fib6_add_1 has cleared the old leaf pointer in the
-+ super-tree leaf node, we have to find a new one for it.
-+
-+ This situation will never arise in the sub-tree since
-+ the node will at least have the route that caused
-+ fib6_add_rt2node to fail.
-+ */
-+
-+ if (pn && !(pn->fn_flags & RTN_RTINFO)) {
-+ pn->leaf = fib6_find_prefix(pn);
-+#if RT6_DEBUG >= 2
-+ if (!pn->leaf) {
-+ BUG_TRAP(pn->leaf);
-+ pn->leaf = &ip6_null_entry;
-+ }
-+#endif
-+ atomic_inc(&pn->leaf->rt6i_ref);
-+ }
-+#endif
- dst_free(&rt->u.dst);
-+ }
- return err;
-
- #ifdef CONFIG_IPV6_SUBTREES
-@@ -597,8 +632,8 @@ out:
- is orphan. If it is, shoot it.
- */
- st_failure:
-- if (fn && !(fn->fn_flags&RTN_RTINFO|RTN_ROOT))
-- fib_repair_tree(fn);
-+ if (fn && !(fn->fn_flags & (RTN_RTINFO | RTN_ROOT)))
-+ fib6_repair_tree(fn);
- dst_free(&rt->u.dst);
- return err;
- #endif
-@@ -641,22 +676,28 @@ static struct fib6_node * fib6_lookup_1(
- break;
- }
-
-- while ((fn->fn_flags & RTN_ROOT) == 0) {
-+ for (;;) {
- #ifdef CONFIG_IPV6_SUBTREES
- if (fn->subtree) {
-- struct fib6_node *st;
-- struct lookup_args *narg;
--
-- narg = args + 1;
--
-- if (narg->addr) {
-- st = fib6_lookup_1(fn->subtree, narg);
-+ struct rt6key *key;
-
-- if (st && !(st->fn_flags & RTN_ROOT))
-- return st;
-+ key = (struct rt6key *) ((u8 *) fn->leaf +
-+ args->offset);
-+
-+ if (addr_match(&key->addr, args->addr, key->plen)) {
-+ struct fib6_node *st;
-+ struct lookup_args *narg = args + 1;
-+ if (!ipv6_addr_any(narg->addr)) {
-+ st = fib6_lookup_1(fn->subtree, narg);
-+
-+ if (st && !(st->fn_flags & RTN_ROOT))
-+ return st;
-+ }
- }
- }
- #endif
-+ if (fn->fn_flags & RTN_ROOT)
-+ break;
-
- if (fn->fn_flags & RTN_RTINFO) {
- struct rt6key *key;
-@@ -680,13 +721,22 @@ struct fib6_node * fib6_lookup(struct fi
- struct lookup_args args[2];
- struct rt6_info *rt = NULL;
- struct fib6_node *fn;
-+#ifdef CONFIG_IPV6_SUBTREES
-+ struct in6_addr saddr_buf;
-+#endif
-
-+#ifdef CONFIG_IPV6_SUBTREES
-+ if (saddr == NULL) {
-+ memset(&saddr_buf, 0, sizeof(struct in6_addr));
-+ saddr = &saddr_buf;
-+ }
-+ args[0].offset = (u8*) &rt->rt6i_src - (u8*) rt;
-+ args[0].addr = saddr;
-+ args[1].offset = (u8*) &rt->rt6i_dst - (u8*) rt;
-+ args[1].addr = daddr;
-+#else
- args[0].offset = (u8*) &rt->rt6i_dst - (u8*) rt;
- args[0].addr = daddr;
--
--#ifdef CONFIG_IPV6_SUBTREES
-- args[1].offset = (u8*) &rt->rt6i_src - (u8*) rt;
-- args[1].addr = saddr;
- #endif
-
- fn = fib6_lookup_1(root, args);
-@@ -739,19 +789,25 @@ struct fib6_node * fib6_locate(struct fi
- {
- struct rt6_info *rt = NULL;
- struct fib6_node *fn;
--
-- fn = fib6_locate_1(root, daddr, dst_len,
-- (u8*) &rt->rt6i_dst - (u8*) rt);
--
- #ifdef CONFIG_IPV6_SUBTREES
-- if (src_len) {
-- BUG_TRAP(saddr!=NULL);
-- if (fn == NULL)
-- fn = fn->subtree;
-+ struct in6_addr saddr_buf;
-+
-+ if (saddr == NULL) {
-+ memset(&saddr_buf, 0, sizeof(struct in6_addr));
-+ saddr = &saddr_buf;
-+ }
-+ fn = fib6_locate_1(root, saddr, src_len,
-+ (u8*) &rt->rt6i_src - (u8*) rt);
-+ if (dst_len) {
- if (fn)
-- fn = fib6_locate_1(fn, saddr, src_len,
-- (u8*) &rt->rt6i_src - (u8*) rt);
-+ fn = fib6_locate_1(fn->subtree, daddr, dst_len,
-+ (u8*) &rt->rt6i_dst - (u8*) rt);
-+ else
-+ return NULL;
- }
-+#else
-+ fn = fib6_locate_1(root, daddr, dst_len,
-+ (u8*) &rt->rt6i_dst - (u8*) rt);
- #endif
-
- if (fn && fn->fn_flags&RTN_RTINFO)
-@@ -939,7 +995,7 @@ static void fib6_del_route(struct fib6_n
- }
- fn = fn->parent;
- }
-- /* No more references are possiible at this point. */
-+ /* No more references are possible at this point. */
- if (atomic_read(&rt->rt6i_ref) != 1) BUG();
- }
-
-diff -uprN linux-2.4.25.old/net/ipv6/ip6_input.c linux-2.4.25/net/ipv6/ip6_input.c
---- linux-2.4.25.old/net/ipv6/ip6_input.c 2003-08-25 12:44:44.000000000 +0100
-+++ linux-2.4.25/net/ipv6/ip6_input.c 2004-06-26 11:29:30.000000000 +0100
-@@ -40,13 +40,42 @@
- #include <net/ip6_route.h>
- #include <net/addrconf.h>
-
-+static inline int ip6_proxy_chk(struct sk_buff *skb)
-+{
-+ struct ipv6hdr *hdr = skb->nh.ipv6h;
-
--
-+ if (ipv6_addr_type(&hdr->daddr)&IPV6_ADDR_UNICAST &&
-+ pneigh_lookup(&nd_tbl, &hdr->daddr, skb->dev, 0)) {
-+ u8 nexthdr = hdr->nexthdr;
-+ int offset;
-+ struct icmp6hdr msg;
-+
-+ if (ipv6_ext_hdr(nexthdr)) {
-+ offset = ipv6_skip_exthdr(skb, sizeof(*hdr), &nexthdr,
-+ skb->len - sizeof(*hdr));
-+ if (offset < 0)
-+ return 0;
-+ } else
-+ offset = sizeof(*hdr);
-+
-+ /* capture unicast NUD probes on behalf of the proxied node */
-+
-+ if (nexthdr == IPPROTO_ICMPV6 &&
-+ !skb_copy_bits(skb, offset, &msg, sizeof(msg)) &&
-+ msg.icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) {
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
- static inline int ip6_rcv_finish( struct sk_buff *skb)
- {
-- if (skb->dst == NULL)
-- ip6_route_input(skb);
--
-+ if (skb->dst == NULL) {
-+ if (ip6_proxy_chk(skb))
-+ return ip6_input(skb);
-+ ip6_route_input(skb);
-+ }
- return skb->dst->input(skb);
- }
-
-diff -uprN linux-2.4.25.old/net/ipv6/ip6_output.c linux-2.4.25/net/ipv6/ip6_output.c
---- linux-2.4.25.old/net/ipv6/ip6_output.c 2003-08-25 12:44:44.000000000 +0100
-+++ linux-2.4.25/net/ipv6/ip6_output.c 2004-06-26 11:29:30.000000000 +0100
-@@ -50,6 +50,8 @@
- #include <net/rawv6.h>
- #include <net/icmp.h>
-
-+#include <net/mipglue.h>
-+
- static __inline__ void ipv6_select_ident(struct sk_buff *skb, struct frag_hdr *fhdr)
- {
- static u32 ipv6_fragmentation_id = 1;
-@@ -194,7 +196,14 @@ int ip6_xmit(struct sock *sk, struct sk_
- u8 proto = fl->proto;
- int seg_len = skb->len;
- int hlimit;
-+ int retval;
-+ struct ipv6_txoptions *orig_opt = opt;
-+
-+ opt = ip6_add_mipv6_txoptions(sk, skb, orig_opt, fl, &dst);
-
-+ if(orig_opt && !opt)
-+ return -ENOMEM;
-+
- if (opt) {
- int head_room;
-
-@@ -209,8 +218,11 @@ int ip6_xmit(struct sock *sk, struct sk_
- struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
- kfree_skb(skb);
- skb = skb2;
-- if (skb == NULL)
-+ if (skb == NULL) {
-+ ip6_free_mipv6_txoptions(opt, orig_opt);
-+
- return -ENOBUFS;
-+ }
- if (sk)
- skb_set_owner_w(skb, sk);
- }
-@@ -242,7 +254,10 @@ int ip6_xmit(struct sock *sk, struct sk_
-
- if (skb->len <= dst->pmtu) {
- IP6_INC_STATS(Ip6OutRequests);
-- return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
-+ ip6_mark_mipv6_packet(opt, skb);
-+ retval = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
-+ ip6_free_mipv6_txoptions(opt, orig_opt);
-+ return retval;
- }
-
- if (net_ratelimit())
-@@ -250,6 +265,9 @@ int ip6_xmit(struct sock *sk, struct sk_
- skb->dev = dst->dev;
- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst->pmtu, skb->dev);
- kfree_skb(skb);
-+
-+ ip6_free_mipv6_txoptions(opt, orig_opt);
-+
- return -EMSGSIZE;
- }
-
-@@ -473,6 +491,7 @@ static int ip6_frag_xmit(struct sock *sk
-
- IP6_INC_STATS(Ip6FragCreates);
- IP6_INC_STATS(Ip6OutRequests);
-+ ip6_mark_mipv6_packet(opt, skb);
- err = NF_HOOK(PF_INET6,NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
- if (err) {
- kfree_skb(last_skb);
-@@ -499,6 +518,7 @@ static int ip6_frag_xmit(struct sock *sk
- IP6_INC_STATS(Ip6FragCreates);
- IP6_INC_STATS(Ip6FragOKs);
- IP6_INC_STATS(Ip6OutRequests);
-+ ip6_mark_mipv6_packet(opt, last_skb);
- return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, last_skb, NULL,dst->dev, ip6_maybe_reroute);
- }
-
-@@ -509,26 +529,43 @@ int ip6_build_xmit(struct sock *sk, inet
- struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
- struct in6_addr *final_dst = NULL;
- struct dst_entry *dst;
-+ struct rt6_info *rt;
- int err = 0;
- unsigned int pktlength, jumbolen, mtu;
- struct in6_addr saddr;
-+ struct ipv6_txoptions *orig_opt = opt;
-+#ifdef CONFIG_IPV6_SUBTREES
-+ struct dst_entry *org_dst;
-+#endif
-+
-+ opt = ip6_add_mipv6_txoptions(sk, NULL, orig_opt, fl, NULL);
-+
-+ if(orig_opt && !opt)
-+ return -ENOMEM;
-
- if (opt && opt->srcrt) {
- struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
- final_dst = fl->fl6_dst;
- fl->fl6_dst = rt0->addr;
-- }
-+ } else if (opt && opt->srcrt2) {
-+ struct rt2_hdr *rt2 = (struct rt2_hdr *) opt->srcrt2;
-+ final_dst = fl->fl6_dst;
-+ fl->fl6_dst = &rt2->addr;
-+ }
-
- if (!fl->oif && ipv6_addr_is_multicast(fl->nl_u.ip6_u.daddr))
- fl->oif = np->mcast_oif;
-
- dst = __sk_dst_check(sk, np->dst_cookie);
-+#ifdef CONFIG_IPV6_SUBTREES
-+ org_dst = dst;
-+#endif
- if (dst) {
-- struct rt6_info *rt = (struct rt6_info*)dst;
-+ rt = (struct rt6_info*)dst;
-
- /* Yes, checking route validity in not connected
- case is not very simple. Take into account,
-- that we do not support routing by source, TOS,
-+ that we do not support routing by TOS,
- and MSG_DONTROUTE --ANK (980726)
-
- 1. If route was host route, check that
-@@ -548,6 +585,13 @@ int ip6_build_xmit(struct sock *sk, inet
- ipv6_addr_cmp(fl->fl6_dst, &rt->rt6i_dst.addr))
- && (np->daddr_cache == NULL ||
- ipv6_addr_cmp(fl->fl6_dst, np->daddr_cache)))
-+#ifdef CONFIG_IPV6_SUBTREES
-+ || (fl->fl6_src != NULL
-+ && (rt->rt6i_src.plen != 128 ||
-+ ipv6_addr_cmp(fl->fl6_src, &rt->rt6i_src.addr))
-+ && (np->saddr_cache == NULL ||
-+ ipv6_addr_cmp(fl->fl6_src, np->saddr_cache)))
-+#endif
- || (fl->oif && fl->oif != dst->dev->ifindex)) {
- dst = NULL;
- } else
-@@ -560,21 +604,42 @@ int ip6_build_xmit(struct sock *sk, inet
- if (dst->error) {
- IP6_INC_STATS(Ip6OutNoRoutes);
- dst_release(dst);
-+ ip6_free_mipv6_txoptions(opt, orig_opt);
- return -ENETUNREACH;
- }
-
- if (fl->fl6_src == NULL) {
- err = ipv6_get_saddr(dst, fl->fl6_dst, &saddr);
--
- if (err) {
- #if IP6_DEBUG >= 2
- printk(KERN_DEBUG "ip6_build_xmit: "
- "no available source address\n");
- #endif
-+
-+#ifdef CONFIG_IPV6_SUBTREES
-+ if (dst != org_dst) {
-+ dst_release(dst);
-+ dst = org_dst;
-+ }
-+#endif
- goto out;
- }
- fl->fl6_src = &saddr;
- }
-+#ifdef CONFIG_IPV6_SUBTREES
-+ rt = (struct rt6_info*)dst;
-+ if (dst != org_dst || rt->rt6i_src.plen != 128 ||
-+ ipv6_addr_cmp(fl->fl6_src, &rt->rt6i_src.addr)) {
-+ dst_release(dst);
-+ dst = ip6_route_output(sk, fl);
-+ if (dst->error) {
-+ IP6_INC_STATS(Ip6OutNoRoutes);
-+ dst_release(dst);
-+ ip6_free_mipv6_txoptions(opt, orig_opt);
-+ return -ENETUNREACH;
-+ }
-+ }
-+#endif
- pktlength = length;
-
- if (hlimit < 0) {
-@@ -667,6 +732,7 @@ int ip6_build_xmit(struct sock *sk, inet
-
- if (!err) {
- IP6_INC_STATS(Ip6OutRequests);
-+ ip6_mark_mipv6_packet(opt, skb);
- err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, ip6_maybe_reroute);
- } else {
- err = -EFAULT;
-@@ -688,9 +754,14 @@ int ip6_build_xmit(struct sock *sk, inet
- * cleanup
- */
- out:
-- ip6_dst_store(sk, dst, fl->nl_u.ip6_u.daddr == &np->daddr ? &np->daddr : NULL);
-+ ip6_dst_store(sk, dst,
-+ fl->nl_u.ip6_u.daddr == &np->daddr ? &np->daddr : NULL,
-+ fl->nl_u.ip6_u.saddr == &np->saddr ? &np->saddr : NULL);
- if (err > 0)
- err = np->recverr ? net_xmit_errno(err) : 0;
-+
-+ ip6_free_mipv6_txoptions(opt, orig_opt);
-+
- return err;
- }
-
-@@ -769,6 +840,15 @@ int ip6_forward(struct sk_buff *skb)
- return -ETIMEDOUT;
- }
-
-+ /* The proxying router can't forward traffic sent to a link-local
-+ address, so signal the sender and discard the packet. This
-+ behavior is required by the MIPv6 specification. */
-+
-+ if (ipv6_addr_type(&hdr->daddr) & IPV6_ADDR_LINKLOCAL &&
-+ skb->dev && pneigh_lookup(&nd_tbl, &hdr->daddr, skb->dev, 0)) {
-+ dst_link_failure(skb);
-+ goto drop;
-+ }
- /* IPv6 specs say nothing about it, but it is clear that we cannot
- send redirects to source routed frames.
- */
-diff -uprN linux-2.4.25.old/net/ipv6/ipv6_syms.c linux-2.4.25/net/ipv6/ipv6_syms.c
---- linux-2.4.25.old/net/ipv6/ipv6_syms.c 2003-11-28 18:26:21.000000000 +0000
-+++ linux-2.4.25/net/ipv6/ipv6_syms.c 2004-06-26 11:29:30.000000000 +0100
-@@ -6,6 +6,8 @@
- #include <net/ipv6.h>
- #include <net/addrconf.h>
- #include <net/ip6_route.h>
-+#include <net/ndisc.h>
-+#include <net/mipglue.h>
-
- EXPORT_SYMBOL(ipv6_addr_type);
- EXPORT_SYMBOL(icmpv6_send);
-@@ -33,3 +35,48 @@ EXPORT_SYMBOL(inet6_ioctl);
- EXPORT_SYMBOL(ipv6_get_saddr);
- EXPORT_SYMBOL(ipv6_chk_addr);
- EXPORT_SYMBOL(in6_dev_finish_destroy);
-+
-+#if defined(CONFIG_IPV6_TUNNEL_MODULE) || defined(CONFIG_IPV6_MOBILITY_MODULE)
-+EXPORT_SYMBOL(ip6_build_xmit);
-+EXPORT_SYMBOL(rt6_lookup);
-+EXPORT_SYMBOL(ipv6_ext_hdr);
-+#endif
-+#ifdef CONFIG_IPV6_MOBILITY_MODULE
-+EXPORT_SYMBOL(mipv6_functions);
-+EXPORT_SYMBOL(mipv6_invalidate_calls);
-+#if defined(CONFIG_IPV6_MOBILITY_HA_MODULE) || defined(CONFIG_IPV6_MOBILITY_MN_MODULE)
-+EXPORT_SYMBOL(ip6_route_add);
-+EXPORT_SYMBOL(ip6_route_del);
-+EXPORT_SYMBOL(ipv6_get_lladdr);
-+EXPORT_SYMBOL(ipv6_get_ifaddr);
-+EXPORT_SYMBOL(nd_tbl);
-+EXPORT_SYMBOL(ndisc_send_ns);
-+EXPORT_SYMBOL(ndisc_send_na);
-+EXPORT_SYMBOL(ndisc_next_option);
-+EXPORT_SYMBOL(inet6_ifa_finish_destroy);
-+#endif
-+#ifdef CONFIG_IPV6_MOBILITY_HA_MODULE
-+EXPORT_SYMBOL(ipv6_dev_ac_dec);
-+EXPORT_SYMBOL(ipv6_dev_ac_inc);
-+EXPORT_SYMBOL(ipv6_dev_mc_dec);
-+EXPORT_SYMBOL(ipv6_dev_mc_inc);
-+EXPORT_SYMBOL(ip6_forward);
-+EXPORT_SYMBOL(ip6_input);
-+EXPORT_SYMBOL(ipv6_chk_acast_addr);
-+#endif
-+#ifdef CONFIG_IPV6_MOBILITY_MN_MODULE
-+#endif
-+EXPORT_SYMBOL(addrconf_add_ifaddr);
-+EXPORT_SYMBOL(addrconf_del_ifaddr);
-+EXPORT_SYMBOL(addrconf_dad_start);
-+EXPORT_SYMBOL(ip6_del_rt);
-+EXPORT_SYMBOL(ip6_routing_table);
-+EXPORT_SYMBOL(rt6_get_dflt_router);
-+EXPORT_SYMBOL(rt6_purge_dflt_routers);
-+EXPORT_SYMBOL(rt6_lock);
-+EXPORT_SYMBOL(ndisc_send_rs);
-+EXPORT_SYMBOL(fib6_clean_tree);
-+EXPORT_SYMBOL(ipv6_del_addr);
-+EXPORT_SYMBOL(ipv6_generate_eui64);
-+EXPORT_SYMBOL(ipv6_inherit_eui64);
-+#endif
-diff -uprN linux-2.4.25.old/net/ipv6/ipv6_tunnel.c linux-2.4.25/net/ipv6/ipv6_tunnel.c
---- linux-2.4.25.old/net/ipv6/ipv6_tunnel.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/ipv6_tunnel.c 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,1604 @@
-+/*
-+ * IPv6 over IPv6 tunnel device
-+ * Linux INET6 implementation
-+ *
-+ * Authors:
-+ * Ville Nuorvala <vnuorval@tcs.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * Based on:
-+ * linux/net/ipv6/sit.c
-+ *
-+ * RFC 2473
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/types.h>
-+#include <linux/socket.h>
-+#include <linux/sockios.h>
-+#include <linux/if.h>
-+#include <linux/in.h>
-+#include <linux/ip.h>
-+#include <linux/if_tunnel.h>
-+#include <linux/net.h>
-+#include <linux/in6.h>
-+#include <linux/netdevice.h>
-+#include <linux/if_arp.h>
-+#include <linux/icmpv6.h>
-+#include <linux/init.h>
-+#include <linux/route.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/tqueue.h>
-+
-+#include <asm/uaccess.h>
-+#include <asm/atomic.h>
-+
-+#include <net/sock.h>
-+#include <net/ipv6.h>
-+#include <net/protocol.h>
-+#include <net/ip6_route.h>
-+#include <net/addrconf.h>
-+#include <net/ipv6_tunnel.h>
-+
-+MODULE_AUTHOR("Ville Nuorvala");
-+MODULE_DESCRIPTION("IPv6-in-IPv6 tunnel");
-+MODULE_LICENSE("GPL");
-+
-+#define IPV6_TLV_TEL_DST_SIZE 8
-+
-+#ifdef IP6_TNL_DEBUG
-+#define IP6_TNL_TRACE(x...) printk(KERN_DEBUG "%s:" x "\n", __FUNCTION__)
-+#else
-+#define IP6_TNL_TRACE(x...) do {;} while(0)
-+#endif
-+
-+#define IPV6_TCLASS_MASK (IPV6_FLOWINFO_MASK & ~IPV6_FLOWLABEL_MASK)
-+
-+#define HASH_SIZE 32
-+
-+#define HASH(addr) (((addr)->s6_addr32[0] ^ (addr)->s6_addr32[1] ^ \
-+ (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \
-+ (HASH_SIZE - 1))
-+
-+static int ip6ip6_fb_tnl_dev_init(struct net_device *dev);
-+static int ip6ip6_tnl_dev_init(struct net_device *dev);
-+
-+/* the IPv6 IPv6 tunnel fallback device */
-+static struct net_device ip6ip6_fb_tnl_dev = {
-+ name: "ip6tnl0",
-+ init: ip6ip6_fb_tnl_dev_init
-+};
-+
-+/* the IPv6 IPv6 fallback tunnel */
-+static struct ip6_tnl ip6ip6_fb_tnl = {
-+ dev: &ip6ip6_fb_tnl_dev,
-+ parms:{name: "ip6tnl0", proto: IPPROTO_IPV6}
-+};
-+
-+/* lists for storing tunnels in use */
-+static struct ip6_tnl *tnls_r_l[HASH_SIZE];
-+static struct ip6_tnl *tnls_wc[1];
-+static struct ip6_tnl **tnls[2] = { tnls_wc, tnls_r_l };
-+
-+/* list for unused cached kernel tunnels */
-+static struct ip6_tnl *tnls_kernel[1];
-+/* maximum number of cached kernel tunnels */
-+static unsigned int max_kdev_count = 0;
-+/* minimum number of cached kernel tunnels */
-+static unsigned int min_kdev_count = 0;
-+/* current number of cached kernel tunnels */
-+static unsigned int kdev_count = 0;
-+
-+/* lists for tunnel hook functions */
-+static struct list_head hooks[IP6_TNL_MAXHOOKS];
-+
-+/* locks for the different lists */
-+static rwlock_t ip6ip6_lock = RW_LOCK_UNLOCKED;
-+static rwlock_t ip6ip6_kernel_lock = RW_LOCK_UNLOCKED;
-+static rwlock_t ip6ip6_hook_lock = RW_LOCK_UNLOCKED;
-+
-+/* flag indicating if the module is being removed */
-+static int shutdown = 0;
-+
-+/**
-+ * ip6ip6_tnl_lookup - fetch tunnel matching the end-point addresses
-+ * @remote: the address of the tunnel exit-point
-+ * @local: the address of the tunnel entry-point
-+ *
-+ * Return:
-+ * tunnel matching given end-points if found,
-+ * else fallback tunnel if its device is up,
-+ * else %NULL
-+ **/
-+
-+struct ip6_tnl *
-+ip6ip6_tnl_lookup(struct in6_addr *remote, struct in6_addr *local)
-+{
-+ unsigned h0 = HASH(remote);
-+ unsigned h1 = HASH(local);
-+ struct ip6_tnl *t;
-+
-+ for (t = tnls_r_l[h0 ^ h1]; t; t = t->next) {
-+ if (!ipv6_addr_cmp(local, &t->parms.laddr) &&
-+ !ipv6_addr_cmp(remote, &t->parms.raddr) &&
-+ (t->dev->flags & IFF_UP))
-+ return t;
-+ }
-+ if ((t = tnls_wc[0]) != NULL && (t->dev->flags & IFF_UP))
-+ return t;
-+
-+ return NULL;
-+}
-+
-+/**
-+ * ip6ip6_bucket - get head of list matching given tunnel parameters
-+ * @p: parameters containing tunnel end-points
-+ *
-+ * Description:
-+ * ip6ip6_bucket() returns the head of the list matching the
-+ * &struct in6_addr entries laddr and raddr in @p.
-+ *
-+ * Return: head of IPv6 tunnel list
-+ **/
-+
-+static struct ip6_tnl **
-+ip6ip6_bucket(struct ip6_tnl_parm *p)
-+{
-+ struct in6_addr *remote = &p->raddr;
-+ struct in6_addr *local = &p->laddr;
-+ unsigned h = 0;
-+ int prio = 0;
-+
-+ if (!ipv6_addr_any(remote) || !ipv6_addr_any(local)) {
-+ prio = 1;
-+ h = HASH(remote) ^ HASH(local);
-+ }
-+ return &tnls[prio][h];
-+}
-+
-+/**
-+ * ip6ip6_kernel_tnl_link - add new kernel tunnel to cache
-+ * @t: kernel tunnel
-+ *
-+ * Note:
-+ * %IP6_TNL_F_KERNEL_DEV is assumed to be raised in t->parms.flags.
-+ * See the comments on ip6ip6_kernel_tnl_add() for more information.
-+ **/
-+
-+static inline void
-+ip6ip6_kernel_tnl_link(struct ip6_tnl *t)
-+{
-+ write_lock_bh(&ip6ip6_kernel_lock);
-+ t->next = tnls_kernel[0];
-+ tnls_kernel[0] = t;
-+ kdev_count++;
-+ write_unlock_bh(&ip6ip6_kernel_lock);
-+}
-+
-+/**
-+ * ip6ip6_kernel_tnl_unlink - remove first kernel tunnel from cache
-+ *
-+ * Return: first free kernel tunnel
-+ *
-+ * Note:
-+ * See the comments on ip6ip6_kernel_tnl_add() for more information.
-+ **/
-+
-+static inline struct ip6_tnl *
-+ip6ip6_kernel_tnl_unlink(void)
-+{
-+ struct ip6_tnl *t;
-+
-+ write_lock_bh(&ip6ip6_kernel_lock);
-+ if ((t = tnls_kernel[0]) != NULL) {
-+ tnls_kernel[0] = t->next;
-+ kdev_count--;
-+ }
-+ write_unlock_bh(&ip6ip6_kernel_lock);
-+ return t;
-+}
-+
-+/**
-+ * ip6ip6_tnl_link - add tunnel to hash table
-+ * @t: tunnel to be added
-+ **/
-+
-+static void
-+ip6ip6_tnl_link(struct ip6_tnl *t)
-+{
-+ struct ip6_tnl **tp = ip6ip6_bucket(&t->parms);
-+
-+ write_lock_bh(&ip6ip6_lock);
-+ t->next = *tp;
-+ *tp = t;
-+ write_unlock_bh(&ip6ip6_lock);
-+}
-+
-+/**
-+ * ip6ip6_tnl_unlink - remove tunnel from hash table
-+ * @t: tunnel to be removed
-+ **/
-+
-+static void
-+ip6ip6_tnl_unlink(struct ip6_tnl *t)
-+{
-+ struct ip6_tnl **tp;
-+
-+ write_lock_bh(&ip6ip6_lock);
-+ for (tp = ip6ip6_bucket(&t->parms); *tp; tp = &(*tp)->next) {
-+ if (t == *tp) {
-+ *tp = t->next;
-+ break;
-+ }
-+ }
-+ write_unlock_bh(&ip6ip6_lock);
-+}
-+
-+/**
-+ * ip6ip6_tnl_create() - create a new tunnel
-+ * @p: tunnel parameters
-+ * @pt: pointer to new tunnel
-+ *
-+ * Description:
-+ * Create tunnel matching given parameters. New kernel managed devices are
-+ * not put in the normal hash structure, but are instead cached for later
-+ * use.
-+ *
-+ * Return:
-+ * 0 on success
-+ **/
-+
-+
-+static int __ip6ip6_tnl_create(struct ip6_tnl_parm *p,
-+ struct ip6_tnl **pt,
-+ int kernel_list)
-+{
-+ struct net_device *dev;
-+ int err = -ENOBUFS;
-+ struct ip6_tnl *t;
-+
-+ MOD_INC_USE_COUNT;
-+ dev = kmalloc(sizeof (*dev) + sizeof (*t), GFP_KERNEL);
-+ if (!dev) {
-+ MOD_DEC_USE_COUNT;
-+ return err;
-+ }
-+ memset(dev, 0, sizeof (*dev) + sizeof (*t));
-+ dev->priv = (void *) (dev + 1);
-+ t = (struct ip6_tnl *) dev->priv;
-+ t->dev = dev;
-+ dev->init = ip6ip6_tnl_dev_init;
-+ dev->features |= NETIF_F_DYNALLOC;
-+ if (kernel_list) {
-+ memcpy(t->parms.name, p->name, IFNAMSIZ - 1);
-+ t->parms.proto = IPPROTO_IPV6;
-+ t->parms.flags = IP6_TNL_F_KERNEL_DEV;
-+ } else {
-+ memcpy(&t->parms, p, sizeof (*p));
-+ }
-+ t->parms.name[IFNAMSIZ - 1] = '\0';
-+ strcpy(dev->name, t->parms.name);
-+ if (!dev->name[0]) {
-+ int i;
-+ for (i = 0; i < IP6_TNL_MAX; i++) {
-+ sprintf(dev->name, "ip6tnl%d", i);
-+ if (__dev_get_by_name(dev->name) == NULL)
-+ break;
-+ }
-+
-+ if (i == IP6_TNL_MAX) {
-+ goto failed;
-+ }
-+ memcpy(t->parms.name, dev->name, IFNAMSIZ);
-+ }
-+ if ((err = register_netdevice(dev)) < 0) {
-+ goto failed;
-+ }
-+ dev_hold(dev);
-+ if (kernel_list) {
-+ ip6ip6_kernel_tnl_link(t);
-+ } else {
-+ ip6ip6_tnl_link(t);
-+ }
-+ *pt = t;
-+ return 0;
-+failed:
-+ kfree(dev);
-+ MOD_DEC_USE_COUNT;
-+ return err;
-+}
-+
-+
-+int ip6ip6_tnl_create(struct ip6_tnl_parm *p, struct ip6_tnl **pt)
-+{
-+ return __ip6ip6_tnl_create(p, pt, 0);
-+}
-+
-+
-+static void manage_kernel_tnls(void *foo);
-+
-+static struct tq_struct manager_task = {
-+ routine:manage_kernel_tnls,
-+ data:NULL
-+};
-+
-+/**
-+ * manage_kernel_tnls() - create and destroy kernel tunnels
-+ *
-+ * Description:
-+ * manage_kernel_tnls() creates new kernel devices if there
-+ * are less than $min_kdev_count of them and deletes old ones if
-+ * there are less than $max_kdev_count of them in the cache
-+ *
-+ * Note:
-+ * Schedules itself to be run later in process context if called from
-+ * interrupt. Therefore only works synchronously when called from process
-+ * context.
-+ **/
-+
-+static void
-+manage_kernel_tnls(void *foo)
-+{
-+ struct ip6_tnl *t = NULL;
-+ struct ip6_tnl_parm parm;
-+
-+ /* We can't do this processing in interrupt
-+ context so schedule it for later */
-+ if (in_interrupt()) {
-+ read_lock(&ip6ip6_kernel_lock);
-+ if (!shutdown &&
-+ (kdev_count < min_kdev_count ||
-+ kdev_count > max_kdev_count)) {
-+ schedule_task(&manager_task);
-+ }
-+ read_unlock(&ip6ip6_kernel_lock);
-+ return;
-+ }
-+
-+ rtnl_lock();
-+ read_lock_bh(&ip6ip6_kernel_lock);
-+ memset(&parm, 0, sizeof (parm));
-+ parm.flags = IP6_TNL_F_KERNEL_DEV;
-+ /* Create tunnels until there are at least min_kdev_count */
-+ while (kdev_count < min_kdev_count) {
-+ read_unlock_bh(&ip6ip6_kernel_lock);
-+ if (!__ip6ip6_tnl_create(&parm, &t, 1)) {
-+ dev_open(t->dev);
-+ } else {
-+ goto err;
-+ }
-+ read_lock_bh(&ip6ip6_kernel_lock);
-+ }
-+
-+ /* Destroy tunnels until there are at most max_kdev_count */
-+ while (kdev_count > max_kdev_count) {
-+ read_unlock_bh(&ip6ip6_kernel_lock);
-+ if ((t = ip6ip6_kernel_tnl_unlink()) != NULL) {
-+ unregister_netdevice(t->dev);
-+ } else {
-+ goto err;
-+ }
-+ read_lock_bh(&ip6ip6_kernel_lock);
-+ }
-+ read_unlock_bh(&ip6ip6_kernel_lock);
-+err:
-+ rtnl_unlock();
-+}
-+
-+/**
-+ * ip6ip6_tnl_inc_max_kdev_count() - increase max kernel dev cache size
-+ * @n: size increase
-+ * Description:
-+ * Increase the upper limit for the number of kernel devices allowed in the
-+ * cache at any on time.
-+ **/
-+
-+unsigned int
-+ip6ip6_tnl_inc_max_kdev_count(unsigned int n)
-+{
-+ write_lock_bh(&ip6ip6_kernel_lock);
-+ max_kdev_count += n;
-+ write_unlock_bh(&ip6ip6_kernel_lock);
-+ manage_kernel_tnls(NULL);
-+ return max_kdev_count;
-+}
-+
-+/**
-+ * ip6ip6_tnl_dec_max_kdev_count() - decrease max kernel dev cache size
-+ * @n: size decrement
-+ * Description:
-+ * Decrease the upper limit for the number of kernel devices allowed in the
-+ * cache at any on time.
-+ **/
-+
-+unsigned int
-+ip6ip6_tnl_dec_max_kdev_count(unsigned int n)
-+{
-+ write_lock_bh(&ip6ip6_kernel_lock);
-+ max_kdev_count -= min(max_kdev_count, n);
-+ if (max_kdev_count < min_kdev_count)
-+ min_kdev_count = max_kdev_count;
-+ write_unlock_bh(&ip6ip6_kernel_lock);
-+ manage_kernel_tnls(NULL);
-+ return max_kdev_count;
-+}
-+
-+/**
-+ * ip6ip6_tnl_inc_min_kdev_count() - increase min kernel dev cache size
-+ * @n: size increase
-+ * Description:
-+ * Increase the lower limit for the number of kernel devices allowed in the
-+ * cache at any on time.
-+ **/
-+
-+unsigned int
-+ip6ip6_tnl_inc_min_kdev_count(unsigned int n)
-+{
-+ write_lock_bh(&ip6ip6_kernel_lock);
-+ min_kdev_count += n;
-+ if (min_kdev_count > max_kdev_count)
-+ max_kdev_count = min_kdev_count;
-+ write_unlock_bh(&ip6ip6_kernel_lock);
-+ manage_kernel_tnls(NULL);
-+ return min_kdev_count;
-+}
-+
-+/**
-+ * ip6ip6_tnl_dec_min_kdev_count() - decrease min kernel dev cache size
-+ * @n: size decrement
-+ * Description:
-+ * Decrease the lower limit for the number of kernel devices allowed in the
-+ * cache at any on time.
-+ **/
-+
-+unsigned int
-+ip6ip6_tnl_dec_min_kdev_count(unsigned int n)
-+{
-+ write_lock_bh(&ip6ip6_kernel_lock);
-+ min_kdev_count -= min(min_kdev_count, n);
-+ write_unlock_bh(&ip6ip6_kernel_lock);
-+ manage_kernel_tnls(NULL);
-+ return min_kdev_count;
-+}
-+
-+/**
-+ * ip6ip6_tnl_locate - find or create tunnel matching given parameters
-+ * @p: tunnel parameters
-+ * @create: != 0 if allowed to create new tunnel if no match found
-+ *
-+ * Description:
-+ * ip6ip6_tnl_locate() first tries to locate an existing tunnel
-+ * based on @parms. If this is unsuccessful, but @create is set a new
-+ * tunnel device is created and registered for use.
-+ *
-+ * Return:
-+ * 0 if tunnel located or created,
-+ * -EINVAL if parameters incorrect,
-+ * -ENODEV if no matching tunnel available
-+ **/
-+
-+int ip6ip6_tnl_locate(struct ip6_tnl_parm *p, struct ip6_tnl **pt, int create)
-+{
-+ struct in6_addr *remote = &p->raddr;
-+ struct in6_addr *local = &p->laddr;
-+ struct ip6_tnl *t;
-+
-+ if (p->proto != IPPROTO_IPV6)
-+ return -EINVAL;
-+
-+ for (t = *ip6ip6_bucket(p); t; t = t->next) {
-+ if (!ipv6_addr_cmp(local, &t->parms.laddr) &&
-+ !ipv6_addr_cmp(remote, &t->parms.raddr)) {
-+ *pt = t;
-+ return (create ? -EEXIST : 0);
-+ }
-+ }
-+ return ip6ip6_tnl_create(p, pt);
-+}
-+
-+/**
-+ * ip6ip6_tnl_dev_destructor - tunnel device destructor
-+ * @dev: the device to be destroyed
-+ **/
-+
-+static void
-+ip6ip6_tnl_dev_destructor(struct net_device *dev)
-+{
-+ if (dev != &ip6ip6_fb_tnl_dev) {
-+ MOD_DEC_USE_COUNT;
-+ }
-+}
-+
-+/**
-+ * ip6ip6_tnl_dev_uninit - tunnel device uninitializer
-+ * @dev: the device to be destroyed
-+ *
-+ * Description:
-+ * ip6ip6_tnl_dev_uninit() removes tunnel from its list
-+ **/
-+
-+static void
-+ip6ip6_tnl_dev_uninit(struct net_device *dev)
-+{
-+ struct ip6_tnl *t = (struct ip6_tnl *) dev->priv;
-+
-+ if (dev == &ip6ip6_fb_tnl_dev) {
-+ write_lock_bh(&ip6ip6_lock);
-+ tnls_wc[0] = NULL;
-+ write_unlock_bh(&ip6ip6_lock);
-+ } else {
-+ ip6ip6_tnl_unlink(t);
-+ }
-+ sock_release(t->sock);
-+ dev_put(dev);
-+}
-+
-+/**
-+ * parse_tvl_tnl_enc_lim - handle encapsulation limit option
-+ * @skb: received socket buffer
-+ *
-+ * Return:
-+ * 0 if none was found,
-+ * else index to encapsulation limit
-+ **/
-+
-+static __u16
-+parse_tlv_tnl_enc_lim(struct sk_buff *skb, __u8 * raw)
-+{
-+ struct ipv6hdr *ipv6h = (struct ipv6hdr *) raw;
-+ __u8 nexthdr = ipv6h->nexthdr;
-+ __u16 off = sizeof (*ipv6h);
-+
-+ while (ipv6_ext_hdr(nexthdr) && nexthdr != NEXTHDR_NONE) {
-+ __u16 optlen = 0;
-+ struct ipv6_opt_hdr *hdr;
-+ if (raw + off + sizeof (*hdr) > skb->data &&
-+ !pskb_may_pull(skb, raw - skb->data + off + sizeof (*hdr)))
-+ break;
-+
-+ hdr = (struct ipv6_opt_hdr *) (raw + off);
-+ if (nexthdr == NEXTHDR_FRAGMENT) {
-+ struct frag_hdr *frag_hdr = (struct frag_hdr *) hdr;
-+ if (frag_hdr->frag_off)
-+ break;
-+ optlen = 8;
-+ } else if (nexthdr == NEXTHDR_AUTH) {
-+ optlen = (hdr->hdrlen + 2) << 2;
-+ } else {
-+ optlen = ipv6_optlen(hdr);
-+ }
-+ if (nexthdr == NEXTHDR_DEST) {
-+ __u16 i = off + 2;
-+ while (1) {
-+ struct ipv6_tlv_tnl_enc_lim *tel;
-+
-+ /* No more room for encapsulation limit */
-+ if (i + sizeof (*tel) > off + optlen)
-+ break;
-+
-+ tel = (struct ipv6_tlv_tnl_enc_lim *) &raw[i];
-+ /* return index of option if found and valid */
-+ if (tel->type == IPV6_TLV_TNL_ENCAP_LIMIT &&
-+ tel->length == 1)
-+ return i;
-+ /* else jump to next option */
-+ if (tel->type)
-+ i += tel->length + 2;
-+ else
-+ i++;
-+ }
-+ }
-+ nexthdr = hdr->nexthdr;
-+ off += optlen;
-+ }
-+ return 0;
-+}
-+
-+/**
-+ * ip6ip6_err - tunnel error handler
-+ *
-+ * Description:
-+ * ip6ip6_err() should handle errors in the tunnel according
-+ * to the specifications in RFC 2473.
-+ **/
-+
-+void ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
-+ int type, int code, int offset, __u32 info)
-+{
-+ struct ipv6hdr *ipv6h = (struct ipv6hdr *) skb->data;
-+ struct ip6_tnl *t;
-+ int rel_msg = 0;
-+ int rel_type = ICMPV6_DEST_UNREACH;
-+ int rel_code = ICMPV6_ADDR_UNREACH;
-+ __u32 rel_info = 0;
-+ __u16 len;
-+
-+ /* If the packet doesn't contain the original IPv6 header we are
-+ in trouble since we might need the source address for furter
-+ processing of the error. */
-+
-+ read_lock(&ip6ip6_lock);
-+ if ((t = ip6ip6_tnl_lookup(&ipv6h->daddr, &ipv6h->saddr)) == NULL)
-+ goto out;
-+
-+ switch (type) {
-+ __u32 teli;
-+ struct ipv6_tlv_tnl_enc_lim *tel;
-+ __u32 mtu;
-+ case ICMPV6_DEST_UNREACH:
-+ if (net_ratelimit())
-+ printk(KERN_WARNING
-+ "%s: Path to destination invalid "
-+ "or inactive!\n", t->parms.name);
-+ rel_msg = 1;
-+ break;
-+ case ICMPV6_TIME_EXCEED:
-+ if (code == ICMPV6_EXC_HOPLIMIT) {
-+ if (net_ratelimit())
-+ printk(KERN_WARNING
-+ "%s: Too small hop limit or "
-+ "routing loop in tunnel!\n",
-+ t->parms.name);
-+ rel_msg = 1;
-+ }
-+ break;
-+ case ICMPV6_PARAMPROB:
-+ /* ignore if parameter problem not caused by a tunnel
-+ encapsulation limit sub-option */
-+ if (code != ICMPV6_HDR_FIELD) {
-+ break;
-+ }
-+ teli = parse_tlv_tnl_enc_lim(skb, skb->data);
-+
-+ if (teli && teli == ntohl(info) - 2) {
-+ tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli];
-+ if (tel->encap_limit == 0) {
-+ if (net_ratelimit())
-+ printk(KERN_WARNING
-+ "%s: Too small encapsulation "
-+ "limit or routing loop in "
-+ "tunnel!\n", t->parms.name);
-+ rel_msg = 1;
-+ }
-+ }
-+ break;
-+ case ICMPV6_PKT_TOOBIG:
-+ mtu = ntohl(info) - offset;
-+ if (mtu < IPV6_MIN_MTU)
-+ mtu = IPV6_MIN_MTU;
-+ t->dev->mtu = mtu;
-+
-+ if ((len = sizeof (*ipv6h) + ipv6h->payload_len) > mtu) {
-+ rel_type = ICMPV6_PKT_TOOBIG;
-+ rel_code = 0;
-+ rel_info = mtu;
-+ rel_msg = 1;
-+ }
-+ break;
-+ }
-+ if (rel_msg && pskb_may_pull(skb, offset + sizeof (*ipv6h))) {
-+ struct rt6_info *rt;
-+ struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
-+ if (!skb2)
-+ goto out;
-+
-+ dst_release(skb2->dst);
-+ skb2->dst = NULL;
-+ skb_pull(skb2, offset);
-+ skb2->nh.raw = skb2->data;
-+
-+ /* Try to guess incoming interface */
-+ rt = rt6_lookup(&skb2->nh.ipv6h->saddr, NULL, 0, 0);
-+
-+ if (rt && rt->rt6i_dev)
-+ skb2->dev = rt->rt6i_dev;
-+
-+ icmpv6_send(skb2, rel_type, rel_code, rel_info, skb2->dev);
-+
-+ if (rt)
-+ dst_release(&rt->u.dst);
-+
-+ kfree_skb(skb2);
-+ }
-+out:
-+ read_unlock(&ip6ip6_lock);
-+}
-+
-+/**
-+ * call_hooks - call ipv6 tunnel hooks
-+ * @hooknum: hook number, either %IP6_TNL_PRE_ENCAP, or
-+ * %IP6_TNL_PRE_DECAP
-+ * @t: the current tunnel
-+ * @skb: the tunneled packet
-+ *
-+ * Description:
-+ * Pass packet to all the hook functions until %IP6_TNL_DROP
-+ *
-+ * Return:
-+ * %IP6_TNL_ACCEPT or %IP6_TNL_DROP
-+ **/
-+
-+static inline int
-+call_hooks(unsigned int hooknum, struct ip6_tnl *t, struct sk_buff *skb)
-+{
-+ struct ip6_tnl_hook_ops *h;
-+ int accept = IP6_TNL_ACCEPT;
-+
-+ if (hooknum < IP6_TNL_MAXHOOKS) {
-+ struct list_head *i;
-+ read_lock(&ip6ip6_hook_lock);
-+ for (i = hooks[hooknum].next; i != &hooks[hooknum]; i = i->next) {
-+ h = (struct ip6_tnl_hook_ops *) i;
-+
-+ if (h->hook) {
-+ accept = h->hook(t, skb);
-+
-+ if (accept != IP6_TNL_ACCEPT)
-+ break;
-+ }
-+ }
-+ read_unlock(&ip6ip6_hook_lock);
-+ }
-+ return accept;
-+}
-+
-+/**
-+ * ip6ip6_rcv - decapsulate IPv6 packet and retransmit it locally
-+ * @skb: received socket buffer
-+ *
-+ * Return: 0
-+ **/
-+
-+int ip6ip6_rcv(struct sk_buff *skb)
-+{
-+ struct ipv6hdr *ipv6h;
-+ struct ip6_tnl *t;
-+
-+ if (!pskb_may_pull(skb, sizeof (*ipv6h)))
-+ goto discard;
-+
-+ ipv6h = skb->nh.ipv6h;
-+
-+ read_lock(&ip6ip6_lock);
-+
-+ if ((t = ip6ip6_tnl_lookup(&ipv6h->saddr, &ipv6h->daddr)) != NULL) {
-+ if (!(t->parms.flags & IP6_TNL_F_CAP_RCV) ||
-+ call_hooks(IP6_TNL_PRE_DECAP, t, skb) != IP6_TNL_ACCEPT) {
-+ t->stat.rx_dropped++;
-+ read_unlock(&ip6ip6_lock);
-+ goto discard;
-+ }
-+ skb->mac.raw = skb->nh.raw;
-+ skb->nh.raw = skb->data;
-+ skb->protocol = htons(ETH_P_IPV6);
-+ skb->pkt_type = PACKET_HOST;
-+ memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
-+ skb->dev = t->dev;
-+ dst_release(skb->dst);
-+ skb->dst = NULL;
-+ t->stat.rx_packets++;
-+ t->stat.rx_bytes += skb->len;
-+ netif_rx(skb);
-+ read_unlock(&ip6ip6_lock);
-+ return 0;
-+ }
-+ read_unlock(&ip6ip6_lock);
-+ icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, skb->dev);
-+discard:
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+static inline struct ipv6_txoptions *create_tel(__u8 encap_limit)
-+{
-+ struct ipv6_tlv_tnl_enc_lim *tel;
-+ struct ipv6_txoptions *opt;
-+ __u8 *raw;
-+
-+ int opt_len = sizeof(*opt) + IPV6_TLV_TEL_DST_SIZE;
-+
-+ if (!(opt = kmalloc(opt_len, GFP_ATOMIC))) {
-+ return NULL;
-+ }
-+ memset(opt, 0, opt_len);
-+ opt->tot_len = opt_len;
-+ opt->dst0opt = (struct ipv6_opt_hdr *) (opt + 1);
-+ opt->opt_nflen = 8;
-+
-+ tel = (struct ipv6_tlv_tnl_enc_lim *) (opt->dst0opt + 1);
-+ tel->type = IPV6_TLV_TNL_ENCAP_LIMIT;
-+ tel->length = 1;
-+ tel->encap_limit = encap_limit;
-+
-+ raw = (__u8 *) opt->dst0opt;
-+ raw[5] = IPV6_TLV_PADN;
-+ raw[6] = 1;
-+
-+ return opt;
-+}
-+
-+static int
-+ip6ip6_getfrag(const void *data, struct in6_addr *addr,
-+ char *buff, unsigned int offset, unsigned int len)
-+{
-+ memcpy(buff, data + offset, len);
-+ return 0;
-+}
-+
-+/**
-+ * ip6ip6_tnl_addr_conflict - compare packet addresses to tunnel's own
-+ * @t: the outgoing tunnel device
-+ * @hdr: IPv6 header from the incoming packet
-+ *
-+ * Description:
-+ * Avoid trivial tunneling loop by checking that tunnel exit-point
-+ * doesn't match source of incoming packet.
-+ *
-+ * Return:
-+ * 1 if conflict,
-+ * 0 else
-+ **/
-+
-+static inline int
-+ip6ip6_tnl_addr_conflict(struct ip6_tnl *t, struct ipv6hdr *hdr)
-+{
-+ return !ipv6_addr_cmp(&t->parms.raddr, &hdr->saddr);
-+}
-+
-+/**
-+ * ip6ip6_tnl_xmit - encapsulate packet and send
-+ * @skb: the outgoing socket buffer
-+ * @dev: the outgoing tunnel device
-+ *
-+ * Description:
-+ * Build new header and do some sanity checks on the packet before sending
-+ * it to ip6_build_xmit().
-+ *
-+ * Return:
-+ * 0
-+ **/
-+
-+int ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+ struct ip6_tnl *t = (struct ip6_tnl *) dev->priv;
-+ struct net_device_stats *stats = &t->stat;
-+ struct ipv6hdr *ipv6h = skb->nh.ipv6h;
-+ struct ipv6_txoptions *opt = NULL;
-+ int encap_limit = -1;
-+ __u16 offset;
-+ struct flowi fl;
-+ int err = 0;
-+ struct dst_entry *dst;
-+ struct sock *sk = t->sock->sk;
-+ struct ipv6_pinfo *np = &sk->net_pinfo.af_inet6;
-+ int mtu;
-+
-+ if (t->recursion++) {
-+ stats->collisions++;
-+ goto tx_err;
-+ }
-+ if (skb->protocol != htons(ETH_P_IPV6) ||
-+ !(t->parms.flags & IP6_TNL_F_CAP_XMIT) ||
-+ ip6ip6_tnl_addr_conflict(t, ipv6h)) {
-+ goto tx_err;
-+ }
-+ if ((offset = parse_tlv_tnl_enc_lim(skb, skb->nh.raw)) > 0) {
-+ struct ipv6_tlv_tnl_enc_lim *tel;
-+ tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->nh.raw[offset];
-+ if (tel->encap_limit == 0) {
-+ icmpv6_send(skb, ICMPV6_PARAMPROB,
-+ ICMPV6_HDR_FIELD, offset + 2, skb->dev);
-+ goto tx_err;
-+ }
-+ encap_limit = tel->encap_limit - 1;
-+ } else if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) {
-+ encap_limit = t->parms.encap_limit;
-+ }
-+ if (call_hooks(IP6_TNL_PRE_ENCAP, t, skb) != IP6_TNL_ACCEPT)
-+ goto discard;
-+ memcpy(&fl, &t->fl, sizeof (fl));
-+
-+ if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS))
-+ fl.fl6_flowlabel |= (*(__u32 *) ipv6h & IPV6_TCLASS_MASK);
-+ if ((t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL))
-+ fl.fl6_flowlabel |= (*(__u32 *) ipv6h & IPV6_FLOWLABEL_MASK);
-+
-+ if (encap_limit >= 0 && (opt = create_tel(encap_limit)) == NULL)
-+ goto tx_err;
-+
-+ dst = __sk_dst_check(sk, np->dst_cookie);
-+
-+ if (dst) {
-+ if (np->daddr_cache == NULL ||
-+ ipv6_addr_cmp(fl.fl6_dst, np->daddr_cache) ||
-+#ifdef CONFIG_IPV6_SUBTREES
-+ np->saddr_cache == NULL ||
-+ ipv6_addr_cmp(fl.fl6_src, np->saddr_cache) ||
-+#endif
-+ (fl.oif && fl.oif != dst->dev->ifindex)) {
-+ dst = NULL;
-+ } else {
-+ dst_hold(dst);
-+ }
-+ }
-+ if (dst == NULL) {
-+ dst = ip6_route_output(sk, &fl);
-+ if (dst->error) {
-+ stats->tx_carrier_errors++;
-+ dst_link_failure(skb);
-+ goto tx_err_dst_release;
-+ }
-+ /* local routing loop */
-+ if (dst->dev == dev) {
-+ stats->collisions++;
-+ if (net_ratelimit())
-+ printk(KERN_WARNING
-+ "%s: Local routing loop detected!\n",
-+ t->parms.name);
-+ goto tx_err_dst_release;
-+ }
-+ }
-+ mtu = dst->pmtu - sizeof (*ipv6h);
-+ if (opt) {
-+ mtu -= (opt->opt_nflen + opt->opt_flen);
-+ }
-+ if (mtu < IPV6_MIN_MTU)
-+ mtu = IPV6_MIN_MTU;
-+ if (skb->dst && mtu < skb->dst->pmtu) {
-+ struct rt6_info *rt = (struct rt6_info *) skb->dst;
-+ rt->rt6i_flags |= RTF_MODIFIED;
-+ rt->u.dst.pmtu = mtu;
-+ }
-+ if (skb->len > mtu) {
-+ icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
-+ goto tx_err_dst_release;
-+ }
-+ ip6_dst_store(sk, dst, &np->daddr, &np->saddr);
-+ err = ip6_build_xmit(sk, ip6ip6_getfrag, (void *) skb->nh.raw,
-+ &fl, skb->len, opt, t->parms.hop_limit,
-+ MSG_DONTWAIT);
-+
-+ if (err == NET_XMIT_SUCCESS || err == NET_XMIT_CN) {
-+ stats->tx_bytes += skb->len;
-+ stats->tx_packets++;
-+ } else {
-+ stats->tx_errors++;
-+ stats->tx_aborted_errors++;
-+ }
-+ if (opt)
-+ kfree(opt);
-+ kfree_skb(skb);
-+ t->recursion--;
-+ return 0;
-+tx_err_dst_release:
-+ dst_release(dst);
-+ if (opt)
-+ kfree(opt);
-+tx_err:
-+ stats->tx_errors++;
-+discard:
-+ stats->tx_dropped++;
-+ kfree_skb(skb);
-+ t->recursion--;
-+ return 0;
-+}
-+
-+static void ip6_tnl_set_cap(struct ip6_tnl *t)
-+{
-+ struct ip6_tnl_parm *p = &t->parms;
-+ struct in6_addr *laddr = &p->laddr;
-+ struct in6_addr *raddr = &p->raddr;
-+ int ltype = ipv6_addr_type(laddr);
-+ int rtype = ipv6_addr_type(raddr);
-+
-+ p->flags &= ~(IP6_TNL_F_CAP_XMIT|IP6_TNL_F_CAP_RCV);
-+
-+ if (ltype != IPV6_ADDR_ANY && rtype != IPV6_ADDR_ANY &&
-+ ((ltype|rtype) &
-+ (IPV6_ADDR_UNICAST|
-+ IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL|
-+ IPV6_ADDR_MAPPED|IPV6_ADDR_RESERVED)) == IPV6_ADDR_UNICAST) {
-+ struct net_device *ldev = NULL;
-+ int l_ok = 1;
-+ int r_ok = 1;
-+
-+ if (p->link)
-+ ldev = dev_get_by_index(p->link);
-+
-+ if ((ltype&IPV6_ADDR_UNICAST) && !ipv6_chk_addr(laddr, ldev))
-+ l_ok = 0;
-+
-+ if ((rtype&IPV6_ADDR_UNICAST) && ipv6_chk_addr(raddr, NULL))
-+ r_ok = 0;
-+
-+ if (l_ok && r_ok) {
-+ if (ltype&IPV6_ADDR_UNICAST)
-+ p->flags |= IP6_TNL_F_CAP_XMIT;
-+ if (rtype&IPV6_ADDR_UNICAST)
-+ p->flags |= IP6_TNL_F_CAP_RCV;
-+ }
-+ if (ldev)
-+ dev_put(ldev);
-+ }
-+}
-+
-+static void ip6ip6_tnl_link_config(struct ip6_tnl *t)
-+{
-+ struct net_device *dev = t->dev;
-+ struct ip6_tnl_parm *p = &t->parms;
-+ struct flowi *fl = &t->fl;
-+
-+ /* Set up flowi template */
-+ fl->fl6_src = &p->laddr;
-+ fl->fl6_dst = &p->raddr;
-+ fl->oif = p->link;
-+ fl->fl6_flowlabel = 0;
-+
-+ if (!(p->flags&IP6_TNL_F_USE_ORIG_TCLASS))
-+ fl->fl6_flowlabel |= IPV6_TCLASS_MASK & htonl(p->flowinfo);
-+ if (!(p->flags&IP6_TNL_F_USE_ORIG_FLOWLABEL))
-+ fl->fl6_flowlabel |= IPV6_FLOWLABEL_MASK & htonl(p->flowinfo);
-+
-+ ip6_tnl_set_cap(t);
-+
-+ if (p->flags&IP6_TNL_F_CAP_XMIT && p->flags&IP6_TNL_F_CAP_RCV)
-+ dev->flags |= IFF_POINTOPOINT;
-+ else
-+ dev->flags &= ~IFF_POINTOPOINT;
-+
-+ if (p->flags & IP6_TNL_F_CAP_XMIT) {
-+ struct rt6_info *rt = rt6_lookup(&p->raddr, &p->laddr,
-+ p->link, 0);
-+
-+ if (rt == NULL)
-+ return;
-+
-+ if (rt->rt6i_dev) {
-+ dev->iflink = rt->rt6i_dev->ifindex;
-+
-+ dev->hard_header_len = rt->rt6i_dev->hard_header_len +
-+ sizeof (struct ipv6hdr);
-+
-+ dev->mtu = rt->rt6i_dev->mtu - sizeof (struct ipv6hdr);
-+
-+ if (dev->mtu < IPV6_MIN_MTU)
-+ dev->mtu = IPV6_MIN_MTU;
-+ }
-+ dst_release(&rt->u.dst);
-+ }
-+}
-+
-+/**
-+ * __ip6ip6_tnl_change - update the tunnel parameters
-+ * @t: tunnel to be changed
-+ * @p: tunnel configuration parameters
-+ *
-+ * Description:
-+ * __ip6ip6_tnl_change() updates the tunnel parameters
-+ **/
-+
-+static void
-+__ip6ip6_tnl_change(struct ip6_tnl *t, struct ip6_tnl_parm *p)
-+{
-+ ipv6_addr_copy(&t->parms.laddr, &p->laddr);
-+ ipv6_addr_copy(&t->parms.raddr, &p->raddr);
-+ t->parms.flags = p->flags;
-+ t->parms.hop_limit = p->hop_limit;
-+ t->parms.encap_limit = p->encap_limit;
-+ t->parms.flowinfo = p->flowinfo;
-+ ip6ip6_tnl_link_config(t);
-+}
-+
-+void ip6ip6_tnl_change(struct ip6_tnl *t, struct ip6_tnl_parm *p)
-+{
-+ ip6ip6_tnl_unlink(t);
-+ __ip6ip6_tnl_change(t, p);
-+ ip6ip6_tnl_link(t);
-+}
-+
-+/**
-+ * ip6ip6_kernel_tnl_add - configure and add kernel tunnel to hash
-+ * @p: kernel tunnel configuration parameters
-+ *
-+ * Description:
-+ * ip6ip6_kernel_tnl_add() fetches an unused kernel tunnel configures
-+ * it according to @p and places it among the active tunnels.
-+ *
-+ * Return:
-+ * number of references to tunnel on success,
-+ * %-EEXIST if there is already a device matching description
-+ * %-EINVAL if p->flags doesn't have %IP6_TNL_F_KERNEL_DEV raised,
-+ * %-ENODEV if there are no unused kernel tunnels available
-+ *
-+ * Note:
-+ * The code for creating, opening, closing and destroying network devices
-+ * must be called from process context, while the Mobile IP code, which
-+ * needs the tunnel devices, unfortunately runs in interrupt context.
-+ *
-+ * The devices must be created and opened in advance, then placed in a
-+ * list where the kernel can fetch and ready them for use at a later time.
-+ *
-+ **/
-+
-+int
-+ip6ip6_kernel_tnl_add(struct ip6_tnl_parm *p)
-+{
-+ struct ip6_tnl *t;
-+
-+ if (!(p->flags & IP6_TNL_F_KERNEL_DEV))
-+ return -EINVAL;
-+ if ((t = ip6ip6_tnl_lookup(&p->raddr, &p->laddr)) != NULL &&
-+ t != &ip6ip6_fb_tnl) {
-+ /* Handle duplicate tunnels by incrementing
-+ reference count */
-+ atomic_inc(&t->refcnt);
-+ goto out;
-+ }
-+ if ((t = ip6ip6_kernel_tnl_unlink()) == NULL)
-+ return -ENODEV;
-+ __ip6ip6_tnl_change(t, p);
-+
-+ atomic_inc(&t->refcnt);
-+
-+ ip6ip6_tnl_link(t);
-+
-+ manage_kernel_tnls(NULL);
-+out:
-+ return atomic_read(&t->refcnt);
-+}
-+
-+/**
-+ * ip6ip6_kernel_tnl_del - delete no longer needed kernel tunnel
-+ * @t: kernel tunnel to be removed from hash
-+ *
-+ * Description:
-+ * ip6ip6_kernel_tnl_del() removes and deconfigures the tunnel @t
-+ * and places it among the unused kernel devices.
-+ *
-+ * Return:
-+ * number of references on success,
-+ * %-EINVAL if p->flags doesn't have %IP6_TNL_F_KERNEL_DEV raised,
-+ *
-+ * Note:
-+ * See the comments on ip6ip6_kernel_tnl_add() for more information.
-+ **/
-+
-+int
-+ip6ip6_kernel_tnl_del(struct ip6_tnl *t)
-+{
-+ if (!t)
-+ return -ENODEV;
-+
-+ if (!(t->parms.flags & IP6_TNL_F_KERNEL_DEV))
-+ return -EINVAL;
-+
-+ if (atomic_dec_and_test(&t->refcnt)) {
-+ struct ip6_tnl_parm p;
-+ ip6ip6_tnl_unlink(t);
-+ memset(&p, 0, sizeof (p));
-+ p.flags = IP6_TNL_F_KERNEL_DEV;
-+
-+ __ip6ip6_tnl_change(t, &p);
-+
-+ ip6ip6_kernel_tnl_link(t);
-+
-+ manage_kernel_tnls(NULL);
-+ }
-+ return atomic_read(&t->refcnt);
-+}
-+
-+/**
-+ * ip6ip6_tnl_ioctl - configure ipv6 tunnels from userspace
-+ * @dev: virtual device associated with tunnel
-+ * @ifr: parameters passed from userspace
-+ * @cmd: command to be performed
-+ *
-+ * Description:
-+ * ip6ip6_tnl_ioctl() is used for managing IPv6 tunnels
-+ * from userspace.
-+ *
-+ * The possible commands are the following:
-+ * %SIOCGETTUNNEL: get tunnel parameters for device
-+ * %SIOCADDTUNNEL: add tunnel matching given tunnel parameters
-+ * %SIOCCHGTUNNEL: change tunnel parameters to those given
-+ * %SIOCDELTUNNEL: delete tunnel
-+ *
-+ * The fallback device "ip6tnl0", created during module
-+ * initialization, can be used for creating other tunnel devices.
-+ *
-+ * Return:
-+ * 0 on success,
-+ * %-EFAULT if unable to copy data to or from userspace,
-+ * %-EPERM if current process hasn't %CAP_NET_ADMIN set or attempting
-+ * to configure kernel devices from userspace,
-+ * %-EINVAL if passed tunnel parameters are invalid,
-+ * %-EEXIST if changing a tunnel's parameters would cause a conflict
-+ * %-ENODEV if attempting to change or delete a nonexisting device
-+ *
-+ * Note:
-+ * See the comments on ip6ip6_kernel_tnl_add() for more information
-+ * about kernel tunnels.
-+ * **/
-+
-+static int
-+ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-+{
-+ int err = 0;
-+ int create;
-+ struct ip6_tnl_parm p;
-+ struct ip6_tnl *t = NULL;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ switch (cmd) {
-+ case SIOCGETTUNNEL:
-+ if (dev == &ip6ip6_fb_tnl_dev) {
-+ if (copy_from_user(&p,
-+ ifr->ifr_ifru.ifru_data,
-+ sizeof (p))) {
-+ err = -EFAULT;
-+ break;
-+ }
-+ if ((err = ip6ip6_tnl_locate(&p, &t, 0)) == -ENODEV)
-+ t = (struct ip6_tnl *) dev->priv;
-+ else if (err)
-+ break;
-+ } else
-+ t = (struct ip6_tnl *) dev->priv;
-+
-+ memcpy(&p, &t->parms, sizeof (p));
-+ if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) {
-+ err = -EFAULT;
-+ }
-+ break;
-+ case SIOCADDTUNNEL:
-+ case SIOCCHGTUNNEL:
-+ err = -EPERM;
-+ create = (cmd == SIOCADDTUNNEL);
-+ if (!capable(CAP_NET_ADMIN))
-+ break;
-+ if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p))) {
-+ err = -EFAULT;
-+ break;
-+ }
-+ if (p.flags & IP6_TNL_F_KERNEL_DEV) {
-+ break;
-+ }
-+ if (!create && dev != &ip6ip6_fb_tnl_dev) {
-+ t = (struct ip6_tnl *) dev->priv;
-+ }
-+ if (!t && (err = ip6ip6_tnl_locate(&p, &t, create))) {
-+ break;
-+ }
-+ if (cmd == SIOCCHGTUNNEL) {
-+ if (t->dev != dev) {
-+ err = -EEXIST;
-+ break;
-+ }
-+ if (t->parms.flags & IP6_TNL_F_KERNEL_DEV) {
-+ err = -EPERM;
-+ break;
-+ }
-+ ip6ip6_tnl_change(t, &p);
-+ netdev_state_change(dev);
-+ }
-+ if (copy_to_user(ifr->ifr_ifru.ifru_data,
-+ &t->parms, sizeof (p))) {
-+ err = -EFAULT;
-+ } else {
-+ err = 0;
-+ }
-+ break;
-+ case SIOCDELTUNNEL:
-+ err = -EPERM;
-+ if (!capable(CAP_NET_ADMIN))
-+ break;
-+
-+ if (dev == &ip6ip6_fb_tnl_dev) {
-+ if (copy_from_user(&p, ifr->ifr_ifru.ifru_data,
-+ sizeof (p))) {
-+ err = -EFAULT;
-+ break;
-+ }
-+ err = ip6ip6_tnl_locate(&p, &t, 0);
-+ if (err)
-+ break;
-+ if (t == &ip6ip6_fb_tnl) {
-+ err = -EPERM;
-+ break;
-+ }
-+ } else {
-+ t = (struct ip6_tnl *) dev->priv;
-+ }
-+ if (t->parms.flags & IP6_TNL_F_KERNEL_DEV)
-+ err = -EPERM;
-+ else
-+ err = unregister_netdevice(t->dev);
-+ break;
-+ default:
-+ err = -EINVAL;
-+ }
-+ MOD_DEC_USE_COUNT;
-+ return err;
-+}
-+
-+/**
-+ * ip6ip6_tnl_get_stats - return the stats for tunnel device
-+ * @dev: virtual device associated with tunnel
-+ *
-+ * Return: stats for device
-+ **/
-+
-+static struct net_device_stats *
-+ip6ip6_tnl_get_stats(struct net_device *dev)
-+{
-+ return &(((struct ip6_tnl *) dev->priv)->stat);
-+}
-+
-+/**
-+ * ip6ip6_tnl_change_mtu - change mtu manually for tunnel device
-+ * @dev: virtual device associated with tunnel
-+ * @new_mtu: the new mtu
-+ *
-+ * Return:
-+ * 0 on success,
-+ * %-EINVAL if mtu too small
-+ **/
-+
-+static int
-+ip6ip6_tnl_change_mtu(struct net_device *dev, int new_mtu)
-+{
-+ if (new_mtu < IPV6_MIN_MTU) {
-+ return -EINVAL;
-+ }
-+ dev->mtu = new_mtu;
-+ return 0;
-+}
-+
-+/**
-+ * ip6ip6_tnl_dev_init_gen - general initializer for all tunnel devices
-+ * @dev: virtual device associated with tunnel
-+ *
-+ * Description:
-+ * Set function pointers and initialize the &struct flowi template used
-+ * by the tunnel.
-+ **/
-+
-+static int
-+ip6ip6_tnl_dev_init_gen(struct net_device *dev)
-+{
-+ struct ip6_tnl *t = (struct ip6_tnl *) dev->priv;
-+ struct flowi *fl = &t->fl;
-+ int err;
-+ struct sock *sk;
-+
-+ if ((err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_IPV6, &t->sock))) {
-+ printk(KERN_ERR
-+ "Failed to create IPv6 tunnel socket (err %d).\n", err);
-+ return err;
-+ }
-+ t->sock->inode->i_uid = 0;
-+ t->sock->inode->i_gid = 0;
-+
-+ sk = t->sock->sk;
-+ sk->allocation = GFP_ATOMIC;
-+ sk->net_pinfo.af_inet6.hop_limit = 254;
-+ sk->net_pinfo.af_inet6.mc_loop = 0;
-+ sk->prot->unhash(sk);
-+
-+ memset(fl, 0, sizeof (*fl));
-+ fl->proto = IPPROTO_IPV6;
-+
-+ dev->destructor = ip6ip6_tnl_dev_destructor;
-+ dev->uninit = ip6ip6_tnl_dev_uninit;
-+ dev->hard_start_xmit = ip6ip6_tnl_xmit;
-+ dev->get_stats = ip6ip6_tnl_get_stats;
-+ dev->do_ioctl = ip6ip6_tnl_ioctl;
-+ dev->change_mtu = ip6ip6_tnl_change_mtu;
-+
-+ dev->type = ARPHRD_TUNNEL6;
-+ dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr);
-+ dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr);
-+ dev->flags |= IFF_NOARP;
-+ dev->iflink = 0;
-+ /* Hmm... MAX_ADDR_LEN is 8, so the ipv6 addresses can't be
-+ copied to dev->dev_addr and dev->broadcast, like the ipv4
-+ addresses were in ipip.c, ip_gre.c and sit.c. */
-+ dev->addr_len = 0;
-+ return 0;
-+}
-+
-+/**
-+ * ip6ip6_tnl_dev_init - initializer for all non fallback tunnel devices
-+ * @dev: virtual device associated with tunnel
-+ **/
-+
-+static int
-+ip6ip6_tnl_dev_init(struct net_device *dev)
-+{
-+ struct ip6_tnl *t = (struct ip6_tnl *) dev->priv;
-+ ip6ip6_tnl_dev_init_gen(dev);
-+ ip6ip6_tnl_link_config(t);
-+ return 0;
-+}
-+
-+#ifdef MODULE
-+
-+/**
-+ * ip6ip6_fb_tnl_open - function called when fallback device opened
-+ * @dev: fallback device
-+ *
-+ * Return: 0
-+ **/
-+
-+static int
-+ip6ip6_fb_tnl_open(struct net_device *dev)
-+{
-+ MOD_INC_USE_COUNT;
-+ return 0;
-+}
-+
-+/**
-+ * ip6ip6_fb_tnl_close - function called when fallback device closed
-+ * @dev: fallback device
-+ *
-+ * Return: 0
-+ **/
-+
-+static int
-+ip6ip6_fb_tnl_close(struct net_device *dev)
-+{
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+#endif
-+
-+/**
-+ * ip6ip6_fb_tnl_dev_init - initializer for fallback tunnel device
-+ * @dev: fallback device
-+ *
-+ * Return: 0
-+ **/
-+
-+int __init
-+ip6ip6_fb_tnl_dev_init(struct net_device *dev)
-+{
-+ ip6ip6_tnl_dev_init_gen(dev);
-+#ifdef MODULE
-+ dev->open = ip6ip6_fb_tnl_open;
-+ dev->stop = ip6ip6_fb_tnl_close;
-+#endif
-+ dev_hold(dev);
-+ tnls_wc[0] = &ip6ip6_fb_tnl;
-+ return 0;
-+}
-+
-+/**
-+ * ip6ip6_tnl_register_hook - add hook for processing of tunneled packets
-+ * @reg: hook function and its parameters
-+ *
-+ * Description:
-+ * Add a netfilter like hook function for special handling of tunneled
-+ * packets. The hook functions are called before encapsulation
-+ * (%IP6_TNL_PRE_ENCAP) and before decapsulation
-+ * (%IP6_TNL_PRE_DECAP). The possible return values by the hook
-+ * functions are %IP6_TNL_DROP, %IP6_TNL_ACCEPT and
-+ * %IP6_TNL_STOLEN (in case the hook function took care of the packet
-+ * and it doesn't have to be processed any further).
-+ **/
-+
-+void
-+ip6ip6_tnl_register_hook(struct ip6_tnl_hook_ops *reg)
-+{
-+ if (reg->hooknum < IP6_TNL_MAXHOOKS) {
-+ struct list_head *i;
-+
-+ write_lock_bh(&ip6ip6_hook_lock);
-+ for (i = hooks[reg->hooknum].next;
-+ i != &hooks[reg->hooknum]; i = i->next) {
-+ if (reg->priority <
-+ ((struct ip6_tnl_hook_ops *) i)->priority) {
-+ break;
-+ }
-+ }
-+ list_add(&reg->list, i->prev);
-+ write_unlock_bh(&ip6ip6_hook_lock);
-+ }
-+}
-+
-+/**
-+ * ip6ip6_tnl_unregister_hook - remove tunnel hook
-+ * @reg: hook function and its parameters
-+ **/
-+
-+void
-+ip6ip6_tnl_unregister_hook(struct ip6_tnl_hook_ops *reg)
-+{
-+ if (reg->hooknum < IP6_TNL_MAXHOOKS) {
-+ write_lock_bh(&ip6ip6_hook_lock);
-+ list_del(&reg->list);
-+ write_unlock_bh(&ip6ip6_hook_lock);
-+ }
-+}
-+
-+
-+/* the IPv6 over IPv6 protocol structure */
-+static struct inet6_protocol ip6ip6_protocol = {
-+ ip6ip6_rcv, /* IPv6 handler */
-+ ip6ip6_err, /* IPv6 error control */
-+ NULL, /* next */
-+ IPPROTO_IPV6, /* protocol ID */
-+ 0, /* copy */
-+ NULL, /* data */
-+ "IPv6 over IPv6" /* name */
-+};
-+
-+/**
-+ * ip6_tunnel_init - register protocol and reserve needed resources
-+ *
-+ * Return: 0 on success
-+ **/
-+
-+int __init ip6_tunnel_init(void)
-+{
-+ int i, err;
-+
-+ ip6ip6_fb_tnl_dev.priv = (void *) &ip6ip6_fb_tnl;
-+
-+ for (i = 0; i < IP6_TNL_MAXHOOKS; i++) {
-+ INIT_LIST_HEAD(&hooks[i]);
-+ }
-+ if ((err = register_netdev(&ip6ip6_fb_tnl_dev)))
-+ return err;
-+
-+ inet6_add_protocol(&ip6ip6_protocol);
-+ return 0;
-+}
-+
-+/**
-+ * ip6_tunnel_cleanup - free resources and unregister protocol
-+ **/
-+
-+void ip6_tunnel_cleanup(void)
-+{
-+ write_lock_bh(&ip6ip6_kernel_lock);
-+ shutdown = 1;
-+ write_unlock_bh(&ip6ip6_kernel_lock);
-+ flush_scheduled_tasks();
-+ manage_kernel_tnls(NULL);
-+ inet6_del_protocol(&ip6ip6_protocol);
-+ unregister_netdev(&ip6ip6_fb_tnl_dev);
-+}
-+
-+#ifdef MODULE
-+module_init(ip6_tunnel_init);
-+module_exit(ip6_tunnel_cleanup);
-+#endif
-+
-+#if defined(CONFIG_IPV6_MOBILITY_HA_MODULE) || defined(CONFIG_IPV6_MOBILITY_MN_MODULE)
-+EXPORT_SYMBOL(ip6ip6_tnl_register_hook);
-+EXPORT_SYMBOL(ip6ip6_tnl_unregister_hook);
-+#endif
-+#ifdef CONFIG_IPV6_MOBILITY_HA_MODULE
-+EXPORT_SYMBOL(ip6ip6_tnl_dec_max_kdev_count);
-+EXPORT_SYMBOL(ip6ip6_tnl_inc_max_kdev_count);
-+EXPORT_SYMBOL(ip6ip6_tnl_dec_min_kdev_count);
-+EXPORT_SYMBOL(ip6ip6_tnl_inc_min_kdev_count);
-+EXPORT_SYMBOL(ip6ip6_kernel_tnl_add);
-+EXPORT_SYMBOL(ip6ip6_kernel_tnl_del);
-+EXPORT_SYMBOL(ip6ip6_tnl_lookup);
-+#endif
-+#ifdef CONFIG_IPV6_MOBILITY_MN_MODULE
-+EXPORT_SYMBOL(ip6ip6_tnl_create);
-+EXPORT_SYMBOL(ip6ip6_tnl_change);
-+#endif
-+
-diff -uprN linux-2.4.25.old/net/ipv6/mipglue.c linux-2.4.25/net/ipv6/mipglue.c
---- linux-2.4.25.old/net/ipv6/mipglue.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mipglue.c 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,63 @@
-+/*
-+ * Glue for Mobility support integration to IPv6
-+ *
-+ * Authors:
-+ * Antti Tuominen <ajtuomin@cc.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ *
-+ */
-+
-+#include <linux/sched.h>
-+
-+#include <net/ipv6.h>
-+#include <net/addrconf.h>
-+#include <net/neighbour.h>
-+#include <net/mipglue.h>
-+
-+extern int ip6_tlvopt_unknown(struct sk_buff *skb, int optoff);
-+
-+/* Initialize all zero */
-+struct mipv6_callable_functions mipv6_functions = { NULL };
-+
-+/* Sets mipv6_functions struct to zero to invalidate all successive
-+ * calls to mipv6 functions. Used on module unload. */
-+
-+void mipv6_invalidate_calls(void)
-+{
-+ memset(&mipv6_functions, 0, sizeof(mipv6_functions));
-+}
-+
-+
-+/* Selects correct handler for tlv encoded destination option. Called
-+ * by ip6_parse_tlv. Checks if mipv6 calls are valid before calling. */
-+
-+int mipv6_handle_dstopt(struct sk_buff *skb, int optoff)
-+{
-+ int ret;
-+
-+ switch (skb->nh.raw[optoff]) {
-+ case MIPV6_TLV_HOMEADDR:
-+ ret = MIPV6_CALLFUNC(mipv6_handle_homeaddr, 0)(skb, optoff);
-+ break;
-+ default:
-+ /* Should never happen */
-+ printk(KERN_ERR __FILE__ ": Invalid destination option code (%d)\n",
-+ skb->nh.raw[optoff]);
-+ ret = 1;
-+ break;
-+ }
-+
-+ /* If mipv6 handlers are not valid, pass the packet to
-+ * ip6_tlvopt_unknown() for correct handling. */
-+ if (!ret)
-+ return ip6_tlvopt_unknown(skb, optoff);
-+
-+ return ret;
-+}
-+
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/Config.in linux-2.4.25/net/ipv6/mobile_ip6/Config.in
---- linux-2.4.25.old/net/ipv6/mobile_ip6/Config.in 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/Config.in 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,12 @@
-+#
-+# Mobile IPv6 Configuration
-+#
-+dep_tristate ' IPv6: Mobility Support (Correspondent Node)' CONFIG_IPV6_MOBILITY $CONFIG_IPV6
-+if [ "$CONFIG_IPV6_IPV6_TUNNEL" != "n" ]; then
-+ dep_tristate ' MIPv6: Mobile Node Support' CONFIG_IPV6_MOBILITY_MN $CONFIG_IPV6_MOBILITY
-+
-+ dep_tristate ' MIPv6: Home Agent Support' CONFIG_IPV6_MOBILITY_HA $CONFIG_IPV6_MOBILITY
-+fi
-+if [ "$CONFIG_IPV6_MOBILITY" != "n" ]; then
-+ bool ' MIPv6: Debug messages' CONFIG_IPV6_MOBILITY_DEBUG
-+fi
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/Makefile linux-2.4.25/net/ipv6/mobile_ip6/Makefile
---- linux-2.4.25.old/net/ipv6/mobile_ip6/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/Makefile 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,35 @@
-+#
-+# Makefile for the MIPL Mobile IPv6 for Linux.
-+#
-+# Note! Dependencies are done automagically by 'make dep', which also
-+# removes any old dependencies. DON'T put your own dependencies here
-+# unless it's something special (ie not a .c file).
-+#
-+
-+
-+O_TARGET := mip6_base.o
-+
-+list-multi := mip6_ha.o mip6_mn.o
-+
-+obj-y := hashlist.o bcache.o mobhdr_common.o stats.o exthdrs.o \
-+ rr_crypto.o hmac.o auth_opt.o mipv6_icmp.o module_cn.o
-+
-+obj-m := $(O_TARGET)
-+
-+mip6_ha-objs := halist.o mipv6_icmp_ha.o tunnel_ha.o \
-+ ndisc_ha.o ha.o module_ha.o
-+
-+mip6_mn-objs := mipv6_icmp_mn.o ioctl_mn.o tunnel_mn.o \
-+ mdetect.o bul.o multiaccess_ctl.o mobhdr_mn.o mn.o \
-+ module_mn.o
-+
-+obj-$(CONFIG_IPV6_MOBILITY_HA) += mip6_ha.o
-+obj-$(CONFIG_IPV6_MOBILITY_MN) += mip6_mn.o
-+
-+include $(TOPDIR)/Rules.make
-+
-+mip6_ha.o: $(mip6_ha-objs)
-+ $(LD) -r -o $@ $(mip6_ha-objs)
-+
-+mip6_mn.o: $(mip6_mn-objs)
-+ $(LD) -r -o $@ $(mip6_mn-objs)
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/README linux-2.4.25/net/ipv6/mobile_ip6/README
---- linux-2.4.25.old/net/ipv6/mobile_ip6/README 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/README 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,15 @@
-+MIPL Mobile IPv6 for Linux
-+
-+More information at http://www.mipl.mediapoli.com/.
-+
-+To join MIPL Mobile IPv6 for Linux mailing lists go to:
-+
-+ http://www.mipl.mediapoli.com/cgi-bin/mailman/listinfo
-+
-+Or send mail with subject "subscribe" for the general list to:
-+
-+ mipl-request@list.mipl.mediapoli.com
-+
-+or for the developer list to:
-+
-+ mipl-devel-request@list.mail.mediapoli.com
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/auth_opt.c linux-2.4.25/net/ipv6/mobile_ip6/auth_opt.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/auth_opt.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/auth_opt.c 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,121 @@
-+/*
-+ * MIPv6 Binding Authentication Data Option functions
-+ *
-+ * Authors:
-+ * Henrik Petander <lpetande@tml.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/autoconf.h>
-+#include <linux/icmpv6.h>
-+#include <net/mipv6.h>
-+
-+#include "debug.h"
-+#include "hmac.h"
-+#include "mobhdr.h"
-+
-+#define DBG_KEY 5
-+
-+int mipv6_auth_build(struct in6_addr *cn_addr, struct in6_addr *coa,
-+ __u8 *mh, __u8 *aud_data, __u8 *k_bu)
-+{
-+ /* First look up the peer from sadb based on his address */
-+ struct ah_processing ahp;
-+
-+ /* Don't add any other options or this system is screwed */
-+
-+ __u8 buf[MAX_HASH_LENGTH];
-+
-+
-+ if (!k_bu) {
-+ DEBUG(DBG_ERROR, "k_bu missing, aborting");
-+ return -1;
-+ }
-+ DEBUG(DBG_KEY, "Key for building authenticator:");
-+ debug_print_buffer(DBG_KEY, k_bu, HMAC_SHA1_KEY_SIZE);
-+
-+ if (ah_hmac_sha1_init(&ahp, k_bu, HMAC_SHA1_KEY_SIZE) < 0) {
-+ DEBUG(DBG_ERROR, "Failed to initialize hmac sha1");
-+ return -1;
-+ }
-+
-+ DEBUG(DBG_KEY, "coa: ");
-+ debug_print_buffer(DBG_KEY, coa, 16);
-+ DEBUG(DBG_KEY, "cn_addr: ");
-+ debug_print_buffer(DBG_KEY, cn_addr, 16);
-+ DEBUG(DBG_KEY, "MH contents: ");
-+ debug_print_buffer(DBG_KEY, mh, aud_data - mh);
-+
-+ /* First the common part */
-+ ah_hmac_sha1_loop(&ahp, coa, sizeof(struct in6_addr));
-+ ah_hmac_sha1_loop(&ahp, cn_addr, sizeof(struct in6_addr));
-+ ah_hmac_sha1_loop(&ahp, mh, aud_data - mh);
-+ ah_hmac_sha1_result(&ahp, buf);
-+
-+ memcpy(aud_data, buf, MIPV6_RR_MAC_LENGTH);
-+
-+ return 0;
-+}
-+
-+int mipv6_auth_check(struct in6_addr *cn_addr, struct in6_addr *coa,
-+ __u8 *opt, __u8 optlen,
-+ struct mipv6_mo_bauth_data *aud, __u8 *k_bu)
-+{
-+ int ret = -1;
-+ struct ah_processing ahp;
-+ __u8 htarget[MAX_HASH_LENGTH];
-+
-+ /* Look up peer by home address */
-+ if (!k_bu) {
-+ DEBUG(DBG_ERROR, "k_bu missing, aborting");
-+ return -1;
-+ }
-+
-+ DEBUG(DBG_KEY, "Key for checking authenticator:");
-+ debug_print_buffer(DBG_KEY, k_bu, HMAC_SHA1_KEY_SIZE);
-+
-+ if (!aud || !coa) {
-+ DEBUG(DBG_INFO, "%s is NULL", aud ? "coa" : "aud");
-+ goto out;
-+ }
-+
-+ if (aud->length != MIPV6_RR_MAC_LENGTH) {
-+ DEBUG(DBG_ERROR,
-+ ": Incorrect authentication option length %d", aud->length);
-+ goto out;
-+ }
-+
-+ if (ah_hmac_sha1_init(&ahp, k_bu, HMAC_SHA1_KEY_SIZE) < 0) {
-+ DEBUG(DBG_ERROR,
-+ "internal error in initialization of authentication algorithm");
-+ goto out;
-+ }
-+ DEBUG(DBG_KEY, "coa: ");
-+ debug_print_buffer(DBG_KEY, coa, 16);
-+ DEBUG(DBG_KEY, "cn_addr: ");
-+ debug_print_buffer(DBG_KEY, cn_addr, 16);
-+ DEBUG(DBG_KEY, "MH contents: ");
-+ debug_print_buffer(DBG_KEY, opt, (u8*) aud->data - opt);
-+
-+ ah_hmac_sha1_loop(&ahp, coa, sizeof(struct in6_addr));
-+ ah_hmac_sha1_loop(&ahp, cn_addr, sizeof(struct in6_addr));
-+
-+ /*
-+ * Process MH + options till the start of the authenticator in
-+ * Auth. data option
-+ */
-+ ah_hmac_sha1_loop(&ahp, opt, (u8 *)aud->data - opt);
-+ ah_hmac_sha1_result(&ahp, htarget);
-+ if (memcmp(htarget, aud->data, MIPV6_RR_MAC_LENGTH) == 0)
-+ ret = 0;
-+
-+ DEBUG(DBG_ERROR, "returning %d", ret);
-+out:
-+ return ret;
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/bcache.c linux-2.4.25/net/ipv6/mobile_ip6/bcache.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/bcache.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/bcache.c 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,746 @@
-+/*
-+ * Binding Cache
-+ *
-+ * Authors:
-+ * Juha Mynttinen <jmynttin@cc.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * 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.
-+ */
-+
-+/*
-+ * Changes:
-+ *
-+ * Nanno Langstraat : Timer code cleaned up, active socket
-+ * test rewritten
-+ */
-+
-+#include <linux/autoconf.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/in6.h>
-+#include <linux/init.h>
-+#include <linux/spinlock.h>
-+#include <linux/proc_fs.h>
-+#include <linux/ipv6_route.h>
-+#include <net/ipv6.h>
-+#include <net/addrconf.h>
-+#include <net/tcp.h>
-+#include <net/udp.h>
-+#include <net/ip6_route.h>
-+#include <net/mipv6.h>
-+
-+#include "bcache.h"
-+#include "hashlist.h"
-+#include "debug.h"
-+#include "mobhdr.h"
-+#include "tunnel.h"
-+#include "config.h"
-+
-+#define TIMERDELAY HZ/10
-+
-+struct mipv6_bcache {
-+ struct hashlist *entries;
-+ __u32 size;
-+ struct timer_list callback_timer;
-+};
-+
-+struct in6_addr_pair {
-+ struct in6_addr *a1;
-+ struct in6_addr *a2;
-+};
-+
-+static rwlock_t bcache_lock = RW_LOCK_UNLOCKED;
-+
-+static struct mipv6_bcache bcache;
-+
-+static int bcache_proc_info(char *buffer, char **start, off_t offset,
-+ int length);
-+
-+#define MIPV6_BCACHE_HASHSIZE 32
-+
-+/* Moment of transmission of a BR, in seconds before bcache entry expiry */
-+#define BCACHE_BR_SEND_LEAD 3
-+
-+#define MIPV6_MAX_BRR 3 /* Send 3 BRRs before deleting BC entry */
-+#define MIPV6_BRR_RATE HZ /* Send BRRs once per second */
-+
-+/*
-+ * Internal functions.
-+ */
-+
-+struct cache_entry_iterator_args {
-+ struct mipv6_bce **entry;
-+};
-+
-+static int find_first_cache_entry_iterator(void *data, void *args,
-+ unsigned long *lifetime)
-+{
-+ struct mipv6_bce *entry =
-+ (struct mipv6_bce *) data;
-+ struct cache_entry_iterator_args *state =
-+ (struct cache_entry_iterator_args *) args;
-+
-+ ASSERT(entry != NULL);
-+
-+ if (entry->type == CACHE_ENTRY) {
-+ *(state->entry) = entry;
-+ return ITERATOR_STOP; /* stop iteration */
-+ } else {
-+ return ITERATOR_CONT; /* continue iteration */
-+ }
-+}
-+
-+
-+/*
-+ * Get memory for a new bcache entry. If bcache is full, a cache
-+ * entry may be deleted to get space for a home registration, but not
-+ * vice versa.
-+ */
-+static struct mipv6_bce *mipv6_bce_alloc(__u8 type)
-+{
-+ struct mipv6_bce *entry;
-+ struct cache_entry_iterator_args args;
-+
-+ DEBUG_FUNC();
-+
-+ entry = (struct mipv6_bce *)
-+ hashlist_alloc(bcache.entries, SLAB_ATOMIC);
-+
-+ /* Cache replacement policy: always replace the CACHE_ENTRY
-+ closest to expiration. Type HOME_REGISTRATION entry may
-+ never be deleted before expiration. */
-+ if (entry == NULL) {
-+ /* cache full, try to delete a CACHE_ENTRY */
-+ args.entry = &entry;
-+ hashlist_iterate(bcache.entries, &args,
-+ find_first_cache_entry_iterator);
-+ if (entry == NULL)
-+ return NULL;
-+ hashlist_delete(bcache.entries,
-+ (struct hashlist_entry *)entry);
-+ entry = (struct mipv6_bce *)
-+ hashlist_alloc(bcache.entries, SLAB_ATOMIC);
-+ }
-+ return entry;
-+}
-+
-+/*
-+ * Frees entry's memory allocated with mipv6_bce_alloc
-+ */
-+static void mipv6_bce_free(struct mipv6_bce *entry)
-+{
-+ hashlist_free(bcache.entries, (void *) entry);
-+}
-+
-+/*
-+ * Removes all expired entries
-+ */
-+static void expire(void)
-+{
-+ struct mipv6_bce *entry;
-+ struct br_addrs {
-+ struct in6_addr daddr;
-+ struct in6_addr saddr;
-+ struct br_addrs *next;
-+ };
-+ struct br_addrs *br_info = NULL;
-+
-+ DEBUG_FUNC();
-+
-+ write_lock(&bcache_lock);
-+
-+ while ((entry = (struct mipv6_bce *)
-+ hashlist_get_first(bcache.entries)) != NULL) {
-+ struct rt6_info *rt;
-+ if (time_after_eq(jiffies, entry->callback_time)) {
-+
-+ DEBUG(DBG_INFO, "an entry expired");
-+
-+ if (entry->type & HOME_REGISTRATION) {
-+ mip6_fn.proxy_del(&entry->home_addr, entry);
-+ }
-+ hashlist_delete(bcache.entries, (void *)entry);
-+ mipv6_bce_free(entry);
-+ entry = NULL;
-+ } else if (entry->br_callback_time != 0 &&
-+ time_after_eq(jiffies, entry->br_callback_time) &&
-+ entry->br_count < MIPV6_MAX_BRR &&
-+ (rt = rt6_lookup(&entry->home_addr, &entry->our_addr, 0, 0)) != NULL){
-+ /* Do we have a destination cache entry for the home address */
-+ if (rt->rt6i_flags & RTF_CACHE) {
-+ struct br_addrs *tmp;
-+ tmp = br_info;
-+ DEBUG(DBG_INFO,
-+ "bcache entry recently used. Sending BR.");
-+ /* queue for sending */
-+ br_info = kmalloc(sizeof(struct br_addrs),
-+ GFP_ATOMIC);
-+ if (br_info) {
-+ ipv6_addr_copy(&br_info->saddr,
-+ &entry->our_addr);
-+ ipv6_addr_copy(&br_info->daddr,
-+ &entry->home_addr);
-+ br_info->next = tmp;
-+ entry->last_br = jiffies;
-+ entry->br_callback_time = jiffies + MIPV6_BRR_RATE;
-+ entry->br_count++;
-+ } else {
-+ br_info = tmp;
-+ DEBUG(DBG_ERROR, "Out of memory");
-+ }
-+
-+ } else
-+ entry->br_callback_time = 0;
-+ dst_release(&rt->u.dst);
-+ } else {
-+ entry->br_callback_time = 0;
-+ break;
-+ }
-+ }
-+ write_unlock(&bcache_lock);
-+
-+ while (br_info) {
-+ struct br_addrs *tmp = br_info->next;
-+ if (mipv6_send_brr(&br_info->saddr, &br_info->daddr, NULL) < 0)
-+ DEBUG(DBG_WARNING,
-+ "BR send for %x:%x:%x:%x:%x:%x:%x:%x failed",
-+ NIPV6ADDR(&br_info->daddr));
-+ kfree(br_info);
-+ br_info = tmp;
-+ }
-+}
-+
-+static void set_timer(void)
-+{
-+ struct mipv6_bce *entry;
-+ unsigned long callback_time;
-+
-+ DEBUG_FUNC();
-+
-+ entry = (struct mipv6_bce *)
-+ hashlist_get_first(bcache.entries);
-+ if (entry != NULL) {
-+ if (entry->br_callback_time > 0 &&
-+ time_after(entry->br_callback_time, jiffies))
-+ callback_time = entry->br_callback_time;
-+ else if (time_after(entry->callback_time, jiffies))
-+ callback_time = entry->callback_time;
-+ else {
-+ DEBUG(DBG_WARNING,
-+ "bcache timer attempted to schedule"
-+ " for a historical jiffies count!");
-+ callback_time = jiffies + TIMERDELAY;
-+ }
-+
-+ DEBUG(DBG_INFO, "setting timer to now");
-+ mod_timer(&bcache.callback_timer, callback_time);
-+ } else {
-+ del_timer(&bcache.callback_timer);
-+ DEBUG(DBG_INFO, "BC empty, not setting a new timer");
-+ }
-+}
-+
-+/*
-+ * The function that is scheduled to do the callback functions. May be
-+ * modified e.g to allow Binding Requests, now only calls expire() and
-+ * schedules a new timer.
-+ */
-+static void timer_handler(unsigned long dummy)
-+{
-+ expire();
-+ write_lock(&bcache_lock);
-+ set_timer();
-+ write_unlock(&bcache_lock);
-+}
-+
-+/*
-+ * Interface functions visible to other modules
-+ */
-+
-+/**
-+ * mipv6_bcache_add - add Binding Cache entry
-+ * @ifindex: interface index
-+ * @our_addr: own address
-+ * @home_addr_org: MN's home address
-+ * @coa: MN's care-of address
-+ * @lifetime: lifetime for this binding
-+ * @prefix: prefix length
-+ * @seq: sequence number
-+ * @flags: flags received in BU
-+ * @type: type of entry
-+ *
-+ * Adds an entry for this @home_addr_org in the Binding Cache. If entry
-+ * already exists, old entry is updated. @type may be %CACHE_ENTRY or
-+ * %HOME_REGISTRATION.
-+ **/
-+int mipv6_bcache_add(int ifindex,
-+ struct in6_addr *our_addr,
-+ struct in6_addr *home_addr,
-+ struct in6_addr *coa,
-+ __u32 lifetime, __u16 seq, __u8 flags, __u8 type)
-+{
-+ struct mipv6_bce *entry;
-+ int update = 0;
-+ int create_tunnel = 0;
-+ unsigned long now = jiffies;
-+ struct in6_addr_pair hashkey;
-+ int ret = -1;
-+
-+ DEBUG_FUNC();
-+
-+ hashkey.a1 = home_addr;
-+ hashkey.a2 = our_addr;
-+
-+ write_lock(&bcache_lock);
-+
-+ if (type == HOME_REGISTRATION && !(mip6node_cnf.capabilities&CAP_HA))
-+ return 0;
-+
-+ if (unlikely(bcache.entries == NULL)) {
-+ ret = -ENOMEM;
-+ goto err;
-+ }
-+
-+ if ((entry = (struct mipv6_bce *)
-+ hashlist_get(bcache.entries, &hashkey)) != NULL) {
-+ /* if an entry for this home_addr exists (with smaller
-+ * seq than the new seq), update it by removing it
-+ * first
-+ */
-+ if (!MIPV6_SEQ_GT(seq, entry->seq)) {
-+ DEBUG(DBG_INFO, "smaller seq than existing, not updating");
-+ goto out;
-+ }
-+ DEBUG(DBG_INFO, "updating an existing entry");
-+ update = 1;
-+
-+ /* H-flag is already checked in BU handler. */
-+ /* XXX: Should we care about the other flags?*/
-+ if (flags != entry->flags) {
-+ DEBUG(DBG_INFO, "entry/BU flag mismatch");
-+ }
-+
-+ if (type == HOME_REGISTRATION) {
-+ create_tunnel = (ipv6_addr_cmp(&entry->coa, coa) ||
-+ entry->ifindex != ifindex);
-+ }
-+ } else {
-+ /* no entry for this home_addr, try to create a new entry */
-+ DEBUG(DBG_INFO, "creating a new entry");
-+ update = 0;
-+
-+ entry = mipv6_bce_alloc(type);
-+ if (entry == NULL) {
-+ DEBUG(DBG_INFO, "cache full, entry not added");
-+ goto err;
-+ }
-+
-+ create_tunnel = (type == HOME_REGISTRATION);
-+ }
-+
-+ if (create_tunnel) {
-+ if (update)
-+ mip6_fn.proxy_del(&entry->home_addr, entry);
-+ if (mip6_fn.proxy_create(flags, ifindex, coa, our_addr, home_addr) < 0) {
-+ goto err_proxy;
-+ }
-+ }
-+
-+ ipv6_addr_copy(&(entry->our_addr), our_addr);
-+ ipv6_addr_copy(&(entry->home_addr), home_addr);
-+ ipv6_addr_copy(&(entry->coa), coa);
-+ entry->ifindex = ifindex;
-+ entry->seq = seq;
-+ entry->type = type;
-+ entry->flags = flags;
-+
-+ entry->last_br = 0;
-+ entry->destunr_count = 0;
-+ entry->callback_time = now + lifetime * HZ;
-+ if (entry->type & HOME_REGISTRATION)
-+ entry->br_callback_time = 0;
-+ else
-+ entry->br_callback_time = now +
-+ (lifetime - BCACHE_BR_SEND_LEAD) * HZ;
-+
-+ if (update) {
-+ DEBUG(DBG_INFO, "updating entry : %x", entry);
-+ hashlist_reposition(bcache.entries, (void *)entry,
-+ entry->callback_time);
-+ } else {
-+ DEBUG(DBG_INFO, "adding entry: %x", entry);
-+ if ((hashlist_add(bcache.entries,
-+ &hashkey,
-+ entry->callback_time, entry)) < 0) {
-+
-+ DEBUG(DBG_ERROR, "Hash add failed");
-+ goto err_hashlist;
-+ }
-+ }
-+
-+ set_timer();
-+
-+out:
-+ write_unlock(&bcache_lock);
-+ return 0;
-+
-+err_hashlist:
-+ if (create_tunnel) {
-+ mip6_fn.proxy_del(home_addr, entry);
-+ }
-+err_proxy:
-+ if (update) {
-+ hashlist_delete(bcache.entries, (void *)entry);
-+ }
-+ mipv6_bce_free(entry);
-+err:
-+ write_unlock(&bcache_lock);
-+ return ret;
-+}
-+
-+int mipv6_bcache_icmp_err(struct in6_addr *home_addr,
-+ struct in6_addr *our_addr,
-+ int destunr_count)
-+{
-+ struct mipv6_bce *entry;
-+ struct in6_addr_pair hashkey;
-+
-+ int ret = -ENOENT;
-+
-+ DEBUG_FUNC();
-+
-+ hashkey.a1 = home_addr;
-+ hashkey.a2 = our_addr;
-+
-+ write_lock(&bcache_lock);
-+ if (unlikely(bcache.entries == NULL)) {
-+ ret = -ENOMEM;
-+ goto err;
-+ }
-+
-+ if ((entry = (struct mipv6_bce *)
-+ hashlist_get(bcache.entries, &hashkey)) != NULL) {
-+ entry->last_destunr = jiffies;
-+ entry->destunr_count = destunr_count;
-+ ret = 0;
-+ }
-+err:
-+ write_unlock(&bcache_lock);
-+ return ret;
-+}
-+
-+
-+/**
-+ * mipv6_bcache_delete - delete Binding Cache entry
-+ * @home_addr: MN's home address
-+ * @our_addr: our address
-+ * @type: type of entry
-+ *
-+ * Deletes an entry associated with @home_addr from Binding Cache.
-+ * Valid values for @type are %CACHE_ENTRY, %HOME_REGISTRATION and
-+ * %ANY_ENTRY. %ANY_ENTRY deletes any type of entry.
-+ **/
-+int mipv6_bcache_delete(struct in6_addr *home_addr,
-+ struct in6_addr *our_addr, __u8 type)
-+{
-+ struct mipv6_bce *entry;
-+ struct in6_addr_pair hashkey;
-+ int err = 0;
-+
-+ DEBUG_FUNC();
-+
-+ if (home_addr == NULL || our_addr == NULL) {
-+ DEBUG(DBG_INFO, "error in arguments");
-+ return -EINVAL;
-+ }
-+
-+ hashkey.a1 = home_addr;
-+ hashkey.a2 = our_addr;
-+
-+ write_lock(&bcache_lock);
-+
-+ if (unlikely(bcache.entries == NULL) ||
-+ (entry = (struct mipv6_bce *)
-+ hashlist_get(bcache.entries, &hashkey)) == NULL ||
-+ !(entry->type & type)) {
-+ DEBUG(DBG_INFO, "No matching entry found");
-+ err = -ENOENT;
-+ goto out;
-+ }
-+
-+ hashlist_delete(bcache.entries, (void *) entry);
-+ mipv6_bce_free(entry);
-+
-+ set_timer();
-+out:
-+ write_unlock(&bcache_lock);
-+ return err;
-+}
-+
-+/**
-+ * mipv6_bcache_exists - check if entry exists
-+ * @home_addr: home address to check
-+ * @our_addr: our address
-+ *
-+ * Determines if a binding exists for @home_addr. Returns type of the
-+ * entry or negative if entry does not exist.
-+ **/
-+int mipv6_bcache_exists(struct in6_addr *home_addr,
-+ struct in6_addr *our_addr)
-+{
-+ struct mipv6_bce *entry;
-+ struct in6_addr_pair hashkey;
-+ int type = -ENOENT;
-+
-+ DEBUG_FUNC();
-+
-+ if (home_addr == NULL || our_addr == NULL)
-+ return -EINVAL;
-+
-+ hashkey.a1 = home_addr;
-+ hashkey.a2 = our_addr;
-+
-+ read_lock(&bcache_lock);
-+ if (likely(bcache.entries != NULL) &&
-+ (entry = (struct mipv6_bce *)
-+ hashlist_get(bcache.entries, &hashkey)) != NULL) {
-+ type = entry->type;
-+ }
-+ read_unlock(&bcache_lock);
-+
-+ return type;
-+}
-+
-+/**
-+ * mipv6_bcache_get - get entry from Binding Cache
-+ * @home_addr: home address to search
-+ * @our_addr: our address
-+ * @entry: pointer to buffer
-+ *
-+ * Gets a copy of Binding Cache entry for @home_addr. If entry
-+ * exists entry is copied to @entry and zero is returned.
-+ * Otherwise returns negative.
-+ **/
-+int mipv6_bcache_get(struct in6_addr *home_addr,
-+ struct in6_addr *our_addr,
-+ struct mipv6_bce *entry)
-+{
-+ struct mipv6_bce *entry2;
-+ struct in6_addr_pair hashkey;
-+ int ret = -ENOENT;
-+
-+ DEBUG_FUNC();
-+
-+ if (home_addr == NULL || our_addr == NULL || entry == NULL)
-+ return -EINVAL;
-+
-+ hashkey.a1 = home_addr;
-+ hashkey.a2 = our_addr;
-+
-+ read_lock_bh(&bcache_lock);
-+
-+ entry2 = (struct mipv6_bce *)
-+ hashlist_get(bcache.entries, &hashkey);
-+ if (entry2 != NULL) {
-+ memcpy(entry, entry2, sizeof(struct mipv6_bce));
-+ ret = 0;
-+ }
-+ read_unlock_bh(&bcache_lock);
-+ return ret;
-+}
-+
-+int mipv6_bcache_iterate(hashlist_iterator_t func, void *args)
-+{
-+ int ret;
-+
-+ read_lock_bh(&bcache_lock);
-+ ret = hashlist_iterate(bcache.entries, args, func);
-+ read_unlock_bh(&bcache_lock);
-+
-+ return ret;
-+}
-+
-+/*
-+ * Proc-filesystem functions
-+ */
-+
-+#define BC_INFO_LEN 80
-+
-+struct procinfo_iterator_args {
-+ char *buffer;
-+ int offset;
-+ int length;
-+ int skip;
-+ int len;
-+};
-+
-+static int procinfo_iterator(void *data, void *args, unsigned long *pref)
-+{
-+ struct procinfo_iterator_args *arg =
-+ (struct procinfo_iterator_args *) args;
-+ struct mipv6_bce *entry =
-+ (struct mipv6_bce *) data;
-+
-+ ASSERT(entry != NULL);
-+
-+ if (arg->skip < arg->offset / BC_INFO_LEN) {
-+ arg->skip++;
-+ return ITERATOR_CONT;
-+ }
-+
-+ if (arg->len >= arg->length)
-+ return ITERATOR_CONT;
-+
-+ /* HoA CoA CallbackInSecs Type */
-+ arg->len += sprintf(arg->buffer + arg->len,
-+ "%08x%08x%08x%08x %08x%08x%08x%08x %010lu %02d\n",
-+ ntohl(entry->home_addr.s6_addr32[0]),
-+ ntohl(entry->home_addr.s6_addr32[1]),
-+ ntohl(entry->home_addr.s6_addr32[2]),
-+ ntohl(entry->home_addr.s6_addr32[3]),
-+ ntohl(entry->coa.s6_addr32[0]),
-+ ntohl(entry->coa.s6_addr32[1]),
-+ ntohl(entry->coa.s6_addr32[2]),
-+ ntohl(entry->coa.s6_addr32[3]),
-+ ((entry->callback_time) - jiffies) / HZ,
-+ (int) entry->type);
-+
-+ return ITERATOR_CONT;
-+}
-+
-+ /*
-+ * Callback function for proc filesystem.
-+ */
-+static int bcache_proc_info(char *buffer, char **start, off_t offset,
-+ int length)
-+{
-+ struct procinfo_iterator_args args;
-+
-+ DEBUG_FUNC();
-+
-+ args.buffer = buffer;
-+ args.offset = offset;
-+ args.length = length;
-+ args.skip = 0;
-+ args.len = 0;
-+
-+ read_lock_bh(&bcache_lock);
-+ hashlist_iterate(bcache.entries, &args, procinfo_iterator);
-+ read_unlock_bh(&bcache_lock);
-+
-+ *start = buffer;
-+ if (offset)
-+ *start += offset % BC_INFO_LEN;
-+
-+ args.len -= offset % BC_INFO_LEN;
-+
-+ if (args.len > length)
-+ args.len = length;
-+ if (args.len < 0)
-+ args.len = 0;
-+
-+ return args.len;
-+}
-+
-+static int bcache_compare(void *data, void *hashkey)
-+{
-+ struct in6_addr_pair *p = (struct in6_addr_pair *) hashkey;
-+ struct mipv6_bce *e = (struct mipv6_bce *) data;
-+
-+ if (ipv6_addr_cmp(&e->home_addr, p->a1) == 0
-+ && ipv6_addr_cmp(&e->our_addr, p->a2) == 0)
-+ return 0;
-+ else
-+ return -1;
-+}
-+
-+static __u32 bcache_hash(void *hashkey)
-+{
-+ struct in6_addr_pair *p = (struct in6_addr_pair *) hashkey;
-+
-+ return p->a1->s6_addr32[0] ^ p->a1->s6_addr32[1] ^
-+ p->a2->s6_addr32[2] ^ p->a2->s6_addr32[3];
-+}
-+
-+/*
-+ * Initialization and shutdown functions
-+ */
-+
-+int __init mipv6_bcache_init(__u32 size)
-+{
-+ if (size < 1) {
-+ DEBUG(DBG_ERROR, "Binding cache size must be at least 1");
-+ return -EINVAL;
-+ }
-+ bcache.entries = hashlist_create(MIPV6_BCACHE_HASHSIZE, size,
-+ sizeof(struct mipv6_bce),
-+ "mip6_bcache", NULL, NULL,
-+ bcache_compare, bcache_hash);
-+
-+ if (bcache.entries == NULL) {
-+ DEBUG(DBG_ERROR, "Failed to initialize hashlist");
-+ return -ENOMEM;
-+ }
-+
-+ init_timer(&bcache.callback_timer);
-+ bcache.callback_timer.data = 0;
-+ bcache.callback_timer.function = timer_handler;
-+ bcache.size = size;
-+
-+ proc_net_create("mip6_bcache", 0, bcache_proc_info);
-+
-+ DEBUG(DBG_INFO, "Binding cache initialized");
-+ return 0;
-+}
-+
-+static int
-+bce_cleanup_iterator(void *rawentry, void *args, unsigned long *sortkey)
-+{
-+ int type = (int) args;
-+ struct mipv6_bce *entry = (struct mipv6_bce *) rawentry;
-+ if (entry->type == type) {
-+ if (entry->type & HOME_REGISTRATION) {
-+ if (unlikely(mip6_fn.proxy_del == NULL))
-+ DEBUG(DBG_ERROR, "proxy_del unitialized");
-+ else
-+ mip6_fn.proxy_del(&entry->home_addr, entry);
-+ }
-+ return ITERATOR_DELETE_ENTRY;
-+ }
-+ return ITERATOR_CONT;
-+
-+}
-+
-+void mipv6_bcache_cleanup(int type)
-+{
-+ write_lock_bh(&bcache_lock);
-+ hashlist_iterate(bcache.entries,(void *) type, bce_cleanup_iterator);
-+ write_unlock_bh(&bcache_lock);
-+}
-+
-+int __exit mipv6_bcache_exit(void)
-+{
-+ struct hashlist *entries;
-+
-+ DEBUG_FUNC();
-+
-+ proc_net_remove("mip6_bcache");
-+
-+ write_lock_bh(&bcache_lock);
-+ DEBUG(DBG_INFO, "Stopping the bcache timer");
-+ del_timer(&bcache.callback_timer);
-+ hashlist_iterate(bcache.entries,(void *)CACHE_ENTRY,
-+ bce_cleanup_iterator);
-+
-+ entries = bcache.entries;
-+ bcache.entries = NULL;
-+ write_unlock_bh(&bcache_lock);
-+
-+ hashlist_destroy(entries);
-+ return 0;
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/bcache.h linux-2.4.25/net/ipv6/mobile_ip6/bcache.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/bcache.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/bcache.h 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,72 @@
-+/*
-+ * MIPL Mobile IPv6 Binding Cache header file
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef _BCACHE_H
-+#define _BCACHE_H
-+
-+#include <linux/in6.h>
-+#include <linux/timer.h>
-+#include "hashlist.h"
-+
-+#define CACHE_ENTRY 1 /* this and HOME_REGISTRATION are the entry types */
-+#define HOME_REGISTRATION 2
-+#define ANY_ENTRY 3
-+
-+#define MIPV6_MAX_DESTUNREACH 5 /* Delete CN BCEs after 5 destination unreachables */
-+#define MIPV6_DEST_UNR_IVAL 10 /* What is the max interval of destination
-+ unreacahable error messages for them to be persistent*/
-+
-+struct mipv6_bce {
-+ struct hashlist_entry e;
-+ int ifindex; /* Interface identifier */
-+ struct in6_addr our_addr; /* our address (as seen by the MN) */
-+ struct in6_addr home_addr; /* MN home address */
-+ struct in6_addr coa; /* MN care-of address */
-+ unsigned long callback_time; /* time of expiration (in jiffies) */
-+ unsigned long br_callback_time; /* time for sending a BR (in jiffies) */
-+ int (*callback_function)(struct mipv6_bce *entry);
-+ __u8 type; /* home registration */
-+ __u8 router; /* mn is router */
-+ __u8 flags; /* flags received in BU */
-+ __u16 seq; /* sequence number */
-+ unsigned long last_br; /* time when last BR sent */
-+ unsigned long last_destunr; /* time when last ICMP destination unreachable received */
-+ int br_count; /* How many BRRs have sent */
-+ int destunr_count; /* Number of destination unreachables received */
-+};
-+
-+int mipv6_bcache_add(int ifindex, struct in6_addr *our_addr,
-+ struct in6_addr *home_addr, struct in6_addr *coa,
-+ __u32 lifetime, __u16 seq, __u8 flags, __u8 type);
-+
-+int mipv6_bcache_icmp_err(struct in6_addr *home_addr,
-+ struct in6_addr *our_addr,
-+ int destunr_count);
-+
-+int mipv6_bcache_delete(struct in6_addr *home_addr, struct in6_addr *our_addr,
-+ __u8 type);
-+
-+int mipv6_bcache_exists(struct in6_addr *home_addr,
-+ struct in6_addr *our_addr);
-+
-+int mipv6_bcache_get(struct in6_addr *home_addr,
-+ struct in6_addr *our_addr,
-+ struct mipv6_bce *entry);
-+
-+int mipv6_bcache_iterate(int (*func)(void *, void *, unsigned long *), void *args);
-+
-+void mipv6_bcache_cleanup(int type);
-+
-+int mipv6_bcache_init(__u32 size);
-+
-+int mipv6_bcache_exit(void);
-+
-+#endif /* _BCACHE_H */
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/bul.c linux-2.4.25/net/ipv6/mobile_ip6/bul.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/bul.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/bul.c 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,634 @@
-+/*
-+ * Binding update list
-+ *
-+ * Authors:
-+ * Juha Mynttinen <jmynttin@cc.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * 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.
-+ */
-+
-+/*
-+ * Changes:
-+ *
-+ * Nanno Langstraat : Timer code cleaned up
-+ */
-+
-+#include <linux/autoconf.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/in6.h>
-+#include <linux/init.h>
-+#include <linux/spinlock.h>
-+#include <net/ipv6.h>
-+#include <net/mipv6.h>
-+#include <linux/proc_fs.h>
-+
-+#include "bul.h"
-+#include "debug.h"
-+#include "hashlist.h"
-+#include "tunnel_mn.h"
-+#include "mobhdr.h"
-+
-+#define MIPV6_BUL_HASHSIZE 32
-+
-+rwlock_t bul_lock = RW_LOCK_UNLOCKED;
-+
-+struct mipv6_bul {
-+ struct hashlist *entries;
-+ struct timer_list callback_timer;
-+};
-+
-+static struct mipv6_bul bul;
-+
-+struct in6_addr_pair {
-+ struct in6_addr *a1;
-+ struct in6_addr *a2;
-+};
-+
-+/**********************************************************************
-+ *
-+ * Private functions
-+ *
-+ **********************************************************************/
-+
-+static int bul_compare(void *data, void *hashkey)
-+{
-+ struct in6_addr_pair *p = (struct in6_addr_pair *)hashkey;
-+ struct mipv6_bul_entry *e = (struct mipv6_bul_entry *)data;
-+
-+ if (ipv6_addr_cmp(&e->cn_addr, p->a1) == 0
-+ && ipv6_addr_cmp(&e->home_addr, p->a2) == 0)
-+ return 0;
-+ else
-+ return -1;
-+}
-+
-+struct test_keys {
-+ struct in6_addr *addr;
-+ u8 *cookie;
-+};
-+
-+static int bul_compare_cookie(void *data, void *keys)
-+{
-+ struct test_keys *p = (struct test_keys *)keys;
-+ struct mipv6_bul_entry *e = (struct mipv6_bul_entry *)data;
-+
-+ if (ipv6_addr_cmp(&e->cn_addr, p->addr) == 0 && e->rr
-+ && memcmp(&e->rr->cot_cookie, p->cookie, 8) == 0)
-+ return 0;
-+ else
-+ return -1;
-+}
-+
-+static u32 bul_hash(void *hashkey)
-+{
-+ struct in6_addr_pair *p = (struct in6_addr_pair *)hashkey;
-+
-+ return p->a1->s6_addr32[0] ^
-+ p->a1->s6_addr32[1] ^
-+ p->a1->s6_addr32[2] ^
-+ p->a1->s6_addr32[3];
-+}
-+
-+static int bul_proc_info(char *buffer, char **start, off_t offset,
-+ int length);
-+
-+static struct mipv6_bul_entry *mipv6_bul_get_entry(void)
-+{
-+ DEBUG_FUNC();
-+ return ((struct mipv6_bul_entry *)
-+ hashlist_alloc(bul.entries, SLAB_ATOMIC));
-+}
-+
-+static void mipv6_bul_entry_free(struct mipv6_bul_entry *entry)
-+{
-+ DEBUG_FUNC();
-+
-+ if (entry->rr) {
-+ if (entry->rr->kbu)
-+ kfree(entry->rr->kbu);
-+ kfree(entry->rr);
-+ }
-+ if (entry->ops)
-+ kfree(entry->ops);
-+ hashlist_free(bul.entries, (void *)entry);
-+}
-+
-+static __inline__ int del_bul_entry_tnl(struct mipv6_bul_entry *entry)
-+{
-+ if (entry->flags & MIPV6_BU_F_HOME) {
-+ return mipv6_mv_tnl_to_ha(&entry->cn_addr,
-+ &entry->coa,
-+ &entry->home_addr);
-+ }
-+ return 0;
-+}
-+
-+static void timer_update(void)
-+{
-+ struct mipv6_bul_entry *entry;
-+
-+ DEBUG_FUNC();
-+
-+ entry = hashlist_get_first(bul.entries);
-+
-+ while (entry && time_after_eq(jiffies, entry->callback_time)) {
-+ if (time_after_eq(jiffies, entry->expire) ||
-+ entry->callback(entry) != 0) {
-+ /*
-+ * Either the entry has expired, or the callback
-+ * indicated that it should be deleted.
-+ */
-+ hashlist_delete(bul.entries, (void *)entry);
-+
-+ del_bul_entry_tnl(entry);
-+ mipv6_bul_entry_free(entry);
-+ DEBUG(DBG_INFO, "Entry deleted (was expired) from "
-+ "binding update list");
-+ } else {
-+ /* move entry to its right place in the hashlist */
-+ DEBUG(DBG_INFO, "Rescheduling");
-+ hashlist_reposition(bul.entries, (void *)entry,
-+ entry->callback_time);
-+ }
-+ entry = (struct mipv6_bul_entry *)
-+ hashlist_get_first(bul.entries);
-+ }
-+
-+ if (entry == NULL) {
-+ DEBUG(DBG_INFO, "bul empty, not setting a new timer");
-+ del_timer(&bul.callback_timer);
-+ } else {
-+ mod_timer(&bul.callback_timer, entry->callback_time);
-+ }
-+}
-+
-+static void timer_handler(unsigned long dummy)
-+{
-+ DEBUG_FUNC();
-+
-+ write_lock(&bul_lock);
-+ timer_update();
-+ write_unlock(&bul_lock);
-+}
-+
-+/**********************************************************************
-+ *
-+ * Public interface functions
-+ *
-+ **********************************************************************/
-+
-+/**
-+ * mipv6_bul_iterate - apply interator function to all entries
-+ * @func: function to apply
-+ * @args: extra arguments for iterator
-+ *
-+ * Applies @func for each entry in Binding Update List. Extra
-+ * arguments given in @args are also passed to the iterator function.
-+ * Caller must hold @bul_lock.
-+ **/
-+int mipv6_bul_iterate(hashlist_iterator_t func, void *args)
-+{
-+ DEBUG_FUNC();
-+
-+ return hashlist_iterate(bul.entries, args, func);
-+}
-+
-+/**
-+ * mipv6_bul_exists - check if Binding Update List entry exists
-+ * @cn: address to check
-+ *
-+ * Checks if Binding Update List has an entry for @cn. Returns true
-+ * if entry exists, false otherwise. Caller may not hold @bul_lock.
-+ **/
-+int mipv6_bul_exists(struct in6_addr *cn, struct in6_addr *haddr)
-+{
-+ int exists;
-+ struct in6_addr_pair hashkey;
-+
-+ DEBUG_FUNC();
-+
-+ hashkey.a1 = cn;
-+ hashkey.a2 = haddr;
-+
-+ read_lock_bh(&bul_lock);
-+
-+ if (unlikely(bul.entries == NULL))
-+ exists = 0;
-+ else
-+ exists = (hashlist_get(bul.entries, &hashkey) != NULL);
-+
-+ read_unlock_bh(&bul_lock);
-+ return exists;
-+}
-+
-+/**
-+ * mipv6_bul_get - get Binding Update List entry
-+ * @cn_addr: CN address to search
-+ * @home_addr: home address to search
-+ *
-+ * Returns Binding Update List entry for @cn_addr if it exists.
-+ * Otherwise returns %NULL. Caller must hold @bul_lock.
-+ **/
-+struct mipv6_bul_entry *mipv6_bul_get(struct in6_addr *cn_addr,
-+ struct in6_addr *home_addr)
-+{
-+ struct mipv6_bul_entry *entry;
-+ struct in6_addr_pair hashkey;
-+
-+ DEBUG_FUNC();
-+
-+ if (unlikely(bul.entries == NULL)) {
-+ return NULL;
-+ }
-+ hashkey.a1 = cn_addr;
-+ hashkey.a2 = home_addr;
-+
-+ entry = (struct mipv6_bul_entry *)
-+ hashlist_get(bul.entries, &hashkey);
-+
-+ return entry;
-+}
-+
-+struct mipv6_bul_entry *mipv6_bul_get_by_ccookie(
-+ struct in6_addr *cn_addr, u8 *cookie)
-+{
-+ struct test_keys key;
-+
-+ DEBUG_FUNC();
-+
-+ if (unlikely(bul.entries == NULL))
-+ return NULL;
-+ key.addr = cn_addr;
-+ key.cookie = cookie;
-+
-+ return (struct mipv6_bul_entry *)
-+ hashlist_get_ex(bul.entries, &key,
-+ bul_compare_cookie);
-+}
-+
-+/**
-+ * mipv6_bul_reschedule - reschedule Binding Update List entry
-+ * @entry: entry to reschedule
-+ *
-+ * Reschedules a Binding Update List entry. Must be called after
-+ * modifying entry lifetime. Caller must hold @bul_lock (write).
-+ **/
-+void mipv6_bul_reschedule(struct mipv6_bul_entry *entry)
-+{
-+ DEBUG_FUNC();
-+
-+ hashlist_reposition(bul.entries,
-+ (void *)entry,
-+ entry->callback_time);
-+ timer_update();
-+}
-+
-+/**
-+ * mipv6_bul_add - add binding update to Binding Update List
-+ * @cn_addr: IPv6 address where BU was sent
-+ * @home_addr: Home address for this binding
-+ * @coa: Care-of address for this binding
-+ * @lifetime: expiration time of the binding in seconds
-+ * @seq: sequence number of the BU
-+ * @flags: %MIPV6_BU_F_* flags
-+ * @callback: callback function called on expiration
-+ * @callback_time: expiration time for callback
-+ * @state: binding send state
-+ * @delay: retransmission delay
-+ * @maxdelay: retransmission maximum delay
-+ * @ops: Mobility header options for BU
-+ * @rr: Return routability information
-+ *
-+ * Adds a binding update sent to @cn_addr for @home_addr to the
-+ * Binding Update List. If entry already exists, it is updated.
-+ * Entry is set to expire in @lifetime seconds. Entry has a callback
-+ * function @callback that is called at @callback_time. Entry @state
-+ * controls resending of this binding update and it can be set to
-+ * %ACK_OK, %RESEND_EXP or %ACK_ERROR. Returns a pointer to the newly
-+ * created or updated entry. Caller must hold @bul_lock (write).
-+ **/
-+struct mipv6_bul_entry *mipv6_bul_add(
-+ struct in6_addr *cn_addr, struct in6_addr *home_addr,
-+ struct in6_addr *coa,
-+ __u32 lifetime, __u16 seq, __u8 flags,
-+ int (*callback)(struct mipv6_bul_entry *entry),
-+ __u32 callback_time,
-+ __u8 state, __u32 delay, __u32 maxdelay,
-+ struct mipv6_mh_opt *ops,
-+ struct mipv6_rr_info *rr)
-+{
-+ struct mipv6_bul_entry *entry;
-+ int update = 0;
-+ struct in6_addr_pair hashkey;
-+
-+ DEBUG_FUNC();
-+
-+ if (unlikely(bul.entries == NULL))
-+ return NULL;
-+
-+ if (cn_addr == NULL || home_addr == NULL || coa == NULL ||
-+ lifetime < 0 || callback == NULL || callback_time < 0 ||
-+ (state != ACK_OK && state != RESEND_EXP && state != ACK_ERROR) ||
-+ delay < 0 || maxdelay < 0) {
-+ DEBUG(DBG_ERROR, "invalid arguments");
-+ return NULL;
-+ }
-+ DEBUG(DBG_INFO, "cn_addr: %x:%x:%x:%x:%x:%x:%x:%x, "
-+ "home_addr: %x:%x:%x:%x:%x:%x:%x:%x"
-+ "coaddr: %x:%x:%x:%x:%x:%x:%x:%x", NIPV6ADDR(cn_addr),
-+ NIPV6ADDR(home_addr), NIPV6ADDR(coa));
-+ hashkey.a1 = cn_addr;
-+ hashkey.a2 = home_addr;
-+
-+ /*
-+ * decide whether to add a new entry or update existing, also
-+ * check if there's room for a new entry when adding a new
-+ * entry (latter is handled by mipv6_bul_get_entry()
-+ */
-+ if ((entry = (struct mipv6_bul_entry *)
-+ hashlist_get(bul.entries, &hashkey)) != NULL) {
-+ /* if an entry for this cn_addr exists (with smaller
-+ * seq than the new entry's seq), update it */
-+
-+ if (MIPV6_SEQ_GT(seq, entry->seq)) {
-+ DEBUG(DBG_INFO, "updating an existing entry");
-+ update = 1;
-+ } else {
-+ DEBUG(DBG_INFO, "smaller seq than existing, not updating");
-+ return NULL;
-+ }
-+ } else {
-+ entry = mipv6_bul_get_entry();
-+ if (entry == NULL) {
-+ DEBUG(DBG_WARNING, "binding update list full, can't add!!!");
-+ return NULL;
-+ }
-+ memset(entry, 0, sizeof(*entry));
-+ /* First BU send happens here, save count in the entry */
-+ entry->consecutive_sends = 1;
-+ }
-+
-+ if (!update) {
-+ ipv6_addr_copy(&(entry->cn_addr), cn_addr);
-+ ipv6_addr_copy(&(entry->home_addr), home_addr);
-+ entry->ops = ops;
-+ }
-+ /* Add Return Routability info to bul entry */
-+ if (rr) {
-+ if(entry->rr)
-+ kfree(entry->rr);
-+ entry->rr = rr;
-+ }
-+
-+ ipv6_addr_copy(&(entry->coa), coa);
-+ entry->lifetime = lifetime;
-+ if (lifetime)
-+ entry->expire = jiffies + lifetime * HZ;
-+ else if (flags & MIPV6_BU_F_ACK)
-+ entry->expire = jiffies + HOME_RESEND_EXPIRE * HZ;
-+ entry->seq = seq;
-+ entry->flags = flags;
-+ entry->lastsend = jiffies; /* current time = last use of the entry */
-+ entry->state = state;
-+ entry->delay = delay;
-+ entry->maxdelay = maxdelay;
-+ entry->callback_time = jiffies + callback_time * HZ;
-+ entry->callback = callback;
-+
-+ if (flags & MIPV6_BU_F_HOME &&
-+ mipv6_mv_tnl_to_ha(cn_addr, coa, home_addr)) {
-+ DEBUG(DBG_ERROR, "reconfiguration of the tunnel failed");
-+ }
-+ if (update) {
-+ DEBUG(DBG_INFO, "updating entry: %x", entry);
-+ hashlist_reposition(bul.entries, (void *)entry,
-+ entry->callback_time);
-+ } else {
-+ DEBUG(DBG_INFO, "adding entry: %x", entry);
-+
-+ hashkey.a1 = &entry->cn_addr;
-+ hashkey.a2 = &entry->home_addr;
-+
-+ if ((hashlist_add(bul.entries, &hashkey,
-+ entry->callback_time,
-+ entry)) < 0) {
-+ DEBUG(DBG_ERROR, "Hash add failed");
-+ mipv6_bul_entry_free(entry);
-+ return NULL;
-+ }
-+ }
-+ timer_update();
-+
-+ return entry;
-+}
-+
-+/**
-+ * mipv6_bul_delete - delete Binding Update List entry
-+ * @cn_addr: address for entry to delete
-+ *
-+ * Deletes the entry for @cn_addr from the Binding Update List.
-+ * Returns zero if entry was deleted succesfully, otherwise returns
-+ * negative. Caller may not hold @bul_lock.
-+ **/
-+int mipv6_bul_delete(struct in6_addr *cn_addr, struct in6_addr *home_addr)
-+{
-+ struct mipv6_bul_entry *entry;
-+ struct in6_addr_pair hashkey;
-+
-+ DEBUG_FUNC();
-+
-+ hashkey.a1 = cn_addr;
-+ hashkey.a2 = home_addr;
-+
-+ write_lock(&bul_lock);
-+
-+ if (unlikely(bul.entries == NULL) ||
-+ (entry = (struct mipv6_bul_entry *)
-+ hashlist_get(bul.entries, &hashkey)) == NULL) {
-+ write_unlock(&bul_lock);
-+ DEBUG(DBG_INFO, "No such entry");
-+ return -ENOENT;
-+ }
-+
-+ hashlist_delete(bul.entries, (void *)entry);
-+
-+ del_bul_entry_tnl(entry);
-+
-+ mipv6_bul_entry_free(entry);
-+ timer_update();
-+ write_unlock(&bul_lock);
-+
-+ DEBUG(DBG_INFO, "Binding update list entry deleted");
-+
-+ return 0;
-+}
-+
-+/**********************************************************************
-+ *
-+ * Proc interface functions
-+ *
-+ **********************************************************************/
-+
-+#define BUL_INFO_LEN 152
-+
-+struct procinfo_iterator_args {
-+ char *buffer;
-+ int offset;
-+ int length;
-+ int skip;
-+ int len;
-+};
-+
-+static int procinfo_iterator(void *data, void *args,
-+ unsigned long *sortkey)
-+{
-+ struct procinfo_iterator_args *arg =
-+ (struct procinfo_iterator_args *)args;
-+ struct mipv6_bul_entry *entry =
-+ (struct mipv6_bul_entry *)data;
-+ unsigned long callback_seconds;
-+
-+ DEBUG_FUNC();
-+
-+ if (entry == NULL) return ITERATOR_ERR;
-+
-+ if (time_after(jiffies, entry->callback_time))
-+ callback_seconds = 0;
-+ else
-+ callback_seconds = (entry->callback_time - jiffies) / HZ;
-+
-+ if (arg->skip < arg->offset / BUL_INFO_LEN) {
-+ arg->skip++;
-+ return ITERATOR_CONT;
-+ }
-+
-+ if (arg->len >= arg->length)
-+ return ITERATOR_CONT;
-+
-+ /* CN HoA CoA ExpInSecs SeqNum State Delay MaxDelay CallbackInSecs */
-+ arg->len += sprintf(arg->buffer + arg->len,
-+ "%08x%08x%08x%08x %08x%08x%08x%08x %08x%08x%08x%08x\n"
-+ "%010lu %05d %02d %010d %010d %010lu\n",
-+ ntohl(entry->cn_addr.s6_addr32[0]),
-+ ntohl(entry->cn_addr.s6_addr32[1]),
-+ ntohl(entry->cn_addr.s6_addr32[2]),
-+ ntohl(entry->cn_addr.s6_addr32[3]),
-+ ntohl(entry->home_addr.s6_addr32[0]),
-+ ntohl(entry->home_addr.s6_addr32[1]),
-+ ntohl(entry->home_addr.s6_addr32[2]),
-+ ntohl(entry->home_addr.s6_addr32[3]),
-+ ntohl(entry->coa.s6_addr32[0]),
-+ ntohl(entry->coa.s6_addr32[1]),
-+ ntohl(entry->coa.s6_addr32[2]),
-+ ntohl(entry->coa.s6_addr32[3]),
-+ (entry->expire - jiffies) / HZ,
-+ entry->seq, entry->state, entry->delay,
-+ entry->maxdelay, callback_seconds);
-+
-+ return ITERATOR_CONT;
-+}
-+
-+
-+/*
-+ * Callback function for proc filesystem.
-+ */
-+static int bul_proc_info(char *buffer, char **start, off_t offset,
-+ int length)
-+{
-+ struct procinfo_iterator_args args;
-+
-+ DEBUG_FUNC();
-+
-+ args.buffer = buffer;
-+ args.offset = offset;
-+ args.length = length;
-+ args.skip = 0;
-+ args.len = 0;
-+
-+ read_lock_bh(&bul_lock);
-+ hashlist_iterate(bul.entries, &args, procinfo_iterator);
-+ read_unlock_bh(&bul_lock);
-+
-+ *start = buffer;
-+ if (offset)
-+ *start += offset % BUL_INFO_LEN;
-+
-+ args.len -= offset % BUL_INFO_LEN;
-+
-+ if (args.len > length)
-+ args.len = length;
-+ if (args.len < 0)
-+ args.len = 0;
-+
-+ return args.len;
-+}
-+
-+/**********************************************************************
-+ *
-+ * Code module init/fini functions
-+ *
-+ **********************************************************************/
-+
-+int __init mipv6_bul_init(__u32 size)
-+{
-+ DEBUG_FUNC();
-+
-+ if (size < 1) {
-+ DEBUG(DBG_CRITICAL,
-+ "Binding update list size must be at least 1");
-+ return -EINVAL;
-+ }
-+ bul.entries = hashlist_create(MIPV6_BUL_HASHSIZE, size,
-+ sizeof(struct mipv6_bul_entry),
-+ "mip6_bul", NULL, NULL,
-+ bul_compare, bul_hash);
-+
-+ if (bul.entries == NULL) {
-+ DEBUG(DBG_CRITICAL, "Couldn't allocate memory for "
-+ "hashlist when creating a binding update list");
-+ return -ENOMEM;
-+ }
-+ init_timer(&bul.callback_timer);
-+ bul.callback_timer.data = 0;
-+ bul.callback_timer.function = timer_handler;
-+ proc_net_create("mip6_bul", 0, bul_proc_info);
-+ DEBUG(DBG_INFO, "Binding update list initialized");
-+ return 0;
-+}
-+
-+void __exit mipv6_bul_exit()
-+{
-+ struct mipv6_bul_entry *entry;
-+ struct hashlist *entries;
-+
-+ DEBUG_FUNC();
-+
-+ proc_net_remove("mip6_bul");
-+
-+ write_lock_bh(&bul_lock);
-+
-+ DEBUG(DBG_INFO, "Stopping the bul timer");
-+ del_timer(&bul.callback_timer);
-+
-+ while ((entry = (struct mipv6_bul_entry *)
-+ hashlist_get_first(bul.entries)) != NULL) {
-+ hashlist_delete(bul.entries, (void *)entry);
-+
-+ del_bul_entry_tnl(entry);
-+
-+ mipv6_bul_entry_free(entry);
-+ }
-+ entries = bul.entries;
-+ bul.entries = NULL;
-+ write_unlock_bh(&bul_lock);
-+
-+ hashlist_destroy(entries);
-+
-+ DEBUG(DBG_INFO, "binding update list destroyed");
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/bul.h linux-2.4.25/net/ipv6/mobile_ip6/bul.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/bul.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/bul.h 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,91 @@
-+/*
-+ * MIPL Mobile IPv6 Binding Update List header file
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef _BUL_H
-+#define _BUL_H
-+
-+#include "hashlist.h"
-+
-+#define ACK_OK 0x01
-+#define RESEND_EXP 0x02
-+#define ACK_ERROR 0x04
-+
-+#define HOME_RESEND_EXPIRE 3600
-+#define MIPV6_COOKIE_LEN 8
-+struct mipv6_rr_info {
-+ /* RR information */
-+ u16 rr_state; /* State of the RR */
-+ u16 rr_flags; /* Flags for the RR */
-+ u8 hot_cookie[MIPV6_COOKIE_LEN]; /* HoT Cookie */
-+ u8 cot_cookie[MIPV6_COOKIE_LEN]; /* CoT Cookie */
-+ u8 home_cookie[MIPV6_COOKIE_LEN]; /* Home Cookie */
-+ u8 careof_cookie[MIPV6_COOKIE_LEN]; /* Careof Cookie */
-+ u32 lastsend_hoti; /* When HoTI was last sent (jiffies) */
-+ u32 lastsend_coti; /* When CoTI was last sent (jiffies) */
-+ u32 home_time; /* when Care-of cookie was received */
-+ u32 careof_time; /* when Home cookie was received */
-+ int home_nonce_index; /* Home cookie nonce index */
-+ int careof_nonce_index; /* Care-of cookie nonce index */
-+ u8 *kbu; /* Binding authentication key */
-+};
-+struct mipv6_bul_entry {
-+ struct hashlist_entry e;
-+ struct in6_addr cn_addr; /* CN to which BU was sent */
-+ struct in6_addr home_addr; /* home address of this binding */
-+ struct in6_addr coa; /* care-of address of the sent BU */
-+
-+ unsigned long expire; /* entry's expiration time (jiffies) */
-+ __u32 lifetime; /* lifetime sent in this BU */
-+ __u32 lastsend; /* last time when BU sent (jiffies) */
-+ __u32 consecutive_sends; /* Number of consecutive BU's sent */
-+ __u16 seq; /* sequence number of the latest BU */
-+ __u8 flags; /* BU send flags */
-+ __u8 state; /* resend state */
-+ __u32 initdelay; /* initial ack wait */
-+ __u32 delay; /* current ack wait */
-+ __u32 maxdelay; /* maximum ack wait */
-+
-+ struct mipv6_rr_info *rr;
-+ struct mipv6_mh_opt *ops; /* saved option values */
-+
-+ unsigned long callback_time;
-+ int (*callback)(struct mipv6_bul_entry *entry);
-+};
-+
-+extern rwlock_t bul_lock;
-+
-+int mipv6_bul_init(__u32 size);
-+
-+void mipv6_bul_exit(void);
-+
-+struct mipv6_bul_entry *mipv6_bul_add(
-+ struct in6_addr *cn_addr, struct in6_addr *home_addr,
-+ struct in6_addr *coa, __u32 lifetime, __u16 seq, __u8 flags,
-+ int (*callback)(struct mipv6_bul_entry *entry), __u32 callback_time,
-+ __u8 state, __u32 delay, __u32 maxdelay, struct mipv6_mh_opt *ops,
-+ struct mipv6_rr_info *rr);
-+
-+int mipv6_bul_delete(struct in6_addr *cn_addr, struct in6_addr *home_addr);
-+
-+int mipv6_bul_exists(struct in6_addr *cnaddr, struct in6_addr *home_addr);
-+
-+struct mipv6_bul_entry *mipv6_bul_get(struct in6_addr *cnaddr,
-+ struct in6_addr *home_addr);
-+struct mipv6_bul_entry *mipv6_bul_get_by_ccookie(struct in6_addr *cn_addr,
-+ u8 *cookie);
-+
-+int bul_entry_expired(struct mipv6_bul_entry *bulentry);
-+
-+void mipv6_bul_reschedule(struct mipv6_bul_entry *entry);
-+
-+int mipv6_bul_iterate(int (*func)(void *, void *, unsigned long *), void *args);
-+
-+#endif /* BUL_H */
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/config.h linux-2.4.25/net/ipv6/mobile_ip6/config.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/config.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/config.h 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,72 @@
-+/*
-+ * Configuration parameters
-+ *
-+ * $Id$
-+ */
-+
-+#define MIPV6VERSION "D24"
-+#define MIPLVERSION "v1.0"
-+
-+#define CAP_CN 0x01
-+#define CAP_HA 0x02
-+#define CAP_MN 0x04
-+
-+struct mip6_conf {
-+ int capabilities;
-+ int debug_level;
-+ int accept_ret_rout;
-+ int max_rtr_reachable_time;
-+ int eager_cell_switching;
-+ int max_num_tunnels;
-+ int min_num_tunnels;
-+ int binding_refresh_advice;
-+ int bu_lladdr;
-+ int bu_keymgm;
-+ int bu_cn_ack;
-+};
-+
-+extern struct mip6_conf mip6node_cnf;
-+
-+struct mipv6_bce;
-+
-+struct mip6_func {
-+ void (*bce_home_add) (int ifindex, struct in6_addr *daddr,
-+ struct in6_addr *haddr, struct in6_addr *coa,
-+ struct in6_addr *rep_coa, __u32 lifetime,
-+ __u16 sequence, __u8 flags, __u8 *k_bu);
-+ void (*bce_cache_add) (int ifindex, struct in6_addr *daddr,
-+ struct in6_addr *haddr, struct in6_addr *coa,
-+ struct in6_addr *rep_coa, __u32 lifetime,
-+ __u16 sequence, __u8 flags, __u8 *k_bu);
-+ void (*bce_home_del) (struct in6_addr *daddr, struct in6_addr *haddr,
-+ struct in6_addr *coa, struct in6_addr *rep_coa,
-+ __u16 sequence, __u8 flags,
-+ __u8 *k_bu);
-+ void (*bce_cache_del) (struct in6_addr *daddr, struct in6_addr *haddr,
-+ struct in6_addr *coa, struct in6_addr *rep_coa,
-+ __u16 sequence, __u8 flags,
-+ __u8 *k_bu);
-+
-+ int (*bce_tnl_rt_add) (struct in6_addr *coa,
-+ struct in6_addr *ha_addr,
-+ struct in6_addr *home_addr);
-+
-+ void (*bce_tnl_rt_del) (struct in6_addr *coa,
-+ struct in6_addr *ha_addr,
-+ struct in6_addr *home_addr);
-+
-+ void (*proxy_del) (struct in6_addr *home_addr, struct mipv6_bce *entry);
-+ int (*proxy_create) (int flags, int ifindex, struct in6_addr *coa,
-+ struct in6_addr *our_addr, struct in6_addr *home_addr);
-+
-+ int (*icmpv6_dhaad_rep_rcv) (struct sk_buff *skb);
-+ int (*icmpv6_dhaad_req_rcv) (struct sk_buff *skb);
-+ int (*icmpv6_pfxadv_rcv) (struct sk_buff *skb);
-+ int (*icmpv6_pfxsol_rcv) (struct sk_buff *skb);
-+ int (*icmpv6_paramprob_rcv) (struct sk_buff *skb);
-+
-+ int (*mn_use_hao) (struct in6_addr *daddr, struct in6_addr *saddr);
-+ void (*mn_check_tunneled_packet) (struct sk_buff *skb);
-+};
-+
-+extern struct mip6_func mip6_fn;
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/debug.h linux-2.4.25/net/ipv6/mobile_ip6/debug.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/debug.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/debug.h 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,112 @@
-+/*
-+ * MIPL Mobile IPv6 Debugging macros and functions
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef _DEBUG_H
-+#define _DEBUG_H
-+
-+#include <linux/autoconf.h>
-+
-+/* priorities for different debug conditions */
-+
-+#define DBG_CRITICAL 0 /* unrecoverable error */
-+#define DBG_ERROR 1 /* error (recoverable) */
-+#define DBG_WARNING 2 /* unusual situation but not a real error */
-+#define DBG_INFO 3 /* generally useful information */
-+#define DBG_EXTRA 4 /* extra information */
-+#define DBG_FUNC_ENTRY 6 /* use to indicate function entry and exit */
-+#define DBG_DATADUMP 7 /* packet dumps, etc. lots of flood */
-+
-+/**
-+ * NIPV6ADDR - macro for IPv6 addresses
-+ * @addr: Network byte order IPv6 address
-+ *
-+ * Macro for printing IPv6 addresses. Used in conjunction with
-+ * printk() or derivatives (such as DEBUG macro).
-+ **/
-+#define NIPV6ADDR(addr) \
-+ ntohs(((u16 *)addr)[0]), \
-+ ntohs(((u16 *)addr)[1]), \
-+ ntohs(((u16 *)addr)[2]), \
-+ ntohs(((u16 *)addr)[3]), \
-+ ntohs(((u16 *)addr)[4]), \
-+ ntohs(((u16 *)addr)[5]), \
-+ ntohs(((u16 *)addr)[6]), \
-+ ntohs(((u16 *)addr)[7])
-+
-+#ifdef CONFIG_IPV6_MOBILITY_DEBUG
-+extern int mipv6_debug;
-+
-+/**
-+ * debug_print - print debug message
-+ * @debug_level: message priority
-+ * @fname: calling function's name
-+ * @fmt: printf-style formatting string
-+ *
-+ * Prints a debug message to system log if @debug_level is less or
-+ * equal to @mipv6_debug. Should always be called using DEBUG()
-+ * macro, not directly.
-+ **/
-+static void debug_print(int debug_level, const char *fname, const char* fmt, ...)
-+{
-+ char s[1024];
-+ va_list args;
-+
-+ if (mipv6_debug < debug_level)
-+ return;
-+
-+ va_start(args, fmt);
-+ vsprintf(s, fmt, args);
-+ printk("mip6[%s]: %s\n", fname, s);
-+ va_end(args);
-+}
-+
-+/**
-+ * debug_print_buffer - print arbitrary buffer to system log
-+ * @debug_level: message priority
-+ * @data: pointer to buffer
-+ * @len: number of bytes to print
-+ *
-+ * Prints @len bytes from buffer @data to system log. @debug_level
-+ * tells on which debug level message gets printed. For
-+ * debug_print_buffer() priority %DBG_DATADUMP should be used.
-+ **/
-+#define debug_print_buffer(debug_level,data,len) { \
-+ if (mipv6_debug >= debug_level) { \
-+ int i; \
-+ for (i=0; i<len; i++) { \
-+ if (i%16 == 0) printk("\n%04x: ", i); \
-+ printk("%02x ", ((unsigned char *)data)[i]); \
-+ } \
-+ printk("\n\n"); \
-+ } \
-+}
-+
-+#define DEBUG(x,y,z...) debug_print(x,__FUNCTION__,y,##z)
-+#define DEBUG_FUNC() \
-+DEBUG(DBG_FUNC_ENTRY, "%s(%d)/%s: ", __FILE__,__LINE__,__FUNCTION__)
-+
-+#else
-+#define DEBUG(x,y,z...)
-+#define DEBUG_FUNC()
-+#define debug_print_buffer(x,y,z)
-+#endif
-+
-+#undef ASSERT
-+#define ASSERT(expression) { \
-+ if (!(expression)) { \
-+ (void)printk(KERN_ERR \
-+ "Assertion \"%s\" failed: file \"%s\", function \"%s\", line %d\n", \
-+ #expression, __FILE__, __FUNCTION__, __LINE__); \
-+ BUG(); \
-+ } \
-+}
-+
-+#endif /* _DEBUG_H */
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/exthdrs.c linux-2.4.25/net/ipv6/mobile_ip6/exthdrs.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/exthdrs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/exthdrs.c 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,394 @@
-+/*
-+ * Extension Header handling and adding code
-+ *
-+ * Authors:
-+ * Sami Kivisaari <skivisaa@cc.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/slab.h>
-+
-+#include <net/ipv6.h>
-+#include <net/ip6_route.h>
-+#include <net/addrconf.h>
-+#include <net/mipv6.h>
-+
-+#include "debug.h"
-+#include "stats.h"
-+#include "mobhdr.h"
-+#include "bcache.h"
-+#include "config.h"
-+
-+/**
-+ * mipv6_append_home_addr - Add Home Address Option
-+ * @opt: buffer for Home Address Option
-+ * @offset: offset from beginning of @opt
-+ * @addr: address for HAO
-+ *
-+ * Adds a Home Address Option to a packet. Option is stored in
-+ * @offset from beginning of @opt. The option is created but the
-+ * original source address in IPv6 header is left intact. The source
-+ * address will be changed from home address to CoA after the checksum
-+ * has been calculated in getfrag. Padding is done automatically, and
-+ * @opt must have allocated space for both actual option and pad.
-+ * Returns offset from @opt to end of options.
-+ **/
-+int mipv6_append_home_addr(__u8 *opt, int offset, struct in6_addr *addr)
-+{
-+ int pad;
-+ struct mipv6_dstopt_homeaddr *ho;
-+
-+ DEBUG(DBG_DATADUMP, "HAO: %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(addr));
-+
-+ pad = (6 - offset) & 7;
-+ mipv6_add_pad(opt + offset, pad);
-+
-+ ho = (struct mipv6_dstopt_homeaddr *)(opt + offset + pad);
-+ ho->type = MIPV6_TLV_HOMEADDR;
-+ ho->length = sizeof(*ho) - 2;
-+ ipv6_addr_copy(&ho->addr, addr);
-+
-+ return offset + pad + sizeof(*ho);
-+}
-+static inline int check_hao_validity(struct mipv6_dstopt_homeaddr *haopt,
-+ u8 *dst1,
-+ struct in6_addr *saddr,
-+ struct in6_addr *daddr)
-+{
-+ int addr_type = ipv6_addr_type(&haopt->addr);
-+ struct mipv6_bce bc_entry;
-+
-+ if (addr_type & IPV6_ADDR_LINKLOCAL ||
-+ !(addr_type & IPV6_ADDR_UNICAST)) {
-+ DEBUG(DBG_INFO, "HAO with link local or non-unicast HoA, "
-+ "not sending BE to "
-+ "home address "
-+ "%x:%x:%x:%x:%x:%x:%x:%x ",
-+ "care-of address %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(&haopt->addr),
-+ NIPV6ADDR(saddr));
-+ return -EINVAL;
-+ } else if (dst1[0] != IPPROTO_MOBILITY &&
-+ (mipv6_bcache_get(&haopt->addr,
-+ daddr, &bc_entry) != 0 ||
-+ ipv6_addr_cmp(saddr, &bc_entry.coa))) {
-+ DEBUG(DBG_INFO, "HAO without binding or incorrect CoA, "
-+ "sending BE code 1: "
-+ "home address %x:%x:%x:%x:%x:%x:%x:%x",
-+ "to care-of address %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(&haopt->addr),
-+ NIPV6ADDR(saddr));
-+ return -ENOENT;
-+ }
-+ return 0;
-+}
-+/**
-+ * mipv6_handle_homeaddr - Home Address Destination Option handler
-+ * @skb: packet buffer
-+ * @optoff: offset to where option begins
-+ *
-+ * Handles Home Address Option in IPv6 Destination Option header.
-+ * Packet and offset to option are passed. If HAO is used without
-+ * binding, sends a Binding Error code 1. When sending BE, notify bit
-+ * is cleared to prevent IPv6 error handling from sending ICMP
-+ * Parameter Problem. Returns 1 on success, otherwise zero.
-+ **/
-+int mipv6_handle_homeaddr(struct sk_buff *skb, int optoff)
-+{
-+ struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
-+ struct in6_addr coaddr;
-+ struct inet6_skb_parm *opt = (struct inet6_skb_parm *) skb->cb;
-+ struct mipv6_dstopt_homeaddr *haopt =
-+ (struct mipv6_dstopt_homeaddr *) &skb->nh.raw[optoff];
-+ u8 *dst1;
-+ int err;
-+
-+ DEBUG_FUNC();
-+
-+ if (haopt->length != sizeof(*haopt) - 2) {
-+ DEBUG(DBG_WARNING, "HAO has invalid length");
-+ MIPV6_INC_STATS(n_ha_drop.invalid);
-+ return 0;
-+ }
-+ dst1 = (u8 *)skb->h.raw;
-+ err = check_hao_validity(haopt, dst1, saddr, &skb->nh.ipv6h->daddr);
-+
-+ if (err) {
-+ haopt->type &= ~(0x80); /* clear notify bit */
-+ if (err == -ENOENT)
-+ mipv6_send_be(&skb->nh.ipv6h->daddr, saddr,
-+ &haopt->addr, MIPV6_BE_HAO_WO_BINDING);
-+ MIPV6_INC_STATS(n_ha_drop.misc);
-+ return 0;
-+ }
-+ ipv6_addr_copy(&coaddr, saddr);
-+ ipv6_addr_copy(saddr, &haopt->addr);
-+ ipv6_addr_copy(&haopt->addr, &coaddr);
-+ opt->hao = optoff;
-+ if (mip6_fn.mn_check_tunneled_packet != NULL)
-+ mip6_fn.mn_check_tunneled_packet(skb);
-+
-+ MIPV6_INC_STATS(n_ha_rcvd);
-+ return 1;
-+}
-+
-+/**
-+ * mipv6_icmp_swap_addrs - Switch HAO and src and RT2 and dest for ICMP errors
-+ * @skb: packet buffer
-+ *
-+ * Reset the source address and the Home Address option in skb before
-+ * appending it to an ICMP error message, so original packet appears
-+ * in the error message rather than mangled.
-+ **/
-+void mipv6_icmp_swap_addrs(struct sk_buff *skb)
-+{
-+ struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
-+ struct in6_addr tmp;
-+ struct in6_addr *hoa;
-+ DEBUG_FUNC();
-+ if (opt->srcrt2) {
-+ struct rt2_hdr *rt2;
-+ rt2 = (struct rt2_hdr *)(skb->nh.raw + opt->srcrt2);
-+ hoa = &rt2->addr;
-+
-+ ipv6_addr_copy(&tmp, hoa);
-+ ipv6_addr_copy(hoa, &skb->nh.ipv6h->daddr);
-+ ipv6_addr_copy(&skb->nh.ipv6h->daddr, &tmp);
-+ rt2->rt_hdr.segments_left++;
-+ skb->nh.ipv6h->hop_limit++;
-+ }
-+ if (opt->hao) {
-+ struct mipv6_dstopt_homeaddr *hao;
-+ hao = (struct mipv6_dstopt_homeaddr *)(skb->nh.raw + opt->hao);
-+ hoa = &hao->addr;
-+
-+ ipv6_addr_copy(&tmp, hoa);
-+ ipv6_addr_copy(hoa, &skb->nh.ipv6h->saddr);
-+ ipv6_addr_copy(&skb->nh.ipv6h->saddr, &tmp);
-+ }
-+}
-+
-+/**
-+ * mipv6_append_rt2hdr - Add Type 2 Routing Header
-+ * @rt: buffer for new routing header
-+ * @addr: intermediate hop address
-+ *
-+ * Adds a Routing Header Type 2 in a packet. Stores newly created
-+ * routing header in buffer @rt. Type 2 RT only carries one address,
-+ * so there is no need to process old routing header. @rt must have
-+ * allocated space for 24 bytes.
-+ **/
-+void mipv6_append_rt2hdr(struct ipv6_rt_hdr *rt, struct in6_addr *addr)
-+{
-+ struct rt2_hdr *rt2 = (struct rt2_hdr *)rt;
-+
-+ DEBUG(DBG_DATADUMP, "RT2: %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(addr));
-+
-+ if (ipv6_addr_type(addr) == IPV6_ADDR_MULTICAST) {
-+ DEBUG(DBG_ERROR, "destination address not unicast");
-+ return;
-+ }
-+
-+ memset(rt2, 0, sizeof(*rt2));
-+ rt2->rt_hdr.type = 2;
-+ rt2->rt_hdr.hdrlen = 2;
-+ rt2->rt_hdr.segments_left = 1;
-+ ipv6_addr_copy(&rt2->addr, addr);
-+}
-+
-+/**
-+ * mipv6_append_dst1opts - Add Destination Option (1) Headers
-+ * @dst1opt: buffer for new destination options
-+ * @saddr: address for Home Address Option
-+ * @old_dst1opt: old destination options
-+ * @len: length of options
-+ *
-+ * Adds Destination Option (1) Header to a packet. New options are
-+ * stored in @dst1opt. If old destination options exist, they are
-+ * copied from @old_dst1opt. Only Home Address Option is destination
-+ * option. @dstopt must have allocated space for @len bytes. @len
-+ * includes Destination Option Header (2 bytes), Home Address Option
-+ * (18 bytes) and possible HAO pad (8n+6).
-+ **/
-+/*
-+ * ISSUE: Home Address Destination Option should really be added to a
-+ * new destination option header specified in Mobile IPv6 spec which
-+ * should be placed after routing header(s), but before fragmentation
-+ * header. Putting HAO in DO1 works for now, but support for the new
-+ * placement should be added to the IPv6 stack.
-+ */
-+void
-+mipv6_append_dst1opts(struct ipv6_opt_hdr *dst1opt, struct in6_addr *saddr,
-+ struct ipv6_opt_hdr *old_dst1opt, int len)
-+{
-+ int offset;
-+
-+ if (old_dst1opt) {
-+ memcpy(dst1opt, old_dst1opt, ipv6_optlen(old_dst1opt));
-+ offset = ipv6_optlen(old_dst1opt);
-+ } else {
-+ offset = sizeof (*dst1opt);
-+ }
-+ dst1opt->hdrlen = (len >> 3) - 1;
-+ mipv6_append_home_addr((__u8 *) dst1opt, offset, saddr);
-+}
-+
-+/**
-+ * mipv6_modify_txoptions - Modify outgoing packets
-+ * @sk: socket
-+ * @skb: packet buffer for outgoing packet
-+ * @old_opt: transmit options
-+ * @fl: packet flow structure
-+ * @dst: pointer to destination cache entry
-+ *
-+ * Adds Home Address Option (for MN packets, when not at home) and
-+ * Routing Header Type 2 (for CN packets when sending to an MN) to
-+ * data packets. Old extension headers are copied from @old_opt (if
-+ * any). Extension headers are _explicitly_ added for packets with
-+ * Mobility Header. Returns the new header structure, or old if no
-+ * changes.
-+ **/
-+struct ipv6_txoptions *
-+mipv6_modify_txoptions(struct sock *sk, struct sk_buff *skb,
-+ struct ipv6_txoptions *old_opt, struct flowi *fl,
-+ struct dst_entry **dst)
-+{
-+ struct ipv6_opt_hdr *old_hopopt = NULL;
-+ struct ipv6_opt_hdr *old_dst1opt = NULL;
-+ struct ipv6_rt_hdr *old_srcrt = NULL;
-+
-+ int srcrtlen = 0, dst1len = 0;
-+ int tot_len, use_hao = 0;
-+ struct ipv6_txoptions *opt;
-+ struct mipv6_bce bc_entry;
-+ struct in6_addr tmpaddr, *saddr, *daddr, coaddr;
-+ __u8 *opt_ptr;
-+
-+ DEBUG_FUNC();
-+
-+ if (fl->proto == IPPROTO_MOBILITY) return old_opt;
-+ /*
-+ * we have to be prepared to the fact that saddr might not be present,
-+ * if that is the case, we acquire saddr just as kernel does.
-+ */
-+ saddr = fl ? fl->fl6_src : NULL;
-+ daddr = fl ? fl->fl6_dst : NULL;
-+
-+ if (daddr == NULL)
-+ return old_opt;
-+ if (saddr == NULL) {
-+ int err = ipv6_get_saddr(NULL, daddr, &tmpaddr);
-+ if (err)
-+ return old_opt;
-+ else
-+ saddr = &tmpaddr;
-+ }
-+
-+ DEBUG(DBG_DATADUMP,
-+ "dest. address of packet: %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(daddr));
-+ DEBUG(DBG_DATADUMP, " and src. address: %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(saddr));
-+
-+ if (old_opt) {
-+ old_hopopt = old_opt->hopopt;
-+ old_dst1opt = old_opt->dst1opt;
-+ old_srcrt = old_opt->srcrt;
-+ }
-+
-+ if (mip6_fn.mn_use_hao != NULL)
-+ use_hao = mip6_fn.mn_use_hao(daddr, saddr);
-+
-+ if (use_hao) {
-+ if (old_dst1opt)
-+ dst1len = ipv6_optlen(old_dst1opt);
-+ dst1len += sizeof(struct mipv6_dstopt_homeaddr) +
-+ ((6 - dst1len) & 7); /* padding */
-+ }
-+
-+ if (mipv6_bcache_get(daddr, saddr, &bc_entry) == 0)
-+ srcrtlen = sizeof(struct rt2_hdr);
-+
-+ if ((tot_len = srcrtlen + dst1len) == 0) {
-+ return old_opt;
-+ }
-+
-+ tot_len += sizeof(*opt);
-+
-+ if (!(opt = kmalloc(tot_len, GFP_ATOMIC))) {
-+ return NULL;
-+ }
-+ memset(opt, 0, tot_len);
-+ opt->tot_len = tot_len;
-+ opt_ptr = (__u8 *) (opt + 1);
-+
-+ if (old_srcrt) {
-+ opt->srcrt = old_srcrt;
-+ opt->opt_nflen += ipv6_optlen(old_srcrt);
-+ }
-+
-+ if (srcrtlen) {
-+ DEBUG(DBG_DATADUMP, "Binding exists. Adding routing header");
-+
-+ opt->srcrt2 = (struct ipv6_rt_hdr *) opt_ptr;
-+ opt->opt_nflen += srcrtlen;
-+ opt_ptr += srcrtlen;
-+
-+ /*
-+ * Append care-of-address to routing header (original
-+ * destination address is home address, the first
-+ * source route segment gets put to the destination
-+ * address and the home address gets to the last
-+ * segment of source route (just as it should))
-+ */
-+
-+ ipv6_addr_copy(&coaddr, &bc_entry.coa);
-+
-+ mipv6_append_rt2hdr(opt->srcrt2, &coaddr);
-+
-+ /*
-+ * reroute output (we have to do this in case of TCP
-+ * segment) unless a routing header of type 0 is also added
-+ */
-+ if (dst && !opt->srcrt) {
-+ struct in6_addr *tmp = fl->fl6_dst;
-+ fl->fl6_dst = &coaddr;
-+
-+ dst_release(*dst);
-+ *dst = ip6_route_output(sk, fl);
-+ if (skb)
-+ skb->dst = *dst;
-+ fl->fl6_dst = tmp;
-+
-+ DEBUG(DBG_DATADUMP, "Rerouted outgoing packet");
-+ }
-+ }
-+
-+ /* Only home address option is inserted to first dst opt header */
-+ if (dst1len) {
-+ opt->dst1opt = (struct ipv6_opt_hdr *) opt_ptr;
-+ opt->opt_flen += dst1len;
-+ opt_ptr += dst1len;
-+ mipv6_append_dst1opts(opt->dst1opt, saddr,
-+ old_dst1opt, dst1len);
-+ opt->mipv6_flags = MIPV6_SND_HAO;
-+ } else if (old_dst1opt) {
-+ opt->dst1opt = old_dst1opt;
-+ opt->opt_flen += ipv6_optlen(old_dst1opt);
-+ }
-+ if (old_hopopt) {
-+ opt->hopopt = old_hopopt;
-+ opt->opt_nflen += ipv6_optlen(old_hopopt);
-+ }
-+
-+ return opt;
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/exthdrs.h linux-2.4.25/net/ipv6/mobile_ip6/exthdrs.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/exthdrs.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/exthdrs.h 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,47 @@
-+/*
-+ * MIPL Mobile IPv6 Extension Headers header file
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef _MIPV6_EXTHDRS_H
-+#define _MIPV6_EXTHDRS_H
-+
-+struct in6_addr;
-+struct sk_buff;
-+struct ipv6_rt_hdr;
-+struct ipv6_opt_hdr;
-+struct ipv6_txoptions;
-+struct flowi;
-+struct dst_entry;
-+/*
-+ * Home Address Destination Option function prototypes
-+ */
-+int mipv6_append_home_addr(__u8 *opt, int offset, struct in6_addr *addr);
-+
-+int mipv6_handle_homeaddr(struct sk_buff *skb, int optoff);
-+
-+void mipv6_icmp_swap_addrs(struct sk_buff *skb);
-+
-+/*
-+ * Creates a routing header of type 2.
-+ */
-+void mipv6_append_rt2hdr(struct ipv6_rt_hdr *srcrt, struct in6_addr *addr);
-+
-+/* Function to add the first destination option header, which may
-+ * include a home address option.
-+ */
-+void mipv6_append_dst1opts(struct ipv6_opt_hdr *dst1opt, struct in6_addr *saddr,
-+ struct ipv6_opt_hdr *old_dst1opt, int len);
-+
-+struct ipv6_txoptions *mipv6_modify_txoptions(
-+ struct sock *sk, struct sk_buff *skb,
-+ struct ipv6_txoptions *old_opt, struct flowi *fl,
-+ struct dst_entry **dst);
-+
-+#endif /* _MIPV6_EXTHDRS_H */
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/ha.c linux-2.4.25/net/ipv6/mobile_ip6/ha.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/ha.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/ha.c 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,553 @@
-+/*
-+ * Home-agent functionality
-+ *
-+ * Authors:
-+ * Sami Kivisaari <skivisaa@cc.hut.fi>
-+ * Henrik Petander <lpetande@cc.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * 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.
-+ *
-+ * Changes: Venkata Jagana,
-+ * Krishna Kumar : Statistics fix
-+ * Masahide Nakamura : Use of mipv6_forward
-+ *
-+ */
-+
-+#include <linux/autoconf.h>
-+#include <linux/net.h>
-+#include <linux/skbuff.h>
-+#include <linux/if_ether.h>
-+#include <linux/netdevice.h>
-+#include <linux/in6.h>
-+#include <linux/init.h>
-+#include <linux/netfilter.h>
-+#include <linux/netfilter_ipv6.h>
-+#ifdef CONFIG_SYSCTL
-+#include <linux/sysctl.h>
-+#endif
-+
-+#include <net/neighbour.h>
-+#include <net/ipv6.h>
-+#include <net/ip6_fib.h>
-+#include <net/ip6_route.h>
-+#include <net/ndisc.h>
-+#include <net/addrconf.h>
-+#include <net/neighbour.h>
-+
-+#include "tunnel_ha.h"
-+#include "bcache.h"
-+#include "stats.h"
-+#include "debug.h"
-+#include "util.h"
-+#include "ha.h"
-+#include "config.h"
-+#include "mobhdr.h"
-+
-+static int mipv6_ha_tunnel_sitelocal = 0;
-+
-+#ifdef CONFIG_SYSCTL
-+
-+static struct ctl_table_header *mipv6_ha_sysctl_header;
-+
-+static struct mipv6_ha_sysctl_table
-+{
-+ struct ctl_table_header *sysctl_header;
-+ ctl_table mipv6_vars[3];
-+ ctl_table mipv6_mobility_table[2];
-+ ctl_table mipv6_proto_table[2];
-+ ctl_table mipv6_root_table[2];
-+} mipv6_ha_sysctl = {
-+ NULL,
-+
-+ {{NET_IPV6_MOBILITY_TUNNEL_SITELOCAL, "tunnel_sitelocal",
-+ &mipv6_ha_tunnel_sitelocal, sizeof(int), 0644, NULL,
-+ &proc_dointvec},
-+ {0}},
-+
-+ {{NET_IPV6_MOBILITY, "mobility", NULL, 0, 0555,
-+ mipv6_ha_sysctl.mipv6_vars}, {0}},
-+ {{NET_IPV6, "ipv6", NULL, 0, 0555,
-+ mipv6_ha_sysctl.mipv6_mobility_table}, {0}},
-+ {{CTL_NET, "net", NULL, 0, 0555,
-+ mipv6_ha_sysctl.mipv6_proto_table}, {0}}
-+};
-+
-+#endif /* CONFIG_SYSCTL */
-+
-+
-+/* this is defined in kernel IPv6 module (sockglue.c) */
-+extern struct packet_type ipv6_packet_type;
-+
-+/* mipv6_forward: Intercept NS packets destined to home address of MN */
-+int mipv6_forward(struct sk_buff *skb)
-+{
-+ struct ipv6hdr *ipv6h;
-+ struct in6_addr *daddr, *saddr;
-+ __u8 nexthdr;
-+ int nhoff;
-+
-+ if (skb == NULL) return 0;
-+
-+ ipv6h = skb->nh.ipv6h;
-+ daddr = &ipv6h->daddr;
-+ saddr = &ipv6h->saddr;
-+
-+ nexthdr = ipv6h->nexthdr;
-+ nhoff = sizeof(*ipv6h);
-+
-+ if (ipv6_ext_hdr(nexthdr))
-+ nhoff = ipv6_skip_exthdr(skb, nhoff, &nexthdr,
-+ skb->len - sizeof(*ipv6h));
-+
-+ /* Do not to forward Neighbor Solicitation to Home Address of MN */
-+ if (nexthdr == IPPROTO_ICMPV6) {
-+ struct icmp6hdr *icmp6h;
-+ int dest_type;
-+
-+ if (nhoff < 0 || !pskb_may_pull(skb, nhoff +
-+ sizeof(struct icmp6hdr))) {
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+
-+ dest_type = ipv6_addr_type(daddr);
-+ icmp6h = (struct icmp6hdr *)&skb->nh.raw[nhoff];
-+
-+ /* Intercepts NS to HoA of MN */
-+
-+ if ((icmp6h->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION) ||
-+ ((dest_type & IPV6_ADDR_MULTICAST) &&
-+ (icmp6h->icmp6_type == NDISC_ROUTER_ADVERTISEMENT))) {
-+ ip6_input(skb);
-+ } else {
-+ ip6_forward(skb);
-+ }
-+ } else {
-+ ip6_forward(skb);
-+ }
-+ return 0;
-+}
-+
-+
-+/**
-+ * mipv6_proxy_nd_rem - stop acting as a proxy for @home_address
-+ * @home_addr: address to remove
-+ * @ha_addr: home agent's address on home link
-+ * @linklocal: link-local compatibility bit
-+ *
-+ * When Home Agent acts as a proxy for an address it must leave the
-+ * solicited node multicast group for that address and stop responding
-+ * to neighbour solicitations.
-+ **/
-+static int mipv6_proxy_nd_rem(struct in6_addr *home_addr,
-+ int ifindex, int linklocal)
-+{
-+ /* When MN returns home HA leaves the solicited mcast groups
-+ * for MNs home addresses
-+ */
-+ int err;
-+ struct net_device *dev;
-+
-+ DEBUG_FUNC();
-+
-+ if ((dev = dev_get_by_index(ifindex)) == NULL) {
-+ DEBUG(DBG_ERROR, "couldn't get dev");
-+ return -ENODEV;
-+ }
-+#if 1 /* TEST */
-+ /* Remove link-local entry */
-+ if (linklocal) {
-+ struct in6_addr ll_addr;
-+ mipv6_generate_ll_addr(&ll_addr, home_addr);
-+ if ((err = pneigh_delete(&nd_tbl, &ll_addr, dev)) < 0) {
-+ DEBUG(DBG_INFO,
-+ "peigh_delete failed for "
-+ "%x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(&ll_addr));
-+ }
-+ }
-+#endif
-+ /* Remove global (or site-local) entry */
-+ if ((err = pneigh_delete(&nd_tbl, home_addr, dev)) < 0) {
-+ DEBUG(DBG_INFO,
-+ "peigh_delete failed for "
-+ "%x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(home_addr));
-+ }
-+ dev_put(dev);
-+ return err;
-+}
-+
-+/**
-+ * mipv6_proxy_nd - join multicast group for this address
-+ * @home_addr: address to defend
-+ * @ha_addr: home agent's address on home link
-+ * @linklocal: link-local compatibility bit
-+ *
-+ * While Mobile Node is away from home, Home Agent acts as a proxy for
-+ * @home_address. HA responds to neighbour solicitations for @home_address
-+ * thus getting all packets destined to home address of MN.
-+ **/
-+static int mipv6_proxy_nd(struct in6_addr *home_addr,
-+ int ifindex, int linklocal)
-+{
-+ /* The HA sends a proxy ndisc_na message to all hosts on MN's
-+ * home subnet by sending a neighbor advertisement with the
-+ * home address or all addresses of the mobile node if the
-+ * prefix is not 0. The addresses are formed by combining the
-+ * suffix or the host part of the address with each subnet
-+ * prefix that exists in the home subnet
-+ */
-+
-+ /* Since no previous entry for MN exists a proxy_nd advertisement
-+ * is sent to all nodes link local multicast address
-+ */
-+ int err = -1;
-+
-+ struct net_device *dev;
-+ struct in6_addr na_saddr;
-+ struct in6_addr ll_addr;
-+ struct pneigh_entry *ll_pneigh;
-+ struct in6_addr mcdest;
-+ int send_ll_na = 0;
-+ int inc_opt = 1;
-+ int solicited = 0;
-+ int override = 1;
-+
-+ DEBUG_FUNC();
-+
-+ if ((dev = dev_get_by_index(ifindex)) == NULL) {
-+ DEBUG(DBG_ERROR, "couldn't get dev");
-+ return -ENODEV;
-+ }
-+
-+ if (!pneigh_lookup(&nd_tbl, home_addr, dev, 1)) {
-+ DEBUG(DBG_INFO,
-+ "peigh_lookup failed for "
-+ "%x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(home_addr));
-+ goto free_dev;
-+ }
-+#if 1 /* TEST */
-+ if (linklocal) {
-+ mipv6_generate_ll_addr(&ll_addr, home_addr);
-+
-+ if ((ll_pneigh = pneigh_lookup(&nd_tbl, &ll_addr,
-+ dev, 1)) == NULL) {
-+ DEBUG(DBG_INFO,
-+ "peigh_lookup failed for "
-+ "%x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(&ll_addr));
-+ pneigh_delete(&nd_tbl, home_addr, dev);
-+ goto free_dev;
-+ } else {
-+ send_ll_na = 1;
-+ }
-+ } else {
-+ ll_pneigh = NULL;
-+ }
-+#endif
-+ /* Proxy neighbor advertisement of MN's home address
-+ * to all nodes solicited multicast address
-+ */
-+ if (!ipv6_get_lladdr(dev, &na_saddr)) {
-+ ipv6_addr_all_nodes(&mcdest);
-+ ndisc_send_na(dev, NULL, &mcdest, home_addr, 0,
-+ solicited, override, inc_opt);
-+#if 1 /* TEST */
-+ if (send_ll_na) {
-+ ndisc_send_na(dev, NULL, &mcdest, &ll_addr,
-+ 0, solicited, override, inc_opt);
-+ }
-+#endif
-+ err = 0;
-+ } else {
-+ DEBUG(DBG_ERROR, "failed to get link local address for sending proxy NA");
-+ }
-+free_dev:
-+ dev_put(dev);
-+ return err;
-+
-+}
-+
-+struct inet6_ifaddr *is_on_link_ipv6_address(struct in6_addr *mn_haddr,
-+ struct in6_addr *ha_addr)
-+{
-+ struct inet6_ifaddr *ifp;
-+ struct inet6_dev *in6_dev;
-+ struct inet6_ifaddr *oifp = NULL;
-+
-+ if ((ifp = ipv6_get_ifaddr(ha_addr, 0)) == NULL)
-+ return NULL;
-+
-+ if ((in6_dev = ifp->idev) != NULL) {
-+ in6_dev_hold(in6_dev);
-+ oifp = in6_dev->addr_list;
-+ while (oifp != NULL) {
-+ spin_lock(&oifp->lock);
-+ if (mipv6_prefix_compare(&oifp->addr, mn_haddr,
-+ oifp->prefix_len) &&
-+ !(oifp->flags & IFA_F_TENTATIVE)) {
-+ spin_unlock(&oifp->lock);
-+ DEBUG(DBG_INFO, "Home Addr Opt: on-link");
-+ in6_ifa_hold(oifp);
-+ break;
-+ }
-+ spin_unlock(&oifp->lock);
-+ oifp = oifp->if_next;
-+ }
-+ in6_dev_put(in6_dev);
-+ }
-+ in6_ifa_put(ifp);
-+/* DEBUG(DBG_WARNING, "Home Addr Opt NOT on-link"); */
-+ return oifp;
-+
-+}
-+
-+/*
-+ * Lifetime checks. ifp->valid_lft >= ifp->prefered_lft always (see addrconf.c)
-+ * Returned value is in seconds.
-+ */
-+
-+static __u32 get_min_lifetime(struct inet6_ifaddr *ifp, __u32 lifetime)
-+{
-+ __u32 rem_lifetime = 0;
-+ unsigned long now = jiffies;
-+
-+ if (ifp->valid_lft == 0) {
-+ rem_lifetime = lifetime;
-+ } else {
-+ __u32 valid_lft_left =
-+ ifp->valid_lft - ((now - ifp->tstamp) / HZ);
-+ rem_lifetime =
-+ min_t(unsigned long, valid_lft_left, lifetime);
-+ }
-+
-+ return rem_lifetime;
-+}
-+
-+#define MAX_LIFETIME 1000
-+
-+/**
-+ * mipv6_lifetime_check - check maximum lifetime is not exceeded
-+ * @lifetime: lifetime to check
-+ *
-+ * Checks @lifetime does not exceed %MAX_LIFETIME. Returns @lifetime
-+ * if not exceeded, otherwise returns %MAX_LIFETIME.
-+ **/
-+static int mipv6_lifetime_check(int lifetime)
-+{
-+ return (lifetime > MAX_LIFETIME) ? MAX_LIFETIME : lifetime;
-+}
-+
-+/* Generic routine handling finish of BU processing */
-+void mipv6_bu_finish(struct inet6_ifaddr *ifp, int ifindex, __u8 ba_status,
-+ struct in6_addr *daddr, struct in6_addr *haddr,
-+ struct in6_addr *coa, struct in6_addr *rep_coa,
-+ __u32 ba_lifetime, __u16 sequence, __u8 flags, __u8 *k_bu)
-+{
-+ int err;
-+
-+ if (ba_status >= REASON_UNSPECIFIED) {
-+ /* DAD failed */
-+ goto out;
-+ }
-+
-+ ba_lifetime = get_min_lifetime(ifp, ba_lifetime);
-+ ba_lifetime = mipv6_lifetime_check(ba_lifetime);
-+
-+ if ((err = mipv6_bcache_add(ifindex, daddr, haddr, coa,
-+ ba_lifetime, sequence, flags,
-+ HOME_REGISTRATION)) != 0 ) {
-+ DEBUG(DBG_WARNING, "home reg failed.");
-+
-+ if (err == -ENOMEDIUM)
-+ return;
-+
-+ ba_status = INSUFFICIENT_RESOURCES;
-+ } else {
-+ DEBUG(DBG_INFO, "home reg succeeded.");
-+ }
-+
-+ DEBUG(DBG_DATADUMP, "home_addr: %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(haddr));
-+ DEBUG(DBG_DATADUMP, "coa: %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(coa));
-+ DEBUG(DBG_DATADUMP, "lifet:%d, seq:%d", ba_lifetime, sequence);
-+out:
-+ mipv6_send_ba(daddr, haddr, coa, rep_coa, ba_status, sequence,
-+ ba_lifetime, k_bu);
-+}
-+
-+static int ha_proxy_create(int flags, int ifindex, struct in6_addr *coa,
-+ struct in6_addr *our_addr, struct in6_addr *home_addr)
-+{
-+ int ret;
-+
-+ if ((ret = mipv6_add_tnl_to_mn(coa, our_addr, home_addr)) <= 0) {
-+ if (ret != -ENOMEDIUM) {
-+ DEBUG(DBG_ERROR, "unable to configure tunnel to MN!");
-+ }
-+ return -1;
-+ }
-+ if (mipv6_proxy_nd(home_addr, ifindex,
-+ flags & MIPV6_BU_F_LLADDR) != 0) {
-+ DEBUG(DBG_ERROR, "mipv6_proxy_nd failed!");
-+ mipv6_del_tnl_to_mn(coa, our_addr, home_addr);
-+ return -2;
-+ }
-+ return 0;
-+}
-+
-+static void ha_proxy_del(struct in6_addr *home_addr, struct mipv6_bce *entry)
-+{
-+ if (mipv6_proxy_nd_rem(&entry->home_addr, entry->ifindex,
-+ entry->flags & MIPV6_BU_F_LLADDR) == 0) {
-+ DEBUG(DBG_INFO, "proxy_nd succ");
-+ } else {
-+ DEBUG(DBG_INFO, "proxy_nd fail");
-+ }
-+ mipv6_del_tnl_to_mn(&entry->coa, &entry->our_addr, home_addr);
-+}
-+
-+static void bc_home_add(int ifindex,
-+ struct in6_addr *daddr, struct in6_addr *haddr,
-+ struct in6_addr *coa, struct in6_addr *rep_coa,
-+ __u32 lifetime, __u16 sequence, __u8 flags,
-+ __u8 *k_bu)
-+{
-+ struct inet6_ifaddr *ifp = NULL;
-+ __u8 ba_status = SUCCESS;
-+
-+ DEBUG_FUNC();
-+
-+ ifp = is_on_link_ipv6_address(haddr, daddr);
-+
-+ if (ifp == NULL) {
-+ ba_status = NOT_HOME_SUBNET;
-+ } else if (((ipv6_addr_type(haddr) & IPV6_ADDR_SITELOCAL) ||
-+ (ipv6_addr_type(coa) & IPV6_ADDR_SITELOCAL))
-+ && !mipv6_ha_tunnel_sitelocal) {
-+ /* Site-local home or care-of addresses are not
-+ accepted by default */
-+ ba_status = ADMINISTRATIVELY_PROHIBITED;
-+ } else {
-+ int ret;
-+
-+ ifindex = ifp->idev->dev->ifindex;
-+
-+ if ((ret = mipv6_dad_start(ifp, ifindex, daddr,
-+ haddr, coa, rep_coa, lifetime,
-+ sequence, flags)) < 0) {
-+ /* An error occurred */
-+ ba_status = -ret;
-+ } else if (ret) {
-+ /* DAD is needed to be performed. */
-+ in6_ifa_put(ifp);
-+ return;
-+ }
-+ }
-+
-+ mipv6_bu_finish(ifp, ifindex, ba_status, daddr, haddr, coa,
-+ rep_coa, lifetime, sequence, flags, k_bu);
-+ if (ifp)
-+ in6_ifa_put(ifp);
-+}
-+
-+static void bc_home_delete(struct in6_addr *daddr, struct in6_addr *haddr,
-+ struct in6_addr *coa, struct in6_addr *rep_coa,
-+ __u16 sequence, __u8 flags, __u8 *k_bu)
-+{
-+ __u8 status = SUCCESS;
-+ struct mipv6_bce bce;
-+
-+ /* Primary Care-of Address Deregistration */
-+ if (mipv6_bcache_get(haddr, daddr, &bce) < 0) {
-+ DEBUG(DBG_INFO, "entry is not in cache");
-+ status = NOT_HA_FOR_MN;
-+ } else {
-+ ha_proxy_del(&bce.home_addr, &bce);
-+ mipv6_bcache_delete(haddr, daddr, HOME_REGISTRATION);
-+ }
-+ mipv6_send_ba(daddr, haddr, coa, rep_coa, status, sequence, 0, k_bu);
-+}
-+
-+extern int mipv6_ra_rcv_ptr(struct sk_buff *skb, struct icmp6hdr *msg);
-+
-+
-+static int
-+mipv6_ha_tnl_xmit_stats_hook(struct ip6_tnl *t, struct sk_buff *skb)
-+{
-+ DEBUG_FUNC();
-+ if (is_mip6_tnl(t))
-+ MIPV6_INC_STATS(n_encapsulations);
-+ return IP6_TNL_ACCEPT;
-+}
-+
-+static struct ip6_tnl_hook_ops mipv6_ha_tnl_xmit_stats_ops = {
-+ {NULL, NULL},
-+ IP6_TNL_PRE_ENCAP,
-+ IP6_TNL_PRI_LAST,
-+ mipv6_ha_tnl_xmit_stats_hook
-+};
-+
-+static int
-+mipv6_ha_tnl_rcv_stats_hook(struct ip6_tnl *t, struct sk_buff *skb)
-+{
-+ DEBUG_FUNC();
-+ if (is_mip6_tnl(t))
-+ MIPV6_INC_STATS(n_decapsulations);
-+ return IP6_TNL_ACCEPT;
-+}
-+
-+static struct ip6_tnl_hook_ops mipv6_ha_tnl_rcv_stats_ops = {
-+ {NULL, NULL},
-+ IP6_TNL_PRE_DECAP,
-+ IP6_TNL_PRI_LAST,
-+ mipv6_ha_tnl_rcv_stats_hook
-+};
-+
-+static struct mip6_func old;
-+
-+int __init mipv6_ha_init(void)
-+{
-+ DEBUG_FUNC();
-+
-+#ifdef CONFIG_SYSCTL
-+ if (!(mipv6_ha_sysctl_header =
-+ register_sysctl_table(mipv6_ha_sysctl.mipv6_root_table, 0)))
-+ printk(KERN_ERR "Failed to register sysctl handlers!");
-+#endif
-+ memcpy(&old, &mip6_fn, sizeof(struct mip6_func));
-+ mip6_fn.bce_home_add = bc_home_add;
-+ mip6_fn.bce_home_del = bc_home_delete;
-+ mip6_fn.proxy_del = ha_proxy_del;
-+ mip6_fn.proxy_create = ha_proxy_create;
-+ /* register packet interception hooks */
-+ ip6ip6_tnl_register_hook(&mipv6_ha_tnl_xmit_stats_ops);
-+ ip6ip6_tnl_register_hook(&mipv6_ha_tnl_rcv_stats_ops);
-+ return 0;
-+}
-+
-+void __exit mipv6_ha_exit(void)
-+{
-+ DEBUG_FUNC();
-+
-+#ifdef CONFIG_SYSCTL
-+ unregister_sysctl_table(mipv6_ha_sysctl_header);
-+#endif
-+
-+ /* remove packet interception hooks */
-+ ip6ip6_tnl_unregister_hook(&mipv6_ha_tnl_rcv_stats_ops);
-+ ip6ip6_tnl_unregister_hook(&mipv6_ha_tnl_xmit_stats_ops);
-+
-+ mip6_fn.bce_home_add = old.bce_home_add;
-+ mip6_fn.bce_home_del = old.bce_home_del;
-+ mip6_fn.proxy_del = old.proxy_del;
-+ mip6_fn.proxy_create = old.proxy_create;
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/ha.h linux-2.4.25/net/ipv6/mobile_ip6/ha.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/ha.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/ha.h 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,39 @@
-+/*
-+ * MIPL Mobile IPv6 Home Agent header file
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef _HA_H
-+#define _HA_H
-+
-+int mipv6_ha_init(void);
-+void mipv6_ha_exit(void);
-+
-+int mipv6_dad_start(struct inet6_ifaddr *ifp, int ifindex,
-+ struct in6_addr *daddr, struct in6_addr *haddr,
-+ struct in6_addr *coa, struct in6_addr *rep_coa,
-+ __u32 ba_lifetime, __u16 sequence, __u8 flags);
-+
-+void mipv6_bu_finish(struct inet6_ifaddr *ifp, int ifindex,
-+ __u8 ba_status, struct in6_addr *daddr,
-+ struct in6_addr *haddr, struct in6_addr *coa,
-+ struct in6_addr *rep_coa, __u32 ba_lifetime,
-+ __u16 sequence, __u8 flags, __u8 *k_bu);
-+
-+
-+static __inline__ void mipv6_generate_ll_addr(struct in6_addr *ll_addr,
-+ struct in6_addr *addr)
-+{
-+ ll_addr->s6_addr32[0] = htonl(0xfe800000);
-+ ll_addr->s6_addr32[1] = 0;
-+ ll_addr->s6_addr32[2] = addr->s6_addr32[2];
-+ ll_addr->s6_addr32[3] = addr->s6_addr32[3];
-+}
-+
-+#endif
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/halist.c linux-2.4.25/net/ipv6/mobile_ip6/halist.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/halist.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/halist.c 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,507 @@
-+/*
-+ * Home Agents List
-+ *
-+ * Authors:
-+ * Antti Tuominen <ajtuomin@tml.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * 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.
-+ *
-+ */
-+
-+#define PREF_BASE 0xffff /* MAX value for u16 field in RA */
-+
-+#include <linux/autoconf.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/proc_fs.h>
-+#include <linux/init.h>
-+#include <net/ipv6.h>
-+#include <net/addrconf.h>
-+
-+#include "hashlist.h"
-+#include "util.h"
-+#include "debug.h"
-+
-+struct mipv6_halist {
-+ struct hashlist *entries;
-+ struct timer_list expire_timer;
-+};
-+
-+static rwlock_t home_agents_lock = RW_LOCK_UNLOCKED;
-+
-+static struct mipv6_halist home_agents;
-+
-+struct mipv6_halist_entry {
-+ struct hashlist_entry e;
-+ int ifindex; /* Link identifier */
-+ struct in6_addr link_local_addr; /* HA's link-local address */
-+ struct in6_addr global_addr; /* HA's Global address */
-+ int plen;
-+ long preference; /* The preference for this HA */
-+ unsigned long expire; /* expiration time (jiffies) */
-+};
-+
-+static inline void mipv6_ha_ac_add(struct in6_addr *ll_addr, int ifindex,
-+ struct in6_addr *glob_addr, int plen)
-+{
-+ struct net_device *dev;
-+
-+ if ((dev = __dev_get_by_index(ifindex)) && ipv6_chk_addr(ll_addr, dev)) {
-+ struct in6_addr addr;
-+ mipv6_ha_anycast(&addr, glob_addr, plen);
-+ ipv6_dev_ac_inc(dev, &addr);
-+ }
-+}
-+
-+static inline void mipv6_ha_ac_del(struct in6_addr *ll_addr, int ifindex,
-+ struct in6_addr *glob_addr, int plen)
-+{
-+ struct net_device *dev;
-+
-+ if ((dev = __dev_get_by_index(ifindex)) && ipv6_chk_addr(ll_addr, dev)) {
-+ struct in6_addr addr;
-+ mipv6_ha_anycast(&addr, glob_addr, plen);
-+ ipv6_dev_ac_dec(dev, &addr);
-+ }
-+}
-+
-+struct preflist_iterator_args {
-+ int count;
-+ int requested;
-+ int ifindex;
-+ struct in6_addr *list;
-+};
-+
-+static int preflist_iterator(void *data, void *args,
-+ unsigned long *pref)
-+{
-+ struct preflist_iterator_args *state =
-+ (struct preflist_iterator_args *)args;
-+ struct mipv6_halist_entry *entry =
-+ (struct mipv6_halist_entry *)data;
-+ struct in6_addr *newaddr =
-+ (struct in6_addr *)state->list + state->count;
-+
-+ if (state->count >= state->requested)
-+ return ITERATOR_STOP;
-+
-+ if (time_after(jiffies, entry->expire)) {
-+ if (!ipv6_addr_any(&entry->link_local_addr)) {
-+ mipv6_ha_ac_del(&entry->link_local_addr,
-+ entry->ifindex,
-+ &entry->global_addr, entry->plen);
-+ }
-+ DEBUG(DBG_INFO, "preflist_iterator: Deleting entry with address %x:%x:%x:%x:%x:%x:%x:%x to list", NIPV6ADDR(&entry->global_addr));
-+ return ITERATOR_DELETE_ENTRY;
-+ }
-+ if (state->ifindex != entry->ifindex)
-+ return ITERATOR_CONT;
-+
-+ ipv6_addr_copy(newaddr, &entry->global_addr);
-+ DEBUG(DBG_INFO, "preflist_iterator: adding new entry with address %x:%x:%x:%x:%x:%x:%x:%x to list", NIPV6ADDR(&entry->global_addr));
-+ state->count++;
-+
-+ return ITERATOR_CONT;
-+}
-+
-+static int gc_iterator(void *data, void *args,
-+ unsigned long *pref)
-+{
-+ struct mipv6_halist_entry *entry =
-+ (struct mipv6_halist_entry *)data;
-+
-+ int *type = (int *)args;
-+
-+ if (*type == 1 || time_after(jiffies, entry->expire)) {
-+ if (!ipv6_addr_any(&entry->link_local_addr)) {
-+ mipv6_ha_ac_del(&entry->link_local_addr,
-+ entry->ifindex,
-+ &entry->global_addr, entry->plen);
-+ }
-+ return ITERATOR_DELETE_ENTRY;
-+ }
-+
-+ return ITERATOR_CONT;
-+}
-+
-+static int mipv6_halist_gc(int type)
-+{
-+ DEBUG_FUNC();
-+ hashlist_iterate(home_agents.entries, &type, gc_iterator);
-+ return 0;
-+}
-+
-+static void mipv6_halist_expire(unsigned long dummy)
-+{
-+ DEBUG_FUNC();
-+
-+ write_lock(&home_agents_lock);
-+ mipv6_halist_gc(0);
-+ write_unlock(&home_agents_lock);
-+}
-+
-+
-+static struct mipv6_halist_entry *mipv6_halist_new_entry(void)
-+{
-+ struct mipv6_halist_entry *entry;
-+
-+ DEBUG_FUNC();
-+
-+ entry = hashlist_alloc(home_agents.entries, SLAB_ATOMIC);
-+
-+ return entry;
-+}
-+
-+
-+
-+/**
-+ * mipv6_halist_add - Add new home agent to the Home Agents List
-+ * @ifindex: interface identifier
-+ * @glob_addr: home agent's global address
-+ * @ll_addr: home agent's link-local address
-+ * @pref: relative preference for this home agent
-+ * @lifetime: lifetime for the entry
-+ *
-+ * Adds new home agent to the Home Agents List. The list is interface
-+ * specific and @ifindex tells through which interface the home agent
-+ * was heard. Returns zero on success and negative on failure.
-+ **/
-+
-+int mipv6_halist_add(int ifindex, struct in6_addr *glob_addr, int plen,
-+ struct in6_addr *ll_addr, unsigned int pref, __u32 lifetime)
-+{
-+ int update = 0, ret = 0;
-+ unsigned int mpref;
-+ struct mipv6_halist_entry *entry = NULL;
-+
-+ DEBUG_FUNC();
-+
-+ write_lock(&home_agents_lock);
-+
-+ if (glob_addr == NULL || lifetime <= 0) {
-+ DEBUG(DBG_WARNING, "invalid arguments");
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+ mpref = PREF_BASE - pref;
-+ if ((entry = (struct mipv6_halist_entry *)
-+ hashlist_get(home_agents.entries, glob_addr)) != NULL) {
-+ if (entry->ifindex == ifindex) {
-+ DEBUG(DBG_DATADUMP, "updating old entry with address %x:%x:%x:%x:%x:%x:%x:%x", NIPV6ADDR(glob_addr));
-+ update = 1;
-+ } else {
-+ DEBUG(DBG_INFO, "halist_add : adding new entry with address %x:%x:%x:%x:%x:%x:%x:%x", NIPV6ADDR(glob_addr));
-+ update = 0;
-+ }
-+ }
-+ if (update) {
-+ entry->expire = jiffies + lifetime * HZ;
-+ if (entry->preference != mpref) {
-+ entry->preference = mpref;
-+ ret = hashlist_reposition(home_agents.entries,
-+ (void *)entry, mpref);
-+ }
-+ } else {
-+ entry = mipv6_halist_new_entry();
-+ if (entry == NULL) {
-+ DEBUG(DBG_INFO, "list full");
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+ entry->ifindex = ifindex;
-+ if (ll_addr) {
-+ ipv6_addr_copy(&entry->link_local_addr, ll_addr);
-+ mipv6_ha_ac_add(ll_addr, ifindex, glob_addr, plen);
-+ } else
-+ ipv6_addr_set(&entry->link_local_addr, 0, 0, 0, 0);
-+
-+ ipv6_addr_copy(&entry->global_addr, glob_addr);
-+ entry->plen = plen;
-+ entry->preference = mpref;
-+ entry->expire = jiffies + lifetime * HZ;
-+ ret = hashlist_add(home_agents.entries, glob_addr, mpref,
-+ entry);
-+ }
-+out:
-+ write_unlock(&home_agents_lock);
-+ return ret;
-+}
-+
-+/**
-+ * mipv6_halist_delete - delete home agent from Home Agents List
-+ * @glob_addr: home agent's global address
-+ *
-+ * Deletes entry for home agent @glob_addr from the Home Agent List.
-+ **/
-+int mipv6_halist_delete(struct in6_addr *glob_addr)
-+{
-+ struct hashlist_entry *e;
-+ struct mipv6_halist_entry *entry;
-+ DEBUG_FUNC();
-+
-+ if (glob_addr == NULL) {
-+ DEBUG(DBG_WARNING, "invalid glob addr");
-+ return -EINVAL;
-+ }
-+ write_lock(&home_agents_lock);
-+ if ((e = hashlist_get(home_agents.entries, glob_addr)) == NULL) {
-+ write_unlock(&home_agents_lock);
-+ return -ENOENT;
-+ }
-+ hashlist_delete(home_agents.entries, e);
-+ entry = (struct mipv6_halist_entry *)e;
-+ if (!ipv6_addr_any(&entry->link_local_addr)) {
-+ mipv6_ha_ac_del(&entry->link_local_addr, entry->ifindex,
-+ &entry->global_addr, entry->plen);
-+ }
-+ hashlist_free(home_agents.entries, e);
-+ write_unlock(&home_agents_lock);
-+ return 0;
-+}
-+
-+/**
-+ * mipv6_ha_get_pref_list - Get list of preferred home agents
-+ * @ifindex: interface identifier
-+ * @addrs: pointer to a buffer to store the list
-+ * @max: maximum number of home agents to return
-+ *
-+ * Creates a list of @max preferred (or all known if less than @max)
-+ * home agents. Home Agents List is interface specific so you must
-+ * supply @ifindex. Stores list in addrs and returns number of home
-+ * agents stored. On failure, returns a negative value.
-+ **/
-+int mipv6_ha_get_pref_list(int ifindex, struct in6_addr **addrs, int max)
-+{
-+ struct preflist_iterator_args args;
-+
-+ DEBUG_FUNC();
-+ if (max <= 0) {
-+ *addrs = NULL;
-+ return 0;
-+ }
-+
-+ args.count = 0;
-+ args.requested = max;
-+ args.ifindex = ifindex;
-+ args.list = kmalloc(max * sizeof(struct in6_addr), GFP_ATOMIC);
-+
-+ if (args.list == NULL) return -ENOMEM;
-+
-+ read_lock(&home_agents_lock);
-+ hashlist_iterate(home_agents.entries, &args, preflist_iterator);
-+ read_unlock(&home_agents_lock);
-+
-+ if (args.count >= 0) {
-+ *addrs = args.list;
-+ } else {
-+ kfree(args.list);
-+ *addrs = NULL;
-+ }
-+
-+ return args.count;
-+}
-+
-+struct getaddr_iterator_args {
-+ struct net_device *dev;
-+ struct in6_addr *addr;
-+};
-+
-+static int getaddr_iterator(void *data, void *args,
-+ unsigned long *pref)
-+{
-+ struct mipv6_halist_entry *entry =
-+ (struct mipv6_halist_entry *)data;
-+ struct getaddr_iterator_args *state =
-+ (struct getaddr_iterator_args *)args;
-+
-+ if (entry->ifindex != state->dev->ifindex)
-+ return ITERATOR_CONT;
-+
-+ if (ipv6_chk_addr(&entry->global_addr, state->dev)) {
-+ ipv6_addr_copy(state->addr, &entry->global_addr);
-+ return ITERATOR_STOP;
-+ }
-+ return ITERATOR_CONT;
-+}
-+
-+/*
-+ * Get Home Agent Address for given interface. If node is not serving
-+ * as a HA for this interface returns negative error value.
-+ */
-+int mipv6_ha_get_addr(int ifindex, struct in6_addr *addr)
-+{
-+ struct getaddr_iterator_args args;
-+ struct net_device *dev;
-+
-+ if (ifindex <= 0)
-+ return -EINVAL;
-+
-+ if ((dev = dev_get_by_index(ifindex)) == NULL)
-+ return -ENODEV;
-+
-+ memset(addr, 0, sizeof(struct in6_addr));
-+ args.dev = dev;
-+ args.addr = addr;
-+ read_lock(&home_agents_lock);
-+ hashlist_iterate(home_agents.entries, &args, getaddr_iterator);
-+ read_unlock(&home_agents_lock);
-+ dev_put(dev);
-+
-+ if (ipv6_addr_any(addr))
-+ return -ENOENT;
-+
-+ return 0;
-+}
-+
-+#define HALIST_INFO_LEN 81
-+
-+struct procinfo_iterator_args {
-+ char *buffer;
-+ int offset;
-+ int length;
-+ int skip;
-+ int len;
-+};
-+
-+static int procinfo_iterator(void *data, void *args,
-+ unsigned long *pref)
-+{
-+ struct procinfo_iterator_args *arg =
-+ (struct procinfo_iterator_args *)args;
-+ struct mipv6_halist_entry *entry =
-+ (struct mipv6_halist_entry *)data;
-+ unsigned long int expire;
-+
-+ DEBUG_FUNC();
-+
-+ if (entry == NULL) return ITERATOR_ERR;
-+
-+ if (time_after(jiffies, entry->expire)) {
-+ if (!ipv6_addr_any(&entry->link_local_addr)) {
-+ mipv6_ha_ac_del(&entry->link_local_addr,
-+ entry->ifindex,
-+ &entry->global_addr, entry->plen);
-+ }
-+ return ITERATOR_DELETE_ENTRY;
-+ }
-+ if (arg->skip < arg->offset / HALIST_INFO_LEN) {
-+ arg->skip++;
-+ return ITERATOR_CONT;
-+ }
-+
-+ if (arg->len >= arg->length)
-+ return ITERATOR_CONT;
-+
-+ expire = (entry->expire - jiffies) / HZ;
-+
-+ arg->len += sprintf(arg->buffer + arg->len,
-+ "%02d %08x%08x%08x%08x %08x%08x%08x%08x %05ld %05ld\n",
-+ entry->ifindex,
-+ ntohl(entry->global_addr.s6_addr32[0]),
-+ ntohl(entry->global_addr.s6_addr32[1]),
-+ ntohl(entry->global_addr.s6_addr32[2]),
-+ ntohl(entry->global_addr.s6_addr32[3]),
-+ ntohl(entry->link_local_addr.s6_addr32[0]),
-+ ntohl(entry->link_local_addr.s6_addr32[1]),
-+ ntohl(entry->link_local_addr.s6_addr32[2]),
-+ ntohl(entry->link_local_addr.s6_addr32[3]),
-+ -(entry->preference - PREF_BASE), expire);
-+
-+ return ITERATOR_CONT;
-+}
-+
-+static int halist_proc_info(char *buffer, char **start, off_t offset,
-+ int length)
-+{
-+ struct procinfo_iterator_args args;
-+
-+ DEBUG_FUNC();
-+
-+ args.buffer = buffer;
-+ args.offset = offset;
-+ args.length = length;
-+ args.skip = 0;
-+ args.len = 0;
-+
-+ read_lock_bh(&home_agents_lock);
-+ hashlist_iterate(home_agents.entries, &args, procinfo_iterator);
-+ read_unlock_bh(&home_agents_lock);
-+
-+ *start = buffer;
-+ if (offset)
-+ *start += offset % HALIST_INFO_LEN;
-+
-+ args.len -= offset % HALIST_INFO_LEN;
-+
-+ if (args.len > length)
-+ args.len = length;
-+ if (args.len < 0)
-+ args.len = 0;
-+
-+ return args.len;
-+}
-+
-+static int halist_compare(void *data, void *hashkey)
-+{
-+ struct mipv6_halist_entry *e = (struct mipv6_halist_entry *)data;
-+ struct in6_addr *key = (struct in6_addr *)hashkey;
-+
-+ return ipv6_addr_cmp(&e->global_addr, key);
-+}
-+
-+static __u32 halist_hash(void *hashkey)
-+{
-+ struct in6_addr *key = (struct in6_addr *)hashkey;
-+ __u32 hash;
-+
-+ hash = key->s6_addr32[0] ^
-+ key->s6_addr32[1] ^
-+ key->s6_addr32[2] ^
-+ key->s6_addr32[3];
-+
-+ return hash;
-+}
-+
-+int __init mipv6_halist_init(__u32 size)
-+{
-+ DEBUG_FUNC();
-+
-+ if (size <= 0) {
-+ DEBUG(DBG_ERROR, "size must be at least 1");
-+ return -EINVAL;
-+ }
-+ init_timer(&home_agents.expire_timer);
-+ home_agents.expire_timer.data = 0;
-+ home_agents.expire_timer.function = mipv6_halist_expire;
-+ home_agents_lock = RW_LOCK_UNLOCKED;
-+
-+ home_agents.entries = hashlist_create(16, size, sizeof(struct mipv6_halist_entry),
-+ "mip6_halist", NULL, NULL,
-+ halist_compare, halist_hash);
-+
-+ if (home_agents.entries == NULL) {
-+ DEBUG(DBG_ERROR, "Failed to initialize hashlist");
-+ return -ENOMEM;
-+ }
-+
-+ proc_net_create("mip6_home_agents", 0, halist_proc_info);
-+ DEBUG(DBG_INFO, "Home Agents List initialized");
-+ return 0;
-+}
-+
-+void __exit mipv6_halist_exit(void)
-+{
-+ DEBUG_FUNC();
-+ proc_net_remove("mip6_home_agents");
-+ write_lock_bh(&home_agents_lock);
-+ DEBUG(DBG_INFO, "Stopping the halist timer");
-+ del_timer(&home_agents.expire_timer);
-+ mipv6_halist_gc(1);
-+ write_unlock_bh(&home_agents_lock);
-+ hashlist_destroy(home_agents.entries);
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/halist.h linux-2.4.25/net/ipv6/mobile_ip6/halist.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/halist.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/halist.h 2004-06-26 11:29:30.000000000 +0100
-@@ -0,0 +1,28 @@
-+/*
-+ * MIPL Mobile IPv6 Home Agents List header file
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef _HALIST_H
-+#define _HALIST_H
-+
-+int mipv6_halist_init(__u32 size);
-+
-+void mipv6_halist_exit(void);
-+
-+int mipv6_halist_add(int ifindex, struct in6_addr *glob_addr, int plen,
-+ struct in6_addr *ll_addr, unsigned int pref, __u32 lifetime);
-+
-+int mipv6_halist_delete(struct in6_addr *glob_addr);
-+
-+int mipv6_ha_get_pref_list(int ifindex, struct in6_addr **addrs, int max);
-+
-+int mipv6_ha_get_addr(int ifindex, struct in6_addr *addr);
-+
-+#endif /* _HALIST_H */
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/hashlist.c linux-2.4.25/net/ipv6/mobile_ip6/hashlist.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/hashlist.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/hashlist.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,351 @@
-+/*
-+ * Generic hashtable with chaining. Supports secodary sort order
-+ * with doubly linked-list.
-+ *
-+ * Authors:
-+ * Sami Kivisaari <skivisaa@cc.hut.fi>
-+ * Antti Tuominen <ajtuomin@tml.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation; either version 2 of
-+ * the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/slab.h>
-+#include "hashlist.h"
-+#include "debug.h"
-+
-+struct hashlist {
-+ int count; /* entry count */
-+ int maxcount; /* max entries */
-+ __u32 bucketnum; /* hash buckets */
-+
-+ kmem_cache_t *kmem;
-+
-+ struct list_head *hashtable;
-+ struct list_head sortedlist;
-+
-+ int (*compare)(void *data, void *hashkey);
-+ __u32 (*hash_function)(void *hashkey);
-+};
-+
-+/**
-+ * hashlist_create - Create new hashlist
-+ * @bucketnum: number of hash buckets
-+ * @maxentries: maximum number of entries (0 = no limit)
-+ * @size: entry size in bytes
-+ * @name: name for kmem_cache_t
-+ * @ctor: kmem_cache_t constructor
-+ * @dtor: kmem_cache_t destructor
-+ * @compare: compare function for key
-+ * @hash_function: hash function
-+ *
-+ * Creates a hashlist structure with @max_entries entries of @size
-+ * bytes. User must supply @hash_function and @compare function for
-+ * the hashlist. User can also supply @ctor and @dtor for kmem_cache.
-+ **/
-+struct hashlist *hashlist_create(int bucketnum, int max_entries, size_t size,
-+ char *name,
-+ void (*ctor)(void *, kmem_cache_t *, unsigned long),
-+ void (*dtor)(void *, kmem_cache_t *, unsigned long),
-+ int (*compare)(void *data, void *hashkey),
-+ __u32 (*hash_function)(void *hashkey))
-+{
-+ int i;
-+ struct hashlist *hl;
-+
-+ if (!compare || !hash_function)
-+ goto hlfailed;
-+
-+ hl = kmalloc(sizeof(struct hashlist), GFP_ATOMIC);
-+ if (!hl) goto hlfailed;
-+
-+ hl->kmem = kmem_cache_create(name, size, 0, 0, ctor, dtor);
-+ if (!hl->kmem) goto poolfailed;
-+
-+ hl->hashtable = kmalloc(
-+ sizeof(struct list_head) * bucketnum, GFP_ATOMIC);
-+ if (!hl->hashtable) goto hashfailed;
-+
-+ for (i = 0; i < bucketnum; i++)
-+ INIT_LIST_HEAD(&hl->hashtable[i]);
-+
-+ INIT_LIST_HEAD(&hl->sortedlist);
-+
-+ hl->maxcount = max_entries;
-+ hl->count = 0;
-+ hl->bucketnum = bucketnum;
-+ hl->compare = compare;
-+ hl->hash_function = hash_function;
-+
-+ return hl;
-+
-+hashfailed:
-+ kmem_cache_destroy(hl->kmem);
-+ hl->kmem = NULL;
-+
-+poolfailed:
-+ kfree(hl);
-+
-+hlfailed:
-+ DEBUG(DBG_ERROR, "could not create hashlist");
-+
-+ return NULL;
-+}
-+
-+/**
-+ * hashlist_destroy - Destroy hashlist
-+ * @hashlist: hashlist to destroy
-+ *
-+ * Frees all memory allocated for a hashlist.
-+ **/
-+void hashlist_destroy(struct hashlist *hashlist)
-+{
-+ DEBUG_FUNC();
-+
-+ if (hashlist == NULL) return;
-+
-+ if (hashlist->hashtable) {
-+ kfree(hashlist->hashtable);
-+ hashlist->hashtable = NULL;
-+ }
-+
-+ if (hashlist->kmem) {
-+ kmem_cache_destroy(hashlist->kmem);
-+ hashlist->kmem = NULL;
-+ }
-+
-+ kfree(hashlist);
-+
-+ return;
-+}
-+
-+/*
-+ * Insert a chain of entries to hashlist into correct order. The
-+ * entries are assumed to have valid hashkeys. We use time_after_eq
-+ * for comparing, since it handles wrap-around correctly, and the
-+ * sortkey is usually jiffies.
-+ */
-+static void sorted_insert(struct list_head *lh, struct hashlist_entry *he)
-+{
-+ struct list_head *p;
-+ struct hashlist_entry *hlp = NULL;
-+ unsigned long sortkey = he->sortkey;
-+
-+ if (list_empty(lh)) {
-+ list_add(&he->sorted, lh);
-+ return;
-+ }
-+
-+ list_for_each(p, lh) {
-+ hlp = list_entry(p, typeof(*hlp), sorted);
-+ if (time_after_eq(hlp->sortkey, sortkey)) {
-+ list_add(&he->sorted, hlp->sorted.prev);
-+ return;
-+ }
-+ }
-+ list_add(&he->sorted, &hlp->sorted);
-+}
-+
-+/**
-+ * hashlist_iterate - Apply function for all elements in a hash list
-+ * @hashlist: pointer to hashlist
-+ * @args: data to pass to the function
-+ * @func: pointer to a function
-+ *
-+ * Apply arbitrary function @func to all elements in a hash list.
-+ * @func must be a pointer to a function with the following prototype:
-+ * int func(void *entry, void *arg, struct in6_addr *hashkey, unsigned
-+ * long *sortkey). Function must return %ITERATOR_STOP,
-+ * %ITERATOR_CONT or %ITERATOR_DELETE_ENTRY. %ITERATOR_STOP stops
-+ * iterator and returns last return value from the function.
-+ * %ITERATOR_CONT continues with iteration. %ITERATOR_DELETE_ENTRY
-+ * deletes current entry from the hashlist. If function changes
-+ * hashlist element's sortkey, iterator automatically schedules
-+ * element to be reinserted after all elements have been processed.
-+ */
-+int hashlist_iterate(
-+ struct hashlist *hashlist, void *args,
-+ hashlist_iterator_t func)
-+{
-+ int res = ITERATOR_CONT;
-+ unsigned long skey;
-+ struct list_head *p, *n, repos;
-+ struct hashlist_entry *he;
-+
-+ DEBUG_FUNC();
-+ INIT_LIST_HEAD(&repos);
-+
-+ list_for_each_safe(p, n, &hashlist->sortedlist) {
-+ he = list_entry(p, typeof(*he), sorted);
-+ if (res == ITERATOR_STOP)
-+ break;
-+ skey = he->sortkey;
-+ res = func(he, args, &he->sortkey);
-+ if (res == ITERATOR_DELETE_ENTRY) {
-+ hashlist_delete(hashlist, he);
-+ hashlist_free(hashlist, he);
-+ } else if (skey != he->sortkey) {
-+ /* iterator changed the sortkey, schedule for
-+ * repositioning */
-+ list_move(&he->sorted, &repos);
-+ }
-+ }
-+ list_for_each_safe(p, n, &repos) {
-+ he = list_entry(p, typeof(*he), sorted);
-+ sorted_insert(&hashlist->sortedlist, he);
-+ }
-+ return res;
-+}
-+
-+/**
-+ * hashlist_alloc - Allocate memory for a hashlist entry
-+ * @hashlist: hashlist for allocated entry
-+ * @size: size of entry in bytes
-+ *
-+ * Allocates @size bytes memory from @hashlist->kmem.
-+ **/
-+void *hashlist_alloc(struct hashlist *hashlist, int type)
-+{
-+ if (hashlist == NULL) return NULL;
-+ return kmem_cache_alloc(hashlist->kmem, type);
-+}
-+
-+/**
-+ * hashlist_free - Free hashlist entry
-+ * @hashlist: hashlist where @he is
-+ * @he: entry to free
-+ *
-+ * Frees an allocated hashlist entry.
-+ **/
-+void hashlist_free(struct hashlist *hashlist, struct hashlist_entry *he)
-+{
-+ kmem_cache_free(hashlist->kmem, he);
-+}
-+
-+/**
-+ * hashlist_add - Add element to hashlist
-+ * @hashlist: pointer to hashlist
-+ * @hashkey: hashkey for the element
-+ * @sortkey: key for sorting
-+ * @data: element data
-+ *
-+ * Add element to hashlist. Hashlist is also sorted in a linked list
-+ * by @sortkey.
-+ */
-+int hashlist_add(struct hashlist *hashlist, void *hashkey,
-+ unsigned long sortkey, void *entry)
-+{
-+ struct hashlist_entry *he = (struct hashlist_entry *)entry;
-+ unsigned int hash;
-+
-+ if (hashlist->count >= hashlist->maxcount)
-+ return -1;
-+
-+ hashlist->count++;
-+
-+ /* link the entry to sorted order */
-+ he->sortkey = sortkey;
-+ sorted_insert(&hashlist->sortedlist, he);
-+
-+ /* hash the entry */
-+ hash = hashlist->hash_function(hashkey) % hashlist->bucketnum;
-+ list_add(&he->hashlist, &hashlist->hashtable[hash]);
-+
-+ return 0;
-+}
-+
-+/**
-+ * hashlist_get_ex - Get element from hashlist
-+ * @hashlist: hashlist
-+ * @hashkey: hashkey of the desired entry
-+ *
-+ * Lookup entry with @hashkey from the hash table using @compare
-+ * function for entry comparison. Returns entry on success, otherwise
-+ * %NULL.
-+ **/
-+struct hashlist_entry *hashlist_get_ex(
-+ struct hashlist *hashlist, void *hashkey,
-+ int (*compare)(void *data, void *hashkey))
-+{
-+ struct list_head *p, *bkt;
-+ __u32 hash;
-+
-+ hash = hashlist->hash_function(hashkey) % hashlist->bucketnum;
-+ bkt = &hashlist->hashtable[hash];
-+
-+ /* scan the entries within the same hashbucket */
-+ list_for_each(p, bkt) {
-+ struct hashlist_entry *he = list_entry(p, typeof(*he),
-+ hashlist);
-+ if (compare(he, hashkey) == 0)
-+ return he;
-+ }
-+
-+ return NULL;
-+}
-+
-+/**
-+ * hashlist_get - Get element from hashlist
-+ * @hashlist: hashlist
-+ * @hashkey: hashkey of the desired entry
-+ *
-+ * Lookup entry with @hashkey from the hash table. Returns entry on
-+ * success, otherwise %NULL.
-+ **/
-+struct hashlist_entry *hashlist_get(struct hashlist *hashlist, void *hashkey)
-+{
-+ return hashlist_get_ex(hashlist, hashkey, hashlist->compare);
-+}
-+
-+/**
-+ * hashlist_reposition - set entry to new position in the list
-+ * @hashlist: hashlist
-+ * @he: entry to reposition
-+ * @sortkey: new sortkey of the entry
-+ *
-+ * If secondary order sortkey changes, entry must be repositioned in
-+ * the sorted list.
-+ **/
-+int hashlist_reposition(struct hashlist *hashlist, struct hashlist_entry *he,
-+ unsigned long sortkey)
-+{
-+ list_del(&he->sorted);
-+ he->sortkey = sortkey;
-+ sorted_insert(&hashlist->sortedlist, he);
-+
-+ return 0;
-+}
-+
-+/**
-+ * hashlist_delete - Delete entry from hashlist
-+ * @hashlist: hashlist where entry is
-+ * @he: entry to delete
-+ *
-+ * Deletes an entry from the hashlist and sorted list.
-+ **/
-+void hashlist_delete(struct hashlist *hashlist,
-+ struct hashlist_entry *he)
-+{
-+ list_del_init(&he->hashlist);
-+ list_del_init(&he->sorted);
-+
-+ hashlist->count--;
-+}
-+
-+/**
-+ * hashlist_get_first - Get first item from sorted list
-+ * @hashlist: pointer to hashlist
-+ *
-+ * Returns first item in the secondary sort order.
-+ **/
-+void * hashlist_get_first(struct hashlist *hashlist)
-+{
-+ if (list_empty(&hashlist->sortedlist))
-+ return NULL;
-+
-+ return list_entry(hashlist->sortedlist.next, struct hashlist_entry, sorted);
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/hashlist.h linux-2.4.25/net/ipv6/mobile_ip6/hashlist.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/hashlist.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/hashlist.h 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,63 @@
-+/*
-+ * MIPL Mobile IPv6 Hashlist header file
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef _HASHLIST_H
-+#define _HASHLIST_H
-+
-+#define ITERATOR_ERR -1
-+#define ITERATOR_CONT 0
-+#define ITERATOR_STOP 1
-+#define ITERATOR_DELETE_ENTRY 2
-+
-+struct kmem_cache_t;
-+
-+struct hashlist_entry {
-+ unsigned long sortkey;
-+ struct list_head sorted;
-+ struct list_head hashlist;
-+};
-+
-+struct hashlist * hashlist_create(
-+ int bucketnum, int max_entries, size_t size, char *name,
-+ void (*ctor)(void *, kmem_cache_t *, unsigned long),
-+ void (*dtor)(void *, kmem_cache_t *, unsigned long),
-+ int (*compare)(void *data, void *hashkey),
-+ __u32 (*hash_function)(void *hashkey));
-+
-+void hashlist_destroy(struct hashlist *hashlist);
-+
-+void *hashlist_alloc(struct hashlist *hashlist, int type);
-+
-+void hashlist_free(struct hashlist *hashlist, struct hashlist_entry *he);
-+
-+struct hashlist_entry *hashlist_get(struct hashlist *hashlist, void *hashkey);
-+
-+struct hashlist_entry *hashlist_get_ex(
-+ struct hashlist *hashlist, void *hashkey,
-+ int (*compare)(void *data, void *hashkey));
-+
-+int hashlist_add(struct hashlist *hashlist, void *hashkey,
-+ unsigned long sortkey, void *data);
-+
-+void hashlist_delete(struct hashlist *hashlist, struct hashlist_entry *he);
-+
-+/* iterator function */
-+typedef int (*hashlist_iterator_t)(void *, void *, unsigned long *);
-+
-+int hashlist_iterate(struct hashlist *hashlist, void *args,
-+ hashlist_iterator_t func);
-+
-+void * hashlist_get_first(struct hashlist *hashlist);
-+
-+int hashlist_reposition(struct hashlist *hashlist, struct hashlist_entry *he,
-+ unsigned long sortkey);
-+
-+#endif
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/hmac.c linux-2.4.25/net/ipv6/mobile_ip6/hmac.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/hmac.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/hmac.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,658 @@
-+/* Authentication algorithms
-+ *
-+ * Authors:
-+ * Alexis Olivereau <Alexis.Olivereau@crm.mot.com>
-+ *
-+ * $Id$
-+ *
-+ * 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.
-+ *
-+ * Changes:
-+ * Henrik Petander : Cleaned up unused parts
-+ *
-+ */
-+
-+#include <linux/sched.h>
-+#include <linux/tty.h>
-+#include <linux/types.h>
-+#include <linux/slab.h>
-+#include <linux/in6.h>
-+
-+#include "hmac.h"
-+#define LROLL(x, s) (((x) << (s)) | ((x) >> (32 - (s))))
-+
-+/* MD5 */
-+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
-+#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
-+#define H(x, y, z) ((x) ^ (y) ^ (z))
-+#define I(x, y, z) ((y) ^ ((x) | ~(z)))
-+
-+#define FF(a, b, c, d, m, s, t) { \
-+ (a) += F ((b), (c), (d)) + (m) + (t); \
-+ (a) = LROLL((a), (s)); \
-+ (a) += (b); \
-+ }
-+#define GG(a, b, c, d, m, s, t) { \
-+ (a) += G ((b), (c), (d)) + (m) + (t); \
-+ (a) = LROLL((a), (s)); \
-+ (a) += (b); \
-+ }
-+#define HH(a, b, c, d, m, s, t) { \
-+ (a) += H ((b), (c), (d)) + (m) + (t); \
-+ (a) = LROLL((a), (s)); \
-+ (a) += (b); \
-+ }
-+#define II(a, b, c, d, m, s, t) { \
-+ (a) += I ((b), (c), (d)) + (m) + (t); \
-+ (a) = LROLL((a), (s)); \
-+ (a) += (b); \
-+ }
-+
-+#define s11 7
-+#define s12 12
-+#define s13 17
-+#define s14 22
-+#define s21 5
-+#define s22 9
-+#define s23 14
-+#define s24 20
-+#define s31 4
-+#define s32 11
-+#define s33 16
-+#define s34 23
-+#define s41 6
-+#define s42 10
-+#define s43 15
-+#define s44 21
-+
-+/* SHA-1 */
-+#define f(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
-+#define g(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
-+#define h(x, y, z) ((x) ^ (y) ^ (z))
-+
-+#define K1 0x5a827999
-+#define K2 0x6ed9eba1
-+#define K3 0x8f1bbcdc
-+#define K4 0xca62c1d6
-+
-+int ah_hmac_md5_init(struct ah_processing *ahp, u_int8_t *key, u_int32_t key_len)
-+{
-+ int i;
-+ int key_up4;
-+ uint32_t ipad = 0x36363636;
-+ uint8_t extkey[64];
-+
-+ ahp->key_auth = key;
-+ ahp->key_auth_len = key_len;
-+ ahp->context = (void *) kmalloc(sizeof(MD5_CTX), GFP_ATOMIC);
-+ if (ahp->context == NULL)
-+ return -1;
-+ md5_init((MD5_CTX *) ahp->context);
-+ if ((64 * sizeof(uint8_t)) < ahp->key_auth_len) {
-+ printk("buffer overflow!");
-+ return -1;
-+ }
-+ memcpy(extkey, ahp->key_auth, ahp->key_auth_len);
-+ if (ahp->key_auth_len % 4) {
-+ memset(extkey + ahp->key_auth_len, 0,
-+ 4 - (ahp->key_auth_len % 4));
-+ }
-+ key_up4 = ((ahp->key_auth_len + 0x3) & 0xFFFFFFFC) / 4;
-+
-+ for (i = 0; i < key_up4; i++)
-+ ((uint32_t *) extkey)[i] = ((uint32_t *) extkey)[i] ^ ipad;
-+ for (i = key_up4; i < 16; i++)
-+ ((uint32_t *) extkey)[i] = ipad;
-+
-+ md5_compute((MD5_CTX *) ahp->context, extkey, 64);
-+ return 0;
-+}
-+
-+void ah_hmac_md5_loop(struct ah_processing *ahp, void *str, uint32_t len)
-+{
-+ md5_compute((MD5_CTX *) ahp->context, str, len);
-+}
-+
-+void ah_hmac_md5_result(struct ah_processing *ahp, char *digest)
-+{
-+ uint8_t inner[HMAC_MD5_HASH_LEN];
-+ int i;
-+ int key_up4;
-+ uint32_t opad = 0x5c5c5c5c;
-+ uint8_t extkey[64];
-+
-+ md5_final((MD5_CTX *) ahp->context, inner);
-+ md5_init((MD5_CTX *) ahp->context);
-+
-+ memcpy(extkey, ahp->key_auth, ahp->key_auth_len);
-+ if (ahp->key_auth_len % 4) {
-+ memset(extkey + ahp->key_auth_len, 0,
-+ 4 - (ahp->key_auth_len % 4));
-+ }
-+ key_up4 = ((ahp->key_auth_len + 0x3) & 0xFFFFFFFC) / 4;
-+
-+ for (i = 0; i < key_up4; i++)
-+ ((uint32_t *) extkey)[i] = ((uint32_t *) extkey)[i] ^ opad;
-+ for (i = key_up4; i < 16; i++)
-+ ((uint32_t *) extkey)[i] = opad;
-+
-+ md5_compute((MD5_CTX *) ahp->context, extkey, 64);
-+ md5_compute((MD5_CTX *) ahp->context, inner, HMAC_MD5_HASH_LEN);
-+
-+ md5_final((MD5_CTX *) ahp->context, digest);
-+
-+ kfree(ahp->context);
-+}
-+
-+int ah_hmac_sha1_init(struct ah_processing *ahp, u_int8_t *key, u_int32_t key_len)
-+{
-+ int i;
-+ int key_up4;
-+ uint32_t ipad = 0x36363636;
-+ uint8_t extkey[64];
-+
-+ ahp->key_auth = key;
-+ ahp->key_auth_len = key_len;
-+
-+ ahp->context = (void *) kmalloc(sizeof(SHA1_CTX), GFP_ATOMIC);
-+ //if (ahp->context == NULL)
-+ // return -1;
-+
-+ sha1_init((SHA1_CTX *) ahp->context);
-+
-+ memcpy(extkey, ahp->key_auth, ahp->key_auth_len);
-+ if (ahp->key_auth_len % 4) {
-+ memset(extkey + ahp->key_auth_len, 0,
-+ 4 - (ahp->key_auth_len % 4));
-+ }
-+ key_up4 = ((ahp->key_auth_len + 0x3) & 0xFFFFFFFC) / 4;
-+
-+ for (i = 0; i < key_up4; i++)
-+ ((uint32_t *) extkey)[i] = ((uint32_t *) extkey)[i] ^ ipad;
-+ for (i = key_up4; i < 16; i++)
-+ ((uint32_t *) extkey)[i] = ipad;
-+
-+ sha1_compute((SHA1_CTX *) ahp->context, extkey, 64);
-+ return 0;
-+}
-+
-+void ah_hmac_sha1_loop(struct ah_processing *ahp, void *str, uint32_t len)
-+{
-+ if (!ahp)
-+ return;
-+ sha1_compute((SHA1_CTX *) ahp->context, str, len);
-+}
-+
-+void ah_hmac_sha1_result(struct ah_processing *ahp, char *digest)
-+{
-+ uint8_t inner[HMAC_SHA1_HASH_LEN];
-+ int i;
-+ int key_up4;
-+ uint32_t opad = 0x5c5c5c5c;
-+ uint8_t extkey[64];
-+
-+ if (!ahp)
-+ return;
-+ sha1_final((SHA1_CTX *) ahp->context, inner);
-+ sha1_init((SHA1_CTX *) ahp->context);
-+
-+ memcpy(extkey, ahp->key_auth, ahp->key_auth_len);
-+ if (ahp->key_auth_len % 4) {
-+ memset(extkey + ahp->key_auth_len, 0,
-+ 4 - (ahp->key_auth_len % 4));
-+ }
-+ key_up4 = ((ahp->key_auth_len + 0x3) & 0xFFFFFFFC) / 4;
-+
-+ for (i = 0; i < key_up4; i++)
-+ ((uint32_t *) extkey)[i] = ((uint32_t *) extkey)[i] ^ opad;
-+ for (i = key_up4; i < 16; i++)
-+ ((uint32_t *) extkey)[i] = opad;
-+
-+ sha1_compute((SHA1_CTX *) ahp->context, extkey, 64);
-+ sha1_compute((SHA1_CTX *) ahp->context, inner,
-+ HMAC_SHA1_HASH_LEN);
-+
-+ sha1_final((SHA1_CTX *) ahp->context, digest);
-+
-+ kfree(ahp->context);
-+}
-+
-+void md5_init(MD5_CTX * ctx)
-+{
-+ ctx->A = 0x67452301;
-+ ctx->B = 0xefcdab89;
-+ ctx->C = 0x98badcfe;
-+ ctx->D = 0x10325476;
-+ ctx->buf_cur = ctx->buf;
-+ ctx->bitlen[0] = ctx->bitlen[1] = 0;
-+ memset(ctx->buf, 0, 64);
-+}
-+
-+void md5_over_block(MD5_CTX * ctx, uint8_t * data)
-+{
-+ uint32_t M[16];
-+ uint32_t a = ctx->A;
-+ uint32_t b = ctx->B;
-+ uint32_t c = ctx->C;
-+ uint32_t d = ctx->D;
-+
-+ create_M_blocks(M, data);
-+
-+ /* Round 1 */
-+ FF(a, b, c, d, M[0], s11, 0xd76aa478); /* 1 */
-+ FF(d, a, b, c, M[1], s12, 0xe8c7b756); /* 2 */
-+ FF(c, d, a, b, M[2], s13, 0x242070db); /* 3 */
-+ FF(b, c, d, a, M[3], s14, 0xc1bdceee); /* 4 */
-+ FF(a, b, c, d, M[4], s11, 0xf57c0faf); /* 5 */
-+ FF(d, a, b, c, M[5], s12, 0x4787c62a); /* 6 */
-+ FF(c, d, a, b, M[6], s13, 0xa8304613); /* 7 */
-+ FF(b, c, d, a, M[7], s14, 0xfd469501); /* 8 */
-+ FF(a, b, c, d, M[8], s11, 0x698098d8); /* 9 */
-+ FF(d, a, b, c, M[9], s12, 0x8b44f7af); /* 10 */
-+ FF(c, d, a, b, M[10], s13, 0xffff5bb1); /* 11 */
-+ FF(b, c, d, a, M[11], s14, 0x895cd7be); /* 12 */
-+ FF(a, b, c, d, M[12], s11, 0x6b901122); /* 13 */
-+ FF(d, a, b, c, M[13], s12, 0xfd987193); /* 14 */
-+ FF(c, d, a, b, M[14], s13, 0xa679438e); /* 15 */
-+ FF(b, c, d, a, M[15], s14, 0x49b40821); /* 16 */
-+
-+ /* Round 2 */
-+ GG(a, b, c, d, M[1], s21, 0xf61e2562); /* 17 */
-+ GG(d, a, b, c, M[6], s22, 0xc040b340); /* 18 */
-+ GG(c, d, a, b, M[11], s23, 0x265e5a51); /* 19 */
-+ GG(b, c, d, a, M[0], s24, 0xe9b6c7aa); /* 20 */
-+ GG(a, b, c, d, M[5], s21, 0xd62f105d); /* 21 */
-+ GG(d, a, b, c, M[10], s22, 0x02441453); /* 22 */
-+ GG(c, d, a, b, M[15], s23, 0xd8a1e681); /* 23 */
-+ GG(b, c, d, a, M[4], s24, 0xe7d3fbc8); /* 24 */
-+ GG(a, b, c, d, M[9], s21, 0x21e1cde6); /* 25 */
-+ GG(d, a, b, c, M[14], s22, 0xc33707d6); /* 26 */
-+ GG(c, d, a, b, M[3], s23, 0xf4d50d87); /* 27 */
-+ GG(b, c, d, a, M[8], s24, 0x455a14ed); /* 28 */
-+ GG(a, b, c, d, M[13], s21, 0xa9e3e905); /* 29 */
-+ GG(d, a, b, c, M[2], s22, 0xfcefa3f8); /* 30 */
-+ GG(c, d, a, b, M[7], s23, 0x676f02d9); /* 31 */
-+ GG(b, c, d, a, M[12], s24, 0x8d2a4c8a); /* 32 */
-+
-+ /* Round 3 */
-+ HH(a, b, c, d, M[5], s31, 0xfffa3942); /* 33 */
-+ HH(d, a, b, c, M[8], s32, 0x8771f681); /* 34 */
-+ HH(c, d, a, b, M[11], s33, 0x6d9d6122); /* 35 */
-+ HH(b, c, d, a, M[14], s34, 0xfde5380c); /* 36 */
-+ HH(a, b, c, d, M[1], s31, 0xa4beea44); /* 37 */
-+ HH(d, a, b, c, M[4], s32, 0x4bdecfa9); /* 38 */
-+ HH(c, d, a, b, M[7], s33, 0xf6bb4b60); /* 39 */
-+ HH(b, c, d, a, M[10], s34, 0xbebfbc70); /* 40 */
-+ HH(a, b, c, d, M[13], s31, 0x289b7ec6); /* 41 */
-+ HH(d, a, b, c, M[0], s32, 0xeaa127fa); /* 42 */
-+ HH(c, d, a, b, M[3], s33, 0xd4ef3085); /* 43 */
-+ HH(b, c, d, a, M[6], s34, 0x4881d05); /* 44 */
-+ HH(a, b, c, d, M[9], s31, 0xd9d4d039); /* 45 */
-+ HH(d, a, b, c, M[12], s32, 0xe6db99e5); /* 46 */
-+ HH(c, d, a, b, M[15], s33, 0x1fa27cf8); /* 47 */
-+ HH(b, c, d, a, M[2], s34, 0xc4ac5665); /* 48 */
-+
-+ /* Round 4 */
-+ II(a, b, c, d, M[0], s41, 0xf4292244); /* 49 */
-+ II(d, a, b, c, M[7], s42, 0x432aff97); /* 50 */
-+ II(c, d, a, b, M[14], s43, 0xab9423a7); /* 51 */
-+ II(b, c, d, a, M[5], s44, 0xfc93a039); /* 52 */
-+ II(a, b, c, d, M[12], s41, 0x655b59c3); /* 53 */
-+ II(d, a, b, c, M[3], s42, 0x8f0ccc92); /* 54 */
-+ II(c, d, a, b, M[10], s43, 0xffeff47d); /* 55 */
-+ II(b, c, d, a, M[1], s44, 0x85845dd1); /* 56 */
-+ II(a, b, c, d, M[8], s41, 0x6fa87e4f); /* 57 */
-+ II(d, a, b, c, M[15], s42, 0xfe2ce6e0); /* 58 */
-+ II(c, d, a, b, M[6], s43, 0xa3014314); /* 59 */
-+ II(b, c, d, a, M[13], s44, 0x4e0811a1); /* 60 */
-+ II(a, b, c, d, M[4], s41, 0xf7537e82); /* 61 */
-+ II(d, a, b, c, M[11], s42, 0xbd3af235); /* 62 */
-+ II(c, d, a, b, M[2], s43, 0x2ad7d2bb); /* 63 */
-+ II(b, c, d, a, M[9], s44, 0xeb86d391); /* 64 */
-+
-+ ctx->A += a;
-+ ctx->B += b;
-+ ctx->C += c;
-+ ctx->D += d;
-+}
-+
-+void create_M_blocks(uint32_t * M, uint8_t * data)
-+{
-+#ifdef HAVE_LITTLE_ENDIAN
-+ memcpy((uint8_t *) M, data, 64);
-+#endif /* HAVE_LITTLE_ENDIAN */
-+
-+#ifdef HAVE_BIG_ENDIAN
-+ int i;
-+ for (i = 0; i < 16; i++, data += 4) {
-+ ((uint8_t *) (&M[i]))[0] = data[3];
-+ ((uint8_t *) (&M[i]))[1] = data[2];
-+ ((uint8_t *) (&M[i]))[2] = data[1];
-+ ((uint8_t *) (&M[i]))[3] = data[0];
-+ }
-+#endif /* HAVE_BIG_ENDIAN */
-+}
-+
-+void md5_compute(MD5_CTX * ctx, uint8_t * data, uint32_t len)
-+{
-+ uint8_t pos = ((ctx->bitlen[0] >> 3) & 0x3f);
-+
-+ /* First we update the bit length */
-+ if ((ctx->bitlen[0] += (len << 3)) < (len << 3))
-+ ctx->bitlen[1]++;
-+ ctx->bitlen[1] += (len >> 29); /* len is expressed in bytes */
-+
-+ if (pos) {
-+ /* Buffer is not empty */
-+ if (64 - pos >= len) {
-+ memcpy(ctx->buf_cur, data, len);
-+ ctx->buf_cur += len;
-+ pos += len;
-+ if (pos == 64) {
-+ /* The current block is over */
-+ md5_over_block(ctx, ctx->buf);
-+ ctx->buf_cur = ctx->buf;
-+ }
-+ return;
-+ } else {
-+ memcpy(ctx->buf_cur, data, 64 - pos);
-+ md5_over_block(ctx, ctx->buf);
-+ len -= (64 - pos);
-+ data += (64 - pos);
-+ ctx->buf_cur = ctx->buf;
-+ }
-+ }
-+ while (len >= 64) {
-+ md5_over_block(ctx, data);
-+ len -= 64;
-+ data += 64;
-+ }
-+ if (len) {
-+ memcpy(ctx->buf_cur, data, len);
-+ ctx->buf_cur += len;
-+ }
-+}
-+
-+void md5_final(MD5_CTX * ctx, uint8_t * digest)
-+{
-+ uint32_t rem_size;
-+ uint8_t *buf_cur = ctx->buf_cur;
-+ int i;
-+
-+ rem_size = 64 - ((ctx->bitlen[0] >> 3) & 0x3f);
-+ *(buf_cur++) = 0x80;
-+
-+ if (rem_size > 8 + 1) {
-+ /* We have enough room in the current block */
-+ for (i = 0; i < rem_size - 8 - 1; i++) {
-+ *(buf_cur++) = 0;
-+ }
-+ } else {
-+ /* We do not have enough room and need therefore to add a new
-+ 64-byte block */
-+ for (i = 0; i < rem_size - 1; i++) {
-+ *(buf_cur++) = 0;
-+ }
-+ md5_over_block(ctx, ctx->buf);
-+
-+ buf_cur = ctx->buf;
-+ for (i = 0; i < 64 - 8; i++) {
-+ *(buf_cur++) = 0;
-+ }
-+ }
-+#ifdef HAVE_LITTLE_ENDIAN
-+ memcpy(buf_cur, (uint8_t *) ctx->bitlen, 8);
-+#endif /* HAVE_LITTLE_ENDIAN */
-+
-+#ifdef HAVE_BIG_ENDIAN
-+ *(buf_cur++) = (ctx->bitlen[0] >> 24) & 0xff;
-+ *(buf_cur++) = (ctx->bitlen[0] >> 16) & 0xff;
-+ *(buf_cur++) = (ctx->bitlen[0] >> 8) & 0xff;
-+ *(buf_cur++) = (ctx->bitlen[0] >> 0) & 0xff;
-+ *(buf_cur++) = (ctx->bitlen[1] >> 24) & 0xff;
-+ *(buf_cur++) = (ctx->bitlen[1] >> 16) & 0xff;
-+ *(buf_cur++) = (ctx->bitlen[1] >> 8) & 0xff;
-+ *(buf_cur++) = (ctx->bitlen[1] >> 0) & 0xff;
-+#endif /* HAVE_BIG_ENDIAN */
-+
-+ md5_over_block(ctx, ctx->buf);
-+
-+#ifdef HAVE_LITTLE_ENDIAN
-+ memcpy(digest + 0, (uint8_t *) (&(ctx->A)), sizeof(uint32_t));
-+ memcpy(digest + 4, (uint8_t *) (&(ctx->B)), sizeof(uint32_t));
-+ memcpy(digest + 8, (uint8_t *) (&(ctx->C)), sizeof(uint32_t));
-+ memcpy(digest + 12, (uint8_t *) (&(ctx->D)), sizeof(uint32_t));
-+#endif /* HAVE_LITTLE_ENDIAN */
-+
-+#ifdef HAVE_BIG_ENDIAN
-+ digest[0] = ((ctx->A) >> 24) & 0xff;
-+ digest[1] = ((ctx->A) >> 16) & 0xff;
-+ digest[2] = ((ctx->A) >> 8) & 0xff;
-+ digest[3] = ((ctx->A) >> 0) & 0xff;
-+ digest[4] = ((ctx->B) >> 24) & 0xff;
-+ digest[5] = ((ctx->B) >> 16) & 0xff;
-+ digest[6] = ((ctx->B) >> 8) & 0xff;
-+ digest[7] = ((ctx->B) >> 0) & 0xff;
-+ digest[8] = ((ctx->C) >> 24) & 0xff;
-+ digest[9] = ((ctx->C) >> 16) & 0xff;
-+ digest[10] = ((ctx->C) >> 8) & 0xff;
-+ digest[11] = ((ctx->C) >> 0) & 0xff;
-+ digest[12] = ((ctx->D) >> 24) & 0xff;
-+ digest[13] = ((ctx->D) >> 16) & 0xff;
-+ digest[14] = ((ctx->D) >> 8) & 0xff;
-+ digest[15] = ((ctx->D) >> 0) & 0xff;
-+#endif /* HAVE_BIG_ENDIAN */
-+}
-+
-+void sha1_init(SHA1_CTX * ctx)
-+{
-+ ctx->A = 0x67452301;
-+ ctx->B = 0xefcdab89;
-+ ctx->C = 0x98badcfe;
-+ ctx->D = 0x10325476;
-+ ctx->E = 0xc3d2e1f0;
-+ ctx->buf_cur = ctx->buf;
-+ ctx->bitlen[0] = ctx->bitlen[1] = 0;
-+ memset(ctx->buf, 0, 64);
-+}
-+
-+void sha1_over_block(SHA1_CTX * ctx, uint8_t * data)
-+{
-+ int i;
-+ uint32_t W[80];
-+ uint32_t a = ctx->A;
-+ uint32_t b = ctx->B;
-+ uint32_t c = ctx->C;
-+ uint32_t d = ctx->D;
-+ uint32_t e = ctx->E;
-+ uint32_t temp;
-+
-+ create_W_blocks(W, data);
-+
-+ /* Round 1 */
-+ for (i = 0; i < 20; i++) {
-+ temp = LROLL(a, 5) + f(b, c, d) + e + W[i] + K1;
-+ e = d;
-+ d = c;
-+ c = LROLL(b, 30);
-+ b = a;
-+ a = temp;
-+ }
-+
-+ /* Round 2 */
-+ for (i = 20; i < 40; i++) {
-+ temp = LROLL(a, 5) + h(b, c, d) + e + W[i] + K2;
-+ e = d;
-+ d = c;
-+ c = LROLL(b, 30);
-+ b = a;
-+ a = temp;
-+ }
-+
-+ /* Round 3 */
-+ for (i = 40; i < 60; i++) {
-+ temp = LROLL(a, 5) + g(b, c, d) + e + W[i] + K3;
-+ e = d;
-+ d = c;
-+ c = LROLL(b, 30);
-+ b = a;
-+ a = temp;
-+ }
-+
-+ /* Round 4 */
-+ for (i = 60; i < 80; i++) {
-+ temp = LROLL(a, 5) + h(b, c, d) + e + W[i] + K4;
-+ e = d;
-+ d = c;
-+ c = LROLL(b, 30);
-+ b = a;
-+ a = temp;
-+ }
-+
-+ ctx->A += a;
-+ ctx->B += b;
-+ ctx->C += c;
-+ ctx->D += d;
-+ ctx->E += e;
-+}
-+
-+void create_W_blocks(uint32_t * W, uint8_t * data)
-+{
-+ int i;
-+
-+#ifdef HAVE_BIG_ENDIAN
-+ memcpy((uint8_t *) W, data, 64);
-+#endif /* HAVE_BIG_ENDIAN */
-+
-+#ifdef HAVE_LITTLE_ENDIAN
-+ for (i = 0; i < 16; i++, data += 4) {
-+ ((uint8_t *) (&W[i]))[0] = data[3];
-+ ((uint8_t *) (&W[i]))[1] = data[2];
-+ ((uint8_t *) (&W[i]))[2] = data[1];
-+ ((uint8_t *) (&W[i]))[3] = data[0];
-+ }
-+#endif /* HAVE_LITTLE_ENDIAN */
-+ for (i = 16; i < 80; i++) {
-+ W[i] = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
-+ W[i] = LROLL(W[i], 1);
-+ }
-+}
-+
-+void sha1_compute(SHA1_CTX * ctx, uint8_t * data, uint32_t len)
-+{
-+ uint8_t pos = ((ctx->bitlen[0] >> 3) & 0x3f);
-+
-+ /* First we update the bit length */
-+ if ((ctx->bitlen[0] += (len << 3)) < (len << 3))
-+ ctx->bitlen[1]++;
-+ ctx->bitlen[1] += (len >> 29); /* len is expressed in bytes */
-+
-+ if (pos) {
-+ /* Buffer is not empty */
-+ if (64 - pos >= len) {
-+ memcpy(ctx->buf_cur, data, len);
-+ ctx->buf_cur += len;
-+ pos += len;
-+ if (pos == 64) {
-+ /* The current block is over */
-+ sha1_over_block(ctx, ctx->buf);
-+ ctx->buf_cur = ctx->buf;
-+ }
-+ return;
-+ } else {
-+ memcpy(ctx->buf_cur, data, 64 - pos);
-+ sha1_over_block(ctx, ctx->buf);
-+ len -= (64 - pos);
-+ data += (64 - pos);
-+ ctx->buf_cur = ctx->buf;
-+ }
-+ }
-+ while (len >= 64) {
-+ sha1_over_block(ctx, data);
-+ len -= 64;
-+ data += 64;
-+ }
-+ if (len) {
-+ memcpy(ctx->buf_cur, data, len);
-+ ctx->buf_cur += len;
-+ }
-+}
-+
-+void sha1_final(SHA1_CTX * ctx, uint8_t * digest)
-+{
-+ uint32_t rem_size;
-+ uint8_t *buf_cur = ctx->buf_cur;
-+ int i;
-+
-+ rem_size = 64 - ((ctx->bitlen[0] >> 3) & 0x3f);
-+ *(buf_cur++) = 0x80;
-+
-+ if (rem_size > 8 + 1) {
-+ /* We have enough room in the current block */
-+ for (i = 0; i < rem_size - 8 - 1; i++) {
-+ *(buf_cur++) = 0;
-+ }
-+ } else {
-+ /* We do not have enough room and need therefore to add a new
-+ 64-byte block */
-+ for (i = 0; i < rem_size - 1; i++) {
-+ *(buf_cur++) = 0;
-+ }
-+ sha1_over_block(ctx, ctx->buf);
-+
-+ buf_cur = ctx->buf;
-+ for (i = 0; i < 64 - 8; i++) {
-+ *(buf_cur++) = 0;
-+ }
-+ }
-+#ifdef HAVE_BIG_ENDIAN
-+ memcpy(buf_cur, (uint8_t *) ctx->bitlen, 8);
-+#endif /* HAVE_BIG_ENDIAN */
-+
-+#ifdef HAVE_LITTLE_ENDIAN
-+ *(buf_cur++) = (ctx->bitlen[1] >> 24) & 0xff;
-+ *(buf_cur++) = (ctx->bitlen[1] >> 16) & 0xff;
-+ *(buf_cur++) = (ctx->bitlen[1] >> 8) & 0xff;
-+ *(buf_cur++) = (ctx->bitlen[1] >> 0) & 0xff;
-+ *(buf_cur++) = (ctx->bitlen[0] >> 24) & 0xff;
-+ *(buf_cur++) = (ctx->bitlen[0] >> 16) & 0xff;
-+ *(buf_cur++) = (ctx->bitlen[0] >> 8) & 0xff;
-+ *(buf_cur++) = (ctx->bitlen[0] >> 0) & 0xff;
-+#endif /* HAVE_LITTLE_ENDIAN */
-+
-+ sha1_over_block(ctx, ctx->buf);
-+
-+#ifdef HAVE_BIG_ENDIAN
-+ memcpy(digest + 0, (uint8_t *) (&(ctx->A)), sizeof(uint32_t));
-+ memcpy(digest + 4, (uint8_t *) (&(ctx->B)), sizeof(uint32_t));
-+ memcpy(digest + 8, (uint8_t *) (&(ctx->C)), sizeof(uint32_t));
-+ memcpy(digest + 12, (uint8_t *) (&(ctx->D)), sizeof(uint32_t));
-+ memcpy(digest + 16, (uint8_t *) (&(ctx->E)), sizeof(uint32_t));
-+#endif /* HAVE_BIG_ENDIAN */
-+
-+#ifdef HAVE_LITTLE_ENDIAN
-+ digest[0] = ((ctx->A) >> 24) & 0xff;
-+ digest[1] = ((ctx->A) >> 16) & 0xff;
-+ digest[2] = ((ctx->A) >> 8) & 0xff;
-+ digest[3] = ((ctx->A) >> 0) & 0xff;
-+ digest[4] = ((ctx->B) >> 24) & 0xff;
-+ digest[5] = ((ctx->B) >> 16) & 0xff;
-+ digest[6] = ((ctx->B) >> 8) & 0xff;
-+ digest[7] = ((ctx->B) >> 0) & 0xff;
-+ digest[8] = ((ctx->C) >> 24) & 0xff;
-+ digest[9] = ((ctx->C) >> 16) & 0xff;
-+ digest[10] = ((ctx->C) >> 8) & 0xff;
-+ digest[11] = ((ctx->C) >> 0) & 0xff;
-+ digest[12] = ((ctx->D) >> 24) & 0xff;
-+ digest[13] = ((ctx->D) >> 16) & 0xff;
-+ digest[14] = ((ctx->D) >> 8) & 0xff;
-+ digest[15] = ((ctx->D) >> 0) & 0xff;
-+ digest[16] = ((ctx->E) >> 24) & 0xff;
-+ digest[17] = ((ctx->E) >> 16) & 0xff;
-+ digest[18] = ((ctx->E) >> 8) & 0xff;
-+ digest[19] = ((ctx->E) >> 0) & 0xff;
-+#endif /* HAVE_LITTLE_ENDIAN */
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/hmac.h linux-2.4.25/net/ipv6/mobile_ip6/hmac.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/hmac.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/hmac.h 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,94 @@
-+/*
-+ * MIPL Mobile IPv6 Message authentication algorithms
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef _HMAC_H
-+#define _HMAC_H
-+
-+#include <linux/types.h>
-+#include <linux/in6.h>
-+
-+#define HAVE_LITTLE_ENDIAN
-+
-+#define NO_EXPIRY 1 /* For sec_as */
-+
-+#define ALG_AUTH_NONE 0
-+#define ALG_AUTH_HMAC_MD5 1
-+#define ALG_AUTH_HMAC_SHA1 2
-+
-+struct sec_as;
-+struct ah_processing {
-+ void *context;
-+ struct sec_as *sas;
-+ u_int8_t *key_auth;
-+ u_int32_t key_auth_len;
-+};
-+
-+struct antireplay {
-+ u_int32_t count;
-+ u_int32_t bitmap;
-+};
-+
-+typedef struct {
-+ u_int32_t A, B, C, D;
-+ u_int32_t bitlen[2];
-+ u_int8_t* buf_cur;
-+ u_int8_t buf[64];
-+} MD5_CTX;
-+
-+typedef struct {
-+ u_int32_t A, B, C, D, E;
-+ u_int32_t bitlen[2];
-+ u_int8_t* buf_cur;
-+ u_int8_t buf[64];
-+} SHA1_CTX;
-+
-+
-+
-+int ah_hmac_md5_init (struct ah_processing *ahp, u_int8_t *key, u_int32_t key_len);
-+void ah_hmac_md5_loop(struct ah_processing*, void*, u_int32_t);
-+void ah_hmac_md5_result(struct ah_processing*, char*);
-+int ah_hmac_sha1_init(struct ah_processing*, u_int8_t *key, u_int32_t key_len);
-+void ah_hmac_sha1_loop(struct ah_processing*, void*, u_int32_t);
-+void ah_hmac_sha1_result(struct ah_processing*, char*);
-+
-+
-+#define AH_HDR_LEN 12 /* # of bytes for Next Header, Payload Length,
-+ RESERVED, Security Parameters Index and
-+
-+ Sequence Number Field */
-+
-+void md5_init(MD5_CTX *ctx);
-+void md5_over_block(MD5_CTX *ctx, u_int8_t* data);
-+void create_M_blocks(u_int32_t* M, u_int8_t* data);
-+void md5_compute(MD5_CTX *ctx, u_int8_t* data, u_int32_t len);
-+void md5_final(MD5_CTX *ctx, u_int8_t* digest);
-+
-+void sha1_init(SHA1_CTX *ctx);
-+void sha1_over_block(SHA1_CTX *ctx, u_int8_t* data);
-+void create_W_blocks(u_int32_t* W, u_int8_t* data);
-+void sha1_compute(SHA1_CTX *ctx, u_int8_t* data, u_int32_t len);
-+void sha1_final(SHA1_CTX *ctx, u_int8_t* digest);
-+
-+struct mipv6_acq {
-+ struct in6_addr coa;
-+ struct in6_addr haddr;
-+ struct in6_addr peer;
-+ u_int32_t spi;
-+};
-+#define MIPV6_MAX_AUTH_DATA 20
-+
-+#define HMAC_MD5_HASH_LEN 16
-+#define HMAC_SHA1_HASH_LEN 20
-+#define HMAC_SHA1_KEY_SIZE 20
-+#define HMAC_MD5_ICV_LEN 12 /* RFC 2403 */
-+#define HMAC_SHA1_ICV_LEN 12 /* RFC 2404 */
-+
-+#endif /* _HMAC_H */
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/ioctl_mn.c linux-2.4.25/net/ipv6/mobile_ip6/ioctl_mn.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/ioctl_mn.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/ioctl_mn.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,142 @@
-+/*
-+ * Mobile Node IOCTL Control device
-+ *
-+ * Authors:
-+ * Henrik Petander <lpetande@tml.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/fs.h>
-+#include <linux/poll.h>
-+#include <linux/ioctl.h>
-+#include <net/ipv6.h>
-+#include <asm/uaccess.h>
-+
-+#include "debug.h"
-+#include "mdetect.h"
-+#include "multiaccess_ctl.h"
-+
-+/* Reserved for local / experimental use */
-+#define MAJOR_NUM 0xf9
-+
-+/* Get Care-of address information for Mobile Node */
-+#define IOCTL_GET_CAREOFADDR _IOWR(MAJOR_NUM, 9, void *)
-+
-+#define MA_IOCTL_SET_IFACE_PREFERENCE _IOR (MAJOR_NUM, 13, void *)
-+
-+/* The name of the device file */
-+#define CTLFILE "mipv6_dev"
-+
-+static int inuse = 0;
-+
-+static int mipv6_open(struct inode *inode, struct file *file)
-+{
-+ DEBUG(DBG_INFO, "(%p)\n", file);
-+
-+ if (inuse)
-+ return -EBUSY;
-+
-+ inuse++;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ return 0;
-+}
-+
-+static int mipv6_close(struct inode *inode, struct file *file)
-+{
-+ DEBUG(DBG_INFO, "(%p,%p)\n", inode, file);
-+ inuse--;
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ return 0;
-+}
-+
-+int mipv6_ioctl(struct inode *inode, struct file *file,
-+ unsigned int ioctl_num, /* The number of the ioctl */
-+ unsigned long arg) /* The parameter to it */
-+{
-+ struct in6_addr careofaddr;
-+
-+ /* Switch according to the ioctl called */
-+ switch (ioctl_num) {
-+ case IOCTL_GET_CAREOFADDR:
-+ DEBUG(DBG_DATADUMP, "IOCTL_GET_CAREOFADDR");
-+ /* First get home address from user and then look up
-+ * the care-of address and return it
-+ */
-+ if (copy_from_user(&careofaddr, (struct in6_addr *)arg,
-+ sizeof(struct in6_addr)) < 0) {
-+ DEBUG(DBG_WARNING, "Copy from user failed");
-+ return -EFAULT;
-+ }
-+ mipv6_get_care_of_address(&careofaddr, &careofaddr);
-+ if (copy_to_user((struct in6_addr *)arg, &careofaddr,
-+ sizeof(struct in6_addr)) < 0) {
-+ DEBUG(DBG_WARNING, "copy_to_user failed");
-+ return -EFAULT;
-+ }
-+ break;
-+ case MA_IOCTL_SET_IFACE_PREFERENCE:
-+ DEBUG(DBG_INFO, "MA_IOCTL_SET_IFACE_PREFERENCE");
-+ ma_ctl_set_preference(arg);
-+ break;
-+
-+ default:
-+ DEBUG(DBG_WARNING, "Unknown ioctl cmd (%d)", ioctl_num);
-+ return -ENOENT;
-+ }
-+ return 0;
-+}
-+
-+struct file_operations Fops = {
-+ owner: THIS_MODULE,
-+ read: NULL,
-+ write: NULL,
-+ poll: NULL,
-+ ioctl: mipv6_ioctl,
-+ open: mipv6_open,
-+ release: mipv6_close
-+};
-+
-+
-+/* Initialize the module - Register the character device */
-+int mipv6_ioctl_mn_init(void)
-+{
-+ int ret_val;
-+
-+ /* Register the character device (atleast try) */
-+ ret_val = register_chrdev(MAJOR_NUM, CTLFILE, &Fops);
-+
-+ /* Negative values signify an error */
-+ if (ret_val < 0) {
-+ DEBUG(DBG_ERROR, "failed registering char device (err=%d)",
-+ ret_val);
-+ return ret_val;
-+ }
-+
-+ DEBUG(DBG_INFO, "Device number %x, success", MAJOR_NUM);
-+ return 0;
-+}
-+
-+
-+/* Cleanup - unregister the appropriate file from /proc */
-+void mipv6_ioctl_mn_exit(void)
-+{
-+ int ret;
-+ /* Unregister the device */
-+ ret = unregister_chrdev(MAJOR_NUM, CTLFILE);
-+
-+ /* If there's an error, report it */
-+ if (ret < 0)
-+ DEBUG(DBG_ERROR, "errorcode: %d\n", ret);
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/mdetect.c linux-2.4.25/net/ipv6/mobile_ip6/mdetect.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/mdetect.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/mdetect.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,1153 @@
-+/*
-+ * Movement Detection Module
-+ *
-+ * Authors:
-+ * Henrik Petander <lpetande@cc.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * 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.
-+ *
-+ * Handles the L3 movement detection of mobile node and also
-+ * changing of its routes.
-+ *
-+ */
-+
-+/*
-+ * Changes:
-+ *
-+ * Nanno Langstraat : Locking fixes
-+ * Venkata Jagana : Locking fix
-+ */
-+
-+#include <linux/autoconf.h>
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+#include <linux/if_arp.h>
-+#include <linux/route.h>
-+#include <net/ipv6.h>
-+#include <net/ip6_route.h>
-+#include <net/addrconf.h>
-+#include <net/mipglue.h>
-+#ifdef CONFIG_SYSCTL
-+#include <linux/sysctl.h>
-+#endif /* CONFIG_SYSCTL */
-+
-+#include "util.h"
-+#include "mdetect.h"
-+#include "mn.h"
-+#include "debug.h"
-+#include "multiaccess_ctl.h"
-+
-+#define START 0
-+#define CONTINUE 1
-+#define OK 2
-+#define DEBUG_MDETECT 7
-+
-+#define DEF_RTR_POLL_IVAL 5 /* In seconds */
-+
-+#define NO_RTR 0
-+#define RTR_SUSPECT 1
-+#define CURR_RTR_OK 2
-+
-+#define RA_RCVD 0
-+#define NA_RCVD 1
-+#define TIMEOUT 2
-+
-+#define MIPV6_MDF_NONE 0x0
-+#define MIPV6_MDF_HAS_RTR_PREV 0x1
-+
-+#define ROUTER_REACHABLE 1
-+#define RADV_MISSED 2
-+#define NOT_REACHABLE 3
-+
-+/* R_TIME_OUT paramater is used to make the decision when to change the
-+ * default router, if the current one is unreachable. 2s is pretty aggressive
-+ * and may result in hopping between two routers. OTOH a small value enhances
-+ * the performance
-+ */
-+#define R_TIME_OUT 30*HZ
-+
-+/* maximum RA interval for router unreachability detection */
-+#define MAX_RADV_INTERVAL 6*HZ /* 6000 ms... */
-+
-+/* Threshold for exponential resending of router solicitations */
-+#define RS_RESEND_LINEAR 10*HZ
-+
-+#define EAGER_CELL_SWITCHING 1
-+#define LAZY_CELL_SWITCHING 0
-+#define RESPECT_DAD 1
-+
-+#define ROUTER_ADDRESS 0x20
-+
-+/* RA flags */
-+#define ND_RA_FLAG_MANAGED 0x80
-+#define ND_RA_FLAG_OTHER 0x40
-+#define ND_RA_FLAG_HA 0x20
-+
-+/* DAD flags for global and link local addresses */
-+
-+#define COA_TENTATIVE 0x10
-+#define LLADDR_TENTATIVE 0x01
-+
-+struct router {
-+ struct list_head list;
-+ struct in6_addr ll_addr;
-+ struct in6_addr raddr; /* Also contains prefix */
-+ __u8 link_addr[MAX_ADDR_LEN]; /* link layer address */
-+ __u8 link_addr_len;
-+ __u8 state;
-+ __u8 is_current;
-+ __u8 reachable;
-+ int ifindex;
-+ int pfix_len; /* Length of the network prefix */
-+ unsigned long lifetime; /* from ra */
-+ __u32 last_ns_sent;
-+ __u32 last_ra_rcvd;
-+ __u32 interval; /* ra interval in milliseconds, 0 if not set */
-+ int glob_addr; /*Whether raddr contains also routers global address*/
-+ __u8 flags; /* RA flags, for example ha */
-+ struct in6_addr CoA; /* care-off address used with this router */
-+ int extra_addr_route;
-+};
-+
-+/* dad could also be RESPECT_DAD for duplicate address detection of
-+ new care-of addresses */
-+static int dad = 0;
-+
-+/* Only one choice, nothing else implemented */
-+int max_rtr_reach_time = DEF_RTR_POLL_IVAL;
-+
-+
-+int eager_cell_switching = EAGER_CELL_SWITCHING; /* Can be set to 0 via proc */
-+static spinlock_t router_lock;
-+static spinlock_t ho_lock;
-+
-+static void coa_timer_handler(unsigned long arg);
-+static void timer_handler(unsigned long foo);
-+static struct router *curr_router = NULL, *next_router = NULL;
-+static struct timer_list r_timer = { function: timer_handler };
-+static struct timer_list coa_timer = { function: coa_timer_handler };
-+#define MAX_ROUTERS 1000
-+static LIST_HEAD(rtr_list);
-+static int num_routers = 0;
-+static struct handoff *_ho = NULL;
-+/*
-+ * Functions for handling the default router list, which movement
-+ * detection uses for avoiding loops etc.
-+ */
-+
-+/* TODO: Send NS to router after MAX interval has passed from last RA */
-+static int mipv6_router_state(struct router *rtr) {
-+ if (rtr->interval) {
-+ if (time_before(jiffies, (rtr->last_ra_rcvd + (rtr->interval * HZ) / 1000)))
-+ return ROUTER_REACHABLE;
-+ else
-+ return NOT_REACHABLE;
-+ }
-+ else
-+ if (time_after(jiffies, rtr->last_ra_rcvd + (rtr->lifetime * HZ)))
-+ return NOT_REACHABLE;
-+ return ROUTER_REACHABLE;
-+}
-+
-+/* searches for a specific router or any router that is reachable,
-+ * if address is NULL. Also deletes obsolete routers.
-+ */
-+static void mipv6_router_gc(void)
-+{
-+ struct router *curr = NULL;
-+ struct list_head *lh, *lh_tmp;
-+
-+ DEBUG_FUNC();
-+
-+ list_for_each_safe(lh, lh_tmp, &rtr_list) {
-+ curr = list_entry(lh, struct router, list);
-+ if (mipv6_router_state(curr) == NOT_REACHABLE && !curr->is_current) {
-+ num_routers--;
-+ list_del_init(&curr->list);
-+ DEBUG(DBG_DATADUMP, "Deleting unreachable router %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(&curr->raddr));
-+ kfree(curr);
-+ }
-+ else {
-+ DEBUG(DBG_DATADUMP, "NOT Deleting router %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(&curr->raddr));
-+ }
-+ }
-+}
-+
-+static struct router *mipv6_rtr_get(struct in6_addr *search_addr)
-+{
-+ struct router *rtr = NULL;
-+ struct list_head *lh;
-+
-+ DEBUG_FUNC();
-+
-+ if (search_addr == NULL)
-+ return NULL;
-+ list_for_each(lh, &rtr_list) {
-+ rtr = list_entry(lh, struct router, list);
-+ if(!ipv6_addr_cmp(search_addr, &rtr->raddr)) {
-+ return rtr;
-+ }
-+ }
-+ return NULL;
-+}
-+
-+/*
-+ * Adds router to list
-+ */
-+static struct router *mipv6_rtr_add(struct router *nrt)
-+{
-+
-+ struct router *rptr;
-+
-+ DEBUG_FUNC();
-+
-+ /* check if someone is trying DoS attack, or we just have some
-+ memory leaks... */
-+ if (num_routers > MAX_ROUTERS) {
-+ DEBUG(DBG_CRITICAL,
-+ "failed to add new router, MAX_ROUTERS exceeded");
-+ return NULL;
-+ }
-+
-+ rptr = kmalloc(sizeof(struct router), GFP_ATOMIC);
-+ if (rptr) {
-+ memcpy(rptr, nrt, sizeof(struct router));
-+ list_add(&rptr->list, &rtr_list);
-+ num_routers++;
-+ }
-+ DEBUG(DBG_INFO, "Adding router: %x:%x:%x:%x:%x:%x:%x:%x, "
-+ "lifetime : %d sec, adv.interval: %d millisec",
-+ NIPV6ADDR(&rptr->raddr), rptr->lifetime, rptr->interval);
-+
-+ DEBUG(DBG_INFO, "num_routers after addition: %d", num_routers);
-+ return rptr;
-+}
-+
-+/* Cleans up the list */
-+static void list_free(struct router **curr_router_p)
-+{
-+ struct router *tmp;
-+ struct list_head *lh, *lh_tmp;
-+
-+ DEBUG_FUNC();
-+
-+ DEBUG(DBG_INFO, "Freeing the router list");
-+ /* set curr_router->prev_router and curr_router NULL */
-+ *curr_router_p = NULL;
-+ list_for_each_safe(lh, lh_tmp, &rtr_list) {
-+ tmp = list_entry(lh, struct router, list);
-+ DEBUG(DBG_INFO, "%x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(&tmp->ll_addr));
-+ list_del(&tmp->list);
-+ kfree(tmp);
-+ num_routers--;
-+ }
-+}
-+
-+int rs_state = START;
-+
-+/* Sends router solicitations to all valid devices
-+ * source = link local address (of sending interface)
-+ * dstaddr = all routers multicast address
-+ * Solicitations are sent at an exponentially decreasing rate
-+ *
-+ * TODO: send solicitation first at a normal rate (from ipv6) and
-+ * after that use the exponentially increasing intervals
-+ */
-+static int rs_send(void)
-+{
-+ struct net_device *dev;
-+ struct in6_addr raddr, lladdr;
-+ struct inet6_dev *in6_dev = NULL;
-+ static int num_rs;
-+
-+ if (rs_state == START) {
-+ num_rs = 0;
-+ rs_state = CONTINUE;
-+ } else if (num_rs++ > MAX_RTR_SOLICITATIONS)
-+ return HZ;
-+
-+ ipv6_addr_all_routers(&raddr);
-+ read_lock(&dev_base_lock);
-+
-+ /* Send router solicitations to all interfaces */
-+ for (dev = dev_base; dev; dev = dev->next) {
-+ if ((dev->flags & IFF_UP) && dev->type == ARPHRD_ETHER) {
-+ DEBUG(DBG_DATADUMP, "Sending RS to device %s",
-+ dev->name);
-+ if (!ipv6_get_lladdr(dev, &lladdr)) {
-+ ndisc_send_rs(dev, &lladdr, &raddr);
-+ in6_dev = in6_dev_get(dev);
-+ in6_dev->if_flags |= IF_RS_SENT;
-+ in6_dev_put(in6_dev);
-+ } else {
-+ DEBUG(DBG_DATADUMP, "%s: device doesn't have link-local address!\n", dev->name);
-+ continue;
-+ }
-+ }
-+
-+ }
-+ read_unlock(&dev_base_lock);
-+ return RTR_SOLICITATION_INTERVAL;
-+}
-+
-+/* Create a new CoA for MN and also add a route to it if it is still tentative
-+ to allow MN to get packets to the address immediately
-+ */
-+static int form_coa(struct in6_addr *coa, struct in6_addr *pfix,
-+ int plen, int ifindex)
-+{
-+ struct net_device *dev;
-+ struct inet6_dev *in6_dev;
-+ int ret = 0;
-+
-+ if ((dev = dev_get_by_index(ifindex)) == NULL) {
-+ DEBUG(DBG_WARNING, "Device is not present");
-+ return -1;
-+ }
-+ if ((in6_dev = in6_dev_get(dev)) == NULL) {
-+ DEBUG(DBG_WARNING, "inet6_dev is not present");
-+ dev_put(dev);
-+ return -1;
-+ }
-+ coa->s6_addr32[0] = pfix->s6_addr32[0];
-+ coa->s6_addr32[1] = pfix->s6_addr32[1];
-+
-+ if (ipv6_generate_eui64(coa->s6_addr + 8, dev) &&
-+ ipv6_inherit_eui64(coa->s6_addr + 8, in6_dev)) {
-+ in6_dev_put(in6_dev);
-+ dev_put(dev);
-+ return -1;
-+ }
-+ if (ipv6_chk_addr(coa, dev) == 0) {
-+ DEBUG(DBG_WARNING, "care-of address still tentative");
-+ ret = 1;
-+ }
-+ DEBUG(DBG_INFO, "Formed new CoA: %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(coa));
-+
-+ in6_dev_put(in6_dev);
-+ dev_put(dev);
-+ return ret;
-+}
-+
-+static inline int rtr_is_gw(struct router *rtr, struct rt6_info *rt)
-+{
-+ return ((rt->rt6i_flags & RTF_GATEWAY) &&
-+ !ipv6_addr_cmp(&rt->rt6i_gateway, &rtr->ll_addr));
-+}
-+
-+static inline int is_prefix_route(struct router *rtr, struct rt6_info *rt)
-+{
-+ return (!(rt->rt6i_flags & RTF_GATEWAY) &&
-+ mipv6_prefix_compare(&rt->rt6i_dst.addr, &rtr->raddr,
-+ rtr->pfix_len));
-+}
-+
-+/*
-+ * Function that determines whether given rt6_info should be destroyed
-+ * (negative => destroy rt6_info, zero or positive => do nothing)
-+ */
-+static int mn_route_cleaner(struct rt6_info *rt, void *arg)
-+{
-+ int type;
-+
-+ struct router *rtr = (struct router *)arg;
-+
-+ int ret = -1;
-+
-+ DEBUG_FUNC();
-+
-+ if (!rt || !rtr) {
-+ DEBUG(DBG_ERROR, "mn_route_cleaner: rt or rtr NULL");
-+ return 0;
-+ }
-+
-+ /* Do not delete routes to local addresses or to multicast
-+ * addresses, since we need them to get router advertisements
-+ * etc. Multicast addresses are more tricky, but we don't
-+ * delete them in any case. The routing mechanism is not optimal for
-+ * multihoming.
-+ *
-+ * Also keep all new prefix routes, gateway routes through rtr and
-+ * all remaining default routes (including those used for reverse
-+ * tunneling)
-+ */
-+ type = ipv6_addr_type(&rt->rt6i_dst.addr);
-+
-+ if ((type & (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL)) ||
-+ rt->rt6i_dev == &loopback_dev || rtr_is_gw(rtr, rt) ||
-+ is_prefix_route(rtr, rt) || (rt->rt6i_flags & RTF_DEFAULT))
-+ ret = 0;
-+
-+ /* delete all others */
-+
-+ if (rt->rt6i_dev != &loopback_dev) {
-+ DEBUG(DEBUG_MDETECT,
-+ "%s route:\n"
-+ "dev: %s,\n"
-+ "gw: %x:%x:%x:%x:%x:%x:%x:%x,\n"
-+ "flags: %x,\n"
-+ "metric: %d,\n"
-+ "src: %x:%x:%x:%x:%x:%x:%x:%x,\n"
-+ "dst: %x:%x:%x:%x:%x:%x:%x:%x,\n"
-+ "plen: %d\n",
-+ (ret ? "Deleting" : "Keeping"),
-+ rt->rt6i_dev->name,
-+ NIPV6ADDR(&rt->rt6i_gateway),
-+ rt->rt6i_flags,
-+ rt->rt6i_metric,
-+ NIPV6ADDR(&rt->rt6i_src.addr),
-+ NIPV6ADDR(&rt->rt6i_dst.addr),
-+ rt->rt6i_dst.plen);
-+ }
-+ return ret;
-+}
-+
-+/*
-+ * Deletes old routes
-+ */
-+static __inline__ void delete_routes(struct router *rtr)
-+{
-+ DEBUG_FUNC();
-+
-+ /* Routing table is locked to ensure that nobody uses its */
-+ write_lock_bh(&rt6_lock);
-+ DEBUG(DBG_INFO, "mipv6: Purging routes");
-+ /* TODO: Does not prune, should it? */
-+ fib6_clean_tree(&ip6_routing_table,
-+ mn_route_cleaner, 0, rtr);
-+ write_unlock_bh(&rt6_lock);
-+
-+}
-+
-+
-+static __inline__ void delete_coas(struct router *rtr)
-+{
-+ struct net_device *dev;
-+ struct inet6_dev *idev;
-+ struct inet6_ifaddr *ifa;
-+
-+ dev = dev_get_by_index(rtr->ifindex);
-+ if (!dev)
-+ return;
-+
-+ idev = in6_dev_get(dev);
-+
-+ if (idev) {
-+ read_lock_bh(&idev->lock);
-+ ifa = idev->addr_list;
-+ while (ifa) {
-+ int keep;
-+ spin_lock(&ifa->lock);
-+
-+ keep = (ifa->flags&(IFA_F_PERMANENT|IFA_F_HOMEADDR) ||
-+ !ipv6_addr_cmp(&ifa->addr, &rtr->CoA));
-+
-+ spin_unlock(&ifa->lock);
-+
-+ if (keep)
-+ ifa = ifa->if_next;
-+ else {
-+ in6_ifa_hold(ifa);
-+ read_unlock_bh(&idev->lock);
-+
-+ ipv6_del_addr(ifa);
-+
-+ read_lock_bh(&idev->lock);
-+ ifa = idev->addr_list;
-+ }
-+ }
-+ read_unlock_bh(&idev->lock);
-+ in6_dev_put(idev);
-+ }
-+ dev_put(dev);
-+}
-+
-+int next_mdet_state[3][3] = {{CURR_RTR_OK, NO_RTR, NO_RTR},
-+ {CURR_RTR_OK, CURR_RTR_OK, NO_RTR},
-+ {CURR_RTR_OK, CURR_RTR_OK, RTR_SUSPECT}};
-+
-+char *states[3] = {"NO_RTR", "RTR_SUSPECT", "CURR_RTR_OK"};
-+char *events[3] = {"RA_RCVD", "NA_RCVD", "TIMEOUT"};
-+
-+/* State transitions
-+ * NO_RTR, RA_RCVD -> CURR_RTR_OK
-+ * NO_RTR, NA_RCVD -> NO_RTR
-+ * NO_RTR, TIMEOUT -> NO_RTR
-+
-+ * RTR_SUSPECT, RA_RCVD -> CURR_RTR_OK
-+ * RTR_SUSPECT, NA_RCVD -> CURR_RTR_OK
-+ * RTR_SUSPECT, TIMEOUT -> NO_RTR
-+
-+ * CURR_RTR_OK, RA_RCVD -> CURR_RTR_OK
-+ * CURR_RTR_OK, NA_RCVD -> CURR_RTR_OK
-+ * CURR_RTR_OK, TIMEOUT -> RTR_SUSPECT
-+ */
-+static int _curr_state = NO_RTR;
-+
-+#if 0
-+static int get_mdet_state(void){
-+ int state;
-+ spin_lock_bh(&router_lock);
-+ state = _curr_state;
-+ spin_unlock_bh(&router_lock);
-+ return state;
-+}
-+#endif
-+
-+/* Needs to be called with router_lock locked */
-+static int mdet_statemachine(int event)
-+{
-+
-+ if (event > 2 || _curr_state > 2) {
-+ DEBUG(DBG_ERROR, "Got illegal event or curr_state");
-+ return -1;
-+ }
-+
-+ DEBUG(DBG_DATADUMP, "Got event %s and curr_state is %s",
-+ events[event], states[_curr_state]);
-+
-+ _curr_state = next_mdet_state[_curr_state][event];
-+ DEBUG(DBG_DATADUMP, "Next state is %s", states[_curr_state]);
-+ return _curr_state;
-+}
-+
-+static void mipv6_do_ll_dad(int ifindex)
-+{
-+ struct net_device *dev = dev_get_by_index(ifindex);
-+ if (dev) {
-+ struct in6_addr lladdr;
-+ struct inet6_ifaddr *ifa;
-+ if (!ipv6_get_lladdr(dev, &lladdr) &&
-+ (ifa = ipv6_get_ifaddr(&lladdr, dev)) != NULL) {
-+ spin_lock_bh(&ifa->lock);
-+ if (!(ifa->flags & IFA_F_TENTATIVE)) {
-+ ifa->flags |= IFA_F_TENTATIVE;
-+ spin_unlock_bh(&ifa->lock);
-+ addrconf_dad_start(ifa, 0);
-+ } else
-+ spin_unlock_bh(&ifa->lock);
-+
-+ }
-+ dev_put(dev);
-+ }
-+}
-+/*
-+ * Changes the router, called from ndisc.c if mipv6_router_event
-+ * returns true.
-+ */
-+
-+static void mipv6_change_router(void)
-+{
-+ struct in6_addr coa;
-+ int ret, ifindex;
-+
-+ DEBUG_FUNC();
-+
-+
-+ if (next_router == NULL)
-+ return;
-+
-+ spin_lock(&router_lock);
-+
-+
-+ if (curr_router != NULL &&
-+ !ipv6_addr_cmp(&curr_router->ll_addr, &next_router->ll_addr)) {
-+ DEBUG(DBG_INFO,"Trying to handoff from: "
-+ "%x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(&curr_router->ll_addr));
-+ DEBUG(DBG_INFO,"Trying to handoff to: "
-+ "%x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(&next_router->ll_addr));
-+ next_router = NULL; /* Let's not leave dangling pointers */
-+ spin_unlock(&router_lock);
-+ return;
-+ }
-+ ret = form_coa(&next_router->CoA, &next_router->raddr,
-+ next_router->pfix_len, next_router->ifindex);
-+ if (ret < 0) {
-+ DEBUG(DBG_ERROR, "handoff: Creation of coa failed");
-+ spin_unlock(&router_lock);
-+ return;
-+ } else if (ret > 0)
-+ next_router->flags |= COA_TENTATIVE;
-+
-+ mdet_statemachine(RA_RCVD); /* TODO: What if DAD fails... */
-+ if (next_router->interval)
-+ mod_timer(&r_timer, jiffies +
-+ (next_router->interval * HZ)/1000);
-+ else
-+ mod_timer(&r_timer, jiffies + max_rtr_reach_time * HZ);
-+
-+
-+ if (ret == 0) {
-+ ipv6_addr_copy(&coa, &next_router->CoA);
-+ ifindex = next_router->ifindex;
-+ spin_unlock(&router_lock);
-+ mipv6_mdet_finalize_ho(&coa, ifindex);
-+ return;
-+ }
-+ spin_unlock(&router_lock);
-+
-+}
-+static unsigned long ns_send(void)
-+{
-+ struct neighbour *neigh;
-+ struct net_device *dev;
-+ struct in6_addr *raddr;
-+
-+ DEBUG(DBG_DATADUMP, "Sending Neighbour solicitation to default router to verify its reachability");
-+ if (!curr_router)
-+ return HZ;
-+ if ((dev = dev_get_by_index(curr_router->ifindex)) == NULL)
-+ return HZ;
-+ if ((neigh = ndisc_get_neigh(dev, &curr_router->ll_addr)) == NULL) {
-+ dev_put(dev);
-+ return HZ;
-+ }
-+ if (curr_router->glob_addr)
-+ raddr = &curr_router->raddr;
-+ else
-+ raddr = &curr_router->ll_addr;
-+
-+ curr_router->last_ns_sent = jiffies;
-+ ndisc_send_ns(dev, neigh, raddr, raddr, NULL);
-+
-+ neigh_release(neigh);
-+ dev_put(dev);
-+ return HZ/5; /* Wait 200ms for a reply */
-+}
-+
-+static int na_rcvd(void)
-+{
-+ int neigh_ok = 0;
-+ struct neighbour *neigh;
-+ struct net_device *dev;
-+
-+ if (!curr_router)
-+ return 0;
-+ if ((dev = dev_get_by_index(curr_router->ifindex)) == NULL)
-+ return 0;
-+ if ((neigh = ndisc_get_neigh(dev, &curr_router->ll_addr)) == NULL) {
-+ dev_put(dev);
-+ return 0;
-+ }
-+ if (neigh->flags & NTF_ROUTER &&
-+ (time_after(neigh->confirmed, curr_router->last_ns_sent) ||
-+ neigh->confirmed == curr_router->last_ns_sent)) {
-+ neigh_ok = 1;
-+ DEBUG(DBG_DATADUMP, "Mdetect event: NA rcvd from curr rtr");
-+ } else
-+ DEBUG(DBG_DATADUMP, "Mdetect event: NA NOT rcvd from curr rtr within time limit");
-+ neigh_release(neigh);
-+ dev_put(dev);
-+ return neigh_ok;
-+}
-+
-+static void coa_timer_handler(unsigned long dummy)
-+{
-+
-+ spin_lock_bh(&ho_lock);
-+ if (_ho) {
-+ DEBUG(DBG_INFO, "Starting handoff after DAD");
-+ mipv6_mobile_node_moved(_ho);
-+ kfree(_ho);
-+ _ho = NULL;
-+ }
-+ spin_unlock_bh(&ho_lock);
-+}
-+static void timer_handler(unsigned long foo)
-+{
-+ unsigned long timeout;
-+ int state;
-+ spin_lock_bh(&router_lock);
-+
-+ if (_curr_state != NO_RTR)
-+ rs_state = START;
-+
-+ if (_curr_state == RTR_SUSPECT && na_rcvd()) {
-+ state = mdet_statemachine(NA_RCVD);
-+ timeout = curr_router->interval ? curr_router->interval : max_rtr_reach_time * HZ;
-+ } else {
-+ state = mdet_statemachine(TIMEOUT);
-+ if (state == NO_RTR)
-+ timeout = rs_send();
-+ else /* RTR_SUSPECT */
-+ timeout = ns_send();
-+ }
-+ if (!timeout)
-+ timeout = HZ;
-+
-+ mipv6_router_gc();
-+ mod_timer(&r_timer, jiffies + timeout);
-+ spin_unlock_bh(&router_lock);
-+}
-+
-+/**
-+ * mipv6_get_care_of_address - get node's care-of primary address
-+ * @homeaddr: one of node's home addresses
-+ * @coaddr: buffer to store care-of address
-+ *
-+ * Stores the current care-of address in the @coaddr, assumes
-+ * addresses in EUI-64 format. Since node might have several home
-+ * addresses caller MUST supply @homeaddr. If node is at home
-+ * @homeaddr is stored in @coaddr. Returns 0 on success, otherwise a
-+ * negative value.
-+ **/
-+int mipv6_get_care_of_address(
-+ struct in6_addr *homeaddr, struct in6_addr *coaddr)
-+{
-+
-+ DEBUG_FUNC();
-+
-+ if (homeaddr == NULL)
-+ return -1;
-+ spin_lock_bh(&router_lock);
-+ if (curr_router == NULL || mipv6_mn_is_at_home(homeaddr) ||
-+ mipv6_prefix_compare(homeaddr, &curr_router->raddr, 64) ||
-+ curr_router->flags&COA_TENTATIVE) {
-+ DEBUG(DBG_INFO,
-+ "mipv6_get_care_of_address: returning home address");
-+ ipv6_addr_copy(coaddr, homeaddr);
-+ spin_unlock_bh(&router_lock);
-+ return 0;
-+
-+ }
-+
-+ /* At home or address check failure probably due to dad wait */
-+ if (mipv6_prefix_compare(&curr_router->raddr, homeaddr,
-+ curr_router->pfix_len)
-+ || (dad == RESPECT_DAD &&
-+ (ipv6_chk_addr(coaddr, NULL) == 0))) {
-+ ipv6_addr_copy(coaddr, homeaddr);
-+ } else {
-+ ipv6_addr_copy(coaddr, &curr_router->CoA);
-+ }
-+
-+ spin_unlock_bh(&router_lock);
-+ return 0;
-+}
-+
-+int mipv6_mdet_del_if(int ifindex)
-+{
-+ struct router *curr = NULL;
-+ struct list_head *lh, *lh_tmp;
-+
-+ spin_lock_bh(&router_lock);
-+ list_for_each_safe(lh, lh_tmp, &rtr_list) {
-+ curr = list_entry(lh, struct router, list);
-+ if (curr->ifindex == ifindex) {
-+ num_routers--;
-+ list_del_init(&curr->list);
-+ DEBUG(DBG_DATADUMP, "Deleting router %x:%x:%x:%x:%x:%x:%x:%x on interface %d",
-+ NIPV6ADDR(&curr->raddr), ifindex);
-+ if (curr_router == curr)
-+ curr_router = NULL;
-+ kfree(curr);
-+ }
-+ }
-+ spin_unlock_bh(&router_lock);
-+ return 0;
-+}
-+
-+void mipv6_mdet_retrigger_ho(void)
-+{
-+ struct handoff ho;
-+
-+ spin_lock_bh(&router_lock);
-+ if (curr_router != NULL) {
-+ ho.coa = &curr_router->CoA;
-+ ho.plen = curr_router->pfix_len;
-+ ho.ifindex = curr_router->ifindex;
-+ ipv6_addr_copy(&ho.rtr_addr, &curr_router->raddr);
-+ ho.home_address = (curr_router->glob_addr &&
-+ curr_router->flags&ND_RA_FLAG_HA);
-+ }
-+ spin_unlock_bh(&router_lock);
-+ mipv6_mobile_node_moved(&ho);
-+}
-+
-+void mipv6_mdet_set_curr_rtr_reachable(int reachable)
-+{
-+ spin_lock_bh(&router_lock);
-+ if (curr_router != NULL) {
-+ curr_router->reachable = reachable;
-+ }
-+ spin_unlock_bh(&router_lock);
-+
-+}
-+
-+int mipv6_mdet_finalize_ho(const struct in6_addr *coa, const int ifindex)
-+{
-+ int dummy;
-+ struct handoff ho;
-+ struct router *tmp;
-+ struct net_device *dev;
-+ struct in6_addr ll_addr;
-+
-+ spin_lock_bh(&router_lock);
-+
-+ if (!next_router) {
-+ spin_unlock_bh(&router_lock);
-+ return 0;
-+ }
-+
-+ dev = dev_get_by_index(next_router->ifindex);
-+
-+ if (ipv6_get_lladdr(dev, &ll_addr) == 0) {
-+ if (ipv6_addr_cmp(&ll_addr, coa) == 0)
-+ DEBUG(DBG_INFO, "DAD for link local address completed");
-+ next_router->flags &= ~LLADDR_TENTATIVE;
-+ }
-+
-+ dev_put(dev);
-+
-+ if (mipv6_prefix_compare(coa, &next_router->CoA,
-+ next_router->pfix_len)) {
-+ DEBUG(DBG_INFO, "DAD for Care-of address completed");
-+ next_router->flags &= ~COA_TENTATIVE;
-+ }
-+ if (!(next_router->flags&LLADDR_TENTATIVE) && !(next_router->flags&COA_TENTATIVE)) {
-+ DEBUG(DBG_INFO, "%s: Proceeding with handoff after DAD\n", __FUNCTION__);
-+ tmp = curr_router;
-+ curr_router = next_router;
-+ curr_router->is_current = 1;
-+ next_router = NULL;
-+ curr_router->flags &= ~COA_TENTATIVE;
-+ delete_routes(curr_router);
-+ delete_coas(curr_router);
-+ if (tmp) {
-+ struct net_device *dev_old = dev_get_by_index(tmp->ifindex);
-+ struct rt6_info *rt = NULL;
-+ if (dev_old) {
-+ rt = rt6_get_dflt_router(&tmp->ll_addr, dev_old);
-+ dev_put(dev_old);
-+ }
-+ if (rt)
-+ ip6_del_rt(rt, NULL);
-+ tmp->is_current = 0;
-+ }
-+
-+ ma_ctl_upd_iface(curr_router->ifindex, MA_IFACE_CURRENT, &dummy);
-+ ma_ctl_upd_iface(curr_router->ifindex, MA_IFACE_CURRENT, &dummy);
-+
-+
-+ ho.coa = &curr_router->CoA;
-+ ho.plen = curr_router->pfix_len;
-+ ho.ifindex = curr_router->ifindex;
-+ ipv6_addr_copy(&ho.rtr_addr, &curr_router->raddr);
-+ ho.home_address = (curr_router->glob_addr &&
-+ curr_router->flags&ND_RA_FLAG_HA);
-+
-+ spin_unlock_bh(&router_lock);
-+ mipv6_mobile_node_moved(&ho);
-+ } else
-+ spin_unlock_bh(&router_lock);
-+ return 0;
-+}
-+/* Decides whether router candidate is the same router as current rtr
-+ * based on prefix / global addresses of the routers and their link local
-+ * addresses
-+ */
-+static int is_current_rtr(struct router *nrt, struct router *crt)
-+{
-+ DEBUG_FUNC();
-+
-+ DEBUG(DEBUG_MDETECT, "Current router: "
-+ "%x:%x:%x:%x:%x:%x:%x:%x and", NIPV6ADDR(&crt->raddr));
-+ DEBUG(DEBUG_MDETECT, "Candidate router: "
-+ "%x:%x:%x:%x:%x:%x:%x:%x", NIPV6ADDR(&nrt->raddr));
-+
-+ return (!ipv6_addr_cmp(&nrt->raddr,&crt->raddr) &&
-+ !ipv6_addr_cmp(&nrt->ll_addr, &crt->ll_addr));
-+}
-+
-+/*
-+ * Change next router to nrtr
-+ * Returns 1, if router has been changed.
-+ */
-+
-+static int change_next_rtr(struct router *nrtr, struct router *ortr)
-+{
-+ int changed = 0;
-+ DEBUG_FUNC();
-+
-+ if (!next_router || ipv6_addr_cmp(&nrtr->raddr, &next_router->raddr)) {
-+ changed = 1;
-+ }
-+ next_router = nrtr;
-+ return changed;
-+}
-+static int clean_ncache(struct router *nrt, struct router *ort, int same_if)
-+{
-+ struct net_device *ortdev;
-+ DEBUG_FUNC();
-+
-+ /* Always call ifdown after a handoff to ensure proper routing */
-+
-+ if (!ort)
-+ return 0;
-+ if ((ortdev = dev_get_by_index(ort->ifindex)) == NULL) {
-+ DEBUG(DBG_WARNING, "Device is not present");
-+ return -1;
-+ }
-+ neigh_ifdown(&nd_tbl, ortdev);
-+ dev_put(ortdev);
-+ return 0;
-+}
-+
-+static int mdet_get_if_preference(int ifi)
-+{
-+ int pref = 0;
-+
-+ DEBUG_FUNC();
-+
-+ pref = ma_ctl_get_preference(ifi);
-+
-+ DEBUG(DEBUG_MDETECT, "ifi: %d preference %d", ifi, pref);
-+
-+ return pref;
-+}
-+
-+/*
-+ * Called from mipv6_mn_ra_rcv to determine whether to do a handoff.
-+ */
-+static int mipv6_router_event(struct router *rptr)
-+{
-+ struct router *nrt = NULL;
-+ int new_router = 0, same_if = 1;
-+ int oldstate = _curr_state;
-+ int addrtype = ipv6_addr_type(&rptr->raddr);
-+
-+ DEBUG_FUNC();
-+
-+ if (rptr->lifetime == 0)
-+ return MIPV6_IGN_RTR;
-+ DEBUG(DEBUG_MDETECT, "Received a RA from router: "
-+ "%x:%x:%x:%x:%x:%x:%x:%x", NIPV6ADDR(&rptr->raddr));
-+ spin_lock(&router_lock);
-+
-+ /* Add or update router entry */
-+ if ((nrt = mipv6_rtr_get(&rptr->raddr)) == NULL) {
-+ if (addrtype == IPV6_ADDR_ANY || (nrt = mipv6_rtr_add(rptr)) == NULL) {
-+ spin_unlock(&router_lock);
-+ return MIPV6_IGN_RTR;
-+ }
-+ DEBUG(DBG_INFO, "Router not on list,adding it to the list");
-+ new_router = 1;
-+ }
-+ nrt->last_ra_rcvd = jiffies;
-+ nrt->state = ROUTER_REACHABLE;
-+ nrt->interval = rptr->interval;
-+ nrt->lifetime = rptr->lifetime;
-+ nrt->ifindex = rptr->ifindex;
-+ nrt->flags = rptr->flags;
-+ nrt->glob_addr = rptr->glob_addr;
-+
-+ /* Whether from current router */
-+ if (curr_router && curr_router->reachable &&
-+ is_current_rtr(nrt, curr_router)) {
-+ if (nrt->interval)
-+ mod_timer(&r_timer, jiffies + (nrt->interval * HZ)/1000);
-+ else
-+ mod_timer(&r_timer, jiffies + max_rtr_reach_time * HZ);
-+ mdet_statemachine(RA_RCVD);
-+ spin_unlock(&router_lock);
-+ return MIPV6_ADD_RTR;
-+ } else if (oldstate == NO_RTR) {
-+ rt6_purge_dflt_routers(0); /* For multiple interface case */
-+ DEBUG(DBG_INFO, "No router or router not reachable, switching to new one");
-+ goto handoff;
-+ }
-+ if (!curr_router) {
-+ /* Startup */
-+ goto handoff;
-+ }
-+ /* Router behind same interface as current one ?*/
-+ same_if = (nrt->ifindex == curr_router->ifindex);
-+ /* Switch to new router behind same interface if eager cell
-+ * switching is used or if the interface is preferred
-+ */
-+ if ((new_router && eager_cell_switching && same_if) ||
-+ (mdet_get_if_preference(nrt->ifindex) >
-+ mdet_get_if_preference(curr_router->ifindex))) {
-+ DEBUG(DBG_INFO, "Switching to new router.");
-+ goto handoff;
-+ }
-+
-+ /* No handoff, don't add default route */
-+ DEBUG(DEBUG_MDETECT, "Ignoring RA");
-+ spin_unlock(&router_lock);
-+ return MIPV6_IGN_RTR;
-+handoff:
-+ clean_ncache(nrt, curr_router, same_if);
-+ nrt->reachable = 1;
-+ if (same_if && change_next_rtr(nrt, curr_router)) {
-+ mipv6_do_ll_dad(nrt->ifindex);
-+ nrt->flags |= LLADDR_TENTATIVE;
-+ }
-+ spin_unlock(&router_lock);
-+
-+ return MIPV6_CHG_RTR;
-+}
-+
-+/*
-+ * Called from ndisc.c's router_discovery.
-+ */
-+
-+static inline int ret_to_ha(struct in6_addr *addr)
-+{
-+ int res = 0;
-+ struct mn_info *minfo;
-+ read_lock(&mn_info_lock);
-+ minfo = mipv6_mninfo_get_by_ha(addr);
-+ if (minfo != NULL) {
-+ spin_lock(&minfo->lock);
-+ if (minfo->has_home_reg) {
-+ res = 1;
-+ }
-+ spin_unlock(&minfo->lock);
-+ }
-+ read_unlock(&mn_info_lock);
-+ return res;
-+}
-+
-+static int mipv6_mn_ra_rcv(struct sk_buff *skb, struct ndisc_options *ndopts)
-+{
-+ int ifi = ((struct inet6_skb_parm *)skb->cb)->iif;
-+ struct ra_msg *ra = (struct ra_msg *) skb->h.raw;
-+ struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
-+ struct router nrt;
-+ struct in6_addr *ha = NULL;
-+ u8 *lladdr = NULL;
-+ int res;
-+ DEBUG_FUNC();
-+
-+ memset(&nrt, 0, sizeof(struct router));
-+
-+ if (ra->icmph.icmp6_home_agent) {
-+ nrt.flags |= ND_RA_FLAG_HA;
-+ DEBUG(DBG_DATADUMP, "RA has ND_RA_FLAG_HA up");
-+ }
-+
-+ if (ra->icmph.icmp6_addrconf_managed) {
-+ nrt.flags |= ND_RA_FLAG_MANAGED;
-+ DEBUG(DBG_DATADUMP, "RA has ND_RA_FLAG_MANAGED up");
-+ }
-+
-+ if (ra->icmph.icmp6_addrconf_other) {
-+ nrt.flags |= ND_RA_FLAG_OTHER;
-+ DEBUG(DBG_DATADUMP, "RA has ND_RA_FLAG_OTHER up");
-+ }
-+
-+ ipv6_addr_copy(&nrt.ll_addr, saddr);
-+ nrt.ifindex = ifi;
-+ nrt.lifetime = ntohs(ra->icmph.icmp6_rt_lifetime);
-+
-+ if (ndopts->nd_opts_src_lladdr) {
-+ lladdr = (u8 *) ndopts->nd_opts_src_lladdr+2;
-+ nrt.link_addr_len = skb->dev->addr_len;
-+ memcpy(nrt.link_addr, lladdr, nrt.link_addr_len);
-+ }
-+ if (ndopts->nd_opts_pi) {
-+ struct nd_opt_hdr *p;
-+ for (p = ndopts->nd_opts_pi;
-+ p;
-+ p = ndisc_next_option(p, ndopts->nd_opts_pi_end)) {
-+ struct prefix_info *pinfo;
-+ int update = 0;
-+
-+ pinfo = (struct prefix_info *) p;
-+
-+ if (!pinfo->autoconf)
-+ continue;
-+
-+ if ((pinfo->router_address &&
-+ (update = ret_to_ha(&pinfo->prefix))) ||
-+ ipv6_addr_type(&nrt.raddr) != IPV6_ADDR_UNICAST) {
-+ ipv6_addr_copy(&nrt.raddr, &pinfo->prefix);
-+ nrt.pfix_len = pinfo->prefix_len;
-+ if (pinfo->router_address)
-+ nrt.glob_addr = 1;
-+ else
-+ nrt.glob_addr = 0;
-+ if (update)
-+ ha = &pinfo->prefix;
-+ DEBUG(DBG_DATADUMP, "Address of the received "
-+ "prefix info option: %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(&nrt.raddr));
-+ DEBUG(DBG_DATADUMP, "the length of the prefix is %d",
-+ nrt.pfix_len);
-+ }
-+ }
-+ }
-+ if (ndopts->nd_opts_rai) {
-+ nrt.interval = ntohl(*(__u32 *)(ndopts->nd_opts_rai+4));
-+ DEBUG(DBG_DATADUMP,
-+ "received router interval option with interval : %d ",
-+ nrt.interval / HZ);
-+
-+ if (nrt.interval > MAX_RADV_INTERVAL) {
-+ nrt.interval = 0;
-+ DEBUG(DBG_DATADUMP, "but we are using: %d, "
-+ "because interval>MAX_RADV_INTERVAL",
-+ nrt.interval / HZ);
-+ }
-+ }
-+
-+ res = mipv6_router_event(&nrt);
-+
-+ if (ha && lladdr) {
-+ mipv6_mn_ha_nd_update(__dev_get_by_index(ifi), ha, lladdr);
-+ }
-+ return res;
-+}
-+
-+int __init mipv6_initialize_mdetect(void)
-+{
-+
-+ DEBUG_FUNC();
-+
-+ spin_lock_init(&router_lock);
-+ spin_lock_init(&ho_lock);
-+ init_timer(&coa_timer);
-+ init_timer(&r_timer);
-+ r_timer.expires = jiffies + HZ;
-+ add_timer(&r_timer);
-+
-+ /* Actual HO, also deletes old routes after the addition of new ones
-+ in ndisc */
-+ MIPV6_SETCALL(mipv6_change_router, mipv6_change_router);
-+
-+ MIPV6_SETCALL(mipv6_ra_rcv, mipv6_mn_ra_rcv);
-+
-+ return 0;
-+}
-+
-+int __exit mipv6_shutdown_mdetect()
-+{
-+
-+ DEBUG_FUNC();
-+
-+ MIPV6_RESETCALL(mipv6_ra_rcv);
-+ MIPV6_RESETCALL(mipv6_change_router);
-+ spin_lock_bh(&router_lock);
-+ spin_lock(&ho_lock);
-+ del_timer(&coa_timer);
-+ del_timer(&r_timer);
-+ /* Free the memory allocated by router list */
-+ list_free(&curr_router);
-+ if (_ho)
-+ kfree(_ho);
-+ spin_unlock(&ho_lock);
-+ spin_unlock_bh(&router_lock);
-+ return 0;
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/mdetect.h linux-2.4.25/net/ipv6/mobile_ip6/mdetect.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/mdetect.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/mdetect.h 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,37 @@
-+/*
-+ * MIPL Mobile IPv6 Movement detection module header file
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef _MDETECT_H
-+#define _MDETECT_H
-+
-+struct handoff {
-+ int home_address; /* Is the coa a home address */
-+ int ifindex;
-+ int plen;
-+ struct in6_addr *coa;
-+ struct in6_addr rtr_addr; /* Prefix or rtr address if coa is home address */
-+};
-+
-+int mipv6_initialize_mdetect(void);
-+
-+int mipv6_shutdown_mdetect(void);
-+
-+int mipv6_get_care_of_address(struct in6_addr *homeaddr, struct in6_addr *coa);
-+
-+int mipv6_mdet_del_if(int ifindex);
-+
-+int mipv6_mdet_finalize_ho(const struct in6_addr *coa, const int ifindex);
-+
-+void mipv6_mdet_retrigger_ho(void);
-+
-+void mipv6_mdet_set_curr_rtr_reachable(int reachable);
-+
-+#endif /* _MDETECT_H */
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/mipv6_icmp.c linux-2.4.25/net/ipv6/mobile_ip6/mipv6_icmp.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/mipv6_icmp.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/mipv6_icmp.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,342 @@
-+/**
-+ * Generic icmp routines
-+ *
-+ * Authors:
-+ * Jaakko Laine <medved@iki.fi>,
-+ * Ville Nuorvala <vnuorval@tcs.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/icmpv6.h>
-+#include <net/checksum.h>
-+#include <net/ipv6.h>
-+#include <net/ip6_route.h>
-+#include <net/mipv6.h>
-+#include <net/mipglue.h>
-+
-+#include "debug.h"
-+#include "bcache.h"
-+#include "mipv6_icmp.h"
-+#include "config.h"
-+
-+struct mipv6_icmpv6_msg {
-+ struct icmp6hdr icmph;
-+ __u8 *data;
-+ struct in6_addr *daddr;
-+ int len;
-+ __u32 csum;
-+};
-+
-+#define MIPV6_ICMP_HOP_LIMIT 64
-+
-+static struct socket *mipv6_icmpv6_socket = NULL;
-+static __u16 identifier = 0;
-+
-+int mipv6_icmpv6_no_rcv(struct sk_buff *skb)
-+{
-+ return 0;
-+}
-+
-+static int mipv6_icmpv6_xmit_holder = -1;
-+
-+static int mipv6_icmpv6_xmit_lock_bh(void)
-+{
-+ if (!spin_trylock(&mipv6_icmpv6_socket->sk->lock.slock)) {
-+ if (mipv6_icmpv6_xmit_holder == smp_processor_id())
-+ return -EAGAIN;
-+ spin_lock(&mipv6_icmpv6_socket->sk->lock.slock);
-+ }
-+ mipv6_icmpv6_xmit_holder = smp_processor_id();
-+ return 0;
-+}
-+
-+static __inline__ int mipv6_icmpv6_xmit_lock(void)
-+{
-+ int ret;
-+ local_bh_disable();
-+ ret = mipv6_icmpv6_xmit_lock_bh();
-+ if (ret)
-+ local_bh_enable();
-+ return ret;
-+}
-+
-+static void mipv6_icmpv6_xmit_unlock_bh(void)
-+{
-+ mipv6_icmpv6_xmit_holder = -1;
-+ spin_unlock(&mipv6_icmpv6_socket->sk->lock.slock);
-+}
-+
-+static __inline__ void mipv6_icmpv6_xmit_unlock(void)
-+{
-+ mipv6_icmpv6_xmit_unlock_bh();
-+ local_bh_enable();
-+}
-+
-+
-+/**
-+ * mipv6_icmpv6_dest_unreach - Destination Unreachable ICMP error message handler
-+ * @skb: buffer containing ICMP error message
-+ *
-+ * Special Mobile IPv6 ICMP handling. If Correspondent Node receives
-+ * persistent ICMP Destination Unreachable messages for a destination
-+ * in its Binding Cache, the binding should be deleted. See draft
-+ * section 8.8.
-+ **/
-+static int mipv6_icmpv6_rcv_dest_unreach(struct sk_buff *skb)
-+{
-+ struct icmp6hdr *icmph = (struct icmp6hdr *) skb->h.raw;
-+ struct ipv6hdr *ipv6h = (struct ipv6hdr *) (icmph + 1);
-+ int left = (skb->tail - skb->h.raw) - sizeof(*icmph)- sizeof(ipv6h);
-+ struct ipv6_opt_hdr *eh;
-+ struct rt2_hdr *rt2h = NULL;
-+ struct in6_addr *daddr = &ipv6h->daddr;
-+ struct in6_addr *saddr = &ipv6h->saddr;
-+ int hdrlen, nexthdr = ipv6h->nexthdr;
-+ struct mipv6_bce bce;
-+ DEBUG_FUNC();
-+
-+ eh = (struct ipv6_opt_hdr *) (ipv6h + 1);
-+
-+ while (left > 0) {
-+ if (nexthdr != NEXTHDR_HOP && nexthdr != NEXTHDR_DEST &&
-+ nexthdr != NEXTHDR_ROUTING)
-+ return 0;
-+
-+ hdrlen = ipv6_optlen(eh);
-+ if (hdrlen > left)
-+ return 0;
-+
-+ if (nexthdr == NEXTHDR_ROUTING) {
-+ struct ipv6_rt_hdr *rth = (struct ipv6_rt_hdr *) eh;
-+
-+ if (rth->type == IPV6_SRCRT_TYPE_2) {
-+ if (hdrlen != sizeof(struct rt2_hdr))
-+ return 0;
-+
-+ rt2h = (struct rt2_hdr *) rth;
-+
-+ if (rt2h->rt_hdr.segments_left > 0)
-+ daddr = &rt2h->addr;
-+ break;
-+ }
-+ }
-+ /* check for home address option in case this node is a MN */
-+ if (nexthdr == NEXTHDR_DEST) {
-+ __u8 *raw = (__u8 *) eh;
-+ __u16 i = 2;
-+ while (1) {
-+ struct mipv6_dstopt_homeaddr *hao;
-+
-+ if (i + sizeof (*hao) > hdrlen)
-+ break;
-+
-+ hao = (struct mipv6_dstopt_homeaddr *) &raw[i];
-+
-+ if (hao->type == MIPV6_TLV_HOMEADDR &&
-+ hao->length == sizeof(struct in6_addr)) {
-+ saddr = &hao->addr;
-+ break;
-+ }
-+ if (hao->type)
-+ i += hao->length + 2;
-+ else
-+ i++;
-+ }
-+
-+ }
-+ nexthdr = eh->nexthdr;
-+ eh = (struct ipv6_opt_hdr *) ((u8 *) eh + hdrlen);
-+ left -= hdrlen;
-+ }
-+ if (rt2h == NULL) return 0;
-+
-+ if (mipv6_bcache_get(daddr, saddr, &bce) == 0 && !(bce.flags&HOME_REGISTRATION)) {
-+ /* A primitive algorithm for detecting persistent ICMP destination unreachable messages */
-+ if (bce.destunr_count &&
-+ time_after(jiffies,
-+ bce.last_destunr + MIPV6_DEST_UNR_IVAL*HZ))
-+ bce.destunr_count = 0;
-+
-+ bce.destunr_count++;
-+
-+ mipv6_bcache_icmp_err(daddr, saddr, bce.destunr_count);
-+
-+ if (bce.destunr_count > MIPV6_MAX_DESTUNREACH && mipv6_bcache_delete(daddr, saddr, CACHE_ENTRY) == 0) {
-+ DEBUG(DBG_INFO, "Deleted bcache entry "
-+ "%x:%x:%x:%x:%x:%x:%x:%x "
-+ "%x:%x:%x:%x:%x:%x:%x:%x (reason: "
-+ "%d dest unreachables) ",
-+ NIPV6ADDR(daddr), NIPV6ADDR(saddr), bce.destunr_count);
-+ }
-+ }
-+ return 0;
-+}
-+
-+static int mipv6_icmpv6_getfrag(const void *data, struct in6_addr *saddr,
-+ char *buff, unsigned int offset,
-+ unsigned int len)
-+{
-+ struct mipv6_icmpv6_msg *msg = (struct mipv6_icmpv6_msg *) data;
-+ struct icmp6hdr *icmph;
-+ __u32 csum;
-+
-+ if (offset) {
-+ msg->csum = csum_partial_copy_nocheck(msg->data + offset -
-+ sizeof(*icmph), buff,
-+ len, msg->csum);
-+ return 0;
-+ }
-+
-+ csum = csum_partial_copy_nocheck((__u8 *) &msg->icmph, buff,
-+ sizeof(*icmph), msg->csum);
-+
-+ csum = csum_partial_copy_nocheck(msg->data, buff + sizeof(*icmph),
-+ len - sizeof(*icmph), csum);
-+
-+ icmph = (struct icmp6hdr *) buff;
-+
-+ icmph->icmp6_cksum = csum_ipv6_magic(saddr, msg->daddr, msg->len,
-+ IPPROTO_ICMPV6, csum);
-+ return 0;
-+}
-+
-+/**
-+ * mipv6_icmpv6_send - generic icmpv6 message send
-+ * @daddr: destination address
-+ * @saddr: source address
-+ * @type: icmp type
-+ * @code: icmp code
-+ * @id: packet identifier. If null, uses internal counter to get new id
-+ * @data: packet data
-+ * @datalen: length of data in bytes
-+ */
-+void mipv6_icmpv6_send(struct in6_addr *daddr, struct in6_addr *saddr, int type,
-+ int code, __u16 *id, __u16 flags, void *data, int datalen)
-+{
-+ struct sock *sk = mipv6_icmpv6_socket->sk;
-+ struct flowi fl;
-+ struct mipv6_icmpv6_msg msg;
-+
-+ DEBUG_FUNC();
-+
-+ fl.proto = IPPROTO_ICMPV6;
-+ fl.fl6_dst = daddr;
-+ fl.fl6_src = saddr;
-+ fl.fl6_flowlabel = 0;
-+ fl.uli_u.icmpt.type = type;
-+ fl.uli_u.icmpt.code = code;
-+
-+ msg.icmph.icmp6_type = type;
-+ msg.icmph.icmp6_code = code;
-+ msg.icmph.icmp6_cksum = 0;
-+
-+ if (id)
-+ msg.icmph.icmp6_identifier = htons(*id);
-+ else
-+ msg.icmph.icmp6_identifier = htons(identifier++);
-+
-+ msg.icmph.icmp6_sequence = htons(flags);
-+ msg.data = data;
-+ msg.csum = 0;
-+ msg.len = datalen + sizeof(struct icmp6hdr);
-+ msg.daddr = daddr;
-+
-+ if (mipv6_icmpv6_xmit_lock())
-+ return;
-+
-+ ip6_build_xmit(sk, mipv6_icmpv6_getfrag, &msg, &fl, msg.len, NULL, -1,
-+ MSG_DONTWAIT);
-+
-+ ICMP6_INC_STATS_BH(Icmp6OutMsgs);
-+ mipv6_icmpv6_xmit_unlock();
-+}
-+
-+/**
-+ * icmp6_rcv - ICMPv6 receive and multiplex
-+ * @skb: buffer containing ICMP message
-+ *
-+ * Generic ICMPv6 receive function to multiplex messages to approriate
-+ * handlers. Only used for ICMP messages with special handling in
-+ * Mobile IPv6.
-+ **/
-+static void icmp6_rcv(struct sk_buff *skb)
-+{
-+ struct icmp6hdr *hdr;
-+
-+ if (skb_is_nonlinear(skb) &&
-+ skb_linearize(skb, GFP_ATOMIC) != 0) {
-+ kfree_skb(skb);
-+ return;
-+ }
-+ __skb_push(skb, skb->data-skb->h.raw);
-+
-+ hdr = (struct icmp6hdr *) skb->h.raw;
-+
-+ switch (hdr->icmp6_type) {
-+ case ICMPV6_DEST_UNREACH:
-+ mipv6_icmpv6_rcv_dest_unreach(skb);
-+ break;
-+
-+ case ICMPV6_PARAMPROB:
-+ mip6_fn.icmpv6_paramprob_rcv(skb);
-+ break;
-+
-+ case MIPV6_DHAAD_REPLY:
-+ mip6_fn.icmpv6_dhaad_rep_rcv(skb);
-+ break;
-+
-+ case MIPV6_PREFIX_ADV:
-+ mip6_fn.icmpv6_pfxadv_rcv(skb);
-+ break;
-+
-+ case MIPV6_DHAAD_REQUEST:
-+ mip6_fn.icmpv6_dhaad_req_rcv(skb);
-+ break;
-+
-+ case MIPV6_PREFIX_SOLICIT:
-+ mip6_fn.icmpv6_pfxsol_rcv(skb);
-+ break;
-+ }
-+}
-+
-+int mipv6_icmpv6_init(void)
-+{
-+ struct sock *sk;
-+ int err;
-+
-+ if ((mipv6_icmpv6_socket = sock_alloc()) == NULL) {
-+ DEBUG(DBG_ERROR, "Cannot allocate mipv6_icmpv6_socket");
-+ return -1;
-+ }
-+ mipv6_icmpv6_socket->type = SOCK_RAW;
-+
-+ if ((err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_ICMP,
-+ &mipv6_icmpv6_socket)) < 0) {
-+ DEBUG(DBG_ERROR, "Cannot initialize mipv6_icmpv6_socket");
-+ sock_release(mipv6_icmpv6_socket);
-+ mipv6_icmpv6_socket = NULL; /* For safety */
-+ return err;
-+ }
-+ sk = mipv6_icmpv6_socket->sk;
-+ sk->allocation = GFP_ATOMIC;
-+ sk->prot->unhash(sk);
-+
-+ /* Register our ICMP handler */
-+ MIPV6_SETCALL(mipv6_icmp_rcv, icmp6_rcv);
-+ return 0;
-+}
-+
-+void mipv6_icmpv6_exit(void)
-+{
-+ MIPV6_RESETCALL(mipv6_icmp_rcv);
-+ if (mipv6_icmpv6_socket)
-+ sock_release(mipv6_icmpv6_socket);
-+ mipv6_icmpv6_socket = NULL; /* For safety */
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/mipv6_icmp.h linux-2.4.25/net/ipv6/mobile_ip6/mipv6_icmp.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/mipv6_icmp.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/mipv6_icmp.h 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,43 @@
-+/*
-+ * MIPL Mobile IPv6 ICMP send and receive prototypes
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef _MIPV6_ICMP
-+#define _MIPV6_ICMP
-+
-+#include <linux/config.h>
-+#include <linux/in6.h>
-+
-+void mipv6_icmpv6_send(struct in6_addr *daddr, struct in6_addr *saddr,
-+ int type, int code, __u16 *id, __u16 flags,
-+ void *data, int datalen);
-+
-+void mipv6_icmpv6_send_dhaad_req(struct in6_addr *home_addr, int plen, __u16 dhaad_id);
-+
-+void mipv6_icmpv6_send_dhaad_rep(int ifindex, __u16 id, struct in6_addr *daddr);
-+/* No handling */
-+int mipv6_icmpv6_no_rcv(struct sk_buff *skb);
-+
-+/* Receive DHAAD Reply message */
-+int mipv6_icmpv6_rcv_dhaad_rep(struct sk_buff *skb);
-+/* Receive Parameter Problem message */
-+int mipv6_icmpv6_rcv_paramprob(struct sk_buff *skb);
-+/* Receive prefix advertisements */
-+int mipv6_icmpv6_rcv_pfx_adv(struct sk_buff *skb);
-+
-+/* Receive DHAAD Request message */
-+int mipv6_icmpv6_rcv_dhaad_req(struct sk_buff *skb);
-+/* Receive prefix solicitations */
-+int mipv6_icmpv6_rcv_pfx_sol(struct sk_buff *skb);
-+
-+int mipv6_icmpv6_init(void);
-+void mipv6_icmpv6_exit(void);
-+
-+#endif
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/mipv6_icmp_ha.c linux-2.4.25/net/ipv6/mobile_ip6/mipv6_icmp_ha.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/mipv6_icmp_ha.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/mipv6_icmp_ha.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,158 @@
-+/*
-+ * Home Agent specific ICMP routines
-+ *
-+ * Authors:
-+ * Antti Tuominen <ajtuomin@tml.hut.fi>
-+ * Jaakko Laine <medved@iki.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/autoconf.h>
-+#include <linux/sched.h>
-+#include <net/ipv6.h>
-+#include <net/addrconf.h>
-+#include <net/ip6_route.h>
-+#include <net/mipv6.h>
-+
-+#include "halist.h"
-+#include "debug.h"
-+#include "mipv6_icmp.h"
-+//#include "prefix.h"
-+
-+/* Is this the easiest way of checking on
-+ * which interface an anycast address is ?
-+ */
-+static int find_ac_dev(struct in6_addr *addr)
-+{
-+ int ifindex = 0;
-+ struct net_device *dev;
-+ read_lock(&dev_base_lock);
-+ for (dev=dev_base; dev; dev=dev->next) {
-+ if (ipv6_chk_acast_addr(dev, addr)) {
-+ ifindex = dev->ifindex;
-+ break;
-+ }
-+ }
-+ read_unlock(&dev_base_lock);
-+ return ifindex;
-+}
-+
-+/**
-+ * mipv6_icmpv6_send_dhaad_rep - Reply to DHAAD Request
-+ * @ifindex: index of interface request was received from
-+ * @id: request's identification number
-+ * @daddr: requester's IPv6 address
-+ *
-+ * When Home Agent receives Dynamic Home Agent Address Discovery
-+ * request, it replies with a list of home agents available on the
-+ * home link.
-+ */
-+void mipv6_icmpv6_send_dhaad_rep(int ifindex, __u16 id, struct in6_addr *daddr)
-+{
-+ __u8 *data = NULL;
-+ struct in6_addr home, *ha_addrs = NULL;
-+ int addr_count, max_addrs, size = 0;
-+
-+ if (daddr == NULL)
-+ return;
-+
-+ if (mipv6_ha_get_addr(ifindex, &home) < 0) {
-+ DEBUG(DBG_INFO, "Not Home Agent in this interface");
-+ return;
-+ }
-+
-+ /* We send all available HA addresses, not exceeding a maximum
-+ * number we can fit in a packet with minimum IPv6 MTU (to
-+ * avoid fragmentation).
-+ */
-+ max_addrs = 76;
-+ addr_count = mipv6_ha_get_pref_list(ifindex, &ha_addrs, max_addrs);
-+
-+ if (addr_count < 0) return;
-+
-+ if (addr_count != 0 && ha_addrs == NULL) {
-+ DEBUG(DBG_ERROR, "addr_count = %d but return no addresses",
-+ addr_count);
-+ return;
-+ }
-+ data = (u8 *)ha_addrs;
-+
-+ size = addr_count * sizeof(struct in6_addr);
-+
-+ mipv6_icmpv6_send(daddr, &home, MIPV6_DHAAD_REPLY,
-+ 0, &id, 0, data, size);
-+ if (ha_addrs) {
-+ data = NULL;
-+ kfree(ha_addrs);
-+ }
-+}
-+
-+/**
-+ * mipv6_icmpv6_dhaad_req - Home Agent Address Discovery Request ICMP handler
-+ * @skb: buffer containing ICMP information message
-+ *
-+ * Special Mobile IPv6 ICMP message. Handles Dynamic Home Agent
-+ * Address Discovery Request messages.
-+ **/
-+int mipv6_icmpv6_rcv_dhaad_req(struct sk_buff *skb)
-+{
-+ struct icmp6hdr *phdr = (struct icmp6hdr *) skb->h.raw;
-+ struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
-+ struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
-+ __u16 identifier;
-+ int ifindex = 0;
-+
-+ DEBUG_FUNC();
-+
-+ /* Invalid packet checks. */
-+ if (phdr->icmp6_code != 0)
-+ return 0;
-+
-+ identifier = ntohs(phdr->icmp6_identifier);
-+
-+ /*
-+ * Make sure we have the right ifindex (if the
-+ * req came through another interface.
-+ */
-+ ifindex = find_ac_dev(daddr);
-+ if (ifindex == 0) {
-+ DEBUG(DBG_WARNING, "received dhaad request to anycast address %x:%x:%x:%x:%x:%x:%x:%x"
-+ " on which prefix we are not HA",
-+ NIPV6ADDR(daddr));
-+ return 0;
-+ }
-+
-+ /*
-+ * send reply with list
-+ */
-+ mipv6_icmpv6_send_dhaad_rep(ifindex, identifier, saddr);
-+ return 1;
-+}
-+#if 0
-+/**
-+ * mipv6_icmpv6_handle_pfx_sol - handle prefix solicitations
-+ * @skb: sk_buff including the icmp6 message
-+ */
-+int mipv6_icmpv6_rcv_pfx_sol(struct sk_buff *skb)
-+{
-+ struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
-+ struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
-+ struct inet6_ifaddr *ifp;
-+
-+ DEBUG_FUNC();
-+
-+ if (!(ifp = ipv6_get_ifaddr(daddr, NULL)))
-+ return -1;
-+
-+ in6_ifa_put(ifp);
-+ mipv6_pfx_cancel_send(saddr, -1);
-+
-+ return 0;
-+}
-+#endif
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/mipv6_icmp_mn.c linux-2.4.25/net/ipv6/mobile_ip6/mipv6_icmp_mn.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/mipv6_icmp_mn.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/mipv6_icmp_mn.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,273 @@
-+/*
-+ * Mobile Node specific ICMP routines
-+ *
-+ * Authors:
-+ * Antti Tuominen <ajtuomin@tml.hut.fi>
-+ * Jaakko Laine <medved@iki.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/sched.h>
-+#include <net/ipv6.h>
-+#include <net/ip6_route.h>
-+#include <net/addrconf.h>
-+#include <net/mipv6.h>
-+
-+#include "mn.h"
-+#include "bul.h"
-+#include "mdetect.h"
-+#include "debug.h"
-+#include "mipv6_icmp.h"
-+#include "util.h"
-+//#include "prefix.h"
-+
-+#define INFINITY 0xffffffff
-+
-+/**
-+ * mipv6_icmpv6_paramprob - Parameter Problem ICMP error message handler
-+ * @skb: buffer containing ICMP error message
-+ *
-+ * Special Mobile IPv6 ICMP handling. If Mobile Node receives ICMP
-+ * Parameter Problem message when using a Home Address Option,
-+ * offending node should be logged and error message dropped. If
-+ * error is received because of a Binding Update, offending node
-+ * should be recorded in Binding Update List and no more Binding
-+ * Updates should be sent to this destination. See RFC 3775 section
-+ * 10.15.
-+ **/
-+int mipv6_icmpv6_rcv_paramprob(struct sk_buff *skb)
-+{
-+ struct icmp6hdr *phdr = (struct icmp6hdr *) skb->h.raw;
-+ struct in6_addr *saddr = skb ? &skb->nh.ipv6h->saddr : NULL;
-+ struct in6_addr *daddr = skb ? &skb->nh.ipv6h->daddr : NULL;
-+ struct ipv6hdr *hdr = (struct ipv6hdr *) (phdr + 1);
-+ int ulen = (skb->tail - (unsigned char *) (phdr + 1));
-+
-+ int errptr;
-+ __u8 *off_octet;
-+
-+ DEBUG_FUNC();
-+
-+ /* We only handle code 1 & 2 messages. */
-+ if (phdr->icmp6_code != ICMPV6_UNK_NEXTHDR &&
-+ phdr->icmp6_code != ICMPV6_UNK_OPTION)
-+ return 0;
-+
-+ /* Find offending octet in the original packet. */
-+ errptr = ntohl(phdr->icmp6_pointer);
-+
-+ /* There is not enough of the original packet left to figure
-+ * out what went wrong. Bail out. */
-+ if (ulen <= errptr)
-+ return 0;
-+
-+ off_octet = ((__u8 *) hdr + errptr);
-+ DEBUG(DBG_INFO, "Parameter problem: offending octet %d [0x%2x]",
-+ errptr, *off_octet);
-+
-+ /* If CN did not understand Mobility Header, set BUL entry to
-+ * ACK_ERROR so no further BUs are sumbitted to this CN. */
-+ if (phdr->icmp6_code == ICMPV6_UNK_NEXTHDR &&
-+ *off_octet == IPPROTO_MOBILITY) {
-+ struct bul_inval_args args;
-+ args.all_rr_states = 1;
-+ args.cn = saddr;
-+ args.mn = daddr;
-+ write_lock(&bul_lock);
-+ mipv6_bul_iterate(mn_bul_invalidate, &args);
-+ write_unlock(&bul_lock);
-+ }
-+
-+ /* If CN did not understand Home Address Option, we log an
-+ * error and discard the error message. */
-+ if (phdr->icmp6_code == ICMPV6_UNK_OPTION &&
-+ *off_octet == MIPV6_TLV_HOMEADDR) {
-+ DEBUG(DBG_WARNING, "Correspondent node does not "
-+ "implement Home Address Option receipt.");
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+/**
-+ * mipv6_mn_dhaad_send_req - Send DHAAD Request to home network
-+ * @home_addr: address to do DHAAD for
-+ * @plen: prefix length for @home_addr
-+ *
-+ * Send Dynamic Home Agent Address Discovery Request to the Home
-+ * Agents anycast address in the nodes home network.
-+ **/
-+void
-+mipv6_icmpv6_send_dhaad_req(struct in6_addr *home_addr, int plen, __u16 dhaad_id)
-+{
-+ struct in6_addr ha_anycast;
-+ struct in6_addr careofaddr;
-+
-+ if (mipv6_get_care_of_address(home_addr, &careofaddr) < 0) {
-+ DEBUG(DBG_WARNING, "Could not get node's Care-of Address");
-+ return;
-+ }
-+
-+ if (mipv6_ha_anycast(&ha_anycast, home_addr, plen) < 0) {
-+ DEBUG(DBG_WARNING,
-+ "Could not get Home Agent Anycast address for home address %x:%x.%x:%x:%x:%x:%x:%x/%d",
-+ NIPV6ADDR(home_addr), plen);
-+ return;
-+ }
-+
-+ mipv6_icmpv6_send(&ha_anycast, &careofaddr, MIPV6_DHAAD_REQUEST, 0,
-+ &dhaad_id, 0, NULL, 0);
-+
-+}
-+
-+/**
-+ * mipv6_icmpv6_dhaad_rep - Home Agent Address Discovery Reply ICMP handler
-+ * @skb: buffer containing ICMP information message
-+ *
-+ * Special Mobile IPv6 ICMP message. Handles Dynamic Home Agent
-+ * Address Discovery Reply messages.
-+ **/
-+int mipv6_icmpv6_rcv_dhaad_rep(struct sk_buff *skb)
-+{
-+ struct icmp6hdr *phdr = (struct icmp6hdr *) skb->h.raw;
-+ struct in6_addr *address;
-+ struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
-+ __u16 identifier;
-+ int ulen = (skb->tail - (unsigned char *) ((__u32 *) phdr + 2));
-+ int i;
-+ struct in6_addr home_addr, coa;
-+ struct in6_addr *first_ha = NULL;
-+ struct mn_info *minfo;
-+ int n_addr = ulen / sizeof(struct in6_addr);
-+
-+ DEBUG_FUNC();
-+
-+ /* Invalid packet checks. */
-+ if (ulen % sizeof(struct in6_addr) != 0)
-+ return 0;
-+
-+ if (phdr->icmp6_code != 0)
-+ return 0;
-+
-+ identifier = ntohs(phdr->icmp6_identifier);
-+ if (ulen > 0) {
-+ address = (struct in6_addr *) ((__u32 *) phdr + 2);
-+ } else {
-+ address = saddr;
-+ n_addr = 1;
-+ }
-+
-+ /* receive list of home agent addresses
-+ * add to home agents list
-+ */
-+ DEBUG(DBG_INFO, "DHAAD: got %d home agents", n_addr);
-+
-+ first_ha = address;
-+
-+ /* lookup H@ with identifier */
-+ read_lock(&mn_info_lock);
-+ minfo = mipv6_mninfo_get_by_id(identifier);
-+ if (!minfo) {
-+ read_unlock(&mn_info_lock);
-+ DEBUG(DBG_INFO, "no mninfo with id %d",
-+ identifier);
-+ return 0;
-+ }
-+ spin_lock(&minfo->lock);
-+
-+ /* Logic:
-+ * 1. if old HA on list, prefer it
-+ * 2. otherwise first HA on list prefered
-+ */
-+ for (i = 0; i < n_addr; i++) {
-+ DEBUG(DBG_INFO, "HA[%d] %x:%x:%x:%x:%x:%x:%x:%x",
-+ i, NIPV6ADDR(address));
-+ if (ipv6_addr_cmp(&minfo->ha, address) == 0) {
-+ spin_unlock(&minfo->lock);
-+ read_unlock(&mn_info_lock);
-+ return 0;
-+ }
-+ address++;
-+ }
-+ ipv6_addr_copy(&minfo->ha, first_ha);
-+ spin_unlock(&minfo->lock);
-+ ipv6_addr_copy(&home_addr, &minfo->home_addr);
-+ read_unlock(&mn_info_lock);
-+
-+ mipv6_get_care_of_address(&home_addr, &coa);
-+ init_home_registration(&home_addr, &coa);
-+
-+ return 1;
-+}
-+#if 0
-+/**
-+ * mipv6_icmpv6_handle_pfx_adv - handle prefix advertisements
-+ * @skb: sk_buff including the icmp6 message
-+ */
-+int mipv6_icmpv6_rcv_pfx_adv(struct sk_buff *skb)
-+{
-+ struct icmp6hdr *hdr = (struct icmp6hdr *) skb->h.raw;
-+ struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
-+ struct in6_addr *daddr = &skb->nh.ipv6h->daddr;
-+ __u8 *opt = (__u8 *) (hdr + 1);
-+ int optlen = (skb->tail - opt);
-+ unsigned long min_expire = INFINITY;
-+ struct inet6_skb_parm *parm = (struct inet6_skb_parm *) skb->cb;
-+
-+ DEBUG_FUNC();
-+
-+ while (optlen > 0) {
-+ int len = opt[1] << 3;
-+ if (len == 0)
-+ goto set_timer;
-+
-+ if (opt[0] == ND_OPT_PREFIX_INFO) {
-+ int ifindex;
-+ unsigned long expire;
-+ struct prefix_info *pinfo =
-+ (struct prefix_info *) opt;
-+ struct net_device *dev;
-+ struct mn_info *mninfo;
-+
-+ read_lock(&mn_info_lock);
-+ mninfo = mipv6_mninfo_get_by_ha(saddr);
-+ if (mninfo == NULL) {
-+ ifindex = 0;
-+ } else {
-+ spin_lock(&mninfo->lock);
-+ ifindex = mninfo->ifindex;
-+ spin_unlock(&mninfo->lock);
-+ mninfo = NULL;
-+ }
-+ read_unlock(&mn_info_lock);
-+
-+ if (!(dev = dev_get_by_index(ifindex))) {
-+ DEBUG(DBG_WARNING, "Cannot find device by index %d", parm->iif);
-+ goto nextopt;
-+ }
-+
-+ expire = ntohl(pinfo->valid);
-+ expire = expire == 0 ? INFINITY : expire;
-+
-+ min_expire = expire < min_expire ? expire : min_expire;
-+
-+ dev_put(dev);
-+ }
-+
-+nextopt:
-+ optlen -= len;
-+ opt += len;
-+ }
-+
-+set_timer:
-+
-+ mipv6_pfx_add_home(parm->iif, saddr, daddr, min_expire);
-+ return 0;
-+}
-+#endif
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/mn.c linux-2.4.25/net/ipv6/mobile_ip6/mn.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/mn.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/mn.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,1521 @@
-+/*
-+ * Mobile-node functionality
-+ *
-+ * Authors:
-+ * Sami Kivisaari <skivisaa@cc.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ *
-+ */
-+
-+#include <linux/autoconf.h>
-+#include <linux/sched.h>
-+#include <linux/ipv6.h>
-+#include <linux/net.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/if_arp.h>
-+#include <linux/ipsec.h>
-+#include <linux/notifier.h>
-+#include <linux/list.h>
-+#include <linux/route.h>
-+#include <linux/netfilter.h>
-+#include <linux/netfilter_ipv6.h>
-+#include <linux/tqueue.h>
-+#include <linux/proc_fs.h>
-+
-+#include <asm/uaccess.h>
-+
-+#include <net/ipv6.h>
-+#include <net/addrconf.h>
-+#include <net/neighbour.h>
-+#include <net/ndisc.h>
-+#include <net/ip6_route.h>
-+#include <net/mipglue.h>
-+
-+#include "util.h"
-+#include "mdetect.h"
-+#include "bul.h"
-+#include "mobhdr.h"
-+#include "debug.h"
-+#include "mn.h"
-+#include "mipv6_icmp.h"
-+#include "multiaccess_ctl.h"
-+//#include "prefix.h"
-+#include "tunnel_mn.h"
-+#include "stats.h"
-+#include "config.h"
-+
-+#define MIPV6_BUL_SIZE 128
-+
-+static LIST_HEAD(mn_info_list);
-+
-+/* Lock for list of MN infos */
-+rwlock_t mn_info_lock = RW_LOCK_UNLOCKED;
-+
-+static spinlock_t ifrh_lock = SPIN_LOCK_UNLOCKED;
-+
-+struct ifr_holder {
-+ struct list_head list;
-+ struct in6_ifreq ifr;
-+ int old_ifi;
-+ struct handoff *ho;
-+};
-+
-+LIST_HEAD(ifrh_list);
-+
-+static struct tq_struct mv_home_addr_task;
-+
-+/* Determines whether manually configured home addresses are preferred as
-+ * source addresses over dynamically configured ones
-+ */
-+int mipv6_use_preconfigured_hoaddr = 1;
-+
-+/* Determines whether home addresses, which are at home are preferred as
-+ * source addresses over other home addresses
-+ */
-+int mipv6_use_topol_corr_hoaddr = 0;
-+
-+static spinlock_t icmpv6_id_lock = SPIN_LOCK_UNLOCKED;
-+static __u16 icmpv6_id = 0;
-+
-+static inline __u16 mipv6_get_dhaad_id(void)
-+{
-+ __u16 ret;
-+ spin_lock_bh(&icmpv6_id_lock);
-+ ret = ++icmpv6_id;
-+ spin_unlock_bh(&icmpv6_id_lock);
-+ return ret;
-+}
-+
-+/**
-+ * mipv6_mninfo_get_by_home - Returns mn_info for a home address
-+ * @haddr: home address of MN
-+ *
-+ * Returns mn_info on success %NULL otherwise. Caller MUST hold
-+ * @mn_info_lock (read or write).
-+ **/
-+struct mn_info *mipv6_mninfo_get_by_home(struct in6_addr *haddr)
-+{
-+ struct list_head *lh;
-+ struct mn_info *minfo;
-+
-+ DEBUG_FUNC();
-+
-+ if (!haddr)
-+ return NULL;
-+
-+ list_for_each(lh, &mn_info_list) {
-+ minfo = list_entry(lh, struct mn_info, list);
-+ spin_lock(&minfo->lock);
-+ if (!ipv6_addr_cmp(&minfo->home_addr, haddr)) {
-+ spin_unlock(&minfo->lock);
-+ return minfo;
-+ }
-+ spin_unlock(&minfo->lock);
-+ }
-+ return NULL;
-+}
-+
-+/**
-+ * mipv6_mninfo_get_by_ha - Lookup mn_info with Home Agent address
-+ * @home_agent: Home Agent address
-+ *
-+ * Searches for a mn_info entry with @ha set to @home_agent. You MUST
-+ * hold @mn_info_lock when calling this function. Returns pointer to
-+ * mn_info entry or %NULL on failure.
-+ **/
-+struct mn_info *mipv6_mninfo_get_by_ha(struct in6_addr *home_agent)
-+{
-+ struct list_head *lh;
-+ struct mn_info *minfo;
-+
-+ if (!home_agent)
-+ return NULL;
-+
-+ list_for_each(lh, &mn_info_list) {
-+ minfo = list_entry(lh, struct mn_info, list);
-+ spin_lock(&minfo->lock);
-+ if (!ipv6_addr_cmp(&minfo->ha, home_agent)) {
-+ spin_unlock(&minfo->lock);
-+ return minfo;
-+ }
-+ spin_unlock(&minfo->lock);
-+ }
-+ return NULL;
-+}
-+
-+/**
-+ * mipv6_mninfo_get_by_id - Lookup mn_info with id
-+ * @id: DHAAD identifier
-+ *
-+ * Searches for a mn_info entry with @dhaad_id set to @id. You MUST
-+ * hold @mn_info_lock when calling this function. Returns pointer to
-+ * mn_info entry or %NULL on failure.
-+ **/
-+struct mn_info *mipv6_mninfo_get_by_id(unsigned short id)
-+{
-+ struct list_head *lh;
-+ struct mn_info *minfo = 0;
-+
-+ list_for_each(lh, &mn_info_list) {
-+ minfo = list_entry(lh, struct mn_info, list);
-+ spin_lock(&minfo->lock);
-+ if (minfo->dhaad_id == id) {
-+ spin_unlock(&minfo->lock);
-+ return minfo;
-+ }
-+ spin_unlock(&minfo->lock);
-+ }
-+ return NULL;
-+}
-+
-+/**
-+ * mipv6_mninfo_add - Adds a new home info for MN
-+ * @ifindex: Interface for home address
-+ * @home_addr: Home address of MN, must be set
-+ * @plen: prefix length of the home address, must be set
-+ * @isathome : home address at home
-+ * @lifetime: lifetime of the home address, 0 is infinite
-+ * @ha: home agent for the home address
-+ * @ha_plen: prefix length of home agent's address, can be zero
-+ * @ha_lifetime: Lifetime of the home address, 0 is infinite
-+ *
-+ * The function adds a new home info entry for MN, allowing it to
-+ * register the home address with the home agent. Starts home
-+ * registration process. If @ha is %ADDRANY, DHAAD is performed to
-+ * find a home agent. Returns 0 on success, a negative value
-+ * otherwise. Caller MUST NOT hold @mn_info_lock or
-+ * @addrconf_hash_lock.
-+ **/
-+void mipv6_mninfo_add(int ifindex, struct in6_addr *home_addr, int plen,
-+ int isathome, unsigned long lifetime, struct in6_addr *ha,
-+ int ha_plen, unsigned long ha_lifetime, int man_conf)
-+{
-+ struct mn_info *minfo;
-+ struct in6_addr coa;
-+
-+ DEBUG_FUNC();
-+
-+ write_lock_bh(&mn_info_lock);
-+ if ((minfo = mipv6_mninfo_get_by_home(home_addr)) != NULL){
-+ DEBUG(1, "MN info already exists");
-+ write_unlock_bh(&mn_info_lock);
-+ return;
-+ }
-+ minfo = kmalloc(sizeof(struct mn_info), GFP_ATOMIC);
-+ if (!minfo) {
-+ write_unlock_bh(&mn_info_lock);
-+ return;
-+ }
-+ memset(minfo, 0, sizeof(struct mn_info));
-+ spin_lock_init(&minfo->lock);
-+
-+
-+ ipv6_addr_copy(&minfo->home_addr, home_addr);
-+
-+ if (ha)
-+ ipv6_addr_copy(&minfo->ha, ha);
-+ if (ha_plen < 128 && ha_plen > 0)
-+ minfo->home_plen = ha_plen;
-+ else minfo->home_plen = 64;
-+
-+ minfo->ifindex_user = ifindex; /* Ifindex for tunnel interface */
-+ minfo->ifindex = ifindex; /* Interface on which home address is currently conf'd */
-+ /* TODO: we should get home address lifetime from somewhere */
-+ /* minfo->home_addr_expires = jiffies + lifetime * HZ; */
-+
-+ /* manual configuration flag cannot be unset by dynamic updates
-+ * from prefix advertisements
-+ */
-+ if (!minfo->man_conf) minfo->man_conf = man_conf;
-+ minfo->is_at_home = isathome;
-+
-+ list_add(&minfo->list, &mn_info_list);
-+ write_unlock_bh(&mn_info_lock);
-+
-+ if (mipv6_get_care_of_address(home_addr, &coa) == 0)
-+ init_home_registration(home_addr, &coa);
-+}
-+
-+/**
-+ * mipv6_mninfo_del - Delete home info for MN
-+ * @home_addr : Home address or prefix
-+ * @del_dyn_only : Delete only dynamically created home entries
-+ *
-+ * Deletes every mn_info entry that matches the first plen bits of
-+ * @home_addr. Returns number of deleted entries on success and a
-+ * negative value otherwise. Caller MUST NOT hold @mn_info_lock.
-+ **/
-+int mipv6_mninfo_del(struct in6_addr *home_addr, int del_dyn_only)
-+{
-+ struct list_head *lh, *next;
-+ struct mn_info *minfo;
-+ int ret = -1;
-+ if (!home_addr)
-+ return -1;
-+
-+ write_lock(&mn_info_lock);
-+
-+ list_for_each_safe(lh, next, &mn_info_list) {
-+ minfo = list_entry(lh, struct mn_info, list);
-+ if (ipv6_addr_cmp(&minfo->home_addr, home_addr) == 0
-+ && ((!minfo->man_conf && del_dyn_only) || !del_dyn_only)){
-+ list_del(&minfo->list);
-+ kfree(minfo);
-+ ret++;
-+ }
-+ }
-+ write_unlock(&mn_info_lock);
-+ return ret;
-+}
-+
-+void mipv6_mn_set_home(int ifindex, struct in6_addr *homeaddr, int plen,
-+ struct in6_addr *homeagent, int ha_plen)
-+{
-+ mipv6_mninfo_add(ifindex, homeaddr, plen, 0, 0,
-+ homeagent, ha_plen, 0, 1);
-+}
-+
-+static int skip_dad(struct in6_addr *addr)
-+{
-+ struct mn_info *minfo;
-+ int ret = 0;
-+
-+ if (addr == NULL) {
-+ DEBUG(DBG_CRITICAL, "Null argument");
-+ return 0;
-+ }
-+ read_lock_bh(&mn_info_lock);
-+ if ((minfo = mipv6_mninfo_get_by_home(addr)) != NULL) {
-+ if ((minfo->is_at_home != MN_NOT_AT_HOME) && (minfo->has_home_reg))
-+ ret = 1;
-+ DEBUG(DBG_INFO, "minfo->is_at_home = %d, minfo->has_home_reg = %d",
-+ minfo->is_at_home, minfo->has_home_reg);
-+ }
-+ read_unlock_bh(&mn_info_lock);
-+
-+ return ret;
-+}
-+/**
-+ * mipv6_mn_is_home_addr - Determines if addr is node's home address
-+ * @addr: IPv6 address
-+ *
-+ * Returns 1 if addr is node's home address. Otherwise returns zero.
-+ **/
-+int mipv6_mn_is_home_addr(struct in6_addr *addr)
-+{
-+ int ret = 0;
-+
-+ if (addr == NULL) {
-+ DEBUG(DBG_CRITICAL, "Null argument");
-+ return -1;
-+ }
-+ read_lock_bh(&mn_info_lock);
-+ if (mipv6_mninfo_get_by_home(addr))
-+ ret = 1;
-+ read_unlock_bh(&mn_info_lock);
-+
-+ return (ret);
-+}
-+
-+/**
-+ * mipv6_mn_is_at_home - determine if node is home for a home address
-+ * @home_addr : home address of MN
-+ *
-+ * Returns 1 if home address in question is in the home network, 0
-+ * otherwise. Caller MUST NOT not hold @mn_info_lock.
-+ **/
-+int mipv6_mn_is_at_home(struct in6_addr *home_addr)
-+{
-+ struct mn_info *minfo;
-+ int ret = 0;
-+ read_lock_bh(&mn_info_lock);
-+ if ((minfo = mipv6_mninfo_get_by_home(home_addr)) != NULL) {
-+ spin_lock(&minfo->lock);
-+ ret = (minfo->is_at_home == MN_AT_HOME);
-+ spin_unlock(&minfo->lock);
-+ }
-+ read_unlock_bh(&mn_info_lock);
-+ return ret;
-+}
-+void mipv6_mn_set_home_reg(struct in6_addr *home_addr, int has_home_reg)
-+{
-+ struct mn_info *minfo;
-+ read_lock_bh(&mn_info_lock);
-+
-+ if ((minfo = mipv6_mninfo_get_by_home(home_addr)) != NULL) {
-+ spin_lock(&minfo->lock);
-+ minfo->has_home_reg = has_home_reg;
-+ spin_unlock(&minfo->lock);
-+ }
-+ read_unlock_bh(&mn_info_lock);
-+}
-+
-+static int mn_inet6addr_event(
-+ struct notifier_block *nb, unsigned long event, void *ptr)
-+{
-+ struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)ptr;
-+
-+ switch (event) {
-+ case NETDEV_UP:
-+ /* Is address a valid coa ?*/
-+ if (!(ifp->flags & IFA_F_TENTATIVE))
-+ mipv6_mdet_finalize_ho(&ifp->addr,
-+ ifp->idev->dev->ifindex);
-+ else if(skip_dad(&ifp->addr))
-+ ifp->flags &= ~IFA_F_TENTATIVE;
-+ break;
-+ case NETDEV_DOWN:
-+#if 0
-+ /* This is useless with manually configured home
-+ addresses, which will not expire
-+ */
-+ mipv6_mninfo_del(&ifp->addr, 0);
-+#endif
-+ break;
-+
-+ }
-+
-+ return NOTIFY_DONE;
-+}
-+
-+struct notifier_block mipv6_mn_inet6addr_notifier = {
-+ mn_inet6addr_event,
-+ NULL,
-+ 0 /* check if using zero is ok */
-+};
-+
-+static void mipv6_get_saddr_hook(struct in6_addr *homeaddr)
-+{
-+ int found = 0, reiter = 0;
-+ struct list_head *lh;
-+ struct mn_info *minfo = NULL;
-+ struct in6_addr coa;
-+
-+ read_lock_bh(&mn_info_lock);
-+restart:
-+ list_for_each(lh, &mn_info_list) {
-+ minfo = list_entry(lh, struct mn_info, list);
-+ if ((ipv6_addr_scope(homeaddr) != ipv6_addr_scope(&minfo->home_addr))
-+ || ipv6_chk_addr(&minfo->home_addr, NULL) == 0)
-+ continue;
-+
-+ spin_lock(&minfo->lock);
-+ if (minfo->is_at_home == MN_AT_HOME || minfo->has_home_reg) {
-+ if ((mipv6_use_topol_corr_hoaddr &&
-+ minfo->is_at_home == MN_AT_HOME) ||
-+ (mipv6_use_preconfigured_hoaddr &&
-+ minfo->man_conf) ||
-+ (!(mipv6_use_preconfigured_hoaddr ||
-+ mipv6_use_topol_corr_hoaddr) || reiter)) {
-+ spin_unlock(&minfo->lock);
-+ ipv6_addr_copy(homeaddr, &minfo->home_addr);
-+ found = 1;
-+ break;
-+ }
-+ }
-+ spin_unlock(&minfo->lock);
-+ }
-+ if (!found && !reiter) {
-+ reiter = 1;
-+ goto restart;
-+ }
-+
-+ if (!found && minfo &&
-+ !mipv6_get_care_of_address(&minfo->home_addr, &coa)) {
-+ ipv6_addr_copy(homeaddr, &coa);
-+ }
-+ read_unlock_bh(&mn_info_lock);
-+
-+ DEBUG(DBG_DATADUMP, "Source address selection: %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(homeaddr));
-+ return;
-+}
-+
-+static void mv_home_addr(void *arg)
-+{
-+ mm_segment_t oldfs;
-+ int err = 0, new_if = 0;
-+ struct list_head *lh, *next;
-+ struct ifr_holder *ifrh;
-+ LIST_HEAD(list);
-+
-+ DEBUG(DBG_INFO, "mipv6 move home address task");
-+
-+ spin_lock_bh(&ifrh_lock);
-+ list_splice_init(&ifrh_list, &list);
-+ spin_unlock_bh(&ifrh_lock);
-+
-+ oldfs = get_fs(); set_fs(KERNEL_DS);
-+ list_for_each_safe(lh, next, &list) {
-+ ifrh = list_entry(lh, struct ifr_holder, list);
-+ if (ifrh->old_ifi) {
-+ new_if = ifrh->ifr.ifr6_ifindex;
-+ ifrh->ifr.ifr6_ifindex = ifrh->old_ifi;
-+ err = addrconf_del_ifaddr(&ifrh->ifr);
-+ ifrh->ifr.ifr6_ifindex = new_if;
-+ if (err < 0)
-+ DEBUG(DBG_WARNING, "removal of home address %x:%x:%x:%x:%x:%x:%x:%x from"
-+ " old interface %d failed with status %d",
-+ NIPV6ADDR(&ifrh->ifr.ifr6_addr), ifrh->old_ifi, err);
-+ }
-+ if(!err) {
-+ err = addrconf_add_ifaddr(&ifrh->ifr);
-+ }
-+ if (ifrh->ho) {
-+ DEBUG(DBG_INFO, "Calling mobile_node moved after moving home address to new if");
-+ mipv6_mobile_node_moved(ifrh->ho);
-+ }
-+ list_del(&ifrh->list);
-+ kfree(ifrh);
-+ }
-+ set_fs(oldfs);
-+
-+ if (err < 0)
-+ DEBUG(DBG_WARNING, "adding of home address to a new interface %d failed %d", new_if, err);
-+ else {
-+ DEBUG(DBG_WARNING, "adding of home address to a new interface OK");
-+ }
-+}
-+
-+struct dhaad_halist {
-+ struct list_head list;
-+ struct in6_addr addr;
-+ int retry;
-+};
-+
-+/* clear all has from candidate list. do this when a new dhaad reply
-+ * is received. */
-+int mipv6_mn_flush_ha_candidate(struct list_head *ha)
-+{
-+ struct list_head *p, *tmp;
-+ struct dhaad_halist *e;
-+
-+ list_for_each_safe(p, tmp, ha) {
-+ e = list_entry(p, struct dhaad_halist, list);
-+ list_del(p);
-+ kfree(e);
-+ e = NULL;
-+ }
-+ return 0;
-+}
-+
-+/* add new ha to candidates. only done when dhaad reply is received. */
-+int mipv6_mn_add_ha_candidate(struct list_head *ha, struct in6_addr *addr)
-+{
-+ struct dhaad_halist *e;
-+
-+ e = kmalloc(sizeof(*e), GFP_ATOMIC);
-+ memset(e, 0, sizeof(*e));
-+ ipv6_addr_copy(&e->addr, addr);
-+
-+ list_add_tail(&e->list, ha);
-+ return 0;
-+}
-+
-+#define MAX_RETRIES_PER_HA 3
-+
-+/* get next ha candidate. this is done when dhaad reply has been
-+ * received and we want to register with the best available ha. */
-+int mipv6_mn_get_ha_candidate(struct list_head *ha, struct in6_addr *addr)
-+{
-+ struct list_head *p;
-+
-+ list_for_each(p, ha) {
-+ struct dhaad_halist *e;
-+ e = list_entry(p, typeof(*e), list);
-+ if (e->retry >= 0 && e->retry < MAX_RETRIES_PER_HA) {
-+ ipv6_addr_copy(addr, &e->addr);
-+ return 0;
-+ }
-+ }
-+ return -1;
-+}
-+
-+/* change candidate status. if registration with ha fails, we
-+ * increase retry for ha candidate. if retry is >= 3 we set it to -1
-+ * (failed), do get_ha_candidate() again */
-+int mipv6_mn_try_ha_candidate(struct list_head *ha, struct in6_addr *addr)
-+{
-+ struct list_head *p;
-+
-+ list_for_each(p, ha) {
-+ struct dhaad_halist *e;
-+ e = list_entry(p, typeof(*e), list);
-+ if (ipv6_addr_cmp(addr, &e->addr) == 0) {
-+ if (e->retry >= MAX_RETRIES_PER_HA) e->retry = -1;
-+ else if (e->retry >= 0) e->retry++;
-+ return 0;
-+ }
-+ }
-+ return -1;
-+}
-+
-+/**
-+ * mipv6_mn_get_bulifetime - Get lifetime for a binding update
-+ * @home_addr: home address for BU
-+ * @coa: care-of address for BU
-+ * @flags: flags used for BU
-+ *
-+ * Returns maximum lifetime for BUs determined by the lifetime of
-+ * care-of address and the lifetime of home address.
-+ **/
-+__u32 mipv6_mn_get_bulifetime(struct in6_addr *home_addr, struct in6_addr *coa,
-+ __u8 flags)
-+{
-+ struct inet6_ifaddr *ifp_hoa, *ifp_coa;
-+ __u32 lifetime = (flags & MIPV6_BU_F_HOME ?
-+ HA_BU_DEF_LIFETIME : CN_BU_DEF_LIFETIME);
-+
-+ ifp_hoa = ipv6_get_ifaddr(home_addr, NULL);
-+ if(!ifp_hoa) {
-+ DEBUG(DBG_INFO, "home address missing");
-+ return 0;
-+ }
-+ if (!(ifp_hoa->flags & IFA_F_PERMANENT)){
-+ if (ifp_hoa->valid_lft)
-+ lifetime = min_t(__u32, lifetime, ifp_hoa->valid_lft);
-+ else
-+ DEBUG(DBG_ERROR, "Zero lifetime for home address");
-+ }
-+ in6_ifa_put(ifp_hoa);
-+
-+ ifp_coa = ipv6_get_ifaddr(coa, NULL);
-+ if (!ifp_coa) {
-+ DEBUG(DBG_INFO, "care-of address missing");
-+ return 0;
-+ }
-+ if (!(ifp_coa->flags & IFA_F_PERMANENT)) {
-+ if(ifp_coa->valid_lft)
-+ lifetime = min_t(__u32, lifetime, ifp_coa->valid_lft);
-+ else
-+ DEBUG(DBG_ERROR,
-+ "Zero lifetime for care-of address");
-+ }
-+ in6_ifa_put(ifp_coa);
-+
-+ DEBUG(DBG_INFO, "Lifetime for binding is %ld", lifetime);
-+ return lifetime;
-+}
-+
-+static int
-+mipv6_mn_tnl_rcv_send_bu_hook(struct ip6_tnl *t, struct sk_buff *skb)
-+{
-+ struct ipv6hdr *inner;
-+ struct ipv6hdr *outer = skb->nh.ipv6h;
-+ struct mn_info *minfo = NULL;
-+ __u32 lifetime;
-+ __u8 user_flags = 0;
-+
-+ DEBUG_FUNC();
-+
-+ if (!is_mip6_tnl(t))
-+ return IP6_TNL_ACCEPT;
-+
-+ if (!mip6node_cnf.accept_ret_rout) {
-+ DEBUG(DBG_INFO, "Return routability administratively disabled"
-+ " not doing route optimization");
-+ return IP6_TNL_ACCEPT;
-+ }
-+ if (!pskb_may_pull(skb, skb->h.raw-skb->data+sizeof(*inner)))
-+ return IP6_TNL_DROP;
-+
-+ inner = (struct ipv6hdr *)skb->h.raw;
-+
-+ read_lock(&mn_info_lock);
-+ minfo = mipv6_mninfo_get_by_home(&inner->daddr);
-+
-+ if (!minfo) {
-+ DEBUG(DBG_WARNING, "MN info missing");
-+ read_unlock(&mn_info_lock);
-+ return IP6_TNL_ACCEPT;
-+ }
-+ DEBUG(DBG_DATADUMP, "MIPV6 MN: Received a tunneled IPv6 packet"
-+ " to %x:%x:%x:%x:%x:%x:%x:%x,"
-+ " from %x:%x:%x:%x:%x:%x:%x:%x with\n tunnel header"
-+ "daddr: %x:%x:%x:%x:%x:%x:%x:%x,"
-+ "saddr: %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(&inner->daddr), NIPV6ADDR(&inner->saddr),
-+ NIPV6ADDR(&outer->daddr), NIPV6ADDR(&outer->saddr));
-+
-+ spin_lock(&minfo->lock);
-+
-+ /* We don't send bus in response to all tunneled packets */
-+
-+ if (!ipv6_addr_cmp(&minfo->ha, &inner->saddr)) {
-+ spin_unlock(&minfo->lock);
-+ read_unlock(&mn_info_lock);
-+ DEBUG(DBG_ERROR, "HA BUG: Received a tunneled packet "
-+ "originally sent by home agent, not sending BU");
-+ return IP6_TNL_ACCEPT;
-+ }
-+ spin_unlock(&minfo->lock);
-+ read_unlock(&mn_info_lock);
-+
-+ DEBUG(DBG_DATADUMP, "Sending BU to correspondent node");
-+
-+ user_flags |= mip6node_cnf.bu_cn_ack ? MIPV6_BU_F_ACK : 0;
-+
-+ if (inner->nexthdr != IPPROTO_DSTOPTS &&
-+ inner->nexthdr != IPPROTO_MOBILITY) {
-+ struct in6_addr coa;
-+ /* Don't start RR when receiving ICMP error messages */
-+ if (inner->nexthdr == IPPROTO_ICMPV6) {
-+ int ptr = (u8*)(inner+1) - skb->data;
-+ u8 type;
-+
-+ if (skb_copy_bits(skb,
-+ ptr+offsetof(struct icmp6hdr,
-+ icmp6_type),
-+ &type, 1)
-+ || !(type & ICMPV6_INFOMSG_MASK)) {
-+ return IP6_TNL_ACCEPT;
-+ }
-+ }
-+ lifetime = mipv6_mn_get_bulifetime(&inner->daddr,
-+ &outer->daddr, 0);
-+ if (lifetime &&
-+ !mipv6_get_care_of_address(&inner->daddr, &coa)) {
-+ write_lock(&bul_lock);
-+ mipv6_send_bu(&inner->daddr, &inner->saddr, &coa,
-+ INITIAL_BINDACK_TIMEOUT,
-+ MAX_BINDACK_TIMEOUT, 1,
-+ user_flags,
-+ lifetime, NULL);
-+ write_unlock(&bul_lock);
-+ }
-+ }
-+ DEBUG(DBG_DATADUMP, "setting rcv_tunnel flag in skb");
-+ skb->security |= MIPV6_RCV_TUNNEL;
-+ return IP6_TNL_ACCEPT;
-+}
-+
-+static struct ip6_tnl_hook_ops mipv6_mn_tnl_rcv_send_bu_ops = {
-+ {NULL, NULL},
-+ IP6_TNL_PRE_DECAP,
-+ IP6_TNL_PRI_FIRST,
-+ mipv6_mn_tnl_rcv_send_bu_hook
-+};
-+
-+static int
-+mipv6_mn_tnl_xmit_stats_hook(struct ip6_tnl *t, struct sk_buff *skb)
-+{
-+ DEBUG_FUNC();
-+ if (is_mip6_tnl(t))
-+ MIPV6_INC_STATS(n_encapsulations);
-+ return IP6_TNL_ACCEPT;
-+}
-+
-+static struct ip6_tnl_hook_ops mipv6_mn_tnl_xmit_stats_ops = {
-+ {NULL, NULL},
-+ IP6_TNL_PRE_ENCAP,
-+ IP6_TNL_PRI_LAST,
-+ mipv6_mn_tnl_xmit_stats_hook
-+};
-+
-+static int
-+mipv6_mn_tnl_rcv_stats_hook(struct ip6_tnl *t, struct sk_buff *skb)
-+{
-+ DEBUG_FUNC();
-+ if (is_mip6_tnl(t))
-+ MIPV6_INC_STATS(n_decapsulations);
-+ return IP6_TNL_ACCEPT;
-+}
-+
-+static struct ip6_tnl_hook_ops mipv6_mn_tnl_rcv_stats_ops = {
-+ {NULL, NULL},
-+ IP6_TNL_PRE_DECAP,
-+ IP6_TNL_PRI_LAST,
-+ mipv6_mn_tnl_rcv_stats_hook
-+};
-+
-+static void mn_check_tunneled_packet(struct sk_buff *skb)
-+{
-+ DEBUG_FUNC();
-+ /* If tunnel flag was set */
-+ if (skb->security & MIPV6_RCV_TUNNEL) {
-+ struct in6_addr coa;
-+ __u32 lifetime;
-+ __u8 user_flags = 0;
-+ int ptr = (u8*)(skb->nh.ipv6h+1) - skb->data;
-+ int len = skb->len - ptr;
-+ __u8 nexthdr = skb->nh.ipv6h->nexthdr;
-+
-+ if (len < 0)
-+ return;
-+
-+ ptr = ipv6_skip_exthdr(skb, ptr, &nexthdr, len);
-+ if (ptr < 0)
-+ return;
-+
-+ if (!mip6node_cnf.accept_ret_rout) {
-+ DEBUG(DBG_INFO, "Return routability administratively disabled");
-+ return;
-+ }
-+ if (nexthdr == IPPROTO_MOBILITY)
-+ return;
-+
-+ /* Don't start RR when receiving ICMP error messages */
-+ if (nexthdr == IPPROTO_ICMPV6) {
-+ u8 type;
-+
-+ if (skb_copy_bits(skb,
-+ ptr+offsetof(struct icmp6hdr,
-+ icmp6_type),
-+ &type, 1)
-+ || !(type & ICMPV6_INFOMSG_MASK)) {
-+ return;
-+ }
-+ }
-+ user_flags |= mip6node_cnf.bu_cn_ack ? MIPV6_BU_F_ACK : 0;
-+ mipv6_get_care_of_address(&skb->nh.ipv6h->daddr, &coa);
-+ lifetime = mipv6_mn_get_bulifetime(&skb->nh.ipv6h->daddr,
-+ &coa, 0);
-+
-+ DEBUG(DBG_WARNING, "packet to address %x:%x:%x:%x:%x:%x:%x:%x"
-+ "was tunneled. Sending BU to CN"
-+ "%x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(&skb->nh.ipv6h->daddr),
-+ NIPV6ADDR(&skb->nh.ipv6h->saddr));
-+ /* This should work also with home address option */
-+
-+ write_lock(&bul_lock);
-+ mipv6_send_bu(&skb->nh.ipv6h->daddr, &skb->nh.ipv6h->saddr,
-+ &coa, INITIAL_BINDACK_TIMEOUT,
-+ MAX_BINDACK_TIMEOUT, 1, user_flags,
-+ lifetime, NULL);
-+ write_unlock(&bul_lock);
-+ }
-+}
-+
-+static int sched_mv_home_addr_task(struct in6_addr *haddr, int plen_new,
-+ int newif, int oldif, struct handoff *ho)
-+{
-+ int alloc_size;
-+ struct ifr_holder *ifrh;
-+
-+ alloc_size = sizeof(*ifrh) + (ho ? sizeof(*ho): 0);
-+ if ((ifrh = kmalloc(alloc_size, GFP_ATOMIC)) == NULL) {
-+ DEBUG(DBG_ERROR, "Out of memory");
-+ return -1;
-+ }
-+ if (ho) {
-+ ifrh->ho = (struct handoff *)((struct ifr_holder *)(ifrh + 1));
-+ memcpy(ifrh->ho, ho, sizeof(*ho));
-+ } else
-+ ifrh->ho = NULL;
-+
-+ /* must queue task to avoid deadlock with rtnl */
-+ ifrh->ifr.ifr6_ifindex = newif;
-+ ifrh->ifr.ifr6_prefixlen = plen_new;
-+ ipv6_addr_copy(&ifrh->ifr.ifr6_addr, haddr);
-+ ifrh->old_ifi = oldif;
-+
-+ spin_lock_bh(&ifrh_lock);
-+ list_add_tail(&ifrh->list, &ifrh_list);
-+ spin_unlock_bh(&ifrh_lock);
-+
-+ schedule_task(&mv_home_addr_task);
-+
-+ return 0;
-+}
-+
-+static void send_ret_home_ns(struct in6_addr *ha_addr,
-+ struct in6_addr *home_addr,
-+ int ifindex)
-+{
-+ struct in6_addr nil;
-+ struct in6_addr mcaddr;
-+ struct net_device *dev = dev_get_by_index(ifindex);
-+ if (!dev)
-+ return;
-+ memset(&nil, 0, sizeof(nil));
-+ addrconf_addr_solict_mult(home_addr, &mcaddr);
-+ ndisc_send_ns(dev, NULL, home_addr, &mcaddr, &nil);
-+ dev_put(dev);
-+}
-+
-+static inline int ha_is_reachable(int ifindex, struct in6_addr *ha)
-+{
-+ struct net_device *dev;
-+ int reachable = 0;
-+
-+ dev = dev_get_by_index(ifindex);
-+ if (dev) {
-+ struct neighbour *neigh;
-+ if ((neigh = ndisc_get_neigh(dev, ha)) != NULL) {
-+ read_lock_bh(&neigh->lock);
-+ if (neigh->nud_state&NUD_VALID)
-+ reachable = 1;
-+ read_unlock_bh(&neigh->lock);
-+ neigh_release(neigh);
-+ }
-+ dev_put(dev);
-+ }
-+ return reachable;
-+}
-+
-+static int mn_ha_handoff(struct handoff *ho)
-+{
-+ struct list_head *lh;
-+ struct mn_info *minfo;
-+ struct in6_addr *coa= ho->coa;
-+ int wait_mv_home = 0;
-+
-+ read_lock_bh(&mn_info_lock);
-+ list_for_each(lh, &mn_info_list) {
-+ __u8 has_home_reg;
-+ int ifindex;
-+ struct in6_addr ha;
-+ __u8 athome;
-+ __u32 lifetime;
-+ struct mipv6_bul_entry *entry = NULL;
-+
-+ minfo = list_entry(lh, struct mn_info, list);
-+ spin_lock(&minfo->lock);
-+ has_home_reg = minfo->has_home_reg;
-+ ifindex = minfo->ifindex;
-+ ipv6_addr_copy(&ha, &minfo->ha);
-+
-+ if (mipv6_prefix_compare(&ho->rtr_addr, &minfo->home_addr,
-+ ho->plen)) {
-+ if (minfo->has_home_reg)
-+ athome = minfo->is_at_home = MN_RETURNING_HOME;
-+ else
-+ athome = minfo->is_at_home = MN_AT_HOME;
-+ coa = &minfo->home_addr;
-+
-+ spin_unlock(&minfo->lock);
-+#if 0
-+ /* Cancel prefix solicitation, rtr is our HA */
-+ mipv6_pfx_cancel_send(&ho->rtr_addr, ifindex);
-+#endif
-+ minfo->ifindex = ho->ifindex;
-+
-+ if (minfo->has_home_reg &&
-+ !ha_is_reachable(ho->ifindex, &minfo->ha)) {
-+ send_ret_home_ns(&minfo->ha,
-+ &minfo->home_addr,
-+ ho->ifindex);
-+ mipv6_mdet_set_curr_rtr_reachable(0);
-+ wait_mv_home++;
-+ }
-+ if (ifindex != ho->ifindex){
-+ wait_mv_home++;
-+ DEBUG(DBG_INFO,
-+ "Moving home address back to "
-+ "the home interface");
-+ sched_mv_home_addr_task(&minfo->home_addr,
-+ 128,
-+ ho->ifindex,
-+ ifindex, ho);
-+ }
-+ if (!has_home_reg || wait_mv_home)
-+ continue;
-+
-+ lifetime = 0;
-+
-+ } else {
-+ athome = minfo->is_at_home = MN_NOT_AT_HOME;
-+ if (minfo->ifindex_user != minfo->ifindex) {
-+ DEBUG(DBG_INFO, "Scheduling home address move to virtual interface");
-+ sched_mv_home_addr_task(&minfo->home_addr,
-+ 128,
-+ minfo->ifindex_user,
-+ minfo->ifindex, ho); /* Is minfo->ifindex correct */
-+
-+ wait_mv_home++;
-+ }
-+ minfo->ifindex = minfo->ifindex_user;
-+ spin_unlock(&minfo->lock);
-+ if (wait_mv_home)
-+ continue;
-+ if (!has_home_reg &&
-+ init_home_registration(&minfo->home_addr,
-+ ho->coa)) {
-+ continue;
-+ }
-+ lifetime = mipv6_mn_get_bulifetime(&minfo->home_addr,
-+ ho->coa,
-+ MIPV6_BU_F_HOME);
-+
-+ }
-+ write_lock(&bul_lock);
-+ if (!(entry = mipv6_bul_get(&ha, &minfo->home_addr)) ||
-+ !(entry->flags & MIPV6_BU_F_HOME)) {
-+ DEBUG(DBG_ERROR,
-+ "Unable to find home registration for "
-+ "home address: %x:%x:%x:%x:%x:%x:%x:%x!\n",
-+ NIPV6ADDR(&minfo->home_addr));
-+ write_unlock(&bul_lock);
-+ continue;
-+ }
-+ DEBUG(DBG_INFO, "Sending home de ? %d registration for "
-+ "home address: %x:%x:%x:%x:%x:%x:%x:%x\n"
-+ "to home agent %x:%x:%x:%x:%x:%x:%x:%x, "
-+ "with lifetime %ld",
-+ (athome != MN_NOT_AT_HOME),
-+ NIPV6ADDR(&entry->home_addr),
-+ NIPV6ADDR(&entry->cn_addr), lifetime);
-+ mipv6_send_bu(&entry->home_addr, &entry->cn_addr,
-+ coa, INITIAL_BINDACK_TIMEOUT,
-+ MAX_BINDACK_TIMEOUT, 1, entry->flags,
-+ lifetime, NULL);
-+ write_unlock(&bul_lock);
-+
-+ }
-+ read_unlock_bh(&mn_info_lock);
-+ return wait_mv_home;
-+}
-+/**
-+ * mn_cn_handoff - called for every bul entry to send BU to CN
-+ * @rawentry: bul entry
-+ * @args: handoff event
-+ * @sortkey:
-+ *
-+ * Since MN can have many home addresses and home networks, every BUL
-+ * entry needs to be checked
-+ **/
-+int mn_cn_handoff(void *rawentry, void *args, unsigned long *sortkey)
-+{
-+ struct mipv6_bul_entry *entry = (struct mipv6_bul_entry *)rawentry;
-+ struct in6_addr *coa = (struct in6_addr *)args;
-+
-+ DEBUG_FUNC();
-+
-+ /* Home registrations already handled by mn_ha_handoff */
-+ if (entry->flags & MIPV6_BU_F_HOME)
-+ return ITERATOR_CONT;
-+
-+ /* BUL is locked by mipv6_mobile_node_moved which calls us
-+ through mipv6_bul_iterate */
-+
-+ if (mipv6_prefix_compare(coa,
-+ &entry->home_addr,
-+ 64)) {
-+ mipv6_send_bu(&entry->home_addr, &entry->cn_addr,
-+ &entry->home_addr, INITIAL_BINDACK_TIMEOUT,
-+ MAX_BINDACK_TIMEOUT, 1, entry->flags, 0,
-+ NULL);
-+ } else {
-+ u32 lifetime = mipv6_mn_get_bulifetime(&entry->home_addr,
-+ coa,
-+ entry->flags);
-+ mipv6_send_bu(&entry->home_addr, &entry->cn_addr,
-+ coa, INITIAL_BINDACK_TIMEOUT,
-+ MAX_BINDACK_TIMEOUT, 1, entry->flags,
-+ lifetime, NULL);
-+ }
-+ return ITERATOR_CONT;
-+}
-+
-+
-+int mn_bul_invalidate(void *rawentry, void *args, unsigned long *sortkey)
-+{
-+ struct mipv6_bul_entry *bul = (struct mipv6_bul_entry *)rawentry;
-+ struct bul_inval_args *arg = (struct bul_inval_args *)args;
-+
-+ DEBUG_FUNC();
-+
-+ if (!ipv6_addr_cmp(arg->cn, &bul->cn_addr) &&
-+ (!ipv6_addr_cmp(arg->mn, &bul->home_addr) ||
-+ !ipv6_addr_cmp(arg->mn, &bul->coa))) {
-+ if (arg->all_rr_states || !bul->rr ||
-+ (bul->rr->rr_state != RR_INIT &&
-+ bul->rr->rr_state != RR_DONE)) {
-+ bul->state = ACK_ERROR;
-+ bul->callback = bul_entry_expired;
-+ bul->callback_time = jiffies +
-+ DUMB_CN_BU_LIFETIME * HZ;
-+ bul->expire = bul->callback_time;
-+ DEBUG(DBG_INFO, "BUL entry set to ACK_ERROR");
-+ mipv6_bul_reschedule(bul);
-+ }
-+ }
-+ return ITERATOR_CONT;
-+}
-+/**
-+ * init_home_registration - start Home Registration process
-+ * @home_addr: home address
-+ * @coa: care-of address
-+ *
-+ * Checks whether we have a Home Agent address for this home address.
-+ * If not starts Dynamic Home Agent Address Discovery. Otherwise
-+ * tries to register with home agent if not already registered.
-+ * Returns 1, if home registration process is started and 0 otherwise
-+ **/
-+int init_home_registration(struct in6_addr *home_addr, struct in6_addr *coa)
-+{
-+ struct mn_info *hinfo;
-+ struct in6_addr ha;
-+ __u8 man_conf;
-+ int ifindex;
-+ __u32 lifetime;
-+ __u8 user_flags = 0, flags;
-+
-+ DEBUG_FUNC();
-+
-+ read_lock_bh(&mn_info_lock);
-+ if ((hinfo = mipv6_mninfo_get_by_home(home_addr)) == NULL) {
-+ DEBUG(DBG_ERROR, "No mn_info found for address: "
-+ "%x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(home_addr));
-+ read_unlock_bh(&mn_info_lock);
-+ return -ENOENT;
-+ }
-+ spin_lock(&hinfo->lock);
-+ if (mipv6_prefix_compare(&hinfo->home_addr, coa, hinfo->home_plen)) {
-+ spin_unlock(&hinfo->lock);
-+ read_unlock_bh(&mn_info_lock);
-+ DEBUG(DBG_INFO, "Adding home address, MN at home");
-+ return 1;
-+ }
-+ if (ipv6_addr_any(&hinfo->ha)) {
-+ int dhaad_id = mipv6_get_dhaad_id();
-+ hinfo->dhaad_id = dhaad_id;
-+ spin_unlock(&hinfo->lock);
-+ mipv6_icmpv6_send_dhaad_req(home_addr, hinfo->home_plen, dhaad_id);
-+ read_unlock_bh(&mn_info_lock);
-+ DEBUG(DBG_INFO,
-+ "Home Agent address not set, initiating DHAAD");
-+ return 1;
-+ }
-+ ipv6_addr_copy(&ha, &hinfo->ha);
-+ man_conf = hinfo->man_conf;
-+ ifindex = hinfo->ifindex;
-+ spin_unlock(&hinfo->lock);
-+ read_unlock_bh(&mn_info_lock);
-+#if 0
-+ if (man_conf)
-+ mipv6_pfx_add_ha(&ha, coa, ifindex);
-+#endif
-+ if (mipv6_bul_exists(&ha, home_addr)) {
-+ DEBUG(DBG_INFO, "BU already sent to HA");
-+ return 0;
-+ }
-+ /* user flags received through sysctl */
-+ user_flags |= mip6node_cnf.bu_lladdr ? MIPV6_BU_F_LLADDR : 0;
-+ user_flags |= mip6node_cnf.bu_keymgm ? MIPV6_BU_F_KEYMGM : 0;
-+
-+ flags = MIPV6_BU_F_HOME | MIPV6_BU_F_ACK | user_flags;
-+
-+ lifetime = mipv6_mn_get_bulifetime(home_addr, coa, flags);
-+
-+ DEBUG(DBG_INFO, "Sending initial home registration for "
-+ "home address: %x:%x:%x:%x:%x:%x:%x:%x\n"
-+ "to home agent %x:%x:%x:%x:%x:%x:%x:%x, "
-+ "with lifetime %ld, prefixlength %d",
-+ NIPV6ADDR(home_addr), NIPV6ADDR(&ha), lifetime, 0);
-+
-+ write_lock_bh(&bul_lock);
-+ mipv6_send_bu(home_addr, &ha, coa, INITIAL_BINDACK_DAD_TIMEOUT,
-+ MAX_BINDACK_TIMEOUT, 1, flags, lifetime, NULL);
-+ write_unlock_bh(&bul_lock);
-+
-+ return 1;
-+}
-+
-+/**
-+ * mipv6_mobile_node_moved - Send BUs to all HAs and CNs
-+ * @ho: handoff structure contains the new and previous routers
-+ *
-+ * Event for handoff. Sends BUs everyone on Binding Update List.
-+ **/
-+int mipv6_mobile_node_moved(struct handoff *ho)
-+{
-+#if 0
-+ int bu_to_prev_router = 1;
-+#endif
-+ int dummy;
-+
-+ DEBUG_FUNC();
-+
-+ ma_ctl_upd_iface(ho->ifindex,
-+ MA_IFACE_CURRENT | MA_IFACE_HAS_ROUTER, &dummy);
-+
-+ /* First send BU to HA, then to all other nodes that are on BU list */
-+ if (mn_ha_handoff(ho) != 0)
-+ return 0; /* Wait for move home address task */
-+#if 0
-+ /* Add current care-of address to mn_info list, if current router acts
-+ as a HA.*/
-+
-+ if (ho->home_address && bu_to_prev_router)
-+ mipv6_mninfo_add(ho->coa, ho->plen,
-+ MN_AT_HOME, 0, &ho->rtr_addr,
-+ ho->plen, ROUTER_BU_DEF_LIFETIME,
-+ 0);
-+
-+#endif
-+ return 0;
-+}
-+
-+/**
-+ * mipv6_mn_send_home_na - send NA when returning home
-+ * @haddr: home address to advertise
-+ *
-+ * After returning home, MN must advertise all its valid addresses in
-+ * home link to all nodes.
-+ **/
-+void mipv6_mn_send_home_na(struct in6_addr *haddr)
-+{
-+ struct net_device *dev = NULL;
-+ struct in6_addr mc_allnodes;
-+ struct mn_info *hinfo = NULL;
-+
-+ read_lock(&mn_info_lock);
-+ hinfo = mipv6_mninfo_get_by_home(haddr);
-+ if (!hinfo) {
-+ read_unlock(&mn_info_lock);
-+ return;
-+ }
-+ spin_lock(&hinfo->lock);
-+ hinfo->is_at_home = MN_AT_HOME;
-+ dev = dev_get_by_index(hinfo->ifindex);
-+ spin_unlock(&hinfo->lock);
-+ read_unlock(&mn_info_lock);
-+ if (dev == NULL) {
-+ DEBUG(DBG_ERROR, "Send home_na: device not found.");
-+ return;
-+ }
-+
-+ ipv6_addr_all_nodes(&mc_allnodes);
-+ ndisc_send_na(dev, NULL, &mc_allnodes, haddr, 0, 0, 1, 1);
-+ dev_put(dev);
-+}
-+
-+static int mn_use_hao(struct in6_addr *daddr, struct in6_addr *saddr)
-+{
-+ struct mipv6_bul_entry *entry;
-+ struct mn_info *minfo = NULL;
-+ int add_ha = 0;
-+
-+ read_lock_bh(&mn_info_lock);
-+ minfo = mipv6_mninfo_get_by_home(saddr);
-+ if (minfo && minfo->is_at_home != MN_AT_HOME) {
-+ read_lock_bh(&bul_lock);
-+ if ((entry = mipv6_bul_get(daddr, saddr)) == NULL) {
-+ read_unlock_bh(&bul_lock);
-+ read_unlock_bh(&mn_info_lock);
-+ return add_ha;
-+ }
-+ add_ha = (entry->state != ACK_ERROR &&
-+ (!entry->rr || entry->rr->rr_state == RR_DONE ||
-+ entry->flags & MIPV6_BU_F_HOME));
-+ read_unlock_bh(&bul_lock);
-+ }
-+ read_unlock_bh(&mn_info_lock);
-+ return add_ha;
-+}
-+
-+static int
-+mn_dev_event(struct notifier_block *nb, unsigned long event, void *ptr)
-+{
-+ struct net_device *dev = ptr;
-+ struct list_head *lh;
-+ struct mn_info *minfo;
-+ int newif = 0;
-+
-+ /* here are probably the events we need to worry about */
-+ switch (event) {
-+ case NETDEV_UP:
-+ DEBUG(DBG_DATADUMP, "New netdevice %s registered.", dev->name);
-+ if (dev->type != ARPHRD_LOOPBACK && !dev_is_mip6_tnl(dev))
-+ ma_ctl_add_iface(dev->ifindex);
-+
-+ break;
-+ case NETDEV_GOING_DOWN:
-+ DEBUG(DBG_DATADUMP, "Netdevice %s disappeared.", dev->name);
-+ /*
-+ * Go through mn_info list and move all home addresses on the
-+ * netdev going down to a new device. This will make it
-+ * practically impossible for the home address to return home,
-+ * but allow MN to retain its connections using the address.
-+ */
-+
-+ read_lock_bh(&mn_info_lock);
-+ list_for_each(lh, &mn_info_list) {
-+ minfo = list_entry(lh, struct mn_info, list);
-+ spin_lock(&minfo->lock);
-+ if (minfo->ifindex == dev->ifindex) {
-+ if (sched_mv_home_addr_task(&minfo->home_addr, 128,
-+ minfo->ifindex_user,
-+ 0, NULL) < 0) {
-+ minfo->ifindex = 0;
-+ spin_unlock(&minfo->lock);
-+ read_unlock_bh(&mn_info_lock);
-+ return NOTIFY_DONE;
-+ } else {
-+ minfo->ifindex = minfo->ifindex_user;
-+ if (minfo->is_at_home) {
-+ minfo->is_at_home = 0;
-+
-+ }
-+ newif = minfo->ifindex_user;
-+ }
-+ }
-+ spin_unlock(&minfo->lock);
-+ }
-+
-+ read_unlock_bh(&mn_info_lock);
-+ }
-+ ma_ctl_upd_iface(dev->ifindex, MA_IFACE_NOT_PRESENT, &newif);
-+ mipv6_mdet_del_if(dev->ifindex);
-+
-+ return NOTIFY_DONE;
-+}
-+
-+struct notifier_block mipv6_mn_dev_notifier = {
-+ mn_dev_event,
-+ NULL,
-+ 0 /* check if using zero is ok */
-+};
-+
-+static void deprecate_addr(struct mn_info *minfo)
-+{
-+ /*
-+ * Lookup address from IPv6 address list and set deprecated flag
-+ */
-+
-+}
-+
-+/*
-+ * Required because we can only modify addresses after the packet is
-+ * constructed. We otherwise mess with higher level protocol
-+ * pseudoheaders. With strict protocol layering life would be SO much
-+ * easier!
-+ */
-+static unsigned int modify_xmit_addrs(unsigned int hooknum,
-+ struct sk_buff **pskb,
-+ const struct net_device *in,
-+ const struct net_device *out,
-+ int (*okfn) (struct sk_buff *))
-+{
-+ struct sk_buff *skb = *pskb;
-+
-+ DEBUG_FUNC();
-+
-+ if (skb) {
-+ struct ipv6hdr *hdr = skb->nh.ipv6h;
-+ struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
-+ struct mipv6_bul_entry *bule;
-+ struct in6_addr *daddr;
-+
-+ if (!ipv6_addr_any(&opt->hoa))
-+ daddr = &opt->hoa;
-+ else
-+ daddr = &hdr->daddr;
-+
-+ /* We don't consult bul when sending a BU to avoid deadlock, since
-+ * BUL is already locked.
-+ */
-+
-+
-+ if (opt->mipv6_flags & MIPV6_SND_HAO &&
-+ !(opt->mipv6_flags & MIPV6_SND_BU)) {
-+ write_lock(&bul_lock);
-+ bule = mipv6_bul_get(daddr, &hdr->saddr);
-+ if (!bule) {
-+ write_unlock(&bul_lock);
-+ return NF_ACCEPT;
-+ }
-+ if (!bule->rr || bule->rr->rr_state == RR_DONE ||
-+ bule->flags & MIPV6_BU_F_HOME) {
-+ DEBUG(DBG_DATADUMP,
-+ "Replace source address with CoA and reroute");
-+ ipv6_addr_copy(&hdr->saddr, &bule->coa);
-+ skb->nfcache |= NFC_ALTERED;
-+ }
-+ write_unlock(&bul_lock);
-+ } else if (opt->mipv6_flags & MIPV6_SND_HAO) {
-+ mipv6_get_care_of_address(&hdr->saddr, &hdr->saddr);
-+ skb->nfcache |= NFC_ALTERED;
-+ }
-+ }
-+ return NF_ACCEPT;
-+}
-+
-+/* We set a netfilter hook so that we can modify outgoing packet's
-+ * source addresses
-+ */
-+struct nf_hook_ops addr_modify_hook_ops = {
-+ {NULL, NULL}, /* List head, no predecessor, no successor */
-+ modify_xmit_addrs,
-+ PF_INET6,
-+ NF_IP6_LOCAL_OUT,
-+ NF_IP6_PRI_FIRST /* Should be of EXTREMELY high priority since we
-+ * do not want to mess with IPSec (possibly
-+ * implemented as packet filter)
-+ */
-+};
-+
-+#define MN_INFO_LEN 77
-+
-+static int mn_proc_info(char *buffer, char **start, off_t offset,
-+ int length)
-+{
-+ struct list_head *p;
-+ struct mn_info *minfo;
-+ int len = 0, skip = 0;
-+
-+ DEBUG_FUNC();
-+
-+ read_lock_bh(&mn_info_lock);
-+ list_for_each(p, &mn_info_list) {
-+ if (len < offset / MN_INFO_LEN) {
-+ skip++;
-+ continue;
-+ }
-+ if (len >= length)
-+ break;
-+ minfo = list_entry(p, struct mn_info, list);
-+ spin_lock(&minfo->lock);
-+ len += sprintf(buffer + len, "%02d %08x%08x%08x%08x %02x "
-+ "%08x%08x%08x%08x %d %d\n",
-+ minfo->ifindex,
-+ ntohl(minfo->home_addr.s6_addr32[0]),
-+ ntohl(minfo->home_addr.s6_addr32[1]),
-+ ntohl(minfo->home_addr.s6_addr32[2]),
-+ ntohl(minfo->home_addr.s6_addr32[3]),
-+ minfo->home_plen,
-+ ntohl(minfo->ha.s6_addr32[0]),
-+ ntohl(minfo->ha.s6_addr32[1]),
-+ ntohl(minfo->ha.s6_addr32[2]),
-+ ntohl(minfo->ha.s6_addr32[3]),
-+ minfo->is_at_home, minfo->has_home_reg);
-+ spin_unlock(&minfo->lock);
-+ }
-+ read_unlock_bh(&mn_info_lock);
-+
-+ *start = buffer;
-+ if (offset)
-+ *start += offset % MN_INFO_LEN;
-+
-+ len -= offset % MN_INFO_LEN;
-+
-+ if (len > length)
-+ len = length;
-+ if (len < 0)
-+ len = 0;
-+
-+ return len;
-+}
-+
-+int mipv6_mn_ha_nd_update(struct net_device *dev,
-+ struct in6_addr *ha, u8 *lladdr)
-+{
-+ int valid = 0;
-+ struct neighbour *neigh;
-+ if ((neigh = ndisc_get_neigh(dev, ha))) {
-+ read_lock(&neigh->lock);
-+ valid = neigh->nud_state & NUD_VALID;
-+ read_unlock(&neigh->lock);
-+ if (!valid && lladdr)
-+ neigh_update(neigh, lladdr, NUD_REACHABLE, 0, 1);
-+ neigh_release(neigh);
-+ }
-+ return valid;
-+}
-+
-+int mipv6_mn_ha_probe(struct inet6_ifaddr *ifp, u8 *lladdr)
-+{
-+ struct mn_info *minfo;
-+
-+ if (!(minfo = mipv6_mninfo_get_by_home(&ifp->addr)) ||
-+ ipv6_addr_any(&minfo->ha))
-+ return 0;
-+
-+ if (mipv6_mn_ha_nd_update(ifp->idev->dev, &minfo->ha, lladdr))
-+ mipv6_mdet_retrigger_ho();
-+ return 1;
-+}
-+
-+int __init mipv6_mn_init(void)
-+{
-+ struct net_device *dev;
-+
-+ DEBUG_FUNC();
-+
-+ if (mipv6_add_tnl_to_ha())
-+ return -ENODEV;
-+
-+ mipv6_bul_init(MIPV6_BUL_SIZE);
-+ mip6_fn.mn_use_hao = mn_use_hao;
-+ mip6_fn.mn_check_tunneled_packet = mn_check_tunneled_packet;
-+ INIT_TQUEUE(&mv_home_addr_task, mv_home_addr, NULL);
-+
-+ ma_ctl_init();
-+ for (dev = dev_base; dev; dev = dev->next) {
-+ if (dev->flags & IFF_UP &&
-+ dev->type != ARPHRD_LOOPBACK && !dev_is_mip6_tnl(dev)) {
-+ ma_ctl_add_iface(dev->ifindex);
-+ }
-+ }
-+ DEBUG(DBG_INFO, "Multiaccess support initialized");
-+
-+ register_netdevice_notifier(&mipv6_mn_dev_notifier);
-+ register_inet6addr_notifier(&mipv6_mn_inet6addr_notifier);
-+
-+ ip6ip6_tnl_register_hook(&mipv6_mn_tnl_rcv_send_bu_ops);
-+ ip6ip6_tnl_register_hook(&mipv6_mn_tnl_xmit_stats_ops);
-+ ip6ip6_tnl_register_hook(&mipv6_mn_tnl_rcv_stats_ops);
-+
-+ MIPV6_SETCALL(mipv6_set_home, mipv6_mn_set_home);
-+
-+ mipv6_initialize_mdetect();
-+
-+ /* COA to home transformation hook */
-+ MIPV6_SETCALL(mipv6_get_home_address, mipv6_get_saddr_hook);
-+ MIPV6_SETCALL(mipv6_mn_ha_probe, mipv6_mn_ha_probe);
-+ MIPV6_SETCALL(mipv6_is_home_addr, mipv6_mn_is_home_addr);
-+ proc_net_create("mip6_mninfo", 0, mn_proc_info);
-+ /* Set packet modification hook (source addresses) */
-+ nf_register_hook(&addr_modify_hook_ops);
-+
-+ return 0;
-+}
-+
-+void __exit mipv6_mn_exit(void)
-+{
-+ struct list_head *lh, *tmp;
-+ struct mn_info *minfo;
-+ DEBUG_FUNC();
-+
-+ mip6_fn.mn_use_hao = NULL;
-+ mip6_fn.mn_check_tunneled_packet = NULL;
-+
-+ MIPV6_RESETCALL(mipv6_set_home);
-+ MIPV6_RESETCALL(mipv6_get_home_address);
-+ MIPV6_RESETCALL(mipv6_mn_ha_probe);
-+ MIPV6_RESETCALL(mipv6_is_home_addr);
-+ nf_unregister_hook(&addr_modify_hook_ops);
-+ proc_net_remove("mip6_mninfo");
-+ mipv6_shutdown_mdetect();
-+ ip6ip6_tnl_unregister_hook(&mipv6_mn_tnl_rcv_stats_ops);
-+ ip6ip6_tnl_unregister_hook(&mipv6_mn_tnl_xmit_stats_ops);
-+ ip6ip6_tnl_unregister_hook(&mipv6_mn_tnl_rcv_send_bu_ops);
-+ ma_ctl_clean();
-+
-+ unregister_inet6addr_notifier(&mipv6_mn_inet6addr_notifier);
-+ unregister_netdevice_notifier(&mipv6_mn_dev_notifier);
-+ write_lock_bh(&mn_info_lock);
-+
-+ list_for_each_safe(lh, tmp, &mn_info_list) {
-+ minfo = list_entry(lh, struct mn_info, list);
-+ if (minfo->is_at_home == MN_NOT_AT_HOME)
-+ deprecate_addr(minfo);
-+ list_del(&minfo->list);
-+ kfree(minfo);
-+ }
-+ write_unlock_bh(&mn_info_lock);
-+ mipv6_bul_exit();
-+ flush_scheduled_tasks();
-+ mipv6_del_tnl_to_ha();
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/mn.h linux-2.4.25/net/ipv6/mobile_ip6/mn.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/mn.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/mn.h 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,96 @@
-+/*
-+ * MIPL Mobile IPv6 Mobile Node header file
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef _MN_H
-+#define _MN_H
-+
-+#include <linux/in6.h>
-+
-+/* constants for sending of BUs*/
-+#define HA_BU_DEF_LIFETIME 10000
-+#define CN_BU_DEF_LIFETIME 420 /* Max lifetime for RR bindings from RFC 3775 */
-+#define DUMB_CN_BU_LIFETIME 600 /* BUL entry lifetime in case of dumb CN */
-+#define ROUTER_BU_DEF_LIFETIME 30 /* For packet forwarding from previous coa */
-+#define ERROR_DEF_LIFETIME DUMB_CN_BU_LIFETIME
-+
-+extern rwlock_t mn_info_lock;
-+
-+#define MN_NOT_AT_HOME 0
-+#define MN_RETURNING_HOME 1
-+#define MN_AT_HOME 2
-+
-+/*
-+ * Mobile Node information record
-+ */
-+struct mn_info {
-+ struct in6_addr home_addr;
-+ struct in6_addr ha;
-+ __u8 home_plen;
-+ __u8 is_at_home;
-+ __u8 has_home_reg;
-+ __u8 man_conf;
-+ int ifindex;
-+ int ifindex_user;
-+ unsigned long home_addr_expires;
-+ unsigned short dhaad_id;
-+ struct list_head list;
-+ spinlock_t lock;
-+};
-+
-+/* prototypes for interface functions */
-+int mipv6_mn_init(void);
-+void mipv6_mn_exit(void);
-+
-+struct handoff;
-+
-+/* Interface to movement detection */
-+int mipv6_mobile_node_moved(struct handoff *ho);
-+
-+void mipv6_mn_send_home_na(struct in6_addr *haddr);
-+/* Init home reg. with coa */
-+int init_home_registration(struct in6_addr *home_addr, struct in6_addr *coa);
-+
-+/* mn_info functions that require locking by caller */
-+struct mn_info *mipv6_mninfo_get_by_home(struct in6_addr *haddr);
-+
-+struct mn_info *mipv6_mninfo_get_by_ha(struct in6_addr *home_agent);
-+
-+struct mn_info *mipv6_mninfo_get_by_id(unsigned short id);
-+
-+/* "safe" mn_info functions */
-+void mipv6_mninfo_add(int ifindex, struct in6_addr *home_addr, int plen,
-+ int isathome, unsigned long lifetime, struct in6_addr *ha,
-+ int ha_plen, unsigned long ha_lifetime, int man_conf);
-+
-+int mipv6_mninfo_del(struct in6_addr *home_addr, int del_dyn_only);
-+
-+void mipv6_mn_set_home_reg(struct in6_addr *home_addr, int has_home_reg);
-+
-+int mipv6_mn_is_at_home(struct in6_addr *addr);
-+
-+int mipv6_mn_is_home_addr(struct in6_addr *addr);
-+
-+__u32 mipv6_mn_get_bulifetime(struct in6_addr *home_addr,
-+ struct in6_addr *coa, __u8 flags);
-+int mn_cn_handoff(void *rawentry, void *args, unsigned long *sortkey);
-+
-+int mipv6_mn_ha_nd_update(struct net_device *dev,
-+ struct in6_addr *ha, u8 *lladdr);
-+
-+struct bul_inval_args {
-+ int all_rr_states;
-+ struct in6_addr *cn;
-+ struct in6_addr *mn;
-+};
-+
-+int mn_bul_invalidate(void *rawentry, void *args, unsigned long *sortkey);
-+
-+#endif /* _MN_H */
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/mobhdr.h linux-2.4.25/net/ipv6/mobile_ip6/mobhdr.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/mobhdr.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/mobhdr.h 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,101 @@
-+/*
-+ * MIPL Mobile IPv6 Mobility Header send and receive
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef _MOBHDR_H
-+#define _MOBHDR_H
-+
-+#include <net/mipv6.h>
-+
-+/* RR states for mipv6_send_bu() */
-+#define RR_INIT 0x00
-+#define RR_WAITH 0x01
-+#define RR_WAITC 0x02
-+#define RR_WAITHC 0x13
-+#define RR_DONE 0x10
-+
-+#define MH_UNKNOWN_CN 1
-+#define MH_AUTH_FAILED 2
-+#define MH_SEQUENCE_MISMATCH 3
-+
-+struct mipv6_bul_entry;
-+struct sk_buff;
-+
-+int mipv6_mh_common_init(void);
-+void mipv6_mh_common_exit(void);
-+int mipv6_mh_mn_init(void);
-+void mipv6_mh_mn_exit(void);
-+
-+struct mipv6_mh_opt {
-+ struct mipv6_mo_alt_coa *alt_coa;
-+ struct mipv6_mo_nonce_indices *nonce_indices;
-+ struct mipv6_mo_bauth_data *auth_data;
-+ struct mipv6_mo_br_advice *br_advice;
-+ int freelen;
-+ int totlen;
-+ u8 *next_free;
-+ u8 data[0];
-+};
-+
-+struct mobopt {
-+ struct mipv6_mo_alt_coa *alt_coa;
-+ struct mipv6_mo_nonce_indices *nonce_indices;
-+ struct mipv6_mo_bauth_data *auth_data;
-+ struct mipv6_mo_br_advice *br_advice;
-+};
-+
-+struct mipv6_mh_opt *alloc_mh_opts(int totlen);
-+int append_mh_opt(struct mipv6_mh_opt *ops, u8 type, u8 len, void *data);
-+int parse_mo_tlv(void *mos, int len, struct mobopt *opts);
-+int mipv6_add_pad(u8 *data, int n);
-+
-+struct mipv6_auth_parm {
-+ struct in6_addr *coa;
-+ struct in6_addr *cn_addr;
-+ __u8 *k_bu;
-+};
-+
-+int send_mh(struct in6_addr *daddr, struct in6_addr *saddr,
-+ u8 msg_type, u8 msg_len, u8 *msg,
-+ struct in6_addr *hao_addr, struct in6_addr *rth_addr,
-+ struct mipv6_mh_opt *ops, struct mipv6_auth_parm *parm);
-+
-+int mipv6_mh_register(int type, int (*func)(struct sk_buff *,
-+ struct in6_addr *, struct in6_addr *,
-+ struct in6_addr *, struct in6_addr *, struct mipv6_mh *));
-+
-+void mipv6_mh_unregister(int type);
-+
-+int mipv6_send_brr(struct in6_addr *saddr, struct in6_addr *daddr,
-+ struct mipv6_mh_opt *ops);
-+
-+int mipv6_send_bu(struct in6_addr *saddr, struct in6_addr *daddr,
-+ struct in6_addr *coa, __u32 initdelay,
-+ __u32 maxackdelay, __u8 exp, __u8 flags,
-+ __u32 lifetime, struct mipv6_mh_opt *ops);
-+
-+int mipv6_send_be(struct in6_addr *saddr, struct in6_addr *daddr,
-+ struct in6_addr *home, __u8 status);
-+
-+int mipv6_send_ba(struct in6_addr *saddr, struct in6_addr *daddr,
-+ struct in6_addr *auth_coa, struct in6_addr *rep_coa,
-+ u8 status, u16 sequence, u32 lifetime, u8 *k_bu);
-+
-+/* Binding Authentication Data Option routines */
-+#define MAX_HASH_LENGTH 20
-+#define MIPV6_RR_MAC_LENGTH 12
-+
-+int mipv6_auth_build(struct in6_addr *cn_addr, struct in6_addr *coa,
-+ __u8 *opt, __u8 *aud_data, __u8 *k_bu);
-+
-+int mipv6_auth_check(struct in6_addr *cn_addr, struct in6_addr *coa,
-+ __u8 *opt, __u8 optlen, struct mipv6_mo_bauth_data *aud,
-+ __u8 *k_bu);
-+#endif /* _MOBHDR_H */
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/mobhdr_common.c linux-2.4.25/net/ipv6/mobile_ip6/mobhdr_common.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/mobhdr_common.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/mobhdr_common.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,1210 @@
-+/*
-+ * Mobile IPv6 Mobility Header Common Functions
-+ *
-+ * Authors:
-+ * Antti Tuominen <ajtuomin@tml.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ *
-+ */
-+
-+#include <linux/autoconf.h>
-+#include <linux/types.h>
-+#include <linux/in6.h>
-+#include <linux/skbuff.h>
-+#include <linux/ipsec.h>
-+#include <linux/init.h>
-+#include <net/ipv6.h>
-+#include <net/ip6_route.h>
-+#include <net/addrconf.h>
-+#include <net/mipv6.h>
-+#include <net/checksum.h>
-+#include <net/protocol.h>
-+
-+#include "stats.h"
-+#include "debug.h"
-+#include "mobhdr.h"
-+#include "bcache.h"
-+
-+#include "rr_crypto.h"
-+#include "exthdrs.h"
-+#include "config.h"
-+
-+#define MIPV6_MH_MAX MIPV6_MH_BE
-+struct mh_proto {
-+ int (*func) (struct sk_buff *,
-+ struct in6_addr *, struct in6_addr *,
-+ struct in6_addr *, struct in6_addr *,
-+ struct mipv6_mh *);
-+};
-+
-+static struct mh_proto mh_rcv[MIPV6_MH_MAX];
-+
-+int mipv6_mh_register(int type, int (*func)(struct sk_buff *,
-+ struct in6_addr *, struct in6_addr *,
-+ struct in6_addr *, struct in6_addr *, struct mipv6_mh *))
-+{
-+ if (mh_rcv[type].func != NULL)
-+ return -1;
-+
-+ mh_rcv[type].func = func;
-+
-+ return 0;
-+}
-+
-+void mipv6_mh_unregister(int type)
-+{
-+ if (type < 0 || type > MIPV6_MH_MAX)
-+ return;
-+
-+ mh_rcv[type].func = NULL;
-+}
-+
-+struct socket *mipv6_mh_socket = NULL;
-+
-+/* TODO: Fix fragmentation */
-+static int dstopts_getfrag(
-+ const void *data, struct in6_addr *addr,
-+ char *buff, unsigned int offset, unsigned int len)
-+{
-+ memcpy(buff, data + offset, len);
-+ return 0;
-+}
-+
-+struct mipv6_mh_opt *alloc_mh_opts(int totlen)
-+{
-+ struct mipv6_mh_opt *ops;
-+
-+ ops = kmalloc(sizeof(*ops) + totlen, GFP_ATOMIC);
-+ if (ops == NULL)
-+ return NULL;
-+
-+ memset(ops, 0, sizeof(*ops));
-+ ops->next_free = ops->data;
-+ ops->freelen = totlen;
-+
-+ return ops;
-+}
-+
-+int append_mh_opt(struct mipv6_mh_opt *ops, u8 type, u8 len, void *data)
-+{
-+ struct mipv6_mo *mo;
-+
-+ if (ops->next_free == NULL) {
-+ DEBUG(DBG_ERROR, "No free room for option");
-+ return -ENOMEM;
-+ }
-+ if (ops->freelen < len + 2) {
-+ DEBUG(DBG_ERROR, "No free room for option");
-+ return -ENOMEM;
-+ }
-+ else {
-+ ops->freelen -= (len + 2);
-+ ops->totlen += (len + 2);
-+ }
-+
-+ mo = (struct mipv6_mo *)ops->next_free;
-+ mo->type = type;
-+ mo->length = len;
-+
-+ switch (type) {
-+ case MIPV6_OPT_ALTERNATE_COA:
-+ ops->alt_coa = (struct mipv6_mo_alt_coa *)mo;
-+ ipv6_addr_copy(&ops->alt_coa->addr, (struct in6_addr *)data);
-+ break;
-+ case MIPV6_OPT_NONCE_INDICES:
-+ DEBUG(DBG_INFO, "Added nonce indices pointer");
-+ ops->nonce_indices = (struct mipv6_mo_nonce_indices *)mo;
-+ ops->nonce_indices->home_nonce_i = *(__u16 *)data;
-+ ops->nonce_indices->careof_nonce_i = *((__u16 *)data + 1);
-+ break;
-+ case MIPV6_OPT_AUTH_DATA:
-+ DEBUG(DBG_INFO, "Added opt auth_data pointer");
-+ ops->auth_data = (struct mipv6_mo_bauth_data *)mo;
-+ break;
-+ case MIPV6_OPT_BIND_REFRESH_ADVICE:
-+ ops->br_advice = (struct mipv6_mo_br_advice *)mo;
-+ ops->br_advice->refresh_interval = htons(*(u16 *)data);
-+ break;
-+ default:
-+ DEBUG(DBG_ERROR, "Unknow option type");
-+ break;
-+ }
-+
-+ if (ops->freelen == 0)
-+ ops->next_free = NULL;
-+ else
-+ ops->next_free += (len + 2);
-+
-+ return 0;
-+}
-+
-+/*
-+ * Calculates required padding with xn + y requirement with offset
-+ */
-+static inline int optpad(int xn, int y, int offset)
-+{
-+ return ((y - offset) & (xn - 1));
-+}
-+
-+static int option_pad(int type, int offset)
-+{
-+ if (type == MIPV6_OPT_ALTERNATE_COA)
-+ return optpad(8, 6, offset); /* 8n + 6 */
-+ if (type == MIPV6_OPT_BIND_REFRESH_ADVICE ||
-+ type == MIPV6_OPT_NONCE_INDICES)
-+ return optpad(2, 0, offset); /* 2n */
-+ return 0;
-+}
-+
-+/*
-+ * Add Pad1 or PadN option to data
-+ */
-+int mipv6_add_pad(u8 *data, int n)
-+{
-+ struct mipv6_mo_padn *padn;
-+
-+ if (n <= 0) return 0;
-+ if (n == 1) {
-+ *data = MIPV6_OPT_PAD1;
-+ return 1;
-+ }
-+ padn = (struct mipv6_mo_padn *)data;
-+ padn->type = MIPV6_OPT_PADN;
-+ padn->length = n - 2;
-+ memset(padn->data, 0, n - 2);
-+ return n;
-+}
-+
-+/*
-+ * Write options to mobility header buffer
-+ */
-+static int prepare_mh_opts(u8 *optdata, int off, struct mipv6_mh_opt *ops)
-+{
-+ u8 *nextopt = optdata;
-+ int offset = off, pad = 0;
-+
-+ if (ops == NULL) {
-+ nextopt = NULL;
-+ return -1;
-+ }
-+
-+ if (ops->alt_coa) {
-+ pad = option_pad(MIPV6_OPT_ALTERNATE_COA, offset);
-+ nextopt += mipv6_add_pad(nextopt, pad);
-+ memcpy(nextopt, ops->alt_coa, sizeof(struct mipv6_mo_alt_coa));
-+ nextopt += sizeof(struct mipv6_mo_alt_coa);
-+ offset += pad + sizeof(struct mipv6_mo_alt_coa);
-+ }
-+
-+ if (ops->br_advice) {
-+ pad = option_pad(MIPV6_OPT_BIND_REFRESH_ADVICE, offset);
-+ nextopt += mipv6_add_pad(nextopt, pad);
-+ memcpy(nextopt, ops->br_advice, sizeof(struct mipv6_mo_br_advice));
-+ nextopt += sizeof(struct mipv6_mo_br_advice);
-+ offset += pad + sizeof(struct mipv6_mo_br_advice);
-+ }
-+
-+ if (ops->nonce_indices) {
-+ pad = option_pad(MIPV6_OPT_NONCE_INDICES, offset);
-+ nextopt += mipv6_add_pad(nextopt, pad);
-+ memcpy(nextopt, ops->nonce_indices, sizeof(struct mipv6_mo_nonce_indices));
-+ nextopt += sizeof(struct mipv6_mo_nonce_indices);
-+ offset += pad + sizeof(struct mipv6_mo_nonce_indices);
-+ }
-+
-+ if (ops->auth_data) {
-+ /* This option should always be the last. Header
-+ * length must be a multiple of 8 octects, so we pad
-+ * if necessary. */
-+ pad = optpad(8, 0, offset + ops->auth_data->length + 2);
-+ nextopt += mipv6_add_pad(nextopt, pad);
-+ memcpy(nextopt, ops->auth_data, ops->auth_data->length + 2);
-+ nextopt += ops->auth_data->length + 2;
-+ }
-+ nextopt = NULL;
-+
-+ return 0;
-+}
-+
-+static int calculate_mh_opts(struct mipv6_mh_opt *ops, int mh_len)
-+{
-+ int offset = mh_len;
-+
-+ if (ops == NULL)
-+ return 0;
-+
-+ if (ops->alt_coa)
-+ offset += sizeof(struct mipv6_mo_alt_coa)
-+ + option_pad(MIPV6_OPT_ALTERNATE_COA, offset);
-+
-+ if (ops->br_advice)
-+ offset += sizeof(struct mipv6_mo_br_advice)
-+ + option_pad(MIPV6_OPT_BIND_REFRESH_ADVICE, offset);
-+
-+ if (ops->nonce_indices)
-+ offset += sizeof(struct mipv6_mo_nonce_indices)
-+ + option_pad(MIPV6_OPT_NONCE_INDICES, offset);
-+
-+ if (ops->auth_data) /* no alignment */
-+ offset += ops->auth_data->length + 2;
-+
-+ return offset - mh_len;
-+}
-+
-+/*
-+ *
-+ * Mobility Header Message send functions
-+ *
-+ */
-+
-+/**
-+ * send_mh - builds and sends a MH msg
-+ *
-+ * @daddr: destination address for packet
-+ * @saddr: source address for packet
-+ * @msg_type: type of MH
-+ * @msg_len: message length
-+ * @msg: MH type specific data
-+ * @hao_addr: home address for home address option
-+ * @rth_addr: routing header address
-+ * @ops: mobility options
-+ * @parm: auth data
-+ *
-+ * Builds MH, appends the type specific msg data to the header and
-+ * sends the packet with a home address option, if a home address was
-+ * given. Returns 0, if everything succeeded and a negative error code
-+ * otherwise.
-+ **/
-+int send_mh(struct in6_addr *daddr,
-+ struct in6_addr *saddr,
-+ u8 msg_type, u8 msg_len, u8 *msg,
-+ struct in6_addr *hao_addr,
-+ struct in6_addr *rth_addr,
-+ struct mipv6_mh_opt *ops,
-+ struct mipv6_auth_parm *parm)
-+{
-+ struct flowi fl;
-+ struct mipv6_mh *mh;
-+ struct sock *sk = mipv6_mh_socket->sk;
-+ struct ipv6_txoptions *txopt = NULL;
-+ int tot_len = sizeof(struct mipv6_mh) + msg_len;
-+ int padded_len = 0, txopt_len = 0;
-+
-+ DEBUG_FUNC();
-+ /* Add length of options */
-+ tot_len += calculate_mh_opts(ops, tot_len);
-+ /* Needs to be a multiple of 8 octets */
-+ padded_len = tot_len + optpad(8, 0, tot_len);
-+
-+ mh = sock_kmalloc(sk, padded_len, GFP_ATOMIC);
-+ if (!mh) {
-+ DEBUG(DBG_ERROR, "memory allocation failed");
-+ return -ENOMEM;
-+ }
-+
-+ memset(&fl, 0, sizeof(fl));
-+ fl.proto = IPPROTO_MOBILITY;
-+ fl.fl6_dst = daddr;
-+ fl.fl6_src = saddr;
-+ fl.fl6_flowlabel = 0;
-+ fl.oif = sk->bound_dev_if;
-+
-+ if (hao_addr || rth_addr) {
-+ __u8 *opt_ptr;
-+
-+ if (hao_addr)
-+ txopt_len += sizeof(struct mipv6_dstopt_homeaddr) + 6;
-+ if (rth_addr)
-+ txopt_len += sizeof(struct rt2_hdr);
-+
-+ txopt_len += sizeof(*txopt);
-+ txopt = sock_kmalloc(sk, txopt_len, GFP_ATOMIC);
-+ if (txopt == NULL) {
-+ DEBUG(DBG_ERROR, "No socket space left");
-+ sock_kfree_s(sk, mh, padded_len);
-+ return -ENOMEM;
-+ }
-+ memset(txopt, 0, txopt_len);
-+ txopt->tot_len = txopt_len;
-+ opt_ptr = (__u8 *) (txopt + 1);
-+ if (hao_addr) {
-+ int holen = sizeof(struct mipv6_dstopt_homeaddr) + 6;
-+ txopt->dst1opt = (struct ipv6_opt_hdr *) opt_ptr;
-+ txopt->opt_flen += holen;
-+ opt_ptr += holen;
-+ mipv6_append_dst1opts(txopt->dst1opt, saddr,
-+ NULL, holen);
-+ txopt->mipv6_flags = MIPV6_SND_HAO | MIPV6_SND_BU;
-+ }
-+ if (rth_addr) {
-+ int rtlen = sizeof(struct rt2_hdr);
-+ txopt->srcrt2 = (struct ipv6_rt_hdr *) opt_ptr;
-+ txopt->opt_nflen += rtlen;
-+ opt_ptr += rtlen;
-+ mipv6_append_rt2hdr(txopt->srcrt2, rth_addr);
-+ }
-+ }
-+
-+ /* Fill in the fields of MH */
-+ mh->payload = NEXTHDR_NONE;
-+ mh->length = (padded_len >> 3) - 1; /* Units of 8 octets - 1 */
-+ mh->type = msg_type;
-+ mh->reserved = 0;
-+ mh->checksum = 0;
-+
-+ memcpy(mh->data, msg, msg_len);
-+ prepare_mh_opts(mh->data + msg_len, msg_len + sizeof(*mh), ops);
-+ /* If BAD is present, this is already done. */
-+ mipv6_add_pad((u8 *)mh + tot_len, padded_len - tot_len);
-+
-+ if (parm && parm->k_bu && ops && ops->auth_data) {
-+ /* Calculate the position of the authorization data before adding checksum*/
-+ mipv6_auth_build(parm->cn_addr, parm->coa, (__u8 *)mh,
-+ (__u8 *)mh + padded_len - MIPV6_RR_MAC_LENGTH, parm->k_bu);
-+ }
-+ /* Calculate the MH checksum */
-+ mh->checksum = csum_ipv6_magic(fl.fl6_src, fl.fl6_dst,
-+ padded_len, IPPROTO_MOBILITY,
-+ csum_partial((char *)mh, padded_len, 0));
-+ ip6_build_xmit(sk, dstopts_getfrag, mh, &fl, padded_len, txopt, 255,
-+ MSG_DONTWAIT);
-+ /* dst cache must be cleared so RR messages can be routed through
-+ different interfaces */
-+ sk_dst_reset(sk);
-+
-+ if (txopt_len)
-+ sock_kfree_s(sk, txopt, txopt_len);
-+ sock_kfree_s(sk, mh, padded_len);
-+ return 0;
-+}
-+
-+/**
-+ * mipv6_send_brr - send a Binding Refresh Request
-+ * @saddr: source address for BRR
-+ * @daddr: destination address for BRR
-+ * @ops: mobility options
-+ *
-+ * Sends a binding request. On a mobile node, use the mobile node's
-+ * home address for @saddr. Returns 0 on success, negative on
-+ * failure.
-+ **/
-+int mipv6_send_brr(struct in6_addr *saddr, struct in6_addr *daddr,
-+ struct mipv6_mh_opt *ops)
-+{
-+ struct mipv6_mh_brr br;
-+
-+ memset(&br, 0, sizeof(br));
-+ /* We don't need to explicitly add a RH to brr, since it will be
-+ * included automatically, if a BCE exists
-+ */
-+ MIPV6_INC_STATS(n_brr_sent);
-+ return send_mh(daddr, saddr, MIPV6_MH_BRR, sizeof(br), (u8 *)&br,
-+ NULL, NULL, ops, NULL);
-+}
-+
-+/**
-+ * mipv6_send_ba - send a Binding Acknowledgement
-+ * @saddr: source address for BA
-+ * @daddr: destination address for BA
-+ * @reply_coa: destination care-of address of MN
-+ * @auth_coa: care-of address of MN used for authentication
-+ * @status: status field value
-+ * @sequence: sequence number from BU
-+ * @lifetime: granted lifetime for binding in seconds
-+ * @ops: mobility options
-+ *
-+ * Send a binding acknowledgement. On a mobile node, use the mobile
-+ * node's home address for saddr. Returns 0 on success, non-zero on
-+ * failure.
-+ **/
-+int mipv6_send_ba(struct in6_addr *saddr, struct in6_addr *daddr,
-+ struct in6_addr *auth_coa, struct in6_addr *rep_coa,
-+ u8 status, u16 sequence, u32 lifetime, u8 *k_bu)
-+{
-+ struct mipv6_mh_ba ba;
-+ struct mipv6_auth_parm parm;
-+ struct mipv6_mh_opt *ops = NULL;
-+ int ops_len = 0, ret = 0;
-+ struct mipv6_bce bc_entry;
-+ int coming_home = 0;
-+ int bypass_tnl = 0;
-+
-+ memset(&ba, 0, sizeof(ba));
-+
-+ ba.status = status;
-+ ba.sequence = htons(sequence);
-+ ba.lifetime = htons(lifetime >> 2);
-+
-+ DEBUG(DBG_INFO, "sending a status %d BA %s authenticator to MN \n"
-+ "%x:%x:%x:%x:%x:%x:%x:%x at care of address \n"
-+ "%x:%x:%x:%x:%x:%x:%x:%x : with lifetime %d and \n"
-+ " sequence number %d",
-+ status, k_bu ? "with" : "without",
-+ NIPV6ADDR(daddr), NIPV6ADDR(auth_coa), lifetime, sequence);
-+
-+ memset(&parm, 0, sizeof(parm));
-+ parm.coa = auth_coa;
-+ parm.cn_addr = saddr;
-+
-+ if (k_bu) {
-+ ops_len += sizeof(struct mipv6_mo_bauth_data) +
-+ MIPV6_RR_MAC_LENGTH;
-+ parm.k_bu = k_bu;
-+ }
-+
-+ if (mip6node_cnf.binding_refresh_advice) {
-+ ops_len += sizeof(struct mipv6_mo_br_advice);
-+ }
-+ if (ops_len) {
-+ ops = alloc_mh_opts(ops_len);
-+ if (ops == NULL) {
-+ DEBUG(DBG_WARNING, "Out of memory");
-+ return -ENOMEM;
-+ }
-+ if (mip6node_cnf.binding_refresh_advice > 0) {
-+ if (append_mh_opt(ops, MIPV6_OPT_BIND_REFRESH_ADVICE, 2,
-+ &mip6node_cnf.binding_refresh_advice) < 0) {
-+ DEBUG(DBG_WARNING, "Adding BRA failed");
-+ if (ops)
-+ kfree(ops);
-+ return -ENOMEM;
-+ }
-+ }
-+ if (k_bu) {
-+ if (append_mh_opt(ops, MIPV6_OPT_AUTH_DATA,
-+ MIPV6_RR_MAC_LENGTH, NULL) < 0) {
-+ DEBUG(DBG_WARNING, "Adding BAD failed");
-+ if (ops)
-+ kfree(ops);
-+ return -ENOMEM;
-+ }
-+ }
-+ }
-+ coming_home = !ipv6_addr_cmp(rep_coa, daddr);
-+
-+ bypass_tnl = (coming_home &&
-+ !mipv6_bcache_get(daddr, saddr, &bc_entry) &&
-+ bc_entry.flags&MIPV6_BU_F_HOME &&
-+ status >= 128);
-+
-+ if (bypass_tnl && mip6_fn.bce_tnl_rt_del)
-+ mip6_fn.bce_tnl_rt_del(&bc_entry.coa,
-+ &bc_entry.our_addr,
-+ &bc_entry.home_addr);
-+
-+ if (coming_home)
-+ ret = send_mh(daddr, saddr, MIPV6_MH_BA, sizeof(ba), (u8 *)&ba,
-+ NULL, NULL, ops, &parm);
-+ else
-+ ret = send_mh(daddr, saddr, MIPV6_MH_BA, sizeof(ba), (u8 *)&ba,
-+ NULL, rep_coa, ops, &parm);
-+
-+ if (bypass_tnl && mip6_fn.bce_tnl_rt_add)
-+ mip6_fn.bce_tnl_rt_add(&bc_entry.coa,
-+ &bc_entry.our_addr,
-+ &bc_entry.home_addr);
-+
-+ if (ret == 0) {
-+ if (status < 128) {
-+ MIPV6_INC_STATS(n_ba_sent);
-+ } else {
-+ MIPV6_INC_STATS(n_ban_sent);
-+ }
-+ }
-+
-+ if (ops)
-+ kfree(ops);
-+
-+ return 0;
-+}
-+
-+/**
-+ * mipv6_send_be - send a Binding Error message
-+ * @saddr: source address for BE
-+ * @daddr: destination address for BE
-+ * @home: Home Address in offending packet (if any)
-+ *
-+ * Sends a binding error. On a mobile node, use the mobile node's
-+ * home address for @saddr. Returns 0 on success, negative on
-+ * failure.
-+ **/
-+int mipv6_send_be(struct in6_addr *saddr, struct in6_addr *daddr,
-+ struct in6_addr *home, __u8 status)
-+{
-+ struct mipv6_mh_be be;
-+ int ret = 0;
-+ struct mipv6_bce bc_entry;
-+ int bypass_tnl = 0;
-+
-+ if (ipv6_addr_is_multicast(daddr))
-+ return -EINVAL;
-+
-+ memset(&be, 0, sizeof(be));
-+ be.status = status;
-+ if (home)
-+ ipv6_addr_copy(&be.home_addr, home);
-+
-+ if (mipv6_bcache_get(daddr, saddr, &bc_entry) == 0 &&
-+ bc_entry.flags&MIPV6_BU_F_HOME)
-+ bypass_tnl = 1;
-+
-+ if (bypass_tnl && mip6_fn.bce_tnl_rt_del)
-+ mip6_fn.bce_tnl_rt_del(&bc_entry.coa,
-+ &bc_entry.our_addr,
-+ &bc_entry.home_addr);
-+
-+ ret = send_mh(daddr, saddr, MIPV6_MH_BE, sizeof(be), (u8 *)&be,
-+ NULL, NULL, NULL, NULL);
-+
-+ if (bypass_tnl && mip6_fn.bce_tnl_rt_add)
-+ mip6_fn.bce_tnl_rt_add(&bc_entry.coa,
-+ &bc_entry.our_addr,
-+ &bc_entry.home_addr);
-+
-+ if (ret == 0)
-+ MIPV6_INC_STATS(n_be_sent);
-+
-+ return ret;
-+}
-+
-+/**
-+ * mipv6_send_addr_test - send a HoT or CoT message
-+ * @saddr: source address
-+ * @daddr: destination address
-+ * @msg_type: HoT or CoT message
-+ * @init: HoTI or CoTI message
-+ *
-+ * Send a reply to HoTI or CoTI message.
-+ **/
-+static int mipv6_send_addr_test(struct in6_addr *saddr,
-+ struct in6_addr *daddr,
-+ int msg_type,
-+ struct mipv6_mh_addr_ti *init)
-+{
-+ u_int8_t *kgen_token = NULL;
-+ struct mipv6_mh_addr_test addr_test;
-+ struct mipv6_rr_nonce *nonce;
-+ struct mipv6_mh_opt *ops = NULL;
-+ int ret = 0;
-+
-+ DEBUG_FUNC();
-+
-+ if ((nonce = mipv6_rr_get_new_nonce())== NULL) {
-+ DEBUG(DBG_WARNING, "Nonce creation failed");
-+ return 0;
-+ }
-+ if (mipv6_rr_cookie_create(daddr, &kgen_token, nonce->index)) {
-+ DEBUG(DBG_WARNING, "No cookie");
-+ return 0;
-+ }
-+
-+ addr_test.nonce_index = nonce->index;
-+ memcpy(addr_test.init_cookie, init->init_cookie,
-+ MIPV6_RR_COOKIE_LENGTH);
-+ memcpy(addr_test.kgen_token, kgen_token,
-+ MIPV6_RR_COOKIE_LENGTH);
-+
-+ /* No options defined */
-+ ret = send_mh(daddr, saddr, msg_type, sizeof(addr_test),
-+ (u8 *)&addr_test, NULL, NULL, ops, NULL);
-+
-+ if (ret == 0) {
-+ if (msg_type == MIPV6_MH_HOT) {
-+ MIPV6_INC_STATS(n_hot_sent);
-+ } else {
-+ MIPV6_INC_STATS(n_cot_sent);
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static void bc_cache_add(int ifindex, struct in6_addr *daddr,
-+ struct in6_addr *haddr, struct in6_addr *coa,
-+ struct in6_addr *rep_coa, __u32 lifetime,
-+ __u16 sequence, __u8 flags, __u8 *k_bu)
-+{
-+ __u8 ba_status = SUCCESS;
-+
-+ if (lifetime > MAX_RR_BINDING_LIFE)
-+ lifetime = MAX_RR_BINDING_LIFE;
-+
-+ if (mipv6_bcache_add(ifindex, daddr, haddr, coa, lifetime,
-+ sequence, flags, CACHE_ENTRY) != 0) {
-+ DEBUG(DBG_ERROR, "binding failed.");
-+ ba_status = INSUFFICIENT_RESOURCES;
-+ }
-+
-+ if (flags & MIPV6_BU_F_ACK) {
-+ DEBUG(DBG_INFO, "sending ack (code=%d)", ba_status);
-+ mipv6_send_ba(daddr, haddr, coa, rep_coa, ba_status, sequence,
-+ lifetime, k_bu);
-+ }
-+}
-+
-+static void bc_cn_home_add(int ifindex, struct in6_addr *daddr,
-+ struct in6_addr *haddr, struct in6_addr *coa,
-+ struct in6_addr *rep_coa, __u32 lifetime,
-+ __u16 sequence, __u8 flags, __u8 *k_bu)
-+{
-+ mipv6_send_ba(daddr, haddr, coa, rep_coa,
-+ HOME_REGISTRATION_NOT_SUPPORTED,
-+ sequence, lifetime, k_bu);
-+}
-+
-+static void bc_cache_delete(struct in6_addr *daddr, struct in6_addr *haddr,
-+ struct in6_addr *coa, struct in6_addr *rep_coa,
-+ __u16 sequence, __u8 flags,
-+ __u8 *k_bu)
-+{
-+ __u8 status = SUCCESS;
-+
-+ /* Cached Care-of Address Deregistration */
-+ if (mipv6_bcache_exists(haddr, daddr) == CACHE_ENTRY) {
-+ mipv6_bcache_delete(haddr, daddr, CACHE_ENTRY);
-+ } else {
-+ DEBUG(DBG_INFO, "entry is not in cache");
-+ status = REASON_UNSPECIFIED;
-+ }
-+ if (flags & MIPV6_BU_F_ACK) {
-+ mipv6_send_ba(daddr, haddr, coa, rep_coa, status, sequence,
-+ 0, k_bu);
-+ }
-+}
-+
-+static void bc_cn_home_delete(struct in6_addr *daddr, struct in6_addr *haddr,
-+ struct in6_addr *coa, struct in6_addr *rep_coa,
-+ __u16 sequence, __u8 flags,
-+ __u8 *k_bu)
-+{
-+}
-+
-+/**
-+ * parse_mo_tlv - Parse TLV-encoded Mobility Options
-+ * @mos: pointer to Mobility Options
-+ * @len: total length of options
-+ * @opts: structure to store option pointers
-+ *
-+ * Parses Mobility Options passed in @mos. Stores pointers in @opts
-+ * to all valid mobility options found in @mos. Unknown options and
-+ * padding (%MIPV6_OPT_PAD1 and %MIPV6_OPT_PADN) is ignored and
-+ * skipped.
-+ **/
-+int parse_mo_tlv(void *mos, int len, struct mobopt *opts)
-+{
-+ struct mipv6_mo *curr = (struct mipv6_mo *)mos;
-+ int left = len;
-+
-+ while (left > 0) {
-+ int optlen = 0;
-+ if (curr->type == MIPV6_OPT_PAD1)
-+ optlen = 1;
-+ else
-+ optlen = 2 + curr->length;
-+
-+ if (optlen > left)
-+ goto bad;
-+
-+ switch (curr->type) {
-+ case MIPV6_OPT_PAD1:
-+ DEBUG(DBG_DATADUMP, "MIPV6_OPT_PAD1 at %x", curr);
-+ break;
-+ case MIPV6_OPT_PADN:
-+ DEBUG(DBG_DATADUMP, "MIPV6_OPT_PADN at %x", curr);
-+ break;
-+ case MIPV6_OPT_ALTERNATE_COA:
-+ DEBUG(DBG_DATADUMP, "MIPV6_OPT_ACOA at %x", curr);
-+ opts->alt_coa = (struct mipv6_mo_alt_coa *)curr;
-+ break;
-+ case MIPV6_OPT_NONCE_INDICES:
-+ DEBUG(DBG_DATADUMP, "MIPV6_OPT_NONCE_INDICES at %x", curr);
-+ opts->nonce_indices =
-+ (struct mipv6_mo_nonce_indices *)curr;
-+ break;
-+ case MIPV6_OPT_AUTH_DATA:
-+ DEBUG(DBG_DATADUMP, "MIPV6_OPT_AUTH_DATA at %x", curr);
-+ opts->auth_data = (struct mipv6_mo_bauth_data *)curr;
-+ break;
-+ case MIPV6_OPT_BIND_REFRESH_ADVICE:
-+ DEBUG(DBG_DATADUMP, "MIPV6_OPT_BIND_REFRESH_ADVICE at %x", curr);
-+ opts->br_advice = (struct mipv6_mo_br_advice *)curr;
-+ break;
-+ default:
-+ DEBUG(DBG_INFO, "MO Unknown option type %d at %x, ignoring.",
-+ curr->type, curr);
-+ /* unknown mobility option, ignore and skip */
-+ }
-+
-+ (u8 *)curr += optlen;
-+ left -= optlen;
-+ }
-+
-+ if (left == 0)
-+ return 0;
-+ bad:
-+ return -1;
-+}
-+
-+/*
-+ *
-+ * Mobility Header Message handlers
-+ *
-+ */
-+
-+static int mipv6_handle_mh_testinit(struct sk_buff *skb,
-+ struct in6_addr *cn,
-+ struct in6_addr *lcoa,
-+ struct in6_addr *saddr,
-+ struct in6_addr *fcoa,
-+ struct mipv6_mh *mh)
-+{
-+ struct mipv6_mh_addr_ti *ti = (struct mipv6_mh_addr_ti *)mh->data;
-+ int msg_len = (mh->length+1) << 3;
-+ int opt_len;
-+ DEBUG_FUNC();
-+
-+ if (msg_len > skb->len)
-+ return -1;
-+
-+ opt_len = msg_len - sizeof(*mh) - sizeof(*ti);
-+
-+ if (opt_len < 0) {
-+ __u32 pos = (__u32)&mh->length - (__u32)skb->nh.raw;
-+ icmpv6_send(skb, ICMPV6_PARAMPROB,
-+ ICMPV6_HDR_FIELD, pos, skb->dev);
-+
-+ DEBUG(DBG_INFO, "Mobility Header length less than H/C TestInit");
-+ return -1;
-+ }
-+ if (!mip6node_cnf.accept_ret_rout) {
-+ DEBUG(DBG_INFO, "Return routability administratively disabled");
-+ return -1;
-+ }
-+ if (lcoa || fcoa) {
-+ DEBUG(DBG_INFO, "H/C TestInit has HAO or RTH2, dropped.");
-+ return -1;
-+ }
-+
-+ if (mh->type == MIPV6_MH_HOTI) {
-+ MIPV6_INC_STATS(n_hoti_rcvd);
-+ return mipv6_send_addr_test(cn, saddr, MIPV6_MH_HOT, ti);
-+ } else if (mh->type == MIPV6_MH_COTI) {
-+ MIPV6_INC_STATS(n_coti_rcvd);
-+ return mipv6_send_addr_test(cn, saddr, MIPV6_MH_COT, ti);
-+ } else
-+ return -1; /* Impossible to get here */
-+}
-+
-+/**
-+ * mipv6_handle_mh_bu - Binding Update handler
-+ * @src: care-of address of sender
-+ * @dst: our address
-+ * @haddr: home address of sender
-+ * @mh: pointer to the beginning of the Mobility Header
-+ *
-+ * Handles Binding Update. Packet and offset to option are passed.
-+ * Returns 0 on success, otherwise negative.
-+ **/
-+static int mipv6_handle_mh_bu(struct sk_buff *skb,
-+ struct in6_addr *dst,
-+ struct in6_addr *unused,
-+ struct in6_addr *haddr,
-+ struct in6_addr *coaddr,
-+ struct mipv6_mh *mh)
-+{
-+ struct mipv6_mh_bu *bu = (struct mipv6_mh_bu *)mh->data;
-+ int msg_len = (mh->length+1) << 3;
-+ int opt_len;
-+ int auth = 0;
-+ int dereg; /* Is this deregistration? */
-+ int addr_type;
-+
-+ struct mipv6_bce bc_entry;
-+ struct in6_addr *coa, *reply_coa;
-+ __u8 *key_bu = NULL; /* RR BU authentication key */
-+ __u8 flags = bu->flags;
-+ __u16 sequence;
-+ __u32 lifetime;
-+ __u16 nonce_ind = (__u16) -1;
-+
-+ if (msg_len > skb->len)
-+ return -1;
-+
-+ opt_len = msg_len - sizeof(*mh) - sizeof(*bu);
-+
-+ if (opt_len < 0) {
-+ __u32 pos = (__u32)&mh->length - (__u32)skb->nh.raw;
-+ icmpv6_send(skb, ICMPV6_PARAMPROB,
-+ ICMPV6_HDR_FIELD, pos, skb->dev);
-+
-+ DEBUG(DBG_INFO, "Mobility Header length less than BU");
-+ MIPV6_INC_STATS(n_bu_drop.invalid);
-+ return -1;
-+ }
-+
-+ addr_type = ipv6_addr_type(haddr);
-+ if (addr_type&IPV6_ADDR_LINKLOCAL || !(addr_type&IPV6_ADDR_UNICAST))
-+ return -EINVAL;
-+
-+ /* If HAO not present, CoA == HAddr */
-+ if (coaddr == NULL)
-+ coa = haddr;
-+ else {
-+ coa = coaddr;
-+ addr_type = ipv6_addr_type(coa);
-+ if (addr_type&IPV6_ADDR_LINKLOCAL ||
-+ !(addr_type&IPV6_ADDR_UNICAST))
-+ return -EINVAL;
-+ }
-+ reply_coa = coa;
-+
-+ sequence = ntohs(bu->sequence);
-+ if (bu->lifetime == 0xffff)
-+ lifetime = 0xffffffff;
-+ else
-+ lifetime = ntohs(bu->lifetime) << 2;
-+
-+ dereg = (ipv6_addr_cmp(haddr, coa) == 0 || lifetime == 0);
-+
-+ if (opt_len > 0) {
-+ struct mobopt opts;
-+ memset(&opts, 0, sizeof(opts));
-+ if (parse_mo_tlv(bu + 1, opt_len, &opts) < 0) {
-+ MIPV6_INC_STATS(n_bu_drop.invalid);
-+ return -1;
-+ }
-+ /*
-+ * MIPV6_OPT_AUTH_DATA, MIPV6_OPT_NONCE_INDICES,
-+ * MIPV6_OPT_ALT_COA
-+ */
-+ if (opts.alt_coa) {
-+ coa = &opts.alt_coa->addr;
-+ dereg = (ipv6_addr_cmp(haddr, coa) == 0 || lifetime == 0);
-+ }
-+ addr_type = ipv6_addr_type(coa);
-+ if (addr_type&IPV6_ADDR_LINKLOCAL ||
-+ !(addr_type&IPV6_ADDR_UNICAST))
-+ return -EINVAL;
-+
-+ if (flags & MIPV6_BU_F_HOME) {
-+ if (opts.nonce_indices)
-+ return -1;
-+ } else {
-+ u8 ba_status = 0;
-+ u8 *h_ckie = NULL, *c_ckie = NULL; /* Home and care-of cookies */
-+
-+ /* BUs to CN MUST include authorization data and nonce indices options */
-+ if (!opts.auth_data || !opts.nonce_indices) {
-+ DEBUG(DBG_WARNING,
-+ "Route optimization BU without authorization material, aborting processing");
-+ return MH_AUTH_FAILED;
-+ }
-+ if (mipv6_rr_cookie_create(
-+ haddr, &h_ckie, opts.nonce_indices->home_nonce_i) < 0) {
-+ DEBUG(DBG_WARNING,
-+ "mipv6_rr_cookie_create failed for home cookie");
-+ ba_status = EXPIRED_HOME_NONCE_INDEX;
-+ }
-+ nonce_ind = opts.nonce_indices->home_nonce_i;
-+ /* Don't create the care-of cookie, if MN deregisters */
-+ if (!dereg && mipv6_rr_cookie_create(
-+ coa, &c_ckie,
-+ opts.nonce_indices->careof_nonce_i) < 0) {
-+ DEBUG(DBG_WARNING,
-+ "mipv6_rr_cookie_create failed for coa cookie");
-+ if (ba_status == 0)
-+ ba_status = EXPIRED_CAREOF_NONCE_INDEX;
-+ else
-+ ba_status = EXPIRED_NONCES;
-+ }
-+ if (ba_status == 0) {
-+ if (dereg)
-+ key_bu = mipv6_rr_key_calc(h_ckie, NULL);
-+ else
-+ key_bu = mipv6_rr_key_calc(h_ckie, c_ckie);
-+ mh->checksum = 0;/* TODO: Don't mangle the packet */
-+ if (key_bu && mipv6_auth_check(
-+ dst, coa, (__u8 *)mh, msg_len + sizeof(*mh), opts.auth_data, key_bu) == 0) {
-+ DEBUG(DBG_INFO, "mipv6_auth_check OK for BU");
-+ auth = 1;
-+ } else {
-+ DEBUG(DBG_WARNING,
-+ "BU Authentication failed");
-+ }
-+ }
-+ if (h_ckie)
-+ kfree(h_ckie);
-+ if (c_ckie)
-+ kfree(c_ckie);
-+ if (ba_status != 0) {
-+ MIPV6_INC_STATS(n_bu_drop.auth);
-+ mipv6_send_ba(dst, haddr, coa,
-+ reply_coa, ba_status,
-+ sequence, 0, NULL);
-+ goto out;
-+ }
-+ }
-+
-+ }
-+ /* Require authorization option for RO, home reg is protected by IPsec */
-+ if (!(flags & MIPV6_BU_F_HOME) && !auth) {
-+ MIPV6_INC_STATS(n_bu_drop.auth);
-+ if (key_bu)
-+ kfree(key_bu);
-+ return MH_AUTH_FAILED;
-+ }
-+
-+ if (mipv6_bcache_get(haddr, dst, &bc_entry) == 0) {
-+ if ((bc_entry.flags&MIPV6_BU_F_HOME) !=
-+ (flags&MIPV6_BU_F_HOME)) {
-+ DEBUG(DBG_INFO,
-+ "Registration type change. Sending BA REG_TYPE_CHANGE_FORBIDDEN");
-+ mipv6_send_ba(dst, haddr, coa, reply_coa,
-+ REG_TYPE_CHANGE_FORBIDDEN,
-+ sequence, lifetime, key_bu);
-+ goto out;
-+ }
-+ if (!MIPV6_SEQ_GT(sequence, bc_entry.seq)) {
-+ DEBUG(DBG_INFO,
-+ "Sequence number mismatch. Sending BA SEQUENCE_NUMBER_OUT_OF_WINDOW");
-+ mipv6_send_ba(dst, haddr, coa, reply_coa,
-+ SEQUENCE_NUMBER_OUT_OF_WINDOW,
-+ bc_entry.seq, lifetime, key_bu);
-+ goto out;
-+ }
-+ }
-+
-+ if (!dereg) {
-+ int ifindex;
-+ struct rt6_info *rt;
-+
-+ /* Avoid looping binding cache entries */
-+ if (mipv6_bcache_get(coa, dst, &bc_entry) == 0) {
-+ DEBUG(DBG_WARNING, "Looped BU, dropping the packet");
-+ goto out;
-+ }
-+ DEBUG(DBG_INFO, "calling bu_add.");
-+ if ((rt = rt6_lookup(haddr, dst, 0, 0)) != NULL) {
-+ ifindex = rt->rt6i_dev->ifindex;
-+ dst_release(&rt->u.dst);
-+ } else {
-+ /*
-+ * Can't process the BU since the right interface is
-+ * not found.
-+ */
-+ DEBUG(DBG_WARNING, "No route entry found for handling "
-+ "a BU request, (using 0 as index)");
-+ ifindex = 0;
-+ }
-+ if (flags & MIPV6_BU_F_HOME)
-+ mip6_fn.bce_home_add(ifindex, dst, haddr, coa,
-+ reply_coa, lifetime, sequence,
-+ flags, key_bu);
-+ else
-+ mip6_fn.bce_cache_add(ifindex, dst, haddr, coa,
-+ reply_coa, lifetime, sequence,
-+ flags, key_bu);
-+ } else {
-+ DEBUG(DBG_INFO, "calling BCE delete.");
-+
-+ if (flags & MIPV6_BU_F_HOME)
-+ mip6_fn.bce_home_del(dst, haddr, coa, reply_coa,
-+ sequence, flags, key_bu);
-+ else {
-+ mipv6_rr_invalidate_nonce(nonce_ind);
-+ mip6_fn.bce_cache_del(dst, haddr, coa, reply_coa,
-+ sequence, flags, key_bu);
-+ }
-+ }
-+ out:
-+ MIPV6_INC_STATS(n_bu_rcvd);
-+ if (key_bu)
-+ kfree(key_bu);
-+ return 0;
-+}
-+
-+static int mipv6_mh_rcv(struct sk_buff *skb)
-+{
-+ struct inet6_skb_parm *opt = (struct inet6_skb_parm *)skb->cb;
-+ struct mipv6_mh *mh;
-+ struct in6_addr *lhome, *fhome, *lcoa = NULL, *fcoa = NULL;
-+ int ret = 0;
-+
-+ fhome = &skb->nh.ipv6h->saddr;
-+ lhome = &skb->nh.ipv6h->daddr;
-+
-+ if (opt->hao != 0) {
-+ struct mipv6_dstopt_homeaddr *hao;
-+ hao = (struct mipv6_dstopt_homeaddr *)(skb->nh.raw + opt->hao);
-+ fcoa = &hao->addr;
-+ }
-+
-+ if (opt->srcrt2 != 0) {
-+ struct rt2_hdr *rt2;
-+ rt2 = (struct rt2_hdr *)((u8 *)skb->nh.raw + opt->srcrt2);
-+ lcoa = &rt2->addr;
-+ }
-+
-+ /* Verify checksum is correct */
-+ if (skb->ip_summed == CHECKSUM_HW) {
-+ skb->ip_summed = CHECKSUM_UNNECESSARY;
-+ if (csum_ipv6_magic(fhome, lhome, skb->len, IPPROTO_MOBILITY,
-+ skb->csum)) {
-+ if (net_ratelimit())
-+ printk(KERN_WARNING "MIPv6 MH hw checksum failed\n");
-+ skb->ip_summed = CHECKSUM_NONE;
-+ }
-+ }
-+ if (skb->ip_summed == CHECKSUM_NONE) {
-+ if (csum_ipv6_magic(fhome, lhome, skb->len, IPPROTO_MOBILITY,
-+ skb_checksum(skb, 0, skb->len, 0))) {
-+ if (net_ratelimit())
-+ printk(KERN_WARNING "MIPv6 MH checksum failed\n");
-+ goto bad;
-+ }
-+ }
-+
-+ if (!pskb_may_pull(skb, skb->h.raw-skb->data+sizeof(*mh)) ||
-+ !pskb_may_pull(skb,
-+ skb->h.raw-skb->data+((skb->h.raw[1]+1)<<3))) {
-+ DEBUG(DBG_INFO, "MIPv6 MH invalid length");
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+
-+ mh = (struct mipv6_mh *) skb->h.raw;
-+
-+ /* Verify there are no more headers after the MH */
-+ if (mh->payload != NEXTHDR_NONE) {
-+ __u32 pos = (__u32)&mh->payload - (__u32)skb->nh.raw;
-+ icmpv6_send(skb, ICMPV6_PARAMPROB,
-+ ICMPV6_HDR_FIELD, pos, skb->dev);
-+
-+ DEBUG(DBG_INFO, "MIPv6 MH error");
-+ goto bad;
-+ }
-+
-+ if (mh->type > MIPV6_MH_MAX) {
-+ /* send binding error */
-+ printk("Invalid mobility header type (%d)\n", mh->type);
-+ mipv6_send_be(lhome, fcoa ? fcoa : fhome,
-+ fcoa ? fhome : NULL,
-+ MIPV6_BE_UNKNOWN_MH_TYPE);
-+ goto bad;
-+ }
-+ if (mh_rcv[mh->type].func != NULL) {
-+ ret = mh_rcv[mh->type].func(skb, lhome, lcoa, fhome, fcoa, mh);
-+ } else {
-+ DEBUG(DBG_INFO, "No handler for MH Type %d", mh->type);
-+ goto bad;
-+ }
-+
-+ kfree_skb(skb);
-+ return 0;
-+
-+bad:
-+ MIPV6_INC_STATS(n_mh_in_error);
-+ kfree_skb(skb);
-+ return 0;
-+
-+}
-+
-+#if LINUX_VERSION_CODE >= 0x2052a
-+struct inet6_protocol mipv6_mh_protocol =
-+{
-+ mipv6_mh_rcv, /* handler */
-+ NULL /* error control */
-+};
-+#else
-+struct inet6_protocol mipv6_mh_protocol =
-+{
-+ mipv6_mh_rcv, /* handler */
-+ NULL, /* error control */
-+ NULL, /* next */
-+ IPPROTO_MOBILITY, /* protocol ID */
-+ 0, /* copy */
-+ NULL, /* data */
-+ "MIPv6 MH" /* name */
-+};
-+#endif
-+
-+/*
-+ *
-+ * Code module init/exit functions
-+ *
-+ */
-+
-+int __init mipv6_mh_common_init(void)
-+{
-+ struct sock *sk;
-+ int err;
-+
-+ mip6_fn.bce_home_add = bc_cn_home_add;
-+ mip6_fn.bce_cache_add = bc_cache_add;
-+ mip6_fn.bce_home_del = bc_cn_home_delete;
-+ mip6_fn.bce_cache_del = bc_cache_delete;
-+
-+ mipv6_mh_socket = sock_alloc();
-+ if (mipv6_mh_socket == NULL) {
-+ printk(KERN_ERR
-+ "Failed to create the MIP6 MH control socket.\n");
-+ return -1;
-+ }
-+ mipv6_mh_socket->type = SOCK_RAW;
-+
-+ if ((err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_MOBILITY,
-+ &mipv6_mh_socket)) < 0) {
-+ printk(KERN_ERR
-+ "Failed to initialize the MIP6 MH control socket (err %d).\n",
-+ err);
-+ sock_release(mipv6_mh_socket);
-+ mipv6_mh_socket = NULL; /* for safety */
-+ return err;
-+ }
-+
-+ sk = mipv6_mh_socket->sk;
-+ sk->allocation = GFP_ATOMIC;
-+ sk->sndbuf = 64 * 1024 + sizeof(struct sk_buff);
-+ sk->prot->unhash(sk);
-+
-+ memset(&mh_rcv, 0, sizeof(mh_rcv));
-+ mh_rcv[MIPV6_MH_HOTI].func = mipv6_handle_mh_testinit;
-+ mh_rcv[MIPV6_MH_COTI].func = mipv6_handle_mh_testinit;
-+ mh_rcv[MIPV6_MH_BU].func = mipv6_handle_mh_bu;
-+
-+#if LINUX_VERSION_CODE >= 0x2052a
-+ if (inet6_add_protocol(&mipv6_mh_protocol, IPPROTO_MOBILITY) < 0) {
-+ printk(KERN_ERR "Failed to register MOBILITY protocol\n");
-+ sock_release(mipv6_mh_socket);
-+ mipv6_mh_socket = NULL;
-+ return -EAGAIN;
-+ }
-+#else
-+ inet6_add_protocol(&mipv6_mh_protocol);
-+#endif
-+ /* To disable the use of dst_cache,
-+ * which slows down the sending of BUs ??
-+ */
-+ sk->dst_cache=NULL;
-+
-+ return 0;
-+}
-+
-+void __exit mipv6_mh_common_exit(void)
-+{
-+ if (mipv6_mh_socket) sock_release(mipv6_mh_socket);
-+ mipv6_mh_socket = NULL; /* For safety. */
-+
-+#if LINUX_VERSION_CODE >= 0x2052a
-+ inet6_del_protocol(&mipv6_mh_protocol, IPPROTO_MOBILITY);
-+#else
-+ inet6_del_protocol(&mipv6_mh_protocol);
-+#endif
-+ memset(&mh_rcv, 0, sizeof(mh_rcv));
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/mobhdr_mn.c linux-2.4.25/net/ipv6/mobile_ip6/mobhdr_mn.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/mobhdr_mn.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/mobhdr_mn.c 2004-06-26 11:29:32.000000000 +0100
-@@ -0,0 +1,1155 @@
-+/*
-+ * Mobile IPv6 Mobility Header Functions for Mobile Node
-+ *
-+ * Authors:
-+ * Antti Tuominen <ajtuomin@tml.hut.fi>
-+ * Niklas Kämpe <nhkampe@cc.hut.fi>
-+ * Henrik Petander <henrik.petander@hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License as
-+ * published by the Free Software Foundation; either version 2 of
-+ * the License, or (at your option) any later version.
-+ *
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/init.h>
-+#include <net/ipv6.h>
-+#include <net/addrconf.h>
-+#include <net/mipv6.h>
-+
-+#include "mobhdr.h"
-+#include "mn.h"
-+#include "bul.h"
-+#include "rr_crypto.h"
-+#include "debug.h"
-+#include "util.h"
-+#include "stats.h"
-+
-+int rr_configured = 1;
-+
-+/* Return value of mipv6_rr_state() */
-+#define NO_RR 0
-+#define DO_RR 1
-+#define RR_FOR_COA 2
-+#define INPROGRESS_RR 3
-+
-+/**
-+ * send_bu_msg - sends a Binding Update
-+ * @bulentry : BUL entry with the information for building a BU
-+ *
-+ * Function builds a BU msg based on the contents of a bul entry.
-+ * Does not change the bul entry.
-+ **/
-+static int send_bu_msg(struct mipv6_bul_entry *binding)
-+{
-+ int auth = 0; /* Use auth */
-+ int ret = 0;
-+ struct mipv6_auth_parm parm;
-+ struct mipv6_mh_bu bu;
-+
-+ if (!binding) {
-+ DEBUG(DBG_ERROR, "called with a null bul entry");
-+ return -1;
-+ }
-+
-+ memset(&parm, 0, sizeof(parm));
-+ if (mipv6_prefix_compare(&binding->coa, &binding->home_addr, 64))
-+ parm.coa = &binding->home_addr;
-+ else
-+ parm.coa = &binding->coa;
-+ parm.cn_addr = &binding->cn_addr;
-+
-+ if (binding->rr && binding->rr->kbu) {
-+ DEBUG(DBG_INFO, "Binding with key");
-+ auth = 1;
-+ parm.k_bu = binding->rr->kbu;
-+ }
-+ memset(&bu, 0, sizeof(bu));
-+ bu.flags = binding->flags;
-+ bu.sequence = htons(binding->seq);
-+ bu.lifetime = htons(binding->lifetime >> 2);
-+ bu.reserved = 0;
-+
-+ ret = send_mh(&binding->cn_addr, &binding->home_addr,
-+ MIPV6_MH_BU, sizeof(bu), (u8 *)&bu,
-+ &binding->home_addr, NULL,
-+ binding->ops, &parm);
-+
-+ if (ret == 0)
-+ MIPV6_INC_STATS(n_bu_sent);
-+
-+ return ret;
-+}
-+
-+/**
-+ * mipv6_send_addr_test_init - send a HoTI or CoTI message
-+ * @saddr: source address for H/CoTI
-+ * @daddr: destination address for H/CoTI
-+ * @msg_type: Identifies whether HoTI or CoTI
-+ * @init_cookie: the HoTi or CoTi init cookie
-+ *
-+ * The message will be retransmitted till we get a HoT or CoT message, since
-+ * our caller (mipv6_RR_start) has entered this message in the BUL with
-+ * exponential backoff retramission set.
-+ */
-+static int mipv6_send_addr_test_init(struct in6_addr *saddr,
-+ struct in6_addr *daddr,
-+ u8 msg_type,
-+ u8 *init_cookie)
-+{
-+ struct mipv6_mh_addr_ti ti;
-+ struct mipv6_mh_opt *ops = NULL;
-+ int ret = 0;
-+
-+ /* Set reserved and copy the cookie from address test init msg */
-+ ti.reserved = 0;
-+ mipv6_rr_mn_cookie_create(init_cookie);
-+ memcpy(ti.init_cookie, init_cookie, MIPV6_RR_COOKIE_LENGTH);
-+
-+ ret = send_mh(daddr, saddr, msg_type, sizeof(ti), (u8 *)&ti,
-+ NULL, NULL, ops, NULL);
-+ if (ret == 0) {
-+ if (msg_type == MIPV6_MH_HOTI) {
-+ MIPV6_INC_STATS(n_hoti_sent);
-+ } else {
-+ MIPV6_INC_STATS(n_coti_sent);
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+/*
-+ *
-+ * Callback handlers for binding update list
-+ *
-+ */
-+
-+/* Return value 0 means keep entry, non-zero means discard entry. */
-+
-+/* Callback for BUs not requiring acknowledgement
-+ */
-+int bul_entry_expired(struct mipv6_bul_entry *bulentry)
-+{
-+ /* Lifetime expired, delete entry. */
-+ DEBUG(DBG_INFO, "bul entry 0x%p lifetime expired, deleting entry",
-+ bulentry);
-+ return 1;
-+}
-+
-+/* Callback for BUs requiring acknowledgement with exponential resending
-+ * scheme */
-+static int bul_resend_exp(struct mipv6_bul_entry *bulentry)
-+{
-+ unsigned long now = jiffies;
-+
-+ DEBUG(DBG_INFO, "(0x%x) resending bu", (int) bulentry);
-+
-+
-+ /* If sending a de-registration, do not care about the
-+ * lifetime value, as de-registrations are normally sent with
-+ * a zero lifetime value. If the entry is a home entry get the
-+ * current lifetime.
-+ */
-+
-+ if (bulentry->lifetime != 0) {
-+ bulentry->lifetime = mipv6_mn_get_bulifetime(
-+ &bulentry->home_addr, &bulentry->coa, bulentry->flags);
-+
-+ bulentry->expire = now + bulentry->lifetime * HZ;
-+ } else {
-+ bulentry->expire = now + HOME_RESEND_EXPIRE * HZ;
-+ }
-+ if (bulentry->rr) {
-+ /* Redo RR, if cookies have expired */
-+ if (time_after(jiffies, bulentry->rr->home_time + MAX_TOKEN_LIFE * HZ))
-+ bulentry->rr->rr_state |= RR_WAITH;
-+ if (time_after(jiffies, bulentry->rr->careof_time + MAX_NONCE_LIFE * HZ))
-+ bulentry->rr->rr_state |= RR_WAITC;
-+
-+ if (bulentry->rr->rr_state & RR_WAITH) {
-+ /* Resend HoTI directly */
-+ mipv6_send_addr_test_init(&bulentry->home_addr,
-+ &bulentry->cn_addr, MIPV6_MH_HOTI,
-+ bulentry->rr->hot_cookie);
-+ }
-+ if (bulentry->rr->rr_state & RR_WAITC) {
-+ /* Resend CoTI directly */
-+ mipv6_send_addr_test_init(&bulentry->coa,
-+ &bulentry->cn_addr, MIPV6_MH_COTI,
-+ bulentry->rr->cot_cookie);
-+ }
-+ goto out;
-+ }
-+
-+ bulentry->seq++;
-+
-+ if (send_bu_msg(bulentry) < 0)
-+ DEBUG(DBG_ERROR, "Resending of BU failed");
-+
-+out:
-+ /* Schedule next retransmission */
-+ if (bulentry->delay < bulentry->maxdelay) {
-+ bulentry->delay = 2 * bulentry->delay;
-+ if (bulentry->delay > bulentry->maxdelay) {
-+ /* can happen if maxdelay is not power(mindelay, 2) */
-+ bulentry->delay = bulentry->maxdelay;
-+ }
-+ } else if (bulentry->flags & MIPV6_BU_F_HOME) {
-+ /* Home registration - continue sending BU at maxdelay rate */
-+ DEBUG(DBG_INFO, "Sending BU to HA after max ack wait time "
-+ "reached(0x%x)", (int) bulentry);
-+ bulentry->delay = bulentry->maxdelay;
-+ } else if (!(bulentry->flags & MIPV6_BU_F_HOME)) {
-+ /* Failed to get BA from a CN */
-+ bulentry->callback_time = now;
-+ return -1;
-+ }
-+
-+ bulentry->callback_time = now + bulentry->delay * HZ;
-+ return 0;
-+}
-+
-+
-+
-+/* Callback for sending a registration refresh BU
-+ */
-+static int bul_refresh(struct mipv6_bul_entry *bulentry)
-+{
-+ unsigned long now = jiffies;
-+
-+ /* Refresh interval passed, send new BU */
-+ DEBUG(DBG_INFO, "bul entry 0x%x refresh interval passed, sending new BU", (int) bulentry);
-+ if (bulentry->lifetime == 0)
-+ return 0;
-+
-+ /* Set new maximum lifetime and expiration time */
-+ bulentry->lifetime = mipv6_mn_get_bulifetime(&bulentry->home_addr,
-+ &bulentry->coa,
-+ bulentry->flags);
-+ bulentry->expire = now + bulentry->lifetime * HZ;
-+ bulentry->seq++;
-+ /* Send update */
-+ if (send_bu_msg(bulentry) < 0)
-+ DEBUG(DBG_ERROR, "Resending of BU failed");
-+
-+ if (time_after_eq(now, bulentry->expire)) {
-+ /* Sanity check */
-+ DEBUG(DBG_ERROR, "bul entry expire time in history - setting expire to %u secs", ERROR_DEF_LIFETIME);
-+ bulentry->lifetime = ERROR_DEF_LIFETIME;
-+ bulentry->expire = now + ERROR_DEF_LIFETIME*HZ;
-+ }
-+
-+ /* Set up retransmission */
-+ bulentry->state = RESEND_EXP;
-+ bulentry->callback = bul_resend_exp;
-+ bulentry->callback_time = now + INITIAL_BINDACK_TIMEOUT*HZ;
-+ bulentry->delay = INITIAL_BINDACK_TIMEOUT;
-+ bulentry->maxdelay = MAX_BINDACK_TIMEOUT;
-+
-+ return 0;
-+}
-+
-+static int mipv6_send_RR_bu(struct mipv6_bul_entry *bulentry)
-+{
-+ int ret;
-+ int ops_len = 0;
-+ u16 nonces[2];
-+
-+ DEBUG(DBG_INFO, "Sending BU to CN %x:%x:%x:%x:%x:%x:%x:%x "
-+ "for home address %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(&bulentry->cn_addr), NIPV6ADDR(&bulentry->home_addr));
-+ nonces[0] = bulentry->rr->home_nonce_index;
-+ nonces[1] = bulentry->rr->careof_nonce_index;
-+ ops_len = sizeof(struct mipv6_mo_bauth_data) + MIPV6_RR_MAC_LENGTH +
-+ sizeof(struct mipv6_mo_nonce_indices);
-+ if (bulentry->ops) {
-+ DEBUG(DBG_WARNING, "Bul entry had existing mobility options, freeing them");
-+ kfree(bulentry->ops);
-+ }
-+ bulentry->ops = alloc_mh_opts(ops_len);
-+
-+ if (!bulentry->ops)
-+ return -ENOMEM;
-+ if (append_mh_opt(bulentry->ops, MIPV6_OPT_NONCE_INDICES,
-+ sizeof(struct mipv6_mo_nonce_indices) - 2, nonces) < 0)
-+ return -ENOMEM;
-+
-+ if (append_mh_opt(bulentry->ops, MIPV6_OPT_AUTH_DATA,
-+ MIPV6_RR_MAC_LENGTH, NULL) < 0)
-+ return -ENOMEM;
-+ /* RR procedure is over, send a BU */
-+ if (!(bulentry->flags & MIPV6_BU_F_ACK)) {
-+ DEBUG(DBG_INFO, "Setting bul callback to bul_entry_expired");
-+ bulentry->state = ACK_OK;
-+ bulentry->callback = bul_entry_expired;
-+ bulentry->callback_time = jiffies + HZ * bulentry->lifetime;
-+ bulentry->expire = jiffies + HZ * bulentry->lifetime;
-+ }
-+ else {
-+ bulentry->callback_time = jiffies + HZ;
-+ bulentry->expire = jiffies + HZ * bulentry->lifetime;
-+ }
-+
-+ ret = send_bu_msg(bulentry);
-+ mipv6_bul_reschedule(bulentry);
-+ return ret;
-+}
-+
-+static int mipv6_rr_state(struct mipv6_bul_entry *bul, struct in6_addr *saddr,
-+ struct in6_addr *coa, __u8 flags)
-+{
-+ if (!rr_configured)
-+ return NO_RR;
-+ if (flags & MIPV6_BU_F_HOME) {
-+ /* We don't need RR, this is a Home Registration */
-+ return NO_RR;
-+ }
-+ if (!bul || !bul->rr) {
-+ /* First time BU to CN, need RR */
-+ return DO_RR;
-+ }
-+
-+ switch (bul->rr->rr_state) {
-+ case RR_INIT:
-+ /* Need RR if first BU to CN */
-+ return DO_RR;
-+ case RR_DONE:
-+ /* If MN moves to a new coa, do RR for it */
-+ if (!ipv6_addr_cmp(&bul->coa, coa))
-+ return NO_RR;
-+ else
-+ return DO_RR;
-+ default:
-+ /*
-+ * We are in the middle of RR, the HoTI and CoTI have been
-+ * sent. But we haven't got HoT and CoT from the CN, so
-+ * don't do anything more at this time.
-+ */
-+ return INPROGRESS_RR;
-+ }
-+}
-+
-+/**
-+ * mipv6_RR_start - Start Return Routability procedure
-+ * @home_addr: home address
-+ * @cn_addr: correspondent address
-+ * @coa: care-of address
-+ * @entry: binding update list entry (if any)
-+ * @initdelay: initial ack timeout
-+ * @maxackdelay: maximum ack timeout
-+ * @flags: flags
-+ * @lifetime: lifetime of binding
-+ * @ops: mobility options
-+ *
-+ * Caller must hold @bul_lock (write).
-+ **/
-+static int mipv6_RR_start(struct in6_addr *home_addr, struct in6_addr *cn_addr,
-+ struct in6_addr *coa, struct mipv6_bul_entry *entry,
-+ __u32 initdelay, __u32 maxackdelay, __u8 flags,
-+ __u32 lifetime, struct mipv6_mh_opt *ops)
-+{
-+ int ret = -1;
-+ struct mipv6_bul_entry *bulentry = entry;
-+ struct mipv6_rr_info *rr = NULL;
-+ int seq = 0;
-+ DEBUG_FUNC();
-+
-+ /* Do RR procedure only for care-of address after handoff,
-+ if home cookie is still valid */
-+ if (bulentry && bulentry->rr) {
-+ if (time_before(jiffies, bulentry->rr->home_time + MAX_NONCE_LIFE * HZ) &&
-+ lifetime && !(ipv6_addr_cmp(home_addr, coa) == 0)) {
-+ mipv6_rr_mn_cookie_create(bulentry->rr->cot_cookie);
-+ DEBUG(DBG_INFO, "Bul entry and rr info exist, only doing RR for CoA");
-+ ipv6_addr_copy(&bulentry->coa, coa);
-+ bulentry->rr->rr_state |= RR_WAITC;
-+ } else if (!lifetime) { /* Send only HoTi when returning home */
-+ mipv6_rr_mn_cookie_create(bulentry->rr->hot_cookie);
-+ DEBUG(DBG_INFO, "Bul entry and rr info exist, only doing RR for HoA");
-+ ipv6_addr_copy(&bulentry->coa, coa); /* Home address as CoA */
-+ bulentry->rr->rr_state |= RR_WAITH;
-+ }
-+ } else {
-+ DEBUG(DBG_INFO, "Doing RR for both HoA and CoA");
-+ rr = kmalloc(sizeof(*rr), GFP_ATOMIC);
-+ memset(rr, 0, sizeof(*rr));
-+ rr->rr_state = RR_WAITHC;
-+ }
-+ if (bulentry) {
-+ if (bulentry->state == ACK_ERROR)
-+ goto out;
-+ seq = bulentry->seq + 1;
-+ } else
-+ seq = 0;
-+ /* Save the info in the BUL to retransmit the BU after RR is done */
-+ /* Caller must hold bul_lock (write) since we don't */
-+
-+ if ((bulentry = mipv6_bul_add(cn_addr, home_addr, coa,
-+ min_t(__u32, lifetime, MAX_RR_BINDING_LIFE),
-+ seq, flags, bul_resend_exp, initdelay,
-+ RESEND_EXP, initdelay,
-+ maxackdelay, ops,
-+ rr)) == NULL) {
-+ DEBUG(DBG_INFO, "couldn't update BUL for HoTi");
-+ goto out;
-+ }
-+
-+ rr = bulentry->rr;
-+ if (rr->rr_state&RR_WAITH)
-+ mipv6_send_addr_test_init(home_addr, cn_addr, MIPV6_MH_HOTI,
-+ rr->hot_cookie);
-+ if (ipv6_addr_cmp(home_addr, coa) && lifetime)
-+ mipv6_send_addr_test_init(coa, cn_addr, MIPV6_MH_COTI, rr->cot_cookie);
-+ else {
-+ bulentry->rr->rr_state &= ~RR_WAITC;
-+ }
-+ ret = 0;
-+out:
-+ return ret;
-+}
-+
-+/*
-+ * Status codes for mipv6_ba_rcvd()
-+ */
-+#define STATUS_UPDATE 0
-+#define STATUS_REMOVE 1
-+
-+/**
-+ * mipv6_ba_rcvd - Update BUL for this Binding Acknowledgement
-+ * @ifindex: interface BA came from
-+ * @cnaddr: sender IPv6 address
-+ * @home_addr: home address
-+ * @sequence: sequence number
-+ * @lifetime: lifetime granted by Home Agent in seconds
-+ * @refresh: recommended resend interval
-+ * @status: %STATUS_UPDATE (ack) or %STATUS_REMOVE (nack)
-+ *
-+ * This function must be called to notify the module of the receipt of
-+ * a binding acknowledgement so that it can cease retransmitting the
-+ * option. The caller must have validated the acknowledgement before calling
-+ * this function. 'status' can be either STATUS_UPDATE in which case the
-+ * binding acknowledgement is assumed to be valid and the corresponding
-+ * binding update list entry is updated, or STATUS_REMOVE in which case
-+ * the corresponding binding update list entry is removed (this can be
-+ * used upon receiving a negative acknowledgement).
-+ * Returns 0 if a matching binding update has been sent or non-zero if
-+ * not.
-+ */
-+static int mipv6_ba_rcvd(int ifindex, struct in6_addr *cnaddr,
-+ struct in6_addr *home_addr,
-+ u16 sequence, u32 lifetime,
-+ u32 refresh, int status)
-+{
-+ struct mipv6_bul_entry *bulentry;
-+ unsigned long now = jiffies;
-+ struct in6_addr coa;
-+
-+ DEBUG(DBG_INFO, "BA received with sequence number 0x%x, status: %d",
-+ (int) sequence, status);
-+
-+ /* Find corresponding entry in binding update list. */
-+ write_lock(&bul_lock);
-+ if ((bulentry = mipv6_bul_get(cnaddr, home_addr)) == NULL) {
-+ DEBUG(DBG_INFO, "- discarded, no entry in bul matches BA source address");
-+ write_unlock(&bul_lock);
-+ return -1;
-+ }
-+
-+ ipv6_addr_copy(&coa, &bulentry->coa);
-+ if (status == SEQUENCE_NUMBER_OUT_OF_WINDOW) {
-+ __u32 lifetime = mipv6_mn_get_bulifetime(&bulentry->home_addr,
-+ &bulentry->coa,
-+ bulentry->flags);
-+ bulentry->seq = sequence;
-+
-+ mipv6_send_bu(&bulentry->home_addr, &bulentry->cn_addr,
-+ &bulentry->coa, INITIAL_BINDACK_TIMEOUT,
-+ MAX_BINDACK_TIMEOUT, 1, bulentry->flags,
-+ lifetime, NULL);
-+ write_unlock(&bul_lock);
-+ return 0;
-+ } else if (status >= REASON_UNSPECIFIED) {
-+ int err;
-+ int at_home = MN_NOT_AT_HOME;
-+ DEBUG(DBG_WARNING, "- NACK - BA status: %d, deleting bul entry", status);
-+ if (bulentry->flags & MIPV6_BU_F_HOME) {
-+ struct mn_info *minfo;
-+ read_lock(&mn_info_lock);
-+ minfo = mipv6_mninfo_get_by_home(home_addr);
-+ if (minfo) {
-+ spin_lock(&minfo->lock);
-+ if (minfo->is_at_home != MN_NOT_AT_HOME)
-+ minfo->is_at_home = MN_AT_HOME;
-+ at_home = minfo->is_at_home;
-+ minfo->has_home_reg = 0;
-+ spin_unlock(&minfo->lock);
-+ }
-+ read_unlock(&mn_info_lock);
-+ DEBUG(DBG_ERROR, "Home registration failed: BA status: %d, deleting bul entry", status);
-+ }
-+ write_unlock(&bul_lock);
-+ err = mipv6_bul_delete(cnaddr, home_addr);
-+ if (at_home == MN_AT_HOME) {
-+ mipv6_mn_send_home_na(home_addr);
-+ write_lock_bh(&bul_lock);
-+ mipv6_bul_iterate(mn_cn_handoff, &coa);
-+ write_unlock_bh(&bul_lock);
-+ }
-+ return err;
-+ }
-+ bulentry->state = ACK_OK;
-+
-+ if (bulentry->flags & MIPV6_BU_F_HOME && lifetime > 0) {
-+ /* For home registrations: schedule a refresh binding update.
-+ * Use the refresh interval given by home agent or 80%
-+ * of lifetime, whichever is less.
-+ *
-+ * Adjust binding lifetime if 'granted' lifetime
-+ * (lifetime value in received binding acknowledgement)
-+ * is shorter than 'requested' lifetime (lifetime
-+ * value sent in corresponding binding update).
-+ * max((L_remain - (L_update - L_ack)), 0)
-+ */
-+ if (lifetime * HZ < (bulentry->expire - bulentry->lastsend)) {
-+ bulentry->expire =
-+ max_t(__u32, bulentry->expire -
-+ ((bulentry->expire - bulentry->lastsend) -
-+ lifetime * HZ), jiffies +
-+ ERROR_DEF_LIFETIME * HZ);
-+ }
-+ if (refresh > lifetime || refresh == 0)
-+ refresh = 4 * lifetime / 5;
-+ DEBUG(DBG_INFO, "setting callback for expiration of"
-+ " a Home Registration: lifetime:%d, refresh:%d",
-+ lifetime, refresh);
-+ bulentry->callback = bul_refresh;
-+ bulentry->callback_time = now + refresh * HZ;
-+ bulentry->expire = now + lifetime * HZ;
-+ bulentry->lifetime = lifetime;
-+ if (time_after_eq(jiffies, bulentry->expire)) {
-+ /* Sanity check */
-+ DEBUG(DBG_ERROR, "bul entry expire time in history - setting expire to %u secs",
-+ ERROR_DEF_LIFETIME);
-+ bulentry->expire = jiffies + ERROR_DEF_LIFETIME * HZ;
-+ }
-+ mipv6_mn_set_home_reg(home_addr, 1);
-+ mipv6_bul_iterate(mn_cn_handoff, &coa);
-+ } else if ((bulentry->flags & MIPV6_BU_F_HOME) && bulentry->lifetime == 0) {
-+ write_unlock(&bul_lock);
-+ DEBUG(DBG_INFO, "Got BA for deregistration BU");
-+ mipv6_mn_set_home_reg(home_addr, 0);
-+ mipv6_bul_delete(cnaddr, home_addr);
-+ mipv6_mn_send_home_na(home_addr);
-+
-+ write_lock_bh(&bul_lock);
-+ mipv6_bul_iterate(mn_cn_handoff, &coa);
-+ write_unlock_bh(&bul_lock);
-+ return 0;
-+ }
-+
-+ mipv6_bul_reschedule(bulentry);
-+ write_unlock(&bul_lock);
-+
-+ return 0;
-+}
-+
-+static int mipv6_handle_mh_HC_test(struct sk_buff *skb,
-+ struct in6_addr *saddr,
-+ struct in6_addr *fcoa,
-+ struct in6_addr *cn,
-+ struct in6_addr *lcoa,
-+ struct mipv6_mh *mh)
-+{
-+ int ret = 0;
-+ int msg_len = (mh->length+1) << 3;
-+ int opt_len;
-+
-+ struct mipv6_mh_addr_test *tm = (struct mipv6_mh_addr_test *)mh->data;
-+ struct mipv6_bul_entry *bulentry;
-+
-+ DEBUG_FUNC();
-+
-+ if (msg_len > skb->len)
-+ return -1;
-+
-+ opt_len = msg_len - sizeof(*mh) - sizeof(*tm);
-+
-+ if (opt_len < 0) {
-+ __u32 pos = (__u32)&mh->length - (__u32)skb->nh.raw;
-+ icmpv6_send(skb, ICMPV6_PARAMPROB,
-+ ICMPV6_HDR_FIELD, pos, skb->dev);
-+
-+ DEBUG(DBG_INFO, "Mobility Header length less than H/C Test");
-+ return -1;
-+ }
-+ if (fcoa || lcoa) {
-+ DEBUG(DBG_INFO, "H/C Test has HAO or RTH2, dropped.");
-+ return -1;
-+ }
-+ write_lock(&bul_lock);
-+
-+ /* We need to get the home address, since CoT only has the CoA*/
-+ if (mh->type == MIPV6_MH_COT) {
-+ if ((bulentry = mipv6_bul_get_by_ccookie(cn, tm->init_cookie)) == NULL) {
-+ DEBUG(DBG_ERROR, "has no BUL or RR state for "
-+ "source:%x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(cn));
-+ write_unlock(&bul_lock);
-+ return -1;
-+ }
-+ } else { /* HoT has the home address */
-+ if (((bulentry = mipv6_bul_get(cn, saddr)) == NULL) || !bulentry->rr) {
-+ DEBUG(DBG_ERROR, "has no BUL or RR state for "
-+ "source:%x:%x:%x:%x:%x:%x:%x:%x "
-+ "dest:%x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(cn), NIPV6ADDR(saddr));
-+ write_unlock(&bul_lock);
-+ return -1;
-+ }
-+ }
-+
-+ switch (mh->type) {
-+ case MIPV6_MH_HOT:
-+ if ((bulentry->rr->rr_state & RR_WAITH) == 0) {
-+ DEBUG(DBG_ERROR, "Not waiting for a Home Test message");
-+ goto out;
-+ }
-+ /*
-+ * Make sure no home cookies have been received yet.
-+ * TODO: Check not being put in at this time since subsequent
-+ * BU's after this time will have home cookie stored.
-+ */
-+
-+ /* Check if the cookie received is the right one */
-+ if (!mipv6_equal_cookies(tm->init_cookie,
-+ bulentry->rr->hot_cookie)) {
-+ /* Invalid cookie, might be an old cookie */
-+ DEBUG(DBG_WARNING, "Received HoT cookie does not match stored cookie");
-+ goto out;
-+ }
-+ DEBUG(DBG_INFO, "Got Care-of Test message");
-+ bulentry->rr->rr_state &= ~RR_WAITH;
-+ memcpy(bulentry->rr->home_cookie, tm->kgen_token, MIPV6_COOKIE_LEN);
-+ bulentry->rr->home_nonce_index = tm->nonce_index;
-+ bulentry->rr->home_time = jiffies;
-+ ret = 1;
-+ break;
-+
-+ case MIPV6_MH_COT:
-+ if ((bulentry->rr->rr_state & RR_WAITC) == 0) {
-+ DEBUG(DBG_ERROR, "Not waiting for a Home Test message");
-+ goto out;
-+ }
-+ /*
-+ * Make sure no home cookies have been received yet.
-+ * TODO: Check not being put in at this time since subsequent
-+ * BU's at this time will have careof cookie stored.
-+ */
-+
-+ /* Check if the cookie received is the right one */
-+ if (!mipv6_equal_cookies(tm->init_cookie,
-+ bulentry->rr->cot_cookie)) {
-+ DEBUG(DBG_INFO, "Received CoT cookie does not match stored cookie");
-+ goto out;
-+ }
-+ bulentry->rr->rr_state &= ~RR_WAITC;
-+ memcpy(bulentry->rr->careof_cookie, tm->kgen_token, MIPV6_COOKIE_LEN);
-+ bulentry->rr->careof_nonce_index = tm->nonce_index;
-+ bulentry->rr->careof_time = jiffies;
-+ ret = 1;
-+ break;
-+ default:
-+ /* Impossible to get here */
-+ break;
-+ }
-+out:
-+ if (bulentry->rr->rr_state == RR_DONE) {
-+ if (bulentry->rr->kbu) /* First free any old keys */
-+ kfree(bulentry->rr->kbu);
-+ /* Store the session key to be used in BU's */
-+ if (ipv6_addr_cmp(&bulentry->coa, &bulentry->home_addr) && bulentry->lifetime)
-+ bulentry->rr->kbu = mipv6_rr_key_calc(bulentry->rr->home_cookie,
-+ bulentry->rr->careof_cookie);
-+ else
-+ bulentry->rr->kbu = mipv6_rr_key_calc(bulentry->rr->home_cookie,
-+ NULL);
-+ /* RR procedure is over, send a BU */
-+ mipv6_send_RR_bu(bulentry);
-+ }
-+ write_unlock(&bul_lock);
-+ return ret;
-+}
-+
-+/**
-+ * mipv6_handle_mh_brr - Binding Refresh Request handler
-+ * @home: home address
-+ * @coa: care-of address
-+ * @cn: source of this packet
-+ * @mh: pointer to the beginning of the Mobility Header
-+ *
-+ * Handles Binding Refresh Request. Packet and offset to option are
-+ * passed. Returns 0 on success, otherwise negative.
-+ **/
-+static int mipv6_handle_mh_brr(struct sk_buff *skb,
-+ struct in6_addr *home,
-+ struct in6_addr *unused1,
-+ struct in6_addr *cn,
-+ struct in6_addr *unused2,
-+ struct mipv6_mh *mh)
-+{
-+ struct mipv6_mh_brr *brr = (struct mipv6_mh_brr *)mh->data;
-+ struct mipv6_bul_entry *binding;
-+ int msg_len = (mh->length+1) << 3;
-+ int opt_len;
-+
-+ if (msg_len > skb->len)
-+ return -1;
-+
-+ opt_len = msg_len - sizeof(*mh) - sizeof(*brr);
-+
-+ if (opt_len < 0) {
-+ __u32 pos = (__u32)&mh->length - (__u32)skb->nh.raw;
-+ icmpv6_send(skb, ICMPV6_PARAMPROB,
-+ ICMPV6_HDR_FIELD, pos, skb->dev);
-+
-+ DEBUG(DBG_WARNING, "Mobility Header length less than BRR");
-+ MIPV6_INC_STATS(n_brr_drop.invalid);
-+ return -1;
-+ }
-+
-+ /* check we know src, else drop */
-+ write_lock(&bul_lock);
-+ if ((binding = mipv6_bul_get(cn, home)) == NULL) {
-+ MIPV6_INC_STATS(n_brr_drop.misc);
-+ write_unlock(&bul_lock);
-+ return MH_UNKNOWN_CN;
-+ }
-+
-+ MIPV6_INC_STATS(n_brr_rcvd);
-+
-+ if (opt_len > 0) {
-+ struct mobopt opts;
-+ memset(&opts, 0, sizeof(opts));
-+ if (parse_mo_tlv(brr + 1, opt_len, &opts) < 0) {
-+ write_unlock(&bul_lock);
-+ return -1;
-+ }
-+ /*
-+ * MIPV6_OPT_AUTH_DATA
-+ */
-+ }
-+
-+ /* must hold bul_lock (write) */
-+ mipv6_RR_start(home, cn, &binding->coa, binding, binding->delay,
-+ binding->maxdelay, binding->flags,
-+ binding->lifetime, binding->ops);
-+
-+ write_unlock(&bul_lock);
-+ /* MAY also decide to delete binding and send zero lifetime BU
-+ with alt-coa set to home address */
-+
-+ return 0;
-+}
-+
-+/**
-+ * mipv6_handle_mh_ba - Binding Acknowledgement handler
-+ * @src: source of this packet
-+ * @coa: care-of address
-+ * @home: home address
-+ * @mh: pointer to the beginning of the Mobility Header
-+ *
-+ **/
-+static int mipv6_handle_mh_ba(struct sk_buff *skb,
-+ struct in6_addr *home,
-+ struct in6_addr *coa,
-+ struct in6_addr *src,
-+ struct in6_addr *unused,
-+ struct mipv6_mh *mh)
-+{
-+ struct mipv6_mh_ba *ba = (struct mipv6_mh_ba *)mh->data;
-+ struct mipv6_bul_entry *binding = NULL;
-+ struct mobopt opts;
-+ int msg_len = (mh->length+1) << 3;
-+ int opt_len;
-+
-+ int auth = 1, req_auth = 1, refresh = -1, ifindex = 0;
-+ u32 lifetime, sequence;
-+
-+ if (msg_len > skb->len)
-+ return -1;
-+
-+ opt_len = msg_len - sizeof(*mh) - sizeof(*ba);
-+
-+ if (opt_len < 0) {
-+ __u32 pos = (__u32)&mh->length - (__u32)skb->nh.raw;
-+ icmpv6_send(skb, ICMPV6_PARAMPROB,
-+ ICMPV6_HDR_FIELD, pos, skb->dev);
-+
-+ DEBUG(DBG_WARNING, "Mobility Header length less than BA");
-+ MIPV6_INC_STATS(n_ba_drop.invalid);
-+ return -1;
-+ }
-+
-+ lifetime = ntohs(ba->lifetime) << 2;
-+ sequence = ntohs(ba->sequence);
-+
-+ if (opt_len > 0) {
-+ memset(&opts, 0, sizeof(opts));
-+ if (parse_mo_tlv(ba + 1, opt_len, &opts) < 0)
-+ return -1;
-+ /*
-+ * MIPV6_OPT_AUTH_DATA, MIPV6_OPT_BR_ADVICE
-+ */
-+ if (opts.br_advice)
-+ refresh = ntohs(opts.br_advice->refresh_interval);
-+ }
-+
-+ if (ba->status >= EXPIRED_HOME_NONCE_INDEX &&
-+ ba->status <= EXPIRED_NONCES)
-+ req_auth = 0;
-+
-+ write_lock(&bul_lock);
-+ binding = mipv6_bul_get(src, home);
-+ if (!binding) {
-+ DEBUG(DBG_INFO, "No binding, BA dropped.");
-+ write_unlock(&bul_lock);
-+ return -1;
-+ }
-+
-+ if (opts.auth_data && binding->rr &&
-+ (mipv6_auth_check(src, coa, (__u8 *)mh, msg_len,
-+ opts.auth_data, binding->rr->kbu) == 0))
-+ auth = 1;
-+
-+ if (req_auth && binding->rr && !auth) {
-+ DEBUG(DBG_INFO, "BA Authentication failed.");
-+ MIPV6_INC_STATS(n_ba_drop.auth);
-+ write_unlock(&bul_lock);
-+ return MH_AUTH_FAILED;
-+ }
-+
-+ if (ba->status == SEQUENCE_NUMBER_OUT_OF_WINDOW) {
-+ DEBUG(DBG_INFO,
-+ "Sequence number out of window, setting seq to %d",
-+ sequence);
-+ } else if (binding->seq != sequence) {
-+ DEBUG(DBG_INFO, "BU/BA Sequence Number mismatch %d != %d",
-+ binding->seq, sequence);
-+ MIPV6_INC_STATS(n_ba_drop.invalid);
-+ write_unlock(&bul_lock);
-+ return MH_SEQUENCE_MISMATCH;
-+ }
-+ if (ba->status == EXPIRED_HOME_NONCE_INDEX || ba->status == EXPIRED_NONCES) {
-+ if (binding->rr) {
-+ /* Need to resend home test init to CN */
-+ binding->rr->rr_state |= RR_WAITH;
-+ mipv6_send_addr_test_init(&binding->home_addr,
-+ &binding->cn_addr,
-+ MIPV6_MH_HOTI,
-+ binding->rr->hot_cookie);
-+ MIPV6_INC_STATS(n_ban_rcvd);
-+ } else {
-+ DEBUG(DBG_WARNING, "Got BA with status EXPIRED_HOME_NONCE_INDEX"
-+ "for non-RR BU");
-+ MIPV6_INC_STATS(n_ba_drop.invalid);
-+ }
-+ write_unlock(&bul_lock);
-+ return 0;
-+ }
-+ if (ba->status == EXPIRED_CAREOF_NONCE_INDEX || ba->status == EXPIRED_NONCES) {
-+ if (binding->rr) {
-+ /* Need to resend care-of test init to CN */
-+ binding->rr->rr_state |= RR_WAITC;
-+ mipv6_send_addr_test_init(&binding->coa,
-+ &binding->cn_addr,
-+ MIPV6_MH_COTI,
-+ binding->rr->cot_cookie);
-+ MIPV6_INC_STATS(n_ban_rcvd);
-+ } else {
-+ DEBUG(DBG_WARNING, "Got BA with status EXPIRED_HOME_CAREOF_INDEX"
-+ "for non-RR BU");
-+ MIPV6_INC_STATS(n_ba_drop.invalid);
-+ }
-+ write_unlock(&bul_lock);
-+ return 0;
-+ }
-+ write_unlock(&bul_lock);
-+
-+ if (ba->status >= REASON_UNSPECIFIED) {
-+ DEBUG(DBG_INFO, "Binding Ack status : %d indicates error", ba->status);
-+ mipv6_ba_rcvd(ifindex, src, home, sequence, lifetime,
-+ refresh, ba->status);
-+ MIPV6_INC_STATS(n_ban_rcvd);
-+ return 0;
-+ }
-+ MIPV6_INC_STATS(n_ba_rcvd);
-+ if (mipv6_ba_rcvd(ifindex, src, home, ntohs(ba->sequence), lifetime,
-+ refresh, ba->status)) {
-+ DEBUG(DBG_WARNING, "mipv6_ba_rcvd failed");
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * mipv6_handle_mh_be - Binding Error handler
-+ * @cn: source of this packet
-+ * @coa: care-of address
-+ * @home: home address
-+ * @mh: pointer to the beginning of the Mobility Header
-+ *
-+ **/
-+
-+static int mipv6_handle_mh_be(struct sk_buff *skb,
-+ struct in6_addr *home,
-+ struct in6_addr *coa,
-+ struct in6_addr *cn,
-+ struct in6_addr *unused,
-+ struct mipv6_mh *mh)
-+{
-+ struct mipv6_mh_be *be = (struct mipv6_mh_be *)mh->data;
-+ int msg_len = (mh->length+1) << 3;
-+ int opt_len;
-+ struct in6_addr *hoa;
-+ struct bul_inval_args args;
-+
-+ DEBUG_FUNC();
-+
-+ if (msg_len > skb->len)
-+ return -1;
-+
-+ opt_len = msg_len - sizeof(*mh) - sizeof(*be);
-+
-+ if (opt_len < 0) {
-+ __u32 pos = (__u32)&mh->length - (__u32)skb->nh.raw;
-+ icmpv6_send(skb, ICMPV6_PARAMPROB,
-+ ICMPV6_HDR_FIELD, pos, skb->dev);
-+
-+ DEBUG(DBG_WARNING, "Mobility Header length less than BE");
-+ MIPV6_INC_STATS(n_be_drop.invalid);
-+ return -1;
-+ }
-+
-+
-+ if (!ipv6_addr_any(&be->home_addr))
-+ hoa = &be->home_addr;
-+ else
-+ hoa = home;
-+
-+ MIPV6_INC_STATS(n_be_rcvd);
-+
-+ args.all_rr_states = 0;
-+ args.cn = cn;
-+ args.mn = hoa;
-+
-+ switch (be->status) {
-+ case 1: /* Home Address Option used without a binding */
-+ /* Get ULP information about CN-MN communication. If
-+ nothing in progress, MUST delete. Otherwise MAY
-+ ignore. */
-+ args.all_rr_states = 1;
-+ case 2: /* Received unknown MH type */
-+ /* If not expecting ack, SHOULD ignore. If MH
-+ extension in use, stop it. If not, stop RO for
-+ this CN. */
-+ write_lock(&bul_lock);
-+ mipv6_bul_iterate(mn_bul_invalidate, &args);
-+ write_unlock(&bul_lock);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+/*
-+ * mipv6_bu_rate_limit() : Takes a bulentry, a COA and 'flags' to check
-+ * whether BU being sent is for Home Registration or not.
-+ *
-+ * If the number of BU's sent is fewer than MAX_FAST_UPDATES, this BU
-+ * is allowed to be sent at the MAX_UPDATE_RATE.
-+ * If the number of BU's sent is greater than or equal to MAX_FAST_UPDATES,
-+ * this BU is allowed to be sent at the SLOW_UPDATE_RATE.
-+ *
-+ * Assumption : This function is not re-entrant. and the caller holds the
-+ * bulentry lock (by calling mipv6_bul_get()) to stop races with other
-+ * CPU's executing this same function.
-+ *
-+ * Side-Effects. Either of the following could on success :
-+ * 1. Sets consecutive_sends to 1 if the entry is a Home agent
-+ * registration or the COA has changed.
-+ * 2. Increments consecutive_sends if the number of BU's sent so
-+ * far is less than MAX_FAST_UPDATES, and this BU is being sent
-+ * atleast MAX_UPDATE_RATE after previous one.
-+ *
-+ * Return Value : 0 on Success, -1 on Failure
-+ */
-+static int mipv6_bu_rate_limit(struct mipv6_bul_entry *bulentry,
-+ struct in6_addr *coa, __u8 flags)
-+{
-+ if ((flags & MIPV6_BU_F_HOME) || ipv6_addr_cmp(&bulentry->coa, coa)) {
-+ /* Home Agent Registration or different COA - restart from 1 */
-+ bulentry->consecutive_sends = 1;
-+ return 0;
-+ }
-+
-+ if (bulentry->consecutive_sends < MAX_FAST_UPDATES) {
-+ /* First MAX_FAST_UPDATES can be sent at MAX_UPDATE_RATE */
-+ if (jiffies - bulentry->lastsend < MAX_UPDATE_RATE * HZ) {
-+ return -1;
-+ }
-+ bulentry->consecutive_sends ++;
-+ } else {
-+ /* Remaining updates SHOULD be sent at SLOW_UPDATE_RATE */
-+ if (jiffies - bulentry->lastsend < SLOW_UPDATE_RATE * HZ) {
-+ return -1;
-+ }
-+ /* Don't inc 'consecutive_sends' to avoid overflow to zero */
-+ }
-+ /* OK to send a BU */
-+ return 0;
-+}
-+
-+/**
-+ * mipv6_send_bu - send a Binding Update
-+ * @saddr: source address for BU
-+ * @daddr: destination address for BU
-+ * @coa: care-of address for MN
-+ * @initdelay: initial BA wait timeout
-+ * @maxackdelay: maximum BA wait timeout
-+ * @exp: exponention back off
-+ * @flags: flags for BU
-+ * @lifetime: granted lifetime for binding
-+ * @ops: mobility options
-+ *
-+ * Send a binding update. 'flags' may contain any of %MIPV6_BU_F_ACK,
-+ * %MIPV6_BU_F_HOME, %MIPV6_BU_F_ROUTER bitwise ORed. If
-+ * %MIPV6_BU_F_ACK is included retransmission will be attempted until
-+ * the update has been acknowledged. Retransmission is done if no
-+ * acknowledgement is received within @initdelay seconds. @exp
-+ * specifies whether to use exponential backoff (@exp != 0) or linear
-+ * backoff (@exp == 0). For exponential backoff the time to wait for
-+ * an acknowledgement is doubled on each retransmission until a delay
-+ * of @maxackdelay, after which retransmission is no longer attempted.
-+ * For linear backoff the delay is kept constant and @maxackdelay
-+ * specifies the maximum number of retransmissions instead. If
-+ * sub-options are present ops must contain all sub-options to be
-+ * added. On a mobile node, use the mobile node's home address for
-+ * @saddr. Returns 0 on success, non-zero on failure.
-+ *
-+ * Caller may not hold @bul_lock.
-+ **/
-+int mipv6_send_bu(struct in6_addr *saddr, struct in6_addr *daddr,
-+ struct in6_addr *coa, u32 initdelay,
-+ u32 maxackdelay, u8 exp, u8 flags, u32 lifetime,
-+ struct mipv6_mh_opt *ops)
-+{
-+ int ret;
-+ __u8 state;
-+ __u16 seq = 0;
-+ int (*callback)(struct mipv6_bul_entry *);
-+ __u32 callback_time;
-+ struct mipv6_bul_entry *bulentry;
-+
-+ /* First a sanity check: don't send BU to local addresses */
-+ if(ipv6_chk_addr(daddr, NULL)) {
-+ DEBUG(DBG_ERROR, "BUG: Trying to send BU to local address");
-+ return -1;
-+ }
-+ DEBUG(DBG_INFO, "Sending BU to CN %x:%x:%x:%x:%x:%x:%x:%x "
-+ "for home address %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(daddr), NIPV6ADDR(saddr));
-+
-+ if ((bulentry = mipv6_bul_get(daddr, saddr)) != NULL) {
-+ if (bulentry->state == ACK_ERROR) {
-+ /*
-+ * Don't send any more BU's to nodes which don't
-+ * understanding one.
-+ */
-+ DEBUG(DBG_INFO, "Not sending BU to node which doesn't"
-+ " understand one");
-+ return -1;
-+ }
-+ if (mipv6_bu_rate_limit(bulentry, coa, flags) < 0) {
-+ DEBUG(DBG_DATADUMP, "Limiting BU sent.");
-+ return 0;
-+ }
-+ }
-+
-+ switch (mipv6_rr_state(bulentry, saddr, coa, flags)) {
-+ case INPROGRESS_RR:
-+ /* We are already doing RR, don't do BU at this time, it is
-+ * done automatically later */
-+ DEBUG(DBG_INFO, "RR in progress not sending BU");
-+ return 0;
-+
-+ case DO_RR:
-+ /* Just do RR and return, BU is done automatically later */
-+ DEBUG(DBG_INFO, "starting RR" );
-+ mipv6_RR_start(saddr, daddr, coa, bulentry, initdelay,
-+ maxackdelay, flags, lifetime, ops);
-+ return 0;
-+
-+ case NO_RR:
-+ DEBUG(DBG_DATADUMP, "No RR necessary" );
-+ default:
-+ break;
-+ }
-+
-+ if (bulentry)
-+ seq = bulentry->seq + 1;
-+
-+ /* Add to binding update list */
-+
-+ if (flags & MIPV6_BU_F_ACK) {
-+ DEBUG(DBG_INFO, "Setting bul callback to bul_resend_exp");
-+ /* Send using exponential backoff */
-+ state = RESEND_EXP;
-+ callback = bul_resend_exp;
-+ callback_time = initdelay;
-+ } else {
-+ DEBUG(DBG_INFO, "Setting bul callback to bul_entry_expired");
-+ /* No acknowledgement/resending required */
-+ state = ACK_OK; /* pretend we got an ack */
-+ callback = bul_entry_expired;
-+ callback_time = lifetime;
-+ }
-+
-+ /* BU only for the home address */
-+ /* We must hold bul_lock (write) while calling add */
-+ if ((bulentry = mipv6_bul_add(daddr, saddr, coa, lifetime, seq,
-+ flags, callback, callback_time,
-+ state, initdelay, maxackdelay, ops,
-+ NULL)) == NULL) {
-+ DEBUG(DBG_INFO, "couldn't update BUL");
-+ return 0;
-+ }
-+ ret = send_bu_msg(bulentry);
-+
-+ return ret;
-+}
-+
-+int __init mipv6_mh_mn_init(void)
-+{
-+ mipv6_mh_register(MIPV6_MH_HOT, mipv6_handle_mh_HC_test);
-+ mipv6_mh_register(MIPV6_MH_COT, mipv6_handle_mh_HC_test);
-+ mipv6_mh_register(MIPV6_MH_BA, mipv6_handle_mh_ba);
-+ mipv6_mh_register(MIPV6_MH_BRR, mipv6_handle_mh_brr);
-+ mipv6_mh_register(MIPV6_MH_BE, mipv6_handle_mh_be);
-+
-+ return 0;
-+}
-+
-+void __exit mipv6_mh_mn_exit(void)
-+{
-+ mipv6_mh_unregister(MIPV6_MH_HOT);
-+ mipv6_mh_unregister(MIPV6_MH_COT);
-+ mipv6_mh_unregister(MIPV6_MH_BA);
-+ mipv6_mh_unregister(MIPV6_MH_BRR);
-+ mipv6_mh_unregister(MIPV6_MH_BE);
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/module_cn.c linux-2.4.25/net/ipv6/mobile_ip6/module_cn.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/module_cn.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/module_cn.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,167 @@
-+/*
-+ * Mobile IPv6 Common Module
-+ *
-+ * Authors:
-+ * Sami Kivisaari <skivisaa@cc.hut.fi>
-+ * Antti Tuominen <ajtuomin@tml.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+
-+#ifdef CONFIG_SYSCTL
-+#include <linux/sysctl.h>
-+#endif /* CONFIG_SYSCTL */
-+
-+#include <net/mipglue.h>
-+
-+#include "bcache.h"
-+#include "mipv6_icmp.h"
-+#include "stats.h"
-+#include "mobhdr.h"
-+#include "exthdrs.h"
-+
-+int mipv6_debug = 1;
-+
-+#if defined(MODULE) && LINUX_VERSION_CODE > 0x20115
-+MODULE_AUTHOR("MIPL Team");
-+MODULE_DESCRIPTION("Mobile IPv6");
-+MODULE_LICENSE("GPL");
-+MODULE_PARM(mipv6_debug, "i");
-+#endif
-+
-+#include "config.h"
-+
-+struct mip6_func mip6_fn;
-+struct mip6_conf mip6node_cnf = {
-+ capabilities: CAP_CN,
-+ accept_ret_rout: 1,
-+ max_rtr_reachable_time: 0,
-+ eager_cell_switching: 0,
-+ max_num_tunnels: 0,
-+ min_num_tunnels: 0,
-+ binding_refresh_advice: 0,
-+ bu_lladdr: 0,
-+ bu_keymgm: 0,
-+ bu_cn_ack: 0
-+};
-+
-+#define MIPV6_BCACHE_SIZE 128
-+
-+/**********************************************************************
-+ *
-+ * MIPv6 CN Module Init / Cleanup
-+ *
-+ **********************************************************************/
-+
-+#ifdef CONFIG_SYSCTL
-+/* Sysctl table */
-+ctl_table mipv6_mobility_table[] = {
-+ {NET_IPV6_MOBILITY_DEBUG, "debuglevel",
-+ &mipv6_debug, sizeof(int), 0644, NULL,
-+ &proc_dointvec},
-+ {NET_IPV6_MOBILITY_RETROUT, "accept_return_routability",
-+ &mip6node_cnf.accept_ret_rout, sizeof(int), 0644, NULL,
-+ &proc_dointvec},
-+ {0}
-+};
-+ctl_table mipv6_table[] = {
-+ {NET_IPV6_MOBILITY, "mobility", NULL, 0, 0555, mipv6_mobility_table},
-+ {0}
-+};
-+
-+static struct ctl_table_header *mipv6_sysctl_header;
-+static struct ctl_table mipv6_net_table[];
-+static struct ctl_table mipv6_root_table[];
-+
-+ctl_table mipv6_net_table[] = {
-+ {NET_IPV6, "ipv6", NULL, 0, 0555, mipv6_table},
-+ {0}
-+};
-+
-+ctl_table mipv6_root_table[] = {
-+ {CTL_NET, "net", NULL, 0, 0555, mipv6_net_table},
-+ {0}
-+};
-+#endif /* CONFIG_SYSCTL */
-+
-+extern void mipv6_rr_init(void);
-+
-+/* Initialize the module */
-+static int __init mip6_init(void)
-+{
-+ int err = 0;
-+
-+ printk(KERN_INFO "MIPL Mobile IPv6 for Linux Correspondent Node %s (%s)\n",
-+ MIPLVERSION, MIPV6VERSION);
-+
-+#ifdef CONFIG_IPV6_MOBILITY_DEBUG
-+ printk(KERN_INFO "Debug-level: %d\n", mipv6_debug);
-+#endif
-+
-+ if ((err = mipv6_bcache_init(MIPV6_BCACHE_SIZE)) < 0)
-+ goto bcache_fail;
-+
-+ if ((err = mipv6_icmpv6_init()) < 0)
-+ goto icmp_fail;
-+
-+ if ((err = mipv6_stats_init()) < 0)
-+ goto stats_fail;
-+ mipv6_rr_init();
-+
-+#ifdef CONFIG_SYSCTL
-+ mipv6_sysctl_header = register_sysctl_table(mipv6_root_table, 0);
-+#endif
-+
-+ if ((err = mipv6_mh_common_init()) < 0)
-+ goto mh_fail;
-+
-+ MIPV6_SETCALL(mipv6_modify_txoptions, mipv6_modify_txoptions);
-+
-+ MIPV6_SETCALL(mipv6_handle_homeaddr, mipv6_handle_homeaddr);
-+ MIPV6_SETCALL(mipv6_icmp_swap_addrs, mipv6_icmp_swap_addrs);
-+
-+ return 0;
-+
-+mh_fail:
-+#ifdef CONFIG_SYSCTL
-+ unregister_sysctl_table(mipv6_sysctl_header);
-+#endif
-+ mipv6_stats_exit();
-+stats_fail:
-+ mipv6_icmpv6_exit();
-+icmp_fail:
-+ mipv6_bcache_exit();
-+bcache_fail:
-+ return err;
-+}
-+module_init(mip6_init);
-+
-+#ifdef MODULE
-+/* Cleanup module */
-+static void __exit mip6_exit(void)
-+{
-+ printk(KERN_INFO "mip6_base.o exiting.\n");
-+#ifdef CONFIG_SYSCTL
-+ unregister_sysctl_table(mipv6_sysctl_header);
-+#endif
-+
-+ /* Invalidate all custom kernel hooks. No need to do this
-+ separately for all hooks. */
-+ mipv6_invalidate_calls();
-+
-+ mipv6_mh_common_exit();
-+ mipv6_stats_exit();
-+ mipv6_icmpv6_exit();
-+ mipv6_bcache_exit();
-+}
-+module_exit(mip6_exit);
-+#endif /* MODULE */
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/module_ha.c linux-2.4.25/net/ipv6/mobile_ip6/module_ha.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/module_ha.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/module_ha.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,264 @@
-+/*
-+ * Mobile IPv6 Home Agent Module
-+ *
-+ * Authors:
-+ * Sami Kivisaari <skivisaa@cc.hut.fi>
-+ * Antti Tuominen <ajtuomin@tml.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+
-+#ifdef CONFIG_SYSCTL
-+#include <linux/sysctl.h>
-+#endif /* CONFIG_SYSCTL */
-+
-+#include <net/mipglue.h>
-+#include <net/addrconf.h>
-+
-+#include "mobhdr.h"
-+#include "tunnel_ha.h"
-+#include "ha.h"
-+#include "halist.h"
-+#include "mipv6_icmp.h"
-+//#include "prefix.h"
-+#include "bcache.h"
-+#include "debug.h"
-+
-+int mipv6_use_auth = 0;
-+
-+#if defined(MODULE) && LINUX_VERSION_CODE > 0x20115
-+MODULE_AUTHOR("MIPL Team");
-+MODULE_DESCRIPTION("Mobile IPv6 Home Agent");
-+MODULE_LICENSE("GPL");
-+#endif
-+
-+#include "config.h"
-+
-+#define MIPV6_HALIST_SIZE 128
-+struct ha_info_opt {
-+ u8 type;
-+ u8 len;
-+ u16 res;
-+ u16 pref;
-+ u16 ltime;
-+};
-+/*
-+ * Called from ndisc.c's router_discovery.
-+ */
-+static int mipv6_ha_ra_rcv(struct sk_buff *skb, struct ndisc_options *ndopts)
-+{
-+ unsigned int ha_info_pref = 0, ha_info_lifetime;
-+ int ifi = ((struct inet6_skb_parm *)skb->cb)->iif;
-+ struct ra_msg *ra = (struct ra_msg *) skb->h.raw;
-+ struct in6_addr *saddr = &skb->nh.ipv6h->saddr;
-+ struct in6_addr ll_addr;
-+ struct hal {
-+ struct in6_addr prefix;
-+ int plen;
-+ struct hal *next;
-+ };
-+
-+ DEBUG_FUNC();
-+
-+ ha_info_lifetime = ntohs(ra->icmph.icmp6_rt_lifetime);
-+ ipv6_addr_copy(&ll_addr, saddr);
-+
-+ if (ndopts->nd_opts_hai) {
-+ struct ha_info_opt *hai = (struct ha_info_opt *)ndopts->nd_opts_hai;
-+ ha_info_pref = ntohs(hai->pref);
-+ ha_info_lifetime = ntohs(hai->ltime);
-+ DEBUG(DBG_DATADUMP,
-+ "received home agent info with preference : %d and lifetime : %d",
-+ ha_info_pref, ha_info_lifetime);
-+ }
-+ if (ndopts->nd_opts_pi) {
-+ struct nd_opt_hdr *p;
-+ for (p = ndopts->nd_opts_pi;
-+ p;
-+ p = ndisc_next_option(p, ndopts->nd_opts_pi_end)) {
-+ struct prefix_info *pinfo;
-+
-+ pinfo = (struct prefix_info *) p;
-+
-+ if (pinfo->router_address) {
-+ DEBUG(DBG_DATADUMP, "Adding router address to "
-+ "ha queue \n");
-+ /* If RA has H bit set and Prefix Info
-+ * Option R bit set, queue this
-+ * address to be added to Home Agents
-+ * List.
-+ */
-+ if (ipv6_addr_type(&pinfo->prefix) &
-+ IPV6_ADDR_LINKLOCAL)
-+ continue;
-+ if (!ra->icmph.icmp6_home_agent || !ha_info_lifetime) {
-+ mipv6_halist_delete(&pinfo->prefix);
-+ continue;
-+ } else {
-+
-+ mipv6_halist_add(ifi, &pinfo->prefix,
-+ pinfo->prefix_len, &ll_addr,
-+ ha_info_pref, ha_info_lifetime);
-+ }
-+
-+ }
-+
-+ }
-+ }
-+ return MIPV6_ADD_RTR;
-+}
-+
-+/**********************************************************************
-+ *
-+ * MIPv6 Module Init / Cleanup
-+ *
-+ **********************************************************************/
-+
-+#ifdef CONFIG_SYSCTL
-+/* Sysctl table */
-+extern int
-+mipv6_max_tnls_sysctl(ctl_table *, int, struct file *, void *, size_t *);
-+
-+extern int
-+mipv6_min_tnls_sysctl(ctl_table *, int, struct file *, void *, size_t *);
-+
-+int max_adv = ~(u16)0;
-+int min_zero = 0;
-+ctl_table mipv6_mobility_table[] = {
-+ {NET_IPV6_MOBILITY_BINDING_REFRESH, "binding_refresh_advice",
-+ &mip6node_cnf.binding_refresh_advice, sizeof(int), 0644, NULL,
-+ &proc_dointvec_minmax, &sysctl_intvec, 0, &min_zero, &max_adv},
-+
-+ {NET_IPV6_MOBILITY_MAX_TNLS, "max_tnls", &mipv6_max_tnls, sizeof(int),
-+ 0644, NULL, &mipv6_max_tnls_sysctl},
-+ {NET_IPV6_MOBILITY_MIN_TNLS, "min_tnls", &mipv6_min_tnls, sizeof(int),
-+ 0644, NULL, &mipv6_min_tnls_sysctl},
-+ {0}
-+};
-+ctl_table mipv6_table[] = {
-+ {NET_IPV6_MOBILITY, "mobility", NULL, 0, 0555, mipv6_mobility_table},
-+ {0}
-+};
-+
-+static struct ctl_table_header *mipv6_sysctl_header;
-+static struct ctl_table mipv6_net_table[];
-+static struct ctl_table mipv6_root_table[];
-+
-+ctl_table mipv6_net_table[] = {
-+ {NET_IPV6, "ipv6", NULL, 0, 0555, mipv6_table},
-+ {0}
-+};
-+
-+ctl_table mipv6_root_table[] = {
-+ {CTL_NET, "net", NULL, 0, 0555, mipv6_net_table},
-+ {0}
-+};
-+#endif /* CONFIG_SYSCTL */
-+
-+extern void mipv6_check_dad(struct in6_addr *haddr);
-+extern void mipv6_dad_init(void);
-+extern void mipv6_dad_exit(void);
-+extern int mipv6_forward(struct sk_buff *);
-+
-+/* Initialize the module */
-+static int __init mip6_ha_init(void)
-+{
-+ int err = 0;
-+
-+ printk(KERN_INFO "MIPL Mobile IPv6 for Linux Home Agent %s (%s)\n",
-+ MIPLVERSION, MIPV6VERSION);
-+ mip6node_cnf.capabilities = CAP_CN | CAP_HA;
-+
-+ mip6_fn.icmpv6_dhaad_rep_rcv = mipv6_icmpv6_no_rcv;
-+ mip6_fn.icmpv6_dhaad_req_rcv = mipv6_icmpv6_rcv_dhaad_req;
-+ mip6_fn.icmpv6_pfxadv_rcv = mipv6_icmpv6_no_rcv;
-+ mip6_fn.icmpv6_pfxsol_rcv = mipv6_icmpv6_no_rcv;
-+ mip6_fn.icmpv6_paramprob_rcv = mipv6_icmpv6_no_rcv;
-+
-+#ifdef CONFIG_IPV6_MOBILITY_DEBUG
-+ printk(KERN_INFO "Debug-level: %d\n", mipv6_debug);
-+#endif
-+
-+#ifdef CONFIG_SYSCTL
-+ mipv6_sysctl_header = register_sysctl_table(mipv6_root_table, 0);
-+#endif
-+ mipv6_initialize_tunnel();
-+
-+ if ((err = mipv6_ha_init()) < 0)
-+ goto ha_fail;
-+
-+ MIPV6_SETCALL(mipv6_ra_rcv, mipv6_ha_ra_rcv);
-+ MIPV6_SETCALL(mipv6_forward, mipv6_forward);
-+ mipv6_dad_init();
-+ MIPV6_SETCALL(mipv6_check_dad, mipv6_check_dad);
-+
-+ if ((err = mipv6_halist_init(MIPV6_HALIST_SIZE)) < 0)
-+ goto halist_fail;
-+
-+// mipv6_initialize_pfx_icmpv6();
-+
-+ return 0;
-+
-+halist_fail:
-+ mipv6_dad_exit();
-+ mipv6_ha_exit();
-+ha_fail:
-+ mipv6_shutdown_tunnel();
-+
-+ mip6_fn.icmpv6_dhaad_rep_rcv = NULL;
-+ mip6_fn.icmpv6_dhaad_req_rcv = NULL;
-+ mip6_fn.icmpv6_pfxadv_rcv = NULL;
-+ mip6_fn.icmpv6_pfxsol_rcv = NULL;
-+ mip6_fn.icmpv6_paramprob_rcv = NULL;
-+
-+ MIPV6_RESETCALL(mipv6_ra_rcv);
-+ MIPV6_RESETCALL(mipv6_forward);
-+ MIPV6_RESETCALL(mipv6_check_dad);
-+
-+#ifdef CONFIG_SYSCTL
-+ unregister_sysctl_table(mipv6_sysctl_header);
-+#endif
-+ return err;
-+}
-+module_init(mip6_ha_init);
-+
-+#ifdef MODULE
-+/* Cleanup module */
-+static void __exit mip6_ha_exit(void)
-+{
-+ printk(KERN_INFO "mip6_ha.o exiting.\n");
-+ mip6node_cnf.capabilities &= ~(int)CAP_HA;
-+
-+ mipv6_bcache_cleanup(HOME_REGISTRATION);
-+
-+ MIPV6_RESETCALL(mipv6_ra_rcv);
-+ MIPV6_RESETCALL(mipv6_forward);
-+ MIPV6_RESETCALL(mipv6_check_dad);
-+
-+ mipv6_halist_exit();
-+// mipv6_shutdown_pfx_icmpv6();
-+
-+ mip6_fn.icmpv6_dhaad_rep_rcv = NULL;
-+ mip6_fn.icmpv6_dhaad_req_rcv = NULL;
-+ mip6_fn.icmpv6_pfxadv_rcv = NULL;
-+ mip6_fn.icmpv6_pfxsol_rcv = NULL;
-+ mip6_fn.icmpv6_paramprob_rcv = NULL;
-+
-+ mipv6_dad_exit();
-+ mipv6_ha_exit();
-+ mipv6_shutdown_tunnel();
-+#ifdef CONFIG_SYSCTL
-+ unregister_sysctl_table(mipv6_sysctl_header);
-+#endif
-+}
-+module_exit(mip6_ha_exit);
-+#endif /* MODULE */
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/module_mn.c linux-2.4.25/net/ipv6/mobile_ip6/module_mn.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/module_mn.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/module_mn.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,188 @@
-+/*
-+ * Mobile IPv6 Mobile Node Module
-+ *
-+ * Authors:
-+ * Sami Kivisaari <skivisaa@cc.hut.fi>
-+ * Antti Tuominen <ajtuomin@tml.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+
-+#ifdef CONFIG_SYSCTL
-+#include <linux/sysctl.h>
-+#endif /* CONFIG_SYSCTL */
-+
-+#include <net/mipglue.h>
-+
-+extern int mipv6_debug;
-+int mipv6_use_auth = 0;
-+
-+#if defined(MODULE) && LINUX_VERSION_CODE > 0x20115
-+MODULE_AUTHOR("MIPL Team");
-+MODULE_DESCRIPTION("Mobile IPv6 Mobile Node");
-+MODULE_LICENSE("GPL");
-+MODULE_PARM(mipv6_debug, "i");
-+#endif
-+
-+#include "config.h"
-+
-+#include "mobhdr.h"
-+#include "mn.h"
-+#include "mipv6_icmp.h"
-+//#include "prefix.h"
-+
-+/* TODO: These will go as soon as we get rid of the last two ioctls */
-+extern int mipv6_ioctl_mn_init(void);
-+extern void mipv6_ioctl_mn_exit(void);
-+
-+/**********************************************************************
-+ *
-+ * MIPv6 Module Init / Cleanup
-+ *
-+ **********************************************************************/
-+
-+#ifdef CONFIG_SYSCTL
-+/* Sysctl table */
-+
-+extern int max_rtr_reach_time;
-+extern int eager_cell_switching;
-+
-+static int max_reach = 1000;
-+static int min_reach = 1;
-+static int max_one = 1;
-+static int min_zero = 0;
-+
-+extern int
-+mipv6_mdetect_mech_sysctl(ctl_table *, int, struct file *, void *, size_t *);
-+
-+extern int
-+mipv6_router_reach_sysctl(ctl_table *, int, struct file *, void *, size_t *);
-+
-+ctl_table mipv6_mobility_table[] = {
-+ {NET_IPV6_MOBILITY_BU_F_LLADDR, "bu_flag_lladdr",
-+ &mip6node_cnf.bu_lladdr, sizeof(int), 0644, NULL,
-+ &proc_dointvec_minmax, &sysctl_intvec, 0, &min_zero, &max_one},
-+ {NET_IPV6_MOBILITY_BU_F_KEYMGM, "bu_flag_keymgm",
-+ &mip6node_cnf.bu_keymgm, sizeof(int), 0644, NULL,
-+ &proc_dointvec_minmax, &sysctl_intvec, 0, &min_zero, &max_one},
-+ {NET_IPV6_MOBILITY_BU_F_CN_ACK, "bu_flag_cn_ack",
-+ &mip6node_cnf.bu_cn_ack, sizeof(int), 0644, NULL,
-+ &proc_dointvec_minmax, &sysctl_intvec, 0, &min_zero, &max_one},
-+
-+ {NET_IPV6_MOBILITY_ROUTER_REACH, "max_router_reachable_time",
-+ &max_rtr_reach_time, sizeof(int), 0644, NULL,
-+ &proc_dointvec_minmax, &sysctl_intvec, 0, &min_reach, &max_reach},
-+
-+ {NET_IPV6_MOBILITY_MDETECT_MECHANISM, "eager_cell_switching",
-+ &eager_cell_switching, sizeof(int), 0644, NULL,
-+ &proc_dointvec_minmax, &sysctl_intvec, 0, &min_zero, &max_one},
-+
-+ {0}
-+};
-+ctl_table mipv6_table[] = {
-+ {NET_IPV6_MOBILITY, "mobility", NULL, 0, 0555, mipv6_mobility_table},
-+ {0}
-+};
-+
-+static struct ctl_table_header *mipv6_sysctl_header;
-+static struct ctl_table mipv6_net_table[];
-+static struct ctl_table mipv6_root_table[];
-+
-+ctl_table mipv6_net_table[] = {
-+ {NET_IPV6, "ipv6", NULL, 0, 0555, mipv6_table},
-+ {0}
-+};
-+
-+ctl_table mipv6_root_table[] = {
-+ {CTL_NET, "net", NULL, 0, 0555, mipv6_net_table},
-+ {0}
-+};
-+#endif /* CONFIG_SYSCTL */
-+
-+/* Initialize the module */
-+static int __init mip6_mn_init(void)
-+{
-+ int err = 0;
-+
-+ printk(KERN_INFO "MIPL Mobile IPv6 for Linux Mobile Node %s (%s)\n",
-+ MIPLVERSION, MIPV6VERSION);
-+ mip6node_cnf.capabilities = CAP_CN | CAP_MN;
-+
-+#ifdef CONFIG_IPV6_MOBILITY_DEBUG
-+ printk(KERN_INFO "Debug-level: %d\n", mipv6_debug);
-+#endif
-+
-+#ifdef CONFIG_SYSCTL
-+ mipv6_sysctl_header = register_sysctl_table(mipv6_root_table, 0);
-+#endif
-+ if ((err = mipv6_mn_init()) < 0)
-+ goto mn_fail;
-+
-+ mipv6_mh_mn_init();
-+
-+ mip6_fn.icmpv6_dhaad_rep_rcv = mipv6_icmpv6_rcv_dhaad_rep;
-+ mip6_fn.icmpv6_dhaad_req_rcv = mipv6_icmpv6_no_rcv;
-+ mip6_fn.icmpv6_pfxadv_rcv = mipv6_icmpv6_no_rcv;
-+ mip6_fn.icmpv6_pfxsol_rcv = mipv6_icmpv6_no_rcv;
-+ mip6_fn.icmpv6_paramprob_rcv = mipv6_icmpv6_rcv_paramprob;
-+
-+// mipv6_initialize_pfx_icmpv6();
-+
-+ if ((err = mipv6_ioctl_mn_init()) < 0)
-+ goto ioctl_fail;
-+
-+ return 0;
-+
-+ioctl_fail:
-+// mipv6_shutdown_pfx_icmpv6();
-+
-+ mip6_fn.icmpv6_dhaad_rep_rcv = NULL;
-+ mip6_fn.icmpv6_dhaad_req_rcv = NULL;
-+ mip6_fn.icmpv6_pfxadv_rcv = NULL;
-+ mip6_fn.icmpv6_pfxsol_rcv = NULL;
-+ mip6_fn.icmpv6_paramprob_rcv = NULL;
-+
-+ mipv6_mh_mn_exit();
-+ mipv6_mn_exit();
-+mn_fail:
-+#ifdef CONFIG_SYSCTL
-+ unregister_sysctl_table(mipv6_sysctl_header);
-+#endif
-+ return err;
-+}
-+module_init(mip6_mn_init);
-+
-+#ifdef MODULE
-+/* Cleanup module */
-+static void __exit mip6_mn_exit(void)
-+{
-+ printk(KERN_INFO "mip6_mn.o exiting.\n");
-+ mip6node_cnf.capabilities &= ~(int)CAP_MN;
-+
-+ mipv6_ioctl_mn_exit();
-+// mipv6_shutdown_pfx_icmpv6();
-+
-+ mip6_fn.icmpv6_dhaad_rep_rcv = NULL;
-+ mip6_fn.icmpv6_dhaad_req_rcv = NULL;
-+ mip6_fn.icmpv6_pfxadv_rcv = NULL;
-+ mip6_fn.icmpv6_pfxsol_rcv = NULL;
-+ mip6_fn.icmpv6_paramprob_rcv = NULL;
-+
-+ mipv6_mn_exit();
-+
-+/* common cleanup */
-+#ifdef CONFIG_SYSCTL
-+ unregister_sysctl_table(mipv6_sysctl_header);
-+#endif
-+}
-+module_exit(mip6_mn_exit);
-+#endif /* MODULE */
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/multiaccess_ctl.c linux-2.4.25/net/ipv6/mobile_ip6/multiaccess_ctl.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/multiaccess_ctl.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/multiaccess_ctl.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,287 @@
-+/*
-+ * 2001 (c) Oy L M Ericsson Ab
-+ *
-+ * Author: NomadicLab / Ericsson Research <ipv6@nomadiclab.com>
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+/*
-+ * Vertical hand-off information manager
-+ */
-+
-+#include <linux/netdevice.h>
-+#include <linux/in6.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/string.h>
-+#include <linux/kernel.h>
-+#include <asm/io.h>
-+#include <asm/uaccess.h>
-+#include <linux/list.h>
-+#include "multiaccess_ctl.h"
-+#include "debug.h"
-+
-+/*
-+ * Local variables
-+ */
-+static LIST_HEAD(if_list);
-+
-+/* Internal interface information list */
-+struct ma_if_info {
-+ struct list_head list;
-+ int interface_id;
-+ int preference;
-+ __u8 status;
-+};
-+
-+/**
-+ * ma_ctl_get_preference - get preference value for interface
-+ * @ifi: interface index
-+ *
-+ * Returns integer value preference for given interface.
-+ **/
-+int ma_ctl_get_preference(int ifi)
-+{
-+ struct list_head *lh;
-+ struct ma_if_info *info;
-+ int pref = 0;
-+
-+ list_for_each(lh, &if_list) {
-+ info = list_entry(lh, struct ma_if_info, list);
-+ if (info->interface_id == ifi) {
-+ pref = info->preference;
-+ return pref;
-+ }
-+ }
-+ return -1;
-+}
-+/**
-+ * ma_ctl_get_preference - get preference value for interface
-+ * @ifi: interface index
-+ *
-+ * Returns integer value interface index for interface with highest preference.
-+ **/
-+int ma_ctl_get_preferred_if(void)
-+{
-+ struct list_head *lh;
-+ struct ma_if_info *info, *pref_if = NULL;
-+
-+ list_for_each(lh, &if_list) {
-+ info = list_entry(lh, struct ma_if_info, list);
-+ if (!pref_if || (info->preference > pref_if->preference)) {
-+ pref_if = info;
-+ }
-+ }
-+ if (pref_if) return pref_if->interface_id;
-+ return 0;
-+}
-+/**
-+ * ma_ctl_set_preference - set preference for interface
-+ * @arg: ioctl args
-+ *
-+ * Sets preference of an existing interface (called by ioctl).
-+ **/
-+void ma_ctl_set_preference(unsigned long arg)
-+{
-+ struct list_head *lh;
-+ struct ma_if_info *info;
-+ struct ma_if_uinfo uinfo;
-+
-+ memset(&uinfo, 0, sizeof(struct ma_if_uinfo));
-+ if (copy_from_user(&uinfo, (struct ma_if_uinfo *)arg,
-+ sizeof(struct ma_if_uinfo)) < 0) {
-+ DEBUG(DBG_WARNING, "copy_from_user failed");
-+ return;
-+ }
-+
-+ /* check if the interface exists */
-+ list_for_each(lh, &if_list) {
-+ info = list_entry(lh, struct ma_if_info, list);
-+ if (info->interface_id == uinfo.interface_id) {
-+ info->preference = uinfo.preference;
-+ return;
-+ }
-+ }
-+}
-+
-+/**
-+ * ma_ctl_add_iface - add new interface to list
-+ * @if_index: interface index
-+ *
-+ * Adds new interface entry to preference list. Preference is set to
-+ * the same value as @if_index. Entry @status is set to
-+ * %MA_IFACE_NOT_USED.
-+ **/
-+void ma_ctl_add_iface(int if_index)
-+{
-+ struct list_head *lh;
-+ struct ma_if_info *info;
-+
-+ DEBUG_FUNC();
-+
-+ /* check if the interface already exists */
-+ list_for_each(lh, &if_list) {
-+ info = list_entry(lh, struct ma_if_info, list);
-+ if (info->interface_id == if_index) {
-+ info->status = MA_IFACE_NOT_USED;
-+ info->preference = if_index;
-+ return;
-+ }
-+ }
-+
-+ info = kmalloc(sizeof(struct ma_if_info), GFP_ATOMIC);
-+ if (info == NULL) {
-+ DEBUG(DBG_ERROR, "Out of memory");
-+ return;
-+ }
-+ memset(info, 0, sizeof(struct ma_if_info));
-+ info->interface_id = if_index;
-+ info->preference = if_index;
-+ info->status = MA_IFACE_NOT_USED;
-+ list_add(&info->list, &if_list);
-+}
-+
-+/**
-+ * ma_ctl_del_iface - remove entry from the list
-+ * @if_index: interface index
-+ *
-+ * Removes entry for interface @if_index from preference list.
-+ **/
-+int ma_ctl_del_iface(int if_index)
-+{
-+ struct list_head *lh, *next;
-+ struct ma_if_info *info;
-+
-+ DEBUG_FUNC();
-+
-+ /* if the iface exists, change availability to 0 */
-+ list_for_each_safe(lh, next, &if_list) {
-+ info = list_entry(lh, struct ma_if_info, list);
-+ if (info->interface_id == if_index) {
-+ list_del(&info->list);
-+ kfree(info);
-+ return 0;
-+ }
-+ }
-+
-+ return -1;
-+}
-+
-+/**
-+ * ma_ctl_upd_iface - update entry (and list)
-+ * @if_index: interface to update
-+ * @status: new status for interface
-+ * @change_if_index: new interface
-+ *
-+ * Updates @if_index entry on preference list. Entry status is set to
-+ * @status. If new @status is %MA_IFACE_CURRENT, updates list to have
-+ * only one current device. If @status is %MA_IFACE_NOT_PRESENT,
-+ * entry is deleted and further if entry had %MA_IFACE_CURRENT set,
-+ * new current device is looked up and returned in @change_if_index.
-+ * New preferred interface is also returned if current device changes
-+ * to %MA_IFACE_NOT_USED. Returns 0 on success, otherwise negative.
-+ **/
-+int ma_ctl_upd_iface(int if_index, int status, int *change_if_index)
-+{
-+ struct list_head *lh, *tmp;
-+ struct ma_if_info *info, *pref = NULL;
-+ int found = 0;
-+
-+ DEBUG_FUNC();
-+
-+ *change_if_index = 0;
-+
-+ /* check if the interface exists */
-+ list_for_each_safe(lh, tmp, &if_list) {
-+ info = list_entry(lh, struct ma_if_info, list);
-+ if (status == MA_IFACE_NOT_PRESENT) {
-+ if (info->interface_id == if_index) {
-+ list_del_init(&info->list);
-+ kfree(info);
-+ found = 1;
-+ break;
-+ }
-+ } else if (status == MA_IFACE_CURRENT) {
-+ if (info->interface_id == if_index) {
-+ info->status |= MA_IFACE_CURRENT;
-+ found = 1;
-+ } else {
-+ info->status |= MA_IFACE_NOT_USED;
-+ }
-+ } else if (status == MA_IFACE_NOT_USED) {
-+ if (info->interface_id == if_index) {
-+ if (info->status | MA_IFACE_CURRENT) {
-+ found = 1;
-+ }
-+ info->status &= !MA_IFACE_CURRENT;
-+ info->status |= MA_IFACE_NOT_USED;
-+ info->status &= !MA_IFACE_HAS_ROUTER;
-+ }
-+ break;
-+ } else if (status == MA_IFACE_HAS_ROUTER) {
-+ if (info->interface_id == if_index) {
-+ info->status |= MA_IFACE_HAS_ROUTER;
-+ }
-+ return 0;
-+ }
-+ }
-+
-+ if (status & (MA_IFACE_NOT_USED|MA_IFACE_NOT_PRESENT) && found) {
-+ /* select new interface */
-+ list_for_each(lh, &if_list) {
-+ info = list_entry(lh, struct ma_if_info, list);
-+ if (pref == NULL || ((info->preference > pref->preference) &&
-+ info->status & MA_IFACE_HAS_ROUTER))
-+ pref = info;
-+ }
-+ if (pref) {
-+ *change_if_index = pref->interface_id;
-+ pref->status |= MA_IFACE_CURRENT;
-+ } else {
-+ *change_if_index = -1;
-+ }
-+ return 0;
-+ }
-+
-+ if (found) return 0;
-+
-+ return -1;
-+}
-+
-+static int if_proc_info(char *buffer, char **start, off_t offset,
-+ int length)
-+{
-+ struct list_head *lh;
-+ struct ma_if_info *info;
-+ int len = 0;
-+
-+ list_for_each(lh, &if_list) {
-+ info = list_entry(lh, struct ma_if_info, list);
-+ len += sprintf(buffer + len, "%02d %010d %1d %1d\n",
-+ info->interface_id, info->preference,
-+ !!(info->status & MA_IFACE_HAS_ROUTER),
-+ !!(info->status & MA_IFACE_CURRENT));
-+ }
-+
-+ *start = buffer + offset;
-+
-+ len -= offset;
-+
-+ if (len > length) len = length;
-+
-+ return len;
-+
-+}
-+
-+void ma_ctl_init(void)
-+{
-+ proc_net_create("mip6_iface", 0, if_proc_info);
-+}
-+
-+void ma_ctl_clean(void)
-+{
-+ proc_net_remove("mip6_iface");
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/multiaccess_ctl.h linux-2.4.25/net/ipv6/mobile_ip6/multiaccess_ctl.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/multiaccess_ctl.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/multiaccess_ctl.h 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,77 @@
-+/*
-+ * 2001 (c) Oy L M Ericsson Ab
-+ *
-+ * Author: NomadicLab / Ericsson Research <ipv6@nomadiclab.com>
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+#ifndef _MULTIACCESS_CTL_H
-+#define _MULTIACCESS_CTL_H
-+
-+/* status */
-+#define MA_IFACE_NOT_PRESENT 0x01
-+#define MA_IFACE_NOT_USED 0x02
-+#define MA_IFACE_HAS_ROUTER 0x04
-+#define MA_IFACE_CURRENT 0x10
-+
-+struct ma_if_uinfo {
-+ int interface_id;
-+ int preference;
-+ __u8 status;
-+};
-+/*
-+ * @ma_ctl_get_preferred_id: returns most preferred interface id
-+ */
-+int ma_ctl_get_preferred_if(void);
-+
-+/* @ma_ctl_get_preference: returns preference for an interface
-+ * @name: name of the interface (dev->name)
-+ */
-+int ma_ctl_get_preference(int ifi);
-+
-+/*
-+ * Public function: ma_ctl_set_preference
-+ * Description: Set preference of an existing interface (called by ioctl)
-+ * Returns:
-+ */
-+void ma_ctl_set_preference(unsigned long);
-+
-+/*
-+ * Public function: ma_ctl_add_iface
-+ * Description: Inform control module to insert a new interface
-+ * Returns: 0 if success, any other number means an error
-+ */
-+void ma_ctl_add_iface(int);
-+
-+/*
-+ * Public function: ma_ctl_del_iface
-+ * Description: Inform control module to remove an obsolete interface
-+ * Returns: 0 if success, any other number means an error
-+ */
-+int ma_ctl_del_iface(int);
-+
-+/*
-+ * Public function: ma_ctl_upd_iface
-+ * Description: Inform control module of status change.
-+ * Returns: 0 if success, any other number means an error
-+ */
-+int ma_ctl_upd_iface(int, int, int *);
-+
-+/*
-+ * Public function: ma_ctl_init
-+ * Description: XXX
-+ * Returns: XXX
-+ */
-+void ma_ctl_init(void);
-+
-+/*
-+ * Public function: ma_ctl_clean
-+ * Description: XXX
-+ * Returns: -
-+ */
-+void ma_ctl_clean(void);
-+
-+
-+#endif
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/ndisc_ha.c linux-2.4.25/net/ipv6/mobile_ip6/ndisc_ha.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/ndisc_ha.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/ndisc_ha.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,596 @@
-+/*
-+ * Mobile IPv6 Duplicate Address Detection Functions
-+ *
-+ * Authors:
-+ * Krishna Kumar <krkumar@us.ibm.com>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ *
-+ */
-+
-+#include <linux/autoconf.h>
-+#include <linux/types.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/in6.h>
-+#include <net/ipv6.h>
-+#include <net/addrconf.h>
-+#include <net/mipv6.h>
-+
-+#include "debug.h"
-+#include "bcache.h"
-+#include "ha.h" /* mipv6_generate_ll_addr */
-+
-+/*
-+ * Binding Updates from MN are cached in this structure till DAD is performed.
-+ * This structure is used to retrieve a pending Binding Update for the HA to
-+ * reply to after performing DAD. The first cell is different from the rest as
-+ * follows :
-+ * 1. The first cell is used to chain the remaining cells.
-+ * 2. The timeout of the first cell is used to delete expired entries
-+ * in the list of cells, while the timeout of the other cells are
-+ * used for timing out a NS request so as to reply to a BU.
-+ * 3. The only elements of the first cell that are used are :
-+ * next, prev, and callback_timer.
-+ *
-+ * TODO : Don't we need to do pneigh_lookup on the Link Local address ?
-+ */
-+struct mipv6_dad_cell {
-+ /* Information needed for DAD management */
-+ struct mipv6_dad_cell *next; /* Next element on the DAD list */
-+ struct mipv6_dad_cell *prev; /* Prev element on the DAD list */
-+ __u16 probes; /* Number of times to probe for addr */
-+ __u16 flags; /* Entry flags - see below */
-+ struct timer_list callback_timer; /* timeout for entry */
-+
-+ /* Information needed for performing DAD */
-+ struct inet6_ifaddr *ifp;
-+ int ifindex;
-+ struct in6_addr daddr;
-+ struct in6_addr haddr; /* home address */
-+ struct in6_addr ll_haddr; /* Link Local value of haddr */
-+ struct in6_addr coa;
-+ struct in6_addr rep_coa;
-+ __u32 ba_lifetime;
-+ __u16 sequence;
-+ __u8 bu_flags;
-+};
-+
-+/* Values for the 'flags' field in the mipv6_dad_cell */
-+#define DAD_INIT_ENTRY 0
-+#define DAD_DUPLICATE_ADDRESS 1
-+#define DAD_UNIQUE_ADDRESS 2
-+
-+/* Head of the pending DAD list */
-+static struct mipv6_dad_cell dad_cell_head;
-+
-+/* Lock to access the pending DAD list */
-+static rwlock_t dad_lock = RW_LOCK_UNLOCKED;
-+
-+/* Timer routine which deletes 'expired' entries in the DAD list */
-+static void mipv6_dad_delete_old_entries(unsigned long unused)
-+{
-+ struct mipv6_dad_cell *curr, *next;
-+ unsigned long next_time = 0;
-+
-+ write_lock(&dad_lock);
-+ curr = dad_cell_head.next;
-+ while (curr != &dad_cell_head) {
-+ next = curr->next;
-+ if (curr->flags != DAD_INIT_ENTRY) {
-+ if (curr->callback_timer.expires <= jiffies) {
-+ /* Entry has expired, free it up. */
-+ curr->next->prev = curr->prev;
-+ curr->prev->next = curr->next;
-+ in6_ifa_put(curr->ifp);
-+ kfree(curr);
-+ } else if (next_time <
-+ curr->callback_timer.expires) {
-+ next_time = curr->callback_timer.expires;
-+ }
-+ }
-+ curr = next;
-+ }
-+ write_unlock(&dad_lock);
-+ if (next_time) {
-+ /*
-+ * Start another timer if more cells need to be removed at
-+ * a later stage.
-+ */
-+ dad_cell_head.callback_timer.expires = next_time;
-+ add_timer(&dad_cell_head.callback_timer);
-+ }
-+}
-+
-+/*
-+ * Queue a timeout routine to clean up 'expired' DAD entries.
-+ */
-+static void mipv6_start_dad_head_timer(struct mipv6_dad_cell *cell)
-+{
-+ unsigned long expire = jiffies +
-+ cell->ifp->idev->nd_parms->retrans_time * 10;
-+
-+ if (!timer_pending(&dad_cell_head.callback_timer) ||
-+ expire < dad_cell_head.callback_timer.expires) {
-+ /*
-+ * Add timer if none pending, or mod the timer if new
-+ * cell needs to be expired before existing timer runs.
-+ *
-+ * We let the cell remain as long as possible, so that
-+ * new BU's as part of retransmissions don't have to go
-+ * through DAD before replying.
-+ */
-+ dad_cell_head.callback_timer.expires = expire;
-+
-+ /*
-+ * Keep the cell around for atleast some time to handle
-+ * retransmissions or BU's due to fast MN movement. This
-+ * is needed otherwise a previous timeout can delete all
-+ * expired entries including this new one.
-+ */
-+ cell->callback_timer.expires = jiffies +
-+ cell->ifp->idev->nd_parms->retrans_time * 5;
-+ if (!timer_pending(&dad_cell_head.callback_timer)) {
-+ add_timer(&dad_cell_head.callback_timer);
-+ } else {
-+ mod_timer(&dad_cell_head.callback_timer, expire);
-+ }
-+ }
-+}
-+
-+
-+/* Join solicited node MC address */
-+static inline void mipv6_join_sol_mc_addr(struct in6_addr *addr,
-+ struct net_device *dev)
-+{
-+ struct in6_addr maddr;
-+
-+ /* Join solicited node MC address */
-+ addrconf_addr_solict_mult(addr, &maddr);
-+ ipv6_dev_mc_inc(dev, &maddr);
-+}
-+
-+/* Leave solicited node MC address */
-+static inline void mipv6_leave_sol_mc_addr(struct in6_addr *addr,
-+ struct net_device *dev)
-+{
-+ struct in6_addr maddr;
-+
-+ addrconf_addr_solict_mult(addr, &maddr);
-+ ipv6_dev_mc_dec(dev, &maddr);
-+}
-+
-+/* Send a NS */
-+static inline void mipv6_dad_send_ns(struct inet6_ifaddr *ifp,
-+ struct in6_addr *haddr)
-+{
-+ struct in6_addr unspec;
-+ struct in6_addr mcaddr;
-+
-+ ipv6_addr_set(&unspec, 0, 0, 0, 0);
-+ addrconf_addr_solict_mult(haddr, &mcaddr);
-+
-+ /* addr is 'unspec' since we treat this address as transient */
-+ ndisc_send_ns(ifp->idev->dev, NULL, haddr, &mcaddr, &unspec);
-+}
-+
-+/*
-+ * Search for a home address in the list of pending DAD's. Called from
-+ * Neighbor Advertisement
-+ * Return values :
-+ * -1 : No DAD entry found for this advertisement, or entry already
-+ * finished processing.
-+ * 0 : Entry found waiting for DAD to finish.
-+ */
-+static int dad_search_haddr(struct in6_addr *ll_haddr,
-+ struct in6_addr *daddr, struct in6_addr *haddr,
-+ struct in6_addr *coa, struct in6_addr *rep_coa,
-+ __u16 * seq, struct inet6_ifaddr **ifp)
-+{
-+ struct mipv6_dad_cell *cell;
-+
-+ read_lock(&dad_lock);
-+ cell = dad_cell_head.next;
-+ while (cell != &dad_cell_head &&
-+ ipv6_addr_cmp(&cell->ll_haddr, ll_haddr) &&
-+ ipv6_addr_cmp(&cell->haddr, ll_haddr)) {
-+ cell = cell->next;
-+ }
-+ if (cell == &dad_cell_head || cell->flags != DAD_INIT_ENTRY) {
-+ /* Not found element, or element already finished processing */
-+ if (cell != &dad_cell_head) {
-+ /*
-+ * Set the state to DUPLICATE, even if it was UNIQUE
-+ * earlier. It is not needed to setup timer via
-+ * mipv6_start_dad_head_timer since this must have
-+ * already been done.
-+ */
-+ cell->flags = DAD_DUPLICATE_ADDRESS;
-+ }
-+ read_unlock(&dad_lock);
-+ return -1;
-+ }
-+
-+ /*
-+ * The NA found an unprocessed entry in the DAD list. Expire this
-+ * entry since another node advertised this address. Caller should
-+ * reject BU (DAD failed).
-+ */
-+ ipv6_addr_copy(daddr, &cell->daddr);
-+ ipv6_addr_copy(haddr, &cell->haddr);
-+ ipv6_addr_copy(coa, &cell->coa);
-+ ipv6_addr_copy(rep_coa, &cell->rep_coa);
-+ *seq = cell->sequence;
-+ *ifp = cell->ifp;
-+
-+ if (del_timer(&cell->callback_timer) == 0) {
-+ /* Timer already deleted, race with Timeout Handler */
-+ /* No action needed */
-+ }
-+
-+ cell->flags = DAD_DUPLICATE_ADDRESS;
-+
-+ /* Now leave this address to avoid future processing of NA's */
-+ mipv6_leave_sol_mc_addr(&cell->ll_haddr, cell->ifp->idev->dev);
-+ /* Leave also global address, if link local address was in use */
-+ if (ipv6_addr_cmp(&cell->ll_haddr, &cell->haddr))
-+ mipv6_leave_sol_mc_addr(&cell->haddr, cell->ifp->idev->dev);
-+ /* Start dad_head timer to remove this entry */
-+ mipv6_start_dad_head_timer(cell);
-+
-+ read_unlock(&dad_lock);
-+
-+ return 0;
-+}
-+
-+/* ENTRY routine called via Neighbor Advertisement */
-+void mipv6_check_dad(struct in6_addr *ll_haddr)
-+{
-+ struct in6_addr daddr, haddr, coa, rep_coa;
-+ struct inet6_ifaddr *ifp;
-+ __u16 seq;
-+
-+ if (dad_search_haddr(ll_haddr, &daddr, &haddr, &coa, &rep_coa, &seq,
-+ &ifp) < 0) {
-+ /*
-+ * Didn't find entry, or no action needed (the action has
-+ * already been performed).
-+ */
-+ return;
-+ }
-+
-+ /*
-+ * A DAD cell was present, meaning that there is a pending BU
-+ * request for 'haddr' - reject the BU.
-+ */
-+ mipv6_bu_finish(ifp, 0, DUPLICATE_ADDR_DETECT_FAIL,
-+ &daddr, &haddr, &coa, &rep_coa, 0, seq, 0, NULL);
-+ return;
-+}
-+
-+/*
-+ * Check if the passed 'cell' is in the list of pending DAD's. Called from
-+ * the Timeout Handler.
-+ *
-+ * Assumes that the caller is holding the dad_lock in reader mode.
-+ */
-+static int dad_search_cell(struct mipv6_dad_cell *cell)
-+{
-+ struct mipv6_dad_cell *tmp;
-+
-+ tmp = dad_cell_head.next;
-+ while (tmp != &dad_cell_head && tmp != cell) {
-+ tmp = tmp->next;
-+ }
-+ if (tmp == cell) {
-+ if (cell->flags == DAD_INIT_ENTRY) {
-+ /* Found valid entry */
-+ if (--cell->probes == 0) {
-+ /*
-+ * Retransmission's are over - return success.
-+ */
-+ cell->flags = DAD_UNIQUE_ADDRESS;
-+
-+ /*
-+ * Leave this address to avoid future
-+ * processing of NA's.
-+ */
-+ mipv6_leave_sol_mc_addr(&cell->ll_haddr,
-+ cell->ifp->idev->
-+ dev);
-+ if (ipv6_addr_cmp(&cell->ll_haddr, &cell->haddr))
-+ mipv6_leave_sol_mc_addr(&cell->haddr,
-+ cell->ifp->idev->dev);
-+ /* start timeout to delete this cell. */
-+ mipv6_start_dad_head_timer(cell);
-+ return 0;
-+ }
-+ /*
-+ * Retransmission not finished, send another NS and
-+ * return failure.
-+ */
-+ mipv6_dad_send_ns(cell->ifp, &cell->ll_haddr);
-+ if (ipv6_addr_cmp(&cell->ll_haddr, &cell->haddr))
-+ mipv6_leave_sol_mc_addr(&cell->haddr,
-+ cell->ifp->idev->dev);
-+ cell->callback_timer.expires = jiffies +
-+ cell->ifp->idev->nd_parms->retrans_time;
-+ add_timer(&cell->callback_timer);
-+ } else {
-+ /*
-+ * This means that an NA was received before the
-+ * timeout and when the state changed from
-+ * DAD_INIT_ENTRY, the BU got failed as a result.
-+ * There is nothing to be done.
-+ */
-+ }
-+ }
-+ return -1;
-+}
-+
-+/* ENTRY routine called via Timeout */
-+static void mipv6_dad_timeout(unsigned long arg)
-+{
-+ __u8 ba_status = SUCCESS;
-+ struct in6_addr daddr;
-+ struct in6_addr haddr;
-+ struct in6_addr coa;
-+ struct in6_addr rep_coa;
-+ struct inet6_ifaddr *ifp;
-+ int ifindex;
-+ __u32 ba_lifetime;
-+ __u16 sequence;
-+ __u8 flags;
-+ struct mipv6_dad_cell *cell = (struct mipv6_dad_cell *) arg;
-+
-+ /*
-+ * If entry is not in the list, we have already sent BU Failure
-+ * after getting a NA.
-+ */
-+ read_lock(&dad_lock);
-+ if (dad_search_cell(cell) < 0) {
-+ /*
-+ * 'cell' is no longer valid (may not be in the list or
-+ * is already processed, due to NA processing), or NS
-+ * retransmissions are not yet over.
-+ */
-+ read_unlock(&dad_lock);
-+ return;
-+ }
-+
-+ /* This is the final Timeout. Send Bind Ack Success */
-+
-+ ifp = cell->ifp;
-+ ifindex = cell->ifindex;
-+ ba_lifetime = cell->ba_lifetime;
-+ sequence = cell->sequence;
-+ flags = cell->bu_flags;
-+
-+ ipv6_addr_copy(&daddr, &cell->daddr);
-+ ipv6_addr_copy(&haddr, &cell->haddr);
-+ ipv6_addr_copy(&coa, &cell->coa);
-+ ipv6_addr_copy(&rep_coa, &cell->rep_coa);
-+ read_unlock(&dad_lock);
-+
-+ /* Send BU Acknowledgement Success */
-+ mipv6_bu_finish(ifp, ifindex, ba_status,
-+ &daddr, &haddr, &coa, &rep_coa,
-+ ba_lifetime, sequence, flags, NULL);
-+ return;
-+}
-+
-+/*
-+ * Check if original home address exists in our DAD pending list, if so return
-+ * the cell.
-+ *
-+ * Assumes that the caller is holding the dad_lock in writer mode.
-+ */
-+static struct mipv6_dad_cell *mipv6_dad_get_cell(struct in6_addr *haddr)
-+{
-+ struct mipv6_dad_cell *cell;
-+
-+ cell = dad_cell_head.next;
-+ while (cell != &dad_cell_head
-+ && ipv6_addr_cmp(&cell->haddr, haddr)) {
-+ cell = cell->next;
-+ }
-+ if (cell == &dad_cell_head) {
-+ /* Not found element */
-+ return NULL;
-+ }
-+ return cell;
-+}
-+
-+/*
-+ * Save all parameters needed for doing a Bind Ack in the mipv6_dad_cell
-+ * structure.
-+ */
-+static void mipv6_dad_save_cell(struct mipv6_dad_cell *cell,
-+ struct inet6_ifaddr *ifp, int ifindex,
-+ struct in6_addr *daddr,
-+ struct in6_addr *haddr,
-+ struct in6_addr *coa,
-+ struct in6_addr *rep_coa,
-+ __u32 ba_lifetime,
-+ __u16 sequence, __u8 flags)
-+{
-+ in6_ifa_hold(ifp);
-+ cell->ifp = ifp;
-+ cell->ifindex = ifindex;
-+
-+ ipv6_addr_copy(&cell->daddr, daddr);
-+ ipv6_addr_copy(&cell->haddr, haddr);
-+ ipv6_addr_copy(&cell->coa, coa);
-+ ipv6_addr_copy(&cell->rep_coa, rep_coa);
-+
-+ /* Convert cell->ll_haddr to Link Local address */
-+ if (flags & MIPV6_BU_F_LLADDR)
-+ mipv6_generate_ll_addr(&cell->ll_haddr, haddr);
-+ else
-+ ipv6_addr_copy(&cell->ll_haddr, haddr);
-+
-+ cell->ba_lifetime = ba_lifetime;
-+ cell->sequence = sequence;
-+ cell->bu_flags = flags;
-+}
-+
-+/*
-+ * Top level DAD routine for performing DAD.
-+ *
-+ * Return values
-+ * 0 : Don't need to do DAD.
-+ * 1 : Need to do DAD.
-+ * -n : Error, where 'n' is the reason for the error.
-+ *
-+ * Assumption : DAD process has been optimized by using cached values upto
-+ * some time. However sometimes this can cause problems. Eg. when the first
-+ * BU was received, DAD might have failed. Before the second BU arrived,
-+ * the node using MN's home address might have stopped using it, but still
-+ * we will return DAD_DUPLICATE_ADDRESS based on the first DAD's result. Or
-+ * this can go the other way around. However, it is a very small possibility
-+ * and thus optimization is turned on by default. It is possible to change
-+ * this feature (needs a little code-rewriting in this routine), but
-+ * currently DAD result is being cached for performance reasons.
-+ */
-+int mipv6_dad_start(struct inet6_ifaddr *ifp, int ifindex,
-+ struct in6_addr *daddr, struct in6_addr *haddr,
-+ struct in6_addr *coa, struct in6_addr *rep_coa,
-+ __u32 ba_lifetime, __u16 sequence, __u8 flags)
-+{
-+ int found;
-+ struct mipv6_dad_cell *cell;
-+ struct mipv6_bce bc_entry;
-+
-+ if (ifp->idev->cnf.dad_transmits == 0) {
-+ /* DAD is not configured on the HA, return SUCCESS */
-+ return 0;
-+ }
-+
-+ if (mipv6_bcache_get(haddr, daddr, &bc_entry) == 0) {
-+ /*
-+ * We already have an entry in our cache - don't need to
-+ * do DAD as we are already defending this home address.
-+ */
-+ return 0;
-+ }
-+
-+ write_lock(&dad_lock);
-+ if ((cell = mipv6_dad_get_cell(haddr)) != NULL) {
-+ /*
-+ * An existing entry for BU was found in our cache due
-+ * to retransmission of the BU or a new COA registration.
-+ */
-+ switch (cell->flags) {
-+ case DAD_INIT_ENTRY:
-+ /* Old entry is waiting for DAD to complete */
-+ break;
-+ case DAD_UNIQUE_ADDRESS:
-+ /* DAD is finished successfully - return success. */
-+ write_unlock(&dad_lock);
-+ return 0;
-+ case DAD_DUPLICATE_ADDRESS:
-+ /*
-+ * DAD is finished and we got a NA while doing BU -
-+ * return failure.
-+ */
-+ write_unlock(&dad_lock);
-+ return -DUPLICATE_ADDR_DETECT_FAIL;
-+ default:
-+ /* Unknown state - should never happen */
-+ DEBUG(DBG_WARNING,
-+ "cell entry in unknown state : %d",
-+ cell->flags);
-+ write_unlock(&dad_lock);
-+ return -REASON_UNSPECIFIED;
-+ }
-+ found = 1;
-+ } else {
-+ if ((cell = (struct mipv6_dad_cell *)
-+ kmalloc(sizeof(struct mipv6_dad_cell), GFP_ATOMIC))
-+ == NULL) {
-+ return -INSUFFICIENT_RESOURCES;
-+ }
-+ found = 0;
-+ }
-+
-+ mipv6_dad_save_cell(cell, ifp, ifindex, daddr, haddr, coa, rep_coa,
-+ ba_lifetime, sequence, flags);
-+
-+ if (!found) {
-+ cell->flags = DAD_INIT_ENTRY;
-+ cell->probes = ifp->idev->cnf.dad_transmits;
-+
-+ /* Insert element on dad_cell_head list */
-+ dad_cell_head.prev->next = cell;
-+ cell->next = &dad_cell_head;
-+ cell->prev = dad_cell_head.prev;
-+ dad_cell_head.prev = cell;
-+ write_unlock(&dad_lock);
-+ if (flags & MIPV6_BU_F_LLADDR) {
-+ /* join the solicited node MC of the global homeaddr.*/
-+ mipv6_join_sol_mc_addr(&cell->haddr, ifp->idev->dev);
-+ /* Send a NS */
-+ mipv6_dad_send_ns(ifp, &cell->haddr);
-+ }
-+ /* join the solicited node MC of the homeaddr. */
-+ mipv6_join_sol_mc_addr(&cell->ll_haddr, ifp->idev->dev);
-+
-+ /* Send a NS */
-+ mipv6_dad_send_ns(ifp, &cell->ll_haddr);
-+
-+ /* Initialize timer for this cell to timeout the NS. */
-+ init_timer(&cell->callback_timer);
-+ cell->callback_timer.data = (unsigned long) cell;
-+ cell->callback_timer.function = mipv6_dad_timeout;
-+ cell->callback_timer.expires = jiffies +
-+ ifp->idev->nd_parms->retrans_time;
-+ add_timer(&cell->callback_timer);
-+ } else {
-+ write_unlock(&dad_lock);
-+ }
-+ return 1;
-+}
-+
-+void __init mipv6_dad_init(void)
-+{
-+ dad_cell_head.next = dad_cell_head.prev = &dad_cell_head;
-+ init_timer(&dad_cell_head.callback_timer);
-+ dad_cell_head.callback_timer.data = 0;
-+ dad_cell_head.callback_timer.function =
-+ mipv6_dad_delete_old_entries;
-+}
-+
-+void __exit mipv6_dad_exit(void)
-+{
-+ struct mipv6_dad_cell *curr, *next;
-+
-+ write_lock_bh(&dad_lock);
-+ del_timer(&dad_cell_head.callback_timer);
-+
-+ curr = dad_cell_head.next;
-+ while (curr != &dad_cell_head) {
-+ next = curr->next;
-+ del_timer(&curr->callback_timer);
-+ if (curr->flags == DAD_INIT_ENTRY) {
-+ /*
-+ * We were in DAD_INIT state and listening to the
-+ * solicited node MC address - need to stop that.
-+ */
-+ mipv6_leave_sol_mc_addr(&curr->ll_haddr,
-+ curr->ifp->idev->dev);
-+ if (ipv6_addr_cmp(&curr->ll_haddr, &curr->haddr))
-+ mipv6_leave_sol_mc_addr(&curr->haddr,
-+ curr->ifp->idev->dev);
-+ }
-+ in6_ifa_put(curr->ifp);
-+ kfree(curr);
-+ curr = next;
-+ }
-+ dad_cell_head.next = dad_cell_head.prev = &dad_cell_head;
-+ write_unlock_bh(&dad_lock);
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/prefix.c linux-2.4.25/net/ipv6/mobile_ip6/prefix.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/prefix.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/prefix.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,217 @@
-+/**
-+ * Prefix solicitation and advertisement
-+ *
-+ * Authors:
-+ * Jaakko Laine <medved@iki.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/icmpv6.h>
-+#include <linux/net.h>
-+#include <linux/spinlock.h>
-+#include <linux/timer.h>
-+#include <linux/netdevice.h>
-+#include <net/ipv6.h>
-+#include <net/addrconf.h>
-+#include <net/ip6_route.h>
-+#include <net/mipv6.h>
-+
-+#include "mipv6_icmp.h"
-+#include "debug.h"
-+#include "sortedlist.h"
-+#include "prefix.h"
-+#include "config.h"
-+
-+#define INFINITY 0xffffffff
-+
-+struct timer_list pfx_timer;
-+
-+struct list_head pfx_list;
-+rwlock_t pfx_list_lock = RW_LOCK_UNLOCKED;
-+
-+int compare_pfx_list_entry(const void *data1, const void *data2,
-+ int datalen)
-+{
-+ struct pfx_list_entry *e1 = (struct pfx_list_entry *) data1;
-+ struct pfx_list_entry *e2 = (struct pfx_list_entry *) data2;
-+
-+ return ((ipv6_addr_cmp(&e1->daddr, &e2->daddr) == 0)
-+ && (e2->ifindex == -1 || e1->ifindex == e2->ifindex));
-+}
-+
-+/**
-+ * mipv6_pfx_cancel_send - cancel pending items to daddr from saddr
-+ * @daddr: Destination address
-+ * @ifindex: pending items on this interface will be canceled
-+ *
-+ * if ifindex == -1, all items to daddr will be removed
-+ */
-+void mipv6_pfx_cancel_send(struct in6_addr *daddr, int ifindex)
-+{
-+ unsigned long tmp;
-+ struct pfx_list_entry entry;
-+
-+ DEBUG_FUNC();
-+
-+ /* We'll just be comparing these parts... */
-+ memcpy(&entry.daddr, daddr, sizeof(struct in6_addr));
-+ entry.ifindex = ifindex;
-+
-+ write_lock_bh(&pfx_list_lock);
-+
-+ while (mipv6_slist_del_item(&pfx_list, &entry,
-+ compare_pfx_list_entry) == 0)
-+ ;
-+
-+ if ((tmp = mipv6_slist_get_first_key(&pfx_list)))
-+ mod_timer(&pfx_timer, tmp);
-+
-+ write_unlock_bh(&pfx_list_lock);
-+}
-+
-+/**
-+ * mipv6_pfx_add_ha - add a new HA to send prefix solicitations to
-+ * @daddr: address of HA
-+ * @saddr: our address to use as source address
-+ * @ifindex: interface index
-+ */
-+void mipv6_pfx_add_ha(struct in6_addr *daddr, struct in6_addr *saddr,
-+ int ifindex)
-+{
-+ unsigned long tmp;
-+ struct pfx_list_entry entry;
-+
-+ DEBUG_FUNC();
-+
-+ memcpy(&entry.daddr, daddr, sizeof(struct in6_addr));
-+ memcpy(&entry.saddr, saddr, sizeof(struct in6_addr));
-+ entry.retries = 0;
-+ entry.ifindex = ifindex;
-+
-+ write_lock_bh(&pfx_list_lock);
-+ if (mipv6_slist_modify(&pfx_list, &entry, sizeof(struct pfx_list_entry),
-+ jiffies + INITIAL_SOLICIT_TIMER * HZ,
-+ compare_pfx_list_entry))
-+ DEBUG(DBG_WARNING, "Cannot add new HA to pfx list");
-+
-+ if ((tmp = mipv6_slist_get_first_key(&pfx_list)))
-+ mod_timer(&pfx_timer, tmp);
-+ write_unlock_bh(&pfx_list_lock);
-+}
-+
-+int mipv6_pfx_add_home(int ifindex, struct in6_addr *saddr,
-+ struct in6_addr *daddr, unsigned long min_expire)
-+{
-+ unsigned long tmp;
-+
-+ write_lock(&pfx_list_lock);
-+
-+ if (min_expire != INFINITY) {
-+ unsigned long expire;
-+ struct pfx_list_entry entry;
-+
-+ memcpy(&entry.daddr, saddr, sizeof(struct in6_addr));
-+ memcpy(&entry.saddr, daddr, sizeof(struct in6_addr));
-+ entry.retries = 0;
-+ entry.ifindex = ifindex;
-+
-+ /* This is against the RFC 3775, but we need to set
-+ * a minimum interval for a prefix solicitation.
-+ * Otherwise a prefix solicitation storm will
-+ * result if valid lifetime of the prefix is
-+ * smaller than MAX_PFX_ADV_DELAY
-+ */
-+ min_expire -= MAX_PFX_ADV_DELAY;
-+ min_expire = min_expire < MIN_PFX_SOL_DELAY ? MIN_PFX_SOL_DELAY : min_expire;
-+
-+ expire = jiffies + min_expire * HZ;
-+
-+ if (mipv6_slist_modify(&pfx_list, &entry,
-+ sizeof(struct pfx_list_entry),
-+ expire,
-+ compare_pfx_list_entry) != 0)
-+ DEBUG(DBG_WARNING, "Cannot add new entry to pfx_list");
-+ }
-+
-+ if ((tmp = mipv6_slist_get_first_key(&pfx_list)))
-+ mod_timer(&pfx_timer, tmp);
-+
-+ write_unlock(&pfx_list_lock);
-+
-+ return 0;
-+}
-+
-+/**
-+ * set_ha_pfx_list - manipulate pfx_list for HA when timer goes off
-+ * @entry: pfx_list_entry that is due
-+ */
-+static void set_ha_pfx_list(struct pfx_list_entry *entry)
-+{
-+}
-+
-+/**
-+ * set_mn_pfx_list - manipulate pfx_list for MN when timer goes off
-+ * @entry: pfx_list_entry that is due
-+ */
-+static void set_mn_pfx_list(struct pfx_list_entry *entry)
-+{
-+}
-+
-+/**
-+ * pfx_timer_handler - general timer handler
-+ * @dummy: dummy
-+ *
-+ * calls set_ha_pfx_list and set_mn_pfx_list to do the thing when
-+ * a timer goes off
-+ */
-+static void pfx_timer_handler(unsigned long dummy)
-+{
-+ unsigned long tmp;
-+ struct pfx_list_entry *entry;
-+
-+ DEBUG_FUNC();
-+
-+ write_lock(&pfx_list_lock);
-+ if (!(entry = mipv6_slist_get_first(&pfx_list)))
-+ goto out;
-+
-+ if (mip6node_cnf.capabilities & CAP_HA)
-+ set_ha_pfx_list(entry);
-+ if (mip6node_cnf.capabilities & CAP_MN)
-+ set_mn_pfx_list(entry);
-+ if ((tmp = mipv6_slist_get_first_key(&pfx_list)))
-+ mod_timer(&pfx_timer, tmp);
-+
-+ out:
-+ write_unlock(&pfx_list_lock);
-+}
-+
-+int mipv6_initialize_pfx_icmpv6(void)
-+{
-+ INIT_LIST_HEAD(&pfx_list);
-+
-+ init_timer(&pfx_timer);
-+ pfx_timer.function = pfx_timer_handler;
-+
-+ return 0;
-+}
-+
-+void mipv6_shutdown_pfx_icmpv6(void)
-+{
-+ struct prefix_info *tmp;
-+
-+ if (timer_pending(&pfx_timer))
-+ del_timer(&pfx_timer);
-+
-+ write_lock_bh(&pfx_list_lock);
-+ while ((tmp = mipv6_slist_del_first(&pfx_list)))
-+ kfree(tmp);
-+ write_unlock_bh(&pfx_list_lock);
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/prefix.h linux-2.4.25/net/ipv6/mobile_ip6/prefix.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/prefix.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/prefix.h 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,57 @@
-+/*
-+ * MIPL Mobile IPv6 Prefix solicitation and advertisement
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef _PREFIX_H
-+#define _PREFIX_H
-+
-+#include <net/addrconf.h>
-+
-+struct pfx_list_entry {
-+ struct in6_addr daddr;
-+ struct in6_addr saddr;
-+ int retries;
-+ int ifindex;
-+};
-+
-+extern struct list_head pfx_list;
-+extern rwlock_t pfx_list_lock;
-+extern struct timer_list pfx_timer;
-+
-+int compare_pfx_list_entry(const void *data1, const void *data2,
-+ int datalen);
-+
-+/**
-+ * mipv6_pfx_cancel_send - cancel pending pfx_advs/sols to daddr
-+ * @daddr: destination address
-+ * @ifindex: pending items on this interface will be canceled
-+ *
-+ * if ifindex == -1, all items to daddr will be removed
-+ */
-+void mipv6_pfx_cancel_send(struct in6_addr *daddr, int ifindex);
-+
-+/**
-+ * mipv6_pfx_add_ha - add a new HA to send prefix solicitations to
-+ * @daddr: address of HA
-+ * @saddr: our address to use as source address
-+ * @ifindex: interface index
-+ */
-+void mipv6_pfx_add_ha(struct in6_addr *daddr, struct in6_addr *saddr,
-+ int ifindex);
-+
-+void mipv6_pfxs_modified(struct prefix_info *pinfo, int ifindex);
-+
-+int mipv6_pfx_add_home(int ifindex, struct in6_addr *daddr,
-+ struct in6_addr *saddr, unsigned long min_expire);
-+
-+int mipv6_initialize_pfx_icmpv6(void);
-+void mipv6_shutdown_pfx_icmpv6(void);
-+
-+#endif
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/prefix_ha.c linux-2.4.25/net/ipv6/mobile_ip6/prefix_ha.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/prefix_ha.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/prefix_ha.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,122 @@
-+/**
-+ * Prefix advertisement for Home Agent
-+ *
-+ * Authors:
-+ * Jaakko Laine <medved@iki.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/icmpv6.h>
-+#include <linux/net.h>
-+#include <linux/spinlock.h>
-+#include <linux/timer.h>
-+#include <linux/netdevice.h>
-+#include <net/ipv6.h>
-+#include <net/addrconf.h>
-+#include <net/ip6_route.h>
-+#include <net/mipv6.h>
-+
-+#include "mipv6_icmp.h"
-+#include "debug.h"
-+#include "sortedlist.h"
-+#include "util.h"
-+#include "bcache.h"
-+#include "config.h"
-+#include "prefix.h"
-+
-+/**
-+ * pfx_adv_iterator - modify pfx_list entries according to new prefix info
-+ * @data: MN's home registration bcache_entry
-+ * @args: new prefix info
-+ * @sortkey: ignored
-+ */
-+static int pfx_adv_iterator(void *data, void *args, unsigned long sortkey)
-+{
-+ struct mipv6_bce *bc_entry = (struct mipv6_bce *) data;
-+ struct prefix_info *pinfo = (struct prefix_info *) args;
-+
-+ if (mipv6_prefix_compare(&bc_entry->coa, &pinfo->prefix,
-+ pinfo->prefix_len) == 0) {
-+ struct pfx_list_entry pfx_entry;
-+
-+ memcpy(&pfx_entry.daddr, &bc_entry->coa,
-+ sizeof(struct in6_addr));
-+ memcpy(&pfx_entry.daddr, &bc_entry->our_addr,
-+ sizeof(struct in6_addr));
-+ pfx_entry.retries = 0;
-+ pfx_entry.ifindex = bc_entry->ifindex;
-+
-+ mipv6_slist_modify(&pfx_list, &pfx_entry,
-+ sizeof(struct pfx_list_entry),
-+ jiffies +
-+ net_random() % (MAX_PFX_ADV_DELAY * HZ),
-+ compare_pfx_list_entry);
-+ }
-+
-+ return 0;
-+}
-+
-+struct homereg_iterator_args {
-+ struct list_head *head;
-+ int count;
-+};
-+
-+static int homereg_iterator(void *data, void *args, unsigned long *sortkey)
-+{
-+ struct mipv6_bce *entry = (struct mipv6_bce *) data;
-+ struct homereg_iterator_args *state =
-+ (struct homereg_iterator_args *) args;
-+
-+ if (entry->type == HOME_REGISTRATION) {
-+ mipv6_slist_add(state->head, entry,
-+ sizeof(struct mipv6_bce),
-+ state->count);
-+ state->count++;
-+ }
-+ return 0;
-+}
-+
-+static int mipv6_bcache_get_homeregs(struct list_head *head)
-+{
-+ struct homereg_iterator_args args;
-+
-+ DEBUG_FUNC();
-+
-+ args.count = 0;
-+ args.head = head;
-+
-+ mipv6_bcache_iterate(homereg_iterator, &args);
-+ return args.count;
-+}
-+
-+/**
-+ * mipv6_prefix_added - prefix was added to interface, act accordingly
-+ * @pinfo: prefix_info that was added
-+ * @ifindex: interface index
-+ */
-+void mipv6_pfxs_modified(struct prefix_info *pinfo, int ifindex)
-+{
-+ int count;
-+ unsigned long tmp;
-+ struct list_head home_regs;
-+
-+ DEBUG_FUNC();
-+
-+ INIT_LIST_HEAD(&home_regs);
-+
-+ if (!(count = mipv6_bcache_get_homeregs(&home_regs)))
-+ return;
-+
-+ write_lock_bh(&pfx_list_lock);
-+ mipv6_slist_for_each(&home_regs, pinfo, pfx_adv_iterator);
-+ if ((tmp = mipv6_slist_get_first_key(&pfx_list)))
-+ mod_timer(&pfx_timer, tmp);
-+ write_unlock_bh(&pfx_list_lock);
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/rr_crypto.c linux-2.4.25/net/ipv6/mobile_ip6/rr_crypto.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/rr_crypto.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/rr_crypto.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,255 @@
-+/*
-+ * rr_cookie.c - Mobile IPv6 return routability crypto
-+ * Author : Henrik Petander <henrik.petander@hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ *
-+ *
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/types.h>
-+#include <linux/spinlock.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/in6.h>
-+#include <linux/init.h>
-+#include <linux/random.h>
-+
-+#include <net/ipv6.h>
-+
-+#include "debug.h"
-+#include "hmac.h"
-+#include "rr_crypto.h"
-+
-+#define DBG_RR 5
-+
-+u8 k_CN[HMAC_SHA1_KEY_SIZE]; // secret key of CN
-+
-+u16 curr_index = 0;
-+
-+struct nonce_timestamp nonce_table[MAX_NONCES];
-+spinlock_t nonce_lock = SPIN_LOCK_UNLOCKED;
-+void update_nonces(void);
-+
-+/** nonce_is_fresh - whether the nonce was generated recently
-+ *
-+ * @non_ts : table entry containing the nonce and a timestamp
-+ * @interval : if nonce was generated within interval seconds it is fresh
-+ *
-+ * Returns 1 if the nonce is fresh, 0 otherwise.
-+ */
-+static int nonce_is_fresh(struct nonce_timestamp *non_ts, unsigned long interval)
-+{
-+ if (time_before(jiffies, non_ts->timestamp + interval * HZ) && !non_ts->invalid)
-+ return 1;
-+ return 0;
-+}
-+void mipv6_rr_invalidate_nonce(u16 nonce_ind)
-+{
-+ spin_lock_bh(&nonce_lock);
-+ if (nonce_ind > MAX_NONCES) {
-+ spin_unlock_bh(&nonce_lock);
-+ return;
-+ }
-+ nonce_table[nonce_ind].invalid = 1;
-+ spin_unlock_bh(&nonce_lock);
-+}
-+/* Returns a pointer to a new nonce */
-+struct mipv6_rr_nonce * mipv6_rr_get_new_nonce(void)
-+{
-+ struct mipv6_rr_nonce *nce = kmalloc(sizeof(*nce), GFP_ATOMIC);
-+
-+ if (!nce)
-+ return NULL;
-+ // Lock nonces here
-+ spin_lock_bh(&nonce_lock);
-+ // If nonce is not fresh create new one
-+ if (!nonce_is_fresh(&nonce_table[curr_index], MIPV6_RR_NONCE_LIFETIME)) {
-+ // increment the last nonce pointer and create new nonce
-+ curr_index++;
-+ // Wrap around
-+ if (curr_index == MAX_NONCES)
-+ curr_index = 0;
-+ // Get random data to fill the nonce data
-+ get_random_bytes(nonce_table[curr_index].nonce.data, MIPV6_RR_NONCE_DATA_LENGTH);
-+ // Fill the index field
-+ nonce_table[curr_index].nonce.index = curr_index;
-+ nonce_table[curr_index].invalid = 0;
-+ nonce_table[curr_index].timestamp = jiffies;
-+ }
-+ spin_unlock_bh(&nonce_lock);
-+ memcpy(nce, &nonce_table[curr_index].nonce, sizeof(*nce));
-+ // Unlock nonces
-+ return nce;
-+}
-+/** mipv6_rr_nonce_get_by_index - returns a nonce for index
-+ * @nonce_ind : index of the nonce
-+ *
-+ * Returns a nonce or NULL if the nonce index was invalid or the nonce
-+ * for the index was not fresh.
-+ */
-+struct mipv6_rr_nonce * mipv6_rr_nonce_get_by_index(u16 nonce_ind)
-+{
-+ struct mipv6_rr_nonce *nce = NULL;
-+
-+ spin_lock_bh(&nonce_lock);
-+ if (nonce_ind >= MAX_NONCES) {
-+ DEBUG(DBG_WARNING, "Nonce index field from BU invalid");
-+
-+ /* Here a double of the nonce_lifetime is used for freshness
-+ * verification, since the nonces
-+ * are not created in response to every initiator packet
-+ */
-+ } else if (nonce_is_fresh(&nonce_table[nonce_ind], 2 * MIPV6_RR_NONCE_LIFETIME)) {
-+ nce = kmalloc(sizeof(*nce), GFP_ATOMIC);
-+ memcpy(nce, &nonce_table[nonce_ind].nonce, sizeof(*nce));
-+ }
-+ spin_unlock_bh(&nonce_lock);
-+
-+ return nce;
-+}
-+
-+/* Fills rr test init cookies with random bytes */
-+void mipv6_rr_mn_cookie_create(u8 *cookie)
-+{
-+ get_random_bytes(cookie, MIPV6_RR_COOKIE_LENGTH);
-+}
-+
-+/** mipv6_rr_cookie_create - builds a home or care-of cookie
-+ *
-+ * @addr : the home or care-of address from HoTI or CoTI
-+ * @ckie : memory where the cookie is copied to
-+ * @nce : pointer to a nonce used for the calculation, nce is freed during the function
-+ *
-+ */
-+int mipv6_rr_cookie_create(struct in6_addr *addr, u8 **ckie,
-+ u16 nonce_index)
-+{
-+ struct ah_processing ah_proc;
-+ u8 digest[HMAC_SHA1_HASH_LEN];
-+ struct mipv6_rr_nonce *nce;
-+
-+ if ((nce = mipv6_rr_nonce_get_by_index(nonce_index))== NULL)
-+ return -1;
-+
-+ if (*ckie == NULL && (*ckie = kmalloc(MIPV6_RR_COOKIE_LENGTH,
-+ GFP_ATOMIC)) == NULL) {
-+ kfree(nce);
-+ return -1;
-+ }
-+ /* Calculate the full hmac-sha1 digest from address and nonce using the secret key of cn */
-+
-+ if (ah_hmac_sha1_init(&ah_proc, k_CN, HMAC_SHA1_KEY_SIZE) < 0) {
-+ DEBUG(DBG_ERROR, "Hmac sha1 initialization failed");
-+ kfree(nce);
-+ return -1;
-+ }
-+
-+ ah_hmac_sha1_loop(&ah_proc, addr, sizeof(*addr));
-+ ah_hmac_sha1_loop(&ah_proc, nce->data, MIPV6_RR_NONCE_DATA_LENGTH);
-+ ah_hmac_sha1_result(&ah_proc, digest);
-+
-+
-+ /* clean up nonce */
-+ kfree(nce);
-+
-+ /* Copy first 64 bits of hash target to the cookie */
-+ memcpy(*ckie, digest, MIPV6_RR_COOKIE_LENGTH);
-+ return 0;
-+}
-+
-+/** mipv6_rr_key_calc - creates BU authentication key
-+ *
-+ * @hoc : Home Cookie
-+ * @coc : Care-of Cookie
-+ *
-+ * Returns BU authentication key of length HMAC_SHA1_KEY_SIZE or NULL in error cases,
-+ * caller needs to free the key.
-+ */
-+u8 *mipv6_rr_key_calc(u8 *hoc, u8 *coc)
-+{
-+
-+ u8 *key_bu = kmalloc(HMAC_SHA1_KEY_SIZE, GFP_ATOMIC);
-+ SHA1_CTX c;
-+
-+ if (!key_bu) {
-+ DEBUG(DBG_CRITICAL, "Memory allocation failed, could nort create BU authentication key");
-+ return NULL;
-+ }
-+
-+ /* Calculate the key from home and care-of cookies
-+ * Kbu = sha1(home_cookie | care-of cookie)
-+ * or KBu = sha1(home_cookie), if MN deregisters
-+ */
-+ sha1_init(&c);
-+ sha1_compute(&c, hoc, MIPV6_RR_COOKIE_LENGTH);
-+ if (coc)
-+ sha1_compute(&c, coc, MIPV6_RR_COOKIE_LENGTH);
-+ sha1_final(&c, key_bu);
-+ DEBUG(DBG_RR, "Home and Care-of cookies used for calculating key ");
-+ debug_print_buffer(DBG_RR, hoc, MIPV6_RR_COOKIE_LENGTH);
-+ if (coc)
-+ debug_print_buffer(DBG_RR, coc, MIPV6_RR_COOKIE_LENGTH);
-+
-+ return key_bu;
-+}
-+
-+void mipv6_rr_init(void)
-+{
-+ get_random_bytes(k_CN, HMAC_SHA1_KEY_SIZE);
-+ memset(nonce_table, 0, MAX_NONCES * sizeof(struct nonce_timestamp));
-+}
-+
-+#ifdef TEST_MIPV6_RR_CRYPTO
-+void mipv6_test_rr(void)
-+{
-+ struct mipv6_rr_nonce *nonce;
-+ struct in6_addr a1, a2;
-+ int ind1, ind2;
-+ u8 *ckie1 = NULL, *ckie2 = NULL;
-+ u8 *key_mn = NULL, *key_cn = NULL;
-+ mipv6_init_rr();
-+
-+ nonce = mipv6_rr_get_new_nonce();
-+ if (!nonce) {
-+ printk("mipv6_rr_get_new_nonce() failed, at 1! \n");
-+ return;
-+ }
-+ mipv6_rr_cookie_create(&a1, &ckie1, nonce->index);
-+ ind1 = nonce->index;
-+ kfree(nonce);
-+
-+ nonce = mipv6_rr_get_new_nonce();
-+ if (!nonce) {
-+ printk("mipv6_rr_get_new_nonce() failed, at 2! \n");
-+ return;
-+ }
-+
-+ mipv6_rr_cookie_create(&a2, &ckie2, nonce->index);
-+ ind2 = nonce->index;
-+ key_mn = mipv6_rr_key_calc(ckie1, ckie2);
-+
-+ /* Create home and coa cookies based on indices */
-+ mipv6_rr_cookie_create(&a1, &ckie1, ind1);
-+ mipv6_rr_cookie_create(&a2, &ckie2, ind2);
-+ key_cn = mipv6_rr_key_calc(ckie1, ckie2);
-+ if (!key_cn || !key_mn) {
-+ printk("creation of secret key failed!\n");
-+ return;
-+ }
-+ if(memcmp(key_cn, key_mn, HMAC_SHA1_KEY_SIZE))
-+ printk("mipv6_rr_key_calc produced different keys for MN and CN \n");
-+ else
-+ printk("mipv6_rr_crypto test OK\n");
-+ kfree(nonce);
-+ kfree(key_cn);
-+ kfree(key_mn);
-+}
-+#endif
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/rr_crypto.h linux-2.4.25/net/ipv6/mobile_ip6/rr_crypto.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/rr_crypto.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/rr_crypto.h 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,72 @@
-+/*
-+ * MIPL Mobile IPv6 Return routability crypto prototypes
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef _RR_CRYPTO
-+#define _RR_CRYPTO
-+
-+#include <linux/in6.h>
-+
-+/* Macros and data structures */
-+
-+#define MIPV6_RR_NONCE_LIFETIME 60
-+#define MIPV6_RR_NONCE_DATA_LENGTH 8
-+#define MIPV6_RR_COOKIE_LENGTH 8
-+#define COOKIE_SIZE 8
-+#define MAX_NONCES 4
-+#define HMAC_SHA1_KEY_SIZE 20
-+
-+struct mipv6_rr_nonce {
-+ u_int16_t index;
-+ u_int8_t data[MIPV6_RR_NONCE_DATA_LENGTH];
-+};
-+
-+struct nonce_timestamp {
-+ struct mipv6_rr_nonce nonce;
-+ unsigned long timestamp;
-+ u_int8_t invalid;
-+};
-+
-+/* Function definitions */
-+
-+/* Return 1 if equal, 0 if not */
-+static __inline__ int mipv6_equal_cookies(u8 *c1, u8 *c2)
-+{
-+ return (memcmp(c1, c2, MIPV6_RR_COOKIE_LENGTH) == 0);
-+}
-+
-+/* Function declarations */
-+
-+/* Create cookie for HoTi and CoTi */
-+extern void mipv6_rr_mn_cookie_create(u8 *cookie);
-+
-+/* Create cookie for HoT and CoT */
-+extern int mipv6_rr_cookie_create(struct in6_addr *addr, u8 **ckie, u16 nonce_index);
-+
-+/* Calculate return routability key from home and care-of cookies, key length is
-+ * HMAC_SHA1_KEY_SIZE
-+ */
-+extern u_int8_t *mipv6_rr_key_calc(u8 *hoc, u8 *coc);
-+
-+extern struct mipv6_rr_nonce *mipv6_rr_get_new_nonce(void);
-+
-+/* For avoiding replay attacks when MN deregisters */
-+extern void mipv6_rr_invalidate_nonce(u16 nonce_index);
-+/*
-+ * initializes the return routability crypto
-+ */
-+
-+void mipv6_rr_init(void);
-+
-+#ifdef TEST_MIPV6_RR_CRYPTO
-+void mipv6_test_rr(void);
-+#endif /* TEST_MIPV6_RR_CRYPTO */
-+
-+#endif /* RR_CRYPTO */
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/sortedlist.c linux-2.4.25/net/ipv6/mobile_ip6/sortedlist.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/sortedlist.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/sortedlist.c 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,349 @@
-+/**
-+ * Sorted list - linked list with sortkey.
-+ *
-+ * Authors:
-+ * Jaakko Laine <medved@iki.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/types.h>
-+#include <linux/list.h>
-+#include <linux/slab.h>
-+#include <linux/spinlock.h>
-+#include <linux/string.h>
-+
-+struct mipv6_sorted_list_entry {
-+ struct list_head list;
-+ void *data;
-+ int datalen;
-+ unsigned long sortkey;
-+};
-+
-+/**
-+ * compare - compares two arbitrary data items
-+ * @data1: first data item
-+ * @data2: second data item
-+ * @datalen: length of data items in bits
-+ *
-+ * datalen is in bits!
-+ */
-+int mipv6_bitwise_compare(const void *data1, const void *data2, int datalen)
-+{
-+ int n = datalen;
-+ __u8 * ptr1 = (__u8 *)data1;
-+ __u8 * ptr2 = (__u8 *)data2;
-+
-+ for (; n>=0; n-=8, ptr1++, ptr2++) {
-+ if (n >= 8) {
-+ if (*ptr1 != *ptr2)
-+ return 0;
-+ } else {
-+ if ((*ptr1 ^ *ptr2) & ((~0) << (8 - n)))
-+ return 0;
-+ }
-+ }
-+
-+ return 1;
-+}
-+
-+/**
-+ * mipv6_slist_add - add an entry to sorted list
-+ * @head: list_head of the sorted list
-+ * @data: item to store
-+ * @datalen: length of data (in bytes)
-+ * @key: sortkey of item
-+ *
-+ * Allocates memory for entry and data
-+ */
-+int mipv6_slist_add(struct list_head *head, void *data, int datalen,
-+ unsigned long sortkey)
-+{
-+ struct list_head *pos;
-+ struct mipv6_sorted_list_entry *entry, *tmp, *next;
-+
-+ entry = kmalloc(sizeof(struct mipv6_sorted_list_entry), GFP_ATOMIC);
-+
-+ if (!entry)
-+ return -1;
-+
-+ entry->data = kmalloc(datalen, GFP_ATOMIC);
-+
-+ if (!entry->data) {
-+ kfree(entry);
-+ return -1;
-+ }
-+
-+ memcpy(entry->data, data, datalen);
-+ entry->datalen = datalen;
-+ entry->sortkey = sortkey;
-+
-+ if ((pos = head->next) == head) {
-+ list_add(&entry->list, head);
-+ return 0;
-+ }
-+
-+ tmp = list_entry(pos, struct mipv6_sorted_list_entry, list);
-+ if (entry->sortkey < tmp->sortkey) {
-+ list_add(&entry->list, head);
-+ return 0;
-+ }
-+
-+ for (; pos != head; pos = pos->next) {
-+ tmp = list_entry(pos, struct mipv6_sorted_list_entry, list);
-+ if (pos->next == head) {
-+ list_add(&entry->list, &tmp->list);
-+ return 0;
-+ }
-+ next = list_entry(pos->next, struct mipv6_sorted_list_entry, list);
-+ if (entry->sortkey >= tmp->sortkey && entry->sortkey < next->sortkey) {
-+ list_add(&entry->list, &tmp->list);
-+ return 0;
-+ }
-+ }
-+
-+ /* never reached */
-+ return -1;
-+}
-+
-+/**
-+ * mipv6_slist_get_first - get the first data item in the list
-+ * @head: list_head of the sorted list
-+ *
-+ * Returns the actual data item, not copy, so don't kfree it
-+ */
-+void *mipv6_slist_get_first(struct list_head *head)
-+{
-+ struct mipv6_sorted_list_entry *entry;
-+
-+ if (list_empty(head))
-+ return NULL;
-+
-+ entry = list_entry(head->next, struct mipv6_sorted_list_entry, list);
-+ return entry->data;
-+}
-+
-+/**
-+ * mipv6_slist_del_first - delete (and get) the first item in list
-+ * @head: list_head of the sorted list
-+ *
-+ * Remember to kfree the item
-+ */
-+void *mipv6_slist_del_first(struct list_head *head)
-+{
-+ void *tmp;
-+ struct mipv6_sorted_list_entry *entry;
-+
-+ if (list_empty(head))
-+ return NULL;
-+
-+ entry = list_entry(head->next, struct mipv6_sorted_list_entry, list);
-+ tmp = entry->data;
-+
-+ list_del(head->next);
-+ kfree(entry);
-+
-+ return tmp;
-+}
-+
-+/**
-+ * mipv6_slist_del_item - delete entry
-+ * @head: list_head of the sorted list
-+ * @data: item to delete
-+ * @compare: function used for comparing the data items
-+ *
-+ * compare function needs to have prototype
-+ * int (*compare)(const void *data1, const void *data2, int datalen)
-+ */
-+int mipv6_slist_del_item(struct list_head *head, void *data,
-+ int (*compare)(const void *data1, const void *data2,
-+ int datalen))
-+{
-+ struct list_head *pos;
-+ struct mipv6_sorted_list_entry *entry;
-+
-+ for(pos = head->next; pos != head; pos = pos->next) {
-+ entry = list_entry(pos, struct mipv6_sorted_list_entry, list);
-+ if (compare(data, entry->data, entry->datalen)) {
-+ list_del(pos);
-+ kfree(entry->data);
-+ kfree(entry);
-+ return 0;
-+ }
-+ }
-+
-+ return -1;
-+}
-+
-+/**
-+ * mipv6_slist_get_first_key - get sortkey of the first item
-+ * @head: list_head of the sorted list
-+ */
-+unsigned long mipv6_slist_get_first_key(struct list_head *head)
-+{
-+ struct mipv6_sorted_list_entry *entry;
-+
-+ if (list_empty(head))
-+ return 0;
-+
-+ entry = list_entry(head->next, struct mipv6_sorted_list_entry, list);
-+ return entry->sortkey;
-+}
-+
-+/**
-+ * mipv6_slist_get_key - get sortkey of the data item
-+ * @head: list_head of the sorted list
-+ * @data: the item to search for
-+ * @compare: function used for comparing the data items
-+ *
-+ * compare function needs to have prototype
-+ * int (*compare)(const void *data1, const void *data2, int datalen)
-+ */
-+unsigned long mipv6_slist_get_key(struct list_head *head, void *data,
-+ int (*compare)(const void *data1,
-+ const void *data2,
-+ int datalen))
-+{
-+ struct list_head *pos;
-+ struct mipv6_sorted_list_entry *entry;
-+
-+ for(pos = head->next; pos != head; pos = pos->next) {
-+ entry = list_entry(pos, struct mipv6_sorted_list_entry, list);
-+ if (compare(data, entry->data, entry->datalen))
-+ return entry->sortkey;
-+ }
-+
-+ return 0;
-+}
-+
-+/**
-+ * mipv6_slist_get_data - get the data item identified by sortkey
-+ * @head: list_head of the sorted list
-+ * @key: sortkey of the item
-+ *
-+ * Returns the actual data item, not copy, so don't kfree it
-+ */
-+void *mipv6_slist_get_data(struct list_head *head, unsigned long sortkey)
-+{
-+ struct list_head *pos;
-+ struct mipv6_sorted_list_entry *entry;
-+
-+ list_for_each(pos, head) {
-+ entry = list_entry(pos, struct mipv6_sorted_list_entry, list);
-+ if (entry->sortkey == sortkey)
-+ return entry->data;
-+ }
-+
-+ return NULL;
-+}
-+
-+/**
-+ * reorder_entry - move an entry to a new position according to sortkey
-+ * @head: list_head of the sorted list
-+ * @entry_pos: current place of the entry
-+ * @key: new sortkey
-+ */
-+static void reorder_entry(struct list_head *head, struct list_head *entry_pos,
-+ unsigned long sortkey)
-+{
-+ struct list_head *pos;
-+ struct mipv6_sorted_list_entry *entry;
-+
-+ list_del(entry_pos);
-+
-+ for (pos = head->next; pos != head; pos = pos->next) {
-+ entry = list_entry(pos, struct mipv6_sorted_list_entry, list);
-+ if (sortkey >= entry->sortkey) {
-+ list_add(entry_pos, &entry->list);
-+ return;
-+ }
-+ }
-+
-+ list_add(entry_pos, head);
-+}
-+
-+/**
-+ * mipv6_slist_modify - modify data item
-+ * @head: list_head of the sorted list
-+ * @data: item, whose sortkey is to be modified
-+ * @datalen: datalen in bytes
-+ * @new_key: new sortkey
-+ * @compare: function used for comparing the data items
-+ *
-+ * Compies the new data on top of the old one, if compare function returns
-+ * true. If there's no matching entry, new one will be created.
-+ * Compare function needs to have prototype
-+ * int (*compare)(const void *data1, const void *data2, int datalen)
-+ */
-+int mipv6_slist_modify(struct list_head *head, void *data, int datalen,
-+ unsigned long new_key,
-+ int (*compare)(const void *data1, const void *data2,
-+ int datalen))
-+{
-+ struct list_head *pos;
-+ struct mipv6_sorted_list_entry *entry;
-+
-+ for (pos = head->next; pos != head; pos = pos->next) {
-+ entry = list_entry(pos, struct mipv6_sorted_list_entry, list);
-+ if (compare(data, entry->data, datalen)) {
-+ memcpy(entry->data, data, datalen);
-+ entry->sortkey = new_key;
-+ reorder_entry(head, &entry->list, new_key);
-+ return 0;
-+ }
-+ }
-+
-+ return mipv6_slist_add(head, data, datalen, new_key);
-+}
-+
-+/**
-+ * mipv6_slist_push_first - move the first entry to place indicated by new_key
-+ * @head: list_head of the sorted list
-+ * @new_key: new sortkey
-+ */
-+int mipv6_slist_push_first(struct list_head *head, unsigned long new_key)
-+{
-+ struct mipv6_sorted_list_entry *entry;
-+
-+ if (list_empty(head))
-+ return -1;
-+
-+ entry = list_entry(head->next, struct mipv6_sorted_list_entry, list);
-+ entry->sortkey = new_key;
-+
-+ reorder_entry(head, head->next, new_key);
-+ return 0;
-+}
-+
-+/**
-+ * mipv6_slist_for_each - apply func to every item in list
-+ * @head: list_head of the sorted list
-+ * @args: args to pass to func
-+ * @func: function to use
-+ *
-+ * function must be of type
-+ * int (*func)(void *data, void *args, unsigned long sortkey)
-+ * List iteration will stop once func has been applied to every item
-+ * or when func returns true
-+ */
-+int mipv6_slist_for_each(struct list_head *head, void *args,
-+ int (*func)(void *data, void *args,
-+ unsigned long sortkey))
-+{
-+ struct list_head *pos;
-+ struct mipv6_sorted_list_entry *entry;
-+
-+ list_for_each(pos, head) {
-+ entry = list_entry(pos, struct mipv6_sorted_list_entry, list);
-+ if (func(entry->data, args, entry->sortkey))
-+ break;
-+ }
-+
-+ return 0;
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/sortedlist.h linux-2.4.25/net/ipv6/mobile_ip6/sortedlist.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/sortedlist.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/sortedlist.h 2004-06-26 11:29:31.000000000 +0100
-@@ -0,0 +1,133 @@
-+/*
-+ * Sorted list - linked list with sortkey
-+ *
-+ * $Id$
-+ *
-+ * 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.
-+ */
-+
-+/**
-+ * compare - compares two arbitrary data items
-+ * @data1: first data item
-+ * @data2: second data item
-+ * @datalen: length of data items in bits
-+ *
-+ * datalen is in bits!
-+ */
-+int mipv6_bitwise_compare(const void *data1, const void *data2, int datalen);
-+
-+/**
-+ * mipv6_slist_add - add an entry to sorted list
-+ * @head: list_head of the sorted list
-+ * @data: item to store
-+ * @datalen: length of data (in bytes)
-+ * @key: sortkey of item
-+ *
-+ * Allocates memory for entry and data
-+ */
-+int mipv6_slist_add(struct list_head *head, void *data, int datalen,
-+ unsigned long sortkey);
-+
-+/**
-+ * mipv6_slist_get_first - get the first data item in the list
-+ * @head: list_head of the sorted list
-+ *
-+ * Returns the actual data item, not copy, so don't kfree it
-+ */
-+void *mipv6_slist_get_first(struct list_head *head);
-+
-+/**
-+ * mipv6_slist_del_first - delete (and get) the first item in list
-+ * @head: list_head of the sorted list
-+ *
-+ * Remember to kfree the item
-+ */
-+void *mipv6_slist_del_first(struct list_head *head);
-+
-+/**
-+ * mipv6_slist_del_item - delete entry
-+ * @head: list_head of the sorted list
-+ * @data: item to delete
-+ * @compare: function used for comparing the data items
-+ *
-+ * compare function needs to have prototype
-+ * int (*compare)(const void *data1, const void *data2, int datalen) where
-+ * datalen is in bits
-+ */
-+int mipv6_slist_del_item(struct list_head *head, void *data,
-+ int (*compare)(const void *data1, const void *data2,
-+ int datalen));
-+
-+/**
-+ * mipv6_slist_get_first_key - get sortkey of the first item
-+ * @head: list_head of the sorted list
-+ */
-+unsigned long mipv6_slist_get_first_key(struct list_head *head);
-+
-+/**
-+ * mipv6_slist_get_key - get sortkey of the data item
-+ * @head: list_head of the sorted list
-+ * @data: the item to search for
-+ * @compare: function used for comparing the data items
-+ *
-+ * compare function needs to have prototype
-+ * int (*compare)(const void *data1, const void *data2, int datalen) where
-+ * datalen is in bits
-+ */
-+unsigned long mipv6_slist_get_key(struct list_head *head, void *data,
-+ int (*compare)(const void *data1,
-+ const void *data2,
-+ int datalen));
-+
-+/**
-+ * mipv6_slist_get_data - get the data item identified by sortkey
-+ * @head: list_head of the sorted list
-+ * @key: sortkey of the item
-+ *
-+ * Returns the actual data item, not copy, so don't kfree it
-+ */
-+void *mipv6_slist_get_data(struct list_head *head, unsigned long sortkey);
-+
-+/**
-+ * mipv6_slist_modify - modify data item
-+ * @head: list_head of the sorted list
-+ * @data: item, whose sortkey is to be modified
-+ * @datalen: datalen in bytes
-+ * @new_key: new sortkey
-+ * @compare: function used for comparing the data items
-+ *
-+ * Compies the new data on top of the old one, if compare function returns
-+ * non-negative. If there's no matching entry, new one will be created.
-+ * Compare function needs to have prototype
-+ * int (*compare)(const void *data1, const void *data2, int datalen) where
-+ * datalen is in bits.
-+ */
-+int mipv6_slist_modify(struct list_head *head, void *data, int datalen,
-+ unsigned long new_key,
-+ int (*compare)(const void *data1, const void *data2,
-+ int datalen));
-+
-+/**
-+ * mipv6_slist_push_first - move the first entry to place indicated by new_key
-+ * @head: list_head of the sorted list
-+ * @new_key: new sortkey
-+ */
-+int mipv6_slist_push_first(struct list_head *head, unsigned long new_key);
-+
-+/**
-+ * mipv6_slist_for_each - apply func to every item in list
-+ * @head: list_head of the sorted list
-+ * @args: args to pass to func
-+ * @func: function to use
-+ *
-+ * function must be of type
-+ * int (*func)(void *data, void *args, unsigned long sortkey)
-+ * List iteration will stop once func has been applied to every item
-+ * or when func returns true
-+ */
-+int mipv6_slist_for_each(struct list_head *head, void *args,
-+ int (*func)(void *data, void *args,
-+ unsigned long sortkey));
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/stats.c linux-2.4.25/net/ipv6/mobile_ip6/stats.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/stats.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/stats.c 2004-06-26 11:29:32.000000000 +0100
-@@ -0,0 +1,90 @@
-+/*
-+ * Statistics module
-+ *
-+ * Authors:
-+ * Sami Kivisaari <skivisaa@cc.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * 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.
-+ *
-+ * Changes:
-+ * Krishna Kumar,
-+ * Venkata Jagana : SMP locking fix
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/proc_fs.h>
-+#include "stats.h"
-+
-+struct mipv6_statistics mipv6_stats;
-+
-+static int proc_info_dump(
-+ char *buffer, char **start,
-+ off_t offset, int length)
-+{
-+ struct inf {
-+ char *name;
-+ int *value;
-+ } int_stats[] = {
-+ {"NEncapsulations", &mipv6_stats.n_encapsulations},
-+ {"NDecapsulations", &mipv6_stats.n_decapsulations},
-+ {"NBindRefreshRqsRcvd", &mipv6_stats.n_brr_rcvd},
-+ {"NHomeTestInitsRcvd", &mipv6_stats.n_hoti_rcvd},
-+ {"NCareofTestInitsRcvd", &mipv6_stats.n_coti_rcvd},
-+ {"NHomeTestRcvd", &mipv6_stats.n_hot_rcvd},
-+ {"NCareofTestRcvd", &mipv6_stats.n_cot_rcvd},
-+ {"NBindUpdatesRcvd", &mipv6_stats.n_bu_rcvd},
-+ {"NBindAcksRcvd", &mipv6_stats.n_ba_rcvd},
-+ {"NBindNAcksRcvd", &mipv6_stats.n_ban_rcvd},
-+ {"NBindErrorsRcvd", &mipv6_stats.n_be_rcvd},
-+ {"NBindRefreshRqsSent", &mipv6_stats.n_brr_sent},
-+ {"NHomeTestInitsSent", &mipv6_stats.n_hoti_sent},
-+ {"NCareofTestInitsSent", &mipv6_stats.n_coti_sent},
-+ {"NHomeTestSent", &mipv6_stats.n_hot_sent},
-+ {"NCareofTestSent", &mipv6_stats.n_cot_sent},
-+ {"NBindUpdatesSent", &mipv6_stats.n_bu_sent},
-+ {"NBindAcksSent", &mipv6_stats.n_ba_sent},
-+ {"NBindNAcksSent", &mipv6_stats.n_ban_sent},
-+ {"NBindErrorsSent", &mipv6_stats.n_be_sent},
-+ {"NBindUpdatesDropAuth", &mipv6_stats.n_bu_drop.auth},
-+ {"NBindUpdatesDropInvalid", &mipv6_stats.n_bu_drop.invalid},
-+ {"NBindUpdatesDropMisc", &mipv6_stats.n_bu_drop.misc},
-+ {"NBindAcksDropAuth", &mipv6_stats.n_bu_drop.auth},
-+ {"NBindAcksDropInvalid", &mipv6_stats.n_bu_drop.invalid},
-+ {"NBindAcksDropMisc", &mipv6_stats.n_bu_drop.misc},
-+ {"NBindRqsDropAuth", &mipv6_stats.n_bu_drop.auth},
-+ {"NBindRqsDropInvalid", &mipv6_stats.n_bu_drop.invalid},
-+ {"NBindRqsDropMisc", &mipv6_stats.n_bu_drop.misc}
-+ };
-+
-+ int i;
-+ int len = 0;
-+ for(i=0; i<sizeof(int_stats) / sizeof(struct inf); i++) {
-+ len += sprintf(buffer + len, "%s = %d\n",
-+ int_stats[i].name, *int_stats[i].value);
-+ }
-+
-+ *start = buffer + offset;
-+
-+ len -= offset;
-+
-+ if(len > length) len = length;
-+
-+ return len;
-+}
-+
-+int mipv6_stats_init(void)
-+{
-+ memset(&mipv6_stats, 0, sizeof(struct mipv6_statistics));
-+ proc_net_create("mip6_stat", 0, proc_info_dump);
-+ return 0;
-+}
-+
-+void mipv6_stats_exit(void)
-+{
-+ proc_net_remove("mip6_stat");
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/stats.h linux-2.4.25/net/ipv6/mobile_ip6/stats.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/stats.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/stats.h 2004-06-26 11:29:32.000000000 +0100
-@@ -0,0 +1,71 @@
-+/*
-+ * MIPL Mobile IPv6 Statistics header file
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef _STATS_H
-+#define _STATS_H
-+
-+struct mipv6_drop {
-+ __u32 auth;
-+ __u32 invalid;
-+ __u32 misc;
-+};
-+
-+struct mipv6_statistics {
-+ int n_encapsulations;
-+ int n_decapsulations;
-+ int n_mh_in_msg;
-+ int n_mh_in_error;
-+ int n_mh_out_msg;
-+ int n_mh_out_error;
-+
-+ int n_brr_rcvd;
-+ int n_hoti_rcvd;
-+ int n_coti_rcvd;
-+ int n_hot_rcvd;
-+ int n_cot_rcvd;
-+ int n_bu_rcvd;
-+ int n_ba_rcvd;
-+ int n_ban_rcvd;
-+ int n_be_rcvd;
-+
-+ int n_brr_sent;
-+ int n_hoti_sent;
-+ int n_coti_sent;
-+ int n_hot_sent;
-+ int n_cot_sent;
-+ int n_bu_sent;
-+ int n_ba_sent;
-+ int n_ban_sent;
-+ int n_be_sent;
-+
-+ int n_ha_rcvd;
-+ int n_ha_sent;
-+
-+ struct mipv6_drop n_bu_drop;
-+ struct mipv6_drop n_ba_drop;
-+ struct mipv6_drop n_brr_drop;
-+ struct mipv6_drop n_be_drop;
-+ struct mipv6_drop n_ha_drop;
-+};
-+
-+extern struct mipv6_statistics mipv6_stats;
-+
-+#ifdef CONFIG_SMP
-+/* atomic_t is max 24 bits long */
-+#define MIPV6_INC_STATS(X) atomic_inc((atomic_t *)&mipv6_stats.X);
-+#else
-+#define MIPV6_INC_STATS(X) mipv6_stats.X++;
-+#endif
-+
-+int mipv6_stats_init(void);
-+void mipv6_stats_exit(void);
-+
-+#endif
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/tunnel.h linux-2.4.25/net/ipv6/mobile_ip6/tunnel.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/tunnel.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/tunnel.h 2004-06-26 11:29:32.000000000 +0100
-@@ -0,0 +1,35 @@
-+/*
-+ * MIPL Mobile IPv6 IP6-IP6 tunneling header file
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef _TUNNEL_H
-+#define _TUNNEL_H
-+
-+#include <linux/in6.h>
-+#include <linux/if_arp.h>
-+#include <net/ipv6_tunnel.h>
-+
-+static __inline__ int is_mip6_tnl(struct ip6_tnl *t)
-+{
-+ return (t != NULL &&
-+ t->parms.flags & IP6_TNL_F_KERNEL_DEV &&
-+ t->parms.flags & IP6_TNL_F_MIP6_DEV);
-+
-+}
-+
-+static __inline__ int dev_is_mip6_tnl(struct net_device *dev)
-+{
-+ struct ip6_tnl *t = (struct ip6_tnl *)dev->priv;
-+ return (dev->type == ARPHRD_TUNNEL6 && is_mip6_tnl(t));
-+}
-+
-+
-+#endif
-+
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/tunnel_ha.c linux-2.4.25/net/ipv6/mobile_ip6/tunnel_ha.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/tunnel_ha.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/tunnel_ha.c 2004-06-26 11:29:32.000000000 +0100
-@@ -0,0 +1,264 @@
-+/*
-+ * IPv6-IPv6 tunneling module
-+ *
-+ * Authors:
-+ * Sami Kivisaari <skivisaa@cc.hut.fi>
-+ * Ville Nuorvala <vnuorval@tml.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ *
-+ */
-+
-+#include <linux/net.h>
-+#include <linux/skbuff.h>
-+#include <linux/ipv6.h>
-+#include <linux/net.h>
-+#include <linux/netdevice.h>
-+#include <linux/init.h>
-+#include <linux/route.h>
-+#include <linux/ipv6_route.h>
-+
-+#ifdef CONFIG_SYSCTL
-+#include <linux/sysctl.h>
-+#endif /* CONFIG_SYSCTL */
-+
-+#include <net/protocol.h>
-+#include <net/ipv6.h>
-+#include <net/ip6_route.h>
-+#include <net/dst.h>
-+#include <net/addrconf.h>
-+
-+#include "tunnel.h"
-+#include "debug.h"
-+#include "stats.h"
-+#include "config.h"
-+
-+#define MIPV6_TNL_MAX IP6_TNL_MAX
-+#define MIPV6_TNL_MIN 1
-+
-+int mipv6_max_tnls = 3;
-+int mipv6_min_tnls = 1;
-+
-+DECLARE_MUTEX(tnl_sem);
-+
-+int mipv6_max_tnls_sysctl(ctl_table *ctl, int write, struct file *filp,
-+ void *buffer, size_t *lenp)
-+{
-+ int err;
-+
-+ DEBUG_FUNC();
-+
-+ down(&tnl_sem);
-+ if (write) {
-+ int diff;
-+ int old_max_tnls = mipv6_max_tnls;
-+ err = proc_dointvec(ctl, write, filp, buffer, lenp);
-+ if (err < 0)
-+ goto out;
-+ if (mipv6_max_tnls < mipv6_min_tnls ||
-+ mipv6_max_tnls > MIPV6_TNL_MAX) {
-+ mipv6_max_tnls = old_max_tnls;
-+ goto out;
-+ }
-+ if (mipv6_max_tnls < old_max_tnls) {
-+ diff = old_max_tnls - mipv6_max_tnls;
-+ ip6ip6_tnl_dec_max_kdev_count(diff);
-+ } else if (mipv6_max_tnls > old_max_tnls) {
-+ diff = mipv6_max_tnls - old_max_tnls;
-+ ip6ip6_tnl_inc_max_kdev_count(diff);
-+ }
-+ } else {
-+ err = proc_dointvec(ctl, write, filp, buffer, lenp);
-+ }
-+out:
-+ up(&tnl_sem);
-+ return err;
-+}
-+
-+int mipv6_min_tnls_sysctl(ctl_table *ctl, int write, struct file *filp,
-+ void *buffer, size_t *lenp)
-+{
-+ int err;
-+
-+ DEBUG_FUNC();
-+
-+ down(&tnl_sem);
-+ if (write) {
-+ int diff;
-+ int old_min_tnls = mipv6_min_tnls;
-+ err = proc_dointvec(ctl, write, filp, buffer, lenp);
-+ if (err < 0)
-+ goto out;
-+ if (mipv6_min_tnls > mipv6_max_tnls ||
-+ mipv6_min_tnls < MIPV6_TNL_MIN) {
-+ mipv6_min_tnls = old_min_tnls;
-+ goto out;
-+ }
-+ if (mipv6_min_tnls < old_min_tnls) {
-+ diff = old_min_tnls - mipv6_min_tnls;
-+ ip6ip6_tnl_dec_min_kdev_count(diff);
-+ } else if (mipv6_min_tnls > old_min_tnls) {
-+ diff = mipv6_min_tnls - old_min_tnls;
-+ ip6ip6_tnl_inc_min_kdev_count(diff);
-+ }
-+ } else {
-+ err = proc_dointvec(ctl, write, filp, buffer, lenp);
-+ }
-+out:
-+ up(&tnl_sem);
-+ return err;
-+}
-+
-+static __inline__ int mipv6_tnl_add(struct in6_addr *remote,
-+ struct in6_addr *local)
-+{
-+ struct ip6_tnl_parm p;
-+ int ret;
-+
-+ DEBUG_FUNC();
-+
-+ memset(&p, 0, sizeof(p));
-+ p.proto = IPPROTO_IPV6;
-+ ipv6_addr_copy(&p.laddr, local);
-+ ipv6_addr_copy(&p.raddr, remote);
-+ p.hop_limit = 255;
-+ p.flags = (IP6_TNL_F_KERNEL_DEV | IP6_TNL_F_MIP6_DEV |
-+ IP6_TNL_F_IGN_ENCAP_LIMIT);
-+
-+ ret = ip6ip6_kernel_tnl_add(&p);
-+ if (ret > 0) {
-+ DEBUG(DBG_INFO, "added tunnel from: "
-+ "%x:%x:%x:%x:%x:%x:%x:%x to: %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(local), NIPV6ADDR(remote));
-+ } else {
-+ DEBUG(DBG_WARNING, "unable to add tunnel from: "
-+ "%x:%x:%x:%x:%x:%x:%x:%x to: %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(local), NIPV6ADDR(remote));
-+ }
-+ return ret;
-+}
-+
-+static __inline__ int mipv6_tnl_del(struct in6_addr *remote,
-+ struct in6_addr *local)
-+{
-+ struct ip6_tnl *t = ip6ip6_tnl_lookup(remote, local);
-+
-+ DEBUG_FUNC();
-+
-+ if (t != NULL && (t->parms.flags & IP6_TNL_F_MIP6_DEV)) {
-+ DEBUG(DBG_INFO, "deleting tunnel from: "
-+ "%x:%x:%x:%x:%x:%x:%x:%x to: %x:%x:%x:%x:%x:%x:%x:%x",
-+ NIPV6ADDR(local), NIPV6ADDR(remote));
-+
-+ return ip6ip6_kernel_tnl_del(t);
-+ }
-+ return 0;
-+}
-+
-+static int add_route_to_mn(struct in6_addr *coa, struct in6_addr *ha_addr,
-+ struct in6_addr *home_addr)
-+{
-+ struct in6_rtmsg rtmsg;
-+ int err;
-+ struct ip6_tnl *t = ip6ip6_tnl_lookup(coa, ha_addr);
-+
-+ if (!is_mip6_tnl(t)) {
-+ DEBUG(DBG_CRITICAL,"Tunnel missing");
-+ return -ENODEV;
-+ }
-+
-+ DEBUG(DBG_INFO, "adding route to: %x:%x:%x:%x:%x:%x:%x:%x via "
-+ "tunnel device", NIPV6ADDR(home_addr));
-+
-+ memset(&rtmsg, 0, sizeof(rtmsg));
-+ ipv6_addr_copy(&rtmsg.rtmsg_dst, home_addr);
-+ rtmsg.rtmsg_dst_len = 128;
-+ rtmsg.rtmsg_type = RTMSG_NEWROUTE;
-+ rtmsg.rtmsg_flags = RTF_UP | RTF_NONEXTHOP | RTF_HOST | RTF_MOBILENODE;
-+ rtmsg.rtmsg_ifindex = t->dev->ifindex;
-+ rtmsg.rtmsg_metric = IP6_RT_PRIO_MIPV6;
-+ if ((err = ip6_route_add(&rtmsg, NULL)) == -EEXIST) {
-+ err = 0;
-+ }
-+ return err;
-+}
-+
-+static void del_route_to_mn(struct in6_addr *coa, struct in6_addr *ha_addr,
-+ struct in6_addr *home_addr)
-+{
-+ struct ip6_tnl *t = ip6ip6_tnl_lookup(coa, ha_addr);
-+
-+ DEBUG_FUNC();
-+
-+ if (is_mip6_tnl(t)) {
-+ struct in6_rtmsg rtmsg;
-+
-+ DEBUG(DBG_INFO, "deleting route to: %x:%x:%x:%x:%x:%x:%x:%x "
-+ " via tunnel device", NIPV6ADDR(home_addr));
-+
-+ memset(&rtmsg, 0, sizeof(rtmsg));
-+ ipv6_addr_copy(&rtmsg.rtmsg_dst, home_addr);
-+ rtmsg.rtmsg_dst_len = 128;
-+ rtmsg.rtmsg_ifindex = t->dev->ifindex;
-+ rtmsg.rtmsg_metric = IP6_RT_PRIO_MIPV6;
-+ ip6_route_del(&rtmsg, NULL);
-+ }
-+}
-+
-+
-+int mipv6_add_tnl_to_mn(struct in6_addr *coa,
-+ struct in6_addr *ha_addr,
-+ struct in6_addr *home_addr)
-+{
-+ int ret;
-+
-+ DEBUG_FUNC();
-+
-+ ret = mipv6_tnl_add(coa, ha_addr);
-+
-+ if (ret > 0) {
-+ int err = add_route_to_mn(coa, ha_addr, home_addr);
-+ if (err) {
-+ if (err != -ENODEV) {
-+ mipv6_tnl_del(coa, ha_addr);
-+ }
-+ return err;
-+ }
-+ }
-+ return ret;
-+}
-+
-+int mipv6_del_tnl_to_mn(struct in6_addr *coa,
-+ struct in6_addr *ha_addr,
-+ struct in6_addr *home_addr)
-+{
-+ DEBUG_FUNC();
-+ del_route_to_mn(coa, ha_addr, home_addr);
-+ return mipv6_tnl_del(coa, ha_addr);
-+}
-+
-+__init void mipv6_initialize_tunnel(void)
-+{
-+ down(&tnl_sem);
-+ ip6ip6_tnl_inc_max_kdev_count(mipv6_max_tnls);
-+ ip6ip6_tnl_inc_min_kdev_count(mipv6_min_tnls);
-+ up(&tnl_sem);
-+ mip6_fn.bce_tnl_rt_add = add_route_to_mn;
-+ mip6_fn.bce_tnl_rt_del = del_route_to_mn;
-+}
-+
-+__exit void mipv6_shutdown_tunnel(void)
-+{
-+ mip6_fn.bce_tnl_rt_del = NULL;
-+ mip6_fn.bce_tnl_rt_add = NULL;
-+ down(&tnl_sem);
-+ ip6ip6_tnl_dec_min_kdev_count(mipv6_min_tnls);
-+ ip6ip6_tnl_dec_max_kdev_count(mipv6_max_tnls);
-+ up(&tnl_sem);
-+}
-+
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/tunnel_ha.h linux-2.4.25/net/ipv6/mobile_ip6/tunnel_ha.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/tunnel_ha.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/tunnel_ha.h 2004-06-26 11:29:32.000000000 +0100
-@@ -0,0 +1,20 @@
-+#ifndef _TUNNEL_HA_H
-+#define _TUNNEL_HA_H
-+
-+#include "tunnel.h"
-+
-+extern int mipv6_max_tnls;
-+extern int mipv6_min_tnls;
-+
-+extern void mipv6_initialize_tunnel(void);
-+extern void mipv6_shutdown_tunnel(void);
-+
-+extern int mipv6_add_tnl_to_mn(struct in6_addr *coa,
-+ struct in6_addr *ha_addr,
-+ struct in6_addr *home_addr);
-+
-+extern int mipv6_del_tnl_to_mn(struct in6_addr *coa,
-+ struct in6_addr *ha_addr,
-+ struct in6_addr *home_addr);
-+
-+#endif
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/tunnel_mn.c linux-2.4.25/net/ipv6/mobile_ip6/tunnel_mn.c
---- linux-2.4.25.old/net/ipv6/mobile_ip6/tunnel_mn.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/tunnel_mn.c 2004-06-26 11:29:32.000000000 +0100
-@@ -0,0 +1,160 @@
-+/*
-+ * IPv6-IPv6 tunneling module
-+ *
-+ * Authors:
-+ * Sami Kivisaari <skivisaa@cc.hut.fi>
-+ * Ville Nuorvala <vnuorval@tml.hut.fi>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ *
-+ */
-+
-+#include <linux/net.h>
-+#include <linux/skbuff.h>
-+#include <linux/ipv6.h>
-+#include <linux/net.h>
-+#include <linux/netdevice.h>
-+#include <linux/init.h>
-+#include <linux/route.h>
-+#include <linux/ipv6_route.h>
-+
-+#ifdef CONFIG_SYSCTL
-+#include <linux/sysctl.h>
-+#endif /* CONFIG_SYSCTL */
-+
-+#include <net/protocol.h>
-+#include <net/ipv6.h>
-+#include <net/ip6_route.h>
-+#include <net/dst.h>
-+#include <net/addrconf.h>
-+
-+#include "tunnel.h"
-+#include "debug.h"
-+#include "stats.h"
-+
-+static struct net_device *mn_ha_tdev;
-+
-+static spinlock_t mn_ha_lock = SPIN_LOCK_UNLOCKED;
-+
-+static __inline__ int add_reverse_route(struct in6_addr *ha_addr,
-+ struct in6_addr *home_addr,
-+ struct net_device *tdev)
-+{
-+ struct in6_rtmsg rtmsg;
-+ int err;
-+
-+ DEBUG_FUNC();
-+
-+ memset(&rtmsg, 0, sizeof(rtmsg));
-+ rtmsg.rtmsg_type = RTMSG_NEWROUTE;
-+ ipv6_addr_copy(&rtmsg.rtmsg_src, home_addr);
-+ rtmsg.rtmsg_src_len = 128;
-+ rtmsg.rtmsg_flags = RTF_UP | RTF_DEFAULT;
-+ rtmsg.rtmsg_ifindex = tdev->ifindex;
-+ rtmsg.rtmsg_metric = IP6_RT_PRIO_MIPV6;
-+ if ((err = ip6_route_add(&rtmsg, NULL)) == -EEXIST) {
-+ return 0;
-+ }
-+ return err;
-+}
-+
-+static __inline__ void del_reverse_route(struct in6_addr *ha_addr,
-+ struct in6_addr *home_addr,
-+ struct net_device *tdev)
-+{
-+ struct in6_rtmsg rtmsg;
-+
-+ DEBUG(DBG_INFO, "removing reverse route via tunnel device");
-+
-+ memset(&rtmsg, 0, sizeof(rtmsg));
-+ ipv6_addr_copy(&rtmsg.rtmsg_src, home_addr);
-+ rtmsg.rtmsg_src_len = 128;
-+ rtmsg.rtmsg_ifindex = tdev->ifindex;
-+ rtmsg.rtmsg_metric = IP6_RT_PRIO_MIPV6;
-+ ip6_route_del(&rtmsg, NULL);
-+}
-+
-+int mipv6_add_tnl_to_ha(void)
-+{
-+ struct ip6_tnl_parm p;
-+ struct ip6_tnl *t;
-+ int err;
-+
-+ DEBUG_FUNC();
-+
-+ memset(&p, 0, sizeof(p));
-+ p.proto = IPPROTO_IPV6;
-+ p.hop_limit = 255;
-+ p.flags = (IP6_TNL_F_KERNEL_DEV | IP6_TNL_F_MIP6_DEV |
-+ IP6_TNL_F_IGN_ENCAP_LIMIT);
-+ strcpy(p.name, "mip6mnha1");
-+
-+ rtnl_lock();
-+ if ((err = ip6ip6_tnl_create(&p, &t))) {
-+ rtnl_unlock();
-+ return err;
-+ }
-+ spin_lock_bh(&mn_ha_lock);
-+
-+ if (!mn_ha_tdev) {
-+ mn_ha_tdev = t->dev;
-+ dev_hold(mn_ha_tdev);
-+ }
-+ spin_unlock_bh(&mn_ha_lock);
-+ dev_open(t->dev);
-+ rtnl_unlock();
-+ return 0;
-+}
-+
-+int mipv6_mv_tnl_to_ha(struct in6_addr *ha_addr,
-+ struct in6_addr *coa,
-+ struct in6_addr *home_addr)
-+{
-+ int err = -ENODEV;
-+
-+ DEBUG_FUNC();
-+
-+ spin_lock_bh(&mn_ha_lock);
-+ if (mn_ha_tdev) {
-+ struct ip6_tnl_parm p;
-+ memset(&p, 0, sizeof(p));
-+ p.proto = IPPROTO_IPV6;
-+ ipv6_addr_copy(&p.laddr, coa);
-+ ipv6_addr_copy(&p.raddr, ha_addr);
-+ p.hop_limit = 255;
-+ p.flags = (IP6_TNL_F_KERNEL_DEV | IP6_TNL_F_MIP6_DEV |
-+ IP6_TNL_F_IGN_ENCAP_LIMIT);
-+
-+ ip6ip6_tnl_change((struct ip6_tnl *) mn_ha_tdev->priv, &p);
-+ if (ipv6_addr_cmp(coa, home_addr)) {
-+ err = add_reverse_route(ha_addr, home_addr,
-+ mn_ha_tdev);
-+ } else {
-+ del_reverse_route(ha_addr, home_addr, mn_ha_tdev);
-+ err = 0;
-+ }
-+ }
-+ spin_unlock_bh(&mn_ha_lock);
-+ return err;
-+}
-+
-+void mipv6_del_tnl_to_ha(void)
-+{
-+ struct net_device *dev;
-+
-+ DEBUG_FUNC();
-+
-+ rtnl_lock();
-+ spin_lock_bh(&mn_ha_lock);
-+ dev = mn_ha_tdev;
-+ mn_ha_tdev = NULL;
-+ spin_unlock_bh(&mn_ha_lock);
-+ dev_put(dev);
-+ unregister_netdevice(dev);
-+ rtnl_unlock();
-+}
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/tunnel_mn.h linux-2.4.25/net/ipv6/mobile_ip6/tunnel_mn.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/tunnel_mn.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/tunnel_mn.h 2004-06-26 11:29:32.000000000 +0100
-@@ -0,0 +1,14 @@
-+#ifndef _TUNNEL_MN_H
-+#define _TUNNEL_MN_H
-+
-+#include "tunnel.h"
-+
-+extern int mipv6_add_tnl_to_ha(void);
-+
-+extern int mipv6_mv_tnl_to_ha(struct in6_addr *ha_addr,
-+ struct in6_addr *coa,
-+ struct in6_addr *home_addr);
-+
-+extern int mipv6_del_tnl_to_ha(void);
-+
-+#endif
-diff -uprN linux-2.4.25.old/net/ipv6/mobile_ip6/util.h linux-2.4.25/net/ipv6/mobile_ip6/util.h
---- linux-2.4.25.old/net/ipv6/mobile_ip6/util.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.25/net/ipv6/mobile_ip6/util.h 2004-06-26 11:29:32.000000000 +0100
-@@ -0,0 +1,91 @@
-+/*
-+ * MIPL Mobile IPv6 Utility functions
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef _UTIL_H
-+#define _UTIL_H
-+
-+#include <linux/in6.h>
-+#include <asm/byteorder.h>
-+
-+/**
-+ * mipv6_prefix_compare - Compare two IPv6 prefixes
-+ * @addr: IPv6 address
-+ * @prefix: IPv6 address
-+ * @nprefix: number of bits to compare
-+ *
-+ * Perform prefix comparison bitwise for the @nprefix first bits
-+ * Returns 1, if the prefixes are the same, 0 otherwise
-+ **/
-+static inline int mipv6_prefix_compare(const struct in6_addr *addr,
-+ const struct in6_addr *prefix,
-+ const unsigned int pfix_len)
-+{
-+ int i;
-+ unsigned int nprefix = pfix_len;
-+
-+ if (nprefix > 128)
-+ return 0;
-+
-+ for (i = 0; nprefix > 0; nprefix -= 32, i++) {
-+ if (nprefix >= 32) {
-+ if (addr->s6_addr32[i] != prefix->s6_addr32[i])
-+ return 0;
-+ } else {
-+ if (((addr->s6_addr32[i] ^ prefix->s6_addr32[i]) &
-+ ((~0) << (32 - nprefix))) != 0)
-+ return 0;
-+ return 1;
-+ }
-+ }
-+
-+ return 1;
-+}
-+
-+/**
-+ * homeagent_anycast - Compute Home Agent anycast address
-+ * @ac_addr: append home agent anycast suffix to passed prefix
-+ * @prefix: prefix ha anycast address is generated from
-+ * @plen: length of prefix in bits
-+ *
-+ * Calculate corresponding Home Agent Anycast Address (RFC2526) in a
-+ * given subnet.
-+ */
-+static inline int
-+mipv6_ha_anycast(struct in6_addr *ac_addr, struct in6_addr *prefix, int plen)
-+{
-+ if (plen <= 0 || plen > 120) {
-+ /* error, interface id should be minimum 8 bits */
-+ return -1;
-+ }
-+ ipv6_addr_copy(ac_addr, prefix);
-+
-+ if (plen < 32)
-+ ac_addr->s6_addr32[0] |= htonl((u32)(~0) >> plen);
-+ if (plen < 64)
-+ ac_addr->s6_addr32[1] |= htonl((u32)(~0) >> (plen > 32 ? plen % 32 : 0));
-+ if (plen < 92)
-+ ac_addr->s6_addr32[2] |= htonl((u32)(~0) >> (plen > 64 ? plen % 32 : 0));
-+ if (plen <= 120)
-+ ac_addr->s6_addr32[3] |= htonl((u32)(~0) >> (plen > 92 ? plen % 32 : 0));
-+
-+ /* RFC2526: for interface identifiers in EUI-64
-+ * format, the universal/local bit in the interface
-+ * identifier MUST be set to 0. */
-+ if (plen == 64) {
-+ ac_addr->s6_addr32[2] &= (int)htonl(0xfdffffff);
-+ }
-+ /* Mobile IPv6 Home-Agents anycast id (0x7e) */
-+ ac_addr->s6_addr32[3] &= (int)htonl(0xfffffffe);
-+
-+ return 0;
-+}
-+
-+#endif /* _UTIL_H */
-diff -uprN linux-2.4.25.old/net/ipv6/ndisc.c linux-2.4.25/net/ipv6/ndisc.c
---- linux-2.4.25.old/net/ipv6/ndisc.c 2003-11-28 18:26:21.000000000 +0000
-+++ linux-2.4.25/net/ipv6/ndisc.c 2004-06-26 11:29:32.000000000 +0100
-@@ -23,6 +23,7 @@
- * and moved to net/core.
- * Pekka Savola : RFC2461 validation
- * YOSHIFUJI Hideaki @USAGI : Verify ND options properly
-+ * Ville Nuorvala : RFC2461 fixes to proxy ND
- */
-
- /* Set to 3 to get tracing... */
-@@ -70,6 +71,7 @@
- #include <net/ip6_route.h>
- #include <net/addrconf.h>
- #include <net/icmp.h>
-+#include <net/mipglue.h>
-
- #include <net/checksum.h>
- #include <linux/proc_fs.h>
-@@ -187,6 +189,8 @@ struct ndisc_options *ndisc_parse_option
- case ND_OPT_TARGET_LL_ADDR:
- case ND_OPT_MTU:
- case ND_OPT_REDIRECT_HDR:
-+ case ND_OPT_RTR_ADV_INTERVAL:
-+ case ND_OPT_HOME_AGENT_INFO:
- if (ndopts->nd_opt_array[nd_opt->nd_opt_type]) {
- ND_PRINTK2((KERN_WARNING
- "ndisc_parse_options(): duplicated ND6 option found: type=%d\n",
-@@ -372,8 +376,8 @@ ndisc_build_ll_hdr(struct sk_buff *skb,
- */
-
- void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
-- struct in6_addr *daddr, struct in6_addr *solicited_addr,
-- int router, int solicited, int override, int inc_opt)
-+ struct in6_addr *daddr, struct in6_addr *solicited_addr,
-+ int router, int solicited, int override, int inc_opt)
- {
- static struct in6_addr tmpaddr;
- struct inet6_ifaddr *ifp;
-@@ -766,7 +770,8 @@ void ndisc_recv_ns(struct sk_buff *skb)
- int addr_type = ipv6_addr_type(saddr);
-
- if (in6_dev && in6_dev->cnf.forwarding &&
-- (addr_type & IPV6_ADDR_UNICAST) &&
-+ (addr_type & IPV6_ADDR_UNICAST ||
-+ addr_type == IPV6_ADDR_ANY) &&
- pneigh_lookup(&nd_tbl, &msg->target, dev, 0)) {
- int inc = ipv6_addr_type(daddr)&IPV6_ADDR_MULTICAST;
-
-@@ -778,13 +783,21 @@ void ndisc_recv_ns(struct sk_buff *skb)
- nd_tbl.stats.rcv_probes_mcast++;
- else
- nd_tbl.stats.rcv_probes_ucast++;
--
-- neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, dev);
-
-- if (neigh) {
-- ndisc_send_na(dev, neigh, saddr, &msg->target,
-- 0, 1, 0, 1);
-- neigh_release(neigh);
-+ if (addr_type & IPV6_ADDR_UNICAST) {
-+ neigh = neigh_event_ns(&nd_tbl, lladdr, saddr, dev);
-+
-+ if (neigh) {
-+ ndisc_send_na(dev, neigh, saddr, &msg->target,
-+ 0, 1, 0, 1);
-+ neigh_release(neigh);
-+ }
-+ } else {
-+ /* the proxy should also protect against DAD */
-+ struct in6_addr maddr;
-+ ipv6_addr_all_nodes(&maddr);
-+ ndisc_send_na(dev, NULL, &maddr, &msg->target,
-+ 0, 0, 0, 1);
- }
- } else {
- struct sk_buff *n = skb_clone(skb, GFP_ATOMIC);
-@@ -849,6 +862,9 @@ void ndisc_recv_na(struct sk_buff *skb)
- if (ifp->flags & IFA_F_TENTATIVE) {
- addrconf_dad_failure(ifp);
- return;
-+ } else if (ndisc_mip_mn_ha_probe(ifp, lladdr)) {
-+ in6_ifa_put(ifp);
-+ return;
- }
- /* What should we make now? The advertisement
- is invalid, but ndisc specs say nothing
-@@ -887,6 +903,7 @@ void ndisc_recv_na(struct sk_buff *skb)
- msg->icmph.icmp6_override, 1);
- neigh_release(neigh);
- }
-+ ndisc_check_mipv6_dad(&msg->target);
- }
-
- static void ndisc_router_discovery(struct sk_buff *skb)
-@@ -894,6 +911,7 @@ static void ndisc_router_discovery(struc
- struct ra_msg *ra_msg = (struct ra_msg *) skb->h.raw;
- struct neighbour *neigh;
- struct inet6_dev *in6_dev;
-+ int change_rtr;
- struct rt6_info *rt;
- int lifetime;
- struct ndisc_options ndopts;
-@@ -923,10 +941,6 @@ static void ndisc_router_discovery(struc
- ND_PRINTK1("RA: can't find in6 device\n");
- return;
- }
-- if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
-- in6_dev_put(in6_dev);
-- return;
-- }
-
- if (!ndisc_parse_options(opt, optlen, &ndopts)) {
- in6_dev_put(in6_dev);
-@@ -935,7 +949,12 @@ static void ndisc_router_discovery(struc
- "ICMP6 RA: invalid ND option, ignored.\n");
- return;
- }
-+ change_rtr = ndisc_mipv6_ra_rcv(skb, &ndopts);
-
-+ if (in6_dev->cnf.forwarding || !in6_dev->cnf.accept_ra) {
-+ in6_dev_put(in6_dev);
-+ return;
-+ }
- if (in6_dev->if_flags & IF_RS_SENT) {
- /*
- * flag that an RA was received after an RS was sent
-@@ -963,8 +982,7 @@ static void ndisc_router_discovery(struc
- ip6_del_rt(rt, NULL);
- rt = NULL;
- }
--
-- if (rt == NULL && lifetime) {
-+ if (rt == NULL && lifetime && change_rtr) {
- ND_PRINTK2("ndisc_rdisc: adding default router\n");
-
- rt = rt6_add_dflt_router(&skb->nh.ipv6h->saddr, skb->dev);
-@@ -1087,6 +1105,8 @@ out:
- if (rt)
- dst_release(&rt->u.dst);
- in6_dev_put(in6_dev);
-+
-+ ndisc_mipv6_change_router(change_rtr);
- }
-
- static void ndisc_redirect_rcv(struct sk_buff *skb)
-diff -uprN linux-2.4.25.old/net/ipv6/raw.c linux-2.4.25/net/ipv6/raw.c
---- linux-2.4.25.old/net/ipv6/raw.c 2003-11-28 18:26:21.000000000 +0000
-+++ linux-2.4.25/net/ipv6/raw.c 2004-06-26 11:29:32.000000000 +0100
-@@ -43,6 +43,7 @@
- #include <net/transp_v6.h>
- #include <net/udp.h>
- #include <net/inet_common.h>
-+#include <net/mipglue.h>
-
- #include <net/rawv6.h>
-
-@@ -636,6 +637,7 @@ static int rawv6_sendmsg(struct sock *sk
- hdr.daddr = daddr;
- else
- hdr.daddr = NULL;
-+ hdr.daddr = mipv6_get_fake_hdr_daddr(hdr.daddr, daddr);
-
- err = ip6_build_xmit(sk, rawv6_frag_cksum, &hdr, &fl, len,
- opt, hlimit, msg->msg_flags);
-diff -uprN linux-2.4.25.old/net/ipv6/route.c linux-2.4.25/net/ipv6/route.c
---- linux-2.4.25.old/net/ipv6/route.c 2004-02-18 13:36:32.000000000 +0000
-+++ linux-2.4.25/net/ipv6/route.c 2004-06-26 11:29:32.000000000 +0100
-@@ -49,6 +49,7 @@
- #include <net/addrconf.h>
- #include <net/tcp.h>
- #include <linux/rtnetlink.h>
-+#include <net/mipglue.h>
-
- #include <asm/uaccess.h>
-
-@@ -363,12 +364,8 @@ static struct rt6_info *rt6_cow(struct r
- rt->u.dst.flags |= DST_HOST;
-
- #ifdef CONFIG_IPV6_SUBTREES
-- if (rt->rt6i_src.plen && saddr) {
-- ipv6_addr_copy(&rt->rt6i_src.addr, saddr);
-- rt->rt6i_src.plen = 128;
-- }
-+ rt->rt6i_src.plen = ort->rt6i_src.plen;
- #endif
--
- rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway);
-
- dst_hold(&rt->u.dst);
-@@ -511,14 +508,19 @@ struct dst_entry * ip6_route_output(stru
- struct rt6_info *rt;
- int strict;
- int attempts = 3;
-+ struct in6_addr *saddr;
-
-+ if (ipv6_chk_addr(fl->nl_u.ip6_u.daddr, NULL))
-+ saddr = NULL;
-+ else
-+ saddr = fl->nl_u.ip6_u.saddr;
-+
- strict = ipv6_addr_type(fl->nl_u.ip6_u.daddr) & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL);
-
- relookup:
- read_lock_bh(&rt6_lock);
-
-- fn = fib6_lookup(&ip6_routing_table, fl->nl_u.ip6_u.daddr,
-- fl->nl_u.ip6_u.saddr);
-+ fn = fib6_lookup(&ip6_routing_table, fl->nl_u.ip6_u.daddr, saddr);
-
- restart:
- rt = fn->leaf;
-@@ -663,25 +665,6 @@ out:
- return (atomic_read(&ip6_dst_ops.entries) > ip6_rt_max_size);
- }
-
--/* Clean host part of a prefix. Not necessary in radix tree,
-- but results in cleaner routing tables.
--
-- Remove it only when all the things will work!
-- */
--
--static void ipv6_addr_prefix(struct in6_addr *pfx,
-- const struct in6_addr *addr, int plen)
--{
-- int b = plen&0x7;
-- int o = plen>>3;
--
-- memcpy(pfx->s6_addr, addr, o);
-- if (o < 16)
-- memset(pfx->s6_addr + o, 0, 16 - o);
-- if (b != 0)
-- pfx->s6_addr[o] = addr->s6_addr[o]&(0xff00 >> b);
--}
--
- static int ipv6_get_mtu(struct net_device *dev)
- {
- int mtu = IPV6_MIN_MTU;
-@@ -810,7 +793,7 @@ int ip6_route_add(struct in6_rtmsg *rtms
- if (!(gwa_type&IPV6_ADDR_UNICAST))
- goto out;
-
-- grt = rt6_lookup(gw_addr, NULL, rtmsg->rtmsg_ifindex, 1);
-+ grt = rt6_lookup(gw_addr, &rtmsg->rtmsg_src, rtmsg->rtmsg_ifindex, 1);
-
- err = -EHOSTUNREACH;
- if (grt == NULL)
-@@ -848,7 +831,15 @@ int ip6_route_add(struct in6_rtmsg *rtms
- goto out;
- }
- }
--
-+#ifdef USE_IPV6_MOBILITY
-+ /* If destination is mobile node, add special skb->dst->input
-+ * function for proxy ND.
-+ */
-+ if (rtmsg->rtmsg_flags & RTF_MOBILENODE) {
-+ rt->u.dst.input = ip6_mipv6_forward;
-+ }
-+#endif /* CONFIG_IPV6_MOBILITY */
-+
- if (ipv6_addr_is_multicast(&rt->rt6i_dst.addr))
- rt->rt6i_hoplimit = IPV6_DEFAULT_MCASTHOPS;
- else
-@@ -936,7 +927,7 @@ void rt6_redirect(struct in6_addr *dest,
- struct rt6_info *rt, *nrt;
-
- /* Locate old route to this destination. */
-- rt = rt6_lookup(dest, NULL, neigh->dev->ifindex, 1);
-+ rt = rt6_lookup(dest, saddr, neigh->dev->ifindex, 1);
-
- if (rt == NULL)
- return;
-@@ -1003,6 +994,9 @@ source_ok:
- nrt = ip6_rt_copy(rt);
- if (nrt == NULL)
- goto out;
-+#ifdef CONFIG_IPV6_SUBTREES
-+ nrt->rt6i_src.plen = rt->rt6i_src.plen;
-+#endif
-
- nrt->rt6i_flags = RTF_GATEWAY|RTF_UP|RTF_DYNAMIC|RTF_CACHE;
- if (on_link)
-@@ -1104,6 +1098,9 @@ void rt6_pmtu_discovery(struct in6_addr
- nrt = ip6_rt_copy(rt);
- if (nrt == NULL)
- goto out;
-+#ifdef CONFIG_IPV6_SUBTREES
-+ nrt->rt6i_src.plen = rt->rt6i_src.plen;
-+#endif
- ipv6_addr_copy(&nrt->rt6i_dst.addr, daddr);
- nrt->rt6i_dst.plen = 128;
- nrt->u.dst.flags |= DST_HOST;
-diff -uprN linux-2.4.25.old/net/ipv6/tcp_ipv6.c linux-2.4.25/net/ipv6/tcp_ipv6.c
---- linux-2.4.25.old/net/ipv6/tcp_ipv6.c 2003-11-28 18:26:21.000000000 +0000
-+++ linux-2.4.25/net/ipv6/tcp_ipv6.c 2004-06-26 11:29:32.000000000 +0100
-@@ -50,6 +50,7 @@
- #include <net/addrconf.h>
- #include <net/ip6_route.h>
- #include <net/inet_ecn.h>
-+#include <net/mipglue.h>
-
- #include <asm/uaccess.h>
-
-@@ -557,6 +558,7 @@ static int tcp_v6_connect(struct sock *s
- struct flowi fl;
- struct dst_entry *dst;
- int addr_type;
-+ int reroute = 0;
- int err;
-
- if (addr_len < SIN6_LEN_RFC2133)
-@@ -660,7 +662,7 @@ static int tcp_v6_connect(struct sock *s
-
- fl.proto = IPPROTO_TCP;
- fl.fl6_dst = &np->daddr;
-- fl.fl6_src = saddr;
-+ fl.fl6_src = saddr;
- fl.oif = sk->bound_dev_if;
- fl.uli_u.ports.dport = usin->sin6_port;
- fl.uli_u.ports.sport = sk->sport;
-@@ -669,31 +671,46 @@ static int tcp_v6_connect(struct sock *s
- struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
- fl.nl_u.ip6_u.daddr = rt0->addr;
- }
--
- dst = ip6_route_output(sk, &fl);
--
-+#ifdef CONFIG_IPV6_SUBTREES
-+ reroute = (saddr == NULL);
-+#endif
- if ((err = dst->error) != 0) {
- dst_release(dst);
- goto failure;
- }
--
-- ip6_dst_store(sk, dst, NULL);
-- sk->route_caps = dst->dev->features&~NETIF_F_IP_CSUM;
--
-+ if (!reroute) {
-+ ip6_dst_store(sk, dst, NULL, NULL);
-+ sk->route_caps = dst->dev->features&~NETIF_F_IP_CSUM;
-+ }
- if (saddr == NULL) {
- err = ipv6_get_saddr(dst, &np->daddr, &saddr_buf);
-+
-+ if (reroute)
-+ dst_release(dst);
- if (err)
- goto failure;
-
- saddr = &saddr_buf;
-+ ipv6_addr_copy(&np->rcv_saddr, saddr);
-+#ifdef CONFIG_IPV6_SUBTREES
-+ fl.fl6_src = saddr;
-+ dst = ip6_route_output(sk, &fl);
-+
-+ if ((err = dst->error) != 0) {
-+ dst_release(dst);
-+ goto failure;
-+ }
-+ ip6_dst_store(sk, dst, NULL, NULL);
-+ sk->route_caps = dst->dev->features&~NETIF_F_IP_CSUM;
-+#endif
- }
-
- /* set the source address */
-- ipv6_addr_copy(&np->rcv_saddr, saddr);
- ipv6_addr_copy(&np->saddr, saddr);
- sk->rcv_saddr= LOOPBACK4_IPV6;
-
-- tp->ext_header_len = 0;
-+ tp->ext_header_len = tcp_v6_get_mipv6_header_len();
- if (np->opt)
- tp->ext_header_len = np->opt->opt_flen+np->opt->opt_nflen;
- tp->mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
-@@ -1338,7 +1355,7 @@ static struct sock * tcp_v6_syn_recv_soc
- #endif
- MOD_INC_USE_COUNT;
-
-- ip6_dst_store(newsk, dst, NULL);
-+ ip6_dst_store(newsk, dst, NULL, NULL);
- sk->route_caps = dst->dev->features&~NETIF_F_IP_CSUM;
-
- newtp = &(newsk->tp_pinfo.af_tcp);
-@@ -1383,7 +1400,7 @@ static struct sock * tcp_v6_syn_recv_soc
- sock_kfree_s(sk, opt, opt->tot_len);
- }
-
-- newtp->ext_header_len = 0;
-+ newtp->ext_header_len = tcp_v6_get_mipv6_header_len();
- if (np->opt)
- newtp->ext_header_len = np->opt->opt_nflen + np->opt->opt_flen;
-
-@@ -1710,7 +1727,7 @@ static int tcp_v6_rebuild_header(struct
- return err;
- }
-
-- ip6_dst_store(sk, dst, NULL);
-+ ip6_dst_store(sk, dst, NULL, NULL);
- sk->route_caps = dst->dev->features&~NETIF_F_IP_CSUM;
- }
-
-@@ -1749,7 +1766,7 @@ static int tcp_v6_xmit(struct sk_buff *s
- return -sk->err_soft;
- }
-
-- ip6_dst_store(sk, dst, NULL);
-+ ip6_dst_store(sk, dst, NULL, NULL);
- }
-
- skb->dst = dst_clone(dst);
-diff -uprN linux-2.4.25.old/net/ipv6/udp.c linux-2.4.25/net/ipv6/udp.c
---- linux-2.4.25.old/net/ipv6/udp.c 2004-02-18 13:36:32.000000000 +0000
-+++ linux-2.4.25/net/ipv6/udp.c 2004-06-26 11:29:32.000000000 +0100
-@@ -48,6 +48,7 @@
- #include <net/ip.h>
- #include <net/udp.h>
- #include <net/inet_common.h>
-+#include <net/mipglue.h>
-
- #include <net/checksum.h>
-
-@@ -232,6 +233,7 @@ int udpv6_connect(struct sock *sk, struc
- struct ip6_flowlabel *flowlabel = NULL;
- int addr_type;
- int err;
-+ int reroute = 0;
-
- if (usin->sin6_family == AF_INET) {
- if (__ipv6_only_sock(sk))
-@@ -331,7 +333,7 @@ ipv4_connected:
-
- fl.proto = IPPROTO_UDP;
- fl.fl6_dst = &np->daddr;
-- fl.fl6_src = &saddr;
-+ fl.fl6_src = NULL;
- fl.oif = sk->bound_dev_if;
- fl.uli_u.ports.dport = sk->dport;
- fl.uli_u.ports.sport = sk->sport;
-@@ -348,29 +350,44 @@ ipv4_connected:
- struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
- fl.fl6_dst = rt0->addr;
- }
--
- dst = ip6_route_output(sk, &fl);
--
- if ((err = dst->error) != 0) {
- dst_release(dst);
- fl6_sock_release(flowlabel);
-- return err;
-- }
--
-- ip6_dst_store(sk, dst, fl.fl6_dst);
--
-+ return err;
-+ }
-+#ifdef CONFIG_IPV6_SUBTREES
-+ reroute = (fl.fl6_src == NULL);
-+#endif
- /* get the source adddress used in the apropriate device */
-
- err = ipv6_get_saddr(dst, daddr, &saddr);
-
-+ if (reroute)
-+ dst_release(dst);
-+
- if (err == 0) {
-- if(ipv6_addr_any(&np->saddr))
-+#ifdef CONFIG_IPV6_SUBTREES
-+ if (reroute) {
-+ fl.fl6_src = &saddr;
-+ dst = ip6_route_output(sk, &fl);
-+ if ((err = dst->error) != 0) {
-+ dst_release(dst);
-+ fl6_sock_release(flowlabel);
-+ return err;
-+ }
-+ }
-+#endif
-+ if(ipv6_addr_any(&np->saddr)) {
- ipv6_addr_copy(&np->saddr, &saddr);
--
-+ fl.fl6_src = &np->saddr;
-+ }
- if(ipv6_addr_any(&np->rcv_saddr)) {
- ipv6_addr_copy(&np->rcv_saddr, &saddr);
- sk->rcv_saddr = LOOPBACK4_IPV6;
- }
-+ ip6_dst_store(sk, dst, fl.fl6_dst,
-+ fl.fl6_src == &np->saddr ? fl.fl6_src : NULL);
- sk->state = TCP_ESTABLISHED;
- }
- fl6_sock_release(flowlabel);
-@@ -894,6 +911,7 @@ static int udpv6_sendmsg(struct sock *sk
- opt = fl6_merge_options(&opt_space, flowlabel, opt);
- if (opt && opt->srcrt)
- udh.daddr = daddr;
-+ udh.daddr = mipv6_get_fake_hdr_daddr(udh.daddr, daddr);
-
- udh.uh.source = sk->sport;
- udh.uh.len = len < 0x10000 ? htons(len) : 0;
-diff -uprN linux-2.4.25.old/net/netsyms.c linux-2.4.25/net/netsyms.c
---- linux-2.4.25.old/net/netsyms.c 2003-11-28 18:26:21.000000000 +0000
-+++ linux-2.4.25/net/netsyms.c 2004-06-26 11:29:32.000000000 +0100
-@@ -190,6 +190,7 @@ EXPORT_SYMBOL(neigh_sysctl_register);
- #endif
- EXPORT_SYMBOL(pneigh_lookup);
- EXPORT_SYMBOL(pneigh_enqueue);
-+EXPORT_SYMBOL(pneigh_delete);
- EXPORT_SYMBOL(neigh_destroy);
- EXPORT_SYMBOL(neigh_parms_alloc);
- EXPORT_SYMBOL(neigh_parms_release);
diff --git a/linux/gumstix-2.6.5-gnalm1-gum0/defconfig b/linux/gumstix-2.6.5-gnalm1-gum0/defconfig
deleted file mode 100644
index 64020e2cbe..0000000000
--- a/linux/gumstix-2.6.5-gnalm1-gum0/defconfig
+++ /dev/null
@@ -1,777 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_STANDALONE=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-
-#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
-# System Type
-#
-# CONFIG_ARCH_ADIFCC is not set
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-CONFIG_ARCH_PXA=y
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
-
-#
-# CLPS711X/EP721X Implementations
-#
-
-#
-# Epxa10db
-#
-
-#
-# Footbridge Implementations
-#
-
-#
-# IOP3xx Implementation Options
-#
-# CONFIG_ARCH_IOP310 is not set
-# CONFIG_ARCH_IOP321 is not set
-
-#
-# IOP3xx Chipset Features
-#
-
-#
-# Intel PXA250/210 Implementations
-#
-CONFIG_ARCH_GUMSTIK=y
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_ARCH_PXA_IDP is not set
-
-#
-# SA11x0 Implementations
-#
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_XSCALE=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
-
-#
-# Processor Features
-#
-# CONFIG_ARM_THUMB is not set
-CONFIG_XSCALE_PMU=y
-
-#
-# General setup
-#
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CPU_FREQ=y
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-CONFIG_FPE_FASTFPE=y
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=y
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Generic Driver Options
-#
-CONFIG_PM=y
-# CONFIG_PREEMPT is not set
-# CONFIG_APM is not set
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="root=/dev/ram0 console=tty0,115200n8"
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CONCAT=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-
-#
-# Mapping drivers for chip access
-#
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x00180000
-CONFIG_MTD_PHYSMAP_LEN=0x00280000
-CONFIG_MTD_PHYSMAP_BUSWIDTH=2
-CONFIG_MTD_GUMSTIK=y
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_EDB7312 is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-CONFIG_MTD_BLKMTD=y
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-CONFIG_BLK_DEV_NBD=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=36000
-CONFIG_BLK_DEV_INITRD=y
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-# CONFIG_PACKET is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_IPV6 is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-CONFIG_IPV6_SCTP__=y
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-CONFIG_PPP=y
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-# CONFIG_PPP_ASYNC is not set
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-# CONFIG_PPP_BSDCOMP is not set
-# CONFIG_PPPOE is not set
-CONFIG_SLIP=y
-# CONFIG_SLIP_COMPRESSED is not set
-# CONFIG_SLIP_SMART is not set
-# CONFIG_SLIP_MODE_SLIP6 is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# Bluetooth support
-#
-CONFIG_BT=y
-CONFIG_BT_L2CAP=y
-CONFIG_BT_SCO=y
-CONFIG_BT_RFCOMM=y
-CONFIG_BT_RFCOMM_TTY=y
-CONFIG_BT_BNEP=y
-# CONFIG_BT_BNEP_MC_FILTER is not set
-# CONFIG_BT_BNEP_PROTO_FILTER is not set
-
-#
-# Bluetooth device drivers
-#
-CONFIG_BT_HCIUART=y
-CONFIG_BT_HCIUART_H4=y
-# CONFIG_BT_HCIUART_BCSP is not set
-# CONFIG_BT_HCIVHCI is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-# CONFIG_INPUT_TSLIBDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_QIC02_TAPE is not set
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-CONFIG_SA1100_RTC=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# I2C support
-#
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-
-#
-# I2C Algorithms
-#
-CONFIG_I2C_ALGOBIT=y
-# CONFIG_I2C_ALGOPCF is not set
-CONFIG_I2C_ALGOPXA=y
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_ISA is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-CONFIG_I2C_PXA2XX=y
-# CONFIG_SCx200_ACB is not set
-
-#
-# Hardware Sensors Chip support
-#
-# CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-
-#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# MMC/SD Card support
-#
-CONFIG_MMC=y
-# CONFIG_MMC_DEBUG is not set
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_PXA=y
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-# CONFIG_EXT2_FS_POSIX_ACL is not set
-# CONFIG_EXT2_FS_SECURITY is not set
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-# CONFIG_DEVPTS_FS_SECURITY is not set
-CONFIG_TMPFS=y
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-CONFIG_CRAMFS=y
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-CONFIG_LDM_PARTITION=y
-# CONFIG_LDM_DEBUG is not set
-# CONFIG_NEC98_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-
-#
-# Native Language Support
-#
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_MDA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Misc devices
-#
-
-#
-# Multimedia Capabilities Port drivers
-#
-# CONFIG_MCP is not set
-
-#
-# Console Switches
-#
-# CONFIG_SWITCHES is not set
-
-#
-# USB support
-#
-
-#
-# USB Gadget Support
-#
-CONFIG_USB_GADGET=y
-# CONFIG_USB_GADGET_NET2280 is not set
-CONFIG_USB_GADGET_PXA2XX=y
-CONFIG_USB_PXA2XX=y
-CONFIG_USB_PXA2XX_SMALL=y
-# CONFIG_USB_GADGET_GOKU is not set
-# CONFIG_USB_GADGET_SA1100 is not set
-# CONFIG_USB_GADGET_DUALSPEED is not set
-# CONFIG_USB_ZERO is not set
-CONFIG_USB_ETH=y
-# CONFIG_USB_GADGETFS is not set
-# CONFIG_USB_FILE_STORAGE is not set
-# CONFIG_USB_G_SERIAL is not set
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_KERNEL is not set
-
-#
-# Security options
-#
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Library routines
-#
-CONFIG_CRC32=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/gumstix-2.6.5-gnalm1-gum0/linux-2.6.5-gnalm1.patch b/linux/gumstix-2.6.5-gnalm1-gum0/linux-2.6.5-gnalm1.patch
deleted file mode 100644
index e8ed5c9d44..0000000000
--- a/linux/gumstix-2.6.5-gnalm1-gum0/linux-2.6.5-gnalm1.patch
+++ /dev/null
@@ -1,20991 +0,0 @@
---- linux-2.6.5/kernel/printk.c~heh 2004-04-03 22:38:24.000000000 -0500
-+++ linux-2.6.5/kernel/printk.c 2004-04-30 20:57:36.000000000 -0400
-@@ -832,3 +832,25 @@
- printk_ratelimit_burst);
- }
- EXPORT_SYMBOL(printk_ratelimit);
-+
-+#include <linux/sysrq.h>
-+
-+static void
-+show_msg_info(int key, struct pt_regs *regs, struct tty_struct *tty)
-+{
-+ call_console_drivers(log_end - logged_chars, log_end);
-+}
-+
-+static struct sysrq_key_op msg_info_op = {
-+ .handler = show_msg_info,
-+ .help_msg = "Dumpmsgs",
-+ .action_msg = "Kernel Messages",
-+};
-+
-+static int __init dbg_init(void)
-+{
-+ register_sysrq_key('d', &msg_info_op);
-+ return 0;
-+}
-+
-+__initcall(dbg_init);
---- linux-2.6.5/kernel/resource.c~heh 2004-04-03 22:37:36.000000000 -0500
-+++ linux-2.6.5/kernel/resource.c 2004-04-30 20:57:36.000000000 -0400
-@@ -179,6 +179,8 @@
- {
- struct resource *tmp, **p;
-
-+ BUG_ON(old->child);
-+
- p = &old->parent->child;
- for (;;) {
- tmp = *p;
-@@ -409,6 +411,47 @@
- EXPORT_SYMBOL(adjust_resource);
-
- /*
-+ * Given an existing resource, change its start and size to match the
-+ * arguments. Returns -EBUSY if it can't fit. Existing children of
-+ * the resource are assumed to be immutable.
-+ */
-+int reallocate_resource(struct resource *res, unsigned long start, unsigned long size)
-+{
-+ struct resource *tmp, *parent = res->parent;
-+ unsigned long end = start + size - 1;
-+ int result = -EBUSY;
-+
-+ write_lock(&resource_lock);
-+
-+ if ((start < parent->start) || (end > parent->end))
-+ goto out;
-+
-+ for (tmp = res->child; tmp; tmp = tmp->sibling) {
-+ if ((tmp->start < start) || (tmp->end > end))
-+ goto out;
-+ }
-+
-+ if (res->sibling && (res->sibling->start <= end))
-+ goto out;
-+
-+ tmp = parent->child;
-+ if (tmp != res) {
-+ while (tmp->sibling != res)
-+ tmp = tmp->sibling;
-+ if (start <= tmp->end)
-+ goto out;
-+ }
-+
-+ res->start = start;
-+ res->end = end;
-+ result = 0;
-+
-+ out:
-+ write_unlock(&resource_lock);
-+ return result;
-+}
-+
-+/*
- * This is compatibility stuff for IO resources.
- *
- * Note how this, unlike the above, knows about
---- linux-2.6.5/include/asm-arm/mach/irq.h~heh 2004-04-03 22:36:54.000000000 -0500
-+++ linux-2.6.5/include/asm-arm/mach/irq.h 2004-04-30 20:57:36.000000000 -0400
-@@ -14,6 +14,19 @@
- struct pt_regs;
- struct seq_file;
-
-+/*
-+ * Architectures are expected to define NR_IRQ_DEVICES and
-+ * NR_IRQ_DEVICE_SHIFT if they wish to use dynamic IRQs.
-+ */
-+#ifndef NR_IRQ_DEVICES
-+#define NR_IRQ_DEVICES 1
-+#endif
-+#define NR_IRQ_PER_DEVICE (1 << (NR_IRQ_DEVICE_SHIFT - 1))
-+
-+#define IRQ_DEVICE(i) ((i) >> NR_IRQ_DEVICE_SHIFT)
-+#define IRQ_INDEX(i) ((i) & (NR_IRQ_PER_GROUP - 1))
-+#define TO_IRQ(g,i) (((g) << NR_IRQ_DEVICE_SHIFT) + (i))
-+
- typedef void (*irq_handler_t)(unsigned int, struct irqdesc *, struct pt_regs *);
- typedef void (*irq_control_t)(unsigned int);
-
---- linux-2.6.5/include/asm-arm/arch-pxa/uncompress.h~heh 2004-04-03 22:36:17.000000000 -0500
-+++ linux-2.6.5/include/asm-arm/arch-pxa/uncompress.h 2004-04-30 20:57:36.000000000 -0400
-@@ -12,6 +12,7 @@
- #define FFUART ((volatile unsigned long *)0x40100000)
- #define BTUART ((volatile unsigned long *)0x40200000)
- #define STUART ((volatile unsigned long *)0x40700000)
-+#define HWUART ((volatile unsigned long *)0x41600000)
-
- #define UART FFUART
-
---- linux-2.6.5/include/asm-arm/arch-pxa/dma.h~heh 2004-04-03 22:38:18.000000000 -0500
-+++ linux-2.6.5/include/asm-arm/arch-pxa/dma.h 2004-04-30 20:57:36.000000000 -0400
-@@ -22,11 +22,11 @@
- * Note: this structure must always be aligned to a 16-byte boundary.
- */
-
--typedef struct {
-- volatile u32 ddadr; /* Points to the next descriptor + flags */
-- volatile u32 dsadr; /* DSADR value for the current transfer */
-- volatile u32 dtadr; /* DTADR value for the current transfer */
-- volatile u32 dcmd; /* DCMD value for the current transfer */
-+typedef struct pxa_dma_desc {
-+ u32 ddadr; /* Points to the next descriptor + flags */
-+ u32 dsadr; /* DSADR value for the current transfer */
-+ u32 dtadr; /* DTADR value for the current transfer */
-+ u32 dcmd; /* DCMD value for the current transfer */
- } pxa_dma_desc;
-
- /*
---- linux-2.6.5/include/asm-arm/arch-pxa/serial.h~heh 2004-04-03 22:37:06.000000000 -0500
-+++ linux-2.6.5/include/asm-arm/arch-pxa/serial.h 2004-04-30 20:57:36.000000000 -0400
-@@ -43,6 +43,15 @@
- io_type: SERIAL_IO_MEM, \
- irq: IRQ_BTUART, \
- flags: STD_COM_FLAGS, \
-+ }, { \
-+ type: PORT_PXA, \
-+ xmit_fifo_size: 64, \
-+ baud_base: BAUD_BASE, \
-+ iomem_base: &HWUART, \
-+ iomem_reg_shift: 2, \
-+ io_type: SERIAL_IO_MEM, \
-+ irq: IRQ_HWUART, \
-+ flags: STD_COM_FLAGS, \
- }
-
- #define EXTRA_SERIAL_PORT_DEFNS
---- linux-2.6.5/include/asm-arm/arch-pxa/pxa-regs.h~heh 2004-04-03 22:37:36.000000000 -0500
-+++ linux-2.6.5/include/asm-arm/arch-pxa/pxa-regs.h 2004-04-30 20:57:36.000000000 -0400
-@@ -124,26 +124,26 @@
- #define DRCMR12 __REG(0x40000130) /* Request to Channel Map Register for AC97 audio transmit Request */
- #define DRCMR13 __REG(0x40000134) /* Request to Channel Map Register for SSP receive Request */
- #define DRCMR14 __REG(0x40000138) /* Request to Channel Map Register for SSP transmit Request */
--#define DRCMR15 __REG(0x4000013c) /* Reserved */
--#define DRCMR16 __REG(0x40000140) /* Reserved */
-+#define DRCMR15 __REG(0x4000013c) /* Request to Channel Map Register for NSSP receive Request */
-+#define DRCMR16 __REG(0x40000140) /* Request to Channel Map Register for NSSP transmit Request */
- #define DRCMR17 __REG(0x40000144) /* Request to Channel Map Register for ICP receive Request */
- #define DRCMR18 __REG(0x40000148) /* Request to Channel Map Register for ICP transmit Request */
- #define DRCMR19 __REG(0x4000014c) /* Request to Channel Map Register for STUART receive Request */
- #define DRCMR20 __REG(0x40000150) /* Request to Channel Map Register for STUART transmit Request */
- #define DRCMR21 __REG(0x40000154) /* Request to Channel Map Register for MMC receive Request */
- #define DRCMR22 __REG(0x40000158) /* Request to Channel Map Register for MMC transmit Request */
--#define DRCMR23 __REG(0x4000015c) /* Reserved */
--#define DRCMR24 __REG(0x40000160) /* Reserved */
-+#define DRCMR23 __REG(0x4000015c) /* Request to Channel Map Register for ASSP receive Request */
-+#define DRCMR24 __REG(0x40000160) /* Request to Channel Map Register for ASSP transmit Request */
- #define DRCMR25 __REG(0x40000164) /* Request to Channel Map Register for USB endpoint 1 Request */
- #define DRCMR26 __REG(0x40000168) /* Request to Channel Map Register for USB endpoint 2 Request */
- #define DRCMR27 __REG(0x4000016C) /* Request to Channel Map Register for USB endpoint 3 Request */
- #define DRCMR28 __REG(0x40000170) /* Request to Channel Map Register for USB endpoint 4 Request */
--#define DRCMR29 __REG(0x40000174) /* Reserved */
-+#define DRCMR29 __REG(0x40000174) /* Request to Channel Map Register for HWUART receive Request */
- #define DRCMR30 __REG(0x40000178) /* Request to Channel Map Register for USB endpoint 6 Request */
- #define DRCMR31 __REG(0x4000017C) /* Request to Channel Map Register for USB endpoint 7 Request */
- #define DRCMR32 __REG(0x40000180) /* Request to Channel Map Register for USB endpoint 8 Request */
- #define DRCMR33 __REG(0x40000184) /* Request to Channel Map Register for USB endpoint 9 Request */
--#define DRCMR34 __REG(0x40000188) /* Reserved */
-+#define DRCMR34 __REG(0x40000188) /* Request to Channel Map Register for HWUART transmit Request */
- #define DRCMR35 __REG(0x4000018C) /* Request to Channel Map Register for USB endpoint 11 Request */
- #define DRCMR36 __REG(0x40000190) /* Request to Channel Map Register for USB endpoint 12 Request */
- #define DRCMR37 __REG(0x40000194) /* Request to Channel Map Register for USB endpoint 13 Request */
-@@ -163,12 +163,16 @@
- #define DRCMRTXPCDR DRCMR12
- #define DRCMRRXSSDR DRCMR13
- #define DRCMRTXSSDR DRCMR14
-+#define DRCMRRXNSSPDR DRCMR15
-+#define DRCMRTXNSSPDR DRCMR16
- #define DRCMRRXICDR DRCMR17
- #define DRCMRTXICDR DRCMR18
- #define DRCMRRXSTRBR DRCMR19
- #define DRCMRTXSTTHR DRCMR20
- #define DRCMRRXMMC DRCMR21
- #define DRCMRTXMMC DRCMR22
-+#define DRCMRRXASSPDR DRCMR23
-+#define DRCMRTXASSPDR DRCMR24
-
- #define DRCMR_MAPVLD (1 << 7) /* Map Valid (read / write) */
- #define DRCMR_CHLNUM 0x0f /* mask for Channel Number (read / write) */
-@@ -303,6 +307,22 @@
- #define BTDLL __REG(0x40200000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
- #define BTDLH __REG(0x40200004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
-
-+/* Hardware UART (HWUART) */
-+#define HWUART HWRBR
-+#define HWRBR __REG(0x41600000) /* Receive Buffer Register (read only) */
-+#define HWTHR __REG(0x41600000) /* Transmit Holding Register (write only) */
-+#define HWIER __REG(0x41600004) /* Interrupt Enable Register (read/write) */
-+#define HWIIR __REG(0x41600008) /* Interrupt ID Register (read only) */
-+#define HWFCR __REG(0x41600008) /* FIFO Control Register (write only) */
-+#define HWLCR __REG(0x4160000C) /* Line Control Register (read/write) */
-+#define HWMCR __REG(0x41600010) /* Modem Control Register (read/write) */
-+#define HWLSR __REG(0x41600014) /* Line Status Register (read only) */
-+#define HWMSR __REG(0x41600018) /* Reserved */
-+#define HWSPR __REG(0x4160001C) /* Scratch Pad Register (read/write) */
-+#define HWISR __REG(0x41600020) /* Infrared Selection Register (read/write) */
-+#define HWDLL __REG(0x41600000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
-+#define HWDLH __REG(0x41600004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
-+
- /* Standard UART (STUART) */
- #define STUART STRBR
- #define STRBR __REG(0x40700000) /* Receive Buffer Register (read only) */
-@@ -1078,6 +1098,111 @@
-
-
- /*
-+ * NSSP Serial Port Registers (Network SSP)
-+ */
-+
-+#define NSSCR0 __REG(0x41400000) /* NSSP Control Register 0 */
-+#define NSSCR1 __REG(0x41400004) /* NSSP Control Register 1 */
-+#define NSSSR __REG(0x41400008) /* NSSP Status Register */
-+#define NSSITR __REG(0x4140000C) /* NSSP Interrupt Test Register */
-+#define NSSDR __REG(0x41400010) /* (Write / Read) NSSP Data Write Register/NSSP Data Read Register */
-+#define NSSTO __REG(0x41400028) /* NSSP Time Out Register */
-+#define NSSPSP __REG(0x4140002C) /* NSSP Programable Serial Port Register*/
-+
-+
-+/*
-+ * ASSP Serial Port Registers (Audio SSP)
-+ */
-+
-+#define ASSCR0 __REG(0x41500000) /* ASSP Control Register 0 */
-+#define ASSCR1 __REG(0x41500004) /* ASSP Control Register 1 */
-+#define ASSSR __REG(0x41500008) /* ASSP Status Register */
-+#define ASSITR __REG(0x4150000C) /* ASSP Interrupt Test Register */
-+#define ASSDR __REG(0x41500010) /* (Write / Read) ASSP Data Write Register/ASSP Data Read Register */
-+#define ASSTO __REG(0x41500028) /* ASSP Time Out Register */
-+#define ASSPSP __REG(0x4150002C) /* ASSP Programable Serial Port Register*/
-+
-+
-+/*
-+ * Bit definitions for SSP, NSSP and ASSP registers
-+ * - note that some bits are only available on the NSSP and ASSP
-+ */
-+
-+#define SSCR0_EDSS (1 << 20) /* ext. data size select */
-+#define SSCR0_SCR_MASK 0x000fff00 /* [19:8] secrial clock rate */
-+#define SSCR0_SCR(x) (((x)<<8) & XSSCR0_SCR_MASK)
-+#define SSCR0_SSE (1 << 7) /* sync ser port enable */
-+#define SSCR0_FRF_MASK 0x00000030 /* [5:4] frame format */
-+#define SSCR0_FRF(x) (((x)<<4) & XSSCR0_FRF_MASK)
-+#define SSCR0_FRF_SPI 0x00000000 /* ser peripheral i/f */
-+#define SSCR0_FRF_TISSP 0x00000010 /* TI sync ser port */
-+#define SSCR0_FRF_MICROWAVE 0x00000020 /* microwire */
-+#define SSCR0_FRF_PSP 0x00000030 /* prog ser protocol */
-+#define SSCR0_DSS_MASK 0x0000000f /* data size select */
-+#define SSCR0_DSS(x) ((x) & XSSCR0_DSS_MASK)
-+
-+#define SSCR1_TTELP (1 << 31) /* tx hi-z later phase */
-+#define SSCR1_TTE (1 << 30) /* tx hi-z enable */
-+#define SSCR1_EBCEI (1 << 29) /* bit count error int mask */
-+#define SSCR1_SCFR (1 << 28) /* slave clock free running */
-+#define SSCR1_SCLKDIR (1 << 25) /* ssp clock direction */
-+#define SSCR1_SFRMDIR (1 << 24) /* ssp frame direction */
-+#define SSCR1_RWOT (1 << 23) /* rx without transmit */
-+#define SSCR1_TSRE (1 << 21) /* tx req enable */
-+#define SSCR1_RSRE (1 << 20) /* rx req enable */
-+#define SSCR1_TINTE (1 << 19) /* timeout int enable */
-+#define SSCR1_STRF (1 << 15) /* select fifo for efwr */
-+#define SSCR1_EFWR (1 << 14) /* fifo write/read enable */
-+#define SSCR1_RFT_MASK 0x00003c00 /* [13:10] rx fifo threshold */
-+#define SSCR1_RFT(x) (((x)<<10) & XSSCR1_RFT_MASK)
-+#define SSCR1_TFT_MASK 0x000003c0 /* [9:6] tx fifo threshold */
-+#define SSCR1_TFT(x) (((x)<<6) & XSSCR1_TFT_MASK)
-+#define SSCR1_MWDS (1 << 5) /* microwire tx data size */
-+#define SSCR1_SPH (1 << 4) /* SPI SSPSCLK phase */
-+#define SSCR1_SPO (1 << 3) /* motorolla SPI polarity */
-+#define SSCR1_LBM (1 << 2) /* loop-back mode */
-+#define SSCR1_TIE (1 << 1) /* tx fifo int enable */
-+#define SSCR1_RIE (1 << 0) /* rx fifo int enable */
-+
-+#define SSPSP_DMYSTOP_MASK 0x01800000 /* [24:23] dummy stop */
-+#define SSPSP_DMYSTOP(x) (((x)<<23) & XSSPSP_DMYSTOP_MASK)
-+#define SSPSP_SFRMWDTH_MASK 0x007f0000 /* [22:16] serial frame width */
-+#define SSPSP_SFRMWDTH(x) (((x)<<16) & XSSPSP_SFRMWDTH_MASK)
-+#define SSPSP_SFRMDLY_MASK 0x0000fe00 /* [15:9] serial frame delay */
-+#define SSPSP_SFRMDLY(x) (((x)<<9) & XSSPSP_SFRMDLY_MASK)
-+#define SSPSP_DMYSTRT_MASK 0x00000180 /* [8:7] dummy start */
-+#define SSPSP_DMYSTRT(x) (((x)<<7) & XSSPSP_DMYSTRT_MASK)
-+#define SSPSP_STRTDLY_MASK 0x00000070 /* [6:4] three-bit start delay */
-+#define SSPSP_STRTDLY(x) (((x)<<4) & XSSPSP_STRTDLY_MASK)
-+#define SSPSP_ETDS (1 << 3) /* end of tx data state */
-+#define SSPSP_SFRMP (1 << 2) /* serial frame polarity */
-+#define SSPSP_SCMODE_MASK 0x00000003 /* bit-rate clock mode */
-+#define SSPSP_SCMODE(x) ((x) & XSSPSP_SCMODE_MASK)
-+
-+#define SSTO_TIMEOUT_MASK 0x00ffffff /* [23:0] timeout */
-+#define SSTO_TIMEOUT(x) ((x) & XSSTO_TIMEOUT_MASK)
-+
-+#define SSITR_TROR (1 << 7) /* test rx fifo overrun */
-+#define SSITR_TRFS (1 << 6) /* test rx fifo serv req */
-+#define SSITR_TTFS (1 << 5) /* test tx fifo serv req */
-+
-+#define SSSR_BCE (1 << 23) /* bit count error */
-+#define SSSR_CSS (1 << 22) /* clock sync stat */
-+#define SSSR_TUR (1 << 21) /* tx fifo underrun */
-+#define SSSR_TINT (1 << 19) /* rx timeout int */
-+#define SSSR_RFL_MASK 0x0000f000 /* rx fifo level */
-+#define SSSR_RFL(x) (((x)<<16) & XSSSR_RFL_MASK)
-+#define SSSR_TFL_MASK 0x00000f00 /* tx fifo level */
-+#define SSSR_TFL(x) (((x)<<8) & XSSSR_TFL_MASK)
-+#define SSSR_ROR (1 << 7) /* rx fifo overrun */
-+#define SSSR_RFS (1 << 6) /* rx fifo serv request */
-+#define SSSR_TFS (1 << 5) /* tx fifo serv req */
-+#define SSSR_BSY (1 << 4) /* SSP busy */
-+#define SSSR_RNE (1 << 3) /* rx fifo not empty */
-+#define SSSR_TNF (1 << 2) /* tx fifo not full */
-+
-+
-+/*
- * MultiMediaCard (MMC) controller
- */
-
-@@ -1122,6 +1247,7 @@
- #define CKEN7_BTUART (1 << 7) /* BTUART Unit Clock Enable */
- #define CKEN6_FFUART (1 << 6) /* FFUART Unit Clock Enable */
- #define CKEN5_STUART (1 << 5) /* STUART Unit Clock Enable */
-+#define CKEN4_HWUART (1 << 4) /* HWUART Unit Clock Enable */
- #define CKEN3_SSP (1 << 3) /* SSP Unit Clock Enable */
- #define CKEN2_AC97 (1 << 2) /* AC97 Unit Clock Enable */
- #define CKEN1_PWM1 (1 << 1) /* PWM1 Clock Enable */
---- linux-2.6.5/include/asm-arm/page.h~heh 2004-04-03 22:36:25.000000000 -0500
-+++ linux-2.6.5/include/asm-arm/page.h 2004-04-30 20:57:36.000000000 -0400
-@@ -92,6 +92,14 @@
- # endif
- #endif
-
-+#ifdef CONFIG_CPU_COPY_V6
-+# ifdef _USER
-+# define MULTI_USER 1
-+# else
-+# define _USER v6
-+# endif
-+#endif
-+
- #ifndef _USER
- #error Unknown user operations model
- #endif
---- linux-2.6.5/include/asm-arm/thread_info.h~heh 2004-04-03 22:37:06.000000000 -0500
-+++ linux-2.6.5/include/asm-arm/thread_info.h 2004-04-30 20:57:36.000000000 -0400
-@@ -108,8 +108,8 @@
- #define TI_CPU 20
- #define TI_CPU_DOMAIN 24
- #define TI_CPU_SAVE 28
--#define TI_USED_MATH 76
--#define TI_FPSTATE (TI_USED_MATH+16)
-+#define TI_USED_CP 76
-+#define TI_FPSTATE (TI_USED_CP+16)
-
- #endif
-
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/include/asm-arm/rtc.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,45 @@
-+/*
-+ * linux/include/asm-arm/rtc.h
-+ *
-+ * Copyright (C) 2003 Deep Blue Solutions Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#ifndef ASMARM_RTC_H
-+#define ASMARM_RTC_H
-+
-+struct module;
-+
-+struct rtc_ops {
-+ struct module *owner;
-+ int (*open)(void);
-+ void (*release)(void);
-+ int (*ioctl)(unsigned int, unsigned long);
-+
-+ void (*read_time)(struct rtc_time *);
-+ int (*set_time)(struct rtc_time *);
-+ void (*read_alarm)(struct rtc_wkalrm *);
-+ int (*set_alarm)(struct rtc_wkalrm *);
-+ int (*proc)(char *buf);
-+};
-+
-+void rtc_time_to_tm(unsigned long, struct rtc_time *);
-+int rtc_tm_to_time(struct rtc_time *, unsigned long *);
-+void rtc_next_alarm_time(struct rtc_time *, struct rtc_time *, struct rtc_time *);
-+void rtc_update(unsigned long, unsigned long);
-+int register_rtc(struct rtc_ops *);
-+void unregister_rtc(struct rtc_ops *);
-+
-+static inline int rtc_periodic_alarm(struct rtc_time *tm)
-+{
-+ return (tm->tm_year == -1) ||
-+ ((unsigned)tm->tm_mon >= 12) ||
-+ ((unsigned)(tm->tm_mday - 1) >= 31) ||
-+ ((unsigned)tm->tm_hour > 23) ||
-+ ((unsigned)tm->tm_min > 59) ||
-+ ((unsigned)tm->tm_sec > 59);
-+}
-+
-+#endif
---- linux-2.6.5/include/linux/serial.h~heh 2004-04-03 22:36:26.000000000 -0500
-+++ linux-2.6.5/include/linux/serial.h 2004-04-30 20:57:36.000000000 -0400
-@@ -81,17 +81,6 @@
- #define SERIAL_IO_HUB6 1
- #define SERIAL_IO_MEM 2
-
--struct serial_uart_config {
-- char *name;
-- int dfl_xmit_fifo_size;
-- int flags;
--};
--
--#define UART_CLEAR_FIFO 0x01
--#define UART_USE_FIFO 0x02
--#define UART_STARTECH 0x04
--#define UART_NATSEMI 0x08
--
- /*
- * Definitions for async_struct (and serial_struct) flags field
- */
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/include/linux/i2c-pxa.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,76 @@
-+/*
-+ * i2c_pxa.h
-+ *
-+ * Copyright (C) 2002 Intrinsyc Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ */
-+#ifndef _I2C_PXA_H_
-+#define _I2C_PXA_H_
-+
-+struct i2c_algo_pxa_data
-+{
-+ void (*write_byte) (u8 value);
-+ u8 (*read_byte) (void);
-+ void (*start) (void);
-+ void (*repeat_start) (void);
-+ void (*stop) (void);
-+ void (*abort) (void);
-+ int (*wait_bus_not_busy) (void);
-+ int (*wait_for_interrupt) (int wait_type);
-+ void (*transfer) (int lastbyte, int receive, int midbyte);
-+ void (*reset) (void);
-+
-+ int udelay;
-+ int timeout;
-+};
-+
-+#define DEF_TIMEOUT 3
-+#define BUS_ERROR (-EREMOTEIO)
-+#define ACK_DELAY 0 /* time to delay before checking bus error */
-+#define MAX_MESSAGES 65536 /* maximum number of messages to send */
-+
-+#define I2C_SLEEP_TIMEOUT 2 /* time to sleep for on i2c transactions */
-+#define I2C_RETRY (-2000) /* an error has occurred retry transmit */
-+#define I2C_TRANSMIT 1
-+#define I2C_RECEIVE 0
-+#define I2C_PXA_SLAVE_ADDR 0x1 /* slave pxa unit address */
-+#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) /* ICR initialization value */
-+/* ICR initialize bit values
-+*
-+* 15. FM 0 (100 Khz operation)
-+* 14. UR 0 (No unit reset)
-+* 13. SADIE 0 (Disables the unit from interrupting on slave addresses
-+* matching its slave address)
-+* 12. ALDIE 0 (Disables the unit from interrupt when it loses arbitration
-+* in master mode)
-+* 11. SSDIE 0 (Disables interrupts from a slave stop detected, in slave mode)
-+* 10. BEIE 1 (Enable interrupts from detected bus errors, no ACK sent)
-+* 9. IRFIE 1 (Enable interrupts from full buffer received)
-+* 8. ITEIE 1 (Enables the I2C unit to interrupt when transmit buffer empty)
-+* 7. GCD 1 (Disables i2c unit response to general call messages as a slave)
-+* 6. IUE 0 (Disable unit until we change settings)
-+* 5. SCLE 1 (Enables the i2c clock output for master mode (drives SCL)
-+* 4. MA 0 (Only send stop with the ICR stop bit)
-+* 3. TB 0 (We are not transmitting a byte initially)
-+* 2. ACKNAK 0 (Send an ACK after the unit receives a byte)
-+* 1. STOP 0 (Do not send a STOP)
-+* 0. START 0 (Do not send a START)
-+*
-+*/
-+
-+#define I2C_ISR_INIT 0x7FF /* status register init */
-+/* I2C status register init values
-+ *
-+ * 10. BED 1 (Clear bus error detected)
-+ * 9. SAD 1 (Clear slave address detected)
-+ * 7. IRF 1 (Clear IDBR Receive Full)
-+ * 6. ITE 1 (Clear IDBR Transmit Empty)
-+ * 5. ALD 1 (Clear Arbitration Loss Detected)
-+ * 4. SSD 1 (Clear Slave Stop Detected)
-+ */
-+
-+#endif
---- linux-2.6.5/include/linux/ioport.h~heh 2004-04-03 22:36:26.000000000 -0500
-+++ linux-2.6.5/include/linux/ioport.h 2004-04-30 20:57:36.000000000 -0400
-@@ -99,6 +99,7 @@
- void (*alignf)(void *, struct resource *,
- unsigned long, unsigned long),
- void *alignf_data);
-+extern int reallocate_resource(struct resource *res, unsigned long start, unsigned long size);
- int adjust_resource(struct resource *res, unsigned long start,
- unsigned long size);
-
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/include/linux/switches.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,74 @@
-+/*
-+ * linux/include/linux/switches.h
-+ *
-+ * Copyright (C) 2000 John Dorsey
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 23 October 2000 - created.
-+ */
-+
-+#if !defined(_LINUX_SWITCHES_H)
-+#define _LINUX_SWITCHES_H
-+
-+#define SWITCHES_MASK_SIZE (128)
-+
-+typedef unsigned long switches_bitfield;
-+
-+#define SWITCHES_BITS (sizeof(switches_bitfield) * 8)
-+#define SWITCHES_NUM_FIELDS (SWITCHES_MASK_SIZE / SWITCHES_BITS)
-+#define SWITCHES_FIELD_SELECT(i) ((i) / SWITCHES_BITS)
-+#define SWITCHES_FIELD_MASK(i) ((switches_bitfield)(1 << (i) % \
-+ SWITCHES_BITS))
-+
-+typedef struct switches_mask_t {
-+ unsigned int count;
-+ switches_bitfield events[SWITCHES_NUM_FIELDS];
-+ switches_bitfield states[SWITCHES_NUM_FIELDS];
-+} switches_mask_t;
-+
-+#define SWITCHES_ZERO(m) \
-+do { \
-+ unsigned int sz_i; \
-+ (m)->count = 0; \
-+ for(sz_i = 0; sz_i < SWITCHES_NUM_FIELDS; ++sz_i) \
-+ (m)->events[sz_i] = (m)->states[sz_i] = 0; \
-+} while (0)
-+
-+/* `s' is the state of the switch, either 0 or non-zero: */
-+#define SWITCHES_SET(m, i, s) \
-+do { \
-+ ((m)->events[SWITCHES_FIELD_SELECT((i))] |= \
-+ SWITCHES_FIELD_MASK((i))); \
-+ if(s) \
-+ ((m)->states[SWITCHES_FIELD_SELECT((i))] |= \
-+ SWITCHES_FIELD_MASK((i))); \
-+ else \
-+ ((m)->states[SWITCHES_FIELD_SELECT((i))] &= \
-+ ~SWITCHES_FIELD_MASK((i))); \
-+ ++((m)->count); \
-+} while (0)
-+
-+/* Should only use to clear an event set by SWITCHES_SET(): */
-+#define SWITCHES_CLEAR(m, i) \
-+do { \
-+ ((m)->events[SWITCHES_FIELD_SELECT((i))] &= \
-+ ~SWITCHES_FIELD_MASK((i))); \
-+ ((m)->states[SWITCHES_FIELD_SELECT((i))] &= \
-+ ~SWITCHES_FIELD_MASK((i))); \
-+ --((m)->count); \
-+}
-+
-+#define SWITCHES_COUNT(m) ((m)->count)
-+
-+/* Returns 0 or non-zero: */
-+#define SWITCHES_EVENT(m, i) \
-+((m)->events[SWITCHES_FIELD_SELECT((i))] & SWITCHES_FIELD_MASK((i)))
-+
-+/* Returns 0 or non-zero: */
-+#define SWITCHES_STATE(m, i) \
-+((m)->states[SWITCHES_FIELD_SELECT((i))] & SWITCHES_FIELD_MASK((i)))
-+
-+#endif /* !defined(_LINUX_SWITCHES_H) */
---- linux-2.6.5/include/linux/serial_reg.h~heh 2004-04-03 22:37:38.000000000 -0500
-+++ linux-2.6.5/include/linux/serial_reg.h 2004-04-30 20:57:36.000000000 -0400
-@@ -121,6 +121,7 @@
- /*
- * These are the definitions for the Modem Control Register
- */
-+#define UART_MCR_AFE 0x20 /* Enable auto-RTS/CTS (TI16C750) */
- #define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
- #define UART_MCR_OUT2 0x08 /* Out2 complement */
- #define UART_MCR_OUT1 0x04 /* Out1 complement */
-@@ -156,6 +157,21 @@
- #define UART_FCR_PXAR32 0xc0 /* receive FIFO treshold = 32 */
-
- /*
-+ * The Intel PXA2xx chip defines those bits
-+ */
-+#define UART_IER_DMAE 0x80 /* DMA Requests Enable */
-+#define UART_IER_UUE 0x40 /* UART Unit Enable */
-+#define UART_IER_NRZE 0x20 /* NRZ coding Enable */
-+#define UART_IER_RTOIE 0x10 /* Receiver Time Out Interrupt Enable */
-+
-+#define UART_IIR_TOD 0x08 /* Character Timeout Indication Detected */
-+
-+#define UART_FCR_PXAR1 0x00 /* receive FIFO treshold = 1 */
-+#define UART_FCR_PXAR8 0x40 /* receive FIFO treshold = 8 */
-+#define UART_FCR_PXAR16 0x80 /* receive FIFO treshold = 16 */
-+#define UART_FCR_PXAR32 0xc0 /* receive FIFO treshold = 32 */
-+
-+/*
- * These are the definitions for the Extended Features Register
- * (StarTech 16C660 only, when DLAB=1)
- */
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/include/linux/mmc/card.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,83 @@
-+/*
-+ * linux/include/linux/mmc/card.h
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Card driver specific definitions.
-+ */
-+#ifndef LINUX_MMC_CARD_H
-+#define LINUX_MMC_CARD_H
-+
-+#include <linux/mmc/mmc.h>
-+
-+struct mmc_cid {
-+ unsigned int manfid;
-+ unsigned int serial;
-+ char prod_name[8];
-+ unsigned char hwrev;
-+ unsigned char fwrev;
-+ unsigned char month;
-+ unsigned char year;
-+};
-+
-+struct mmc_csd {
-+ unsigned char mmc_prot;
-+ unsigned short cmdclass;
-+ unsigned short tacc_clks;
-+ unsigned int tacc_ns;
-+ unsigned int max_dtr;
-+ unsigned int read_blkbits;
-+ unsigned int capacity;
-+};
-+
-+struct mmc_host;
-+
-+/*
-+ * MMC device
-+ */
-+struct mmc_card {
-+ struct list_head node; /* node in hosts devices list */
-+ struct mmc_host *host; /* the host this device belongs to */
-+ struct device dev; /* the device */
-+ unsigned int rca; /* relative card address of device */
-+ unsigned int state; /* (our) card state */
-+#define MMC_STATE_PRESENT (1<<0)
-+#define MMC_STATE_DEAD (1<<1)
-+ struct mmc_cid cid; /* card identification */
-+ struct mmc_csd csd; /* card specific */
-+};
-+
-+#define mmc_card_dead(c) ((c)->state & MMC_STATE_DEAD)
-+#define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT)
-+
-+#define mmc_card_name(c) ((c)->cid.prod_name)
-+#define mmc_card_id(c) ((c)->dev.bus_id)
-+
-+#define mmc_list_to_card(l) container_of(l, struct mmc_card, node)
-+#define mmc_get_drvdata(c) dev_get_drvdata(&(c)->dev)
-+#define mmc_set_drvdata(c,d) dev_set_drvdata(&(c)->dev, d)
-+
-+/*
-+ * MMC device driver (e.g., Flash card, I/O card...)
-+ */
-+struct mmc_driver {
-+ struct device_driver drv;
-+ int (*probe)(struct mmc_card *);
-+ void (*remove)(struct mmc_card *);
-+ int (*suspend)(struct mmc_card *, u32);
-+ int (*resume)(struct mmc_card *);
-+};
-+
-+extern int mmc_register_driver(struct mmc_driver *);
-+extern void mmc_unregister_driver(struct mmc_driver *);
-+
-+static inline int mmc_card_claim_host(struct mmc_card *card)
-+{
-+ return __mmc_claim_host(card->host, card);
-+}
-+
-+#define mmc_card_release_host(c) mmc_release_host((c)->host)
-+
-+#endif
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/include/linux/mmc/mmc.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,88 @@
-+/*
-+ * linux/include/linux/mmc/mmc.h
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#ifndef MMC_H
-+#define MMC_H
-+
-+#include <linux/list.h>
-+#include <linux/interrupt.h>
-+#include <linux/device.h>
-+
-+struct request;
-+struct mmc_data;
-+struct mmc_request;
-+
-+struct mmc_command {
-+ u32 opcode;
-+ u32 arg;
-+ u32 resp[4];
-+ unsigned int flags; /* expected response type */
-+#define MMC_RSP_NONE (0 << 0)
-+#define MMC_RSP_SHORT (1 << 0)
-+#define MMC_RSP_LONG (2 << 0)
-+#define MMC_RSP_MASK (3 << 0)
-+#define MMC_RSP_CRC (1 << 3) /* expect valid crc */
-+#define MMC_RSP_BUSY (1 << 4) /* card may send busy */
-+
-+ unsigned int retries; /* max number of retries */
-+ unsigned int error; /* command error */
-+
-+#define MMC_ERR_NONE 0
-+#define MMC_ERR_TIMEOUT 1
-+#define MMC_ERR_BADCRC 2
-+#define MMC_ERR_FIFO 3
-+#define MMC_ERR_FAILED 4
-+#define MMC_ERR_INVALID 5
-+
-+ struct mmc_data *data; /* data segment associated with cmd */
-+ struct mmc_request *req; /* assoicated request */
-+};
-+
-+struct mmc_data {
-+ unsigned int timeout_ns; /* data timeout (in ns, max 80ms) */
-+ unsigned int timeout_clks; /* data timeout (in clocks) */
-+ unsigned int blksz_bits; /* data block size */
-+ unsigned int blocks; /* number of blocks */
-+ struct request *rq; /* request structure */
-+ unsigned int error; /* data error */
-+ unsigned int flags;
-+
-+#define MMC_DATA_WRITE (1 << 8)
-+#define MMC_DATA_READ (1 << 9)
-+#define MMC_DATA_STREAM (1 << 10)
-+
-+ unsigned int bytes_xfered;
-+
-+ struct mmc_command *stop; /* stop command */
-+ struct mmc_request *req; /* assoicated request */
-+};
-+
-+struct mmc_request {
-+ struct mmc_command *cmd;
-+ struct mmc_data *data;
-+ struct mmc_command *stop;
-+
-+ void *done_data; /* completion data */
-+ void (*done)(struct mmc_request *);/* completion function */
-+};
-+
-+struct mmc_host;
-+struct mmc_card;
-+
-+extern int mmc_wait_for_req(struct mmc_host *, struct mmc_request *);
-+extern int mmc_wait_for_cmd(struct mmc_host *, struct mmc_command *, int);
-+
-+extern int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card);
-+
-+static inline void mmc_claim_host(struct mmc_host *host)
-+{
-+ __mmc_claim_host(host, (struct mmc_card *)-1);
-+}
-+
-+extern void mmc_release_host(struct mmc_host *host);
-+
-+#endif
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/include/linux/mmc/host.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,67 @@
-+/*
-+ * linux/include/linux/mmc/host.h
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Host driver specific definitions.
-+ */
-+#ifndef LINUX_MMC_HOST_H
-+#define LINUX_MMC_HOST_H
-+
-+#include <linux/mmc/mmc.h>
-+
-+struct mmc_ios {
-+ unsigned int clock; /* clock rate */
-+ unsigned short vdd; /* supply (units of 10mV) */
-+ unsigned char bus_mode; /* command output mode */
-+
-+#define MMC_BUSMODE_OPENDRAIN 1
-+#define MMC_BUSMODE_PUSHPULL 2
-+
-+ unsigned char power_mode; /* power supply mode */
-+
-+#define MMC_POWER_OFF 0
-+#define MMC_POWER_UP 1
-+#define MMC_POWER_ON 2
-+};
-+
-+struct mmc_host_ops {
-+ void (*request)(struct mmc_host *host, struct mmc_request *req);
-+ void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);
-+};
-+
-+struct mmc_card;
-+
-+struct mmc_host {
-+ struct device *dev;
-+ struct mmc_host_ops *ops;
-+ unsigned int f_min;
-+ unsigned int f_max;
-+ u32 ocr_avail;
-+
-+ /* private data */
-+ unsigned int host_num; /* host number */
-+ struct mmc_ios ios; /* current io bus settings */
-+ u32 ocr; /* the current OCR setting */
-+
-+ struct list_head cards; /* devices attached to this host */
-+
-+ wait_queue_head_t wq;
-+ spinlock_t lock; /* card_busy lock */
-+ struct mmc_card *card_busy; /* the MMC card claiming host */
-+ struct mmc_card *card_selected; /* the selected MMC card */
-+};
-+
-+extern int mmc_init_host(struct mmc_host *);
-+extern int mmc_add_host(struct mmc_host *);
-+extern void mmc_remove_host(struct mmc_host *);
-+extern int mmc_suspend_host(struct mmc_host *, u32);
-+extern int mmc_resume_host(struct mmc_host *);
-+
-+extern void mmc_detect_change(struct mmc_host *);
-+extern void mmc_request_done(struct mmc_host *, struct mmc_request *);
-+
-+#endif
-+
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/include/linux/mmc/protocol.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,203 @@
-+/*
-+ * Header for MultiMediaCard (MMC)
-+ *
-+ * Copyright 2002 Hewlett-Packard Company
-+ *
-+ * Use consistent with the GNU GPL is permitted,
-+ * provided that this copyright notice is
-+ * preserved in its entirety in all copies and derived works.
-+ *
-+ * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
-+ * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
-+ * FITNESS FOR ANY PARTICULAR PURPOSE.
-+ *
-+ * Many thanks to Alessandro Rubini and Jonathan Corbet!
-+ *
-+ * Based strongly on code by:
-+ *
-+ * Author: Yong-iL Joh <tolkien@mizi.com>
-+ * Date : $Date$
-+ *
-+ * Author: Andrew Christian
-+ * 15 May 2002
-+ */
-+
-+#ifndef MMC_MMC_PROTOCOL_H
-+#define MMC_MMC_PROTOCOL_H
-+
-+/* Standard MMC commands (3.1) type argument response */
-+ /* class 1 */
-+#define MMC_GO_IDLE_STATE 0 /* bc */
-+#define MMC_SEND_OP_COND 1 /* bcr [31:0] OCR R3 */
-+#define MMC_ALL_SEND_CID 2 /* bcr R2 */
-+#define MMC_SET_RELATIVE_ADDR 3 /* ac [31:16] RCA R1 */
-+#define MMC_SET_DSR 4 /* bc [31:16] RCA */
-+#define MMC_SELECT_CARD 7 /* ac [31:16] RCA R1 */
-+#define MMC_SEND_CSD 9 /* ac [31:16] RCA R2 */
-+#define MMC_SEND_CID 10 /* ac [31:16] RCA R2 */
-+#define MMC_READ_DAT_UNTIL_STOP 11 /* adtc [31:0] dadr R1 */
-+#define MMC_STOP_TRANSMISSION 12 /* ac R1b */
-+#define MMC_SEND_STATUS 13 /* ac [31:16] RCA R1 */
-+#define MMC_GO_INACTIVE_STATE 15 /* ac [31:16] RCA */
-+
-+ /* class 2 */
-+#define MMC_SET_BLOCKLEN 16 /* ac [31:0] block len R1 */
-+#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
-+#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
-+
-+ /* class 3 */
-+#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
-+
-+ /* class 4 */
-+#define MMC_SET_BLOCK_COUNT 23 /* adtc [31:0] data addr R1 */
-+#define MMC_WRITE_BLOCK 24 /* adtc [31:0] data addr R1 */
-+#define MMC_WRITE_MULTIPLE_BLOCK 25 /* adtc R1 */
-+#define MMC_PROGRAM_CID 26 /* adtc R1 */
-+#define MMC_PROGRAM_CSD 27 /* adtc R1 */
-+
-+ /* class 6 */
-+#define MMC_SET_WRITE_PROT 28 /* ac [31:0] data addr R1b */
-+#define MMC_CLR_WRITE_PROT 29 /* ac [31:0] data addr R1b */
-+#define MMC_SEND_WRITE_PROT 30 /* adtc [31:0] wpdata addr R1 */
-+
-+ /* class 5 */
-+#define MMC_ERASE_GROUP_START 35 /* ac [31:0] data addr R1 */
-+#define MMC_ERASE_GROUP_END 36 /* ac [31:0] data addr R1 */
-+#define MMC_ERASE 37 /* ac R1b */
-+
-+ /* class 9 */
-+#define MMC_FAST_IO 39 /* ac <Complex> R4 */
-+#define MMC_GO_IRQ_STATE 40 /* bcr R5 */
-+
-+ /* class 7 */
-+#define MMC_LOCK_UNLOCK 42 /* adtc R1b */
-+
-+ /* class 8 */
-+#define MMC_APP_CMD 55 /* ac [31:16] RCA R1 */
-+#define MMC_GEN_CMD 56 /* adtc [0] RD/WR R1b */
-+
-+/*
-+ MMC status in R1
-+ Type
-+ e : error bit
-+ s : status bit
-+ r : detected and set for the actual command response
-+ x : detected and set during command execution. the host must poll
-+ the card by sending status command in order to read these bits.
-+ Clear condition
-+ a : according to the card state
-+ b : always related to the previous command. Reception of
-+ a valid command will clear it (with a delay of one command)
-+ c : clear by read
-+ */
-+
-+#define R1_OUT_OF_RANGE (1 << 31) /* er, c */
-+#define R1_ADDRESS_ERROR (1 << 30) /* erx, c */
-+#define R1_BLOCK_LEN_ERROR (1 << 29) /* er, c */
-+#define R1_ERASE_SEQ_ERROR (1 << 28) /* er, c */
-+#define R1_ERASE_PARAM (1 << 27) /* ex, c */
-+#define R1_WP_VIOLATION (1 << 26) /* erx, c */
-+#define R1_CARD_IS_LOCKED (1 << 25) /* sx, a */
-+#define R1_LOCK_UNLOCK_FAILED (1 << 24) /* erx, c */
-+#define R1_COM_CRC_ERROR (1 << 23) /* er, b */
-+#define R1_ILLEGAL_COMMAND (1 << 22) /* er, b */
-+#define R1_CARD_ECC_FAILED (1 << 21) /* ex, c */
-+#define R1_CC_ERROR (1 << 20) /* erx, c */
-+#define R1_ERROR (1 << 19) /* erx, c */
-+#define R1_UNDERRUN (1 << 18) /* ex, c */
-+#define R1_OVERRUN (1 << 17) /* ex, c */
-+#define R1_CID_CSD_OVERWRITE (1 << 16) /* erx, c, CID/CSD overwrite */
-+#define R1_WP_ERASE_SKIP (1 << 15) /* sx, c */
-+#define R1_CARD_ECC_DISABLED (1 << 14) /* sx, a */
-+#define R1_ERASE_RESET (1 << 13) /* sr, c */
-+#define R1_STATUS(x) (x & 0xFFFFE000)
-+#define R1_CURRENT_STATE(x) ((x & 0x00001E00) >> 9) /* sx, b (4 bits) */
-+#define R1_READY_FOR_DATA (1 << 8) /* sx, a */
-+#define R1_APP_CMD (1 << 7) /* sr, c */
-+
-+/* These are unpacked versions of the actual responses */
-+
-+struct _mmc_csd {
-+ u8 csd_structure;
-+ u8 spec_vers;
-+ u8 taac;
-+ u8 nsac;
-+ u8 tran_speed;
-+ u16 ccc;
-+ u8 read_bl_len;
-+ u8 read_bl_partial;
-+ u8 write_blk_misalign;
-+ u8 read_blk_misalign;
-+ u8 dsr_imp;
-+ u16 c_size;
-+ u8 vdd_r_curr_min;
-+ u8 vdd_r_curr_max;
-+ u8 vdd_w_curr_min;
-+ u8 vdd_w_curr_max;
-+ u8 c_size_mult;
-+ union {
-+ struct { /* MMC system specification version 3.1 */
-+ u8 erase_grp_size;
-+ u8 erase_grp_mult;
-+ } v31;
-+ struct { /* MMC system specification version 2.2 */
-+ u8 sector_size;
-+ u8 erase_grp_size;
-+ } v22;
-+ } erase;
-+ u8 wp_grp_size;
-+ u8 wp_grp_enable;
-+ u8 default_ecc;
-+ u8 r2w_factor;
-+ u8 write_bl_len;
-+ u8 write_bl_partial;
-+ u8 file_format_grp;
-+ u8 copy;
-+ u8 perm_write_protect;
-+ u8 tmp_write_protect;
-+ u8 file_format;
-+ u8 ecc;
-+};
-+
-+#define MMC_VDD_145_150 0x00000001 /* VDD voltage 1.45 - 1.50 */
-+#define MMC_VDD_150_155 0x00000002 /* VDD voltage 1.50 - 1.55 */
-+#define MMC_VDD_155_160 0x00000004 /* VDD voltage 1.55 - 1.60 */
-+#define MMC_VDD_160_165 0x00000008 /* VDD voltage 1.60 - 1.65 */
-+#define MMC_VDD_165_170 0x00000010 /* VDD voltage 1.65 - 1.70 */
-+#define MMC_VDD_17_18 0x00000020 /* VDD voltage 1.7 - 1.8 */
-+#define MMC_VDD_18_19 0x00000040 /* VDD voltage 1.8 - 1.9 */
-+#define MMC_VDD_19_20 0x00000080 /* VDD voltage 1.9 - 2.0 */
-+#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */
-+#define MMC_VDD_21_22 0x00000200 /* VDD voltage 2.1 ~ 2.2 */
-+#define MMC_VDD_22_23 0x00000400 /* VDD voltage 2.2 ~ 2.3 */
-+#define MMC_VDD_23_24 0x00000800 /* VDD voltage 2.3 ~ 2.4 */
-+#define MMC_VDD_24_25 0x00001000 /* VDD voltage 2.4 ~ 2.5 */
-+#define MMC_VDD_25_26 0x00002000 /* VDD voltage 2.5 ~ 2.6 */
-+#define MMC_VDD_26_27 0x00004000 /* VDD voltage 2.6 ~ 2.7 */
-+#define MMC_VDD_27_28 0x00008000 /* VDD voltage 2.7 ~ 2.8 */
-+#define MMC_VDD_28_29 0x00010000 /* VDD voltage 2.8 ~ 2.9 */
-+#define MMC_VDD_29_30 0x00020000 /* VDD voltage 2.9 ~ 3.0 */
-+#define MMC_VDD_30_31 0x00040000 /* VDD voltage 3.0 ~ 3.1 */
-+#define MMC_VDD_31_32 0x00080000 /* VDD voltage 3.1 ~ 3.2 */
-+#define MMC_VDD_32_33 0x00100000 /* VDD voltage 3.2 ~ 3.3 */
-+#define MMC_VDD_33_34 0x00200000 /* VDD voltage 3.3 ~ 3.4 */
-+#define MMC_VDD_34_35 0x00400000 /* VDD voltage 3.4 ~ 3.5 */
-+#define MMC_VDD_35_36 0x00800000 /* VDD voltage 3.5 ~ 3.6 */
-+#define MMC_CARD_BUSY 0x80000000 /* Card Power up status bit */
-+
-+
-+/*
-+ * CSD field definitions
-+ */
-+
-+#define CSD_STRUCT_VER_1_0 0 /* Valid for system specification 1.0 - 1.2 */
-+#define CSD_STRUCT_VER_1_1 1 /* Valid for system specification 1.4 - 2.2 */
-+#define CSD_STRUCT_VER_1_2 2 /* Valid for system specification 3.1 */
-+
-+#define CSD_SPEC_VER_0 0 /* Implements system specification 1.0 - 1.2 */
-+#define CSD_SPEC_VER_1 1 /* Implements system specification 1.4 */
-+#define CSD_SPEC_VER_2 2 /* Implements system specification 2.0 - 2.2 */
-+#define CSD_SPEC_VER_3 3 /* Implements system specification 3.1 */
-+
-+#endif /* MMC_MMC_PROTOCOL_H */
-+
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/include/linux/l3/algo-bit.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,39 @@
-+/*
-+ * linux/include/linux/l3/algo-bit.h
-+ *
-+ * Copyright (C) 2001 Russell King, 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.
-+ *
-+ * L3 Bus bit-banging algorithm. Derived from i2c-algo-bit.h by
-+ * Simon G. Vogl.
-+ */
-+#ifndef L3_ALGO_BIT_H
-+#define L3_ALGO_BIT_H 1
-+
-+#include <linux/l3/l3.h>
-+
-+struct l3_algo_bit_data {
-+ void (*setdat) (void *data, int state);
-+ void (*setclk) (void *data, int state);
-+ void (*setmode)(void *data, int state);
-+ void (*setdir) (void *data, int in); /* set data direction */
-+ int (*getdat) (void *data);
-+
-+ void *data;
-+
-+ /* bus timings (us) */
-+ int data_hold;
-+ int data_setup;
-+ int clock_high;
-+ int mode_hold;
-+ int mode_setup;
-+ int mode;
-+};
-+
-+int l3_bit_add_bus(struct l3_adapter *);
-+int l3_bit_del_bus(struct l3_adapter *);
-+
-+#endif
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/include/linux/l3/l3.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,95 @@
-+/*
-+ * linux/include/linux/l3/l3.h
-+ *
-+ * Copyright (C) 2001 Russell King, 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.
-+ *
-+ * Derived from i2c.h by Simon G. Vogl
-+ */
-+#ifndef L3_H
-+#define L3_H
-+
-+struct l3_msg {
-+ unsigned char addr; /* slave address */
-+ unsigned char flags;
-+#define L3_M_RD 0x01
-+#define L3_M_NOADDR 0x02
-+ unsigned short len; /* msg length */
-+ unsigned char *buf; /* pointer to msg data */
-+};
-+
-+#ifdef __KERNEL__
-+
-+#include <linux/types.h>
-+#include <linux/list.h>
-+
-+struct l3_adapter;
-+
-+struct l3_algorithm {
-+ /* textual description */
-+ char name[32];
-+
-+ /* perform bus transactions */
-+ int (*xfer)(struct l3_adapter *, struct l3_msg msgs[], int num);
-+};
-+
-+struct semaphore;
-+
-+/*
-+ * l3_adapter is the structure used to identify a physical L3 bus along
-+ * with the access algorithms necessary to access it.
-+ */
-+struct l3_adapter {
-+ /*
-+ * This name is used to uniquely identify the adapter.
-+ * It should be the same as the module name.
-+ */
-+ char name[32];
-+
-+ /*
-+ * the algorithm to access the bus
-+ */
-+ struct l3_algorithm *algo;
-+
-+ /*
-+ * Algorithm specific data
-+ */
-+ void *algo_data;
-+
-+ /*
-+ * This may be NULL, or should point to the module struct
-+ */
-+ struct module *owner;
-+
-+ /*
-+ * private data for the adapter
-+ */
-+ void *data;
-+
-+ /*
-+ * Our lock. Unlike the i2c layer, we allow this to be used for
-+ * other stuff, like the i2c layer lock. Some people implement
-+ * i2c stuff using the same signals as the l3 bus.
-+ */
-+ struct semaphore *lock;
-+
-+ /*
-+ * List of all adapters.
-+ */
-+ struct list_head adapters;
-+};
-+
-+extern int l3_add_adapter(struct l3_adapter *);
-+extern int l3_del_adapter(struct l3_adapter *);
-+extern void l3_put_adapter(struct l3_adapter *);
-+extern struct l3_adapter *l3_get_adapter(const char *name);
-+
-+extern int l3_write(struct l3_adapter *, int, const char *, int);
-+extern int l3_read(struct l3_adapter *, int, char *, int);
-+
-+#endif
-+
-+#endif /* L3_H */
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/include/linux/l3/uda1341.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,61 @@
-+/*
-+ * linux/include/linux/l3/uda1341.h
-+ *
-+ * Philips UDA1341 mixer device driver
-+ *
-+ * Copyright (c) 2000 Nicolas Pitre <nico@cam.org>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License.
-+ */
-+
-+#define UDA1341_NAME "uda1341"
-+
-+struct uda1341_cfg {
-+ unsigned int fs:16;
-+ unsigned int format:3;
-+};
-+
-+#define FMT_I2S 0
-+#define FMT_LSB16 1
-+#define FMT_LSB18 2
-+#define FMT_LSB20 3
-+#define FMT_MSB 4
-+#define FMT_LSB16MSB 5
-+#define FMT_LSB18MSB 6
-+#define FMT_LSB20MSB 7
-+
-+#define L3_UDA1341_CONFIGURE 0x13410001
-+
-+struct l3_gain {
-+ unsigned int left:8;
-+ unsigned int right:8;
-+ unsigned int unused:8;
-+ unsigned int channel:8;
-+};
-+
-+#define L3_SET_VOLUME 0x13410002
-+#define L3_SET_TREBLE 0x13410003
-+#define L3_SET_BASS 0x13410004
-+#define L3_SET_GAIN 0x13410005
-+
-+struct l3_agc {
-+ unsigned int level:8;
-+ unsigned int enable:1;
-+ unsigned int attack:7;
-+ unsigned int decay:8;
-+ unsigned int channel:8;
-+};
-+
-+#define L3_INPUT_AGC 0x13410006
-+
-+struct uda1341;
-+
-+int uda1341_configure(struct uda1341 *uda, struct uda1341_cfg *conf);
-+int uda1341_mixer_ctl(struct uda1341 *uda, int cmd, void *arg);
-+int uda1341_open(struct uda1341 *uda);
-+void uda1341_close(struct uda1341 *uda);
-+
-+struct uda1341 *uda1341_attach(const char *adapter);
-+void uda1341_detach(struct uda1341 *uda);
-+
---- linux-2.6.5/include/linux/i2c-id.h~heh 2004-04-03 22:36:16.000000000 -0500
-+++ linux-2.6.5/include/linux/i2c-id.h 2004-04-30 20:57:36.000000000 -0400
-@@ -187,6 +187,7 @@
- #define I2C_ALGO_BITHS 0x130000 /* enhanced bit style adapters */
- #define I2C_ALGO_OCP_IOP3XX 0x140000 /* XSCALE IOP3XX On-chip I2C alg */
-
-+#define I2C_ALGO_PXA 0x200000 /* Intel PXA I2C algorithm */
- #define I2C_ALGO_EXP 0x800000 /* experimental */
-
- #define I2C_ALGO_MASK 0xff0000 /* Mask for algorithms */
---- linux-2.6.5/include/linux/serial_core.h~heh 2004-04-03 22:36:18.000000000 -0500
-+++ linux-2.6.5/include/linux/serial_core.h 2004-04-30 20:57:36.000000000 -0400
-@@ -17,7 +17,7 @@
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
-- * $Id$
-+ * $Id$
- */
-
- /*
-@@ -159,8 +159,6 @@
- spinlock_t lock; /* port lock */
- unsigned int iobase; /* in/out[bwl] */
- char *membase; /* read/write[bwl] */
-- unsigned int irq; /* irq number */
-- unsigned int uartclk; /* base uart clock */
- unsigned char fifosize; /* tx fifo size */
- unsigned char x_char; /* xon/xoff char */
- unsigned char regshift; /* reg offset shift */
-@@ -172,6 +170,7 @@
-
- unsigned int read_status_mask; /* driver specific */
- unsigned int ignore_status_mask; /* driver specific */
-+
- struct uart_info *info; /* pointer to parent info */
- struct uart_icount icount; /* statistics */
-
-@@ -182,7 +181,6 @@
-
- unsigned int flags;
-
--#define UPF_HUP_NOTIFY (1 << 0)
- #define UPF_FOURPORT (1 << 1)
- #define UPF_SAK (1 << 2)
- #define UPF_SPD_MASK (0x1030)
-@@ -212,9 +210,12 @@
- unsigned int timeout; /* character-based timeout */
- unsigned int type; /* port type */
- struct uart_ops *ops;
-+ unsigned int uartclk; /* base uart clock */
- unsigned int custom_divisor;
-+ unsigned int irq; /* irq number */
- unsigned int line; /* port index */
- unsigned long mapbase; /* for ioremap */
-+ struct device *dev; /* parent device */
- unsigned char hub6; /* this should be in the 8250 driver */
- unsigned char unused[3];
- };
---- linux-2.6.5/include/linux/vmalloc.h~heh 2004-04-03 22:38:23.000000000 -0500
-+++ linux-2.6.5/include/linux/vmalloc.h 2004-04-30 20:57:36.000000000 -0400
-@@ -35,6 +35,8 @@
- * Lowlevel-APIs (not for driver use!)
- */
- extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags);
-+extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
-+ unsigned long start, unsigned long end);
- extern struct vm_struct *remove_vm_area(void *addr);
- extern int map_vm_area(struct vm_struct *area, pgprot_t prot,
- struct page ***pages);
---- linux-2.6.5/include/linux/mm.h~heh 2004-04-03 22:36:15.000000000 -0500
-+++ linux-2.6.5/include/linux/mm.h 2004-04-30 20:57:36.000000000 -0400
-@@ -655,5 +655,12 @@
- int in_gate_area(struct task_struct *task, unsigned long addr);
- #endif
-
-+#ifndef __arm__
-+#define memc_update_addr(x,y,z)
-+#define memc_update_mm(x)
-+#define memc_clear(x,y)
-+#endif
-+
- #endif /* __KERNEL__ */
- #endif /* _LINUX_MM_H */
-+
---- linux-2.6.5/init/do_mounts.c~heh 2004-04-03 22:36:56.000000000 -0500
-+++ linux-2.6.5/init/do_mounts.c 2004-04-30 20:57:36.000000000 -0400
-@@ -391,7 +391,7 @@
- root_device_name += 5;
- }
-
-- is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
-+ is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR || MAJOR(ROOT_DEV) == 31;
-
- if (initrd_load())
- goto out;
---- linux-2.6.5/fs/binfmt_aout.c~heh 2004-04-03 22:36:26.000000000 -0500
-+++ linux-2.6.5/fs/binfmt_aout.c 2004-04-30 20:57:36.000000000 -0400
-@@ -432,7 +432,11 @@
- else
- send_sig(SIGTRAP, current, 0);
- }
-+#ifndef __arm__
- return 0;
-+#else
-+ return regs->ARM_r0;
-+#endif
- }
-
- static int load_aout_library(struct file *file)
-@@ -462,8 +466,11 @@
-
- /* For QMAGIC, the starting address is 0x20 into the page. We mask
- this off to get the starting address for the page */
--
-- start_addr = ex.a_entry & 0xfffff000;
-+#ifndef __arm__
-+ start_addr = ex.a_entry & 0xfffff000;
-+#else
-+ start_addr = ex.a_entry & 0xffff8000;
-+#endif
-
- if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) {
- static unsigned long error_time;
---- linux-2.6.5/mm/slab.c~heh 2004-04-03 22:37:41.000000000 -0500
-+++ linux-2.6.5/mm/slab.c 2004-04-30 20:57:36.000000000 -0400
-@@ -2115,12 +2115,12 @@
- *
- * Called with disabled ints.
- */
--static inline void __cache_free (kmem_cache_t *cachep, void* objp)
-+static inline void __cache_free (kmem_cache_t *cachep, void* objp, void *caller)
- {
- struct array_cache *ac = ac_data(cachep);
-
- check_irq_off();
-- objp = cache_free_debugcheck(cachep, objp, __builtin_return_address(0));
-+ objp = cache_free_debugcheck(cachep, objp, caller /*__builtin_return_address(0)*/);
-
- if (likely(ac->avail < ac->limit)) {
- STATS_INC_FREEHIT(cachep);
-@@ -2289,7 +2289,7 @@
- unsigned long flags;
-
- local_irq_save(flags);
-- __cache_free(cachep, objp);
-+ __cache_free(cachep, objp, __builtin_return_address(0));
- local_irq_restore(flags);
- }
-
-@@ -2312,7 +2312,7 @@
- local_irq_save(flags);
- kfree_debugcheck(objp);
- c = GET_PAGE_CACHE(virt_to_page(objp));
-- __cache_free(c, (void*)objp);
-+ __cache_free(c, (void*)objp, __builtin_return_address(0));
- local_irq_restore(flags);
- }
-
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/Documentation/l3/structure 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,36 @@
-+L3 Bus Driver
-+-------------
-+
-+The structure of the driver is as follows:
-+
-+ +----------+ +----------+ +----------+
-+ | client 1 | | client 2 | | client 3 |
-+ +-----^----+ +----^-----+ +----^-----+
-+ | | |
-+ +-----v--------------v---------------v-----+
-+ | |
-+ +-----^-------+ +-------^-----+
-+ | | core | |
-+ +-----v----+ | | +----v-----+
-+ | device | | | | device |
-+ | driver 1 | | | | driver 2 |
-+ +-----^----+ | | +----^-----+
-+ | | services | |
-+ +-----v-------+ +-------v-----+
-+ | |
-+ +-----------------^----^-------------------+
-+ | |
-+ | +-v---------+
-+ | | algorithm |
-+ | | driver |
-+ | +-v---------+
-+ | |
-+ +-v----v-+
-+ | bus |
-+ | driver |
-+ +--------+
-+
-+Clients talk to the core to attach device drivers and bus adapters, and
-+to instruct device drivers to perform actions. Device drivers then talk
-+to the core to perform L3 bus transactions via the algorithm driver and
-+ultimately bus driver.
---- linux-2.6.5/arch/arm/kernel/debug.S~heh 2004-04-03 22:36:55.000000000 -0500
-+++ linux-2.6.5/arch/arm/kernel/debug.S 2004-04-30 20:57:36.000000000 -0400
-@@ -192,6 +192,20 @@
-
- @ if all ports are inactive, then there is nothing we can do
- moveq pc, lr
-+ ldr r1, [\rx, #UTCR2]
-+ teq r1, #5
-+ movne r1, #0
-+ strne r1, [\rx, #UTCR3]
-+ movne r1, #8
-+ strne r1, [\rx, #UTCR0]
-+ movne r1, #5
-+ strne r1, [\rx, #UTCR2]
-+ movne r1, #0
-+ strne r1, [\rx, #UTCR1]
-+ movne r1, #3
-+ strne r1, [\rx, #UTCR3]
-+ movne r1, #255
-+ strne r1, [\rx, #UTSR0]
- .endm
-
- .macro senduart,rd,rx
-@@ -287,7 +301,7 @@
-
- #elif defined(CONFIG_ARCH_INTEGRATOR)
-
--#include <asm/hardware/serial_amba.h>
-+#include <asm/hardware/amba_serial.h>
-
- .macro addruart,rx
- mrc p15, 0, \rx, c1, c0
-@@ -298,7 +312,7 @@
- .endm
-
- .macro senduart,rd,rx
-- strb \rd, [\rx, #AMBA_UARTDR]
-+ strb \rd, [\rx, #UART01x_DR]
- .endm
-
- .macro waituart,rd,rx
---- linux-2.6.5/arch/arm/kernel/entry-armv.S~heh 2004-04-03 22:36:54.000000000 -0500
-+++ linux-2.6.5/arch/arm/kernel/entry-armv.S 2004-04-30 20:57:36.000000000 -0400
-@@ -1181,6 +1181,9 @@
- * get out of that mode without clobbering one register.
- */
- vector_FIQ: disable_fiq
-+ mrs r13, spsr
-+ orr r13, r13, #PSR_F_BIT
-+ msr spsr, r13
- subs pc, lr, #4
-
- /*=============================================================================
---- linux-2.6.5/arch/arm/kernel/irq.c~heh 2004-04-03 22:36:12.000000000 -0500
-+++ linux-2.6.5/arch/arm/kernel/irq.c 2004-04-30 20:57:36.000000000 -0400
-@@ -47,12 +47,36 @@
- #define MAX_IRQ_CNT 100000
-
- static volatile unsigned long irq_err_count;
--static spinlock_t irq_controller_lock;
- static LIST_HEAD(irq_pending);
-
- struct irqdesc irq_desc[NR_IRQS];
- void (*init_arch_irq)(void) __initdata = NULL;
-
-+#if NR_IRQ_DEVICES > 1
-+struct irq_device {
-+ spinlock_t lock;
-+ int nr_irqs;
-+ struct irq_desc *irqs;
-+};
-+
-+static struct irq_device irq_devices[NR_IRQ_DEVICES] = {
-+ [0] = {
-+ .lock = SPIN_LOCK_UNLOCKED,
-+ .nr_irqs = NR_IRQS,
-+ .irqs = irq_desc,
-+ },
-+};
-+#define IRQ_LOCK(irq) (&irq_devices[IRQ_DEVICE(irq)].lock)
-+#define IRQ_DESC(irq) (&irq_devices[IRQ_DEVICE(irq)].irqs[IRQ_INDEX(irq)])
-+#define IRQ_VALID(irq) (IRQ_DEVICE(irq) < NR_IRQ_DEVICES && \
-+ IRQ_INDEX(irq) < irq_devices[IRQ_DEVICE(irq)].nr_irqs)
-+#else
-+static spinlock_t irq_controller_lock = SPIN_LOCK_UNLOCKED;
-+#define IRQ_LOCK(irq) (&irq_controller_lock)
-+#define IRQ_DESC(irq) (&irq_desc[irq])
-+#define IRQ_VALID(irq) ((irq) < NR_IRQS)
-+#endif
-+
- /*
- * Dummy mask/unmask handler
- */
-@@ -95,13 +119,13 @@
- */
- void disable_irq(unsigned int irq)
- {
-- struct irqdesc *desc = irq_desc + irq;
-+ struct irqdesc *desc = IRQ_DESC(irq);
- unsigned long flags;
-
-- spin_lock_irqsave(&irq_controller_lock, flags);
-+ spin_lock_irqsave(IRQ_LOCK(irq), flags);
- desc->disable_depth++;
- list_del_init(&desc->pend);
-- spin_unlock_irqrestore(&irq_controller_lock, flags);
-+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
- }
-
- /**
-@@ -116,10 +140,10 @@
- */
- void enable_irq(unsigned int irq)
- {
-- struct irqdesc *desc = irq_desc + irq;
-+ struct irqdesc *desc = IRQ_DESC(irq);
- unsigned long flags;
-
-- spin_lock_irqsave(&irq_controller_lock, flags);
-+ spin_lock_irqsave(IRQ_LOCK(irq), flags);
- if (unlikely(!desc->disable_depth)) {
- printk("enable_irq(%u) unbalanced from %p\n", irq,
- __builtin_return_address(0));
-@@ -140,7 +164,7 @@
- list_add(&desc->pend, &irq_pending);
- }
- }
-- spin_unlock_irqrestore(&irq_controller_lock, flags);
-+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
- }
-
- /*
-@@ -148,24 +172,24 @@
- */
- void enable_irq_wake(unsigned int irq)
- {
-- struct irqdesc *desc = irq_desc + irq;
-+ struct irqdesc *desc = IRQ_DESC(irq);
- unsigned long flags;
-
-- spin_lock_irqsave(&irq_controller_lock, flags);
-+ spin_lock_irqsave(IRQ_LOCK(irq), flags);
- if (desc->chip->wake)
- desc->chip->wake(irq, 1);
-- spin_unlock_irqrestore(&irq_controller_lock, flags);
-+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
- }
-
- void disable_irq_wake(unsigned int irq)
- {
-- struct irqdesc *desc = irq_desc + irq;
-+ struct irqdesc *desc = IRQ_DESC(irq);
- unsigned long flags;
-
-- spin_lock_irqsave(&irq_controller_lock, flags);
-+ spin_lock_irqsave(IRQ_LOCK(irq), flags);
- if (desc->chip->wake)
- desc->chip->wake(irq, 0);
-- spin_unlock_irqrestore(&irq_controller_lock, flags);
-+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
- }
-
- int show_interrupts(struct seq_file *p, void *v)
-@@ -175,8 +199,8 @@
- unsigned long flags;
-
- if (i < NR_IRQS) {
-- spin_lock_irqsave(&irq_controller_lock, flags);
-- action = irq_desc[i].action;
-+ spin_lock_irqsave(IRQ_LOCK(irq), flags);
-+ action = IRQ_DESC(i)->action;
- if (!action)
- goto unlock;
-
-@@ -187,7 +211,7 @@
-
- seq_putc(p, '\n');
- unlock:
-- spin_unlock_irqrestore(&irq_controller_lock, flags);
-+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
- } else if (i == NR_IRQS) {
- #ifdef CONFIG_ARCH_ACORN
- show_fiq_list(p, v);
-@@ -259,7 +283,7 @@
- unsigned int status;
- int retval = 0;
-
-- spin_unlock(&irq_controller_lock);
-+ spin_unlock(IRQ_LOCK(irq));
-
- if (!(action->flags & SA_INTERRUPT))
- local_irq_enable();
-@@ -274,7 +298,7 @@
- if (status & SA_SAMPLE_RANDOM)
- add_interrupt_randomness(irq);
-
-- spin_lock_irq(&irq_controller_lock);
-+ spin_lock_irq(IRQ_LOCK(irq));
-
- return retval;
- }
-@@ -455,7 +479,7 @@
- desc = &bad_irq_desc;
-
- irq_enter();
-- spin_lock(&irq_controller_lock);
-+ spin_lock(IRQ_LOCK(irq));
- desc->handle(irq, desc, regs);
-
- /*
-@@ -464,7 +488,7 @@
- if (!list_empty(&irq_pending))
- do_pending_irqs(regs);
-
-- spin_unlock(&irq_controller_lock);
-+ spin_unlock(IRQ_LOCK(irq));
- irq_exit();
- }
-
-@@ -473,7 +497,7 @@
- struct irqdesc *desc;
- unsigned long flags;
-
-- if (irq >= NR_IRQS) {
-+ if (!IRQ_VALID(irq)) {
- printk(KERN_ERR "Trying to install handler for IRQ%d\n", irq);
- return;
- }
-@@ -481,12 +505,12 @@
- if (handle == NULL)
- handle = do_bad_IRQ;
-
-- desc = irq_desc + irq;
-+ desc = IRQ_DESC(irq);
-
- if (is_chained && desc->chip == &bad_chip)
- printk(KERN_WARNING "Trying to install chained handler for IRQ%d\n", irq);
-
-- spin_lock_irqsave(&irq_controller_lock, flags);
-+ spin_lock_irqsave(IRQ_LOCK(irq), flags);
- if (handle == do_bad_IRQ) {
- desc->chip->mask(irq);
- desc->chip->ack(irq);
-@@ -499,7 +523,7 @@
- desc->disable_depth = 0;
- desc->chip->unmask(irq);
- }
-- spin_unlock_irqrestore(&irq_controller_lock, flags);
-+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
- }
-
- void set_irq_chip(unsigned int irq, struct irqchip *chip)
-@@ -507,7 +531,7 @@
- struct irqdesc *desc;
- unsigned long flags;
-
-- if (irq >= NR_IRQS) {
-+ if (!IRQ_VALID(irq)) {
- printk(KERN_ERR "Trying to install chip for IRQ%d\n", irq);
- return;
- }
-@@ -515,10 +539,10 @@
- if (chip == NULL)
- chip = &bad_chip;
-
-- desc = irq_desc + irq;
-- spin_lock_irqsave(&irq_controller_lock, flags);
-+ desc = IRQ_DESC(irq);
-+ spin_lock_irqsave(IRQ_LOCK(irq), flags);
- desc->chip = chip;
-- spin_unlock_irqrestore(&irq_controller_lock, flags);
-+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
- }
-
- int set_irq_type(unsigned int irq, unsigned int type)
-@@ -527,16 +551,21 @@
- unsigned long flags;
- int ret = -ENXIO;
-
-- if (irq >= NR_IRQS) {
-+ if (!IRQ_VALID(irq)) {
- printk(KERN_ERR "Trying to set irq type for IRQ%d\n", irq);
- return -ENODEV;
- }
-
-- desc = irq_desc + irq;
-+ desc = IRQ_DESC(irq);
-+ if (!desc->action && desc->handle != do_bad_IRQ) {
-+ printk(KERN_ERR "Setting type of unclaimed IRQ%d from ", irq);
-+ print_symbol("%s\n", (unsigned long)__builtin_return_address(0));
-+ }
-+
- if (desc->chip->type) {
-- spin_lock_irqsave(&irq_controller_lock, flags);
-+ spin_lock_irqsave(IRQ_LOCK(irq), flags);
- ret = desc->chip->type(irq, type);
-- spin_unlock_irqrestore(&irq_controller_lock, flags);
-+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
- }
-
- return ret;
-@@ -547,17 +576,17 @@
- struct irqdesc *desc;
- unsigned long flags;
-
-- if (irq >= NR_IRQS) {
-+ if (!IRQ_VALID(irq)) {
- printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq);
- return;
- }
-
-- desc = irq_desc + irq;
-- spin_lock_irqsave(&irq_controller_lock, flags);
-+ desc = IRQ_DESC(irq);
-+ spin_lock_irqsave(IRQ_LOCK(irq), flags);
- desc->valid = (iflags & IRQF_VALID) != 0;
- desc->probe_ok = (iflags & IRQF_PROBE) != 0;
- desc->noautoenable = (iflags & IRQF_NOAUTOEN) != 0;
-- spin_unlock_irqrestore(&irq_controller_lock, flags);
-+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
- }
-
- int setup_irq(unsigned int irq, struct irqaction *new)
-@@ -587,13 +616,13 @@
- /*
- * The following block of code has to be executed atomically
- */
-- desc = irq_desc + irq;
-- spin_lock_irqsave(&irq_controller_lock, flags);
-+ desc = IRQ_DESC(irq);
-+ spin_lock_irqsave(IRQ_LOCK(irq), flags);
- p = &desc->action;
- if ((old = *p) != NULL) {
- /* Can't share interrupts unless both agree to */
- if (!(old->flags & new->flags & SA_SHIRQ)) {
-- spin_unlock_irqrestore(&irq_controller_lock, flags);
-+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
- return -EBUSY;
- }
-
-@@ -618,7 +647,7 @@
- }
- }
-
-- spin_unlock_irqrestore(&irq_controller_lock, flags);
-+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
- return 0;
- }
-
-@@ -659,7 +688,7 @@
- unsigned long retval;
- struct irqaction *action;
-
-- if (irq >= NR_IRQS || !irq_desc[irq].valid || !handler ||
-+ if (!IRQ_VALID(irq) || !IRQ_DESC(irq)->valid || !handler ||
- (irq_flags & SA_SHIRQ && !dev_id))
- return -EINVAL;
-
-@@ -700,14 +729,14 @@
- struct irqaction * action, **p;
- unsigned long flags;
-
-- if (irq >= NR_IRQS || !irq_desc[irq].valid) {
-+ if (!IRQ_VALID(irq) || !IRQ_DESC(irq)->valid) {
- printk(KERN_ERR "Trying to free IRQ%d\n",irq);
- dump_stack();
- return;
- }
-
-- spin_lock_irqsave(&irq_controller_lock, flags);
-- for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) {
-+ spin_lock_irqsave(IRQ_LOCK(irq), flags);
-+ for (p = &IRQ_DESC(irq)->action; (action = *p) != NULL; p = &action->next) {
- if (action->dev_id != dev_id)
- continue;
-
-@@ -715,7 +744,7 @@
- *p = action->next;
- break;
- }
-- spin_unlock_irqrestore(&irq_controller_lock, flags);
-+ spin_unlock_irqrestore(IRQ_LOCK(irq), flags);
-
- if (!action) {
- printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
-@@ -747,19 +776,18 @@
- * first snaffle up any unassigned but
- * probe-able interrupts
- */
-- spin_lock_irq(&irq_controller_lock);
- for (i = 0; i < NR_IRQS; i++) {
-- if (!irq_desc[i].probe_ok || irq_desc[i].action)
-- continue;
--
-- irq_desc[i].probing = 1;
-- irq_desc[i].triggered = 0;
-- if (irq_desc[i].chip->type)
-- irq_desc[i].chip->type(i, IRQT_PROBE);
-- irq_desc[i].chip->unmask(i);
-- irqs += 1;
-+ spin_lock_irq(IRQ_LOCK(i));
-+ if (irq_desc[i].probe_ok && !irq_desc[i].action) {
-+ irq_desc[i].probing = 1;
-+ irq_desc[i].triggered = 0;
-+ if (irq_desc[i].chip->type)
-+ irq_desc[i].chip->type(i, IRQT_PROBE);
-+ irq_desc[i].chip->unmask(i);
-+ irqs += 1;
-+ }
-+ spin_unlock_irq(IRQ_LOCK(i));
- }
-- spin_unlock_irq(&irq_controller_lock);
-
- /*
- * wait for spurious interrupts to mask themselves out again
-@@ -770,14 +798,14 @@
- /*
- * now filter out any obviously spurious interrupts
- */
-- spin_lock_irq(&irq_controller_lock);
- for (i = 0; i < NR_IRQS; i++) {
-+ spin_lock_irq(IRQ_LOCK(i));
- if (irq_desc[i].probing && irq_desc[i].triggered) {
- irq_desc[i].probing = 0;
- irqs -= 1;
- }
-+ spin_unlock_irq(IRQ_LOCK(i));
- }
-- spin_unlock_irq(&irq_controller_lock);
-
- return irqs;
- }
-@@ -788,11 +816,13 @@
- {
- unsigned int mask = 0, i;
-
-- spin_lock_irq(&irq_controller_lock);
-- for (i = 0; i < 16 && i < NR_IRQS; i++)
-- if (irq_desc[i].probing && irq_desc[i].triggered)
-+ for (i = 0; i < 16 && i < NR_IRQS; i++) {
-+ struct irqdesc *desc = IRQ_DESC(i);
-+ spin_lock_irq(IRQ_LOCK(i));
-+ if (desc->probing && desc->triggered)
- mask |= 1 << i;
-- spin_unlock_irq(&irq_controller_lock);
-+ spin_unlock_irq(IRQ_LOCK(i));
-+ }
-
- up(&probe_sem);
-
-@@ -813,23 +843,21 @@
- * look at the interrupts, and find exactly one
- * that we were probing has been triggered
- */
-- spin_lock_irq(&irq_controller_lock);
- for (i = 0; i < NR_IRQS; i++) {
-- if (irq_desc[i].probing &&
-- irq_desc[i].triggered) {
-+ struct irqdesc *desc = IRQ_DESC(i);
-+
-+ spin_lock_irq(IRQ_LOCK(i));
-+ if (desc->probing && desc->triggered) {
- if (irq_found != NO_IRQ) {
-+ spin_unlock_irq(IRQ_LOCK(i));
- irq_found = NO_IRQ;
-- goto out;
-+ break;
- }
- irq_found = i;
- }
-+ spin_unlock_irq(IRQ_LOCK(i));
- }
-
-- if (irq_found == -1)
-- irq_found = NO_IRQ;
--out:
-- spin_unlock_irq(&irq_controller_lock);
--
- up(&probe_sem);
-
- return irq_found;
---- linux-2.6.5/arch/arm/kernel/bios32.c~heh 2004-04-03 22:36:56.000000000 -0500
-+++ linux-2.6.5/arch/arm/kernel/bios32.c 2004-04-30 20:57:36.000000000 -0400
-@@ -565,8 +565,6 @@
- if (hw->postinit)
- hw->postinit();
-
-- pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq);
--
- list_for_each_entry(sys, &hw->buses, node) {
- struct pci_bus *bus = sys->bus;
-
-@@ -581,6 +579,11 @@
- pci_bus_assign_resources(bus);
-
- /*
-+ * Fixup IRQs.
-+ */
-+ pci_bus_fixup_irqs(bus, pcibios_swizzle, pcibios_map_irq);
-+
-+ /*
- * Tell drivers about devices found.
- */
- pci_bus_add_devices(bus);
---- linux-2.6.5/arch/arm/kernel/traps.c~heh 2004-04-03 22:36:57.000000000 -0500
-+++ linux-2.6.5/arch/arm/kernel/traps.c 2004-04-30 20:57:36.000000000 -0400
-@@ -206,33 +206,43 @@
- c_backtrace(fp, 0x10);
- }
-
--spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
--
--/*
-- * This function is protected against re-entrancy.
-- */
--NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
-+static void __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
- {
-- struct task_struct *tsk = current;
-+ struct task_struct *tsk = thread->task;
- static int die_counter;
-
-- console_verbose();
-- spin_lock_irq(&die_lock);
-- bust_spinlocks(1);
--
- printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter);
- print_modules();
- printk("CPU: %d\n", smp_processor_id());
- show_regs(regs);
- printk("Process %s (pid: %d, stack limit = 0x%p)\n",
-- tsk->comm, tsk->pid, tsk->thread_info + 1);
-+ tsk->comm, tsk->pid, thread + 1);
-
- if (!user_mode(regs) || in_interrupt()) {
- dump_mem("Stack: ", regs->ARM_sp, 8192+(unsigned long)tsk->thread_info);
- dump_backtrace(regs, tsk);
- dump_instr(regs);
- }
-+}
-+
-+void nmi_watchdog(struct thread_info *thread, struct pt_regs *regs)
-+{
-+ __die("NMI watchdog", 0, thread, regs);
-+}
-
-+spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
-+
-+/*
-+ * This function is protected against re-entrancy.
-+ */
-+NORET_TYPE void die(const char *str, struct pt_regs *regs, int err)
-+{
-+ struct thread_info *thread = current_thread_info();
-+
-+ console_verbose();
-+ spin_lock_irq(&die_lock);
-+ bust_spinlocks(1);
-+ __die(str, err, thread, regs);
- bust_spinlocks(0);
- spin_unlock_irq(&die_lock);
- do_exit(SIGSEGV);
---- linux-2.6.5/arch/arm/Kconfig~heh 2004-04-03 22:37:07.000000000 -0500
-+++ linux-2.6.5/arch/arm/Kconfig 2004-04-30 20:57:36.000000000 -0400
-@@ -297,7 +297,7 @@
-
- config CPU_FREQ
- bool "Support CPU clock change (EXPERIMENTAL)"
-- depends on (ARCH_SA1100 || ARCH_INTEGRATOR) && EXPERIMENTAL
-+ depends on (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_PXA) && EXPERIMENTAL
- help
- CPU clock scaling allows you to change the clock speed of the
- running CPU on the fly. This is a nice method to save battery power,
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/fastfpe/entry.S 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,294 @@
-+/*
-+At entry the registers contain the following information:
-+
-+r14 return address for undefined exception return
-+r9 return address for return from exception
-+r13 user registers on stack, offset 0 up to offset 4*15 contains
-+ registers r0..15, then the psr
-+r10 FP workspace 35 words (init, reg[8][4], fpsr, fpcr)
-+
-+*/
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .data
-+fp_const:
-+ .word 0, 0x00000000, 0, 0x80000000 @ 0
-+ .word 0, 0x80000000, 0, 0 @ 1
-+ .word 0, 0x80000000, 0, 1 @ 2
-+ .word 0, 0xc0000000, 0, 1 @ 3
-+ .word 0, 0x80000000, 0, 2 @ 4
-+ .word 0, 0xa0000000, 0, 2 @ 5
-+ .word 0, 0x80000000, 0, -1 @ 0.5
-+ .word 0, 0xa0000000, 0, 3 @ 10
-+fp_undef:
-+ .word 0
-+fp_cond:
-+ .word 0xf0f0 @ eq
-+ .word 0x0f0f @ ne
-+ .word 0xcccc @ cs
-+ .word 0x3333 @ cc
-+ .word 0xff00 @ mi
-+ .word 0x00ff @ pl
-+ .word 0xaaaa @ vs
-+ .word 0x5555 @ vc
-+ .word 0x0c0c @ hi
-+ .word 0xf3f3 @ ls
-+ .word 0xaa55 @ ge
-+ .word 0x55aa @ lt
-+ .word 0x0a05 @ gt
-+ .word 0xf5fa @ le
-+ .word 0xffff @ al
-+ .word 0x0000 @ nv
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .text
-+ .globl fastfpe_enter
-+fastfpe_enter:
-+ ldr r4,=fp_undef
-+ str r14,[r4] @ to free one register
-+ add r10,r10,#4 @ to make the code simpler
-+ mov r4, r0 @ r4=trapped instruction
-+ and r1,r4,#0x00000f00 @ r1=coprocessor << 8
-+next_enter:
-+ cmp r1,#1<<8 @ copro 1 ?
-+ beq copro_1
-+ cmp r1,#2<<8
-+ movne pc,r14
-+
-+copro_2:
-+ and r1,r4,#0x0f000000
-+ cmp r1,#0x0c000000 @ CPDT with post indexing
-+ cmpne r1,#0x0d000000 @ CPDT with pre indexing
-+ beq CPDT_M_enter
-+ mov pc,r14
-+
-+copro_1:
-+ and r1,r4,#0x0f000000
-+ cmp r1,#0x0e000000 @ CPDO
-+ beq CPDO_CPRT_enter
-+ cmp r1,#0x0c000000 @ CPDT with post indexing
-+ cmpne r1,#0x0d000000 @ CPDT with pre indexing
-+ beq CPDT_1_enter
-+ mov pc,r14
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl fastfpe_next
-+fastfpe_next:
-+ ldr r5,[r13,#60]
-+next_after_cond:
-+__x1:
-+ ldrt r4,[r5],#4
-+
-+ ldr r0,=fp_cond @ check condition of next instruction
-+ ldr r1,[r13,#64] @ psr containing flags
-+ mov r2,r4,lsr#28
-+ mov r1,r1,lsr#28
-+ ldr r0,[r0,r2,lsl#2]
-+ mov r0,r0,lsr r1
-+ tst r0,#1
-+ beq next_after_cond @ must not necessarily have been an
-+ @ FP instruction !
-+ and r1,r4,#0x0f000000 @ Test for copro instruction
-+ cmp r1,#0x0c000000
-+ rsbgts r0,r1,#0x0e000000 @ cmpgt #0x0e000000,r1
-+ movlt pc,r9 @ next is no copro instruction, return
-+
-+ ands r1,r4,#0x00000f00 @ r1 = coprocessor << 8
-+ cmpne r1,#3<<8
-+ movge pc,r9 @ copro = 0 or >=3, return
-+
-+ str r5,[r13,#60] @ save updated pc
-+ b next_enter
-+
-+/*---------------------------------------------------------------------------*/
-+
-+undefined:
-+ ldr r4,=fp_undef
-+ ldr pc,[r4]
-+
-+/*---------------------------------------------------------------------------*/
-+
-+CPDT_1_enter:
-+ and r5,r4,#0x000f0000 @ r5=base register number << 16
-+ ldr r6,[r13,r5,lsr#14] @ r6=base address
-+ cmp r5,#0x000f0000 @ base register = pc ?
-+ addeq r6,r6,#4
-+ and r7,r4,#0x000000ff @ r7=offset value
-+
-+ tst r4,#0x00800000 @ up or down?
-+ addne r7,r6,r7,lsl#2
-+ subeq r7,r6,r7,lsl#2 @ r6=base address +/- offset
-+ tst r4,#0x01000000 @ preindexing ?
-+ movne r6,r7
-+ tst r4,#0x00200000 @ write back ?
-+ cmpne r5,#0x000f0000 @ base register = pc ?
-+ strne r7,[r13,r5,lsr#14]
-+
-+ and r0,r4,#0x00007000 @ r0=fp register number << 12
-+ add r0,r10,r0,lsr#8 @ r0=address of fp register
-+ mov r1,#0
-+ tst r4,#0x00008000
-+ orrne r1,r1,#1 @ T0
-+ tst r4,#0x00400000
-+ orrne r1,r1,#2 @ T1
-+ tst r4,#0x00100000
-+ orrne r1,r1,#4 @ L/S
-+
-+ add pc,pc,r1,lsl#2
-+ mov r0,r0
-+ b CPDT_store_single @ these functions get
-+ b CPDT_store_double @ r0=address of fp register
-+ b CPDT_store_extended @ r6=address of data
-+ b undefined @ CPDT_store_decimal
-+ b CPDT_load_single
-+ b CPDT_load_double
-+ b CPDT_load_extended
-+ b undefined @ CPDT_load_decimal
-+
-+/*---------------------------------------------------------------------------*/
-+
-+CPDT_M_enter:
-+ and r5,r4,#0x000f0000 @ r5=base register number << 16
-+ ldr r6,[r13,r5,lsr#14] @ r6=base address
-+ cmp r5,#0x000f0000 @ base register = pc ?
-+ addeq r6,r6,#4
-+ and r7,r4,#0x000000ff @ r7=offset value
-+
-+ tst r4,#0x00800000 @ up or down?
-+ addne r7,r6,r7,lsl#2
-+ subeq r7,r6,r7,lsl#2 @ r7=base address +/- offset
-+ tst r4,#0x01000000 @ preindexing ?
-+ movne r6,r7
-+ tst r4,#0x00200000 @ write back ?
-+ cmpne r5,#0x000f0000 @ base register = pc ?
-+ strne r7,[r13,r5,lsr#14]
-+
-+ and r0,r4,#0x00007000 @ r0=fp register number << 12
-+ and r1,r4,#0x00008000
-+ mov r1,r1,lsr#15 @ N0
-+ and r2,r4,#0x00400000
-+ orrs r1,r1,r2,lsr#21 @ N1
-+ addeq r1,r1,#4 @ r1=register count
-+
-+ tst r4,#0x00100000 @ load/store
-+ beq CPDT_sfm
-+ b CPDT_lfm
-+
-+/*---------------------------------------------------------------------------*/
-+
-+CPDO_CPRT_enter:
-+ tst r4,#0x00000010
-+ bne CPRT_enter
-+
-+ and r0,r4,#0x00007000
-+ add r0,r10,r0,lsr#8 @ r0=address of Fd
-+ and r1,r4,#0x00070000
-+ add r1,r10,r1,lsr#12 @ r1=address of Fn
-+ tst r4,#0x00000008
-+ bne CPDO_const
-+ and r2,r4,#0x00000007
-+ add r2,r10,r2,lsl#4 @ r2=address of Fm
-+
-+CPDO_constback:
-+ and r3,r4,#0x00f00000
-+ tst r4,#0x00008000
-+ orrne r3,r3,#0x01000000
-+
-+ add pc,pc,r3,lsr#18
-+ mov r0,r0
-+ b CPDO_adf
-+ b CPDO_muf
-+ b CPDO_suf
-+ b CPDO_rsf
-+ b CPDO_dvf
-+ b CPDO_rdf
-+ b undefined
-+ b undefined
-+ b undefined @ CPDO_rmf
-+ b CPDO_muf
-+ b CPDO_dvf
-+ b CPDO_rdf
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b CPDO_mvf
-+ b CPDO_mnf
-+ b CPDO_abs
-+ b CPDO_rnd
-+ b CPDO_sqt
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b CPDO_rnd
-+ b fastfpe_next
-+
-+CPDO_const:
-+ ldr r2,=fp_const
-+ and r3,r4,#0x00000007
-+ add r2,r2,r3,lsl#4
-+ b CPDO_constback
-+
-+/*---------------------------------------------------------------------------*/
-+
-+CPRT_enter:
-+ and r0,r4,#0x0000f000 @ r0=Rd<<12
-+ and r1,r4,#0x00070000
-+ add r1,r10,r1,lsr#12 @ r1=address of Fn
-+ tst r4,#0x00000008
-+ bne CPRT_const
-+ and r2,r4,#0x00000007
-+ add r2,r10,r2,lsl#4 @ r2=address of Fm
-+
-+CPRT_constback:
-+ and r3,r4,#0x00f00000
-+
-+ add pc,pc,r3,lsr#18
-+ mov r0,r0
-+ b CPRT_flt
-+ b CPRT_fix
-+ b CPRT_wfs
-+ b CPRT_rfs
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b CPRT_cmf
-+ b undefined
-+ b CPRT_cnf
-+ b undefined
-+ b CPRT_cmf
-+ b undefined
-+ b CPRT_cnf
-+
-+CPRT_const:
-+ ldr r2,=fp_const
-+ and r3,r4,#0x00000007
-+ add r2,r2,r3,lsl#4
-+ b CPRT_constback
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ @ The fetch of the next instruction to emulate could fault
-+
-+ .section .fixup,"ax"
-+ .align
-+__f1:
-+ mov pc,r9
-+ .previous
-+ .section __ex_table,"a"
-+ .align 3
-+ .long __x1,__f1
-+ .previous
-+
-+/*---------------------------------------------------------------------------*/
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/fastfpe/module.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,62 @@
-+/*
-+ Fast Floating Point Emulator
-+ (c) Peter Teichmann <mail@peter-teichmann.de>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2 of the License, or
-+ (at your option) any later version.
-+
-+ 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/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+
-+#ifndef MODULE
-+#define kern_fp_enter fp_enter
-+
-+extern char fpe_type[];
-+#endif
-+
-+static void (*orig_fp_enter)(void); /* old kern_fp_enter value */
-+extern void (*kern_fp_enter)(void); /* current FP handler */
-+extern void fastfpe_enter(void); /* forward declarations */
-+
-+static int __init fpe_init(void)
-+{
-+ if (fpe_type[0] && strcmp(fpe_type, "fastfpe"))
-+ return 0;
-+
-+ printk("Fast Floating Point Emulator V0.9 (c) Peter Teichmann.\n");
-+
-+ /* Save pointer to the old FP handler and then patch ourselves in */
-+ orig_fp_enter = kern_fp_enter;
-+ kern_fp_enter = fastfpe_enter;
-+
-+ return 0;
-+}
-+
-+static void __exit fpe_exit(void)
-+{
-+ /* Restore the values we saved earlier. */
-+ kern_fp_enter = orig_fp_enter;
-+}
-+
-+module_init(fpe_init);
-+module_exit(fpe_exit);
-+
-+MODULE_AUTHOR("Peter Teichmann <mail@peter-teichmann.de>");
-+MODULE_DESCRIPTION("Fast floating point emulator with full precision");
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/fastfpe/CPDO.S 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,682 @@
-+/*
-+The FP structure has 4 words reserved for each register, the first is used just
-+for the sign in bit 31, the second and third are for the mantissa (unsigned
-+integer, high 32 bit first) and the fourth is the exponent (signed integer).
-+The mantissa is always normalized.
-+
-+If the exponent is 0x80000000, that is the most negative value, the number
-+represented is 0 and both mantissa words are also 0.
-+
-+If the exponent is 0x7fffffff, that is the biggest positive value, the number
-+represented is infinity if the high 32 mantissa bit are also 0, otherwise it is
-+a NaN. The low 32 mantissa bit are 0 if the number represented is infinity.
-+
-+Decimal and packed decimal numbers are not supported yet.
-+
-+The parameters to these functions are r0=destination pointer, r1 and r2
-+source pointers. r4 is the instruction. They may use r0-r8 and r14. They return
-+to fastfpe_next, except CPDO_rnf_core which expects the return address in r14.
-+*/
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_adf
-+CPDO_adf:
-+ ldmia r1,{r1,r3,r5,r7}
-+ ldmia r2,{r2,r4,r6,r8}
-+
-+ cmp r7,#0x7fffffff
-+ cmpne r8,#0x7fffffff
-+ beq CPDO_adf_extra
-+
-+ cmp r1,r2
-+ bne CPDO_suf_s
-+
-+CPDO_adf_s:
-+ subs r2,r7,r8
-+ bge CPDO_adf_2nd
-+
-+ mov r7,r8
-+ rsb r2,r2,#0
-+ cmp r2,#32
-+ ble CPDO_adf_1st2
-+
-+ sub r2,r2,#32
-+ cmp r2,#32
-+ movgt r2,#32
-+ mov r5,r3,lsr r2
-+ mov r3,#0
-+ b CPDO_adf_add
-+
-+CPDO_adf_1st2:
-+ rsb r8,r2,#32
-+ mov r5,r5,lsr r2
-+ orr r5,r5,r3,lsl r8
-+ mov r3,r3,lsr r2 @ 1. op normalized
-+ b CPDO_adf_add
-+
-+CPDO_adf_2nd:
-+ cmp r2,#32
-+ ble CPDO_adf_2nd2
-+
-+ sub r2,r2,#32
-+ cmp r2,#32
-+ movgt r2,#32
-+ mov r6,r4,lsr r2
-+ mov r4,#0
-+ b CPDO_adf_add
-+
-+CPDO_adf_2nd2:
-+ rsb r8,r2,#32
-+ mov r6,r6,lsr r2
-+ orr r6,r6,r4,lsl r8
-+ mov r4,r4,lsr r2 @ 2. op normalized
-+
-+CPDO_adf_add:
-+ adds r5,r5,r6
-+ adcs r3,r3,r4 @ do addition
-+ bcc CPDO_adf_end
-+
-+ add r7,r7,#1
-+ movs r3,r3,rrx
-+ mov r5,r5,rrx @ correct for overflow
-+
-+CPDO_adf_end:
-+ cmp r7,#0x20000000
-+ bge CPDO_inf
-+
-+ stmia r0,{r1,r3,r5,r7}
-+ b fastfpe_next
-+
-+CPDO_adf_extra:
-+ cmp r7,#0x7fffffff @ was it the 1st ?
-+ bne CPDO_infnan_2 @ no it was the 2nd
-+ cmp r8,#0x7fffffff @ if 1st, 2nd too ?
-+ bne CPDO_infnan_1 @ no only 1st
-+ cmp r3,#0
-+ cmpeq r4,#0
-+ bne CPDO_nan_12
-+ b CPDO_inf
-+
-+/*---------------------------------------------------------------------------*/
-+
-+CPDO_infnan_1:
-+ stmia r0,{r1,r3,r5,r7}
-+ b fastfpe_next
-+
-+CPDO_infnan_2:
-+ stmia r0,{r2,r4,r6,r8}
-+ b fastfpe_next
-+
-+CPDO_nan_12:
-+ orr r2,r3,r4
-+ b CPDO_inf_1
-+
-+CPDO_nan:
-+ mov r2,#0x40000000 @ create non signalling NaN
-+ b CPDO_inf_1
-+
-+CPDO_inf:
-+ mov r2,#0
-+CPDO_inf_1:
-+ mov r3,#0
-+ mov r4,#0x7fffffff
-+CPDO_store_1234:
-+ stmia r0,{r1,r2,r3,r4}
-+ b fastfpe_next
-+
-+CPDO_zero:
-+ mov r1,#0
-+CPDO_zero_1:
-+ mov r2,#0
-+ mov r3,#0
-+ mov r4,#0x80000000
-+ stmia r0,{r1,r2,r3,r4}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_suf
-+CPDO_suf:
-+ ldmia r1,{r1,r3,r5,r7}
-+ ldmia r2,{r2,r4,r6,r8}
-+
-+CPDO_suf_l:
-+ cmp r7,#0x7fffffff
-+ cmpne r8,#0x7fffffff
-+ beq CPDO_suf_extra
-+
-+ cmp r1,r2
-+ bne CPDO_adf_s
-+
-+CPDO_suf_s:
-+ subs r2,r7,r8 @ determine greater number
-+ bgt CPDO_suf_2nd @ first number is greater
-+ blt CPDO_suf_1st @ second number is greater
-+ cmp r3,r4 @ also mantissa is important
-+ cmpeq r5,r6
-+ bhi CPDO_suf_2nd @ first number is greater
-+ beq CPDO_zero
-+
-+CPDO_suf_1st:
-+ eor r1,r1,#0x80000000 @ second number is greater, invert sign
-+ mov r7,r8
-+ rsb r2,r2,#0
-+ cmp r2,#32
-+ ble CPDO_suf_1st2
-+
-+ sub r2,r2,#32
-+ cmp r2,#32
-+ movgt r2,#32
-+ mov r5,r3,lsr r2
-+ mov r3,#0
-+ b CPDO_suf_1st_sub
-+
-+CPDO_suf_1st2:
-+ rsb r8,r2,#32
-+ mov r5,r5,lsr r2
-+ orr r5,r5,r3,lsl r8
-+ mov r3,r3,lsr r2 @ 1. op normalized
-+
-+CPDO_suf_1st_sub:
-+ subs r5,r6,r5 @ do subtraction
-+ sbc r3,r4,r3
-+ b CPDO_suf_norm
-+
-+CPDO_suf_2nd:
-+ cmp r2,#32
-+ ble CPDO_suf_2nd2
-+
-+ sub r2,r2,#32
-+ cmp r2,#32
-+ movgt r2,#32
-+ mov r6,r4,lsr r2
-+ mov r4,#0
-+ b CPDO_suf_2nd_sub
-+
-+CPDO_suf_2nd2:
-+ rsb r8,r2,#32
-+ mov r6,r6,lsr r2
-+ orr r6,r6,r4,lsl r8
-+ mov r4,r4,lsr r2 @ 2. op normalized
-+
-+CPDO_suf_2nd_sub:
-+ subs r5,r5,r6
-+ sbc r3,r3,r4 @ do subtraction
-+
-+CPDO_suf_norm:
-+ teq r3,#0 @ normalize 32bit
-+ moveq r3,r5
-+ moveq r5,#0
-+ subeq r7,r7,#32
-+
-+ cmp r3,#0x00010000 @ 16bit
-+ movcc r3,r3,lsl#16
-+ orrcc r3,r3,r5,lsr#16
-+ movcc r5,r5,lsl#16
-+ subcc r7,r7,#16
-+
-+ cmp r3,#0x01000000 @ 8bit
-+ movcc r3,r3,lsl#8
-+ orrcc r3,r3,r5,lsr#24
-+ movcc r5,r5,lsl#8
-+ subcc r7,r7,#8
-+
-+ cmp r3,#0x10000000 @ 4bit
-+ movcc r3,r3,lsl#4
-+ orrcc r3,r3,r5,lsr#28
-+ movcc r5,r5,lsl#4
-+ subcc r7,r7,#4
-+
-+ cmp r3,#0x40000000 @ 2bit
-+ movcc r3,r3,lsl#2
-+ orrcc r3,r3,r5,lsr#30
-+ movcc r5,r5,lsl#2
-+ subcc r7,r7,#2
-+
-+ cmp r3,#0x80000000 @ 1bit
-+ movcc r3,r3,lsl#1
-+ orrcc r3,r3,r5,lsr#31
-+ movcc r5,r5,lsl#1
-+ subcc r7,r7,#1
-+
-+ cmp r7,#0xe0000000
-+ ble CPDO_zero_1
-+
-+ stmia r0,{r1,r3,r5,r7}
-+ b fastfpe_next
-+
-+CPDO_suf_extra:
-+ cmp r7,#0x7fffffff @ was it the 1st ?
-+ eorne r2,r2,#0x80000000 @ change sign, might have been INF
-+ bne CPDO_infnan_2 @ no it was the 2nd
-+ cmp r8,#0x7fffffff @ if 1st, 2nd too ?
-+ bne CPDO_infnan_1 @ no only 1st
-+ cmp r3,#0
-+ cmpeq r4,#0
-+ bne CPDO_nan_12
-+ b CPDO_nan @ here is difference with adf !
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_rsf
-+CPDO_rsf:
-+ mov r3,r2
-+ ldmia r1,{r2,r4,r6,r8}
-+ ldmia r3,{r1,r3,r5,r7}
-+ b CPDO_suf_l
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_muf
-+CPDO_muf:
-+ ldmia r1,{r1,r3,r5,r7}
-+ ldmia r2,{r2,r4,r6,r8}
-+
-+ cmp r7,#0x7fffffff
-+ cmpne r8,#0x7fffffff
-+ beq CPDO_muf_extra
-+
-+ eor r1,r1,r2
-+ adds r8,r7,r8
-+ bvs CPDO_zero_1
-+
-+ umull r7,r2,r3,r4
-+ umull r14,r3,r6,r3
-+ adds r7,r7,r3 @ r2|r7|r14 = r2|r7|#0 + #0|r3|r14
-+ adc r2,r2,#0
-+ umull r4,r3,r5,r4
-+ adds r14,r14,r4 @ r2|r7|r14 += #0|r3|r4
-+ adcs r7,r7,r3
-+ adc r2,r2,#0
-+ umull r4,r3,r5,r6
-+ adds r14,r14,r3 @ r2|r7|r14 += #0|#0|r3
-+ adcs r7,r7,#0
-+ adcs r2,r2,#0
-+
-+ bpl CPDO_muf_norm
-+
-+ add r8,r8,#1
-+ b CPDO_muf_end
-+
-+CPDO_muf_norm:
-+ adds r14,r14,r14
-+ adcs r7,r7,r7
-+ adcs r2,r2,r2
-+
-+CPDO_muf_end:
-+ cmp r8,#0x20000000
-+ bge CPDO_inf
-+ cmp r8,#0xe0000000
-+ ble CPDO_zero_1
-+ stmia r0,{r1,r2,r7,r8}
-+ b fastfpe_next
-+
-+CPDO_muf_extra:
-+ cmp r7,#0x7fffffff @ was it the first?
-+ bne CPDO_muf_extra_2nd @ no, so it was the second
-+ cmp r8,#0x7fffffff @ yes, second too?
-+ bne CPDO_muf_extra_1st @ no, only first
-+ orr r3,r3,r4 @ if both inf -> inf, otherwise nan
-+ eor r1,r1,r2 @ sign for the inf case
-+ b CPDO_infnan_1
-+
-+CPDO_muf_extra_1st:
-+ cmp r3,#0 @ is it a nan?
-+ bne CPDO_infnan_1
-+ cmp r8,#0x80000000 @ is the second 0?
-+ beq CPDO_nan
-+ eor r1,r1,r2 @ correct sign for inf
-+ b CPDO_inf
-+
-+CPDO_muf_extra_2nd:
-+ cmp r4,#0 @ is it a nan?
-+ bne CPDO_infnan_2
-+ cmp r7,#0x80000000 @ is the first 0?
-+ beq CPDO_nan
-+ eor r1,r1,r2 @ correct sign for inf
-+ b CPDO_inf
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_dvf
-+CPDO_dvf:
-+ ldmia r1,{r1,r3,r5,r7}
-+ ldmia r2,{r2,r4,r6,r8}
-+
-+CPDO_dvf_l:
-+ cmp r7,#0x7fffffff
-+ cmpne r8,#0x7fffffff
-+ beq CPDO_dvf_extra
-+ cmp r8,#0x80000000
-+ beq CPDO_dvf_by0
-+
-+ eor r1,r1,r2
-+ cmp r7,#0x80000000
-+ beq CPDO_zero_1
-+
-+ sub r8,r7,r8
-+
-+ mov r2,#0
-+ mov r7,#1
-+
-+ cmp r3,r4
-+ cmpeq r5,r6
-+ bcs CPDO_dvf_loop_
-+
-+ sub r8,r8,#1
-+
-+CPDO_dvf_loop:
-+ adds r5,r5,r5
-+ adcs r3,r3,r3
-+ bcs CPDO_dvf_anyway
-+CPDO_dvf_loop_:
-+ subs r5,r5,r6
-+ sbcs r3,r3,r4
-+ bcs CPDO_dvf_okay
-+
-+ adds r5,r5,r6
-+ adc r3,r3,r4
-+ adds r7,r7,r7
-+ adcs r2,r2,r2
-+ bcc CPDO_dvf_loop
-+ b CPDO_dvf_end
-+
-+CPDO_dvf_anyway:
-+ adcs r7,r7,r7
-+ adcs r2,r2,r2
-+ bcs CPDO_dvf_end
-+ subs r5,r5,r6
-+ sbc r3,r3,r4
-+ b CPDO_dvf_loop
-+
-+CPDO_dvf_okay:
-+ adcs r7,r7,r7
-+ adcs r2,r2,r2
-+ bcc CPDO_dvf_loop
-+
-+CPDO_dvf_end:
-+ b CPDO_muf_end
-+
-+CPDO_dvf_by0:
-+ cmp R7,#0x80000000
-+ beq CPDO_nan @ first also 0 -> nan
-+ eor r1,r1,r2 @ otherwise calculatesign for inf
-+ b CPDO_inf
-+
-+CPDO_dvf_extra:
-+ cmp r7,#0x7fffffff @ was it the first?
-+ bne CPDO_dvf_extra_2nd @ no, so it was the second
-+ cmp r8,#0x7fffffff @ yes, second too?
-+ bne CPDO_dvf_extra_1st @ no, only first
-+ orrs r3,r3,r4
-+ beq CPDO_nan @ if both inf -> create nan
-+ b CPDO_nan_12 @ otherwise keep nan
-+
-+CPDO_dvf_extra_1st:
-+ eor r1,r1,r2 @ correct sign for inf
-+ b CPDO_infnan_1
-+
-+CPDO_dvf_extra_2nd:
-+ cmp r4,#0 @ is it a nan?
-+ bne CPDO_infnan_2
-+ eor r1,r1,r2 @ correct sign for zero
-+ b CPDO_zero_1
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_rdf
-+CPDO_rdf:
-+ mov r3,r2
-+ ldmia r1,{r2,r4,r6,r8}
-+ ldmia r3,{r1,r3,r5,r7}
-+ b CPDO_dvf_l
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_rmf
-+CPDO_rmf:
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_mvf
-+CPDO_mvf:
-+ ldmia r2,{r1,r2,r3,r4}
-+ stmia r0,{r1,r2,r3,r4}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_mnf
-+CPDO_mnf:
-+ ldmia r2,{r1,r2,r3,r4}
-+ eor r1,r1,#0x80000000
-+ stmia r0,{r1,r2,r3,r4}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_abs
-+CPDO_abs:
-+ ldmia r2,{r1,r2,r3,r4}
-+ bic r1,r1,#0x80000000
-+ stmia r0,{r1,r2,r3,r4}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_sqt
-+CPDO_sqt:
-+ ldmia r2,{r1,r2,r3,r4}
-+ cmp r1,#0
-+ bne CPDO_nan
-+ cmp r4,#0x7fffffff
-+ beq CPDO_store_1234
-+
-+ tst r4,r4,lsr#1 @carry=exponent bit 0
-+ bcc CPDO_sqt_exponenteven
-+ adds r3,r3,r3
-+ adcs r2,r2,r2 @carry is needed in loop!
-+CPDO_sqt_exponenteven:
-+ mov r4,r4,asr #1
-+ str r4,[r0,#12]
-+
-+ mov r4,#0x80000000
-+ mov r5,#0
-+ sub r2,r2,#0x80000000
-+
-+ mov r8,#0x40000000
-+ mov r14,#0x80000000
-+
-+ mov r1,#1
-+ b CPDO_sqt_loop1_first
-+CPDO_sqt_loop1:
-+ adds r3,r3,r3
-+ adcs r2,r2,r2
-+CPDO_sqt_loop1_first:
-+ add r6,r4,r8,lsr r1 @r7 const = r5
-+ bcs CPDO_sqt_loop1_1
-+ cmp r2,r6
-+ cmpeq r3,r5 @r5 for r7
-+ bcc CPDO_sqt_loop1_0
-+CPDO_sqt_loop1_1:
-+ orr r4,r4,r14,lsr r1
-+ subs r3,r3,r5 @r5 for r7
-+ sbc r2,r2,r6
-+CPDO_sqt_loop1_0:
-+ add r1,r1,#1
-+ cmp r1,#30
-+ ble CPDO_sqt_loop1
-+
-+ adds r3,r3,r3
-+ adcs r2,r2,r2
-+ bcs CPDO_sqt_between_1
-+ adds r7,r5,#0x80000000
-+ adc r6,r4,#0
-+ cmp r2,r6
-+ cmpeq r3,r7
-+ bcc CPDO_sqt_between_0
-+CPDO_sqt_between_1:
-+ orr r4,r4,#0x00000001
-+ subs r3,r3,r5
-+ sbc r2,r2,r4
-+ subs r3,r3,#0x80000000
-+ sbc r2,r2,#0
-+CPDO_sqt_between_0:
-+ mov r1,#0
-+
-+CPDO_sqt_loop2:
-+ adds r3,r3,r3
-+ adcs r2,r2,r2
-+ bcs CPDO_sqt_loop2_1
-+ adds r7,r5,r8,lsr r1
-+ adc r6,r4,#0
-+ cmp r2,r6
-+ cmpeq r3,r7
-+ bcc CPDO_sqt_loop2_0
-+CPDO_sqt_loop2_1:
-+ orr r5,r5,r14,lsr r1
-+ subs r3,r3,r5
-+ sbc r2,r2,r4
-+ subs r3,r3,r8,lsr r1
-+ sbc r2,r2,#0
-+CPDO_sqt_loop2_0:
-+ add r1,r1,#1
-+ cmp r1,#30
-+ ble CPDO_sqt_loop2
-+
-+ adds r3,r3,r3
-+ adcs r2,r2,r2
-+ bcs CPDO_sqt_after_1
-+ cmp r2,r6
-+ cmpeq r3,r7
-+ bcc CPDO_sqt_after_0
-+CPDO_sqt_after_1:
-+ orr r5,r5,#0x00000001
-+CPDO_sqt_after_0:
-+
-+ mov r1,#0
-+ stmia r0,{r1,r4,r5}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_rnd
-+CPDO_rnd:
-+ ldmia r2,{r1,r2,r3,r5}
-+ bl CPDO_rnd_core
-+
-+CPDO_rnd_store:
-+ stmia r0,{r1,r2,r3,r5}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_rnd_core
-+CPDO_rnd_core:
-+ and r4,r4,#0x00000060
-+ add pc,pc,r4,lsr#3
-+ mov r0,r0
-+ b CPDO_rnd_N
-+ b CPDO_rnd_P
-+ b CPDO_rnd_M
-+ b CPDO_rnd_Z
-+
-+CPDO_rnd_N:
-+ cmp r5,#-1
-+ blt CPDO_rnd_zero
-+ cmp r5,#63
-+ movge pc,r14
-+ mov r4,#0x40000000
-+ cmp r5,#31
-+ bge CPDO_rnd_N_2
-+
-+ adds r2,r2,r4,lsr r5
-+ bcc CPDO_rnd_end
-+ b CPDO_rnd_end_norm
-+
-+CPDO_rnd_N_2:
-+CPDO_rnd_P_2:
-+ sub r6,r5,#32
-+ adds r3,r3,r4,ror r6 @ror ist needed to handle a -1 correctly
-+ adcs r2,r2,#0
-+ bcc CPDO_rnd_end
-+ b CPDO_rnd_end_norm
-+
-+CPDO_rnd_P:
-+ tst r1,#0x80000000
-+ bne CPDO_rnd_M_entry
-+CPDO_rnd_P_entry:
-+ cmp r5,#0
-+ blt CPDO_rnd_P_small
-+ cmp r5,#63
-+ movge pc,r14
-+ mov r4,#0x7fffffff
-+ cmp r5,#32
-+ bge CPDO_rnd_P_2
-+
-+ adds r3,r3,#0xffffffff
-+ adcs r2,r2,r4,lsr r5
-+ bcc CPDO_rnd_end
-+ b CPDO_rnd_end_norm
-+
-+CPDO_rnd_P_small:
-+ cmp r5,#0x80000000
-+ moveq pc,r14
-+ b CPDO_rnd_one
-+
-+CPDO_rnd_M:
-+ tst r1,#0x80000000
-+ bne CPDO_rnd_P_entry
-+CPDO_rnd_M_entry:
-+ cmp r5,#0
-+ blt CPDO_rnd_zero
-+ cmp r5,#63
-+ movge pc,r14
-+
-+ b CPDO_rnd_end
-+
-+CPDO_rnd_Z:
-+ cmp r5,#0
-+ blt CPDO_rnd_zero
-+ cmp r5,#63
-+ movge pc,r14
-+ b CPDO_rnd_end
-+
-+CPDO_rnd_end_norm:
-+ add r5,r5,#1
-+ movs r2,r2,rrx
-+ mov r3,r3,rrx
-+CPDO_rnd_end:
-+ rsbs r4,r5,#31
-+ bmi CPDO_rnd_end_2
-+ mov r3,#0
-+ mov r2,r2,lsr r4
-+ mov r2,r2,lsl r4
-+ mov pc,r14
-+
-+CPDO_rnd_end_2:
-+ rsb r4,r5,#63
-+ mov r3,r3,lsr r4
-+ mov r3,r3,lsl r4
-+ mov pc,r14
-+
-+CPDO_rnd_one:
-+ mov r2,#0x80000000
-+ mov r3,#0
-+ mov r5,#0
-+ mov pc,r14
-+
-+CPDO_rnd_zero:
-+ mov r1,#0
-+ mov r2,#0
-+ mov r3,#0
-+ mov r5,#0x80000000
-+ mov pc,r14
-+
-+/*---------------------------------------------------------------------------*/
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/fastfpe/CPRT.S 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,185 @@
-+/*
-+The FP structure has 4 words reserved for each register, the first is used
-+just
-+for the sign in bit 31, the second and third are for the mantissa (unsigned
-+integer, high 32 bit first) and the fourth is the exponent (signed integer).
-+The mantissa is always normalized.
-+
-+If the exponent is 0x80000000, that is the most negative value, the number
-+represented is 0 and both mantissa words are also 0.
-+
-+If the exponent is 0x7fffffff, that is the biggest positive value, the
-+number
-+represented is infinity if the high 32 mantissa bit are also 0, otherwise it
-+is
-+a NaN. The low 32 mantissa bit are 0 if the number represented is infinity.
-+
-+Decimal and packed decimal numbers are not supported yet.
-+*/
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .text
-+ .globl CPRT_flt
-+CPRT_flt:
-+ add r0,r13,r0,lsr#10
-+ ldr r2,[r0]
-+ mov r3,#0
-+ cmp r2,#0
-+ beq CPRT_flt_zero
-+
-+ ands r0,r2,#0x80000000
-+ rsbne r2,r2,#0
-+ mov r4,#31
-+
-+ cmp r2,#0x00010000
-+ movcc r2,r2,lsl#16
-+ subcc r4,r4,#16
-+
-+ cmp r2,#0x01000000
-+ movcc r2,r2,lsl#8
-+ subcc r4,r4,#8
-+
-+ cmp r2,#0x10000000
-+ movcc r2,r2,lsl#4
-+ subcc r4,r4,#4
-+
-+ cmp r2,#0x40000000
-+ movcc r2,r2,lsl#2
-+ subcc r4,r4,#2
-+
-+ cmp r2,#0x80000000
-+ movcc r2,r2,lsl#1
-+ subcc r4,r4,#1
-+
-+ stmia r1,{r0,r2,r3,r4}
-+ b fastfpe_next
-+
-+CPRT_flt_zero:
-+ mov r0,#0
-+ mov r4,#0x80000000
-+ stmia r1,{r0,r2,r3,r4}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPRT_fix
-+CPRT_fix:
-+ ldmia r2,{r1,r2,r3,r5}
-+ bl CPDO_rnd_core
-+
-+CPRT_back:
-+ add r0,r13,r0,lsr#10
-+ cmp r5,#0
-+ blt CPRT_int_zero
-+ cmp r5,#30
-+ bgt CPRT_overflow
-+
-+ rsb r5,r5,#31
-+ mov r2,r2,lsr r5
-+ tst r1,#0x80000000
-+ rsbne r2,r2,#0
-+
-+ str r2,[r0]
-+ b fastfpe_next
-+
-+CPRT_int_zero:
-+ mov r2,#0
-+ str r2,[r0]
-+ b fastfpe_next
-+
-+CPRT_overflow:
-+ mov r2,#0x80000000
-+ tst r1,#0x80000000
-+ subeq r2,r2,#1
-+ str r2,[r0]
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPRT_wfs
-+CPRT_wfs:
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPRT_rfs
-+CPRT_rfs:
-+ add r0,r13,r0,lsr#10
-+ mov r1,#0x02000000 @ Software Emulation, not Acorn FPE
-+ str r1,[r0]
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPRT_cmf
-+CPRT_cmf:
-+ ldmia r1,{r1,r3,r5,r7}
-+ ldmia r2,{r2,r4,r6,r8}
-+
-+CPRT_cmf_e:
-+ ldr r0,[r13,#16*4]
-+
-+ cmp r7,#0x7fffffff
-+ bic r0,r0,#0xf0000000
-+
-+ cmpeq r3,#0xffffffff
-+ beq CPRT_cmf_unordered
-+ cmp r8,#0x7fffffff
-+ cmpeq r4,#0xffffffff
-+ beq CPRT_cmf_unordered
-+
-+ cmp r1,r2
-+ beq CPRT_cmf_equalsign
-+ b CPRT_cmf_sign
-+
-+CPRT_cmf_equalsign:
-+ cmp r7,r8
-+ beq CPRT_cmf_equalexponent
-+ bgt CPRT_cmf_sign
-+ b CPRT_cmf_signb
-+
-+CPRT_cmf_equalexponent:
-+ cmp r3,r4
-+ cmpeq r5,r6
-+ beq CPRT_cmf_equal
-+ bhi CPRT_cmf_sign
-+ b CPRT_cmf_signb
-+
-+CPRT_cmf_sign:
-+ cmp r7,#0x80000000 @ (0.0 == -0.0)?
-+ cmpeq r7,r8
-+ beq CPRT_cmf_equal
-+ tst r1,#0x80000000
-+ orreq r0,r0,#0x20000000
-+ orrne r0,r0,#0x80000000
-+ str r0,[r13,#16*4]
-+ b fastfpe_next
-+
-+CPRT_cmf_signb:
-+ tst r1,#0x80000000
-+ orrne r0,r0,#0x20000000
-+ orreq r0,r0,#0x80000000
-+ str r0,[r13,#16*4]
-+ b fastfpe_next
-+
-+CPRT_cmf_equal:
-+ orr r0,r0,#0x60000000
-+ str r0,[r13,#16*4]
-+ b fastfpe_next
-+
-+CPRT_cmf_unordered:
-+ orr r0,r0,#0x10000000
-+ str r0,[r13,#16*4]
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPRT_cnf
-+CPRT_cnf:
-+ ldmia r1,{r1,r3,r5,r7}
-+ ldmia r2,{r2,r4,r6,r8}
-+ eor r2,r2,#0x80000000
-+ b CPRT_cmf_e
-+
-+/*---------------------------------------------------------------------------*/
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/fastfpe/CPDT.S 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,430 @@
-+/*
-+The FP structure has 4 words reserved for each register, the first is used just
-+for the sign in bit 31, the second and third are for the mantissa (unsigned
-+integer, high 32 bit first) and the fourth is the exponent (signed integer).
-+The mantissa is always normalized.
-+
-+If the exponent is 0x80000000, that is the most negative value, the number
-+represented is 0 and both mantissa words are also 0.
-+
-+If the exponent is 0x7fffffff, that is the biggest positive value, the number
-+represented is infinity if the high 32 mantissa bit are also 0, otherwise it is
-+a NaN. The low 32 mantissa bit are 0 if the number represented is infinity.
-+
-+Decimal and packed decimal numbers are not supported yet.
-+*/
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_load_single
-+CPDT_load_single:
-+ ldr r1,[r6]
-+
-+ and r2,r1,#0x80000000 @ r2 = sign
-+
-+ mov r5,r1,lsr#23
-+ bics r5,r5,#0x100
-+ beq CPDT_ls_e0 @ exponent = 0; zero/denormalized
-+ teq r5,#255
-+ beq CPDT_ls_e255 @ exponent = 255; infinity/NaN
-+
-+ sub r5,r5,#127 @ r5 = exponent, remove normalized bias
-+
-+ mov r3,r1,lsl#8
-+ orr r3,r3,#0x80000000
-+ mov r4,#0 @ r3,r4 = mantissa
-+
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+CPDT_ls_e0:
-+ movs r3,r1,lsl#9
-+ beq CPDT_load_zero
-+
-+ mov r5,#-127
-+
-+CPDT_ls_e0_norm:
-+ tst r3,#0x80000000
-+ subeq r5,r5,#1
-+ moveq r3,r3,lsl#1
-+ beq CPDT_ls_e0_norm
-+
-+ mov r4,#0
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+CPDT_ls_e255:
-+ mov r3,r1,lsl#9
-+ mov r4,#0
-+ mov r5,#0x7fffffff
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+CPDT_load_zero:
-+ mov r3,#0
-+ mov r4,#0
-+ mov r5,#0x80000000
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_load_double
-+CPDT_load_double:
-+ ldr r1,[r6]
-+ ldr r6,[r6,#4]
-+
-+ and r2,r1,#0x80000000 @ r2 = sign
-+
-+ mov r5,r1,lsr#20
-+ bics r5,r5,#0x800
-+ beq CPDT_ld_e0 @ exponent = 0; zero/denormalized
-+ add r4,r5,#1
-+ teq r4,#2048
-+ beq CPDT_ld_e2047 @ exponent = 2047; infinity/NaN
-+
-+ add r5,r5,#1
-+ sub r5,r5,#1024 @ r5 = exponent, remove normalized bias
-+
-+ mov r3,r1,lsl#11
-+ orr r3,r3,#0x80000000
-+ orr r3,r3,r6,lsr #21
-+ mov r4,r6,lsl#11 @ r3,r4 = mantissa
-+
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+CPDT_ld_e0:
-+ mov r3,r1,lsl#12
-+ orr r3,r3,r6,lsr#20
-+ movs r4,r6,lsl#12
-+ teqeq r3,#0
-+ beq CPDT_load_zero
-+
-+ mov r5,#1
-+ sub r5,r5,#1024
-+
-+CPDT_ld_e0_norm:
-+ tst r3,#0x80000000
-+ subeq r5,r5,#1
-+ moveqs r4,r4,lsl#1
-+ adceq r3,r3,r3
-+ beq CPDT_ld_e0_norm
-+
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+CPDT_ld_e2047:
-+ mov r3,r1,lsl#12
-+ orr r3,r3,r6,lsr#1
-+ bic r6,r6,#0x80000000
-+ orr r3,r3,r6 @ to get all fraction bits !
-+ mov r4,#0
-+ mov r5,#0x7fffffff
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_load_extended
-+CPDT_load_extended:
-+ ldr r1,[r6]
-+ ldr r3,[r6,#4]
-+ ldr r4,[r6,#8]
-+
-+ and r2,r1,#0x80000000
-+ bics r5,r1,#0x80000000
-+ beq CPDT_le_e0
-+ add r1,r5,#1
-+ teq r4,#32768
-+ beq CPDT_le_e32767
-+
-+ add r5,r5,#1
-+ sub r5,r5,#16384
-+
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+CPDT_le_e0:
-+ teq r3,#0
-+ teqeq r4,#0
-+ beq CPDT_load_zero
-+
-+ mov r5,#2
-+ sub r5,r5,#16384
-+ b CPDT_ld_e0_norm
-+
-+CPDT_le_e32767:
-+ mov r3,r3,lsl#1
-+ orr r3,r3,r4,lsr#1
-+ bic r4,r4,#0x80000000
-+ orr r3,r3,r4
-+ mov r5,#0x7fffffff
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_load_decimal
-+CPDT_load_decimal:
-+
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_store_single
-+CPDT_store_single:
-+ ldmia r0,{r1-r4}
-+
-+ cmp r4,#-127
-+ ble CPDT_ss_e0
-+ cmp r4,#128
-+ bge CPDT_ss_e255
-+
-+ adds r2,r2,#1<<7 @ round to nearest
-+ bcs CPDT_ss_rnd_ovfl @ very very seldom taken
-+
-+CPDT_ss_store:
-+ add r4,r4,#127
-+ orr r1,r1,r4,lsl#23
-+
-+ bic r2,r2,#0x80000000
-+ orr r1,r1,r2,lsr#8
-+
-+ str r1,[r6]
-+ b fastfpe_next
-+
-+CPDT_ss_rnd_ovfl:
-+ add r4,r4,#1
-+ cmp r4,#128
-+ bge CPDT_ss_e255
-+
-+ mov r2,#0x80000000
-+ mov r3,#0
-+ b CPDT_ss_store
-+
-+CPDT_ss_e0:
-+ cmp r4,#-150
-+ ble CPDT_ss_zero
-+
-+ add r4,r4,#126
-+CPDT_ss_unnormalize:
-+ mov r2,r2,lsr#1
-+ adds r4,r4,#1
-+ bne CPDT_ss_unnormalize
-+
-+ orr r1,r1,r2,lsr#8
-+
-+CPDT_ss_zero:
-+ str r1,[r6]
-+ b fastfpe_next
-+
-+CPDT_ss_e255:
-+ cmp r4,#0x7fffffff
-+ bne CPDT_ss_inf
-+ cmp r2,#0
-+ beq CPDT_ss_inf
-+
-+ orr r1,r1,#0x00200000 @ for safety so that it is not INF
-+ orr r1,r1,r2,lsr#9 @ get highest bit of mantissa
-+
-+CPDT_ss_inf:
-+ orr r1,r1,#0x7f000000
-+ orr r1,r1,#0x00800000
-+ str r1,[r6]
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_store_double
-+CPDT_store_double:
-+ ldmia r0,{r1-r4}
-+
-+ cmp r4,#1024 @ this check has to be first, or
-+ bge CPDT_sd_e2047 @ overflow can occur on second !
-+ add r0,r4,#3
-+ cmp r0,#-1023+3 @ cmp with -1023
-+ ble CPDT_sd_e0
-+
-+ adds r3,r3,#1<<10 @ round to nearest
-+ adcs r2,r2,#0
-+ bcs CPDT_sd_rnd_ovfl @ very very seldom taken
-+
-+CPDT_sd_store:
-+ sub r4,r4,#1
-+ add r4,r4,#1024
-+ orr r1,r1,r4,lsl#20
-+
-+ bic r2,r2,#0x80000000
-+ orr r1,r1,r2,lsr#11
-+
-+ mov r2,r2,lsl#21
-+ orr r2,r2,r3,lsr#11
-+
-+ stmia r6,{r1,r2}
-+ b fastfpe_next
-+
-+CPDT_sd_rnd_ovfl:
-+ add r4,r4,#1
-+ cmp r4,#1024
-+ bge CPDT_sd_e2047
-+
-+ mov r2,#0x80000000
-+ mov r3,#0
-+ b CPDT_sd_store
-+
-+CPDT_sd_e0:
-+ add r0,r4,#1075-1024
-+ cmp r0,#-1024
-+ ble CPDT_sd_zero
-+
-+ add r4,r4,#1024
-+ sub r4,r4,#2
-+CPDT_sd_unnormalize:
-+ movs r2,r2,lsr#1
-+ mov r3,r3,rrx
-+ adds r4,r4,#1
-+ bne CPDT_sd_unnormalize
-+
-+ orr r1,r1,r2,lsr#11
-+ mov r2,r2,lsl#21
-+ orr r2,r2,r3,lsr#11
-+
-+ stmia r6,{r1,r2}
-+ b fastfpe_next
-+
-+CPDT_sd_zero:
-+ mov r2,#0
-+ stmia r6,{r1,r2}
-+ b fastfpe_next
-+
-+CPDT_sd_e2047:
-+ cmp r4,#0x7fffffff
-+ bne CPDT_sd_inf
-+ cmp r2,#0
-+ beq CPDT_sd_inf
-+
-+ orr r1,r1,#0x00040000 @ for safety so that it is not INF
-+ orr r1,r1,r2,lsr#12 @ get highest bit of mantissa
-+
-+CPDT_sd_inf:
-+ orr r1,r1,#0x7f000000
-+ orr r1,r1,#0x00f00000
-+ stmia r6,{r1,r2}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_store_extended
-+CPDT_store_extended:
-+ ldmia r0,{r1-r4}
-+
-+ cmp r4,#16384 @ this check has to be first, or
-+ bge CPDT_se_e32767 @ overflow can occur with second !
-+ add r0,r4,#63
-+ cmp r0,#-16383+63
-+ ble CPDT_se_e0
-+
-+ sub r4,r4,#1
-+ add r4,r4,#16384
-+ orr r1,r1,r4
-+
-+ stmia r6,{r1-r3}
-+ b fastfpe_next
-+
-+CPDT_se_e0:
-+ add r0,r4,#16446-16384
-+ cmp r0,#-16384
-+ ble CPDT_se_zero
-+
-+ add r4,r4,#16384
-+ sub r4,r4,#2
-+CPDT_se_unnormalize:
-+ movs r2,r2,lsr#1
-+ mov r3,r3,rrx
-+ adds r4,r4,#1
-+ bne CPDT_se_unnormalize
-+
-+ stmia r6,{r1-r3}
-+ b fastfpe_next
-+
-+CPDT_se_zero:
-+ mov r2,#0
-+ mov r3,#0
-+ stmia r6,{r1-r3}
-+ b fastfpe_next
-+
-+CPDT_se_e32767:
-+ cmp r4,#0x7fffffff
-+ bne CPDT_se_inf
-+ cmp r2,#0
-+ beq CPDT_se_inf
-+
-+ mov r2,r2,lsl#1
-+ orr r2,r2,#0x20000000
-+
-+CPDT_se_inf:
-+ orr r1,r1,#0x00007f00
-+ orr r1,r1,#0x000000ff
-+ stmia r6,{r1-r3}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_store_decimal
-+CPDT_store_decimal:
-+
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_sfm
-+CPDT_sfm:
-+ add r2,r10,r0,lsr#8
-+ ldr r4,[r2,#0]
-+ ldr r3,[r2,#4]
-+ bic r3,r3,#0x80000000
-+ orr r3,r3,r4
-+ str r3,[r6],#4
-+ ldr r3,[r2,#8]
-+ str r3,[r6],#4
-+ ldr r3,[r2,#12]
-+ str r3,[r6],#4
-+
-+ add r0,r0,#1<<12
-+ and r0,r0,#7<<12
-+ subs r1,r1,#1
-+ bne CPDT_sfm
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_lfm
-+CPDT_lfm:
-+ add r2,r10,r0,lsr#8
-+ ldr r4,[r6],#4
-+ and r3,r4,#0x80000000
-+ str r3,[r2,#0]
-+ ldr r3,[r6],#4
-+ str r3,[r2,#8]
-+ ldr r3,[r6],#4
-+ str r3,[r2,#12]
-+
-+ cmp r3,#0x80000000 @ does the exp indicate zero?
-+ biceq r4,r4,#0x80000000 @ if so, indicate 'denormalized'
-+ beq CPDT_lfm_storer4
-+ cmp r3,#0x7fffffff @ does the exp indicate inf or NaN?
-+ biceq r4,r4,#0x80000000 @ if so, indicate 'denormalized'
-+ beq CPDT_lfm_storer4
-+ orrne r4,r4,#0x80000000 @ otherwise, set normalized bit
-+
-+CPDT_lfm_storer4:
-+ str r4,[r2,#4]
-+
-+ add r0,r0,#1<<12
-+ and r0,r0,#7<<12
-+ subs r1,r1,#1
-+ bne CPDT_lfm
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/fastfpe/Makefile 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,14 @@
-+#
-+# linux/arch/arm/fastfpe/Makefile
-+#
-+# Copyright (C) Peter Teichmann
-+#
-+
-+obj-y :=
-+obj-m :=
-+obj-n :=
-+obj- :=
-+
-+fastfpe-objs := module.o entry.o CPDO.o CPRT.o CPDT.o
-+
-+obj-$(CONFIG_FPE_FASTFPE) += fastfpe.o
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/common/rtctime.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,482 @@
-+/*
-+ * linux/arch/arm/common/rtctime.c
-+ *
-+ * Copyright (C) 2003 Deep Blue Solutions Ltd.
-+ * Based on sa1100-rtc.c, Nils Faerber, CIH, Nicolas Pitre.
-+ * Based on rtc.c by Paul Gortmaker
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/time.h>
-+#include <linux/rtc.h>
-+#include <linux/poll.h>
-+#include <linux/proc_fs.h>
-+#include <linux/miscdevice.h>
-+#include <linux/spinlock.h>
-+#include <linux/device.h>
-+
-+#include <asm/rtc.h>
-+#include <asm/semaphore.h>
-+
-+static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
-+static struct fasync_struct *rtc_async_queue;
-+
-+/*
-+ * rtc_lock protects rtc_irq_data
-+ */
-+static spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
-+static unsigned long rtc_irq_data;
-+
-+/*
-+ * rtc_sem protects rtc_inuse and rtc_ops
-+ */
-+static DECLARE_MUTEX(rtc_sem);
-+static unsigned long rtc_inuse;
-+static struct rtc_ops *rtc_ops;
-+
-+#define rtc_epoch 1900UL
-+
-+static const unsigned char days_in_month[] = {
-+ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-+};
-+
-+#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
-+#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400))
-+
-+static int month_days(unsigned int month, unsigned int year)
-+{
-+ return days_in_month[month] + (LEAP_YEAR(year) && month == 1);
-+}
-+
-+/*
-+ * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
-+ */
-+void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
-+{
-+ int days, month, year;
-+
-+ days = time / 86400;
-+ time -= days * 86400;
-+
-+ tm->tm_wday = (days + 4) % 7;
-+
-+ year = 1970 + days / 365;
-+ days -= (year - 1970) * 365
-+ + LEAPS_THRU_END_OF(year - 1)
-+ - LEAPS_THRU_END_OF(1970 - 1);
-+ if (days < 0) {
-+ year -= 1;
-+ days += 365 + LEAP_YEAR(year);
-+ }
-+ tm->tm_year = year - 1900;
-+ tm->tm_yday = days + 1;
-+
-+ for (month = 0; month < 11; month++) {
-+ int newdays;
-+
-+ newdays = days - month_days(month, year);
-+ if (newdays < 0)
-+ break;
-+ days = newdays;
-+ }
-+ tm->tm_mon = month;
-+ tm->tm_mday = days + 1;
-+
-+ tm->tm_hour = time / 3600;
-+ time -= tm->tm_hour * 3600;
-+ tm->tm_min = time / 60;
-+ tm->tm_sec = time - tm->tm_min * 60;
-+}
-+
-+/*
-+ * Convert Gregorian date to seconds since 01-01-1970 00:00:00.
-+ */
-+int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time)
-+{
-+ unsigned int yrs = tm->tm_year + 1900;
-+
-+ *time = 0;
-+
-+ if (yrs < 1970 ||
-+ tm->tm_mon >= 12 ||
-+ tm->tm_mday < 1 ||
-+ tm->tm_mday > month_days(tm->tm_mon, yrs) ||
-+ tm->tm_hour >= 24 ||
-+ tm->tm_min >= 60 ||
-+ tm->tm_sec >= 60)
-+ return -EINVAL;
-+
-+ *time = mktime(yrs, tm->tm_mon + 1, tm->tm_mday,
-+ tm->tm_hour, tm->tm_min, tm->tm_sec);
-+
-+ return 0;
-+}
-+
-+/*
-+ * Calculate the next alarm time given the requested alarm time mask
-+ * and the current time.
-+ *
-+ * FIXME: for now, we just copy the alarm time because we're lazy (and
-+ * is therefore buggy - setting a 10am alarm at 8pm will not result in
-+ * the alarm triggering.)
-+ */
-+void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, struct rtc_time *alrm)
-+{
-+ next->tm_year = now->tm_year;
-+ next->tm_mon = now->tm_mon;
-+ next->tm_mday = now->tm_mday;
-+ next->tm_hour = alrm->tm_hour;
-+ next->tm_min = alrm->tm_min;
-+ next->tm_sec = alrm->tm_sec;
-+}
-+
-+static inline void rtc_read_time(struct rtc_ops *ops, struct rtc_time *tm)
-+{
-+ memset(tm, 0, sizeof(struct rtc_time));
-+ ops->read_time(tm);
-+}
-+
-+static inline int rtc_set_time(struct rtc_ops *ops, struct rtc_time *tm)
-+{
-+ return ops->set_time(tm);
-+}
-+
-+static inline void rtc_read_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
-+{
-+ memset(alrm, 0, sizeof(struct rtc_wkalrm));
-+ ops->read_alarm(alrm);
-+}
-+
-+static inline int rtc_set_alarm(struct rtc_ops *ops, struct rtc_wkalrm *alrm)
-+{
-+ return ops->set_alarm(alrm);
-+}
-+
-+void rtc_update(unsigned long num, unsigned long events)
-+{
-+ spin_lock(&rtc_lock);
-+ rtc_irq_data = (rtc_irq_data + (num << 8)) | events;
-+ spin_unlock(&rtc_lock);
-+
-+ wake_up_interruptible(&rtc_wait);
-+ kill_fasync(&rtc_async_queue, SIGIO, POLL_IN);
-+}
-+
-+
-+static ssize_t
-+rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ unsigned long data;
-+ ssize_t ret;
-+
-+ if (count < sizeof(unsigned long))
-+ return -EINVAL;
-+
-+ add_wait_queue(&rtc_wait, &wait);
-+ do {
-+ __set_current_state(TASK_INTERRUPTIBLE);
-+
-+ spin_lock_irq(&rtc_lock);
-+ data = rtc_irq_data;
-+ rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+
-+ if (data != 0) {
-+ ret = 0;
-+ break;
-+ }
-+ if (file->f_flags & O_NONBLOCK) {
-+ ret = -EAGAIN;
-+ break;
-+ }
-+ if (signal_pending(current)) {
-+ ret = -ERESTARTSYS;
-+ break;
-+ }
-+ schedule();
-+ } while (1);
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&rtc_wait, &wait);
-+
-+ if (ret == 0) {
-+ ret = put_user(data, (unsigned long *)buf);
-+ if (ret == 0)
-+ ret = sizeof(unsigned long);
-+ }
-+ return ret;
-+}
-+
-+static unsigned int rtc_poll(struct file *file, poll_table *wait)
-+{
-+ unsigned long data;
-+
-+ poll_wait(file, &rtc_wait, wait);
-+
-+ spin_lock_irq(&rtc_lock);
-+ data = rtc_irq_data;
-+ spin_unlock_irq(&rtc_lock);
-+
-+ return data != 0 ? POLLIN | POLLRDNORM : 0;
-+}
-+
-+static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-+ unsigned long arg)
-+{
-+ struct rtc_ops *ops = file->private_data;
-+ struct rtc_time tm;
-+ struct rtc_wkalrm alrm;
-+ int ret;
-+
-+ switch (cmd) {
-+ case RTC_ALM_READ:
-+ rtc_read_alarm(ops, &alrm);
-+ ret = copy_to_user((void *)arg, &alrm.time, sizeof(tm));
-+ if (ret)
-+ ret = -EFAULT;
-+ break;
-+
-+ case RTC_ALM_SET:
-+ ret = copy_from_user(&alrm.time, (void *)arg, sizeof(tm));
-+ alrm.enabled = 0;
-+ alrm.pending = 0;
-+ alrm.time.tm_mday = -1;
-+ alrm.time.tm_mon = -1;
-+ alrm.time.tm_year = -1;
-+ alrm.time.tm_wday = -1;
-+ alrm.time.tm_yday = -1;
-+ alrm.time.tm_isdst = -1;
-+ if (ret == 0)
-+ ret = rtc_set_alarm(ops, &alrm);
-+ else
-+ ret = -EFAULT;
-+ break;
-+
-+ case RTC_RD_TIME:
-+ rtc_read_time(ops, &tm);
-+ ret = copy_to_user((void *)arg, &tm, sizeof(tm));
-+ if (ret)
-+ ret = -EFAULT;
-+ break;
-+
-+ case RTC_SET_TIME:
-+ if (!capable(CAP_SYS_TIME)) {
-+ ret = -EACCES;
-+ break;
-+ }
-+ ret = copy_from_user(&tm, (void *)arg, sizeof(tm));
-+ if (ret == 0)
-+ ret = rtc_set_time(ops, &tm);
-+ else
-+ ret = -EFAULT;
-+ break;
-+
-+#ifndef rtc_epoch
-+ case RTC_EPOCH_SET:
-+ /*
-+ * There were no RTC clocks before 1900.
-+ */
-+ if (arg < 1900) {
-+ ret = -EINVAL;
-+ break;
-+ }
-+ if (!capable(CAP_SYS_TIME)) {
-+ ret = -EACCES;
-+ break;
-+ }
-+ rtc_epoch = arg;
-+ ret = 0;
-+ break;
-+#endif
-+
-+ case RTC_EPOCH_READ:
-+ ret = put_user(rtc_epoch, (unsigned long *)arg);
-+ break;
-+
-+ case RTC_WKALM_SET:
-+ ret = copy_from_user(&alrm, (void *)arg, sizeof(alrm));
-+ if (ret == 0)
-+ ret = rtc_set_alarm(ops, &alrm);
-+ else
-+ ret = -EFAULT;
-+ break;
-+
-+ case RTC_WKALM_RD:
-+ rtc_read_alarm(ops, &alrm);
-+ ret = copy_to_user((void *)arg, &alrm, sizeof(alrm));
-+ if (ret)
-+ ret = -EFAULT;
-+ break;
-+
-+ default:
-+ ret = ops->ioctl(cmd, arg);
-+ }
-+ return ret;
-+}
-+
-+static int rtc_open(struct inode *inode, struct file *file)
-+{
-+ int ret;
-+
-+ down(&rtc_sem);
-+
-+ if (rtc_inuse) {
-+ ret = -EBUSY;
-+ } else if (!rtc_ops || !try_module_get(rtc_ops->owner)) {
-+ ret = -ENODEV;
-+ } else {
-+ file->private_data = rtc_ops;
-+
-+ ret = rtc_ops->open ? rtc_ops->open() : 0;
-+ if (ret == 0) {
-+ spin_lock_irq(&rtc_lock);
-+ rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+
-+ rtc_inuse = 1;
-+ }
-+ }
-+ up(&rtc_sem);
-+
-+ return ret;
-+}
-+
-+static int rtc_release(struct inode *inode, struct file *file)
-+{
-+ struct rtc_ops *ops = file->private_data;
-+
-+ if (ops->release)
-+ ops->release();
-+
-+ spin_lock_irq(&rtc_lock);
-+ rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+
-+ module_put(rtc_ops->owner);
-+ rtc_inuse = 0;
-+
-+ return 0;
-+}
-+
-+static int rtc_fasync(int fd, struct file *file, int on)
-+{
-+ return fasync_helper(fd, file, on, &rtc_async_queue);
-+}
-+
-+static struct file_operations rtc_fops = {
-+ .owner = THIS_MODULE,
-+ .llseek = no_llseek,
-+ .read = rtc_read,
-+ .poll = rtc_poll,
-+ .ioctl = rtc_ioctl,
-+ .open = rtc_open,
-+ .release = rtc_release,
-+ .fasync = rtc_fasync,
-+};
-+
-+static struct miscdevice rtc_miscdev = {
-+ .minor = RTC_MINOR,
-+ .name = "rtc",
-+ .fops = &rtc_fops,
-+};
-+
-+
-+static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
-+{
-+ struct rtc_ops *ops = data;
-+ struct rtc_wkalrm alrm;
-+ struct rtc_time tm;
-+ char *p = page;
-+ int len;
-+
-+ rtc_read_time(ops, &tm);
-+
-+ p += sprintf(p,
-+ "rtc_time\t: %02d:%02d:%02d\n"
-+ "rtc_date\t: %04d-%02d-%02d\n"
-+ "rtc_epoch\t: %04lu\n",
-+ tm.tm_hour, tm.tm_min, tm.tm_sec,
-+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
-+ rtc_epoch);
-+
-+ rtc_read_alarm(ops, &alrm);
-+ p += sprintf(p, "alrm_time\t: ");
-+ if ((unsigned int)alrm.time.tm_hour <= 24)
-+ p += sprintf(p, "%02d:", alrm.time.tm_hour);
-+ else
-+ p += sprintf(p, "**:");
-+ if ((unsigned int)alrm.time.tm_min <= 59)
-+ p += sprintf(p, "%02d:", alrm.time.tm_min);
-+ else
-+ p += sprintf(p, "**:");
-+ if ((unsigned int)alrm.time.tm_sec <= 59)
-+ p += sprintf(p, "%02d\n", alrm.time.tm_sec);
-+ else
-+ p += sprintf(p, "**\n");
-+
-+ p += sprintf(p, "alrm_date\t: ");
-+ if ((unsigned int)alrm.time.tm_year <= 200)
-+ p += sprintf(p, "%04d-", alrm.time.tm_year + 1900);
-+ else
-+ p += sprintf(p, "****-");
-+ if ((unsigned int)alrm.time.tm_mon <= 11)
-+ p += sprintf(p, "%02d-", alrm.time.tm_mon + 1);
-+ else
-+ p += sprintf(p, "**-");
-+ if ((unsigned int)alrm.time.tm_mday <= 31)
-+ p += sprintf(p, "%02d\n", alrm.time.tm_mday);
-+ else
-+ p += sprintf(p, "**\n");
-+ p += sprintf(p, "alrm_wakeup\t: %s\n", alrm.enabled ? "yes" : "no");
-+ p += sprintf(p, "alrm_pending\t: %s\n", alrm.pending ? "yes" : "no");
-+
-+ if (ops->proc)
-+ p += ops->proc(p);
-+
-+ len = (p - page) - off;
-+ if (len < 0)
-+ len = 0;
-+ *eof = len <= count;
-+ *start = page + off;
-+
-+ return len;
-+}
-+
-+int register_rtc(struct rtc_ops *ops)
-+{
-+ int ret = -EBUSY;
-+
-+ down(&rtc_sem);
-+ if (rtc_ops == NULL) {
-+ rtc_ops = ops;
-+
-+ ret = misc_register(&rtc_miscdev);
-+ if (ret == 0)
-+ create_proc_read_entry("driver/rtc", 0, 0,
-+ rtc_read_proc, ops);
-+ }
-+ up(&rtc_sem);
-+
-+ return ret;
-+}
-+
-+void unregister_rtc(struct rtc_ops *rtc)
-+{
-+ down(&rtc_sem);
-+ if (rtc == rtc_ops) {
-+ remove_proc_entry("driver/rtc", NULL);
-+ misc_deregister(&rtc_miscdev);
-+ rtc_ops = NULL;
-+ }
-+ up(&rtc_sem);
-+}
-+
-+EXPORT_SYMBOL(rtc_time_to_tm);
-+EXPORT_SYMBOL(rtc_tm_to_time);
-+EXPORT_SYMBOL(rtc_update);
-+EXPORT_SYMBOL(register_rtc);
-+EXPORT_SYMBOL(unregister_rtc);
---- linux-2.6.5/arch/arm/common/Makefile~heh 2004-04-03 22:36:57.000000000 -0500
-+++ linux-2.6.5/arch/arm/common/Makefile 2004-04-30 20:57:36.000000000 -0400
-@@ -2,7 +2,7 @@
- # Makefile for the linux kernel.
- #
-
--obj-y += platform.o
-+obj-y += platform.o rtctime.o
- obj-$(CONFIG_ARM_AMBA) += amba.o
- obj-$(CONFIG_ICST525) += icst525.o
- obj-$(CONFIG_SA1111) += sa1111.o sa1111-pcibuf.o
---- linux-2.6.5/arch/arm/mach-pxa/generic.c~heh 2004-04-03 22:36:53.000000000 -0500
-+++ linux-2.6.5/arch/arm/mach-pxa/generic.c 2004-04-30 20:57:36.000000000 -0400
-@@ -132,7 +132,7 @@
- /* virtual physical length type */
- { 0xf6000000, 0x20000000, 0x01000000, MT_DEVICE }, /* PCMCIA0 IO */
- { 0xf7000000, 0x30000000, 0x01000000, MT_DEVICE }, /* PCMCIA1 IO */
-- { 0xf8000000, 0x40000000, 0x01400000, MT_DEVICE }, /* Devs */
-+ { 0xf8000000, 0x40000000, 0x01800000, MT_DEVICE }, /* Devs */
- { 0xfa000000, 0x44000000, 0x00100000, MT_DEVICE }, /* LCD */
- { 0xfc000000, 0x48000000, 0x00100000, MT_DEVICE }, /* Mem Ctl */
- { 0xff000000, 0x00000000, 0x00100000, MT_DEVICE } /* UNCACHED_PHYS_0 */
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-pxa/cpu-pxa.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,322 @@
-+/*
-+ * linux/arch/arm/mach-pxa/cpu-pxa.c
-+ *
-+ * Copyright (C) 2002,2003 Intrinsyc Software
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * History:
-+ * 31-Jul-2002 : Initial version [FB]
-+ * 29-Jan-2003 : added PXA255 support [FB]
-+ * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.)
-+ *
-+ * Note:
-+ * This driver may change the memory bus clock rate, but will not do any
-+ * platform specific access timing changes... for example if you have flash
-+ * memory connected to CS0, you will need to register a platform specific
-+ * notifier which will adjust the memory access strobes to maintain a
-+ * minimum strobe width.
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/sched.h>
-+#include <linux/init.h>
-+#include <linux/cpufreq.h>
-+
-+#include <asm/hardware.h>
-+
-+#define DEBUG 0
-+
-+#ifdef DEBUG
-+ static unsigned int freq_debug = DEBUG;
-+ MODULE_PARM(freq_debug, "i");
-+ MODULE_PARM_DESC(freq_debug, "Set the debug messages to on=1/off=0");
-+#else
-+ #define freq_debug 0
-+#endif
-+
-+typedef struct
-+{
-+ unsigned int khz;
-+ unsigned int membus;
-+ unsigned int cccr;
-+ unsigned int div2;
-+} pxa_freqs_t;
-+
-+/* Define the refresh period in mSec for the SDRAM and the number of rows */
-+#define SDRAM_TREF 64 /* standard 64ms SDRAM */
-+#define SDRAM_ROWS 4096 /* 64MB=8192 32MB=4096 */
-+#define MDREFR_DRI(x) ((x*SDRAM_TREF)/(SDRAM_ROWS*32))
-+
-+#define CCLKCFG_TURBO 0x1
-+#define CCLKCFG_FCS 0x2
-+#define PXA25x_MIN_FREQ 99500
-+#define PXA25x_MAX_FREQ 398100
-+#define MDREFR_DB2_MASK (MDREFR_K2DB2 | MDREFR_K1DB2)
-+#define MDREFR_DRI_MASK 0xFFF
-+
-+
-+/* Use the run mode frequencies for the CPUFREQ_POLICY_PERFORMANCE policy */
-+static pxa_freqs_t pxa255_run_freqs[] =
-+{
-+ /* CPU MEMBUS CCCR DIV2*/
-+ { 99500, 99500, 0x121, 1}, /* run= 99, turbo= 99, PXbus=50, SDRAM=50 */
-+ {132700, 132700, 0x123, 1}, /* run=133, turbo=133, PXbus=66, SDRAM=66 */
-+ {199100, 99500, 0x141, 0}, /* run=199, turbo=199, PXbus=99, SDRAM=99 */
-+ {265400, 132700, 0x143, 1}, /* run=265, turbo=265, PXbus=133, SDRAM=66 */
-+ {331800, 165900, 0x145, 1}, /* run=331, turbo=331, PXbus=166, SDRAM=83 */
-+ {398100, 99500, 0x161, 0}, /* run=398, turbo=398, PXbus=196, SDRAM=99 */
-+ {0,}
-+};
-+#define NUM_RUN_FREQS (sizeof(pxa255_run_freqs)/sizeof(pxa_freqs_t))
-+
-+static struct cpufreq_frequency_table pxa255_run_freq_table[NUM_RUN_FREQS+1];
-+
-+/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */
-+static pxa_freqs_t pxa255_turbo_freqs[] =
-+{
-+ /* CPU MEMBUS CCCR DIV2*/
-+ { 99500, 99500, 0x121, 1}, /* run=99, turbo= 99, PXbus=50, SDRAM=50 */
-+ {199100, 99500, 0x221, 0}, /* run=99, turbo=199, PXbus=50, SDRAM=99 */
-+ {298500, 99500, 0x321, 0}, /* run=99, turbo=287, PXbus=50, SDRAM=99 */
-+ {298600, 99500, 0x1c1, 0}, /* run=199, turbo=287, PXbus=99, SDRAM=99 */
-+ {398100, 99500, 0x241, 0}, /* run=199, turbo=398, PXbus=99, SDRAM=99 */
-+ {0,}
-+};
-+#define NUM_TURBO_FREQS (sizeof(pxa255_turbo_freqs)/sizeof(pxa_freqs_t))
-+
-+static struct cpufreq_frequency_table pxa255_turbo_freq_table[NUM_TURBO_FREQS+1];
-+
-+/* find a valid frequency point */
-+static int pxa_verify_policy(struct cpufreq_policy *policy)
-+{
-+ int ret;
-+ struct cpufreq_frequency_table *pxa_freqs_table;
-+
-+ if(policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
-+ pxa_freqs_table = pxa255_run_freq_table;
-+ } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
-+ pxa_freqs_table = pxa255_turbo_freq_table;
-+ } else if (policy->policy == CPUFREQ_POLICY_GOVERNOR) {
-+ pxa_freqs_table = pxa255_run_freq_table;
-+ } else {
-+ printk("CPU PXA: Unknown policy found. "
-+ "Using CPUFREQ_POLICY_PERFORMANCE\n");
-+ pxa_freqs_table = pxa255_run_freq_table;
-+ }
-+ ret=cpufreq_frequency_table_verify(policy, pxa_freqs_table);
-+
-+ if(freq_debug) {
-+ printk("Verified CPU policy: %dKhz min to %dKhz max\n",
-+ policy->min, policy->max);
-+ }
-+
-+ return ret;
-+}
-+
-+static int pxa_set_target(struct cpufreq_policy *policy,
-+ unsigned int target_freq,
-+ unsigned int relation)
-+{
-+ int idx;
-+ unsigned long cpus_allowed;
-+ int cpu = policy->cpu;
-+ struct cpufreq_freqs freqs;
-+ pxa_freqs_t *pxa_freq_settings;
-+ struct cpufreq_frequency_table *pxa_freqs_table;
-+ unsigned long flags;
-+ unsigned int unused;
-+ unsigned int preset_mdrefr, postset_mdrefr;
-+
-+ /*
-+ * Save this threads cpus_allowed mask.
-+ */
-+ cpus_allowed = current->cpus_allowed;
-+
-+ /*
-+ * Bind to the specified CPU. When this call returns,
-+ * we should be running on the right CPU.
-+ */
-+ set_cpus_allowed(current, 1 << cpu);
-+ BUG_ON(cpu != smp_processor_id());
-+
-+ /* Get the current policy */
-+ if(policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
-+ pxa_freq_settings = pxa255_run_freqs;
-+ pxa_freqs_table = pxa255_run_freq_table;
-+ }else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) {
-+ pxa_freq_settings = pxa255_turbo_freqs;
-+ pxa_freqs_table = pxa255_turbo_freq_table;
-+ }else if (policy->policy == CPUFREQ_POLICY_GOVERNOR) {
-+ pxa_freq_settings = pxa255_run_freqs;
-+ pxa_freqs_table = pxa255_run_freq_table;
-+ }else {
-+ printk("CPU PXA: Unknown policy found. "
-+ "Using CPUFREQ_POLICY_PERFORMANCE\n");
-+ pxa_freq_settings = pxa255_run_freqs;
-+ pxa_freqs_table = pxa255_run_freq_table;
-+ }
-+
-+ /* Lookup the next frequency */
-+ if (cpufreq_frequency_table_target(policy, pxa_freqs_table,
-+ target_freq, relation, &idx)) {
-+ return -EINVAL;
-+ }
-+
-+ freqs.old = policy->cur;
-+ freqs.new = pxa_freq_settings[idx].khz;
-+ freqs.cpu = policy->cpu;
-+ if(freq_debug) {
-+ printk(KERN_INFO "Changing CPU frequency to %d Mhz, (SDRAM %d Mhz)\n",
-+ freqs.new/1000, (pxa_freq_settings[idx].div2) ?
-+ (pxa_freq_settings[idx].membus/2000) :
-+ (pxa_freq_settings[idx].membus/1000));
-+ }
-+
-+ void *ramstart = phys_to_virt(0xa0000000);
-+
-+ /*
-+ * Tell everyone what we're about to do...
-+ * you should add a notify client with any platform specific
-+ * Vcc changing capability
-+ */
-+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-+
-+ /* Calculate the next MDREFR. If we're slowing down the SDRAM clock
-+ * we need to preset the smaller DRI before the change. If we're speeding
-+ * up we need to set the larger DRI value after the change.
-+ */
-+ preset_mdrefr = postset_mdrefr = MDREFR;
-+ if((MDREFR & MDREFR_DRI_MASK) > MDREFR_DRI(pxa_freq_settings[idx].membus)) {
-+ preset_mdrefr = (preset_mdrefr & ~MDREFR_DRI_MASK) |
-+ MDREFR_DRI(pxa_freq_settings[idx].membus);
-+ }
-+ postset_mdrefr = (postset_mdrefr & ~MDREFR_DRI_MASK) |
-+ MDREFR_DRI(pxa_freq_settings[idx].membus);
-+
-+ /* If we're dividing the memory clock by two for the SDRAM clock, this
-+ * must be set prior to the change. Clearing the divide must be done
-+ * after the change.
-+ */
-+ if(pxa_freq_settings[idx].div2) {
-+ preset_mdrefr |= MDREFR_DB2_MASK;
-+ postset_mdrefr |= MDREFR_DB2_MASK;
-+ } else {
-+ postset_mdrefr &= ~MDREFR_DB2_MASK;
-+ }
-+
-+ local_irq_save(flags);
-+
-+ /* Set new the CCCR */
-+ CCCR = pxa_freq_settings[idx].cccr;
-+
-+ __asm__ __volatile__(" \
-+ ldr r4, [%1] ; /* load MDREFR */ \
-+ b 2f ; \
-+ .align 5 ; \
-+1: \
-+ str %4, [%1] ; /* preset the MDREFR */ \
-+ mcr p14, 0, %2, c6, c0, 0 ; /* set CCLKCFG[FCS] */ \
-+ str %5, [%1] ; /* postset the MDREFR */ \
-+ \
-+ b 3f ; \
-+2: b 1b ; \
-+3: nop ; \
-+ "
-+ : "=&r" (unused)
-+ : "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart), \
-+ "r" (preset_mdrefr), "r" (postset_mdrefr)
-+ : "r4", "r5");
-+ local_irq_restore(flags);
-+
-+ /*
-+ * Restore the CPUs allowed mask.
-+ */
-+ set_cpus_allowed(current, cpus_allowed);
-+
-+ /*
-+ * Tell everyone what we've just done...
-+ * you should add a notify client with any platform specific
-+ * SDRAM refresh timer adjustments
-+ */
-+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-+
-+ return 0;
-+}
-+
-+static int pxa_cpufreq_init(struct cpufreq_policy *policy)
-+{
-+ unsigned long cpus_allowed;
-+ unsigned int cpu = policy->cpu;
-+ int i;
-+
-+ cpus_allowed = current->cpus_allowed;
-+
-+ set_cpus_allowed(current, 1 << cpu);
-+ BUG_ON(cpu != smp_processor_id());
-+
-+ /* set default policy and cpuinfo */
-+ policy->policy = CPUFREQ_POLICY_PERFORMANCE;
-+ policy->cpuinfo.max_freq = PXA25x_MAX_FREQ;
-+ policy->cpuinfo.min_freq = PXA25x_MIN_FREQ;
-+ policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */
-+ policy->cur = get_clk_frequency_khz(0); /* current freq */
-+ policy->min = policy->max = policy->cur;
-+
-+ /* Generate the run cpufreq_frequency_table struct */
-+ for(i=0;i<NUM_RUN_FREQS;i++) {
-+ pxa255_run_freq_table[i].frequency = pxa255_run_freqs[i].khz;
-+ pxa255_run_freq_table[i].index = i;
-+ }
-+ pxa255_run_freq_table[i].frequency = CPUFREQ_TABLE_END;
-+ /* Generate the turbo cpufreq_frequency_table struct */
-+ for(i=0;i<NUM_TURBO_FREQS;i++) {
-+ pxa255_turbo_freq_table[i].frequency = pxa255_turbo_freqs[i].khz;
-+ pxa255_turbo_freq_table[i].index = i;
-+ }
-+ pxa255_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END;
-+
-+ set_cpus_allowed(current, cpus_allowed);
-+ printk(KERN_INFO "PXA CPU frequency change support initialized\n");
-+
-+ return 0;
-+}
-+
-+static struct cpufreq_driver pxa_cpufreq_driver = {
-+ .verify = pxa_verify_policy,
-+ .target = pxa_set_target,
-+ .init = pxa_cpufreq_init,
-+ .name = "PXA25x",
-+};
-+
-+static int __init pxa_cpu_init(void)
-+{
-+ return cpufreq_register_driver(&pxa_cpufreq_driver);
-+}
-+
-+static void __exit pxa_cpu_exit(void)
-+{
-+ cpufreq_unregister_driver(&pxa_cpufreq_driver);
-+}
-+
-+
-+MODULE_AUTHOR ("Intrinsyc Software Inc.");
-+MODULE_DESCRIPTION ("CPU frequency changing driver for the PXA architecture");
-+MODULE_LICENSE("GPL");
-+module_init(pxa_cpu_init);
-+module_exit(pxa_cpu_exit);
-+
---- linux-2.6.5/arch/arm/boot/compressed/misc.c~heh 2004-04-03 22:37:37.000000000 -0500
-+++ linux-2.6.5/arch/arm/boot/compressed/misc.c 2004-04-30 20:57:36.000000000 -0400
-@@ -113,7 +113,7 @@
- * gzip delarations
- */
- #define OF(args) args
--#define STATIC static
-+#define STATIC
-
- typedef unsigned char uch;
- typedef unsigned short ush;
-@@ -122,12 +122,12 @@
- #define WSIZE 0x8000 /* Window size must be at least 32k, */
- /* and a power of two */
-
--static uch *inbuf; /* input buffer */
--static uch window[WSIZE]; /* Sliding window buffer */
-+unsigned char *inbuf; /* input buffer */
-+unsigned char window[WSIZE]; /* Sliding window buffer */
-
--static unsigned insize; /* valid bytes in inbuf */
--static unsigned inptr; /* index of next byte to be processed in inbuf */
--static unsigned outcnt; /* bytes in output buffer */
-+unsigned int insize; /* valid bytes in inbuf */
-+unsigned int inptr; /* index of next byte to be processed in inbuf */
-+unsigned int outcnt; /* bytes in output buffer */
-
- /* gzip flag byte */
- #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
-@@ -166,9 +166,9 @@
- extern char input_data[];
- extern char input_data_end[];
-
--static uch *output_data;
--static ulg output_ptr;
--static ulg bytes_out;
-+unsigned char *output_data;
-+unsigned long output_ptr;
-+unsigned long bytes_out;
-
- static void *malloc(int size);
- static void free(void *where);
-@@ -179,8 +179,8 @@
- static void puts(const char *);
-
- extern int end;
--static ulg free_mem_ptr;
--static ulg free_mem_ptr_end;
-+unsigned long free_mem_ptr;
-+unsigned long free_mem_ptr_end;
-
- #define HEAP_SIZE 0x2000
-
---- linux-2.6.5/arch/arm/mm/ioremap.c~heh 2004-04-03 22:37:36.000000000 -0500
-+++ linux-2.6.5/arch/arm/mm/ioremap.c 2004-04-30 20:57:36.000000000 -0400
-@@ -13,15 +13,18 @@
- * virtual space. One should *only* use readl, writel, memcpy_toio and
- * so on with such remapped areas.
- *
-- * Because the ARM only has a 32-bit address space we can't address the
-- * whole of the (physical) PCI space at once. PCI huge-mode addressing
-- * allows us to circumvent this restriction by splitting PCI space into
-- * two 2GB chunks and mapping only one at a time into processor memory.
-- * We use MMU protection domains to trap any attempt to access the bank
-- * that is not currently mapped. (This isn't fully implemented yet.)
-+ * ioremap support tweaked to allow support for large page mappings. We
-+ * have several issues that needs to be resolved first however:
-+ *
-+ * 1. We need set_pte, or something like set_pte to understand large
-+ * page mappings.
-+ *
-+ * 2. we need the unmap_* functions to likewise understand large page
-+ * mappings.
- */
- #include <linux/errno.h>
- #include <linux/mm.h>
-+#include <linux/slab.h>
- #include <linux/vmalloc.h>
-
- #include <asm/page.h>
-@@ -29,31 +32,162 @@
- #include <asm/io.h>
- #include <asm/tlbflush.h>
-
--static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
-- unsigned long phys_addr, pgprot_t pgprot)
-+extern rwlock_t vmlist_lock;
-+extern struct vm_struct *vmlist;
-+
-+static struct vm_struct *
-+get_io_vm_area(unsigned long size, unsigned long align, unsigned long flags)
- {
-+ struct vm_struct **p, *tmp, *area;
-+ unsigned long addr;
-+
-+ area = (struct vm_struct *)kmalloc(sizeof(*area), GFP_KERNEL);
-+ if (!area)
-+ return NULL;
-+
-+ align -= 1;
-+
-+ size += PAGE_SIZE;
-+ addr = VMALLOC_START;
-+ write_lock(&vmlist_lock);
-+ for (p = &vmlist; (tmp = *p); p = &tmp->next) {
-+ if ((unsigned long)tmp->addr < addr)
-+ continue;
-+ if ((size + addr) < addr)
-+ goto out;
-+ if (size + addr <= (unsigned long) tmp->addr)
-+ break;
-+ addr = tmp->size + (unsigned long) tmp->addr;
-+ if ((addr + align) < addr)
-+ goto out;
-+ addr = (addr + align) & ~align;
-+ if (addr > VMALLOC_END - size)
-+ goto out;
-+ }
-+ area->flags = flags;
-+ area->addr = (void *)addr;
-+ area->size = size;
-+ area->next = *p;
-+ *p = area;
-+ write_unlock(&vmlist_lock);
-+ return area;
-+
-+out:
-+ write_unlock(&vmlist_lock);
-+ kfree(area);
-+ return NULL;
-+}
-+
-+static inline void unmap_area_pte(pmd_t *pmd, unsigned long address, unsigned long size)
-+{
-+ pte_t *ptep;
- unsigned long end;
-
-+ if (pmd_none(*pmd))
-+ return;
-+ if (pmd_bad(*pmd)) {
-+ pmd_ERROR(*pmd);
-+ pmd_clear(pmd);
-+ return;
-+ }
-+ ptep = pte_offset_kernel(pmd, address);
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
-- if (address >= end)
-- BUG();
- do {
-- if (!pte_none(*pte)) {
-- printk("remap_area_pte: page already exists\n");
-- BUG();
-+ pte_t pte;
-+ pte = ptep_get_and_clear(ptep);
-+ address += PAGE_SIZE;
-+ ptep++;
-+ if (pte_none(pte))
-+ continue;
-+ if (pte_present(pte)) {
-+ unsigned long pfn = pte_pfn(pte);
-+ struct page *page;
-+
-+ if (!pfn_valid(pfn))
-+ continue;
-+ page = pfn_to_page(pfn);
-+ if (!PageReserved(page))
-+ __free_page(page);
-+ continue;
- }
-- set_pte(pte, pfn_pte(phys_addr >> PAGE_SHIFT, pgprot));
-+ printk(KERN_CRIT "Whee.. Swapped out page in kernel page table\n");
-+ } while (address < end);
-+}
-+
-+static inline void unmap_area_pmd(pgd_t *dir, unsigned long address, unsigned long size)
-+{
-+ pmd_t *pmd;
-+ unsigned long end;
-+
-+ if (pgd_none(*dir))
-+ return;
-+ if (pgd_bad(*dir)) {
-+ pgd_ERROR(*dir);
-+ pgd_clear(dir);
-+ return;
-+ }
-+ pmd = pmd_offset(dir, address);
-+ address &= ~PGDIR_MASK;
-+ end = address + size;
-+ if (end > PGDIR_SIZE)
-+ end = PGDIR_SIZE;
-+ do {
-+ unmap_area_pte(pmd, address, end - address);
-+ address = (address + PMD_SIZE) & PMD_MASK;
-+ pmd++;
-+ } while (address < end);
-+}
-+
-+static void
-+unmap_area_pages(unsigned long address, unsigned long size)
-+{
-+ unsigned long start = address;
-+ unsigned long end = address + size;
-+ pgd_t *dir;
-+
-+ dir = pgd_offset_k(address);
-+ flush_cache_vunmap(start, end);
-+ do {
-+ unmap_area_pmd(dir, address, end - address);
-+ address = (address + PGDIR_SIZE) & PGDIR_MASK;
-+ dir++;
-+ } while (address && (address < end));
-+ flush_tlb_kernel_range(start, end);
-+}
-+
-+static inline void
-+remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
-+ unsigned long pfn, pgprot_t pgprot)
-+{
-+ unsigned long end;
-+
-+ address &= ~PMD_MASK;
-+ end = address + size;
-+ if (end > PMD_SIZE)
-+ end = PMD_SIZE;
-+ BUG_ON(address >= end);
-+ do {
-+ if (!pte_none(*pte))
-+ goto bad;
-+
-+ set_pte(pte, pfn_pte(pfn, pgprot));
- address += PAGE_SIZE;
-- phys_addr += PAGE_SIZE;
-+ pfn++;
- pte++;
- } while (address && (address < end));
-+ return;
-+
-+ bad:
-+ printk("remap_area_pte: page already exists\n");
-+ BUG();
- }
-
--static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
-- unsigned long phys_addr, unsigned long flags)
-+static inline int
-+remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
-+ unsigned long pfn, unsigned long flags)
- {
- unsigned long end;
- pgprot_t pgprot;
-@@ -64,51 +198,53 @@
- if (end > PGDIR_SIZE)
- end = PGDIR_SIZE;
-
-- phys_addr -= address;
-- if (address >= end)
-- BUG();
-+ pfn -= address >> PAGE_SHIFT;
-+ BUG_ON(address >= end);
-
- pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags);
- do {
- pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address);
- if (!pte)
- return -ENOMEM;
-- remap_area_pte(pte, address, end - address, address + phys_addr, pgprot);
-+ remap_area_pte(pte, address, end - address, pfn + (address >> PAGE_SHIFT), pgprot);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address && (address < end));
- return 0;
- }
-
--static int remap_area_pages(unsigned long address, unsigned long phys_addr,
-- unsigned long size, unsigned long flags)
-+static int
-+remap_area_pages(unsigned long start, unsigned long pfn,
-+ unsigned long size, unsigned long flags)
- {
-- int error;
-+ unsigned long address = start;
-+ unsigned long end = start + size;
-+ int err = 0;
- pgd_t * dir;
-- unsigned long end = address + size;
-
-- phys_addr -= address;
-+ pfn -= address >> PAGE_SHIFT;
- dir = pgd_offset(&init_mm, address);
-- flush_cache_all();
-- if (address >= end)
-- BUG();
-+ BUG_ON(address >= end);
- spin_lock(&init_mm.page_table_lock);
- do {
-- pmd_t *pmd;
-- pmd = pmd_alloc(&init_mm, dir, address);
-- error = -ENOMEM;
-- if (!pmd)
-+ pmd_t *pmd = pmd_alloc(&init_mm, dir, address);
-+ if (!pmd) {
-+ err = -ENOMEM;
- break;
-+ }
- if (remap_area_pmd(pmd, address, end - address,
-- phys_addr + address, flags))
-+ pfn + (address >> PAGE_SHIFT), flags)) {
-+ err = -ENOMEM;
- break;
-- error = 0;
-+ }
-+
- address = (address + PGDIR_SIZE) & PGDIR_MASK;
- dir++;
- } while (address && (address < end));
-+
- spin_unlock(&init_mm.page_table_lock);
-- flush_tlb_all();
-- return error;
-+ flush_cache_vmap(start, end);
-+ return err;
- }
-
- /*
-@@ -146,11 +282,11 @@
- /*
- * Ok, go for it..
- */
-- area = get_vm_area(size, VM_IOREMAP);
-+ area = get_io_vm_area(size, align, VM_IOREMAP);
- if (!area)
- return NULL;
- addr = area->addr;
-- if (remap_area_pages((unsigned long) addr, phys_addr, size, flags)) {
-+ if (remap_area_pages((unsigned long) addr, phys_addr >> PAGE_SHIFT, size, flags)) {
- vfree(addr);
- return NULL;
- }
-@@ -159,5 +295,26 @@
-
- void __iounmap(void *addr)
- {
-- vfree((void *) (PAGE_MASK & (unsigned long) addr));
-+ struct vm_struct **p, *tmp;
-+
-+ if (!addr)
-+ return;
-+
-+ if ((PAGE_SIZE - 1) & (unsigned long)addr) {
-+ printk(KERN_ERR "Trying to iounmap() bad address (%p)\n", addr);
-+ return;
-+ }
-+
-+ write_lock(&vmlist_lock);
-+ for (p = &vmlist; (tmp = *p); p = &tmp->next) {
-+ if (tmp->addr == addr) {
-+ *p = tmp->next;
-+ unmap_area_pages((unsigned long) tmp->addr, tmp->size);
-+ write_unlock(&vmlist_lock);
-+ kfree(tmp);
-+ return;
-+ }
-+ }
-+ write_unlock(&vmlist_lock);
-+ printk(KERN_ERR "Trying to iounmap nonexistent area (%p)\n", addr);
- }
---- linux-2.6.5/arch/arm/mm/proc-xscale.S~heh 2004-04-03 22:38:05.000000000 -0500
-+++ linux-2.6.5/arch/arm/mm/proc-xscale.S 2004-04-30 20:57:36.000000000 -0400
-@@ -563,11 +563,62 @@
- movne r2, #0 @ no -> fault
-
- str r2, [r0] @ hardware version
-+
-+ @ We try to map 64K page entries when possible.
-+ @ We do that for kernel space only since the usage pattern from
-+ @ the setting of VM area is quite simple. User space is not worth
-+ @ the implied complexity because of ever randomly changing PTEs
-+ @ (page aging, swapout, etc) requiring constant coherency checks.
-+ @ Since PTEs are usually set in increasing order, we test the
-+ @ possibility for a large page only when given the last PTE of a
-+ @ 64K boundary.
-+ tsteq r1, #L_PTE_USER
-+ andeq r1, r0, #(15 << 2)
-+ teqeq r1, #(15 << 2)
-+ beq 1f
-+
- mov ip, #0
- mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
- mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
- mov pc, lr
-
-+ @ See if we have 16 identical PTEs but with consecutive base addresses
-+1: bic r3, r2, #0x0000f000
-+ mov r1, #0x0000f000
-+2: eor r2, r2, r3
-+ teq r2, r1
-+ bne 4f
-+ subs r1, r1, #0x00001000
-+ ldr r2, [r0, #-4]!
-+ bne 2b
-+ eors r2, r2, r3
-+ bne 4f
-+
-+ @ Now create our LARGE PTE from the current EXT one.
-+ bic r3, r3, #PTE_TYPE_MASK
-+ orr r3, r3, #PTE_TYPE_LARGE
-+ and r2, r3, #0x30 @ EXT_AP --> LARGE_AP0
-+ orr r2, r2, r2, lsl #2 @ add LARGE_AP1
-+ orr r2, r2, r2, lsl #4 @ add LARGE_AP3 + LARGE_AP2
-+ and r1, r3, #0x3c0 @ EXT_TEX
-+ bic r3, r3, #0x3c0
-+ orr r2, r2, r1, lsl #(12 - 6) @ --> LARGE_TEX
-+ orr r2, r2, r3 @ add remaining bits
-+
-+ @ then put it in the pagetable
-+ mov r3, r2
-+3: strd r2, [r0], #8
-+ tst r0, #(15 << 2)
-+ bne 3b
-+
-+ @ Then sync the 2 corresponding cache lines
-+ sub r0, r0, #(16 << 2)
-+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
-+4: orr r0, r0, #(15 << 2)
-+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
-+ mov ip, #0
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ mov pc, lr
-
- .ltorg
-
---- linux-2.6.5/arch/arm/mach-sa1100/Makefile~heh 2004-04-03 22:38:26.000000000 -0500
-+++ linux-2.6.5/arch/arm/mach-sa1100/Makefile 2004-04-30 20:57:36.000000000 -0400
-@@ -3,7 +3,7 @@
- #
-
- # Common support
--obj-y := generic.o irq.o dma.o
-+obj-y := generic.o irq.o dma.o nmi-oopser.o
- obj-m :=
- obj-n :=
- obj- :=
-@@ -88,7 +88,7 @@
- obj-$(CONFIG_LEDS) += $(led-y)
-
- # SA1110 USB client support
--#obj-$(CONFIG_SA1100_USB) += usb/
-+obj-$(CONFIG_SA1100_USB) += usb/
-
- # Miscelaneous functions
- obj-$(CONFIG_PM) += pm.o sleep.o
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/strings.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,43 @@
-+/*
-+ * usb/strings.h
-+ *
-+ * Copyright (C) 2002 Russell King.
-+ *
-+ * USB device string handling, built upon usb buffers.
-+ */
-+#ifndef USBDEV_STRINGS_H
-+#define USBDEV_STRINGS_H
-+
-+#include <linux/spinlock.h>
-+
-+struct usb_buf;
-+
-+#define NR_STRINGS 8
-+
-+struct usb_string_descriptor;
-+
-+struct usbc_strs {
-+ spinlock_t lock;
-+ struct usb_buf *buf[NR_STRINGS];
-+};
-+
-+#define usbc_string_desc(buf) ((struct usb_string_descriptor *)(buf)->data)
-+
-+void usbc_string_from_cstr(struct usb_buf *buf, const char *str);
-+struct usb_buf *usbc_string_alloc(int len);
-+void usbc_string_free(struct usb_buf *buf);
-+
-+int usbc_string_add(struct usbc_strs *table, struct usb_buf *buf);
-+void usbc_string_del(struct usbc_strs *table, int nr);
-+
-+/*
-+ * Note: usbc_string_find() increments the buffer use count.
-+ * You must call usbb_put() after use.
-+ */
-+struct usb_buf *
-+usbc_string_find(struct usbc_strs *table, unsigned int lang, unsigned int idx);
-+
-+void usbc_string_free_all(struct usbc_strs *table);
-+void usbc_string_init(struct usbc_strs *table);
-+
-+#endif
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb_ctl.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,114 @@
-+/*
-+ * Copyright (C) Compaq Computer Corporation, 1998, 1999
-+ * Copyright (C) Extenex Corporation 2001
-+ *
-+ * usb_ctl.h
-+ *
-+ * PRIVATE interface used to share info among components of the SA-1100 USB
-+ * core: usb_ctl, usb_ep0, usb_recv and usb_send. Clients of the USB core
-+ * should use sa1100_usb.h.
-+ *
-+ */
-+
-+#ifndef _USB_CTL_H
-+#define _USB_CTL_H
-+
-+#include <asm/dma.h> /* dmach_t */
-+
-+struct usb_client;
-+
-+struct usb_stats_t {
-+ unsigned long ep0_fifo_write_failures;
-+ unsigned long ep0_bytes_written;
-+ unsigned long ep0_fifo_read_failures;
-+ unsigned long ep0_bytes_read;
-+};
-+
-+struct usb_info_t
-+{
-+ struct usb_client *client;
-+ dma_regs_t *dmach_tx, *dmach_rx;
-+ int state;
-+ unsigned char address;
-+ struct usb_stats_t stats;
-+};
-+
-+/* in usb_ctl.c */
-+extern struct usb_info_t usbd_info;
-+
-+/*
-+ * Function Prototypes
-+ */
-+enum { kError=-1, kEvSuspend=0, kEvReset=1,
-+ kEvResume=2, kEvAddress=3, kEvConfig=4, kEvDeConfig=5 };
-+int usbctl_next_state_on_event( int event );
-+
-+/* endpoint zero */
-+void ep0_reset(void);
-+void ep0_int_hndlr(void);
-+
-+/* receiver */
-+int ep1_recv(void);
-+int ep1_init(dma_regs_t *dma);
-+void ep1_int_hndlr(int status);
-+void ep1_reset(void);
-+void ep1_stall(void);
-+
-+/* xmitter */
-+void ep2_reset(void);
-+int ep2_init(dma_regs_t *dma);
-+void ep2_int_hndlr(int status);
-+void ep2_stall(void);
-+
-+#define UDC_write(reg, val) { \
-+ int i = 10000; \
-+ do { \
-+ (reg) = (val); \
-+ if (i-- <= 0) { \
-+ printk( "%s [%d]: write %#x to %p (%#x) failed\n", \
-+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
-+ break; \
-+ } \
-+ } while((reg) != (val)); \
-+}
-+
-+#define UDC_set(reg, val) { \
-+ int i = 10000; \
-+ do { \
-+ (reg) |= (val); \
-+ if (i-- <= 0) { \
-+ printk( "%s [%d]: set %#x of %p (%#x) failed\n", \
-+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
-+ break; \
-+ } \
-+ } while(!((reg) & (val))); \
-+}
-+
-+#define UDC_clear(reg, val) { \
-+ int i = 10000; \
-+ do { \
-+ (reg) &= ~(val); \
-+ if (i-- <= 0) { \
-+ printk( "%s [%d]: clear %#x of %p (%#x) failed\n", \
-+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
-+ break; \
-+ } \
-+ } while((reg) & (val)); \
-+}
-+
-+#define UDC_flip(reg, val) { \
-+ int i = 10000; \
-+ (reg) = (val); \
-+ do { \
-+ (reg) = (val); \
-+ if (i-- <= 0) { \
-+ printk( "%s [%d]: flip %#x of %p (%#x) failed\n", \
-+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
-+ break; \
-+ } \
-+ } while(((reg) & (val))); \
-+}
-+
-+
-+#define CHECK_ADDRESS { if ( Ser0UDCAR == 1 ) { printk("%s:%d I lost my address!!!\n",__FUNCTION__, __LINE__);}}
-+#endif /* _USB_CTL_H */
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb_send.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,302 @@
-+/*
-+ * Generic xmit layer for the SA1100 USB client function
-+ * Copyright (c) 2001 by Nicolas Pitre
-+ *
-+ * This code was loosely inspired by the original version which was
-+ * Copyright (c) Compaq Computer Corporation, 1998-1999
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This is still work in progress...
-+ *
-+ * Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
-+ * 15/03/2001 - ep2_start now sets UDCAR to overcome something that is hardware
-+ * bug, I think. green@iXcelerator.com
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+#include <linux/errno.h>
-+#include <linux/delay.h> // for the massive_attack hack 28Feb01ww
-+#include <linux/usb_ch9.h>
-+
-+#include <asm/dma.h>
-+
-+#include "usbdev.h"
-+#include "sa1100_usb.h"
-+#include "sa1100usb.h"
-+
-+static unsigned int ep2_curdmalen;
-+static unsigned int ep2_remain;
-+
-+static struct sausb_dev *ep2_dev;
-+
-+static void udc_set_cs2(u32 val, u32 mask, u32 check)
-+{
-+ int i = 0;
-+
-+ do {
-+ Ser0UDCCS2 = val;
-+ udelay(1);
-+ if ((Ser0UDCCS2 & mask) == check)
-+ return;
-+ } while (i++ < 10000);
-+
-+ printk("UDC: UDCCS2 write timed out: val=0x%08x\n", val);
-+}
-+
-+/* set feature stall executing, async */
-+static void ep2_start(struct sausb_dev *usb)
-+{
-+ ep2_curdmalen = min(ep2_remain, usb->ep[1].maxpktsize);
-+ if (ep2_curdmalen == 0)
-+ return;
-+
-+ /*
-+ * must do this _before_ queue buffer..
-+ * stop NAKing IN tokens
-+ */
-+ udc_set_cs2(usb->ep[1].udccs | UDCCS2_TPC, UDCCS2_TPC, 0);
-+
-+ UDC_write(Ser0UDCIMP, ep2_curdmalen - 1);
-+
-+ /* Remove if never seen...8Mar01ww */
-+ {
-+ int massive_attack = 20;
-+ while (Ser0UDCIMP != ep2_curdmalen - 1 && massive_attack--) {
-+ printk("usbsnd: Oh no you don't! Let me spin...");
-+ udelay(500);
-+ printk("and try again...\n");
-+ UDC_write(Ser0UDCIMP, ep2_curdmalen - 1);
-+ }
-+ if (massive_attack != 20) {
-+ if (Ser0UDCIMP != ep2_curdmalen - 1)
-+ printk("usbsnd: Massive attack FAILED. %d\n",
-+ 20 - massive_attack);
-+ else
-+ printk("usbsnd: Massive attack WORKED. %d\n",
-+ 20 - massive_attack);
-+ }
-+ }
-+ /* End remove if never seen... 8Mar01ww */
-+
-+ /*
-+ * fight stupid silicon bug
-+ */
-+ Ser0UDCAR = usb->ctl->address;
-+
-+ sa1100_start_dma(usb->ep[1].dmach, usb->ep[1].pktdma, ep2_curdmalen);
-+}
-+
-+static void udc_ep2_done(struct sausb_dev *usb, int flag)
-+{
-+ int size = usb->ep[1].buflen - ep2_remain;
-+
-+ if (!usb->ep[1].buflen)
-+ return;
-+
-+ dma_unmap_single(usb->dev, usb->ep[1].bufdma, usb->ep[1].buflen,
-+ DMA_TO_DEVICE);
-+
-+ usb->ep[1].bufdma = 0;
-+ usb->ep[1].buflen = 0;
-+ usb->ep[1].pktdma = 0;
-+
-+ if (usb->ep[1].cb_func)
-+ usb->ep[1].cb_func(usb->ep[1].cb_data, flag, size);
-+}
-+
-+/*
-+ * Initialisation. Clear out the status.
-+ */
-+void udc_ep2_init(struct sausb_dev *usb)
-+{
-+ ep2_dev = usb;
-+
-+ usb->ep[1].udccs = UDCCS2_FST;
-+
-+ BUG_ON(usb->ep[1].buflen);
-+ BUG_ON(usb->ep[1].pktlen);
-+
-+ sa1100_reset_dma(usb->ep[1].dmach);
-+}
-+
-+/*
-+ * Note: rev A0-B2 chips don't like FST
-+ */
-+void udc_ep2_halt(struct sausb_dev *usb, int halt)
-+{
-+ usb->ep[1].host_halt = halt;
-+
-+ if (halt) {
-+ usb->ep[1].udccs |= UDCCS2_FST;
-+ udc_set_cs2(UDCCS2_FST, UDCCS2_FST, UDCCS2_FST);
-+ } else {
-+ sa1100_clear_dma(usb->ep[1].dmach);
-+
-+ udc_set_cs2(UDCCS2_FST, UDCCS2_FST, UDCCS2_FST);
-+ udc_set_cs2(0, UDCCS2_FST, 0);
-+ udc_set_cs2(UDCCS2_SST, UDCCS2_SST, 0);
-+
-+ usb->ep[1].udccs &= ~UDCCS2_FST;
-+
-+ udc_ep2_done(usb, -EINTR);
-+ }
-+}
-+
-+/*
-+ * This gets called when we receive a SET_CONFIGURATION packet to EP0.
-+ * We were configured. We can now send packets to the host.
-+ */
-+void udc_ep2_config(struct sausb_dev *usb, unsigned int maxpktsize)
-+{
-+ /*
-+ * We shouldn't be transmitting anything...
-+ */
-+ BUG_ON(usb->ep[1].buflen);
-+ BUG_ON(usb->ep[1].pktlen);
-+
-+ /*
-+ * Set our configuration.
-+ */
-+ usb->ep[1].maxpktsize = maxpktsize;
-+ usb->ep[1].configured = 1;
-+
-+ /*
-+ * Clear any pending TPC status.
-+ */
-+ udc_set_cs2(UDCCS2_TPC, UDCCS2_TPC, 0);
-+
-+ /*
-+ * Enable EP2 interrupts.
-+ */
-+ usb->udccr &= ~UDCCR_TIM;
-+ UDC_write(Ser0UDCCR, usb->udccr);
-+
-+ usb->ep[1].udccs = 0;
-+}
-+
-+/*
-+ * We saw a reset from the attached hub, or were deconfigured.
-+ * This means we are no longer configured.
-+ */
-+void udc_ep2_reset(struct sausb_dev *usb)
-+{
-+ /*
-+ * Disable EP2 interrupts.
-+ */
-+ usb->udccr |= UDCCR_TIM;
-+ UDC_write(Ser0UDCCR, usb->udccr);
-+
-+ usb->ep[1].configured = 0;
-+ usb->ep[1].maxpktsize = 0;
-+
-+ sa1100_reset_dma(usb->ep[1].dmach);
-+ udc_ep2_done(usb, -EINTR);
-+}
-+
-+void udc_ep2_int_hndlr(struct sausb_dev *usb)
-+{
-+ u32 status = Ser0UDCCS2;
-+
-+ // check for stupid silicon bug.
-+ if (Ser0UDCAR != usb->ctl->address)
-+ Ser0UDCAR = usb->ctl->address;
-+
-+ udc_set_cs2(usb->ep[1].udccs | UDCCS2_SST, UDCCS2_SST, 0);
-+
-+ if (!(status & UDCCS2_TPC)) {
-+ printk("usb_send: Not TPC: UDCCS2 = %x\n", status);
-+ return;
-+ }
-+
-+ sa1100_stop_dma(usb->ep[1].dmach);
-+
-+ if (status & (UDCCS2_TPE | UDCCS2_TUR)) {
-+ printk("usb_send: transmit error %x\n", status);
-+ usb->ep[1].fifo_errs ++;
-+ udc_ep2_done(usb, -EIO);
-+ } else {
-+ unsigned int imp;
-+#if 1 // 22Feb01ww/Oleg
-+ imp = ep2_curdmalen;
-+#else
-+ // this is workaround for case when setting
-+ // of Ser0UDCIMP was failed
-+ imp = Ser0UDCIMP + 1;
-+#endif
-+ usb->ep[1].pktdma += imp;
-+ ep2_remain -= imp;
-+
-+ usb->ep[1].bytes += imp;
-+ usb->ep[1].packets++;
-+
-+ sa1100_clear_dma(usb->ep[1].dmach);
-+
-+ if (ep2_remain != 0) {
-+ ep2_start(usb);
-+ } else {
-+ udc_ep2_done(usb, 0);
-+ }
-+ }
-+}
-+
-+int udc_ep2_send(struct sausb_dev *usb, char *buf, int len)
-+{
-+ unsigned long flags;
-+ dma_addr_t dma;
-+ int ret;
-+
-+ if (!buf || len == 0)
-+ return -EINVAL;
-+
-+ dma = dma_map_single(usb->dev, buf, len, DMA_TO_DEVICE);
-+
-+ spin_lock_irqsave(&usb->lock, flags);
-+ do {
-+ if (!usb->ep[1].configured) {
-+ ret = -ENODEV;
-+ break;
-+ }
-+
-+ if (usb->ep[1].buflen) {
-+ ret = -EBUSY;
-+ break;
-+ }
-+
-+ usb->ep[1].bufdma = dma;
-+ usb->ep[1].buflen = len;
-+ usb->ep[1].pktdma = dma;
-+ ep2_remain = len;
-+
-+ sa1100_clear_dma(usb->ep[1].dmach);
-+
-+ ep2_start(usb);
-+ ret = 0;
-+ } while (0);
-+ spin_unlock_irqrestore(&usb->lock, flags);
-+
-+ if (ret)
-+ dma_unmap_single(usb->dev, dma, len, DMA_TO_DEVICE);
-+
-+ return ret;
-+}
-+
-+void udc_ep2_send_reset(struct sausb_dev *usb)
-+{
-+ sa1100_reset_dma(usb->ep[1].dmach);
-+ udc_ep2_done(usb, -EINTR);
-+}
-+
-+int udc_ep2_idle(struct sausb_dev *usb)
-+{
-+ if (!usb->ep[1].configured)
-+ return -ENODEV;
-+
-+ if (usb->ep[1].buflen)
-+ return -EBUSY;
-+
-+ return 0;
-+}
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb-char.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,709 @@
-+/*
-+ * (C) Copyright 2000-2001 Extenex Corporation
-+ *
-+ * 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.
-+ *
-+ * usb-char.c
-+ *
-+ * Miscellaneous character device interface for SA1100 USB function
-+ * driver.
-+ *
-+ * Background:
-+ * The SA1100 function driver ported from the Compaq Itsy project
-+ * has an interface, usb-eth.c, to feed network packets over the
-+ * usb wire and into the Linux TCP/IP stack.
-+ *
-+ * This file replaces that one with a simple character device
-+ * interface that allows unstructured "byte pipe" style reads and
-+ * writes over the USB bulk endpoints by userspace programs.
-+ *
-+ * A new define, CONFIG_SA1100_USB_NETLINK, has been created that,
-+ * when set, (the default) causes the ethernet interface to be used.
-+ * When not set, this more pedestrian character interface is linked
-+ * in instead.
-+ *
-+ * Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
-+ *
-+ * ward.willats@extenex.com
-+ *
-+ * To do:
-+ * - Can't dma into ring buffer directly with dma_map/unmap usb_recv
-+ * uses and get bytes out at the same time DMA is going on. Investigate:
-+ * a) changing usb_recv to use alloc_consistent() at client request; or
-+ * b) non-ring-buffer based data structures. In the meantime, I am using
-+ * a bounce buffer. Simple, but wasteful.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/config.h>
-+#include <linux/miscdevice.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/cache.h>
-+#include <linux/poll.h>
-+#include <linux/circ_buf.h>
-+#include <linux/timer.h>
-+#include <linux/usb_ch9.h>
-+
-+#include <asm/io.h>
-+#include <asm/semaphore.h>
-+#include <asm/page.h>
-+#include <asm/mach-types.h>
-+
-+#include "usb-char.h"
-+#include "client.h"
-+
-+
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Driver Options
-+//////////////////////////////////////////////////////////////////////////////
-+
-+#define VERSION "0.4"
-+
-+
-+#define VERBOSITY 1
-+
-+#if VERBOSITY
-+# define PRINTK(x, a...) printk (x, ## a)
-+#else
-+# define PRINTK(x, a...) /**/
-+#endif
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Globals - Macros - Enums - Structures
-+//////////////////////////////////////////////////////////////////////////////
-+#ifndef MIN
-+#define MIN( a, b ) ((a)<(b)?(a):(b))
-+#endif
-+
-+typedef int bool; enum { false = 0, true = 1 };
-+
-+static const char pszMe[] = "usbchr: ";
-+
-+static wait_queue_head_t wq_read;
-+static wait_queue_head_t wq_write;
-+static wait_queue_head_t wq_poll;
-+
-+/* Serialze multiple writers onto the transmit hardware
-+.. since we sleep the writer during transmit to stay in
-+.. sync. (Multiple writers don't make much sense, but..) */
-+static DECLARE_MUTEX( xmit_sem );
-+
-+// size of usb DATA0/1 packets. 64 is standard maximum
-+// for bulk transport, though most hosts seem to be able
-+// to handle larger.
-+#define TX_PACKET_SIZE 64
-+#define RX_PACKET_SIZE 64
-+#define RBUF_SIZE (4*PAGE_SIZE)
-+
-+static struct wcirc_buf {
-+ char *buf;
-+ int in;
-+ int out;
-+} rx_ring = { NULL, 0, 0 };
-+
-+static struct {
-+ unsigned long cnt_rx_complete;
-+ unsigned long cnt_rx_errors;
-+ unsigned long bytes_rx;
-+ unsigned long cnt_tx_timeouts;
-+ unsigned long cnt_tx_errors;
-+ unsigned long bytes_tx;
-+} charstats;
-+
-+
-+static char * tx_buf = NULL;
-+static char * packet_buffer = NULL;
-+static int sending = 0;
-+static int usb_ref_count = 0;
-+static int last_tx_result = 0;
-+static int last_rx_result = 0;
-+static int last_tx_size = 0;
-+static struct timer_list tx_timer;
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Prototypes
-+//////////////////////////////////////////////////////////////////////////////
-+static char * what_the_f( int e );
-+static void free_txrx_buffers( void );
-+static void twiddle_descriptors(struct usb_client *client);
-+static int usbc_open( struct inode *pInode, struct file *pFile );
-+static void rx_done_callback_packet_buffer(void *data, int flag, int size );
-+
-+static void tx_timeout( unsigned long );
-+static void tx_done_callback(void *data, int flag, int size );
-+
-+static ssize_t usbc_read( struct file *, char *, size_t, loff_t * );
-+static ssize_t usbc_write( struct file *, const char *, size_t, loff_t * );
-+static unsigned int usbc_poll( struct file *pFile, poll_table * pWait );
-+static int usbc_ioctl( struct inode *pInode, struct file *pFile,
-+ unsigned int nCmd, unsigned long argument );
-+static int usbc_close( struct inode *pInode, struct file *pFile );
-+
-+#ifdef CONFIG_SA1100_EXTENEX1
-+static void extenex_configured_notify_proc( void );
-+#endif
-+//////////////////////////////////////////////////////////////////////////////
-+// Private Helpers
-+//////////////////////////////////////////////////////////////////////////////
-+
-+static char * what_the_f( int e )
-+{
-+ char * p;
-+ switch( e ) {
-+ case 0:
-+ p = "noErr";
-+ break;
-+ case -ENODEV:
-+ p = "ENODEV - usb not in config state";
-+ break;
-+ case -EBUSY:
-+ p = "EBUSY - another request on the hardware";
-+ break;
-+ case -EAGAIN:
-+ p = "EAGAIN";
-+ break;
-+ case -EINTR:
-+ p = "EINTR - interrupted\n";
-+ break;
-+ case -EPIPE:
-+ p = "EPIPE - zero length xfer\n";
-+ break;
-+ default:
-+ p = "????";
-+ break;
-+ }
-+ return p;
-+}
-+
-+static void free_txrx_buffers( void )
-+{
-+ if ( rx_ring.buf != NULL ) {
-+ kfree( rx_ring.buf );
-+ rx_ring.buf = NULL;
-+ }
-+ if ( packet_buffer != NULL ) {
-+ kfree( packet_buffer );
-+ packet_buffer = NULL;
-+ }
-+ if ( tx_buf != NULL ) {
-+ kfree( tx_buf );
-+ tx_buf = NULL;
-+ }
-+}
-+
-+/* twiddle_descriptors()
-+ * It is between open() and start(). Setup descriptors.
-+ */
-+static void twiddle_descriptors(struct usb_client *client)
-+{
-+ struct cdb *cdb = sa1100_usb_get_descriptor_ptr();
-+
-+ cdb->ep1.wMaxPacketSize = cpu_to_le16(RX_PACKET_SIZE);
-+ cdb->ep2.wMaxPacketSize = cpu_to_le16(TX_PACKET_SIZE);
-+
-+#ifdef CONFIG_SA1100_EXTENEX1
-+ if (machine_is_extenex1()) {
-+ int nr;
-+
-+ cdb->cfg.bmAttributes = USB_CONFIG_SELFPOWERED;
-+ cdb->cfg.MaxPower = 0;
-+
-+ nr = sa1100_usb_add_string(client->ctl, "HHT Bulk Transfer");
-+
-+ if (nr > 0)
-+ cdb->intf.iInterface = nr;
-+ }
-+#endif
-+}
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// ASYNCHRONOUS
-+//////////////////////////////////////////////////////////////////////////////
-+static void kick_start_rx( void )
-+{
-+ if ( usb_ref_count ) {
-+ int total_space = CIRC_SPACE( rx_ring.in, rx_ring.out, RBUF_SIZE );
-+ if ( total_space >= RX_PACKET_SIZE ) {
-+ sa1100_usb_recv_set_callback(rx_done_callback_packet_buffer, NULL);
-+ sa1100_usb_recv( packet_buffer, RX_PACKET_SIZE);
-+ }
-+ }
-+}
-+/*
-+ * rx_done_callback_packet_buffer()
-+ * We have completed a DMA xfer into the temp packet buffer.
-+ * Move to ring.
-+ *
-+ * flag values:
-+ * on init, -EAGAIN
-+ * on reset, -EINTR
-+ * on RPE, -EIO
-+ * on short packet -EPIPE
-+ */
-+static void
-+rx_done_callback_packet_buffer(void *data, int flag, int size )
-+{
-+ charstats.cnt_rx_complete++;
-+
-+ if ( flag == 0 || flag == -EPIPE ) {
-+ size_t n;
-+
-+ charstats.bytes_rx += size;
-+
-+ n = CIRC_SPACE_TO_END( rx_ring.in, rx_ring.out, RBUF_SIZE );
-+ n = MIN( n, size );
-+ size -= n;
-+
-+ memcpy( &rx_ring.buf[ rx_ring.in ], packet_buffer, n );
-+ rx_ring.in = (rx_ring.in + n) & (RBUF_SIZE-1);
-+ memcpy( &rx_ring.buf[ rx_ring.in ], packet_buffer + n, size );
-+ rx_ring.in = (rx_ring.in + size) & (RBUF_SIZE-1);
-+
-+ wake_up_interruptible( &wq_read );
-+ wake_up_interruptible( &wq_poll );
-+
-+ last_rx_result = 0;
-+
-+ kick_start_rx();
-+
-+ } else if ( flag != -EAGAIN ) {
-+ charstats.cnt_rx_errors++;
-+ last_rx_result = flag;
-+ wake_up_interruptible( &wq_read );
-+ wake_up_interruptible( &wq_poll );
-+ }
-+ else /* init, start a read */
-+ kick_start_rx();
-+}
-+
-+
-+static void tx_timeout( unsigned long unused )
-+{
-+ printk( "%stx timeout\n", pszMe );
-+ sa1100_usb_send_reset();
-+ charstats.cnt_tx_timeouts++;
-+}
-+
-+
-+// on init, -EAGAIN
-+// on reset, -EINTR
-+// on TPE, -EIO
-+static void tx_done_callback(void *data, int flags, int size )
-+{
-+ if ( flags == 0 )
-+ charstats.bytes_tx += size;
-+ else
-+ charstats.cnt_tx_errors++;
-+ last_tx_size = size;
-+ last_tx_result = flags;
-+ sending = 0;
-+ wake_up_interruptible( &wq_write );
-+ wake_up_interruptible( &wq_poll );
-+}
-+
-+
-+static struct usb_client usbc_client = {
-+ .name = "usb-char",
-+
-+ /*
-+ * USB client identification for host use in CPU endian.
-+ */
-+ .vendor = 0,
-+ .product = 0,
-+ .version = 0,
-+ .class = 0xff,
-+ .subclass = 0,
-+ .protocol = 0,
-+};
-+
-+#ifdef CONFIG_SA1100_EXTENEX1
-+#include "../../../drivers/char/ex_gpio.h"
-+static void extenex_state_change(void *data, int state, int oldstate)
-+{
-+ if (exgpio_play_string( "440,1:698,1") == -EAGAIN)
-+ printk( "%sWanted to BEEP but ex_gpio not open\n", pszMe );
-+}
-+#endif
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Workers
-+//////////////////////////////////////////////////////////////////////////////
-+
-+static int usbc_open(struct inode *pInode, struct file *pFile)
-+{
-+ int retval = 0;
-+
-+ PRINTK( KERN_DEBUG "%sopen()\n", pszMe );
-+
-+#ifdef CONFIG_SA1100_EXTENEX1
-+ if (machine_is_extenex1()) {
-+ usbc_client.vendor = 0x0c9f;
-+ usbc_client.product = 0x0100;
-+ usbc_client.version = 0x0001;
-+ usbc_client.manufacturer_str = "Extenex";
-+ usbc_client.product_str = "Handheld Theater";
-+ usbc_client.serial_str = "00000000";
-+ usbc_client.state_change = extenex_state_change;
-+ }
-+#endif
-+
-+ /* start usb core */
-+ retval = usbctl_open(&usbc_client);
-+ if (retval)
-+ return retval;
-+
-+ /* allocate memory */
-+ if ( usb_ref_count == 0 ) {
-+ tx_buf = (char*) kmalloc( TX_PACKET_SIZE, GFP_KERNEL | GFP_DMA );
-+ if ( tx_buf == NULL ) {
-+ printk( "%sARGHH! COULD NOT ALLOCATE TX BUFFER\n", pszMe );
-+ goto malloc_fail;
-+ }
-+ rx_ring.buf =
-+ (char*) kmalloc( RBUF_SIZE, GFP_KERNEL );
-+
-+ if ( rx_ring.buf == NULL ) {
-+ printk( "%sARGHH! COULD NOT ALLOCATE RX BUFFER\n", pszMe );
-+ goto malloc_fail;
-+ }
-+
-+ packet_buffer =
-+ (char*) kmalloc( RX_PACKET_SIZE, GFP_KERNEL | GFP_DMA );
-+
-+ if ( packet_buffer == NULL ) {
-+ printk( "%sARGHH! COULD NOT ALLOCATE RX PACKET BUFFER\n", pszMe );
-+ goto malloc_fail;
-+ }
-+ rx_ring.in = rx_ring.out = 0;
-+ memset( &charstats, 0, sizeof( charstats ) );
-+ sending = 0;
-+ last_tx_result = 0;
-+ last_tx_size = 0;
-+ }
-+
-+ /* modify default descriptors */
-+ twiddle_descriptors(&usbc_client);
-+
-+ retval = usbctl_start(&usbc_client);
-+ if ( retval ) {
-+ printk( "%sAGHH! Could not USB core\n", pszMe );
-+ free_txrx_buffers();
-+ return retval;
-+ }
-+ usb_ref_count++; /* must do _before_ kick_start() */
-+ MOD_INC_USE_COUNT;
-+ kick_start_rx();
-+ return 0;
-+
-+ malloc_fail:
-+ free_txrx_buffers();
-+ return -ENOMEM;
-+}
-+
-+/*
-+ * Read endpoint. Note that you can issue a read to an
-+ * unconfigured endpoint. Eventually, the host may come along
-+ * and configure underneath this module and data will appear.
-+ */
-+static ssize_t usbc_read( struct file *pFile, char *pUserBuffer,
-+ size_t stCount, loff_t *pPos )
-+{
-+ ssize_t retval;
-+ unsigned long flags;
-+ DECLARE_WAITQUEUE( wait, current );
-+
-+ PRINTK( KERN_DEBUG "%sread()\n", pszMe );
-+
-+ local_irq_save(flags);
-+ if ( last_rx_result == 0 ) {
-+ local_irq_restore( flags );
-+ } else { /* an error happended and receiver is paused */
-+ local_irq_restore( flags );
-+ last_rx_result = 0;
-+ kick_start_rx();
-+ }
-+
-+ add_wait_queue( &wq_read, &wait );
-+ while( 1 ) {
-+ ssize_t bytes_avail;
-+ ssize_t bytes_to_end;
-+
-+ set_current_state( TASK_INTERRUPTIBLE );
-+
-+ /* snap ring buf state */
-+ local_irq_save( flags );
-+ bytes_avail = CIRC_CNT( rx_ring.in, rx_ring.out, RBUF_SIZE );
-+ bytes_to_end = CIRC_CNT_TO_END( rx_ring.in, rx_ring.out, RBUF_SIZE );
-+ local_irq_restore( flags );
-+
-+ if ( bytes_avail != 0 ) {
-+ ssize_t bytes_to_move = MIN( stCount, bytes_avail );
-+ retval = 0; // will be bytes transfered
-+ if ( bytes_to_move != 0 ) {
-+ size_t n = MIN( bytes_to_end, bytes_to_move );
-+ if ( copy_to_user( pUserBuffer,
-+ &rx_ring.buf[ rx_ring.out ],
-+ n ) ) {
-+ retval = -EFAULT;
-+ break;
-+ }
-+ bytes_to_move -= n;
-+ retval += n;
-+ // might go 1 char off end, so wrap
-+ rx_ring.out = ( rx_ring.out + n ) & (RBUF_SIZE-1);
-+ if ( copy_to_user( pUserBuffer + n,
-+ &rx_ring.buf[ rx_ring.out ],
-+ bytes_to_move )
-+ ) {
-+ retval = -EFAULT;
-+ break;
-+ }
-+ rx_ring.out += bytes_to_move; // cannot wrap
-+ retval += bytes_to_move;
-+ kick_start_rx();
-+ }
-+ break;
-+ }
-+ else if ( last_rx_result ) {
-+ retval = last_rx_result;
-+ break;
-+ }
-+ else if ( pFile->f_flags & O_NONBLOCK ) { // no data, can't sleep
-+ retval = -EAGAIN;
-+ break;
-+ }
-+ else if ( signal_pending( current ) ) { // no data, can sleep, but signal
-+ retval = -ERESTARTSYS;
-+ break;
-+ }
-+ schedule(); // no data, can sleep
-+ }
-+ set_current_state( TASK_RUNNING );
-+ remove_wait_queue( &wq_read, &wait );
-+
-+ if ( retval < 0 )
-+ printk( "%sread error %d - %s\n", pszMe, retval, what_the_f( retval ) );
-+ return retval;
-+}
-+
-+/*
-+ * Write endpoint. This routine attempts to break the passed in buffer
-+ * into usb DATA0/1 packet size chunks and send them to the host.
-+ * (The lower-level driver tries to do this too, but easier for us
-+ * to manage things here.)
-+ *
-+ * We are at the mercy of the host here, in that it must send an IN
-+ * token to us to pull this data back, so hopefully some higher level
-+ * protocol is expecting traffic to flow in that direction so the host
-+ * is actually polling us. To guard against hangs, a 5 second timeout
-+ * is used.
-+ *
-+ * This routine takes some care to only report bytes sent that have
-+ * actually made it across the wire. Thus we try to stay in lockstep
-+ * with the completion routine and only have one packet on the xmit
-+ * hardware at a time. Multiple simultaneous writers will get
-+ * "undefined" results.
-+ *
-+ */
-+static ssize_t usbc_write( struct file *pFile, const char * pUserBuffer,
-+ size_t stCount, loff_t *pPos )
-+{
-+ ssize_t retval = 0;
-+ ssize_t stSent = 0;
-+
-+ DECLARE_WAITQUEUE( wait, current );
-+
-+ PRINTK( KERN_DEBUG "%swrite() %d bytes\n", pszMe, stCount );
-+
-+ down( &xmit_sem ); // only one thread onto the hardware at a time
-+
-+ while( stCount != 0 && retval == 0 ) {
-+ int nThisTime = MIN( TX_PACKET_SIZE, stCount );
-+ copy_from_user( tx_buf, pUserBuffer, nThisTime );
-+ sending = nThisTime;
-+ sa1100_usb_send_set_callback(tx_done_callback, NULL);
-+ retval = sa1100_usb_send( tx_buf, nThisTime);
-+ if ( retval < 0 ) {
-+ char * p = what_the_f( retval );
-+ printk( "%sCould not queue xmission. rc=%d - %s\n",
-+ pszMe, retval, p );
-+ sending = 0;
-+ break;
-+ }
-+ /* now have something on the diving board */
-+ add_wait_queue( &wq_write, &wait );
-+ tx_timer.expires = jiffies + ( HZ * 5 );
-+ add_timer( &tx_timer );
-+ while( 1 ) {
-+ set_current_state( TASK_INTERRUPTIBLE );
-+ if ( sending == 0 ) { /* it jumped into the pool */
-+ del_timer( &tx_timer );
-+ retval = last_tx_result;
-+ if ( retval == 0 ) {
-+ stSent += last_tx_size;
-+ pUserBuffer += last_tx_size;
-+ stCount -= last_tx_size;
-+ }
-+ else
-+ printk( "%sxmission error rc=%d - %s\n",
-+ pszMe, retval, what_the_f(retval) );
-+ break;
-+ }
-+ else if ( signal_pending( current ) ) {
-+ del_timer( &tx_timer );
-+ printk( "%ssignal\n", pszMe );
-+ retval = -ERESTARTSYS;
-+ break;
-+ }
-+ schedule();
-+ }
-+ set_current_state( TASK_RUNNING );
-+ remove_wait_queue( &wq_write, &wait );
-+ }
-+
-+ up( &xmit_sem );
-+
-+ if ( 0 == retval )
-+ retval = stSent;
-+ return retval;
-+}
-+
-+static unsigned int usbc_poll( struct file *pFile, poll_table * pWait )
-+{
-+ unsigned int retval = 0;
-+
-+ PRINTK( KERN_DEBUG "%poll()\n", pszMe );
-+
-+ poll_wait( pFile, &wq_poll, pWait );
-+
-+ if ( CIRC_CNT( rx_ring.in, rx_ring.out, RBUF_SIZE ) )
-+ retval |= POLLIN | POLLRDNORM;
-+ if ( sa1100_usb_xmitter_avail() )
-+ retval |= POLLOUT | POLLWRNORM;
-+ return retval;
-+}
-+
-+static int usbc_ioctl( struct inode *pInode, struct file *pFile,
-+ unsigned int nCmd, unsigned long argument )
-+{
-+ int retval = 0;
-+
-+ switch( nCmd ) {
-+
-+ case USBC_IOC_FLUSH_RECEIVER:
-+ sa1100_usb_recv_reset();
-+ rx_ring.in = rx_ring.out = 0;
-+ break;
-+
-+ case USBC_IOC_FLUSH_TRANSMITTER:
-+ sa1100_usb_send_reset();
-+ break;
-+
-+ case USBC_IOC_FLUSH_ALL:
-+ sa1100_usb_recv_reset();
-+ rx_ring.in = rx_ring.out = 0;
-+ sa1100_usb_send_reset();
-+ break;
-+
-+ default:
-+ retval = -ENOIOCTLCMD;
-+ break;
-+
-+ }
-+ return retval;
-+}
-+
-+
-+static int usbc_close( struct inode *pInode, struct file * pFile )
-+{
-+ PRINTK( KERN_DEBUG "%sclose()\n", pszMe );
-+ if ( --usb_ref_count == 0 ) {
-+ down( &xmit_sem );
-+ usbctl_stop(&usbc_client);
-+ free_txrx_buffers();
-+ del_timer( &tx_timer );
-+ usbctl_close(&usbc_client);
-+ up(&xmit_sem);
-+ }
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Initialization
-+//////////////////////////////////////////////////////////////////////////////
-+
-+static struct file_operations usbc_fops = {
-+ owner: THIS_MODULE,
-+ open: usbc_open,
-+ read: usbc_read,
-+ write: usbc_write,
-+ poll: usbc_poll,
-+ ioctl: usbc_ioctl,
-+ release: usbc_close,
-+};
-+
-+static struct miscdevice usbc_misc_device = {
-+ USBC_MINOR,
-+ "usb_char",
-+ &usbc_fops
-+};
-+
-+/*
-+ * usbc_init()
-+ */
-+
-+static int __init usbc_init( void )
-+{
-+ int rc;
-+
-+#if !defined( CONFIG_ARCH_SA1100 )
-+ return -ENODEV;
-+#endif
-+
-+ if ( (rc = misc_register( &usbc_misc_device )) != 0 ) {
-+ printk( KERN_WARNING "%sCould not register device 10, "
-+ "%d. (%d)\n", pszMe, USBC_MINOR, rc );
-+ return -EBUSY;
-+ }
-+
-+ // initialize wait queues
-+ init_waitqueue_head( &wq_read );
-+ init_waitqueue_head( &wq_write );
-+ init_waitqueue_head( &wq_poll );
-+
-+ // initialize tx timeout timer
-+ init_timer( &tx_timer );
-+ tx_timer.function = tx_timeout;
-+
-+ printk( KERN_INFO "USB Function Character Driver Interface"
-+ " - %s, (C) 2001, Extenex Corp.\n", VERSION
-+ );
-+
-+ return rc;
-+}
-+
-+static void __exit usbc_exit( void )
-+{
-+}
-+
-+module_init(usbc_init);
-+module_exit(usbc_exit);
-+
-+// end: usb-char.c
-+
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb-eth.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,535 @@
-+/*
-+ * Network driver for the SA1100 USB client function
-+ * Copyright (c) 2001 by Nicolas Pitre
-+ *
-+ * This code was loosely inspired by the original initial ethernet test driver
-+ * Copyright (c) Compaq Computer Corporation, 1999
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Issues:
-+ * - DMA needs 8 byte aligned buffer, but causes inefficiencies
-+ * in the IP code.
-+ * - stall endpoint operations appeared to be very unstable.
-+ */
-+
-+/*
-+ * Define RX_NO_COPY if you want data to arrive directly into the
-+ * receive network buffers, instead of arriving into bounce buffer
-+ * and then get copied to network buffer.
-+ *
-+ * Since the SA1100 DMA engine is unable to cope with unaligned
-+ * buffer addresses, we need to use bounce buffers or suffer the
-+ * alignment trap performance hit.
-+ */
-+#undef RX_NO_COPY
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/random.h>
-+#include <linux/usb_ch9.h>
-+
-+#include "client.h"
-+
-+
-+#define ETHERNET_VENDOR_ID 0x049f
-+#define ETHERNET_PRODUCT_ID 0x505A
-+#define MAX_PACKET 32768
-+
-+/*
-+ * This is our usb "packet size", and must match the host "packet size".
-+ */
-+static int usb_rsize = 64;
-+static int usb_wsize = 64;
-+
-+struct usbe_info {
-+ struct net_device dev;
-+ struct usb_client client;
-+ struct sk_buff *cur_tx_skb;
-+ struct sk_buff *next_tx_skb;
-+ struct sk_buff *cur_rx_skb;
-+ struct sk_buff *next_rx_skb;
-+#ifndef RX_NO_COPY
-+ char *dmabuf; // dma expects it's buffers to be aligned on 8 bytes boundary
-+#endif
-+ struct net_device_stats stats;
-+};
-+
-+
-+static int usbeth_change_mtu(struct net_device *dev, int new_mtu)
-+{
-+ if (new_mtu <= sizeof(struct ethhdr) || new_mtu > MAX_PACKET)
-+ return -EINVAL;
-+
-+ // no second zero-length packet read wanted after mtu-sized packets
-+ if (((new_mtu + sizeof(struct ethhdr)) % usb_rsize) == 0)
-+ return -EDOM;
-+
-+ dev->mtu = new_mtu;
-+ return 0;
-+}
-+
-+static struct sk_buff *usb_new_recv_skb(struct usbe_info *usbe)
-+{
-+ struct sk_buff *skb;
-+
-+ skb = alloc_skb(2 + sizeof(struct ethhdr) + usbe->dev.mtu,
-+ GFP_ATOMIC);
-+
-+ if (skb)
-+ skb_reserve(skb, 2);
-+
-+ return skb;
-+}
-+
-+static void usbeth_recv_callback(void *data, int flag, int len)
-+{
-+ struct usbe_info *usbe = data;
-+ struct sk_buff *skb;
-+ unsigned int size;
-+ char *buf;
-+
-+ skb = usbe->cur_rx_skb;
-+
-+ /* flag validation */
-+ if (flag != 0)
-+ goto error;
-+
-+ /*
-+ * Make sure we have enough room left in the buffer.
-+ */
-+ if (len > skb_tailroom(skb)) {
-+ usbe->stats.rx_over_errors++;
-+ usbe->stats.rx_errors++;
-+ goto oversize;
-+ }
-+
-+ /*
-+ * If the packet is smaller than usb_rsize bytes, the packet
-+ * is complete, and we need to use the next receive buffer.
-+ */
-+ if (len != usb_rsize)
-+ usbe->cur_rx_skb = usbe->next_rx_skb;
-+
-+ /*
-+ * Put the data onto the socket buffer and resume USB receive.
-+ */
-+#ifndef RX_NO_COPY
-+ memcpy(skb_put(skb, len), usbe->dmabuf, len);
-+ buf = usbe->dmabuf;
-+ size = usb_rsize;
-+#else
-+ skb_put(skb, len);
-+ buf = usbe->cur_rx_skb->tail;
-+ size = skb_tailroom(usbe->cur_rx_skb);
-+#endif
-+ usbctl_ep_queue_buffer(usbe->client.ctl, 1, buf, size);
-+
-+ if (len == usb_rsize)
-+ return;
-+
-+ /*
-+ * A frame must contain at least an ethernet header.
-+ */
-+ if (skb->len < sizeof(struct ethhdr)) {
-+ usbe->stats.rx_length_errors++;
-+ usbe->stats.rx_errors++;
-+ goto recycle;
-+ }
-+
-+ /*
-+ * MAC must match our address or the broadcast address.
-+ * Really, we should let any packet through, otherwise
-+ * things that rely on multicast won't work.
-+ */
-+ if (memcmp(skb->data, usbe->dev.dev_addr, ETH_ALEN) &&
-+ memcmp(skb->data, usbe->dev.broadcast, ETH_ALEN)) {
-+ usbe->stats.rx_frame_errors++;
-+ usbe->stats.rx_errors++;
-+ goto recycle;
-+ }
-+
-+ /*
-+ * We're going to consume this SKB. Get a new skb to
-+ * replace it with. IF this fails, we'd better recycle
-+ * the one we have.
-+ */
-+ usbe->next_rx_skb = usb_new_recv_skb(usbe);
-+ if (!usbe->next_rx_skb) {
-+ if (net_ratelimit())
-+ printk(KERN_ERR "%s: can't allocate new rx skb\n",
-+ usbe->dev.name);
-+ usbe->stats.rx_dropped++;
-+ goto recycle;
-+ }
-+
-+// FIXME: eth_copy_and_csum "small" packets to new SKB (small < ~200 bytes) ?
-+
-+ usbe->stats.rx_packets++;
-+ usbe->stats.rx_bytes += skb->len;
-+ usbe->dev.last_rx = jiffies;
-+
-+ skb->dev = &usbe->dev;
-+ skb->protocol = eth_type_trans(skb, &usbe->dev);
-+ skb->ip_summed = CHECKSUM_NONE;
-+
-+ if (netif_rx(skb) == NET_RX_DROP)
-+ usbe->stats.rx_dropped++;
-+ return;
-+
-+ error:
-+ /*
-+ * Oops, IO error, or stalled.
-+ */
-+ switch (flag) {
-+ case -EIO: /* aborted transfer */
-+ usbe->stats.rx_errors++;
-+ break;
-+
-+ case -EPIPE: /* fifo screwed/no data */
-+ usbe->stats.rx_fifo_errors++;
-+ usbe->stats.rx_errors++;
-+ break;
-+
-+ case -EINTR: /* reset */
-+ break;
-+
-+ case -EAGAIN: /* initialisation */
-+ break;
-+ }
-+
-+ oversize:
-+ skb_trim(skb, 0);
-+
-+#ifndef RX_NO_COPY
-+ buf = usbe->dmabuf;
-+ size = usb_rsize;
-+#else
-+ buf = skb->tail;
-+ size = skb_tailroom(skb);
-+#endif
-+ usbctl_ep_queue_buffer(usbe->client.ctl, 1, buf, size);
-+ return;
-+
-+ recycle:
-+ skb_trim(skb, 0);
-+ usbe->next_rx_skb = skb;
-+ return;
-+}
-+
-+/*
-+ * Send a skb.
-+ *
-+ * Note that the receiver expects the last packet to be a non-multiple
-+ * of its rsize. If the packet length is a muliple of wsize (and
-+ * therefore the remote rsize) tweak the length.
-+ */
-+static void usbeth_send(struct sk_buff *skb, struct usbe_info *usbe)
-+{
-+ unsigned int len = skb->len;
-+ int ret;
-+
-+ if ((len % usb_wsize) == 0)
-+ len++;
-+
-+ ret = usbctl_ep_queue_buffer(usbe->client.ctl, 2, skb->data, len);
-+ if (ret) {
-+ printk(KERN_ERR "%s: tx dropping packet: %d\n",
-+ usbe->dev.name, ret);
-+
-+ /*
-+ * If the USB core can't accept the packet, we drop it.
-+ */
-+ dev_kfree_skb_irq(skb);
-+
-+ usbe->cur_tx_skb = NULL;
-+ usbe->stats.tx_carrier_errors++;
-+ } else {
-+ usbe->dev.trans_start = jiffies;
-+ }
-+}
-+
-+static void usbeth_send_callback(void *data, int flag, int size)
-+{
-+ struct usbe_info *usbe = data;
-+ struct sk_buff *skb = usbe->cur_tx_skb;
-+
-+ switch (flag) {
-+ case 0:
-+ usbe->stats.tx_packets++;
-+ usbe->stats.tx_bytes += skb->len;
-+ break;
-+ case -EIO:
-+ usbe->stats.tx_errors++;
-+ break;
-+ default:
-+ usbe->stats.tx_dropped++;
-+ break;
-+ }
-+
-+ dev_kfree_skb_irq(skb);
-+
-+ skb = usbe->cur_tx_skb = usbe->next_tx_skb;
-+ usbe->next_tx_skb = NULL;
-+
-+ if (skb)
-+ usbeth_send(skb, usbe);
-+
-+ netif_wake_queue(&usbe->dev);
-+}
-+
-+static int usbeth_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+ struct usbe_info *usbe = dev->priv;
-+ unsigned long flags;
-+
-+ if (usbe->next_tx_skb) {
-+ printk(KERN_ERR "%s: called with next_tx_skb != NULL\n",
-+ usbe->dev.name);
-+ return 1;
-+ }
-+
-+ local_irq_save(flags);
-+ if (usbe->cur_tx_skb) {
-+ usbe->next_tx_skb = skb;
-+ netif_stop_queue(dev);
-+ } else {
-+ usbe->cur_tx_skb = skb;
-+
-+ usbeth_send(skb, usbe);
-+ }
-+ local_irq_restore(flags);
-+ return 0;
-+}
-+
-+/*
-+ * Transmit timed out. Reset the endpoint, and re-queue the pending
-+ * packet. If we have a free transmit slot, wake the transmit queue.
-+ */
-+static void usbeth_xmit_timeout(struct net_device *dev)
-+{
-+ struct usbe_info *usbe = dev->priv;
-+ unsigned long flags;
-+
-+ usbctl_ep_reset(usbe->client.ctl, 2);
-+
-+ local_irq_save(flags);
-+ if (usbe->cur_tx_skb)
-+ usbeth_send(usbe->cur_tx_skb, usbe);
-+
-+ if (usbe->next_tx_skb == NULL)
-+ netif_wake_queue(dev);
-+
-+ usbe->stats.tx_errors++;
-+ local_irq_restore(flags);
-+}
-+
-+static int usbeth_open(struct net_device *dev)
-+{
-+ struct usbe_info *usbe = dev->priv;
-+ unsigned char *buf;
-+ unsigned int size;
-+
-+ usbctl_ep_set_callback(usbe->client.ctl, 2, usbeth_send_callback, usbe);
-+ usbctl_ep_set_callback(usbe->client.ctl, 1, usbeth_recv_callback, usbe);
-+
-+ usbe->cur_tx_skb = usbe->next_tx_skb = NULL;
-+ usbe->cur_rx_skb = usb_new_recv_skb(usbe);
-+ usbe->next_rx_skb = usb_new_recv_skb(usbe);
-+ if (!usbe->cur_rx_skb || !usbe->next_rx_skb) {
-+ printk(KERN_ERR "%s: can't allocate new skb\n",
-+ usbe->dev.name);
-+ if (usbe->cur_rx_skb)
-+ kfree_skb(usbe->cur_rx_skb);
-+ if (usbe->next_rx_skb)
-+ kfree_skb(usbe->next_rx_skb);
-+ return -ENOMEM;;
-+ }
-+#ifndef RX_NO_COPY
-+ buf = usbe->dmabuf;
-+ size = usb_rsize;
-+#else
-+ buf = usbe->cur_rx_skb->tail;
-+ size = skb_tailroom(usbe->cur_rx_skb);
-+#endif
-+ usbctl_ep_queue_buffer(usbe->client.ctl, 1, buf, size);
-+
-+ if (netif_carrier_ok(dev))
-+ netif_start_queue(dev);
-+
-+ return 0;
-+}
-+
-+static int usbeth_close(struct net_device *dev)
-+{
-+ struct usbe_info *usbe = dev->priv;
-+
-+ netif_stop_queue(dev);
-+
-+ usbctl_ep_set_callback(usbe->client.ctl, 2, NULL, NULL);
-+ usbctl_ep_set_callback(usbe->client.ctl, 1, NULL, NULL);
-+ usbctl_ep_reset(usbe->client.ctl, 2);
-+ usbctl_ep_reset(usbe->client.ctl, 1);
-+
-+ if (usbe->cur_tx_skb)
-+ kfree_skb(usbe->cur_tx_skb);
-+ if (usbe->next_tx_skb)
-+ kfree_skb(usbe->next_tx_skb);
-+ if (usbe->cur_rx_skb)
-+ kfree_skb(usbe->cur_rx_skb);
-+ if (usbe->next_rx_skb)
-+ kfree_skb(usbe->next_rx_skb);
-+
-+ return 0;
-+}
-+
-+static struct net_device_stats *usbeth_stats(struct net_device *dev)
-+{
-+ struct usbe_info *usbe = dev->priv;
-+
-+ return &usbe->stats;
-+}
-+
-+static int __init usbeth_probe(struct net_device *dev)
-+{
-+ u8 node_id[ETH_ALEN];
-+
-+ SET_MODULE_OWNER(dev);
-+
-+ /*
-+ * Assign the hardware address of the board:
-+ * generate it randomly, as there can be many such
-+ * devices on the bus.
-+ */
-+ get_random_bytes(node_id, sizeof node_id);
-+ node_id[0] &= 0xfe; // clear multicast bit
-+ memcpy(dev->dev_addr, node_id, sizeof node_id);
-+
-+ ether_setup(dev);
-+ dev->flags &= ~IFF_MULTICAST;
-+ dev->flags &= ~IFF_BROADCAST;
-+ //dev->flags |= IFF_NOARP;
-+
-+ return 0;
-+}
-+
-+/*
-+ * This is called when something in the upper usb client layers
-+ * changes that affects the endpoint connectivity state (eg,
-+ * connection or disconnection from the host.) We probably want
-+ * to do some more handling here, like kicking off a pending
-+ * transmission if we're running?
-+ */
-+static void usbeth_state_change(void *data, int state, int oldstate)
-+{
-+ struct usbe_info *usbe = data;
-+
-+ if (state == USB_STATE_CONFIGURED) {
-+ netif_carrier_on(&usbe->dev);
-+ if (netif_running(&usbe->dev))
-+ netif_wake_queue(&usbe->dev);
-+ } else {
-+ if (netif_running(&usbe->dev))
-+ netif_stop_queue(&usbe->dev);
-+ netif_carrier_off(&usbe->dev);
-+ }
-+}
-+
-+static struct usbe_info usbe_info = {
-+ .dev = {
-+ .name = "usbf",
-+ .init = usbeth_probe,
-+ .get_stats = usbeth_stats,
-+ .watchdog_timeo = 1 * HZ,
-+ .open = usbeth_open,
-+ .stop = usbeth_close,
-+ .hard_start_xmit = usbeth_xmit,
-+ .change_mtu = usbeth_change_mtu,
-+ .tx_timeout = usbeth_xmit_timeout,
-+ .priv = &usbe_info,
-+ },
-+ .client = {
-+ .name = "usbeth",
-+ .priv = &usbe_info,
-+ .state_change = usbeth_state_change,
-+
-+ /*
-+ * USB client identification for host use in CPU endian.
-+ */
-+ .vendor = ETHERNET_VENDOR_ID,
-+ .product = ETHERNET_PRODUCT_ID,
-+ .version = 0,
-+ .class = 0xff, /* vendor specific */
-+ .subclass = 0,
-+ .protocol = 0,
-+
-+ .product_str = "SA1100 USB NIC",
-+ },
-+};
-+
-+static int __init usbeth_init(void)
-+{
-+ int rc;
-+
-+#ifndef RX_NO_COPY
-+ usbe_info.dmabuf = kmalloc(usb_rsize, GFP_KERNEL | GFP_DMA);
-+ if (!usbe_info.dmabuf)
-+ return -ENOMEM;
-+#endif
-+
-+ if (register_netdev(&usbe_info.dev) != 0) {
-+#ifndef RX_NO_COPY
-+ kfree(usbe_info.dmabuf);
-+#endif
-+ return -EIO;
-+ }
-+
-+ rc = usbctl_open(&usbe_info.client);
-+ if (rc == 0) {
-+ struct cdb *cdb = sa1100_usb_get_descriptor_ptr();
-+
-+ cdb->ep1.wMaxPacketSize = cpu_to_le16(usb_rsize);
-+ cdb->ep2.wMaxPacketSize = cpu_to_le16(usb_wsize);
-+
-+ rc = usbctl_start(&usbe_info.client);
-+ if (rc)
-+ usbctl_close(&usbe_info.client);
-+ }
-+
-+ if (rc) {
-+ unregister_netdev(&usbe_info.dev);
-+#ifndef RX_NO_COPY
-+ kfree(usbe_info.dmabuf);
-+#endif
-+ }
-+
-+ return rc;
-+}
-+
-+static void __exit usbeth_cleanup(void)
-+{
-+ usbctl_stop(&usbe_info.client);
-+ usbctl_close(&usbe_info.client);
-+
-+ unregister_netdev(&usbe_info.dev);
-+#ifndef RX_NO_COPY
-+ kfree(usbe_info.dmabuf);
-+#endif
-+}
-+
-+module_init(usbeth_init);
-+module_exit(usbeth_cleanup);
-+
-+MODULE_DESCRIPTION("USB client ethernet driver");
-+MODULE_PARM(usb_rsize, "1i");
-+MODULE_PARM_DESC(usb_rsize, "number of bytes in packets from host to sa11x0");
-+MODULE_PARM(usb_wsize, "1i");
-+MODULE_PARM_DESC(usb_wsize, "number of bytes in packets from sa11x0 to host");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb_recv.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,318 @@
-+/*
-+ * Generic receive layer for the SA1100 USB client function
-+ * Copyright (c) 2001 by Nicolas Pitre
-+ *
-+ * This code was loosely inspired by the original version which was
-+ * Copyright (c) Compaq Computer Corporation, 1998-1999
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This is still work in progress...
-+ *
-+ * Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+#include <linux/errno.h>
-+#include <linux/usb_ch9.h>
-+
-+#include <asm/byteorder.h>
-+#include <asm/dma.h>
-+
-+#include "sa1100_usb.h"
-+#include "sa1100usb.h"
-+
-+static int naking;
-+
-+#if 1
-+static void dump_buf(struct sausb_dev *usb, const char *prefix)
-+{
-+ printk("%s: buf [dma=%08x len=%3d] pkt [cpu=%08x dma=%08x len=%3d rem=%3d]\n",
-+ prefix,
-+ usb->ep[0].bufdma,
-+ usb->ep[0].buflen,
-+ (unsigned int)usb->ep[0].pktcpu,
-+ usb->ep[0].pktdma,
-+ usb->ep[0].pktlen,
-+ usb->ep[0].pktrem);
-+}
-+#endif
-+
-+static void udc_ep1_done(struct sausb_dev *usb, int flag, int size)
-+{
-+// printk("UDC: rxd: %3d %3d\n", flag, size);
-+ dump_buf(usb, "UDC: rxd");
-+
-+ if (!usb->ep[0].buflen)
-+ return;
-+
-+ dma_unmap_single(usb->dev, usb->ep[0].bufdma, usb->ep[0].buflen,
-+ DMA_FROM_DEVICE);
-+
-+ usb->ep[0].bufdma = 0;
-+ usb->ep[0].buflen = 0;
-+ usb->ep[0].pktcpu = NULL;
-+ usb->ep[0].pktdma = 0;
-+ usb->ep[0].pktlen = 0;
-+ usb->ep[0].pktrem = 0;
-+
-+ if (usb->ep[0].cb_func)
-+ usb->ep[0].cb_func(usb->ep[0].cb_data, flag, size);
-+}
-+
-+/*
-+ * Initialisation. Clear out the status, and set FST.
-+ */
-+void udc_ep1_init(struct sausb_dev *usb)
-+{
-+ sa1100_reset_dma(usb->ep[0].dmach);
-+
-+ UDC_clear(Ser0UDCCS1, UDCCS1_FST | UDCCS1_RPE | UDCCS1_RPC);
-+
-+ BUG_ON(usb->ep[0].buflen);
-+ BUG_ON(usb->ep[0].pktlen);
-+}
-+
-+void udc_ep1_halt(struct sausb_dev *usb, int halt)
-+{
-+ if (halt) {
-+ /* force stall at UDC */
-+ UDC_set(Ser0UDCCS1, UDCCS1_FST);
-+ } else {
-+ sa1100_reset_dma(usb->ep[0].dmach);
-+
-+ UDC_clear(Ser0UDCCS1, UDCCS1_FST);
-+
-+ udc_ep1_done(usb, -EINTR, 0);
-+ }
-+}
-+
-+/*
-+ * This gets called when we receive a SET_CONFIGURATION packet to EP0.
-+ * We were configured. We can now accept packets from the host.
-+ */
-+void udc_ep1_config(struct sausb_dev *usb, unsigned int maxpktsize)
-+{
-+ usb->ep[0].maxpktsize = maxpktsize;
-+ usb->ep[0].configured = 1;
-+
-+ Ser0UDCOMP = maxpktsize - 1;
-+
-+ sa1100_reset_dma(usb->ep[0].dmach);
-+ udc_ep1_done(usb, -EINTR, 0);
-+
-+ /*
-+ * Enable EP1 interrupts.
-+ */
-+ usb->udccr &= ~UDCCR_RIM;
-+ UDC_write(Ser0UDCCR, usb->udccr);
-+}
-+
-+/*
-+ * We saw a reset from the attached hub. This means we are no
-+ * longer configured, and as far as the rest of the world is
-+ * concerned, we don't exist.
-+ */
-+void udc_ep1_reset(struct sausb_dev *usb)
-+{
-+ /*
-+ * Disable EP1 interrupts.
-+ */
-+ usb->udccr |= UDCCR_RIM;
-+ UDC_write(Ser0UDCCR, usb->udccr);
-+
-+ usb->ep[0].configured = 0;
-+ usb->ep[0].maxpktsize = 0;
-+
-+ sa1100_reset_dma(usb->ep[0].dmach);
-+ udc_ep1_done(usb, -EINTR, 0);
-+}
-+
-+void udc_ep1_int_hndlr(struct sausb_dev *usb)
-+{
-+ dma_addr_t dma_addr;
-+ unsigned int len;
-+ u32 status = Ser0UDCCS1;
-+
-+ dump_buf(usb, "UDC: int");
-+
-+ if (naking) {
-+ printk("UDC: usbrx: in ISR but naking [0x%02x]\n", status);
-+ return;
-+ }
-+
-+ if (!(status & UDCCS1_RPC))
-+ /* you can get here if we are holding NAK */
-+ return;
-+
-+ if (!usb->ep[0].buflen) {
-+ printk("UDC: usb_recv: RPC for non-existent buffer [0x%02x]\n", status);
-+ naking = 1;
-+ return;
-+ }
-+
-+ sa1100_stop_dma(usb->ep[0].dmach);
-+
-+ dma_addr = sa1100_get_dma_pos(usb->ep[0].dmach);
-+
-+ /*
-+ * We've finished with the DMA for this packet.
-+ */
-+ sa1100_clear_dma(usb->ep[0].dmach);
-+
-+ if (status & UDCCS1_SST) {
-+ printk("UDC: usb_recv: stall sent\n");
-+ UDC_flip(Ser0UDCCS1, UDCCS1_SST);
-+
-+ /*
-+ * UDC aborted current transfer, so we do.
-+ *
-+ * It would be better to re-queue this buffer IMHO. It
-+ * hasn't gone anywhere yet. --rmk
-+ */
-+ UDC_flip(Ser0UDCCS1, UDCCS1_RPC);
-+ udc_ep1_done(usb, -EIO, 0);
-+ return;
-+ }
-+
-+ if (status & UDCCS1_RPE) {
-+ printk("UDC: usb_recv: RPError %x\n", status);
-+ UDC_flip(Ser0UDCCS1, UDCCS1_RPC);
-+ udc_ep1_done(usb, -EIO, 0);
-+ return;
-+ }
-+
-+ len = dma_addr - usb->ep[0].pktdma;
-+ if (len < 0) {
-+ printk("UDC: usb_recv: dma_addr (%x) < pktdma (%x)\n",
-+ dma_addr, usb->ep[0].pktdma);
-+ len = 0;
-+ }
-+
-+ if (len > usb->ep[0].pktlen)
-+ len = usb->ep[0].pktlen;
-+
-+ /*
-+ * If our transfer was smaller, and we have bytes left in
-+ * the FIFO, we need to read them out manually.
-+ */
-+ if (len < usb->ep[0].pktlen && (Ser0UDCCS1 & UDCCS1_RNE)) {
-+ char *buf;
-+
-+ dma_sync_single(usb->dev, usb->ep[0].pktdma + len,
-+ usb->ep[0].pktlen - len, DMA_FROM_DEVICE);
-+
-+ buf = (char *)usb->ep[0].pktcpu + len;
-+
-+ do {
-+ *buf++ = Ser0UDCDR;
-+ len++;
-+ } while (len < usb->ep[0].pktlen && (Ser0UDCCS1 & UDCCS1_RNE));
-+
-+ /*
-+ * Note: knowing the internals of this macro is BAD, but we
-+ * need this to cause the data to be written back to memory.
-+ */
-+ dma_sync_single(usb->dev, usb->ep[0].pktdma + len,
-+ usb->ep[0].pktlen - len, DMA_TO_DEVICE);
-+ }
-+
-+ /*
-+ * If the FIFO still contains data, something's definitely wrong.
-+ */
-+ if (Ser0UDCCS1 & UDCCS1_RNE) {
-+ printk("UDC: usb_recv: fifo screwed, shouldn't contain data\n");
-+ usb->ep[0].fifo_errs++;
-+ naking = 1;
-+ udc_ep1_done(usb, -EPIPE, 0);
-+ return;
-+ }
-+
-+ /*
-+ * Do statistics.
-+ */
-+ if (len) {
-+ usb->ep[0].bytes += len;
-+ usb->ep[0].packets ++;
-+ }
-+
-+ /*
-+ * Update remaining byte count for this buffer.
-+ */
-+ usb->ep[0].pktrem -= len;
-+
-+ /*
-+ * If we received a full-sized packet, and there's more
-+ * data remaining, th, queue up another receive.
-+ */
-+ if (len == usb->ep[0].pktlen && usb->ep[0].pktrem != 0) {
-+ usb->ep[0].pktcpu += len;
-+ usb->ep[0].pktdma += len;
-+ usb->ep[0].pktlen = min(usb->ep[0].pktrem, usb->ep[0].maxpktsize);
-+ sa1100_start_dma(usb->ep[0].dmach, usb->ep[0].pktdma, usb->ep[0].pktlen);
-+ /*
-+ * Clear RPC to receive next packet.
-+ */
-+ UDC_flip(Ser0UDCCS1, UDCCS1_RPC);
-+ dump_buf(usb, "UDC: req");
-+ return;
-+ }
-+
-+ naking = 1;
-+ udc_ep1_done(usb, 0, usb->ep[0].buflen - usb->ep[0].pktrem);
-+}
-+
-+int udc_ep1_queue_buffer(struct sausb_dev *usb, char *buf, unsigned int len)
-+{
-+ unsigned long flags;
-+ dma_addr_t dma;
-+ int ret;
-+
-+ if (!buf || len == 0)
-+ return -EINVAL;
-+
-+ dma = dma_map_single(usb->dev, buf, len, DMA_FROM_DEVICE);
-+
-+ spin_lock_irqsave(&usb->lock, flags);
-+ do {
-+ if (usb->ep[0].buflen) {
-+ ret = -EBUSY;
-+ break;
-+ }
-+
-+ sa1100_clear_dma(usb->ep[0].dmach);
-+
-+ usb->ep[0].bufdma = dma;
-+ usb->ep[0].buflen = len;
-+ usb->ep[0].pktcpu = buf;
-+ usb->ep[0].pktdma = dma;
-+ usb->ep[0].pktlen = min(len, usb->ep[0].maxpktsize);
-+ usb->ep[0].pktrem = len;
-+
-+ sa1100_start_dma(usb->ep[0].dmach, usb->ep[0].bufdma, usb->ep[0].buflen);
-+ dump_buf(usb, "UDC: que");
-+
-+ if (naking) {
-+ /* turn off NAK of OUT packets, if set */
-+ UDC_flip(Ser0UDCCS1, UDCCS1_RPC);
-+ naking = 0;
-+ }
-+
-+ ret = 0;
-+ } while (0);
-+ spin_unlock_irqrestore(&usb->lock, flags);
-+
-+ if (ret)
-+ dma_unmap_single(usb->dev, dma, len, DMA_FROM_DEVICE);
-+
-+ return 0;
-+}
-+
-+void udc_ep1_recv_reset(struct sausb_dev *usb)
-+{
-+ sa1100_reset_dma(usb->ep[0].dmach);
-+ udc_ep1_done(usb, -EINTR, 0);
-+}
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/buffer.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,63 @@
-+/*
-+ * usb/buffer.c
-+ *
-+ * Copyright (C) 2002 Russell King.
-+ */
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+
-+#include "buffer.h"
-+
-+static LIST_HEAD(buffers);
-+
-+struct usb_buf *usbb_alloc(int size, int gfp)
-+{
-+ unsigned long flags;
-+ struct usb_buf *buf;
-+
-+ buf = kmalloc(sizeof(struct usb_buf) + size, gfp);
-+ if (buf) {
-+ atomic_set(&buf->users, 1);
-+ local_irq_save(flags);
-+ list_add(&buf->list, &buffers);
-+ local_irq_restore(flags);
-+ buf->len = 0;
-+ buf->data = (unsigned char *) (buf + 1);
-+ buf->head = (unsigned char *) (buf + 1);
-+ }
-+
-+ return buf;
-+}
-+
-+void __usbb_free(struct usb_buf *buf)
-+{
-+ unsigned long flags;
-+ local_irq_save(flags);
-+ list_del(&buf->list);
-+ local_irq_restore(flags);
-+ kfree(buf);
-+}
-+
-+EXPORT_SYMBOL(usbb_alloc);
-+EXPORT_SYMBOL(__usbb_free);
-+
-+static void __exit usbb_exit(void)
-+{
-+ if (!list_empty(&buffers)) {
-+ struct list_head *l, *n;
-+ printk("usbb: buffers not freed:\n");
-+
-+ list_for_each_safe(l, n, &buffers) {
-+ struct usb_buf *b = list_entry(l, struct usb_buf, list);
-+
-+ printk(" %p: alloced from %p count %d\n",
-+ b, b->alloced_by, atomic_read(&b->users));
-+
-+ __usbb_free(b);
-+ }
-+ }
-+}
-+
-+module_exit(usbb_exit);
-+
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb-char.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,34 @@
-+/*
-+ * Copyright (C) 2001 Extenex Corporation
-+ *
-+ * usb-char.h
-+ *
-+ * Character device emulation client for SA-1100 client usb core.
-+ *
-+ *
-+ *
-+ */
-+#ifndef _USB_CHAR_H
-+#define _USB_CHAR_H
-+
-+#define USBC_MAJOR 10 /* miscellaneous character device */
-+#define USBC_MINOR 240 /* in the "reserved for local use" range */
-+
-+#define USBC_MAGIC 0x8E
-+
-+/* zap everything in receive ring buffer */
-+#define USBC_IOC_FLUSH_RECEIVER _IO( USBC_MAGIC, 0x01 )
-+
-+/* reset transmitter */
-+#define USBC_IOC_FLUSH_TRANSMITTER _IO( USBC_MAGIC, 0x02 )
-+
-+/* do both of above */
-+#define USBC_IOC_FLUSH_ALL _IO( USBC_MAGIC, 0x03 )
-+
-+
-+
-+
-+
-+
-+#endif /* _USB_CHAR_H */
-+
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/buffer.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,45 @@
-+/*
-+ * usb/buffer.h: USB client buffers
-+ *
-+ * Copyright (C) 2002 Russell King.
-+ *
-+ * Loosely based on linux/skbuff.h
-+ */
-+#ifndef USBDEV_BUFFER_H
-+#define USBDEV_BUFFER_H
-+
-+#include <linux/list.h>
-+
-+struct usb_buf {
-+ atomic_t users;
-+ struct list_head list;
-+ void *alloced_by;
-+ unsigned char *data;
-+ unsigned char *head;
-+ unsigned int len;
-+};
-+
-+extern struct usb_buf *usbb_alloc(int size, int gfp);
-+extern void __usbb_free(struct usb_buf *);
-+
-+static inline struct usb_buf *usbb_get(struct usb_buf *buf)
-+{
-+ atomic_inc(&buf->users);
-+ return buf;
-+}
-+
-+static inline void usbb_put(struct usb_buf *buf)
-+{
-+ if (atomic_dec_and_test(&buf->users))
-+ __usbb_free(buf);
-+}
-+
-+static inline void *usbb_push(struct usb_buf *buf, int len)
-+{
-+ unsigned char *b = buf->head;
-+ buf->head += len;
-+ buf->len += len;
-+ return b;
-+}
-+
-+#endif
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/sa1100usb.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,1160 @@
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h>
-+#include <linux/usb_ch9.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/spinlock.h>
-+#include <linux/device.h>
-+
-+#include <asm/mach-types.h>
-+#include <asm/io.h>
-+#include <asm/dma.h>
-+#include <asm/irq.h>
-+
-+#include "buffer.h"
-+#include "usbdev.h"
-+#include "sa1100_usb.h"
-+#include "sa1100usb.h"
-+
-+#ifdef DEBUG
-+#define DPRINTK(fmt, args...) printk( fmt , ## args)
-+#else
-+#define DPRINTK(fmt, args...)
-+#endif
-+
-+static inline void pcs(const char *prefix)
-+{
-+#ifdef DEBUG
-+ __u32 foo = Ser0UDCCS0;
-+
-+ DPRINTK("%s UDCAR: %d\n", prefix, Ser0UDCAR);
-+
-+ printk("UDC: %s: %08x [ %s%s%s%s%s%s]\n", prefix,
-+ foo,
-+ foo & UDCCS0_SE ? "SE " : "",
-+ foo & UDCCS0_DE ? "DE " : "",
-+ foo & UDCCS0_FST ? "FST " : "",
-+ foo & UDCCS0_SST ? "SST " : "",
-+ foo & UDCCS0_IPR ? "IPR " : "",
-+ foo & UDCCS0_OPR ? "OPR " : "");
-+#endif
-+}
-+
-+/*
-+ * soft_connect_hook()
-+ *
-+ * Some devices have platform-specific circuitry to make USB
-+ * not seem to be plugged in, even when it is. This allows
-+ * software to control when a device 'appears' on the USB bus
-+ * (after Linux has booted and this driver has loaded, for
-+ * example). If you have such a circuit, control it here.
-+ */
-+static inline void soft_connect_hook(int enable)
-+{
-+#ifdef CONFIG_SA1100_EXTENEX1
-+ if (machine_is_extenex1()) {
-+ if (enable) {
-+ PPDR |= PPC_USB_SOFT_CON;
-+ PPSR |= PPC_USB_SOFT_CON;
-+ } else {
-+ PPSR &= ~PPC_USB_SOFT_CON;
-+ PPDR &= ~PPC_USB_SOFT_CON;
-+ }
-+ }
-+#endif
-+}
-+
-+/*
-+ * disable the UDC at the source
-+ */
-+static inline void udc_disable(struct sausb_dev *usb)
-+{
-+ soft_connect_hook(0);
-+
-+ usb->udccr = UDCCR_UDD | UDCCR_SUSIM;
-+
-+ UDC_write(Ser0UDCCR, usb->udccr);
-+}
-+
-+/*
-+ * Clear any pending write from the EP0 write buffer.
-+ */
-+static void ep0_clear_write(struct sausb_dev *usb)
-+{
-+ struct usb_buf *buf;
-+
-+ buf = usb->wrbuf;
-+ usb->wrint = NULL;
-+ usb->wrbuf = NULL;
-+ usb->wrptr = NULL;
-+ usb->wrlen = 0;
-+
-+ if (buf)
-+ usbb_put(buf);
-+}
-+
-+static int udc_start(void *priv)
-+{
-+ struct sausb_dev *usb = priv;
-+
-+ usb->ep[0].maxpktsize = 0;
-+ usb->ep[1].maxpktsize = 0;
-+
-+ /*
-+ * start UDC internal machinery running, but mask interrupts.
-+ */
-+ usb->udccr = UDCCR_SUSIM | UDCCR_TIM | UDCCR_RIM | UDCCR_EIM |
-+ UDCCR_RESIM;
-+ UDC_write(Ser0UDCCR, usb->udccr);
-+
-+ udelay(100);
-+
-+ /*
-+ * clear all interrupt sources
-+ */
-+ Ser0UDCSR = UDCSR_RSTIR | UDCSR_RESIR | UDCSR_EIR |
-+ UDCSR_RIR | UDCSR_TIR | UDCSR_SUSIR;
-+
-+ /*
-+ * flush DMA and fire through some -EAGAINs
-+ */
-+ udc_ep1_init(usb);
-+ udc_ep2_init(usb);
-+
-+ /*
-+ * enable any platform specific hardware
-+ */
-+ soft_connect_hook(1);
-+
-+ /*
-+ * Enable resume, suspend and endpoint 0 interrupts. Leave
-+ * endpoint 1 and 2 interrupts masked.
-+ *
-+ * If you are unplugged you will immediately get a suspend
-+ * interrupt. If you are plugged and have a soft connect-circuit,
-+ * you will get a reset. If you are plugged without a soft-connect,
-+ * I think you also get suspend.
-+ */
-+ usb->udccr &= ~(UDCCR_SUSIM | UDCCR_EIM | UDCCR_RESIM);
-+ UDC_write(Ser0UDCCR, usb->udccr);
-+
-+ return 0;
-+}
-+
-+static int udc_stop(void *priv)
-+{
-+ struct sausb_dev *usb = priv;
-+
-+ ep0_clear_write(usb);
-+
-+ /* mask everything */
-+ Ser0UDCCR = 0xFC;
-+
-+ udc_ep1_reset(usb);
-+ udc_ep2_reset(usb);
-+
-+ udc_disable(usb);
-+
-+ return 0;
-+}
-+
-+
-+
-+
-+
-+/*
-+ * some voodo I am adding, since the vanilla macros just aren't doing it
-+ * 1Mar01ww
-+ */
-+
-+#define ABORT_BITS (UDCCS0_SST | UDCCS0_SE)
-+#define OK_TO_WRITE (!(Ser0UDCCS0 & ABORT_BITS))
-+#define BOTH_BITS (UDCCS0_IPR | UDCCS0_DE)
-+
-+static void set_de(void)
-+{
-+ int i = 1;
-+
-+ while (1) {
-+ if (OK_TO_WRITE) {
-+ Ser0UDCCS0 |= UDCCS0_DE;
-+ } else {
-+ DPRINTK("UDC: quitting set DE because SST or SE set\n");
-+ break;
-+ }
-+ if (Ser0UDCCS0 & UDCCS0_DE)
-+ break;
-+ udelay(i);
-+ if (++i == 50) {
-+ printk("UDC: Dangnabbbit! Cannot set DE! (DE=%8.8X CCS0=%8.8X)\n",
-+ UDCCS0_DE, Ser0UDCCS0);
-+ break;
-+ }
-+ }
-+}
-+
-+static void set_ipr(void)
-+{
-+ int i = 1;
-+
-+ while (1) {
-+ if (OK_TO_WRITE) {
-+ Ser0UDCCS0 |= UDCCS0_IPR;
-+ } else {
-+ DPRINTK("UDC: Quitting set IPR because SST or SE set\n");
-+ break;
-+ }
-+ if (Ser0UDCCS0 & UDCCS0_IPR)
-+ break;
-+ udelay(i);
-+ if (++i == 50) {
-+ printk("UDC: Dangnabbbit! Cannot set IPR! (IPR=%8.8X CCS0=%8.8X)\n",
-+ UDCCS0_IPR, Ser0UDCCS0);
-+ break;
-+ }
-+ }
-+}
-+
-+static void set_ipr_and_de(void)
-+{
-+ int i = 1;
-+
-+ while (1) {
-+ if (OK_TO_WRITE) {
-+ Ser0UDCCS0 |= BOTH_BITS;
-+ } else {
-+ DPRINTK("UDC: Quitting set IPR/DE because SST or SE set\n");
-+ break;
-+ }
-+ if ((Ser0UDCCS0 & BOTH_BITS) == BOTH_BITS)
-+ break;
-+ udelay(i);
-+ if (++i == 50) {
-+ printk("UDC: Dangnabbbit! Cannot set DE/IPR! (DE=%8.8X IPR=%8.8X CCS0=%8.8X)\n",
-+ UDCCS0_DE, UDCCS0_IPR, Ser0UDCCS0);
-+ break;
-+ }
-+ }
-+}
-+
-+static inline void set_cs_bits(__u32 bits)
-+{
-+ if (bits & (UDCCS0_SO | UDCCS0_SSE | UDCCS0_FST | UDCCS0_SST))
-+ Ser0UDCCS0 = bits;
-+ else if ((bits & BOTH_BITS) == BOTH_BITS)
-+ set_ipr_and_de();
-+ else if (bits & UDCCS0_IPR)
-+ set_ipr();
-+ else if (bits & UDCCS0_DE)
-+ set_de();
-+}
-+
-+/*
-+ * udc_ep0_write_fifo()
-+ *
-+ * Stick bytes in the 8 bytes endpoint zero FIFO. This version uses a
-+ * variety of tricks to make sure the bytes are written correctly:
-+ * 1. The count register is checked to see if the byte went in,
-+ * and the write is attempted again if not.
-+ * 2. An overall counter is used to break out so we don't hang in
-+ * those (rare) cases where the UDC reverses direction of the
-+ * FIFO underneath us without notification (in response to host
-+ * aborting a setup transaction early).
-+ */
-+static void udc_ep0_write_fifo(struct sausb_dev *usb)
-+{
-+ unsigned int bytes_this_time = min(usb->wrlen, 8U);
-+ int bytes_written = 0;
-+
-+ DPRINTK("WF=%d: ", bytes_this_time);
-+
-+ while (bytes_this_time--) {
-+ unsigned int cwc;
-+ int i;
-+
-+ DPRINTK("%2.2X ", *usb->wrptr);
-+
-+ cwc = Ser0UDCWC & 15;
-+
-+ i = 10;
-+ do {
-+ Ser0UDCD0 = *usb->wrptr;
-+ udelay(20); /* voodo 28Feb01ww */
-+ } while ((Ser0UDCWC & 15) == cwc && --i);
-+
-+ if (i == 0) {
-+ printk("UDC: udc_ep0_write_fifo: write failure\n");
-+ usb->ep0_wr_fifo_errs++;
-+ }
-+
-+ usb->wrptr++;
-+ bytes_written++;
-+ }
-+ usb->wrlen -= bytes_written;
-+
-+ /* following propagation voodo so maybe caller writing IPR in
-+ ..a moment might actually get it to stick 28Feb01ww */
-+ udelay(300);
-+
-+ usb->ep0_wr_bytes += bytes_written;
-+ DPRINTK("L=%d WCR=%8.8X\n", usb->wrlen, Ser0UDCWC);
-+}
-+
-+/*
-+ * read_fifo()
-+ *
-+ * Read 1-8 bytes out of FIFO and put in request. Called to do the
-+ * initial read of setup requests from the host. Return number of
-+ * bytes read.
-+ *
-+ * Like write fifo above, this driver uses multiple reads checked
-+ * against the count register with an overall timeout.
-+ */
-+static int
-+udc_ep0_read_fifo(struct sausb_dev *usb, struct usb_ctrlrequest *request, int sz)
-+{
-+ unsigned char *pOut = (unsigned char *) request;
-+ unsigned int fifo_count, bytes_read = 0;
-+
-+ fifo_count = Ser0UDCWC & 15;
-+
-+ DPRINTK("RF=%d ", fifo_count);
-+ BUG_ON(fifo_count > sz);
-+
-+ while (fifo_count--) {
-+ unsigned int cwc;
-+ int i;
-+
-+ cwc = Ser0UDCWC & 15;
-+
-+ i = 10;
-+ do {
-+ *pOut = (unsigned char) Ser0UDCD0;
-+ udelay(20);
-+ } while ((Ser0UDCWC & 15) == cwc && --i);
-+
-+ if (i == 0) {
-+ printk(KERN_ERR "UDC: udc_ep0_read_fifo: read failure\n");
-+ usb->ep0_rd_fifo_errs++;
-+ break;
-+ }
-+ pOut++;
-+ bytes_read++;
-+ }
-+
-+ DPRINTK("fc=%d\n", bytes_read);
-+ usb->ep0_rd_bytes += bytes_read;
-+ usb->ep0_rd_packets ++;
-+ return bytes_read;
-+}
-+
-+static void ep0_sh_write_data(struct sausb_dev *usb)
-+{
-+ /*
-+ * If bytes left is zero, we are coming in on the
-+ * interrupt after the last packet went out. And
-+ * we know we don't have to empty packet this
-+ * transfer so just set DE and we are done
-+ */
-+ set_cs_bits(UDCCS0_DE);
-+}
-+
-+static void ep0_sh_write_with_empty_packet(struct sausb_dev *usb)
-+{
-+ /*
-+ * If bytes left is zero, we are coming in on the
-+ * interrupt after the last packet went out.
-+ * We must do short packet suff, so set DE and IPR
-+ */
-+ set_cs_bits(UDCCS0_IPR | UDCCS0_DE);
-+ DPRINTK("UDC: sh_write_empty: Sent empty packet\n");
-+}
-+
-+static int udc_clear_opr(void)
-+{
-+ int i = 10000;
-+ int is_clear;
-+
-+ /*FIXME*/
-+ do {
-+ Ser0UDCCS0 = UDCCS0_SO;
-+ is_clear = !(Ser0UDCCS0 & UDCCS0_OPR);
-+ if (i-- <= 0)
-+ break;
-+ } while (!is_clear);
-+
-+ return is_clear;
-+}
-+
-+static int udc_ep0_queue(void *priv, struct usb_buf *buf,
-+ unsigned int req_len)
-+{
-+ struct sausb_dev *usb = priv;
-+ __u32 cs_reg_bits = UDCCS0_IPR;
-+
-+ DPRINTK("a=%d r=%d\n", buf->len, req_len);
-+
-+ /*
-+ * thou shalt not enter data phase until
-+ * Out Packet Ready is clear
-+ */
-+ if (!udc_clear_opr()) {
-+ printk("UDC: SO did not clear OPR\n");
-+ set_cs_bits(UDCCS0_DE | UDCCS0_SO);
-+ usbb_put(buf);
-+ return 1;
-+ }
-+
-+ usb->ep0_wr_packets++;
-+
-+ usb->wrbuf = buf;
-+ usb->wrptr = buf->data;
-+ usb->wrlen = min(buf->len, req_len);
-+
-+ udc_ep0_write_fifo(usb);
-+
-+ if (usb->wrlen == 0) {
-+ /*
-+ * out in one, so data end
-+ */
-+ cs_reg_bits |= UDCCS0_DE;
-+ ep0_clear_write(usb);
-+ } else if (buf->len < req_len) {
-+ /*
-+ * we are going to short-change host
-+ * so need nul to not stall
-+ */
-+ usb->wrint = ep0_sh_write_with_empty_packet;
-+ } else {
-+ /*
-+ * we have as much or more than requested
-+ */
-+ usb->wrint = ep0_sh_write_data;
-+ }
-+
-+ /*
-+ * note: IPR was set uncondtionally at start of routine
-+ */
-+ set_cs_bits(cs_reg_bits);
-+ return 0;
-+}
-+
-+/*
-+ * When SO and DE sent, UDC will enter status phase and ack, propagating
-+ * new address to udc core. Next control transfer will be on the new
-+ * address.
-+ *
-+ * You can't see the change in a read back of CAR until then (about 250us
-+ * later, on my box). The original Intel driver sets S0 and DE and code
-+ * to check that address has propagated here. I tried this, but it would
-+ * only sometimes work! The rest of the time it would never propagate and
-+ * we'd spin forever. So now I just set it and pray...
-+ */
-+static void udc_set_address(void *priv, unsigned int addr)
-+{
-+ Ser0UDCAR = addr;
-+}
-+
-+static void udc_set_config(void *priv, struct cdb *cdb)
-+{
-+ struct sausb_dev *usb = priv;
-+
-+ if (cdb) {
-+ udc_ep1_config(usb, le16_to_cpu(cdb->ep1.wMaxPacketSize));
-+ udc_ep2_config(usb, le16_to_cpu(cdb->ep2.wMaxPacketSize));
-+ } else {
-+ udc_ep1_reset(usb);
-+ udc_ep2_reset(usb);
-+ }
-+}
-+
-+static unsigned int udc_ep_get_status(void *priv, unsigned int ep)
-+{
-+ unsigned int status;
-+
-+ switch (ep) {
-+ case 0:
-+ status = (Ser0UDCCS0 & UDCCS0_FST) ? 1 : 0;
-+ break;
-+
-+ case 1:
-+ status = (Ser0UDCCS1 & UDCCS1_FST) ? 1 : 0;
-+ break;
-+
-+ case 2:
-+ status = (Ser0UDCCS2 & UDCCS2_FST) ? 1 : 0;
-+ break;
-+
-+ default:
-+ printk(KERN_ERR "UDC: get_status: bad end point %d\n", ep);
-+ status = 0;
-+ break;
-+ }
-+
-+ return status;
-+}
-+
-+static void udc_ep_halt(void *priv, unsigned int ep, int halt)
-+{
-+ struct sausb_dev *usb = priv;
-+
-+ printk("UDC: ep%d %s halt\n", ep, halt ? "set" : "clear");
-+
-+ switch (ep) {
-+ case 1:
-+ udc_ep1_halt(usb, halt);
-+ break;
-+
-+ case 2:
-+ udc_ep2_halt(usb, halt);
-+ break;
-+ }
-+}
-+
-+static int udc_ep_queue(void *priv, unsigned int ep, char *buf, unsigned int len)
-+{
-+ struct sausb_dev *usb = priv;
-+ int ret = -EINVAL;
-+
-+ switch (ep) {
-+ case 1:
-+ ret = udc_ep1_queue_buffer(usb, buf, len);
-+ break;
-+ case 2:
-+ ret = udc_ep2_send(usb, buf, len);
-+ break;
-+ }
-+
-+ return ret;
-+}
-+
-+static void udc_ep_reset(void *priv, unsigned int ep)
-+{
-+ struct sausb_dev *usb = priv;
-+
-+ switch (ep) {
-+ case 1:
-+ udc_ep1_recv_reset(usb);
-+ break;
-+ case 2:
-+ udc_ep2_send_reset(usb);
-+ break;
-+ }
-+}
-+
-+static void udc_ep_callback(void *priv, unsigned int ep, usb_callback_t cb, void *data)
-+{
-+ struct sausb_dev *usb = priv;
-+ unsigned long flags;
-+
-+ if (ep == 1 || ep == 2) {
-+ ep -= 1;
-+
-+ spin_lock_irqsave(&usb->lock, flags);
-+ usb->ep[ep].cb_func = cb;
-+ usb->ep[ep].cb_data = data;
-+ spin_unlock_irqrestore(&usb->lock, flags);
-+ }
-+}
-+
-+static int udc_ep_idle(void *priv, unsigned int ep)
-+{
-+ struct sausb_dev *usb = priv;
-+ int ret = -EINVAL;
-+
-+ switch (ep) {
-+ case 1:
-+ break;
-+ case 2:
-+ ret = udc_ep2_idle(usb);
-+ break;
-+ }
-+
-+ return ret;
-+}
-+
-+static struct usbc_driver usb_sa1100_drv = {
-+ .owner = THIS_MODULE,
-+ .name = "SA1100",
-+ .start = udc_start,
-+ .stop = udc_stop,
-+ .ep0_queue = udc_ep0_queue,
-+ .set_address = udc_set_address,
-+ .set_config = udc_set_config,
-+ .ep_get_status = udc_ep_get_status,
-+ .ep_halt = udc_ep_halt,
-+ .ep_queue = udc_ep_queue,
-+ .ep_reset = udc_ep_reset,
-+ .ep_callback = udc_ep_callback,
-+ .ep_idle = udc_ep_idle,
-+};
-+
-+
-+/*
-+ * udc_ep0_read_packet()
-+ *
-+ * This setup handler is the "idle" state of endpoint zero. It looks for
-+ * OPR (OUT packet ready) to see if a setup request has been been received
-+ * from the host. Requests without a return data phase are immediately
-+ * handled. Otherwise, the handler may be set to one of the sh_write_xxxx
-+ * data pumpers if more than 8 bytes need to get back to the host.
-+ */
-+static void udc_ep0_read_packet(struct sausb_dev *usb, u32 cs_reg_in)
-+{
-+ struct usb_ctrlrequest req;
-+ int n, ret = RET_NOACTION;
-+
-+ /*
-+ * A control request has been received by EP0.
-+ * Read the request.
-+ */
-+ n = udc_ep0_read_fifo(usb, &req, sizeof(req));
-+
-+ if (n == sizeof(req)) {
-+ ret = usbctl_parse_request(usb->ctl, &req);
-+ } else {
-+ /*
-+ * The request wasn't fully received. Force a
-+ * stall.
-+ */
-+ set_cs_bits(UDCCS0_FST | UDCCS0_SO);
-+ printk("UDC: fifo read error: wanted %d bytes got %d\n",
-+ sizeof(req), n);
-+ }
-+
-+ switch (ret) {
-+ case RET_ERROR:
-+ case RET_NOACTION:
-+ break;
-+
-+ case RET_ACK:
-+ set_cs_bits(UDCCS0_DE | UDCCS0_SO);
-+ break;
-+
-+ case RET_REQERROR:
-+ /*
-+ * Send stall PID to host.
-+ */
-+ set_cs_bits(UDCCS0_DE | UDCCS0_SO | UDCCS0_FST);
-+ break;
-+ }
-+}
-+
-+/*
-+ * HACK DEBUG 3Mar01ww
-+ * Well, maybe not, it really seems to help! 08Mar01ww
-+ */
-+static void core_kicker(struct sausb_dev *usb)
-+{
-+ __u32 car = Ser0UDCAR;
-+ __u32 imp = Ser0UDCIMP;
-+ __u32 omp = Ser0UDCOMP;
-+
-+ UDC_set(Ser0UDCCR, UDCCR_UDD);
-+ udelay(300);
-+ UDC_clear(Ser0UDCCR, UDCCR_UDD);
-+
-+ Ser0UDCAR = car;
-+ Ser0UDCIMP = imp;
-+ Ser0UDCOMP = omp;
-+}
-+
-+static void enable_resume_mask_suspend(struct sausb_dev *usb)
-+{
-+ int i;
-+
-+ usb->udccr |= UDCCR_SUSIM;
-+
-+ i = 1;
-+ do {
-+ Ser0UDCCR = usb->udccr;
-+ udelay(i);
-+ if (Ser0UDCCR == usb->udccr)
-+ break;
-+ if (Ser0UDCSR & UDCSR_RSTIR)
-+ break;
-+ } while (i++ < 50);
-+
-+ if (i == 50)
-+ printk("UDC: enable_resume: could not set SUSIM 0x%08x\n",
-+ Ser0UDCCR);
-+
-+ usb->udccr &= ~UDCCR_RESIM;
-+
-+ i = 1;
-+ do {
-+ Ser0UDCCR = usb->udccr;
-+ udelay(i);
-+ if (Ser0UDCCR == usb->udccr)
-+ break;
-+ if (Ser0UDCSR & UDCSR_RSTIR)
-+ break;
-+ } while (i++ < 50);
-+
-+ if (i == 50)
-+ printk("UDC: enable_resume: could not clear RESIM 0x%08x\n",
-+ Ser0UDCCR);
-+}
-+
-+static void enable_suspend_mask_resume(struct sausb_dev *usb)
-+{
-+ int i;
-+
-+ usb->udccr |= UDCCR_RESIM;
-+
-+ i = 1;
-+ do {
-+ Ser0UDCCR = usb->udccr;
-+ udelay(i);
-+ if (Ser0UDCCR == usb->udccr)
-+ break;
-+ if (Ser0UDCSR & UDCSR_RSTIR)
-+ break;
-+ } while (i++ < 50);
-+
-+ if (i == 50)
-+ printk("UDC: enable_resume: could not set RESIM 0x%08x\n",
-+ Ser0UDCCR);
-+
-+ usb->udccr &= ~UDCCR_SUSIM;
-+
-+ i = 1;
-+ do {
-+ Ser0UDCCR = usb->udccr;
-+ udelay(i);
-+ if (Ser0UDCCR == usb->udccr)
-+ break;
-+ if (Ser0UDCSR & UDCSR_RSTIR)
-+ break;
-+ } while (i++ < 50);
-+
-+ if (i == 50)
-+ printk("UDC: enable_resume: could not clear SUSIM 0x%08x\n",
-+ Ser0UDCCR);
-+}
-+
-+/*
-+ * Reset received from HUB (or controller just went nuts and reset by
-+ * itself!) so UDC core has been reset, track this state here
-+ */
-+static void udc_reset(struct sausb_dev *usb)
-+{
-+ if (usbctl_reset(usb->ctl)) {
-+ ep0_clear_write(usb);
-+
-+ /*
-+ * Clean up endpoints.
-+ */
-+ udc_ep1_reset(usb);
-+ udc_ep2_reset(usb);
-+ }
-+
-+ /*
-+ * mask reset ints, they flood during sequence, enable
-+ * suspend and resume
-+ */
-+ usb->udccr = (usb->udccr & ~(UDCCR_SUSIM | UDCCR_RESIM)) | UDCCR_REM;
-+ Ser0UDCCR = usb->udccr;
-+}
-+
-+/*
-+ * handle interrupt for endpoint zero
-+ */
-+static void udc_ep0_int_hndlr(struct sausb_dev *usb)
-+{
-+ u32 cs_reg_in;
-+
-+ pcs("-->");
-+
-+ cs_reg_in = Ser0UDCCS0;
-+
-+ /*
-+ * If "setup end" has been set, the usb controller has terminated
-+ * a setup transaction before we set DE. This happens during
-+ * enumeration with some hosts. For example, the host will ask for
-+ * our device descriptor and specify a return of 64 bytes. When we
-+ * hand back the first 8, the host will know our max packet size
-+ * and turn around and issue a new setup immediately. This causes
-+ * the UDC to auto-ack the new setup and set SE. We must then
-+ * "unload" (process) the new setup, which is what will happen
-+ * after this preamble is finished executing.
-+ */
-+ if (cs_reg_in & UDCCS0_SE) {
-+ DPRINTK("UDC: early termination of setup\n");
-+
-+ /*
-+ * Clear setup end
-+ */
-+ set_cs_bits(UDCCS0_SSE);
-+
-+ /*
-+ * Clear any pending write.
-+ */
-+ ep0_clear_write(usb);
-+ }
-+
-+ /*
-+ * UDC sent a stall due to a protocol violation.
-+ */
-+ if (cs_reg_in & UDCCS0_SST) {
-+ usb->ep0_stall_sent++;
-+
-+ DPRINTK("UDC: write_preamble: UDC sent stall\n");
-+
-+ /*
-+ * Clear sent stall
-+ */
-+ set_cs_bits(UDCCS0_SST);
-+
-+ /*
-+ * Clear any pending write.
-+ */
-+ ep0_clear_write(usb);
-+ }
-+
-+ switch (cs_reg_in & (UDCCS0_OPR | UDCCS0_IPR)) {
-+ case UDCCS0_OPR | UDCCS0_IPR:
-+ DPRINTK("UDC: write_preamble: see OPR. Stopping write to "
-+ "handle new SETUP\n");
-+
-+ /*
-+ * very rarely, you can get OPR and
-+ * leftover IPR. Try to clear
-+ */
-+ UDC_clear(Ser0UDCCS0, UDCCS0_IPR);
-+
-+ /*
-+ * Clear any pending write.
-+ */
-+ ep0_clear_write(usb);
-+
-+ /*FALLTHROUGH*/
-+ case UDCCS0_OPR:
-+ /*
-+ * A new setup request is pending. Handle
-+ * it. Note that we don't try to read a
-+ * packet if SE was set and OPR is clear.
-+ */
-+ udc_ep0_read_packet(usb, cs_reg_in);
-+ break;
-+
-+ case 0:
-+ if (usb->wrint) {
-+ if (usb->wrlen != 0) {
-+ /*
-+ * More data to go
-+ */
-+ udc_ep0_write_fifo(usb);
-+ set_ipr();
-+ }
-+
-+ if (usb->wrlen == 0) {
-+ /*
-+ * All data sent.
-+ */
-+ usb->wrint(usb);
-+
-+ ep0_clear_write(usb);
-+ }
-+ }
-+ break;
-+
-+ case UDCCS0_IPR:
-+ DPRINTK("UDC: IPR set, not writing\n");
-+ usb->ep0_early_irqs++;
-+ break;
-+ }
-+
-+ pcs("<--");
-+}
-+
-+static irqreturn_t udc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct sausb_dev *usb = dev_id;
-+ u32 status = Ser0UDCSR;
-+
-+ /*
-+ * ReSeT Interrupt Request - UDC has been reset
-+ */
-+ if (status & UDCSR_RSTIR) {
-+ udc_reset(usb);
-+
-+ /*
-+ * clear all pending sources
-+ */
-+ UDC_flip(Ser0UDCSR, status);
-+ return IRQ_HANDLED;
-+ }
-+
-+ /*
-+ * else we have done something other than reset,
-+ * so be sure reset enabled
-+ */
-+ usb->udccr &= ~UDCCR_REM;
-+ UDC_write(Ser0UDCCR, usb->udccr);
-+
-+ /*
-+ * RESume Interrupt Request
-+ */
-+ if (status & UDCSR_RESIR) {
-+ usbctl_resume(usb->ctl);
-+ core_kicker(usb);
-+ enable_suspend_mask_resume(usb);
-+ }
-+
-+ /*
-+ * SUSpend Interrupt Request
-+ */
-+ if (status & UDCSR_SUSIR) {
-+ usbctl_suspend(usb->ctl);
-+ enable_resume_mask_suspend(usb);
-+ }
-+
-+ /*
-+ * clear all pending sources
-+ */
-+ UDC_flip(Ser0UDCSR, status);
-+
-+ if (status & UDCSR_EIR)
-+ udc_ep0_int_hndlr(usb);
-+
-+ if (status & UDCSR_RIR)
-+ udc_ep1_int_hndlr(usb);
-+
-+ if (status & UDCSR_TIR)
-+ udc_ep2_int_hndlr(usb);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+#ifdef CONFIG_PROC_FS
-+
-+#define SAY( fmt, args... ) p += sprintf(p, fmt, ## args )
-+#define SAYV( num ) p += sprintf(p, num_fmt, "Value", num )
-+#define SAYC( label, yn ) p += sprintf(p, yn_fmt, label, yn )
-+#define SAYS( label, v ) p += sprintf(p, cnt_fmt, label, v )
-+
-+static int
-+udc_read_proc(char *page, char **start, off_t off, int cnt, int *eof,
-+ void *data)
-+{
-+ struct sausb_dev *usb = data;
-+ char *p = page;
-+ u32 v;
-+ int len, i;
-+
-+ p += usbctl_proc_info(usb->ctl, p);
-+ p += sprintf(p, "\nUDC:\n");
-+ v = Ser0UDCAR;
-+ p += sprintf(p, "Address\t: %d (0x%02x)\n", v, v);
-+ v = Ser0UDCIMP;
-+ p += sprintf(p, "IN max\t: %d (0x%02x)\n", v + 1, v);
-+ v = Ser0UDCOMP;
-+ p += sprintf(p, "OUT max\t: %d (0x%02x)\n", v + 1, v);
-+ v = Ser0UDCCR;
-+ p += sprintf(p, "UDCCR\t: 0x%02x "
-+ "[ %cSUSIM %cTIM %cRIM %cEIM %cRESIM %cUDA %cUDD ] "
-+ "(0x%02x)\n",
-+ v,
-+ v & UDCCR_SUSIM ? '+' : '-', v & UDCCR_TIM ? '+' : '-',
-+ v & UDCCR_RIM ? '+' : '-', v & UDCCR_EIM ? '+' : '-',
-+ v & UDCCR_RESIM ? '+' : '-', v & UDCCR_UDA ? '+' : '-',
-+ v & UDCCR_UDD ? '+' : '-', usb->udccr);
-+ v = Ser0UDCCS0;
-+ p += sprintf(p, "UDCCS0\t: 0x%02x "
-+ "[ %cSO %cSE %cDE %cFST %cSST %cIPR %cOPR ]\n",
-+ v,
-+ v & UDCCS0_SO ? '+' : '-', v & UDCCS0_SE ? '+' : '-',
-+ v & UDCCS0_DE ? '+' : '-', v & UDCCS0_FST ? '+' : '-',
-+ v & UDCCS0_SST ? '+' : '-', v & UDCCS0_IPR ? '+' : '-',
-+ v & UDCCS0_OPR ? '+' : '-');
-+ v = Ser0UDCCS1;
-+ p += sprintf(p, "UDCCS1\t: 0x%02x "
-+ "[ %cRNE %cFST %cSST %cRPE %cRPC %cRFS ]\n",
-+ v,
-+ v & UDCCS1_RNE ? '+' : '-', v & UDCCS1_FST ? '+' : '-',
-+ v & UDCCS1_SST ? '+' : '-', v & UDCCS1_RPE ? '+' : '-',
-+ v & UDCCS1_RPC ? '+' : '-', v & UDCCS1_RFS ? '+' : '-');
-+ v = Ser0UDCCS2;
-+ p += sprintf(p, "UDCCS2\t: 0x%02x "
-+ "[ %cFST %cSST %cTUR %cTPE %cTPC %cTFS ]\n",
-+ v,
-+ v & UDCCS2_FST ? '+' : '-', v & UDCCS2_SST ? '+' : '-',
-+ v & UDCCS2_TUR ? '+' : '-', v & UDCCS2_TPE ? '+' : '-',
-+ v & UDCCS2_TPC ? '+' : '-', v & UDCCS2_TFS ? '+' : '-');
-+
-+ p += sprintf(p, "\n");
-+ p += sprintf(p, " Bytes Packets FIFO errs Max Sz\n");
-+ p += sprintf(p, "EP0 Rd: %10ld %10ld %10ld -\n",
-+ usb->ep0_rd_bytes,
-+ usb->ep0_rd_packets,
-+ usb->ep0_rd_fifo_errs);
-+ p += sprintf(p, "EP0 Wr: %10ld %10ld %10ld -\n",
-+ usb->ep0_wr_bytes,
-+ usb->ep0_wr_packets,
-+ usb->ep0_wr_fifo_errs);
-+
-+ for (i = 0; i < 2; i++)
-+ p += sprintf(p, "EP%d : %10ld %10ld %10ld %6d\n",
-+ i + 1,
-+ usb->ep[i].bytes,
-+ usb->ep[i].packets,
-+ usb->ep[i].fifo_errs,
-+ usb->ep[i].maxpktsize);
-+
-+ p += sprintf(p, "Stalls sent\t: %ld\n", usb->ep0_stall_sent);
-+ p += sprintf(p, "Early ints\t: %ld\n", usb->ep0_early_irqs);
-+
-+#if 0
-+ v = Ser0UDCSR;
-+ SAY("\nUDC Interrupt Request Register\n");
-+ SAYV(v);
-+ SAYC("Reset pending", (v & UDCSR_RSTIR) ? yes : no);
-+ SAYC("Suspend pending", (v & UDCSR_SUSIR) ? yes : no);
-+ SAYC("Resume pending", (v & UDCSR_RESIR) ? yes : no);
-+ SAYC("ep0 pending", (v & UDCSR_EIR) ? yes : no);
-+ SAYC("receiver pending", (v & UDCSR_RIR) ? yes : no);
-+ SAYC("tramsitter pending", (v & UDCSR_TIR) ? yes : no);
-+
-+#ifdef CONFIG_SA1100_EXTENEX1
-+ SAYC("\nSoft connect",
-+ (PPSR & PPC_USB_SOFT_CON) ? "Visible" : "Hidden");
-+#endif
-+#endif
-+
-+ len = (p - page) - off;
-+ if (len < 0)
-+ len = 0;
-+ *eof = (len <= cnt) ? 1 : 0;
-+ *start = page + off;
-+
-+ return len;
-+}
-+
-+#endif
-+
-+extern struct usbctl usbctl;
-+
-+static int __devinit udc_probe(struct device *dev)
-+{
-+ struct sausb_dev *usb;
-+ int retval;
-+
-+ if (!request_mem_region(0x80000000, 0x10000, "sa11x0-udc"))
-+ return -EBUSY;
-+
-+ usb = kmalloc(sizeof(struct sausb_dev), GFP_KERNEL);
-+ if (!usb)
-+ return -ENOMEM;
-+
-+ memset(usb, 0, sizeof(struct sausb_dev));
-+ dev_set_drvdata(dev, usb);
-+
-+ usb_sa1100_drv.priv = usb;
-+
-+ usb->dev = dev;
-+ usb->ctl = &usbctl;
-+
-+ spin_lock_init(&usb->lock);
-+
-+ udc_disable(usb);
-+
-+ usbctl_init(usb->ctl, &usb_sa1100_drv);
-+
-+#ifdef CONFIG_PROC_FS
-+ create_proc_read_entry("sausb", 0, NULL, udc_read_proc, usb);
-+#endif
-+
-+ /* setup rx dma */
-+ retval = sa1100_request_dma(DMA_Ser0UDCRd, "USB receive",
-+ NULL, NULL, &usb->ep[0].dmach);
-+ if (retval) {
-+ printk("UDC: unable to register for rx dma rc=%d\n",
-+ retval);
-+ goto err;
-+ }
-+
-+ /* setup tx dma */
-+ retval = sa1100_request_dma(DMA_Ser0UDCWr, "USB transmit",
-+ NULL, NULL, &usb->ep[1].dmach);
-+ if (retval) {
-+ printk("UDC: unable to register for tx dma rc=%d\n",
-+ retval);
-+ goto err;
-+ }
-+
-+ /* now allocate the IRQ. */
-+ retval = request_irq(IRQ_Ser0UDC, udc_interrupt, SA_INTERRUPT,
-+ "SA USB core", usb);
-+ if (retval) {
-+ printk("UDC: couldn't request USB irq rc=%d\n", retval);
-+ goto err;
-+ }
-+
-+ return retval;
-+
-+ err:
-+ if (usb->ep[2].dmach) {
-+ sa1100_free_dma(usb->ep[2].dmach);
-+ usb->ep[2].dmach = NULL;
-+ }
-+ if (usb->ep[1].dmach) {
-+ sa1100_free_dma(usb->ep[1].dmach);
-+ usb->ep[1].dmach = NULL;
-+ }
-+#ifdef CONFIG_PROC_FS
-+ remove_proc_entry("sausb", NULL);
-+#endif
-+ release_mem_region(0x80000000, 0x10000);
-+ return retval;
-+}
-+
-+/*
-+ * Release DMA and interrupt resources
-+ */
-+static int __devexit udc_remove(struct device *dev)
-+{
-+ struct sausb_dev *usb = dev_get_drvdata(dev);
-+
-+ dev_set_drvdata(dev, NULL);
-+
-+#ifdef CONFIG_PROC_FS
-+ remove_proc_entry("sausb", NULL);
-+#endif
-+
-+ udc_disable(usb);
-+
-+ free_irq(IRQ_Ser0UDC, usb);
-+ sa1100_free_dma(usb->ep[1].dmach);
-+ sa1100_free_dma(usb->ep[0].dmach);
-+
-+ usbctl_exit(usb->ctl);
-+
-+ release_mem_region(0x80000000, 0x10000);
-+
-+ return 0;
-+}
-+
-+static struct device_driver sa11x0usb_driver = {
-+ .name = "sa11x0-udc",
-+ .bus = &platform_bus_type,
-+ .probe = udc_probe,
-+ .remove = __devexit_p(udc_remove),
-+};
-+
-+static int __init udc_init(void)
-+{
-+ return driver_register(&sa11x0usb_driver);
-+}
-+
-+static void __exit udc_exit(void)
-+{
-+ driver_unregister(&sa11x0usb_driver);
-+}
-+
-+module_init(udc_init);
-+module_exit(udc_exit);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("SA1100 USB Gadget driver");
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/control.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,933 @@
-+/*
-+ * usb/control.c
-+ *
-+ * This parses and handles all the control messages to/from endpoint 0.
-+ */
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/usb_ch9.h>
-+#include <linux/gfp.h>
-+#include <linux/init.h>
-+
-+#include "buffer.h"
-+#include "client.h"
-+#include "usbdev.h"
-+
-+#include "sa1100_usb.h"
-+
-+#define USB_ENDPOINT_HALT 0
-+#define USB_DEVICE_REMOTE_WAKEUP 1
-+
-+#undef DEBUG
-+
-+#ifdef DEBUG
-+#define DPRINTK(fmt, args...) printk(KERN_DEBUG fmt , ## args)
-+#else
-+#define DPRINTK(fmt, args...)
-+#endif
-+
-+/*
-+ * print string descriptor
-+ */
-+static char * __attribute__((unused))
-+psdesc(char *str, int len, struct usb_string_descriptor *desc)
-+{
-+ char *start = str;
-+ int nchars = (desc->bLength - 2) / sizeof(__u16) + 2;
-+ int i;
-+
-+ if (nchars >= len)
-+ nchars = len - 1;
-+
-+ nchars -= 2;
-+
-+ *str++ = '"';
-+ for(i = 0; i < nchars; i++)
-+ *str++ = le16_to_cpu(desc->wData[i]);
-+ *str++ = '"';
-+ *str = '\0';
-+
-+ return start;
-+}
-+
-+enum {
-+ kError = -1,
-+ kEvSuspend = 0,
-+ kEvReset = 1,
-+ kEvResume = 2,
-+ kEvAddress = 3,
-+ kEvConfig = 4,
-+ kEvDeConfig = 5
-+};
-+
-+enum {
-+ kStateZombie = 0,
-+ kStateZombieSuspend = 1,
-+ kStateDefault = 2,
-+ kStateDefaultSuspend = 3,
-+ kStateAddr = 4,
-+ kStateAddrSuspend = 5,
-+ kStateConfig = 6,
-+ kStateConfigSuspend = 7
-+};
-+
-+#define kE kError
-+#define kSZ kStateZombie
-+#define kSZS kStateZombieSuspend
-+#define kSD kStateDefault
-+#define kSDS kStateDefaultSuspend
-+#define kSA kStateAddr
-+#define kSAS kStateAddrSuspend
-+#define kSC kStateConfig
-+#define kSCS kStateConfigSuspend
-+
-+/*
-+ * Fig 9-1 P192
-+ * Zombie == Attached | Powered
-+ */
-+static int device_state_machine[8][6] = {
-+// suspend reset resume addr config deconfig
-+{ kSZS, kSD, kE, kE, kE, kE }, /* zombie */
-+{ kE, kSD, kSZ, kE, kE, kE }, /* zom sus */
-+{ kSDS, kError, kSD, kSA, kE, kE }, /* default */
-+{ kE, kSD, kSD, kE, kE, kE }, /* def sus */
-+{ kSAS, kSD, kE, kE, kSC, kE }, /* addr */
-+{ kE, kSD, kSA, kE, kE, kE }, /* addr sus */
-+{ kSCS, kSD, kE, kE, kE, kSA }, /* config */
-+{ kE, kSD, kSC, kE, kE, kE } /* cfg sus */
-+};
-+
-+/*
-+ * "device state" is the usb device framework state, as opposed to the
-+ * "state machine state" which is whatever the driver needs and is much
-+ * more fine grained
-+ */
-+static int sm_state_to_device_state[8] = {
-+ USB_STATE_POWERED, /* zombie */
-+ USB_STATE_SUSPENDED, /* zombie suspended */
-+ USB_STATE_DEFAULT, /* default */
-+ USB_STATE_SUSPENDED, /* default suspended */
-+ USB_STATE_ADDRESS, /* address */
-+ USB_STATE_SUSPENDED, /* address suspended */
-+ USB_STATE_CONFIGURED, /* config */
-+ USB_STATE_SUSPENDED /* config suspended */
-+};
-+
-+static char * state_names[8] = {
-+ "zombie",
-+ "zombie suspended",
-+ "default",
-+ "default suspended",
-+ "address",
-+ "address suspended",
-+ "configured",
-+ "config suspended"
-+};
-+
-+static char * event_names[6] = {
-+ "suspend",
-+ "reset",
-+ "resume",
-+ "address assigned",
-+ "configure",
-+ "de-configure"
-+};
-+
-+static char * device_state_names[] = {
-+ "not attached",
-+ "attached",
-+ "powered",
-+ "default",
-+ "address",
-+ "configured",
-+ "suspended"
-+};
-+
-+static void usbctl_callbacks(struct usbctl *ctl, int state, int oldstate)
-+{
-+ struct usb_client *clnt = ctl->clnt;
-+
-+ /*
-+ * Inform any clients currently attached
-+ * that the connectivity state changed.
-+ */
-+ if (clnt && clnt->state_change)
-+ clnt->state_change(clnt->priv, state, oldstate);
-+}
-+
-+/*
-+ * called by the interrupt handler here and the two endpoint
-+ * files when interesting .."events" happen
-+ */
-+static int usbctl_next_state_on_event(struct usbctl *ctl, int event)
-+{
-+ int next_state, next_dev_state, old_dev_state;
-+
-+ printk(KERN_DEBUG "usbctl: %s --[%s]--> ", state_names[ctl->sm_state],
-+ event_names[event]);
-+
-+ next_state = device_state_machine[ctl->sm_state][event];
-+ if (next_state != kError) {
-+ next_dev_state = sm_state_to_device_state[next_state];
-+
-+ printk("%s. Device in %s state.\n",
-+ state_names[next_state],
-+ device_state_names[next_dev_state]);
-+
-+ old_dev_state = ctl->state;
-+ ctl->sm_state = next_state;
-+ ctl->state = next_dev_state;
-+
-+ if (old_dev_state != next_dev_state)
-+ usbctl_callbacks(ctl, next_dev_state, old_dev_state);
-+ } else
-+ printk("(error)\n");
-+
-+ return next_state;
-+}
-+
-+/*
-+ * Driver detected USB HUB reset.
-+ */
-+int usbctl_reset(struct usbctl *ctl)
-+{
-+ int ret;
-+
-+ ret = usbctl_next_state_on_event(ctl, kEvReset) == kError;
-+
-+ if (!ret) {
-+ ctl->address = 0;
-+ }
-+ return ret;
-+}
-+
-+EXPORT_SYMBOL(usbctl_reset);
-+
-+void usbctl_suspend(struct usbctl *ctl)
-+{
-+ usbctl_next_state_on_event(ctl, kEvSuspend);
-+}
-+
-+EXPORT_SYMBOL(usbctl_suspend);
-+
-+void usbctl_resume(struct usbctl *ctl)
-+{
-+ usbctl_next_state_on_event(ctl, kEvResume);
-+}
-+
-+EXPORT_SYMBOL(usbctl_resume);
-+
-+static struct usb_interface_descriptor *
-+usbctl_get_interface_descriptor(struct usbctl *ctl, unsigned int interface)
-+{
-+ /*FIXME*/
-+ struct cdb *cdb = sa1100_usb_get_descriptor_ptr();
-+
-+ return (struct usb_interface_descriptor *)&cdb->intf;
-+}
-+
-+static inline int
-+__usbctl_queue(struct usbctl *ctl, struct usb_ctrlrequest *req,
-+ struct usb_buf *buf)
-+{
-+ unsigned int reqlen = le16_to_cpu(req->wLength);
-+
-+ return ctl->driver->ep0_queue(ctl->driver->priv, buf, reqlen) ?
-+ RET_ERROR : RET_QUEUED;
-+}
-+
-+static int
-+usbctl_queue(struct usbctl *ctl, struct usb_ctrlrequest *req,
-+ void *data, unsigned int len)
-+{
-+ struct usb_buf *buf;
-+
-+ buf = usbb_alloc(len, GFP_ATOMIC);
-+ if (!buf) {
-+ printk(KERN_ERR "usb: out of memory\n");
-+ return RET_ERROR;
-+ }
-+
-+ if (data)
-+ memcpy(usbb_push(buf, len), data, len);
-+
-+ return __usbctl_queue(ctl, req, buf);
-+}
-+
-+/*
-+ * 9.4.5: Get Status (device)
-+ */
-+static int
-+usbctl_parse_dev_get_status(struct usbctl *ctl, struct usb_ctrlrequest *req)
-+{
-+ u16 status;
-+
-+ status = /* self_powered_hook() ? 1 : 0 */1;
-+
-+ status = cpu_to_le16(status);
-+
-+ return usbctl_queue(ctl, req, &status, 2);
-+}
-+
-+/*
-+ * Send USB device description to the host.
-+ */
-+static int
-+usbctl_desc_device(struct usbctl *ctl, struct usb_ctrlrequest *req)
-+{
-+ return __usbctl_queue(ctl, req, usbb_get(ctl->dev_desc_buf));
-+}
-+
-+/*
-+ * Send USB configuration information to the host.
-+ */
-+static int
-+usbctl_desc_config(struct usbctl *ctl, struct usb_ctrlrequest *req)
-+{
-+ /*FIXME*/
-+ struct cdb *cdb = sa1100_usb_get_descriptor_ptr();
-+
-+ return usbctl_queue(ctl, req, cdb, sizeof(struct cdb));
-+}
-+
-+/*
-+ * Send a string to the host from the string table.
-+ */
-+static int
-+usbctl_desc_string(struct usbctl *ctl, struct usb_ctrlrequest *req,
-+ unsigned int idx)
-+{
-+ struct usb_buf *buf;
-+ unsigned int lang = le16_to_cpu(req->wIndex);
-+ char string[32] __attribute__((unused));
-+ int ret;
-+
-+ DPRINTK("usbctl: desc_string (index %u, lang 0x%04x): ", idx, lang);
-+
-+ buf = usbc_string_find(&ctl->strings, lang, idx);
-+ if (buf) {
-+ DPRINTK("%s\n", idx == 0 ? "language" :
-+ psdesc(string, sizeof(string), usbc_string_desc(buf)));
-+
-+ ret = __usbctl_queue(ctl, req, buf);
-+ } else {
-+ DPRINTK("not found -> stall\n");
-+ ret = RET_REQERROR;
-+ }
-+ return ret;
-+}
-+
-+/*
-+ * Send an interface description (and endpoints) to the host.
-+ */
-+static int
-+usbctl_desc_interface(struct usbctl *ctl, struct usb_ctrlrequest *req,
-+ unsigned int idx)
-+{
-+ struct usb_interface_descriptor *desc;
-+ int ret;
-+
-+ DPRINTK("usbctl: desc_interface (index %d)\n", idx);
-+
-+ desc = usbctl_get_interface_descriptor(ctl, idx);
-+
-+ if (desc) {
-+ ret = usbctl_queue(ctl, req, desc, desc->bLength);
-+ } else {
-+ printk("usbctl: unknown interface %d\n", idx);
-+ ret = RET_REQERROR;
-+ }
-+
-+ return ret;
-+}
-+
-+/*
-+ * Send an endpoint (1 .. n) to the host.
-+ */
-+static int
-+usbctl_desc_endpoint(struct usbctl *ctl, struct usb_ctrlrequest *req,
-+ unsigned int idx)
-+{
-+ int ret;
-+
-+ DPRINTK("usbctl: desc_endpoint (index %d)\n", idx);
-+
-+ if (idx >= 1 && idx <= ctl->nr_ep) {
-+ struct usb_endpoint_descriptor *ep = ctl->ep_desc[idx - 1];
-+
-+ ret = usbctl_queue(ctl, req, ep, ep->bLength);
-+ } else {
-+ printk("usbctl: unknown endpoint %d\n", idx);
-+ ret = RET_REQERROR;
-+ }
-+
-+ return ret;
-+}
-+
-+/*
-+ * 9.4.3: Parse a request for a descriptor.
-+ * Unspecified conditions:
-+ * None
-+ * Valid states: default, address, configured.
-+ */
-+static int
-+usbctl_parse_dev_descriptor(struct usbctl *ctl, struct usb_ctrlrequest *req)
-+{
-+ unsigned int idx = le16_to_cpu(req->wValue) & 255;
-+ unsigned int type = le16_to_cpu(req->wValue) >> 8;
-+ int ret;
-+
-+ switch (type) {
-+ case USB_DT_DEVICE: /* check if idx matters */
-+ ret = usbctl_desc_device(ctl, req);
-+ break;
-+
-+ case USB_DT_CONFIG: /* check if idx matters */
-+ ret = usbctl_desc_config(ctl, req);
-+ break;
-+
-+ case USB_DT_STRING:
-+ ret = usbctl_desc_string(ctl, req, idx);
-+ break;
-+
-+ case USB_DT_INTERFACE:
-+ ret = usbctl_desc_interface(ctl, req, idx);
-+ break;
-+
-+ case USB_DT_ENDPOINT:
-+ ret = usbctl_desc_endpoint(ctl, req, idx);
-+ break;
-+
-+ case USB_DT_DEVICE_QUALIFIER:
-+ case USB_DT_OTHER_SPEED_CONFIG:
-+ case USB_DT_INTERFACE_POWER:
-+ default:
-+ printk(KERN_ERR "usbctl: unknown descriptor: "
-+ "wValue = 0x%04x wIndex = 0x%04x\n",
-+ le16_to_cpu(req->wValue), le16_to_cpu(req->wIndex));
-+ ret = RET_REQERROR;
-+ break;
-+ }
-+
-+ return ret;
-+}
-+
-+/*
-+ * 9.4.6: Set Address
-+ * The USB1.1 spec says the response to SetAddress() with value 0
-+ * is undefined. It then goes on to define the response. We
-+ * acknowledge addresses of zero, but take no further action.
-+ */
-+static int
-+usbctl_parse_dev_set_address(struct usbctl *ctl, struct usb_ctrlrequest *req)
-+{
-+ unsigned int address = le16_to_cpu(req->wValue) & 0x7f;
-+
-+ if (ctl->state == USB_STATE_CONFIGURED)
-+ return RET_REQERROR;
-+
-+ if (address != 0) {
-+ ctl->address = address;
-+
-+ usbctl_next_state_on_event(ctl, kEvAddress);
-+
-+ ctl->driver->set_address(ctl->driver->priv, address);
-+ }
-+
-+ return RET_ACK;
-+}
-+
-+/*
-+ * 9.4.2: Get Configuration.
-+ * Unspecified conditions:
-+ * - non-zero wIndex, wValue or wLength (ignored)
-+ * - default state (request error)
-+ * Valid states: address, configured.
-+ */
-+static int
-+usbctl_parse_dev_get_config(struct usbctl *ctl, struct usb_ctrlrequest *req)
-+{
-+ u8 status = 0;
-+
-+ if (ctl->state == USB_STATE_CONFIGURED)
-+ status = 1;
-+
-+ return usbctl_queue(ctl, req, &status, 1);
-+}
-+
-+/*
-+ * 9.4.7: Set Configuration.
-+ * Unspecified conditions:
-+ * - default state (request error)
-+ */
-+static int
-+usbctl_parse_dev_set_config(struct usbctl *ctl, struct usb_ctrlrequest *req)
-+{
-+ unsigned int cfg = le16_to_cpu(req->wValue);
-+ int ret = RET_REQERROR;
-+
-+ if (ctl->state == USB_STATE_DEFAULT)
-+ return ret;
-+
-+ if (cfg == 0) {
-+ /* enter address state, or remain in address state */
-+ usbctl_next_state_on_event(ctl, kEvDeConfig);
-+
-+ ctl->driver->set_config(ctl->driver->priv, NULL);
-+
-+ ret = RET_ACK;
-+ } else if (cfg == 1) {
-+ /* enter configured state, and set configuration */
-+ /*FIXME*/
-+ struct cdb *cdb = sa1100_usb_get_descriptor_ptr();
-+
-+ usbctl_next_state_on_event(ctl, kEvConfig);
-+
-+ ctl->driver->set_config(ctl->driver->priv, cdb);
-+ ret = RET_ACK;
-+ }
-+
-+ return ret;
-+}
-+
-+/*
-+ * Interface handling
-+ */
-+
-+/*
-+ * 9.4.5: Get Status (interface)
-+ */
-+static int
-+usbctl_parse_int_get_status(struct usbctl *ctl, struct usb_ctrlrequest *req)
-+{
-+ unsigned int interface = le16_to_cpu(req->wIndex) & 255;
-+ u16 status;
-+
-+ switch (ctl->state) {
-+ case USB_STATE_DEFAULT:
-+ return RET_REQERROR;
-+
-+ case USB_STATE_ADDRESS:
-+ if (interface != 0)
-+ return RET_REQERROR;
-+ break;
-+
-+ case USB_STATE_CONFIGURED:
-+ if (interface != 1)
-+ return RET_REQERROR;
-+ break;
-+ }
-+
-+ status = cpu_to_le16(0);
-+
-+ return usbctl_queue(ctl, req, &status, 2);
-+}
-+
-+/*
-+ * 9.4.4: Get Interface
-+ * Unspecified conditions:
-+ * -
-+ * States: Default (unspecified), Address (Request Error), Configured (ok)
-+ */
-+static int
-+usbctl_parse_int_get_interface(struct usbctl *ctl, struct usb_ctrlrequest *req)
-+{
-+ unsigned int interface = le16_to_cpu(req->wIndex) & 255;
-+ u8 null = 0;
-+
-+ if (ctl->state != USB_STATE_CONFIGURED)
-+ return RET_REQERROR;
-+
-+ /*
-+ * If the interface doesn't exist, respond with request error
-+ */
-+ if (interface != 1)
-+ return RET_REQERROR;
-+
-+ printk("usbctl: get interface %d not supported\n", interface);
-+
-+ return usbctl_queue(ctl, req, &null, 1);
-+}
-+
-+static int
-+usbctl_parse_int_set_interface(struct usbctl *ctl, struct usb_ctrlrequest *req)
-+{
-+ unsigned int interface = le16_to_cpu(req->wIndex) & 255;
-+
-+ if (interface != 0)
-+ printk("usbctl: set interface %d not supported (ignored)\n",
-+ interface);
-+
-+ return RET_ACK;
-+}
-+
-+/*
-+ * Endpoint handling
-+ */
-+
-+/*
-+ * 9.4.5: Get Status (endpoint)
-+ */
-+static int
-+usbctl_parse_ep_get_status(struct usbctl *ctl, struct usb_ctrlrequest *req)
-+{
-+ unsigned int ep = le16_to_cpu(req->wIndex) & 15;
-+ u16 status;
-+
-+ if ((ep != 0 && ctl->state != USB_STATE_CONFIGURED) ||
-+ ep <= ctl->nr_ep)
-+ return RET_REQERROR;
-+
-+ status = ctl->driver->ep_get_status(ctl->driver->priv, ep);
-+ status = cpu_to_le16(status);
-+
-+ return usbctl_queue(ctl, req, &status, 2);
-+}
-+
-+/*
-+ * 9.4.1: Clear an endpoint feature. We only support ENDPOINT_HALT.
-+ * Unspecified conditions:
-+ * - non-zero wLength is not specified (ignored)
-+ * Valid states: Address, Configured.
-+ */
-+static int
-+usbctl_parse_ep_clear_feature(struct usbctl *ctl, struct usb_ctrlrequest *req)
-+{
-+ unsigned int feature = le16_to_cpu(req->wValue);
-+ unsigned int ep = le16_to_cpu(req->wIndex) & 15;
-+ int ret;
-+
-+ if ((ep != 0 && ctl->state != USB_STATE_CONFIGURED) ||
-+ ep <= ctl->nr_ep)
-+ return RET_REQERROR;
-+
-+ if (feature == USB_ENDPOINT_HALT) {
-+ ctl->driver->ep_halt(ctl->driver->priv, ep, 0);
-+ ret = RET_ACK;
-+ } else {
-+ printk(KERN_ERR "usbctl: unsupported clear feature: "
-+ "wValue = 0x%04x wIndex = 0x%04x\n",
-+ feature, ep);
-+
-+ ret = RET_REQERROR;
-+ }
-+ return ret;
-+}
-+
-+/*
-+ * 9.4.9: Set Feature (endpoint)
-+ */
-+static int
-+usbctl_parse_ep_set_feature(struct usbctl *ctl, struct usb_ctrlrequest *req)
-+{
-+ unsigned int feature = le16_to_cpu(req->wValue);
-+ unsigned int ep = le16_to_cpu(req->wIndex) & 15;
-+ int ret;
-+
-+ if ((ep != 0 && ctl->state != USB_STATE_CONFIGURED) ||
-+ ep <= ctl->nr_ep)
-+ return RET_REQERROR;
-+
-+ if (feature == USB_ENDPOINT_HALT) {
-+ ctl->driver->ep_halt(ctl->driver->priv, ep, 1);
-+ ret = RET_ACK;
-+ } else {
-+ printk(KERN_ERR "usbctl: unsupported set feature "
-+ "wValue = 0x%04x wIndex = 0x%04x\n",
-+ feature, ep);
-+
-+ ret = RET_REQERROR;
-+ }
-+ return ret;
-+}
-+
-+/*
-+ * This reflects Table 9.3 (p186) in the USB1.1 spec.
-+ *
-+ * Some notes:
-+ * - USB1.1 specifies remote wakeup feature, so we don't implement
-+ * USB_RECIP_DEVICE USB_REQ_{SET,CLEAR}_FEATURE
-+ * - USB1.1 doesn't actually specify any interface features, so we
-+ * don't implement USB_RECIP_INTERFACE USB_REQ_{SET,CLEAR}_FEATURE
-+ */
-+static int (*request_fns[4][16])(struct usbctl *, struct usb_ctrlrequest *) = {
-+ [USB_RECIP_DEVICE] = {
-+ [USB_REQ_GET_STATUS] = usbctl_parse_dev_get_status,
-+ [USB_REQ_CLEAR_FEATURE] = NULL,
-+ [USB_REQ_SET_FEATURE] = NULL,
-+ [USB_REQ_SET_ADDRESS] = usbctl_parse_dev_set_address,
-+ [USB_REQ_GET_DESCRIPTOR] = usbctl_parse_dev_descriptor,
-+ [USB_REQ_SET_DESCRIPTOR] = NULL,
-+ [USB_REQ_GET_CONFIGURATION] = usbctl_parse_dev_get_config,
-+ [USB_REQ_SET_CONFIGURATION] = usbctl_parse_dev_set_config,
-+ },
-+
-+ [USB_RECIP_INTERFACE] = {
-+ [USB_REQ_GET_STATUS] = usbctl_parse_int_get_status,
-+ [USB_REQ_CLEAR_FEATURE] = NULL,
-+ [USB_REQ_SET_FEATURE] = NULL,
-+ [USB_REQ_GET_INTERFACE] = usbctl_parse_int_get_interface,
-+ [USB_REQ_SET_INTERFACE] = usbctl_parse_int_set_interface,
-+ },
-+
-+ [USB_RECIP_ENDPOINT] = {
-+ [USB_REQ_GET_STATUS] = usbctl_parse_ep_get_status,
-+ [USB_REQ_CLEAR_FEATURE] = usbctl_parse_ep_clear_feature,
-+ [USB_REQ_SET_FEATURE] = usbctl_parse_ep_set_feature,
-+ },
-+};
-+
-+static void __attribute__((unused))
-+usbctl_dump_request(const char *prefix, const struct usb_ctrlrequest *req)
-+{
-+ printk("%sbRequestType=0x%02x bRequest=0x%02x "
-+ "wValue=0x%04x wIndex=0x%04x wLength=0x%04x\n",
-+ prefix, req->bRequestType, req->bRequest,
-+ le16_to_cpu(req->wValue), le16_to_cpu(req->wIndex),
-+ le16_to_cpu(req->wLength));
-+}
-+
-+int usbctl_parse_request(struct usbctl *ctl, struct usb_ctrlrequest *req)
-+{
-+ unsigned int type;
-+ int (*fn)(struct usbctl *, struct usb_ctrlrequest *) = NULL;
-+ int ret = RET_REQERROR;
-+
-+ //usbctl_dump_request("usbctl: ", req);
-+
-+ type = req->bRequestType & USB_TYPE_MASK;
-+ if (type == USB_TYPE_STANDARD) {
-+ unsigned int recip;
-+
-+ recip = req->bRequestType & USB_RECIP_MASK;
-+ if (recip < ARRAY_SIZE(request_fns) &&
-+ req->bRequest < ARRAY_SIZE(request_fns[0]))
-+ fn = request_fns[recip][req->bRequest];
-+ }
-+
-+ if (fn)
-+ ret = fn(ctl, req);
-+ else
-+ usbctl_dump_request(KERN_ERR "usbctl: unknown request: ",
-+ req);
-+
-+ /*
-+ * Make sure we're doing the right thing.
-+ */
-+ if (req->bRequestType & USB_DIR_IN) {
-+ if (ret != RET_QUEUED && ret != RET_REQERROR)
-+ printk("Error: device to host transfer expected\n");
-+ } else {
-+ if (ret == RET_QUEUED)
-+ printk("Error: no device to host transfer expected\n");
-+ }
-+
-+ return ret;
-+}
-+
-+EXPORT_SYMBOL(usbctl_parse_request);
-+
-+/* Start running. Must have called usb_open (above) first */
-+int usbctl_start(struct usb_client *client)
-+{
-+ struct usbctl *ctl = client->ctl;
-+
-+ if (ctl == NULL || ctl->clnt != client) {
-+ printk("usbctl: start: no client registered\n");
-+ return -EPERM;
-+ }
-+
-+ ctl->sm_state = kStateZombie;
-+ ctl->state = USB_STATE_POWERED;
-+
-+ /*
-+ * Notify the client as to our state.
-+ */
-+ usbctl_callbacks(ctl, USB_STATE_POWERED, USB_STATE_SUSPENDED);
-+
-+ return ctl->driver->start(ctl->driver->priv);
-+}
-+
-+EXPORT_SYMBOL(usbctl_start);
-+
-+/*
-+ * Stop USB core from running
-+ */
-+void usbctl_stop(struct usb_client *client)
-+{
-+ struct usbctl *ctl = client->ctl;
-+
-+ if (ctl == NULL || ctl->clnt != client) {
-+ printk("USBDEV: stop: no client/driver registered\n");
-+ return;
-+ }
-+
-+ ctl->driver->stop(ctl->driver->priv);
-+}
-+
-+EXPORT_SYMBOL(usbctl_stop);
-+
-+struct usbctl usbctl;
-+
-+EXPORT_SYMBOL(usbctl);
-+
-+/* Open SA usb core on behalf of a client, but don't start running */
-+
-+int usbctl_open(struct usb_client *client)
-+{
-+ struct usbctl *ctl = &usbctl;
-+ int ret;
-+printk("usbctl_open: ctl %p driver %p\n", ctl, ctl->driver);
-+ if (!ctl->driver || !try_module_get(ctl->driver->owner))
-+ return -ENODEV;
-+
-+ if (ctl->clnt != NULL) {
-+ ret = -EBUSY;
-+ goto err;
-+ }
-+
-+ ctl->clnt = client;
-+ ctl->state = USB_STATE_SUSPENDED;
-+ ctl->nr_ep = 2;
-+ /* start in zombie suspended state */
-+ ctl->sm_state = kStateZombieSuspend;
-+ ctl->state = USB_STATE_SUSPENDED;
-+ client->ctl = ctl;
-+
-+ ctl->dev_desc_buf = usbb_alloc(sizeof(struct usb_device_descriptor),
-+ GFP_KERNEL);
-+ if (!ctl->dev_desc_buf) {
-+ ret = -ENOMEM;
-+ goto err;
-+ }
-+
-+ ctl->dev_desc = usbb_push(ctl->dev_desc_buf,
-+ sizeof(struct usb_device_descriptor));
-+
-+ /* create descriptors for enumeration */
-+ initialize_descriptors(ctl);
-+
-+ return 0;
-+
-+ err:
-+ module_put(ctl->driver->owner);
-+ return ret;
-+}
-+
-+EXPORT_SYMBOL(usbctl_open);
-+
-+/* Tell SA core client is through using it */
-+void usbctl_close(struct usb_client *client)
-+{
-+ struct usbctl *ctl = client->ctl;
-+
-+ if (ctl == NULL || ctl->clnt != client) {
-+ printk("usbctl: close: no client registered\n");
-+ return;
-+ }
-+
-+ usbb_put(ctl->dev_desc_buf);
-+
-+ client->ctl = NULL;
-+ ctl->clnt = NULL;
-+ ctl->dev_desc = NULL;
-+ ctl->dev_desc_buf = NULL;
-+ /* reset to zombie suspended state */
-+ ctl->sm_state = kStateZombieSuspend;
-+ ctl->state = USB_STATE_SUSPENDED;
-+
-+ usbc_string_free_all(&ctl->strings);
-+
-+ if (ctl->driver->owner)
-+ module_put(ctl->driver->owner);
-+}
-+
-+EXPORT_SYMBOL(usbctl_close);
-+
-+int usbctl_proc_info(struct usbctl *ctl, char *buf)
-+{
-+ char *p = buf;
-+
-+ p += sprintf(p, "USB Gadget Core:\n");
-+ p += sprintf(p, "Driver\t: %s\n",
-+ ctl->driver ? ctl->driver->name : "none");
-+ p += sprintf(p, "Client\t: %s\n",
-+ ctl->clnt ? ctl->clnt->name : "none");
-+ p += sprintf(p, "State\t: %s (%s) %d\n",
-+ device_state_names[sm_state_to_device_state[ctl->sm_state]],
-+ state_names[ctl->sm_state],
-+ ctl->sm_state);
-+ p += sprintf(p, "Address\t: %d\n", ctl->address);
-+
-+ return p - buf;
-+}
-+
-+EXPORT_SYMBOL(usbctl_proc_info);
-+
-+int
-+usbctl_ep_queue_buffer(struct usbctl *ctl, unsigned int ep,
-+ char *buf, unsigned int len)
-+{
-+ return ctl->driver->ep_queue(ctl->driver->priv, ep, buf, len);
-+}
-+
-+EXPORT_SYMBOL(usbctl_ep_queue_buffer);
-+
-+void usbctl_ep_reset(struct usbctl *ctl, unsigned int ep)
-+{
-+ return ctl->driver->ep_reset(ctl->driver->priv, ep);
-+}
-+
-+EXPORT_SYMBOL(usbctl_ep_reset);
-+
-+void
-+usbctl_ep_set_callback(struct usbctl *ctl, unsigned int ep,
-+ usb_callback_t callback, void *data)
-+{
-+ ctl->driver->ep_callback(ctl->driver->priv, ep, callback, data);
-+}
-+
-+EXPORT_SYMBOL(usbctl_ep_set_callback);
-+
-+int usbctl_ep_idle(struct usbctl *ctl, unsigned int ep)
-+{
-+ return ctl->driver->ep_idle(ctl->driver->priv, ep);
-+}
-+
-+EXPORT_SYMBOL(usbctl_ep_idle);
-+
-+/*
-+ * usbctl_init()
-+ * Module load time. Allocate dma and interrupt resources. Setup /proc fs
-+ * entry. Leave UDC disabled.
-+ */
-+int usbctl_init(struct usbctl *ctl, struct usbc_driver *drv)
-+{
-+ usbc_string_init(&ctl->strings);
-+printk("usbctl_init: %p %p\n", ctl, drv);
-+ /*
-+ * start in zombie suspended state
-+ */
-+ ctl->sm_state = kStateZombieSuspend;
-+ ctl->state = USB_STATE_SUSPENDED;
-+ ctl->driver = drv;
-+
-+ return 0;
-+}
-+
-+/*
-+ * usbctl_exit()
-+ */
-+void usbctl_exit(struct usbctl *ctl)
-+{
-+ usbc_string_free_all(&ctl->strings);
-+
-+ ctl->driver = NULL;
-+}
-+
-+EXPORT_SYMBOL(usbctl_init);
-+EXPORT_SYMBOL(usbctl_exit);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("USB gadget core");
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/client.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,40 @@
-+#ifndef USBDEV_CLIENT_H
-+#define USBDEV_CLIENT_H
-+
-+#include "sa1100_usb.h" /* grr */
-+
-+struct usbctl;
-+
-+struct usb_client {
-+ struct usbctl *ctl;
-+ const char *name; /* Client name */
-+ void *priv; /* Client-private data */
-+ void (*state_change)(void *priv, int state, int oldstate);
-+ __u16 vendor; /* USB vendor ID */
-+ __u16 product; /* USB product ID */
-+ __u16 version; /* USB version ID */
-+ __u8 class; /* USB class */
-+ __u8 subclass; /* USB subclass */
-+ __u8 protocol; /* USB protocol */
-+ __u8 unused1;
-+ __u16 unused2;
-+ const char *manufacturer_str;
-+ const char *product_str;
-+ const char *serial_str;
-+};
-+
-+int usbctl_start(struct usb_client *client);
-+void usbctl_stop(struct usb_client *client);
-+int usbctl_open(struct usb_client *client);
-+void usbctl_close(struct usb_client *client);
-+
-+int
-+usbctl_ep_queue_buffer(struct usbctl *ctl, unsigned int ep,
-+ char *buf, unsigned int len);
-+void usbctl_ep_reset(struct usbctl *ctl, unsigned int ep);
-+void
-+usbctl_ep_set_callback(struct usbctl *ctl, unsigned int ep,
-+ usb_callback_t callback, void *data);
-+int usbctl_ep_idle(struct usbctl *ctl, unsigned int ep);
-+
-+#endif
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/sa1100_usb.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,50 @@
-+/*
-+ * sa1100_usb.h
-+ *
-+ * Public interface to the sa1100 USB core. For use by client modules
-+ * like usb-eth and usb-char.
-+ *
-+ */
-+#ifndef _SA1100_USB_H
-+#define _SA1100_USB_H
-+
-+typedef void (*usb_callback_t)(void *data, int flag, int size);
-+
-+/* in usb_send.c */
-+int sa1100_usb_xmitter_avail( void );
-+int sa1100_usb_send(char *buf, int len);
-+void sa1100_usb_send_set_callback(usb_callback_t callback, void *data);
-+void sa1100_usb_send_reset(void);
-+
-+/* in usb_recev.c */
-+int sa1100_usb_recv(char *buf, int len);
-+void sa1100_usb_recv_set_callback(usb_callback_t callback, void *data);
-+void sa1100_usb_recv_reset(void);
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Descriptor Management
-+//////////////////////////////////////////////////////////////////////////////
-+
-+// MaxPower:
-+#define USB_POWER(x) ((x)>>1) /* convert mA to descriptor units of A for MaxPower */
-+
-+/* "config descriptor buffer" - that is, one config,
-+ ..one interface and 2 endpoints */
-+struct cdb {
-+ struct usb_config_descriptor cfg;
-+ struct usb_interface_descriptor intf;
-+ struct usb_endpoint_descriptor ep1, ep2;
-+} __attribute__ ((packed));
-+
-+
-+/*=======================================================
-+ * Descriptor API
-+ */
-+
-+/* Get the address of the statically allocated desc_t structure
-+ in the usb core driver. Clients can modify this between
-+ the time they call sa1100_usb_open() and sa1100_usb_start()
-+*/
-+struct cdb *sa1100_usb_get_descriptor_ptr(void);
-+
-+#endif /* _SA1100_USB_H */
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/sa1100usb.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,136 @@
-+/*
-+ * Copyright (C) Compaq Computer Corporation, 1998, 1999
-+ * Copyright (C) Extenex Corporation 2001
-+ *
-+ * usb_ctl.h
-+ *
-+ * PRIVATE interface used to share info among components of the SA-1100 USB
-+ * core: usb_ctl, usb_ep0, usb_recv and usb_send. Clients of the USB core
-+ * should use sa1100_usb.h.
-+ *
-+ */
-+#ifndef SA1100USB_H
-+#define SA1100USB_H
-+
-+struct usbctl;
-+
-+struct sausb_dev {
-+ struct device *dev;
-+ struct usbctl *ctl;
-+ spinlock_t lock;
-+
-+ u32 udccr;
-+
-+ /*
-+ * EP0 write thread.
-+ */
-+ void (*wrint)(struct sausb_dev *);
-+ struct usb_buf *wrbuf;
-+ unsigned char *wrptr;
-+ unsigned int wrlen;
-+
-+ /*
-+ * EP0 statistics.
-+ */
-+ unsigned long ep0_wr_fifo_errs;
-+ unsigned long ep0_wr_bytes;
-+ unsigned long ep0_wr_packets;
-+ unsigned long ep0_rd_fifo_errs;
-+ unsigned long ep0_rd_bytes;
-+ unsigned long ep0_rd_packets;
-+ unsigned long ep0_stall_sent;
-+ unsigned long ep0_early_irqs;
-+
-+ /*
-+ * EP1 .. n
-+ */
-+ struct {
-+ dma_regs_t *dmach;
-+
-+ dma_addr_t bufdma;
-+ unsigned int buflen;
-+ void *pktcpu;
-+ dma_addr_t pktdma;
-+ unsigned int pktlen;
-+ unsigned int pktrem;
-+
-+ void *cb_data;
-+ void (*cb_func)(void *data, int flag, int size);
-+
-+ u32 udccs;
-+ unsigned int maxpktsize;
-+ unsigned int configured;
-+ unsigned int host_halt;
-+ unsigned long fifo_errs;
-+ unsigned long bytes;
-+ unsigned long packets;
-+ } ep[2];
-+};
-+
-+/* receiver */
-+int ep1_recv(void);
-+void udc_ep1_init(struct sausb_dev *);
-+void udc_ep1_halt(struct sausb_dev *, int);
-+void udc_ep1_reset(struct sausb_dev *);
-+void udc_ep1_config(struct sausb_dev *, unsigned int);
-+void udc_ep1_int_hndlr(struct sausb_dev *);
-+
-+/* xmitter */
-+void udc_ep2_init(struct sausb_dev *);
-+void udc_ep2_halt(struct sausb_dev *, int);
-+void udc_ep2_reset(struct sausb_dev *);
-+void udc_ep2_config(struct sausb_dev *, unsigned int);
-+void udc_ep2_int_hndlr(struct sausb_dev *);
-+
-+#define UDC_write(reg, val) do { \
-+ int i = 10000; \
-+ do { \
-+ (reg) = (val); \
-+ if (i-- <= 0) { \
-+ printk( "%s [%d]: write %#x to %p (%#x) failed\n", \
-+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
-+ break; \
-+ } \
-+ } while((reg) != (val)); \
-+} while (0)
-+
-+#define UDC_set(reg, val) do { \
-+ int i = 10000; \
-+ do { \
-+ (reg) |= (val); \
-+ if (i-- <= 0) { \
-+ printk( "%s [%d]: set %#x of %p (%#x) failed\n", \
-+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
-+ break; \
-+ } \
-+ } while(!((reg) & (val))); \
-+} while (0)
-+
-+#define UDC_clear(reg, val) do { \
-+ int i = 10000; \
-+ do { \
-+ (reg) &= ~(val); \
-+ if (i-- <= 0) { \
-+ printk( "%s [%d]: clear %#x of %p (%#x) failed\n", \
-+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
-+ break; \
-+ } \
-+ } while((reg) & (val)); \
-+} while (0)
-+
-+#define UDC_flip(reg, val) do { \
-+ int i = 10000; \
-+ (reg) = (val); \
-+ do { \
-+ (reg) = (val); \
-+ if (i-- <= 0) { \
-+ printk( "%s [%d]: flip %#x of %p (%#x) failed\n", \
-+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
-+ break; \
-+ } \
-+ } while(((reg) & (val))); \
-+} while (0)
-+
-+#define CHECK_ADDRESS { if ( Ser0UDCAR == 1 ) { printk("%s:%d I lost my address!!!\n",__FUNCTION__, __LINE__);}}
-+
-+#endif
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/strings.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,117 @@
-+/*
-+ * usb/strings.c
-+ *
-+ * Copyright (C) 2002 Russell King.
-+ */
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/errno.h>
-+#include <linux/spinlock.h>
-+#include <linux/string.h>
-+#include <linux/usb_ch9.h>
-+
-+#include "buffer.h"
-+#include "strings.h"
-+
-+struct usb_buf *usbc_string_alloc(int len)
-+{
-+ struct usb_buf *buf;
-+ int tot_len;
-+
-+ tot_len = sizeof(struct usb_descriptor_header) + sizeof(u16) * len;
-+
-+ buf = usbb_alloc(tot_len, GFP_KERNEL);
-+
-+ if (buf) {
-+ struct usb_string_descriptor *desc = usbb_push(buf, tot_len);
-+
-+ desc->bLength = tot_len;
-+ desc->bDescriptorType = USB_DT_STRING;
-+ }
-+ return buf;
-+}
-+
-+void usbc_string_free(struct usb_buf *buf)
-+{
-+ if (buf)
-+ usbb_put(buf);
-+}
-+
-+void usbc_string_from_cstr(struct usb_buf *buf, const char *str)
-+{
-+ struct usb_string_descriptor *desc = usbc_string_desc(buf);
-+ int i, len;
-+
-+ len = strlen(str);
-+ BUG_ON((sizeof(__u16) * len) > desc->bLength - sizeof(struct usb_descriptor_header));
-+
-+ for (i = 0; i < len; i++)
-+ desc->wData[i] = cpu_to_le16(str[i]);
-+}
-+
-+int usbc_string_add(struct usbc_strs *table, struct usb_buf *buf)
-+{
-+ int nr, i;
-+
-+ nr = -ENOSPC;
-+ spin_lock_irq(&table->lock);
-+ for (i = 0; i < NR_STRINGS; i++)
-+ if (table->buf[i] == NULL) {
-+ table->buf[i] = buf;
-+ nr = i;
-+ break;
-+ }
-+ spin_unlock_irq(&table->lock);
-+
-+ return nr;
-+}
-+
-+void usbc_string_del(struct usbc_strs *table, int nr)
-+{
-+ if (nr < NR_STRINGS) {
-+ spin_lock_irq(&table->lock);
-+ table->buf[nr] = NULL;
-+ spin_unlock_irq(&table->lock);
-+ }
-+}
-+
-+struct usb_buf *
-+usbc_string_find(struct usbc_strs *table, unsigned int lang, unsigned int idx)
-+{
-+ struct usb_buf *buf = NULL;
-+
-+ if (idx < NR_STRINGS) {
-+ spin_lock_irq(&table->lock);
-+ buf = usbb_get(table->buf[idx]);
-+ spin_unlock_irq(&table->lock);
-+ }
-+
-+ return buf;
-+}
-+
-+void usbc_string_free_all(struct usbc_strs *table)
-+{
-+ int i;
-+
-+ spin_lock_irq(&table->lock);
-+ for (i = 0; i < NR_STRINGS; i++) {
-+ usbc_string_free(table->buf[i]);
-+ table->buf[i] = NULL;
-+ }
-+ spin_unlock_irq(&table->lock);
-+}
-+
-+void usbc_string_init(struct usbc_strs *table)
-+{
-+ memset(table, 0, sizeof(struct usbc_strs));
-+ spin_lock_init(&table->lock);
-+}
-+
-+EXPORT_SYMBOL(usbc_string_from_cstr);
-+EXPORT_SYMBOL(usbc_string_alloc);
-+EXPORT_SYMBOL(usbc_string_free);
-+EXPORT_SYMBOL(usbc_string_add);
-+EXPORT_SYMBOL(usbc_string_del);
-+EXPORT_SYMBOL(usbc_string_find);
-+EXPORT_SYMBOL(usbc_string_free_all);
-+EXPORT_SYMBOL(usbc_string_init);
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/usb_ctl.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,171 @@
-+ /*
-+ * Copyright (C) Compaq Computer Corporation, 1998, 1999
-+ * Copyright (C) Extenex Corporation, 2001
-+ *
-+ * usb_ctl.c
-+ *
-+ * SA1100 USB controller core driver.
-+ *
-+ * This file provides interrupt routing and overall coordination
-+ * of the three endpoints in usb_ep0, usb_receive (1), and usb_send (2).
-+ *
-+ * Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
-+ *
-+ */
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/usb.h>
-+
-+#include "buffer.h"
-+#include "client.h"
-+#include "usbdev.h"
-+#include "sa1100_usb.h"
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Globals
-+//////////////////////////////////////////////////////////////////////////////
-+
-+/* device descriptors */
-+static struct cdb cdb;
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Private Helpers
-+//////////////////////////////////////////////////////////////////////////////
-+
-+int sa1100_usb_add_string(struct usbctl *ctl, const char *str)
-+{
-+ int nr = 0;
-+
-+ if (str) {
-+ struct usb_buf *buf;
-+ int len;
-+
-+ len = strlen(str);
-+
-+ nr = -ENOMEM;
-+ buf = usbc_string_alloc(len);
-+ if (buf) {
-+ usbc_string_from_cstr(buf, str);
-+ nr = usbc_string_add(&ctl->strings, buf);
-+
-+ if (nr < 0)
-+ usbc_string_free(buf);
-+ }
-+ }
-+
-+ return nr;
-+}
-+
-+EXPORT_SYMBOL(sa1100_usb_add_string);
-+
-+static int sa1100_usb_add_language(struct usbctl *ctl, unsigned int lang)
-+{
-+ struct usb_buf *buf;
-+ int nr = -ENOMEM;
-+
-+ buf = usbc_string_alloc(1);
-+ if (buf) {
-+ usbc_string_desc(buf)->wData[0] = cpu_to_le16(lang); /* American English */
-+ nr = usbc_string_add(&ctl->strings, buf);
-+
-+ if (nr < 0)
-+ usbc_string_free(buf);
-+ }
-+
-+ return nr;
-+}
-+
-+/* setup default descriptors */
-+
-+void initialize_descriptors(struct usbctl *ctl)
-+{
-+ struct usb_client *clnt = ctl->clnt;
-+ int r;
-+
-+ ctl->ep_desc[0] = (struct usb_endpoint_descriptor *)&cdb.ep1;
-+ ctl->ep_desc[1] = (struct usb_endpoint_descriptor *)&cdb.ep2;
-+
-+ cdb.cfg.bLength = USB_DT_CONFIG_SIZE;
-+ cdb.cfg.bDescriptorType = USB_DT_CONFIG;
-+ cdb.cfg.wTotalLength = cpu_to_le16(sizeof(struct cdb));
-+ cdb.cfg.bNumInterfaces = 1;
-+ cdb.cfg.bConfigurationValue = 1;
-+ cdb.cfg.iConfiguration = 0;
-+ cdb.cfg.bmAttributes = USB_CONFIG_ATT_ONE;
-+ cdb.cfg.bMaxPower = USB_POWER( 500 );
-+
-+ cdb.intf.bLength = USB_DT_INTERFACE_SIZE;
-+ cdb.intf.bDescriptorType = USB_DT_INTERFACE;
-+ cdb.intf.bInterfaceNumber = 0; /* unique intf index*/
-+ cdb.intf.bAlternateSetting = 0;
-+ cdb.intf.bNumEndpoints = 2;
-+ cdb.intf.bInterfaceClass = 0xff; /* vendor specific */
-+ cdb.intf.bInterfaceSubClass = 0;
-+ cdb.intf.bInterfaceProtocol = 0;
-+ cdb.intf.iInterface = 0;
-+
-+ cdb.ep1.bLength = USB_DT_INTERFACE_SIZE;
-+ cdb.ep1.bDescriptorType = USB_DT_ENDPOINT;
-+ cdb.ep1.bEndpointAddress = USB_DIR_OUT | 1;
-+ cdb.ep1.bmAttributes = USB_ENDPOINT_XFER_BULK;
-+ cdb.ep1.wMaxPacketSize = cpu_to_le16(64);
-+ cdb.ep1.bInterval = 0;
-+
-+ cdb.ep2.bLength = USB_DT_INTERFACE_SIZE;
-+ cdb.ep2.bDescriptorType = USB_DT_ENDPOINT;
-+ cdb.ep2.bEndpointAddress = USB_DIR_IN | 2;
-+ cdb.ep2.bmAttributes = USB_ENDPOINT_XFER_BULK;
-+ cdb.ep2.wMaxPacketSize = cpu_to_le16(64);
-+ cdb.ep2.bInterval = 0;
-+
-+ ctl->dev_desc->bLength = USB_DT_DEVICE_SIZE;
-+ ctl->dev_desc->bDescriptorType = USB_DT_DEVICE;
-+ ctl->dev_desc->bcdUSB = cpu_to_le16(0x100); /* 1.0 */
-+ ctl->dev_desc->bDeviceClass = clnt->class;
-+ ctl->dev_desc->bDeviceSubClass = clnt->subclass;
-+ ctl->dev_desc->bDeviceProtocol = clnt->protocol;
-+ ctl->dev_desc->bMaxPacketSize0 = 8; /* ep0 max fifo size */
-+ ctl->dev_desc->idVendor = cpu_to_le16(clnt->vendor);
-+ ctl->dev_desc->idProduct = cpu_to_le16(clnt->product);
-+ ctl->dev_desc->bcdDevice = cpu_to_le16(clnt->version);
-+ ctl->dev_desc->bNumConfigurations = 1;
-+
-+ /* set language */
-+ /* See: http://www.usb.org/developers/data/USB_LANGIDs.pdf */
-+ r = sa1100_usb_add_language(ctl, 0x409);
-+ if (r < 0)
-+ printk(KERN_ERR "usbc: couldn't add language\n");
-+
-+ r = sa1100_usb_add_string(ctl, clnt->manufacturer_str);
-+ if (r < 0)
-+ printk(KERN_ERR "usbc: couldn't add manufacturer string\n");
-+
-+ ctl->dev_desc->iManufacturer = r > 0 ? r : 0;
-+
-+ r = sa1100_usb_add_string(ctl, clnt->product_str);
-+ if (r < 0)
-+ printk(KERN_ERR "usbc: couldn't add product string\n");
-+
-+ ctl->dev_desc->iProduct = r > 0 ? r : 0;
-+
-+ r = sa1100_usb_add_string(ctl, clnt->serial_str);
-+ if (r < 0)
-+ printk(KERN_ERR "usbc: couldn't add serial string\n");
-+
-+ ctl->dev_desc->iSerialNumber = r > 0 ? r : 0;
-+}
-+
-+
-+/*====================================================
-+ * Descriptor Manipulation.
-+ * Use these between open() and start() above to setup
-+ * the descriptors for your device.
-+ */
-+
-+/* get pointer to static default descriptor */
-+struct cdb *sa1100_usb_get_descriptor_ptr(void)
-+{
-+ return &cdb;
-+}
-+
-+EXPORT_SYMBOL(sa1100_usb_get_descriptor_ptr);
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/Makefile 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,12 @@
-+#
-+# Makefile for the USB client
-+#
-+
-+usbdevcore-objs := buffer.o control.o strings.o usb_ctl.o
-+
-+sa1100-objs := sa1100usb.o usb_recv.o usb_send.o
-+
-+obj-$(CONFIG_SA1100_USB) += usbdevcore.o sa1100.o
-+obj-$(CONFIG_SA1100_USB_NETLINK) += usb-eth.o
-+obj-$(CONFIG_SA1100_USB_CHAR) += usb-char.o
-+
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/usb/usbdev.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,91 @@
-+#ifndef USBDEV_H
-+#define USBDEV_H
-+
-+#include "strings.h"
-+
-+struct usb_buf;
-+struct module;
-+struct cdb;
-+struct usb_client;
-+
-+struct usbc_driver {
-+ struct module *owner;
-+ const char *name;
-+ void *priv;
-+ int (*start)(void *);
-+ int (*stop)(void *);
-+
-+ int (*ep0_queue)(void *, struct usb_buf *buf, unsigned int req_len);
-+ void (*set_address)(void *, unsigned int addr);
-+ void (*set_config)(void *, struct cdb *config);
-+
-+ /*
-+ * Get specified endpoint status, as defined in 9.4.5.
-+ */
-+ unsigned int (*ep_get_status)(void *, unsigned int ep);
-+ void (*ep_halt)(void *, unsigned int ep, int halt);
-+
-+ /*
-+ * Client
-+ */
-+ int (*ep_queue)(void *, unsigned int, char *, unsigned int);
-+ void (*ep_reset)(void *, unsigned int);
-+ void (*ep_callback)(void *, unsigned int, void (*)(void *, int, int), void *);
-+ int (*ep_idle)(void *, unsigned int);
-+};
-+
-+struct usbc_endpoint {
-+ struct usb_endpoint_descriptor *desc;
-+};
-+
-+struct usbc_interface {
-+ struct usb_interface_descriptor *desc;
-+ unsigned int nr_ep;
-+ struct usbc_endpoint *ep[0];
-+};
-+
-+struct usbc_config {
-+ struct usb_config_descriptor *desc;
-+ unsigned int nr_interface;
-+ struct usbc_interface *interface[0];
-+};
-+
-+struct usbctl {
-+ struct usb_client *clnt;
-+ const struct usbc_driver *driver;
-+
-+ /* Internal state */
-+ unsigned int address; /* host assigned address */
-+ unsigned int state; /* our device state */
-+ unsigned int sm_state; /* state machine state */
-+
-+ struct usbc_config *config; /* active configuration */
-+ struct usbc_strs strings;
-+
-+ /* Descriptors */
-+ struct usb_device_descriptor *dev_desc; /* device descriptor */
-+ struct usb_buf *dev_desc_buf; /* device descriptor buffer */
-+
-+
-+ int nr_ep;
-+ struct usb_endpoint_descriptor *ep_desc[2];
-+};
-+
-+/*
-+ * Function Prototypes
-+ */
-+
-+#define RET_ERROR (-1)
-+#define RET_NOACTION (0)
-+#define RET_QUEUED (1)
-+#define RET_ACK (2)
-+#define RET_REQERROR (3)
-+
-+int usbctl_parse_request(struct usbctl *ctl, struct usb_ctrlrequest *req);
-+
-+int usbctl_reset(struct usbctl *ctl);
-+void usbctl_suspend(struct usbctl *ctl);
-+void usbctl_resume(struct usbctl *ctl);
-+
-+#endif
-+
---- linux-2.6.5/arch/arm/mach-sa1100/pm.c~heh 2004-04-03 22:36:27.000000000 -0500
-+++ linux-2.6.5/arch/arm/mach-sa1100/pm.c 2004-04-30 20:57:36.000000000 -0400
-@@ -150,6 +150,7 @@
- */
- static int sa11x0_pm_prepare(u32 state)
- {
-+ nmi_watchdog_disable();
- return 0;
- }
-
-@@ -158,6 +159,7 @@
- */
- static int sa11x0_pm_finish(u32 state)
- {
-+ nmi_watchdog_enable();
- return 0;
- }
-
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/arch/arm/mach-sa1100/nmi-oopser.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,104 @@
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/gfp.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+
-+#include <asm/ptrace.h>
-+#include <asm/domain.h>
-+#include <asm/hardware.h>
-+
-+static void *nmi_stack;
-+
-+asm(" \n\
-+nmi_start: \n\
-+ mrs r8, spsr \n\
-+ ldr r9, .Lstack \n\
-+ ldr sp, [r9] \n\
-+ sub sp, sp, #18 * 4 \n\
-+ str r8, [sp, #16 * 4] \n\
-+ str lr, [sp, #15 * 4] \n\
-+ stmia sp, {r0 - r7} \n\
-+ add r0, sp, #8 * 4 \n\
-+ mrs r2, cpsr \n\
-+ bic r1, r2, #0x1f \n\
-+ orr r1, r1, #0x13 \n\
-+ msr cpsr_c, r1 \n\
-+ mov r0, r0 \n\
-+ stmia r0, {r8 - lr} \n\
-+ mov r0, r0 \n\
-+ msr cpsr_c, r2 \n\
-+ mov r0, r0 \n\
-+ mov r0, sp \n\
-+ mov lr, pc \n\
-+ ldr pc, .Lfn \n\
-+ ldmia sp, {r0 - r7} \n\
-+ ldr r8, [sp, #16 * 4] \n\
-+ ldr lr, [sp, #15 * 4] \n\
-+ add sp, sp, #18 * 4 \n\
-+ msr spsr, r8 \n\
-+ movs pc, lr \n\
-+ \n\
-+.Lstack: .long nmi_stack \n\
-+.Lfn: .long nmi_fn \n\
-+nmi_end:");
-+
-+extern unsigned char nmi_start, nmi_end;
-+
-+static void __attribute__((unused)) nmi_fn(struct pt_regs *regs)
-+{
-+ struct thread_info *thread;
-+ unsigned long osmr0, osmr1, oscr, ossr, icmr, icip;
-+
-+ oscr = OSCR;
-+ osmr0 = OSMR0;
-+ osmr1 = OSMR1;
-+ ossr = OSSR;
-+ icmr = ICMR;
-+ icip = ICIP;
-+
-+ OSSR = OSSR_M1;
-+ ICMR &= ~IC_OST1;
-+
-+ thread = (struct thread_info *)(regs->ARM_sp & ~8191);
-+
-+ bust_spinlocks(1);
-+ printk("OSMR0:%08lx OSMR1:%08lx OSCR:%08lx OSSR:%08lx ICMR:%08lx ICIP:%08lx\n",
-+ osmr0, osmr1, oscr, ossr, icmr, icip);
-+ nmi_watchdog(thread, regs);
-+ bust_spinlocks(0);
-+
-+ OSSR = OSSR_M1;
-+ OSMR1 = OSSR + 36864000;
-+ ICMR |= IC_OST1;
-+}
-+
-+static int nmi_init(void)
-+{
-+ unsigned char *vec_base = (unsigned char *)vectors_base();
-+return 0;
-+ nmi_stack = (void *)__get_free_page(GFP_KERNEL);
-+ if (!nmi_stack)
-+ return -ENOMEM;
-+
-+ nmi_stack += PAGE_SIZE;
-+
-+ modify_domain(DOMAIN_USER, DOMAIN_MANAGER);
-+ memcpy(vec_base + 0x1c, &nmi_start, &nmi_end - &nmi_start);
-+ modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
-+
-+ /*
-+ * Ensure timer 1 is set to FIQ, and enabled.
-+ */
-+ OSMR1 = OSCR - 1;
-+ OSSR = OSSR_M1;
-+ OIER |= OIER_E1;
-+ ICLR |= IC_OST1;
-+ ICMR |= IC_OST1;
-+
-+ return 0;
-+}
-+
-+__initcall(nmi_init);
---- linux-2.6.5/drivers/media/Kconfig~heh 2004-04-03 22:36:51.000000000 -0500
-+++ linux-2.6.5/drivers/media/Kconfig 2004-04-30 20:57:36.000000000 -0400
-@@ -32,6 +32,8 @@
-
- source "drivers/media/common/Kconfig"
-
-+source "drivers/media/mmc/Kconfig"
-+
- config VIDEO_TUNER
- tristate
- default y if VIDEO_BT848=y || VIDEO_SAA7134=y || VIDEO_MXB=y || VIDEO_CX88=y
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/media/mmc/Kconfig 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,52 @@
-+#
-+# MMC subsystem configuration
-+#
-+
-+menu "MMC/SD Card support"
-+
-+config MMC
-+ tristate "MMC support"
-+ help
-+ MMC is the "multi-media card" bus protocol.
-+
-+ If you want MMC support, you should say Y here and also
-+ to the specific driver for your MMC interface.
-+
-+config MMC_DEBUG
-+ bool "MMC debugging"
-+ depends on MMC != n
-+ help
-+ This is an option for use by developers; most people should
-+ say N here. This enables MMC core and driver debugging.
-+
-+config MMC_BLOCK
-+ tristate "MMC block device driver"
-+ depends on MMC
-+ default y
-+ help
-+ Say Y here to enable the MMC block device driver support.
-+ This provides a block device driver, which you can use to
-+ mount the filesystem. Almost everyone wishing MMC support
-+ should say Y or M here.
-+
-+config MMC_ARMMMCI
-+ tristate "ARM AMBA Multimedia Card Interface support"
-+ depends on ARM_AMBA && MMC
-+ help
-+ This selects the ARM(R) AMBA(R) PrimeCell Multimedia Card
-+ Interface (PL180 and PL181) support. If you have an ARM(R)
-+ platform with a Multimedia Card slot, say Y or M here.
-+
-+ If unsure, say N.
-+
-+config MMC_PXA
-+ tristate "Intel PXA255 Multimedia Card Interface support"
-+ depends on ARCH_PXA && MMC
-+ help
-+ This selects the Intel(R) PXA(R) Multimedia card Interface.
-+ If you have a PXA(R) platform with a Multimedia Card slot,
-+ say Y or M here.
-+
-+ If unsure, say N.
-+
-+endmenu
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/media/mmc/mmc_queue.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,171 @@
-+/*
-+ * linux/drivers/media/mmc/mmc_queue.c
-+ *
-+ * Copyright (C) 2003 Russell King, 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 version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ */
-+#include <linux/module.h>
-+#include <linux/blkdev.h>
-+
-+#include <linux/mmc/card.h>
-+#include <linux/mmc/host.h>
-+#include "mmc_queue.h"
-+
-+/*
-+ * Prepare a MMC request. Essentially, this means passing the
-+ * preparation off to the media driver. The media driver will
-+ * create a mmc_io_request in req->special.
-+ */
-+static int mmc_prep_request(struct request_queue *q, struct request *req)
-+{
-+ struct mmc_queue *mq = q->queuedata;
-+ int ret = BLKPREP_KILL;
-+
-+ if (req->flags & REQ_SPECIAL) {
-+ /*
-+ * Special commands already have the command
-+ * blocks already setup in req->special.
-+ */
-+ BUG_ON(!req->special);
-+
-+ ret = BLKPREP_OK;
-+ } else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
-+ /*
-+ * Block I/O requests need translating according
-+ * to the protocol.
-+ */
-+ ret = mq->prep_fn(mq, req);
-+ } else {
-+ /*
-+ * Everything else is invalid.
-+ */
-+ blk_dump_rq_flags(req, "MMC bad request");
-+ }
-+
-+ if (ret == BLKPREP_OK)
-+ req->flags |= REQ_DONTPREP;
-+
-+ return ret;
-+}
-+
-+static int mmc_queue_thread(void *d)
-+{
-+ struct mmc_queue *mq = d;
-+ struct request_queue *q = mq->queue;
-+ DECLARE_WAITQUEUE(wait, current);
-+ int ret;
-+
-+ /*
-+ * Set iothread to ensure that we aren't put to sleep by
-+ * the process freezing. We handle suspension ourselves.
-+ */
-+ current->flags |= PF_MEMALLOC|PF_IOTHREAD;
-+
-+ daemonize("mmcqd");
-+
-+ spin_lock_irq(&current->sighand->siglock);
-+ sigfillset(&current->blocked);
-+ recalc_sigpending();
-+ spin_unlock_irq(&current->sighand->siglock);
-+
-+ mq->thread = current;
-+ complete(&mq->thread_complete);
-+
-+ add_wait_queue(&mq->thread_wq, &wait);
-+ spin_lock_irq(q->queue_lock);
-+ do {
-+ struct request *req = NULL;
-+
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (!blk_queue_plugged(q))
-+ mq->req = req = elv_next_request(q);
-+ spin_unlock(q->queue_lock);
-+
-+ if (!req) {
-+ if (!mq->thread)
-+ break;
-+ schedule();
-+ continue;
-+ }
-+ set_current_state(TASK_RUNNING);
-+
-+ ret = mq->issue_fn(mq, req);
-+
-+ spin_lock_irq(q->queue_lock);
-+ end_request(req, ret);
-+ } while (1);
-+ remove_wait_queue(&mq->thread_wq, &wait);
-+
-+ complete_and_exit(&mq->thread_complete, 0);
-+ return 0;
-+}
-+
-+/*
-+ * Generic MMC request handler. This is called for any queue on a
-+ * particular host. When the host is not busy, we look for a request
-+ * on any queue on this host, and attempt to issue it. This may
-+ * not be the queue we were asked to process.
-+ */
-+static void mmc_request(request_queue_t *q)
-+{
-+ struct mmc_queue *mq = q->queuedata;
-+
-+ if (!mq->req && !blk_queue_plugged(q))
-+ wake_up(&mq->thread_wq);
-+}
-+
-+/**
-+ * mmc_init_queue - initialise a queue structure.
-+ * @mq: mmc queue
-+ * @card: mmc card to attach this queue
-+ * @lock: queue lock
-+ *
-+ * Initialise a MMC card request queue.
-+ */
-+int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock)
-+{
-+ u64 limit = BLK_BOUNCE_HIGH;
-+ int ret;
-+
-+ if (card->host->dev->dma_mask)
-+ limit = *card->host->dev->dma_mask;
-+
-+ mq->card = card;
-+ mq->queue = blk_init_queue(mmc_request, lock);
-+ blk_queue_prep_rq(mq->queue, mmc_prep_request);
-+ blk_queue_bounce_limit(mq->queue, limit);
-+
-+ mq->queue->queuedata = mq;
-+ mq->req = NULL;
-+
-+ init_completion(&mq->thread_complete);
-+ init_waitqueue_head(&mq->thread_wq);
-+
-+ ret = kernel_thread(mmc_queue_thread, mq, CLONE_KERNEL);
-+ if (ret < 0) {
-+ blk_cleanup_queue(mq->queue);
-+ } else {
-+ wait_for_completion(&mq->thread_complete);
-+ init_completion(&mq->thread_complete);
-+ }
-+
-+ return ret;
-+}
-+
-+EXPORT_SYMBOL(mmc_init_queue);
-+
-+void mmc_cleanup_queue(struct mmc_queue *mq)
-+{
-+ mq->thread = NULL;
-+ wake_up(&mq->thread_wq);
-+ wait_for_completion(&mq->thread_complete);
-+ blk_cleanup_queue(mq->queue);
-+
-+ mq->card = NULL;
-+}
-+
-+EXPORT_SYMBOL(mmc_cleanup_queue);
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/media/mmc/pxamci.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,587 @@
-+/*
-+ * linux/drivers/media/mmc/pxa.c - PXA MMCI driver
-+ *
-+ * Copyright (C) 2003 Russell King, 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 version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This hardware is really sick. No way to clear interrupts. Have
-+ * to turn off the clock whenever we touch the device. Yuck!
-+ *
-+ * 1 and 3 byte data transfers not supported
-+ * max block length up to 1023
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/ioport.h>
-+#include <linux/device.h>
-+#include <linux/interrupt.h>
-+#include <linux/blkdev.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/mmc/host.h>
-+#include <linux/mmc/protocol.h>
-+
-+#include <asm/dma.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/sizes.h>
-+
-+#include "pxamci.h"
-+
-+#ifdef CONFIG_MMC_DEBUG
-+#define DBG(x...) printk(KERN_DEBUG x)
-+#else
-+#define DBG(x...) do { } while (0)
-+#endif
-+
-+struct pxamci_host {
-+ struct mmc_host mmc;
-+ spinlock_t lock;
-+ struct resource *res;
-+ void *base;
-+ int irq;
-+ int dma;
-+ unsigned int clkrt;
-+ unsigned int cmdat;
-+ unsigned int imask;
-+ unsigned int power_mode;
-+
-+ struct mmc_request *req;
-+ struct mmc_command *cmd;
-+ struct mmc_data *data;
-+
-+ dma_addr_t sg_dma;
-+ struct pxa_dma_desc *sg_cpu;
-+
-+ dma_addr_t dma_buf;
-+ unsigned int dma_size;
-+ unsigned int dma_dir;
-+};
-+
-+#define to_pxamci_host(x) container_of(x, struct pxamci_host, mmc)
-+
-+/*
-+ * The base MMC clock rate
-+ */
-+#define CLOCKRATE 20000000
-+
-+static inline unsigned int ns_to_clocks(unsigned int ns)
-+{
-+ return (ns * (CLOCKRATE / 1000000) + 999) / 1000;
-+}
-+
-+static void pxamci_stop_clock(struct pxamci_host *host)
-+{
-+ if (readl(host->base + MMC_STAT) & STAT_CLK_EN) {
-+ unsigned long flags;
-+ unsigned int v;
-+
-+ writel(STOP_CLOCK, host->base + MMC_STRPCL);
-+
-+ /*
-+ * Wait for the "clock has stopped" interrupt.
-+ * We need to unmask the interrupt to receive
-+ * the notification. Sigh.
-+ */
-+ spin_lock_irqsave(&host->lock, flags);
-+ writel(host->imask & ~CLK_IS_OFF, host->base + MMC_I_MASK);
-+ do {
-+ v = readl(host->base + MMC_I_REG);
-+ } while (!(v & CLK_IS_OFF));
-+ writel(host->imask, host->base + MMC_I_MASK);
-+ spin_unlock_irqrestore(&host->lock, flags);
-+ }
-+}
-+
-+static void pxamci_enable_irq(struct pxamci_host *host, unsigned int mask)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&host->lock, flags);
-+ host->imask &= ~mask;
-+ writel(host->imask, host->base + MMC_I_MASK);
-+ spin_unlock_irqrestore(&host->lock, flags);
-+}
-+
-+static void pxamci_disable_irq(struct pxamci_host *host, unsigned int mask)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&host->lock, flags);
-+ host->imask |= mask;
-+ writel(host->imask, host->base + MMC_I_MASK);
-+ spin_unlock_irqrestore(&host->lock, flags);
-+}
-+
-+static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data)
-+{
-+ unsigned int nob = data->blocks;
-+ unsigned int timeout, size;
-+ dma_addr_t dma;
-+ u32 dcmd;
-+ int i;
-+
-+ host->data = data;
-+
-+ if (data->flags & MMC_DATA_STREAM)
-+ nob = 0xffff;
-+
-+ writel(nob, host->base + MMC_NOB);
-+ writel(1 << data->blksz_bits, host->base + MMC_BLKLEN);
-+
-+ timeout = ns_to_clocks(data->timeout_ns) + data->timeout_clks;
-+ writel((timeout + 255) / 256, host->base + MMC_RDTO);
-+
-+ if (data->flags & MMC_DATA_READ) {
-+ host->dma_dir = DMA_FROM_DEVICE;
-+ dcmd = DCMD_INCTRGADDR | DCMD_FLOWTRG;
-+ DRCMRTXMMC = 0;
-+ DRCMRRXMMC = host->dma | DRCMR_MAPVLD;
-+ } else {
-+ host->dma_dir = DMA_TO_DEVICE;
-+ dcmd = DCMD_INCSRCADDR | DCMD_FLOWSRC;
-+ DRCMRRXMMC = 0;
-+ DRCMRTXMMC = host->dma | DRCMR_MAPVLD;
-+ }
-+
-+ dcmd |= DCMD_BURST32 | DCMD_WIDTH1;
-+
-+ host->dma_size = data->blocks << data->blksz_bits;
-+ host->dma_buf = dma_map_single(host->mmc.dev, data->rq->buffer,
-+ host->dma_size, host->dma_dir);
-+
-+ for (i = 0, size = host->dma_size, dma = host->dma_buf; size; i++) {
-+ u32 len = size;
-+
-+ if (len > DCMD_LENGTH)
-+ len = 0x1000;
-+
-+ if (data->flags & MMC_DATA_READ) {
-+ host->sg_cpu[i].dsadr = host->res->start + MMC_RXFIFO;
-+ host->sg_cpu[i].dtadr = dma;
-+ } else {
-+ host->sg_cpu[i].dsadr = dma;
-+ host->sg_cpu[i].dtadr = host->res->start + MMC_TXFIFO;
-+ }
-+ host->sg_cpu[i].dcmd = dcmd | len;
-+
-+ dma += len;
-+ size -= len;
-+
-+ if (size) {
-+ host->sg_cpu[i].ddadr = host->sg_dma + (i + 1) *
-+ sizeof(struct pxa_dma_desc);
-+ } else {
-+ host->sg_cpu[i].ddadr = DDADR_STOP;
-+ }
-+ }
-+ wmb();
-+
-+ DDADR(host->dma) = host->sg_dma;
-+ DCSR(host->dma) = DCSR_RUN;
-+}
-+
-+static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, unsigned int cmdat)
-+{
-+ WARN_ON(host->cmd != NULL);
-+ host->cmd = cmd;
-+
-+ if (cmd->flags & MMC_RSP_BUSY)
-+ cmdat |= CMDAT_BUSY;
-+
-+ switch (cmd->flags & (MMC_RSP_MASK | MMC_RSP_CRC)) {
-+ case MMC_RSP_SHORT | MMC_RSP_CRC:
-+ cmdat |= CMDAT_RESP_SHORT;
-+ break;
-+ case MMC_RSP_SHORT:
-+ cmdat |= CMDAT_RESP_R3;
-+ break;
-+ case MMC_RSP_LONG | MMC_RSP_CRC:
-+ cmdat |= CMDAT_RESP_R2;
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ writel(cmd->opcode, host->base + MMC_CMD);
-+ writel(cmd->arg >> 16, host->base + MMC_ARGH);
-+ writel(cmd->arg & 0xffff, host->base + MMC_ARGL);
-+ writel(cmdat, host->base + MMC_CMDAT);
-+ writel(host->clkrt, host->base + MMC_CLKRT);
-+
-+ writel(START_CLOCK, host->base + MMC_STRPCL);
-+
-+ pxamci_enable_irq(host, END_CMD_RES);
-+}
-+
-+static void pxamci_finish_request(struct pxamci_host *host, struct mmc_request *req)
-+{
-+ DBG("PXAMCI: request done\n");
-+ host->req = NULL;
-+ host->cmd = NULL;
-+ host->data = NULL;
-+ mmc_request_done(&host->mmc, req);
-+}
-+
-+static int pxamci_cmd_done(struct pxamci_host *host, unsigned int stat)
-+{
-+ struct mmc_command *cmd = host->cmd;
-+ int i;
-+ u32 v;
-+
-+ if (!cmd)
-+ return 0;
-+
-+ host->cmd = NULL;
-+
-+ /*
-+ * Did I mention this is Sick. We always need to
-+ * discard the upper 8 bits of the first 16-bit word.
-+ */
-+ v = readl(host->base + MMC_RES) & 0xffff;
-+ for (i = 0; i < 4; i++) {
-+ u32 w1 = readl(host->base + MMC_RES) & 0xffff;
-+ u32 w2 = readl(host->base + MMC_RES) & 0xffff;
-+ cmd->resp[i] = v << 24 | w1 << 8 | w2 >> 8;
-+ v = w2;
-+ }
-+
-+ if (stat & STAT_TIME_OUT_RESPONSE) {
-+ cmd->error = MMC_ERR_TIMEOUT;
-+ } else if (stat & STAT_RES_CRC_ERR && cmd->flags & MMC_RSP_CRC) {
-+ cmd->error = MMC_ERR_BADCRC;
-+ }
-+
-+ pxamci_disable_irq(host, END_CMD_RES);
-+ if (host->data && cmd->error == MMC_ERR_NONE) {
-+ pxamci_enable_irq(host, DATA_TRAN_DONE);
-+ } else {
-+ pxamci_finish_request(host, host->req);
-+ }
-+
-+ return 1;
-+}
-+
-+static int pxamci_data_done(struct pxamci_host *host, unsigned int stat)
-+{
-+ struct mmc_data *data = host->data;
-+
-+ if (!data)
-+ return 0;
-+
-+ DCSR(host->dma) = 0;
-+ dma_unmap_single(host->mmc.dev, host->dma_buf, host->dma_size,
-+ host->dma_dir);
-+
-+ if (stat & STAT_READ_TIME_OUT)
-+ data->error = MMC_ERR_TIMEOUT;
-+ else if (stat & (STAT_CRC_READ_ERROR|STAT_CRC_WRITE_ERROR))
-+ data->error = MMC_ERR_BADCRC;
-+
-+ data->bytes_xfered = (data->blocks - readl(host->base + MMC_NOB))
-+ << data->blksz_bits;
-+
-+ pxamci_disable_irq(host, DATA_TRAN_DONE);
-+
-+ host->data = NULL;
-+ if (host->req->stop && data->error == MMC_ERR_NONE) {
-+ pxamci_stop_clock(host);
-+ pxamci_start_cmd(host, host->req->stop, 0);
-+ } else {
-+ pxamci_finish_request(host, host->req);
-+ }
-+
-+ return 1;
-+}
-+
-+static irqreturn_t pxamci_irq(int irq, void *devid, struct pt_regs *regs)
-+{
-+ struct pxamci_host *host = devid;
-+ unsigned int ireg;
-+ int handled = 0;
-+
-+ ireg = readl(host->base + MMC_I_REG);
-+
-+ DBG("PXAMCI: irq %08x\n", ireg);
-+
-+ if (ireg) {
-+ unsigned stat = readl(host->base + MMC_STAT);
-+
-+ DBG("PXAMCI: stat %08x\n", stat);
-+
-+ if (ireg & END_CMD_RES)
-+ handled |= pxamci_cmd_done(host, stat);
-+ if (ireg & DATA_TRAN_DONE)
-+ handled |= pxamci_data_done(host, stat);
-+ }
-+
-+ return IRQ_RETVAL(handled);
-+}
-+
-+static void pxamci_request(struct mmc_host *mmc, struct mmc_request *req)
-+{
-+ struct pxamci_host *host = to_pxamci_host(mmc);
-+ unsigned int cmdat;
-+
-+ WARN_ON(host->req != NULL);
-+
-+ host->req = req;
-+
-+ pxamci_stop_clock(host);
-+
-+ cmdat = host->cmdat;
-+ host->cmdat &= ~CMDAT_INIT;
-+
-+ if (req->data) {
-+ pxamci_setup_data(host, req->data);
-+
-+ cmdat &= ~CMDAT_BUSY;
-+ cmdat |= CMDAT_DATAEN | CMDAT_DMAEN;
-+ if (req->data->flags & MMC_DATA_WRITE)
-+ cmdat |= CMDAT_WRITE;
-+
-+ if (req->data->flags & MMC_DATA_STREAM)
-+ cmdat |= CMDAT_STREAM;
-+ }
-+
-+ pxamci_start_cmd(host, req->cmd, cmdat);
-+}
-+
-+static void pxamci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
-+{
-+ struct pxamci_host *host = to_pxamci_host(mmc);
-+
-+ DBG("pxamci_set_ios: clock %u power %u vdd %u.%02u\n",
-+ ios->clock, ios->power_mode, ios->vdd / 100,
-+ ios->vdd % 100);
-+
-+ if (ios->clock) {
-+ unsigned int clk = CLOCKRATE / ios->clock;
-+ if (CLOCKRATE / clk > ios->clock)
-+ clk <<= 1;
-+ host->clkrt = fls(clk) - 1;
-+
-+ /*
-+ * we write clkrt on the next command
-+ */
-+ } else if (readl(host->base + MMC_STAT) & STAT_CLK_EN) {
-+ /*
-+ * Ensure that the clock is off.
-+ */
-+ writel(STOP_CLOCK, host->base + MMC_STRPCL);
-+ }
-+
-+ if (host->power_mode != ios->power_mode) {
-+ host->power_mode = ios->power_mode;
-+
-+ /*
-+ * power control? none on the lubbock.
-+ */
-+
-+ if (ios->power_mode == MMC_POWER_ON)
-+ host->cmdat |= CMDAT_INIT;
-+ }
-+
-+ DBG("pxamci_set_ios: clkrt = %x cmdat = %x\n",
-+ host->clkrt, host->cmdat);
-+}
-+
-+static struct mmc_host_ops pxamci_ops = {
-+ .request = pxamci_request,
-+ .set_ios = pxamci_set_ios,
-+};
-+
-+static struct resource *platform_device_resource(struct platform_device *dev, unsigned int mask, int nr)
-+{
-+ int i;
-+
-+ for (i = 0; i < dev->num_resources; i++)
-+ if (dev->resource[i].flags == mask && nr-- == 0)
-+ return &dev->resource[i];
-+ return NULL;
-+}
-+
-+static int platform_device_irq(struct platform_device *dev, int nr)
-+{
-+ int i;
-+
-+ for (i = 0; i < dev->num_resources; i++)
-+ if (dev->resource[i].flags == IORESOURCE_IRQ && nr-- == 0)
-+ return dev->resource[i].start;
-+ return NO_IRQ;
-+}
-+
-+static void pxamci_dma_irq(int dma, void *devid, struct pt_regs *regs)
-+{
-+ printk(KERN_ERR "DMA%d: IRQ???\n", dma);
-+ DCSR(dma) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
-+}
-+
-+static int pxamci_probe(struct device *dev)
-+{
-+ struct platform_device *pdev = to_platform_device(dev);
-+ struct pxamci_host *host;
-+ struct resource *r;
-+ int ret, irq;
-+
-+ r = platform_device_resource(pdev, IORESOURCE_MEM, 0);
-+ irq = platform_device_irq(pdev, 0);
-+ if (!r || irq == NO_IRQ)
-+ return -ENXIO;
-+
-+ r = request_mem_region(r->start, SZ_4K, "PXAMCI");
-+ if (!r)
-+ return -EBUSY;
-+
-+ host = kmalloc(sizeof(struct pxamci_host), GFP_KERNEL);
-+ if (!host) {
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+
-+ memset(host, 0, sizeof(struct pxamci_host));
-+ host->dma = -1;
-+
-+ host->sg_cpu = dma_alloc_coherent(dev, PAGE_SIZE, &host->sg_dma, GFP_KERNEL);
-+ if (!host->sg_cpu) {
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+
-+ ret = mmc_init_host(&host->mmc);
-+ if (ret)
-+ goto out;
-+
-+ spin_lock_init(&host->lock);
-+ host->res = r;
-+ host->irq = irq;
-+ host->imask = TXFIFO_WR_REQ|RXFIFO_RD_REQ|CLK_IS_OFF|STOP_CMD|
-+ END_CMD_RES|PRG_DONE|DATA_TRAN_DONE;
-+ host->mmc.dev = dev;
-+ host->mmc.ops = &pxamci_ops;
-+ host->mmc.f_min = 312500;
-+ host->mmc.f_max = 20000000;
-+ host->mmc.ocr_avail = MMC_VDD_32_33;
-+
-+ host->base = ioremap(r->start, SZ_4K);
-+ if (!host->base) {
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+
-+ /*
-+ * Ensure that the host controller is shut down, and setup
-+ * with our defaults.
-+ */
-+ pxamci_stop_clock(host);
-+ writel(0, host->base + MMC_SPI);
-+ writel(64, host->base + MMC_RESTO);
-+
-+#ifdef CONFIG_PREEMPT
-+#error Not Preempt-safe
-+#endif
-+ pxa_gpio_mode(GPIO6_MMCCLK_MD);
-+ pxa_gpio_mode(GPIO8_MMCCS0_MD);
-+ CKEN |= CKEN12_MMC;
-+
-+ host->dma = pxa_request_dma("PXAMCI", DMA_PRIO_LOW, pxamci_dma_irq, host);
-+ if (host->dma < 0)
-+ goto out;
-+
-+ ret = request_irq(host->irq, pxamci_irq, 0, "PXAMCI", host);
-+ if (ret)
-+ goto out;
-+
-+ dev_set_drvdata(dev, host);
-+
-+ mmc_add_host(&host->mmc);
-+
-+ return 0;
-+
-+ out:
-+ if (host) {
-+ if (host->dma >= 0)
-+ pxa_free_dma(host->dma);
-+ if (host->base)
-+ iounmap(host->base);
-+ if (host->sg_cpu)
-+ dma_free_coherent(dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
-+ kfree(host);
-+ }
-+ release_resource(r);
-+ return ret;
-+}
-+
-+static int pxamci_remove(struct device *dev)
-+{
-+ struct pxamci_host *host = dev_get_drvdata(dev);
-+
-+ dev_set_drvdata(dev, NULL);
-+
-+ if (host) {
-+ mmc_remove_host(&host->mmc);
-+
-+ pxamci_stop_clock(host);
-+ writel(TXFIFO_WR_REQ|RXFIFO_RD_REQ|CLK_IS_OFF|STOP_CMD|
-+ END_CMD_RES|PRG_DONE|DATA_TRAN_DONE,
-+ host->base + MMC_I_MASK);
-+
-+ free_irq(host->irq, host);
-+ pxa_free_dma(host->dma);
-+ iounmap(host->base);
-+ dma_free_coherent(dev, PAGE_SIZE, host->sg_cpu, host->sg_dma);
-+
-+ release_resource(host->res);
-+
-+ kfree(host);
-+ }
-+ return 0;
-+}
-+
-+static int pxamci_suspend(struct device *dev, u32 state, u32 level)
-+{
-+ struct pxamci_host *host = dev_get_drvdata(dev);
-+ int ret = 0;
-+
-+ if (host && level == SUSPEND_DISABLE)
-+ ret = mmc_suspend_host(&host->mmc, state);
-+ return ret;
-+}
-+
-+static int pxamci_resume(struct device *dev, u32 level)
-+{
-+ struct pxamci_host *host = dev_get_drvdata(dev);
-+ int ret = 0;
-+
-+ if (host && level == RESUME_ENABLE)
-+ ret = mmc_resume_host(&host->mmc);
-+ return ret;
-+}
-+
-+static struct device_driver pxamci_driver = {
-+ .name = "pxamci",
-+ .bus = &platform_bus_type,
-+ .probe = pxamci_probe,
-+ .remove = pxamci_remove,
-+ .suspend = pxamci_suspend,
-+ .resume = pxamci_resume,
-+};
-+
-+static int __init pxamci_init(void)
-+{
-+ return driver_register(&pxamci_driver);
-+}
-+
-+static void __exit pxamci_exit(void)
-+{
-+ driver_unregister(&pxamci_driver);
-+}
-+
-+module_init(pxamci_init);
-+module_exit(pxamci_exit);
-+
-+MODULE_DESCRIPTION("PXA Multimedia Card Interface Driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/media/mmc/mmc.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,15 @@
-+/*
-+ * linux/drivers/media/mmc/mmc.h
-+ *
-+ * Copyright (C) 2003 Russell King, 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 version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#ifndef _MMC_H
-+/* core-internal functions */
-+void mmc_init_card(struct mmc_card *card, struct mmc_host *host);
-+int mmc_register_card(struct mmc_card *card);
-+void mmc_remove_card(struct mmc_card *card);
-+#endif
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/media/mmc/mmc_sysfs.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,231 @@
-+/*
-+ * linux/drivers/media/mmc/mmc_sysfs.c
-+ *
-+ * Copyright (C) 2003 Russell King, 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 version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * MMC sysfs/driver model support.
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/device.h>
-+
-+#include <linux/mmc/card.h>
-+#include <linux/mmc/host.h>
-+
-+#include "mmc.h"
-+
-+#define dev_to_mmc_card(d) container_of(d, struct mmc_card, dev)
-+#define to_mmc_driver(d) container_of(d, struct mmc_driver, drv)
-+
-+static void mmc_release_card(struct device *dev)
-+{
-+ struct mmc_card *card = dev_to_mmc_card(dev);
-+
-+ kfree(card);
-+}
-+
-+/*
-+ * This currently matches any MMC driver to any MMC card - drivers
-+ * themselves make the decision whether to drive this card in their
-+ * probe method.
-+ */
-+static int mmc_bus_match(struct device *dev, struct device_driver *drv)
-+{
-+ return 1;
-+}
-+
-+static int
-+mmc_bus_hotplug(struct device *dev, char **envp, int num_envp, char *buf,
-+ int buf_size)
-+{
-+ struct mmc_card *card = dev_to_mmc_card(dev);
-+ char ccc[13];
-+ int i = 0;
-+
-+#define add_env(fmt,val) \
-+ ({ \
-+ int len, ret = -ENOMEM; \
-+ if (i < num_envp) { \
-+ envp[i++] = buf; \
-+ len = snprintf(buf, buf_size, fmt, val) + 1; \
-+ buf_size -= len; \
-+ buf += len; \
-+ if (buf_size >= 0) \
-+ ret = 0; \
-+ } \
-+ ret; \
-+ })
-+
-+ for (i = 0; i < 12; i++)
-+ ccc[i] = card->csd.cmdclass & (1 << i) ? '1' : '0';
-+ ccc[12] = '\0';
-+
-+ i = 0;
-+ add_env("MMC_CCC=%s", ccc);
-+ add_env("MMC_MANFID=%03x", card->cid.manfid);
-+ add_env("MMC_SLOT_NAME=%s", card->dev.bus_id);
-+
-+ return 0;
-+}
-+
-+static int mmc_bus_suspend(struct device *dev, u32 state)
-+{
-+ struct mmc_driver *drv = to_mmc_driver(dev->driver);
-+ struct mmc_card *card = dev_to_mmc_card(dev);
-+ int ret = 0;
-+
-+ if (dev->driver && drv->suspend)
-+ ret = drv->suspend(card, state);
-+ return ret;
-+}
-+
-+static int mmc_bus_resume(struct device *dev)
-+{
-+ struct mmc_driver *drv = to_mmc_driver(dev->driver);
-+ struct mmc_card *card = dev_to_mmc_card(dev);
-+ int ret = 0;
-+
-+ if (dev->driver && drv->resume)
-+ ret = drv->resume(card);
-+ return ret;
-+}
-+
-+static struct bus_type mmc_bus_type = {
-+ .name = "mmc",
-+ .match = mmc_bus_match,
-+ .hotplug = mmc_bus_hotplug,
-+ .suspend = mmc_bus_suspend,
-+ .resume = mmc_bus_resume,
-+};
-+
-+
-+static int mmc_drv_probe(struct device *dev)
-+{
-+ struct mmc_driver *drv = to_mmc_driver(dev->driver);
-+ struct mmc_card *card = dev_to_mmc_card(dev);
-+
-+ return drv->probe(card);
-+}
-+
-+static int mmc_drv_remove(struct device *dev)
-+{
-+ struct mmc_driver *drv = to_mmc_driver(dev->driver);
-+ struct mmc_card *card = dev_to_mmc_card(dev);
-+
-+ drv->remove(card);
-+
-+ return 0;
-+}
-+
-+
-+/**
-+ * mmc_register_driver - register a media driver
-+ * @drv: MMC media driver
-+ */
-+int mmc_register_driver(struct mmc_driver *drv)
-+{
-+ drv->drv.bus = &mmc_bus_type;
-+ drv->drv.probe = mmc_drv_probe;
-+ drv->drv.remove = mmc_drv_remove;
-+ return driver_register(&drv->drv);
-+}
-+
-+EXPORT_SYMBOL(mmc_register_driver);
-+
-+/**
-+ * mmc_unregister_driver - unregister a media driver
-+ * @drv: MMC media driver
-+ */
-+void mmc_unregister_driver(struct mmc_driver *drv)
-+{
-+ drv->drv.bus = &mmc_bus_type;
-+ driver_unregister(&drv->drv);
-+}
-+
-+EXPORT_SYMBOL(mmc_unregister_driver);
-+
-+
-+#define MMC_ATTR(name, fmt, args...) \
-+static ssize_t mmc_dev_show_##name (struct device *dev, char *buf) \
-+{ \
-+ struct mmc_card *card = dev_to_mmc_card(dev); \
-+ return sprintf(buf, fmt, args); \
-+} \
-+static DEVICE_ATTR(name, S_IRUGO, mmc_dev_show_##name, NULL)
-+
-+MMC_ATTR(date, "%02d/%04d\n", card->cid.month, 1997 + card->cid.year);
-+MMC_ATTR(fwrev, "0x%x\n", card->cid.fwrev);
-+MMC_ATTR(hwrev, "0x%x\n", card->cid.hwrev);
-+MMC_ATTR(manfid, "0x%03x\n", card->cid.manfid);
-+MMC_ATTR(serial, "0x%06x\n", card->cid.serial);
-+MMC_ATTR(name, "%s\n", card->cid.prod_name);
-+
-+static struct device_attribute *mmc_dev_attributes[] = {
-+ &dev_attr_date,
-+ &dev_attr_fwrev,
-+ &dev_attr_hwrev,
-+ &dev_attr_manfid,
-+ &dev_attr_serial,
-+ &dev_attr_name,
-+};
-+
-+/*
-+ * Internal function. Initialise a MMC card structure.
-+ */
-+void mmc_init_card(struct mmc_card *card, struct mmc_host *host)
-+{
-+ memset(card, 0, sizeof(struct mmc_card));
-+ card->host = host;
-+ device_initialize(&card->dev);
-+ card->dev.parent = card->host->dev;
-+ card->dev.bus = &mmc_bus_type;
-+ card->dev.release = mmc_release_card;
-+}
-+
-+/*
-+ * Internal function. Register a new MMC card with the driver model.
-+ */
-+int mmc_register_card(struct mmc_card *card)
-+{
-+ int ret, i;
-+
-+ snprintf(card->dev.bus_id, sizeof(card->dev.bus_id),
-+ "mmc%02x:%04x", card->host->host_num, card->rca);
-+
-+ ret = device_add(&card->dev);
-+ if (ret == 0)
-+ for (i = 0; i < ARRAY_SIZE(mmc_dev_attributes); i++)
-+ device_create_file(&card->dev, mmc_dev_attributes[i]);
-+
-+ return ret;
-+}
-+
-+/*
-+ * Internal function. Unregister a new MMC card with the
-+ * driver model, and (eventually) free it.
-+ */
-+void mmc_remove_card(struct mmc_card *card)
-+{
-+ if (mmc_card_present(card))
-+ device_del(&card->dev);
-+
-+ put_device(&card->dev);
-+}
-+
-+
-+static int __init mmc_init(void)
-+{
-+ return bus_register(&mmc_bus_type);
-+}
-+
-+static void __exit mmc_exit(void)
-+{
-+ bus_unregister(&mmc_bus_type);
-+}
-+
-+module_init(mmc_init);
-+module_exit(mmc_exit);
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/media/mmc/mmci.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,445 @@
-+/*
-+ * linux/drivers/media/mmc/mmci.c - ARM PrimeCell MMCI PL180/1 driver
-+ *
-+ * Copyright (C) 2003 Deep Blue Solutions, 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 version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/moduleparam.h>
-+#include <linux/init.h>
-+#include <linux/ioport.h>
-+#include <linux/device.h>
-+#include <linux/interrupt.h>
-+#include <linux/blkdev.h>
-+#include <linux/delay.h>
-+#include <linux/mmc/host.h>
-+#include <linux/mmc/protocol.h>
-+
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/hardware/amba.h>
-+
-+#include "mmci.h"
-+
-+#define DRIVER_NAME "mmci-pl18x"
-+
-+#ifdef CONFIG_MMC_DEBUG
-+#define DBG(x...) printk(KERN_DEBUG x)
-+#else
-+#define DBG(x...) do { } while (0)
-+#endif
-+
-+static int fmax = 515633;
-+
-+static void
-+mmci_request_end(struct mmci_host *host, struct mmc_request *req)
-+{
-+ writel(0, host->base + MMCICOMMAND);
-+ host->req = NULL;
-+ host->cmd = NULL;
-+ host->data = NULL;
-+
-+ if (req->data)
-+ req->data->bytes_xfered = host->data_xfered;
-+
-+ mmc_request_done(&host->mmc, req);
-+}
-+
-+static void mmci_start_data(struct mmci_host *host, struct mmc_data *data)
-+{
-+ unsigned int datactrl;
-+
-+ DBG("MMCI: data: blksz %04x blks %04x flags %08x\n",
-+ 1 << data->blksz_bits, data->blocks, data->flags);
-+
-+ datactrl = MCI_DPSM_ENABLE | data->blksz_bits << 4;
-+
-+ if (data->flags & MMC_DATA_READ)
-+ datactrl |= MCI_DPSM_DIRECTION;
-+
-+ host->data = data;
-+ host->buffer = data->rq->buffer;
-+ host->size = data->blocks << data->blksz_bits;
-+ host->data_xfered = 0;
-+
-+ writel(0x800000, host->base + MMCIDATATIMER);
-+ writel(host->size, host->base + MMCIDATALENGTH);
-+ writel(datactrl, host->base + MMCIDATACTRL);
-+}
-+
-+static void
-+mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c)
-+{
-+ DBG("MMCI: cmd: op %02x arg %08x flags %08x\n",
-+ cmd->opcode, cmd->arg, cmd->flags);
-+
-+ if (readl(host->base + MMCICOMMAND) & MCI_CPSM_ENABLE) {
-+ writel(0, host->base + MMCICOMMAND);
-+ udelay(1);
-+ }
-+
-+ c |= cmd->opcode | MCI_CPSM_ENABLE;
-+ switch (cmd->flags & MMC_RSP_MASK) {
-+ case MMC_RSP_NONE:
-+ default:
-+ break;
-+ case MMC_RSP_LONG:
-+ c |= MCI_CPSM_LONGRSP;
-+ case MMC_RSP_SHORT:
-+ c |= MCI_CPSM_RESPONSE;
-+ break;
-+ }
-+ if (/*interrupt*/0)
-+ c |= MCI_CPSM_INTERRUPT;
-+
-+ host->cmd = cmd;
-+
-+ writel(cmd->arg, host->base + MMCIARGUMENT);
-+ writel(c, host->base + MMCICOMMAND);
-+}
-+
-+static void
-+mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
-+ unsigned int status)
-+{
-+ if (status & MCI_DATABLOCKEND) {
-+ host->data_xfered += 1 << data->blksz_bits;
-+ }
-+ if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|MCI_RXOVERRUN)) {
-+ if (status & MCI_DATACRCFAIL)
-+ data->error = MMC_ERR_BADCRC;
-+ else if (status & MCI_DATATIMEOUT)
-+ data->error = MMC_ERR_TIMEOUT;
-+ else if (status & (MCI_TXUNDERRUN|MCI_RXOVERRUN))
-+ data->error = MMC_ERR_FIFO;
-+ status |= MCI_DATAEND;
-+ }
-+ if (status & MCI_DATAEND) {
-+ host->data = NULL;
-+ if (!data->stop) {
-+ mmci_request_end(host, data->req);
-+ } else /*if (readl(host->base + MMCIDATACNT) > 6)*/ {
-+ mmci_start_command(host, data->stop, 0);
-+ }
-+ }
-+}
-+
-+static void
-+mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
-+ unsigned int status)
-+{
-+ host->cmd = NULL;
-+
-+ cmd->resp[0] = readl(host->base + MMCIRESPONSE0);
-+ cmd->resp[1] = readl(host->base + MMCIRESPONSE1);
-+ cmd->resp[2] = readl(host->base + MMCIRESPONSE2);
-+ cmd->resp[3] = readl(host->base + MMCIRESPONSE3);
-+
-+ if (status & MCI_CMDTIMEOUT) {
-+ cmd->error = MMC_ERR_TIMEOUT;
-+ } else if (status & MCI_CMDCRCFAIL && cmd->flags & MMC_RSP_CRC) {
-+ cmd->error = MMC_ERR_BADCRC;
-+ }
-+
-+ if (!cmd->data || cmd->error != MMC_ERR_NONE) {
-+ mmci_request_end(host, cmd->req);
-+ } else if (!(cmd->data->flags & MMC_DATA_READ)) {
-+ mmci_start_data(host, cmd->data);
-+ }
-+}
-+
-+static irqreturn_t mmci_irq(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct mmci_host *host = dev_id;
-+ u32 status;
-+ int ret = 0;
-+
-+ do {
-+ struct mmc_command *cmd;
-+ struct mmc_data *data;
-+
-+ status = readl(host->base + MMCISTATUS);
-+ writel(status, host->base + MMCICLEAR);
-+
-+ if (!(status & MCI_IRQMASK))
-+ break;
-+
-+ DBG("MMCI: irq %08x\n", status);
-+
-+ if (status & (MCI_RXDATAAVLBL|MCI_RXFIFOHALFFULL)) {
-+ int count = host->size - (readl(host->base + MMCIFIFOCNT) << 2);
-+ if (count < 0)
-+ count = 0;
-+ if (count && host->buffer) {
-+ readsl(host->base + MMCIFIFO, host->buffer, count >> 2);
-+ host->buffer += count;
-+ host->size -= count;
-+ if (host->size == 0)
-+ host->buffer = NULL;
-+ } else {
-+ static int first = 1;
-+ if (first) {
-+ first = 0;
-+ printk(KERN_ERR "MMCI: sinking excessive data\n");
-+ }
-+ readl(host->base + MMCIFIFO);
-+ }
-+ }
-+ if (status & (MCI_TXFIFOEMPTY|MCI_TXFIFOHALFEMPTY)) {
-+ int count = host->size;
-+ if (count > MCI_FIFOHALFSIZE)
-+ count = MCI_FIFOHALFSIZE;
-+ if (count && host->buffer) {
-+ writesl(host->base + MMCIFIFO, host->buffer, count >> 2);
-+ host->buffer += count;
-+ host->size -= count;
-+ if (host->size == 0)
-+ host->buffer = NULL;
-+ } else {
-+ static int first = 1;
-+ if (first) {
-+ first = 0;
-+ printk(KERN_ERR "MMCI: ran out of source data\n");
-+ }
-+ }
-+ }
-+
-+ data = host->data;
-+ if (status & (MCI_DATACRCFAIL|MCI_DATATIMEOUT|MCI_TXUNDERRUN|
-+ MCI_RXOVERRUN|MCI_DATAEND|MCI_DATABLOCKEND))
-+ mmci_data_irq(host, data, status);
-+
-+ cmd = host->cmd;
-+ if (status & (MCI_CMDCRCFAIL|MCI_CMDTIMEOUT|MCI_CMDSENT|MCI_CMDRESPEND) && cmd)
-+ mmci_cmd_irq(host, cmd, status);
-+
-+ ret = 1;
-+ } while (status);
-+
-+ return IRQ_RETVAL(ret);
-+}
-+
-+static void mmci_request(struct mmc_host *mmc, struct mmc_request *req)
-+{
-+ struct mmci_host *host = to_mmci_host(mmc);
-+
-+ WARN_ON(host->req != NULL);
-+
-+ host->req = req;
-+
-+ if (req->data && req->data->flags & MMC_DATA_READ)
-+ mmci_start_data(host, req->data);
-+
-+ mmci_start_command(host, req->cmd, 0);
-+}
-+
-+static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
-+{
-+ struct mmci_host *host = to_mmci_host(mmc);
-+ u32 clk = 0, pwr = 0;
-+
-+ DBG("MMCI: set_ios: clock %dHz busmode %d powermode %d Vdd %d.%02d\n",
-+ ios->clock, ios->bus_mode, ios->power_mode,
-+ ios->vdd / 100, ios->vdd % 100);
-+
-+ if (ios->clock) {
-+ clk = host->mclk / (2 * ios->clock) - 1;
-+ if (clk > 256)
-+ clk = 255;
-+ clk |= MCI_CLK_ENABLE;
-+ }
-+
-+ switch (ios->power_mode) {
-+ case MMC_POWER_OFF:
-+ break;
-+ case MMC_POWER_UP:
-+ pwr |= MCI_PWR_UP;
-+ break;
-+ case MMC_POWER_ON:
-+ pwr |= MCI_PWR_ON;
-+ break;
-+ }
-+
-+ if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)
-+ pwr |= MCI_ROD;
-+
-+ writel(clk, host->base + MMCICLOCK);
-+
-+ if (host->pwr != pwr) {
-+ host->pwr = pwr;
-+ writel(pwr, host->base + MMCIPOWER);
-+ }
-+}
-+
-+static struct mmc_host_ops mmci_ops = {
-+ .request = mmci_request,
-+ .set_ios = mmci_set_ios,
-+};
-+
-+static int mmci_probe(struct amba_device *dev, void *id)
-+{
-+ struct mmci_host *host;
-+ int ret;
-+// void *tmp;
-+
-+ /* enable the interrupt via the VIC */
-+// tmp = ioremap(0xc3000000, SZ_4K);
-+// if (tmp) {
-+// u32 val = readl(tmp + 0x10);
-+// writel(val | 0x180, tmp + 0x10);
-+// iounmap(tmp);
-+// }
-+
-+ if (!request_mem_region(dev->res.start, SZ_4K, DRIVER_NAME))
-+ return -EBUSY;
-+
-+ host = kmalloc(sizeof(struct mmci_host), GFP_KERNEL);
-+ if (!host) {
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+
-+ memset(host, 0, sizeof(struct mmci_host));
-+
-+ ret = mmc_init_host(&host->mmc);
-+ if (ret)
-+ goto out;
-+
-+ host->base = ioremap(dev->res.start, SZ_4K);
-+ if (!host->base) {
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+
-+ host->irq = dev->irq;
-+ host->mclk = 33000000; /* impd1 */
-+ host->mmc.dev = &dev->dev;
-+ host->mmc.ops = &mmci_ops;
-+ host->mmc.f_min = (host->mclk + 511) / 512;
-+ host->mmc.f_max = host->mclk / 2;
-+ if (host->mmc.f_max > fmax)
-+ host->mmc.f_max = fmax;
-+
-+ host->mmc.ocr_avail = MMC_VDD_35_36;
-+
-+ writel(0, host->base + MMCIMASK0);
-+ writel(0, host->base + MMCIMASK1);
-+ writel(0xfff, host->base + MMCICLEAR);
-+
-+ ret = request_irq(host->irq, mmci_irq, SA_SHIRQ, DRIVER_NAME, host);
-+ if (ret)
-+ goto out;
-+
-+ writel(MCI_IRQENABLE, host->base + MMCIMASK0);
-+
-+ amba_set_drvdata(dev, host);
-+
-+ mmc_add_host(&host->mmc);
-+
-+ return 0;
-+
-+ out:
-+ if (host) {
-+ if (host->base)
-+ iounmap(host->base);
-+ kfree(host);
-+ }
-+ release_mem_region(dev->res.start, SZ_4K);
-+ return ret;
-+}
-+
-+static int mmci_remove(struct amba_device *dev)
-+{
-+ struct mmci_host *host = amba_get_drvdata(dev);
-+
-+ amba_set_drvdata(dev, NULL);
-+
-+ if (host) {
-+ mmc_remove_host(&host->mmc);
-+
-+ writel(0, host->base + MMCIMASK0);
-+ writel(0, host->base + MMCIMASK1);
-+
-+ writel(0, host->base + MMCICOMMAND);
-+ writel(0, host->base + MMCIDATACTRL);
-+
-+ free_irq(host->irq, host);
-+
-+ iounmap(host->base);
-+
-+ kfree(host);
-+
-+ release_mem_region(dev->res.start, SZ_4K);
-+ }
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM
-+static int mmci_suspend(struct amba_device *dev, u32 state)
-+{
-+ struct mmci_host *host = amba_get_drvdata(dev);
-+
-+ return host ? mmc_suspend_host(&host->mmc, state) : 0;
-+}
-+
-+static int mmci_resume(struct amba_device *dev)
-+{
-+ struct mmci_host *host = amba_get_drvdata(dev);
-+ int ret = 0;
-+
-+ if (host) {
-+ writel(MCI_IRQENABLE, host->base + MMCIMASK0);
-+ ret = mmc_resume_host(&host->mmc);
-+ }
-+
-+ return ret;
-+}
-+#else
-+#define mmci_suspend NULL
-+#define mmci_resume NULL
-+#endif
-+
-+static struct amba_id mmci_ids[] = {
-+ {
-+ .id = 0x00041180,
-+ .mask = 0x000fffff,
-+ },
-+ {
-+ .id = 0x00041181,
-+ .mask = 0x000fffff,
-+ },
-+ { 0, 0 },
-+};
-+
-+static struct amba_driver mmci_driver = {
-+ .drv = {
-+ .name = DRIVER_NAME,
-+ },
-+ .probe = mmci_probe,
-+ .remove = mmci_remove,
-+ .suspend = mmci_suspend,
-+ .resume = mmci_resume,
-+ .id_table = mmci_ids,
-+};
-+
-+static int __init mmci_init(void)
-+{
-+ return amba_driver_register(&mmci_driver);
-+}
-+
-+static void __exit mmci_exit(void)
-+{
-+ amba_driver_unregister(&mmci_driver);
-+}
-+
-+module_init(mmci_init);
-+module_exit(mmci_exit);
-+module_param(fmax, int, 0444);
-+
-+MODULE_DESCRIPTION("ARM PrimeCell PL180/181 Multimedia Card Interface driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/media/mmc/mmc_queue.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,29 @@
-+#ifndef MMC_QUEUE_H
-+#define MMC_QUEUE_H
-+
-+struct request;
-+struct task_struct;
-+
-+struct mmc_queue {
-+ struct mmc_card *card;
-+ struct completion thread_complete;
-+ wait_queue_head_t thread_wq;
-+ struct task_struct *thread;
-+ struct request *req;
-+ int (*prep_fn)(struct mmc_queue *, struct request *);
-+ int (*issue_fn)(struct mmc_queue *, struct request *);
-+ void *data;
-+ struct request_queue *queue;
-+};
-+
-+struct mmc_io_request {
-+ struct request *rq;
-+ int num;
-+ struct mmc_command selcmd; /* mmc_queue private */
-+ struct mmc_command cmd[4]; /* max 4 commands */
-+};
-+
-+extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *);
-+extern void mmc_cleanup_queue(struct mmc_queue *);
-+
-+#endif
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/media/mmc/mmc_block.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,482 @@
-+/*
-+ * Block driver for media (i.e., flash cards)
-+ *
-+ * Copyright 2002 Hewlett-Packard Company
-+ *
-+ * Use consistent with the GNU GPL is permitted,
-+ * provided that this copyright notice is
-+ * preserved in its entirety in all copies and derived works.
-+ *
-+ * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
-+ * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
-+ * FITNESS FOR ANY PARTICULAR PURPOSE.
-+ *
-+ * Many thanks to Alessandro Rubini and Jonathan Corbet!
-+ *
-+ * Author: Andrew Christian
-+ * 28 May 2002
-+ */
-+#include <linux/moduleparam.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+
-+#include <linux/sched.h>
-+#include <linux/kernel.h> /* printk() */
-+#include <linux/fs.h> /* everything... */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/hdreg.h> /* HDIO_GETGEO */
-+#include <linux/kdev_t.h>
-+#include <linux/blkdev.h>
-+#include <linux/devfs_fs_kernel.h>
-+
-+#include <linux/mmc/card.h>
-+#include <linux/mmc/protocol.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include "mmc_queue.h"
-+
-+#define MMC_SHIFT 3 /* max 8 partitions per card */
-+
-+static int mmc_major;
-+static int maxsectors = 8;
-+
-+/*
-+ * There is one mmc_blk_data per slot.
-+ */
-+struct mmc_blk_data {
-+ spinlock_t lock;
-+ struct gendisk *disk;
-+ struct mmc_queue queue;
-+
-+ unsigned int usage;
-+ unsigned int block_bits;
-+ unsigned int suspended;
-+};
-+
-+static DECLARE_MUTEX(open_lock);
-+
-+static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
-+{
-+ struct mmc_blk_data *md;
-+
-+ down(&open_lock);
-+ md = disk->private_data;
-+ if (md && md->usage == 0)
-+ md = NULL;
-+ if (md)
-+ md->usage++;
-+ up(&open_lock);
-+
-+ return md;
-+}
-+
-+static void mmc_blk_put(struct mmc_blk_data *md)
-+{
-+ down(&open_lock);
-+ md->usage--;
-+ if (md->usage == 0) {
-+ put_disk(md->disk);
-+ mmc_cleanup_queue(&md->queue);
-+ kfree(md);
-+ }
-+ up(&open_lock);
-+}
-+
-+static int mmc_blk_open(struct inode *inode, struct file *filp)
-+{
-+ struct mmc_blk_data *md;
-+ int ret = -ENXIO;
-+
-+ md = mmc_blk_get(inode->i_bdev->bd_disk);
-+ if (md) {
-+ if (md->usage == 2)
-+ check_disk_change(inode->i_bdev);
-+ ret = 0;
-+ }
-+
-+ return ret;
-+}
-+
-+static int mmc_blk_release(struct inode *inode, struct file *filp)
-+{
-+ struct mmc_blk_data *md = inode->i_bdev->bd_disk->private_data;
-+
-+ mmc_blk_put(md);
-+ return 0;
-+}
-+
-+static int
-+mmc_blk_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
-+{
-+ struct block_device *bdev = inode->i_bdev;
-+
-+ if (cmd == HDIO_GETGEO) {
-+ struct hd_geometry geo;
-+
-+ memset(&geo, 0, sizeof(struct hd_geometry));
-+
-+ geo.cylinders = get_capacity(bdev->bd_disk) / (4 * 16);
-+ geo.heads = 4;
-+ geo.sectors = 16;
-+ geo.start = get_start_sect(bdev);
-+
-+ return copy_to_user((void *)arg, &geo, sizeof(geo))
-+ ? -EFAULT : 0;
-+ }
-+
-+ return -ENOTTY;
-+}
-+
-+static struct block_device_operations mmc_bdops = {
-+ .open = mmc_blk_open,
-+ .release = mmc_blk_release,
-+ .ioctl = mmc_blk_ioctl,
-+ .owner = THIS_MODULE,
-+};
-+
-+struct mmc_blk_request {
-+ struct mmc_request req;
-+ struct mmc_command cmd;
-+ struct mmc_command stop;
-+ struct mmc_data data;
-+};
-+
-+static int mmc_blk_prep_rq(struct mmc_queue *mq, struct request *req)
-+{
-+ struct mmc_blk_data *md = mq->data;
-+
-+ /*
-+ * If we have no device, we haven't finished initialising.
-+ */
-+ if (!md || !mq->card) {
-+ printk("killing request - no device/host\n");
-+ goto kill;
-+ }
-+
-+ if (md->suspended) {
-+ blk_plug_device(md->queue.queue);
-+ goto defer;
-+ }
-+
-+ /*
-+ * Check for excessive requests.
-+ */
-+ if (req->sector + req->nr_sectors > get_capacity(req->rq_disk)) {
-+ printk("bad request size\n");
-+ goto kill;
-+ }
-+
-+ return BLKPREP_OK;
-+
-+ defer:
-+ return BLKPREP_DEFER;
-+ kill:
-+ return BLKPREP_KILL;
-+}
-+
-+static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
-+{
-+ struct mmc_blk_data *md = mq->data;
-+ struct mmc_card *card = md->queue.card;
-+ int err, sz = 0;
-+
-+ err = mmc_card_claim_host(card);
-+ if (err)
-+ goto cmd_err;
-+
-+ do {
-+ struct mmc_blk_request rq;
-+ struct mmc_command cmd;
-+
-+ memset(&rq, 0, sizeof(struct mmc_blk_request));
-+ rq.req.cmd = &rq.cmd;
-+ rq.req.data = &rq.data;
-+
-+ rq.cmd.arg = req->sector << 9;
-+ rq.cmd.flags = MMC_RSP_SHORT | MMC_RSP_CRC;
-+ rq.data.rq = req;
-+ rq.data.timeout_ns = card->csd.tacc_ns * 10;
-+ rq.data.timeout_clks = card->csd.tacc_clks * 10;
-+ rq.data.blksz_bits = md->block_bits;
-+ rq.data.blocks = req->current_nr_sectors >> (md->block_bits - 9);
-+ rq.stop.opcode = MMC_STOP_TRANSMISSION;
-+ rq.stop.arg = 0;
-+ rq.stop.flags = MMC_RSP_SHORT | MMC_RSP_CRC | MMC_RSP_BUSY;
-+
-+ if (rq_data_dir(req) == READ) {
-+ rq.cmd.opcode = rq.data.blocks > 1 ? MMC_READ_MULTIPLE_BLOCK : MMC_READ_SINGLE_BLOCK;
-+ rq.data.flags |= MMC_DATA_READ;
-+ } else {
-+ rq.cmd.opcode = MMC_WRITE_BLOCK;
-+ rq.cmd.flags |= MMC_RSP_BUSY;
-+ rq.data.flags |= MMC_DATA_WRITE;
-+ rq.data.blocks = 1;
-+ }
-+ rq.req.stop = rq.data.blocks > 1 ? &rq.stop : NULL;
-+
-+ mmc_wait_for_req(card->host, &rq.req);
-+ if (rq.cmd.error) {
-+ err = rq.cmd.error;
-+ printk("error %d sending read/write command\n", err);
-+ goto cmd_err;
-+ }
-+
-+ if (rq_data_dir(req) == READ) {
-+ sz = rq.data.bytes_xfered;
-+ } else {
-+ sz = 0;
-+ }
-+
-+ if (rq.data.error) {
-+ err = rq.data.error;
-+ printk("error %d transferring data\n", err);
-+ goto cmd_err;
-+ }
-+
-+ if (rq.stop.error) {
-+ err = rq.stop.error;
-+ printk("error %d sending stop command\n", err);
-+ goto cmd_err;
-+ }
-+
-+ do {
-+ cmd.opcode = MMC_SEND_STATUS;
-+ cmd.arg = card->rca << 16;
-+ cmd.flags = MMC_RSP_SHORT | MMC_RSP_CRC;
-+ err = mmc_wait_for_cmd(card->host, &cmd, 5);
-+ if (err) {
-+ printk("error %d requesting status\n", err);
-+ goto cmd_err;
-+ }
-+ } while (!(cmd.resp[0] & R1_READY_FOR_DATA));
-+
-+#if 0
-+ if (cmd.resp[0] & ~0x00000900)
-+ printk("status = %08x\n", cmd.resp[0]);
-+ err = mmc_decode_status(cmd.resp);
-+ if (err)
-+ goto cmd_err;
-+#endif
-+
-+ sz = rq.data.bytes_xfered;
-+ } while (end_that_request_chunk(req, 1, sz));
-+
-+ mmc_card_release_host(card);
-+
-+ return 1;
-+
-+ cmd_err:
-+ mmc_card_release_host(card);
-+
-+ end_that_request_chunk(req, 1, sz);
-+ req->errors = err;
-+
-+ return 0;
-+}
-+
-+#define MMC_NUM_MINORS (256 >> MMC_SHIFT)
-+
-+static unsigned long dev_use[MMC_NUM_MINORS/(8*sizeof(unsigned long))];
-+
-+static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
-+{
-+ struct mmc_blk_data *md;
-+ int devidx;
-+
-+ devidx = find_first_zero_bit(dev_use, MMC_NUM_MINORS);
-+ if (devidx >= MMC_NUM_MINORS)
-+ return NULL;
-+ __set_bit(devidx, dev_use);
-+
-+ md = kmalloc(sizeof(struct mmc_blk_data), GFP_KERNEL);
-+ if (md) {
-+ memset(md, 0, sizeof(struct mmc_blk_data));
-+
-+ md->disk = alloc_disk(1 << MMC_SHIFT);
-+ if (md->disk == NULL) {
-+ kfree(md);
-+ md = NULL;
-+ goto out;
-+ }
-+
-+ spin_lock_init(&md->lock);
-+ md->usage = 1;
-+
-+ mmc_init_queue(&md->queue, card, &md->lock);
-+ md->queue.prep_fn = mmc_blk_prep_rq;
-+ md->queue.issue_fn = mmc_blk_issue_rq;
-+ md->queue.data = md;
-+
-+ md->disk->major = mmc_major;
-+ md->disk->first_minor = devidx << MMC_SHIFT;
-+ md->disk->fops = &mmc_bdops;
-+ md->disk->private_data = md;
-+ md->disk->queue = md->queue.queue;
-+ md->disk->driverfs_dev = &card->dev;
-+
-+ sprintf(md->disk->disk_name, "mmcblk%d", devidx);
-+ sprintf(md->disk->devfs_name, "mmc/blk%d", devidx);
-+
-+ md->block_bits = md->queue.card->csd.read_blkbits;
-+
-+ blk_queue_max_sectors(md->queue.queue, maxsectors);
-+ blk_queue_hardsect_size(md->queue.queue, 1 << md->block_bits);
-+ set_capacity(md->disk, md->queue.card->csd.capacity);
-+ }
-+ out:
-+ return md;
-+}
-+
-+static int
-+mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
-+{
-+ struct mmc_command cmd;
-+ int err;
-+
-+ mmc_card_claim_host(card);
-+ cmd.opcode = MMC_SET_BLOCKLEN;
-+ cmd.arg = 1 << card->csd.read_blkbits;
-+ cmd.flags = MMC_RSP_SHORT | MMC_RSP_CRC;
-+ err = mmc_wait_for_cmd(card->host, &cmd, 5);
-+ mmc_card_release_host(card);
-+
-+ if (err) {
-+ printk(KERN_ERR "%s: unable to set block size to %d: %d\n",
-+ md->disk->disk_name, cmd.arg, err);
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static int mmc_blk_probe(struct mmc_card *card)
-+{
-+ struct mmc_blk_data *md;
-+ int err;
-+
-+ if (card->csd.cmdclass & ~0x1ff)
-+ return -ENODEV;
-+
-+ if (card->csd.read_blkbits < 9) {
-+ printk(KERN_WARNING "%s: read blocksize too small (%u)\n",
-+ mmc_card_id(card), 1 << card->csd.read_blkbits);
-+ return -ENODEV;
-+ }
-+
-+ md = mmc_blk_alloc(card);
-+ if (md == NULL)
-+ return -ENOMEM;
-+
-+ err = mmc_blk_set_blksize(md, card);
-+ if (err)
-+ goto out;
-+
-+ printk(KERN_INFO "%s: %s %s %dKiB\n",
-+ md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
-+ (card->csd.capacity << card->csd.read_blkbits) / 1024);
-+
-+ mmc_set_drvdata(card, md);
-+ add_disk(md->disk);
-+ return 0;
-+
-+ out:
-+ mmc_blk_put(md);
-+
-+ return err;
-+}
-+
-+static void mmc_blk_remove(struct mmc_card *card)
-+{
-+ struct mmc_blk_data *md = mmc_get_drvdata(card);
-+
-+ if (md) {
-+ int devidx;
-+
-+ del_gendisk(md->disk);
-+
-+ /*
-+ * I think this is needed.
-+ */
-+ md->disk->queue = NULL;
-+
-+ devidx = md->disk->first_minor >> MMC_SHIFT;
-+ __clear_bit(devidx, dev_use);
-+
-+ mmc_blk_put(md);
-+ }
-+ mmc_set_drvdata(card, NULL);
-+}
-+
-+#ifdef CONFIG_PM
-+static int mmc_blk_suspend(struct mmc_card *card, u32 state)
-+{
-+ struct mmc_blk_data *md = mmc_get_drvdata(card);
-+
-+ if (md) {
-+ blk_stop_queue(md->queue.queue);
-+ }
-+ return 0;
-+}
-+
-+static int mmc_blk_resume(struct mmc_card *card)
-+{
-+ struct mmc_blk_data *md = mmc_get_drvdata(card);
-+
-+ if (md) {
-+ mmc_blk_set_blksize(md, md->queue.card);
-+ blk_start_queue(md->queue.queue);
-+ }
-+ return 0;
-+}
-+#else
-+#define mmc_blk_suspend NULL
-+#define mmc_blk_resume NULL
-+#endif
-+
-+static struct mmc_driver mmc_driver = {
-+ .drv = {
-+ .name = "mmcblk",
-+ },
-+ .probe = mmc_blk_probe,
-+ .remove = mmc_blk_remove,
-+ .suspend = mmc_blk_suspend,
-+ .resume = mmc_blk_resume,
-+};
-+
-+static int __init mmc_blk_init(void)
-+{
-+ int res = -ENOMEM;
-+
-+ res = register_blkdev(mmc_major, "mmc");
-+ if (res < 0) {
-+ printk(KERN_WARNING "Unable to get major %d for MMC media: %d\n",
-+ mmc_major, res);
-+ goto out;
-+ }
-+ if (mmc_major == 0)
-+ mmc_major = res;
-+
-+ devfs_mk_dir("mmc");
-+ return mmc_register_driver(&mmc_driver);
-+
-+ out:
-+ return res;
-+}
-+
-+static void __exit mmc_blk_exit(void)
-+{
-+ mmc_unregister_driver(&mmc_driver);
-+ devfs_remove("mmc");
-+ unregister_blkdev(mmc_major, "mmc");
-+}
-+
-+module_init(mmc_blk_init);
-+module_exit(mmc_blk_exit);
-+module_param(maxsectors, int, 0444);
-+
-+MODULE_PARM_DESC(maxsectors, "Maximum number of sectors for a single request");
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("Multimedia Card (MMC) block device driver");
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/media/mmc/pxamci.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,94 @@
-+#undef MMC_STRPCL
-+#undef MMC_STAT
-+#undef MMC_CLKRT
-+#undef MMC_SPI
-+#undef MMC_CMDAT
-+#undef MMC_RESTO
-+#undef MMC_RDTO
-+#undef MMC_BLKLEN
-+#undef MMC_NOB
-+#undef MMC_PRTBUF
-+#undef MMC_I_MASK
-+#undef END_CMD_RES
-+#undef PRG_DONE
-+#undef DATA_TRAN_DONE
-+#undef MMC_I_REG
-+#undef MMC_CMD
-+#undef MMC_ARGH
-+#undef MMC_ARGL
-+#undef MMC_RES
-+#undef MMC_RXFIFO
-+#undef MMC_TXFIFO
-+
-+#define MMC_STRPCL 0x0000
-+#define STOP_CLOCK (1 << 0)
-+#define START_CLOCK (2 << 0)
-+
-+#define MMC_STAT 0x0004
-+#define STAT_END_CMD_RES (1 << 13)
-+#define STAT_PRG_DONE (1 << 12)
-+#define STAT_DATA_TRAN_DONE (1 << 11)
-+#define STAT_CLK_EN (1 << 8)
-+#define STAT_RECV_FIFO_FULL (1 << 7)
-+#define STAT_XMIT_FIFO_EMPTY (1 << 6)
-+#define STAT_RES_CRC_ERR (1 << 5)
-+#define STAT_SPI_READ_ERROR_TOKEN (1 << 4)
-+#define STAT_CRC_READ_ERROR (1 << 3)
-+#define STAT_CRC_WRITE_ERROR (1 << 2)
-+#define STAT_TIME_OUT_RESPONSE (1 << 1)
-+#define STAT_READ_TIME_OUT (1 << 0)
-+
-+#define MMC_CLKRT 0x0008 /* 3 bit */
-+
-+#define MMC_SPI 0x000c
-+#define SPI_CS_ADDRESS (1 << 3)
-+#define SPI_CS_EN (1 << 2)
-+#define CRC_ON (1 << 1)
-+#define SPI_EN (1 << 0)
-+
-+#define MMC_CMDAT 0x0010
-+#define CMDAT_DMAEN (1 << 7)
-+#define CMDAT_INIT (1 << 6)
-+#define CMDAT_BUSY (1 << 5)
-+#define CMDAT_STREAM (1 << 4) /* 1 = stream */
-+#define CMDAT_WRITE (1 << 3) /* 1 = write */
-+#define CMDAT_DATAEN (1 << 2)
-+#define CMDAT_RESP_NONE (0 << 0)
-+#define CMDAT_RESP_SHORT (1 << 0)
-+#define CMDAT_RESP_R2 (2 << 0)
-+#define CMDAT_RESP_R3 (3 << 0)
-+
-+#define MMC_RESTO 0x0014 /* 7 bit */
-+
-+#define MMC_RDTO 0x0018 /* 16 bit */
-+
-+#define MMC_BLKLEN 0x001c /* 10 bit */
-+
-+#define MMC_NOB 0x0020 /* 16 bit */
-+
-+#define MMC_PRTBUF 0x0024
-+#define BUF_PART_FULL (1 << 0)
-+
-+#define MMC_I_MASK 0x0028
-+#define TXFIFO_WR_REQ (1 << 6)
-+#define RXFIFO_RD_REQ (1 << 5)
-+#define CLK_IS_OFF (1 << 4)
-+#define STOP_CMD (1 << 3)
-+#define END_CMD_RES (1 << 2)
-+#define PRG_DONE (1 << 1)
-+#define DATA_TRAN_DONE (1 << 0)
-+
-+#define MMC_I_REG 0x002c
-+/* same as MMC_I_MASK */
-+
-+#define MMC_CMD 0x0030
-+
-+#define MMC_ARGH 0x0034 /* 16 bit */
-+
-+#define MMC_ARGL 0x0038 /* 16 bit */
-+
-+#define MMC_RES 0x003c /* 16 bit */
-+
-+#define MMC_RXFIFO 0x0040 /* 8 bit */
-+
-+#define MMC_TXFIFO 0x0044 /* 8 bit */
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/media/mmc/mmci.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,147 @@
-+/*
-+ * linux/drivers/media/mmc/mmci.h - ARM PrimeCell MMCI PL180/1 driver
-+ *
-+ * Copyright (C) 2003 Deep Blue Solutions, 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 version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#define MMCIPOWER 0x000
-+#define MCI_PWR_OFF 0x00
-+#define MCI_PWR_UP 0x02
-+#define MCI_PWR_ON 0x03
-+#define MCI_OD (1 << 6)
-+#define MCI_ROD (1 << 7)
-+
-+#define MMCICLOCK 0x004
-+#define MCI_CLK_ENABLE (1 << 8)
-+#define MCI_PWRSAVE (1 << 9)
-+#define MCI_BYPASS (1 << 10)
-+
-+#define MMCIARGUMENT 0x008
-+#define MMCICOMMAND 0x00c
-+#define MCI_CPSM_RESPONSE (1 << 6)
-+#define MCI_CPSM_LONGRSP (1 << 7)
-+#define MCI_CPSM_INTERRUPT (1 << 8)
-+#define MCI_CPSM_PENDING (1 << 9)
-+#define MCI_CPSM_ENABLE (1 << 10)
-+
-+#define MMCIRESPCMD 0x010
-+#define MMCIRESPONSE0 0x014
-+#define MMCIRESPONSE1 0x018
-+#define MMCIRESPONSE2 0x01c
-+#define MMCIRESPONSE3 0x020
-+#define MMCIDATATIMER 0x024
-+#define MMCIDATALENGTH 0x028
-+#define MMCIDATACTRL 0x02c
-+#define MCI_DPSM_ENABLE (1 << 0)
-+#define MCI_DPSM_DIRECTION (1 << 1)
-+#define MCI_DPSM_MODE (1 << 2)
-+#define MCI_DPSM_DMAENABLE (1 << 3)
-+
-+#define MMCIDATACNT 0x030
-+#define MMCISTATUS 0x034
-+#define MCI_CMDCRCFAIL (1 << 0)
-+#define MCI_DATACRCFAIL (1 << 1)
-+#define MCI_CMDTIMEOUT (1 << 2)
-+#define MCI_DATATIMEOUT (1 << 3)
-+#define MCI_TXUNDERRUN (1 << 4)
-+#define MCI_RXOVERRUN (1 << 5)
-+#define MCI_CMDRESPEND (1 << 6)
-+#define MCI_CMDSENT (1 << 7)
-+#define MCI_DATAEND (1 << 8)
-+#define MCI_DATABLOCKEND (1 << 10)
-+#define MCI_CMDACTIVE (1 << 11)
-+#define MCI_TXACTIVE (1 << 12)
-+#define MCI_RXACTIVE (1 << 13)
-+#define MCI_TXFIFOHALFEMPTY (1 << 14)
-+#define MCI_RXFIFOHALFFULL (1 << 15)
-+#define MCI_TXFIFOFULL (1 << 16)
-+#define MCI_RXFIFOFULL (1 << 17)
-+#define MCI_TXFIFOEMPTY (1 << 18)
-+#define MCI_RXFIFOEMPTY (1 << 19)
-+#define MCI_TXDATAAVLBL (1 << 20)
-+#define MCI_RXDATAAVLBL (1 << 21)
-+
-+#define MMCICLEAR 0x038
-+#define MCI_CMDCRCFAILCLR (1 << 0)
-+#define MCI_DATACRCFAILCLR (1 << 1)
-+#define MCI_CMDTIMEOUTCLR (1 << 2)
-+#define MCI_DATATIMEOUTCLR (1 << 3)
-+#define MCI_TXUNDERRUNCLR (1 << 4)
-+#define MCI_RXOVERRUNCLR (1 << 5)
-+#define MCI_CMDRESPENDCLR (1 << 6)
-+#define MCI_CMDSENTCLR (1 << 7)
-+#define MCI_DATAENDCLR (1 << 8)
-+#define MCI_DATABLOCKENDCLR (1 << 10)
-+
-+#define MMCIMASK0 0x03c
-+#define MCI_CMDCRCFAILMASK (1 << 0)
-+#define MCI_DATACRCFAILMASK (1 << 1)
-+#define MCI_CMDTIMEOUTMASK (1 << 2)
-+#define MCI_DATATIMEOUTMASK (1 << 3)
-+#define MCI_TXUNDERRUNMASK (1 << 4)
-+#define MCI_RXOVERRUNMASK (1 << 5)
-+#define MCI_CMDRESPENDMASK (1 << 6)
-+#define MCI_CMDSENTMASK (1 << 7)
-+#define MCI_DATAENDMASK (1 << 8)
-+#define MCI_DATABLOCKENDMASK (1 << 10)
-+#define MCI_CMDACTIVEMASK (1 << 11)
-+#define MCI_TXACTIVEMASK (1 << 12)
-+#define MCI_RXACTIVEMASK (1 << 13)
-+#define MCI_TXFIFOHALFEMPTYMASK (1 << 14)
-+#define MCI_RXFIFOHALFFULLMASK (1 << 15)
-+#define MCI_TXFIFOFULLMASK (1 << 16)
-+#define MCI_RXFIFOFULLMASK (1 << 17)
-+#define MCI_TXFIFOEMPTYMASK (1 << 18)
-+#define MCI_RXFIFOEMPTYMASK (1 << 19)
-+#define MCI_TXDATAAVLBLMASK (1 << 20)
-+#define MCI_RXDATAAVLBLMASK (1 << 21)
-+
-+#define MMCIMASK1 0x040
-+#define MMCIFIFOCNT 0x048
-+#define MMCIFIFO 0x080 /* to 0x0bc */
-+
-+#define MCI_IRQMASK \
-+ (MCI_CMDCRCFAIL|MCI_DATACRCFAIL|MCI_CMDTIMEOUT|MCI_DATATIMEOUT| \
-+ MCI_TXUNDERRUN|MCI_RXOVERRUN|MCI_CMDRESPEND|MCI_CMDSENT| \
-+ MCI_DATAEND|MCI_DATABLOCKEND| \
-+ MCI_TXFIFOHALFEMPTY|MCI_RXFIFOHALFFULL| \
-+ MCI_TXFIFOEMPTY|MCI_RXDATAAVLBL)
-+
-+#define MCI_IRQENABLE \
-+ (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \
-+ MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \
-+ MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_DATAENDMASK| \
-+ MCI_DATABLOCKENDMASK|MCI_TXFIFOHALFEMPTYMASK| \
-+ MCI_RXFIFOHALFFULLMASK)
-+
-+#define MCI_FIFOSIZE 16
-+
-+#define MCI_FIFOHALFSIZE (MCI_FIFOSIZE / 2)
-+
-+struct mmci_host {
-+ struct mmc_host mmc;
-+ void *base;
-+ int irq;
-+ unsigned int mclk;
-+ u32 pwr;
-+
-+ struct mmc_request *req;
-+ struct mmc_command *cmd;
-+ struct mmc_data *data;
-+
-+ unsigned int data_xfered;
-+
-+ /* pio stuff */
-+ void *buffer;
-+ unsigned int size;
-+
-+ /* dma stuff */
-+// struct scatterlist *sg_list;
-+// int sg_len;
-+// int sg_dir;
-+};
-+
-+#define to_mmci_host(mmc) container_of(mmc, struct mmci_host, mmc)
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/media/mmc/mmc.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,801 @@
-+/*
-+ * linux/drivers/media/mmc/mmc.c
-+ *
-+ * Copyright (C) 2003 Russell King, 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 version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/interrupt.h>
-+#include <linux/completion.h>
-+#include <linux/device.h>
-+#include <linux/delay.h>
-+#include <linux/err.h>
-+
-+#include <linux/mmc/card.h>
-+#include <linux/mmc/host.h>
-+#include <linux/mmc/protocol.h>
-+
-+#include "mmc.h"
-+
-+#ifdef CONFIG_MMC_DEBUG
-+#define DBG(x...) printk(KERN_DEBUG x)
-+#else
-+#define DBG(x...) do { } while (0)
-+#endif
-+
-+#define CMD_RETRIES 3
-+
-+/*
-+ * OCR Bit positions to 10s of Vdd mV.
-+ */
-+static const unsigned short mmc_ocr_bit_to_vdd[] = {
-+ 150, 155, 160, 165, 170, 180, 190, 200,
-+ 210, 220, 230, 240, 250, 260, 270, 280,
-+ 290, 300, 310, 320, 330, 340, 350, 360
-+};
-+
-+static const unsigned int tran_exp[] = {
-+ 10000, 100000, 1000000, 10000000,
-+ 0, 0, 0, 0
-+};
-+
-+static const unsigned char tran_mant[] = {
-+ 0, 10, 12, 13, 15, 20, 25, 30,
-+ 35, 40, 45, 50, 55, 60, 70, 80,
-+};
-+
-+static const unsigned int tacc_exp[] = {
-+ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
-+};
-+
-+static const unsigned int tacc_mant[] = {
-+ 0, 10, 12, 13, 15, 20, 25, 30,
-+ 35, 40, 45, 50, 55, 60, 70, 80,
-+};
-+
-+
-+/**
-+ * mmc_request_done - finish processing an MMC command
-+ * @host: MMC host which completed command
-+ * @cmd: MMC command which completed
-+ * @err: MMC error code
-+ *
-+ * MMC drivers should call this function when they have completed
-+ * their processing of a command. This should be called before the
-+ * data part of the command has completed.
-+ */
-+void mmc_request_done(struct mmc_host *host, struct mmc_request *req)
-+{
-+ struct mmc_command *cmd = req->cmd;
-+ int err = req->cmd->error;
-+ DBG("MMC: req done (%02x): %d: %08x %08x %08x %08x\n", cmd->opcode,
-+ err, cmd->resp[0], cmd->resp[1], cmd->resp[2], cmd->resp[3]);
-+
-+ if (err && cmd->retries) {
-+ cmd->retries--;
-+ cmd->error = 0;
-+ host->ops->request(host, req);
-+ } else if (req->done) {
-+ req->done(req);
-+ }
-+}
-+
-+EXPORT_SYMBOL(mmc_request_done);
-+
-+/**
-+ * mmc_start_request - start a command on a host
-+ * @host: MMC host to start command on
-+ * @cmd: MMC command to start
-+ *
-+ * Queue a command on the specified host. We expect the
-+ * caller to be holding the host lock with interrupts disabled.
-+ */
-+void
-+mmc_start_request(struct mmc_host *host, struct mmc_request *req)
-+{
-+ DBG("MMC: starting cmd %02x arg %08x flags %08x\n",
-+ req->cmd->opcode, req->cmd->arg, req->cmd->flags);
-+
-+ req->cmd->error = 0;
-+ req->cmd->req = req;
-+ if (req->data) {
-+ req->cmd->data = req->data;
-+ req->data->error = 0;
-+ req->data->req = req;
-+ if (req->stop) {
-+ req->data->stop = req->stop;
-+ req->stop->error = 0;
-+ req->stop->req = req;
-+ }
-+ }
-+ host->ops->request(host, req);
-+}
-+
-+EXPORT_SYMBOL(mmc_start_request);
-+
-+static void mmc_wait_done(struct mmc_request *req)
-+{
-+ complete(req->done_data);
-+}
-+
-+int mmc_wait_for_req(struct mmc_host *host, struct mmc_request *req)
-+{
-+ DECLARE_COMPLETION(complete);
-+
-+ req->done_data = &complete;
-+ req->done = mmc_wait_done;
-+
-+ mmc_start_request(host, req);
-+
-+ wait_for_completion(&complete);
-+
-+ return 0;
-+}
-+
-+EXPORT_SYMBOL(mmc_wait_for_req);
-+
-+/**
-+ * mmc_wait_for_cmd - start a command and wait for completion
-+ * @host: MMC host to start command
-+ * @cmd: MMC command to start
-+ * @retries: maximum number of retries
-+ *
-+ * Start a new MMC command for a host, and wait for the command
-+ * to complete. Return any error that occurred while the command
-+ * was executing. Do not attempt to parse the response.
-+ */
-+int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries)
-+{
-+ struct mmc_request req;
-+
-+ BUG_ON(host->card_busy == NULL);
-+
-+ memset(&req, 0, sizeof(struct mmc_request));
-+
-+ memset(cmd->resp, 0, sizeof(cmd->resp));
-+ cmd->retries = retries;
-+
-+ req.cmd = cmd;
-+ cmd->data = NULL;
-+
-+ mmc_wait_for_req(host, &req);
-+
-+ return cmd->error;
-+}
-+
-+EXPORT_SYMBOL(mmc_wait_for_cmd);
-+
-+
-+
-+/**
-+ * __mmc_claim_host - exclusively claim a host
-+ * @host: mmc host to claim
-+ * @card: mmc card to claim host for
-+ *
-+ * Claim a host for a set of operations. If a valid card
-+ * is passed and this wasn't the last card selected, select
-+ * the card before returning.
-+ *
-+ * Note: you should use mmc_card_claim_host or mmc_claim_host.
-+ */
-+int __mmc_claim_host(struct mmc_host *host, struct mmc_card *card)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ unsigned long flags;
-+ int err = 0;
-+
-+ add_wait_queue(&host->wq, &wait);
-+ spin_lock_irqsave(&host->lock, flags);
-+ while (1) {
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ if (host->card_busy == NULL)
-+ break;
-+ spin_unlock_irqrestore(&host->lock, flags);
-+ schedule();
-+ spin_lock_irqsave(&host->lock, flags);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ host->card_busy = card;
-+ spin_unlock_irqrestore(&host->lock, flags);
-+ remove_wait_queue(&host->wq, &wait);
-+
-+ if (card != (void *)-1 && host->card_selected != card) {
-+ struct mmc_command cmd;
-+
-+ host->card_selected = card;
-+
-+ cmd.opcode = MMC_SELECT_CARD;
-+ cmd.arg = card->rca << 16;
-+ cmd.flags = MMC_RSP_SHORT | MMC_RSP_CRC;
-+
-+ err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
-+ }
-+
-+ return err;
-+}
-+
-+EXPORT_SYMBOL(__mmc_claim_host);
-+
-+/**
-+ * mmc_release_host - release a host
-+ * @host: mmc host to release
-+ *
-+ * Release a MMC host, allowing others to claim the host
-+ * for their operations.
-+ */
-+void mmc_release_host(struct mmc_host *host)
-+{
-+ unsigned long flags;
-+
-+ BUG_ON(host->card_busy == NULL);
-+
-+ spin_lock_irqsave(&host->lock, flags);
-+ host->card_busy = NULL;
-+ spin_unlock_irqrestore(&host->lock, flags);
-+
-+ wake_up(&host->wq);
-+}
-+
-+EXPORT_SYMBOL(mmc_release_host);
-+
-+static void mmc_deselect_cards(struct mmc_host *host)
-+{
-+ struct mmc_command cmd;
-+
-+ /*
-+ * Ensure that no card is selected.
-+ */
-+ if (host->card_selected) {
-+ host->card_selected = NULL;
-+
-+ cmd.opcode = MMC_SELECT_CARD;
-+ cmd.arg = 0;
-+ cmd.flags = MMC_RSP_NONE;
-+
-+ mmc_wait_for_cmd(host, &cmd, 0);
-+ }
-+}
-+
-+
-+static inline void mmc_delay(unsigned int ms)
-+{
-+ if (ms < HZ / 1000) {
-+ yield();
-+ mdelay(ms);
-+ } else {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(ms * HZ / 1000);
-+ }
-+}
-+
-+static u32 mmc_select_voltage(struct mmc_host *host, u32 ocr)
-+{
-+ int bit;
-+
-+ /*
-+ * Mask off any voltages we don't support
-+ */
-+ ocr &= host->ocr_avail;
-+
-+ /*
-+ * Select the lowest voltage
-+ */
-+ bit = ffs(ocr);
-+ if (bit) {
-+ bit -= 1;
-+
-+ ocr = 1 << bit;
-+
-+ host->ios.vdd = mmc_ocr_bit_to_vdd[bit];
-+ host->ops->set_ios(host, &host->ios);
-+ } else {
-+ ocr = 0;
-+ }
-+
-+ return ocr;
-+}
-+
-+static void mmc_decode_cid(struct mmc_cid *cid, u32 *resp)
-+{
-+ memset(cid, 0, sizeof(struct mmc_cid));
-+
-+ cid->manfid = resp[0] >> 8;
-+ cid->prod_name[0] = resp[0];
-+ cid->prod_name[1] = resp[1] >> 24;
-+ cid->prod_name[2] = resp[1] >> 16;
-+ cid->prod_name[3] = resp[1] >> 8;
-+ cid->prod_name[4] = resp[1];
-+ cid->prod_name[5] = resp[2] >> 24;
-+ cid->prod_name[6] = resp[2] >> 16;
-+ cid->prod_name[7] = '\0';
-+ cid->hwrev = (resp[2] >> 12) & 15;
-+ cid->fwrev = (resp[2] >> 8) & 15;
-+ cid->serial = (resp[2] & 255) << 16 | (resp[3] >> 16);
-+ cid->month = (resp[3] >> 12) & 15;
-+ cid->year = (resp[3] >> 8) & 15;
-+}
-+
-+static void mmc_decode_csd(struct mmc_csd *csd, u32 *resp)
-+{
-+ unsigned int e, m;
-+
-+ csd->mmc_prot = (resp[0] >> 26) & 15;
-+ m = (resp[0] >> 19) & 15;
-+ e = (resp[0] >> 16) & 7;
-+ csd->tacc_ns = (tacc_exp[e] * tacc_mant[m] + 9) / 10;
-+ csd->tacc_clks = ((resp[0] >> 8) & 255) * 100;
-+
-+ m = (resp[0] >> 3) & 15;
-+ e = resp[0] & 7;
-+ csd->max_dtr = tran_exp[e] * tran_mant[m];
-+ csd->cmdclass = (resp[1] >> 20) & 0xfff;
-+
-+ e = (resp[2] >> 15) & 7;
-+ m = (resp[1] << 2 | resp[2] >> 30) & 0x3fff;
-+ csd->capacity = (1 + m) << (e + 2);
-+
-+ csd->read_blkbits = (resp[1] >> 16) & 15;
-+}
-+
-+/*
-+ * Locate a MMC card on this MMC host given a CID.
-+ */
-+static struct mmc_card *
-+mmc_find_card(struct mmc_host *host, struct mmc_cid *cid)
-+{
-+ struct mmc_card *card;
-+
-+ list_for_each_entry(card, &host->cards, node) {
-+ if (memcmp(&card->cid, cid, sizeof(struct mmc_cid)) == 0)
-+ return card;
-+ }
-+ return NULL;
-+}
-+
-+/*
-+ * Allocate a new MMC card, and assign a unique RCA.
-+ */
-+static struct mmc_card *
-+mmc_alloc_card(struct mmc_host *host, struct mmc_cid *cid, unsigned int *frca)
-+{
-+ struct mmc_card *card, *c;
-+ unsigned int rca = *frca;
-+
-+ card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL);
-+ if (!card)
-+ return ERR_PTR(-ENOMEM);
-+
-+ mmc_init_card(card, host);
-+ memcpy(&card->cid, cid, sizeof(struct mmc_cid));
-+
-+ again:
-+ list_for_each_entry(c, &host->cards, node)
-+ if (c->rca == rca) {
-+ rca++;
-+ goto again;
-+ }
-+
-+ card->rca = rca;
-+
-+ *frca = rca;
-+
-+ return card;
-+}
-+
-+/*
-+ * Apply power to the MMC stack.
-+ */
-+static void mmc_power_up(struct mmc_host *host)
-+{
-+ struct mmc_command cmd;
-+ int bit = fls(host->ocr_avail) - 1;
-+
-+ host->ios.vdd = mmc_ocr_bit_to_vdd[bit];
-+ host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
-+ host->ios.power_mode = MMC_POWER_UP;
-+ host->ops->set_ios(host, &host->ios);
-+
-+ mmc_delay(1);
-+
-+ host->ios.clock = host->f_min;
-+ host->ios.power_mode = MMC_POWER_ON;
-+ host->ops->set_ios(host, &host->ios);
-+
-+ mmc_delay(2);
-+
-+ cmd.opcode = MMC_GO_IDLE_STATE;
-+ cmd.arg = 0;
-+ cmd.flags = MMC_RSP_NONE;
-+
-+ mmc_wait_for_cmd(host, &cmd, 0);
-+}
-+
-+static void mmc_power_off(struct mmc_host *host)
-+{
-+ host->ios.clock = 0;
-+ host->ios.vdd = 0;
-+ host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
-+ host->ios.power_mode = MMC_POWER_OFF;
-+ host->ops->set_ios(host, &host->ios);
-+}
-+
-+static int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
-+{
-+ struct mmc_command cmd;
-+ int i, err = 0;
-+
-+ cmd.opcode = MMC_SEND_OP_COND;
-+ cmd.arg = ocr;
-+ cmd.flags = MMC_RSP_SHORT;
-+
-+ for (i = 100; i; i--) {
-+ err = mmc_wait_for_cmd(host, &cmd, 0);
-+ if (err != MMC_ERR_NONE)
-+ break;
-+
-+ if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0)
-+ break;
-+
-+ err = MMC_ERR_TIMEOUT;
-+ }
-+
-+ if (rocr)
-+ *rocr = cmd.resp[0];
-+
-+ return err;
-+}
-+
-+/*
-+ * Discover cards by requesting their CID. If this command
-+ * times out, it is not an error; there are no further cards
-+ * to be discovered. Add new cards to the list.
-+ *
-+ * Create a mmc_card entry for each discovered card, assigning
-+ * it an RCA, and save the CID.
-+ */
-+static void mmc_discover_cards(struct mmc_host *host)
-+{
-+ struct mmc_card *card;
-+ unsigned int first_rca = 1, err;
-+
-+ while (1) {
-+ struct mmc_command cmd;
-+ struct mmc_cid cid;
-+
-+ /*
-+ * Read CID
-+ */
-+ cmd.opcode = MMC_ALL_SEND_CID;
-+ cmd.arg = 0;
-+ cmd.flags = MMC_RSP_LONG | MMC_RSP_CRC;
-+
-+ err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
-+ if (err == MMC_ERR_TIMEOUT) {
-+ err = MMC_ERR_NONE;
-+ break;
-+ }
-+ if (err != MMC_ERR_NONE) {
-+ printk(KERN_ERR "MMC: mmc%d error requesting CID: %d\n",
-+ host->host_num, err);
-+ break;
-+ }
-+
-+ mmc_decode_cid(&cid, cmd.resp);
-+
-+ card = mmc_find_card(host, &cid);
-+ if (!card) {
-+ card = mmc_alloc_card(host, &cid, &first_rca);
-+ if (IS_ERR(card)) {
-+ err = PTR_ERR(card);
-+ break;
-+ }
-+ list_add(&card->node, &host->cards);
-+ }
-+
-+ card->state &= ~MMC_STATE_DEAD;
-+
-+ cmd.opcode = MMC_SET_RELATIVE_ADDR;
-+ cmd.arg = card->rca << 16;
-+ cmd.flags = MMC_RSP_SHORT | MMC_RSP_CRC;
-+
-+ err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
-+ if (err != MMC_ERR_NONE)
-+ card->state |= MMC_STATE_DEAD;
-+ }
-+}
-+
-+static void mmc_read_csds(struct mmc_host *host)
-+{
-+ struct mmc_card *card;
-+
-+ list_for_each_entry(card, &host->cards, node) {
-+ struct mmc_command cmd;
-+ int err;
-+
-+ if (card->state & (MMC_STATE_DEAD|MMC_STATE_PRESENT))
-+ continue;
-+
-+ cmd.opcode = MMC_SEND_CSD;
-+ cmd.arg = card->rca << 16;
-+ cmd.flags = MMC_RSP_LONG | MMC_RSP_CRC;
-+
-+ err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
-+ if (err != MMC_ERR_NONE) {
-+ card->state |= MMC_STATE_DEAD;
-+ continue;
-+ }
-+
-+ mmc_decode_csd(&card->csd, cmd.resp);
-+ }
-+}
-+
-+static unsigned int mmc_calculate_clock(struct mmc_host *host)
-+{
-+ struct mmc_card *card;
-+ unsigned int max_dtr = host->f_max;
-+
-+ list_for_each_entry(card, &host->cards, node)
-+ if (!mmc_card_dead(card) && max_dtr > card->csd.max_dtr)
-+ max_dtr = card->csd.max_dtr;
-+
-+ DBG("MMC: selected %d.%03dMHz transfer rate\n",
-+ max_dtr / 1000000, (max_dtr / 1000) % 1000);
-+
-+ return max_dtr;
-+}
-+
-+/*
-+ * Check whether cards we already know about are still present.
-+ * We do this by requesting status, and checking whether a card
-+ * responds.
-+ *
-+ * A request for status does not cause a state change in data
-+ * transfer mode.
-+ */
-+static void mmc_check_cards(struct mmc_host *host)
-+{
-+ struct list_head *l, *n;
-+
-+ mmc_deselect_cards(host);
-+
-+ list_for_each_safe(l, n, &host->cards) {
-+ struct mmc_card *card = mmc_list_to_card(l);
-+ struct mmc_command cmd;
-+ int err;
-+
-+ cmd.opcode = MMC_SEND_STATUS;
-+ cmd.arg = card->rca << 16;
-+ cmd.flags = MMC_RSP_LONG | MMC_RSP_CRC;
-+
-+ err = mmc_wait_for_cmd(host, &cmd, CMD_RETRIES);
-+ if (err == MMC_ERR_NONE)
-+ continue;
-+
-+ /*
-+ * Ok, we believe this card has been removed.
-+ */
-+ card->state |= MMC_STATE_DEAD;
-+ }
-+}
-+
-+static void mmc_setup(struct mmc_host *host)
-+{
-+ if (host->ios.power_mode != MMC_POWER_ON) {
-+ int err;
-+ u32 ocr;
-+
-+ mmc_power_up(host);
-+
-+ err = mmc_send_op_cond(host, 0, &ocr);
-+ if (err != MMC_ERR_NONE)
-+ return;
-+
-+ host->ocr = mmc_select_voltage(host, ocr);
-+ } else {
-+ host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
-+ host->ios.clock = host->f_min;
-+ host->ops->set_ios(host, &host->ios);
-+
-+ /*
-+ * We should remember the OCR mask from the existing
-+ * cards, and detect the new cards OCR mask, combine
-+ * the two and re-select the VDD. However, if we do
-+ * change VDD, we should do an idle, and then do a
-+ * full re-initialisation. We would need to notify
-+ * drivers so that they can re-setup the cards as
-+ * well, while keeping their queues at bay.
-+ *
-+ * For the moment, we take the easy way out - if the
-+ * new cards don't like our currently selected VDD,
-+ * they drop off the bus.
-+ */
-+ }
-+
-+ if (host->ocr == 0)
-+ return;
-+
-+ /*
-+ * Send the selected OCR multiple times... until the cards
-+ * all get the idea that they should be ready for CMD2.
-+ * (My SanDisk card seems to need this.)
-+ */
-+ mmc_send_op_cond(host, host->ocr, NULL);
-+
-+ mmc_discover_cards(host);
-+
-+ /*
-+ * Ok, now switch to push-pull mode.
-+ */
-+ host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
-+ host->ops->set_ios(host, &host->ios);
-+
-+ mmc_read_csds(host);
-+}
-+
-+
-+/**
-+ * mmc_detect_change - process change of state on a MMC socket
-+ * @host: host which changed state.
-+ *
-+ * All we know is that card(s) have been inserted or removed
-+ * from the socket(s). We don't know which socket or cards.
-+ */
-+void mmc_detect_change(struct mmc_host *host)
-+{
-+ struct list_head *l, *n;
-+
-+ mmc_claim_host(host);
-+
-+ if (host->ios.power_mode == MMC_POWER_ON)
-+ mmc_check_cards(host);
-+
-+ mmc_setup(host);
-+
-+ if (!list_empty(&host->cards)) {
-+ /*
-+ * (Re-)calculate the fastest clock rate which the
-+ * attached cards and the host support.
-+ */
-+ host->ios.clock = mmc_calculate_clock(host);
-+ host->ops->set_ios(host, &host->ios);
-+ }
-+
-+ mmc_release_host(host);
-+
-+ list_for_each_safe(l, n, &host->cards) {
-+ struct mmc_card *card = mmc_list_to_card(l);
-+
-+ /*
-+ * If this is a new and good card, register it.
-+ */
-+ if (!mmc_card_present(card) && !mmc_card_dead(card)) {
-+ if (mmc_register_card(card))
-+ card->state |= MMC_STATE_DEAD;
-+ else
-+ card->state |= MMC_STATE_PRESENT;
-+ }
-+
-+ /*
-+ * If this card is dead, destroy it.
-+ */
-+ if (mmc_card_dead(card)) {
-+ list_del(&card->node);
-+ mmc_remove_card(card);
-+ }
-+ }
-+
-+ /*
-+ * If we discover that there are no cards on the
-+ * bus, turn off the clock and power down.
-+ */
-+ if (list_empty(&host->cards))
-+ mmc_power_off(host);
-+}
-+
-+EXPORT_SYMBOL(mmc_detect_change);
-+
-+
-+/**
-+ * mmc_init_host - initialise the per-host structure.
-+ * @host: mmc host
-+ *
-+ * Initialise the per-host structure.
-+ */
-+int mmc_init_host(struct mmc_host *host)
-+{
-+ static unsigned int host_num;
-+
-+ memset(host, 0, sizeof(struct mmc_host));
-+
-+ host->host_num = host_num++;
-+
-+ spin_lock_init(&host->lock);
-+ init_waitqueue_head(&host->wq);
-+ INIT_LIST_HEAD(&host->cards);
-+
-+ return 0;
-+}
-+
-+EXPORT_SYMBOL(mmc_init_host);
-+
-+/**
-+ * mmc_add_host - initialise host hardware
-+ * @host: mmc host
-+ */
-+int mmc_add_host(struct mmc_host *host)
-+{
-+ mmc_power_off(host);
-+ mmc_detect_change(host);
-+
-+ return 0;
-+}
-+
-+EXPORT_SYMBOL(mmc_add_host);
-+
-+/**
-+ * mmc_remove_host - remove host hardware
-+ * @host: mmc host
-+ *
-+ * Unregister and remove all cards associated with this host,
-+ * and power down the MMC bus.
-+ */
-+void mmc_remove_host(struct mmc_host *host)
-+{
-+ struct list_head *l, *n;
-+
-+ list_for_each_safe(l, n, &host->cards) {
-+ struct mmc_card *card = mmc_list_to_card(l);
-+
-+ mmc_remove_card(card);
-+ }
-+
-+ mmc_power_off(host);
-+}
-+
-+EXPORT_SYMBOL(mmc_remove_host);
-+
-+#ifdef CONFIG_PM
-+
-+/**
-+ * mmc_suspend_host - suspend a host
-+ * @host: mmc host
-+ * @state: suspend mode (PM_SUSPEND_xxx)
-+ */
-+int mmc_suspend_host(struct mmc_host *host, u32 state)
-+{
-+ mmc_claim_host(host);
-+ mmc_deselect_cards(host);
-+ mmc_power_off(host);
-+ mmc_release_host(host);
-+
-+ return 0;
-+}
-+
-+/**
-+ * mmc_resume_host - resume a previously suspended host
-+ * @host: mmc host
-+ */
-+int mmc_resume_host(struct mmc_host *host)
-+{
-+ mmc_detect_change(host);
-+
-+ return 0;
-+}
-+
-+
-+#else /* CONFIG_PM is not set */
-+
-+int mmc_suspend_host(struct mmc_host *host, u32 state) { return 0; }
-+int mmc_resume_host(struct mmc_host *host) { return 0; }
-+
-+#endif
-+
-+EXPORT_SYMBOL(mmc_suspend_host);
-+EXPORT_SYMBOL(mmc_resume_host);
-+
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/media/mmc/Makefile 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,21 @@
-+#
-+# Makefile for the kernel mmc device drivers.
-+#
-+
-+#
-+# Core
-+#
-+obj-$(CONFIG_MMC) += mmc_core.o
-+
-+#
-+# Media drivers
-+#
-+obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
-+
-+#
-+# Host drivers
-+#
-+obj-$(CONFIG_MMC_ARMMMCI) += mmci.o
-+obj-$(CONFIG_MMC_PXA) += pxamci.o
-+
-+mmc_core-y := mmc.o mmc_queue.o mmc_sysfs.o
---- linux-2.6.5/drivers/media/Makefile~heh 2004-04-03 22:38:15.000000000 -0500
-+++ linux-2.6.5/drivers/media/Makefile 2004-04-30 20:57:36.000000000 -0400
-@@ -3,3 +3,6 @@
- #
-
- obj-y := video/ radio/ dvb/ common/
-+
-+obj-$(CONFIG_MMC) += mmc/
-+
---- linux-2.6.5/drivers/serial/Kconfig~heh 2004-04-03 22:38:15.000000000 -0500
-+++ linux-2.6.5/drivers/serial/Kconfig 2004-04-30 20:57:36.000000000 -0400
-@@ -315,6 +315,29 @@
- your boot loader (lilo or loadlin) about how to pass options to the
- kernel at boot time.)
-
-+config SERIAL_PXA
-+ bool "PXA serial port support"
-+ depends on ARM && ARCH_PXA
-+ select SERIAL_CORE
-+ help
-+ If you have a machine based on an Intel XScale PXA2xx CPU you
-+ can enable its onboard serial ports by enabling this option.
-+
-+config SERIAL_PXA_CONSOLE
-+ bool "Console on PXA serial port"
-+ depends on SERIAL_PXA
-+ select SERIAL_CORE_CONSOLE
-+ help
-+ If you have enabled the serial port on the Intel XScale PXA
-+ CPU you can make it the console by answering Y to this option.
-+
-+ Even if you say Y here, the currently visible virtual console
-+ (/dev/tty0) will still be used as the system console by default, but
-+ you can alter that using a kernel command line option such as
-+ "console=ttySA0". (Try "man bootparam" or see the documentation of
-+ your boot loader (lilo or loadlin) about how to pass options to the
-+ kernel at boot time.)
-+
- config SERIAL_SA1100
- bool "SA1100 serial port support"
- depends on ARM && ARCH_SA1100
---- linux-2.6.5/drivers/serial/pxa.c~heh 2004-04-03 22:38:16.000000000 -0500
-+++ linux-2.6.5/drivers/serial/pxa.c 2004-04-30 20:57:36.000000000 -0400
-@@ -294,7 +294,6 @@
- unsigned char status;
- unsigned int ret;
-
--return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
- spin_lock_irqsave(&up->port.lock, flags);
- status = serial_in(up, UART_MSR);
- spin_unlock_irqrestore(&up->port.lock, flags);
-@@ -800,6 +799,21 @@
- .ops = &serial_pxa_pops,
- .line = 2,
- },
-+ }, { /* HWUART */
-+ .name = "HWUART",
-+ .cken = CKEN4_HWUART,
-+ .port = {
-+ .type = PORT_PXA,
-+ .iotype = SERIAL_IO_MEM,
-+ .membase = (void *)&HWUART,
-+ .mapbase = __PREG(HWUART),
-+ .irq = IRQ_HWUART,
-+ .uartclk = 921600 * 16,
-+ .fifosize = 64,
-+ .flags = ASYNC_SKIP_TEST,
-+ .ops = &serial_pxa_pops,
-+ .line = 3,
-+ },
- }
- };
-
---- linux-2.6.5/drivers/serial/sa1100.c~heh 2004-04-03 22:36:24.000000000 -0500
-+++ linux-2.6.5/drivers/serial/sa1100.c 2004-04-30 20:57:36.000000000 -0400
-@@ -448,6 +448,15 @@
- unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
-
- /*
-+ * If we don't support modem control lines, don't allow
-+ * these to be set.
-+ */
-+ if (0) {
-+ termios->c_cflag &= ~(HUPCL | CRTSCTS | CMSPAR);
-+ termios->c_cflag |= CLOCAL;
-+ }
-+
-+ /*
- * We only support CS7 and CS8.
- */
- while ((termios->c_cflag & CSIZE) != CS7 &&
-@@ -894,6 +903,7 @@
- if (sa1100_ports[i].port.mapbase != res->start)
- continue;
-
-+ sa1100_ports[i].port.dev = _dev;
- uart_add_one_port(&sa1100_reg, &sa1100_ports[i].port);
- dev_set_drvdata(_dev, &sa1100_ports[i]);
- break;
---- linux-2.6.5/drivers/mtd/mtd_blkdevs.c~heh 2004-04-03 22:36:14.000000000 -0500
-+++ linux-2.6.5/drivers/mtd/mtd_blkdevs.c 2004-04-30 20:57:36.000000000 -0400
-@@ -81,7 +81,7 @@
- struct request_queue *rq = tr->blkcore_priv->rq;
-
- /* we might get involved when memory gets low, so use PF_MEMALLOC */
-- current->flags |= PF_MEMALLOC;
-+ current->flags |= PF_MEMALLOC|PF_IOTHREAD;
-
- daemonize("%sd", tr->name);
-
---- linux-2.6.5/drivers/mtd/devices/doc1000.c~heh 2004-04-03 22:37:36.000000000 -0500
-+++ linux-2.6.5/drivers/mtd/devices/doc1000.c 2004-04-30 20:57:36.000000000 -0400
-@@ -1,6 +1,6 @@
- /*======================================================================
-
-- $Id$
-+ $Id$
-
- ======================================================================*/
-
-@@ -20,6 +20,7 @@
- #include <linux/ioctl.h>
- #include <asm/io.h>
- #include <asm/system.h>
-+#include <asm/segment.h>
- #include <stdarg.h>
- #include <linux/delay.h>
- #include <linux/init.h>
-@@ -482,7 +483,7 @@
- else
- priv->devstat[erase->dev] = erase->state = MTD_ERASE_PENDING;
- }
-- else if (erase->time + erase_timeout < jiffies)
-+ else if (time_after(jiffies, erase->time + erase_timeout))
- {
- printk("Flash erase timed out. The world is broken.\n");
-
---- linux-2.6.5/drivers/mtd/mtdconcat.c~heh 2004-04-03 22:37:37.000000000 -0500
-+++ linux-2.6.5/drivers/mtd/mtdconcat.c 2004-04-30 20:57:36.000000000 -0400
-@@ -7,7 +7,7 @@
- *
- * This code is GPL
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/module.h>
-@@ -26,7 +26,7 @@
- */
- struct mtd_concat {
- struct mtd_info mtd;
-- int num_subdev;
-+ int num_subdev;
- struct mtd_info **subdev;
- };
-
-@@ -37,21 +37,20 @@
- #define SIZEOF_STRUCT_MTD_CONCAT(num_subdev) \
- ((sizeof(struct mtd_concat) + (num_subdev) * sizeof(struct mtd_info *)))
-
--
- /*
- * Given a pointer to the MTD object in the mtd_concat structure,
- * we can retrieve the pointer to that structure with this macro.
- */
- #define CONCAT(x) ((struct mtd_concat *)(x))
-
--
- /*
- * MTD methods which look up the relevant subdevice, translate the
- * effective address and pass through to the subdevice.
- */
-
--static int concat_read (struct mtd_info *mtd, loff_t from, size_t len,
-- size_t *retlen, u_char *buf)
-+static int
-+concat_read(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t * retlen, u_char * buf)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- int err = -EINVAL;
-@@ -59,43 +58,43 @@
-
- *retlen = 0;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- size_t size, retsize;
-
-- if (from >= subdev->size)
-- { /* Not destined for this subdev */
-- size = 0;
-+ if (from >= subdev->size) {
-+ /* Not destined for this subdev */
-+ size = 0;
- from -= subdev->size;
-+ continue;
- }
-+ if (from + len > subdev->size)
-+ /* First part goes into this subdev */
-+ size = subdev->size - from;
- else
-- {
-- if (from + len > subdev->size)
-- size = subdev->size - from; /* First part goes into this subdev */
-- else
-- size = len; /* Entire transaction goes into this subdev */
-+ /* Entire transaction goes into this subdev */
-+ size = len;
-
-- err = subdev->read(subdev, from, size, &retsize, buf);
-+ err = subdev->read(subdev, from, size, &retsize, buf);
-
-- if(err)
-- break;
-+ if (err)
-+ break;
-
-- *retlen += retsize;
-- len -= size;
-- if(len == 0)
-- break;
-+ *retlen += retsize;
-+ len -= size;
-+ if (len == 0)
-+ break;
-
-- err = -EINVAL;
-- buf += size;
-- from = 0;
-- }
-+ err = -EINVAL;
-+ buf += size;
-+ from = 0;
- }
- return err;
- }
-
--static int concat_write (struct mtd_info *mtd, loff_t to, size_t len,
-- size_t *retlen, const u_char *buf)
-+static int
-+concat_write(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t * retlen, const u_char * buf)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- int err = -EINVAL;
-@@ -106,46 +105,44 @@
-
- *retlen = 0;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- size_t size, retsize;
-
-- if (to >= subdev->size)
-- {
-- size = 0;
-+ if (to >= subdev->size) {
-+ size = 0;
- to -= subdev->size;
-+ continue;
- }
-+ if (to + len > subdev->size)
-+ size = subdev->size - to;
- else
-- {
-- if (to + len > subdev->size)
-- size = subdev->size - to;
-- else
-- size = len;
-+ size = len;
-
-- if (!(subdev->flags & MTD_WRITEABLE))
-- err = -EROFS;
-- else
-- err = subdev->write(subdev, to, size, &retsize, buf);
-+ if (!(subdev->flags & MTD_WRITEABLE))
-+ err = -EROFS;
-+ else
-+ err = subdev->write(subdev, to, size, &retsize, buf);
-
-- if(err)
-- break;
-+ if (err)
-+ break;
-
-- *retlen += retsize;
-- len -= size;
-- if(len == 0)
-- break;
-+ *retlen += retsize;
-+ len -= size;
-+ if (len == 0)
-+ break;
-
-- err = -EINVAL;
-- buf += size;
-- to = 0;
-- }
-+ err = -EINVAL;
-+ buf += size;
-+ to = 0;
- }
- return err;
- }
-
--static int concat_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
-- size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel)
-+static int
-+concat_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t * retlen, u_char * buf, u_char * eccbuf,
-+ struct nand_oobinfo *oobsel)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- int err = -EINVAL;
-@@ -153,53 +150,56 @@
-
- *retlen = 0;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- size_t size, retsize;
--
-- if (from >= subdev->size)
-- { /* Not destined for this subdev */
-- size = 0;
-+
-+ if (from >= subdev->size) {
-+ /* Not destined for this subdev */
-+ size = 0;
- from -= subdev->size;
-+ continue;
- }
-+
-+ if (from + len > subdev->size)
-+ /* First part goes into this subdev */
-+ size = subdev->size - from;
- else
-- {
-- if (from + len > subdev->size)
-- size = subdev->size - from; /* First part goes into this subdev */
-- else
-- size = len; /* Entire transaction goes into this subdev */
--
-- if (subdev->read_ecc)
-- err = subdev->read_ecc(subdev, from, size, &retsize, buf, eccbuf, oobsel);
-- else
-- err = -EINVAL;
-+ /* Entire transaction goes into this subdev */
-+ size = len;
-
-- if(err)
-- break;
-+ if (subdev->read_ecc)
-+ err = subdev->read_ecc(subdev, from, size,
-+ &retsize, buf, eccbuf, oobsel);
-+ else
-+ err = -EINVAL;
-
-- *retlen += retsize;
-- len -= size;
-- if(len == 0)
-- break;
-+ if (err)
-+ break;
-
-- err = -EINVAL;
-- buf += size;
-- if (eccbuf)
-- {
-- eccbuf += subdev->oobsize;
-- /* in nand.c at least, eccbufs are tagged with 2 (int)eccstatus',
-- we must account for these */
-- eccbuf += 2 * (sizeof(int));
-- }
-- from = 0;
-+ *retlen += retsize;
-+ len -= size;
-+ if (len == 0)
-+ break;
-+
-+ err = -EINVAL;
-+ buf += size;
-+ if (eccbuf) {
-+ eccbuf += subdev->oobsize;
-+ /* in nand.c at least, eccbufs are
-+ tagged with 2 (int)eccstatus'; we
-+ must account for these */
-+ eccbuf += 2 * (sizeof (int));
- }
-+ from = 0;
- }
- return err;
- }
-
--static int concat_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
-- size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel)
-+static int
-+concat_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t * retlen, const u_char * buf, u_char * eccbuf,
-+ struct nand_oobinfo *oobsel)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- int err = -EINVAL;
-@@ -210,50 +210,48 @@
-
- *retlen = 0;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- size_t size, retsize;
--
-- if (to >= subdev->size)
-- {
-- size = 0;
-+
-+ if (to >= subdev->size) {
-+ size = 0;
- to -= subdev->size;
-+ continue;
- }
-+ if (to + len > subdev->size)
-+ size = subdev->size - to;
- else
-- {
-- if (to + len > subdev->size)
-- size = subdev->size - to;
-- else
-- size = len;
-+ size = len;
-
-- if (!(subdev->flags & MTD_WRITEABLE))
-- err = -EROFS;
-- else if (subdev->write_ecc)
-- err = subdev->write_ecc(subdev, to, size, &retsize, buf, eccbuf, oobsel);
-- else
-- err = -EINVAL;
-+ if (!(subdev->flags & MTD_WRITEABLE))
-+ err = -EROFS;
-+ else if (subdev->write_ecc)
-+ err = subdev->write_ecc(subdev, to, size,
-+ &retsize, buf, eccbuf, oobsel);
-+ else
-+ err = -EINVAL;
-
-- if(err)
-- break;
-+ if (err)
-+ break;
-
-- *retlen += retsize;
-- len -= size;
-- if(len == 0)
-- break;
-+ *retlen += retsize;
-+ len -= size;
-+ if (len == 0)
-+ break;
-
-- err = -EINVAL;
-- buf += size;
-- if (eccbuf)
-- eccbuf += subdev->oobsize;
-- to = 0;
-- }
-+ err = -EINVAL;
-+ buf += size;
-+ if (eccbuf)
-+ eccbuf += subdev->oobsize;
-+ to = 0;
- }
- return err;
- }
-
--static int concat_read_oob (struct mtd_info *mtd, loff_t from, size_t len,
-- size_t *retlen, u_char *buf)
-+static int
-+concat_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t * retlen, u_char * buf)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- int err = -EINVAL;
-@@ -261,46 +259,47 @@
-
- *retlen = 0;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- size_t size, retsize;
--
-- if (from >= subdev->size)
-- { /* Not destined for this subdev */
-- size = 0;
-+
-+ if (from >= subdev->size) {
-+ /* Not destined for this subdev */
-+ size = 0;
- from -= subdev->size;
-+ continue;
- }
-+ if (from + len > subdev->size)
-+ /* First part goes into this subdev */
-+ size = subdev->size - from;
- else
-- {
-- if (from + len > subdev->size)
-- size = subdev->size - from; /* First part goes into this subdev */
-- else
-- size = len; /* Entire transaction goes into this subdev */
--
-- if (subdev->read_oob)
-- err = subdev->read_oob(subdev, from, size, &retsize, buf);
-- else
-- err = -EINVAL;
-+ /* Entire transaction goes into this subdev */
-+ size = len;
-
-- if(err)
-- break;
-+ if (subdev->read_oob)
-+ err = subdev->read_oob(subdev, from, size,
-+ &retsize, buf);
-+ else
-+ err = -EINVAL;
-
-- *retlen += retsize;
-- len -= size;
-- if(len == 0)
-- break;
-+ if (err)
-+ break;
-
-- err = -EINVAL;
-- buf += size;
-- from = 0;
-- }
-+ *retlen += retsize;
-+ len -= size;
-+ if (len == 0)
-+ break;
-+
-+ err = -EINVAL;
-+ buf += size;
-+ from = 0;
- }
- return err;
- }
-
--static int concat_write_oob (struct mtd_info *mtd, loff_t to, size_t len,
-- size_t *retlen, const u_char *buf)
-+static int
-+concat_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t * retlen, const u_char * buf)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- int err = -EINVAL;
-@@ -311,50 +310,46 @@
-
- *retlen = 0;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- size_t size, retsize;
--
-- if (to >= subdev->size)
-- {
-- size = 0;
-+
-+ if (to >= subdev->size) {
-+ size = 0;
- to -= subdev->size;
-+ continue;
- }
-+ if (to + len > subdev->size)
-+ size = subdev->size - to;
- else
-- {
-- if (to + len > subdev->size)
-- size = subdev->size - to;
-- else
-- size = len;
-+ size = len;
-
-- if (!(subdev->flags & MTD_WRITEABLE))
-- err = -EROFS;
-- else if (subdev->write_oob)
-- err = subdev->write_oob(subdev, to, size, &retsize, buf);
-- else
-- err = -EINVAL;
-+ if (!(subdev->flags & MTD_WRITEABLE))
-+ err = -EROFS;
-+ else if (subdev->write_oob)
-+ err = subdev->write_oob(subdev, to, size, &retsize,
-+ buf);
-+ else
-+ err = -EINVAL;
-
-- if(err)
-- break;
-+ if (err)
-+ break;
-
-- *retlen += retsize;
-- len -= size;
-- if(len == 0)
-- break;
-+ *retlen += retsize;
-+ len -= size;
-+ if (len == 0)
-+ break;
-
-- err = -EINVAL;
-- buf += size;
-- to = 0;
-- }
-+ err = -EINVAL;
-+ buf += size;
-+ to = 0;
- }
- return err;
- }
-
--
--static void concat_erase_callback (struct erase_info *instr)
-+static void concat_erase_callback(struct erase_info *instr)
- {
-- wake_up((wait_queue_head_t *)instr->priv);
-+ wake_up((wait_queue_head_t *) instr->priv);
- }
-
- static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase)
-@@ -370,18 +365,18 @@
-
- erase->mtd = mtd;
- erase->callback = concat_erase_callback;
-- erase->priv = (unsigned long)&waitq;
--
-+ erase->priv = (unsigned long) &waitq;
-+
- /*
- * FIXME: Allow INTERRUPTIBLE. Which means
- * not having the wait_queue head on the stack.
- */
- err = mtd->erase(mtd, erase);
-- if (!err)
-- {
-+ if (!err) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&waitq, &wait);
-- if (erase->state != MTD_ERASE_DONE && erase->state != MTD_ERASE_FAILED)
-+ if (erase->state != MTD_ERASE_DONE
-+ && erase->state != MTD_ERASE_FAILED)
- schedule();
- remove_wait_queue(&waitq, &wait);
- set_current_state(TASK_RUNNING);
-@@ -391,7 +386,7 @@
- return err;
- }
-
--static int concat_erase (struct mtd_info *mtd, struct erase_info *instr)
-+static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- struct mtd_info *subdev;
-@@ -402,10 +397,10 @@
- if (!(mtd->flags & MTD_WRITEABLE))
- return -EROFS;
-
-- if(instr->addr > concat->mtd.size)
-+ if (instr->addr > concat->mtd.size)
- return -EINVAL;
-
-- if(instr->len + instr->addr > concat->mtd.size)
-+ if (instr->len + instr->addr > concat->mtd.size)
- return -EINVAL;
-
- /*
-@@ -414,23 +409,22 @@
- * region info rather than looking at each particular sub-device
- * in turn.
- */
-- if (!concat->mtd.numeraseregions)
-- { /* the easy case: device has uniform erase block size */
-- if(instr->addr & (concat->mtd.erasesize - 1))
-+ if (!concat->mtd.numeraseregions) {
-+ /* the easy case: device has uniform erase block size */
-+ if (instr->addr & (concat->mtd.erasesize - 1))
- return -EINVAL;
-- if(instr->len & (concat->mtd.erasesize - 1))
-+ if (instr->len & (concat->mtd.erasesize - 1))
- return -EINVAL;
-- }
-- else
-- { /* device has variable erase size */
-- struct mtd_erase_region_info *erase_regions = concat->mtd.eraseregions;
-+ } else {
-+ /* device has variable erase size */
-+ struct mtd_erase_region_info *erase_regions =
-+ concat->mtd.eraseregions;
-
- /*
- * Find the erase region where the to-be-erased area begins:
- */
-- for(i = 0; i < concat->mtd.numeraseregions &&
-- instr->addr >= erase_regions[i].offset; i++)
-- ;
-+ for (i = 0; i < concat->mtd.numeraseregions &&
-+ instr->addr >= erase_regions[i].offset; i++) ;
- --i;
-
- /*
-@@ -438,25 +432,26 @@
- * to-be-erased area begins. Verify that the starting
- * offset is aligned to this region's erase size:
- */
-- if (instr->addr & (erase_regions[i].erasesize-1))
-+ if (instr->addr & (erase_regions[i].erasesize - 1))
- return -EINVAL;
-
- /*
- * now find the erase region where the to-be-erased area ends:
- */
-- for(; i < concat->mtd.numeraseregions &&
-- (instr->addr + instr->len) >= erase_regions[i].offset ; ++i)
-- ;
-+ for (; i < concat->mtd.numeraseregions &&
-+ (instr->addr + instr->len) >= erase_regions[i].offset;
-+ ++i) ;
- --i;
- /*
- * check if the ending offset is aligned to this region's erase size
- */
-- if ((instr->addr + instr->len) & (erase_regions[i].erasesize-1))
-+ if ((instr->addr + instr->len) & (erase_regions[i].erasesize -
-+ 1))
- return -EINVAL;
- }
-
- /* make a local copy of instr to avoid modifying the caller's struct */
-- erase = kmalloc(sizeof(struct erase_info),GFP_KERNEL);
-+ erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL);
-
- if (!erase)
- return -ENOMEM;
-@@ -468,39 +463,40 @@
- * find the subdevice where the to-be-erased area begins, adjust
- * starting offset to be relative to the subdevice start
- */
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- subdev = concat->subdev[i];
-- if(subdev->size <= erase->addr)
-+ if (subdev->size <= erase->addr)
- erase->addr -= subdev->size;
- else
- break;
-- }
-- if(i >= concat->num_subdev) /* must never happen since size */
-- BUG(); /* limit has been verified above */
-+ }
-+
-+ /* must never happen since size limit has been verified above */
-+ if (i >= concat->num_subdev)
-+ BUG();
-
- /* now do the erase: */
- err = 0;
-- for(;length > 0; i++) /* loop for all subevices affected by this request */
-- {
-- subdev = concat->subdev[i]; /* get current subdevice */
-+ for (; length > 0; i++) {
-+ /* loop for all subdevices affected by this request */
-+ subdev = concat->subdev[i]; /* get current subdevice */
-
- /* limit length to subdevice's size: */
-- if(erase->addr + length > subdev->size)
-+ if (erase->addr + length > subdev->size)
- erase->len = subdev->size - erase->addr;
- else
- erase->len = length;
-
-- if (!(subdev->flags & MTD_WRITEABLE))
-- {
-+ if (!(subdev->flags & MTD_WRITEABLE)) {
- err = -EROFS;
- break;
- }
- length -= erase->len;
-- if ((err = concat_dev_erase(subdev, erase)))
-- {
-- if(err == -EINVAL) /* sanity check: must never happen since */
-- BUG(); /* block alignment has been checked above */
-+ if ((err = concat_dev_erase(subdev, erase))) {
-+ /* sanity check: should never happen since
-+ * block alignment has been checked above */
-+ if (err == -EINVAL)
-+ BUG();
- break;
- }
- /*
-@@ -523,85 +519,79 @@
- return 0;
- }
-
--static int concat_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
-+static int concat_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- int i, err = -EINVAL;
-
-- if ((len + ofs) > mtd->size)
-+ if ((len + ofs) > mtd->size)
- return -EINVAL;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- size_t size;
-
-- if (ofs >= subdev->size)
-- {
-- size = 0;
-+ if (ofs >= subdev->size) {
-+ size = 0;
- ofs -= subdev->size;
-+ continue;
- }
-+ if (ofs + len > subdev->size)
-+ size = subdev->size - ofs;
- else
-- {
-- if (ofs + len > subdev->size)
-- size = subdev->size - ofs;
-- else
-- size = len;
-+ size = len;
-
-- err = subdev->lock(subdev, ofs, size);
-+ err = subdev->lock(subdev, ofs, size);
-
-- if(err)
-- break;
-+ if (err)
-+ break;
-
-- len -= size;
-- if(len == 0)
-- break;
-+ len -= size;
-+ if (len == 0)
-+ break;
-
-- err = -EINVAL;
-- ofs = 0;
-- }
-+ err = -EINVAL;
-+ ofs = 0;
- }
-+
- return err;
- }
-
--static int concat_unlock (struct mtd_info *mtd, loff_t ofs, size_t len)
-+static int concat_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- int i, err = 0;
-
-- if ((len + ofs) > mtd->size)
-+ if ((len + ofs) > mtd->size)
- return -EINVAL;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- size_t size;
-
-- if (ofs >= subdev->size)
-- {
-- size = 0;
-+ if (ofs >= subdev->size) {
-+ size = 0;
- ofs -= subdev->size;
-+ continue;
- }
-+ if (ofs + len > subdev->size)
-+ size = subdev->size - ofs;
- else
-- {
-- if (ofs + len > subdev->size)
-- size = subdev->size - ofs;
-- else
-- size = len;
-+ size = len;
-
-- err = subdev->unlock(subdev, ofs, size);
-+ err = subdev->unlock(subdev, ofs, size);
-
-- if(err)
-- break;
-+ if (err)
-+ break;
-
-- len -= size;
-- if(len == 0)
-- break;
-+ len -= size;
-+ if (len == 0)
-+ break;
-
-- err = -EINVAL;
-- ofs = 0;
-- }
-+ err = -EINVAL;
-+ ofs = 0;
- }
-+
- return err;
- }
-
-@@ -610,8 +600,7 @@
- struct mtd_concat *concat = CONCAT(mtd);
- int i;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- subdev->sync(subdev);
- }
-@@ -622,10 +611,9 @@
- struct mtd_concat *concat = CONCAT(mtd);
- int i, rc = 0;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
-- if((rc = subdev->suspend(subdev)) < 0)
-+ if ((rc = subdev->suspend(subdev)) < 0)
- return rc;
- }
- return rc;
-@@ -636,8 +624,7 @@
- struct mtd_concat *concat = CONCAT(mtd);
- int i;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- subdev->resume(subdev);
- }
-@@ -649,11 +636,10 @@
- * stored to *new_dev upon success. This function does _not_
- * register any devices: this is the caller's responsibility.
- */
--struct mtd_info *mtd_concat_create(
-- struct mtd_info *subdev[], /* subdevices to concatenate */
-- int num_devs, /* number of subdevices */
-- char *name) /* name for the new device */
--{
-+struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to concatenate */
-+ int num_devs, /* number of subdevices */
-+ char *name)
-+{ /* name for the new device */
- int i;
- size_t size;
- struct mtd_concat *concat;
-@@ -661,94 +647,103 @@
- int num_erase_region;
-
- printk(KERN_NOTICE "Concatenating MTD devices:\n");
-- for(i = 0; i < num_devs; i++)
-+ for (i = 0; i < num_devs; i++)
- printk(KERN_NOTICE "(%d): \"%s\"\n", i, subdev[i]->name);
- printk(KERN_NOTICE "into device \"%s\"\n", name);
-
- /* allocate the device structure */
- size = SIZEOF_STRUCT_MTD_CONCAT(num_devs);
-- concat = kmalloc (size, GFP_KERNEL);
-- if(!concat)
-- {
-- printk ("memory allocation error while creating concatenated device \"%s\"\n",
-- name);
-- return NULL;
-+ concat = kmalloc(size, GFP_KERNEL);
-+ if (!concat) {
-+ printk
-+ ("memory allocation error while creating concatenated device \"%s\"\n",
-+ name);
-+ return NULL;
- }
- memset(concat, 0, size);
-- concat->subdev = (struct mtd_info **)(concat + 1);
-+ concat->subdev = (struct mtd_info **) (concat + 1);
-
- /*
- * Set up the new "super" device's MTD object structure, check for
- * incompatibilites between the subdevices.
- */
-- concat->mtd.type = subdev[0]->type;
-- concat->mtd.flags = subdev[0]->flags;
-- concat->mtd.size = subdev[0]->size;
-+ concat->mtd.type = subdev[0]->type;
-+ concat->mtd.flags = subdev[0]->flags;
-+ concat->mtd.size = subdev[0]->size;
- concat->mtd.erasesize = subdev[0]->erasesize;
-- concat->mtd.oobblock = subdev[0]->oobblock;
-- concat->mtd.oobsize = subdev[0]->oobsize;
-- concat->mtd.ecctype = subdev[0]->ecctype;
-- concat->mtd.eccsize = subdev[0]->eccsize;
-+ concat->mtd.oobblock = subdev[0]->oobblock;
-+ concat->mtd.oobsize = subdev[0]->oobsize;
-+ concat->mtd.ecctype = subdev[0]->ecctype;
-+ concat->mtd.eccsize = subdev[0]->eccsize;
-+ if (subdev[0]->read_ecc)
-+ concat->mtd.read_ecc = concat_read_ecc;
-+ if (subdev[0]->write_ecc)
-+ concat->mtd.write_ecc = concat_write_ecc;
-+ if (subdev[0]->read_oob)
-+ concat->mtd.read_oob = concat_read_oob;
-+ if (subdev[0]->write_oob)
-+ concat->mtd.write_oob = concat_write_oob;
-
-- concat->subdev[0] = subdev[0];
-+ concat->subdev[0] = subdev[0];
-
-- for(i = 1; i < num_devs; i++)
-- {
-- if(concat->mtd.type != subdev[i]->type)
-- {
-+ for (i = 1; i < num_devs; i++) {
-+ if (concat->mtd.type != subdev[i]->type) {
- kfree(concat);
-- printk ("Incompatible device type on \"%s\"\n", subdev[i]->name);
-+ printk("Incompatible device type on \"%s\"\n",
-+ subdev[i]->name);
- return NULL;
- }
-- if(concat->mtd.flags != subdev[i]->flags)
-- { /*
-- * Expect all flags except MTD_WRITEABLE to be equal on
-- * all subdevices.
-+ if (concat->mtd.flags != subdev[i]->flags) {
-+ /*
-+ * Expect all flags except MTD_WRITEABLE to be
-+ * equal on all subdevices.
- */
-- if((concat->mtd.flags ^ subdev[i]->flags) & ~MTD_WRITEABLE)
-- {
-+ if ((concat->mtd.flags ^ subdev[i]->
-+ flags) & ~MTD_WRITEABLE) {
- kfree(concat);
-- printk ("Incompatible device flags on \"%s\"\n", subdev[i]->name);
-+ printk("Incompatible device flags on \"%s\"\n",
-+ subdev[i]->name);
- return NULL;
-- }
-- else /* if writeable attribute differs, make super device writeable */
-- concat->mtd.flags |= subdev[i]->flags & MTD_WRITEABLE;
-+ } else
-+ /* if writeable attribute differs,
-+ make super device writeable */
-+ concat->mtd.flags |=
-+ subdev[i]->flags & MTD_WRITEABLE;
- }
- concat->mtd.size += subdev[i]->size;
-- if(concat->mtd.oobblock != subdev[i]->oobblock ||
-- concat->mtd.oobsize != subdev[i]->oobsize ||
-- concat->mtd.ecctype != subdev[i]->ecctype ||
-- concat->mtd.eccsize != subdev[i]->eccsize)
-- {
-+ if (concat->mtd.oobblock != subdev[i]->oobblock ||
-+ concat->mtd.oobsize != subdev[i]->oobsize ||
-+ concat->mtd.ecctype != subdev[i]->ecctype ||
-+ concat->mtd.eccsize != subdev[i]->eccsize ||
-+ !concat->mtd.read_ecc != !subdev[i]->read_ecc ||
-+ !concat->mtd.write_ecc != !subdev[i]->write_ecc ||
-+ !concat->mtd.read_oob != !subdev[i]->read_oob ||
-+ !concat->mtd.write_oob != !subdev[i]->write_oob) {
- kfree(concat);
-- printk ("Incompatible OOB or ECC data on \"%s\"\n", subdev[i]->name);
-+ printk("Incompatible OOB or ECC data on \"%s\"\n",
-+ subdev[i]->name);
- return NULL;
- }
- concat->subdev[i] = subdev[i];
--
-+
- }
-
-- concat->num_subdev = num_devs;
-- concat->mtd.name = name;
-+ concat->num_subdev = num_devs;
-+ concat->mtd.name = name;
-
- /*
- * NOTE: for now, we do not provide any readv()/writev() methods
- * because they are messy to implement and they are not
- * used to a great extent anyway.
- */
-- concat->mtd.erase = concat_erase;
-- concat->mtd.read = concat_read;
-- concat->mtd.write = concat_write;
-- concat->mtd.read_ecc = concat_read_ecc;
-- concat->mtd.write_ecc = concat_write_ecc;
-- concat->mtd.read_oob = concat_read_oob;
-- concat->mtd.write_oob = concat_write_oob;
-- concat->mtd.sync = concat_sync;
-- concat->mtd.lock = concat_lock;
-- concat->mtd.unlock = concat_unlock;
-- concat->mtd.suspend = concat_suspend;
-- concat->mtd.resume = concat_resume;
--
-+ concat->mtd.erase = concat_erase;
-+ concat->mtd.read = concat_read;
-+ concat->mtd.write = concat_write;
-+ concat->mtd.sync = concat_sync;
-+ concat->mtd.lock = concat_lock;
-+ concat->mtd.unlock = concat_unlock;
-+ concat->mtd.suspend = concat_suspend;
-+ concat->mtd.resume = concat_resume;
-
- /*
- * Combine the erase block size info of the subdevices:
-@@ -758,44 +753,44 @@
- */
- max_erasesize = curr_erasesize = subdev[0]->erasesize;
- num_erase_region = 1;
-- for(i = 0; i < num_devs; i++)
-- {
-- if(subdev[i]->numeraseregions == 0)
-- { /* current subdevice has uniform erase size */
-- if(subdev[i]->erasesize != curr_erasesize)
-- { /* if it differs from the last subdevice's erase size, count it */
-+ for (i = 0; i < num_devs; i++) {
-+ if (subdev[i]->numeraseregions == 0) {
-+ /* current subdevice has uniform erase size */
-+ if (subdev[i]->erasesize != curr_erasesize) {
-+ /* if it differs from the last subdevice's erase size, count it */
- ++num_erase_region;
- curr_erasesize = subdev[i]->erasesize;
-- if(curr_erasesize > max_erasesize)
-+ if (curr_erasesize > max_erasesize)
- max_erasesize = curr_erasesize;
- }
-- }
-- else
-- { /* current subdevice has variable erase size */
-+ } else {
-+ /* current subdevice has variable erase size */
- int j;
-- for(j = 0; j < subdev[i]->numeraseregions; j++)
-- { /* walk the list of erase regions, count any changes */
-- if(subdev[i]->eraseregions[j].erasesize != curr_erasesize)
-- {
-+ for (j = 0; j < subdev[i]->numeraseregions; j++) {
-+
-+ /* walk the list of erase regions, count any changes */
-+ if (subdev[i]->eraseregions[j].erasesize !=
-+ curr_erasesize) {
- ++num_erase_region;
-- curr_erasesize = subdev[i]->eraseregions[j].erasesize;
-- if(curr_erasesize > max_erasesize)
-+ curr_erasesize =
-+ subdev[i]->eraseregions[j].
-+ erasesize;
-+ if (curr_erasesize > max_erasesize)
- max_erasesize = curr_erasesize;
- }
- }
- }
- }
-
-- if(num_erase_region == 1)
-- { /*
-+ if (num_erase_region == 1) {
-+ /*
- * All subdevices have the same uniform erase size.
- * This is easy:
- */
- concat->mtd.erasesize = curr_erasesize;
- concat->mtd.numeraseregions = 0;
-- }
-- else
-- { /*
-+ } else {
-+ /*
- * erase block size varies across the subdevices: allocate
- * space to store the data describing the variable erase regions
- */
-@@ -804,13 +799,14 @@
-
- concat->mtd.erasesize = max_erasesize;
- concat->mtd.numeraseregions = num_erase_region;
-- concat->mtd.eraseregions = erase_region_p = kmalloc (
-- num_erase_region * sizeof(struct mtd_erase_region_info), GFP_KERNEL);
-- if(!erase_region_p)
-- {
-+ concat->mtd.eraseregions = erase_region_p =
-+ kmalloc(num_erase_region *
-+ sizeof (struct mtd_erase_region_info), GFP_KERNEL);
-+ if (!erase_region_p) {
- kfree(concat);
-- printk ("memory allocation error while creating erase region list"
-- " for device \"%s\"\n", name);
-+ printk
-+ ("memory allocation error while creating erase region list"
-+ " for device \"%s\"\n", name);
- return NULL;
- }
-
-@@ -820,46 +816,53 @@
- */
- curr_erasesize = subdev[0]->erasesize;
- begin = position = 0;
-- for(i = 0; i < num_devs; i++)
-- {
-- if(subdev[i]->numeraseregions == 0)
-- { /* current subdevice has uniform erase size */
-- if(subdev[i]->erasesize != curr_erasesize)
-- { /*
-+ for (i = 0; i < num_devs; i++) {
-+ if (subdev[i]->numeraseregions == 0) {
-+ /* current subdevice has uniform erase size */
-+ if (subdev[i]->erasesize != curr_erasesize) {
-+ /*
- * fill in an mtd_erase_region_info structure for the area
- * we have walked so far:
- */
-- erase_region_p->offset = begin;
-- erase_region_p->erasesize = curr_erasesize;
-- erase_region_p->numblocks = (position - begin) / curr_erasesize;
-+ erase_region_p->offset = begin;
-+ erase_region_p->erasesize =
-+ curr_erasesize;
-+ erase_region_p->numblocks =
-+ (position - begin) / curr_erasesize;
- begin = position;
-
- curr_erasesize = subdev[i]->erasesize;
- ++erase_region_p;
- }
- position += subdev[i]->size;
-- }
-- else
-- { /* current subdevice has variable erase size */
-+ } else {
-+ /* current subdevice has variable erase size */
- int j;
-- for(j = 0; j < subdev[i]->numeraseregions; j++)
-- { /* walk the list of erase regions, count any changes */
-- if(subdev[i]->eraseregions[j].erasesize != curr_erasesize)
-- {
-- erase_region_p->offset = begin;
-- erase_region_p->erasesize = curr_erasesize;
-- erase_region_p->numblocks = (position - begin) / curr_erasesize;
-+ for (j = 0; j < subdev[i]->numeraseregions; j++) {
-+ /* walk the list of erase regions, count any changes */
-+ if (subdev[i]->eraseregions[j].
-+ erasesize != curr_erasesize) {
-+ erase_region_p->offset = begin;
-+ erase_region_p->erasesize =
-+ curr_erasesize;
-+ erase_region_p->numblocks =
-+ (position -
-+ begin) / curr_erasesize;
- begin = position;
-
-- curr_erasesize = subdev[i]->eraseregions[j].erasesize;
-+ curr_erasesize =
-+ subdev[i]->eraseregions[j].
-+ erasesize;
- ++erase_region_p;
- }
-- position += subdev[i]->eraseregions[j].numblocks * curr_erasesize;
-+ position +=
-+ subdev[i]->eraseregions[j].
-+ numblocks * curr_erasesize;
- }
- }
- }
- /* Now write the final entry */
-- erase_region_p->offset = begin;
-+ erase_region_p->offset = begin;
- erase_region_p->erasesize = curr_erasesize;
- erase_region_p->numblocks = (position - begin) / curr_erasesize;
- }
-@@ -874,16 +877,14 @@
- void mtd_concat_destroy(struct mtd_info *mtd)
- {
- struct mtd_concat *concat = CONCAT(mtd);
-- if(concat->mtd.numeraseregions)
-+ if (concat->mtd.numeraseregions)
- kfree(concat->mtd.eraseregions);
- kfree(concat);
- }
-
--
- EXPORT_SYMBOL(mtd_concat_create);
- EXPORT_SYMBOL(mtd_concat_destroy);
-
--
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Robert Kaiser <rkaiser@sysgo.de>");
- MODULE_DESCRIPTION("Generic support for concatenating of MTD devices");
---- linux-2.6.5/drivers/mtd/maps/Makefile~heh 2004-04-03 22:36:12.000000000 -0500
-+++ linux-2.6.5/drivers/mtd/maps/Makefile 2004-04-30 20:57:36.000000000 -0400
-@@ -17,12 +17,14 @@
- obj-$(CONFIG_MTD_ELAN_104NC) += elan-104nc.o
- obj-$(CONFIG_MTD_EPXA10DB) += epxa10db-flash.o
- obj-$(CONFIG_MTD_IQ80310) += iq80310.o
-+obj-$(CONFIG_MTD_IQ80321) += iq80321.o
- obj-$(CONFIG_MTD_L440GX) += l440gx.o
- obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o
- obj-$(CONFIG_MTD_ICH2ROM) += ich2rom.o
- obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o
- obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o
- obj-$(CONFIG_MTD_MBX860) += mbx860.o
-+obj-$(CONFIG_MTD_NORA) += nora.o
- obj-$(CONFIG_MTD_CEIVA) += ceiva.o
- obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o
- obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
---- linux-2.6.5/drivers/mtd/maps/sa1100-flash.c~heh 2004-04-03 22:36:51.000000000 -0500
-+++ linux-2.6.5/drivers/mtd/maps/sa1100-flash.c 2004-04-30 20:57:36.000000000 -0400
-@@ -14,6 +14,7 @@
- #include <linux/init.h>
- #include <linux/errno.h>
- #include <linux/slab.h>
-+#include <linux/device.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -887,6 +888,7 @@
- int width;
- void *vbase;
- void (*set_vpp)(struct map_info *, int);
-+ char name[16];
- struct map_info *map;
- struct mtd_info *mtd;
- struct resource *res;
-@@ -925,6 +927,8 @@
- }
-
- sa[i].map = maps + i;
-+ sa[i].map->name = sa[i].name;
-+ sprintf(sa[i].name, "sa1100-%d", i);
-
- sa[i].vbase = ioremap(sa[i].base, sa[i].size);
- if (!sa[i].vbase) {
-@@ -986,7 +990,7 @@
- */
- #ifdef CONFIG_MTD_CONCAT
- *rmtd = mtd_concat_create(subdev, found,
-- "sa1100 flash");
-+ "sa1100");
- if (*rmtd == NULL)
- ret = -ENXIO;
- #else
-@@ -1044,13 +1048,9 @@
- * - Is the MSC setup for flash (no -> failure)
- * - Probe for flash
- */
--
--static struct map_info sa1100_probe_map __initdata = {
-- .name = "SA1100-flash",
--};
--
--static void __init sa1100_probe_one_cs(unsigned int msc, unsigned long phys)
-+static void sa1100_probe_one_cs(unsigned int msc, unsigned long phys)
- {
-+ struct map_info map;
- struct mtd_info *mtd;
-
- printk(KERN_INFO "* Probing 0x%08lx: MSC = 0x%04x %d bit ",
-@@ -1066,19 +1066,23 @@
- return;
- }
-
-- sa1100_probe_map.buswidth = msc & MSC_RBW ? 2 : 4;
-- sa1100_probe_map.size = SZ_1M;
-- sa1100_probe_map.phys = phys;
-- sa1100_probe_map.virt = (unsigned long)ioremap(phys, SZ_1M);
-- if (sa1100_probe_map.virt == 0)
-+ memset(&map, 0, sizeof(map));
-+
-+ map.name = "Probe";
-+ map.buswidth = msc & MSC_RBW ? 2 : 4;
-+ map.size = SZ_1M;
-+ map.phys = NO_XIP;
-+ map.virt = (unsigned long)ioremap(phys, SZ_1M);
-+ if (map.virt == 0)
- goto fail;
-- simple_map_init(&sa1100_probe_map);
-+
-+ simple_map_init(&map);
-
- /* Shame cfi_probe blurts out kernel messages... */
-- mtd = do_map_probe("cfi_probe", &sa1100_probe_map);
-+ mtd = do_map_probe("cfi_probe", &map);
- if (mtd)
- map_destroy(mtd);
-- iounmap((void *)sa1100_probe_map.virt);
-+ iounmap((void *)map.virt);
-
- if (!mtd)
- goto fail;
-@@ -1090,7 +1094,7 @@
- printk("failed\n");
- }
-
--static void __init sa1100_probe_flash(void)
-+static void sa1100_probe_flash(void)
- {
- printk(KERN_INFO "-- SA11xx Flash probe. Please report results.\n");
- sa1100_probe_one_cs(MSC0, SA1100_CS0_PHYS);
-@@ -1321,10 +1325,9 @@
- kfree(parsed_parts);
- }
-
--static struct mtd_info *mymtd;
--
--static int __init sa1100_mtd_init(void)
-+static int __init sa1100_mtd_probe(struct device *dev)
- {
-+ struct mtd_info *mtd;
- int ret;
- int nr;
-
-@@ -1332,21 +1335,74 @@
- if (nr < 0)
- return nr;
-
-- ret = sa1100_setup_mtd(info, nr, &mymtd);
-- if (ret == 0)
-- sa1100_locate_partitions(mymtd);
-+ ret = sa1100_setup_mtd(info, nr, &mtd);
-+ if (ret == 0) {
-+ sa1100_locate_partitions(mtd);
-+ dev_set_drvdata(dev, mtd);
-+ }
-
- return ret;
- }
-
--static void __exit sa1100_mtd_cleanup(void)
-+static int __exit sa1100_mtd_remove(struct device *dev)
- {
-- sa1100_destroy_mtd(info, mymtd);
-+ struct mtd_info *mtd = dev_get_drvdata(dev);
-+ sa1100_destroy_mtd(info, mtd);
- sa1100_destroy_partitions();
-+ return 0;
-+}
-+
-+static int sa1100_mtd_suspend(struct device *dev, u32 level, u32 state)
-+{
-+ struct mtd_info *mtd = dev_get_drvdata(dev);
-+ if (level == SUSPEND_SAVE_STATE)
-+ mtd->suspend(mtd);
-+ return 0;
-+}
-+
-+static int sa1100_mtd_resume(struct device *dev, u32 level)
-+{
-+ struct mtd_info *mtd = dev_get_drvdata(dev);
-+ if (level == RESUME_RESTORE_STATE)
-+ mtd->resume(mtd);
-+ return 0;
-+}
-+
-+static struct platform_device sa1100_mtd_device = {
-+ .name = "flash",
-+ .id = 0,
-+};
-+
-+static struct device_driver sa1100_mtd_driver = {
-+ .name = "flash",
-+ .bus = &platform_bus_type,
-+ .probe = sa1100_mtd_probe,
-+#ifdef MODULE
-+ .remove = sa1100_mtd_remove,
-+#endif
-+ .suspend = sa1100_mtd_suspend,
-+ .resume = sa1100_mtd_resume,
-+};
-+
-+static int __init sa1100_mtd_init(void)
-+{
-+ int ret = driver_register(&sa1100_mtd_driver);
-+ if (ret == 0) {
-+ ret = platform_device_register(&sa1100_mtd_device);
-+ if (ret)
-+ driver_unregister(&sa1100_mtd_driver);
-+ }
-+ return ret;
-+}
-+
-+static void __exit sa1100_mtd_exit(void)
-+{
-+ platform_device_unregister(&sa1100_mtd_device);
-+ driver_unregister(&sa1100_mtd_driver);
- }
-
- module_init(sa1100_mtd_init);
--module_exit(sa1100_mtd_cleanup);
-+module_exit(sa1100_mtd_exit);
-
- MODULE_AUTHOR("Nicolas Pitre");
- MODULE_DESCRIPTION("SA1100 CFI map driver");
---- linux-2.6.5/drivers/mtd/maps/pcmciamtd.c~heh 2004-04-03 22:36:19.000000000 -0500
-+++ linux-2.6.5/drivers/mtd/maps/pcmciamtd.c 2004-04-30 20:57:36.000000000 -0400
-@@ -25,10 +25,9 @@
- #include <pcmcia/ds.h>
-
- #include <linux/mtd/map.h>
--#include <linux/mtd/mtd.h>
-
--#ifdef CONFIG_MTD_DEBUG
--static int debug = CONFIG_MTD_DEBUG_VERBOSE;
-+#if 1 //def CONFIG_MTD_DEBUG
-+static int debug = 5; //CONFIG_MTD_DEBUG_VERBOSE;
- MODULE_PARM(debug, "i");
- MODULE_PARM_DESC(debug, "Set Debug Level 0=quiet, 5=noisy");
- #undef DEBUG
-@@ -88,7 +87,7 @@
- static int setvpp;
-
- /* Force card to be treated as FLASH, ROM or RAM */
--static int mem_type;
-+static int mem_type = 1;
-
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>");
---- linux-2.6.5/drivers/mtd/maps/pci.c~heh 2004-04-03 22:36:56.000000000 -0500
-+++ linux-2.6.5/drivers/mtd/maps/pci.c 2004-04-30 20:57:36.000000000 -0400
-@@ -22,6 +22,8 @@
- #include <linux/mtd/map.h>
- #include <linux/mtd/partitions.h>
-
-+#include <asm/io.h>
-+
- struct map_pci_info;
-
- struct mtd_pci_info {
---- linux-2.6.5/drivers/input/Kconfig~heh 2004-04-03 22:36:18.000000000 -0500
-+++ linux-2.6.5/drivers/input/Kconfig 2004-04-30 20:57:36.000000000 -0400
-@@ -80,7 +80,7 @@
- module will be called joydev.
-
- config INPUT_TSDEV
-- tristate "Touchscreen interface"
-+ tristate "Compaq Touchscreen interface"
- depends on INPUT
- ---help---
- Say Y here if you have an application that only can understand the
-@@ -102,6 +102,10 @@
- depends on INPUT_TSDEV
- default "320"
-
-+config INPUT_TSLIBDEV
-+ tristate "TSLIB Touchscreen interface"
-+ depends on INPUT
-+
- config INPUT_EVDEV
- tristate "Event interface"
- depends on INPUT
---- linux-2.6.5/drivers/input/serio/Kconfig~heh 2004-04-03 22:37:07.000000000 -0500
-+++ linux-2.6.5/drivers/input/serio/Kconfig 2004-04-30 20:57:36.000000000 -0400
-@@ -80,7 +80,7 @@
-
- config SERIO_RPCKBD
- tristate "Acorn RiscPC keyboard controller"
-- depends on ARCH_ACORN && SERIO
-+ depends on (ARCH_ACORN || ARCH_CLPS7500) && SERIO
- default y
- help
- Say Y here if you have the Acorn RiscPC and want to use an AT
-@@ -89,6 +89,18 @@
- To compile this driver as a module, choose M here: the
- module will be called rpckbd.
-
-+config SERIO_CLPS7500
-+ tristate "CLPS7500 PS/2 mouse port controller"
-+ depends on ARCH_CLPS7500 && SERIO
-+ help
-+ Say Y here if you have CLPS7500 based hardware and want to use
-+ the mouse port.
-+
-+ This driver is also available as a module ( = code which can be
-+ inserted in and removed from the running kernel whenever you want).
-+ The module will be called clps7500ps2. If you want to compile it
-+ as a module, say M here and read <file:Documentation/modules.txt>.
-+
- config SERIO_AMBAKMI
- tristate "AMBA KMI keyboard controller"
- depends on ARCH_INTEGRATOR && SERIO
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/input/serio/sa1100ir.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,90 @@
-+/*
-+ * linux/drivers/input/serio/sa1100ir.c
-+ *
-+ * 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.
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/serio.h>
-+
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/hardware.h>
-+
-+
-+
-+struct sa1100_kbd {
-+ struct serio io;
-+ void *base;
-+ int irq;
-+};
-+
-+static void sa1100ir_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct sa1100_kbd *kbd = dev_id;
-+ unsigned int status;
-+
-+ do {
-+ unsigned int flag, data;
-+
-+ status = readl(kbd->base + UTSR1);
-+ if (!(status & UTSR1_RNE))
-+ break;
-+
-+ flag = (status & UTSR1_FRE ? SERIO_FRAME : 0) |
-+ (status & UTSR1_PRE ? SERIO_PARITY : 0);
-+
-+ data = readl(kbd->base + UTDR);
-+
-+ serio_interrupt(&kbd->io, data, flag);
-+ } while (1);
-+
-+ status = readl(kbd->base + UTSR0) & UTSR0_RID | UTSR0_RBB | UTSR0_REB;
-+ if (status)
-+ writel(status, kbd->base + UTSR0);
-+}
-+
-+static int sa1100ir_kbd_open(struct serio *io)
-+{
-+ struct sa1100_kbd *kbd = io->driver;
-+ int ret;
-+
-+ ret = request_irq(kbd->irq, sa1100ir_int, 0, kbd->io.phys, kbd);
-+ if (ret)
-+ return ret;
-+
-+ return 0;
-+}
-+
-+static void sa1100ir_kbd_close(struct serio *io)
-+{
-+ struct sa1100_kbd *kbd = io->driver;
-+
-+ free_irq(kbd->irq, kbd);
-+}
-+
-+static struct sa1100_kbd sa1100_kbd = {
-+ .io = {
-+ .type = 0,
-+ .open = sa1100ir_kbd_open,
-+ .close = sa1100ir_kbd_close,
-+ .name = "SA11x0 IR port",
-+ .phys = "sa11x0/ir",
-+ .driver = &sa1100_kbd,
-+ },
-+};
-+
-+static int __init sa1100_kbd_init(void)
-+{
-+ serio_register_port(&sa1100_kbd.io);
-+}
-+
-+static void __exit sa1100_kbd_exit(void)
-+{
-+ serio_unregister_port(&sa1100_kbd.io);
-+}
-+
-+module_init(sa1100_kbd_init);
-+module_exit(sa1100_kbd_exit);
---- linux-2.6.5/drivers/input/serio/Makefile~heh 2004-04-03 22:36:16.000000000 -0500
-+++ linux-2.6.5/drivers/input/serio/Makefile 2004-04-30 20:57:36.000000000 -0400
-@@ -10,6 +10,7 @@
- obj-$(CONFIG_SERIO_SERPORT) += serport.o
- obj-$(CONFIG_SERIO_CT82C710) += ct82c710.o
- obj-$(CONFIG_SERIO_RPCKBD) += rpckbd.o
-+obj-$(CONFIG_SERIO_CLPS7500) += clps7500ps2.o
- obj-$(CONFIG_SERIO_SA1111) += sa1111ps2.o
- obj-$(CONFIG_SERIO_AMBAKMI) += ambakmi.o
- obj-$(CONFIG_SERIO_Q40KBD) += q40kbd.o
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/input/tslibdev.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,358 @@
-+/*
-+ * linux/drivers/input/tslibdev.c
-+ *
-+ * Copyright (C) 2002 Russell King
-+ *
-+ * From tsdev.c:
-+ *
-+ * Copyright (c) 2001 "Crazy" james Simmons
-+ *
-+ * Input driver to Touchscreen device driver module.
-+ *
-+ * Sponsored by Transvirtual Technology
-+ */
-+
-+/*
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Should you need to contact me, the author, you can do so either by
-+ * e-mail - mail your message to <jsimmons@transvirtual.com>.
-+ */
-+
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/input.h>
-+#include <linux/config.h>
-+#include <linux/smp_lock.h>
-+#include <linux/random.h>
-+#include <linux/time.h>
-+#include <linux/list.h>
-+#include <linux/miscdevice.h>
-+
-+struct ucb1x00_dev {
-+ int exist;
-+ char name[16];
-+ wait_queue_head_t wait;
-+ struct list_head list;
-+ struct input_handle handle;
-+ int x;
-+ int y;
-+ int pressure;
-+};
-+
-+struct ts_event {
-+ u16 pressure;
-+ u16 x;
-+ u16 y;
-+ u16 pad;
-+ struct timeval stamp;
-+};
-+
-+#define TSDEV_BUFFER_SIZE 64
-+
-+struct ucb1x00_list {
-+ struct list_head list;
-+ struct fasync_struct *fasync;
-+ struct ucb1x00_dev *tsdev;
-+ unsigned int head;
-+ unsigned int tail;
-+ struct ts_event event[TSDEV_BUFFER_SIZE];
-+};
-+
-+static struct input_handler ucb1x00_handler;
-+static struct ucb1x00_dev *ucb1x00_dev;
-+
-+static void ucb1x00_remove(struct ucb1x00_dev *tsdev);
-+
-+
-+static int ucb1x00_fasync(int fd, struct file *file, int on)
-+{
-+ struct ucb1x00_list *list = file->private_data;
-+ int retval;
-+
-+ retval = fasync_helper(fd, file, on, &list->fasync);
-+ return retval < 0 ? retval : 0;
-+}
-+
-+static int ucb1x00_open(struct inode *inode, struct file *file)
-+{
-+ struct ucb1x00_list *list;
-+ int empty;
-+
-+ if (!ucb1x00_dev || !ucb1x00_dev->exist)
-+ return -ENODEV;
-+
-+ printk(KERN_WARNING
-+ "tslibdev: process %s (%d) uses obsolete tslib device\n",
-+ current->comm, current->pid);
-+
-+ list = kmalloc(sizeof(struct ucb1x00_list), GFP_KERNEL);
-+ if (!list)
-+ return -ENOMEM;
-+
-+ memset(list, 0, sizeof(struct ucb1x00_list));
-+
-+ empty = list_empty(&ucb1x00_dev->list);
-+
-+ list->tsdev = ucb1x00_dev;
-+ list_add(&list->list, &list->tsdev->list);
-+
-+ file->private_data = list;
-+
-+ if (empty && list->tsdev->exist)
-+ input_open_device(&list->tsdev->handle);
-+
-+ return 0;
-+}
-+
-+static int ucb1x00_release(struct inode *inode, struct file *file)
-+{
-+ struct ucb1x00_list *list = file->private_data;
-+
-+ ucb1x00_fasync(-1, file, 0);
-+
-+ list_del(&list->list);
-+
-+ ucb1x00_remove(list->tsdev);
-+
-+ kfree(list);
-+
-+ return 0;
-+}
-+
-+static ssize_t
-+ucb1x00_read(struct file *file, char *buffer, size_t count, loff_t * ppos)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct ucb1x00_list *list = file->private_data;
-+ int retval = 0;
-+
-+ if (list->head == list->tail) {
-+ add_wait_queue(&list->tsdev->wait, &wait);
-+
-+ while (list->head == list->tail) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (!list->tsdev->exist) {
-+ retval = -ENODEV;
-+ break;
-+ }
-+ if (file->f_flags & O_NONBLOCK) {
-+ retval = -EAGAIN;
-+ break;
-+ }
-+ if (signal_pending(current)) {
-+ retval = -ERESTARTSYS;
-+ break;
-+ }
-+ schedule();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&list->tsdev->wait, &wait);
-+ }
-+
-+ if (retval)
-+ return retval;
-+
-+ while (list->head != list->tail && count >= sizeof(struct ts_event)) {
-+ if (copy_to_user(buffer, list->event + list->tail,
-+ sizeof(struct ts_event)))
-+ return retval ? retval : -EFAULT;
-+ list->tail = (list->tail + 1) & (TSDEV_BUFFER_SIZE - 1);
-+ retval += sizeof(struct ts_event);
-+ buffer += sizeof(struct ts_event);
-+ count -= sizeof(struct ts_event);
-+ }
-+ return retval;
-+}
-+
-+/* No kernel lock - fine */
-+static unsigned int ucb1x00_poll(struct file *file, poll_table * wait)
-+{
-+ struct ucb1x00_list *list = file->private_data;
-+
-+ poll_wait(file, &list->tsdev->wait, wait);
-+ if (list->head != list->tail || !list->tsdev->exist)
-+ return POLLIN | POLLRDNORM;
-+ return 0;
-+}
-+
-+static int
-+ucb1x00_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-+ unsigned long arg)
-+{
-+ return -EINVAL;
-+}
-+
-+struct file_operations ucb1x00_fops = {
-+ .owner = THIS_MODULE,
-+ .open = ucb1x00_open,
-+ .release = ucb1x00_release,
-+ .read = ucb1x00_read,
-+ .poll = ucb1x00_poll,
-+ .fasync = ucb1x00_fasync,
-+ .ioctl = ucb1x00_ioctl,
-+};
-+
-+/*
-+ * The official UCB1x00 touchscreen is a miscdevice:
-+ * 10 char Non-serial mice, misc features
-+ * 14 = /dev/touchscreen/ucb1x00 UCB 1x00 touchscreen
-+ */
-+static struct miscdevice ucb1x00_ts_dev = {
-+ .minor = 14,
-+ .name = "touchscreen/ucb1x00",
-+ .fops = &ucb1x00_fops,
-+ .devfs_name = "touchscreen/ucb1x00",
-+};
-+
-+static void ucb1x00_remove(struct ucb1x00_dev *tsdev)
-+{
-+ if (list_empty(&tsdev->list)) {
-+ if (tsdev->exist) {
-+ input_close_device(&tsdev->handle);
-+ wake_up_interruptible(&tsdev->wait);
-+ } else {
-+ misc_deregister(&ucb1x00_ts_dev);
-+ ucb1x00_dev = NULL;
-+ kfree(tsdev);
-+ }
-+ }
-+}
-+
-+
-+static void
-+ucb1x00_event(struct input_handle *handle, unsigned int type, unsigned int code,
-+ int value)
-+{
-+ struct ucb1x00_dev *tsdev = handle->private;
-+ struct list_head *l;
-+
-+ /* sorry, we only handle absolute stuff */
-+ if (type == EV_ABS) {
-+ switch (code) {
-+ case ABS_X:
-+ tsdev->x = value;
-+ break;
-+ case ABS_Y:
-+ tsdev->y = value;
-+ break;
-+ case ABS_PRESSURE:
-+ tsdev->pressure = value;
-+ break;
-+ }
-+ return;
-+ }
-+
-+ if (type != EV_SYN || code != SYN_REPORT)
-+ return;
-+
-+ list_for_each(l, &tsdev->list) {
-+ struct ucb1x00_list *list = list_entry(l, struct ucb1x00_list, list);
-+ list->event[list->head].pressure = tsdev->pressure;
-+ if (tsdev->pressure) {
-+ list->event[list->head].x = tsdev->x;
-+ list->event[list->head].y = tsdev->y;
-+ } else {
-+ list->event[list->head].x = 0;
-+ list->event[list->head].y = 0;
-+ }
-+ do_gettimeofday(&list->event[list->head].stamp);
-+ list->head = (list->head + 1) & (TSDEV_BUFFER_SIZE - 1);
-+ kill_fasync(&list->fasync, SIGIO, POLL_IN);
-+ }
-+ wake_up_interruptible(&tsdev->wait);
-+}
-+
-+static struct input_handle *
-+ucb1x00_connect(struct input_handler *handler, struct input_dev *dev,
-+ struct input_device_id *id)
-+{
-+ struct ucb1x00_dev *tsdev;
-+
-+ if (ucb1x00_dev)
-+ return NULL;
-+
-+ tsdev = kmalloc(sizeof(struct ucb1x00_dev), GFP_KERNEL);
-+ if (!tsdev)
-+ return NULL;
-+
-+ memset(tsdev, 0, sizeof(struct ucb1x00_dev));
-+ init_waitqueue_head(&tsdev->wait);
-+ INIT_LIST_HEAD(&tsdev->list);
-+
-+ ucb1x00_dev = tsdev;
-+
-+ strcpy(tsdev->name, ucb1x00_ts_dev.name);
-+
-+ tsdev->handle.dev = dev;
-+ tsdev->handle.name = tsdev->name;
-+ tsdev->handle.handler = handler;
-+ tsdev->handle.private = tsdev;
-+
-+ misc_register(&ucb1x00_ts_dev);
-+
-+ tsdev->exist = 1;
-+
-+ return &tsdev->handle;
-+}
-+
-+static void ucb1x00_disconnect(struct input_handle *handle)
-+{
-+ struct ucb1x00_dev *tsdev = handle->private;
-+
-+ tsdev->exist = 0;
-+ ucb1x00_remove(tsdev);
-+}
-+
-+static struct input_device_id ucb1x00_ids[] = {
-+ {
-+ .flags = INPUT_DEVICE_ID_MATCH_ABSBIT,
-+ .evbit = { BIT(EV_ABS) },
-+ .absbit = { BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_PRESSURE) },
-+ },
-+
-+ {},/* Terminating entry */
-+};
-+
-+MODULE_DEVICE_TABLE(input, ucb1x00_ids);
-+
-+static struct input_handler ucb1x00_handler = {
-+ .event = ucb1x00_event,
-+ .connect = ucb1x00_connect,
-+ .disconnect = ucb1x00_disconnect,
-+ .name = "touchscreen/ucb1x00",
-+ .id_table = ucb1x00_ids,
-+};
-+
-+static int __init ucb1x00_init(void)
-+{
-+ input_register_handler(&ucb1x00_handler);
-+ printk(KERN_INFO "ts: UCB1x00 touchscreen protocol output\n");
-+ return 0;
-+}
-+
-+static void __exit ucb1x00_exit(void)
-+{
-+ input_unregister_handler(&ucb1x00_handler);
-+}
-+
-+module_init(ucb1x00_init);
-+module_exit(ucb1x00_exit);
-+
-+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-+MODULE_DESCRIPTION("Input driver to UCB1x00 touchscreen converter");
---- linux-2.6.5/drivers/input/Makefile~heh 2004-04-03 22:38:17.000000000 -0500
-+++ linux-2.6.5/drivers/input/Makefile 2004-04-30 20:57:36.000000000 -0400
-@@ -8,6 +8,7 @@
- obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
- obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
- obj-$(CONFIG_INPUT_EVDEV) += evdev.o
-+obj-$(CONFIG_INPUT_TSLIBDEV) += tslibdev.o
- obj-$(CONFIG_INPUT_TSDEV) += tsdev.o
- obj-$(CONFIG_INPUT_POWER) += power.o
- obj-$(CONFIG_INPUT_EVBUG) += evbug.o
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/char/sa1100-rtc.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,416 @@
-+/*
-+ * Real Time Clock interface for Linux on Intel SA11x0/PXA2xx
-+ *
-+ * Copyright (c) 2000 Nils Faerber
-+ *
-+ * Based on rtc.c by Paul Gortmaker
-+ * Date/time conversion routines taken from arch/arm/kernel/time.c
-+ * by Linus Torvalds and Russel King
-+ * and the GNU C Library
-+ * ( ... I love the GPL ... just take what you need! ;)
-+ *
-+ * 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.
-+ *
-+ * 1.00 2001-06-08 Nicolas Pitre <nico@cam.org>
-+ * - added periodic timer capability using OSMR1
-+ * - flag compatibility with other RTC chips
-+ * - permission checks for ioctls
-+ * - major cleanup, partial rewrite
-+ *
-+ * 0.03 2001-03-07 CIH <cih@coventive.com>
-+ * - Modify the bug setups RTC clock.
-+ *
-+ * 0.02 2001-02-27 Nils Faerber <nils@@kernelconcepts.de>
-+ * - removed mktime(), added alarm irq clear
-+ *
-+ * 0.01 2000-10-01 Nils Faerber <nils@@kernelconcepts.de>
-+ * - initial release
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/fs.h>
-+#include <linux/miscdevice.h>
-+#include <linux/string.h>
-+#include <linux/init.h>
-+#include <linux/poll.h>
-+#include <linux/proc_fs.h>
-+#include <linux/interrupt.h>
-+#include <linux/rtc.h>
-+
-+#include <asm/bitops.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/rtc.h>
-+
-+#define TIMER_FREQ 3686400
-+
-+#define RTC_DEF_DIVIDER 32768 - 1
-+#define RTC_DEF_TRIM 0
-+
-+/* Those are the bits from a classic RTC we want to mimic */
-+#define RTC_IRQF 0x80 /* any of the following 3 is active */
-+#define RTC_PF 0x40
-+#define RTC_AF 0x20
-+#define RTC_UF 0x10
-+
-+static unsigned long rtc_freq = 1024;
-+static struct rtc_time rtc_alarm = {
-+ .tm_year = 0,
-+ .tm_mon = 0,
-+ .tm_mday = 0,
-+ .tm_hour = 0,
-+ .tm_mon = 0,
-+ .tm_sec = 0,
-+};
-+
-+extern spinlock_t rtc_lock;
-+
-+static int rtc_update_alarm(struct rtc_time *alrm)
-+{
-+ struct rtc_time alarm_tm, now_tm;
-+ unsigned long now, time;
-+ int ret;
-+
-+ do {
-+ now = RCNR;
-+ rtc_time_to_tm(now, &now_tm);
-+ rtc_next_alarm_time(&alarm_tm, &now_tm, alrm);
-+ ret = rtc_tm_to_time(&alarm_tm, &time);
-+ if (ret != 0)
-+ break;
-+
-+ RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL);
-+ RTAR = time;
-+ } while (now != RCNR);
-+
-+ return ret;
-+}
-+
-+static irqreturn_t rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ unsigned int rtsr;
-+ unsigned long events = 0;
-+
-+ spin_lock(&rtc_lock);
-+
-+ rtsr = RTSR;
-+ /* clear interrupt sources */
-+ RTSR = 0;
-+ RTSR = (RTSR_AL|RTSR_HZ) & (rtsr >> 2);
-+
-+ /* clear alarm interrupt if it has occurred */
-+ if (rtsr & RTSR_AL)
-+ rtsr &= ~RTSR_ALE;
-+ RTSR = rtsr & (RTSR_ALE|RTSR_HZE);
-+
-+ /* update irq data & counter */
-+ if (rtsr & RTSR_AL)
-+ events |= (RTC_AF|RTC_IRQF);
-+ if (rtsr & RTSR_HZ)
-+ events |= (RTC_UF|RTC_IRQF);
-+
-+ rtc_update(1, events);
-+
-+ if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm))
-+ rtc_update_alarm(&rtc_alarm);
-+
-+ spin_unlock(&rtc_lock);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+#if 0
-+static unsigned long rtc_irq_data;
-+
-+static irqreturn_t timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ /*
-+ * If we match for the first time, the periodic interrupt flag won't
-+ * be set. If it is, then we did wrap around (very unlikely but
-+ * still possible) and compute the amount of missed periods.
-+ * The match reg is updated only when the data is actually retrieved
-+ * to avoid unnecessary interrupts.
-+ */
-+ OSSR = OSSR_M1; /* clear match on timer1 */
-+ if (rtc_irq_data & RTC_PF) {
-+ rtc_irq_data += (rtc_freq * ((1<<30)/(TIMER_FREQ>>2))) << 8;
-+ } else {
-+ rtc_update(1, RTC_PF | RTC_IRQF);
-+ }
-+
-+ wake_up_interruptible(&rtc_wait);
-+ kill_fasync (&rtc_async_queue, SIGIO, POLL_IN);
-+
-+ return IRQ_HANDLED;
-+}
-+#endif
-+
-+static int sa1100_rtc_open(void)
-+{
-+ int ret;
-+
-+ ret = request_irq(IRQ_RTC1Hz, rtc_interrupt, SA_INTERRUPT, "rtc 1Hz", NULL);
-+ if (ret) {
-+ printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTC1Hz);
-+ goto fail_ui;
-+ }
-+ ret = request_irq(IRQ_RTCAlrm, rtc_interrupt, SA_INTERRUPT, "rtc Alrm", NULL);
-+ if (ret) {
-+ printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_RTCAlrm);
-+ goto fail_ai;
-+ }
-+#if 0
-+ ret = request_irq(IRQ_OST1, timer1_interrupt, SA_INTERRUPT, "rtc timer", NULL);
-+ if (ret) {
-+ printk(KERN_ERR "rtc: IRQ%d already in use.\n", IRQ_OST1);
-+ goto fail_pi;
-+ }
-+ rtc_irq_data = 0;
-+#endif
-+ return 0;
-+
-+ fail_pi:
-+ free_irq(IRQ_RTCAlrm, NULL);
-+ fail_ai:
-+ free_irq(IRQ_RTC1Hz, NULL);
-+ fail_ui:
-+ return ret;
-+}
-+
-+static void sa1100_rtc_release(void)
-+{
-+ spin_lock_irq (&rtc_lock);
-+ RTSR = 0;
-+ OIER &= ~OIER_E1;
-+ OSSR = OSSR_M1;
-+ spin_unlock_irq (&rtc_lock);
-+
-+// free_irq(IRQ_OST1, NULL);
-+ free_irq(IRQ_RTCAlrm, NULL);
-+ free_irq(IRQ_RTC1Hz, NULL);
-+}
-+
-+#if 0
-+ssize_t rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ unsigned long data;
-+ ssize_t retval;
-+
-+ if (count < sizeof(unsigned long))
-+ return -EINVAL;
-+
-+ add_wait_queue(&rtc_wait, &wait);
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ for (;;) {
-+ spin_lock_irq (&rtc_lock);
-+ data = rtc_irq_data;
-+ if (data != 0) {
-+ rtc_irq_data = 0;
-+ break;
-+ }
-+ spin_unlock_irq (&rtc_lock);
-+
-+ if (file->f_flags & O_NONBLOCK) {
-+ retval = -EAGAIN;
-+ goto out;
-+ }
-+
-+ if (signal_pending(current)) {
-+ retval = -ERESTARTSYS;
-+ goto out;
-+ }
-+
-+ schedule();
-+ }
-+
-+ if (data & RTC_PF) {
-+ /* interpolate missed periods and set match for the next one */
-+ unsigned long period = TIMER_FREQ/rtc_freq;
-+ unsigned long oscr = OSCR;
-+ unsigned long osmr1 = OSMR1;
-+ unsigned long missed = (oscr - osmr1)/period;
-+ data += missed << 8;
-+ OSSR = OSSR_M1; /* clear match on timer 1 */
-+ OSMR1 = osmr1 + (missed + 1)*period;
-+ /* ensure we didn't miss another match in the mean time */
-+ while( (signed long)((osmr1 = OSMR1) - OSCR) <= 0 ) {
-+ data += 0x100;
-+ OSSR = OSSR_M1; /* clear match on timer 1 */
-+ OSMR1 = osmr1 + period;
-+ }
-+ }
-+ spin_unlock_irq (&rtc_lock);
-+
-+ data -= 0x100; /* the first IRQ wasn't actually missed */
-+
-+ retval = put_user(data, (unsigned long *)buf);
-+ if (!retval)
-+ retval = sizeof(unsigned long);
-+
-+out:
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&rtc_wait, &wait);
-+ return retval;
-+}
-+#endif
-+
-+static int sa1100_rtc_ioctl(unsigned int cmd, unsigned long arg)
-+{
-+ switch (cmd) {
-+ case RTC_AIE_OFF:
-+ spin_lock_irq(&rtc_lock);
-+ RTSR &= ~RTSR_ALE;
-+// rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+ case RTC_AIE_ON:
-+ spin_lock_irq(&rtc_lock);
-+ RTSR |= RTSR_ALE;
-+// rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+ case RTC_UIE_OFF:
-+ spin_lock_irq(&rtc_lock);
-+ RTSR &= ~RTSR_HZE;
-+// rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+ case RTC_UIE_ON:
-+ spin_lock_irq(&rtc_lock);
-+ RTSR |= RTSR_HZE;
-+// rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+#if 0
-+ case RTC_PIE_OFF:
-+ spin_lock_irq(&rtc_lock);
-+ OIER &= ~OIER_E1;
-+// rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+ case RTC_PIE_ON:
-+ if ((rtc_freq > 64) && !capable(CAP_SYS_RESOURCE))
-+ return -EACCES;
-+ spin_lock_irq(&rtc_lock);
-+ OSMR1 = TIMER_FREQ/rtc_freq + OSCR;
-+ OIER |= OIER_E1;
-+// rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+ case RTC_IRQP_READ:
-+ return put_user(rtc_freq, (unsigned long *)arg);
-+ case RTC_IRQP_SET:
-+ if (arg < 1 || arg > TIMER_FREQ)
-+ return -EINVAL;
-+ if ((arg > 64) && (!capable(CAP_SYS_RESOURCE)))
-+ return -EACCES;
-+ rtc_freq = arg;
-+ return 0;
-+#endif
-+ }
-+ return -EINVAL;
-+}
-+
-+static void sa1100_rtc_read_time(struct rtc_time *tm)
-+{
-+ rtc_time_to_tm(RCNR, tm);
-+}
-+
-+static int sa1100_rtc_set_time(struct rtc_time *tm)
-+{
-+ unsigned long time;
-+ int ret;
-+
-+ ret = rtc_tm_to_time(tm, &time);
-+ if (ret == 0)
-+ RCNR = time;
-+ return ret;
-+}
-+
-+static void sa1100_rtc_read_alarm(struct rtc_wkalrm *alrm)
-+{
-+ memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time));
-+ alrm->pending = RTSR & RTSR_AL ? 1 : 0;
-+}
-+
-+static int sa1100_rtc_set_alarm(struct rtc_wkalrm *alrm)
-+{
-+ int ret;
-+
-+ spin_lock_irq(&rtc_lock);
-+ ret = rtc_update_alarm(&alrm->time);
-+ if (ret == 0) {
-+ memcpy(&rtc_alarm, &alrm->time, sizeof(struct rtc_time));
-+
-+ if (alrm->enabled)
-+ enable_irq_wake(IRQ_RTCAlrm);
-+ else
-+ disable_irq_wake(IRQ_RTCAlrm);
-+ }
-+ spin_unlock_irq(&rtc_lock);
-+
-+ return ret;
-+}
-+
-+static int sa1100_rtc_proc(char *buf)
-+{
-+ char *p = buf;
-+
-+ p += sprintf(p, "trim/divider\t: 0x%08x\n", RTTR);
-+ p += sprintf(p, "alarm_IRQ\t: %s\n", (RTSR & RTSR_ALE) ? "yes" : "no" );
-+ p += sprintf(p, "update_IRQ\t: %s\n", (RTSR & RTSR_HZE) ? "yes" : "no");
-+ p += sprintf(p, "periodic_IRQ\t: %s\n", (OIER & OIER_E1) ? "yes" : "no");
-+ p += sprintf(p, "periodic_freq\t: %ld\n", rtc_freq);
-+
-+ return p - buf;
-+}
-+
-+static struct rtc_ops sa1100_rtc_ops = {
-+ .owner = THIS_MODULE,
-+ .open = sa1100_rtc_open,
-+ .release = sa1100_rtc_release,
-+ .ioctl = sa1100_rtc_ioctl,
-+
-+ .read_time = sa1100_rtc_read_time,
-+ .set_time = sa1100_rtc_set_time,
-+ .read_alarm = sa1100_rtc_read_alarm,
-+ .set_alarm = sa1100_rtc_set_alarm,
-+ .proc = sa1100_rtc_proc,
-+};
-+
-+static int __init rtc_init(void)
-+{
-+ /*
-+ * According to the manual we should be able to let RTTR be zero
-+ * and then a default diviser for a 32.768KHz clock is used.
-+ * Apparently this doesn't work, at least for my SA1110 rev 5.
-+ * If the clock divider is uninitialized then reset it to the
-+ * default value to get the 1Hz clock.
-+ */
-+ if (RTTR == 0) {
-+ RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16);
-+ printk(KERN_WARNING "rtc: warning: initializing default clock divider/trim value\n");
-+ /* The current RTC value probably doesn't make sense either */
-+ RCNR = 0;
-+ }
-+
-+ register_rtc(&sa1100_rtc_ops);
-+
-+ return 0;
-+}
-+
-+static void __exit rtc_exit(void)
-+{
-+ unregister_rtc(&sa1100_rtc_ops);
-+}
-+
-+module_init(rtc_init);
-+module_exit(rtc_exit);
-+
-+MODULE_AUTHOR("Nils Faerber <nils@@kernelconcepts.de>");
-+MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)");
-+MODULE_LICENSE("GPL"); /* so says the header */
---- linux-2.6.5/drivers/char/Kconfig~heh 2004-04-03 22:36:15.000000000 -0500
-+++ linux-2.6.5/drivers/char/Kconfig 2004-04-30 20:57:36.000000000 -0400
-@@ -814,6 +814,10 @@
-
- If unsure, say N.
-
-+config SA1100_RTC
-+ tristate "SA1100 or PXA Real Time Clock"
-+ depends on ARCH_SA1100 || ARCH_PXA
-+
- config DTLK
- tristate "Double Talk PC internal speech card support"
- help
---- linux-2.6.5/drivers/char/tty_io.c~heh 2004-04-03 22:37:23.000000000 -0500
-+++ linux-2.6.5/drivers/char/tty_io.c 2004-04-30 20:57:36.000000000 -0400
-@@ -1535,10 +1535,17 @@
- return 0;
- }
-
-+/*
-+ * In the case of pty's, "tty" is the master side
-+ * and "real_tty" is the slave side.
-+ */
- static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
- struct winsize * arg)
- {
- struct winsize tmp_ws;
-+ struct task_struct *p;
-+ struct list_head *l;
-+ struct pid *pid;
-
- if (copy_from_user(&tmp_ws, arg, sizeof(*arg)))
- return -EFAULT;
-@@ -1558,8 +1565,21 @@
- #endif
- if (tty->pgrp > 0)
- kill_pg(tty->pgrp, SIGWINCH, 1);
-- if ((real_tty->pgrp != tty->pgrp) && (real_tty->pgrp > 0))
-- kill_pg(real_tty->pgrp, SIGWINCH, 1);
-+
-+ /*
-+ * Send SIGWINCH to the whole session on the slave tty.
-+ * However, in the case of non-master pty's, be careful
-+ * not to send two SIGWINCH to the same procress group.
-+ */
-+ if (real_tty->session > 0) {
-+ read_lock(&tasklist_lock);
-+ for_each_task_pid(real_tty->session, PIDTYPE_SID, p, l, pid) {
-+ if (process_group(p) != tty->pgrp)
-+ group_send_sig_info(SIGWINCH, (void *)1L, p);
-+ }
-+ read_unlock(&tasklist_lock);
-+ }
-+
- tty->winsize = tmp_ws;
- real_tty->winsize = tmp_ws;
- return 0;
---- linux-2.6.5/drivers/Makefile~heh 2004-04-03 22:37:43.000000000 -0500
-+++ linux-2.6.5/drivers/Makefile 2004-04-30 20:57:36.000000000 -0400
-@@ -11,6 +11,8 @@
- # PnP must come after ACPI since it will eventually need to check if acpi
- # was used and do nothing if so
- obj-$(CONFIG_PNP) += pnp/
-+obj-$(CONFIG_I2C) += i2c/
-+obj-$(CONFIG_L3) += l3/
-
- # char/ comes before serial/ etc so that the VT console is the boot-time
- # default.
-@@ -41,7 +43,6 @@
- obj-$(CONFIG_GAMEPORT) += input/gameport/
- obj-$(CONFIG_SERIO) += input/serio/
- obj-$(CONFIG_I2O) += message/
--obj-$(CONFIG_I2C) += i2c/
- obj-$(CONFIG_PHONE) += telephony/
- obj-$(CONFIG_MD) += md/
- obj-$(CONFIG_BT) += bluetooth/
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/l3/Kconfig 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,24 @@
-+#
-+# L3 bus configuration
-+#
-+
-+menu "L3 serial bus support"
-+
-+config L3
-+ tristate "L3 support"
-+
-+config L3_ALGOBIT
-+ bool "L3 bit-banging interfaces"
-+ depends on L3=y
-+
-+config L3_BIT_SA1100_GPIO
-+ bool "SA11x0 GPIO adapter"
-+ depends on L3_ALGOBIT && ARCH_SA1100
-+
-+# i2c must come before this
-+config BIT_SA1100_GPIO
-+ bool
-+ depends on L3_BIT_SA1100_GPIO || I2C_BIT_SA1100_GPIO=y
-+ default y
-+
-+endmenu
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/l3/l3-core.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,203 @@
-+/*
-+ * linux/drivers/l3/l3-core.c
-+ *
-+ * Copyright (C) 2001 Russell King
-+ *
-+ * General structure taken from i2c-core.c by Simon G. Vogl
-+ *
-+ * 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.
-+ *
-+ * See linux/Documentation/l3 for further documentation.
-+ */
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/slab.h>
-+#include <linux/proc_fs.h>
-+#include <linux/kmod.h>
-+#include <linux/init.h>
-+#include <linux/l3/l3.h>
-+
-+static DECLARE_MUTEX(adapter_lock);
-+static LIST_HEAD(adapter_list);
-+
-+static DECLARE_MUTEX(driver_lock);
-+static LIST_HEAD(driver_list);
-+
-+/**
-+ * l3_add_adapter - register a new L3 bus adapter
-+ * @adap: l3_adapter structure for the registering adapter
-+ *
-+ * Make the adapter available for use by clients using name adap->name.
-+ * The adap->adapters list is initialised by this function.
-+ *
-+ * Returns 0;
-+ */
-+int l3_add_adapter(struct l3_adapter *adap)
-+{
-+ down(&adapter_lock);
-+ list_add(&adap->adapters, &adapter_list);
-+ up(&adapter_lock);
-+ return 0;
-+}
-+
-+/**
-+ * l3_del_adapter - unregister a L3 bus adapter
-+ * @adap: l3_adapter structure to unregister
-+ *
-+ * Remove an adapter from the list of available L3 Bus adapters.
-+ *
-+ * Returns 0;
-+ */
-+int l3_del_adapter(struct l3_adapter *adap)
-+{
-+ down(&adapter_lock);
-+ list_del(&adap->adapters);
-+ up(&adapter_lock);
-+ return 0;
-+}
-+
-+static struct l3_adapter *__l3_get_adapter(const char *name)
-+{
-+ struct list_head *l;
-+
-+ list_for_each(l, &adapter_list) {
-+ struct l3_adapter *adap = list_entry(l, struct l3_adapter, adapters);
-+
-+ if (strcmp(adap->name, name) == 0)
-+ return adap;
-+ }
-+
-+ return NULL;
-+}
-+
-+/**
-+ * l3_get_adapter - get a reference to an adapter
-+ * @name: driver name
-+ *
-+ * Obtain a l3_adapter structure for the specified adapter. If the adapter
-+ * is not currently load, then load it. The adapter will be locked in core
-+ * until all references are released via l3_put_adapter.
-+ */
-+struct l3_adapter *l3_get_adapter(const char *name)
-+{
-+ struct l3_adapter *adap;
-+ int try;
-+
-+ for (try = 0; try < 2; try ++) {
-+ down(&adapter_lock);
-+ adap = __l3_get_adapter(name);
-+ if (adap && !try_module_get(adap->owner))
-+ adap = NULL;
-+ up(&adapter_lock);
-+
-+ if (adap)
-+ break;
-+
-+ if (try == 0)
-+ request_module(name);
-+ }
-+
-+ return adap;
-+}
-+
-+/**
-+ * l3_put_adapter - release a reference to an adapter
-+ * @adap: driver to release reference
-+ *
-+ * Indicate to the L3 core that you no longer require the adapter reference.
-+ * The adapter module may be unloaded when there are no references to its
-+ * data structure.
-+ *
-+ * You must not use the reference after calling this function.
-+ */
-+void l3_put_adapter(struct l3_adapter *adap)
-+{
-+ if (adap && adap->owner)
-+ module_put(adap->owner);
-+}
-+
-+/**
-+ * l3_transfer - transfer information on an L3 bus
-+ * @adap: adapter structure to perform transfer on
-+ * @msgs: array of l3_msg structures describing transfer
-+ * @num: number of l3_msg structures
-+ *
-+ * Transfer the specified messages to/from a device on the L3 bus.
-+ *
-+ * Returns number of messages successfully transferred, otherwise negative
-+ * error code.
-+ */
-+int l3_transfer(struct l3_adapter *adap, struct l3_msg msgs[], int num)
-+{
-+ int ret = -ENOSYS;
-+
-+ if (adap->algo->xfer) {
-+ down(adap->lock);
-+ ret = adap->algo->xfer(adap, msgs, num);
-+ up(adap->lock);
-+ }
-+ return ret;
-+}
-+
-+/**
-+ * l3_write - send data to a device on an L3 bus
-+ * @adap: L3 bus adapter
-+ * @addr: L3 bus address
-+ * @buf: buffer for bytes to send
-+ * @len: number of bytes to send
-+ *
-+ * Send len bytes pointed to by buf to device address addr on the L3 bus
-+ * described by client.
-+ *
-+ * Returns the number of bytes transferred, or negative error code.
-+ */
-+int l3_write(struct l3_adapter *adap, int addr, const char *buf, int len)
-+{
-+ struct l3_msg msg;
-+ int ret;
-+
-+ msg.addr = addr;
-+ msg.flags = 0;
-+ msg.buf = (char *)buf;
-+ msg.len = len;
-+
-+ ret = l3_transfer(adap, &msg, 1);
-+ return ret == 1 ? len : ret;
-+}
-+
-+/**
-+ * l3_read - receive data from a device on an L3 bus
-+ * @adap: L3 bus adapter
-+ * @addr: L3 bus address
-+ * @buf: buffer for bytes to receive
-+ * @len: number of bytes to receive
-+ *
-+ * Receive len bytes from device address addr on the L3 bus described by
-+ * client to a buffer pointed to by buf.
-+ *
-+ * Returns the number of bytes transferred, or negative error code.
-+ */
-+int l3_read(struct l3_adapter *adap, int addr, char *buf, int len)
-+{
-+ struct l3_msg msg;
-+ int ret;
-+
-+ msg.addr = addr;
-+ msg.flags = L3_M_RD;
-+ msg.buf = buf;
-+ msg.len = len;
-+
-+ ret = l3_transfer(adap, &msg, 1);
-+ return ret == 1 ? len : ret;
-+}
-+
-+EXPORT_SYMBOL(l3_add_adapter);
-+EXPORT_SYMBOL(l3_del_adapter);
-+EXPORT_SYMBOL(l3_get_adapter);
-+EXPORT_SYMBOL(l3_put_adapter);
-+EXPORT_SYMBOL(l3_transfer);
-+EXPORT_SYMBOL(l3_write);
-+EXPORT_SYMBOL(l3_read);
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/l3/l3-algo-bit.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,175 @@
-+/*
-+ * L3 bus algorithm module.
-+ *
-+ * Copyright (C) 2001 Russell King, 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 version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Note that L3 buses can share the same pins as I2C buses, so we must
-+ * _not_ generate an I2C start condition. An I2C start condition is
-+ * defined as a high-to-low transition of the data line while the clock
-+ * is high. Therefore, we must only change the data line while the
-+ * clock is low.
-+ */
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+#include <linux/l3/l3.h>
-+#include <linux/l3/algo-bit.h>
-+
-+#define setdat(adap,val) adap->setdat(adap->data, val)
-+#define setclk(adap,val) adap->setclk(adap->data, val)
-+#define setmode(adap,val) adap->setmode(adap->data, val)
-+#define setdatin(adap) adap->setdir(adap->data, 1)
-+#define setdatout(adap) adap->setdir(adap->data, 0)
-+#define getdat(adap) adap->getdat(adap->data)
-+
-+/*
-+ * Send one byte of data to the chip. Data is latched into the chip on
-+ * the rising edge of the clock.
-+ */
-+static void sendbyte(struct l3_algo_bit_data *adap, unsigned int byte)
-+{
-+ int i;
-+
-+ for (i = 0; i < 8; i++) {
-+ setclk(adap, 0);
-+ udelay(adap->data_hold);
-+ setdat(adap, byte & 1);
-+ udelay(adap->data_setup);
-+ setclk(adap, 1);
-+ udelay(adap->clock_high);
-+ byte >>= 1;
-+ }
-+}
-+
-+/*
-+ * Send a set of bytes to the chip. We need to pulse the MODE line
-+ * between each byte, but never at the start nor at the end of the
-+ * transfer.
-+ */
-+static void sendbytes(struct l3_algo_bit_data *adap, const char *buf, int len)
-+{
-+ int i;
-+
-+ for (i = 0; i < len; i++) {
-+ if (i) {
-+ udelay(adap->mode_hold);
-+ setmode(adap, 0);
-+ udelay(adap->mode);
-+ }
-+ setmode(adap, 1);
-+ udelay(adap->mode_setup);
-+ sendbyte(adap, buf[i]);
-+ }
-+}
-+
-+/*
-+ * Read one byte of data from the chip. Data is latched into the chip on
-+ * the rising edge of the clock.
-+ */
-+static unsigned int readbyte(struct l3_algo_bit_data *adap)
-+{
-+ unsigned int byte = 0;
-+ int i;
-+
-+ for (i = 0; i < 8; i++) {
-+ setclk(adap, 0);
-+ udelay(adap->data_hold + adap->data_setup);
-+ setclk(adap, 1);
-+ if (getdat(adap))
-+ byte |= 1 << i;
-+ udelay(adap->clock_high);
-+ }
-+
-+ return byte;
-+}
-+
-+/*
-+ * Read a set of bytes from the chip. We need to pulse the MODE line
-+ * between each byte, but never at the start nor at the end of the
-+ * transfer.
-+ */
-+static void readbytes(struct l3_algo_bit_data *adap, char *buf, int len)
-+{
-+ int i;
-+
-+ for (i = 0; i < len; i++) {
-+ if (i) {
-+ udelay(adap->mode_hold);
-+ setmode(adap, 0);
-+ }
-+ setmode(adap, 1);
-+ udelay(adap->mode_setup);
-+ buf[i] = readbyte(adap);
-+ }
-+}
-+
-+static int l3_xfer(struct l3_adapter *l3_adap, struct l3_msg msgs[], int num)
-+{
-+ struct l3_algo_bit_data *adap = l3_adap->algo_data;
-+ int i;
-+
-+ /*
-+ * If we share an I2C bus, ensure that it is in STOP mode
-+ */
-+ setclk(adap, 1);
-+ setdat(adap, 1);
-+ setmode(adap, 1);
-+ setdatout(adap);
-+ udelay(adap->mode);
-+
-+ for (i = 0; i < num; i++) {
-+ struct l3_msg *pmsg = &msgs[i];
-+
-+ if (!(pmsg->flags & L3_M_NOADDR)) {
-+ setmode(adap, 0);
-+ udelay(adap->mode_setup);
-+ sendbyte(adap, pmsg->addr);
-+ udelay(adap->mode_hold);
-+ }
-+
-+ if (pmsg->flags & L3_M_RD) {
-+ setdatin(adap);
-+ readbytes(adap, pmsg->buf, pmsg->len);
-+ } else {
-+ setdatout(adap);
-+ sendbytes(adap, pmsg->buf, pmsg->len);
-+ }
-+ }
-+
-+ /*
-+ * Ensure that we leave the bus in I2C stop mode.
-+ */
-+ setclk(adap, 1);
-+ setdat(adap, 1);
-+ setmode(adap, 0);
-+ setdatin(adap);
-+
-+ return num;
-+}
-+
-+static struct l3_algorithm l3_bit_algo = {
-+ name: "L3 bit-shift algorithm",
-+ xfer: l3_xfer,
-+};
-+
-+int l3_bit_add_bus(struct l3_adapter *adap)
-+{
-+ adap->algo = &l3_bit_algo;
-+ return l3_add_adapter(adap);
-+}
-+
-+int l3_bit_del_bus(struct l3_adapter *adap)
-+{
-+ return l3_del_adapter(adap);
-+}
-+
-+EXPORT_SYMBOL(l3_bit_add_bus);
-+EXPORT_SYMBOL(l3_bit_del_bus);
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/l3/Makefile 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,11 @@
-+#
-+# Makefile for the L3 bus driver.
-+#
-+
-+# Link order:
-+# (core, adapters, algorithms, drivers) then clients
-+
-+l3-$(CONFIG_L3_ALGOBIT) += l3-algo-bit.o
-+l3-$(CONFIG_BIT_SA1100_GPIO) += l3-bit-sa1100.o
-+
-+obj-$(CONFIG_L3) += l3-core.o $(l3-y) $(l3-drv-y)
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/l3/l3-bit-sa1100.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,271 @@
-+/*
-+ * linux/drivers/l3/l3-bit-sa1100.c
-+ *
-+ * Copyright (C) 2001 Russell King
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This is a combined I2C and L3 bus driver.
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/ioport.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/i2c.h>
-+#include <linux/i2c-algo-bit.h>
-+#include <linux/l3/algo-bit.h>
-+
-+#include <asm/system.h>
-+#include <asm/hardware.h>
-+#include <asm/mach-types.h>
-+#include <asm/arch/assabet.h>
-+
-+#define NAME "l3-bit-sa1100-gpio"
-+
-+struct bit_data {
-+ unsigned int sda;
-+ unsigned int scl;
-+ unsigned int l3_mode;
-+};
-+
-+static int getsda(void *data)
-+{
-+ struct bit_data *bits = data;
-+
-+ return GPLR & bits->sda;
-+}
-+
-+#ifdef CONFIG_I2C_BIT_SA1100_GPIO
-+static void i2c_setsda(void *data, int state)
-+{
-+ struct bit_data *bits = data;
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+ if (state)
-+ GPDR &= ~bits->sda;
-+ else {
-+ GPCR = bits->sda;
-+ GPDR |= bits->sda;
-+ }
-+ local_irq_restore(flags);
-+}
-+
-+static void i2c_setscl(void *data, int state)
-+{
-+ struct bit_data *bits = data;
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+ if (state)
-+ GPDR &= ~bits->scl;
-+ else {
-+ GPCR = bits->scl;
-+ GPDR |= bits->scl;
-+ }
-+ local_irq_restore(flags);
-+}
-+
-+static int i2c_getscl(void *data)
-+{
-+ struct bit_data *bits = data;
-+
-+ return GPLR & bits->scl;
-+}
-+
-+static struct i2c_algo_bit_data i2c_bit_data = {
-+ .setsda = i2c_setsda,
-+ .setscl = i2c_setscl,
-+ .getsda = getsda,
-+ .getscl = i2c_getscl,
-+ .udelay = 10,
-+ .mdelay = 10,
-+ .timeout = 100,
-+};
-+
-+static struct i2c_adapter i2c_adapter = {
-+ .algo_data = &i2c_bit_data,
-+};
-+
-+#define LOCK &i2c_adapter.bus_lock
-+
-+static int __init i2c_init(struct bit_data *bits)
-+{
-+ i2c_bit_data.data = bits;
-+ return i2c_bit_add_bus(&i2c_adapter);
-+}
-+
-+static void i2c_exit(void)
-+{
-+ i2c_bit_del_bus(&i2c_adapter);
-+}
-+
-+#else
-+static DECLARE_MUTEX(l3_lock);
-+#define LOCK &l3_lock
-+#define i2c_init(bits) (0)
-+#define i2c_exit() do { } while (0)
-+#endif
-+
-+#ifdef CONFIG_L3_BIT_SA1100_GPIO
-+/*
-+ * iPAQs need the clock line driven hard high and low.
-+ */
-+static void l3_setscl(void *data, int state)
-+{
-+ struct bit_data *bits = data;
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+ if (state)
-+ GPSR = bits->scl;
-+ else
-+ GPCR = bits->scl;
-+ GPDR |= bits->scl;
-+ local_irq_restore(flags);
-+}
-+
-+static void l3_setsda(void *data, int state)
-+{
-+ struct bit_data *bits = data;
-+
-+ if (state)
-+ GPSR = bits->sda;
-+ else
-+ GPCR = bits->sda;
-+}
-+
-+static void l3_setdir(void *data, int in)
-+{
-+ struct bit_data *bits = data;
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+ if (in)
-+ GPDR &= ~bits->sda;
-+ else
-+ GPDR |= bits->sda;
-+ local_irq_restore(flags);
-+}
-+
-+static void l3_setmode(void *data, int state)
-+{
-+ struct bit_data *bits = data;
-+
-+ if (state)
-+ GPSR = bits->l3_mode;
-+ else
-+ GPCR = bits->l3_mode;
-+}
-+
-+static struct l3_algo_bit_data l3_bit_data = {
-+ .data = NULL,
-+ .setdat = l3_setsda,
-+ .setclk = l3_setscl,
-+ .setmode = l3_setmode,
-+ .setdir = l3_setdir,
-+ .getdat = getsda,
-+ .data_hold = 1,
-+ .data_setup = 1,
-+ .clock_high = 1,
-+ .mode_hold = 1,
-+ .mode_setup = 1,
-+};
-+
-+static struct l3_adapter l3_adapter = {
-+ .owner = THIS_MODULE,
-+ .name = NAME,
-+ .algo_data = &l3_bit_data,
-+ .lock = LOCK,
-+};
-+
-+static int __init l3_init(struct bit_data *bits)
-+{
-+ l3_bit_data.data = bits;
-+ return l3_bit_add_bus(&l3_adapter);
-+}
-+
-+static void __exit l3_exit(void)
-+{
-+ l3_bit_del_bus(&l3_adapter);
-+}
-+#else
-+#define l3_init(bits) (0)
-+#define l3_exit() do { } while (0)
-+#endif
-+
-+static struct bit_data bit_data;
-+
-+static int __init bus_init(void)
-+{
-+ struct bit_data *bit = &bit_data;
-+ unsigned long flags;
-+ int ret;
-+
-+ if (machine_is_assabet() || machine_is_pangolin()) {
-+ bit->sda = GPIO_GPIO15;
-+ bit->scl = GPIO_GPIO18;
-+ bit->l3_mode = GPIO_GPIO17;
-+ }
-+
-+ if (machine_is_h3600() || machine_is_h3100()) {
-+ bit->sda = GPIO_GPIO14;
-+ bit->scl = GPIO_GPIO16;
-+ bit->l3_mode = GPIO_GPIO15;
-+ }
-+
-+ if (machine_is_stork()) {
-+ bit->sda = GPIO_GPIO15;
-+ bit->scl = GPIO_GPIO18;
-+ bit->l3_mode = GPIO_GPIO17;
-+ }
-+
-+ if (!bit->sda)
-+ return -ENODEV;
-+
-+ /*
-+ * Default level for L3 mode is low.
-+ * We set SCL and SDA high (i2c idle state).
-+ */
-+ local_irq_save(flags);
-+ GPDR &= ~(bit->scl | bit->sda);
-+ GPCR = bit->l3_mode | bit->scl | bit->sda;
-+ GPDR |= bit->l3_mode;
-+ local_irq_restore(flags);
-+
-+ if (machine_is_assabet()) {
-+ /*
-+ * Release reset on UCB1300, ADI7171 and UDA1341. We
-+ * need to do this here so that we can communicate on
-+ * the I2C/L3 buses.
-+ */
-+ ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
-+ mdelay(1);
-+ ASSABET_BCR_clear(ASSABET_BCR_CODEC_RST);
-+ mdelay(1);
-+ ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
-+ }
-+
-+ ret = i2c_init(bit);
-+ if (ret == 0 && bit->l3_mode) {
-+ ret = l3_init(bit);
-+ if (ret)
-+ i2c_exit();
-+ }
-+
-+ return ret;
-+}
-+
-+static void __exit bus_exit(void)
-+{
-+ l3_exit();
-+ i2c_exit();
-+}
-+
-+module_init(bus_init);
-+module_exit(bus_exit);
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/misc/switches.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,22 @@
-+/*
-+ * linux/drivers/misc/switches.h
-+ *
-+ * Copyright (C) 2001 John Dorsey
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 19 December 2001 - created.
-+ */
-+
-+#if !defined(_SWITCHES_H)
-+# define _SWITCHES_H
-+
-+#include <linux/switches.h>
-+
-+#define SWITCHES_NAME "switches"
-+
-+extern int switches_event(switches_mask_t *mask);
-+
-+#endif /* !defined(_SWITCHES_H) */
---- linux-2.6.5/drivers/misc/Kconfig~heh 2004-04-03 22:36:26.000000000 -0500
-+++ linux-2.6.5/drivers/misc/Kconfig 2004-04-30 20:57:36.000000000 -0400
-@@ -21,5 +21,62 @@
-
- If unsure, say N.
-
-+menu "Multimedia Capabilities Port drivers"
-+
-+config MCP
-+ tristate "Multimedia drivers"
-+
-+# Interface drivers
-+config MCP_SA1100
-+ tristate "Support SA1100 MCP interface"
-+ depends on MCP && ARCH_SA1100
-+
-+# Chip drivers
-+config MCP_UCB1200
-+ tristate "Support for UCB1200 / UCB1300"
-+ depends on MCP
-+
-+config MCP_UCB1200_AUDIO
-+ tristate "Audio / Telephony interface support"
-+ depends on MCP_UCB1200 && SOUND
-+
-+config MCP_UCB1200_TS
-+ tristate "Touchscreen interface support"
-+ depends on MCP_UCB1200 && INPUT
-+
-+endmenu
-+
-+
-+menu "Console Switches"
-+
-+config SWITCHES
-+ tristate "Console Switch Support"
-+ help
-+ Say Y here to include support for simple console momentary switches.
-+ This driver implements a miscellaneous character device (named
-+ `switches' in /proc/misc) which can be read by userland programs
-+ to respond to switch press events. This mechanism is efficient for
-+ systems which may not implement a traditional heavyweight console
-+ server.
-+
-+ It is also possible to say M to build this driver as a module (named
-+ `switches.o').
-+
-+config SWITCHES_SA1100
-+ tristate "SA-1100 switches"
-+ depends on SWITCHES && ARCH_SA1100
-+ help
-+ Say Y here to include support for switches routed directly to
-+ interruptable signals on StrongARM SA-1100 systems.
-+
-+config SWITCHES_UCB1X00
-+ tristate "UCB1x00 switches"
-+ depends on SWITCHES && MCP_UCB1200
-+ help
-+ Say Y here to include support for switches routed through a
-+ UCB1x00 modem/audio analog front-end device.
-+
-+endmenu
-+
- endmenu
-
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/misc/ucb1x00-assabet.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,73 @@
-+/*
-+ * linux/drivers/misc/ucb1x00-assabet.c
-+ *
-+ * Copyright (C) 2001-2003 Russell King, 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.
-+ *
-+ * We handle the machine-specific bits of the UCB1x00 driver here.
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/fs.h>
-+#include <linux/proc_fs.h>
-+#include <linux/device.h>
-+
-+#include <asm/dma.h>
-+
-+#include "ucb1x00.h"
-+
-+#define UCB1X00_ATTR(name,input)\
-+static ssize_t name##_show(struct class_device *dev, char *buf) \
-+{ \
-+ struct ucb1x00 *ucb = classdev_to_ucb1x00(dev); \
-+ int val; \
-+ ucb1x00_adc_enable(ucb); \
-+ val = ucb1x00_adc_read(ucb, input, UCB_NOSYNC); \
-+ ucb1x00_adc_disable(ucb); \
-+ return sprintf(buf, "%d\n", val); \
-+} \
-+static CLASS_DEVICE_ATTR(name,0444,name##_show,NULL)
-+
-+UCB1X00_ATTR(vbatt, UCB_ADC_INP_AD1);
-+UCB1X00_ATTR(vcharger, UCB_ADC_INP_AD0);
-+UCB1X00_ATTR(batt_temp, UCB_ADC_INP_AD2);
-+
-+static int ucb1x00_assabet_add(struct class_device *dev)
-+{
-+ class_device_create_file(dev, &class_device_attr_vbatt);
-+ class_device_create_file(dev, &class_device_attr_vcharger);
-+ class_device_create_file(dev, &class_device_attr_batt_temp);
-+ return 0;
-+}
-+
-+static void ucb1x00_assabet_remove(struct class_device *dev)
-+{
-+ class_device_remove_file(dev, &class_device_attr_batt_temp);
-+ class_device_remove_file(dev, &class_device_attr_vcharger);
-+ class_device_remove_file(dev, &class_device_attr_vbatt);
-+}
-+
-+static struct class_interface ucb1x00_assabet_interface = {
-+ .add = ucb1x00_assabet_add,
-+ .remove = ucb1x00_assabet_remove,
-+};
-+
-+static int __init ucb1x00_assabet_init(void)
-+{
-+ return ucb1x00_register_interface(&ucb1x00_assabet_interface);
-+}
-+
-+static void __exit ucb1x00_assabet_exit(void)
-+{
-+ ucb1x00_unregister_interface(&ucb1x00_assabet_interface);
-+}
-+
-+module_init(ucb1x00_assabet_init);
-+module_exit(ucb1x00_assabet_exit);
-+
-+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-+MODULE_DESCRIPTION("Assabet noddy testing only example ADC driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/misc/mcp-pxa.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,57 @@
-+/*
-+ * linux/drivers/misc/mcp-pxa.c
-+ *
-+ * 2002-01-10 Jeff Sutherland <jeffs@accelent.com>
-+ *
-+ * 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.
-+ *
-+ * NOTE: This is a quick hack to gain access to the aclink codec's
-+ * touch screen facility. Its audio is handled by a separate
-+ * (non-mcp) driver at the present time.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/ac97_codec.h>
-+
-+#include "mcp.h"
-+
-+
-+extern int pxa_ac97_get(struct ac97_codec **codec);
-+extern void pxa_ac97_put(void);
-+
-+
-+struct mcp *mcp_get(void)
-+{
-+ struct ac97_codec *codec;
-+ if (pxa_ac97_get(&codec) < 0)
-+ return NULL;
-+ return (struct mcp *)codec;
-+}
-+
-+void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val)
-+{
-+ struct ac97_codec *codec = (struct ac97_codec *)mcp;
-+ codec->codec_write(codec, reg, val);
-+}
-+
-+unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg)
-+{
-+ struct ac97_codec *codec = (struct ac97_codec *)mcp;
-+ return codec->codec_read(codec, reg);
-+}
-+
-+void mcp_enable(struct mcp *mcp)
-+{
-+ /*
-+ * Should we do something here to make sure the aclink
-+ * codec is alive???
-+ * A: not for now --NP
-+ */
-+}
-+
-+void mcp_disable(struct mcp *mcp)
-+{
-+}
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/misc/mcp-core.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,235 @@
-+/*
-+ * linux/drivers/misc/mcp-core.c
-+ *
-+ * Copyright (C) 2001 Russell King
-+ *
-+ * 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.
-+ *
-+ * Generic MCP (Multimedia Communications Port) layer. All MCP locking
-+ * is solely held within this file.
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/smp.h>
-+#include <linux/device.h>
-+
-+#include <asm/dma.h>
-+#include <asm/system.h>
-+
-+#include "mcp.h"
-+
-+#define to_mcp(d) container_of(d, struct mcp, attached_device)
-+#define to_mcp_driver(d) container_of(d, struct mcp_driver, drv)
-+
-+static int mcp_bus_match(struct device *dev, struct device_driver *drv)
-+{
-+ return 1;
-+}
-+
-+static int mcp_bus_probe(struct device *dev)
-+{
-+ struct mcp *mcp = to_mcp(dev);
-+ struct mcp_driver *drv = to_mcp_driver(dev->driver);
-+
-+ return drv->probe(mcp);
-+}
-+
-+static int mcp_bus_remove(struct device *dev)
-+{
-+ struct mcp *mcp = to_mcp(dev);
-+ struct mcp_driver *drv = to_mcp_driver(dev->driver);
-+
-+ drv->remove(mcp);
-+ return 0;
-+}
-+
-+static int mcp_bus_suspend(struct device *dev, u32 state)
-+{
-+ struct mcp *mcp = to_mcp(dev);
-+ int ret = 0;
-+
-+ if (dev->driver) {
-+ struct mcp_driver *drv = to_mcp_driver(dev->driver);
-+
-+ ret = drv->suspend(mcp, state);
-+ }
-+ return ret;
-+}
-+
-+static int mcp_bus_resume(struct device *dev)
-+{
-+ struct mcp *mcp = to_mcp(dev);
-+ int ret = 0;
-+
-+ if (dev->driver) {
-+ struct mcp_driver *drv = to_mcp_driver(dev->driver);
-+
-+ ret = drv->resume(mcp);
-+ }
-+ return ret;
-+}
-+
-+static struct bus_type mcp_bus_type = {
-+ .name = "mcp",
-+ .match = mcp_bus_match,
-+ .suspend = mcp_bus_suspend,
-+ .resume = mcp_bus_resume,
-+};
-+
-+/**
-+ * mcp_set_telecom_divisor - set the telecom divisor
-+ * @mcp: MCP interface structure
-+ * @div: SIB clock divisor
-+ *
-+ * Set the telecom divisor on the MCP interface. The resulting
-+ * sample rate is SIBCLOCK/div.
-+ */
-+void mcp_set_telecom_divisor(struct mcp *mcp, unsigned int div)
-+{
-+ spin_lock_irq(&mcp->lock);
-+ mcp->set_telecom_divisor(mcp, div);
-+ spin_unlock_irq(&mcp->lock);
-+}
-+
-+/**
-+ * mcp_set_audio_divisor - set the audio divisor
-+ * @mcp: MCP interface structure
-+ * @div: SIB clock divisor
-+ *
-+ * Set the audio divisor on the MCP interface.
-+ */
-+void mcp_set_audio_divisor(struct mcp *mcp, unsigned int div)
-+{
-+ spin_lock_irq(&mcp->lock);
-+ mcp->set_audio_divisor(mcp, div);
-+ spin_unlock_irq(&mcp->lock);
-+}
-+
-+/**
-+ * mcp_reg_write - write a device register
-+ * @mcp: MCP interface structure
-+ * @reg: 4-bit register index
-+ * @val: 16-bit data value
-+ *
-+ * Write a device register. The MCP interface must be enabled
-+ * to prevent this function hanging.
-+ */
-+void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&mcp->lock, flags);
-+ mcp->reg_write(mcp, reg, val);
-+ spin_unlock_irqrestore(&mcp->lock, flags);
-+}
-+
-+/**
-+ * mcp_reg_read - read a device register
-+ * @mcp: MCP interface structure
-+ * @reg: 4-bit register index
-+ *
-+ * Read a device register and return its value. The MCP interface
-+ * must be enabled to prevent this function hanging.
-+ */
-+unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg)
-+{
-+ unsigned long flags;
-+ unsigned int val;
-+
-+ spin_lock_irqsave(&mcp->lock, flags);
-+ val = mcp->reg_read(mcp, reg);
-+ spin_unlock_irqrestore(&mcp->lock, flags);
-+
-+ return val;
-+}
-+
-+/**
-+ * mcp_enable - enable the MCP interface
-+ * @mcp: MCP interface to enable
-+ *
-+ * Enable the MCP interface. Each call to mcp_enable will need
-+ * a corresponding call to mcp_disable to disable the interface.
-+ */
-+void mcp_enable(struct mcp *mcp)
-+{
-+ spin_lock_irq(&mcp->lock);
-+ if (mcp->use_count++ == 0)
-+ mcp->enable(mcp);
-+ spin_unlock_irq(&mcp->lock);
-+}
-+
-+/**
-+ * mcp_disable - disable the MCP interface
-+ * @mcp: MCP interface to disable
-+ *
-+ * Disable the MCP interface. The MCP interface will only be
-+ * disabled once the number of calls to mcp_enable matches the
-+ * number of calls to mcp_disable.
-+ */
-+void mcp_disable(struct mcp *mcp)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&mcp->lock, flags);
-+ if (--mcp->use_count == 0)
-+ mcp->disable(mcp);
-+ spin_unlock_irqrestore(&mcp->lock, flags);
-+}
-+
-+int mcp_host_register(struct mcp *mcp, struct device *parent)
-+{
-+ mcp->attached_device.parent = parent;
-+ mcp->attached_device.bus = &mcp_bus_type;
-+ mcp->attached_device.dma_mask = parent->dma_mask;
-+ strcpy(mcp->attached_device.bus_id, "mcp0");
-+ return device_register(&mcp->attached_device);
-+}
-+
-+void mcp_host_unregister(struct mcp *mcp)
-+{
-+ device_unregister_wait(&mcp->attached_device);
-+}
-+
-+int mcp_driver_register(struct mcp_driver *mcpdrv)
-+{
-+ mcpdrv->drv.bus = &mcp_bus_type;
-+ mcpdrv->drv.probe = mcp_bus_probe;
-+ mcpdrv->drv.remove = mcp_bus_remove;
-+ return driver_register(&mcpdrv->drv);
-+}
-+
-+void mcp_driver_unregister(struct mcp_driver *mcpdrv)
-+{
-+ driver_unregister(&mcpdrv->drv);
-+}
-+
-+static int __init mcp_init(void)
-+{
-+ return bus_register(&mcp_bus_type);
-+}
-+
-+static void __exit mcp_exit(void)
-+{
-+ bus_unregister(&mcp_bus_type);
-+}
-+
-+module_init(mcp_init);
-+module_exit(mcp_exit);
-+
-+EXPORT_SYMBOL(mcp_set_telecom_divisor);
-+EXPORT_SYMBOL(mcp_set_audio_divisor);
-+EXPORT_SYMBOL(mcp_reg_write);
-+EXPORT_SYMBOL(mcp_reg_read);
-+EXPORT_SYMBOL(mcp_enable);
-+EXPORT_SYMBOL(mcp_disable);
-+EXPORT_SYMBOL(mcp_host_register);
-+EXPORT_SYMBOL(mcp_host_unregister);
-+EXPORT_SYMBOL(mcp_driver_register);
-+EXPORT_SYMBOL(mcp_driver_unregister);
-+
-+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-+MODULE_DESCRIPTION("Core multimedia communications port driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/misc/ucb1x00-ts.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,465 @@
-+/*
-+ * linux/drivers/misc/ucb1x00-ts.c
-+ *
-+ * Copyright (C) 2001 Russell King, 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 version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 21-Jan-2002 <jco@ict.es> :
-+ *
-+ * Added support for synchronous A/D mode. This mode is useful to
-+ * avoid noise induced in the touchpanel by the LCD, provided that
-+ * the UCB1x00 has a valid LCD sync signal routed to its ADCSYNC pin.
-+ * It is important to note that the signal connected to the ADCSYNC
-+ * pin should provide pulses even when the LCD is blanked, otherwise
-+ * a pen touch needed to unblank the LCD will never be read.
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/smp.h>
-+#include <linux/smp_lock.h>
-+#include <linux/sched.h>
-+#include <linux/completion.h>
-+#include <linux/delay.h>
-+#include <linux/string.h>
-+#include <linux/input.h>
-+#include <linux/device.h>
-+#include <linux/slab.h>
-+
-+#include <asm/dma.h>
-+#include <asm/semaphore.h>
-+
-+#include "ucb1x00.h"
-+
-+
-+struct ucb1x00_ts {
-+ struct input_dev idev;
-+ struct ucb1x00 *ucb;
-+
-+ struct semaphore irq_wait;
-+ struct semaphore sem;
-+ struct completion init_exit;
-+ struct task_struct *rtask;
-+ int use_count;
-+ u16 x_res;
-+ u16 y_res;
-+
-+ int restart:1;
-+ int adcsync:1;
-+};
-+
-+static int adcsync = UCB_NOSYNC;
-+
-+static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
-+{
-+ input_report_abs(&ts->idev, ABS_X, x);
-+ input_report_abs(&ts->idev, ABS_Y, y);
-+ input_report_abs(&ts->idev, ABS_PRESSURE, pressure);
-+ input_sync(&ts->idev);
-+}
-+
-+static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
-+{
-+ input_report_abs(&ts->idev, ABS_PRESSURE, 0);
-+ input_sync(&ts->idev);
-+}
-+
-+/*
-+ * Switch to interrupt mode.
-+ */
-+static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts)
-+{
-+ if (ts->ucb->id == UCB_ID_1400_BUGGY)
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
-+ UCB_TS_CR_MODE_INT);
-+ else
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
-+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
-+ UCB_TS_CR_MODE_INT);
-+}
-+
-+/*
-+ * Switch to pressure mode, and read pressure. We don't need to wait
-+ * here, since both plates are being driven.
-+ */
-+static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
-+{
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
-+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
-+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-+
-+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
-+}
-+
-+/*
-+ * Switch to X position mode and measure Y plate. We switch the plate
-+ * configuration in pressure mode, then switch to position mode. This
-+ * gives a faster response time. Even so, we need to wait about 55us
-+ * for things to stabilise.
-+ */
-+static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
-+{
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
-+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
-+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
-+ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
-+
-+ udelay(55);
-+
-+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
-+}
-+
-+/*
-+ * Switch to Y position mode and measure X plate. We switch the plate
-+ * configuration in pressure mode, then switch to position mode. This
-+ * gives a faster response time. Even so, we need to wait about 55us
-+ * for things to stabilise.
-+ */
-+static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts)
-+{
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
-+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
-+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
-+ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
-+
-+ udelay(55);
-+
-+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);
-+}
-+
-+/*
-+ * Switch to X plate resistance mode. Set MX to ground, PX to
-+ * supply. Measure current.
-+ */
-+static inline unsigned int ucb1x00_ts_read_xres(struct ucb1x00_ts *ts)
-+{
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
-+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-+ return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
-+}
-+
-+/*
-+ * Switch to Y plate resistance mode. Set MY to ground, PY to
-+ * supply. Measure current.
-+ */
-+static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts)
-+{
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
-+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-+ return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
-+}
-+
-+/*
-+ * This is a RT kernel thread that handles the ADC accesses
-+ * (mainly so we can use semaphores in the UCB1200 core code
-+ * to serialise accesses to the ADC, and in the UCB1400 case where
-+ * any register access may sleep).
-+ */
-+static int ucb1x00_thread(void *_ts)
-+{
-+ struct ucb1x00_ts *ts = _ts;
-+ struct task_struct *tsk = current;
-+ int valid;
-+
-+ ts->rtask = tsk;
-+
-+ daemonize("ktsd");
-+ /* only want to receive SIGKILL */
-+ allow_signal(SIGKILL);
-+
-+ /*
-+ * We could run as a real-time thread. However, thus far
-+ * this doesn't seem to be necessary.
-+ */
-+// tsk->policy = SCHED_FIFO;
-+// tsk->rt_priority = 1;
-+
-+ complete(&ts->init_exit);
-+
-+ valid = 0;
-+
-+ for (;;) {
-+ unsigned int x, y, p, val;
-+
-+ ts->restart = 0;
-+
-+ ucb1x00_adc_enable(ts->ucb);
-+
-+ x = ucb1x00_ts_read_xpos(ts);
-+ y = ucb1x00_ts_read_ypos(ts);
-+ p = ucb1x00_ts_read_pressure(ts);
-+
-+ /*
-+ * Switch back to interrupt mode.
-+ */
-+ ucb1x00_ts_mode_int(ts);
-+ ucb1x00_adc_disable(ts->ucb);
-+
-+ set_task_state(tsk, TASK_UNINTERRUPTIBLE);
-+ schedule_timeout(HZ / 100);
-+ if (signal_pending(tsk))
-+ break;
-+
-+ ucb1x00_enable(ts->ucb);
-+ val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
-+
-+ if (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW)) {
-+ ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
-+ ucb1x00_disable(ts->ucb);
-+
-+ /*
-+ * If we spat out a valid sample set last time,
-+ * spit out a "pen off" sample here.
-+ */
-+ if (valid) {
-+ ucb1x00_ts_event_release(ts);
-+ valid = 0;
-+ }
-+
-+ /*
-+ * Since ucb1x00_enable_irq() might sleep due
-+ * to the way the UCB1400 regs are accessed, we
-+ * can't use set_task_state() before that call,
-+ * and not changing state before enabling the
-+ * interrupt is racy. A semaphore solves all
-+ * those issues quite nicely.
-+ */
-+ down_interruptible(&ts->irq_wait);
-+ } else {
-+ ucb1x00_disable(ts->ucb);
-+
-+ /*
-+ * Filtering is policy. Policy belongs in user
-+ * space. We therefore leave it to user space
-+ * to do any filtering they please.
-+ */
-+ if (!ts->restart) {
-+ ucb1x00_ts_evt_add(ts, p, x, y);
-+ valid = 1;
-+ }
-+
-+ set_task_state(tsk, TASK_INTERRUPTIBLE);
-+ }
-+
-+ schedule_timeout(HZ / 100);
-+ if (signal_pending(tsk))
-+ break;
-+ }
-+
-+ ts->rtask = NULL;
-+ complete_and_exit(&ts->init_exit, 0);
-+}
-+
-+/*
-+ * We only detect touch screen _touches_ with this interrupt
-+ * handler, and even then we just schedule our task.
-+ */
-+static void ucb1x00_ts_irq(int idx, void *id)
-+{
-+ struct ucb1x00_ts *ts = id;
-+ ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
-+ up(&ts->irq_wait);
-+}
-+
-+static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
-+{
-+ input_report_abs(&ts->idev, ABS_PRESSURE, 0);
-+}
-+
-+static int ucb1x00_ts_open(struct input_dev *idev)
-+{
-+ struct ucb1x00_ts *ts = (struct ucb1x00_ts *)idev;
-+ int ret = 0;
-+
-+ if (down_interruptible(&ts->sem))
-+ return -EINTR;
-+
-+ if (ts->use_count++ != 0)
-+ goto out;
-+
-+ if (ts->rtask)
-+ panic("ucb1x00: rtask running?");
-+
-+ sema_init(&ts->irq_wait, 0);
-+ ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts);
-+ if (ret < 0)
-+ goto out;
-+
-+ /*
-+ * If we do this at all, we should allow the user to
-+ * measure and read the X and Y resistance at any time.
-+ */
-+ ucb1x00_adc_enable(ts->ucb);
-+ ts->x_res = ucb1x00_ts_read_xres(ts);
-+ ts->y_res = ucb1x00_ts_read_yres(ts);
-+ ucb1x00_adc_disable(ts->ucb);
-+
-+ init_completion(&ts->init_exit);
-+ ret = kernel_thread(ucb1x00_thread, ts, CLONE_KERNEL);
-+ if (ret >= 0) {
-+ wait_for_completion(&ts->init_exit);
-+ ret = 0;
-+ } else {
-+ ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
-+ }
-+
-+ out:
-+ if (ret)
-+ ts->use_count--;
-+ up(&ts->sem);
-+ return ret;
-+}
-+
-+/*
-+ * Release touchscreen resources. Disable IRQs.
-+ */
-+static void ucb1x00_ts_close(struct input_dev *idev)
-+{
-+ struct ucb1x00_ts *ts = (struct ucb1x00_ts *)idev;
-+
-+ down(&ts->sem);
-+ if (--ts->use_count == 0) {
-+ if (ts->rtask) {
-+ send_sig(SIGKILL, ts->rtask, 1);
-+ wait_for_completion(&ts->init_exit);
-+ }
-+
-+ ucb1x00_enable(ts->ucb);
-+ ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 0);
-+ ucb1x00_disable(ts->ucb);
-+ }
-+ up(&ts->sem);
-+}
-+
-+#if 0
-+static int ucb1x00_ts_resume(struct device *_dev, u32 level)
-+{
-+ struct ucb1x00_device *dev = ucb1x00_dev(_dev);
-+ struct ucb1x00_ts *ts = ucb1x00_get_drvdata(dev);
-+
-+ if (level == RESUME_ENABLE && ts->rtask != NULL) {
-+ /*
-+ * Restart the TS thread to ensure the
-+ * TS interrupt mode is set up again
-+ * after sleep.
-+ */
-+ ts->restart = 1;
-+ up(&ts->irq_wait);
-+ }
-+ return 0;
-+}
-+#endif
-+
-+
-+/*
-+ * Initialisation.
-+ */
-+static int ucb1x00_ts_add(struct class_device *dev)
-+{
-+ struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
-+ struct ucb1x00_ts *ts;
-+
-+ ts = kmalloc(sizeof(struct ucb1x00_ts), GFP_KERNEL);
-+ if (!ts)
-+ return -ENOMEM;
-+
-+ memset(ts, 0, sizeof(struct ucb1x00_ts));
-+
-+ ts->ucb = ucb;
-+ ts->adcsync = adcsync;
-+ init_MUTEX(&ts->sem);
-+
-+ ts->idev.name = "Touchscreen panel";
-+ ts->idev.id.product = ts->ucb->id;
-+ ts->idev.open = ucb1x00_ts_open;
-+ ts->idev.close = ucb1x00_ts_close;
-+
-+ __set_bit(EV_ABS, ts->idev.evbit);
-+ __set_bit(ABS_X, ts->idev.absbit);
-+ __set_bit(ABS_Y, ts->idev.absbit);
-+ __set_bit(ABS_PRESSURE, ts->idev.absbit);
-+
-+ input_register_device(&ts->idev);
-+
-+ ucb->ts_data = ts;
-+
-+ return 0;
-+}
-+
-+static void ucb1x00_ts_remove(struct class_device *dev)
-+{
-+ struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
-+ struct ucb1x00_ts *ts = ucb->ts_data;
-+
-+ input_unregister_device(&ts->idev);
-+ kfree(ts);
-+}
-+
-+static struct class_interface ucb1x00_ts_interface = {
-+ .add = ucb1x00_ts_add,
-+ .remove = ucb1x00_ts_remove,
-+};
-+
-+static int __init ucb1x00_ts_init(void)
-+{
-+ return ucb1x00_register_interface(&ucb1x00_ts_interface);
-+}
-+
-+static void __exit ucb1x00_ts_exit(void)
-+{
-+ ucb1x00_unregister_interface(&ucb1x00_ts_interface);
-+}
-+
-+#ifndef MODULE
-+
-+/*
-+ * Parse kernel command-line options.
-+ *
-+ * syntax : ucbts=[sync|nosync],...
-+ */
-+static int __init ucb1x00_ts_setup(char *str)
-+{
-+ char *p;
-+
-+ while ((p = strsep(&str, ",")) != NULL) {
-+ if (strcmp(p, "sync") == 0)
-+ adcsync = UCB_SYNC;
-+ }
-+
-+ return 1;
-+}
-+
-+__setup("ucbts=", ucb1x00_ts_setup);
-+
-+#else
-+
-+MODULE_PARM(adcsync, "i");
-+MODULE_PARM_DESC(adcsync, "Enable use of ADCSYNC signal");
-+
-+#endif
-+
-+module_init(ucb1x00_ts_init);
-+module_exit(ucb1x00_ts_exit);
-+
-+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-+MODULE_DESCRIPTION("UCB1x00 touchscreen driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/misc/ucb1x00-core.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,624 @@
-+/*
-+ * linux/drivers/misc/ucb1x00-core.c
-+ *
-+ * Copyright (C) 2001 Russell King, 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.
-+ *
-+ * The UCB1x00 core driver provides basic services for handling IO,
-+ * the ADC, interrupts, and accessing registers. It is designed
-+ * such that everything goes through this layer, thereby providing
-+ * a consistent locking methodology, as well as allowing the drivers
-+ * to be used on other non-MCP-enabled hardware platforms.
-+ *
-+ * Note that all locks are private to this file. Nothing else may
-+ * touch them.
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/interrupt.h>
-+#include <linux/device.h>
-+
-+#include <asm/dma.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+
-+#include "ucb1x00.h"
-+
-+/**
-+ * ucb1x00_io_set_dir - set IO direction
-+ * @ucb: UCB1x00 structure describing chip
-+ * @in: bitfield of IO pins to be set as inputs
-+ * @out: bitfield of IO pins to be set as outputs
-+ *
-+ * Set the IO direction of the ten general purpose IO pins on
-+ * the UCB1x00 chip. The @in bitfield has priority over the
-+ * @out bitfield, in that if you specify a pin as both input
-+ * and output, it will end up as an input.
-+ *
-+ * ucb1x00_enable must have been called to enable the comms
-+ * before using this function.
-+ *
-+ * This function takes a spinlock, disabling interrupts.
-+ */
-+void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int in, unsigned int out)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&ucb->io_lock, flags);
-+ ucb->io_dir |= out;
-+ ucb->io_dir &= ~in;
-+
-+ ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
-+ spin_unlock_irqrestore(&ucb->io_lock, flags);
-+}
-+
-+/**
-+ * ucb1x00_io_write - set or clear IO outputs
-+ * @ucb: UCB1x00 structure describing chip
-+ * @set: bitfield of IO pins to set to logic '1'
-+ * @clear: bitfield of IO pins to set to logic '0'
-+ *
-+ * Set the IO output state of the specified IO pins. The value
-+ * is retained if the pins are subsequently configured as inputs.
-+ * The @clear bitfield has priority over the @set bitfield -
-+ * outputs will be cleared.
-+ *
-+ * ucb1x00_enable must have been called to enable the comms
-+ * before using this function.
-+ *
-+ * This function takes a spinlock, disabling interrupts.
-+ */
-+void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int set, unsigned int clear)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&ucb->io_lock, flags);
-+ ucb->io_out |= set;
-+ ucb->io_out &= ~clear;
-+
-+ ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
-+ spin_unlock_irqrestore(&ucb->io_lock, flags);
-+}
-+
-+/**
-+ * ucb1x00_io_read - read the current state of the IO pins
-+ * @ucb: UCB1x00 structure describing chip
-+ *
-+ * Return a bitfield describing the logic state of the ten
-+ * general purpose IO pins.
-+ *
-+ * ucb1x00_enable must have been called to enable the comms
-+ * before using this function.
-+ *
-+ * This function does not take any semaphores or spinlocks.
-+ */
-+unsigned int ucb1x00_io_read(struct ucb1x00 *ucb)
-+{
-+ return ucb1x00_reg_read(ucb, UCB_IO_DATA);
-+}
-+
-+/*
-+ * UCB1300 data sheet says we must:
-+ * 1. enable ADC => 5us (including reference startup time)
-+ * 2. select input => 51*tsibclk => 4.3us
-+ * 3. start conversion => 102*tsibclk => 8.5us
-+ * (tsibclk = 1/11981000)
-+ * Period between SIB 128-bit frames = 10.7us
-+ */
-+
-+/**
-+ * ucb1x00_adc_enable - enable the ADC converter
-+ * @ucb: UCB1x00 structure describing chip
-+ *
-+ * Enable the ucb1x00 and ADC converter on the UCB1x00 for use.
-+ * Any code wishing to use the ADC converter must call this
-+ * function prior to using it.
-+ *
-+ * This function takes the ADC semaphore to prevent two or more
-+ * concurrent uses, and therefore may sleep. As a result, it
-+ * can only be called from process context, not interrupt
-+ * context.
-+ *
-+ * You should release the ADC as soon as possible using
-+ * ucb1x00_adc_disable.
-+ */
-+void ucb1x00_adc_enable(struct ucb1x00 *ucb)
-+{
-+ down(&ucb->adc_sem);
-+
-+ ucb->adc_cr |= UCB_ADC_ENA;
-+
-+ ucb1x00_enable(ucb);
-+ ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr);
-+}
-+
-+/**
-+ * ucb1x00_adc_read - read the specified ADC channel
-+ * @ucb: UCB1x00 structure describing chip
-+ * @adc_channel: ADC channel mask
-+ * @sync: wait for syncronisation pulse.
-+ *
-+ * Start an ADC conversion and wait for the result. Note that
-+ * synchronised ADC conversions (via the ADCSYNC pin) must wait
-+ * until the trigger is asserted and the conversion is finished.
-+ *
-+ * This function currently spins waiting for the conversion to
-+ * complete (2 frames max without sync).
-+ *
-+ * If called for a synchronised ADC conversion, it may sleep
-+ * with the ADC semaphore held.
-+ *
-+ * See ucb1x00.h for definition of the UCB_ADC_DAT macro. It
-+ * addresses a bug in the ucb1200/1300 which, of course, Philips
-+ * decided to finally fix in the ucb1400 ;-) -jws
-+ */
-+unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync)
-+{
-+ unsigned int val;
-+
-+ if (sync)
-+ adc_channel |= UCB_ADC_SYNC_ENA;
-+
-+ ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr | adc_channel);
-+ ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr | adc_channel | UCB_ADC_START);
-+
-+ for (;;) {
-+ val = ucb1x00_reg_read(ucb, UCB_ADC_DATA);
-+ if (val & UCB_ADC_DAT_VAL)
-+ break;
-+ /* yield to other processes */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(1);
-+ }
-+
-+ return UCB_ADC_DAT(val);
-+}
-+
-+/**
-+ * ucb1x00_adc_disable - disable the ADC converter
-+ * @ucb: UCB1x00 structure describing chip
-+ *
-+ * Disable the ADC converter and release the ADC semaphore.
-+ */
-+void ucb1x00_adc_disable(struct ucb1x00 *ucb)
-+{
-+ ucb->adc_cr &= ~UCB_ADC_ENA;
-+ ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr);
-+ ucb1x00_disable(ucb);
-+
-+ up(&ucb->adc_sem);
-+}
-+
-+/*
-+ * UCB1x00 Interrupt handling.
-+ *
-+ * The UCB1x00 can generate interrupts when the SIBCLK is stopped.
-+ * Since we need to read an internal register, we must re-enable
-+ * SIBCLK to talk to the chip. We leave the clock running until
-+ * we have finished processing all interrupts from the chip.
-+ *
-+ * A restriction with interrupts exists when using the ucb1400, as
-+ * the codec read/write routines may sleep while waiting for codec
-+ * access completion and uses semaphores for access control to the
-+ * AC97 bus. A complete codec read cycle could take anywhere from
-+ * 60 to 100uSec so we *definitely* don't want to spin inside the
-+ * interrupt handler waiting for codec access. So, we handle the
-+ * interrupt by scheduling a RT kernel thread to run in process
-+ * context instead of interrupt context.
-+ */
-+
-+static int ucb1x00_thread(void *_ucb)
-+{
-+ struct task_struct *tsk = current;
-+ DECLARE_WAITQUEUE(wait, tsk);
-+ struct ucb1x00 *ucb = _ucb;
-+ struct ucb1x00_irq *irq;
-+ unsigned int isr, i;
-+
-+ ucb->rtask = tsk;
-+
-+ daemonize();
-+ reparent_to_init();
-+ tsk->tty = NULL;
-+ tsk->policy = SCHED_FIFO;
-+ tsk->rt_priority = 1;
-+ strcpy(tsk->comm, "kUCB1x00d");
-+
-+ /* only want to receive SIGKILL */
-+ spin_lock_irq(&tsk->sigmask_lock);
-+ siginitsetinv(&tsk->blocked, sigmask(SIGKILL));
-+ recalc_sigpending();
-+ spin_unlock_irq(&tsk->sigmask_lock);
-+
-+ add_wait_queue(&ucb->irq_wait, &wait);
-+ set_task_state(tsk, TASK_INTERRUPTIBLE);
-+ complete(&ucb->complete);
-+
-+ for (;;) {
-+ if (signal_pending(tsk))
-+ break;
-+ enable_irq(ucb->irq);
-+ schedule();
-+
-+ ucb1x00_enable(ucb);
-+ isr = ucb1x00_reg_read(ucb, UCB_IE_STATUS);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
-+
-+ for (i = 0, irq = ucb->irq_handler;
-+ i < 16 && isr;
-+ i++, isr >>= 1, irq++)
-+ if (isr & 1 && irq->fn)
-+ irq->fn(i, irq->devid);
-+ ucb1x00_disable(ucb);
-+
-+ set_task_state(tsk, TASK_INTERRUPTIBLE);
-+ }
-+
-+ remove_wait_queue(&ucb->irq_wait, &wait);
-+ ucb->rtask = NULL;
-+ complete_and_exit(&ucb->complete, 0);
-+}
-+
-+static irqreturn_t ucb1x00_irq(int irqnr, void *devid, struct pt_regs *regs)
-+{
-+ struct ucb1x00 *ucb = devid;
-+ disable_irq(irqnr);
-+ wake_up(&ucb->irq_wait);
-+ return IRQ_HANDLED;
-+}
-+
-+/**
-+ * ucb1x00_hook_irq - hook a UCB1x00 interrupt
-+ * @ucb: UCB1x00 structure describing chip
-+ * @idx: interrupt index
-+ * @fn: function to call when interrupt is triggered
-+ * @devid: device id to pass to interrupt handler
-+ *
-+ * Hook the specified interrupt. You can only register one handler
-+ * for each interrupt source. The interrupt source is not enabled
-+ * by this function; use ucb1x00_enable_irq instead.
-+ *
-+ * Interrupt handlers will be called with other interrupts enabled.
-+ *
-+ * Returns zero on success, or one of the following errors:
-+ * -EINVAL if the interrupt index is invalid
-+ * -EBUSY if the interrupt has already been hooked
-+ */
-+int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid)
-+{
-+ struct ucb1x00_irq *irq;
-+ int ret = -EINVAL;
-+
-+ if (idx < 16) {
-+ irq = ucb->irq_handler + idx;
-+ ret = -EBUSY;
-+
-+ spin_lock_irq(&ucb->lock);
-+ if (irq->fn == NULL) {
-+ irq->devid = devid;
-+ irq->fn = fn;
-+ ret = 0;
-+ }
-+ spin_unlock_irq(&ucb->lock);
-+ }
-+ return ret;
-+}
-+
-+/**
-+ * ucb1x00_enable_irq - enable an UCB1x00 interrupt source
-+ * @ucb: UCB1x00 structure describing chip
-+ * @idx: interrupt index
-+ * @edges: interrupt edges to enable
-+ *
-+ * Enable the specified interrupt to trigger on %UCB_RISING,
-+ * %UCB_FALLING or both edges. The interrupt should have been
-+ * hooked by ucb1x00_hook_irq.
-+ */
-+void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges)
-+{
-+ unsigned long flags;
-+
-+ if (idx < 16) {
-+ spin_lock_irqsave(&ucb->lock, flags);
-+
-+ ucb1x00_enable(ucb);
-+
-+ /* This prevents spurious interrupts on the UCB1400 */
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 1 << idx);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
-+
-+ if (edges & UCB_RISING) {
-+ ucb->irq_ris_enbl |= 1 << idx;
-+ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
-+ }
-+ if (edges & UCB_FALLING) {
-+ ucb->irq_fal_enbl |= 1 << idx;
-+ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
-+ }
-+ ucb1x00_disable(ucb);
-+ spin_unlock_irqrestore(&ucb->lock, flags);
-+ }
-+}
-+
-+/**
-+ * ucb1x00_disable_irq - disable an UCB1x00 interrupt source
-+ * @ucb: UCB1x00 structure describing chip
-+ * @edges: interrupt edges to disable
-+ *
-+ * Disable the specified interrupt triggering on the specified
-+ * (%UCB_RISING, %UCB_FALLING or both) edges.
-+ */
-+void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges)
-+{
-+ unsigned long flags;
-+
-+ if (idx < 16) {
-+ spin_lock_irqsave(&ucb->lock, flags);
-+
-+ ucb1x00_enable(ucb);
-+ if (edges & UCB_RISING) {
-+ ucb->irq_ris_enbl &= ~(1 << idx);
-+ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
-+ }
-+ if (edges & UCB_FALLING) {
-+ ucb->irq_fal_enbl &= ~(1 << idx);
-+ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
-+ }
-+ ucb1x00_disable(ucb);
-+ spin_unlock_irqrestore(&ucb->lock, flags);
-+ }
-+}
-+
-+/**
-+ * ucb1x00_free_irq - disable and free the specified UCB1x00 interrupt
-+ * @ucb: UCB1x00 structure describing chip
-+ * @idx: interrupt index
-+ * @devid: device id.
-+ *
-+ * Disable the interrupt source and remove the handler. devid must
-+ * match the devid passed when hooking the interrupt.
-+ *
-+ * Returns zero on success, or one of the following errors:
-+ * -EINVAL if the interrupt index is invalid
-+ * -ENOENT if devid does not match
-+ */
-+int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid)
-+{
-+ struct ucb1x00_irq *irq;
-+ int ret;
-+
-+ if (idx >= 16)
-+ goto bad;
-+
-+ irq = ucb->irq_handler + idx;
-+ ret = -ENOENT;
-+
-+ spin_lock_irq(&ucb->lock);
-+ if (irq->devid == devid) {
-+ ucb->irq_ris_enbl &= ~(1 << idx);
-+ ucb->irq_fal_enbl &= ~(1 << idx);
-+
-+ ucb1x00_enable(ucb);
-+ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
-+ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
-+ ucb1x00_disable(ucb);
-+
-+ irq->fn = NULL;
-+ irq->devid = NULL;
-+ ret = 0;
-+ }
-+ spin_unlock_irq(&ucb->lock);
-+ return ret;
-+
-+bad:
-+ printk(KERN_ERR "Freeing bad UCB1x00 irq %d\n", idx);
-+ return -EINVAL;
-+}
-+
-+/*
-+ * Try to probe our interrupt, rather than relying on lots of
-+ * hard-coded machine dependencies. For reference, the expected
-+ * IRQ mappings are:
-+ *
-+ * Machine Default IRQ
-+ * adsbitsy IRQ_GPCIN4
-+ * cerf IRQ_GPIO_UCB1200_IRQ
-+ * flexanet IRQ_GPIO_GUI
-+ * freebird IRQ_GPIO_FREEBIRD_UCB1300_IRQ
-+ * graphicsclient ADS_EXT_IRQ(8)
-+ * graphicsmaster ADS_EXT_IRQ(8)
-+ * lart LART_IRQ_UCB1200
-+ * omnimeter IRQ_GPIO23
-+ * pfs168 IRQ_GPIO_UCB1300_IRQ
-+ * simpad IRQ_GPIO_UCB1300_IRQ
-+ * shannon SHANNON_IRQ_GPIO_IRQ_CODEC
-+ * yopy IRQ_GPIO_UCB1200_IRQ
-+ */
-+static int ucb1x00_detect_irq(struct ucb1x00 *ucb)
-+{
-+ unsigned long mask;
-+
-+ mask = probe_irq_on();
-+ if (!mask)
-+ return NO_IRQ;
-+
-+ /*
-+ * Enable the ADC interrupt.
-+ */
-+ ucb1x00_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC);
-+ ucb1x00_reg_write(ucb, UCB_IE_FAL, UCB_IE_ADC);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0xffff);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
-+
-+ /*
-+ * Cause an ADC interrupt.
-+ */
-+ ucb1x00_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA);
-+ ucb1x00_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | UCB_ADC_START);
-+
-+ /*
-+ * Wait for the conversion to complete.
-+ */
-+ while ((ucb1x00_reg_read(ucb, UCB_ADC_DATA) & UCB_ADC_DAT_VAL) == 0);
-+ ucb1x00_reg_write(ucb, UCB_ADC_CR, 0);
-+
-+ /*
-+ * Disable and clear interrupt.
-+ */
-+ ucb1x00_reg_write(ucb, UCB_IE_RIS, 0);
-+ ucb1x00_reg_write(ucb, UCB_IE_FAL, 0);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0xffff);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
-+
-+ /*
-+ * Read triggered interrupt.
-+ */
-+ return probe_irq_off(mask);
-+}
-+
-+static int ucb1x00_probe(struct mcp *mcp)
-+{
-+ struct ucb1x00 *ucb;
-+ unsigned int id;
-+ int ret = -ENODEV;
-+
-+ mcp_enable(mcp);
-+ id = mcp_reg_read(mcp, UCB_ID);
-+
-+ if (id != UCB_ID_1200 && id != UCB_ID_1300) {
-+ printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id);
-+ goto err_disable;
-+ }
-+
-+ ucb = kmalloc(sizeof(struct ucb1x00), GFP_KERNEL);
-+ ret = -ENOMEM;
-+ if (!ucb)
-+ goto err_disable;
-+
-+ memset(ucb, 0, sizeof(struct ucb1x00));
-+
-+ ucb->cdev.class = &ucb1x00_class;
-+ ucb->cdev.dev = &mcp->attached_device;
-+ strlcpy(ucb->cdev.class_id, "ucb1x00", sizeof(ucb->cdev.class_id));
-+
-+ spin_lock_init(&ucb->lock);
-+ spin_lock_init(&ucb->io_lock);
-+ sema_init(&ucb->adc_sem, 1);
-+
-+ ucb->id = id;
-+ ucb->mcp = mcp;
-+ ucb->irq = ucb1x00_detect_irq(ucb);
-+ if (ucb->irq == NO_IRQ) {
-+ printk(KERN_ERR "UCB1x00: IRQ probe failed\n");
-+ ret = -ENODEV;
-+ goto err_free;
-+ }
-+
-+ ret = request_irq(ucb->irq, ucb1x00_irq, 0, "UCB1x00", ucb);
-+ if (ret) {
-+ printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
-+ ucb->irq, ret);
-+ goto err_free;
-+ }
-+
-+ set_irq_type(ucb->irq, IRQT_RISING);
-+ mcp_set_drvdata(mcp, ucb);
-+
-+ ret = class_device_register(&ucb->cdev);
-+ if (ret) {
-+ free_irq(ucb->irq, ucb);
-+ err_free:
-+ kfree(ucb);
-+ }
-+ err_disable:
-+ mcp_disable(mcp);
-+ return ret;
-+}
-+
-+static void ucb1x00_remove(struct mcp *mcp)
-+{
-+ struct ucb1x00 *ucb = mcp_get_drvdata(mcp);
-+
-+ class_device_unregister(&ucb->cdev);
-+ free_irq(ucb->irq, ucb);
-+}
-+
-+static void ucb1x00_release(struct class_device *dev)
-+{
-+ struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
-+ kfree(ucb);
-+}
-+
-+static struct class ucb1x00_class = {
-+ .name = "ucb1x00",
-+ .release = ucb1x00_release,
-+};
-+
-+int ucb1x00_register_interface(struct class_interface *intf)
-+{
-+ intf->class = &ucb1x00_class;
-+ return class_interface_register(intf);
-+}
-+
-+void ucb1x00_unregister_interface(struct class_interface *intf)
-+{
-+ class_interface_unregister(intf);
-+}
-+
-+static struct mcp_driver ucb1x00_driver = {
-+ .drv = {
-+ .name = "ucb1x00",
-+ },
-+ .probe = ucb1x00_probe,
-+ .remove = ucb1x00_remove,
-+};
-+
-+static int __init ucb1x00_init(void)
-+{
-+ int ret = class_register(&ucb1x00_class);
-+ if (ret == 0) {
-+ ret = mcp_driver_register(&ucb1x00_driver);
-+ if (ret)
-+ class_unregister(&ucb1x00_class);
-+ }
-+ return ret;
-+}
-+
-+static void __exit ucb1x00_exit(void)
-+{
-+ mcp_driver_unregister(&ucb1x00_driver);
-+ class_unregister(&ucb1x00_class);
-+}
-+
-+module_init(ucb1x00_init);
-+module_exit(ucb1x00_exit);
-+
-+EXPORT_SYMBOL(ucb1x00_class);
-+
-+EXPORT_SYMBOL(ucb1x00_io_set_dir);
-+EXPORT_SYMBOL(ucb1x00_io_write);
-+EXPORT_SYMBOL(ucb1x00_io_read);
-+
-+EXPORT_SYMBOL(ucb1x00_adc_enable);
-+EXPORT_SYMBOL(ucb1x00_adc_read);
-+EXPORT_SYMBOL(ucb1x00_adc_disable);
-+
-+EXPORT_SYMBOL(ucb1x00_hook_irq);
-+EXPORT_SYMBOL(ucb1x00_free_irq);
-+EXPORT_SYMBOL(ucb1x00_enable_irq);
-+EXPORT_SYMBOL(ucb1x00_disable_irq);
-+
-+EXPORT_SYMBOL(ucb1x00_register_interface);
-+EXPORT_SYMBOL(ucb1x00_unregister_interface);
-+
-+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-+MODULE_DESCRIPTION("UCB1x00 core driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/misc/switches-ucb1x00.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,214 @@
-+/*
-+ * linux/drivers/misc/switches-ucb1x00.c
-+ *
-+ * Copyright (C) 2001 John Dorsey
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 19 December 2001 - created from sa1100_switches.c.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/device.h>
-+
-+#include <asm/dma.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/mach-types.h>
-+
-+#ifdef CONFIG_SA1100_ASSABET
-+#include <asm/arch/assabet.h>
-+#endif
-+
-+#include "switches.h"
-+#include "ucb1x00.h"
-+
-+
-+static void switches_ucb1x00_handler(int irq, void *devid);
-+
-+
-+#ifdef CONFIG_SA1100_ASSABET
-+
-+/* Assabet
-+ * ^^^^^^^
-+ * Six switches are routed to GPIO pins on the UCB1300: S3 -- S8.
-+ * This code sets bits in the range [3, 8] in the mask that we
-+ * return to userland. Note that we transpose signals SW7 and SW8;
-+ * see assabet_switches_ucb1x00_handler().
-+ */
-+
-+static int assabet_switches_ucb1x00_init(struct ucb1x00 *ucb)
-+{
-+ int i;
-+
-+ ucb1x00_enable(ucb);
-+
-+ ucb1x00_io_set_dir(ucb,
-+ UCB_IO_0 | UCB_IO_1 | UCB_IO_2 |
-+ UCB_IO_3 | UCB_IO_4 | UCB_IO_5, 0);
-+
-+ for (i = 0; i < 6; ++i) {
-+ ucb1x00_enable_irq(ucb, i, UCB_RISING | UCB_FALLING);
-+
-+ if (ucb1x00_hook_irq(ucb, i,
-+ switches_ucb1x00_handler, ucb) < 0) {
-+ printk(KERN_ERR "%s: unable to hook IRQ for "
-+ "UCB1300 IO_%d\n", SWITCHES_NAME, i);
-+
-+ /* FIXME: BUGGY ERROR HANDLING */
-+ return -EBUSY;
-+ }
-+
-+ }
-+
-+ ucb1x00_disable(ucb);
-+
-+ return 0;
-+
-+}
-+
-+static void assabet_switches_ucb1x00_shutdown(struct ucb1x00 *ucb)
-+{
-+ int i;
-+
-+ ucb1x00_enable(ucb);
-+
-+ for (i = 5; i >= 0; --i) {
-+ ucb1x00_disable_irq(ucb, i, UCB_RISING | UCB_FALLING);
-+
-+ /* Only error conditions are ENOENT and EINVAL; silently
-+ * ignore:
-+ */
-+ ucb1x00_free_irq(ucb, i, ucb);
-+ }
-+
-+ ucb1x00_disable(ucb);
-+}
-+
-+static void assabet_switches_ucb1x00_handler(struct ucb1x00 *ucb, int irq, switches_mask_t *mask)
-+{
-+ unsigned int last, this;
-+ static unsigned int states = 0;
-+
-+ last = ((states & (1 << irq)) != 0);
-+ this = ((ucb1x00_io_read(ucb) & (1 << irq)) != 0);
-+
-+ if (last == this) /* debounce */
-+ return;
-+
-+ /* Intel StrongARM SA-1110 Development Board
-+ * Schematics Figure 5, Sheet 5 of 12
-+ *
-+ * See switches S8 and S7. Notice their
-+ * relationship to signals SW7 and SW8. Hmmm.
-+ */
-+
-+ switch (irq) {
-+
-+ case 4:
-+
-+ SWITCHES_SET(mask, 8, this);
-+ break;
-+
-+ case 5:
-+
-+ SWITCHES_SET(mask, 7, this);
-+ break;
-+
-+ default:
-+
-+ SWITCHES_SET(mask, irq + 3, this);
-+
-+ }
-+
-+ states = this ? (states | (1 << irq)) : (states & ~(1 << irq));
-+
-+}
-+#endif /* CONFIG_SA1100_ASSABET */
-+
-+
-+/* switches_ucb1x00_handler()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * This routine is a generalized handler for UCB1x00 GPIO switches
-+ * which calls a board-specific service routine and passes an event
-+ * mask to the core event handler. This routine is appropriate for
-+ * systems which use the ucb1x00 framework, and can be registered
-+ * using ucb1x00_hook_irq().
-+ */
-+static void switches_ucb1x00_handler(int irq, void *devid)
-+{
-+ struct ucb1x00 *ucb = devid;
-+ switches_mask_t mask;
-+
-+ SWITCHES_ZERO(&mask);
-+
-+ /* Porting note: call a board-specific UCB1x00 switch handler here.
-+ * The handler can assume that sufficient storage for `mask' has
-+ * been allocated, and that the corresponding switches_mask_t
-+ * structure has been zeroed.
-+ */
-+
-+#ifdef CONFIG_SA1100_ASSABET
-+ if (machine_is_assabet()) {
-+ assabet_switches_ucb1x00_handler(ucb, irq, &mask);
-+ }
-+#endif
-+
-+ switches_event(&mask);
-+}
-+
-+static int switches_add(struct class_device *dev)
-+{
-+ struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
-+ int ret = -ENODEV;
-+
-+#ifdef CONFIG_SA1100_ASSABET
-+ if (machine_is_assabet()) {
-+ ret = assabet_switches_ucb1x00_init(ucb);
-+ }
-+#endif
-+ /* Porting note: call a board-specific init routine here. */
-+
-+ return ret;
-+}
-+
-+static void switches_remove(struct class_device *dev)
-+{
-+ struct ucb1x00 *ucb = classdev_to_ucb1x00(dev);
-+
-+ /* Porting note: call a board-specific shutdown routine here. */
-+
-+#ifdef CONFIG_SA1100_ASSABET
-+ if (machine_is_assabet()) {
-+ assabet_switches_ucb1x00_shutdown(ucb);
-+ }
-+#endif
-+}
-+
-+static struct class_interface ucb1x00_switches_interface = {
-+ .add = switches_add,
-+ .remove = switches_remove,
-+};
-+
-+static int __init switches_ucb1x00_init(void)
-+{
-+ return ucb1x00_register_interface(&ucb1x00_switches_interface);
-+}
-+
-+static void __exit switches_ucb1x00_exit(void)
-+{
-+ ucb1x00_unregister_interface(&ucb1x00_switches_interface);
-+}
-+
-+module_init(switches_ucb1x00_init);
-+module_exit(switches_ucb1x00_exit);
-+
-+MODULE_DESCRIPTION("ucb1x00 switches driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/misc/switches-core.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,200 @@
-+/*
-+ * linux/drivers/misc/switches-core.c
-+ *
-+ * Copyright (C) 2000-2001 John Dorsey
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 5 October 2000 - created.
-+ *
-+ * 25 October 2000 - userland file interface added.
-+ *
-+ * 13 January 2001 - added support for Spot.
-+ *
-+ * 11 September 2001 - UCB1200 driver framework support added.
-+ *
-+ * 19 December 2001 - separated out SA-1100 and UCB1x00 code.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/fs.h>
-+#include <linux/kernel.h>
-+#include <linux/miscdevice.h>
-+#include <linux/module.h>
-+#include <linux/mm.h>
-+#include <linux/poll.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/wait.h>
-+
-+#include <asm/uaccess.h>
-+
-+#include "switches.h"
-+
-+
-+MODULE_AUTHOR("John Dorsey");
-+MODULE_DESCRIPTION("Console switch support");
-+MODULE_LICENSE("GPL");
-+
-+
-+struct switches_action {
-+ struct list_head list;
-+ switches_mask_t mask;
-+};
-+
-+
-+static int switches_users = 0;
-+
-+static spinlock_t switches_lock = SPIN_LOCK_UNLOCKED;
-+
-+DECLARE_WAIT_QUEUE_HEAD(switches_wait);
-+LIST_HEAD(switches_event_queue);
-+
-+
-+static ssize_t switches_read(struct file *file, char *buffer,
-+ size_t count, loff_t *pos)
-+{
-+ unsigned long flags;
-+ struct list_head *event;
-+ struct switches_action *action;
-+
-+ if (count < sizeof(struct switches_mask_t))
-+ return -EINVAL;
-+
-+ while (list_empty(&switches_event_queue)) {
-+
-+ if (file->f_flags & O_NDELAY)
-+ return -EAGAIN;
-+
-+ interruptible_sleep_on(&switches_wait);
-+
-+ if (signal_pending(current))
-+ return -ERESTARTSYS;
-+
-+ }
-+
-+ if (verify_area(VERIFY_WRITE, buffer, sizeof(struct switches_mask_t)))
-+ return -EFAULT;
-+
-+ spin_lock_irqsave(&switches_lock, flags);
-+
-+ event = switches_event_queue.next;
-+ action = list_entry(event, struct switches_action, list);
-+ copy_to_user(buffer, &(action->mask), sizeof(struct switches_mask_t));
-+ list_del(event);
-+ kfree(action);
-+
-+ spin_unlock_irqrestore(&switches_lock, flags);
-+
-+ return 0;
-+
-+}
-+
-+static ssize_t switches_write(struct file *file, const char *buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ return -EINVAL;
-+}
-+
-+static unsigned int switches_poll(struct file *file, poll_table *wait)
-+{
-+
-+ poll_wait(file, &switches_wait, wait);
-+
-+ if (!list_empty(&switches_event_queue))
-+ return POLLIN | POLLRDNORM;
-+
-+ return 0;
-+
-+}
-+
-+static int switches_open(struct inode *inode, struct file *file)
-+{
-+
-+ if (switches_users > 0)
-+ return -EBUSY;
-+
-+ ++switches_users;
-+ return 0;
-+
-+}
-+
-+static int switches_release(struct inode *inode, struct file *file)
-+{
-+
-+ --switches_users;
-+ return 0;
-+
-+}
-+
-+static struct file_operations switches_ops = {
-+ .owner = THIS_MODULE,
-+ .read = switches_read,
-+ .write = switches_write,
-+ .poll = switches_poll,
-+ .open = switches_open,
-+ .release = switches_release,
-+};
-+
-+static struct miscdevice switches_misc = {
-+ .minor = MISC_DYNAMIC_MINOR,
-+ .name = SWITCHES_NAME,
-+ .fops = &switches_ops,
-+};
-+
-+int switches_event(switches_mask_t *mask)
-+{
-+ struct switches_action *action;
-+
-+ if ((switches_users > 0) && (SWITCHES_COUNT(mask) > 0)) {
-+
-+ if ((action = (struct switches_action *)
-+ kmalloc(sizeof(struct switches_action),
-+ GFP_KERNEL)) == NULL) {
-+ printk(KERN_ERR "%s: unable to allocate action "
-+ "descriptor\n", SWITCHES_NAME);
-+ return -1;
-+ }
-+
-+ action->mask = *mask;
-+
-+ spin_lock(&switches_lock);
-+ list_add_tail(&action->list, &switches_event_queue);
-+ spin_unlock(&switches_lock);
-+
-+ wake_up_interruptible(&switches_wait);
-+
-+ }
-+
-+ return 0;
-+
-+}
-+
-+EXPORT_SYMBOL(switches_event);
-+
-+
-+static int __init switches_init(void)
-+{
-+ if (misc_register(&switches_misc) < 0) {
-+ printk(KERN_ERR "%s: unable to register misc device\n",
-+ SWITCHES_NAME);
-+ return -EIO;
-+ }
-+
-+ printk(KERN_INFO "Console switches initialized\n");
-+
-+ return 0;
-+}
-+
-+static void __exit switches_exit(void)
-+{
-+ if (misc_deregister(&switches_misc) < 0)
-+ printk(KERN_ERR "%s: unable to deregister misc device\n",
-+ SWITCHES_NAME);
-+}
-+
-+module_init(switches_init);
-+module_exit(switches_exit);
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/misc/ucb1x00-audio.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,439 @@
-+/*
-+ * linux/drivers/misc/ucb1x00-audio.c
-+ *
-+ * Copyright (C) 2001 Russell King, 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 version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/fs.h>
-+#include <linux/errno.h>
-+#include <linux/slab.h>
-+#include <linux/sound.h>
-+#include <linux/soundcard.h>
-+#include <linux/list.h>
-+#include <linux/device.h>
-+
-+#include <asm/dma.h>
-+#include <asm/hardware.h>
-+#include <asm/semaphore.h>
-+#include <asm/uaccess.h>
-+
-+#include "ucb1x00.h"
-+
-+#include "../sound/oss/sa1100-audio.h"
-+
-+#define MAGIC 0x41544154
-+
-+struct ucb1x00_audio {
-+ struct file_operations fops;
-+ struct file_operations mops;
-+ struct ucb1x00 *ucb;
-+ audio_stream_t output_stream;
-+ audio_stream_t input_stream;
-+ audio_state_t state;
-+ unsigned int rate;
-+ int dev_id;
-+ int mix_id;
-+ unsigned int daa_oh_bit;
-+ unsigned int telecom;
-+ unsigned int magic;
-+ unsigned int ctrl_a;
-+ unsigned int ctrl_b;
-+
-+ /* mixer info */
-+ unsigned int mod_cnt;
-+ unsigned short output_level;
-+ unsigned short input_level;
-+};
-+
-+#define REC_MASK (SOUND_MASK_VOLUME | SOUND_MASK_MIC)
-+#define DEV_MASK REC_MASK
-+
-+static int
-+ucb1x00_mixer_ioctl(struct inode *ino, struct file *filp, uint cmd, ulong arg)
-+{
-+ struct ucb1x00_audio *ucba;
-+ unsigned int val, gain;
-+ int ret = 0;
-+
-+ ucba = list_entry(filp->f_op, struct ucb1x00_audio, mops);
-+
-+ if (_IOC_TYPE(cmd) != 'M')
-+ return -EINVAL;
-+
-+ if (cmd == SOUND_MIXER_INFO) {
-+ struct mixer_info mi;
-+
-+ strncpy(mi.id, "UCB1x00", sizeof(mi.id));
-+ strncpy(mi.name, "Philips UCB1x00", sizeof(mi.name));
-+ mi.modify_counter = ucba->mod_cnt;
-+ return copy_to_user((void *)arg, &mi, sizeof(mi)) ? -EFAULT : 0;
-+ }
-+
-+ if (_IOC_DIR(cmd) & _IOC_WRITE) {
-+ unsigned int left, right;
-+
-+ ret = get_user(val, (unsigned int *)arg);
-+ if (ret)
-+ goto out;
-+
-+ left = val & 255;
-+ right = val >> 8;
-+
-+ if (left > 100)
-+ left = 100;
-+ if (right > 100)
-+ right = 100;
-+
-+ gain = (left + right) / 2;
-+
-+ ret = -EINVAL;
-+ if (!ucba->telecom) {
-+ switch(_IOC_NR(cmd)) {
-+ case SOUND_MIXER_VOLUME:
-+ ucba->output_level = gain | gain << 8;
-+ ucba->mod_cnt++;
-+ ucba->ctrl_b = (ucba->ctrl_b & 0xff00) |
-+ ((gain * 31) / 100);
-+ ucb1x00_reg_write(ucba->ucb, UCB_AC_B,
-+ ucba->ctrl_b);
-+ ret = 0;
-+ break;
-+
-+ case SOUND_MIXER_MIC:
-+ ucba->input_level = gain | gain << 8;
-+ ucba->mod_cnt++;
-+ ucba->ctrl_a = (ucba->ctrl_a & 0x7f) |
-+ (((gain * 31) / 100) << 7);
-+ ucb1x00_reg_write(ucba->ucb, UCB_AC_A,
-+ ucba->ctrl_a);
-+ ret = 0;
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) {
-+ switch (_IOC_NR(cmd)) {
-+ case SOUND_MIXER_VOLUME:
-+ val = ucba->output_level;
-+ break;
-+
-+ case SOUND_MIXER_MIC:
-+ val = ucba->input_level;
-+ break;
-+
-+ case SOUND_MIXER_RECSRC:
-+ case SOUND_MIXER_RECMASK:
-+ val = ucba->telecom ? 0 : REC_MASK;
-+ break;
-+
-+ case SOUND_MIXER_DEVMASK:
-+ val = ucba->telecom ? 0 : DEV_MASK;
-+ break;
-+
-+ case SOUND_MIXER_CAPS:
-+ case SOUND_MIXER_STEREODEVS:
-+ val = 0;
-+ break;
-+
-+ default:
-+ val = 0;
-+ ret = -EINVAL;
-+ break;
-+ }
-+
-+ if (ret == 0)
-+ ret = put_user(val, (int *)arg);
-+ }
-+ out:
-+ return ret;
-+}
-+
-+static int ucb1x00_audio_setrate(struct ucb1x00_audio *ucba, int rate)
-+{
-+ unsigned int div_rate = ucb1x00_clkrate(ucba->ucb) / 32;
-+ unsigned int div;
-+
-+ div = (div_rate + (rate / 2)) / rate;
-+ if (div < 6)
-+ div = 6;
-+ if (div > 127)
-+ div = 127;
-+
-+ ucba->ctrl_a = (ucba->ctrl_a & ~0x7f) | div;
-+
-+ if (ucba->telecom) {
-+ ucb1x00_reg_write(ucba->ucb, UCB_TC_B, 0);
-+ ucb1x00_set_telecom_divisor(ucba->ucb, div * 32);
-+ ucb1x00_reg_write(ucba->ucb, UCB_TC_A, ucba->ctrl_a);
-+ ucb1x00_reg_write(ucba->ucb, UCB_TC_B, ucba->ctrl_b);
-+ } else {
-+ ucb1x00_reg_write(ucba->ucb, UCB_AC_B, 0);
-+ ucb1x00_set_audio_divisor(ucba->ucb, div * 32);
-+ ucb1x00_reg_write(ucba->ucb, UCB_AC_A, ucba->ctrl_a);
-+ ucb1x00_reg_write(ucba->ucb, UCB_AC_B, ucba->ctrl_b);
-+ }
-+
-+ ucba->rate = div_rate / div;
-+
-+ return ucba->rate;
-+}
-+
-+static int ucb1x00_audio_getrate(struct ucb1x00_audio *ucba)
-+{
-+ return ucba->rate;
-+}
-+
-+static void ucb1x00_audio_startup(void *data)
-+{
-+ struct ucb1x00_audio *ucba = data;
-+
-+ ucb1x00_enable(ucba->ucb);
-+ ucb1x00_audio_setrate(ucba, ucba->rate);
-+
-+ ucb1x00_reg_write(ucba->ucb, UCB_MODE, UCB_MODE_DYN_VFLAG_ENA);
-+
-+ /*
-+ * Take off-hook
-+ */
-+ if (ucba->daa_oh_bit)
-+ ucb1x00_io_write(ucba->ucb, 0, ucba->daa_oh_bit);
-+}
-+
-+static void ucb1x00_audio_shutdown(void *data)
-+{
-+ struct ucb1x00_audio *ucba = data;
-+
-+ /*
-+ * Place on-hook
-+ */
-+ if (ucba->daa_oh_bit)
-+ ucb1x00_io_write(ucba->ucb, ucba->daa_oh_bit, 0);
-+
-+ ucb1x00_reg_write(ucba->ucb, ucba->telecom ? UCB_TC_B : UCB_AC_B, 0);
-+ ucb1x00_disable(ucba->ucb);
-+}
-+
-+static int
-+ucb1x00_audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
-+{
-+ struct ucb1x00_audio *ucba;
-+ int val, ret = 0;
-+
-+ ucba = list_entry(file->f_op, struct ucb1x00_audio, fops);
-+
-+ /*
-+ * Make sure we have our magic number
-+ */
-+ if (ucba->magic != MAGIC)
-+ return -ENODEV;
-+
-+ switch (cmd) {
-+ case SNDCTL_DSP_STEREO:
-+ ret = get_user(val, (int *)arg);
-+ if (ret)
-+ return ret;
-+ if (val != 0)
-+ return -EINVAL;
-+ val = 0;
-+ break;
-+
-+ case SNDCTL_DSP_CHANNELS:
-+ case SOUND_PCM_READ_CHANNELS:
-+ val = 1;
-+ break;
-+
-+ case SNDCTL_DSP_SPEED:
-+ ret = get_user(val, (int *)arg);
-+ if (ret)
-+ return ret;
-+ val = ucb1x00_audio_setrate(ucba, val);
-+ break;
-+
-+ case SOUND_PCM_READ_RATE:
-+ val = ucb1x00_audio_getrate(ucba);
-+ break;
-+
-+ case SNDCTL_DSP_SETFMT:
-+ case SNDCTL_DSP_GETFMTS:
-+ val = AFMT_S16_LE;
-+ break;
-+
-+ default:
-+ return ucb1x00_mixer_ioctl(inode, file, cmd, arg);
-+ }
-+
-+ return put_user(val, (int *)arg);
-+}
-+
-+static int ucb1x00_audio_open(struct inode *inode, struct file *file)
-+{
-+ struct ucb1x00_audio *ucba;
-+
-+ ucba = list_entry(file->f_op, struct ucb1x00_audio, fops);
-+
-+ return sa1100_audio_attach(inode, file, &ucba->state);
-+}
-+
-+static struct ucb1x00_audio *ucb1x00_audio_alloc(struct ucb1x00 *ucb)
-+{
-+ struct ucb1x00_audio *ucba;
-+
-+ ucba = kmalloc(sizeof(*ucba), GFP_KERNEL);
-+ if (ucba) {
-+ memset(ucba, 0, sizeof(*ucba));
-+
-+ ucba->magic = MAGIC;
-+ ucba->ucb = ucb;
-+ ucba->fops.owner = THIS_MODULE;
-+ ucba->fops.open = ucb1x00_audio_open;
-+ ucba->mops.owner = THIS_MODULE;
-+ ucba->mops.ioctl = ucb1x00_mixer_ioctl;
-+ ucba->state.output_stream = &ucba->output_stream;
-+ ucba->state.input_stream = &ucba->input_stream;
-+ ucba->state.data = ucba;
-+ ucba->state.hw_init = ucb1x00_audio_startup;
-+ ucba->state.hw_shutdown = ucb1x00_audio_shutdown;
-+ ucba->state.client_ioctl = ucb1x00_audio_ioctl;
-+
-+ /* There is a bug in the StrongARM causes corrupt MCP data to be sent to
-+ * the codec when the FIFOs are empty and writes are made to the OS timer
-+ * match register 0. To avoid this we must make sure that data is always
-+ * sent to the codec.
-+ */
-+ ucba->state.need_tx_for_rx = 1;
-+
-+ init_MUTEX(&ucba->state.sem);
-+ ucba->rate = 8000;
-+ }
-+ return ucba;
-+}
-+
-+static struct ucb1x00_audio *ucb1x00_audio_add_one(struct ucb1x00 *ucb, int telecom)
-+{
-+ struct ucb1x00_audio *a;
-+
-+ a = ucb1x00_audio_alloc(ucb);
-+ if (a) {
-+ a->telecom = telecom;
-+
-+ a->input_stream.dev = ucb->cdev.dev;
-+ a->output_stream.dev = ucb->cdev.dev;
-+ a->ctrl_a = 0;
-+
-+ if (a->telecom) {
-+ a->input_stream.dma_dev = ucb->mcp->dma_telco_rd;
-+ a->input_stream.id = "UCB1x00 telco in";
-+ a->output_stream.dma_dev = ucb->mcp->dma_telco_wr;
-+ a->output_stream.id = "UCB1x00 telco out";
-+ a->ctrl_b = UCB_TC_B_IN_ENA|UCB_TC_B_OUT_ENA;
-+#if 0
-+ a->daa_oh_bit = UCB_IO_8;
-+
-+ ucb1x00_enable(ucb);
-+ ucb1x00_io_write(ucb, a->daa_oh_bit, 0);
-+ ucb1x00_io_set_dir(ucb, UCB_IO_7 | UCB_IO_6, a->daa_oh_bit);
-+ ucb1x00_disable(ucb);
-+#endif
-+ } else {
-+ a->input_stream.dma_dev = ucb->mcp->dma_audio_rd;
-+ a->input_stream.id = "UCB1x00 audio in";
-+ a->output_stream.dma_dev = ucb->mcp->dma_audio_wr;
-+ a->output_stream.id = "UCB1x00 audio out";
-+ a->ctrl_b = UCB_AC_B_IN_ENA|UCB_AC_B_OUT_ENA;
-+ }
-+
-+ a->dev_id = register_sound_dsp(&a->fops, -1);
-+ a->mix_id = register_sound_mixer(&a->mops, -1);
-+
-+ printk("Sound: UCB1x00 %s: dsp id %d mixer id %d\n",
-+ a->telecom ? "telecom" : "audio",
-+ a->dev_id, a->mix_id);
-+ }
-+
-+ return a;
-+}
-+
-+static void ucb1x00_audio_remove_one(struct ucb1x00_audio *a)
-+{
-+ unregister_sound_dsp(a->dev_id);
-+ unregister_sound_mixer(a->mix_id);
-+ kfree(a);
-+}
-+
-+static int ucb1x00_audio_add(struct class_device *cdev)
-+{
-+ struct ucb1x00 *ucb = classdev_to_ucb1x00(cdev);
-+
-+ if (ucb->cdev.dev == NULL || ucb->cdev.dev->dma_mask == NULL)
-+ return -ENXIO;
-+
-+ ucb->audio_data = ucb1x00_audio_add_one(ucb, 0);
-+ ucb->telecom_data = ucb1x00_audio_add_one(ucb, 1);
-+
-+ return 0;
-+}
-+
-+static void ucb1x00_audio_remove(struct class_device *cdev)
-+{
-+ struct ucb1x00 *ucb = classdev_to_ucb1x00(cdev);
-+
-+ ucb1x00_audio_remove_one(ucb->audio_data);
-+ ucb1x00_audio_remove_one(ucb->telecom_data);
-+}
-+
-+#if 0 //def CONFIG_PM
-+static int ucb1x00_audio_suspend(struct ucb1x00 *ucb, u32 state)
-+{
-+ struct ucb1x00_audio *a;
-+
-+ a = ucb->audio_data;
-+ sa1100_audio_suspend(&a->state, state);
-+ a = ucb->telecom_data;
-+ sa1100_audio_suspend(&a->state, state);
-+
-+ return 0;
-+}
-+
-+static int ucb1x00_audio_resume(struct ucb1x00 *ucb)
-+{
-+ struct ucb1x00_audio *a;
-+
-+ a = ucb->audio_data;
-+ sa1100_audio_resume(&a->state);
-+ a = ucb->telecom_data;
-+ sa1100_audio_resume(&a->state);
-+
-+ return 0;
-+}
-+#else
-+#define ucb1x00_audio_suspend NULL
-+#define ucb1x00_audio_resume NULL
-+#endif
-+
-+static struct class_interface ucb1x00_audio_interface = {
-+ .add = ucb1x00_audio_add,
-+ .remove = ucb1x00_audio_remove,
-+};
-+
-+static int __init ucb1x00_audio_init(void)
-+{
-+ return ucb1x00_register_interface(&ucb1x00_audio_interface);
-+}
-+
-+static void __exit ucb1x00_audio_exit(void)
-+{
-+ ucb1x00_unregister_interface(&ucb1x00_audio_interface);
-+}
-+
-+module_init(ucb1x00_audio_init);
-+module_exit(ucb1x00_audio_exit);
-+
-+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-+MODULE_DESCRIPTION("UCB1x00 telecom/audio driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/misc/mcp-sa1100.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,275 @@
-+/*
-+ * linux/drivers/misc/mcp-sa1100.c
-+ *
-+ * Copyright (C) 2001 Russell King
-+ *
-+ * 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.
-+ *
-+ * SA1100 MCP (Multimedia Communications Port) driver.
-+ *
-+ * MCP read/write timeouts from Jordi Colomer, rehacked by rmk.
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/spinlock.h>
-+#include <linux/slab.h>
-+#include <linux/device.h>
-+
-+#include <asm/dma.h>
-+#include <asm/hardware.h>
-+#include <asm/mach-types.h>
-+#include <asm/system.h>
-+
-+#include <asm/arch/assabet.h>
-+
-+#include "mcp.h"
-+
-+static void
-+mcp_sa1100_set_telecom_divisor(struct mcp *mcp, unsigned int divisor)
-+{
-+ unsigned int mccr0;
-+
-+ divisor /= 32;
-+
-+ mccr0 = Ser4MCCR0 & ~0x00007f00;
-+ mccr0 |= divisor << 8;
-+ Ser4MCCR0 = mccr0;
-+}
-+
-+static void
-+mcp_sa1100_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
-+{
-+ unsigned int mccr0;
-+
-+ divisor /= 32;
-+
-+ mccr0 = Ser4MCCR0 & ~0x0000007f;
-+ mccr0 |= divisor;
-+ Ser4MCCR0 = mccr0;
-+}
-+
-+/*
-+ * Write data to the device. The bit should be set after 3 subframe
-+ * times (each frame is 64 clocks). We wait a maximum of 6 subframes.
-+ * We really should try doing something more productive while we
-+ * wait.
-+ */
-+static void
-+mcp_sa1100_write(struct mcp *mcp, unsigned int reg, unsigned int val)
-+{
-+ int ret = -ETIME;
-+ int i;
-+
-+ Ser4MCDR2 = reg << 17 | MCDR2_Wr | (val & 0xffff);
-+
-+ for (i = 0; i < 2; i++) {
-+ udelay(mcp->rw_timeout);
-+ if (Ser4MCSR & MCSR_CWC) {
-+ ret = 0;
-+ break;
-+ }
-+ }
-+
-+ if (ret < 0)
-+ printk(KERN_WARNING "mcp: write timed out\n");
-+}
-+
-+/*
-+ * Read data from the device. The bit should be set after 3 subframe
-+ * times (each frame is 64 clocks). We wait a maximum of 6 subframes.
-+ * We really should try doing something more productive while we
-+ * wait.
-+ */
-+static unsigned int
-+mcp_sa1100_read(struct mcp *mcp, unsigned int reg)
-+{
-+ int ret = -ETIME;
-+ int i;
-+
-+ Ser4MCDR2 = reg << 17 | MCDR2_Rd;
-+
-+ for (i = 0; i < 2; i++) {
-+ udelay(mcp->rw_timeout);
-+ if (Ser4MCSR & MCSR_CRC) {
-+ ret = Ser4MCDR2 & 0xffff;
-+ break;
-+ }
-+ }
-+
-+ if (ret < 0)
-+ printk(KERN_WARNING "mcp: read timed out\n");
-+
-+ return ret;
-+}
-+
-+static void mcp_sa1100_enable(struct mcp *mcp)
-+{
-+ Ser4MCSR = -1;
-+ Ser4MCCR0 |= MCCR0_MCE;
-+}
-+
-+static void mcp_sa1100_disable(struct mcp *mcp)
-+{
-+ Ser4MCCR0 &= ~MCCR0_MCE;
-+}
-+
-+/*
-+ * Our methods.
-+ */
-+static struct mcp mcp_sa1100 = {
-+ .owner = THIS_MODULE,
-+ .lock = SPIN_LOCK_UNLOCKED,
-+ .sclk_rate = 11981000,
-+ .dma_audio_rd = DMA_Ser4MCP0Rd,
-+ .dma_audio_wr = DMA_Ser4MCP0Wr,
-+ .dma_telco_rd = DMA_Ser4MCP1Rd,
-+ .dma_telco_wr = DMA_Ser4MCP1Wr,
-+ .set_telecom_divisor = mcp_sa1100_set_telecom_divisor,
-+ .set_audio_divisor = mcp_sa1100_set_audio_divisor,
-+ .reg_write = mcp_sa1100_write,
-+ .reg_read = mcp_sa1100_read,
-+ .enable = mcp_sa1100_enable,
-+ .disable = mcp_sa1100_disable,
-+};
-+
-+static int mcp_sa1100_probe(struct device *dev)
-+{
-+ struct platform_device *pdev = to_platform_device(dev);
-+ struct mcp *mcp = &mcp_sa1100;
-+ int ret;
-+
-+ if (!machine_is_adsbitsy() && !machine_is_assabet() &&
-+ !machine_is_cerf() && !machine_is_flexanet() &&
-+ !machine_is_freebird() && !machine_is_graphicsclient() &&
-+ !machine_is_graphicsmaster() && !machine_is_lart() &&
-+ !machine_is_omnimeter() && !machine_is_pfs168() &&
-+ !machine_is_shannon() && !machine_is_simpad() &&
-+ !machine_is_yopy())
-+ return -ENODEV;
-+
-+ if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp"))
-+ return -EBUSY;
-+
-+ mcp->me = dev;
-+ dev_set_drvdata(dev, mcp);
-+
-+ if (machine_is_assabet()) {
-+ ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
-+ }
-+
-+ /*
-+ * Setup the PPC unit correctly.
-+ */
-+ PPDR &= ~PPC_RXD4;
-+ PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
-+ PSDR |= PPC_RXD4;
-+ PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-+ PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-+
-+ Ser4MCSR = -1;
-+ Ser4MCCR1 = 0;
-+ Ser4MCCR0 = 0x00007f7f | MCCR0_ADM;
-+
-+ /*
-+ * Calculate the read/write timeout (us) from the bit clock
-+ * rate. This is the period for 3 64-bit frames. Always
-+ * round this time up.
-+ */
-+ mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) /
-+ mcp->sclk_rate;
-+
-+ ret = mcp_host_register(mcp, &pdev->dev);
-+ if (ret != 0) {
-+ release_mem_region(0x80060000, 0x60);
-+ dev_set_drvdata(dev, NULL);
-+ }
-+
-+ return ret;
-+}
-+
-+static int mcp_sa1100_remove(struct device *dev)
-+{
-+ struct mcp *mcp = dev_get_drvdata(dev);
-+
-+ dev_set_drvdata(dev, NULL);
-+
-+ mcp_host_unregister(mcp);
-+ release_mem_region(0x80060000, 0x60);
-+
-+ return 0;
-+}
-+
-+struct mcp_sa1100_state {
-+ u32 mccr0;
-+ u32 mccr1;
-+};
-+
-+static int mcp_sa1100_suspend(struct device *dev, u32 state, u32 level)
-+{
-+ struct mcp_sa1100_state *s = (struct mcp_sa1100_state *)dev->saved_state;
-+
-+ if (!s) {
-+ s = kmalloc(sizeof(struct mcp_sa1100_state), GFP_KERNEL);
-+ dev->saved_state = (unsigned char *)s;
-+ }
-+
-+ if (s) {
-+ s->mccr0 = Ser4MCCR0;
-+ s->mccr1 = Ser4MCCR1;
-+ }
-+
-+ if (level == SUSPEND_DISABLE)
-+ Ser4MCCR0 &= ~MCCR0_MCE;
-+ return 0;
-+}
-+
-+static int mcp_sa1100_resume(struct device *dev, u32 level)
-+{
-+ struct mcp_sa1100_state *s = (struct mcp_sa1100_state *)dev->saved_state;
-+
-+ if (s && level == RESUME_RESTORE_STATE) {
-+ Ser4MCCR1 = s->mccr1;
-+ Ser4MCCR0 = s->mccr0;
-+
-+ dev->saved_state = NULL;
-+ kfree(s);
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * The driver for the SA11x0 MCP port.
-+ */
-+static struct device_driver mcp_sa1100_driver = {
-+ .name = "sa11x0-mcp",
-+ .bus = &platform_bus_type,
-+ .probe = mcp_sa1100_probe,
-+ .remove = mcp_sa1100_remove,
-+ .suspend = mcp_sa1100_suspend,
-+ .resume = mcp_sa1100_resume,
-+};
-+
-+/*
-+ * This needs re-working
-+ */
-+static int __init mcp_sa1100_init(void)
-+{
-+ return driver_register(&mcp_sa1100_driver);
-+}
-+
-+static void __exit mcp_sa1100_exit(void)
-+{
-+ driver_unregister(&mcp_sa1100_driver);
-+}
-+
-+module_init(mcp_sa1100_init);
-+module_exit(mcp_sa1100_exit);
-+
-+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-+MODULE_DESCRIPTION("SA11x0 multimedia communications port driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/misc/mcp.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,58 @@
-+/*
-+ * linux/drivers/misc/mcp.h
-+ *
-+ * Copyright (C) 2001 Russell King, 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.
-+ */
-+#ifndef MCP_H
-+#define MCP_H
-+
-+struct mcp {
-+ struct module *owner;
-+ struct device *me;
-+ spinlock_t lock;
-+ int use_count;
-+ unsigned int sclk_rate;
-+ unsigned int rw_timeout;
-+ dma_device_t dma_audio_rd;
-+ dma_device_t dma_audio_wr;
-+ dma_device_t dma_telco_rd;
-+ dma_device_t dma_telco_wr;
-+ void (*set_telecom_divisor)(struct mcp *, unsigned int);
-+ void (*set_audio_divisor)(struct mcp *, unsigned int);
-+ void (*reg_write)(struct mcp *, unsigned int, unsigned int);
-+ unsigned int (*reg_read)(struct mcp *, unsigned int);
-+ void (*enable)(struct mcp *);
-+ void (*disable)(struct mcp *);
-+ struct device attached_device;
-+};
-+
-+void mcp_set_telecom_divisor(struct mcp *, unsigned int);
-+void mcp_set_audio_divisor(struct mcp *, unsigned int);
-+void mcp_reg_write(struct mcp *, unsigned int, unsigned int);
-+unsigned int mcp_reg_read(struct mcp *, unsigned int);
-+void mcp_enable(struct mcp *);
-+void mcp_disable(struct mcp *);
-+#define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate)
-+
-+int mcp_host_register(struct mcp *, struct device *);
-+void mcp_host_unregister(struct mcp *);
-+
-+struct mcp_driver {
-+ struct device_driver drv;
-+ int (*probe)(struct mcp *);
-+ void (*remove)(struct mcp *);
-+ int (*suspend)(struct mcp *, u32);
-+ int (*resume)(struct mcp *);
-+};
-+
-+int mcp_driver_register(struct mcp_driver *);
-+void mcp_driver_unregister(struct mcp_driver *);
-+
-+#define mcp_get_drvdata(mcp) dev_get_drvdata(&(mcp)->attached_device)
-+#define mcp_set_drvdata(mcp,d) dev_set_drvdata(&(mcp)->attached_device, d)
-+
-+#endif
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/misc/ucb1x00-input.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,233 @@
-+/*
-+ * linux/drivers/misc/ucb1x00.h
-+ *
-+ * Copyright (C) 2001 Russell King, 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.
-+ */
-+#ifndef UCB1200_H
-+#define UCB1200_H
-+
-+#define UCB_IO_DATA 0x00
-+#define UCB_IO_DIR 0x01
-+
-+#define UCB_IO_0 (1 << 0)
-+#define UCB_IO_1 (1 << 1)
-+#define UCB_IO_2 (1 << 2)
-+#define UCB_IO_3 (1 << 3)
-+#define UCB_IO_4 (1 << 4)
-+#define UCB_IO_5 (1 << 5)
-+#define UCB_IO_6 (1 << 6)
-+#define UCB_IO_7 (1 << 7)
-+#define UCB_IO_8 (1 << 8)
-+#define UCB_IO_9 (1 << 9)
-+
-+#define UCB_IE_RIS 0x02
-+#define UCB_IE_FAL 0x03
-+#define UCB_IE_STATUS 0x04
-+#define UCB_IE_CLEAR 0x04
-+#define UCB_IE_ADC (1 << 11)
-+#define UCB_IE_TSPX (1 << 12)
-+#define UCB_IE_TSMX (1 << 13)
-+#define UCB_IE_TCLIP (1 << 14)
-+#define UCB_IE_ACLIP (1 << 15)
-+
-+#define UCB_IRQ_TSPX 12
-+
-+#define UCB_TC_A 0x05
-+#define UCB_TC_A_LOOP (1 << 7) /* UCB1200 */
-+#define UCB_TC_A_AMPL (1 << 7) /* UCB1300 */
-+
-+#define UCB_TC_B 0x06
-+#define UCB_TC_B_VOICE_ENA (1 << 3)
-+#define UCB_TC_B_CLIP (1 << 4)
-+#define UCB_TC_B_ATT (1 << 6)
-+#define UCB_TC_B_SIDE_ENA (1 << 11)
-+#define UCB_TC_B_MUTE (1 << 13)
-+#define UCB_TC_B_IN_ENA (1 << 14)
-+#define UCB_TC_B_OUT_ENA (1 << 15)
-+
-+#define UCB_AC_A 0x07
-+#define UCB_AC_B 0x08
-+#define UCB_AC_B_LOOP (1 << 8)
-+#define UCB_AC_B_MUTE (1 << 13)
-+#define UCB_AC_B_IN_ENA (1 << 14)
-+#define UCB_AC_B_OUT_ENA (1 << 15)
-+
-+#define UCB_TS_CR 0x09
-+#define UCB_TS_CR_TSMX_POW (1 << 0)
-+#define UCB_TS_CR_TSPX_POW (1 << 1)
-+#define UCB_TS_CR_TSMY_POW (1 << 2)
-+#define UCB_TS_CR_TSPY_POW (1 << 3)
-+#define UCB_TS_CR_TSMX_GND (1 << 4)
-+#define UCB_TS_CR_TSPX_GND (1 << 5)
-+#define UCB_TS_CR_TSMY_GND (1 << 6)
-+#define UCB_TS_CR_TSPY_GND (1 << 7)
-+#define UCB_TS_CR_MODE_INT (0 << 8)
-+#define UCB_TS_CR_MODE_PRES (1 << 8)
-+#define UCB_TS_CR_MODE_POS (2 << 8)
-+#define UCB_TS_CR_BIAS_ENA (1 << 11)
-+#define UCB_TS_CR_TSPX_LOW (1 << 12)
-+#define UCB_TS_CR_TSMX_LOW (1 << 13)
-+
-+#define UCB_ADC_CR 0x0a
-+#define UCB_ADC_SYNC_ENA (1 << 0)
-+#define UCB_ADC_VREFBYP_CON (1 << 1)
-+#define UCB_ADC_INP_TSPX (0 << 2)
-+#define UCB_ADC_INP_TSMX (1 << 2)
-+#define UCB_ADC_INP_TSPY (2 << 2)
-+#define UCB_ADC_INP_TSMY (3 << 2)
-+#define UCB_ADC_INP_AD0 (4 << 2)
-+#define UCB_ADC_INP_AD1 (5 << 2)
-+#define UCB_ADC_INP_AD2 (6 << 2)
-+#define UCB_ADC_INP_AD3 (7 << 2)
-+#define UCB_ADC_EXT_REF (1 << 5)
-+#define UCB_ADC_START (1 << 7)
-+#define UCB_ADC_ENA (1 << 15)
-+
-+#define UCB_ADC_DATA 0x0b
-+#define UCB_ADC_DAT_VAL (1 << 15)
-+#define UCB_ADC_DAT(x) (((x) & 0x7fe0) >> 5)
-+
-+#define UCB_ID 0x0c
-+#define UCB_ID_1200 0x1004
-+#define UCB_ID_1300 0x1005
-+#define UCB_ID_1400 0x4304
-+#define UCB_ID_1400_BUGGY 0x4303 /* fake ID */
-+
-+#define UCB_MODE 0x0d
-+#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
-+#define UCB_MODE_AUD_OFF_CAN (1 << 13)
-+
-+#include "mcp.h"
-+
-+struct ucb1x00;
-+
-+struct ucb1x00_irq {
-+ void *devid;
-+ void (*fn)(int, void *);
-+};
-+
-+struct ucb1x00 {
-+ spinlock_t lock;
-+ struct mcp *mcp;
-+ unsigned int irq;
-+ struct semaphore adc_sem;
-+ spinlock_t io_lock;
-+ u16 id;
-+ u16 io_dir;
-+ u16 io_out;
-+ u16 adc_cr;
-+ u16 irq_fal_enbl;
-+ u16 irq_ris_enbl;
-+ struct ucb1x00_irq irq_handler[16];
-+};
-+
-+/**
-+ * ucb1x00_clkrate - return the UCB1x00 SIB clock rate
-+ * @ucb: UCB1x00 structure describing chip
-+ *
-+ * Return the SIB clock rate in Hz.
-+ */
-+static inline unsigned int ucb1x00_clkrate(struct ucb1x00 *ucb)
-+{
-+ return mcp_get_sclk_rate(ucb->mcp);
-+}
-+
-+/**
-+ * ucb1x00_enable - enable the UCB1x00 SIB clock
-+ * @ucb: UCB1x00 structure describing chip
-+ *
-+ * Enable the SIB clock. This can be called multiple times.
-+ */
-+static inline void ucb1x00_enable(struct ucb1x00 *ucb)
-+{
-+ mcp_enable(ucb->mcp);
-+}
-+
-+/**
-+ * ucb1x00_disable - disable the UCB1x00 SIB clock
-+ * @ucb: UCB1x00 structure describing chip
-+ *
-+ * Disable the SIB clock. The SIB clock will only be disabled
-+ * when the number of ucb1x00_enable calls match the number of
-+ * ucb1x00_disable calls.
-+ */
-+static inline void ucb1x00_disable(struct ucb1x00 *ucb)
-+{
-+ mcp_disable(ucb->mcp);
-+}
-+
-+/**
-+ * ucb1x00_reg_write - write a UCB1x00 register
-+ * @ucb: UCB1x00 structure describing chip
-+ * @reg: UCB1x00 4-bit register index to write
-+ * @val: UCB1x00 16-bit value to write
-+ *
-+ * Write the UCB1x00 register @reg with value @val. The SIB
-+ * clock must be running for this function to return.
-+ */
-+static inline void ucb1x00_reg_write(struct ucb1x00 *ucb, unsigned int reg, unsigned int val)
-+{
-+ mcp_reg_write(ucb->mcp, reg, val);
-+}
-+
-+/**
-+ * ucb1x00_reg_read - read a UCB1x00 register
-+ * @ucb: UCB1x00 structure describing chip
-+ * @reg: UCB1x00 4-bit register index to write
-+ *
-+ * Read the UCB1x00 register @reg and return its value. The SIB
-+ * clock must be running for this function to return.
-+ */
-+static inline unsigned int ucb1x00_reg_read(struct ucb1x00 *ucb, unsigned int reg)
-+{
-+ return mcp_reg_read(ucb->mcp, reg);
-+}
-+/**
-+ * ucb1x00_set_audio_divisor -
-+ * @ucb: UCB1x00 structure describing chip
-+ * @div: SIB clock divisor
-+ */
-+static inline void ucb1x00_set_audio_divisor(struct ucb1x00 *ucb, unsigned int div)
-+{
-+ mcp_set_audio_divisor(ucb->mcp, div);
-+}
-+
-+/**
-+ * ucb1x00_set_telecom_divisor -
-+ * @ucb: UCB1x00 structure describing chip
-+ * @div: SIB clock divisor
-+ */
-+static inline void ucb1x00_set_telecom_divisor(struct ucb1x00 *ucb, unsigned int div)
-+{
-+ mcp_set_telecom_divisor(ucb->mcp, div);
-+}
-+
-+struct ucb1x00 *ucb1x00_get(void);
-+
-+void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int, unsigned int);
-+void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int, unsigned int);
-+unsigned int ucb1x00_io_read(struct ucb1x00 *ucb);
-+
-+#define UCB_NOSYNC (0)
-+#define UCB_SYNC (1)
-+
-+unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync);
-+void ucb1x00_adc_enable(struct ucb1x00 *ucb);
-+void ucb1x00_adc_disable(struct ucb1x00 *ucb);
-+
-+/*
-+ * Which edges of the IRQ do you want to control today?
-+ */
-+#define UCB_RISING (1 << 0)
-+#define UCB_FALLING (1 << 1)
-+
-+int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid);
-+void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
-+void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
-+int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid);
-+
-+#endif
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/misc/ucb1x00.h 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,271 @@
-+/*
-+ * linux/drivers/misc/ucb1x00.h
-+ *
-+ * Copyright (C) 2001 Russell King, 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.
-+ */
-+#ifndef UCB1200_H
-+#define UCB1200_H
-+
-+#ifdef CONFIG_ARCH_PXA
-+
-+/* ucb1400 aclink register mappings: */
-+
-+#define UCB_IO_DATA 0x5a
-+#define UCB_IO_DIR 0x5c
-+#define UCB_IE_RIS 0x5e
-+#define UCB_IE_FAL 0x60
-+#define UCB_IE_STATUS 0x62
-+#define UCB_IE_CLEAR 0x62
-+#define UCB_TS_CR 0x64
-+#define UCB_ADC_CR 0x66
-+#define UCB_ADC_DATA 0x68
-+#define UCB_ID 0x7e /* 7c is mfr id, 7e part id (from aclink spec) */
-+
-+#define UCB_ADC_DAT(x) ((x) & 0x3ff)
-+
-+#else
-+
-+/* ucb1x00 SIB register mappings: */
-+
-+#define UCB_IO_DATA 0x00
-+#define UCB_IO_DIR 0x01
-+#define UCB_IE_RIS 0x02
-+#define UCB_IE_FAL 0x03
-+#define UCB_IE_STATUS 0x04
-+#define UCB_IE_CLEAR 0x04
-+#define UCB_TC_A 0x05
-+#define UCB_TC_B 0x06
-+#define UCB_AC_A 0x07
-+#define UCB_AC_B 0x08
-+#define UCB_TS_CR 0x09
-+#define UCB_ADC_CR 0x0a
-+#define UCB_ADC_DATA 0x0b
-+#define UCB_ID 0x0c
-+#define UCB_MODE 0x0d
-+
-+#define UCB_ADC_DAT(x) (((x) & 0x7fe0) >> 5)
-+
-+#endif
-+
-+
-+#define UCB_IO_0 (1 << 0)
-+#define UCB_IO_1 (1 << 1)
-+#define UCB_IO_2 (1 << 2)
-+#define UCB_IO_3 (1 << 3)
-+#define UCB_IO_4 (1 << 4)
-+#define UCB_IO_5 (1 << 5)
-+#define UCB_IO_6 (1 << 6)
-+#define UCB_IO_7 (1 << 7)
-+#define UCB_IO_8 (1 << 8)
-+#define UCB_IO_9 (1 << 9)
-+
-+#define UCB_IE_ADC (1 << 11)
-+#define UCB_IE_TSPX (1 << 12)
-+#define UCB_IE_TSMX (1 << 13)
-+#define UCB_IE_TCLIP (1 << 14)
-+#define UCB_IE_ACLIP (1 << 15)
-+
-+#define UCB_IRQ_TSPX 12
-+
-+#define UCB_TC_A_LOOP (1 << 7) /* UCB1200 */
-+#define UCB_TC_A_AMPL (1 << 7) /* UCB1300 */
-+
-+#define UCB_TC_B_VOICE_ENA (1 << 3)
-+#define UCB_TC_B_CLIP (1 << 4)
-+#define UCB_TC_B_ATT (1 << 6)
-+#define UCB_TC_B_SIDE_ENA (1 << 11)
-+#define UCB_TC_B_MUTE (1 << 13)
-+#define UCB_TC_B_IN_ENA (1 << 14)
-+#define UCB_TC_B_OUT_ENA (1 << 15)
-+
-+#define UCB_AC_B_LOOP (1 << 8)
-+#define UCB_AC_B_MUTE (1 << 13)
-+#define UCB_AC_B_IN_ENA (1 << 14)
-+#define UCB_AC_B_OUT_ENA (1 << 15)
-+
-+#define UCB_TS_CR_TSMX_POW (1 << 0)
-+#define UCB_TS_CR_TSPX_POW (1 << 1)
-+#define UCB_TS_CR_TSMY_POW (1 << 2)
-+#define UCB_TS_CR_TSPY_POW (1 << 3)
-+#define UCB_TS_CR_TSMX_GND (1 << 4)
-+#define UCB_TS_CR_TSPX_GND (1 << 5)
-+#define UCB_TS_CR_TSMY_GND (1 << 6)
-+#define UCB_TS_CR_TSPY_GND (1 << 7)
-+#define UCB_TS_CR_MODE_INT (0 << 8)
-+#define UCB_TS_CR_MODE_PRES (1 << 8)
-+#define UCB_TS_CR_MODE_POS (2 << 8)
-+#define UCB_TS_CR_BIAS_ENA (1 << 11)
-+#define UCB_TS_CR_TSPX_LOW (1 << 12)
-+#define UCB_TS_CR_TSMX_LOW (1 << 13)
-+
-+#define UCB_ADC_SYNC_ENA (1 << 0)
-+#define UCB_ADC_VREFBYP_CON (1 << 1)
-+#define UCB_ADC_INP_TSPX (0 << 2)
-+#define UCB_ADC_INP_TSMX (1 << 2)
-+#define UCB_ADC_INP_TSPY (2 << 2)
-+#define UCB_ADC_INP_TSMY (3 << 2)
-+#define UCB_ADC_INP_AD0 (4 << 2)
-+#define UCB_ADC_INP_AD1 (5 << 2)
-+#define UCB_ADC_INP_AD2 (6 << 2)
-+#define UCB_ADC_INP_AD3 (7 << 2)
-+#define UCB_ADC_EXT_REF (1 << 5)
-+#define UCB_ADC_START (1 << 7)
-+#define UCB_ADC_ENA (1 << 15)
-+
-+#define UCB_ADC_DAT_VAL (1 << 15)
-+
-+#define UCB_ID_1200 0x1004
-+#define UCB_ID_1300 0x1005
-+#define UCB_ID_1400 0x4304
-+#define UCB_ID_1400_BUGGY 0x4303 /* fake ID */
-+
-+#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
-+#define UCB_MODE_AUD_OFF_CAN (1 << 13)
-+
-+#include <linux/completion.h>
-+#include "mcp.h"
-+
-+struct ucb1x00_irq {
-+ void *devid;
-+ void (*fn)(int, void *);
-+};
-+
-+extern struct class ucb1x00_class;
-+
-+struct ucb1x00 {
-+ spinlock_t lock;
-+ struct mcp *mcp;
-+ unsigned int irq;
-+ struct semaphore adc_sem;
-+ spinlock_t io_lock;
-+ wait_queue_head_t irq_wait;
-+ struct completion complete;
-+ struct task_struct *rtask;
-+ u16 id;
-+ u16 io_dir;
-+ u16 io_out;
-+ u16 adc_cr;
-+ u16 irq_fal_enbl;
-+ u16 irq_ris_enbl;
-+ struct ucb1x00_irq irq_handler[16];
-+ struct class_device cdev;
-+ void *audio_data;
-+ void *telecom_data;
-+ void *ts_data;
-+};
-+
-+#define classdev_to_ucb1x00(cd) container_of(cd, struct ucb1x00, cdev)
-+
-+int ucb1x00_register_interface(struct class_interface *intf);
-+void ucb1x00_unregister_interface(struct class_interface *intf);
-+
-+/**
-+ * ucb1x00_clkrate - return the UCB1x00 SIB clock rate
-+ * @ucb: UCB1x00 structure describing chip
-+ *
-+ * Return the SIB clock rate in Hz.
-+ */
-+static inline unsigned int ucb1x00_clkrate(struct ucb1x00 *ucb)
-+{
-+ return mcp_get_sclk_rate(ucb->mcp);
-+}
-+
-+/**
-+ * ucb1x00_enable - enable the UCB1x00 SIB clock
-+ * @ucb: UCB1x00 structure describing chip
-+ *
-+ * Enable the SIB clock. This can be called multiple times.
-+ */
-+static inline void ucb1x00_enable(struct ucb1x00 *ucb)
-+{
-+ mcp_enable(ucb->mcp);
-+}
-+
-+/**
-+ * ucb1x00_disable - disable the UCB1x00 SIB clock
-+ * @ucb: UCB1x00 structure describing chip
-+ *
-+ * Disable the SIB clock. The SIB clock will only be disabled
-+ * when the number of ucb1x00_enable calls match the number of
-+ * ucb1x00_disable calls.
-+ */
-+static inline void ucb1x00_disable(struct ucb1x00 *ucb)
-+{
-+ mcp_disable(ucb->mcp);
-+}
-+
-+/**
-+ * ucb1x00_reg_write - write a UCB1x00 register
-+ * @ucb: UCB1x00 structure describing chip
-+ * @reg: UCB1x00 4-bit register index to write
-+ * @val: UCB1x00 16-bit value to write
-+ *
-+ * Write the UCB1x00 register @reg with value @val. The SIB
-+ * clock must be running for this function to return.
-+ */
-+static inline void ucb1x00_reg_write(struct ucb1x00 *ucb, unsigned int reg, unsigned int val)
-+{
-+ mcp_reg_write(ucb->mcp, reg, val);
-+}
-+
-+/**
-+ * ucb1x00_reg_read - read a UCB1x00 register
-+ * @ucb: UCB1x00 structure describing chip
-+ * @reg: UCB1x00 4-bit register index to write
-+ *
-+ * Read the UCB1x00 register @reg and return its value. The SIB
-+ * clock must be running for this function to return.
-+ */
-+static inline unsigned int ucb1x00_reg_read(struct ucb1x00 *ucb, unsigned int reg)
-+{
-+ return mcp_reg_read(ucb->mcp, reg);
-+}
-+/**
-+ * ucb1x00_set_audio_divisor -
-+ * @ucb: UCB1x00 structure describing chip
-+ * @div: SIB clock divisor
-+ */
-+static inline void ucb1x00_set_audio_divisor(struct ucb1x00 *ucb, unsigned int div)
-+{
-+ mcp_set_audio_divisor(ucb->mcp, div);
-+}
-+
-+/**
-+ * ucb1x00_set_telecom_divisor -
-+ * @ucb: UCB1x00 structure describing chip
-+ * @div: SIB clock divisor
-+ */
-+static inline void ucb1x00_set_telecom_divisor(struct ucb1x00 *ucb, unsigned int div)
-+{
-+ mcp_set_telecom_divisor(ucb->mcp, div);
-+}
-+
-+#define ucb1x00_get() NULL
-+
-+void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int, unsigned int);
-+void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int, unsigned int);
-+unsigned int ucb1x00_io_read(struct ucb1x00 *ucb);
-+
-+#define UCB_NOSYNC (0)
-+#define UCB_SYNC (1)
-+
-+unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync);
-+void ucb1x00_adc_enable(struct ucb1x00 *ucb);
-+void ucb1x00_adc_disable(struct ucb1x00 *ucb);
-+
-+/*
-+ * Which edges of the IRQ do you want to control today?
-+ */
-+#define UCB_RISING (1 << 0)
-+#define UCB_FALLING (1 << 1)
-+
-+int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid);
-+void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
-+void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
-+int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid);
-+
-+#endif
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/misc/switches-sa1100.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,323 @@
-+/*
-+ * linux/drivers/misc/switches-sa1100.c
-+ *
-+ * Copyright (C) 2001 John Dorsey
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 19 December 2001 - created from sa1100_switches.c.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/interrupt.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/mach-types.h>
-+#include <asm/irq.h>
-+
-+#include <asm/arch/assabet.h>
-+#include <asm/arch/neponset.h>
-+#include <asm/arch/badge4.h>
-+
-+#include "switches.h"
-+
-+
-+static irqreturn_t switches_sa1100_handler(int irq, void *dev_id,
-+ struct pt_regs *regs);
-+
-+
-+#ifdef CONFIG_SA1100_ASSABET
-+
-+/* Assabet
-+ * ^^^^^^^
-+ * We have two general-purpose switches, S1 and S2, available via GPIO
-+ * on Assabet. This code sets bits in the range [1, 2] in the mask that
-+ * we return to userland.
-+ */
-+
-+static int assabet_switches_sa1100_init(void)
-+{
-+
-+ if (machine_has_neponset())
-+ NCR_0 |= NCR_GP01_OFF;
-+
-+ if (request_irq(IRQ_GPIO0, switches_sa1100_handler, SA_INTERRUPT,
-+ SWITCHES_NAME, NULL) < 0) {
-+ printk(KERN_ERR "%s: unable to register IRQ for GPIO 0\n",
-+ SWITCHES_NAME);
-+ return -EIO;
-+ }
-+
-+ if (request_irq(IRQ_GPIO1, switches_sa1100_handler, SA_INTERRUPT,
-+ SWITCHES_NAME, NULL) < 0) {
-+ printk(KERN_ERR "%s: unable to register IRQ for GPIO 1\n",
-+ SWITCHES_NAME);
-+ free_irq(IRQ_GPIO0, NULL);
-+ return -EIO;
-+ }
-+
-+ set_irq_type(IRQ_GPIO0, IRQT_BOTHEDGE);
-+ set_irq_type(IRQ_GPIO1, IRQT_BOTHEDGE);
-+
-+ return 0;
-+
-+}
-+
-+static void assabet_switches_sa1100_shutdown(void)
-+{
-+
-+ free_irq(IRQ_GPIO1, NULL);
-+ free_irq(IRQ_GPIO0, NULL);
-+
-+}
-+
-+static irqreturn_t assabet_switches_sa1100_handler(int irq, switches_mask_t *mask)
-+{
-+ unsigned int s, last, this;
-+ static unsigned int states = 0;
-+
-+ switch (irq) {
-+
-+ case IRQ_GPIO0: s = 0; break;
-+
-+ case IRQ_GPIO1: s = 1; break;
-+
-+ default: return IRQ_NONE;
-+
-+ }
-+
-+ last = ((states & (1 << s)) != 0);
-+ this = ((GPLR & GPIO_GPIO(s)) != 0);
-+
-+ if (last == this) /* debounce */
-+ return IRQ_HANDLED;
-+
-+ SWITCHES_SET(mask, s + 1, this);
-+
-+ states = this ? (states | (1 << s)) : (states & ~(1 << s));
-+
-+ return IRQ_HANDLED;
-+}
-+#endif /* CONFIG_SA1100_ASSABET */
-+
-+#ifdef CONFIG_SA1100_BADGE4
-+
-+/* BadgePAD 4
-+ * ^^^^^^^^^^
-+ *
-+ * Here we use test point J6 (BADGE4_GPIO_TESTPT_J6 aka GPIO 23) as a
-+ * general purpose switch input. We map this to switch #0.
-+ */
-+
-+#define BADGE4_SW0_GPIO GPIO_GPIO23 /* aka BADGE4_GPIO_TESTPT_J6 */
-+#define BADGE4_SW0_IRQ IRQ_GPIO23
-+
-+static int badge4_switches_sa1100_init(void)
-+{
-+ if (request_irq(BADGE4_SW0_IRQ, switches_sa1100_handler, SA_INTERRUPT,
-+ SWITCHES_NAME, NULL) < 0) {
-+ printk(KERN_ERR "%s: unable to register IRQ for SW0\n",
-+ SWITCHES_NAME);
-+ return -EIO;
-+ }
-+
-+ set_irq_type(BADGE4_SW0_IRQ, IRQT_BOTHEDGE);
-+
-+ return 0;
-+}
-+
-+static void badge4_switches_sa1100_shutdown(void)
-+{
-+ free_irq(BADGE4_SW0_IRQ, NULL);
-+}
-+
-+static irqreturn_t badge4_switches_sa1100_handler(int irq, switches_mask_t *mask)
-+{
-+ unsigned int swno, last, this, gpio;
-+ static unsigned int states = 0;
-+
-+ switch (irq) {
-+ case BADGE4_SW0_IRQ:
-+ swno = 0;
-+ gpio = BADGE4_SW0_GPIO;
-+ break;
-+ default:
-+ return IRQ_NONE;
-+ }
-+
-+ last = ((states & gpio) != 0);
-+ this = ((GPLR & gpio) != 0);
-+
-+ if (last == this) /* debounce */
-+ return IRQ_HANDLED;
-+
-+ SWITCHES_SET(mask, swno, this);
-+
-+ states = this ? (states | gpio) : (states & ~gpio);
-+
-+ return IRQ_HANDLED;
-+}
-+#endif /* CONFIG_SA1100_BADGE4 */
-+
-+
-+#ifdef CONFIG_SA1100_SPOT
-+
-+/* Spot
-+ * ^^^^
-+ * Spot (R2, R3) has a single general-purpose switch (S1), which is
-+ * also the power-on switch. We set bit [1] in the mask we return to
-+ * userland.
-+ */
-+
-+static int spot_switches_sa1100_init(void)
-+{
-+
-+ set_GPIO_IRQ_edge(GPIO_SW1, GPIO_BOTH_EDGES);
-+
-+ if (request_irq(IRQ_GPIO_SW1, switches_sa1100_handler, SA_INTERRUPT,
-+ SWITCHES_NAME, NULL) < 0) {
-+ printk(KERN_ERR "%s: unable to register IRQ for SW1\n",
-+ SWITCHES_NAME);
-+ return -EIO;
-+ }
-+
-+ return 0;
-+
-+}
-+
-+static void spot_switches_sa1100_shutdown(void)
-+{
-+
-+ free_irq(IRQ_GPIO_SW1, NULL);
-+
-+}
-+
-+static irqreturn_t spot_switches_sa1100_handler(int irq, switches_mask_t *mask)
-+{
-+ unsigned int s, last, this;
-+ static unsigned int states = 0;
-+
-+ switch (irq) {
-+
-+ case IRQ_GPIO_SW1: s = 0; break;
-+
-+ default: return IRQ_NONE;
-+
-+ }
-+
-+ last = ((states & (1 << s)) != 0);
-+ this = ((GPLR & GPIO_GPIO(s)) != 0);
-+
-+ if (last == this) /* debounce */
-+ return IRQ_HANDLED;
-+
-+ SWITCHES_SET(mask, s + 1, this);
-+
-+ states = this ? (states | (1 << s)) : (states & ~(1 << s));
-+
-+ return IRQ_HANDLED;
-+
-+}
-+#endif /* CONFIG_SA1100_SPOT */
-+
-+
-+/* switches_sa1100_handler()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * This routine is a generalized handler for SA-1100 switches
-+ * which manages action descriptors and calls a board-specific
-+ * service routine. This routine is appropriate for GPIO switches
-+ * or other primary interrupt sources, and can be registered as a
-+ * first-class IRQ handler using request_irq().
-+ */
-+static irqreturn_t switches_sa1100_handler(int irq, void *dev_id,
-+ struct pt_regs *regs)
-+{
-+ switches_mask_t mask;
-+ irqreturn_t ret = IRQ_NONE;
-+
-+ SWITCHES_ZERO(&mask);
-+
-+ /* Porting note: call a board-specific switch interrupt handler
-+ * here. The handler can assume that sufficient storage for
-+ * `mask' has been allocated, and that the corresponding
-+ * switches_mask_t structure has been zeroed.
-+ */
-+
-+ if (machine_is_assabet()) {
-+#ifdef CONFIG_SA1100_ASSABET
-+ ret = assabet_switches_sa1100_handler(irq, &mask);
-+#endif
-+ } else if (machine_is_badge4()) {
-+#ifdef CONFIG_SA1100_BADGE4
-+ ret = badge4_switches_sa1100_handler(irq, &mask);
-+#endif
-+ } else if (machine_is_spot()) {
-+#ifdef CONFIG_SA1100_SPOT
-+ ret = spot_switches_sa1100_handler(irq, &mask);
-+#endif
-+ }
-+
-+ switches_event(&mask);
-+
-+ return ret;
-+}
-+
-+int __init switches_sa1100_init(void)
-+{
-+
-+ /* Porting note: call a board-specific init routine here. */
-+
-+ if (machine_is_assabet()) {
-+#ifdef CONFIG_SA1100_ASSABET
-+ if (assabet_switches_sa1100_init() < 0)
-+ return -EIO;
-+#endif
-+ } else if (machine_is_badge4()) {
-+#ifdef CONFIG_SA1100_BADGE4
-+ if (badge4_switches_sa1100_init() < 0)
-+ return -EIO;
-+#endif
-+ } else if (machine_is_spot()) {
-+#ifdef CONFIG_SA1100_SPOT
-+ if (spot_switches_sa1100_init() < 0)
-+ return -EIO;
-+#endif
-+ }
-+
-+ return 0;
-+
-+}
-+
-+void __exit switches_sa1100_exit(void)
-+{
-+
-+ /* Porting note: call a board-specific shutdown routine here. */
-+
-+ if (machine_is_assabet()) {
-+#ifdef CONFIG_SA1100_ASSABET
-+ assabet_switches_sa1100_shutdown();
-+#endif
-+ } else if (machine_is_badge4()) {
-+#ifdef CONFIG_SA1100_BADGE4
-+ badge4_switches_sa1100_shutdown();
-+#endif
-+ } else if (machine_is_spot()) {
-+#ifdef CONFIG_SA1100_SPOT
-+ spot_switches_sa1100_shutdown();
-+#endif
-+ }
-+
-+}
-+
-+module_init(switches_sa1100_init);
-+module_exit(switches_sa1100_exit);
-+
-+MODULE_DESCRIPTION("SA-1100 switches driver");
-+MODULE_LICENSE("GPL");
---- linux-2.6.5/drivers/misc/Makefile~heh 2004-04-03 22:38:17.000000000 -0500
-+++ linux-2.6.5/drivers/misc/Makefile 2004-04-30 20:57:36.000000000 -0400
-@@ -4,3 +4,21 @@
- obj- := misc.o # Dummy rule to force built-in.o to be made
-
- obj-$(CONFIG_IBM_ASM) += ibmasm/
-+
-+obj-$(CONFIG_MCP) += mcp-core.o
-+obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
-+obj-$(CONFIG_MCP_UCB1200_AUDIO) += ucb1x00-audio.o
-+obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o
-+
-+ifeq ($(CONFIG_SA1100_ASSABET),y)
-+obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
-+endif
-+
-+obj-$(CONFIG_SWITCHES) += switches-core.o
-+obj-$(CONFIG_SWITCHES_SA1100) += switches-sa1100.o
-+obj-$(CONFIG_SWITCHES_UCB1X00) += switches-ucb1x00.o
-+
-+obj-$(CONFIG_MCP_SA1100) += mcp-sa1100.o
-+
-+obj-$(CONFIG_UCB1400_TS) += mcp-pxa.o ucb1x00-core.o ucb1x00-ts.o
-+
---- linux-2.6.5/drivers/i2c/busses/Kconfig~heh 2004-04-03 22:38:10.000000000 -0500
-+++ linux-2.6.5/drivers/i2c/busses/Kconfig 2004-04-30 20:57:36.000000000 -0400
-@@ -70,6 +70,16 @@
- This support is also available as a module. If so, the module
- will be called i2c-hydra.
-
-+config I2C_BIT_SA1100_GPIO
-+ bool "SA1100 I2C GPIO adapter"
-+ depends on ARCH_SA1100 && I2C_ALGOBIT
-+ help
-+ This supports I2C on the SA11x0 processor GPIO pins. This
-+ shares support with the L3 driver.
-+
-+ This support is also available as a module. If so, the module
-+ will be called l3-bit-sa1100.
-+
- config I2C_I801
- tristate "Intel 801"
- depends on I2C && PCI && EXPERIMENTAL
-@@ -241,6 +251,18 @@
- This support is also available as a module. If so, the module
- will be called i2c-prosavage.
-
-+config I2C_PXA2XX
-+ tristate "PXA I2C Interface"
-+ depends on I2C && ARCH_PXA
-+ select I2C_ALGOPXA
-+ help
-+ This supports the use of the PXA I2C interface found on the Intel
-+ PXA 25x and PXA 26x systems. Say Y if you have one of these.
-+
-+ This support is also available as a module. If you want to compile
-+ it as a module, say M here and read Documentation/modules.txt.
-+ The module will be called i2c-adap-pxa.
-+
- config I2C_RPXLITE
- tristate "Embedded Planet RPX Lite/Classic support"
- depends on (RPXLITE || RPXCLASSIC) && I2C
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/i2c/busses/pxa2xx_i2c.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,388 @@
-+/*
-+ * i2c_adap_pxa.c
-+ *
-+ * I2C adapter for the PXA I2C bus access.
-+ *
-+ * Copyright (C) 2002 Intrinsyc Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * History:
-+ * Apr 2002: Initial version [CS]
-+ * Jun 2002: Properly seperated algo/adap [FB]
-+ * Jan 2003: Fixed several bugs concerning interrupt handling [Kai-Uwe Bloem]
-+ * Jan 2003: added limited signal handling [Kai-Uwe Bloem]
-+ * Jun 2003: updated for 2.5 [Dustin McIntire]
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+
-+#include <linux/i2c.h>
-+#include <linux/i2c-id.h>
-+#include <linux/init.h>
-+#include <linux/time.h>
-+#include <linux/sched.h>
-+#include <linux/delay.h>
-+#include <linux/errno.h>
-+#include <linux/interrupt.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/arch/irqs.h> /* for IRQ_I2C */
-+
-+#include <linux/i2c-pxa.h>
-+
-+/*
-+ * Set this to zero to remove all debug statements via dead code elimination.
-+ */
-+//#define DEBUG 1
-+
-+#if DEBUG
-+static unsigned int i2c_debug = DEBUG;
-+#else
-+#define i2c_debug 0
-+#endif
-+
-+static int irq = 0;
-+static volatile int i2c_pending = 0; /* interrupt pending when 1 */
-+static volatile int bus_error = 0;
-+static volatile int tx_finished = 0;
-+static volatile int rx_finished = 0;
-+
-+static wait_queue_head_t i2c_wait;
-+static void i2c_pxa_transfer( int lastbyte, int receive, int midbyte);
-+
-+/* place a byte in the transmit register */
-+static void i2c_pxa_write_byte(u8 value)
-+{
-+ IDBR = value;
-+}
-+
-+/* read byte in the receive register */
-+static u8 i2c_pxa_read_byte(void)
-+{
-+ return (u8) (0xff & IDBR);
-+}
-+
-+static void i2c_pxa_start(void)
-+{
-+ unsigned long icr = ICR;
-+ icr |= ICR_START;
-+ icr &= ~(ICR_STOP | ICR_ALDIE | ICR_ACKNAK);
-+ ICR = icr;
-+
-+ bus_error=0; /* clear any bus_error from previous txfers */
-+ tx_finished=0; /* clear rx and tx interrupts from previous txfers */
-+ rx_finished=0;
-+ i2c_pending = 0;
-+}
-+
-+static void i2c_pxa_repeat_start(void)
-+{
-+ unsigned long icr = ICR;
-+ icr |= ICR_START;
-+ icr &= ~(ICR_STOP | ICR_ALDIE);
-+ ICR = icr;
-+
-+ bus_error=0; /* clear any bus_error from previous txfers */
-+ tx_finished=0; /* clear rx and tx interrupts from previous txfers */
-+ rx_finished=0;
-+ i2c_pending = 0;
-+}
-+
-+static void i2c_pxa_stop(void)
-+{
-+ unsigned long icr = ICR;
-+ icr |= ICR_STOP;
-+ icr &= ~(ICR_START);
-+ ICR = icr;
-+}
-+
-+static void i2c_pxa_midbyte(void)
-+{
-+ unsigned long icr = ICR;
-+ icr &= ~(ICR_START | ICR_STOP);
-+ ICR = icr;
-+}
-+
-+static void i2c_pxa_abort(void)
-+{
-+ unsigned long timeout = jiffies + HZ/4;
-+
-+#ifdef PXA_ABORT_MA
-+ while ((long)(timeout - jiffies) > 0 && (ICR & ICR_TB)) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(1);
-+ }
-+
-+ ICR |= ICR_MA;
-+ udelay(100);
-+#else
-+ while ((long)(timeout - jiffies) > 0 && (IBMR & 0x1) == 0) {
-+ i2c_pxa_transfer( 1, I2C_RECEIVE, 1);
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(1);
-+ }
-+#endif
-+ ICR &= ~(ICR_MA | ICR_START | ICR_STOP);
-+}
-+
-+static int i2c_pxa_wait_bus_not_busy( void)
-+{
-+ int timeout = DEF_TIMEOUT;
-+
-+ while (timeout-- && (ISR & ISR_IBB)) {
-+ udelay(100); /* wait for 100 us */
-+ }
-+
-+ return (timeout<=0);
-+}
-+
-+spinlock_t i2c_pxa_irqlock = SPIN_LOCK_UNLOCKED;
-+
-+static void i2c_pxa_wait_for_ite(void){
-+ unsigned long flags;
-+ if (irq > 0) {
-+ spin_lock_irqsave(&i2c_pxa_irqlock, flags);
-+ if (i2c_pending == 0) {
-+ interruptible_sleep_on_timeout(&i2c_wait, I2C_SLEEP_TIMEOUT );
-+ }
-+ i2c_pending = 0;
-+ spin_unlock_irqrestore(&i2c_pxa_irqlock, flags);
-+ } else {
-+ udelay(100);
-+ }
-+}
-+
-+static int i2c_pxa_wait_for_int( int wait_type)
-+{
-+ int timeout = DEF_TIMEOUT;
-+#ifdef DEBUG
-+ if (bus_error)
-+ printk(KERN_INFO"i2c_pxa_wait_for_int: Bus error on enter\n");
-+ if (rx_finished)
-+ printk(KERN_INFO"i2c_pxa_wait_for_int: Receive interrupt on enter\n");
-+ if (tx_finished)
-+ printk(KERN_INFO"i2c_pxa_wait_for_int: Transmit interrupt on enter\n");
-+#endif
-+
-+ if (wait_type == I2C_RECEIVE){ /* wait on receive */
-+
-+ do {
-+ i2c_pxa_wait_for_ite();
-+ } while (!(rx_finished) && timeout-- && !signal_pending(current));
-+
-+#ifdef DEBUG
-+ if (timeout<0){
-+ if (tx_finished)
-+ printk("Error: i2c-algo-pxa.o: received a tx"
-+ " interrupt while waiting on a rx in wait_for_int");
-+ }
-+#endif
-+ } else { /* wait on transmit */
-+
-+ do {
-+ i2c_pxa_wait_for_ite();
-+ } while (!(tx_finished) && timeout-- && !signal_pending(current));
-+
-+#ifdef DEBUG
-+ if (timeout<0){
-+ if (rx_finished)
-+ printk("Error: i2c-algo-pxa.o: received a rx"
-+ " interrupt while waiting on a tx in wait_for_int");
-+ }
-+#endif
-+ }
-+
-+ udelay(ACK_DELAY); /* this is needed for the bus error */
-+
-+ tx_finished=0;
-+ rx_finished=0;
-+
-+ if (bus_error){
-+ bus_error=0;
-+ if( i2c_debug > 2)printk("wait_for_int: error - no ack.\n");
-+ return BUS_ERROR;
-+ }
-+
-+ if (signal_pending(current)) {
-+ return (-ERESTARTSYS);
-+ } else if (timeout < 0) {
-+ if( i2c_debug > 2)printk("wait_for_int: timeout.\n");
-+ return(-EIO);
-+ } else
-+ return(0);
-+}
-+
-+static void i2c_pxa_transfer( int lastbyte, int receive, int midbyte)
-+{
-+ if( lastbyte)
-+ {
-+ if( receive==I2C_RECEIVE) ICR |= ICR_ACKNAK;
-+ i2c_pxa_stop();
-+ }
-+ else if( midbyte)
-+ {
-+ i2c_pxa_midbyte();
-+ }
-+ ICR |= ICR_TB;
-+}
-+
-+static void i2c_pxa_reset( void)
-+{
-+#ifdef DEBUG
-+ printk("Resetting I2C Controller Unit\n");
-+#endif
-+
-+ /* abort any transfer currently under way */
-+ i2c_pxa_abort();
-+
-+ /* reset according to 9.8 */
-+ ICR = ICR_UR;
-+ ISR = I2C_ISR_INIT;
-+ ICR &= ~ICR_UR;
-+
-+ /* set the global I2C clock on */
-+ CKEN |= CKEN14_I2C;
-+
-+ /* set our slave address */
-+ ISAR = I2C_PXA_SLAVE_ADDR;
-+
-+ /* set control register values */
-+ ICR = I2C_ICR_INIT;
-+
-+ /* clear any leftover states from prior transmissions */
-+ i2c_pending = rx_finished = tx_finished = bus_error = 0;
-+
-+ /* enable unit */
-+ ICR |= ICR_IUE;
-+ udelay(100);
-+}
-+
-+static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *regs)
-+{
-+ unsigned long flags;
-+ int status, wakeup = 0;
-+ status = (ISR);
-+
-+ if (status & ISR_BED){
-+ (ISR) |= ISR_BED;
-+ bus_error=ISR_BED;
-+ wakeup = 1;
-+ }
-+ if (status & ISR_ITE){
-+ (ISR) |= ISR_ITE;
-+ tx_finished=ISR_ITE;
-+ wakeup = 1;
-+ }
-+ if (status & ISR_IRF){
-+ (ISR) |= ISR_IRF;
-+ rx_finished=ISR_IRF;
-+ wakeup = 1;
-+ }
-+ if (wakeup) {
-+ spin_lock_irqsave(&i2c_pxa_irqlock, flags);
-+ i2c_pending = 1;
-+ spin_unlock_irqrestore(&i2c_pxa_irqlock, flags);
-+ wake_up_interruptible(&i2c_wait);
-+ }
-+ return IRQ_HANDLED;
-+}
-+
-+static int i2c_pxa_resource_init( void)
-+{
-+ init_waitqueue_head(&i2c_wait);
-+
-+ if (request_irq(IRQ_I2C, &i2c_pxa_handler, SA_INTERRUPT, "I2C", 0) < 0) {
-+ irq = 0;
-+ if(i2c_debug)
-+ printk(KERN_INFO "I2C: Failed to register I2C irq %i\n", IRQ_I2C);
-+ return -ENODEV;
-+ }
-+ return 0;
-+}
-+
-+static void i2c_pxa_resource_release( void)
-+{
-+ if( irq > 0)
-+ {
-+ disable_irq(irq);
-+ free_irq(irq,0);
-+ irq=0;
-+ }
-+}
-+
-+static int i2c_pxa_client_register(struct i2c_client *client)
-+{
-+ return 0;
-+}
-+
-+static int i2c_pxa_client_unregister(struct i2c_client *client)
-+{
-+ return 0;
-+}
-+
-+static struct i2c_algo_pxa_data i2c_pxa_data = {
-+ write_byte: i2c_pxa_write_byte,
-+ read_byte: i2c_pxa_read_byte,
-+
-+ start: i2c_pxa_start,
-+ repeat_start: i2c_pxa_repeat_start,
-+ stop: i2c_pxa_stop,
-+ abort: i2c_pxa_abort,
-+
-+ wait_bus_not_busy: i2c_pxa_wait_bus_not_busy,
-+ wait_for_interrupt: i2c_pxa_wait_for_int,
-+ transfer: i2c_pxa_transfer,
-+ reset: i2c_pxa_reset,
-+
-+ udelay: 10,
-+ timeout: DEF_TIMEOUT,
-+};
-+
-+static struct i2c_adapter i2c_pxa_ops = {
-+ .owner = THIS_MODULE,
-+ .id = I2C_ALGO_PXA,
-+ .algo_data = &i2c_pxa_data,
-+ .dev = {
-+ .name = "PXA I2C Adapter",
-+ },
-+ .client_register = i2c_pxa_client_register,
-+ .client_unregister = i2c_pxa_client_unregister,
-+ .retries = 2,
-+};
-+
-+extern int i2c_pxa_add_bus(struct i2c_adapter *);
-+extern int i2c_pxa_del_bus(struct i2c_adapter *);
-+
-+static int __init i2c_adap_pxa_init(void)
-+{
-+ if( i2c_pxa_resource_init() == 0) {
-+
-+ if (i2c_pxa_add_bus(&i2c_pxa_ops) < 0) {
-+ i2c_pxa_resource_release();
-+ printk(KERN_INFO "I2C: Failed to add bus\n");
-+ return -ENODEV;
-+ }
-+ } else {
-+ return -ENODEV;
-+ }
-+
-+ printk(KERN_INFO "I2C: Successfully added bus\n");
-+
-+ return 0;
-+}
-+
-+static void i2c_adap_pxa_exit(void)
-+{
-+ i2c_pxa_del_bus( &i2c_pxa_ops);
-+ i2c_pxa_resource_release();
-+
-+ printk(KERN_INFO "I2C: Successfully removed bus\n");
-+}
-+
-+module_init(i2c_adap_pxa_init);
-+module_exit(i2c_adap_pxa_exit);
---- linux-2.6.5/drivers/i2c/busses/Makefile~heh 2004-04-03 22:36:17.000000000 -0500
-+++ linux-2.6.5/drivers/i2c/busses/Makefile 2004-04-30 20:57:36.000000000 -0400
-@@ -21,6 +21,7 @@
- obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o
- obj-$(CONFIG_I2C_PIIX4) += i2c-piix4.o
- obj-$(CONFIG_I2C_PROSAVAGE) += i2c-prosavage.o
-+obj-$(CONFIG_I2C_PXA) += pxa2xx_i2c.o
- obj-$(CONFIG_I2C_RPXLITE) += i2c-rpx.o
- obj-$(CONFIG_I2C_SAVAGE4) += i2c-savage4.o
- obj-$(CONFIG_I2C_SIS5595) += i2c-sis5595.o
---- linux-2.6.5/drivers/i2c/algos/Kconfig~heh 2004-04-03 22:37:59.000000000 -0500
-+++ linux-2.6.5/drivers/i2c/algos/Kconfig 2004-04-30 20:57:36.000000000 -0400
-@@ -38,6 +38,18 @@
- This support is also available as a module. If so, the module
- will be called i2c-algo-ite.
-
-+config I2C_ALGOPXA
-+ tristate "PXA I2C Algorithm"
-+ depends on ARCH_PXA && I2C
-+ help
-+ This supports the use of the PXA I2C interface found on the Intel
-+ PXA 25x and PXA 26x systems. Say Y if you have one of these.
-+ You should also say Y for the PXA I2C peripheral driver support below.
-+
-+ This support is also available as a module. If you want to compile
-+ it as a module, say M here and read Documentation/modules.txt.
-+ The module will be called i2c-algo-pxa.
-+
- config I2C_ALGO8XX
- tristate "MPC8xx CPM I2C interface"
- depends on 8xx && I2C
---- /dev/null 2003-09-23 18:19:32.000000000 -0400
-+++ linux-2.6.5/drivers/i2c/algos/i2c-algo-pxa.c 2004-04-30 20:57:36.000000000 -0400
-@@ -0,0 +1,384 @@
-+/*
-+ * i2c-algo-pxa.c
-+ *
-+ * I2C algorithm for the PXA I2C bus access.
-+ * Byte driven algorithm similar to pcf.
-+ *
-+ * Copyright (C) 2002 Intrinsyc Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * History:
-+ * Apr 2002: Initial version [CS]
-+ * Jun 2002: Properly seperated algo/adap [FB]
-+ * Jan 2003: added limited signal handling [Kai-Uwe Bloem]
-+ * Jan 2003: allow SMBUS_QUICK as valid msg [FB]
-+ * Jun 2003: updated for 2.5 [Dustin McIntire]
-+ *
-+ */
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/errno.h>
-+#include <linux/i2c.h> /* struct i2c_msg and others */
-+#include <linux/i2c-id.h>
-+
-+#include <linux/i2c-pxa.h>
-+
-+/*
-+ * Set this to zero to remove all the debug statements via dead code elimination.
-+ */
-+//#define DEBUG 1
-+
-+#if DEBUG
-+static unsigned int i2c_debug = DEBUG;
-+#else
-+#define i2c_debug 0
-+#endif
-+
-+static int pxa_scan = 1;
-+
-+static int i2c_pxa_valid_messages( struct i2c_msg msgs[], int num)
-+{
-+ int i;
-+ if (num < 1 || num > MAX_MESSAGES){
-+ if( i2c_debug)
-+ printk(KERN_INFO "Invalid number of messages (max=%d, num=%d)\n",
-+ MAX_MESSAGES, num);
-+ return -EINVAL;
-+ }
-+
-+ /* check consistency of our messages */
-+ for (i=0;i<num;i++){
-+ if (&msgs[i]==NULL){
-+ if( i2c_debug) printk(KERN_INFO "Msgs is NULL\n");
-+ return -EINVAL;
-+ } else {
-+ if (msgs[i].buf == NULL){
-+ if( i2c_debug)printk(KERN_INFO "Length is less than zero");
-+ return -EINVAL;
-+ }
-+ }
-+ }
-+
-+ return 1;
-+}
-+
-+static int i2c_pxa_readbytes(struct i2c_adapter *i2c_adap, char *buf,
-+ int count, int last)
-+{
-+
-+ int i, timeout=0;
-+ struct i2c_algo_pxa_data *adap = i2c_adap->algo_data;
-+
-+ /* increment number of bytes to read by one -- read dummy byte */
-+ for (i = 0; i <= count; i++) {
-+ if (i!=0){
-+ /* set ACK to NAK for last received byte ICR[ACKNAK] = 1
-+ only if not a repeated start */
-+
-+ if ((i == count) && last) {
-+ adap->transfer( last, I2C_RECEIVE, 0);
-+ }else{
-+ adap->transfer( 0, I2C_RECEIVE, 1);
-+ }
-+
-+ timeout = adap->wait_for_interrupt(I2C_RECEIVE);
-+
-+#ifdef DEBUG
-+ if (timeout==BUS_ERROR){
-+ printk(KERN_INFO "i2c_pxa_readbytes: bus error -> forcing reset\n");
-+ adap->reset();
-+ return I2C_RETRY;
-+ } else
-+#endif
-+ if (timeout == -ERESTARTSYS) {
-+ adap->abort();
-+ return timeout;
-+ } else
-+ if (timeout){
-+#ifdef DEBUG
-+ printk(KERN_INFO "i2c_pxa_readbytes: timeout -> forcing reset\n");
-+#endif
-+ adap->reset();
-+ return I2C_RETRY;
-+ }
-+
-+ }
-+
-+ if (i) {
-+ buf[i - 1] = adap->read_byte();
-+ } else {
-+ adap->read_byte(); /* dummy read */
-+ }
-+ }
-+ return (i - 1);
-+}
-+
-+static int i2c_pxa_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
-+ int count, int last)
-+{
-+
-+ struct i2c_algo_pxa_data *adap = i2c_adap->algo_data;
-+ int wrcount, timeout;
-+
-+ for (wrcount=0; wrcount<count; ++wrcount) {
-+
-+ adap->write_byte(buf[wrcount]);
-+ if ((wrcount==(count-1)) && last) {
-+ adap->transfer( last, I2C_TRANSMIT, 0);
-+ }else{
-+ adap->transfer( 0, I2C_TRANSMIT, 1);
-+ }
-+
-+ timeout = adap->wait_for_interrupt(I2C_TRANSMIT);
-+
-+#ifdef DEBUG
-+ if (timeout==BUS_ERROR) {
-+ printk(KERN_INFO "i2c_pxa_sendbytes: bus error -> forcing reset.\n");
-+ adap->reset();
-+ return I2C_RETRY;
-+ } else
-+#endif
-+ if (timeout == -ERESTARTSYS) {
-+ adap->abort();
-+ return timeout;
-+ } else
-+ if (timeout) {
-+#ifdef DEBUG
-+ printk(KERN_INFO "i2c_pxa_sendbytes: timeout -> forcing reset\n");
-+#endif
-+ adap->reset();
-+ return I2C_RETRY;
-+ }
-+ }
-+ return (wrcount);
-+}
-+
-+
-+static inline int i2c_pxa_set_ctrl_byte(struct i2c_algo_pxa_data * adap, struct i2c_msg *msg)
-+{
-+ u16 flags = msg->flags;
-+ u8 addr;
-+ addr = (u8) ( (0x7f & msg->addr) << 1 );
-+ if (flags & I2C_M_RD )
-+ addr |= 1;
-+ if (flags & I2C_M_REV_DIR_ADDR )
-+ addr ^= 1;
-+ adap->write_byte(addr);
-+ return 0;
-+}
-+
-+static int i2c_pxa_do_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
-+{
-+ struct i2c_algo_pxa_data * adap;
-+ struct i2c_msg *pmsg=NULL;
-+ int i;
-+ int ret=0, timeout;
-+
-+ adap = i2c_adap->algo_data;
-+
-+ timeout = adap->wait_bus_not_busy();
-+
-+ if (timeout) {
-+ return I2C_RETRY;
-+ }
-+
-+ for (i = 0;ret >= 0 && i < num; i++) {
-+ int last = i + 1 == num;
-+ pmsg = &msgs[i];
-+
-+ ret = i2c_pxa_set_ctrl_byte(adap,pmsg);
-+
-+ /* Send START */
-+ if (i == 0) {
-+ adap->start();
-+ }else{
-+ adap->repeat_start();
-+ }
-+
-+ adap->transfer(0, I2C_TRANSMIT, 0);
-+
-+ /* Wait for ITE (transmit empty) */
-+ timeout = adap->wait_for_interrupt(I2C_TRANSMIT);
-+
-+#ifdef DEBUG
-+ /* Check for ACK (bus error) */
-+ if (timeout==BUS_ERROR){
-+ printk(KERN_INFO "i2c_pxa_do_xfer: bus error -> forcing reset\n");
-+ adap->reset();
-+ return I2C_RETRY;
-+ } else
-+#endif
-+ if (timeout == -ERESTARTSYS) {
-+ adap->abort();
-+ return timeout;
-+ } else
-+ if (timeout) {
-+#ifdef DEBUG
-+ printk(KERN_INFO "i2c_pxa_do_xfer: timeout -> forcing reset\n");
-+#endif
-+ adap->reset();
-+ return I2C_RETRY;
-+ }
-+/* FIXME: handle arbitration... */
-+#if 0
-+ /* Check for bus arbitration loss */
-+ if (adap->arbitration_loss()){
-+ printk("Arbitration loss detected \n");
-+ adap->reset();
-+ return I2C_RETRY;
-+ }
-+#endif
-+
-+ /* Read */
-+ if (pmsg->flags & I2C_M_RD) {
-+ /* read bytes into buffer*/
-+ ret = i2c_pxa_readbytes(i2c_adap, pmsg->buf, pmsg->len, last);
-+#if DEBUG > 2
-+ if (ret != pmsg->len) {
-+ printk(KERN_INFO"i2c_pxa_do_xfer: read %d/%d bytes.\n",
-+ ret, pmsg->len);
-+ } else {
-+ printk(KERN_INFO"i2c_pxa_do_xfer: read %d bytes.\n",ret);
-+ }
-+#endif
-+ } else { /* Write */
-+ ret = i2c_pxa_sendbytes(i2c_adap, pmsg->buf, pmsg->len, last);
-+#if DEBUG > 2
-+ if (ret != pmsg->len) {
-+ printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d/%d bytes.\n",
-+ ret, pmsg->len);
-+ } else {
-+ printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d bytes.\n",ret);
-+ }
-+#endif
-+ }
-+ }
-+
-+ if (ret<0){
-+ return ret;
-+ }else{
-+ return i;
-+ }
-+}
-+
-+static int i2c_pxa_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
-+{
-+ int retval = i2c_pxa_valid_messages( msgs, num);
-+ if( retval > 0)
-+ {
-+ int i;
-+ for (i=i2c_adap->retries; i>=0; i--){
-+ int retval = i2c_pxa_do_xfer(i2c_adap,msgs,num);
-+ if (retval!=I2C_RETRY){
-+ return retval;
-+ }
-+ if( i2c_debug)printk(KERN_INFO"Retrying transmission \n");
-+ udelay(100);
-+ }
-+ if( i2c_debug)printk(KERN_INFO"Retried %i times\n",i2c_adap->retries);
-+ return -EREMOTEIO;
-+
-+ }
-+ return retval;
-+}
-+
-+static u32 i2c_pxa_functionality(struct i2c_adapter * adapter)
-+{
-+ /* Emulate the SMBUS functions */
-+ return I2C_FUNC_SMBUS_EMUL;
-+}
-+
-+struct i2c_algorithm i2c_pxa_algorithm = {
-+ name: "PXA I2C Algorithm",
-+ id: I2C_ALGO_PXA,
-+ master_xfer: i2c_pxa_xfer,
-+ smbus_xfer: NULL,
-+ slave_send: NULL,
-+ slave_recv: NULL,
-+ algo_control: NULL,
-+ functionality: i2c_pxa_functionality,
-+};
-+
-+/*
-+ * registering functions to load algorithms at runtime
-+ */
-+int i2c_pxa_add_bus(struct i2c_adapter *i2c_adap)
-+{
-+ struct i2c_algo_pxa_data *adap = i2c_adap->algo_data;
-+
-+ printk(KERN_INFO"I2C: Adding %s.\n", i2c_adap->dev.name);
-+
-+ i2c_adap->algo = &i2c_pxa_algorithm;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ /* register new adapter to i2c module... */
-+ i2c_add_adapter(i2c_adap);
-+
-+ adap->reset();
-+
-+ /* scan bus */
-+ if (pxa_scan) {
-+ int i;
-+ printk(KERN_INFO "I2C: Scanning bus ");
-+ for (i = 0x02; i < 0xff; i+=2) {
-+ if( i==(I2C_PXA_SLAVE_ADDR<<1)) continue;
-+
-+ if (adap->wait_bus_not_busy()) {
-+ printk(KERN_INFO "I2C: scanning bus %s - TIMEOUT.\n",
-+ i2c_adap->dev.name);
-+ return -EIO;
-+ }
-+ adap->write_byte(i);
-+ adap->start();
-+ adap->transfer(0, I2C_TRANSMIT, 0);
-+
-+ if ((adap->wait_for_interrupt(I2C_TRANSMIT) != BUS_ERROR)) {
-+ printk("(%02x)",i>>1);
-+ adap->abort();
-+ } else {
-+// printk(".");
-+ adap->stop();
-+ }
-+ udelay(adap->udelay);
-+ }
-+ printk("\n");
-+ }
-+ return 0;
-+}
-+
-+int i2c_pxa_del_bus(struct i2c_adapter *i2c_adap)
-+{
-+ int res;
-+ if ((res = i2c_del_adapter(i2c_adap)) < 0)
-+ return res;
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ printk(KERN_INFO "I2C: Removing %s.\n", i2c_adap->dev.name);
-+
-+ return 0;
-+}
-+
-+static int __init i2c_algo_pxa_init (void)
-+{
-+ printk(KERN_INFO "I2C: PXA algorithm module loaded.\n");
-+ return 0;
-+}
-+
-+EXPORT_SYMBOL(i2c_pxa_add_bus);
-+EXPORT_SYMBOL(i2c_pxa_del_bus);
-+
-+MODULE_PARM(pxa_scan, "i");
-+MODULE_PARM_DESC(pxa_scan, "Scan for active chips on the bus");
-+
-+MODULE_AUTHOR("Intrinsyc Software Inc.");
-+MODULE_LICENSE("GPL");
-+
-+module_init(i2c_algo_pxa_init);
---- linux-2.6.5/drivers/i2c/algos/Makefile~heh 2004-04-03 22:37:37.000000000 -0500
-+++ linux-2.6.5/drivers/i2c/algos/Makefile 2004-04-30 20:57:36.000000000 -0400
-@@ -4,6 +4,7 @@
-
- obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o
- obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o
-+obj-$(CONFIG_I2C_ALGOPXA) += i2c-algo-pxa.o
- obj-$(CONFIG_I2C_ALGOITE) += i2c-algo-ite.o
-
- ifeq ($(CONFIG_I2C_DEBUG_ALGO),y)
---- linux-2.6.5/Makefile~heh 2004-04-03 22:37:36.000000000 -0500
-+++ linux-2.6.5/Makefile 2004-04-30 20:57:58.000000000 -0400
-@@ -1,7 +1,7 @@
- VERSION = 2
- PATCHLEVEL = 6
- SUBLEVEL = 5
--EXTRAVERSION =
-+EXTRAVERSION = -gnalm1
- NAME=Zonked Quokka
-
- # *DOCUMENTATION*
diff --git a/linux/gumstix_2.6.5-gnalm1-gum0.bb b/linux/gumstix_2.6.5-gnalm1-gum0.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/gumstix_2.6.5-gnalm1-gum0.bb
+++ /dev/null
diff --git a/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh36.12/defconfig-ipaqpxa b/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh36.12/defconfig-ipaqpxa
deleted file mode 100644
index 9446168fdb..0000000000
--- a/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh36.12/defconfig-ipaqpxa
+++ /dev/null
@@ -1,1575 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-CONFIG_ARCH_PXA=y
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_OMAHA is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_MX1ADS is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_RISCSTATION is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_AT91RM9200DK is not set
-# CONFIG_MINIMAL_OOPS is not set
-
-#
-# Linux As Bootldr support
-#
-# CONFIG_LAB is not set
-# CONFIG_BIG_KERNEL is not set
-# CONFIG_USE_DATE_CODE is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-
-#
-# Archimedes/A5000 Implementations (select only ONE)
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ACCELENT is not set
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CEP is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_CONSUS is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_FRODO is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_HACKKIT is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_JORNADA56X is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_SIMPUTER is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_USB is not set
-# CONFIG_SA1100_USB_NETLINK is not set
-# CONFIG_SA1100_USB_CHAR is not set
-# CONFIG_REGISTERS is not set
-
-#
-# Intel PXA250/210 Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_ARCH_PXA_IDP is not set
-# CONFIG_ARCH_PXA_CERF is not set
-CONFIG_ARCH_H3900=y
-CONFIG_ARCH_H1900=y
-CONFIG_ARCH_H5400=y
-# CONFIG_ARCH_H2200 is not set
-CONFIG_ARCH_AXIM=y
-CONFIG_PXA_USB=m
-CONFIG_PXA_USB_NETLINK=m
-CONFIG_PXA_USB_CHAR=m
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_FORTUNET is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM922T is not set
-# CONFIG_PLD is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_ARM1026 is not set
-# CONFIG_CPU_SA110 is not set
-# CONFIG_CPU_SA1100 is not set
-CONFIG_CPU_32v5=y
-CONFIG_CPU_XSCALE=y
-CONFIG_XSCALE_PXA250=y
-# CONFIG_XSCALE_80200_OLD is not set
-# CONFIG_CPU_32v3 is not set
-# CONFIG_CPU_32v4 is not set
-# CONFIG_SA1100_IPAQ is not set
-CONFIG_PXA_IPAQ=y
-CONFIG_IPAQ_HANDHELD=y
-
-#
-# Compaq iPAQ Handheld
-#
-CONFIG_IPAQ_HAL=m
-# CONFIG_H3600_MICRO is not set
-CONFIG_IPAQ_HAS_ROSELLA=y
-CONFIG_H3600_ASIC=m
-CONFIG_H3900_ASIC_DEBUG=m
-CONFIG_H5400_ASIC=m
-CONFIG_H1900_ASIC=m
-CONFIG_H1900_TS=m
-CONFIG_H3600_HARDWARE=y
-CONFIG_IPAQ_SLEEVE=m
-CONFIG_SLEEVE_DEBUG=y
-CONFIG_SLEEVE_DEBUG_VERBOSE=0
-# CONFIG_SLEEVE_IRQ_DEMUX is not set
-
-#
-# Dell Axim X5
-#
-CONFIG_AXIM_HAL=m
-
-#
-# Processor Features
-#
-# CONFIG_DISCONTIGMEM is not set
-
-#
-# General setup
-#
-# CONFIG_PCI is not set
-# CONFIG_ISA is not set
-# CONFIG_ISA_DMA is not set
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_CPU_FREQ=y
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=m
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_CLPS6700 is not set
-# CONFIG_PCMCIA_SA1100 is not set
-CONFIG_PCMCIA_PXA=m
-# CONFIG_MERCURY_BACKPAQ is not set
-
-#
-# MMC/SD Card support
-#
-CONFIG_MMC=m
-CONFIG_MMC_DEBUG=y
-CONFIG_MMC_DEBUG_VERBOSE=0
-CONFIG_MMC_SAMSUNG_ASIC=m
-# CONFIG_MMC_S3C2410 is not set
-CONFIG_MMC_H5400=m
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_XIP_KERNEL is not set
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_PM=y
-CONFIG_APM=m
-# CONFIG_HWTIMER is not set
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="keepinitrd"
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-CONFIG_PARPORT=m
-CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_CML1=m
-# CONFIG_PARPORT_SERIAL is not set
-# CONFIG_PARPORT_PC_FIFO is not set
-# CONFIG_PARPORT_PC_SUPERIO is not set
-CONFIG_PARPORT_PC_PCMCIA=m
-# CONFIG_PARPORT_ARC is not set
-# CONFIG_PARPORT_IDP is not set
-# CONFIG_PARPORT_AMIGA is not set
-# CONFIG_PARPORT_MFC3 is not set
-# CONFIG_PARPORT_ATARI is not set
-# CONFIG_PARPORT_GSC is not set
-# CONFIG_PARPORT_SUNBPP is not set
-# CONFIG_PARPORT_OTHER is not set
-# CONFIG_PARPORT_1284 is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=1
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=m
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_GEOMETRY=y
-# CONFIG_MTD_CFI_B1 is not set
-CONFIG_MTD_CFI_B2=y
-CONFIG_MTD_CFI_B4=y
-# CONFIG_MTD_CFI_B8 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_IPAQ=y
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-# CONFIG_MTD_SA1100 is not set
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_LUBBOCK is not set
-# CONFIG_MTD_EPXA10DB is not set
-# CONFIG_MTD_FORTUNET is not set
-# CONFIG_MTD_AUTCPU12 is not set
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_H720X is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_CEIVA is not set
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PCMCIA is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-CONFIG_MTD_BLKMTD=m
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_NVRD=m
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-CONFIG_BLK_DEV_LVM=m
-CONFIG_BLK_DEV_DM=m
-
-#
-# Networking options
-#
-CONFIG_PACKET=m
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-# CONFIG_IP_NF_AMANDA is not set
-# CONFIG_IP_NF_TFTP is not set
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_MAC=m
-# CONFIG_IP_NF_MATCH_PKTTYPE is not set
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-# CONFIG_IP_NF_MATCH_RECENT is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
-# CONFIG_IP_NF_MATCH_DSCP is not set
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-# CONFIG_IP_NF_MATCH_HELPER is not set
-CONFIG_IP_NF_MATCH_STATE=m
-# CONFIG_IP_NF_MATCH_CONNTRACK is not set
-# CONFIG_IP_NF_MATCH_UNCLEAN is not set
-# CONFIG_IP_NF_MATCH_OWNER is not set
-CONFIG_IP_NF_FILTER=m
-# CONFIG_IP_NF_TARGET_REJECT is not set
-# CONFIG_IP_NF_TARGET_MIRROR is not set
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-# CONFIG_IP_NF_TARGET_ECN is not set
-# CONFIG_IP_NF_TARGET_DSCP is not set
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_NAT_NEEDED=y
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-CONFIG_IPV6=m
-CONFIG_IPV6_SUBTREES=y
-CONFIG_IPV6_IPV6_TUNNEL=m
-CONFIG_IPV6_MOBILITY=m
-CONFIG_IPV6_MOBILITY_MN=m
-# CONFIG_IPV6_MOBILITY_HA is not set
-CONFIG_IPV6_MOBILITY_DEBUG=y
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-# CONFIG_IP6_NF_MATCH_RT is not set
-# CONFIG_IP6_NF_MATCH_OPTS is not set
-# CONFIG_IP6_NF_MATCH_FRAG is not set
-# CONFIG_IP6_NF_MATCH_HL is not set
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-# CONFIG_IP6_NF_MATCH_OWNER is not set
-CONFIG_IP6_NF_MATCH_MARK=m
-# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
-# CONFIG_IP6_NF_MATCH_AHESP is not set
-# CONFIG_IP6_NF_MATCH_LENGTH is not set
-# CONFIG_IP6_NF_MATCH_EUI64 is not set
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-
-#
-#
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_DEV_APPLETALK is not set
-# CONFIG_DECNET is not set
-CONFIG_BRIDGE=m
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_IPSEC=m
-
-#
-# IPSec options (FreeS/WAN)
-#
-CONFIG_IPSEC_IPIP=y
-CONFIG_IPSEC_AH=y
-CONFIG_IPSEC_AUTH_HMAC_MD5=y
-CONFIG_IPSEC_AUTH_HMAC_SHA1=y
-CONFIG_IPSEC_ESP=y
-CONFIG_IPSEC_ENC_3DES=y
-CONFIG_IPSEC_IPCOMP=y
-CONFIG_IPSEC_DEBUG=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_MPPE=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_STRIP is not set
-# CONFIG_WAVELAN is not set
-# CONFIG_ARLAN is not set
-# CONFIG_AIRONET4500 is not set
-# CONFIG_AIRONET4500_NONCS is not set
-# CONFIG_AIRONET4500_PROC is not set
-# CONFIG_HERMES is not set
-# CONFIG_SPECTRUM24T is not set
-
-#
-# Wireless Pcmcia cards support
-#
-# CONFIG_PCMCIA_HERMES is not set
-# CONFIG_AIRO_CS is not set
-# CONFIG_WVLAN_CS is not set
-# CONFIG_MWVLAN_CS is not set
-# CONFIG_HOSTAP is not set
-# CONFIG_HOSTAP_CS is not set
-CONFIG_NET_WIRELESS=y
-CONFIG_ATMELWLAN=y
-CONFIG_ATMELWLAN_USB_503A_RFMD=m
-CONFIG_ATMELWLAN_PCMCIA_502A=m
-CONFIG_ATMELWLAN_PCMCIA_3COM=m
-CONFIG_ATMELWLAN_PCMCIA_502AD=m
-CONFIG_ATMELWLAN_PCMCIA_502AE=m
-CONFIG_ATMELWLAN_PCMCIA_504=m
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_AXNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-# CONFIG_ARCNET_COM20020_CS is not set
-# CONFIG_PCMCIA_IBMTR is not set
-CONFIG_NET_PCMCIA_RADIO=y
-CONFIG_PCMCIA_RAYCS=m
-CONFIG_PCMCIA_NETWAVE=m
-CONFIG_PCMCIA_WAVELAN=m
-# CONFIG_AIRONET4500_CS is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-CONFIG_IRDA_ULTRA=y
-
-#
-# IrDA options
-#
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-CONFIG_IRDA_DEBUG=y
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=m
-CONFIG_IRPORT_SIR=m
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-CONFIG_PXA_FIR=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=m
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=m
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_IDEDISK_STROKE is not set
-# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-# CONFIG_BLK_DEV_IDEDISK_WD is not set
-# CONFIG_BLK_DEV_COMMERIAL is not set
-# CONFIG_BLK_DEV_TIVO is not set
-CONFIG_BLK_DEV_IDECS=m
-CONFIG_BLK_DEV_IDECD=m
-CONFIG_BLK_DEV_IDETAPE=m
-CONFIG_BLK_DEV_IDEFLOPPY=m
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_DMA_NONPCI is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=m
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-CONFIG_SD_EXTRA_DEVS=40
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_SR_EXTRA_DEVS=2
-CONFIG_CHR_DEV_SG=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_DEBUG_QUEUES is not set
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_PPA is not set
-# CONFIG_SCSI_IMM is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_SIM710 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# PCMCIA SCSI adapter support
-#
-CONFIG_SCSI_PCMCIA=y
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-CONFIG_INPUT=m
-CONFIG_INPUT_KEYBDEV=m
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_JOYDEV=m
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_UINPUT=m
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
-CONFIG_SERIAL_EXTENDED=y
-# CONFIG_SERIAL_MANY_PORTS is not set
-# CONFIG_SERIAL_SHARE_IRQ is not set
-# CONFIG_SERIAL_DETECT_IRQ is not set
-# CONFIG_SERIAL_MULTIPORT is not set
-# CONFIG_HUB6 is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_ANAKIN is not set
-# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-# CONFIG_SERIAL_S3C2410 is not set
-# CONFIG_SERIAL_S3C2410_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_UART00 is not set
-# CONFIG_SERIAL_UART00_CONSOLE is not set
-# CONFIG_SERIAL_SA1100 is not set
-# CONFIG_SERIAL_SA1100_CONSOLE is not set
-# CONFIG_SERIAL_SIR_PXA is not set
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=32
-# CONFIG_PRINTER is not set
-# CONFIG_PPDEV is not set
-CONFIG_NEWTONKBD=m
-# CONFIG_SA1100_PROFILER is not set
-
-#
-# Compaq iPAQ H3600 support
-#
-CONFIG_TOUCHSCREEN_H3600=m
-# CONFIG_H3600_BACKPAQ_FPGA is not set
-# CONFIG_H3600_BACKPAQ_ACCEL is not set
-# CONFIG_H3600_BACKPAQ_GASGAUGE is not set
-# CONFIG_H3600_BACKPAQ_SRAM is not set
-# CONFIG_H3600_BACKPAQ_AUDIO is not set
-# CONFIG_H3600_STOWAWAY is not set
-# CONFIG_H3800_MICROKBD is not set
-# CONFIG_SA1100_LIRC is not set
-CONFIG_H5400_BUZZER=m
-CONFIG_H5400_FSI=m
-
-#
-# I2C support
-#
-CONFIG_I2C=m
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-CONFIG_I2C_PXA_ALGO=m
-CONFIG_I2C_PXA_ADAP=m
-CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_PROC=m
-# CONFIG_I2C_DS1307 is not set
-
-#
-# L3 serial bus support
-#
-# CONFIG_L3 is not set
-# CONFIG_L3_ALGOBIT is not set
-# CONFIG_L3_BIT_SA1100_GPIO is not set
-
-#
-# Other L3 adapters
-#
-# CONFIG_L3_S3C2410 is not set
-# CONFIG_L3_SA1111 is not set
-# CONFIG_L3_BACKPAQ is not set
-# CONFIG_BIT_SA1100_GPIO is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-CONFIG_MOUSE=m
-# CONFIG_PSMOUSE is not set
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-# CONFIG_MK712_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_INPUT_NS558 is not set
-# CONFIG_INPUT_LIGHTNING is not set
-# CONFIG_INPUT_PCIGAME is not set
-# CONFIG_INPUT_CS461X is not set
-# CONFIG_INPUT_EMU10K1 is not set
-CONFIG_INPUT_SERIO=m
-CONFIG_INPUT_SERPORT=m
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_ANALOG is not set
-# CONFIG_INPUT_A3D is not set
-# CONFIG_INPUT_ADI is not set
-# CONFIG_INPUT_COBRA is not set
-# CONFIG_INPUT_GF2K is not set
-# CONFIG_INPUT_GRIP is not set
-# CONFIG_INPUT_INTERACT is not set
-# CONFIG_INPUT_TMDC is not set
-# CONFIG_INPUT_SIDEWINDER is not set
-# CONFIG_INPUT_IFORCE_USB is not set
-# CONFIG_INPUT_IFORCE_232 is not set
-# CONFIG_INPUT_WARRIOR is not set
-# CONFIG_INPUT_MAGELLAN is not set
-# CONFIG_INPUT_SPACEORB is not set
-# CONFIG_INPUT_SPACEBALL is not set
-# CONFIG_INPUT_STINGER is not set
-# CONFIG_INPUT_DB9 is not set
-# CONFIG_INPUT_GAMECON is not set
-# CONFIG_INPUT_TURBOGRAFX is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-# CONFIG_ACQUIRE_WDT is not set
-# CONFIG_ADVANTECH_WDT is not set
-# CONFIG_ALIM7101_WDT is not set
-# CONFIG_SC520_WDT is not set
-# CONFIG_PCWATCHDOG is not set
-# CONFIG_21285_WATCHDOG is not set
-# CONFIG_977_WATCHDOG is not set
-# CONFIG_SA1100_WATCHDOG is not set
-CONFIG_PXA_WATCHDOG=m
-# CONFIG_OMAHA_WATCHDOG is not set
-# CONFIG_EUROTECH_WDT is not set
-# CONFIG_IB700_WDT is not set
-# CONFIG_WAFER_WDT is not set
-# CONFIG_I810_TCO is not set
-# CONFIG_MIXCOMWD is not set
-# CONFIG_60XX_WDT is not set
-# CONFIG_SC1200_WDT is not set
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_W83877F_WDT is not set
-# CONFIG_WDT is not set
-# CONFIG_WDTPCI is not set
-# CONFIG_MACHZ_WDT is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_PXA_RTC=m
-CONFIG_PXA_RTC_HACK=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-CONFIG_PCMCIA_SERIAL_CS=m
-CONFIG_PCMCIA_MOBILISCAN_CS=m
-# CONFIG_AXIM_TS is not set
-CONFIG_AXIM_KEY=m
-# CONFIG_AXIM_KEY_FIX is not set
-
-#
-# Multimedia devices
-#
-CONFIG_MEDIA=m
-CONFIG_VIDEO_DEV=m
-CONFIG_V4L2_DEV=m
-
-#
-# Video For Linux
-#
-CONFIG_VIDEO_PROC_FS=y
-# CONFIG_I2C_PARPORT is not set
-
-#
-# Video Adapters
-#
-# CONFIG_VIDEO_PMS is not set
-# CONFIG_VIDEO_BWQCAM is not set
-# CONFIG_VIDEO_CQCAM is not set
-CONFIG_VIDEO_CPIA=m
-CONFIG_VIDEO_CPIA_USB=m
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIDEO_ZORAN_BUZ is not set
-# CONFIG_VIDEO_ZORAN_DC10 is not set
-# CONFIG_VIDEO_ZORAN_LML33 is not set
-# CONFIG_VIDEO_ZR36120 is not set
-# CONFIG_VIDEO_MEYE is not set
-# CONFIG_VIDEO_CYBERPRO is not set
-# CONFIG_VIDEO_H3600_BACKPAQ is not set
-# CONFIG_VIDEO_HAWKEYE is not set
-
-#
-# Video for Linux 2 (V4L2)
-#
-CONFIG_VIDEO_WINNOV_CS=m
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_CADET is not set
-# CONFIG_RADIO_RTRACK is not set
-# CONFIG_RADIO_RTRACK2 is not set
-# CONFIG_RADIO_AZTECH is not set
-# CONFIG_RADIO_GEMTEK is not set
-# CONFIG_RADIO_GEMTEK_PCI is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_MAESTRO is not set
-# CONFIG_RADIO_MIROPCM20 is not set
-# CONFIG_RADIO_MIROPCM20_RDS is not set
-# CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_TERRATEC is not set
-# CONFIG_RADIO_TRUST is not set
-# CONFIG_RADIO_TYPHOON is not set
-# CONFIG_RADIO_ZOLTRIX is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=m
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=m
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_UMSDOS_FS=m
-CONFIG_VFAT_FS=m
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-CONFIG_CRAMFS=y
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-CONFIG_ISO9660_FS=m
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DRIVERFS_FS is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=m
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-# CONFIG_ROOT_NFS is not set
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-CONFIG_SUNRPC=m
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-
-#
-# Console drivers
-#
-CONFIG_PC_KEYMAP=y
-# CONFIG_VGA_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_ACORN is not set
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_S3C2410 is not set
-# CONFIG_FB_SA1100 is not set
-# CONFIG_FB_EPSON1356 is not set
-# CONFIG_FB_MQ200 is not set
-CONFIG_FB_PXA=y
-# CONFIG_FB_PXA_8BPP is not set
-CONFIG_FB_PXA_16BPP=y
-CONFIG_FB_MQ1100=y
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-# CONFIG_FBCON_CFB4 is not set
-# CONFIG_FBCON_CFB8 is not set
-CONFIG_FBCON_CFB16=y
-# CONFIG_FBCON_CFB24 is not set
-# CONFIG_FBCON_CFB32 is not set
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA_PLANES is not set
-# CONFIG_FBCON_VGA is not set
-# CONFIG_FBCON_HGA is not set
-# CONFIG_FBCON_NO_LOGO is not set
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-CONFIG_FONT_8x8=y
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-CONFIG_SOUND_H3900_UDA1380=m
-CONFIG_SOUND_H5400=m
-CONFIG_SOUND_OSS=m
-# CONFIG_SOUND_TRACEINIT is not set
-# CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_ADLIB is not set
-# CONFIG_SOUND_ACI_MIXER is not set
-# CONFIG_SOUND_CS4232 is not set
-# CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_VMIDI is not set
-# CONFIG_SOUND_TRIX is not set
-# CONFIG_SOUND_MSS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_NM256 is not set
-# CONFIG_SOUND_MAD16 is not set
-# CONFIG_SOUND_PAS is not set
-# CONFIG_PAS_JOYSTICK is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_SB is not set
-# CONFIG_SOUND_AWE32_SYNTH is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_OPL3SA2 is not set
-# CONFIG_SOUND_YMFPCI is not set
-# CONFIG_SOUND_YMFPCI_LEGACY is not set
-# CONFIG_SOUND_UART6850 is not set
-# CONFIG_SOUND_AEDSP16 is not set
-# CONFIG_SOUND_VIDC is not set
-# CONFIG_SOUND_WAVEARTIST is not set
-CONFIG_SOUND_PXA_AC97=m
-# CONFIG_SOUND_TVMIXER is not set
-
-#
-# Multimedia Capabilities Port drivers
-#
-# CONFIG_MCP is not set
-# CONFIG_MCP_SA1100 is not set
-# CONFIG_MCP_UCB1200 is not set
-# CONFIG_MCP_UCB1200_AUDIO is not set
-# CONFIG_MCP_UCB1200_TS is not set
-# CONFIG_MCP_UCB1400_TS is not set
-
-#
-# Console Switches
-#
-# CONFIG_SWITCHES is not set
-
-#
-# USB support
-#
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_LONG_TIMEOUT is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-CONFIG_USB_OHCI=m
-# CONFIG_USB_OHCI_SA1111 is not set
-CONFIG_USB_OHCI_H5400=m
-# CONFIG_USB_OHCI_S3C2410 is not set
-# CONFIG_USB_SL811HS is not set
-
-#
-# USB Device Class drivers
-#
-CONFIG_USB_AUDIO=m
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_BLUETOOTH is not set
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-CONFIG_USB_PRINTER=m
-
-#
-# USB Human Interface Devices (HID)
-#
-CONFIG_USB_HID=m
-CONFIG_USB_HIDINPUT=y
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_WACOM is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_OV511=m
-CONFIG_USB_PWC=m
-CONFIG_USB_SE401=m
-CONFIG_USB_STV680=m
-CONFIG_USB_VICAM=m
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-CONFIG_USB_CDCETHER=m
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_BRLVGER is not set
-
-#
-# Linux As Bootldr Modules
-#
-# CONFIG_BIG_KERNEL is not set
-# CONFIG_USE_DATE_CODE is not set
-# CONFIG_YMODEM is not set
-# CONFIG_LAB_DUMMY is not set
-# CONFIG_LAB_CRC is not set
-# CONFIG_LAB_YMODEM is not set
-# CONFIG_LAB_MTD is not set
-# CONFIG_LAB_COPY is not set
-# CONFIG_LAB_COPY_YMODEM is not set
-# CONFIG_LAB_COPY_FLASH is not set
-# CONFIG_LAB_COPY_FS is not set
-# CONFIG_LAB_COPY_WRAPPER is not set
-
-#
-# Bluetooth support
-#
-CONFIG_BLUEZ=m
-CONFIG_BLUEZ_L2CAP=m
-CONFIG_BLUEZ_SCO=m
-CONFIG_BLUEZ_RFCOMM=m
-CONFIG_BLUEZ_RFCOMM_TTY=y
-CONFIG_BLUEZ_BNEP=m
-CONFIG_BLUEZ_BNEP_MC_FILTER=y
-CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
-
-#
-# Bluetooth device drivers
-#
-# CONFIG_BLUEZ_HCIUSB is not set
-CONFIG_BLUEZ_HCIUART=m
-CONFIG_BLUEZ_HCIUART_H4=y
-CONFIG_BLUEZ_HCIUART_BCSP=y
-# CONFIG_BLUEZ_HCIUART_BCSP_TXCRC is not set
-# CONFIG_BLUEZ_HCIBFUSB is not set
-CONFIG_BLUEZ_HCIDTL1=m
-CONFIG_BLUEZ_HCIBT3C=m
-CONFIG_BLUEZ_HCIBLUECARD=m
-CONFIG_BLUEZ_HCIBTUART=m
-# CONFIG_BLUEZ_HCIVHCI is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_FRAME_POINTER is not set
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_NO_PGT_CACHE is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
-
-#
-# Library routines
-#
-# CONFIG_CRC32 is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh36.12/ipsec.patch b/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh36.12/ipsec.patch
deleted file mode 100644
index 4e2efc035b..0000000000
--- a/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh36.12/ipsec.patch
+++ /dev/null
@@ -1,1446 +0,0 @@
---- linux/net/Makefile 3 Dec 2003 19:15:16 -0000 1.25
-+++ linux/net/Makefile 20 Feb 2003 15:50:38 -0000 1.24
-@@ -19,6 +19,7 @@
- subdir-$(CONFIG_NETFILTER) += ipv4/netfilter
- subdir-$(CONFIG_UNIX) += unix
- subdir-$(CONFIG_IPV6) += ipv6
-+subdir-$(CONFIG_IPSEC) += ipsec
-
- ifneq ($(CONFIG_IPV6),n)
- ifneq ($(CONFIG_IPV6),)
---- /dev/null 2004-02-02 20:32:13.000000000 +0000
-+++ linux/include/zlib/zlib.h 2004-07-05 23:56:59.000000000 +0100
-@@ -0,0 +1,893 @@
-+/* zlib.h -- interface of the 'zlib' general purpose compression library
-+ version 1.1.4, March 11th, 2002
-+
-+ Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
-+
-+ This software is provided 'as-is', without any express or implied
-+ warranty. In no event will the authors be held liable for any damages
-+ arising from the use of this software.
-+
-+ Permission is granted to anyone to use this software for any purpose,
-+ including commercial applications, and to alter it and redistribute it
-+ freely, subject to the following restrictions:
-+
-+ 1. The origin of this software must not be misrepresented; you must not
-+ claim that you wrote the original software. If you use this software
-+ in a product, an acknowledgment in the product documentation would be
-+ appreciated but is not required.
-+ 2. Altered source versions must be plainly marked as such, and must not be
-+ misrepresented as being the original software.
-+ 3. This notice may not be removed or altered from any source distribution.
-+
-+ Jean-loup Gailly Mark Adler
-+ jloup@gzip.org madler@alumni.caltech.edu
-+
-+
-+ The data format used by the zlib library is described by RFCs (Request for
-+ Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
-+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
-+*/
-+
-+#ifndef _ZLIB_H
-+#define _ZLIB_H
-+
-+#include "zconf.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#define ZLIB_VERSION "1.1.4"
-+
-+/*
-+ The 'zlib' compression library provides in-memory compression and
-+ decompression functions, including integrity checks of the uncompressed
-+ data. This version of the library supports only one compression method
-+ (deflation) but other algorithms will be added later and will have the same
-+ stream interface.
-+
-+ Compression can be done in a single step if the buffers are large
-+ enough (for example if an input file is mmap'ed), or can be done by
-+ repeated calls of the compression function. In the latter case, the
-+ application must provide more input and/or consume the output
-+ (providing more output space) before each call.
-+
-+ The library also supports reading and writing files in gzip (.gz) format
-+ with an interface similar to that of stdio.
-+
-+ The library does not install any signal handler. The decoder checks
-+ the consistency of the compressed data, so the library should never
-+ crash even in case of corrupted input.
-+*/
-+
-+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-+typedef void (*free_func) OF((voidpf opaque, voidpf address));
-+
-+struct internal_state;
-+
-+typedef struct z_stream_s {
-+ Bytef *next_in; /* next input byte */
-+ uInt avail_in; /* number of bytes available at next_in */
-+ uLong total_in; /* total nb of input bytes read so far */
-+
-+ Bytef *next_out; /* next output byte should be put there */
-+ uInt avail_out; /* remaining free space at next_out */
-+ uLong total_out; /* total nb of bytes output so far */
-+
-+ const char *msg; /* last error message, NULL if no error */
-+ struct internal_state FAR *state; /* not visible by applications */
-+
-+ alloc_func zalloc; /* used to allocate the internal state */
-+ free_func zfree; /* used to free the internal state */
-+ voidpf opaque; /* private data object passed to zalloc and zfree */
-+
-+ int data_type; /* best guess about the data type: ascii or binary */
-+ uLong adler; /* adler32 value of the uncompressed data */
-+ uLong reserved; /* reserved for future use */
-+} z_stream;
-+
-+typedef z_stream FAR *z_streamp;
-+
-+/*
-+ The application must update next_in and avail_in when avail_in has
-+ dropped to zero. It must update next_out and avail_out when avail_out
-+ has dropped to zero. The application must initialize zalloc, zfree and
-+ opaque before calling the init function. All other fields are set by the
-+ compression library and must not be updated by the application.
-+
-+ The opaque value provided by the application will be passed as the first
-+ parameter for calls of zalloc and zfree. This can be useful for custom
-+ memory management. The compression library attaches no meaning to the
-+ opaque value.
-+
-+ zalloc must return Z_NULL if there is not enough memory for the object.
-+ If zlib is used in a multi-threaded application, zalloc and zfree must be
-+ thread safe.
-+
-+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
-+ exactly 65536 bytes, but will not be required to allocate more than this
-+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
-+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
-+ have their offset normalized to zero. The default allocation function
-+ provided by this library ensures this (see zutil.c). To reduce memory
-+ requirements and avoid any allocation of 64K objects, at the expense of
-+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-+
-+ The fields total_in and total_out can be used for statistics or
-+ progress reports. After compression, total_in holds the total size of
-+ the uncompressed data and may be saved for use in the decompressor
-+ (particularly if the decompressor wants to decompress everything in
-+ a single step).
-+*/
-+
-+ /* constants */
-+
-+#define Z_NO_FLUSH 0
-+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
-+#define Z_SYNC_FLUSH 2
-+#define Z_FULL_FLUSH 3
-+#define Z_FINISH 4
-+/* Allowed flush values; see deflate() below for details */
-+
-+#define Z_OK 0
-+#define Z_STREAM_END 1
-+#define Z_NEED_DICT 2
-+#define Z_ERRNO (-1)
-+#define Z_STREAM_ERROR (-2)
-+#define Z_DATA_ERROR (-3)
-+#define Z_MEM_ERROR (-4)
-+#define Z_BUF_ERROR (-5)
-+#define Z_VERSION_ERROR (-6)
-+/* Return codes for the compression/decompression functions. Negative
-+ * values are errors, positive values are used for special but normal events.
-+ */
-+
-+#define Z_NO_COMPRESSION 0
-+#define Z_BEST_SPEED 1
-+#define Z_BEST_COMPRESSION 9
-+#define Z_DEFAULT_COMPRESSION (-1)
-+/* compression levels */
-+
-+#define Z_FILTERED 1
-+#define Z_HUFFMAN_ONLY 2
-+#define Z_DEFAULT_STRATEGY 0
-+/* compression strategy; see deflateInit2() below for details */
-+
-+#define Z_BINARY 0
-+#define Z_ASCII 1
-+#define Z_UNKNOWN 2
-+/* Possible values of the data_type field */
-+
-+#define Z_DEFLATED 8
-+/* The deflate compression method (the only one supported in this version) */
-+
-+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-+
-+#define zlib_version zlibVersion()
-+/* for compatibility with versions < 1.0.2 */
-+
-+ /* basic functions */
-+
-+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
-+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
-+ If the first character differs, the library code actually used is
-+ not compatible with the zlib.h header file used by the application.
-+ This check is automatically made by deflateInit and inflateInit.
-+ */
-+
-+/*
-+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
-+
-+ Initializes the internal stream state for compression. The fields
-+ zalloc, zfree and opaque must be initialized before by the caller.
-+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to
-+ use default allocation functions.
-+
-+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
-+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
-+ all (the input data is simply copied a block at a time).
-+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
-+ compression (currently equivalent to level 6).
-+
-+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
-+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
-+ with the version assumed by the caller (ZLIB_VERSION).
-+ msg is set to null if there is no error message. deflateInit does not
-+ perform any compression: this will be done by deflate().
-+*/
-+
-+
-+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
-+/*
-+ deflate compresses as much data as possible, and stops when the input
-+ buffer becomes empty or the output buffer becomes full. It may introduce some
-+ output latency (reading input without producing any output) except when
-+ forced to flush.
-+
-+ The detailed semantics are as follows. deflate performs one or both of the
-+ following actions:
-+
-+ - Compress more input starting at next_in and update next_in and avail_in
-+ accordingly. If not all input can be processed (because there is not
-+ enough room in the output buffer), next_in and avail_in are updated and
-+ processing will resume at this point for the next call of deflate().
-+
-+ - Provide more output starting at next_out and update next_out and avail_out
-+ accordingly. This action is forced if the parameter flush is non zero.
-+ Forcing flush frequently degrades the compression ratio, so this parameter
-+ should be set only when necessary (in interactive applications).
-+ Some output may be provided even if flush is not set.
-+
-+ Before the call of deflate(), the application should ensure that at least
-+ one of the actions is possible, by providing more input and/or consuming
-+ more output, and updating avail_in or avail_out accordingly; avail_out
-+ should never be zero before the call. The application can consume the
-+ compressed output when it wants, for example when the output buffer is full
-+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
-+ and with zero avail_out, it must be called again after making room in the
-+ output buffer because there might be more output pending.
-+
-+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
-+ flushed to the output buffer and the output is aligned on a byte boundary, so
-+ that the decompressor can get all input data available so far. (In particular
-+ avail_in is zero after the call if enough output space has been provided
-+ before the call.) Flushing may degrade compression for some compression
-+ algorithms and so it should be used only when necessary.
-+
-+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
-+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
-+ restart from this point if previous compressed data has been damaged or if
-+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
-+ the compression.
-+
-+ If deflate returns with avail_out == 0, this function must be called again
-+ with the same value of the flush parameter and more output space (updated
-+ avail_out), until the flush is complete (deflate returns with non-zero
-+ avail_out).
-+
-+ If the parameter flush is set to Z_FINISH, pending input is processed,
-+ pending output is flushed and deflate returns with Z_STREAM_END if there
-+ was enough output space; if deflate returns with Z_OK, this function must be
-+ called again with Z_FINISH and more output space (updated avail_out) but no
-+ more input data, until it returns with Z_STREAM_END or an error. After
-+ deflate has returned Z_STREAM_END, the only possible operations on the
-+ stream are deflateReset or deflateEnd.
-+
-+ Z_FINISH can be used immediately after deflateInit if all the compression
-+ is to be done in a single step. In this case, avail_out must be at least
-+ 0.1% larger than avail_in plus 12 bytes. If deflate does not return
-+ Z_STREAM_END, then it must be called again as described above.
-+
-+ deflate() sets strm->adler to the adler32 checksum of all input read
-+ so far (that is, total_in bytes).
-+
-+ deflate() may update data_type if it can make a good guess about
-+ the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
-+ binary. This field is only for information purposes and does not affect
-+ the compression algorithm in any manner.
-+
-+ deflate() returns Z_OK if some progress has been made (more input
-+ processed or more output produced), Z_STREAM_END if all input has been
-+ consumed and all output has been produced (only when flush is set to
-+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
-+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
-+ (for example avail_in or avail_out was zero).
-+*/
-+
-+
-+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
-+/*
-+ All dynamically allocated data structures for this stream are freed.
-+ This function discards any unprocessed input and does not flush any
-+ pending output.
-+
-+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
-+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
-+ prematurely (some input or output was discarded). In the error case,
-+ msg may be set but then points to a static string (which must not be
-+ deallocated).
-+*/
-+
-+
-+/*
-+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
-+
-+ Initializes the internal stream state for decompression. The fields
-+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
-+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
-+ value depends on the compression method), inflateInit determines the
-+ compression method from the zlib header and allocates all data structures
-+ accordingly; otherwise the allocation will be deferred to the first call of
-+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
-+ use default allocation functions.
-+
-+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
-+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
-+ version assumed by the caller. msg is set to null if there is no error
-+ message. inflateInit does not perform any decompression apart from reading
-+ the zlib header if present: this will be done by inflate(). (So next_in and
-+ avail_in may be modified, but next_out and avail_out are unchanged.)
-+*/
-+
-+
-+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
-+/*
-+ inflate decompresses as much data as possible, and stops when the input
-+ buffer becomes empty or the output buffer becomes full. It may some
-+ introduce some output latency (reading input without producing any output)
-+ except when forced to flush.
-+
-+ The detailed semantics are as follows. inflate performs one or both of the
-+ following actions:
-+
-+ - Decompress more input starting at next_in and update next_in and avail_in
-+ accordingly. If not all input can be processed (because there is not
-+ enough room in the output buffer), next_in is updated and processing
-+ will resume at this point for the next call of inflate().
-+
-+ - Provide more output starting at next_out and update next_out and avail_out
-+ accordingly. inflate() provides as much output as possible, until there
-+ is no more input data or no more space in the output buffer (see below
-+ about the flush parameter).
-+
-+ Before the call of inflate(), the application should ensure that at least
-+ one of the actions is possible, by providing more input and/or consuming
-+ more output, and updating the next_* and avail_* values accordingly.
-+ The application can consume the uncompressed output when it wants, for
-+ example when the output buffer is full (avail_out == 0), or after each
-+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
-+ must be called again after making room in the output buffer because there
-+ might be more output pending.
-+
-+ If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
-+ output as possible to the output buffer. The flushing behavior of inflate is
-+ not specified for values of the flush parameter other than Z_SYNC_FLUSH
-+ and Z_FINISH, but the current implementation actually flushes as much output
-+ as possible anyway.
-+
-+ inflate() should normally be called until it returns Z_STREAM_END or an
-+ error. However if all decompression is to be performed in a single step
-+ (a single call of inflate), the parameter flush should be set to
-+ Z_FINISH. In this case all pending input is processed and all pending
-+ output is flushed; avail_out must be large enough to hold all the
-+ uncompressed data. (The size of the uncompressed data may have been saved
-+ by the compressor for this purpose.) The next operation on this stream must
-+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
-+ is never required, but can be used to inform inflate that a faster routine
-+ may be used for the single inflate() call.
-+
-+ If a preset dictionary is needed at this point (see inflateSetDictionary
-+ below), inflate sets strm-adler to the adler32 checksum of the
-+ dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
-+ it sets strm->adler to the adler32 checksum of all output produced
-+ so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
-+ an error code as described below. At the end of the stream, inflate()
-+ checks that its computed adler32 checksum is equal to that saved by the
-+ compressor and returns Z_STREAM_END only if the checksum is correct.
-+
-+ inflate() returns Z_OK if some progress has been made (more input processed
-+ or more output produced), Z_STREAM_END if the end of the compressed data has
-+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
-+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
-+ corrupted (input stream not conforming to the zlib format or incorrect
-+ adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
-+ (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
-+ enough memory, Z_BUF_ERROR if no progress is possible or if there was not
-+ enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
-+ case, the application may then call inflateSync to look for a good
-+ compression block.
-+*/
-+
-+
-+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
-+/*
-+ All dynamically allocated data structures for this stream are freed.
-+ This function discards any unprocessed input and does not flush any
-+ pending output.
-+
-+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
-+ was inconsistent. In the error case, msg may be set but then points to a
-+ static string (which must not be deallocated).
-+*/
-+
-+ /* Advanced functions */
-+
-+/*
-+ The following functions are needed only in some special applications.
-+*/
-+
-+/*
-+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
-+ int level,
-+ int method,
-+ int windowBits,
-+ int memLevel,
-+ int strategy));
-+
-+ This is another version of deflateInit with more compression options. The
-+ fields next_in, zalloc, zfree and opaque must be initialized before by
-+ the caller.
-+
-+ The method parameter is the compression method. It must be Z_DEFLATED in
-+ this version of the library.
-+
-+ The windowBits parameter is the base two logarithm of the window size
-+ (the size of the history buffer). It should be in the range 8..15 for this
-+ version of the library. Larger values of this parameter result in better
-+ compression at the expense of memory usage. The default value is 15 if
-+ deflateInit is used instead.
-+
-+ The memLevel parameter specifies how much memory should be allocated
-+ for the internal compression state. memLevel=1 uses minimum memory but
-+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
-+ for optimal speed. The default value is 8. See zconf.h for total memory
-+ usage as a function of windowBits and memLevel.
-+
-+ The strategy parameter is used to tune the compression algorithm. Use the
-+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
-+ filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
-+ string match). Filtered data consists mostly of small values with a
-+ somewhat random distribution. In this case, the compression algorithm is
-+ tuned to compress them better. The effect of Z_FILTERED is to force more
-+ Huffman coding and less string matching; it is somewhat intermediate
-+ between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
-+ the compression ratio but not the correctness of the compressed output even
-+ if it is not set appropriately.
-+
-+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
-+ method). msg is set to null if there is no error message. deflateInit2 does
-+ not perform any compression: this will be done by deflate().
-+*/
-+
-+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
-+ const Bytef *dictionary,
-+ uInt dictLength));
-+/*
-+ Initializes the compression dictionary from the given byte sequence
-+ without producing any compressed output. This function must be called
-+ immediately after deflateInit, deflateInit2 or deflateReset, before any
-+ call of deflate. The compressor and decompressor must use exactly the same
-+ dictionary (see inflateSetDictionary).
-+
-+ The dictionary should consist of strings (byte sequences) that are likely
-+ to be encountered later in the data to be compressed, with the most commonly
-+ used strings preferably put towards the end of the dictionary. Using a
-+ dictionary is most useful when the data to be compressed is short and can be
-+ predicted with good accuracy; the data can then be compressed better than
-+ with the default empty dictionary.
-+
-+ Depending on the size of the compression data structures selected by
-+ deflateInit or deflateInit2, a part of the dictionary may in effect be
-+ discarded, for example if the dictionary is larger than the window size in
-+ deflate or deflate2. Thus the strings most likely to be useful should be
-+ put at the end of the dictionary, not at the front.
-+
-+ Upon return of this function, strm->adler is set to the Adler32 value
-+ of the dictionary; the decompressor may later use this value to determine
-+ which dictionary has been used by the compressor. (The Adler32 value
-+ applies to the whole dictionary even if only a subset of the dictionary is
-+ actually used by the compressor.)
-+
-+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
-+ parameter is invalid (such as NULL dictionary) or the stream state is
-+ inconsistent (for example if deflate has already been called for this stream
-+ or if the compression method is bsort). deflateSetDictionary does not
-+ perform any compression: this will be done by deflate().
-+*/
-+
-+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
-+ z_streamp source));
-+/*
-+ Sets the destination stream as a complete copy of the source stream.
-+
-+ This function can be useful when several compression strategies will be
-+ tried, for example when there are several ways of pre-processing the input
-+ data with a filter. The streams that will be discarded should then be freed
-+ by calling deflateEnd. Note that deflateCopy duplicates the internal
-+ compression state which can be quite large, so this strategy is slow and
-+ can consume lots of memory.
-+
-+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
-+ (such as zalloc being NULL). msg is left unchanged in both source and
-+ destination.
-+*/
-+
-+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
-+/*
-+ This function is equivalent to deflateEnd followed by deflateInit,
-+ but does not free and reallocate all the internal compression state.
-+ The stream will keep the same compression level and any other attributes
-+ that may have been set by deflateInit2.
-+
-+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-+ stream state was inconsistent (such as zalloc or state being NULL).
-+*/
-+
-+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
-+ int level,
-+ int strategy));
-+/*
-+ Dynamically update the compression level and compression strategy. The
-+ interpretation of level and strategy is as in deflateInit2. This can be
-+ used to switch between compression and straight copy of the input data, or
-+ to switch to a different kind of input data requiring a different
-+ strategy. If the compression level is changed, the input available so far
-+ is compressed with the old level (and may be flushed); the new level will
-+ take effect only at the next call of deflate().
-+
-+ Before the call of deflateParams, the stream state must be set as for
-+ a call of deflate(), since the currently available input may have to
-+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
-+
-+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
-+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
-+ if strm->avail_out was zero.
-+*/
-+
-+/*
-+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
-+ int windowBits));
-+
-+ This is another version of inflateInit with an extra parameter. The
-+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
-+ before by the caller.
-+
-+ The windowBits parameter is the base two logarithm of the maximum window
-+ size (the size of the history buffer). It should be in the range 8..15 for
-+ this version of the library. The default value is 15 if inflateInit is used
-+ instead. If a compressed stream with a larger window size is given as
-+ input, inflate() will return with the error code Z_DATA_ERROR instead of
-+ trying to allocate a larger window.
-+
-+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
-+ memLevel). msg is set to null if there is no error message. inflateInit2
-+ does not perform any decompression apart from reading the zlib header if
-+ present: this will be done by inflate(). (So next_in and avail_in may be
-+ modified, but next_out and avail_out are unchanged.)
-+*/
-+
-+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
-+ const Bytef *dictionary,
-+ uInt dictLength));
-+/*
-+ Initializes the decompression dictionary from the given uncompressed byte
-+ sequence. This function must be called immediately after a call of inflate
-+ if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
-+ can be determined from the Adler32 value returned by this call of
-+ inflate. The compressor and decompressor must use exactly the same
-+ dictionary (see deflateSetDictionary).
-+
-+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
-+ parameter is invalid (such as NULL dictionary) or the stream state is
-+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
-+ expected one (incorrect Adler32 value). inflateSetDictionary does not
-+ perform any decompression: this will be done by subsequent calls of
-+ inflate().
-+*/
-+
-+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
-+/*
-+ Skips invalid compressed data until a full flush point (see above the
-+ description of deflate with Z_FULL_FLUSH) can be found, or until all
-+ available input is skipped. No output is provided.
-+
-+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
-+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
-+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
-+ case, the application may save the current current value of total_in which
-+ indicates where valid compressed data was found. In the error case, the
-+ application may repeatedly call inflateSync, providing more input each time,
-+ until success or end of the input data.
-+*/
-+
-+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
-+/*
-+ This function is equivalent to inflateEnd followed by inflateInit,
-+ but does not free and reallocate all the internal decompression state.
-+ The stream will keep attributes that may have been set by inflateInit2.
-+
-+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-+ stream state was inconsistent (such as zalloc or state being NULL).
-+*/
-+
-+
-+ /* utility functions */
-+
-+/*
-+ The following utility functions are implemented on top of the
-+ basic stream-oriented functions. To simplify the interface, some
-+ default options are assumed (compression level and memory usage,
-+ standard memory allocation functions). The source code of these
-+ utility functions can easily be modified if you need special options.
-+*/
-+
-+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
-+ const Bytef *source, uLong sourceLen));
-+/*
-+ Compresses the source buffer into the destination buffer. sourceLen is
-+ the byte length of the source buffer. Upon entry, destLen is the total
-+ size of the destination buffer, which must be at least 0.1% larger than
-+ sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
-+ compressed buffer.
-+ This function can be used to compress a whole file at once if the
-+ input file is mmap'ed.
-+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory, Z_BUF_ERROR if there was not enough room in the output
-+ buffer.
-+*/
-+
-+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
-+ const Bytef *source, uLong sourceLen,
-+ int level));
-+/*
-+ Compresses the source buffer into the destination buffer. The level
-+ parameter has the same meaning as in deflateInit. sourceLen is the byte
-+ length of the source buffer. Upon entry, destLen is the total size of the
-+ destination buffer, which must be at least 0.1% larger than sourceLen plus
-+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
-+
-+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
-+ Z_STREAM_ERROR if the level parameter is invalid.
-+*/
-+
-+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
-+ const Bytef *source, uLong sourceLen));
-+/*
-+ Decompresses the source buffer into the destination buffer. sourceLen is
-+ the byte length of the source buffer. Upon entry, destLen is the total
-+ size of the destination buffer, which must be large enough to hold the
-+ entire uncompressed data. (The size of the uncompressed data must have
-+ been saved previously by the compressor and transmitted to the decompressor
-+ by some mechanism outside the scope of this compression library.)
-+ Upon exit, destLen is the actual size of the compressed buffer.
-+ This function can be used to decompress a whole file at once if the
-+ input file is mmap'ed.
-+
-+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory, Z_BUF_ERROR if there was not enough room in the output
-+ buffer, or Z_DATA_ERROR if the input data was corrupted.
-+*/
-+
-+
-+typedef voidp gzFile;
-+
-+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
-+/*
-+ Opens a gzip (.gz) file for reading or writing. The mode parameter
-+ is as in fopen ("rb" or "wb") but can also include a compression level
-+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
-+ Huffman only compression as in "wb1h". (See the description
-+ of deflateInit2 for more information about the strategy parameter.)
-+
-+ gzopen can be used to read a file which is not in gzip format; in this
-+ case gzread will directly read from the file without decompression.
-+
-+ gzopen returns NULL if the file could not be opened or if there was
-+ insufficient memory to allocate the (de)compression state; errno
-+ can be checked to distinguish the two cases (if errno is zero, the
-+ zlib error is Z_MEM_ERROR). */
-+
-+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
-+/*
-+ gzdopen() associates a gzFile with the file descriptor fd. File
-+ descriptors are obtained from calls like open, dup, creat, pipe or
-+ fileno (in the file has been previously opened with fopen).
-+ The mode parameter is as in gzopen.
-+ The next call of gzclose on the returned gzFile will also close the
-+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
-+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
-+ gzdopen returns NULL if there was insufficient memory to allocate
-+ the (de)compression state.
-+*/
-+
-+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
-+/*
-+ Dynamically update the compression level or strategy. See the description
-+ of deflateInit2 for the meaning of these parameters.
-+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
-+ opened for writing.
-+*/
-+
-+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
-+/*
-+ Reads the given number of uncompressed bytes from the compressed file.
-+ If the input file was not in gzip format, gzread copies the given number
-+ of bytes into the buffer.
-+ gzread returns the number of uncompressed bytes actually read (0 for
-+ end of file, -1 for error). */
-+
-+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
-+ const voidp buf, unsigned len));
-+/*
-+ Writes the given number of uncompressed bytes into the compressed file.
-+ gzwrite returns the number of uncompressed bytes actually written
-+ (0 in case of error).
-+*/
-+
-+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
-+/*
-+ Converts, formats, and writes the args to the compressed file under
-+ control of the format string, as in fprintf. gzprintf returns the number of
-+ uncompressed bytes actually written (0 in case of error).
-+*/
-+
-+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
-+/*
-+ Writes the given null-terminated string to the compressed file, excluding
-+ the terminating null character.
-+ gzputs returns the number of characters written, or -1 in case of error.
-+*/
-+
-+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
-+/*
-+ Reads bytes from the compressed file until len-1 characters are read, or
-+ a newline character is read and transferred to buf, or an end-of-file
-+ condition is encountered. The string is then terminated with a null
-+ character.
-+ gzgets returns buf, or Z_NULL in case of error.
-+*/
-+
-+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
-+/*
-+ Writes c, converted to an unsigned char, into the compressed file.
-+ gzputc returns the value that was written, or -1 in case of error.
-+*/
-+
-+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
-+/*
-+ Reads one byte from the compressed file. gzgetc returns this byte
-+ or -1 in case of end of file or error.
-+*/
-+
-+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
-+/*
-+ Flushes all pending output into the compressed file. The parameter
-+ flush is as in the deflate() function. The return value is the zlib
-+ error number (see function gzerror below). gzflush returns Z_OK if
-+ the flush parameter is Z_FINISH and all output could be flushed.
-+ gzflush should be called only when strictly necessary because it can
-+ degrade compression.
-+*/
-+
-+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
-+ z_off_t offset, int whence));
-+/*
-+ Sets the starting position for the next gzread or gzwrite on the
-+ given compressed file. The offset represents a number of bytes in the
-+ uncompressed data stream. The whence parameter is defined as in lseek(2);
-+ the value SEEK_END is not supported.
-+ If the file is opened for reading, this function is emulated but can be
-+ extremely slow. If the file is opened for writing, only forward seeks are
-+ supported; gzseek then compresses a sequence of zeroes up to the new
-+ starting position.
-+
-+ gzseek returns the resulting offset location as measured in bytes from
-+ the beginning of the uncompressed stream, or -1 in case of error, in
-+ particular if the file is opened for writing and the new starting position
-+ would be before the current position.
-+*/
-+
-+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
-+/*
-+ Rewinds the given file. This function is supported only for reading.
-+
-+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
-+*/
-+
-+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
-+/*
-+ Returns the starting position for the next gzread or gzwrite on the
-+ given compressed file. This position represents a number of bytes in the
-+ uncompressed data stream.
-+
-+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
-+*/
-+
-+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
-+/*
-+ Returns 1 when EOF has previously been detected reading the given
-+ input stream, otherwise zero.
-+*/
-+
-+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
-+/*
-+ Flushes all pending output if necessary, closes the compressed file
-+ and deallocates all the (de)compression state. The return value is the zlib
-+ error number (see function gzerror below).
-+*/
-+
-+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
-+/*
-+ Returns the error message for the last error which occurred on the
-+ given compressed file. errnum is set to zlib error number. If an
-+ error occurred in the file system and not in the compression library,
-+ errnum is set to Z_ERRNO and the application may consult errno
-+ to get the exact error code.
-+*/
-+
-+ /* checksum functions */
-+
-+/*
-+ These functions are not related to compression but are exported
-+ anyway because they might be useful in applications using the
-+ compression library.
-+*/
-+
-+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
-+
-+/*
-+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
-+ return the updated checksum. If buf is NULL, this function returns
-+ the required initial value for the checksum.
-+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
-+ much faster. Usage example:
-+
-+ uLong adler = adler32(0L, Z_NULL, 0);
-+
-+ while (read_buffer(buffer, length) != EOF) {
-+ adler = adler32(adler, buffer, length);
-+ }
-+ if (adler != original_adler) error();
-+*/
-+
-+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
-+/*
-+ Update a running crc with the bytes buf[0..len-1] and return the updated
-+ crc. If buf is NULL, this function returns the required initial value
-+ for the crc. Pre- and post-conditioning (one's complement) is performed
-+ within this function so it shouldn't be done by the application.
-+ Usage example:
-+
-+ uLong crc = crc32(0L, Z_NULL, 0);
-+
-+ while (read_buffer(buffer, length) != EOF) {
-+ crc = crc32(crc, buffer, length);
-+ }
-+ if (crc != original_crc) error();
-+*/
-+
-+
-+ /* various hacks, don't look :) */
-+
-+/* deflateInit and inflateInit are macros to allow checking the zlib version
-+ * and the compiler's view of z_stream:
-+ */
-+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
-+ const char *version, int stream_size));
-+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
-+ const char *version, int stream_size));
-+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
-+ int windowBits, int memLevel,
-+ int strategy, const char *version,
-+ int stream_size));
-+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
-+ const char *version, int stream_size));
-+#define deflateInit(strm, level) \
-+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
-+#define inflateInit(strm) \
-+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
-+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
-+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
-+ (strategy), ZLIB_VERSION, sizeof(z_stream))
-+#define inflateInit2(strm, windowBits) \
-+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
-+
-+
-+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
-+ struct internal_state {int dummy;}; /* hack for buggy compilers */
-+#endif
-+
-+ZEXTERN const char * ZEXPORT zError OF((int err));
-+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
-+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _ZLIB_H */
---- /dev/null 2004-02-02 20:32:13.000000000 +0000
-+++ linux/include/zlib/zutil.h 2004-07-05 23:59:30.000000000 +0100
-@@ -0,0 +1,225 @@
-+/* zutil.h -- internal interface and configuration of the compression library
-+ * Copyright (C) 1995-2002 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+/* @(#) $Id$ */
-+
-+#ifndef _Z_UTIL_H
-+#define _Z_UTIL_H
-+
-+#include "zlib.h"
-+
-+#include <linux/string.h>
-+#define HAVE_MEMCPY
-+
-+#if 0 // #ifdef STDC
-+# include <stddef.h>
-+# include <string.h>
-+# include <stdlib.h>
-+#endif
-+#ifndef __KERNEL__
-+#ifdef NO_ERRNO_H
-+ extern int errno;
-+#else
-+# include <errno.h>
-+#endif
-+#endif
-+
-+#ifndef local
-+# define local static
-+#endif
-+/* compile with -Dlocal if your debugger can't find static symbols */
-+
-+typedef unsigned char uch;
-+typedef uch FAR uchf;
-+typedef unsigned short ush;
-+typedef ush FAR ushf;
-+typedef unsigned long ulg;
-+
-+extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
-+/* (size given to avoid silly warnings with Visual C++) */
-+
-+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
-+
-+#define ERR_RETURN(strm,err) \
-+ return (strm->msg = ERR_MSG(err), (err))
-+/* To be used only when the state is known to be valid */
-+
-+ /* common constants */
-+
-+#ifndef DEF_WBITS
-+# define DEF_WBITS MAX_WBITS
-+#endif
-+/* default windowBits for decompression. MAX_WBITS is for compression only */
-+
-+#if MAX_MEM_LEVEL >= 8
-+# define DEF_MEM_LEVEL 8
-+#else
-+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-+#endif
-+/* default memLevel */
-+
-+#define STORED_BLOCK 0
-+#define STATIC_TREES 1
-+#define DYN_TREES 2
-+/* The three kinds of block type */
-+
-+#define MIN_MATCH 3
-+#define MAX_MATCH 258
-+/* The minimum and maximum match lengths */
-+
-+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-+
-+ /* target dependencies */
-+
-+#ifdef MSDOS
-+# define OS_CODE 0x00
-+# if defined(__TURBOC__) || defined(__BORLANDC__)
-+# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
-+ /* Allow compilation with ANSI keywords only enabled */
-+ void _Cdecl farfree( void *block );
-+ void *_Cdecl farmalloc( unsigned long nbytes );
-+# else
-+# include <alloc.h>
-+# endif
-+# else /* MSC or DJGPP */
-+# include <malloc.h>
-+# endif
-+#endif
-+
-+#ifdef OS2
-+# define OS_CODE 0x06
-+#endif
-+
-+#ifdef WIN32 /* Window 95 & Windows NT */
-+# define OS_CODE 0x0b
-+#endif
-+
-+#if defined(VAXC) || defined(VMS)
-+# define OS_CODE 0x02
-+# define F_OPEN(name, mode) \
-+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
-+#endif
-+
-+#ifdef AMIGA
-+# define OS_CODE 0x01
-+#endif
-+
-+#if defined(ATARI) || defined(atarist)
-+# define OS_CODE 0x05
-+#endif
-+
-+#if defined(MACOS) || defined(TARGET_OS_MAC)
-+# define OS_CODE 0x07
-+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-+# include <unix.h> /* for fdopen */
-+# else
-+# ifndef fdopen
-+# define fdopen(fd,mode) NULL /* No fdopen() */
-+# endif
-+# endif
-+#endif
-+
-+#ifdef __50SERIES /* Prime/PRIMOS */
-+# define OS_CODE 0x0F
-+#endif
-+
-+#ifdef TOPS20
-+# define OS_CODE 0x0a
-+#endif
-+
-+#if defined(_BEOS_) || defined(RISCOS)
-+# define fdopen(fd,mode) NULL /* No fdopen() */
-+#endif
-+
-+#if (defined(_MSC_VER) && (_MSC_VER > 600))
-+# define fdopen(fd,type) _fdopen(fd,type)
-+#endif
-+
-+
-+ /* Common defaults */
-+
-+#ifndef OS_CODE
-+# define OS_CODE 0x03 /* assume Unix */
-+#endif
-+
-+#ifndef F_OPEN
-+# define F_OPEN(name, mode) fopen((name), (mode))
-+#endif
-+
-+ /* functions */
-+
-+#ifdef HAVE_STRERROR
-+ extern char *strerror OF((int));
-+# define zstrerror(errnum) strerror(errnum)
-+#else
-+# define zstrerror(errnum) ""
-+#endif
-+
-+#if defined(pyr)
-+# define NO_MEMCPY
-+#endif
-+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
-+ /* Use our own functions for small and medium model with MSC <= 5.0.
-+ * You may have to use the same strategy for Borland C (untested).
-+ * The __SC__ check is for Symantec.
-+ */
-+# define NO_MEMCPY
-+#endif
-+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
-+# define HAVE_MEMCPY
-+#endif
-+#ifdef HAVE_MEMCPY
-+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
-+# define zmemcpy _fmemcpy
-+# define zmemcmp _fmemcmp
-+# define zmemzero(dest, len) _fmemset(dest, 0, len)
-+# else
-+# define zmemcpy memcpy
-+# define zmemcmp memcmp
-+# define zmemzero(dest, len) memset(dest, 0, len)
-+# endif
-+#else
-+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
-+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
-+ extern void zmemzero OF((Bytef* dest, uInt len));
-+#endif
-+
-+/* Diagnostic functions */
-+#ifdef DEBUG
-+# include <stdio.h>
-+ extern int z_verbose;
-+ extern void z_error OF((char *m));
-+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
-+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
-+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
-+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
-+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
-+#else
-+# define Assert(cond,msg)
-+# define Trace(x)
-+# define Tracev(x)
-+# define Tracevv(x)
-+# define Tracec(c,x)
-+# define Tracecv(c,x)
-+#endif
-+
-+
-+typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
-+ uInt len));
-+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-+void zcfree OF((voidpf opaque, voidpf ptr));
-+
-+#define ZALLOC(strm, items, size) \
-+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
-+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
-+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
-+
-+#endif /* _Z_UTIL_H */
---- /dev/null 2004-02-02 20:32:13.000000000 +0000
-+++ linux/include/zconf.h 2004-07-04 15:38:31.000000000 +0100
-@@ -0,0 +1,309 @@
-+/* zconf.h -- configuration of the zlib compression library
-+ * Copyright (C) 1995-2002 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* @(#) $Id$ */
-+
-+#ifndef _ZCONF_H
-+#define _ZCONF_H
-+
-+/*
-+ * If you *really* need a unique prefix for all types and library functions,
-+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
-+ */
-+#ifdef IPCOMP_PREFIX
-+# define deflateInit_ ipcomp_deflateInit_
-+# define deflate ipcomp_deflate
-+# define deflateEnd ipcomp_deflateEnd
-+# define inflateInit_ ipcomp_inflateInit_
-+# define inflate ipcomp_inflate
-+# define inflateEnd ipcomp_inflateEnd
-+# define deflateInit2_ ipcomp_deflateInit2_
-+# define deflateSetDictionary ipcomp_deflateSetDictionary
-+# define deflateCopy ipcomp_deflateCopy
-+# define deflateReset ipcomp_deflateReset
-+# define deflateParams ipcomp_deflateParams
-+# define inflateInit2_ ipcomp_inflateInit2_
-+# define inflateSetDictionary ipcomp_inflateSetDictionary
-+# define inflateSync ipcomp_inflateSync
-+# define inflateSyncPoint ipcomp_inflateSyncPoint
-+# define inflateReset ipcomp_inflateReset
-+# define compress ipcomp_compress
-+# define compress2 ipcomp_compress2
-+# define uncompress ipcomp_uncompress
-+# define adler32 ipcomp_adler32
-+# define crc32 ipcomp_crc32
-+# define get_crc_table ipcomp_get_crc_table
-+/* SSS: these also need to be prefixed to avoid clash with ppp_deflate and ext2compression */
-+# define inflate_blocks ipcomp_deflate_blocks
-+# define inflate_blocks_free ipcomp_deflate_blocks_free
-+# define inflate_blocks_new ipcomp_inflate_blocks_new
-+# define inflate_blocks_reset ipcomp_inflate_blocks_reset
-+# define inflate_blocks_sync_point ipcomp_inflate_blocks_sync_point
-+# define inflate_set_dictionary ipcomp_inflate_set_dictionary
-+# define inflate_codes ipcomp_inflate_codes
-+# define inflate_codes_free ipcomp_inflate_codes_free
-+# define inflate_codes_new ipcomp_inflate_codes_new
-+# define inflate_fast ipcomp_inflate_fast
-+# define inflate_trees_bits ipcomp_inflate_trees_bits
-+# define inflate_trees_dynamic ipcomp_inflate_trees_dynamic
-+# define inflate_trees_fixed ipcomp_inflate_trees_fixed
-+# define inflate_flush ipcomp_inflate_flush
-+# define inflate_mask ipcomp_inflate_mask
-+# define _dist_code _ipcomp_dist_code
-+# define _length_code _ipcomp_length_code
-+# define _tr_align _ipcomp_tr_align
-+# define _tr_flush_block _ipcomp_tr_flush_block
-+# define _tr_init _ipcomp_tr_init
-+# define _tr_stored_block _ipcomp_tr_stored_block
-+# define _tr_tally _ipcomp_tr_tally
-+# define zError ipcomp_zError
-+# define z_errmsg ipcomp_z_errmsg
-+# define zlibVersion ipcomp_zlibVersion
-+# define match_init ipcomp_match_init
-+# define longest_match ipcomp_longest_match
-+#endif
-+
-+#ifdef Z_PREFIX
-+# define Byte z_Byte
-+# define uInt z_uInt
-+# define uLong z_uLong
-+# define Bytef z_Bytef
-+# define charf z_charf
-+# define intf z_intf
-+# define uIntf z_uIntf
-+# define uLongf z_uLongf
-+# define voidpf z_voidpf
-+# define voidp z_voidp
-+#endif
-+
-+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-+# define WIN32
-+#endif
-+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
-+# ifndef __32BIT__
-+# define __32BIT__
-+# endif
-+#endif
-+#if defined(__MSDOS__) && !defined(MSDOS)
-+# define MSDOS
-+#endif
-+
-+/*
-+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
-+ * than 64k bytes at a time (needed on systems with 16-bit int).
-+ */
-+#if defined(MSDOS) && !defined(__32BIT__)
-+# define MAXSEG_64K
-+#endif
-+#ifdef MSDOS
-+# define UNALIGNED_OK
-+#endif
-+
-+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
-+# define STDC
-+#endif
-+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
-+# ifndef STDC
-+# define STDC
-+# endif
-+#endif
-+
-+#ifndef STDC
-+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-+# define const
-+# endif
-+#endif
-+
-+/* Some Mac compilers merge all .h files incorrectly: */
-+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
-+# define NO_DUMMY_DECL
-+#endif
-+
-+/* Old Borland C incorrectly complains about missing returns: */
-+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
-+# define NEED_DUMMY_RETURN
-+#endif
-+
-+
-+/* Maximum value for memLevel in deflateInit2 */
-+#ifndef MAX_MEM_LEVEL
-+# ifdef MAXSEG_64K
-+# define MAX_MEM_LEVEL 8
-+# else
-+# define MAX_MEM_LEVEL 9
-+# endif
-+#endif
-+
-+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
-+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
-+ * created by gzip. (Files created by minigzip can still be extracted by
-+ * gzip.)
-+ */
-+#ifndef MAX_WBITS
-+# define MAX_WBITS 15 /* 32K LZ77 window */
-+#endif
-+
-+/* The memory requirements for deflate are (in bytes):
-+ (1 << (windowBits+2)) + (1 << (memLevel+9))
-+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
-+ plus a few kilobytes for small objects. For example, if you want to reduce
-+ the default memory requirements from 256K to 128K, compile with
-+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
-+ Of course this will generally degrade compression (there's no free lunch).
-+
-+ The memory requirements for inflate are (in bytes) 1 << windowBits
-+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
-+ for small objects.
-+*/
-+
-+ /* Type declarations */
-+
-+#ifndef OF /* function prototypes */
-+# ifdef STDC
-+# define OF(args) args
-+# else
-+# define OF(args) ()
-+# endif
-+#endif
-+
-+/* The following definitions for FAR are needed only for MSDOS mixed
-+ * model programming (small or medium model with some far allocations).
-+ * This was tested only with MSC; for other MSDOS compilers you may have
-+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
-+ * just define FAR to be empty.
-+ */
-+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
-+ /* MSC small or medium model */
-+# define SMALL_MEDIUM
-+# ifdef _MSC_VER
-+# define FAR _far
-+# else
-+# define FAR far
-+# endif
-+#endif
-+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
-+# ifndef __32BIT__
-+# define SMALL_MEDIUM
-+# define FAR _far
-+# endif
-+#endif
-+
-+/* Compile with -DZLIB_DLL for Windows DLL support */
-+#if defined(ZLIB_DLL)
-+# if defined(_WINDOWS) || defined(WINDOWS)
-+# ifdef FAR
-+# undef FAR
-+# endif
-+# include <windows.h>
-+# define ZEXPORT WINAPI
-+# ifdef WIN32
-+# define ZEXPORTVA WINAPIV
-+# else
-+# define ZEXPORTVA FAR _cdecl _export
-+# endif
-+# endif
-+# if defined (__BORLANDC__)
-+# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
-+# include <windows.h>
-+# define ZEXPORT __declspec(dllexport) WINAPI
-+# define ZEXPORTRVA __declspec(dllexport) WINAPIV
-+# else
-+# if defined (_Windows) && defined (__DLL__)
-+# define ZEXPORT _export
-+# define ZEXPORTVA _export
-+# endif
-+# endif
-+# endif
-+#endif
-+
-+#if defined (__BEOS__)
-+# if defined (ZLIB_DLL)
-+# define ZEXTERN extern __declspec(dllexport)
-+# else
-+# define ZEXTERN extern __declspec(dllimport)
-+# endif
-+#endif
-+
-+#ifndef ZEXPORT
-+# define ZEXPORT
-+#endif
-+#ifndef ZEXPORTVA
-+# define ZEXPORTVA
-+#endif
-+#ifndef ZEXTERN
-+# define ZEXTERN extern
-+#endif
-+
-+#ifndef FAR
-+# define FAR
-+#endif
-+
-+#if !defined(MACOS) && !defined(TARGET_OS_MAC)
-+typedef unsigned char Byte; /* 8 bits */
-+#endif
-+typedef unsigned int uInt; /* 16 bits or more */
-+typedef unsigned long uLong; /* 32 bits or more */
-+
-+#ifdef SMALL_MEDIUM
-+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
-+# define Bytef Byte FAR
-+#else
-+ typedef Byte FAR Bytef;
-+#endif
-+typedef char FAR charf;
-+typedef int FAR intf;
-+typedef uInt FAR uIntf;
-+typedef uLong FAR uLongf;
-+
-+#ifdef STDC
-+ typedef void FAR *voidpf;
-+ typedef void *voidp;
-+#else
-+ typedef Byte FAR *voidpf;
-+ typedef Byte *voidp;
-+#endif
-+
-+#ifdef HAVE_UNISTD_H
-+# include <sys/types.h> /* for off_t */
-+# include <unistd.h> /* for SEEK_* and off_t */
-+# define z_off_t off_t
-+#endif
-+#ifndef SEEK_SET
-+# define SEEK_SET 0 /* Seek from beginning of file. */
-+# define SEEK_CUR 1 /* Seek from current position. */
-+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
-+#endif
-+#ifndef z_off_t
-+# define z_off_t long
-+#endif
-+
-+/* MVS linker does not support external names larger than 8 bytes */
-+#if defined(__MVS__)
-+# pragma map(deflateInit_,"DEIN")
-+# pragma map(deflateInit2_,"DEIN2")
-+# pragma map(deflateEnd,"DEEND")
-+# pragma map(inflateInit_,"ININ")
-+# pragma map(inflateInit2_,"ININ2")
-+# pragma map(inflateEnd,"INEND")
-+# pragma map(inflateSync,"INSY")
-+# pragma map(inflateSetDictionary,"INSEDI")
-+# pragma map(inflate_blocks,"INBL")
-+# pragma map(inflate_blocks_new,"INBLNE")
-+# pragma map(inflate_blocks_free,"INBLFR")
-+# pragma map(inflate_blocks_reset,"INBLRE")
-+# pragma map(inflate_codes_free,"INCOFR")
-+# pragma map(inflate_codes,"INCO")
-+# pragma map(inflate_fast,"INFA")
-+# pragma map(inflate_flush,"INFLU")
-+# pragma map(inflate_mask,"INMA")
-+# pragma map(inflate_set_dictionary,"INSEDI2")
-+# pragma map(ipcomp_inflate_copyright,"INCOPY")
-+# pragma map(inflate_trees_bits,"INTRBI")
-+# pragma map(inflate_trees_dynamic,"INTRDY")
-+# pragma map(inflate_trees_fixed,"INTRFI")
-+# pragma map(inflate_trees_free,"INTRFR")
-+#endif
-+
-+#endif /* _ZCONF_H */
diff --git a/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh36.13/defconfig-ipaqpxa b/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh36.13/defconfig-ipaqpxa
deleted file mode 100644
index 681818f9ab..0000000000
--- a/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh36.13/defconfig-ipaqpxa
+++ /dev/null
@@ -1,1577 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-CONFIG_ARCH_PXA=y
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_OMAHA is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_MX1ADS is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_RISCSTATION is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_AT91RM9200DK is not set
-# CONFIG_MINIMAL_OOPS is not set
-
-#
-# Linux As Bootldr support
-#
-# CONFIG_LAB is not set
-# CONFIG_BIG_KERNEL is not set
-# CONFIG_USE_DATE_CODE is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-
-#
-# Archimedes/A5000 Implementations (select only ONE)
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ACCELENT is not set
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CEP is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_CONSUS is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_FRODO is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_HACKKIT is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_JORNADA56X is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_SIMPUTER is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_USB is not set
-# CONFIG_SA1100_USB_NETLINK is not set
-# CONFIG_SA1100_USB_CHAR is not set
-# CONFIG_REGISTERS is not set
-
-#
-# Intel PXA250/210 Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_ARCH_PXA_IDP is not set
-# CONFIG_ARCH_PXA_CERF is not set
-CONFIG_ARCH_H3900=y
-CONFIG_ARCH_H1900=y
-CONFIG_ARCH_H5400=y
-# CONFIG_ARCH_H2200 is not set
-CONFIG_ARCH_AXIM=y
-CONFIG_PXA_USB=m
-CONFIG_PXA_USB_NETLINK=m
-CONFIG_PXA_USB_CHAR=m
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_FORTUNET is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM922T is not set
-# CONFIG_PLD is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_ARM1026 is not set
-# CONFIG_CPU_SA110 is not set
-# CONFIG_CPU_SA1100 is not set
-CONFIG_CPU_32v5=y
-CONFIG_CPU_XSCALE=y
-CONFIG_XSCALE_PXA250=y
-# CONFIG_XSCALE_80200_OLD is not set
-# CONFIG_CPU_32v3 is not set
-# CONFIG_CPU_32v4 is not set
-# CONFIG_SA1100_IPAQ is not set
-CONFIG_PXA_IPAQ=y
-CONFIG_IPAQ_HANDHELD=y
-
-#
-# Compaq iPAQ Handheld
-#
-CONFIG_IPAQ_HAL=m
-# CONFIG_H3600_MICRO is not set
-CONFIG_IPAQ_HAS_ROSELLA=y
-CONFIG_IPAQ_HAS_ASIC3=y
-CONFIG_H3600_ASIC=m
-CONFIG_H3900_ASIC_DEBUG=m
-CONFIG_H5400_ASIC=m
-CONFIG_H1900_ASIC=m
-CONFIG_H1900_TS=m
-CONFIG_H3600_HARDWARE=y
-CONFIG_IPAQ_SLEEVE=m
-CONFIG_SLEEVE_DEBUG=y
-CONFIG_SLEEVE_DEBUG_VERBOSE=0
-# CONFIG_SLEEVE_IRQ_DEMUX is not set
-
-#
-# Dell Axim X5
-#
-CONFIG_AXIM_HAL=m
-
-#
-# Processor Features
-#
-# CONFIG_DISCONTIGMEM is not set
-
-#
-# General setup
-#
-# CONFIG_PCI is not set
-# CONFIG_ISA is not set
-# CONFIG_ISA_DMA is not set
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_CPU_FREQ=y
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=m
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_CLPS6700 is not set
-# CONFIG_PCMCIA_SA1100 is not set
-CONFIG_PCMCIA_PXA=m
-# CONFIG_MERCURY_BACKPAQ is not set
-
-#
-# MMC/SD Card support
-#
-CONFIG_MMC=m
-CONFIG_MMC_DEBUG=y
-CONFIG_MMC_DEBUG_VERBOSE=0
-CONFIG_MMC_SAMSUNG_ASIC=m
-# CONFIG_MMC_S3C2410 is not set
-CONFIG_MMC_H5400=m
-CONFIG_MMC_ASIC3=m
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_XIP_KERNEL is not set
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_PM=y
-CONFIG_APM=m
-# CONFIG_HWTIMER is not set
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="keepinitrd"
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-CONFIG_PARPORT=m
-CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_CML1=m
-# CONFIG_PARPORT_SERIAL is not set
-# CONFIG_PARPORT_PC_FIFO is not set
-# CONFIG_PARPORT_PC_SUPERIO is not set
-CONFIG_PARPORT_PC_PCMCIA=m
-# CONFIG_PARPORT_ARC is not set
-# CONFIG_PARPORT_IDP is not set
-# CONFIG_PARPORT_AMIGA is not set
-# CONFIG_PARPORT_MFC3 is not set
-# CONFIG_PARPORT_ATARI is not set
-# CONFIG_PARPORT_GSC is not set
-# CONFIG_PARPORT_SUNBPP is not set
-# CONFIG_PARPORT_OTHER is not set
-# CONFIG_PARPORT_1284 is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=1
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=m
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_GEOMETRY=y
-# CONFIG_MTD_CFI_B1 is not set
-CONFIG_MTD_CFI_B2=y
-CONFIG_MTD_CFI_B4=y
-# CONFIG_MTD_CFI_B8 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_IPAQ=y
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-# CONFIG_MTD_SA1100 is not set
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_LUBBOCK is not set
-# CONFIG_MTD_EPXA10DB is not set
-# CONFIG_MTD_FORTUNET is not set
-# CONFIG_MTD_AUTCPU12 is not set
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_H720X is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_CEIVA is not set
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PCMCIA is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-CONFIG_MTD_BLKMTD=m
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_NVRD=m
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-CONFIG_BLK_DEV_LVM=m
-CONFIG_BLK_DEV_DM=m
-
-#
-# Networking options
-#
-CONFIG_PACKET=m
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-# CONFIG_IP_NF_AMANDA is not set
-# CONFIG_IP_NF_TFTP is not set
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_MAC=m
-# CONFIG_IP_NF_MATCH_PKTTYPE is not set
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-# CONFIG_IP_NF_MATCH_RECENT is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
-# CONFIG_IP_NF_MATCH_DSCP is not set
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-# CONFIG_IP_NF_MATCH_HELPER is not set
-CONFIG_IP_NF_MATCH_STATE=m
-# CONFIG_IP_NF_MATCH_CONNTRACK is not set
-# CONFIG_IP_NF_MATCH_UNCLEAN is not set
-# CONFIG_IP_NF_MATCH_OWNER is not set
-CONFIG_IP_NF_FILTER=m
-# CONFIG_IP_NF_TARGET_REJECT is not set
-# CONFIG_IP_NF_TARGET_MIRROR is not set
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-# CONFIG_IP_NF_TARGET_ECN is not set
-# CONFIG_IP_NF_TARGET_DSCP is not set
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_NAT_NEEDED=y
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-CONFIG_IPV6=m
-CONFIG_IPV6_SUBTREES=y
-CONFIG_IPV6_IPV6_TUNNEL=m
-CONFIG_IPV6_MOBILITY=m
-CONFIG_IPV6_MOBILITY_MN=m
-# CONFIG_IPV6_MOBILITY_HA is not set
-CONFIG_IPV6_MOBILITY_DEBUG=y
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-# CONFIG_IP6_NF_MATCH_RT is not set
-# CONFIG_IP6_NF_MATCH_OPTS is not set
-# CONFIG_IP6_NF_MATCH_FRAG is not set
-# CONFIG_IP6_NF_MATCH_HL is not set
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-# CONFIG_IP6_NF_MATCH_OWNER is not set
-CONFIG_IP6_NF_MATCH_MARK=m
-# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
-# CONFIG_IP6_NF_MATCH_AHESP is not set
-# CONFIG_IP6_NF_MATCH_LENGTH is not set
-# CONFIG_IP6_NF_MATCH_EUI64 is not set
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-
-#
-#
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_DEV_APPLETALK is not set
-# CONFIG_DECNET is not set
-CONFIG_BRIDGE=m
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_IPSEC=m
-
-#
-# IPSec options (FreeS/WAN)
-#
-CONFIG_IPSEC_IPIP=y
-CONFIG_IPSEC_AH=y
-CONFIG_IPSEC_AUTH_HMAC_MD5=y
-CONFIG_IPSEC_AUTH_HMAC_SHA1=y
-CONFIG_IPSEC_ESP=y
-CONFIG_IPSEC_ENC_3DES=y
-CONFIG_IPSEC_IPCOMP=y
-CONFIG_IPSEC_DEBUG=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_MPPE=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_STRIP is not set
-# CONFIG_WAVELAN is not set
-# CONFIG_ARLAN is not set
-# CONFIG_AIRONET4500 is not set
-# CONFIG_AIRONET4500_NONCS is not set
-# CONFIG_AIRONET4500_PROC is not set
-# CONFIG_HERMES is not set
-# CONFIG_SPECTRUM24T is not set
-
-#
-# Wireless Pcmcia cards support
-#
-# CONFIG_PCMCIA_HERMES is not set
-# CONFIG_AIRO_CS is not set
-# CONFIG_WVLAN_CS is not set
-# CONFIG_MWVLAN_CS is not set
-# CONFIG_HOSTAP is not set
-# CONFIG_HOSTAP_CS is not set
-CONFIG_NET_WIRELESS=y
-CONFIG_ATMELWLAN=y
-CONFIG_ATMELWLAN_USB_503A_RFMD=m
-CONFIG_ATMELWLAN_PCMCIA_502A=m
-CONFIG_ATMELWLAN_PCMCIA_3COM=m
-CONFIG_ATMELWLAN_PCMCIA_502AD=m
-CONFIG_ATMELWLAN_PCMCIA_502AE=m
-CONFIG_ATMELWLAN_PCMCIA_504=m
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_AXNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-# CONFIG_ARCNET_COM20020_CS is not set
-# CONFIG_PCMCIA_IBMTR is not set
-CONFIG_NET_PCMCIA_RADIO=y
-CONFIG_PCMCIA_RAYCS=m
-CONFIG_PCMCIA_NETWAVE=m
-CONFIG_PCMCIA_WAVELAN=m
-# CONFIG_AIRONET4500_CS is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-CONFIG_IRDA_ULTRA=y
-
-#
-# IrDA options
-#
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-CONFIG_IRDA_DEBUG=y
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=m
-CONFIG_IRPORT_SIR=m
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-CONFIG_PXA_FIR=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=m
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=m
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_IDEDISK_STROKE is not set
-# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-# CONFIG_BLK_DEV_IDEDISK_WD is not set
-# CONFIG_BLK_DEV_COMMERIAL is not set
-# CONFIG_BLK_DEV_TIVO is not set
-CONFIG_BLK_DEV_IDECS=m
-CONFIG_BLK_DEV_IDECD=m
-CONFIG_BLK_DEV_IDETAPE=m
-CONFIG_BLK_DEV_IDEFLOPPY=m
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_DMA_NONPCI is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=m
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-CONFIG_SD_EXTRA_DEVS=40
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_SR_EXTRA_DEVS=2
-CONFIG_CHR_DEV_SG=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_DEBUG_QUEUES is not set
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_PPA is not set
-# CONFIG_SCSI_IMM is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_SIM710 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# PCMCIA SCSI adapter support
-#
-CONFIG_SCSI_PCMCIA=y
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-CONFIG_INPUT=m
-CONFIG_INPUT_KEYBDEV=m
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_JOYDEV=m
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_UINPUT=m
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
-CONFIG_SERIAL_EXTENDED=y
-# CONFIG_SERIAL_MANY_PORTS is not set
-# CONFIG_SERIAL_SHARE_IRQ is not set
-# CONFIG_SERIAL_DETECT_IRQ is not set
-# CONFIG_SERIAL_MULTIPORT is not set
-# CONFIG_HUB6 is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_ANAKIN is not set
-# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-# CONFIG_SERIAL_S3C2410 is not set
-# CONFIG_SERIAL_S3C2410_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_UART00 is not set
-# CONFIG_SERIAL_UART00_CONSOLE is not set
-# CONFIG_SERIAL_SA1100 is not set
-# CONFIG_SERIAL_SA1100_CONSOLE is not set
-# CONFIG_SERIAL_SIR_PXA is not set
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=32
-# CONFIG_PRINTER is not set
-# CONFIG_PPDEV is not set
-CONFIG_NEWTONKBD=m
-# CONFIG_SA1100_PROFILER is not set
-
-#
-# Compaq iPAQ H3600 support
-#
-CONFIG_TOUCHSCREEN_H3600=m
-# CONFIG_H3600_BACKPAQ_FPGA is not set
-# CONFIG_H3600_BACKPAQ_ACCEL is not set
-# CONFIG_H3600_BACKPAQ_GASGAUGE is not set
-# CONFIG_H3600_BACKPAQ_SRAM is not set
-# CONFIG_H3600_BACKPAQ_AUDIO is not set
-# CONFIG_H3600_STOWAWAY is not set
-# CONFIG_H3800_MICROKBD is not set
-# CONFIG_SA1100_LIRC is not set
-CONFIG_H5400_BUZZER=m
-CONFIG_H5400_FSI=m
-
-#
-# I2C support
-#
-CONFIG_I2C=m
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-CONFIG_I2C_PXA_ALGO=m
-CONFIG_I2C_PXA_ADAP=m
-CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_PROC=m
-# CONFIG_I2C_DS1307 is not set
-
-#
-# L3 serial bus support
-#
-# CONFIG_L3 is not set
-# CONFIG_L3_ALGOBIT is not set
-# CONFIG_L3_BIT_SA1100_GPIO is not set
-
-#
-# Other L3 adapters
-#
-# CONFIG_L3_S3C2410 is not set
-# CONFIG_L3_SA1111 is not set
-# CONFIG_L3_BACKPAQ is not set
-# CONFIG_BIT_SA1100_GPIO is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-CONFIG_MOUSE=m
-# CONFIG_PSMOUSE is not set
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-# CONFIG_MK712_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_INPUT_NS558 is not set
-# CONFIG_INPUT_LIGHTNING is not set
-# CONFIG_INPUT_PCIGAME is not set
-# CONFIG_INPUT_CS461X is not set
-# CONFIG_INPUT_EMU10K1 is not set
-CONFIG_INPUT_SERIO=m
-CONFIG_INPUT_SERPORT=m
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_ANALOG is not set
-# CONFIG_INPUT_A3D is not set
-# CONFIG_INPUT_ADI is not set
-# CONFIG_INPUT_COBRA is not set
-# CONFIG_INPUT_GF2K is not set
-# CONFIG_INPUT_GRIP is not set
-# CONFIG_INPUT_INTERACT is not set
-# CONFIG_INPUT_TMDC is not set
-# CONFIG_INPUT_SIDEWINDER is not set
-# CONFIG_INPUT_IFORCE_USB is not set
-# CONFIG_INPUT_IFORCE_232 is not set
-# CONFIG_INPUT_WARRIOR is not set
-# CONFIG_INPUT_MAGELLAN is not set
-# CONFIG_INPUT_SPACEORB is not set
-# CONFIG_INPUT_SPACEBALL is not set
-# CONFIG_INPUT_STINGER is not set
-# CONFIG_INPUT_DB9 is not set
-# CONFIG_INPUT_GAMECON is not set
-# CONFIG_INPUT_TURBOGRAFX is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-# CONFIG_ACQUIRE_WDT is not set
-# CONFIG_ADVANTECH_WDT is not set
-# CONFIG_ALIM7101_WDT is not set
-# CONFIG_SC520_WDT is not set
-# CONFIG_PCWATCHDOG is not set
-# CONFIG_21285_WATCHDOG is not set
-# CONFIG_977_WATCHDOG is not set
-# CONFIG_SA1100_WATCHDOG is not set
-CONFIG_PXA_WATCHDOG=m
-# CONFIG_OMAHA_WATCHDOG is not set
-# CONFIG_EUROTECH_WDT is not set
-# CONFIG_IB700_WDT is not set
-# CONFIG_WAFER_WDT is not set
-# CONFIG_I810_TCO is not set
-# CONFIG_MIXCOMWD is not set
-# CONFIG_60XX_WDT is not set
-# CONFIG_SC1200_WDT is not set
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_W83877F_WDT is not set
-# CONFIG_WDT is not set
-# CONFIG_WDTPCI is not set
-# CONFIG_MACHZ_WDT is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_PXA_RTC=m
-CONFIG_PXA_RTC_HACK=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-CONFIG_PCMCIA_SERIAL_CS=m
-CONFIG_PCMCIA_MOBILISCAN_CS=m
-# CONFIG_AXIM_TS is not set
-CONFIG_AXIM_KEY=m
-# CONFIG_AXIM_KEY_FIX is not set
-
-#
-# Multimedia devices
-#
-CONFIG_MEDIA=m
-CONFIG_VIDEO_DEV=m
-CONFIG_V4L2_DEV=m
-
-#
-# Video For Linux
-#
-CONFIG_VIDEO_PROC_FS=y
-# CONFIG_I2C_PARPORT is not set
-
-#
-# Video Adapters
-#
-# CONFIG_VIDEO_PMS is not set
-# CONFIG_VIDEO_BWQCAM is not set
-# CONFIG_VIDEO_CQCAM is not set
-CONFIG_VIDEO_CPIA=m
-CONFIG_VIDEO_CPIA_USB=m
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIDEO_ZORAN_BUZ is not set
-# CONFIG_VIDEO_ZORAN_DC10 is not set
-# CONFIG_VIDEO_ZORAN_LML33 is not set
-# CONFIG_VIDEO_ZR36120 is not set
-# CONFIG_VIDEO_MEYE is not set
-# CONFIG_VIDEO_CYBERPRO is not set
-# CONFIG_VIDEO_H3600_BACKPAQ is not set
-# CONFIG_VIDEO_HAWKEYE is not set
-
-#
-# Video for Linux 2 (V4L2)
-#
-CONFIG_VIDEO_WINNOV_CS=m
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_CADET is not set
-# CONFIG_RADIO_RTRACK is not set
-# CONFIG_RADIO_RTRACK2 is not set
-# CONFIG_RADIO_AZTECH is not set
-# CONFIG_RADIO_GEMTEK is not set
-# CONFIG_RADIO_GEMTEK_PCI is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_MAESTRO is not set
-# CONFIG_RADIO_MIROPCM20 is not set
-# CONFIG_RADIO_MIROPCM20_RDS is not set
-# CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_TERRATEC is not set
-# CONFIG_RADIO_TRUST is not set
-# CONFIG_RADIO_TYPHOON is not set
-# CONFIG_RADIO_ZOLTRIX is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=m
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=m
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_UMSDOS_FS=m
-CONFIG_VFAT_FS=m
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-CONFIG_CRAMFS=y
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-CONFIG_ISO9660_FS=m
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DRIVERFS_FS is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=m
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-# CONFIG_ROOT_NFS is not set
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-CONFIG_SUNRPC=m
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-
-#
-# Console drivers
-#
-CONFIG_PC_KEYMAP=y
-# CONFIG_VGA_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_ACORN is not set
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_S3C2410 is not set
-# CONFIG_FB_SA1100 is not set
-# CONFIG_FB_EPSON1356 is not set
-# CONFIG_FB_MQ200 is not set
-CONFIG_FB_PXA=y
-# CONFIG_FB_PXA_8BPP is not set
-CONFIG_FB_PXA_16BPP=y
-CONFIG_FB_MQ1100=y
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-# CONFIG_FBCON_CFB4 is not set
-# CONFIG_FBCON_CFB8 is not set
-CONFIG_FBCON_CFB16=y
-# CONFIG_FBCON_CFB24 is not set
-# CONFIG_FBCON_CFB32 is not set
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA_PLANES is not set
-# CONFIG_FBCON_VGA is not set
-# CONFIG_FBCON_HGA is not set
-# CONFIG_FBCON_NO_LOGO is not set
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-CONFIG_FONT_8x8=y
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-CONFIG_SOUND_H3900_UDA1380=m
-CONFIG_SOUND_H5400=m
-CONFIG_SOUND_OSS=m
-# CONFIG_SOUND_TRACEINIT is not set
-# CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_ADLIB is not set
-# CONFIG_SOUND_ACI_MIXER is not set
-# CONFIG_SOUND_CS4232 is not set
-# CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_VMIDI is not set
-# CONFIG_SOUND_TRIX is not set
-# CONFIG_SOUND_MSS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_NM256 is not set
-# CONFIG_SOUND_MAD16 is not set
-# CONFIG_SOUND_PAS is not set
-# CONFIG_PAS_JOYSTICK is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_SB is not set
-# CONFIG_SOUND_AWE32_SYNTH is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_OPL3SA2 is not set
-# CONFIG_SOUND_YMFPCI is not set
-# CONFIG_SOUND_YMFPCI_LEGACY is not set
-# CONFIG_SOUND_UART6850 is not set
-# CONFIG_SOUND_AEDSP16 is not set
-# CONFIG_SOUND_VIDC is not set
-# CONFIG_SOUND_WAVEARTIST is not set
-CONFIG_SOUND_PXA_AC97=m
-# CONFIG_SOUND_TVMIXER is not set
-
-#
-# Multimedia Capabilities Port drivers
-#
-# CONFIG_MCP is not set
-# CONFIG_MCP_SA1100 is not set
-# CONFIG_MCP_UCB1200 is not set
-# CONFIG_MCP_UCB1200_AUDIO is not set
-# CONFIG_MCP_UCB1200_TS is not set
-# CONFIG_MCP_UCB1400_TS is not set
-
-#
-# Console Switches
-#
-# CONFIG_SWITCHES is not set
-
-#
-# USB support
-#
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_LONG_TIMEOUT is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-CONFIG_USB_OHCI=m
-# CONFIG_USB_OHCI_SA1111 is not set
-CONFIG_USB_OHCI_H5400=m
-# CONFIG_USB_OHCI_S3C2410 is not set
-# CONFIG_USB_SL811HS is not set
-
-#
-# USB Device Class drivers
-#
-CONFIG_USB_AUDIO=m
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_BLUETOOTH is not set
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-CONFIG_USB_PRINTER=m
-
-#
-# USB Human Interface Devices (HID)
-#
-CONFIG_USB_HID=m
-CONFIG_USB_HIDINPUT=y
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_WACOM is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_OV511=m
-CONFIG_USB_PWC=m
-CONFIG_USB_SE401=m
-CONFIG_USB_STV680=m
-CONFIG_USB_VICAM=m
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-CONFIG_USB_CDCETHER=m
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_BRLVGER is not set
-
-#
-# Linux As Bootldr Modules
-#
-# CONFIG_BIG_KERNEL is not set
-# CONFIG_USE_DATE_CODE is not set
-# CONFIG_YMODEM is not set
-# CONFIG_LAB_DUMMY is not set
-# CONFIG_LAB_CRC is not set
-# CONFIG_LAB_YMODEM is not set
-# CONFIG_LAB_MTD is not set
-# CONFIG_LAB_COPY is not set
-# CONFIG_LAB_COPY_YMODEM is not set
-# CONFIG_LAB_COPY_FLASH is not set
-# CONFIG_LAB_COPY_FS is not set
-# CONFIG_LAB_COPY_WRAPPER is not set
-
-#
-# Bluetooth support
-#
-CONFIG_BLUEZ=m
-CONFIG_BLUEZ_L2CAP=m
-CONFIG_BLUEZ_SCO=m
-CONFIG_BLUEZ_RFCOMM=m
-CONFIG_BLUEZ_RFCOMM_TTY=y
-CONFIG_BLUEZ_BNEP=m
-CONFIG_BLUEZ_BNEP_MC_FILTER=y
-CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
-
-#
-# Bluetooth device drivers
-#
-# CONFIG_BLUEZ_HCIUSB is not set
-CONFIG_BLUEZ_HCIUART=m
-CONFIG_BLUEZ_HCIUART_H4=y
-CONFIG_BLUEZ_HCIUART_BCSP=y
-# CONFIG_BLUEZ_HCIUART_BCSP_TXCRC is not set
-# CONFIG_BLUEZ_HCIBFUSB is not set
-CONFIG_BLUEZ_HCIDTL1=m
-CONFIG_BLUEZ_HCIBT3C=m
-CONFIG_BLUEZ_HCIBLUECARD=m
-CONFIG_BLUEZ_HCIBTUART=m
-# CONFIG_BLUEZ_HCIVHCI is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_FRAME_POINTER is not set
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_NO_PGT_CACHE is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
-
-#
-# Library routines
-#
-# CONFIG_CRC32 is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh36.14/defconfig-ipaqpxa b/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh36.14/defconfig-ipaqpxa
deleted file mode 100644
index fc9682743a..0000000000
--- a/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh36.14/defconfig-ipaqpxa
+++ /dev/null
@@ -1,1578 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-CONFIG_ARCH_PXA=y
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_OMAHA is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_MX1ADS is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_RISCSTATION is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_AT91RM9200DK is not set
-# CONFIG_MINIMAL_OOPS is not set
-
-#
-# Linux As Bootldr support
-#
-# CONFIG_LAB is not set
-# CONFIG_BIG_KERNEL is not set
-# CONFIG_USE_DATE_CODE is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-
-#
-# Archimedes/A5000 Implementations (select only ONE)
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ACCELENT is not set
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CEP is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_CONSUS is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_FRODO is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_HACKKIT is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_JORNADA56X is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_SIMPUTER is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_USB is not set
-# CONFIG_SA1100_USB_NETLINK is not set
-# CONFIG_SA1100_USB_CHAR is not set
-# CONFIG_REGISTERS is not set
-
-#
-# Intel PXA250/210 Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_ARCH_PXA_IDP is not set
-# CONFIG_ARCH_PXA_CERF is not set
-CONFIG_ARCH_H3900=y
-CONFIG_ARCH_H1900=y
-CONFIG_ARCH_H5400=y
-# CONFIG_ARCH_H2200 is not set
-CONFIG_ARCH_AXIM=y
-CONFIG_PXA_USB=m
-CONFIG_PXA_USB_NETLINK=m
-CONFIG_PXA_USB_CHAR=m
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_FORTUNET is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM922T is not set
-# CONFIG_PLD is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_ARM1026 is not set
-# CONFIG_CPU_SA110 is not set
-# CONFIG_CPU_SA1100 is not set
-CONFIG_CPU_32v5=y
-CONFIG_CPU_XSCALE=y
-CONFIG_XSCALE_PXA250=y
-# CONFIG_XSCALE_80200_OLD is not set
-# CONFIG_CPU_32v3 is not set
-# CONFIG_CPU_32v4 is not set
-# CONFIG_SA1100_IPAQ is not set
-CONFIG_PXA_IPAQ=y
-CONFIG_IPAQ_HANDHELD=y
-
-#
-# Compaq iPAQ Handheld
-#
-CONFIG_IPAQ_HAL=m
-# CONFIG_H3600_MICRO is not set
-CONFIG_IPAQ_HAS_ROSELLA=y
-CONFIG_IPAQ_HAS_ASIC3=y
-CONFIG_H3600_ASIC=m
-CONFIG_H3900_ASIC_DEBUG=m
-CONFIG_H5400_ASIC=m
-CONFIG_H1900_ASIC=m
-CONFIG_H1900_TS=m
-CONFIG_H3600_HARDWARE=y
-CONFIG_IPAQ_SLEEVE=m
-CONFIG_SLEEVE_DEBUG=y
-CONFIG_SLEEVE_DEBUG_VERBOSE=0
-# CONFIG_SLEEVE_IRQ_DEMUX is not set
-
-#
-# Dell Axim X5
-#
-CONFIG_AXIM_HAL=m
-
-#
-# Processor Features
-#
-# CONFIG_DISCONTIGMEM is not set
-
-#
-# General setup
-#
-# CONFIG_PCI is not set
-# CONFIG_ISA is not set
-# CONFIG_ISA_DMA is not set
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_CPU_FREQ=y
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=m
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_CLPS6700 is not set
-# CONFIG_PCMCIA_SA1100 is not set
-CONFIG_PCMCIA_PXA=m
-# CONFIG_MERCURY_BACKPAQ is not set
-
-#
-# MMC/SD Card support
-#
-CONFIG_MMC=m
-CONFIG_MMC_DEBUG=y
-CONFIG_MMC_DEBUG_VERBOSE=0
-CONFIG_MMC_SAMSUNG_ASIC=m
-# CONFIG_MMC_S3C2410 is not set
-CONFIG_MMC_H5400=m
-CONFIG_MMC_ASIC3=m
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_XIP_KERNEL is not set
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_PM=y
-CONFIG_APM=m
-# CONFIG_HWTIMER is not set
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="keepinitrd"
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-CONFIG_PARPORT=m
-CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_CML1=m
-# CONFIG_PARPORT_SERIAL is not set
-# CONFIG_PARPORT_PC_FIFO is not set
-# CONFIG_PARPORT_PC_SUPERIO is not set
-CONFIG_PARPORT_PC_PCMCIA=m
-# CONFIG_PARPORT_ARC is not set
-# CONFIG_PARPORT_IDP is not set
-# CONFIG_PARPORT_AMIGA is not set
-# CONFIG_PARPORT_MFC3 is not set
-# CONFIG_PARPORT_ATARI is not set
-# CONFIG_PARPORT_GSC is not set
-# CONFIG_PARPORT_SUNBPP is not set
-# CONFIG_PARPORT_OTHER is not set
-# CONFIG_PARPORT_1284 is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=1
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=m
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_GEOMETRY=y
-# CONFIG_MTD_CFI_B1 is not set
-CONFIG_MTD_CFI_B2=y
-CONFIG_MTD_CFI_B4=y
-# CONFIG_MTD_CFI_B8 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_IPAQ=y
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-# CONFIG_MTD_SA1100 is not set
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_LUBBOCK is not set
-# CONFIG_MTD_EPXA10DB is not set
-# CONFIG_MTD_FORTUNET is not set
-# CONFIG_MTD_AUTCPU12 is not set
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_H720X is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_CEIVA is not set
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PCMCIA is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-CONFIG_MTD_BLKMTD=m
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_NVRD=m
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-CONFIG_BLK_DEV_LVM=m
-CONFIG_BLK_DEV_DM=m
-
-#
-# Networking options
-#
-CONFIG_PACKET=m
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-# CONFIG_IP_NF_AMANDA is not set
-# CONFIG_IP_NF_TFTP is not set
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_MAC=m
-# CONFIG_IP_NF_MATCH_PKTTYPE is not set
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-# CONFIG_IP_NF_MATCH_RECENT is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
-# CONFIG_IP_NF_MATCH_DSCP is not set
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-# CONFIG_IP_NF_MATCH_HELPER is not set
-CONFIG_IP_NF_MATCH_STATE=m
-# CONFIG_IP_NF_MATCH_CONNTRACK is not set
-# CONFIG_IP_NF_MATCH_UNCLEAN is not set
-# CONFIG_IP_NF_MATCH_OWNER is not set
-CONFIG_IP_NF_FILTER=m
-# CONFIG_IP_NF_TARGET_REJECT is not set
-# CONFIG_IP_NF_TARGET_MIRROR is not set
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-# CONFIG_IP_NF_TARGET_ECN is not set
-# CONFIG_IP_NF_TARGET_DSCP is not set
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_NAT_NEEDED=y
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-CONFIG_IPV6=m
-CONFIG_IPV6_SUBTREES=y
-CONFIG_IPV6_IPV6_TUNNEL=m
-CONFIG_IPV6_MOBILITY=m
-CONFIG_IPV6_MOBILITY_MN=m
-# CONFIG_IPV6_MOBILITY_HA is not set
-CONFIG_IPV6_MOBILITY_DEBUG=y
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-# CONFIG_IP6_NF_MATCH_RT is not set
-# CONFIG_IP6_NF_MATCH_OPTS is not set
-# CONFIG_IP6_NF_MATCH_FRAG is not set
-# CONFIG_IP6_NF_MATCH_HL is not set
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-# CONFIG_IP6_NF_MATCH_OWNER is not set
-CONFIG_IP6_NF_MATCH_MARK=m
-# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
-# CONFIG_IP6_NF_MATCH_AHESP is not set
-# CONFIG_IP6_NF_MATCH_LENGTH is not set
-# CONFIG_IP6_NF_MATCH_EUI64 is not set
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-
-#
-#
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_DEV_APPLETALK is not set
-# CONFIG_DECNET is not set
-CONFIG_BRIDGE=m
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_IPSEC=m
-
-#
-# IPSec options (FreeS/WAN)
-#
-CONFIG_KLIPS_AUTH_HMAC_MD5=y
-CONFIG_KLIPS_AUTH_HMAC_SHA1=y
-CONFIG_KLIPS_ENC_3DES=y
-
-#
-# ESP always enabled with tunnel mode
-#
-CONFIG_KLIPS_IPCOMP=y
-CONFIG_KLIPS_DEBUG=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_MPPE=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_STRIP is not set
-# CONFIG_WAVELAN is not set
-# CONFIG_ARLAN is not set
-# CONFIG_AIRONET4500 is not set
-# CONFIG_AIRONET4500_NONCS is not set
-# CONFIG_AIRONET4500_PROC is not set
-# CONFIG_HERMES is not set
-# CONFIG_SPECTRUM24T is not set
-
-#
-# Wireless Pcmcia cards support
-#
-# CONFIG_PCMCIA_HERMES is not set
-# CONFIG_AIRO_CS is not set
-# CONFIG_WVLAN_CS is not set
-# CONFIG_MWVLAN_CS is not set
-# CONFIG_HOSTAP is not set
-# CONFIG_HOSTAP_CS is not set
-CONFIG_NET_WIRELESS=y
-CONFIG_ATMELWLAN=y
-CONFIG_ATMELWLAN_USB_503A_RFMD=m
-CONFIG_ATMELWLAN_PCMCIA_502A=m
-CONFIG_ATMELWLAN_PCMCIA_3COM=m
-CONFIG_ATMELWLAN_PCMCIA_502AD=m
-CONFIG_ATMELWLAN_PCMCIA_502AE=m
-CONFIG_ATMELWLAN_PCMCIA_504=m
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_AXNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-# CONFIG_ARCNET_COM20020_CS is not set
-# CONFIG_PCMCIA_IBMTR is not set
-CONFIG_NET_PCMCIA_RADIO=y
-CONFIG_PCMCIA_RAYCS=m
-CONFIG_PCMCIA_NETWAVE=m
-CONFIG_PCMCIA_WAVELAN=m
-# CONFIG_AIRONET4500_CS is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-CONFIG_IRDA_ULTRA=y
-
-#
-# IrDA options
-#
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-CONFIG_IRDA_DEBUG=y
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=m
-CONFIG_IRPORT_SIR=m
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-CONFIG_PXA_FIR=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=m
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=m
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_IDEDISK_STROKE is not set
-# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-# CONFIG_BLK_DEV_IDEDISK_WD is not set
-# CONFIG_BLK_DEV_COMMERIAL is not set
-# CONFIG_BLK_DEV_TIVO is not set
-CONFIG_BLK_DEV_IDECS=m
-CONFIG_BLK_DEV_IDECD=m
-CONFIG_BLK_DEV_IDETAPE=m
-CONFIG_BLK_DEV_IDEFLOPPY=m
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_DMA_NONPCI is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=m
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-CONFIG_SD_EXTRA_DEVS=40
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_SR_EXTRA_DEVS=2
-CONFIG_CHR_DEV_SG=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_DEBUG_QUEUES is not set
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_PPA is not set
-# CONFIG_SCSI_IMM is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_SIM710 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# PCMCIA SCSI adapter support
-#
-CONFIG_SCSI_PCMCIA=y
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-CONFIG_INPUT=m
-CONFIG_INPUT_KEYBDEV=m
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_JOYDEV=m
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_UINPUT=m
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
-CONFIG_SERIAL_EXTENDED=y
-# CONFIG_SERIAL_MANY_PORTS is not set
-# CONFIG_SERIAL_SHARE_IRQ is not set
-# CONFIG_SERIAL_DETECT_IRQ is not set
-# CONFIG_SERIAL_MULTIPORT is not set
-# CONFIG_HUB6 is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_ANAKIN is not set
-# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-# CONFIG_SERIAL_S3C2410 is not set
-# CONFIG_SERIAL_S3C2410_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_UART00 is not set
-# CONFIG_SERIAL_UART00_CONSOLE is not set
-# CONFIG_SERIAL_SA1100 is not set
-# CONFIG_SERIAL_SA1100_CONSOLE is not set
-# CONFIG_SERIAL_SIR_PXA is not set
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=32
-# CONFIG_PRINTER is not set
-# CONFIG_PPDEV is not set
-CONFIG_NEWTONKBD=m
-# CONFIG_SA1100_PROFILER is not set
-
-#
-# Compaq iPAQ H3600 support
-#
-CONFIG_TOUCHSCREEN_H3600=m
-# CONFIG_H3600_BACKPAQ_FPGA is not set
-# CONFIG_H3600_BACKPAQ_ACCEL is not set
-# CONFIG_H3600_BACKPAQ_GASGAUGE is not set
-# CONFIG_H3600_BACKPAQ_SRAM is not set
-# CONFIG_H3600_BACKPAQ_AUDIO is not set
-# CONFIG_H3600_STOWAWAY is not set
-# CONFIG_H3800_MICROKBD is not set
-# CONFIG_SA1100_LIRC is not set
-CONFIG_H5400_BUZZER=m
-CONFIG_H5400_FSI=m
-
-#
-# I2C support
-#
-CONFIG_I2C=m
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-CONFIG_I2C_PXA_ALGO=m
-CONFIG_I2C_PXA_ADAP=m
-CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_PROC=m
-# CONFIG_I2C_DS1307 is not set
-
-#
-# L3 serial bus support
-#
-# CONFIG_L3 is not set
-# CONFIG_L3_ALGOBIT is not set
-# CONFIG_L3_BIT_SA1100_GPIO is not set
-
-#
-# Other L3 adapters
-#
-# CONFIG_L3_S3C2410 is not set
-# CONFIG_L3_SA1111 is not set
-# CONFIG_L3_BACKPAQ is not set
-# CONFIG_BIT_SA1100_GPIO is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-CONFIG_MOUSE=m
-# CONFIG_PSMOUSE is not set
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-# CONFIG_MK712_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_INPUT_NS558 is not set
-# CONFIG_INPUT_LIGHTNING is not set
-# CONFIG_INPUT_PCIGAME is not set
-# CONFIG_INPUT_CS461X is not set
-# CONFIG_INPUT_EMU10K1 is not set
-CONFIG_INPUT_SERIO=m
-CONFIG_INPUT_SERPORT=m
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_ANALOG is not set
-# CONFIG_INPUT_A3D is not set
-# CONFIG_INPUT_ADI is not set
-# CONFIG_INPUT_COBRA is not set
-# CONFIG_INPUT_GF2K is not set
-# CONFIG_INPUT_GRIP is not set
-# CONFIG_INPUT_INTERACT is not set
-# CONFIG_INPUT_TMDC is not set
-# CONFIG_INPUT_SIDEWINDER is not set
-# CONFIG_INPUT_IFORCE_USB is not set
-# CONFIG_INPUT_IFORCE_232 is not set
-# CONFIG_INPUT_WARRIOR is not set
-# CONFIG_INPUT_MAGELLAN is not set
-# CONFIG_INPUT_SPACEORB is not set
-# CONFIG_INPUT_SPACEBALL is not set
-# CONFIG_INPUT_STINGER is not set
-# CONFIG_INPUT_DB9 is not set
-# CONFIG_INPUT_GAMECON is not set
-# CONFIG_INPUT_TURBOGRAFX is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-# CONFIG_ACQUIRE_WDT is not set
-# CONFIG_ADVANTECH_WDT is not set
-# CONFIG_ALIM7101_WDT is not set
-# CONFIG_SC520_WDT is not set
-# CONFIG_PCWATCHDOG is not set
-# CONFIG_21285_WATCHDOG is not set
-# CONFIG_977_WATCHDOG is not set
-# CONFIG_SA1100_WATCHDOG is not set
-CONFIG_PXA_WATCHDOG=m
-# CONFIG_OMAHA_WATCHDOG is not set
-# CONFIG_EUROTECH_WDT is not set
-# CONFIG_IB700_WDT is not set
-# CONFIG_WAFER_WDT is not set
-# CONFIG_I810_TCO is not set
-# CONFIG_MIXCOMWD is not set
-# CONFIG_60XX_WDT is not set
-# CONFIG_SC1200_WDT is not set
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_W83877F_WDT is not set
-# CONFIG_WDT is not set
-# CONFIG_WDTPCI is not set
-# CONFIG_MACHZ_WDT is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_PXA_RTC=m
-CONFIG_PXA_RTC_HACK=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-CONFIG_PCMCIA_SERIAL_CS=m
-CONFIG_PCMCIA_MOBILISCAN_CS=m
-# CONFIG_AXIM_TS is not set
-CONFIG_AXIM_KEY=m
-# CONFIG_AXIM_KEY_FIX is not set
-
-#
-# Multimedia devices
-#
-CONFIG_MEDIA=m
-CONFIG_VIDEO_DEV=m
-CONFIG_V4L2_DEV=m
-
-#
-# Video For Linux
-#
-CONFIG_VIDEO_PROC_FS=y
-# CONFIG_I2C_PARPORT is not set
-
-#
-# Video Adapters
-#
-# CONFIG_VIDEO_PMS is not set
-# CONFIG_VIDEO_BWQCAM is not set
-# CONFIG_VIDEO_CQCAM is not set
-CONFIG_VIDEO_CPIA=m
-CONFIG_VIDEO_CPIA_USB=m
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIDEO_ZORAN_BUZ is not set
-# CONFIG_VIDEO_ZORAN_DC10 is not set
-# CONFIG_VIDEO_ZORAN_LML33 is not set
-# CONFIG_VIDEO_ZR36120 is not set
-# CONFIG_VIDEO_MEYE is not set
-# CONFIG_VIDEO_CYBERPRO is not set
-# CONFIG_VIDEO_H3600_BACKPAQ is not set
-# CONFIG_VIDEO_HAWKEYE is not set
-
-#
-# Video for Linux 2 (V4L2)
-#
-CONFIG_VIDEO_WINNOV_CS=m
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_CADET is not set
-# CONFIG_RADIO_RTRACK is not set
-# CONFIG_RADIO_RTRACK2 is not set
-# CONFIG_RADIO_AZTECH is not set
-# CONFIG_RADIO_GEMTEK is not set
-# CONFIG_RADIO_GEMTEK_PCI is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_MAESTRO is not set
-# CONFIG_RADIO_MIROPCM20 is not set
-# CONFIG_RADIO_MIROPCM20_RDS is not set
-# CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_TERRATEC is not set
-# CONFIG_RADIO_TRUST is not set
-# CONFIG_RADIO_TYPHOON is not set
-# CONFIG_RADIO_ZOLTRIX is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=m
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=m
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_UMSDOS_FS=m
-CONFIG_VFAT_FS=m
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-CONFIG_CRAMFS=y
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-CONFIG_ISO9660_FS=m
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DRIVERFS_FS is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=m
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-# CONFIG_ROOT_NFS is not set
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-CONFIG_SUNRPC=m
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-
-#
-# Console drivers
-#
-CONFIG_PC_KEYMAP=y
-# CONFIG_VGA_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_ACORN is not set
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_S3C2410 is not set
-# CONFIG_FB_SA1100 is not set
-# CONFIG_FB_EPSON1356 is not set
-# CONFIG_FB_MQ200 is not set
-CONFIG_FB_PXA=y
-# CONFIG_FB_PXA_8BPP is not set
-CONFIG_FB_PXA_16BPP=y
-CONFIG_FB_MQ1100=y
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-# CONFIG_FBCON_CFB4 is not set
-# CONFIG_FBCON_CFB8 is not set
-CONFIG_FBCON_CFB16=y
-# CONFIG_FBCON_CFB24 is not set
-# CONFIG_FBCON_CFB32 is not set
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA_PLANES is not set
-# CONFIG_FBCON_VGA is not set
-# CONFIG_FBCON_HGA is not set
-# CONFIG_FBCON_NO_LOGO is not set
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-CONFIG_FONT_8x8=y
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-CONFIG_SOUND_H3900_UDA1380=m
-CONFIG_SOUND_H5400=m
-CONFIG_SOUND_OSS=m
-# CONFIG_SOUND_TRACEINIT is not set
-# CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_ADLIB is not set
-# CONFIG_SOUND_ACI_MIXER is not set
-# CONFIG_SOUND_CS4232 is not set
-# CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_VMIDI is not set
-# CONFIG_SOUND_TRIX is not set
-# CONFIG_SOUND_MSS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_NM256 is not set
-# CONFIG_SOUND_MAD16 is not set
-# CONFIG_SOUND_PAS is not set
-# CONFIG_PAS_JOYSTICK is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_SB is not set
-# CONFIG_SOUND_AWE32_SYNTH is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_OPL3SA2 is not set
-# CONFIG_SOUND_YMFPCI is not set
-# CONFIG_SOUND_YMFPCI_LEGACY is not set
-# CONFIG_SOUND_UART6850 is not set
-# CONFIG_SOUND_AEDSP16 is not set
-# CONFIG_SOUND_VIDC is not set
-# CONFIG_SOUND_WAVEARTIST is not set
-CONFIG_SOUND_PXA_AC97=m
-# CONFIG_SOUND_TVMIXER is not set
-
-#
-# Multimedia Capabilities Port drivers
-#
-# CONFIG_MCP is not set
-# CONFIG_MCP_SA1100 is not set
-# CONFIG_MCP_UCB1200 is not set
-# CONFIG_MCP_UCB1200_AUDIO is not set
-# CONFIG_MCP_UCB1200_TS is not set
-# CONFIG_MCP_UCB1400_TS is not set
-
-#
-# Console Switches
-#
-# CONFIG_SWITCHES is not set
-
-#
-# USB support
-#
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_LONG_TIMEOUT is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-CONFIG_USB_OHCI=m
-# CONFIG_USB_OHCI_SA1111 is not set
-CONFIG_USB_OHCI_H5400=m
-# CONFIG_USB_OHCI_S3C2410 is not set
-# CONFIG_USB_SL811HS is not set
-
-#
-# USB Device Class drivers
-#
-CONFIG_USB_AUDIO=m
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_BLUETOOTH is not set
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-CONFIG_USB_PRINTER=m
-
-#
-# USB Human Interface Devices (HID)
-#
-CONFIG_USB_HID=m
-CONFIG_USB_HIDINPUT=y
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_WACOM is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_OV511=m
-CONFIG_USB_PWC=m
-CONFIG_USB_SE401=m
-CONFIG_USB_STV680=m
-CONFIG_USB_VICAM=m
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-CONFIG_USB_CDCETHER=m
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_BRLVGER is not set
-
-#
-# Linux As Bootldr Modules
-#
-# CONFIG_BIG_KERNEL is not set
-# CONFIG_USE_DATE_CODE is not set
-# CONFIG_YMODEM is not set
-# CONFIG_LAB_DUMMY is not set
-# CONFIG_LAB_CRC is not set
-# CONFIG_LAB_YMODEM is not set
-# CONFIG_LAB_MTD is not set
-# CONFIG_LAB_COPY is not set
-# CONFIG_LAB_COPY_YMODEM is not set
-# CONFIG_LAB_COPY_FLASH is not set
-# CONFIG_LAB_COPY_FS is not set
-# CONFIG_LAB_COPY_WRAPPER is not set
-
-#
-# Bluetooth support
-#
-CONFIG_BLUEZ=m
-CONFIG_BLUEZ_L2CAP=m
-CONFIG_BLUEZ_SCO=m
-CONFIG_BLUEZ_RFCOMM=m
-CONFIG_BLUEZ_RFCOMM_TTY=y
-CONFIG_BLUEZ_BNEP=m
-CONFIG_BLUEZ_BNEP_MC_FILTER=y
-CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
-
-#
-# Bluetooth device drivers
-#
-# CONFIG_BLUEZ_HCIUSB is not set
-CONFIG_BLUEZ_HCIUART=m
-CONFIG_BLUEZ_HCIUART_H4=y
-CONFIG_BLUEZ_HCIUART_BCSP=y
-# CONFIG_BLUEZ_HCIUART_BCSP_TXCRC is not set
-# CONFIG_BLUEZ_HCIBFUSB is not set
-CONFIG_BLUEZ_HCIDTL1=m
-CONFIG_BLUEZ_HCIBT3C=m
-CONFIG_BLUEZ_HCIBLUECARD=m
-CONFIG_BLUEZ_HCIBTUART=m
-# CONFIG_BLUEZ_HCIVHCI is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_FRAME_POINTER is not set
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_NO_PGT_CACHE is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
-
-#
-# Library routines
-#
-# CONFIG_CRC32 is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh37.1/defconfig-ipaqpxa b/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh37.1/defconfig-ipaqpxa
deleted file mode 100644
index ee30cf0a42..0000000000
--- a/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh37.1/defconfig-ipaqpxa
+++ /dev/null
@@ -1,1578 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-CONFIG_ARCH_PXA=y
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_OMAHA is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_MX1ADS is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_RISCSTATION is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_AT91RM9200DK is not set
-# CONFIG_MINIMAL_OOPS is not set
-
-#
-# Linux As Bootldr support
-#
-# CONFIG_LAB is not set
-# CONFIG_BIG_KERNEL is not set
-# CONFIG_USE_DATE_CODE is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-
-#
-# Archimedes/A5000 Implementations (select only ONE)
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ACCELENT is not set
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CEP is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_CONSUS is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_FRODO is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_HACKKIT is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_JORNADA56X is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_SIMPUTER is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_USB is not set
-# CONFIG_SA1100_USB_NETLINK is not set
-# CONFIG_SA1100_USB_CHAR is not set
-# CONFIG_REGISTERS is not set
-
-#
-# Intel PXA250/210 Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_ARCH_PXA_IDP is not set
-# CONFIG_ARCH_PXA_CERF is not set
-CONFIG_ARCH_H3900=y
-CONFIG_ARCH_H1900=y
-CONFIG_ARCH_H5400=y
-# CONFIG_ARCH_H2200 is not set
-CONFIG_ARCH_AXIM=y
-CONFIG_PXA_USB=m
-CONFIG_PXA_USB_NETLINK=m
-CONFIG_PXA_USB_CHAR=m
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_FORTUNET is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM922T is not set
-# CONFIG_PLD is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_ARM1026 is not set
-# CONFIG_CPU_SA110 is not set
-# CONFIG_CPU_SA1100 is not set
-CONFIG_CPU_32v5=y
-CONFIG_CPU_XSCALE=y
-CONFIG_XSCALE_PXA250=y
-# CONFIG_XSCALE_80200_OLD is not set
-# CONFIG_CPU_32v3 is not set
-# CONFIG_CPU_32v4 is not set
-# CONFIG_SA1100_IPAQ is not set
-CONFIG_PXA_IPAQ=y
-CONFIG_IPAQ_HANDHELD=y
-
-#
-# Compaq iPAQ Handheld
-#
-CONFIG_IPAQ_HAL=m
-# CONFIG_H3600_MICRO is not set
-CONFIG_IPAQ_HAS_ROSELLA=y
-CONFIG_IPAQ_HAS_ASIC3=y
-CONFIG_H3600_ASIC=m
-CONFIG_H3900_ASIC_DEBUG=m
-CONFIG_H5400_ASIC=m
-CONFIG_H1900_ASIC=m
-CONFIG_H1900_TS=m
-CONFIG_H3600_HARDWARE=y
-CONFIG_IPAQ_SLEEVE=m
-CONFIG_SLEEVE_DEBUG=y
-CONFIG_SLEEVE_DEBUG_VERBOSE=0
-# CONFIG_SLEEVE_IRQ_DEMUX is not set
-
-#
-# Dell Axim X5
-#
-CONFIG_AXIM_HAL=m
-
-#
-# Processor Features
-#
-# CONFIG_DISCONTIGMEM is not set
-
-#
-# General setup
-#
-# CONFIG_PCI is not set
-# CONFIG_ISA is not set
-# CONFIG_ISA_DMA is not set
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_CPU_FREQ=y
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=m
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_CLPS6700 is not set
-# CONFIG_PCMCIA_SA1100 is not set
-CONFIG_PCMCIA_PXA=m
-# CONFIG_MERCURY_BACKPAQ is not set
-
-#
-# MMC/SD Card support
-#
-CONFIG_MMC=m
-CONFIG_MMC_DEBUG=y
-CONFIG_MMC_DEBUG_VERBOSE=0
-CONFIG_MMC_SAMSUNG_ASIC=m
-# CONFIG_MMC_S3C2410 is not set
-CONFIG_MMC_H5400=m
-CONFIG_MMC_ASIC3=m
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_XIP_KERNEL is not set
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_PM=y
-CONFIG_APM=m
-# CONFIG_HWTIMER is not set
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="keepinitrd"
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-CONFIG_PARPORT=m
-CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_CML1=m
-# CONFIG_PARPORT_SERIAL is not set
-# CONFIG_PARPORT_PC_FIFO is not set
-# CONFIG_PARPORT_PC_SUPERIO is not set
-CONFIG_PARPORT_PC_PCMCIA=m
-# CONFIG_PARPORT_ARC is not set
-# CONFIG_PARPORT_IDP is not set
-# CONFIG_PARPORT_AMIGA is not set
-# CONFIG_PARPORT_MFC3 is not set
-# CONFIG_PARPORT_ATARI is not set
-# CONFIG_PARPORT_GSC is not set
-# CONFIG_PARPORT_SUNBPP is not set
-# CONFIG_PARPORT_OTHER is not set
-# CONFIG_PARPORT_1284 is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=1
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=m
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_GEOMETRY=y
-# CONFIG_MTD_CFI_B1 is not set
-CONFIG_MTD_CFI_B2=y
-CONFIG_MTD_CFI_B4=y
-# CONFIG_MTD_CFI_B8 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_IPAQ=y
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-# CONFIG_MTD_SA1100 is not set
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_LUBBOCK is not set
-# CONFIG_MTD_EPXA10DB is not set
-# CONFIG_MTD_FORTUNET is not set
-# CONFIG_MTD_AUTCPU12 is not set
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_H720X is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_CEIVA is not set
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PCMCIA is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-CONFIG_MTD_BLKMTD=m
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_NVRD=m
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-CONFIG_BLK_DEV_LVM=m
-CONFIG_BLK_DEV_DM=m
-
-#
-# Networking options
-#
-CONFIG_PACKET=m
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-# CONFIG_IP_NF_AMANDA is not set
-# CONFIG_IP_NF_TFTP is not set
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_MAC=m
-# CONFIG_IP_NF_MATCH_PKTTYPE is not set
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-# CONFIG_IP_NF_MATCH_RECENT is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
-# CONFIG_IP_NF_MATCH_DSCP is not set
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-# CONFIG_IP_NF_MATCH_HELPER is not set
-CONFIG_IP_NF_MATCH_STATE=m
-# CONFIG_IP_NF_MATCH_CONNTRACK is not set
-# CONFIG_IP_NF_MATCH_UNCLEAN is not set
-# CONFIG_IP_NF_MATCH_OWNER is not set
-CONFIG_IP_NF_FILTER=m
-# CONFIG_IP_NF_TARGET_REJECT is not set
-# CONFIG_IP_NF_TARGET_MIRROR is not set
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-# CONFIG_IP_NF_TARGET_ECN is not set
-# CONFIG_IP_NF_TARGET_DSCP is not set
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_NAT_NEEDED=y
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-CONFIG_IPV6=m
-CONFIG_IPV6_SUBTREES=y
-CONFIG_IPV6_TUNNEL=m
-CONFIG_IPV6_MOBILITY=m
-CONFIG_IPV6_MOBILITY_MN=m
-# CONFIG_IPV6_MOBILITY_HA is not set
-CONFIG_IPV6_MOBILITY_DEBUG=y
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-# CONFIG_IP6_NF_MATCH_RT is not set
-# CONFIG_IP6_NF_MATCH_OPTS is not set
-# CONFIG_IP6_NF_MATCH_FRAG is not set
-# CONFIG_IP6_NF_MATCH_HL is not set
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-# CONFIG_IP6_NF_MATCH_OWNER is not set
-CONFIG_IP6_NF_MATCH_MARK=m
-# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
-# CONFIG_IP6_NF_MATCH_AHESP is not set
-# CONFIG_IP6_NF_MATCH_LENGTH is not set
-# CONFIG_IP6_NF_MATCH_EUI64 is not set
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-
-#
-#
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_DEV_APPLETALK is not set
-# CONFIG_DECNET is not set
-CONFIG_BRIDGE=m
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_IPSEC=m
-
-#
-# IPSec options (FreeS/WAN)
-#
-CONFIG_KLIPS_AUTH_HMAC_MD5=y
-CONFIG_KLIPS_AUTH_HMAC_SHA1=y
-CONFIG_KLIPS_ENC_3DES=y
-
-#
-# ESP always enabled with tunnel mode
-#
-CONFIG_KLIPS_IPCOMP=y
-CONFIG_KLIPS_DEBUG=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_MPPE=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_STRIP is not set
-# CONFIG_WAVELAN is not set
-# CONFIG_ARLAN is not set
-# CONFIG_AIRONET4500 is not set
-# CONFIG_AIRONET4500_NONCS is not set
-# CONFIG_AIRONET4500_PROC is not set
-# CONFIG_HERMES is not set
-# CONFIG_SPECTRUM24T is not set
-
-#
-# Wireless Pcmcia cards support
-#
-# CONFIG_PCMCIA_HERMES is not set
-# CONFIG_AIRO_CS is not set
-# CONFIG_WVLAN_CS is not set
-# CONFIG_MWVLAN_CS is not set
-# CONFIG_HOSTAP is not set
-# CONFIG_HOSTAP_CS is not set
-CONFIG_NET_WIRELESS=y
-CONFIG_ATMELWLAN=y
-CONFIG_ATMELWLAN_USB_503A_RFMD=m
-CONFIG_ATMELWLAN_PCMCIA_502A=m
-CONFIG_ATMELWLAN_PCMCIA_3COM=m
-CONFIG_ATMELWLAN_PCMCIA_502AD=m
-CONFIG_ATMELWLAN_PCMCIA_502AE=m
-CONFIG_ATMELWLAN_PCMCIA_504=m
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_AXNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-# CONFIG_ARCNET_COM20020_CS is not set
-# CONFIG_PCMCIA_IBMTR is not set
-CONFIG_NET_PCMCIA_RADIO=y
-CONFIG_PCMCIA_RAYCS=m
-CONFIG_PCMCIA_NETWAVE=m
-CONFIG_PCMCIA_WAVELAN=m
-# CONFIG_AIRONET4500_CS is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-CONFIG_IRDA_ULTRA=y
-
-#
-# IrDA options
-#
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-CONFIG_IRDA_DEBUG=y
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=m
-CONFIG_IRPORT_SIR=m
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-CONFIG_PXA_FIR=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=m
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=m
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_IDEDISK_STROKE is not set
-# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-# CONFIG_BLK_DEV_IDEDISK_WD is not set
-# CONFIG_BLK_DEV_COMMERIAL is not set
-# CONFIG_BLK_DEV_TIVO is not set
-CONFIG_BLK_DEV_IDECS=m
-CONFIG_BLK_DEV_IDECD=m
-CONFIG_BLK_DEV_IDETAPE=m
-CONFIG_BLK_DEV_IDEFLOPPY=m
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_DMA_NONPCI is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=m
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-CONFIG_SD_EXTRA_DEVS=40
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_SR_EXTRA_DEVS=2
-CONFIG_CHR_DEV_SG=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_DEBUG_QUEUES is not set
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_PPA is not set
-# CONFIG_SCSI_IMM is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_SIM710 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# PCMCIA SCSI adapter support
-#
-CONFIG_SCSI_PCMCIA=y
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-CONFIG_INPUT=m
-CONFIG_INPUT_KEYBDEV=m
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_JOYDEV=m
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_UINPUT=m
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
-CONFIG_SERIAL_EXTENDED=y
-# CONFIG_SERIAL_MANY_PORTS is not set
-# CONFIG_SERIAL_SHARE_IRQ is not set
-# CONFIG_SERIAL_DETECT_IRQ is not set
-# CONFIG_SERIAL_MULTIPORT is not set
-# CONFIG_HUB6 is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_ANAKIN is not set
-# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-# CONFIG_SERIAL_S3C2410 is not set
-# CONFIG_SERIAL_S3C2410_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_UART00 is not set
-# CONFIG_SERIAL_UART00_CONSOLE is not set
-# CONFIG_SERIAL_SA1100 is not set
-# CONFIG_SERIAL_SA1100_CONSOLE is not set
-# CONFIG_SERIAL_SIR_PXA is not set
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=32
-# CONFIG_PRINTER is not set
-# CONFIG_PPDEV is not set
-CONFIG_NEWTONKBD=m
-# CONFIG_SA1100_PROFILER is not set
-
-#
-# Compaq iPAQ H3600 support
-#
-CONFIG_TOUCHSCREEN_H3600=m
-# CONFIG_H3600_BACKPAQ_FPGA is not set
-# CONFIG_H3600_BACKPAQ_ACCEL is not set
-# CONFIG_H3600_BACKPAQ_GASGAUGE is not set
-# CONFIG_H3600_BACKPAQ_SRAM is not set
-# CONFIG_H3600_BACKPAQ_AUDIO is not set
-# CONFIG_H3600_STOWAWAY is not set
-# CONFIG_H3800_MICROKBD is not set
-# CONFIG_SA1100_LIRC is not set
-CONFIG_H5400_BUZZER=m
-CONFIG_H5400_FSI=m
-
-#
-# I2C support
-#
-CONFIG_I2C=m
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-CONFIG_I2C_PXA_ALGO=m
-CONFIG_I2C_PXA_ADAP=m
-CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_PROC=m
-# CONFIG_I2C_DS1307 is not set
-
-#
-# L3 serial bus support
-#
-# CONFIG_L3 is not set
-# CONFIG_L3_ALGOBIT is not set
-# CONFIG_L3_BIT_SA1100_GPIO is not set
-
-#
-# Other L3 adapters
-#
-# CONFIG_L3_S3C2410 is not set
-# CONFIG_L3_SA1111 is not set
-# CONFIG_L3_BACKPAQ is not set
-# CONFIG_BIT_SA1100_GPIO is not set
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-CONFIG_MOUSE=m
-# CONFIG_PSMOUSE is not set
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-# CONFIG_MK712_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_INPUT_NS558 is not set
-# CONFIG_INPUT_LIGHTNING is not set
-# CONFIG_INPUT_PCIGAME is not set
-# CONFIG_INPUT_CS461X is not set
-# CONFIG_INPUT_EMU10K1 is not set
-CONFIG_INPUT_SERIO=m
-CONFIG_INPUT_SERPORT=m
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_ANALOG is not set
-# CONFIG_INPUT_A3D is not set
-# CONFIG_INPUT_ADI is not set
-# CONFIG_INPUT_COBRA is not set
-# CONFIG_INPUT_GF2K is not set
-# CONFIG_INPUT_GRIP is not set
-# CONFIG_INPUT_INTERACT is not set
-# CONFIG_INPUT_TMDC is not set
-# CONFIG_INPUT_SIDEWINDER is not set
-# CONFIG_INPUT_IFORCE_USB is not set
-# CONFIG_INPUT_IFORCE_232 is not set
-# CONFIG_INPUT_WARRIOR is not set
-# CONFIG_INPUT_MAGELLAN is not set
-# CONFIG_INPUT_SPACEORB is not set
-# CONFIG_INPUT_SPACEBALL is not set
-# CONFIG_INPUT_STINGER is not set
-# CONFIG_INPUT_DB9 is not set
-# CONFIG_INPUT_GAMECON is not set
-# CONFIG_INPUT_TURBOGRAFX is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-# CONFIG_ACQUIRE_WDT is not set
-# CONFIG_ADVANTECH_WDT is not set
-# CONFIG_ALIM7101_WDT is not set
-# CONFIG_SC520_WDT is not set
-# CONFIG_PCWATCHDOG is not set
-# CONFIG_21285_WATCHDOG is not set
-# CONFIG_977_WATCHDOG is not set
-# CONFIG_SA1100_WATCHDOG is not set
-CONFIG_PXA_WATCHDOG=m
-# CONFIG_OMAHA_WATCHDOG is not set
-# CONFIG_EUROTECH_WDT is not set
-# CONFIG_IB700_WDT is not set
-# CONFIG_WAFER_WDT is not set
-# CONFIG_I810_TCO is not set
-# CONFIG_MIXCOMWD is not set
-# CONFIG_60XX_WDT is not set
-# CONFIG_SC1200_WDT is not set
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_W83877F_WDT is not set
-# CONFIG_WDT is not set
-# CONFIG_WDTPCI is not set
-# CONFIG_MACHZ_WDT is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_PXA_RTC=m
-CONFIG_PXA_RTC_HACK=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-CONFIG_PCMCIA_SERIAL_CS=m
-CONFIG_PCMCIA_MOBILISCAN_CS=m
-# CONFIG_AXIM_TS is not set
-CONFIG_AXIM_KEY=m
-# CONFIG_AXIM_KEY_FIX is not set
-
-#
-# Multimedia devices
-#
-CONFIG_MEDIA=m
-CONFIG_VIDEO_DEV=m
-CONFIG_V4L2_DEV=m
-
-#
-# Video For Linux
-#
-CONFIG_VIDEO_PROC_FS=y
-# CONFIG_I2C_PARPORT is not set
-
-#
-# Video Adapters
-#
-# CONFIG_VIDEO_PMS is not set
-# CONFIG_VIDEO_BWQCAM is not set
-# CONFIG_VIDEO_CQCAM is not set
-CONFIG_VIDEO_CPIA=m
-CONFIG_VIDEO_CPIA_USB=m
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIDEO_ZORAN_BUZ is not set
-# CONFIG_VIDEO_ZORAN_DC10 is not set
-# CONFIG_VIDEO_ZORAN_LML33 is not set
-# CONFIG_VIDEO_ZR36120 is not set
-# CONFIG_VIDEO_MEYE is not set
-# CONFIG_VIDEO_CYBERPRO is not set
-# CONFIG_VIDEO_H3600_BACKPAQ is not set
-# CONFIG_VIDEO_HAWKEYE is not set
-
-#
-# Video for Linux 2 (V4L2)
-#
-CONFIG_VIDEO_WINNOV_CS=m
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_CADET is not set
-# CONFIG_RADIO_RTRACK is not set
-# CONFIG_RADIO_RTRACK2 is not set
-# CONFIG_RADIO_AZTECH is not set
-# CONFIG_RADIO_GEMTEK is not set
-# CONFIG_RADIO_GEMTEK_PCI is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_MAESTRO is not set
-# CONFIG_RADIO_MIROPCM20 is not set
-# CONFIG_RADIO_MIROPCM20_RDS is not set
-# CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_TERRATEC is not set
-# CONFIG_RADIO_TRUST is not set
-# CONFIG_RADIO_TYPHOON is not set
-# CONFIG_RADIO_ZOLTRIX is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=m
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=m
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_UMSDOS_FS=m
-CONFIG_VFAT_FS=m
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-CONFIG_CRAMFS=y
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-CONFIG_ISO9660_FS=m
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DRIVERFS_FS is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=m
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-# CONFIG_ROOT_NFS is not set
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-CONFIG_SUNRPC=m
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-
-#
-# Console drivers
-#
-CONFIG_PC_KEYMAP=y
-# CONFIG_VGA_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_ACORN is not set
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_S3C2410 is not set
-# CONFIG_FB_SA1100 is not set
-# CONFIG_FB_EPSON1356 is not set
-# CONFIG_FB_MQ200 is not set
-CONFIG_FB_PXA=y
-# CONFIG_FB_PXA_8BPP is not set
-CONFIG_FB_PXA_16BPP=y
-CONFIG_FB_MQ1100=y
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-# CONFIG_FBCON_CFB4 is not set
-# CONFIG_FBCON_CFB8 is not set
-CONFIG_FBCON_CFB16=y
-# CONFIG_FBCON_CFB24 is not set
-# CONFIG_FBCON_CFB32 is not set
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA_PLANES is not set
-# CONFIG_FBCON_VGA is not set
-# CONFIG_FBCON_HGA is not set
-# CONFIG_FBCON_NO_LOGO is not set
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-CONFIG_FONT_8x8=y
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-CONFIG_SOUND_H3900_UDA1380=m
-CONFIG_SOUND_H5400=m
-CONFIG_SOUND_OSS=m
-# CONFIG_SOUND_TRACEINIT is not set
-# CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_ADLIB is not set
-# CONFIG_SOUND_ACI_MIXER is not set
-# CONFIG_SOUND_CS4232 is not set
-# CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_VMIDI is not set
-# CONFIG_SOUND_TRIX is not set
-# CONFIG_SOUND_MSS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_NM256 is not set
-# CONFIG_SOUND_MAD16 is not set
-# CONFIG_SOUND_PAS is not set
-# CONFIG_PAS_JOYSTICK is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_SB is not set
-# CONFIG_SOUND_AWE32_SYNTH is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_OPL3SA2 is not set
-# CONFIG_SOUND_YMFPCI is not set
-# CONFIG_SOUND_YMFPCI_LEGACY is not set
-# CONFIG_SOUND_UART6850 is not set
-# CONFIG_SOUND_AEDSP16 is not set
-# CONFIG_SOUND_VIDC is not set
-# CONFIG_SOUND_WAVEARTIST is not set
-CONFIG_SOUND_PXA_AC97=m
-# CONFIG_SOUND_TVMIXER is not set
-
-#
-# Multimedia Capabilities Port drivers
-#
-# CONFIG_MCP is not set
-# CONFIG_MCP_SA1100 is not set
-# CONFIG_MCP_UCB1200 is not set
-# CONFIG_MCP_UCB1200_AUDIO is not set
-# CONFIG_MCP_UCB1200_TS is not set
-# CONFIG_MCP_UCB1400_TS is not set
-
-#
-# Console Switches
-#
-# CONFIG_SWITCHES is not set
-
-#
-# USB support
-#
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_LONG_TIMEOUT is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-CONFIG_USB_OHCI=m
-# CONFIG_USB_OHCI_SA1111 is not set
-CONFIG_USB_OHCI_H5400=m
-# CONFIG_USB_OHCI_S3C2410 is not set
-# CONFIG_USB_SL811HS is not set
-
-#
-# USB Device Class drivers
-#
-CONFIG_USB_AUDIO=m
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_BLUETOOTH is not set
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-CONFIG_USB_PRINTER=m
-
-#
-# USB Human Interface Devices (HID)
-#
-CONFIG_USB_HID=m
-CONFIG_USB_HIDINPUT=y
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_WACOM is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_OV511=m
-CONFIG_USB_PWC=m
-CONFIG_USB_SE401=m
-CONFIG_USB_STV680=m
-CONFIG_USB_VICAM=m
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-CONFIG_USB_CDCETHER=m
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_BRLVGER is not set
-
-#
-# Linux As Bootldr Modules
-#
-# CONFIG_BIG_KERNEL is not set
-# CONFIG_USE_DATE_CODE is not set
-# CONFIG_YMODEM is not set
-# CONFIG_LAB_DUMMY is not set
-# CONFIG_LAB_CRC is not set
-# CONFIG_LAB_YMODEM is not set
-# CONFIG_LAB_MTD is not set
-# CONFIG_LAB_COPY is not set
-# CONFIG_LAB_COPY_YMODEM is not set
-# CONFIG_LAB_COPY_FLASH is not set
-# CONFIG_LAB_COPY_FS is not set
-# CONFIG_LAB_COPY_WRAPPER is not set
-
-#
-# Bluetooth support
-#
-CONFIG_BLUEZ=m
-CONFIG_BLUEZ_L2CAP=m
-CONFIG_BLUEZ_SCO=m
-CONFIG_BLUEZ_RFCOMM=m
-CONFIG_BLUEZ_RFCOMM_TTY=y
-CONFIG_BLUEZ_BNEP=m
-CONFIG_BLUEZ_BNEP_MC_FILTER=y
-CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
-
-#
-# Bluetooth device drivers
-#
-# CONFIG_BLUEZ_HCIUSB is not set
-CONFIG_BLUEZ_HCIUART=m
-CONFIG_BLUEZ_HCIUART_H4=y
-CONFIG_BLUEZ_HCIUART_BCSP=y
-# CONFIG_BLUEZ_HCIUART_BCSP_TXCRC is not set
-# CONFIG_BLUEZ_HCIBFUSB is not set
-CONFIG_BLUEZ_HCIDTL1=m
-CONFIG_BLUEZ_HCIBT3C=m
-CONFIG_BLUEZ_HCIBLUECARD=m
-CONFIG_BLUEZ_HCIBTUART=m
-# CONFIG_BLUEZ_HCIVHCI is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_FRAME_POINTER is not set
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_NO_PGT_CACHE is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
-
-#
-# Library routines
-#
-# CONFIG_CRC32 is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh37.4/defconfig-ipaqpxa b/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh37.4/defconfig-ipaqpxa
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh37.4/defconfig-ipaqpxa
+++ /dev/null
diff --git a/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh37.4/mmc_h5400.patch b/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh37.4/mmc_h5400.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/handhelds-pxa-2.4.19-rmk6-pxa1-hh37.4/mmc_h5400.patch
+++ /dev/null
diff --git a/linux/handhelds-pxa-2.6/defconfig b/linux/handhelds-pxa-2.6/defconfig
deleted file mode 100644
index cd92420627..0000000000
--- a/linux/handhelds-pxa-2.6/defconfig
+++ /dev/null
@@ -1,1328 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-CONFIG_IKCONFIG=y
-# CONFIG_MINIMAL_OOPS is not set
-CONFIG_IKCONFIG_PROC=y
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_L7200 is not set
-CONFIG_ARCH_PXA=y
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE_PB is not set
-
-#
-# Intel PXA2xx Implementations
-#
-CONFIG_PXA25x=y
-# CONFIG_PXA27x is not set
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_MACH_MAINSTONE is not set
-# CONFIG_ARCH_PXA_IDP is not set
-CONFIG_ARCH_ESERIES=y
-CONFIG_MACH_E740=y
-CONFIG_MACH_E750=y
-CONFIG_MACH_E800=y
-CONFIG_ESERIES_TMIO=y
-CONFIG_OHCI_TMIO=y
-# CONFIG_MTD_NAND_TMIO is not set
-CONFIG_ESERIES_UDC=y
-# CONFIG_E740_PCMCIA is not set
-# CONFIG_E750_PCMCIA is not set
-# CONFIG_E800_PCMCIA is not set
-# CONFIG_MACH_A620 is not set
-# CONFIG_ARCH_H1900 is not set
-CONFIG_ARCH_H2200=y
-CONFIG_H2200_PCMCIA=m
-CONFIG_H2200_LCD=m
-CONFIG_H2200_TS=m
-CONFIG_ARCH_H3900=y
-CONFIG_MACH_H4000=y
-CONFIG_ARCH_H5400=y
-# CONFIG_MACH_HIMALAYA is not set
-# CONFIG_HIMALAYA_USB is not set
-# CONFIG_PXA_NSSP is not set
-# CONFIG_HIMALAYA_INPUT is not set
-# CONFIG_HIMALAYA_LEDS is not set
-# CONFIG_ARCH_AXIMX5 is not set
-# CONFIG_AXIMX5_MISC is not set
-# CONFIG_AXIMX5_LCD is not set
-# CONFIG_AXIMX5_PCMCIA is not set
-# CONFIG_AXIMX5_BUTTONS is not set
-# CONFIG_ARCH_AXIMX3 is not set
-# CONFIG_ARCH_ROVERP1 is not set
-# CONFIG_ARCH_ROVERP5P is not set
-
-#
-# Linux As Bootloader
-#
-# CONFIG_LAB is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_XSCALE=y
-CONFIG_CPU_XSCALE_PXA250=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
-
-#
-# Processor Features
-#
-# CONFIG_ARM_FASTCALL is not set
-CONFIG_ARM_THUMB=y
-CONFIG_XSCALE_PMU=y
-
-#
-# Compaq/iPAQ Options
-#
-CONFIG_PXA_IPAQ=y
-
-#
-# XScale-based iPAQ
-#
-CONFIG_IPAQ_HANDHELD=y
-CONFIG_IPAQ_SLEEVE=m
-CONFIG_IPAQ_ASIC2=m
-CONFIG_IPAQ_ASIC2_TOUCHSCREEN=m
-CONFIG_IPAQ_ASIC3=m
-CONFIG_IPAQ_H3900_LCD=m
-CONFIG_IPAQ_H4000_LCD=m
-CONFIG_IPAQ_SAMCOP=m
-CONFIG_IPAQ_SAMCOP_ADC=m
-CONFIG_IPAQ_SAMCOP_TOUCHSCREEN=m
-CONFIG_IPAQ_SHAMCOP=m
-CONFIG_IPAQ_SHAMCOP_ADC=m
-CONFIG_IPAQ_SHAMCOP_TOUCHSCREEN=m
-CONFIG_IPAQ_SHAMCOP_NAND=m
-CONFIG_IPAQ_H5400_LCD=m
-CONFIG_IPAQ_H5400_WIFI=m
-
-#
-# General setup
-#
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-# CONFIG_CPU_FREQ is not set
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=m
-# CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_TCIC is not set
-CONFIG_PCMCIA_PXA2XX=m
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-# CONFIG_VFP is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-CONFIG_SOC_DEVICE=m
-# CONFIG_DOCKING_HOTPLUG is not set
-# CONFIG_DEBUG_DRIVER is not set
-CONFIG_PM=y
-# CONFIG_PREEMPT is not set
-# CONFIG_APM is not set
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="keepinitrd"
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=1
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CONCAT=m
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_GEOMETRY=y
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_IPAQ=y
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_EDB7312 is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-CONFIG_MTD_NAND=m
-# CONFIG_MTD_NAND_VERIFY_WRITE is not set
-# CONFIG_MTD_NAND_H1900 is not set
-CONFIG_MTD_NAND_IDS=m
-# CONFIG_MTD_NAND_DISKONCHIP is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-# CONFIG_MMC_TOSHIBA is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_BLK_DEV_INITRD=y
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=m
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-CONFIG_IPV6=m
-# CONFIG_IPV6_PRIVACY is not set
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_TUNNEL=m
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_BRIDGE_NETFILTER=y
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_TFTP is not set
-# CONFIG_IP_NF_AMANDA is not set
-# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-# CONFIG_IP_NF_MATCH_IPRANGE is not set
-CONFIG_IP_NF_MATCH_MAC=m
-# CONFIG_IP_NF_MATCH_PKTTYPE is not set
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-# CONFIG_IP_NF_MATCH_RECENT is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
-# CONFIG_IP_NF_MATCH_DSCP is not set
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-# CONFIG_IP_NF_MATCH_HELPER is not set
-CONFIG_IP_NF_MATCH_STATE=m
-# CONFIG_IP_NF_MATCH_CONNTRACK is not set
-# CONFIG_IP_NF_MATCH_OWNER is not set
-# CONFIG_IP_NF_MATCH_PHYSDEV is not set
-CONFIG_IP_NF_FILTER=m
-# CONFIG_IP_NF_TARGET_REJECT is not set
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-# CONFIG_IP_NF_TARGET_NETMAP is not set
-# CONFIG_IP_NF_TARGET_SAME is not set
-# CONFIG_IP_NF_NAT_LOCAL is not set
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-# CONFIG_IP_NF_TARGET_ECN is not set
-# CONFIG_IP_NF_TARGET_DSCP is not set
-CONFIG_IP_NF_TARGET_MARK=m
-# CONFIG_IP_NF_TARGET_CLASSIFY is not set
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-# CONFIG_IP_NF_RAW is not set
-# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
-# CONFIG_IP_NF_MATCH_REALM is not set
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-# CONFIG_IP6_NF_MATCH_RT is not set
-# CONFIG_IP6_NF_MATCH_OPTS is not set
-# CONFIG_IP6_NF_MATCH_FRAG is not set
-# CONFIG_IP6_NF_MATCH_HL is not set
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-# CONFIG_IP6_NF_MATCH_OWNER is not set
-CONFIG_IP6_NF_MATCH_MARK=m
-# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
-# CONFIG_IP6_NF_MATCH_AHESP is not set
-# CONFIG_IP6_NF_MATCH_LENGTH is not set
-# CONFIG_IP6_NF_MATCH_EUI64 is not set
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
-# CONFIG_IP6_NF_RAW is not set
-
-#
-# Bridge: Netfilter Configuration
-#
-# CONFIG_BRIDGE_NF_EBTABLES is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-CONFIG_BRIDGE=m
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-CONFIG_IRDA_ULTRA=y
-
-#
-# IrDA options
-#
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-CONFIG_IRDA_DEBUG=y
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=m
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# Old SIR device drivers
-#
-CONFIG_IRPORT_SIR=m
-
-#
-# Old Serial dongle support
-#
-# CONFIG_DONGLE_OLD is not set
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_SIGMATEL_FIR is not set
-CONFIG_BT=m
-# CONFIG_BT_L2CAP is not set
-# CONFIG_BT_SCO is not set
-
-#
-# Bluetooth device drivers
-#
-# CONFIG_BT_HCIUSB is not set
-# CONFIG_BT_HCIUART is not set
-# CONFIG_BT_HCIBCM203X is not set
-# CONFIG_BT_HCIBFUSB is not set
-# CONFIG_BT_HCIDTL1 is not set
-# CONFIG_BT_HCIBT3C is not set
-# CONFIG_BT_HCIBLUECARD is not set
-# CONFIG_BT_HCIBTUART is not set
-# CONFIG_BT_HCIVHCI is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-CONFIG_MII=m
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-CONFIG_PCMCIA_WAVELAN=m
-CONFIG_PCMCIA_NETWAVE=m
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-CONFIG_PCMCIA_RAYCS=m
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-CONFIG_HERMES=m
-# CONFIG_ATMEL is not set
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-CONFIG_PCMCIA_HERMES=m
-CONFIG_AIRO_CS=m
-# CONFIG_PCMCIA_WL3501 is not set
-CONFIG_NET_WIRELESS=y
-# CONFIG_HOSTAP is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-CONFIG_PCMCIA_AXNET=m
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=m
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECS=m
-CONFIG_BLK_DEV_IDECD=m
-CONFIG_BLK_DEV_IDETAPE=m
-CONFIG_BLK_DEV_IDEFLOPPY=m
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_IDE_TASKFILE_IO is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=m
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=m
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_CHR_DEV_SG=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI Transport Attributes
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# PCMCIA SCSI adapter support
-#
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-# CONFIG_PCMCIA_SYM53C500 is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-CONFIG_INPUT_TSDEV=m
-CONFIG_INPUT_TSDEV_SCREEN_X=240
-CONFIG_INPUT_TSDEV_SCREEN_Y=320
-CONFIG_INPUT_TSLIBDEV=m
-CONFIG_INPUT_EVDEV=m
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=m
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_CT82C710 is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-# CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-CONFIG_KEYBOARD_NEWTON=m
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_DZ is not set
-CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# I2C support
-#
-CONFIG_I2C=m
-CONFIG_I2C_CHARDEV=m
-
-#
-# I2C Algorithms
-#
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPXA is not set
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_ELV is not set
-# CONFIG_I2C_ISA is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PXA is not set
-# CONFIG_SCx200_ACB is not set
-
-#
-# Hardware Sensors Chip support
-#
-# CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-
-#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# L3 serial bus support
-#
-CONFIG_L3=m
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_SA1100_WATCHDOG is not set
-
-#
-# USB-based Watchdog Cards
-#
-# CONFIG_USBPCWATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-# CONFIG_SYNCLINK_CS is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# Multimedia devices
-#
-CONFIG_VIDEO_DEV=m
-
-#
-# Video For Linux
-#
-
-#
-# Video Adapters
-#
-CONFIG_VIDEO_CPIA=m
-# CONFIG_VIDEO_CPIA_USB is not set
-# CONFIG_VIDEO_SAA5246A is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_OVCAMCHIP is not set
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_MAESTRO is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-CONFIG_EXT3_FS=m
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_REISERFS_FS_XATTR is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=m
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=m
-
-#
-# CD-ROM/DVD Filesystems
-#
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-# CONFIG_ZISOFS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-CONFIG_TMPFS=y
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_NAND=y
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
-CONFIG_CRAMFS=m
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V4 is not set
-# CONFIG_NFSD_TCP is not set
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_SUNRPC=m
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-
-#
-# Native Language Support
-#
-CONFIG_NLS=m
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-# CONFIG_NLS_ASCII is not set
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Graphics support
-#
-CONFIG_FB=y
-CONFIG_FB_MODES=y
-CONFIG_LCD_CLASS_DEVICE=m
-CONFIG_LCD_DEVICE=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=m
-CONFIG_BACKLIGHT_DEVICE=y
-# CONFIG_FB_VSFB is not set
-CONFIG_FB_MQ1100=m
-CONFIG_FB_PXA=m
-# CONFIG_FB_PXA_PARAMETERS is not set
-# CONFIG_FB_PXA_8BPP is not set
-CONFIG_FB_PXA_16BPP=y
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_MDA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=m
-CONFIG_FONTS=y
-# CONFIG_FONT_8x8 is not set
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-CONFIG_FONT_MINI_4x6=y
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-
-#
-# Logo configuration
-#
-# CONFIG_LOGO is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# Misc devices
-#
-
-#
-# SoC drivers
-#
-CONFIG_SOC_MQ11XX=m
-# CONFIG_BATTERY_MONITOR is not set
-
-#
-# USB support
-#
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_EHCI_HCD is not set
-CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_UHCI_HCD is not set
-# CONFIG_USB_SL811HS is not set
-# CONFIG_USB_SL811HS_ALT is not set
-
-#
-# USB Device Class drivers
-#
-
-#
-# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
-#
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_STORAGE is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-# CONFIG_USB_HID is not set
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_EGALAX is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_VICAM is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_KONICAWC is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_PWC is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_SN9C102 is not set
-# CONFIG_USB_STV680 is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_TIGL is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETSERVO is not set
-# CONFIG_USB_TEST is not set
-
-#
-# USB Gadget Support
-#
-CONFIG_USB_GADGET=y
-# CONFIG_USB_GADGET_NET2280 is not set
-CONFIG_USB_GADGET_PXA2XX=y
-CONFIG_USB_PXA2XX=y
-CONFIG_USB_PXA2XX_SMALL=y
-# CONFIG_USB_GADGET_GOKU is not set
-# CONFIG_USB_GADGET_SA1100 is not set
-# CONFIG_USB_GADGET_MQ11XX is not set
-# CONFIG_USB_GADGET_DUMMY_HCD is not set
-# CONFIG_USB_GADGET_DUALSPEED is not set
-CONFIG_USB_ZERO=m
-CONFIG_USB_ETH=m
-# CONFIG_USB_ETH_RNDIS is not set
-# CONFIG_USB_GADGETFS is not set
-CONFIG_USB_FILE_STORAGE=m
-# CONFIG_USB_FILE_STORAGE_TEST is not set
-# CONFIG_USB_G_SERIAL is not set
-# CONFIG_USB_G_CHAR is not set
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_INFO is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_LL_PXA_JTAG is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_LL is not set
-
-#
-# 1-Wire subsystem
-#
-# CONFIG_ONEWIRE is not set
-
-#
-# Security options
-#
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-# CONFIG_CRYPTO_TEA is not set
-CONFIG_CRYPTO_ARC4=m
-# CONFIG_CRYPTO_KHAZAD is not set
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Library routines
-#
-CONFIG_CRC_CCITT=m
-CONFIG_CRC32=m
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/handhelds-pxa-2.6/defconfig-ipaq-pxa-2.6 b/linux/handhelds-pxa-2.6/defconfig-ipaq-pxa-2.6
deleted file mode 100644
index 0a7d4a6694..0000000000
--- a/linux/handhelds-pxa-2.6/defconfig-ipaq-pxa-2.6
+++ /dev/null
@@ -1,1304 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_STANDALONE=y
-CONFIG_BROKEN=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-CONFIG_IKCONFIG=y
-# CONFIG_MINIMAL_OOPS is not set
-CONFIG_IKCONFIG_PROC=y
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_ADIFCC is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-CONFIG_ARCH_PXA=y
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_VERSATILE_PB is not set
-
-#
-# Intel PXA250/210 Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_ARCH_PXA_IDP is not set
-# CONFIG_ARCH_H1900 is not set
-CONFIG_ARCH_H2200=y
-CONFIG_H2200_PCMCIA=m
-CONFIG_H2200_LCD=m
-# CONFIG_H2200_BATTERY is not set
-CONFIG_H2200_TS=m
-CONFIG_ARCH_H3900=y
-CONFIG_MACH_H4000=y
-CONFIG_ARCH_H5400=y
-CONFIG_ARCH_AXIMX5=y
-# CONFIG_AXIMX5_MISC is not set
-# CONFIG_AXIMX5_LCD is not set
-# CONFIG_AXIMX5_PCMCIA is not set
-# CONFIG_AXIMX5_BUTTONS is not set
-# CONFIG_ARCH_AXIMX3 is not set
-CONFIG_MACH_E740=y
-CONFIG_MACH_E750=y
-CONFIG_MACH_E800=y
-CONFIG_ARCH_ESERIES=y
-# CONFIG_ARCH_ROVERP5P is not set
-
-#
-# S3C2410 Implementations
-#
-
-#
-# Linux As Bootloader
-#
-# CONFIG_LAB is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_XSCALE=y
-CONFIG_CPU_XSCALE_PXA250=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
-
-#
-# Processor Features
-#
-# CONFIG_ARM_FASTCALL is not set
-CONFIG_ARM_THUMB=y
-CONFIG_XSCALE_PMU=y
-
-#
-# Compaq/iPAQ Options
-#
-CONFIG_PXA_IPAQ=y
-
-#
-# XScale-based iPAQ
-#
-CONFIG_IPAQ_HANDHELD=y
-CONFIG_IPAQ_SLEEVE=m
-CONFIG_IPAQ_ASIC2=m
-CONFIG_IPAQ_ASIC2_TOUCHSCREEN=m
-CONFIG_IPAQ_ASIC3=m
-CONFIG_IPAQ_H3900_LCD=m
-CONFIG_IPAQ_H4000_LCD=m
-CONFIG_IPAQ_SAMCOP=m
-CONFIG_IPAQ_SAMCOP_ADC=m
-CONFIG_IPAQ_SAMCOP_TOUCHSCREEN=m
-CONFIG_IPAQ_SHAMCOP=m
-CONFIG_IPAQ_SHAMCOP_ADC=m
-CONFIG_IPAQ_SHAMCOP_TOUCHSCREEN=m
-CONFIG_IPAQ_SHAMCOP_NAND=m
-CONFIG_IPAQ_H5400_LCD=m
-CONFIG_IPAQ_H5400_WIFI=m
-
-#
-# General setup
-#
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-# CONFIG_CPU_FREQ is not set
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=m
-# CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_TCIC is not set
-CONFIG_PCMCIA_PXA2XX=m
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Generic Driver Options
-#
-# CONFIG_FW_LOADER is not set
-CONFIG_SOC_DEVICE=m
-# CONFIG_DOCKING_HOTPLUG is not set
-# CONFIG_DEBUG_DRIVER is not set
-CONFIG_PM=y
-# CONFIG_PREEMPT is not set
-# CONFIG_APM is not set
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="keepinitrd"
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=1
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CONCAT=m
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_GEOMETRY=y
-# CONFIG_MTD_CFI_B1 is not set
-CONFIG_MTD_CFI_B2=y
-CONFIG_MTD_CFI_B4=y
-# CONFIG_MTD_CFI_B8 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_IPAQ=y
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_EDB7312 is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-CONFIG_MTD_NAND=m
-# CONFIG_MTD_NAND_VERIFY_WRITE is not set
-# CONFIG_MTD_NAND_H1900 is not set
-CONFIG_MTD_NAND_IDS=m
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_BLK_DEV_INITRD=y
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=m
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-CONFIG_IPV6=m
-# CONFIG_IPV6_PRIVACY is not set
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_TUNNEL=m
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_BRIDGE_NETFILTER=y
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_TFTP is not set
-# CONFIG_IP_NF_AMANDA is not set
-# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-# CONFIG_IP_NF_MATCH_IPRANGE is not set
-CONFIG_IP_NF_MATCH_MAC=m
-# CONFIG_IP_NF_MATCH_PKTTYPE is not set
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-# CONFIG_IP_NF_MATCH_RECENT is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
-# CONFIG_IP_NF_MATCH_DSCP is not set
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-# CONFIG_IP_NF_MATCH_HELPER is not set
-CONFIG_IP_NF_MATCH_STATE=m
-# CONFIG_IP_NF_MATCH_CONNTRACK is not set
-# CONFIG_IP_NF_MATCH_OWNER is not set
-# CONFIG_IP_NF_MATCH_PHYSDEV is not set
-CONFIG_IP_NF_FILTER=m
-# CONFIG_IP_NF_TARGET_REJECT is not set
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-# CONFIG_IP_NF_TARGET_NETMAP is not set
-# CONFIG_IP_NF_TARGET_SAME is not set
-# CONFIG_IP_NF_NAT_LOCAL is not set
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-# CONFIG_IP_NF_TARGET_ECN is not set
-# CONFIG_IP_NF_TARGET_DSCP is not set
-CONFIG_IP_NF_TARGET_MARK=m
-# CONFIG_IP_NF_TARGET_CLASSIFY is not set
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-# CONFIG_IP_NF_RAW is not set
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-# CONFIG_IP6_NF_MATCH_RT is not set
-# CONFIG_IP6_NF_MATCH_OPTS is not set
-# CONFIG_IP6_NF_MATCH_FRAG is not set
-# CONFIG_IP6_NF_MATCH_HL is not set
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-# CONFIG_IP6_NF_MATCH_OWNER is not set
-CONFIG_IP6_NF_MATCH_MARK=m
-# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
-# CONFIG_IP6_NF_MATCH_AHESP is not set
-# CONFIG_IP6_NF_MATCH_LENGTH is not set
-# CONFIG_IP6_NF_MATCH_EUI64 is not set
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
-# CONFIG_IP6_NF_RAW is not set
-
-#
-# Bridge: Netfilter Configuration
-#
-# CONFIG_BRIDGE_NF_EBTABLES is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-CONFIG_BRIDGE=m
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-CONFIG_IRDA_ULTRA=y
-
-#
-# IrDA options
-#
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-CONFIG_IRDA_DEBUG=y
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=m
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# Old SIR device drivers
-#
-CONFIG_IRPORT_SIR=m
-
-#
-# Old Serial dongle support
-#
-# CONFIG_DONGLE_OLD is not set
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_SIGMATEL_FIR is not set
-# CONFIG_TOSHIBA_FIR is not set
-CONFIG_BT=m
-# CONFIG_BT_L2CAP is not set
-# CONFIG_BT_SCO is not set
-
-#
-# Bluetooth device drivers
-#
-# CONFIG_BT_HCIUSB is not set
-# CONFIG_BT_HCIUART is not set
-# CONFIG_BT_HCIBCM203X is not set
-# CONFIG_BT_HCIBFUSB is not set
-# CONFIG_BT_HCIDTL1 is not set
-# CONFIG_BT_HCIBT3C is not set
-# CONFIG_BT_HCIBLUECARD is not set
-# CONFIG_BT_HCIBTUART is not set
-# CONFIG_BT_HCIVHCI is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-CONFIG_MII=m
-# CONFIG_SMC91X is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-CONFIG_PCMCIA_WAVELAN=m
-CONFIG_PCMCIA_NETWAVE=m
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-CONFIG_PCMCIA_RAYCS=m
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-CONFIG_HERMES=m
-# CONFIG_ATMEL is not set
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-CONFIG_PCMCIA_HERMES=m
-CONFIG_AIRO_CS=m
-# CONFIG_PCMCIA_WL3501 is not set
-CONFIG_NET_WIRELESS=y
-# CONFIG_HOSTAP is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-CONFIG_PCMCIA_AXNET=m
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-CONFIG_BLK_DEV_IDEDISK=m
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_IDEDISK_STROKE is not set
-CONFIG_BLK_DEV_IDECS=m
-CONFIG_BLK_DEV_IDECD=m
-CONFIG_BLK_DEV_IDETAPE=m
-CONFIG_BLK_DEV_IDEFLOPPY=m
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_IDE_TASKFILE_IO is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=m
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=m
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_CHR_DEV_SG=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_REPORT_LUNS=y
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI Transport Attributes
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# PCMCIA SCSI adapter support
-#
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-CONFIG_INPUT_TSDEV=m
-CONFIG_INPUT_TSDEV_SCREEN_X=240
-CONFIG_INPUT_TSDEV_SCREEN_Y=320
-CONFIG_INPUT_TSLIBDEV=m
-CONFIG_INPUT_EVDEV=m
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=m
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_CT82C710 is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-# CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-CONFIG_KEYBOARD_NEWTON=m
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_DZ is not set
-CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_PXA_JTAG is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# I2C support
-#
-CONFIG_I2C=m
-CONFIG_I2C_CHARDEV=m
-
-#
-# I2C Algorithms
-#
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPXA is not set
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_ELV is not set
-# CONFIG_I2C_ISA is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PXA is not set
-# CONFIG_SCx200_ACB is not set
-
-#
-# Hardware Sensors Chip support
-#
-# CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-
-#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# L3 serial bus support
-#
-CONFIG_L3=m
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-
-#
-# USB-based Watchdog Cards
-#
-# CONFIG_USBPCWATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-# CONFIG_SYNCLINK_CS is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# Multimedia devices
-#
-CONFIG_VIDEO_DEV=m
-
-#
-# Video For Linux
-#
-
-#
-# Video Adapters
-#
-CONFIG_VIDEO_CPIA=m
-# CONFIG_VIDEO_CPIA_USB is not set
-# CONFIG_VIDEO_SAA5246A is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_MAESTRO is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-CONFIG_EXT3_FS=m
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=m
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=m
-
-#
-# CD-ROM/DVD Filesystems
-#
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-# CONFIG_ZISOFS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-CONFIG_TMPFS=y
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=m
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_NAND=y
-CONFIG_CRAMFS=m
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V4 is not set
-# CONFIG_NFSD_TCP is not set
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_SUNRPC=m
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-
-#
-# Native Language Support
-#
-CONFIG_NLS=m
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Graphics support
-#
-CONFIG_FB=y
-CONFIG_FB_MODES=y
-CONFIG_LCD_CLASS_DEVICE=m
-CONFIG_LCD_DEVICE=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=m
-CONFIG_BACKLIGHT_DEVICE=y
-# CONFIG_FB_VSFB is not set
-CONFIG_FB_MQ1100=m
-CONFIG_FB_PXA=m
-# CONFIG_FB_PXA_8BPP is not set
-CONFIG_FB_PXA_16BPP=y
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_MDA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=m
-CONFIG_PCI_CONSOLE=y
-CONFIG_FONTS=y
-# CONFIG_FONT_8x8 is not set
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-CONFIG_FONT_MINI_4x6=y
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-
-#
-# Logo configuration
-#
-# CONFIG_LOGO is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# Misc devices
-#
-
-#
-# Multimedia Capabilities Port drivers
-#
-# CONFIG_MCP is not set
-
-#
-# Console Switches
-#
-CONFIG_SWITCHES=m
-
-#
-# SoC drivers
-#
-CONFIG_SOC_MQ11XX=m
-# CONFIG_BATTERY_MONITOR is not set
-
-#
-# USB support
-#
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_EHCI_HCD is not set
-CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_UHCI_HCD is not set
-# CONFIG_USB_SL811HS is not set
-# CONFIG_USB_SL811HS_ALT is not set
-
-#
-# USB Device Class drivers
-#
-
-#
-# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
-#
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_STORAGE is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-# CONFIG_USB_HID is not set
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_VICAM is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_KONICAWC is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_PWC is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_STV680 is not set
-# CONFIG_USB_W9968CF is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_TIGL is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_TEST is not set
-
-#
-# USB Gadget Support
-#
-CONFIG_USB_GADGET=y
-
-#
-# USB Device Controller drivers
-#
-CONFIG_USB_GADGET_PXA2XX=m
-CONFIG_USB_PXA2XX=y
-CONFIG_USB_PXA2XX_SMALL=y
-CONFIG_USB_GADGET_MQ11XX=m
-CONFIG_USB_MQ11XX=y
-# CONFIG_USB_GADGET_DUMMY_HCD is not set
-# CONFIG_USB_GADGET_DUALSPEED is not set
-
-#
-# USB Gadget Drivers
-#
-CONFIG_USB_ZERO=m
-CONFIG_USB_ETH=m
-# CONFIG_USB_ETH_RNDIS is not set
-# CONFIG_USB_GADGETFS is not set
-CONFIG_USB_FILE_STORAGE=m
-# CONFIG_USB_FILE_STORAGE_TEST is not set
-# CONFIG_USB_G_SERIAL is not set
-# CONFIG_USB_G_CHAR is not set
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_INFO is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_LL_PXA_JTAG is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_LL is not set
-
-#
-# Security options
-#
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Library routines
-#
-CONFIG_CRC32=m
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/handhelds-pxa-2.6/defconfig-ipaq-pxa-2.6_2.6.8.1-hh0 b/linux/handhelds-pxa-2.6/defconfig-ipaq-pxa-2.6_2.6.8.1-hh0
deleted file mode 100644
index 8d03220347..0000000000
--- a/linux/handhelds-pxa-2.6/defconfig-ipaq-pxa-2.6_2.6.8.1-hh0
+++ /dev/null
@@ -1,1382 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_CLEAN_COMPILE is not set
-CONFIG_BROKEN=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-CONFIG_IKCONFIG=y
-# CONFIG_MINIMAL_OOPS is not set
-CONFIG_IKCONFIG_PROC=y
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_L7200 is not set
-CONFIG_ARCH_PXA=y
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE_PB is not set
-
-#
-# Intel PXA2xx Implementations
-#
-CONFIG_PXA25x=y
-# CONFIG_PXA27x is not set
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_MACH_MAINSTONE is not set
-# CONFIG_ARCH_PXA_IDP is not set
-CONFIG_ARCH_ESERIES=y
-CONFIG_MACH_E740=y
-CONFIG_MACH_E750=y
-CONFIG_MACH_E800=y
-CONFIG_ESERIES_TMIO=y
-CONFIG_OHCI_TMIO=y
-CONFIG_MTD_NAND_TMIO=y
-CONFIG_ESERIES_UDC=y
-# CONFIG_E740_PCMCIA is not set
-# CONFIG_E750_PCMCIA is not set
-# CONFIG_E800_PCMCIA is not set
-CONFIG_MACH_A620=y
-CONFIG_A620_LCD=m
-CONFIG_A620_BUTTONS=m
-CONFIG_ARCH_H1900=y
-CONFIG_ARCH_H2200=y
-CONFIG_H2200_PCMCIA=m
-CONFIG_H2200_LCD=m
-# CONFIG_H2200_BATTERY is not set
-CONFIG_H2200_TS=m
-CONFIG_H2200_AUDIO=m
-CONFIG_ARCH_H3900=y
-CONFIG_MACH_H4000=y
-CONFIG_ARCH_H5400=y
-# CONFIG_ARCH_AXIMX5 is not set
-# CONFIG_ARCH_AXIMX3 is not set
-CONFIG_ARCH_ROVERP1=y
-CONFIG_ARCH_ROVERP5P=y
-CONFIG_ROVERP5P_LCD=m
-CONFIG_ROVERP5P_PCMCIA=m
-
-#
-# Linux As Bootloader
-#
-# CONFIG_LAB is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_XSCALE=y
-CONFIG_CPU_XSCALE_PXA250=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
-
-#
-# Processor Features
-#
-# CONFIG_ARM_FASTCALL is not set
-CONFIG_ARM_THUMB=y
-CONFIG_XSCALE_PMU=y
-
-#
-# Compaq/iPAQ Options
-#
-CONFIG_PXA_IPAQ=y
-
-#
-# XScale-based iPAQ
-#
-CONFIG_IPAQ_HANDHELD=y
-# CONFIG_IPAQ_SLEEVE is not set
-CONFIG_IPAQ_ASIC2=m
-CONFIG_IPAQ_ASIC2_TOUCHSCREEN=m
-CONFIG_IPAQ_ASIC3=m
-# CONFIG_IPAQ_H1900_LCD is not set
-# CONFIG_IPAQ_H3900_LCD is not set
-CONFIG_IPAQ_H4000_LCD=m
-CONFIG_IPAQ_SAMCOP=m
-CONFIG_IPAQ_SAMCOP_ADC=m
-CONFIG_IPAQ_SAMCOP_TOUCHSCREEN=m
-CONFIG_IPAQ_SHAMCOP=m
-CONFIG_IPAQ_SHAMCOP_ADC=m
-CONFIG_IPAQ_SHAMCOP_TOUCHSCREEN=m
-CONFIG_IPAQ_SHAMCOP_NAND=m
-CONFIG_IPAQ_H5400_LCD=m
-CONFIG_IPAQ_H5400_WIFI=m
-
-#
-# General setup
-#
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-# CONFIG_CPU_FREQ is not set
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=m
-# CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_TCIC is not set
-CONFIG_PCMCIA_PXA2XX=m
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-# CONFIG_VFP is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
-CONFIG_SOC_DEVICE=m
-# CONFIG_DOCKING_HOTPLUG is not set
-# CONFIG_DEBUG_DRIVER is not set
-CONFIG_PM=y
-# CONFIG_PREEMPT is not set
-# CONFIG_APM is not set
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="keepinitrd"
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=1
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CONCAT=m
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_GEOMETRY=y
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_IPAQ=y
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_EDB7312 is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-CONFIG_MTD_NAND=m
-# CONFIG_MTD_NAND_VERIFY_WRITE is not set
-# CONFIG_MTD_NAND_H1900 is not set
-CONFIG_MTD_NAND_IDS=m
-# CONFIG_MTD_NAND_DISKONCHIP is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_BLK_DEV_INITRD=y
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=m
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-CONFIG_IPV6=m
-# CONFIG_IPV6_PRIVACY is not set
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_TUNNEL=m
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_BRIDGE_NETFILTER=y
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_TFTP is not set
-# CONFIG_IP_NF_AMANDA is not set
-# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-# CONFIG_IP_NF_MATCH_IPRANGE is not set
-CONFIG_IP_NF_MATCH_MAC=m
-# CONFIG_IP_NF_MATCH_PKTTYPE is not set
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-# CONFIG_IP_NF_MATCH_RECENT is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
-# CONFIG_IP_NF_MATCH_DSCP is not set
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-# CONFIG_IP_NF_MATCH_HELPER is not set
-CONFIG_IP_NF_MATCH_STATE=m
-# CONFIG_IP_NF_MATCH_CONNTRACK is not set
-# CONFIG_IP_NF_MATCH_OWNER is not set
-# CONFIG_IP_NF_MATCH_PHYSDEV is not set
-CONFIG_IP_NF_FILTER=m
-# CONFIG_IP_NF_TARGET_REJECT is not set
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-# CONFIG_IP_NF_TARGET_NETMAP is not set
-# CONFIG_IP_NF_TARGET_SAME is not set
-# CONFIG_IP_NF_NAT_LOCAL is not set
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-# CONFIG_IP_NF_TARGET_ECN is not set
-# CONFIG_IP_NF_TARGET_DSCP is not set
-CONFIG_IP_NF_TARGET_MARK=m
-# CONFIG_IP_NF_TARGET_CLASSIFY is not set
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-# CONFIG_IP_NF_RAW is not set
-# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
-# CONFIG_IP_NF_MATCH_REALM is not set
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-# CONFIG_IP6_NF_MATCH_RT is not set
-# CONFIG_IP6_NF_MATCH_OPTS is not set
-# CONFIG_IP6_NF_MATCH_FRAG is not set
-# CONFIG_IP6_NF_MATCH_HL is not set
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-# CONFIG_IP6_NF_MATCH_OWNER is not set
-CONFIG_IP6_NF_MATCH_MARK=m
-# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
-# CONFIG_IP6_NF_MATCH_AHESP is not set
-# CONFIG_IP6_NF_MATCH_LENGTH is not set
-# CONFIG_IP6_NF_MATCH_EUI64 is not set
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
-# CONFIG_IP6_NF_RAW is not set
-
-#
-# Bridge: Netfilter Configuration
-#
-# CONFIG_BRIDGE_NF_EBTABLES is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-CONFIG_BRIDGE=m
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-CONFIG_IRDA_ULTRA=y
-
-#
-# IrDA options
-#
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-CONFIG_IRDA_DEBUG=y
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=m
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# Old SIR device drivers
-#
-CONFIG_IRPORT_SIR=m
-
-#
-# Old Serial dongle support
-#
-# CONFIG_DONGLE_OLD is not set
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_SIGMATEL_FIR is not set
-CONFIG_BT=m
-# CONFIG_BT_L2CAP is not set
-# CONFIG_BT_SCO is not set
-
-#
-# Bluetooth device drivers
-#
-# CONFIG_BT_HCIUSB is not set
-# CONFIG_BT_HCIUART is not set
-# CONFIG_BT_HCIBCM203X is not set
-# CONFIG_BT_HCIBFUSB is not set
-# CONFIG_BT_HCIDTL1 is not set
-# CONFIG_BT_HCIBT3C is not set
-# CONFIG_BT_HCIBLUECARD is not set
-# CONFIG_BT_HCIBTUART is not set
-# CONFIG_BT_HCIVHCI is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-CONFIG_MII=m
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-CONFIG_PCMCIA_WAVELAN=m
-CONFIG_PCMCIA_NETWAVE=m
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-CONFIG_PCMCIA_RAYCS=m
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-CONFIG_HERMES=m
-# CONFIG_ATMEL is not set
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-CONFIG_PCMCIA_HERMES=m
-CONFIG_AIRO_CS=m
-# CONFIG_PCMCIA_WL3501 is not set
-CONFIG_NET_WIRELESS=y
-# CONFIG_HOSTAP is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-CONFIG_PCMCIA_AXNET=m
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=m
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECS=m
-CONFIG_BLK_DEV_IDECD=m
-CONFIG_BLK_DEV_IDETAPE=m
-CONFIG_BLK_DEV_IDEFLOPPY=m
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_IDE_TASKFILE_IO is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=m
-# CONFIG_IDE_ARM is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=m
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_CHR_DEV_SG=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI Transport Attributes
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# PCMCIA SCSI adapter support
-#
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-# CONFIG_PCMCIA_SYM53C500 is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-CONFIG_INPUT_TSDEV=m
-CONFIG_INPUT_TSDEV_SCREEN_X=240
-CONFIG_INPUT_TSDEV_SCREEN_Y=320
-CONFIG_INPUT_TSLIBDEV=m
-CONFIG_INPUT_EVDEV=m
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=m
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_CT82C710 is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-# CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-CONFIG_KEYBOARD_NEWTON=m
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_DZ is not set
-CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# I2C support
-#
-CONFIG_I2C=m
-CONFIG_I2C_CHARDEV=m
-
-#
-# I2C Algorithms
-#
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-CONFIG_I2C_ALGOPXA=m
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_ELV is not set
-# CONFIG_I2C_ISA is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-CONFIG_I2C_PXA=m
-# CONFIG_SCx200_ACB is not set
-
-#
-# Hardware Sensors Chip support
-#
-# CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-
-#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-CONFIG_I2C_DEBUG_CORE=y
-CONFIG_I2C_DEBUG_ALGO=y
-CONFIG_I2C_DEBUG_BUS=y
-CONFIG_I2C_DEBUG_CHIP=y
-
-#
-# L3 serial bus support
-#
-CONFIG_L3=m
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_SA1100_WATCHDOG is not set
-
-#
-# USB-based Watchdog Cards
-#
-# CONFIG_USBPCWATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-# CONFIG_SYNCLINK_CS is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# Multimedia devices
-#
-CONFIG_VIDEO_DEV=m
-
-#
-# Video For Linux
-#
-
-#
-# Video Adapters
-#
-CONFIG_VIDEO_CPIA=m
-# CONFIG_VIDEO_CPIA_USB is not set
-# CONFIG_VIDEO_SAA5246A is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_OVCAMCHIP is not set
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_MAESTRO is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-CONFIG_EXT3_FS=m
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_REISERFS_FS_XATTR is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=m
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=m
-
-#
-# CD-ROM/DVD Filesystems
-#
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-# CONFIG_ZISOFS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-CONFIG_TMPFS=y
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=m
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_NAND=y
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
-CONFIG_CRAMFS=m
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V4 is not set
-# CONFIG_NFSD_TCP is not set
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_EXPORTFS=m
-CONFIG_SUNRPC=m
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-
-#
-# Native Language Support
-#
-CONFIG_NLS=m
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-# CONFIG_NLS_ASCII is not set
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Graphics support
-#
-CONFIG_FB=y
-CONFIG_FB_MODES=y
-CONFIG_LCD_CLASS_DEVICE=m
-CONFIG_LCD_DEVICE=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=m
-CONFIG_BACKLIGHT_DEVICE=y
-# CONFIG_FB_VSFB is not set
-CONFIG_FB_MQ1100=m
-CONFIG_FB_PXA=m
-# CONFIG_FB_PXA_PARAMETERS is not set
-# CONFIG_FB_PXA_8BPP is not set
-CONFIG_FB_PXA_16BPP=y
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_MDA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=m
-CONFIG_FONTS=y
-# CONFIG_FONT_8x8 is not set
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-CONFIG_FONT_MINI_4x6=y
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-
-#
-# Logo configuration
-#
-# CONFIG_LOGO is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=m
-
-#
-# Advanced Linux Sound Architecture
-#
-CONFIG_SND=m
-CONFIG_SND_TIMER=m
-CONFIG_SND_PCM=m
-# CONFIG_SND_SEQUENCER is not set
-CONFIG_SND_OSSEMUL=y
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-CONFIG_SND_VERBOSE_PRINTK=y
-CONFIG_SND_DEBUG=y
-CONFIG_SND_DEBUG_MEMORY=y
-CONFIG_SND_DEBUG_DETECT=y
-
-#
-# Generic devices
-#
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-
-#
-# ALSA ARM devices
-#
-CONFIG_SND_PXA2XX_UDA1380=m
-# CONFIG_SND_H5XXX_AK4535 is not set
-# CONFIG_SND_PXA_AC97 is not set
-
-#
-# ALSA USB devices
-#
-# CONFIG_SND_USB_AUDIO is not set
-
-#
-# PCMCIA devices
-#
-
-#
-# Open Sound System
-#
-# CONFIG_SOUND_PRIME is not set
-# CONFIG_SOUND_UDA1341 is not set
-
-#
-# Misc devices
-#
-
-#
-# SoC drivers
-#
-CONFIG_SOC_MQ11XX=m
-# CONFIG_BATTERY_MONITOR is not set
-
-#
-# USB support
-#
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_EHCI_HCD is not set
-CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_UHCI_HCD is not set
-# CONFIG_USB_SL811HS is not set
-# CONFIG_USB_SL811HS_ALT is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_AUDIO is not set
-
-#
-# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
-#
-# CONFIG_USB_MIDI is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_STORAGE is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-# CONFIG_USB_HID is not set
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_EGALAX is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_VICAM is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_KONICAWC is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_PWC is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_SN9C102 is not set
-# CONFIG_USB_STV680 is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_TIGL is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETSERVO is not set
-# CONFIG_USB_TEST is not set
-
-#
-# USB Gadget Support
-#
-CONFIG_USB_GADGET=m
-# CONFIG_USB_GADGET_NET2280 is not set
-CONFIG_USB_GADGET_PXA2XX=y
-CONFIG_USB_PXA2XX=m
-# CONFIG_USB_PXA2XX_SMALL is not set
-# CONFIG_USB_GADGET_GOKU is not set
-# CONFIG_USB_GADGET_SA1100 is not set
-# CONFIG_USB_GADGET_MQ11XX is not set
-# CONFIG_USB_GADGET_DUMMY_HCD is not set
-# CONFIG_USB_GADGET_DUALSPEED is not set
-CONFIG_USB_ZERO=m
-CONFIG_USB_ETH=m
-# CONFIG_USB_ETH_RNDIS is not set
-# CONFIG_USB_GADGETFS is not set
-CONFIG_USB_FILE_STORAGE=m
-# CONFIG_USB_FILE_STORAGE_TEST is not set
-# CONFIG_USB_G_SERIAL is not set
-# CONFIG_USB_G_CHAR is not set
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_INFO is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_LL_PXA_JTAG is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_LL is not set
-
-#
-# Security options
-#
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-# CONFIG_CRYPTO_TEA is not set
-CONFIG_CRYPTO_ARC4=m
-# CONFIG_CRYPTO_KHAZAD is not set
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Library routines
-#
-CONFIG_CRC_CCITT=m
-CONFIG_CRC32=m
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/handhelds-pxa-2.6_2.6.6-hh0.bb b/linux/handhelds-pxa-2.6_2.6.6-hh0.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/handhelds-pxa-2.6_2.6.6-hh0.bb
+++ /dev/null
diff --git a/linux/handhelds-pxa-2.6_2.6.8.1-hh0.bb b/linux/handhelds-pxa-2.6_2.6.8.1-hh0.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/handhelds-pxa-2.6_2.6.8.1-hh0.bb
+++ /dev/null
diff --git a/linux/handhelds-pxa-2.6_cvs.bb b/linux/handhelds-pxa-2.6_cvs.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/handhelds-pxa-2.6_cvs.bb
+++ /dev/null
diff --git a/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh36.12.bb b/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh36.12.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh36.12.bb
+++ /dev/null
diff --git a/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh36.13.bb b/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh36.13.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh36.13.bb
+++ /dev/null
diff --git a/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh36.14.bb b/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh36.14.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh36.14.bb
+++ /dev/null
diff --git a/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh37.1.bb b/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh37.1.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh37.1.bb
+++ /dev/null
diff --git a/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh37.4.bb b/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh37.4.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/handhelds-pxa_2.4.19-rmk6-pxa1-hh37.4.bb
+++ /dev/null
diff --git a/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh36.12/defconfig-ipaqsa b/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh36.12/defconfig-ipaqsa
deleted file mode 100644
index f144aa6c17..0000000000
--- a/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh36.12/defconfig-ipaqsa
+++ /dev/null
@@ -1,1505 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_OMAHA is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_MX1ADS is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_RISCSTATION is not set
-CONFIG_ARCH_SA1100=y
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_AT91RM9200DK is not set
-# CONFIG_MINIMAL_OOPS is not set
-
-#
-# Linux As Bootldr support
-#
-# CONFIG_LAB is not set
-# CONFIG_BIG_KERNEL is not set
-# CONFIG_USE_DATE_CODE is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-
-#
-# Archimedes/A5000 Implementations (select only ONE)
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ACCELENT is not set
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CEP is not set
-# CONFIG_SA1100_CERF is not set
-CONFIG_SA1100_H3100=y
-CONFIG_SA1100_H3600=y
-CONFIG_SA1100_H3800=y
-# CONFIG_SA1100_CONSUS is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_FRODO is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_HACKKIT is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_JORNADA56X is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_SIMPUTER is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-CONFIG_SA1100_USB=m
-CONFIG_SA1100_USB_NETLINK=m
-CONFIG_SA1100_USB_CHAR=m
-CONFIG_REGISTERS=m
-
-#
-# Intel PXA250/210 Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_ARCH_PXA_IDP is not set
-# CONFIG_ARCH_PXA_CERF is not set
-# CONFIG_ARCH_H3900 is not set
-# CONFIG_ARCH_H1900 is not set
-# CONFIG_ARCH_H5400 is not set
-# CONFIG_ARCH_H2200 is not set
-# CONFIG_ARCH_AXIM is not set
-# CONFIG_PXA_USB is not set
-# CONFIG_PXA_USB_NETLINK is not set
-# CONFIG_PXA_USB_CHAR is not set
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_FORTUNET is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM922T is not set
-# CONFIG_PLD is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_ARM1026 is not set
-# CONFIG_CPU_SA110 is not set
-CONFIG_CPU_SA1100=y
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
-CONFIG_SA1100_IPAQ=y
-# CONFIG_PXA_IPAQ is not set
-CONFIG_IPAQ_HANDHELD=y
-
-#
-# Compaq iPAQ Handheld
-#
-CONFIG_IPAQ_HAL=m
-CONFIG_H3600_MICRO=m
-CONFIG_IPAQ_HAS_ROSELLA=y
-CONFIG_H3600_ASIC=m
-CONFIG_H3900_ASIC_DEBUG=y
-# CONFIG_H5400_ASIC is not set
-# CONFIG_H1900_ASIC is not set
-# CONFIG_H1900_TS is not set
-CONFIG_H3600_HARDWARE=y
-CONFIG_IPAQ_SLEEVE=m
-CONFIG_SLEEVE_DEBUG=y
-CONFIG_SLEEVE_DEBUG_VERBOSE=0
-# CONFIG_SLEEVE_IRQ_DEMUX is not set
-
-#
-# Processor Features
-#
-CONFIG_DISCONTIGMEM=y
-
-#
-# General setup
-#
-# CONFIG_PCI is not set
-CONFIG_ISA=y
-# CONFIG_ISA_DMA is not set
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_CPU_FREQ=y
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=m
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_CLPS6700 is not set
-CONFIG_PCMCIA_SA1100=m
-# CONFIG_PCMCIA_PXA is not set
-CONFIG_MERCURY_BACKPAQ=m
-
-#
-# MMC/SD Card support
-#
-CONFIG_MMC=m
-CONFIG_MMC_DEBUG=y
-CONFIG_MMC_DEBUG_VERBOSE=0
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_PM=y
-CONFIG_APM=m
-CONFIG_HWTIMER=m
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="keepinitrd"
-# CONFIG_LEDS is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=1
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_GEOMETRY=y
-# CONFIG_MTD_CFI_B1 is not set
-CONFIG_MTD_CFI_B2=y
-CONFIG_MTD_CFI_B4=y
-# CONFIG_MTD_CFI_B8 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_IPAQ=y
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-# CONFIG_MTD_SA1100 is not set
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_LUBBOCK is not set
-# CONFIG_MTD_EPXA10DB is not set
-# CONFIG_MTD_FORTUNET is not set
-# CONFIG_MTD_AUTCPU12 is not set
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_H720X is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_CEIVA is not set
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PCMCIA is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-CONFIG_MTD_MTDRAM=m
-CONFIG_MTDRAM_TOTAL_SIZE=4096
-CONFIG_MTDRAM_ERASE_SIZE=128
-CONFIG_MTD_BLKMTD=m
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_NVRD=m
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-CONFIG_BLK_DEV_LVM=m
-CONFIG_BLK_DEV_DM=m
-
-#
-# Networking options
-#
-CONFIG_PACKET=m
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-# CONFIG_IP_NF_AMANDA is not set
-# CONFIG_IP_NF_TFTP is not set
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_MAC=m
-# CONFIG_IP_NF_MATCH_PKTTYPE is not set
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-# CONFIG_IP_NF_MATCH_RECENT is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
-# CONFIG_IP_NF_MATCH_DSCP is not set
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-# CONFIG_IP_NF_MATCH_HELPER is not set
-CONFIG_IP_NF_MATCH_STATE=m
-# CONFIG_IP_NF_MATCH_CONNTRACK is not set
-# CONFIG_IP_NF_MATCH_UNCLEAN is not set
-# CONFIG_IP_NF_MATCH_OWNER is not set
-CONFIG_IP_NF_FILTER=m
-# CONFIG_IP_NF_TARGET_REJECT is not set
-# CONFIG_IP_NF_TARGET_MIRROR is not set
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-# CONFIG_IP_NF_TARGET_ECN is not set
-# CONFIG_IP_NF_TARGET_DSCP is not set
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_NAT_NEEDED=y
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-CONFIG_IPV6=m
-CONFIG_IPV6_SUBTREES=y
-CONFIG_IPV6_IPV6_TUNNEL=m
-CONFIG_IPV6_MOBILITY=m
-CONFIG_IPV6_MOBILITY_MN=m
-# CONFIG_IPV6_MOBILITY_HA is not set
-CONFIG_IPV6_MOBILITY_DEBUG=y
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-# CONFIG_IP6_NF_MATCH_RT is not set
-# CONFIG_IP6_NF_MATCH_OPTS is not set
-# CONFIG_IP6_NF_MATCH_FRAG is not set
-# CONFIG_IP6_NF_MATCH_HL is not set
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-# CONFIG_IP6_NF_MATCH_OWNER is not set
-CONFIG_IP6_NF_MATCH_MARK=m
-# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
-# CONFIG_IP6_NF_MATCH_AHESP is not set
-# CONFIG_IP6_NF_MATCH_LENGTH is not set
-# CONFIG_IP6_NF_MATCH_EUI64 is not set
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-
-#
-#
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_DEV_APPLETALK is not set
-# CONFIG_DECNET is not set
-CONFIG_BRIDGE=m
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_IPSEC=m
-
-#
-# IPSec options (FreeS/WAN)
-#
-CONFIG_IPSEC_IPIP=y
-CONFIG_IPSEC_AH=y
-CONFIG_IPSEC_AUTH_HMAC_MD5=y
-CONFIG_IPSEC_AUTH_HMAC_SHA1=y
-CONFIG_IPSEC_ESP=y
-CONFIG_IPSEC_ENC_3DES=y
-CONFIG_IPSEC_IPCOMP=y
-CONFIG_IPSEC_DEBUG=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-# CONFIG_PPP_MPPE is not set
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_STRIP is not set
-# CONFIG_WAVELAN is not set
-# CONFIG_ARLAN is not set
-# CONFIG_AIRONET4500 is not set
-# CONFIG_AIRONET4500_NONCS is not set
-# CONFIG_AIRONET4500_PROC is not set
-# CONFIG_HERMES is not set
-# CONFIG_SPECTRUM24T is not set
-
-#
-# Wireless Pcmcia cards support
-#
-# CONFIG_PCMCIA_HERMES is not set
-# CONFIG_AIRO_CS is not set
-# CONFIG_WVLAN_CS is not set
-# CONFIG_MWVLAN_CS is not set
-# CONFIG_HOSTAP is not set
-# CONFIG_HOSTAP_CS is not set
-CONFIG_NET_WIRELESS=y
-CONFIG_ATMELWLAN=y
-# CONFIG_ATMELWLAN_USB_503A_RFMD is not set
-CONFIG_ATMELWLAN_PCMCIA_502A=m
-CONFIG_ATMELWLAN_PCMCIA_3COM=m
-CONFIG_ATMELWLAN_PCMCIA_502AD=m
-CONFIG_ATMELWLAN_PCMCIA_502AE=m
-CONFIG_ATMELWLAN_PCMCIA_504=m
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_AXNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-# CONFIG_ARCNET_COM20020_CS is not set
-# CONFIG_PCMCIA_IBMTR is not set
-CONFIG_NET_PCMCIA_RADIO=y
-CONFIG_PCMCIA_RAYCS=m
-CONFIG_PCMCIA_NETWAVE=m
-CONFIG_PCMCIA_WAVELAN=m
-# CONFIG_AIRONET4500_CS is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-CONFIG_IRDA_ULTRA=y
-
-#
-# IrDA options
-#
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-CONFIG_IRDA_DEBUG=y
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=m
-CONFIG_IRPORT_SIR=m
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-CONFIG_SA1100_FIR=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=m
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=m
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_IDEDISK_STROKE is not set
-# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-# CONFIG_BLK_DEV_IDEDISK_WD is not set
-# CONFIG_BLK_DEV_COMMERIAL is not set
-# CONFIG_BLK_DEV_TIVO is not set
-CONFIG_BLK_DEV_IDECS=m
-CONFIG_BLK_DEV_IDECD=m
-CONFIG_BLK_DEV_IDETAPE=m
-CONFIG_BLK_DEV_IDEFLOPPY=m
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_DMA_NONPCI is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=m
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-CONFIG_SD_EXTRA_DEVS=40
-CONFIG_CHR_DEV_ST=m
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_SR_EXTRA_DEVS=2
-CONFIG_CHR_DEV_SG=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_DEBUG_QUEUES is not set
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_SIM710 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# PCMCIA SCSI adapter support
-#
-CONFIG_SCSI_PCMCIA=y
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-CONFIG_INPUT=m
-CONFIG_INPUT_KEYBDEV=m
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_JOYDEV=m
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_UINPUT=m
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=m
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_ANAKIN is not set
-# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-# CONFIG_SERIAL_S3C2410 is not set
-# CONFIG_SERIAL_S3C2410_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_UART00 is not set
-# CONFIG_SERIAL_UART00_CONSOLE is not set
-CONFIG_SERIAL_SA1100=y
-CONFIG_SERIAL_SA1100_CONSOLE=y
-CONFIG_SA1100_DEFAULT_BAUDRATE=115200
-CONFIG_SERIAL_H3800_ASIC=m
-# CONFIG_SERIAL_SIR_PXA is not set
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=32
-CONFIG_NEWTONKBD=m
-CONFIG_SA1100_PROFILER=m
-
-#
-# Compaq iPAQ H3600 support
-#
-CONFIG_TOUCHSCREEN_H3600=m
-CONFIG_H3600_BACKPAQ_FPGA=m
-CONFIG_H3600_BACKPAQ_ACCEL=m
-CONFIG_H3600_BACKPAQ_GASGAUGE=m
-CONFIG_H3600_BACKPAQ_SRAM=m
-CONFIG_H3600_BACKPAQ_AUDIO=m
-CONFIG_H3600_STOWAWAY=m
-CONFIG_H3800_MICROKBD=m
-CONFIG_SA1100_LIRC=m
-# CONFIG_H5400_BUZZER is not set
-# CONFIG_H5400_FSI is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# L3 serial bus support
-#
-CONFIG_L3=y
-CONFIG_L3_ALGOBIT=y
-CONFIG_L3_BIT_SA1100_GPIO=y
-
-#
-# Other L3 adapters
-#
-# CONFIG_L3_S3C2410 is not set
-# CONFIG_L3_SA1111 is not set
-CONFIG_L3_BACKPAQ=m
-CONFIG_BIT_SA1100_GPIO=y
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-CONFIG_MOUSE=m
-# CONFIG_PSMOUSE is not set
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-# CONFIG_MK712_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_INPUT_NS558 is not set
-# CONFIG_INPUT_LIGHTNING is not set
-# CONFIG_INPUT_PCIGAME is not set
-# CONFIG_INPUT_CS461X is not set
-# CONFIG_INPUT_EMU10K1 is not set
-CONFIG_INPUT_SERIO=m
-CONFIG_INPUT_SERPORT=m
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_ANALOG is not set
-# CONFIG_INPUT_A3D is not set
-# CONFIG_INPUT_ADI is not set
-# CONFIG_INPUT_COBRA is not set
-# CONFIG_INPUT_GF2K is not set
-# CONFIG_INPUT_GRIP is not set
-# CONFIG_INPUT_INTERACT is not set
-# CONFIG_INPUT_TMDC is not set
-# CONFIG_INPUT_SIDEWINDER is not set
-# CONFIG_INPUT_IFORCE_USB is not set
-# CONFIG_INPUT_IFORCE_232 is not set
-# CONFIG_INPUT_WARRIOR is not set
-# CONFIG_INPUT_MAGELLAN is not set
-# CONFIG_INPUT_SPACEORB is not set
-# CONFIG_INPUT_SPACEBALL is not set
-# CONFIG_INPUT_STINGER is not set
-# CONFIG_INPUT_DB9 is not set
-# CONFIG_INPUT_GAMECON is not set
-# CONFIG_INPUT_TURBOGRAFX is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-# CONFIG_ACQUIRE_WDT is not set
-# CONFIG_ADVANTECH_WDT is not set
-# CONFIG_ALIM7101_WDT is not set
-# CONFIG_SC520_WDT is not set
-# CONFIG_PCWATCHDOG is not set
-# CONFIG_21285_WATCHDOG is not set
-# CONFIG_977_WATCHDOG is not set
-CONFIG_SA1100_WATCHDOG=m
-# CONFIG_PXA_WATCHDOG is not set
-# CONFIG_OMAHA_WATCHDOG is not set
-# CONFIG_EUROTECH_WDT is not set
-# CONFIG_IB700_WDT is not set
-# CONFIG_WAFER_WDT is not set
-# CONFIG_I810_TCO is not set
-# CONFIG_MIXCOMWD is not set
-# CONFIG_60XX_WDT is not set
-# CONFIG_SC1200_WDT is not set
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_W83877F_WDT is not set
-# CONFIG_WDT is not set
-# CONFIG_WDTPCI is not set
-# CONFIG_MACHZ_WDT is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_SA1100_RTC=m
-# CONFIG_PXA_RTC_HACK is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-CONFIG_PCMCIA_SERIAL_CS=m
-# CONFIG_PCMCIA_MOBILISCAN_CS is not set
-# CONFIG_AXIM_KEY_FIX is not set
-
-#
-# Multimedia devices
-#
-CONFIG_MEDIA=m
-CONFIG_VIDEO_DEV=m
-CONFIG_V4L2_DEV=m
-
-#
-# Video For Linux
-#
-CONFIG_VIDEO_PROC_FS=y
-# CONFIG_I2C_PARPORT is not set
-
-#
-# Video Adapters
-#
-# CONFIG_VIDEO_PMS is not set
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIDEO_ZORAN_BUZ is not set
-# CONFIG_VIDEO_ZORAN_DC10 is not set
-# CONFIG_VIDEO_ZORAN_LML33 is not set
-# CONFIG_VIDEO_ZR36120 is not set
-# CONFIG_VIDEO_MEYE is not set
-# CONFIG_VIDEO_CYBERPRO is not set
-CONFIG_VIDEO_H3600_BACKPAQ=m
-# CONFIG_VIDEO_HAWKEYE is not set
-
-#
-# Video for Linux 2 (V4L2)
-#
-CONFIG_VIDEO_WINNOV_CS=m
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_CADET is not set
-# CONFIG_RADIO_RTRACK is not set
-# CONFIG_RADIO_RTRACK2 is not set
-# CONFIG_RADIO_AZTECH is not set
-# CONFIG_RADIO_GEMTEK is not set
-# CONFIG_RADIO_GEMTEK_PCI is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_MAESTRO is not set
-# CONFIG_RADIO_MIROPCM20 is not set
-# CONFIG_RADIO_MIROPCM20_RDS is not set
-# CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_TERRATEC is not set
-# CONFIG_RADIO_TRUST is not set
-# CONFIG_RADIO_TYPHOON is not set
-# CONFIG_RADIO_ZOLTRIX is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=m
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=m
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_UMSDOS_FS=m
-CONFIG_VFAT_FS=m
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-CONFIG_CRAMFS=y
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-CONFIG_ISO9660_FS=m
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DRIVERFS_FS is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=m
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-# CONFIG_ROOT_NFS is not set
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-CONFIG_SUNRPC=m
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-
-#
-# Console drivers
-#
-CONFIG_PC_KEYMAP=y
-# CONFIG_VGA_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_ACORN is not set
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_S3C2410 is not set
-CONFIG_FB_SA1100=y
-# CONFIG_FB_EPSON1356 is not set
-# CONFIG_FB_MQ200 is not set
-# CONFIG_FB_PXA is not set
-# CONFIG_FB_MQ1100 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-CONFIG_FBCON_CFB4=y
-# CONFIG_FBCON_CFB8 is not set
-CONFIG_FBCON_CFB16=y
-# CONFIG_FBCON_CFB24 is not set
-# CONFIG_FBCON_CFB32 is not set
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA_PLANES is not set
-# CONFIG_FBCON_VGA is not set
-# CONFIG_FBCON_HGA is not set
-# CONFIG_FBCON_NO_LOGO is not set
-CONFIG_FBCON_FONTWIDTH8_ONLY=y
-CONFIG_FBCON_FONTS=y
-CONFIG_FONT_8x8=y
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-CONFIG_SOUND_SA1100=m
-CONFIG_SOUND_UDA1341=m
-# CONFIG_SOUND_SA1100_MONO is not set
-# CONFIG_SOUND_ASSABET_UDA1341 is not set
-CONFIG_SOUND_H3600_UDA1341=m
-# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
-# CONFIG_SOUND_SA1111_UDA1341 is not set
-# CONFIG_SOUND_SA1100SSP is not set
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_VIDC is not set
-# CONFIG_SOUND_WAVEARTIST is not set
-# CONFIG_SOUND_PXA_AC97 is not set
-# CONFIG_SOUND_TVMIXER is not set
-
-#
-# Multimedia Capabilities Port drivers
-#
-# CONFIG_MCP is not set
-# CONFIG_MCP_SA1100 is not set
-# CONFIG_MCP_UCB1200 is not set
-# CONFIG_MCP_UCB1200_AUDIO is not set
-# CONFIG_MCP_UCB1200_TS is not set
-# CONFIG_MCP_UCB1400_TS is not set
-
-#
-# Console Switches
-#
-# CONFIG_SWITCHES is not set
-
-#
-# USB support
-#
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_LONG_TIMEOUT is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-# CONFIG_USB_OHCI_SA1111 is not set
-# CONFIG_USB_OHCI_H5400 is not set
-# CONFIG_USB_OHCI_S3C2410 is not set
-CONFIG_USB_SL811HS=m
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_BLUETOOTH is not set
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-CONFIG_USB_PRINTER=m
-
-#
-# USB Human Interface Devices (HID)
-#
-CONFIG_USB_HID=m
-CONFIG_USB_HIDINPUT=y
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_WACOM is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_OV511=m
-CONFIG_USB_PWC=m
-CONFIG_USB_SE401=m
-CONFIG_USB_STV680=m
-CONFIG_USB_VICAM=m
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-CONFIG_USB_CDCETHER=m
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_BRLVGER is not set
-
-#
-# Linux As Bootldr Modules
-#
-# CONFIG_BIG_KERNEL is not set
-# CONFIG_USE_DATE_CODE is not set
-# CONFIG_YMODEM is not set
-# CONFIG_LAB_DUMMY is not set
-# CONFIG_LAB_CRC is not set
-# CONFIG_LAB_YMODEM is not set
-# CONFIG_LAB_MTD is not set
-# CONFIG_LAB_COPY is not set
-# CONFIG_LAB_COPY_YMODEM is not set
-# CONFIG_LAB_COPY_FLASH is not set
-# CONFIG_LAB_COPY_FS is not set
-# CONFIG_LAB_COPY_WRAPPER is not set
-
-#
-# Bluetooth support
-#
-CONFIG_BLUEZ=m
-CONFIG_BLUEZ_L2CAP=m
-CONFIG_BLUEZ_SCO=m
-CONFIG_BLUEZ_RFCOMM=m
-CONFIG_BLUEZ_RFCOMM_TTY=y
-CONFIG_BLUEZ_BNEP=m
-CONFIG_BLUEZ_BNEP_MC_FILTER=y
-CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
-
-#
-# Bluetooth device drivers
-#
-# CONFIG_BLUEZ_HCIUSB is not set
-CONFIG_BLUEZ_HCIUART=m
-CONFIG_BLUEZ_HCIUART_H4=y
-CONFIG_BLUEZ_HCIUART_BCSP=y
-# CONFIG_BLUEZ_HCIUART_BCSP_TXCRC is not set
-# CONFIG_BLUEZ_HCIBFUSB is not set
-CONFIG_BLUEZ_HCIDTL1=m
-CONFIG_BLUEZ_HCIBT3C=m
-CONFIG_BLUEZ_HCIBLUECARD=m
-CONFIG_BLUEZ_HCIBTUART=m
-# CONFIG_BLUEZ_HCIVHCI is not set
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_NO_PGT_CACHE is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
-
-#
-# Library routines
-#
-# CONFIG_CRC32 is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh36.12/disable-pcmcia-probe.patch b/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh36.12/disable-pcmcia-probe.patch
deleted file mode 100644
index 79ba036323..0000000000
--- a/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh36.12/disable-pcmcia-probe.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-
-#
-# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux/drivers/pcmcia/Config.in~disable-pcmcia-probe 2003-05-13 11:18:23.000000000 +0200
-+++ linux/drivers/pcmcia/Config.in 2004-05-27 13:59:50.000000000 +0200
-@@ -15,9 +15,6 @@
- tristate 'PCMCIA/CardBus support' CONFIG_PCMCIA
- if [ "$CONFIG_PCMCIA" != "n" ]; then
- # yes, I really mean the following...
-- if [ "$CONFIG_ISA" = "y" -o "$CONFIG_ARCH_SA1100" = "y" ]; then
-- define_bool CONFIG_PCMCIA_PROBE y
-- fi
- if [ "$CONFIG_PCI" != "n" ]; then
- bool ' CardBus support' CONFIG_CARDBUS
- fi
diff --git a/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh36.12/ipsec.patch b/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh36.12/ipsec.patch
deleted file mode 100644
index 4e2efc035b..0000000000
--- a/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh36.12/ipsec.patch
+++ /dev/null
@@ -1,1446 +0,0 @@
---- linux/net/Makefile 3 Dec 2003 19:15:16 -0000 1.25
-+++ linux/net/Makefile 20 Feb 2003 15:50:38 -0000 1.24
-@@ -19,6 +19,7 @@
- subdir-$(CONFIG_NETFILTER) += ipv4/netfilter
- subdir-$(CONFIG_UNIX) += unix
- subdir-$(CONFIG_IPV6) += ipv6
-+subdir-$(CONFIG_IPSEC) += ipsec
-
- ifneq ($(CONFIG_IPV6),n)
- ifneq ($(CONFIG_IPV6),)
---- /dev/null 2004-02-02 20:32:13.000000000 +0000
-+++ linux/include/zlib/zlib.h 2004-07-05 23:56:59.000000000 +0100
-@@ -0,0 +1,893 @@
-+/* zlib.h -- interface of the 'zlib' general purpose compression library
-+ version 1.1.4, March 11th, 2002
-+
-+ Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
-+
-+ This software is provided 'as-is', without any express or implied
-+ warranty. In no event will the authors be held liable for any damages
-+ arising from the use of this software.
-+
-+ Permission is granted to anyone to use this software for any purpose,
-+ including commercial applications, and to alter it and redistribute it
-+ freely, subject to the following restrictions:
-+
-+ 1. The origin of this software must not be misrepresented; you must not
-+ claim that you wrote the original software. If you use this software
-+ in a product, an acknowledgment in the product documentation would be
-+ appreciated but is not required.
-+ 2. Altered source versions must be plainly marked as such, and must not be
-+ misrepresented as being the original software.
-+ 3. This notice may not be removed or altered from any source distribution.
-+
-+ Jean-loup Gailly Mark Adler
-+ jloup@gzip.org madler@alumni.caltech.edu
-+
-+
-+ The data format used by the zlib library is described by RFCs (Request for
-+ Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
-+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
-+*/
-+
-+#ifndef _ZLIB_H
-+#define _ZLIB_H
-+
-+#include "zconf.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#define ZLIB_VERSION "1.1.4"
-+
-+/*
-+ The 'zlib' compression library provides in-memory compression and
-+ decompression functions, including integrity checks of the uncompressed
-+ data. This version of the library supports only one compression method
-+ (deflation) but other algorithms will be added later and will have the same
-+ stream interface.
-+
-+ Compression can be done in a single step if the buffers are large
-+ enough (for example if an input file is mmap'ed), or can be done by
-+ repeated calls of the compression function. In the latter case, the
-+ application must provide more input and/or consume the output
-+ (providing more output space) before each call.
-+
-+ The library also supports reading and writing files in gzip (.gz) format
-+ with an interface similar to that of stdio.
-+
-+ The library does not install any signal handler. The decoder checks
-+ the consistency of the compressed data, so the library should never
-+ crash even in case of corrupted input.
-+*/
-+
-+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-+typedef void (*free_func) OF((voidpf opaque, voidpf address));
-+
-+struct internal_state;
-+
-+typedef struct z_stream_s {
-+ Bytef *next_in; /* next input byte */
-+ uInt avail_in; /* number of bytes available at next_in */
-+ uLong total_in; /* total nb of input bytes read so far */
-+
-+ Bytef *next_out; /* next output byte should be put there */
-+ uInt avail_out; /* remaining free space at next_out */
-+ uLong total_out; /* total nb of bytes output so far */
-+
-+ const char *msg; /* last error message, NULL if no error */
-+ struct internal_state FAR *state; /* not visible by applications */
-+
-+ alloc_func zalloc; /* used to allocate the internal state */
-+ free_func zfree; /* used to free the internal state */
-+ voidpf opaque; /* private data object passed to zalloc and zfree */
-+
-+ int data_type; /* best guess about the data type: ascii or binary */
-+ uLong adler; /* adler32 value of the uncompressed data */
-+ uLong reserved; /* reserved for future use */
-+} z_stream;
-+
-+typedef z_stream FAR *z_streamp;
-+
-+/*
-+ The application must update next_in and avail_in when avail_in has
-+ dropped to zero. It must update next_out and avail_out when avail_out
-+ has dropped to zero. The application must initialize zalloc, zfree and
-+ opaque before calling the init function. All other fields are set by the
-+ compression library and must not be updated by the application.
-+
-+ The opaque value provided by the application will be passed as the first
-+ parameter for calls of zalloc and zfree. This can be useful for custom
-+ memory management. The compression library attaches no meaning to the
-+ opaque value.
-+
-+ zalloc must return Z_NULL if there is not enough memory for the object.
-+ If zlib is used in a multi-threaded application, zalloc and zfree must be
-+ thread safe.
-+
-+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
-+ exactly 65536 bytes, but will not be required to allocate more than this
-+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
-+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
-+ have their offset normalized to zero. The default allocation function
-+ provided by this library ensures this (see zutil.c). To reduce memory
-+ requirements and avoid any allocation of 64K objects, at the expense of
-+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-+
-+ The fields total_in and total_out can be used for statistics or
-+ progress reports. After compression, total_in holds the total size of
-+ the uncompressed data and may be saved for use in the decompressor
-+ (particularly if the decompressor wants to decompress everything in
-+ a single step).
-+*/
-+
-+ /* constants */
-+
-+#define Z_NO_FLUSH 0
-+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
-+#define Z_SYNC_FLUSH 2
-+#define Z_FULL_FLUSH 3
-+#define Z_FINISH 4
-+/* Allowed flush values; see deflate() below for details */
-+
-+#define Z_OK 0
-+#define Z_STREAM_END 1
-+#define Z_NEED_DICT 2
-+#define Z_ERRNO (-1)
-+#define Z_STREAM_ERROR (-2)
-+#define Z_DATA_ERROR (-3)
-+#define Z_MEM_ERROR (-4)
-+#define Z_BUF_ERROR (-5)
-+#define Z_VERSION_ERROR (-6)
-+/* Return codes for the compression/decompression functions. Negative
-+ * values are errors, positive values are used for special but normal events.
-+ */
-+
-+#define Z_NO_COMPRESSION 0
-+#define Z_BEST_SPEED 1
-+#define Z_BEST_COMPRESSION 9
-+#define Z_DEFAULT_COMPRESSION (-1)
-+/* compression levels */
-+
-+#define Z_FILTERED 1
-+#define Z_HUFFMAN_ONLY 2
-+#define Z_DEFAULT_STRATEGY 0
-+/* compression strategy; see deflateInit2() below for details */
-+
-+#define Z_BINARY 0
-+#define Z_ASCII 1
-+#define Z_UNKNOWN 2
-+/* Possible values of the data_type field */
-+
-+#define Z_DEFLATED 8
-+/* The deflate compression method (the only one supported in this version) */
-+
-+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-+
-+#define zlib_version zlibVersion()
-+/* for compatibility with versions < 1.0.2 */
-+
-+ /* basic functions */
-+
-+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
-+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
-+ If the first character differs, the library code actually used is
-+ not compatible with the zlib.h header file used by the application.
-+ This check is automatically made by deflateInit and inflateInit.
-+ */
-+
-+/*
-+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
-+
-+ Initializes the internal stream state for compression. The fields
-+ zalloc, zfree and opaque must be initialized before by the caller.
-+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to
-+ use default allocation functions.
-+
-+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
-+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
-+ all (the input data is simply copied a block at a time).
-+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
-+ compression (currently equivalent to level 6).
-+
-+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
-+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
-+ with the version assumed by the caller (ZLIB_VERSION).
-+ msg is set to null if there is no error message. deflateInit does not
-+ perform any compression: this will be done by deflate().
-+*/
-+
-+
-+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
-+/*
-+ deflate compresses as much data as possible, and stops when the input
-+ buffer becomes empty or the output buffer becomes full. It may introduce some
-+ output latency (reading input without producing any output) except when
-+ forced to flush.
-+
-+ The detailed semantics are as follows. deflate performs one or both of the
-+ following actions:
-+
-+ - Compress more input starting at next_in and update next_in and avail_in
-+ accordingly. If not all input can be processed (because there is not
-+ enough room in the output buffer), next_in and avail_in are updated and
-+ processing will resume at this point for the next call of deflate().
-+
-+ - Provide more output starting at next_out and update next_out and avail_out
-+ accordingly. This action is forced if the parameter flush is non zero.
-+ Forcing flush frequently degrades the compression ratio, so this parameter
-+ should be set only when necessary (in interactive applications).
-+ Some output may be provided even if flush is not set.
-+
-+ Before the call of deflate(), the application should ensure that at least
-+ one of the actions is possible, by providing more input and/or consuming
-+ more output, and updating avail_in or avail_out accordingly; avail_out
-+ should never be zero before the call. The application can consume the
-+ compressed output when it wants, for example when the output buffer is full
-+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
-+ and with zero avail_out, it must be called again after making room in the
-+ output buffer because there might be more output pending.
-+
-+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
-+ flushed to the output buffer and the output is aligned on a byte boundary, so
-+ that the decompressor can get all input data available so far. (In particular
-+ avail_in is zero after the call if enough output space has been provided
-+ before the call.) Flushing may degrade compression for some compression
-+ algorithms and so it should be used only when necessary.
-+
-+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
-+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
-+ restart from this point if previous compressed data has been damaged or if
-+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
-+ the compression.
-+
-+ If deflate returns with avail_out == 0, this function must be called again
-+ with the same value of the flush parameter and more output space (updated
-+ avail_out), until the flush is complete (deflate returns with non-zero
-+ avail_out).
-+
-+ If the parameter flush is set to Z_FINISH, pending input is processed,
-+ pending output is flushed and deflate returns with Z_STREAM_END if there
-+ was enough output space; if deflate returns with Z_OK, this function must be
-+ called again with Z_FINISH and more output space (updated avail_out) but no
-+ more input data, until it returns with Z_STREAM_END or an error. After
-+ deflate has returned Z_STREAM_END, the only possible operations on the
-+ stream are deflateReset or deflateEnd.
-+
-+ Z_FINISH can be used immediately after deflateInit if all the compression
-+ is to be done in a single step. In this case, avail_out must be at least
-+ 0.1% larger than avail_in plus 12 bytes. If deflate does not return
-+ Z_STREAM_END, then it must be called again as described above.
-+
-+ deflate() sets strm->adler to the adler32 checksum of all input read
-+ so far (that is, total_in bytes).
-+
-+ deflate() may update data_type if it can make a good guess about
-+ the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
-+ binary. This field is only for information purposes and does not affect
-+ the compression algorithm in any manner.
-+
-+ deflate() returns Z_OK if some progress has been made (more input
-+ processed or more output produced), Z_STREAM_END if all input has been
-+ consumed and all output has been produced (only when flush is set to
-+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
-+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
-+ (for example avail_in or avail_out was zero).
-+*/
-+
-+
-+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
-+/*
-+ All dynamically allocated data structures for this stream are freed.
-+ This function discards any unprocessed input and does not flush any
-+ pending output.
-+
-+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
-+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
-+ prematurely (some input or output was discarded). In the error case,
-+ msg may be set but then points to a static string (which must not be
-+ deallocated).
-+*/
-+
-+
-+/*
-+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
-+
-+ Initializes the internal stream state for decompression. The fields
-+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
-+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
-+ value depends on the compression method), inflateInit determines the
-+ compression method from the zlib header and allocates all data structures
-+ accordingly; otherwise the allocation will be deferred to the first call of
-+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
-+ use default allocation functions.
-+
-+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
-+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
-+ version assumed by the caller. msg is set to null if there is no error
-+ message. inflateInit does not perform any decompression apart from reading
-+ the zlib header if present: this will be done by inflate(). (So next_in and
-+ avail_in may be modified, but next_out and avail_out are unchanged.)
-+*/
-+
-+
-+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
-+/*
-+ inflate decompresses as much data as possible, and stops when the input
-+ buffer becomes empty or the output buffer becomes full. It may some
-+ introduce some output latency (reading input without producing any output)
-+ except when forced to flush.
-+
-+ The detailed semantics are as follows. inflate performs one or both of the
-+ following actions:
-+
-+ - Decompress more input starting at next_in and update next_in and avail_in
-+ accordingly. If not all input can be processed (because there is not
-+ enough room in the output buffer), next_in is updated and processing
-+ will resume at this point for the next call of inflate().
-+
-+ - Provide more output starting at next_out and update next_out and avail_out
-+ accordingly. inflate() provides as much output as possible, until there
-+ is no more input data or no more space in the output buffer (see below
-+ about the flush parameter).
-+
-+ Before the call of inflate(), the application should ensure that at least
-+ one of the actions is possible, by providing more input and/or consuming
-+ more output, and updating the next_* and avail_* values accordingly.
-+ The application can consume the uncompressed output when it wants, for
-+ example when the output buffer is full (avail_out == 0), or after each
-+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
-+ must be called again after making room in the output buffer because there
-+ might be more output pending.
-+
-+ If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
-+ output as possible to the output buffer. The flushing behavior of inflate is
-+ not specified for values of the flush parameter other than Z_SYNC_FLUSH
-+ and Z_FINISH, but the current implementation actually flushes as much output
-+ as possible anyway.
-+
-+ inflate() should normally be called until it returns Z_STREAM_END or an
-+ error. However if all decompression is to be performed in a single step
-+ (a single call of inflate), the parameter flush should be set to
-+ Z_FINISH. In this case all pending input is processed and all pending
-+ output is flushed; avail_out must be large enough to hold all the
-+ uncompressed data. (The size of the uncompressed data may have been saved
-+ by the compressor for this purpose.) The next operation on this stream must
-+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
-+ is never required, but can be used to inform inflate that a faster routine
-+ may be used for the single inflate() call.
-+
-+ If a preset dictionary is needed at this point (see inflateSetDictionary
-+ below), inflate sets strm-adler to the adler32 checksum of the
-+ dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
-+ it sets strm->adler to the adler32 checksum of all output produced
-+ so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
-+ an error code as described below. At the end of the stream, inflate()
-+ checks that its computed adler32 checksum is equal to that saved by the
-+ compressor and returns Z_STREAM_END only if the checksum is correct.
-+
-+ inflate() returns Z_OK if some progress has been made (more input processed
-+ or more output produced), Z_STREAM_END if the end of the compressed data has
-+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
-+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
-+ corrupted (input stream not conforming to the zlib format or incorrect
-+ adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
-+ (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
-+ enough memory, Z_BUF_ERROR if no progress is possible or if there was not
-+ enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
-+ case, the application may then call inflateSync to look for a good
-+ compression block.
-+*/
-+
-+
-+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
-+/*
-+ All dynamically allocated data structures for this stream are freed.
-+ This function discards any unprocessed input and does not flush any
-+ pending output.
-+
-+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
-+ was inconsistent. In the error case, msg may be set but then points to a
-+ static string (which must not be deallocated).
-+*/
-+
-+ /* Advanced functions */
-+
-+/*
-+ The following functions are needed only in some special applications.
-+*/
-+
-+/*
-+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
-+ int level,
-+ int method,
-+ int windowBits,
-+ int memLevel,
-+ int strategy));
-+
-+ This is another version of deflateInit with more compression options. The
-+ fields next_in, zalloc, zfree and opaque must be initialized before by
-+ the caller.
-+
-+ The method parameter is the compression method. It must be Z_DEFLATED in
-+ this version of the library.
-+
-+ The windowBits parameter is the base two logarithm of the window size
-+ (the size of the history buffer). It should be in the range 8..15 for this
-+ version of the library. Larger values of this parameter result in better
-+ compression at the expense of memory usage. The default value is 15 if
-+ deflateInit is used instead.
-+
-+ The memLevel parameter specifies how much memory should be allocated
-+ for the internal compression state. memLevel=1 uses minimum memory but
-+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
-+ for optimal speed. The default value is 8. See zconf.h for total memory
-+ usage as a function of windowBits and memLevel.
-+
-+ The strategy parameter is used to tune the compression algorithm. Use the
-+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
-+ filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
-+ string match). Filtered data consists mostly of small values with a
-+ somewhat random distribution. In this case, the compression algorithm is
-+ tuned to compress them better. The effect of Z_FILTERED is to force more
-+ Huffman coding and less string matching; it is somewhat intermediate
-+ between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
-+ the compression ratio but not the correctness of the compressed output even
-+ if it is not set appropriately.
-+
-+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
-+ method). msg is set to null if there is no error message. deflateInit2 does
-+ not perform any compression: this will be done by deflate().
-+*/
-+
-+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
-+ const Bytef *dictionary,
-+ uInt dictLength));
-+/*
-+ Initializes the compression dictionary from the given byte sequence
-+ without producing any compressed output. This function must be called
-+ immediately after deflateInit, deflateInit2 or deflateReset, before any
-+ call of deflate. The compressor and decompressor must use exactly the same
-+ dictionary (see inflateSetDictionary).
-+
-+ The dictionary should consist of strings (byte sequences) that are likely
-+ to be encountered later in the data to be compressed, with the most commonly
-+ used strings preferably put towards the end of the dictionary. Using a
-+ dictionary is most useful when the data to be compressed is short and can be
-+ predicted with good accuracy; the data can then be compressed better than
-+ with the default empty dictionary.
-+
-+ Depending on the size of the compression data structures selected by
-+ deflateInit or deflateInit2, a part of the dictionary may in effect be
-+ discarded, for example if the dictionary is larger than the window size in
-+ deflate or deflate2. Thus the strings most likely to be useful should be
-+ put at the end of the dictionary, not at the front.
-+
-+ Upon return of this function, strm->adler is set to the Adler32 value
-+ of the dictionary; the decompressor may later use this value to determine
-+ which dictionary has been used by the compressor. (The Adler32 value
-+ applies to the whole dictionary even if only a subset of the dictionary is
-+ actually used by the compressor.)
-+
-+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
-+ parameter is invalid (such as NULL dictionary) or the stream state is
-+ inconsistent (for example if deflate has already been called for this stream
-+ or if the compression method is bsort). deflateSetDictionary does not
-+ perform any compression: this will be done by deflate().
-+*/
-+
-+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
-+ z_streamp source));
-+/*
-+ Sets the destination stream as a complete copy of the source stream.
-+
-+ This function can be useful when several compression strategies will be
-+ tried, for example when there are several ways of pre-processing the input
-+ data with a filter. The streams that will be discarded should then be freed
-+ by calling deflateEnd. Note that deflateCopy duplicates the internal
-+ compression state which can be quite large, so this strategy is slow and
-+ can consume lots of memory.
-+
-+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
-+ (such as zalloc being NULL). msg is left unchanged in both source and
-+ destination.
-+*/
-+
-+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
-+/*
-+ This function is equivalent to deflateEnd followed by deflateInit,
-+ but does not free and reallocate all the internal compression state.
-+ The stream will keep the same compression level and any other attributes
-+ that may have been set by deflateInit2.
-+
-+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-+ stream state was inconsistent (such as zalloc or state being NULL).
-+*/
-+
-+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
-+ int level,
-+ int strategy));
-+/*
-+ Dynamically update the compression level and compression strategy. The
-+ interpretation of level and strategy is as in deflateInit2. This can be
-+ used to switch between compression and straight copy of the input data, or
-+ to switch to a different kind of input data requiring a different
-+ strategy. If the compression level is changed, the input available so far
-+ is compressed with the old level (and may be flushed); the new level will
-+ take effect only at the next call of deflate().
-+
-+ Before the call of deflateParams, the stream state must be set as for
-+ a call of deflate(), since the currently available input may have to
-+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
-+
-+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
-+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
-+ if strm->avail_out was zero.
-+*/
-+
-+/*
-+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
-+ int windowBits));
-+
-+ This is another version of inflateInit with an extra parameter. The
-+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
-+ before by the caller.
-+
-+ The windowBits parameter is the base two logarithm of the maximum window
-+ size (the size of the history buffer). It should be in the range 8..15 for
-+ this version of the library. The default value is 15 if inflateInit is used
-+ instead. If a compressed stream with a larger window size is given as
-+ input, inflate() will return with the error code Z_DATA_ERROR instead of
-+ trying to allocate a larger window.
-+
-+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
-+ memLevel). msg is set to null if there is no error message. inflateInit2
-+ does not perform any decompression apart from reading the zlib header if
-+ present: this will be done by inflate(). (So next_in and avail_in may be
-+ modified, but next_out and avail_out are unchanged.)
-+*/
-+
-+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
-+ const Bytef *dictionary,
-+ uInt dictLength));
-+/*
-+ Initializes the decompression dictionary from the given uncompressed byte
-+ sequence. This function must be called immediately after a call of inflate
-+ if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
-+ can be determined from the Adler32 value returned by this call of
-+ inflate. The compressor and decompressor must use exactly the same
-+ dictionary (see deflateSetDictionary).
-+
-+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
-+ parameter is invalid (such as NULL dictionary) or the stream state is
-+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
-+ expected one (incorrect Adler32 value). inflateSetDictionary does not
-+ perform any decompression: this will be done by subsequent calls of
-+ inflate().
-+*/
-+
-+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
-+/*
-+ Skips invalid compressed data until a full flush point (see above the
-+ description of deflate with Z_FULL_FLUSH) can be found, or until all
-+ available input is skipped. No output is provided.
-+
-+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
-+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
-+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
-+ case, the application may save the current current value of total_in which
-+ indicates where valid compressed data was found. In the error case, the
-+ application may repeatedly call inflateSync, providing more input each time,
-+ until success or end of the input data.
-+*/
-+
-+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
-+/*
-+ This function is equivalent to inflateEnd followed by inflateInit,
-+ but does not free and reallocate all the internal decompression state.
-+ The stream will keep attributes that may have been set by inflateInit2.
-+
-+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-+ stream state was inconsistent (such as zalloc or state being NULL).
-+*/
-+
-+
-+ /* utility functions */
-+
-+/*
-+ The following utility functions are implemented on top of the
-+ basic stream-oriented functions. To simplify the interface, some
-+ default options are assumed (compression level and memory usage,
-+ standard memory allocation functions). The source code of these
-+ utility functions can easily be modified if you need special options.
-+*/
-+
-+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
-+ const Bytef *source, uLong sourceLen));
-+/*
-+ Compresses the source buffer into the destination buffer. sourceLen is
-+ the byte length of the source buffer. Upon entry, destLen is the total
-+ size of the destination buffer, which must be at least 0.1% larger than
-+ sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
-+ compressed buffer.
-+ This function can be used to compress a whole file at once if the
-+ input file is mmap'ed.
-+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory, Z_BUF_ERROR if there was not enough room in the output
-+ buffer.
-+*/
-+
-+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
-+ const Bytef *source, uLong sourceLen,
-+ int level));
-+/*
-+ Compresses the source buffer into the destination buffer. The level
-+ parameter has the same meaning as in deflateInit. sourceLen is the byte
-+ length of the source buffer. Upon entry, destLen is the total size of the
-+ destination buffer, which must be at least 0.1% larger than sourceLen plus
-+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
-+
-+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
-+ Z_STREAM_ERROR if the level parameter is invalid.
-+*/
-+
-+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
-+ const Bytef *source, uLong sourceLen));
-+/*
-+ Decompresses the source buffer into the destination buffer. sourceLen is
-+ the byte length of the source buffer. Upon entry, destLen is the total
-+ size of the destination buffer, which must be large enough to hold the
-+ entire uncompressed data. (The size of the uncompressed data must have
-+ been saved previously by the compressor and transmitted to the decompressor
-+ by some mechanism outside the scope of this compression library.)
-+ Upon exit, destLen is the actual size of the compressed buffer.
-+ This function can be used to decompress a whole file at once if the
-+ input file is mmap'ed.
-+
-+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory, Z_BUF_ERROR if there was not enough room in the output
-+ buffer, or Z_DATA_ERROR if the input data was corrupted.
-+*/
-+
-+
-+typedef voidp gzFile;
-+
-+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
-+/*
-+ Opens a gzip (.gz) file for reading or writing. The mode parameter
-+ is as in fopen ("rb" or "wb") but can also include a compression level
-+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
-+ Huffman only compression as in "wb1h". (See the description
-+ of deflateInit2 for more information about the strategy parameter.)
-+
-+ gzopen can be used to read a file which is not in gzip format; in this
-+ case gzread will directly read from the file without decompression.
-+
-+ gzopen returns NULL if the file could not be opened or if there was
-+ insufficient memory to allocate the (de)compression state; errno
-+ can be checked to distinguish the two cases (if errno is zero, the
-+ zlib error is Z_MEM_ERROR). */
-+
-+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
-+/*
-+ gzdopen() associates a gzFile with the file descriptor fd. File
-+ descriptors are obtained from calls like open, dup, creat, pipe or
-+ fileno (in the file has been previously opened with fopen).
-+ The mode parameter is as in gzopen.
-+ The next call of gzclose on the returned gzFile will also close the
-+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
-+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
-+ gzdopen returns NULL if there was insufficient memory to allocate
-+ the (de)compression state.
-+*/
-+
-+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
-+/*
-+ Dynamically update the compression level or strategy. See the description
-+ of deflateInit2 for the meaning of these parameters.
-+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
-+ opened for writing.
-+*/
-+
-+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
-+/*
-+ Reads the given number of uncompressed bytes from the compressed file.
-+ If the input file was not in gzip format, gzread copies the given number
-+ of bytes into the buffer.
-+ gzread returns the number of uncompressed bytes actually read (0 for
-+ end of file, -1 for error). */
-+
-+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
-+ const voidp buf, unsigned len));
-+/*
-+ Writes the given number of uncompressed bytes into the compressed file.
-+ gzwrite returns the number of uncompressed bytes actually written
-+ (0 in case of error).
-+*/
-+
-+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
-+/*
-+ Converts, formats, and writes the args to the compressed file under
-+ control of the format string, as in fprintf. gzprintf returns the number of
-+ uncompressed bytes actually written (0 in case of error).
-+*/
-+
-+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
-+/*
-+ Writes the given null-terminated string to the compressed file, excluding
-+ the terminating null character.
-+ gzputs returns the number of characters written, or -1 in case of error.
-+*/
-+
-+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
-+/*
-+ Reads bytes from the compressed file until len-1 characters are read, or
-+ a newline character is read and transferred to buf, or an end-of-file
-+ condition is encountered. The string is then terminated with a null
-+ character.
-+ gzgets returns buf, or Z_NULL in case of error.
-+*/
-+
-+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
-+/*
-+ Writes c, converted to an unsigned char, into the compressed file.
-+ gzputc returns the value that was written, or -1 in case of error.
-+*/
-+
-+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
-+/*
-+ Reads one byte from the compressed file. gzgetc returns this byte
-+ or -1 in case of end of file or error.
-+*/
-+
-+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
-+/*
-+ Flushes all pending output into the compressed file. The parameter
-+ flush is as in the deflate() function. The return value is the zlib
-+ error number (see function gzerror below). gzflush returns Z_OK if
-+ the flush parameter is Z_FINISH and all output could be flushed.
-+ gzflush should be called only when strictly necessary because it can
-+ degrade compression.
-+*/
-+
-+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
-+ z_off_t offset, int whence));
-+/*
-+ Sets the starting position for the next gzread or gzwrite on the
-+ given compressed file. The offset represents a number of bytes in the
-+ uncompressed data stream. The whence parameter is defined as in lseek(2);
-+ the value SEEK_END is not supported.
-+ If the file is opened for reading, this function is emulated but can be
-+ extremely slow. If the file is opened for writing, only forward seeks are
-+ supported; gzseek then compresses a sequence of zeroes up to the new
-+ starting position.
-+
-+ gzseek returns the resulting offset location as measured in bytes from
-+ the beginning of the uncompressed stream, or -1 in case of error, in
-+ particular if the file is opened for writing and the new starting position
-+ would be before the current position.
-+*/
-+
-+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
-+/*
-+ Rewinds the given file. This function is supported only for reading.
-+
-+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
-+*/
-+
-+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
-+/*
-+ Returns the starting position for the next gzread or gzwrite on the
-+ given compressed file. This position represents a number of bytes in the
-+ uncompressed data stream.
-+
-+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
-+*/
-+
-+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
-+/*
-+ Returns 1 when EOF has previously been detected reading the given
-+ input stream, otherwise zero.
-+*/
-+
-+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
-+/*
-+ Flushes all pending output if necessary, closes the compressed file
-+ and deallocates all the (de)compression state. The return value is the zlib
-+ error number (see function gzerror below).
-+*/
-+
-+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
-+/*
-+ Returns the error message for the last error which occurred on the
-+ given compressed file. errnum is set to zlib error number. If an
-+ error occurred in the file system and not in the compression library,
-+ errnum is set to Z_ERRNO and the application may consult errno
-+ to get the exact error code.
-+*/
-+
-+ /* checksum functions */
-+
-+/*
-+ These functions are not related to compression but are exported
-+ anyway because they might be useful in applications using the
-+ compression library.
-+*/
-+
-+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
-+
-+/*
-+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
-+ return the updated checksum. If buf is NULL, this function returns
-+ the required initial value for the checksum.
-+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
-+ much faster. Usage example:
-+
-+ uLong adler = adler32(0L, Z_NULL, 0);
-+
-+ while (read_buffer(buffer, length) != EOF) {
-+ adler = adler32(adler, buffer, length);
-+ }
-+ if (adler != original_adler) error();
-+*/
-+
-+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
-+/*
-+ Update a running crc with the bytes buf[0..len-1] and return the updated
-+ crc. If buf is NULL, this function returns the required initial value
-+ for the crc. Pre- and post-conditioning (one's complement) is performed
-+ within this function so it shouldn't be done by the application.
-+ Usage example:
-+
-+ uLong crc = crc32(0L, Z_NULL, 0);
-+
-+ while (read_buffer(buffer, length) != EOF) {
-+ crc = crc32(crc, buffer, length);
-+ }
-+ if (crc != original_crc) error();
-+*/
-+
-+
-+ /* various hacks, don't look :) */
-+
-+/* deflateInit and inflateInit are macros to allow checking the zlib version
-+ * and the compiler's view of z_stream:
-+ */
-+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
-+ const char *version, int stream_size));
-+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
-+ const char *version, int stream_size));
-+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
-+ int windowBits, int memLevel,
-+ int strategy, const char *version,
-+ int stream_size));
-+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
-+ const char *version, int stream_size));
-+#define deflateInit(strm, level) \
-+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
-+#define inflateInit(strm) \
-+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
-+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
-+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
-+ (strategy), ZLIB_VERSION, sizeof(z_stream))
-+#define inflateInit2(strm, windowBits) \
-+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
-+
-+
-+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
-+ struct internal_state {int dummy;}; /* hack for buggy compilers */
-+#endif
-+
-+ZEXTERN const char * ZEXPORT zError OF((int err));
-+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
-+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _ZLIB_H */
---- /dev/null 2004-02-02 20:32:13.000000000 +0000
-+++ linux/include/zlib/zutil.h 2004-07-05 23:59:30.000000000 +0100
-@@ -0,0 +1,225 @@
-+/* zutil.h -- internal interface and configuration of the compression library
-+ * Copyright (C) 1995-2002 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+/* @(#) $Id$ */
-+
-+#ifndef _Z_UTIL_H
-+#define _Z_UTIL_H
-+
-+#include "zlib.h"
-+
-+#include <linux/string.h>
-+#define HAVE_MEMCPY
-+
-+#if 0 // #ifdef STDC
-+# include <stddef.h>
-+# include <string.h>
-+# include <stdlib.h>
-+#endif
-+#ifndef __KERNEL__
-+#ifdef NO_ERRNO_H
-+ extern int errno;
-+#else
-+# include <errno.h>
-+#endif
-+#endif
-+
-+#ifndef local
-+# define local static
-+#endif
-+/* compile with -Dlocal if your debugger can't find static symbols */
-+
-+typedef unsigned char uch;
-+typedef uch FAR uchf;
-+typedef unsigned short ush;
-+typedef ush FAR ushf;
-+typedef unsigned long ulg;
-+
-+extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
-+/* (size given to avoid silly warnings with Visual C++) */
-+
-+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
-+
-+#define ERR_RETURN(strm,err) \
-+ return (strm->msg = ERR_MSG(err), (err))
-+/* To be used only when the state is known to be valid */
-+
-+ /* common constants */
-+
-+#ifndef DEF_WBITS
-+# define DEF_WBITS MAX_WBITS
-+#endif
-+/* default windowBits for decompression. MAX_WBITS is for compression only */
-+
-+#if MAX_MEM_LEVEL >= 8
-+# define DEF_MEM_LEVEL 8
-+#else
-+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-+#endif
-+/* default memLevel */
-+
-+#define STORED_BLOCK 0
-+#define STATIC_TREES 1
-+#define DYN_TREES 2
-+/* The three kinds of block type */
-+
-+#define MIN_MATCH 3
-+#define MAX_MATCH 258
-+/* The minimum and maximum match lengths */
-+
-+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-+
-+ /* target dependencies */
-+
-+#ifdef MSDOS
-+# define OS_CODE 0x00
-+# if defined(__TURBOC__) || defined(__BORLANDC__)
-+# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
-+ /* Allow compilation with ANSI keywords only enabled */
-+ void _Cdecl farfree( void *block );
-+ void *_Cdecl farmalloc( unsigned long nbytes );
-+# else
-+# include <alloc.h>
-+# endif
-+# else /* MSC or DJGPP */
-+# include <malloc.h>
-+# endif
-+#endif
-+
-+#ifdef OS2
-+# define OS_CODE 0x06
-+#endif
-+
-+#ifdef WIN32 /* Window 95 & Windows NT */
-+# define OS_CODE 0x0b
-+#endif
-+
-+#if defined(VAXC) || defined(VMS)
-+# define OS_CODE 0x02
-+# define F_OPEN(name, mode) \
-+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
-+#endif
-+
-+#ifdef AMIGA
-+# define OS_CODE 0x01
-+#endif
-+
-+#if defined(ATARI) || defined(atarist)
-+# define OS_CODE 0x05
-+#endif
-+
-+#if defined(MACOS) || defined(TARGET_OS_MAC)
-+# define OS_CODE 0x07
-+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-+# include <unix.h> /* for fdopen */
-+# else
-+# ifndef fdopen
-+# define fdopen(fd,mode) NULL /* No fdopen() */
-+# endif
-+# endif
-+#endif
-+
-+#ifdef __50SERIES /* Prime/PRIMOS */
-+# define OS_CODE 0x0F
-+#endif
-+
-+#ifdef TOPS20
-+# define OS_CODE 0x0a
-+#endif
-+
-+#if defined(_BEOS_) || defined(RISCOS)
-+# define fdopen(fd,mode) NULL /* No fdopen() */
-+#endif
-+
-+#if (defined(_MSC_VER) && (_MSC_VER > 600))
-+# define fdopen(fd,type) _fdopen(fd,type)
-+#endif
-+
-+
-+ /* Common defaults */
-+
-+#ifndef OS_CODE
-+# define OS_CODE 0x03 /* assume Unix */
-+#endif
-+
-+#ifndef F_OPEN
-+# define F_OPEN(name, mode) fopen((name), (mode))
-+#endif
-+
-+ /* functions */
-+
-+#ifdef HAVE_STRERROR
-+ extern char *strerror OF((int));
-+# define zstrerror(errnum) strerror(errnum)
-+#else
-+# define zstrerror(errnum) ""
-+#endif
-+
-+#if defined(pyr)
-+# define NO_MEMCPY
-+#endif
-+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
-+ /* Use our own functions for small and medium model with MSC <= 5.0.
-+ * You may have to use the same strategy for Borland C (untested).
-+ * The __SC__ check is for Symantec.
-+ */
-+# define NO_MEMCPY
-+#endif
-+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
-+# define HAVE_MEMCPY
-+#endif
-+#ifdef HAVE_MEMCPY
-+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
-+# define zmemcpy _fmemcpy
-+# define zmemcmp _fmemcmp
-+# define zmemzero(dest, len) _fmemset(dest, 0, len)
-+# else
-+# define zmemcpy memcpy
-+# define zmemcmp memcmp
-+# define zmemzero(dest, len) memset(dest, 0, len)
-+# endif
-+#else
-+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
-+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
-+ extern void zmemzero OF((Bytef* dest, uInt len));
-+#endif
-+
-+/* Diagnostic functions */
-+#ifdef DEBUG
-+# include <stdio.h>
-+ extern int z_verbose;
-+ extern void z_error OF((char *m));
-+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
-+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
-+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
-+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
-+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
-+#else
-+# define Assert(cond,msg)
-+# define Trace(x)
-+# define Tracev(x)
-+# define Tracevv(x)
-+# define Tracec(c,x)
-+# define Tracecv(c,x)
-+#endif
-+
-+
-+typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
-+ uInt len));
-+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-+void zcfree OF((voidpf opaque, voidpf ptr));
-+
-+#define ZALLOC(strm, items, size) \
-+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
-+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
-+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
-+
-+#endif /* _Z_UTIL_H */
---- /dev/null 2004-02-02 20:32:13.000000000 +0000
-+++ linux/include/zconf.h 2004-07-04 15:38:31.000000000 +0100
-@@ -0,0 +1,309 @@
-+/* zconf.h -- configuration of the zlib compression library
-+ * Copyright (C) 1995-2002 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* @(#) $Id$ */
-+
-+#ifndef _ZCONF_H
-+#define _ZCONF_H
-+
-+/*
-+ * If you *really* need a unique prefix for all types and library functions,
-+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
-+ */
-+#ifdef IPCOMP_PREFIX
-+# define deflateInit_ ipcomp_deflateInit_
-+# define deflate ipcomp_deflate
-+# define deflateEnd ipcomp_deflateEnd
-+# define inflateInit_ ipcomp_inflateInit_
-+# define inflate ipcomp_inflate
-+# define inflateEnd ipcomp_inflateEnd
-+# define deflateInit2_ ipcomp_deflateInit2_
-+# define deflateSetDictionary ipcomp_deflateSetDictionary
-+# define deflateCopy ipcomp_deflateCopy
-+# define deflateReset ipcomp_deflateReset
-+# define deflateParams ipcomp_deflateParams
-+# define inflateInit2_ ipcomp_inflateInit2_
-+# define inflateSetDictionary ipcomp_inflateSetDictionary
-+# define inflateSync ipcomp_inflateSync
-+# define inflateSyncPoint ipcomp_inflateSyncPoint
-+# define inflateReset ipcomp_inflateReset
-+# define compress ipcomp_compress
-+# define compress2 ipcomp_compress2
-+# define uncompress ipcomp_uncompress
-+# define adler32 ipcomp_adler32
-+# define crc32 ipcomp_crc32
-+# define get_crc_table ipcomp_get_crc_table
-+/* SSS: these also need to be prefixed to avoid clash with ppp_deflate and ext2compression */
-+# define inflate_blocks ipcomp_deflate_blocks
-+# define inflate_blocks_free ipcomp_deflate_blocks_free
-+# define inflate_blocks_new ipcomp_inflate_blocks_new
-+# define inflate_blocks_reset ipcomp_inflate_blocks_reset
-+# define inflate_blocks_sync_point ipcomp_inflate_blocks_sync_point
-+# define inflate_set_dictionary ipcomp_inflate_set_dictionary
-+# define inflate_codes ipcomp_inflate_codes
-+# define inflate_codes_free ipcomp_inflate_codes_free
-+# define inflate_codes_new ipcomp_inflate_codes_new
-+# define inflate_fast ipcomp_inflate_fast
-+# define inflate_trees_bits ipcomp_inflate_trees_bits
-+# define inflate_trees_dynamic ipcomp_inflate_trees_dynamic
-+# define inflate_trees_fixed ipcomp_inflate_trees_fixed
-+# define inflate_flush ipcomp_inflate_flush
-+# define inflate_mask ipcomp_inflate_mask
-+# define _dist_code _ipcomp_dist_code
-+# define _length_code _ipcomp_length_code
-+# define _tr_align _ipcomp_tr_align
-+# define _tr_flush_block _ipcomp_tr_flush_block
-+# define _tr_init _ipcomp_tr_init
-+# define _tr_stored_block _ipcomp_tr_stored_block
-+# define _tr_tally _ipcomp_tr_tally
-+# define zError ipcomp_zError
-+# define z_errmsg ipcomp_z_errmsg
-+# define zlibVersion ipcomp_zlibVersion
-+# define match_init ipcomp_match_init
-+# define longest_match ipcomp_longest_match
-+#endif
-+
-+#ifdef Z_PREFIX
-+# define Byte z_Byte
-+# define uInt z_uInt
-+# define uLong z_uLong
-+# define Bytef z_Bytef
-+# define charf z_charf
-+# define intf z_intf
-+# define uIntf z_uIntf
-+# define uLongf z_uLongf
-+# define voidpf z_voidpf
-+# define voidp z_voidp
-+#endif
-+
-+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-+# define WIN32
-+#endif
-+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
-+# ifndef __32BIT__
-+# define __32BIT__
-+# endif
-+#endif
-+#if defined(__MSDOS__) && !defined(MSDOS)
-+# define MSDOS
-+#endif
-+
-+/*
-+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
-+ * than 64k bytes at a time (needed on systems with 16-bit int).
-+ */
-+#if defined(MSDOS) && !defined(__32BIT__)
-+# define MAXSEG_64K
-+#endif
-+#ifdef MSDOS
-+# define UNALIGNED_OK
-+#endif
-+
-+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
-+# define STDC
-+#endif
-+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
-+# ifndef STDC
-+# define STDC
-+# endif
-+#endif
-+
-+#ifndef STDC
-+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-+# define const
-+# endif
-+#endif
-+
-+/* Some Mac compilers merge all .h files incorrectly: */
-+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
-+# define NO_DUMMY_DECL
-+#endif
-+
-+/* Old Borland C incorrectly complains about missing returns: */
-+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
-+# define NEED_DUMMY_RETURN
-+#endif
-+
-+
-+/* Maximum value for memLevel in deflateInit2 */
-+#ifndef MAX_MEM_LEVEL
-+# ifdef MAXSEG_64K
-+# define MAX_MEM_LEVEL 8
-+# else
-+# define MAX_MEM_LEVEL 9
-+# endif
-+#endif
-+
-+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
-+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
-+ * created by gzip. (Files created by minigzip can still be extracted by
-+ * gzip.)
-+ */
-+#ifndef MAX_WBITS
-+# define MAX_WBITS 15 /* 32K LZ77 window */
-+#endif
-+
-+/* The memory requirements for deflate are (in bytes):
-+ (1 << (windowBits+2)) + (1 << (memLevel+9))
-+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
-+ plus a few kilobytes for small objects. For example, if you want to reduce
-+ the default memory requirements from 256K to 128K, compile with
-+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
-+ Of course this will generally degrade compression (there's no free lunch).
-+
-+ The memory requirements for inflate are (in bytes) 1 << windowBits
-+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
-+ for small objects.
-+*/
-+
-+ /* Type declarations */
-+
-+#ifndef OF /* function prototypes */
-+# ifdef STDC
-+# define OF(args) args
-+# else
-+# define OF(args) ()
-+# endif
-+#endif
-+
-+/* The following definitions for FAR are needed only for MSDOS mixed
-+ * model programming (small or medium model with some far allocations).
-+ * This was tested only with MSC; for other MSDOS compilers you may have
-+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
-+ * just define FAR to be empty.
-+ */
-+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
-+ /* MSC small or medium model */
-+# define SMALL_MEDIUM
-+# ifdef _MSC_VER
-+# define FAR _far
-+# else
-+# define FAR far
-+# endif
-+#endif
-+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
-+# ifndef __32BIT__
-+# define SMALL_MEDIUM
-+# define FAR _far
-+# endif
-+#endif
-+
-+/* Compile with -DZLIB_DLL for Windows DLL support */
-+#if defined(ZLIB_DLL)
-+# if defined(_WINDOWS) || defined(WINDOWS)
-+# ifdef FAR
-+# undef FAR
-+# endif
-+# include <windows.h>
-+# define ZEXPORT WINAPI
-+# ifdef WIN32
-+# define ZEXPORTVA WINAPIV
-+# else
-+# define ZEXPORTVA FAR _cdecl _export
-+# endif
-+# endif
-+# if defined (__BORLANDC__)
-+# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
-+# include <windows.h>
-+# define ZEXPORT __declspec(dllexport) WINAPI
-+# define ZEXPORTRVA __declspec(dllexport) WINAPIV
-+# else
-+# if defined (_Windows) && defined (__DLL__)
-+# define ZEXPORT _export
-+# define ZEXPORTVA _export
-+# endif
-+# endif
-+# endif
-+#endif
-+
-+#if defined (__BEOS__)
-+# if defined (ZLIB_DLL)
-+# define ZEXTERN extern __declspec(dllexport)
-+# else
-+# define ZEXTERN extern __declspec(dllimport)
-+# endif
-+#endif
-+
-+#ifndef ZEXPORT
-+# define ZEXPORT
-+#endif
-+#ifndef ZEXPORTVA
-+# define ZEXPORTVA
-+#endif
-+#ifndef ZEXTERN
-+# define ZEXTERN extern
-+#endif
-+
-+#ifndef FAR
-+# define FAR
-+#endif
-+
-+#if !defined(MACOS) && !defined(TARGET_OS_MAC)
-+typedef unsigned char Byte; /* 8 bits */
-+#endif
-+typedef unsigned int uInt; /* 16 bits or more */
-+typedef unsigned long uLong; /* 32 bits or more */
-+
-+#ifdef SMALL_MEDIUM
-+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
-+# define Bytef Byte FAR
-+#else
-+ typedef Byte FAR Bytef;
-+#endif
-+typedef char FAR charf;
-+typedef int FAR intf;
-+typedef uInt FAR uIntf;
-+typedef uLong FAR uLongf;
-+
-+#ifdef STDC
-+ typedef void FAR *voidpf;
-+ typedef void *voidp;
-+#else
-+ typedef Byte FAR *voidpf;
-+ typedef Byte *voidp;
-+#endif
-+
-+#ifdef HAVE_UNISTD_H
-+# include <sys/types.h> /* for off_t */
-+# include <unistd.h> /* for SEEK_* and off_t */
-+# define z_off_t off_t
-+#endif
-+#ifndef SEEK_SET
-+# define SEEK_SET 0 /* Seek from beginning of file. */
-+# define SEEK_CUR 1 /* Seek from current position. */
-+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
-+#endif
-+#ifndef z_off_t
-+# define z_off_t long
-+#endif
-+
-+/* MVS linker does not support external names larger than 8 bytes */
-+#if defined(__MVS__)
-+# pragma map(deflateInit_,"DEIN")
-+# pragma map(deflateInit2_,"DEIN2")
-+# pragma map(deflateEnd,"DEEND")
-+# pragma map(inflateInit_,"ININ")
-+# pragma map(inflateInit2_,"ININ2")
-+# pragma map(inflateEnd,"INEND")
-+# pragma map(inflateSync,"INSY")
-+# pragma map(inflateSetDictionary,"INSEDI")
-+# pragma map(inflate_blocks,"INBL")
-+# pragma map(inflate_blocks_new,"INBLNE")
-+# pragma map(inflate_blocks_free,"INBLFR")
-+# pragma map(inflate_blocks_reset,"INBLRE")
-+# pragma map(inflate_codes_free,"INCOFR")
-+# pragma map(inflate_codes,"INCO")
-+# pragma map(inflate_fast,"INFA")
-+# pragma map(inflate_flush,"INFLU")
-+# pragma map(inflate_mask,"INMA")
-+# pragma map(inflate_set_dictionary,"INSEDI2")
-+# pragma map(ipcomp_inflate_copyright,"INCOPY")
-+# pragma map(inflate_trees_bits,"INTRBI")
-+# pragma map(inflate_trees_dynamic,"INTRDY")
-+# pragma map(inflate_trees_fixed,"INTRFI")
-+# pragma map(inflate_trees_free,"INTRFR")
-+#endif
-+
-+#endif /* _ZCONF_H */
diff --git a/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh36.12/mkdep.patch b/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh36.12/mkdep.patch
deleted file mode 100644
index 4daeaa11be..0000000000
--- a/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh36.12/mkdep.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-
-#
-# Made by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux/Makefile~mkdep 2003-12-19 09:36:51.000000000 -0800
-+++ linux/Makefile 2003-12-19 09:57:44.000000000 -0800
-@@ -458,7 +458,7 @@
-
- dep-files: scripts/mkdep archdep include/linux/version.h
- scripts/mkdep -- init/*.c > .depend
-- scripts/mkdep -- `find $(FINDHPATH) -name SCCS -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend
-+ $(foreach, dir, $(FINDHPATH), scripts/mkdep -- `find $(dir) -name SCCS -prune -o -follow -name \*.h ! -name modversions.h -print` >> .hdepend)
- $(MAKE) $(patsubst %,_sfdep_%,$(SUBDIRS)) _FASTDEP_ALL_SUB_DIRS="$(SUBDIRS)"
- ifdef CONFIG_MODVERSIONS
- $(MAKE) update-modverfile
diff --git a/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh37.1/defconfig-ipaqsa b/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh37.1/defconfig-ipaqsa
deleted file mode 100644
index c440fd3d59..0000000000
--- a/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh37.1/defconfig-ipaqsa
+++ /dev/null
@@ -1,1508 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_OMAHA is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_MX1ADS is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_RISCSTATION is not set
-CONFIG_ARCH_SA1100=y
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_AT91RM9200DK is not set
-# CONFIG_MINIMAL_OOPS is not set
-
-#
-# Linux As Bootldr support
-#
-# CONFIG_LAB is not set
-# CONFIG_BIG_KERNEL is not set
-# CONFIG_USE_DATE_CODE is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-
-#
-# Archimedes/A5000 Implementations (select only ONE)
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ACCELENT is not set
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CEP is not set
-# CONFIG_SA1100_CERF is not set
-CONFIG_SA1100_H3100=y
-CONFIG_SA1100_H3600=y
-CONFIG_SA1100_H3800=y
-# CONFIG_SA1100_CONSUS is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_FRODO is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_HACKKIT is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_JORNADA56X is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_SIMPUTER is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-CONFIG_SA1100_USB=m
-CONFIG_SA1100_USB_NETLINK=m
-CONFIG_SA1100_USB_CHAR=m
-CONFIG_REGISTERS=m
-
-#
-# Intel PXA250/210 Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_ARCH_PXA_IDP is not set
-# CONFIG_ARCH_PXA_CERF is not set
-# CONFIG_ARCH_H3900 is not set
-# CONFIG_ARCH_H1900 is not set
-# CONFIG_ARCH_H5400 is not set
-# CONFIG_ARCH_H2200 is not set
-# CONFIG_ARCH_AXIM is not set
-# CONFIG_PXA_USB is not set
-# CONFIG_PXA_USB_NETLINK is not set
-# CONFIG_PXA_USB_CHAR is not set
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_FORTUNET is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM922T is not set
-# CONFIG_PLD is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_ARM1026 is not set
-# CONFIG_CPU_SA110 is not set
-CONFIG_CPU_SA1100=y
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
-CONFIG_SA1100_IPAQ=y
-# CONFIG_PXA_IPAQ is not set
-CONFIG_IPAQ_HANDHELD=y
-
-#
-# Compaq iPAQ Handheld
-#
-CONFIG_IPAQ_HAL=m
-CONFIG_H3600_MICRO=m
-CONFIG_IPAQ_HAS_ROSELLA=y
-# CONFIG_IPAQ_HAS_ASIC3 is not set
-CONFIG_H3600_ASIC=m
-CONFIG_H3900_ASIC_DEBUG=y
-# CONFIG_H5400_ASIC is not set
-# CONFIG_H1900_ASIC is not set
-# CONFIG_H1900_TS is not set
-CONFIG_H3600_HARDWARE=y
-CONFIG_IPAQ_SLEEVE=m
-CONFIG_SLEEVE_DEBUG=y
-CONFIG_SLEEVE_DEBUG_VERBOSE=0
-# CONFIG_SLEEVE_IRQ_DEMUX is not set
-
-#
-# Processor Features
-#
-CONFIG_DISCONTIGMEM=y
-
-#
-# General setup
-#
-# CONFIG_PCI is not set
-CONFIG_ISA=y
-# CONFIG_ISA_DMA is not set
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_CPU_FREQ=y
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=m
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_CLPS6700 is not set
-CONFIG_PCMCIA_SA1100=m
-# CONFIG_PCMCIA_PXA is not set
-CONFIG_MERCURY_BACKPAQ=m
-
-#
-# MMC/SD Card support
-#
-CONFIG_MMC=m
-CONFIG_MMC_DEBUG=y
-CONFIG_MMC_DEBUG_VERBOSE=0
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_PM=y
-CONFIG_APM=m
-CONFIG_HWTIMER=m
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="keepinitrd"
-# CONFIG_LEDS is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=1
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_GEOMETRY=y
-# CONFIG_MTD_CFI_B1 is not set
-CONFIG_MTD_CFI_B2=y
-CONFIG_MTD_CFI_B4=y
-# CONFIG_MTD_CFI_B8 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-CONFIG_MTD_IPAQ=y
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-# CONFIG_MTD_SA1100 is not set
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_LUBBOCK is not set
-# CONFIG_MTD_EPXA10DB is not set
-# CONFIG_MTD_FORTUNET is not set
-# CONFIG_MTD_AUTCPU12 is not set
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_H720X is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_CEIVA is not set
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PCMCIA is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-CONFIG_MTD_MTDRAM=m
-CONFIG_MTDRAM_TOTAL_SIZE=4096
-CONFIG_MTDRAM_ERASE_SIZE=128
-CONFIG_MTD_BLKMTD=m
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_NVRD=m
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=y
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-CONFIG_BLK_DEV_LVM=m
-CONFIG_BLK_DEV_DM=m
-
-#
-# Networking options
-#
-CONFIG_PACKET=m
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-# CONFIG_IP_NF_AMANDA is not set
-# CONFIG_IP_NF_TFTP is not set
-CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_MAC=m
-# CONFIG_IP_NF_MATCH_PKTTYPE is not set
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-# CONFIG_IP_NF_MATCH_RECENT is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
-# CONFIG_IP_NF_MATCH_DSCP is not set
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-# CONFIG_IP_NF_MATCH_HELPER is not set
-CONFIG_IP_NF_MATCH_STATE=m
-# CONFIG_IP_NF_MATCH_CONNTRACK is not set
-# CONFIG_IP_NF_MATCH_UNCLEAN is not set
-# CONFIG_IP_NF_MATCH_OWNER is not set
-CONFIG_IP_NF_FILTER=m
-# CONFIG_IP_NF_TARGET_REJECT is not set
-# CONFIG_IP_NF_TARGET_MIRROR is not set
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-# CONFIG_IP_NF_TARGET_ECN is not set
-# CONFIG_IP_NF_TARGET_DSCP is not set
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_ARPTABLES is not set
-CONFIG_IP_NF_COMPAT_IPCHAINS=m
-CONFIG_IP_NF_NAT_NEEDED=y
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-CONFIG_IPV6=m
-CONFIG_IPV6_SUBTREES=y
-CONFIG_IPV6_TUNNEL=m
-CONFIG_IPV6_MOBILITY=m
-CONFIG_IPV6_MOBILITY_MN=m
-# CONFIG_IPV6_MOBILITY_HA is not set
-CONFIG_IPV6_MOBILITY_DEBUG=y
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-# CONFIG_IP6_NF_MATCH_RT is not set
-# CONFIG_IP6_NF_MATCH_OPTS is not set
-# CONFIG_IP6_NF_MATCH_FRAG is not set
-# CONFIG_IP6_NF_MATCH_HL is not set
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-# CONFIG_IP6_NF_MATCH_OWNER is not set
-CONFIG_IP6_NF_MATCH_MARK=m
-# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
-# CONFIG_IP6_NF_MATCH_AHESP is not set
-# CONFIG_IP6_NF_MATCH_LENGTH is not set
-# CONFIG_IP6_NF_MATCH_EUI64 is not set
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-
-#
-#
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_DEV_APPLETALK is not set
-# CONFIG_DECNET is not set
-CONFIG_BRIDGE=m
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_IPSEC=m
-
-#
-# IPSec options (FreeS/WAN)
-#
-CONFIG_KLIPS_AUTH_HMAC_MD5=y
-CONFIG_KLIPS_AUTH_HMAC_SHA1=y
-CONFIG_KLIPS_ENC_3DES=y
-
-#
-# ESP always enabled with tunnel mode
-#
-CONFIG_KLIPS_IPCOMP=y
-CONFIG_KLIPS_DEBUG=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-# CONFIG_PPP_MPPE is not set
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_STRIP is not set
-# CONFIG_WAVELAN is not set
-# CONFIG_ARLAN is not set
-# CONFIG_AIRONET4500 is not set
-# CONFIG_AIRONET4500_NONCS is not set
-# CONFIG_AIRONET4500_PROC is not set
-# CONFIG_AIRO is not set
-# CONFIG_HERMES is not set
-# CONFIG_SPECTRUM24T is not set
-
-#
-# Wireless Pcmcia cards support
-#
-# CONFIG_PCMCIA_HERMES is not set
-# CONFIG_AIRO_CS is not set
-# CONFIG_WVLAN_CS is not set
-# CONFIG_MWVLAN_CS is not set
-# CONFIG_HOSTAP is not set
-# CONFIG_HOSTAP_CS is not set
-CONFIG_NET_WIRELESS=y
-CONFIG_ATMELWLAN=y
-# CONFIG_ATMELWLAN_USB_503A_RFMD is not set
-CONFIG_ATMELWLAN_PCMCIA_502A=m
-CONFIG_ATMELWLAN_PCMCIA_3COM=m
-CONFIG_ATMELWLAN_PCMCIA_502AD=m
-CONFIG_ATMELWLAN_PCMCIA_502AE=m
-CONFIG_ATMELWLAN_PCMCIA_504=m
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_AXNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-# CONFIG_ARCNET_COM20020_CS is not set
-# CONFIG_PCMCIA_IBMTR is not set
-CONFIG_NET_PCMCIA_RADIO=y
-CONFIG_PCMCIA_RAYCS=m
-CONFIG_PCMCIA_NETWAVE=m
-CONFIG_PCMCIA_WAVELAN=m
-# CONFIG_AIRONET4500_CS is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-CONFIG_IRDA_ULTRA=y
-
-#
-# IrDA options
-#
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-CONFIG_IRDA_DEBUG=y
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=m
-CONFIG_IRPORT_SIR=m
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-CONFIG_SA1100_FIR=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=m
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=m
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_IDEDISK_STROKE is not set
-# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-# CONFIG_BLK_DEV_IDEDISK_WD is not set
-# CONFIG_BLK_DEV_COMMERIAL is not set
-# CONFIG_BLK_DEV_TIVO is not set
-CONFIG_BLK_DEV_IDECS=m
-CONFIG_BLK_DEV_IDECD=m
-CONFIG_BLK_DEV_IDETAPE=m
-CONFIG_BLK_DEV_IDEFLOPPY=m
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_DMA_NONPCI is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=m
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-CONFIG_SD_EXTRA_DEVS=40
-CONFIG_CHR_DEV_ST=m
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_SR_EXTRA_DEVS=2
-CONFIG_CHR_DEV_SG=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_DEBUG_QUEUES is not set
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_SIM710 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# PCMCIA SCSI adapter support
-#
-CONFIG_SCSI_PCMCIA=y
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-CONFIG_INPUT=m
-CONFIG_INPUT_KEYBDEV=m
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_JOYDEV=m
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_UINPUT=m
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=m
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_ANAKIN is not set
-# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-# CONFIG_SERIAL_S3C2410 is not set
-# CONFIG_SERIAL_S3C2410_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_UART00 is not set
-# CONFIG_SERIAL_UART00_CONSOLE is not set
-CONFIG_SERIAL_SA1100=y
-CONFIG_SERIAL_SA1100_CONSOLE=y
-CONFIG_SA1100_DEFAULT_BAUDRATE=115200
-CONFIG_SERIAL_H3800_ASIC=m
-# CONFIG_SERIAL_SIR_PXA is not set
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=32
-CONFIG_NEWTONKBD=m
-CONFIG_SA1100_PROFILER=m
-
-#
-# Compaq iPAQ H3600 support
-#
-CONFIG_TOUCHSCREEN_H3600=m
-CONFIG_H3600_BACKPAQ_FPGA=m
-CONFIG_H3600_BACKPAQ_ACCEL=m
-CONFIG_H3600_BACKPAQ_GASGAUGE=m
-CONFIG_H3600_BACKPAQ_SRAM=m
-CONFIG_H3600_BACKPAQ_AUDIO=m
-CONFIG_H3600_STOWAWAY=m
-CONFIG_H3800_MICROKBD=m
-CONFIG_SA1100_LIRC=m
-# CONFIG_H5400_BUZZER is not set
-# CONFIG_H5400_FSI is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# L3 serial bus support
-#
-CONFIG_L3=y
-CONFIG_L3_ALGOBIT=y
-CONFIG_L3_BIT_SA1100_GPIO=y
-
-#
-# Other L3 adapters
-#
-# CONFIG_L3_S3C2410 is not set
-# CONFIG_L3_SA1111 is not set
-CONFIG_L3_BACKPAQ=m
-CONFIG_BIT_SA1100_GPIO=y
-
-#
-# SPI support
-#
-# CONFIG_SPI is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-CONFIG_MOUSE=m
-# CONFIG_PSMOUSE is not set
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-# CONFIG_MK712_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_INPUT_NS558 is not set
-# CONFIG_INPUT_LIGHTNING is not set
-# CONFIG_INPUT_PCIGAME is not set
-# CONFIG_INPUT_CS461X is not set
-# CONFIG_INPUT_EMU10K1 is not set
-CONFIG_INPUT_SERIO=m
-CONFIG_INPUT_SERPORT=m
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_ANALOG is not set
-# CONFIG_INPUT_A3D is not set
-# CONFIG_INPUT_ADI is not set
-# CONFIG_INPUT_COBRA is not set
-# CONFIG_INPUT_GF2K is not set
-# CONFIG_INPUT_GRIP is not set
-# CONFIG_INPUT_INTERACT is not set
-# CONFIG_INPUT_TMDC is not set
-# CONFIG_INPUT_SIDEWINDER is not set
-# CONFIG_INPUT_IFORCE_USB is not set
-# CONFIG_INPUT_IFORCE_232 is not set
-# CONFIG_INPUT_WARRIOR is not set
-# CONFIG_INPUT_MAGELLAN is not set
-# CONFIG_INPUT_SPACEORB is not set
-# CONFIG_INPUT_SPACEBALL is not set
-# CONFIG_INPUT_STINGER is not set
-# CONFIG_INPUT_DB9 is not set
-# CONFIG_INPUT_GAMECON is not set
-# CONFIG_INPUT_TURBOGRAFX is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-# CONFIG_ACQUIRE_WDT is not set
-# CONFIG_ADVANTECH_WDT is not set
-# CONFIG_ALIM7101_WDT is not set
-# CONFIG_SC520_WDT is not set
-# CONFIG_PCWATCHDOG is not set
-# CONFIG_21285_WATCHDOG is not set
-# CONFIG_977_WATCHDOG is not set
-CONFIG_SA1100_WATCHDOG=m
-# CONFIG_PXA_WATCHDOG is not set
-# CONFIG_OMAHA_WATCHDOG is not set
-# CONFIG_EUROTECH_WDT is not set
-# CONFIG_IB700_WDT is not set
-# CONFIG_WAFER_WDT is not set
-# CONFIG_I810_TCO is not set
-# CONFIG_MIXCOMWD is not set
-# CONFIG_60XX_WDT is not set
-# CONFIG_SC1200_WDT is not set
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_W83877F_WDT is not set
-# CONFIG_WDT is not set
-# CONFIG_WDTPCI is not set
-# CONFIG_MACHZ_WDT is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_SA1100_RTC=m
-# CONFIG_PXA_RTC_HACK is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-CONFIG_PCMCIA_SERIAL_CS=m
-# CONFIG_PCMCIA_MOBILISCAN_CS is not set
-# CONFIG_AXIM_KEY_FIX is not set
-
-#
-# Multimedia devices
-#
-CONFIG_MEDIA=m
-CONFIG_VIDEO_DEV=m
-CONFIG_V4L2_DEV=m
-
-#
-# Video For Linux
-#
-CONFIG_VIDEO_PROC_FS=y
-# CONFIG_I2C_PARPORT is not set
-
-#
-# Video Adapters
-#
-# CONFIG_VIDEO_PMS is not set
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIDEO_ZORAN_BUZ is not set
-# CONFIG_VIDEO_ZORAN_DC10 is not set
-# CONFIG_VIDEO_ZORAN_LML33 is not set
-# CONFIG_VIDEO_ZR36120 is not set
-# CONFIG_VIDEO_MEYE is not set
-# CONFIG_VIDEO_CYBERPRO is not set
-CONFIG_VIDEO_H3600_BACKPAQ=m
-# CONFIG_VIDEO_HAWKEYE is not set
-
-#
-# Video for Linux 2 (V4L2)
-#
-CONFIG_VIDEO_WINNOV_CS=m
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_CADET is not set
-# CONFIG_RADIO_RTRACK is not set
-# CONFIG_RADIO_RTRACK2 is not set
-# CONFIG_RADIO_AZTECH is not set
-# CONFIG_RADIO_GEMTEK is not set
-# CONFIG_RADIO_GEMTEK_PCI is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_MAESTRO is not set
-# CONFIG_RADIO_MIROPCM20 is not set
-# CONFIG_RADIO_MIROPCM20_RDS is not set
-# CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_TERRATEC is not set
-# CONFIG_RADIO_TRUST is not set
-# CONFIG_RADIO_TYPHOON is not set
-# CONFIG_RADIO_ZOLTRIX is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=m
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=m
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_UMSDOS_FS=m
-CONFIG_VFAT_FS=m
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-CONFIG_CRAMFS=y
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-CONFIG_ISO9660_FS=m
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DRIVERFS_FS is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=m
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-# CONFIG_ROOT_NFS is not set
-CONFIG_NFSD=m
-CONFIG_NFSD_V3=y
-CONFIG_SUNRPC=m
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-
-#
-# Console drivers
-#
-CONFIG_PC_KEYMAP=y
-# CONFIG_VGA_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_ACORN is not set
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_S3C2410 is not set
-CONFIG_FB_SA1100=y
-# CONFIG_FB_EPSON1356 is not set
-# CONFIG_FB_MQ200 is not set
-# CONFIG_FB_PXA is not set
-# CONFIG_FB_MQ1100 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-CONFIG_FBCON_CFB4=y
-# CONFIG_FBCON_CFB8 is not set
-CONFIG_FBCON_CFB16=y
-# CONFIG_FBCON_CFB24 is not set
-# CONFIG_FBCON_CFB32 is not set
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA_PLANES is not set
-# CONFIG_FBCON_VGA is not set
-# CONFIG_FBCON_HGA is not set
-# CONFIG_FBCON_NO_LOGO is not set
-CONFIG_FBCON_FONTWIDTH8_ONLY=y
-CONFIG_FBCON_FONTS=y
-CONFIG_FONT_8x8=y
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-CONFIG_SOUND_SA1100=m
-CONFIG_SOUND_UDA1341=m
-# CONFIG_SOUND_SA1100_MONO is not set
-# CONFIG_SOUND_ASSABET_UDA1341 is not set
-CONFIG_SOUND_H3600_UDA1341=m
-# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
-# CONFIG_SOUND_SA1111_UDA1341 is not set
-# CONFIG_SOUND_SA1100SSP is not set
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_VIDC is not set
-# CONFIG_SOUND_WAVEARTIST is not set
-# CONFIG_SOUND_PXA_AC97 is not set
-# CONFIG_SOUND_TVMIXER is not set
-
-#
-# Multimedia Capabilities Port drivers
-#
-# CONFIG_MCP is not set
-# CONFIG_MCP_SA1100 is not set
-# CONFIG_MCP_UCB1200 is not set
-# CONFIG_MCP_UCB1200_AUDIO is not set
-# CONFIG_MCP_UCB1200_TS is not set
-# CONFIG_MCP_UCB1400_TS is not set
-
-#
-# Console Switches
-#
-# CONFIG_SWITCHES is not set
-
-#
-# USB support
-#
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_LONG_TIMEOUT is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-# CONFIG_USB_OHCI_SA1111 is not set
-# CONFIG_USB_OHCI_H5400 is not set
-# CONFIG_USB_OHCI_S3C2410 is not set
-CONFIG_USB_SL811HS=m
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_BLUETOOTH is not set
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-CONFIG_USB_PRINTER=m
-
-#
-# USB Human Interface Devices (HID)
-#
-CONFIG_USB_HID=m
-CONFIG_USB_HIDINPUT=y
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_WACOM is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_OV511=m
-CONFIG_USB_PWC=m
-CONFIG_USB_SE401=m
-CONFIG_USB_STV680=m
-CONFIG_USB_VICAM=m
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DABUSB is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-CONFIG_USB_CDCETHER=m
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_BRLVGER is not set
-
-#
-# Linux As Bootldr Modules
-#
-# CONFIG_BIG_KERNEL is not set
-# CONFIG_USE_DATE_CODE is not set
-# CONFIG_YMODEM is not set
-# CONFIG_LAB_DUMMY is not set
-# CONFIG_LAB_CRC is not set
-# CONFIG_LAB_YMODEM is not set
-# CONFIG_LAB_MTD is not set
-# CONFIG_LAB_COPY is not set
-# CONFIG_LAB_COPY_YMODEM is not set
-# CONFIG_LAB_COPY_FLASH is not set
-# CONFIG_LAB_COPY_FS is not set
-# CONFIG_LAB_COPY_WRAPPER is not set
-
-#
-# Bluetooth support
-#
-CONFIG_BLUEZ=m
-CONFIG_BLUEZ_L2CAP=m
-CONFIG_BLUEZ_SCO=m
-CONFIG_BLUEZ_RFCOMM=m
-CONFIG_BLUEZ_RFCOMM_TTY=y
-CONFIG_BLUEZ_BNEP=m
-CONFIG_BLUEZ_BNEP_MC_FILTER=y
-CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
-
-#
-# Bluetooth device drivers
-#
-# CONFIG_BLUEZ_HCIUSB is not set
-CONFIG_BLUEZ_HCIUART=m
-CONFIG_BLUEZ_HCIUART_H4=y
-CONFIG_BLUEZ_HCIUART_BCSP=y
-# CONFIG_BLUEZ_HCIUART_BCSP_TXCRC is not set
-# CONFIG_BLUEZ_HCIBFUSB is not set
-CONFIG_BLUEZ_HCIDTL1=m
-CONFIG_BLUEZ_HCIBT3C=m
-CONFIG_BLUEZ_HCIBLUECARD=m
-CONFIG_BLUEZ_HCIBTUART=m
-# CONFIG_BLUEZ_HCIVHCI is not set
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_NO_PGT_CACHE is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
-
-#
-# Library routines
-#
-# CONFIG_CRC32 is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh37.4/defconfig-ipaqsa b/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh37.4/defconfig-ipaqsa
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/handhelds-sa-2.4.19-rmk6-pxa1-hh37.4/defconfig-ipaqsa
+++ /dev/null
diff --git a/linux/handhelds-sa-2.6/defconfig-jornada56x b/linux/handhelds-sa-2.6/defconfig-jornada56x
deleted file mode 100644
index ebc9a88f2c..0000000000
--- a/linux/handhelds-sa-2.6/defconfig-jornada56x
+++ /dev/null
@@ -1,877 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-# CONFIG_IKCONFIG is not set
-# CONFIG_MINIMAL_OOPS is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODULE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-CONFIG_ARCH_SA1100=y
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE_PB is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_COLLIE is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_BADGE4 is not set
-CONFIG_SA1100_JORNADA56X=y
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HACKKIT is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_STORK is not set
-# CONFIG_SA1100_SSP is not set
-CONFIG_SA1100_USB=y
-CONFIG_SA1100_USB_NETLINK=y
-# CONFIG_SA1100_USB_CHAR is not set
-
-#
-# Linux As Bootloader
-#
-# CONFIG_LAB is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_SA1100=y
-CONFIG_CPU_32v4=y
-CONFIG_CPU_ABRT_EV4=y
-CONFIG_CPU_CACHE_V4WB=y
-CONFIG_CPU_TLB_V4WB=y
-CONFIG_CPU_MINICACHE=y
-
-#
-# Processor Features
-#
-# CONFIG_ARM_FASTCALL is not set
-
-#
-# Compaq/iPAQ Options
-#
-
-#
-# General setup
-#
-CONFIG_DISCONTIGMEM=y
-CONFIG_ISA=y
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-# CONFIG_CPU_FREQ is not set
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=y
-# CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_I82365 is not set
-# CONFIG_TCIC is not set
-CONFIG_PCMCIA_SA1100=y
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-# CONFIG_VFP is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_MISC=y
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
-# CONFIG_SOC_DEVICE is not set
-# CONFIG_DOCKING_HOTPLUG is not set
-CONFIG_PM=y
-CONFIG_PREEMPT=y
-CONFIG_APM=y
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE=""
-# CONFIG_LEDS is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=3
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-CONFIG_MTD_SA1100=y
-# CONFIG_MTD_EDB7312 is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_RAM is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-CONFIG_BT=m
-# CONFIG_BT_L2CAP is not set
-# CONFIG_BT_SCO is not set
-
-#
-# Bluetooth device drivers
-#
-# CONFIG_BT_HCIUART is not set
-CONFIG_BT_HCIDTL1=m
-CONFIG_BT_HCIBT3C=m
-CONFIG_BT_HCIBLUECARD=m
-CONFIG_BT_HCIBTUART=m
-# CONFIG_BT_HCIVHCI is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-CONFIG_MII=m
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-CONFIG_ARLAN=m
-CONFIG_WAVELAN=m
-CONFIG_PCMCIA_WAVELAN=m
-# CONFIG_PCMCIA_NETWAVE is not set
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-# CONFIG_PCMCIA_RAYCS is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-CONFIG_HERMES=m
-# CONFIG_ATMEL is not set
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-CONFIG_PCMCIA_HERMES=m
-CONFIG_AIRO_CS=m
-# CONFIG_PCMCIA_WL3501 is not set
-CONFIG_NET_WIRELESS=y
-# CONFIG_HOSTAP is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-# CONFIG_PCMCIA_AXNET is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-CONFIG_PPP=m
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=m
-CONFIG_BLK_DEV_IDE=m
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_IDEDISK=m
-# CONFIG_IDEDISK_MULTI_MODE is not set
-CONFIG_BLK_DEV_IDECS=m
-CONFIG_BLK_DEV_IDECD=m
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_IDE_TASKFILE_IO is not set
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=m
-# CONFIG_IDE_ARM is not set
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_BLK_DEV_IDEDMA is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
-# CONFIG_INPUT_JOYDEV is not set
-CONFIG_INPUT_TSDEV=y
-CONFIG_INPUT_TSDEV_SCREEN_X=240
-CONFIG_INPUT_TSDEV_SCREEN_Y=320
-# CONFIG_INPUT_TSLIBDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-# CONFIG_SERIAL_DZ is not set
-CONFIG_SERIAL_SA1100=y
-CONFIG_SERIAL_SA1100_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# L3 serial bus support
-#
-# CONFIG_L3 is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-CONFIG_SA1100_RTC=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-# CONFIG_SYNCLINK_CS is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=m
-# CONFIG_EXT2_FS_XATTR is not set
-CONFIG_EXT3_FS=m
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=m
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_REISERFS_FS_XATTR is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=y
-
-#
-# CD-ROM/DVD Filesystems
-#
-CONFIG_ISO9660_FS=m
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-CONFIG_DEVFS_DEBUG=y
-# CONFIG_DEVPTS_FS_XATTR is not set
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
-CONFIG_CRAMFS=m
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
-CONFIG_SUNRPC=m
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-
-#
-# Native Language Support
-#
-CONFIG_NLS=m
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Graphics support
-#
-CONFIG_FB=y
-CONFIG_FB_MODES=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_LCD_DEVICE=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_DEVICE=y
-CONFIG_FB_SA1100=y
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_MDA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-# CONFIG_FONT_8x8 is not set
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-CONFIG_FONT_MINI_4x6=y
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-
-#
-# Logo configuration
-#
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# Misc devices
-#
-
-#
-# SoC drivers
-#
-# CONFIG_BATTERY_MONITOR is not set
-
-#
-# USB support
-#
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_DEBUG_KERNEL is not set
-
-#
-# Security options
-#
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Library routines
-#
-CONFIG_CRC_CCITT=m
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/handhelds-sa-2.6_cvs.bb b/linux/handhelds-sa-2.6_cvs.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/handhelds-sa-2.6_cvs.bb
+++ /dev/null
diff --git a/linux/handhelds-sa_2.4.19-rmk6-pxa1-hh36.12.bb b/linux/handhelds-sa_2.4.19-rmk6-pxa1-hh36.12.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/handhelds-sa_2.4.19-rmk6-pxa1-hh36.12.bb
+++ /dev/null
diff --git a/linux/handhelds-sa_2.4.19-rmk6-pxa1-hh37.1.bb b/linux/handhelds-sa_2.4.19-rmk6-pxa1-hh37.1.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/handhelds-sa_2.4.19-rmk6-pxa1-hh37.1.bb
+++ /dev/null
diff --git a/linux/handhelds-sa_2.4.19-rmk6-pxa1-hh37.4.bb b/linux/handhelds-sa_2.4.19-rmk6-pxa1-hh37.4.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/handhelds-sa_2.4.19-rmk6-pxa1-hh37.4.bb
+++ /dev/null
diff --git a/linux/ipod_2.4.24-ipod0.bb b/linux/ipod_2.4.24-ipod0.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/ipod_2.4.24-ipod0.bb
+++ /dev/null
diff --git a/linux/linux-bast-2.4.25-vrs1-bast1/defconfig b/linux/linux-bast-2.4.25-vrs1-bast1/defconfig
deleted file mode 100644
index 1dc6f19154..0000000000
--- a/linux/linux-bast-2.4.25-vrs1-bast1/defconfig
+++ /dev/null
@@ -1,1115 +0,0 @@
-#
-# Automatically generated by make menuconfig: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_KMOD is not set
-
-#
-# System Type
-#
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_OMAHA is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_MX1ADS is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_RISCSTATION is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
-CONFIG_ARCH_BAST=y
-# CONFIG_ARCH_AT91RM9200 is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ACCELENT is not set
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSAGC is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_ADSBITSYPLUS is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CEP is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_H3XXX is not set
-# CONFIG_H3600_SLEEVE is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_FRODO is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_HACKKIT is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_SIMPUTER is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_USB is not set
-# CONFIG_SA1100_USB_NETLINK is not set
-# CONFIG_SA1100_USB_CHAR is not set
-# CONFIG_SA1100_SSP is not set
-
-#
-# AT91RM9200 Implementations
-#
-# CONFIG_ARCH_AT91RM9200DK is not set
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_FORTUNET is not set
-# CONFIG_ARCH_GUIDEA07 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_PLD is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-CONFIG_CPU_ARM920T=y
-CONFIG_CPU_S3C2410X=y
-# CONFIG_CPU_ARM922T is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_ARM1020E is not set
-# CONFIG_CPU_ARM1022 is not set
-# CONFIG_CPU_ARM1026 is not set
-# CONFIG_CPU_SA110 is not set
-# CONFIG_CPU_SA1100 is not set
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
-# CONFIG_ARM_THUMB is not set
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-# CONFIG_DISCONTIGMEM is not set
-
-#
-# General setup
-#
-# CONFIG_PCI is not set
-CONFIG_ISA=y
-# CONFIG_ISA_DMA is not set
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-# CONFIG_HOTPLUG is not set
-# CONFIG_PCMCIA is not set
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_MISC=y
-# CONFIG_PM is not set
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="root=/dev/hda1 ro"
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-CONFIG_PARPORT=y
-CONFIG_PARPORT_PC=y
-# CONFIG_PARPORT_PC_FIFO is not set
-CONFIG_PARPORT_PC_SUPERIO=y
-# CONFIG_PARPORT_PC_PCMCIA is not set
-# CONFIG_PARPORT_ARC is not set
-# CONFIG_PARPORT_IDP is not set
-# CONFIG_PARPORT_AMIGA is not set
-# CONFIG_PARPORT_MFC3 is not set
-# CONFIG_PARPORT_ATARI is not set
-# CONFIG_PARPORT_GSC is not set
-# CONFIG_PARPORT_SUNBPP is not set
-# CONFIG_PARPORT_IP22 is not set
-CONFIG_PARPORT_OTHER=y
-CONFIG_PARPORT_1284=y
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-CONFIG_MTD_DEBUG=y
-CONFIG_MTD_DEBUG_VERBOSE=1
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_REDBOOT_PARTS=y
-# CONFIG_MTD_CMDLINE_PARTS is not set
-CONFIG_MTD_AFS_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-CONFIG_NFTL=y
-CONFIG_NFTL_RW=y
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_CFI_AMDSTD=y
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_RAM=y
-CONFIG_MTD_ROM=y
-CONFIG_MTD_ABSENT=y
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_NORA is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-# CONFIG_MTD_SA1100 is not set
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_FORTUNET is not set
-# CONFIG_MTD_EPXA is not set
-# CONFIG_MTD_BAST is not set
-# CONFIG_MTD_AUTCPU12 is not set
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_CEIVA is not set
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PCMCIA is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-# CONFIG_MTD_DOC1000 is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
-CONFIG_MTD_NAND_IDS=y
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
-# CONFIG_CISS_MONITOR_THREAD is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_NBD=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_STATS is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_NETFILTER=y
-CONFIG_NETFILTER_DEBUG=y
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-# CONFIG_IPV6 is not set
-# CONFIG_KHTTPD is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-CONFIG_IPV6_SCTP__=y
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_DEV_APPLETALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_ARM_AM79C961A is not set
-# CONFIG_ARM_CIRRUS is not set
-CONFIG_NE2K_BAST=y
-CONFIG_DM9000_BAST=y
-# CONFIG_SUNLANCE is not set
-# CONFIG_SUNBMAC is not set
-# CONFIG_SUNQE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
-CONFIG_NET_ISA=y
-# CONFIG_E2100 is not set
-# CONFIG_EWRK3 is not set
-# CONFIG_EEXPRESS is not set
-# CONFIG_EEXPRESS_PRO is not set
-# CONFIG_HPLAN_PLUS is not set
-# CONFIG_HPLAN is not set
-# CONFIG_LP486E is not set
-# CONFIG_ETH16I is not set
-# CONFIG_NE2000 is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-# CONFIG_PPP is not set
-CONFIG_SLIP=y
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-CONFIG_IRDA=y
-CONFIG_IRLAN=y
-# CONFIG_IRNET is not set
-CONFIG_IRCOMM=y
-CONFIG_IRDA_ULTRA=y
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-CONFIG_IRDA_DEBUG=y
-
-#
-# Infrared-port device drivers
-#
-# CONFIG_IRTTY_SIR is not set
-# CONFIG_IRPORT_SIR is not set
-# CONFIG_DONGLE is not set
-# CONFIG_USB_IRDA is not set
-CONFIG_NSC_FIR=y
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_OLD is not set
-# CONFIG_TOSHIBA_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-# CONFIG_VIA_IRCC_FIR is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=y
-# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_IDEDISK_STROKE is not set
-# CONFIG_BLK_DEV_IDECS is not set
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
-CONFIG_BLK_DEV_IDE_BAST=y
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_DMA_NONPCI is not set
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-# CONFIG_BLK_DEV_ATARAID_SII is not set
-
-#
-# SCSI support
-#
-# CONFIG_SCSI is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-CONFIG_INPUT=y
-CONFIG_INPUT_KEYBDEV=y
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_JOYDEV=y
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_UINPUT is not set
-# CONFIG_INPUT_MX1TS is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-# CONFIG_SERIAL is not set
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_DUMMY_KEYB=y
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_ANAKIN is not set
-# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_UART00 is not set
-# CONFIG_SERIAL_UART00_CONSOLE is not set
-# CONFIG_SERIAL_SA1100 is not set
-# CONFIG_SERIAL_SA1100_CONSOLE is not set
-# CONFIG_SERIAL_OMAHA is not set
-# CONFIG_SERIAL_OMAHA_CONSOLE is not set
-# CONFIG_SERIAL_AT91 is not set
-# CONFIG_SERIAL_AT91_CONSOLE is not set
-CONFIG_SERIAL_S3C2410X=y
-CONFIG_SERIAL_S3C2410X_CONSOLE=y
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-CONFIG_PRINTER=y
-# CONFIG_LP_CONSOLE is not set
-CONFIG_PPDEV=y
-# CONFIG_TIPAR is not set
-
-#
-# I2C support
-#
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-CONFIG_I2C_PHILIPSPAR=y
-# CONFIG_I2C_ELV is not set
-# CONFIG_I2C_VELLEMAN is not set
-# CONFIG_SCx200_I2C is not set
-# CONFIG_I2C_GUIDE is not set
-CONFIG_I2C_S3C2410BIT=y
-# CONFIG_SCx200_ACB is not set
-# CONFIG_I2C_ALGOPCF is not set
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_PROC=y
-# CONFIG_I2C_DS1307 is not set
-
-#
-# L3 serial bus support
-#
-# CONFIG_L3 is not set
-# CONFIG_L3_ALGOBIT is not set
-# CONFIG_L3_BIT_SA1100_GPIO is not set
-# CONFIG_L3_SA1111 is not set
-# CONFIG_BIT_SA1100_GPIO is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-CONFIG_MOUSE=y
-CONFIG_PSMOUSE=y
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-# CONFIG_MK712_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_INPUT_NS558 is not set
-# CONFIG_INPUT_LIGHTNING is not set
-# CONFIG_INPUT_PCIGAME is not set
-# CONFIG_INPUT_CS461X is not set
-# CONFIG_INPUT_EMU10K1 is not set
-# CONFIG_INPUT_SERIO is not set
-# CONFIG_INPUT_SERPORT is not set
-# CONFIG_INPUT_ANALOG is not set
-# CONFIG_INPUT_A3D is not set
-# CONFIG_INPUT_ADI is not set
-# CONFIG_INPUT_COBRA is not set
-# CONFIG_INPUT_GF2K is not set
-# CONFIG_INPUT_GRIP is not set
-# CONFIG_INPUT_INTERACT is not set
-# CONFIG_INPUT_TMDC is not set
-# CONFIG_INPUT_SIDEWINDER is not set
-# CONFIG_INPUT_IFORCE_USB is not set
-# CONFIG_INPUT_IFORCE_232 is not set
-# CONFIG_INPUT_WARRIOR is not set
-# CONFIG_INPUT_MAGELLAN is not set
-# CONFIG_INPUT_SPACEORB is not set
-# CONFIG_INPUT_SPACEBALL is not set
-# CONFIG_INPUT_STINGER is not set
-# CONFIG_INPUT_DB9 is not set
-# CONFIG_INPUT_GAMECON is not set
-# CONFIG_INPUT_TURBOGRAFX is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_IPMI_PANIC_EVENT is not set
-# CONFIG_IPMI_DEVICE_INTERFACE is not set
-# CONFIG_IPMI_KCS is not set
-# CONFIG_IPMI_WATCHDOG is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-# CONFIG_ACQUIRE_WDT is not set
-# CONFIG_ADVANTECH_WDT is not set
-# CONFIG_ALIM1535_WDT is not set
-# CONFIG_ALIM7101_WDT is not set
-# CONFIG_SC520_WDT is not set
-# CONFIG_PCWATCHDOG is not set
-# CONFIG_21285_WATCHDOG is not set
-# CONFIG_977_WATCHDOG is not set
-# CONFIG_SA1100_WATCHDOG is not set
-# CONFIG_EPXA_WATCHDOG is not set
-# CONFIG_OMAHA_WATCHDOG is not set
-CONFIG_S3C2410_WATCHDOG=y
-# CONFIG_AT91_WATCHDOG is not set
-# CONFIG_EUROTECH_WDT is not set
-# CONFIG_IB700_WDT is not set
-# CONFIG_WAFER_WDT is not set
-# CONFIG_I810_TCO is not set
-# CONFIG_MIXCOMWD is not set
-# CONFIG_60XX_WDT is not set
-# CONFIG_SC1200_WDT is not set
-# CONFIG_SCx200_WDT is not set
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_W83877F_WDT is not set
-# CONFIG_WDT is not set
-# CONFIG_WDTPCI is not set
-# CONFIG_MACHZ_WDT is not set
-# CONFIG_AMD7XX_TCO is not set
-# CONFIG_SCx200 is not set
-# CONFIG_SCx200_GPIO is not set
-# CONFIG_AMD_PM768 is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_BAST_RTC=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-
-#
-# Direct Rendering Manager (XFree86 DRI support)
-#
-# CONFIG_DRM is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_QFMT_V2 is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-CONFIG_REISERFS_FS=y
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BEFS_DEBUG is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=y
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=y
-# CONFIG_EFS_FS is not set
-CONFIG_JFFS_FS=y
-CONFIG_JFFS_FS_VERBOSE=0
-CONFIG_JFFS_PROC_FS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_CRAMFS=y
-# CONFIG_TMPFS is not set
-CONFIG_RAMFS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-# CONFIG_JFS_FS is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-CONFIG_ROMFS_FS=y
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_TRACE is not set
-# CONFIG_XFS_DEBUG is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_ROOT_NFS=y
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-# CONFIG_SMB_FS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-CONFIG_ZISOFS_FS=y
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_MINIX_SUBPARTITION=y
-CONFIG_SOLARIS_X86_PARTITION=y
-CONFIG_UNIXWARE_DISKLABEL=y
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-# CONFIG_SMB_NLS is not set
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_CODEPAGE_852=y
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Console drivers
-#
-# CONFIG_VGA_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_ACORN is not set
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_SA1100 is not set
-CONFIG_FB_S3C2410=y
-# CONFIG_FB_DBMX1 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-CONFIG_FBCON_CFB4=y
-CONFIG_FBCON_CFB8=y
-# CONFIG_FBCON_CFB16 is not set
-# CONFIG_FBCON_CFB24 is not set
-# CONFIG_FBCON_CFB32 is not set
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA_PLANES is not set
-# CONFIG_FBCON_VGA is not set
-# CONFIG_FBCON_HGA is not set
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-CONFIG_FONT_ACORN_8x8=y
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_ALI5455 is not set
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_FORTE is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-CONFIG_SOUND_S3C2410=y
-CONFIG_SOUND_S3C2410_TLV320AIC23=y
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_VIDC is not set
-# CONFIG_SOUND_WAVEARTIST is not set
-# CONFIG_SOUND_TVMIXER is not set
-# CONFIG_SOUND_AD1980 is not set
-# CONFIG_SOUND_WM97XX is not set
-
-#
-# Multimedia Capabilities Port drivers
-#
-# CONFIG_MCP is not set
-# CONFIG_MCP_SA1100 is not set
-# CONFIG_MCP_UCB1200 is not set
-# CONFIG_MCP_UCB1200_AUDIO is not set
-# CONFIG_MCP_UCB1200_TS is not set
-
-#
-# USB support
-#
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-# CONFIG_USB_OHCI_SA1111 is not set
-CONFIG_USB_OHCI_S3C2410=y
-# CONFIG_USB_SL811HS_ALT is not set
-# CONFIG_USB_SL811HS is not set
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_BLUETOOTH is not set
-# CONFIG_USB_MIDI is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-CONFIG_USB_PRINTER=y
-CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT=y
-CONFIG_USB_HIDDEV=y
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDCETHER is not set
-CONFIG_USB_USBNET=y
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-CONFIG_USB_SERIAL=y
-# CONFIG_USB_SERIAL_DEBUG is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-CONFIG_USB_SERIAL_FTDI_SIO=y
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_KOBIL_SCT is not set
-CONFIG_USB_SERIAL_PL2303=y
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_TIGL is not set
-# CONFIG_USB_BRLVGER is not set
-# CONFIG_USB_LCD is not set
-
-#
-# Support for USB gadgets
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BLUEZ is not set
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_NO_PGT_CACHE is not set
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SLAB=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_WAITQ=y
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_LL=y
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
-CONFIG_DEBUG_S3C2410X_UART0=y
-
-#
-# Library routines
-#
-# CONFIG_CRC32 is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/linux-bast-2.4.25-vrs1-bast1/mkdep.patch b/linux/linux-bast-2.4.25-vrs1-bast1/mkdep.patch
deleted file mode 100644
index 57218a7d1a..0000000000
--- a/linux/linux-bast-2.4.25-vrs1-bast1/mkdep.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-
-#
-# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux-2.4.25/Makefile~mkdep 2004-03-31 17:15:12.000000000 +0200
-+++ linux-2.4.25/Makefile 2004-03-31 17:18:50.000000000 +0200
-@@ -502,7 +502,7 @@
- ifdef CONFIG_MODVERSIONS
- $(MAKE) update-modverfile
- endif
-- scripts/mkdep -- `find $(FINDHPATH) \( -name SCCS -o -name .svn \) -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend
-+ $(foreach, dir, $(FINDHPATH), scripts/mkdep -- `find $(dir) -name SCCS -prune -o -follow -name \*.h ! -name modversions.h -print` >> .hdepend)
- scripts/mkdep -- init/*.c > .depend
-
- ifdef CONFIG_MODVERSIONS
diff --git a/linux/linux-bast_2.4.25-vrs1-bast1.bb b/linux/linux-bast_2.4.25-vrs1-bast1.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-bast_2.4.25-vrs1-bast1.bb
+++ /dev/null
diff --git a/linux/linux-colinux-2.4.28/colinux-0.6.1.patch b/linux/linux-colinux-2.4.28/colinux-0.6.1.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-colinux-2.4.28/colinux-0.6.1.patch
+++ /dev/null
diff --git a/linux/linux-colinux-2.4.28/defconfig b/linux/linux-colinux-2.4.28/defconfig
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-colinux-2.4.28/defconfig
+++ /dev/null
diff --git a/linux/linux-colinux-2.4.28/gcc-registerparanoia.patch b/linux/linux-colinux-2.4.28/gcc-registerparanoia.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-colinux-2.4.28/gcc-registerparanoia.patch
+++ /dev/null
diff --git a/linux/linux-colinux-2.4.28/gcc340-fixes-v2.4.26-try3.patch b/linux/linux-colinux-2.4.28/gcc340-fixes-v2.4.26-try3.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-colinux-2.4.28/gcc340-fixes-v2.4.26-try3.patch
+++ /dev/null
diff --git a/linux/linux-colinux-2.4.28/linux-2.4.24-attribute-used.patch b/linux/linux-colinux-2.4.28/linux-2.4.24-attribute-used.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-colinux-2.4.28/linux-2.4.24-attribute-used.patch
+++ /dev/null
diff --git a/linux/linux-colinux-2.4.28/nofpu.patch b/linux/linux-colinux-2.4.28/nofpu.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-colinux-2.4.28/nofpu.patch
+++ /dev/null
diff --git a/linux/linux-colinux-2.4.28/shortloadbytes.patch b/linux/linux-colinux-2.4.28/shortloadbytes.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-colinux-2.4.28/shortloadbytes.patch
+++ /dev/null
diff --git a/linux/linux-colinux_2.4.28.bb b/linux/linux-colinux_2.4.28.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-colinux_2.4.28.bb
+++ /dev/null
diff --git a/linux/linux-epia-2.6.8.1/epia_defconfig b/linux/linux-epia-2.6.8.1/epia_defconfig
deleted file mode 100644
index 7984e3c14c..0000000000
--- a/linux/linux-epia-2.6.8.1/epia_defconfig
+++ /dev/null
@@ -1,1480 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_X86=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_GENERIC_ISA_DMA=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# Processor type and features
-#
-CONFIG_X86_PC=y
-# CONFIG_X86_ELAN is not set
-# CONFIG_X86_VOYAGER is not set
-# CONFIG_X86_NUMAQ is not set
-# CONFIG_X86_SUMMIT is not set
-# CONFIG_X86_BIGSMP is not set
-# CONFIG_X86_VISWS is not set
-# CONFIG_X86_GENERICARCH is not set
-# CONFIG_X86_ES7000 is not set
-# CONFIG_M386 is not set
-# CONFIG_M486 is not set
-# CONFIG_M586 is not set
-# CONFIG_M586TSC is not set
-# CONFIG_M586MMX is not set
-# CONFIG_M686 is not set
-# CONFIG_MPENTIUMII is not set
-# CONFIG_MPENTIUMIII is not set
-# CONFIG_MPENTIUMM is not set
-# CONFIG_MPENTIUM4 is not set
-# CONFIG_MK6 is not set
-# CONFIG_MK7 is not set
-# CONFIG_MK8 is not set
-# CONFIG_MCRUSOE is not set
-# CONFIG_MWINCHIPC6 is not set
-# CONFIG_MWINCHIP2 is not set
-# CONFIG_MWINCHIP3D is not set
-CONFIG_MCYRIXIII=y
-# CONFIG_MVIAC3_2 is not set
-# CONFIG_X86_GENERIC is not set
-CONFIG_X86_CMPXCHG=y
-CONFIG_X86_XADD=y
-CONFIG_X86_L1_CACHE_SHIFT=5
-CONFIG_RWSEM_XCHGADD_ALGORITHM=y
-CONFIG_X86_WP_WORKS_OK=y
-CONFIG_X86_INVLPG=y
-CONFIG_X86_BSWAP=y
-CONFIG_X86_POPAD_OK=y
-CONFIG_X86_ALIGNMENT_16=y
-CONFIG_X86_USE_PPRO_CHECKSUM=y
-CONFIG_X86_USE_3DNOW=y
-# CONFIG_HPET_TIMER is not set
-# CONFIG_SMP is not set
-# CONFIG_PREEMPT is not set
-# CONFIG_X86_UP_APIC is not set
-CONFIG_X86_TSC=y
-CONFIG_X86_MCE=y
-# CONFIG_X86_MCE_NONFATAL is not set
-# CONFIG_TOSHIBA is not set
-# CONFIG_I8K is not set
-# CONFIG_MICROCODE is not set
-# CONFIG_X86_MSR is not set
-# CONFIG_X86_CPUID is not set
-
-#
-# Firmware Drivers
-#
-# CONFIG_EDD is not set
-CONFIG_NOHIGHMEM=y
-# CONFIG_HIGHMEM4G is not set
-# CONFIG_HIGHMEM64G is not set
-# CONFIG_MATH_EMULATION is not set
-CONFIG_MTRR=y
-# CONFIG_EFI is not set
-CONFIG_REGPARM=y
-
-#
-# Power management options (ACPI, APM)
-#
-CONFIG_PM=y
-CONFIG_SOFTWARE_SUSPEND=y
-# CONFIG_PM_DISK is not set
-
-#
-# ACPI (Advanced Configuration and Power Interface) Support
-#
-CONFIG_ACPI=y
-CONFIG_ACPI_BOOT=y
-CONFIG_ACPI_INTERPRETER=y
-CONFIG_ACPI_SLEEP=y
-CONFIG_ACPI_SLEEP_PROC_FS=y
-CONFIG_ACPI_AC=y
-CONFIG_ACPI_BATTERY=y
-CONFIG_ACPI_BUTTON=y
-CONFIG_ACPI_FAN=y
-CONFIG_ACPI_PROCESSOR=y
-CONFIG_ACPI_THERMAL=y
-# CONFIG_ACPI_ASUS is not set
-# CONFIG_ACPI_TOSHIBA is not set
-# CONFIG_ACPI_DEBUG is not set
-CONFIG_ACPI_BUS=y
-CONFIG_ACPI_EC=y
-CONFIG_ACPI_POWER=y
-CONFIG_ACPI_PCI=y
-CONFIG_ACPI_SYSTEM=y
-# CONFIG_X86_PM_TIMER is not set
-
-#
-# APM (Advanced Power Management) BIOS Support
-#
-# CONFIG_APM is not set
-
-#
-# CPU Frequency scaling
-#
-CONFIG_CPU_FREQ=y
-# CONFIG_CPU_FREQ_PROC_INTF is not set
-CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
-CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
-# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
-CONFIG_CPU_FREQ_GOV_USERSPACE=y
-# CONFIG_CPU_FREQ_24_API is not set
-CONFIG_CPU_FREQ_TABLE=y
-
-#
-# CPUFreq processor drivers
-#
-CONFIG_X86_ACPI_CPUFREQ=m
-# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
-# CONFIG_X86_POWERNOW_K6 is not set
-# CONFIG_X86_POWERNOW_K7 is not set
-# CONFIG_X86_POWERNOW_K8 is not set
-# CONFIG_X86_GX_SUSPMOD is not set
-# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
-# CONFIG_X86_SPEEDSTEP_ICH is not set
-# CONFIG_X86_SPEEDSTEP_SMI is not set
-# CONFIG_X86_P4_CLOCKMOD is not set
-# CONFIG_X86_LONGRUN is not set
-CONFIG_X86_LONGHAUL=y
-
-#
-# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
-#
-CONFIG_PCI=y
-# CONFIG_PCI_GOBIOS is not set
-# CONFIG_PCI_GOMMCONFIG is not set
-# CONFIG_PCI_GODIRECT is not set
-CONFIG_PCI_GOANY=y
-CONFIG_PCI_BIOS=y
-CONFIG_PCI_DIRECT=y
-CONFIG_PCI_MMCONFIG=y
-# CONFIG_PCI_LEGACY_PROC is not set
-# CONFIG_PCI_NAMES is not set
-CONFIG_ISA=y
-# CONFIG_EISA is not set
-# CONFIG_MCA is not set
-# CONFIG_SCx200 is not set
-
-#
-# PCMCIA/CardBus support
-#
-# CONFIG_PCMCIA is not set
-CONFIG_PCMCIA_PROBE=y
-
-#
-# PCI Hotplug Support
-#
-# CONFIG_HOTPLUG_PCI is not set
-
-#
-# Executable file formats
-#
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_MISC=m
-
-#
-# Device Drivers
-#
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Parallel port support
-#
-CONFIG_PARPORT=m
-CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_CML1=m
-# CONFIG_PARPORT_SERIAL is not set
-# CONFIG_PARPORT_PC_FIFO is not set
-# CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_OTHER is not set
-# CONFIG_PARPORT_1284 is not set
-
-#
-# Plug and Play support
-#
-# CONFIG_PNP is not set
-
-#
-# Block devices
-#
-CONFIG_BLK_DEV_FD=m
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_LBD=y
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_IDE_SATA is not set
-# CONFIG_BLK_DEV_HD_IDE is not set
-CONFIG_BLK_DEV_IDEDISK=y
-CONFIG_IDEDISK_MULTI_MODE=y
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-CONFIG_IDE_TASKFILE_IO=y
-
-#
-# IDE chipset support/bugfixes
-#
-CONFIG_IDE_GENERIC=y
-# CONFIG_BLK_DEV_CMD640 is not set
-CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_IDEPCI_SHARE_IRQ=y
-# CONFIG_BLK_DEV_OFFBOARD is not set
-CONFIG_BLK_DEV_GENERIC=y
-# CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_PCI_AUTO=y
-# CONFIG_IDEDMA_ONLYDISK is not set
-CONFIG_BLK_DEV_ADMA=y
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_ATIIXP is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-# CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SIS5513 is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-CONFIG_BLK_DEV_VIA82CXXX=y
-# CONFIG_IDE_ARM is not set
-# CONFIG_IDE_CHIPSETS is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_IVB is not set
-CONFIG_IDEDMA_AUTO=y
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-CONFIG_CHR_DEV_ST=m
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_CHR_DEV_SG=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI Transport Attributes
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_PPA is not set
-# CONFIG_SCSI_IMM is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-CONFIG_IEEE1394=y
-
-#
-# Subsystem Options
-#
-# CONFIG_IEEE1394_VERBOSEDEBUG is not set
-# CONFIG_IEEE1394_OUI_DB is not set
-CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y
-CONFIG_IEEE1394_CONFIG_ROM_IP1394=y
-
-#
-# Device Drivers
-#
-# CONFIG_IEEE1394_PCILYNX is not set
-CONFIG_IEEE1394_OHCI1394=y
-
-#
-# Protocol Drivers
-#
-CONFIG_IEEE1394_VIDEO1394=m
-CONFIG_IEEE1394_SBP2=m
-# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
-CONFIG_IEEE1394_ETH1394=m
-CONFIG_IEEE1394_DV1394=m
-CONFIG_IEEE1394_RAWIO=m
-CONFIG_IEEE1394_CMP=m
-CONFIG_IEEE1394_AMDTP=m
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-CONFIG_IPV6=y
-# CONFIG_IPV6_PRIVACY is not set
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_IPV6_TUNNEL is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=y
-# CONFIG_IP_NF_FTP is not set
-# CONFIG_IP_NF_IRC is not set
-# CONFIG_IP_NF_TFTP is not set
-# CONFIG_IP_NF_AMANDA is not set
-CONFIG_IP_NF_QUEUE=y
-CONFIG_IP_NF_IPTABLES=y
-CONFIG_IP_NF_MATCH_LIMIT=y
-CONFIG_IP_NF_MATCH_IPRANGE=y
-CONFIG_IP_NF_MATCH_MAC=y
-CONFIG_IP_NF_MATCH_PKTTYPE=y
-CONFIG_IP_NF_MATCH_MARK=y
-CONFIG_IP_NF_MATCH_MULTIPORT=y
-CONFIG_IP_NF_MATCH_TOS=y
-CONFIG_IP_NF_MATCH_RECENT=y
-CONFIG_IP_NF_MATCH_ECN=y
-CONFIG_IP_NF_MATCH_DSCP=y
-CONFIG_IP_NF_MATCH_AH_ESP=y
-CONFIG_IP_NF_MATCH_LENGTH=y
-CONFIG_IP_NF_MATCH_TTL=y
-CONFIG_IP_NF_MATCH_TCPMSS=y
-CONFIG_IP_NF_MATCH_HELPER=y
-CONFIG_IP_NF_MATCH_STATE=y
-CONFIG_IP_NF_MATCH_CONNTRACK=y
-CONFIG_IP_NF_MATCH_OWNER=y
-CONFIG_IP_NF_FILTER=y
-CONFIG_IP_NF_TARGET_REJECT=y
-CONFIG_IP_NF_NAT=y
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=y
-CONFIG_IP_NF_TARGET_REDIRECT=y
-CONFIG_IP_NF_TARGET_NETMAP=y
-CONFIG_IP_NF_TARGET_SAME=y
-# CONFIG_IP_NF_NAT_LOCAL is not set
-# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
-CONFIG_IP_NF_MANGLE=y
-CONFIG_IP_NF_TARGET_TOS=y
-CONFIG_IP_NF_TARGET_ECN=y
-CONFIG_IP_NF_TARGET_DSCP=y
-CONFIG_IP_NF_TARGET_MARK=y
-CONFIG_IP_NF_TARGET_CLASSIFY=y
-CONFIG_IP_NF_TARGET_LOG=y
-CONFIG_IP_NF_TARGET_ULOG=y
-CONFIG_IP_NF_TARGET_TCPMSS=y
-CONFIG_IP_NF_ARPTABLES=y
-CONFIG_IP_NF_ARPFILTER=y
-CONFIG_IP_NF_ARP_MANGLE=y
-# CONFIG_IP_NF_RAW is not set
-# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
-# CONFIG_IP_NF_MATCH_REALM is not set
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-# CONFIG_IP6_NF_IPTABLES is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-CONFIG_BT=m
-CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
-CONFIG_BT_RFCOMM=m
-# CONFIG_BT_RFCOMM_TTY is not set
-CONFIG_BT_BNEP=m
-# CONFIG_BT_BNEP_MC_FILTER is not set
-# CONFIG_BT_BNEP_PROTO_FILTER is not set
-# CONFIG_BT_HIDP is not set
-
-#
-# Bluetooth device drivers
-#
-CONFIG_BT_HCIUSB=m
-CONFIG_BT_HCIUSB_SCO=y
-# CONFIG_BT_HCIUART is not set
-# CONFIG_BT_HCIBCM203X is not set
-# CONFIG_BT_HCIBFUSB is not set
-# CONFIG_BT_HCIVHCI is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-
-#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_CS89x0 is not set
-# CONFIG_DGRS is not set
-# CONFIG_EEPRO100 is not set
-# CONFIG_E100 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-CONFIG_VIA_RHINE=y
-# CONFIG_VIA_RHINE_MMIO is not set
-# CONFIG_VIA_VELOCITY is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_JOYDEV=m
-# CONFIG_INPUT_TSDEV is not set
-CONFIG_INPUT_EVDEV=m
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_I8042=y
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PARKBD is not set
-# CONFIG_SERIO_PCIPS2 is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=y
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=m
-# CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-CONFIG_INPUT_MISC=y
-# CONFIG_INPUT_PCSPKR is not set
-CONFIG_INPUT_UINPUT=m
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_ACPI is not set
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_PRINTER=m
-# CONFIG_LP_CONSOLE is not set
-CONFIG_PPDEV=m
-# CONFIG_TIPAR is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_SONYPI is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-CONFIG_CLE266VGAIO=m
-CONFIG_AGP=y
-# CONFIG_AGP_ALI is not set
-# CONFIG_AGP_ATI is not set
-# CONFIG_AGP_AMD is not set
-# CONFIG_AGP_AMD64 is not set
-# CONFIG_AGP_INTEL is not set
-# CONFIG_AGP_INTEL_MCH is not set
-# CONFIG_AGP_NVIDIA is not set
-# CONFIG_AGP_SIS is not set
-# CONFIG_AGP_SWORKS is not set
-CONFIG_AGP_VIA=y
-# CONFIG_AGP_EFFICEON is not set
-CONFIG_DRM=y
-# CONFIG_DRM_TDFX is not set
-# CONFIG_DRM_GAMMA is not set
-# CONFIG_DRM_R128 is not set
-# CONFIG_DRM_RADEON is not set
-# CONFIG_DRM_MGA is not set
-# CONFIG_DRM_SIS is not set
-CONFIG_DRM_VIA=m
-# CONFIG_DRM_MACH64 is not set
-# CONFIG_MWAVE is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_HPET is not set
-# CONFIG_HANGCHECK_TIMER is not set
-
-#
-# I2C support
-#
-CONFIG_I2C=m
-CONFIG_I2C_CHARDEV=m
-
-#
-# I2C Algorithms
-#
-CONFIG_I2C_ALGOBIT=m
-# CONFIG_I2C_ALGOPCF is not set
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_ELEKTOR is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
-CONFIG_I2C_ISA=m
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_PARPORT is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_SCx200_ACB is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-CONFIG_I2C_VIA=m
-CONFIG_I2C_VIAPRO=m
-# CONFIG_I2C_VOODOO3 is not set
-
-#
-# Hardware Sensors Chip support
-#
-CONFIG_I2C_SENSOR=m
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-
-#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_EEPROM is not set
-CONFIG_SENSORS_VT1211=m
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# Dallas's 1-wire bus
-#
-# CONFIG_W1 is not set
-
-#
-# Misc devices
-#
-# CONFIG_IBM_ASM is not set
-
-#
-# Multimedia devices
-#
-CONFIG_VIDEO_DEV=m
-
-#
-# Video For Linux
-#
-
-#
-# Video Adapters
-#
-# CONFIG_VIDEO_BT848 is not set
-# CONFIG_VIDEO_PMS is not set
-# CONFIG_VIDEO_BWQCAM is not set
-# CONFIG_VIDEO_CQCAM is not set
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_VIDEO_SAA5246A is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIDEO_SAA7134 is not set
-# CONFIG_VIDEO_MXB is not set
-# CONFIG_VIDEO_DPC is not set
-# CONFIG_VIDEO_HEXIUM_ORION is not set
-# CONFIG_VIDEO_HEXIUM_GEMINI is not set
-# CONFIG_VIDEO_CX88 is not set
-# CONFIG_VIDEO_OVCAMCHIP is not set
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_CADET is not set
-# CONFIG_RADIO_RTRACK is not set
-# CONFIG_RADIO_RTRACK2 is not set
-# CONFIG_RADIO_AZTECH is not set
-# CONFIG_RADIO_GEMTEK is not set
-# CONFIG_RADIO_GEMTEK_PCI is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_MAESTRO is not set
-# CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_SF16FMR2 is not set
-# CONFIG_RADIO_TERRATEC is not set
-# CONFIG_RADIO_TRUST is not set
-# CONFIG_RADIO_TYPHOON is not set
-# CONFIG_RADIO_ZOLTRIX is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-CONFIG_DVB=y
-CONFIG_DVB_CORE=m
-
-#
-# Supported Frontend Modules
-#
-# CONFIG_DVB_STV0299 is not set
-# CONFIG_DVB_SP887X is not set
-# CONFIG_DVB_ALPS_TDLB7 is not set
-# CONFIG_DVB_ALPS_TDMB7 is not set
-# CONFIG_DVB_ATMEL_AT76C651 is not set
-# CONFIG_DVB_CX24110 is not set
-# CONFIG_DVB_GRUNDIG_29504_491 is not set
-CONFIG_DVB_GRUNDIG_29504_401=m
-# CONFIG_DVB_MT312 is not set
-# CONFIG_DVB_VES1820 is not set
-# CONFIG_DVB_VES1X93 is not set
-CONFIG_DVB_TDA1004X=m
-CONFIG_DVB_TDA1004X_FIRMWARE_FILE="/usr/lib/hotplug/firmware/tda1004x.bin"
-CONFIG_DVB_NXT6000=m
-
-#
-# Supported SAA7146 based PCI Adapters
-#
-CONFIG_DVB_AV7110=m
-# CONFIG_DVB_AV7110_OSD is not set
-CONFIG_DVB_BUDGET=m
-CONFIG_DVB_BUDGET_CI=m
-# CONFIG_DVB_BUDGET_AV is not set
-CONFIG_DVB_BUDGET_PATCH=m
-
-#
-# Supported USB Adapters
-#
-# CONFIG_DVB_TTUSB_BUDGET is not set
-# CONFIG_DVB_TTUSB_DEC is not set
-
-#
-# Supported FlexCopII (B2C2) Adapters
-#
-# CONFIG_DVB_B2C2_SKYSTAR is not set
-
-#
-# Supported BT878 Adapters
-#
-CONFIG_VIDEO_SAA7146=m
-CONFIG_VIDEO_SAA7146_VV=m
-CONFIG_VIDEO_VIDEOBUF=m
-CONFIG_VIDEO_BUF=m
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-# CONFIG_VIDEO_SELECT is not set
-
-#
-# Console display driver support
-#
-CONFIG_VGA_CONSOLE=y
-# CONFIG_MDA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-
-#
-# Advanced Linux Sound Architecture
-#
-CONFIG_SND=y
-CONFIG_SND_TIMER=y
-CONFIG_SND_PCM=y
-CONFIG_SND_RAWMIDI=y
-CONFIG_SND_SEQUENCER=y
-# CONFIG_SND_SEQ_DUMMY is not set
-CONFIG_SND_OSSEMUL=y
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
-CONFIG_SND_SEQUENCER_OSS=y
-# CONFIG_SND_VERBOSE_PRINTK is not set
-# CONFIG_SND_DEBUG is not set
-
-#
-# Generic devices
-#
-CONFIG_SND_MPU401_UART=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_VIRMIDI is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_MPU401 is not set
-
-#
-# ISA devices
-#
-# CONFIG_SND_AD1848 is not set
-# CONFIG_SND_CS4231 is not set
-# CONFIG_SND_CS4232 is not set
-# CONFIG_SND_CS4236 is not set
-# CONFIG_SND_ES1688 is not set
-# CONFIG_SND_ES18XX is not set
-# CONFIG_SND_GUSCLASSIC is not set
-# CONFIG_SND_GUSEXTREME is not set
-# CONFIG_SND_GUSMAX is not set
-# CONFIG_SND_INTERWAVE is not set
-# CONFIG_SND_INTERWAVE_STB is not set
-# CONFIG_SND_OPTI92X_AD1848 is not set
-# CONFIG_SND_OPTI92X_CS4231 is not set
-# CONFIG_SND_OPTI93X is not set
-# CONFIG_SND_SB8 is not set
-# CONFIG_SND_SB16 is not set
-# CONFIG_SND_SBAWE is not set
-# CONFIG_SND_WAVEFRONT is not set
-# CONFIG_SND_CMI8330 is not set
-# CONFIG_SND_OPL3SA2 is not set
-# CONFIG_SND_SGALAXY is not set
-# CONFIG_SND_SSCAPE is not set
-
-#
-# PCI devices
-#
-CONFIG_SND_AC97_CODEC=y
-# CONFIG_SND_ALI5451 is not set
-# CONFIG_SND_ATIIXP is not set
-# CONFIG_SND_AU8810 is not set
-# CONFIG_SND_AU8820 is not set
-# CONFIG_SND_AU8830 is not set
-# CONFIG_SND_AZT3328 is not set
-# CONFIG_SND_BT87X is not set
-# CONFIG_SND_CS46XX is not set
-# CONFIG_SND_CS4281 is not set
-# CONFIG_SND_EMU10K1 is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_TRIDENT is not set
-# CONFIG_SND_YMFPCI is not set
-# CONFIG_SND_ALS4000 is not set
-# CONFIG_SND_CMIPCI is not set
-# CONFIG_SND_ENS1370 is not set
-# CONFIG_SND_ENS1371 is not set
-# CONFIG_SND_ES1938 is not set
-# CONFIG_SND_ES1968 is not set
-# CONFIG_SND_MAESTRO3 is not set
-# CONFIG_SND_FM801 is not set
-# CONFIG_SND_ICE1712 is not set
-# CONFIG_SND_ICE1724 is not set
-# CONFIG_SND_INTEL8X0 is not set
-# CONFIG_SND_INTEL8X0M is not set
-# CONFIG_SND_SONICVIBES is not set
-CONFIG_SND_VIA82XX=y
-# CONFIG_SND_VX222 is not set
-
-#
-# ALSA USB devices
-#
-# CONFIG_SND_USB_AUDIO is not set
-
-#
-# Open Sound System
-#
-# CONFIG_SOUND_PRIME is not set
-
-#
-# USB support
-#
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-
-#
-# USB Host Controller Drivers
-#
-CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_SPLIT_ISO is not set
-# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-# CONFIG_USB_OHCI_HCD is not set
-CONFIG_USB_UHCI_HCD=y
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_AUDIO is not set
-
-#
-# USB Bluetooth TTY can only be used with disabled Bluetooth subsystem
-#
-# CONFIG_USB_MIDI is not set
-# CONFIG_USB_ACM is not set
-CONFIG_USB_PRINTER=m
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_RW_DETECT is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-CONFIG_USB_HID=y
-CONFIG_USB_HIDINPUT=y
-# CONFIG_HID_FF is not set
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_EGALAX is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_VICAM is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_KONICAWC is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_PWC is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_SN9C102 is not set
-# CONFIG_USB_STV680 is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_TIGL is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETSERVO is not set
-# CONFIG_USB_TEST is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-# CONFIG_EXT2_FS_XATTR is not set
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_XATTR=y
-# CONFIG_EXT3_FS_POSIX_ACL is not set
-# CONFIG_EXT3_FS_SECURITY is not set
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-CONFIG_XFS_FS=y
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_SECURITY is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-CONFIG_AUTOFS4_FS=y
-
-#
-# CD-ROM/DVD Filesystems
-#
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-# CONFIG_ZISOFS is not set
-CONFIG_UDF_FS=y
-CONFIG_UDF_NLS=y
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-CONFIG_TMPFS=y
-# CONFIG_HUGETLBFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-CONFIG_HFSPLUS_FS=m
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-CONFIG_CRAMFS=y
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-# CONFIG_ROOT_NFS is not set
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-CONFIG_MAC_PARTITION=y
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-
-#
-# Native Language Support
-#
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Profiling support
-#
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
-
-#
-# Kernel hacking
-#
-# CONFIG_DEBUG_KERNEL is not set
-CONFIG_EARLY_PRINTK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-# CONFIG_FRAME_POINTER is not set
-# CONFIG_4KSTACKS is not set
-
-#
-# Security options
-#
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_X86_BIOS_REBOOT=y
-CONFIG_PC=y
diff --git a/linux/linux-epia_2.6.8.1.bb b/linux/linux-epia_2.6.8.1.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-epia_2.6.8.1.bb
+++ /dev/null
diff --git a/linux/linux-mtx-1-2.4.24/01-mtd-2004-01-27.diff b/linux/linux-mtx-1-2.4.24/01-mtd-2004-01-27.diff
deleted file mode 100644
index 1a31cb79fb..0000000000
--- a/linux/linux-mtx-1-2.4.24/01-mtd-2004-01-27.diff
+++ /dev/null
@@ -1,51462 +0,0 @@
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/Config.in linux/drivers/mtd/Config.in
---- linux-mips-2.4.24-pre2/drivers/mtd/Config.in 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/Config.in 2004-11-17 18:17:58.809348880 +0100
-@@ -1,5 +1,5 @@
-
--# $Id$
-+# $Id$
-
- mainmenu_option next_comment
- comment 'Memory Technology Devices (MTD)'
-@@ -30,6 +30,7 @@
- if [ "$CONFIG_NFTL" = "y" -o "$CONFIG_NFTL" = "m" ]; then
- bool ' Write support for NFTL (BETA)' CONFIG_NFTL_RW
- fi
-+ dep_tristate ' INFTL (Inverse NAND Flash Translation Layer) support' CONFIG_INFTL $CONFIG_MTD
-
- source drivers/mtd/chips/Config.in
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/Makefile linux/drivers/mtd/Makefile
---- linux-mips-2.4.24-pre2/drivers/mtd/Makefile 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/Makefile 2004-11-17 18:17:58.826346296 +0100
-@@ -1,30 +1,7 @@
- #
- # Makefile for the memory technology device drivers.
- #
--# Note! Dependencies are done automagically by 'make dep', which also
--# removes any old dependencies. DON'T put your own dependencies here
--# unless it's something special (ie not a .c file).
--#
--# Note 2! The CFLAGS definitions are now inherited from the
--# parent makes..
--#
--# $Id$
--
--
--obj-y += chips/chipslink.o maps/mapslink.o \
-- devices/devlink.o nand/nandlink.o
--obj-m :=
--obj-n :=
--obj- :=
--
--O_TARGET := mtdlink.o
--
--export-objs := mtdcore.o mtdpart.o redboot.o cmdlinepart.o afs.o mtdconcat.o
--list-multi := nftl.o
--
--mod-subdirs :=
--subdir-y := chips maps devices nand
--subdir-m := $(subdir-y)
-+# $Id$
-
- # *** BIG UGLY NOTE ***
- #
-@@ -52,15 +29,44 @@
-
- # 'Users' - code which presents functionality to userspace.
- obj-$(CONFIG_MTD_CHAR) += mtdchar.o
--obj-$(CONFIG_MTD_BLOCK) += mtdblock.o
--obj-$(CONFIG_MTD_BLOCK_RO) += mtdblock_ro.o
--obj-$(CONFIG_FTL) += ftl.o
--obj-$(CONFIG_NFTL) += nftl.o
-+obj-$(CONFIG_MTD_BLOCK) += mtdblock.o mtd_blkdevs.o
-+obj-$(CONFIG_MTD_BLOCK_RO) += mtdblock_ro.o mtd_blkdevs.o
-+obj-$(CONFIG_FTL) += ftl.o mtd_blkdevs.o
-+obj-$(CONFIG_NFTL) += nftl.o mtd_blkdevs.o
-+obj-$(CONFIG_INFTL) += inftl.o mtd_blkdevs.o
-
- nftl-objs := nftlcore.o nftlmount.o
-+inftl-objs := inftlcore.o inftlmount.o
-+
-+ifeq ($(PATCHLEVEL),4)
-+
-+export-objs := mtdcore.o mtdpart.o redboot.o cmdlinepart.o afs.o \
-+ mtdconcat.o mtd_blkdevs-24.o
-+
-+mtd_blkdevs-objs := mtd_blkdevs-24.o
-+
-+obj-y += chips/chipslink.o maps/mapslink.o \
-+ devices/devlink.o nand/nandlink.o
-+
-+O_TARGET := mtdlink.o
-+
-+list-multi := nftl.o inftl.o mtd_blkdevs.o
-+
-+mod-subdirs :=
-+subdir-y := chips maps devices nand
-+subdir-m := $(subdir-y)
-
- include $(TOPDIR)/Rules.make
-
- nftl.o: $(nftl-objs)
- $(LD) -r -o $@ $(nftl-objs)
-
-+inftl.o: $(inftl-objs)
-+ $(LD) -r -o $@ $(inftl-objs)
-+
-+mtd_blkdevs.o: $(mtd_blkdevs-objs)
-+ $(LD) -r -o $@ $(mtd_blkdevs-objs)
-+
-+else
-+obj-y += chips/ maps/ devices/ nand/
-+endif
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/afs.c linux/drivers/mtd/afs.c
---- linux-mips-2.4.24-pre2/drivers/mtd/afs.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/afs.c 2004-11-17 18:17:58.827346144 +0100
-@@ -21,7 +21,7 @@
- This is access code for flashes using ARM's flash partitioning
- standards.
-
-- $Id$
-+ $Id$
-
- ======================================================================*/
-
-@@ -76,17 +76,19 @@
- return ret;
- }
-
-+ ret = 1;
-+
- /*
- * Does it contain the magic number?
- */
- if (fs.signature != 0xa0ffff9f)
-- ret = 1;
-+ ret = 0;
-
- /*
- * Don't touch the SIB.
- */
- if (fs.type == 2)
-- ret = 1;
-+ ret = 0;
-
- *iis_start = fs.image_info_base & mask;
- *img_start = fs.image_start & mask;
-@@ -96,14 +98,14 @@
- * be located after the footer structure.
- */
- if (*iis_start >= ptr)
-- ret = 1;
-+ ret = 0;
-
- /*
- * Check the start of this image. The image
- * data can not be located after this block.
- */
- if (*img_start > off)
-- ret = 1;
-+ ret = 0;
-
- return ret;
- }
-@@ -125,7 +127,9 @@
- return ret;
- }
-
--int parse_afs_partitions(struct mtd_info *mtd, struct mtd_partition **pparts)
-+static int parse_afs_partitions(struct mtd_info *mtd,
-+ struct mtd_partition **pparts,
-+ unsigned long origin)
- {
- struct mtd_partition *parts;
- u_int mask, off, idx, sz;
-@@ -150,7 +154,7 @@
- ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask);
- if (ret < 0)
- break;
-- if (ret == 1)
-+ if (ret == 0)
- continue;
-
- ret = afs_read_iis(mtd, &iis, iis_ptr);
-@@ -183,7 +187,7 @@
- ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask);
- if (ret < 0)
- break;
-- if (ret == 1)
-+ if (ret == 0)
- continue;
-
- /* Read the image info block */
-@@ -227,7 +231,25 @@
- return idx ? idx : ret;
- }
-
--EXPORT_SYMBOL(parse_afs_partitions);
-+static struct mtd_part_parser afs_parser = {
-+ .owner = THIS_MODULE,
-+ .parse_fn = parse_afs_partitions,
-+ .name = "afs",
-+};
-+
-+static int __init afs_parser_init(void)
-+{
-+ return register_mtd_parser(&afs_parser);
-+}
-+
-+static void __exit afs_parser_exit(void)
-+{
-+ deregister_mtd_parser(&afs_parser);
-+}
-+
-+module_init(afs_parser_init);
-+module_exit(afs_parser_exit);
-+
-
- MODULE_AUTHOR("ARM Ltd");
- MODULE_DESCRIPTION("ARM Firmware Suite partition parser");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/chips/Config.in linux/drivers/mtd/chips/Config.in
---- linux-mips-2.4.24-pre2/drivers/mtd/chips/Config.in 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/chips/Config.in 2004-11-17 18:17:58.905334288 +0100
-@@ -1,6 +1,6 @@
- # drivers/mtd/chips/Config.in
-
--# $Id$
-+# $Id$
-
- mainmenu_option next_comment
-
-@@ -11,13 +11,12 @@
-
- if [ "$CONFIG_MTD_CFI" = "y" -o "$CONFIG_MTD_JEDECPROBE" = "y" ]; then
- define_bool CONFIG_MTD_GEN_PROBE y
--else
-- if [ "$CONFIG_MTD_CFI" = "m" -o "$CONFIG_MTD_JEDECPROBE" = "m" ]; then
-+elif [ "$CONFIG_MTD_CFI" = "m" -o "$CONFIG_MTD_JEDECPROBE" = "m" ]; then
- define_bool CONFIG_MTD_GEN_PROBE m
-- else
-+else
- define_bool CONFIG_MTD_GEN_PROBE n
-- fi
- fi
-+
- if [ "$CONFIG_MTD_GEN_PROBE" = "y" -o "$CONFIG_MTD_GEN_PROBE" = "m" ]; then
- bool ' Flash chip driver advanced configuration options' CONFIG_MTD_CFI_ADV_OPTIONS
- if [ "$CONFIG_MTD_CFI_ADV_OPTIONS" = "y" ]; then
-@@ -44,8 +43,27 @@
- fi
- dep_tristate ' Support for Intel/Sharp flash chips' CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_GEN_PROBE
- dep_tristate ' Support for AMD/Fujitsu flash chips' CONFIG_MTD_CFI_AMDSTD $CONFIG_MTD_GEN_PROBE
-+if [ "$CONFIG_MTD_CFI_AMDSTD" = "y" -o "$CONFIG_MTD_CFI_AMDSTD" = "m" ]; then
-+ bool ' Retry failed commands (erase/program)' CONFIG_MTD_CFI_AMDSTD_RETRY n
-+ if [ "$CONFIG_MTD_CFI_AMDSTD_RETRY" = "y" ]; then
-+ int ' Max retries of failed commands (erase/program)' CONFIG_MTD_CFI_AMDSTD_RETRY_MAX 0
-+ fi
-+fi
-+
- dep_tristate ' Support for ST (Advanced Architecture) flash chips' CONFIG_MTD_CFI_STAA $CONFIG_MTD_GEN_PROBE
-
-+if [ "$CONFIG_MTD_CFI_INTELEXT" = "y" \
-+ -o "$CONFIG_MTD_CFI_AMDSTD" = "y" \
-+ -o "$CONFIG_MTD_CFI_STAA" = "y" ]; then
-+ define_bool CONFIG_MTD_CFI_UTIL y
-+elif [ "$CONFIG_MTD_CFI_INTELEXT" = "m" \
-+ -o "$CONFIG_MTD_CFI_AMDSTD" = "m" \
-+ -o "$CONFIG_MTD_CFI_STAA" = "m" ]; then
-+ define_bool CONFIG_MTD_CFI_UTIL m
-+else
-+ define_bool CONFIG_MTD_CFI_UTIL n
-+fi
-+
- dep_tristate ' Support for RAM chips in bus mapping' CONFIG_MTD_RAM $CONFIG_MTD
- dep_tristate ' Support for ROM chips in bus mapping' CONFIG_MTD_ROM $CONFIG_MTD
- dep_tristate ' Support for absent chips in bus mapping' CONFIG_MTD_ABSENT $CONFIG_MTD
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/chips/Makefile linux/drivers/mtd/chips/Makefile
---- linux-mips-2.4.24-pre2/drivers/mtd/chips/Makefile 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/chips/Makefile 2004-11-17 18:17:58.907333984 +0100
-@@ -1,11 +1,12 @@
- #
- # linux/drivers/chips/Makefile
- #
--# $Id$
-+# $Id$
-
-+ifeq ($(PATCHLEVEL),4)
- O_TARGET := chipslink.o
--
--export-objs := chipreg.o gen_probe.o
-+export-objs := chipreg.o gen_probe.o cfi_util.o
-+endif
-
- # *** BIG UGLY NOTE ***
- #
-@@ -17,6 +18,7 @@
- obj-$(CONFIG_MTD) += chipreg.o
- obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
- obj-$(CONFIG_MTD_CFI) += cfi_probe.o
-+obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o
- obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o
- obj-$(CONFIG_MTD_CFI_AMDSTD) += cfi_cmdset_0002.o
- obj-$(CONFIG_MTD_CFI_INTELEXT) += cfi_cmdset_0001.o
-@@ -28,4 +30,4 @@
- obj-$(CONFIG_MTD_SHARP) += sharp.o
- obj-$(CONFIG_MTD_ABSENT) += map_absent.o
-
--include $(TOPDIR)/Rules.make
-+-include $(TOPDIR)/Rules.make
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/chips/amd_flash.c linux/drivers/mtd/chips/amd_flash.c
---- linux-mips-2.4.24-pre2/drivers/mtd/chips/amd_flash.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/chips/amd_flash.c 2004-11-17 18:17:58.909333680 +0100
-@@ -3,7 +3,7 @@
- *
- * Author: Jonas Holmberg <jonas.holmberg@axis.com>
- *
-- * $Id$
-+ * $Id$
- *
- * Copyright (c) 2001 Axis Communications AB
- *
-@@ -19,6 +19,7 @@
- #include <linux/slab.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
-+#include <linux/init.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/flashchip.h>
-@@ -125,10 +126,10 @@
-
-
- static struct mtd_chip_driver amd_flash_chipdrv = {
-- probe: amd_flash_probe,
-- destroy: amd_flash_destroy,
-- name: "amd_flash",
-- module: THIS_MODULE
-+ .probe = amd_flash_probe,
-+ .destroy = amd_flash_destroy,
-+ .name = "amd_flash",
-+ .module = THIS_MODULE
- };
-
-
-@@ -140,11 +141,11 @@
- static inline __u32 wide_read(struct map_info *map, __u32 addr)
- {
- if (map->buswidth == 1) {
-- return map->read8(map, addr);
-+ return map_read8(map, addr);
- } else if (map->buswidth == 2) {
-- return map->read16(map, addr);
-+ return map_read16(map, addr);
- } else if (map->buswidth == 4) {
-- return map->read32(map, addr);
-+ return map_read32(map, addr);
- }
-
- return 0;
-@@ -153,11 +154,11 @@
- static inline void wide_write(struct map_info *map, __u32 val, __u32 addr)
- {
- if (map->buswidth == 1) {
-- map->write8(map, val, addr);
-+ map_write8(map, val, addr);
- } else if (map->buswidth == 2) {
-- map->write16(map, val, addr);
-+ map_write16(map, val, addr);
- } else if (map->buswidth == 4) {
-- map->write32(map, val, addr);
-+ map_write32(map, val, addr);
- }
- }
-
-@@ -424,231 +425,228 @@
-
- static struct mtd_info *amd_flash_probe(struct map_info *map)
- {
-- /* Keep this table on the stack so that it gets deallocated after the
-- * probe is done.
-- */
-- const struct amd_flash_info table[] = {
-+ static const struct amd_flash_info table[] = {
- {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV160DT,
-- name: "AMD AM29LV160DT",
-- size: 0x00200000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
-- { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 }
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV160DT,
-+ .name = "AMD AM29LV160DT",
-+ .size = 0x00200000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
-+ { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 }
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV160DB,
-- name: "AMD AM29LV160DB",
-- size: 0x00200000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },
-- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV160DB,
-+ .name = "AMD AM29LV160DB",
-+ .size = 0x00200000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 },
-+ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 }
- }
- }, {
-- mfr_id: MANUFACTURER_TOSHIBA,
-- dev_id: TC58FVT160,
-- name: "Toshiba TC58FVT160",
-- size: 0x00200000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
-- { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 }
-+ .mfr_id = MANUFACTURER_TOSHIBA,
-+ .dev_id = TC58FVT160,
-+ .name = "Toshiba TC58FVT160",
-+ .size = 0x00200000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
-+ { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 }
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV160TE,
-- name: "Fujitsu MBM29LV160TE",
-- size: 0x00200000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
-- { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 }
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV160TE,
-+ .name = "Fujitsu MBM29LV160TE",
-+ .size = 0x00200000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
-+ { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 }
- }
- }, {
-- mfr_id: MANUFACTURER_TOSHIBA,
-- dev_id: TC58FVB160,
-- name: "Toshiba TC58FVB160",
-- size: 0x00200000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },
-- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
-+ .mfr_id = MANUFACTURER_TOSHIBA,
-+ .dev_id = TC58FVB160,
-+ .name = "Toshiba TC58FVB160",
-+ .size = 0x00200000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 },
-+ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 }
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV160BE,
-- name: "Fujitsu MBM29LV160BE",
-- size: 0x00200000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },
-- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV160BE,
-+ .name = "Fujitsu MBM29LV160BE",
-+ .size = 0x00200000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 },
-+ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 }
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV800BB,
-- name: "AMD AM29LV800BB",
-- size: 0x00100000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },
-- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x010000, erasesize: 0x10000, numblocks: 15 }
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV800BB,
-+ .name = "AMD AM29LV800BB",
-+ .size = 0x00100000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 },
-+ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 15 }
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F800BB,
-- name: "AMD AM29F800BB",
-- size: 0x00100000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },
-- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x010000, erasesize: 0x10000, numblocks: 15 }
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F800BB,
-+ .name = "AMD AM29F800BB",
-+ .size = 0x00100000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 },
-+ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 15 }
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV800BT,
-- name: "AMD AM29LV800BT",
-- size: 0x00100000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
-- { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 }
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV800BT,
-+ .name = "AMD AM29LV800BT",
-+ .size = 0x00100000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 },
-+ { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 }
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F800BT,
-- name: "AMD AM29F800BT",
-- size: 0x00100000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
-- { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 }
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F800BT,
-+ .name = "AMD AM29F800BT",
-+ .size = 0x00100000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 },
-+ { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 }
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV800BB,
-- name: "AMD AM29LV800BB",
-- size: 0x00100000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
-- { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 }
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV800BB,
-+ .name = "AMD AM29LV800BB",
-+ .size = 0x00100000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 },
-+ { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 }
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV800BB,
-- name: "Fujitsu MBM29LV800BB",
-- size: 0x00100000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },
-- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x010000, erasesize: 0x10000, numblocks: 15 }
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV800BB,
-+ .name = "Fujitsu MBM29LV800BB",
-+ .size = 0x00100000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 },
-+ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 15 }
- }
- }, {
-- mfr_id: MANUFACTURER_ST,
-- dev_id: M29W800T,
-- name: "ST M29W800T",
-- size: 0x00100000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
-- { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 }
-+ .mfr_id = MANUFACTURER_ST,
-+ .dev_id = M29W800T,
-+ .name = "ST M29W800T",
-+ .size = 0x00100000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 },
-+ { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 }
- }
- }, {
-- mfr_id: MANUFACTURER_ST,
-- dev_id: M29W160DT,
-- name: "ST M29W160DT",
-- size: 0x00200000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
-- { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 }
-+ .mfr_id = MANUFACTURER_ST,
-+ .dev_id = M29W160DT,
-+ .name = "ST M29W160DT",
-+ .size = 0x00200000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
-+ { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 }
- }
- }, {
-- mfr_id: MANUFACTURER_ST,
-- dev_id: M29W160DB,
-- name: "ST M29W160DB",
-- size: 0x00200000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },
-- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
-+ .mfr_id = MANUFACTURER_ST,
-+ .dev_id = M29W160DB,
-+ .name = "ST M29W160DB",
-+ .size = 0x00200000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 },
-+ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 }
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29BDS323D,
-- name: "AMD AM29BDS323D",
-- size: 0x00400000,
-- numeraseregions: 3,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 48 },
-- { offset: 0x300000, erasesize: 0x10000, numblocks: 15 },
-- { offset: 0x3f0000, erasesize: 0x02000, numblocks: 8 },
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29BDS323D,
-+ .name = "AMD AM29BDS323D",
-+ .size = 0x00400000,
-+ .numeraseregions = 3,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 48 },
-+ { .offset = 0x300000, .erasesize = 0x10000, .numblocks = 15 },
-+ { .offset = 0x3f0000, .erasesize = 0x02000, .numblocks = 8 },
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29BDS643D,
-- name: "AMD AM29BDS643D",
-- size: 0x00800000,
-- numeraseregions: 3,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 96 },
-- { offset: 0x600000, erasesize: 0x10000, numblocks: 31 },
-- { offset: 0x7f0000, erasesize: 0x02000, numblocks: 8 },
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29BDS643D,
-+ .name = "AMD AM29BDS643D",
-+ .size = 0x00800000,
-+ .numeraseregions = 3,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 96 },
-+ { .offset = 0x600000, .erasesize = 0x10000, .numblocks = 31 },
-+ { .offset = 0x7f0000, .erasesize = 0x02000, .numblocks = 8 },
- }
- }, {
-- mfr_id: MANUFACTURER_ATMEL,
-- dev_id: AT49xV16x,
-- name: "Atmel AT49xV16x",
-- size: 0x00200000,
-- numeraseregions: 2,
-- regions: {
-- { offset: 0x000000, erasesize: 0x02000, numblocks: 8 },
-- { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
-+ .mfr_id = MANUFACTURER_ATMEL,
-+ .dev_id = AT49xV16x,
-+ .name = "Atmel AT49xV16x",
-+ .size = 0x00200000,
-+ .numeraseregions = 2,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x02000, .numblocks = 8 },
-+ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 }
- }
- }, {
-- mfr_id: MANUFACTURER_ATMEL,
-- dev_id: AT49xV16xT,
-- name: "Atmel AT49xV16xT",
-- size: 0x00200000,
-- numeraseregions: 2,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
-- { offset: 0x1F0000, erasesize: 0x02000, numblocks: 8 }
-+ .mfr_id = MANUFACTURER_ATMEL,
-+ .dev_id = AT49xV16xT,
-+ .name = "Atmel AT49xV16xT",
-+ .size = 0x00200000,
-+ .numeraseregions = 2,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
-+ { .offset = 0x1F0000, .erasesize = 0x02000, .numblocks = 8 }
- }
- }
- };
-@@ -822,7 +820,7 @@
-
- chip->state = FL_READY;
-
-- map->copy_from(map, buf, adr, len);
-+ map_copy_from(map, buf, adr, len);
-
- wake_up(&chip->wq);
- spin_unlock_bh(chip->mutex);
-@@ -984,7 +982,7 @@
- u_char tmp_buf[4];
- __u32 datum;
-
-- map->copy_from(map, tmp_buf,
-+ map_copy_from(map, tmp_buf,
- bus_ofs + private->chips[chipnum].start,
- map->buswidth);
- while (len && i < map->buswidth)
-@@ -1057,7 +1055,7 @@
- u_char tmp_buf[2];
- __u32 datum;
-
-- map->copy_from(map, tmp_buf,
-+ map_copy_from(map, tmp_buf,
- ofs + private->chips[chipnum].start,
- map->buswidth);
- while (len--) {
-@@ -1178,7 +1176,7 @@
- __u8 verify;
-
- for (address = adr; address < (adr + size); address++) {
-- if ((verify = map->read8(map, address)) != 0xFF) {
-+ if ((verify = map_read8(map, address)) != 0xFF) {
- error = 1;
- break;
- }
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/chips/cfi_cmdset_0001.c linux/drivers/mtd/chips/cfi_cmdset_0001.c
---- linux-mips-2.4.24-pre2/drivers/mtd/chips/cfi_cmdset_0001.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/chips/cfi_cmdset_0001.c 2004-11-17 18:17:58.910333528 +0100
-@@ -4,7 +4,7 @@
- *
- * (C) 2000 Red Hat. GPL'd
- *
-- * $Id$
-+ * $Id$
- *
- *
- * 10/10/2000 Nicolas Pitre <nico@cam.org>
-@@ -21,6 +21,7 @@
- #include <linux/types.h>
- #include <linux/kernel.h>
- #include <linux/sched.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <asm/byteorder.h>
-
-@@ -29,10 +30,14 @@
- #include <linux/delay.h>
- #include <linux/interrupt.h>
- #include <linux/mtd/map.h>
--#include <linux/mtd/cfi.h>
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/compatmac.h>
-+#include <linux/mtd/cfi.h>
-+
-+/* #define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE */
-
--// debugging, turns off buffer write mode #define FORCE_WORD_WRITE
-+// debugging, turns off buffer write mode if set to 1
-+#define FORCE_WORD_WRITE 0
-
- static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
- static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
-@@ -52,16 +57,21 @@
-
- static struct mtd_info *cfi_intelext_setup (struct map_info *);
-
--static int do_point (struct mtd_info *mtd, loff_t from, size_t len,
-+static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len,
- size_t *retlen, u_char **mtdbuf);
--static void do_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from,
-+static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from,
- size_t len);
-
-+
-+/*
-+ * *********** SETUP AND PROBE BITS ***********
-+ */
-+
- static struct mtd_chip_driver cfi_intelext_chipdrv = {
-- probe: NULL, /* Not usable directly */
-- destroy: cfi_intelext_destroy,
-- name: "cfi_cmdset_0001",
-- module: THIS_MODULE
-+ .probe = NULL, /* Not usable directly */
-+ .destroy = cfi_intelext_destroy,
-+ .name = "cfi_cmdset_0001",
-+ .module = THIS_MODULE
- };
-
- /* #define DEBUG_LOCK_BITS */
-@@ -102,13 +112,63 @@
- }
-
- printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n",
-- extp->VccOptimal >> 8, extp->VccOptimal & 0xf);
-+ extp->VccOptimal >> 4, extp->VccOptimal & 0xf);
- if (extp->VppOptimal)
- printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n",
-- extp->VppOptimal >> 8, extp->VppOptimal & 0xf);
-+ extp->VppOptimal >> 4, extp->VppOptimal & 0xf);
- }
- #endif
-
-+#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
-+/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */
-+static void fixup_intel_strataflash(struct map_info *map, void* param)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ struct cfi_pri_amdstd *extp = cfi->cmdset_priv;
-+
-+ printk(KERN_WARNING "cfi_cmdset_0001: Suspend "
-+ "erase on write disabled.\n");
-+ extp->SuspendCmdSupport &= ~1;
-+}
-+#endif
-+
-+static void fixup_st_m28w320ct(struct map_info *map, void* param)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+
-+ cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */
-+ cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */
-+}
-+
-+static void fixup_st_m28w320cb(struct map_info *map, void* param)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+
-+ /* Note this is done after the region info is endian swapped */
-+ cfi->cfiq->EraseRegionInfo[1] =
-+ (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e;
-+};
-+
-+static struct cfi_fixup fixup_table[] = {
-+#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
-+ {
-+ CFI_MFR_ANY, CFI_ID_ANY,
-+ fixup_intel_strataflash, NULL
-+ },
-+#endif
-+ {
-+ 0x0020, /* STMicroelectronics */
-+ 0x00ba, /* M28W320CT */
-+ fixup_st_m28w320ct, NULL
-+ }, {
-+ 0x0020, /* STMicroelectronics */
-+ 0x00bb, /* M28W320CB */
-+ fixup_st_m28w320cb, NULL
-+ }, {
-+ 0, 0, NULL, NULL
-+ }
-+};
-+
- /* This routine is made available to other mtd code via
- * inter_module_register. It must only be accessed through
- * inter_module_get which will bump the use count of this module. The
-@@ -120,7 +180,6 @@
- {
- struct cfi_private *cfi = map->fldrv_priv;
- int i;
-- __u32 base = cfi->chips[0].start;
-
- if (cfi->cfi_mode == CFI_MODE_CFI) {
- /*
-@@ -130,59 +189,29 @@
- */
- __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
- struct cfi_pri_intelext *extp;
-- int ofs_factor = cfi->interleave * cfi->device_type;
--
-- //printk(" Intel/Sharp Extended Query Table at 0x%4.4X\n", adr);
-- if (!adr)
-- return NULL;
-
-- /* Switch it into Query Mode */
-- cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
--
-- extp = kmalloc(sizeof(*extp), GFP_KERNEL);
-- if (!extp) {
-- printk(KERN_ERR "Failed to allocate memory\n");
-+ extp = (struct cfi_pri_intelext*)cfi_read_pri(map, adr, sizeof(*extp), "Intel/Sharp");
-+ if (!extp)
- return NULL;
-- }
--
-- /* Read in the Extended Query Table */
-- for (i=0; i<sizeof(*extp); i++) {
-- ((unsigned char *)extp)[i] =
-- cfi_read_query(map, (base+((adr+i)*ofs_factor)));
-- }
--
-- if (extp->MajorVersion != '1' ||
-- (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
-- printk(KERN_WARNING " Unknown IntelExt Extended Query "
-- "version %c.%c.\n", extp->MajorVersion,
-- extp->MinorVersion);
-- kfree(extp);
-- return NULL;
-- }
-
- /* Do some byteswapping if necessary */
- extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport);
- extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask);
- extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr);
-
-+ /* Install our own private info structure */
-+ cfi->cmdset_priv = extp;
-+
-+ cfi_fixup(map, fixup_table);
-+
- #ifdef DEBUG_CFI_FEATURES
- /* Tell the user about it in lots of lovely detail */
- cfi_tell_features(extp);
- #endif
-
- if(extp->SuspendCmdSupport & 1) {
--//#define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
--#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
--/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */
-- printk(KERN_WARNING "cfi_cmdset_0001: Suspend "
-- "erase on write disabled.\n");
-- extp->SuspendCmdSupport &= ~1;
--#else
- printk(KERN_NOTICE "cfi_cmdset_0001: Erase suspend on write enabled\n");
--#endif
- }
-- /* Install our own private info structure */
-- cfi->cmdset_priv = extp;
- }
-
- for (i=0; i< cfi->numchips; i++) {
-@@ -194,8 +223,6 @@
-
- map->fldrv = &cfi_intelext_chipdrv;
-
-- /* Make sure it's in read mode */
-- cfi_send_gen_cmd(0xff, 0x55, base, map, cfi, cfi->device_type, NULL);
- return cfi_intelext_setup(map);
- }
-
-@@ -261,20 +288,16 @@
- mtd->erase = cfi_intelext_erase_varsize;
- mtd->read = cfi_intelext_read;
-
-- if(map->point && map->unpoint){
-- mtd->point = do_point;
-- mtd->unpoint = do_unpoint;
-+ if (map_is_linear(map)) {
-+ mtd->point = cfi_intelext_point;
-+ mtd->unpoint = cfi_intelext_unpoint;
- }
-
--#ifndef FORCE_WORD_WRITE
-- if ( cfi->cfiq->BufWriteTimeoutTyp ) {
-- printk("Using buffer write method\n" );
-+ if ( cfi->cfiq->BufWriteTimeoutTyp && !FORCE_WORD_WRITE) {
-+ printk(KERN_INFO "Using buffer write method\n" );
- mtd->write = cfi_intelext_write_buffers;
- } else {
--#else
-- {
--#endif
-- printk("Using word write method\n" );
-+ printk(KERN_INFO "Using word write method\n" );
- mtd->write = cfi_intelext_write_words;
- }
- mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg;
-@@ -286,8 +309,8 @@
- mtd->resume = cfi_intelext_resume;
- mtd->flags = MTD_CAP_NORFLASH;
- map->fldrv = &cfi_intelext_chipdrv;
-- MOD_INC_USE_COUNT;
- mtd->name = map->name;
-+ __module_get(THIS_MODULE);
- return mtd;
-
- setup_err:
-@@ -301,78 +324,170 @@
- return NULL;
- }
-
--static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
-+/*
-+ * *********** CHIP ACCESS FUNCTIONS ***********
-+ */
-+
-+static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
- {
-- cfi_word status, status_OK;
-- unsigned long timeo;
- DECLARE_WAITQUEUE(wait, current);
-- unsigned long cmd_addr;
- struct cfi_private *cfi = map->fldrv_priv;
-+ cfi_word status, status_OK = CMD(0x80);
-+ unsigned long timeo;
-+ struct cfi_pri_intelext *cfip = (struct cfi_pri_intelext *)cfi->cmdset_priv;
-
-- adr += chip->start;
--
-- /* Ensure cmd read/writes are aligned. */
-- cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1);
--
-- /* Let's determine this according to the interleave only once */
-- status_OK = CMD(0x80);
--
-+ resettime:
- timeo = jiffies + HZ;
- retry:
-- spin_lock(chip->mutex);
--
-- /* Check that the chip's ready to talk to us.
-- * If it's in FL_ERASING state, suspend it and make it talk now.
-- */
- switch (chip->state) {
-
-- case FL_READY:
-- case FL_POINT:
-+ case FL_STATUS:
-+ for (;;) {
-+ status = cfi_read(map, adr);
-+ if ((status & status_OK) == status_OK)
- break;
-
-+ if (time_after(jiffies, timeo)) {
-+ printk(KERN_ERR "Waiting for chip to be ready timed out. Status %llx\n",
-+ (long long)status);
-+ spin_unlock(chip->mutex);
-+ return -EIO;
-+ }
-+ spin_unlock(chip->mutex);
-+ cfi_udelay(1);
-+ spin_lock(chip->mutex);
-+ /* Someone else might have been playing with it. */
-+ goto retry;
-+ }
-+
-+ case FL_READY:
- case FL_CFI_QUERY:
- case FL_JEDEC_QUERY:
-- cfi_write(map, CMD(0x70), cmd_addr);
-- chip->state = FL_STATUS;
-+ return 0;
-
-- case FL_STATUS:
-- status = cfi_read(map, cmd_addr);
-- if ((status & status_OK) == status_OK) {
-- cfi_write(map, CMD(0xff), cmd_addr);
-- chip->state = FL_READY;
-+ case FL_ERASING:
-+ if (!(cfip->FeatureSupport & 2) ||
-+ !(mode == FL_READY || mode == FL_POINT ||
-+ (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1))))
-+ goto sleep;
-+
-+
-+ /* Erase suspend */
-+ cfi_write(map, CMD(0xB0), adr);
-+
-+ /* If the flash has finished erasing, then 'erase suspend'
-+ * appears to make some (28F320) flash devices switch to
-+ * 'read' mode. Make sure that we switch to 'read status'
-+ * mode so we get the right data. --rmk
-+ */
-+ cfi_write(map, CMD(0x70), adr);
-+ chip->oldstate = FL_ERASING;
-+ chip->state = FL_ERASE_SUSPENDING;
-+ chip->erase_suspended = 1;
-+ for (;;) {
-+ status = cfi_read(map, adr);
-+ if ((status & status_OK) == status_OK)
- break;
-- }
-
-- /* Urgh. Chip not yet ready to talk to us. */
- if (time_after(jiffies, timeo)) {
-- spin_unlock(chip->mutex);
-- printk(KERN_ERR "waiting for chip to be ready timed out in read. WSM status = %llx\n", (__u64)status);
-+ /* Urgh. Resume and pretend we weren't here. */
-+ cfi_write(map, CMD(0xd0), adr);
-+ /* Make sure we're in 'read status' mode if it had finished */
-+ cfi_write(map, CMD(0x70), adr);
-+ chip->state = FL_ERASING;
-+ chip->oldstate = FL_READY;
-+ printk(KERN_ERR "Chip not ready after erase "
-+ "suspended: status = 0x%x\n", status);
- return -EIO;
- }
-
-- /* Latency issues. Drop the lock, wait a while and retry */
- spin_unlock(chip->mutex);
- cfi_udelay(1);
-- goto retry;
-+ spin_lock(chip->mutex);
-+ /* Nobody will touch it while it's in state FL_ERASE_SUSPENDING.
-+ So we can just loop here. */
-+ }
-+ chip->state = FL_STATUS;
-+ return 0;
-+
-+ case FL_POINT:
-+ /* Only if there's no operation suspended... */
-+ if (mode == FL_READY && chip->oldstate == FL_READY)
-+ return 0;
-
- default:
-- /* Stick ourselves on a wait queue to be woken when
-- someone changes the status */
-+ sleep:
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&chip->wq, &wait);
- spin_unlock(chip->mutex);
- schedule();
- remove_wait_queue(&chip->wq, &wait);
-- timeo = jiffies + HZ;
-- goto retry;
-+ spin_lock(chip->mutex);
-+ goto resettime;
- }
-+}
-+
-+static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+
-+ switch(chip->oldstate) {
-+ case FL_ERASING:
-+ chip->state = chip->oldstate;
-+ /* What if one interleaved chip has finished and the
-+ other hasn't? The old code would leave the finished
-+ one in READY mode. That's bad, and caused -EROFS
-+ errors to be returned from do_erase_oneblock because
-+ that's the only bit it checked for at the time.
-+ As the state machine appears to explicitly allow
-+ sending the 0x70 (Read Status) command to an erasing
-+ chip and expecting it to be ignored, that's what we
-+ do. */
-+ cfi_write(map, CMD(0xd0), adr);
-+ cfi_write(map, CMD(0x70), adr);
-+ chip->oldstate = FL_READY;
-+ chip->state = FL_ERASING;
-+ break;
-+
-+ case FL_READY:
-+ case FL_STATUS:
-+ /* We should really make set_vpp() count, rather than doing this */
-+ DISABLE_VPP(map);
-+ break;
-+ default:
-+ printk(KERN_ERR "put_chip() called with oldstate %d!!\n", chip->oldstate);
-+ }
-+ wake_up(&chip->wq);
-+}
-+
-+static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
-+{
-+ unsigned long cmd_addr;
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ int ret = 0;
-+
-+ adr += chip->start;
-+
-+ /* Ensure cmd read/writes are aligned. */
-+ cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1);
-+
-+ spin_lock(chip->mutex);
-+
-+ ret = get_chip(map, chip, cmd_addr, FL_POINT);
-+
-+ if (!ret) {
-+ if (chip->state != FL_POINT && chip->state != FL_READY)
-+ cfi_write(map, CMD(0xff), cmd_addr);
-
- chip->state = FL_POINT;
- chip->ref_point_counter++;
-+ }
- spin_unlock(chip->mutex);
-- return 0;
-+
-+ return ret;
- }
--static int do_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
-+
-+static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
- {
- struct map_info *map = mtd->priv;
- struct cfi_private *cfi = map->fldrv_priv;
-@@ -380,12 +495,10 @@
- int chipnum;
- int ret = 0;
-
-- if (from + len > mtd->size)
-+ if (!map->virt || (from + len > mtd->size))
- return -EINVAL;
-
-- *mtdbuf = map->point(map, from, len);
-- if(*mtdbuf == NULL)
-- return -EINVAL; /* can not point this region */
-+ *mtdbuf = (void *)map->virt + from;
- *retlen = 0;
-
- /* Now lock the chip(s) to POINT state */
-@@ -418,14 +531,13 @@
- return 0;
- }
-
--static void do_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
-+static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
- {
- struct map_info *map = mtd->priv;
- struct cfi_private *cfi = map->fldrv_priv;
- unsigned long ofs;
- int chipnum;
-
-- map->unpoint(map, addr, from, len);
- /* Now unlock the chip(s) POINT state */
-
- /* ofs: offset within the first chip that the first read should start */
-@@ -446,13 +558,14 @@
- thislen = len;
-
- spin_lock(chip->mutex);
-- if(chip->state == FL_POINT){
-+ if (chip->state == FL_POINT) {
- chip->ref_point_counter--;
- if(chip->ref_point_counter == 0)
- chip->state = FL_READY;
- } else
-- printk("Warning: unpoint called on non pointed region\n"); /* Should this give an error? */
-- wake_up(&chip->wq);
-+ printk(KERN_ERR "Warning: unpoint called on non pointed region\n"); /* Should this give an error? */
-+
-+ put_chip(map, chip, chip->start);
- spin_unlock(chip->mutex);
-
- len -= thislen;
-@@ -463,136 +576,32 @@
-
- static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
- {
-- cfi_word status, status_OK;
-- unsigned long timeo;
-- DECLARE_WAITQUEUE(wait, current);
-- int suspended = 0;
- unsigned long cmd_addr;
- struct cfi_private *cfi = map->fldrv_priv;
-+ int ret;
-
- adr += chip->start;
-
- /* Ensure cmd read/writes are aligned. */
- cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1);
-
-- /* Let's determine this according to the interleave only once */
-- status_OK = CMD(0x80);
--
-- timeo = jiffies + HZ;
-- retry:
- spin_lock(chip->mutex);
--
-- /* Check that the chip's ready to talk to us.
-- * If it's in FL_ERASING state, suspend it and make it talk now.
-- */
-- switch (chip->state) {
-- case FL_ERASING:
-- if (!cfi->cmdset_priv ||
-- !(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2))
-- goto sleep; /* We don't support erase suspend */
--
-- cfi_write (map, CMD(0xb0), cmd_addr);
-- /* If the flash has finished erasing, then 'erase suspend'
-- * appears to make some (28F320) flash devices switch to
-- * 'read' mode. Make sure that we switch to 'read status'
-- * mode so we get the right data. --rmk
-- */
-- cfi_write(map, CMD(0x70), cmd_addr);
-- chip->oldstate = FL_ERASING;
-- chip->state = FL_ERASE_SUSPENDING;
-- // printk("Erase suspending at 0x%lx\n", cmd_addr);
-- for (;;) {
-- status = cfi_read(map, cmd_addr);
-- if ((status & status_OK) == status_OK)
-- break;
--
-- if (time_after(jiffies, timeo)) {
-- /* Urgh */
-- cfi_write(map, CMD(0xd0), cmd_addr);
-- /* make sure we're in 'read status' mode */
-- cfi_write(map, CMD(0x70), cmd_addr);
-- chip->state = FL_ERASING;
-- spin_unlock(chip->mutex);
-- printk(KERN_ERR "Chip not ready after erase "
-- "suspended: status = 0x%llx\n", (__u64)status);
-- return -EIO;
-- }
--
-+ ret = get_chip(map, chip, cmd_addr, FL_READY);
-+ if (ret) {
- spin_unlock(chip->mutex);
-- cfi_udelay(1);
-- spin_lock(chip->mutex);
-+ return ret;
- }
-
-- suspended = 1;
-+ if (chip->state != FL_POINT && chip->state != FL_READY) {
- cfi_write(map, CMD(0xff), cmd_addr);
-- chip->state = FL_READY;
-- break;
--
--#if 0
-- case FL_WRITING:
-- /* Not quite yet */
--#endif
--
-- case FL_READY:
-- case FL_POINT:
-- break;
--
-- case FL_CFI_QUERY:
-- case FL_JEDEC_QUERY:
-- cfi_write(map, CMD(0x70), cmd_addr);
-- chip->state = FL_STATUS;
-
-- case FL_STATUS:
-- status = cfi_read(map, cmd_addr);
-- if ((status & status_OK) == status_OK) {
-- cfi_write(map, CMD(0xff), cmd_addr);
- chip->state = FL_READY;
-- break;
- }
-
-- /* Urgh. Chip not yet ready to talk to us. */
-- if (time_after(jiffies, timeo)) {
-- spin_unlock(chip->mutex);
-- printk(KERN_ERR "waiting for chip to be ready timed out in read. WSM status = %llx\n", (__u64)status);
-- return -EIO;
-- }
-+ map_copy_from(map, buf, adr, len);
-
-- /* Latency issues. Drop the lock, wait a while and retry */
-- spin_unlock(chip->mutex);
-- cfi_udelay(1);
-- goto retry;
-+ put_chip(map, chip, cmd_addr);
-
-- default:
-- sleep:
-- /* Stick ourselves on a wait queue to be woken when
-- someone changes the status */
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-- spin_unlock(chip->mutex);
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
-- timeo = jiffies + HZ;
-- goto retry;
-- }
--
-- map->copy_from(map, buf, adr, len);
--
-- if (suspended) {
-- chip->state = chip->oldstate;
-- /* What if one interleaved chip has finished and the
-- other hasn't? The old code would leave the finished
-- one in READY mode. That's bad, and caused -EROFS
-- errors to be returned from do_erase_oneblock because
-- that's the only bit it checked for at the time.
-- As the state machine appears to explicitly allow
-- sending the 0x70 (Read Status) command to an erasing
-- chip and expecting it to be ignored, that's what we
-- do. */
-- cfi_write(map, CMD(0xd0), cmd_addr);
-- cfi_write(map, CMD(0x70), cmd_addr);
-- }
--
-- wake_up(&chip->wq);
- spin_unlock(chip->mutex);
- return 0;
- }
-@@ -640,70 +649,52 @@
- {
- struct map_info *map = mtd->priv;
- struct cfi_private *cfi = map->fldrv_priv;
-- struct cfi_pri_intelext *extp=cfi->cmdset_priv;
-- int ofs_factor = cfi->interleave * cfi->device_type;
-- int count=len;
-+ struct cfi_pri_intelext *extp = cfi->cmdset_priv;
- struct flchip *chip;
-- int chip_num,offst;
-- unsigned long timeo;
-- DECLARE_WAITQUEUE(wait, current);
-+ int ofs_factor = cfi->interleave * cfi->device_type;
-+ int count = len;
-+ int chip_num, offst;
-+ int ret;
-
-- chip=0;
-- /* Calculate which chip & protection register offset we need */
-- chip_num=((unsigned int)from/reg_sz);
-- offst=from-(reg_sz*chip_num)+base_offst;
-+ chip_num = ((unsigned int)from/reg_sz);
-+ offst = from - (reg_sz*chip_num)+base_offst;
-
-- while(count){
-+ while (count) {
-+ /* Calculate which chip & protection register offset we need */
-
-- if(chip_num>=cfi->numchips)
-+ if (chip_num >= cfi->numchips)
- goto out;
-
-- /* Make sure that the chip is in the right state */
-+ chip = &cfi->chips[chip_num];
-
-- timeo = jiffies + HZ;
-- chip=&cfi->chips[chip_num];
-- retry:
- spin_lock(chip->mutex);
--
-- switch (chip->state) {
-- case FL_READY:
-- case FL_STATUS:
-- case FL_CFI_QUERY:
-- case FL_JEDEC_QUERY:
-- break;
--
-- default:
-- /* Stick ourselves on a wait queue to be woken when
-- someone changes the status */
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-+ ret = get_chip(map, chip, chip->start, FL_JEDEC_QUERY);
-+ if (ret) {
- spin_unlock(chip->mutex);
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
-- timeo = jiffies + HZ;
-- goto retry;
-+ return (len-count)?:ret;
- }
-
-- /* Now read the data required from this flash */
-+ if (chip->state != FL_JEDEC_QUERY) {
-+ cfi_write(map, CMD(0x90), chip->start);
-+ chip->state = FL_JEDEC_QUERY;
-+ }
-
-- cfi_send_gen_cmd(0x90, 0x55,chip->start, map, cfi, cfi->device_type, NULL);
-- while(count && ((offst-base_offst)<reg_sz)){
-- *buf=map->read8(map,(chip->start+((extp->ProtRegAddr+1)*ofs_factor)+offst));
-+ while (count && ((offst-base_offst) < reg_sz)) {
-+ *buf = map_read8(map,(chip->start+((extp->ProtRegAddr+1)*ofs_factor)+offst));
- buf++;
- offst++;
- count--;
- }
-
-- chip->state=FL_CFI_QUERY;
-+ put_chip(map, chip, chip->start);
- spin_unlock(chip->mutex);
-+
- /* Move on to the next chip */
- chip_num++;
-- offst=base_offst;
--
-+ offst = base_offst;
- }
-
- out:
-- wake_up(&chip->wq);
- return len-count;
- }
-
-@@ -749,103 +740,20 @@
- static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, cfi_word datum)
- {
- struct cfi_private *cfi = map->fldrv_priv;
-- struct cfi_pri_intelext *extp = cfi->cmdset_priv;
-- cfi_word status, status_OK;
-- unsigned long timeo;
-- DECLARE_WAITQUEUE(wait, current);
-- int z, suspended=0, ret=0;
--
-- adr += chip->start;
--
-- /* Let's determine this according to the interleave only once */
-- status_OK = CMD(0x80);
--
-- timeo = jiffies + HZ;
-- retry:
-- spin_lock(chip->mutex);
--
-- /* Check that the chip's ready to talk to us.
-- * Later, we can actually think about interrupting it
-- * if it's in FL_ERASING state.
-- * Not just yet, though.
-- */
-- switch (chip->state) {
-- case FL_READY:
-- break;
--
-- case FL_CFI_QUERY:
-- case FL_JEDEC_QUERY:
-- cfi_write(map, CMD(0x70), adr);
-- chip->state = FL_STATUS;
--
-- case FL_STATUS:
-- status = cfi_read(map, adr);
-- if ((status & status_OK) == status_OK)
-- break;
--
-- /* Urgh. Chip not yet ready to talk to us. */
-- if (time_after(jiffies, timeo)) {
-- spin_unlock(chip->mutex);
-- printk(KERN_ERR "waiting for chip to be ready timed out in read\n");
-- return -EIO;
-- }
--
-- /* Latency issues. Drop the lock, wait a while and retry */
-- spin_unlock(chip->mutex);
-- cfi_udelay(1);
-- goto retry;
--
-- case FL_ERASING:
-- if (!extp ||
-- !((extp->FeatureSupport & 2) && (extp->SuspendCmdSupport & 1)))
-- goto sleep; /* We don't support erase suspend */
--
-- cfi_write (map, CMD(0xb0), adr);
--
-- /* If the flash has finished erasing, then 'erase suspend'
-- * appears to make some (28F320) flash devices switch to
-- * 'read' mode. Make sure that we switch to 'read status'
-- * mode so we get the right data. --rmk
-- */
-- cfi_write(map, CMD(0x70), adr);
-- chip->oldstate = FL_ERASING;
-- chip->state = FL_ERASE_SUSPENDING;
-- for (;;) {
-- status = cfi_read(map, adr);
-- if ((status & status_OK) == status_OK)
-- break;
-+ cfi_word status, status_OK;
-+ unsigned long timeo;
-+ int z, ret=0;
-
-- if (time_after(jiffies, timeo)) {
-- /* Urgh */
-- cfi_write(map, CMD(0xd0), adr);
-- /* make sure we're in 'read status' mode */
-- cfi_write(map, CMD(0x70), adr);
-- chip->state = FL_ERASING;
-- spin_unlock(chip->mutex);
-- printk(KERN_ERR "Chip not ready after erase "
-- "suspended: status = 0x%x\n", status);
-- return -EIO;
-- }
-+ adr += chip->start;
-
-- spin_unlock(chip->mutex);
-- cfi_udelay(1);
-- spin_lock(chip->mutex);
-- }
-- suspended = 1;
-- chip->state = FL_STATUS;
-- break;
-+ /* Let's determine this according to the interleave only once */
-+ status_OK = CMD(0x80);
-
-- default:
-- sleep:
-- /* Stick ourselves on a wait queue to be woken when
-- someone changes the status */
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-+ spin_lock(chip->mutex);
-+ ret = get_chip(map, chip, adr, FL_WRITING);
-+ if (ret) {
- spin_unlock(chip->mutex);
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
-- timeo = jiffies + HZ;
-- goto retry;
-+ return ret;
- }
-
- ENABLE_VPP(map);
-@@ -862,6 +770,8 @@
- for (;;) {
- if (chip->state != FL_WRITING) {
- /* Someone's suspended the write. Sleep */
-+ DECLARE_WAITQUEUE(wait, current);
-+
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&chip->wq, &wait);
- spin_unlock(chip->mutex);
-@@ -879,7 +789,6 @@
- /* OK Still waiting */
- if (time_after(jiffies, timeo)) {
- chip->state = FL_STATUS;
-- DISABLE_VPP(map);
- printk(KERN_ERR "waiting for chip to be ready timed out in word write\n");
- ret = -EIO;
- goto out;
-@@ -908,27 +817,11 @@
- /* put back into read status register mode */
- cfi_write(map, CMD(0x70), adr);
- ret = -EROFS;
-- goto out;
- }
- out:
-- if (suspended) {
-- chip->state = chip->oldstate;
-- /* What if one interleaved chip has finished and the
-- other hasn't? The old code would leave the finished
-- one in READY mode. That's bad, and caused -EROFS
-- errors to be returned from do_erase_oneblock because
-- that's the only bit it checked for at the time.
-- As the state machine appears to explicitly allow
-- sending the 0x70 (Read Status) command to an erasing
-- chip and expecting it to be ignored, that's what we
-- do. */
-- cfi_write(map, CMD(0xd0), adr);
-- cfi_write(map, CMD(0x70), adr);
-- } else
-- DISABLE_VPP(map); /* must not clear the VPP if there is a suspended erase to be resumed */
--
-- wake_up(&chip->wq);
-+ put_chip(map, chip, adr);
- spin_unlock(chip->mutex);
-+
- return ret;
- }
-
-@@ -1059,11 +952,9 @@
- unsigned long adr, const u_char *buf, int len)
- {
- struct cfi_private *cfi = map->fldrv_priv;
-- struct cfi_pri_intelext *extp = cfi->cmdset_priv;
- cfi_word status, status_OK;
- unsigned long cmd_adr, timeo;
-- DECLARE_WAITQUEUE(wait, current);
-- int wbufsize, z, suspended=0, ret=0;
-+ int wbufsize, z, ret=0, bytes, words;
-
- wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize;
- adr += chip->start;
-@@ -1072,91 +963,18 @@
- /* Let's determine this according to the interleave only once */
- status_OK = CMD(0x80);
-
-- timeo = jiffies + HZ;
-- retry:
- spin_lock(chip->mutex);
--
-- /* Check that the chip's ready to talk to us.
-- * Later, we can actually think about interrupting it
-- * if it's in FL_ERASING state.
-- * Not just yet, though.
-- */
-- switch (chip->state) {
-- case FL_READY:
-- case FL_CFI_QUERY:
-- case FL_JEDEC_QUERY:
-- cfi_write(map, CMD(0x70), cmd_adr);
-- chip->state = FL_STATUS;
--
-- case FL_STATUS:
-- status = cfi_read(map, cmd_adr);
-- if ((status & status_OK) == status_OK)
-- break;
-- /* Urgh. Chip not yet ready to talk to us. */
-- if (time_after(jiffies, timeo)) {
-+ ret = get_chip(map, chip, cmd_adr, FL_WRITING);
-+ if (ret) {
- spin_unlock(chip->mutex);
-- printk(KERN_ERR "waiting for chip to be ready timed out in buffer write\n");
-- return -EIO;
-+ return ret;
- }
-
-- /* Latency issues. Drop the lock, wait a while and retry */
-- spin_unlock(chip->mutex);
-- cfi_udelay(1);
-- goto retry;
--
-- case FL_ERASING:
-- if (!extp ||
-- !((extp->FeatureSupport & 2) && (extp->SuspendCmdSupport & 1)))
-- goto sleep; /* We don't support erase suspend */
--
-- cfi_write (map, CMD(0xb0), adr);
--
-- /* If the flash has finished erasing, then 'erase suspend'
-- * appears to make some (28F320) flash devices switch to
-- * 'read' mode. Make sure that we switch to 'read status'
-- * mode so we get the right data. --rmk
-- */
-- cfi_write(map, CMD(0x70), adr);
-- chip->oldstate = FL_ERASING;
-- chip->state = FL_ERASE_SUSPENDING;
-- for (;;) {
-- status = cfi_read(map, adr);
-- if ((status & status_OK) == status_OK)
-- break;
--
-- if (time_after(jiffies, timeo)) {
-- /* Urgh */
-- cfi_write(map, CMD(0xd0), adr);
-- /* make sure we're in 'read status' mode */
-- cfi_write(map, CMD(0x70), adr);
-- chip->state = FL_ERASING;
-- spin_unlock(chip->mutex);
-- printk(KERN_ERR "Chip not ready after erase "
-- "suspended: status = 0x%x\n", status);
-- return -EIO;
-- }
-+ if (chip->state != FL_STATUS)
-+ cfi_write(map, CMD(0x70), cmd_adr);
-
-- spin_unlock(chip->mutex);
-- cfi_udelay(1);
-- spin_lock(chip->mutex);
-- }
-- suspended = 1;
-- chip->state = FL_STATUS;
-- break;
-+ status = cfi_read(map, cmd_adr);
-
-- default:
-- sleep:
-- /* Stick ourselves on a wait queue to be woken when
-- someone changes the status */
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-- spin_unlock(chip->mutex);
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
-- timeo = jiffies + HZ;
-- goto retry;
-- }
-- /* We know we're now in FL_STATUS mode, and 'status' is current */
- /* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set
- [...], the device will not accept any more Write to Buffer commands".
- So we must check here and reset those bits if they're set. Otherwise
-@@ -1185,7 +1003,6 @@
- /* Argh. Not ready for write to buffer */
- cfi_write(map, CMD(0x70), cmd_adr);
- chip->state = FL_STATUS;
-- DISABLE_VPP(map);
- printk(KERN_ERR "Chip not ready for buffer write. Xstatus = %llx, status = %llx\n", (__u64)status, (__u64)cfi_read(map, cmd_adr));
- /* Odd. Clear status bits */
- cfi_write(map, CMD(0x50), cmd_adr);
-@@ -1196,20 +1013,42 @@
- }
-
- /* Write length of data to come */
-- cfi_write(map, CMD(len/CFIDEV_BUSWIDTH-1), cmd_adr );
-+ bytes = len & (CFIDEV_BUSWIDTH-1);
-+ words = len / CFIDEV_BUSWIDTH;
-+ cfi_write(map, CMD(words - !bytes), cmd_adr );
-
- /* Write data */
-- for (z = 0; z < len; z += CFIDEV_BUSWIDTH) {
-+ z = 0;
-+ while(z < words * CFIDEV_BUSWIDTH) {
- if (cfi_buswidth_is_1()) {
-- map->write8 (map, *((__u8*)buf)++, adr+z);
-+ map_write8 (map, *((__u8*)buf)++, adr+z);
- } else if (cfi_buswidth_is_2()) {
-- map->write16 (map, *((__u16*)buf)++, adr+z);
-+ map_write16 (map, *((__u16*)buf)++, adr+z);
- } else if (cfi_buswidth_is_4()) {
-- map->write32 (map, *((__u32*)buf)++, adr+z);
-+ map_write32 (map, *((__u32*)buf)++, adr+z);
- } else if (cfi_buswidth_is_8()) {
-- map->write64 (map, *((__u64*)buf)++, adr+z);
-+ map_write64 (map, *((__u64*)buf)++, adr+z);
-+ } else {
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+ z += CFIDEV_BUSWIDTH;
-+ }
-+ if (bytes) {
-+ int i = 0, n = 0;
-+ u_char tmp_buf[8], *tmp_p = tmp_buf;
-+
-+ while (bytes--)
-+ tmp_buf[i++] = buf[n++];
-+ while (i < CFIDEV_BUSWIDTH)
-+ tmp_buf[i++] = 0xff;
-+ if (cfi_buswidth_is_2()) {
-+ map_write16 (map, *((__u16*)tmp_p)++, adr+z);
-+ } else if (cfi_buswidth_is_4()) {
-+ map_write32 (map, *((__u32*)tmp_p)++, adr+z);
-+ } else if (cfi_buswidth_is_8()) {
-+ map_write64 (map, *((__u64*)tmp_p)++, adr+z);
- } else {
-- DISABLE_VPP(map);
- ret = -EINVAL;
- goto out;
- }
-@@ -1227,6 +1066,7 @@
- for (;;) {
- if (chip->state != FL_WRITING) {
- /* Someone's suspended the write. Sleep */
-+ DECLARE_WAITQUEUE(wait, current);
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&chip->wq, &wait);
- spin_unlock(chip->mutex);
-@@ -1244,7 +1084,6 @@
- /* OK Still waiting */
- if (time_after(jiffies, timeo)) {
- chip->state = FL_STATUS;
-- DISABLE_VPP(map);
- printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n");
- ret = -EIO;
- goto out;
-@@ -1266,6 +1105,7 @@
-
- /* Done and happy. */
- chip->state = FL_STATUS;
-+
- /* check for lock bit */
- if (status & CMD(0x02)) {
- /* clear status */
-@@ -1273,26 +1113,10 @@
- /* put back into read status register mode */
- cfi_write(map, CMD(0x70), adr);
- ret = -EROFS;
-- goto out;
- }
-- out:
-- if (suspended) {
-- chip->state = chip->oldstate;
-- /* What if one interleaved chip has finished and the
-- other hasn't? The old code would leave the finished
-- one in READY mode. That's bad, and caused -EROFS
-- errors to be returned from do_erase_oneblock because
-- that's the only bit it checked for at the time.
-- As the state machine appears to explicitly allow
-- sending the 0x70 (Read Status) command to an erasing
-- chip and expecting it to be ignored, that's what we
-- do. */
-- cfi_write(map, CMD(0xd0), adr);
-- cfi_write(map, CMD(0x70), adr);
-- } else
-- DISABLE_VPP(map); /* must not clear the VPP if there is a suspended erase to be resumed */
-
-- wake_up(&chip->wq);
-+ out:
-+ put_chip(map, chip, cmd_adr);
- spin_unlock(chip->mutex);
- return ret;
- }
-@@ -1336,12 +1160,12 @@
- }
-
- /* Write buffer is worth it only if more than one word to write... */
-- while(len > CFIDEV_BUSWIDTH) {
-+ while(len) {
- /* We must not cross write block boundaries */
- int size = wbufsize - (ofs & (wbufsize-1));
-
- if (size > len)
-- size = len & ~(CFIDEV_BUSWIDTH-1);
-+ size = len;
- ret = do_write_buffer(map, &cfi->chips[chipnum],
- ofs, buf, size);
- if (ret)
-@@ -1359,17 +1183,6 @@
- return 0;
- }
- }
--
-- /* ... and write the remaining bytes */
-- if (len > 0) {
-- size_t local_retlen;
-- ret = cfi_intelext_write_words(mtd, ofs + (chipnum << cfi->chipshift),
-- len, &local_retlen, buf);
-- if (ret)
-- return ret;
-- (*retlen) += local_retlen;
-- }
--
- return 0;
- }
-
-@@ -1479,45 +1292,12 @@
- /* Let's determine this according to the interleave only once */
- status_OK = CMD(0x80);
-
-- timeo = jiffies + HZ;
--retry:
-+ retry:
- spin_lock(chip->mutex);
--
-- /* Check that the chip's ready to talk to us. */
-- switch (chip->state) {
-- case FL_CFI_QUERY:
-- case FL_JEDEC_QUERY:
-- case FL_READY:
-- cfi_write(map, CMD(0x70), adr);
-- chip->state = FL_STATUS;
--
-- case FL_STATUS:
-- status = cfi_read(map, adr);
-- if ((status & status_OK) == status_OK)
-- break;
--
-- /* Urgh. Chip not yet ready to talk to us. */
-- if (time_after(jiffies, timeo)) {
-- spin_unlock(chip->mutex);
-- printk(KERN_ERR "waiting for chip to be ready timed out in erase\n");
-- return -EIO;
-- }
--
-- /* Latency issues. Drop the lock, wait a while and retry */
-- spin_unlock(chip->mutex);
-- cfi_udelay(1);
-- goto retry;
--
-- default:
-- /* Stick ourselves on a wait queue to be woken when
-- someone changes the status */
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-+ ret = get_chip(map, chip, adr, FL_ERASING);
-+ if (ret) {
- spin_unlock(chip->mutex);
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
-- timeo = jiffies + HZ;
-- goto retry;
-+ return ret;
- }
-
- ENABLE_VPP(map);
-@@ -1528,7 +1308,7 @@
- cfi_write(map, CMD(0x20), adr);
- cfi_write(map, CMD(0xD0), adr);
- chip->state = FL_ERASING;
-- chip->oldstate = 0;
-+ chip->erase_suspended = 0;
-
- spin_unlock(chip->mutex);
- set_current_state(TASK_UNINTERRUPTIBLE);
-@@ -1550,11 +1330,11 @@
- spin_lock(chip->mutex);
- continue;
- }
-- if (chip->oldstate) {
-+ if (chip->erase_suspended) {
- /* This erase was suspended and resumed.
- Adjust the timeout */
- timeo = jiffies + (HZ*20); /* FIXME */
-- chip->oldstate = 0;
-+ chip->erase_suspended = 0;
- }
-
- status = cfi_read(map, adr);
-@@ -1658,39 +1438,22 @@
- int i;
- struct flchip *chip;
- int ret = 0;
-- DECLARE_WAITQUEUE(wait, current);
-
- for (i=0; !ret && i<cfi->numchips; i++) {
- chip = &cfi->chips[i];
-
-- retry:
- spin_lock(chip->mutex);
-+ ret = get_chip(map, chip, chip->start, FL_SYNCING);
-
-- switch(chip->state) {
-- case FL_READY:
-- case FL_STATUS:
-- case FL_CFI_QUERY:
-- case FL_JEDEC_QUERY:
-+ if (!ret) {
- chip->oldstate = chip->state;
- chip->state = FL_SYNCING;
- /* No need to wake_up() on this state change -
- * as the whole point is that nobody can do anything
- * with the chip now anyway.
- */
-- case FL_SYNCING:
-- spin_unlock(chip->mutex);
-- break;
--
-- default:
-- /* Not an idle state */
-- add_wait_queue(&chip->wq, &wait);
--
-- spin_unlock(chip->mutex);
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
--
-- goto retry;
- }
-+ spin_unlock(chip->mutex);
- }
-
- /* Unlock the chips again */
-@@ -1731,52 +1494,18 @@
- struct cfi_private *cfi = map->fldrv_priv;
- cfi_word status, status_OK;
- unsigned long timeo = jiffies + HZ;
-- DECLARE_WAITQUEUE(wait, current);
-+ int ret;
-
- adr += chip->start;
-
- /* Let's determine this according to the interleave only once */
- status_OK = CMD(0x80);
-
-- timeo = jiffies + HZ;
--retry:
- spin_lock(chip->mutex);
--
-- /* Check that the chip's ready to talk to us. */
-- switch (chip->state) {
-- case FL_CFI_QUERY:
-- case FL_JEDEC_QUERY:
-- case FL_READY:
-- cfi_write(map, CMD(0x70), adr);
-- chip->state = FL_STATUS;
--
-- case FL_STATUS:
-- status = cfi_read(map, adr);
-- if ((status & status_OK) == status_OK)
-- break;
--
-- /* Urgh. Chip not yet ready to talk to us. */
-- if (time_after(jiffies, timeo)) {
-- spin_unlock(chip->mutex);
-- printk(KERN_ERR "%s: waiting for chip to be ready timed out\n", __FUNCTION__);
-- return -EIO;
-- }
--
-- /* Latency issues. Drop the lock, wait a while and retry */
-- spin_unlock(chip->mutex);
-- cfi_udelay(1);
-- goto retry;
--
-- default:
-- /* Stick ourselves on a wait queue to be woken when
-- someone changes the status */
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-+ ret = get_chip(map, chip, adr, FL_LOCKING);
-+ if (ret) {
- spin_unlock(chip->mutex);
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
-- timeo = jiffies + HZ;
-- goto retry;
-+ return ret;
- }
-
- ENABLE_VPP(map);
-@@ -1823,8 +1552,7 @@
-
- /* Done and happy. */
- chip->state = FL_STATUS;
-- DISABLE_VPP(map);
-- wake_up(&chip->wq);
-+ put_chip(map, chip, adr);
- spin_unlock(chip->mutex);
- return 0;
- }
-@@ -1889,22 +1617,23 @@
-
- spin_lock(chip->mutex);
-
-- switch(chip->state) {
-+ switch (chip->state) {
- case FL_READY:
- case FL_STATUS:
- case FL_CFI_QUERY:
- case FL_JEDEC_QUERY:
-+ if (chip->oldstate == FL_READY) {
- chip->oldstate = chip->state;
- chip->state = FL_PM_SUSPENDED;
- /* No need to wake_up() on this state change -
- * as the whole point is that nobody can do anything
- * with the chip now anyway.
- */
-- case FL_PM_SUSPENDED:
-+ }
- break;
--
- default:
- ret = -EAGAIN;
-+ case FL_PM_SUSPENDED:
- break;
- }
- spin_unlock(chip->mutex);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/chips/cfi_cmdset_0002.c linux/drivers/mtd/chips/cfi_cmdset_0002.c
---- linux-mips-2.4.24-pre2/drivers/mtd/chips/cfi_cmdset_0002.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/chips/cfi_cmdset_0002.c 2004-11-17 18:17:58.937329424 +0100
-@@ -6,16 +6,22 @@
- *
- * 2_by_8 routines added by Simon Munton
- *
-+ * 4_by_16 work by Carolyn J. Smith
-+ *
-+ * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
-+ *
- * This code is GPL
- *
-- * $Id$
-+ * $Id$
- *
- */
-
-+#include <linux/config.h>
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
- #include <linux/sched.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <asm/byteorder.h>
-
-@@ -23,16 +29,50 @@
- #include <linux/slab.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
-+#include <linux/mtd/compatmac.h>
- #include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/cfi.h>
-
- #define AMD_BOOTLOC_BUG
-+#define FORCE_WORD_WRITE 0
-+
-+
-+/*
-+ * This is an attempt to coalesce the retry logic in one place - that way
-+ * there aren't #ifdefs scattered throughout.
-+ */
-+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
-+
-+#ifndef CONFIG_MTD_CFI_AMDSTD_RETRY_MAX
-+#define CONFIG_MTD_CFI_AMDSTD_RETRY_MAX 0
-+#endif
-+
-+#define RETRY_CMD_LABEL retry_cmd: do {} while (0)
-+#define HANDLE_WACKY_STATE() handle_wacky_state(__func__, retry_cmd_cnt, adr, datum, prev_oldstatus, prev_status, oldstatus, status)
-+static int retry_cmd_max = CONFIG_MTD_CFI_AMDSTD_RETRY_MAX;
-+#define DECLARE_RETRY_CMD_CNT() int retry_cmd_cnt = 0
-+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
-+#define CHECK_RETRIES() do { if (++retry_cmd_cnt <= retry_cmd_max) goto retry_cmd; } while (0)
-+#endif
-+
-+#else
-+
-+#define RETRY_CMD_LABEL do {} while (0)
-+#define HANDLE_WACKY_STATE() handle_wacky_state(__func__, adr, datum, prev_oldstatus, prev_status, oldstatus, status)
-+#define DECLARE_RETRY_CMD_CNT()
-+#define CHECK_RETRIES()
-+
-+#endif /* !defined(CONFIG_MTD_CFI_AMDSTD_RETRY) */
-+
-
- static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
--static int cfi_amdstd_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
-+static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
-+static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
- static int cfi_amdstd_erase_chip(struct mtd_info *, struct erase_info *);
--static int cfi_amdstd_erase_onesize(struct mtd_info *, struct erase_info *);
- static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *);
-+static int cfi_amdstd_lock_varsize(struct mtd_info *, loff_t, size_t);
-+static int cfi_amdstd_unlock_varsize(struct mtd_info *, loff_t, size_t);
- static void cfi_amdstd_sync (struct mtd_info *);
- static int cfi_amdstd_suspend (struct mtd_info *);
- static void cfi_amdstd_resume (struct mtd_info *);
-@@ -45,55 +85,136 @@
-
-
- static struct mtd_chip_driver cfi_amdstd_chipdrv = {
-- probe: NULL, /* Not usable directly */
-- destroy: cfi_amdstd_destroy,
-- name: "cfi_cmdset_0002",
-- module: THIS_MODULE
-+ .probe = NULL, /* Not usable directly */
-+ .destroy = cfi_amdstd_destroy,
-+ .name = "cfi_cmdset_0002",
-+ .module = THIS_MODULE
- };
-
--struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
-+
-+/* #define DEBUG_LOCK_BITS */
-+/* #define DEBUG_CFI_FEATURES */
-+
-+
-+#ifdef DEBUG_CFI_FEATURES
-+static void cfi_tell_features(struct cfi_pri_amdstd *extp)
- {
-- struct cfi_private *cfi = map->fldrv_priv;
-- unsigned char bootloc;
-- int ofs_factor = cfi->interleave * cfi->device_type;
-- int i;
-- __u8 major, minor;
-- __u32 base = cfi->chips[0].start;
-+ const char* erase_suspend[3] = {
-+ "Not supported", "Read only", "Read/write"
-+ };
-+ const char* top_bottom[6] = {
-+ "No WP", "8x8KiB sectors at top & bottom, no WP",
-+ "Bottom boot", "Top boot",
-+ "Uniform, Bottom WP", "Uniform, Top WP"
-+ };
-+
-+ printk(" Silicon revision: %d\n", extp->SiliconRevision >> 1);
-+ printk(" Address sensitive unlock: %s\n",
-+ (extp->SiliconRevision & 1) ? "Not required" : "Required");
-
-- if (cfi->cfi_mode==CFI_MODE_CFI){
-- __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
-+ if (extp->EraseSuspend < ARRAY_SIZE(erase_suspend))
-+ printk(" Erase Suspend: %s\n", erase_suspend[extp->EraseSuspend]);
-+ else
-+ printk(" Erase Suspend: Unknown value %d\n", extp->EraseSuspend);
-
-- cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
-+ if (extp->BlkProt == 0)
-+ printk(" Block protection: Not supported\n");
-+ else
-+ printk(" Block protection: %d sectors per group\n", extp->BlkProt);
-+
-+
-+ printk(" Temporary block unprotect: %s\n",
-+ extp->TmpBlkUnprotect ? "Supported" : "Not supported");
-+ printk(" Block protect/unprotect scheme: %d\n", extp->BlkProtUnprot);
-+ printk(" Number of simultaneous operations: %d\n", extp->SimultaneousOps);
-+ printk(" Burst mode: %s\n",
-+ extp->BurstMode ? "Supported" : "Not supported");
-+ if (extp->PageMode == 0)
-+ printk(" Page mode: Not supported\n");
-+ else
-+ printk(" Page mode: %d word page\n", extp->PageMode << 2);
-
-- major = cfi_read_query(map, base + (adr+3)*ofs_factor);
-- minor = cfi_read_query(map, base + (adr+4)*ofs_factor);
-+ printk(" Vpp Supply Minimum Program/Erase Voltage: %d.%d V\n",
-+ extp->VppMin >> 4, extp->VppMin & 0xf);
-+ printk(" Vpp Supply Maximum Program/Erase Voltage: %d.%d V\n",
-+ extp->VppMax >> 4, extp->VppMax & 0xf);
-
-- printk(KERN_NOTICE " Amd/Fujitsu Extended Query Table v%c.%c at 0x%4.4X\n",
-- major, minor, adr);
-- cfi_send_gen_cmd(0xf0, 0x55, base, map, cfi, cfi->device_type, NULL);
--
-- cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
-- cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
-- cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
-- cfi->mfr = cfi_read_query(map, base);
-- cfi->id = cfi_read_query(map, base + ofs_factor);
-+ if (extp->TopBottom < ARRAY_SIZE(top_bottom))
-+ printk(" Top/Bottom Boot Block: %s\n", top_bottom[extp->TopBottom]);
-+ else
-+ printk(" Top/Bottom Boot Block: Unknown value %d\n", extp->TopBottom);
-+}
-+#endif
-
-- /* Wheee. Bring me the head of someone at AMD. */
- #ifdef AMD_BOOTLOC_BUG
-+/* Wheee. Bring me the head of someone at AMD. */
-+static void fixup_amd_bootblock(struct map_info *map, void* param)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ struct cfi_pri_amdstd *extp = cfi->cmdset_priv;
-+ __u8 major = extp->MajorVersion;
-+ __u8 minor = extp->MinorVersion;
-+
- if (((major << 8) | minor) < 0x3131) {
- /* CFI version 1.0 => don't trust bootloc */
- if (cfi->id & 0x80) {
- printk(KERN_WARNING "%s: JEDEC Device ID is 0x%02X. Assuming broken CFI table.\n", map->name, cfi->id);
-- bootloc = 3; /* top boot */
-+ extp->TopBottom = 3; /* top boot */
- } else {
-- bootloc = 2; /* bottom boot */
-+ extp->TopBottom = 2; /* bottom boot */
- }
-- } else
-+ }
-+}
- #endif
-+
-+static struct cfi_fixup fixup_table[] = {
-+#ifdef AMD_BOOTLOC_BUG
- {
-- cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
-- bootloc = cfi_read_query(map, base + (adr+15)*ofs_factor);
-+ 0x0001, /* AMD */
-+ CFI_ID_ANY,
-+ fixup_amd_bootblock, NULL
-+ },
-+#endif
-+ { 0, 0, NULL, NULL }
-+};
-+
-+
-+struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ unsigned char bootloc;
-+ int i;
-+
-+ if (cfi->cfi_mode==CFI_MODE_CFI){
-+ /*
-+ * It's a real CFI chip, not one for which the probe
-+ * routine faked a CFI structure. So we read the feature
-+ * table from it.
-+ */
-+ __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
-+ struct cfi_pri_amdstd *extp;
-+
-+ extp = (struct cfi_pri_amdstd*)cfi_read_pri(map, adr, sizeof(*extp), "Amd/Fujitsu");
-+ if (!extp)
-+ return NULL;
-+
-+ /* Install our own private info structure */
-+ cfi->cmdset_priv = extp;
-+
-+ cfi_fixup(map, fixup_table);
-+
-+#ifdef DEBUG_CFI_FEATURES
-+ /* Tell the user about it in lots of lovely detail */
-+ cfi_tell_features(extp);
-+#endif
-+
-+ bootloc = extp->TopBottom;
-+ if ((bootloc != 2) && (bootloc != 3)) {
-+ printk(KERN_WARNING "%s: CFI does not contain boot "
-+ "bank location. Assuming top.\n", map->name);
-+ bootloc = 2;
- }
-+
- if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) {
- printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name);
-
-@@ -106,6 +227,11 @@
- cfi->cfiq->EraseRegionInfo[j] = swap;
- }
- }
-+ /*
-+ * These might already be setup (more correctly) by
-+ * jedec_probe.c - still need it for cfi_probe.c path.
-+ */
-+ if ( ! (cfi->addr_unlock1 && cfi->addr_unlock2) ) {
- switch (cfi->device_type) {
- case CFI_DEVICETYPE_X8:
- cfi->addr_unlock1 = 0x555;
-@@ -125,9 +251,13 @@
- cfi->addr_unlock2 = 0xaaa;
- break;
- default:
-- printk(KERN_NOTICE "Eep. Unknown cfi_cmdset_0002 device type %d\n", cfi->device_type);
-+ printk(KERN_WARNING
-+ "MTD %s(): Unsupported device type %d\n",
-+ __func__, cfi->device_type);
- return NULL;
- }
-+ }
-+
- } /* CFI mode */
-
- for (i=0; i< cfi->numchips; i++) {
-@@ -138,15 +268,17 @@
-
- map->fldrv = &cfi_amdstd_chipdrv;
-
-- cfi_send_gen_cmd(0xf0, 0x55, base, map, cfi, cfi->device_type, NULL);
- return cfi_amdstd_setup(map);
- }
-
-+
- static struct mtd_info *cfi_amdstd_setup(struct map_info *map)
- {
- struct cfi_private *cfi = map->fldrv_priv;
- struct mtd_info *mtd;
- unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave;
-+ unsigned long offset = 0;
-+ int i,j;
-
- mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
- printk(KERN_NOTICE "number of %s chips: %d\n",
-@@ -163,15 +295,9 @@
- /* Also select the correct geometry setup too */
- mtd->size = devsize * cfi->numchips;
-
-- if (cfi->cfiq->NumEraseRegions == 1) {
-- /* No need to muck about with multiple erase sizes */
-- mtd->erasesize = ((cfi->cfiq->EraseRegionInfo[0] >> 8) & ~0xff) * cfi->interleave;
-- } else {
-- unsigned long offset = 0;
-- int i,j;
--
- mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
-- mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * mtd->numeraseregions, GFP_KERNEL);
-+ mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
-+ * mtd->numeraseregions, GFP_KERNEL);
- if (!mtd->eraseregions) {
- printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n");
- goto setup_err;
-@@ -206,39 +332,52 @@
- mtd->eraseregions[i].numblocks);
- }
- #endif
-- }
-
- switch (CFIDEV_BUSWIDTH)
- {
- case 1:
- case 2:
- case 4:
--#if 1
-- if (mtd->numeraseregions > 1)
-- mtd->erase = cfi_amdstd_erase_varsize;
-- else
-+#ifdef CFI_WORD_64
-+ case 8:
- #endif
-- if (((cfi->cfiq->EraseRegionInfo[0] & 0xffff) + 1) == 1)
-+ if (mtd->numeraseregions == 1
-+ && ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) + 1) == 1) {
- mtd->erase = cfi_amdstd_erase_chip;
-- else
-- mtd->erase = cfi_amdstd_erase_onesize;
-+ } else {
-+ mtd->erase = cfi_amdstd_erase_varsize;
-+ mtd->lock = cfi_amdstd_lock_varsize;
-+ mtd->unlock = cfi_amdstd_unlock_varsize;
-+ }
-+
-+ if ( cfi->cfiq->BufWriteTimeoutTyp && !FORCE_WORD_WRITE) {
-+ DEBUG(MTD_DEBUG_LEVEL1, "Using buffer write method\n" );
-+ mtd->write = cfi_amdstd_write_buffers;
-+ } else {
-+ DEBUG(MTD_DEBUG_LEVEL1, "Using word write method\n" );
-+ mtd->write = cfi_amdstd_write_words;
-+ }
-+
- mtd->read = cfi_amdstd_read;
-- mtd->write = cfi_amdstd_write;
- break;
-
- default:
-- printk(KERN_WARNING "Unsupported buswidth\n");
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
- goto setup_err;
- break;
- }
- if (cfi->fast_prog) {
-- /* In cfi_amdstd_write() we frob the protection stuff
-+ /* In cfi_amdstd_write_words() we frob the protection stuff
- without paying any attention to the state machine.
- This upsets in-progress erases. So we turn this flag
- off for now till the code gets fixed. */
- printk(KERN_NOTICE "cfi_cmdset_0002: Disabling fast programming due to code brokenness.\n");
- cfi->fast_prog = 0;
- }
-+ /* FIXME: erase-suspend-program is broken. See
-+ http://lists.infradead.org/pipermail/linux-mtd/2003-December/009001.html */
-+ printk(KERN_NOTICE "cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.\n");
-
-
- /* does this chip have a secsi area? */
-@@ -266,7 +405,7 @@
- mtd->flags = MTD_CAP_NORFLASH;
- map->fldrv = &cfi_amdstd_chipdrv;
- mtd->name = map->name;
-- MOD_INC_USE_COUNT;
-+ __module_get(THIS_MODULE);
- return mtd;
-
- setup_err:
-@@ -280,46 +419,210 @@
- return NULL;
- }
-
--static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
-+
-+/* This is more work to coalesce the retry #ifdefs in one location */
-+static inline void handle_wacky_state(const char *func,
-+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
-+ int retry_cmd_cnt,
-+#endif
-+ unsigned long adr,
-+ cfi_word datum,
-+ cfi_word prev_oldstatus,
-+ cfi_word prev_status,
-+ cfi_word oldstatus,
-+ cfi_word status)
-+{
-+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
-+ if ( retry_cmd_cnt == retry_cmd_max ) {
-+#endif
-+ printk(KERN_WARNING
-+ "MTD %s(): Wacky! Unable to decode failure status\n"
-+ "Possible buggy device - try "
-+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
-+ "increasing retry_cmd_max from %d\n"
-+#else
-+ "enabling CONFIG_MTD_CFI_AMDSTD_RETRY\n"
-+ "in your kernel config and setting driver retry_cmd_max\n"
-+#endif
-+ , func
-+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
-+ , retry_cmd_max
-+#endif
-+ );
-+
-+ printk(KERN_WARNING
-+ "MTD %s(): 0x%.8lx(0x%.8x): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
-+ func, adr, datum,
-+ prev_oldstatus, prev_status,
-+ oldstatus, status);
-+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
-+ }
-+#endif
-+}
-+
-+
-+static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
- {
- DECLARE_WAITQUEUE(wait, current);
-- unsigned long timeo = jiffies + HZ;
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ cfi_word status, oldstatus;
-+ cfi_word dq6 = CMD(1<<6);
-+ cfi_word dq2 = CMD(1<<2);
-+ unsigned long timeo;
-+ struct cfi_pri_amdstd *cfip = (struct cfi_pri_amdstd *)cfi->cmdset_priv;
-
-+ resettime:
-+ timeo = jiffies + HZ;
- retry:
-+ switch (chip->state) {
-+
-+ case FL_STATUS:
-+ for (;;) {
-+ oldstatus = cfi_read(map, adr);
-+ status = cfi_read(map, adr);
-+ if (((oldstatus ^ status) & (dq6 | dq2)) == 0)
-+ break;
-+
-+ if (time_after(jiffies, timeo)) {
-+ printk(KERN_ERR "Waiting for chip to be ready timed out. Status %llx\n",
-+ (long long)status);
-+ cfi_spin_unlock(chip->mutex);
-+ return -EIO;
-+ }
-+ cfi_spin_unlock(chip->mutex);
-+ cfi_udelay(1);
- cfi_spin_lock(chip->mutex);
-+ /* Someone else might have been playing with it. */
-+ goto retry;
-+ }
-
-- if (chip->state != FL_READY){
--#if 0
-- printk(KERN_DEBUG "Waiting for chip to read, status = %d\n", chip->state);
--#endif
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-+ case FL_READY:
-+ case FL_CFI_QUERY:
-+ case FL_JEDEC_QUERY:
-+ return 0;
-+
-+ case FL_ERASING:
-+ if (mode == FL_WRITING) /* FIXME: Erase-suspend-program appears broken. */
-+ goto sleep;
-+
-+ if (!(mode == FL_READY || mode == FL_POINT
-+ || (mode == FL_WRITING && (cfip->EraseSuspend & 0x2))
-+ || (mode == FL_WRITING && (cfip->EraseSuspend & 0x1))))
-+ goto sleep;
-+
-+ oldstatus = cfi_read(map, adr);
-+ status = cfi_read(map, adr);
-+ if ((oldstatus ^ status) & dq2) {
-+ printk(KERN_ERR "Can't suspend erase -- block in progress\n");
-+ goto sleep;
-+ }
-+
-+ /* Erase suspend */
-+ /* FIXME - is there a way to verify suspend? */
-+ cfi_write(map, CMD(0xB0), chip->in_progress_block_addr);
-+ chip->oldstate = FL_ERASING;
-+ chip->state = FL_ERASE_SUSPENDING;
-+ chip->erase_suspended = 1;
-+ for (;;) {
-+ oldstatus = cfi_read(map, chip->in_progress_block_addr);
-+ status = cfi_read(map, chip->in_progress_block_addr);
-+ if (((oldstatus ^ status) & dq6) == 0)
-+ break;
-+
-+ if (time_after(jiffies, timeo)) {
-+ /* Urgh. Resume and pretend we weren't here. */
-+ /* FIXME - is there a way to verify resume? */
-+ cfi_write(map, CMD(0x30), chip->in_progress_block_addr);
-+ chip->state = FL_ERASING;
-+ chip->oldstate = FL_READY;
-+ printk(KERN_ERR "Chip not ready after erase "
-+ "suspended: status = 0x%x\n", status);
-+ return -EIO;
-+ }
-
- cfi_spin_unlock(chip->mutex);
-+ cfi_udelay(1);
-+ cfi_spin_lock(chip->mutex);
-+ /* Nobody will touch it while it's in state FL_ERASE_SUSPENDING.
-+ So we can just loop here. */
-+ }
-+ chip->state = FL_READY;
-+ return 0;
-+
-+ case FL_POINT:
-+ /* Only if there's no operation suspended... */
-+ if (mode == FL_READY && chip->oldstate == FL_READY)
-+ return 0;
-
-+ default:
-+ sleep:
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ add_wait_queue(&chip->wq, &wait);
-+ cfi_spin_unlock(chip->mutex);
- schedule();
- remove_wait_queue(&chip->wq, &wait);
--#if 0
-- if(signal_pending(current))
-- return -EINTR;
--#endif
-- timeo = jiffies + HZ;
-+ cfi_spin_lock(chip->mutex);
-+ goto resettime;
-+ }
-+}
-
-- goto retry;
-+
-+static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+
-+ switch(chip->oldstate) {
-+ case FL_ERASING:
-+ chip->state = chip->oldstate;
-+ cfi_write(map, CMD(0x30), chip->in_progress_block_addr);
-+ chip->oldstate = FL_READY;
-+ chip->state = FL_ERASING;
-+ break;
-+
-+ case FL_READY:
-+ case FL_STATUS:
-+ /* We should really make set_vpp() count, rather than doing this */
-+ DISABLE_VPP(map);
-+ break;
-+ default:
-+ printk(KERN_ERR "MTD: put_chip() called with oldstate %d!!\n", chip->oldstate);
- }
-+ wake_up(&chip->wq);
-+}
-+
-+
-+static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
-+{
-+ unsigned long cmd_addr;
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ int ret;
-
- adr += chip->start;
-
-+ /* Ensure cmd read/writes are aligned. */
-+ cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1);
-+
-+ cfi_spin_lock(chip->mutex);
-+ ret = get_chip(map, chip, cmd_addr, FL_READY);
-+ if (ret) {
-+ cfi_spin_unlock(chip->mutex);
-+ return ret;
-+ }
-+
-+ if (chip->state != FL_POINT && chip->state != FL_READY) {
-+ cfi_write(map, CMD(0xf0), cmd_addr);
- chip->state = FL_READY;
-+ }
-
-- map->copy_from(map, buf, adr, len);
-+ map_copy_from(map, buf, adr, len);
-
-- wake_up(&chip->wq);
-- cfi_spin_unlock(chip->mutex);
-+ put_chip(map, chip, cmd_addr);
-
-+ cfi_spin_unlock(chip->mutex);
- return 0;
- }
-
-+
- static int cfi_amdstd_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
- {
- struct map_info *map = mtd->priv;
-@@ -361,6 +664,7 @@
- return ret;
- }
-
-+
- static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
- {
- DECLARE_WAITQUEUE(wait, current);
-@@ -394,12 +698,14 @@
-
- chip->state = FL_READY;
-
-+ /* should these be CFI_DEVICETYPE_X8 instead of cfi->device_type? */
- cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
- cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
-
-- map->copy_from(map, buf, adr, len);
-+ map_copy_from(map, buf, adr, len);
-
-+ /* should these be CFI_DEVICETYPE_X8 instead of cfi->device_type? */
- cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
- cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
-@@ -454,125 +760,241 @@
- return ret;
- }
-
--static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, __u32 datum, int fast)
-+
-+static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, cfi_word datum, int fast)
- {
-- unsigned long timeo = jiffies + HZ;
-- unsigned int oldstatus, status;
-- unsigned int dq6, dq5;
- struct cfi_private *cfi = map->fldrv_priv;
-- DECLARE_WAITQUEUE(wait, current);
-+ unsigned long timeo = jiffies + HZ;
-+ cfi_word oldstatus, status, prev_oldstatus, prev_status;
-+ cfi_word dq6 = CMD(1<<6);
-+ /*
-+ * We use a 1ms + 1 jiffies generic timeout for writes (most devices
-+ * have a max write time of a few hundreds usec). However, we should
-+ * use the maximum timeout value given by the chip at probe time
-+ * instead. Unfortunately, struct flchip does have a field for
-+ * maximum timeout, only for typical which can be far too short
-+ * depending of the conditions. The ' + 1' is to avoid having a
-+ * timeout of 0 jiffies if HZ is smaller than 1000.
-+ */
-+ unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
- int ret = 0;
-+ int ta = 0;
-+ DECLARE_RETRY_CMD_CNT();
-
-- retry:
-- cfi_spin_lock(chip->mutex);
--
-- if (chip->state != FL_READY) {
--#if 0
-- printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", chip->state);
--#endif
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-+ adr += chip->start;
-
-+ cfi_spin_lock(chip->mutex);
-+ ret = get_chip(map, chip, adr, FL_WRITING);
-+ if (ret) {
- cfi_spin_unlock(chip->mutex);
--
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
--#if 0
-- printk(KERN_DEBUG "Wake up to write:\n");
-- if(signal_pending(current))
-- return -EINTR;
--#endif
-- timeo = jiffies + HZ;
--
-- goto retry;
-+ return ret;
- }
-
-- chip->state = FL_WRITING;
-+ RETRY_CMD_LABEL;
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8x)\n",
-+ __func__, adr, datum );
-+
-+ /*
-+ * Check for a NOP for the case when the datum to write is already
-+ * present - it saves time and works around buggy chips that corrupt
-+ * data at other locations when 0xff is written to a location that
-+ * already contains 0xff.
-+ */
-+ status = cfi_read(map, adr);
-+ if (status == datum) {
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): NOP 0x%.8x == 0x%.8x\n",
-+ __func__, status, datum );
-+ goto op_done;
-+ }
-
-- adr += chip->start;
- ENABLE_VPP(map);
- if (fast) { /* Unlock bypass */
- cfi_send_gen_cmd(0xA0, 0, chip->start, map, cfi, cfi->device_type, NULL);
-- }
-- else {
-+ } else {
-+ /*
-+ * The CFI_DEVICETYPE_X8 argument is needed even when
-+ * cfi->device_type != CFI_DEVICETYPE_X8. The addresses for
-+ * command sequences don't scale even when the device is
-+ * wider. This is the case for many of the cfi_send_gen_cmd()
-+ * below. I'm not sure, however, why some use
-+ * cfi->device_type.
-+ */
- cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- }
--
- cfi_write(map, datum, adr);
-+ chip->state = FL_WRITING;
-
- cfi_spin_unlock(chip->mutex);
- cfi_udelay(chip->word_write_time);
- cfi_spin_lock(chip->mutex);
-
-- /* Polling toggle bits instead of reading back many times
-- This ensures that write operation is really completed,
-- or tells us why it failed. */
-- dq6 = CMD(1<<6);
-- dq5 = CMD(1<<5);
-- timeo = jiffies + (HZ/1000); /* setting timeout to 1ms for now */
-+ /*
-+ * Polling toggle bits instead of reading back many times This ensures
-+ * that write operation is really completed, or tells us why it
-+ * failed.
-+ *
-+ * It may appear that the polling and decoding of error state might be
-+ * simplified. Don't do it unless you really know what you are doing.
-+ *
-+ * You must remember that JESD21-C 3.5.3 states that the status must
-+ * be read back an _additional_ two times before a failure is
-+ * determined. This is because these devices have internal state
-+ * machines that are asynchronous to the external data bus. During an
-+ * erase or write the read-back status of the polling bits might be
-+ * transitioning internaly when the external read-back occurs. This
-+ * means that the bits aren't in the final state and they might appear
-+ * to report an error as they are in a transient state: dq7 is
-+ * asynchronous with dq6 and other status bits.
-+ *
-+ * This asynchronous behaviour can cause infrequent errors that will
-+ * usually disappear the next time an erase or write happens (Try
-+ * tracking those errors down!). To ensure that the bits are not in
-+ * transition, the location must be read-back two more times and
-+ * compared against what was written - BOTH reads MUST match what was
-+ * written. Don't think this can be simplified to only the last read
-+ * matching the datum written: status bits *can* match the datum
-+ * written.
-+ *
-+ * If the final comparison fails, error state can *then* be decoded.
-+ *
-+ * - Thayne Harbaugh
-+ */
-+ /* See comment above for timeout value. */
-+ timeo = jiffies + uWriteTimeout;
-+ for (;;) {
-+ if (chip->state != FL_WRITING) {
-+ /* Someone's suspended the write. Sleep */
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ add_wait_queue(&chip->wq, &wait);
-+ cfi_spin_unlock(chip->mutex);
-+ schedule();
-+ remove_wait_queue(&chip->wq, &wait);
-+ timeo = jiffies + (HZ / 2); /* FIXME */
-+ cfi_spin_lock(chip->mutex);
-+ continue;
-+ }
-
- oldstatus = cfi_read(map, adr);
- status = cfi_read(map, adr);
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n",
-+ __func__, oldstatus, status );
-
-- while( (status & dq6) != (oldstatus & dq6) &&
-- (status & dq5) != dq5 &&
-- !time_after(jiffies, timeo) ) {
-+ /*
-+ * This only checks if dq6 is still toggling and that our
-+ * timer hasn't expired. We purposefully ignore the chip's
-+ * internal timer that will assert dq5 and leave dq6 toggling.
-+ * This is done for a variety of reasons:
-+ *
-+ * 1) Not all chips support dq5.
-+ *
-+ * 2) Dealing with asynchronous status bit and data updates
-+ * and reading a device two more times creates _messy_ logic
-+ * when trying to deal with interleaved devices - some may be
-+ * changing while others are still busy.
-+ *
-+ * 3) Checking dq5 only helps to optimize an error case that
-+ * should at worst be infrequent and at best non-existent.
-+ *
-+ * If our timeout occurs _then_ we will check dq5 to see if
-+ * the device also had an internal timeout.
-+ */
-+ if ( (((status ^ oldstatus) & dq6) == 0)
-+ || ( ta = time_after(jiffies, timeo)) )
-+ break;
-
-- if (need_resched()) {
-+ /* Latency issues. Drop the lock, wait a while and retry */
- cfi_spin_unlock(chip->mutex);
-- yield();
-+ cfi_udelay(1);
- cfi_spin_lock(chip->mutex);
-- } else
-- udelay(1);
--
-- oldstatus = cfi_read( map, adr );
-- status = cfi_read( map, adr );
- }
-
-- if( (status & dq6) != (oldstatus & dq6) ) {
-- /* The erasing didn't stop?? */
-- if( (status & dq5) == dq5 ) {
-- /* When DQ5 raises, we must check once again
-- if DQ6 is toggling. If not, the erase has been
-- completed OK. If not, reset chip. */
-+ /*
-+ * Something kicked us out of the read-back loop. We'll check success
-+ * befor checking failure. Even though dq6 might be true data, it is
-+ * unkown if all of the other bits have changed to true data due to
-+ * the asynchronous nature of the internal state machine. We will
-+ * read two more times and use this to either verify that the write
-+ * completed successfully or that something really went wrong. BOTH
-+ * reads must match what was written - this certifies that bits aren't
-+ * still changing and that the status bits erroneously match the datum
-+ * that was written.
-+ */
-+ prev_oldstatus = oldstatus;
-+ prev_status = status;
- oldstatus = cfi_read(map, adr);
- status = cfi_read(map, adr);
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n",
-+ __func__, oldstatus, status );
-
-- if ( (oldstatus & 0x00FF) == (status & 0x00FF) ) {
-- printk(KERN_WARNING "Warning: DQ5 raised while program operation was in progress, however operation completed OK\n" );
-+ if ( oldstatus == datum && status == datum ) {
-+ /* success - do nothing */
-+ goto op_done;
-+ }
-+
-+ if ( ta ) {
-+ /* Only check dq5 on the chips that are still toggling. */
-+ cfi_word dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1;
-+ if ( status & dq5mask ) {
-+ /* dq5 asserted - decode interleave chips */
-+ printk( KERN_WARNING
-+ "MTD %s(): FLASH internal timeout: 0x%.8x 0x%.8x 0x%8x\n",
-+ __func__,
-+ status & dq5mask, status, datum );
- } else {
-- /* DQ5 is active so we can do a reset and stop the erase */
-- cfi_write(map, CMD(0xF0), chip->start);
-- printk(KERN_WARNING "Internal flash device timeout occurred or write operation was performed while flash was programming.\n" );
-+ printk( KERN_WARNING
-+ "MTD %s(): Software timed out during write.\n",
-+ __func__ );
-+ }
-+ goto op_failed;
- }
-- } else {
-- printk(KERN_WARNING "Waiting for write to complete timed out in do_write_oneword.");
-
-+ /*
-+ * If we get to here then it means that something
-+ * is wrong and it's not a timeout. Something
-+ * is seriously wacky! Dump some debug info.
-+ */
-+ /*
-+ * Found a clue about the chips that reach this state.
-+ * Some flash chips (SST >cough<)
-+ * are horribly broken. They do not ignore traffic that is
-+ * destined to other devices. This happens because some solutions
-+ * are on shared busses, the erase and program sequences have
-+ * have multiple commands, and the sequence is interspersed with
-+ * commands destined to other devices. A good flash chip will
-+ * examine the command and destination address and will ignore
-+ * commands that are for other devices.
-+ */
-+ HANDLE_WACKY_STATE();
-+
-+ op_failed:
-+ /* reset on all failures. */
-+ cfi_write( map, CMD(0xF0), chip->start );
-+ /* FIXME - should have reset delay before continuing */
-+ CHECK_RETRIES();
-+ ret = -EIO;
-+
-+ op_done:
- chip->state = FL_READY;
-- wake_up(&chip->wq);
-- cfi_spin_unlock(chip->mutex);
-- DISABLE_VPP(map);
-- ret = -EIO;
-- }
-- }
--
-- DISABLE_VPP(map);
-- chip->state = FL_READY;
-- wake_up(&chip->wq);
-+ put_chip(map, chip, adr);
- cfi_spin_unlock(chip->mutex);
-
- return ret;
- }
-
--static int cfi_amdstd_write (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf)
-+
-+static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf)
- {
- struct map_info *map = mtd->priv;
- struct cfi_private *cfi = map->fldrv_priv;
- int ret = 0;
- int chipnum;
- unsigned long ofs, chipstart;
-+ DECLARE_WAITQUEUE(wait, current);
-
- *retlen = 0;
- if (!len)
-@@ -587,19 +1009,52 @@
- unsigned long bus_ofs = ofs & ~(CFIDEV_BUSWIDTH-1);
- int i = ofs - bus_ofs;
- int n = 0;
-- u_char tmp_buf[4];
-- __u32 datum;
-+ u_char tmp_buf[8];
-+ cfi_word datum;
-+
-+ retry:
-+ cfi_spin_lock(cfi->chips[chipnum].mutex);
-+
-+ if (cfi->chips[chipnum].state != FL_READY) {
-+#if 0
-+ printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", cfi->chips[chipnum].state);
-+#endif
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ add_wait_queue(&cfi->chips[chipnum].wq, &wait);
-+
-+ cfi_spin_unlock(cfi->chips[chipnum].mutex);
-+
-+ schedule();
-+ remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
-+#if 0
-+ if(signal_pending(current))
-+ return -EINTR;
-+#endif
-+ goto retry;
-+ }
-+
-+ map_copy_from(map, tmp_buf, bus_ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
-
-- map->copy_from(map, tmp_buf, bus_ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
-- while (len && i < CFIDEV_BUSWIDTH)
-- tmp_buf[i++] = buf[n++], len--;
-+ cfi_spin_unlock(cfi->chips[chipnum].mutex);
-+
-+ while (len && i < CFIDEV_BUSWIDTH) {
-+ tmp_buf[i++] = buf[n++];
-+ len--;
-+ }
-
-+ /* already know that buswidth > 1 */
- if (cfi_buswidth_is_2()) {
- datum = *(__u16*)tmp_buf;
- } else if (cfi_buswidth_is_4()) {
- datum = *(__u32*)tmp_buf;
-+#ifdef CFI_WORD_64
-+ } else if (cfi_buswidth_is_8()) {
-+ datum = *(__u64*)tmp_buf;
-+#endif
- } else {
-- return -EINVAL; /* should never happen, but be safe */
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
-+ return -EINVAL;
- }
-
- ret = do_write_oneword(map, &cfi->chips[chipnum],
-@@ -628,7 +1083,7 @@
-
- /* We are now aligned, write as much as possible */
- while(len >= CFIDEV_BUSWIDTH) {
-- __u32 datum;
-+ cfi_word datum;
-
- if (cfi_buswidth_is_1()) {
- datum = *(__u8*)buf;
-@@ -636,7 +1091,13 @@
- datum = *(__u16*)buf;
- } else if (cfi_buswidth_is_4()) {
- datum = *(__u32*)buf;
-+#ifdef CFI_WORD_64
-+ } else if (cfi_buswidth_is_8()) {
-+ datum = *(__u64*)buf;
-+#endif
- } else {
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
- return -EINVAL;
- }
- ret = do_write_oneword(map, &cfi->chips[chipnum],
-@@ -685,10 +1146,34 @@
- /* Write the trailing bytes if any */
- if (len & (CFIDEV_BUSWIDTH-1)) {
- int i = 0, n = 0;
-- u_char tmp_buf[4];
-- __u32 datum;
-+ u_char tmp_buf[8];
-+ cfi_word datum;
-+
-+ retry1:
-+ cfi_spin_lock(cfi->chips[chipnum].mutex);
-+
-+ if (cfi->chips[chipnum].state != FL_READY) {
-+#if 0
-+ printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", cfi->chips[chipnum].state);
-+#endif
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ add_wait_queue(&cfi->chips[chipnum].wq, &wait);
-+
-+ cfi_spin_unlock(cfi->chips[chipnum].mutex);
-+
-+ schedule();
-+ remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
-+#if 0
-+ if(signal_pending(current))
-+ return -EINTR;
-+#endif
-+ goto retry1;
-+ }
-+
-+ map_copy_from(map, tmp_buf, ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
-+
-+ cfi_spin_unlock(cfi->chips[chipnum].mutex);
-
-- map->copy_from(map, tmp_buf, ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
- while (len--)
- tmp_buf[i++] = buf[n++];
-
-@@ -696,8 +1181,14 @@
- datum = *(__u16*)tmp_buf;
- } else if (cfi_buswidth_is_4()) {
- datum = *(__u32*)tmp_buf;
-+#ifdef CFI_WORD_64
-+ } else if (cfi_buswidth_is_8()) {
-+ datum = *(__u64*)tmp_buf;
-+#endif
- } else {
-- return -EINVAL; /* should never happen, but be safe */
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
-+ return -EINVAL;
- }
-
- ret = do_write_oneword(map, &cfi->chips[chipnum],
-@@ -711,289 +1202,446 @@
- return 0;
- }
-
--static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
-+
-+/*
-+ * FIXME: interleaved mode not tested, and probably not supported!
-+ */
-+static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
-+ unsigned long adr, const u_char *buf, int len)
- {
-- unsigned int oldstatus, status;
-- unsigned int dq6, dq5;
-- unsigned long timeo = jiffies + HZ;
-- unsigned int adr;
- struct cfi_private *cfi = map->fldrv_priv;
-- DECLARE_WAITQUEUE(wait, current);
--
-- retry:
-- cfi_spin_lock(chip->mutex);
-+ unsigned long timeo = jiffies + HZ;
-+ cfi_word oldstatus, status, prev_oldstatus, prev_status;
-+ cfi_word dq6 = CMD(1<<6);
-+ /* see comments in do_write_oneword() regarding uWriteTimeo. */
-+ static unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
-+ int ret = -EIO;
-+ int ta = 0;
-+ unsigned long cmd_adr;
-+ int z, bytes, words;
-+ cfi_word datum;
-+ DECLARE_RETRY_CMD_CNT();
-
-- if (chip->state != FL_READY){
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-+ adr += chip->start;
-+ cmd_adr = adr;
-
-+ cfi_spin_lock(chip->mutex);
-+ ret = get_chip(map, chip, adr, FL_WRITING);
-+ if (ret) {
- cfi_spin_unlock(chip->mutex);
-+ return ret;
-+ }
-
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
--#if 0
-- if(signal_pending(current))
-- return -EINTR;
-+ if (cfi_buswidth_is_1()) {
-+ datum = *(__u8*)buf;
-+ } else if (cfi_buswidth_is_2()) {
-+ datum = *(__u16*)buf;
-+ } else if (cfi_buswidth_is_4()) {
-+ datum = *(__u32*)buf;
-+#ifdef CFI_WORD_64
-+ } else if (cfi_buswidth_is_8()) {
-+ datum = *(__u64*)buf;
- #endif
-- timeo = jiffies + HZ;
--
-- goto retry;
-+ } else {
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
-+ return -EINVAL;
- }
-
-- chip->state = FL_ERASING;
-+ RETRY_CMD_LABEL;
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8x)\n",
-+ __func__, adr, datum );
-
-- /* Handle devices with one erase region, that only implement
-- * the chip erase command.
-- */
- ENABLE_VPP(map);
- cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-- cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-- cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-- cfi_send_gen_cmd(0x10, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-- timeo = jiffies + (HZ*20);
-- adr = cfi->addr_unlock1;
-+ //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-
-- /* Wait for the end of programing/erasure by using the toggle method.
-- * As long as there is a programming procedure going on, bit 6 of the last
-- * written byte is toggling it's state with each consectuve read.
-- * The toggling stops as soon as the procedure is completed.
-- *
-- * If the process has gone on for too long on the chip bit 5 gets.
-- * After bit5 is set you can kill the operation by sending a reset
-- * command to the chip.
-- */
-- dq6 = CMD(1<<6);
-- dq5 = CMD(1<<5);
-+ /* Write Buffer Load */
-+ cfi_write(map, CMD(0x25), cmd_adr);
-
-- oldstatus = cfi_read(map, adr);
-- status = cfi_read(map, adr);
-- while( ((status & dq6) != (oldstatus & dq6)) &&
-- ((status & dq5) != dq5) &&
-- !time_after(jiffies, timeo)) {
-- int wait_reps;
-+ chip->state = FL_WRITING_TO_BUFFER;
-+
-+ /* Write length of data to come */
-+ bytes = len & (CFIDEV_BUSWIDTH-1);
-+ words = len / CFIDEV_BUSWIDTH;
-+ cfi_write(map, CMD(words - !bytes), cmd_adr );
-+ /* Write data */
-+ z = 0;
-+ while(z < words * CFIDEV_BUSWIDTH) {
-+ if (cfi_buswidth_is_1()) {
-+ datum = *((__u8*)buf);
-+ map_write8 (map, *((__u8*)buf)++, adr+z);
-+ } else if (cfi_buswidth_is_2()) {
-+ datum = *((__u16*)buf);
-+ map_write16 (map, *((__u16*)buf)++, adr+z);
-+ } else if (cfi_buswidth_is_4()) {
-+ datum = *((__u32*)buf);
-+ map_write32 (map, *((__u32*)buf)++, adr+z);
-+#ifdef CFI_WORD_64
-+ } else if (cfi_buswidth_is_8()) {
-+ datum = *((__u64*)buf);
-+ map_write64 (map, *((__u64*)buf)++, adr+z);
-+#endif
-+ } else {
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
-+ ret = -EINVAL;
-+ goto op_failed;
-+ }
-+ z += CFIDEV_BUSWIDTH;
-+ }
-+ if (bytes) {
-+ int i = 0, n = 0;
-+ u_char tmp_buf[8], *tmp_p = tmp_buf;
-+
-+ while (bytes--)
-+ tmp_buf[i++] = buf[n++];
-+ while (i < CFIDEV_BUSWIDTH)
-+ tmp_buf[i++] = 0xff;
-+ if (cfi_buswidth_is_2()) {
-+ datum = *((__u16*)tmp_p);
-+ map_write16 (map, *((__u16*)tmp_p)++, adr+z);
-+ } else if (cfi_buswidth_is_4()) {
-+ datum = *((__u32*)tmp_p);
-+ map_write32 (map, *((__u32*)tmp_p)++, adr+z);
-+#ifdef CFI_WORD_64
-+ } else if (cfi_buswidth_is_8()) {
-+ datum = *((__u64*)tmp_p);
-+ map_write64 (map, *((__u64*)tmp_p)++, adr+z);
-+#endif
-+ } else {
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
-+ ret = -EINVAL;
-+ goto op_failed;
-+ }
-+ } else if (words > 0) {
-+ z -= CFIDEV_BUSWIDTH;
-+ }
-+
-+ adr += z;
-+
-+ /* Write Buffer Program Confirm: GO GO GO */
-+ cfi_write(map, CMD(0x29), cmd_adr);
-+ chip->state = FL_WRITING;
-
-- /* an initial short sleep */
- cfi_spin_unlock(chip->mutex);
-- schedule_timeout(HZ/100);
-+ cfi_udelay(chip->buffer_write_time);
- cfi_spin_lock(chip->mutex);
-
-- if (chip->state != FL_ERASING) {
-- /* Someone's suspended the erase. Sleep */
-+ timeo = jiffies + uWriteTimeout;
-+
-+ for (;;) {
-+ if (chip->state != FL_WRITING) {
-+ /* Someone's suspended the write. Sleep */
-+ DECLARE_WAITQUEUE(wait, current);
-+
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&chip->wq, &wait);
--
- cfi_spin_unlock(chip->mutex);
-- printk("erase suspended. Sleeping\n");
--
- schedule();
- remove_wait_queue(&chip->wq, &wait);
--#if 0
-- if (signal_pending(current))
-- return -EINTR;
--#endif
-- timeo = jiffies + (HZ*2); /* FIXME */
-+ timeo = jiffies + (HZ / 2); /* FIXME */
- cfi_spin_lock(chip->mutex);
- continue;
- }
-
-- /* Busy wait for 1/10 of a milisecond */
-- for(wait_reps = 0;
-- (wait_reps < 100) &&
-- ((status & dq6) != (oldstatus & dq6)) &&
-- ((status & dq5) != dq5);
-- wait_reps++) {
-+ oldstatus = cfi_read(map, adr);
-+ status = cfi_read(map, adr);
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n",
-+ __func__, oldstatus, status );
-+
-+ /* See comments in do_write_oneword() about checking status */
-+ if ( (((status ^ oldstatus) & dq6) == 0)
-+ || ( ta = time_after(jiffies, timeo)) ) {
-+ break;
-+ }
-
- /* Latency issues. Drop the lock, wait a while and retry */
- cfi_spin_unlock(chip->mutex);
--
- cfi_udelay(1);
--
- cfi_spin_lock(chip->mutex);
-- oldstatus = cfi_read(map, adr);
-- status = cfi_read(map, adr);
- }
-+
-+ /* See comments in do_write_oneword() about "two more checks" */
-+ prev_oldstatus = oldstatus;
-+ prev_status = status;
- oldstatus = cfi_read(map, adr);
- status = cfi_read(map, adr);
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n",
-+ __func__, oldstatus, status );
-+
-+ if ( oldstatus == datum && status == datum ) {
-+ /* success - do nothing */
-+ goto op_done;
-+ }
-+
-+ if ( ta ) {
-+ /* Only check dq5 on the chips that are still toggling. */
-+ cfi_word dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1;
-+ if ( status & dq5mask ) {
-+ /* dq5 asserted - decode interleave chips */
-+ printk( KERN_WARNING
-+ "MTD %s(): FLASH internal timeout: 0x%.8x 0x%.8x 0x%8x\n",
-+ __func__,
-+ status & dq5mask, status, datum );
-+ } else {
-+ printk( KERN_WARNING
-+ "MTD %s(): Software timed out during write.\n",
-+ __func__ );
- }
-- if ((status & dq6) != (oldstatus & dq6)) {
-- /* The erasing didn't stop?? */
-- if ((status & dq5) == dq5) {
-- /* dq5 is active so we can do a reset and stop the erase */
-- cfi_write(map, CMD(0xF0), chip->start);
-+ goto op_failed;
- }
-+
-+ HANDLE_WACKY_STATE();
-+
-+ op_failed:
-+ /* reset on all failures. */
-+ cfi_write( map, CMD(0xF0), chip->start );
-+ /* FIXME - should have reset delay before continuing */
-+ CHECK_RETRIES();
-+ ret = -EIO;
-+
-+ op_done:
- chip->state = FL_READY;
-- wake_up(&chip->wq);
-+ put_chip(map, chip, adr);
- cfi_spin_unlock(chip->mutex);
-- printk("waiting for erase to complete timed out.");
-- DISABLE_VPP(map);
-- return -EIO;
-+
-+ return ret;
-+}
-+
-+
-+static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf)
-+{
-+ struct map_info *map = mtd->priv;
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ int wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize;
-+ int ret = 0;
-+ int chipnum;
-+ unsigned long ofs;
-+
-+ *retlen = 0;
-+ if (!len)
-+ return 0;
-+
-+ chipnum = to >> cfi->chipshift;
-+ ofs = to - (chipnum << cfi->chipshift);
-+
-+ /* If it's not bus-aligned, do the first word write */
-+ if (ofs & (CFIDEV_BUSWIDTH-1)) {
-+ size_t local_len = (-ofs)&(CFIDEV_BUSWIDTH-1);
-+ if (local_len > len)
-+ local_len = len;
-+ ret = cfi_amdstd_write_words(mtd, to, local_len,
-+ retlen, buf);
-+ if (ret)
-+ return ret;
-+ ofs += local_len;
-+ buf += local_len;
-+ len -= local_len;
-+
-+ if (ofs >> cfi->chipshift) {
-+ chipnum ++;
-+ ofs = 0;
-+ if (chipnum == cfi->numchips)
-+ return 0;
-+ }
-+ }
-+
-+ /* Write buffer is worth it only if more than one word to write... */
-+ while (len) {
-+ /* We must not cross write block boundaries */
-+ int size = wbufsize - (ofs & (wbufsize-1));
-+
-+ if (size > len)
-+ size = len;
-+ ret = do_write_buffer(map, &cfi->chips[chipnum],
-+ ofs, buf, size);
-+ if (ret)
-+ return ret;
-+
-+ ofs += size;
-+ buf += size;
-+ (*retlen) += size;
-+ len -= size;
-+
-+ if (ofs >> cfi->chipshift) {
-+ chipnum ++;
-+ ofs = 0;
-+ if (chipnum == cfi->numchips)
-+ return 0;
-+ }
- }
-- DISABLE_VPP(map);
-- chip->state = FL_READY;
-- wake_up(&chip->wq);
-- cfi_spin_unlock(chip->mutex);
-
- return 0;
- }
-
--static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
-+
-+/*
-+ * Handle devices with one erase region, that only implement
-+ * the chip erase command.
-+ */
-+static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
- {
-- unsigned int oldstatus, status;
-- unsigned int dq6, dq5;
-- unsigned long timeo = jiffies + HZ;
- struct cfi_private *cfi = map->fldrv_priv;
-+ cfi_word oldstatus, status, prev_oldstatus, prev_status;
-+ cfi_word dq6 = CMD(1<<6);
-+ unsigned long timeo = jiffies + HZ;
-+ unsigned long int adr;
- DECLARE_WAITQUEUE(wait, current);
-+ int ret = 0;
-+ int ta = 0;
-+ cfi_word datum = 0;
-+ DECLARE_RETRY_CMD_CNT();
-
-- retry:
-- cfi_spin_lock(chip->mutex);
--
-- if (chip->state != FL_READY){
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-+ adr = cfi->addr_unlock1;
-
-+ cfi_spin_lock(chip->mutex);
-+ ret = get_chip(map, chip, adr, FL_WRITING);
-+ if (ret) {
- cfi_spin_unlock(chip->mutex);
--
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
--#if 0
-- if(signal_pending(current))
-- return -EINTR;
--#endif
-- timeo = jiffies + HZ;
--
-- goto retry;
-+ return ret;
- }
-
-- chip->state = FL_ERASING;
-+ RETRY_CMD_LABEL;
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
-+ __func__, chip->start );
-
-- adr += chip->start;
- ENABLE_VPP(map);
- cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-- cfi_write(map, CMD(0x30), adr);
--
-- timeo = jiffies + (HZ*20);
--
-- /* Wait for the end of programing/erasure by using the toggle method.
-- * As long as there is a programming procedure going on, bit 6 of the last
-- * written byte is toggling it's state with each consectuve read.
-- * The toggling stops as soon as the procedure is completed.
-- *
-- * If the process has gone on for too long on the chip bit 5 gets.
-- * After bit5 is set you can kill the operation by sending a reset
-- * command to the chip.
-- */
-- dq6 = CMD(1<<6);
-- dq5 = CMD(1<<5);
-+ cfi_send_gen_cmd(0x10, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-
-- oldstatus = cfi_read(map, adr);
-- status = cfi_read(map, adr);
-- while( ((status & dq6) != (oldstatus & dq6)) &&
-- ((status & dq5) != dq5) &&
-- !time_after(jiffies, timeo)) {
-- int wait_reps;
-+ chip->state = FL_ERASING;
-+ chip->erase_suspended = 0;
-+ chip->in_progress_block_addr = adr;
-
-- /* an initial short sleep */
- cfi_spin_unlock(chip->mutex);
-- schedule_timeout(HZ/100);
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ schedule_timeout((chip->erase_time*HZ)/(2*1000));
- cfi_spin_lock(chip->mutex);
-
-+ timeo = jiffies + (HZ*20);
-+
-+ for (;;) {
- if (chip->state != FL_ERASING) {
- /* Someone's suspended the erase. Sleep */
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&chip->wq, &wait);
--
- cfi_spin_unlock(chip->mutex);
-- printk(KERN_DEBUG "erase suspended. Sleeping\n");
--
- schedule();
- remove_wait_queue(&chip->wq, &wait);
--#if 0
-- if (signal_pending(current))
-- return -EINTR;
--#endif
-- timeo = jiffies + (HZ*2); /* FIXME */
- cfi_spin_lock(chip->mutex);
- continue;
- }
-+ if (chip->erase_suspended) {
-+ /* This erase was suspended and resumed.
-+ Adjust the timeout */
-+ timeo = jiffies + (HZ*20); /* FIXME */
-+ chip->erase_suspended = 0;
-+ }
-
-- /* Busy wait for 1/10 of a milisecond */
-- for(wait_reps = 0;
-- (wait_reps < 100) &&
-- ((status & dq6) != (oldstatus & dq6)) &&
-- ((status & dq5) != dq5);
-- wait_reps++) {
-+ oldstatus = cfi_read(map, adr);
-+ status = cfi_read(map, adr);
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n",
-+ __func__, oldstatus, status );
-+ if ( (((status ^ oldstatus) & dq6) == 0)
-+ || ( ta = time_after(jiffies, timeo)) )
-+ break;
-
- /* Latency issues. Drop the lock, wait a while and retry */
- cfi_spin_unlock(chip->mutex);
--
-- cfi_udelay(1);
--
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ schedule_timeout(1);
- cfi_spin_lock(chip->mutex);
-- oldstatus = cfi_read(map, adr);
-- status = cfi_read(map, adr);
- }
-+
-+ prev_oldstatus = oldstatus;
-+ prev_status = status;
- oldstatus = cfi_read(map, adr);
- status = cfi_read(map, adr);
-- }
-- if( (status & dq6) != (oldstatus & dq6) )
-- {
-- /* The erasing didn't stop?? */
-- if( ( status & dq5 ) == dq5 )
-- {
-- /* When DQ5 raises, we must check once again if DQ6 is toggling.
-- If not, the erase has been completed OK. If not, reset chip. */
-- oldstatus = cfi_read( map, adr );
-- status = cfi_read( map, adr );
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n",
-+ __func__, oldstatus, status );
-
-- if( ( oldstatus & 0x00FF ) == ( status & 0x00FF ) )
-- {
-- printk( "Warning: DQ5 raised while erase operation was in progress, but erase completed OK\n" );
-- }
-- else
-- {
-- /* DQ5 is active so we can do a reset and stop the erase */
-- cfi_write(map, CMD(0xF0), chip->start);
-- printk( KERN_WARNING "Internal flash device timeout occured or write operation was performed while flash was erasing\n" );
-+ if ( cfi_buswidth_is_1() ) {
-+ datum = (__u8)~0;
-+ } else if ( cfi_buswidth_is_2() ) {
-+ datum = (__u16)~0;
-+ } else if ( cfi_buswidth_is_4() ) {
-+ datum = (__u32)~0;
-+#ifdef CFI_WORD_64
-+ } else if ( cfi_buswidth_is_8() ) {
-+ datum = (__u64)~0;
-+#endif
-+ } else {
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
-+ goto op_failed;
-+ }
-+
-+ if ( oldstatus == datum && status == datum ) {
-+ /* success - do nothing */
-+ goto op_done;
-+ }
-+
-+ if ( ta ) {
-+ /* Only check dq5 on the chips that are still toggling. */
-+ cfi_word dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1;
-+ if ( status & dq5mask ) {
-+ /* dq5 asserted - decode interleave chips */
-+ printk( KERN_WARNING
-+ "MTD %s(): FLASH internal timeout: 0x%.8x\n",
-+ __func__,
-+ status & dq5mask );
-+ } else {
-+ printk( KERN_WARNING
-+ "MTD %s(): Software timed out during write.\n",
-+ __func__ );
- }
-+ goto op_failed;
- }
-- else
-- {
-- printk( "Waiting for erase to complete timed out in do_erase_oneblock.");
-
-- chip->state = FL_READY;
-- wake_up(&chip->wq);
-- cfi_spin_unlock(chip->mutex);
-- DISABLE_VPP(map);
-- return -EIO;
-- }
-- }
-+ HANDLE_WACKY_STATE();
-
-- DISABLE_VPP(map);
-+ op_failed:
-+ /* reset on all failures. */
-+ cfi_write( map, CMD(0xF0), chip->start );
-+ /* FIXME - should have reset delay before continuing */
-+ CHECK_RETRIES();
-+ ret = -EIO;
-+
-+ op_done:
- chip->state = FL_READY;
-- wake_up(&chip->wq);
-+ put_chip(map, chip, adr);
- cfi_spin_unlock(chip->mutex);
-- return 0;
-+
-+ return ret;
- }
-
--static int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
-+
-+typedef int (*frob_t)(struct map_info *map, struct flchip *chip,
-+ unsigned long adr, void *thunk);
-+
-+
-+static int cfi_amdstd_varsize_frob(struct mtd_info *mtd, frob_t frob,
-+ loff_t ofs, size_t len, void *thunk)
- {
- struct map_info *map = mtd->priv;
- struct cfi_private *cfi = map->fldrv_priv;
-- unsigned long adr, len;
-+ unsigned long adr;
- int chipnum, ret = 0;
- int i, first;
- struct mtd_erase_region_info *regions = mtd->eraseregions;
-
-- if (instr->addr > mtd->size)
-+ if (ofs > mtd->size)
- return -EINVAL;
-
-- if ((instr->len + instr->addr) > mtd->size)
-+ if ((len + ofs) > mtd->size)
- return -EINVAL;
-
- /* Check that both start and end of the requested erase are
-@@ -1008,7 +1656,7 @@
- start of the requested erase, and then go back one.
- */
-
-- while (i < mtd->numeraseregions && instr->addr >= regions[i].offset)
-+ while (i < mtd->numeraseregions && ofs >= regions[i].offset)
- i++;
- i--;
-
-@@ -1018,7 +1666,7 @@
- effect here.
- */
-
-- if (instr->addr & (regions[i].erasesize-1))
-+ if (ofs & (regions[i].erasesize-1))
- return -EINVAL;
-
- /* Remember the erase region we start on */
-@@ -1028,7 +1676,7 @@
- * with the erase region at that address.
- */
-
-- while (i<mtd->numeraseregions && (instr->addr + instr->len) >= regions[i].offset)
-+ while (i<mtd->numeraseregions && (ofs + len) >= regions[i].offset)
- i++;
-
- /* As before, drop back one to point at the region in which
-@@ -1036,17 +1684,16 @@
- */
- i--;
-
-- if ((instr->addr + instr->len) & (regions[i].erasesize-1))
-+ if ((ofs + len) & (regions[i].erasesize-1))
- return -EINVAL;
-
-- chipnum = instr->addr >> cfi->chipshift;
-- adr = instr->addr - (chipnum << cfi->chipshift);
-- len = instr->len;
-+ chipnum = ofs >> cfi->chipshift;
-+ adr = ofs - (chipnum << cfi->chipshift);
-
- i=first;
-
-- while(len) {
-- ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
-+ while (len) {
-+ ret = (*frob)(map, &cfi->chips[chipnum], adr, thunk);
-
- if (ret)
- return ret;
-@@ -1066,50 +1713,171 @@
- }
- }
-
-- instr->state = MTD_ERASE_DONE;
-- if (instr->callback)
-- instr->callback(instr);
--
- return 0;
- }
-
--static int cfi_amdstd_erase_onesize(struct mtd_info *mtd, struct erase_info *instr)
-+
-+static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, void *thunk)
- {
-- struct map_info *map = mtd->priv;
- struct cfi_private *cfi = map->fldrv_priv;
-- unsigned long adr, len;
-- int chipnum, ret = 0;
-+ cfi_word oldstatus, status, prev_oldstatus, prev_status;
-+ cfi_word dq6 = CMD(1<<6);
-+ unsigned long timeo = jiffies + HZ;
-+ DECLARE_WAITQUEUE(wait, current);
-+ int ret = 0;
-+ int ta = 0;
-+ cfi_word datum = 0;
-+ DECLARE_RETRY_CMD_CNT();
-
-- if (instr->addr & (mtd->erasesize - 1))
-- return -EINVAL;
-+ adr += chip->start;
-
-- if (instr->len & (mtd->erasesize -1))
-- return -EINVAL;
-+ cfi_spin_lock(chip->mutex);
-+ ret = get_chip(map, chip, adr, FL_ERASING);
-+ if (ret) {
-+ cfi_spin_unlock(chip->mutex);
-+ return ret;
-+ }
-
-- if ((instr->len + instr->addr) > mtd->size)
-- return -EINVAL;
-+ RETRY_CMD_LABEL;
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
-+ __func__, adr );
-
-- chipnum = instr->addr >> cfi->chipshift;
-- adr = instr->addr - (chipnum << cfi->chipshift);
-- len = instr->len;
-+ ENABLE_VPP(map);
-+ cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-+ cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-+ cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-+ cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-+ cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-+ cfi_write(map, CMD(0x30), adr);
-
-- while(len) {
-- ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
-+ chip->state = FL_ERASING;
-+ chip->erase_suspended = 0;
-+ chip->in_progress_block_addr = adr;
-
-- if (ret)
-- return ret;
-+ cfi_spin_unlock(chip->mutex);
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ schedule_timeout((chip->erase_time*HZ)/(2*1000));
-+ cfi_spin_lock(chip->mutex);
-
-- adr += mtd->erasesize;
-- len -= mtd->erasesize;
-+ timeo = jiffies + (HZ*20);
-
-- if (adr >> cfi->chipshift) {
-- adr = 0;
-- chipnum++;
-+ /* Wait for the end of programing/erasure by using the toggle method.
-+ * As long as there is a programming procedure going on, bit 6 is
-+ * toggling its state with each consecutive read. The toggling stops
-+ * as soon as the procedure is completed.
-+ *
-+ * If the process has gone on for too long on the chip, bit 5 gets
-+ * set. After bit5 is set you can kill the operation by sending a
-+ * reset command to the chip.
-+ */
-+ /* See comments in do_write_oneword(). */
-
-- if (chipnum >= cfi->numchips)
-+ for (;;) {
-+ if (chip->state != FL_ERASING) {
-+ /* Someone's suspended the erase. Sleep */
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ add_wait_queue(&chip->wq, &wait);
-+ cfi_spin_unlock(chip->mutex);
-+ schedule();
-+ remove_wait_queue(&chip->wq, &wait);
-+ cfi_spin_lock(chip->mutex);
-+ continue;
-+ }
-+ if (chip->erase_suspended) {
-+ /* This erase was suspended and resumed.
-+ Adjust the timeout */
-+ timeo = jiffies + (HZ*20); /* FIXME */
-+ chip->erase_suspended = 0;
-+ }
-+
-+ oldstatus = cfi_read(map, adr);
-+ status = cfi_read(map, adr);
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n",
-+ __func__, oldstatus, status );
-+ if ( (((status ^ oldstatus) & dq6) == 0)
-+ || ( ta = time_after(jiffies, timeo)) )
- break;
-+
-+ /* Latency issues. Drop the lock, wait a while and retry */
-+ cfi_spin_unlock(chip->mutex);
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ schedule_timeout(1);
-+ cfi_spin_lock(chip->mutex);
- }
-+
-+ prev_oldstatus = oldstatus;
-+ prev_status = status;
-+ oldstatus = cfi_read(map, adr);
-+ status = cfi_read(map, adr);
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n",
-+ __func__, oldstatus, status );
-+
-+ if ( cfi_buswidth_is_1() ) {
-+ datum = (__u8)~0;
-+ } else if ( cfi_buswidth_is_2() ) {
-+ datum = (__u16)~0;
-+ } else if ( cfi_buswidth_is_4() ) {
-+ datum = (__u32)~0;
-+#ifdef CFI_WORD_64
-+ } else if ( cfi_buswidth_is_8() ) {
-+ datum = (__u64)~0;
-+#endif
-+ } else {
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
-+ goto op_failed;
-+ }
-+
-+ if ( oldstatus == datum && status == datum ) {
-+ /* success - do nothing */
-+ goto op_done;
-+ }
-+
-+ if ( ta ) {
-+ /* Only check dq5 on the chips that are still toggling. */
-+ cfi_word dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1;
-+ if ( status & dq5mask ) {
-+ /* dq5 asserted - decode interleave chips */
-+ printk( KERN_WARNING
-+ "MTD %s(): FLASH internal timeout: 0x%.8x\n",
-+ __func__,
-+ status & dq5mask );
-+ } else {
-+ printk( KERN_WARNING
-+ "MTD %s(): Software timed out during write.\n",
-+ __func__ );
- }
-+ goto op_failed;
-+ }
-+
-+ HANDLE_WACKY_STATE();
-+
-+ op_failed:
-+ /* reset on all failures. */
-+ cfi_write( map, CMD(0xF0), chip->start );
-+ /* FIXME - should have reset delay before continuing */
-+ CHECK_RETRIES();
-+ ret = -EIO;
-+
-+ op_done:
-+ chip->state = FL_READY;
-+ put_chip(map, chip, adr);
-+ cfi_spin_unlock(chip->mutex);
-+ return ret;
-+}
-+
-+
-+int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
-+{
-+ unsigned long ofs, len;
-+ int ret;
-+
-+ ofs = instr->addr;
-+ len = instr->len;
-+
-+ ret = cfi_amdstd_varsize_frob(mtd, do_erase_oneblock, ofs, len, 0);
-+ if (ret)
-+ return ret;
-
- instr->state = MTD_ERASE_DONE;
- if (instr->callback)
-@@ -1118,6 +1886,7 @@
- return 0;
- }
-
-+
- static int cfi_amdstd_erase_chip(struct mtd_info *mtd, struct erase_info *instr)
- {
- struct map_info *map = mtd->priv;
-@@ -1141,6 +1910,7 @@
- return 0;
- }
-
-+
- static void cfi_amdstd_sync (struct mtd_info *mtd)
- {
- struct map_info *map = mtd->priv;
-@@ -1254,6 +2024,7 @@
- return ret;
- }
-
-+
- static void cfi_amdstd_resume(struct mtd_info *mtd)
- {
- struct map_info *map = mtd->priv;
-@@ -1279,6 +2050,137 @@
- }
- }
-
-+
-+#ifdef DEBUG_LOCK_BITS
-+
-+static int do_printlockstatus_oneblock(struct map_info *map,
-+ struct flchip *chip,
-+ unsigned long adr,
-+ void *thunk)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ int ofs_factor = cfi->interleave * cfi->device_type;
-+
-+ cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
-+ printk(KERN_DEBUG "block status register for 0x%08lx is %x\n",
-+ adr, cfi_read_query(map, adr+(2*ofs_factor)));
-+ cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
-+
-+ return 0;
-+}
-+
-+
-+#define debug_dump_locks(mtd, frob, ofs, len, thunk) \
-+ cfi_amdstd_varsize_frob((mtd), (frob), (ofs), (len), (thunk))
-+
-+#else
-+
-+#define debug_dump_locks(...)
-+
-+#endif /* DEBUG_LOCK_BITS */
-+
-+
-+struct xxlock_thunk {
-+ cfi_word val;
-+ flstate_t state;
-+};
-+
-+
-+#define DO_XXLOCK_ONEBLOCK_LOCK ((struct xxlock_thunk){0x01, FL_LOCKING})
-+#define DO_XXLOCK_ONEBLOCK_UNLOCK ((struct xxlock_thunk){0x00, FL_UNLOCKING})
-+
-+
-+/*
-+ * FIXME - this is *very* specific to a particular chip. It likely won't
-+ * work for all chips that require unlock. It also hasn't been tested
-+ * with interleaved chips.
-+ */
-+static int do_xxlock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, void *thunk)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ struct xxlock_thunk *xxlt = (struct xxlock_thunk *)thunk;
-+ int ret;
-+
-+ /*
-+ * This is easy because these are writes to registers and not writes
-+ * to flash memory - that means that we don't have to check status
-+ * and timeout.
-+ */
-+
-+ adr += chip->start;
-+ /*
-+ * lock block registers:
-+ * - on 64k boundariesand
-+ * - bit 1 set high
-+ * - block lock registers are 4MiB lower - overflow subtract (danger)
-+ */
-+ adr = ((adr & ~0xffff) | 0x2) + ~0x3fffff;
-+
-+ cfi_spin_lock(chip->mutex);
-+ ret = get_chip(map, chip, adr, FL_LOCKING);
-+ if (ret) {
-+ cfi_spin_unlock(chip->mutex);
-+ return ret;
-+ }
-+
-+ chip->state = xxlt->state;
-+ cfi_write(map, CMD(xxlt->val), adr);
-+
-+ /* Done and happy. */
-+ chip->state = FL_READY;
-+ put_chip(map, chip, adr);
-+ cfi_spin_unlock(chip->mutex);
-+ return 0;
-+}
-+
-+
-+static int cfi_amdstd_lock_varsize(struct mtd_info *mtd,
-+ loff_t ofs,
-+ size_t len)
-+{
-+ int ret;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3,
-+ "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
-+ __func__, ofs, len);
-+ debug_dump_locks(mtd, do_printlockstatus_oneblock, ofs, len, 0);
-+
-+ ret = cfi_amdstd_varsize_frob(mtd, do_xxlock_oneblock, ofs, len,
-+ (void *)&DO_XXLOCK_ONEBLOCK_LOCK);
-+
-+ DEBUG(MTD_DEBUG_LEVEL3,
-+ "%s: lock status after, ret=%d\n",
-+ __func__, ret);
-+
-+ debug_dump_locks(mtd, do_printlockstatus_oneblock, ofs, len, 0);
-+
-+ return ret;
-+}
-+
-+
-+static int cfi_amdstd_unlock_varsize(struct mtd_info *mtd,
-+ loff_t ofs,
-+ size_t len)
-+{
-+ int ret;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3,
-+ "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
-+ __func__, ofs, len);
-+ debug_dump_locks(mtd, do_printlockstatus_oneblock, ofs, len, 0);
-+
-+ ret = cfi_amdstd_varsize_frob(mtd, do_xxlock_oneblock, ofs, len,
-+ (void *)&DO_XXLOCK_ONEBLOCK_UNLOCK);
-+
-+ DEBUG(MTD_DEBUG_LEVEL3,
-+ "%s: lock status after, ret=%d\n",
-+ __func__, ret);
-+ debug_dump_locks(mtd, do_printlockstatus_oneblock, ofs, len, 0);
-+
-+ return ret;
-+}
-+
-+
- static void cfi_amdstd_destroy(struct mtd_info *mtd)
- {
- struct map_info *map = mtd->priv;
-@@ -1291,17 +2193,20 @@
-
- static char im_name[]="cfi_cmdset_0002";
-
-+
- int __init cfi_amdstd_init(void)
- {
- inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0002);
- return 0;
- }
-
-+
- static void __exit cfi_amdstd_exit(void)
- {
- inter_module_unregister(im_name);
- }
-
-+
- module_init(cfi_amdstd_init);
- module_exit(cfi_amdstd_exit);
-
-@@ -1309,3 +2214,7 @@
- MODULE_AUTHOR("Crossnet Co. <info@crossnet.co.jp> et al.");
- MODULE_DESCRIPTION("MTD chip driver for AMD/Fujitsu flash chips");
-
-+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
-+MODULE_PARM(retry_cmd_max, "i");
-+MODULE_PARM_DESC(retry_cmd_max, "Number of times to retry an erase or program command if it fails - should only be needed by buggy hardware: default 0");
-+#endif
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/chips/cfi_cmdset_0020.c linux/drivers/mtd/chips/cfi_cmdset_0020.c
---- linux-mips-2.4.24-pre2/drivers/mtd/chips/cfi_cmdset_0020.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/chips/cfi_cmdset_0020.c 2004-11-17 18:17:58.945328208 +0100
-@@ -21,16 +21,19 @@
- #include <linux/types.h>
- #include <linux/kernel.h>
- #include <linux/sched.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <asm/byteorder.h>
-
- #include <linux/errno.h>
-+#include <linux/init.h>
- #include <linux/slab.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
-+#include <linux/mtd/compatmac.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/cfi.h>
--#include <linux/mtd/compatmac.h>
-+#include <linux/mtd/mtd.h>
-
-
- static int cfi_staa_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
-@@ -51,10 +54,10 @@
- static struct mtd_info *cfi_staa_setup (struct map_info *);
-
- static struct mtd_chip_driver cfi_staa_chipdrv = {
-- probe: NULL, /* Not usable directly */
-- destroy: cfi_staa_destroy,
-- name: "cfi_cmdset_0020",
-- module: THIS_MODULE
-+ .probe = NULL, /* Not usable directly */
-+ .destroy = cfi_staa_destroy,
-+ .name = "cfi_cmdset_0020",
-+ .module = THIS_MODULE
- };
-
- /* #define DEBUG_LOCK_BITS */
-@@ -113,7 +116,6 @@
- {
- struct cfi_private *cfi = map->fldrv_priv;
- int i;
-- __u32 base = cfi->chips[0].start;
-
- if (cfi->cfi_mode) {
- /*
-@@ -123,35 +125,10 @@
- */
- __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
- struct cfi_pri_intelext *extp;
-- int ofs_factor = cfi->interleave * cfi->device_type;
--
-- printk(" ST Microelectronics Extended Query Table at 0x%4.4X\n", adr);
-- if (!adr)
-- return NULL;
--
-- /* Switch it into Query Mode */
-- cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
--
-- extp = kmalloc(sizeof(*extp), GFP_KERNEL);
-- if (!extp) {
-- printk(KERN_ERR "Failed to allocate memory\n");
-- return NULL;
-- }
--
-- /* Read in the Extended Query Table */
-- for (i=0; i<sizeof(*extp); i++) {
-- ((unsigned char *)extp)[i] =
-- cfi_read_query(map, (base+((adr+i)*ofs_factor)));
-- }
-
-- if (extp->MajorVersion != '1' ||
-- (extp->MinorVersion < '0' || extp->MinorVersion > '2')) {
-- printk(KERN_WARNING " Unknown staa Extended Query "
-- "version %c.%c.\n", extp->MajorVersion,
-- extp->MinorVersion);
-- kfree(extp);
-+ extp = (struct cfi_pri_intelext*)cfi_read_pri(map, adr, sizeof(*extp), "ST Microelectronics");
-+ if (!extp)
- return NULL;
-- }
-
- /* Do some byteswapping if necessary */
- extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport);
-@@ -172,11 +149,6 @@
- cfi->chips[i].erase_time = 1024;
- }
-
-- map->fldrv = &cfi_staa_chipdrv;
-- MOD_INC_USE_COUNT;
--
-- /* Make sure it's in read mode */
-- cfi_send_gen_cmd(0xff, 0x55, base, map, cfi, cfi->device_type, NULL);
- return cfi_staa_setup(map);
- }
-
-@@ -208,6 +180,7 @@
- if (!mtd->eraseregions) {
- printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");
- kfree(cfi->cmdset_priv);
-+ kfree(mtd);
- return NULL;
- }
-
-@@ -232,6 +205,7 @@
- printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize);
- kfree(mtd->eraseregions);
- kfree(cfi->cmdset_priv);
-+ kfree(mtd);
- return NULL;
- }
-
-@@ -256,7 +230,7 @@
- mtd->flags |= MTD_ECC; /* FIXME: Not all STMicro flashes have this */
- mtd->eccsize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */
- map->fldrv = &cfi_staa_chipdrv;
-- MOD_INC_USE_COUNT;
-+ __module_get(THIS_MODULE);
- mtd->name = map->name;
- return mtd;
- }
-@@ -288,7 +262,7 @@
- */
- switch (chip->state) {
- case FL_ERASING:
-- if (!((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2)
-+ if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2))
- goto sleep; /* We don't support erase suspend */
-
- cfi_write (map, CMD(0xb0), cmd_addr);
-@@ -374,7 +348,7 @@
- goto retry;
- }
-
-- map->copy_from(map, buf, adr, len);
-+ map_copy_from(map, buf, adr, len);
-
- if (suspended) {
- chip->state = chip->oldstate;
-@@ -540,11 +514,11 @@
- /* Write data */
- for (z = 0; z < len; z += CFIDEV_BUSWIDTH) {
- if (cfi_buswidth_is_1()) {
-- map->write8 (map, *((__u8*)buf)++, adr+z);
-+ map_write8 (map, *((__u8*)buf)++, adr+z);
- } else if (cfi_buswidth_is_2()) {
-- map->write16 (map, *((__u16*)buf)++, adr+z);
-+ map_write16 (map, *((__u16*)buf)++, adr+z);
- } else if (cfi_buswidth_is_4()) {
-- map->write32 (map, *((__u32*)buf)++, adr+z);
-+ map_write32 (map, *((__u32*)buf)++, adr+z);
- } else {
- DISABLE_VPP(map);
- return -EINVAL;
-@@ -1436,13 +1410,13 @@
-
- static char im_name[]="cfi_cmdset_0020";
-
--mod_init_t cfi_staa_init(void)
-+int __init cfi_staa_init(void)
- {
- inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0020);
- return 0;
- }
-
--mod_exit_t cfi_staa_exit(void)
-+static void __exit cfi_staa_exit(void)
- {
- inter_module_unregister(im_name);
- }
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/chips/cfi_probe.c linux/drivers/mtd/chips/cfi_probe.c
---- linux-mips-2.4.24-pre2/drivers/mtd/chips/cfi_probe.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/chips/cfi_probe.c 2004-11-17 18:17:58.947327904 +0100
-@@ -1,13 +1,14 @@
- /*
- Common Flash Interface probe code.
- (C) 2000 Red Hat. GPL'd.
-- $Id$
-+ $Id$
- */
-
- #include <linux/config.h>
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <asm/byteorder.h>
- #include <linux/errno.h>
-@@ -25,7 +26,7 @@
- #endif
-
- static int cfi_probe_chip(struct map_info *map, __u32 base,
-- struct flchip *chips, struct cfi_private *cfi);
-+ unsigned long *chip_map, struct cfi_private *cfi);
- static int cfi_chip_setup(struct map_info *map, struct cfi_private *cfi);
-
- struct mtd_info *cfi_probe(struct map_info *map);
-@@ -48,7 +49,7 @@
- }
-
- static int cfi_probe_chip(struct map_info *map, __u32 base,
-- struct flchip *chips, struct cfi_private *cfi)
-+ unsigned long *chip_map, struct cfi_private *cfi)
- {
- int i;
-
-@@ -77,18 +78,24 @@
- }
-
- /* Check each previous chip to see if it's an alias */
-- for (i=0; i<cfi->numchips; i++) {
-+ for (i=0; i < (base >> cfi->chipshift); i++) {
-+ unsigned long start;
-+ if(!test_bit(i, chip_map)) {
-+ /* Skip location; no valid chip at this address */
-+ continue;
-+ }
-+ start = i << cfi->chipshift;
- /* This chip should be in read mode if it's one
- we've already touched. */
-- if (qry_present(map,chips[i].start,cfi)) {
-+ if (qry_present(map, start, cfi)) {
- /* Eep. This chip also had the QRY marker.
- * Is it an alias for the new one? */
-- cfi_send_gen_cmd(0xF0, 0, chips[i].start, map, cfi, cfi->device_type, NULL);
-+ cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL);
-
- /* If the QRY marker goes away, it's an alias */
-- if (!qry_present(map, chips[i].start, cfi)) {
-+ if (!qry_present(map, start, cfi)) {
- printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
-- map->name, base, chips[i].start);
-+ map->name, base, start);
- return 0;
- }
- /* Yes, it's actually got QRY for data. Most
-@@ -99,7 +106,7 @@
-
- if (qry_present(map, base, cfi)) {
- printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
-- map->name, base, chips[i].start);
-+ map->name, base, start);
- return 0;
- }
- }
-@@ -107,13 +114,7 @@
-
- /* OK, if we got to here, then none of the previous chips appear to
- be aliases for the current one. */
-- if (cfi->numchips == MAX_CFI_CHIPS) {
-- printk(KERN_WARNING"%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n", map->name, MAX_CFI_CHIPS);
-- /* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */
-- return -1;
-- }
-- chips[cfi->numchips].start = base;
-- chips[cfi->numchips].state = FL_READY;
-+ set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
- cfi->numchips++;
-
- /* Put it back into Read Mode */
-@@ -179,9 +180,28 @@
- (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1);
- #endif
- }
-+
-+ /* Note we put the device back into Read Mode BEFORE going into Auto
-+ * Select Mode, as some devices support nesting of modes, others
-+ * don't. This way should always work.
-+ * On cmdset 0001 the writes of 0xaa and 0x55 are not needed, and
-+ * so should be treated as nops or illegal (and so put the device
-+ * back into Read Mode, which is a nop in this case).
-+ */
-+ cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL);
-+ cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
-+ cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
-+ cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
-+ cfi->mfr = cfi_read_query(map, base);
-+ cfi->id = cfi_read_query(map, base + ofs_factor);
-+
- /* Put it back into Read Mode */
- cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
-
-+ printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit mode\n",
-+ map->name, cfi->interleave, cfi->device_type*8, base,
-+ map->buswidth*8);
-+
- return 1;
- }
-
-@@ -240,11 +260,11 @@
- printk("No Alternate Algorithm Table\n");
-
-
-- printk("Vcc Minimum: %x.%x V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf);
-- printk("Vcc Maximum: %x.%x V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf);
-+ printk("Vcc Minimum: %2d.%d V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf);
-+ printk("Vcc Maximum: %2d.%d V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf);
- if (cfip->VppMin) {
-- printk("Vpp Minimum: %x.%x V\n", cfip->VppMin >> 4, cfip->VppMin & 0xf);
-- printk("Vpp Maximum: %x.%x V\n", cfip->VppMax >> 4, cfip->VppMax & 0xf);
-+ printk("Vpp Minimum: %2d.%d V\n", cfip->VppMin >> 4, cfip->VppMin & 0xf);
-+ printk("Vpp Maximum: %2d.%d V\n", cfip->VppMax >> 4, cfip->VppMax & 0xf);
- }
- else
- printk("No Vpp line\n");
-@@ -303,8 +323,8 @@
- #endif /* DEBUG_CFI */
-
- static struct chip_probe cfi_chip_probe = {
-- name: "CFI",
-- probe_chip: cfi_probe_chip
-+ .name = "CFI",
-+ .probe_chip = cfi_probe_chip
- };
-
- struct mtd_info *cfi_probe(struct map_info *map)
-@@ -317,9 +337,9 @@
- }
-
- static struct mtd_chip_driver cfi_chipdrv = {
-- probe: cfi_probe,
-- name: "cfi_probe",
-- module: THIS_MODULE
-+ .probe = cfi_probe,
-+ .name = "cfi_probe",
-+ .module = THIS_MODULE
- };
-
- int __init cfi_probe_init(void)
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/chips/cfi_util.c linux/drivers/mtd/chips/cfi_util.c
---- linux-mips-2.4.24-pre2/drivers/mtd/chips/cfi_util.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/chips/cfi_util.c 2004-11-17 18:17:58.000000000 +0100
-@@ -0,0 +1,91 @@
-+/*
-+ * Common Flash Interface support:
-+ * Generic utility functions not dependant on command set
-+ *
-+ * Copyright (C) 2002 Red Hat
-+ * Copyright (C) 2003 STMicroelectronics Limited
-+ *
-+ * This code is covered by the GPL.
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <asm/io.h>
-+#include <asm/byteorder.h>
-+
-+#include <linux/errno.h>
-+#include <linux/slab.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/cfi.h>
-+#include <linux/mtd/compatmac.h>
-+
-+struct cfi_extquery *
-+cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ __u32 base = 0; // cfi->chips[0].start;
-+ int ofs_factor = cfi->interleave * cfi->device_type;
-+ int i;
-+ struct cfi_extquery *extp = NULL;
-+
-+ printk(" %s Extended Query Table at 0x%4.4X\n", name, adr);
-+ if (!adr)
-+ goto out;
-+
-+ /* Switch it into Query Mode */
-+ cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
-+
-+ extp = kmalloc(size, GFP_KERNEL);
-+ if (!extp) {
-+ printk(KERN_ERR "Failed to allocate memory\n");
-+ goto out;
-+ }
-+
-+ /* Read in the Extended Query Table */
-+ for (i=0; i<size; i++) {
-+ ((unsigned char *)extp)[i] =
-+ cfi_read_query(map, base+((adr+i)*ofs_factor));
-+ }
-+
-+ if (extp->MajorVersion != '1' ||
-+ (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
-+ printk(KERN_WARNING " Unknown %s Extended Query "
-+ "version %c.%c.\n", name, extp->MajorVersion,
-+ extp->MinorVersion);
-+ kfree(extp);
-+ extp = NULL;
-+ goto out;
-+ }
-+
-+out:
-+ /* Make sure it's in read mode */
-+ cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL);
-+
-+ return extp;
-+}
-+
-+EXPORT_SYMBOL(cfi_read_pri);
-+
-+void cfi_fixup(struct map_info *map, struct cfi_fixup* fixups)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ struct cfi_fixup *f;
-+
-+ for (f=fixups; f->fixup; f++) {
-+ if (((f->mfr == CFI_MFR_ANY) || (f->mfr == cfi->mfr)) &&
-+ ((f->id == CFI_ID_ANY) || (f->id == cfi->id))) {
-+ f->fixup(map, f->param);
-+ }
-+ }
-+}
-+
-+EXPORT_SYMBOL(cfi_fixup);
-+
-+MODULE_LICENSE("GPL");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/chips/chipreg.c linux/drivers/mtd/chips/chipreg.c
---- linux-mips-2.4.24-pre2/drivers/mtd/chips/chipreg.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/chips/chipreg.c 2004-11-17 18:17:58.949327600 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Registration for chip drivers
- *
-@@ -7,10 +7,13 @@
-
- #include <linux/kernel.h>
- #include <linux/config.h>
-+#include <linux/module.h>
- #include <linux/kmod.h>
- #include <linux/spinlock.h>
--#include <linux/mtd/compatmac.h>
-+#include <linux/slab.h>
- #include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/compatmac.h>
-
- spinlock_t chip_drvs_lock = SPIN_LOCK_UNLOCKED;
- static LIST_HEAD(chip_drvs_list);
-@@ -44,10 +47,8 @@
- break;
- }
- }
-- if (ret && !try_inc_mod_count(ret->module)) {
-- /* Eep. Failed. */
-+ if (ret && !try_module_get(ret->module))
- ret = NULL;
-- }
-
- spin_unlock(&chip_drvs_lock);
-
-@@ -64,32 +65,46 @@
-
- drv = get_mtd_chip_driver(name);
-
-- if (!drv && !request_module(name))
-+ if (!drv && !request_module("%s", name))
- drv = get_mtd_chip_driver(name);
-
- if (!drv)
- return NULL;
-
- ret = drv->probe(map);
--#ifdef CONFIG_MODULES
-+
- /* We decrease the use count here. It may have been a
- probe-only module, which is no longer required from this
- point, having given us a handle on (and increased the use
- count of) the actual driver code.
- */
-- if(drv->module)
-- __MOD_DEC_USE_COUNT(drv->module);
--#endif
-+ module_put(drv->module);
-
- if (ret)
- return ret;
-
- return NULL;
- }
-+/*
-+ * Destroy an MTD device which was created for a map device.
-+ * Make sure the MTD device is already unregistered before calling this
-+ */
-+void map_destroy(struct mtd_info *mtd)
-+{
-+ struct map_info *map = mtd->priv;
-+
-+ if (map->fldrv->destroy)
-+ map->fldrv->destroy(mtd);
-+
-+ module_put(map->fldrv->module);
-+
-+ kfree(mtd);
-+}
-
- EXPORT_SYMBOL(register_mtd_chip_driver);
- EXPORT_SYMBOL(unregister_mtd_chip_driver);
- EXPORT_SYMBOL(do_map_probe);
-+EXPORT_SYMBOL(map_destroy);
-
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/chips/gen_probe.c linux/drivers/mtd/chips/gen_probe.c
---- linux-mips-2.4.24-pre2/drivers/mtd/chips/gen_probe.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/chips/gen_probe.c 2004-11-17 18:17:58.951327296 +0100
-@@ -1,14 +1,17 @@
- /*
- * Routines common to all CFI-type probes.
-- * (C) 2001, 2001 Red Hat, Inc.
-+ * (C) 2001-2003 Red Hat, Inc.
- * GPL'd
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/cfi.h>
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/gen_probe.h>
-
- static struct mtd_info *check_cmd_set(struct map_info *, int);
-@@ -50,11 +53,11 @@
-
- struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chip_probe *cp)
- {
-- unsigned long base=0;
- struct cfi_private cfi;
- struct cfi_private *retcfi;
-- struct flchip chip[MAX_CFI_CHIPS];
-- int i;
-+ unsigned long *chip_map;
-+ int i, j;
-+ int max_chips;
-
- memset(&cfi, 0, sizeof(cfi));
-
-@@ -77,8 +80,6 @@
- return NULL;
- }
- #endif
-- chip[0].start = 0;
-- chip[0].state = FL_READY;
- cfi.chipshift = cfi.cfiq->DevSize;
-
- switch(cfi.interleave) {
-@@ -103,20 +104,28 @@
- cfi.numchips = 1;
-
- /*
-+ * Allocate memory for bitmap of valid chips.
-+ * Align bitmap storage size to full byte.
-+ */
-+ max_chips = map->size >> cfi.chipshift;
-+ chip_map = kmalloc((max_chips / 8) + ((max_chips % 8) ? 1 : 0), GFP_KERNEL);
-+ if (!chip_map) {
-+ printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name);
-+ kfree(cfi.cfiq);
-+ return NULL;
-+ }
-+
-+ set_bit(0, chip_map); /* Mark first chip valid */
-+
-+ /*
- * Now probe for other chips, checking sensibly for aliases while
- * we're at it. The new_chip probe above should have let the first
- * chip in read mode.
-- *
-- * NOTE: Here, we're checking if there is room for another chip
-- * the same size within the mapping. Therefore,
-- * base + chipsize <= map->size is the correct thing to do,
-- * because, base + chipsize would be the _first_ byte of the
-- * next chip, not the one we're currently pondering.
- */
-
-- for (base = (1<<cfi.chipshift); base + (1<<cfi.chipshift) <= map->size;
-- base += (1<<cfi.chipshift))
-- cp->probe_chip(map, base, &chip[0], &cfi);
-+ for (i = 1; i < max_chips; i++) {
-+ cp->probe_chip(map, i << cfi.chipshift, chip_map, &cfi);
-+ }
-
- /*
- * Now allocate the space for the structures we need to return to
-@@ -128,19 +137,26 @@
- if (!retcfi) {
- printk(KERN_WARNING "%s: kmalloc failed for CFI private structure\n", map->name);
- kfree(cfi.cfiq);
-+ kfree(chip_map);
- return NULL;
- }
-
- memcpy(retcfi, &cfi, sizeof(cfi));
-- memcpy(&retcfi->chips[0], chip, sizeof(struct flchip) * cfi.numchips);
-+ memset(&retcfi->chips[0], 0, sizeof(struct flchip) * cfi.numchips);
-
-- /* Fix up the stuff that breaks when you move it */
-- for (i=0; i< retcfi->numchips; i++) {
-- init_waitqueue_head(&retcfi->chips[i].wq);
-- spin_lock_init(&retcfi->chips[i]._spinlock);
-- retcfi->chips[i].mutex = &retcfi->chips[i]._spinlock;
-+ for (i = 0, j = 0; (j < cfi.numchips) && (i < max_chips); i++) {
-+ if(test_bit(i, chip_map)) {
-+ struct flchip *pchip = &retcfi->chips[j++];
-+
-+ pchip->start = (i << cfi.chipshift);
-+ pchip->state = FL_READY;
-+ init_waitqueue_head(&pchip->wq);
-+ spin_lock_init(&pchip->_spinlock);
-+ pchip->mutex = &pchip->_spinlock;
-+ }
- }
-
-+ kfree(chip_map);
- return retcfi;
- }
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/chips/jedec.c linux/drivers/mtd/chips/jedec.c
---- linux-mips-2.4.24-pre2/drivers/mtd/chips/jedec.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/chips/jedec.c 2004-11-17 18:17:58.953326992 +0100
-@@ -11,10 +11,16 @@
- * not going to guess how to send commands to them, plus I expect they will
- * all speak CFI..
- *
-- * $Id$
-+ * $Id$
- */
-
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
- #include <linux/mtd/jedec.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/compatmac.h>
-
- static struct mtd_info *jedec_probe(struct map_info *);
- static int jedec_probe8(struct map_info *map,unsigned long base,
-@@ -33,14 +39,51 @@
-
- /* Listing of parts and sizes. We need this table to learn the sector
- size of the chip and the total length */
--static const struct JEDECTable JEDEC_table[] =
-- {{0x013D,"AMD Am29F017D",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
-- {0x01AD,"AMD Am29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
-- {0x01D5,"AMD Am29F080",1*1024*1024,64*1024,MTD_CAP_NORFLASH},
-- {0x01A4,"AMD Am29F040",512*1024,64*1024,MTD_CAP_NORFLASH},
-- {0x20E3,"AMD Am29W040B",512*1024,64*1024,MTD_CAP_NORFLASH},
-- {0xC2AD,"Macronix MX29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
-- {}};
-+static const struct JEDECTable JEDEC_table[] = {
-+ {
-+ .jedec = 0x013D,
-+ .name = "AMD Am29F017D",
-+ .size = 2*1024*1024,
-+ .sectorsize = 64*1024,
-+ .capabilities = MTD_CAP_NORFLASH
-+ },
-+ {
-+ .jedec = 0x01AD,
-+ .name = "AMD Am29F016",
-+ .size = 2*1024*1024,
-+ .sectorsize = 64*1024,
-+ .capabilities = MTD_CAP_NORFLASH
-+ },
-+ {
-+ .jedec = 0x01D5,
-+ .name = "AMD Am29F080",
-+ .size = 1*1024*1024,
-+ .sectorsize = 64*1024,
-+ .capabilities = MTD_CAP_NORFLASH
-+ },
-+ {
-+ .jedec = 0x01A4,
-+ .name = "AMD Am29F040",
-+ .size = 512*1024,
-+ .sectorsize = 64*1024,
-+ .capabilities = MTD_CAP_NORFLASH
-+ },
-+ {
-+ .jedec = 0x20E3,
-+ .name = "AMD Am29W040B",
-+ .size = 512*1024,
-+ .sectorsize = 64*1024,
-+ .capabilities = MTD_CAP_NORFLASH
-+ },
-+ {
-+ .jedec = 0xC2AD,
-+ .name = "Macronix MX29F016",
-+ .size = 2*1024*1024,
-+ .sectorsize = 64*1024,
-+ .capabilities = MTD_CAP_NORFLASH
-+ },
-+ { .jedec = 0x0 }
-+};
-
- static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id);
- static void jedec_sync(struct mtd_info *mtd) {};
-@@ -54,9 +97,9 @@
-
-
- static struct mtd_chip_driver jedec_chipdrv = {
-- probe: jedec_probe,
-- name: "jedec",
-- module: THIS_MODULE
-+ .probe = jedec_probe,
-+ .name = "jedec",
-+ .module = THIS_MODULE
- };
-
- /* Probe entry point */
-@@ -131,8 +174,7 @@
- /* Generate a part name that includes the number of different chips and
- other configuration information */
- count = 1;
-- strncpy(Part,map->name,sizeof(Part)-10);
-- Part[sizeof(Part)-11] = 0;
-+ strlcpy(Part,map->name,sizeof(Part)-10);
- strcat(Part," ");
- Uniq = 0;
- for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
-@@ -209,8 +251,7 @@
- // printk("Part: '%s'\n",Part);
-
- memset(MTD,0,sizeof(*MTD));
-- // strncpy(MTD->name,Part,sizeof(MTD->name));
-- // MTD->name[sizeof(MTD->name)-1] = 0;
-+ // strlcpy(MTD->name,Part,sizeof(MTD->name));
- MTD->name = map->name;
- MTD->type = MTD_NORFLASH;
- MTD->flags = MTD_CAP_NORFLASH;
-@@ -229,7 +270,7 @@
- MTD->priv = map;
- map->fldrv_priv = priv;
- map->fldrv = &jedec_chipdrv;
-- MOD_INC_USE_COUNT;
-+ __module_get(THIS_MODULE);
- return MTD;
- }
-
-@@ -351,8 +392,8 @@
- static int jedec_probe8(struct map_info *map,unsigned long base,
- struct jedec_private *priv)
- {
-- #define flread(x) map->read8(map,base+x)
-- #define flwrite(v,x) map->write8(map,v,base+x)
-+ #define flread(x) map_read8(map,base+x)
-+ #define flwrite(v,x) map_write8(map,v,base+x)
-
- const unsigned long AutoSel1 = 0xAA;
- const unsigned long AutoSel2 = 0x55;
-@@ -411,8 +452,8 @@
- static int jedec_probe32(struct map_info *map,unsigned long base,
- struct jedec_private *priv)
- {
-- #define flread(x) map->read32(map,base+((x)<<2))
-- #define flwrite(v,x) map->write32(map,v,base+((x)<<2))
-+ #define flread(x) map_read32(map,base+((x)<<2))
-+ #define flwrite(v,x) map_write32(map,v,base+((x)<<2))
-
- const unsigned long AutoSel1 = 0xAAAAAAAA;
- const unsigned long AutoSel2 = 0x55555555;
-@@ -490,7 +531,7 @@
- {
- struct map_info *map = (struct map_info *)mtd->priv;
-
-- map->copy_from(map, buf, from, len);
-+ map_copy_from(map, buf, from, len);
- *retlen = len;
- return 0;
- }
-@@ -514,7 +555,7 @@
- get = priv->bank_fill[0] - offset;
-
- bank /= priv->bank_fill[0];
-- map->copy_from(map,buf + *retlen,bank*my_bank_size + offset,get);
-+ map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get);
-
- len -= get;
- *retlen += get;
-@@ -545,8 +586,8 @@
- static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
- {
- // Does IO to the currently selected chip
-- #define flread(x) map->read8(map,chip->base+((x)<<chip->addrshift))
-- #define flwrite(v,x) map->write8(map,v,chip->base+((x)<<chip->addrshift))
-+ #define flread(x) map_read8(map,chip->base+((x)<<chip->addrshift))
-+ #define flwrite(v,x) map_write8(map,v,chip->base+((x)<<chip->addrshift))
-
- unsigned long Time = 0;
- unsigned long NoTime = 0;
-@@ -608,7 +649,7 @@
-
- /* Poll the flash for erasure completion, specs say this can take as long
- as 480 seconds to do all the sectors (for a 2 meg flash).
-- Erasure time is dependant on chip age, temp and wear.. */
-+ Erasure time is dependent on chip age, temp and wear.. */
-
- /* This being a generic routine assumes a 32 bit bus. It does read32s
- and bundles interleved chips into the same grouping. This will work
-@@ -651,19 +692,19 @@
- or this is not really flash ;> */
- switch (map->buswidth) {
- case 1:
-- Last[0] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
-- Last[1] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
-- Last[2] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[0] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[1] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[2] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off);
- break;
- case 2:
-- Last[0] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
-- Last[1] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
-- Last[2] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[0] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[1] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[2] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off);
- break;
- case 3:
-- Last[0] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
-- Last[1] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
-- Last[2] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[0] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[1] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[2] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off);
- break;
- }
- Count = 3;
-@@ -699,13 +740,13 @@
-
- switch (map->buswidth) {
- case 1:
-- Last[Count % 4] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[Count % 4] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off);
- break;
- case 2:
-- Last[Count % 4] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[Count % 4] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off);
- break;
- case 4:
-- Last[Count % 4] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[Count % 4] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off);
- break;
- }
- Count++;
-@@ -755,10 +796,10 @@
- size_t *retlen, const u_char *buf)
- {
- /* Does IO to the currently selected chip. It takes the bank addressing
-- base (which is divisable by the chip size) adds the necesary lower bits
-- of addrshift (interleve index) and then adds the control register index. */
-- #define flread(x) map->read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
-- #define flwrite(v,x) map->write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
-+ base (which is divisible by the chip size) adds the necessary lower bits
-+ of addrshift (interleave index) and then adds the control register index. */
-+ #define flread(x) map_read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
-+ #define flwrite(v,x) map_write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
-
- struct map_info *map = (struct map_info *)mtd->priv;
- struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv;
-@@ -794,7 +835,7 @@
- // Loop over this page
- for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++)
- {
-- unsigned char oldbyte = map->read8(map,base+off);
-+ unsigned char oldbyte = map_read8(map,base+off);
- unsigned char Last[4];
- unsigned long Count = 0;
-
-@@ -809,10 +850,10 @@
- flwrite(0xAA,0x555);
- flwrite(0x55,0x2AA);
- flwrite(0xA0,0x555);
-- map->write8(map,*buf,base + off);
-- Last[0] = map->read8(map,base + off);
-- Last[1] = map->read8(map,base + off);
-- Last[2] = map->read8(map,base + off);
-+ map_write8(map,*buf,base + off);
-+ Last[0] = map_read8(map,base + off);
-+ Last[1] = map_read8(map,base + off);
-+ Last[2] = map_read8(map,base + off);
-
- /* Wait for the flash to finish the operation. We store the last 4
- status bytes that have been retrieved so we can determine why
-@@ -820,7 +861,7 @@
- failure */
- for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] &&
- Count < 10000; Count++)
-- Last[Count % 4] = map->read8(map,base + off);
-+ Last[Count % 4] = map_read8(map,base + off);
- if (Last[(Count - 1) % 4] != *buf)
- {
- jedec_flash_failed(Last[(Count - 3) % 4]);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/chips/jedec_probe.c linux/drivers/mtd/chips/jedec_probe.c
---- linux-mips-2.4.24-pre2/drivers/mtd/chips/jedec_probe.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/chips/jedec_probe.c 2004-11-17 18:17:58.954326840 +0100
-@@ -1,9 +1,11 @@
- /*
- Common Flash Interface probe code.
- (C) 2000 Red Hat. GPL'd.
-- $Id$
-+ $Id$
- See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
- for the standard this probe goes back to.
-+
-+ Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
- */
-
- #include <linux/config.h>
-@@ -15,7 +17,9 @@
- #include <linux/errno.h>
- #include <linux/slab.h>
- #include <linux/interrupt.h>
-+#include <linux/init.h>
-
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/cfi.h>
- #include <linux/mtd/gen_probe.h>
-@@ -26,20 +30,24 @@
- #define MANUFACTURER_FUJITSU 0x0004
- #define MANUFACTURER_INTEL 0x0089
- #define MANUFACTURER_MACRONIX 0x00C2
--#define MANUFACTURER_ST 0x0020
-+#define MANUFACTURER_PMC 0x009D
- #define MANUFACTURER_SST 0x00BF
-+#define MANUFACTURER_ST 0x0020
- #define MANUFACTURER_TOSHIBA 0x0098
-+#define MANUFACTURER_WINBOND 0x00da
-
-
- /* AMD */
- #define AM29F800BB 0x2258
- #define AM29F800BT 0x22D6
-+#define AM29LV400BB 0x22BA
-+#define AM29LV400BT 0x22B9
- #define AM29LV800BB 0x225B
- #define AM29LV800BT 0x22DA
- #define AM29LV160DT 0x22C4
- #define AM29LV160DB 0x2249
- #define AM29F017D 0x003D
--#define AM29F016 0x00AD
-+#define AM29F016D 0x00AD
- #define AM29F080 0x00D5
- #define AM29F040 0x00A4
- #define AM29LV040B 0x004F
-@@ -54,6 +62,7 @@
- #define AT49BV32XT 0x00C9
-
- /* Fujitsu */
-+#define MBM29F040C 0x00A4
- #define MBM29LV650UE 0x22D7
- #define MBM29LV320TE 0x22F6
- #define MBM29LV320BE 0x22F9
-@@ -61,6 +70,9 @@
- #define MBM29LV160BE 0x2249
- #define MBM29LV800BA 0x225B
- #define MBM29LV800TA 0x22DA
-+#define MBM29LV400TC 0x22B9
-+#define MBM29LV400BC 0x22BA
-+
-
- /* Intel */
- #define I28F004B3T 0x00d4
-@@ -93,8 +105,14 @@
- #define MX29F004T 0x0045
- #define MX29F004B 0x0046
-
-+/* PMC */
-+#define PM49FL002 0x006D
-+#define PM49FL004 0x006E
-+#define PM49FL008 0x006A
-+
- /* ST - www.st.com */
--#define M29W800T 0x00D7
-+#define M29W800DT 0x00D7
-+#define M29W800DB 0x005B
- #define M29W160DT 0x22C4
- #define M29W160DB 0x2249
- #define M29W040B 0x00E3
-@@ -110,6 +128,7 @@
- #define SST39LF040 0x00D7
- #define SST39SF010A 0x00B5
- #define SST39SF020A 0x00B6
-+#define SST49LF004B 0x0060
- #define SST49LF030A 0x001C
- #define SST49LF040A 0x0051
- #define SST49LF080A 0x005B
-@@ -122,15 +141,87 @@
- #define TC58FVT641 0x0093
- #define TC58FVB641 0x0095
-
-+/* Winbond */
-+#define W49V002A 0x00b0
-+
-+
-+/*
-+ * Unlock address sets for AMD command sets.
-+ * Intel command sets use the MTD_UADDR_UNNECESSARY.
-+ * Each identifier, except MTD_UADDR_UNNECESSARY, and
-+ * MTD_UADDR_NO_SUPPORT must be defined below in unlock_addrs[].
-+ * MTD_UADDR_NOT_SUPPORTED must be 0 so that structure
-+ * initialization need not require initializing all of the
-+ * unlock addresses for all bit widths.
-+ */
-+enum uaddr {
-+ MTD_UADDR_NOT_SUPPORTED = 0, /* data width not supported */
-+ MTD_UADDR_0x0555_0x02AA,
-+ MTD_UADDR_0x0555_0x0AAA,
-+ MTD_UADDR_0x5555_0x2AAA,
-+ MTD_UADDR_0x0AAA_0x0555,
-+ MTD_UADDR_DONT_CARE, /* Requires an arbitrary address */
-+ MTD_UADDR_UNNECESSARY, /* Does not require any address */
-+};
-+
-+
-+struct unlock_addr {
-+ int addr1;
-+ int addr2;
-+};
-+
-+
-+/*
-+ * I don't like the fact that the first entry in unlock_addrs[]
-+ * exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore,
-+ * should not be used. The problem is that structures with
-+ * initializers have extra fields initialized to 0. It is _very_
-+ * desireable to have the unlock address entries for unsupported
-+ * data widths automatically initialized - that means that
-+ * MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here
-+ * must go unused.
-+ */
-+static const struct unlock_addr unlock_addrs[] = {
-+ [MTD_UADDR_NOT_SUPPORTED] = {
-+ .addr1 = 0xffff,
-+ .addr2 = 0xffff
-+ },
-+
-+ [MTD_UADDR_0x0555_0x02AA] = {
-+ .addr1 = 0x0555,
-+ .addr2 = 0x02aa
-+ },
-+
-+ [MTD_UADDR_0x0555_0x0AAA] = {
-+ .addr1 = 0x0555,
-+ .addr2 = 0x0aaa
-+ },
-+
-+ [MTD_UADDR_0x5555_0x2AAA] = {
-+ .addr1 = 0x5555,
-+ .addr2 = 0x2aaa
-+ },
-+
-+ [MTD_UADDR_0x0AAA_0x0555] = {
-+ .addr1 = 0x0AAA,
-+ .addr2 = 0x0555
-+ },
-+
-+ [MTD_UADDR_DONT_CARE] = {
-+ .addr1 = 0x0000, /* Doesn't matter which address */
-+ .addr2 = 0x0000 /* is used - must be last entry */
-+ }
-+};
-+
-
- struct amd_flash_info {
- const __u16 mfr_id;
- const __u16 dev_id;
- const char *name;
- const int DevSize;
-- const int InterfaceDesc;
- const int NumEraseRegions;
- const int CmdSet;
-+ const __u8 uaddr[4]; /* unlock addrs for 8, 16, 32, 64 */
- const ulong regions[4];
- };
-
-@@ -145,760 +236,1214 @@
- #define SIZE_4MiB 22
- #define SIZE_8MiB 23
-
-+
-+/*
-+ * Please keep this list ordered by manufacturer!
-+ * Fortunately, the list isn't searched often and so a
-+ * slow, linear search isn't so bad.
-+ */
- static const struct amd_flash_info jedec_table[] = {
- {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F032B,
-- name: "AMD AM29F032B",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,64)
-- }
-- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV160DT,
-- name: "AMD AM29LV160DT",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,31),
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F032B,
-+ .name = "AMD AM29F032B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,64)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV160DT,
-+ .name = "AMD AM29LV160DT",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,31),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV160DB,
-- name: "AMD AM29LV160DB",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV160DB,
-+ .name = "AMD AM29LV160DB",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x10000,31)
- }
- }, {
-- mfr_id: MANUFACTURER_TOSHIBA,
-- dev_id: TC58FVT160,
-- name: "Toshiba TC58FVT160",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,31),
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV400BB,
-+ .name = "AMD AM29LV400BB",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
-+ ERASEINFO(0x02000,2),
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x10000,7)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV400BT,
-+ .name = "AMD AM29LV400BT",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,7),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_TOSHIBA,
-- dev_id: TC58FVB160,
-- name: "Toshiba TC58FVB160",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV800BB,
-+ .name = "AMD AM29LV800BB",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x08000,1),
-- ERASEINFO(0x10000,31)
-+ ERASEINFO(0x10000,15),
- }
- }, {
-- mfr_id: MANUFACTURER_TOSHIBA,
-- dev_id: TC58FVB321,
-- name: "Toshiba TC58FVB321",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x02000,8),
-- ERASEINFO(0x10000,63)
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F800BB,
-+ .name = "AMD AM29F800BB",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
-+ ERASEINFO(0x02000,2),
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x10000,15),
- }
- }, {
-- mfr_id: MANUFACTURER_TOSHIBA,
-- dev_id: TC58FVT321,
-- name: "Toshiba TC58FVT321",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x10000,63),
-- ERASEINFO(0x02000,8)
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV800BT,
-+ .name = "AMD AM29LV800BT",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,15),
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x02000,2),
-+ ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_TOSHIBA,
-- dev_id: TC58FVB641,
-- name: "Toshiba TC58FVB641",
-- DevSize: SIZE_8MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x02000,8),
-- ERASEINFO(0x10000,127)
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F800BT,
-+ .name = "AMD AM29F800BT",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,15),
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x02000,2),
-+ ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_TOSHIBA,
-- dev_id: TC58FVT641,
-- name: "Toshiba TC58FVT641",
-- DevSize: SIZE_8MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x10000,127),
-- ERASEINFO(0x02000,8)
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F017D,
-+ .name = "AMD AM29F017D",
-+ .uaddr = {
-+ [0] = MTD_UADDR_DONT_CARE /* x8 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,32),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F016D,
-+ .name = "AMD AM29F016D",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,32),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F080,
-+ .name = "AMD AM29F080",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,16),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F040,
-+ .name = "AMD AM29F040",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,8),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV040B,
-+ .name = "AMD AM29LV040B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,8),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_ATMEL,
-+ .dev_id = AT49BV512,
-+ .name = "Atmel AT49BV512",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_64KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,1)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_ATMEL,
-+ .dev_id = AT29LV512,
-+ .name = "Atmel AT29LV512",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_64KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x80,256),
-+ ERASEINFO(0x80,256)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_ATMEL,
-+ .dev_id = AT49BV16X,
-+ .name = "Atmel AT49BV16X",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x02000,8),
-+ ERASEINFO(0x10000,31)
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV650UE,
-- name: "Fujitsu MBM29LV650UE",
-- DevSize: SIZE_8MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,128)
-- }
-- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV320TE,
-- name: "Fujitsu MBM29LV320TE",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x10000,63),
-+ .mfr_id = MANUFACTURER_ATMEL,
-+ .dev_id = AT49BV16XT,
-+ .name = "Atmel AT49BV16XT",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x10000,31),
- ERASEINFO(0x02000,8)
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV320BE,
-- name: "Fujitsu MBM29LV320BE",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x02000,8),
-+ .mfr_id = MANUFACTURER_ATMEL,
-+ .dev_id = AT49BV32X,
-+ .name = "Atmel AT49BV32X",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x02000,8),
- ERASEINFO(0x10000,63)
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV160TE,
-- name: "Fujitsu MBM29LV160TE",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,31),
-- ERASEINFO(0x08000,1),
-- ERASEINFO(0x02000,2),
-- ERASEINFO(0x04000,1)
-+ .mfr_id = MANUFACTURER_ATMEL,
-+ .dev_id = AT49BV32XT,
-+ .name = "Atmel AT49BV32XT",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x10000,63),
-+ ERASEINFO(0x02000,8)
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV160BE,
-- name: "Fujitsu MBM29LV160BE",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-- ERASEINFO(0x02000,2),
-- ERASEINFO(0x08000,1),
-- ERASEINFO(0x10000,31)
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29F040C,
-+ .name = "Fujitsu MBM29F040C",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,8)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV650UE,
-+ .name = "Fujitsu MBM29LV650UE",
-+ .uaddr = {
-+ [0] = MTD_UADDR_DONT_CARE /* x16 */
-+ },
-+ .DevSize = SIZE_8MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,128)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV320TE,
-+ .name = "Fujitsu MBM29LV320TE",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x10000,63),
-+ ERASEINFO(0x02000,8)
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV800BA,
-- name: "Fujitsu MBM29LV800BA",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-- ERASEINFO(0x02000,2),
-- ERASEINFO(0x08000,1),
-- ERASEINFO(0x10000,15)
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV320BE,
-+ .name = "Fujitsu MBM29LV320BE",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x02000,8),
-+ ERASEINFO(0x10000,63)
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV800TA,
-- name: "Fujitsu MBM29LV800TA",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,15),
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV160TE,
-+ .name = "Fujitsu MBM29LV160TE",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,31),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV800BB,
-- name: "AMD AM29LV800BB",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV160BE,
-+ .name = "Fujitsu MBM29LV160BE",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x08000,1),
-- ERASEINFO(0x10000,15),
-+ ERASEINFO(0x10000,31)
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F800BB,
-- name: "AMD AM29F800BB",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV800BA,
-+ .name = "Fujitsu MBM29LV800BA",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x08000,1),
-- ERASEINFO(0x10000,15),
-+ ERASEINFO(0x10000,15)
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV800BT,
-- name: "AMD AM29LV800BT",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,15),
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV800TA,
-+ .name = "Fujitsu MBM29LV800TA",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,15),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F800BT,
-- name: "AMD AM29F800BT",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,15),
-- ERASEINFO(0x08000,1),
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV400BC,
-+ .name = "Fujitsu MBM29LV400BC",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
- ERASEINFO(0x02000,2),
-- ERASEINFO(0x04000,1)
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x10000,7)
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV800BB,
-- name: "AMD AM29LV800BB",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,15),
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV400TC,
-+ .name = "Fujitsu MBM29LV400TC",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,7),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F004B3B,
-- name: "Intel 28F004B3B",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F004B3B,
-+ .name = "Intel 28F004B3B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x02000, 8),
- ERASEINFO(0x10000, 7),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F004B3T,
-- name: "Intel 28F004B3T",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F004B3T,
-+ .name = "Intel 28F004B3T",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x10000, 7),
- ERASEINFO(0x02000, 8),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F400B3B,
-- name: "Intel 28F400B3B",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F400B3B,
-+ .name = "Intel 28F400B3B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x02000, 8),
- ERASEINFO(0x10000, 7),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F400B3T,
-- name: "Intel 28F400B3T",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F400B3T,
-+ .name = "Intel 28F400B3T",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x10000, 7),
- ERASEINFO(0x02000, 8),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F008B3B,
-- name: "Intel 28F008B3B",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F008B3B,
-+ .name = "Intel 28F008B3B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x02000, 8),
- ERASEINFO(0x10000, 15),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F008B3T,
-- name: "Intel 28F008B3T",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F008B3T,
-+ .name = "Intel 28F008B3T",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x10000, 15),
- ERASEINFO(0x02000, 8),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F008S5,
-- name: "Intel 28F008S5",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_INTEL_EXT,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,16),
-- }
-- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F016S5,
-- name: "Intel 28F016S5",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_INTEL_EXT,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,32),
-- }
-- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F008SA,
-- name: "Intel 28F008SA",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 1,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F008S5,
-+ .name = "Intel 28F008S5",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_INTEL_EXT,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,16),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F016S5,
-+ .name = "Intel 28F016S5",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_INTEL_EXT,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,32),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F008SA,
-+ .name = "Intel 28F008SA",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
- ERASEINFO(0x10000, 16),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F800B3B,
-- name: "Intel 28F800B3B",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F800B3B,
-+ .name = "Intel 28F800B3B",
-+ .uaddr = {
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x02000, 8),
- ERASEINFO(0x10000, 15),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F800B3T,
-- name: "Intel 28F800B3T",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F800B3T,
-+ .name = "Intel 28F800B3T",
-+ .uaddr = {
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x10000, 15),
- ERASEINFO(0x02000, 8),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F016B3B,
-- name: "Intel 28F016B3B",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F016B3B,
-+ .name = "Intel 28F016B3B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x02000, 8),
- ERASEINFO(0x10000, 31),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F016S3,
-- name: "Intel I28F016S3",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 1,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F016S3,
-+ .name = "Intel I28F016S3",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
- ERASEINFO(0x10000, 32),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F016B3T,
-- name: "Intel 28F016B3T",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F016B3T,
-+ .name = "Intel 28F016B3T",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x10000, 31),
- ERASEINFO(0x02000, 8),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F160B3B,
-- name: "Intel 28F160B3B",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F160B3B,
-+ .name = "Intel 28F160B3B",
-+ .uaddr = {
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x02000, 8),
- ERASEINFO(0x10000, 31),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F160B3T,
-- name: "Intel 28F160B3T",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F160B3T,
-+ .name = "Intel 28F160B3T",
-+ .uaddr = {
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x10000, 31),
- ERASEINFO(0x02000, 8),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F320B3B,
-- name: "Intel 28F320B3B",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F320B3B,
-+ .name = "Intel 28F320B3B",
-+ .uaddr = {
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x02000, 8),
- ERASEINFO(0x10000, 63),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F320B3T,
-- name: "Intel 28F320B3T",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F320B3T,
-+ .name = "Intel 28F320B3T",
-+ .uaddr = {
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x10000, 63),
- ERASEINFO(0x02000, 8),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F640B3B,
-- name: "Intel 28F640B3B",
-- DevSize: SIZE_8MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F640B3B,
-+ .name = "Intel 28F640B3B",
-+ .uaddr = {
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_8MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x02000, 8),
- ERASEINFO(0x10000, 127),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F640B3T,
-- name: "Intel 28F640B3T",
-- DevSize: SIZE_8MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F640B3T,
-+ .name = "Intel 28F640B3T",
-+ .uaddr = {
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_8MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x10000, 127),
- ERASEINFO(0x02000, 8),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I82802AB,
-- name: "Intel 82802AB",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_INTEL_EXT,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,8),
-- }
-- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I82802AC,
-- name: "Intel 82802AC",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_INTEL_EXT,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,16),
-- }
-- }, {
-- mfr_id: MANUFACTURER_ST,
-- dev_id: M29W800T,
-- name: "ST M29W800T",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,15),
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I82802AB,
-+ .name = "Intel 82802AB",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_INTEL_EXT,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,8),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I82802AC,
-+ .name = "Intel 82802AC",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_INTEL_EXT,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,16),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_MACRONIX,
-+ .dev_id = MX29LV160T,
-+ .name = "MXIC MX29LV160T",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,31),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_ST,
-- dev_id: M29W160DT,
-- name: "ST M29W160DT",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,31),
-- ERASEINFO(0x08000,1),
-- ERASEINFO(0x02000,2),
-- ERASEINFO(0x04000,1)
-- }
-- }, {
-- mfr_id: MANUFACTURER_ST,
-- dev_id: M29W160DB,
-- name: "ST M29W160DB",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-+ .mfr_id = MANUFACTURER_MACRONIX,
-+ .dev_id = MX29LV160B,
-+ .name = "MXIC MX29LV160B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x10000,31)
- }
- }, {
-- mfr_id: MANUFACTURER_ATMEL,
-- dev_id: AT49BV512,
-- name: "Atmel AT49BV512",
-- DevSize: SIZE_64KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,1)
-- }
-- }, {
-- mfr_id: MANUFACTURER_ATMEL,
-- dev_id: AT29LV512,
-- name: "Atmel AT29LV512",
-- DevSize: SIZE_64KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {
-- ERASEINFO(0x80,256),
-- ERASEINFO(0x80,256)
-- }
-- }, {
-- mfr_id: MANUFACTURER_ATMEL,
-- dev_id: AT49BV16X,
-- name: "Atmel AT49BV16X",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x02000,8),
-- ERASEINFO(0x10000,31)
-+ .mfr_id = MANUFACTURER_MACRONIX,
-+ .dev_id = MX29F016,
-+ .name = "Macronix MX29F016",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,32),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_MACRONIX,
-+ .dev_id = MX29F004T,
-+ .name = "Macronix MX29F004T",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,7),
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x02000,2),
-+ ERASEINFO(0x04000,1),
- }
- }, {
-- mfr_id: MANUFACTURER_ATMEL,
-- dev_id: AT49BV16XT,
-- name: "Atmel AT49BV16XT",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x10000,31),
-- ERASEINFO(0x02000,8)
-+ .mfr_id = MANUFACTURER_MACRONIX,
-+ .dev_id = MX29F004B,
-+ .name = "Macronix MX29F004B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
-+ ERASEINFO(0x02000,2),
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x10000,7),
- }
- }, {
-- mfr_id: MANUFACTURER_ATMEL,
-- dev_id: AT49BV32X,
-- name: "Atmel AT49BV32X",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x02000,8),
-- ERASEINFO(0x10000,63)
-+ .mfr_id = MANUFACTURER_PMC,
-+ .dev_id = PM49FL002,
-+ .name = "PMC Pm49FL002",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_256KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO( 0x01000, 64 )
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_PMC,
-+ .dev_id = PM49FL004,
-+ .name = "PMC Pm49FL004",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO( 0x01000, 128 )
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_PMC,
-+ .dev_id = PM49FL008,
-+ .name = "PMC Pm49FL008",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO( 0x01000, 256 )
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST39LF512,
-+ .name = "SST 39LF512",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_64KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,16),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST39LF010,
-+ .name = "SST 39LF010",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_128KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,32),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST39LF020,
-+ .name = "SST 39LF020",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_256KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,64),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST39LF040,
-+ .name = "SST 39LF040",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,128),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST39SF010A,
-+ .name = "SST 39SF010A",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_128KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,32),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST39SF020A,
-+ .name = "SST 39SF020A",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_256KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,64),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST49LF004B,
-+ .name = "SST 49LF004B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,128),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST49LF030A,
-+ .name = "SST 49LF030A",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,96),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST49LF040A,
-+ .name = "SST 49LF040A",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,128),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST49LF080A,
-+ .name = "SST 49LF080A",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,256),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
-+ .dev_id = M29W800DT,
-+ .name = "ST M29W800DT",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
-+ [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,15),
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x02000,2),
-+ ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_ATMEL,
-- dev_id: AT49BV32XT,
-- name: "Atmel AT49BV32XT",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x10000,63),
-- ERASEINFO(0x02000,8)
-+ .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
-+ .dev_id = M29W800DB,
-+ .name = "ST M29W800DB",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
-+ [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
-+ ERASEINFO(0x02000,2),
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x10000,15)
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F017D,
-- name: "AMD AM29F017D",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,32),
-- }
-- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F016,
-- name: "AMD AM29F016",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,32),
-- }
-- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F080,
-- name: "AMD AM29F080",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,16),
-- }
-- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F040,
-- name: "AMD AM29F040",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,8),
-- }
-- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV040B,
-- name: "AMD AM29LV040B",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,8),
-- }
-- }, {
-- mfr_id: MANUFACTURER_ST,
-- dev_id: M29W040B,
-- name: "ST M29W040B",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,8),
-- }
-- }, {
-- mfr_id: MANUFACTURER_MACRONIX,
-- dev_id: MX29LV160T,
-- name: "MXIC MX29LV160T",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,31),
-+ .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
-+ .dev_id = M29W160DT,
-+ .name = "ST M29W160DT",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,31),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_MACRONIX,
-- dev_id: MX29LV160B,
-- name: "MXIC MX29LV160B",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-+ .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
-+ .dev_id = M29W160DB,
-+ .name = "ST M29W160DB",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x10000,31)
- }
- }, {
-- mfr_id: MANUFACTURER_MACRONIX,
-- dev_id: MX29F016,
-- name: "Macronix MX29F016",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,32),
-- }
-- }, {
-- mfr_id: MANUFACTURER_MACRONIX,
-- dev_id: MX29F004T,
-- name: "Macronix MX29F004T",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,7),
-+ .mfr_id = MANUFACTURER_ST,
-+ .dev_id = M29W040B,
-+ .name = "ST M29W040B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,8),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_TOSHIBA,
-+ .dev_id = TC58FVT160,
-+ .name = "Toshiba TC58FVT160",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,31),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x02000,2),
-- ERASEINFO(0x04000,1),
-+ ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_MACRONIX,
-- dev_id: MX29F004B,
-- name: "Macronix MX29F004B",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-+ .mfr_id = MANUFACTURER_TOSHIBA,
-+ .dev_id = TC58FVB160,
-+ .name = "Toshiba TC58FVB160",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x08000,1),
-- ERASEINFO(0x10000,7),
-+ ERASEINFO(0x10000,31)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_TOSHIBA,
-+ .dev_id = TC58FVB321,
-+ .name = "Toshiba TC58FVB321",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x02000,8),
-+ ERASEINFO(0x10000,63)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_TOSHIBA,
-+ .dev_id = TC58FVT321,
-+ .name = "Toshiba TC58FVT321",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x10000,63),
-+ ERASEINFO(0x02000,8)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_TOSHIBA,
-+ .dev_id = TC58FVB641,
-+ .name = "Toshiba TC58FVB641",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_8MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x02000,8),
-+ ERASEINFO(0x10000,127)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_TOSHIBA,
-+ .dev_id = TC58FVT641,
-+ .name = "Toshiba TC58FVT641",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_8MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x10000,127),
-+ ERASEINFO(0x02000,8)
- }
- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST39LF512,
-- name: "SST 39LF512",
-- DevSize: SIZE_64KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,16),
-- }
-- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST39LF010,
-- name: "SST 39LF010",
-- DevSize: SIZE_128KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,32),
-- }
-- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST39LF020,
-- name: "SST 39LF020",
-- DevSize: SIZE_256KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,64),
-- }
-- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST39LF040,
-- name: "SST 39LF040",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,128),
-- }
-- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST39SF010A,
-- name: "SST 39SF010A",
-- DevSize: SIZE_128KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,32),
-- }
-- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST39SF020A,
-- name: "SST 39SF020A",
-- DevSize: SIZE_256KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,64),
-- }
-- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST49LF030A,
-- name: "SST 49LF030A",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,96),
-- }
-- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST49LF040A,
-- name: "SST 49LF040A",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,128),
-- }
-- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST49LF080A,
-- name: "SST 49LF080A",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,256),
-+ .mfr_id = MANUFACTURER_WINBOND,
-+ .dev_id = W49V002A,
-+ .name = "Winbond W49V002A",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_256KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000, 3),
-+ ERASEINFO(0x08000, 1),
-+ ERASEINFO(0x02000, 2),
-+ ERASEINFO(0x04000, 1),
- }
- }
- };
-@@ -907,7 +1452,7 @@
- static int cfi_jedec_setup(struct cfi_private *p_cfi, int index);
-
- static int jedec_probe_chip(struct map_info *map, __u32 base,
-- struct flchip *chips, struct cfi_private *cfi);
-+ unsigned long *chip_map, struct cfi_private *cfi);
-
- struct mtd_info *jedec_probe(struct map_info *map);
-
-@@ -944,11 +1489,43 @@
- * this should be safe.
- */
- cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
-+ /* FIXME - should have reset delay before continuing */
-+}
-
-+
-+static inline __u8 finfo_uaddr(const struct amd_flash_info *finfo, int device_type)
-+{
-+ int uaddr_idx;
-+ __u8 uaddr = MTD_UADDR_NOT_SUPPORTED;
-+
-+ switch ( device_type ) {
-+ case CFI_DEVICETYPE_X8: uaddr_idx = 0; break;
-+ case CFI_DEVICETYPE_X16: uaddr_idx = 1; break;
-+ case CFI_DEVICETYPE_X32: uaddr_idx = 2; break;
-+ default:
-+ printk(KERN_NOTICE "MTD: %s(): unknown device_type %d\n",
-+ __func__, device_type);
-+ goto uaddr_done;
-+ }
-+
-+ uaddr = finfo->uaddr[uaddr_idx];
-+
-+ if (uaddr != MTD_UADDR_NOT_SUPPORTED ) {
-+ /* ASSERT("The unlock addresses for non-8-bit mode
-+ are bollocks. We don't really need an array."); */
-+ uaddr = finfo->uaddr[0];
-+ }
-+
-+ uaddr_done:
-+ return uaddr;
- }
-+
-+
- static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
- {
- int i,num_erase_regions;
-+ unsigned long mask;
-+ __u8 uaddr;
-
- printk("Found: %s\n",jedec_table[index].name);
-
-@@ -971,41 +1548,170 @@
- p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i];
- }
- p_cfi->cmdset_priv = 0;
-+
-+ /* This may be redundant for some cases, but it doesn't hurt */
-+ p_cfi->mfr = jedec_table[index].mfr_id;
-+ p_cfi->id = jedec_table[index].dev_id;
-+
-+ uaddr = finfo_uaddr(&jedec_table[index], p_cfi->device_type);
-+ if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) {
-+ kfree( p_cfi->cfiq );
-+ return 0;
-+ }
-+
-+ /* Mask out address bits which are smaller than the device type */
-+ mask = ~(p_cfi->device_type-1);
-+ p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1 & mask;
-+ p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2 & mask;
-+
- return 1; /* ok */
- }
-
--static int jedec_probe_chip(struct map_info *map, __u32 base,
-- struct flchip *chips, struct cfi_private *cfi)
-+
-+/*
-+ * There is a BIG problem properly ID'ing the JEDEC devic and guaranteeing
-+ * the mapped address, unlock addresses, and proper chip ID. This function
-+ * attempts to minimize errors. It is doubtfull that this probe will ever
-+ * be perfect - consequently there should be some module parameters that
-+ * could be manually specified to force the chip info.
-+ */
-+static inline int jedec_match( __u32 base,
-+ struct map_info *map,
-+ struct cfi_private *cfi,
-+ const struct amd_flash_info *finfo )
- {
-- int i;
-- int unlockpass = 0;
-+ int rc = 0; /* failure until all tests pass */
-+ u32 mfr, id;
-+ __u8 uaddr;
-+ unsigned long mask;
-
-- if (!cfi->numchips) {
-+ /*
-+ * The IDs must match. For X16 and X32 devices operating in
-+ * a lower width ( X8 or X16 ), the device ID's are usually just
-+ * the lower byte(s) of the larger device ID for wider mode. If
-+ * a part is found that doesn't fit this assumption (device id for
-+ * smaller width mode is completely unrealated to full-width mode)
-+ * then the jedec_table[] will have to be augmented with the IDs
-+ * for different widths.
-+ */
- switch (cfi->device_type) {
- case CFI_DEVICETYPE_X8:
-- cfi->addr_unlock1 = 0x555;
-- cfi->addr_unlock2 = 0x2aa;
-+ mfr = (__u8)finfo->mfr_id;
-+ id = (__u8)finfo->dev_id;
- break;
- case CFI_DEVICETYPE_X16:
-- cfi->addr_unlock1 = 0xaaa;
-- if (map->buswidth == cfi->interleave) {
-- /* X16 chip(s) in X8 mode */
-- cfi->addr_unlock2 = 0x555;
-- } else {
-- cfi->addr_unlock2 = 0x554;
-- }
-+ mfr = (__u16)finfo->mfr_id;
-+ id = (__u16)finfo->dev_id;
- break;
- case CFI_DEVICETYPE_X32:
-- cfi->addr_unlock1 = 0x1555;
-- cfi->addr_unlock2 = 0xaaa;
-+ mfr = (__u16)finfo->mfr_id;
-+ id = (__u32)finfo->dev_id;
- break;
- default:
-- printk(KERN_NOTICE "Eep. Unknown jedec_probe device type %d\n", cfi->device_type);
-- return 0;
-+ printk(KERN_WARNING
-+ "MTD %s(): Unsupported device type %d\n",
-+ __func__, cfi->device_type);
-+ goto match_done;
-+ }
-+ if ( cfi->mfr != mfr || cfi->id != id ) {
-+ goto match_done;
-+ }
-+
-+ /* the part size must fit in the memory window */
-+ DEBUG( MTD_DEBUG_LEVEL3,
-+ "MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n",
-+ __func__, base, 1 << finfo->DevSize, base + (1 << finfo->DevSize) );
-+ if ( base + cfi->interleave * ( 1 << finfo->DevSize ) > map->size ) {
-+ DEBUG( MTD_DEBUG_LEVEL3,
-+ "MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n",
-+ __func__, finfo->mfr_id, finfo->dev_id,
-+ 1 << finfo->DevSize );
-+ goto match_done;
-+ }
-+
-+ uaddr = finfo_uaddr(finfo, cfi->device_type);
-+ if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) {
-+ goto match_done;
-+ }
-+
-+ mask = ~(cfi->device_type-1);
-+
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n",
-+ __func__, cfi->addr_unlock1, cfi->addr_unlock2 );
-+ if ( MTD_UADDR_UNNECESSARY != uaddr && MTD_UADDR_DONT_CARE != uaddr
-+ && ( (unlock_addrs[uaddr].addr1 & mask) != cfi->addr_unlock1 ||
-+ (unlock_addrs[uaddr].addr2 & mask) != cfi->addr_unlock2 ) ) {
-+ DEBUG( MTD_DEBUG_LEVEL3,
-+ "MTD %s(): 0x%.4x 0x%.4x did not match\n",
-+ __func__,
-+ unlock_addrs[uaddr].addr1 & mask,
-+ unlock_addrs[uaddr].addr2 & mask);
-+ goto match_done;
- }
-+
-+ /*
-+ * Make sure the ID's dissappear when the device is taken out of
-+ * ID mode. The only time this should fail when it should succeed
-+ * is when the ID's are written as data to the same
-+ * addresses. For this rare and unfortunate case the chip
-+ * cannot be probed correctly.
-+ * FIXME - write a driver that takes all of the chip info as
-+ * module parameters, doesn't probe but forces a load.
-+ */
-+ DEBUG( MTD_DEBUG_LEVEL3,
-+ "MTD %s(): check ID's disappear when not in ID mode\n",
-+ __func__ );
-+ jedec_reset( base, map, cfi );
-+ mfr = jedec_read_mfr( map, base, cfi );
-+ id = jedec_read_id( map, base, cfi );
-+ if ( mfr == cfi->mfr && id == cfi->id ) {
-+ DEBUG( MTD_DEBUG_LEVEL3,
-+ "MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n"
-+ "You might need to manually specify JEDEC parameters.\n",
-+ __func__, cfi->mfr, cfi->id );
-+ goto match_done;
-+ }
-+
-+ /* all tests passed - mark as success */
-+ rc = 1;
-+
-+ /*
-+ * Put the device back in ID mode - only need to do this if we
-+ * were truly frobbing a real device.
-+ */
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): return to ID mode\n", __func__ );
-+ if(cfi->addr_unlock1) {
-+ cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
-+ cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
- }
-+ cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
-+ /* FIXME - should have a delay before continuing */
-+
-+ match_done:
-+ return rc;
-+}
-+
-+
-+static int jedec_probe_chip(struct map_info *map, __u32 base,
-+ unsigned long *chip_map, struct cfi_private *cfi)
-+{
-+ int i;
-+ enum uaddr uaddr_idx = MTD_UADDR_NOT_SUPPORTED;
-
- retry:
-+ if (!cfi->numchips) {
-+ unsigned long mask = ~(cfi->device_type-1);
-+
-+ uaddr_idx++;
-+
-+ if (MTD_UADDR_UNNECESSARY == uaddr_idx)
-+ return 0;
-+
-+ /* Mask out address bits which are smaller than the device type */
-+ cfi->addr_unlock1 = unlock_addrs[uaddr_idx].addr1 & mask;
-+ cfi->addr_unlock2 = unlock_addrs[uaddr_idx].addr2 & mask;
-+ }
-+
- /* Make certain we aren't probing past the end of map */
- if (base >= map->size) {
- printk(KERN_NOTICE
-@@ -1038,6 +1744,7 @@
- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
- }
- cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
-+ /* FIXME - should have a delay before continuing */
-
- if (!cfi->numchips) {
- /* This is the first time we're called. Set up the CFI
-@@ -1045,26 +1752,21 @@
-
- cfi->mfr = jedec_read_mfr(map, base, cfi);
- cfi->id = jedec_read_id(map, base, cfi);
-- printk(KERN_INFO "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
-+ DEBUG(MTD_DEBUG_LEVEL3,
-+ "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
- cfi->mfr, cfi->id, cfi->interleave, cfi->device_type);
- for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) {
-- if (cfi->mfr == jedec_table[i].mfr_id &&
-- cfi->id == jedec_table[i].dev_id) {
-+ if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
-+ DEBUG( MTD_DEBUG_LEVEL3,
-+ "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
-+ __func__, cfi->mfr, cfi->id,
-+ cfi->addr_unlock1, cfi->addr_unlock2 );
- if (!cfi_jedec_setup(cfi, i))
- return 0;
- goto ok_out;
- }
- }
-- switch(unlockpass++) {
-- case 0:
-- cfi->addr_unlock1 |= cfi->addr_unlock1 << 4;
-- cfi->addr_unlock2 |= cfi->addr_unlock2 << 4;
-- goto retry;
-- case 1:
-- cfi->addr_unlock1 = cfi->addr_unlock2 = 0;
- goto retry;
-- }
-- return 0;
- } else {
- __u16 mfr;
- __u16 id;
-@@ -1081,21 +1783,24 @@
- }
- }
-
-- /* Check each previous chip to see if it's an alias */
-- for (i=0; i<cfi->numchips; i++) {
-- /* This chip should be in read mode if it's one
-- we've already touched. */
-- if (jedec_read_mfr(map, chips[i].start, cfi) == cfi->mfr &&
-- jedec_read_id(map, chips[i].start, cfi) == cfi->id) {
-+ /* Check each previous chip locations to see if it's an alias */
-+ for (i=0; i < (base >> cfi->chipshift); i++) {
-+ unsigned long start;
-+ if(!test_bit(i, chip_map)) {
-+ continue; /* Skip location; no valid chip at this address */
-+ }
-+ start = i << cfi->chipshift;
-+ if (jedec_read_mfr(map, start, cfi) == cfi->mfr &&
-+ jedec_read_id(map, start, cfi) == cfi->id) {
- /* Eep. This chip also looks like it's in autoselect mode.
- Is it an alias for the new one? */
-- jedec_reset(chips[i].start, map, cfi);
-+ jedec_reset(start, map, cfi);
-
- /* If the device IDs go away, it's an alias */
- if (jedec_read_mfr(map, base, cfi) != cfi->mfr ||
- jedec_read_id(map, base, cfi) != cfi->id) {
- printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
-- map->name, base, chips[i].start);
-+ map->name, base, start);
- return 0;
- }
-
-@@ -1107,7 +1812,7 @@
- if (jedec_read_mfr(map, base, cfi) == cfi->mfr &&
- jedec_read_id(map, base, cfi) == cfi->id) {
- printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
-- map->name, base, chips[i].start);
-+ map->name, base, start);
- return 0;
- }
- }
-@@ -1115,13 +1820,7 @@
-
- /* OK, if we got to here, then none of the previous chips appear to
- be aliases for the current one. */
-- if (cfi->numchips == MAX_CFI_CHIPS) {
-- printk(KERN_WARNING"%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n", map->name, MAX_CFI_CHIPS);
-- /* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */
-- return -1;
-- }
-- chips[cfi->numchips].start = base;
-- chips[cfi->numchips].state = FL_READY;
-+ set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
- cfi->numchips++;
-
- ok_out:
-@@ -1136,8 +1835,8 @@
- }
-
- static struct chip_probe jedec_chip_probe = {
-- name: "JEDEC",
-- probe_chip: jedec_probe_chip
-+ .name = "JEDEC",
-+ .probe_chip = jedec_probe_chip
- };
-
- struct mtd_info *jedec_probe(struct map_info *map)
-@@ -1150,9 +1849,9 @@
- }
-
- static struct mtd_chip_driver jedec_chipdrv = {
-- probe: jedec_probe,
-- name: "jedec_probe",
-- module: THIS_MODULE
-+ .probe = jedec_probe,
-+ .name = "jedec_probe",
-+ .module = THIS_MODULE
- };
-
- int __init jedec_probe_init(void)
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/chips/map_absent.c linux/drivers/mtd/chips/map_absent.c
---- linux-mips-2.4.24-pre2/drivers/mtd/chips/map_absent.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/chips/map_absent.c 2004-11-17 18:17:58.963325472 +0100
-@@ -1,7 +1,7 @@
- /*
- * Common code to handle absent "placeholder" devices
- * Copyright 2001 Resilience Corporation <ebrower@resilience.com>
-- * $Id$
-+ * $Id$
- *
- * This map driver is used to allocate "placeholder" MTD
- * devices on systems that have socketed/removable media.
-@@ -23,9 +23,10 @@
- #include <linux/kernel.h>
- #include <linux/errno.h>
- #include <linux/slab.h>
--
-+#include <linux/init.h>
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
--
-+#include <linux/mtd/compatmac.h>
-
- static int map_absent_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
- static int map_absent_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
-@@ -36,10 +37,10 @@
-
-
- static struct mtd_chip_driver map_absent_chipdrv = {
-- probe: map_absent_probe,
-- destroy: map_absent_destroy,
-- name: "map_absent",
-- module: THIS_MODULE
-+ .probe = map_absent_probe,
-+ .destroy = map_absent_destroy,
-+ .name = "map_absent",
-+ .module = THIS_MODULE
- };
-
- static struct mtd_info *map_absent_probe(struct map_info *map)
-@@ -65,7 +66,7 @@
- mtd->flags = 0;
- mtd->erasesize = PAGE_SIZE;
-
-- MOD_INC_USE_COUNT;
-+ __module_get(THIS_MODULE);
- return mtd;
- }
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/chips/map_ram.c linux/drivers/mtd/chips/map_ram.c
---- linux-mips-2.4.24-pre2/drivers/mtd/chips/map_ram.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/chips/map_ram.c 2004-11-17 18:17:58.965325168 +0100
-@@ -1,7 +1,7 @@
- /*
- * Common code to handle map devices which are simple RAM
- * (C) 2000 Red Hat. GPL'd.
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/module.h>
-@@ -11,8 +11,10 @@
- #include <asm/byteorder.h>
- #include <linux/errno.h>
- #include <linux/slab.h>
--
-+#include <linux/init.h>
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-+#include <linux/mtd/compatmac.h>
-
-
- static int mapram_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
-@@ -23,9 +25,9 @@
-
-
- static struct mtd_chip_driver mapram_chipdrv = {
-- probe: map_ram_probe,
-- name: "map_ram",
-- module: THIS_MODULE
-+ .probe = map_ram_probe,
-+ .name = "map_ram",
-+ .module = THIS_MODULE
- };
-
- static struct mtd_info *map_ram_probe(struct map_info *map)
-@@ -34,21 +36,21 @@
-
- /* Check the first byte is RAM */
- #if 0
-- map->write8(map, 0x55, 0);
-- if (map->read8(map, 0) != 0x55)
-+ map_write8(map, 0x55, 0);
-+ if (map_read8(map, 0) != 0x55)
- return NULL;
-
-- map->write8(map, 0xAA, 0);
-- if (map->read8(map, 0) != 0xAA)
-+ map_write8(map, 0xAA, 0);
-+ if (map_read8(map, 0) != 0xAA)
- return NULL;
-
- /* Check the last byte is RAM */
-- map->write8(map, 0x55, map->size-1);
-- if (map->read8(map, map->size-1) != 0x55)
-+ map_write8(map, 0x55, map->size-1);
-+ if (map_read8(map, map->size-1) != 0x55)
- return NULL;
-
-- map->write8(map, 0xAA, map->size-1);
-- if (map->read8(map, map->size-1) != 0xAA)
-+ map_write8(map, 0xAA, map->size-1);
-+ if (map_read8(map, map->size-1) != 0xAA)
- return NULL;
- #endif
- /* OK. It seems to be RAM. */
-@@ -74,7 +76,7 @@
- while(mtd->size & (mtd->erasesize - 1))
- mtd->erasesize >>= 1;
-
-- MOD_INC_USE_COUNT;
-+ __module_get(THIS_MODULE);
- return mtd;
- }
-
-@@ -83,7 +85,7 @@
- {
- struct map_info *map = (struct map_info *)mtd->priv;
-
-- map->copy_from(map, buf, from, len);
-+ map_copy_from(map, buf, from, len);
- *retlen = len;
- return 0;
- }
-@@ -92,7 +94,7 @@
- {
- struct map_info *map = (struct map_info *)mtd->priv;
-
-- map->copy_to(map, to, buf, len);
-+ map_copy_to(map, to, buf, len);
- *retlen = len;
- return 0;
- }
-@@ -105,7 +107,7 @@
- unsigned long i;
-
- for (i=0; i<instr->len; i++)
-- map->write8(map, 0xFF, instr->addr + i);
-+ map_write8(map, 0xFF, instr->addr + i);
-
- if (instr->callback)
- instr->callback(instr);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/chips/map_rom.c linux/drivers/mtd/chips/map_rom.c
---- linux-mips-2.4.24-pre2/drivers/mtd/chips/map_rom.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/chips/map_rom.c 2004-11-17 18:17:58.966325016 +0100
-@@ -1,7 +1,7 @@
- /*
- * Common code to handle map devices which are simple ROM
- * (C) 2000 Red Hat. GPL'd.
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/version.h>
-@@ -12,8 +12,10 @@
- #include <asm/byteorder.h>
- #include <linux/errno.h>
- #include <linux/slab.h>
--
-+#include <linux/init.h>
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-+#include <linux/mtd/compatmac.h>
-
- static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
- static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
-@@ -21,9 +23,9 @@
- struct mtd_info *map_rom_probe(struct map_info *map);
-
- static struct mtd_chip_driver maprom_chipdrv = {
-- probe: map_rom_probe,
-- name: "map_rom",
-- module: THIS_MODULE
-+ .probe = map_rom_probe,
-+ .name = "map_rom",
-+ .module = THIS_MODULE
- };
-
- struct mtd_info *map_rom_probe(struct map_info *map)
-@@ -49,7 +51,7 @@
- while(mtd->size & (mtd->erasesize - 1))
- mtd->erasesize >>= 1;
-
-- MOD_INC_USE_COUNT;
-+ __module_get(THIS_MODULE);
- return mtd;
- }
-
-@@ -58,7 +60,7 @@
- {
- struct map_info *map = (struct map_info *)mtd->priv;
-
-- map->copy_from(map, buf, from, len);
-+ map_copy_from(map, buf, from, len);
- *retlen = len;
- return 0;
- }
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/chips/sharp.c linux/drivers/mtd/chips/sharp.c
---- linux-mips-2.4.24-pre2/drivers/mtd/chips/sharp.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/chips/sharp.c 2004-11-17 18:17:58.968324712 +0100
-@@ -4,7 +4,7 @@
- * Copyright 2000,2001 David A. Schleef <ds@schleef.org>
- * 2000,2001 Lineo, Inc.
- *
-- * $Id$
-+ * $Id$
- *
- * Devices supported:
- * LH28F016SCT Symmetrical block flash memory, 2Mx8
-@@ -28,6 +28,7 @@
- #include <linux/errno.h>
- #include <linux/interrupt.h>
- #include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/cfi.h>
- #include <linux/delay.h>
-
-@@ -98,10 +99,10 @@
- static void sharp_destroy(struct mtd_info *mtd);
-
- static struct mtd_chip_driver sharp_chipdrv = {
-- probe: sharp_probe,
-- destroy: sharp_destroy,
-- name: "sharp",
-- module: THIS_MODULE
-+ .probe = sharp_probe,
-+ .destroy = sharp_destroy,
-+ .name = "sharp",
-+ .module = THIS_MODULE
- };
-
-
-@@ -116,8 +117,10 @@
- return NULL;
-
- sharp = kmalloc(sizeof(*sharp), GFP_KERNEL);
-- if(!sharp)
-+ if(!sharp) {
-+ kfree(mtd);
- return NULL;
-+ }
-
- memset(mtd, 0, sizeof(*mtd));
-
-@@ -163,12 +166,12 @@
- u32 read0, read4;
- int width = 4;
-
-- tmp = map->read32(map, base+0);
-+ tmp = map_read32(map, base+0);
-
-- map->write32(map, CMD_READ_ID, base+0);
-+ map_write32(map, CMD_READ_ID, base+0);
-
-- read0=map->read32(map, base+0);
-- read4=map->read32(map, base+4);
-+ read0=map_read32(map, base+0);
-+ read4=map_read32(map, base+4);
- if(read0 == 0x89898989){
- printk("Looks like sharp flash\n");
- switch(read4){
-@@ -196,10 +199,10 @@
- printk("Sort-of looks like sharp flash, 0x%08x 0x%08x\n",
- read0,read4);
- }
-- }else if((map->read32(map, base+0) == CMD_READ_ID)){
-+ }else if((map_read32(map, base+0) == CMD_READ_ID)){
- /* RAM, probably */
- printk("Looks like RAM\n");
-- map->write32(map, tmp, base+0);
-+ map_write32(map, tmp, base+0);
- }else{
- printk("Doesn't look like sharp flash, 0x%08x 0x%08x\n",
- read0,read4);
-@@ -221,10 +224,10 @@
-
- switch(chip->state){
- case FL_READY:
-- map->write32(map,CMD_READ_STATUS,adr);
-+ map_write32(map,CMD_READ_STATUS,adr);
- chip->state = FL_STATUS;
- case FL_STATUS:
-- status = map->read32(map,adr);
-+ status = map_read32(map,adr);
- //printk("status=%08x\n",status);
-
- udelay(100);
-@@ -252,7 +255,7 @@
- goto retry;
- }
-
-- map->write32(map,CMD_RESET, adr);
-+ map_write32(map,CMD_RESET, adr);
-
- chip->state = FL_READY;
-
-@@ -293,7 +296,7 @@
- if(ret<0)
- break;
-
-- map->copy_from(map,buf,ofs,thislen);
-+ map_copy_from(map,buf,ofs,thislen);
-
- sharp_release(&sharp->chips[chipnum]);
-
-@@ -354,17 +357,17 @@
- ret = sharp_wait(map,chip);
-
- for(try=0;try<10;try++){
-- map->write32(map,CMD_BYTE_WRITE,adr);
-+ map_write32(map,CMD_BYTE_WRITE,adr);
- /* cpu_to_le32 -> hack to fix the writel be->le conversion */
-- map->write32(map,cpu_to_le32(datum),adr);
-+ map_write32(map,cpu_to_le32(datum),adr);
-
- chip->state = FL_WRITING;
-
- timeo = jiffies + (HZ/2);
-
-- map->write32(map,CMD_READ_STATUS,adr);
-+ map_write32(map,CMD_READ_STATUS,adr);
- for(i=0;i<100;i++){
-- status = map->read32(map,adr);
-+ status = map_read32(map,adr);
- if((status & SR_READY)==SR_READY)
- break;
- }
-@@ -377,9 +380,9 @@
-
- printk("sharp: error writing byte at addr=%08lx status=%08x\n",adr,status);
-
-- map->write32(map,CMD_CLEAR_STATUS,adr);
-+ map_write32(map,CMD_CLEAR_STATUS,adr);
- }
-- map->write32(map,CMD_RESET,adr);
-+ map_write32(map,CMD_RESET,adr);
- chip->state = FL_READY;
-
- wake_up(&chip->wq);
-@@ -436,14 +439,14 @@
- int status;
- DECLARE_WAITQUEUE(wait, current);
-
-- map->write32(map,CMD_READ_STATUS,adr);
-- status = map->read32(map,adr);
-+ map_write32(map,CMD_READ_STATUS,adr);
-+ status = map_read32(map,adr);
-
- timeo = jiffies + HZ;
-
- while(time_before(jiffies, timeo)){
-- map->write32(map,CMD_READ_STATUS,adr);
-- status = map->read32(map,adr);
-+ map_write32(map,CMD_READ_STATUS,adr);
-+ status = map_read32(map,adr);
- if((status & SR_READY)==SR_READY){
- ret = 0;
- goto out;
-@@ -485,26 +488,26 @@
- sharp_unlock_oneblock(map,chip,adr);
- #endif
-
-- map->write32(map,CMD_BLOCK_ERASE_1,adr);
-- map->write32(map,CMD_BLOCK_ERASE_2,adr);
-+ map_write32(map,CMD_BLOCK_ERASE_1,adr);
-+ map_write32(map,CMD_BLOCK_ERASE_2,adr);
-
- chip->state = FL_ERASING;
-
- ret = sharp_do_wait_for_ready(map,chip,adr);
- if(ret<0)return ret;
-
-- map->write32(map,CMD_READ_STATUS,adr);
-- status = map->read32(map,adr);
-+ map_write32(map,CMD_READ_STATUS,adr);
-+ status = map_read32(map,adr);
-
- if(!(status&SR_ERRORS)){
-- map->write32(map,CMD_RESET,adr);
-+ map_write32(map,CMD_RESET,adr);
- chip->state = FL_READY;
- //spin_unlock_bh(chip->mutex);
- return 0;
- }
-
- printk("sharp: error erasing block at addr=%08lx status=%08x\n",adr,status);
-- map->write32(map,CMD_CLEAR_STATUS,adr);
-+ map_write32(map,CMD_CLEAR_STATUS,adr);
-
- //spin_unlock_bh(chip->mutex);
-
-@@ -518,17 +521,17 @@
- int i;
- int status;
-
-- map->write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr);
-- map->write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr);
-+ map_write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr);
-+ map_write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr);
-
- udelay(100);
-
-- status = map->read32(map,adr);
-+ status = map_read32(map,adr);
- printk("status=%08x\n",status);
-
- for(i=0;i<1000;i++){
-- //map->write32(map,CMD_READ_STATUS,adr);
-- status = map->read32(map,adr);
-+ //map_write32(map,CMD_READ_STATUS,adr);
-+ status = map_read32(map,adr);
- if((status & SR_READY)==SR_READY)
- break;
- udelay(100);
-@@ -538,13 +541,13 @@
- }
-
- if(!(status&SR_ERRORS)){
-- map->write32(map,CMD_RESET,adr);
-+ map_write32(map,CMD_RESET,adr);
- chip->state = FL_READY;
- return;
- }
-
- printk("sharp: error unlocking block at addr=%08lx status=%08x\n",adr,status);
-- map->write32(map,CMD_CLEAR_STATUS,adr);
-+ map_write32(map,CMD_CLEAR_STATUS,adr);
- }
- #endif
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/cmdlinepart.c linux/drivers/mtd/cmdlinepart.c
---- linux-mips-2.4.24-pre2/drivers/mtd/cmdlinepart.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/cmdlinepart.c 2004-11-17 18:17:58.829345840 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Read flash partition table from command line
- *
-@@ -28,7 +28,7 @@
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/partitions.h>
--#include <asm/setup.h>
-+#include <linux/mtd/compatmac.h>
- #include <linux/bootmem.h>
-
- /* error message prefix */
-@@ -178,8 +178,7 @@
- parts[this_part].mask_flags = mask_flags;
- if (name)
- {
-- strncpy(extra_mem, name, name_len);
-- extra_mem[name_len] = 0;
-+ strlcpy(extra_mem, name, name_len + 1);
- }
- else
- {
-@@ -258,8 +257,7 @@
- this_mtd->parts = parts;
- this_mtd->num_parts = num_parts;
- this_mtd->mtd_id = (char*)(this_mtd + 1);
-- strncpy(this_mtd->mtd_id, mtd_id, mtd_id_len);
-- this_mtd->mtd_id[mtd_id_len] = 0;
-+ strlcpy(this_mtd->mtd_id, mtd_id, mtd_id_len + 1);
-
- /* link into chain */
- this_mtd->next = partitions;
-@@ -291,13 +289,14 @@
- * information. It returns partitions for the requested mtd device, or
- * the first one in the chain if a NULL mtd_id is passed in.
- */
--int parse_cmdline_partitions(struct mtd_info *master,
-+static int parse_cmdline_partitions(struct mtd_info *master,
- struct mtd_partition **pparts,
-- const char *mtd_id)
-+ unsigned long origin)
- {
- unsigned long offset;
- int i;
- struct cmdline_mtd_partition *part;
-+ char *mtd_id = master->name;
-
- if(!cmdline)
- return -EINVAL;
-@@ -349,7 +348,25 @@
-
- __setup("mtdparts=", mtdpart_setup);
-
--EXPORT_SYMBOL(parse_cmdline_partitions);
-+static struct mtd_part_parser cmdline_parser = {
-+ .owner = THIS_MODULE,
-+ .parse_fn = parse_cmdline_partitions,
-+ .name = "cmdlinepart",
-+};
-+
-+static int __init cmdline_parser_init(void)
-+{
-+ return register_mtd_parser(&cmdline_parser);
-+}
-+
-+static void __exit cmdline_parser_exit(void)
-+{
-+ deregister_mtd_parser(&cmdline_parser);
-+}
-+
-+module_init(cmdline_parser_init);
-+module_exit(cmdline_parser_exit);
-+
-
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Marius Groeger <mag@sysgo.de>");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/devices/Config.in linux/drivers/mtd/devices/Config.in
---- linux-mips-2.4.24-pre2/drivers/mtd/devices/Config.in 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/devices/Config.in 2004-11-17 18:17:58.972324104 +0100
-@@ -1,6 +1,6 @@
--# drivers/mtd/maps/Config.in
-+# drivers/mtd/devices/Config.in
-
--# $Id$
-+# $Id$
-
- mainmenu_option next_comment
-
-@@ -28,13 +28,13 @@
- dep_tristate ' MTD emulation using block device' CONFIG_MTD_BLKMTD $CONFIG_MTD
-
- comment 'Disk-On-Chip Device Drivers'
-- dep_tristate ' M-Systems Disk-On-Chip 1000' CONFIG_MTD_DOC1000 $CONFIG_MTD
- dep_tristate ' M-Systems Disk-On-Chip 2000 and Millennium' CONFIG_MTD_DOC2000 $CONFIG_MTD
- dep_tristate ' M-Systems Disk-On-Chip Millennium-only alternative driver (see help)' CONFIG_MTD_DOC2001 $CONFIG_MTD
-- if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then
-+ dep_tristate ' M-Systems Disk-On-Chip Millennium Plus driver (see help)' CONFIG_MTD_DOC2001PLUS $CONFIG_MTD
-+ if [ "$CONFIG_MTD_DOC2001PLUS" = "y" -o "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then
- define_bool CONFIG_MTD_DOCPROBE y
- else
-- if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then
-+ if [ "$CONFIG_MTD_DOC2001PLUS" = "m" -o "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then
- define_bool CONFIG_MTD_DOCPROBE m
- else
- define_bool CONFIG_MTD_DOCPROBE n
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/devices/Makefile linux/drivers/mtd/devices/Makefile
---- linux-mips-2.4.24-pre2/drivers/mtd/devices/Makefile 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/devices/Makefile 2004-11-17 18:17:58.974323800 +0100
-@@ -1,9 +1,12 @@
- #
- # linux/drivers/devices/Makefile
- #
--# $Id$
-+# $Id$
-
-+ifeq ($(PATCHLEVEL),4)
- O_TARGET := devlink.o
-+export-objs := docecc.o
-+endif
-
- # *** BIG UGLY NOTE ***
- #
-@@ -12,15 +15,16 @@
- # here where previously there was none. We now have to ensure that
- # doc200[01].o are linked before docprobe.o
-
--obj-$(CONFIG_MTD_DOC1000) += doc1000.o
- obj-$(CONFIG_MTD_DOC2000) += doc2000.o
- obj-$(CONFIG_MTD_DOC2001) += doc2001.o
-+obj-$(CONFIG_MTD_DOC2001PLUS) += doc2001plus.o
- obj-$(CONFIG_MTD_DOCPROBE) += docprobe.o docecc.o
- obj-$(CONFIG_MTD_SLRAM) += slram.o
-+obj-$(CONFIG_MTD_PHRAM) += phram.o
- obj-$(CONFIG_MTD_PMC551) += pmc551.o
- obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o
- obj-$(CONFIG_MTD_MTDRAM) += mtdram.o
- obj-$(CONFIG_MTD_LART) += lart.o
- obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o
-
--include $(TOPDIR)/Rules.make
-+-include $(TOPDIR)/Rules.make
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/devices/blkmtd-25.c linux/drivers/mtd/devices/blkmtd-25.c
---- linux-mips-2.4.24-pre2/drivers/mtd/devices/blkmtd-25.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/devices/blkmtd-25.c 2004-11-17 18:17:58.000000000 +0100
-@@ -0,0 +1,827 @@
-+/*
-+ * $Id$
-+ *
-+ * blkmtd.c - use a block device as a fake MTD
-+ *
-+ * Author: Simon Evans <spse@secret.org.uk>
-+ *
-+ * Copyright (C) 2001,2002 Simon Evans
-+ *
-+ * Licence: GPL
-+ *
-+ * How it works:
-+ * The driver uses raw/io to read/write the device and the page
-+ * cache to cache access. Writes update the page cache with the
-+ * new data and mark it dirty and add the page into a BIO which
-+ * is then written out.
-+ *
-+ * It can be loaded Read-Only to prevent erases and writes to the
-+ * medium.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/fs.h>
-+#include <linux/blkdev.h>
-+#include <linux/bio.h>
-+#include <linux/pagemap.h>
-+#include <linux/list.h>
-+#include <linux/init.h>
-+#include <linux/mtd/mtd.h>
-+
-+
-+#define err(format, arg...) printk(KERN_ERR "blkmtd: " format "\n" , ## arg)
-+#define info(format, arg...) printk(KERN_INFO "blkmtd: " format "\n" , ## arg)
-+#define warn(format, arg...) printk(KERN_WARNING "blkmtd: " format "\n" , ## arg)
-+#define crit(format, arg...) printk(KERN_CRIT "blkmtd: " format "\n" , ## arg)
-+
-+
-+/* Default erase size in K, always make it a multiple of PAGE_SIZE */
-+#define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */
-+#define VERSION "$Revision$"
-+
-+/* Info for the block device */
-+struct blkmtd_dev {
-+ struct list_head list;
-+ struct block_device *blkdev;
-+ struct mtd_info mtd_info;
-+ struct semaphore wrbuf_mutex;
-+};
-+
-+
-+/* Static info about the MTD, used in cleanup_module */
-+static LIST_HEAD(blkmtd_device_list);
-+
-+
-+static void blkmtd_sync(struct mtd_info *mtd);
-+
-+#define MAX_DEVICES 4
-+
-+/* Module parameters passed by insmod/modprobe */
-+char *device[MAX_DEVICES]; /* the block device to use */
-+int erasesz[MAX_DEVICES]; /* optional default erase size */
-+int ro[MAX_DEVICES]; /* optional read only flag */
-+int sync;
-+
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>");
-+MODULE_DESCRIPTION("Emulate an MTD using a block device");
-+MODULE_PARM(device, "1-4s");
-+MODULE_PARM_DESC(device, "block device to use");
-+MODULE_PARM(erasesz, "1-4i");
-+MODULE_PARM_DESC(erasesz, "optional erase size to use in KiB. eg 4=4KiB.");
-+MODULE_PARM(ro, "1-4i");
-+MODULE_PARM_DESC(ro, "1=Read only, writes and erases cause errors");
-+MODULE_PARM(sync, "i");
-+MODULE_PARM_DESC(sync, "1=Synchronous writes");
-+
-+
-+/* completion handler for BIO reads */
-+static int bi_read_complete(struct bio *bio, unsigned int bytes_done, int error)
-+{
-+ if (bio->bi_size)
-+ return 1;
-+
-+ complete((struct completion*)bio->bi_private);
-+ return 0;
-+}
-+
-+
-+/* completion handler for BIO writes */
-+static int bi_write_complete(struct bio *bio, unsigned int bytes_done, int error)
-+{
-+ const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
-+ struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
-+
-+ if (bio->bi_size)
-+ return 1;
-+
-+ if(!uptodate)
-+ err("bi_write_complete: not uptodate\n");
-+
-+ do {
-+ struct page *page = bvec->bv_page;
-+ DEBUG(3, "Cleaning up page %ld\n", page->index);
-+ if (--bvec >= bio->bi_io_vec)
-+ prefetchw(&bvec->bv_page->flags);
-+
-+ if (uptodate) {
-+ SetPageUptodate(page);
-+ } else {
-+ ClearPageUptodate(page);
-+ SetPageError(page);
-+ }
-+ ClearPageDirty(page);
-+ unlock_page(page);
-+ page_cache_release(page);
-+ } while (bvec >= bio->bi_io_vec);
-+
-+ complete((struct completion*)bio->bi_private);
-+ return 0;
-+}
-+
-+
-+/* read one page from the block device */
-+static int blkmtd_readpage(struct blkmtd_dev *dev, struct page *page)
-+{
-+ struct bio *bio;
-+ struct completion event;
-+ int err = -ENOMEM;
-+
-+ if(PageUptodate(page)) {
-+ DEBUG(2, "blkmtd: readpage page %ld is already upto date\n", page->index);
-+ unlock_page(page);
-+ return 0;
-+ }
-+
-+ ClearPageUptodate(page);
-+ ClearPageError(page);
-+
-+ bio = bio_alloc(GFP_KERNEL, 1);
-+ if(bio) {
-+ init_completion(&event);
-+ bio->bi_bdev = dev->blkdev;
-+ bio->bi_sector = page->index << (PAGE_SHIFT-9);
-+ bio->bi_private = &event;
-+ bio->bi_end_io = bi_read_complete;
-+ if(bio_add_page(bio, page, PAGE_SIZE, 0) == PAGE_SIZE) {
-+ submit_bio(READ, bio);
-+ blk_run_queues();
-+ wait_for_completion(&event);
-+ err = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : -EIO;
-+ bio_put(bio);
-+ }
-+ }
-+
-+ if(err)
-+ SetPageError(page);
-+ else
-+ SetPageUptodate(page);
-+ flush_dcache_page(page);
-+ unlock_page(page);
-+ return err;
-+}
-+
-+
-+/* write out the current BIO and wait for it to finish */
-+static int blkmtd_write_out(struct bio *bio)
-+{
-+ struct completion event;
-+ int err;
-+
-+ if(!bio->bi_vcnt) {
-+ bio_put(bio);
-+ return 0;
-+ }
-+
-+ init_completion(&event);
-+ bio->bi_private = &event;
-+ bio->bi_end_io = bi_write_complete;
-+ submit_bio(WRITE, bio);
-+ blk_run_queues();
-+ wait_for_completion(&event);
-+ DEBUG(3, "submit_bio completed, bi_vcnt = %d\n", bio->bi_vcnt);
-+ err = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : -EIO;
-+ bio_put(bio);
-+ return err;
-+}
-+
-+
-+/**
-+ * blkmtd_add_page - add a page to the current BIO
-+ * @bio: bio to add to (NULL to alloc initial bio)
-+ * @blkdev: block device
-+ * @page: page to add
-+ * @pagecnt: pages left to add
-+ *
-+ * Adds a page to the current bio, allocating it if necessary. If it cannot be
-+ * added, the current bio is written out and a new one is allocated. Returns
-+ * the new bio to add or NULL on error
-+ */
-+static struct bio *blkmtd_add_page(struct bio *bio, struct block_device *blkdev,
-+ struct page *page, int pagecnt)
-+{
-+
-+ retry:
-+ if(!bio) {
-+ bio = bio_alloc(GFP_KERNEL, pagecnt);
-+ if(!bio)
-+ return NULL;
-+ bio->bi_sector = page->index << (PAGE_SHIFT-9);
-+ bio->bi_bdev = blkdev;
-+ }
-+
-+ if(bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) {
-+ blkmtd_write_out(bio);
-+ bio = NULL;
-+ goto retry;
-+ }
-+ return bio;
-+}
-+
-+
-+/**
-+ * write_pages - write block of data to device via the page cache
-+ * @dev: device to write to
-+ * @buf: data source or NULL if erase (output is set to 0xff)
-+ * @to: offset into output device
-+ * @len: amount to data to write
-+ * @retlen: amount of data written
-+ *
-+ * Grab pages from the page cache and fill them with the source data.
-+ * Non page aligned start and end result in a readin of the page and
-+ * part of the page being modified. Pages are added to the bio and then written
-+ * out.
-+ */
-+static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to,
-+ size_t len, size_t *retlen)
-+{
-+ int pagenr, offset;
-+ size_t start_len = 0, end_len;
-+ int pagecnt = 0;
-+ int err = 0;
-+ struct bio *bio = NULL;
-+ size_t thislen = 0;
-+
-+ pagenr = to >> PAGE_SHIFT;
-+ offset = to & ~PAGE_MASK;
-+
-+ DEBUG(2, "blkmtd: write_pages: buf = %p to = %ld len = %d pagenr = %d offset = %d\n",
-+ buf, (long)to, len, pagenr, offset);
-+
-+ /* see if we have to do a partial write at the start */
-+ if(offset) {
-+ start_len = ((offset + len) > PAGE_SIZE) ? PAGE_SIZE - offset : len;
-+ len -= start_len;
-+ }
-+
-+ /* calculate the length of the other two regions */
-+ end_len = len & ~PAGE_MASK;
-+ len -= end_len;
-+
-+ if(start_len)
-+ pagecnt++;
-+
-+ if(len)
-+ pagecnt += len >> PAGE_SHIFT;
-+
-+ if(end_len)
-+ pagecnt++;
-+
-+ down(&dev->wrbuf_mutex);
-+
-+ DEBUG(3, "blkmtd: write: start_len = %d len = %d end_len = %d pagecnt = %d\n",
-+ start_len, len, end_len, pagecnt);
-+
-+ if(start_len) {
-+ /* do partial start region */
-+ struct page *page;
-+
-+ DEBUG(3, "blkmtd: write: doing partial start, page = %d len = %d offset = %d\n",
-+ pagenr, start_len, offset);
-+
-+ BUG_ON(!buf);
-+ page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev);
-+ lock_page(page);
-+ if(PageDirty(page)) {
-+ err("to = %lld start_len = %d len = %d end_len = %d pagenr = %d\n",
-+ to, start_len, len, end_len, pagenr);
-+ BUG();
-+ }
-+ memcpy(page_address(page)+offset, buf, start_len);
-+ SetPageDirty(page);
-+ SetPageUptodate(page);
-+ buf += start_len;
-+ thislen = start_len;
-+ bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt);
-+ if(!bio) {
-+ err = -ENOMEM;
-+ err("bio_add_page failed\n");
-+ goto write_err;
-+ }
-+ pagecnt--;
-+ pagenr++;
-+ }
-+
-+ /* Now do the main loop to a page aligned, n page sized output */
-+ if(len) {
-+ int pagesc = len >> PAGE_SHIFT;
-+ DEBUG(3, "blkmtd: write: whole pages start = %d, count = %d\n",
-+ pagenr, pagesc);
-+ while(pagesc) {
-+ struct page *page;
-+
-+ /* see if page is in the page cache */
-+ DEBUG(3, "blkmtd: write: grabbing page %d from page cache\n", pagenr);
-+ page = grab_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr);
-+ if(PageDirty(page)) {
-+ BUG();
-+ }
-+ if(!page) {
-+ warn("write: cannot grab cache page %d", pagenr);
-+ err = -ENOMEM;
-+ goto write_err;
-+ }
-+ if(!buf) {
-+ memset(page_address(page), 0xff, PAGE_SIZE);
-+ } else {
-+ memcpy(page_address(page), buf, PAGE_SIZE);
-+ buf += PAGE_SIZE;
-+ }
-+ bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt);
-+ if(!bio) {
-+ err = -ENOMEM;
-+ err("bio_add_page failed\n");
-+ goto write_err;
-+ }
-+ pagenr++;
-+ pagecnt--;
-+ SetPageDirty(page);
-+ SetPageUptodate(page);
-+ pagesc--;
-+ thislen += PAGE_SIZE;
-+ }
-+ }
-+
-+ if(end_len) {
-+ /* do the third region */
-+ struct page *page;
-+ DEBUG(3, "blkmtd: write: doing partial end, page = %d len = %d\n",
-+ pagenr, end_len);
-+ BUG_ON(!buf);
-+ page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev);
-+ lock_page(page);
-+ if(PageDirty(page)) {
-+ err("to = %lld start_len = %d len = %d end_len = %d pagenr = %d\n",
-+ to, start_len, len, end_len, pagenr);
-+ BUG();
-+ }
-+ memcpy(page_address(page), buf, end_len);
-+ SetPageDirty(page);
-+ SetPageUptodate(page);
-+ DEBUG(3, "blkmtd: write: writing out partial end\n");
-+ thislen += end_len;
-+ bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt);
-+ if(!bio) {
-+ err = -ENOMEM;
-+ err("bio_add_page failed\n");
-+ goto write_err;
-+ }
-+ pagenr++;
-+ }
-+
-+ DEBUG(3, "blkmtd: write: got %d vectors to write\n", bio->bi_vcnt);
-+ write_err:
-+ if(bio)
-+ blkmtd_write_out(bio);
-+
-+ DEBUG(2, "blkmtd: write: end, retlen = %d, err = %d\n", *retlen, err);
-+ up(&dev->wrbuf_mutex);
-+
-+ if(retlen)
-+ *retlen = thislen;
-+ return err;
-+}
-+
-+
-+/* erase a specified part of the device */
-+static int blkmtd_erase(struct mtd_info *mtd, struct erase_info *instr)
-+{
-+ struct blkmtd_dev *dev = mtd->priv;
-+ struct mtd_erase_region_info *einfo = mtd->eraseregions;
-+ int numregions = mtd->numeraseregions;
-+ size_t from;
-+ u_long len;
-+ int err = -EIO;
-+ int retlen;
-+
-+ instr->state = MTD_ERASING;
-+ from = instr->addr;
-+ len = instr->len;
-+
-+ /* check erase region has valid start and length */
-+ DEBUG(2, "blkmtd: erase: dev = `%s' from = 0x%x len = 0x%lx\n",
-+ mtd->name+9, from, len);
-+ while(numregions) {
-+ DEBUG(3, "blkmtd: checking erase region = 0x%08X size = 0x%X num = 0x%x\n",
-+ einfo->offset, einfo->erasesize, einfo->numblocks);
-+ if(from >= einfo->offset
-+ && from < einfo->offset + (einfo->erasesize * einfo->numblocks)) {
-+ if(len == einfo->erasesize
-+ && ( (from - einfo->offset) % einfo->erasesize == 0))
-+ break;
-+ }
-+ numregions--;
-+ einfo++;
-+ }
-+
-+ if(!numregions) {
-+ /* Not a valid erase block */
-+ err("erase: invalid erase request 0x%lX @ 0x%08X", len, from);
-+ instr->state = MTD_ERASE_FAILED;
-+ err = -EIO;
-+ }
-+
-+ if(instr->state != MTD_ERASE_FAILED) {
-+ /* do the erase */
-+ DEBUG(3, "Doing erase from = %d len = %ld\n", from, len);
-+ err = write_pages(dev, NULL, from, len, &retlen);
-+ if(err || retlen != len) {
-+ err("erase failed err = %d", err);
-+ instr->state = MTD_ERASE_FAILED;
-+ } else {
-+ instr->state = MTD_ERASE_DONE;
-+ }
-+ }
-+
-+ DEBUG(3, "blkmtd: erase: checking callback\n");
-+ if (instr->callback) {
-+ (*(instr->callback))(instr);
-+ }
-+ DEBUG(2, "blkmtd: erase: finished (err = %d)\n", err);
-+ return err;
-+}
-+
-+
-+/* read a range of the data via the page cache */
-+static int blkmtd_read(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t *retlen, u_char *buf)
-+{
-+ struct blkmtd_dev *dev = mtd->priv;
-+ int err = 0;
-+ int offset;
-+ int pagenr, pages;
-+ size_t thislen = 0;
-+
-+ DEBUG(2, "blkmtd: read: dev = `%s' from = %ld len = %d buf = %p\n",
-+ mtd->name+9, (long int)from, len, buf);
-+
-+ if(from > mtd->size)
-+ return -EINVAL;
-+ if(from + len > mtd->size)
-+ len = mtd->size - from;
-+
-+ pagenr = from >> PAGE_SHIFT;
-+ offset = from - (pagenr << PAGE_SHIFT);
-+
-+ pages = (offset+len+PAGE_SIZE-1) >> PAGE_SHIFT;
-+ DEBUG(3, "blkmtd: read: pagenr = %d offset = %d, pages = %d\n",
-+ pagenr, offset, pages);
-+
-+ while(pages) {
-+ struct page *page;
-+ int cpylen;
-+
-+ DEBUG(3, "blkmtd: read: looking for page: %d\n", pagenr);
-+ page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev);
-+ if(IS_ERR(page)) {
-+ err = -EIO;
-+ goto readerr;
-+ }
-+
-+ cpylen = (PAGE_SIZE > len) ? len : PAGE_SIZE;
-+ if(offset+cpylen > PAGE_SIZE)
-+ cpylen = PAGE_SIZE-offset;
-+
-+ memcpy(buf + thislen, page_address(page) + offset, cpylen);
-+ offset = 0;
-+ len -= cpylen;
-+ thislen += cpylen;
-+ pagenr++;
-+ pages--;
-+ if(!PageDirty(page))
-+ page_cache_release(page);
-+ }
-+
-+ readerr:
-+ if(retlen)
-+ *retlen = thislen;
-+ DEBUG(2, "blkmtd: end read: retlen = %d, err = %d\n", thislen, err);
-+ return err;
-+}
-+
-+
-+/* write data to the underlying device */
-+static int blkmtd_write(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf)
-+{
-+ struct blkmtd_dev *dev = mtd->priv;
-+ int err;
-+
-+ if(!len)
-+ return 0;
-+
-+ DEBUG(2, "blkmtd: write: dev = `%s' to = %ld len = %d buf = %p\n",
-+ mtd->name+9, (long int)to, len, buf);
-+
-+ if(to >= mtd->size) {
-+ return -ENOSPC;
-+ }
-+
-+ if(to + len > mtd->size) {
-+ len = mtd->size - to;
-+ }
-+
-+ err = write_pages(dev, buf, to, len, retlen);
-+ if(err > 0)
-+ err = 0;
-+ DEBUG(2, "blkmtd: write: end, err = %d\n", err);
-+ return err;
-+}
-+
-+
-+/* sync the device - wait until the write queue is empty */
-+static void blkmtd_sync(struct mtd_info *mtd)
-+{
-+ /* Currently all writes are synchronous */
-+}
-+
-+
-+static void free_device(struct blkmtd_dev *dev)
-+{
-+ DEBUG(2, "blkmtd: free_device() dev = %p\n", dev);
-+ if(dev) {
-+ if(dev->mtd_info.eraseregions)
-+ kfree(dev->mtd_info.eraseregions);
-+ if(dev->mtd_info.name)
-+ kfree(dev->mtd_info.name);
-+
-+ if(dev->blkdev) {
-+ invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping);
-+ close_bdev_excl(dev->blkdev, BDEV_RAW);
-+ }
-+ kfree(dev);
-+ }
-+}
-+
-+
-+/* For a given size and initial erase size, calculate the number
-+ * and size of each erase region. Goes round the loop twice,
-+ * once to find out how many regions, then allocates space,
-+ * then round the loop again to fill it in.
-+ */
-+static struct mtd_erase_region_info *calc_erase_regions(
-+ size_t erase_size, size_t total_size, int *regions)
-+{
-+ struct mtd_erase_region_info *info = NULL;
-+
-+ DEBUG(2, "calc_erase_regions, es = %d size = %d regions = %d\n",
-+ erase_size, total_size, *regions);
-+ /* Make any user specified erasesize be a power of 2
-+ and at least PAGE_SIZE */
-+ if(erase_size) {
-+ int es = erase_size;
-+ erase_size = 1;
-+ while(es != 1) {
-+ es >>= 1;
-+ erase_size <<= 1;
-+ }
-+ if(erase_size < PAGE_SIZE)
-+ erase_size = PAGE_SIZE;
-+ } else {
-+ erase_size = CONFIG_MTD_BLKDEV_ERASESIZE;
-+ }
-+
-+ *regions = 0;
-+
-+ do {
-+ int tot_size = total_size;
-+ int er_size = erase_size;
-+ int count = 0, offset = 0, regcnt = 0;
-+
-+ while(tot_size) {
-+ count = tot_size / er_size;
-+ if(count) {
-+ tot_size = tot_size % er_size;
-+ if(info) {
-+ DEBUG(2, "adding to erase info off=%d er=%d cnt=%d\n",
-+ offset, er_size, count);
-+ (info+regcnt)->offset = offset;
-+ (info+regcnt)->erasesize = er_size;
-+ (info+regcnt)->numblocks = count;
-+ (*regions)++;
-+ }
-+ regcnt++;
-+ offset += (count * er_size);
-+ }
-+ while(er_size > tot_size)
-+ er_size >>= 1;
-+ }
-+ if(info == NULL) {
-+ info = kmalloc(regcnt * sizeof(struct mtd_erase_region_info), GFP_KERNEL);
-+ if(!info)
-+ break;
-+ }
-+ } while(!(*regions));
-+ DEBUG(2, "calc_erase_regions done, es = %d size = %d regions = %d\n",
-+ erase_size, total_size, *regions);
-+ return info;
-+}
-+
-+
-+extern dev_t __init name_to_dev_t(const char *line);
-+
-+static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size)
-+{
-+ struct block_device *bdev;
-+ int mode;
-+ struct blkmtd_dev *dev;
-+
-+ if(!devname)
-+ return NULL;
-+
-+ /* Get a handle on the device */
-+
-+
-+#ifdef MODULE
-+ mode = (readonly) ? O_RDONLY : O_RDWR;
-+ bdev = open_bdev_excl(devname, mode, BDEV_RAW, NULL);
-+#else
-+ mode = (readonly) ? FMODE_READ : FMODE_WRITE;
-+ bdev = open_by_devnum(name_to_dev_t(devname), mode, BDEV_RAW);
-+#endif
-+ if(IS_ERR(bdev)) {
-+ err("error: cannot open device %s", devname);
-+ DEBUG(2, "blkmtd: opening bdev returned %ld\n", PTR_ERR(bdev));
-+ return NULL;
-+ }
-+
-+ DEBUG(1, "blkmtd: found a block device major = %d, minor = %d\n",
-+ MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev));
-+
-+ if(MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
-+ err("attempting to use an MTD device as a block device");
-+ blkdev_put(bdev, BDEV_RAW);
-+ return NULL;
-+ }
-+
-+ dev = kmalloc(sizeof(struct blkmtd_dev), GFP_KERNEL);
-+ if(dev == NULL) {
-+ blkdev_put(bdev, BDEV_RAW);
-+ return NULL;
-+ }
-+
-+ memset(dev, 0, sizeof(struct blkmtd_dev));
-+ if(!readonly) {
-+ init_MUTEX(&dev->wrbuf_mutex);
-+ }
-+
-+ dev->blkdev = bdev;
-+ dev->mtd_info.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
-+
-+ /* Setup the MTD structure */
-+ /* make the name contain the block device in */
-+ dev->mtd_info.name = kmalloc(sizeof("blkmtd: ") + strlen(devname), GFP_KERNEL);
-+ if(dev->mtd_info.name == NULL)
-+ goto devinit_err;
-+
-+ sprintf(dev->mtd_info.name, "blkmtd: %s", devname);
-+ dev->mtd_info.eraseregions = calc_erase_regions(erase_size, dev->mtd_info.size,
-+ &dev->mtd_info.numeraseregions);
-+ if(dev->mtd_info.eraseregions == NULL)
-+ goto devinit_err;
-+
-+ dev->mtd_info.erasesize = dev->mtd_info.eraseregions->erasesize;
-+ DEBUG(1, "blkmtd: init: found %d erase regions\n",
-+ dev->mtd_info.numeraseregions);
-+
-+ if(readonly) {
-+ dev->mtd_info.type = MTD_ROM;
-+ dev->mtd_info.flags = MTD_CAP_ROM;
-+ } else {
-+ dev->mtd_info.type = MTD_RAM;
-+ dev->mtd_info.flags = MTD_CAP_RAM;
-+ dev->mtd_info.erase = blkmtd_erase;
-+ dev->mtd_info.write = blkmtd_write;
-+ dev->mtd_info.writev = default_mtd_writev;
-+ dev->mtd_info.sync = blkmtd_sync;
-+ }
-+ dev->mtd_info.read = blkmtd_read;
-+ dev->mtd_info.readv = default_mtd_readv;
-+ dev->mtd_info.priv = dev;
-+ dev->mtd_info.owner = THIS_MODULE;
-+
-+ list_add(&dev->list, &blkmtd_device_list);
-+ if (add_mtd_device(&dev->mtd_info)) {
-+ /* Device didnt get added, so free the entry */
-+ list_del(&dev->list);
-+ goto devinit_err;
-+ } else {
-+ info("mtd%d: [%s] erase_size = %dKiB %s",
-+ dev->mtd_info.index, dev->mtd_info.name + strlen("blkmtd: "),
-+ dev->mtd_info.erasesize >> 10,
-+ readonly ? "(read-only)" : "");
-+ }
-+
-+ return dev;
-+
-+ devinit_err:
-+ free_device(dev);
-+ return NULL;
-+}
-+
-+
-+/* Cleanup and exit - sync the device and kill of the kernel thread */
-+static void __devexit cleanup_blkmtd(void)
-+{
-+ struct list_head *temp1, *temp2;
-+
-+ /* Remove the MTD devices */
-+ list_for_each_safe(temp1, temp2, &blkmtd_device_list) {
-+ struct blkmtd_dev *dev = list_entry(temp1, struct blkmtd_dev,
-+ list);
-+ blkmtd_sync(&dev->mtd_info);
-+ del_mtd_device(&dev->mtd_info);
-+ info("mtd%d: [%s] removed", dev->mtd_info.index,
-+ dev->mtd_info.name + strlen("blkmtd: "));
-+ list_del(&dev->list);
-+ free_device(dev);
-+ }
-+}
-+
-+#ifndef MODULE
-+
-+/* Handle kernel boot params */
-+
-+
-+static int __init param_blkmtd_device(char *str)
-+{
-+ int i;
-+
-+ for(i = 0; i < MAX_DEVICES; i++) {
-+ device[i] = str;
-+ DEBUG(2, "blkmtd: device setup: %d = %s\n", i, device[i]);
-+ strsep(&str, ",");
-+ }
-+ return 1;
-+}
-+
-+
-+static int __init param_blkmtd_erasesz(char *str)
-+{
-+ int i;
-+ for(i = 0; i < MAX_DEVICES; i++) {
-+ char *val = strsep(&str, ",");
-+ if(val)
-+ erasesz[i] = simple_strtoul(val, NULL, 0);
-+ DEBUG(2, "blkmtd: erasesz setup: %d = %d\n", i, erasesz[i]);
-+ }
-+
-+ return 1;
-+}
-+
-+
-+static int __init param_blkmtd_ro(char *str)
-+{
-+ int i;
-+ for(i = 0; i < MAX_DEVICES; i++) {
-+ char *val = strsep(&str, ",");
-+ if(val)
-+ ro[i] = simple_strtoul(val, NULL, 0);
-+ DEBUG(2, "blkmtd: ro setup: %d = %d\n", i, ro[i]);
-+ }
-+
-+ return 1;
-+}
-+
-+
-+static int __init param_blkmtd_sync(char *str)
-+{
-+ if(str[0] == '1')
-+ sync = 1;
-+ return 1;
-+}
-+
-+__setup("blkmtd_device=", param_blkmtd_device);
-+__setup("blkmtd_erasesz=", param_blkmtd_erasesz);
-+__setup("blkmtd_ro=", param_blkmtd_ro);
-+__setup("blkmtd_sync=", param_blkmtd_sync);
-+
-+#endif
-+
-+
-+/* Startup */
-+static int __init init_blkmtd(void)
-+{
-+ int i;
-+
-+ info("version " VERSION);
-+ /* Check args - device[0] is the bare minimum*/
-+ if(!device[0]) {
-+ err("error: missing `device' name\n");
-+ return -EINVAL;
-+ }
-+
-+ for(i = 0; i < MAX_DEVICES; i++)
-+ add_device(device[i], ro[i], erasesz[i] << 10);
-+
-+ if(list_empty(&blkmtd_device_list))
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+module_init(init_blkmtd);
-+module_exit(cleanup_blkmtd);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/devices/blkmtd.c linux/drivers/mtd/devices/blkmtd.c
---- linux-mips-2.4.24-pre2/drivers/mtd/devices/blkmtd.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/devices/blkmtd.c 2004-11-17 18:17:58.991321216 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * blkmtd.c - use a block device as a fake MTD
- *
-@@ -143,7 +143,7 @@
- for(cnt = 0; cnt < pages; cnt++) {
- page = grab_cache_page(dev->binding->bd_inode->i_mapping, pagenrs[cnt]);
- pagelst[cnt] = page;
-- if(!PageUptodate(page)) {
-+ if(!Page_Uptodate(page)) {
- iobuf->blocks[iobuf->nr_pages] = pagenrs[cnt];
- iobuf->maplist[iobuf->nr_pages++] = page;
- }
-@@ -912,7 +912,7 @@
- dev->mtd_info.point = 0;
- dev->mtd_info.unpoint = 0;
- dev->mtd_info.priv = dev;
-- dev->mtd_info.module = THIS_MODULE;
-+ dev->mtd_info.owner = THIS_MODULE;
-
- list_add(&dev->list, &blkmtd_device_list);
- if (add_mtd_device(&dev->mtd_info)) {
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/devices/doc2000.c linux/drivers/mtd/devices/doc2000.c
---- linux-mips-2.4.24-pre2/drivers/mtd/devices/doc2000.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/devices/doc2000.c 2004-11-17 18:17:58.994320760 +0100
-@@ -4,7 +4,7 @@
- * (c) 1999 Machine Vision Holdings, Inc.
- * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/kernel.h>
-@@ -25,6 +25,7 @@
- #include <linux/mtd/doc2000.h>
-
- #define DOC_SUPPORT_2000
-+#define DOC_SUPPORT_2000TSOP
- #define DOC_SUPPORT_MILLENNIUM
-
- #ifdef DOC_SUPPORT_2000
-@@ -33,7 +34,7 @@
- #define DoC_is_2000(doc) (0)
- #endif
-
--#ifdef DOC_SUPPORT_MILLENNIUM
-+#if defined(DOC_SUPPORT_2000TSOP) || defined(DOC_SUPPORT_MILLENNIUM)
- #define DoC_is_Millennium(doc) (doc->ChipID == DOC_ChipID_DocMil)
- #else
- #define DoC_is_Millennium(doc) (0)
-@@ -56,6 +57,9 @@
- size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel);
- static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
- size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel);
-+static int doc_writev_ecc(struct mtd_info *mtd, const struct iovec *vecs,
-+ unsigned long count, loff_t to, size_t *retlen,
-+ u_char *eccbuf, struct nand_oobinfo *oobsel);
- static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
- size_t *retlen, u_char *buf);
- static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-@@ -92,6 +96,10 @@
-
- /* Out-of-line routine to wait for chip response */
- while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
-+ /* issue 2 read from NOP register after reading from CDSNControl register
-+ see Software Requirement 11.4 item 2. */
-+ DoC_Delay(doc, 2);
-+
- if (time_after(jiffies, timeo)) {
- DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
- return -EIO;
-@@ -145,6 +153,8 @@
-
- /* Send the command */
- WriteDOC_(command, docptr, doc->ioreg);
-+ if (DoC_is_Millennium(doc))
-+ WriteDOC(command, docptr, WritePipeTerm);
-
- /* Lower the CLE line */
- WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
-@@ -206,6 +216,9 @@
- }
- }
-
-+ if (DoC_is_Millennium(doc))
-+ WriteDOC(ofs & 0xff, docptr, WritePipeTerm);
-+
- DoC_Delay(doc, 2); /* Needed for some slow flash chips. mf. */
-
- /* FIXME: The SlowIO's for millennium could be replaced by
-@@ -344,15 +357,25 @@
-
- /* Read the manufacturer and device id codes from the device */
-
-- /* CDSN Slow IO register see Software Requirement 11.4 item 5. */
-+ if (DoC_is_Millennium(doc)) {
-+ DoC_Delay(doc, 2);
-+ dummy = ReadDOC(doc->virtadr, ReadPipeInit);
-+ mfr = ReadDOC(doc->virtadr, LastDataRead);
-+
-+ DoC_Delay(doc, 2);
-+ dummy = ReadDOC(doc->virtadr, ReadPipeInit);
-+ id = ReadDOC(doc->virtadr, LastDataRead);
-+ } else {
-+ /* CDSN Slow IO register see Software Req 11.4 item 5. */
- dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
- DoC_Delay(doc, 2);
- mfr = ReadDOC_(doc->virtadr, doc->ioreg);
-
-- /* CDSN Slow IO register see Software Requirement 11.4 item 5. */
-+ /* CDSN Slow IO register see Software Req 11.4 item 5. */
- dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
- DoC_Delay(doc, 2);
- id = ReadDOC_(doc->virtadr, doc->ioreg);
-+ }
-
- /* No response - return failure */
- if (mfr == 0xff || mfr == 0)
-@@ -410,20 +433,16 @@
-
- /* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
-
--static void DoC_ScanChips(struct DiskOnChip *this)
-+static void DoC_ScanChips(struct DiskOnChip *this, int maxchips)
- {
- int floor, chip;
- int numchips[MAX_FLOORS];
-- int maxchips = MAX_CHIPS;
- int ret = 1;
-
- this->numchips = 0;
- this->mfr = 0;
- this->id = 0;
-
-- if (DoC_is_Millennium(this))
-- maxchips = MAX_CHIPS_MIL;
--
- /* For each floor, find the number of valid chips it contains */
- for (floor = 0; floor < MAX_FLOORS; floor++) {
- ret = 1;
-@@ -515,6 +534,7 @@
- {
- struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
- struct DiskOnChip *old = NULL;
-+ int maxchips;
-
- /* We must avoid being called twice for the same device. */
-
-@@ -538,14 +558,28 @@
-
-
- switch (this->ChipID) {
-+ case DOC_ChipID_Doc2kTSOP:
-+ mtd->name = "DiskOnChip 2000 TSOP";
-+ this->ioreg = DoC_Mil_CDSN_IO;
-+ /* Pretend it's a Millennium */
-+ this->ChipID = DOC_ChipID_DocMil;
-+ maxchips = MAX_CHIPS;
-+ break;
- case DOC_ChipID_Doc2k:
- mtd->name = "DiskOnChip 2000";
- this->ioreg = DoC_2k_CDSN_IO;
-+ maxchips = MAX_CHIPS;
- break;
- case DOC_ChipID_DocMil:
- mtd->name = "DiskOnChip Millennium";
- this->ioreg = DoC_Mil_CDSN_IO;
-+ maxchips = MAX_CHIPS_MIL;
- break;
-+ default:
-+ printk("Unknown ChipID 0x%02x\n", this->ChipID);
-+ kfree(mtd);
-+ iounmap((void *) this->virtadr);
-+ return;
- }
-
- printk(KERN_NOTICE "%s found at address 0x%lX\n", mtd->name,
-@@ -553,11 +587,12 @@
-
- mtd->type = MTD_NANDFLASH;
- mtd->flags = MTD_CAP_NANDFLASH;
-+ mtd->ecctype = MTD_ECC_RS_DiskOnChip;
- mtd->size = 0;
- mtd->erasesize = 0;
- mtd->oobblock = 512;
- mtd->oobsize = 16;
-- mtd->module = THIS_MODULE;
-+ mtd->owner = THIS_MODULE;
- mtd->erase = doc_erase;
- mtd->point = NULL;
- mtd->unpoint = NULL;
-@@ -565,6 +600,7 @@
- mtd->write = doc_write;
- mtd->read_ecc = doc_read_ecc;
- mtd->write_ecc = doc_write_ecc;
-+ mtd->writev_ecc = doc_writev_ecc;
- mtd->read_oob = doc_read_oob;
- mtd->write_oob = doc_write_oob;
- mtd->sync = NULL;
-@@ -577,7 +613,7 @@
- init_MUTEX(&this->lock);
-
- /* Ident all the chips present. */
-- DoC_ScanChips(this);
-+ DoC_ScanChips(this, maxchips);
-
- if (!this->totlen) {
- kfree(mtd);
-@@ -608,6 +644,7 @@
- unsigned char syndrome[6];
- volatile char dummy;
- int i, len256 = 0, ret=0;
-+ size_t left = len;
-
- docptr = this->virtadr;
-
-@@ -617,6 +654,10 @@
-
- down(&this->lock);
-
-+ *retlen = 0;
-+ while (left) {
-+ len = left;
-+
- /* Don't allow a single read to cross a 512-byte block boundary */
- if (from + len > ((from | 0x1ff) + 1))
- len = ((from | 0x1ff) + 1) - from;
-@@ -673,7 +714,7 @@
- DoC_ReadBuf(this, &buf[len256], len - len256);
-
- /* Let the caller know we completed it */
-- *retlen = len;
-+ *retlen += len;
-
- if (eccbuf) {
- /* Read the ECC data through the DiskOnChip ECC logic */
-@@ -730,11 +771,16 @@
-
- /* according to 11.4.1, we need to wait for the busy line
- * drop if we read to the end of the page. */
-- if(0 == ((from + *retlen) & 0x1ff))
-+ if(0 == ((from + len) & 0x1ff))
- {
- DoC_WaitReady(this);
- }
-
-+ from += len;
-+ left -= len;
-+ buf += len;
-+ }
-+
- up(&this->lock);
-
- return ret;
-@@ -757,6 +803,8 @@
- volatile char dummy;
- int len256 = 0;
- struct Nand *mychip;
-+ size_t left = len;
-+ int status;
-
- docptr = this->virtadr;
-
-@@ -766,15 +814,21 @@
-
- down(&this->lock);
-
-+ *retlen = 0;
-+ while (left) {
-+ len = left;
-+
- /* Don't allow a single write to cross a 512-byte block boundary */
- if (to + len > ((to | 0x1ff) + 1))
- len = ((to | 0x1ff) + 1) - to;
-
- /* The ECC will not be calculated correctly if less than 512 is written */
-+/* DBB-
- if (len != 0x200 && eccbuf)
- printk(KERN_WARNING
- "ECC needs a full sector write (adr: %lx size %lx)\n",
- (long) to, (long) len);
-+ -DBB */
-
- /* printk("DoC_Write (adr: %lx size %lx)\n", (long) to, (long) len); */
-
-@@ -853,6 +907,9 @@
- WriteDOC_(0, docptr, this->ioreg);
- }
-
-+ WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_FLASH_IO | CDSN_CTRL_CE, docptr,
-+ CDSNControl);
-+
- /* Read the ECC data through the DiskOnChip ECC logic */
- for (di = 0; di < 6; di++) {
- eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
-@@ -874,10 +931,16 @@
- DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
- /* There's an implicit DoC_WaitReady() in DoC_Command */
-
-+ if (DoC_is_Millennium(this)) {
-+ ReadDOC(docptr, ReadPipeInit);
-+ status = ReadDOC(docptr, LastDataRead);
-+ } else {
- dummy = ReadDOC(docptr, CDSNSlowIO);
- DoC_Delay(this, 2);
-+ status = ReadDOC_(docptr, this->ioreg);
-+ }
-
-- if (ReadDOC_(docptr, this->ioreg) & 1) {
-+ if (status & 1) {
- printk(KERN_ERR "Error programming flash\n");
- /* Error in programming */
- *retlen = 0;
-@@ -886,7 +949,7 @@
- }
-
- /* Let the caller know we completed it */
-- *retlen = len;
-+ *retlen += len;
-
- if (eccbuf) {
- unsigned char x[8];
-@@ -901,13 +964,81 @@
- x[7]=0x55;
-
- ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x);
-+ if (ret) {
- up(&this->lock);
- return ret;
- }
-+ }
-+
-+ to += len;
-+ left -= len;
-+ buf += len;
-+ }
-+
- up(&this->lock);
- return 0;
- }
-
-+static int doc_writev_ecc(struct mtd_info *mtd, const struct iovec *vecs,
-+ unsigned long count, loff_t to, size_t *retlen,
-+ u_char *eccbuf, struct nand_oobinfo *oobsel)
-+{
-+ static char static_buf[512];
-+ static DECLARE_MUTEX(writev_buf_sem);
-+
-+ size_t totretlen = 0;
-+ size_t thisvecofs = 0;
-+ int ret= 0;
-+
-+ down(&writev_buf_sem);
-+
-+ while(count) {
-+ size_t thislen, thisretlen;
-+ unsigned char *buf;
-+
-+ buf = vecs->iov_base + thisvecofs;
-+ thislen = vecs->iov_len - thisvecofs;
-+
-+
-+ if (thislen >= 512) {
-+ thislen = thislen & ~(512-1);
-+ thisvecofs += thislen;
-+ } else {
-+ /* Not enough to fill a page. Copy into buf */
-+ memcpy(static_buf, buf, thislen);
-+ buf = &static_buf[thislen];
-+
-+ while(count && thislen < 512) {
-+ vecs++;
-+ count--;
-+ thisvecofs = min((512-thislen), vecs->iov_len);
-+ memcpy(buf, vecs->iov_base, thisvecofs);
-+ thislen += thisvecofs;
-+ buf += thisvecofs;
-+ }
-+ buf = static_buf;
-+ }
-+ if (count && thisvecofs == vecs->iov_len) {
-+ thisvecofs = 0;
-+ vecs++;
-+ count--;
-+ }
-+ ret = doc_write_ecc(mtd, to, thislen, &thisretlen, buf, eccbuf, oobsel);
-+
-+ totretlen += thisretlen;
-+
-+ if (ret || thisretlen != thislen)
-+ break;
-+
-+ to += thislen;
-+ }
-+
-+ up(&writev_buf_sem);
-+ *retlen = totretlen;
-+ return ret;
-+}
-+
-+
- static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
- size_t * retlen, u_char * buf)
- {
-@@ -977,6 +1108,7 @@
- unsigned long docptr = this->virtadr;
- struct Nand *mychip = &this->chips[ofs >> this->chipshift];
- volatile int dummy;
-+ int status;
-
- // printk("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",(long)ofs, len,
- // buf[0], buf[1], buf[2], buf[3], buf[8], buf[9], buf[14],buf[15]);
-@@ -1025,10 +1157,16 @@
- DoC_Command(this, NAND_CMD_STATUS, 0);
- /* DoC_WaitReady() is implicit in DoC_Command */
-
-+ if (DoC_is_Millennium(this)) {
-+ ReadDOC(docptr, ReadPipeInit);
-+ status = ReadDOC(docptr, LastDataRead);
-+ } else {
- dummy = ReadDOC(docptr, CDSNSlowIO);
- DoC_Delay(this, 2);
-+ status = ReadDOC_(docptr, this->ioreg);
-+ }
-
-- if (ReadDOC_(docptr, this->ioreg) & 1) {
-+ if (status & 1) {
- printk(KERN_ERR "Error programming oob data\n");
- /* There was an error */
- *retlen = 0;
-@@ -1044,10 +1182,16 @@
- DoC_Command(this, NAND_CMD_STATUS, 0);
- /* DoC_WaitReady() is implicit in DoC_Command */
-
-+ if (DoC_is_Millennium(this)) {
-+ ReadDOC(docptr, ReadPipeInit);
-+ status = ReadDOC(docptr, LastDataRead);
-+ } else {
- dummy = ReadDOC(docptr, CDSNSlowIO);
- DoC_Delay(this, 2);
-+ status = ReadDOC_(docptr, this->ioreg);
-+ }
-
-- if (ReadDOC_(docptr, this->ioreg) & 1) {
-+ if (status & 1) {
- printk(KERN_ERR "Error programming oob data\n");
- /* There was an error */
- *retlen = 0;
-@@ -1080,6 +1224,7 @@
- volatile int dummy;
- unsigned long docptr;
- struct Nand *mychip;
-+ int status;
-
- down(&this->lock);
-
-@@ -1111,10 +1256,16 @@
-
- DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
-
-+ if (DoC_is_Millennium(this)) {
-+ ReadDOC(docptr, ReadPipeInit);
-+ status = ReadDOC(docptr, LastDataRead);
-+ } else {
- dummy = ReadDOC(docptr, CDSNSlowIO);
- DoC_Delay(this, 2);
-+ status = ReadDOC_(docptr, this->ioreg);
-+ }
-
-- if (ReadDOC_(docptr, this->ioreg) & 1) {
-+ if (status & 1) {
- printk(KERN_ERR "Error erasing at 0x%x\n", ofs);
- /* There was an error */
- instr->state = MTD_ERASE_FAILED;
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/devices/doc2001.c linux/drivers/mtd/devices/doc2001.c
---- linux-mips-2.4.24-pre2/drivers/mtd/devices/doc2001.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/devices/doc2001.c 2004-11-17 18:17:58.995320608 +0100
-@@ -4,7 +4,7 @@
- * (c) 1999 Machine Vision Holdings, Inc.
- * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/kernel.h>
-@@ -359,14 +359,15 @@
-
- mtd->type = MTD_NANDFLASH;
- mtd->flags = MTD_CAP_NANDFLASH;
-+ mtd->ecctype = MTD_ECC_RS_DiskOnChip;
- mtd->size = 0;
-
-- /* FIXME: erase size is not always 8kB */
-+ /* FIXME: erase size is not always 8KiB */
- mtd->erasesize = 0x2000;
-
- mtd->oobblock = 512;
- mtd->oobsize = 16;
-- mtd->module = THIS_MODULE;
-+ mtd->owner = THIS_MODULE;
- mtd->erase = doc_erase;
- mtd->point = NULL;
- mtd->unpoint = NULL;
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/devices/doc2001plus.c linux/drivers/mtd/devices/doc2001plus.c
---- linux-mips-2.4.24-pre2/drivers/mtd/devices/doc2001plus.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/devices/doc2001plus.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,1154 @@
-+/*
-+ * Linux driver for Disk-On-Chip Millennium Plus
-+ *
-+ * (c) 2002-2003 Greg Ungerer <gerg@snapgear.com>
-+ * (c) 2002-2003 SnapGear Inc
-+ * (c) 1999 Machine Vision Holdings, Inc.
-+ * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
-+ *
-+ * $Id$
-+ *
-+ * Released under GPL
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <asm/errno.h>
-+#include <asm/io.h>
-+#include <asm/uaccess.h>
-+#include <linux/miscdevice.h>
-+#include <linux/pci.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/doc2000.h>
-+
-+/* #define ECC_DEBUG */
-+
-+/* I have no idea why some DoC chips can not use memcop_form|to_io().
-+ * This may be due to the different revisions of the ASIC controller built-in or
-+ * simplily a QA/Bug issue. Who knows ?? If you have trouble, please uncomment
-+ * this:*/
-+#undef USE_MEMCPY
-+
-+static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t *retlen, u_char *buf);
-+static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf);
-+static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t *retlen, u_char *buf, u_char *eccbuf,
-+ struct nand_oobinfo *oobsel);
-+static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf, u_char *eccbuf,
-+ struct nand_oobinfo *oobsel);
-+static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-+ size_t *retlen, u_char *buf);
-+static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-+ size_t *retlen, const u_char *buf);
-+static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
-+
-+static struct mtd_info *docmilpluslist = NULL;
-+
-+
-+/* Perform the required delay cycles by writing to the NOP register */
-+static void DoC_Delay(unsigned long docptr, int cycles)
-+{
-+ int i;
-+
-+ for (i = 0; (i < cycles); i++)
-+ WriteDOC(0, docptr, Mplus_NOP);
-+}
-+
-+#define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1)
-+
-+/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
-+static int _DoC_WaitReady(unsigned long docptr)
-+{
-+ unsigned int c = 0xffff;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3,
-+ "_DoC_WaitReady called for out-of-line wait\n");
-+
-+ /* Out-of-line routine to wait for chip response */
-+ while (((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) && --c)
-+ ;
-+
-+ if (c == 0)
-+ DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
-+
-+ return (c == 0);
-+}
-+
-+static inline int DoC_WaitReady(unsigned long docptr)
-+{
-+ /* This is inline, to optimise the common case, where it's ready instantly */
-+ int ret = 0;
-+
-+ /* read form NOP register should be issued prior to the read from CDSNControl
-+ see Software Requirement 11.4 item 2. */
-+ DoC_Delay(docptr, 4);
-+
-+ if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK)
-+ /* Call the out-of-line routine to wait */
-+ ret = _DoC_WaitReady(docptr);
-+
-+ return ret;
-+}
-+
-+/* For some reason the Millennium Plus seems to occassionally put itself
-+ * into reset mode. For me this happens randomly, with no pattern that I
-+ * can detect. M-systems suggest always check this on any block level
-+ * operation and setting to normal mode if in reset mode.
-+ */
-+static inline void DoC_CheckASIC(unsigned long docptr)
-+{
-+ /* Make sure the DoC is in normal mode */
-+ if ((ReadDOC(docptr, Mplus_DOCControl) & DOC_MODE_NORMAL) == 0) {
-+ WriteDOC((DOC_MODE_NORMAL | DOC_MODE_MDWREN), docptr, Mplus_DOCControl);
-+ WriteDOC(~(DOC_MODE_NORMAL | DOC_MODE_MDWREN), docptr, Mplus_CtrlConfirm);
-+ }
-+}
-+
-+/* DoC_Command: Send a flash command to the flash chip through the Flash
-+ * command register. Need 2 Write Pipeline Terminates to complete send.
-+ */
-+static inline void DoC_Command(unsigned long docptr, unsigned char command,
-+ unsigned char xtraflags)
-+{
-+ WriteDOC(command, docptr, Mplus_FlashCmd);
-+ WriteDOC(command, docptr, Mplus_WritePipeTerm);
-+ WriteDOC(command, docptr, Mplus_WritePipeTerm);
-+}
-+
-+/* DoC_Address: Set the current address for the flash chip through the Flash
-+ * Address register. Need 2 Write Pipeline Terminates to complete send.
-+ */
-+static inline void DoC_Address(struct DiskOnChip *doc, int numbytes,
-+ unsigned long ofs, unsigned char xtraflags1,
-+ unsigned char xtraflags2)
-+{
-+ unsigned long docptr = doc->virtadr;
-+
-+ /* Allow for possible Mill Plus internal flash interleaving */
-+ ofs >>= doc->interleave;
-+
-+ switch (numbytes) {
-+ case 1:
-+ /* Send single byte, bits 0-7. */
-+ WriteDOC(ofs & 0xff, docptr, Mplus_FlashAddress);
-+ break;
-+ case 2:
-+ /* Send bits 9-16 followed by 17-23 */
-+ WriteDOC((ofs >> 9) & 0xff, docptr, Mplus_FlashAddress);
-+ WriteDOC((ofs >> 17) & 0xff, docptr, Mplus_FlashAddress);
-+ break;
-+ case 3:
-+ /* Send 0-7, 9-16, then 17-23 */
-+ WriteDOC(ofs & 0xff, docptr, Mplus_FlashAddress);
-+ WriteDOC((ofs >> 9) & 0xff, docptr, Mplus_FlashAddress);
-+ WriteDOC((ofs >> 17) & 0xff, docptr, Mplus_FlashAddress);
-+ break;
-+ default:
-+ return;
-+ }
-+
-+ WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-+ WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-+}
-+
-+/* DoC_SelectChip: Select a given flash chip within the current floor */
-+static int DoC_SelectChip(unsigned long docptr, int chip)
-+{
-+ /* No choice for flash chip on Millennium Plus */
-+ return 0;
-+}
-+
-+/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
-+static int DoC_SelectFloor(unsigned long docptr, int floor)
-+{
-+ WriteDOC((floor & 0x3), docptr, Mplus_DeviceSelect);
-+ return 0;
-+}
-+
-+/*
-+ * Translate the given offset into the appropriate command and offset.
-+ * This does the mapping using the 16bit interleave layout defined by
-+ * M-Systems, and looks like this for a sector pair:
-+ * +-----------+-------+-------+-------+--------------+---------+-----------+
-+ * | 0 --- 511 |512-517|518-519|520-521| 522 --- 1033 |1034-1039|1040 - 1055|
-+ * +-----------+-------+-------+-------+--------------+---------+-----------+
-+ * | Data 0 | ECC 0 |Flags0 |Flags1 | Data 1 |ECC 1 | OOB 1 + 2 |
-+ * +-----------+-------+-------+-------+--------------+---------+-----------+
-+ */
-+/* FIXME: This lives in INFTL not here. Other users of flash devices
-+ may not want it */
-+static unsigned int DoC_GetDataOffset(struct mtd_info *mtd, loff_t *from)
-+{
-+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-+
-+ if (this->interleave) {
-+ unsigned int ofs = *from & 0x3ff;
-+ unsigned int cmd;
-+
-+ if (ofs < 512) {
-+ cmd = NAND_CMD_READ0;
-+ ofs &= 0x1ff;
-+ } else if (ofs < 1014) {
-+ cmd = NAND_CMD_READ1;
-+ ofs = (ofs & 0x1ff) + 10;
-+ } else {
-+ cmd = NAND_CMD_READOOB;
-+ ofs = ofs - 1014;
-+ }
-+
-+ *from = (*from & ~0x3ff) | ofs;
-+ return cmd;
-+ } else {
-+ /* No interleave */
-+ if ((*from) & 0x100)
-+ return NAND_CMD_READ1;
-+ return NAND_CMD_READ0;
-+ }
-+}
-+
-+static unsigned int DoC_GetECCOffset(struct mtd_info *mtd, loff_t *from)
-+{
-+ unsigned int ofs, cmd;
-+
-+ if (*from & 0x200) {
-+ cmd = NAND_CMD_READOOB;
-+ ofs = 10 + (*from & 0xf);
-+ } else {
-+ cmd = NAND_CMD_READ1;
-+ ofs = (*from & 0xf);
-+ }
-+
-+ *from = (*from & ~0x3ff) | ofs;
-+ return cmd;
-+}
-+
-+static unsigned int DoC_GetFlagsOffset(struct mtd_info *mtd, loff_t *from)
-+{
-+ unsigned int ofs, cmd;
-+
-+ cmd = NAND_CMD_READ1;
-+ ofs = (*from & 0x200) ? 8 : 6;
-+ *from = (*from & ~0x3ff) | ofs;
-+ return cmd;
-+}
-+
-+static unsigned int DoC_GetHdrOffset(struct mtd_info *mtd, loff_t *from)
-+{
-+ unsigned int ofs, cmd;
-+
-+ cmd = NAND_CMD_READOOB;
-+ ofs = (*from & 0x200) ? 24 : 16;
-+ *from = (*from & ~0x3ff) | ofs;
-+ return cmd;
-+}
-+
-+static inline void MemReadDOC(unsigned long docptr, unsigned char *buf, int len)
-+{
-+#ifndef USE_MEMCPY
-+ int i;
-+ for (i = 0; i < len; i++)
-+ buf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
-+#else
-+ memcpy_fromio(buf, docptr + DoC_Mil_CDSN_IO, len);
-+#endif
-+}
-+
-+static inline void MemWriteDOC(unsigned long docptr, unsigned char *buf, int len)
-+{
-+#ifndef USE_MEMCPY
-+ int i;
-+ for (i = 0; i < len; i++)
-+ WriteDOC(buf[i], docptr, Mil_CDSN_IO + i);
-+#else
-+ memcpy_toio(docptr + DoC_Mil_CDSN_IO, buf, len);
-+#endif
-+}
-+
-+/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
-+static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
-+{
-+ int mfr, id, i, j;
-+ volatile char dummy;
-+ unsigned long docptr = doc->virtadr;
-+
-+ /* Page in the required floor/chip */
-+ DoC_SelectFloor(docptr, floor);
-+ DoC_SelectChip(docptr, chip);
-+
-+ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-+ WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);
-+
-+ /* Reset the chip, see Software Requirement 11.4 item 1. */
-+ DoC_Command(docptr, NAND_CMD_RESET, 0);
-+ DoC_WaitReady(docptr);
-+
-+ /* Read the NAND chip ID: 1. Send ReadID command */
-+ DoC_Command(docptr, NAND_CMD_READID, 0);
-+
-+ /* Read the NAND chip ID: 2. Send address byte zero */
-+ DoC_Address(doc, 1, 0x00, 0, 0x00);
-+
-+ WriteDOC(0, docptr, Mplus_FlashControl);
-+ DoC_WaitReady(docptr);
-+
-+ /* Read the manufacturer and device id codes of the flash device through
-+ CDSN IO register see Software Requirement 11.4 item 5.*/
-+ dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-+ dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-+
-+ mfr = ReadDOC(docptr, Mil_CDSN_IO);
-+ if (doc->interleave)
-+ dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */
-+
-+ id = ReadDOC(docptr, Mil_CDSN_IO);
-+ if (doc->interleave)
-+ dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */
-+
-+ dummy = ReadDOC(docptr, Mplus_LastDataRead);
-+ dummy = ReadDOC(docptr, Mplus_LastDataRead);
-+
-+ /* Disable flash internally */
-+ WriteDOC(0, docptr, Mplus_FlashSelect);
-+
-+ /* No response - return failure */
-+ if (mfr == 0xff || mfr == 0)
-+ return 0;
-+
-+ for (i = 0; nand_flash_ids[i].name != NULL; i++) {
-+ if (id == nand_flash_ids[i].id) {
-+ /* Try to identify manufacturer */
-+ for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
-+ if (nand_manuf_ids[j].id == mfr)
-+ break;
-+ }
-+ printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, "
-+ "Chip ID: %2.2X (%s:%s)\n", mfr, id,
-+ nand_manuf_ids[j].name, nand_flash_ids[i].name);
-+ doc->mfr = mfr;
-+ doc->id = id;
-+ doc->chipshift = nand_flash_ids[i].chipshift;
-+ doc->erasesize = nand_flash_ids[i].erasesize << doc->interleave;
-+ break;
-+ }
-+ }
-+
-+ if (nand_flash_ids[i].name == NULL)
-+ return 0;
-+ return 1;
-+}
-+
-+/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
-+static void DoC_ScanChips(struct DiskOnChip *this)
-+{
-+ int floor, chip;
-+ int numchips[MAX_FLOORS_MPLUS];
-+ int ret;
-+
-+ this->numchips = 0;
-+ this->mfr = 0;
-+ this->id = 0;
-+
-+ /* Work out the intended interleave setting */
-+ this->interleave = 0;
-+ if (this->ChipID == DOC_ChipID_DocMilPlus32)
-+ this->interleave = 1;
-+
-+ /* Check the ASIC agrees */
-+ if ( (this->interleave << 2) !=
-+ (ReadDOC(this->virtadr, Mplus_Configuration) & 4)) {
-+ u_char conf = ReadDOC(this->virtadr, Mplus_Configuration);
-+ printk(KERN_NOTICE "Setting DiskOnChip Millennium Plus interleave to %s\n",
-+ this->interleave?"on (16-bit)":"off (8-bit)");
-+ conf ^= 4;
-+ WriteDOC(this->virtadr, conf, Mplus_Configuration);
-+ }
-+
-+ /* For each floor, find the number of valid chips it contains */
-+ for (floor = 0,ret = 1; floor < MAX_FLOORS_MPLUS; floor++) {
-+ numchips[floor] = 0;
-+ for (chip = 0; chip < MAX_CHIPS_MPLUS && ret != 0; chip++) {
-+ ret = DoC_IdentChip(this, floor, chip);
-+ if (ret) {
-+ numchips[floor]++;
-+ this->numchips++;
-+ }
-+ }
-+ }
-+ /* If there are none at all that we recognise, bail */
-+ if (!this->numchips) {
-+ printk("No flash chips recognised.\n");
-+ return;
-+ }
-+
-+ /* Allocate an array to hold the information for each chip */
-+ this->chips = kmalloc(sizeof(struct Nand) * this->numchips, GFP_KERNEL);
-+ if (!this->chips){
-+ printk("MTD: No memory for allocating chip info structures\n");
-+ return;
-+ }
-+
-+ /* Fill out the chip array with {floor, chipno} for each
-+ * detected chip in the device. */
-+ for (floor = 0, ret = 0; floor < MAX_FLOORS_MPLUS; floor++) {
-+ for (chip = 0 ; chip < numchips[floor] ; chip++) {
-+ this->chips[ret].floor = floor;
-+ this->chips[ret].chip = chip;
-+ this->chips[ret].curadr = 0;
-+ this->chips[ret].curmode = 0x50;
-+ ret++;
-+ }
-+ }
-+
-+ /* Calculate and print the total size of the device */
-+ this->totlen = this->numchips * (1 << this->chipshift);
-+ printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld MiB\n",
-+ this->numchips ,this->totlen >> 20);
-+}
-+
-+static int DoCMilPlus_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
-+{
-+ int tmp1, tmp2, retval;
-+
-+ if (doc1->physadr == doc2->physadr)
-+ return 1;
-+
-+ /* Use the alias resolution register which was set aside for this
-+ * purpose. If it's value is the same on both chips, they might
-+ * be the same chip, and we write to one and check for a change in
-+ * the other. It's unclear if this register is usuable in the
-+ * DoC 2000 (it's in the Millennium docs), but it seems to work. */
-+ tmp1 = ReadDOC(doc1->virtadr, Mplus_AliasResolution);
-+ tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
-+ if (tmp1 != tmp2)
-+ return 0;
-+
-+ WriteDOC((tmp1+1) % 0xff, doc1->virtadr, Mplus_AliasResolution);
-+ tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
-+ if (tmp2 == (tmp1+1) % 0xff)
-+ retval = 1;
-+ else
-+ retval = 0;
-+
-+ /* Restore register contents. May not be necessary, but do it just to
-+ * be safe. */
-+ WriteDOC(tmp1, doc1->virtadr, Mplus_AliasResolution);
-+
-+ return retval;
-+}
-+
-+static const char im_name[] = "DoCMilPlus_init";
-+
-+/* This routine is made available to other mtd code via
-+ * inter_module_register. It must only be accessed through
-+ * inter_module_get which will bump the use count of this module. The
-+ * addresses passed back in mtd are valid as long as the use count of
-+ * this module is non-zero, i.e. between inter_module_get and
-+ * inter_module_put. Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
-+ */
-+static void DoCMilPlus_init(struct mtd_info *mtd)
-+{
-+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-+ struct DiskOnChip *old = NULL;
-+
-+ /* We must avoid being called twice for the same device. */
-+ if (docmilpluslist)
-+ old = (struct DiskOnChip *)docmilpluslist->priv;
-+
-+ while (old) {
-+ if (DoCMilPlus_is_alias(this, old)) {
-+ printk(KERN_NOTICE "Ignoring DiskOnChip Millennium "
-+ "Plus at 0x%lX - already configured\n",
-+ this->physadr);
-+ iounmap((void *)this->virtadr);
-+ kfree(mtd);
-+ return;
-+ }
-+ if (old->nextdoc)
-+ old = (struct DiskOnChip *)old->nextdoc->priv;
-+ else
-+ old = NULL;
-+ }
-+
-+ mtd->name = "DiskOnChip Millennium Plus";
-+ printk(KERN_NOTICE "DiskOnChip Millennium Plus found at "
-+ "address 0x%lX\n", this->physadr);
-+
-+ mtd->type = MTD_NANDFLASH;
-+ mtd->flags = MTD_CAP_NANDFLASH;
-+ mtd->ecctype = MTD_ECC_RS_DiskOnChip;
-+ mtd->size = 0;
-+
-+ mtd->erasesize = 0;
-+ mtd->oobblock = 512;
-+ mtd->oobsize = 16;
-+ mtd->owner = THIS_MODULE;
-+ mtd->erase = doc_erase;
-+ mtd->point = NULL;
-+ mtd->unpoint = NULL;
-+ mtd->read = doc_read;
-+ mtd->write = doc_write;
-+ mtd->read_ecc = doc_read_ecc;
-+ mtd->write_ecc = doc_write_ecc;
-+ mtd->read_oob = doc_read_oob;
-+ mtd->write_oob = doc_write_oob;
-+ mtd->sync = NULL;
-+
-+ this->totlen = 0;
-+ this->numchips = 0;
-+ this->curfloor = -1;
-+ this->curchip = -1;
-+
-+ /* Ident all the chips present. */
-+ DoC_ScanChips(this);
-+
-+ if (!this->totlen) {
-+ kfree(mtd);
-+ iounmap((void *)this->virtadr);
-+ } else {
-+ this->nextdoc = docmilpluslist;
-+ docmilpluslist = mtd;
-+ mtd->size = this->totlen;
-+ mtd->erasesize = this->erasesize;
-+ add_mtd_device(mtd);
-+ return;
-+ }
-+}
-+
-+#if 0
-+static int doc_dumpblk(struct mtd_info *mtd, loff_t from)
-+{
-+ int i;
-+ loff_t fofs;
-+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-+ unsigned long docptr = this->virtadr;
-+ struct Nand *mychip = &this->chips[from >> (this->chipshift)];
-+ unsigned char *bp, buf[1056];
-+ char c[32];
-+
-+ from &= ~0x3ff;
-+
-+ /* Don't allow read past end of device */
-+ if (from >= this->totlen)
-+ return -EINVAL;
-+
-+ DoC_CheckASIC(docptr);
-+
-+ /* Find the chip which is to be used and select it */
-+ if (this->curfloor != mychip->floor) {
-+ DoC_SelectFloor(docptr, mychip->floor);
-+ DoC_SelectChip(docptr, mychip->chip);
-+ } else if (this->curchip != mychip->chip) {
-+ DoC_SelectChip(docptr, mychip->chip);
-+ }
-+ this->curfloor = mychip->floor;
-+ this->curchip = mychip->chip;
-+
-+ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-+ WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);
-+
-+ /* Reset the chip, see Software Requirement 11.4 item 1. */
-+ DoC_Command(docptr, NAND_CMD_RESET, 0);
-+ DoC_WaitReady(docptr);
-+
-+ fofs = from;
-+ DoC_Command(docptr, DoC_GetDataOffset(mtd, &fofs), 0);
-+ DoC_Address(this, 3, fofs, 0, 0x00);
-+ WriteDOC(0, docptr, Mplus_FlashControl);
-+ DoC_WaitReady(docptr);
-+
-+ /* disable the ECC engine */
-+ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-+
-+ ReadDOC(docptr, Mplus_ReadPipeInit);
-+ ReadDOC(docptr, Mplus_ReadPipeInit);
-+
-+ /* Read the data via the internal pipeline through CDSN IO
-+ register, see Pipelined Read Operations 11.3 */
-+ MemReadDOC(docptr, buf, 1054);
-+ buf[1054] = ReadDOC(docptr, Mplus_LastDataRead);
-+ buf[1055] = ReadDOC(docptr, Mplus_LastDataRead);
-+
-+ memset(&c[0], 0, sizeof(c));
-+ printk("DUMP OFFSET=%x:\n", (int)from);
-+
-+ for (i = 0, bp = &buf[0]; (i < 1056); i++) {
-+ if ((i % 16) == 0)
-+ printk("%08x: ", i);
-+ printk(" %02x", *bp);
-+ c[(i & 0xf)] = ((*bp >= 0x20) && (*bp <= 0x7f)) ? *bp : '.';
-+ bp++;
-+ if (((i + 1) % 16) == 0)
-+ printk(" %s\n", c);
-+ }
-+ printk("\n");
-+
-+ /* Disable flash internally */
-+ WriteDOC(0, docptr, Mplus_FlashSelect);
-+
-+ return 0;
-+}
-+#endif
-+
-+static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t *retlen, u_char *buf)
-+{
-+ /* Just a special case of doc_read_ecc */
-+ return doc_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
-+}
-+
-+static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t *retlen, u_char *buf, u_char *eccbuf,
-+ struct nand_oobinfo *oobsel)
-+{
-+ int ret, i;
-+ volatile char dummy;
-+ loff_t fofs;
-+ unsigned char syndrome[6];
-+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-+ unsigned long docptr = this->virtadr;
-+ struct Nand *mychip = &this->chips[from >> (this->chipshift)];
-+
-+ /* Don't allow read past end of device */
-+ if (from >= this->totlen)
-+ return -EINVAL;
-+
-+ /* Don't allow a single read to cross a 512-byte block boundary */
-+ if (from + len > ((from | 0x1ff) + 1))
-+ len = ((from | 0x1ff) + 1) - from;
-+
-+ DoC_CheckASIC(docptr);
-+
-+ /* Find the chip which is to be used and select it */
-+ if (this->curfloor != mychip->floor) {
-+ DoC_SelectFloor(docptr, mychip->floor);
-+ DoC_SelectChip(docptr, mychip->chip);
-+ } else if (this->curchip != mychip->chip) {
-+ DoC_SelectChip(docptr, mychip->chip);
-+ }
-+ this->curfloor = mychip->floor;
-+ this->curchip = mychip->chip;
-+
-+ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-+ WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);
-+
-+ /* Reset the chip, see Software Requirement 11.4 item 1. */
-+ DoC_Command(docptr, NAND_CMD_RESET, 0);
-+ DoC_WaitReady(docptr);
-+
-+ fofs = from;
-+ DoC_Command(docptr, DoC_GetDataOffset(mtd, &fofs), 0);
-+ DoC_Address(this, 3, fofs, 0, 0x00);
-+ WriteDOC(0, docptr, Mplus_FlashControl);
-+ DoC_WaitReady(docptr);
-+
-+ if (eccbuf) {
-+ /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
-+ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-+ WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);
-+ } else {
-+ /* disable the ECC engine */
-+ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-+ }
-+
-+ /* Let the caller know we completed it */
-+ *retlen = len;
-+ ret = 0;
-+
-+ ReadDOC(docptr, Mplus_ReadPipeInit);
-+ ReadDOC(docptr, Mplus_ReadPipeInit);
-+
-+ if (eccbuf) {
-+ /* Read the data via the internal pipeline through CDSN IO
-+ register, see Pipelined Read Operations 11.3 */
-+ MemReadDOC(docptr, buf, len);
-+
-+ /* Read the ECC data following raw data */
-+ MemReadDOC(docptr, eccbuf, 4);
-+ eccbuf[4] = ReadDOC(docptr, Mplus_LastDataRead);
-+ eccbuf[5] = ReadDOC(docptr, Mplus_LastDataRead);
-+
-+ /* Flush the pipeline */
-+ dummy = ReadDOC(docptr, Mplus_ECCConf);
-+ dummy = ReadDOC(docptr, Mplus_ECCConf);
-+
-+ /* Check the ECC Status */
-+ if (ReadDOC(docptr, Mplus_ECCConf) & 0x80) {
-+ int nb_errors;
-+ /* There was an ECC error */
-+#ifdef ECC_DEBUG
-+ printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
-+#endif
-+ /* Read the ECC syndrom through the DiskOnChip ECC logic.
-+ These syndrome will be all ZERO when there is no error */
-+ for (i = 0; i < 6; i++)
-+ syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
-+
-+ nb_errors = doc_decode_ecc(buf, syndrome);
-+#ifdef ECC_DEBUG
-+ printk("ECC Errors corrected: %x\n", nb_errors);
-+#endif
-+ if (nb_errors < 0) {
-+ /* We return error, but have actually done the read. Not that
-+ this can be told to user-space, via sys_read(), but at least
-+ MTD-aware stuff can know about it by checking *retlen */
-+#ifdef ECC_DEBUG
-+ printk("%s(%d): Millennium Plus ECC error (from=0x%x:\n",
-+ __FILE__, __LINE__, (int)from);
-+ printk(" syndrome= %02x:%02x:%02x:%02x:%02x:"
-+ "%02x\n",
-+ syndrome[0], syndrome[1], syndrome[2],
-+ syndrome[3], syndrome[4], syndrome[5]);
-+ printk(" eccbuf= %02x:%02x:%02x:%02x:%02x:"
-+ "%02x\n",
-+ eccbuf[0], eccbuf[1], eccbuf[2],
-+ eccbuf[3], eccbuf[4], eccbuf[5]);
-+#endif
-+ ret = -EIO;
-+ }
-+ }
-+
-+#ifdef PSYCHO_DEBUG
-+ printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
-+ (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
-+ eccbuf[4], eccbuf[5]);
-+#endif
-+
-+ /* disable the ECC engine */
-+ WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf);
-+ } else {
-+ /* Read the data via the internal pipeline through CDSN IO
-+ register, see Pipelined Read Operations 11.3 */
-+ MemReadDOC(docptr, buf, len-2);
-+ buf[len-2] = ReadDOC(docptr, Mplus_LastDataRead);
-+ buf[len-1] = ReadDOC(docptr, Mplus_LastDataRead);
-+ }
-+
-+ /* Disable flash internally */
-+ WriteDOC(0, docptr, Mplus_FlashSelect);
-+
-+ return ret;
-+}
-+
-+static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf)
-+{
-+ char eccbuf[6];
-+ return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, NULL);
-+}
-+
-+static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf, u_char *eccbuf,
-+ struct nand_oobinfo *oobsel)
-+{
-+ int i, before, ret = 0;
-+ loff_t fto;
-+ volatile char dummy;
-+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-+ unsigned long docptr = this->virtadr;
-+ struct Nand *mychip = &this->chips[to >> (this->chipshift)];
-+
-+ /* Don't allow write past end of device */
-+ if (to >= this->totlen)
-+ return -EINVAL;
-+
-+ /* Don't allow writes which aren't exactly one block (512 bytes) */
-+ if ((to & 0x1ff) || (len != 0x200))
-+ return -EINVAL;
-+
-+ /* Determine position of OOB flags, before or after data */
-+ before = (this->interleave && (to & 0x200));
-+
-+ DoC_CheckASIC(docptr);
-+
-+ /* Find the chip which is to be used and select it */
-+ if (this->curfloor != mychip->floor) {
-+ DoC_SelectFloor(docptr, mychip->floor);
-+ DoC_SelectChip(docptr, mychip->chip);
-+ } else if (this->curchip != mychip->chip) {
-+ DoC_SelectChip(docptr, mychip->chip);
-+ }
-+ this->curfloor = mychip->floor;
-+ this->curchip = mychip->chip;
-+
-+ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-+ WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);
-+
-+ /* Reset the chip, see Software Requirement 11.4 item 1. */
-+ DoC_Command(docptr, NAND_CMD_RESET, 0);
-+ DoC_WaitReady(docptr);
-+
-+ /* Set device to appropriate plane of flash */
-+ fto = to;
-+ WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd);
-+
-+ /* On interleaved devices the flags for 2nd half 512 are before data */
-+ if (eccbuf && before)
-+ fto -= 2;
-+
-+ /* issue the Serial Data In command to initial the Page Program process */
-+ DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
-+ DoC_Address(this, 3, fto, 0x00, 0x00);
-+
-+ /* Disable the ECC engine */
-+ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-+
-+ if (eccbuf) {
-+ if (before) {
-+ /* Write the block status BLOCK_USED (0x5555) */
-+ WriteDOC(0x55, docptr, Mil_CDSN_IO);
-+ WriteDOC(0x55, docptr, Mil_CDSN_IO);
-+ }
-+
-+ /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
-+ WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf);
-+ }
-+
-+ MemWriteDOC(docptr, (unsigned char *) buf, len);
-+
-+ if (eccbuf) {
-+ /* Write ECC data to flash, the ECC info is generated by
-+ the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */
-+ DoC_Delay(docptr, 3);
-+
-+ /* Read the ECC data through the DiskOnChip ECC logic */
-+ for (i = 0; i < 6; i++)
-+ eccbuf[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
-+
-+ /* disable the ECC engine */
-+ WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
-+
-+ /* Write the ECC data to flash */
-+ MemWriteDOC(docptr, eccbuf, 6);
-+
-+ if (!before) {
-+ /* Write the block status BLOCK_USED (0x5555) */
-+ WriteDOC(0x55, docptr, Mil_CDSN_IO+6);
-+ WriteDOC(0x55, docptr, Mil_CDSN_IO+7);
-+ }
-+
-+#ifdef PSYCHO_DEBUG
-+ printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
-+ (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
-+ eccbuf[4], eccbuf[5]);
-+#endif
-+ }
-+
-+ WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-+ WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-+
-+ /* Commit the Page Program command and wait for ready
-+ see Software Requirement 11.4 item 1.*/
-+ DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
-+ DoC_WaitReady(docptr);
-+
-+ /* Read the status of the flash device through CDSN IO register
-+ see Software Requirement 11.4 item 5.*/
-+ DoC_Command(docptr, NAND_CMD_STATUS, 0);
-+ dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-+ dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-+ DoC_Delay(docptr, 2);
-+ if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
-+ printk("MTD: Error 0x%x programming at 0x%x\n", dummy, (int)to);
-+ /* Error in programming
-+ FIXME: implement Bad Block Replacement (in nftl.c ??) */
-+ *retlen = 0;
-+ ret = -EIO;
-+ }
-+ dummy = ReadDOC(docptr, Mplus_LastDataRead);
-+
-+ /* Disable flash internally */
-+ WriteDOC(0, docptr, Mplus_FlashSelect);
-+
-+ /* Let the caller know we completed it */
-+ *retlen = len;
-+
-+ return ret;
-+}
-+
-+static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-+ size_t *retlen, u_char *buf)
-+{
-+ loff_t fofs, base;
-+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-+ unsigned long docptr = this->virtadr;
-+ struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-+ size_t i, size, got, want;
-+
-+ DoC_CheckASIC(docptr);
-+
-+ /* Find the chip which is to be used and select it */
-+ if (this->curfloor != mychip->floor) {
-+ DoC_SelectFloor(docptr, mychip->floor);
-+ DoC_SelectChip(docptr, mychip->chip);
-+ } else if (this->curchip != mychip->chip) {
-+ DoC_SelectChip(docptr, mychip->chip);
-+ }
-+ this->curfloor = mychip->floor;
-+ this->curchip = mychip->chip;
-+
-+ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-+ WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);
-+
-+ /* disable the ECC engine */
-+ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-+ DoC_WaitReady(docptr);
-+
-+ /* Maximum of 16 bytes in the OOB region, so limit read to that */
-+ if (len > 16)
-+ len = 16;
-+ got = 0;
-+ want = len;
-+
-+ for (i = 0; ((i < 3) && (want > 0)); i++) {
-+ /* Figure out which region we are accessing... */
-+ fofs = ofs;
-+ base = ofs & 0xf;
-+ if (!this->interleave) {
-+ DoC_Command(docptr, NAND_CMD_READOOB, 0);
-+ size = 16 - base;
-+ } else if (base < 6) {
-+ DoC_Command(docptr, DoC_GetECCOffset(mtd, &fofs), 0);
-+ size = 6 - base;
-+ } else if (base < 8) {
-+ DoC_Command(docptr, DoC_GetFlagsOffset(mtd, &fofs), 0);
-+ size = 8 - base;
-+ } else {
-+ DoC_Command(docptr, DoC_GetHdrOffset(mtd, &fofs), 0);
-+ size = 16 - base;
-+ }
-+ if (size > want)
-+ size = want;
-+
-+ /* Issue read command */
-+ DoC_Address(this, 3, fofs, 0, 0x00);
-+ WriteDOC(0, docptr, Mplus_FlashControl);
-+ DoC_WaitReady(docptr);
-+
-+ ReadDOC(docptr, Mplus_ReadPipeInit);
-+ ReadDOC(docptr, Mplus_ReadPipeInit);
-+ MemReadDOC(docptr, &buf[got], size - 2);
-+ buf[got + size - 2] = ReadDOC(docptr, Mplus_LastDataRead);
-+ buf[got + size - 1] = ReadDOC(docptr, Mplus_LastDataRead);
-+
-+ ofs += size;
-+ got += size;
-+ want -= size;
-+ }
-+
-+ /* Disable flash internally */
-+ WriteDOC(0, docptr, Mplus_FlashSelect);
-+
-+ *retlen = len;
-+ return 0;
-+}
-+
-+static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-+ size_t *retlen, const u_char *buf)
-+{
-+ volatile char dummy;
-+ loff_t fofs, base;
-+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-+ unsigned long docptr = this->virtadr;
-+ struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-+ size_t i, size, got, want;
-+ int ret = 0;
-+
-+ DoC_CheckASIC(docptr);
-+
-+ /* Find the chip which is to be used and select it */
-+ if (this->curfloor != mychip->floor) {
-+ DoC_SelectFloor(docptr, mychip->floor);
-+ DoC_SelectChip(docptr, mychip->chip);
-+ } else if (this->curchip != mychip->chip) {
-+ DoC_SelectChip(docptr, mychip->chip);
-+ }
-+ this->curfloor = mychip->floor;
-+ this->curchip = mychip->chip;
-+
-+ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-+ WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);
-+
-+
-+ /* Maximum of 16 bytes in the OOB region, so limit write to that */
-+ if (len > 16)
-+ len = 16;
-+ got = 0;
-+ want = len;
-+
-+ for (i = 0; ((i < 3) && (want > 0)); i++) {
-+ /* Reset the chip, see Software Requirement 11.4 item 1. */
-+ DoC_Command(docptr, NAND_CMD_RESET, 0);
-+ DoC_WaitReady(docptr);
-+
-+ /* Figure out which region we are accessing... */
-+ fofs = ofs;
-+ base = ofs & 0x0f;
-+ if (!this->interleave) {
-+ WriteDOC(NAND_CMD_READOOB, docptr, Mplus_FlashCmd);
-+ size = 16 - base;
-+ } else if (base < 6) {
-+ WriteDOC(DoC_GetECCOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
-+ size = 6 - base;
-+ } else if (base < 8) {
-+ WriteDOC(DoC_GetFlagsOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
-+ size = 8 - base;
-+ } else {
-+ WriteDOC(DoC_GetHdrOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
-+ size = 16 - base;
-+ }
-+ if (size > want)
-+ size = want;
-+
-+ /* Issue the Serial Data In command to initial the Page Program process */
-+ DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
-+ DoC_Address(this, 3, fofs, 0, 0x00);
-+
-+ /* Disable the ECC engine */
-+ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-+
-+ /* Write the data via the internal pipeline through CDSN IO
-+ register, see Pipelined Write Operations 11.2 */
-+ MemWriteDOC(docptr, (unsigned char *) &buf[got], size);
-+ WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-+ WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-+
-+ /* Commit the Page Program command and wait for ready
-+ see Software Requirement 11.4 item 1.*/
-+ DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
-+ DoC_WaitReady(docptr);
-+
-+ /* Read the status of the flash device through CDSN IO register
-+ see Software Requirement 11.4 item 5.*/
-+ DoC_Command(docptr, NAND_CMD_STATUS, 0x00);
-+ dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-+ dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-+ DoC_Delay(docptr, 2);
-+ if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
-+ printk("MTD: Error 0x%x programming oob at 0x%x\n",
-+ dummy, (int)ofs);
-+ /* FIXME: implement Bad Block Replacement */
-+ *retlen = 0;
-+ ret = -EIO;
-+ }
-+ dummy = ReadDOC(docptr, Mplus_LastDataRead);
-+
-+ ofs += size;
-+ got += size;
-+ want -= size;
-+ }
-+
-+ /* Disable flash internally */
-+ WriteDOC(0, docptr, Mplus_FlashSelect);
-+
-+ *retlen = len;
-+ return ret;
-+}
-+
-+int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
-+{
-+ volatile char dummy;
-+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-+ __u32 ofs = instr->addr;
-+ __u32 len = instr->len;
-+ unsigned long docptr = this->virtadr;
-+ struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-+
-+ DoC_CheckASIC(docptr);
-+
-+ if (len != mtd->erasesize)
-+ printk(KERN_WARNING "MTD: Erase not right size (%x != %x)n",
-+ len, mtd->erasesize);
-+
-+ /* Find the chip which is to be used and select it */
-+ if (this->curfloor != mychip->floor) {
-+ DoC_SelectFloor(docptr, mychip->floor);
-+ DoC_SelectChip(docptr, mychip->chip);
-+ } else if (this->curchip != mychip->chip) {
-+ DoC_SelectChip(docptr, mychip->chip);
-+ }
-+ this->curfloor = mychip->floor;
-+ this->curchip = mychip->chip;
-+
-+ instr->state = MTD_ERASE_PENDING;
-+
-+ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-+ WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);
-+
-+ DoC_Command(docptr, NAND_CMD_RESET, 0x00);
-+ DoC_WaitReady(docptr);
-+
-+ DoC_Command(docptr, NAND_CMD_ERASE1, 0);
-+ DoC_Address(this, 2, ofs, 0, 0x00);
-+ DoC_Command(docptr, NAND_CMD_ERASE2, 0);
-+ DoC_WaitReady(docptr);
-+ instr->state = MTD_ERASING;
-+
-+ /* Read the status of the flash device through CDSN IO register
-+ see Software Requirement 11.4 item 5. */
-+ DoC_Command(docptr, NAND_CMD_STATUS, 0);
-+ dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-+ dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-+ if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
-+ printk("MTD: Error 0x%x erasing at 0x%x\n", dummy, ofs);
-+ /* FIXME: implement Bad Block Replacement (in nftl.c ??) */
-+ instr->state = MTD_ERASE_FAILED;
-+ } else {
-+ instr->state = MTD_ERASE_DONE;
-+ }
-+ dummy = ReadDOC(docptr, Mplus_LastDataRead);
-+
-+ /* Disable flash internally */
-+ WriteDOC(0, docptr, Mplus_FlashSelect);
-+
-+ if (instr->callback)
-+ instr->callback(instr);
-+
-+ return 0;
-+}
-+
-+/****************************************************************************
-+ *
-+ * Module stuff
-+ *
-+ ****************************************************************************/
-+
-+int __init init_doc2001plus(void)
-+{
-+ inter_module_register(im_name, THIS_MODULE, &DoCMilPlus_init);
-+ return 0;
-+}
-+
-+static void __exit cleanup_doc2001plus(void)
-+{
-+ struct mtd_info *mtd;
-+ struct DiskOnChip *this;
-+
-+ while ((mtd=docmilpluslist)) {
-+ this = (struct DiskOnChip *)mtd->priv;
-+ docmilpluslist = this->nextdoc;
-+
-+ del_mtd_device(mtd);
-+
-+ iounmap((void *)this->virtadr);
-+ kfree(this->chips);
-+ kfree(mtd);
-+ }
-+ inter_module_unregister(im_name);
-+}
-+
-+module_exit(cleanup_doc2001plus);
-+module_init(init_doc2001plus);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com> et al.");
-+MODULE_DESCRIPTION("Driver for DiskOnChip Millennium Plus");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/devices/docecc.c linux/drivers/mtd/devices/docecc.c
---- linux-mips-2.4.24-pre2/drivers/mtd/devices/docecc.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/devices/docecc.c 2004-11-17 18:17:59.019316960 +0100
-@@ -7,7 +7,7 @@
- * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
- * Copyright (C) 2000 Netgem S.A.
- *
-- * $Id$
-+ * $Id$
- *
- * 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
-@@ -519,6 +519,8 @@
- return nb_errors;
- }
-
-+EXPORT_SYMBOL_GPL(doc_decode_ecc);
-+
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Fabrice Bellard <fabrice.bellard@netgem.com>");
- MODULE_DESCRIPTION("ECC code for correcting errors detected by DiskOnChip 2000 and Millennium ECC hardware");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/devices/docprobe.c linux/drivers/mtd/devices/docprobe.c
---- linux-mips-2.4.24-pre2/drivers/mtd/devices/docprobe.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/devices/docprobe.c 2004-11-17 18:17:59.020316808 +0100
-@@ -4,7 +4,7 @@
- /* (C) 1999 Machine Vision Holdings, Inc. */
- /* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> */
-
--/* $Id$ */
-+/* $Id$ */
-
-
-
-@@ -31,14 +31,12 @@
- /* DOC_SINGLE_DRIVER:
- Millennium driver has been merged into DOC2000 driver.
-
-- The newly-merged driver doesn't appear to work for writing. It's the
-- same with the DiskOnChip 2000 and the Millennium. If you have a
-- Millennium and you want write support to work, remove the definition
-- of DOC_SINGLE_DRIVER below to use the old doc2001-specific driver.
--
-- Otherwise, it's left on in the hope that it'll annoy someone with
-- a Millennium enough that they go through and work out what the
-- difference is :)
-+ The old Millennium-only driver has been retained just in case there
-+ are problems with the new code. If the combined driver doesn't work
-+ for you, you can try the old one by undefining DOC_SINGLE_DRIVER
-+ below and also enabling it in your configuration. If this fixes the
-+ problems, please send a report to the MTD mailing list at
-+ <linux-mtd@lists.infradead.org>.
- */
- #define DOC_SINGLE_DRIVER
-
-@@ -47,18 +45,15 @@
- #include <linux/module.h>
- #include <asm/errno.h>
- #include <asm/io.h>
--#include <asm/uaccess.h>
--#include <linux/miscdevice.h>
--#include <linux/pci.h>
- #include <linux/delay.h>
- #include <linux/slab.h>
--#include <linux/sched.h>
- #include <linux/init.h>
- #include <linux/types.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/nand.h>
- #include <linux/mtd/doc2000.h>
-+#include <linux/mtd/compatmac.h>
-
- /* Where to look for the devices? */
- #ifndef CONFIG_MTD_DOCPROBE_ADDRESS
-@@ -92,17 +87,17 @@
- 0xff000000,
- #elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C)
- 0xff000000,
--#else
-+##else
- #warning Unknown architecture for DiskOnChip. No default probe locations defined
- #endif
-- 0 };
-+ 0xffffffff };
-
- /* doccheck: Probe a given memory window to see if there's a DiskOnChip present */
-
- static inline int __init doccheck(unsigned long potential, unsigned long physadr)
- {
- unsigned long window=potential;
-- unsigned char tmp, ChipID;
-+ unsigned char tmp, tmpb, tmpc, ChipID;
- #ifndef DOC_PASSIVE_PROBE
- unsigned char tmp2;
- #endif
-@@ -140,26 +135,80 @@
- window, DOCControl);
- #endif /* !DOC_PASSIVE_PROBE */
-
-+ /* We need to read the ChipID register four times. For some
-+ newer DiskOnChip 2000 units, the first three reads will
-+ return the DiskOnChip Millennium ident. Don't ask. */
- ChipID = ReadDOC(window, ChipID);
-
- switch (ChipID) {
- case DOC_ChipID_Doc2k:
- /* Check the TOGGLE bit in the ECC register */
- tmp = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
-- if ((ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT) != tmp)
-+ tmpb = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
-+ tmpc = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
-+ if (tmp != tmpb && tmp == tmpc)
- return ChipID;
- break;
-
- case DOC_ChipID_DocMil:
-+ /* Check for the new 2000 with Millennium ASIC */
-+ ReadDOC(window, ChipID);
-+ ReadDOC(window, ChipID);
-+ if (ReadDOC(window, ChipID) != DOC_ChipID_DocMil)
-+ ChipID = DOC_ChipID_Doc2kTSOP;
-+
- /* Check the TOGGLE bit in the ECC register */
- tmp = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
-- if ((ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT) != tmp)
-+ tmpb = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
-+ tmpc = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
-+ if (tmp != tmpb && tmp == tmpc)
-+ return ChipID;
-+ break;
-+
-+ case DOC_ChipID_DocMilPlus16:
-+ case DOC_ChipID_DocMilPlus32:
-+ case 0:
-+ /* Possible Millennium+, need to do more checks */
-+#ifndef DOC_PASSIVE_PROBE
-+ /* Possibly release from power down mode */
-+ for (tmp = 0; (tmp < 4); tmp++)
-+ ReadDOC(window, Mplus_Power);
-+
-+ /* Reset the DiskOnChip ASIC */
-+ tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
-+ DOC_MODE_BDECT;
-+ WriteDOC(tmp, window, Mplus_DOCControl);
-+ WriteDOC(~tmp, window, Mplus_CtrlConfirm);
-+
-+ mdelay(1);
-+ /* Enable the DiskOnChip ASIC */
-+ tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
-+ DOC_MODE_BDECT;
-+ WriteDOC(tmp, window, Mplus_DOCControl);
-+ WriteDOC(~tmp, window, Mplus_CtrlConfirm);
-+ mdelay(1);
-+#endif /* !DOC_PASSIVE_PROBE */
-+
-+ ChipID = ReadDOC(window, ChipID);
-+
-+ switch (ChipID) {
-+ case DOC_ChipID_DocMilPlus16:
-+ case DOC_ChipID_DocMilPlus32:
-+ /* Check the TOGGLE bit in the toggle register */
-+ tmp = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT;
-+ tmpb = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT;
-+ tmpc = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT;
-+ if (tmp != tmpb && tmp == tmpc)
- return ChipID;
-+ default:
- break;
-+ }
-+ /* FALL TRHU */
-
- default:
--#ifndef CONFIG_MTD_DOCPROBE_55AA
-- printk(KERN_WARNING "Possible DiskOnChip with unknown ChipID %2.2X found at 0x%lx\n",
-+
-+#ifdef CONFIG_MTD_DOCPROBE_55AA
-+ printk(KERN_DEBUG "Possible DiskOnChip with unknown ChipID %2.2X found at 0x%lx\n",
- ChipID, physadr);
- #endif
- #ifndef DOC_PASSIVE_PROBE
-@@ -200,6 +249,12 @@
- return;
-
- if ((ChipID = doccheck(docptr, physadr))) {
-+ if (ChipID == DOC_ChipID_Doc2kTSOP) {
-+ /* Remove this at your own peril. The hardware driver works but nothing prevents you from erasing bad blocks */
-+ printk(KERN_NOTICE "Refusing to drive DiskOnChip 2000 TSOP until Bad Block Table is correctly supported by INFTL\n");
-+ iounmap((void *)docptr);
-+ return;
-+ }
- docfound = 1;
- mtd = kmalloc(sizeof(struct DiskOnChip) + sizeof(struct mtd_info), GFP_KERNEL);
-
-@@ -221,6 +276,12 @@
- sprintf(namebuf, "with ChipID %2.2X", ChipID);
-
- switch(ChipID) {
-+ case DOC_ChipID_Doc2kTSOP:
-+ name="2000 TSOP";
-+ im_funcname = "DoC2k_init";
-+ im_modname = "doc2000";
-+ break;
-+
- case DOC_ChipID_Doc2k:
- name="2000";
- im_funcname = "DoC2k_init";
-@@ -237,6 +298,13 @@
- im_modname = "doc2001";
- #endif /* DOC_SINGLE_DRIVER */
- break;
-+
-+ case DOC_ChipID_DocMilPlus16:
-+ case DOC_ChipID_DocMilPlus32:
-+ name="MillenniumPlus";
-+ im_funcname = "DoCMilPlus_init";
-+ im_modname = "doc2001plus";
-+ break;
- }
-
- if (im_funcname)
-@@ -248,6 +316,7 @@
- return;
- }
- printk(KERN_NOTICE "Cannot find driver for DiskOnChip %s at 0x%lX\n", name, physadr);
-+ kfree(mtd);
- }
- iounmap((void *)docptr);
- }
-@@ -267,7 +336,7 @@
- printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location);
- DoC_Probe(doc_config_location);
- } else {
-- for (i=0; doc_locations[i]; i++) {
-+ for (i=0; (doc_locations[i] != 0xffffffff); i++) {
- DoC_Probe(doc_locations[i]);
- }
- }
-@@ -275,11 +344,7 @@
- found, so the user knows we at least tried. */
- if (!docfound)
- printk(KERN_INFO "No recognised DiskOnChip devices found\n");
-- /* So it looks like we've been used and we get unloaded */
-- MOD_INC_USE_COUNT;
-- MOD_DEC_USE_COUNT;
-- return 0;
--
-+ return -EAGAIN;
- }
-
- module_init(init_doc);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/devices/lart.c linux/drivers/mtd/devices/lart.c
---- linux-mips-2.4.24-pre2/drivers/mtd/devices/lart.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/devices/lart.c 2004-11-17 18:17:59.022316504 +0100
-@@ -2,7 +2,7 @@
- /*
- * MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART.
- *
-- * $Id$
-+ * $Id$
- *
- * Author: Abraham vd Merwe <abraham@2d3d.co.za>
- *
-@@ -584,45 +584,40 @@
-
- static struct mtd_info mtd;
-
--static struct mtd_erase_region_info erase_regions[] =
--{
-+static struct mtd_erase_region_info erase_regions[] = {
- /* parameter blocks */
- {
-- offset: 0x00000000,
-- erasesize: FLASH_BLOCKSIZE_PARAM,
-- numblocks: FLASH_NUMBLOCKS_16m_PARAM
-+ .offset = 0x00000000,
-+ .erasesize = FLASH_BLOCKSIZE_PARAM,
-+ .numblocks = FLASH_NUMBLOCKS_16m_PARAM,
- },
- /* main blocks */
- {
-- offset: FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM,
-- erasesize: FLASH_BLOCKSIZE_MAIN,
-- numblocks: FLASH_NUMBLOCKS_16m_MAIN
-+ .offset = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM,
-+ .erasesize = FLASH_BLOCKSIZE_MAIN,
-+ .numblocks = FLASH_NUMBLOCKS_16m_MAIN,
- }
- };
-
- #ifdef HAVE_PARTITIONS
--static struct mtd_partition lart_partitions[] =
--{
-+static struct mtd_partition lart_partitions[] = {
- /* blob */
- {
-- name: "blob",
-- offset: BLOB_START,
-- size: BLOB_LEN,
-- mask_flags: 0
-+ .name = "blob",
-+ .offset = BLOB_START,
-+ .size = BLOB_LEN,
- },
- /* kernel */
- {
-- name: "kernel",
-- offset: KERNEL_START, /* MTDPART_OFS_APPEND */
-- size: KERNEL_LEN,
-- mask_flags: 0
-+ .name = "kernel",
-+ .offset = KERNEL_START, /* MTDPART_OFS_APPEND */
-+ .size = KERNEL_LEN,
- },
- /* initial ramdisk / file system */
- {
-- name: "file system",
-- offset: INITRD_START, /* MTDPART_OFS_APPEND */
-- size: INITRD_LEN, /* MTDPART_SIZ_FULL */
-- mask_flags: 0
-+ .name = "file system",
-+ .offset = INITRD_START, /* MTDPART_OFS_APPEND */
-+ .size = INITRD_LEN, /* MTDPART_SIZ_FULL */
- }
- };
- #endif
-@@ -646,10 +641,10 @@
- mtd.erasesize = FLASH_BLOCKSIZE_MAIN;
- mtd.numeraseregions = NB_OF (erase_regions);
- mtd.eraseregions = erase_regions;
-- mtd.module = THIS_MODULE;
- mtd.erase = flash_erase;
- mtd.read = flash_read;
- mtd.write = flash_write;
-+ mtd.owner = THIS_MODULE;
-
- #ifdef LART_DEBUG
- printk (KERN_DEBUG
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/devices/ms02-nv.c linux/drivers/mtd/devices/ms02-nv.c
---- linux-mips-2.4.24-pre2/drivers/mtd/devices/ms02-nv.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/devices/ms02-nv.c 2004-11-17 18:17:59.023316352 +0100
-@@ -6,7 +6,7 @@
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/init.h>
-@@ -38,9 +38,9 @@
-
- /*
- * Addresses we probe for an MS02-NV at. Modules may be located
-- * at any 8MB boundary within a 0MB up to 112MB range or at any 32MB
-- * boundary within a 0MB up to 448MB range. We don't support a module
-- * at 0MB, though.
-+ * at any 8MiB boundary within a 0MiB up to 112MiB range or at any 32MiB
-+ * boundary within a 0MiB up to 448MiB range. We don't support a module
-+ * at 0MiB, though.
- */
- static ulong ms02nv_addrs[] __initdata = {
- 0x07000000, 0x06800000, 0x06000000, 0x05800000, 0x05000000,
-@@ -130,7 +130,7 @@
-
- int ret = -ENODEV;
-
-- /* The module decodes 8MB of address space. */
-+ /* The module decodes 8MiB of address space. */
- mod_res = kmalloc(sizeof(*mod_res), GFP_KERNEL);
- if (!mod_res)
- return -ENOMEM;
-@@ -222,7 +222,7 @@
- mtd->flags = MTD_CAP_RAM | MTD_XIP;
- mtd->size = fixsize;
- mtd->name = (char *)ms02nv_name;
-- mtd->module = THIS_MODULE;
-+ mtd->owner = THIS_MODULE;
- mtd->read = ms02nv_read;
- mtd->write = ms02nv_write;
-
-@@ -233,7 +233,7 @@
- goto err_out_csr_res;
- }
-
-- printk(KERN_INFO "mtd%d: %s at 0x%08lx, size %uMB.\n",
-+ printk(KERN_INFO "mtd%d: %s at 0x%08lx, size %uMiB.\n",
- mtd->index, ms02nv_name, addr, size >> 20);
-
- mp->next = root_ms02nv_mtd;
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/devices/ms02-nv.h linux/drivers/mtd/devices/ms02-nv.h
---- linux-mips-2.4.24-pre2/drivers/mtd/devices/ms02-nv.h 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/devices/ms02-nv.h 2004-11-17 18:17:59.025316048 +0100
-@@ -9,6 +9,8 @@
- * 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.
-+ *
-+ * $Id$
- */
-
- #include <linux/ioport.h>
-@@ -39,8 +41,8 @@
- * The diagnostic area defines two status words to be read by an
- * operating system, a magic ID to distinguish a MS02-NV board from
- * anything else and a status information providing results of tests
-- * as well as the size of SRAM available, which can be 1MB or 2MB
-- * (that's what the firmware handles; no idea if 2MB modules ever
-+ * as well as the size of SRAM available, which can be 1MiB or 2MiB
-+ * (that's what the firmware handles; no idea if 2MiB modules ever
- * existed).
- *
- * The firmware only handles the MS02-NV board if installed in the
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/devices/mtdram.c linux/drivers/mtd/devices/mtdram.c
---- linux-mips-2.4.24-pre2/drivers/mtd/devices/mtdram.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/devices/mtdram.c 2004-11-17 18:17:59.040313768 +0100
-@@ -1,6 +1,6 @@
- /*
- * mtdram - a test mtd device
-- * $Id$
-+ * $Id$
- * Author: Alexander Larsson <alex@cendio.se>
- *
- * Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
-@@ -13,6 +13,8 @@
- #include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/ioport.h>
-+#include <linux/vmalloc.h>
-+#include <linux/init.h>
- #include <linux/mtd/compatmac.h>
- #include <linux/mtd/mtd.h>
-
-@@ -136,7 +138,7 @@
- mtd->erasesize = MTDRAM_ERASE_SIZE;
- mtd->priv = mapped_address;
-
-- mtd->module = THIS_MODULE;
-+ mtd->owner = THIS_MODULE;
- mtd->erase = ram_erase;
- mtd->point = ram_point;
- mtd->unpoint = ram_unpoint;
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/devices/phram.c linux/drivers/mtd/devices/phram.c
---- linux-mips-2.4.24-pre2/drivers/mtd/devices/phram.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/devices/phram.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,362 @@
-+/**
-+ *
-+ * $Id$
-+ *
-+ * Copyright (c) Jochen Schaeuble <psionic@psionic.de>
-+ * 07/2003 rewritten by Joern Engel <joern@wh.fh-wedel.de>
-+ *
-+ * DISCLAIMER: This driver makes use of Rusty's excellent module code,
-+ * so it will not work for 2.4 without changes and it wont work for 2.4
-+ * as a module without major changes. Oh well!
-+ *
-+ * Usage:
-+ *
-+ * one commend line parameter per device, each in the form:
-+ * phram=<name>,<start>,<len>
-+ * <name> may be up to 63 characters.
-+ * <start> and <len> can be octal, decimal or hexadecimal. If followed
-+ * by "k", "M" or "G", the numbers will be interpreted as kilo, mega or
-+ * gigabytes.
-+ *
-+ */
-+
-+#include <asm/io.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/list.h>
-+#include <linux/module.h>
-+#include <linux/moduleparam.h>
-+#include <linux/mtd/mtd.h>
-+
-+#define ERROR(fmt, args...) printk(KERN_ERR "phram: " fmt , ## args)
-+
-+struct phram_mtd_list {
-+ struct list_head list;
-+ struct mtd_info *mtdinfo;
-+};
-+
-+static LIST_HEAD(phram_list);
-+
-+
-+
-+int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
-+{
-+ u_char *start = (u_char *)mtd->priv;
-+
-+ if (instr->addr + instr->len > mtd->size)
-+ return -EINVAL;
-+
-+ memset(start + instr->addr, 0xff, instr->len);
-+
-+ /* This'll catch a few races. Free the thing before returning :)
-+ * I don't feel at all ashamed. This kind of thing is possible anyway
-+ * with flash, but unlikely.
-+ */
-+
-+ instr->state = MTD_ERASE_DONE;
-+
-+ if (instr->callback)
-+ (*(instr->callback))(instr);
-+ else
-+ kfree(instr);
-+
-+ return 0;
-+}
-+
-+int phram_point(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t *retlen, u_char **mtdbuf)
-+{
-+ u_char *start = (u_char *)mtd->priv;
-+
-+ if (from + len > mtd->size)
-+ return -EINVAL;
-+
-+ *mtdbuf = start + from;
-+ *retlen = len;
-+ return 0;
-+}
-+
-+void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
-+{
-+}
-+
-+int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t *retlen, u_char *buf)
-+{
-+ u_char *start = (u_char *)mtd->priv;
-+
-+ if (from + len > mtd->size)
-+ return -EINVAL;
-+
-+ memcpy(buf, start + from, len);
-+
-+ *retlen = len;
-+ return 0;
-+}
-+
-+int phram_write(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf)
-+{
-+ u_char *start = (u_char *)mtd->priv;
-+
-+ if (to + len > mtd->size)
-+ return -EINVAL;
-+
-+ memcpy(start + to, buf, len);
-+
-+ *retlen = len;
-+ return 0;
-+}
-+
-+
-+
-+static void unregister_devices(void)
-+{
-+ struct phram_mtd_list *this;
-+
-+ list_for_each_entry(this, &phram_list, list) {
-+ del_mtd_device(this->mtdinfo);
-+ iounmap(this->mtdinfo->priv);
-+ kfree(this->mtdinfo);
-+ kfree(this);
-+ }
-+}
-+
-+static int register_device(char *name, unsigned long start, unsigned long len)
-+{
-+ struct phram_mtd_list *new;
-+ int ret = -ENOMEM;
-+
-+ new = kmalloc(sizeof(*new), GFP_KERNEL);
-+ if (!new)
-+ goto out0;
-+
-+ new->mtdinfo = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
-+ if (!new->mtdinfo)
-+ goto out1;
-+
-+ memset(new->mtdinfo, 0, sizeof(struct mtd_info));
-+
-+ ret = -EIO;
-+ new->mtdinfo->priv = ioremap(start, len);
-+ if (!new->mtdinfo->priv) {
-+ ERROR("ioremap failed\n");
-+ goto out2;
-+ }
-+
-+
-+ new->mtdinfo->name = name;
-+ new->mtdinfo->size = len;
-+ new->mtdinfo->flags = MTD_CAP_RAM | MTD_ERASEABLE | MTD_VOLATILE;
-+ new->mtdinfo->erase = phram_erase;
-+ new->mtdinfo->point = phram_point;
-+ new->mtdinfo->unpoint = phram_unpoint;
-+ new->mtdinfo->read = phram_read;
-+ new->mtdinfo->write = phram_write;
-+ new->mtdinfo->owner = THIS_MODULE;
-+ new->mtdinfo->type = MTD_RAM;
-+ new->mtdinfo->erasesize = 0x0;
-+
-+ ret = -EAGAIN;
-+ if (add_mtd_device(new->mtdinfo)) {
-+ ERROR("Failed to register new device\n");
-+ goto out3;
-+ }
-+
-+ list_add_tail(&new->list, &phram_list);
-+ return 0;
-+
-+out3:
-+ iounmap(new->mtdinfo->priv);
-+out2:
-+ kfree(new->mtdinfo);
-+out1:
-+ kfree(new);
-+out0:
-+ return ret;
-+}
-+
-+static int ustrtoul(const char *cp, char **endp, unsigned int base)
-+{
-+ unsigned long result = simple_strtoul(cp, endp, base);
-+
-+ switch (**endp) {
-+ case 'G':
-+ result *= 1024;
-+ case 'M':
-+ result *= 1024;
-+ case 'k':
-+ result *= 1024;
-+ endp++;
-+ }
-+ return result;
-+}
-+
-+static int parse_num32(uint32_t *num32, const char *token)
-+{
-+ char *endp;
-+ unsigned long n;
-+
-+ n = ustrtoul(token, &endp, 0);
-+ if (*endp)
-+ return -EINVAL;
-+
-+ *num32 = n;
-+ return 0;
-+}
-+
-+static int parse_name(char **pname, const char *token)
-+{
-+ size_t len;
-+ char *name;
-+
-+ len = strlen(token) + 1;
-+ if (len > 64)
-+ return -ENOSPC;
-+
-+ name = kmalloc(len, GFP_KERNEL);
-+ if (!name)
-+ return -ENOMEM;
-+
-+ strcpy(name, token);
-+
-+ *pname = name;
-+ return 0;
-+}
-+
-+#define parse_err(fmt, args...) do { \
-+ ERROR(fmt , ## args); \
-+ return 0; \
-+} while (0)
-+
-+static int phram_setup(const char *val, struct kernel_param *kp)
-+{
-+ char buf[64+12+12], *str = buf;
-+ char *token[3];
-+ char *name;
-+ uint32_t start;
-+ uint32_t len;
-+ int i, ret;
-+
-+ if (strnlen(val, sizeof(str)) >= sizeof(str))
-+ parse_err("parameter too long\n");
-+
-+ strcpy(str, val);
-+
-+ for (i=0; i<3; i++)
-+ token[i] = strsep(&str, ",");
-+
-+ if (str)
-+ parse_err("too many arguments\n");
-+
-+ if (!token[2])
-+ parse_err("not enough arguments\n");
-+
-+ ret = parse_name(&name, token[0]);
-+ if (ret == -ENOMEM)
-+ parse_err("out of memory\n");
-+ if (ret == -ENOSPC)
-+ parse_err("name too long\n");
-+ if (ret)
-+ return 0;
-+
-+ ret = parse_num32(&start, token[1]);
-+ if (ret)
-+ parse_err("illegal start address\n");
-+
-+ ret = parse_num32(&len, token[2]);
-+ if (ret)
-+ parse_err("illegal device length\n");
-+
-+ register_device(name, start, len);
-+
-+ return 0;
-+}
-+
-+module_param_call(phram, phram_setup, NULL, NULL, 000);
-+MODULE_PARM_DESC(phram, "Memory region to map. \"map=<name>,<start><length>\"");
-+
-+/*
-+ * Just for compatibility with slram, this is horrible and should go someday.
-+ */
-+static int __init slram_setup(const char *val, struct kernel_param *kp)
-+{
-+ char buf[256], *str = buf;
-+
-+ if (!val || !val[0])
-+ parse_err("no arguments to \"slram=\"\n");
-+
-+ if (strnlen(val, sizeof(str)) >= sizeof(str))
-+ parse_err("parameter too long\n");
-+
-+ strcpy(str, val);
-+
-+ while (str) {
-+ char *token[3];
-+ char *name;
-+ uint32_t start;
-+ uint32_t len;
-+ int i, ret;
-+
-+ for (i=0; i<3; i++) {
-+ token[i] = strsep(&str, ",");
-+ if (token[i])
-+ continue;
-+ parse_err("wrong number of arguments to \"slram=\"\n");
-+ }
-+
-+ /* name */
-+ ret = parse_name(&name, token[0]);
-+ if (ret == -ENOMEM)
-+ parse_err("of memory\n");
-+ if (ret == -ENOSPC)
-+ parse_err("too long\n");
-+ if (ret)
-+ return 1;
-+
-+ /* start */
-+ ret = parse_num32(&start, token[1]);
-+ if (ret)
-+ parse_err("illegal start address\n");
-+
-+ /* len */
-+ if (token[2][0] == '+')
-+ ret = parse_num32(&len, token[2] + 1);
-+ else
-+ ret = parse_num32(&len, token[2]);
-+
-+ if (ret)
-+ parse_err("illegal device length\n");
-+
-+ if (token[2][0] != '+') {
-+ if (len < start)
-+ parse_err("end < start\n");
-+ len -= start;
-+ }
-+
-+ register_device(name, start, len);
-+ }
-+ return 1;
-+}
-+
-+module_param_call(slram, slram_setup, NULL, NULL, 000);
-+MODULE_PARM_DESC(slram, "List of memory regions to map. \"map=<name>,<start><length/end>\"");
-+
-+
-+int __init init_phram(void)
-+{
-+ printk(KERN_ERR "phram loaded\n");
-+ return 0;
-+}
-+
-+static void __exit cleanup_phram(void)
-+{
-+ unregister_devices();
-+}
-+
-+module_init(init_phram);
-+module_exit(cleanup_phram);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Jörn Engel <joern@wh.fh-wedel.de>");
-+MODULE_DESCRIPTION("MTD driver for physical RAM");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/devices/pmc551.c linux/drivers/mtd/devices/pmc551.c
---- linux-mips-2.4.24-pre2/drivers/mtd/devices/pmc551.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/devices/pmc551.c 2004-11-17 18:17:59.043313312 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * PMC551 PCI Mezzanine Ram Device
- *
-@@ -681,11 +681,6 @@
-
- printk(KERN_INFO PMC551_VERSION);
-
-- if(!pci_present()) {
-- printk(KERN_NOTICE "pmc551: PCI not enabled.\n");
-- return -ENODEV;
-- }
--
- /*
- * PCU-bus chipset probe.
- */
-@@ -787,10 +782,10 @@
- mtd->write = pmc551_write;
- mtd->point = pmc551_point;
- mtd->unpoint = pmc551_unpoint;
-- mtd->module = THIS_MODULE;
- mtd->type = MTD_RAM;
- mtd->name = "PMC551 RAM board";
- mtd->erasesize = 0x10000;
-+ mtd->owner = THIS_MODULE;
-
- if (add_mtd_device(mtd)) {
- printk(KERN_NOTICE "pmc551: Failed to register new device\n");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/devices/slram.c linux/drivers/mtd/devices/slram.c
---- linux-mips-2.4.24-pre2/drivers/mtd/devices/slram.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/devices/slram.c 2004-11-17 18:17:59.044313160 +0100
-@@ -1,6 +1,6 @@
- /*======================================================================
-
-- $Id$
-+ $Id$
-
- This driver provides a method to access memory not used by the kernel
- itself (i.e. if the kernel commandline mem=xxx is used). To actually
-@@ -199,7 +199,7 @@
- (*curmtd)->mtdinfo->unpoint = slram_unpoint;
- (*curmtd)->mtdinfo->read = slram_read;
- (*curmtd)->mtdinfo->write = slram_write;
-- (*curmtd)->mtdinfo->module = THIS_MODULE;
-+ (*curmtd)->mtdinfo->owner = THIS_MODULE;
- (*curmtd)->mtdinfo->type = MTD_RAM;
- (*curmtd)->mtdinfo->erasesize = 0x0;
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/ftl.c linux/drivers/mtd/ftl.c
---- linux-mips-2.4.24-pre2/drivers/mtd/ftl.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/ftl.c 2004-11-17 18:17:58.837344624 +0100
-@@ -1,5 +1,5 @@
- /* This version ported to the Linux-MTD system by dwmw2@infradead.org
-- * $Id$
-+ * $Id$
- *
- * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
-@@ -55,8 +55,8 @@
- contact M-Systems (http://www.m-sys.com) directly.
-
- ======================================================================*/
-+#include <linux/mtd/blktrans.h>
- #include <linux/module.h>
--#include <linux/mtd/compatmac.h>
- #include <linux/mtd/mtd.h>
- /*#define PSYCHO_DEBUG */
-
-@@ -68,43 +68,13 @@
- #include <linux/timer.h>
- #include <linux/major.h>
- #include <linux/fs.h>
--#include <linux/ioctl.h>
-+#include <linux/init.h>
- #include <linux/hdreg.h>
--
--#if (LINUX_VERSION_CODE >= 0x20100)
- #include <linux/vmalloc.h>
--#endif
--#if (LINUX_VERSION_CODE >= 0x20303)
- #include <linux/blkpg.h>
--#endif
-+#include <asm/uaccess.h>
-
- #include <linux/mtd/ftl.h>
--/*====================================================================*/
--/* Stuff which really ought to be in compatmac.h */
--
--#if (LINUX_VERSION_CODE < 0x20328)
--#define register_disk(dev, drive, minors, ops, size) \
-- do { (dev)->part[(drive)*(minors)].nr_sects = size; \
-- if (size == 0) (dev)->part[(drive)*(minors)].start_sect = -1; \
-- resetup_one_dev(dev, drive); } while (0)
--#endif
--
--#if (LINUX_VERSION_CODE < 0x20320)
--#define BLK_DEFAULT_QUEUE(n) blk_dev[n].request_fn
--#define blk_init_queue(q, req) q = (req)
--#define blk_cleanup_queue(q) q = NULL
--#define request_arg_t void
--#else
--#define request_arg_t request_queue_t *q
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
--#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
--#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
--#else
--#define BLK_INC_USE_COUNT do {} while(0)
--#define BLK_DEC_USE_COUNT do {} while(0)
--#endif
-
- /*====================================================================*/
-
-@@ -119,19 +89,6 @@
- #define FTL_MAJOR 44
- #endif
-
--/* Funky stuff for setting up a block device */
--#define MAJOR_NR FTL_MAJOR
--#define DEVICE_NAME "ftl"
--#define DEVICE_REQUEST do_ftl_request
--#define DEVICE_ON(device)
--#define DEVICE_OFF(device)
--
--#define DEVICE_NR(minor) ((minor)>>5)
--#define REGION_NR(minor) (((minor)>>3)&3)
--#define PART_NR(minor) ((minor)&7)
--#define MINOR_NR(dev,reg,part) (((dev)<<5)+((reg)<<3)+(part))
--
--#include <linux/blk.h>
-
- /*====================================================================*/
-
-@@ -142,8 +99,7 @@
- #define MAX_REGION 4
-
- /* Maximum number of partitions in an FTL region */
--#define PART_BITS 3
--#define MAX_PART 8
-+#define PART_BITS 4
-
- /* Maximum number of outstanding erase requests per socket */
- #define MAX_ERASE 8
-@@ -154,7 +110,7 @@
-
- /* Each memory region corresponds to a minor device */
- typedef struct partition_t {
-- struct mtd_info *mtd;
-+ struct mtd_blktrans_dev mbd;
- u_int32_t state;
- u_int32_t *VirtualBlockMap;
- u_int32_t *VirtualPageMap;
-@@ -179,21 +135,10 @@
- region_info_t region;
- memory_handle_t handle;
- #endif
-- atomic_t open;
- } partition_t;
-
--partition_t *myparts[MAX_MTD_DEVICES];
--
--static void ftl_notify_add(struct mtd_info *mtd);
--static void ftl_notify_remove(struct mtd_info *mtd);
--
- void ftl_freepart(partition_t *part);
-
--static struct mtd_notifier ftl_notifier = {
-- add: ftl_notify_add,
-- remove: ftl_notify_remove,
--};
--
- /* Partition state flags */
- #define FTL_FORMATTED 0x01
-
-@@ -204,51 +149,11 @@
- #define XFER_PREPARED 0x03
- #define XFER_FAILED 0x04
-
--static struct hd_struct ftl_hd[MINOR_NR(MAX_DEV, 0, 0)];
--static int ftl_sizes[MINOR_NR(MAX_DEV, 0, 0)];
--static int ftl_blocksizes[MINOR_NR(MAX_DEV, 0, 0)];
--
--static struct gendisk ftl_gendisk = {
-- major: FTL_MAJOR,
-- major_name: "ftl",
-- minor_shift: PART_BITS,
-- max_p: MAX_PART,
--#if (LINUX_VERSION_CODE < 0x20328)
-- max_nr: MAX_DEV*MAX_PART,
--#endif
-- part: ftl_hd,
-- sizes: ftl_sizes,
--};
--
- /*====================================================================*/
-
--static int ftl_ioctl(struct inode *inode, struct file *file,
-- u_int cmd, u_long arg);
--static int ftl_open(struct inode *inode, struct file *file);
--static release_t ftl_close(struct inode *inode, struct file *file);
--static int ftl_reread_partitions(int minor);
-
- static void ftl_erase_callback(struct erase_info *done);
-
--#if LINUX_VERSION_CODE < 0x20326
--static struct file_operations ftl_blk_fops = {
-- open: ftl_open,
-- release: ftl_close,
-- ioctl: ftl_ioctl,
-- read: block_read,
-- write: block_write,
-- fsync: block_fsync
--};
--#else
--static struct block_device_operations ftl_blk_fops = {
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14)
-- owner: THIS_MODULE,
--#endif
-- open: ftl_open,
-- release: ftl_close,
-- ioctl: ftl_ioctl,
--};
--#endif
-
- /*======================================================================
-
-@@ -264,13 +169,13 @@
- loff_t offset, max_offset;
- int ret;
- part->header.FormattedSize = 0;
-- max_offset = (0x100000<part->mtd->size)?0x100000:part->mtd->size;
-+ max_offset = (0x100000<part->mbd.mtd->size)?0x100000:part->mbd.mtd->size;
- /* Search first megabyte for a valid FTL header */
- for (offset = 0;
- (offset + sizeof(header)) < max_offset;
-- offset += part->mtd->erasesize ? : 0x2000) {
-+ offset += part->mbd.mtd->erasesize ? : 0x2000) {
-
-- ret = part->mtd->read(part->mtd, offset, sizeof(header), &ret,
-+ ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &ret,
- (unsigned char *)&header);
-
- if (ret)
-@@ -283,15 +188,15 @@
- printk(KERN_NOTICE "ftl_cs: FTL header not found.\n");
- return -ENOENT;
- }
-- if ((le16_to_cpu(header.NumEraseUnits) > 65536) || header.BlockSize != 9 ||
-+ if (header.BlockSize != 9 ||
- (header.EraseUnitSize < 10) || (header.EraseUnitSize > 31) ||
- (header.NumTransferUnits >= le16_to_cpu(header.NumEraseUnits))) {
- printk(KERN_NOTICE "ftl_cs: FTL header corrupt!\n");
- return -1;
- }
-- if ((1 << header.EraseUnitSize) != part->mtd->erasesize) {
-+ if ((1 << header.EraseUnitSize) != part->mbd.mtd->erasesize) {
- printk(KERN_NOTICE "ftl: FTL EraseUnitSize %x != MTD erasesize %x\n",
-- 1 << header.EraseUnitSize,part->mtd->erasesize);
-+ 1 << header.EraseUnitSize,part->mbd.mtd->erasesize);
- return -1;
- }
- part->header = header;
-@@ -326,7 +231,7 @@
- for (i = 0; i < le16_to_cpu(part->header.NumEraseUnits); i++) {
- offset = ((i + le16_to_cpu(part->header.FirstPhysicalEUN))
- << part->header.EraseUnitSize);
-- ret = part->mtd->read(part->mtd, offset, sizeof(header), &retval,
-+ ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &retval,
- (unsigned char *)&header);
-
- if (ret)
-@@ -391,7 +296,7 @@
- part->EUNInfo[i].Deleted = 0;
- offset = part->EUNInfo[i].Offset + le32_to_cpu(header.BAMOffset);
-
-- ret = part->mtd->read(part->mtd, offset,
-+ ret = part->mbd.mtd->read(part->mbd.mtd, offset,
- part->BlocksPerUnit * sizeof(u_int32_t), &retval,
- (unsigned char *)part->bam_cache);
-
-@@ -456,7 +361,7 @@
- erase->len = 1 << part->header.EraseUnitSize;
- erase->priv = (u_long)part;
-
-- ret = part->mtd->erase(part->mtd, erase);
-+ ret = part->mbd.mtd->erase(part->mbd.mtd, erase);
-
- if (!ret)
- xfer->EraseCount++;
-@@ -523,7 +428,7 @@
- header.LogicalEUN = cpu_to_le16(0xffff);
- header.EraseCount = cpu_to_le32(xfer->EraseCount);
-
-- ret = part->mtd->write(part->mtd, xfer->Offset, sizeof(header),
-+ ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset, sizeof(header),
- &retlen, (u_char *)&header);
-
- if (ret) {
-@@ -539,7 +444,7 @@
-
- for (i = 0; i < nbam; i++, offset += sizeof(u_int32_t)) {
-
-- ret = part->mtd->write(part->mtd, offset, sizeof(u_int32_t),
-+ ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t),
- &retlen, (u_char *)&ctl);
-
- if (ret)
-@@ -586,7 +491,7 @@
-
- offset = eun->Offset + le32_to_cpu(part->header.BAMOffset);
-
-- ret = part->mtd->read(part->mtd, offset,
-+ ret = part->mbd.mtd->read(part->mbd.mtd, offset,
- part->BlocksPerUnit * sizeof(u_int32_t),
- &retlen, (u_char *) (part->bam_cache));
-
-@@ -604,7 +509,7 @@
- offset = xfer->Offset + 20; /* Bad! */
- unit = cpu_to_le16(0x7fff);
-
-- ret = part->mtd->write(part->mtd, offset, sizeof(u_int16_t),
-+ ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int16_t),
- &retlen, (u_char *) &unit);
-
- if (ret) {
-@@ -624,7 +529,7 @@
- break;
- case BLOCK_DATA:
- case BLOCK_REPLACEMENT:
-- ret = part->mtd->read(part->mtd, src, SECTOR_SIZE,
-+ ret = part->mbd.mtd->read(part->mbd.mtd, src, SECTOR_SIZE,
- &retlen, (u_char *) buf);
- if (ret) {
- printk(KERN_WARNING "ftl: Error reading old xfer unit in copy_erase_unit\n");
-@@ -632,7 +537,7 @@
- }
-
-
-- ret = part->mtd->write(part->mtd, dest, SECTOR_SIZE,
-+ ret = part->mbd.mtd->write(part->mbd.mtd, dest, SECTOR_SIZE,
- &retlen, (u_char *) buf);
- if (ret) {
- printk(KERN_WARNING "ftl: Error writing new xfer unit in copy_erase_unit\n");
-@@ -651,7 +556,7 @@
- }
-
- /* Write the BAM to the transfer unit */
-- ret = part->mtd->write(part->mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset),
-+ ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset),
- part->BlocksPerUnit * sizeof(int32_t), &retlen,
- (u_char *)part->bam_cache);
- if (ret) {
-@@ -661,7 +566,7 @@
-
-
- /* All clear? Then update the LogicalEUN again */
-- ret = part->mtd->write(part->mtd, xfer->Offset + 20, sizeof(u_int16_t),
-+ ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + 20, sizeof(u_int16_t),
- &retlen, (u_char *)&srcunitswap);
-
- if (ret) {
-@@ -749,8 +654,8 @@
- if (queued) {
- DEBUG(1, "ftl_cs: waiting for transfer "
- "unit to be prepared...\n");
-- if (part->mtd->sync)
-- part->mtd->sync(part->mtd);
-+ if (part->mbd.mtd->sync)
-+ part->mbd.mtd->sync(part->mbd.mtd);
- } else {
- static int ne = 0;
- if (++ne < 5)
-@@ -848,7 +753,7 @@
- /* Invalidate cache */
- part->bam_index = 0xffff;
-
-- ret = part->mtd->read(part->mtd,
-+ ret = part->mbd.mtd->read(part->mbd.mtd,
- part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset),
- part->BlocksPerUnit * sizeof(u_int32_t),
- &retlen, (u_char *) (part->bam_cache));
-@@ -877,78 +782,6 @@
-
- } /* find_free */
-
--/*======================================================================
--
-- This gets a memory handle for the region corresponding to the
-- minor device number.
--
--======================================================================*/
--
--static int ftl_open(struct inode *inode, struct file *file)
--{
-- int minor = MINOR(inode->i_rdev);
-- partition_t *partition;
--
-- if (minor>>4 >= MAX_MTD_DEVICES)
-- return -ENODEV;
--
-- partition = myparts[minor>>4];
--
-- if (!partition)
-- return -ENODEV;
--
-- if (partition->state != FTL_FORMATTED)
-- return -ENXIO;
--
-- if (ftl_gendisk.part[minor].nr_sects == 0)
-- return -ENXIO;
--
-- BLK_INC_USE_COUNT;
--
-- if (!get_mtd_device(partition->mtd, -1)) {
-- BLK_DEC_USE_COUNT;
-- return -ENXIO;
-- }
--
-- if ((file->f_mode & 2) && !(partition->mtd->flags & MTD_CLEAR_BITS) ) {
-- put_mtd_device(partition->mtd);
-- BLK_DEC_USE_COUNT;
-- return -EROFS;
-- }
--
-- DEBUG(0, "ftl_cs: ftl_open(%d)\n", minor);
--
-- atomic_inc(&partition->open);
--
-- return 0;
--}
--
--/*====================================================================*/
--
--static release_t ftl_close(struct inode *inode, struct file *file)
--{
-- int minor = MINOR(inode->i_rdev);
-- partition_t *part = myparts[minor >> 4];
-- int i;
--
-- DEBUG(0, "ftl_cs: ftl_close(%d)\n", minor);
--
-- /* Wait for any pending erase operations to complete */
-- if (part->mtd->sync)
-- part->mtd->sync(part->mtd);
--
-- for (i = 0; i < part->header.NumTransferUnits; i++) {
-- if (part->XferInfo[i].state == XFER_ERASED)
-- prepare_xfer(part, i);
-- }
--
-- atomic_dec(&part->open);
--
-- put_mtd_device(part->mtd);
-- BLK_DEC_USE_COUNT;
-- release_return(0);
--} /* ftl_close */
--
-
- /*======================================================================
-
-@@ -983,7 +816,7 @@
- else {
- offset = (part->EUNInfo[log_addr / bsize].Offset
- + (log_addr % bsize));
-- ret = part->mtd->read(part->mtd, offset, SECTOR_SIZE,
-+ ret = part->mbd.mtd->read(part->mbd.mtd, offset, SECTOR_SIZE,
- &retlen, (u_char *) buffer);
-
- if (ret) {
-@@ -1022,7 +855,7 @@
- le32_to_cpu(part->header.BAMOffset));
-
- #ifdef PSYCHO_DEBUG
-- ret = part->mtd->read(part->mtd, offset, sizeof(u_int32_t),
-+ ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(u_int32_t),
- &retlen, (u_char *)&old_addr);
- if (ret) {
- printk(KERN_WARNING"ftl: Error reading old_addr in set_bam_entry: %d\n",ret);
-@@ -1059,7 +892,7 @@
- #endif
- part->bam_cache[blk] = le_virt_addr;
- }
-- ret = part->mtd->write(part->mtd, offset, sizeof(u_int32_t),
-+ ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t),
- &retlen, (u_char *)&le_virt_addr);
-
- if (ret) {
-@@ -1119,7 +952,7 @@
- part->EUNInfo[part->bam_index].Deleted++;
- offset = (part->EUNInfo[part->bam_index].Offset +
- blk * SECTOR_SIZE);
-- ret = part->mtd->write(part->mtd, offset, SECTOR_SIZE, &retlen,
-+ ret = part->mbd.mtd->write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen,
- buffer);
-
- if (ret) {
-@@ -1151,164 +984,32 @@
- return 0;
- } /* ftl_write */
-
--/*======================================================================
--
-- IOCTL calls for getting device parameters.
--
--======================================================================*/
--
--static int ftl_ioctl(struct inode *inode, struct file *file,
-- u_int cmd, u_long arg)
-+static int ftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
- {
-- struct hd_geometry *geo = (struct hd_geometry *)arg;
-- int ret = 0, minor = MINOR(inode->i_rdev);
-- partition_t *part= myparts[minor >> 4];
-+ partition_t *part = (void *)dev;
- u_long sect;
-
-- if (!part)
-- return -ENODEV; /* How? */
--
-- switch (cmd) {
-- case HDIO_GETGEO:
-- ret = verify_area(VERIFY_WRITE, (long *)arg, sizeof(*geo));
-- if (ret) return ret;
-- /* Sort of arbitrary: round size down to 4K boundary */
-+ /* Sort of arbitrary: round size down to 4KiB boundary */
- sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE;
-- put_user(1, (char *)&geo->heads);
-- put_user(8, (char *)&geo->sectors);
-- put_user((sect>>3), (short *)&geo->cylinders);
-- put_user(ftl_hd[minor].start_sect, (u_long *)&geo->start);
-- break;
-- case BLKGETSIZE:
-- ret = put_user(ftl_hd[minor].nr_sects, (unsigned long *)arg);
-- break;
--#ifdef BLKGETSIZE64
-- case BLKGETSIZE64:
-- ret = put_user((u64)ftl_hd[minor].nr_sects << 9, (u64 *)arg);
-- break;
--#endif
-- case BLKRRPART:
-- ret = ftl_reread_partitions(minor);
-- break;
--#if (LINUX_VERSION_CODE < 0x20303)
-- case BLKFLSBUF:
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-- if (!capable(CAP_SYS_ADMIN)) return -EACCES;
--#endif
-- fsync_dev(inode->i_rdev);
-- invalidate_buffers(inode->i_rdev);
-- break;
-- RO_IOCTLS(inode->i_rdev, arg);
--#else
-- case BLKROSET:
-- case BLKROGET:
-- case BLKFLSBUF:
-- ret = blk_ioctl(inode->i_rdev, cmd, arg);
-- break;
--#endif
-- default:
-- ret = -EINVAL;
-- }
--
-- return ret;
--} /* ftl_ioctl */
--
--/*======================================================================
-
-- Handler for block device requests
-+ geo->heads = 1;
-+ geo->sectors = 8;
-+ geo->cylinders = sect >> 3;
-
--======================================================================*/
--
--static int ftl_reread_partitions(int minor)
--{
-- partition_t *part = myparts[minor >> 4];
-- int i, whole;
--
-- DEBUG(0, "ftl_cs: ftl_reread_partition(%d)\n", minor);
-- if ((atomic_read(&part->open) > 1)) {
-- return -EBUSY;
-- }
-- whole = minor & ~(MAX_PART-1);
--
-- i = MAX_PART - 1;
-- while (i-- > 0) {
-- if (ftl_hd[whole+i].nr_sects > 0) {
-- kdev_t rdev = MKDEV(FTL_MAJOR, whole+i);
--
-- invalidate_device(rdev, 1);
-- }
-- ftl_hd[whole+i].start_sect = 0;
-- ftl_hd[whole+i].nr_sects = 0;
-- }
--
-- scan_header(part);
--
-- register_disk(&ftl_gendisk, whole >> PART_BITS, MAX_PART,
-- &ftl_blk_fops, le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE);
--
--#ifdef PCMCIA_DEBUG
-- for (i = 0; i < MAX_PART; i++) {
-- if (ftl_hd[whole+i].nr_sects > 0)
-- printk(KERN_INFO " %d: start %ld size %ld\n", i,
-- ftl_hd[whole+i].start_sect,
-- ftl_hd[whole+i].nr_sects);
-- }
--#endif
- return 0;
- }
-
--/*======================================================================
--
-- Handler for block device requests
--
--======================================================================*/
--
--static void do_ftl_request(request_arg_t)
-+static int ftl_readsect(struct mtd_blktrans_dev *dev,
-+ unsigned long block, char *buf)
- {
-- int ret, minor;
-- partition_t *part;
--
-- do {
-- // sti();
-- INIT_REQUEST;
--
-- minor = MINOR(CURRENT->rq_dev);
--
-- part = myparts[minor >> 4];
-- if (part) {
-- ret = 0;
--
-- switch (CURRENT->cmd) {
-- case READ:
-- ret = ftl_read(part, CURRENT->buffer,
-- CURRENT->sector+ftl_hd[minor].start_sect,
-- CURRENT->current_nr_sectors);
-- if (ret) printk("ftl_read returned %d\n", ret);
-- break;
--
-- case WRITE:
-- ret = ftl_write(part, CURRENT->buffer,
-- CURRENT->sector+ftl_hd[minor].start_sect,
-- CURRENT->current_nr_sectors);
-- if (ret) printk("ftl_write returned %d\n", ret);
-- break;
--
-- default:
-- panic("ftl_cs: unknown block command!\n");
--
-- }
-- } else {
-- ret = 1;
-- printk("NULL part in ftl_request\n");
-- }
--
-- if (!ret) {
-- CURRENT->sector += CURRENT->current_nr_sectors;
-- }
-+ return ftl_read((void *)dev, buf, block, 1);
-+}
-
-- end_request((ret == 0) ? 1 : 0);
-- } while (1);
--} /* do_ftl_request */
-+static int ftl_writesect(struct mtd_blktrans_dev *dev,
-+ unsigned long block, char *buf)
-+{
-+ return ftl_write((void *)dev, buf, block, 1);
-+}
-
- /*====================================================================*/
-
-@@ -1337,19 +1038,9 @@
-
- } /* ftl_freepart */
-
--static void ftl_notify_add(struct mtd_info *mtd)
-+static void ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
- {
- partition_t *partition;
-- int device;
--
-- for (device=0; device < MAX_MTD_DEVICES && myparts[device]; device++)
-- ;
--
-- if (device == MAX_MTD_DEVICES) {
-- printk(KERN_NOTICE "Maximum number of FTL partitions reached\n"
-- "Not scanning <%s>\n", mtd->name);
-- return;
-- }
-
- partition = kmalloc(sizeof(partition_t), GFP_KERNEL);
-
-@@ -1361,92 +1052,55 @@
-
- memset(partition, 0, sizeof(partition_t));
-
-- partition->mtd = mtd;
-+ partition->mbd.mtd = mtd;
-
- if ((scan_header(partition) == 0) &&
- (build_maps(partition) == 0)) {
-
- partition->state = FTL_FORMATTED;
-- atomic_set(&partition->open, 0);
-- myparts[device] = partition;
-- ftl_reread_partitions(device << 4);
- #ifdef PCMCIA_DEBUG
-- printk(KERN_INFO "ftl_cs: opening %d kb FTL partition\n",
-+ printk(KERN_INFO "ftl_cs: opening %d KiB FTL partition\n",
- le32_to_cpu(partition->header.FormattedSize) >> 10);
- #endif
-+ partition->mbd.size = le32_to_cpu(partition->header.FormattedSize) >> 9;
-+ partition->mbd.blksize = SECTOR_SIZE;
-+ partition->mbd.tr = tr;
-+ partition->mbd.devnum = -1;
-+ if (add_mtd_blktrans_dev((void *)partition))
-+ kfree(partition);
-+
- } else
- kfree(partition);
- }
-
--static void ftl_notify_remove(struct mtd_info *mtd)
-+static void ftl_remove_dev(struct mtd_blktrans_dev *dev)
- {
-- int i,j;
--
-- /* Q: What happens if you try to remove a device which has
-- * a currently-open FTL partition on it?
-- *
-- * A: You don't. The ftl_open routine is responsible for
-- * increasing the use count of the driver module which
-- * it uses.
-- */
--
-- /* That's the theory, anyway :) */
--
-- for (i=0; i< MAX_MTD_DEVICES; i++)
-- if (myparts[i] && myparts[i]->mtd == mtd) {
--
-- if (myparts[i]->state == FTL_FORMATTED)
-- ftl_freepart(myparts[i]);
--
-- myparts[i]->state = 0;
-- for (j=0; j<16; j++) {
-- ftl_gendisk.part[j].nr_sects=0;
-- ftl_gendisk.part[j].start_sect=0;
-- }
-- kfree(myparts[i]);
-- myparts[i] = NULL;
-- }
-+ del_mtd_blktrans_dev(dev);
-+ kfree(dev);
- }
-
-+struct mtd_blktrans_ops ftl_tr = {
-+ .name = "ftl",
-+ .major = FTL_MAJOR,
-+ .part_bits = PART_BITS,
-+ .readsect = ftl_readsect,
-+ .writesect = ftl_writesect,
-+ .getgeo = ftl_getgeo,
-+ .add_mtd = ftl_add_mtd,
-+ .remove_dev = ftl_remove_dev,
-+ .owner = THIS_MODULE,
-+};
-+
- int init_ftl(void)
- {
-- int i;
--
-- memset(myparts, 0, sizeof(myparts));
-+ DEBUG(0, "$Id$\n");
-
-- DEBUG(0, "$Id$\n");
--
-- if (register_blkdev(FTL_MAJOR, "ftl", &ftl_blk_fops)) {
-- printk(KERN_NOTICE "ftl_cs: unable to grab major "
-- "device number!\n");
-- return -EAGAIN;
-- }
--
-- for (i = 0; i < MINOR_NR(MAX_DEV, 0, 0); i++)
-- ftl_blocksizes[i] = 1024;
-- for (i = 0; i < MAX_DEV*MAX_PART; i++) {
-- ftl_hd[i].nr_sects = 0;
-- ftl_hd[i].start_sect = 0;
-- }
-- blksize_size[FTL_MAJOR] = ftl_blocksizes;
-- ftl_gendisk.major = FTL_MAJOR;
-- blk_init_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR), &do_ftl_request);
-- add_gendisk(&ftl_gendisk);
--
-- register_mtd_user(&ftl_notifier);
--
-- return 0;
-+ return register_mtd_blktrans(&ftl_tr);
- }
-
- static void __exit cleanup_ftl(void)
- {
-- unregister_mtd_user(&ftl_notifier);
--
-- unregister_blkdev(FTL_MAJOR, "ftl");
-- blk_cleanup_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR));
-- blksize_size[FTL_MAJOR] = NULL;
--
-- del_gendisk(&ftl_gendisk);
-+ deregister_mtd_blktrans(&ftl_tr);
- }
-
- module_init(init_ftl);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/inftlcore.c linux/drivers/mtd/inftlcore.c
---- linux-mips-2.4.24-pre2/drivers/mtd/inftlcore.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/inftlcore.c 2004-11-17 18:17:58.000000000 +0100
-@@ -0,0 +1,900 @@
-+/*
-+ * inftlcore.c -- Linux driver for Inverse Flash Translation Layer (INFTL)
-+ *
-+ * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
-+ *
-+ * Based heavily on the nftlcore.c code which is:
-+ * (c) 1999 Machine Vision Holdings, Inc.
-+ * Author: David Woodhouse <dwmw2@infradead.org>
-+ *
-+ * $Id$
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/init.h>
-+#include <linux/kmod.h>
-+#include <linux/hdreg.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nftl.h>
-+#include <linux/mtd/inftl.h>
-+#include <asm/uaccess.h>
-+#include <asm/errno.h>
-+#include <asm/io.h>
-+
-+/*
-+ * Maximum number of loops while examining next block, to have a
-+ * chance to detect consistency problems (they should never happen
-+ * because of the checks done in the mounting.
-+ */
-+#define MAX_LOOPS 10000
-+
-+extern void INFTL_dumptables(struct INFTLrecord *inftl);
-+extern void INFTL_dumpVUchains(struct INFTLrecord *inftl);
-+
-+static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
-+{
-+ struct INFTLrecord *inftl;
-+ unsigned long temp;
-+
-+ if (mtd->ecctype != MTD_ECC_RS_DiskOnChip)
-+ return;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: add_mtd for %s\n", mtd->name);
-+
-+ inftl = kmalloc(sizeof(*inftl), GFP_KERNEL);
-+
-+ if (!inftl) {
-+ printk(KERN_WARNING "INFTL: Out of memory for data structures\n");
-+ return;
-+ }
-+ memset(inftl, 0, sizeof(*inftl));
-+
-+ inftl->mbd.mtd = mtd;
-+ inftl->mbd.devnum = -1;
-+ inftl->mbd.blksize = 512;
-+ inftl->mbd.tr = tr;
-+
-+ if (INFTL_mount(inftl) < 0) {
-+ printk(KERN_WARNING "INFTL: could not mount device\n");
-+ kfree(inftl);
-+ return;
-+ }
-+
-+ /* OK, it's a new one. Set up all the data structures. */
-+
-+ /* Calculate geometry */
-+ inftl->cylinders = 1024;
-+ inftl->heads = 16;
-+
-+ temp = inftl->cylinders * inftl->heads;
-+ inftl->sectors = inftl->mbd.size / temp;
-+ if (inftl->mbd.size % temp) {
-+ inftl->sectors++;
-+ temp = inftl->cylinders * inftl->sectors;
-+ inftl->heads = inftl->mbd.size / temp;
-+
-+ if (inftl->mbd.size % temp) {
-+ inftl->heads++;
-+ temp = inftl->heads * inftl->sectors;
-+ inftl->cylinders = inftl->mbd.size / temp;
-+ }
-+ }
-+
-+ if (inftl->mbd.size != inftl->heads * inftl->cylinders * inftl->sectors) {
-+ /*
-+ Oh no we don't have
-+ mbd.size == heads * cylinders * sectors
-+ */
-+ printk(KERN_WARNING "INFTL: cannot calculate a geometry to "
-+ "match size of 0x%lx.\n", inftl->mbd.size);
-+ printk(KERN_WARNING "INFTL: using C:%d H:%d S:%d "
-+ "(== 0x%lx sects)\n",
-+ inftl->cylinders, inftl->heads , inftl->sectors,
-+ (long)inftl->cylinders * (long)inftl->heads *
-+ (long)inftl->sectors );
-+ }
-+
-+ if (add_mtd_blktrans_dev(&inftl->mbd)) {
-+ if (inftl->PUtable)
-+ kfree(inftl->PUtable);
-+ if (inftl->VUtable)
-+ kfree(inftl->VUtable);
-+ kfree(inftl);
-+ return;
-+ }
-+#ifdef PSYCHO_DEBUG
-+ printk(KERN_INFO "INFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a');
-+#endif
-+ return;
-+}
-+
-+static void inftl_remove_dev(struct mtd_blktrans_dev *dev)
-+{
-+ struct INFTLrecord *inftl = (void *)dev;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: remove_dev (i=%d)\n", dev->devnum);
-+
-+ del_mtd_blktrans_dev(dev);
-+
-+ if (inftl->PUtable)
-+ kfree(inftl->PUtable);
-+ if (inftl->VUtable)
-+ kfree(inftl->VUtable);
-+ kfree(inftl);
-+}
-+
-+/*
-+ * Actual INFTL access routines.
-+ */
-+
-+/*
-+ * INFTL_findfreeblock: Find a free Erase Unit on the INFTL partition.
-+ * This function is used when the give Virtual Unit Chain.
-+ */
-+static u16 INFTL_findfreeblock(struct INFTLrecord *inftl, int desperate)
-+{
-+ u16 pot = inftl->LastFreeEUN;
-+ int silly = inftl->nb_blocks;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_findfreeblock(inftl=0x%x,"
-+ "desperate=%d)\n", (int)inftl, desperate);
-+
-+ /*
-+ * Normally, we force a fold to happen before we run out of free
-+ * blocks completely.
-+ */
-+ if (!desperate && inftl->numfreeEUNs < 2) {
-+ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: there are too few free "
-+ "EUNs (%d)\n", inftl->numfreeEUNs);
-+ return 0xffff;
-+ }
-+
-+ /* Scan for a free block */
-+ do {
-+ if (inftl->PUtable[pot] == BLOCK_FREE) {
-+ inftl->LastFreeEUN = pot;
-+ return pot;
-+ }
-+
-+ if (++pot > inftl->lastEUN)
-+ pot = 0;
-+
-+ if (!silly--) {
-+ printk(KERN_WARNING "INFTL: no free blocks found! "
-+ "EUN range = %d - %d\n", 0, inftl->LastFreeEUN);
-+ return BLOCK_NIL;
-+ }
-+ } while (pot != inftl->LastFreeEUN);
-+
-+ return BLOCK_NIL;
-+}
-+
-+static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned pendingblock)
-+{
-+ u16 BlockMap[MAX_SECTORS_PER_UNIT];
-+ unsigned char BlockDeleted[MAX_SECTORS_PER_UNIT];
-+ unsigned int thisEUN, prevEUN, status;
-+ int block, silly;
-+ unsigned int targetEUN;
-+ struct inftl_oob oob;
-+ size_t retlen;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_foldchain(inftl=0x%x,thisVUC=%d,"
-+ "pending=%d)\n", (int)inftl, thisVUC, pendingblock);
-+
-+ memset(BlockMap, 0xff, sizeof(BlockMap));
-+ memset(BlockDeleted, 0, sizeof(BlockDeleted));
-+
-+ thisEUN = targetEUN = inftl->VUtable[thisVUC];
-+
-+ if (thisEUN == BLOCK_NIL) {
-+ printk(KERN_WARNING "INFTL: trying to fold non-existent "
-+ "Virtual Unit Chain %d!\n", thisVUC);
-+ return BLOCK_NIL;
-+ }
-+
-+ /*
-+ * Scan to find the Erase Unit which holds the actual data for each
-+ * 512-byte block within the Chain.
-+ */
-+ silly = MAX_LOOPS;
-+ while (thisEUN < inftl->nb_blocks) {
-+ for (block = 0; block < inftl->EraseSize/SECTORSIZE; block ++) {
-+ if ((BlockMap[block] != 0xffff) || BlockDeleted[block])
-+ continue;
-+
-+ if (MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize)
-+ + (block * SECTORSIZE), 16 , &retlen,
-+ (char *)&oob) < 0)
-+ status = SECTOR_IGNORE;
-+ else
-+ status = oob.b.Status | oob.b.Status1;
-+
-+ switch(status) {
-+ case SECTOR_FREE:
-+ case SECTOR_IGNORE:
-+ break;
-+ case SECTOR_USED:
-+ BlockMap[block] = thisEUN;
-+ continue;
-+ case SECTOR_DELETED:
-+ BlockDeleted[block] = 1;
-+ continue;
-+ default:
-+ printk(KERN_WARNING "INFTL: unknown status "
-+ "for block %d in EUN %d: %x\n",
-+ block, thisEUN, status);
-+ break;
-+ }
-+ }
-+
-+ if (!silly--) {
-+ printk(KERN_WARNING "INFTL: infinite loop in Virtual "
-+ "Unit Chain 0x%x\n", thisVUC);
-+ return BLOCK_NIL;
-+ }
-+
-+ thisEUN = inftl->PUtable[thisEUN];
-+ }
-+
-+ /*
-+ * OK. We now know the location of every block in the Virtual Unit
-+ * Chain, and the Erase Unit into which we are supposed to be copying.
-+ * Go for it.
-+ */
-+ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: folding chain %d into unit %d\n",
-+ thisVUC, targetEUN);
-+
-+ for (block = 0; block < inftl->EraseSize/SECTORSIZE ; block++) {
-+ unsigned char movebuf[SECTORSIZE];
-+ int ret;
-+
-+ /*
-+ * If it's in the target EUN already, or if it's pending write,
-+ * do nothing.
-+ */
-+ if (BlockMap[block] == targetEUN || (pendingblock ==
-+ (thisVUC * (inftl->EraseSize / SECTORSIZE) + block))) {
-+ continue;
-+ }
-+
-+ /*
-+ * Copy only in non free block (free blocks can only
-+ * happen in case of media errors or deleted blocks).
-+ */
-+ if (BlockMap[block] == BLOCK_NIL)
-+ continue;
-+
-+ ret = MTD_READECC(inftl->mbd.mtd, (inftl->EraseSize *
-+ BlockMap[block]) + (block * SECTORSIZE), SECTORSIZE,
-+ &retlen, movebuf, (char *)&oob, NULL);
-+ if (ret < 0) {
-+ ret = MTD_READECC(inftl->mbd.mtd, (inftl->EraseSize *
-+ BlockMap[block]) + (block * SECTORSIZE),
-+ SECTORSIZE, &retlen, movebuf, (char *)&oob,
-+ NULL);
-+ if (ret != -EIO)
-+ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went "
-+ "away on retry?\n");
-+ }
-+ MTD_WRITEECC(inftl->mbd.mtd, (inftl->EraseSize * targetEUN) +
-+ (block * SECTORSIZE), SECTORSIZE, &retlen,
-+ movebuf, (char *)&oob, NULL);
-+ }
-+
-+ /*
-+ * Newest unit in chain now contains data from _all_ older units.
-+ * So go through and erase each unit in chain, oldest first. (This
-+ * is important, by doing oldest first if we crash/reboot then it
-+ * it is relatively simple to clean up the mess).
-+ */
-+ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: want to erase virtual chain %d\n",
-+ thisVUC);
-+
-+ for (;;) {
-+ /* Find oldest unit in chain. */
-+ thisEUN = inftl->VUtable[thisVUC];
-+ prevEUN = BLOCK_NIL;
-+ while (inftl->PUtable[thisEUN] != BLOCK_NIL) {
-+ prevEUN = thisEUN;
-+ thisEUN = inftl->PUtable[thisEUN];
-+ }
-+
-+ /* Check if we are all done */
-+ if (thisEUN == targetEUN)
-+ break;
-+
-+ if (INFTL_formatblock(inftl, thisEUN) < 0) {
-+ /*
-+ * Could not erase : mark block as reserved.
-+ * FixMe: Update Bad Unit Table on disk.
-+ */
-+ inftl->PUtable[thisEUN] = BLOCK_RESERVED;
-+ } else {
-+ /* Correctly erased : mark it as free */
-+ inftl->PUtable[thisEUN] = BLOCK_FREE;
-+ inftl->PUtable[prevEUN] = BLOCK_NIL;
-+ inftl->numfreeEUNs++;
-+ }
-+ }
-+
-+ return targetEUN;
-+}
-+
-+u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock)
-+{
-+ /*
-+ * This is the part that needs some cleverness applied.
-+ * For now, I'm doing the minimum applicable to actually
-+ * get the thing to work.
-+ * Wear-levelling and other clever stuff needs to be implemented
-+ * and we also need to do some assessment of the results when
-+ * the system loses power half-way through the routine.
-+ */
-+ u16 LongestChain = 0;
-+ u16 ChainLength = 0, thislen;
-+ u16 chain, EUN;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_makefreeblock(inftl=0x%x,"
-+ "pending=%d)\n", (int)inftl, pendingblock);
-+
-+ for (chain = 0; chain < inftl->nb_blocks; chain++) {
-+ EUN = inftl->VUtable[chain];
-+ thislen = 0;
-+
-+ while (EUN <= inftl->lastEUN) {
-+ thislen++;
-+ EUN = inftl->PUtable[EUN];
-+ if (thislen > 0xff00) {
-+ printk(KERN_WARNING "INFTL: endless loop in "
-+ "Virtual Chain %d: Unit %x\n",
-+ chain, EUN);
-+ /*
-+ * Actually, don't return failure.
-+ * Just ignore this chain and get on with it.
-+ */
-+ thislen = 0;
-+ break;
-+ }
-+ }
-+
-+ if (thislen > ChainLength) {
-+ ChainLength = thislen;
-+ LongestChain = chain;
-+ }
-+ }
-+
-+ if (ChainLength < 2) {
-+ printk(KERN_WARNING "INFTL: no Virtual Unit Chains available "
-+ "for folding. Failing request\n");
-+ return BLOCK_NIL;
-+ }
-+
-+ return INFTL_foldchain(inftl, LongestChain, pendingblock);
-+}
-+
-+static int nrbits(unsigned int val, int bitcount)
-+{
-+ int i, total = 0;
-+
-+ for (i = 0; (i < bitcount); i++)
-+ total += (((0x1 << i) & val) ? 1 : 0);
-+ return total;
-+}
-+
-+/*
-+ * INFTL_findwriteunit: Return the unit number into which we can write
-+ * for this block. Make it available if it isn't already.
-+ */
-+static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
-+{
-+ unsigned int thisVUC = block / (inftl->EraseSize / SECTORSIZE);
-+ unsigned int thisEUN, writeEUN, prev_block, status;
-+ unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize -1);
-+ struct inftl_oob oob;
-+ struct inftl_bci bci;
-+ unsigned char anac, nacs, parity;
-+ size_t retlen;
-+ int silly, silly2 = 3;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_findwriteunit(inftl=0x%x,"
-+ "block=%d)\n", (int)inftl, block);
-+
-+ do {
-+ /*
-+ * Scan the media to find a unit in the VUC which has
-+ * a free space for the block in question.
-+ */
-+ writeEUN = BLOCK_NIL;
-+ thisEUN = inftl->VUtable[thisVUC];
-+ silly = MAX_LOOPS;
-+
-+ while (thisEUN <= inftl->lastEUN) {
-+ MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) +
-+ blockofs, 8, &retlen, (char *)&bci);
-+
-+ status = bci.Status | bci.Status1;
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: status of block %d in "
-+ "EUN %d is %x\n", block , writeEUN, status);
-+
-+ switch(status) {
-+ case SECTOR_FREE:
-+ writeEUN = thisEUN;
-+ break;
-+ case SECTOR_DELETED:
-+ case SECTOR_USED:
-+ /* Can't go any further */
-+ goto hitused;
-+ case SECTOR_IGNORE:
-+ break;
-+ default:
-+ /*
-+ * Invalid block. Don't use it any more.
-+ * Must implement.
-+ */
-+ break;
-+ }
-+
-+ if (!silly--) {
-+ printk(KERN_WARNING "INFTL: infinite loop in "
-+ "Virtual Unit Chain 0x%x\n", thisVUC);
-+ return 0xffff;
-+ }
-+
-+ /* Skip to next block in chain */
-+ thisEUN = inftl->PUtable[thisEUN];
-+ }
-+
-+hitused:
-+ if (writeEUN != BLOCK_NIL)
-+ return writeEUN;
-+
-+
-+ /*
-+ * OK. We didn't find one in the existing chain, or there
-+ * is no existing chain. Allocate a new one.
-+ */
-+ writeEUN = INFTL_findfreeblock(inftl, 0);
-+
-+ if (writeEUN == BLOCK_NIL) {
-+ /*
-+ * That didn't work - there were no free blocks just
-+ * waiting to be picked up. We're going to have to fold
-+ * a chain to make room.
-+ */
-+ thisEUN = INFTL_makefreeblock(inftl, 0xffff);
-+
-+ /*
-+ * Hopefully we free something, lets try again.
-+ * This time we are desperate...
-+ */
-+ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: using desperate==1 "
-+ "to find free EUN to accommodate write to "
-+ "VUC %d\n", thisVUC);
-+ writeEUN = INFTL_findfreeblock(inftl, 1);
-+ if (writeEUN == BLOCK_NIL) {
-+ /*
-+ * Ouch. This should never happen - we should
-+ * always be able to make some room somehow.
-+ * If we get here, we've allocated more storage
-+ * space than actual media, or our makefreeblock
-+ * routine is missing something.
-+ */
-+ printk(KERN_WARNING "INFTL: cannot make free "
-+ "space.\n");
-+#ifdef DEBUG
-+ INFTL_dumptables(inftl);
-+ INFTL_dumpVUchains(inftl);
-+#endif
-+ return BLOCK_NIL;
-+ }
-+ }
-+
-+ /*
-+ * Insert new block into virtual chain. Firstly update the
-+ * block headers in flash...
-+ */
-+ anac = 0;
-+ nacs = 0;
-+ thisEUN = inftl->VUtable[thisVUC];
-+ if (thisEUN != BLOCK_NIL) {
-+ MTD_READOOB(inftl->mbd.mtd, thisEUN * inftl->EraseSize
-+ + 8, 8, &retlen, (char *)&oob.u);
-+ anac = oob.u.a.ANAC + 1;
-+ nacs = oob.u.a.NACs + 1;
-+ }
-+
-+ prev_block = inftl->VUtable[thisVUC];
-+ if (prev_block < inftl->nb_blocks)
-+ prev_block -= inftl->firstEUN;
-+
-+ parity = (nrbits(thisVUC, 16) & 0x1) ? 0x1 : 0;
-+ parity |= (nrbits(prev_block, 16) & 0x1) ? 0x2 : 0;
-+ parity |= (nrbits(anac, 8) & 0x1) ? 0x4 : 0;
-+ parity |= (nrbits(nacs, 8) & 0x1) ? 0x8 : 0;
-+
-+ oob.u.a.virtualUnitNo = cpu_to_le16(thisVUC);
-+ oob.u.a.prevUnitNo = cpu_to_le16(prev_block);
-+ oob.u.a.ANAC = anac;
-+ oob.u.a.NACs = nacs;
-+ oob.u.a.parityPerField = parity;
-+ oob.u.a.discarded = 0xaa;
-+
-+ MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize + 8, 8,
-+ &retlen, (char *)&oob.u);
-+
-+ /* Also back up header... */
-+ oob.u.b.virtualUnitNo = cpu_to_le16(thisVUC);
-+ oob.u.b.prevUnitNo = cpu_to_le16(prev_block);
-+ oob.u.b.ANAC = anac;
-+ oob.u.b.NACs = nacs;
-+ oob.u.b.parityPerField = parity;
-+ oob.u.b.discarded = 0xaa;
-+
-+ MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize +
-+ SECTORSIZE * 4 + 8, 8, &retlen, (char *)&oob.u);
-+
-+ inftl->PUtable[writeEUN] = inftl->VUtable[thisVUC];
-+ inftl->VUtable[thisVUC] = writeEUN;
-+
-+ inftl->numfreeEUNs--;
-+ return writeEUN;
-+
-+ } while (silly2--);
-+
-+ printk(KERN_WARNING "INFTL: error folding to make room for Virtual "
-+ "Unit Chain 0x%x\n", thisVUC);
-+ return 0xffff;
-+}
-+
-+/*
-+ * Given a Virtual Unit Chain, see if it can be deleted, and if so do it.
-+ */
-+static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
-+{
-+ unsigned char BlockUsed[MAX_SECTORS_PER_UNIT];
-+ unsigned char BlockDeleted[MAX_SECTORS_PER_UNIT];
-+ unsigned int thisEUN, status;
-+ int block, silly;
-+ struct inftl_bci bci;
-+ size_t retlen;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_trydeletechain(inftl=0x%x,"
-+ "thisVUC=%d)\n", (int)inftl, thisVUC);
-+
-+ memset(BlockUsed, 0, sizeof(BlockUsed));
-+ memset(BlockDeleted, 0, sizeof(BlockDeleted));
-+
-+ thisEUN = inftl->VUtable[thisVUC];
-+ if (thisEUN == BLOCK_NIL) {
-+ printk(KERN_WARNING "INFTL: trying to delete non-existent "
-+ "Virtual Unit Chain %d!\n", thisVUC);
-+ return;
-+ }
-+
-+ /*
-+ * Scan through the Erase Units to determine whether any data is in
-+ * each of the 512-byte blocks within the Chain.
-+ */
-+ silly = MAX_LOOPS;
-+ while (thisEUN < inftl->nb_blocks) {
-+ for (block = 0; block < inftl->EraseSize/SECTORSIZE; block++) {
-+ if (BlockUsed[block] || BlockDeleted[block])
-+ continue;
-+
-+ if (MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize)
-+ + (block * SECTORSIZE), 8 , &retlen,
-+ (char *)&bci) < 0)
-+ status = SECTOR_IGNORE;
-+ else
-+ status = bci.Status | bci.Status1;
-+
-+ switch(status) {
-+ case SECTOR_FREE:
-+ case SECTOR_IGNORE:
-+ break;
-+ case SECTOR_USED:
-+ BlockUsed[block] = 1;
-+ continue;
-+ case SECTOR_DELETED:
-+ BlockDeleted[block] = 1;
-+ continue;
-+ default:
-+ printk(KERN_WARNING "INFTL: unknown status "
-+ "for block %d in EUN %d: 0x%x\n",
-+ block, thisEUN, status);
-+ }
-+ }
-+
-+ if (!silly--) {
-+ printk(KERN_WARNING "INFTL: infinite loop in Virtual "
-+ "Unit Chain 0x%x\n", thisVUC);
-+ return;
-+ }
-+
-+ thisEUN = inftl->PUtable[thisEUN];
-+ }
-+
-+ for (block = 0; block < inftl->EraseSize/SECTORSIZE; block++)
-+ if (BlockUsed[block])
-+ return;
-+
-+ /*
-+ * For each block in the chain free it and make it available
-+ * for future use. Erase from the oldest unit first.
-+ */
-+ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: deleting empty VUC %d\n", thisVUC);
-+
-+ for (;;) {
-+ u16 *prevEUN = &inftl->VUtable[thisVUC];
-+ thisEUN = *prevEUN;
-+
-+ /* If the chain is all gone already, we're done */
-+ if (thisEUN == BLOCK_NIL) {
-+ DEBUG(MTD_DEBUG_LEVEL2, "INFTL: Empty VUC %d for deletion was already absent\n", thisEUN);
-+ return;
-+ }
-+
-+ /* Find oldest unit in chain. */
-+ while (inftl->PUtable[thisEUN] != BLOCK_NIL) {
-+ BUG_ON(thisEUN >= inftl->nb_blocks);
-+
-+ prevEUN = &inftl->PUtable[thisEUN];
-+ thisEUN = *prevEUN;
-+ }
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "Deleting EUN %d from VUC %d\n",
-+ thisEUN, thisVUC);
-+
-+ if (INFTL_formatblock(inftl, thisEUN) < 0) {
-+ /*
-+ * Could not erase : mark block as reserved.
-+ * FixMe: Update Bad Unit Table on medium.
-+ */
-+ inftl->PUtable[thisEUN] = BLOCK_RESERVED;
-+ } else {
-+ /* Correctly erased : mark it as free */
-+ inftl->PUtable[thisEUN] = BLOCK_FREE;
-+ inftl->numfreeEUNs++;
-+ }
-+
-+ /* Now sort out whatever was pointing to it... */
-+ *prevEUN = BLOCK_NIL;
-+
-+ /* Ideally we'd actually be responsive to new
-+ requests while we're doing this -- if there's
-+ free space why should others be made to wait? */
-+ cond_resched();
-+ }
-+
-+ inftl->VUtable[thisVUC] = BLOCK_NIL;
-+}
-+
-+static int INFTL_deleteblock(struct INFTLrecord *inftl, unsigned block)
-+{
-+ unsigned int thisEUN = inftl->VUtable[block / (inftl->EraseSize / SECTORSIZE)];
-+ unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1);
-+ unsigned int status;
-+ int silly = MAX_LOOPS;
-+ size_t retlen;
-+ struct inftl_bci bci;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_deleteblock(inftl=0x%x,"
-+ "block=%d)\n", (int)inftl, block);
-+
-+ while (thisEUN < inftl->nb_blocks) {
-+ if (MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) +
-+ blockofs, 8, &retlen, (char *)&bci) < 0)
-+ status = SECTOR_IGNORE;
-+ else
-+ status = bci.Status | bci.Status1;
-+
-+ switch (status) {
-+ case SECTOR_FREE:
-+ case SECTOR_IGNORE:
-+ break;
-+ case SECTOR_DELETED:
-+ thisEUN = BLOCK_NIL;
-+ goto foundit;
-+ case SECTOR_USED:
-+ goto foundit;
-+ default:
-+ printk(KERN_WARNING "INFTL: unknown status for "
-+ "block %d in EUN %d: 0x%x\n",
-+ block, thisEUN, status);
-+ break;
-+ }
-+
-+ if (!silly--) {
-+ printk(KERN_WARNING "INFTL: infinite loop in Virtual "
-+ "Unit Chain 0x%x\n",
-+ block / (inftl->EraseSize / SECTORSIZE));
-+ return 1;
-+ }
-+ thisEUN = inftl->PUtable[thisEUN];
-+ }
-+
-+foundit:
-+ if (thisEUN != BLOCK_NIL) {
-+ loff_t ptr = (thisEUN * inftl->EraseSize) + blockofs;
-+
-+ if (MTD_READOOB(inftl->mbd.mtd, ptr, 8, &retlen, (char *)&bci) < 0)
-+ return -EIO;
-+ bci.Status = bci.Status1 = SECTOR_DELETED;
-+ if (MTD_WRITEOOB(inftl->mbd.mtd, ptr, 8, &retlen, (char *)&bci) < 0)
-+ return -EIO;
-+ INFTL_trydeletechain(inftl, block / (inftl->EraseSize / SECTORSIZE));
-+ }
-+ return 0;
-+}
-+
-+static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
-+ char *buffer)
-+{
-+ struct INFTLrecord *inftl = (void *)mbd;
-+ unsigned int writeEUN;
-+ unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1);
-+ size_t retlen;
-+ u8 eccbuf[6];
-+ char *p, *pend;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_writeblock(inftl=0x%x,block=%d,"
-+ "buffer=0x%x)\n", (int)inftl, block, (int)buffer);
-+
-+ /* Is block all zero? */
-+ pend = buffer + SECTORSIZE;
-+ for (p = buffer; p < pend && !*p; p++)
-+ ;
-+
-+ if (p < pend) {
-+ writeEUN = INFTL_findwriteunit(inftl, block);
-+
-+ if (writeEUN == BLOCK_NIL) {
-+ printk(KERN_WARNING "inftl_writeblock(): cannot find "
-+ "block to write to\n");
-+ /*
-+ * If we _still_ haven't got a block to use,
-+ * we're screwed.
-+ */
-+ return 1;
-+ }
-+
-+ MTD_WRITEECC(inftl->mbd.mtd, (writeEUN * inftl->EraseSize) +
-+ blockofs, SECTORSIZE, &retlen, (char *)buffer,
-+ (char *)eccbuf, NULL);
-+ /*
-+ * No need to write SECTOR_USED flags since they are written
-+ * in mtd_writeecc
-+ */
-+ } else {
-+ INFTL_deleteblock(inftl, block);
-+ }
-+
-+ return 0;
-+}
-+
-+static int inftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
-+ char *buffer)
-+{
-+ struct INFTLrecord *inftl = (void *)mbd;
-+ unsigned int thisEUN = inftl->VUtable[block / (inftl->EraseSize / SECTORSIZE)];
-+ unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1);
-+ unsigned int status;
-+ int silly = MAX_LOOPS;
-+ struct inftl_bci bci;
-+ size_t retlen;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_readblock(inftl=0x%x,block=%d,"
-+ "buffer=0x%x)\n", (int)inftl, block, (int)buffer);
-+
-+ while (thisEUN < inftl->nb_blocks) {
-+ if (MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) +
-+ blockofs, 8, &retlen, (char *)&bci) < 0)
-+ status = SECTOR_IGNORE;
-+ else
-+ status = bci.Status | bci.Status1;
-+
-+ switch (status) {
-+ case SECTOR_DELETED:
-+ thisEUN = BLOCK_NIL;
-+ goto foundit;
-+ case SECTOR_USED:
-+ goto foundit;
-+ case SECTOR_FREE:
-+ case SECTOR_IGNORE:
-+ break;
-+ default:
-+ printk(KERN_WARNING "INFTL: unknown status for "
-+ "block %ld in EUN %d: 0x%04x\n",
-+ block, thisEUN, status);
-+ break;
-+ }
-+
-+ if (!silly--) {
-+ printk(KERN_WARNING "INFTL: infinite loop in "
-+ "Virtual Unit Chain 0x%lx\n",
-+ block / (inftl->EraseSize / SECTORSIZE));
-+ return 1;
-+ }
-+
-+ thisEUN = inftl->PUtable[thisEUN];
-+ }
-+
-+foundit:
-+ if (thisEUN == BLOCK_NIL) {
-+ /* The requested block is not on the media, return all 0x00 */
-+ memset(buffer, 0, SECTORSIZE);
-+ } else {
-+ size_t retlen;
-+ loff_t ptr = (thisEUN * inftl->EraseSize) + blockofs;
-+ u_char eccbuf[6];
-+ if (MTD_READECC(inftl->mbd.mtd, ptr, SECTORSIZE, &retlen,
-+ buffer, eccbuf, NULL))
-+ return -EIO;
-+ }
-+ return 0;
-+}
-+
-+static int inftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
-+{
-+ struct INFTLrecord *inftl = (void *)dev;
-+
-+ geo->heads = inftl->heads;
-+ geo->sectors = inftl->sectors;
-+ geo->cylinders = inftl->cylinders;
-+
-+ return 0;
-+}
-+
-+struct mtd_blktrans_ops inftl_tr = {
-+ .name = "inftl",
-+ .major = INFTL_MAJOR,
-+ .part_bits = INFTL_PARTN_BITS,
-+ .getgeo = inftl_getgeo,
-+ .readsect = inftl_readblock,
-+ .writesect = inftl_writeblock,
-+ .add_mtd = inftl_add_mtd,
-+ .remove_dev = inftl_remove_dev,
-+ .owner = THIS_MODULE,
-+};
-+
-+extern char inftlmountrev[];
-+
-+int __init init_inftl(void)
-+{
-+ printk(KERN_INFO "INFTL: inftlcore.c $Revision$, "
-+ "inftlmount.c %s\n", inftlmountrev);
-+
-+ return register_mtd_blktrans(&inftl_tr);
-+}
-+
-+static void __exit cleanup_inftl(void)
-+{
-+ deregister_mtd_blktrans(&inftl_tr);
-+}
-+
-+module_init(init_inftl);
-+module_exit(cleanup_inftl);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>, David Woodhouse <dwmw2@infradead.org>, Fabrice Bellard <fabrice.bellard@netgem.com> et al.");
-+MODULE_DESCRIPTION("Support code for Inverse Flash Translation Layer, used on M-Systems DiskOnChip 2000, Millennium and Millennium Plus");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/inftlmount.c linux/drivers/mtd/inftlmount.c
---- linux-mips-2.4.24-pre2/drivers/mtd/inftlmount.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/inftlmount.c 2004-11-17 18:17:58.000000000 +0100
-@@ -0,0 +1,817 @@
-+/*
-+ * inftlmount.c -- INFTL mount code with extensive checks.
-+ *
-+ * Author: Greg Ungerer (gerg@snapgear.com)
-+ * (C) Copyright 2002-2003, Greg Ungerer (gerg@snapgear.com)
-+ *
-+ * Based heavily on the nftlmount.c code which is:
-+ * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
-+ * Copyright (C) 2000 Netgem S.A.
-+ *
-+ * $Id$
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <asm/errno.h>
-+#include <asm/io.h>
-+#include <asm/uaccess.h>
-+#include <linux/miscdevice.h>
-+#include <linux/pci.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/init.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nftl.h>
-+#include <linux/mtd/inftl.h>
-+#include <linux/mtd/compatmac.h>
-+
-+char inftlmountrev[]="$Revision$";
-+
-+/*
-+ * find_boot_record: Find the INFTL Media Header and its Spare copy which
-+ * contains the various device information of the INFTL partition and
-+ * Bad Unit Table. Update the PUtable[] table according to the Bad
-+ * Unit Table. PUtable[] is used for management of Erase Unit in
-+ * other routines in inftlcore.c and inftlmount.c.
-+ */
-+static int find_boot_record(struct INFTLrecord *inftl)
-+{
-+ struct inftl_unittail h1;
-+ //struct inftl_oob oob;
-+ unsigned int i, block, boot_record_count = 0;
-+ u8 buf[SECTORSIZE];
-+ struct INFTLMediaHeader *mh = &inftl->MediaHdr;
-+ struct INFTLPartition *ip;
-+ int retlen;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: find_boot_record(inftl=0x%x)\n",
-+ (int)inftl);
-+
-+ /*
-+ * Assume logical EraseSize == physical erasesize for starting the
-+ * scan. We'll sort it out later if we find a MediaHeader which says
-+ * otherwise.
-+ */
-+ inftl->EraseSize = inftl->mbd.mtd->erasesize;
-+ inftl->nb_blocks = inftl->mbd.mtd->size / inftl->EraseSize;
-+
-+ inftl->MediaUnit = BLOCK_NIL;
-+ inftl->SpareMediaUnit = BLOCK_NIL;
-+
-+ /* Search for a valid boot record */
-+ for (block = 0; block < inftl->nb_blocks; block++) {
-+ int ret;
-+
-+ /*
-+ * Check for BNAND header first. Then whinge if it's found
-+ * but later checks fail.
-+ */
-+ if ((ret = MTD_READ(inftl->mbd.mtd, block * inftl->EraseSize,
-+ SECTORSIZE, &retlen, buf))) {
-+ static int warncount = 5;
-+
-+ if (warncount) {
-+ printk(KERN_WARNING "INFTL: block read at 0x%x "
-+ "of mtd%d failed: %d\n",
-+ block * inftl->EraseSize,
-+ inftl->mbd.mtd->index, ret);
-+ if (!--warncount)
-+ printk(KERN_WARNING "INFTL: further "
-+ "failures for this block will "
-+ "not be printed\n");
-+ }
-+ continue;
-+ }
-+
-+ if (retlen < 6 || memcmp(buf, "BNAND", 6)) {
-+ /* BNAND\0 not found. Continue */
-+ continue;
-+ }
-+
-+ /* To be safer with BIOS, also use erase mark as discriminant */
-+ if ((ret = MTD_READOOB(inftl->mbd.mtd, block * inftl->EraseSize +
-+ SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0)) {
-+ printk(KERN_WARNING "INFTL: ANAND header found at "
-+ "0x%x in mtd%d, but OOB data read failed "
-+ "(err %d)\n", block * inftl->EraseSize,
-+ inftl->mbd.mtd->index, ret);
-+ continue;
-+ }
-+
-+ if (boot_record_count) {
-+ /*
-+ * We've already processed one. So we just check if
-+ * this one is the same as the first one we found.
-+ */
-+ if (memcmp(mh, buf, sizeof(struct INFTLMediaHeader))) {
-+ printk(KERN_WARNING "INFTL: Media Headers at "
-+ "0x%x and 0x%x disagree.\n",
-+ inftl->MediaUnit * inftl->EraseSize,
-+ block * inftl->EraseSize);
-+ return -1;
-+ }
-+ if (boot_record_count == 1)
-+ inftl->SpareMediaUnit = block;
-+
-+ /*
-+ * Mark this boot record (INFTL MediaHeader) block as
-+ * reserved.
-+ */
-+ inftl->PUtable[block] = BLOCK_RESERVED;
-+
-+ boot_record_count++;
-+ continue;
-+ }
-+
-+ /*
-+ * This is the first we've seen.
-+ * Copy the media header structure into place.
-+ */
-+ memcpy(mh, buf, sizeof(struct INFTLMediaHeader));
-+ mh->NoOfBootImageBlocks = le32_to_cpu(mh->NoOfBootImageBlocks);
-+ mh->NoOfBinaryPartitions = le32_to_cpu(mh->NoOfBinaryPartitions);
-+ mh->NoOfBDTLPartitions = le32_to_cpu(mh->NoOfBDTLPartitions);
-+ mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits);
-+ mh->FormatFlags = le32_to_cpu(mh->FormatFlags);
-+ mh->PercentUsed = le32_to_cpu(mh->PercentUsed);
-+
-+#ifdef CONFIG_MTD_DEBUG_VERBOSE
-+ if (CONFIG_MTD_DEBUG_VERBOSE >= 2) {
-+ printk("INFTL: Media Header ->\n"
-+ " bootRecordID = %s\n"
-+ " NoOfBootImageBlocks = %d\n"
-+ " NoOfBinaryPartitions = %d\n"
-+ " NoOfBDTLPartitions = %d\n"
-+ " BlockMultiplerBits = %d\n"
-+ " FormatFlgs = %d\n"
-+ " OsakVersion = 0x%x\n"
-+ " PercentUsed = %d\n",
-+ mh->bootRecordID, mh->NoOfBootImageBlocks,
-+ mh->NoOfBinaryPartitions,
-+ mh->NoOfBDTLPartitions,
-+ mh->BlockMultiplierBits, mh->FormatFlags,
-+ mh->OsakVersion, mh->PercentUsed);
-+ }
-+#endif
-+
-+ if (mh->NoOfBDTLPartitions == 0) {
-+ printk(KERN_WARNING "INFTL: Media Header sanity check "
-+ "failed: NoOfBDTLPartitions (%d) == 0, "
-+ "must be at least 1\n", mh->NoOfBDTLPartitions);
-+ return -1;
-+ }
-+
-+ if ((mh->NoOfBDTLPartitions + mh->NoOfBinaryPartitions) > 4) {
-+ printk(KERN_WARNING "INFTL: Media Header sanity check "
-+ "failed: Total Partitions (%d) > 4, "
-+ "BDTL=%d Binary=%d\n", mh->NoOfBDTLPartitions +
-+ mh->NoOfBinaryPartitions,
-+ mh->NoOfBDTLPartitions,
-+ mh->NoOfBinaryPartitions);
-+ return -1;
-+ }
-+
-+ if (mh->BlockMultiplierBits > 1) {
-+ printk(KERN_WARNING "INFTL: sorry, we don't support "
-+ "UnitSizeFactor 0x%02x\n",
-+ mh->BlockMultiplierBits);
-+ return -1;
-+ } else if (mh->BlockMultiplierBits == 1) {
-+ printk(KERN_WARNING "INFTL: support for INFTL with "
-+ "UnitSizeFactor 0x%02x is experimental\n",
-+ mh->BlockMultiplierBits);
-+ inftl->EraseSize = inftl->mbd.mtd->erasesize <<
-+ (0xff - mh->BlockMultiplierBits);
-+ inftl->nb_blocks = inftl->mbd.mtd->size / inftl->EraseSize;
-+ }
-+
-+ /* Scan the partitions */
-+ for (i = 0; (i < 4); i++) {
-+ ip = &mh->Partitions[i];
-+ ip->virtualUnits = le32_to_cpu(ip->virtualUnits);
-+ ip->firstUnit = le32_to_cpu(ip->firstUnit);
-+ ip->lastUnit = le32_to_cpu(ip->lastUnit);
-+ ip->flags = le32_to_cpu(ip->flags);
-+ ip->spareUnits = le32_to_cpu(ip->spareUnits);
-+ ip->Reserved0 = le32_to_cpu(ip->Reserved0);
-+
-+#ifdef CONFIG_MTD_DEBUG_VERBOSE
-+ if (CONFIG_MTD_DEBUG_VERBOSE >= 2) {
-+ printk(" PARTITION[%d] ->\n"
-+ " virtualUnits = %d\n"
-+ " firstUnit = %d\n"
-+ " lastUnit = %d\n"
-+ " flags = 0x%x\n"
-+ " spareUnits = %d\n",
-+ i, ip->virtualUnits, ip->firstUnit,
-+ ip->lastUnit, ip->flags,
-+ ip->spareUnits);
-+ }
-+#endif
-+
-+ if (ip->Reserved0 != ip->firstUnit) {
-+ struct erase_info *instr = &inftl->instr;
-+
-+ /*
-+ * Most likely this is using the
-+ * undocumented qiuck mount feature.
-+ * We don't support that, we will need
-+ * to erase the hidden block for full
-+ * compatibility.
-+ */
-+ instr->addr = ip->Reserved0 * inftl->EraseSize;
-+ instr->len = inftl->EraseSize;
-+ MTD_ERASE(inftl->mbd.mtd, instr);
-+ }
-+ if ((ip->lastUnit - ip->firstUnit + 1) < ip->virtualUnits) {
-+ printk(KERN_WARNING "INFTL: Media Header "
-+ "Partition %d sanity check failed\n"
-+ " firstUnit %d : lastUnit %d > "
-+ "virtualUnits %d\n", i, ip->lastUnit,
-+ ip->firstUnit, ip->Reserved0);
-+ return -1;
-+ }
-+ if (ip->Reserved1 != 0) {
-+ printk(KERN_WARNING "INFTL: Media Header "
-+ "Partition %d sanity check failed: "
-+ "Reserved1 %d != 0\n",
-+ i, ip->Reserved1);
-+ return -1;
-+ }
-+
-+ if (ip->flags & INFTL_BDTL)
-+ break;
-+ }
-+
-+ if (i >= 4) {
-+ printk(KERN_WARNING "INFTL: Media Header Partition "
-+ "sanity check failed:\n No partition "
-+ "marked as Disk Partition\n");
-+ return -1;
-+ }
-+
-+ inftl->nb_boot_blocks = ip->firstUnit;
-+ inftl->numvunits = ip->virtualUnits;
-+ if (inftl->numvunits > (inftl->nb_blocks -
-+ inftl->nb_boot_blocks - 2)) {
-+ printk(KERN_WARNING "INFTL: Media Header sanity check "
-+ "failed:\n numvunits (%d) > nb_blocks "
-+ "(%d) - nb_boot_blocks(%d) - 2\n",
-+ inftl->numvunits, inftl->nb_blocks,
-+ inftl->nb_boot_blocks);
-+ return -1;
-+ }
-+
-+ inftl->mbd.size = inftl->numvunits *
-+ (inftl->EraseSize / SECTORSIZE);
-+
-+ /*
-+ * Block count is set to last used EUN (we won't need to keep
-+ * any meta-data past that point).
-+ */
-+ inftl->firstEUN = ip->firstUnit;
-+ inftl->lastEUN = ip->lastUnit;
-+ inftl->nb_blocks = ip->lastUnit + 1;
-+
-+ /* Memory alloc */
-+ inftl->PUtable = kmalloc(inftl->nb_blocks * sizeof(u16), GFP_KERNEL);
-+ if (!inftl->PUtable) {
-+ printk(KERN_WARNING "INFTL: allocation of PUtable "
-+ "failed (%d bytes)\n",
-+ inftl->nb_blocks * sizeof(u16));
-+ return -ENOMEM;
-+ }
-+
-+ inftl->VUtable = kmalloc(inftl->nb_blocks * sizeof(u16), GFP_KERNEL);
-+ if (!inftl->VUtable) {
-+ kfree(inftl->PUtable);
-+ printk(KERN_WARNING "INFTL: allocation of VUtable "
-+ "failed (%d bytes)\n",
-+ inftl->nb_blocks * sizeof(u16));
-+ return -ENOMEM;
-+ }
-+
-+ /* Mark the blocks before INFTL MediaHeader as reserved */
-+ for (i = 0; i < inftl->nb_boot_blocks; i++)
-+ inftl->PUtable[i] = BLOCK_RESERVED;
-+ /* Mark all remaining blocks as potentially containing data */
-+ for (; i < inftl->nb_blocks; i++)
-+ inftl->PUtable[i] = BLOCK_NOTEXPLORED;
-+
-+ /* Mark this boot record (NFTL MediaHeader) block as reserved */
-+ inftl->PUtable[block] = BLOCK_RESERVED;
-+
-+#if 0
-+ /* Read Bad Erase Unit Table and modify PUtable[] accordingly */
-+ for (i = 0; i < inftl->nb_blocks; i++) {
-+ if ((i & (SECTORSIZE - 1)) == 0) {
-+ /* read one sector for every SECTORSIZE of blocks */
-+ if ((ret = MTD_READECC(inftl->mbd.mtd,
-+ block * inftl->EraseSize + i + SECTORSIZE,
-+ SECTORSIZE, &retlen, buf,
-+ (char *)&oob, NULL)) < 0) {
-+ printk(KERN_WARNING "INFTL: read of "
-+ "bad sector table failed "
-+ "(err %d)\n", ret);
-+ kfree(inftl->VUtable);
-+ kfree(inftl->PUtable);
-+ return -1;
-+ }
-+ }
-+ /* Mark the Bad Erase Unit as RESERVED in PUtable */
-+ if (buf[i & (SECTORSIZE - 1)] != 0xff)
-+ inftl->PUtable[i] = BLOCK_RESERVED;
-+ }
-+#endif
-+
-+ inftl->MediaUnit = block;
-+ boot_record_count++;
-+ }
-+
-+ return boot_record_count ? 0 : -1;
-+}
-+
-+static int memcmpb(void *a, int c, int n)
-+{
-+ int i;
-+ for (i = 0; i < n; i++) {
-+ if (c != ((unsigned char *)a)[i])
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * check_free_sector: check if a free sector is actually FREE,
-+ * i.e. All 0xff in data and oob area.
-+ */
-+static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address,
-+ int len, int check_oob)
-+{
-+ int i, retlen;
-+ u8 buf[SECTORSIZE];
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: check_free_sectors(inftl=0x%x,"
-+ "address=0x%x,len=%d,check_oob=%d)\n", (int)inftl,
-+ address, len, check_oob);
-+
-+ for (i = 0; i < len; i += SECTORSIZE) {
-+ /*
-+ * We want to read the sector without ECC check here since a
-+ * free sector does not have ECC syndrome on it yet.
-+ */
-+ if (MTD_READ(inftl->mbd.mtd, address, SECTORSIZE, &retlen, buf) < 0)
-+ return -1;
-+ if (memcmpb(buf, 0xff, SECTORSIZE) != 0)
-+ return -1;
-+
-+ if (check_oob) {
-+ if (MTD_READOOB(inftl->mbd.mtd, address,
-+ inftl->mbd.mtd->oobsize, &retlen, buf) < 0)
-+ return -1;
-+ if (memcmpb(buf, 0xff, inftl->mbd.mtd->oobsize) != 0)
-+ return -1;
-+ }
-+ address += SECTORSIZE;
-+ }
-+
-+ return 0;
-+}
-+
-+/*
-+ * INFTL_format: format a Erase Unit by erasing ALL Erase Zones in the Erase
-+ * Unit and Update INFTL metadata. Each erase operation is
-+ * checked with check_free_sectors.
-+ *
-+ * Return: 0 when succeed, -1 on error.
-+ *
-+ * ToDo: 1. Is it neceressary to check_free_sector after erasing ??
-+ * 2. UnitSizeFactor != 0xFF
-+ */
-+int INFTL_formatblock(struct INFTLrecord *inftl, int block)
-+{
-+ int retlen;
-+ struct inftl_unittail uci;
-+ struct erase_info *instr = &inftl->instr;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_formatblock(inftl=0x%x,"
-+ "block=%d)\n", (int)inftl, block);
-+
-+ memset(instr, 0, sizeof(struct erase_info));
-+
-+ /* FIXME: Shouldn't we be setting the 'discarded' flag to zero
-+ _first_? */
-+
-+ /* Use async erase interface, test return code */
-+ instr->addr = block * inftl->EraseSize;
-+ instr->len = inftl->EraseSize;
-+ MTD_ERASE(inftl->mbd.mtd, instr);
-+
-+ if (instr->state == MTD_ERASE_FAILED) {
-+ /*
-+ * Could not format, FixMe: We should update the BadUnitTable
-+ * both in memory and on disk.
-+ */
-+ printk(KERN_WARNING "INFTL: error while formatting block %d\n",
-+ block);
-+ return -1;
-+ }
-+
-+ /*
-+ * Check the "freeness" of Erase Unit before updating metadata.
-+ * FixMe: is this check really necessary? Since we have check the
-+ * return code after the erase operation.
-+ */
-+ if (check_free_sectors(inftl, instr->addr, inftl->EraseSize, 1) != 0)
-+ return -1;
-+
-+ uci.EraseMark = cpu_to_le16(ERASE_MARK);
-+ uci.EraseMark1 = cpu_to_le16(ERASE_MARK);
-+ uci.Reserved[0] = 0;
-+ uci.Reserved[1] = 0;
-+ uci.Reserved[2] = 0;
-+ uci.Reserved[3] = 0;
-+ if (MTD_WRITEOOB(inftl->mbd.mtd, block * inftl->EraseSize + SECTORSIZE * 2 +
-+ 8, 8, &retlen, (char *)&uci) < 0)
-+ return -1;
-+ return 0;
-+}
-+
-+/*
-+ * format_chain: Format an invalid Virtual Unit chain. It frees all the Erase
-+ * Units in a Virtual Unit Chain, i.e. all the units are disconnected.
-+ *
-+ * Since the chain is invalid then we will have to erase it from its
-+ * head (normally for INFTL we go from the oldest). But if it has a
-+ * loop then there is no oldest...
-+ */
-+static void format_chain(struct INFTLrecord *inftl, unsigned int first_block)
-+{
-+ unsigned int block = first_block, block1;
-+
-+ printk(KERN_WARNING "INFTL: formatting chain at block %d\n",
-+ first_block);
-+
-+ for (;;) {
-+ block1 = inftl->PUtable[block];
-+
-+ printk(KERN_WARNING "INFTL: formatting block %d\n", block);
-+ if (INFTL_formatblock(inftl, block) < 0) {
-+ /*
-+ * Cannot format !!!! Mark it as Bad Unit,
-+ * FixMe: update the BadUnitTable on disk.
-+ */
-+ inftl->PUtable[block] = BLOCK_RESERVED;
-+ } else {
-+ inftl->PUtable[block] = BLOCK_FREE;
-+ }
-+
-+ /* Goto next block on the chain */
-+ block = block1;
-+
-+ if (block == BLOCK_NIL || block >= inftl->lastEUN)
-+ break;
-+ }
-+}
-+
-+void INFTL_dumptables(struct INFTLrecord *s)
-+{
-+ int i;
-+
-+ printk("-------------------------------------------"
-+ "----------------------------------\n");
-+
-+ printk("VUtable[%d] ->", s->nb_blocks);
-+ for (i = 0; i < s->nb_blocks; i++) {
-+ if ((i % 8) == 0)
-+ printk("\n%04x: ", i);
-+ printk("%04x ", s->VUtable[i]);
-+ }
-+
-+ printk("\n-------------------------------------------"
-+ "----------------------------------\n");
-+
-+ printk("PUtable[%d-%d=%d] ->", s->firstEUN, s->lastEUN, s->nb_blocks);
-+ for (i = 0; i <= s->lastEUN; i++) {
-+ if ((i % 8) == 0)
-+ printk("\n%04x: ", i);
-+ printk("%04x ", s->PUtable[i]);
-+ }
-+
-+ printk("\n-------------------------------------------"
-+ "----------------------------------\n");
-+
-+ printk("INFTL ->\n"
-+ " EraseSize = %d\n"
-+ " h/s/c = %d/%d/%d\n"
-+ " numvunits = %d\n"
-+ " firstEUN = %d\n"
-+ " lastEUN = %d\n"
-+ " numfreeEUNs = %d\n"
-+ " LastFreeEUN = %d\n"
-+ " nb_blocks = %d\n"
-+ " nb_boot_blocks = %d",
-+ s->EraseSize, s->heads, s->sectors, s->cylinders,
-+ s->numvunits, s->firstEUN, s->lastEUN, s->numfreeEUNs,
-+ s->LastFreeEUN, s->nb_blocks, s->nb_boot_blocks);
-+
-+ printk("\n-------------------------------------------"
-+ "----------------------------------\n");
-+}
-+
-+void INFTL_dumpVUchains(struct INFTLrecord *s)
-+{
-+ int logical, block, i;
-+
-+ printk("-------------------------------------------"
-+ "----------------------------------\n");
-+
-+ printk("INFTL Virtual Unit Chains:\n");
-+ for (logical = 0; logical < s->nb_blocks; logical++) {
-+ block = s->VUtable[logical];
-+ if (block > s->nb_blocks)
-+ continue;
-+ printk(" LOGICAL %d --> %d ", logical, block);
-+ for (i = 0; i < s->nb_blocks; i++) {
-+ if (s->PUtable[block] == BLOCK_NIL)
-+ break;
-+ block = s->PUtable[block];
-+ printk("%d ", block);
-+ }
-+ printk("\n");
-+ }
-+
-+ printk("-------------------------------------------"
-+ "----------------------------------\n");
-+}
-+
-+int INFTL_mount(struct INFTLrecord *s)
-+{
-+ unsigned int block, first_block, prev_block, last_block;
-+ unsigned int first_logical_block, logical_block, erase_mark;
-+ int chain_length, do_format_chain;
-+ struct inftl_unithead1 h0;
-+ struct inftl_unittail h1;
-+ int i, retlen;
-+ u8 *ANACtable, ANAC;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_mount(inftl=0x%x)\n", (int)s);
-+
-+ /* Search for INFTL MediaHeader and Spare INFTL Media Header */
-+ if (find_boot_record(s) < 0) {
-+ printk(KERN_WARNING "INFTL: could not find valid boot record?\n");
-+ return -1;
-+ }
-+
-+ /* Init the logical to physical table */
-+ for (i = 0; i < s->nb_blocks; i++)
-+ s->VUtable[i] = BLOCK_NIL;
-+
-+ logical_block = block = BLOCK_NIL;
-+
-+ /* Temporary buffer to store ANAC numbers. */
-+ ANACtable = kmalloc(s->nb_blocks * sizeof(u8), GFP_KERNEL);
-+ memset(ANACtable, 0, s->nb_blocks);
-+
-+ /*
-+ * First pass is to explore each physical unit, and construct the
-+ * virtual chains that exist (newest physical unit goes into VUtable).
-+ * Any block that is in any way invalid will be left in the
-+ * NOTEXPLORED state. Then at the end we will try to format it and
-+ * mark it as free.
-+ */
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 1, explore each unit\n");
-+ for (first_block = s->firstEUN; first_block <= s->lastEUN; first_block++) {
-+ if (s->PUtable[first_block] != BLOCK_NOTEXPLORED)
-+ continue;
-+
-+ do_format_chain = 0;
-+ first_logical_block = BLOCK_NIL;
-+ last_block = BLOCK_NIL;
-+ block = first_block;
-+
-+ for (chain_length = 0; ; chain_length++) {
-+
-+ if ((chain_length == 0) &&
-+ (s->PUtable[block] != BLOCK_NOTEXPLORED)) {
-+ /* Nothing to do here, onto next block */
-+ break;
-+ }
-+
-+ if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8,
-+ 8, &retlen, (char *)&h0) < 0 ||
-+ MTD_READOOB(s->mbd.mtd, block * s->EraseSize +
-+ 2 * SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0) {
-+ /* Should never happen? */
-+ do_format_chain++;
-+ break;
-+ }
-+
-+ logical_block = le16_to_cpu(h0.virtualUnitNo);
-+ prev_block = le16_to_cpu(h0.prevUnitNo);
-+ erase_mark = le16_to_cpu((h1.EraseMark | h1.EraseMark1));
-+ ANACtable[block] = h0.ANAC;
-+
-+ /* Previous block is relative to start of Partition */
-+ if (prev_block < s->nb_blocks)
-+ prev_block += s->firstEUN;
-+
-+ /* Already explored partial chain? */
-+ if (s->PUtable[block] != BLOCK_NOTEXPLORED) {
-+ /* Check if chain for this logical */
-+ if (logical_block == first_logical_block) {
-+ if (last_block != BLOCK_NIL)
-+ s->PUtable[last_block] = block;
-+ }
-+ break;
-+ }
-+
-+ /* Check for invalid block */
-+ if (erase_mark != ERASE_MARK) {
-+ printk(KERN_WARNING "INFTL: corrupt block %d "
-+ "in chain %d, chain length %d, erase "
-+ "mark 0x%x?\n", block, first_block,
-+ chain_length, erase_mark);
-+ /*
-+ * Assume end of chain, probably incomplete
-+ * fold/erase...
-+ */
-+ if (chain_length == 0)
-+ do_format_chain++;
-+ break;
-+ }
-+
-+ /* Check for it being free already then... */
-+ if ((logical_block == BLOCK_FREE) ||
-+ (logical_block == BLOCK_NIL)) {
-+ s->PUtable[block] = BLOCK_FREE;
-+ break;
-+ }
-+
-+ /* Sanity checks on block numbers */
-+ if ((logical_block >= s->nb_blocks) ||
-+ ((prev_block >= s->nb_blocks) &&
-+ (prev_block != BLOCK_NIL))) {
-+ if (chain_length > 0) {
-+ printk(KERN_WARNING "INFTL: corrupt "
-+ "block %d in chain %d?\n",
-+ block, first_block);
-+ do_format_chain++;
-+ }
-+ break;
-+ }
-+
-+ if (first_logical_block == BLOCK_NIL) {
-+ first_logical_block = logical_block;
-+ } else {
-+ if (first_logical_block != logical_block) {
-+ /* Normal for folded chain... */
-+ break;
-+ }
-+ }
-+
-+ /*
-+ * Current block is valid, so if we followed a virtual
-+ * chain to get here then we can set the previous
-+ * block pointer in our PUtable now. Then move onto
-+ * the previous block in the chain.
-+ */
-+ s->PUtable[block] = BLOCK_NIL;
-+ if (last_block != BLOCK_NIL)
-+ s->PUtable[last_block] = block;
-+ last_block = block;
-+ block = prev_block;
-+
-+ /* Check for end of chain */
-+ if (block == BLOCK_NIL)
-+ break;
-+
-+ /* Validate next block before following it... */
-+ if (block > s->lastEUN) {
-+ printk(KERN_WARNING "INFTL: invalid previous "
-+ "block %d in chain %d?\n", block,
-+ first_block);
-+ do_format_chain++;
-+ break;
-+ }
-+ }
-+
-+ if (do_format_chain) {
-+ format_chain(s, first_block);
-+ continue;
-+ }
-+
-+ /*
-+ * Looks like a valid chain then. It may not really be the
-+ * newest block in the chain, but it is the newest we have
-+ * found so far. We might update it in later iterations of
-+ * this loop if we find something newer.
-+ */
-+ s->VUtable[first_logical_block] = first_block;
-+ logical_block = BLOCK_NIL;
-+ }
-+
-+#ifdef CONFIG_MTD_DEBUG_VERBOSE
-+ if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
-+ INFTL_dumptables(s);
-+#endif
-+
-+ /*
-+ * Second pass, check for infinite loops in chains. These are
-+ * possible because we don't update the previous pointers when
-+ * we fold chains. No big deal, just fix them up in PUtable.
-+ */
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 2, validate virtual chains\n");
-+ for (logical_block = 0; logical_block < s->numvunits; logical_block++) {
-+ block = s->VUtable[logical_block];
-+ last_block = BLOCK_NIL;
-+
-+ /* Check for free/reserved/nil */
-+ if (block >= BLOCK_RESERVED)
-+ continue;
-+
-+ ANAC = ANACtable[block];
-+ for (i = 0; i < s->numvunits; i++) {
-+ if (s->PUtable[block] == BLOCK_NIL)
-+ break;
-+ if (s->PUtable[block] > s->lastEUN) {
-+ printk(KERN_WARNING "INFTL: invalid prev %d, "
-+ "in virtual chain %d\n",
-+ s->PUtable[block], logical_block);
-+ s->PUtable[block] = BLOCK_NIL;
-+
-+ }
-+ if (ANACtable[block] != ANAC) {
-+ /*
-+ * Chain must point back to itself. This is ok,
-+ * but we will need adjust the tables with this
-+ * newest block and oldest block.
-+ */
-+ s->VUtable[logical_block] = block;
-+ s->PUtable[last_block] = BLOCK_NIL;
-+ break;
-+ }
-+
-+ ANAC--;
-+ last_block = block;
-+ block = s->PUtable[block];
-+ }
-+
-+ if (i >= s->nb_blocks) {
-+ /*
-+ * Uhoo, infinite chain with valid ANACS!
-+ * Format whole chain...
-+ */
-+ format_chain(s, first_block);
-+ }
-+ }
-+
-+#ifdef CONFIG_MTD_DEBUG_VERBOSE
-+ if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
-+ INFTL_dumptables(s);
-+ if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
-+ INFTL_dumpVUchains(s);
-+#endif
-+
-+ /*
-+ * Third pass, format unreferenced blocks and init free block count.
-+ */
-+ s->numfreeEUNs = 0;
-+ s->LastFreeEUN = BLOCK_NIL;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 3, format unused blocks\n");
-+ for (block = s->firstEUN; block <= s->lastEUN; block++) {
-+ if (s->PUtable[block] == BLOCK_NOTEXPLORED) {
-+ printk("INFTL: unreferenced block %d, formatting it\n",
-+ block);
-+ if (INFTL_formatblock(s, block) < 0)
-+ s->PUtable[block] = BLOCK_RESERVED;
-+ else
-+ s->PUtable[block] = BLOCK_FREE;
-+ }
-+ if (s->PUtable[block] == BLOCK_FREE) {
-+ s->numfreeEUNs++;
-+ if (s->LastFreeEUN == BLOCK_NIL)
-+ s->LastFreeEUN = block;
-+ }
-+ }
-+
-+ kfree(ANACtable);
-+ return 0;
-+}
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/Config.in linux/drivers/mtd/maps/Config.in
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/Config.in 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/Config.in 2004-11-17 18:17:59.049312400 +0100
-@@ -1,17 +1,14 @@
- # drivers/mtd/maps/Config.in
-
--# $Id$
-+# $Id$
-
- mainmenu_option next_comment
-
- comment 'Mapping drivers for chip access'
-
--dep_tristate ' CFI Flash device in physical memory map' CONFIG_MTD_PHYSMAP $CONFIG_MTD_GEN_PROBE
--if [ "$CONFIG_MTD_PHYSMAP" = "y" -o "$CONFIG_MTD_PHYSMAP" = "m" ]; then
-- hex ' Physical start address of flash mapping' CONFIG_MTD_PHYSMAP_START 0x8000000
-- hex ' Physical length of flash mapping' CONFIG_MTD_PHYSMAP_LEN 0x4000000
-- int ' Bus width in octets' CONFIG_MTD_PHYSMAP_BUSWIDTH 2
--fi
-+bool ' Support for non-linear mappings of flash chips' CONFIG_MTD_COMPLEX_MAPPINGS
-+
-+bool ' CFI Flash device in physical memory map' CONFIG_MTD_PHYSMAP $CONFIG_MTD_GEN_PROBE
-
- if [ "$CONFIG_SPARC" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
- dep_tristate ' Sun Microsystems userflash support' CONFIG_MTD_SUN_UFLASH $CONFIG_MTD_CFI
-@@ -21,51 +18,68 @@
- dep_tristate ' CFI Flash device mapped on Photron PNC-2000' CONFIG_MTD_PNC2000 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS
- dep_tristate ' CFI Flash device mapped on AMD SC520 CDP' CONFIG_MTD_SC520CDP $CONFIG_MTD_CFI
- dep_tristate ' CFI Flash device mapped on AMD NetSc520' CONFIG_MTD_NETSC520 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS
-- dep_tristate ' CFI Flash device mapped on Arcom SBC-GXx boards' CONFIG_MTD_SBC_GXX $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS
-- dep_tristate ' CFI Flash device mapped on Arcom ELAN-104NC' CONFIG_MTD_ELAN_104NC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS
-+ dep_tristate ' CFI Flash device mapped on Arcom SBC-GXx boards' CONFIG_MTD_SBC_GXX $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS $CONFIG_MTD_COMPLEX_MAPPINGS
-+ dep_tristate ' CFI Flash device mapped on Arcom ELAN-104NC' CONFIG_MTD_ELAN_104NC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS $CONFIG_MTD_COMPLEX_MAPPINGS
- dep_tristate ' CFI Flash device mapped on DIL/Net PC' CONFIG_MTD_DILNETPC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS $CONFIG_MTD_CONCAT
- if [ "$CONFIG_MTD_DILNETPC" = "y" -o "$CONFIG_MTD_DILNETPC" = "m" ]; then
- hex ' Size of boot partition' CONFIG_MTD_DILNETPC_BOOTSIZE 0x80000
- fi
-- dep_tristate ' JEDEC Flash device mapped on Mixcom piggyback card' CONFIG_MTD_MIXMEM $CONFIG_MTD_JEDEC
-- dep_tristate ' JEDEC Flash device mapped on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC
-- dep_tristate ' JEDEC Flash device mapped on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC
-+ dep_tristate ' JEDEC Flash device mapped on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC $CONFIG_MTD_COMPLEX_MAPPINGS
-+ dep_tristate ' JEDEC Flash device mapped on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC $CONFIG_MTD_COMPLEX_MAPPINGS
- dep_tristate ' Flash device mapped with DOCCS on NatSemi SCx200' CONFIG_MTD_SCx200_DOCFLASH $CONFIG_MTD_CFI
- dep_tristate ' BIOS flash chip on Intel L440GX boards' CONFIG_MTD_L440GX $CONFIG_MTD_JEDECPROBE
- dep_tristate ' ROM connected to AMD76X southbridge' CONFIG_MTD_AMD76XROM $CONFIG_MTD_GEN_PROBE
-- dep_tristate ' ROM connected to Intel Hub Controller 2' CONFIG_MTD_ICH2ROM $CONFIG_MTD_JEDECPROBE
-+ dep_tristate ' ROM connected to Intel Hub Controller 2/3/4/5' CONFIG_MTD_ICHXROM $CONFIG_MTD_JEDECPROBE $CONFIG_MTD_COMPLEX_MAPPINGS
- dep_tristate ' CFI Flash device mapped on SnapGear/SecureEdge' CONFIG_MTD_NETtel $CONFIG_MTD_PARTITIONS
- dep_tristate ' BIOS flash chip on Intel SCB2 boards' CONFIG_MTD_SCB2_FLASH $CONFIG_MTD_GEN_PROBE
- fi
-
--if [ "$CONFIG_PPC" = "y" ]; then
-- dep_tristate ' CFI Flash device mapped on TQM8XXL' CONFIG_MTD_TQM8XXL $CONFIG_MTD_CFI $CONFIG_TQM8xxL
-+if [ "$CONFIG_PPC32" = "y" ]; then
-+ if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "y" ]; then
-+ dep_tristate ' Flash device on SBC8240' CONFIG_MTD_SBC8240 $CONFIG_MTD_JEDECPROBE
-+ fi
-+ if [ "$CONFIG_8xx" = "y" ]; then
-+ if [ "$CONFIG_TQM8xxL" = "y" ]; then
-+ dep_tristate ' CFI Flash device mapped on TQM8XXL' CONFIG_MTD_TQM8XXL $CONFIG_MTD_CFI
-+ fi
-+ if [ "$CONFIG_RPXLITE" = "y" -o "$CONFIG_RPXCLASSIC" = "y" ]; then
- dep_tristate ' CFI Flash device mapped on RPX Lite or CLLF' CONFIG_MTD_RPXLITE $CONFIG_MTD_CFI
-+ fi
-+ if [ "$CONFIG_MBX" = "y" ]; then
- dep_tristate ' System flash on MBX860 board' CONFIG_MTD_MBX860 $CONFIG_MTD_CFI
-+ fi
-+ if [ "$CONFIG_DBOX2" = "y" ]; then
- dep_tristate ' CFI Flash device mapped on D-Box2' CONFIG_MTD_DBOX2 $CONFIG_MTD_CFI
-+ fi
- dep_tristate ' CFI Flash device mapping on FlagaDM' CONFIG_MTD_CFI_FLAGADM $CONFIG_MTD_CFI
-- dep_tristate ' CFI Flash device mapped on IBM Redwood-4/5' CONFIG_MTD_REDWOOD $CONFIG_MTD_CFI
-+ fi
-+ if [ "$CONFIG_4xx" = "y" ]; then
-+ if [ "$CONFIG_40x" = "y" ]; then
-+ if [ "$CONFIG_REDWOOD_4" = "y" -o "$CONFIG_REDWOOD_5" = "y" -o "$CONFIG_REDWOOD_6" = "y" ]; then
-+ dep_tristate ' CFI Flash device mapped on IBM Redwood' CONFIG_MTD_REDWOOD $CONFIG_MTD_CFI
-+ fi
-+ dep_tristate ' CFI Flash device mapped on IBM Beech' CONFIG_MTD_BEECH $CONFIG_MTD_CFI $CONFIG_BEECH
-+ dep_tristate ' CFI Flash device mapped on IBM Arctic' CONFIG_MTD_ARCTIC $CONFIG_MTD_CFI $CONFIG_ARCTIC2
-+ fi
-+ if [ "$CONFIG_440" = "y" ]; then
-+ dep_tristate ' Flash devices mapped on IBM Ebony' CONFIG_MTD_EBONY $CONFIG_MTD_CFI $CONFIG_EBONY
-+ fi
-+ fi
- fi
-
--if [ "$CONFIG_MIPS" = "y" ]; then
-- dep_tristate ' Pb1000 MTD support' CONFIG_MTD_PB1000 $CONFIG_MIPS_PB1000
-- dep_tristate ' Pb1500 MTD support' CONFIG_MTD_PB1500 $CONFIG_MIPS_PB1500
-- dep_tristate ' Pb1100 MTD support' CONFIG_MTD_PB1100 $CONFIG_MIPS_PB1100
-- dep_tristate ' Bosporus MTD support' CONFIG_MTD_BOSPORUS $CONFIG_MIPS_BOSPORUS
-- dep_tristate ' XXS1500 boot flash device' CONFIG_MTD_XXS1500 $CONFIG_MIPS_XXS1500
-- dep_tristate ' MTX-1 flash device' CONFIG_MTD_MTX1 $CONFIG_MIPS_MTX1
-- if [ "$CONFIG_MTD_PB1500" = "y" -o "$CONFIG_MTD_PB1500" = "m" \
-- -o "$CONFIG_MTD_PB1100" = "y" -o "$CONFIG_MTD_PB1100" = "m" ]; then
-- bool ' Pb[15]00 boot flash device' CONFIG_MTD_PB1500_BOOT
-- bool ' Pb[15]00 user flash device (2nd 32MiB bank)' CONFIG_MTD_PB1500_USER
-+if [ "$CONFIG_MIPS" = "y" -o "$CONFIG_MIPS64" = "y" ]; then
-+ if [ "$CONFIG_MIPS_PB1000" = "y" -o "$CONFIG_MIPS_PB1100" = "y" -o "$CONFIG_MIPS_PB1500" = "y" ]; then
-+ tristate ' Pb1x00 MTD support' CONFIG_MTD_PB1XXX
-+ if [ "$CONFIG_MIPS_PB1500" = "y" -o "$CONFIG_MIPS_PB1100" = "m" ]; then
-+ bool ' Pb1x00 boot flash device' CONFIG_MTD_PB1500_BOOT
-+ bool ' Pb1x00 user flash device (2nd 32MiB bank)' CONFIG_MTD_PB1500_USER
-+ fi
- fi
- tristate ' Db1x00 MTD support' CONFIG_MTD_DB1X00
- if [ "$CONFIG_MTD_DB1X00" = "y" -o "$CONFIG_MTD_DB1X00" = "m" ]; then
- bool ' Db1x00 boot flash device' CONFIG_MTD_DB1X00_BOOT
- bool ' Db1x00 user flash device (2nd bank)' CONFIG_MTD_DB1X00_USER
- fi
-- dep_tristate ' Hydrogen 3 MTD support' CONFIG_MTD_HYDIII $CONFIG_MIPS_HYDROGEN3
-- dep_tristate ' Mirage MTD support' CONFIG_MTD_MIRAGE $CONFIG_MIPS_MIRAGE
- dep_tristate ' Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board' CONFIG_MTD_CSTM_MIPS_IXX $CONFIG_MTD_CFI $CONFIG_MTD_JEDEC $CONFIG_MTD_PARTITIONS
- if [ "$CONFIG_MTD_CSTM_MIPS_IXX" = "y" -o "$CONFIG_MTD_CSTM_MIPS_IXX" = "m" ]; then
- hex ' Physical start address of flash mapping' CONFIG_MTD_CSTM_MIPS_IXX_START 0x8000000
-@@ -73,7 +87,7 @@
- int ' Bus width in octets' CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH 2
- fi
- dep_tristate ' Momenco Ocelot boot flash device' CONFIG_MTD_OCELOT $CONFIG_MOMENCO_OCELOT
-- dep_tristate ' LASAT flash device' CONFIG_MTD_LASAT $CONFIG_MTD_CFI $CONFIG_LASAT
-+ dep_tristate ' LASAT flash device' CONFIG_MTD_LASAT $CONFIG_LASAT
- fi
-
- if [ "$CONFIG_SUPERH" = "y" ]; then
-@@ -85,21 +99,24 @@
- fi
-
- if [ "$CONFIG_ARM" = "y" ]; then
-- dep_tristate ' CFI Flash device mapped on Nora' CONFIG_MTD_NORA $CONFIG_MTD_CFI
- dep_tristate ' CFI Flash device mapped on ARM Integrator/P720T' CONFIG_MTD_ARM_INTEGRATOR $CONFIG_MTD_CFI
- dep_tristate ' Cirrus CDB89712 evaluation board mappings' CONFIG_MTD_CDB89712 $CONFIG_MTD_CFI $CONFIG_ARCH_CDB89712
- dep_tristate ' CFI Flash device mapped on StrongARM SA11x0' CONFIG_MTD_SA1100 $CONFIG_MTD_CFI $CONFIG_ARCH_SA1100 $CONFIG_MTD_PARTITIONS
-- dep_tristate ' CFI Flash device mapped on DC21285 Footbridge' CONFIG_MTD_DC21285 $CONFIG_MTD_CFI $CONFIG_ARCH_FOOTBRIDGE
-+ dep_tristate ' CFI Flash device mapped on DC21285 Footbridge' CONFIG_MTD_DC21285 $CONFIG_MTD_CFI $CONFIG_ARCH_FOOTBRIDGE $CONFIG_MTD_COMPLEX_MAPPINGS
- dep_tristate ' CFI Flash device mapped on the XScale IQ80310 board' CONFIG_MTD_IQ80310 $CONFIG_MTD_CFI $CONFIG_ARCH_IQ80310
-+ dep_tristate ' CFI Flash device mapped on the XScale Lubbock board' CONFIG_MTD_LUBBOCK $CONFIG_MTD_CFI $CONFIG_ARCH_LUBBOCK
-+ dep_tristate ' CFI Flash device mapped on XScale IXP425 systems' CONFIG_MTD_IXP425 $CONFIG_MTD_CFI $CONFIG_MTD_COMPLEX_MAPPINGS
- dep_tristate ' CFI Flash device mapped on Epxa10db' CONFIG_MTD_EPXA10DB $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS $CONFIG_ARCH_CAMELOT
- dep_tristate ' CFI Flash device mapped on the FortuNet board' CONFIG_MTD_FORTUNET $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS $CONFIG_SA1100_FORTUNET
- dep_tristate ' NV-RAM mapping AUTCPU12 board' CONFIG_MTD_AUTCPU12 $CONFIG_ARCH_AUTCPU12
- dep_tristate ' CFI Flash device mapped on EDB7312' CONFIG_MTD_EDB7312 $CONFIG_MTD_CFI
-+ dep_tristate ' CFI Flash device mapped on Hynix evaluation boards' CONFIG_MTD_H720X $CONFIG_MTD_CFI
- dep_tristate ' JEDEC Flash device mapped on impA7' CONFIG_MTD_IMPA7 $CONFIG_MTD_JEDECPROBE
- dep_tristate ' JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame' CONFIG_MTD_CEIVA $CONFIG_MTD_JEDECPROBE $CONFIG_ARCH_CEIVA
-+ dep_tristate ' NOR Flash device on TOTO board' CONFIG_MTD_NOR_TOTO $CONFIG_MTD $CONFIG_OMAP_TOTO
- fi
- if [ "$CONFIG_ALPHA" = "y" ]; then
-- dep_tristate ' Flash chip mapping on TSUNAMI' CONFIG_MTD_TSUNAMI $CONFIG_MTD_GENPROBE
-+ dep_tristate ' Flash chip mapping on TSUNAMI' CONFIG_MTD_TSUNAMI $CONFIG_MTD_GENPROBE $CONFIG_MTD_COMPLEX_MAPPINGS
- fi
-
- if [ "$CONFIG_UCLINUX" = "y" ]; then
-@@ -107,7 +124,7 @@
- fi
-
- # This needs CFI or JEDEC, depending on the cards found.
--dep_tristate ' PCI MTD driver' CONFIG_MTD_PCI $CONFIG_MTD $CONFIG_PCI
--dep_tristate ' PCMCIA MTD driver' CONFIG_MTD_PCMCIA $CONFIG_MTD $CONFIG_PCMCIA
-+dep_tristate ' PCI MTD driver' CONFIG_MTD_PCI $CONFIG_MTD $CONFIG_PCI $CONFIG_MTD_COMPLEX_MAPPINGS
-+dep_tristate ' PCMCIA MTD driver' CONFIG_MTD_PCMCIA $CONFIG_MTD $CONFIG_PCMCIA $CONFIG_MTD_COMPLEX_MAPPINGS
-
- endmenu
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/Makefile linux/drivers/mtd/maps/Makefile
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/Makefile 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/Makefile 2004-11-17 18:17:59.051312096 +0100
-@@ -1,12 +1,16 @@
- #
- # linux/drivers/maps/Makefile
- #
--# $Id$
-+# $Id$
-
--BELOW25 := $(shell echo $(PATCHLEVEL) | sed s/[1234]/y/)
--
--ifeq ($(BELOW25),y)
-+ifeq ($(PATCHLEVEL),4)
- O_TARGET := mapslink.o
-+export-objs := map_funcs.o
-+endif
-+
-+
-+ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y)
-+obj-$(CONFIG_MTD) += map_funcs.o
- endif
-
- # Chip mappings
-@@ -21,19 +25,13 @@
- obj-$(CONFIG_MTD_IQ80310) += iq80310.o
- obj-$(CONFIG_MTD_L440GX) += l440gx.o
- obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o
--obj-$(CONFIG_MTD_ICH2ROM) += ich2rom.o
-+obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o
- obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o
-+obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o
- obj-$(CONFIG_MTD_MBX860) += mbx860.o
--obj-$(CONFIG_MTD_NORA) += nora.o
- obj-$(CONFIG_MTD_CEIVA) += ceiva.o
- obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o
--ifneq ($(CONFIG_MTD_PHYSMAP),n)
-- ifeq ($(CONFIG_MTD_PHYSMAP_BUSWIDTH),8)
-- obj-$(CONFIG_MTD_PHYSMAP) += physmap64.o
-- else
-- obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
-- endif
--endif
-+obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
- obj-$(CONFIG_MTD_PNC2000) += pnc2000.o
- obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o
- obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o
-@@ -49,15 +47,9 @@
- obj-$(CONFIG_MTD_OCELOT) += ocelot.o
- obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
- obj-$(CONFIG_MTD_PCI) += pci.o
--obj-$(CONFIG_MTD_PB1000) += pb1xxx-flash.o
--obj-$(CONFIG_MTD_PB1100) += pb1xxx-flash.o
--obj-$(CONFIG_MTD_PB1500) += pb1xxx-flash.o
--obj-$(CONFIG_MTD_XXS1500) += xxs1500.o
--obj-$(CONFIG_MTD_MTX1) += mtx-1.o
--obj-$(CONFIG_MTD_LASAT) += lasat.o
-+obj-$(CONFIG_MTD_PB1XXX) += pb1xxx-flash.o
- obj-$(CONFIG_MTD_DB1X00) += db1x00-flash.o
--obj-$(CONFIG_MTD_HYDIII) += hydrogen3-flash.o
--obj-$(CONFIG_MTD_BOSPORUS) += pb1xxx-flash.o
-+obj-$(CONFIG_MTD_LASAT) += lasat.o
- obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o
- obj-$(CONFIG_MTD_EDB7312) += edb7312.o
- obj-$(CONFIG_MTD_IMPA7) += impa7.o
-@@ -66,6 +58,13 @@
- obj-$(CONFIG_MTD_UCLINUX) += uclinux.o
- obj-$(CONFIG_MTD_NETtel) += nettel.o
- obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o
--obj-$(CONFIG_MTD_MIRAGE) += mirage-flash.o
-+obj-$(CONFIG_MTD_EBONY) += ebony.o
-+obj-$(CONFIG_MTD_BEECH) += beech-mtd.o
-+obj-$(CONFIG_MTD_ARCTIC) += arctic-mtd.o
-+obj-$(CONFIG_MTD_H720X) += h720x-flash.o
-+obj-$(CONFIG_MTD_SBC8240) += sbc8240.o
-+obj-$(CONFIG_MTD_NOR_TOTO) += omap-toto-flash.o
-+obj-$(CONFIG_MTD_MPC1211) += mpc1211.o
-+obj-$(CONFIG_MTD_IXP425) += ixp425.o
-
--include $(TOPDIR)/Rules.make
-+-include $(TOPDIR)/Rules.make
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/amd76xrom.c linux/drivers/mtd/maps/amd76xrom.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/amd76xrom.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/amd76xrom.c 2004-11-17 18:17:59.052311944 +0100
-@@ -2,12 +2,13 @@
- * amd76xrom.c
- *
- * Normal mappings of chips in physical memory
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -16,77 +17,59 @@
- #include <linux/pci_ids.h>
-
-
-+#define xstr(s) str(s)
-+#define str(s) #s
-+#define MOD_NAME xstr(KBUILD_BASENAME)
-+
-+#define MTD_DEV_NAME_LENGTH 16
-+
- struct amd76xrom_map_info {
- struct map_info map;
- struct mtd_info *mtd;
- unsigned long window_addr;
- u32 window_start, window_size;
- struct pci_dev *pdev;
-+ struct resource window_rsrc;
-+ struct resource rom_rsrc;
-+ char mtd_name[MTD_DEV_NAME_LENGTH];
- };
-
--static __u8 amd76xrom_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--static __u16 amd76xrom_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
-
--static __u32 amd76xrom_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
-+static struct amd76xrom_map_info amd76xrom_map = {
-+ .map = {
-+ .name = MOD_NAME,
-+ .size = 0,
-+ .buswidth = 1,
-+ }
-+ /* remaining fields of structure are initialized to 0 */
-+};
-
--static void amd76xrom_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
-
--static void amd76xrom_write8(struct map_info *map, __u8 d, unsigned long adr)
-+static void amd76xrom_cleanup(struct amd76xrom_map_info *info)
- {
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
-+ u8 byte;
-
--static void amd76xrom_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
-+ /* Disable writes through the rom window */
-+ pci_read_config_byte(info->pdev, 0x40, &byte);
-+ pci_write_config_byte(info->pdev, 0x40, byte & ~1);
-
--static void amd76xrom_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
-+ if (info->mtd) {
-+ del_mtd_device(info->mtd);
-+ map_destroy(info->mtd);
-+ info->mtd = NULL;
-+ info->map.virt = 0;
-+ }
-+ if (info->rom_rsrc.parent)
-+ release_resource(&info->rom_rsrc);
-+ if (info->window_rsrc.parent)
-+ release_resource(&info->window_rsrc);
-
--static void amd76xrom_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
-+ if (info->window_addr) {
-+ iounmap((void *)(info->window_addr));
-+ info->window_addr = 0;
-+ }
- }
-
--static struct amd76xrom_map_info amd76xrom_map = {
-- map: {
-- name: "AMD76X rom",
-- size: 0,
-- buswidth: 1,
-- read8: amd76xrom_read8,
-- read16: amd76xrom_read16,
-- read32: amd76xrom_read32,
-- copy_from: amd76xrom_copy_from,
-- write8: amd76xrom_write8,
-- write16: amd76xrom_write16,
-- write32: amd76xrom_write32,
-- copy_to: amd76xrom_copy_to,
-- /* The standard rom socket is for single power supply chips
-- * that don't have an extra vpp.
-- */
-- },
-- mtd: 0,
-- window_addr: 0,
--};
-
- static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
- const struct pci_device_id *ent)
-@@ -97,6 +80,10 @@
- u8 segen_bits;
- };
- static struct rom_window rom_window[] = {
-+ /*
-+ * Need the 5MiB window for chips that have block lock/unlock
-+ * registers located below 4MiB window.
-+ */
- { 0xffb00000, 5*1024*1024, (1<<7) | (1<<6), },
- { 0xffc00000, 4*1024*1024, (1<<7), },
- { 0xffff0000, 64*1024, 0 },
-@@ -112,19 +99,29 @@
- int i;
- u32 rom_size;
-
-+ info->pdev = pdev;
- window = &rom_window[0];
--#if 0
-- while(window->size) {
-- if (request_mem_region(window->start, window->size, "amd76xrom")) {
-- break;
-- }
-- window++;
-- }
-- if (!window->size) {
-- printk(KERN_ERR "amd76xrom: cannot reserve rom window\n");
-- goto err_out_none;
-+
-+ while (window->size) {
-+ /*
-+ * Try to reserve the window mem region. If this fails then
-+ * it is likely due to a fragment of the window being
-+ * "reseved" by the BIOS. In the case that the
-+ * request_mem_region() fails then once the rom size is
-+ * discovered we will try to reserve the unreserved fragment.
-+ */
-+ info->window_rsrc.name = MOD_NAME;
-+ info->window_rsrc.start = window->start;
-+ info->window_rsrc.end = window->start + window->size - 1;
-+ info->window_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-+ if (request_resource(&iomem_resource, &info->window_rsrc)) {
-+ info->window_rsrc.parent = NULL;
-+ printk(KERN_ERR MOD_NAME
-+ " %s(): Unable to register resource"
-+ " 0x%.08lx-0x%.08lx - kernel bug?\n",
-+ __func__,
-+ info->window_rsrc.start, info->window_rsrc.end);
- }
--#endif
-
- /* Enable the selected rom window */
- pci_read_config_byte(pdev, 0x43, &byte);
-@@ -136,49 +133,94 @@
-
- /* FIXME handle registers 0x80 - 0x8C the bios region locks */
-
-- printk(KERN_NOTICE "amd76xrom window : %x at %x\n",
-+ printk(KERN_NOTICE MOD_NAME " window : %x at %x\n",
- window->size, window->start);
- /* For write accesses caches are useless */
-- info->window_addr = (unsigned long)ioremap_nocache(window->start, window->size);
-+ info->window_addr =
-+ (unsigned long)ioremap_nocache(window->start,
-+ window->size);
-
- if (!info->window_addr) {
- printk(KERN_ERR "Failed to ioremap\n");
-- goto err_out_free_mmio_region;
-+ continue;
- }
-- info->mtd = 0;
-+
-+ info->mtd = NULL;
-+
- for(i = 0; (rom_size = rom_probe_sizes[i]); i++) {
- char **chip_type;
- if (rom_size > window->size) {
- continue;
- }
-- info->map.map_priv_1 =
-+ info->map.phys = window->start + window->size - rom_size;
-+ info->map.virt =
- info->window_addr + window->size - rom_size;
- info->map.size = rom_size;
-+ simple_map_init(&info->map);
- chip_type = rom_probe_types;
- for(; !info->mtd && *chip_type; chip_type++) {
- info->mtd = do_map_probe(*chip_type, &amd76xrom_map.map);
- }
-- if (info->mtd) {
-- break;
-- }
-+ if (info->mtd) goto found_mtd;
- }
-- if (!info->mtd) {
-- goto err_out_iounmap;
-+ iounmap((void *)(info->window_addr));
-+ info->window_addr = 0;
-+
-+ /* Disable writes through the rom window */
-+ pci_read_config_byte(pdev, 0x40, &byte);
-+ pci_write_config_byte(pdev, 0x40, byte & ~1);
-+
-+ window++;
- }
-- printk(KERN_NOTICE "amd76xrom chip at offset: %x\n",
-+ goto failed;
-+
-+ found_mtd:
-+ printk(KERN_NOTICE MOD_NAME " chip at offset: 0x%x\n",
- window->size - rom_size);
-
-- info->mtd->module = THIS_MODULE;
-+ info->mtd->owner = THIS_MODULE;
-+
-+ if (!info->window_rsrc.parent) {
-+ /* failed to reserve entire window - try fragments */
-+ info->window_rsrc.name = MOD_NAME;
-+ info->window_rsrc.start = window->start;
-+ info->window_rsrc.end = window->start + window->size - rom_size - 1;
-+ info->window_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-+ if (request_resource(&iomem_resource, &info->window_rsrc)) {
-+ printk(KERN_ERR MOD_NAME
-+ ": cannot reserve window resource fragment\n");
-+ goto failed;
-+ }
-+ }
-+
- add_mtd_device(info->mtd);
- info->window_start = window->start;
- info->window_size = window->size;
-+
-+ if (info->window_rsrc.parent) {
-+ /*
-+ * Registering the MTD device in iomem may not be possible
-+ * if there is a BIOS "reserved" and BUSY range. If this
-+ * fails then continue anyway.
-+ */
-+ snprintf(info->mtd_name, MTD_DEV_NAME_LENGTH,
-+ "mtd%d", info->mtd->index);
-+
-+ info->rom_rsrc.name = info->mtd_name;
-+ info->rom_rsrc.start = window->start + window->size - rom_size;
-+ info->rom_rsrc.end = window->start + window->size - 1;
-+ info->rom_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-+ if (request_resource(&info->window_rsrc, &info->rom_rsrc)) {
-+ printk(KERN_ERR MOD_NAME
-+ ": cannot reserve MTD resource\n");
-+ info->rom_rsrc.parent = NULL;
-+ }
-+ }
-+
- return 0;
-
--err_out_iounmap:
-- iounmap((void *)(info->window_addr));
--err_out_free_mmio_region:
-- release_mem_region(window->start, window->size);
--err_out_none:
-+ failed:
-+ amd76xrom_cleanup(info);
- return -ENODEV;
- }
-
-@@ -186,21 +228,8 @@
- static void __devexit amd76xrom_remove_one (struct pci_dev *pdev)
- {
- struct amd76xrom_map_info *info = &amd76xrom_map;
-- u8 byte;
--
-- del_mtd_device(info->mtd);
-- map_destroy(info->mtd);
-- info->mtd = 0;
-- info->map.map_priv_1 = 0;
--
-- iounmap((void *)(info->window_addr));
-- info->window_addr = 0;
--
-- /* Disable writes through the rom window */
-- pci_read_config_byte(pdev, 0x40, &byte);
-- pci_write_config_byte(pdev, 0x40, byte & ~1);
-
-- release_mem_region(info->window_start, info->window_size);
-+ amd76xrom_cleanup(info);
- }
-
- static struct pci_device_id amd76xrom_pci_tbl[] __devinitdata = {
-@@ -208,6 +237,7 @@
- PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7440,
- PCI_ANY_ID, PCI_ANY_ID, },
-+ { PCI_VENDOR_ID_AMD, 0x7468 }, /* amd8111 support */
- { 0, }
- };
-
-@@ -215,10 +245,10 @@
-
- #if 0
- static struct pci_driver amd76xrom_driver = {
-- name: "amd76xrom",
-- id_table: amd76xrom_pci_tbl,
-- probe: amd76xrom_init_one,
-- remove: amd76xrom_remove_one,
-+ .name = MOD_NAME,
-+ .id_table = amd76xrom_pci_tbl,
-+ .probe = amd76xrom_init_one,
-+ .remove = amd76xrom_remove_one,
- };
- #endif
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/arctic-mtd.c linux/drivers/mtd/maps/arctic-mtd.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/arctic-mtd.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/arctic-mtd.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,135 @@
-+/*
-+ * $Id$
-+ *
-+ * drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for
-+ * IBM 405LP Arctic boards.
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Copyright (C) 2002, International Business Machines Corporation
-+ * All Rights Reserved.
-+ *
-+ * Bishop Brock
-+ * IBM Research, Austin Center for Low-Power Computing
-+ * bcbrock@us.ibm.com
-+ * March 2002
-+ *
-+ * modified for Arctic by,
-+ * David Gibson
-+ * IBM OzLabs, Canberra, Australia
-+ * <arctic@gibson.dropbear.id.au>
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/init.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+
-+#include <asm/io.h>
-+#include <asm/ibm4xx.h>
-+
-+/*
-+ * 0 : 0xFE00 0000 - 0xFEFF FFFF : Filesystem 1 (16MiB)
-+ * 1 : 0xFF00 0000 - 0xFF4F FFFF : kernel (5.12MiB)
-+ * 2 : 0xFF50 0000 - 0xFFF5 FFFF : Filesystem 2 (10.624MiB) (if non-XIP)
-+ * 3 : 0xFFF6 0000 - 0xFFFF FFFF : PIBS Firmware (640KiB)
-+ */
-+
-+#define FFS1_SIZE 0x01000000 /* 16MiB */
-+#define KERNEL_SIZE 0x00500000 /* 5.12MiB */
-+#define FFS2_SIZE 0x00a60000 /* 10.624MiB */
-+#define FIRMWARE_SIZE 0x000a0000 /* 640KiB */
-+
-+
-+#define NAME "Arctic Linux Flash"
-+#define PADDR SUBZERO_BOOTFLASH_PADDR
-+#define BUSWIDTH 2
-+#define SIZE SUBZERO_BOOTFLASH_SIZE
-+#define PARTITIONS 4
-+
-+/* Flash memories on these boards are memory resources, accessed big-endian. */
-+
-+{
-+ /* do nothing for now */
-+}
-+
-+static struct map_info arctic_mtd_map = {
-+ .name = NAME,
-+ .size = SIZE,
-+ .buswidth = BUSWIDTH,
-+ .phys = PADDR,
-+};
-+
-+static struct mtd_info *arctic_mtd;
-+
-+static struct mtd_partition arctic_partitions[PARTITIONS] = {
-+ { .name = "Filesystem",
-+ .size = FFS1_SIZE,
-+ .offset = 0,},
-+ { .name = "Kernel",
-+ .size = KERNEL_SIZE,
-+ .offset = FFS1_SIZE,},
-+ { .name = "Filesystem",
-+ .size = FFS2_SIZE,
-+ .offset = FFS1_SIZE + KERNEL_SIZE,},
-+ { .name = "Firmware",
-+ .size = FIRMWARE_SIZE,
-+ .offset = SUBZERO_BOOTFLASH_SIZE - FIRMWARE_SIZE,},
-+};
-+
-+static int __init
-+init_arctic_mtd(void)
-+{
-+ printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
-+
-+ arctic_mtd_map.virt = (unsigned long) ioremap(PADDR, SIZE);
-+
-+ if (!arctic_mtd_map.virt) {
-+ printk("%s: failed to ioremap 0x%x\n", NAME, PADDR);
-+ return -EIO;
-+ }
-+ simple_map_init(&arctic_mtd_map);
-+
-+ printk("%s: probing %d-bit flash bus\n", NAME, BUSWIDTH * 8);
-+ arctic_mtd = do_map_probe("cfi_probe", &arctic_mtd_map);
-+
-+ if (!arctic_mtd)
-+ return -ENXIO;
-+
-+ arctic_mtd->owner = THIS_MODULE;
-+
-+ return add_mtd_partitions(arctic_mtd, arctic_partitions, PARTITIONS);
-+}
-+
-+static void __exit
-+cleanup_arctic_mtd(void)
-+{
-+ if (arctic_mtd) {
-+ del_mtd_partitions(arctic_mtd);
-+ map_destroy(arctic_mtd);
-+ iounmap((void *) arctic_mtd_map.virt);
-+ }
-+}
-+
-+module_init(init_arctic_mtd);
-+module_exit(cleanup_arctic_mtd);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("David Gibson <arctic@gibson.dropbear.id.au>");
-+MODULE_DESCRIPTION("MTD map and partitions for IBM 405LP Arctic boards");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/autcpu12-nvram.c linux/drivers/mtd/maps/autcpu12-nvram.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/autcpu12-nvram.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/autcpu12-nvram.c 2004-11-17 18:17:59.059310880 +0100
-@@ -2,7 +2,7 @@
- * NV-RAM memory access on autcpu12
- * (C) 2002 Thomas Gleixner (gleixner@autronix.de)
- *
-- * $Id$
-+ * $Id$
- *
- * 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
-@@ -24,6 +24,7 @@
- #include <linux/types.h>
- #include <linux/kernel.h>
- #include <linux/ioport.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <asm/sizes.h>
- #include <asm/hardware.h>
-@@ -32,80 +33,27 @@
- #include <linux/mtd/map.h>
- #include <linux/mtd/partitions.h>
-
--__u8 autcpu12_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 autcpu12_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 autcpu12_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void autcpu12_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void autcpu12_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void autcpu12_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void autcpu12_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void autcpu12_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- while(len) {
-- __raw_writeb(*(unsigned char *) from, map->map_priv_1 + to);
-- from++;
-- to++;
-- len--;
-- }
--}
-
- static struct mtd_info *sram_mtd;
-
- struct map_info autcpu12_sram_map = {
-- name: "SRAM",
-- size: 32768,
-- buswidth: 8,
-- read8: autcpu12_read8,
-- read16: autcpu12_read16,
-- read32: autcpu12_read32,
-- copy_from: autcpu12_copy_from,
-- write8: autcpu12_write8,
-- write16: autcpu12_write16,
-- write32: autcpu12_write32,
-- copy_to: autcpu12_copy_to
-+ .name = "SRAM",
-+ .size = 32768,
-+ .buswidth = 4,
-+ .phys = 0x12000000,
- };
-
- static int __init init_autcpu12_sram (void)
- {
- int err, save0, save1;
-
-- autcpu12_sram_map.map_priv_1 = (unsigned long)ioremap(0x12000000, SZ_128K);
-- if (!autcpu12_sram_map.map_priv_1) {
-+ autcpu12_sram_map.virt = (unsigned long)ioremap(0x12000000, SZ_128K);
-+ if (!autcpu12_sram_map.virt) {
- printk("Failed to ioremap autcpu12 NV-RAM space\n");
- err = -EIO;
- goto out;
- }
-+ simple_map_init(&autcpu_sram_map);
-
- /*
- * Check for 32K/128K
-@@ -115,20 +63,20 @@
- * Read and check result on ofs 0x0
- * Restore contents
- */
-- save0 = autcpu12_read32(&autcpu12_sram_map,0);
-- save1 = autcpu12_read32(&autcpu12_sram_map,0x10000);
-- autcpu12_write32(&autcpu12_sram_map,~save0,0x10000);
-+ save0 = map_read32(&autcpu12_sram_map,0);
-+ save1 = map_read32(&autcpu12_sram_map,0x10000);
-+ map_write32(&autcpu12_sram_map,~save0,0x10000);
- /* if we find this pattern on 0x0, we have 32K size
- * restore contents and exit
- */
-- if ( autcpu12_read32(&autcpu12_sram_map,0) != save0) {
-- autcpu12_write32(&autcpu12_sram_map,save0,0x0);
-+ if ( map_read32(&autcpu12_sram_map,0) != save0) {
-+ map_write32(&autcpu12_sram_map,save0,0x0);
- goto map;
- }
- /* We have a 128K found, restore 0x10000 and set size
- * to 128K
- */
-- autcpu12_write32(&autcpu12_sram_map,save1,0x10000);
-+ ma[_write32(&autcpu12_sram_map,save1,0x10000);
- autcpu12_sram_map.size = SZ_128K;
-
- map:
-@@ -139,7 +87,7 @@
- goto out_ioremap;
- }
-
-- sram_mtd->module = THIS_MODULE;
-+ sram_mtd->owner = THIS_MODULE;
- sram_mtd->erasesize = 16;
-
- if (add_mtd_device(sram_mtd)) {
-@@ -148,7 +96,7 @@
- goto out_probe;
- }
-
-- printk("NV-RAM device size %ldK registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K);
-+ printk("NV-RAM device size %ldKiB registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K);
-
- return 0;
-
-@@ -157,7 +105,7 @@
- sram_mtd = 0;
-
- out_ioremap:
-- iounmap((void *)autcpu12_sram_map.map_priv_1);
-+ iounmap((void *)autcpu12_sram_map.virt);
- out:
- return err;
- }
-@@ -167,7 +115,7 @@
- if (sram_mtd) {
- del_mtd_device(sram_mtd);
- map_destroy(sram_mtd);
-- iounmap((void *)autcpu12_sram_map.map_priv_1);
-+ iounmap((void *)autcpu12_sram_map.virt);
- }
- }
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/beech-mtd.c linux/drivers/mtd/maps/beech-mtd.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/beech-mtd.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/beech-mtd.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,112 @@
-+/*
-+ * $Id$
-+ *
-+ * drivers/mtd/maps/beech-mtd.c MTD mappings and partition tables for
-+ * IBM 405LP Beech boards.
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Copyright (C) 2002, International Business Machines Corporation
-+ * All Rights Reserved.
-+ *
-+ * Bishop Brock
-+ * IBM Research, Austin Center for Low-Power Computing
-+ * bcbrock@us.ibm.com
-+ * March 2002
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/init.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+
-+#include <asm/io.h>
-+#include <asm/ibm4xx.h>
-+
-+#define NAME "Beech Linux Flash"
-+#define PADDR BEECH_BIGFLASH_PADDR
-+#define SIZE BEECH_BIGFLASH_SIZE
-+#define BUSWIDTH 1
-+
-+/* Flash memories on these boards are memory resources, accessed big-endian. */
-+
-+
-+static struct map_info beech_mtd_map = {
-+ .name = NAME,
-+ .size = SIZE,
-+ .buswidth = BUSWIDTH,
-+ .phys = PADDR
-+};
-+
-+static struct mtd_info *beech_mtd;
-+
-+static struct mtd_partition beech_partitions[2] = {
-+ {
-+ .name = "Linux Kernel",
-+ .size = BEECH_KERNEL_SIZE,
-+ .offset = BEECH_KERNEL_OFFSET
-+ }, {
-+ .name = "Free Area",
-+ .size = BEECH_FREE_AREA_SIZE,
-+ .offset = BEECH_FREE_AREA_OFFSET
-+ }
-+};
-+
-+static int __init
-+init_beech_mtd(void)
-+{
-+ printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
-+
-+ beech_mtd_map.virt = (unsigned long) ioremap(PADDR, SIZE);
-+
-+ if (!beech_mtd_map.virt) {
-+ printk("%s: failed to ioremap 0x%x\n", NAME, PADDR);
-+ return -EIO;
-+ }
-+
-+ simple_map_init(&beech_mtd_map);
-+
-+ printk("%s: probing %d-bit flash bus\n", NAME, BUSWIDTH * 8);
-+ beech_mtd = do_map_probe("cfi_probe", &beech_mtd_map);
-+
-+ if (!beech_mtd)
-+ return -ENXIO;
-+
-+ beech_mtd->owner = THIS_MODULE;
-+
-+ return add_mtd_partitions(beech_mtd, beech_partitions, 2);
-+}
-+
-+static void __exit
-+cleanup_beech_mtd(void)
-+{
-+ if (beech_mtd) {
-+ del_mtd_partitions(beech_mtd);
-+ map_destroy(beech_mtd);
-+ iounmap((void *) beech_mtd_map.virt);
-+ }
-+}
-+
-+module_init(init_beech_mtd);
-+module_exit(cleanup_beech_mtd);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Bishop Brock <bcbrock@us.ibm.com>");
-+MODULE_DESCRIPTION("MTD map and partitions for IBM 405LP Beech boards");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/cdb89712.c linux/drivers/mtd/maps/cdb89712.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/cdb89712.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/cdb89712.c 2004-11-17 18:17:59.061310576 +0100
-@@ -1,13 +1,14 @@
- /*
- * Flash on Cirrus CDB89712
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
- #include <linux/ioport.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <asm/arch/hardware.h>
- #include <linux/mtd/mtd.h>
-@@ -16,77 +17,21 @@
-
-
-
--__u8 cdb89712_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 cdb89712_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 cdb89712_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void cdb89712_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void cdb89712_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void cdb89712_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void cdb89712_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- // printk ("cdb89712_copy_from: 0x%x@0x%x -> 0x%x\n", len, from, to);
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void cdb89712_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- while(len) {
-- __raw_writeb(*(unsigned char *) from, map->map_priv_1 + to);
-- from++;
-- to++;
-- len--;
-- }
--}
--
-
- static struct mtd_info *flash_mtd;
-
- struct map_info cdb89712_flash_map = {
-- name: "flash",
-- size: FLASH_SIZE,
-- buswidth: FLASH_WIDTH,
-- read8: cdb89712_read8,
-- read16: cdb89712_read16,
-- read32: cdb89712_read32,
-- copy_from: cdb89712_copy_from,
-- write8: cdb89712_write8,
-- write16: cdb89712_write16,
-- write32: cdb89712_write32,
-- copy_to: cdb89712_copy_to
-+ .name = "flash",
-+ .size = FLASH_SIZE,
-+ .buswidth = FLASH_WIDTH,
-+ .phys = FLASH_START,
- };
-
- struct resource cdb89712_flash_resource = {
-- name: "Flash",
-- start: FLASH_START,
-- end: FLASH_START + FLASH_SIZE - 1,
-- flags: IORESOURCE_IO | IORESOURCE_BUSY,
-+ .name = "Flash",
-+ .start = FLASH_START,
-+ .end = FLASH_START + FLASH_SIZE - 1,
-+ .flags = IORESOURCE_IO | IORESOURCE_BUSY,
- };
-
- static int __init init_cdb89712_flash (void)
-@@ -99,13 +44,13 @@
- goto out;
- }
-
-- cdb89712_flash_map.map_priv_1 = (unsigned long)ioremap(FLASH_START, FLASH_SIZE);
-- if (!cdb89712_flash_map.map_priv_1) {
-+ cdb89712_flash_map.virt = (unsigned long)ioremap(FLASH_START, FLASH_SIZE);
-+ if (!cdb89712_flash_map.virt) {
- printk(KERN_NOTICE "Failed to ioremap Cdb89712 FLASH space\n");
- err = -EIO;
- goto out_resource;
- }
--
-+ simple_map_init(&cdb89712_flash_map);
- flash_mtd = do_map_probe("cfi_probe", &cdb89712_flash_map);
- if (!flash_mtd) {
- flash_mtd = do_map_probe("map_rom", &cdb89712_flash_map);
-@@ -118,7 +63,7 @@
- goto out_ioremap;
- }
-
-- flash_mtd->module = THIS_MODULE;
-+ flash_mtd->owner = THIS_MODULE;
-
- if (add_mtd_device(flash_mtd)) {
- printk("FLASH device addition failed\n");
-@@ -132,7 +77,7 @@
- map_destroy(flash_mtd);
- flash_mtd = 0;
- out_ioremap:
-- iounmap((void *)cdb89712_flash_map.map_priv_1);
-+ iounmap((void *)cdb89712_flash_map.virt);
- out_resource:
- release_resource (&cdb89712_flash_resource);
- out:
-@@ -146,24 +91,17 @@
- static struct mtd_info *sram_mtd;
-
- struct map_info cdb89712_sram_map = {
-- name: "SRAM",
-- size: SRAM_SIZE,
-- buswidth: SRAM_WIDTH,
-- read8: cdb89712_read8,
-- read16: cdb89712_read16,
-- read32: cdb89712_read32,
-- copy_from: cdb89712_copy_from,
-- write8: cdb89712_write8,
-- write16: cdb89712_write16,
-- write32: cdb89712_write32,
-- copy_to: cdb89712_copy_to
-+ .name = "SRAM",
-+ .size = SRAM_SIZE,
-+ .buswidth = SRAM_WIDTH,
-+ .phys = SRAM_START,
- };
-
- struct resource cdb89712_sram_resource = {
-- name: "SRAM",
-- start: SRAM_START,
-- end: SRAM_START + SRAM_SIZE - 1,
-- flags: IORESOURCE_IO | IORESOURCE_BUSY,
-+ .name = "SRAM",
-+ .start = SRAM_START,
-+ .end = SRAM_START + SRAM_SIZE - 1,
-+ .flags = IORESOURCE_IO | IORESOURCE_BUSY,
- };
-
- static int __init init_cdb89712_sram (void)
-@@ -176,13 +114,13 @@
- goto out;
- }
-
-- cdb89712_sram_map.map_priv_1 = (unsigned long)ioremap(SRAM_START, SRAM_SIZE);
-- if (!cdb89712_sram_map.map_priv_1) {
-+ cdb89712_sram_map.virt = (unsigned long)ioremap(SRAM_START, SRAM_SIZE);
-+ if (!cdb89712_sram_map.virt) {
- printk(KERN_NOTICE "Failed to ioremap Cdb89712 SRAM space\n");
- err = -EIO;
- goto out_resource;
- }
--
-+ simple_map_init(&cdb89712_sram_map);
- sram_mtd = do_map_probe("map_ram", &cdb89712_sram_map);
- if (!sram_mtd) {
- printk("SRAM probe failed\n");
-@@ -190,7 +128,7 @@
- goto out_ioremap;
- }
-
-- sram_mtd->module = THIS_MODULE;
-+ sram_mtd->owner = THIS_MODULE;
- sram_mtd->erasesize = 16;
-
- if (add_mtd_device(sram_mtd)) {
-@@ -205,7 +143,7 @@
- map_destroy(sram_mtd);
- sram_mtd = 0;
- out_ioremap:
-- iounmap((void *)cdb89712_sram_map.map_priv_1);
-+ iounmap((void *)cdb89712_sram_map.virt);
- out_resource:
- release_resource (&cdb89712_sram_resource);
- out:
-@@ -221,20 +159,17 @@
- static struct mtd_info *bootrom_mtd;
-
- struct map_info cdb89712_bootrom_map = {
-- name: "BootROM",
-- size: BOOTROM_SIZE,
-- buswidth: BOOTROM_WIDTH,
-- read8: cdb89712_read8,
-- read16: cdb89712_read16,
-- read32: cdb89712_read32,
-- copy_from: cdb89712_copy_from,
-+ .name = "BootROM",
-+ .size = BOOTROM_SIZE,
-+ .buswidth = BOOTROM_WIDTH,
-+ .phys = BOOTROM_START,
- };
-
- struct resource cdb89712_bootrom_resource = {
-- name: "BootROM",
-- start: BOOTROM_START,
-- end: BOOTROM_START + BOOTROM_SIZE - 1,
-- flags: IORESOURCE_IO | IORESOURCE_BUSY,
-+ .name = "BootROM",
-+ .start = BOOTROM_START,
-+ .end = BOOTROM_START + BOOTROM_SIZE - 1,
-+ .flags = IORESOURCE_IO | IORESOURCE_BUSY,
- };
-
- static int __init init_cdb89712_bootrom (void)
-@@ -247,13 +182,13 @@
- goto out;
- }
-
-- cdb89712_bootrom_map.map_priv_1 = (unsigned long)ioremap(BOOTROM_START, BOOTROM_SIZE);
-- if (!cdb89712_bootrom_map.map_priv_1) {
-+ cdb89712_bootrom_map.virt = (unsigned long)ioremap(BOOTROM_START, BOOTROM_SIZE);
-+ if (!cdb89712_bootrom_map.virt) {
- printk(KERN_NOTICE "Failed to ioremap Cdb89712 BootROM space\n");
- err = -EIO;
- goto out_resource;
- }
--
-+ simple_map_init(&cdb89712_bootrom_map);
- bootrom_mtd = do_map_probe("map_rom", &cdb89712_bootrom_map);
- if (!bootrom_mtd) {
- printk("BootROM probe failed\n");
-@@ -261,7 +196,7 @@
- goto out_ioremap;
- }
-
-- bootrom_mtd->module = THIS_MODULE;
-+ bootrom_mtd->owner = THIS_MODULE;
- bootrom_mtd->erasesize = 0x10000;
-
- if (add_mtd_device(bootrom_mtd)) {
-@@ -276,7 +211,7 @@
- map_destroy(bootrom_mtd);
- bootrom_mtd = 0;
- out_ioremap:
-- iounmap((void *)cdb89712_bootrom_map.map_priv_1);
-+ iounmap((void *)cdb89712_bootrom_map.virt);
- out_resource:
- release_resource (&cdb89712_bootrom_resource);
- out:
-@@ -306,21 +241,21 @@
- if (sram_mtd) {
- del_mtd_device(sram_mtd);
- map_destroy(sram_mtd);
-- iounmap((void *)cdb89712_sram_map.map_priv_1);
-+ iounmap((void *)cdb89712_sram_map.virt);
- release_resource (&cdb89712_sram_resource);
- }
-
- if (flash_mtd) {
- del_mtd_device(flash_mtd);
- map_destroy(flash_mtd);
-- iounmap((void *)cdb89712_flash_map.map_priv_1);
-+ iounmap((void *)cdb89712_flash_map.virt);
- release_resource (&cdb89712_flash_resource);
- }
-
- if (bootrom_mtd) {
- del_mtd_device(bootrom_mtd);
- map_destroy(bootrom_mtd);
-- iounmap((void *)cdb89712_bootrom_map.map_priv_1);
-+ iounmap((void *)cdb89712_bootrom_map.virt);
- release_resource (&cdb89712_bootrom_resource);
- }
- }
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/ceiva.c linux/drivers/mtd/maps/ceiva.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/ceiva.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/ceiva.c 2004-11-17 18:17:59.063310272 +0100
-@@ -11,7 +11,7 @@
- *
- * (C) 2000 Nicolas Pitre <nico@cam.org>
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
-@@ -19,6 +19,7 @@
- #include <linux/types.h>
- #include <linux/ioport.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -31,62 +32,10 @@
- #include <asm/sizes.h>
-
- /*
-- * This isnt complete yet, so...
-+ * This isn't complete yet, so...
- */
- #define CONFIG_MTD_CEIVA_STATICMAP
-
--static __u8 clps_read8(struct map_info *map, unsigned long ofs)
--{
-- return readb(map->map_priv_1 + ofs);
--}
--
--static __u16 clps_read16(struct map_info *map, unsigned long ofs)
--{
-- return readw(map->map_priv_1 + ofs);
--}
--
--static __u32 clps_read32(struct map_info *map, unsigned long ofs)
--{
-- return readl(map->map_priv_1 + ofs);
--}
--
--static void clps_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy(to, (void *)(map->map_priv_1 + from), len);
--}
--
--static void clps_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- writeb(d, map->map_priv_1 + adr);
--}
--
--static void clps_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- writew(d, map->map_priv_1 + adr);
--}
--
--static void clps_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- writel(d, map->map_priv_1 + adr);
--}
--
--static void clps_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy((void *)(map->map_priv_1 + to), from, len);
--}
--
--static struct map_info clps_map __initdata = {
-- name: "clps flash",
-- read8: clps_read8,
-- read16: clps_read16,
-- read32: clps_read32,
-- copy_from: clps_copy_from,
-- write8: clps_write8,
-- write16: clps_write16,
-- write32: clps_write32,
-- copy_to: clps_copy_to,
--};
--
- #ifdef CONFIG_MTD_CEIVA_STATICMAP
- /*
- * See include/linux/mtd/partitions.h for definition of the mtd_partition
-@@ -176,7 +125,7 @@
- maps = kmalloc(sizeof(struct map_info) * nr, GFP_KERNEL);
- if (!maps)
- return -ENOMEM;
--
-+ memset(maps, 0, sizeof(struct map_info) * nr);
- /*
- * Claim and then map the memory regions.
- */
-@@ -191,7 +140,9 @@
- }
-
- clps[i].map = maps + i;
-- memcpy(clps[i].map, &clps_map, sizeof(struct map_info));
-+
-+ clps[i].map->name = "clps flash";
-+ clps[i].map->phys = clps[i].base;
-
- clps[i].vbase = ioremap(clps[i].base, clps[i].size);
- if (!clps[i].vbase) {
-@@ -199,16 +150,18 @@
- break;
- }
-
-- clps[i].map->map_priv_1 = (unsigned long)clps[i].vbase;
-+ clps[i].map->virt = (unsigned long)clps[i].vbase;
- clps[i].map->buswidth = clps[i].width;
- clps[i].map->size = clps[i].size;
-
-+ simple_map_init(&clps[i].map);
-+
- clps[i].mtd = do_map_probe("jedec_probe", clps[i].map);
- if (clps[i].mtd == NULL) {
- ret = -ENXIO;
- break;
- }
-- clps[i].mtd->module = THIS_MODULE;
-+ clps[i].mtd->owner = THIS_MODULE;
- subdev[i] = clps[i].mtd;
-
- printk(KERN_INFO "clps flash: JEDEC device at 0x%08lx, %dMiB, "
-@@ -318,10 +271,8 @@
- return nr;
- }
-
--extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
--extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, char *);
--
- static struct mtd_partition *parsed_parts;
-+static const char *probes[] = { "cmdlinepart", "RedBoot", NULL };
-
- static void __init clps_locate_partitions(struct mtd_info *mtd)
- {
-@@ -331,20 +282,11 @@
- /*
- * Partition selection stuff.
- */
--#ifdef CONFIG_MTD_CMDLINE_PARTS
-- nr_parts = parse_cmdline_partitions(mtd, &parsed_parts, "clps");
-+ nr_parts = parse_mtd_partitions(mtd, probes, &parsed_parts, 0);
- if (nr_parts > 0) {
- part_type = "command line";
- break;
- }
--#endif
--#ifdef CONFIG_MTD_REDBOOT_PARTS
-- nr_parts = parse_redboot_partitions(mtd, &parsed_parts);
-- if (nr_parts > 0) {
-- part_type = "RedBoot";
-- break;
-- }
--#endif
- #ifdef CONFIG_MTD_CEIVA_STATICMAP
- nr_parts = clps_static_partitions(&parsed_parts);
- if (nr_parts > 0) {
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/cfi_flagadm.c linux/drivers/mtd/maps/cfi_flagadm.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/cfi_flagadm.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/cfi_flagadm.c 2004-11-17 18:17:59.064310120 +0100
-@@ -1,7 +1,7 @@
- /*
- * Copyright © 2001 Flaga hf. Medical Devices, Kári Davíðsson <kd@flaga.is>
- *
-- * $Id$
-+ * $Id$
- *
- * 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
-@@ -27,6 +27,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -55,83 +56,33 @@
- #define FLASH_PARTITION3_ADDR 0x00240000
- #define FLASH_PARTITION3_SIZE 0x001C0000
-
--__u8 flagadm_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 flagadm_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 flagadm_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void flagadm_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void flagadm_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void flagadm_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void flagadm_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void flagadm_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
-
- struct map_info flagadm_map = {
-- name: "FlagaDM flash device",
-- size: FLASH_SIZE,
-- buswidth: 2,
-- read8: flagadm_read8,
-- read16: flagadm_read16,
-- read32: flagadm_read32,
-- copy_from: flagadm_copy_from,
-- write8: flagadm_write8,
-- write16: flagadm_write16,
-- write32: flagadm_write32,
-- copy_to: flagadm_copy_to
-+ .name = "FlagaDM flash device",
-+ .size = FLASH_SIZE,
-+ .buswidth = 2,
- };
-
- struct mtd_partition flagadm_parts[] = {
- {
-- name : "Bootloader",
-- offset : FLASH_PARTITION0_ADDR,
-- size : FLASH_PARTITION0_SIZE
-+ .name = "Bootloader",
-+ .offset = FLASH_PARTITION0_ADDR,
-+ .size = FLASH_PARTITION0_SIZE
- },
- {
-- name : "Kernel image",
-- offset : FLASH_PARTITION1_ADDR,
-- size : FLASH_PARTITION1_SIZE
-+ .name = "Kernel image",
-+ .offset = FLASH_PARTITION1_ADDR,
-+ .size = FLASH_PARTITION1_SIZE
- },
- {
-- name : "Initial ramdisk image",
-- offset : FLASH_PARTITION2_ADDR,
-- size : FLASH_PARTITION2_SIZE
-+ .name = "Initial ramdisk image",
-+ .offset = FLASH_PARTITION2_ADDR,
-+ .size = FLASH_PARTITION2_SIZE
- },
- {
-- name : "Persistant storage",
-- offset : FLASH_PARTITION3_ADDR,
-- size : FLASH_PARTITION3_SIZE
-+ .name = "Persistant storage",
-+ .offset = FLASH_PARTITION3_ADDR,
-+ .size = FLASH_PARTITION3_SIZE
- }
- };
-
-@@ -144,22 +95,26 @@
- printk(KERN_NOTICE "FlagaDM flash device: %x at %x\n",
- FLASH_SIZE, FLASH_PHYS_ADDR);
-
-- flagadm_map.map_priv_1 = (unsigned long)ioremap(FLASH_PHYS_ADDR,
-+ flagadm_map.phys = FLASH_PHYS_ADDR;
-+ flagadm_map.virt = (unsigned long)ioremap(FLASH_PHYS_ADDR,
- FLASH_SIZE);
-
-- if (!flagadm_map.map_priv_1) {
-+ if (!flagadm_map.virt) {
- printk("Failed to ioremap\n");
- return -EIO;
- }
-+
-+ simple_map_init(&flagadm_map);
-+
- mymtd = do_map_probe("cfi_probe", &flagadm_map);
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
- add_mtd_partitions(mymtd, flagadm_parts, PARTITION_COUNT);
- printk(KERN_NOTICE "FlagaDM flash device initialized\n");
- return 0;
- }
-
-- iounmap((void *)flagadm_map.map_priv_1);
-+ iounmap((void *)flagadm_map.virt);
- return -ENXIO;
- }
-
-@@ -169,9 +124,9 @@
- del_mtd_partitions(mymtd);
- map_destroy(mymtd);
- }
-- if (flagadm_map.map_priv_1) {
-- iounmap((void *)flagadm_map.map_priv_1);
-- flagadm_map.map_priv_1 = 0;
-+ if (flagadm_map.virt) {
-+ iounmap((void *)flagadm_map.virt);
-+ flagadm_map.virt = 0;
- }
- }
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/cstm_mips_ixx.c linux/drivers/mtd/maps/cstm_mips_ixx.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/cstm_mips_ixx.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/cstm_mips_ixx.c 2004-11-17 18:17:59.065309968 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Mapping of a custom board with both AMD CFI and JEDEC flash in partitions.
- * Config with both CFI and JEDEC device support.
-@@ -33,55 +33,13 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/partitions.h>
- #include <linux/config.h>
--
--#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
- #include <linux/delay.h>
--#endif
--
--__u8 cstm_mips_ixx_read8(struct map_info *map, unsigned long ofs)
--{
-- return *(__u8 *)(map->map_priv_1 + ofs);
--}
--
--__u16 cstm_mips_ixx_read16(struct map_info *map, unsigned long ofs)
--{
-- return *(__u16 *)(map->map_priv_1 + ofs);
--}
--
--__u32 cstm_mips_ixx_read32(struct map_info *map, unsigned long ofs)
--{
-- return *(__u32 *)(map->map_priv_1 + ofs);
--}
--
--void cstm_mips_ixx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void cstm_mips_ixx_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- *(__u8 *)(map->map_priv_1 + adr) = d;
--}
--
--void cstm_mips_ixx_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- *(__u16 *)(map->map_priv_1 + adr) = d;
--}
--
--void cstm_mips_ixx_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- *(__u32 *)(map->map_priv_1 + adr) = d;
--}
--
--void cstm_mips_ixx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
-
- #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
- #define CC_GCR 0xB4013818
-@@ -97,10 +55,17 @@
- #define CC_GPAICR 0xB4013804
- #endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */
-
-+#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
- void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp)
- {
-+ static spinlock_t vpp_lock = SPIN_LOCK_UNLOCKED;
-+ static int vpp_count = 0;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&vpp_lock, flags);
-+
- if (vpp) {
--#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
-+ if (!vpp_count++) {
- __u16 data;
- __u8 data1;
- static u8 first = 1;
-@@ -116,10 +81,9 @@
- enabling vpp after powerup */
- udelay(40);
- }
--#endif /* CONFIG_MIPS_ITE8172 */
- }
-- else {
--#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
-+ } else {
-+ if (!--vpp_count) {
- __u16 data;
-
- // Set GPIO port B pin3 to high
-@@ -127,26 +91,11 @@
- data = (data & 0xff3f) | 0x0040;
- *(__u16 *)CC_GPBCR = data;
- *(__u8 *)CC_GPBDR = (*(__u8*)CC_GPBDR) & 0xf7;
--#endif /* CONFIG_MIPS_ITE8172 */
- }
-+ }
-+ spin_unlock_irqrestore(&vpp_lock, flags);
- }
--
--const struct map_info basic_cstm_mips_ixx_map = {
-- NULL,
-- 0,
-- 0,
-- cstm_mips_ixx_read8,
-- cstm_mips_ixx_read16,
-- cstm_mips_ixx_read32,
-- cstm_mips_ixx_copy_from,
-- cstm_mips_ixx_write8,
-- cstm_mips_ixx_write16,
-- cstm_mips_ixx_write32,
-- cstm_mips_ixx_copy_to,
-- cstm_mips_ixx_set_vpp,
-- 0,
-- 0
--};
-+#endif
-
- /* board and partition description */
-
-@@ -175,9 +124,9 @@
- static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {
- { // 28F128J3A in 2x16 configuration
- {
-- name: "main partition ",
-- size: 0x02000000, // 128 x 2 x 128k byte sectors
-- offset: 0,
-+ .name = "main partition ",
-+ .size = 0x02000000, // 128 x 2 x 128k byte sectors
-+ .offset = 0,
- },
- },
- };
-@@ -197,9 +146,9 @@
- static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {
- {
- {
-- name: "main partition",
-- size: CONFIG_MTD_CSTM_MIPS_IXX_LEN,
-- offset: 0,
-+ .name = "main partition",
-+ .size = CONFIG_MTD_CSTM_MIPS_IXX_LEN,
-+ .offset = 0,
- },
- },
- };
-@@ -216,17 +165,24 @@
-
- /* Initialize mapping */
- for (i=0;i<PHYSMAP_NUMBER;i++) {
-- printk(KERN_NOTICE "cstm_mips_ixx flash device: %lx at %lx\n", cstm_mips_ixx_board_desc[i].window_size, cstm_mips_ixx_board_desc[i].window_addr);
-- memcpy((char *)&cstm_mips_ixx_map[i],(char *)&basic_cstm_mips_ixx_map,sizeof(struct map_info));
-- cstm_mips_ixx_map[i].map_priv_1 = (unsigned long)ioremap(cstm_mips_ixx_board_desc[i].window_addr, cstm_mips_ixx_board_desc[i].window_size);
-- if (!cstm_mips_ixx_map[i].map_priv_1) {
-+ printk(KERN_NOTICE "cstm_mips_ixx flash device: 0x%lx at 0x%lx\n",
-+ cstm_mips_ixx_board_desc[i].window_size, cstm_mips_ixx_board_desc[i].window_addr);
-+
-+
-+ cstm_mips_ixx_map[i].phys = cstm_mips_ixx_board_desc[i].window_addr;
-+ cstm_mips_ixx_map[i].virt = (unsigned long)ioremap(cstm_mips_ixx_board_desc[i].window_addr, cstm_mips_ixx_board_desc[i].window_size);
-+ if (!cstm_mips_ixx_map[i].virt) {
- printk(KERN_WARNING "Failed to ioremap\n");
- return -EIO;
- }
- cstm_mips_ixx_map[i].name = cstm_mips_ixx_board_desc[i].name;
- cstm_mips_ixx_map[i].size = cstm_mips_ixx_board_desc[i].window_size;
- cstm_mips_ixx_map[i].buswidth = cstm_mips_ixx_board_desc[i].buswidth;
-- //printk(KERN_NOTICE "cstm_mips_ixx: ioremap is %x\n",(unsigned int)(cstm_mips_ixx_map[i].map_priv_1));
-+#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
-+ cstm_mips_ixx_map[i].set_vpp = cstm_mips_ixx_set_vpp;
-+#endif
-+ simple_map_init(&cstm_mips_ixx_map[i]);
-+ //printk(KERN_NOTICE "cstm_mips_ixx: ioremap is %x\n",(unsigned int)(cstm_mips_ixx_map[i].virt));
- }
-
- #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
-@@ -244,7 +200,7 @@
- printk(KERN_NOTICE "cstm_mips_ixx %d jedec: mymtd is %x\n",i,(unsigned int)mymtd);
- }
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
- cstm_mips_ixx_map[i].map_priv_2 = (unsigned long)mymtd;
- add_mtd_partitions(mymtd, parts, cstm_mips_ixx_board_desc[i].num_partitions);
-@@ -266,9 +222,9 @@
- del_mtd_partitions(mymtd);
- map_destroy(mymtd);
- }
-- if (cstm_mips_ixx_map[i].map_priv_1) {
-- iounmap((void *)cstm_mips_ixx_map[i].map_priv_1);
-- cstm_mips_ixx_map[i].map_priv_1 = 0;
-+ if (cstm_mips_ixx_map[i].virt) {
-+ iounmap((void *)cstm_mips_ixx_map[i].virt);
-+ cstm_mips_ixx_map[i].virt = 0;
- }
- }
- }
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/db1x00-flash.c linux/drivers/mtd/maps/db1x00-flash.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/db1x00-flash.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/db1x00-flash.c 2004-11-17 18:17:59.067309664 +0100
-@@ -8,6 +8,7 @@
- #include <linux/config.h>
- #include <linux/module.h>
- #include <linux/types.h>
-+#include <linux/init.h>
- #include <linux/kernel.h>
-
- #include <linux/mtd/mtd.h>
-@@ -29,76 +30,6 @@
- static unsigned long flash_size;
-
- static BCSR * const bcsr = (BCSR *)0xAE000000;
--
--__u8 physmap_read8(struct map_info *map, unsigned long ofs)
--{
-- __u8 ret;
-- ret = __raw_readb(map->map_priv_1 + ofs);
-- DBG("read8 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--__u16 physmap_read16(struct map_info *map, unsigned long ofs)
--{
-- __u16 ret;
-- ret = __raw_readw(map->map_priv_1 + ofs);
-- DBG("read16 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--__u32 physmap_read32(struct map_info *map, unsigned long ofs)
--{
-- __u32 ret;
-- ret = __raw_readl(map->map_priv_1 + ofs);
-- DBG("read32 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- DBG("physmap_copy from %x to %x\n", (unsigned)from, (unsigned)to);
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void physmap_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- DBG("write8 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- DBG("write16 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- DBG("write32 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- DBG("physmap_copy_to %x from %x\n", (unsigned)to, (unsigned)from);
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
--
--static struct map_info db1x00_map = {
-- name: "Db1x00 flash",
-- read8: physmap_read8,
-- read16: physmap_read16,
-- read32: physmap_read32,
-- copy_from: physmap_copy_from,
-- write8: physmap_write8,
-- write16: physmap_write16,
-- write32: physmap_write32,
-- copy_to: physmap_copy_to,
--};
--
- static unsigned char flash_buswidth = 4;
-
- /*
-@@ -115,58 +46,62 @@
- */
- static struct mtd_partition db1x00_partitions[] = {
- {
-- name: "User FS",
-- size: 0x1c00000,
-- offset: 0x0000000
-+ .name = "User FS",
-+ .size = 0x1c00000,
-+ .offset = 0x0000000
- },{
-- name: "yamon",
-- size: 0x0100000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE
-+ .name = "yamon",
-+ .size = 0x0100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE
- },{
-- name: "raw kernel",
-- size: (0x300000-0x40000), /* last 256KB is yamon env */
-- offset: MTDPART_OFS_APPEND,
-+ .name = "raw kernel",
-+ .size = (0x300000-0x40000), /* last 256KB is env */
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #elif defined(DB1X00_BOOT_ONLY)
- static struct mtd_partition db1x00_partitions[] = {
- {
-- name: "User FS",
-- size: 0x00c00000,
-- offset: 0x0000000
-+ .name = "User FS",
-+ .size = 0x00c00000,
-+ .offset = 0x0000000
- },{
-- name: "yamon",
-- size: 0x0100000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE
-+ .name = "yamon",
-+ .size = 0x0100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE
- },{
-- name: "raw kernel",
-- size: (0x300000-0x40000), /* last 256KB is yamon env */
-- offset: MTDPART_OFS_APPEND,
-+ .name = "raw kernel",
-+ .size = (0x300000-0x40000), /* last 256KB is env */
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #elif defined(DB1X00_USER_ONLY)
- static struct mtd_partition db1x00_partitions[] = {
- {
-- name: "User FS",
-- size: 0x0e00000,
-- offset: 0x0000000
-+ .name = "User FS",
-+ .size = 0x0e00000,
-+ .offset = 0x0000000
- },{
-- name: "raw kernel",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "raw kernel",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #else
- #error MTD_DB1X00 define combo error /* should never happen */
- #endif
-+#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
-
-+#define NAME "Db1x00 Linux Flash"
-
--#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
-+static struct map_info db1xxx_mtd_map = {
-+ .name = NAME,
-+};
-
- static struct mtd_partition *parsed_parts;
--static struct mtd_info *mymtd;
-+static struct mtd_info *db1xxx_mtd;
-
- /*
- * Probe the flash density and setup window address and size
-@@ -174,7 +109,7 @@
- * want the MTD driver to be probing the boot or user flash,
- * so having the option to enable only one bank is important.
- */
--int setup_flash_params()
-+int setup_flash_params(void)
- {
- switch ((bcsr->status >> 14) & 0x3) {
- case 0: /* 64Mbit devices */
-@@ -228,6 +163,10 @@
- default:
- return 1;
- }
-+ db1xxx_mtd_map.size = window_size;
-+ db1xxx_mtd_map.buswidth = flash_buswidth;
-+ db1xxx_mtd_map.phys = window_addr;
-+ db1xxx_mtd_map.buswidth = flash_buswidth;
- return 0;
- }
-
-@@ -235,10 +174,6 @@
- {
- struct mtd_partition *parts;
- int nb_parts = 0;
-- char *part_type;
--
-- /* Default flash buswidth */
-- db1x00_map.buswidth = flash_buswidth;
-
- if (setup_flash_params())
- return -ENXIO;
-@@ -246,32 +181,29 @@
- /*
- * Static partition definition selection
- */
-- part_type = "static";
- parts = db1x00_partitions;
- nb_parts = NB_OF(db1x00_partitions);
-- db1x00_map.size = window_size;
-
- /*
- * Now let's probe for the actual flash. Do it here since
- * specific machine settings might have been set above.
- */
- printk(KERN_NOTICE "Db1xxx flash: probing %d-bit flash bus\n",
-- db1x00_map.buswidth*8);
-- db1x00_map.map_priv_1 =
-- (unsigned long)ioremap(window_addr, window_size);
-- mymtd = do_map_probe("cfi_probe", &db1x00_map);
-- if (!mymtd) return -ENXIO;
-- mymtd->module = THIS_MODULE;
-+ db1xxx_mtd_map.buswidth*8);
-+ db1xxx_mtd_map.virt = (unsigned long)ioremap(window_addr, window_size);
-+ db1xxx_mtd = do_map_probe("cfi_probe", &db1xxx_mtd_map);
-+ if (!db1xxx_mtd) return -ENXIO;
-+ db1xxx_mtd->owner = THIS_MODULE;
-
-- add_mtd_partitions(mymtd, parts, nb_parts);
-+ add_mtd_partitions(db1xxx_mtd, parts, nb_parts);
- return 0;
- }
-
- static void __exit db1x00_mtd_cleanup(void)
- {
-- if (mymtd) {
-- del_mtd_partitions(mymtd);
-- map_destroy(mymtd);
-+ if (db1xxx_mtd) {
-+ del_mtd_partitions(db1xxx_mtd);
-+ map_destroy(db1xxx_mtd);
- if (parsed_parts)
- kfree(parsed_parts);
- }
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/dbox2-flash.c linux/drivers/mtd/maps/dbox2-flash.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/dbox2-flash.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/dbox2-flash.c 2004-11-17 18:17:59.068309512 +0100
-@@ -1,12 +1,13 @@
- /*
-- * $Id$
-+ * $Id$
- *
-- * Nokia / Sagem D-Box 2 flash driver
-+ * D-Box 2 flash driver
- */
-
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -16,22 +17,44 @@
- /* partition_info gives details on the logical partitions that the split the
- * single flash device into. If the size if zero we use up to the end of the
- * device. */
--static struct mtd_partition partition_info[]= {{name: "BR bootloader", // raw
-- size: 128 * 1024,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE},
-- {name: "PPC bootloader", // flfs
-- size: 128 * 1024,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: 0},
-- {name: "Kernel", // idxfs
-- size: 768 * 1024,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: 0},
-- {name: "System", // jffs
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: 0}};
-+static struct mtd_partition partition_info[]= {
-+ {
-+ .name = "BR bootloader",
-+ .size = 128 * 1024,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE
-+ },
-+ {
-+ .name = "flfs (ppcboot)",
-+ .size = 128 * 1024,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = 0
-+ },
-+ {
-+ .name = "root (cramfs)",
-+ .size = 7040 * 1024,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = 0
-+ },
-+ {
-+ .name = "var (jffs2)",
-+ .size = 896 * 1024,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = 0
-+ },
-+ {
-+ .name = "flash without bootloader",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = 128 * 1024,
-+ .mask_flags = 0
-+ },
-+ {
-+ .name = "complete flash",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE
-+ }
-+};
-
- #define NUM_PARTITIONS (sizeof(partition_info) / sizeof(partition_info[0]))
-
-@@ -40,72 +63,24 @@
-
- static struct mtd_info *mymtd;
-
--__u8 dbox2_flash_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 dbox2_flash_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 dbox2_flash_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void dbox2_flash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void dbox2_flash_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void dbox2_flash_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void dbox2_flash_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void dbox2_flash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
-
- struct map_info dbox2_flash_map = {
-- name: "D-Box 2 flash memory",
-- size: WINDOW_SIZE,
-- buswidth: 4,
-- read8: dbox2_flash_read8,
-- read16: dbox2_flash_read16,
-- read32: dbox2_flash_read32,
-- copy_from: dbox2_flash_copy_from,
-- write8: dbox2_flash_write8,
-- write16: dbox2_flash_write16,
-- write32: dbox2_flash_write32,
-- copy_to: dbox2_flash_copy_to
-+ .name = "D-Box 2 flash memory",
-+ .size = WINDOW_SIZE,
-+ .buswidth = 4,
-+ .phys = WINDOW_ADDR,
- };
-
- int __init init_dbox2_flash(void)
- {
- printk(KERN_NOTICE "D-Box 2 flash driver (size->0x%X mem->0x%X)\n", WINDOW_SIZE, WINDOW_ADDR);
-- dbox2_flash_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-+ dbox2_flash_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-
-- if (!dbox2_flash_map.map_priv_1) {
-+ if (!dbox2_flash_map.virt) {
- printk("Failed to ioremap\n");
- return -EIO;
- }
-+ simple_map_init(&dbox2_flash_map);
-
- // Probe for dual Intel 28F320 or dual AMD
- mymtd = do_map_probe("cfi_probe", &dbox2_flash_map);
-@@ -117,7 +92,7 @@
- }
-
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
- /* Create MTD devices for each partition. */
- add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
-@@ -125,7 +100,7 @@
- return 0;
- }
-
-- iounmap((void *)dbox2_flash_map.map_priv_1);
-+ iounmap((void *)dbox2_flash_map.virt);
- return -ENXIO;
- }
-
-@@ -135,9 +110,9 @@
- del_mtd_partitions(mymtd);
- map_destroy(mymtd);
- }
-- if (dbox2_flash_map.map_priv_1) {
-- iounmap((void *)dbox2_flash_map.map_priv_1);
-- dbox2_flash_map.map_priv_1 = 0;
-+ if (dbox2_flash_map.virt) {
-+ iounmap((void *)dbox2_flash_map.virt);
-+ dbox2_flash_map.virt = 0;
- }
- }
-
-@@ -146,5 +121,5 @@
-
-
- MODULE_LICENSE("GPL");
--MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>");
--MODULE_DESCRIPTION("MTD map driver for Nokia/Sagem D-Box 2 board");
-+MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>, Bastian Blank <waldi@tuxbox.org>, Alexander Wild <wild@te-elektronik.com>");
-+MODULE_DESCRIPTION("MTD map driver for D-Box 2 board");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/dc21285.c linux/drivers/mtd/maps/dc21285.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/dc21285.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/dc21285.c 2004-11-17 18:17:59.069309360 +0100
-@@ -5,12 +5,13 @@
- *
- * This code is GPL
- *
-- * $Id$
-+ * $Id$
- */
- #include <linux/config.h>
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -92,26 +93,42 @@
- }
-
- struct map_info dc21285_map = {
-- name: "DC21285 flash",
-- size: 16*1024*1024,
-- read8: dc21285_read8,
-- read16: dc21285_read16,
-- read32: dc21285_read32,
-- copy_from: dc21285_copy_from,
-- write8: dc21285_write8,
-- write16: dc21285_write16,
-- write32: dc21285_write32,
-- copy_to: dc21285_copy_to
-+ .name = "DC21285 flash",
-+ .phys = NO_XIP,
-+ .size = 16*1024*1024,
-+ .read8 = dc21285_read8,
-+ .read16 = dc21285_read16,
-+ .read32 = dc21285_read32,
-+ .copy_from = dc21285_copy_from,
-+ .write8 = dc21285_write8,
-+ .write16 = dc21285_write16,
-+ .write32 = dc21285_write32,
-+ .copy_to = dc21285_copy_to
- };
-
-
- /* Partition stuff */
- static struct mtd_partition *dc21285_parts;
--
--extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **);
-+#ifdef CONFIG_MTD_PARTITIONS
-+static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-+#endif
-
- int __init init_dc21285(void)
- {
-+
-+ /*
-+ * Flash timing is determined with bits 19-16 of the
-+ * CSR_SA110_CNTL. The value is the number of wait cycles, or
-+ * 0 for 16 cycles (the default). Cycles are 20 ns.
-+ * Here we use 7 for 140 ns flash chips.
-+ */
-+ /* access time */
-+ *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x000f0000) | (7 << 16));
-+ /* burst time */
-+ *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x00f00000) | (7 << 20));
-+ /* tristate time */
-+ *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24));
-+
- /* Determine buswidth */
- switch (*CSR_SA110_CNTL & (3<<14)) {
- case SA110_CNTL_ROMWIDTH_8:
-@@ -141,33 +158,18 @@
- if (mymtd) {
- int nrparts = 0;
-
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
- /* partition fixup */
-
--#ifdef CONFIG_MTD_REDBOOT_PARTS
-- nrparts = parse_redboot_partitions(mymtd, &dc21285_parts);
--#endif
-+#ifdef CONFIG_MTD_PARTITIONS
-+ nrparts = parse_mtd_partitions(mymtd, probes, &dc21285_parts, (void *)0);
- if (nrparts > 0) {
- add_mtd_partitions(mymtd, dc21285_parts, nrparts);
-- } else if (nrparts == 0) {
-- printk(KERN_NOTICE "RedBoot partition table failed\n");
-- add_mtd_device(mymtd);
-+ return 0;
- }
--
-- /*
-- * Flash timing is determined with bits 19-16 of the
-- * CSR_SA110_CNTL. The value is the number of wait cycles, or
-- * 0 for 16 cycles (the default). Cycles are 20 ns.
-- * Here we use 7 for 140 ns flash chips.
-- */
-- /* access time */
-- *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x000f0000) | (7 << 16));
-- /* burst time */
-- *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x00f00000) | (7 << 20));
-- /* tristate time */
-- *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24));
--
-+#endif
-+ add_mtd_device(mymtd);
- return 0;
- }
-
-@@ -177,17 +179,16 @@
-
- static void __exit cleanup_dc21285(void)
- {
-- if (mymtd) {
-+#ifdef CONFIG_MTD_PARTITIONS
-+ if (dc21285_parts) {
-+ del_mtd_partitions(mymtd);
-+ kfree(dc21285_parts);
-+ } else
-+#endif
- del_mtd_device(mymtd);
-+
- map_destroy(mymtd);
-- mymtd = NULL;
-- }
-- if (dc21285_map.map_priv_1) {
- iounmap((void *)dc21285_map.map_priv_1);
-- dc21285_map.map_priv_1 = 0;
-- }
-- if(dc21285_parts)
-- kfree(dc21285_parts);
- }
-
- module_init(init_dc21285);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/dilnetpc.c linux/drivers/mtd/maps/dilnetpc.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/dilnetpc.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/dilnetpc.c 2004-11-17 18:17:59.071309056 +0100
-@@ -14,7 +14,7 @@
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
-- * $Id$
-+ * $Id$
- *
- * The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems
- * featuring the AMD Elan SC410 processor. There are two variants of this
-@@ -29,6 +29,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -36,7 +37,7 @@
- #include <linux/mtd/concat.h>
-
- /*
--** The DIL/NetPC keeps it's BIOS in two distinct flash blocks.
-+** The DIL/NetPC keeps its BIOS in two distinct flash blocks.
- ** Destroying any of these blocks transforms the DNPC into
- ** a paperweight (albeit not a very useful one, considering
- ** it only weighs a few grams).
-@@ -189,45 +190,6 @@
- }
-
-
--static __u8 dnpc_read8(struct map_info *map, unsigned long ofs)
--{
-- return readb(map->map_priv_1 + ofs);
--}
--
--static __u16 dnpc_read16(struct map_info *map, unsigned long ofs)
--{
-- return readw(map->map_priv_1 + ofs);
--}
--
--static __u32 dnpc_read32(struct map_info *map, unsigned long ofs)
--{
-- return readl(map->map_priv_1 + ofs);
--}
--
--static void dnpc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
--}
--
--static void dnpc_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- writeb(d, map->map_priv_1 + adr);
--}
--
--static void dnpc_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- writew(d, map->map_priv_1 + adr);
--}
--
--static void dnpc_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- writel(d, map->map_priv_1 + adr);
--}
--
--static void dnpc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio((void *)(map->map_priv_1 + to), from, len);
--}
-
- /*
- ************************************************************
-@@ -288,19 +250,11 @@
- #define WINDOW_ADDR FLASH_BASE
-
- static struct map_info dnpc_map = {
-- name: "ADNP Flash Bank",
-- size: ADNP_WINDOW_SIZE,
-- buswidth: 1,
-- read8: dnpc_read8,
-- read16: dnpc_read16,
-- read32: dnpc_read32,
-- copy_from: dnpc_copy_from,
-- write8: dnpc_write8,
-- write16: dnpc_write16,
-- write32: dnpc_write32,
-- copy_to: dnpc_copy_to,
-- set_vpp: adnp_set_vpp,
-- map_priv_2: WINDOW_ADDR
-+ .name = "ADNP Flash Bank",
-+ .size = ADNP_WINDOW_SIZE,
-+ .buswidth = 1,
-+ .set_vpp = adnp_set_vpp,
-+ .phys = WINDOW_ADDR
- };
-
- /*
-@@ -316,29 +270,29 @@
- static struct mtd_partition partition_info[]=
- {
- {
-- name: "ADNP boot",
-- offset: 0,
-- size: 0xf0000,
-+ .name = "ADNP boot",
-+ .offset = 0,
-+ .size = 0xf0000,
- },
- {
-- name: "ADNP system BIOS",
-- offset: MTDPART_OFS_NXTBLK,
-- size: 0x10000,
-+ .name = "ADNP system BIOS",
-+ .offset = MTDPART_OFS_NXTBLK,
-+ .size = 0x10000,
- #ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
-- mask_flags: MTD_WRITEABLE,
-+ .mask_flags = MTD_WRITEABLE,
- #endif
- },
- {
-- name: "ADNP file system",
-- offset: MTDPART_OFS_NXTBLK,
-- size: 0x2f0000,
-+ .name = "ADNP file system",
-+ .offset = MTDPART_OFS_NXTBLK,
-+ .size = 0x2f0000,
- },
- {
-- name: "ADNP system BIOS entry",
-- offset: MTDPART_OFS_NXTBLK,
-- size: MTDPART_SIZ_FULL,
-+ .name = "ADNP system BIOS entry",
-+ .offset = MTDPART_OFS_NXTBLK,
-+ .size = MTDPART_SIZ_FULL,
- #ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
-- mask_flags: MTD_WRITEABLE,
-+ .mask_flags = MTD_WRITEABLE,
- #endif
- },
- };
-@@ -369,21 +323,21 @@
- static struct mtd_partition higlvl_partition_info[]=
- {
- {
-- name: "ADNP boot block",
-- offset: 0,
-- size: CONFIG_MTD_DILNETPC_BOOTSIZE,
-+ .name = "ADNP boot block",
-+ .offset = 0,
-+ .size = CONFIG_MTD_DILNETPC_BOOTSIZE,
- },
- {
-- name: "ADNP file system space",
-- offset: MTDPART_OFS_NXTBLK,
-- size: ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000,
-+ .name = "ADNP file system space",
-+ .offset = MTDPART_OFS_NXTBLK,
-+ .size = ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000,
- },
- {
-- name: "ADNP system BIOS + BIOS Entry",
-- offset: MTDPART_OFS_NXTBLK,
-- size: MTDPART_SIZ_FULL,
-+ .name = "ADNP system BIOS + BIOS Entry",
-+ .offset = MTDPART_OFS_NXTBLK,
-+ .size = MTDPART_SIZ_FULL,
- #ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
-- mask_flags: MTD_WRITEABLE,
-+ .mask_flags = MTD_WRITEABLE,
- #endif
- },
- };
-@@ -447,18 +401,19 @@
- }
-
- printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n",
-- is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.map_priv_2);
-+ is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.phys);
-
-- dnpc_map.map_priv_1 = (unsigned long)ioremap_nocache(dnpc_map.map_priv_2, dnpc_map.size);
-+ dnpc_map.virt = (unsigned long)ioremap_nocache(dnpc_map.phys, dnpc_map.size);
-
-- dnpc_map_flash(dnpc_map.map_priv_2, dnpc_map.size);
-+ dnpc_map_flash(dnpc_map.phys, dnpc_map.size);
-
-- if (!dnpc_map.map_priv_1) {
-+ if (!dnpc_map.virt) {
- printk("Failed to ioremap_nocache\n");
- return -EIO;
- }
-+ simple_map_init(&dnpc_map);
-
-- printk("FLASH virtual address: 0x%lx\n", dnpc_map.map_priv_1);
-+ printk("FLASH virtual address: 0x%lx\n", dnpc_map.virt);
-
- mymtd = do_map_probe("jedec_probe", &dnpc_map);
-
-@@ -475,11 +430,11 @@
- mymtd->erasesize = 0x10000;
-
- if (!mymtd) {
-- iounmap((void *)dnpc_map.map_priv_1);
-+ iounmap((void *)dnpc_map.virt);
- return -ENXIO;
- }
-
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
- /*
- ** Supply pointers to lowlvl_parts[] array to add_mtd_partitions()
-@@ -525,10 +480,10 @@
- del_mtd_partitions(mymtd);
- map_destroy(mymtd);
- }
-- if (dnpc_map.map_priv_1) {
-- iounmap((void *)dnpc_map.map_priv_1);
-+ if (dnpc_map.virt) {
-+ iounmap((void *)dnpc_map.virt);
- dnpc_unmap_flash();
-- dnpc_map.map_priv_1 = 0;
-+ dnpc_map.virt = 0;
- }
- }
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/ebony.c linux/drivers/mtd/maps/ebony.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/ebony.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/ebony.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,164 @@
-+/*
-+ * $Id$
-+ *
-+ * Mapping for Ebony user flash
-+ *
-+ * Matt Porter <mporter@mvista.com>
-+ *
-+ * Copyright 2002 MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/config.h>
-+#include <asm/io.h>
-+#include <asm/ibm440.h>
-+#include <platforms/ebony.h>
-+
-+static struct mtd_info *flash;
-+
-+static struct map_info ebony_small_map = {
-+ .name = "Ebony small flash",
-+ .size = EBONY_SMALL_FLASH_SIZE,
-+ .buswidth = 1,
-+};
-+
-+static struct map_info ebony_large_map = {
-+ .name = "Ebony large flash",
-+ .size = EBONY_LARGE_FLASH_SIZE,
-+ .buswidth = 1,
-+};
-+
-+static struct mtd_partition ebony_small_partitions[] = {
-+ {
-+ .name = "OpenBIOS",
-+ .offset = 0x0,
-+ .size = 0x80000,
-+ }
-+};
-+
-+static struct mtd_partition ebony_large_partitions[] = {
-+ {
-+ .name = "fs",
-+ .offset = 0,
-+ .size = 0x380000,
-+ },
-+ {
-+ .name = "firmware",
-+ .offset = 0x380000,
-+ .size = 0x80000,
-+ }
-+};
-+
-+int __init init_ebony(void)
-+{
-+ u8 fpga0_reg;
-+ unsigned long fpga0_adr;
-+ unsigned long long small_flash_base, large_flash_base;
-+
-+ fpga0_adr = ioremap64(EBONY_FPGA_ADDR, 16);
-+ if (!fpga0_adr)
-+ return -ENOMEM;
-+
-+ fpga0_reg = readb(fpga0_adr);
-+ iounmap64(fpga0_adr);
-+
-+ if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
-+ !EBONY_FLASH_SEL(fpga0_reg))
-+ small_flash_base = EBONY_SMALL_FLASH_HIGH2;
-+ else if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
-+ EBONY_FLASH_SEL(fpga0_reg))
-+ small_flash_base = EBONY_SMALL_FLASH_HIGH1;
-+ else if (!EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
-+ !EBONY_FLASH_SEL(fpga0_reg))
-+ small_flash_base = EBONY_SMALL_FLASH_LOW2;
-+ else
-+ small_flash_base = EBONY_SMALL_FLASH_LOW1;
-+
-+ if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
-+ !EBONY_ONBRD_FLASH_EN(fpga0_reg))
-+ large_flash_base = EBONY_LARGE_FLASH_LOW;
-+ else
-+ large_flash_base = EBONY_LARGE_FLASH_HIGH;
-+
-+ ebony_small_map.phys = small_flash_base;
-+ ebony_small_map.virt =
-+ (unsigned long)ioremap64(small_flash_base,
-+ ebony_small_map.size);
-+
-+ if (!ebony_small_map.virt) {
-+ printk("Failed to ioremap flash\n");
-+ return -EIO;
-+ }
-+
-+ simple_map_init(&ebony_small_map);
-+
-+ flash = do_map_probe("map_rom", &ebony_small_map);
-+ if (flash) {
-+ flash->owner = THIS_MODULE;
-+ add_mtd_partitions(flash, ebony_small_partitions,
-+ ARRAY_SIZE(ebony_small_partitions));
-+ } else {
-+ printk("map probe failed for flash\n");
-+ return -ENXIO;
-+ }
-+
-+ ebony_large_map.phys = large_flash_base;
-+ ebony_large_map.virt =
-+ (unsigned long)ioremap64(large_flash_base,
-+ ebony_large_map.size);
-+
-+ if (!ebony_large_map.virt) {
-+ printk("Failed to ioremap flash\n");
-+ return -EIO;
-+ }
-+
-+ simple_map_init(&ebony_large_map);
-+
-+ flash = do_map_probe("cfi_probe", &ebony_large_map);
-+ if (flash) {
-+ flash->owner = THIS_MODULE;
-+ add_mtd_partitions(flash, ebony_large_partitions,
-+ ARRAY_SIZE(ebony_large_partitions));
-+ } else {
-+ printk("map probe failed for flash\n");
-+ return -ENXIO;
-+ }
-+
-+ return 0;
-+}
-+
-+static void __exit cleanup_ebony(void)
-+{
-+ if (flash) {
-+ del_mtd_partitions(flash);
-+ map_destroy(flash);
-+ }
-+
-+ if (ebony_small_map.virt) {
-+ iounmap((void *)ebony_small_map.virt);
-+ ebony_small_map.virt = 0;
-+ }
-+
-+ if (ebony_large_map.virt) {
-+ iounmap((void *)ebony_large_map.virt);
-+ ebony_large_map.virt = 0;
-+ }
-+}
-+
-+module_init(init_ebony);
-+module_exit(cleanup_ebony);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Matt Porter <mporter@mvista.com>");
-+MODULE_DESCRIPTION("MTD map and partitions for IBM 440GP Ebony boards");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/edb7312.c linux/drivers/mtd/maps/edb7312.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/edb7312.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/edb7312.c 2004-11-17 18:17:59.073308752 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Handle mapping of the NOR flash on Cogent EDB7312 boards
- *
-@@ -13,6 +13,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -35,61 +36,11 @@
-
- static struct mtd_info *mymtd;
-
--__u8 edb7312nor_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 edb7312nor_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 edb7312nor_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void edb7312nor_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void edb7312nor_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void edb7312nor_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void edb7312nor_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void edb7312nor_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
--
- struct map_info edb7312nor_map = {
-- name: "NOR flash on EDB7312",
-- size: WINDOW_SIZE,
-- buswidth: BUSWIDTH,
-- read8: edb7312nor_read8,
-- read16: edb7312nor_read16,
-- read32: edb7312nor_read32,
-- copy_from: edb7312nor_copy_from,
-- write8: edb7312nor_write8,
-- write16: edb7312nor_write16,
-- write32: edb7312nor_write32,
-- copy_to: edb7312nor_copy_to
-+ .name = "NOR flash on EDB7312",
-+ .size = WINDOW_SIZE,
-+ .buswidth = BUSWIDTH,
-+ .phys = WINDOW_ADDR,
- };
-
- #ifdef CONFIG_MTD_PARTITIONS
-@@ -100,29 +51,23 @@
- static struct mtd_partition static_partitions[3] =
- {
- {
-- name: "ARMboot",
-- size: 0x40000,
-- offset: 0
-+ .name = "ARMboot",
-+ .size = 0x40000,
-+ .offset = 0
- },
- {
-- name: "Kernel",
-- size: 0x200000,
-- offset: 0x40000
-+ .name = "Kernel",
-+ .size = 0x200000,
-+ .offset = 0x40000
- },
- {
-- name: "RootFS",
-- size: 0xDC0000,
-- offset: 0x240000
-+ .name = "RootFS",
-+ .size = 0xDC0000,
-+ .offset = 0x240000
- },
- };
-
--#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
--
--#ifdef CONFIG_MTD_CMDLINE_PARTS
--int parse_cmdline_partitions(struct mtd_info *master,
-- struct mtd_partition **pparts,
-- const char *mtd_id);
--#endif
-+static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-
- #endif
-
-@@ -137,32 +82,33 @@
-
- printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n",
- WINDOW_SIZE, WINDOW_ADDR);
-- edb7312nor_map.map_priv_1 = (unsigned long)
-+ edb7312nor_map.virt = (unsigned long)
- ioremap(WINDOW_ADDR, WINDOW_SIZE);
-
-- if (!edb7312nor_map.map_priv_1) {
-+ if (!edb7312nor_map.virt) {
- printk(MSG_PREFIX "failed to ioremap\n");
- return -EIO;
- }
-
-+ simple_map_init(&edb7312nor_map);
-+
- mymtd = 0;
- type = rom_probe_types;
- for(; !mymtd && *type; type++) {
- mymtd = do_map_probe(*type, &edb7312nor_map);
- }
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
- #ifdef CONFIG_MTD_PARTITIONS
--#ifdef CONFIG_MTD_CMDLINE_PARTS
-- mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts, MTDID);
-+ mtd_parts_nb = parse_mtd_partitions(mymtd, probes, &mtd_parts, MTDID);
- if (mtd_parts_nb > 0)
-- part_type = "command line";
--#endif
-+ part_type = "detected";
-+
- if (mtd_parts_nb == 0)
- {
- mtd_parts = static_partitions;
-- mtd_parts_nb = NB_OF(static_partitions);
-+ mtd_parts_nb = ARRAY_SIZE(static_partitions);
- part_type = "static";
- }
- #endif
-@@ -178,7 +124,7 @@
- return 0;
- }
-
-- iounmap((void *)edb7312nor_map.map_priv_1);
-+ iounmap((void *)edb7312nor_map.virt);
- return -ENXIO;
- }
-
-@@ -188,9 +134,9 @@
- del_mtd_device(mymtd);
- map_destroy(mymtd);
- }
-- if (edb7312nor_map.map_priv_1) {
-- iounmap((void *)edb7312nor_map.map_priv_1);
-- edb7312nor_map.map_priv_1 = 0;
-+ if (edb7312nor_map.virt) {
-+ iounmap((void *)edb7312nor_map.virt);
-+ edb7312nor_map.virt = 0;
- }
- }
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/elan-104nc.c linux/drivers/mtd/maps/elan-104nc.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/elan-104nc.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/elan-104nc.c 2004-11-17 18:17:59.074308600 +0100
-@@ -16,7 +16,7 @@
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-- $Id$
-+ $Id$
-
- The ELAN-104NC has up to 8 Mibyte of Intel StrataFlash (28F320/28F640) in x16
- mode. This drivers uses the CFI probe and Intel Extended Command Set drivers.
-@@ -40,6 +40,7 @@
- #include <asm/io.h>
-
- #include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/partitions.h>
-
- #define WINDOW_START 0xb0000
-@@ -59,14 +60,14 @@
- * single flash device into. If the size if zero we use up to the end of the
- * device. */
- static struct mtd_partition partition_info[]={
-- { name: "ELAN-104NC flash boot partition",
-- offset: 0,
-- size: 640*1024 },
-- { name: "ELAN-104NC flash partition 1",
-- offset: 640*1024,
-- size: 896*1024 },
-- { name: "ELAN-104NC flash partition 2",
-- offset: (640+896)*1024 }
-+ { .name = "ELAN-104NC flash boot partition",
-+ .offset = 0,
-+ .size = 640*1024 },
-+ { .name = "ELAN-104NC flash partition 1",
-+ .offset = 640*1024,
-+ .size = 896*1024 },
-+ { .name = "ELAN-104NC flash partition 2",
-+ .offset = (640+896)*1024 }
- };
- #define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0]))
-
-@@ -195,19 +196,20 @@
- }
-
- static struct map_info elan_104nc_map = {
-- name: "ELAN-104NC flash",
-- size: 8*1024*1024, /* this must be set to a maximum possible amount
-+ .name = "ELAN-104NC flash",
-+ .phys = NO_XIP,
-+ .size = 8*1024*1024, /* this must be set to a maximum possible amount
- of flash so the cfi probe routines find all
- the chips */
-- buswidth: 2,
-- read8: elan_104nc_read8,
-- read16: elan_104nc_read16,
-- read32: elan_104nc_read32,
-- copy_from: elan_104nc_copy_from,
-- write8: elan_104nc_write8,
-- write16: elan_104nc_write16,
-- write32: elan_104nc_write32,
-- copy_to: elan_104nc_copy_to
-+ .buswidth = 2,
-+ .read8 = elan_104nc_read8,
-+ .read16 = elan_104nc_read16,
-+ .read32 = elan_104nc_read32,
-+ .copy_from = elan_104nc_copy_from,
-+ .write8 = elan_104nc_write8,
-+ .write16 = elan_104nc_write16,
-+ .write32 = elan_104nc_write32,
-+ .copy_to = elan_104nc_copy_to
- };
-
- /* MTD device for all of the flash. */
-@@ -221,20 +223,13 @@
- }
-
- iounmap((void *)iomapadr);
-- release_region(PAGE_IO,PAGE_IO_SIZE);
- }
-
- int __init init_elan_104nc(void)
- {
-- /* Urg! We use I/O port 0x22 without request_region()ing it */
-- /*
-- if (check_region(PAGE_IO,PAGE_IO_SIZE) != 0) {
-- printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
-- elan_104nc_map.name,
-- PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 );
-- return -EAGAIN;
-- }
-- */
-+ /* Urg! We use I/O port 0x22 without request_region()ing it,
-+ because it's already allocated to the PIC. */
-+
- iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH);
- if (!iomapadr) {
- printk( KERN_ERR"%s: failed to ioremap memory region\n",
-@@ -242,10 +237,6 @@
- return -EIO;
- }
-
-- /*
-- request_region( PAGE_IO, PAGE_IO_SIZE, "ELAN-104NC flash" );
-- */
--
- printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
- elan_104nc_map.name,
- PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1,
-@@ -260,7 +251,7 @@
- return -ENXIO;
- }
-
-- all_mtd->module=THIS_MODULE;
-+ all_mtd->owner = THIS_MODULE;
-
- /* Create MTD devices for each partition. */
- add_mtd_partitions( all_mtd, partition_info, NUM_PARTITIONS );
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/epxa10db-flash.c linux/drivers/mtd/maps/epxa10db-flash.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/epxa10db-flash.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/epxa10db-flash.c 2004-11-17 18:17:59.079307840 +0100
-@@ -5,7 +5,7 @@
- * Copyright (C) 2001 Altera Corporation
- * Copyright (C) 2001 Red Hat, Inc.
- *
-- * $Id$
-+ * $Id$
- *
- * 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
-@@ -26,6 +26,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -43,87 +44,38 @@
-
- static struct mtd_info *mymtd;
-
--extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **);
- static int epxa_default_partitions(struct mtd_info *master, struct mtd_partition **pparts);
-
--static __u8 epxa_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--static __u16 epxa_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--static __u32 epxa_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--static void epxa_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
--}
--
--static void epxa_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void epxa_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void epxa_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void epxa_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio((void *)(map->map_priv_1 + to), from, len);
--}
--
--
-
- static struct map_info epxa_map = {
-- name: "EPXA flash",
-- size: FLASH_SIZE,
-- buswidth: 2,
-- read8: epxa_read8,
-- read16: epxa_read16,
-- read32: epxa_read32,
-- copy_from: epxa_copy_from,
-- write8: epxa_write8,
-- write16: epxa_write16,
-- write32: epxa_write32,
-- copy_to: epxa_copy_to
-+ .name = "EPXA flash",
-+ .size = FLASH_SIZE,
-+ .buswidth = 2,
-+ .phys = FLASH_START,
- };
-
-+static const char *probes[] = { "RedBoot", "afs", NULL };
-
- static int __init epxa_mtd_init(void)
- {
- int i;
-
-- printk(KERN_NOTICE "%s flash device: %x at %x\n", BOARD_NAME, FLASH_SIZE, FLASH_START);
-- epxa_map.map_priv_1 = (unsigned long)ioremap(FLASH_START, FLASH_SIZE);
-- if (!epxa_map.map_priv_1) {
-+ printk(KERN_NOTICE "%s flash device: 0x%x at 0x%x\n", BOARD_NAME, FLASH_SIZE, FLASH_START);
-+
-+ epxa_map.virt = (unsigned long)ioremap(FLASH_START, FLASH_SIZE);
-+ if (!epxa_map.virt) {
- printk("Failed to ioremap %s flash\n",BOARD_NAME);
- return -EIO;
- }
-+ simple_map_init(&epxa_map);
-
- mymtd = do_map_probe("cfi_probe", &epxa_map);
- if (!mymtd) {
-- iounmap((void *)epxa_map.map_priv_1);
-+ iounmap((void *)epxa_map.virt);
- return -ENXIO;
- }
-
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
- /* Unlock the flash device. */
- if(mymtd->unlock){
-@@ -135,23 +87,14 @@
- }
- }
-
--#ifdef CONFIG_MTD_REDBOOT_PARTS
-- nr_parts = parse_redboot_partitions(mymtd, &parts);
--
-- if (nr_parts > 0) {
-- add_mtd_partitions(mymtd, parts, nr_parts);
-- return 0;
-- }
--#endif
--#ifdef CONFIG_MTD_AFS_PARTS
-- nr_parts = parse_afs_partitions(mymtd, &parts);
-+#ifdef CONFIG_MTD_PARTITIONS
-+ nr_parts = parse_mtd_partitions(mymtd, probes, &parts, 0);
-
- if (nr_parts > 0) {
- add_mtd_partitions(mymtd, parts, nr_parts);
- return 0;
- }
- #endif
--
- /* No recognised partitioning schemes found - use defaults */
- nr_parts = epxa_default_partitions(mymtd, &parts);
- if (nr_parts > 0) {
-@@ -173,9 +116,9 @@
- del_mtd_device(mymtd);
- map_destroy(mymtd);
- }
-- if (epxa_map.map_priv_1) {
-- iounmap((void *)epxa_map.map_priv_1);
-- epxa_map.map_priv_1 = 0;
-+ if (epxa_map.virt) {
-+ iounmap((void *)epxa_map.virt);
-+ epxa_map.virt = 0;
- }
- }
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/fortunet.c linux/drivers/mtd/maps/fortunet.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/fortunet.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/fortunet.c 2004-11-17 18:17:59.080307688 +0100
-@@ -1,11 +1,12 @@
- /* fortunet.c memory map
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -23,7 +24,7 @@
-
- struct map_region
- {
-- int window_addr_phyical;
-+ int window_addr_physical;
- int altbuswidth;
- struct map_info map_info;
- struct mtd_info *mymtd;
-@@ -37,57 +38,10 @@
- static int map_regions_parts[MAX_NUM_REGIONS] = {0,0,0,0};
-
-
--__u8 fortunet_read8(struct map_info *map, unsigned long ofs)
--{
-- return *(__u8 *)(map->map_priv_1 + ofs);
--}
--
--__u16 fortunet_read16(struct map_info *map, unsigned long ofs)
--{
-- return *(__u16 *)(map->map_priv_1 + ofs);
--}
--
--__u32 fortunet_read32(struct map_info *map, unsigned long ofs)
--{
-- return *(__u32 *)(map->map_priv_1 + ofs);
--}
--
--void fortunet_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy(to, (void *)(map->map_priv_1 + from), len);
--}
--
--void fortunet_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- *(__u8 *)(map->map_priv_1 + adr) = d;
--}
--
--void fortunet_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- *(__u16 *)(map->map_priv_1 + adr) = d;
--}
--
--void fortunet_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- *(__u32 *)(map->map_priv_1 + adr) = d;
--}
--
--void fortunet_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy((void *)(map->map_priv_1 + to), from, len);
--}
-
- struct map_info default_map = {
-- size: DEF_WINDOW_SIZE,
-- buswidth: 4,
-- read8: fortunet_read8,
-- read16: fortunet_read16,
-- read32: fortunet_read32,
-- copy_from: fortunet_copy_from,
-- write8: fortunet_write8,
-- write16: fortunet_write16,
-- write32: fortunet_write32,
-- copy_to: fortunet_copy_to
-+ .size = DEF_WINDOW_SIZE,
-+ .buswidth = 4,
- };
-
- static char * __init get_string_option(char *dest,int dest_size,char *sor)
-@@ -147,7 +101,7 @@
- get_options (get_string_option(string,sizeof(string),line),6,params);
- if(params[0]<1)
- {
-- printk(MTD_FORTUNET_PK "Bad paramters for MTD Region "
-+ printk(MTD_FORTUNET_PK "Bad parameters for MTD Region "
- " name,region-number[,base,size,buswidth,altbuswidth]\n");
- return 1;
- }
-@@ -161,14 +115,14 @@
- memcpy(&map_regions[params[1]].map_info,
- &default_map,sizeof(map_regions[params[1]].map_info));
- map_regions_set[params[1]] = 1;
-- map_regions[params[1]].window_addr_phyical = DEF_WINDOW_ADDR_PHY;
-+ map_regions[params[1]].window_addr_physical = DEF_WINDOW_ADDR_PHY;
- map_regions[params[1]].altbuswidth = 2;
- map_regions[params[1]].mymtd = NULL;
- map_regions[params[1]].map_info.name = map_regions[params[1]].map_name;
- strcpy(map_regions[params[1]].map_info.name,string);
- if(params[0]>1)
- {
-- map_regions[params[1]].window_addr_phyical = params[2];
-+ map_regions[params[1]].window_addr_physical = params[2];
- }
- if(params[0]>2)
- {
-@@ -185,14 +139,14 @@
- return 1;
- }
-
--static int __init MTD_New_Partion(char *line)
-+static int __init MTD_New_Partition(char *line)
- {
- char string[MAX_NAME_SIZE];
- int params[4];
- get_options (get_string_option(string,sizeof(string),line),4,params);
- if(params[0]<3)
- {
-- printk(MTD_FORTUNET_PK "Bad paramters for MTD Partion "
-+ printk(MTD_FORTUNET_PK "Bad parameters for MTD Partition "
- " name,region-number,size,offset\n");
- return 1;
- }
-@@ -204,7 +158,7 @@
- }
- if(map_regions_parts[params[1]]>=MAX_NUM_PARTITIONS)
- {
-- printk(MTD_FORTUNET_PK "Out of space for partion in this region\n");
-+ printk(MTD_FORTUNET_PK "Out of space for partition in this region\n");
- return 1;
- }
- map_regions[params[1]].parts[map_regions_parts[params[1]]].name =
-@@ -220,7 +174,10 @@
- }
-
- __setup("MTD_Region=", MTD_New_Region);
--__setup("MTD_Partion=", MTD_New_Partion);
-+__setup("MTD_Partition=", MTD_New_Partition);
-+
-+/* Backwards-spelling-compatibility */
-+__setup("MTD_Partion=", MTD_New_Partition);
-
- int __init init_fortunet(void)
- {
-@@ -229,13 +186,13 @@
- {
- if(map_regions_parts[ix]&&(!map_regions_set[ix]))
- {
-- printk(MTD_FORTUNET_PK "Region %d is not setup (Seting to default)\n",
-+ printk(MTD_FORTUNET_PK "Region %d is not setup (Setting to default)\n",
- ix);
- memset(&map_regions[ix],0,sizeof(map_regions[ix]));
- memcpy(&map_regions[ix].map_info,&default_map,
- sizeof(map_regions[ix].map_info));
- map_regions_set[ix] = 1;
-- map_regions[ix].window_addr_phyical = DEF_WINDOW_ADDR_PHY;
-+ map_regions[ix].window_addr_physical = DEF_WINDOW_ADDR_PHY;
- map_regions[ix].altbuswidth = 2;
- map_regions[ix].mymtd = NULL;
- map_regions[ix].map_info.name = map_regions[ix].map_name;
-@@ -244,30 +201,35 @@
- if(map_regions_set[ix])
- {
- iy++;
-- printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at phyicaly "
-+ printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at physically "
- " address %x size %x\n",
- map_regions[ix].map_info.name,
-- map_regions[ix].window_addr_phyical,
-+ map_regions[ix].window_addr_physical,
- map_regions[ix].map_info.size);
-- map_regions[ix].map_info.map_priv_1 =
-+
-+ map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical,
-+
-+ map_regions[ix].map_info.virt =
- (int)ioremap_nocache(
-- map_regions[ix].window_addr_phyical,
-+ map_regions[ix].window_addr_physical,
- map_regions[ix].map_info.size);
-- if(!map_regions[ix].map_info.map_priv_1)
-+ if(!map_regions[ix].map_info.virt)
- {
- printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n",
- map_regions[ix].map_info.name);
- return -ENXIO;
- }
-- printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is veritualy at: %x\n",
-+ simple_map_init(&map_regions[ix].map_info);
-+
-+ printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is virtually at: %x\n",
- map_regions[ix].map_info.name,
-- map_regions[ix].map_info.map_priv_1);
-+ map_regions[ix].map_info.virt);
- map_regions[ix].mymtd = do_map_probe("cfi_probe",
- &map_regions[ix].map_info);
- if((!map_regions[ix].mymtd)&&(
- map_regions[ix].altbuswidth!=map_regions[ix].map_info.buswidth))
- {
-- printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternet buswidth "
-+ printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternate buswidth "
- "for %s flash.\n",
- map_regions[ix].map_info.name);
- map_regions[ix].map_info.buswidth =
-@@ -275,7 +237,7 @@
- map_regions[ix].mymtd = do_map_probe("cfi_probe",
- &map_regions[ix].map_info);
- }
-- map_regions[ix].mymtd->module = THIS_MODULE;
-+ map_regions[ix].mymtd->owner = THIS_MODULE;
- add_mtd_partitions(map_regions[ix].mymtd,
- map_regions[ix].parts,map_regions_parts[ix]);
- }
-@@ -297,7 +259,7 @@
- del_mtd_partitions( map_regions[ix].mymtd );
- map_destroy( map_regions[ix].mymtd );
- }
-- iounmap((void *)map_regions[ix].map_info.map_priv_1);
-+ iounmap((void *)map_regions[ix].map_info.virt);
- }
- }
- }
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/h720x-flash.c linux/drivers/mtd/maps/h720x-flash.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/h720x-flash.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/h720x-flash.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,142 @@
-+/*
-+ * Flash memory access on Hynix GMS30C7201/HMS30C7202 based
-+ * evaluation boards
-+ *
-+ * (C) 2002 Jungjun Kim <jungjun.kim@hynix.com>
-+ * 2003 Thomas Gleixner <tglx@linutronix.de>
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/slab.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+
-+static struct mtd_info *mymtd;
-+
-+static struct map_info h720x_map = {
-+ .name = "H720X",
-+ .buswidth = 4,
-+ .size = FLASH_SIZE,
-+ .phys = FLASH_PHYS,
-+};
-+
-+static struct mtd_partition h720x_partitions[] = {
-+ {
-+ .name = "ArMon",
-+ .size = 0x00080000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE
-+ },{
-+ .name = "Env",
-+ .size = 0x00040000,
-+ .offset = 0x00080000,
-+ .mask_flags = MTD_WRITEABLE
-+ },{
-+ .name = "Kernel",
-+ .size = 0x00180000,
-+ .offset = 0x000c0000,
-+ .mask_flags = MTD_WRITEABLE
-+ },{
-+ .name = "Ramdisk",
-+ .size = 0x00400000,
-+ .offset = 0x00240000,
-+ .mask_flags = MTD_WRITEABLE
-+ },{
-+ .name = "jffs2",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND
-+ }
-+};
-+
-+#define NUM_PARTITIONS (sizeof(h720x_partitions)/sizeof(h720x_partitions[0]))
-+
-+static int nr_mtd_parts;
-+static struct mtd_partition *mtd_parts;
-+static const char *probes[] = { "cmdlinepart", NULL };
-+
-+/*
-+ * Initialize FLASH support
-+ */
-+int __init h720x_mtd_init(void)
-+{
-+
-+ char *part_type = NULL;
-+
-+ h720x_map.virt = (unsigned long)ioremap(FLASH_PHYS, FLASH_SIZE);
-+
-+ if (!h720x_map.virt) {
-+ printk(KERN_ERR "H720x-MTD: ioremap failed\n");
-+ return -EIO;
-+ }
-+
-+ simple_map_init(&h720x_map);
-+
-+ // Probe for flash buswidth 4
-+ printk (KERN_INFO "H720x-MTD probing 32bit FLASH\n");
-+ mymtd = do_map_probe("cfi_probe", &h720x_map);
-+ if (!mymtd) {
-+ printk (KERN_INFO "H720x-MTD probing 16bit FLASH\n");
-+ // Probe for buswidth 2
-+ h720x_map.buswidth = 2;
-+ mymtd = do_map_probe("cfi_probe", &h720x_map);
-+ }
-+
-+ if (mymtd) {
-+ mymtd->owner = THIS_MODULE;
-+
-+#ifdef CONFIG_MTD_PARTITIONS
-+ nr_mtd_parts = parse_mtd_partitions(mymtd, probes, &mtd_parts, 0);
-+ if (nr_mtd_parts > 0)
-+ part_type = "command line";
-+#endif
-+ if (nr_mtd_parts <= 0) {
-+ mtd_parts = h720x_partitions;
-+ nr_mtd_parts = NUM_PARTITIONS;
-+ part_type = "builtin";
-+ }
-+ printk(KERN_INFO "Using %s partition table\n", part_type);
-+ add_mtd_partitions(mymtd, mtd_parts, nr_mtd_parts);
-+ return 0;
-+ }
-+
-+ iounmap((void *)h720x_map.virt);
-+ return -ENXIO;
-+}
-+
-+/*
-+ * Cleanup
-+ */
-+static void __exit h720x_mtd_cleanup(void)
-+{
-+
-+ if (mymtd) {
-+ del_mtd_partitions(mymtd);
-+ map_destroy(mymtd);
-+ }
-+
-+ /* Free partition info, if commandline partition was used */
-+ if (mtd_parts && (mtd_parts != h720x_partitions))
-+ kfree (mtd_parts);
-+
-+ if (h720x_map.virt) {
-+ iounmap((void *)h720x_map.virt);
-+ h720x_map.virt = 0;
-+ }
-+}
-+
-+
-+module_init(h720x_mtd_init);
-+module_exit(h720x_mtd_cleanup);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
-+MODULE_DESCRIPTION("MTD map driver for Hynix evaluation boards");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/ichxrom.c linux/drivers/mtd/maps/ichxrom.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/ichxrom.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/ichxrom.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,380 @@
-+/*
-+ * ichxrom.c
-+ *
-+ * Normal mappings of chips in physical memory
-+ * $Id$
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <asm/io.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/config.h>
-+#include <linux/pci.h>
-+#include <linux/pci_ids.h>
-+
-+#define xstr(s) str(s)
-+#define str(s) #s
-+#define MOD_NAME xstr(KBUILD_BASENAME)
-+
-+#define MTD_DEV_NAME_LENGTH 16
-+
-+#define RESERVE_MEM_REGION 0
-+
-+#define ICHX_FWH_REGION_START 0xFF000000UL
-+#define ICHX_FWH_REGION_SIZE 0x01000000UL
-+#define BIOS_CNTL 0x4e
-+#define FWH_DEC_EN1 0xE3
-+#define FWH_DEC_EN2 0xF0
-+#define FWH_SEL1 0xE8
-+#define FWH_SEL2 0xEE
-+
-+struct ichxrom_map_info {
-+ struct map_info map;
-+ struct mtd_info *mtd;
-+ unsigned long window_addr;
-+ struct pci_dev *pdev;
-+ struct resource window_rsrc;
-+ struct resource rom_rsrc;
-+ char mtd_name[MTD_DEV_NAME_LENGTH];
-+};
-+
-+static inline unsigned long addr(struct map_info *map, unsigned long ofs)
-+{
-+ unsigned long offset;
-+ offset = ((8*1024*1024) - map->size) + ofs;
-+ if (offset >= (4*1024*1024)) {
-+ offset += 0x400000;
-+ }
-+ return map->map_priv_1 + 0x400000 + offset;
-+}
-+
-+static inline unsigned long dbg_addr(struct map_info *map, unsigned long addr)
-+{
-+ return addr - map->map_priv_1 + ICHX_FWH_REGION_START;
-+}
-+
-+static __u8 ichxrom_read8(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readb(addr(map, ofs));
-+}
-+
-+static __u16 ichxrom_read16(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readw(addr(map, ofs));
-+}
-+
-+static __u32 ichxrom_read32(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readl(addr(map, ofs));
-+}
-+
-+static void ichxrom_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-+{
-+ memcpy_fromio(to, addr(map, from), len);
-+}
-+
-+static void ichxrom_write8(struct map_info *map, __u8 d, unsigned long ofs)
-+{
-+ __raw_writeb(d, addr(map,ofs));
-+ mb();
-+}
-+
-+static void ichxrom_write16(struct map_info *map, __u16 d, unsigned long ofs)
-+{
-+ __raw_writew(d, addr(map, ofs));
-+ mb();
-+}
-+
-+static void ichxrom_write32(struct map_info *map, __u32 d, unsigned long ofs)
-+{
-+ __raw_writel(d, addr(map, ofs));
-+ mb();
-+}
-+
-+static void ichxrom_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-+{
-+ memcpy_toio(addr(map, to), from, len);
-+}
-+
-+static struct ichxrom_map_info ichxrom_map = {
-+ .map = {
-+ .name = MOD_NAME,
-+ .phys = NO_XIP,
-+ .size = 0,
-+ .buswidth = 1,
-+ .read8 = ichxrom_read8,
-+ .read16 = ichxrom_read16,
-+ .read32 = ichxrom_read32,
-+ .copy_from = ichxrom_copy_from,
-+ .write8 = ichxrom_write8,
-+ .write16 = ichxrom_write16,
-+ .write32 = ichxrom_write32,
-+ .copy_to = ichxrom_copy_to,
-+ /* Firmware hubs only use vpp when being programmed
-+ * in a factory setting. So in-place programming
-+ * needs to use a different method.
-+ */
-+ },
-+ /* remaining fields of structure are initialized to 0 */
-+};
-+
-+enum fwh_lock_state {
-+ FWH_DENY_WRITE = 1,
-+ FWH_IMMUTABLE = 2,
-+ FWH_DENY_READ = 4,
-+};
-+
-+static void ichxrom_cleanup(struct ichxrom_map_info *info)
-+{
-+ u16 word;
-+
-+ /* Disable writes through the rom window */
-+ pci_read_config_word(info->pdev, BIOS_CNTL, &word);
-+ pci_write_config_word(info->pdev, BIOS_CNTL, word & ~1);
-+
-+ if (info->mtd) {
-+ del_mtd_device(info->mtd);
-+ map_destroy(info->mtd);
-+ info->mtd = NULL;
-+ info->map.virt = 0;
-+ }
-+ if (info->rom_rsrc.parent)
-+ release_resource(&info->rom_rsrc);
-+ if (info->window_rsrc.parent)
-+ release_resource(&info->window_rsrc);
-+
-+ if (info->window_addr) {
-+ iounmap((void *)(info->window_addr));
-+ info->window_addr = 0;
-+ }
-+}
-+
-+
-+static int ichxrom_set_lock_state(struct mtd_info *mtd, loff_t ofs, size_t len,
-+ enum fwh_lock_state state)
-+{
-+ struct map_info *map = mtd->priv;
-+ unsigned long start = ofs;
-+ unsigned long end = start + len -1;
-+
-+ /* FIXME do I need to guard against concurrency here? */
-+ /* round down to 64K boundaries */
-+ start = start & ~0xFFFF;
-+ end = end & ~0xFFFF;
-+ while (start <= end) {
-+ unsigned long ctrl_addr;
-+ ctrl_addr = addr(map, start) - 0x400000 + 2;
-+ writeb(state, ctrl_addr);
-+ start = start + 0x10000;
-+ }
-+ return 0;
-+}
-+
-+static int ichxrom_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
-+{
-+ return ichxrom_set_lock_state(mtd, ofs, len, FWH_DENY_WRITE);
-+}
-+
-+static int ichxrom_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
-+{
-+ return ichxrom_set_lock_state(mtd, ofs, len, 0);
-+}
-+
-+static int __devinit ichxrom_init_one (struct pci_dev *pdev,
-+ const struct pci_device_id *ent)
-+{
-+ u16 word;
-+ struct ichxrom_map_info *info = &ichxrom_map;
-+ unsigned long map_size;
-+
-+ /* For now I just handle the ichx and I assume there
-+ * are not a lot of resources up at the top of the address
-+ * space. It is possible to handle other devices in the
-+ * top 16MB but it is very painful. Also since
-+ * you can only really attach a FWH to an ICHX there
-+ * a number of simplifications you can make.
-+ *
-+ * Also you can page firmware hubs if an 8MB window isn't enough
-+ * but don't currently handle that case either.
-+ */
-+
-+ info->pdev = pdev;
-+
-+ /*
-+ * Try to reserve the window mem region. If this fails then
-+ * it is likely due to the window being "reseved" by the BIOS.
-+ */
-+ info->window_rsrc.name = MOD_NAME;
-+ info->window_rsrc.start = ICHX_FWH_REGION_START;
-+ info->window_rsrc.end = ICHX_FWH_REGION_START + ICHX_FWH_REGION_SIZE - 1;
-+ info->window_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-+ if (request_resource(&iomem_resource, &info->window_rsrc)) {
-+ info->window_rsrc.parent = NULL;
-+ printk(KERN_ERR MOD_NAME
-+ " %s(): Unable to register resource"
-+ " 0x%.08lx-0x%.08lx - kernel bug?\n",
-+ __func__,
-+ info->window_rsrc.start, info->window_rsrc.end);
-+ }
-+
-+ /* Enable writes through the rom window */
-+ pci_read_config_word(pdev, BIOS_CNTL, &word);
-+ if (!(word & 1) && (word & (1<<1))) {
-+ /* The BIOS will generate an error if I enable
-+ * this device, so don't even try.
-+ */
-+ printk(KERN_ERR MOD_NAME ": firmware access control, I can't enable writes\n");
-+ goto failed;
-+ }
-+ pci_write_config_word(pdev, BIOS_CNTL, word | 1);
-+
-+
-+ /* Map the firmware hub into my address space. */
-+ /* Does this use too much virtual address space? */
-+ info->window_addr = (unsigned long)ioremap(
-+ ICHX_FWH_REGION_START, ICHX_FWH_REGION_SIZE);
-+ if (!info->window_addr) {
-+ printk(KERN_ERR "Failed to ioremap\n");
-+ goto failed;
-+ }
-+
-+ /* For now assume the firmware has setup all relevant firmware
-+ * windows. We don't have enough information to handle this case
-+ * intelligently.
-+ */
-+
-+ /* FIXME select the firmware hub and enable a window to it. */
-+
-+ info->mtd = 0;
-+ info->map.map_priv_1 = info->window_addr;
-+
-+ map_size = ICHX_FWH_REGION_SIZE;
-+ while(!info->mtd && (map_size > 0)) {
-+ info->map.size = map_size;
-+ info->mtd = do_map_probe("jedec_probe", &ichxrom_map.map);
-+ map_size -= 512*1024;
-+ }
-+ if (!info->mtd) {
-+ goto failed;
-+ }
-+ /* I know I can only be a firmware hub here so put
-+ * in the special lock and unlock routines.
-+ */
-+ info->mtd->lock = ichxrom_lock;
-+ info->mtd->unlock = ichxrom_unlock;
-+
-+ info->mtd->owner = THIS_MODULE;
-+ add_mtd_device(info->mtd);
-+
-+ if (info->window_rsrc.parent) {
-+ /*
-+ * Registering the MTD device in iomem may not be possible
-+ * if there is a BIOS "reserved" and BUSY range. If this
-+ * fails then continue anyway.
-+ */
-+ snprintf(info->mtd_name, MTD_DEV_NAME_LENGTH,
-+ "mtd%d", info->mtd->index);
-+
-+ info->rom_rsrc.name = info->mtd_name;
-+ info->rom_rsrc.start = ICHX_FWH_REGION_START
-+ + ICHX_FWH_REGION_SIZE - map_size;
-+ info->rom_rsrc.end = ICHX_FWH_REGION_START
-+ + ICHX_FWH_REGION_SIZE;
-+ info->rom_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-+ if (request_resource(&info->window_rsrc, &info->rom_rsrc)) {
-+ printk(KERN_ERR MOD_NAME
-+ ": cannot reserve MTD resource\n");
-+ info->rom_rsrc.parent = NULL;
-+ }
-+ }
-+
-+ return 0;
-+
-+ failed:
-+ ichxrom_cleanup(info);
-+ return -ENODEV;
-+}
-+
-+
-+static void __devexit ichxrom_remove_one (struct pci_dev *pdev)
-+{
-+ struct ichxrom_map_info *info = &ichxrom_map;
-+ u16 word;
-+
-+ del_mtd_device(info->mtd);
-+ map_destroy(info->mtd);
-+ info->mtd = 0;
-+ info->map.map_priv_1 = 0;
-+
-+ iounmap((void *)(info->window_addr));
-+ info->window_addr = 0;
-+
-+ /* Disable writes through the rom window */
-+ pci_read_config_word(pdev, BIOS_CNTL, &word);
-+ pci_write_config_word(pdev, BIOS_CNTL, word & ~1);
-+
-+#if RESERVE_MEM_REGION
-+ release_mem_region(ICHX_FWH_REGION_START, ICHX_FWH_REGION_SIZE);
-+#endif
-+}
-+
-+static struct pci_device_id ichxrom_pci_tbl[] __devinitdata = {
-+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,
-+ PCI_ANY_ID, PCI_ANY_ID, },
-+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
-+ PCI_ANY_ID, PCI_ANY_ID, },
-+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
-+ PCI_ANY_ID, PCI_ANY_ID, },
-+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,
-+ PCI_ANY_ID, PCI_ANY_ID, },
-+ { 0, },
-+};
-+
-+MODULE_DEVICE_TABLE(pci, ichxrom_pci_tbl);
-+
-+#if 0
-+static struct pci_driver ichxrom_driver = {
-+ .name = MOD_NAME,
-+ .id_table = ichxrom_pci_tbl,
-+ .probe = ichxrom_init_one,
-+ .remove = ichxrom_remove_one,
-+};
-+#endif
-+
-+static struct pci_dev *mydev;
-+int __init init_ichxrom(void)
-+{
-+ struct pci_dev *pdev;
-+ struct pci_device_id *id;
-+ pdev = 0;
-+ for(id = ichxrom_pci_tbl; id->vendor; id++) {
-+ pdev = pci_find_device(id->vendor, id->device, 0);
-+ if (pdev) {
-+ break;
-+ }
-+ }
-+ if (pdev) {
-+ mydev = pdev;
-+ return ichxrom_init_one(pdev, &ichxrom_pci_tbl[0]);
-+ }
-+ return -ENXIO;
-+#if 0
-+ return pci_module_init(&ichxrom_driver);
-+#endif
-+}
-+
-+static void __exit cleanup_ichxrom(void)
-+{
-+ ichxrom_remove_one(mydev);
-+}
-+
-+module_init(init_ichxrom);
-+module_exit(cleanup_ichxrom);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Eric Biederman <ebiederman@lnxi.com>");
-+MODULE_DESCRIPTION("MTD map driver for BIOS chips on the ICHX southbridge");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/impa7.c linux/drivers/mtd/maps/impa7.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/impa7.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/impa7.c 2004-11-17 18:17:59.084307080 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Handle mapping of the NOR flash on implementa A7 boards
- *
-@@ -13,6 +13,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -37,75 +38,17 @@
-
- static struct mtd_info *impa7_mtd[NUM_FLASHBANKS] = { 0 };
-
--__u8 impa7_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 impa7_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 impa7_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void impa7_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void impa7_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void impa7_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void impa7_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void impa7_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
-
- static struct map_info impa7_map[NUM_FLASHBANKS] = {
- {
-- name: "impA7 NOR Flash Bank #0",
-- size: WINDOW_SIZE0,
-- buswidth: BUSWIDTH,
-- read8: impa7_read8,
-- read16: impa7_read16,
-- read32: impa7_read32,
-- copy_from: impa7_copy_from,
-- write8: impa7_write8,
-- write16: impa7_write16,
-- write32: impa7_write32,
-- copy_to: impa7_copy_to
-+ .name = "impA7 NOR Flash Bank #0",
-+ .size = WINDOW_SIZE0,
-+ .buswidth = BUSWIDTH,
- },
- {
-- name: "impA7 NOR Flash Bank #1",
-- size: WINDOW_SIZE1,
-- buswidth: BUSWIDTH,
-- read8: impa7_read8,
-- read16: impa7_read16,
-- read32: impa7_read32,
-- copy_from: impa7_copy_from,
-- write8: impa7_write8,
-- write16: impa7_write16,
-- write32: impa7_write32,
-- copy_to: impa7_copy_to
-+ .name = "impA7 NOR Flash Bank #1",
-+ .size = WINDOW_SIZE1,
-+ .buswidth = BUSWIDTH,
- },
- };
-
-@@ -117,24 +60,18 @@
- static struct mtd_partition static_partitions[] =
- {
- {
-- name: "FileSystem",
-- size: 0x800000,
-- offset: 0x00000000
-+ .name = "FileSystem",
-+ .size = 0x800000,
-+ .offset = 0x00000000
- },
- };
-
--#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
-+static int mtd_parts_nb[NUM_FLASHBANKS];
-+static struct mtd_partition *mtd_parts[NUM_FLASHBANKS];
-
--#ifdef CONFIG_MTD_CMDLINE_PARTS
--int parse_cmdline_partitions(struct mtd_info *master,
-- struct mtd_partition **pparts,
-- const char *mtd_id);
- #endif
-
--#endif
--
--static int mtd_parts_nb = 0;
--static struct mtd_partition *mtd_parts = 0;
-+static const char *probes[] = { "cmdlinepart", NULL };
-
- int __init init_impa7(void)
- {
-@@ -146,20 +83,21 @@
- { WINDOW_ADDR0, WINDOW_SIZE0 },
- { WINDOW_ADDR1, WINDOW_SIZE1 },
- };
-- char mtdid[10];
- int devicesfound = 0;
-
- for(i=0; i<NUM_FLASHBANKS; i++)
- {
- printk(KERN_NOTICE MSG_PREFIX "probing 0x%08lx at 0x%08lx\n",
- pt[i].size, pt[i].addr);
-- impa7_map[i].map_priv_1 = (unsigned long)
-- ioremap(pt[i].addr, pt[i].size);
-
-- if (!impa7_map[i].map_priv_1) {
-+ impa7_map[i].phys = pt[i].addr;
-+ impa7_map[i].virt = (unsigned long)
-+ ioremap(pt[i].addr, pt[i].size);
-+ if (!impa7_map[i].virt) {
- printk(MSG_PREFIX "failed to ioremap\n");
- return -EIO;
- }
-+ simple_map_init(&impa7_map[i]);
-
- impa7_mtd[i] = 0;
- type = rom_probe_types;
-@@ -167,43 +105,34 @@
- impa7_mtd[i] = do_map_probe(*type, &impa7_map[i]);
- }
-
-- if (impa7_mtd[i])
-- {
-- impa7_mtd[i]->module = THIS_MODULE;
-- add_mtd_device(impa7_mtd[i]);
-+ if (impa7_mtd[i]) {
-+ impa7_mtd[i]->owner = THIS_MODULE;
- devicesfound++;
- #ifdef CONFIG_MTD_PARTITIONS
--#ifdef CONFIG_MTD_CMDLINE_PARTS
-- sprintf(mtdid, MTDID, i);
-- mtd_parts_nb = parse_cmdline_partitions(impa7_mtd[i],
-- &mtd_parts,
-- mtdid);
-- if (mtd_parts_nb > 0)
-+ mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i],
-+ probes,
-+ &mtd_parts[i],
-+ 0);
-+ if (mtd_parts_nb[i] > 0) {
- part_type = "command line";
--#endif
-- if (mtd_parts_nb <= 0)
-- {
-- mtd_parts = static_partitions;
-- mtd_parts_nb = NB_OF(static_partitions);
-+ } else {
-+ mtd_parts[i] = static_partitions;
-+ mtd_parts_nb[i] = ARRAY_SIZE(static_partitions);
- part_type = "static";
- }
-- if (mtd_parts_nb <= 0)
-- {
-- printk(KERN_NOTICE MSG_PREFIX
-- "no partition info available\n");
-- }
-- else
-- {
-+
- printk(KERN_NOTICE MSG_PREFIX
- "using %s partition definition\n",
- part_type);
- add_mtd_partitions(impa7_mtd[i],
-- mtd_parts, mtd_parts_nb);
-- }
-+ mtd_parts[i], mtd_parts_nb[i]);
-+#else
-+ add_mtd_device(impa7_mtd[i]);
-+
- #endif
- }
- else
-- iounmap((void *)impa7_map[i].map_priv_1);
-+ iounmap((void *)impa7_map[i].virt);
- }
- return devicesfound == 0 ? -ENXIO : 0;
- }
-@@ -211,17 +140,16 @@
- static void __exit cleanup_impa7(void)
- {
- int i;
-- for (i=0; i<NUM_FLASHBANKS; i++)
-- {
-- if (impa7_mtd[i])
-- {
-+ for (i=0; i<NUM_FLASHBANKS; i++) {
-+ if (impa7_mtd[i]) {
-+#ifdef CONFIG_MTD_PARTITIONS
-+ del_mtd_partitions(impa7_mtd[i]);
-+#else
- del_mtd_device(impa7_mtd[i]);
-+#endif
- map_destroy(impa7_mtd[i]);
-- }
-- if (impa7_map[i].map_priv_1)
-- {
-- iounmap((void *)impa7_map[i].map_priv_1);
-- impa7_map[i].map_priv_1 = 0;
-+ iounmap((void *)impa7_map[i].virt);
-+ impa7_map[i].virt = 0;
- }
- }
- }
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/integrator-flash-v24.c linux/drivers/mtd/maps/integrator-flash-v24.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/integrator-flash-v24.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/integrator-flash-v24.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,258 @@
-+/*======================================================================
-+
-+ drivers/mtd/maps/armflash.c: ARM Flash Layout/Partitioning
-+
-+ Copyright (C) 2000 ARM Limited
-+
-+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+
-+ This is access code for flashes using ARM's flash partitioning
-+ standards.
-+
-+ $Id$
-+
-+======================================================================*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/ioport.h>
-+#include <linux/init.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/system.h>
-+
-+// board specific stuff - sorry, it should be in arch/arm/mach-*.
-+#ifdef CONFIG_ARCH_INTEGRATOR
-+
-+#define FLASH_BASE INTEGRATOR_FLASH_BASE
-+#define FLASH_SIZE INTEGRATOR_FLASH_SIZE
-+
-+#define FLASH_PART_SIZE 0x400000
-+
-+#define SC_CTRLC (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
-+#define SC_CTRLS (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
-+#define EBI_CSR1 (IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_CSR1_OFFSET)
-+#define EBI_LOCK (IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_LOCK_OFFSET)
-+
-+/*
-+ * Initialise the flash access systems:
-+ * - Disable VPP
-+ * - Assert WP
-+ * - Set write enable bit in EBI reg
-+ */
-+static void armflash_flash_init(void)
-+{
-+ unsigned int tmp;
-+
-+ __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
-+
-+ tmp = __raw_readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE;
-+ __raw_writel(tmp, EBI_CSR1);
-+
-+ if (!(__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) {
-+ __raw_writel(0xa05f, EBI_LOCK);
-+ __raw_writel(tmp, EBI_CSR1);
-+ __raw_writel(0, EBI_LOCK);
-+ }
-+}
-+
-+/*
-+ * Shutdown the flash access systems:
-+ * - Disable VPP
-+ * - Assert WP
-+ * - Clear write enable bit in EBI reg
-+ */
-+static void armflash_flash_exit(void)
-+{
-+ unsigned int tmp;
-+
-+ __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
-+
-+ /*
-+ * Clear the write enable bit in system controller EBI register.
-+ */
-+ tmp = __raw_readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE;
-+ __raw_writel(tmp, EBI_CSR1);
-+
-+ if (__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) {
-+ __raw_writel(0xa05f, EBI_LOCK);
-+ __raw_writel(tmp, EBI_CSR1);
-+ __raw_writel(0, EBI_LOCK);
-+ }
-+}
-+
-+static void armflash_flash_wp(int on)
-+{
-+ unsigned int reg;
-+
-+ if (on)
-+ reg = SC_CTRLC;
-+ else
-+ reg = SC_CTRLS;
-+
-+ __raw_writel(INTEGRATOR_SC_CTRL_nFLWP, reg);
-+}
-+
-+static void armflash_set_vpp(struct map_info *map, int on)
-+{
-+ unsigned int reg;
-+
-+ if (on)
-+ reg = SC_CTRLS;
-+ else
-+ reg = SC_CTRLC;
-+
-+ __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg);
-+}
-+#endif
-+
-+#ifdef CONFIG_ARCH_P720T
-+
-+#define FLASH_BASE (0x04000000)
-+#define FLASH_SIZE (64*1024*1024)
-+
-+#define FLASH_PART_SIZE (4*1024*1024)
-+#define FLASH_BLOCK_SIZE (128*1024)
-+
-+static void armflash_flash_init(void)
-+{
-+}
-+
-+static void armflash_flash_exit(void)
-+{
-+}
-+
-+static void armflash_flash_wp(int on)
-+{
-+}
-+
-+static void armflash_set_vpp(struct map_info *map, int on)
-+{
-+}
-+#endif
-+
-+
-+static struct map_info armflash_map =
-+{
-+ .name = "AFS",
-+ .set_vpp = armflash_set_vpp,
-+ .phys = FLASH_BASE,
-+};
-+
-+static struct mtd_info *mtd;
-+static struct mtd_partition *parts;
-+static const char *probes[] = { "RedBoot", "afs", NULL };
-+
-+static int __init armflash_cfi_init(void *base, u_int size)
-+{
-+ int ret;
-+
-+ armflash_flash_init();
-+ armflash_flash_wp(1);
-+
-+ /*
-+ * look for CFI based flash parts fitted to this board
-+ */
-+ armflash_map.size = size;
-+ armflash_map.buswidth = 4;
-+ armflash_map.virt = (unsigned long) base;
-+
-+ simple_map_init(&armflash_map);
-+
-+ /*
-+ * Also, the CFI layer automatically works out what size
-+ * of chips we have, and does the necessary identification
-+ * for us automatically.
-+ */
-+ mtd = do_map_probe("cfi_probe", &armflash_map);
-+ if (!mtd)
-+ return -ENXIO;
-+
-+ mtd->owner = THIS_MODULE;
-+
-+ ret = parse_mtd_partitions(mtd, probes, &parts, (void *)0);
-+ if (ret > 0) {
-+ ret = add_mtd_partitions(mtd, parts, ret);
-+ if (ret)
-+ printk(KERN_ERR "mtd partition registration "
-+ "failed: %d\n", ret);
-+ }
-+
-+ /*
-+ * If we got an error, free all resources.
-+ */
-+ if (ret < 0) {
-+ del_mtd_partitions(mtd);
-+ map_destroy(mtd);
-+ }
-+
-+ return ret;
-+}
-+
-+static void armflash_cfi_exit(void)
-+{
-+ if (mtd) {
-+ del_mtd_partitions(mtd);
-+ map_destroy(mtd);
-+ }
-+ if (parts)
-+ kfree(parts);
-+}
-+
-+static int __init armflash_init(void)
-+{
-+ int err = -EBUSY;
-+ void *base;
-+
-+ if (request_mem_region(FLASH_BASE, FLASH_SIZE, "flash") == NULL)
-+ goto out;
-+
-+ base = ioremap(FLASH_BASE, FLASH_SIZE);
-+ err = -ENOMEM;
-+ if (base == NULL)
-+ goto release;
-+
-+ err = armflash_cfi_init(base, FLASH_SIZE);
-+ if (err) {
-+ iounmap(base);
-+release:
-+ release_mem_region(FLASH_BASE, FLASH_SIZE);
-+ }
-+out:
-+ return err;
-+}
-+
-+static void __exit armflash_exit(void)
-+{
-+ armflash_cfi_exit();
-+ iounmap((void *)armflash_map.virt);
-+ release_mem_region(FLASH_BASE, FLASH_SIZE);
-+ armflash_flash_exit();
-+}
-+
-+module_init(armflash_init);
-+module_exit(armflash_exit);
-+
-+MODULE_AUTHOR("ARM Ltd");
-+MODULE_DESCRIPTION("ARM Integrator CFI map driver");
-+MODULE_LICENSE("GPL");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/integrator-flash.c linux/drivers/mtd/maps/integrator-flash.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/integrator-flash.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/integrator-flash.c 2004-11-17 18:17:59.101304496 +0100
-@@ -1,8 +1,9 @@
- /*======================================================================
-
-- drivers/mtd/maps/armflash.c: ARM Flash Layout/Partitioning
-+ drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver
-
- Copyright (C) 2000 ARM Limited
-+ Copyright (C) 2003 Deep Blue Solutions Ltd.
-
- 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
-@@ -21,7 +22,7 @@
- This is access code for flashes using ARM's flash partitioning
- standards.
-
-- $Id$
-+ $Id$
-
- ======================================================================*/
-
-@@ -31,268 +32,181 @@
- #include <linux/kernel.h>
- #include <linux/slab.h>
- #include <linux/ioport.h>
-+#include <linux/device.h>
- #include <linux/init.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/partitions.h>
-
-+#include <asm/mach/flash.h>
- #include <asm/hardware.h>
- #include <asm/io.h>
- #include <asm/system.h>
-
--extern int parse_afs_partitions(struct mtd_info *, struct mtd_partition **);
--
--// board specific stuff - sorry, it should be in arch/arm/mach-*.
--#ifdef CONFIG_ARCH_INTEGRATOR
--
--#define FLASH_BASE INTEGRATOR_FLASH_BASE
--#define FLASH_SIZE INTEGRATOR_FLASH_SIZE
--
--#define FLASH_PART_SIZE 0x400000
--
--#define SC_CTRLC (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
--#define SC_CTRLS (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
--#define EBI_CSR1 (IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_CSR1_OFFSET)
--#define EBI_LOCK (IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_LOCK_OFFSET)
--
--/*
-- * Initialise the flash access systems:
-- * - Disable VPP
-- * - Assert WP
-- * - Set write enable bit in EBI reg
-- */
--static void armflash_flash_init(void)
--{
-- unsigned int tmp;
--
-- __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
--
-- tmp = __raw_readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE;
-- __raw_writel(tmp, EBI_CSR1);
--
-- if (!(__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) {
-- __raw_writel(0xa05f, EBI_LOCK);
-- __raw_writel(tmp, EBI_CSR1);
-- __raw_writel(0, EBI_LOCK);
-- }
--}
--
--/*
-- * Shutdown the flash access systems:
-- * - Disable VPP
-- * - Assert WP
-- * - Clear write enable bit in EBI reg
-- */
--static void armflash_flash_exit(void)
--{
-- unsigned int tmp;
--
-- __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
--
-- /*
-- * Clear the write enable bit in system controller EBI register.
-- */
-- tmp = __raw_readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE;
-- __raw_writel(tmp, EBI_CSR1);
--
-- if (__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) {
-- __raw_writel(0xa05f, EBI_LOCK);
-- __raw_writel(tmp, EBI_CSR1);
-- __raw_writel(0, EBI_LOCK);
-- }
--}
--
--static void armflash_flash_wp(int on)
--{
-- unsigned int reg;
--
-- if (on)
-- reg = SC_CTRLC;
-- else
-- reg = SC_CTRLS;
--
-- __raw_writel(INTEGRATOR_SC_CTRL_nFLWP, reg);
--}
--
--static void armflash_set_vpp(struct map_info *map, int on)
--{
-- unsigned int reg;
--
-- if (on)
-- reg = SC_CTRLS;
-- else
-- reg = SC_CTRLC;
--
-- __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg);
--}
--#endif
--
- #ifdef CONFIG_ARCH_P720T
--
- #define FLASH_BASE (0x04000000)
- #define FLASH_SIZE (64*1024*1024)
--
--#define FLASH_PART_SIZE (4*1024*1024)
--#define FLASH_BLOCK_SIZE (128*1024)
--
--static void armflash_flash_init(void)
--{
--}
--
--static void armflash_flash_exit(void)
--{
--}
--
--static void armflash_flash_wp(int on)
--{
--}
--
--static void armflash_set_vpp(struct map_info *map, int on)
--{
--}
- #endif
-
--static __u8 armflash_read8(struct map_info *map, unsigned long ofs)
--{
-- return readb(ofs + map->map_priv_2);
--}
--
--static __u16 armflash_read16(struct map_info *map, unsigned long ofs)
--{
-- return readw(ofs + map->map_priv_2);
--}
-+struct armflash_info {
-+ struct flash_platform_data *plat;
-+ struct resource *res;
-+ struct mtd_partition *parts;
-+ struct mtd_info *mtd;
-+ struct map_info map;
-+};
-
--static __u32 armflash_read32(struct map_info *map, unsigned long ofs)
-+static void armflash_set_vpp(struct map_info *map, int on)
- {
-- return readl(ofs + map->map_priv_2);
--}
-+ struct armflash_info *info = container_of(map, struct armflash_info, map);
-
--static void armflash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy(to, (void *) (from + map->map_priv_2), len);
-+ if (info->plat && info->plat->set_vpp)
-+ info->plat->set_vpp(on);
- }
-
--static void armflash_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- writeb(d, adr + map->map_priv_2);
--}
--
--static void armflash_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- writew(d, adr + map->map_priv_2);
--}
-+static const char *probes[] = { "RedBoot", "afs", NULL };
-
--static void armflash_write32(struct map_info *map, __u32 d, unsigned long adr)
-+static int armflash_probe(struct device *_dev)
- {
-- writel(d, adr + map->map_priv_2);
--}
-+ struct platform_device *dev = to_platform_device(_dev);
-+ struct flash_platform_data *plat = dev->dev.platform_data;
-+ struct resource *res = dev->resource;
-+ unsigned int size = res->end - res->start + 1;
-+ struct armflash_info *info;
-+ int err;
-+ void *base;
-
--static void armflash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy((void *) (to + map->map_priv_2), from, len);
--}
-+ info = kmalloc(sizeof(struct armflash_info), GFP_KERNEL);
-+ if (!info) {
-+ err = -ENOMEM;
-+ goto out;
-+ }
-
--static struct map_info armflash_map =
--{
-- name: "AFS",
-- read8: armflash_read8,
-- read16: armflash_read16,
-- read32: armflash_read32,
-- copy_from: armflash_copy_from,
-- write8: armflash_write8,
-- write16: armflash_write16,
-- write32: armflash_write32,
-- copy_to: armflash_copy_to,
-- set_vpp: armflash_set_vpp,
--};
-+ memset(info, 0, sizeof(struct armflash_info));
-
--static struct mtd_info *mtd;
--static struct mtd_partition *parts;
-+ info->plat = plat;
-+ if (plat && plat->init) {
-+ err = plat->init();
-+ if (err)
-+ goto no_resource;
-+ }
-
--static int __init armflash_cfi_init(void *base, u_int size)
--{
-- int ret;
-+ info->res = request_mem_region(res->start, size, "armflash");
-+ if (!info->res) {
-+ err = -EBUSY;
-+ goto no_resource;
-+ }
-
-- armflash_flash_init();
-- armflash_flash_wp(1);
-+ base = ioremap(res->start, size);
-+ if (!base) {
-+ err = -ENOMEM;
-+ goto no_mem;
-+ }
-
- /*
- * look for CFI based flash parts fitted to this board
- */
-- armflash_map.size = size;
-- armflash_map.buswidth = 4;
-- armflash_map.map_priv_2 = (unsigned long) base;
-+ info->map.size = size;
-+ info->map.buswidth = plat->width;
-+ info->map.phys = res->start;
-+ info->map.virt = (unsigned long) base;
-+ info->map.name = dev->dev.bus_id;
-+ info->map.set_vpp = armflash_set_vpp;
-+
-+ simple_map_init(&info->map);
-
- /*
- * Also, the CFI layer automatically works out what size
- * of chips we have, and does the necessary identification
- * for us automatically.
- */
-- mtd = do_map_probe("cfi_probe", &armflash_map);
-- if (!mtd)
-- return -ENXIO;
--
-- mtd->module = THIS_MODULE;
--
-- ret = parse_afs_partitions(mtd, &parts);
-- if (ret > 0) {
-- ret = add_mtd_partitions(mtd, parts, ret);
-- if (ret)
-- printk(KERN_ERR "mtd partition registration "
-- "failed: %d\n", ret);
-+ info->mtd = do_map_probe(plat->map_name, &info->map);
-+ if (!info->mtd) {
-+ err = -ENXIO;
-+ goto no_device;
- }
-
-+ info->mtd->owner = THIS_MODULE;
-+
-+ err = parse_mtd_partitions(info->mtd, probes, &info->parts, 0);
-+ if (err > 0) {
-+ err = add_mtd_partitions(info->mtd, info->parts, err);
-+ if (err)
-+ printk(KERN_ERR
-+ "mtd partition registration failed: %d\n", err);
-+ }
-+
-+ if (err == 0)
-+ dev_set_drvdata(&dev->dev, info);
-+
- /*
- * If we got an error, free all resources.
- */
-- if (ret < 0) {
-- del_mtd_partitions(mtd);
-- map_destroy(mtd);
-+ if (err < 0) {
-+ if (info->mtd) {
-+ del_mtd_partitions(info->mtd);
-+ map_destroy(info->mtd);
- }
-+ if (info->parts)
-+ kfree(info->parts);
-
-- return ret;
--}
--
--static void armflash_cfi_exit(void)
--{
-- if (mtd) {
-- del_mtd_partitions(mtd);
-- map_destroy(mtd);
-+ no_device:
-+ iounmap(base);
-+ no_mem:
-+ release_mem_region(res->start, size);
-+ no_resource:
-+ if (plat && plat->exit)
-+ plat->exit();
-+ kfree(info);
- }
-- if (parts)
-- kfree(parts);
-+ out:
-+ return err;
- }
-
--static int __init armflash_init(void)
-+static int armflash_remove(struct device *_dev)
- {
-- int err = -EBUSY;
-- void *base;
-+ struct platform_device *dev = to_platform_device(_dev);
-+ struct armflash_info *info = dev_get_drvdata(&dev->dev);
-
-- if (request_mem_region(FLASH_BASE, FLASH_SIZE, "flash") == NULL)
-- goto out;
-+ dev_set_drvdata(&dev->dev, NULL);
-
-- base = ioremap(FLASH_BASE, FLASH_SIZE);
-- err = -ENOMEM;
-- if (base == NULL)
-- goto release;
-+ if (info) {
-+ if (info->mtd) {
-+ del_mtd_partitions(info->mtd);
-+ map_destroy(info->mtd);
-+ }
-+ if (info->parts)
-+ kfree(info->parts);
-
-- err = armflash_cfi_init(base, FLASH_SIZE);
-- if (err) {
-- iounmap(base);
--release:
-- release_mem_region(FLASH_BASE, FLASH_SIZE);
-+ iounmap((void *)info->map.virt);
-+ release_resource(info->res);
-+ kfree(info->res);
-+
-+ if (info->plat && info->plat->exit)
-+ info->plat->exit();
-+
-+ kfree(info);
- }
--out:
-- return err;
-+
-+ return 0;
-+}
-+
-+static struct device_driver armflash_driver = {
-+ .name = "armflash",
-+ .bus = &platform_bus_type,
-+ .probe = armflash_probe,
-+ .remove = armflash_remove,
-+};
-+
-+static int __init armflash_init(void)
-+{
-+ return driver_register(&armflash_driver);
- }
-
- static void __exit armflash_exit(void)
- {
-- armflash_cfi_exit();
-- iounmap((void *)armflash_map.map_priv_2);
-- release_mem_region(FLASH_BASE, FLASH_SIZE);
-- armflash_flash_exit();
-+ driver_unregister(&armflash_driver);
- }
-
- module_init(armflash_init);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/iq80310.c linux/drivers/mtd/maps/iq80310.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/iq80310.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/iq80310.c 2004-11-17 18:17:59.103304192 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Mapping for the Intel XScale IQ80310 evaluation board
- *
-@@ -14,6 +14,8 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -26,127 +28,72 @@
-
- static struct mtd_info *mymtd;
-
--static __u8 iq80310_read8(struct map_info *map, unsigned long ofs)
--{
-- return *(__u8 *)(map->map_priv_1 + ofs);
--}
--
--static __u16 iq80310_read16(struct map_info *map, unsigned long ofs)
--{
-- return *(__u16 *)(map->map_priv_1 + ofs);
--}
--
--static __u32 iq80310_read32(struct map_info *map, unsigned long ofs)
--{
-- return *(__u32 *)(map->map_priv_1 + ofs);
--}
--
--static void iq80310_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy(to, (void *)(map->map_priv_1 + from), len);
--}
--
--static void iq80310_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- *(__u8 *)(map->map_priv_1 + adr) = d;
--}
--
--static void iq80310_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- *(__u16 *)(map->map_priv_1 + adr) = d;
--}
--
--static void iq80310_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- *(__u32 *)(map->map_priv_1 + adr) = d;
--}
--
--static void iq80310_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy((void *)(map->map_priv_1 + to), from, len);
--}
--
- static struct map_info iq80310_map = {
-- name: "IQ80310 flash",
-- size: WINDOW_SIZE,
-- buswidth: BUSWIDTH,
-- read8: iq80310_read8,
-- read16: iq80310_read16,
-- read32: iq80310_read32,
-- copy_from: iq80310_copy_from,
-- write8: iq80310_write8,
-- write16: iq80310_write16,
-- write32: iq80310_write32,
-- copy_to: iq80310_copy_to
-+ .name = "IQ80310 flash",
-+ .size = WINDOW_SIZE,
-+ .buswidth = BUSWIDTH,
-+ .phys = WINDOW_ADDR
- };
-
- static struct mtd_partition iq80310_partitions[4] = {
- {
-- name: "Firmware",
-- size: 0x00080000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE /* force read-only */
-+ .name = "Firmware",
-+ .size = 0x00080000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
- },{
-- name: "Kernel",
-- size: 0x000a0000,
-- offset: 0x00080000,
-+ .name = "Kernel",
-+ .size = 0x000a0000,
-+ .offset = 0x00080000,
- },{
-- name: "Filesystem",
-- size: 0x00600000,
-- offset: 0x00120000
-+ .name = "Filesystem",
-+ .size = 0x00600000,
-+ .offset = 0x00120000
- },{
-- name: "RedBoot",
-- size: 0x000e0000,
-- offset: 0x00720000,
-- mask_flags: MTD_WRITEABLE
-+ .name = "RedBoot",
-+ .size = 0x000e0000,
-+ .offset = 0x00720000,
-+ .mask_flags = MTD_WRITEABLE
- }
- };
-
--#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
--
- static struct mtd_info *mymtd;
- static struct mtd_partition *parsed_parts;
--
--extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
-+static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-
- static int __init init_iq80310(void)
- {
- struct mtd_partition *parts;
- int nb_parts = 0;
- int parsed_nr_parts = 0;
-- char *part_type = "static";
-+ int ret;
-
-- iq80310_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-- if (!iq80310_map.map_priv_1) {
-+ iq80310_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-+ if (!iq80310_map.virt) {
- printk("Failed to ioremap\n");
- return -EIO;
- }
-+ simple_map_init(&iq80310_map);
-+
- mymtd = do_map_probe("cfi_probe", &iq80310_map);
- if (!mymtd) {
-- iounmap((void *)iq80310_map.map_priv_1);
-+ iounmap((void *)iq80310_map.virt);
- return -ENXIO;
- }
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
--#ifdef CONFIG_MTD_REDBOOT_PARTS
-- if (parsed_nr_parts == 0) {
-- int ret = parse_redboot_partitions(mymtd, &parsed_parts);
-+ ret = parse_mtd_partitions(mymtd, probes, &parsed_parts, 0);
-
-- if (ret > 0) {
-- part_type = "RedBoot";
-+ if (ret > 0)
- parsed_nr_parts = ret;
-- }
-- }
--#endif
-
- if (parsed_nr_parts > 0) {
- parts = parsed_parts;
- nb_parts = parsed_nr_parts;
- } else {
- parts = iq80310_partitions;
-- nb_parts = NB_OF(iq80310_partitions);
-+ nb_parts = ARRAY_SIZE(iq80310_partitions);
- }
-- printk(KERN_NOTICE "Using %s partition definition\n", part_type);
- add_mtd_partitions(mymtd, parts, nb_parts);
- return 0;
- }
-@@ -159,8 +106,8 @@
- if (parsed_parts)
- kfree(parsed_parts);
- }
-- if (iq80310_map.map_priv_1)
-- iounmap((void *)iq80310_map.map_priv_1);
-+ if (iq80310_map.virt)
-+ iounmap((void *)iq80310_map.virt);
- }
-
- module_init(init_iq80310);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/ixp425.c linux/drivers/mtd/maps/ixp425.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/ixp425.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/ixp425.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,220 @@
-+/*
-+ * $Id$
-+ *
-+ * drivers/mtd/maps/ixp425.c
-+ *
-+ * MTD Map file for IXP425 based systems. Please do not make per-board
-+ * map driver as the code will be 90% identical. For now just add
-+ * if(machine_is_XXX()) checks to the code. I'll clean this stuff to
-+ * use platform_data in the the future so we can get rid of that too.
-+ *
-+ * Original Author: Intel Corporation
-+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
-+ *
-+ * Copyright (C) 2002 Intel Corporation
-+ * Copyright (C) 2003 MontaVista Software, Inc.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/string.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/ioport.h>
-+#include <asm/io.h>
-+#include <asm/mach-types.h>
-+
-+#include <linux/reboot.h>
-+
-+#define WINDOW_ADDR 0x50000000
-+#define BUSWIDTH 2
-+
-+#ifndef __ARMEB__
-+#define BYTE0(h) ((h) & 0xFF)
-+#define BYTE1(h) (((h) >> 8) & 0xFF)
-+#else
-+#define BYTE0(h) (((h) >> 8) & 0xFF)
-+#define BYTE1(h) ((h) & 0xFF)
-+#endif
-+
-+static __u16
-+ixp425_read16(struct map_info *map, unsigned long ofs)
-+{
-+ return *(__u16 *) (map->map_priv_1 + ofs);
-+}
-+
-+/*
-+ * The IXP425 expansion bus only allows 16-bit wide acceses
-+ * when attached to a 16-bit wide device (such as the 28F128J3A),
-+ * so we can't just memcpy_fromio().
-+ */
-+static void
-+ixp425_copy_from(struct map_info *map, void *to,
-+ unsigned long from, ssize_t len)
-+{
-+ int i;
-+ u8 *dest = (u8 *) to;
-+ u16 *src = (u16 *) (map->map_priv_1 + from);
-+ u16 data;
-+
-+ for (i = 0; i < (len / 2); i++) {
-+ data = src[i];
-+ dest[i * 2] = BYTE0(data);
-+ dest[i * 2 + 1] = BYTE1(data);
-+ }
-+
-+ if (len & 1)
-+ dest[len - 1] = BYTE0(src[i]);
-+}
-+
-+static void
-+ixp425_write16(struct map_info *map, __u16 d, unsigned long adr)
-+{
-+ *(__u16 *) (map->map_priv_1 + adr) = d;
-+}
-+
-+static struct map_info ixp425_map = {
-+ .name = "IXP425 Flash",
-+ .buswidth = BUSWIDTH,
-+ .read16 = ixp425_read16,
-+ .copy_from = ixp425_copy_from,
-+ .write16 = ixp425_write16,
-+};
-+
-+/*
-+ * Put flash back in read mode so RedBoot can boot properly.
-+ */
-+int ixp425_mtd_reboot(struct notifier_block *n, unsigned long code, void *p)
-+{
-+ if (code != SYS_RESTART)
-+ return NOTIFY_DONE;
-+
-+ ixp425_write16(&ixp425_map, 0xff, 0x55 * 0x2);
-+ return NOTIFY_DONE;
-+}
-+
-+static struct notifier_block ixp425_mtd_notifier = {
-+ notifier_call:ixp425_mtd_reboot,
-+ next:NULL,
-+ priority:0
-+};
-+
-+static struct mtd_partition *parsed_parts;
-+static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-+
-+static struct mtd_partition ixp425_partitions[] = {
-+ {
-+ .name = "image",
-+ .offset = 0x00040000,
-+ .size = 0x00400000,
-+ }, {
-+ .name = "user",
-+ .offset = 0x00440000,
-+ .size = MTDPART_SIZ_FULL
-+ }
-+};
-+
-+#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
-+
-+static struct mtd_info *ixp425_mtd;
-+static struct resource *mtd_resource;
-+
-+static void
-+ixp425_exit(void)
-+{
-+ if (ixp425_mtd) {
-+ del_mtd_partitions(ixp425_mtd);
-+ map_destroy(ixp425_mtd);
-+ }
-+ if (ixp425_map.map_priv_1)
-+ iounmap((void *) ixp425_map.map_priv_1);
-+ if (mtd_resource)
-+ release_mem_region(WINDOW_ADDR, ixp425_map.size);
-+
-+ if (parsed_parts)
-+ kfree(parsed_parts);
-+
-+ unregister_reboot_notifier(&ixp425_mtd_notifier);
-+
-+ /* Disable flash write */
-+ *IXP425_EXP_CS0 &= ~IXP425_FLASH_WRITABLE;
-+
-+ if(machine_is_adi_coyote())
-+ *IXP425_EXP_CS1 &= ~IXP425_FLASH_WRITABLE;
-+}
-+
-+static int __init
-+ixp425_init(void)
-+{
-+ int res = -1, npart;
-+
-+ /* Enable flash write */
-+ *IXP425_EXP_CS0 |= IXP425_FLASH_WRITABLE;
-+
-+ /*
-+ * Coyote requires CS1 write to be enabled and has 32MB flash.
-+ * This will move to the platform init code in 2.6
-+ */
-+ if(machine_is_adi_coyote()) {
-+ *IXP425_EXP_CS1 |= IXP425_FLASH_WRITABLE;
-+ ixp425_map.size = 0x02000000;
-+ } else
-+ ixp425_map.size = 0x01000000;
-+
-+ ixp425_map.map_priv_1 = 0;
-+ mtd_resource =
-+ request_mem_region(WINDOW_ADDR, ixp425_map.size, "IXP425 Flash");
-+ if (!mtd_resource) {
-+ printk(KERN_ERR
-+ "ixp425 flash: Could not request mem region.\n");
-+ res = -ENOMEM;
-+ goto Error;
-+ }
-+
-+ ixp425_map.map_priv_1 =
-+ (unsigned long) ioremap(WINDOW_ADDR, ixp425_map.size);
-+ if (!ixp425_map.map_priv_1) {
-+ printk("ixp425 Flash: Failed to map IO region. (ioremap)\n");
-+ res = -EIO;
-+ goto Error;
-+ }
-+
-+ ixp425_mtd = do_map_probe("cfi_probe", &ixp425_map);
-+ if (!ixp425_mtd) {
-+ res = -ENXIO;
-+ goto Error;
-+ }
-+ ixp425_mtd->owner = THIS_MODULE;
-+
-+ /* Try to parse RedBoot partitions */
-+ npart = parse_mtd_partitions(ixp425_mtd, probes, &parsed_parts, 0);
-+ if (npart > 0)
-+ res = add_mtd_partitions(ixp425_mtd, parsed_parts, npart);
-+ else {
-+ printk("IXP425 Flash: Using static MTD partitions.\n");
-+ res = add_mtd_partitions(ixp425_mtd, ixp425_partitions,
-+ NB_OF(ixp425_partitions));
-+ }
-+
-+ if (res)
-+ goto Error;
-+
-+ register_reboot_notifier(&ixp425_mtd_notifier);
-+
-+ return res;
-+
-+Error:
-+ ixp425_exit();
-+ return res;
-+}
-+
-+module_init(ixp425_init);
-+module_exit(ixp425_exit);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("MTD map driver for ixp425 evaluation board");
-+MODULE_AUTHOR("Deepak Saxena");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/l440gx.c linux/drivers/mtd/maps/l440gx.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/l440gx.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/l440gx.c 2004-11-17 18:17:59.105303888 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * BIOS Flash chip on Intel 440GX board.
- *
-@@ -9,6 +9,7 @@
- #include <linux/module.h>
- #include <linux/pci.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -27,48 +28,6 @@
-
- static struct mtd_info *mymtd;
-
--__u8 l440gx_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 l440gx_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 l440gx_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void l440gx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void l440gx_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void l440gx_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void l440gx_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void l440gx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
-
- /* Is this really the vpp port? */
- void l440gx_set_vpp(struct map_info *map, int vpp)
-@@ -85,22 +44,15 @@
- }
-
- struct map_info l440gx_map = {
-- name: "L440GX BIOS",
-- size: WINDOW_SIZE,
-- buswidth: BUSWIDTH,
-- read8: l440gx_read8,
-- read16: l440gx_read16,
-- read32: l440gx_read32,
-- copy_from: l440gx_copy_from,
-- write8: l440gx_write8,
-- write16: l440gx_write16,
-- write32: l440gx_write32,
-- copy_to: l440gx_copy_to,
-+ .name = "L440GX BIOS",
-+ .size = WINDOW_SIZE,
-+ .buswidth = BUSWIDTH,
-+ .phys = WINDOW_ADDR,
- #if 0
- /* FIXME verify that this is the
- * appripriate code for vpp enable/disable
- */
-- set_vpp: l440gx_set_vpp
-+ .set_vpp = l440gx_set_vpp
- #endif
- };
-
-@@ -113,7 +65,6 @@
- dev = pci_find_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB_0, NULL);
-
--
- pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
-
-@@ -122,15 +73,14 @@
- return -ENODEV;
- }
-
-+ l440gx_map.virt = (unsigned long)ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE);
-
-- l440gx_map.map_priv_1 = (unsigned long)ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE);
--
-- if (!l440gx_map.map_priv_1) {
-+ if (!l440gx_map.virt) {
- printk(KERN_WARNING "Failed to ioremap L440GX flash region\n");
- return -ENOMEM;
- }
--
-- printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.map_priv_1);
-+ simple_map_init(&l440gx_map);
-+ printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.virt);
-
- /* Setup the pm iobase resource
- * This code should move into some kind of generic bridge
-@@ -153,7 +103,7 @@
- /* Allocate the resource region */
- if (pci_assign_resource(pm_dev, PIIXE_IOBASE_RESOURCE) != 0) {
- printk(KERN_WARNING "Could not allocate pm iobase resource\n");
-- iounmap((void *)l440gx_map.map_priv_1);
-+ iounmap((void *)l440gx_map.virt);
- return -ENXIO;
- }
- }
-@@ -181,13 +131,13 @@
- mymtd = do_map_probe("map_rom", &l440gx_map);
- }
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
- add_mtd_device(mymtd);
- return 0;
- }
-
-- iounmap((void *)l440gx_map.map_priv_1);
-+ iounmap((void *)l440gx_map.virt);
- return -ENXIO;
- }
-
-@@ -196,7 +146,7 @@
- del_mtd_device(mymtd);
- map_destroy(mymtd);
-
-- iounmap((void *)l440gx_map.map_priv_1);
-+ iounmap((void *)l440gx_map.virt);
- }
-
- module_init(init_l440gx);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/lasat.c linux/drivers/mtd/maps/lasat.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/lasat.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/lasat.c 2004-11-17 18:17:59.106303736 +0100
-@@ -1,11 +1,20 @@
- /*
-- * Flash device on lasat 100 and 200 boards
-+ * Flash device on Lasat 100 and 200 boards
-+ *
-+ * (C) 2002 Brian Murphy <brian@murphy.dk>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version
-+ * 2 as published by the Free Software Foundation.
-+ *
-+ * $Id$
- *
- */
-
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -13,123 +22,80 @@
- #include <linux/config.h>
- #include <asm/lasat/lasat.h>
-
--static struct mtd_info *mymtd;
--
--static __u8 sp_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--static __u16 sp_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--static __u32 sp_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--static void sp_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
-+static struct mtd_info *lasat_mtd;
-
--static void sp_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void sp_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void sp_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
-+static struct mtd_partition partition_info[LASAT_MTD_LAST];
-+static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Filesystem", "Config"};
-
--static void sp_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-+static void lasat_set_vpp(struct map_info *map, int vpp)
- {
-- memcpy_toio(map->map_priv_1 + to, from, len);
-+ if (vpp)
-+ *lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit;
-+ else
-+ *lasat_misc->flash_wp_reg &= ~(1 << lasat_misc->flash_wp_bit);
- }
-
--static struct map_info sp_map = {
-- name: "SP flash",
-- buswidth: 4,
-- read8: sp_read8,
-- read16: sp_read16,
-- read32: sp_read32,
-- copy_from: sp_copy_from,
-- write8: sp_write8,
-- write16: sp_write16,
-- write32: sp_write32,
-- copy_to: sp_copy_to
-+static struct map_info lasat_map = {
-+ .name = "LASAT flash",
-+ .buswidth = 4,
-+ .set_vpp = lasat_set_vpp
- };
-
--static struct mtd_partition partition_info[LASAT_MTD_LAST];
--static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Config", "Filesystem"};
--
--static int __init init_sp(void)
-+static int __init init_lasat(void)
- {
- int i;
-- int nparts = 0;
-- /* this does not play well with the old flash code which
-- * protects and uprotects the flash when necessary */
-+ /* since we use AMD chips and set_vpp is not implimented
-+ * for these (yet) we still have to permanently enable flash write */
- printk(KERN_NOTICE "Unprotecting flash\n");
-- *lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit;
-+ ENABLE_VPP((&lasat_map));
-
-- sp_map.map_priv_1 = ioremap_nocache(
-- lasat_flash_partition_start(LASAT_MTD_BOOTLOADER),
-- lasat_board_info.li_flash_size);
-- sp_map.size = lasat_board_info.li_flash_size;
-+ lasat_map.phys = lasat_flash_partition_start(LASAT_MTD_BOOTLOADER);
-+ lasat_map.virt = (unsigned long)ioremap_nocache(
-+ lasat_map.phys, lasat_board_info.li_flash_size);
-+ lasat_map.size = lasat_board_info.li_flash_size;
-
-- printk(KERN_NOTICE "sp flash device: %lx at %lx\n",
-- sp_map.size, sp_map.map_priv_1);
-+ simple_map_init(&lasat_map);
-
- for (i=0; i < LASAT_MTD_LAST; i++)
- partition_info[i].name = lasat_mtd_partnames[i];
-
-- mymtd = do_map_probe("cfi_probe", &sp_map);
-- if (mymtd) {
-+ lasat_mtd = do_map_probe("cfi_probe", &lasat_map);
-+
-+ if (!lasat_mtd)
-+ lasat_mtd = do_map_probe("jedec_probe", &lasat_map);
-+
-+ if (lasat_mtd) {
- u32 size, offset = 0;
-
-- mymtd->module = THIS_MODULE;
-+ lasat_mtd->owner = THIS_MODULE;
-
- for (i=0; i < LASAT_MTD_LAST; i++) {
- size = lasat_flash_partition_size(i);
-- if (size != 0) {
-- nparts++;
- partition_info[i].size = size;
- partition_info[i].offset = offset;
- offset += size;
- }
-- }
-
-- add_mtd_partitions( mymtd, partition_info, nparts );
-+ add_mtd_partitions( lasat_mtd, partition_info, LASAT_MTD_LAST );
- return 0;
- }
-
- return -ENXIO;
- }
-
--static void __exit cleanup_sp(void)
-+static void __exit cleanup_lasat(void)
- {
-- if (mymtd) {
-- del_mtd_partitions(mymtd);
-- map_destroy(mymtd);
-+ if (lasat_mtd) {
-+ del_mtd_partitions(lasat_mtd);
-+ map_destroy(lasat_mtd);
- }
-- if (sp_map.map_priv_1) {
-- sp_map.map_priv_1 = 0;
-+ if (lasat_map.virt) {
-+ lasat_map.virt = 0;
- }
- }
-
--module_init(init_sp);
--module_exit(cleanup_sp);
-+module_init(init_lasat);
-+module_exit(cleanup_lasat);
-
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Brian Murphy <brian@murphy.dk>");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/lubbock-flash.c linux/drivers/mtd/maps/lubbock-flash.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/lubbock-flash.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/lubbock-flash.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,151 @@
-+/*
-+ * $Id$
-+ *
-+ * Map driver for the Lubbock developer platform.
-+ *
-+ * Author: Nicolas Pitre
-+ * Copyright: (C) 2001 MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <asm/io.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+#include <asm/hardware.h>
-+
-+
-+#define ROM_ADDR 0x00000000
-+#define FLASH_ADDR 0x04000000
-+
-+#define WINDOW_SIZE 64*1024*1024
-+
-+static struct map_info lubbock_maps[2] = { {
-+ .size = WINDOW_SIZE,
-+ .phys = 0x00000000,
-+}, {
-+ .size = WINDOW_SIZE,
-+ .phys = 0x04000000,
-+} };
-+
-+static struct mtd_partition lubbock_partitions[] = {
-+ {
-+ .name = "Bootloader",
-+ .size = 0x00040000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
-+ },{
-+ .name = "Kernel",
-+ .size = 0x00100000,
-+ .offset = 0x00040000,
-+ },{
-+ .name = "Filesystem",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = 0x00140000
-+ }
-+};
-+
-+static struct mtd_info *mymtds[2];
-+static struct mtd_partition *parsed_parts[2];
-+static int nr_parsed_parts[2];
-+
-+static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-+
-+static int __init init_lubbock(void)
-+{
-+ int flashboot = (CONF_SWITCHES & 1);
-+ int ret = 0, i;
-+
-+ lubbock_maps[0].buswidth = lubbock_maps[1].buswidth =
-+ (BOOT_DEF & 1) ? 2 : 4;
-+
-+ /* Compensate for the nROMBT switch which swaps the flash banks */
-+ printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n",
-+ flashboot?"Flash":"ROM", flashboot);
-+
-+ lubbock_maps[flashboot^1].name = "Lubbock Application Flash";
-+ lubbock_maps[flashboot].name = "Lubbock Boot ROM";
-+
-+ for (i = 0; i < 2; i++) {
-+ lubbock_maps[i].virt = (unsigned long)__ioremap(lubbock_maps[i].phys, WINDOW_SIZE, 0);
-+ if (!lubbock_maps[i].virt) {
-+ printk(KERN_WARNING "Failed to ioremap %s\n", lubbock_maps[i].name);
-+ if (!ret)
-+ ret = -ENOMEM;
-+ continue;
-+ }
-+ simple_map_init(&lubbock_maps[i]);
-+
-+ printk(KERN_NOTICE "Probing %s at physical address 0x%08lx (%d-bit buswidth)\n",
-+ lubbock_maps[i].name, lubbock_maps[i].phys,
-+ lubbock_maps[i].buswidth * 8);
-+
-+ mymtds[i] = do_map_probe("cfi_probe", &lubbock_maps[i]);
-+
-+ if (!mymtds[i]) {
-+ iounmap((void *)lubbock_maps[i].virt);
-+ if (!ret)
-+ ret = -EIO;
-+ continue;
-+ }
-+ mymtds[i]->owner = THIS_MODULE;
-+
-+ int ret = parse_mtd_partitions(mymtds[i], probes,
-+ &parsed_parts[i], 0);
-+
-+ if (ret > 0)
-+ nr_parsed_parts[i] = ret;
-+ }
-+
-+ if (!mymtds[0] && !mymtds[1])
-+ return ret;
-+
-+ for (i = 0; i < 2; i++) {
-+ if (!mymtds[i]) {
-+ printk(KERN_WARNING "%s is absent. Skipping\n", lubbock_maps[i].name);
-+ } else if (nr_parsed_parts[i]) {
-+ add_mtd_partitions(mymtds[i], parsed_parts[i], nr_parsed_parts[i]);
-+ } else if (!i) {
-+ printk("Using static partitions on %s\n", lubbock_maps[i].name);
-+ add_mtd_partitions(mymtds[i], lubbock_partitions, ARRAY_SIZE(lubbock_partitions));
-+ } else {
-+ printk("Registering %s as whole device\n", lubbock_maps[i].name);
-+ add_mtd_device(mymtds[i]);
-+ }
-+ }
-+ return 0;
-+}
-+
-+static void __exit cleanup_lubbock(void)
-+{
-+ int i;
-+ for (i = 0; i < 2; i++) {
-+ if (!mymtds[i])
-+ continue;
-+
-+ if (nr_parsed_parts[i] || !i)
-+ del_mtd_partitions(mymtds[i]);
-+ else
-+ del_mtd_device(mymtds[i]);
-+
-+ map_destroy(mymtds[i]);
-+ iounmap((void *)lubbock_maps[i].virt);
-+
-+ if (parsed_parts[i])
-+ kfree(parsed_parts[i]);
-+ }
-+}
-+
-+module_init(init_lubbock);
-+module_exit(cleanup_lubbock);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
-+MODULE_DESCRIPTION("MTD map driver for Intel Lubbock");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/map_funcs.c linux/drivers/mtd/maps/map_funcs.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/map_funcs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/map_funcs.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,96 @@
-+/*
-+ * $Id$
-+ *
-+ * Out-of-line map I/O functions for simple maps when CONFIG_COMPLEX_MAPPINGS
-+ * is enabled.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/config.h>
-+#include <linux/types.h>
-+#include <linux/string.h>
-+#include <asm/io.h>
-+
-+#include <linux/mtd/map.h>
-+
-+static u8 simple_map_read8(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readb(map->virt + ofs);
-+}
-+
-+static u16 simple_map_read16(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readw(map->virt + ofs);
-+}
-+
-+static u32 simple_map_read32(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readl(map->virt + ofs);
-+}
-+
-+static u64 simple_map_read64(struct map_info *map, unsigned long ofs)
-+{
-+#ifndef CONFIG_MTD_CFI_B8 /* 64-bit mappings */
-+ BUG();
-+ return 0;
-+#else
-+ return __raw_readll(map->virt + ofs);
-+#endif
-+}
-+
-+static void simple_map_write8(struct map_info *map, u8 datum, unsigned long ofs)
-+{
-+ __raw_writeb(datum, map->virt + ofs);
-+ mb();
-+}
-+
-+static void simple_map_write16(struct map_info *map, u16 datum, unsigned long ofs)
-+{
-+ __raw_writew(datum, map->virt + ofs);
-+ mb();
-+}
-+
-+static void simple_map_write32(struct map_info *map, u32 datum, unsigned long ofs)
-+{
-+ __raw_writel(datum, map->virt + ofs);
-+ mb();
-+}
-+
-+static void simple_map_write64(struct map_info *map, u64 datum, unsigned long ofs)
-+{
-+#ifndef CONFIG_MTD_CFI_B8 /* 64-bit mappings */
-+ BUG();
-+#else
-+ __raw_writell(datum, map->virt + ofs);
-+ mb();
-+#endif /* CFI_B8 */
-+}
-+
-+static void simple_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-+{
-+ memcpy_fromio(to, map->virt + from, len);
-+}
-+
-+static void simple_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-+{
-+ memcpy_toio(map->virt + to, from, len);
-+}
-+
-+void simple_map_init(struct map_info *map)
-+{
-+ map->read8 = simple_map_read8;
-+ map->read16 = simple_map_read16;
-+ map->read32 = simple_map_read32;
-+ map->read64 = simple_map_read64;
-+ map->write8 = simple_map_write8;
-+ map->write16 = simple_map_write16;
-+ map->write32 = simple_map_write32;
-+ map->write64 = simple_map_write64;
-+ map->copy_from = simple_map_copy_from;
-+ map->copy_to = simple_map_copy_to;
-+}
-+
-+EXPORT_SYMBOL(simple_map_init);
-+
-+MODULE_LICENSE("GPL");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/mbx860.c linux/drivers/mtd/maps/mbx860.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/mbx860.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/mbx860.c 2004-11-17 18:17:59.110303128 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Handle mapping of the flash on MBX860 boards
- *
-@@ -15,6 +15,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -36,91 +37,46 @@
- * single flash device into. If the size if zero we use up to the end of the
- * device. */
- static struct mtd_partition partition_info[]={
-- { name: "MBX flash BOOT partition",
-- offset: 0,
-- size: BOOT_PARTITION_SIZE_KiB*1024 },
-- { name: "MBX flash DATA partition",
-- offset: BOOT_PARTITION_SIZE_KiB*1024,
-- size: (KERNEL_PARTITION_SIZE_KiB)*1024 },
-- { name: "MBX flash APPLICATION partition",
-- offset: (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 }
-+ { .name = "MBX flash BOOT partition",
-+ .offset = 0,
-+ .size = BOOT_PARTITION_SIZE_KiB*1024 },
-+ { .name = "MBX flash DATA partition",
-+ .offset = BOOT_PARTITION_SIZE_KiB*1024,
-+ .size = (KERNEL_PARTITION_SIZE_KiB)*1024 },
-+ { .name = "MBX flash APPLICATION partition",
-+ .offset = (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 }
- };
-
-
- static struct mtd_info *mymtd;
-
--__u8 mbx_read8(struct map_info *map, unsigned long ofs)
--{
-- return readb(map->map_priv_1 + ofs);
--}
--
--__u16 mbx_read16(struct map_info *map, unsigned long ofs)
--{
-- return readw(map->map_priv_1 + ofs);
--}
--
--__u32 mbx_read32(struct map_info *map, unsigned long ofs)
--{
-- return readl(map->map_priv_1 + ofs);
--}
--
--void mbx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
--}
--
--void mbx_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- writeb(d, map->map_priv_1 + adr);
--}
--
--void mbx_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- writew(d, map->map_priv_1 + adr);
--}
--
--void mbx_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- writel(d, map->map_priv_1 + adr);
--}
--
--void mbx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio((void *)(map->map_priv_1 + to), from, len);
--}
--
- struct map_info mbx_map = {
-- name: "MBX flash",
-- size: WINDOW_SIZE,
-- buswidth: 4,
-- read8: mbx_read8,
-- read16: mbx_read16,
-- read32: mbx_read32,
-- copy_from: mbx_copy_from,
-- write8: mbx_write8,
-- write16: mbx_write16,
-- write32: mbx_write32,
-- copy_to: mbx_copy_to
-+ .name = "MBX flash",
-+ .size = WINDOW_SIZE,
-+ .phys = WINDOW_ADDR,
-+ .buswidth = 4,
- };
-
- int __init init_mbx(void)
- {
-- printk(KERN_NOTICE "Motorola MBX flash device: %x at %x\n", WINDOW_SIZE*4, WINDOW_ADDR);
-- mbx_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4);
-+ printk(KERN_NOTICE "Motorola MBX flash device: 0x%x at 0x%x\n", WINDOW_SIZE*4, WINDOW_ADDR);
-+ mbx_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4);
-
-- if (!mbx_map.map_priv_1) {
-+ if (!mbx_map.virt) {
- printk("Failed to ioremap\n");
- return -EIO;
- }
-+ simple_map_init(&mbx_map);
-+
- mymtd = do_map_probe("jedec_probe", &mbx_map);
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
- add_mtd_device(mymtd);
- add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
- return 0;
- }
-
-- iounmap((void *)mbx_map.map_priv_1);
-+ iounmap((void *)mbx_map.virt);
- return -ENXIO;
- }
-
-@@ -130,9 +86,9 @@
- del_mtd_device(mymtd);
- map_destroy(mymtd);
- }
-- if (mbx_map.map_priv_1) {
-- iounmap((void *)mbx_map.map_priv_1);
-- mbx_map.map_priv_1 = 0;
-+ if (mbx_map.virt) {
-+ iounmap((void *)mbx_map.virt);
-+ mbx_map.virt = 0;
- }
- }
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/mpc1211.c linux/drivers/mtd/maps/mpc1211.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/mpc1211.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/mpc1211.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,79 @@
-+/*
-+ * Flash on MPC-1211
-+ *
-+ * (C) 2002 Interface, Saito.K & Jeanne
-+ *
-+ * GPL'd
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <asm/io.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/config.h>
-+
-+static struct mtd_info *flash_mtd;
-+static struct mtd_partition *parsed_parts;
-+
-+struct map_info mpc1211_flash_map = {
-+ .name = "MPC-1211 FLASH",
-+ .size = 0x80000,
-+ .buswidth = 1,
-+};
-+
-+static struct mtd_partition mpc1211_partitions[] = {
-+ {
-+ .name = "IPL & ETH-BOOT",
-+ .offset = 0x00000000,
-+ .size = 0x10000,
-+ },
-+ {
-+ .name = "Flash FS",
-+ .offset = 0x00010000,
-+ .size = MTDPART_SIZ_FULL,
-+ }
-+};
-+
-+static int __init init_mpc1211_maps(void)
-+{
-+ int nr_parts;
-+
-+ mpc1211_flash_map.phys = 0;
-+ mpc1211_flash_map.virt = P2SEGADDR(0);
-+
-+ simple_map_init(&mpc1211_flash_map);
-+
-+ printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n");
-+ flash_mtd = do_map_probe("jedec_probe", &mpc1211_flash_map);
-+ if (!flash_mtd) {
-+ printk(KERN_NOTICE "Flash chips not detected at either possible location.\n");
-+ return -ENXIO;
-+ }
-+ printk(KERN_NOTICE "MPC-1211: Flash at 0x%08lx\n", mpc1211_flash_map.virt & 0x1fffffff);
-+ flash_mtd->module = THIS_MODULE;
-+
-+ parsed_parts = mpc1211_partitions;
-+ nr_parts = ARRAY_SIZE(mpc1211_partitions);
-+
-+ add_mtd_partitions(flash_mtd, parsed_parts, nr_parts);
-+ return 0;
-+}
-+
-+static void __exit cleanup_mpc1211_maps(void)
-+{
-+ if (parsed_parts)
-+ del_mtd_partitions(flash_mtd);
-+ else
-+ del_mtd_device(flash_mtd);
-+ map_destroy(flash_mtd);
-+}
-+
-+module_init(init_mpc1211_maps);
-+module_exit(cleanup_mpc1211_maps);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Saito.K & Jeanne <ksaito@interface.co.jp>");
-+MODULE_DESCRIPTION("MTD map driver for MPC-1211 boards. Interface");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/netsc520.c linux/drivers/mtd/maps/netsc520.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/netsc520.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/netsc520.c 2004-11-17 18:17:59.113302672 +0100
-@@ -3,7 +3,7 @@
- * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com)
- * based on sc520cdp.c by Sysgo Real-Time Solutions GmbH
- *
-- * $Id$
-+ * $Id$
- *
- * 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
-@@ -27,6 +27,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -50,95 +51,41 @@
- ** recoverable afterwards.
- */
-
--static __u8 netsc520_read8(struct map_info *map, unsigned long ofs)
--{
-- return readb(map->map_priv_1 + ofs);
--}
--
--static __u16 netsc520_read16(struct map_info *map, unsigned long ofs)
--{
-- return readw(map->map_priv_1 + ofs);
--}
--
--static __u32 netsc520_read32(struct map_info *map, unsigned long ofs)
--{
-- return readl(map->map_priv_1 + ofs);
--}
--
--static void netsc520_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
--}
--
--static void netsc520_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- writeb(d, map->map_priv_1 + adr);
--}
--
--static void netsc520_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- writew(d, map->map_priv_1 + adr);
--}
--
--static void netsc520_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- writel(d, map->map_priv_1 + adr);
--}
--
--static void netsc520_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio((void *)(map->map_priv_1 + to), from, len);
--}
--
- /* partition_info gives details on the logical partitions that the split the
- * single flash device into. If the size if zero we use up to the end of the
- * device. */
- static struct mtd_partition partition_info[]={
- {
-- name: "NetSc520 boot kernel",
-- offset: 0,
-- size: 0xc0000
-+ .name = "NetSc520 boot kernel",
-+ .offset = 0,
-+ .size = 0xc0000
- },
- {
-- name: "NetSc520 Low BIOS",
-- offset: 0xc0000,
-- size: 0x40000
-+ .name = "NetSc520 Low BIOS",
-+ .offset = 0xc0000,
-+ .size = 0x40000
- },
- {
-- name: "NetSc520 file system",
-- offset: 0x100000,
-- size: 0xe80000
-+ .name = "NetSc520 file system",
-+ .offset = 0x100000,
-+ .size = 0xe80000
- },
- {
-- name: "NetSc520 High BIOS",
-- offset: 0xf80000,
-- size: 0x80000
-+ .name = "NetSc520 High BIOS",
-+ .offset = 0xf80000,
-+ .size = 0x80000
- },
- };
- #define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0]))
-
--/*
-- * If no idea what is going on here. This is taken from the FlashFX stuff.
-- */
--#define ROMCS 1
--
--
- #define WINDOW_SIZE 0x00100000
- #define WINDOW_ADDR 0x00200000
-
- static struct map_info netsc520_map = {
-- name: "netsc520 Flash Bank",
-- size: WINDOW_SIZE,
-- buswidth: 4,
-- read8: netsc520_read8,
-- read16: netsc520_read16,
-- read32: netsc520_read32,
-- copy_from: netsc520_copy_from,
-- write8: netsc520_write8,
-- write16: netsc520_write16,
-- write32: netsc520_write32,
-- copy_to: netsc520_copy_to,
-- map_priv_2: WINDOW_ADDR
-+ .name = "netsc520 Flash Bank",
-+ .size = WINDOW_SIZE,
-+ .buswidth = 4,
-+ .phys = WINDOW_ADDR,
- };
-
- #define NUM_FLASH_BANKS (sizeof(netsc520_map)/sizeof(struct map_info))
-@@ -147,13 +94,16 @@
-
- static int __init init_netsc520(void)
- {
-- printk(KERN_NOTICE "NetSc520 flash device: %lx at %lx\n", netsc520_map.size, netsc520_map.map_priv_2);
-- netsc520_map.map_priv_1 = (unsigned long)ioremap_nocache(netsc520_map.map_priv_2, netsc520_map.size);
-+ printk(KERN_NOTICE "NetSc520 flash device: 0x%lx at 0x%lx\n", netsc520_map.size, netsc520_map.phys);
-+ netsc520_map.virt = (unsigned long)ioremap_nocache(netsc520_map.phys, netsc520_map.size);
-
-- if (!netsc520_map.map_priv_1) {
-+ if (!netsc520_map.virt) {
- printk("Failed to ioremap_nocache\n");
- return -EIO;
- }
-+
-+ simple_map_init(&netsc520_map);
-+
- mymtd = do_map_probe("cfi_probe", &netsc520_map);
- if(!mymtd)
- mymtd = do_map_probe("map_ram", &netsc520_map);
-@@ -161,11 +111,11 @@
- mymtd = do_map_probe("map_rom", &netsc520_map);
-
- if (!mymtd) {
-- iounmap((void *)netsc520_map.map_priv_1);
-+ iounmap((void *)netsc520_map.virt);
- return -ENXIO;
- }
-
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
- add_mtd_partitions( mymtd, partition_info, NUM_PARTITIONS );
- return 0;
- }
-@@ -176,9 +126,9 @@
- del_mtd_partitions(mymtd);
- map_destroy(mymtd);
- }
-- if (netsc520_map.map_priv_1) {
-- iounmap((void *)netsc520_map.map_priv_1);
-- netsc520_map.map_priv_1 = 0;
-+ if (netsc520_map.virt) {
-+ iounmap((void *)netsc520_map.virt);
-+ netsc520_map.virt = 0;
- }
- }
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/nettel.c linux/drivers/mtd/maps/nettel.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/nettel.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/nettel.c 2004-11-17 18:17:59.114302520 +0100
-@@ -6,7 +6,7 @@
- * (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com)
- * (C) Copyright 2001-2002, SnapGear (www.snapgear.com)
- *
-- * $Id$
-+ * $Id$
- */
-
- /****************************************************************************/
-@@ -59,128 +59,72 @@
-
- /****************************************************************************/
-
--static __u8 nettel_read8(struct map_info *map, unsigned long ofs)
--{
-- return(readb(map->map_priv_1 + ofs));
--}
--
--static __u16 nettel_read16(struct map_info *map, unsigned long ofs)
--{
-- return(readw(map->map_priv_1 + ofs));
--}
--
--static __u32 nettel_read32(struct map_info *map, unsigned long ofs)
--{
-- return(readl(map->map_priv_1 + ofs));
--}
--
--static void nettel_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--static void nettel_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- writeb(d, map->map_priv_1 + adr);
--}
--
--static void nettel_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- writew(d, map->map_priv_1 + adr);
--}
--
--static void nettel_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- writel(d, map->map_priv_1 + adr);
--}
--
--static void nettel_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
--
- /****************************************************************************/
-
- #ifdef CONFIG_MTD_CFI_INTELEXT
- static struct map_info nettel_intel_map = {
-- name: "SnapGear Intel",
-- size: 0,
-- buswidth: INTEL_BUSWIDTH,
-- read8: nettel_read8,
-- read16: nettel_read16,
-- read32: nettel_read32,
-- copy_from: nettel_copy_from,
-- write8: nettel_write8,
-- write16: nettel_write16,
-- write32: nettel_write32,
-- copy_to: nettel_copy_to
-+ .name = "SnapGear Intel",
-+ .size = 0,
-+ .buswidth = INTEL_BUSWIDTH,
- };
-
- static struct mtd_partition nettel_intel_partitions[] = {
- {
-- name: "SnapGear kernel",
-- offset: 0,
-- size: 0x000e0000
-+ .name = "SnapGear kernel",
-+ .offset = 0,
-+ .size = 0x000e0000
- },
- {
-- name: "SnapGear filesystem",
-- offset: 0x00100000,
-+ .name = "SnapGear filesystem",
-+ .offset = 0x00100000,
- },
- {
-- name: "SnapGear config",
-- offset: 0x000e0000,
-- size: 0x00020000
-+ .name = "SnapGear config",
-+ .offset = 0x000e0000,
-+ .size = 0x00020000
- },
- {
-- name: "SnapGear Intel",
-- offset: 0
-+ .name = "SnapGear Intel",
-+ .offset = 0
- },
- {
-- name: "SnapGear BIOS Config",
-- offset: 0x007e0000,
-- size: 0x00020000
-+ .name = "SnapGear BIOS Config",
-+ .offset = 0x007e0000,
-+ .size = 0x00020000
- },
- {
-- name: "SnapGear BIOS",
-- offset: 0x007e0000,
-- size: 0x00020000
-+ .name = "SnapGear BIOS",
-+ .offset = 0x007e0000,
-+ .size = 0x00020000
- },
- };
- #endif
-
- static struct map_info nettel_amd_map = {
-- name: "SnapGear AMD",
-- size: AMD_WINDOW_MAXSIZE,
-- buswidth: AMD_BUSWIDTH,
-- read8: nettel_read8,
-- read16: nettel_read16,
-- read32: nettel_read32,
-- copy_from: nettel_copy_from,
-- write8: nettel_write8,
-- write16: nettel_write16,
-- write32: nettel_write32,
-- copy_to: nettel_copy_to
-+ .name = "SnapGear AMD",
-+ .size = AMD_WINDOW_MAXSIZE,
-+ .buswidth = AMD_BUSWIDTH,
- };
-
- static struct mtd_partition nettel_amd_partitions[] = {
- {
-- name: "SnapGear BIOS config",
-- offset: 0x000e0000,
-- size: 0x00010000
-+ .name = "SnapGear BIOS config",
-+ .offset = 0x000e0000,
-+ .size = 0x00010000
- },
- {
-- name: "SnapGear BIOS",
-- offset: 0x000f0000,
-- size: 0x00010000
-+ .name = "SnapGear BIOS",
-+ .offset = 0x000f0000,
-+ .size = 0x00010000
- },
- {
-- name: "SnapGear AMD",
-- offset: 0
-+ .name = "SnapGear AMD",
-+ .offset = 0
- },
- {
-- name: "SnapGear high BIOS",
-- offset: 0x001f0000,
-- size: 0x00010000
-+ .name = "SnapGear high BIOS",
-+ .offset = 0x001f0000,
-+ .size = 0x00010000
- }
- };
-
-@@ -328,18 +272,20 @@
- *amdpar = SC520_PAR(SC520_PAR_BOOTCS, amdaddr, maxsize);
- __asm__ ("wbinvd");
-
-- nettel_amd_map.map_priv_1 = (unsigned long)
-+ nettel_amd_map.phys = amdaddr;
-+ nettel_amd_map.virt = (unsigned long)
- ioremap_nocache(amdaddr, maxsize);
-- if (!nettel_amd_map.map_priv_1) {
-+ if (!nettel_amd_map.virt) {
- printk("SNAPGEAR: failed to ioremap() BOOTCS\n");
- return(-EIO);
- }
-+ simple_map_init(&nettel_amd_map);
-
- if ((amd_mtd = do_map_probe("jedec_probe", &nettel_amd_map))) {
- printk(KERN_NOTICE "SNAPGEAR: AMD flash device size = %dK\n",
- amd_mtd->size>>10);
-
-- amd_mtd->module = THIS_MODULE;
-+ amd_mtd->owner = THIS_MODULE;
-
- /* The high BIOS partition is only present for 2MB units */
- num_amd_partitions = NUM_AMD_PARTITIONS;
-@@ -387,8 +333,8 @@
-
- /* Destroy useless AMD MTD mapping */
- amd_mtd = NULL;
-- iounmap((void *) nettel_amd_map.map_priv_1);
-- nettel_amd_map.map_priv_1 = (unsigned long) NULL;
-+ iounmap((void *) nettel_amd_map.virt);
-+ nettel_amd_map.virt = (unsigned long) NULL;
- #else
- /* Only AMD flash supported */
- return(-ENXIO);
-@@ -411,16 +357,18 @@
-
- /* Probe for the the size of the first Intel flash */
- nettel_intel_map.size = maxsize;
-- nettel_intel_map.map_priv_1 = (unsigned long)
-+ nettel_intel_map.phys = intel0addr;
-+ nettel_intel_map.virt = (unsigned long)
- ioremap_nocache(intel0addr, maxsize);
-- if (!nettel_intel_map.map_priv_1) {
-+ if (!nettel_intel_map.virt) {
- printk("SNAPGEAR: failed to ioremap() ROMCS1\n");
- return(-EIO);
- }
-+ simple_map_init(&nettel_intel_map);
-
- intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
- if (! intel_mtd) {
-- iounmap((void *) nettel_intel_map.map_priv_1);
-+ iounmap((void *) nettel_intel_map.virt);
- return(-ENXIO);
- }
-
-@@ -441,19 +389,19 @@
- /* Delete the old map and probe again to do both chips */
- map_destroy(intel_mtd);
- intel_mtd = NULL;
-- iounmap((void *) nettel_intel_map.map_priv_1);
-+ iounmap((void *) nettel_intel_map.virt);
-
- nettel_intel_map.size = maxsize;
-- nettel_intel_map.map_priv_1 = (unsigned long)
-+ nettel_intel_map.virt = (unsigned long)
- ioremap_nocache(intel0addr, maxsize);
-- if (!nettel_intel_map.map_priv_1) {
-+ if (!nettel_intel_map.virt) {
- printk("SNAPGEAR: failed to ioremap() ROMCS1/2\n");
- return(-EIO);
- }
-
- intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
- if (! intel_mtd) {
-- iounmap((void *) nettel_intel_map.map_priv_1);
-+ iounmap((void *) nettel_intel_map.virt);
- return(-ENXIO);
- }
-
-@@ -468,7 +416,7 @@
- printk(KERN_NOTICE "SNAPGEAR: Intel flash device size = %dK\n",
- (intel_mtd->size >> 10));
-
-- intel_mtd->module = THIS_MODULE;
-+ intel_mtd->owner = THIS_MODULE;
-
- #ifndef CONFIG_BLK_DEV_INITRD
- ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 1);
-@@ -523,18 +471,18 @@
- del_mtd_partitions(amd_mtd);
- map_destroy(amd_mtd);
- }
-- if (nettel_amd_map.map_priv_1) {
-- iounmap((void *)nettel_amd_map.map_priv_1);
-- nettel_amd_map.map_priv_1 = 0;
-+ if (nettel_amd_map.virt) {
-+ iounmap((void *)nettel_amd_map.virt);
-+ nettel_amd_map.virt = 0;
- }
- #ifdef CONFIG_MTD_CFI_INTELEXT
- if (intel_mtd) {
- del_mtd_partitions(intel_mtd);
- map_destroy(intel_mtd);
- }
-- if (nettel_intel_map.map_priv_1) {
-- iounmap((void *)nettel_intel_map.map_priv_1);
-- nettel_intel_map.map_priv_1 = 0;
-+ if (nettel_intel_map.virt) {
-+ iounmap((void *)nettel_intel_map.virt);
-+ nettel_intel_map.virt = 0;
- }
- #endif
- }
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/ocelot.c linux/drivers/mtd/maps/ocelot.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/ocelot.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/ocelot.c 2004-11-17 18:17:59.115302368 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Flash on Momenco Ocelot
- */
-@@ -7,6 +7,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -20,47 +21,23 @@
- #define NVRAM_WINDOW_SIZE 0x00007FF0
- #define NVRAM_BUSWIDTH 1
-
--extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
--
- static unsigned int cacheflush = 0;
-
- static struct mtd_info *flash_mtd;
- static struct mtd_info *nvram_mtd;
-
--__u8 ocelot_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--void ocelot_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- cacheflush = 1;
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void ocelot_copy_from_cache(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- if (cacheflush) {
-- dma_cache_inv(map->map_priv_2, map->size);
-- cacheflush = 0;
-- }
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void ocelot_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-+static void ocelot_ram_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
- {
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
-+ struct map_info *map = (struct map_info *)mtd->priv;
-+ size_t done = 0;
-
--void ocelot_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
- /* If we use memcpy, it does word-wide writes. Even though we told the
- GT64120A that it's an 8-bit wide region, word-wide writes don't work.
- We end up just writing the first byte of the four to all four bytes.
- So we have this loop instead */
-+ *retlen = len;
- while(len) {
-- __raw_writeb(*(unsigned char *) from, map->map_priv_1 + to);
-+ __raw_writeb(*(unsigned char *) from, map->virt + to);
- from++;
- to++;
- len--;
-@@ -70,24 +47,21 @@
- static struct mtd_partition *parsed_parts;
-
- struct map_info ocelot_flash_map = {
-- name: "Ocelot boot flash",
-- size: FLASH_WINDOW_SIZE,
-- buswidth: FLASH_BUSWIDTH,
-- read8: ocelot_read8,
-- copy_from: ocelot_copy_from_cache,
-- write8: ocelot_write8,
-+ .name = "Ocelot boot flash",
-+ .size = FLASH_WINDOW_SIZE,
-+ .buswidth = FLASH_BUSWIDTH,
-+ .phys = FLASH_WINDOW_ADDR,
- };
-
- struct map_info ocelot_nvram_map = {
-- name: "Ocelot NVRAM",
-- size: NVRAM_WINDOW_SIZE,
-- buswidth: NVRAM_BUSWIDTH,
-- read8: ocelot_read8,
-- copy_from: ocelot_copy_from,
-- write8: ocelot_write8,
-- copy_to: ocelot_copy_to
-+ .name = "Ocelot NVRAM",
-+ .size = NVRAM_WINDOW_SIZE,
-+ .buswidth = NVRAM_BUSWIDTH,
-+ .phys = NVRAM_WINDOW_ADDR,
- };
-
-+static const char *probes[] = { "RedBoot", NULL };
-+
- static int __init init_ocelot_maps(void)
- {
- void *pld;
-@@ -107,12 +81,13 @@
- iounmap(pld);
-
- /* Now ioremap the NVRAM space */
-- ocelot_nvram_map.map_priv_1 = (unsigned long)ioremap_nocache(NVRAM_WINDOW_ADDR, NVRAM_WINDOW_SIZE);
-- if (!ocelot_nvram_map.map_priv_1) {
-+ ocelot_nvram_map.virt = (unsigned long)ioremap_nocache(NVRAM_WINDOW_ADDR, NVRAM_WINDOW_SIZE);
-+ if (!ocelot_nvram_map.virt) {
- printk(KERN_NOTICE "Failed to ioremap Ocelot NVRAM space\n");
- return -EIO;
- }
-- // ocelot_nvram_map.map_priv_2 = ocelot_nvram_map.map_priv_1;
-+
-+ simple_map_init(&ocelot_nvram_map);
-
- /* And do the RAM probe on it to get an MTD device */
- nvram_mtd = do_map_probe("map_ram", &ocelot_nvram_map);
-@@ -120,22 +95,21 @@
- printk("NVRAM probe failed\n");
- goto fail_1;
- }
-- nvram_mtd->module = THIS_MODULE;
-+ nvram_mtd->owner = THIS_MODULE;
- nvram_mtd->erasesize = 16;
-+ /* Override the write() method */
-+ nvram_mtd->write = ocelot_ram_write;
-
- /* Now map the flash space */
-- ocelot_flash_map.map_priv_1 = (unsigned long)ioremap_nocache(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE);
-- if (!ocelot_flash_map.map_priv_1) {
-+ ocelot_flash_map.virt = (unsigned long)ioremap_nocache(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE);
-+ if (!ocelot_flash_map.virt) {
- printk(KERN_NOTICE "Failed to ioremap Ocelot flash space\n");
- goto fail_2;
- }
- /* Now the cached version */
-- ocelot_flash_map.map_priv_2 = (unsigned long)__ioremap(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE, 0);
-+ ocelot_flash_map.cached = (unsigned long)__ioremap(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE, 0);
-
-- if (!ocelot_flash_map.map_priv_2) {
-- /* Doesn't matter if it failed. Just use the uncached version */
-- ocelot_flash_map.map_priv_2 = ocelot_flash_map.map_priv_1;
-- }
-+ simple_map_init(&ocelot_flash_map);
-
- /* Only probe for flash if the write jumper is present */
- if (brd_status & 0x40) {
-@@ -155,10 +129,10 @@
-
- add_mtd_device(nvram_mtd);
-
-- flash_mtd->module = THIS_MODULE;
-- nr_parts = parse_redboot_partitions(flash_mtd, &parsed_parts);
-+ flash_mtd->owner = THIS_MODULE;
-+ nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_parts, 0);
-
-- if (nr_parts)
-+ if (nr_parts > 0)
- add_mtd_partitions(flash_mtd, parsed_parts, nr_parts);
- else
- add_mtd_device(flash_mtd);
-@@ -166,14 +140,13 @@
- return 0;
-
- fail3:
-- iounmap((void *)ocelot_flash_map.map_priv_1);
-- if (ocelot_flash_map.map_priv_2 &&
-- ocelot_flash_map.map_priv_2 != ocelot_flash_map.map_priv_1)
-- iounmap((void *)ocelot_flash_map.map_priv_2);
-+ iounmap((void *)ocelot_flash_map.virt);
-+ if (ocelot_flash_map.cached)
-+ iounmap((void *)ocelot_flash_map.cached);
- fail_2:
- map_destroy(nvram_mtd);
- fail_1:
-- iounmap((void *)ocelot_nvram_map.map_priv_1);
-+ iounmap((void *)ocelot_nvram_map.virt);
-
- return -ENXIO;
- }
-@@ -182,16 +155,16 @@
- {
- del_mtd_device(nvram_mtd);
- map_destroy(nvram_mtd);
-- iounmap((void *)ocelot_nvram_map.map_priv_1);
-+ iounmap((void *)ocelot_nvram_map.virt);
-
- if (parsed_parts)
- del_mtd_partitions(flash_mtd);
- else
- del_mtd_device(flash_mtd);
- map_destroy(flash_mtd);
-- iounmap((void *)ocelot_flash_map.map_priv_1);
-- if (ocelot_flash_map.map_priv_2 != ocelot_flash_map.map_priv_1)
-- iounmap((void *)ocelot_flash_map.map_priv_2);
-+ iounmap((void *)ocelot_flash_map.virt);
-+ if (ocelot_flash_map.cached)
-+ iounmap((void *)ocelot_flash_map.cached);
- }
-
- module_init(init_ocelot_maps);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/octagon-5066.c linux/drivers/mtd/maps/octagon-5066.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/octagon-5066.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/octagon-5066.c 2004-11-17 18:17:59.117302064 +0100
-@@ -1,4 +1,4 @@
--// $Id$
-+// $Id$
- /* ######################################################################
-
- Octagon 5066 MTD Driver.
-@@ -31,6 +31,7 @@
- #include <asm/io.h>
-
- #include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
-
- #define WINDOW_START 0xe8000
- #define WINDOW_LENGTH 0x8000
-@@ -151,32 +152,34 @@
-
- static struct map_info oct5066_map[2] = {
- {
-- name: "Octagon 5066 Socket",
-- size: 512 * 1024,
-- buswidth: 1,
-- read8: oct5066_read8,
-- read16: oct5066_read16,
-- read32: oct5066_read32,
-- copy_from: oct5066_copy_from,
-- write8: oct5066_write8,
-- write16: oct5066_write16,
-- write32: oct5066_write32,
-- copy_to: oct5066_copy_to,
-- map_priv_1: 1<<6
-+ .name = "Octagon 5066 Socket",
-+ .phys = NO_XIP,
-+ .size = 512 * 1024,
-+ .buswidth = 1,
-+ .read8 = oct5066_read8,
-+ .read16 = oct5066_read16,
-+ .read32 = oct5066_read32,
-+ .copy_from = oct5066_copy_from,
-+ .write8 = oct5066_write8,
-+ .write16 = oct5066_write16,
-+ .write32 = oct5066_write32,
-+ .copy_to = oct5066_copy_to,
-+ .map_priv_1 = 1<<6
- },
- {
-- name: "Octagon 5066 Internal Flash",
-- size: 2 * 1024 * 1024,
-- buswidth: 1,
-- read8: oct5066_read8,
-- read16: oct5066_read16,
-- read32: oct5066_read32,
-- copy_from: oct5066_copy_from,
-- write8: oct5066_write8,
-- write16: oct5066_write16,
-- write32: oct5066_write32,
-- copy_to: oct5066_copy_to,
-- map_priv_1: 2<<6
-+ .name = "Octagon 5066 Internal Flash",
-+ .phys = NO_XIP,
-+ .size = 2 * 1024 * 1024,
-+ .buswidth = 1,
-+ .read8 = oct5066_read8,
-+ .read16 = oct5066_read16,
-+ .read32 = oct5066_read32,
-+ .copy_from = oct5066_copy_from,
-+ .write8 = oct5066_write8,
-+ .write16 = oct5066_write16,
-+ .write32 = oct5066_write32,
-+ .copy_to = oct5066_copy_to,
-+ .map_priv_1 = 2<<6
- }
- };
-
-@@ -244,6 +247,7 @@
- }
- if (OctProbe() != 0) {
- printk(KERN_NOTICE "5066: Octagon Probe Failed, is this an Octagon 5066 SBC?\n");
-+ iounmap((void *)iomapadr);
- ret = -EAGAIN;
- goto out_unmap;
- }
-@@ -261,7 +265,7 @@
- if (!oct5066_mtd[i])
- oct5066_mtd[i] = do_map_probe("map_rom", &oct5066_map[i]);
- if (oct5066_mtd[i]) {
-- oct5066_mtd[i]->module = THIS_MODULE;
-+ oct5066_mtd[i]->owner = THIS_MODULE;
- add_mtd_device(oct5066_mtd[i]);
- }
- }
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/omap-toto-flash.c linux/drivers/mtd/maps/omap-toto-flash.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/omap-toto-flash.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/omap-toto-flash.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,137 @@
-+/*
-+ * NOR Flash memory access on TI Toto board
-+ *
-+ * jzhang@ti.com (C) 2003 Texas Instruments.
-+ *
-+ * (C) 2002 MontVista Software, Inc.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+
-+
-+#ifndef CONFIG_ARCH_OMAP
-+#error This is for OMAP architecture only
-+#endif
-+
-+//these lines need be moved to a hardware header file
-+#define OMAP_TOTO_FLASH_BASE 0xd8000000
-+#define OMAP_TOTO_FLASH_SIZE 0x80000
-+
-+static struct map_info omap_toto_map_flash = {
-+ .name = "OMAP Toto flash",
-+ .buswidth = 2,
-+ .virt = OMAP_TOTO_FLASH_BASE,
-+};
-+
-+
-+static struct mtd_partition toto_flash_partitions[] = {
-+ {
-+ .name = "BootLoader",
-+ .size = 0x00040000, /* hopefully u-boot will stay 128k + 128*/
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "ReservedSpace",
-+ .size = 0x00030000,
-+ .offset = MTDPART_OFS_APPEND,
-+ //mask_flags: MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "EnvArea", /* bottom 64KiB for env vars */
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
-+ }
-+};
-+
-+static struct mtd_partition *parsed_parts;
-+
-+static struct mtd_info *flash_mtd;
-+
-+static int __init init_flash (void)
-+{
-+
-+ struct mtd_partition *parts;
-+ int nb_parts = 0;
-+ int parsed_nr_parts = 0;
-+ const char *part_type;
-+
-+ /*
-+ * Static partition definition selection
-+ */
-+ part_type = "static";
-+
-+ parts = toto_flash_partitions;
-+ nb_parts = ARRAY_SIZE(toto_flash_partitions);
-+ omap_toto_map_flash.size = OMAP_TOTO_FLASH_SIZE;
-+ omap_toto_map_flash.phys = virt_to_phys(OMAP_TOTO_FLASH_BASE);
-+
-+ simple_map_init(&omap_toto_map_flash);
-+ /*
-+ * Now let's probe for the actual flash. Do it here since
-+ * specific machine settings might have been set above.
-+ */
-+ printk(KERN_NOTICE "OMAP toto flash: probing %d-bit flash bus\n",
-+ omap_toto_map_flash.buswidth*8);
-+ flash_mtd = do_map_probe("jedec_probe", &omap_toto_map_flash);
-+ if (!flash_mtd)
-+ return -ENXIO;
-+
-+ if (parsed_nr_parts > 0) {
-+ parts = parsed_parts;
-+ nb_parts = parsed_nr_parts;
-+ }
-+
-+ if (nb_parts == 0) {
-+ printk(KERN_NOTICE "OMAP toto flash: no partition info available,"
-+ "registering whole flash at once\n");
-+ if (add_mtd_device(flash_mtd)){
-+ return -ENXIO;
-+ }
-+ } else {
-+ printk(KERN_NOTICE "Using %s partition definition\n",
-+ part_type);
-+ return add_mtd_partitions(flash_mtd, parts, nb_parts);
-+ }
-+ return 0;
-+}
-+
-+int __init omap_toto_mtd_init(void)
-+{
-+ int status;
-+
-+ if (status = init_flash()) {
-+ printk(KERN_ERR "OMAP Toto Flash: unable to init map for toto flash\n");
-+ }
-+ return status;
-+}
-+
-+static void __exit omap_toto_mtd_cleanup(void)
-+{
-+ if (flash_mtd) {
-+ del_mtd_partitions(flash_mtd);
-+ map_destroy(flash_mtd);
-+ if (parsed_parts)
-+ kfree(parsed_parts);
-+ }
-+}
-+
-+module_init(omap_toto_mtd_init);
-+module_exit(omap_toto_mtd_cleanup);
-+
-+MODULE_AUTHOR("Jian Zhang");
-+MODULE_DESCRIPTION("OMAP Toto board map driver");
-+MODULE_LICENSE("GPL");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/pb1xxx-flash.c linux/drivers/mtd/maps/pb1xxx-flash.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/pb1xxx-flash.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/pb1xxx-flash.c 2004-11-17 18:17:59.119301760 +0100
-@@ -3,12 +3,13 @@
- *
- * (C) 2001 Pete Popov <ppopov@mvista.com>
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
- #include <linux/module.h>
- #include <linux/types.h>
-+#include <linux/init.h>
- #include <linux/kernel.h>
-
- #include <linux/mtd/mtd.h>
-@@ -25,210 +26,110 @@
- #endif
-
- #ifdef CONFIG_MIPS_PB1000
-+
- #define WINDOW_ADDR 0x1F800000
- #define WINDOW_SIZE 0x800000
--#endif
--
--__u8 physmap_read8(struct map_info *map, unsigned long ofs)
--{
-- __u8 ret;
-- ret = __raw_readb(map->map_priv_1 + ofs);
-- DBG("read8 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--__u16 physmap_read16(struct map_info *map, unsigned long ofs)
--{
-- __u16 ret;
-- ret = __raw_readw(map->map_priv_1 + ofs);
-- DBG("read16 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--__u32 physmap_read32(struct map_info *map, unsigned long ofs)
--{
-- __u32 ret;
-- ret = __raw_readl(map->map_priv_1 + ofs);
-- DBG("read32 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- DBG("physmap_copy from %x to %x\n", (unsigned)from, (unsigned)to);
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void physmap_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- DBG("write8 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- DBG("write16 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- DBG("write32 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- DBG("physmap_copy_to %x from %x\n", (unsigned)to, (unsigned)from);
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
--
--
--
--static struct map_info pb1xxx_map = {
-- name: "Pb1xxx flash",
-- read8: physmap_read8,
-- read16: physmap_read16,
-- read32: physmap_read32,
-- copy_from: physmap_copy_from,
-- write8: physmap_write8,
-- write16: physmap_write16,
-- write32: physmap_write32,
-- copy_to: physmap_copy_to,
--};
-
--
--#ifdef CONFIG_MIPS_PB1000
--
--static unsigned long flash_size = 0x00800000;
--static unsigned char flash_buswidth = 4;
- static struct mtd_partition pb1xxx_partitions[] = {
- {
-- name: "yamon env",
-- size: 0x00020000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE
-- },{
-- name: "User FS",
-- size: 0x003e0000,
-- offset: 0x20000,
-- },{
-- name: "boot code",
-- size: 0x100000,
-- offset: 0x400000,
-- mask_flags: MTD_WRITEABLE
-- },{
-- name: "raw/kernel",
-- size: 0x300000,
-- offset: 0x500000
-- }
-+ .name = "yamon env",
-+ .size = 0x00020000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE},
-+ {
-+ .name = "User FS",
-+ .size = 0x003e0000,
-+ .offset = 0x20000,},
-+ {
-+ .name = "boot code",
-+ .size = 0x100000,
-+ .offset = 0x400000,
-+ .mask_flags = MTD_WRITEABLE},
-+ {
-+ .name = "raw/kernel",
-+ .size = 0x300000,
-+ .offset = 0x500000}
- };
-
- #elif defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100)
-
--static unsigned char flash_buswidth = 4;
- #if defined(CONFIG_MTD_PB1500_BOOT) && defined(CONFIG_MTD_PB1500_USER)
--/* both 32MiB banks will be used. Combine the first 32MiB bank and the
-- * first 28MiB of the second bank together into a single jffs/jffs2
-+/* both 32MB banks will be used. Combine the first 32MB bank and the
-+ * first 28MB of the second bank together into a single jffs/jffs2
- * partition.
- */
--static unsigned long flash_size = 0x04000000;
- #define WINDOW_ADDR 0x1C000000
- #define WINDOW_SIZE 0x4000000
- static struct mtd_partition pb1xxx_partitions[] = {
- {
-- name: "User FS",
-- size: 0x3c00000,
-- offset: 0x0000000
-- },{
-- name: "yamon",
-- size: 0x0100000,
-- offset: 0x3c00000,
-- mask_flags: MTD_WRITEABLE
-- },{
-- name: "raw kernel",
-- size: 0x02c0000,
-- offset: 0x3d00000
-+ .name = "User FS",
-+ .size = 0x3c00000,
-+ .offset = 0x0000000
-+ },{
-+ .name = "yamon",
-+ .size = 0x0100000,
-+ .offset = 0x3c00000,
-+ .mask_flags = MTD_WRITEABLE
-+ },{
-+ .name = "raw kernel",
-+ .size = 0x02c0000,
-+ .offset = 0x3d00000
- }
- };
- #elif defined(CONFIG_MTD_PB1500_BOOT) && !defined(CONFIG_MTD_PB1500_USER)
--static unsigned long flash_size = 0x02000000;
- #define WINDOW_ADDR 0x1E000000
- #define WINDOW_SIZE 0x2000000
- static struct mtd_partition pb1xxx_partitions[] = {
- {
-- name: "User FS",
-- size: 0x1c00000,
-- offset: 0x0000000
-- },{
-- name: "yamon",
-- size: 0x0100000,
-- offset: 0x1c00000,
-- mask_flags: MTD_WRITEABLE
-- },{
-- name: "raw kernel",
-- size: 0x02c0000,
-- offset: 0x1d00000
-+ .name = "User FS",
-+ .size = 0x1c00000,
-+ .offset = 0x0000000
-+ },{
-+ .name = "yamon",
-+ .size = 0x0100000,
-+ .offset = 0x1c00000,
-+ .mask_flags = MTD_WRITEABLE
-+ },{
-+ .name = "raw kernel",
-+ .size = 0x02c0000,
-+ .offset = 0x1d00000
- }
- };
- #elif !defined(CONFIG_MTD_PB1500_BOOT) && defined(CONFIG_MTD_PB1500_USER)
--static unsigned long flash_size = 0x02000000;
- #define WINDOW_ADDR 0x1C000000
- #define WINDOW_SIZE 0x2000000
- static struct mtd_partition pb1xxx_partitions[] = {
- {
-- name: "User FS",
-- size: 0x1e00000,
-- offset: 0x0000000
-- },{
-- name: "raw kernel",
-- size: 0x0200000,
-- offset: 0x1e00000,
-+ .name = "User FS",
-+ .size = 0x1e00000,
-+ .offset = 0x0000000
-+ },{
-+ .name = "raw kernel",
-+ .size = 0x0200000,
-+ .offset = 0x1e00000,
- }
- };
- #else
- #error MTD_PB1500 define combo error /* should never happen */
- #endif
--#elif defined(CONFIG_MTD_BOSPORUS)
--static unsigned char flash_buswidth = 2;
--static unsigned long flash_size = 0x02000000;
--#define WINDOW_ADDR 0x1F000000
--#define WINDOW_SIZE 0x2000000
--static struct mtd_partition pb1xxx_partitions[] = {
-- {
-- name: "User FS",
-- size: 0x00400000,
-- offset: 0x00000000,
-- },{
-- name: "Yamon-2",
-- size: 0x00100000,
-- offset: 0x00400000,
-- },{
-- name: "Root FS",
-- size: 0x00700000,
-- offset: 0x00500000,
-- },{
-- name: "Yamon-1",
-- size: 0x00100000,
-- offset: 0x00C00000,
-- },{
-- name: "Kernel",
-- size: 0x00300000,
-- offset: 0x00D00000,
-- }
--};
- #else
- #error Unsupported board
- #endif
-
-+#define NAME "Pb1x00 Linux Flash"
-+#define PADDR WINDOW_ADDR
-+#define BUSWIDTH 4
-+#define SIZE WINDOW_SIZE
-+#define PARTITIONS 4
-+
-+static struct map_info pb1xxx_mtd_map = {
-+ .name = NAME,
-+ .size = SIZE,
-+ .buswidth = BUSWIDTH,
-+ .phys = PADDR,
-+};
-
--#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
--
--static struct mtd_partition *parsed_parts;
--static struct mtd_info *mymtd;
-+static struct mtd_info *pb1xxx_mtd;
-
- int __init pb1xxx_mtd_init(void)
- {
-@@ -236,40 +137,37 @@
- int nb_parts = 0;
- char *part_type;
-
-- /* Default flash buswidth */
-- pb1xxx_map.buswidth = flash_buswidth;
--
- /*
- * Static partition definition selection
- */
- part_type = "static";
- parts = pb1xxx_partitions;
-- nb_parts = NB_OF(pb1xxx_partitions);
-- pb1xxx_map.size = flash_size;
-+ nb_parts = ARRAY_SIZE(pb1xxx_partitions);
-
- /*
- * Now let's probe for the actual flash. Do it here since
- * specific machine settings might have been set above.
- */
- printk(KERN_NOTICE "Pb1xxx flash: probing %d-bit flash bus\n",
-- pb1xxx_map.buswidth*8);
-- pb1xxx_map.map_priv_1 =
-- (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-- mymtd = do_map_probe("cfi_probe", &pb1xxx_map);
-- if (!mymtd) return -ENXIO;
-- mymtd->module = THIS_MODULE;
-+ BUSWIDTH*8);
-+ pb1xxx_mtd_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-+
-+ simple_map_init(&pb1xxx_mtd_map);
-+
-+ pb1xxx_mtd = do_map_probe("cfi_probe", &pb1xxx_mtd_map);
-+ if (!pb1xxx_mtd) return -ENXIO;
-+ pb1xxx_mtd->owner = THIS_MODULE;
-
-- add_mtd_partitions(mymtd, parts, nb_parts);
-+ add_mtd_partitions(pb1xxx_mtd, parts, nb_parts);
- return 0;
- }
-
- static void __exit pb1xxx_mtd_cleanup(void)
- {
-- if (mymtd) {
-- del_mtd_partitions(mymtd);
-- map_destroy(mymtd);
-- if (parsed_parts)
-- kfree(parsed_parts);
-+ if (pb1xxx_mtd) {
-+ del_mtd_partitions(pb1xxx_mtd);
-+ map_destroy(pb1xxx_mtd);
-+ iounmap((void *) pb1xxx_mtd_map.virt);
- }
- }
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/pci.c linux/drivers/mtd/maps/pci.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/pci.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/pci.c 2004-11-17 18:17:59.121301456 +0100
-@@ -7,7 +7,7 @@
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-- * $Id$
-+ * $Id$
- *
- * Generic PCI memory map driver. We support the following boards:
- * - Intel IQ80310 ATU.
-@@ -98,10 +98,10 @@
- }
-
- static struct mtd_pci_info intel_iq80310_info = {
-- init: intel_iq80310_init,
-- exit: intel_iq80310_exit,
-- translate: intel_iq80310_translate,
-- map_name: "cfi_probe",
-+ .init = intel_iq80310_init,
-+ .exit = intel_iq80310_exit,
-+ .translate = intel_iq80310_translate,
-+ .map_name = "cfi_probe",
- };
-
- /*
-@@ -181,10 +181,10 @@
- }
-
- static struct mtd_pci_info intel_dc21285_info = {
-- init: intel_dc21285_init,
-- exit: intel_dc21285_exit,
-- translate: intel_dc21285_translate,
-- map_name: "jedec_probe",
-+ .init = intel_dc21285_init,
-+ .exit = intel_dc21285_exit,
-+ .translate = intel_dc21285_translate,
-+ .map_name = "jedec_probe",
- };
-
- /*
-@@ -193,22 +193,20 @@
-
- static struct pci_device_id mtd_pci_ids[] __devinitdata = {
- {
-- vendor: PCI_VENDOR_ID_INTEL,
-- device: 0x530d,
-- subvendor: PCI_ANY_ID,
-- subdevice: PCI_ANY_ID,
-- class: PCI_CLASS_MEMORY_OTHER << 8,
-- class_mask: 0xffff00,
-- driver_data: (unsigned long)&intel_iq80310_info,
-+ .vendor = PCI_VENDOR_ID_INTEL,
-+ .device = 0x530d,
-+ .subvendor = PCI_ANY_ID,
-+ .subdevice = PCI_ANY_ID,
-+ .class = PCI_CLASS_MEMORY_OTHER << 8,
-+ .class_mask = 0xffff00,
-+ .driver_data = (unsigned long)&intel_iq80310_info,
- },
- {
-- vendor: PCI_VENDOR_ID_DEC,
-- device: PCI_DEVICE_ID_DEC_21285,
-- subvendor: 0, /* DC21285 defaults to 0 on reset */
-- subdevice: 0, /* DC21285 defaults to 0 on reset */
-- class: 0,
-- class_mask: 0,
-- driver_data: (unsigned long)&intel_dc21285_info,
-+ .vendor = PCI_VENDOR_ID_DEC,
-+ .device = PCI_DEVICE_ID_DEC_21285,
-+ .subvendor = 0, /* DC21285 defaults to 0 on reset */
-+ .subdevice = 0, /* DC21285 defaults to 0 on reset */
-+ .driver_data = (unsigned long)&intel_dc21285_info,
- },
- { 0, }
- };
-@@ -275,14 +273,15 @@
- }
-
- static struct map_info mtd_pci_map = {
-- read8: mtd_pci_read8,
-- read16: mtd_pci_read16,
-- read32: mtd_pci_read32,
-- copy_from: mtd_pci_copyfrom,
-- write8: mtd_pci_write8,
-- write16: mtd_pci_write16,
-- write32: mtd_pci_write32,
-- copy_to: mtd_pci_copyto,
-+ .phys = NO_XIP,
-+ .read8 = mtd_pci_read8,
-+ .read16 = mtd_pci_read16,
-+ .read32 = mtd_pci_read32,
-+ .copy_from = mtd_pci_copyfrom,
-+ .write8 = mtd_pci_write8,
-+ .write16 = mtd_pci_write16,
-+ .write32 = mtd_pci_write32,
-+ .copy_to = mtd_pci_copyto,
- };
-
- static int __devinit
-@@ -322,7 +321,7 @@
- if (!mtd)
- goto release;
-
-- mtd->module = THIS_MODULE;
-+ mtd->owner = THIS_MODULE;
- add_mtd_device(mtd);
-
- pci_set_drvdata(dev, mtd);
-@@ -359,10 +358,10 @@
- }
-
- static struct pci_driver mtd_pci_driver = {
-- name: "MTD PCI",
-- probe: mtd_pci_probe,
-- remove: __devexit_p(mtd_pci_remove),
-- id_table: mtd_pci_ids,
-+ .name = "MTD PCI",
-+ .probe = mtd_pci_probe,
-+ .remove = __devexit_p(mtd_pci_remove),
-+ .id_table = mtd_pci_ids,
- };
-
- static int __init mtd_pci_maps_init(void)
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/pcmciamtd.c linux/drivers/mtd/maps/pcmciamtd.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/pcmciamtd.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/pcmciamtd.c 2004-11-17 18:17:59.122301304 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * pcmciamtd.c - MTD driver for PCMCIA flash memory cards
- *
-@@ -14,6 +14,7 @@
- #include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/timer.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <asm/system.h>
-
-@@ -24,6 +25,7 @@
- #include <pcmcia/ds.h>
-
- #include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
-
- #ifdef CONFIG_MTD_DEBUG
- static int debug = CONFIG_MTD_DEBUG_VERBOSE;
-@@ -47,7 +49,7 @@
-
-
- #define DRIVER_DESC "PCMCIA Flash memory card driver"
--#define DRIVER_VERSION "$Revision$"
-+#define DRIVER_VERSION "$Revision$"
-
- /* Size of the PCMCIA address space: 26 bits = 64 MB */
- #define MAX_PCMCIA_ADDR 0x4000000
-@@ -96,7 +98,7 @@
- MODULE_PARM(mem_speed, "i");
- MODULE_PARM_DESC(mem_speed, "Set memory access speed in ns");
- MODULE_PARM(force_size, "i");
--MODULE_PARM_DESC(force_size, "Force size of card in MB (1-64)");
-+MODULE_PARM_DESC(force_size, "Force size of card in MiB (1-64)");
- MODULE_PARM(setvpp, "i");
- MODULE_PARM_DESC(setvpp, "Set Vpp (0=Never, 1=On writes, 2=Always on, default=0)");
- MODULE_PARM(vpp, "i");
-@@ -106,11 +108,13 @@
-
-
-
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)
- static inline void cs_error(client_handle_t handle, int func, int ret)
- {
- error_info_t err = { func, ret };
- CardServices(ReportError, handle, &err);
- }
-+#endif
-
-
- /* read/write{8,16} copy_{from,to} routines with window remapping to access whole card */
-@@ -529,6 +533,7 @@
-
- card_settings(dev, link, &new_name);
-
-+ dev->pcmcia_map.phys = NO_XIP;
- dev->pcmcia_map.read8 = pcmcia_read8_remap;
- dev->pcmcia_map.read16 = pcmcia_read16_remap;
- dev->pcmcia_map.copy_from = pcmcia_copy_from_remap;
-@@ -539,7 +544,7 @@
- dev->pcmcia_map.set_vpp = pcmciamtd_set_vpp;
-
- /* Request a memory window for PCMCIA. Some architeures can map windows upto the maximum
-- that PCMCIA can support (64Mb) - this is ideal and we aim for a window the size of the
-+ that PCMCIA can support (64MiB) - this is ideal and we aim for a window the size of the
- whole card - otherwise we try smaller windows until we succeed */
-
- req.Attributes = WIN_MEMORY_TYPE_CM | WIN_ENABLE;
-@@ -552,7 +557,7 @@
-
- do {
- int ret;
-- DEBUG(2, "requesting window with size = %dKB memspeed = %d",
-+ DEBUG(2, "requesting window with size = %dKiB memspeed = %d",
- req.Size >> 10, req.AccessSpeed);
- link->win = (window_handle_t)link->handle;
- ret = CardServices(RequestWindow, &link->win, &req);
-@@ -560,7 +565,7 @@
- if(ret) {
- req.Size >>= 1;
- } else {
-- DEBUG(2, "Got window of size %dKB", req.Size >> 10);
-+ DEBUG(2, "Got window of size %dKiB", req.Size >> 10);
- dev->win_size = req.Size;
- break;
- }
-@@ -573,7 +578,7 @@
- pcmciamtd_release((u_long)link);
- return;
- }
-- DEBUG(1, "Allocated a window of %dKB", dev->win_size >> 10);
-+ DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);
-
- /* Get write protect status */
- CS_CHECK(GetStatus, link->handle, &status);
-@@ -642,21 +647,21 @@
- }
-
- dev->mtd_info = mtd;
-- mtd->module = THIS_MODULE;
-+ mtd->owner = THIS_MODULE;
-
- if(new_name) {
- int size = 0;
- char unit = ' ';
- /* Since we are using a default name, make it better by adding in the
- size */
-- if(mtd->size < 1048576) { /* <1MB in size, show size in K */
-+ if(mtd->size < 1048576) { /* <1MiB in size, show size in KiB */
- size = mtd->size >> 10;
- unit = 'K';
- } else {
- size = mtd->size >> 20;
- unit = 'M';
- }
-- snprintf(dev->mtd_name, sizeof(dev->mtd_name), "%d%cB %s", size, unit, "PCMCIA Memory card");
-+ snprintf(dev->mtd_name, sizeof(dev->mtd_name), "%d%ciB %s", size, unit, "PCMCIA Memory card");
- }
-
- /* If the memory found is fits completely into the mapped PCMCIA window,
-@@ -828,16 +833,20 @@
- }
-
-
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,68)
-+static struct pcmcia_driver pcmciamtd_driver = {
-+ .drv = {
-+ .name = "pcmciamtd"
-+ },
-+ .attach = pcmciamtd_attach,
-+ .detach = pcmciamtd_detach,
-+ .owner = THIS_MODULE
-+};
-+#endif
-+
-+
- static int __init init_pcmciamtd(void)
- {
-- servinfo_t serv;
--
-- info(DRIVER_DESC " " DRIVER_VERSION);
-- CardServices(GetCardServicesInfo, &serv);
-- if (serv.Revision != CS_RELEASE_CODE) {
-- err("Card Services release does not match!");
-- return -1;
-- }
-
- if(buswidth && buswidth != 1 && buswidth != 2) {
- info("bad buswidth (%d), using default", buswidth);
-@@ -851,15 +860,24 @@
- info("bad mem_type (%d), using default", mem_type);
- mem_type = 0;
- }
-+
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,68)
-+ return pcmcia_register_driver(&pcmciamtd_driver);
-+#else
- register_pccard_driver(&dev_info, &pcmciamtd_attach, &pcmciamtd_detach);
- return 0;
-+#endif
- }
-
-
- static void __exit exit_pcmciamtd(void)
- {
- DEBUG(1, DRIVER_DESC " unloading");
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,68)
-+ pcmcia_unregister_driver(&pcmciamtd_driver);
-+#else
- unregister_pccard_driver(&dev_info);
-+#endif
-
- while(dev_list) {
- dev_link_t *link = dev_list;
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/physmap.c linux/drivers/mtd/maps/physmap.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/physmap.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/physmap.c 2004-11-17 18:17:59.124301000 +0100
-@@ -1,179 +1,114 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Normal mappings of chips in physical memory
-+ *
-+ * Copyright (C) 2003 MontaVista Software Inc.
-+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
-+ *
-+ * 031022 - [jsun] add run-time configure and partition setup
- */
-
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
- #include <linux/config.h>
--
--#ifdef CONFIG_MTD_PARTITIONS
- #include <linux/mtd/partitions.h>
--#endif
--
--#define WINDOW_ADDR CONFIG_MTD_PHYSMAP_START
--#define WINDOW_SIZE CONFIG_MTD_PHYSMAP_LEN
--#define BUSWIDTH CONFIG_MTD_PHYSMAP_BUSWIDTH
-
- static struct mtd_info *mymtd;
-
--__u8 physmap_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 physmap_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 physmap_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
-+struct map_info physmap_map = {.name = "phys_mapped_flash"};
-
--void physmap_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
-+#ifdef CONFIG_MTD_PARTITIONS
-+static struct mtd_partition *mtd_parts;
-+static int mtd_parts_nb;
-
--void physmap_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
-+static int num_physmap_partitions;
-+static struct mtd_partition *physmap_partitions;
-
--void physmap_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
-+char *part_probes[] __initdata = {"cmdlinepart", "RedBoot", NULL};
-
--void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-+void physmap_set_partitions(struct mtd_partition *parts, int num_parts)
- {
-- memcpy_toio(map->map_priv_1 + to, from, len);
-+ physmap_partitions=parts;
-+ num_physmap_partitions=num_parts;
- }
--
--struct map_info physmap_map = {
-- name: "Physically mapped flash",
-- size: WINDOW_SIZE,
-- buswidth: BUSWIDTH,
-- read8: physmap_read8,
-- read16: physmap_read16,
-- read32: physmap_read32,
-- copy_from: physmap_copy_from,
-- write8: physmap_write8,
-- write16: physmap_write16,
-- write32: physmap_write32,
-- copy_to: physmap_copy_to
--};
--
--#ifdef CONFIG_MTD_PARTITIONS
--#ifdef CONFIG_MTD_CMDLINE_PARTS
--static struct mtd_partition *mtd_parts = 0;
--static int mtd_parts_nb = 0;
--#else
--static struct mtd_partition physmap_partitions[] = {
--/* Put your own partition definitions here */
--#if 0
-- {
-- name: "bootROM",
-- size: 0x80000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "zImage",
-- size: 0x100000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "ramdisk.gz",
-- size: 0x300000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "User FS",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-- }
--#endif
--};
--
--#define NUM_PARTITIONS (sizeof(physmap_partitions)/sizeof(struct mtd_partition))
--
--#endif
--#endif
-+#endif /* CONFIG_MTD_PARTITIONS */
-
- int __init init_physmap(void)
- {
- static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", 0 };
- const char **type;
-
-- printk(KERN_NOTICE "physmap flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
-- physmap_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-+ printk(KERN_NOTICE "physmap flash device: %lx at %lx\n", physmap_map.size, physmap_map.phys);
-+ physmap_map.virt = (unsigned long)ioremap(physmap_map.phys, physmap_map.size);
-
-- if (!physmap_map.map_priv_1) {
-+ if (!physmap_map.virt) {
- printk("Failed to ioremap\n");
- return -EIO;
- }
-
-+ simple_map_init(&physmap_map);
-+
- mymtd = 0;
- type = rom_probe_types;
- for(; !mymtd && *type; type++) {
- mymtd = do_map_probe(*type, &physmap_map);
- }
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
-- add_mtd_device(mymtd);
- #ifdef CONFIG_MTD_PARTITIONS
--#ifdef CONFIG_MTD_CMDLINE_PARTS
-- mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts,
-- "phys");
-+ mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes,
-+ &mtd_parts, 0);
-+
- if (mtd_parts_nb > 0)
- {
-- printk(KERN_NOTICE
-- "Using command line partition definition\n");
- add_mtd_partitions (mymtd, mtd_parts, mtd_parts_nb);
-+ return 0;
- }
--#else
-- if (NUM_PARTITIONS != 0)
-+
-+ if (num_physmap_partitions != 0)
- {
- printk(KERN_NOTICE
- "Using physmap partition definition\n");
-- add_mtd_partitions (mymtd, physmap_partitions, NUM_PARTITIONS);
-+ add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions);
-+ return 0;
- }
-
- #endif
--#endif
-+ add_mtd_device(mymtd);
-+
- return 0;
- }
-
-- iounmap((void *)physmap_map.map_priv_1);
-+ iounmap((void *)physmap_map.virt);
- return -ENXIO;
- }
-
- static void __exit cleanup_physmap(void)
- {
-- if (mymtd) {
-+#ifdef CONFIG_MTD_PARTITIONS
-+ if (mtd_parts_nb) {
-+ del_mtd_partitions(mymtd);
-+ kfree(mtd_parts);
-+ } else if (num_physmap_partitions) {
-+ del_mtd_partitions(mymtd);
-+ } else {
- del_mtd_device(mymtd);
-- map_destroy(mymtd);
-- }
-- if (physmap_map.map_priv_1) {
-- iounmap((void *)physmap_map.map_priv_1);
-- physmap_map.map_priv_1 = 0;
- }
-+#else
-+ del_mtd_device(mymtd);
-+#endif
-+ map_destroy(mymtd);
-+
-+ iounmap((void *)physmap_map.virt);
-+ physmap_map.virt = 0;
- }
-
- module_init(init_physmap);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/pnc2000.c linux/drivers/mtd/maps/pnc2000.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/pnc2000.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/pnc2000.c 2004-11-17 18:17:59.125300848 +0100
-@@ -5,12 +5,13 @@
- *
- * This code is GPL
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -24,58 +25,13 @@
- * MAP DRIVER STUFF
- */
-
--__u8 pnc_read8(struct map_info *map, unsigned long ofs)
--{
-- return *(__u8 *)(WINDOW_ADDR + ofs);
--}
--
--__u16 pnc_read16(struct map_info *map, unsigned long ofs)
--{
-- return *(__u16 *)(WINDOW_ADDR + ofs);
--}
--
--__u32 pnc_read32(struct map_info *map, unsigned long ofs)
--{
-- return *(volatile unsigned int *)(WINDOW_ADDR + ofs);
--}
--
--void pnc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy(to, (void *)(WINDOW_ADDR + from), len);
--}
--
--void pnc_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- *(__u8 *)(WINDOW_ADDR + adr) = d;
--}
--
--void pnc_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- *(__u16 *)(WINDOW_ADDR + adr) = d;
--}
--
--void pnc_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- *(__u32 *)(WINDOW_ADDR + adr) = d;
--}
--
--void pnc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy((void *)(WINDOW_ADDR + to), from, len);
--}
-
- struct map_info pnc_map = {
-- name: "PNC-2000",
-- size: WINDOW_SIZE,
-- buswidth: 4,
-- read8: pnc_read8,
-- read16: pnc_read16,
-- read32: pnc_read32,
-- copy_from: pnc_copy_from,
-- write8: pnc_write8,
-- write16: pnc_write16,
-- write32: pnc_write32,
-- copy_to: pnc_copy_to
-+ .name = "PNC-2000",
-+ .size = WINDOW_SIZE,
-+ .buswidth = 4,
-+ .phys = 0xFFFFFFFF,
-+ .virt = WINDOW_ADDR,
- };
-
-
-@@ -84,19 +40,19 @@
- */
- static struct mtd_partition pnc_partitions[3] = {
- {
-- name: "PNC-2000 boot firmware",
-- size: 0x20000,
-- offset: 0
-+ .name = "PNC-2000 boot firmware",
-+ .size = 0x20000,
-+ .offset = 0
- },
- {
-- name: "PNC-2000 kernel",
-- size: 0x1a0000,
-- offset: 0x20000
-+ .name = "PNC-2000 kernel",
-+ .size = 0x1a0000,
-+ .offset = 0x20000
- },
- {
-- name: "PNC-2000 filesystem",
-- size: 0x240000,
-- offset: 0x1c0000
-+ .name = "PNC-2000 filesystem",
-+ .size = 0x240000,
-+ .offset = 0x1c0000
- }
- };
-
-@@ -110,9 +66,11 @@
- {
- printk(KERN_NOTICE "Photron PNC-2000 flash mapping: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
-
-+ simple_map_init(&pnc_map);
-+
- mymtd = do_map_probe("cfi_probe", &pnc_map);
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
- return add_mtd_partitions(mymtd, pnc_partitions, 3);
- }
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/redwood.c linux/drivers/mtd/maps/redwood.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/redwood.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/redwood.c 2004-11-17 18:17:59.126300696 +0100
-@@ -1,38 +1,23 @@
- /*
-- * $Id:
-+ * $Id$
- *
-- * redwood.c - mapper for IBM Redwood-4/5 board.
-+ * drivers/mtd/maps/redwood.c
- *
-- * Copyright 2001 MontaVista Softare Inc.
-+ * FLASH map for the IBM Redwood 4/5/6 boards.
- *
-- * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
-- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
-- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-- *
-- * 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.
-- *
-- * History: 12/17/2001 - Armin
-- * migrated to use do_map_probe
-+ * Author: MontaVista Software, Inc. <source@mvista.com>
- *
-+ * 2001-2003 (c) MontaVista, Software, Inc. This file is licensed under
-+ * the terms of the GNU General Public License version 2. This program
-+ * is licensed "as is" without any warranty of any kind, whether express
-+ * or implied.
- */
-
-+#include <linux/config.h>
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -40,96 +25,102 @@
-
- #include <asm/io.h>
-
-+#if !defined (CONFIG_REDWOOD_6)
-+
- #define WINDOW_ADDR 0xffc00000
- #define WINDOW_SIZE 0x00400000
-
--__u8 redwood_flash_read8(struct map_info *map, unsigned long ofs)
--{
-- return *(__u8 *)(map->map_priv_1 + ofs);
--}
--
--__u16 redwood_flash_read16(struct map_info *map, unsigned long ofs)
--{
-- return *(__u16 *)(map->map_priv_1 + ofs);
--}
--
--__u32 redwood_flash_read32(struct map_info *map, unsigned long ofs)
--{
-- return *(volatile unsigned int *)(map->map_priv_1 + ofs);
--}
--
--void redwood_flash_copy_from(struct map_info *map, void *to,
-- unsigned long from, ssize_t len)
--{
-- memcpy(to, (void *)(map->map_priv_1 + from), len);
--}
--
--void redwood_flash_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- *(__u8 *)(map->map_priv_1 + adr) = d;
--}
--
--void redwood_flash_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- *(__u16 *)(map->map_priv_1 + adr) = d;
--}
--
--void redwood_flash_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- *(__u32 *)(map->map_priv_1 + adr) = d;
--}
--
--void redwood_flash_copy_to(struct map_info *map, unsigned long to,
-- const void *from, ssize_t len)
--{
-- memcpy((void *)(map->map_priv_1 + to), from, len);
--}
-+#define RW_PART0_OF 0
-+#define RW_PART0_SZ 0x10000
-+#define RW_PART1_OF RW_PART0_SZ
-+#define RW_PART1_SZ 0x200000 - 0x10000
-+#define RW_PART2_OF 0x200000
-+#define RW_PART2_SZ 0x10000
-+#define RW_PART3_OF 0x210000
-+#define RW_PART3_SZ 0x200000 - (0x10000 + 0x20000)
-+#define RW_PART4_OF 0x3e0000
-+#define RW_PART4_SZ 0x20000
-
--struct map_info redwood_flash_map = {
-- name: "IBM Redwood",
-- size: WINDOW_SIZE,
-- buswidth: 2,
-- read8: redwood_flash_read8,
-- read16: redwood_flash_read16,
-- read32: redwood_flash_read32,
-- copy_from: redwood_flash_copy_from,
-- write8: redwood_flash_write8,
-- write16: redwood_flash_write16,
-- write32: redwood_flash_write32,
-- copy_to: redwood_flash_copy_to
-+static struct mtd_partition redwood_flash_partitions[] = {
-+ {
-+ .name = "Redwood OpenBIOS Vital Product Data",
-+ .offset = RW_PART0_OF,
-+ .size = RW_PART0_SZ,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
-+ },
-+ {
-+ .name = "Redwood kernel",
-+ .offset = RW_PART1_OF,
-+ .size = RW_PART1_SZ
-+ },
-+ {
-+ .name = "Redwood OpenBIOS non-volatile storage",
-+ .offset = RW_PART2_OF,
-+ .size = RW_PART2_SZ,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
-+ },
-+ {
-+ .name = "Redwood filesystem",
-+ .offset = RW_PART3_OF,
-+ .size = RW_PART3_SZ
-+ },
-+ {
-+ .name = "Redwood OpenBIOS",
-+ .offset = RW_PART4_OF,
-+ .size = RW_PART4_SZ,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
-+ }
- };
-
-+#else /* CONFIG_REDWOOD_6 */
-+/* FIXME: the window is bigger - armin */
-+#define WINDOW_ADDR 0xff800000
-+#define WINDOW_SIZE 0x00800000
-+
-+#define RW_PART0_OF 0
-+#define RW_PART0_SZ 0x400000 /* 4 MiB data */
-+#define RW_PART1_OF RW_PART0_OF + RW_PART0_SZ
-+#define RW_PART1_SZ 0x10000 /* 64K VPD */
-+#define RW_PART2_OF RW_PART1_OF + RW_PART1_SZ
-+#define RW_PART2_SZ 0x400000 - (0x10000 + 0x20000)
-+#define RW_PART3_OF RW_PART2_OF + RW_PART2_SZ
-+#define RW_PART3_SZ 0x20000
-
- static struct mtd_partition redwood_flash_partitions[] = {
- {
-- name: "Redwood OpenBIOS Vital Product Data",
-- offset: 0,
-- size: 0x10000,
-- mask_flags: MTD_WRITEABLE /* force read-only */
-+ .name = "Redwood filesystem",
-+ .offset = RW_PART0_OF,
-+ .size = RW_PART0_SZ
- },
- {
-- name: "Redwood kernel",
-- offset: 0x10000,
-- size: 0x200000 - 0x10000
-+ .name = "Redwood OpenBIOS Vital Product Data",
-+ .offset = RW_PART1_OF,
-+ .size = RW_PART1_SZ,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
- },
- {
-- name: "Redwood OpenBIOS non-volatile storage",
-- offset: 0x200000,
-- size: 0x10000,
-- mask_flags: MTD_WRITEABLE /* force read-only */
-+ .name = "Redwood kernel",
-+ .offset = RW_PART2_OF,
-+ .size = RW_PART2_SZ
- },
- {
-- name: "Redwood filesystem",
-- offset: 0x210000,
-- size: 0x200000 - (0x10000 + 0x20000)
-- },
-- {
-- name: "Redwood OpenBIOS",
-- offset: 0x3e0000,
-- size: 0x20000,
-- mask_flags: MTD_WRITEABLE /* force read-only */
-+ .name = "Redwood OpenBIOS",
-+ .offset = RW_PART3_OF,
-+ .size = RW_PART3_SZ,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
- }
- };
-+
-+#endif /* CONFIG_REDWOOD_6 */
-+
-+struct map_info redwood_flash_map = {
-+ .name = "IBM Redwood",
-+ .size = WINDOW_SIZE,
-+ .buswidth = 2,
-+ .phys = WINDOW_ADDR,
-+};
-+
-+
- #define NUM_REDWOOD_FLASH_PARTITIONS \
- (sizeof(redwood_flash_partitions)/sizeof(redwood_flash_partitions[0]))
-
-@@ -140,18 +131,19 @@
- printk(KERN_NOTICE "redwood: flash mapping: %x at %x\n",
- WINDOW_SIZE, WINDOW_ADDR);
-
-- redwood_flash_map.map_priv_1 =
-+ redwood_flash_map.virt =
- (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-
-- if (!redwood_flash_map.map_priv_1) {
-+ if (!redwood_flash_map.virt) {
- printk("init_redwood_flash: failed to ioremap\n");
- return -EIO;
- }
-+ simple_map_init(&redwood_flash_map);
-
- redwood_mtd = do_map_probe("cfi_probe",&redwood_flash_map);
-
- if (redwood_mtd) {
-- redwood_mtd->module = THIS_MODULE;
-+ redwood_mtd->owner = THIS_MODULE;
- return add_mtd_partitions(redwood_mtd,
- redwood_flash_partitions,
- NUM_REDWOOD_FLASH_PARTITIONS);
-@@ -164,10 +156,15 @@
- {
- if (redwood_mtd) {
- del_mtd_partitions(redwood_mtd);
-- iounmap((void *)redwood_flash_map.map_priv_1);
-+ /* moved iounmap after map_destroy - armin */
- map_destroy(redwood_mtd);
-+ iounmap((void *)redwood_flash_map.virt);
- }
- }
-
- module_init(init_redwood_flash);
- module_exit(cleanup_redwood_flash);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("MontaVista Software <source@mvista.com>");
-+MODULE_DESCRIPTION("MTD map driver for the IBM Redwood reference boards");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/rpxlite.c linux/drivers/mtd/maps/rpxlite.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/rpxlite.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/rpxlite.c 2004-11-17 18:17:59.127300544 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Handle mapping of the flash on the RPX Lite and CLLF boards
- */
-@@ -7,6 +7,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -17,80 +18,31 @@
-
- static struct mtd_info *mymtd;
-
--__u8 rpxlite_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 rpxlite_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 rpxlite_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void rpxlite_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
--}
--
--void rpxlite_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void rpxlite_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void rpxlite_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void rpxlite_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio((void *)(map->map_priv_1 + to), from, len);
--}
--
--struct map_info rpxlite_map = {
-- name: "RPX",
-- size: WINDOW_SIZE,
-- buswidth: 4,
-- read8: rpxlite_read8,
-- read16: rpxlite_read16,
-- read32: rpxlite_read32,
-- copy_from: rpxlite_copy_from,
-- write8: rpxlite_write8,
-- write16: rpxlite_write16,
-- write32: rpxlite_write32,
-- copy_to: rpxlite_copy_to
-+static struct map_info rpxlite_map = {
-+ .name = "RPX",
-+ .size = WINDOW_SIZE,
-+ .buswidth = 4,
-+ .phys = WINDOW_ADDR,
- };
-
- int __init init_rpxlite(void)
- {
- printk(KERN_NOTICE "RPX Lite or CLLF flash device: %x at %x\n", WINDOW_SIZE*4, WINDOW_ADDR);
-- rpxlite_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4);
-+ rpxlite_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4);
-
-- if (!rpxlite_map.map_priv_1) {
-+ if (!rpxlite_map.virt) {
- printk("Failed to ioremap\n");
- return -EIO;
- }
-+ simple_map_init(&rpxlite_map);
- mymtd = do_map_probe("cfi_probe", &rpxlite_map);
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
- add_mtd_device(mymtd);
- return 0;
- }
-
-- iounmap((void *)rpxlite_map.map_priv_1);
-+ iounmap((void *)rpxlite_map.virt);
- return -ENXIO;
- }
-
-@@ -100,9 +52,9 @@
- del_mtd_device(mymtd);
- map_destroy(mymtd);
- }
-- if (rpxlite_map.map_priv_1) {
-- iounmap((void *)rpxlite_map.map_priv_1);
-- rpxlite_map.map_priv_1 = 0;
-+ if (rpxlite_map.virt) {
-+ iounmap((void *)rpxlite_map.virt);
-+ rpxlite_map.virt = 0;
- }
- }
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/sa1100-flash.c linux/drivers/mtd/maps/sa1100-flash.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/sa1100-flash.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/sa1100-flash.c 2004-11-17 18:17:59.129300240 +0100
-@@ -3,7 +3,7 @@
- *
- * (C) 2000 Nicolas Pitre <nico@cam.org>
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
-@@ -11,278 +11,212 @@
- #include <linux/types.h>
- #include <linux/ioport.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/slab.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/partitions.h>
-+#include <linux/mtd/concat.h>
-
- #include <asm/hardware.h>
-+#include <asm/mach-types.h>
- #include <asm/io.h>
-+#include <asm/sizes.h>
-
-+#include <asm/arch/h3600.h>
-
- #ifndef CONFIG_ARCH_SA1100
- #error This is for SA1100 architecture only
- #endif
-
-+/*
-+ * This isnt complete yet, so...
-+ */
-+#define CONFIG_MTD_SA1100_STATICMAP 1
-
--#define WINDOW_ADDR 0xe8000000
--
--static __u8 sa1100_read8(struct map_info *map, unsigned long ofs)
--{
-- return readb(map->map_priv_1 + ofs);
--}
--
--static __u16 sa1100_read16(struct map_info *map, unsigned long ofs)
--{
-- return readw(map->map_priv_1 + ofs);
--}
--
--static __u32 sa1100_read32(struct map_info *map, unsigned long ofs)
--{
-- return readl(map->map_priv_1 + ofs);
--}
--
--static void sa1100_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy(to, (void *)(map->map_priv_1 + from), len);
--}
--
--static void sa1100_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- writeb(d, map->map_priv_1 + adr);
--}
--
--static void sa1100_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- writew(d, map->map_priv_1 + adr);
--}
--
--static void sa1100_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- writel(d, map->map_priv_1 + adr);
--}
--
--static void sa1100_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy((void *)(map->map_priv_1 + to), from, len);
--}
--
--static struct map_info sa1100_map = {
-- name: "SA1100 flash",
-- read8: sa1100_read8,
-- read16: sa1100_read16,
-- read32: sa1100_read32,
-- copy_from: sa1100_copy_from,
-- write8: sa1100_write8,
-- write16: sa1100_write16,
-- write32: sa1100_write32,
-- copy_to: sa1100_copy_to,
--
-- map_priv_1: WINDOW_ADDR,
-- map_priv_2: -1,
--};
--
--
-+#ifdef CONFIG_MTD_SA1100_STATICMAP
- /*
- * Here are partition information for all known SA1100-based devices.
- * See include/linux/mtd/partitions.h for definition of the mtd_partition
- * structure.
- *
-- * The *_max_flash_size is the maximum possible mapped flash size which
-- * is not necessarily the actual flash size. It must be no more than
-- * the value specified in the "struct map_desc *_io_desc" mapping
-- * definition for the corresponding machine.
-+ * Please note:
-+ * 1. We no longer support static flash mappings via the machine io_desc
-+ * structure.
-+ * 2. The flash size given should be the largest flash size that can
-+ * be accommodated.
-+ *
-+ * The MTD layer will detect flash chip aliasing and reduce the size of
-+ * the map accordingly.
- *
- * Please keep these in alphabetical order, and formatted as per existing
- * entries. Thanks.
- */
-
- #ifdef CONFIG_SA1100_ADSBITSY
--#define ADSBITSY_FLASH_SIZE 0x02000000
- static struct mtd_partition adsbitsy_partitions[] = {
- {
-- name: "bootROM",
-- size: 0x80000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "zImage",
-- size: 0x100000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "ramdisk.gz",
-- size: 0x300000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "User FS",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "bootROM",
-+ .size = 0x80000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "zImage",
-+ .size = 0x100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "ramdisk.gz",
-+ .size = 0x300000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "User FS",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_ASSABET
- /* Phase 4 Assabet has two 28F160B3 flash parts in bank 0: */
--#define ASSABET4_FLASH_SIZE 0x00400000
- static struct mtd_partition assabet4_partitions[] = {
- {
-- name: "bootloader",
-- size: 0x00020000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "bootloader params",
-- size: 0x00020000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "jffs",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "bootloader",
-+ .size = 0x00020000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "bootloader params",
-+ .size = 0x00020000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "jffs",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
-
- /* Phase 5 Assabet has two 28F128J3A flash parts in bank 0: */
--#define ASSABET5_FLASH_SIZE 0x02000000
- static struct mtd_partition assabet5_partitions[] = {
- {
-- name: "bootloader",
-- size: 0x00040000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "bootloader params",
-- size: 0x00040000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "jffs",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "bootloader",
-+ .size = 0x00040000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "bootloader params",
-+ .size = 0x00040000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "jffs",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
-
--#define ASSABET_FLASH_SIZE ASSABET5_FLASH_SIZE
- #define assabet_partitions assabet5_partitions
- #endif
-
- #ifdef CONFIG_SA1100_BADGE4
--
- /*
-- * 1 x Intel 28F320C3BA100 Advanced+ Boot Block Flash (32 Mi bit)
-+ * 1 x Intel 28F320C3 Advanced+ Boot Block Flash (32 Mi bit)
- * Eight 4 KiW Parameter Bottom Blocks (64 KiB)
- * Sixty-three 32 KiW Main Blocks (4032 Ki b)
-+ *
-+ * <or>
-+ *
-+ * 1 x Intel 28F640C3 Advanced+ Boot Block Flash (64 Mi bit)
-+ * Eight 4 KiW Parameter Bottom Blocks (64 KiB)
-+ * One-hundred-twenty-seven 32 KiW Main Blocks (8128 Ki b)
- */
--#define BADGE4_FLASH_SIZE 0x00400000
- static struct mtd_partition badge4_partitions[] = {
- {
-- name: "BLOB boot loader",
-- offset: 0,
-- size: 0x0000A000
-- }, {
-- name: "params",
-- offset: MTDPART_OFS_APPEND,
-- size: 0x00006000
-- }, {
-- name: "kernel",
-- offset: MTDPART_OFS_APPEND,
-- size: 0x00100000
-- }, {
-- name: "root",
-- offset: MTDPART_OFS_APPEND,
-- size: MTDPART_SIZ_FULL
-+ .name = "BLOB boot loader",
-+ .offset = 0,
-+ .size = 0x0000A000
-+ }, {
-+ .name = "params",
-+ .offset = MTDPART_OFS_APPEND,
-+ .size = 0x00006000
-+ }, {
-+ .name = "root",
-+ .offset = MTDPART_OFS_APPEND,
-+ .size = MTDPART_SIZ_FULL
- }
- };
--
- #endif
-
-
- #ifdef CONFIG_SA1100_CERF
- #ifdef CONFIG_SA1100_CERF_FLASH_32MB
--#define CERF_FLASH_SIZE 0x02000000
--static struct mtd_partition cerf_partitions[] = {
-- {
-- name: "firmware",
-- size: 0x00040000,
-- offset: 0,
-- }, {
-- name: "params",
-- size: 0x00040000,
-- offset: 0x00040000,
-- }, {
-- name: "kernel",
-- size: 0x00100000,
-- offset: 0x00080000,
-- }, {
-- name: "rootdisk",
-- size: 0x01E80000,
-- offset: 0x00180000,
-- }
--};
-+# define CERF_FLASH_SIZE 0x02000000
- #elif defined CONFIG_SA1100_CERF_FLASH_16MB
--#define CERF_FLASH_SIZE 0x01000000
-+# define CERF_FLASH_SIZE 0x01000000
-+#elif defined CONFIG_SA1100_CERF_FLASH_8MB
-+# define CERF_FLASH_SIZE 0x00800000
-+#else
-+# error "Undefined flash size for CERF in sa1100-flash.c"
-+#endif
-+
- static struct mtd_partition cerf_partitions[] = {
- {
-- name: "firmware",
-- size: 0x00020000,
-- offset: 0,
-- }, {
-- name: "params",
-- size: 0x00020000,
-- offset: 0x00020000,
-- }, {
-- name: "kernel",
-- size: 0x00100000,
-- offset: 0x00040000,
-- }, {
-- name: "rootdisk",
-- size: 0x00EC0000,
-- offset: 0x00140000,
-+ .name = "Bootloader",
-+ .size = 0x00020000,
-+ .offset = 0x00000000,
-+ }, {
-+ .name = "Params",
-+ .size = 0x00040000,
-+ .offset = 0x00020000,
-+ }, {
-+ .name = "Kernel",
-+ .size = 0x00100000,
-+ .offset = 0x00060000,
-+ }, {
-+ .name = "Filesystem",
-+ .size = CERF_FLASH_SIZE-0x00160000,
-+ .offset = 0x00160000,
- }
- };
--#elif defined CONFIG_SA1100_CERF_FLASH_8MB
--# error "Unwritten type definition"
--#else
--# error "Undefined memory orientation for CERF in sa1100-flash.c"
--#endif
- #endif
-
- #ifdef CONFIG_SA1100_CONSUS
--#define CONSUS_FLASH_SIZE 0x02000000
- static struct mtd_partition consus_partitions[] = {
- {
-- name: "Consus boot firmware",
-- offset: 0,
-- size: 0x00040000,
-- mask_flags: MTD_WRITABLE, /* force read-only */
-- }, {
-- name: "Consus kernel",
-- offset: 0x00040000,
-- size: 0x00100000,
-- mask_flags: 0,
-+ .name = "Consus boot firmware",
-+ .offset = 0,
-+ .size = 0x00040000,
-+ .mask_flags = MTD_WRITABLE, /* force read-only */
-+ }, {
-+ .name = "Consus kernel",
-+ .offset = 0x00040000,
-+ .size = 0x00100000,
-+ .mask_flags = 0,
- }, {
-- name: "Consus disk",
-- offset: 0x00140000,
-+ .name = "Consus disk",
-+ .offset = 0x00140000,
- /* The rest (up to 16M) for jffs. We could put 0 and
- make it find the size automatically, but right now
- i have 32 megs. jffs will use all 32 megs if given
- the chance, and this leads to horrible problems
- when you try to re-flash the image because blob
- won't erase the whole partition. */
-- size: 0x01000000 - 0x00140000,
-- mask_flags: 0,
-+ .size = 0x01000000 - 0x00140000,
-+ .mask_flags = 0,
- }, {
- /* this disk is a secondary disk, which can be used as
- needed, for simplicity, make it the size of the other
- consus partition, although realistically it could be
- the remainder of the disk (depending on the file
- system used) */
-- name: "Consus disk2",
-- offset: 0x01000000,
-- size: 0x01000000 - 0x00140000,
-- mask_flags: 0,
-+ .name = "Consus disk2",
-+ .offset = 0x01000000,
-+ .size = 0x01000000 - 0x00140000,
-+ .mask_flags = 0,
- }
- };
- #endif
-@@ -292,96 +226,95 @@
- #define FLEXANET_FLASH_SIZE 0x02000000
- static struct mtd_partition flexanet_partitions[] = {
- {
-- name: "bootloader",
-- size: 0x00040000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "bootloader params",
-- size: 0x00040000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "kernel",
-- size: 0x000C0000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "altkernel",
-- size: 0x000C0000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "root",
-- size: 0x00400000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "free1",
-- size: 0x00300000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "free2",
-- size: 0x00300000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "free3",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-+ .name = "bootloader",
-+ .size = 0x00040000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "bootloader params",
-+ .size = 0x00040000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "kernel",
-+ .size = 0x000C0000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "altkernel",
-+ .size = 0x000C0000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "root",
-+ .size = 0x00400000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "free1",
-+ .size = 0x00300000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "free2",
-+ .size = 0x00300000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "free3",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_FREEBIRD
--#define FREEBIRD_FLASH_SIZE 0x02000000
- static struct mtd_partition freebird_partitions[] = {
--#if CONFIG_SA1100_FREEBIRD_NEW
-+#ifdef CONFIG_SA1100_FREEBIRD_NEW
- {
-- name: "firmware",
-- size: 0x00040000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "kernel",
-- size: 0x00080000,
-- offset: 0x00040000,
-- }, {
-- name: "params",
-- size: 0x00040000,
-- offset: 0x000C0000,
-- }, {
-- name: "initrd",
-- size: 0x00100000,
-- offset: 0x00100000,
-- }, {
-- name: "root cramfs",
-- size: 0x00300000,
-- offset: 0x00200000,
-- }, {
-- name: "usr cramfs",
-- size: 0x00C00000,
-- offset: 0x00500000,
-- }, {
-- name: "local",
-- size: MTDPART_SIZ_FULL,
-- offset: 0x01100000,
-+ .name = "firmware",
-+ .size = 0x00040000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "kernel",
-+ .size = 0x00080000,
-+ .offset = 0x00040000,
-+ }, {
-+ .name = "params",
-+ .size = 0x00040000,
-+ .offset = 0x000C0000,
-+ }, {
-+ .name = "initrd",
-+ .size = 0x00100000,
-+ .offset = 0x00100000,
-+ }, {
-+ .name = "root cramfs",
-+ .size = 0x00300000,
-+ .offset = 0x00200000,
-+ }, {
-+ .name = "usr cramfs",
-+ .size = 0x00C00000,
-+ .offset = 0x00500000,
-+ }, {
-+ .name = "local",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = 0x01100000,
- }
- #else
- {
-- size: 0x00040000,
-- offset: 0,
-+ .size = 0x00040000,
-+ .offset = 0,
- }, {
-- size: 0x000c0000,
-- offset: MTDPART_OFS_APPEND,
-+ .size = 0x000c0000,
-+ .offset = MTDPART_OFS_APPEND,
- }, {
-- size: 0x00400000,
-- offset: MTDPART_OFS_APPEND,
-+ .size = 0x00400000,
-+ .offset = MTDPART_OFS_APPEND,
- }, {
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- #endif
- };
-@@ -389,178 +322,215 @@
-
- #ifdef CONFIG_SA1100_FRODO
- /* Frodo has 2 x 16M 28F128J3A flash chips in bank 0: */
--#define FRODO_FLASH_SIZE 0x02000000
- static struct mtd_partition frodo_partitions[] =
- {
- {
-- name: "Boot Loader",
-- size: 0x00040000,
-- offset: 0x00000000
-- }, {
-- name: "Parameter Block",
-- size: 0x00040000,
-- offset: MTDPART_OFS_APPEND
-- }, {
-- name: "Linux Kernel",
-- size: 0x00100000,
-- offset: MTDPART_OFS_APPEND
-- }, {
-- name: "Ramdisk",
-- size: 0x00680000,
-- offset: MTDPART_OFS_APPEND
-- }, {
-- name: "Flash File System",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND
-+ .name = "bootloader",
-+ .size = 0x00040000,
-+ .offset = 0x00000000,
-+ .mask_flags = MTD_WRITEABLE
-+ }, {
-+ .name = "bootloader params",
-+ .size = 0x00040000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE
-+ }, {
-+ .name = "kernel",
-+ .size = 0x00100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE
-+ }, {
-+ .name = "ramdisk",
-+ .size = 0x00400000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE
-+ }, {
-+ .name = "file system",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_GRAPHICSCLIENT
--#define GRAPHICSCLIENT_FLASH_SIZE 0x02000000
- static struct mtd_partition graphicsclient_partitions[] = {
- {
-- name: "zImage",
-- size: 0x100000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "ramdisk.gz",
-- size: 0x300000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "User FS",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "zImage",
-+ .size = 0x100000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "ramdisk.gz",
-+ .size = 0x300000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "User FS",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_GRAPHICSMASTER
--#define GRAPHICSMASTER_FLASH_SIZE 0x01000000
- static struct mtd_partition graphicsmaster_partitions[] = {
- {
-- name: "zImage",
-- size: 0x100000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-+ .name = "zImage",
-+ .size = 0x100000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
- {
-- name: "ramdisk.gz",
-- size: 0x300000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-+ .name = "ramdisk.gz",
-+ .size = 0x300000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
- {
-- name: "User FS",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "User FS",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #endif
-
--#ifdef CONFIG_SA1100_H3600
--#define H3600_FLASH_SIZE 0x02000000
--static struct mtd_partition h3600_partitions[] = {
-+#ifdef CONFIG_SA1100_H3XXX
-+static struct mtd_partition h3xxx_partitions[] = {
- {
-- name: "H3600 boot firmware",
-- size: 0x00040000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "H3600 kernel",
-- size: 0x00080000,
-- offset: 0x00040000,
-+ .name = "H3XXX boot firmware",
-+ .size = 0x00040000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
-- name: "H3600 params",
-- size: 0x00040000,
-- offset: 0x000C0000,
-+#ifdef CONFIG_MTD_2PARTS_IPAQ
-+ .name = "H3XXX root jffs2",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = 0x00040000,
-+#else
-+ .name = "H3XXX kernel",
-+ .size = 0x00080000,
-+ .offset = 0x00040000,
-+ }, {
-+ .name = "H3XXX params",
-+ .size = 0x00040000,
-+ .offset = 0x000C0000,
- }, {
- #ifdef CONFIG_JFFS2_FS
-- name: "H3600 root jffs2",
-- size: MTDPART_SIZ_FULL,
-- offset: 0x00100000,
-+ .name = "H3XXX root jffs2",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = 0x00100000,
- #else
-- name: "H3600 initrd",
-- size: 0x00100000,
-- offset: 0x00100000,
-+ .name = "H3XXX initrd",
-+ .size = 0x00100000,
-+ .offset = 0x00100000,
- }, {
-- name: "H3600 root cramfs",
-- size: 0x00300000,
-- offset: 0x00200000,
-+ .name = "H3XXX root cramfs",
-+ .size = 0x00300000,
-+ .offset = 0x00200000,
- }, {
-- name: "H3600 usr cramfs",
-- size: 0x00800000,
-- offset: 0x00500000,
-+ .name = "H3XXX usr cramfs",
-+ .size = 0x00800000,
-+ .offset = 0x00500000,
- }, {
-- name: "H3600 usr local",
-- size: MTDPART_SIZ_FULL,
-- offset: 0x00d00000,
-+ .name = "H3XXX usr local",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = 0x00d00000,
-+#endif
- #endif
- }
- };
-
--static void h3600_set_vpp(struct map_info *map, int vpp)
-+static void h3xxx_set_vpp(struct map_info *map, int vpp)
- {
- assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, vpp);
- }
-+#else
-+#define h3xxx_set_vpp NULL
-+#endif
-+
-+#ifdef CONFIG_SA1100_HACKKIT
-+static struct mtd_partition hackkit_partitions[] = {
-+ {
-+ .name = "BLOB",
-+ .size = 0x00040000,
-+ .offset = 0x00000000,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "config",
-+ .size = 0x00040000,
-+ .offset = MTDPART_OFS_APPEND,
-+ }, {
-+ .name = "kernel",
-+ .size = 0x00100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ }, {
-+ .name = "initrd",
-+ .size = 0x00180000,
-+ .offset = MTDPART_OFS_APPEND,
-+ }, {
-+ .name = "rootfs",
-+ .size = 0x700000,
-+ .offset = MTDPART_OFS_APPEND,
-+ }, {
-+ .name = "data",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
-+ }
-+};
- #endif
-
- #ifdef CONFIG_SA1100_HUW_WEBPANEL
--#define HUW_WEBPANEL_FLASH_SIZE 0x01000000
- static struct mtd_partition huw_webpanel_partitions[] = {
- {
-- name: "Loader",
-- size: 0x00040000,
-- offset: 0,
-- }, {
-- name: "Sector 1",
-- size: 0x00040000,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "Loader",
-+ .size = 0x00040000,
-+ .offset = 0,
-+ }, {
-+ .name = "Sector 1",
-+ .size = 0x00040000,
-+ .offset = MTDPART_OFS_APPEND,
- }, {
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_JORNADA720
--#define JORNADA720_FLASH_SIZE 0x02000000
- static struct mtd_partition jornada720_partitions[] = {
- {
-- name: "JORNADA720 boot firmware",
-- size: 0x00040000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-+ .name = "JORNADA720 boot firmware",
-+ .size = 0x00040000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
-- name: "JORNADA720 kernel",
-- size: 0x000c0000,
-- offset: 0x00040000,
-+ .name = "JORNADA720 kernel",
-+ .size = 0x000c0000,
-+ .offset = 0x00040000,
- }, {
-- name: "JORNADA720 params",
-- size: 0x00040000,
-- offset: 0x00100000,
-+ .name = "JORNADA720 params",
-+ .size = 0x00040000,
-+ .offset = 0x00100000,
- }, {
-- name: "JORNADA720 initrd",
-- size: 0x00100000,
-- offset: 0x00140000,
-+ .name = "JORNADA720 initrd",
-+ .size = 0x00100000,
-+ .offset = 0x00140000,
- }, {
-- name: "JORNADA720 root cramfs",
-- size: 0x00300000,
-- offset: 0x00240000,
-+ .name = "JORNADA720 root cramfs",
-+ .size = 0x00300000,
-+ .offset = 0x00240000,
- }, {
-- name: "JORNADA720 usr cramfs",
-- size: 0x00800000,
-- offset: 0x00540000,
-+ .name = "JORNADA720 usr cramfs",
-+ .size = 0x00800000,
-+ .offset = 0x00540000,
- }, {
-- name: "JORNADA720 usr local",
-- size: 0 /* will expand to the end of the flash */
-- offset: 0x00d00000,
-+ .name = "JORNADA720 usr local",
-+ .size = 0, /* will expand to the end of the flash */
-+ .offset = 0x00d00000,
- }
- };
-
--static void jornada720_set_vpp(int vpp)
-+static void jornada720_set_vpp(struct map_info *map, int vpp)
- {
- if (vpp)
- PPSR |= 0x80;
-@@ -568,454 +538,811 @@
- PPSR &= ~0x80;
- PPDR |= 0x80;
- }
--
-+#else
-+#define jornada720_set_vpp NULL
- #endif
-
- #ifdef CONFIG_SA1100_PANGOLIN
--#define PANGOLIN_FLASH_SIZE 0x04000000
- static struct mtd_partition pangolin_partitions[] = {
- {
-- name: "boot firmware",
-- size: 0x00080000,
-- offset: 0x00000000,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "kernel",
-- size: 0x00100000,
-- offset: 0x00080000,
-- }, {
-- name: "initrd",
-- size: 0x00280000,
-- offset: 0x00180000,
-- }, {
-- name: "initrd-test",
-- size: 0x03C00000,
-- offset: 0x00400000,
-+ .name = "boot firmware",
-+ .size = 0x00080000,
-+ .offset = 0x00000000,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "kernel",
-+ .size = 0x00100000,
-+ .offset = 0x00080000,
-+ }, {
-+ .name = "initrd",
-+ .size = 0x00280000,
-+ .offset = 0x00180000,
-+ }, {
-+ .name = "initrd-test",
-+ .size = 0x03C00000,
-+ .offset = 0x00400000,
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_PT_SYSTEM3
- /* erase size is 0x40000 == 256k partitions have to have this boundary */
--#define SYSTEM3_FLASH_SIZE 0x01000000
- static struct mtd_partition system3_partitions[] = {
- {
-- name: "BLOB",
-- size: 0x00040000,
-- offset: 0x00000000,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "config",
-- size: 0x00040000,
-- offset: MTDPART_OFS_APPEND,
-- }, {
-- name: "kernel",
-- size: 0x00100000,
-- offset: MTDPART_OFS_APPEND,
-- }, {
-- name: "root",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "BLOB",
-+ .size = 0x00040000,
-+ .offset = 0x00000000,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "config",
-+ .size = 0x00040000,
-+ .offset = MTDPART_OFS_APPEND,
-+ }, {
-+ .name = "kernel",
-+ .size = 0x00100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ }, {
-+ .name = "root",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_SHANNON
--#define SHANNON_FLASH_SIZE 0x00400000
- static struct mtd_partition shannon_partitions[] = {
- {
-- name: "BLOB boot loader",
-- offset: 0,
-- size: 0x20000
-+ .name = "BLOB boot loader",
-+ .offset = 0,
-+ .size = 0x20000
- },
- {
-- name: "kernel",
-- offset: MTDPART_OFS_APPEND,
-- size: 0xe0000
-+ .name = "kernel",
-+ .offset = MTDPART_OFS_APPEND,
-+ .size = 0xe0000
- },
- {
-- name: "initrd",
-- offset: MTDPART_OFS_APPEND,
-- size: MTDPART_SIZ_FULL
-+ .name = "initrd",
-+ .offset = MTDPART_OFS_APPEND,
-+ .size = MTDPART_SIZ_FULL
- }
- };
-
- #endif
-
- #ifdef CONFIG_SA1100_SHERMAN
--#define SHERMAN_FLASH_SIZE 0x02000000
- static struct mtd_partition sherman_partitions[] = {
- {
-- size: 0x50000,
-- offset: 0,
-+ .size = 0x50000,
-+ .offset = 0,
- }, {
-- size: 0x70000,
-- offset: MTDPART_OFS_APPEND,
-+ .size = 0x70000,
-+ .offset = MTDPART_OFS_APPEND,
- }, {
-- size: 0x600000,
-- offset: MTDPART_OFS_APPEND,
-+ .size = 0x600000,
-+ .offset = MTDPART_OFS_APPEND,
- }, {
-- size: 0xA0000,
-- offset: MTDPART_OFS_APPEND,
-+ .size = 0xA0000,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_SIMPAD
--#define SIMPAD_FLASH_SIZE 0x02000000
- static struct mtd_partition simpad_partitions[] = {
- {
-- name: "SIMpad boot firmware",
-- size: 0x00080000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "SIMpad kernel",
-- size: 0x00100000,
-- offset: 0x00080000,
-- }, {
--#ifdef CONFIG_JFFS2_FS
-- name: "SIMpad root jffs2",
-- size: MTDPART_SIZ_FULL,
-- offset: 0x00180000,
-+ .name = "SIMpad boot firmware",
-+ .size = 0x00080000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "SIMpad kernel",
-+ .size = 0x00100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ }, {
-+#ifdef CONFIG_ROOT_CRAMFS
-+ .name = "SIMpad root cramfs",
-+ .size =0x00D80000,
-+ .offset = MTDPART_OFS_APPEND
-+
-+ }, {
-+ .name = "SIMpad local jffs2",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND
- #else
-- name: "SIMpad initrd",
-- size: 0x00300000,
-- offset: 0x00180000,
-- }, {
-- name: "SIMpad root cramfs",
-- size: 0x00300000,
-- offset: 0x00480000,
-- }, {
-- name: "SIMpad usr cramfs",
-- size: 0x005c0000,
-- offset: 0x00780000,
-- }, {
-- name: "SIMpad usr local",
-- size: MTDPART_SIZ_FULL,
-- offset: 0x00d40000,
-+ .name = "SIMpad root jffs2",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND
- #endif
- }
- };
- #endif /* CONFIG_SA1100_SIMPAD */
-
- #ifdef CONFIG_SA1100_STORK
--#define STORK_FLASH_SIZE 0x02000000
- static struct mtd_partition stork_partitions[] = {
- {
-- name: "STORK boot firmware",
-- size: 0x00040000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "STORK params",
-- size: 0x00040000,
-- offset: 0x00040000,
-- }, {
-- name: "STORK kernel",
-- size: 0x00100000,
-- offset: 0x00080000,
-+ .name = "STORK boot firmware",
-+ .size = 0x00040000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "STORK params",
-+ .size = 0x00040000,
-+ .offset = 0x00040000,
-+ }, {
-+ .name = "STORK kernel",
-+ .size = 0x00100000,
-+ .offset = 0x00080000,
- }, {
- #ifdef CONFIG_JFFS2_FS
-- name: "STORK root jffs2",
-- offset: 0x00180000,
-- size: MTDPART_SIZ_FULL,
-+ .name = "STORK root jffs2",
-+ .offset = 0x00180000,
-+ .size = MTDPART_SIZ_FULL,
- #else
-- name: "STORK initrd",
-- size: 0x00100000,
-- offset: 0x00180000,
-- }, {
-- name: "STORK root cramfs",
-- size: 0x00300000,
-- offset: 0x00280000,
-- }, {
-- name: "STORK usr cramfs",
-- size: 0x00800000,
-- offset: 0x00580000,
-- }, {
-- name: "STORK usr local",
-- offset: 0x00d80000,
-- size: MTDPART_SIZ_FULL,
-+ .name = "STORK initrd",
-+ .size = 0x00100000,
-+ .offset = 0x00180000,
-+ }, {
-+ .name = "STORK root cramfs",
-+ .size = 0x00300000,
-+ .offset = 0x00280000,
-+ }, {
-+ .name = "STORK usr cramfs",
-+ .size = 0x00800000,
-+ .offset = 0x00580000,
-+ }, {
-+ .name = "STORK usr local",
-+ .offset = 0x00d80000,
-+ .size = MTDPART_SIZ_FULL,
-+#endif
-+ }
-+};
- #endif
-+
-+#ifdef CONFIG_SA1100_TRIZEPS
-+static struct mtd_partition trizeps_partitions[] = {
-+ {
-+ .name = "Bootloader",
-+ .size = 0x00100000,
-+ .offset = 0,
-+ }, {
-+ .name = "Kernel",
-+ .size = 0x00100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ }, {
-+ .name = "root",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_YOPY
--#define YOPY_FLASH_SIZE 0x08000000
- static struct mtd_partition yopy_partitions[] = {
- {
-- name: "boot firmware",
-- size: 0x00040000,
-- offset: 0x00000000,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-+ .name = "boot firmware",
-+ .size = 0x00040000,
-+ .offset = 0x00000000,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
-- name: "kernel",
-- size: 0x00080000,
-- offset: 0x00080000,
-+ .name = "kernel",
-+ .size = 0x00080000,
-+ .offset = 0x00080000,
- }, {
-- name: "initrd",
-- size: 0x00300000,
-- offset: 0x00100000,
-+ .name = "initrd",
-+ .size = 0x00300000,
-+ .offset = 0x00100000,
- }, {
-- name: "root",
-- size: 0x01000000,
-- offset: 0x00400000,
-+ .name = "root",
-+ .size = 0x01000000,
-+ .offset = 0x00400000,
- }
- };
- #endif
-
--extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
--extern int parse_bootldr_partitions(struct mtd_info *master, struct mtd_partition **pparts);
--
--static struct mtd_partition *parsed_parts;
--static struct mtd_info *mymtd;
--
--int __init sa1100_mtd_init(void)
-+static int __init sa1100_static_partitions(struct mtd_partition **parts)
- {
-- struct mtd_partition *parts;
-- int nb_parts = 0, ret;
-- int parsed_nr_parts = 0;
-- const char *part_type;
-- unsigned long base = -1UL;
--
-- /* Default flash buswidth */
-- sa1100_map.buswidth = (MSC0 & MSC_RBW) ? 2 : 4;
--
-- /*
-- * Static partition definition selection
-- */
-- part_type = "static";
-+ int nb_parts = 0;
-
- #ifdef CONFIG_SA1100_ADSBITSY
- if (machine_is_adsbitsy()) {
-- parts = adsbitsy_partitions;
-+ *parts = adsbitsy_partitions;
- nb_parts = ARRAY_SIZE(adsbitsy_partitions);
-- sa1100_map.size = ADSBITSY_FLASH_SIZE;
-- sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2 : 4;
- }
- #endif
- #ifdef CONFIG_SA1100_ASSABET
- if (machine_is_assabet()) {
-- parts = assabet_partitions;
-+ *parts = assabet_partitions;
- nb_parts = ARRAY_SIZE(assabet_partitions);
-- sa1100_map.size = ASSABET_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_BADGE4
- if (machine_is_badge4()) {
-- parts = badge4_partitions;
-+ *parts = badge4_partitions;
- nb_parts = ARRAY_SIZE(badge4_partitions);
-- sa1100_map.size = BADGE4_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_CERF
- if (machine_is_cerf()) {
-- parts = cerf_partitions;
-+ *parts = cerf_partitions;
- nb_parts = ARRAY_SIZE(cerf_partitions);
-- sa1100_map.size = CERF_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_CONSUS
- if (machine_is_consus()) {
-- parts = consus_partitions;
-+ *parts = consus_partitions;
- nb_parts = ARRAY_SIZE(consus_partitions);
-- sa1100_map.size = CONSUS_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_FLEXANET
- if (machine_is_flexanet()) {
-- parts = flexanet_partitions;
-+ *parts = flexanet_partitions;
- nb_parts = ARRAY_SIZE(flexanet_partitions);
-- sa1100_map.size = FLEXANET_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_FREEBIRD
- if (machine_is_freebird()) {
-- parts = freebird_partitions;
-+ *parts = freebird_partitions;
- nb_parts = ARRAY_SIZE(freebird_partitions);
-- sa1100_map.size = FREEBIRD_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_FRODO
- if (machine_is_frodo()) {
-- parts = frodo_partitions;
-+ *parts = frodo_partitions;
- nb_parts = ARRAY_SIZE(frodo_partitions);
-- sa1100_map.size = FRODO_FLASH_SIZE;
-- base = 0x00000000;
- }
- #endif
- #ifdef CONFIG_SA1100_GRAPHICSCLIENT
- if (machine_is_graphicsclient()) {
-- parts = graphicsclient_partitions;
-+ *parts = graphicsclient_partitions;
- nb_parts = ARRAY_SIZE(graphicsclient_partitions);
-- sa1100_map.size = GRAPHICSCLIENT_FLASH_SIZE;
-- sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2:4;
- }
- #endif
- #ifdef CONFIG_SA1100_GRAPHICSMASTER
- if (machine_is_graphicsmaster()) {
-- parts = graphicsmaster_partitions;
-+ *parts = graphicsmaster_partitions;
- nb_parts = ARRAY_SIZE(graphicsmaster_partitions);
-- sa1100_map.size = GRAPHICSMASTER_FLASH_SIZE;
-- sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2:4;
- }
- #endif
--#ifdef CONFIG_SA1100_H3600
-- if (machine_is_h3600()) {
-- parts = h3600_partitions;
-- nb_parts = ARRAY_SIZE(h3600_partitions);
-- sa1100_map.size = H3600_FLASH_SIZE;
-- sa1100_map.set_vpp = h3600_set_vpp;
-+#ifdef CONFIG_SA1100_H3XXX
-+ if (machine_is_h3xxx()) {
-+ *parts = h3xxx_partitions;
-+ nb_parts = ARRAY_SIZE(h3xxx_partitions);
-+ }
-+#endif
-+#ifdef CONFIG_SA1100_HACKKIT
-+ if (machine_is_hackkit()) {
-+ *parts = hackkit_partitions;
-+ nb_parts = ARRAY_SIZE(hackkit_partitions);
- }
- #endif
- #ifdef CONFIG_SA1100_HUW_WEBPANEL
- if (machine_is_huw_webpanel()) {
-- parts = huw_webpanel_partitions;
-+ *parts = huw_webpanel_partitions;
- nb_parts = ARRAY_SIZE(huw_webpanel_partitions);
-- sa1100_map.size = HUW_WEBPANEL_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_JORNADA720
- if (machine_is_jornada720()) {
-- parts = jornada720_partitions;
-+ *parts = jornada720_partitions;
- nb_parts = ARRAY_SIZE(jornada720_partitions);
-- sa1100_map.size = JORNADA720_FLASH_SIZE;
-- sa1100_map.set_vpp = jornada720_set_vpp;
- }
- #endif
- #ifdef CONFIG_SA1100_PANGOLIN
- if (machine_is_pangolin()) {
-- parts = pangolin_partitions;
-+ *parts = pangolin_partitions;
- nb_parts = ARRAY_SIZE(pangolin_partitions);
-- sa1100_map.size = PANGOLIN_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_PT_SYSTEM3
- if (machine_is_pt_system3()) {
-- parts = system3_partitions;
-+ *parts = system3_partitions;
- nb_parts = ARRAY_SIZE(system3_partitions);
-- sa1100_map.size = SYSTEM3_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_SHANNON
- if (machine_is_shannon()) {
-- parts = shannon_partitions;
-+ *parts = shannon_partitions;
- nb_parts = ARRAY_SIZE(shannon_partitions);
-- sa1100_map.size = SHANNON_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_SHERMAN
- if (machine_is_sherman()) {
-- parts = sherman_partitions;
-+ *parts = sherman_partitions;
- nb_parts = ARRAY_SIZE(sherman_partitions);
-- sa1100_map.size = SHERMAN_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_SIMPAD
- if (machine_is_simpad()) {
-- parts = simpad_partitions;
-+ *parts = simpad_partitions;
- nb_parts = ARRAY_SIZE(simpad_partitions);
-- sa1100_map.size = SIMPAD_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_STORK
- if (machine_is_stork()) {
-- parts = stork_partitions;
-+ *parts = stork_partitions;
- nb_parts = ARRAY_SIZE(stork_partitions);
-- sa1100_map.size = STORK_FLASH_SIZE;
-+ }
-+#endif
-+#ifdef CONFIG_SA1100_TRIZEPS
-+ if (machine_is_trizeps()) {
-+ *parts = trizeps_partitions;
-+ nb_parts = ARRAY_SIZE(trizeps_partitions);
- }
- #endif
- #ifdef CONFIG_SA1100_YOPY
- if (machine_is_yopy()) {
-- parts = yopy_partitions;
-+ *parts = yopy_partitions;
- nb_parts = ARRAY_SIZE(yopy_partitions);
-- sa1100_map.size = YOPY_FLASH_SIZE;
- }
- #endif
-
-+ return nb_parts;
-+}
-+#endif
-+
-+struct sa_info {
-+ unsigned long base;
-+ unsigned long size;
-+ int width;
-+ void *vbase;
-+ void (*set_vpp)(struct map_info *, int);
-+ struct map_info *map;
-+ struct mtd_info *mtd;
-+ struct resource *res;
-+};
-+
-+#define NR_SUBMTD 4
-+
-+static struct sa_info info[NR_SUBMTD];
-+
-+static int __init sa1100_setup_mtd(struct sa_info *sa, int nr, struct mtd_info **rmtd)
-+{
-+ struct mtd_info *subdev[nr];
-+ struct map_info *maps;
-+ int i, found = 0, ret = 0;
-+
- /*
-- * For simple flash devices, use ioremap to map the flash.
-+ * Allocate the map_info structs in one go.
- */
-- if (base != (unsigned long)-1) {
-- if (!request_mem_region(base, sa1100_map.size, "flash"))
-- return -EBUSY;
-- sa1100_map.map_priv_2 = base;
-- sa1100_map.map_priv_1 = (unsigned long)
-- ioremap(base, sa1100_map.size);
-+ maps = kmalloc(sizeof(struct map_info) * nr, GFP_KERNEL);
-+ if (!maps)
-+ return -ENOMEM;
-+
-+ memset(maps, 0, sizeof(struct map_info) * nr);
-+
-+ /*
-+ * Claim and then map the memory regions.
-+ */
-+ for (i = 0; i < nr; i++) {
-+ if (sa[i].base == (unsigned long)-1)
-+ break;
-+
-+ sa[i].res = request_mem_region(sa[i].base, sa[i].size, "sa1100 flash");
-+ if (!sa[i].res) {
-+ ret = -EBUSY;
-+ break;
-+ }
-+
-+ sa[i].map = maps + i;
-+
-+ sa[i].vbase = ioremap(sa[i].base, sa[i].size);
-+ if (!sa[i].vbase) {
- ret = -ENOMEM;
-- if (!sa1100_map.map_priv_1)
-- goto out_err;
-+ break;
- }
-
-+ sa[i].map->virt = (unsigned long)sa[i].vbase;
-+ sa[i].map->phys = sa[i].base;
-+ sa[i].map->set_vpp = sa[i].set_vpp;
-+ sa[i].map->buswidth = sa[i].width;
-+ sa[i].map->size = sa[i].size;
-+
-+ simple_map_init(sa[i].map);
-+
- /*
- * Now let's probe for the actual flash. Do it here since
- * specific machine settings might have been set above.
- */
-- printk(KERN_NOTICE "SA1100 flash: probing %d-bit flash bus\n", sa1100_map.buswidth*8);
-- mymtd = do_map_probe("cfi_probe", &sa1100_map);
-+ sa[i].mtd = do_map_probe("cfi_probe", sa[i].map);
-+ if (sa[i].mtd == NULL) {
- ret = -ENXIO;
-- if (!mymtd)
-- goto out_err;
-- mymtd->module = THIS_MODULE;
-+ break;
-+ }
-+ sa[i].mtd->owner = THIS_MODULE;
-+ subdev[i] = sa[i].mtd;
-+
-+ printk(KERN_INFO "SA1100 flash: CFI device at 0x%08lx, %dMiB, "
-+ "%d-bit\n", sa[i].base, sa[i].mtd->size >> 20,
-+ sa[i].width * 8);
-+ found += 1;
-+ }
-
- /*
-- * Dynamic partition selection stuff (might override the static ones)
-+ * ENXIO is special. It means we didn't find a chip when
-+ * we probed. We need to tear down the mapping, free the
-+ * resource and mark it as such.
- */
--#ifdef CONFIG_MTD_REDBOOT_PARTS
-- if (parsed_nr_parts == 0) {
-- int ret = parse_redboot_partitions(mymtd, &parsed_parts);
-+ if (ret == -ENXIO) {
-+ iounmap(sa[i].vbase);
-+ sa[i].vbase = NULL;
-+ release_resource(sa[i].res);
-+ sa[i].res = NULL;
-+ }
-
-- if (ret > 0) {
-- part_type = "RedBoot";
-- parsed_nr_parts = ret;
-+ /*
-+ * If we found one device, don't bother with concat support.
-+ * If we found multiple devices, use concat if we have it
-+ * available, otherwise fail.
-+ */
-+ if (ret == 0 || ret == -ENXIO) {
-+ if (found == 1) {
-+ *rmtd = subdev[0];
-+ ret = 0;
-+ } else if (found > 1) {
-+ /*
-+ * We detected multiple devices. Concatenate
-+ * them together.
-+ */
-+#ifdef CONFIG_MTD_CONCAT
-+ *rmtd = mtd_concat_create(subdev, found,
-+ "sa1100 flash");
-+ if (*rmtd == NULL)
-+ ret = -ENXIO;
-+#else
-+ printk(KERN_ERR "SA1100 flash: multiple devices "
-+ "found but MTD concat support disabled.\n");
-+ ret = -ENXIO;
-+#endif
- }
- }
-+
-+ /*
-+ * If we failed, clean up.
-+ */
-+ if (ret) {
-+ do {
-+ if (sa[i].mtd)
-+ map_destroy(sa[i].mtd);
-+ if (sa[i].vbase)
-+ iounmap(sa[i].vbase);
-+ if (sa[i].res)
-+ release_resource(sa[i].res);
-+ } while (i--);
-+
-+ kfree(maps);
-+ }
-+
-+ return ret;
-+}
-+
-+static void __exit sa1100_destroy_mtd(struct sa_info *sa, struct mtd_info *mtd)
-+{
-+ int i;
-+
-+ del_mtd_partitions(mtd);
-+
-+#ifdef CONFIG_MTD_CONCAT
-+ if (mtd != sa[0].mtd)
-+ mtd_concat_destroy(mtd);
- #endif
--#ifdef CONFIG_MTD_CMDLINE_PARTS
-- if (parsed_nr_parts == 0) {
-- int ret = parse_cmdline_partitions(mymtd, &parsed_parts, "sa1100");
-- if (ret > 0) {
-- part_type = "Command Line";
-- parsed_nr_parts = ret;
-+
-+ for (i = NR_SUBMTD; i >= 0; i--) {
-+ if (sa[i].mtd)
-+ map_destroy(sa[i].mtd);
-+ if (sa[i].vbase)
-+ iounmap(sa[i].vbase);
-+ if (sa[i].res)
-+ release_resource(sa[i].res);
- }
-+ kfree(sa[0].map);
-+}
-+
-+/*
-+ * A Thought: can we automatically detect the flash?
-+ * - Check to see if the region is busy (yes -> failure)
-+ * - Is the MSC setup for flash (no -> failure)
-+ * - Probe for flash
-+ */
-+
-+static struct map_info sa1100_probe_map __initdata = {
-+ .name = "SA1100-flash",
-+};
-+
-+static void __init sa1100_probe_one_cs(unsigned int msc, unsigned long phys)
-+{
-+ struct mtd_info *mtd;
-+
-+ printk(KERN_INFO "* Probing 0x%08lx: MSC = 0x%04x %d bit ",
-+ phys, msc & 0xffff, msc & MSC_RBW ? 16 : 32);
-+
-+ if (check_mem_region(phys, 0x08000000)) {
-+ printk("busy\n");
-+ return;
- }
--#endif
-
-- if (parsed_nr_parts > 0) {
-- parts = parsed_parts;
-- nb_parts = parsed_nr_parts;
-+ if ((msc & 3) == 1) {
-+ printk("wrong type\n");
-+ return;
- }
-
-- if (nb_parts == 0) {
-- printk(KERN_NOTICE "SA1100 flash: no partition info available, registering whole flash at once\n");
-- add_mtd_device(mymtd);
-- } else {
-- printk(KERN_NOTICE "Using %s partition definition\n", part_type);
-- add_mtd_partitions(mymtd, parts, nb_parts);
-+ sa1100_probe_map.buswidth = msc & MSC_RBW ? 2 : 4;
-+ sa1100_probe_map.size = SZ_1M;
-+ sa1100_probe_map.phys = phys;
-+ sa1100_probe_map.virt = (unsigned long)ioremap(phys, SZ_1M);
-+ if (sa1100_probe_map.virt == 0)
-+ goto fail;
-+ simple_map_init(&sa1100_probe_map);
-+
-+ /* Shame cfi_probe blurts out kernel messages... */
-+ mtd = do_map_probe("cfi_probe", &sa1100_probe_map);
-+ if (mtd)
-+ map_destroy(mtd);
-+ iounmap((void *)sa1100_probe_map.virt);
-+
-+ if (!mtd)
-+ goto fail;
-+
-+ printk("pass\n");
-+ return;
-+
-+ fail:
-+ printk("failed\n");
-+}
-+
-+static void __init sa1100_probe_flash(void)
-+{
-+ printk(KERN_INFO "-- SA11xx Flash probe. Please report results.\n");
-+ sa1100_probe_one_cs(MSC0, SA1100_CS0_PHYS);
-+ sa1100_probe_one_cs(MSC0 >> 16, SA1100_CS1_PHYS);
-+ sa1100_probe_one_cs(MSC1, SA1100_CS2_PHYS);
-+ sa1100_probe_one_cs(MSC1 >> 16, SA1100_CS3_PHYS);
-+ sa1100_probe_one_cs(MSC2, SA1100_CS4_PHYS);
-+ sa1100_probe_one_cs(MSC2 >> 16, SA1100_CS5_PHYS);
-+ printk(KERN_INFO "-- SA11xx Flash probe complete.\n");
-+}
-+
-+static int __init sa1100_locate_flash(void)
-+{
-+ int i, nr = -ENODEV;
-+
-+ sa1100_probe_flash();
-+
-+ if (machine_is_adsbitsy()) {
-+ info[0].base = SA1100_CS1_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_assabet()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ info[1].base = SA1100_CS1_PHYS; /* neponset */
-+ info[1].size = SZ_32M;
-+ nr = 2;
-+ }
-+ if (machine_is_badge4()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_64M;
-+ nr = 1;
-+ }
-+ if (machine_is_cerf()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_consus()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_flexanet()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_freebird()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_frodo()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_graphicsclient()) {
-+ info[0].base = SA1100_CS1_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
- }
-- return 0;
-+ if (machine_is_graphicsmaster()) {
-+ info[0].base = SA1100_CS1_PHYS;
-+ info[0].size = SZ_16M;
-+ nr = 1;
-+ }
-+ if (machine_is_h3xxx()) {
-+ info[0].set_vpp = h3xxx_set_vpp;
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_huw_webpanel()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_16M;
-+ nr = 1;
-+ }
-+ if (machine_is_itsy()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_jornada720()) {
-+ info[0].set_vpp = jornada720_set_vpp;
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_nanoengine()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[1].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_pangolin()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_64M;
-+ nr = 1;
-+ }
-+ if (machine_is_pfs168()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_pleb()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_4M;
-+ info[1].base = SA1100_CS1_PHYS;
-+ info[1].size = SZ_4M;
-+ nr = 2;
-+ }
-+ if (machine_is_pt_system3()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_16M;
-+ nr = 1;
-+ }
-+ if (machine_is_shannon()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_4M;
-+ nr = 1;
-+ }
-+ if (machine_is_sherman()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_simpad()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_16M;
-+ info[1].base = SA1100_CS1_PHYS;
-+ info[1].size = SZ_16M;
-+ nr = 2;
-+ }
-+ if (machine_is_stork()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_trizeps()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_16M;
-+ nr = 1;
-+ }
-+ if (machine_is_victor()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_2M;
-+ nr = 1;
-+ }
-+ if (machine_is_yopy()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_64M;
-+ info[1].base = SA1100_CS1_PHYS;
-+ info[1].size = SZ_64M;
-+ nr = 2;
-+ }
-+
-+ if (nr < 0)
-+ return nr;
-
-- out_err:
-- if (sa1100_map.map_priv_2 != -1) {
-- iounmap((void *)sa1100_map.map_priv_1);
-- release_mem_region(sa1100_map.map_priv_2, sa1100_map.size);
-+ /*
-+ * Retrieve the buswidth from the MSC registers.
-+ * We currently only implement CS0 and CS1 here.
-+ */
-+ for (i = 0; i < nr; i++) {
-+ switch (info[i].base) {
-+ default:
-+ printk(KERN_WARNING "SA1100 flash: unknown base address "
-+ "0x%08lx, assuming CS0\n", info[i].base);
-+ case SA1100_CS0_PHYS:
-+ info[i].width = (MSC0 & MSC_RBW) ? 2 : 4;
-+ break;
-+
-+ case SA1100_CS1_PHYS:
-+ info[i].width = ((MSC0 >> 16) & MSC_RBW) ? 2 : 4;
-+ break;
- }
-- return ret;
-+ }
-+
-+ return nr;
- }
-
--static void __exit sa1100_mtd_cleanup(void)
-+static struct mtd_partition *parsed_parts;
-+const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
-+
-+static void __init sa1100_locate_partitions(struct mtd_info *mtd)
- {
-- if (mymtd) {
-- del_mtd_partitions(mymtd);
-- map_destroy(mymtd);
-- if (parsed_parts)
-- kfree(parsed_parts);
-+ const char *part_type = NULL;
-+ int nr_parts = 0;
-+
-+ do {
-+ /*
-+ * Partition selection stuff.
-+ */
-+#ifdef CONFIG_MTD_PARTITIONS
-+ nr_parts = parse_mtd_partitions(mtd, part_probes, &parsed_parts, 0);
-+ if (nr_parts > 0) {
-+ part_type = "dynamic";
-+ break;
- }
-- if (sa1100_map.map_priv_2 != -1) {
-- iounmap((void *)sa1100_map.map_priv_1);
-- release_mem_region(sa1100_map.map_priv_2, sa1100_map.size);
-+#endif
-+#ifdef CONFIG_MTD_SA1100_STATICMAP
-+ nr_parts = sa1100_static_partitions(&parsed_parts);
-+ if (nr_parts > 0) {
-+ part_type = "static";
-+ break;
- }
-+#endif
-+ } while (0);
-+
-+ if (nr_parts == 0) {
-+ printk(KERN_NOTICE "SA1100 flash: no partition info "
-+ "available, registering whole flash\n");
-+ add_mtd_device(mtd);
-+ } else {
-+ printk(KERN_NOTICE "SA1100 flash: using %s partition "
-+ "definition\n", part_type);
-+ add_mtd_partitions(mtd, parsed_parts, nr_parts);
-+ }
-+
-+ /* Always succeeds. */
-+}
-+
-+static void __exit sa1100_destroy_partitions(void)
-+{
-+ if (parsed_parts)
-+ kfree(parsed_parts);
-+}
-+
-+static struct mtd_info *mymtd;
-+
-+static int __init sa1100_mtd_init(void)
-+{
-+ int ret;
-+ int nr;
-+
-+ nr = sa1100_locate_flash();
-+ if (nr < 0)
-+ return nr;
-+
-+ ret = sa1100_setup_mtd(info, nr, &mymtd);
-+ if (ret == 0)
-+ sa1100_locate_partitions(mymtd);
-+
-+ return ret;
-+}
-+
-+static void __exit sa1100_mtd_cleanup(void)
-+{
-+ sa1100_destroy_mtd(info, mymtd);
-+ sa1100_destroy_partitions();
- }
-
- module_init(sa1100_mtd_init);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/sbc8240.c linux/drivers/mtd/maps/sbc8240.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/sbc8240.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/sbc8240.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,417 @@
-+/*
-+ * Handle mapping of the flash memory access routines on the SBC8240 board.
-+ *
-+ * Carolyn Smith, Tektronix, Inc.
-+ *
-+ * This code is GPLed
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+/*
-+ * The SBC8240 has 2 flash banks.
-+ * Bank 0 is a 512 KiB AMD AM29F040B; 8 x 64 KiB sectors.
-+ * It contains the U-Boot code (7 sectors) and the environment (1 sector).
-+ * Bank 1 is 4 x 1 MiB AMD AM29LV800BT; 15 x 64 KiB sectors, 1 x 32 KiB sector,
-+ * 2 x 8 KiB sectors, 1 x 16 KiB sectors.
-+ * Both parts are JEDEC compatible.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <asm/io.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/cfi.h>
-+
-+#ifdef CONFIG_MTD_PARTITIONS
-+#include <linux/mtd/partitions.h>
-+#endif
-+
-+#define DEBUG
-+
-+#ifdef DEBUG
-+# define debugk(fmt,args...) printk(fmt ,##args)
-+#else
-+# define debugk(fmt,args...)
-+#endif
-+
-+
-+#define WINDOW_ADDR0 0xFFF00000 /* 512 KiB */
-+#define WINDOW_SIZE0 0x00080000
-+#define BUSWIDTH0 1
-+
-+#define WINDOW_ADDR1 0xFF000000 /* 4 MiB */
-+#define WINDOW_SIZE1 0x00400000
-+#define BUSWIDTH1 8
-+
-+#define MSG_PREFIX "sbc8240:" /* prefix for our printk()'s */
-+#define MTDID "sbc8240-%d" /* for mtdparts= partitioning */
-+
-+
-+static __u8 sbc8240_read8 (struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readb(map->map_priv_1 + ofs);
-+}
-+
-+static __u16 sbc8240_read16 (struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readw(map->map_priv_1 + ofs);
-+}
-+
-+static __u32 sbc8240_read32 (struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readl(map->map_priv_1 + ofs);
-+}
-+
-+unsigned long long result64;
-+
-+static __u64 sbc8240_read64 (struct map_info *map, unsigned long ofs)
-+{
-+ unsigned long flags, msr, saved_msr;
-+ volatile long saved_fr[2];
-+ volatile unsigned long long result;
-+ volatile unsigned long *p;
-+
-+ save_flags(flags);
-+ cli();
-+
-+ /* turn off floating point unavailable exceptions */
-+
-+ __asm__ __volatile__ (
-+ "mfmsr %0"
-+ : "=r" (msr) :);
-+
-+ saved_msr = msr;
-+ msr |= MSR_FP;
-+ msr &= ~(MSR_FE0 | MSR_FE1);
-+
-+ __asm__ __volatile__ (
-+ "mtmsr %0\n"
-+ "isync\n"
-+ : : "r" (msr));
-+
-+ /* read the data via a floating point register */
-+
-+ ofs = map->map_priv_1 + ofs;
-+ p = (unsigned long *) &result64;
-+
-+ __asm__ __volatile__ (
-+ "lfd 1,0(%1)\n"
-+ "stfd 1,0(%0)\n"
-+ : : "r" (p), "r" (ofs)
-+ );
-+
-+ /* restore state */
-+
-+ __asm__ __volatile__ (
-+ "mtmsr %0\n"
-+ "isync\n"
-+ : : "r" (saved_msr));
-+
-+ restore_flags(flags);
-+
-+ p = (unsigned long *) &result64;
-+ debugk("sbc8240_read64 ofs 0x%x result 0x%08x%08x\n", ofs, *p, *(p+1));
-+
-+ return result64;
-+}
-+
-+static void sbc8240_copy_from (struct map_info *map,
-+ void *to, unsigned long from, ssize_t len)
-+{
-+ memcpy_fromio (to, (void *) (map->map_priv_1 + from), len);
-+}
-+
-+static void sbc8240_write8 (struct map_info *map, __u8 d, unsigned long adr)
-+{
-+ __raw_writeb(d, map->map_priv_1 + adr);
-+ mb();
-+}
-+
-+static void sbc8240_write16 (struct map_info *map, __u16 d,
-+ unsigned long adr)
-+{
-+ __raw_writew(d, map->map_priv_1 + adr);
-+ mb();
-+}
-+
-+static void sbc8240_write32 (struct map_info *map, __u32 d,
-+ unsigned long adr)
-+{
-+ __raw_writel(d, map->map_priv_1 + adr);
-+ mb();
-+}
-+
-+static void sbc8240_write64 (struct map_info *map, __u64 data,
-+ unsigned long adr)
-+{
-+ unsigned long long tmp;
-+ unsigned long flags, msr, saved_msr, *p;
-+ volatile long saved_fr[2];
-+
-+ save_flags(flags);
-+ cli();
-+
-+ /* turn off floating point unavailable exceptions */
-+
-+ __asm__ __volatile__ (
-+ "mfmsr %0"
-+ : "=r" (msr) :);
-+
-+ saved_msr = msr;
-+ msr |= MSR_FP;
-+ msr &= ~(MSR_FE0 | MSR_FE1);
-+
-+ __asm__ __volatile__ (
-+ "mtmsr %0\n"
-+ "isync\n"
-+ : : "r" (msr));
-+
-+
-+ /* write the data via a floating point register */
-+
-+ tmp = data;
-+ p = (unsigned long *) &tmp;
-+ adr = map->map_priv_1 + adr;
-+ debugk("sbc8240_write64 adr 0x%x data 0x%08x%08x\n", adr, *p, *(p+1));
-+
-+ __asm__ __volatile__ (
-+ "stfd 1,0(%2)\n"
-+ "lfd 1,0(%0)\n"
-+ "stfd 1,0(%1)\n"
-+ "lfd 1,0(%2)\n"
-+ : : "r" (p), "r" (adr), "b" (saved_fr)
-+ );
-+
-+ /* restore state */
-+
-+ __asm__ __volatile__ (
-+ "mtmsr %0\n"
-+ "isync\n"
-+ : : "r" (saved_msr));
-+
-+ restore_flags(flags);
-+}
-+
-+static void sbc8240_copy_to (struct map_info *map,
-+ unsigned long to, const void *from, ssize_t len)
-+{
-+ memcpy_toio ((void *) (map->map_priv_1 + to), from, len);
-+}
-+
-+static struct map_info sbc8240_map[2] = {
-+ {
-+ .name = "sbc8240 Flash Bank #0",
-+ .size = WINDOW_SIZE0,
-+ .buswidth = BUSWIDTH0,
-+ .read8 = sbc8240_read8,
-+ .read16 = sbc8240_read16,
-+ .read32 = sbc8240_read32,
-+ .read64 = sbc8240_read64,
-+ .copy_from = sbc8240_copy_from,
-+ .write8 = sbc8240_write8,
-+ .write16 = sbc8240_write16,
-+ .write32 = sbc8240_write32,
-+ .write64 = sbc8240_write64,
-+ .copy_to = sbc8240_copy_to
-+ },
-+ {
-+ .name = "sbc8240 Flash Bank #1",
-+ .size = WINDOW_SIZE1,
-+ .buswidth = BUSWIDTH1,
-+ .read8 = sbc8240_read8,
-+ .read16 = sbc8240_read16,
-+ .read32 = sbc8240_read32,
-+ .read64 = sbc8240_read64,
-+ .copy_from = sbc8240_copy_from,
-+ .write8 = sbc8240_write8,
-+ .write16 = sbc8240_write16,
-+ .write32 = sbc8240_write32,
-+ .write64 = sbc8240_write64,
-+ .copy_to = sbc8240_copy_to
-+ }
-+};
-+
-+#define NUM_FLASH_BANKS (sizeof(sbc8240_map) / sizeof(struct map_info))
-+
-+/*
-+ * The following defines the partition layout of SBC8240 boards.
-+ *
-+ * See include/linux/mtd/partitions.h for definition of the
-+ * mtd_partition structure.
-+ *
-+ * The *_max_flash_size is the maximum possible mapped flash size
-+ * which is not necessarily the actual flash size. It must correspond
-+ * to the value specified in the mapping definition defined by the
-+ * "struct map_desc *_io_desc" for the corresponding machine.
-+ */
-+
-+#ifdef CONFIG_MTD_PARTITIONS
-+
-+static struct mtd_partition sbc8240_uboot_partitions [] = {
-+ /* Bank 0 */
-+ {
-+ .name = "U-boot", /* U-Boot Firmware */
-+ .offset = 0,
-+ .size = 0x00070000, /* 7 x 64 KiB sectors */
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ },
-+ {
-+ .name = "environment", /* U-Boot environment */
-+ .offset = 0x00070000,
-+ .size = 0x00010000, /* 1 x 64 KiB sector */
-+ },
-+};
-+
-+static struct mtd_partition sbc8240_fs_partitions [] = {
-+ {
-+ .name = "jffs", /* JFFS filesystem */
-+ .offset = 0,
-+ .size = 0x003C0000, /* 4 * 15 * 64KiB */
-+ },
-+ {
-+ .name = "tmp32",
-+ .offset = 0x003C0000,
-+ .size = 0x00020000, /* 4 * 32KiB */
-+ },
-+ {
-+ .name = "tmp8a",
-+ .offset = 0x003E0000,
-+ .size = 0x00008000, /* 4 * 8KiB */
-+ },
-+ {
-+ .name = "tmp8b",
-+ .offset = 0x003E8000,
-+ .size = 0x00008000, /* 4 * 8KiB */
-+ },
-+ {
-+ .name = "tmp16",
-+ .offset = 0x003F0000,
-+ .size = 0x00010000, /* 4 * 16KiB */
-+ }
-+};
-+
-+#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
-+
-+/* trivial struct to describe partition information */
-+struct mtd_part_def
-+{
-+ int nums;
-+ unsigned char *type;
-+ struct mtd_partition* mtd_part;
-+};
-+
-+static struct mtd_info *sbc8240_mtd[NUM_FLASH_BANKS];
-+static struct mtd_part_def sbc8240_part_banks[NUM_FLASH_BANKS];
-+
-+
-+#endif /* CONFIG_MTD_PARTITIONS */
-+
-+
-+int __init init_sbc8240_mtd (void)
-+{
-+ static struct _cjs {
-+ u_long addr;
-+ u_long size;
-+ } pt[NUM_FLASH_BANKS] = {
-+ {
-+ .addr = WINDOW_ADDR0,
-+ .size = WINDOW_SIZE0
-+ },
-+ {
-+ .addr = WINDOW_ADDR1,
-+ .size = WINDOW_SIZE1
-+ },
-+ };
-+
-+ int devicesfound = 0;
-+ int i;
-+
-+ for (i = 0; i < NUM_FLASH_BANKS; i++) {
-+ printk (KERN_NOTICE MSG_PREFIX
-+ "Probing 0x%08lx at 0x%08lx\n", pt[i].size, pt[i].addr);
-+
-+ sbc8240_map[i].map_priv_1 =
-+ (unsigned long) ioremap (pt[i].addr, pt[i].size);
-+ if (!sbc8240_map[i].map_priv_1) {
-+ printk (MSG_PREFIX "failed to ioremap\n");
-+ return -EIO;
-+ }
-+
-+ sbc8240_mtd[i] = do_map_probe("jedec_probe", &sbc8240_map[i]);
-+
-+ if (sbc8240_mtd[i]) {
-+ sbc8240_mtd[i]->module = THIS_MODULE;
-+ devicesfound++;
-+ }
-+ }
-+
-+ if (!devicesfound) {
-+ printk(KERN_NOTICE MSG_PREFIX
-+ "No suppported flash chips found!\n");
-+ return -ENXIO;
-+ }
-+
-+#ifdef CONFIG_MTD_PARTITIONS
-+ sbc8240_part_banks[0].mtd_part = sbc8240_uboot_partitions;
-+ sbc8240_part_banks[0].type = "static image";
-+ sbc8240_part_banks[0].nums = NB_OF(sbc8240_uboot_partitions);
-+ sbc8240_part_banks[1].mtd_part = sbc8240_fs_partitions;
-+ sbc8240_part_banks[1].type = "static file system";
-+ sbc8240_part_banks[1].nums = NB_OF(sbc8240_fs_partitions);
-+
-+ for (i = 0; i < NUM_FLASH_BANKS; i++) {
-+
-+ if (!sbc8240_mtd[i]) continue;
-+ if (sbc8240_part_banks[i].nums == 0) {
-+ printk (KERN_NOTICE MSG_PREFIX
-+ "No partition info available, registering whole device\n");
-+ add_mtd_device(sbc8240_mtd[i]);
-+ } else {
-+ printk (KERN_NOTICE MSG_PREFIX
-+ "Using %s partition definition\n", sbc8240_part_banks[i].mtd_part->name);
-+ add_mtd_partitions (sbc8240_mtd[i],
-+ sbc8240_part_banks[i].mtd_part,
-+ sbc8240_part_banks[i].nums);
-+ }
-+ }
-+#else
-+ printk(KERN_NOTICE MSG_PREFIX
-+ "Registering %d flash banks at once\n", devicesfound);
-+
-+ for (i = 0; i < devicesfound; i++) {
-+ add_mtd_device(sbc8240_mtd[i]);
-+ }
-+#endif /* CONFIG_MTD_PARTITIONS */
-+
-+ return devicesfound == 0 ? -ENXIO : 0;
-+}
-+
-+static void __exit cleanup_sbc8240_mtd (void)
-+{
-+ int i;
-+
-+ for (i = 0; i < NUM_FLASH_BANKS; i++) {
-+ if (sbc8240_mtd[i]) {
-+ del_mtd_device (sbc8240_mtd[i]);
-+ map_destroy (sbc8240_mtd[i]);
-+ }
-+ if (sbc8240_map[i].map_priv_1) {
-+ iounmap ((void *) sbc8240_map[i].map_priv_1);
-+ sbc8240_map[i].map_priv_1 = 0;
-+ }
-+ }
-+}
-+
-+module_init (init_sbc8240_mtd);
-+module_exit (cleanup_sbc8240_mtd);
-+
-+MODULE_LICENSE ("GPL");
-+MODULE_AUTHOR ("Carolyn Smith <carolyn.smith@tektronix.com>");
-+MODULE_DESCRIPTION ("MTD map driver for SBC8240 boards");
-+
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/sbc_gxx.c linux/drivers/mtd/maps/sbc_gxx.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/sbc_gxx.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/sbc_gxx.c 2004-11-17 18:17:59.132299784 +0100
-@@ -17,7 +17,7 @@
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-- $Id$
-+ $Id$
-
- The SBC-MediaGX / SBC-GXx has up to 16 MiB of
- Intel StrataFlash (28F320/28F640) in x8 mode.
-@@ -91,14 +91,14 @@
- * single flash device into. If the size if zero we use up to the end of the
- * device. */
- static struct mtd_partition partition_info[]={
-- { name: "SBC-GXx flash boot partition",
-- offset: 0,
-- size: BOOT_PARTITION_SIZE_KiB*1024 },
-- { name: "SBC-GXx flash data partition",
-- offset: BOOT_PARTITION_SIZE_KiB*1024,
-- size: (DATA_PARTITION_SIZE_KiB)*1024 },
-- { name: "SBC-GXx flash application partition",
-- offset: (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 }
-+ { .name = "SBC-GXx flash boot partition",
-+ .offset = 0,
-+ .size = BOOT_PARTITION_SIZE_KiB*1024 },
-+ { .name = "SBC-GXx flash data partition",
-+ .offset = BOOT_PARTITION_SIZE_KiB*1024,
-+ .size = (DATA_PARTITION_SIZE_KiB)*1024 },
-+ { .name = "SBC-GXx flash application partition",
-+ .offset = (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 }
- };
-
- #define NUM_PARTITIONS 3
-@@ -203,19 +203,20 @@
- }
-
- static struct map_info sbc_gxx_map = {
-- name: "SBC-GXx flash",
-- size: MAX_SIZE_KiB*1024, /* this must be set to a maximum possible amount
-+ .name = "SBC-GXx flash",
-+ .phys = NO_XIP,
-+ .size = MAX_SIZE_KiB*1024, /* this must be set to a maximum possible amount
- of flash so the cfi probe routines find all
- the chips */
-- buswidth: 1,
-- read8: sbc_gxx_read8,
-- read16: sbc_gxx_read16,
-- read32: sbc_gxx_read32,
-- copy_from: sbc_gxx_copy_from,
-- write8: sbc_gxx_write8,
-- write16: sbc_gxx_write16,
-- write32: sbc_gxx_write32,
-- copy_to: sbc_gxx_copy_to
-+ .buswidth = 1,
-+ .read8 = sbc_gxx_read8,
-+ .read16 = sbc_gxx_read16,
-+ .read32 = sbc_gxx_read32,
-+ .copy_from = sbc_gxx_copy_from,
-+ .write8 = sbc_gxx_write8,
-+ .write16 = sbc_gxx_write16,
-+ .write32 = sbc_gxx_write32,
-+ .copy_to = sbc_gxx_copy_to
- };
-
- /* MTD device for all of the flash. */
-@@ -234,12 +235,6 @@
-
- int __init init_sbc_gxx(void)
- {
-- if (check_region(PAGE_IO,PAGE_IO_SIZE) != 0) {
-- printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
-- sbc_gxx_map.name,
-- PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 );
-- return -EAGAIN;
-- }
- iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH);
- if (!iomapadr) {
- printk( KERN_ERR"%s: failed to ioremap memory region\n",
-@@ -247,7 +242,14 @@
- return -EIO;
- }
-
-- request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash" );
-+ if (!request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash")) {
-+ printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
-+ sbc_gxx_map.name,
-+ PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 );
-+ iounmap((void *)iomapadr);
-+ return -EAGAIN;
-+ }
-+
-
- printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
- sbc_gxx_map.name,
-@@ -261,7 +263,7 @@
- return -ENXIO;
- }
-
-- all_mtd->module=THIS_MODULE;
-+ all_mtd->owner = THIS_MODULE;
-
- /* Create MTD devices for each partition. */
- add_mtd_partitions(all_mtd, partition_info, NUM_PARTITIONS );
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/sc520cdp.c linux/drivers/mtd/maps/sc520cdp.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/sc520cdp.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/sc520cdp.c 2004-11-17 18:17:59.133299632 +0100
-@@ -16,7 +16,7 @@
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
-- * $Id$
-+ * $Id$
- *
- *
- * The SC520CDP is an evaluation board for the Elan SC520 processor available
-@@ -29,6 +29,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -84,88 +85,25 @@
- #define WINDOW_SIZE_1 0x00800000
- #define WINDOW_SIZE_2 0x00080000
-
--static __u8 sc520cdp_read8(struct map_info *map, unsigned long ofs)
--{
-- return readb(map->map_priv_1 + ofs);
--}
--
--static __u16 sc520cdp_read16(struct map_info *map, unsigned long ofs)
--{
-- return readw(map->map_priv_1 + ofs);
--}
--
--static __u32 sc520cdp_read32(struct map_info *map, unsigned long ofs)
--{
-- return readl(map->map_priv_1 + ofs);
--}
--
--static void sc520cdp_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
--}
--
--static void sc520cdp_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- writeb(d, map->map_priv_1 + adr);
--}
--
--static void sc520cdp_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- writew(d, map->map_priv_1 + adr);
--}
--
--static void sc520cdp_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- writel(d, map->map_priv_1 + adr);
--}
--
--static void sc520cdp_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio((void *)(map->map_priv_1 + to), from, len);
--}
-
- static struct map_info sc520cdp_map[] = {
- {
-- name: "SC520CDP Flash Bank #0",
-- size: WINDOW_SIZE_0,
-- buswidth: 4,
-- read8: sc520cdp_read8,
-- read16: sc520cdp_read16,
-- read32: sc520cdp_read32,
-- copy_from: sc520cdp_copy_from,
-- write8: sc520cdp_write8,
-- write16: sc520cdp_write16,
-- write32: sc520cdp_write32,
-- copy_to: sc520cdp_copy_to,
-- map_priv_2: WINDOW_ADDR_0
-+ .name = "SC520CDP Flash Bank #0",
-+ .size = WINDOW_SIZE_0,
-+ .buswidth = 4,
-+ .phys = WINDOW_ADDR_0
- },
- {
-- name: "SC520CDP Flash Bank #1",
-- size: WINDOW_SIZE_1,
-- buswidth: 4,
-- read8: sc520cdp_read8,
-- read16: sc520cdp_read16,
-- read32: sc520cdp_read32,
-- copy_from: sc520cdp_copy_from,
-- write8: sc520cdp_write8,
-- write16: sc520cdp_write16,
-- write32: sc520cdp_write32,
-- copy_to: sc520cdp_copy_to,
-- map_priv_2: WINDOW_ADDR_1
-+ .name = "SC520CDP Flash Bank #1",
-+ .size = WINDOW_SIZE_1,
-+ .buswidth = 4,
-+ .phys = WINDOW_ADDR_1
- },
- {
-- name: "SC520CDP DIL Flash",
-- size: WINDOW_SIZE_2,
-- buswidth: 1,
-- read8: sc520cdp_read8,
-- read16: sc520cdp_read16,
-- read32: sc520cdp_read32,
-- copy_from: sc520cdp_copy_from,
-- write8: sc520cdp_write8,
-- write16: sc520cdp_write16,
-- write32: sc520cdp_write32,
-- copy_to: sc520cdp_copy_to,
-- map_priv_2: WINDOW_ADDR_2
-+ .name = "SC520CDP DIL Flash",
-+ .size = WINDOW_SIZE_2,
-+ .buswidth = 1,
-+ .phys = WINDOW_ADDR_2
- },
- };
-
-@@ -255,9 +193,9 @@
- /* map in SC520's MMCR area */
- mmcr = (unsigned long *)ioremap_nocache(SC520_MMCR_BASE, SC520_MMCR_EXTENT);
- if(!mmcr) { /* ioremap_nocache failed: skip the PAR reprogramming */
-- /* force map_priv_2 fields to BIOS defaults: */
-+ /* force physical address fields to BIOS defaults: */
- for(i = 0; i < NUM_FLASH_BANKS; i++)
-- sc520cdp_map[i].map_priv_2 = par_table[i].default_address;
-+ sc520cdp_map[i].phys = par_table[i].default_address;
- return;
- }
-
-@@ -282,7 +220,7 @@
- sc520cdp_map[i].name);
- printk(KERN_NOTICE "Trying default address 0x%lx\n",
- par_table[i].default_address);
-- sc520cdp_map[i].map_priv_2 = par_table[i].default_address;
-+ sc520cdp_map[i].phys = par_table[i].default_address;
- }
- }
- iounmap((void *)mmcr);
-@@ -300,13 +238,18 @@
- #endif
-
- for (i = 0; i < NUM_FLASH_BANKS; i++) {
-- printk(KERN_NOTICE "SC520 CDP flash device: %lx at %lx\n", sc520cdp_map[i].size, sc520cdp_map[i].map_priv_2);
-- sc520cdp_map[i].map_priv_1 = (unsigned long)ioremap_nocache(sc520cdp_map[i].map_priv_2, sc520cdp_map[i].size);
-+ printk(KERN_NOTICE "SC520 CDP flash device: 0x%lx at 0x%lx\n",
-+ sc520cdp_map[i].size, sc520cdp_map[i].phys);
-
-- if (!sc520cdp_map[i].map_priv_1) {
-+ sc520cdp_map[i].virt = (unsigned long)ioremap_nocache(sc520cdp_map[i].phys, sc520cdp_map[i].size);
-+
-+ if (!sc520cdp_map[i].virt) {
- printk("Failed to ioremap_nocache\n");
- return -EIO;
- }
-+
-+ simple_map_init(&sc520cdp_map[i]);
-+
- mymtd[i] = do_map_probe("cfi_probe", &sc520cdp_map[i]);
- if(!mymtd[i])
- mymtd[i] = do_map_probe("jedec_probe", &sc520cdp_map[i]);
-@@ -314,11 +257,11 @@
- mymtd[i] = do_map_probe("map_rom", &sc520cdp_map[i]);
-
- if (mymtd[i]) {
-- mymtd[i]->module = THIS_MODULE;
-+ mymtd[i]->owner = THIS_MODULE;
- ++devices_found;
- }
- else {
-- iounmap((void *)sc520cdp_map[i].map_priv_1);
-+ iounmap((void *)sc520cdp_map[i].virt);
- }
- }
- if(devices_found >= 2) {
-@@ -346,9 +289,9 @@
- for (i = 0; i < NUM_FLASH_BANKS; i++) {
- if (mymtd[i])
- map_destroy(mymtd[i]);
-- if (sc520cdp_map[i].map_priv_1) {
-- iounmap((void *)sc520cdp_map[i].map_priv_1);
-- sc520cdp_map[i].map_priv_1 = 0;
-+ if (sc520cdp_map[i].virt) {
-+ iounmap((void *)sc520cdp_map[i].virt);
-+ sc520cdp_map[i].virt = 0;
- }
- }
- }
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/scb2_flash.c linux/drivers/mtd/maps/scb2_flash.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/scb2_flash.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/scb2_flash.c 2004-11-17 18:17:59.135299328 +0100
-@@ -1,6 +1,6 @@
- /*
- * MTD map driver for BIOS Flash on Intel SCB2 boards
-- * $Id$
-+ * $Id$
- * Copyright (C) 2002 Sun Microsystems, Inc.
- * Tim Hockin <thockin@sun.com>
- *
-@@ -14,7 +14,7 @@
- * try to request it here, but if it fails, we carry on anyway.
- *
- * This is how the chip is attached, so said the schematic:
-- * * a 4 MiB (32 Mb) 16 bit chip
-+ * * a 4 MiB (32 Mib) 16 bit chip
- * * a 1 MiB memory region
- * * A20 and A21 pulled up
- * * D8-D15 ignored
-@@ -48,6 +48,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -60,65 +61,13 @@
- #define SCB2_ADDR 0xfff00000
- #define SCB2_WINDOW 0x00100000
-
--static __u8 scb2_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--static __u16 scb2_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--static __u32 scb2_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--static void scb2_copy_from(struct map_info *map, void *to,
-- unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--static void scb2_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void scb2_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void scb2_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void scb2_copy_to(struct map_info *map, unsigned long to,
-- const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
-
- static void *scb2_ioaddr;
- static struct mtd_info *scb2_mtd;
- struct map_info scb2_map = {
-- name: "SCB2 BIOS Flash",
-- size: 0,
-- buswidth: 1,
-- read8: scb2_read8,
-- read16: scb2_read16,
-- read32: scb2_read32,
-- copy_from: scb2_copy_from,
-- write8: scb2_write8,
-- write16: scb2_write16,
-- write32: scb2_write32,
-- copy_to: scb2_copy_to,
-+ .name = "SCB2 BIOS Flash",
-+ .size = 0,
-+ .buswidth = 1,
- };
- static int region_fail;
-
-@@ -137,6 +86,8 @@
- return -1;
- }
-
-+ /* I wasn't here. I didn't see. dwmw2. */
-+
- /* the chip is sometimes bigger than the map - what a waste */
- mtd->size = map->size;
-
-@@ -211,9 +162,12 @@
- return -ENOMEM;
- }
-
-- scb2_map.map_priv_1 = (unsigned long)scb2_ioaddr;
-+ scb2_map.phys = SCB2_ADDR;
-+ scb2_map.virt = (unsigned long)scb2_ioaddr;
- scb2_map.size = SCB2_WINDOW;
-
-+ simple_map_init(&scb2_map);
-+
- /* try to find a chip */
- scb2_mtd = do_map_probe("cfi_probe", &scb2_map);
-
-@@ -225,7 +179,7 @@
- return -ENODEV;
- }
-
-- scb2_mtd->module = THIS_MODULE;
-+ scb2_mtd->owner = THIS_MODULE;
- if (scb2_fixup_mtd(scb2_mtd) < 0) {
- del_mtd_device(scb2_mtd);
- map_destroy(scb2_mtd);
-@@ -235,7 +189,7 @@
- return -ENODEV;
- }
-
-- printk(KERN_NOTICE MODNAME ": chip size %x at offset %x\n",
-+ printk(KERN_NOTICE MODNAME ": chip size 0x%x at offset 0x%x\n",
- scb2_mtd->size, SCB2_WINDOW - scb2_mtd->size);
-
- add_mtd_device(scb2_mtd);
-@@ -266,19 +220,19 @@
-
- static struct pci_device_id scb2_flash_pci_ids[] __devinitdata = {
- {
-- vendor: PCI_VENDOR_ID_SERVERWORKS,
-- device: PCI_DEVICE_ID_SERVERWORKS_CSB5,
-- subvendor: PCI_ANY_ID,
-- subdevice: PCI_ANY_ID
-+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
-+ .device = PCI_DEVICE_ID_SERVERWORKS_CSB5,
-+ .subvendor = PCI_ANY_ID,
-+ .subdevice = PCI_ANY_ID
- },
- { 0, }
- };
-
- static struct pci_driver scb2_flash_driver = {
-- name: "Intel SCB2 BIOS Flash",
-- id_table: scb2_flash_pci_ids,
-- probe: scb2_flash_probe,
-- remove: __devexit_p(scb2_flash_remove),
-+ .name = "Intel SCB2 BIOS Flash",
-+ .id_table = scb2_flash_pci_ids,
-+ .probe = scb2_flash_probe,
-+ .remove = __devexit_p(scb2_flash_remove),
- };
-
- static int __init
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/scx200_docflash.c linux/drivers/mtd/maps/scx200_docflash.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/scx200_docflash.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/scx200_docflash.c 2004-11-17 18:17:59.136299176 +0100
-@@ -2,7 +2,7 @@
-
- Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
-
-- $Id$
-+ $Id$
-
- National Semiconductor SCx200 flash mapped with DOCCS
- */
-@@ -11,6 +11,7 @@
- #include <linux/config.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -75,46 +76,9 @@
- #define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0]))
- #endif
-
--static __u8 scx200_docflash_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--static __u16 scx200_docflash_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--static void scx200_docflash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--static void scx200_docflash_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void scx200_docflash_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void scx200_docflash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
-
- static struct map_info scx200_docflash_map = {
- .name = "NatSemi SCx200 DOCCS Flash",
-- .read8 = scx200_docflash_read8,
-- .read16 = scx200_docflash_read16,
-- .copy_from = scx200_docflash_copy_from,
-- .write8 = scx200_docflash_write8,
-- .write16 = scx200_docflash_write16,
-- .copy_to = scx200_docflash_copy_to
- };
-
- int __init init_scx200_docflash(void)
-@@ -213,8 +177,11 @@
- else
- scx200_docflash_map.buswidth = 2;
-
-- scx200_docflash_map.map_priv_1 = (unsigned long)ioremap(docmem.start, scx200_docflash_map.size);
-- if (!scx200_docflash_map.map_priv_1) {
-+ simple_map_init(&scx200_docflash_map);
-+
-+ scx200_docflash_map.phys = docmem.start;
-+ scx200_docflash_map.virt = (unsigned long)ioremap(docmem.start, scx200_docflash_map.size);
-+ if (!scx200_docflash_map.virt) {
- printk(KERN_ERR NAME ": failed to ioremap the flash\n");
- release_resource(&docmem);
- return -EIO;
-@@ -223,7 +190,7 @@
- mymtd = do_map_probe(flashtype, &scx200_docflash_map);
- if (!mymtd) {
- printk(KERN_ERR NAME ": unable to detect flash\n");
-- iounmap((void *)scx200_docflash_map.map_priv_1);
-+ iounmap((void *)scx200_docflash_map.virt);
- release_resource(&docmem);
- return -ENXIO;
- }
-@@ -231,7 +198,7 @@
- if (size < mymtd->size)
- printk(KERN_WARNING NAME ": warning, flash mapping is smaller than flash size\n");
-
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
- #if PARTITION
- partition_info[3].offset = mymtd->size-partition_info[3].size;
-@@ -253,8 +220,8 @@
- #endif
- map_destroy(mymtd);
- }
-- if (scx200_docflash_map.map_priv_1) {
-- iounmap((void *)scx200_docflash_map.map_priv_1);
-+ if (scx200_docflash_map.virt) {
-+ iounmap((void *)scx200_docflash_map.virt);
- release_resource(&docmem);
- }
- }
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/solutionengine.c linux/drivers/mtd/maps/solutionengine.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/solutionengine.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/solutionengine.c 2004-11-17 18:17:59.137299024 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Flash and EPROM on Hitachi Solution Engine and similar boards.
- *
-@@ -11,6 +11,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -18,60 +19,39 @@
- #include <linux/config.h>
-
-
--extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
--
--__u32 soleng_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void soleng_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void soleng_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--
- static struct mtd_info *flash_mtd;
- static struct mtd_info *eprom_mtd;
-
- static struct mtd_partition *parsed_parts;
-
- struct map_info soleng_eprom_map = {
-- name: "Solution Engine EPROM",
-- size: 0x400000,
-- buswidth: 4,
-- copy_from: soleng_copy_from,
-+ .name = "Solution Engine EPROM",
-+ .size = 0x400000,
-+ .buswidth = 4,
- };
-
- struct map_info soleng_flash_map = {
-- name: "Solution Engine FLASH",
-- size: 0x400000,
-- buswidth: 4,
-- read32: soleng_read32,
-- copy_from: soleng_copy_from,
-- write32: soleng_write32,
-+ .name = "Solution Engine FLASH",
-+ .size = 0x400000,
-+ .buswidth = 4,
- };
-
-+static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-+
- #ifdef CONFIG_MTD_SUPERH_RESERVE
- static struct mtd_partition superh_se_partitions[] = {
- /* Reserved for boot code, read-only */
- {
-- name: "flash_boot",
-- offset: 0x00000000,
-- size: CONFIG_MTD_SUPERH_RESERVE,
-- mask_flags: MTD_WRITEABLE,
-+ .name = "flash_boot",
-+ .offset = 0x00000000,
-+ .size = CONFIG_MTD_SUPERH_RESERVE,
-+ .mask_flags = MTD_WRITEABLE,
- },
- /* All else is writable (e.g. JFFS) */
- {
-- name: "Flash FS",
-- offset: MTDPART_OFS_NXTBLK,
-- size: MTDPART_SIZ_FULL,
-+ .name = "Flash FS",
-+ .offset = MTDPART_OFS_NXTBLK,
-+ .size = MTDPART_SIZ_FULL,
- }
- };
- #endif /* CONFIG_MTD_SUPERH_RESERVE */
-@@ -81,16 +61,22 @@
- int nr_parts = 0;
-
- /* First probe at offset 0 */
-- soleng_flash_map.map_priv_1 = P2SEGADDR(0);
-- soleng_eprom_map.map_priv_1 = P1SEGADDR(0x01000000);
-+ soleng_flash_map.phys = 0;
-+ soleng_flash_map.virt = P2SEGADDR(0);
-+ soleng_eprom_map.phys = 0x01000000;
-+ soleng_eprom_map.virt = P1SEGADDR(0x01000000);
-+ simple_map_init(&soleng_eprom_map);
-+ simple_map_init(&soleng_flash_map);
-
- printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n");
- flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map);
- if (!flash_mtd) {
- /* Not there. Try swapping */
- printk(KERN_NOTICE "Probing for flash chips at 0x01000000:\n");
-- soleng_flash_map.map_priv_1 = P2SEGADDR(0x01000000);
-- soleng_eprom_map.map_priv_1 = P1SEGADDR(0);
-+ soleng_flash_map.phys = 0x01000000;
-+ soleng_flash_map.virt = P2SEGADDR(0x01000000);
-+ soleng_eprom_map.phys = 0;
-+ soleng_eprom_map.virt = P1SEGADDR(0);
- flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map);
- if (!flash_mtd) {
- /* Eep. */
-@@ -99,25 +85,20 @@
- }
- }
- printk(KERN_NOTICE "Solution Engine: Flash at 0x%08lx, EPROM at 0x%08lx\n",
-- soleng_flash_map.map_priv_1 & 0x1fffffff,
-- soleng_eprom_map.map_priv_1 & 0x1fffffff);
-- flash_mtd->module = THIS_MODULE;
-+ soleng_flash_map.phys & 0x1fffffff,
-+ soleng_eprom_map.phys & 0x1fffffff);
-+ flash_mtd->owner = THIS_MODULE;
-
- eprom_mtd = do_map_probe("map_rom", &soleng_eprom_map);
- if (eprom_mtd) {
-- eprom_mtd->module = THIS_MODULE;
-+ eprom_mtd->owner = THIS_MODULE;
- add_mtd_device(eprom_mtd);
- }
-
--#ifdef CONFIG_MTD_REDBOOT_PARTS
-- nr_parts = parse_redboot_partitions(flash_mtd, &parsed_parts);
-- if (nr_parts > 0)
-- printk(KERN_NOTICE "Found RedBoot partition table.\n");
-- else if (nr_parts < 0)
-- printk(KERN_NOTICE "Error looking for RedBoot partitions.\n");
--#endif /* CONFIG_MTD_REDBOOT_PARTS */
-+ nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_parts, 0);
-+
- #if CONFIG_MTD_SUPERH_RESERVE
-- if (nr_parts == 0) {
-+ if (nr_parts <= 0) {
- printk(KERN_NOTICE "Using configured partition at 0x%08x.\n",
- CONFIG_MTD_SUPERH_RESERVE);
- parsed_parts = superh_se_partitions;
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/sun_uflash.c linux/drivers/mtd/maps/sun_uflash.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/sun_uflash.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/sun_uflash.c 2004-11-17 18:17:59.139298720 +0100
-@@ -1,4 +1,4 @@
--/* $Id$
-+/* $Id$
- *
- * sun_uflash - Driver implementation for user-programmable flash
- * present on many Sun Microsystems SME boardsets.
-@@ -48,60 +48,11 @@
- struct list_head list;
- };
-
--__u8 uflash_read8(struct map_info *map, unsigned long ofs)
--{
-- return(__raw_readb(map->map_priv_1 + ofs));
--}
--
--__u16 uflash_read16(struct map_info *map, unsigned long ofs)
--{
-- return(__raw_readw(map->map_priv_1 + ofs));
--}
--
--__u32 uflash_read32(struct map_info *map, unsigned long ofs)
--{
-- return(__raw_readl(map->map_priv_1 + ofs));
--}
--
--void uflash_copy_from(struct map_info *map, void *to, unsigned long from,
-- ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void uflash_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
--}
--
--void uflash_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
--}
--
--void uflash_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
--}
--
--void uflash_copy_to(struct map_info *map, unsigned long to, const void *from,
-- ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
-
- struct map_info uflash_map_templ = {
-- name: "SUNW,???-????",
-- size: UFLASH_WINDOW_SIZE,
-- buswidth: UFLASH_BUSWIDTH,
-- read8: uflash_read8,
-- read16: uflash_read16,
-- read32: uflash_read32,
-- copy_from: uflash_copy_from,
-- write8: uflash_write8,
-- write16: uflash_write16,
-- write32: uflash_write32,
-- copy_to: uflash_copy_to
-+ .name = "SUNW,???-????",
-+ .size = UFLASH_WINDOW_SIZE,
-+ .buswidth = UFLASH_BUSWIDTH,
- };
-
- int uflash_devinit(struct linux_ebus_device* edev)
-@@ -145,20 +96,22 @@
- if(0 != pdev->name && 0 < strlen(pdev->name)) {
- pdev->map.name = pdev->name;
- }
--
-- pdev->map.map_priv_1 =
-+ pdev->phys = edev->resource[0].start;
-+ pdev->virt =
- (unsigned long)ioremap_nocache(edev->resource[0].start, pdev->map.size);
-- if(0 == pdev->map.map_priv_1) {
-+ if(0 == pdev->map.virt) {
- printk("%s: failed to map device\n", __FUNCTION__);
- kfree(pdev->name);
- kfree(pdev);
- return(-1);
- }
-
-+ simple_map_init(&pdev->map);
-+
- /* MTD registration */
- pdev->mtd = do_map_probe("cfi_probe", &pdev->map);
- if(0 == pdev->mtd) {
-- iounmap((void *)pdev->map.map_priv_1);
-+ iounmap((void *)pdev->map.virt);
- kfree(pdev->name);
- kfree(pdev);
- return(-ENXIO);
-@@ -166,7 +119,7 @@
-
- list_add(&pdev->list, &device_list);
-
-- pdev->mtd->module = THIS_MODULE;
-+ pdev->mtd->owner = THIS_MODULE;
-
- add_mtd_device(pdev->mtd);
- return(0);
-@@ -211,9 +164,9 @@
- del_mtd_device(udev->mtd);
- map_destroy(udev->mtd);
- }
-- if(0 != udev->map.map_priv_1) {
-- iounmap((void*)udev->map.map_priv_1);
-- udev->map.map_priv_1 = 0;
-+ if(0 != udev->map.virt) {
-+ iounmap((void*)udev->map.virt);
-+ udev->map.virt = 0;
- }
- if(0 != udev->name) {
- kfree(udev->name);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/tqm8xxl.c linux/drivers/mtd/maps/tqm8xxl.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/tqm8xxl.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/tqm8xxl.c 2004-11-17 18:17:59.140298568 +0100
-@@ -2,7 +2,7 @@
- * Handle mapping of the flash memory access routines
- * on TQM8xxL based devices.
- *
-- * $Id$
-+ * $Id$
- *
- * based on rpxlite.c
- *
-@@ -26,6 +26,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
-
- #include <linux/mtd/mtd.h>
-@@ -51,46 +52,6 @@
- static unsigned long num_banks;
- static unsigned long start_scan_addr;
-
--__u8 tqm8xxl_read8(struct map_info *map, unsigned long ofs)
--{
-- return *((__u8 *)(map->map_priv_1 + ofs));
--}
--
--__u16 tqm8xxl_read16(struct map_info *map, unsigned long ofs)
--{
-- return *((__u16 *)(map->map_priv_1 + ofs));
--}
--
--__u32 tqm8xxl_read32(struct map_info *map, unsigned long ofs)
--{
-- return *((__u32 *)(map->map_priv_1 + ofs));
--}
--
--void tqm8xxl_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
--}
--
--void tqm8xxl_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- *((__u8 *)(map->map_priv_1 + adr)) = d;
--}
--
--void tqm8xxl_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- *((__u16 *)( map->map_priv_1 + adr)) = d;
--}
--
--void tqm8xxl_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- *((__u32 *)(map->map_priv_1 + adr)) = d;
--}
--
--void tqm8xxl_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio((void *)(map->map_priv_1 + to), from, len);
--}
--
- /*
- * Here are partition information for all known TQM8xxL series devices.
- * See include/linux/mtd/partitions.h for definition of the mtd_partition
-@@ -107,50 +68,48 @@
- static unsigned long tqm8xxl_max_flash_size = 0x00800000;
-
- /* partition definition for first flash bank
-- * also ref. to "drivers\char\flash_config.c"
-+ * (cf. "drivers/char/flash_config.c")
- */
- static struct mtd_partition tqm8xxl_partitions[] = {
- {
-- name: "ppcboot",
-- offset: 0x00000000,
-- size: 0x00020000, /* 128KB */
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-+ .name = "ppcboot",
-+ .offset = 0x00000000,
-+ .size = 0x00020000, /* 128KB */
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
- {
-- name: "kernel", /* default kernel image */
-- offset: 0x00020000,
-- size: 0x000e0000,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-+ .name = "kernel", /* default kernel image */
-+ .offset = 0x00020000,
-+ .size = 0x000e0000,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
- {
-- name: "user",
-- offset: 0x00100000,
-- size: 0x00100000,
-+ .name = "user",
-+ .offset = 0x00100000,
-+ .size = 0x00100000,
- },
- {
-- name: "initrd",
-- offset: 0x00200000,
-- size: 0x00200000,
-+ .name = "initrd",
-+ .offset = 0x00200000,
-+ .size = 0x00200000,
- }
- };
--/* partition definition for second flahs bank */
-+/* partition definition for second flash bank */
- static struct mtd_partition tqm8xxl_fs_partitions[] = {
- {
-- name: "cramfs",
-- offset: 0x00000000,
-- size: 0x00200000,
-+ .name = "cramfs",
-+ .offset = 0x00000000,
-+ .size = 0x00200000,
- },
- {
-- name: "jffs",
-- offset: 0x00200000,
-- size: 0x00200000,
-- //size: MTDPART_SIZ_FULL,
-+ .name = "jffs",
-+ .offset = 0x00200000,
-+ .size = 0x00200000,
-+ .//size = MTDPART_SIZ_FULL,
- }
- };
- #endif
-
--#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
--
- int __init init_tqm_mtd(void)
- {
- int idx = 0, ret = 0;
-@@ -160,67 +119,73 @@
-
- flash_addr = bd->bi_flashstart;
- flash_size = bd->bi_flashsize;
-- //request maximum flash size address spzce
-+
-+ //request maximum flash size address space
- start_scan_addr = (unsigned long)ioremap(flash_addr, flash_size);
- if (!start_scan_addr) {
-- //printk("%s:Failed to ioremap address:0x%x\n", __FUNCTION__, FLASH_ADDR);
-- printk("%s:Failed to ioremap address:0x%x\n", __FUNCTION__, flash_addr);
-+ printk(KERN_WARNING "%s:Failed to ioremap address:0x%x\n", __FUNCTION__, flash_addr);
- return -EIO;
- }
-- for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++)
-- {
-+
-+ for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
- if(mtd_size >= flash_size)
- break;
-
-- printk("%s: chip probing count %d\n", __FUNCTION__, idx);
-+ printk(KERN_INFO "%s: chip probing count %d\n", __FUNCTION__, idx);
-
- map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info), GFP_KERNEL);
-- if(map_banks[idx] == NULL)
-- {
-- //return -ENOMEM;
-+ if(map_banks[idx] == NULL) {
- ret = -ENOMEM;
-+ /* FIXME: What if some MTD devices were probed already? */
- goto error_mem;
- }
-+
- memset((void *)map_banks[idx], 0, sizeof(struct map_info));
- map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL);
-- if(map_banks[idx]->name == NULL)
-- {
-- //return -ENOMEM;
-+
-+ if (!map_banks[idx]->name) {
- ret = -ENOMEM;
-+ /* FIXME: What if some MTD devices were probed already? */
- goto error_mem;
- }
-- memset((void *)map_banks[idx]->name, 0, 16);
--
- sprintf(map_banks[idx]->name, "TQM8xxL%d", idx);
-+
- map_banks[idx]->size = flash_size;
- map_banks[idx]->buswidth = 4;
-- map_banks[idx]->read8 = tqm8xxl_read8;
-- map_banks[idx]->read16 = tqm8xxl_read16;
-- map_banks[idx]->read32 = tqm8xxl_read32;
-- map_banks[idx]->copy_from = tqm8xxl_copy_from;
-- map_banks[idx]->write8 = tqm8xxl_write8;
-- map_banks[idx]->write16 = tqm8xxl_write16;
-- map_banks[idx]->write32 = tqm8xxl_write32;
-- map_banks[idx]->copy_to = tqm8xxl_copy_to;
-+
-+ simple_map_init(map_banks[idx]);
-+
-+ map_banks[idx]->virt = start_scan_addr;
-+ map_banks[idx]->phys = flash_addr;
-+ /* FIXME: This looks utterly bogus, but I'm trying to
-+ preserve the behaviour of the original (shown here)...
-+
- map_banks[idx]->map_priv_1 =
- start_scan_addr + ((idx > 0) ?
- (mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0);
-+ */
-+
-+ if (idx && mtd_banks[idx-1]) {
-+ map_banks[idx]->virt += mtd_banks[idx-1]->size;
-+ map_banks[idx]->phys += mtd_banks[idx-1]->size;
-+ }
-+
- //start to probe flash chips
- mtd_banks[idx] = do_map_probe("cfi_probe", map_banks[idx]);
-- if(mtd_banks[idx])
-- {
-- mtd_banks[idx]->module = THIS_MODULE;
-+
-+ if (mtd_banks[idx]) {
-+ mtd_banks[idx]->owner = THIS_MODULE;
- mtd_size += mtd_banks[idx]->size;
- num_banks++;
-- printk("%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks,
-+
-+ printk(KERN_INFO "%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks,
- mtd_banks[idx]->name, mtd_banks[idx]->size);
- }
- }
-
- /* no supported flash chips found */
-- if(!num_banks)
-- {
-- printk("TQM8xxL: No support flash chips found!\n");
-+ if (!num_banks) {
-+ printk(KERN_NOTICE "TQM8xxL: No support flash chips found!\n");
- ret = -ENXIO;
- goto error_mem;
- }
-@@ -231,12 +196,13 @@
- */
- part_banks[0].mtd_part = tqm8xxl_partitions;
- part_banks[0].type = "Static image";
-- part_banks[0].nums = NB_OF(tqm8xxl_partitions);
-+ part_banks[0].nums = ARRAY_SIZE(tqm8xxl_partitions);
-+
- part_banks[1].mtd_part = tqm8xxl_fs_partitions;
- part_banks[1].type = "Static file system";
-- part_banks[1].nums = NB_OF(tqm8xxl_fs_partitions);
-- for(idx = 0; idx < num_banks ; idx++)
-- {
-+ part_banks[1].nums = ARRAY_SIZE(tqm8xxl_fs_partitions);
-+
-+ for(idx = 0; idx < num_banks ; idx++) {
- if (part_banks[idx].nums == 0) {
- printk(KERN_NOTICE "TQM flash%d: no partition info available, registering whole flash at once\n", idx);
- add_mtd_device(mtd_banks[idx]);
-@@ -254,12 +220,9 @@
- #endif
- return 0;
- error_mem:
-- for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++)
-- {
-- if(map_banks[idx] != NULL)
-- {
-- if(map_banks[idx]->name != NULL)
-- {
-+ for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
-+ if(map_banks[idx] != NULL) {
-+ if(map_banks[idx]->name != NULL) {
- kfree(map_banks[idx]->name);
- map_banks[idx]->name = NULL;
- }
-@@ -267,18 +230,15 @@
- map_banks[idx] = NULL;
- }
- }
-- //return -ENOMEM;
- error:
- iounmap((void *)start_scan_addr);
-- //return -ENXIO;
- return ret;
- }
-
- static void __exit cleanup_tqm_mtd(void)
- {
- unsigned int idx = 0;
-- for(idx = 0 ; idx < num_banks ; idx++)
-- {
-+ for(idx = 0 ; idx < num_banks ; idx++) {
- /* destroy mtd_info previously allocated */
- if (mtd_banks[idx]) {
- del_mtd_partitions(mtd_banks[idx]);
-@@ -288,6 +248,7 @@
- kfree(map_banks[idx]->name);
- kfree(map_banks[idx]);
- }
-+
- if (start_scan_addr) {
- iounmap((void *)start_scan_addr);
- start_scan_addr = 0;
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/tsunami_flash.c linux/drivers/mtd/maps/tsunami_flash.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/tsunami_flash.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/tsunami_flash.c 2004-11-17 18:17:59.141298416 +0100
-@@ -2,11 +2,13 @@
- * tsunami_flash.c
- *
- * flash chip on alpha ds10...
-- * $Id$
-+ * $Id$
- */
- #include <asm/io.h>
- #include <asm/core_tsunami.h>
-+#include <linux/init.h>
- #include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
-
- #define FLASH_ENABLE_PORT 0x00C00001
- #define FLASH_ENABLE_BYTE 0x01
-@@ -58,18 +60,12 @@
- static struct map_info tsunami_flash_map = {
- .name = "flash chip on the Tsunami TIG bus",
- .size = MAX_TIG_FLASH_SIZE,
-+ .phys = NO_XIP;
- .buswidth = 1,
- .read8 = tsunami_flash_read8,
-- .read16 = 0,
-- .read32 = 0,
- .copy_from = tsunami_flash_copy_from,
- .write8 = tsunami_flash_write8,
-- .write16 = 0,
-- .write32 = 0,
- .copy_to = tsunami_flash_copy_to,
-- .set_vpp = 0,
-- .map_priv_1 = 0,
--
- };
-
- static struct mtd_info *tsunami_flash_mtd;
-@@ -99,7 +95,7 @@
- tsunami_flash_mtd = do_map_probe(*type, &tsunami_flash_map);
- }
- if (tsunami_flash_mtd) {
-- tsunami_flash_mtd->module = THIS_MODULE;
-+ tsunami_flash_mtd->owner = THIS_MODULE;
- add_mtd_device(tsunami_flash_mtd);
- return 0;
- }
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/uclinux.c linux/drivers/mtd/maps/uclinux.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/uclinux.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/uclinux.c 2004-11-17 18:17:59.142298264 +0100
-@@ -5,7 +5,7 @@
- *
- * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
- *
-- * $Id$
-+ * $Id$
- */
-
- /****************************************************************************/
-@@ -24,58 +24,11 @@
-
- /****************************************************************************/
-
--__u8 uclinux_read8(struct map_info *map, unsigned long ofs)
--{
-- return(*((__u8 *) (map->map_priv_1 + ofs)));
--}
--
--__u16 uclinux_read16(struct map_info *map, unsigned long ofs)
--{
-- return(*((__u16 *) (map->map_priv_1 + ofs)));
--}
--
--__u32 uclinux_read32(struct map_info *map, unsigned long ofs)
--{
-- return(*((__u32 *) (map->map_priv_1 + ofs)));
--}
--
--void uclinux_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy(to, (void *)(map->map_priv_1 + from), len);
--}
--
--void uclinux_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- *((__u8 *) (map->map_priv_1 + adr)) = d;
--}
--
--void uclinux_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- *((__u16 *) (map->map_priv_1 + adr)) = d;
--}
--
--void uclinux_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- *((__u32 *) (map->map_priv_1 + adr)) = d;
--}
--
--void uclinux_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy((void *) (map->map_priv_1 + to), from, len);
--}
-
- /****************************************************************************/
-
- struct map_info uclinux_ram_map = {
-- name: "RAM",
-- read8: uclinux_read8,
-- read16: uclinux_read16,
-- read32: uclinux_read32,
-- copy_from: uclinux_copy_from,
-- write8: uclinux_write8,
-- write16: uclinux_write16,
-- write32: uclinux_write32,
-- copy_to: uclinux_copy_to,
-+ .name = "RAM",
- };
-
- struct mtd_info *uclinux_ram_mtdinfo;
-@@ -83,7 +36,7 @@
- /****************************************************************************/
-
- struct mtd_partition uclinux_romfs[] = {
-- { name: "ROMfs", offset: 0 }
-+ { .name = "ROMfs" }
- };
-
- #define NUM_PARTITIONS (sizeof(uclinux_romfs) / sizeof(uclinux_romfs[0]))
-@@ -94,7 +47,7 @@
- size_t *retlen, u_char **mtdbuf)
- {
- struct map_info *map = (struct map_info *) mtd->priv;
-- *mtdbuf = (u_char *) (map->map_priv_1 + ((int) from));
-+ *mtdbuf = (u_char *) (map->virt + ((int) from));
- *retlen = len;
- return(0);
- }
-@@ -108,29 +61,31 @@
- extern char _ebss;
-
- mapp = &uclinux_ram_map;
-- mapp->map_priv_2 = (unsigned long) &_ebss;
-+ mapp->phys = (unsigned long) &_ebss;
- mapp->size = PAGE_ALIGN(*((unsigned long *)((&_ebss) + 8)));
- mapp->buswidth = 4;
-
- printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n",
- (int) mapp->map_priv_2, (int) mapp->size);
-
-- mapp->map_priv_1 = (unsigned long)
-- ioremap_nocache(mapp->map_priv_2, mapp->size);
-+ mapp->virt = (unsigned long)
-+ ioremap_nocache(mapp->phys, mapp->size);
-
-- if (mapp->map_priv_1 == 0) {
-+ if (mapp->virt == 0) {
- printk("uclinux[mtd]: ioremap_nocache() failed\n");
- return(-EIO);
- }
-
-+ simple_map_init(mapp);
-+
- mtd = do_map_probe("map_ram", mapp);
- if (!mtd) {
- printk("uclinux[mtd]: failed to find a mapping?\n");
-- iounmap((void *) mapp->map_priv_1);
-+ iounmap((void *) mapp->virt);
- return(-ENXIO);
- }
-
-- mtd->module = THIS_MODULE;
-+ mtd->owner = THIS_MODULE;
- mtd->point = uclinux_point;
- mtd->priv = mapp;
-
-@@ -155,8 +110,8 @@
- uclinux_ram_mtdinfo = NULL;
- }
- if (uclinux_ram_map.map_priv_1) {
-- iounmap((void *) uclinux_ram_map.map_priv_1);
-- uclinux_ram_map.map_priv_1 = 0;
-+ iounmap((void *) uclinux_ram_map.virt);
-+ uclinux_ram_map.virt = 0;
- }
- }
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/maps/vmax301.c linux/drivers/mtd/maps/vmax301.c
---- linux-mips-2.4.24-pre2/drivers/mtd/maps/vmax301.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/maps/vmax301.c 2004-11-17 18:17:59.144297960 +0100
-@@ -1,4 +1,4 @@
--// $Id$
-+// $Id$
- /* ######################################################################
-
- Tempustech VMAX SBC301 MTD Driver.
-@@ -24,6 +24,7 @@
- #include <asm/io.h>
-
- #include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
-
-
- #define WINDOW_START 0xd8000
-@@ -142,34 +143,36 @@
-
- static struct map_info vmax_map[2] = {
- {
-- name: "VMAX301 Internal Flash",
-- size: 3*2*1024*1024,
-- buswidth: 1,
-- read8: vmax301_read8,
-- read16: vmax301_read16,
-- read32: vmax301_read32,
-- copy_from: vmax301_copy_from,
-- write8: vmax301_write8,
-- write16: vmax301_write16,
-- write32: vmax301_write32,
-- copy_to: vmax301_copy_to,
-- map_priv_1: WINDOW_START + WINDOW_LENGTH,
-- map_priv_2: 0xFFFFFFFF
-+ .name = "VMAX301 Internal Flash",
-+ .phys = NO_XIP,
-+ .size = 3*2*1024*1024,
-+ .buswidth = 1,
-+ .read8 = vmax301_read8,
-+ .read16 = vmax301_read16,
-+ .read32 = vmax301_read32,
-+ .copy_from = vmax301_copy_from,
-+ .write8 = vmax301_write8,
-+ .write16 = vmax301_write16,
-+ .write32 = vmax301_write32,
-+ .copy_to = vmax301_copy_to,
-+ .map_priv_1 = WINDOW_START + WINDOW_LENGTH,
-+ .map_priv_2 = 0xFFFFFFFF
- },
- {
-- name: "VMAX301 Socket",
-- size: 0,
-- buswidth: 1,
-- read8: vmax301_read8,
-- read16: vmax301_read16,
-- read32: vmax301_read32,
-- copy_from: vmax301_copy_from,
-- write8: vmax301_write8,
-- write16: vmax301_write16,
-- write32: vmax301_write32,
-- copy_to: vmax301_copy_to,
-- map_priv_1: WINDOW_START + (3*WINDOW_LENGTH),
-- map_priv_2: 0xFFFFFFFF
-+ .name = "VMAX301 Socket",
-+ .phys = NO_XIP,
-+ .size = 0,
-+ .buswidth = 1,
-+ .read8 = vmax301_read8,
-+ .read16 = vmax301_read16,
-+ .read32 = vmax301_read32,
-+ .copy_from = vmax301_copy_from,
-+ .write8 = vmax301_write8,
-+ .write16 = vmax301_write16,
-+ .write32 = vmax301_write32,
-+ .copy_to = vmax301_copy_to,
-+ .map_priv_1 = WINDOW_START + (3*WINDOW_LENGTH),
-+ .map_priv_2 = 0xFFFFFFFF
- }
- };
-
-@@ -206,8 +209,8 @@
- address of the first half, because it's used more
- often.
- */
-- vmax_map[0].map_priv_1 = iomapadr + WINDOW_START;
-- vmax_map[1].map_priv_1 = iomapadr + (3*WINDOW_START);
-+ vmax_map[0].map_priv_2 = iomapadr + WINDOW_START;
-+ vmax_map[1].map_priv_2 = iomapadr + (3*WINDOW_START);
-
- for (i=0; i<2; i++) {
- vmax_mtd[i] = do_map_probe("cfi_probe", &vmax_map[i]);
-@@ -218,7 +221,7 @@
- if (!vmax_mtd[i])
- vmax_mtd[i] = do_map_probe("map_rom", &vmax_map[i]);
- if (vmax_mtd[i]) {
-- vmax_mtd[i]->module = THIS_MODULE;
-+ vmax_mtd[i]->owner = THIS_MODULE;
- add_mtd_device(vmax_mtd[i]);
- }
- }
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/mtd_blkdevs-24.c linux/drivers/mtd/mtd_blkdevs-24.c
---- linux-mips-2.4.24-pre2/drivers/mtd/mtd_blkdevs-24.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/mtd_blkdevs-24.c 2004-11-17 18:17:58.000000000 +0100
-@@ -0,0 +1,699 @@
-+/*
-+ * $Id$
-+ *
-+ * (C) 2003 David Woodhouse <dwmw2@infradead.org>
-+ *
-+ * Interface to Linux 2.4 block layer for MTD 'translation layers'.
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/list.h>
-+#include <linux/fs.h>
-+#include <linux/mtd/blktrans.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/blkdev.h>
-+#include <linux/blk.h>
-+#include <linux/blkpg.h>
-+#include <linux/spinlock.h>
-+#include <linux/hdreg.h>
-+#include <linux/init.h>
-+#include <asm/semaphore.h>
-+#include <asm/uaccess.h>
-+
-+static LIST_HEAD(blktrans_majors);
-+
-+extern struct semaphore mtd_table_mutex;
-+extern struct mtd_info *mtd_table[];
-+
-+struct mtd_blkcore_priv {
-+ devfs_handle_t devfs_dir_handle;
-+ int blksizes[256];
-+ int sizes[256];
-+ struct hd_struct part_table[256];
-+ struct gendisk gd;
-+ spinlock_t devs_lock; /* See comment in _request function */
-+ struct completion thread_dead;
-+ int exiting;
-+ wait_queue_head_t thread_wq;
-+};
-+
-+static inline struct mtd_blktrans_dev *tr_get_dev(struct mtd_blktrans_ops *tr,
-+ int devnum)
-+{
-+ struct list_head *this;
-+ struct mtd_blktrans_dev *d;
-+
-+ list_for_each(this, &tr->devs) {
-+ d = list_entry(this, struct mtd_blktrans_dev, list);
-+
-+ if (d->devnum == devnum)
-+ return d;
-+ }
-+ return NULL;
-+}
-+
-+static inline struct mtd_blktrans_ops *get_tr(int major)
-+{
-+ struct list_head *this;
-+ struct mtd_blktrans_ops *t;
-+
-+ list_for_each(this, &blktrans_majors) {
-+ t = list_entry(this, struct mtd_blktrans_ops, list);
-+
-+ if (t->major == major)
-+ return t;
-+ }
-+ return NULL;
-+}
-+
-+static int do_blktrans_request(struct mtd_blktrans_ops *tr,
-+ struct mtd_blktrans_dev *dev,
-+ struct request *req)
-+{
-+ unsigned long block, nsect;
-+ char *buf;
-+ int minor;
-+
-+ minor = MINOR(req->rq_dev);
-+ block = req->sector;
-+ nsect = req->current_nr_sectors;
-+ buf = req->buffer;
-+
-+ if (block + nsect > tr->blkcore_priv->part_table[minor].nr_sects) {
-+ printk(KERN_WARNING "Access beyond end of device.\n");
-+ return 0;
-+ }
-+ block += tr->blkcore_priv->part_table[minor].start_sect;
-+
-+ switch(req->cmd) {
-+ case READ:
-+ for (; nsect > 0; nsect--, block++, buf += 512)
-+ if (tr->readsect(dev, block, buf))
-+ return 0;
-+ return 1;
-+
-+ case WRITE:
-+ if (!tr->writesect)
-+ return 0;
-+
-+ for (; nsect > 0; nsect--, block++, buf += 512)
-+ if (tr->writesect(dev, block, buf))
-+ return 0;
-+ return 1;
-+
-+ default:
-+ printk(KERN_NOTICE "Unknown request cmd %d\n", req->cmd);
-+ return 0;
-+ }
-+}
-+
-+static int mtd_blktrans_thread(void *arg)
-+{
-+ struct mtd_blktrans_ops *tr = arg;
-+ struct request_queue *rq = BLK_DEFAULT_QUEUE(tr->major);
-+
-+ /* we might get involved when memory gets low, so use PF_MEMALLOC */
-+ current->flags |= PF_MEMALLOC;
-+
-+ snprintf(current->comm, sizeof(current->comm), "%sd", tr->name);
-+
-+ /* daemonize() doesn't do this for us since some kernel threads
-+ actually want to deal with signals. We can't just call
-+ exit_sighand() since that'll cause an oops when we finally
-+ do exit. */
-+
-+#ifndef __rh_config_h__ /* HAVE_NPTL */
-+ spin_lock_irq(&current->sigmask_lock);
-+ sigfillset(&current->blocked);
-+ recalc_sigpending(current);
-+ spin_unlock_irq(&current->sigmask_lock);
-+#else
-+ spin_lock_irq(&current->sighand->siglock);
-+ sigfillset(&current->blocked);
-+ recalc_sigpending();
-+ spin_unlock_irq(&current->sighand->siglock);
-+#endif
-+ daemonize();
-+
-+ while (!tr->blkcore_priv->exiting) {
-+ struct request *req;
-+ struct mtd_blktrans_dev *dev;
-+ int devnum;
-+ int res = 0;
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+ spin_lock_irq(&io_request_lock);
-+
-+ if (list_empty(&rq->queue_head)) {
-+
-+ add_wait_queue(&tr->blkcore_priv->thread_wq, &wait);
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ spin_unlock_irq(&io_request_lock);
-+
-+ schedule();
-+ remove_wait_queue(&tr->blkcore_priv->thread_wq, &wait);
-+
-+ continue;
-+ }
-+
-+ req = blkdev_entry_next_request(&rq->queue_head);
-+
-+ devnum = MINOR(req->rq_dev) >> tr->part_bits;
-+
-+ /* The ll_rw_blk code knows not to touch the request
-+ at the head of the queue */
-+ spin_unlock_irq(&io_request_lock);
-+
-+ /* FIXME: Where can we store the dev, on which
-+ we already have a refcount anyway? We need to
-+ lock against concurrent addition/removal of devices,
-+ but if we use the mtd_table_mutex we deadlock when
-+ grok_partitions is called from the registration
-+ callbacks. */
-+ spin_lock(&tr->blkcore_priv->devs_lock);
-+ dev = tr_get_dev(tr, devnum);
-+ spin_unlock(&tr->blkcore_priv->devs_lock);
-+
-+ BUG_ON(!dev);
-+
-+ /* Ensure serialisation of requests */
-+ down(&dev->sem);
-+
-+ res = do_blktrans_request(tr, dev, req);
-+ up(&dev->sem);
-+
-+ if (!end_that_request_first(req, res, tr->name)) {
-+ spin_lock_irq(&io_request_lock);
-+ blkdev_dequeue_request(req);
-+ end_that_request_last(req);
-+ spin_unlock_irq(&io_request_lock);
-+ }
-+ }
-+ complete_and_exit(&tr->blkcore_priv->thread_dead, 0);
-+}
-+
-+static void mtd_blktrans_request(struct request_queue *rq)
-+{
-+ struct mtd_blktrans_ops *tr = rq->queuedata;
-+ wake_up(&tr->blkcore_priv->thread_wq);
-+}
-+
-+int blktrans_open(struct inode *i, struct file *f)
-+{
-+ struct mtd_blktrans_ops *tr = NULL;
-+ struct mtd_blktrans_dev *dev = NULL;
-+ int major_nr = MAJOR(i->i_rdev);
-+ int minor_nr = MINOR(i->i_rdev);
-+ int devnum;
-+ int ret = -ENODEV;
-+
-+ if (is_read_only(i->i_rdev) && (f->f_mode & FMODE_WRITE))
-+ return -EROFS;
-+
-+ down(&mtd_table_mutex);
-+
-+ tr = get_tr(major_nr);
-+
-+ if (!tr)
-+ goto out;
-+
-+ devnum = minor_nr >> tr->part_bits;
-+
-+ dev = tr_get_dev(tr, devnum);
-+
-+ if (!dev)
-+ goto out;
-+
-+ if (!tr->blkcore_priv->part_table[minor_nr].nr_sects) {
-+ ret = -ENODEV;
-+ goto out;
-+ }
-+
-+ if (!try_inc_mod_count(dev->mtd->owner))
-+ goto out;
-+
-+ if (!try_inc_mod_count(tr->owner))
-+ goto out_tr;
-+
-+ dev->mtd->usecount++;
-+
-+ ret = 0;
-+ if (tr->open && (ret = tr->open(dev))) {
-+ dev->mtd->usecount--;
-+ if (dev->mtd->owner)
-+ __MOD_DEC_USE_COUNT(dev->mtd->owner);
-+ out_tr:
-+ if (tr->owner)
-+ __MOD_DEC_USE_COUNT(tr->owner);
-+ }
-+ out:
-+ up(&mtd_table_mutex);
-+
-+ return ret;
-+}
-+
-+int blktrans_release(struct inode *i, struct file *f)
-+{
-+ struct mtd_blktrans_dev *dev;
-+ struct mtd_blktrans_ops *tr;
-+ int ret = 0;
-+ int devnum;
-+
-+ down(&mtd_table_mutex);
-+
-+ tr = get_tr(MAJOR(i->i_rdev));
-+ if (!tr) {
-+ up(&mtd_table_mutex);
-+ return -ENODEV;
-+ }
-+
-+ devnum = MINOR(i->i_rdev) >> tr->part_bits;
-+ dev = tr_get_dev(tr, devnum);
-+
-+ if (!dev) {
-+ up(&mtd_table_mutex);
-+ return -ENODEV;
-+ }
-+
-+ if (tr->release)
-+ ret = tr->release(dev);
-+
-+ if (!ret) {
-+ dev->mtd->usecount--;
-+ if (dev->mtd->owner)
-+ __MOD_DEC_USE_COUNT(dev->mtd->owner);
-+ if (tr->owner)
-+ __MOD_DEC_USE_COUNT(tr->owner);
-+ }
-+
-+ up(&mtd_table_mutex);
-+
-+ return ret;
-+}
-+
-+static int mtd_blktrans_rrpart(kdev_t rdev, struct mtd_blktrans_ops *tr,
-+ struct mtd_blktrans_dev *dev)
-+{
-+ struct gendisk *gd = &(tr->blkcore_priv->gd);
-+ int i;
-+ int minor = MINOR(rdev);
-+
-+ if (minor & ((1<<tr->part_bits)-1) || !tr->part_bits) {
-+ /* BLKRRPART on a partition. Go away. */
-+ return -ENOTTY;
-+ }
-+
-+ if (!capable(CAP_SYS_ADMIN))
-+ return -EACCES;
-+
-+ /* We are required to prevent simultaneous open() ourselves.
-+ The core doesn't do that for us. Did I ever mention how
-+ much the Linux block layer sucks? Sledgehammer approach... */
-+ down(&mtd_table_mutex);
-+
-+ for (i=0; i < (1<<tr->part_bits); i++) {
-+ invalidate_device(MKDEV(tr->major, minor+i), 1);
-+ gd->part[minor + i].start_sect = 0;
-+ gd->part[minor + i].nr_sects = 0;
-+ }
-+
-+ grok_partitions(gd, minor, 1 << tr->part_bits,
-+ tr->blkcore_priv->sizes[minor]);
-+ up(&mtd_table_mutex);
-+
-+ return 0;
-+}
-+
-+static int blktrans_ioctl(struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ struct mtd_blktrans_dev *dev;
-+ struct mtd_blktrans_ops *tr;
-+ int devnum;
-+
-+ switch(cmd) {
-+ case BLKGETSIZE:
-+ case BLKGETSIZE64:
-+ case BLKBSZSET:
-+ case BLKBSZGET:
-+ case BLKROSET:
-+ case BLKROGET:
-+ case BLKRASET:
-+ case BLKRAGET:
-+ case BLKPG:
-+ case BLKELVGET:
-+ case BLKELVSET:
-+ return blk_ioctl(inode->i_rdev, cmd, arg);
-+ }
-+
-+ down(&mtd_table_mutex);
-+
-+ tr = get_tr(MAJOR(inode->i_rdev));
-+ if (!tr) {
-+ up(&mtd_table_mutex);
-+ return -ENODEV;
-+ }
-+
-+ devnum = MINOR(inode->i_rdev) >> tr->part_bits;
-+ dev = tr_get_dev(tr, devnum);
-+
-+ up(&mtd_table_mutex);
-+
-+ if (!dev)
-+ return -ENODEV;
-+
-+ switch(cmd) {
-+ case BLKRRPART:
-+ return mtd_blktrans_rrpart(inode->i_rdev, tr, dev);
-+
-+ case BLKFLSBUF:
-+ blk_ioctl(inode->i_rdev, cmd, arg);
-+ if (tr->flush)
-+ return tr->flush(dev);
-+ /* The core code did the work, we had nothing to do. */
-+ return 0;
-+
-+ case HDIO_GETGEO:
-+ if (tr->getgeo) {
-+ struct hd_geometry g;
-+ struct gendisk *gd = &(tr->blkcore_priv->gd);
-+ int ret;
-+
-+ memset(&g, 0, sizeof(g));
-+ ret = tr->getgeo(dev, &g);
-+ if (ret)
-+ return ret;
-+
-+ g.start = gd->part[MINOR(inode->i_rdev)].start_sect;
-+ if (copy_to_user((void *)arg, &g, sizeof(g)))
-+ return -EFAULT;
-+ return 0;
-+ } /* else */
-+ default:
-+ return -ENOTTY;
-+ }
-+}
-+
-+struct block_device_operations mtd_blktrans_ops = {
-+ .owner = THIS_MODULE,
-+ .open = blktrans_open,
-+ .release = blktrans_release,
-+ .ioctl = blktrans_ioctl,
-+};
-+
-+int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
-+{
-+ struct mtd_blktrans_ops *tr = new->tr;
-+ struct list_head *this;
-+ int last_devnum = -1;
-+ int i;
-+
-+ if (!down_trylock(&mtd_table_mutex)) {
-+ up(&mtd_table_mutex);
-+ BUG();
-+ }
-+
-+ spin_lock(&tr->blkcore_priv->devs_lock);
-+
-+ list_for_each(this, &tr->devs) {
-+ struct mtd_blktrans_dev *d = list_entry(this, struct mtd_blktrans_dev, list);
-+ if (new->devnum == -1) {
-+ /* Use first free number */
-+ if (d->devnum != last_devnum+1) {
-+ /* Found a free devnum. Plug it in here */
-+ new->devnum = last_devnum+1;
-+ list_add_tail(&new->list, &d->list);
-+ goto added;
-+ }
-+ } else if (d->devnum == new->devnum) {
-+ /* Required number taken */
-+ spin_unlock(&tr->blkcore_priv->devs_lock);
-+ return -EBUSY;
-+ } else if (d->devnum > new->devnum) {
-+ /* Required number was free */
-+ list_add_tail(&new->list, &d->list);
-+ goto added;
-+ }
-+ last_devnum = d->devnum;
-+ }
-+ if (new->devnum == -1)
-+ new->devnum = last_devnum+1;
-+
-+ if ((new->devnum << tr->part_bits) > 256) {
-+ spin_unlock(&tr->blkcore_priv->devs_lock);
-+ return -EBUSY;
-+ }
-+
-+ init_MUTEX(&new->sem);
-+ list_add_tail(&new->list, &tr->devs);
-+ added:
-+ spin_unlock(&tr->blkcore_priv->devs_lock);
-+
-+ if (!tr->writesect)
-+ new->readonly = 1;
-+
-+ for (i = new->devnum << tr->part_bits;
-+ i < (new->devnum+1) << tr->part_bits;
-+ i++) {
-+ set_device_ro(MKDEV(tr->major, i), new->readonly);
-+ tr->blkcore_priv->blksizes[i] = new->blksize;
-+ tr->blkcore_priv->sizes[i] = 0;
-+ tr->blkcore_priv->part_table[i].nr_sects = 0;
-+ tr->blkcore_priv->part_table[i].start_sect = 0;
-+ }
-+
-+ /*
-+ <viro_zzz> dwmw2: BLOCK_SIZE_BITS has nothing to do with block devices
-+ <viro> dwmw2: any code which sets blk_size[][] should be
-+ size >> 10 /+ 2.4 and its dumb units */
-+
-+ tr->blkcore_priv->sizes[new->devnum << tr->part_bits] =
-+ (new->size * new->blksize) >> 10; /* 2.4 and its dumb units */
-+
-+ /* But this is still in device's sectors? $DEITY knows */
-+ tr->blkcore_priv->part_table[new->devnum << tr->part_bits].nr_sects = new->size;
-+
-+ if (tr->part_bits) {
-+ grok_partitions(&tr->blkcore_priv->gd, new->devnum,
-+ 1 << tr->part_bits, new->size);
-+ }
-+#ifdef CONFIG_DEVFS_FS
-+ if (!tr->part_bits) {
-+ char name[2];
-+
-+ name[0] = '0' + new->devnum;
-+ name[1] = 0;
-+
-+ new->blkcore_priv =
-+ devfs_register(tr->blkcore_priv->devfs_dir_handle,
-+ name, DEVFS_FL_DEFAULT, tr->major,
-+ new->devnum, S_IFBLK|S_IRUGO|S_IWUGO,
-+ &mtd_blktrans_ops, NULL);
-+ }
-+#endif
-+ return 0;
-+}
-+
-+int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
-+{
-+ struct mtd_blktrans_ops *tr = old->tr;
-+ int i;
-+
-+ if (!down_trylock(&mtd_table_mutex)) {
-+ up(&mtd_table_mutex);
-+ BUG();
-+ }
-+
-+#ifdef CONFIG_DEVFS_FS
-+ if (!tr->part_bits) {
-+ devfs_unregister(old->blkcore_priv);
-+ old->blkcore_priv = NULL;
-+ } else {
-+ devfs_register_partitions(&tr->blkcore_priv->gd,
-+ old->devnum << tr->part_bits, 1);
-+ }
-+#endif
-+ spin_lock(&tr->blkcore_priv->devs_lock);
-+ list_del(&old->list);
-+ spin_unlock(&tr->blkcore_priv->devs_lock);
-+
-+ for (i = (old->devnum << tr->part_bits);
-+ i < ((old->devnum+1) << tr->part_bits); i++) {
-+ tr->blkcore_priv->sizes[i] = 0;
-+ tr->blkcore_priv->part_table[i].nr_sects = 0;
-+ tr->blkcore_priv->part_table[i].start_sect = 0;
-+ }
-+
-+ return 0;
-+}
-+
-+void blktrans_notify_remove(struct mtd_info *mtd)
-+{
-+ struct list_head *this, *this2, *next;
-+
-+ list_for_each(this, &blktrans_majors) {
-+ struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);
-+
-+ list_for_each_safe(this2, next, &tr->devs) {
-+ struct mtd_blktrans_dev *dev = list_entry(this2, struct mtd_blktrans_dev, list);
-+
-+ if (dev->mtd == mtd)
-+ tr->remove_dev(dev);
-+ }
-+ }
-+}
-+
-+void blktrans_notify_add(struct mtd_info *mtd)
-+{
-+ struct list_head *this;
-+
-+ if (mtd->type == MTD_ABSENT)
-+ return;
-+
-+ list_for_each(this, &blktrans_majors) {
-+ struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);
-+
-+ tr->add_mtd(tr, mtd);
-+ }
-+
-+}
-+
-+static struct mtd_notifier blktrans_notifier = {
-+ .add = blktrans_notify_add,
-+ .remove = blktrans_notify_remove,
-+};
-+
-+int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
-+{
-+ int ret, i;
-+
-+ /* Register the notifier if/when the first device type is
-+ registered, to prevent the link/init ordering from fucking
-+ us over. */
-+ if (!blktrans_notifier.list.next)
-+ register_mtd_user(&blktrans_notifier);
-+
-+ tr->blkcore_priv = kmalloc(sizeof(*tr->blkcore_priv), GFP_KERNEL);
-+ if (!tr->blkcore_priv)
-+ return -ENOMEM;
-+
-+ memset(tr->blkcore_priv, 0, sizeof(*tr->blkcore_priv));
-+
-+ down(&mtd_table_mutex);
-+
-+ ret = devfs_register_blkdev(tr->major, tr->name, &mtd_blktrans_ops);
-+ if (ret) {
-+ printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n",
-+ tr->name, tr->major, ret);
-+ kfree(tr->blkcore_priv);
-+ up(&mtd_table_mutex);
-+ return ret;
-+ }
-+
-+ blk_init_queue(BLK_DEFAULT_QUEUE(tr->major), &mtd_blktrans_request);
-+ (BLK_DEFAULT_QUEUE(tr->major))->queuedata = tr;
-+
-+ init_completion(&tr->blkcore_priv->thread_dead);
-+ init_waitqueue_head(&tr->blkcore_priv->thread_wq);
-+
-+ ret = kernel_thread(mtd_blktrans_thread, tr,
-+ CLONE_FS|CLONE_FILES|CLONE_SIGHAND);
-+ if (ret < 0) {
-+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(tr->major));
-+ devfs_unregister_blkdev(tr->major, tr->name);
-+ kfree(tr->blkcore_priv);
-+ up(&mtd_table_mutex);
-+ return ret;
-+ }
-+
-+ tr->blkcore_priv->devfs_dir_handle =
-+ devfs_mk_dir(NULL, tr->name, NULL);
-+
-+ blksize_size[tr->major] = tr->blkcore_priv->blksizes;
-+ blk_size[tr->major] = tr->blkcore_priv->sizes;
-+
-+ tr->blkcore_priv->gd.major = tr->major;
-+ tr->blkcore_priv->gd.major_name = tr->name;
-+ tr->blkcore_priv->gd.minor_shift = tr->part_bits;
-+ tr->blkcore_priv->gd.max_p = (1<<tr->part_bits) - 1;
-+ tr->blkcore_priv->gd.part = tr->blkcore_priv->part_table;
-+ tr->blkcore_priv->gd.sizes = tr->blkcore_priv->sizes;
-+ tr->blkcore_priv->gd.nr_real = 256 >> tr->part_bits;
-+
-+ spin_lock_init(&tr->blkcore_priv->devs_lock);
-+
-+ add_gendisk(&tr->blkcore_priv->gd);
-+
-+ INIT_LIST_HEAD(&tr->devs);
-+ list_add(&tr->list, &blktrans_majors);
-+
-+ for (i=0; i<MAX_MTD_DEVICES; i++) {
-+ if (mtd_table[i] && mtd_table[i]->type != MTD_ABSENT)
-+ tr->add_mtd(tr, mtd_table[i]);
-+ }
-+ up(&mtd_table_mutex);
-+
-+ return 0;
-+}
-+
-+int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
-+{
-+ struct list_head *this, *next;
-+
-+ down(&mtd_table_mutex);
-+
-+ /* Clean up the kernel thread */
-+ tr->blkcore_priv->exiting = 1;
-+ wake_up(&tr->blkcore_priv->thread_wq);
-+ wait_for_completion(&tr->blkcore_priv->thread_dead);
-+
-+ /* Remove it from the list of active majors */
-+ list_del(&tr->list);
-+
-+ /* Remove each of its devices */
-+ list_for_each_safe(this, next, &tr->devs) {
-+ struct mtd_blktrans_dev *dev = list_entry(this, struct mtd_blktrans_dev, list);
-+ tr->remove_dev(dev);
-+ }
-+
-+ blksize_size[tr->major] = NULL;
-+ blk_size[tr->major] = NULL;
-+
-+ del_gendisk(&tr->blkcore_priv->gd);
-+
-+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(tr->major));
-+ devfs_unregister_blkdev(tr->major, tr->name);
-+
-+ devfs_unregister(tr->blkcore_priv->devfs_dir_handle);
-+
-+ up(&mtd_table_mutex);
-+
-+ kfree(tr->blkcore_priv);
-+
-+ if (!list_empty(&tr->devs))
-+ BUG();
-+ return 0;
-+}
-+
-+static void __exit mtd_blktrans_exit(void)
-+{
-+ /* No race here -- if someone's currently in register_mtd_blktrans
-+ we're screwed anyway. */
-+ if (blktrans_notifier.list.next)
-+ unregister_mtd_user(&blktrans_notifier);
-+}
-+
-+module_exit(mtd_blktrans_exit);
-+
-+EXPORT_SYMBOL_GPL(register_mtd_blktrans);
-+EXPORT_SYMBOL_GPL(deregister_mtd_blktrans);
-+EXPORT_SYMBOL_GPL(add_mtd_blktrans_dev);
-+EXPORT_SYMBOL_GPL(del_mtd_blktrans_dev);
-+
-+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("Common interface to block layer for MTD 'translation layers'");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/mtd_blkdevs.c linux/drivers/mtd/mtd_blkdevs.c
---- linux-mips-2.4.24-pre2/drivers/mtd/mtd_blkdevs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/mtd_blkdevs.c 2004-11-17 18:17:58.000000000 +0100
-@@ -0,0 +1,479 @@
-+/*
-+ * $Id$
-+ *
-+ * (C) 2003 David Woodhouse <dwmw2@infradead.org>
-+ *
-+ * Interface to Linux 2.5 block layer for MTD 'translation layers'.
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/list.h>
-+#include <linux/fs.h>
-+#include <linux/mtd/blktrans.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/blkdev.h>
-+#include <linux/blk.h>
-+#include <linux/blkpg.h>
-+#include <linux/spinlock.h>
-+#include <linux/hdreg.h>
-+#include <linux/init.h>
-+#include <asm/semaphore.h>
-+#include <asm/uaccess.h>
-+#include <linux/devfs_fs_kernel.h>
-+
-+static LIST_HEAD(blktrans_majors);
-+
-+extern struct semaphore mtd_table_mutex;
-+extern struct mtd_info *mtd_table[];
-+
-+struct mtd_blkcore_priv {
-+ struct completion thread_dead;
-+ int exiting;
-+ wait_queue_head_t thread_wq;
-+ struct request_queue *rq;
-+ spinlock_t queue_lock;
-+};
-+
-+static int do_blktrans_request(struct mtd_blktrans_ops *tr,
-+ struct mtd_blktrans_dev *dev,
-+ struct request *req)
-+{
-+ unsigned long block, nsect;
-+ char *buf;
-+
-+ block = req->sector;
-+ nsect = req->current_nr_sectors;
-+ buf = req->buffer;
-+
-+ if (!(req->flags & REQ_CMD))
-+ return 0;
-+
-+ if (block + nsect > get_capacity(req->rq_disk))
-+ return 0;
-+
-+ switch(rq_data_dir(req)) {
-+ case READ:
-+ for (; nsect > 0; nsect--, block++, buf += 512)
-+ if (tr->readsect(dev, block, buf))
-+ return 0;
-+ return 1;
-+
-+ case WRITE:
-+ if (!tr->writesect)
-+ return 0;
-+
-+ for (; nsect > 0; nsect--, block++, buf += 512)
-+ if (tr->writesect(dev, block, buf))
-+ return 0;
-+ return 1;
-+
-+ default:
-+ printk(KERN_NOTICE "Unknown request %ld\n", rq_data_dir(req));
-+ return 0;
-+ }
-+}
-+
-+static int mtd_blktrans_thread(void *arg)
-+{
-+ struct mtd_blktrans_ops *tr = arg;
-+ struct request_queue *rq = tr->blkcore_priv->rq;
-+
-+ /* we might get involved when memory gets low, so use PF_MEMALLOC */
-+ current->flags |= PF_MEMALLOC;
-+
-+ daemonize("%sd", tr->name);
-+
-+ /* daemonize() doesn't do this for us since some kernel threads
-+ actually want to deal with signals. We can't just call
-+ exit_sighand() since that'll cause an oops when we finally
-+ do exit. */
-+ spin_lock_irq(&current->sighand->siglock);
-+ sigfillset(&current->blocked);
-+ recalc_sigpending();
-+ spin_unlock_irq(&current->sighand->siglock);
-+
-+ spin_lock_irq(rq->queue_lock);
-+
-+ while (!tr->blkcore_priv->exiting) {
-+ struct request *req;
-+ struct mtd_blktrans_dev *dev;
-+ int res = 0;
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+ req = elv_next_request(rq);
-+
-+ if (!req) {
-+ add_wait_queue(&tr->blkcore_priv->thread_wq, &wait);
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ spin_unlock_irq(rq->queue_lock);
-+
-+ schedule();
-+ remove_wait_queue(&tr->blkcore_priv->thread_wq, &wait);
-+
-+ spin_lock_irq(rq->queue_lock);
-+
-+ continue;
-+ }
-+
-+ dev = req->rq_disk->private_data;
-+ tr = dev->tr;
-+
-+ spin_unlock_irq(rq->queue_lock);
-+
-+ down(&dev->sem);
-+ res = do_blktrans_request(tr, dev, req);
-+ up(&dev->sem);
-+
-+ spin_lock_irq(rq->queue_lock);
-+
-+ end_request(req, res);
-+ }
-+ complete_and_exit(&tr->blkcore_priv->thread_dead, 0);
-+}
-+
-+static void mtd_blktrans_request(struct request_queue *rq)
-+{
-+ struct mtd_blktrans_ops *tr = rq->queuedata;
-+ wake_up(&tr->blkcore_priv->thread_wq);
-+}
-+
-+
-+int blktrans_open(struct inode *i, struct file *f)
-+{
-+ struct mtd_blktrans_dev *dev;
-+ struct mtd_blktrans_ops *tr;
-+ int ret = -ENODEV;
-+
-+ dev = i->i_bdev->bd_disk->private_data;
-+ tr = dev->tr;
-+
-+ if (!try_module_get(dev->mtd->owner))
-+ goto out;
-+
-+ if (!try_module_get(tr->owner))
-+ goto out_tr;
-+
-+ /* FIXME: Locking. A hot pluggable device can go away
-+ (del_mtd_device can be called for it) without its module
-+ being unloaded. */
-+ dev->mtd->usecount++;
-+
-+ ret = 0;
-+ if (tr->open && (ret = tr->open(dev))) {
-+ dev->mtd->usecount--;
-+ module_put(dev->mtd->owner);
-+ out_tr:
-+ module_put(tr->owner);
-+ }
-+ out:
-+ return ret;
-+}
-+
-+int blktrans_release(struct inode *i, struct file *f)
-+{
-+ struct mtd_blktrans_dev *dev;
-+ struct mtd_blktrans_ops *tr;
-+ int ret = 0;
-+
-+ dev = i->i_bdev->bd_disk->private_data;
-+ tr = dev->tr;
-+
-+ if (tr->release)
-+ ret = tr->release(dev);
-+
-+ if (!ret) {
-+ dev->mtd->usecount--;
-+ module_put(dev->mtd->owner);
-+ module_put(tr->owner);
-+ }
-+
-+ return ret;
-+}
-+
-+
-+static int blktrans_ioctl(struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data;
-+ struct mtd_blktrans_ops *tr = dev->tr;
-+
-+ switch (cmd) {
-+ case BLKFLSBUF:
-+ if (tr->flush)
-+ return tr->flush(dev);
-+ /* The core code did the work, we had nothing to do. */
-+ return 0;
-+
-+ case HDIO_GETGEO:
-+ if (tr->getgeo) {
-+ struct hd_geometry g;
-+ int ret;
-+
-+ memset(&g, 0, sizeof(g));
-+ ret = tr->getgeo(dev, &g);
-+
-+ if (ret)
-+ return ret;
-+
-+ g.start = get_start_sect(inode->i_bdev);
-+ if (copy_to_user((void *)arg, &g, sizeof(g)))
-+ return -EFAULT;
-+ return 0;
-+ } /* else */
-+ default:
-+ return -ENOTTY;
-+ }
-+}
-+
-+struct block_device_operations mtd_blktrans_ops = {
-+ .owner = THIS_MODULE,
-+ .open = blktrans_open,
-+ .release = blktrans_release,
-+ .ioctl = blktrans_ioctl,
-+};
-+
-+int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
-+{
-+ struct mtd_blktrans_ops *tr = new->tr;
-+ struct list_head *this;
-+ int last_devnum = -1;
-+ struct gendisk *gd;
-+
-+ if (!down_trylock(&mtd_table_mutex)) {
-+ up(&mtd_table_mutex);
-+ BUG();
-+ }
-+
-+ list_for_each(this, &tr->devs) {
-+ struct mtd_blktrans_dev *d = list_entry(this, struct mtd_blktrans_dev, list);
-+ if (new->devnum == -1) {
-+ /* Use first free number */
-+ if (d->devnum != last_devnum+1) {
-+ /* Found a free devnum. Plug it in here */
-+ new->devnum = last_devnum+1;
-+ list_add_tail(&new->list, &d->list);
-+ goto added;
-+ }
-+ } else if (d->devnum == new->devnum) {
-+ /* Required number taken */
-+ return -EBUSY;
-+ } else if (d->devnum > new->devnum) {
-+ /* Required number was free */
-+ list_add_tail(&new->list, &d->list);
-+ goto added;
-+ }
-+ last_devnum = d->devnum;
-+ }
-+ if (new->devnum == -1)
-+ new->devnum = last_devnum+1;
-+
-+ if ((new->devnum << tr->part_bits) > 256) {
-+ return -EBUSY;
-+ }
-+
-+ init_MUTEX(&new->sem);
-+ list_add_tail(&new->list, &tr->devs);
-+ added:
-+ if (!tr->writesect)
-+ new->readonly = 1;
-+
-+ gd = alloc_disk(1 << tr->part_bits);
-+ if (!gd) {
-+ list_del(&new->list);
-+ return -ENOMEM;
-+ }
-+ gd->major = tr->major;
-+ gd->first_minor = (new->devnum) << tr->part_bits;
-+ gd->fops = &mtd_blktrans_ops;
-+
-+ snprintf(gd->disk_name, sizeof(gd->disk_name),
-+ "%s%c", tr->name, (tr->part_bits?'a':'0') + new->devnum);
-+ snprintf(gd->devfs_name, sizeof(gd->devfs_name),
-+ "%s/%c", tr->name, (tr->part_bits?'a':'0') + new->devnum);
-+
-+ /* 2.5 has capacity in units of 512 bytes while still
-+ having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */
-+ set_capacity(gd, (new->size * new->blksize) >> 9);
-+
-+ gd->private_data = new;
-+ new->blkcore_priv = gd;
-+ gd->queue = tr->blkcore_priv->rq;
-+
-+ if (new->readonly)
-+ set_disk_ro(gd, 1);
-+
-+ add_disk(gd);
-+
-+ return 0;
-+}
-+
-+int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
-+{
-+ if (!down_trylock(&mtd_table_mutex)) {
-+ up(&mtd_table_mutex);
-+ BUG();
-+ }
-+
-+ list_del(&old->list);
-+
-+ del_gendisk(old->blkcore_priv);
-+ put_disk(old->blkcore_priv);
-+
-+ return 0;
-+}
-+
-+void blktrans_notify_remove(struct mtd_info *mtd)
-+{
-+ struct list_head *this, *this2, *next;
-+
-+ list_for_each(this, &blktrans_majors) {
-+ struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);
-+
-+ list_for_each_safe(this2, next, &tr->devs) {
-+ struct mtd_blktrans_dev *dev = list_entry(this2, struct mtd_blktrans_dev, list);
-+
-+ if (dev->mtd == mtd)
-+ tr->remove_dev(dev);
-+ }
-+ }
-+}
-+
-+void blktrans_notify_add(struct mtd_info *mtd)
-+{
-+ struct list_head *this;
-+
-+ if (mtd->type == MTD_ABSENT)
-+ return;
-+
-+ list_for_each(this, &blktrans_majors) {
-+ struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);
-+
-+ tr->add_mtd(tr, mtd);
-+ }
-+
-+}
-+
-+static struct mtd_notifier blktrans_notifier = {
-+ .add = blktrans_notify_add,
-+ .remove = blktrans_notify_remove,
-+};
-+
-+int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
-+{
-+ int ret, i;
-+
-+ /* Register the notifier if/when the first device type is
-+ registered, to prevent the link/init ordering from fucking
-+ us over. */
-+ if (!blktrans_notifier.list.next)
-+ register_mtd_user(&blktrans_notifier);
-+
-+ tr->blkcore_priv = kmalloc(sizeof(*tr->blkcore_priv), GFP_KERNEL);
-+ if (!tr->blkcore_priv)
-+ return -ENOMEM;
-+
-+ memset(tr->blkcore_priv, 0, sizeof(*tr->blkcore_priv));
-+
-+ down(&mtd_table_mutex);
-+
-+ ret = register_blkdev(tr->major, tr->name);
-+ if (ret) {
-+ printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n",
-+ tr->name, tr->major, ret);
-+ kfree(tr->blkcore_priv);
-+ up(&mtd_table_mutex);
-+ return ret;
-+ }
-+ spin_lock_init(&tr->blkcore_priv->queue_lock);
-+ init_completion(&tr->blkcore_priv->thread_dead);
-+ init_waitqueue_head(&tr->blkcore_priv->thread_wq);
-+
-+ tr->blkcore_priv->rq = blk_init_queue(mtd_blktrans_request, &tr->blkcore_priv->queue_lock);
-+ if (!tr->blkcore_priv->rq) {
-+ unregister_blkdev(tr->major, tr->name);
-+ kfree(tr->blkcore_priv);
-+ up(&mtd_table_mutex);
-+ return -ENOMEM;
-+ }
-+
-+ tr->blkcore_priv->rq->queuedata = tr;
-+
-+ ret = kernel_thread(mtd_blktrans_thread, tr,
-+ CLONE_FS|CLONE_FILES|CLONE_SIGHAND);
-+ if (ret < 0) {
-+ blk_cleanup_queue(tr->blkcore_priv->rq);
-+ unregister_blkdev(tr->major, tr->name);
-+ kfree(tr->blkcore_priv);
-+ up(&mtd_table_mutex);
-+ return ret;
-+ }
-+
-+ devfs_mk_dir(tr->name);
-+
-+ INIT_LIST_HEAD(&tr->devs);
-+ list_add(&tr->list, &blktrans_majors);
-+
-+ for (i=0; i<MAX_MTD_DEVICES; i++) {
-+ if (mtd_table[i] && mtd_table[i]->type != MTD_ABSENT)
-+ tr->add_mtd(tr, mtd_table[i]);
-+ }
-+
-+ up(&mtd_table_mutex);
-+
-+ return 0;
-+}
-+
-+int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
-+{
-+ struct list_head *this, *next;
-+
-+ down(&mtd_table_mutex);
-+
-+ /* Clean up the kernel thread */
-+ tr->blkcore_priv->exiting = 1;
-+ wake_up(&tr->blkcore_priv->thread_wq);
-+ wait_for_completion(&tr->blkcore_priv->thread_dead);
-+
-+ /* Remove it from the list of active majors */
-+ list_del(&tr->list);
-+
-+ list_for_each_safe(this, next, &tr->devs) {
-+ struct mtd_blktrans_dev *dev = list_entry(this, struct mtd_blktrans_dev, list);
-+ tr->remove_dev(dev);
-+ }
-+
-+ devfs_remove(tr->name);
-+ blk_cleanup_queue(tr->blkcore_priv->rq);
-+ unregister_blkdev(tr->major, tr->name);
-+
-+ up(&mtd_table_mutex);
-+
-+ kfree(tr->blkcore_priv);
-+
-+ if (!list_empty(&tr->devs))
-+ BUG();
-+ return 0;
-+}
-+
-+static void __exit mtd_blktrans_exit(void)
-+{
-+ /* No race here -- if someone's currently in register_mtd_blktrans
-+ we're screwed anyway. */
-+ if (blktrans_notifier.list.next)
-+ unregister_mtd_user(&blktrans_notifier);
-+}
-+
-+module_exit(mtd_blktrans_exit);
-+
-+EXPORT_SYMBOL_GPL(register_mtd_blktrans);
-+EXPORT_SYMBOL_GPL(deregister_mtd_blktrans);
-+EXPORT_SYMBOL_GPL(add_mtd_blktrans_dev);
-+EXPORT_SYMBOL_GPL(del_mtd_blktrans_dev);
-+
-+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("Common interface to block layer for MTD 'translation layers'");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/mtdblock.c linux/drivers/mtd/mtdblock.c
---- linux-mips-2.4.24-pre2/drivers/mtd/mtdblock.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/mtdblock.c 2004-11-17 18:17:58.856341736 +0100
-@@ -1,52 +1,25 @@
- /*
- * Direct MTD block device access
- *
-- * $Id$
-+ * $Id$
- *
-- * 02-nov-2000 Nicolas Pitre Added read-modify-write with cache
-+ * (C) 2000-2003 Nicolas Pitre <nico@cam.org>
-+ * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
- */
-
- #include <linux/config.h>
- #include <linux/types.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
-+#include <linux/fs.h>
-+#include <linux/init.h>
- #include <linux/slab.h>
-+#include <linux/vmalloc.h>
- #include <linux/mtd/mtd.h>
--#include <linux/mtd/compatmac.h>
--
--#define MAJOR_NR MTD_BLOCK_MAJOR
--#define DEVICE_NAME "mtdblock"
--#define DEVICE_REQUEST mtdblock_request
--#define DEVICE_NR(device) (device)
--#define DEVICE_ON(device)
--#define DEVICE_OFF(device)
--#define DEVICE_NO_RANDOM
--#include <linux/blk.h>
--/* for old kernels... */
--#ifndef QUEUE_EMPTY
--#define QUEUE_EMPTY (!CURRENT)
--#endif
--#if LINUX_VERSION_CODE < 0x20300
--#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].plug_tq.sync)
--#else
--#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].request_queue.plugged)
--#endif
--
--#ifdef CONFIG_DEVFS_FS
--#include <linux/devfs_fs_kernel.h>
--static void mtd_notify_add(struct mtd_info* mtd);
--static void mtd_notify_remove(struct mtd_info* mtd);
--static struct mtd_notifier notifier = {
-- mtd_notify_add,
-- mtd_notify_remove,
-- NULL
--};
--static devfs_handle_t devfs_dir_handle = NULL;
--static devfs_handle_t devfs_rw_handle[MAX_MTD_DEVICES];
--#endif
-+#include <linux/mtd/blktrans.h>
-
- static struct mtdblk_dev {
-- struct mtd_info *mtd; /* Locked */
-+ struct mtd_info *mtd;
- int count;
- struct semaphore cache_sem;
- unsigned char *cache_data;
-@@ -55,19 +28,6 @@
- enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state;
- } *mtdblks[MAX_MTD_DEVICES];
-
--static spinlock_t mtdblks_lock;
--
--static int mtd_sizes[MAX_MTD_DEVICES];
--static int mtd_blksizes[MAX_MTD_DEVICES];
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
--#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
--#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
--#else
--#define BLK_INC_USE_COUNT do {} while(0)
--#define BLK_DEC_USE_COUNT do {} while(0)
--#endif
--
- /*
- * Cache stuff...
- *
-@@ -151,7 +111,7 @@
- return ret;
-
- /*
-- * Here we could argably set the cache state to STATE_CLEAN.
-+ * Here we could argubly set the cache state to STATE_CLEAN.
- * However this could lead to inconsistency since we will not
- * be notified if this content is altered on the flash by other
- * means. Let's declare it empty and leave buffering tasks to
-@@ -277,57 +237,47 @@
- return 0;
- }
-
-+static int mtdblock_readsect(struct mtd_blktrans_dev *dev,
-+ unsigned long block, char *buf)
-+{
-+ struct mtdblk_dev *mtdblk = mtdblks[dev->devnum];
-+ return do_cached_read(mtdblk, block<<9, 512, buf);
-+}
-
-+static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
-+ unsigned long block, char *buf)
-+{
-+ struct mtdblk_dev *mtdblk = mtdblks[dev->devnum];
-+ if (unlikely(!mtdblk->cache_data)) {
-+ mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize);
-+ if (!mtdblk->cache_data)
-+ return -EINTR;
-+ /* -EINTR is not really correct, but it is the best match
-+ * documented in man 2 write for all cases. We could also
-+ * return -EAGAIN sometimes, but why bother?
-+ */
-+ }
-+ return do_cached_write(mtdblk, block<<9, 512, buf);
-+}
-
--static int mtdblock_open(struct inode *inode, struct file *file)
-+static int mtdblock_open(struct mtd_blktrans_dev *mbd)
- {
- struct mtdblk_dev *mtdblk;
-- struct mtd_info *mtd;
-- int dev;
-+ struct mtd_info *mtd = mbd->mtd;
-+ int dev = mbd->devnum;
-
- DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
-
-- if (!inode)
-- return -EINVAL;
--
-- dev = MINOR(inode->i_rdev);
-- if (dev >= MAX_MTD_DEVICES)
-- return -EINVAL;
--
-- BLK_INC_USE_COUNT;
--
-- mtd = get_mtd_device(NULL, dev);
-- if (!mtd)
-- return -ENODEV;
-- if (MTD_ABSENT == mtd->type) {
-- put_mtd_device(mtd);
-- BLK_DEC_USE_COUNT;
-- return -ENODEV;
-- }
--
-- spin_lock(&mtdblks_lock);
--
-- /* If it's already open, no need to piss about. */
- if (mtdblks[dev]) {
- mtdblks[dev]->count++;
-- spin_unlock(&mtdblks_lock);
-- put_mtd_device(mtd);
- return 0;
- }
-
-- /* OK, it's not open. Try to find it */
--
-- /* First we have to drop the lock, because we have to
-- to things which might sleep.
-- */
-- spin_unlock(&mtdblks_lock);
--
-+ /* OK, it's not open. Create cache info for it */
- mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
-- if (!mtdblk) {
-- put_mtd_device(mtd);
-- BLK_DEC_USE_COUNT;
-+ if (!mtdblk)
- return -ENOMEM;
-- }
-+
- memset(mtdblk, 0, sizeof(*mtdblk));
- mtdblk->count = 1;
- mtdblk->mtd = mtd;
-@@ -337,336 +287,102 @@
- if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM &&
- mtdblk->mtd->erasesize) {
- mtdblk->cache_size = mtdblk->mtd->erasesize;
-- mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize);
-- if (!mtdblk->cache_data) {
-- put_mtd_device(mtdblk->mtd);
-- kfree(mtdblk);
-- BLK_DEC_USE_COUNT;
-- return -ENOMEM;
-- }
-- }
--
-- /* OK, we've created a new one. Add it to the list. */
--
-- spin_lock(&mtdblks_lock);
--
-- if (mtdblks[dev]) {
-- /* Another CPU made one at the same time as us. */
-- mtdblks[dev]->count++;
-- spin_unlock(&mtdblks_lock);
-- put_mtd_device(mtdblk->mtd);
-- vfree(mtdblk->cache_data);
-- kfree(mtdblk);
-- return 0;
-+ mtdblk->cache_data = NULL;
- }
-
- mtdblks[dev] = mtdblk;
-- mtd_sizes[dev] = mtdblk->mtd->size/1024;
-- if (mtdblk->mtd->erasesize)
-- mtd_blksizes[dev] = mtdblk->mtd->erasesize;
-- if (mtd_blksizes[dev] > PAGE_SIZE)
-- mtd_blksizes[dev] = PAGE_SIZE;
-- set_device_ro (inode->i_rdev, !(mtdblk->mtd->flags & MTD_WRITEABLE));
--
-- spin_unlock(&mtdblks_lock);
-
- DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
-
- return 0;
- }
-
--static release_t mtdblock_release(struct inode *inode, struct file *file)
-+static int mtdblock_release(struct mtd_blktrans_dev *mbd)
- {
-- int dev;
-- struct mtdblk_dev *mtdblk;
-- DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n");
-+ int dev = mbd->devnum;
-+ struct mtdblk_dev *mtdblk = mtdblks[dev];
-
-- if (inode == NULL)
-- release_return(-ENODEV);
--
-- dev = MINOR(inode->i_rdev);
-- mtdblk = mtdblks[dev];
-+ DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n");
-
- down(&mtdblk->cache_sem);
- write_cached_data(mtdblk);
- up(&mtdblk->cache_sem);
-
-- spin_lock(&mtdblks_lock);
- if (!--mtdblk->count) {
- /* It was the last usage. Free the device */
- mtdblks[dev] = NULL;
-- spin_unlock(&mtdblks_lock);
- if (mtdblk->mtd->sync)
- mtdblk->mtd->sync(mtdblk->mtd);
-- put_mtd_device(mtdblk->mtd);
- vfree(mtdblk->cache_data);
- kfree(mtdblk);
-- } else {
-- spin_unlock(&mtdblks_lock);
- }
--
- DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
-
-- BLK_DEC_USE_COUNT;
-- release_return(0);
--}
--
--
--/*
-- * This is a special request_fn because it is executed in a process context
-- * to be able to sleep independently of the caller. The io_request_lock
-- * is held upon entry and exit.
-- * The head of our request queue is considered active so there is no need
-- * to dequeue requests before we are done.
-- */
--static void handle_mtdblock_request(void)
--{
-- struct request *req;
-- struct mtdblk_dev *mtdblk;
-- unsigned int res;
--
-- for (;;) {
-- INIT_REQUEST;
-- req = CURRENT;
-- spin_unlock_irq(&io_request_lock);
-- mtdblk = mtdblks[MINOR(req->rq_dev)];
-- res = 0;
--
-- if (MINOR(req->rq_dev) >= MAX_MTD_DEVICES)
-- panic("%s: minor out of bounds", __FUNCTION__);
--
-- if ((req->sector + req->current_nr_sectors) > (mtdblk->mtd->size >> 9))
-- goto end_req;
--
-- // Handle the request
-- switch (req->cmd)
-- {
-- int err;
--
-- case READ:
-- down(&mtdblk->cache_sem);
-- err = do_cached_read (mtdblk, req->sector << 9,
-- req->current_nr_sectors << 9,
-- req->buffer);
-- up(&mtdblk->cache_sem);
-- if (!err)
-- res = 1;
-- break;
--
-- case WRITE:
-- // Read only device
-- if ( !(mtdblk->mtd->flags & MTD_WRITEABLE) )
-- break;
--
-- // Do the write
-- down(&mtdblk->cache_sem);
-- err = do_cached_write (mtdblk, req->sector << 9,
-- req->current_nr_sectors << 9,
-- req->buffer);
-- up(&mtdblk->cache_sem);
-- if (!err)
-- res = 1;
-- break;
-- }
--
--end_req:
-- spin_lock_irq(&io_request_lock);
-- end_request(res);
-- }
--}
--
--static volatile int leaving = 0;
--static DECLARE_MUTEX_LOCKED(thread_sem);
--static DECLARE_WAIT_QUEUE_HEAD(thr_wq);
--
--int mtdblock_thread(void *dummy)
--{
-- struct task_struct *tsk = current;
-- DECLARE_WAITQUEUE(wait, tsk);
--
-- /* we might get involved when memory gets low, so use PF_MEMALLOC */
-- tsk->flags |= PF_MEMALLOC;
-- strcpy(tsk->comm, "mtdblockd");
-- spin_lock_irq(&tsk->sigmask_lock);
-- sigfillset(&tsk->blocked);
-- recalc_sigpending(tsk);
-- spin_unlock_irq(&tsk->sigmask_lock);
-- daemonize();
--
-- while (!leaving) {
-- add_wait_queue(&thr_wq, &wait);
-- set_current_state(TASK_INTERRUPTIBLE);
-- spin_lock_irq(&io_request_lock);
-- if (QUEUE_EMPTY || QUEUE_PLUGGED) {
-- spin_unlock_irq(&io_request_lock);
-- schedule();
-- remove_wait_queue(&thr_wq, &wait);
-- } else {
-- remove_wait_queue(&thr_wq, &wait);
-- set_current_state(TASK_RUNNING);
-- handle_mtdblock_request();
-- spin_unlock_irq(&io_request_lock);
-- }
-- }
--
-- up(&thread_sem);
- return 0;
- }
-
--#if LINUX_VERSION_CODE < 0x20300
--#define RQFUNC_ARG void
--#else
--#define RQFUNC_ARG request_queue_t *q
--#endif
--
--static void mtdblock_request(RQFUNC_ARG)
-+static int mtdblock_flush(struct mtd_blktrans_dev *dev)
- {
-- /* Don't do anything, except wake the thread if necessary */
-- wake_up(&thr_wq);
--}
-+ struct mtdblk_dev *mtdblk = mtdblks[dev->devnum];
-
--
--static int mtdblock_ioctl(struct inode * inode, struct file * file,
-- unsigned int cmd, unsigned long arg)
--{
-- struct mtdblk_dev *mtdblk;
--
-- mtdblk = mtdblks[MINOR(inode->i_rdev)];
--
--#ifdef PARANOIA
-- if (!mtdblk)
-- BUG();
--#endif
--
-- switch (cmd) {
-- case BLKGETSIZE: /* Return device size */
-- return put_user((mtdblk->mtd->size >> 9), (unsigned long *) arg);
--
--#ifdef BLKGETSIZE64
-- case BLKGETSIZE64:
-- return put_user((u64)mtdblk->mtd->size, (u64 *)arg);
--#endif
--
-- case BLKFLSBUF:
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-- if(!capable(CAP_SYS_ADMIN))
-- return -EACCES;
--#endif
-- fsync_dev(inode->i_rdev);
-- invalidate_buffers(inode->i_rdev);
- down(&mtdblk->cache_sem);
- write_cached_data(mtdblk);
- up(&mtdblk->cache_sem);
-+
- if (mtdblk->mtd->sync)
- mtdblk->mtd->sync(mtdblk->mtd);
- return 0;
--
-- default:
-- return -EINVAL;
-- }
- }
-
--#if LINUX_VERSION_CODE < 0x20326
--static struct file_operations mtd_fops =
-+static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
- {
-- open: mtdblock_open,
-- ioctl: mtdblock_ioctl,
-- release: mtdblock_release,
-- read: block_read,
-- write: block_write
--};
--#else
--static struct block_device_operations mtd_fops =
--{
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14)
-- owner: THIS_MODULE,
--#endif
-- open: mtdblock_open,
-- release: mtdblock_release,
-- ioctl: mtdblock_ioctl
--};
--#endif
-+ struct mtd_blktrans_dev *dev = kmalloc(sizeof(*dev), GFP_KERNEL);
-
--#ifdef CONFIG_DEVFS_FS
--/* Notification that a new device has been added. Create the devfs entry for
-- * it. */
--
--static void mtd_notify_add(struct mtd_info* mtd)
--{
-- char name[8];
--
-- if (!mtd || mtd->type == MTD_ABSENT)
-+ if (!dev)
- return;
-
-- sprintf(name, "%d", mtd->index);
-- devfs_rw_handle[mtd->index] = devfs_register(devfs_dir_handle, name,
-- DEVFS_FL_DEFAULT, MTD_BLOCK_MAJOR, mtd->index,
-- S_IFBLK | S_IRUGO | S_IWUGO,
-- &mtd_fops, NULL);
--}
--
--static void mtd_notify_remove(struct mtd_info* mtd)
--{
-- if (!mtd || mtd->type == MTD_ABSENT)
-- return;
-+ memset(dev, 0, sizeof(*dev));
-
-- devfs_unregister(devfs_rw_handle[mtd->index]);
--}
--#endif
-+ dev->mtd = mtd;
-+ dev->devnum = mtd->index;
-+ dev->blksize = 512;
-+ dev->size = mtd->size >> 9;
-+ dev->tr = tr;
-+
-+ if (!(mtd->flags & MTD_WRITEABLE))
-+ dev->readonly = 1;
-+
-+ add_mtd_blktrans_dev(dev);
-+}
-+
-+static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
-+{
-+ del_mtd_blktrans_dev(dev);
-+ kfree(dev);
-+}
-+
-+struct mtd_blktrans_ops mtdblock_tr = {
-+ .name = "mtdblock",
-+ .major = 31,
-+ .part_bits = 0,
-+ .open = mtdblock_open,
-+ .flush = mtdblock_flush,
-+ .release = mtdblock_release,
-+ .readsect = mtdblock_readsect,
-+ .writesect = mtdblock_writesect,
-+ .add_mtd = mtdblock_add_mtd,
-+ .remove_dev = mtdblock_remove_dev,
-+ .owner = THIS_MODULE,
-+};
-
- int __init init_mtdblock(void)
- {
-- int i;
--
-- spin_lock_init(&mtdblks_lock);
--#ifdef CONFIG_DEVFS_FS
-- if (devfs_register_blkdev(MTD_BLOCK_MAJOR, DEVICE_NAME, &mtd_fops))
-- {
-- printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
-- MTD_BLOCK_MAJOR);
-- return -EAGAIN;
-- }
--
-- devfs_dir_handle = devfs_mk_dir(NULL, DEVICE_NAME, NULL);
-- register_mtd_user(&notifier);
--#else
-- if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) {
-- printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
-- MTD_BLOCK_MAJOR);
-- return -EAGAIN;
-- }
--#endif
--
-- /* We fill it in at open() time. */
-- for (i=0; i< MAX_MTD_DEVICES; i++) {
-- mtd_sizes[i] = 0;
-- mtd_blksizes[i] = BLOCK_SIZE;
-- }
-- init_waitqueue_head(&thr_wq);
-- /* Allow the block size to default to BLOCK_SIZE. */
-- blksize_size[MAJOR_NR] = mtd_blksizes;
-- blk_size[MAJOR_NR] = mtd_sizes;
--
-- blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request);
-- kernel_thread (mtdblock_thread, NULL, CLONE_FS|CLONE_FILES|CLONE_SIGHAND);
-- return 0;
-+ return register_mtd_blktrans(&mtdblock_tr);
- }
-
- static void __exit cleanup_mtdblock(void)
- {
-- leaving = 1;
-- wake_up(&thr_wq);
-- down(&thread_sem);
--#ifdef CONFIG_DEVFS_FS
-- unregister_mtd_user(&notifier);
-- devfs_unregister(devfs_dir_handle);
-- devfs_unregister_blkdev(MTD_BLOCK_MAJOR, DEVICE_NAME);
--#else
-- unregister_blkdev(MAJOR_NR,DEVICE_NAME);
--#endif
-- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-- blksize_size[MAJOR_NR] = NULL;
-- blk_size[MAJOR_NR] = NULL;
-+ deregister_mtd_blktrans(&mtdblock_tr);
- }
-
- module_init(init_mtdblock);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/mtdblock_ro.c linux/drivers/mtd/mtdblock_ro.c
---- linux-mips-2.4.24-pre2/drivers/mtd/mtdblock_ro.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/mtdblock_ro.c 2004-11-17 18:17:58.857341584 +0100
-@@ -1,301 +1,87 @@
- /*
-- * $Id$
-+ * $Id$
- *
-- * Read-only version of the mtdblock device, without the
-- * read/erase/modify/writeback stuff
-+ * (C) 2003 David Woodhouse <dwmw2@infradead.org>
-+ *
-+ * Simple read-only (writable only for RAM) mtdblock driver
- */
-
--#ifdef MTDBLOCK_DEBUG
--#define DEBUGLVL debug
--#endif
--
--
--#include <linux/module.h>
--#include <linux/types.h>
--
-+#include <linux/init.h>
-+#include <linux/slab.h>
- #include <linux/mtd/mtd.h>
--#include <linux/mtd/compatmac.h>
--
--#define MAJOR_NR MTD_BLOCK_MAJOR
--#define DEVICE_NAME "mtdblock"
--#define DEVICE_REQUEST mtdblock_request
--#define DEVICE_NR(device) (device)
--#define DEVICE_ON(device)
--#define DEVICE_OFF(device)
--#define DEVICE_NO_RANDOM
--#include <linux/blk.h>
--
--#if LINUX_VERSION_CODE < 0x20300
--#define RQFUNC_ARG void
--#define blkdev_dequeue_request(req) do {CURRENT = req->next;} while (0)
--#else
--#define RQFUNC_ARG request_queue_t *q
--#endif
--
--#ifdef MTDBLOCK_DEBUG
--static int debug = MTDBLOCK_DEBUG;
--MODULE_PARM(debug, "i");
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
--#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
--#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
--#else
--#define BLK_INC_USE_COUNT do {} while(0)
--#define BLK_DEC_USE_COUNT do {} while(0)
--#endif
--
--static int mtd_sizes[MAX_MTD_DEVICES];
-+#include <linux/mtd/blktrans.h>
-
--
--static int mtdblock_open(struct inode *inode, struct file *file)
-+static int mtdblock_readsect(struct mtd_blktrans_dev *dev,
-+ unsigned long block, char *buf)
- {
-- struct mtd_info *mtd = NULL;
--
-- int dev;
--
-- DEBUG(1,"mtdblock_open\n");
--
-- if (inode == 0)
-- return -EINVAL;
--
-- dev = MINOR(inode->i_rdev);
--
-- mtd = get_mtd_device(NULL, dev);
-- if (!mtd)
-- return -EINVAL;
-- if (MTD_ABSENT == mtd->type) {
-- put_mtd_device(mtd);
-- return -EINVAL;
-- }
--
-- BLK_INC_USE_COUNT;
--
-- mtd_sizes[dev] = mtd->size>>9;
--
-- DEBUG(1, "ok\n");
-+ size_t retlen;
-
-+ if (dev->mtd->read(dev->mtd, (block * 512), 512, &retlen, buf))
-+ return 1;
- return 0;
- }
-
--static release_t mtdblock_release(struct inode *inode, struct file *file)
-+static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
-+ unsigned long block, char *buf)
- {
-- int dev;
-- struct mtd_info *mtd;
--
-- DEBUG(1, "mtdblock_release\n");
--
-- if (inode == NULL)
-- release_return(-ENODEV);
--
-- dev = MINOR(inode->i_rdev);
-- mtd = __get_mtd_device(NULL, dev);
--
-- if (!mtd) {
-- printk(KERN_WARNING "MTD device is absent on mtd_release!\n");
-- BLK_DEC_USE_COUNT;
-- release_return(-ENODEV);
-- }
--
-- if (mtd->sync)
-- mtd->sync(mtd);
--
-- put_mtd_device(mtd);
--
-- DEBUG(1, "ok\n");
-+ size_t retlen;
-
-- BLK_DEC_USE_COUNT;
-- release_return(0);
-+ if (dev->mtd->write(dev->mtd, (block * 512), 512, &retlen, buf))
-+ return 1;
-+ return 0;
- }
-
--
--static void mtdblock_request(RQFUNC_ARG)
-+static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
- {
-- struct request *current_request;
-- unsigned int res = 0;
-- struct mtd_info *mtd;
--
-- while (1)
-- {
-- /* Grab the Request and unlink it from the request list, INIT_REQUEST
-- will execute a return if we are done. */
-- INIT_REQUEST;
-- current_request = CURRENT;
--
-- if (MINOR(current_request->rq_dev) >= MAX_MTD_DEVICES)
-- {
-- printk("mtd: Unsupported device!\n");
-- end_request(0);
-- continue;
-- }
--
-- // Grab our MTD structure
--
-- mtd = __get_mtd_device(NULL, MINOR(current_request->rq_dev));
-- if (!mtd) {
-- printk("MTD device %d doesn't appear to exist any more\n", CURRENT_DEV);
-- end_request(0);
-- }
--
-- if (current_request->sector << 9 > mtd->size ||
-- (current_request->sector + current_request->current_nr_sectors) << 9 > mtd->size)
-- {
-- printk("mtd: Attempt to read past end of device!\n");
-- printk("size: %x, sector: %lx, nr_sectors %lx\n", mtd->size,
-- current_request->sector, current_request->current_nr_sectors);
-- end_request(0);
-- continue;
-- }
--
-- /* Remove the request we are handling from the request list so nobody messes
-- with it */
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-- /* Now drop the lock that the ll_rw_blk functions grabbed for us
-- and process the request. This is necessary due to the extreme time
-- we spend processing it. */
-- spin_unlock_irq(&io_request_lock);
--#endif
--
-- // Handle the request
-- switch (current_request->cmd)
-- {
-- size_t retlen;
-+ struct mtd_blktrans_dev *dev = kmalloc(sizeof(*dev), GFP_KERNEL);
-
-- case READ:
-- if (MTD_READ(mtd,current_request->sector<<9,
-- current_request->current_nr_sectors << 9,
-- &retlen, current_request->buffer) == 0)
-- res = 1;
-- else
-- res = 0;
-- break;
-+ if (!dev)
-+ return;
-
-- case WRITE:
-+ memset(dev, 0, sizeof(*dev));
-
-- /* printk("mtdblock_request WRITE sector=%d(%d)\n",current_request->sector,
-- current_request->current_nr_sectors);
-- */
-+ dev->mtd = mtd;
-+ dev->devnum = mtd->index;
-+ dev->blksize = 512;
-+ dev->size = mtd->size >> 9;
-+ dev->tr = tr;
-+ if ((mtd->flags & (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEABLE)) !=
-+ (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEABLE))
-+ dev->readonly = 1;
-
-- // Read only device
-- if ((mtd->flags & MTD_CAP_RAM) == 0)
-- {
-- res = 0;
-- break;
-- }
--
-- // Do the write
-- if (MTD_WRITE(mtd,current_request->sector<<9,
-- current_request->current_nr_sectors << 9,
-- &retlen, current_request->buffer) == 0)
-- res = 1;
-- else
-- res = 0;
-- break;
--
-- // Shouldn't happen
-- default:
-- printk("mtd: unknown request\n");
-- break;
-- }
--
-- // Grab the lock and re-thread the item onto the linked list
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-- spin_lock_irq(&io_request_lock);
--#endif
-- end_request(res);
-- }
-+ add_mtd_blktrans_dev(dev);
- }
-
--
--
--static int mtdblock_ioctl(struct inode * inode, struct file * file,
-- unsigned int cmd, unsigned long arg)
-+static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
- {
-- struct mtd_info *mtd;
--
-- mtd = __get_mtd_device(NULL, MINOR(inode->i_rdev));
--
-- if (!mtd) return -EINVAL;
--
-- switch (cmd) {
-- case BLKGETSIZE: /* Return device size */
-- return put_user((mtd->size >> 9), (unsigned long *) arg);
--
--#ifdef BLKGETSIZE64
-- case BLKGETSIZE64:
-- return put_user((u64)mtd->size, (u64 *)arg);
--#endif
--
-- case BLKFLSBUF:
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-- if(!capable(CAP_SYS_ADMIN)) return -EACCES;
--#endif
-- fsync_dev(inode->i_rdev);
-- invalidate_buffers(inode->i_rdev);
-- if (mtd->sync)
-- mtd->sync(mtd);
-- return 0;
--
-- default:
-- return -ENOTTY;
-- }
-+ del_mtd_blktrans_dev(dev);
-+ kfree(dev);
- }
-
--#if LINUX_VERSION_CODE < 0x20326
--static struct file_operations mtd_fops =
--{
-- open: mtdblock_open,
-- ioctl: mtdblock_ioctl,
-- release: mtdblock_release,
-- read: block_read,
-- write: block_write
--};
--#else
--static struct block_device_operations mtd_fops =
--{
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14)
-- owner: THIS_MODULE,
--#endif
-- open: mtdblock_open,
-- release: mtdblock_release,
-- ioctl: mtdblock_ioctl
-+struct mtd_blktrans_ops mtdblock_tr = {
-+ .name = "mtdblock",
-+ .major = 31,
-+ .part_bits = 0,
-+ .readsect = mtdblock_readsect,
-+ .writesect = mtdblock_writesect,
-+ .add_mtd = mtdblock_add_mtd,
-+ .remove_dev = mtdblock_remove_dev,
-+ .owner = THIS_MODULE,
- };
--#endif
-
--int __init init_mtdblock(void)
-+static int __init mtdblock_init(void)
- {
-- int i;
--
-- if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) {
-- printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
-- MTD_BLOCK_MAJOR);
-- return -EAGAIN;
-- }
--
-- /* We fill it in at open() time. */
-- for (i=0; i< MAX_MTD_DEVICES; i++) {
-- mtd_sizes[i] = 0;
-- }
--
-- /* Allow the block size to default to BLOCK_SIZE. */
-- blksize_size[MAJOR_NR] = NULL;
-- blk_size[MAJOR_NR] = mtd_sizes;
--
-- blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request);
-- return 0;
-+ return register_mtd_blktrans(&mtdblock_tr);
- }
-
--static void __exit cleanup_mtdblock(void)
-+static void __exit mtdblock_exit(void)
- {
-- unregister_blkdev(MAJOR_NR,DEVICE_NAME);
-- blk_size[MAJOR_NR] = NULL;
-- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-+ deregister_mtd_blktrans(&mtdblock_tr);
- }
-
--module_init(init_mtdblock);
--module_exit(cleanup_mtdblock);
--
-+module_init(mtdblock_init);
-+module_exit(mtdblock_exit);
-
- MODULE_LICENSE("GPL");
--MODULE_AUTHOR("Erwin Authried <eauth@softsys.co.at> et al.");
-+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
- MODULE_DESCRIPTION("Simple read-only block device emulation access to MTD devices");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/mtdchar.c linux/drivers/mtd/mtdchar.c
---- linux-mips-2.4.24-pre2/drivers/mtd/mtdchar.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/mtdchar.c 2004-11-17 18:17:58.859341280 +0100
-@@ -1,8 +1,7 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Character-device access to raw MTD devices.
-- * Pure 2.4 version - compatibility cruft removed to mtdchar-compat.c
- *
- */
-
-@@ -10,7 +9,11 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/mtd/mtd.h>
-+#include <linux/mtd/compatmac.h>
- #include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/fs.h>
-+#include <asm/uaccess.h>
-
- #ifdef CONFIG_DEVFS_FS
- #include <linux/devfs_fs_kernel.h>
-@@ -18,8 +21,8 @@
- static void mtd_notify_remove(struct mtd_info* mtd);
-
- static struct mtd_notifier notifier = {
-- add: mtd_notify_add,
-- remove: mtd_notify_remove,
-+ .add = mtd_notify_add,
-+ .remove = mtd_notify_remove,
- };
-
- static devfs_handle_t devfs_dir_handle;
-@@ -60,7 +63,7 @@
-
- static int mtd_open(struct inode *inode, struct file *file)
- {
-- int minor = minor(inode->i_rdev);
-+ int minor = iminor(inode);
- int devnum = minor >> 1;
- struct mtd_info *mtd;
-
-@@ -442,81 +445,13 @@
- break;
- }
-
-- case MEMWRITEDATA:
-+ case MEMSETOOBSEL:
- {
-- struct mtd_oob_buf buf;
-- void *databuf;
-- ssize_t retlen;
--
-- if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf)))
-- return -EFAULT;
--
-- if (buf.length > 0x4096)
-- return -EINVAL;
--
-- if (!mtd->write_ecc)
-- ret = -EOPNOTSUPP;
-- else
-- ret = verify_area(VERIFY_READ, (char *)buf.ptr, buf.length);
--
-- if (ret)
-- return ret;
--
-- databuf = kmalloc(buf.length, GFP_KERNEL);
-- if (!databuf)
-- return -ENOMEM;
--
-- if (copy_from_user(databuf, buf.ptr, buf.length)) {
-- kfree(databuf);
-+ if (copy_from_user(&mtd->oobinfo ,(void *)arg, sizeof(struct nand_oobinfo)))
- return -EFAULT;
-- }
--
-- ret = (mtd->write_ecc)(mtd, buf.start, buf.length, &retlen, databuf, NULL, 0);
--
-- if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t)))
-- ret = -EFAULT;
--
-- kfree(databuf);
- break;
--
- }
-
-- case MEMREADDATA:
-- {
-- struct mtd_oob_buf buf;
-- void *databuf;
-- ssize_t retlen = 0;
--
-- if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf)))
-- return -EFAULT;
--
-- if (buf.length > 0x4096)
-- return -EINVAL;
--
-- if (!mtd->read_ecc)
-- ret = -EOPNOTSUPP;
-- else
-- ret = verify_area(VERIFY_WRITE, (char *)buf.ptr, buf.length);
--
-- if (ret)
-- return ret;
--
-- databuf = kmalloc(buf.length, GFP_KERNEL);
-- if (!databuf)
-- return -ENOMEM;
--
-- ret = (mtd->read_ecc)(mtd, buf.start, buf.length, &retlen, databuf, NULL, 0);
--
-- if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t)))
-- ret = -EFAULT;
-- else if (retlen && copy_to_user(buf.ptr, databuf, retlen))
-- ret = -EFAULT;
--
-- kfree(databuf);
-- break;
-- }
--
--
- default:
- DEBUG(MTD_DEBUG_LEVEL0, "Invalid ioctl %x (MEMGETINFO = %x)\n", cmd, MEMGETINFO);
- ret = -ENOTTY;
-@@ -526,13 +461,13 @@
- } /* memory_ioctl */
-
- static struct file_operations mtd_fops = {
-- owner: THIS_MODULE,
-- llseek: mtd_lseek, /* lseek */
-- read: mtd_read, /* read */
-- write: mtd_write, /* write */
-- ioctl: mtd_ioctl, /* ioctl */
-- open: mtd_open, /* open */
-- release: mtd_close, /* release */
-+ .owner = THIS_MODULE,
-+ .llseek = mtd_lseek,
-+ .read = mtd_read,
-+ .write = mtd_write,
-+ .ioctl = mtd_ioctl,
-+ .open = mtd_open,
-+ .release = mtd_close,
- };
-
-
-@@ -572,26 +507,18 @@
-
- static int __init init_mtdchar(void)
- {
--#ifdef CONFIG_DEVFS_FS
-- if (devfs_register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops))
-+ if (register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops))
- {
- printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
- MTD_CHAR_MAJOR);
- return -EAGAIN;
- }
-
-+#ifdef CONFIG_DEVFS_FS
- devfs_dir_handle = devfs_mk_dir(NULL, "mtd", NULL);
-
- register_mtd_user(&notifier);
--#else
-- if (register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops))
-- {
-- printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
-- MTD_CHAR_MAJOR);
-- return -EAGAIN;
-- }
- #endif
--
- return 0;
- }
-
-@@ -600,10 +527,8 @@
- #ifdef CONFIG_DEVFS_FS
- unregister_mtd_user(&notifier);
- devfs_unregister(devfs_dir_handle);
-- devfs_unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
--#else
-- unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
- #endif
-+ unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
- }
-
- module_init(init_mtdchar);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/mtdconcat.c linux/drivers/mtd/mtdconcat.c
---- linux-mips-2.4.24-pre2/drivers/mtd/mtdconcat.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/mtdconcat.c 2004-11-17 18:17:58.860341128 +0100
-@@ -3,9 +3,11 @@
- *
- * (C) 2002 Robert Kaiser <rkaiser@sysgo.de>
- *
-+ * NAND support by Christian Gan <cgan@iders.ca>
-+ *
- * This code is GPL
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/module.h>
-@@ -35,21 +37,20 @@
- #define SIZEOF_STRUCT_MTD_CONCAT(num_subdev) \
- ((sizeof(struct mtd_concat) + (num_subdev) * sizeof(struct mtd_info *)))
-
--
- /*
- * Given a pointer to the MTD object in the mtd_concat structure,
- * we can retrieve the pointer to that structure with this macro.
- */
- #define CONCAT(x) ((struct mtd_concat *)(x))
-
--
- /*
- * MTD methods which look up the relevant subdevice, translate the
- * effective address and pass through to the subdevice.
- */
-
--static int concat_read (struct mtd_info *mtd, loff_t from, size_t len,
-- size_t *retlen, u_char *buf)
-+static int
-+concat_read(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t * retlen, u_char * buf)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- int err = -EINVAL;
-@@ -57,43 +58,43 @@
-
- *retlen = 0;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- size_t size, retsize;
-
-- if (from >= subdev->size)
-- {
-+ if (from >= subdev->size) {
-+ /* Not destined for this subdev */
- size = 0;
- from -= subdev->size;
-+ continue;
- }
-- else
-- {
- if (from + len > subdev->size)
-+ /* First part goes into this subdev */
- size = subdev->size - from;
- else
-+ /* Entire transaction goes into this subdev */
- size = len;
-
- err = subdev->read(subdev, from, size, &retsize, buf);
-
-- if(err)
-+ if (err)
- break;
-
- *retlen += retsize;
- len -= size;
-- if(len == 0)
-+ if (len == 0)
- break;
-
- err = -EINVAL;
- buf += size;
- from = 0;
- }
-- }
- return err;
- }
-
--static int concat_write (struct mtd_info *mtd, loff_t to, size_t len,
-- size_t *retlen, const u_char *buf)
-+static int
-+concat_write(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t * retlen, const u_char * buf)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- int err = -EINVAL;
-@@ -104,18 +105,15 @@
-
- *retlen = 0;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- size_t size, retsize;
-
-- if (to >= subdev->size)
-- {
-+ if (to >= subdev->size) {
- size = 0;
- to -= subdev->size;
-+ continue;
- }
-- else
-- {
- if (to + len > subdev->size)
- size = subdev->size - to;
- else
-@@ -126,25 +124,232 @@
- else
- err = subdev->write(subdev, to, size, &retsize, buf);
-
-- if(err)
-+ if (err)
- break;
-
- *retlen += retsize;
- len -= size;
-- if(len == 0)
-+ if (len == 0)
- break;
-
- err = -EINVAL;
- buf += size;
- to = 0;
- }
-+ return err;
-+}
-+
-+static int
-+concat_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t * retlen, u_char * buf, u_char * eccbuf,
-+ struct nand_oobinfo *oobsel)
-+{
-+ struct mtd_concat *concat = CONCAT(mtd);
-+ int err = -EINVAL;
-+ int i;
-+
-+ *retlen = 0;
-+
-+ for (i = 0; i < concat->num_subdev; i++) {
-+ struct mtd_info *subdev = concat->subdev[i];
-+ size_t size, retsize;
-+
-+ if (from >= subdev->size) {
-+ /* Not destined for this subdev */
-+ size = 0;
-+ from -= subdev->size;
-+ continue;
-+ }
-+
-+ if (from + len > subdev->size)
-+ /* First part goes into this subdev */
-+ size = subdev->size - from;
-+ else
-+ /* Entire transaction goes into this subdev */
-+ size = len;
-+
-+ if (subdev->read_ecc)
-+ err = subdev->read_ecc(subdev, from, size,
-+ &retsize, buf, eccbuf, oobsel);
-+ else
-+ err = -EINVAL;
-+
-+ if (err)
-+ break;
-+
-+ *retlen += retsize;
-+ len -= size;
-+ if (len == 0)
-+ break;
-+
-+ err = -EINVAL;
-+ buf += size;
-+ if (eccbuf) {
-+ eccbuf += subdev->oobsize;
-+ /* in nand.c at least, eccbufs are
-+ tagged with 2 (int)eccstatus'; we
-+ must account for these */
-+ eccbuf += 2 * (sizeof (int));
-+ }
-+ from = 0;
- }
- return err;
- }
-
--static void concat_erase_callback (struct erase_info *instr)
-+static int
-+concat_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t * retlen, const u_char * buf, u_char * eccbuf,
-+ struct nand_oobinfo *oobsel)
- {
-- wake_up((wait_queue_head_t *)instr->priv);
-+ struct mtd_concat *concat = CONCAT(mtd);
-+ int err = -EINVAL;
-+ int i;
-+
-+ if (!(mtd->flags & MTD_WRITEABLE))
-+ return -EROFS;
-+
-+ *retlen = 0;
-+
-+ for (i = 0; i < concat->num_subdev; i++) {
-+ struct mtd_info *subdev = concat->subdev[i];
-+ size_t size, retsize;
-+
-+ if (to >= subdev->size) {
-+ size = 0;
-+ to -= subdev->size;
-+ continue;
-+ }
-+ if (to + len > subdev->size)
-+ size = subdev->size - to;
-+ else
-+ size = len;
-+
-+ if (!(subdev->flags & MTD_WRITEABLE))
-+ err = -EROFS;
-+ else if (subdev->write_ecc)
-+ err = subdev->write_ecc(subdev, to, size,
-+ &retsize, buf, eccbuf, oobsel);
-+ else
-+ err = -EINVAL;
-+
-+ if (err)
-+ break;
-+
-+ *retlen += retsize;
-+ len -= size;
-+ if (len == 0)
-+ break;
-+
-+ err = -EINVAL;
-+ buf += size;
-+ if (eccbuf)
-+ eccbuf += subdev->oobsize;
-+ to = 0;
-+ }
-+ return err;
-+}
-+
-+static int
-+concat_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t * retlen, u_char * buf)
-+{
-+ struct mtd_concat *concat = CONCAT(mtd);
-+ int err = -EINVAL;
-+ int i;
-+
-+ *retlen = 0;
-+
-+ for (i = 0; i < concat->num_subdev; i++) {
-+ struct mtd_info *subdev = concat->subdev[i];
-+ size_t size, retsize;
-+
-+ if (from >= subdev->size) {
-+ /* Not destined for this subdev */
-+ size = 0;
-+ from -= subdev->size;
-+ continue;
-+ }
-+ if (from + len > subdev->size)
-+ /* First part goes into this subdev */
-+ size = subdev->size - from;
-+ else
-+ /* Entire transaction goes into this subdev */
-+ size = len;
-+
-+ if (subdev->read_oob)
-+ err = subdev->read_oob(subdev, from, size,
-+ &retsize, buf);
-+ else
-+ err = -EINVAL;
-+
-+ if (err)
-+ break;
-+
-+ *retlen += retsize;
-+ len -= size;
-+ if (len == 0)
-+ break;
-+
-+ err = -EINVAL;
-+ buf += size;
-+ from = 0;
-+ }
-+ return err;
-+}
-+
-+static int
-+concat_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t * retlen, const u_char * buf)
-+{
-+ struct mtd_concat *concat = CONCAT(mtd);
-+ int err = -EINVAL;
-+ int i;
-+
-+ if (!(mtd->flags & MTD_WRITEABLE))
-+ return -EROFS;
-+
-+ *retlen = 0;
-+
-+ for (i = 0; i < concat->num_subdev; i++) {
-+ struct mtd_info *subdev = concat->subdev[i];
-+ size_t size, retsize;
-+
-+ if (to >= subdev->size) {
-+ size = 0;
-+ to -= subdev->size;
-+ continue;
-+ }
-+ if (to + len > subdev->size)
-+ size = subdev->size - to;
-+ else
-+ size = len;
-+
-+ if (!(subdev->flags & MTD_WRITEABLE))
-+ err = -EROFS;
-+ else if (subdev->write_oob)
-+ err = subdev->write_oob(subdev, to, size, &retsize,
-+ buf);
-+ else
-+ err = -EINVAL;
-+
-+ if (err)
-+ break;
-+
-+ *retlen += retsize;
-+ len -= size;
-+ if (len == 0)
-+ break;
-+
-+ err = -EINVAL;
-+ buf += size;
-+ to = 0;
-+ }
-+ return err;
-+}
-+
-+static void concat_erase_callback(struct erase_info *instr)
-+{
-+ wake_up((wait_queue_head_t *) instr->priv);
- }
-
- static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase)
-@@ -160,18 +365,18 @@
-
- erase->mtd = mtd;
- erase->callback = concat_erase_callback;
-- erase->priv = (unsigned long)&waitq;
-+ erase->priv = (unsigned long) &waitq;
-
- /*
- * FIXME: Allow INTERRUPTIBLE. Which means
- * not having the wait_queue head on the stack.
- */
- err = mtd->erase(mtd, erase);
-- if (!err)
-- {
-+ if (!err) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&waitq, &wait);
-- if (erase->state != MTD_ERASE_DONE && erase->state != MTD_ERASE_FAILED)
-+ if (erase->state != MTD_ERASE_DONE
-+ && erase->state != MTD_ERASE_FAILED)
- schedule();
- remove_wait_queue(&waitq, &wait);
- set_current_state(TASK_RUNNING);
-@@ -181,7 +386,7 @@
- return err;
- }
-
--static int concat_erase (struct mtd_info *mtd, struct erase_info *instr)
-+static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- struct mtd_info *subdev;
-@@ -192,10 +397,10 @@
- if (!(mtd->flags & MTD_WRITEABLE))
- return -EROFS;
-
-- if(instr->addr > concat->mtd.size)
-+ if (instr->addr > concat->mtd.size)
- return -EINVAL;
-
-- if(instr->len + instr->addr > concat->mtd.size)
-+ if (instr->len + instr->addr > concat->mtd.size)
- return -EINVAL;
-
- /*
-@@ -204,23 +409,22 @@
- * region info rather than looking at each particular sub-device
- * in turn.
- */
-- if (!concat->mtd.numeraseregions)
-- { /* the easy case: device has uniform erase block size */
-- if(instr->addr & (concat->mtd.erasesize - 1))
-+ if (!concat->mtd.numeraseregions) {
-+ /* the easy case: device has uniform erase block size */
-+ if (instr->addr & (concat->mtd.erasesize - 1))
- return -EINVAL;
-- if(instr->len & (concat->mtd.erasesize - 1))
-+ if (instr->len & (concat->mtd.erasesize - 1))
- return -EINVAL;
-- }
-- else
-- { /* device has variable erase size */
-- struct mtd_erase_region_info *erase_regions = concat->mtd.eraseregions;
-+ } else {
-+ /* device has variable erase size */
-+ struct mtd_erase_region_info *erase_regions =
-+ concat->mtd.eraseregions;
-
- /*
- * Find the erase region where the to-be-erased area begins:
- */
-- for(i = 0; i < concat->mtd.numeraseregions &&
-- instr->addr >= erase_regions[i].offset; i++)
-- ;
-+ for (i = 0; i < concat->mtd.numeraseregions &&
-+ instr->addr >= erase_regions[i].offset; i++) ;
- --i;
-
- /*
-@@ -228,25 +432,26 @@
- * to-be-erased area begins. Verify that the starting
- * offset is aligned to this region's erase size:
- */
-- if (instr->addr & (erase_regions[i].erasesize-1))
-+ if (instr->addr & (erase_regions[i].erasesize - 1))
- return -EINVAL;
-
- /*
- * now find the erase region where the to-be-erased area ends:
- */
-- for(; i < concat->mtd.numeraseregions &&
-- (instr->addr + instr->len) >= erase_regions[i].offset ; ++i)
-- ;
-+ for (; i < concat->mtd.numeraseregions &&
-+ (instr->addr + instr->len) >= erase_regions[i].offset;
-+ ++i) ;
- --i;
- /*
- * check if the ending offset is aligned to this region's erase size
- */
-- if ((instr->addr + instr->len) & (erase_regions[i].erasesize-1))
-+ if ((instr->addr + instr->len) & (erase_regions[i].erasesize -
-+ 1))
- return -EINVAL;
- }
-
- /* make a local copy of instr to avoid modifying the caller's struct */
-- erase = kmalloc(sizeof(struct erase_info),GFP_KERNEL);
-+ erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL);
-
- if (!erase)
- return -ENOMEM;
-@@ -258,39 +463,40 @@
- * find the subdevice where the to-be-erased area begins, adjust
- * starting offset to be relative to the subdevice start
- */
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- subdev = concat->subdev[i];
-- if(subdev->size <= erase->addr)
-+ if (subdev->size <= erase->addr)
- erase->addr -= subdev->size;
- else
- break;
- }
-- if(i >= concat->num_subdev) /* must never happen since size */
-- BUG(); /* limit has been verified above */
-+
-+ /* must never happen since size limit has been verified above */
-+ if (i >= concat->num_subdev)
-+ BUG();
-
- /* now do the erase: */
- err = 0;
-- for(;length > 0; i++) /* loop for all subevices affected by this request */
-- {
-+ for (; length > 0; i++) {
-+ /* loop for all subdevices affected by this request */
- subdev = concat->subdev[i]; /* get current subdevice */
-
- /* limit length to subdevice's size: */
-- if(erase->addr + length > subdev->size)
-+ if (erase->addr + length > subdev->size)
- erase->len = subdev->size - erase->addr;
- else
- erase->len = length;
-
-- if (!(subdev->flags & MTD_WRITEABLE))
-- {
-+ if (!(subdev->flags & MTD_WRITEABLE)) {
- err = -EROFS;
- break;
- }
- length -= erase->len;
-- if ((err = concat_dev_erase(subdev, erase)))
-- {
-- if(err == -EINVAL) /* sanity check: must never happen since */
-- BUG(); /* block alignment has been checked above */
-+ if ((err = concat_dev_erase(subdev, erase))) {
-+ /* sanity check: should never happen since
-+ * block alignment has been checked above */
-+ if (err == -EINVAL)
-+ BUG();
- break;
- }
- /*
-@@ -313,7 +519,7 @@
- return 0;
- }
-
--static int concat_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
-+static int concat_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- int i, err = -EINVAL;
-@@ -321,18 +527,15 @@
- if ((len + ofs) > mtd->size)
- return -EINVAL;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- size_t size;
-
-- if (ofs >= subdev->size)
-- {
-+ if (ofs >= subdev->size) {
- size = 0;
- ofs -= subdev->size;
-+ continue;
- }
-- else
-- {
- if (ofs + len > subdev->size)
- size = subdev->size - ofs;
- else
-@@ -340,21 +543,21 @@
-
- err = subdev->lock(subdev, ofs, size);
-
-- if(err)
-+ if (err)
- break;
-
- len -= size;
-- if(len == 0)
-+ if (len == 0)
- break;
-
- err = -EINVAL;
- ofs = 0;
- }
-- }
-+
- return err;
- }
-
--static int concat_unlock (struct mtd_info *mtd, loff_t ofs, size_t len)
-+static int concat_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- int i, err = 0;
-@@ -362,18 +565,15 @@
- if ((len + ofs) > mtd->size)
- return -EINVAL;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- size_t size;
-
-- if (ofs >= subdev->size)
-- {
-+ if (ofs >= subdev->size) {
- size = 0;
- ofs -= subdev->size;
-+ continue;
- }
-- else
-- {
- if (ofs + len > subdev->size)
- size = subdev->size - ofs;
- else
-@@ -381,17 +581,17 @@
-
- err = subdev->unlock(subdev, ofs, size);
-
-- if(err)
-+ if (err)
- break;
-
- len -= size;
-- if(len == 0)
-+ if (len == 0)
- break;
-
- err = -EINVAL;
- ofs = 0;
- }
-- }
-+
- return err;
- }
-
-@@ -400,8 +600,7 @@
- struct mtd_concat *concat = CONCAT(mtd);
- int i;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- subdev->sync(subdev);
- }
-@@ -412,10 +611,9 @@
- struct mtd_concat *concat = CONCAT(mtd);
- int i, rc = 0;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
-- if((rc = subdev->suspend(subdev)) < 0)
-+ if ((rc = subdev->suspend(subdev)) < 0)
- return rc;
- }
- return rc;
-@@ -426,8 +624,7 @@
- struct mtd_concat *concat = CONCAT(mtd);
- int i;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- subdev->resume(subdev);
- }
-@@ -439,11 +636,10 @@
- * stored to *new_dev upon success. This function does _not_
- * register any devices: this is the caller's responsibility.
- */
--struct mtd_info *mtd_concat_create(
-- struct mtd_info *subdev[], /* subdevices to concatenate */
-+struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to concatenate */
- int num_devs, /* number of subdevices */
-- char *name) /* name for the new device */
--{
-+ char *name)
-+{ /* name for the new device */
- int i;
- size_t size;
- struct mtd_concat *concat;
-@@ -451,21 +647,21 @@
- int num_erase_region;
-
- printk(KERN_NOTICE "Concatenating MTD devices:\n");
-- for(i = 0; i < num_devs; i++)
-+ for (i = 0; i < num_devs; i++)
- printk(KERN_NOTICE "(%d): \"%s\"\n", i, subdev[i]->name);
- printk(KERN_NOTICE "into device \"%s\"\n", name);
-
- /* allocate the device structure */
- size = SIZEOF_STRUCT_MTD_CONCAT(num_devs);
-- concat = kmalloc (size, GFP_KERNEL);
-- if(!concat)
-- {
-- printk ("memory allocation error while creating concatenated device \"%s\"\n",
-+ concat = kmalloc(size, GFP_KERNEL);
-+ if (!concat) {
-+ printk
-+ ("memory allocation error while creating concatenated device \"%s\"\n",
- name);
- return NULL;
- }
- memset(concat, 0, size);
-- concat->subdev = (struct mtd_info **)(concat + 1);
-+ concat->subdev = (struct mtd_info **) (concat + 1);
-
- /*
- * Set up the new "super" device's MTD object structure, check for
-@@ -479,39 +675,53 @@
- concat->mtd.oobsize = subdev[0]->oobsize;
- concat->mtd.ecctype = subdev[0]->ecctype;
- concat->mtd.eccsize = subdev[0]->eccsize;
-+ if (subdev[0]->read_ecc)
-+ concat->mtd.read_ecc = concat_read_ecc;
-+ if (subdev[0]->write_ecc)
-+ concat->mtd.write_ecc = concat_write_ecc;
-+ if (subdev[0]->read_oob)
-+ concat->mtd.read_oob = concat_read_oob;
-+ if (subdev[0]->write_oob)
-+ concat->mtd.write_oob = concat_write_oob;
-
- concat->subdev[0] = subdev[0];
-
-- for(i = 1; i < num_devs; i++)
-- {
-- if(concat->mtd.type != subdev[i]->type)
-- {
-+ for (i = 1; i < num_devs; i++) {
-+ if (concat->mtd.type != subdev[i]->type) {
- kfree(concat);
-- printk ("Incompatible device type on \"%s\"\n", subdev[i]->name);
-+ printk("Incompatible device type on \"%s\"\n",
-+ subdev[i]->name);
- return NULL;
- }
-- if(concat->mtd.flags != subdev[i]->flags)
-- { /*
-- * Expect all flags except MTD_WRITEABLE to be equal on
-- * all subdevices.
-+ if (concat->mtd.flags != subdev[i]->flags) {
-+ /*
-+ * Expect all flags except MTD_WRITEABLE to be
-+ * equal on all subdevices.
- */
-- if((concat->mtd.flags ^ subdev[i]->flags) & ~MTD_WRITEABLE)
-- {
-+ if ((concat->mtd.flags ^ subdev[i]->
-+ flags) & ~MTD_WRITEABLE) {
- kfree(concat);
-- printk ("Incompatible device flags on \"%s\"\n", subdev[i]->name);
-+ printk("Incompatible device flags on \"%s\"\n",
-+ subdev[i]->name);
- return NULL;
-- }
-- else /* if writeable attribute differs, make super device writeable */
-- concat->mtd.flags |= subdev[i]->flags & MTD_WRITEABLE;
-+ } else
-+ /* if writeable attribute differs,
-+ make super device writeable */
-+ concat->mtd.flags |=
-+ subdev[i]->flags & MTD_WRITEABLE;
- }
- concat->mtd.size += subdev[i]->size;
-- if(concat->mtd.oobblock != subdev[i]->oobblock ||
-+ if (concat->mtd.oobblock != subdev[i]->oobblock ||
- concat->mtd.oobsize != subdev[i]->oobsize ||
- concat->mtd.ecctype != subdev[i]->ecctype ||
-- concat->mtd.eccsize != subdev[i]->eccsize)
-- {
-+ concat->mtd.eccsize != subdev[i]->eccsize ||
-+ !concat->mtd.read_ecc != !subdev[i]->read_ecc ||
-+ !concat->mtd.write_ecc != !subdev[i]->write_ecc ||
-+ !concat->mtd.read_oob != !subdev[i]->read_oob ||
-+ !concat->mtd.write_oob != !subdev[i]->write_oob) {
- kfree(concat);
-- printk ("Incompatible OOB or ECC data on \"%s\"\n", subdev[i]->name);
-+ printk("Incompatible OOB or ECC data on \"%s\"\n",
-+ subdev[i]->name);
- return NULL;
- }
- concat->subdev[i] = subdev[i];
-@@ -535,7 +745,6 @@
- concat->mtd.suspend = concat_suspend;
- concat->mtd.resume = concat_resume;
-
--
- /*
- * Combine the erase block size info of the subdevices:
- *
-@@ -544,44 +753,44 @@
- */
- max_erasesize = curr_erasesize = subdev[0]->erasesize;
- num_erase_region = 1;
-- for(i = 0; i < num_devs; i++)
-- {
-- if(subdev[i]->numeraseregions == 0)
-- { /* current subdevice has uniform erase size */
-- if(subdev[i]->erasesize != curr_erasesize)
-- { /* if it differs from the last subdevice's erase size, count it */
-+ for (i = 0; i < num_devs; i++) {
-+ if (subdev[i]->numeraseregions == 0) {
-+ /* current subdevice has uniform erase size */
-+ if (subdev[i]->erasesize != curr_erasesize) {
-+ /* if it differs from the last subdevice's erase size, count it */
- ++num_erase_region;
- curr_erasesize = subdev[i]->erasesize;
-- if(curr_erasesize > max_erasesize)
-+ if (curr_erasesize > max_erasesize)
- max_erasesize = curr_erasesize;
- }
-- }
-- else
-- { /* current subdevice has variable erase size */
-+ } else {
-+ /* current subdevice has variable erase size */
- int j;
-- for(j = 0; j < subdev[i]->numeraseregions; j++)
-- { /* walk the list of erase regions, count any changes */
-- if(subdev[i]->eraseregions[j].erasesize != curr_erasesize)
-- {
-+ for (j = 0; j < subdev[i]->numeraseregions; j++) {
-+
-+ /* walk the list of erase regions, count any changes */
-+ if (subdev[i]->eraseregions[j].erasesize !=
-+ curr_erasesize) {
- ++num_erase_region;
-- curr_erasesize = subdev[i]->eraseregions[j].erasesize;
-- if(curr_erasesize > max_erasesize)
-+ curr_erasesize =
-+ subdev[i]->eraseregions[j].
-+ erasesize;
-+ if (curr_erasesize > max_erasesize)
- max_erasesize = curr_erasesize;
- }
- }
- }
- }
-
-- if(num_erase_region == 1)
-- { /*
-+ if (num_erase_region == 1) {
-+ /*
- * All subdevices have the same uniform erase size.
- * This is easy:
- */
- concat->mtd.erasesize = curr_erasesize;
- concat->mtd.numeraseregions = 0;
-- }
-- else
-- { /*
-+ } else {
-+ /*
- * erase block size varies across the subdevices: allocate
- * space to store the data describing the variable erase regions
- */
-@@ -590,12 +799,13 @@
-
- concat->mtd.erasesize = max_erasesize;
- concat->mtd.numeraseregions = num_erase_region;
-- concat->mtd.eraseregions = erase_region_p = kmalloc (
-- num_erase_region * sizeof(struct mtd_erase_region_info), GFP_KERNEL);
-- if(!erase_region_p)
-- {
-+ concat->mtd.eraseregions = erase_region_p =
-+ kmalloc(num_erase_region *
-+ sizeof (struct mtd_erase_region_info), GFP_KERNEL);
-+ if (!erase_region_p) {
- kfree(concat);
-- printk ("memory allocation error while creating erase region list"
-+ printk
-+ ("memory allocation error while creating erase region list"
- " for device \"%s\"\n", name);
- return NULL;
- }
-@@ -606,41 +816,48 @@
- */
- curr_erasesize = subdev[0]->erasesize;
- begin = position = 0;
-- for(i = 0; i < num_devs; i++)
-- {
-- if(subdev[i]->numeraseregions == 0)
-- { /* current subdevice has uniform erase size */
-- if(subdev[i]->erasesize != curr_erasesize)
-- { /*
-+ for (i = 0; i < num_devs; i++) {
-+ if (subdev[i]->numeraseregions == 0) {
-+ /* current subdevice has uniform erase size */
-+ if (subdev[i]->erasesize != curr_erasesize) {
-+ /*
- * fill in an mtd_erase_region_info structure for the area
- * we have walked so far:
- */
- erase_region_p->offset = begin;
-- erase_region_p->erasesize = curr_erasesize;
-- erase_region_p->numblocks = (position - begin) / curr_erasesize;
-+ erase_region_p->erasesize =
-+ curr_erasesize;
-+ erase_region_p->numblocks =
-+ (position - begin) / curr_erasesize;
- begin = position;
-
- curr_erasesize = subdev[i]->erasesize;
- ++erase_region_p;
- }
- position += subdev[i]->size;
-- }
-- else
-- { /* current subdevice has variable erase size */
-+ } else {
-+ /* current subdevice has variable erase size */
- int j;
-- for(j = 0; j < subdev[i]->numeraseregions; j++)
-- { /* walk the list of erase regions, count any changes */
-- if(subdev[i]->eraseregions[j].erasesize != curr_erasesize)
-- {
-+ for (j = 0; j < subdev[i]->numeraseregions; j++) {
-+ /* walk the list of erase regions, count any changes */
-+ if (subdev[i]->eraseregions[j].
-+ erasesize != curr_erasesize) {
- erase_region_p->offset = begin;
-- erase_region_p->erasesize = curr_erasesize;
-- erase_region_p->numblocks = (position - begin) / curr_erasesize;
-+ erase_region_p->erasesize =
-+ curr_erasesize;
-+ erase_region_p->numblocks =
-+ (position -
-+ begin) / curr_erasesize;
- begin = position;
-
-- curr_erasesize = subdev[i]->eraseregions[j].erasesize;
-+ curr_erasesize =
-+ subdev[i]->eraseregions[j].
-+ erasesize;
- ++erase_region_p;
- }
-- position += subdev[i]->eraseregions[j].numblocks * curr_erasesize;
-+ position +=
-+ subdev[i]->eraseregions[j].
-+ numblocks * curr_erasesize;
- }
- }
- }
-@@ -660,16 +877,14 @@
- void mtd_concat_destroy(struct mtd_info *mtd)
- {
- struct mtd_concat *concat = CONCAT(mtd);
-- if(concat->mtd.numeraseregions)
-+ if (concat->mtd.numeraseregions)
- kfree(concat->mtd.eraseregions);
- kfree(concat);
- }
-
--
- EXPORT_SYMBOL(mtd_concat_create);
- EXPORT_SYMBOL(mtd_concat_destroy);
-
--
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Robert Kaiser <rkaiser@sysgo.de>");
- MODULE_DESCRIPTION("Generic support for concatenating of MTD devices");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/mtdcore.c linux/drivers/mtd/mtdcore.c
---- linux-mips-2.4.24-pre2/drivers/mtd/mtdcore.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/mtdcore.c 2004-11-17 18:17:58.862340824 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Core registration and callback routines for MTD
- * drivers and users.
-@@ -17,6 +17,7 @@
- #include <linux/major.h>
- #include <linux/fs.h>
- #include <linux/ioctl.h>
-+#include <linux/init.h>
- #include <linux/mtd/compatmac.h>
- #ifdef CONFIG_PROC_FS
- #include <linux/proc_fs.h>
-@@ -24,9 +25,15 @@
-
- #include <linux/mtd/mtd.h>
-
--static DECLARE_MUTEX(mtd_table_mutex);
--static struct mtd_info *mtd_table[MAX_MTD_DEVICES];
--static struct mtd_notifier *mtd_notifiers = NULL;
-+/* These are exported solely for the purpose of mtd_blkdevs.c. You
-+ should not use them for _anything_ else */
-+DECLARE_MUTEX(mtd_table_mutex);
-+struct mtd_info *mtd_table[MAX_MTD_DEVICES];
-+
-+EXPORT_SYMBOL_GPL(mtd_table_mutex);
-+EXPORT_SYMBOL_GPL(mtd_table);
-+
-+static LIST_HEAD(mtd_notifiers);
-
- /**
- * add_mtd_device - register an MTD device
-@@ -44,21 +51,28 @@
-
- down(&mtd_table_mutex);
-
-- for (i=0; i< MAX_MTD_DEVICES; i++)
-- if (!mtd_table[i])
-- {
-- struct mtd_notifier *not=mtd_notifiers;
-+ for (i=0; i < MAX_MTD_DEVICES; i++)
-+ if (!mtd_table[i]) {
-+ struct list_head *this;
-
- mtd_table[i] = mtd;
- mtd->index = i;
-+ mtd->usecount = 0;
-+
- DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name);
-- while (not)
-- {
-- (*(not->add))(mtd);
-- not = not->next;
-+ /* No need to get a refcount on the module containing
-+ the notifier, since we hold the mtd_table_mutex */
-+ list_for_each(this, &mtd_notifiers) {
-+ struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);
-+ not->add(mtd);
- }
-+
- up(&mtd_table_mutex);
-- MOD_INC_USE_COUNT;
-+ /* We _know_ we aren't being removed, because
-+ our caller is still holding us here. So none
-+ of this try_ nonsense, and no bitching about it
-+ either. :) */
-+ __module_get(THIS_MODULE);
- return 0;
- }
-
-@@ -78,29 +92,34 @@
-
- int del_mtd_device (struct mtd_info *mtd)
- {
-- struct mtd_notifier *not=mtd_notifiers;
-- int i;
-+ int ret;
-
- down(&mtd_table_mutex);
-
-- for (i=0; i < MAX_MTD_DEVICES; i++)
-- {
-- if (mtd_table[i] == mtd)
-- {
-- while (not)
-- {
-- (*(not->remove))(mtd);
-- not = not->next;
-- }
-- mtd_table[i] = NULL;
-- up (&mtd_table_mutex);
-- MOD_DEC_USE_COUNT;
-- return 0;
-+ if (mtd_table[mtd->index] != mtd) {
-+ ret = -ENODEV;
-+ } else if (mtd->usecount) {
-+ printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n",
-+ mtd->index, mtd->name, mtd->usecount);
-+ ret = -EBUSY;
-+ } else {
-+ struct list_head *this;
-+
-+ /* No need to get a refcount on the module containing
-+ the notifier, since we hold the mtd_table_mutex */
-+ list_for_each(this, &mtd_notifiers) {
-+ struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);
-+ not->remove(mtd);
- }
-+
-+ mtd_table[mtd->index] = NULL;
-+
-+ module_put(THIS_MODULE);
-+ ret = 0;
- }
-
- up(&mtd_table_mutex);
-- return 1;
-+ return ret;
- }
-
- /**
-@@ -118,10 +137,9 @@
-
- down(&mtd_table_mutex);
-
-- new->next = mtd_notifiers;
-- mtd_notifiers = new;
-+ list_add(&new->list, &mtd_notifiers);
-
-- MOD_INC_USE_COUNT;
-+ __module_get(THIS_MODULE);
-
- for (i=0; i< MAX_MTD_DEVICES; i++)
- if (mtd_table[i])
-@@ -142,34 +160,24 @@
-
- int unregister_mtd_user (struct mtd_notifier *old)
- {
-- struct mtd_notifier **prev = &mtd_notifiers;
-- struct mtd_notifier *cur;
- int i;
-
- down(&mtd_table_mutex);
-
-- while ((cur = *prev)) {
-- if (cur == old) {
-- *prev = cur->next;
--
-- MOD_DEC_USE_COUNT;
-+ module_put(THIS_MODULE);
-
- for (i=0; i< MAX_MTD_DEVICES; i++)
- if (mtd_table[i])
- old->remove(mtd_table[i]);
-
-+ list_del(&old->list);
- up(&mtd_table_mutex);
- return 0;
-- }
-- prev = &cur->next;
-- }
-- up(&mtd_table_mutex);
-- return 1;
- }
-
-
- /**
-- * __get_mtd_device - obtain a validated handle for an MTD device
-+ * get_mtd_device - obtain a validated handle for an MTD device
- * @mtd: last known address of the required MTD device
- * @num: internal device number of the required MTD device
- *
-@@ -177,11 +185,10 @@
- * table, if any. Given an address and num == -1, search the device table
- * for a device with that address and return if it's still present. Given
- * both, return the num'th driver only if its address matches. Return NULL
-- * if not. get_mtd_device() increases the use count, but
-- * __get_mtd_device() doesn't - you should generally use get_mtd_device().
-+ * if not.
- */
-
--struct mtd_info *__get_mtd_device(struct mtd_info *mtd, int num)
-+struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
- {
- struct mtd_info *ret = NULL;
- int i;
-@@ -198,10 +205,27 @@
- ret = NULL;
- }
-
-+ if (ret && !try_module_get(ret->owner))
-+ ret = NULL;
-+
-+ if (ret)
-+ ret->usecount++;
-+
- up(&mtd_table_mutex);
- return ret;
- }
-
-+void put_mtd_device(struct mtd_info *mtd)
-+{
-+ int c;
-+
-+ down(&mtd_table_mutex);
-+ c = --mtd->usecount;
-+ up(&mtd_table_mutex);
-+ BUG_ON(c < 0);
-+
-+ module_put(mtd->owner);
-+}
-
- /* default_mtd_writev - default mtd writev method for MTD devices that
- * dont implement their own
-@@ -265,7 +289,8 @@
-
- EXPORT_SYMBOL(add_mtd_device);
- EXPORT_SYMBOL(del_mtd_device);
--EXPORT_SYMBOL(__get_mtd_device);
-+EXPORT_SYMBOL(get_mtd_device);
-+EXPORT_SYMBOL(put_mtd_device);
- EXPORT_SYMBOL(register_mtd_user);
- EXPORT_SYMBOL(unregister_mtd_user);
- EXPORT_SYMBOL(default_mtd_writev);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/mtdpart.c linux/drivers/mtd/mtdpart.c
---- linux-mips-2.4.24-pre2/drivers/mtd/mtdpart.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/mtdpart.c 2004-11-17 18:17:58.863340672 +0100
-@@ -5,7 +5,7 @@
- *
- * This code is GPL
- *
-- * $Id$
-+ * $Id$
- *
- * 02-21-2002 Thomas Gleixner <gleixner@autronix.de>
- * added support for read_oob, write_oob
-@@ -16,10 +16,11 @@
- #include <linux/kernel.h>
- #include <linux/slab.h>
- #include <linux/list.h>
--
-+#include <linux/config.h>
-+#include <linux/kmod.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/partitions.h>
--
-+#include <linux/mtd/compatmac.h>
-
- /* Our partition linked list */
- static LIST_HEAD(mtd_partitions);
-@@ -54,8 +55,12 @@
- len = 0;
- else if (from + len > mtd->size)
- len = mtd->size - from;
-+ if (part->master->read_ecc == NULL)
- return part->master->read (part->master, from + part->offset,
- len, retlen, buf);
-+ else
-+ return part->master->read_ecc (part->master, from + part->offset,
-+ len, retlen, buf, NULL, &mtd->oobinfo);
- }
-
- static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
-@@ -78,9 +83,11 @@
-
-
- static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
-- size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel)
-+ size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel)
- {
- struct mtd_part *part = PART(mtd);
-+ if (oobsel == NULL)
-+ oobsel = &mtd->oobinfo;
- if (from >= mtd->size)
- len = 0;
- else if (from + len > mtd->size)
-@@ -113,7 +120,7 @@
- size_t *retlen, u_char *buf)
- {
- struct mtd_part *part = PART(mtd);
-- return part->master->read_user_prot_reg (part->master, from,
-+ return part->master->read_fact_prot_reg (part->master, from,
- len, retlen, buf);
- }
-
-@@ -127,17 +134,24 @@
- len = 0;
- else if (to + len > mtd->size)
- len = mtd->size - to;
-+ if (part->master->write_ecc == NULL)
- return part->master->write (part->master, to + part->offset,
- len, retlen, buf);
-+ else
-+ return part->master->write_ecc (part->master, to + part->offset,
-+ len, retlen, buf, NULL, &mtd->oobinfo);
-+
- }
-
- static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
- size_t *retlen, const u_char *buf,
-- u_char *eccbuf, int oobsel)
-+ u_char *eccbuf, struct nand_oobinfo *oobsel)
- {
- struct mtd_part *part = PART(mtd);
- if (!(mtd->flags & MTD_WRITEABLE))
- return -EROFS;
-+ if (oobsel == NULL)
-+ oobsel = &mtd->oobinfo;
- if (to >= mtd->size)
- len = 0;
- else if (to + len > mtd->size)
-@@ -174,25 +188,37 @@
- struct mtd_part *part = PART(mtd);
- if (!(mtd->flags & MTD_WRITEABLE))
- return -EROFS;
-+ if (part->master->writev_ecc == NULL)
- return part->master->writev (part->master, vecs, count,
- to + part->offset, retlen);
-+ else
-+ return part->master->writev_ecc (part->master, vecs, count,
-+ to + part->offset, retlen,
-+ NULL, &mtd->oobinfo);
- }
-
- static int part_readv (struct mtd_info *mtd, struct iovec *vecs,
- unsigned long count, loff_t from, size_t *retlen)
- {
- struct mtd_part *part = PART(mtd);
-+ if (part->master->readv_ecc == NULL)
- return part->master->readv (part->master, vecs, count,
- from + part->offset, retlen);
-+ else
-+ return part->master->readv_ecc (part->master, vecs, count,
-+ from + part->offset, retlen,
-+ NULL, &mtd->oobinfo);
- }
-
- static int part_writev_ecc (struct mtd_info *mtd, const struct iovec *vecs,
- unsigned long count, loff_t to, size_t *retlen,
-- u_char *eccbuf, int oobsel)
-+ u_char *eccbuf, struct nand_oobinfo *oobsel)
- {
- struct mtd_part *part = PART(mtd);
- if (!(mtd->flags & MTD_WRITEABLE))
- return -EROFS;
-+ if (oobsel == NULL)
-+ oobsel = &mtd->oobinfo;
- return part->master->writev_ecc (part->master, vecs, count,
- to + part->offset, retlen,
- eccbuf, oobsel);
-@@ -200,9 +226,11 @@
-
- static int part_readv_ecc (struct mtd_info *mtd, struct iovec *vecs,
- unsigned long count, loff_t from, size_t *retlen,
-- u_char *eccbuf, int oobsel)
-+ u_char *eccbuf, struct nand_oobinfo *oobsel)
- {
- struct mtd_part *part = PART(mtd);
-+ if (oobsel == NULL)
-+ oobsel = &mtd->oobinfo;
- return part->master->readv_ecc (part->master, vecs, count,
- from + part->offset, retlen,
- eccbuf, oobsel);
-@@ -288,7 +316,7 @@
- */
-
- int add_mtd_partitions(struct mtd_info *master,
-- struct mtd_partition *parts,
-+ const struct mtd_partition *parts,
- int nbparts)
- {
- struct mtd_part *slave;
-@@ -321,7 +349,7 @@
-
- slave->mtd.name = parts[i].name;
- slave->mtd.bank_size = master->bank_size;
-- slave->mtd.module = master->module;
-+ slave->mtd.owner = master->owner;
-
- slave->mtd.read = part_read;
- slave->mtd.write = part_write;
-@@ -452,6 +480,75 @@
- EXPORT_SYMBOL(add_mtd_partitions);
- EXPORT_SYMBOL(del_mtd_partitions);
-
-+static spinlock_t part_parser_lock = SPIN_LOCK_UNLOCKED;
-+static LIST_HEAD(part_parsers);
-+
-+struct mtd_part_parser *get_partition_parser(const char *name)
-+{
-+ struct list_head *this;
-+ void *ret = NULL;
-+ spin_lock(&part_parser_lock);
-+
-+ list_for_each(this, &part_parsers) {
-+ struct mtd_part_parser *p = list_entry(this, struct mtd_part_parser, list);
-+
-+ if (!strcmp(p->name, name) && try_module_get(p->owner)) {
-+ ret = p;
-+ break;
-+ }
-+ }
-+ spin_unlock(&part_parser_lock);
-+
-+ return ret;
-+}
-+
-+int register_mtd_parser(struct mtd_part_parser *p)
-+{
-+ spin_lock(&part_parser_lock);
-+ list_add(&p->list, &part_parsers);
-+ spin_unlock(&part_parser_lock);
-+
-+ return 0;
-+}
-+
-+int deregister_mtd_parser(struct mtd_part_parser *p)
-+{
-+ spin_lock(&part_parser_lock);
-+ list_del(&p->list);
-+ spin_unlock(&part_parser_lock);
-+ return 0;
-+}
-+
-+int parse_mtd_partitions(struct mtd_info *master, const char **types,
-+ struct mtd_partition **pparts, unsigned long origin)
-+{
-+ struct mtd_part_parser *parser;
-+ int ret = 0;
-+
-+ for ( ; ret <= 0 && *types; types++) {
-+ parser = get_partition_parser(*types);
-+#ifdef CONFIG_KMOD
-+ if (!parser && !request_module("%s", *types))
-+ parser = get_partition_parser(*types);
-+#endif
-+ if (!parser) {
-+ printk(KERN_NOTICE "%s partition parsing not available\n",
-+ *types);
-+ continue;
-+ }
-+ ret = (*parser->parse_fn)(master, pparts, origin);
-+ if (ret > 0) {
-+ printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
-+ ret, parser->name, master->name);
-+ }
-+ put_partition_parser(parser);
-+ }
-+ return ret;
-+}
-+
-+EXPORT_SYMBOL_GPL(parse_mtd_partitions);
-+EXPORT_SYMBOL_GPL(register_mtd_parser);
-+EXPORT_SYMBOL_GPL(deregister_mtd_parser);
-
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/nand/Config.in linux/drivers/mtd/nand/Config.in
---- linux-mips-2.4.24-pre2/drivers/mtd/nand/Config.in 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/nand/Config.in 2004-11-17 18:17:59.159295680 +0100
-@@ -1,6 +1,6 @@
- # drivers/mtd/nand/Config.in
-
--# $Id$
-+# $Id$
-
- mainmenu_option next_comment
-
-@@ -11,26 +11,27 @@
- bool ' Verify NAND page writes' CONFIG_MTD_NAND_VERIFY_WRITE
- fi
-
--if [ "$CONFIG_ARM" = "y" -a "$CONFIG_ARCH_P720T" = "y" ]; then
-- dep_tristate ' NAND Flash device on SPIA board' CONFIG_MTD_NAND_SPIA $CONFIG_MTD_NAND
-+if [ "$CONFIG_ARM" = "y" ]; then
-+ dep_tristate ' NAND Flash device on SPIA board' CONFIG_MTD_NAND_SPIA $CONFIG_MTD_NAND $CONFIG_ARCH_P720T
-+ dep_tristate ' NAND Flash device on TOTO board' CONFIG_MTD_NAND_TOTO $CONFIG_MTD_NAND $CONFIG_ARCH_OMAP
-+ dep_tristate ' SmartMedia Card on AUTCPU12 board' CONFIG_MTD_NAND_AUTCPU12 $CONFIG_MTD_NAND $CONFIG_ARCH_AUTCPU12
-+ dep_tristate ' NAND Flash device on EDP7312 board' CONFIG_MTD_NAND_EDB7312 $CONFIG_MTD_NAND $CONFIG_ARCH_EDB7312
- fi
-
--if [ "$CONFIG_ARCH_AUTCPU12" = "y" ]; then
-- dep_tristate ' SmartMedia Card on AUTCPU12 board' CONFIG_MTD_NAND_AUTCPU12 $CONFIG_MTD_NAND
--fi
--
--if [ "$CONFIG_ARCH_EDB7312" = "y" ]; then
-- dep_tristate ' NAND Flash device on EDP7312 board' CONFIG_MTD_NAND_EDB7312 $CONFIG_MTD_NAND
--fi
--
--if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" -o "$CONFIG_MTD_NAND" = "y" ]; then
-+if [ "$CONFIG_MTD_DOC2001PLUS" = "y" -o "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" -o "$CONFIG_MTD_NAND" = "y" ]; then
- define_bool CONFIG_MTD_NAND_IDS y
-+else
-+ if [ "$CONFIG_MTD_DOC2001PLUS" = "m" -o "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" -o "$CONFIG_MTD_NAND" = "m" ]; then
-+ define_bool CONFIG_MTD_NAND_IDS m
-+ fi
- fi
-
--if [ "$CONFIG_MTD_NAND_IDS" != "y" ]; then
--if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" -o "$CONFIG_MTD_NAND" = "m" ]; then
-- define_bool CONFIG_MTD_NAND_IDS m
-+if [ "$CONFIG_TOSHIBA_RBTX4925" = "y" ]; then
-+ dep_tristate ' SmartMedia Card on Toshiba RBTX4925 reference board' CONFIG_MTD_NAND_TX4925NDFMC $CONFIG_MTD_NAND $CONFIG_TOSHIBA_RBTX4925_MPLEX_NAND
- fi
-+
-+if [ "$CONFIG_TOSHIBA_RBTX4938" = "y" ]; then
-+ dep_tristate ' NAND Flash device on Toshiba RBTX4938 reference board' CONFIG_MTD_NAND_TX4938NDFMC $CONFIG_MTD_NAND $CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND
- fi
-
- endmenu
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/nand/Makefile linux/drivers/mtd/nand/Makefile
---- linux-mips-2.4.24-pre2/drivers/mtd/nand/Makefile 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/nand/Makefile 2004-11-17 18:17:59.161295376 +0100
-@@ -1,16 +1,20 @@
- #
- # linux/drivers/nand/Makefile
- #
--# $Id$
-+# $Id$
-
-+ifeq ($(PATCHLEVEL),4)
- O_TARGET := nandlink.o
--
- export-objs := nand.o nand_ecc.o nand_ids.o
-+endif
-
- obj-$(CONFIG_MTD_NAND) += nand.o nand_ecc.o
- obj-$(CONFIG_MTD_NAND_SPIA) += spia.o
-+obj-$(CONFIG_MTD_NAND_TOTO) += toto.o
- obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o
- obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o
-+obj-$(CONFIG_MTD_NAND_TX4925NDFMC) += tx4925ndfmc.o
-+obj-$(CONFIG_MTD_NAND_TX4938NDFMC) += tx4938ndfmc.o
- obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o
-
--include $(TOPDIR)/Rules.make
-+-include $(TOPDIR)/Rules.make
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/nand/autcpu12.c linux/drivers/mtd/nand/autcpu12.c
---- linux-mips-2.4.24-pre2/drivers/mtd/nand/autcpu12.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/nand/autcpu12.c 2004-11-17 18:17:59.162295224 +0100
-@@ -4,9 +4,9 @@
- * Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de>
- *
- * Derived from drivers/mtd/spia.c
-- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
-+ * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
- *
-- * $Id$
-+ * $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
-@@ -25,10 +25,10 @@
- * added page_cache
- *
- * 10-06-2002 TG 128K card support added
-- *
- */
-
- #include <linux/slab.h>
-+#include <linux/init.h>
- #include <linux/module.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/nand.h>
-@@ -70,6 +70,7 @@
- /*
- * Define partitions for flash devices
- */
-+extern struct nand_oobinfo jffs2_oobinfo;
-
- static struct mtd_partition partition_info16k[] = {
- { name: "AUTCPU12 flash partition 1",
-@@ -95,7 +96,7 @@
- size: 16 * SZ_1M },
- { name: "AUTCPU12 flash partition 2",
- offset: 16 * SZ_1M,
-- size: 48 * SZ_1M},
-+ size: 48 * SZ_1M },
- };
-
- static struct mtd_partition partition_info128k[] = {
-@@ -104,7 +105,7 @@
- size: 16 * SZ_1M },
- { name: "AUTCPU12 flash partition 2",
- offset: 16 * SZ_1M,
-- size: 112 * SZ_1M},
-+ size: 112 * SZ_1M },
- };
-
- #define NUM_PARTITIONS16K 2
-@@ -114,7 +115,7 @@
- /*
- * hardware specific access to control-lines
- */
--void autcpu12_hwcontrol(int cmd)
-+static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd)
- {
-
- switch(cmd){
-@@ -133,7 +134,7 @@
- /*
- * read device ready pin
- */
--int autcpu12_device_ready(void)
-+int autcpu12_device_ready(struct mtd_info *mtd)
- {
-
- return ( (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) & AUTCPU12_SMC_RDY) ? 1 : 0;
-@@ -184,7 +185,7 @@
- this->eccmode = NAND_ECC_SOFT;
-
- /* Scan to find existance of the device */
-- if (nand_scan (autcpu12_mtd)) {
-+ if (nand_scan (autcpu12_mtd, 1)) {
- err = -ENXIO;
- goto out_ior;
- }
-@@ -197,15 +198,6 @@
- goto out_ior;
- }
-
-- /* Allocate memory for internal data buffer */
-- this->data_cache = kmalloc (sizeof(u_char) * (autcpu12_mtd->oobblock + autcpu12_mtd->oobsize), GFP_KERNEL);
-- if (!this->data_cache) {
-- printk ("Unable to allocate NAND data cache for AUTCPU12.\n");
-- err = -ENOMEM;
-- goto out_buf;
-- }
-- this->cache_page = -1;
--
- /* Register the partitions */
- switch(autcpu12_mtd->size){
- case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break;
-@@ -215,13 +207,11 @@
- default: {
- printk ("Unsupported SmartMedia device\n");
- err = -ENXIO;
-- goto out_cac;
-+ goto out_buf;
- }
- }
- goto out;
-
--out_cac:
-- kfree (this->data_cache);
- out_buf:
- kfree (this->data_buf);
- out_ior:
-@@ -250,7 +240,6 @@
-
- /* Free internal data buffers */
- kfree (this->data_buf);
-- kfree (this->data_cache);
-
- /* unmap physical adress */
- iounmap((void *)autcpu12_fio_base);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/nand/diskonchip.c linux/drivers/mtd/nand/diskonchip.c
---- linux-mips-2.4.24-pre2/drivers/mtd/nand/diskonchip.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/nand/diskonchip.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,534 @@
-+/*
-+ * drivers/mtd/nand/diskonchip.c
-+ *
-+ * (C) 2003 Red Hat, Inc.
-+ *
-+ * Author: David Woodhouse <dwmw2@infradead.org>
-+ *
-+ * Interface to generic NAND code for M-Systems DiskOnChip devices
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/delay.h>
-+#include <asm/io.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/doc2000.h>
-+#include <linux/mtd/compatmac.h>
-+
-+struct doc_priv {
-+ unsigned long virtadr;
-+ unsigned long physadr;
-+ u_char ChipID;
-+ u_char CDSNControl;
-+ int chips_per_floor; /* The number of chips detected on each floor */
-+ int curfloor;
-+ int curchip;
-+};
-+
-+#define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil)
-+#define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k)
-+
-+static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd);
-+static void doc200x_select_chip(struct mtd_info *mtd, int chip);
-+
-+static int debug=0;
-+MODULE_PARM(debug, "i");
-+
-+static int try_dword=1;
-+MODULE_PARM(try_dword, "i");
-+
-+static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
-+{
-+ volatile char dummy;
-+ int i;
-+
-+ for (i = 0; i < cycles; i++) {
-+ if (DoC_is_Millennium(doc))
-+ dummy = ReadDOC(doc->virtadr, NOP);
-+ else
-+ dummy = ReadDOC(doc->virtadr, DOCStatus);
-+ }
-+
-+}
-+/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
-+static int _DoC_WaitReady(struct doc_priv *doc)
-+{
-+ unsigned long docptr = doc->virtadr;
-+ unsigned long timeo = jiffies + (HZ * 10);
-+
-+ if(debug) printk("_DoC_WaitReady...\n");
-+ /* Out-of-line routine to wait for chip response */
-+ while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
-+ if (time_after(jiffies, timeo)) {
-+ printk("_DoC_WaitReady timed out.\n");
-+ return -EIO;
-+ }
-+ udelay(1);
-+ cond_resched();
-+ }
-+
-+ return 0;
-+}
-+
-+static inline int DoC_WaitReady(struct doc_priv *doc)
-+{
-+ unsigned long docptr = doc->virtadr;
-+ int ret = 0;
-+
-+ DoC_Delay(doc, 4);
-+
-+ if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
-+ /* Call the out-of-line routine to wait */
-+ ret = _DoC_WaitReady(doc);
-+
-+ DoC_Delay(doc, 2);
-+ if(debug) printk("DoC_WaitReady OK\n");
-+ return ret;
-+}
-+
-+static void doc2000_write_byte(struct mtd_info *mtd, u_char datum)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+
-+ if(debug)printk("write_byte %02x\n", datum);
-+ WriteDOC(datum, docptr, CDSNSlowIO);
-+ WriteDOC(datum, docptr, 2k_CDSN_IO);
-+}
-+
-+static u_char doc2000_read_byte(struct mtd_info *mtd)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+
-+ ReadDOC(docptr, CDSNSlowIO);
-+ u_char ret = ReadDOC(docptr, 2k_CDSN_IO);
-+ if (debug) printk("read_byte returns %02x\n", ret);
-+ return ret;
-+}
-+static void doc2000_writebuf(struct mtd_info *mtd,
-+ const u_char *buf, int len)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+ int i;
-+ if (debug)printk("writebuf of %d bytes: ", len);
-+ for (i=0; i < len; i++) {
-+ WriteDOC_(buf[i], docptr, DoC_2k_CDSN_IO + i);
-+ if (debug && i < 16)
-+ printk("%02x ", buf[i]);
-+ }
-+ if (debug) printk("\n");
-+}
-+
-+static void doc2000_readbuf(struct mtd_info *mtd,
-+ u_char *buf, int len)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+ int i;
-+
-+ if (debug)printk("readbuf of %d bytes: ", len);
-+
-+ for (i=0; i < len; i++) {
-+ buf[i] = ReadDOC(docptr, 2k_CDSN_IO + i);
-+ }
-+}
-+
-+static void doc2000_readbuf_dword(struct mtd_info *mtd,
-+ u_char *buf, int len)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+ int i;
-+
-+ if (debug) printk("readbuf_dword of %d bytes: ", len);
-+
-+ if (unlikely((((unsigned long)buf)|len) & 3)) {
-+ for (i=0; i < len; i++) {
-+ *(uint8_t *)(&buf[i]) = ReadDOC(docptr, 2k_CDSN_IO + i);
-+ }
-+ } else {
-+ for (i=0; i < len; i+=4) {
-+ *(uint32_t*)(&buf[i]) = readl(docptr + DoC_2k_CDSN_IO + i);
-+ }
-+ }
-+}
-+
-+static int doc2000_verifybuf(struct mtd_info *mtd,
-+ const u_char *buf, int len)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+ int i;
-+
-+ for (i=0; i < len; i++)
-+ if (buf[i] != ReadDOC(docptr, 2k_CDSN_IO))
-+ return i;
-+ return 0;
-+}
-+
-+static uint16_t doc200x_ident_chip(struct mtd_info *mtd, int nr)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ uint16_t ret;
-+
-+ doc200x_select_chip(mtd, nr);
-+ doc200x_hwcontrol(mtd, NAND_CTL_SETCLE);
-+ this->write_byte(mtd, NAND_CMD_READID);
-+ doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE);
-+ doc200x_hwcontrol(mtd, NAND_CTL_SETALE);
-+ this->write_byte(mtd, 0);
-+ doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
-+
-+ ret = this->read_byte(mtd) << 8;
-+ ret |= this->read_byte(mtd);
-+
-+ if (doc->ChipID == DOC_ChipID_Doc2k && try_dword && !nr) {
-+ /* First chip probe. See if we get same results by 32-bit access */
-+ union {
-+ uint32_t dword;
-+ uint8_t byte[4];
-+ } ident;
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+
-+ doc200x_hwcontrol(mtd, NAND_CTL_SETCLE);
-+ doc2000_write_byte(mtd, NAND_CMD_READID);
-+ doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE);
-+ doc200x_hwcontrol(mtd, NAND_CTL_SETALE);
-+ doc2000_write_byte(mtd, 0);
-+ doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
-+
-+ ident.dword = readl(docptr + DoC_2k_CDSN_IO);
-+ if (((ident.byte[0] << 8) | ident.byte[1]) == ret) {
-+ printk(KERN_INFO "DiskOnChip 2000 responds to DWORD access\n");
-+ this->read_buf = &doc2000_readbuf_dword;
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+static void doc2000_count_chips(struct mtd_info *mtd)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ uint16_t mfrid;
-+ int i;
-+
-+ /* Max 4 chips per floor on DiskOnChip 2000 */
-+ doc->chips_per_floor = 4;
-+
-+ /* Find out what the first chip is */
-+ mfrid = doc200x_ident_chip(mtd, 0);
-+
-+ /* Find how many chips in each floor. */
-+ for (i = 1; i < 4; i++) {
-+ if (doc200x_ident_chip(mtd, i) != mfrid)
-+ break;
-+ }
-+ doc->chips_per_floor = i;
-+}
-+
-+static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
-+{
-+ struct doc_priv *doc = (void *)this->priv;
-+
-+ int status;
-+
-+ DoC_WaitReady(doc);
-+ this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
-+ DoC_WaitReady(doc);
-+ status = (int)this->read_byte(mtd);
-+
-+ return status;
-+}
-+
-+static void doc2001_write_byte(struct mtd_info *mtd, u_char datum)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+
-+ WriteDOC(datum, docptr, CDSNSlowIO);
-+ WriteDOC(datum, docptr, Mil_CDSN_IO);
-+ WriteDOC(datum, docptr, WritePipeTerm);
-+}
-+
-+static u_char doc2001_read_byte(struct mtd_info *mtd)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+
-+ ReadDOC(docptr, CDSNSlowIO);
-+ /* 11.4.5 -- delay twice to allow extended length cycle */
-+ DoC_Delay(doc, 2);
-+ ReadDOC(docptr, ReadPipeInit);
-+ return ReadDOC(docptr, Mil_CDSN_IO);
-+}
-+
-+static void doc2001_writebuf(struct mtd_info *mtd,
-+ const u_char *buf, int len)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+ int i;
-+
-+ for (i=0; i < len; i++)
-+ WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i);
-+ /* Terminate write pipeline */
-+ WriteDOC(0x00, docptr, WritePipeTerm);
-+}
-+
-+static void doc2001_readbuf(struct mtd_info *mtd,
-+ u_char *buf, int len)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+ int i;
-+
-+ /* Start read pipeline */
-+ ReadDOC(docptr, ReadPipeInit);
-+
-+ for (i=0; i < len-1; i++)
-+ buf[i] = ReadDOC(docptr, Mil_CDSN_IO);
-+
-+ /* Terminate read pipeline */
-+ buf[i] = ReadDOC(docptr, LastDataRead);
-+}
-+static int doc2001_verifybuf(struct mtd_info *mtd,
-+ const u_char *buf, int len)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+ int i;
-+
-+ /* Start read pipeline */
-+ ReadDOC(docptr, ReadPipeInit);
-+
-+ for (i=0; i < len-1; i++)
-+ if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {
-+ ReadDOC(docptr, LastDataRead);
-+ return i;
-+ }
-+ if (buf[i] != ReadDOC(docptr, LastDataRead))
-+ return i;
-+ return 0;
-+}
-+
-+static void doc200x_select_chip(struct mtd_info *mtd, int chip)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+ int floor = 0;
-+
-+ /* 11.4.4 -- deassert CE before changing chip */
-+ doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE);
-+
-+ if(debug)printk("select chip (%d)\n", chip);
-+
-+ if (chip == -1)
-+ return;
-+
-+ floor = chip / doc->chips_per_floor;
-+ chip -= (floor * doc->chips_per_floor);
-+
-+ WriteDOC(floor, docptr, FloorSelect);
-+ WriteDOC(chip, docptr, CDSNDeviceSelect);
-+
-+ doc200x_hwcontrol(mtd, NAND_CTL_SETNCE);
-+
-+ doc->curchip = chip;
-+ doc->curfloor = floor;
-+}
-+
-+static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+
-+ switch(cmd) {
-+ case NAND_CTL_SETNCE:
-+ doc->CDSNControl |= CDSN_CTRL_CE;
-+ break;
-+ case NAND_CTL_CLRNCE:
-+ doc->CDSNControl &= ~CDSN_CTRL_CE;
-+ break;
-+ case NAND_CTL_SETCLE:
-+ doc->CDSNControl |= CDSN_CTRL_CLE;
-+ break;
-+ case NAND_CTL_CLRCLE:
-+ doc->CDSNControl &= ~CDSN_CTRL_CLE;
-+ break;
-+ case NAND_CTL_SETALE:
-+ doc->CDSNControl |= CDSN_CTRL_ALE;
-+ break;
-+ case NAND_CTL_CLRALE:
-+ doc->CDSNControl &= ~CDSN_CTRL_ALE;
-+ break;
-+ case NAND_CTL_SETWP:
-+ doc->CDSNControl |= CDSN_CTRL_WP;
-+ break;
-+ case NAND_CTL_CLRWP:
-+ doc->CDSNControl &= ~CDSN_CTRL_WP;
-+ break;
-+ }
-+ if (debug)printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl);
-+ WriteDOC(doc->CDSNControl, docptr, CDSNControl);
-+ /* 11.4.3 -- 4 NOPs after CSDNControl write */
-+ DoC_Delay(doc, 4);
-+}
-+
-+static int doc200x_dev_ready(struct mtd_info *mtd)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+
-+ /* 11.4.2 -- must NOP four times before checking FR/B# */
-+ DoC_Delay(doc, 4);
-+ if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
-+ if(debug)
-+ printk("not ready\n");
-+ return 0;
-+ }
-+ /* 11.4.2 -- Must NOP twice if it's ready */
-+ DoC_Delay(doc, 2);
-+ if (debug)printk("was ready\n");
-+ return 1;
-+}
-+
-+static int doc200x_block_bad(struct mtd_info *mtd, unsigned long block)
-+{
-+ /* FIXME: Look it up in the BBT */
-+ return 0;
-+}
-+
-+struct doc_priv mydoc = {
-+ .physadr = 0xd4000,
-+ .curfloor = -1,
-+ .curchip = -1,
-+};
-+
-+u_char mydatabuf[528];
-+
-+struct nand_chip mynand = {
-+ .priv = (void *)&mydoc,
-+ .select_chip = doc200x_select_chip,
-+ .hwcontrol = doc200x_hwcontrol,
-+ .dev_ready = doc200x_dev_ready,
-+ .waitfunc = doc200x_wait,
-+ .block_bad = doc200x_block_bad,
-+ .eccmode = NAND_ECC_SOFT,
-+ .data_buf = mydatabuf,
-+};
-+
-+struct mtd_info mymtd = {
-+ .priv = (void *)&mynand,
-+ .owner = THIS_MODULE,
-+};
-+
-+int __init init_nanddoc(void)
-+{
-+ mydoc.virtadr = (unsigned long)ioremap(mydoc.physadr, DOC_IOREMAP_LEN);
-+ int nrchips = 1;
-+ char *name;
-+
-+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
-+ mydoc.virtadr, DOCControl);
-+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
-+ mydoc.virtadr, DOCControl);
-+
-+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
-+ mydoc.virtadr, DOCControl);
-+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
-+ mydoc.virtadr, DOCControl);
-+
-+ mydoc.ChipID = ReadDOC(mydoc.virtadr, ChipID);
-+
-+ switch(mydoc.ChipID) {
-+ case DOC_ChipID_DocMil:
-+ mynand.write_byte = doc2001_write_byte;
-+ mynand.read_byte = doc2001_read_byte;
-+ mynand.write_buf = doc2001_writebuf;
-+ mynand.read_buf = doc2001_readbuf;
-+ mynand.verify_buf = doc2001_verifybuf;
-+
-+ ReadDOC(mydoc.virtadr, ChipID);
-+ ReadDOC(mydoc.virtadr, ChipID);
-+ if (ReadDOC(mydoc.virtadr, ChipID) != DOC_ChipID_DocMil) {
-+ /* It's not a Millennium; it's one of the newer
-+ DiskOnChip 2000 units with a similar ASIC.
-+ Treat it like a Millennium, except that it
-+ can have multiple chips. */
-+ doc2000_count_chips(&mymtd);
-+ nrchips = 4 * mydoc.chips_per_floor;
-+ name = "DiskOnChip 2000 (INFTL Model)";
-+ } else {
-+ /* Bog-standard Millennium */
-+ mydoc.chips_per_floor = 1;
-+ nrchips = 1;
-+ name = "DiskOnChip Millennium";
-+ }
-+ break;
-+
-+ case DOC_ChipID_Doc2k:
-+ mynand.write_byte = doc2000_write_byte;
-+ mynand.read_byte = doc2000_read_byte;
-+ mynand.write_buf = doc2000_writebuf;
-+ mynand.read_buf = doc2000_readbuf;
-+ mynand.verify_buf = doc2000_verifybuf;
-+
-+ doc2000_count_chips(&mymtd);
-+ nrchips = 4 * mydoc.chips_per_floor;
-+ name = "DiskOnChip 2000 (NFTL Model)";
-+ mydoc.CDSNControl |= CDSN_CTRL_FLASH_IO;
-+
-+ break;
-+
-+ default:
-+ return -EIO;
-+ }
-+ if (nand_scan(&mymtd, nrchips)) {
-+ iounmap((void *)mydoc.virtadr);
-+ return -EIO;
-+ }
-+ mymtd.name = name;
-+ add_mtd_device(&mymtd);
-+
-+ return 0;
-+}
-+
-+void __exit cleanup_nanddoc(void)
-+{
-+ del_mtd_device(&mymtd);
-+ iounmap((void *)mydoc.virtadr);
-+}
-+
-+module_init(init_nanddoc);
-+module_exit(cleanup_nanddoc);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-+MODULE_DESCRIPTION("M-Systems DiskOnChip 2000 and Millennium device driver\n");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/nand/edb7312.c linux/drivers/mtd/nand/edb7312.c
---- linux-mips-2.4.24-pre2/drivers/mtd/nand/edb7312.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/nand/edb7312.c 2004-11-17 18:17:59.165294768 +0100
-@@ -6,7 +6,7 @@
- * Derived from drivers/mtd/nand/autcpu12.c
- * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
- *
-- * $Id$
-+ * $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
-@@ -20,6 +20,7 @@
-
- #include <linux/slab.h>
- #include <linux/module.h>
-+#include <linux/init.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/nand.h>
- #include <linux/mtd/partitions.h>
-@@ -77,16 +78,13 @@
- };
- #define NUM_PARTITIONS 1
-
--extern int parse_cmdline_partitions(struct mtd_info *master,
-- struct mtd_partition **pparts,
-- const char *mtd_id);
- #endif
-
-
- /*
- * hardware specific access to control-lines
- */
--static void ep7312_hwcontrol(int cmd)
-+static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd)
- {
- switch(cmd) {
-
-@@ -116,10 +114,13 @@
- /*
- * read device ready pin
- */
--static int ep7312_device_ready(void)
-+static int ep7312_device_ready(struct mtd_info *mtd)
- {
- return 1;
- }
-+#ifdef CONFIG_MTD_PARTITIONS
-+const char *part_probes[] = { "cmdlinepart", NULL };
-+#endif
-
- /*
- * Main initialization routine
-@@ -174,7 +175,7 @@
- this->chip_delay = 15;
-
- /* Scan to find existence of the device */
-- if (nand_scan (ep7312_mtd)) {
-+ if (nand_scan (ep7312_mtd, 1)) {
- iounmap((void *)ep7312_fio_base);
- kfree (ep7312_mtd);
- return -ENXIO;
-@@ -189,27 +190,16 @@
- return -ENOMEM;
- }
-
-- /* Allocate memory for internal data buffer */
-- this->data_cache = kmalloc (sizeof(u_char) * (ep7312_mtd->oobblock + ep7312_mtd->oobsize), GFP_KERNEL);
-- if (!this->data_cache) {
-- printk("Unable to allocate NAND data cache for EDB7312.\n");
-- kfree (this->data_buf);
-- iounmap((void *)ep7312_fio_base);
-- kfree (ep7312_mtd);
-- return -ENOMEM;
-- }
-- this->cache_page = -1;
--
--#ifdef CONFIG_MTD_CMDLINE_PARTS
-- mtd_parts_nb = parse_cmdline_partitions(ep7312_mtd, &mtd_parts,
-- "edb7312-nand");
-+#ifdef CONFIG_PARTITIONS
-+ ep7312_mtd->name = "edb7312-nand";
-+ mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes,
-+ &mtd_parts, 0);
- if (mtd_parts_nb > 0)
- part_type = "command line";
- else
- mtd_parts_nb = 0;
- #endif
-- if (mtd_parts_nb == 0)
-- {
-+ if (mtd_parts_nb == 0) {
- mtd_parts = partition_info;
- mtd_parts_nb = NUM_PARTITIONS;
- part_type = "static";
-@@ -236,7 +226,6 @@
-
- /* Free internal data buffer */
- kfree (this->data_buf);
-- kfree (this->data_cache);
-
- /* Free the MTD device structure */
- kfree (ep7312_mtd);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/nand/nand.c linux/drivers/mtd/nand/nand.c
---- linux-mips-2.4.24-pre2/drivers/mtd/nand/nand.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/nand/nand.c 2004-11-17 18:17:59.167294464 +0100
-@@ -8,7 +8,7 @@
- * Additional technical information is available on
- * http://www.linux-mtd.infradead.org/tech/nand.html
- *
-- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
-+ * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
- * 2002 Thomas Gleixner (tglx@linutronix.de)
- *
- * 10-29-2001 Thomas Gleixner (tglx@linutronix.de)
-@@ -112,10 +112,27 @@
- * for mtd->read_ecc / mtd->write_ecc
- * some minor cleanups
- *
-- * 12-05-2000 tglx: Dave Ellis (DGE@sixnetio) provided the fix for
-+ * 12-05-2002 tglx: Dave Ellis (DGE@sixnetio) provided the fix for
- * WRITE_VERIFY long time ago. Thanks for remembering me.
- *
-- * $Id$
-+ * 02-14-2003 tglx: Reject non page aligned writes
-+ * Fixed ecc select in nand_write_page to match semantics.
-+ *
-+ * 02-18-2003 tglx: Changed oobsel to pointer. Added a default oob-selector
-+ *
-+ * 02-18-2003 tglx: Implemented oobsel again. Now it uses a pointer to
-+ + a structure, which will be supplied by a filesystem driver
-+ * If NULL is given, then the defaults (none or defaults
-+ * supplied by ioctl (MEMSETOOBSEL) are used.
-+ * For partitions the partition defaults are used (mtdpart.c)
-+ *
-+ * 06-04-2003 tglx: fix compile errors and fix write verify problem for
-+ * some chips, which need either a delay between the readback
-+ * and the next write command or have the CE removed. The
-+ * CE disable/enable is much faster than a 20us delay and
-+ * it should work on all available chips.
-+ *
-+ * $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
-@@ -130,102 +147,151 @@
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/nand.h>
- #include <linux/mtd/nand_ecc.h>
-+#include <linux/mtd/compatmac.h>
- #include <linux/interrupt.h>
- #include <asm/io.h>
-
- /*
-- * Macros for low-level register control
-- */
--#define nand_select() this->hwcontrol(NAND_CTL_SETNCE);
--
--#define nand_deselect() this->hwcontrol(NAND_CTL_CLRNCE);
--
--/*
-- * out of band configuration for different filesystems
-- */
--static int oobconfigs[][6] = {
-- { 0,0,0,0,0,0},
--
-- { NAND_JFFS2_OOB_ECCPOS0, NAND_JFFS2_OOB_ECCPOS1, NAND_JFFS2_OOB_ECCPOS2,
-- NAND_JFFS2_OOB_ECCPOS3, NAND_JFFS2_OOB_ECCPOS4, NAND_JFFS2_OOB_ECCPOS5 },
--
-- { NAND_YAFFS_OOB_ECCPOS0, NAND_YAFFS_OOB_ECCPOS1, NAND_YAFFS_OOB_ECCPOS2,
-- NAND_YAFFS_OOB_ECCPOS3, NAND_YAFFS_OOB_ECCPOS4, NAND_YAFFS_OOB_ECCPOS5 }
--};
--
--/*
- * NAND low-level MTD interface functions
- */
-+static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len);
-+static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len);
-+static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len);
-+
- static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
- static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
-- size_t * retlen, u_char * buf, u_char * eccbuf, int oobsel);
-+ size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
- static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
- static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf);
- static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
-- size_t * retlen, const u_char * buf, u_char * eccbuf, int oobsel);
-+ size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
- static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char *buf);
- static int nand_writev (struct mtd_info *mtd, const struct iovec *vecs,
- unsigned long count, loff_t to, size_t * retlen);
- static int nand_writev_ecc (struct mtd_info *mtd, const struct iovec *vecs,
-- unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, int oobsel);
-+ unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
- static int nand_erase (struct mtd_info *mtd, struct erase_info *instr);
- static void nand_sync (struct mtd_info *mtd);
--static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, int col,
-- int last, u_char *oob_buf, int oobsel);
-+static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, struct nand_oobinfo *oobsel);
-+
-+static u_char nand_read_byte(struct mtd_info *mtd)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ return readb(this->IO_ADDR_R);
-+}
-+
-+static void nand_write_byte(struct mtd_info *mtd, u_char byte)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ writeb(byte, this->IO_ADDR_W);
-+}
-+
-+static void nand_select_chip(struct mtd_info *mtd, int chip)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ switch(chip) {
-+ case -1:
-+ this->hwcontrol(mtd, NAND_CTL_CLRNCE);
-+ break;
-+ case 0:
-+ this->hwcontrol(mtd, NAND_CTL_SETNCE);
-+ break;
-+
-+ default:
-+ BUG();
-+ }
-+}
-+
-+static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ writeb(buf[i], this->IO_ADDR_W);
-+}
-+
-+static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ buf[i] = readb(this->IO_ADDR_R);
-+}
-+
-+static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ if (buf[i] != readb(this->IO_ADDR_R))
-+ return i;
-+
-+ return 0;
-+}
-+
-+/* Appropriate chip should already be selected */
-+static int nand_block_bad(struct mtd_info *mtd, unsigned long page)
-+{
-+ struct nand_chip *this = mtd->priv;
-+
-+ this->cmdfunc (mtd, NAND_CMD_READOOB, NAND_BADBLOCK_POS, page);
-+ if (this->read_byte(mtd) != 0xff)
-+ return 1;
-+
-+ return 0;
-+}
-+
- /*
- * Send command to NAND device
- */
- static void nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
- {
- register struct nand_chip *this = mtd->priv;
-- register unsigned long NAND_IO_ADDR = this->IO_ADDR_W;
-
- /* Begin command latch cycle */
-- this->hwcontrol (NAND_CTL_SETCLE);
-+ this->hwcontrol(mtd, NAND_CTL_SETCLE);
- /*
- * Write out the command to the device.
- */
-- if (command != NAND_CMD_SEQIN)
-- writeb (command, NAND_IO_ADDR);
-- else {
-- if (mtd->oobblock == 256 && column >= 256) {
-- column -= 256;
-- writeb (NAND_CMD_READOOB, NAND_IO_ADDR);
-- writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
-- } else if (mtd->oobblock == 512 && column >= 256) {
-- if (column < 512) {
-- column -= 256;
-- writeb (NAND_CMD_READ1, NAND_IO_ADDR);
-- writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
-- } else {
-- column -= 512;
-- writeb (NAND_CMD_READOOB, NAND_IO_ADDR);
-- writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
-- }
-+ if (command == NAND_CMD_SEQIN) {
-+ int readcmd;
-+
-+ if (column >= mtd->oobblock) {
-+ /* OOB area */
-+ column -= mtd->oobblock;
-+ readcmd = NAND_CMD_READOOB;
-+ } else if (column < 256) {
-+ /* First 256 bytes --> READ0 */
-+ readcmd = NAND_CMD_READ0;
- } else {
-- writeb (NAND_CMD_READ0, NAND_IO_ADDR);
-- writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
-+ column -= 256;
-+ readcmd = NAND_CMD_READ1;
- }
-+ this->write_byte(mtd, readcmd);
- }
-+ this->write_byte(mtd, command);
-
- /* Set ALE and clear CLE to start address cycle */
-- this->hwcontrol (NAND_CTL_CLRCLE);
-+ this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-
- if (column != -1 || page_addr != -1) {
-- this->hwcontrol (NAND_CTL_SETALE);
-+ this->hwcontrol(mtd, NAND_CTL_SETALE);
-
- /* Serially input address */
- if (column != -1)
-- writeb (column, NAND_IO_ADDR);
-+ this->write_byte(mtd, column);
- if (page_addr != -1) {
-- writeb ((unsigned char) (page_addr & 0xff), NAND_IO_ADDR);
-- writeb ((unsigned char) ((page_addr >> 8) & 0xff), NAND_IO_ADDR);
-+ this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
-+ this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
- /* One more address cycle for higher density devices */
- if (mtd->size & 0x0c000000)
-- writeb ((unsigned char) ((page_addr >> 16) & 0x0f), NAND_IO_ADDR);
-+ this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
- }
- /* Latch in address */
-- this->hwcontrol (NAND_CTL_CLRALE);
-+ this->hwcontrol(mtd, NAND_CTL_CLRALE);
- }
-
- /*
-@@ -244,10 +310,11 @@
- case NAND_CMD_RESET:
- if (this->dev_ready)
- break;
-- this->hwcontrol (NAND_CTL_SETCLE);
-- writeb (NAND_CMD_STATUS, NAND_IO_ADDR);
-- this->hwcontrol (NAND_CTL_CLRCLE);
-- while ( !(readb (this->IO_ADDR_R) & 0x40));
-+ udelay(this->chip_delay);
-+ this->hwcontrol(mtd, NAND_CTL_SETCLE);
-+ this->write_byte(mtd, NAND_CMD_STATUS);
-+ this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-+ while ( !(this->read_byte(mtd) & 0x40));
- return;
-
- /* This applies to read commands */
-@@ -263,7 +330,7 @@
- }
-
- /* wait until command is processed */
-- while (!this->dev_ready());
-+ while (!this->dev_ready(mtd));
- }
-
- /*
-@@ -288,17 +355,17 @@
- spin_unlock_bh (&this->chip_lock);
- return;
- }
--
-+#if 0 /* This was broken. And of dubious utility */
- if (this->state == FL_ERASING) {
- if (new_state != FL_ERASING) {
- this->state = new_state;
- spin_unlock_bh (&this->chip_lock);
-- nand_select (); /* select in any case */
-+ this->select_chip(mtd, 0); /* select in any case */
- this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
- return;
- }
- }
--
-+#endif
- set_current_state (TASK_UNINTERRUPTIBLE);
- add_wait_queue (&this->wq, &wait);
- spin_unlock_bh (&this->chip_lock);
-@@ -334,17 +401,17 @@
- return 0;
- }
- if (this->dev_ready) {
-- if (this->dev_ready ())
-+ if (this->dev_ready(mtd))
- break;
- }
-- if (readb (this->IO_ADDR_R) & 0x40)
-+ if (this->read_byte(mtd) & 0x40)
- break;
-
- spin_unlock_bh (&this->chip_lock);
- yield ();
- spin_lock_bh (&this->chip_lock);
- }
-- status = (int) readb (this->IO_ADDR_R);
-+ status = (int) this->read_byte(mtd);
- spin_unlock_bh (&this->chip_lock);
-
- return status;
-@@ -352,14 +419,15 @@
-
- /*
- * Nand_page_program function is used for write and writev !
-+ * This function will always program a full page of data
-+ * If you call it with a non page aligned buffer, you're lost :)
- */
--static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this,
-- int page, int col, int last, u_char *oob_buf, int oobsel)
-+static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, struct nand_oobinfo *oobsel)
- {
- int i, status;
- u_char ecc_code[6], *oob_data;
-- int eccmode = oobsel ? this->eccmode : NAND_ECC_NONE;
-- int *oob_config = oobconfigs[oobsel];
-+ int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
-+ int *oob_config = oobsel->eccpos;
-
- /* pad oob area, if we have no oob buffer from fs-driver */
- if (!oob_buf) {
-@@ -369,66 +437,42 @@
- } else
- oob_data = oob_buf;
-
-- /* software ecc 3 Bytes ECC / 256 Byte Data ? */
-- if (eccmode == NAND_ECC_SOFT) {
-- /* Read back previous written data, if col > 0 */
-- if (col) {
-- this->cmdfunc (mtd, NAND_CMD_READ0, 0, page);
-- for (i = 0; i < col; i++)
-- this->data_poi[i] = readb (this->IO_ADDR_R);
-- }
-- if ((col < this->eccsize) && (last >= this->eccsize)) {
-- this->calculate_ecc (&this->data_poi[0], &(ecc_code[0]));
-- for (i = 0; i < 3; i++)
-- oob_data[oob_config[i]] = ecc_code[i];
-- }
-- /* Calculate and write the second ECC if we have enough data */
-- if ((mtd->oobblock == 512) && (last == 512)) {
-- this->calculate_ecc (&this->data_poi[256], &(ecc_code[3]));
-- for (i = 3; i < 6; i++)
-- oob_data[oob_config[i]] = ecc_code[i];
-- }
-- } else {
-- /* For hardware ECC skip ECC, if we have no full page write */
-- if (eccmode != NAND_ECC_NONE && (col || last != mtd->oobblock))
-- eccmode = NAND_ECC_NONE;
-- }
--
-- /* Prepad for partial page programming !!! */
-- for (i = 0; i < col; i++)
-- this->data_poi[i] = 0xff;
--
-- /* Postpad for partial page programming !!! oob is already padded */
-- for (i = last; i < mtd->oobblock; i++)
-- this->data_poi[i] = 0xff;
--
- /* Send command to begin auto page programming */
- this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page);
-
- /* Write out complete page of data, take care of eccmode */
-- switch (this->eccmode) {
-+ switch (eccmode) {
- /* No ecc and software ecc 3/256, write all */
- case NAND_ECC_NONE:
-+ printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n");
-+ this->write_buf(mtd, this->data_poi, mtd->oobblock);
-+ break;
- case NAND_ECC_SOFT:
-- for (i = 0; i < mtd->oobblock; i++)
-- writeb ( this->data_poi[i] , this->IO_ADDR_W);
-+ this->calculate_ecc(mtd, &this->data_poi[0], &(ecc_code[0]));
-+ for (i = 0; i < 3; i++)
-+ oob_data[oob_config[i]] = ecc_code[i];
-+ /* Calculate and write the second ECC for 512 Byte page size */
-+ if (mtd->oobblock == 512) {
-+ this->calculate_ecc(mtd, &this->data_poi[256], &(ecc_code[3]));
-+ for (i = 3; i < 6; i++)
-+ oob_data[oob_config[i]] = ecc_code[i];
-+ }
-+ this->write_buf(mtd, this->data_poi, mtd->oobblock);
- break;
-
- /* Hardware ecc 3 byte / 256 data, write first half, get ecc, then second, if 512 byte pagesize */
- case NAND_ECC_HW3_256:
-- this->enable_hwecc (NAND_ECC_WRITE); /* enable hardware ecc logic for write */
-- for (i = 0; i < mtd->eccsize; i++)
-- writeb ( this->data_poi[i] , this->IO_ADDR_W);
-+ this->enable_hwecc(mtd, NAND_ECC_WRITE); /* enable hardware ecc logic for write */
-+ this->write_buf(mtd, this->data_poi, mtd->eccsize);
-
-- this->calculate_ecc (NULL, &(ecc_code[0]));
-+ this->calculate_ecc(mtd, NULL, &(ecc_code[0]));
- for (i = 0; i < 3; i++)
- oob_data[oob_config[i]] = ecc_code[i];
-
- if (mtd->oobblock == 512) {
-- this->enable_hwecc (NAND_ECC_WRITE); /* enable hardware ecc logic for write*/
-- for (i = mtd->eccsize; i < mtd->oobblock; i++)
-- writeb ( this->data_poi[i] , this->IO_ADDR_W);
-- this->calculate_ecc (NULL, &(ecc_code[3]));
-+ this->enable_hwecc(mtd, NAND_ECC_WRITE); /* enable hardware ecc logic for write*/
-+ this->write_buf(mtd, &this->data_poi[mtd->eccsize], mtd->oobblock - mtd->eccsize);
-+ this->calculate_ecc(mtd, NULL, &(ecc_code[3]));
- for (i = 3; i < 6; i++)
- oob_data[oob_config[i]] = ecc_code[i];
- }
-@@ -436,20 +480,18 @@
-
- /* Hardware ecc 3 byte / 512 byte data, write full page */
- case NAND_ECC_HW3_512:
-- this->enable_hwecc (NAND_ECC_WRITE); /* enable hardware ecc logic */
-- for (i = 0; i < mtd->oobblock; i++)
-- writeb ( this->data_poi[i] , this->IO_ADDR_W);
-- this->calculate_ecc (NULL, &(ecc_code[0]));
-+ this->enable_hwecc(mtd, NAND_ECC_WRITE); /* enable hardware ecc logic */
-+ this->write_buf(mtd, this->data_poi, mtd->oobblock);
-+ this->calculate_ecc(mtd, NULL, &(ecc_code[0]));
- for (i = 0; i < 3; i++)
- oob_data[oob_config[i]] = ecc_code[i];
- break;
-
- /* Hardware ecc 6 byte / 512 byte data, write full page */
- case NAND_ECC_HW6_512:
-- this->enable_hwecc (NAND_ECC_WRITE); /* enable hardware ecc logic */
-- for (i = 0; i < mtd->oobblock; i++)
-- writeb ( this->data_poi[i] , this->IO_ADDR_W);
-- this->calculate_ecc (NULL, &(ecc_code[0]));
-+ this->enable_hwecc(mtd, NAND_ECC_WRITE); /* enable hardware ecc logic */
-+ this->write_buf(mtd, this->data_poi, mtd->oobblock);
-+ this->calculate_ecc(mtd, NULL, &(ecc_code[0]));
- for (i = 0; i < 6; i++)
- oob_data[oob_config[i]] = ecc_code[i];
- break;
-@@ -460,8 +502,7 @@
- }
-
- /* Write out OOB data */
-- for (i = 0; i < mtd->oobsize; i++)
-- writeb ( oob_data[i] , this->IO_ADDR_W);
-+ this->write_buf(mtd, oob_data, mtd->oobsize);
-
- /* Send command to actually program the data */
- this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1);
-@@ -490,25 +531,21 @@
- */
-
- /* Send command to read back the page */
-- this->cmdfunc (mtd, NAND_CMD_READ0, col, page);
-+ this->cmdfunc (mtd, NAND_CMD_READ0, 0, page);
- /* Loop through and verify the data */
-- for (i = col; i < last; i++) {
-- if (this->data_poi[i] != readb (this->IO_ADDR_R)) {
-+ if (this->verify_buf(mtd, this->data_poi, mtd->oobblock)) {
- DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
- return -EIO;
- }
-- }
-
- /* check, if we have a fs-supplied oob-buffer */
- if (oob_buf) {
-- for (i = 0; i < mtd->oobsize; i++) {
-- if (oob_data[i] != readb (this->IO_ADDR_R)) {
-+ if (this->verify_buf(mtd, oob_data, mtd->oobsize)) {
- DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
- return -EIO;
- }
-- }
- } else {
-- if (eccmode != NAND_ECC_NONE && !col && last == mtd->oobblock) {
-+ if (eccmode != NAND_ECC_NONE) {
- int ecc_bytes = 0;
-
- switch (this->eccmode) {
-@@ -518,8 +555,7 @@
- case NAND_ECC_HW6_512: ecc_bytes = 6; break;
- }
-
-- for (i = 0; i < mtd->oobsize; i++)
-- oob_data[i] = readb (this->IO_ADDR_R);
-+ this->read_buf(mtd, oob_data, mtd->oobsize);
-
- for (i = 0; i < ecc_bytes; i++) {
- if (oob_data[oob_config[i]] != ecc_code[i]) {
-@@ -531,6 +567,13 @@
- }
- }
- }
-+ /*
-+ * Terminate the read command. This is faster than sending a reset command or
-+ * applying a 20us delay before issuing the next programm sequence.
-+ * This is not a problem for all chips, but I have found a bunch of them.
-+ */
-+ this->select_chip(mtd, -1);
-+ this->select_chip(mtd, 0);
- #endif
- return 0;
- }
-@@ -540,7 +583,7 @@
- */
- static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
- {
-- return (nand_read_ecc (mtd, from, len, retlen, buf, NULL, 0));
-+ return nand_read_ecc (mtd, from, len, retlen, buf, NULL, NULL);
- }
-
-
-@@ -548,7 +591,7 @@
- * NAND read with ECC
- */
- static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
-- size_t * retlen, u_char * buf, u_char * oob_buf, int oobsel)
-+ size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel)
- {
- int j, col, page, end, ecc;
- int erase_state = 0;
-@@ -557,9 +600,15 @@
- u_char *data_poi, *oob_data = oob_buf;
- u_char ecc_calc[6];
- u_char ecc_code[6];
-- int eccmode = oobsel ? this->eccmode : NAND_ECC_NONE;
-+ int eccmode;
-+ int *oob_config;
-+
-+ // use chip default if zero
-+ if (oobsel == NULL)
-+ oobsel = &mtd->oobinfo;
-
-- int *oob_config = oobconfigs[oobsel];
-+ eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
-+ oob_config = oobsel->eccpos;
-
- DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
-
-@@ -574,7 +623,7 @@
- nand_get_chip (this, mtd ,FL_READING, &erase_state);
-
- /* Select the NAND device */
-- nand_select ();
-+ this->select_chip(mtd, 0);
-
- /* First we calculate the starting page */
- page = from >> this->page_shift;
-@@ -596,7 +645,7 @@
- if (!this->dev_ready)
- udelay (this->chip_delay);
- else
-- while (!this->dev_ready());
-+ while (!this->dev_ready(mtd));
- }
-
- /*
-@@ -616,39 +665,40 @@
-
- j = 0;
- switch (eccmode) {
-- case NAND_ECC_NONE: /* No ECC, Read in a page */
-- while (j < end)
-- data_poi[j++] = readb (this->IO_ADDR_R);
-+ case NAND_ECC_NONE: { /* No ECC, Read in a page */
-+ static unsigned long lastwhinge = 0;
-+ if ((lastwhinge / HZ) != (jiffies / HZ)) {
-+ printk (KERN_WARNING "Reading data from NAND FLASH without ECC is not recommended\n");
-+ lastwhinge = jiffies;
-+ }
-+ this->read_buf(mtd, data_poi, end);
- break;
-+ }
-
- case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */
-- while (j < end)
-- data_poi[j++] = readb (this->IO_ADDR_R);
-- this->calculate_ecc (&data_poi[0], &ecc_calc[0]);
-+ this->read_buf(mtd, data_poi, end);
-+ this->calculate_ecc(mtd, &data_poi[0], &ecc_calc[0]);
- if (mtd->oobblock == 512)
-- this->calculate_ecc (&data_poi[256], &ecc_calc[3]);
-+ this->calculate_ecc(mtd, &data_poi[256], &ecc_calc[3]);
- break;
-
- case NAND_ECC_HW3_256: /* Hardware ECC 3 byte /256 byte data: Read in first 256 byte, get ecc, */
-- this->enable_hwecc (NAND_ECC_READ);
-- while (j < ecc)
-- data_poi[j++] = readb (this->IO_ADDR_R);
-- this->calculate_ecc (&data_poi[0], &ecc_calc[0]); /* read from hardware */
-+ this->enable_hwecc(mtd, NAND_ECC_READ);
-+ this->read_buf(mtd, data_poi, ecc);
-+ this->calculate_ecc(mtd, &data_poi[0], &ecc_calc[0]); /* read from hardware */
-
- if (mtd->oobblock == 512) { /* read second, if pagesize = 512 */
-- this->enable_hwecc (NAND_ECC_READ);
-- while (j < end)
-- data_poi[j++] = readb (this->IO_ADDR_R);
-- this->calculate_ecc (&data_poi[256], &ecc_calc[3]); /* read from hardware */
-+ this->enable_hwecc(mtd, NAND_ECC_READ);
-+ this->read_buf(mtd, &data_poi[ecc], end-ecc);
-+ this->calculate_ecc(mtd, &data_poi[256], &ecc_calc[3]); /* read from hardware */
- }
- break;
-
- case NAND_ECC_HW3_512:
- case NAND_ECC_HW6_512: /* Hardware ECC 3/6 byte / 512 byte data : Read in a page */
-- this->enable_hwecc (NAND_ECC_READ);
-- while (j < end)
-- data_poi[j++] = readb (this->IO_ADDR_R);
-- this->calculate_ecc (&data_poi[0], &ecc_calc[0]); /* read from hardware */
-+ this->enable_hwecc(mtd, NAND_ECC_READ);
-+ this->read_buf(mtd, data_poi, end);
-+ this->calculate_ecc(mtd, &data_poi[0], &ecc_calc[0]); /* read from hardware */
- break;
-
- default:
-@@ -658,7 +708,7 @@
-
- /* read oobdata */
- for (j = 0; j < mtd->oobsize; j++)
-- oob_data[oob + j] = readb (this->IO_ADDR_R);
-+ oob_data[oob + j] = this->read_byte(mtd);
-
- /* Skip ECC, if not active */
- if (eccmode == NAND_ECC_NONE)
-@@ -669,7 +719,7 @@
- ecc_code[j] = oob_data[oob + oob_config[j]];
-
- /* correct data, if neccecary */
-- ecc_status = this->correct_data (&data_poi[0], &ecc_code[0], &ecc_calc[0]);
-+ ecc_status = this->correct_data(mtd, &data_poi[0], &ecc_code[0], &ecc_calc[0]);
- /* check, if we have a fs supplied oob-buffer */
- if (oob_buf) {
- oob += mtd->oobsize;
-@@ -682,7 +732,7 @@
- }
-
- if (mtd->oobblock == 512 && eccmode != NAND_ECC_HW3_512) {
-- ecc_status = this->correct_data (&data_poi[256], &ecc_code[3], &ecc_calc[3]);
-+ ecc_status = this->correct_data(mtd, &data_poi[256], &ecc_code[3], &ecc_calc[3]);
- if (oob_buf) {
- *((int *)&oob_data[oob]) = ecc_status;
- oob += sizeof(int);
-@@ -705,7 +755,7 @@
- }
-
- /* De-select the NAND device */
-- nand_deselect ();
-+ this->select_chip(mtd, -1);
-
- /* Wake up anyone waiting on the device */
- spin_lock_bh (&this->chip_lock);
-@@ -753,7 +803,7 @@
- nand_get_chip (this, mtd , FL_READING, &erase_state);
-
- /* Select the NAND device */
-- nand_select ();
-+ this->select_chip(mtd, 0);
-
- /* Send the read command */
- this->cmdfunc (mtd, NAND_CMD_READOOB, col, page);
-@@ -761,13 +811,20 @@
- * Read the data, if we read more than one page
- * oob data, let the device transfer the data !
- */
-- for (i = 0; i < len; i++) {
-- buf[i] = readb (this->IO_ADDR_R);
-- if ((col++ & (mtd->oobsize - 1)) == (mtd->oobsize - 1))
-+ i = 0;
-+ while (i < len) {
-+ int thislen = (mtd->oobsize - col) & (mtd->oobsize - 1);
-+ if (!thislen)
-+ thislen = mtd->oobsize;
-+ thislen = min_t(int, thislen, len);
-+ this->read_buf(mtd, &buf[i], thislen);
-+ i += thislen;
-+ col += thislen;
-+ /* Delay between pages */
- udelay (this->chip_delay);
- }
- /* De-select the NAND device */
-- nand_deselect ();
-+ this->select_chip(mtd, -1);
-
- /* Wake up anyone waiting on the device */
- spin_lock_bh (&this->chip_lock);
-@@ -780,45 +837,54 @@
- return 0;
- }
-
-+#define NOTALIGNED(x) (x & (mtd->oobblock-1)) != 0
-+
- /*
- * Use NAND write ECC
- */
- static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
- {
-- return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, 0));
-+ return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL));
- }
- /*
- * NAND write with ECC
- */
- static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
-- size_t * retlen, const u_char * buf, u_char * eccbuf, int oobsel)
-+ size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel)
- {
-- int i, page, col, cnt, ret = 0, oob = 0, written = 0;
-+ int page, ret = 0, oob = 0, written = 0;
- struct nand_chip *this = mtd->priv;
-
- DEBUG (MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
-
- /* Do not allow write past end of device */
- if ((to + len) > mtd->size) {
-- DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Attempt to write past end of page\n");
-+ DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Attempt to write past end of page\n");
-+ return -EINVAL;
-+ }
-+
-+ /* reject writes, which are not page aligned */
-+ if (NOTALIGNED (to) || NOTALIGNED(len)) {
-+ printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
- return -EINVAL;
- }
-
-+ // if oobsel is NULL, use chip defaults
-+ if (oobsel == NULL)
-+ oobsel = &mtd->oobinfo;
-+
- /* Shift to get page */
- page = ((int) to) >> this->page_shift;
-
-- /* Get the starting column */
-- col = to & (mtd->oobblock - 1);
--
- /* Grab the lock and see if the device is available */
- nand_get_chip (this, mtd, FL_WRITING, NULL);
-
- /* Select the NAND device */
-- nand_select ();
-+ this->select_chip(mtd, 0);
-
- /* Check the WP bit */
- this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
-- if (!(readb (this->IO_ADDR_R) & 0x80)) {
-+ if (!(this->read_byte(mtd) & 0x80)) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Device is write protected!!!\n");
- ret = -EIO;
- goto out;
-@@ -826,42 +892,27 @@
-
- /* Loop until all data is written */
- while (written < len) {
-- /*
-- * Check, if we have a full page write, then we can
-- * use the given buffer, else we have to copy
-- */
-- if (!col && (len - written) >= mtd->oobblock) {
-+ int cnt = mtd->oobblock;
- this->data_poi = (u_char*) &buf[written];
-- cnt = mtd->oobblock;
-- } else {
-- cnt = 0;
-- for (i = col; i < len && i < mtd->oobblock; i++) {
-- this->data_buf[i] = buf[written + i];
-- cnt++;
-- }
-- this->data_poi = this->data_buf;
-- }
-- /* We use the same function for write and writev !) */
-+ /* We use the same function for write and writev */
- if (eccbuf) {
-- ret = nand_write_page (mtd, this, page, col, cnt ,&eccbuf[oob], oobsel);
-+ ret = nand_write_page (mtd, this, page, &eccbuf[oob], oobsel);
- oob += mtd->oobsize;
- } else
-- ret = nand_write_page (mtd, this, page, col, cnt, NULL, oobsel);
-+ ret = nand_write_page (mtd, this, page, NULL, oobsel);
-
- if (ret)
- goto out;
-
- /* Update written bytes count */
- written += cnt;
-- /* Next write is aligned */
-- col = 0;
- /* Increment page address */
- page++;
- }
-
- out:
- /* De-select the NAND device */
-- nand_deselect ();
-+ this->select_chip(mtd, -1);
-
- /* Wake up anyone waiting on the device */
- spin_lock_bh (&this->chip_lock);
-@@ -873,13 +924,21 @@
- return ret;
- }
-
-+static u_char ffchars[] = {
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
-+};
-+
- /*
- * NAND write out-of-band
- */
- static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
- {
-- int i, column, page, status, ret = 0;
-+ int column, page, status, ret = 0;
- struct nand_chip *this = mtd->priv;
-+#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
-+ int i;
-+#endif
-
- DEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
-
-@@ -902,27 +961,31 @@
- nand_get_chip (this, mtd, FL_WRITING, NULL);
-
- /* Select the NAND device */
-- nand_select ();
-+ this->select_chip(mtd, 0);
-+
-+ /* Reset the chip. Some chips (like the Toshiba TC5832DC found
-+ in one of my DiskOnChip 2000 test units) will clear the whole
-+ data page too if we don't do this. I have no clue why, but
-+ I seem to have 'fixed' it in the doc2000 driver in
-+ August 1999. dwmw2. */
-+ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
-
- /* Check the WP bit */
- this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
-- if (!(readb (this->IO_ADDR_R) & 0x80)) {
-+ if (!(this->read_byte(mtd) & 0x80)) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Device is write protected!!!\n");
- ret = -EIO;
- goto out;
- }
--
- /* Write out desired data */
- this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page);
-+
- /* prepad 0xff for partial programming */
-- for (i = 0; i < column; i++)
-- writeb (0xff, this->IO_ADDR_W);
-+ this->write_buf(mtd, ffchars, column);
- /* write data */
-- for (i = 0; i < len; i++)
-- writeb (buf[i], this->IO_ADDR_W);
-+ this->write_buf(mtd, buf, len);
- /* postpad 0xff for partial programming */
-- for (i = len + column; i < mtd->oobsize; i++)
-- writeb (0xff, this->IO_ADDR_W);
-+ this->write_buf(mtd, ffchars, mtd->oobsize - (len+column));
-
- /* Send command to program the OOB data */
- this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1);
-@@ -944,7 +1007,7 @@
-
- /* Loop through and verify the data */
- for (i = 0; i < len; i++) {
-- if (buf[i] != readb (this->IO_ADDR_R)) {
-+ if (buf[i] != this->read_byte(mtd)) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
- ret = -EIO;
- goto out;
-@@ -954,7 +1017,7 @@
-
- out:
- /* De-select the NAND device */
-- nand_deselect ();
-+ this->select_chip(mtd, -1);
-
- /* Wake up anyone waiting on the device */
- spin_lock_bh (&this->chip_lock);
-@@ -976,9 +1039,9 @@
- }
-
- static int nand_writev_ecc (struct mtd_info *mtd, const struct iovec *vecs, unsigned long count,
-- loff_t to, size_t * retlen, u_char *eccbuf, int oobsel)
-+ loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel)
- {
-- int i, page, col, cnt, len, total_len, ret = 0, written = 0;
-+ int i, page, len, total_len, ret = 0, written = 0;
- struct nand_chip *this = mtd->priv;
-
- /* Calculate total length of data */
-@@ -995,39 +1058,42 @@
- return -EINVAL;
- }
-
-+ /* reject writes, which are not page aligned */
-+ if (NOTALIGNED (to) || NOTALIGNED(total_len)) {
-+ printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
-+ return -EINVAL;
-+ }
-+
-+ // if oobsel is NULL, use chip defaults
-+ if (oobsel == NULL)
-+ oobsel = &mtd->oobinfo;
-+
- /* Shift to get page */
- page = ((int) to) >> this->page_shift;
-
-- /* Get the starting column */
-- col = to & (mtd->oobblock - 1);
--
- /* Grab the lock and see if the device is available */
- nand_get_chip (this, mtd, FL_WRITING, NULL);
-
- /* Select the NAND device */
-- nand_select ();
-+ this->select_chip(mtd, 0);
-
- /* Check the WP bit */
- this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
-- if (!(readb (this->IO_ADDR_R) & 0x80)) {
-+ if (!(this->read_byte(mtd) & 0x80)) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_writev: Device is write protected!!!\n");
- ret = -EIO;
- goto out;
- }
-
- /* Loop until all iovecs' data has been written */
-- cnt = col;
- len = 0;
--
- while (count) {
- /*
-- * Check, if we write from offset 0 and if the tuple
-- * gives us not enough data for a full page write. Then we
-- * can use the iov direct, else we have to copy into
-- * data_buf.
-+ * Check, if the tuple gives us not enough data for a
-+ * full page write. Then we can use the iov direct,
-+ * else we have to copy into data_buf.
- */
-- if (!cnt && (vecs->iov_len - len) >= mtd->oobblock) {
-- cnt = mtd->oobblock;
-+ if ((vecs->iov_len - len) >= mtd->oobblock) {
- this->data_poi = (u_char *) vecs->iov_base;
- this->data_poi += len;
- len += mtd->oobblock;
-@@ -1042,6 +1108,7 @@
- * Read data out of each tuple until we have a full page
- * to write or we've read all the tuples.
- */
-+ int cnt = 0;
- while ((cnt < mtd->oobblock) && count) {
- if (vecs->iov_base != NULL && vecs->iov_len) {
- this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++];
-@@ -1057,15 +1124,12 @@
- }
-
- /* We use the same function for write and writev !) */
-- ret = nand_write_page (mtd, this, page, col, cnt, NULL, oobsel);
-+ ret = nand_write_page (mtd, this, page, NULL, oobsel);
- if (ret)
- goto out;
-
- /* Update written bytes count */
-- written += (cnt - col);
--
-- /* Reset written byte counter and column */
-- col = cnt = 0;
-+ written += mtd->oobblock;;
-
- /* Increment page address */
- page++;
-@@ -1073,7 +1137,7 @@
-
- out:
- /* De-select the NAND device */
-- nand_deselect ();
-+ this->select_chip(mtd, -1);
-
- /* Wake up anyone waiting on the device */
- spin_lock_bh (&this->chip_lock);
-@@ -1125,11 +1189,11 @@
- pages_per_block = mtd->erasesize / mtd->oobblock;
-
- /* Select the NAND device */
-- nand_select ();
-+ this->select_chip(mtd, 0);
-
- /* Check the WP bit */
- this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
-- if (!(readb (this->IO_ADDR_R) & 0x80)) {
-+ if (!(this->read_byte(mtd) & 0x80)) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Device is write protected!!!\n");
- instr->state = MTD_ERASE_FAILED;
- goto erase_exit;
-@@ -1142,8 +1206,7 @@
-
- while (len) {
- /* Check if we have a bad block, we do not erase bad blocks ! */
-- this->cmdfunc (mtd, NAND_CMD_READOOB, NAND_BADBLOCK_POS, page);
-- if (readb (this->IO_ADDR_R) != 0xff) {
-+ if (this->block_bad(mtd, page)) {
- printk (KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page);
- instr->state = MTD_ERASE_FAILED;
- goto erase_exit;
-@@ -1179,7 +1242,7 @@
- if (this->state == FL_ERASING || this->state == FL_READY) {
- /* Select the NAND device again, if we were interrupted */
- this->state = FL_ERASING;
-- nand_select ();
-+ this->select_chip(mtd, 0);
- continue;
- } else {
- set_current_state (TASK_UNINTERRUPTIBLE);
-@@ -1194,7 +1257,7 @@
-
- erase_exit:
- /* De-select the NAND device */
-- nand_deselect ();
-+ this->select_chip(mtd, -1);
- spin_unlock_bh (&this->chip_lock);
-
- ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;;
-@@ -1205,6 +1268,7 @@
- /* The device is ready */
- spin_lock_bh (&this->chip_lock);
- this->state = FL_READY;
-+ wake_up (&this->wq);
- spin_unlock_bh (&this->chip_lock);
-
- /* Return more or less happy */
-@@ -1259,7 +1323,7 @@
- /*
- * Scan for the NAND device
- */
--int nand_scan (struct mtd_info *mtd)
-+int nand_scan (struct mtd_info *mtd, int maxchips)
- {
- int i, nand_maf_id, nand_dev_id;
- struct nand_chip *this = mtd->priv;
-@@ -1276,23 +1340,38 @@
- if (this->waitfunc == NULL)
- this->waitfunc = nand_wait;
-
-+ if (!this->block_bad)
-+ this->block_bad = nand_block_bad;
-+ if (!this->select_chip)
-+ this->select_chip = nand_select_chip;
-+ if (!this->write_byte)
-+ this->write_byte = nand_write_byte;
-+ if (!this->read_byte)
-+ this->read_byte = nand_read_byte;
-+ if (!this->write_buf)
-+ this->write_buf = nand_write_buf;
-+ if (!this->read_buf)
-+ this->read_buf = nand_read_buf;
-+ if (!this->verify_buf)
-+ this->verify_buf = nand_verify_buf;
-+
- /* Select the device */
-- nand_select ();
-+ this->select_chip(mtd, 0);
-
- /* Send the command for reading device ID */
- this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
-
- /* Read manufacturer and device IDs */
-- nand_maf_id = readb (this->IO_ADDR_R);
-- nand_dev_id = readb (this->IO_ADDR_R);
-+ nand_maf_id = this->read_byte(mtd);
-+ nand_dev_id = this->read_byte(mtd);
-
- /* Print and store flash device information */
- for (i = 0; nand_flash_ids[i].name != NULL; i++) {
- if (nand_dev_id == nand_flash_ids[i].id && !mtd->size) {
- mtd->name = nand_flash_ids[i].name;
- mtd->erasesize = nand_flash_ids[i].erasesize;
-- mtd->size = (1 << nand_flash_ids[i].chipshift);
- mtd->eccsize = 256;
-+ this->chipshift = nand_flash_ids[i].chipshift;
- if (nand_flash_ids[i].page256) {
- mtd->oobblock = 256;
- mtd->oobsize = 8;
-@@ -1307,13 +1386,34 @@
- if (nand_manuf_ids[i].id == nand_maf_id)
- break;
- }
-- printk (KERN_INFO "NAND device: Manufacture ID:"
-+ printk (KERN_INFO "NAND device: Manufacturer ID:"
- " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
- nand_manuf_ids[i].name , mtd->name);
- break;
- }
- }
-
-+ if (!mtd->name) {
-+ printk (KERN_WARNING "No NAND device found!!!\n");
-+ return 1;
-+ }
-+
-+ for (i=1; i < maxchips; i++) {
-+ this->select_chip(mtd, i);
-+
-+ /* Send the command for reading device ID */
-+ this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
-+
-+ /* Read manufacturer and device IDs */
-+ if (nand_maf_id != this->read_byte(mtd) ||
-+ nand_dev_id != this->read_byte(mtd))
-+ break;
-+ }
-+ if (i > 1)
-+ printk(KERN_INFO "%d NAND chips detected\n", i);
-+
-+ mtd->size = (1 << this->chipshift) /* * i when we fix the rest of the code */;
-+
- /*
- * check ECC mode, default to software
- * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize
-@@ -1324,6 +1424,7 @@
- switch (this->eccmode) {
-
- case NAND_ECC_HW3_512:
-+ case NAND_ECC_HW6_512:
- if (mtd->oobblock == 256) {
- printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n");
- this->eccmode = NAND_ECC_SOFT;
-@@ -1340,6 +1441,7 @@
- BUG();
-
- case NAND_ECC_NONE:
-+ printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n");
- this->eccmode = NAND_ECC_NONE;
- break;
-
-@@ -1359,18 +1461,11 @@
- spin_lock_init (&this->chip_lock);
-
- /* De-select the device */
-- nand_deselect ();
--
-- /* Print warning message for no device */
-- if (!mtd->size) {
-- printk (KERN_WARNING "No NAND device found!!!\n");
-- return 1;
-- }
-+ this->select_chip(mtd, -1);
-
- /* Fill in remaining MTD driver data */
- mtd->type = MTD_NANDFLASH;
- mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC;
-- mtd->module = THIS_MODULE;
- mtd->ecctype = MTD_ECC_SW;
- mtd->erase = nand_erase;
- mtd->point = NULL;
-@@ -1389,6 +1484,7 @@
- mtd->unlock = NULL;
- mtd->suspend = NULL;
- mtd->resume = NULL;
-+ mtd->owner = THIS_MODULE;
-
- /* Return happy */
- return 0;
-@@ -1397,5 +1493,5 @@
- EXPORT_SYMBOL (nand_scan);
-
- MODULE_LICENSE ("GPL");
--MODULE_AUTHOR ("Steven J. Hill <sjhill@cotw.com>, Thomas Gleixner <tglx@linutronix.de>");
-+MODULE_AUTHOR ("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>");
- MODULE_DESCRIPTION ("Generic NAND flash driver code");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/nand/nand_ecc.c linux/drivers/mtd/nand/nand_ecc.c
---- linux-mips-2.4.24-pre2/drivers/mtd/nand/nand_ecc.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/nand/nand_ecc.c 2004-11-17 18:17:59.168294312 +0100
-@@ -1,10 +1,10 @@
- /*
- * drivers/mtd/nand_ecc.c
- *
-- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
-+ * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
- * Toshiba America Electronics Components, Inc.
- *
-- * $Id$
-+ * $Id$
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
-@@ -17,6 +17,7 @@
- #include <linux/types.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
-+#include <linux/mtd/nand_ecc.h>
-
- /*
- * Pre-calculated 256-way 1 byte column parity
-@@ -84,7 +85,7 @@
- /*
- * Calculate 3 byte ECC code for 256 byte block
- */
--void nand_calculate_ecc (const u_char *dat, u_char *ecc_code)
-+void nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
- {
- u_char idx, reg1, reg2, reg3;
- int j;
-@@ -119,7 +120,7 @@
- /*
- * Detect and correct a 1 bit error for 256 byte block
- */
--int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc)
-+int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
- {
- u_char a, b, c, d1, d2, d3, add, bit, i;
-
-@@ -209,5 +210,5 @@
- EXPORT_SYMBOL(nand_correct_data);
-
- MODULE_LICENSE("GPL");
--MODULE_AUTHOR("Steven J. Hill <sjhill@cotw.com>");
-+MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>");
- MODULE_DESCRIPTION("Generic NAND ECC support");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/nand/nand_ids.c linux/drivers/mtd/nand/nand_ids.c
---- linux-mips-2.4.24-pre2/drivers/mtd/nand/nand_ids.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/nand/nand_ids.c 2004-11-17 18:17:59.169294160 +0100
-@@ -4,7 +4,7 @@
- * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de)
- *
- *
-- * $Id$
-+ * $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
-@@ -18,21 +18,21 @@
- * Chip ID list
- */
- struct nand_flash_dev nand_flash_ids[] = {
-- {"NAND 1MB 5V", 0x6e, 20, 0x1000, 1}, // 1Mb 5V
-- {"NAND 2MB 5V", 0x64, 21, 0x1000, 1}, // 2Mb 5V
-- {"NAND 4MB 5V", 0x6b, 22, 0x2000, 0}, // 4Mb 5V
-- {"NAND 1MB 3,3V", 0xe8, 20, 0x1000, 1}, // 1Mb 3.3V
-- {"NAND 1MB 3,3V", 0xec, 20, 0x1000, 1}, // 1Mb 3.3V
-- {"NAND 2MB 3,3V", 0xea, 21, 0x1000, 1}, // 2Mb 3.3V
-- {"NAND 4MB 3,3V", 0xd5, 22, 0x2000, 0}, // 4Mb 3.3V
-- {"NAND 4MB 3,3V", 0xe3, 22, 0x2000, 0}, // 4Mb 3.3V
-- {"NAND 4MB 3,3V", 0xe5, 22, 0x2000, 0}, // 4Mb 3.3V
-- {"NAND 8MB 3,3V", 0xd6, 23, 0x2000, 0}, // 8Mb 3.3V
-- {"NAND 8MB 3,3V", 0xe6, 23, 0x2000, 0}, // 8Mb 3.3V
-- {"NAND 16MB 3,3V", 0x73, 24, 0x4000, 0},// 16Mb 3,3V
-- {"NAND 32MB 3,3V", 0x75, 25, 0x4000, 0}, // 32Mb 3,3V
-- {"NAND 64MB 3,3V", 0x76, 26, 0x4000, 0}, // 64Mb 3,3V
-- {"NAND 128MB 3,3V", 0x79, 27, 0x4000, 0}, // 128Mb 3,3V
-+ {"NAND 1MiB 5V", 0x6e, 20, 0x1000, 1},
-+ {"NAND 2MiB 5V", 0x64, 21, 0x1000, 1},
-+ {"NAND 4MiB 5V", 0x6b, 22, 0x2000, 0},
-+ {"NAND 1MiB 3,3V", 0xe8, 20, 0x1000, 1},
-+ {"NAND 1MiB 3,3V", 0xec, 20, 0x1000, 1},
-+ {"NAND 2MiB 3,3V", 0xea, 21, 0x1000, 1},
-+ {"NAND 4MiB 3,3V", 0xd5, 22, 0x2000, 0},
-+ {"NAND 4MiB 3,3V", 0xe3, 22, 0x2000, 0},
-+ {"NAND 4MiB 3,3V", 0xe5, 22, 0x2000, 0},
-+ {"NAND 8MiB 3,3V", 0xd6, 23, 0x2000, 0},
-+ {"NAND 8MiB 3,3V", 0xe6, 23, 0x2000, 0},
-+ {"NAND 16MiB 3,3V", 0x73, 24, 0x4000, 0},
-+ {"NAND 32MiB 3,3V", 0x75, 25, 0x4000, 0},
-+ {"NAND 64MiB 3,3V", 0x76, 26, 0x4000, 0},
-+ {"NAND 128MiB 3,3V", 0x79, 27, 0x4000, 0},
- {NULL,}
- };
-
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/nand/spia.c linux/drivers/mtd/nand/spia.c
---- linux-mips-2.4.24-pre2/drivers/mtd/nand/spia.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/nand/spia.c 2004-11-17 18:17:59.171293856 +0100
-@@ -1,14 +1,14 @@
- /*
- * drivers/mtd/nand/spia.c
- *
-- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
-+ * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
- *
- *
- * 10-29-2001 TG change to support hardwarespecific access
- * to controllines (due to change in nand.c)
- * page_cache added
- *
-- * $Id$
-+ * $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
-@@ -20,6 +20,8 @@
- * a 64Mibit (8MiB x 8 bits) NAND flash device.
- */
-
-+#include <linux/kernel.h>
-+#include <linux/init.h>
- #include <linux/slab.h>
- #include <linux/module.h>
- #include <linux/mtd/mtd.h>
-@@ -35,14 +37,14 @@
- /*
- * Values specific to the SPIA board (used with EP7212 processor)
- */
--#define SPIA_IO_ADDR = 0xd0000000 /* Start of EP7212 IO address space */
--#define SPIA_FIO_ADDR = 0xf0000000 /* Address where flash is mapped */
--#define SPIA_PEDR = 0x0080 /*
-+#define SPIA_IO_BASE 0xd0000000 /* Start of EP7212 IO address space */
-+#define SPIA_FIO_BASE 0xf0000000 /* Address where flash is mapped */
-+#define SPIA_PEDR 0x0080 /*
- * IO offset to Port E data register
- * where the CLE, ALE and NCE pins
- * are wired to.
- */
--#define SPIA_PEDDR = 0x00c0 /*
-+#define SPIA_PEDDR 0x00c0 /*
- * IO offset to Port E data direction
- * register so we can control the IO
- * lines.
-@@ -62,21 +64,20 @@
- MODULE_PARM(spia_pedr, "i");
- MODULE_PARM(spia_peddr, "i");
-
--__setup("spia_io_base=",spia_io_base);
--__setup("spia_fio_base=",spia_fio_base);
--__setup("spia_pedr=",spia_pedr);
--__setup("spia_peddr=",spia_peddr);
--
- /*
- * Define partitions for flash device
- */
- const static struct mtd_partition partition_info[] = {
-- { name: "SPIA flash partition 1",
-- offset: 0,
-- size: 2*1024*1024 },
-- { name: "SPIA flash partition 2",
-- offset: 2*1024*1024,
-- size: 6*1024*1024 }
-+ {
-+ .name = "SPIA flash partition 1",
-+ .offset = 0,
-+ .size = 2*1024*1024
-+ },
-+ {
-+ .name = "SPIA flash partition 2",
-+ .offset = 2*1024*1024,
-+ .size = 6*1024*1024
-+ }
- };
- #define NUM_PARTITIONS 2
-
-@@ -84,7 +85,7 @@
- /*
- * hardware specific access to control-lines
- */
--void spia_hwcontrol(int cmd){
-+static void spia_hwcontrol(struct mtd_info *mtd, int cmd){
-
- switch(cmd){
-
-@@ -139,7 +140,7 @@
- this->chip_delay = 15;
-
- /* Scan to find existence of the device */
-- if (nand_scan (spia_mtd)) {
-+ if (nand_scan (spia_mtd, 1)) {
- kfree (spia_mtd);
- return -ENXIO;
- }
-@@ -152,16 +153,6 @@
- return -ENOMEM;
- }
-
-- /* Allocate memory for internal data buffer */
-- this->data_cache = kmalloc (sizeof(u_char) * (spia_mtd->oobblock + spia_mtd->oobsize), GFP_KERNEL);
-- if (!this->data_cache) {
-- printk ("Unable to allocate NAND data cache for SPIA.\n");
-- kfree (this->data_buf);
-- kfree (spia_mtd);
-- return = -ENOMEM;
-- }
-- this->cache_page = -1;
--
- /* Register the partitions */
- add_mtd_partitions(spia_mtd, partition_info, NUM_PARTITIONS);
-
-@@ -183,7 +174,6 @@
-
- /* Free internal data buffer */
- kfree (this->data_buf);
-- kfree (this->page_cache);
-
- /* Free the MTD device structure */
- kfree (spia_mtd);
-@@ -192,5 +182,5 @@
- #endif
-
- MODULE_LICENSE("GPL");
--MODULE_AUTHOR("Steven J. Hill <sjhill@cotw.com");
-+MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com");
- MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on SPIA board");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/nand/toto.c linux/drivers/mtd/nand/toto.c
---- linux-mips-2.4.24-pre2/drivers/mtd/nand/toto.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/nand/toto.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,221 @@
-+/*
-+ * drivers/mtd/nand/toto.c
-+ *
-+ * Copyright (c) 2003 Texas Instruments
-+ *
-+ * Derived from drivers/mtd/autcpu12.c
-+ *
-+ * Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Overview:
-+ * This is a device driver for the NAND flash device found on the
-+ * TI fido board. It supports 32MiB and 64MiB cards
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/partitions.h>
-+#include <asm/io.h>
-+#include <asm/arch/hardware.h>
-+#include <asm/sizes.h>
-+#include <asm/arch/toto.h>
-+#include <asm/arch-omap1510/hardware.h>
-+#include <asm/arch/gpio.h>
-+
-+/*
-+ * MTD structure for TOTO board
-+ */
-+static struct mtd_info *toto_mtd = NULL;
-+
-+static int toto_io_base = OMAP_FLASH_1_BASE;
-+
-+#define CONFIG_NAND_WORKAROUND 1
-+
-+#define NAND_NCE 0x4000
-+#define NAND_CLE 0x1000
-+#define NAND_ALE 0x0002
-+#define NAND_MASK (NAND_CLE | NAND_ALE | NAND_NCE)
-+
-+#define T_NAND_CTL_CLRALE(iob) gpiosetout(NAND_ALE, 0)
-+#define T_NAND_CTL_SETALE(iob) gpiosetout(NAND_ALE, NAND_ALE)
-+#ifdef CONFIG_NAND_WORKAROUND /* "some" dev boards busted, blue wired to rts2 :( */
-+#define T_NAND_CTL_CLRCLE(iob) gpiosetout(NAND_CLE, 0); rts2setout(2, 2)
-+#define T_NAND_CTL_SETCLE(iob) gpiosetout(NAND_CLE, NAND_CLE); rts2setout(2, 0)
-+#else
-+#define T_NAND_CTL_CLRCLE(iob) gpiosetout(NAND_CLE, 0)
-+#define T_NAND_CTL_SETCLE(iob) gpiosetout(NAND_CLE, NAND_CLE)
-+#endif
-+#define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0)
-+#define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE)
-+
-+/*
-+ * Define partitions for flash devices
-+ */
-+
-+static struct mtd_partition partition_info64M[] = {
-+ { .name = "toto kernel partition 1",
-+ .offset = 0,
-+ .size = 2 * SZ_1M },
-+ { .name = "toto file sys partition 2",
-+ .offset = 2 * SZ_1M,
-+ .size = 14 * SZ_1M },
-+ { .name = "toto user partition 3",
-+ .offset = 16 * SZ_1M,
-+ .size = 16 * SZ_1M },
-+ { .name = "toto devboard extra partition 4",
-+ .offset = 32 * SZ_1M,
-+ .size = 32 * SZ_1M },
-+};
-+
-+static struct mtd_partition partition_info32M[] = {
-+ { .name = "toto kernel partition 1",
-+ .offset = 0,
-+ .size = 2 * SZ_1M },
-+ { .name = "toto file sys partition 2",
-+ .offset = 2 * SZ_1M,
-+ .size = 14 * SZ_1M },
-+ { .name = "toto user partition 3",
-+ .offset = 16 * SZ_1M,
-+ .size = 16 * SZ_1M },
-+};
-+
-+#define NUM_PARTITIONS32M 3
-+#define NUM_PARTITIONS64M 4
-+/*
-+ * hardware specific access to control-lines
-+*/
-+
-+static void toto_hwcontrol(struct mtd_info *mtd, int cmd)
-+{
-+
-+ udelay(1); /* hopefully enough time for tc make proceding write to clear */
-+ switch(cmd){
-+
-+ case NAND_CTL_SETCLE: T_NAND_CTL_SETCLE(cmd); break;
-+ case NAND_CTL_CLRCLE: T_NAND_CTL_CLRCLE(cmd); break;
-+
-+ case NAND_CTL_SETALE: T_NAND_CTL_SETALE(cmd); break;
-+ case NAND_CTL_CLRALE: T_NAND_CTL_CLRALE(cmd); break;
-+
-+ case NAND_CTL_SETNCE: T_NAND_CTL_SETNCE(cmd); break;
-+ case NAND_CTL_CLRNCE: T_NAND_CTL_CLRNCE(cmd); break;
-+ }
-+ udelay(1); /* allow time to ensure gpio state to over take memory write */
-+}
-+
-+/*
-+ * Main initialization routine
-+ */
-+int __init toto_init (void)
-+{
-+ struct nand_chip *this;
-+ int err = 0;
-+
-+ /* Allocate memory for MTD device structure and private data */
-+ toto_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
-+ GFP_KERNEL);
-+ if (!toto_mtd) {
-+ printk (KERN_WARNING "Unable to allocate toto NAND MTD device structure.\n");
-+ err = -ENOMEM;
-+ goto out;
-+ }
-+
-+ /* Get pointer to private data */
-+ this = (struct nand_chip *) (&toto_mtd[1]);
-+
-+ /* Initialize structures */
-+ memset((char *) toto_mtd, 0, sizeof(struct mtd_info));
-+ memset((char *) this, 0, sizeof(struct nand_chip));
-+
-+ /* Link the private data with the MTD structure */
-+ toto_mtd->priv = this;
-+
-+ /* Set address of NAND IO lines */
-+ this->IO_ADDR_R = toto_io_base;
-+ this->IO_ADDR_W = toto_io_base;
-+ this->hwcontrol = toto_hwcontrol;
-+ this->dev_ready = NULL;
-+ /* 25 us command delay time */
-+ this->chip_delay = 30;
-+ this->eccmode = NAND_ECC_SOFT;
-+
-+ /* Scan to find existance of the device */
-+ if (nand_scan (toto_mtd, 1)) {
-+ err = -ENXIO;
-+ goto out_mtd;
-+ }
-+
-+ /* Allocate memory for internal data buffer */
-+ this->data_buf = kmalloc (sizeof(u_char) * (toto_mtd->oobblock + toto_mtd->oobsize), GFP_KERNEL);
-+ if (!this->data_buf) {
-+ printk (KERN_WARNING "Unable to allocate NAND data buffer for toto.\n");
-+ err = -ENOMEM;
-+ goto out_mtd;
-+ }
-+
-+ /* Register the partitions */
-+ switch(toto_mtd->size){
-+ case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break;
-+ case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break;
-+ default: {
-+ printk (KERN_WARNING "Unsupported Nand device\n");
-+ err = -ENXIO;
-+ goto out_buf;
-+ }
-+ }
-+
-+ gpioreserve(NAND_MASK); /* claim our gpios */
-+ archflashwp(0,0); /* open up flash for writing */
-+
-+ goto out;
-+
-+out_buf:
-+ kfree (this->data_buf);
-+out_mtd:
-+ kfree (toto_mtd);
-+out:
-+ return err;
-+}
-+
-+module_init(toto_init);
-+
-+/*
-+ * Clean up routine
-+ */
-+static void __exit toto_cleanup (void)
-+{
-+ struct nand_chip *this = (struct nand_chip *) &toto_mtd[1];
-+
-+ /* Unregister partitions */
-+ del_mtd_partitions(toto_mtd);
-+
-+ /* Unregister the device */
-+ del_mtd_device (toto_mtd);
-+
-+ /* Free internal data buffers */
-+ kfree (this->data_buf);
-+
-+ /* Free the MTD device structure */
-+ kfree (toto_mtd);
-+
-+ /* stop flash writes */
-+ archflashwp(0,1);
-+
-+ /* release gpios to system */
-+ gpiorelease(NAND_MASK);
-+}
-+module_exit(toto_cleanup);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Richard Woodruff <r-woodruff2@ti.com>");
-+MODULE_DESCRIPTION("Glue layer for NAND flash on toto board");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/nand/tx4925ndfmc.c linux/drivers/mtd/nand/tx4925ndfmc.c
---- linux-mips-2.4.24-pre2/drivers/mtd/nand/tx4925ndfmc.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/nand/tx4925ndfmc.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,442 @@
-+/*
-+ * drivers/mtd/tx4925ndfmc.c
-+ *
-+ * Overview:
-+ * This is a device driver for the NAND flash device found on the
-+ * Toshiba RBTX4925 reference board, which is a SmartMediaCard. It supports
-+ * 16MiB, 32MiB and 64MiB cards.
-+ *
-+ * Author: MontaVista Software, Inc. source@mvista.com
-+ *
-+ * Derived from drivers/mtd/autcpu12.c
-+ * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
-+ *
-+ * $Id$
-+ *
-+ * Copyright (C) 2001 Toshiba Corporation
-+ *
-+ * 2003 (c) MontaVista Software, Inc. This file is licensed under
-+ * the terms of the GNU General Public License version 2. This program
-+ * is licensed "as is" without any warranty of any kind, whether express
-+ * or implied.
-+ *
-+ */
-+
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/delay.h>
-+#include <asm/io.h>
-+#include <asm/tx4925/tx4925_nand.h>
-+
-+extern struct nand_oobinfo jffs2_oobinfo;
-+
-+/*
-+ * MTD structure for RBTX4925 board
-+ */
-+static struct mtd_info *tx4925ndfmc_mtd = NULL;
-+
-+/*
-+ * Module stuff
-+ */
-+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-+#define tx4925ndfmc_init init_module
-+#define tx4925ndfmc_cleanup cleanup_module
-+#endif
-+
-+/*
-+ * Define partitions for flash devices
-+ */
-+
-+static struct mtd_partition partition_info16k[] = {
-+ { .name = "RBTX4925 flash partition 1",
-+ .offset = 0,
-+ .size = 8 * 0x00100000 },
-+ { .name = "RBTX4925 flash partition 2",
-+ .offset = 8 * 0x00100000,
-+ .size = 8 * 0x00100000 },
-+};
-+
-+static struct mtd_partition partition_info32k[] = {
-+ { .name = "RBTX4925 flash partition 1",
-+ .offset = 0,
-+ .size = 8 * 0x00100000 },
-+ { .name = "RBTX4925 flash partition 2",
-+ .offset = 8 * 0x00100000,
-+ .size = 24 * 0x00100000 },
-+};
-+
-+static struct mtd_partition partition_info64k[] = {
-+ { .name = "User FS",
-+ .offset = 0,
-+ .size = 16 * 0x00100000 },
-+ { .name = "RBTX4925 flash partition 2",
-+ .offset = 16 * 0x00100000,
-+ .size = 48 * 0x00100000},
-+};
-+
-+static struct mtd_partition partition_info128k[] = {
-+ { .name = "Skip bad section",
-+ .offset = 0,
-+ .size = 16 * 0x00100000 },
-+ { .name = "User FS",
-+ .offset = 16 * 0x00100000,
-+ .size = 112 * 0x00100000 },
-+};
-+#define NUM_PARTITIONS16K 2
-+#define NUM_PARTITIONS32K 2
-+#define NUM_PARTITIONS64K 2
-+#define NUM_PARTITIONS128K 2
-+
-+/*
-+ * hardware specific access to control-lines
-+*/
-+static void tx4925ndfmc_hwcontrol(struct mtd_info *mtd, int cmd)
-+{
-+
-+ switch(cmd){
-+
-+ case NAND_CTL_SETCLE:
-+ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_CLE;
-+ break;
-+ case NAND_CTL_CLRCLE:
-+ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_CLE;
-+ break;
-+ case NAND_CTL_SETALE:
-+ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ALE;
-+ break;
-+ case NAND_CTL_CLRALE:
-+ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ALE;
-+ break;
-+ case NAND_CTL_SETNCE:
-+ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_CE;
-+ break;
-+ case NAND_CTL_CLRNCE:
-+ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_CE;
-+ break;
-+ case NAND_CTL_SETWP:
-+ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_WE;
-+ break;
-+ case NAND_CTL_CLRWP:
-+ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_WE;
-+ break;
-+ }
-+}
-+
-+/*
-+* read device ready pin
-+*/
-+static int tx4925ndfmc_device_ready(struct mtd_info *mtd)
-+{
-+ int ready;
-+ ready = (tx4925_ndfmcptr->sr & TX4925_NDSFR_BUSY) ? 0 : 1;
-+ return ready;
-+}
-+void tx4925ndfmc_enable_hwecc(struct mtd_info *mtd, int mode)
-+{
-+ /* reset first */
-+ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_MASK;
-+ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
-+ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_ENAB;
-+}
-+static void tx4925ndfmc_disable_ecc(void)
-+{
-+ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
-+}
-+static void tx4925ndfmc_enable_read_ecc(void)
-+{
-+ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
-+ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_READ;
-+}
-+void tx4925ndfmc_readecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code){
-+ int i;
-+ u_char *ecc = ecc_code;
-+ tx4925ndfmc_enable_read_ecc();
-+ for (i = 0;i < 6;i++,ecc++)
-+ *ecc = tx4925_read_nfmc(&(tx4925_ndfmcptr->dtr));
-+ tx4925ndfmc_disable_ecc();
-+}
-+void tx4925ndfmc_device_setup(void)
-+{
-+
-+ *(unsigned char *)0xbb005000 &= ~0x08;
-+
-+ /* reset NDFMC */
-+ tx4925_ndfmcptr->rstr |= TX4925_NDFRSTR_RST;
-+ while (tx4925_ndfmcptr->rstr & TX4925_NDFRSTR_RST);
-+
-+ /* setup BusSeparete, Hold Time, Strobe Pulse Width */
-+ tx4925_ndfmcptr->mcr = TX4925_BSPRT ? TX4925_NDFMCR_BSPRT : 0;
-+ tx4925_ndfmcptr->spr = TX4925_HOLD << 4 | TX4925_SPW;
-+}
-+static u_char tx4925ndfmc_nand_read_byte(struct mtd_info *mtd)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ return tx4925_read_nfmc(this->IO_ADDR_R);
-+}
-+
-+static void tx4925ndfmc_nand_write_byte(struct mtd_info *mtd, u_char byte)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ tx4925_write_nfmc(byte, this->IO_ADDR_W);
-+}
-+
-+static void tx4925ndfmc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ tx4925_write_nfmc(buf[i], this->IO_ADDR_W);
-+}
-+
-+static void tx4925ndfmc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ buf[i] = tx4925_read_nfmc(this->IO_ADDR_R);
-+}
-+
-+static int tx4925ndfmc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ if (buf[i] != tx4925_read_nfmc(this->IO_ADDR_R))
-+ return i;
-+
-+ return 0;
-+}
-+
-+/*
-+ * Send command to NAND device
-+ */
-+static void tx4925ndfmc_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
-+{
-+ register struct nand_chip *this = mtd->priv;
-+
-+ /* Begin command latch cycle */
-+ this->hwcontrol(mtd, NAND_CTL_SETCLE);
-+ /*
-+ * Write out the command to the device.
-+ */
-+ if (command == NAND_CMD_SEQIN) {
-+ int readcmd;
-+
-+ if (column >= mtd->oobblock) {
-+ /* OOB area */
-+ column -= mtd->oobblock;
-+ readcmd = NAND_CMD_READOOB;
-+ } else if (column < 256) {
-+ /* First 256 bytes --> READ0 */
-+ readcmd = NAND_CMD_READ0;
-+ } else {
-+ column -= 256;
-+ readcmd = NAND_CMD_READ1;
-+ }
-+ this->write_byte(mtd, readcmd);
-+ }
-+ this->write_byte(mtd, command);
-+
-+ /* Set ALE and clear CLE to start address cycle */
-+ this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-+
-+ if (column != -1 || page_addr != -1) {
-+ this->hwcontrol(mtd, NAND_CTL_SETALE);
-+
-+ /* Serially input address */
-+ if (column != -1)
-+ this->write_byte(mtd, column);
-+ if (page_addr != -1) {
-+ this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
-+ this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
-+ /* One more address cycle for higher density devices */
-+ if (mtd->size & 0x0c000000)
-+ this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
-+ }
-+ /* Latch in address */
-+ this->hwcontrol(mtd, NAND_CTL_CLRALE);
-+ }
-+
-+ /*
-+ * program and erase have their own busy handlers
-+ * status and sequential in needs no delay
-+ */
-+ switch (command) {
-+
-+ case NAND_CMD_PAGEPROG:
-+ /* Turn off WE */
-+ this->hwcontrol (mtd, NAND_CTL_CLRWP);
-+ return;
-+
-+ case NAND_CMD_SEQIN:
-+ /* Turn on WE */
-+ this->hwcontrol (mtd, NAND_CTL_SETWP);
-+ return;
-+
-+ case NAND_CMD_ERASE1:
-+ case NAND_CMD_ERASE2:
-+ case NAND_CMD_STATUS:
-+ return;
-+
-+ case NAND_CMD_RESET:
-+ if (this->dev_ready)
-+ break;
-+ this->hwcontrol(mtd, NAND_CTL_SETCLE);
-+ this->write_byte(mtd, NAND_CMD_STATUS);
-+ this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-+ while ( !(this->read_byte(mtd) & 0x40));
-+ return;
-+
-+ /* This applies to read commands */
-+ default:
-+ /*
-+ * If we don't have access to the busy pin, we apply the given
-+ * command delay
-+ */
-+ if (!this->dev_ready) {
-+ udelay (this->chip_delay);
-+ return;
-+ }
-+ }
-+
-+ /* wait until command is processed */
-+ while (!this->dev_ready(mtd));
-+}
-+
-+#ifdef CONFIG_MTD_CMDLINE_PARTS
-+extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partitio
-+n **pparts, char *);
-+#endif
-+
-+/*
-+ * Main initialization routine
-+ */
-+extern int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
-+int __init tx4925ndfmc_init (void)
-+{
-+ struct nand_chip *this;
-+ int err = 0;
-+
-+ /* Allocate memory for MTD device structure and private data */
-+ tx4925ndfmc_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
-+ GFP_KERNEL);
-+ if (!tx4925ndfmc_mtd) {
-+ printk ("Unable to allocate RBTX4925 NAND MTD device structure.\n");
-+ err = -ENOMEM;
-+ goto out;
-+ }
-+
-+ tx4925ndfmc_device_setup();
-+
-+ /* io is indirect via a register so don't need to ioremap address */
-+
-+ /* Get pointer to private data */
-+ this = (struct nand_chip *) (&tx4925ndfmc_mtd[1]);
-+
-+ /* Initialize structures */
-+ memset((char *) tx4925ndfmc_mtd, 0, sizeof(struct mtd_info));
-+ memset((char *) this, 0, sizeof(struct nand_chip));
-+
-+ /* Link the private data with the MTD structure */
-+ tx4925ndfmc_mtd->priv = this;
-+
-+ /* Set address of NAND IO lines */
-+ this->IO_ADDR_R = (unsigned long)&(tx4925_ndfmcptr->dtr);
-+ this->IO_ADDR_W = (unsigned long)&(tx4925_ndfmcptr->dtr);
-+ this->hwcontrol = tx4925ndfmc_hwcontrol;
-+ this->enable_hwecc = tx4925ndfmc_enable_hwecc;
-+ this->calculate_ecc = tx4925ndfmc_readecc;
-+ this->correct_data = nand_correct_data;
-+ this->eccmode = NAND_ECC_HW6_512;
-+ this->dev_ready = tx4925ndfmc_device_ready;
-+ /* 20 us command delay time */
-+ this->chip_delay = 20;
-+ this->read_byte = tx4925ndfmc_nand_read_byte;
-+ this->write_byte = tx4925ndfmc_nand_write_byte;
-+ this->cmdfunc = tx4925ndfmc_nand_command;
-+ this->write_buf = tx4925ndfmc_nand_write_buf;
-+ this->read_buf = tx4925ndfmc_nand_read_buf;
-+ this->verify_buf = tx4925ndfmc_nand_verify_buf;
-+
-+ /* Scan to find existance of the device */
-+ if (nand_scan (tx4925ndfmc_mtd, 1)) {
-+ err = -ENXIO;
-+ goto out_ior;
-+ }
-+
-+ /* Allocate memory for internal data buffer */
-+ this->data_buf = kmalloc (sizeof(u_char) * (tx4925ndfmc_mtd->oobblock + tx4925ndfmc_mtd->oobsize), GFP_KERNEL);
-+ if (!this->data_buf) {
-+ printk ("Unable to allocate NAND data buffer for RBTX4925.\n");
-+ err = -ENOMEM;
-+ goto out_ior;
-+ }
-+
-+ /* Register the partitions */
-+#ifdef CONFIG_MTD_CMDLINE_PARTS
-+ {
-+ int mtd_parts_nb = 0;
-+ struct mtd_partition *mtd_parts = 0;
-+ mtd_parts_nb = parse_cmdline_partitions(tx4925ndfmc_mtd, &mtd_parts, "tx4925ndfmc");
-+ if (mtd_parts_nb > 0)
-+ add_mtd_partitions(tx4925ndfmc_mtd, mtd_parts, mtd_parts_nb);
-+ else
-+ add_mtd_device(tx4925ndfmc_mtd);
-+ }
-+#else /* ifdef CONFIG_MTD_CMDLINE_PARTS */
-+ switch(tx4925ndfmc_mtd->size){
-+ case 0x01000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info16k, NUM_PARTITIONS16K); break;
-+ case 0x02000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info32k, NUM_PARTITIONS32K); break;
-+ case 0x04000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info64k, NUM_PARTITIONS64K); break;
-+ case 0x08000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info128k, NUM_PARTITIONS128K); break;
-+ default: {
-+ printk ("Unsupported SmartMedia device\n");
-+ err = -ENXIO;
-+ goto out_buf;
-+ }
-+ }
-+#endif /* ifdef CONFIG_MTD_CMDLINE_PARTS */
-+ goto out;
-+
-+out_buf:
-+ kfree (this->data_buf);
-+out_ior:
-+out:
-+ return err;
-+}
-+
-+module_init(tx4925ndfmc_init);
-+
-+/*
-+ * Clean up routine
-+ */
-+#ifdef MODULE
-+static void __exit tx4925ndfmc_cleanup (void)
-+{
-+ struct nand_chip *this = (struct nand_chip *) &tx4925ndfmc_mtd[1];
-+
-+ /* Unregister partitions */
-+ del_mtd_partitions(tx4925ndfmc_mtd);
-+
-+ /* Unregister the device */
-+ del_mtd_device (tx4925ndfmc_mtd);
-+
-+ /* Free internal data buffers */
-+ kfree (this->data_buf);
-+
-+ /* Free the MTD device structure */
-+ kfree (tx4925ndfmc_mtd);
-+}
-+module_exit(tx4925ndfmc_cleanup);
-+#endif
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Alice Hennessy <ahennessy@mvista.com>");
-+MODULE_DESCRIPTION("Glue layer for SmartMediaCard on Toshiba RBTX4925");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/nand/tx4938ndfmc.c linux/drivers/mtd/nand/tx4938ndfmc.c
---- linux-mips-2.4.24-pre2/drivers/mtd/nand/tx4938ndfmc.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/nand/tx4938ndfmc.c 2004-11-17 18:17:59.000000000 +0100
-@@ -0,0 +1,422 @@
-+/*
-+ * drivers/mtd/nand/tx4938ndfmc.c
-+ *
-+ * Overview:
-+ * This is a device driver for the NAND flash device connected to
-+ * TX4938 internal NAND Memory Controller.
-+ * TX4938 NDFMC is almost same as TX4925 NDFMC, but register size are 64 bit.
-+ *
-+ * Author: source@mvista.com
-+ *
-+ * Based on spia.c by Steven J. Hill
-+ *
-+ * $Id$
-+ *
-+ * Copyright (C) 2000-2001 Toshiba Corporation
-+ *
-+ * 2003 (c) MontaVista Software, Inc. This file is licensed under the
-+ * terms of the GNU General Public License version 2. This program is
-+ * licensed "as is" without any warranty of any kind, whether express
-+ * or implied.
-+ */
-+#include <linux/config.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/nand_ecc.h>
-+#include <linux/mtd/partitions.h>
-+#include <asm/io.h>
-+#include <asm/bootinfo.h>
-+#include <linux/delay.h>
-+#include <asm/tx4938/rbtx4938.h>
-+
-+extern struct nand_oobinfo jffs2_oobinfo;
-+
-+/*
-+ * MTD structure for TX4938 NDFMC
-+ */
-+static struct mtd_info *tx4938ndfmc_mtd;
-+
-+/*
-+ * Define partitions for flash device
-+ */
-+#define flush_wb() (void)tx4938_ndfmcptr->mcr;
-+
-+#define NUM_PARTITIONS 3
-+#define NUMBER_OF_CIS_BLOCKS 24
-+#define SIZE_OF_BLOCK 0x00004000
-+#define NUMBER_OF_BLOCK_PER_ZONE 1024
-+#define SIZE_OF_ZONE (NUMBER_OF_BLOCK_PER_ZONE * SIZE_OF_BLOCK)
-+#ifndef CONFIG_MTD_CMDLINE_PARTS
-+/*
-+ * You can use the following sample of MTD partitions
-+ * on the NAND Flash Memory 32MB or more.
-+ *
-+ * The following figure shows the image of the sample partition on
-+ * the 32MB NAND Flash Memory.
-+ *
-+ * Block No.
-+ * 0 +-----------------------------+ ------
-+ * | CIS | ^
-+ * 24 +-----------------------------+ |
-+ * | kernel image | | Zone 0
-+ * | | |
-+ * +-----------------------------+ |
-+ * 1023 | unused area | v
-+ * +-----------------------------+ ------
-+ * 1024 | JFFS2 | ^
-+ * | | |
-+ * | | | Zone 1
-+ * | | |
-+ * | | |
-+ * | | v
-+ * 2047 +-----------------------------+ ------
-+ *
-+ */
-+static struct mtd_partition partition_info[NUM_PARTITIONS] = {
-+ {
-+ .name = "RBTX4938 CIS Area",
-+ .offset = 0,
-+ .size = (NUMBER_OF_CIS_BLOCKS * SIZE_OF_BLOCK),
-+ .mask_flags = MTD_WRITEABLE /* This partition is NOT writable */
-+ },
-+ {
-+ .name = "RBTX4938 kernel image",
-+ .offset = MTDPART_OFS_APPEND,
-+ .size = 8 * 0x00100000, /* 8MB (Depends on size of kernel image) */
-+ .mask_flags = MTD_WRITEABLE /* This partition is NOT writable */
-+ },
-+ {
-+ .name = "Root FS (JFFS2)",
-+ .offset = (0 + SIZE_OF_ZONE), /* start address of next zone */
-+ .size = MTDPART_SIZ_FULL
-+ },
-+};
-+#endif
-+
-+static void tx4938ndfmc_hwcontrol(struct mtd_info *mtd, int cmd)
-+{
-+ switch (cmd) {
-+ case NAND_CTL_SETCLE:
-+ tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_CLE;
-+ break;
-+ case NAND_CTL_CLRCLE:
-+ tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_CLE;
-+ break;
-+ case NAND_CTL_SETALE:
-+ tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_ALE;
-+ break;
-+ case NAND_CTL_CLRALE:
-+ tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_ALE;
-+ break;
-+ /* TX4938_NDFMCR_CE bit is 0:high 1:low */
-+ case NAND_CTL_SETNCE:
-+ tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_CE;
-+ break;
-+ case NAND_CTL_CLRNCE:
-+ tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_CE;
-+ break;
-+ case NAND_CTL_SETWP:
-+ tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_WE;
-+ break;
-+ case NAND_CTL_CLRWP:
-+ tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_WE;
-+ break;
-+ }
-+}
-+static int tx4938ndfmc_dev_ready(struct mtd_info *mtd)
-+{
-+ flush_wb();
-+ return !(tx4938_ndfmcptr->sr & TX4938_NDFSR_BUSY);
-+}
-+static void tx4938ndfmc_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
-+{
-+ u32 mcr = tx4938_ndfmcptr->mcr;
-+ mcr &= ~TX4938_NDFMCR_ECC_ALL;
-+ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
-+ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_READ;
-+ ecc_code[1] = tx4938_ndfmcptr->dtr;
-+ ecc_code[0] = tx4938_ndfmcptr->dtr;
-+ ecc_code[2] = tx4938_ndfmcptr->dtr;
-+ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
-+}
-+static void tx4938ndfmc_enable_hwecc(struct mtd_info *mtd, int mode)
-+{
-+ u32 mcr = tx4938_ndfmcptr->mcr;
-+ mcr &= ~TX4938_NDFMCR_ECC_ALL;
-+ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_RESET;
-+ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
-+ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_ON;
-+}
-+
-+static u_char tx4938ndfmc_nand_read_byte(struct mtd_info *mtd)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ return tx4938_read_nfmc(this->IO_ADDR_R);
-+}
-+
-+static void tx4938ndfmc_nand_write_byte(struct mtd_info *mtd, u_char byte)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ tx4938_write_nfmc(byte, this->IO_ADDR_W);
-+}
-+
-+static void tx4938ndfmc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ tx4938_write_nfmc(buf[i], this->IO_ADDR_W);
-+}
-+
-+static void tx4938ndfmc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ buf[i] = tx4938_read_nfmc(this->IO_ADDR_R);
-+}
-+
-+static int tx4938ndfmc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ if (buf[i] != tx4938_read_nfmc(this->IO_ADDR_R))
-+ return i;
-+
-+ return 0;
-+}
-+
-+/*
-+ * Send command to NAND device
-+ */
-+static void tx4938ndfmc_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
-+{
-+ register struct nand_chip *this = mtd->priv;
-+
-+ /* Begin command latch cycle */
-+ this->hwcontrol(mtd, NAND_CTL_SETCLE);
-+ /*
-+ * Write out the command to the device.
-+ */
-+ if (command == NAND_CMD_SEQIN) {
-+ int readcmd;
-+
-+ if (column >= mtd->oobblock) {
-+ /* OOB area */
-+ column -= mtd->oobblock;
-+ readcmd = NAND_CMD_READOOB;
-+ } else if (column < 256) {
-+ /* First 256 bytes --> READ0 */
-+ readcmd = NAND_CMD_READ0;
-+ } else {
-+ column -= 256;
-+ readcmd = NAND_CMD_READ1;
-+ }
-+ this->write_byte(mtd, readcmd);
-+ }
-+ this->write_byte(mtd, command);
-+
-+ /* Set ALE and clear CLE to start address cycle */
-+ this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-+
-+ if (column != -1 || page_addr != -1) {
-+ this->hwcontrol(mtd, NAND_CTL_SETALE);
-+
-+ /* Serially input address */
-+ if (column != -1)
-+ this->write_byte(mtd, column);
-+ if (page_addr != -1) {
-+ this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
-+ this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
-+ /* One more address cycle for higher density devices */
-+ if (mtd->size & 0x0c000000)
-+ this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
-+ }
-+ /* Latch in address */
-+ this->hwcontrol(mtd, NAND_CTL_CLRALE);
-+ }
-+
-+ /*
-+ * program and erase have their own busy handlers
-+ * status and sequential in needs no delay
-+ */
-+ switch (command) {
-+
-+ case NAND_CMD_PAGEPROG:
-+ /* Turn off WE */
-+ this->hwcontrol (mtd, NAND_CTL_CLRWP);
-+ return;
-+
-+ case NAND_CMD_SEQIN:
-+ /* Turn on WE */
-+ this->hwcontrol (mtd, NAND_CTL_SETWP);
-+ return;
-+
-+ case NAND_CMD_ERASE1:
-+ case NAND_CMD_ERASE2:
-+ case NAND_CMD_STATUS:
-+ return;
-+
-+ case NAND_CMD_RESET:
-+ if (this->dev_ready)
-+ break;
-+ this->hwcontrol(mtd, NAND_CTL_SETCLE);
-+ this->write_byte(mtd, NAND_CMD_STATUS);
-+ this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-+ while ( !(this->read_byte(mtd) & 0x40));
-+ return;
-+
-+ /* This applies to read commands */
-+ default:
-+ /*
-+ * If we don't have access to the busy pin, we apply the given
-+ * command delay
-+ */
-+ if (!this->dev_ready) {
-+ udelay (this->chip_delay);
-+ return;
-+ }
-+ }
-+
-+ /* wait until command is processed */
-+ while (!this->dev_ready(mtd));
-+}
-+
-+#ifdef CONFIG_MTD_CMDLINE_PARTS
-+extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, char *);
-+#endif
-+/*
-+ * Main initialization routine
-+ */
-+int __init tx4938ndfmc_init (void)
-+{
-+ struct nand_chip *this;
-+ int bsprt = 0, hold = 0xf, spw = 0xf;
-+ int protected = 0;
-+
-+ if ((*rbtx4938_piosel_ptr & 0x0c) != 0x08) {
-+ printk("TX4938 NDFMC: disabled by IOC PIOSEL\n");
-+ return -ENODEV;
-+ }
-+ bsprt = 1;
-+ hold = 2;
-+ spw = 9 - 1; /* 8 GBUSCLK = 80ns (@ GBUSCLK 100MHz) */
-+
-+ if ((tx4938_ccfgptr->pcfg &
-+ (TX4938_PCFG_ATA_SEL|TX4938_PCFG_ISA_SEL|TX4938_PCFG_NDF_SEL))
-+ != TX4938_PCFG_NDF_SEL) {
-+ printk("TX4938 NDFMC: disabled by PCFG.\n");
-+ return -ENODEV;
-+ }
-+
-+ /* reset NDFMC */
-+ tx4938_ndfmcptr->rstr |= TX4938_NDFRSTR_RST;
-+ while (tx4938_ndfmcptr->rstr & TX4938_NDFRSTR_RST)
-+ ;
-+ /* setup BusSeparete, Hold Time, Strobe Pulse Width */
-+ tx4938_ndfmcptr->mcr = bsprt ? TX4938_NDFMCR_BSPRT : 0;
-+ tx4938_ndfmcptr->spr = hold << 4 | spw;
-+
-+ /* Allocate memory for MTD device structure and private data */
-+ tx4938ndfmc_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
-+ GFP_KERNEL);
-+ if (!tx4938ndfmc_mtd) {
-+ printk ("Unable to allocate TX4938 NDFMC MTD device structure.\n");
-+ return -ENOMEM;
-+ }
-+
-+ /* Get pointer to private data */
-+ this = (struct nand_chip *) (&tx4938ndfmc_mtd[1]);
-+
-+ /* Initialize structures */
-+ memset((char *) tx4938ndfmc_mtd, 0, sizeof(struct mtd_info));
-+ memset((char *) this, 0, sizeof(struct nand_chip));
-+
-+ /* Link the private data with the MTD structure */
-+ tx4938ndfmc_mtd->priv = this;
-+
-+ /* Set address of NAND IO lines */
-+ this->IO_ADDR_R = (unsigned long)&tx4938_ndfmcptr->dtr;
-+ this->IO_ADDR_W = (unsigned long)&tx4938_ndfmcptr->dtr;
-+ this->hwcontrol = tx4938ndfmc_hwcontrol;
-+ this->dev_ready = tx4938ndfmc_dev_ready;
-+ this->calculate_ecc = tx4938ndfmc_calculate_ecc;
-+ this->correct_data = nand_correct_data;
-+ this->enable_hwecc = tx4938ndfmc_enable_hwecc;
-+ this->eccmode = NAND_ECC_HW3_256;
-+ this->chip_delay = 100;
-+ this->read_byte = tx4938ndfmc_nand_read_byte;
-+ this->write_byte = tx4938ndfmc_nand_write_byte;
-+ this->cmdfunc = tx4938ndfmc_nand_command;
-+ this->write_buf = tx4938ndfmc_nand_write_buf;
-+ this->read_buf = tx4938ndfmc_nand_read_buf;
-+ this->verify_buf = tx4938ndfmc_nand_verify_buf;
-+
-+ /* Scan to find existance of the device */
-+ if (nand_scan (tx4938ndfmc_mtd, 1)) {
-+ kfree (tx4938ndfmc_mtd);
-+ return -ENXIO;
-+ }
-+
-+ /* Allocate memory for internal data buffer */
-+ this->data_buf = kmalloc (sizeof(u_char) * (tx4938ndfmc_mtd->oobblock + tx4938ndfmc_mtd->oobsize), GFP_KERNEL);
-+ if (!this->data_buf) {
-+ printk ("Unable to allocate NAND data buffer for TX4938.\n");
-+ kfree (tx4938ndfmc_mtd);
-+ return -ENOMEM;
-+ }
-+
-+ if (protected) {
-+ printk(KERN_INFO "TX4938 NDFMC: write protected.\n");
-+ tx4938ndfmc_mtd->flags &= ~(MTD_WRITEABLE | MTD_ERASEABLE);
-+ }
-+
-+#ifdef CONFIG_MTD_CMDLINE_PARTS
-+ {
-+ int mtd_parts_nb = 0;
-+ struct mtd_partition *mtd_parts = 0;
-+ mtd_parts_nb = parse_cmdline_partitions(tx4938ndfmc_mtd, &mtd_parts, "tx4938ndfmc");
-+ if (mtd_parts_nb > 0)
-+ add_mtd_partitions(tx4938ndfmc_mtd, mtd_parts, mtd_parts_nb);
-+ else
-+ add_mtd_device(tx4938ndfmc_mtd);
-+ }
-+#else
-+ add_mtd_partitions(tx4938ndfmc_mtd, partition_info, NUM_PARTITIONS );
-+#endif
-+
-+ return 0;
-+}
-+module_init(tx4938ndfmc_init);
-+
-+/*
-+ * Clean up routine
-+ */
-+static void __exit tx4938ndfmc_cleanup (void)
-+{
-+ struct nand_chip *this = (struct nand_chip *) tx4938ndfmc_mtd->priv;
-+
-+ /* Unregister the device */
-+#ifdef CONFIG_MTD_CMDLINE_PARTS
-+ del_mtd_partitions(tx4938ndfmc_mtd);
-+#endif
-+ del_mtd_device (tx4938ndfmc_mtd);
-+
-+ /* Free the MTD device structure */
-+ kfree (tx4938ndfmc_mtd);
-+
-+ /* Free internal data buffer */
-+ kfree (this->data_buf);
-+}
-+module_exit(tx4938ndfmc_cleanup);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Alice Hennessy <ahennessy@mvista.com>");
-+MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on TX4938 NDFMC");
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/nftlcore.c linux/drivers/mtd/nftlcore.c
---- linux-mips-2.4.24-pre2/drivers/mtd/nftlcore.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/nftlcore.c 2004-11-17 18:17:58.881337936 +0100
-@@ -1,7 +1,7 @@
- /* Linux driver for NAND Flash Translation Layer */
- /* (c) 1999 Machine Vision Holdings, Inc. */
- /* Author: David Woodhouse <dwmw2@infradead.org> */
--/* $Id$ */
-+/* $Id$ */
-
- /*
- The contents of this file are distributed under the GNU General
-@@ -23,15 +23,13 @@
- #include <linux/slab.h>
- #include <linux/sched.h>
- #include <linux/init.h>
--#include <linux/blkpg.h>
-+#include <linux/hdreg.h>
-
--#ifdef CONFIG_KMOD
- #include <linux/kmod.h>
--#endif
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/nand.h>
- #include <linux/mtd/nftl.h>
--#include <linux/mtd/compatmac.h>
-+#include <linux/mtd/blktrans.h>
-
- /* maximum number of loops while examining next block, to have a
- chance to detect consistency problems (they should never happen
-@@ -39,187 +37,95 @@
-
- #define MAX_LOOPS 10000
-
--/* NFTL block device stuff */
--#define MAJOR_NR NFTL_MAJOR
--#define DEVICE_REQUEST nftl_request
--#define DEVICE_OFF(device)
--
--
--#include <linux/blk.h>
--#include <linux/hdreg.h>
--
--/* Linux-specific block device functions */
--
--/* I _HATE_ the Linux block device setup more than anything else I've ever
-- * encountered, except ...
-- */
--
--static int nftl_sizes[256];
--static int nftl_blocksizes[256];
--
--/* .. for the Linux partition table handling. */
--struct hd_struct part_table[256];
--
--#if LINUX_VERSION_CODE < 0x20328
--static void dummy_init (struct gendisk *crap)
--{}
--#endif
--
--static struct gendisk nftl_gendisk = {
-- major: MAJOR_NR,
-- major_name: "nftl",
-- minor_shift: NFTL_PARTN_BITS, /* Bits to shift to get real from partition */
-- max_p: (1<<NFTL_PARTN_BITS)-1, /* Number of partitions per real */
--#if LINUX_VERSION_CODE < 0x20328
-- max_nr: MAX_NFTLS, /* maximum number of real */
-- init: dummy_init, /* init function */
--#endif
-- part: part_table, /* hd struct */
-- sizes: nftl_sizes, /* block sizes */
--};
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
--#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
--#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
--#else
--#define BLK_INC_USE_COUNT do {} while(0)
--#define BLK_DEC_USE_COUNT do {} while(0)
--#endif
--
--struct NFTLrecord *NFTLs[MAX_NFTLS];
-
--static void NFTL_setup(struct mtd_info *mtd)
-+static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
- {
-- int i;
- struct NFTLrecord *nftl;
- unsigned long temp;
-- int firstfree = -1;
--
-- DEBUG(MTD_DEBUG_LEVEL1,"NFTL_setup\n");
-
-- for (i = 0; i < MAX_NFTLS; i++) {
-- if (!NFTLs[i] && firstfree == -1)
-- firstfree = i;
-- else if (NFTLs[i] && NFTLs[i]->mtd == mtd) {
-- /* This is a Spare Media Header for an NFTL we've already found */
-- DEBUG(MTD_DEBUG_LEVEL1, "MTD already mounted as NFTL\n");
-+ if (mtd->ecctype != MTD_ECC_RS_DiskOnChip)
- return;
-- }
-- }
-- if (firstfree == -1) {
-- printk(KERN_WARNING "No more NFTL slot available\n");
-- return;
-- }
-+
-+ DEBUG(MTD_DEBUG_LEVEL1, "NFTL: add_mtd for %s\n", mtd->name);
-
- nftl = kmalloc(sizeof(struct NFTLrecord), GFP_KERNEL);
-+
- if (!nftl) {
-- printk(KERN_WARNING "Out of memory for NFTL data structures\n");
-+ printk(KERN_WARNING "NFTL: out of memory for data structures\n");
- return;
- }
-+ memset(nftl, 0, sizeof(*nftl));
-
-- init_MUTEX(&nftl->mutex);
--
-- nftl->mtd = mtd;
-+ nftl->mbd.mtd = mtd;
-+ nftl->mbd.devnum = -1;
-+ nftl->mbd.blksize = 512;
-+ nftl->mbd.tr = tr;
-
- if (NFTL_mount(nftl) < 0) {
-- printk(KERN_WARNING "Could not mount NFTL device\n");
-+ printk(KERN_WARNING "NFTL: could not mount device\n");
- kfree(nftl);
- return;
- }
-
- /* OK, it's a new one. Set up all the data structures. */
--#ifdef PSYCHO_DEBUG
-- printk("Found new NFTL nftl%c\n", firstfree + 'a');
--#endif
-
-- /* linux stuff */
-- nftl->usecount = 0;
-+ /* Calculate geometry */
- nftl->cylinders = 1024;
- nftl->heads = 16;
-
- temp = nftl->cylinders * nftl->heads;
-- nftl->sectors = nftl->nr_sects / temp;
-- if (nftl->nr_sects % temp) {
-+ nftl->sectors = nftl->mbd.size / temp;
-+ if (nftl->mbd.size % temp) {
- nftl->sectors++;
- temp = nftl->cylinders * nftl->sectors;
-- nftl->heads = nftl->nr_sects / temp;
-+ nftl->heads = nftl->mbd.size / temp;
-
-- if (nftl->nr_sects % temp) {
-+ if (nftl->mbd.size % temp) {
- nftl->heads++;
- temp = nftl->heads * nftl->sectors;
-- nftl->cylinders = nftl->nr_sects / temp;
-+ nftl->cylinders = nftl->mbd.size / temp;
- }
- }
-
-- if (nftl->nr_sects != nftl->heads * nftl->cylinders * nftl->sectors) {
-- printk(KERN_WARNING "Cannot calculate an NFTL geometry to "
-- "match size of 0x%x.\n", nftl->nr_sects);
-- printk(KERN_WARNING "Using C:%d H:%d S:%d (== 0x%lx sects)\n",
-+ if (nftl->mbd.size != nftl->heads * nftl->cylinders * nftl->sectors) {
-+ /*
-+ Oh no we don't have
-+ mbd.size == heads * cylinders * sectors
-+ */
-+ printk(KERN_WARNING "NFTL: cannot calculate a geometry to "
-+ "match size of 0x%lx.\n", nftl->mbd.size);
-+ printk(KERN_WARNING "NFTL: using C:%d H:%d S:%d "
-+ "(== 0x%lx sects)\n",
- nftl->cylinders, nftl->heads , nftl->sectors,
-- (long)nftl->cylinders * (long)nftl->heads * (long)nftl->sectors );
--
-- /* Oh no we don't have nftl->nr_sects = nftl->heads * nftl->cylinders * nftl->sectors; */
-+ (long)nftl->cylinders * (long)nftl->heads *
-+ (long)nftl->sectors );
- }
-- NFTLs[firstfree] = nftl;
-- /* Finally, set up the block device sizes */
-- nftl_sizes[firstfree * 16] = nftl->nr_sects;
-- //nftl_blocksizes[firstfree*16] = 512;
-- part_table[firstfree * 16].nr_sects = nftl->nr_sects;
--
-- nftl_gendisk.nr_real++;
--
-- /* partition check ... */
--#if LINUX_VERSION_CODE < 0x20328
-- resetup_one_dev(&nftl_gendisk, firstfree);
--#else
-- grok_partitions(&nftl_gendisk, firstfree, 1<<NFTL_PARTN_BITS, nftl->nr_sects);
--#endif
--}
--
--static void NFTL_unsetup(int i)
--{
-- struct NFTLrecord *nftl = NFTLs[i];
--
-- DEBUG(MTD_DEBUG_LEVEL1, "NFTL_unsetup %d\n", i);
--
-- NFTLs[i] = NULL;
-
-+ if (add_mtd_blktrans_dev(&nftl->mbd)) {
- if (nftl->ReplUnitTable)
- kfree(nftl->ReplUnitTable);
- if (nftl->EUNtable)
- kfree(nftl->EUNtable);
--
-- nftl_gendisk.nr_real--;
- kfree(nftl);
--}
--
--/* Search the MTD device for NFTL partitions */
--static void NFTL_notify_add(struct mtd_info *mtd)
--{
-- DEBUG(MTD_DEBUG_LEVEL1, "NFTL_notify_add for %s\n", mtd->name);
--
-- if (mtd) {
-- if (!mtd->read_oob) {
-- /* If this MTD doesn't have out-of-band data,
-- then there's no point continuing */
-- DEBUG(MTD_DEBUG_LEVEL1, "No OOB data, quitting\n");
- return;
- }
-- DEBUG(MTD_DEBUG_LEVEL3, "mtd->read = %p, size = %d, erasesize = %d\n",
-- mtd->read, mtd->size, mtd->erasesize);
--
-- NFTL_setup(mtd);
-- }
-+#ifdef PSYCHO_DEBUG
-+ printk(KERN_INFO "NFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a');
-+#endif
- }
-
--static void NFTL_notify_remove(struct mtd_info *mtd)
-+static void nftl_remove_dev(struct mtd_blktrans_dev *dev)
- {
-- int i;
-+ struct NFTLrecord *nftl = (void *)dev;
-
-- for (i = 0; i < MAX_NFTLS; i++) {
-- if (NFTLs[i] && NFTLs[i]->mtd == mtd)
-- NFTL_unsetup(i);
-- }
-+ DEBUG(MTD_DEBUG_LEVEL1, "NFTL: remove_dev (i=%d)\n", dev->devnum);
-+
-+ del_mtd_blktrans_dev(dev);
-+ if (nftl->ReplUnitTable)
-+ kfree(nftl->ReplUnitTable);
-+ if (nftl->EUNtable)
-+ kfree(nftl->EUNtable);
-+ kfree(nftl);
- }
-
- #ifdef CONFIG_NFTL_RW
-@@ -303,7 +209,7 @@
-
- targetEUN = thisEUN;
- for (block = 0; block < nftl->EraseSize / 512; block ++) {
-- MTD_READOOB(nftl->mtd,
-+ MTD_READOOB(nftl->mbd.mtd,
- (thisEUN * nftl->EraseSize) + (block * 512),
- 16 , &retlen, (char *)&oob);
- if (block == 2) {
-@@ -420,7 +326,7 @@
- chain by selecting the longer one */
- oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS);
- oob.u.c.unused = 0xffffffff;
-- MTD_WRITEOOB(nftl->mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8,
-+ MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8,
- 8, &retlen, (char *)&oob.u);
- }
-
-@@ -444,16 +350,16 @@
- if (BlockMap[block] == BLOCK_NIL)
- continue;
-
-- ret = MTD_READECC(nftl->mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512),
-+ ret = MTD_READECC(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512),
- 512, &retlen, movebuf, (char *)&oob, NAND_ECC_DISKONCHIP);
- if (ret < 0) {
-- ret = MTD_READECC(nftl->mtd, (nftl->EraseSize * BlockMap[block])
-+ ret = MTD_READECC(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block])
- + (block * 512), 512, &retlen,
- movebuf, (char *)&oob, NAND_ECC_DISKONCHIP);
- if (ret != -EIO)
- printk("Error went away on retry.\n");
- }
-- MTD_WRITEECC(nftl->mtd, (nftl->EraseSize * targetEUN) + (block * 512),
-+ MTD_WRITEECC(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + (block * 512),
- 512, &retlen, movebuf, (char *)&oob, NAND_ECC_DISKONCHIP);
- }
-
-@@ -462,7 +368,7 @@
- = cpu_to_le16(thisVUC);
- oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff;
-
-- MTD_WRITEOOB(nftl->mtd, (nftl->EraseSize * targetEUN) + 8,
-+ MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 8,
- 8, &retlen, (char *)&oob.u);
-
- /* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */
-@@ -582,7 +488,7 @@
-
- lastEUN = writeEUN;
-
-- MTD_READOOB(nftl->mtd, (writeEUN * nftl->EraseSize) + blockofs,
-+ MTD_READOOB(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs,
- 8, &retlen, (char *)&bci);
-
- DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n",
-@@ -670,12 +576,12 @@
- nftl->ReplUnitTable[writeEUN] = BLOCK_NIL;
-
- /* ... and on the flash itself */
-- MTD_READOOB(nftl->mtd, writeEUN * nftl->EraseSize + 8, 8,
-+ MTD_READOOB(nftl->mbd.mtd, writeEUN * nftl->EraseSize + 8, 8,
- &retlen, (char *)&oob.u);
-
- oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum = cpu_to_le16(thisVUC);
-
-- MTD_WRITEOOB(nftl->mtd, writeEUN * nftl->EraseSize + 8, 8,
-+ MTD_WRITEOOB(nftl->mbd.mtd, writeEUN * nftl->EraseSize + 8, 8,
- &retlen, (char *)&oob.u);
-
- /* we link the new block to the chain only after the
-@@ -685,13 +591,13 @@
- /* Both in our cache... */
- nftl->ReplUnitTable[lastEUN] = writeEUN;
- /* ... and on the flash itself */
-- MTD_READOOB(nftl->mtd, (lastEUN * nftl->EraseSize) + 8,
-+ MTD_READOOB(nftl->mbd.mtd, (lastEUN * nftl->EraseSize) + 8,
- 8, &retlen, (char *)&oob.u);
-
- oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum
- = cpu_to_le16(writeEUN);
-
-- MTD_WRITEOOB(nftl->mtd, (lastEUN * nftl->EraseSize) + 8,
-+ MTD_WRITEOOB(nftl->mbd.mtd, (lastEUN * nftl->EraseSize) + 8,
- 8, &retlen, (char *)&oob.u);
- }
-
-@@ -704,8 +610,10 @@
- return 0xffff;
- }
-
--static int NFTL_writeblock(struct NFTLrecord *nftl, unsigned block, char *buffer)
-+static int nftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
-+ char *buffer)
- {
-+ struct NFTLrecord *nftl = (void *)mbd;
- u16 writeEUN;
- unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1);
- size_t retlen;
-@@ -720,7 +628,7 @@
- return 1;
- }
-
-- MTD_WRITEECC(nftl->mtd, (writeEUN * nftl->EraseSize) + blockofs,
-+ MTD_WRITEECC(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs,
- 512, &retlen, (char *)buffer, (char *)eccbuf, NAND_ECC_DISKONCHIP);
- /* no need to write SECTOR_USED flags since they are written in mtd_writeecc */
-
-@@ -728,8 +636,10 @@
- }
- #endif /* CONFIG_NFTL_RW */
-
--static int NFTL_readblock(struct NFTLrecord *nftl, unsigned block, char *buffer)
-+static int nftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
-+ char *buffer)
- {
-+ struct NFTLrecord *nftl = (void *)mbd;
- u16 lastgoodEUN;
- u16 thisEUN = nftl->EUNtable[block / (nftl->EraseSize / 512)];
- unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1);
-@@ -742,7 +652,7 @@
-
- if (thisEUN != BLOCK_NIL) {
- while (thisEUN < nftl->nb_blocks) {
-- if (MTD_READOOB(nftl->mtd, (thisEUN * nftl->EraseSize) + blockofs,
-+ if (MTD_READOOB(nftl->mbd.mtd, (thisEUN * nftl->EraseSize) + blockofs,
- 8, &retlen, (char *)&bci) < 0)
- status = SECTOR_IGNORE;
- else
-@@ -761,13 +671,13 @@
- case SECTOR_IGNORE:
- break;
- default:
-- printk("Unknown status for block %d in EUN %d: %x\n",
-+ printk("Unknown status for block %ld in EUN %d: %x\n",
- block, thisEUN, status);
- break;
- }
-
- if (!silly--) {
-- printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%x\n",
-+ printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%lx\n",
- block / (nftl->EraseSize / 512));
- return 1;
- }
-@@ -783,264 +693,22 @@
- loff_t ptr = (lastgoodEUN * nftl->EraseSize) + blockofs;
- size_t retlen;
- u_char eccbuf[6];
-- if (MTD_READECC(nftl->mtd, ptr, 512, &retlen, buffer, eccbuf, NAND_ECC_DISKONCHIP))
-+ if (MTD_READECC(nftl->mbd.mtd, ptr, 512, &retlen, buffer, eccbuf, NAND_ECC_DISKONCHIP))
- return -EIO;
- }
- return 0;
- }
-
--static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
--{
-- struct NFTLrecord *nftl;
-- int p;
--
-- nftl = NFTLs[MINOR(inode->i_rdev) >> NFTL_PARTN_BITS];
--
-- if (!nftl) return -EINVAL;
--
-- switch (cmd) {
-- case HDIO_GETGEO: {
-- struct hd_geometry g;
--
-- g.heads = nftl->heads;
-- g.sectors = nftl->sectors;
-- g.cylinders = nftl->cylinders;
-- g.start = part_table[MINOR(inode->i_rdev)].start_sect;
-- return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0;
-- }
-- case BLKGETSIZE: /* Return device size */
-- return put_user(part_table[MINOR(inode->i_rdev)].nr_sects,
-- (unsigned long *) arg);
--
--#ifdef BLKGETSIZE64
-- case BLKGETSIZE64:
-- return put_user((u64)part_table[MINOR(inode->i_rdev)].nr_sects << 9,
-- (u64 *)arg);
--#endif
--
-- case BLKFLSBUF:
-- if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-- fsync_dev(inode->i_rdev);
-- invalidate_buffers(inode->i_rdev);
-- if (nftl->mtd->sync)
-- nftl->mtd->sync(nftl->mtd);
-- return 0;
--
-- case BLKRRPART:
-- if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-- if (nftl->usecount > 1) return -EBUSY;
-- /*
-- * We have to flush all buffers and invalidate caches,
-- * or we won't be able to re-use the partitions,
-- * if there was a change and we don't want to reboot
-- */
-- p = (1<<NFTL_PARTN_BITS) - 1;
-- while (p-- > 0) {
-- kdev_t devp = MKDEV(MAJOR(inode->i_dev), MINOR(inode->i_dev)+p);
-- if (part_table[p].nr_sects > 0)
-- invalidate_device (devp, 1);
--
-- part_table[MINOR(inode->i_dev)+p].start_sect = 0;
-- part_table[MINOR(inode->i_dev)+p].nr_sects = 0;
-- }
--
--#if LINUX_VERSION_CODE < 0x20328
-- resetup_one_dev(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS);
--#else
-- grok_partitions(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS,
-- 1<<NFTL_PARTN_BITS, nftl->nr_sects);
--#endif
-- return 0;
--
--#if (LINUX_VERSION_CODE < 0x20303)
-- RO_IOCTLS(inode->i_rdev, arg); /* ref. linux/blk.h */
--#else
-- case BLKROSET:
-- case BLKROGET:
-- case BLKSSZGET:
-- return blk_ioctl(inode->i_rdev, cmd, arg);
--#endif
--
-- default:
-- return -EINVAL;
-- }
--}
--
--void nftl_request(RQFUNC_ARG)
--{
-- unsigned int dev, block, nsect;
-- struct NFTLrecord *nftl;
-- char *buffer;
-- struct request *req;
-- int res;
--
-- while (1) {
-- INIT_REQUEST; /* blk.h */
-- req = CURRENT;
--
-- /* We can do this because the generic code knows not to
-- touch the request at the head of the queue */
-- spin_unlock_irq(&io_request_lock);
--
-- DEBUG(MTD_DEBUG_LEVEL2, "NFTL_request\n");
-- DEBUG(MTD_DEBUG_LEVEL3, "NFTL %s request, from sector 0x%04lx for 0x%04lx sectors\n",
-- (req->cmd == READ) ? "Read " : "Write",
-- req->sector, req->current_nr_sectors);
--
-- dev = MINOR(req->rq_dev);
-- block = req->sector;
-- nsect = req->current_nr_sectors;
-- buffer = req->buffer;
-- res = 1; /* succeed */
--
-- if (dev >= MAX_NFTLS * (1<<NFTL_PARTN_BITS)) {
-- /* there is no such partition */
-- printk("nftl: bad minor number: device = %s\n",
-- kdevname(req->rq_dev));
-- res = 0; /* fail */
-- goto repeat;
-- }
--
-- nftl = NFTLs[dev / (1<<NFTL_PARTN_BITS)];
-- DEBUG(MTD_DEBUG_LEVEL3, "Waiting for mutex\n");
-- down(&nftl->mutex);
-- DEBUG(MTD_DEBUG_LEVEL3, "Got mutex\n");
--
-- if (block + nsect > part_table[dev].nr_sects) {
-- /* access past the end of device */
-- printk("nftl%c%d: bad access: block = %d, count = %d\n",
-- (MINOR(req->rq_dev)>>6)+'a', dev & 0xf, block, nsect);
-- up(&nftl->mutex);
-- res = 0; /* fail */
-- goto repeat;
-- }
--
-- block += part_table[dev].start_sect;
--
-- if (req->cmd == READ) {
-- DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request of 0x%x sectors @ %x "
-- "(req->nr_sectors == %lx)\n", nsect, block, req->nr_sectors);
--
-- for ( ; nsect > 0; nsect-- , block++, buffer += 512) {
-- /* Read a single sector to req->buffer + (512 * i) */
-- if (NFTL_readblock(nftl, block, buffer)) {
-- DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request failed\n");
-- up(&nftl->mutex);
-- res = 0;
-- goto repeat;
-- }
-- }
--
-- DEBUG(MTD_DEBUG_LEVEL2,"NFTL read request completed OK\n");
-- up(&nftl->mutex);
-- goto repeat;
-- } else if (req->cmd == WRITE) {
-- DEBUG(MTD_DEBUG_LEVEL2, "NFTL write request of 0x%x sectors @ %x "
-- "(req->nr_sectors == %lx)\n", nsect, block,
-- req->nr_sectors);
--#ifdef CONFIG_NFTL_RW
-- for ( ; nsect > 0; nsect-- , block++, buffer += 512) {
-- /* Read a single sector to req->buffer + (512 * i) */
-- if (NFTL_writeblock(nftl, block, buffer)) {
-- DEBUG(MTD_DEBUG_LEVEL1,"NFTL write request failed\n");
-- up(&nftl->mutex);
-- res = 0;
-- goto repeat;
-- }
-- }
-- DEBUG(MTD_DEBUG_LEVEL2,"NFTL write request completed OK\n");
--#else
-- res = 0; /* Writes always fail */
--#endif /* CONFIG_NFTL_RW */
-- up(&nftl->mutex);
-- goto repeat;
-- } else {
-- DEBUG(MTD_DEBUG_LEVEL0, "NFTL unknown request\n");
-- up(&nftl->mutex);
-- res = 0;
-- goto repeat;
-- }
-- repeat:
-- DEBUG(MTD_DEBUG_LEVEL3, "end_request(%d)\n", res);
-- spin_lock_irq(&io_request_lock);
-- end_request(res);
-- }
--}
--
--static int nftl_open(struct inode *ip, struct file *fp)
--{
-- int nftlnum = MINOR(ip->i_rdev) >> NFTL_PARTN_BITS;
-- struct NFTLrecord *thisNFTL;
-- thisNFTL = NFTLs[nftlnum];
--
-- DEBUG(MTD_DEBUG_LEVEL2,"NFTL_open\n");
--
--#ifdef CONFIG_KMOD
-- if (!thisNFTL && nftlnum == 0) {
-- request_module("docprobe");
-- thisNFTL = NFTLs[nftlnum];
-- }
--#endif
-- if (!thisNFTL) {
-- DEBUG(MTD_DEBUG_LEVEL2,"ENODEV: thisNFTL = %d, minor = %d, ip = %p, fp = %p\n",
-- nftlnum, ip->i_rdev, ip, fp);
-- return -ENODEV;
-- }
--
--#ifndef CONFIG_NFTL_RW
-- if (fp->f_mode & FMODE_WRITE)
-- return -EROFS;
--#endif /* !CONFIG_NFTL_RW */
--
-- thisNFTL->usecount++;
-- BLK_INC_USE_COUNT;
-- if (!get_mtd_device(thisNFTL->mtd, -1)) {
-- BLK_DEC_USE_COUNT;
-- return -ENXIO;
-- }
--
-- return 0;
--}
--
--static int nftl_release(struct inode *inode, struct file *fp)
-+static int nftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
- {
-- struct NFTLrecord *thisNFTL;
--
-- thisNFTL = NFTLs[MINOR(inode->i_rdev) / 16];
--
-- DEBUG(MTD_DEBUG_LEVEL2, "NFTL_release\n");
--
-- if (thisNFTL->mtd->sync)
-- thisNFTL->mtd->sync(thisNFTL->mtd);
-- thisNFTL->usecount--;
-- BLK_DEC_USE_COUNT;
-+ struct NFTLrecord *nftl = (void *)dev;
-
-- put_mtd_device(thisNFTL->mtd);
-+ geo->heads = nftl->heads;
-+ geo->sectors = nftl->sectors;
-+ geo->cylinders = nftl->cylinders;
-
- return 0;
- }
--#if LINUX_VERSION_CODE < 0x20326
--static struct file_operations nftl_fops = {
-- read: block_read,
-- write: block_write,
-- ioctl: nftl_ioctl,
-- open: nftl_open,
-- release: nftl_release,
-- fsync: block_fsync,
--};
--#else
--static struct block_device_operations nftl_fops =
--{
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14)
-- owner: THIS_MODULE,
--#endif
-- open: nftl_open,
-- release: nftl_release,
-- ioctl: nftl_ioctl
--};
--#endif
--
--
-
- /****************************************************************************
- *
-@@ -1048,49 +716,33 @@
- *
- ****************************************************************************/
-
--static struct mtd_notifier nftl_notifier = {
-- add: NFTL_notify_add,
-- remove: NFTL_notify_remove
-+
-+struct mtd_blktrans_ops nftl_tr = {
-+ .name = "nftl",
-+ .major = NFTL_MAJOR,
-+ .part_bits = NFTL_PARTN_BITS,
-+ .getgeo = nftl_getgeo,
-+ .readsect = nftl_readblock,
-+#ifdef CONFIG_NFTL_RW
-+ .writesect = nftl_writeblock,
-+#endif
-+ .add_mtd = nftl_add_mtd,
-+ .remove_dev = nftl_remove_dev,
-+ .owner = THIS_MODULE,
- };
-
- extern char nftlmountrev[];
-
- int __init init_nftl(void)
- {
-- int i;
--
--#ifdef PRERELEASE
-- printk(KERN_INFO "NFTL driver: nftlcore.c $Revision$, nftlmount.c %s\n", nftlmountrev);
--#endif
--
-- if (register_blkdev(MAJOR_NR, "nftl", &nftl_fops)){
-- printk("unable to register NFTL block device on major %d\n", MAJOR_NR);
-- return -EBUSY;
-- } else {
-- blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &nftl_request);
-+ printk(KERN_INFO "NFTL driver: nftlcore.c $Revision$, nftlmount.c %s\n", nftlmountrev);
-
-- /* set block size to 1kB each */
-- for (i = 0; i < 256; i++) {
-- nftl_blocksizes[i] = 1024;
-- }
-- blksize_size[MAJOR_NR] = nftl_blocksizes;
--
-- add_gendisk(&nftl_gendisk);
-- }
--
-- register_mtd_user(&nftl_notifier);
--
-- return 0;
-+ return register_mtd_blktrans(&nftl_tr);
- }
-
- static void __exit cleanup_nftl(void)
- {
-- unregister_mtd_user(&nftl_notifier);
-- unregister_blkdev(MAJOR_NR, "nftl");
--
-- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
--
-- del_gendisk(&nftl_gendisk);
-+ deregister_mtd_blktrans(&nftl_tr);
- }
-
- module_init(init_nftl);
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/nftlmount.c linux/drivers/mtd/nftlmount.c
---- linux-mips-2.4.24-pre2/drivers/mtd/nftlmount.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/nftlmount.c 2004-11-17 18:17:58.899335200 +0100
-@@ -4,7 +4,7 @@
- * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
- * Copyright (C) 2000 Netgem S.A.
- *
-- * $Id$
-+ * $Id$
- *
- * 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
-@@ -21,26 +21,17 @@
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
--#define __NO_VERSION__
- #include <linux/kernel.h>
--#include <linux/module.h>
- #include <asm/errno.h>
--#include <asm/io.h>
--#include <asm/uaccess.h>
--#include <linux/miscdevice.h>
--#include <linux/pci.h>
- #include <linux/delay.h>
- #include <linux/slab.h>
--#include <linux/sched.h>
--#include <linux/init.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/nand.h>
- #include <linux/mtd/nftl.h>
--#include <linux/mtd/compatmac.h>
-
- #define SECTORSIZE 512
-
--char nftlmountrev[]="$Revision$";
-+char nftlmountrev[]="$Revision$";
-
- /* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
- * various device information of the NFTL partition and Bad Unit Table. Update
-@@ -59,8 +50,8 @@
-
- /* Assume logical EraseSize == physical erasesize for starting the scan.
- We'll sort it out later if we find a MediaHeader which says otherwise */
-- nftl->EraseSize = nftl->mtd->erasesize;
-- nftl->nb_blocks = nftl->mtd->size / nftl->EraseSize;
-+ nftl->EraseSize = nftl->mbd.mtd->erasesize;
-+ nftl->nb_blocks = nftl->mbd.mtd->size / nftl->EraseSize;
-
- nftl->MediaUnit = BLOCK_NIL;
- nftl->SpareMediaUnit = BLOCK_NIL;
-@@ -71,12 +62,12 @@
-
- /* Check for ANAND header first. Then can whinge if it's found but later
- checks fail */
-- if ((ret = MTD_READ(nftl->mtd, block * nftl->EraseSize, SECTORSIZE, &retlen, buf))) {
-+ if ((ret = MTD_READ(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE, &retlen, buf))) {
- static int warncount = 5;
-
- if (warncount) {
- printk(KERN_WARNING "Block read at 0x%x of mtd%d failed: %d\n",
-- block * nftl->EraseSize, nftl->mtd->index, ret);
-+ block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
- if (!--warncount)
- printk(KERN_WARNING "Further failures for this block will not be printed\n");
- }
-@@ -87,16 +78,16 @@
- /* ANAND\0 not found. Continue */
- #if 0
- printk(KERN_DEBUG "ANAND header not found at 0x%x in mtd%d\n",
-- block * nftl->EraseSize, nftl->mtd->index);
-+ block * nftl->EraseSize, nftl->mbd.mtd->index);
- #endif
- continue;
- }
-
- /* To be safer with BIOS, also use erase mark as discriminant */
-- if ((ret = MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8,
-- 8, &retlen, (char *)&h1)) < 0) {
-+ if ((ret = MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8,
-+ 8, &retlen, (char *)&h1) < 0)) {
- printk(KERN_WARNING "ANAND header found at 0x%x in mtd%d, but OOB data read failed (err %d)\n",
-- block * nftl->EraseSize, nftl->mtd->index, ret);
-+ block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
- continue;
- }
-
-@@ -106,23 +97,23 @@
- */
- if (le16_to_cpu(h1.EraseMark | h1.EraseMark1) != ERASE_MARK) {
- printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but erase mark not present (0x%04x,0x%04x instead)\n",
-- block * nftl->EraseSize, nftl->mtd->index,
-+ block * nftl->EraseSize, nftl->mbd.mtd->index,
- le16_to_cpu(h1.EraseMark), le16_to_cpu(h1.EraseMark1));
- continue;
- }
-
- /* Finally reread to check ECC */
-- if ((ret = MTD_READECC(nftl->mtd, block * nftl->EraseSize, SECTORSIZE,
-- &retlen, buf, (char *)&oob, NAND_ECC_DISKONCHIP)) < 0) {
-+ if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE,
-+ &retlen, buf, (char *)&oob, NAND_ECC_DISKONCHIP) < 0)) {
- printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but ECC read failed (err %d)\n",
-- block * nftl->EraseSize, nftl->mtd->index, ret);
-+ block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
- continue;
- }
-
- /* Paranoia. Check the ANAND header is still there after the ECC read */
- if (memcmp(buf, "ANAND", 6)) {
- printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but went away on reread!\n",
-- block * nftl->EraseSize, nftl->mtd->index);
-+ block * nftl->EraseSize, nftl->mbd.mtd->index);
- printk(KERN_NOTICE "New data are: %02x %02x %02x %02x %02x %02x\n",
- buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
- continue;
-@@ -137,8 +128,12 @@
- printk(KERN_NOTICE "NFTL Media Headers at 0x%x and 0x%x disagree.\n",
- nftl->MediaUnit * nftl->EraseSize, block * nftl->EraseSize);
- /* if (debug) Print both side by side */
-+ if (boot_record_count < 2) {
-+ /* We haven't yet seen two real ones */
- return -1;
- }
-+ continue;
-+ }
- if (boot_record_count == 1)
- nftl->SpareMediaUnit = block;
-
-@@ -163,8 +158,8 @@
- } else if (mh->UnitSizeFactor != 0xff) {
- printk(KERN_NOTICE "WARNING: Support for NFTL with UnitSizeFactor 0x%02x is experimental\n",
- mh->UnitSizeFactor);
-- nftl->EraseSize = nftl->mtd->erasesize << (0xff - mh->UnitSizeFactor);
-- nftl->nb_blocks = nftl->mtd->size / nftl->EraseSize;
-+ nftl->EraseSize = nftl->mbd.mtd->erasesize << (0xff - mh->UnitSizeFactor);
-+ nftl->nb_blocks = nftl->mbd.mtd->size / nftl->EraseSize;
- }
- nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN);
- if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) {
-@@ -182,7 +177,7 @@
- return -1;
- }
-
-- nftl->nr_sects = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
-+ nftl->mbd.size = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
-
- /* If we're not using the last sectors in the device for some reason,
- reduce nb_blocks accordingly so we forget they're there */
-@@ -220,7 +215,7 @@
- for (i = 0; i < nftl->nb_blocks; i++) {
- if ((i & (SECTORSIZE - 1)) == 0) {
- /* read one sector for every SECTORSIZE of blocks */
-- if ((ret = MTD_READECC(nftl->mtd, block * nftl->EraseSize +
-+ if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize +
- i + SECTORSIZE, SECTORSIZE, &retlen, buf,
- (char *)&oob, NAND_ECC_DISKONCHIP)) < 0) {
- printk(KERN_NOTICE "Read of bad sector table failed (err %d)\n",
-@@ -263,16 +258,16 @@
- for (i = 0; i < len; i += SECTORSIZE) {
- /* we want to read the sector without ECC check here since a free
- sector does not have ECC syndrome on it yet */
-- if (MTD_READ(nftl->mtd, address, SECTORSIZE, &retlen, buf) < 0)
-+ if (MTD_READ(nftl->mbd.mtd, address, SECTORSIZE, &retlen, buf) < 0)
- return -1;
- if (memcmpb(buf, 0xff, SECTORSIZE) != 0)
- return -1;
-
- if (check_oob) {
-- if (MTD_READOOB(nftl->mtd, address, nftl->mtd->oobsize,
-+ if (MTD_READOOB(nftl->mbd.mtd, address, nftl->mbd.mtd->oobsize,
- &retlen, buf) < 0)
- return -1;
-- if (memcmpb(buf, 0xff, nftl->mtd->oobsize) != 0)
-+ if (memcmpb(buf, 0xff, nftl->mbd.mtd->oobsize) != 0)
- return -1;
- }
- address += SECTORSIZE;
-@@ -297,7 +292,7 @@
- struct erase_info *instr = &nftl->instr;
-
- /* Read the Unit Control Information #1 for Wear-Leveling */
-- if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8,
-+ if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8,
- 8, &retlen, (char *)&uci) < 0)
- goto default_uci1;
-
-@@ -314,7 +309,7 @@
- /* XXX: use async erase interface, XXX: test return code */
- instr->addr = block * nftl->EraseSize;
- instr->len = nftl->EraseSize;
-- MTD_ERASE(nftl->mtd, instr);
-+ MTD_ERASE(nftl->mbd.mtd, instr);
-
- if (instr->state == MTD_ERASE_FAILED) {
- /* could not format, FixMe: We should update the BadUnitTable
-@@ -337,7 +332,7 @@
- return -1;
-
- uci.WearInfo = le32_to_cpu(nb_erases);
-- if (MTD_WRITEOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
-+ if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
- &retlen, (char *)&uci) < 0)
- return -1;
- return 0;
-@@ -363,7 +358,7 @@
- block = first_block;
- for (;;) {
- for (i = 0; i < sectors_per_block; i++) {
-- if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + i * SECTORSIZE,
-+ if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i * SECTORSIZE,
- 8, &retlen, (char *)&bci) < 0)
- status = SECTOR_IGNORE;
- else
-@@ -383,7 +378,7 @@
- /* sector not free actually : mark it as SECTOR_IGNORE */
- bci.Status = SECTOR_IGNORE;
- bci.Status1 = SECTOR_IGNORE;
-- MTD_WRITEOOB(nftl->mtd,
-+ MTD_WRITEOOB(nftl->mbd.mtd,
- block * nftl->EraseSize + i * SECTORSIZE,
- 8, &retlen, (char *)&bci);
- }
-@@ -476,7 +471,7 @@
- size_t retlen;
-
- /* check erase mark. */
-- if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
-+ if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
- &retlen, (char *)&h1) < 0)
- return -1;
-
-@@ -491,7 +486,7 @@
- h1.EraseMark = cpu_to_le16(ERASE_MARK);
- h1.EraseMark1 = cpu_to_le16(ERASE_MARK);
- h1.WearInfo = cpu_to_le32(0);
-- if (MTD_WRITEOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
-+ if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
- &retlen, (char *)&h1) < 0)
- return -1;
- } else {
-@@ -503,7 +498,7 @@
- SECTORSIZE, 0) != 0)
- return -1;
-
-- if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + i,
-+ if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i,
- 16, &retlen, buf) < 0)
- return -1;
- if (i == SECTORSIZE) {
-@@ -533,7 +528,7 @@
- struct nftl_uci2 uci;
- size_t retlen;
-
-- if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8,
-+ if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8,
- 8, &retlen, (char *)&uci) < 0)
- return 0;
-
-@@ -572,9 +567,9 @@
-
- for (;;) {
- /* read the block header. If error, we format the chain */
-- if (MTD_READOOB(s->mtd, block * s->EraseSize + 8, 8,
-+ if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 8,
- &retlen, (char *)&h0) < 0 ||
-- MTD_READOOB(s->mtd, block * s->EraseSize + SECTORSIZE + 8, 8,
-+ MTD_READOOB(s->mbd.mtd, block * s->EraseSize + SECTORSIZE + 8, 8,
- &retlen, (char *)&h1) < 0) {
- s->ReplUnitTable[block] = BLOCK_NIL;
- do_format_chain = 1;
-diff -Nurb linux-mips-2.4.24-pre2/drivers/mtd/redboot.c linux/drivers/mtd/redboot.c
---- linux-mips-2.4.24-pre2/drivers/mtd/redboot.c 2004-11-17 18:04:53.000000000 +0100
-+++ linux/drivers/mtd/redboot.c 2004-11-17 18:17:58.901334896 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Parse RedBoot-style Flash Image System (FIS) tables and
- * produce a Linux partition array to match.
-@@ -7,6 +7,7 @@
-
- #include <linux/kernel.h>
- #include <linux/slab.h>
-+#include <linux/init.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/partitions.h>
-@@ -34,7 +35,9 @@
- return 1;
- }
-
--int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts)
-+static int parse_redboot_partitions(struct mtd_info *master,
-+ struct mtd_partition **pparts,
-+ unsigned long fis_origin)
- {
- int nrparts = 0;
- struct fis_image_desc *buf;
-@@ -43,7 +46,9 @@
- int ret, i;
- size_t retlen;
- char *names;
-+ char *nullname;
- int namelen = 0;
-+ static char nullstring[] = "unallocated";
-
- buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-
-@@ -90,7 +95,11 @@
- goto out;
- }
- new_fl->img = &buf[i];
-+ if (fis_origin) {
-+ buf[i].flash_base -= fis_origin;
-+ } else {
- buf[i].flash_base &= master->size-1;
-+ }
-
- /* I'm sure the JFFS2 code has done me permanent damage.
- * I now think the following is _normal_
-@@ -110,18 +119,24 @@
- if (tmp_fl->img->flash_base + tmp_fl->img->size + master->erasesize < tmp_fl->next->img->flash_base)
- nrparts++;
- }
-- parts = kmalloc(sizeof(*parts)*nrparts + namelen, GFP_KERNEL);
-+ parts = kmalloc(sizeof(*parts)*nrparts + sizeof(nullstring) + namelen, GFP_KERNEL);
-
- if (!parts) {
- ret = -ENOMEM;
- goto out;
- }
-- names = (char *)&parts[nrparts];
-+
- memset(parts, 0, sizeof(*parts)*nrparts + namelen);
-+
-+ /* FIXME: Include nullname only if it's used */
-+ nullname = (char *)&parts[nrparts];
-+ sprintf(nullname, nullstring);
-+ names = nullname + sizeof(nullstring);
-+
- i=0;
-
- if (fl->img->flash_base) {
-- parts[0].name = "unallocated space";
-+ parts[0].name = nullname;
- parts[0].size = fl->img->flash_base;
- parts[0].offset = 0;
- }
-@@ -133,11 +148,11 @@
- strcpy(names, fl->img->name);
- names += strlen(names)+1;
-
-- if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize < fl->next->img->flash_base) {
-+ if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) {
- i++;
- parts[i].offset = parts[i-1].size + parts[i-1].offset;
- parts[i].size = fl->next->img->flash_base - parts[i].offset;
-- parts[i].name = "unallocated space";
-+ parts[i].name = nullname;
- }
- tmp_fl = fl;
- fl = fl->next;
-@@ -155,7 +170,24 @@
- return ret;
- }
-
--EXPORT_SYMBOL(parse_redboot_partitions);
-+static struct mtd_part_parser redboot_parser = {
-+ .owner = THIS_MODULE,
-+ .parse_fn = parse_redboot_partitions,
-+ .name = "RedBoot",
-+};
-+
-+static int __init redboot_parser_init(void)
-+{
-+ return register_mtd_parser(&redboot_parser);
-+}
-+
-+static void __exit redboot_parser_exit(void)
-+{
-+ deregister_mtd_parser(&redboot_parser);
-+}
-+
-+module_init(redboot_parser_init);
-+module_exit(redboot_parser_exit);
-
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.com>");
-diff -Nurb linux-mips-2.4.24-pre2/fs/Config.in linux/fs/Config.in
---- linux-mips-2.4.24-pre2/fs/Config.in 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/Config.in 2004-11-17 18:17:59.489245520 +0100
-@@ -49,6 +49,7 @@
- dep_tristate 'Journalling Flash File System v2 (JFFS2) support' CONFIG_JFFS2_FS $CONFIG_MTD
- if [ "$CONFIG_JFFS2_FS" = "y" -o "$CONFIG_JFFS2_FS" = "m" ] ; then
- int 'JFFS2 debugging verbosity (0 = quiet, 2 = noisy)' CONFIG_JFFS2_FS_DEBUG 0
-+ bool 'JFFS2 support for NAND chips' CONFIG_JFFS2_FS_NAND
- fi
- tristate 'Compressed ROM file system support' CONFIG_CRAMFS
- bool 'Virtual memory file system support (former shm fs)' CONFIG_TMPFS
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/Makefile linux/fs/jffs2/Makefile
---- linux-mips-2.4.24-pre2/fs/jffs2/Makefile 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/Makefile 2004-11-17 18:17:59.000000000 +0100
-@@ -1,7 +1,7 @@
- #
- # Makefile for the linux Journalling Flash FileSystem (JFFS) routines.
- #
--# $Id$
-+# $Id$
- #
- # Note! Dependencies are done automagically by 'make dep', which also
- # removes any old dependencies. DON'T put your own dependencies here
-@@ -10,16 +10,31 @@
- # Note 2! The CFLAGS definitions are now in the main makefile...
-
-
--COMPR_OBJS := compr.o compr_rubin.o compr_rtime.o pushpull.o \
-- compr_zlib.o
-+obj-$(CONFIG_JFFS2_FS) := jffs2.o
-+
-+COMPR_OBJS := compr.o compr_rubin.o compr_rtime.o compr_zlib.o
- JFFS2_OBJS := dir.o file.o ioctl.o nodelist.o malloc.o \
-- read.o nodemgmt.o readinode.o super.o write.o scan.o gc.o \
-- symlink.o build.o erase.o background.o
-+ read.o nodemgmt.o readinode.o write.o scan.o gc.o \
-+ symlink.o build.o erase.o background.o fs.o writev.o
-
--O_TARGET := jffs2.o
-+BELOW25 := $(shell echo $(PATCHLEVEL) | sed s/[1234]/y/)
-+
-+ifeq ($(BELOW25),y)
-+LINUX_OBJS := super-v24.o crc32.o rbtree.o
-+else
-+LINUX_OBJS := super.o
-+endif
-
--obj-y := $(COMPR_OBJS) $(JFFS2_OBJS)
--obj-m := $(O_TARGET)
-+NAND_OBJS-$(CONFIG_JFFS2_FS_NAND) := wbuf.o
-
-+jffs2-objs := $(COMPR_OBJS) $(JFFS2_OBJS) $(VERS_OBJS) $(NAND_OBJS-y) \
-+ $(LINUX_OBJS)
-+
-+
-+# 2.4 build compatibility
-+ifeq ($(BELOW25),y)
-+obj-y := $(jffs2-objs)
-+O_TARGET := jffs2.o
- include $(TOPDIR)/Rules.make
-+endif
-
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/background.c linux/fs/jffs2/background.c
---- linux-mips-2.4.24-pre2/fs/jffs2/background.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/background.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,61 +1,36 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #define __KERNEL_SYSCALLS__
-
- #include <linux/kernel.h>
--#include <linux/sched.h>
--#include <linux/unistd.h>
- #include <linux/jffs2.h>
- #include <linux/mtd/mtd.h>
--#include <linux/interrupt.h>
- #include <linux/completion.h>
-+#include <linux/sched.h>
-+#include <linux/unistd.h>
-+#include <linux/suspend.h>
- #include "nodelist.h"
-
-
- static int jffs2_garbage_collect_thread(void *);
--static int thread_should_wake(struct jffs2_sb_info *c);
-
- void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c)
- {
-- spin_lock_bh(&c->erase_completion_lock);
-- if (c->gc_task && thread_should_wake(c))
-+ spin_lock(&c->erase_completion_lock);
-+ if (c->gc_task && jffs2_thread_should_wake(c))
- send_sig(SIGHUP, c->gc_task, 1);
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
- }
-
- /* This must only ever be called when no GC thread is currently running */
-@@ -86,12 +61,12 @@
-
- void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c)
- {
-- spin_lock_bh(&c->erase_completion_lock);
-+ spin_lock(&c->erase_completion_lock);
- if (c->gc_task) {
- D1(printk(KERN_DEBUG "jffs2: Killing GC task %d\n", c->gc_task->pid));
- send_sig(SIGKILL, c->gc_task, 1);
- }
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
- wait_for_completion(&c->gc_thread_exit);
- }
-
-@@ -99,34 +74,37 @@
- {
- struct jffs2_sb_info *c = _c;
-
-- daemonize();
-- current->tty = NULL;
-+ daemonize("jffs2_gcd_mtd%d", c->mtd->index);
-+ allow_signal(SIGKILL);
-+ allow_signal(SIGSTOP);
-+ allow_signal(SIGCONT);
-+
- c->gc_task = current;
- up(&c->gc_thread_start);
-
-- sprintf(current->comm, "jffs2_gcd_mtd%d", c->mtd->index);
--
-- /* FIXME in the 2.2 backport */
-- current->nice = 10;
-+ set_user_nice(current, 10);
-
- for (;;) {
-- spin_lock_irq(&current->sigmask_lock);
-- siginitsetinv (&current->blocked, sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGCONT));
-- recalc_sigpending(current);
-- spin_unlock_irq(&current->sigmask_lock);
-+ allow_signal(SIGHUP);
-
-- if (!thread_should_wake(c)) {
-+ if (!jffs2_thread_should_wake(c)) {
- set_current_state (TASK_INTERRUPTIBLE);
- D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n"));
-- /* Yes, there's a race here; we checked thread_should_wake() before
-- setting current->state to TASK_INTERRUPTIBLE. But it doesn't
-+ /* Yes, there's a race here; we checked jffs2_thread_should_wake()
-+ before setting current->state to TASK_INTERRUPTIBLE. But it doesn't
- matter - We don't care if we miss a wakeup, because the GC thread
- is only an optimisation anyway. */
- schedule();
- }
-
-- if (current->need_resched)
-- schedule();
-+ if (current->flags & PF_FREEZE) {
-+ refrigerator(0);
-+ /* refrigerator() should recalc sigpending for us
-+ but doesn't. No matter - allow_signal() will. */
-+ continue;
-+ }
-+
-+ cond_resched();
-
- /* Put_super will send a SIGKILL and then wait on the sem.
- */
-@@ -134,9 +112,7 @@
- siginfo_t info;
- unsigned long signr;
-
-- spin_lock_irq(&current->sigmask_lock);
-- signr = dequeue_signal(&current->blocked, &info);
-- spin_unlock_irq(&current->sigmask_lock);
-+ signr = dequeue_signal_lock(current, &current->blocked, &info);
-
- switch(signr) {
- case SIGSTOP:
-@@ -147,9 +123,10 @@
-
- case SIGKILL:
- D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread(): SIGKILL received.\n"));
-- spin_lock_bh(&c->erase_completion_lock);
-+ die:
-+ spin_lock(&c->erase_completion_lock);
- c->gc_task = NULL;
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
- complete_and_exit(&c->gc_thread_exit, 0);
-
- case SIGHUP:
-@@ -157,27 +134,15 @@
- break;
- default:
- D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread(): signal %ld received\n", signr));
--
- }
- }
- /* We don't want SIGHUP to interrupt us. STOP and KILL are OK though. */
-- spin_lock_irq(&current->sigmask_lock);
-- siginitsetinv (&current->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGCONT));
-- recalc_sigpending(current);
-- spin_unlock_irq(&current->sigmask_lock);
-+ disallow_signal(SIGHUP);
-
- D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread(): pass\n"));
-- jffs2_garbage_collect_pass(c);
-+ if (jffs2_garbage_collect_pass(c) == -ENOSPC) {
-+ printk(KERN_NOTICE "No space for garbage collection. Aborting GC thread\n");
-+ goto die;
-+ }
- }
--}
--
--static int thread_should_wake(struct jffs2_sb_info *c)
--{
-- D1(printk(KERN_DEBUG "thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x\n",
-- c->nr_free_blocks, c->nr_erasing_blocks, c->dirty_size));
-- if (c->nr_free_blocks + c->nr_erasing_blocks < JFFS2_RESERVED_BLOCKS_GCTRIGGER &&
-- c->dirty_size > c->sector_size)
-- return 1;
-- else
-- return 0;
- }
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/build.c linux/fs/jffs2/build.c
---- linux-mips-2.4.24-pre2/fs/jffs2/build.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/build.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,47 +1,22 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/kernel.h>
--#include <linux/jffs2.h>
-+#include <linux/sched.h>
- #include <linux/slab.h>
- #include "nodelist.h"
-
--int jffs2_build_inode_pass1(struct jffs2_sb_info *, struct jffs2_inode_cache *);
--int jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *, struct jffs2_inode_cache *);
-+static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *, struct jffs2_inode_cache *, struct jffs2_full_dirent **);
-
- static inline struct jffs2_inode_cache *
- first_inode_chain(int *i, struct jffs2_sb_info *c)
-@@ -68,16 +43,52 @@
- ic; \
- ic = next_inode(&i, ic, (c)))
-
-+
-+static inline void jffs2_build_inode_pass1(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
-+{
-+ struct jffs2_full_dirent *fd;
-+
-+ D1(printk(KERN_DEBUG "jffs2_build_inode building directory inode #%u\n", ic->ino));
-+
-+ /* For each child, increase nlink */
-+ for(fd = ic->scan_dents; fd; fd = fd->next) {
-+ struct jffs2_inode_cache *child_ic;
-+ if (!fd->ino)
-+ continue;
-+
-+ /* XXX: Can get high latency here with huge directories */
-+
-+ child_ic = jffs2_get_ino_cache(c, fd->ino);
-+ if (!child_ic) {
-+ printk(KERN_NOTICE "Eep. Child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n",
-+ fd->name, fd->ino, ic->ino);
-+ continue;
-+ }
-+
-+ if (child_ic->nlink++ && fd->type == DT_DIR) {
-+ printk(KERN_NOTICE "Child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", fd->name, fd->ino, ic->ino);
-+ if (fd->ino == 1 && ic->ino == 1) {
-+ printk(KERN_NOTICE "This is mostly harmless, and probably caused by creating a JFFS2 image\n");
-+ printk(KERN_NOTICE "using a buggy version of mkfs.jffs2. Use at least v1.17.\n");
-+ }
-+ /* What do we do about it? */
-+ }
-+ D1(printk(KERN_DEBUG "Increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino));
-+ /* Can't free them. We might need them in pass 2 */
-+ }
-+}
-+
- /* Scan plan:
- - Scan physical nodes. Build map of inodes/dirents. Allocate inocaches as we go
- - Scan directory tree from top down, setting nlink in inocaches
- - Scan inocaches for inodes with nlink==0
- */
--int jffs2_build_filesystem(struct jffs2_sb_info *c)
-+static int jffs2_build_filesystem(struct jffs2_sb_info *c)
- {
- int ret;
- int i;
- struct jffs2_inode_cache *ic;
-+ struct jffs2_full_dirent *dead_fds = NULL;
-
- /* First, scan the medium and build all the inode caches with
- lists of physical nodes */
-@@ -90,14 +101,17 @@
- return ret;
-
- D1(printk(KERN_DEBUG "Scanned flash completely\n"));
-- /* Now build the data map for each inode, marking obsoleted nodes
-- as such, and also increase nlink of any children. */
-+ D1(jffs2_dump_block_lists(c));
-+
-+ /* Now scan the directory tree, increasing nlink according to every dirent found. */
- for_each_inode(i, c, ic) {
- D1(printk(KERN_DEBUG "Pass 1: ino #%u\n", ic->ino));
-- ret = jffs2_build_inode_pass1(c, ic);
-- if (ret) {
-- D1(printk(KERN_WARNING "Eep. jffs2_build_inode_pass1 for ino %d returned %d\n", ic->ino, ret));
-- return ret;
-+
-+ D1(BUG_ON(ic->ino > c->highest_ino));
-+
-+ if (ic->scan_dents) {
-+ jffs2_build_inode_pass1(c, ic);
-+ cond_resched();
- }
- }
- D1(printk(KERN_DEBUG "Pass 1 complete\n"));
-@@ -107,181 +121,226 @@
- children too, and repeat the scan. As that's going to be
- a fairly uncommon occurrence, it's not so evil to do it this
- way. Recursion bad. */
-- do {
-- D1(printk(KERN_DEBUG "Pass 2 (re)starting\n"));
-- ret = 0;
-+ D1(printk(KERN_DEBUG "Pass 2 starting\n"));
-+
- for_each_inode(i, c, ic) {
- D1(printk(KERN_DEBUG "Pass 2: ino #%u, nlink %d, ic %p, nodes %p\n", ic->ino, ic->nlink, ic, ic->nodes));
- if (ic->nlink)
- continue;
-
-- ret = jffs2_build_remove_unlinked_inode(c, ic);
-- if (ret)
-- break;
-- /* -EAGAIN means the inode's nlink was zero, so we deleted it,
-- and furthermore that it had children and their nlink has now
-- gone to zero too. So we have to restart the scan. */
-+ jffs2_build_remove_unlinked_inode(c, ic, &dead_fds);
-+ cond_resched();
-+ }
-+
-+ D1(printk(KERN_DEBUG "Pass 2a starting\n"));
-+
-+ while (dead_fds) {
-+ struct jffs2_inode_cache *ic;
-+ struct jffs2_full_dirent *fd = dead_fds;
-+
-+ dead_fds = fd->next;
-+
-+ ic = jffs2_get_ino_cache(c, fd->ino);
-+ D1(printk(KERN_DEBUG "Removing dead_fd ino #%u (\"%s\"), ic at %p\n", fd->ino, fd->name, ic));
-+
-+ if (ic)
-+ jffs2_build_remove_unlinked_inode(c, ic, &dead_fds);
-+ jffs2_free_full_dirent(fd);
- }
-- } while(ret == -EAGAIN);
-
- D1(printk(KERN_DEBUG "Pass 2 complete\n"));
-
-- /* Finally, we can scan again and free the dirent nodes and scan_info structs */
-+ /* Finally, we can scan again and free the dirent structs */
- for_each_inode(i, c, ic) {
-- struct jffs2_scan_info *scan = ic->scan;
- struct jffs2_full_dirent *fd;
- D1(printk(KERN_DEBUG "Pass 3: ino #%u, ic %p, nodes %p\n", ic->ino, ic, ic->nodes));
-- if (!scan) {
-- if (ic->nlink) {
-- D1(printk(KERN_WARNING "Why no scan struct for ino #%u which has nlink %d?\n", ic->ino, ic->nlink));
-- }
-- continue;
-- }
-- ic->scan = NULL;
-- while(scan->dents) {
-- fd = scan->dents;
-- scan->dents = fd->next;
-+
-+ while(ic->scan_dents) {
-+ fd = ic->scan_dents;
-+ ic->scan_dents = fd->next;
- jffs2_free_full_dirent(fd);
- }
-- kfree(scan);
-+ ic->scan_dents = NULL;
-+ cond_resched();
- }
- D1(printk(KERN_DEBUG "Pass 3 complete\n"));
-+ D1(jffs2_dump_block_lists(c));
-+
-+ /* Rotate the lists by some number to ensure wear levelling */
-+ jffs2_rotate_lists(c);
-
- return ret;
- }
-
--int jffs2_build_inode_pass1(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
-+static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, struct jffs2_full_dirent **dead_fds)
- {
-- struct jffs2_tmp_dnode_info *tn;
-+ struct jffs2_raw_node_ref *raw;
- struct jffs2_full_dirent *fd;
-- struct jffs2_node_frag *fraglist = NULL;
-- struct jffs2_tmp_dnode_info *metadata = NULL;
--
-- D1(printk(KERN_DEBUG "jffs2_build_inode building inode #%u\n", ic->ino));
-- if (ic->ino > c->highest_ino)
-- c->highest_ino = ic->ino;
-
-- if (!ic->scan->tmpnodes && ic->ino != 1) {
-- D1(printk(KERN_DEBUG "jffs2_build_inode: ino #%u has no data nodes!\n", ic->ino));
-- }
-- /* Build the list to make sure any obsolete nodes are marked as such */
-- while(ic->scan->tmpnodes) {
-- tn = ic->scan->tmpnodes;
-- ic->scan->tmpnodes = tn->next;
--
-- if (metadata && tn->version > metadata->version) {
-- D1(printk(KERN_DEBUG "jffs2_build_inode_pass1 ignoring old metadata at 0x%08x\n",
-- metadata->fn->raw->flash_offset &~3));
-+ D1(printk(KERN_DEBUG "JFFS2: Removing ino #%u with nlink == zero.\n", ic->ino));
-
-- jffs2_free_full_dnode(metadata->fn);
-- jffs2_free_tmp_dnode_info(metadata);
-- metadata = NULL;
-+ for (raw = ic->nodes; raw != (void *)ic; raw = raw->next_in_ino) {
-+ D1(printk(KERN_DEBUG "obsoleting node at 0x%08x\n", ref_offset(raw)));
-+ jffs2_mark_node_obsolete(c, raw);
- }
-
-- if (tn->fn->size) {
-- jffs2_add_full_dnode_to_fraglist (c, &fraglist, tn->fn);
-- jffs2_free_tmp_dnode_info(tn);
-- } else {
-- if (!metadata) {
-- metadata = tn;
-- } else {
-- D1(printk(KERN_DEBUG "jffs2_build_inode_pass1 ignoring new metadata at 0x%08x\n",
-- tn->fn->raw->flash_offset &~3));
--
-- jffs2_free_full_dnode(tn->fn);
-- jffs2_free_tmp_dnode_info(tn);
-- }
-- }
-- }
-+ if (ic->scan_dents) {
-+ int whinged = 0;
-+ D1(printk(KERN_DEBUG "Inode #%u was a directory which may have children...\n", ic->ino));
-
-- /* OK. Now clear up */
-- if (metadata) {
-- jffs2_free_full_dnode(metadata->fn);
-- jffs2_free_tmp_dnode_info(metadata);
-- }
-- metadata = NULL;
-+ while(ic->scan_dents) {
-+ struct jffs2_inode_cache *child_ic;
-
-- while (fraglist) {
-- struct jffs2_node_frag *frag;
-- frag = fraglist;
-- fraglist = fraglist->next;
-+ fd = ic->scan_dents;
-+ ic->scan_dents = fd->next;
-
-- if (frag->node && !(--frag->node->frags)) {
-- jffs2_free_full_dnode(frag->node);
-+ if (!fd->ino) {
-+ /* It's a deletion dirent. Ignore it */
-+ D1(printk(KERN_DEBUG "Child \"%s\" is a deletion dirent, skipping...\n", fd->name));
-+ jffs2_free_full_dirent(fd);
-+ continue;
- }
-- jffs2_free_node_frag(frag);
-+ if (!whinged) {
-+ whinged = 1;
-+ printk(KERN_NOTICE "Inode #%u was a directory with children - removing those too...\n", ic->ino);
- }
-
-- /* Now for each child, increase nlink */
-- for(fd=ic->scan->dents; fd; fd = fd->next) {
-- struct jffs2_inode_cache *child_ic;
-- if (!fd->ino)
-- continue;
-+ D1(printk(KERN_DEBUG "Removing child \"%s\", ino #%u\n",
-+ fd->name, fd->ino));
-
- child_ic = jffs2_get_ino_cache(c, fd->ino);
- if (!child_ic) {
-- printk(KERN_NOTICE "Eep. Child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n",
-- fd->name, fd->ino, ic->ino);
-+ printk(KERN_NOTICE "Cannot remove child \"%s\", ino #%u, because it doesn't exist\n", fd->name, fd->ino);
-+ jffs2_free_full_dirent(fd);
- continue;
- }
-
-- if (child_ic->nlink++ && fd->type == DT_DIR) {
-- printk(KERN_NOTICE "Child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", fd->name, fd->ino, ic->ino);
-- if (fd->ino == 1 && ic->ino == 1) {
-- printk(KERN_NOTICE "This is mostly harmless, and probably caused by creating a JFFS2 image\n");
-- printk(KERN_NOTICE "using a buggy version of mkfs.jffs2. Use at least v1.17.\n");
-+ /* Reduce nlink of the child. If it's now zero, stick it on the
-+ dead_fds list to be cleaned up later. Else just free the fd */
-+
-+ child_ic->nlink--;
-+
-+ if (!child_ic->nlink) {
-+ D1(printk(KERN_DEBUG "Inode #%u (\"%s\") has now got zero nlink. Adding to dead_fds list.\n",
-+ fd->ino, fd->name));
-+ fd->next = *dead_fds;
-+ *dead_fds = fd;
-+ } else {
-+ D1(printk(KERN_DEBUG "Inode #%u (\"%s\") has now got nlink %d. Ignoring.\n",
-+ fd->ino, fd->name, child_ic->nlink));
-+ jffs2_free_full_dirent(fd);
- }
-- /* What do we do about it? */
- }
-- D1(printk(KERN_DEBUG "Increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino));
-- /* Can't free them. We might need them in pass 2 */
- }
-- return 0;
-+
-+ /*
-+ We don't delete the inocache from the hash list and free it yet.
-+ The erase code will do that, when all the nodes are completely gone.
-+ */
- }
-
--int jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
-+static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
- {
-- struct jffs2_raw_node_ref *raw;
-- struct jffs2_full_dirent *fd;
-- int ret = 0;
-+ uint32_t size;
-
-- if(!ic->scan) {
-- D1(printk(KERN_DEBUG "ino #%u was already removed\n", ic->ino));
-- return 0;
-- }
-+ /* Deletion should almost _always_ be allowed. We're fairly
-+ buggered once we stop allowing people to delete stuff
-+ because there's not enough free space... */
-+ c->resv_blocks_deletion = 2;
-+
-+ /* Be conservative about how much space we need before we allow writes.
-+ On top of that which is required for deletia, require an extra 2%
-+ of the medium to be available, for overhead caused by nodes being
-+ split across blocks, etc. */
-+
-+ size = c->flash_size / 50; /* 2% of flash size */
-+ size += c->nr_blocks * 100; /* And 100 bytes per eraseblock */
-+ size += c->sector_size - 1; /* ... and round up */
-+
-+ c->resv_blocks_write = c->resv_blocks_deletion + (size / c->sector_size);
-+
-+ /* When do we let the GC thread run in the background */
-+
-+ c->resv_blocks_gctrigger = c->resv_blocks_write + 1;
-+
-+ /* When do we allow garbage collection to merge nodes to make
-+ long-term progress at the expense of short-term space exhaustion? */
-+ c->resv_blocks_gcmerge = c->resv_blocks_deletion + 1;
-+
-+ /* When do we allow garbage collection to eat from bad blocks rather
-+ than actually making progress? */
-+ c->resv_blocks_gcbad = 0;//c->resv_blocks_deletion + 2;
-+
-+ /* If there's less than this amount of dirty space, don't bother
-+ trying to GC to make more space. It'll be a fruitless task */
-+ c->nospc_dirty_size = c->sector_size + (c->flash_size / 100);
-+
-+ D1(printk(KERN_DEBUG "JFFS2 trigger levels (size %d KiB, block size %d KiB, %d blocks)\n",
-+ c->flash_size / 1024, c->sector_size / 1024, c->nr_blocks));
-+ D1(printk(KERN_DEBUG "Blocks required to allow deletion: %d (%d KiB)\n",
-+ c->resv_blocks_deletion, c->resv_blocks_deletion*c->sector_size/1024));
-+ D1(printk(KERN_DEBUG "Blocks required to allow writes: %d (%d KiB)\n",
-+ c->resv_blocks_write, c->resv_blocks_write*c->sector_size/1024));
-+ D1(printk(KERN_DEBUG "Blocks required to quiesce GC thread: %d (%d KiB)\n",
-+ c->resv_blocks_gctrigger, c->resv_blocks_gctrigger*c->sector_size/1024));
-+ D1(printk(KERN_DEBUG "Blocks required to allow GC merges: %d (%d KiB)\n",
-+ c->resv_blocks_gcmerge, c->resv_blocks_gcmerge*c->sector_size/1024));
-+ D1(printk(KERN_DEBUG "Blocks required to GC bad blocks: %d (%d KiB)\n",
-+ c->resv_blocks_gcbad, c->resv_blocks_gcbad*c->sector_size/1024));
-+ D1(printk(KERN_DEBUG "Amount of dirty space required to GC: %d bytes\n",
-+ c->nospc_dirty_size));
-+}
-
-- D1(printk(KERN_DEBUG "JFFS2: Removing ino #%u with nlink == zero.\n", ic->ino));
-+int jffs2_do_mount_fs(struct jffs2_sb_info *c)
-+{
-+ int i;
-
-- for (raw = ic->nodes; raw != (void *)ic; raw = raw->next_in_ino) {
-- D1(printk(KERN_DEBUG "obsoleting node at 0x%08x\n", raw->flash_offset&~3));
-- jffs2_mark_node_obsolete(c, raw);
-+ c->free_size = c->flash_size;
-+ c->nr_blocks = c->flash_size / c->sector_size;
-+ c->blocks = kmalloc(sizeof(struct jffs2_eraseblock) * c->nr_blocks, GFP_KERNEL);
-+ if (!c->blocks)
-+ return -ENOMEM;
-+ for (i=0; i<c->nr_blocks; i++) {
-+ INIT_LIST_HEAD(&c->blocks[i].list);
-+ c->blocks[i].offset = i * c->sector_size;
-+ c->blocks[i].free_size = c->sector_size;
-+ c->blocks[i].dirty_size = 0;
-+ c->blocks[i].wasted_size = 0;
-+ c->blocks[i].unchecked_size = 0;
-+ c->blocks[i].used_size = 0;
-+ c->blocks[i].first_node = NULL;
-+ c->blocks[i].last_node = NULL;
-+ }
-+
-+ init_MUTEX(&c->alloc_sem);
-+ init_MUTEX(&c->erase_free_sem);
-+ init_waitqueue_head(&c->erase_wait);
-+ init_waitqueue_head(&c->inocache_wq);
-+ spin_lock_init(&c->erase_completion_lock);
-+ spin_lock_init(&c->inocache_lock);
-+
-+ INIT_LIST_HEAD(&c->clean_list);
-+ INIT_LIST_HEAD(&c->very_dirty_list);
-+ INIT_LIST_HEAD(&c->dirty_list);
-+ INIT_LIST_HEAD(&c->erasable_list);
-+ INIT_LIST_HEAD(&c->erasing_list);
-+ INIT_LIST_HEAD(&c->erase_pending_list);
-+ INIT_LIST_HEAD(&c->erasable_pending_wbuf_list);
-+ INIT_LIST_HEAD(&c->erase_complete_list);
-+ INIT_LIST_HEAD(&c->free_list);
-+ INIT_LIST_HEAD(&c->bad_list);
-+ INIT_LIST_HEAD(&c->bad_used_list);
-+ c->highest_ino = 1;
-+
-+ if (jffs2_build_filesystem(c)) {
-+ D1(printk(KERN_DEBUG "build_fs failed\n"));
-+ jffs2_free_ino_caches(c);
-+ jffs2_free_raw_node_refs(c);
-+ kfree(c->blocks);
-+ return -EIO;
- }
-
-- if (ic->scan->dents) {
-- printk(KERN_NOTICE "Inode #%u was a directory with children - removing those too...\n", ic->ino);
--
-- while(ic->scan->dents) {
-- struct jffs2_inode_cache *child_ic;
-+ jffs2_calc_trigger_levels(c);
-
-- fd = ic->scan->dents;
-- ic->scan->dents = fd->next;
--
-- D1(printk(KERN_DEBUG "Removing child \"%s\", ino #%u\n",
-- fd->name, fd->ino));
--
-- child_ic = jffs2_get_ino_cache(c, fd->ino);
-- if (!child_ic) {
-- printk(KERN_NOTICE "Cannot remove child \"%s\", ino #%u, because it doesn't exist\n", fd->name, fd->ino);
-- continue;
-- }
-- jffs2_free_full_dirent(fd);
-- child_ic->nlink--;
-- }
-- ret = -EAGAIN;
-- }
-- kfree(ic->scan);
-- ic->scan = NULL;
-- // jffs2_del_ino_cache(c, ic);
-- // jffs2_free_inode_cache(ic);
-- return ret;
-+ return 0;
- }
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/compr.c linux/fs/jffs2/compr.c
---- linux-mips-2.4.24-pre2/fs/jffs2/compr.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/compr.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,59 +1,37 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
- * Created by Arjan van de Ven <arjanv@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/kernel.h>
- #include <linux/string.h>
--#include <linux/types.h>
- #include <linux/errno.h>
-+#include <linux/types.h>
-+#include <linux/slab.h>
- #include <linux/jffs2.h>
-+#include "nodelist.h"
-
--int zlib_compress(unsigned char *data_in, unsigned char *cpage_out, __u32 *sourcelen, __u32 *dstlen);
--void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, __u32 srclen, __u32 destlen);
--int rtime_compress(unsigned char *data_in, unsigned char *cpage_out, __u32 *sourcelen, __u32 *dstlen);
--void rtime_decompress(unsigned char *data_in, unsigned char *cpage_out, __u32 srclen, __u32 destlen);
--int rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out, __u32 *sourcelen, __u32 *dstlen);
--void rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out, __u32 srclen, __u32 destlen);
--int dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out, __u32 *sourcelen, __u32 *dstlen);
--void dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, __u32 srclen, __u32 destlen);
-+int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen);
-+void jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen);
-+int jffs2_rtime_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen);
-+void jffs2_rtime_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen);
-+int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen);
-+void jffs2_rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen);
-+int jffs2_dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen);
-+void jffs2_dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen);
-
-
- /* jffs2_compress:
- * @data: Pointer to uncompressed data
-- * @cdata: Pointer to buffer for compressed data
-+ * @cdata: Pointer to returned pointer to buffer for compressed data
- * @datalen: On entry, holds the amount of data available for compression.
- * On exit, expected to hold the amount of data actually compressed.
- * @cdatalen: On entry, holds the amount of space available for compressed
-@@ -68,47 +46,59 @@
- * jffs2_compress should compress as much as will fit, and should set
- * *datalen accordingly to show the amount of data which were compressed.
- */
--unsigned char jffs2_compress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 *datalen, __u32 *cdatalen)
-+unsigned char jffs2_compress(unsigned char *data_in, unsigned char **cpage_out,
-+ uint32_t *datalen, uint32_t *cdatalen)
- {
-+#ifdef JFFS2_COMPRESSION
- int ret;
-
-- ret = zlib_compress(data_in, cpage_out, datalen, cdatalen);
-+ *cpage_out = kmalloc(*cdatalen, GFP_KERNEL);
-+ if (!*cpage_out) {
-+ printk(KERN_WARNING "No memory for compressor allocation. Compression failed\n");
-+ goto out;
-+ }
-+
-+#ifdef JFFS2_USE_ZLIB
-+ ret = jffs2_zlib_compress(data_in, *cpage_out, datalen, cdatalen);
- if (!ret) {
- return JFFS2_COMPR_ZLIB;
- }
--#if 0 /* Disabled 23/9/1. With zlib it hardly ever gets a look in */
-- ret = dynrubin_compress(data_in, cpage_out, datalen, cdatalen);
-+#endif
-+#ifdef JFFS2_USE_DYNRUBIN
-+ ret = jffs2_dynrubin_compress(data_in, *cpage_out, datalen, cdatalen);
- if (!ret) {
- return JFFS2_COMPR_DYNRUBIN;
- }
- #endif
--#if 0 /* Disabled 26/2/1. Obsoleted by dynrubin */
-- ret = rubinmips_compress(data_in, cpage_out, datalen, cdatalen);
-+#ifdef JFFS2_USE_RUBINMIPS
-+ ret = jffs2_rubinmips_compress(data_in, *cpage_out, datalen, cdatalen);
- if (!ret) {
- return JFFS2_COMPR_RUBINMIPS;
- }
- #endif
-+#ifdef JFFS2_USE_RTIME
- /* rtime does manage to recompress already-compressed data */
-- ret = rtime_compress(data_in, cpage_out, datalen, cdatalen);
-+ ret = jffs2_rtime_compress(data_in, *cpage_out, datalen, cdatalen);
- if (!ret) {
- return JFFS2_COMPR_RTIME;
- }
--#if 0
-- /* We don't need to copy. Let the caller special-case the COMPR_NONE case. */
-- /* If we get here, no compression is going to work */
-- /* But we might want to use the fragmentation part -- Arjan */
-- memcpy(cpage_out,data_in,min(*datalen,*cdatalen));
-- if (*datalen > *cdatalen)
-- *datalen = *cdatalen;
- #endif
-+ kfree(*cpage_out);
-+#endif /* Compression */
-+ out:
-+ *cpage_out = data_in;
-+ *datalen = *cdatalen;
- return JFFS2_COMPR_NONE; /* We failed to compress */
--
- }
-
-+void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig)
-+{
-+ if (orig != comprbuf)
-+ kfree(comprbuf);
-+}
-
- int jffs2_decompress(unsigned char comprtype, unsigned char *cdata_in,
-- unsigned char *data_out, __u32 cdatalen, __u32 datalen)
-+ unsigned char *data_out, uint32_t cdatalen, uint32_t datalen)
- {
- switch (comprtype) {
- case JFFS2_COMPR_NONE:
-@@ -119,30 +109,27 @@
- case JFFS2_COMPR_ZERO:
- memset(data_out, 0, datalen);
- break;
--
-+#ifdef JFFS2_USE_ZLIB
- case JFFS2_COMPR_ZLIB:
-- zlib_decompress(cdata_in, data_out, cdatalen, datalen);
-+ jffs2_zlib_decompress(cdata_in, data_out, cdatalen, datalen);
- break;
--
-+#endif
-+#ifdef JFFS2_USE_RTIME
- case JFFS2_COMPR_RTIME:
-- rtime_decompress(cdata_in, data_out, cdatalen, datalen);
-+ jffs2_rtime_decompress(cdata_in, data_out, cdatalen, datalen);
- break;
--
-- case JFFS2_COMPR_RUBINMIPS:
--#if 0 /* Disabled 23/9/1 */
-- rubinmips_decompress(cdata_in, data_out, cdatalen, datalen);
--#else
-- printk(KERN_WARNING "JFFS2: Rubinmips compression encountered but support not compiled in!\n");
- #endif
-+#ifdef JFFS2_USE_RUBINMIPS
-+ case JFFS2_COMPR_RUBINMIPS:
-+ jffs2_rubinmips_decompress(cdata_in, data_out, cdatalen, datalen);
- break;
-- case JFFS2_COMPR_DYNRUBIN:
--#if 1 /* Phase this one out */
-- dynrubin_decompress(cdata_in, data_out, cdatalen, datalen);
--#else
-- printk(KERN_WARNING "JFFS2: Dynrubin compression encountered but support not compiled in!\n");
- #endif
-- break;
-+#ifdef JFFS2_USE_DYNRUBIN
-+ case JFFS2_COMPR_DYNRUBIN:
-
-+ jffs2_dynrubin_decompress(cdata_in, data_out, cdatalen, datalen);
-+ break;
-+#endif
- default:
- printk(KERN_NOTICE "Unknown JFFS2 compression type 0x%02x\n", comprtype);
- return -EIO;
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/compr_rtime.c linux/fs/jffs2/compr_rtime.c
---- linux-mips-2.4.24-pre2/fs/jffs2/compr_rtime.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/compr_rtime.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,43 +1,19 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
- * Created by Arjan van de Ven <arjanv@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- *
- * Very simple lz77-ish encoder.
- *
- * Theory of operation: Both encoder and decoder have a list of "last
-- * occurances" for every possible source-value; after sending the
-+ * occurrences" for every possible source-value; after sending the
- * first source-byte, the second byte indicated the "run" length of
- * matches
- *
-@@ -51,10 +27,10 @@
- #include <linux/string.h>
-
- /* _compress returns the compressed size, -1 if bigger */
--int rtime_compress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 *sourcelen, __u32 *dstlen)
-+int jffs2_rtime_compress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t *sourcelen, uint32_t *dstlen)
- {
-- int positions[256];
-+ short positions[256];
- int outpos = 0;
- int pos=0;
-
-@@ -91,10 +67,10 @@
- }
-
-
--void rtime_decompress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 srclen, __u32 destlen)
-+void jffs2_rtime_decompress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t srclen, uint32_t destlen)
- {
-- int positions[256];
-+ short positions[256];
- int outpos = 0;
- int pos=0;
-
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/compr_rubin.c linux/fs/jffs2/compr_rubin.c
---- linux-mips-2.4.24-pre2/fs/jffs2/compr_rubin.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/compr_rubin.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,37 +1,13 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001, 2002 Red Hat, Inc.
- *
- * Created by Arjan van de Ven <arjanv@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
-@@ -43,7 +19,7 @@
-
-
-
--void init_rubin(struct rubin_state *rs, int div, int *bits)
-+static void init_rubin(struct rubin_state *rs, int div, int *bits)
- {
- int c;
-
-@@ -56,7 +32,7 @@
- }
-
-
--int encode(struct rubin_state *rs, long A, long B, int symbol)
-+static int encode(struct rubin_state *rs, long A, long B, int symbol)
- {
-
- long i0, i1;
-@@ -91,7 +67,7 @@
- }
-
-
--void end_rubin(struct rubin_state *rs)
-+static void end_rubin(struct rubin_state *rs)
- {
-
- int i;
-@@ -104,7 +80,7 @@
- }
-
-
--void init_decode(struct rubin_state *rs, int div, int *bits)
-+static void init_decode(struct rubin_state *rs, int div, int *bits)
- {
- init_rubin(rs, div, bits);
-
-@@ -151,7 +127,7 @@
- rs->rec_q = rec_q;
- }
-
--int decode(struct rubin_state *rs, long A, long B)
-+static int decode(struct rubin_state *rs, long A, long B)
- {
- unsigned long p = rs->p, q = rs->q;
- long i0, threshold;
-@@ -212,8 +188,8 @@
-
-
-
--int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in,
-- unsigned char *cpage_out, __u32 *sourcelen, __u32 *dstlen)
-+static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in,
-+ unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen)
- {
- int outpos = 0;
- int pos=0;
-@@ -246,20 +222,20 @@
- }
- #if 0
- /* _compress returns the compressed size, -1 if bigger */
--int rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 *sourcelen, __u32 *dstlen)
-+int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t *sourcelen, uint32_t *dstlen)
- {
- return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen);
- }
- #endif
--int dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 *sourcelen, __u32 *dstlen)
-+int jffs2_dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t *sourcelen, uint32_t *dstlen)
- {
- int bits[8];
- unsigned char histo[256];
- int i;
- int ret;
-- __u32 mysrclen, mydstlen;
-+ uint32_t mysrclen, mydstlen;
-
- mysrclen = *sourcelen;
- mydstlen = *dstlen - 8;
-@@ -315,8 +291,8 @@
- return 0;
- }
-
--void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata_in,
-- unsigned char *page_out, __u32 srclen, __u32 destlen)
-+static void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata_in,
-+ unsigned char *page_out, uint32_t srclen, uint32_t destlen)
- {
- int outpos = 0;
- struct rubin_state rs;
-@@ -330,14 +306,14 @@
- }
-
-
--void rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 sourcelen, __u32 dstlen)
-+void jffs2_rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t sourcelen, uint32_t dstlen)
- {
- rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen);
- }
-
--void dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 sourcelen, __u32 dstlen)
-+void jffs2_dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t sourcelen, uint32_t dstlen)
- {
- int bits[8];
- int c;
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/compr_rubin.h linux/fs/jffs2/compr_rubin.h
---- linux-mips-2.4.24-pre2/fs/jffs2/compr_rubin.h 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/compr_rubin.h 2004-11-17 18:17:59.000000000 +0100
-@@ -1,7 +1,7 @@
- /* Rubin encoder/decoder header */
- /* work started at : aug 3, 1994 */
- /* last modification : aug 15, 1994 */
--/* $Id$ */
-+/* $Id$ */
-
- #include "pushpull.h"
-
-@@ -19,10 +19,3 @@
- int bit_divider;
- int bits[8];
- };
--
--
--void init_rubin (struct rubin_state *rs, int div, int *bits);
--int encode (struct rubin_state *, long, long, int);
--void end_rubin (struct rubin_state *);
--void init_decode (struct rubin_state *, int div, int *bits);
--int decode (struct rubin_state *, long, long);
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/compr_zlib.c linux/fs/jffs2/compr_zlib.c
---- linux-mips-2.4.24-pre2/fs/jffs2/compr_zlib.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/compr_zlib.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,50 +1,26 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001, 2002 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
--#ifndef __KERNEL__
-+#if !defined(__KERNEL__) && !defined(__ECOS)
- #error "The userspace support got too messy and was removed. Update your mkfs.jffs2"
- #endif
-
- #include <linux/config.h>
- #include <linux/kernel.h>
--#include <linux/mtd/compatmac.h> /* for min() */
- #include <linux/slab.h>
--#include <linux/jffs2.h>
- #include <linux/zlib.h>
-+#include <linux/zutil.h>
-+#include <asm/semaphore.h>
- #include "nodelist.h"
-
- /* Plan: call deflate() with avail_in == *sourcelen,
-@@ -58,21 +34,24 @@
-
- static DECLARE_MUTEX(deflate_sem);
- static DECLARE_MUTEX(inflate_sem);
--static void *deflate_workspace;
--static void *inflate_workspace;
-+static z_stream inf_strm, def_strm;
-+
-+#ifdef __KERNEL__ /* Linux-only */
-+#include <linux/vmalloc.h>
-+#include <linux/init.h>
-
- int __init jffs2_zlib_init(void)
- {
-- deflate_workspace = vmalloc(zlib_deflate_workspacesize());
-- if (!deflate_workspace) {
-+ def_strm.workspace = vmalloc(zlib_deflate_workspacesize());
-+ if (!def_strm.workspace) {
- printk(KERN_WARNING "Failed to allocate %d bytes for deflate workspace\n", zlib_deflate_workspacesize());
- return -ENOMEM;
- }
- D1(printk(KERN_DEBUG "Allocated %d bytes for deflate workspace\n", zlib_deflate_workspacesize()));
-- inflate_workspace = vmalloc(zlib_inflate_workspacesize());
-- if (!inflate_workspace) {
-+ inf_strm.workspace = vmalloc(zlib_inflate_workspacesize());
-+ if (!inf_strm.workspace) {
- printk(KERN_WARNING "Failed to allocate %d bytes for inflate workspace\n", zlib_inflate_workspacesize());
-- vfree(deflate_workspace);
-+ vfree(def_strm.workspace);
- return -ENOMEM;
- }
- D1(printk(KERN_DEBUG "Allocated %d bytes for inflate workspace\n", zlib_inflate_workspacesize()));
-@@ -81,97 +60,120 @@
-
- void jffs2_zlib_exit(void)
- {
-- vfree(deflate_workspace);
-- vfree(inflate_workspace);
-+ vfree(def_strm.workspace);
-+ vfree(inf_strm.workspace);
- }
-+#endif /* __KERNEL__ */
-
--int zlib_compress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 *sourcelen, __u32 *dstlen)
-+int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t *sourcelen, uint32_t *dstlen)
- {
-- z_stream strm;
- int ret;
-
- if (*dstlen <= STREAM_END_SPACE)
- return -1;
-
- down(&deflate_sem);
-- strm.workspace = deflate_workspace;
-
-- if (Z_OK != zlib_deflateInit(&strm, 3)) {
-+ if (Z_OK != zlib_deflateInit(&def_strm, 3)) {
- printk(KERN_WARNING "deflateInit failed\n");
- up(&deflate_sem);
- return -1;
- }
-
-- strm.next_in = data_in;
-- strm.total_in = 0;
-+ def_strm.next_in = data_in;
-+ def_strm.total_in = 0;
-
-- strm.next_out = cpage_out;
-- strm.total_out = 0;
-+ def_strm.next_out = cpage_out;
-+ def_strm.total_out = 0;
-
-- while (strm.total_out < *dstlen - STREAM_END_SPACE && strm.total_in < *sourcelen) {
-- strm.avail_out = *dstlen - (strm.total_out + STREAM_END_SPACE);
-- strm.avail_in = min((unsigned)(*sourcelen-strm.total_in), strm.avail_out);
-+ while (def_strm.total_out < *dstlen - STREAM_END_SPACE && def_strm.total_in < *sourcelen) {
-+ def_strm.avail_out = *dstlen - (def_strm.total_out + STREAM_END_SPACE);
-+ def_strm.avail_in = min((unsigned)(*sourcelen-def_strm.total_in), def_strm.avail_out);
- D1(printk(KERN_DEBUG "calling deflate with avail_in %d, avail_out %d\n",
-- strm.avail_in, strm.avail_out));
-- ret = zlib_deflate(&strm, Z_PARTIAL_FLUSH);
-+ def_strm.avail_in, def_strm.avail_out));
-+ ret = zlib_deflate(&def_strm, Z_PARTIAL_FLUSH);
- D1(printk(KERN_DEBUG "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n",
-- strm.avail_in, strm.avail_out, strm.total_in, strm.total_out));
-+ def_strm.avail_in, def_strm.avail_out, def_strm.total_in, def_strm.total_out));
- if (ret != Z_OK) {
- D1(printk(KERN_DEBUG "deflate in loop returned %d\n", ret));
-- zlib_deflateEnd(&strm);
-+ zlib_deflateEnd(&def_strm);
- up(&deflate_sem);
- return -1;
- }
- }
-- strm.avail_out += STREAM_END_SPACE;
-- strm.avail_in = 0;
-- ret = zlib_deflate(&strm, Z_FINISH);
-- zlib_deflateEnd(&strm);
-- up(&deflate_sem);
-+ def_strm.avail_out += STREAM_END_SPACE;
-+ def_strm.avail_in = 0;
-+ ret = zlib_deflate(&def_strm, Z_FINISH);
-+ zlib_deflateEnd(&def_strm);
-+
- if (ret != Z_STREAM_END) {
- D1(printk(KERN_DEBUG "final deflate returned %d\n", ret));
-- return -1;
-+ ret = -1;
-+ goto out;
- }
-
-- D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld\n",
-- strm.total_in, strm.total_out));
-+ if (def_strm.total_out >= def_strm.total_in) {
-+ D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld; failing\n",
-+ def_strm.total_in, def_strm.total_out));
-+ ret = -1;
-+ goto out;
-+ }
-
-- if (strm.total_out >= strm.total_in)
-- return -1;
-+ D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld\n",
-+ def_strm.total_in, def_strm.total_out));
-
-- *dstlen = strm.total_out;
-- *sourcelen = strm.total_in;
-- return 0;
-+ *dstlen = def_strm.total_out;
-+ *sourcelen = def_strm.total_in;
-+ ret = 0;
-+ out:
-+ up(&deflate_sem);
-+ return ret;
- }
-
--void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 srclen, __u32 destlen)
-+void jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t srclen, uint32_t destlen)
- {
-- z_stream strm;
- int ret;
-+ int wbits = MAX_WBITS;
-
- down(&inflate_sem);
-- strm.workspace = inflate_workspace;
-
-- if (Z_OK != zlib_inflateInit(&strm)) {
-+ inf_strm.next_in = data_in;
-+ inf_strm.avail_in = srclen;
-+ inf_strm.total_in = 0;
-+
-+ inf_strm.next_out = cpage_out;
-+ inf_strm.avail_out = destlen;
-+ inf_strm.total_out = 0;
-+
-+ /* If it's deflate, and it's got no preset dictionary, then
-+ we can tell zlib to skip the adler32 check. */
-+ if (srclen > 2 && !(data_in[1] & PRESET_DICT) &&
-+ ((data_in[0] & 0x0f) == Z_DEFLATED) &&
-+ !(((data_in[0]<<8) + data_in[1]) % 31)) {
-+
-+ D2(printk(KERN_DEBUG "inflate skipping adler32\n"));
-+ wbits = -((data_in[0] >> 4) + 8);
-+ inf_strm.next_in += 2;
-+ inf_strm.avail_in -= 2;
-+ } else {
-+ /* Let this remain D1 for now -- it should never happen */
-+ D1(printk(KERN_DEBUG "inflate not skipping adler32\n"));
-+ }
-+
-+
-+ if (Z_OK != zlib_inflateInit2(&inf_strm, wbits)) {
- printk(KERN_WARNING "inflateInit failed\n");
- up(&inflate_sem);
- return;
- }
-- strm.next_in = data_in;
-- strm.avail_in = srclen;
-- strm.total_in = 0;
--
-- strm.next_out = cpage_out;
-- strm.avail_out = destlen;
-- strm.total_out = 0;
-
-- while((ret = zlib_inflate(&strm, Z_FINISH)) == Z_OK)
-+ while((ret = zlib_inflate(&inf_strm, Z_FINISH)) == Z_OK)
- ;
- if (ret != Z_STREAM_END) {
- printk(KERN_NOTICE "inflate returned %d\n", ret);
- }
-- zlib_inflateEnd(&strm);
-+ zlib_inflateEnd(&inf_strm);
- up(&inflate_sem);
- }
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/comprtest.c linux/fs/jffs2/comprtest.c
---- linux-mips-2.4.24-pre2/fs/jffs2/comprtest.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/comprtest.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,4 +1,4 @@
--/* $Id$ */
-+/* $Id$ */
-
- #include <linux/kernel.h>
- #include <linux/string.h>
-@@ -266,13 +266,13 @@
- static unsigned char decomprbuf[TESTDATA_LEN];
-
- int jffs2_decompress(unsigned char comprtype, unsigned char *cdata_in,
-- unsigned char *data_out, __u32 cdatalen, __u32 datalen);
-+ unsigned char *data_out, uint32_t cdatalen, uint32_t datalen);
- unsigned char jffs2_compress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 *datalen, __u32 *cdatalen);
-+ uint32_t *datalen, uint32_t *cdatalen);
-
- int init_module(void ) {
- unsigned char comprtype;
-- __u32 c, d;
-+ uint32_t c, d;
- int ret;
-
- printk("Original data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/crc32.c linux/fs/jffs2/crc32.c
---- linux-mips-2.4.24-pre2/fs/jffs2/crc32.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/jffs2/crc32.c 2004-11-17 18:17:59.283276832 +0100
-@@ -0,0 +1,97 @@
-+/*
-+ * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
-+ * code or tables extracted from it, as desired without restriction.
-+ *
-+ * First, the polynomial itself and its table of feedback terms. The
-+ * polynomial is
-+ * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
-+ *
-+ * Note that we take it "backwards" and put the highest-order term in
-+ * the lowest-order bit. The X^32 term is "implied"; the LSB is the
-+ * X^31 term, etc. The X^0 term (usually shown as "+1") results in
-+ * the MSB being 1
-+ *
-+ * Note that the usual hardware shift register implementation, which
-+ * is what we're using (we're merely optimizing it by doing eight-bit
-+ * chunks at a time) shifts bits into the lowest-order term. In our
-+ * implementation, that means shifting towards the right. Why do we
-+ * do it this way? Because the calculated CRC must be transmitted in
-+ * order from highest-order term to lowest-order term. UARTs transmit
-+ * characters in order from LSB to MSB. By storing the CRC this way
-+ * we hand it to the UART in the order low-byte to high-byte; the UART
-+ * sends each low-bit to hight-bit; and the result is transmission bit
-+ * by bit from highest- to lowest-order term without requiring any bit
-+ * shuffling on our part. Reception works similarly
-+ *
-+ * The feedback terms table consists of 256, 32-bit entries. Notes
-+ *
-+ * The table can be generated at runtime if desired; code to do so
-+ * is shown later. It might not be obvious, but the feedback
-+ * terms simply represent the results of eight shift/xor opera
-+ * tions for all combinations of data and CRC register values
-+ *
-+ * The values must be right-shifted by eight bits by the "updcrc
-+ * logic; the shift must be unsigned (bring in zeroes). On some
-+ * hardware you could probably optimize the shift in assembler by
-+ * using byte-swap instructions
-+ * polynomial $edb88320
-+ */
-+
-+/* $Id$ */
-+
-+#include "crc32.h"
-+
-+const uint32_t crc32_table[256] = {
-+ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
-+ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
-+ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
-+ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
-+ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
-+ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
-+ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
-+ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
-+ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
-+ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
-+ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
-+ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
-+ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
-+ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
-+ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
-+ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
-+ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
-+ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
-+ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
-+ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
-+ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
-+ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
-+ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
-+ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
-+ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
-+ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
-+ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
-+ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
-+ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
-+ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
-+ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
-+ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
-+ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
-+ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
-+ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
-+ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
-+ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
-+ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
-+ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
-+ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
-+ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
-+ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
-+ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
-+ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
-+ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
-+ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
-+ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
-+ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
-+ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
-+ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
-+ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
-+ 0x2d02ef8dL
-+};
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/crc32.h linux/fs/jffs2/crc32.h
---- linux-mips-2.4.24-pre2/fs/jffs2/crc32.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/jffs2/crc32.h 2004-11-17 18:17:59.284276680 +0100
-@@ -0,0 +1,21 @@
-+#ifndef CRC32_H
-+#define CRC32_H
-+
-+/* $Id$ */
-+
-+#include <linux/types.h>
-+
-+extern const uint32_t crc32_table[256];
-+
-+/* Return a 32-bit CRC of the contents of the buffer. */
-+
-+static inline uint32_t
-+crc32(uint32_t val, const void *ss, int len)
-+{
-+ const unsigned char *s = ss;
-+ while (--len >= 0)
-+ val = crc32_table[(val ^ *s++) & 0xff] ^ (val >> 8);
-+ return val;
-+}
-+
-+#endif
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/dir.c linux/fs/jffs2/dir.c
---- linux-mips-2.4.24-pre2/fs/jffs2/dir.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/dir.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,84 +1,73 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/kernel.h>
- #include <linux/slab.h>
-+#include <linux/sched.h>
- #include <linux/fs.h>
--#include <linux/mtd/compatmac.h> /* For completion */
-+#include <linux/crc32.h>
- #include <linux/jffs2.h>
- #include <linux/jffs2_fs_i.h>
- #include <linux/jffs2_fs_sb.h>
-+#include <linux/time.h>
- #include "nodelist.h"
--#include <linux/crc32.h>
-+
-+/* Urgh. Please tell me there's a nicer way of doing these. */
-+#include <linux/version.h>
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,48)
-+typedef int mknod_arg_t;
-+#define NAMEI_COMPAT(x) ((void *)x)
-+#else
-+typedef dev_t mknod_arg_t;
-+#define NAMEI_COMPAT(x) (x)
-+#endif
-
- static int jffs2_readdir (struct file *, void *, filldir_t);
-
--static int jffs2_create (struct inode *,struct dentry *,int);
--static struct dentry *jffs2_lookup (struct inode *,struct dentry *);
-+static int jffs2_create (struct inode *,struct dentry *,int,
-+ struct nameidata *);
-+static struct dentry *jffs2_lookup (struct inode *,struct dentry *,
-+ struct nameidata *);
- static int jffs2_link (struct dentry *,struct inode *,struct dentry *);
- static int jffs2_unlink (struct inode *,struct dentry *);
- static int jffs2_symlink (struct inode *,struct dentry *,const char *);
- static int jffs2_mkdir (struct inode *,struct dentry *,int);
- static int jffs2_rmdir (struct inode *,struct dentry *);
--static int jffs2_mknod (struct inode *,struct dentry *,int,int);
-+static int jffs2_mknod (struct inode *,struct dentry *,int,mknod_arg_t);
- static int jffs2_rename (struct inode *, struct dentry *,
- struct inode *, struct dentry *);
-
- struct file_operations jffs2_dir_operations =
- {
-- read: generic_read_dir,
-- readdir: jffs2_readdir,
-- ioctl: jffs2_ioctl,
-- fsync: jffs2_null_fsync
-+ .read = generic_read_dir,
-+ .readdir = jffs2_readdir,
-+ .ioctl = jffs2_ioctl,
-+ .fsync = jffs2_fsync
- };
-
-
- struct inode_operations jffs2_dir_inode_operations =
- {
-- create: jffs2_create,
-- lookup: jffs2_lookup,
-- link: jffs2_link,
-- unlink: jffs2_unlink,
-- symlink: jffs2_symlink,
-- mkdir: jffs2_mkdir,
-- rmdir: jffs2_rmdir,
-- mknod: jffs2_mknod,
-- rename: jffs2_rename,
-- setattr: jffs2_setattr,
-+ .create = NAMEI_COMPAT(jffs2_create),
-+ .lookup = NAMEI_COMPAT(jffs2_lookup),
-+ .link = jffs2_link,
-+ .unlink = jffs2_unlink,
-+ .symlink = jffs2_symlink,
-+ .mkdir = jffs2_mkdir,
-+ .rmdir = jffs2_rmdir,
-+ .mknod = jffs2_mknod,
-+ .rename = jffs2_rename,
-+ .setattr = jffs2_setattr,
- };
-
- /***********************************************************************/
-@@ -88,12 +77,13 @@
- and we use the same hash function as the dentries. Makes this
- nice and simple
- */
--static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target)
-+static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target,
-+ struct nameidata *nd)
- {
- struct jffs2_inode_info *dir_f;
- struct jffs2_sb_info *c;
- struct jffs2_full_dirent *fd = NULL, *fd_list;
-- __u32 ino = 0;
-+ uint32_t ino = 0;
- struct inode *inode = NULL;
-
- D1(printk(KERN_DEBUG "jffs2_lookup()\n"));
-@@ -153,8 +143,9 @@
- offset++;
- }
- if (offset == 1) {
-- D1(printk(KERN_DEBUG "Dirent 1: \"..\", ino #%lu\n", filp->f_dentry->d_parent->d_inode->i_ino));
-- if (filldir(dirent, "..", 2, 1, filp->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
-+ unsigned long pino = parent_ino(filp->f_dentry);
-+ D1(printk(KERN_DEBUG "Dirent 1: \"..\", ino #%lu\n", pino));
-+ if (filldir(dirent, "..", 2, 1, pino, DT_DIR) < 0)
- goto out;
- offset++;
- }
-@@ -188,18 +179,14 @@
-
- /***********************************************************************/
-
--static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode)
-+
-+static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
-+ struct nameidata *nd)
- {
-+ struct jffs2_raw_inode *ri;
- struct jffs2_inode_info *f, *dir_f;
- struct jffs2_sb_info *c;
- struct inode *inode;
-- struct jffs2_raw_inode *ri;
-- struct jffs2_raw_dirent *rd;
-- struct jffs2_full_dnode *fn;
-- struct jffs2_full_dirent *fd;
-- int namelen;
-- __u32 alloclen, phys_ofs;
-- __u32 writtenlen;
- int ret;
-
- ri = jffs2_alloc_raw_inode();
-@@ -210,23 +197,11 @@
-
- D1(printk(KERN_DEBUG "jffs2_create()\n"));
-
-- /* Try to reserve enough space for both node and dirent.
-- * Just the node will do for now, though
-- */
-- namelen = dentry->d_name.len;
-- ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);
-- D1(printk(KERN_DEBUG "jffs2_create(): reserved 0x%x bytes\n", alloclen));
-- if (ret) {
-- jffs2_free_raw_inode(ri);
-- return ret;
-- }
--
- inode = jffs2_new_inode(dir_i, mode, ri);
-
- if (IS_ERR(inode)) {
- D1(printk(KERN_DEBUG "jffs2_new_inode() failed\n"));
- jffs2_free_raw_inode(ri);
-- jffs2_complete_reservation(c);
- return PTR_ERR(inode);
- }
-
-@@ -236,93 +211,22 @@
- inode->i_mapping->nrpages = 0;
-
- f = JFFS2_INODE_INFO(inode);
-+ dir_f = JFFS2_INODE_INFO(dir_i);
-
-- ri->data_crc = 0;
-- ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
--
-- fn = jffs2_write_dnode(inode, ri, NULL, 0, phys_ofs, &writtenlen);
-- D1(printk(KERN_DEBUG "jffs2_create created file with mode 0x%x\n", ri->mode));
-- jffs2_free_raw_inode(ri);
--
-- if (IS_ERR(fn)) {
-- D1(printk(KERN_DEBUG "jffs2_write_dnode() failed\n"));
-- /* Eeek. Wave bye bye */
-- up(&f->sem);
-- jffs2_complete_reservation(c);
-- jffs2_clear_inode(inode);
-- return PTR_ERR(fn);
-- }
-- /* No data here. Only a metadata node, which will be
-- obsoleted by the first data write
-- */
-- f->metadata = fn;
--
-- /* Work out where to put the dirent node now. */
-- writtenlen = PAD(writtenlen);
-- phys_ofs += writtenlen;
-- alloclen -= writtenlen;
-- up(&f->sem);
--
-- if (alloclen < sizeof(*rd)+namelen) {
-- /* Not enough space left in this chunk. Get some more */
-- jffs2_complete_reservation(c);
-- ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
-+ ret = jffs2_do_create(c, dir_f, f, ri,
-+ dentry->d_name.name, dentry->d_name.len);
-
- if (ret) {
-- /* Eep. */
-- D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n"));
- jffs2_clear_inode(inode);
-+ make_bad_inode(inode);
-+ iput(inode);
-+ jffs2_free_raw_inode(ri);
- return ret;
- }
-- }
-
-- rd = jffs2_alloc_raw_dirent();
-- if (!rd) {
-- /* Argh. Now we treat it like a normal delete */
-- jffs2_complete_reservation(c);
-- jffs2_clear_inode(inode);
-- return -ENOMEM;
-- }
--
-- dir_f = JFFS2_INODE_INFO(dir_i);
-- down(&dir_f->sem);
--
-- rd->magic = JFFS2_MAGIC_BITMASK;
-- rd->nodetype = JFFS2_NODETYPE_DIRENT;
-- rd->totlen = sizeof(*rd) + namelen;
-- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
--
-- rd->pino = dir_i->i_ino;
-- rd->version = ++dir_f->highest_version;
-- rd->ino = inode->i_ino;
-- rd->mctime = CURRENT_TIME;
-- rd->nsize = namelen;
-- rd->type = DT_REG;
-- rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
-- rd->name_crc = crc32(0, dentry->d_name.name, namelen);
--
-- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
--
-- jffs2_complete_reservation(c);
--
-- if (IS_ERR(fd)) {
-- /* dirent failed to write. Delete the inode normally
-- as if it were the final unlink() */
-- jffs2_free_raw_dirent(rd);
-- up(&dir_f->sem);
-- jffs2_clear_inode(inode);
-- return PTR_ERR(fd);
-- }
--
-- dir_i->i_mtime = dir_i->i_ctime = rd->mctime;
--
-- jffs2_free_raw_dirent(rd);
--
-- /* Link the fd into the inode's list, obsoleting an old
-- one if necessary. */
-- jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-- up(&dir_f->sem);
-+ dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(ri->ctime));
-
-+ jffs2_free_raw_inode(ri);
- d_instantiate(dentry, inode);
-
- D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n",
-@@ -332,173 +236,48 @@
-
- /***********************************************************************/
-
--static int jffs2_do_unlink(struct inode *dir_i, struct dentry *dentry, int rename)
--{
-- struct jffs2_inode_info *dir_f, *f;
-- struct jffs2_sb_info *c;
-- struct jffs2_raw_dirent *rd;
-- struct jffs2_full_dirent *fd;
-- __u32 alloclen, phys_ofs;
-- int ret;
--
-- c = JFFS2_SB_INFO(dir_i->i_sb);
--
-- rd = jffs2_alloc_raw_dirent();
-- if (!rd)
-- return -ENOMEM;
--
-- ret = jffs2_reserve_space(c, sizeof(*rd)+dentry->d_name.len, &phys_ofs, &alloclen, ALLOC_DELETION);
-- if (ret) {
-- jffs2_free_raw_dirent(rd);
-- return ret;
-- }
--
-- dir_f = JFFS2_INODE_INFO(dir_i);
-- down(&dir_f->sem);
--
-- /* Build a deletion node */
-- rd->magic = JFFS2_MAGIC_BITMASK;
-- rd->nodetype = JFFS2_NODETYPE_DIRENT;
-- rd->totlen = sizeof(*rd) + dentry->d_name.len;
-- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
--
-- rd->pino = dir_i->i_ino;
-- rd->version = ++dir_f->highest_version;
-- rd->ino = 0;
-- rd->mctime = CURRENT_TIME;
-- rd->nsize = dentry->d_name.len;
-- rd->type = DT_UNKNOWN;
-- rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
-- rd->name_crc = crc32(0, dentry->d_name.name, dentry->d_name.len);
--
-- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, dentry->d_name.len, phys_ofs, NULL);
--
-- jffs2_complete_reservation(c);
-- jffs2_free_raw_dirent(rd);
--
-- if (IS_ERR(fd)) {
-- up(&dir_f->sem);
-- return PTR_ERR(fd);
-- }
--
-- /* File it. This will mark the old one obsolete. */
-- jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-- up(&dir_f->sem);
--
-- if (!rename) {
-- f = JFFS2_INODE_INFO(dentry->d_inode);
-- down(&f->sem);
--
-- while (f->dents) {
-- /* There can be only deleted ones */
-- fd = f->dents;
--
-- f->dents = fd->next;
--
-- if (fd->ino) {
-- printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n",
-- f->inocache->ino, fd->name, fd->ino);
-- } else {
-- D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", fd->name, f->inocache->ino));
-- }
-- jffs2_mark_node_obsolete(c, fd->raw);
-- jffs2_free_full_dirent(fd);
-- }
-- /* Don't oops on unlinking a bad inode */
-- if (f->inocache)
-- f->inocache->nlink--;
-- dentry->d_inode->i_nlink--;
-- up(&f->sem);
-- }
--
-- return 0;
--}
-
- static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry)
- {
-- return jffs2_do_unlink(dir_i, dentry, 0);
--}
--/***********************************************************************/
--
--static int jffs2_do_link (struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry, int rename)
--{
-- struct jffs2_inode_info *dir_f, *f;
-- struct jffs2_sb_info *c;
-- struct jffs2_raw_dirent *rd;
-- struct jffs2_full_dirent *fd;
-- __u32 alloclen, phys_ofs;
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(dir_i->i_sb);
-+ struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
-+ struct jffs2_inode_info *dead_f = JFFS2_INODE_INFO(dentry->d_inode);
- int ret;
-
-- c = JFFS2_SB_INFO(dir_i->i_sb);
--
-- rd = jffs2_alloc_raw_dirent();
-- if (!rd)
-- return -ENOMEM;
--
-- ret = jffs2_reserve_space(c, sizeof(*rd)+dentry->d_name.len, &phys_ofs, &alloclen, ALLOC_NORMAL);
-- if (ret) {
-- jffs2_free_raw_dirent(rd);
-+ ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,
-+ dentry->d_name.len, dead_f);
-+ if (dead_f->inocache)
-+ dentry->d_inode->i_nlink = dead_f->inocache->nlink;
- return ret;
-- }
--
-- dir_f = JFFS2_INODE_INFO(dir_i);
-- down(&dir_f->sem);
--
-- /* Build a deletion node */
-- rd->magic = JFFS2_MAGIC_BITMASK;
-- rd->nodetype = JFFS2_NODETYPE_DIRENT;
-- rd->totlen = sizeof(*rd) + dentry->d_name.len;
-- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
--
-- rd->pino = dir_i->i_ino;
-- rd->version = ++dir_f->highest_version;
-- rd->ino = old_dentry->d_inode->i_ino;
-- rd->mctime = CURRENT_TIME;
-- rd->nsize = dentry->d_name.len;
--
-- /* XXX: This is ugly. */
-- rd->type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
-- if (!rd->type) rd->type = DT_REG;
--
-- rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
-- rd->name_crc = crc32(0, dentry->d_name.name, dentry->d_name.len);
--
-- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, dentry->d_name.len, phys_ofs, NULL);
--
-- jffs2_complete_reservation(c);
-- jffs2_free_raw_dirent(rd);
--
-- if (IS_ERR(fd)) {
-- up(&dir_f->sem);
-- return PTR_ERR(fd);
-- }
--
-- /* File it. This will mark the old one obsolete. */
-- jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-- up(&dir_f->sem);
--
-- if (!rename) {
-- f = JFFS2_INODE_INFO(old_dentry->d_inode);
-- down(&f->sem);
-- old_dentry->d_inode->i_nlink = ++f->inocache->nlink;
-- up(&f->sem);
-- }
-- return 0;
- }
-+/***********************************************************************/
-+
-
- static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry)
- {
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dentry->d_inode->i_sb);
-+ struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode);
-+ struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
- int ret;
-+ uint8_t type;
-
-- /* Can't link a bad inode. */
-- if (!JFFS2_INODE_INFO(old_dentry->d_inode)->inocache)
-+ /* Don't let people make hard links to bad inodes. */
-+ if (!f->inocache)
- return -EIO;
-
- if (S_ISDIR(old_dentry->d_inode->i_mode))
- return -EPERM;
-
-- ret = jffs2_do_link(old_dentry, dir_i, dentry, 0);
-+ /* XXX: This is ugly */
-+ type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
-+ if (!type) type = DT_REG;
-+
-+ ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len);
-+
- if (!ret) {
-+ down(&f->sem);
-+ old_dentry->d_inode->i_nlink = ++f->inocache->nlink;
-+ up(&f->sem);
- d_instantiate(dentry, old_dentry->d_inode);
- atomic_inc(&old_dentry->d_inode->i_count);
- }
-@@ -517,8 +296,7 @@
- struct jffs2_full_dnode *fn;
- struct jffs2_full_dirent *fd;
- int namelen;
-- __u32 alloclen, phys_ofs;
-- __u32 writtenlen;
-+ uint32_t alloclen, phys_ofs;
- int ret;
-
- /* FIXME: If you care. We'd need to use frags for the target
-@@ -556,15 +334,16 @@
-
- f = JFFS2_INODE_INFO(inode);
-
-- inode->i_size = ri->isize = ri->dsize = ri->csize = strlen(target);
-- ri->totlen = sizeof(*ri) + ri->dsize;
-- ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
-+ inode->i_size = strlen(target);
-+ ri->isize = ri->dsize = ri->csize = cpu_to_je32(inode->i_size);
-+ ri->totlen = cpu_to_je32(sizeof(*ri) + inode->i_size);
-+ ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
-
- ri->compr = JFFS2_COMPR_NONE;
-- ri->data_crc = crc32(0, target, strlen(target));
-- ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
-+ ri->data_crc = cpu_to_je32(crc32(0, target, strlen(target)));
-+ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-
-- fn = jffs2_write_dnode(inode, ri, target, strlen(target), phys_ofs, &writtenlen);
-+ fn = jffs2_write_dnode(c, f, ri, target, strlen(target), phys_ofs, ALLOC_NORMAL);
-
- jffs2_free_raw_inode(ri);
-
-@@ -581,13 +360,6 @@
- f->metadata = fn;
- up(&f->sem);
-
-- /* Work out where to put the dirent node now. */
-- writtenlen = (writtenlen+3)&~3;
-- phys_ofs += writtenlen;
-- alloclen -= writtenlen;
--
-- if (alloclen < sizeof(*rd)+namelen) {
-- /* Not enough space left in this chunk. Get some more */
- jffs2_complete_reservation(c);
- ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
- if (ret) {
-@@ -595,7 +367,6 @@
- jffs2_clear_inode(inode);
- return ret;
- }
-- }
-
- rd = jffs2_alloc_raw_dirent();
- if (!rd) {
-@@ -608,41 +379,42 @@
- dir_f = JFFS2_INODE_INFO(dir_i);
- down(&dir_f->sem);
-
-- rd->magic = JFFS2_MAGIC_BITMASK;
-- rd->nodetype = JFFS2_NODETYPE_DIRENT;
-- rd->totlen = sizeof(*rd) + namelen;
-- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
--
-- rd->pino = dir_i->i_ino;
-- rd->version = ++dir_f->highest_version;
-- rd->ino = inode->i_ino;
-- rd->mctime = CURRENT_TIME;
-+ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
-+ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
-+ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
-+
-+ rd->pino = cpu_to_je32(dir_i->i_ino);
-+ rd->version = cpu_to_je32(++dir_f->highest_version);
-+ rd->ino = cpu_to_je32(inode->i_ino);
-+ rd->mctime = cpu_to_je32(get_seconds());
- rd->nsize = namelen;
- rd->type = DT_LNK;
-- rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
-- rd->name_crc = crc32(0, dentry->d_name.name, namelen);
-+ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
-+ rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
-
-- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
--
-- jffs2_complete_reservation(c);
-+ fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
-
- if (IS_ERR(fd)) {
- /* dirent failed to write. Delete the inode normally
- as if it were the final unlink() */
-+ jffs2_complete_reservation(c);
- jffs2_free_raw_dirent(rd);
- up(&dir_f->sem);
- jffs2_clear_inode(inode);
- return PTR_ERR(fd);
- }
-
-- dir_i->i_mtime = dir_i->i_ctime = rd->mctime;
-+ dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime));
-
- jffs2_free_raw_dirent(rd);
-
- /* Link the fd into the inode's list, obsoleting an old
- one if necessary. */
- jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-+
- up(&dir_f->sem);
-+ jffs2_complete_reservation(c);
-
- d_instantiate(dentry, inode);
- return 0;
-@@ -659,8 +431,7 @@
- struct jffs2_full_dnode *fn;
- struct jffs2_full_dirent *fd;
- int namelen;
-- __u32 alloclen, phys_ofs;
-- __u32 writtenlen;
-+ uint32_t alloclen, phys_ofs;
- int ret;
-
- mode |= S_IFDIR;
-@@ -692,13 +463,15 @@
-
- inode->i_op = &jffs2_dir_inode_operations;
- inode->i_fop = &jffs2_dir_operations;
-+ /* Directories get nlink 2 at start */
-+ inode->i_nlink = 2;
-
- f = JFFS2_INODE_INFO(inode);
-
-- ri->data_crc = 0;
-- ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
-+ ri->data_crc = cpu_to_je32(0);
-+ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-
-- fn = jffs2_write_dnode(inode, ri, NULL, 0, phys_ofs, &writtenlen);
-+ fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
-
- jffs2_free_raw_inode(ri);
-
-@@ -715,13 +488,6 @@
- f->metadata = fn;
- up(&f->sem);
-
-- /* Work out where to put the dirent node now. */
-- writtenlen = PAD(writtenlen);
-- phys_ofs += writtenlen;
-- alloclen -= writtenlen;
--
-- if (alloclen < sizeof(*rd)+namelen) {
-- /* Not enough space left in this chunk. Get some more */
- jffs2_complete_reservation(c);
- ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
- if (ret) {
-@@ -729,7 +495,6 @@
- jffs2_clear_inode(inode);
- return ret;
- }
-- }
-
- rd = jffs2_alloc_raw_dirent();
- if (!rd) {
-@@ -742,41 +507,43 @@
- dir_f = JFFS2_INODE_INFO(dir_i);
- down(&dir_f->sem);
-
-- rd->magic = JFFS2_MAGIC_BITMASK;
-- rd->nodetype = JFFS2_NODETYPE_DIRENT;
-- rd->totlen = sizeof(*rd) + namelen;
-- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
--
-- rd->pino = dir_i->i_ino;
-- rd->version = ++dir_f->highest_version;
-- rd->ino = inode->i_ino;
-- rd->mctime = CURRENT_TIME;
-+ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
-+ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
-+ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
-+
-+ rd->pino = cpu_to_je32(dir_i->i_ino);
-+ rd->version = cpu_to_je32(++dir_f->highest_version);
-+ rd->ino = cpu_to_je32(inode->i_ino);
-+ rd->mctime = cpu_to_je32(get_seconds());
- rd->nsize = namelen;
- rd->type = DT_DIR;
-- rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
-- rd->name_crc = crc32(0, dentry->d_name.name, namelen);
-+ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
-+ rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
-
-- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
--
-- jffs2_complete_reservation(c);
-+ fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
-
- if (IS_ERR(fd)) {
- /* dirent failed to write. Delete the inode normally
- as if it were the final unlink() */
-+ jffs2_complete_reservation(c);
- jffs2_free_raw_dirent(rd);
- up(&dir_f->sem);
- jffs2_clear_inode(inode);
- return PTR_ERR(fd);
- }
-
-- dir_i->i_mtime = dir_i->i_ctime = rd->mctime;
-+ dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime));
-+ dir_i->i_nlink++;
-
- jffs2_free_raw_dirent(rd);
-
- /* Link the fd into the inode's list, obsoleting an old
- one if necessary. */
- jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-+
- up(&dir_f->sem);
-+ jffs2_complete_reservation(c);
-
- d_instantiate(dentry, inode);
- return 0;
-@@ -786,15 +553,19 @@
- {
- struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode);
- struct jffs2_full_dirent *fd;
-+ int ret;
-
- for (fd = f->dents ; fd; fd = fd->next) {
- if (fd->ino)
- return -ENOTEMPTY;
- }
-- return jffs2_unlink(dir_i, dentry);
-+ ret = jffs2_unlink(dir_i, dentry);
-+ if (!ret)
-+ dir_i->i_nlink--;
-+ return ret;
- }
-
--static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, int rdev)
-+static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, mknod_arg_t rdev)
- {
- struct jffs2_inode_info *f, *dir_f;
- struct jffs2_sb_info *c;
-@@ -804,12 +575,14 @@
- struct jffs2_full_dnode *fn;
- struct jffs2_full_dirent *fd;
- int namelen;
-- unsigned short dev;
-+ jint16_t dev;
- int devlen = 0;
-- __u32 alloclen, phys_ofs;
-- __u32 writtenlen;
-+ uint32_t alloclen, phys_ofs;
- int ret;
-
-+ if (!old_valid_dev(rdev))
-+ return -EINVAL;
-+
- ri = jffs2_alloc_raw_inode();
- if (!ri)
- return -ENOMEM;
-@@ -817,7 +590,7 @@
- c = JFFS2_SB_INFO(dir_i->i_sb);
-
- if (S_ISBLK(mode) || S_ISCHR(mode)) {
-- dev = (MAJOR(to_kdev_t(rdev)) << 8) | MINOR(to_kdev_t(rdev));
-+ dev = cpu_to_je16(old_encode_dev(rdev));
- devlen = sizeof(dev);
- }
-
-@@ -844,15 +617,15 @@
-
- f = JFFS2_INODE_INFO(inode);
-
-- ri->dsize = ri->csize = devlen;
-- ri->totlen = sizeof(*ri) + ri->csize;
-- ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
-+ ri->dsize = ri->csize = cpu_to_je32(devlen);
-+ ri->totlen = cpu_to_je32(sizeof(*ri) + devlen);
-+ ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
-
- ri->compr = JFFS2_COMPR_NONE;
-- ri->data_crc = crc32(0, &dev, devlen);
-- ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
-+ ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen));
-+ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-
-- fn = jffs2_write_dnode(inode, ri, (char *)&dev, devlen, phys_ofs, &writtenlen);
-+ fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, phys_ofs, ALLOC_NORMAL);
-
- jffs2_free_raw_inode(ri);
-
-@@ -869,13 +642,6 @@
- f->metadata = fn;
- up(&f->sem);
-
-- /* Work out where to put the dirent node now. */
-- writtenlen = (writtenlen+3)&~3;
-- phys_ofs += writtenlen;
-- alloclen -= writtenlen;
--
-- if (alloclen < sizeof(*rd)+namelen) {
-- /* Not enough space left in this chunk. Get some more */
- jffs2_complete_reservation(c);
- ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
- if (ret) {
-@@ -883,7 +649,6 @@
- jffs2_clear_inode(inode);
- return ret;
- }
-- }
-
- rd = jffs2_alloc_raw_dirent();
- if (!rd) {
-@@ -896,44 +661,45 @@
- dir_f = JFFS2_INODE_INFO(dir_i);
- down(&dir_f->sem);
-
-- rd->magic = JFFS2_MAGIC_BITMASK;
-- rd->nodetype = JFFS2_NODETYPE_DIRENT;
-- rd->totlen = sizeof(*rd) + namelen;
-- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
--
-- rd->pino = dir_i->i_ino;
-- rd->version = ++dir_f->highest_version;
-- rd->ino = inode->i_ino;
-- rd->mctime = CURRENT_TIME;
-+ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
-+ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
-+ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
-+
-+ rd->pino = cpu_to_je32(dir_i->i_ino);
-+ rd->version = cpu_to_je32(++dir_f->highest_version);
-+ rd->ino = cpu_to_je32(inode->i_ino);
-+ rd->mctime = cpu_to_je32(get_seconds());
- rd->nsize = namelen;
-
- /* XXX: This is ugly. */
- rd->type = (mode & S_IFMT) >> 12;
-
-- rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
-- rd->name_crc = crc32(0, dentry->d_name.name, namelen);
--
-- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
-+ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
-+ rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
-
-- jffs2_complete_reservation(c);
-+ fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
-
- if (IS_ERR(fd)) {
- /* dirent failed to write. Delete the inode normally
- as if it were the final unlink() */
-+ jffs2_complete_reservation(c);
- jffs2_free_raw_dirent(rd);
- up(&dir_f->sem);
- jffs2_clear_inode(inode);
- return PTR_ERR(fd);
- }
-
-- dir_i->i_mtime = dir_i->i_ctime = rd->mctime;
-+ dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime));
-
- jffs2_free_raw_dirent(rd);
-
- /* Link the fd into the inode's list, obsoleting an old
- one if necessary. */
- jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-+
- up(&dir_f->sem);
-+ jffs2_complete_reservation(c);
-
- d_instantiate(dentry, inode);
-
-@@ -944,7 +710,9 @@
- struct inode *new_dir_i, struct dentry *new_dentry)
- {
- int ret;
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
- struct jffs2_inode_info *victim_f = NULL;
-+ uint8_t type;
-
- /* The VFS will check for us and prevent trying to rename a
- * file over a directory and vice versa, but if it's a directory,
-@@ -973,7 +741,15 @@
- */
-
- /* Make a hard link */
-- ret = jffs2_do_link(old_dentry, new_dir_i, new_dentry, 1);
-+
-+ /* XXX: This is ugly */
-+ type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
-+ if (!type) type = DT_REG;
-+
-+ ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i),
-+ old_dentry->d_inode->i_ino, type,
-+ new_dentry->d_name.name, new_dentry->d_name.len);
-+
- if (ret)
- return ret;
-
-@@ -989,22 +765,36 @@
- }
- }
-
-+ /* If it was a directory we moved, and there was no victim,
-+ increase i_nlink on its new parent */
-+ if (S_ISDIR(old_dentry->d_inode->i_mode) && !victim_f)
-+ new_dir_i->i_nlink++;
-+
- /* Unlink the original */
-- ret = jffs2_do_unlink(old_dir_i, old_dentry, 1);
-+ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
-+ old_dentry->d_name.name, old_dentry->d_name.len, NULL);
-+
-+ /* We don't touch inode->i_nlink */
-
- if (ret) {
- /* Oh shit. We really ought to make a single node which can do both atomically */
- struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode);
- down(&f->sem);
-+ old_dentry->d_inode->i_nlink++;
- if (f->inocache)
-- old_dentry->d_inode->i_nlink = f->inocache->nlink++;
-+ f->inocache->nlink++;
- up(&f->sem);
-
- printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ret);
- /* Might as well let the VFS know */
- d_instantiate(new_dentry, old_dentry->d_inode);
- atomic_inc(&old_dentry->d_inode->i_count);
-- }
- return ret;
-+ }
-+
-+ if (S_ISDIR(old_dentry->d_inode->i_mode))
-+ old_dir_i->i_nlink--;
-+
-+ return 0;
- }
-
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/erase.c linux/fs/jffs2/erase.c
---- linux-mips-2.4.24-pre2/fs/jffs2/erase.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/erase.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,68 +1,60 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-+
- #include <linux/kernel.h>
- #include <linux/slab.h>
- #include <linux/mtd/mtd.h>
--#include <linux/jffs2.h>
--#include <linux/interrupt.h>
--#include "nodelist.h"
-+#include <linux/compiler.h>
- #include <linux/crc32.h>
-+#include <linux/sched.h>
-+#include <linux/pagemap.h>
-+#include "nodelist.h"
-
- struct erase_priv_struct {
- struct jffs2_eraseblock *jeb;
- struct jffs2_sb_info *c;
- };
-
-+#ifndef __ECOS
- static void jffs2_erase_callback(struct erase_info *);
-+#endif
-+static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
- static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-
- void jffs2_erase_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
- {
-- struct erase_info *instr;
- int ret;
-+#ifdef __ECOS
-+ ret = jffs2_flash_erase(c, jeb);
-+ if (!ret) {
-+ jffs2_erase_succeeded(c, jeb);
-+ return;
-+ }
-+#else /* Linux */
-+ struct erase_info *instr;
-
- instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL);
- if (!instr) {
- printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n");
-- spin_lock_bh(&c->erase_completion_lock);
-+ spin_lock(&c->erase_completion_lock);
- list_del(&jeb->list);
- list_add(&jeb->list, &c->erase_pending_list);
- c->erasing_size -= c->sector_size;
-- spin_unlock_bh(&c->erase_completion_lock);
-+ c->dirty_size += c->sector_size;
-+ jeb->dirty_size = c->sector_size;
-+ spin_unlock(&c->erase_completion_lock);
- return;
- }
-
-@@ -77,19 +69,27 @@
- ((struct erase_priv_struct *)instr->priv)->jeb = jeb;
- ((struct erase_priv_struct *)instr->priv)->c = c;
-
-+ /* NAND , read out the fail counter, if possible */
-+ if (!jffs2_can_mark_obsolete(c))
-+ jffs2_nand_read_failcnt(c,jeb);
-+
- ret = c->mtd->erase(c->mtd, instr);
-- if (!ret) {
-+ if (!ret)
- return;
-- }
-+
-+ kfree(instr);
-+#endif /* __ECOS */
-+
- if (ret == -ENOMEM || ret == -EAGAIN) {
- /* Erase failed immediately. Refile it on the list */
- D1(printk(KERN_DEBUG "Erase at 0x%08x failed: %d. Refiling on erase_pending_list\n", jeb->offset, ret));
-- spin_lock_bh(&c->erase_completion_lock);
-+ spin_lock(&c->erase_completion_lock);
- list_del(&jeb->list);
- list_add(&jeb->list, &c->erase_pending_list);
- c->erasing_size -= c->sector_size;
-- spin_unlock_bh(&c->erase_completion_lock);
-- kfree(instr);
-+ c->dirty_size += c->sector_size;
-+ jeb->dirty_size = c->sector_size;
-+ spin_unlock(&c->erase_completion_lock);
- return;
- }
-
-@@ -97,74 +97,101 @@
- printk(KERN_WARNING "Erase at 0x%08x failed immediately: -EROFS. Is the sector locked?\n", jeb->offset);
- else
- printk(KERN_WARNING "Erase at 0x%08x failed immediately: errno %d\n", jeb->offset, ret);
-- spin_lock_bh(&c->erase_completion_lock);
-- list_del(&jeb->list);
-- list_add(&jeb->list, &c->bad_list);
-- c->nr_erasing_blocks--;
-- c->bad_size += c->sector_size;
-- c->erasing_size -= c->sector_size;
-- spin_unlock_bh(&c->erase_completion_lock);
-- wake_up(&c->erase_wait);
-- kfree(instr);
-+
-+ jffs2_erase_failed(c, jeb);
- }
-
--void jffs2_erase_pending_blocks(struct jffs2_sb_info *c)
-+void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count)
- {
- struct jffs2_eraseblock *jeb;
-
-- spin_lock_bh(&c->erase_completion_lock);
-- while (!list_empty(&c->erase_pending_list)) {
-+ down(&c->erase_free_sem);
-
-- jeb = list_entry(c->erase_pending_list.next, struct jffs2_eraseblock, list);
-+ spin_lock(&c->erase_completion_lock);
-
-- D1(printk(KERN_DEBUG "Starting erase of pending block 0x%08x\n", jeb->offset));
-+ while (!list_empty(&c->erase_complete_list) ||
-+ !list_empty(&c->erase_pending_list)) {
-
-+ if (!list_empty(&c->erase_complete_list)) {
-+ jeb = list_entry(c->erase_complete_list.next, struct jffs2_eraseblock, list);
-+ list_del(&jeb->list);
-+ spin_unlock(&c->erase_completion_lock);
-+ jffs2_mark_erased_block(c, jeb);
-+
-+ if (!--count) {
-+ D1(printk(KERN_DEBUG "Count reached. jffs2_erase_pending_blocks leaving\n"));
-+ goto done;
-+ }
-+
-+ } else if (!list_empty(&c->erase_pending_list)) {
-+ jeb = list_entry(c->erase_pending_list.next, struct jffs2_eraseblock, list);
-+ D1(printk(KERN_DEBUG "Starting erase of pending block 0x%08x\n", jeb->offset));
- list_del(&jeb->list);
- c->erasing_size += c->sector_size;
-+ c->wasted_size -= jeb->wasted_size;
- c->free_size -= jeb->free_size;
- c->used_size -= jeb->used_size;
- c->dirty_size -= jeb->dirty_size;
-- jeb->used_size = jeb->dirty_size = jeb->free_size = 0;
-+ jeb->wasted_size = jeb->used_size = jeb->dirty_size = jeb->free_size = 0;
- jffs2_free_all_node_refs(c, jeb);
- list_add(&jeb->list, &c->erasing_list);
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
-
- jffs2_erase_block(c, jeb);
-+
-+ } else {
-+ BUG();
-+ }
-+
- /* Be nice */
-- if (current->need_resched)
-- schedule();
-- spin_lock_bh(&c->erase_completion_lock);
-+ cond_resched();
-+ spin_lock(&c->erase_completion_lock);
- }
-- spin_unlock_bh(&c->erase_completion_lock);
-+
-+ spin_unlock(&c->erase_completion_lock);
-+ done:
- D1(printk(KERN_DEBUG "jffs2_erase_pending_blocks completed\n"));
-+
-+ up(&c->erase_free_sem);
-+}
-+
-+static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
-+{
-+ D1(printk(KERN_DEBUG "Erase completed successfully at 0x%08x\n", jeb->offset));
-+ spin_lock(&c->erase_completion_lock);
-+ list_del(&jeb->list);
-+ list_add_tail(&jeb->list, &c->erase_complete_list);
-+ spin_unlock(&c->erase_completion_lock);
-+ /* Ensure that kupdated calls us again to mark them clean */
-+ jffs2_erase_pending_trigger(c);
- }
-
-+static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
-+{
-+ spin_lock(&c->erase_completion_lock);
-+ c->erasing_size -= c->sector_size;
-+ c->bad_size += c->sector_size;
-+ list_del(&jeb->list);
-+ list_add(&jeb->list, &c->bad_list);
-+ c->nr_erasing_blocks--;
-+ spin_unlock(&c->erase_completion_lock);
-+ wake_up(&c->erase_wait);
-+}
-
-+#ifndef __ECOS
- static void jffs2_erase_callback(struct erase_info *instr)
- {
- struct erase_priv_struct *priv = (void *)instr->priv;
-
- if(instr->state != MTD_ERASE_DONE) {
- printk(KERN_WARNING "Erase at 0x%08x finished, but state != MTD_ERASE_DONE. State is 0x%x instead.\n", instr->addr, instr->state);
-- spin_lock(&priv->c->erase_completion_lock);
-- priv->c->erasing_size -= priv->c->sector_size;
-- priv->c->bad_size += priv->c->sector_size;
-- list_del(&priv->jeb->list);
-- list_add(&priv->jeb->list, &priv->c->bad_list);
-- priv->c->nr_erasing_blocks--;
-- spin_unlock(&priv->c->erase_completion_lock);
-- wake_up(&priv->c->erase_wait);
-+ jffs2_erase_failed(priv->c, priv->jeb);
- } else {
-- D1(printk(KERN_DEBUG "Erase completed successfully at 0x%08x\n", instr->addr));
-- spin_lock(&priv->c->erase_completion_lock);
-- list_del(&priv->jeb->list);
-- list_add_tail(&priv->jeb->list, &priv->c->erase_complete_list);
-- spin_unlock(&priv->c->erase_completion_lock);
-+ jffs2_erase_succeeded(priv->c, priv->jeb);
- }
-- /* Make sure someone picks up the block off the erase_complete list */
-- OFNI_BS_2SFFJ(priv->c)->s_dirt = 1;
- kfree(instr);
- }
-+#endif /* !__ECOS */
-
- /* Hmmm. Maybe we should accept the extra space it takes and make
- this a standard doubly-linked list? */
-@@ -221,7 +248,7 @@
- this = ic->nodes;
-
- while(this) {
-- printk( "0x%08x(%d)->", this->flash_offset & ~3, this->flash_offset &3);
-+ printk( "0x%08x(%d)->", ref_offset(this), ref_flags(this));
- if (++i == 5) {
- printk("\n" KERN_DEBUG);
- i=0;
-@@ -256,54 +283,43 @@
- jeb->last_node = NULL;
- }
-
--void jffs2_erase_pending_trigger(struct jffs2_sb_info *c)
-+static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
- {
-- OFNI_BS_2SFFJ(c)->s_dirt = 1;
--}
--
--void jffs2_mark_erased_blocks(struct jffs2_sb_info *c)
--{
-- static struct jffs2_unknown_node marker = {JFFS2_MAGIC_BITMASK, JFFS2_NODETYPE_CLEANMARKER, sizeof(struct jffs2_unknown_node)};
-- struct jffs2_eraseblock *jeb;
-- struct jffs2_raw_node_ref *marker_ref;
-+ struct jffs2_raw_node_ref *marker_ref = NULL;
- unsigned char *ebuf;
-- ssize_t retlen;
-+ size_t retlen;
- int ret;
-
-- marker.hdr_crc = crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4);
--
-- spin_lock_bh(&c->erase_completion_lock);
-- while (!list_empty(&c->erase_complete_list)) {
-- jeb = list_entry(c->erase_complete_list.next, struct jffs2_eraseblock, list);
-- list_del(&jeb->list);
-- spin_unlock_bh(&c->erase_completion_lock);
--
-+ if (!jffs2_cleanmarker_oob(c)) {
- marker_ref = jffs2_alloc_raw_node_ref();
- if (!marker_ref) {
- printk(KERN_WARNING "Failed to allocate raw node ref for clean marker\n");
-- /* Come back later */
-+ /* Stick it back on the list from whence it came and come back later */
- jffs2_erase_pending_trigger(c);
-+ spin_lock(&c->erase_completion_lock);
-+ list_add(&jeb->list, &c->erase_complete_list);
-+ spin_unlock(&c->erase_completion_lock);
- return;
- }
--
-+ }
- ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
- if (!ebuf) {
- printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Assuming it worked\n", jeb->offset);
- } else {
-- __u32 ofs = jeb->offset;
-+ uint32_t ofs = jeb->offset;
-
- D1(printk(KERN_DEBUG "Verifying erase at 0x%08x\n", jeb->offset));
- while(ofs < jeb->offset + c->sector_size) {
-- __u32 readlen = min((__u32)PAGE_SIZE, jeb->offset + c->sector_size - ofs);
-+ uint32_t readlen = min((uint32_t)PAGE_SIZE, jeb->offset + c->sector_size - ofs);
- int i;
-
-- ret = c->mtd->read(c->mtd, ofs, readlen, &retlen, ebuf);
-- if (ret < 0) {
-+ ret = jffs2_flash_read(c, ofs, readlen, &retlen, ebuf);
-+ if (ret) {
- printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret);
- goto bad;
- }
- if (retlen != readlen) {
-- printk(KERN_WARNING "Short read from newly-erased block at 0x%08x. Wanted %d, got %d\n", ofs, readlen, retlen);
-+ printk(KERN_WARNING "Short read from newly-erased block at 0x%08x. Wanted %d, got %zd\n", ofs, readlen, retlen);
- goto bad;
- }
- for (i=0; i<readlen; i += sizeof(unsigned long)) {
-@@ -312,62 +328,89 @@
- if (datum + 1) {
- printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", datum, ofs + i);
- bad:
-+ if (!jffs2_cleanmarker_oob(c))
- jffs2_free_raw_node_ref(marker_ref);
-+ else
-+ jffs2_write_nand_badblock( c ,jeb );
- kfree(ebuf);
- bad2:
-- spin_lock_bh(&c->erase_completion_lock);
-+ spin_lock(&c->erase_completion_lock);
- c->erasing_size -= c->sector_size;
- c->bad_size += c->sector_size;
-
- list_add_tail(&jeb->list, &c->bad_list);
- c->nr_erasing_blocks--;
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
- wake_up(&c->erase_wait);
- return;
- }
- }
- ofs += readlen;
-+ cond_resched();
- }
- kfree(ebuf);
- }
-
- /* Write the erase complete marker */
- D1(printk(KERN_DEBUG "Writing erased marker to block at 0x%08x\n", jeb->offset));
-- ret = c->mtd->write(c->mtd, jeb->offset, sizeof(marker), &retlen, (char *)&marker);
-+ if (jffs2_cleanmarker_oob(c)) {
-+
-+ if (jffs2_write_nand_cleanmarker(c, jeb))
-+ goto bad2;
-+
-+ jeb->first_node = jeb->last_node = NULL;
-+
-+ jeb->free_size = c->sector_size;
-+ jeb->used_size = 0;
-+ jeb->dirty_size = 0;
-+ jeb->wasted_size = 0;
-+ } else {
-+ struct jffs2_unknown_node marker = {
-+ .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
-+ .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
-+ .totlen = cpu_to_je32(c->cleanmarker_size)
-+ };
-+
-+ marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4));
-+
-+ /* We only write the header; the rest was noise or padding anyway */
-+ ret = jffs2_flash_write(c, jeb->offset, sizeof(marker), &retlen, (char *)&marker);
- if (ret) {
- printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n",
- jeb->offset, ret);
- goto bad2;
- }
- if (retlen != sizeof(marker)) {
-- printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %d, got %d\n",
-+ printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %d, got %zd\n",
- jeb->offset, sizeof(marker), retlen);
- goto bad2;
- }
-
- marker_ref->next_in_ino = NULL;
- marker_ref->next_phys = NULL;
-- marker_ref->flash_offset = jeb->offset;
-- marker_ref->totlen = PAD(sizeof(marker));
-+ marker_ref->flash_offset = jeb->offset | REF_NORMAL;
-+ marker_ref->__totlen = c->cleanmarker_size;
-
- jeb->first_node = jeb->last_node = marker_ref;
-
-- jeb->free_size = c->sector_size - marker_ref->totlen;
-- jeb->used_size = marker_ref->totlen;
-+ jeb->free_size = c->sector_size - c->cleanmarker_size;
-+ jeb->used_size = c->cleanmarker_size;
- jeb->dirty_size = 0;
-+ jeb->wasted_size = 0;
-+ }
-
-- spin_lock_bh(&c->erase_completion_lock);
-+ spin_lock(&c->erase_completion_lock);
- c->erasing_size -= c->sector_size;
- c->free_size += jeb->free_size;
- c->used_size += jeb->used_size;
-
- ACCT_SANITY_CHECK(c,jeb);
-- ACCT_PARANOIA_CHECK(jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-
- list_add_tail(&jeb->list, &c->free_list);
- c->nr_erasing_blocks--;
- c->nr_free_blocks++;
-+ spin_unlock(&c->erase_completion_lock);
- wake_up(&c->erase_wait);
-- }
-- spin_unlock_bh(&c->erase_completion_lock);
- }
-+
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/file.c linux/fs/jffs2/file.c
---- linux-mips-2.4.24-pre2/fs/jffs2/file.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/file.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,319 +1,106 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
-+#include <linux/version.h>
- #include <linux/kernel.h>
--#include <linux/mtd/compatmac.h> /* for min() */
- #include <linux/slab.h>
- #include <linux/fs.h>
-+#include <linux/time.h>
- #include <linux/pagemap.h>
-+#include <linux/highmem.h>
-+#include <linux/crc32.h>
- #include <linux/jffs2.h>
- #include "nodelist.h"
--#include <linux/crc32.h>
-
- extern int generic_file_open(struct inode *, struct file *) __attribute__((weak));
- extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) __attribute__((weak));
-
-
--int jffs2_null_fsync(struct file *filp, struct dentry *dentry, int datasync)
-+int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync)
- {
-- /* Move along. Nothing to see here */
-+ struct inode *inode = dentry->d_inode;
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-+
-+ /* Trigger GC to flush any pending writes for this inode */
-+ jffs2_flush_wbuf_gc(c, inode->i_ino);
-+
- return 0;
- }
-
- struct file_operations jffs2_file_operations =
- {
-- llseek: generic_file_llseek,
-- open: generic_file_open,
-- read: generic_file_read,
-- write: generic_file_write,
-- ioctl: jffs2_ioctl,
-- mmap: generic_file_mmap,
-- fsync: jffs2_null_fsync
-+ .llseek = generic_file_llseek,
-+ .open = generic_file_open,
-+ .read = generic_file_read,
-+ .write = generic_file_write,
-+ .ioctl = jffs2_ioctl,
-+ .mmap = generic_file_readonly_mmap,
-+ .fsync = jffs2_fsync,
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,29)
-+ .sendfile = generic_file_sendfile
-+#endif
- };
-
- /* jffs2_file_inode_operations */
-
- struct inode_operations jffs2_file_inode_operations =
- {
-- setattr: jffs2_setattr
-+ .setattr = jffs2_setattr
- };
-
- struct address_space_operations jffs2_file_address_operations =
- {
-- readpage: jffs2_readpage,
-- prepare_write: jffs2_prepare_write,
-- commit_write: jffs2_commit_write
-+ .readpage = jffs2_readpage,
-+ .prepare_write =jffs2_prepare_write,
-+ .commit_write = jffs2_commit_write
- };
-
--int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
--{
-- struct jffs2_full_dnode *old_metadata, *new_metadata;
-- struct inode *inode = dentry->d_inode;
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
-- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-- struct jffs2_raw_inode *ri;
-- unsigned short dev;
-- unsigned char *mdata = NULL;
-- int mdatalen = 0;
-- unsigned int ivalid;
-- __u32 phys_ofs, alloclen;
-- int ret;
-- D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino));
-- ret = inode_change_ok(inode, iattr);
-- if (ret)
-- return ret;
--
-- /* Special cases - we don't want more than one data node
-- for these types on the medium at any time. So setattr
-- must read the original data associated with the node
-- (i.e. the device numbers or the target name) and write
-- it out again with the appropriate data attached */
-- if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
-- /* For these, we don't actually need to read the old node */
-- dev = (MAJOR(to_kdev_t(dentry->d_inode->i_rdev)) << 8) |
-- MINOR(to_kdev_t(dentry->d_inode->i_rdev));
-- mdata = (char *)&dev;
-- mdatalen = sizeof(dev);
-- D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen));
-- } else if (S_ISLNK(inode->i_mode)) {
-- mdatalen = f->metadata->size;
-- mdata = kmalloc(f->metadata->size, GFP_USER);
-- if (!mdata)
-- return -ENOMEM;
-- ret = jffs2_read_dnode(c, f->metadata, mdata, 0, mdatalen);
-- if (ret) {
-- kfree(mdata);
-- return ret;
-- }
-- D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen));
-- }
--
-- ri = jffs2_alloc_raw_inode();
-- if (!ri) {
-- if (S_ISLNK(inode->i_mode))
-- kfree(mdata);
-- return -ENOMEM;
-- }
--
-- ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, ALLOC_NORMAL);
-- if (ret) {
-- jffs2_free_raw_inode(ri);
-- if (S_ISLNK(inode->i_mode))
-- kfree(mdata);
-- return ret;
-- }
-- down(&f->sem);
-- ivalid = iattr->ia_valid;
--
-- ri->magic = JFFS2_MAGIC_BITMASK;
-- ri->nodetype = JFFS2_NODETYPE_INODE;
-- ri->totlen = sizeof(*ri) + mdatalen;
-- ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
--
-- ri->ino = inode->i_ino;
-- ri->version = ++f->highest_version;
--
-- ri->mode = (ivalid & ATTR_MODE)?iattr->ia_mode:inode->i_mode;
-- ri->uid = (ivalid & ATTR_UID)?iattr->ia_uid:inode->i_uid;
-- ri->gid = (ivalid & ATTR_GID)?iattr->ia_gid:inode->i_gid;
--
-- if (ivalid & ATTR_MODE && ri->mode & S_ISGID &&
-- !in_group_p(ri->gid) && !capable(CAP_FSETID))
-- ri->mode &= ~S_ISGID;
--
-- ri->isize = (ivalid & ATTR_SIZE)?iattr->ia_size:inode->i_size;
-- ri->atime = (ivalid & ATTR_ATIME)?iattr->ia_atime:inode->i_atime;
-- ri->mtime = (ivalid & ATTR_MTIME)?iattr->ia_mtime:inode->i_mtime;
-- ri->ctime = (ivalid & ATTR_CTIME)?iattr->ia_ctime:inode->i_ctime;
--
-- ri->offset = 0;
-- ri->csize = ri->dsize = mdatalen;
-- ri->compr = JFFS2_COMPR_NONE;
-- if (inode->i_size < ri->isize) {
-- /* It's an extension. Make it a hole node */
-- ri->compr = JFFS2_COMPR_ZERO;
-- ri->dsize = ri->isize - inode->i_size;
-- ri->offset = inode->i_size;
-- }
-- ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
-- if (mdatalen)
-- ri->data_crc = crc32(0, mdata, mdatalen);
-- else
-- ri->data_crc = 0;
--
-- new_metadata = jffs2_write_dnode(inode, ri, mdata, mdatalen, phys_ofs, NULL);
-- if (S_ISLNK(inode->i_mode))
-- kfree(mdata);
--
-- jffs2_complete_reservation(c);
--
-- if (IS_ERR(new_metadata)) {
-- jffs2_free_raw_inode(ri);
-- up(&f->sem);
-- return PTR_ERR(new_metadata);
-- }
-- /* It worked. Update the inode */
-- inode->i_atime = ri->atime;
-- inode->i_ctime = ri->ctime;
-- inode->i_mtime = ri->mtime;
-- inode->i_mode = ri->mode;
-- inode->i_uid = ri->uid;
-- inode->i_gid = ri->gid;
--
--
-- old_metadata = f->metadata;
--
-- if (inode->i_size > ri->isize) {
-- vmtruncate(inode, ri->isize);
-- jffs2_truncate_fraglist (c, &f->fraglist, ri->isize);
-- }
--
-- if (inode->i_size < ri->isize) {
-- jffs2_add_full_dnode_to_inode(c, f, new_metadata);
-- inode->i_size = ri->isize;
-- f->metadata = NULL;
-- } else {
-- f->metadata = new_metadata;
-- }
-- if (old_metadata) {
-- jffs2_mark_node_obsolete(c, old_metadata->raw);
-- jffs2_free_full_dnode(old_metadata);
-- }
-- jffs2_free_raw_inode(ri);
-- up(&f->sem);
-- return 0;
--}
--
- int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg)
- {
- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-- struct jffs2_node_frag *frag = f->fraglist;
-- __u32 offset = pg->index << PAGE_CACHE_SHIFT;
-- __u32 end = offset + PAGE_CACHE_SIZE;
- unsigned char *pg_buf;
- int ret;
-
-- D1(printk(KERN_DEBUG "jffs2_do_readpage_nolock(): ino #%lu, page at offset 0x%x\n", inode->i_ino, offset));
-+ D2(printk(KERN_DEBUG "jffs2_do_readpage_nolock(): ino #%lu, page at offset 0x%lx\n", inode->i_ino, pg->index << PAGE_CACHE_SHIFT));
-
- if (!PageLocked(pg))
- PAGE_BUG(pg);
-
-- while(frag && frag->ofs + frag->size <= offset) {
-- // D1(printk(KERN_DEBUG "skipping frag %d-%d; before the region we care about\n", frag->ofs, frag->ofs + frag->size));
-- frag = frag->next;
-- }
--
- pg_buf = kmap(pg);
-+ /* FIXME: Can kmap fail? */
-
-- /* XXX FIXME: Where a single physical node actually shows up in two
-- frags, we read it twice. Don't do that. */
-- /* Now we're pointing at the first frag which overlaps our page */
-- while(offset < end) {
-- D2(printk(KERN_DEBUG "jffs2_readpage: offset %d, end %d\n", offset, end));
-- if (!frag || frag->ofs > offset) {
-- __u32 holesize = end - offset;
-- if (frag) {
-- D1(printk(KERN_NOTICE "Eep. Hole in ino %ld fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", inode->i_ino, frag->ofs, offset));
-- holesize = min(holesize, frag->ofs - offset);
-- D1(jffs2_print_frag_list(f));
-- }
-- D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize));
-- memset(pg_buf, 0, holesize);
-- pg_buf += holesize;
-- offset += holesize;
-- continue;
-- } else if (frag->ofs < offset && (offset & (PAGE_CACHE_SIZE-1)) != 0) {
-- D1(printk(KERN_NOTICE "Eep. Overlap in ino #%ld fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n",
-- inode->i_ino, frag->ofs, offset));
-- D1(jffs2_print_frag_list(f));
-- memset(pg_buf, 0, end - offset);
-- ClearPageUptodate(pg);
-- SetPageError(pg);
-- kunmap(pg);
-- return -EIO;
-- } else if (!frag->node) {
-- __u32 holeend = min(end, frag->ofs + frag->size);
-- D1(printk(KERN_DEBUG "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n", offset, holeend, frag->ofs, frag->ofs + frag->size));
-- memset(pg_buf, 0, holeend - offset);
-- pg_buf += holeend - offset;
-- offset = holeend;
-- frag = frag->next;
-- continue;
-- } else {
-- __u32 readlen;
-- __u32 fragofs; /* offset within the frag to start reading */
-+ ret = jffs2_read_inode_range(c, f, pg_buf, pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE);
-
-- fragofs = offset - frag->ofs;
-- readlen = min(frag->size - fragofs, end - offset);
-- D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%x\n", frag->ofs+fragofs,
-- fragofs+frag->ofs+readlen, frag->node->raw->flash_offset & ~3));
-- ret = jffs2_read_dnode(c, frag->node, pg_buf, fragofs + frag->ofs - frag->node->ofs, readlen);
-- D2(printk(KERN_DEBUG "node read done\n"));
- if (ret) {
-- D1(printk(KERN_DEBUG"jffs2_readpage error %d\n",ret));
-- memset(pg_buf, 0, readlen);
- ClearPageUptodate(pg);
- SetPageError(pg);
-- kunmap(pg);
-- return ret;
-- }
--
-- pg_buf += readlen;
-- offset += readlen;
-- frag = frag->next;
-- D2(printk(KERN_DEBUG "node read was OK. Looping\n"));
-- }
-- }
-- D2(printk(KERN_DEBUG "readpage finishing\n"));
-+ } else {
- SetPageUptodate(pg);
- ClearPageError(pg);
-+ }
-
- flush_dcache_page(pg);
--
- kunmap(pg);
-- D1(printk(KERN_DEBUG "readpage finished\n"));
-+
-+ D2(printk(KERN_DEBUG "readpage finished\n"));
- return 0;
- }
-
- int jffs2_do_readpage_unlock(struct inode *inode, struct page *pg)
- {
- int ret = jffs2_do_readpage_nolock(inode, pg);
-- UnlockPage(pg);
-+ unlock_page(pg);
- return ret;
- }
-
-@@ -333,17 +120,17 @@
- {
- struct inode *inode = pg->mapping->host;
- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
-- __u32 pageofs = pg->index << PAGE_CACHE_SHIFT;
-+ uint32_t pageofs = pg->index << PAGE_CACHE_SHIFT;
- int ret = 0;
-
-- D1(printk(KERN_DEBUG "jffs2_prepare_write() nrpages %ld\n", inode->i_mapping->nrpages));
-+ D1(printk(KERN_DEBUG "jffs2_prepare_write()\n"));
-
- if (pageofs > inode->i_size) {
- /* Make new hole frag from old EOF to new page */
- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
- struct jffs2_raw_inode ri;
- struct jffs2_full_dnode *fn;
-- __u32 phys_ofs, alloc_len;
-+ uint32_t phys_ofs, alloc_len;
-
- D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
- (unsigned int)inode->i_size, pageofs));
-@@ -355,29 +142,30 @@
- down(&f->sem);
- memset(&ri, 0, sizeof(ri));
-
-- ri.magic = JFFS2_MAGIC_BITMASK;
-- ri.nodetype = JFFS2_NODETYPE_INODE;
-- ri.totlen = sizeof(ri);
-- ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4);
--
-- ri.ino = f->inocache->ino;
-- ri.version = ++f->highest_version;
-- ri.mode = inode->i_mode;
-- ri.uid = inode->i_uid;
-- ri.gid = inode->i_gid;
-- ri.isize = max((__u32)inode->i_size, pageofs);
-- ri.atime = ri.ctime = ri.mtime = CURRENT_TIME;
-- ri.offset = inode->i_size;
-- ri.dsize = pageofs - inode->i_size;
-- ri.csize = 0;
-+ ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
-+ ri.totlen = cpu_to_je32(sizeof(ri));
-+ ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4));
-+
-+ ri.ino = cpu_to_je32(f->inocache->ino);
-+ ri.version = cpu_to_je32(++f->highest_version);
-+ ri.mode = cpu_to_jemode(inode->i_mode);
-+ ri.uid = cpu_to_je16(inode->i_uid);
-+ ri.gid = cpu_to_je16(inode->i_gid);
-+ ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs));
-+ ri.atime = ri.ctime = ri.mtime = cpu_to_je32(get_seconds());
-+ ri.offset = cpu_to_je32(inode->i_size);
-+ ri.dsize = cpu_to_je32(pageofs - inode->i_size);
-+ ri.csize = cpu_to_je32(0);
- ri.compr = JFFS2_COMPR_ZERO;
-- ri.node_crc = crc32(0, &ri, sizeof(ri)-8);
-- ri.data_crc = 0;
-+ ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
-+ ri.data_crc = cpu_to_je32(0);
-+
-+ fn = jffs2_write_dnode(c, f, &ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
-
-- fn = jffs2_write_dnode(inode, &ri, NULL, 0, phys_ofs, NULL);
-- jffs2_complete_reservation(c);
- if (IS_ERR(fn)) {
- ret = PTR_ERR(fn);
-+ jffs2_complete_reservation(c);
- up(&f->sem);
- return ret;
- }
-@@ -391,16 +179,17 @@
- D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in prepare_write, returned %d\n", ret));
- jffs2_mark_node_obsolete(c, fn->raw);
- jffs2_free_full_dnode(fn);
-+ jffs2_complete_reservation(c);
- up(&f->sem);
- return ret;
- }
-+ jffs2_complete_reservation(c);
- inode->i_size = pageofs;
- up(&f->sem);
- }
-
--
- /* Read in the page if it wasn't already present, unless it's a whole page */
-- if (!Page_Uptodate(pg) && (start || end < PAGE_CACHE_SIZE)) {
-+ if (!PageUptodate(pg) && (start || end < PAGE_CACHE_SIZE)) {
- down(&f->sem);
- ret = jffs2_do_readpage_nolock(inode, pg);
- up(&f->sem);
-@@ -417,14 +206,12 @@
- struct inode *inode = pg->mapping->host;
- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-- __u32 newsize = max_t(__u32, filp->f_dentry->d_inode->i_size, (pg->index << PAGE_CACHE_SHIFT) + end);
-- __u32 file_ofs = (pg->index << PAGE_CACHE_SHIFT);
-- __u32 writelen = min((__u32)PAGE_CACHE_SIZE, newsize - file_ofs);
- struct jffs2_raw_inode *ri;
- int ret = 0;
-- ssize_t writtenlen = 0;
-+ uint32_t writtenlen = 0;
-
-- D1(printk(KERN_DEBUG "jffs2_commit_write(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n", inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags));
-+ D1(printk(KERN_DEBUG "jffs2_commit_write(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n",
-+ inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags));
-
- if (!start && end == PAGE_CACHE_SIZE) {
- /* We need to avoid deadlock with page_cache_read() in
-@@ -435,109 +222,47 @@
- }
-
- ri = jffs2_alloc_raw_inode();
-- if (!ri)
-- return -ENOMEM;
--
-- while(writelen) {
-- struct jffs2_full_dnode *fn;
-- unsigned char *comprbuf = NULL;
-- unsigned char comprtype = JFFS2_COMPR_NONE;
-- __u32 phys_ofs, alloclen;
-- __u32 datalen, cdatalen;
-
-- D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, file_ofs));
--
-- ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL);
-- if (ret) {
-- SetPageError(pg);
-- D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret));
-- break;
-+ if (!ri) {
-+ D1(printk(KERN_DEBUG "jffs2_commit_write(): Allocation of raw inode failed\n"));
-+ return -ENOMEM;
- }
-- down(&f->sem);
-- datalen = writelen;
-- cdatalen = min(alloclen - sizeof(*ri), writelen);
--
-- comprbuf = kmalloc(cdatalen, GFP_KERNEL);
-- if (comprbuf) {
-- comprtype = jffs2_compress(page_address(pg)+ (file_ofs & (PAGE_CACHE_SIZE-1)), comprbuf, &datalen, &cdatalen);
-- }
-- if (comprtype == JFFS2_COMPR_NONE) {
-- /* Either compression failed, or the allocation of comprbuf failed */
-- if (comprbuf)
-- kfree(comprbuf);
-- comprbuf = page_address(pg) + (file_ofs & (PAGE_CACHE_SIZE -1));
-- datalen = cdatalen;
-- }
-- /* Now comprbuf points to the data to be written, be it compressed or not.
-- comprtype holds the compression type, and comprtype == JFFS2_COMPR_NONE means
-- that the comprbuf doesn't need to be kfree()d.
-- */
--
-- ri->magic = JFFS2_MAGIC_BITMASK;
-- ri->nodetype = JFFS2_NODETYPE_INODE;
-- ri->totlen = sizeof(*ri) + cdatalen;
-- ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
--
-- ri->ino = inode->i_ino;
-- ri->version = ++f->highest_version;
-- ri->mode = inode->i_mode;
-- ri->uid = inode->i_uid;
-- ri->gid = inode->i_gid;
-- ri->isize = max((__u32)inode->i_size, file_ofs + datalen);
-- ri->atime = ri->ctime = ri->mtime = CURRENT_TIME;
-- ri->offset = file_ofs;
-- ri->csize = cdatalen;
-- ri->dsize = datalen;
-- ri->compr = comprtype;
-- ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
-- ri->data_crc = crc32(0, comprbuf, cdatalen);
--
-- fn = jffs2_write_dnode(inode, ri, comprbuf, cdatalen, phys_ofs, NULL);
-
-- jffs2_complete_reservation(c);
-+ /* Set the fields that the generic jffs2_write_inode_range() code can't find */
-+ ri->ino = cpu_to_je32(inode->i_ino);
-+ ri->mode = cpu_to_jemode(inode->i_mode);
-+ ri->uid = cpu_to_je16(inode->i_uid);
-+ ri->gid = cpu_to_je16(inode->i_gid);
-+ ri->isize = cpu_to_je32((uint32_t)inode->i_size);
-+ ri->atime = ri->ctime = ri->mtime = cpu_to_je32(get_seconds());
-+
-+ /* In 2.4, it was already kmapped by generic_file_write(). Doesn't
-+ hurt to do it again. The alternative is ifdefs, which are ugly. */
-+ kmap(pg);
-+
-+ ret = jffs2_write_inode_range(c, f, ri, page_address(pg) + start,
-+ (pg->index << PAGE_CACHE_SHIFT) + start,
-+ end - start, &writtenlen);
-
-- if (comprtype != JFFS2_COMPR_NONE)
-- kfree(comprbuf);
-+ kunmap(pg);
-
-- if (IS_ERR(fn)) {
-- ret = PTR_ERR(fn);
-- up(&f->sem);
-- SetPageError(pg);
-- break;
-- }
-- ret = jffs2_add_full_dnode_to_inode(c, f, fn);
-- if (f->metadata) {
-- jffs2_mark_node_obsolete(c, f->metadata->raw);
-- jffs2_free_full_dnode(f->metadata);
-- f->metadata = NULL;
-- }
-- up(&f->sem);
- if (ret) {
-- /* Eep */
-- D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n", ret));
-- jffs2_mark_node_obsolete(c, fn->raw);
-- jffs2_free_full_dnode(fn);
-+ /* There was an error writing. */
- SetPageError(pg);
-- break;
- }
-- inode->i_size = ri->isize;
-+
-+ if (writtenlen) {
-+ if (inode->i_size < (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen) {
-+ inode->i_size = (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen;
- inode->i_blocks = (inode->i_size + 511) >> 9;
-- inode->i_ctime = inode->i_mtime = ri->ctime;
-- if (!datalen) {
-- printk(KERN_WARNING "Eep. We didn't actually write any bloody data\n");
-- ret = -EIO;
-- SetPageError(pg);
-- break;
-+
-+ inode->i_ctime = inode->i_mtime = ITIME(je32_to_cpu(ri->ctime));
- }
-- D1(printk(KERN_DEBUG "increasing writtenlen by %d\n", datalen));
-- writtenlen += datalen;
-- file_ofs += datalen;
-- writelen -= datalen;
- }
-
- jffs2_free_raw_inode(ri);
-
-- if (writtenlen < end) {
-+ if (start+writtenlen < end) {
- /* generic_file_write has written more to the page cache than we've
- actually written to the medium. Mark the page !Uptodate so that
- it gets reread */
-@@ -545,13 +270,7 @@
- SetPageError(pg);
- ClearPageUptodate(pg);
- }
-- if (writtenlen <= start) {
-- /* We didn't even get to the start of the affected part */
-- ret = ret?ret:-ENOSPC;
-- D1(printk(KERN_DEBUG "jffs2_commit_write(): Only %x bytes written to page. start (%x) not reached, returning %d\n", writtenlen, start, ret));
-- }
-- writtenlen = min(end-start, writtenlen-start);
-
-- D1(printk(KERN_DEBUG "jffs2_commit_write() returning %d. nrpages is %ld\n",writtenlen?writtenlen:ret, inode->i_mapping->nrpages));
-+ D1(printk(KERN_DEBUG "jffs2_commit_write() returning %d\n",writtenlen?writtenlen:ret));
- return writtenlen?writtenlen:ret;
- }
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/fs.c linux/fs/jffs2/fs.c
---- linux-mips-2.4.24-pre2/fs/jffs2/fs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/jffs2/fs.c 2004-11-17 18:17:59.301274096 +0100
-@@ -0,0 +1,618 @@
-+/*
-+ * JFFS2 -- Journalling Flash File System, Version 2.
-+ *
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
-+ *
-+ * Created by David Woodhouse <dwmw2@redhat.com>
-+ *
-+ * For licensing information, see the file 'LICENCE' in this directory.
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+#include <linux/version.h>
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/fs.h>
-+#include <linux/list.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/pagemap.h>
-+#include <linux/slab.h>
-+#include <linux/vfs.h>
-+#include <linux/crc32.h>
-+#include "nodelist.h"
-+
-+
-+static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
-+{
-+ struct jffs2_full_dnode *old_metadata, *new_metadata;
-+ struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-+ struct jffs2_raw_inode *ri;
-+ unsigned short dev;
-+ unsigned char *mdata = NULL;
-+ int mdatalen = 0;
-+ unsigned int ivalid;
-+ uint32_t phys_ofs, alloclen;
-+ int ret;
-+ D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino));
-+ ret = inode_change_ok(inode, iattr);
-+ if (ret)
-+ return ret;
-+
-+ /* Special cases - we don't want more than one data node
-+ for these types on the medium at any time. So setattr
-+ must read the original data associated with the node
-+ (i.e. the device numbers or the target name) and write
-+ it out again with the appropriate data attached */
-+ if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
-+ /* For these, we don't actually need to read the old node */
-+ dev = old_encode_dev(inode->i_rdev);
-+ mdata = (char *)&dev;
-+ mdatalen = sizeof(dev);
-+ D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen));
-+ } else if (S_ISLNK(inode->i_mode)) {
-+ mdatalen = f->metadata->size;
-+ mdata = kmalloc(f->metadata->size, GFP_USER);
-+ if (!mdata)
-+ return -ENOMEM;
-+ ret = jffs2_read_dnode(c, f->metadata, mdata, 0, mdatalen);
-+ if (ret) {
-+ kfree(mdata);
-+ return ret;
-+ }
-+ D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen));
-+ }
-+
-+ ri = jffs2_alloc_raw_inode();
-+ if (!ri) {
-+ if (S_ISLNK(inode->i_mode))
-+ kfree(mdata);
-+ return -ENOMEM;
-+ }
-+
-+ ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, ALLOC_NORMAL);
-+ if (ret) {
-+ jffs2_free_raw_inode(ri);
-+ if (S_ISLNK(inode->i_mode & S_IFMT))
-+ kfree(mdata);
-+ return ret;
-+ }
-+ down(&f->sem);
-+ ivalid = iattr->ia_valid;
-+
-+ ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
-+ ri->totlen = cpu_to_je32(sizeof(*ri) + mdatalen);
-+ ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
-+
-+ ri->ino = cpu_to_je32(inode->i_ino);
-+ ri->version = cpu_to_je32(++f->highest_version);
-+
-+ ri->uid = cpu_to_je16((ivalid & ATTR_UID)?iattr->ia_uid:inode->i_uid);
-+ ri->gid = cpu_to_je16((ivalid & ATTR_GID)?iattr->ia_gid:inode->i_gid);
-+
-+ if (ivalid & ATTR_MODE)
-+ if (iattr->ia_mode & S_ISGID &&
-+ !in_group_p(je16_to_cpu(ri->gid)) && !capable(CAP_FSETID))
-+ ri->mode = cpu_to_jemode(iattr->ia_mode & ~S_ISGID);
-+ else
-+ ri->mode = cpu_to_jemode(iattr->ia_mode);
-+ else
-+ ri->mode = cpu_to_jemode(inode->i_mode);
-+
-+
-+ ri->isize = cpu_to_je32((ivalid & ATTR_SIZE)?iattr->ia_size:inode->i_size);
-+ ri->atime = cpu_to_je32(I_SEC((ivalid & ATTR_ATIME)?iattr->ia_atime:inode->i_atime));
-+ ri->mtime = cpu_to_je32(I_SEC((ivalid & ATTR_MTIME)?iattr->ia_mtime:inode->i_mtime));
-+ ri->ctime = cpu_to_je32(I_SEC((ivalid & ATTR_CTIME)?iattr->ia_ctime:inode->i_ctime));
-+
-+ ri->offset = cpu_to_je32(0);
-+ ri->csize = ri->dsize = cpu_to_je32(mdatalen);
-+ ri->compr = JFFS2_COMPR_NONE;
-+ if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
-+ /* It's an extension. Make it a hole node */
-+ ri->compr = JFFS2_COMPR_ZERO;
-+ ri->dsize = cpu_to_je32(iattr->ia_size - inode->i_size);
-+ ri->offset = cpu_to_je32(inode->i_size);
-+ }
-+ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-+ if (mdatalen)
-+ ri->data_crc = cpu_to_je32(crc32(0, mdata, mdatalen));
-+ else
-+ ri->data_crc = cpu_to_je32(0);
-+
-+ new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, phys_ofs, ALLOC_NORMAL);
-+ if (S_ISLNK(inode->i_mode))
-+ kfree(mdata);
-+
-+ if (IS_ERR(new_metadata)) {
-+ jffs2_complete_reservation(c);
-+ jffs2_free_raw_inode(ri);
-+ up(&f->sem);
-+ return PTR_ERR(new_metadata);
-+ }
-+ /* It worked. Update the inode */
-+ inode->i_atime = ITIME(je32_to_cpu(ri->atime));
-+ inode->i_ctime = ITIME(je32_to_cpu(ri->ctime));
-+ inode->i_mtime = ITIME(je32_to_cpu(ri->mtime));
-+ inode->i_mode = jemode_to_cpu(ri->mode);
-+ inode->i_uid = je16_to_cpu(ri->uid);
-+ inode->i_gid = je16_to_cpu(ri->gid);
-+
-+
-+ old_metadata = f->metadata;
-+
-+ if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size)
-+ jffs2_truncate_fraglist (c, &f->fragtree, iattr->ia_size);
-+
-+ if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
-+ jffs2_add_full_dnode_to_inode(c, f, new_metadata);
-+ inode->i_size = iattr->ia_size;
-+ f->metadata = NULL;
-+ } else {
-+ f->metadata = new_metadata;
-+ }
-+ if (old_metadata) {
-+ jffs2_mark_node_obsolete(c, old_metadata->raw);
-+ jffs2_free_full_dnode(old_metadata);
-+ }
-+ jffs2_free_raw_inode(ri);
-+
-+ up(&f->sem);
-+ jffs2_complete_reservation(c);
-+
-+ /* We have to do the vmtruncate() without f->sem held, since
-+ some pages may be locked and waiting for it in readpage().
-+ We are protected from a simultaneous write() extending i_size
-+ back past iattr->ia_size, because do_truncate() holds the
-+ generic inode semaphore. */
-+ if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size)
-+ vmtruncate(inode, iattr->ia_size);
-+
-+ return 0;
-+}
-+
-+int jffs2_setattr(struct dentry *dentry, struct iattr *iattr)
-+{
-+ return jffs2_do_setattr(dentry->d_inode, iattr);
-+}
-+
-+int jffs2_statfs(struct super_block *sb, struct kstatfs *buf)
-+{
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-+ unsigned long avail;
-+
-+ buf->f_type = JFFS2_SUPER_MAGIC;
-+ buf->f_bsize = 1 << PAGE_SHIFT;
-+ buf->f_blocks = c->flash_size >> PAGE_SHIFT;
-+ buf->f_files = 0;
-+ buf->f_ffree = 0;
-+ buf->f_namelen = JFFS2_MAX_NAME_LEN;
-+
-+ spin_lock(&c->erase_completion_lock);
-+
-+ avail = c->dirty_size + c->free_size;
-+ if (avail > c->sector_size * c->resv_blocks_write)
-+ avail -= c->sector_size * c->resv_blocks_write;
-+ else
-+ avail = 0;
-+
-+ buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT;
-+
-+ D1(jffs2_dump_block_lists(c));
-+
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ return 0;
-+}
-+
-+
-+void jffs2_clear_inode (struct inode *inode)
-+{
-+ /* We can forget about this inode for now - drop all
-+ * the nodelists associated with it, etc.
-+ */
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-+ struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
-+
-+ D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
-+
-+ jffs2_do_clear_inode(c, f);
-+}
-+
-+void jffs2_read_inode (struct inode *inode)
-+{
-+ struct jffs2_inode_info *f;
-+ struct jffs2_sb_info *c;
-+ struct jffs2_raw_inode latest_node;
-+ int ret;
-+
-+ D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino));
-+
-+ f = JFFS2_INODE_INFO(inode);
-+ c = JFFS2_SB_INFO(inode->i_sb);
-+
-+ jffs2_init_inode_info(f);
-+
-+ ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
-+
-+ if (ret) {
-+ make_bad_inode(inode);
-+ up(&f->sem);
-+ return;
-+ }
-+ inode->i_mode = jemode_to_cpu(latest_node.mode);
-+ inode->i_uid = je16_to_cpu(latest_node.uid);
-+ inode->i_gid = je16_to_cpu(latest_node.gid);
-+ inode->i_size = je32_to_cpu(latest_node.isize);
-+ inode->i_atime = ITIME(je32_to_cpu(latest_node.atime));
-+ inode->i_mtime = ITIME(je32_to_cpu(latest_node.mtime));
-+ inode->i_ctime = ITIME(je32_to_cpu(latest_node.ctime));
-+
-+ inode->i_nlink = f->inocache->nlink;
-+
-+ inode->i_blksize = PAGE_SIZE;
-+ inode->i_blocks = (inode->i_size + 511) >> 9;
-+
-+ switch (inode->i_mode & S_IFMT) {
-+ jint16_t rdev;
-+
-+ case S_IFLNK:
-+ inode->i_op = &jffs2_symlink_inode_operations;
-+ break;
-+
-+ case S_IFDIR:
-+ {
-+ struct jffs2_full_dirent *fd;
-+
-+ for (fd=f->dents; fd; fd = fd->next) {
-+ if (fd->type == DT_DIR && fd->ino)
-+ inode->i_nlink++;
-+ }
-+ /* and '..' */
-+ inode->i_nlink++;
-+ /* Root dir gets i_nlink 3 for some reason */
-+ if (inode->i_ino == 1)
-+ inode->i_nlink++;
-+
-+ inode->i_op = &jffs2_dir_inode_operations;
-+ inode->i_fop = &jffs2_dir_operations;
-+ break;
-+ }
-+ case S_IFREG:
-+ inode->i_op = &jffs2_file_inode_operations;
-+ inode->i_fop = &jffs2_file_operations;
-+ inode->i_mapping->a_ops = &jffs2_file_address_operations;
-+ inode->i_mapping->nrpages = 0;
-+ break;
-+
-+ case S_IFBLK:
-+ case S_IFCHR:
-+ /* Read the device numbers from the media */
-+ D1(printk(KERN_DEBUG "Reading device numbers from flash\n"));
-+ if (jffs2_read_dnode(c, f->metadata, (char *)&rdev, 0, sizeof(rdev)) < 0) {
-+ /* Eep */
-+ printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino);
-+ up(&f->sem);
-+ jffs2_do_clear_inode(c, f);
-+ make_bad_inode(inode);
-+ return;
-+ }
-+
-+ case S_IFSOCK:
-+ case S_IFIFO:
-+ inode->i_op = &jffs2_file_inode_operations;
-+ init_special_inode(inode, inode->i_mode,
-+ old_decode_dev((je16_to_cpu(rdev))));
-+ break;
-+
-+ default:
-+ printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu\n", inode->i_mode, (unsigned long)inode->i_ino);
-+ }
-+
-+ up(&f->sem);
-+
-+ D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
-+}
-+
-+void jffs2_dirty_inode(struct inode *inode)
-+{
-+ struct iattr iattr;
-+
-+ if (!(inode->i_state & I_DIRTY_DATASYNC)) {
-+ D2(printk(KERN_DEBUG "jffs2_dirty_inode() not calling setattr() for ino #%lu\n", inode->i_ino));
-+ return;
-+ }
-+
-+ D1(printk(KERN_DEBUG "jffs2_dirty_inode() calling setattr() for ino #%lu\n", inode->i_ino));
-+
-+ iattr.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_MTIME|ATTR_CTIME;
-+ iattr.ia_mode = inode->i_mode;
-+ iattr.ia_uid = inode->i_uid;
-+ iattr.ia_gid = inode->i_gid;
-+ iattr.ia_atime = inode->i_atime;
-+ iattr.ia_mtime = inode->i_mtime;
-+ iattr.ia_ctime = inode->i_ctime;
-+
-+ jffs2_do_setattr(inode, &iattr);
-+}
-+
-+int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
-+{
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-+
-+ if (c->flags & JFFS2_SB_FLAG_RO && !(sb->s_flags & MS_RDONLY))
-+ return -EROFS;
-+
-+ /* We stop if it was running, then restart if it needs to.
-+ This also catches the case where it was stopped and this
-+ is just a remount to restart it */
-+ if (!(sb->s_flags & MS_RDONLY))
-+ jffs2_stop_garbage_collect_thread(c);
-+
-+ if (!(*flags & MS_RDONLY))
-+ jffs2_start_garbage_collect_thread(c);
-+
-+ sb->s_flags = (sb->s_flags & ~MS_RDONLY)|(*flags & MS_RDONLY);
-+
-+ return 0;
-+}
-+
-+void jffs2_write_super (struct super_block *sb)
-+{
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-+ sb->s_dirt = 0;
-+
-+ if (sb->s_flags & MS_RDONLY)
-+ return;
-+
-+ D1(printk(KERN_DEBUG "jffs2_write_super()\n"));
-+ jffs2_garbage_collect_trigger(c);
-+ jffs2_erase_pending_blocks(c, 0);
-+ jffs2_flush_wbuf_gc(c, 0);
-+}
-+
-+
-+/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
-+ fill in the raw_inode while you're at it. */
-+struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri)
-+{
-+ struct inode *inode;
-+ struct super_block *sb = dir_i->i_sb;
-+ struct jffs2_sb_info *c;
-+ struct jffs2_inode_info *f;
-+ int ret;
-+
-+ D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode));
-+
-+ c = JFFS2_SB_INFO(sb);
-+
-+ inode = new_inode(sb);
-+
-+ if (!inode)
-+ return ERR_PTR(-ENOMEM);
-+
-+ f = JFFS2_INODE_INFO(inode);
-+ jffs2_init_inode_info(f);
-+
-+ memset(ri, 0, sizeof(*ri));
-+ /* Set OS-specific defaults for new inodes */
-+ ri->uid = cpu_to_je16(current->fsuid);
-+
-+ if (dir_i->i_mode & S_ISGID) {
-+ ri->gid = cpu_to_je16(dir_i->i_gid);
-+ if (S_ISDIR(mode))
-+ mode |= S_ISGID;
-+ } else {
-+ ri->gid = cpu_to_je16(current->fsgid);
-+ }
-+ ri->mode = cpu_to_jemode(mode);
-+ ret = jffs2_do_new_inode (c, f, mode, ri);
-+ if (ret) {
-+ make_bad_inode(inode);
-+ iput(inode);
-+ return ERR_PTR(ret);
-+ }
-+ inode->i_nlink = 1;
-+ inode->i_ino = je32_to_cpu(ri->ino);
-+ inode->i_mode = jemode_to_cpu(ri->mode);
-+ inode->i_gid = je16_to_cpu(ri->gid);
-+ inode->i_uid = je16_to_cpu(ri->uid);
-+ inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME;
-+ ri->atime = ri->mtime = ri->ctime = cpu_to_je32(I_SEC(inode->i_mtime));
-+
-+ inode->i_blksize = PAGE_SIZE;
-+ inode->i_blocks = 0;
-+ inode->i_size = 0;
-+
-+ insert_inode_hash(inode);
-+
-+ return inode;
-+}
-+
-+
-+int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
-+{
-+ struct jffs2_sb_info *c;
-+ struct inode *root_i;
-+ int ret;
-+ size_t blocks;
-+
-+ c = JFFS2_SB_INFO(sb);
-+
-+ c->flash_size = c->mtd->size;
-+
-+ /*
-+ * Check, if we have to concatenate physical blocks to larger virtual blocks
-+ * to reduce the memorysize for c->blocks. (kmalloc allows max. 128K allocation)
-+ */
-+ blocks = c->flash_size / c->mtd->erasesize;
-+ while ((blocks * sizeof (struct jffs2_eraseblock)) > (128 * 1024))
-+ blocks >>= 1;
-+
-+ c->sector_size = c->flash_size / blocks;
-+ if (c->sector_size != c->mtd->erasesize)
-+ printk(KERN_INFO "jffs2: Erase block size too small (%dKiB). Using virtual blocks size (%dKiB) instead\n",
-+ c->mtd->erasesize / 1024, c->sector_size / 1024);
-+
-+ if (c->flash_size < 5*c->sector_size) {
-+ printk(KERN_ERR "jffs2: Too few erase blocks (%d)\n", c->flash_size / c->sector_size);
-+ return -EINVAL;
-+ }
-+
-+ c->cleanmarker_size = sizeof(struct jffs2_unknown_node);
-+ /* Joern -- stick alignment for weird 8-byte-page flash here */
-+
-+ if (jffs2_cleanmarker_oob(c)) {
-+ /* NAND (or other bizarre) flash... do setup accordingly */
-+ ret = jffs2_nand_flash_setup(c);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ c->inocache_list = kmalloc(INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *), GFP_KERNEL);
-+ if (!c->inocache_list) {
-+ ret = -ENOMEM;
-+ goto out_wbuf;
-+ }
-+ memset(c->inocache_list, 0, INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *));
-+
-+ if ((ret = jffs2_do_mount_fs(c)))
-+ goto out_inohash;
-+
-+ ret = -EINVAL;
-+
-+ D1(printk(KERN_DEBUG "jffs2_do_fill_super(): Getting root inode\n"));
-+ root_i = iget(sb, 1);
-+ if (is_bad_inode(root_i)) {
-+ D1(printk(KERN_WARNING "get root inode failed\n"));
-+ goto out_nodes;
-+ }
-+
-+ D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n"));
-+ sb->s_root = d_alloc_root(root_i);
-+ if (!sb->s_root)
-+ goto out_root_i;
-+
-+#if LINUX_VERSION_CODE >= 0x20403
-+ sb->s_maxbytes = 0xFFFFFFFF;
-+#endif
-+ sb->s_blocksize = PAGE_CACHE_SIZE;
-+ sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-+ sb->s_magic = JFFS2_SUPER_MAGIC;
-+ if (!(sb->s_flags & MS_RDONLY))
-+ jffs2_start_garbage_collect_thread(c);
-+ return 0;
-+
-+ out_root_i:
-+ iput(root_i);
-+ out_nodes:
-+ jffs2_free_ino_caches(c);
-+ jffs2_free_raw_node_refs(c);
-+ kfree(c->blocks);
-+ out_inohash:
-+ kfree(c->inocache_list);
-+ out_wbuf:
-+ jffs2_nand_flash_cleanup(c);
-+
-+ return ret;
-+}
-+
-+void jffs2_gc_release_inode(struct jffs2_sb_info *c,
-+ struct jffs2_inode_info *f)
-+{
-+ iput(OFNI_EDONI_2SFFJ(f));
-+}
-+
-+struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
-+ int inum, int nlink)
-+{
-+ struct inode *inode;
-+ struct jffs2_inode_cache *ic;
-+ if (!nlink) {
-+ /* The inode has zero nlink but its nodes weren't yet marked
-+ obsolete. This has to be because we're still waiting for
-+ the final (close() and) iput() to happen.
-+
-+ There's a possibility that the final iput() could have
-+ happened while we were contemplating. In order to ensure
-+ that we don't cause a new read_inode() (which would fail)
-+ for the inode in question, we use ilookup() in this case
-+ instead of iget().
-+
-+ The nlink can't _become_ zero at this point because we're
-+ holding the alloc_sem, and jffs2_do_unlink() would also
-+ need that while decrementing nlink on any inode.
-+ */
-+ inode = ilookup(OFNI_BS_2SFFJ(c), inum);
-+ if (!inode) {
-+ D1(printk(KERN_DEBUG "ilookup() failed for ino #%u; inode is probably deleted.\n",
-+ inum));
-+
-+ spin_lock(&c->inocache_lock);
-+ ic = jffs2_get_ino_cache(c, inum);
-+ if (!ic) {
-+ D1(printk(KERN_DEBUG "Inode cache for ino #%u is gone.\n", inum));
-+ spin_unlock(&c->inocache_lock);
-+ return NULL;
-+ }
-+ if (ic->state != INO_STATE_CHECKEDABSENT) {
-+ /* Wait for progress. Don't just loop */
-+ D1(printk(KERN_DEBUG "Waiting for ino #%u in state %d\n",
-+ ic->ino, ic->state));
-+ sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
-+ } else {
-+ spin_unlock(&c->inocache_lock);
-+ }
-+
-+ return NULL;
-+ }
-+ } else {
-+ /* Inode has links to it still; they're not going away because
-+ jffs2_do_unlink() would need the alloc_sem and we have it.
-+ Just iget() it, and if read_inode() is necessary that's OK.
-+ */
-+ inode = iget(OFNI_BS_2SFFJ(c), inum);
-+ if (!inode)
-+ return ERR_PTR(-ENOMEM);
-+ }
-+ if (is_bad_inode(inode)) {
-+ printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. nlink %d\n",
-+ inum, nlink);
-+ /* NB. This will happen again. We need to do something appropriate here. */
-+ iput(inode);
-+ return ERR_PTR(-EIO);
-+ }
-+
-+ return JFFS2_INODE_INFO(inode);
-+}
-+
-+unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
-+ struct jffs2_inode_info *f,
-+ unsigned long offset,
-+ unsigned long *priv)
-+{
-+ struct inode *inode = OFNI_EDONI_2SFFJ(f);
-+ struct page *pg;
-+
-+ pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT,
-+ (void *)jffs2_do_readpage_unlock, inode);
-+ if (IS_ERR(pg))
-+ return (void *)pg;
-+
-+ *priv = (unsigned long)pg;
-+ return kmap(pg);
-+}
-+
-+void jffs2_gc_release_page(struct jffs2_sb_info *c,
-+ unsigned char *ptr,
-+ unsigned long *priv)
-+{
-+ struct page *pg = (void *)*priv;
-+
-+ kunmap(pg);
-+ page_cache_release(pg);
-+}
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/gc.c linux/fs/jffs2/gc.c
---- linux-mips-2.4.24-pre2/fs/jffs2/gc.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/gc.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,76 +1,67 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/kernel.h>
- #include <linux/mtd/mtd.h>
- #include <linux/slab.h>
--#include <linux/jffs2.h>
--#include <linux/sched.h>
--#include <linux/interrupt.h>
- #include <linux/pagemap.h>
--#include "nodelist.h"
- #include <linux/crc32.h>
-+#include <linux/compiler.h>
-+#include <linux/stat.h>
-+#include "nodelist.h"
-
-+static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
-+ struct jffs2_inode_cache *ic,
-+ struct jffs2_raw_node_ref *raw);
- static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dnode *fd);
-+ struct jffs2_inode_info *f, struct jffs2_full_dnode *fd);
- static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dirent *fd);
-+ struct jffs2_inode_info *f, struct jffs2_full_dirent *fd);
- static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dirent *fd);
-+ struct jffs2_inode_info *f, struct jffs2_full_dirent *fd);
- static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *indeo, struct jffs2_full_dnode *fn,
-- __u32 start, __u32 end);
-+ struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
-+ uint32_t start, uint32_t end);
- static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dnode *fn,
-- __u32 start, __u32 end);
-+ struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
-+ uint32_t start, uint32_t end);
-+static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-+ struct jffs2_raw_node_ref *raw, struct jffs2_inode_info *f);
-
- /* Called with erase_completion_lock held */
- static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c)
- {
- struct jffs2_eraseblock *ret;
- struct list_head *nextlist = NULL;
-+ int n = jiffies % 128;
-
- /* Pick an eraseblock to garbage collect next. This is where we'll
- put the clever wear-levelling algorithms. Eventually. */
-- if (!list_empty(&c->bad_used_list) && c->nr_free_blocks > JFFS2_RESERVED_BLOCKS_GCBAD) {
-+ /* We possibly want to favour the dirtier blocks more when the
-+ number of free blocks is low. */
-+ if (!list_empty(&c->bad_used_list) && c->nr_free_blocks > c->resv_blocks_gcbad) {
- D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n"));
- nextlist = &c->bad_used_list;
-- } else if (jiffies % 100 && !list_empty(&c->dirty_list)) {
-- /* Most of the time, pick one off the dirty list */
-+ } else if (n < 50 && !list_empty(&c->erasable_list)) {
-+ /* Note that most of them will have gone directly to be erased.
-+ So don't favour the erasable_list _too_ much. */
-+ D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next\n"));
-+ nextlist = &c->erasable_list;
-+ } else if (n < 110 && !list_empty(&c->very_dirty_list)) {
-+ /* Most of the time, pick one off the very_dirty list */
-+ D1(printk(KERN_DEBUG "Picking block from very_dirty_list to GC next\n"));
-+ nextlist = &c->very_dirty_list;
-+ } else if (n < 126 && !list_empty(&c->dirty_list)) {
- D1(printk(KERN_DEBUG "Picking block from dirty_list to GC next\n"));
- nextlist = &c->dirty_list;
- } else if (!list_empty(&c->clean_list)) {
-@@ -80,9 +71,16 @@
- D1(printk(KERN_DEBUG "Picking block from dirty_list to GC next (clean_list was empty)\n"));
-
- nextlist = &c->dirty_list;
-+ } else if (!list_empty(&c->very_dirty_list)) {
-+ D1(printk(KERN_DEBUG "Picking block from very_dirty_list to GC next (clean_list and dirty_list were empty)\n"));
-+ nextlist = &c->very_dirty_list;
-+ } else if (!list_empty(&c->erasable_list)) {
-+ D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next (clean_list and {very_,}dirty_list were empty)\n"));
-+
-+ nextlist = &c->erasable_list;
- } else {
-- /* Eep. Both were empty */
-- printk(KERN_NOTICE "jffs2: No clean _or_ dirty blocks to GC from! Where are they all?\n");
-+ /* Eep. All were empty */
-+ printk(KERN_NOTICE "jffs2: No clean, dirty _or_ erasable blocks to GC from! Where are they all?\n");
- return NULL;
- }
-
-@@ -94,6 +92,17 @@
- printk(KERN_WARNING "Eep. ret->gc_node for block at 0x%08x is NULL\n", ret->offset);
- BUG();
- }
-+
-+ /* Have we accidentally picked a clean block with wasted space ? */
-+ if (ret->wasted_size) {
-+ D1(printk(KERN_DEBUG "Converting wasted_size %08x to dirty_size\n", ret->wasted_size));
-+ ret->dirty_size += ret->wasted_size;
-+ c->wasted_size -= ret->wasted_size;
-+ c->dirty_size += ret->wasted_size;
-+ ret->wasted_size = 0;
-+ }
-+
-+ D1(jffs2_dump_block_lists(c));
- return ret;
- }
-
-@@ -103,21 +112,90 @@
- */
- int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
- {
-- struct jffs2_eraseblock *jeb;
- struct jffs2_inode_info *f;
-- struct jffs2_raw_node_ref *raw;
-- struct jffs2_node_frag *frag;
-- struct jffs2_full_dnode *fn = NULL;
-- struct jffs2_full_dirent *fd;
- struct jffs2_inode_cache *ic;
-- __u32 start = 0, end = 0, nrfrags = 0;
-- struct inode *inode;
-- int ret = 0;
-+ struct jffs2_eraseblock *jeb;
-+ struct jffs2_raw_node_ref *raw;
-+ int ret = 0, inum, nlink;
-
- if (down_interruptible(&c->alloc_sem))
- return -EINTR;
-
-- spin_lock_bh(&c->erase_completion_lock);
-+ for (;;) {
-+ spin_lock(&c->erase_completion_lock);
-+ if (!c->unchecked_size)
-+ break;
-+
-+ /* We can't start doing GC yet. We haven't finished checking
-+ the node CRCs etc. Do it now. */
-+
-+ /* checked_ino is protected by the alloc_sem */
-+ if (c->checked_ino > c->highest_ino) {
-+ printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n",
-+ c->unchecked_size);
-+ D1(jffs2_dump_block_lists(c));
-+ spin_unlock(&c->erase_completion_lock);
-+ BUG();
-+ }
-+
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ spin_lock(&c->inocache_lock);
-+
-+ ic = jffs2_get_ino_cache(c, c->checked_ino++);
-+
-+ if (!ic) {
-+ spin_unlock(&c->inocache_lock);
-+ continue;
-+ }
-+
-+ if (!ic->nlink) {
-+ D1(printk(KERN_DEBUG "Skipping check of ino #%d with nlink zero\n",
-+ ic->ino));
-+ spin_unlock(&c->inocache_lock);
-+ continue;
-+ }
-+ switch(ic->state) {
-+ case INO_STATE_CHECKEDABSENT:
-+ case INO_STATE_PRESENT:
-+ D1(printk(KERN_DEBUG "Skipping ino #%u already checked\n", ic->ino));
-+ spin_unlock(&c->inocache_lock);
-+ continue;
-+
-+ case INO_STATE_GC:
-+ case INO_STATE_CHECKING:
-+ printk(KERN_WARNING "Inode #%u is in state %d during CRC check phase!\n", ic->ino, ic->state);
-+ spin_unlock(&c->inocache_lock);
-+ BUG();
-+
-+ case INO_STATE_READING:
-+ /* We need to wait for it to finish, lest we move on
-+ and trigger the BUG() above while we haven't yet
-+ finished checking all its nodes */
-+ D1(printk(KERN_DEBUG "Waiting for ino #%u to finish reading\n", ic->ino));
-+ up(&c->alloc_sem);
-+ sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
-+ return 0;
-+
-+ default:
-+ BUG();
-+
-+ case INO_STATE_UNCHECKED:
-+ ;
-+ }
-+ ic->state = INO_STATE_CHECKING;
-+ spin_unlock(&c->inocache_lock);
-+
-+ D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() triggering inode scan of ino#%u\n", ic->ino));
-+
-+ ret = jffs2_do_crccheck_inode(c, ic);
-+ if (ret)
-+ printk(KERN_WARNING "Returned error for crccheck of ino #%u. Expect badness...\n", ic->ino);
-+
-+ jffs2_set_inocache_state(c, ic, INO_STATE_CHECKEDABSENT);
-+ up(&c->alloc_sem);
-+ return ret;
-+ }
-
- /* First, work out which block we're garbage-collecting */
- jeb = c->gcblock;
-@@ -127,12 +205,14 @@
-
- if (!jeb) {
- printk(KERN_NOTICE "jffs2: Couldn't find erase block to garbage collect!\n");
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
- up(&c->alloc_sem);
- return -EIO;
- }
-
-- D1(printk(KERN_DEBUG "garbage collect from block at phys 0x%08x\n", jeb->offset));
-+ D1(printk(KERN_DEBUG "GC from block %08x, used_size %08x, dirty_size %08x, free_size %08x\n", jeb->offset, jeb->used_size, jeb->dirty_size, jeb->free_size));
-+ D1(if (c->nextblock)
-+ printk(KERN_DEBUG "Nextblock at %08x, used_size %08x, dirty_size %08x, wasted_size %08x, free_size %08x\n", c->nextblock->offset, c->nextblock->used_size, c->nextblock->dirty_size, c->nextblock->wasted_size, c->nextblock->free_size));
-
- if (!jeb->used_size) {
- up(&c->alloc_sem);
-@@ -141,92 +221,211 @@
-
- raw = jeb->gc_node;
-
-- while(raw->flash_offset & 1) {
-- D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", raw->flash_offset &~3));
-- jeb->gc_node = raw = raw->next_phys;
-- if (!raw) {
-+ while(ref_obsolete(raw)) {
-+ D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", ref_offset(raw)));
-+ raw = raw->next_phys;
-+ if (unlikely(!raw)) {
- printk(KERN_WARNING "eep. End of raw list while still supposedly nodes to GC\n");
- printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n",
- jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size);
-- spin_unlock_bh(&c->erase_completion_lock);
-+ jeb->gc_node = raw;
-+ spin_unlock(&c->erase_completion_lock);
- up(&c->alloc_sem);
- BUG();
- }
- }
-- D1(printk(KERN_DEBUG "Going to garbage collect node at 0x%08x\n", raw->flash_offset &~3));
-+ jeb->gc_node = raw;
-+
-+ D1(printk(KERN_DEBUG "Going to garbage collect node at 0x%08x\n", ref_offset(raw)));
-+
- if (!raw->next_in_ino) {
- /* Inode-less node. Clean marker, snapshot or something like that */
-- spin_unlock_bh(&c->erase_completion_lock);
-+ /* FIXME: If it's something that needs to be copied, including something
-+ we don't grok that has JFFS2_NODETYPE_RWCOMPAT_COPY, we should do so */
-+ spin_unlock(&c->erase_completion_lock);
- jffs2_mark_node_obsolete(c, raw);
- up(&c->alloc_sem);
- goto eraseit_lock;
- }
-
- ic = jffs2_raw_ref_to_ic(raw);
-- D1(printk(KERN_DEBUG "Inode number is #%u\n", ic->ino));
--
-- spin_unlock_bh(&c->erase_completion_lock);
-
-- D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass collecting from block @0x%08x. Node @0x%08x, ino #%u\n", jeb->offset, raw->flash_offset&~3, ic->ino));
-- if (!ic->nlink) {
-- /* The inode has zero nlink but its nodes weren't yet marked
-- obsolete. This has to be because we're still waiting for
-- the final (close() and) iput() to happen.
--
-- There's a possibility that the final iput() could have
-- happened while we were contemplating. In order to ensure
-- that we don't cause a new read_inode() (which would fail)
-- for the inode in question, we use ilookup() in this case
-- instead of iget().
--
-- The nlink can't _become_ zero at this point because we're
-- holding the alloc_sem, and jffs2_do_unlink() would also
-- need that while decrementing nlink on any inode.
-+ /* We need to hold the inocache. Either the erase_completion_lock or
-+ the inocache_lock are sufficient; we trade down since the inocache_lock
-+ causes less contention. */
-+ spin_lock(&c->inocache_lock);
-+
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass collecting from block @0x%08x. Node @0x%08x(%d), ino #%u\n", jeb->offset, ref_offset(raw), ref_flags(raw), ic->ino));
-+
-+ /* Three possibilities:
-+ 1. Inode is already in-core. We must iget it and do proper
-+ updating to its fragtree, etc.
-+ 2. Inode is not in-core, node is REF_PRISTINE. We lock the
-+ inocache to prevent a read_inode(), copy the node intact.
-+ 3. Inode is not in-core, node is not pristine. We must iget()
-+ and take the slow path.
- */
-- inode = ilookup(OFNI_BS_2SFFJ(c), ic->ino);
-- if (!inode) {
-- D1(printk(KERN_DEBUG "ilookup() failed for ino #%u; inode is probably deleted.\n",
-+
-+ switch(ic->state) {
-+ case INO_STATE_CHECKEDABSENT:
-+ /* It's been checked, but it's not currently in-core.
-+ We can just copy any pristine nodes, but have
-+ to prevent anyone else from doing read_inode() while
-+ we're at it, so we set the state accordingly */
-+ if (ref_flags(raw) == REF_PRISTINE)
-+ ic->state = INO_STATE_GC;
-+ else {
-+ D1(printk(KERN_DEBUG "Ino #%u is absent but node not REF_PRISTINE. Reading.\n",
- ic->ino));
-- up(&c->alloc_sem);
-- return 0;
- }
-- } else {
-- /* Inode has links to it still; they're not going away because
-- jffs2_do_unlink() would need the alloc_sem and we have it.
-- Just iget() it, and if read_inode() is necessary that's OK.
-+ break;
-+
-+ case INO_STATE_PRESENT:
-+ /* It's in-core. GC must iget() it. */
-+ break;
-+
-+ case INO_STATE_UNCHECKED:
-+ case INO_STATE_CHECKING:
-+ case INO_STATE_GC:
-+ /* Should never happen. We should have finished checking
-+ by the time we actually start doing any GC, and since
-+ we're holding the alloc_sem, no other garbage collection
-+ can happen.
- */
-- inode = iget(OFNI_BS_2SFFJ(c), ic->ino);
-- if (!inode) {
-+ printk(KERN_CRIT "Inode #%u already in state %d in jffs2_garbage_collect_pass()!\n",
-+ ic->ino, ic->state);
- up(&c->alloc_sem);
-- return -ENOMEM;
-+ spin_unlock(&c->inocache_lock);
-+ BUG();
-+
-+ case INO_STATE_READING:
-+ /* Someone's currently trying to read it. We must wait for
-+ them to finish and then go through the full iget() route
-+ to do the GC. However, sometimes read_inode() needs to get
-+ the alloc_sem() (for marking nodes invalid) so we must
-+ drop the alloc_sem before sleeping. */
-+
-+ up(&c->alloc_sem);
-+ D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() waiting for ino #%u in state %d\n",
-+ ic->ino, ic->state));
-+ sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
-+ /* And because we dropped the alloc_sem we must start again from the
-+ beginning. Ponder chance of livelock here -- we're returning success
-+ without actually making any progress.
-+
-+ Q: What are the chances that the inode is back in INO_STATE_READING
-+ again by the time we next enter this function? And that this happens
-+ enough times to cause a real delay?
-+
-+ A: Small enough that I don't care :)
-+ */
-+ return 0;
- }
-+
-+ /* OK. Now if the inode is in state INO_STATE_GC, we are going to copy the
-+ node intact, and we don't have to muck about with the fragtree etc.
-+ because we know it's not in-core. If it _was_ in-core, we go through
-+ all the iget() crap anyway */
-+
-+ if (ic->state == INO_STATE_GC) {
-+ spin_unlock(&c->inocache_lock);
-+
-+ ret = jffs2_garbage_collect_pristine(c, ic, raw);
-+
-+ spin_lock(&c->inocache_lock);
-+ ic->state = INO_STATE_CHECKEDABSENT;
-+ wake_up(&c->inocache_wq);
-+
-+ if (ret != -EBADFD) {
-+ spin_unlock(&c->inocache_lock);
-+ goto release_sem;
- }
-- if (is_bad_inode(inode)) {
-- printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u\n", ic->ino);
-- /* NB. This will happen again. We need to do something appropriate here. */
-+
-+ /* Fall through if it wanted us to, with inocache_lock held */
-+ }
-+
-+ /* Prevent the fairly unlikely race where the gcblock is
-+ entirely obsoleted by the final close of a file which had
-+ the only valid nodes in the block, followed by erasure,
-+ followed by freeing of the ic because the erased block(s)
-+ held _all_ the nodes of that inode.... never been seen but
-+ it's vaguely possible. */
-+
-+ inum = ic->ino;
-+ nlink = ic->nlink;
-+ spin_unlock(&c->inocache_lock);
-+
-+ f = jffs2_gc_fetch_inode(c, inum, nlink);
-+ if (IS_ERR(f))
-+ return PTR_ERR(f);
-+ if (!f)
-+ return 0;
-+
-+ ret = jffs2_garbage_collect_live(c, jeb, raw, f);
-+
-+ jffs2_gc_release_inode(c, f);
-+
-+ release_sem:
- up(&c->alloc_sem);
-- iput(inode);
-- return -EIO;
-+
-+ eraseit_lock:
-+ /* If we've finished this block, start it erasing */
-+ spin_lock(&c->erase_completion_lock);
-+
-+ eraseit:
-+ if (c->gcblock && !c->gcblock->used_size) {
-+ D1(printk(KERN_DEBUG "Block at 0x%08x completely obsoleted by GC. Moving to erase_pending_list\n", c->gcblock->offset));
-+ /* We're GC'ing an empty block? */
-+ list_add_tail(&c->gcblock->list, &c->erase_pending_list);
-+ c->gcblock = NULL;
-+ c->nr_erasing_blocks++;
-+ jffs2_erase_pending_trigger(c);
- }
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ return ret;
-+}
-+
-+static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-+ struct jffs2_raw_node_ref *raw, struct jffs2_inode_info *f)
-+{
-+ struct jffs2_node_frag *frag;
-+ struct jffs2_full_dnode *fn = NULL;
-+ struct jffs2_full_dirent *fd;
-+ uint32_t start = 0, end = 0, nrfrags = 0;
-+ int ret = 0;
-
-- f = JFFS2_INODE_INFO(inode);
- down(&f->sem);
-+
- /* Now we have the lock for this inode. Check that it's still the one at the head
- of the list. */
-
-- if (raw->flash_offset & 1) {
-+ spin_lock(&c->erase_completion_lock);
-+
-+ if (c->gcblock != jeb) {
-+ spin_unlock(&c->erase_completion_lock);
-+ D1(printk(KERN_DEBUG "GC block is no longer gcblock. Restart\n"));
-+ goto upnout;
-+ }
-+ if (ref_obsolete(raw)) {
-+ spin_unlock(&c->erase_completion_lock);
- D1(printk(KERN_DEBUG "node to be GC'd was obsoleted in the meantime.\n"));
- /* They'll call again */
- goto upnout;
- }
-+ spin_unlock(&c->erase_completion_lock);
-+
- /* OK. Looks safe. And nobody can get us now because we have the semaphore. Move the block */
- if (f->metadata && f->metadata->raw == raw) {
- fn = f->metadata;
-- ret = jffs2_garbage_collect_metadata(c, jeb, inode, fn);
-+ ret = jffs2_garbage_collect_metadata(c, jeb, f, fn);
- goto upnout;
- }
-
-- for (frag = f->fraglist; frag; frag = frag->next) {
-+ /* FIXME. Read node and do lookup? */
-+ for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
- if (frag->node && frag->node->raw == raw) {
- fn = frag->node;
- end = frag->ofs + frag->size;
-@@ -237,13 +436,22 @@
- }
- }
- if (fn) {
-+ if (ref_flags(raw) == REF_PRISTINE) {
-+ ret = jffs2_garbage_collect_pristine(c, f->inocache, raw);
-+ if (!ret) {
-+ /* Urgh. Return it sensibly. */
-+ frag->node->raw = f->inocache->nodes;
-+ }
-+ if (ret != -EBADFD)
-+ goto upnout;
-+ }
- /* We found a datanode. Do the GC */
- if((start >> PAGE_CACHE_SHIFT) < ((end-1) >> PAGE_CACHE_SHIFT)) {
- /* It crosses a page boundary. Therefore, it must be a hole. */
-- ret = jffs2_garbage_collect_hole(c, jeb, inode, fn, start, end);
-+ ret = jffs2_garbage_collect_hole(c, jeb, f, fn, start, end);
- } else {
- /* It could still be a hole. But we GC the page this way anyway */
-- ret = jffs2_garbage_collect_dnode(c, jeb, inode, fn, start, end);
-+ ret = jffs2_garbage_collect_dnode(c, jeb, f, fn, start, end);
- }
- goto upnout;
- }
-@@ -255,12 +463,13 @@
- }
-
- if (fd && fd->ino) {
-- ret = jffs2_garbage_collect_dirent(c, jeb, inode, fd);
-+ ret = jffs2_garbage_collect_dirent(c, jeb, f, fd);
- } else if (fd) {
-- ret = jffs2_garbage_collect_deletion_dirent(c, jeb, inode, fd);
-+ ret = jffs2_garbage_collect_deletion_dirent(c, jeb, f, fd);
- } else {
-- printk(KERN_WARNING "Raw node at 0x%08x wasn't in node lists for ino #%lu\n", raw->flash_offset&~3, inode->i_ino);
-- if (raw->flash_offset & 1) {
-+ printk(KERN_WARNING "Raw node at 0x%08x wasn't in node lists for ino #%u\n",
-+ ref_offset(raw), f->inocache->ino);
-+ if (ref_obsolete(raw)) {
- printk(KERN_WARNING "But it's obsolete so we don't mind too much\n");
- } else {
- ret = -EIO;
-@@ -268,46 +477,197 @@
- }
- upnout:
- up(&f->sem);
-- up(&c->alloc_sem);
-- iput(inode);
-
-- eraseit_lock:
-- /* If we've finished this block, start it erasing */
-- spin_lock_bh(&c->erase_completion_lock);
-+ return ret;
-+}
-
-- eraseit:
-- if (c->gcblock && !c->gcblock->used_size) {
-- D1(printk(KERN_DEBUG "Block at 0x%08x completely obsoleted by GC. Moving to erase_pending_list\n", c->gcblock->offset));
-- /* We're GC'ing an empty block? */
-- list_add_tail(&c->gcblock->list, &c->erase_pending_list);
-- c->gcblock = NULL;
-- c->nr_erasing_blocks++;
-- jffs2_erase_pending_trigger(c);
-+static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
-+ struct jffs2_inode_cache *ic,
-+ struct jffs2_raw_node_ref *raw)
-+{
-+ union jffs2_node_union *node;
-+ struct jffs2_raw_node_ref *nraw;
-+ size_t retlen;
-+ int ret;
-+ uint32_t phys_ofs, alloclen;
-+ uint32_t crc, rawlen;
-+ int retried = 0;
-+
-+ D1(printk(KERN_DEBUG "Going to GC REF_PRISTINE node at 0x%08x\n", ref_offset(raw)));
-+
-+ rawlen = ref_totlen(c, c->gcblock, raw);
-+
-+ /* Ask for a small amount of space (or the totlen if smaller) because we
-+ don't want to force wastage of the end of a block if splitting would
-+ work. */
-+ ret = jffs2_reserve_space_gc(c, min_t(uint32_t, sizeof(struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN,
-+ rawlen), &phys_ofs, &alloclen);
-+ if (ret)
-+ return ret;
-+
-+ if (alloclen < rawlen) {
-+ /* Doesn't fit untouched. We'll go the old route and split it */
-+ return -EBADFD;
-+ }
-+
-+ node = kmalloc(rawlen, GFP_KERNEL);
-+ if (!node)
-+ return -ENOMEM;
-+
-+ ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (char *)node);
-+ if (!ret && retlen != rawlen)
-+ ret = -EIO;
-+ if (ret)
-+ goto out_node;
-+
-+ crc = crc32(0, node, sizeof(struct jffs2_unknown_node)-4);
-+ if (je32_to_cpu(node->u.hdr_crc) != crc) {
-+ printk(KERN_WARNING "Header CRC failed on REF_PRISTINE node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-+ ref_offset(raw), je32_to_cpu(node->u.hdr_crc), crc);
-+ goto bail;
-+ }
-+
-+ switch(je16_to_cpu(node->u.nodetype)) {
-+ case JFFS2_NODETYPE_INODE:
-+ crc = crc32(0, node, sizeof(node->i)-8);
-+ if (je32_to_cpu(node->i.node_crc) != crc) {
-+ printk(KERN_WARNING "Node CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-+ ref_offset(raw), je32_to_cpu(node->i.node_crc), crc);
-+ goto bail;
-+ }
-+
-+ if (je32_to_cpu(node->i.dsize)) {
-+ crc = crc32(0, node->i.data, je32_to_cpu(node->i.csize));
-+ if (je32_to_cpu(node->i.data_crc) != crc) {
-+ printk(KERN_WARNING "Data CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-+ ref_offset(raw), je32_to_cpu(node->i.data_crc), crc);
-+ goto bail;
- }
-- spin_unlock_bh(&c->erase_completion_lock);
-+ }
-+ break;
-+
-+ case JFFS2_NODETYPE_DIRENT:
-+ crc = crc32(0, node, sizeof(node->d)-8);
-+ if (je32_to_cpu(node->d.node_crc) != crc) {
-+ printk(KERN_WARNING "Node CRC failed on REF_PRISTINE dirent node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-+ ref_offset(raw), je32_to_cpu(node->d.node_crc), crc);
-+ goto bail;
-+ }
-+
-+ if (node->d.nsize) {
-+ crc = crc32(0, node->d.name, node->d.nsize);
-+ if (je32_to_cpu(node->d.name_crc) != crc) {
-+ printk(KERN_WARNING "Name CRC failed on REF_PRISTINE dirent ode at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-+ ref_offset(raw), je32_to_cpu(node->d.name_crc), crc);
-+ goto bail;
-+ }
-+ }
-+ break;
-+ default:
-+ printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n",
-+ ref_offset(raw), je16_to_cpu(node->u.nodetype));
-+ goto bail;
-+ }
-+
-+ nraw = jffs2_alloc_raw_node_ref();
-+ if (!nraw) {
-+ ret = -ENOMEM;
-+ goto out_node;
-+ }
-+
-+ /* OK, all the CRCs are good; this node can just be copied as-is. */
-+ retry:
-+ nraw->flash_offset = phys_ofs;
-+ nraw->__totlen = rawlen;
-+ nraw->next_phys = NULL;
-+
-+ ret = jffs2_flash_write(c, phys_ofs, rawlen, &retlen, (char *)node);
-+
-+ if (ret || (retlen != rawlen)) {
-+ printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n",
-+ rawlen, phys_ofs, ret, retlen);
-+ if (retlen) {
-+ /* Doesn't belong to any inode */
-+ nraw->next_in_ino = NULL;
-+
-+ nraw->flash_offset |= REF_OBSOLETE;
-+ jffs2_add_physical_node_ref(c, nraw);
-+ jffs2_mark_node_obsolete(c, nraw);
-+ } else {
-+ printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", nraw->flash_offset);
-+ jffs2_free_raw_node_ref(nraw);
-+ }
-+ if (!retried && (nraw == jffs2_alloc_raw_node_ref())) {
-+ /* Try to reallocate space and retry */
-+ uint32_t dummy;
-+ struct jffs2_eraseblock *jeb = &c->blocks[phys_ofs / c->sector_size];
-+
-+ retried = 1;
-+
-+ D1(printk(KERN_DEBUG "Retrying failed write of REF_PRISTINE node.\n"));
-+
-+ ACCT_SANITY_CHECK(c,jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+
-+ ret = jffs2_reserve_space_gc(c, rawlen, &phys_ofs, &dummy);
-+
-+ if (!ret) {
-+ D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", phys_ofs));
-
-+ ACCT_SANITY_CHECK(c,jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+
-+ goto retry;
-+ }
-+ D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
-+ jffs2_free_raw_node_ref(nraw);
-+ }
-+
-+ if (!ret)
-+ ret = -EIO;
-+ goto out_node;
-+ }
-+ nraw->flash_offset |= REF_PRISTINE;
-+ jffs2_add_physical_node_ref(c, nraw);
-+
-+ /* Link into per-inode list. This is safe because of the ic
-+ state being INO_STATE_GC. Note that if we're doing this
-+ for an inode which is in-code, the 'nraw' pointer is then
-+ going to be fetched from ic->nodes by our caller. */
-+ nraw->next_in_ino = ic->nodes;
-+ ic->nodes = nraw;
-+
-+ jffs2_mark_node_obsolete(c, raw);
-+ D1(printk(KERN_DEBUG "WHEEE! GC REF_PRISTINE node at 0x%08x succeeded\n", ref_offset(raw)));
-+
-+ out_node:
-+ kfree(node);
- return ret;
-+ bail:
-+ ret = -EBADFD;
-+ goto out_node;
- }
-
- static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dnode *fn)
-+ struct jffs2_inode_info *f, struct jffs2_full_dnode *fn)
- {
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_full_dnode *new_fn;
- struct jffs2_raw_inode ri;
-- unsigned short dev;
-+ jint16_t dev;
- char *mdata = NULL, mdatalen = 0;
-- __u32 alloclen, phys_ofs;
-+ uint32_t alloclen, phys_ofs;
- int ret;
-
-- if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
-+ if (S_ISBLK(JFFS2_F_I_MODE(f)) ||
-+ S_ISCHR(JFFS2_F_I_MODE(f)) ) {
- /* For these, we don't actually need to read the old node */
-- dev = (MAJOR(to_kdev_t(inode->i_rdev)) << 8) |
-- MINOR(to_kdev_t(inode->i_rdev));
-+ /* FIXME: for minor or major > 255. */
-+ dev = cpu_to_je16(((JFFS2_F_I_RDEV_MAJ(f) << 8) |
-+ JFFS2_F_I_RDEV_MIN(f)));
- mdata = (char *)&dev;
- mdatalen = sizeof(dev);
- D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bytes of kdev_t\n", mdatalen));
-- } else if (S_ISLNK(inode->i_mode)) {
-+ } else if (S_ISLNK(JFFS2_F_I_MODE(f))) {
- mdatalen = fn->size;
- mdata = kmalloc(fn->size, GFP_KERNEL);
- if (!mdata) {
-@@ -326,34 +686,34 @@
-
- ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen);
- if (ret) {
-- printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_metadata failed: %d\n",
-+ printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_metadata failed: %d\n",
- sizeof(ri)+ mdatalen, ret);
- goto out;
- }
-
- memset(&ri, 0, sizeof(ri));
-- ri.magic = JFFS2_MAGIC_BITMASK;
-- ri.nodetype = JFFS2_NODETYPE_INODE;
-- ri.totlen = sizeof(ri) + mdatalen;
-- ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4);
--
-- ri.ino = inode->i_ino;
-- ri.version = ++f->highest_version;
-- ri.mode = inode->i_mode;
-- ri.uid = inode->i_uid;
-- ri.gid = inode->i_gid;
-- ri.isize = inode->i_size;
-- ri.atime = inode->i_atime;
-- ri.ctime = inode->i_ctime;
-- ri.mtime = inode->i_mtime;
-- ri.offset = 0;
-- ri.csize = mdatalen;
-- ri.dsize = mdatalen;
-+ ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
-+ ri.totlen = cpu_to_je32(sizeof(ri) + mdatalen);
-+ ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4));
-+
-+ ri.ino = cpu_to_je32(f->inocache->ino);
-+ ri.version = cpu_to_je32(++f->highest_version);
-+ ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
-+ ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
-+ ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
-+ ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f));
-+ ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
-+ ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
-+ ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f));
-+ ri.offset = cpu_to_je32(0);
-+ ri.csize = cpu_to_je32(mdatalen);
-+ ri.dsize = cpu_to_je32(mdatalen);
- ri.compr = JFFS2_COMPR_NONE;
-- ri.node_crc = crc32(0, &ri, sizeof(ri)-8);
-- ri.data_crc = crc32(0, mdata, mdatalen);
-+ ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
-+ ri.data_crc = cpu_to_je32(crc32(0, mdata, mdatalen));
-
-- new_fn = jffs2_write_dnode(inode, &ri, mdata, mdatalen, phys_ofs, NULL);
-+ new_fn = jffs2_write_dnode(c, f, &ri, mdata, mdatalen, phys_ofs, ALLOC_GC);
-
- if (IS_ERR(new_fn)) {
- printk(KERN_WARNING "Error writing new dnode: %ld\n", PTR_ERR(new_fn));
-@@ -364,41 +724,40 @@
- jffs2_free_full_dnode(fn);
- f->metadata = new_fn;
- out:
-- if (S_ISLNK(inode->i_mode))
-+ if (S_ISLNK(JFFS2_F_I_MODE(f)))
- kfree(mdata);
- return ret;
- }
-
- static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dirent *fd)
-+ struct jffs2_inode_info *f, struct jffs2_full_dirent *fd)
- {
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_full_dirent *new_fd;
- struct jffs2_raw_dirent rd;
-- __u32 alloclen, phys_ofs;
-+ uint32_t alloclen, phys_ofs;
- int ret;
-
-- rd.magic = JFFS2_MAGIC_BITMASK;
-- rd.nodetype = JFFS2_NODETYPE_DIRENT;
-+ rd.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ rd.nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
- rd.nsize = strlen(fd->name);
-- rd.totlen = sizeof(rd) + rd.nsize;
-- rd.hdr_crc = crc32(0, &rd, sizeof(struct jffs2_unknown_node)-4);
-+ rd.totlen = cpu_to_je32(sizeof(rd) + rd.nsize);
-+ rd.hdr_crc = cpu_to_je32(crc32(0, &rd, sizeof(struct jffs2_unknown_node)-4));
-
-- rd.pino = inode->i_ino;
-- rd.version = ++f->highest_version;
-- rd.ino = fd->ino;
-- rd.mctime = max(inode->i_mtime, inode->i_ctime);
-+ rd.pino = cpu_to_je32(f->inocache->ino);
-+ rd.version = cpu_to_je32(++f->highest_version);
-+ rd.ino = cpu_to_je32(fd->ino);
-+ rd.mctime = cpu_to_je32(max(JFFS2_F_I_MTIME(f), JFFS2_F_I_CTIME(f)));
- rd.type = fd->type;
-- rd.node_crc = crc32(0, &rd, sizeof(rd)-8);
-- rd.name_crc = crc32(0, fd->name, rd.nsize);
-+ rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8));
-+ rd.name_crc = cpu_to_je32(crc32(0, fd->name, rd.nsize));
-
- ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &phys_ofs, &alloclen);
- if (ret) {
-- printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_dirent failed: %d\n",
-+ printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dirent failed: %d\n",
- sizeof(rd)+rd.nsize, ret);
- return ret;
- }
-- new_fd = jffs2_write_dirent(inode, &rd, fd->name, rd.nsize, phys_ofs, NULL);
-+ new_fd = jffs2_write_dirent(c, f, &rd, fd->name, rd.nsize, phys_ofs, ALLOC_GC);
-
- if (IS_ERR(new_fd)) {
- printk(KERN_WARNING "jffs2_write_dirent in garbage_collect_dirent failed: %ld\n", PTR_ERR(new_fd));
-@@ -409,19 +768,98 @@
- }
-
- static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dirent *fd)
-+ struct jffs2_inode_info *f, struct jffs2_full_dirent *fd)
- {
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_full_dirent **fdp = &f->dents;
- int found = 0;
-
-- /* FIXME: When we run on NAND flash, we need to work out whether
-- this deletion dirent is still needed to actively delete a
-- 'real' dirent with the same name that's still somewhere else
-- on the flash. For now, we know that we've actually obliterated
-- all the older dirents when they became obsolete, so we didn't
-- really need to write the deletion to flash in the first place.
-- */
-+ /* On a medium where we can't actually mark nodes obsolete
-+ pernamently, such as NAND flash, we need to work out
-+ whether this deletion dirent is still needed to actively
-+ delete a 'real' dirent with the same name that's still
-+ somewhere else on the flash. */
-+ if (!jffs2_can_mark_obsolete(c)) {
-+ struct jffs2_raw_dirent *rd;
-+ struct jffs2_raw_node_ref *raw;
-+ int ret;
-+ size_t retlen;
-+ int name_len = strlen(fd->name);
-+ uint32_t name_crc = crc32(0, fd->name, name_len);
-+ uint32_t rawlen = ref_totlen(c, jeb, fd->raw);
-+
-+ rd = kmalloc(rawlen, GFP_KERNEL);
-+ if (!rd)
-+ return -ENOMEM;
-+
-+ /* Prevent the erase code from nicking the obsolete node refs while
-+ we're looking at them. I really don't like this extra lock but
-+ can't see any alternative. Suggestions on a postcard to... */
-+ down(&c->erase_free_sem);
-+
-+ for (raw = f->inocache->nodes; raw != (void *)f->inocache; raw = raw->next_in_ino) {
-+
-+ /* We only care about obsolete ones */
-+ if (!(ref_obsolete(raw)))
-+ continue;
-+
-+ /* Any dirent with the same name is going to have the same length... */
-+ if (ref_totlen(c, NULL, raw) != rawlen)
-+ continue;
-+
-+ /* Doesn't matter if there's one in the same erase block. We're going to
-+ delete it too at the same time. */
-+ if ((raw->flash_offset & ~(c->sector_size-1)) ==
-+ (fd->raw->flash_offset & ~(c->sector_size-1)))
-+ continue;
-+
-+ D1(printk(KERN_DEBUG "Check potential deletion dirent at %08x\n", ref_offset(raw)));
-+
-+ /* This is an obsolete node belonging to the same directory, and it's of the right
-+ length. We need to take a closer look...*/
-+ ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (char *)rd);
-+ if (ret) {
-+ printk(KERN_WARNING "jffs2_g_c_deletion_dirent(): Read error (%d) reading obsolete node at %08x\n", ret, ref_offset(raw));
-+ /* If we can't read it, we don't need to continue to obsolete it. Continue */
-+ continue;
-+ }
-+ if (retlen != rawlen) {
-+ printk(KERN_WARNING "jffs2_g_c_deletion_dirent(): Short read (%zd not %zd) reading header from obsolete node at %08x\n",
-+ retlen, rawlen, ref_offset(raw));
-+ continue;
-+ }
-+
-+ if (je16_to_cpu(rd->nodetype) != JFFS2_NODETYPE_DIRENT)
-+ continue;
-+
-+ /* If the name CRC doesn't match, skip */
-+ if (je32_to_cpu(rd->name_crc) != name_crc)
-+ continue;
-+
-+ /* If the name length doesn't match, or it's another deletion dirent, skip */
-+ if (rd->nsize != name_len || !je32_to_cpu(rd->ino))
-+ continue;
-+
-+ /* OK, check the actual name now */
-+ if (memcmp(rd->name, fd->name, name_len))
-+ continue;
-+
-+ /* OK. The name really does match. There really is still an older node on
-+ the flash which our deletion dirent obsoletes. So we have to write out
-+ a new deletion dirent to replace it */
-+ up(&c->erase_free_sem);
-+
-+ D1(printk(KERN_DEBUG "Deletion dirent at %08x still obsoletes real dirent \"%s\" at %08x for ino #%u\n",
-+ ref_offset(fd->raw), fd->name, ref_offset(raw), je32_to_cpu(rd->ino)));
-+ kfree(rd);
-+
-+ return jffs2_garbage_collect_dirent(c, jeb, f, fd);
-+ }
-+
-+ up(&c->erase_free_sem);
-+ kfree(rd);
-+ }
-+
-+ /* No need for it any more. Just mark it obsolete and remove it from the list */
- while (*fdp) {
- if ((*fdp) == fd) {
- found = 1;
-@@ -431,7 +869,7 @@
- fdp = &(*fdp)->next;
- }
- if (!found) {
-- printk(KERN_WARNING "Deletion dirent \"%s\" not found in list for ino #%lu\n", fd->name, inode->i_ino);
-+ printk(KERN_WARNING "Deletion dirent \"%s\" not found in list for ino #%u\n", fd->name, f->inocache->ino);
- }
- jffs2_mark_node_obsolete(c, fd->raw);
- jffs2_free_full_dirent(fd);
-@@ -439,93 +877,95 @@
- }
-
- static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dnode *fn,
-- __u32 start, __u32 end)
-+ struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
-+ uint32_t start, uint32_t end)
- {
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_raw_inode ri;
- struct jffs2_node_frag *frag;
- struct jffs2_full_dnode *new_fn;
-- __u32 alloclen, phys_ofs;
-+ uint32_t alloclen, phys_ofs;
- int ret;
-
-- D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%lu from offset 0x%x to 0x%x\n",
-- inode->i_ino, start, end));
-+ D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n",
-+ f->inocache->ino, start, end));
-
- memset(&ri, 0, sizeof(ri));
-
- if(fn->frags > 1) {
- size_t readlen;
-- __u32 crc;
-+ uint32_t crc;
- /* It's partially obsoleted by a later write. So we have to
- write it out again with the _same_ version as before */
-- ret = c->mtd->read(c->mtd, fn->raw->flash_offset & ~3, sizeof(ri), &readlen, (char *)&ri);
-+ ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(ri), &readlen, (char *)&ri);
- if (readlen != sizeof(ri) || ret) {
-- printk(KERN_WARNING "Node read failed in jffs2_garbage_collect_hole. Ret %d, retlen %d. Data will be lost by writing new hold node\n", ret, readlen);
-+ printk(KERN_WARNING "Node read failed in jffs2_garbage_collect_hole. Ret %d, retlen %zd. Data will be lost by writing new hole node\n", ret, readlen);
- goto fill;
- }
-- if (ri.nodetype != JFFS2_NODETYPE_INODE) {
-+ if (je16_to_cpu(ri.nodetype) != JFFS2_NODETYPE_INODE) {
- printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had node type 0x%04x instead of JFFS2_NODETYPE_INODE(0x%04x)\n",
-- fn->raw->flash_offset & ~3, ri.nodetype, JFFS2_NODETYPE_INODE);
-+ ref_offset(fn->raw),
-+ je16_to_cpu(ri.nodetype), JFFS2_NODETYPE_INODE);
- return -EIO;
- }
-- if (ri.totlen != sizeof(ri)) {
-- printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had totlen 0x%x instead of expected 0x%x\n",
-- fn->raw->flash_offset & ~3, ri.totlen, sizeof(ri));
-+ if (je32_to_cpu(ri.totlen) != sizeof(ri)) {
-+ printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had totlen 0x%x instead of expected 0x%zx\n",
-+ ref_offset(fn->raw),
-+ je32_to_cpu(ri.totlen), sizeof(ri));
- return -EIO;
- }
- crc = crc32(0, &ri, sizeof(ri)-8);
-- if (crc != ri.node_crc) {
-+ if (crc != je32_to_cpu(ri.node_crc)) {
- printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had CRC 0x%08x which doesn't match calculated CRC 0x%08x\n",
-- fn->raw->flash_offset & ~3, ri.node_crc, crc);
-+ ref_offset(fn->raw),
-+ je32_to_cpu(ri.node_crc), crc);
- /* FIXME: We could possibly deal with this by writing new holes for each frag */
-- printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%lu will be lost\n",
-- start, end, inode->i_ino);
-+ printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n",
-+ start, end, f->inocache->ino);
- goto fill;
- }
- if (ri.compr != JFFS2_COMPR_ZERO) {
-- printk(KERN_WARNING "jffs2_garbage_collect_hole: Node 0x%08x wasn't a hole node!\n", fn->raw->flash_offset & ~3);
-- printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%lu will be lost\n",
-- start, end, inode->i_ino);
-+ printk(KERN_WARNING "jffs2_garbage_collect_hole: Node 0x%08x wasn't a hole node!\n", ref_offset(fn->raw));
-+ printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n",
-+ start, end, f->inocache->ino);
- goto fill;
- }
- } else {
- fill:
-- ri.magic = JFFS2_MAGIC_BITMASK;
-- ri.nodetype = JFFS2_NODETYPE_INODE;
-- ri.totlen = sizeof(ri);
-- ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4);
--
-- ri.ino = inode->i_ino;
-- ri.version = ++f->highest_version;
-- ri.offset = start;
-- ri.dsize = end - start;
-- ri.csize = 0;
-+ ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
-+ ri.totlen = cpu_to_je32(sizeof(ri));
-+ ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4));
-+
-+ ri.ino = cpu_to_je32(f->inocache->ino);
-+ ri.version = cpu_to_je32(++f->highest_version);
-+ ri.offset = cpu_to_je32(start);
-+ ri.dsize = cpu_to_je32(end - start);
-+ ri.csize = cpu_to_je32(0);
- ri.compr = JFFS2_COMPR_ZERO;
- }
-- ri.mode = inode->i_mode;
-- ri.uid = inode->i_uid;
-- ri.gid = inode->i_gid;
-- ri.isize = inode->i_size;
-- ri.atime = inode->i_atime;
-- ri.ctime = inode->i_ctime;
-- ri.mtime = inode->i_mtime;
-- ri.data_crc = 0;
-- ri.node_crc = crc32(0, &ri, sizeof(ri)-8);
-+ ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
-+ ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
-+ ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
-+ ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f));
-+ ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
-+ ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
-+ ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f));
-+ ri.data_crc = cpu_to_je32(0);
-+ ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
-
- ret = jffs2_reserve_space_gc(c, sizeof(ri), &phys_ofs, &alloclen);
- if (ret) {
-- printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_hole failed: %d\n",
-+ printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_hole failed: %d\n",
- sizeof(ri), ret);
- return ret;
- }
-- new_fn = jffs2_write_dnode(inode, &ri, NULL, 0, phys_ofs, NULL);
-+ new_fn = jffs2_write_dnode(c, f, &ri, NULL, 0, phys_ofs, ALLOC_GC);
-
- if (IS_ERR(new_fn)) {
- printk(KERN_WARNING "Error writing new hole node: %ld\n", PTR_ERR(new_fn));
- return PTR_ERR(new_fn);
- }
-- if (ri.version == f->highest_version) {
-+ if (je32_to_cpu(ri.version) == f->highest_version) {
- jffs2_add_full_dnode_to_inode(c, f, new_fn);
- if (f->metadata) {
- jffs2_mark_node_obsolete(c, f->metadata->raw);
-@@ -541,12 +981,17 @@
- * number as before. (Except in case of error -- see 'goto fill;'
- * above.)
- */
-- D1(if(fn->frags <= 1) {
-+ D1(if(unlikely(fn->frags <= 1)) {
- printk(KERN_WARNING "jffs2_garbage_collect_hole: Replacing fn with %d frag(s) but new ver %d != highest_version %d of ino #%d\n",
-- fn->frags, ri.version, f->highest_version, ri.ino);
-+ fn->frags, je32_to_cpu(ri.version), f->highest_version,
-+ je32_to_cpu(ri.ino));
- });
-
-- for (frag = f->fraglist; frag; frag = frag->next) {
-+ /* This is a partially-overlapped hole node. Mark it REF_NORMAL not REF_PRISTINE */
-+ mark_ref_normal(new_fn->raw);
-+
-+ for (frag = jffs2_lookup_node_frag(&f->fragtree, fn->ofs);
-+ frag; frag = frag_next(frag)) {
- if (frag->ofs > fn->size + fn->ofs)
- break;
- if (frag->node == fn) {
-@@ -571,49 +1016,146 @@
- }
-
- static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dnode *fn,
-- __u32 start, __u32 end)
-+ struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
-+ uint32_t start, uint32_t end)
- {
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_full_dnode *new_fn;
- struct jffs2_raw_inode ri;
-- __u32 alloclen, phys_ofs, offset, orig_end;
-+ uint32_t alloclen, phys_ofs, offset, orig_end, orig_start;
- int ret = 0;
- unsigned char *comprbuf = NULL, *writebuf;
-- struct page *pg;
-+ unsigned long pg;
- unsigned char *pg_ptr;
-
--
- memset(&ri, 0, sizeof(ri));
-
-- D1(printk(KERN_DEBUG "Writing replacement dnode for ino #%lu from offset 0x%x to 0x%x\n",
-- inode->i_ino, start, end));
-+ D1(printk(KERN_DEBUG "Writing replacement dnode for ino #%u from offset 0x%x to 0x%x\n",
-+ f->inocache->ino, start, end));
-
- orig_end = end;
-+ orig_start = start;
-
-+ if (c->nr_free_blocks + c->nr_erasing_blocks > c->resv_blocks_gcmerge) {
-+ /* Attempt to do some merging. But only expand to cover logically
-+ adjacent frags if the block containing them is already considered
-+ to be dirty. Otherwise we end up with GC just going round in
-+ circles dirtying the nodes it already wrote out, especially
-+ on NAND where we have small eraseblocks and hence a much higher
-+ chance of nodes having to be split to cross boundaries. */
-
-- /* If we're looking at the last node in the block we're
-- garbage-collecting, we allow ourselves to merge as if the
-- block was already erasing. We're likely to be GC'ing a
-- partial page, and the next block we GC is likely to have
-- the other half of this page right at the beginning, which
-- means we'd expand it _then_, as nr_erasing_blocks would have
-- increased since we checked, and in doing so would obsolete
-- the partial node which we'd have written here. Meaning that
-- the GC would churn and churn, and just leave dirty blocks in
-- it's wake.
-- */
-- if(c->nr_free_blocks + c->nr_erasing_blocks > JFFS2_RESERVED_BLOCKS_GCMERGE - (fn->raw->next_phys?0:1)) {
-- /* Shitloads of space */
-- /* FIXME: Integrate this properly with GC calculations */
-- start &= ~(PAGE_CACHE_SIZE-1);
-- end = min_t(__u32, start + PAGE_CACHE_SIZE, inode->i_size);
-- D1(printk(KERN_DEBUG "Plenty of free space, so expanding to write from offset 0x%x to 0x%x\n",
-- start, end));
-- if (end < orig_end) {
-- printk(KERN_WARNING "Eep. jffs2_garbage_collect_dnode extended node to write, but it got smaller: start 0x%x, orig_end 0x%x, end 0x%x\n", start, orig_end, end);
-- end = orig_end;
-+ struct jffs2_node_frag *frag;
-+ uint32_t min, max;
-+
-+ min = start & ~(PAGE_CACHE_SIZE-1);
-+ max = min + PAGE_CACHE_SIZE;
-+
-+ frag = jffs2_lookup_node_frag(&f->fragtree, start);
-+
-+ /* BUG_ON(!frag) but that'll happen anyway... */
-+
-+ BUG_ON(frag->ofs != start);
-+
-+ /* First grow down... */
-+ while((frag = frag_prev(frag)) && frag->ofs >= min) {
-+
-+ /* If the previous frag doesn't even reach the beginning, there's
-+ excessive fragmentation. Just merge. */
-+ if (frag->ofs > min) {
-+ D1(printk(KERN_DEBUG "Expanding down to cover partial frag (0x%x-0x%x)\n",
-+ frag->ofs, frag->ofs+frag->size));
-+ start = frag->ofs;
-+ continue;
-+ }
-+ /* OK. This frag holds the first byte of the page. */
-+ if (!frag->node || !frag->node->raw) {
-+ D1(printk(KERN_DEBUG "First frag in page is hole (0x%x-0x%x). Not expanding down.\n",
-+ frag->ofs, frag->ofs+frag->size));
-+ break;
-+ } else {
-+
-+ /* OK, it's a frag which extends to the beginning of the page. Does it live
-+ in a block which is still considered clean? If so, don't obsolete it.
-+ If not, cover it anyway. */
-+
-+ struct jffs2_raw_node_ref *raw = frag->node->raw;
-+ struct jffs2_eraseblock *jeb;
-+
-+ jeb = &c->blocks[raw->flash_offset / c->sector_size];
-+
-+ if (jeb == c->gcblock) {
-+ D1(printk(KERN_DEBUG "Expanding down to cover frag (0x%x-0x%x) in gcblock at %08x\n",
-+ frag->ofs, frag->ofs+frag->size, ref_offset(raw)));
-+ start = frag->ofs;
-+ break;
- }
-+ if (!ISDIRTY(jeb->dirty_size + jeb->wasted_size)) {
-+ D1(printk(KERN_DEBUG "Not expanding down to cover frag (0x%x-0x%x) in clean block %08x\n",
-+ frag->ofs, frag->ofs+frag->size, jeb->offset));
-+ break;
-+ }
-+
-+ D1(printk(KERN_DEBUG "Expanding down to cover frag (0x%x-0x%x) in dirty block %08x\n",
-+ frag->ofs, frag->ofs+frag->size, jeb->offset));
-+ start = frag->ofs;
-+ break;
-+ }
-+ }
-+
-+ /* ... then up */
-+
-+ /* Find last frag which is actually part of the node we're to GC. */
-+ frag = jffs2_lookup_node_frag(&f->fragtree, end-1);
-+
-+ while((frag = frag_next(frag)) && frag->ofs+frag->size <= max) {
-+
-+ /* If the previous frag doesn't even reach the beginning, there's lots
-+ of fragmentation. Just merge. */
-+ if (frag->ofs+frag->size < max) {
-+ D1(printk(KERN_DEBUG "Expanding up to cover partial frag (0x%x-0x%x)\n",
-+ frag->ofs, frag->ofs+frag->size));
-+ end = frag->ofs + frag->size;
-+ continue;
-+ }
-+
-+ if (!frag->node || !frag->node->raw) {
-+ D1(printk(KERN_DEBUG "Last frag in page is hole (0x%x-0x%x). Not expanding up.\n",
-+ frag->ofs, frag->ofs+frag->size));
-+ break;
-+ } else {
-+
-+ /* OK, it's a frag which extends to the beginning of the page. Does it live
-+ in a block which is still considered clean? If so, don't obsolete it.
-+ If not, cover it anyway. */
-+
-+ struct jffs2_raw_node_ref *raw = frag->node->raw;
-+ struct jffs2_eraseblock *jeb;
-+
-+ jeb = &c->blocks[raw->flash_offset / c->sector_size];
-+
-+ if (jeb == c->gcblock) {
-+ D1(printk(KERN_DEBUG "Expanding up to cover frag (0x%x-0x%x) in gcblock at %08x\n",
-+ frag->ofs, frag->ofs+frag->size, ref_offset(raw)));
-+ end = frag->ofs + frag->size;
-+ break;
-+ }
-+ if (!ISDIRTY(jeb->dirty_size + jeb->wasted_size)) {
-+ D1(printk(KERN_DEBUG "Not expanding up to cover frag (0x%x-0x%x) in clean block %08x\n",
-+ frag->ofs, frag->ofs+frag->size, jeb->offset));
-+ break;
-+ }
-+
-+ D1(printk(KERN_DEBUG "Expanding up to cover frag (0x%x-0x%x) in dirty block %08x\n",
-+ frag->ofs, frag->ofs+frag->size, jeb->offset));
-+ end = frag->ofs + frag->size;
-+ break;
-+ }
-+ }
-+ D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n",
-+ orig_start, orig_end, start, end));
-+
-+ BUG_ON(end > JFFS2_F_I_SIZE(f));
-+ BUG_ON(end < orig_end);
-+ BUG_ON(start > orig_start);
- }
-
- /* First, use readpage() to read the appropriate page into the page cache */
-@@ -623,63 +1165,57 @@
- * page OK. We'll actually write it out again in commit_write, which is a little
- * suboptimal, but at least we're correct.
- */
-- pg = read_cache_page(inode->i_mapping, start >> PAGE_CACHE_SHIFT, (void *)jffs2_do_readpage_unlock, inode);
-+ pg_ptr = jffs2_gc_fetch_page(c, f, start, &pg);
-
-- if (IS_ERR(pg)) {
-- printk(KERN_WARNING "read_cache_page() returned error: %ld\n", PTR_ERR(pg));
-- return PTR_ERR(pg);
-+ if (IS_ERR(pg_ptr)) {
-+ printk(KERN_WARNING "read_cache_page() returned error: %ld\n", PTR_ERR(pg_ptr));
-+ return PTR_ERR(pg_ptr);
- }
-- pg_ptr = (char *)kmap(pg);
-- comprbuf = kmalloc(end - start, GFP_KERNEL);
-
- offset = start;
- while(offset < orig_end) {
-- __u32 datalen;
-- __u32 cdatalen;
-+ uint32_t datalen;
-+ uint32_t cdatalen;
- char comprtype = JFFS2_COMPR_NONE;
-
- ret = jffs2_reserve_space_gc(c, sizeof(ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen);
-
- if (ret) {
-- printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_dnode failed: %d\n",
-+ printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dnode failed: %d\n",
- sizeof(ri)+ JFFS2_MIN_DATA_LEN, ret);
- break;
- }
-- cdatalen = min(alloclen - sizeof(ri), end - offset);
-+ cdatalen = min_t(uint32_t, alloclen - sizeof(ri), end - offset);
- datalen = end - offset;
-
- writebuf = pg_ptr + (offset & (PAGE_CACHE_SIZE -1));
-
-- if (comprbuf) {
-- comprtype = jffs2_compress(writebuf, comprbuf, &datalen, &cdatalen);
-- }
-- if (comprtype) {
-- writebuf = comprbuf;
-- } else {
-- datalen = cdatalen;
-- }
-- ri.magic = JFFS2_MAGIC_BITMASK;
-- ri.nodetype = JFFS2_NODETYPE_INODE;
-- ri.totlen = sizeof(ri) + cdatalen;
-- ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4);
--
-- ri.ino = inode->i_ino;
-- ri.version = ++f->highest_version;
-- ri.mode = inode->i_mode;
-- ri.uid = inode->i_uid;
-- ri.gid = inode->i_gid;
-- ri.isize = inode->i_size;
-- ri.atime = inode->i_atime;
-- ri.ctime = inode->i_ctime;
-- ri.mtime = inode->i_mtime;
-- ri.offset = offset;
-- ri.csize = cdatalen;
-- ri.dsize = datalen;
-+ comprtype = jffs2_compress(writebuf, &comprbuf, &datalen, &cdatalen);
-+
-+ ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
-+ ri.totlen = cpu_to_je32(sizeof(ri) + cdatalen);
-+ ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4));
-+
-+ ri.ino = cpu_to_je32(f->inocache->ino);
-+ ri.version = cpu_to_je32(++f->highest_version);
-+ ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
-+ ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
-+ ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
-+ ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f));
-+ ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
-+ ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
-+ ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f));
-+ ri.offset = cpu_to_je32(offset);
-+ ri.csize = cpu_to_je32(cdatalen);
-+ ri.dsize = cpu_to_je32(datalen);
- ri.compr = comprtype;
-- ri.node_crc = crc32(0, &ri, sizeof(ri)-8);
-- ri.data_crc = crc32(0, writebuf, cdatalen);
-+ ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
-+ ri.data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
-+
-+ new_fn = jffs2_write_dnode(c, f, &ri, comprbuf, cdatalen, phys_ofs, ALLOC_GC);
-
-- new_fn = jffs2_write_dnode(inode, &ri, writebuf, cdatalen, phys_ofs, NULL);
-+ jffs2_free_comprbuf(comprbuf, writebuf);
-
- if (IS_ERR(new_fn)) {
- printk(KERN_WARNING "Error writing new dnode: %ld\n", PTR_ERR(new_fn));
-@@ -694,12 +1230,8 @@
- f->metadata = NULL;
- }
- }
-- if (comprbuf) kfree(comprbuf);
-
-- kunmap(pg);
-- /* XXX: Does the page get freed automatically? */
-- /* AAA: Judging by the unmount getting stuck in __wait_on_page, nope. */
-- page_cache_release(pg);
-+ jffs2_gc_release_page(c, pg_ptr, &pg);
- return ret;
- }
-
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/ioctl.c linux/fs/jffs2/ioctl.c
---- linux-mips-2.4.24-pre2/fs/jffs2/ioctl.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/ioctl.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,37 +1,13 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
-@@ -42,6 +18,6 @@
- {
- /* Later, this will provide for lsattr.jffs2 and chattr.jffs2, which
- will include compression support etc. */
-- return -EINVAL;
-+ return -ENOTTY;
- }
-
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/malloc.c linux/fs/jffs2/malloc.c
---- linux-mips-2.4.24-pre2/fs/jffs2/malloc.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/malloc.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,37 +1,13 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
-@@ -47,6 +23,9 @@
- #define JFFS2_SLAB_POISON 0
- #endif
-
-+// replace this by #define D3 (x) x for cache debugging
-+#define D3(x)
-+
- /* These are initialised to NULL in the kernel startup code.
- If you're porting to other operating systems, beware */
- static kmem_cache_t *full_dnode_slab;
-@@ -57,57 +36,47 @@
- static kmem_cache_t *node_frag_slab;
- static kmem_cache_t *inode_cache_slab;
-
--void jffs2_free_tmp_dnode_info_list(struct jffs2_tmp_dnode_info *tn)
--{
-- struct jffs2_tmp_dnode_info *next;
--
-- while (tn) {
-- next = tn;
-- tn = tn->next;
-- jffs2_free_full_dnode(next->fn);
-- jffs2_free_tmp_dnode_info(next);
-- }
--}
--
--void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
--{
-- struct jffs2_full_dirent *next;
--
-- while (fd) {
-- next = fd->next;
-- jffs2_free_full_dirent(fd);
-- fd = next;
-- }
--}
--
- int __init jffs2_create_slab_caches(void)
- {
-- full_dnode_slab = kmem_cache_create("jffs2_full_dnode", sizeof(struct jffs2_full_dnode), 0, JFFS2_SLAB_POISON, NULL, NULL);
-+ full_dnode_slab = kmem_cache_create("jffs2_full_dnode",
-+ sizeof(struct jffs2_full_dnode),
-+ 0, JFFS2_SLAB_POISON, NULL, NULL);
- if (!full_dnode_slab)
- goto err;
-
-- raw_dirent_slab = kmem_cache_create("jffs2_raw_dirent", sizeof(struct jffs2_raw_dirent), 0, JFFS2_SLAB_POISON, NULL, NULL);
-+ raw_dirent_slab = kmem_cache_create("jffs2_raw_dirent",
-+ sizeof(struct jffs2_raw_dirent),
-+ 0, JFFS2_SLAB_POISON, NULL, NULL);
- if (!raw_dirent_slab)
- goto err;
-
-- raw_inode_slab = kmem_cache_create("jffs2_raw_inode", sizeof(struct jffs2_raw_inode), 0, JFFS2_SLAB_POISON, NULL, NULL);
-+ raw_inode_slab = kmem_cache_create("jffs2_raw_inode",
-+ sizeof(struct jffs2_raw_inode),
-+ 0, JFFS2_SLAB_POISON, NULL, NULL);
- if (!raw_inode_slab)
- goto err;
-
-- tmp_dnode_info_slab = kmem_cache_create("jffs2_tmp_dnode", sizeof(struct jffs2_tmp_dnode_info), 0, JFFS2_SLAB_POISON, NULL, NULL);
-+ tmp_dnode_info_slab = kmem_cache_create("jffs2_tmp_dnode",
-+ sizeof(struct jffs2_tmp_dnode_info),
-+ 0, JFFS2_SLAB_POISON, NULL, NULL);
- if (!tmp_dnode_info_slab)
- goto err;
-
-- raw_node_ref_slab = kmem_cache_create("jffs2_raw_node_ref", sizeof(struct jffs2_raw_node_ref), 0, JFFS2_SLAB_POISON, NULL, NULL);
-+ raw_node_ref_slab = kmem_cache_create("jffs2_raw_node_ref",
-+ sizeof(struct jffs2_raw_node_ref),
-+ 0, JFFS2_SLAB_POISON, NULL, NULL);
- if (!raw_node_ref_slab)
- goto err;
-
-- node_frag_slab = kmem_cache_create("jffs2_node_frag", sizeof(struct jffs2_node_frag), 0, JFFS2_SLAB_POISON, NULL, NULL);
-+ node_frag_slab = kmem_cache_create("jffs2_node_frag",
-+ sizeof(struct jffs2_node_frag),
-+ 0, JFFS2_SLAB_POISON, NULL, NULL);
- if (!node_frag_slab)
- goto err;
-
-- inode_cache_slab = kmem_cache_create("jffs2_inode_cache", sizeof(struct jffs2_inode_cache), 0, JFFS2_SLAB_POISON, NULL, NULL);
--
-+ inode_cache_slab = kmem_cache_create("jffs2_inode_cache",
-+ sizeof(struct jffs2_inode_cache),
-+ 0, JFFS2_SLAB_POISON, NULL, NULL);
- if (inode_cache_slab)
- return 0;
- err:
-@@ -131,7 +100,6 @@
- kmem_cache_destroy(node_frag_slab);
- if(inode_cache_slab)
- kmem_cache_destroy(inode_cache_slab);
--
- }
-
- struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize)
-@@ -146,75 +114,92 @@
-
- struct jffs2_full_dnode *jffs2_alloc_full_dnode(void)
- {
-- void *ret = kmem_cache_alloc(full_dnode_slab, GFP_KERNEL);
-+ struct jffs2_full_dnode *ret = kmem_cache_alloc(full_dnode_slab, GFP_KERNEL);
-+ D3 (printk (KERN_DEBUG "alloc_full_dnode at %p\n", ret));
- return ret;
- }
-
- void jffs2_free_full_dnode(struct jffs2_full_dnode *x)
- {
-+ D3 (printk (KERN_DEBUG "free full_dnode at %p\n", x));
- kmem_cache_free(full_dnode_slab, x);
- }
-
- struct jffs2_raw_dirent *jffs2_alloc_raw_dirent(void)
- {
-- return kmem_cache_alloc(raw_dirent_slab, GFP_KERNEL);
-+ struct jffs2_raw_dirent *ret = kmem_cache_alloc(raw_dirent_slab, GFP_KERNEL);
-+ D3 (printk (KERN_DEBUG "alloc_raw_dirent\n", ret));
-+ return ret;
- }
-
- void jffs2_free_raw_dirent(struct jffs2_raw_dirent *x)
- {
-+ D3 (printk (KERN_DEBUG "free_raw_dirent at %p\n", x));
- kmem_cache_free(raw_dirent_slab, x);
- }
-
- struct jffs2_raw_inode *jffs2_alloc_raw_inode(void)
- {
-- return kmem_cache_alloc(raw_inode_slab, GFP_KERNEL);
-+ struct jffs2_raw_inode *ret = kmem_cache_alloc(raw_inode_slab, GFP_KERNEL);
-+ D3 (printk (KERN_DEBUG "alloc_raw_inode at %p\n", ret));
-+ return ret;
- }
-
- void jffs2_free_raw_inode(struct jffs2_raw_inode *x)
- {
-+ D3 (printk (KERN_DEBUG "free_raw_inode at %p\n", x));
- kmem_cache_free(raw_inode_slab, x);
- }
-
- struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void)
- {
-- return kmem_cache_alloc(tmp_dnode_info_slab, GFP_KERNEL);
-+ struct jffs2_tmp_dnode_info *ret = kmem_cache_alloc(tmp_dnode_info_slab, GFP_KERNEL);
-+ D3 (printk (KERN_DEBUG "alloc_tmp_dnode_info at %p\n", ret));
-+ return ret;
- }
-
- void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x)
- {
-+ D3 (printk (KERN_DEBUG "free_tmp_dnode_info at %p\n", x));
- kmem_cache_free(tmp_dnode_info_slab, x);
- }
-
- struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void)
- {
-- return kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL);
-+ struct jffs2_raw_node_ref *ret = kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL);
-+ D3 (printk (KERN_DEBUG "alloc_raw_node_ref at %p\n", ret));
-+ return ret;
- }
-
- void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x)
- {
-+ D3 (printk (KERN_DEBUG "free_raw_node_ref at %p\n", x));
- kmem_cache_free(raw_node_ref_slab, x);
- }
-
- struct jffs2_node_frag *jffs2_alloc_node_frag(void)
- {
-- return kmem_cache_alloc(node_frag_slab, GFP_KERNEL);
-+ struct jffs2_node_frag *ret = kmem_cache_alloc(node_frag_slab, GFP_KERNEL);
-+ D3 (printk (KERN_DEBUG "alloc_node_frag at %p\n", ret));
-+ return ret;
- }
-
- void jffs2_free_node_frag(struct jffs2_node_frag *x)
- {
-+ D3 (printk (KERN_DEBUG "free_node_frag at %p\n", x));
- kmem_cache_free(node_frag_slab, x);
- }
-
- struct jffs2_inode_cache *jffs2_alloc_inode_cache(void)
- {
- struct jffs2_inode_cache *ret = kmem_cache_alloc(inode_cache_slab, GFP_KERNEL);
-- D1(printk(KERN_DEBUG "Allocated inocache at %p\n", ret));
-+ D3 (printk(KERN_DEBUG "Allocated inocache at %p\n", ret));
- return ret;
- }
-
- void jffs2_free_inode_cache(struct jffs2_inode_cache *x)
- {
-- D1(printk(KERN_DEBUG "Freeing inocache at %p\n", x));
-+ D3 (printk(KERN_DEBUG "Freeing inocache at %p\n", x));
- kmem_cache_free(inode_cache_slab, x);
- }
-
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/nodelist.c linux/fs/jffs2/nodelist.c
---- linux-mips-2.4.24-pre2/fs/jffs2/nodelist.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/nodelist.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,44 +1,24 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001, 2002 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/kernel.h>
--#include <linux/jffs2.h>
-+#include <linux/sched.h>
- #include <linux/fs.h>
- #include <linux/mtd/mtd.h>
-+#include <linux/rbtree.h>
-+#include <linux/crc32.h>
-+#include <linux/slab.h>
-+#include <linux/pagemap.h>
- #include "nodelist.h"
-
- void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list)
-@@ -78,7 +58,7 @@
- /* Put a new tmp_dnode_info into the list, keeping the list in
- order of increasing version
- */
--void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct jffs2_tmp_dnode_info **list)
-+static void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct jffs2_tmp_dnode_info **list)
- {
- struct jffs2_tmp_dnode_info **prev = list;
-
-@@ -89,13 +69,37 @@
- *prev = tn;
- }
-
-+static void jffs2_free_tmp_dnode_info_list(struct jffs2_tmp_dnode_info *tn)
-+{
-+ struct jffs2_tmp_dnode_info *next;
-+
-+ while (tn) {
-+ next = tn;
-+ tn = tn->next;
-+ jffs2_free_full_dnode(next->fn);
-+ jffs2_free_tmp_dnode_info(next);
-+ }
-+}
-+
-+static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
-+{
-+ struct jffs2_full_dirent *next;
-+
-+ while (fd) {
-+ next = fd->next;
-+ jffs2_free_full_dirent(fd);
-+ fd = next;
-+ }
-+}
-+
-+
- /* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated
- with this ino, returning the former in order of version */
-
- int jffs2_get_inode_nodes(struct jffs2_sb_info *c, ino_t ino, struct jffs2_inode_info *f,
- struct jffs2_tmp_dnode_info **tnp, struct jffs2_full_dirent **fdp,
-- __u32 *highest_version, __u32 *latest_mctime,
-- __u32 *mctime_ver)
-+ uint32_t *highest_version, uint32_t *latest_mctime,
-+ uint32_t *mctime_ver)
- {
- struct jffs2_raw_node_ref *ref = f->inocache->nodes;
- struct jffs2_tmp_dnode_info *tn, *ret_tn = NULL;
-@@ -109,43 +113,71 @@
-
- D1(printk(KERN_DEBUG "jffs2_get_inode_nodes(): ino #%lu\n", ino));
- if (!f->inocache->nodes) {
-- printk(KERN_WARNING "Eep. no nodes for ino #%lu\n", ino);
-+ printk(KERN_WARNING "Eep. no nodes for ino #%lu\n", (unsigned long)ino);
- }
-+
-+ spin_lock(&c->erase_completion_lock);
-+
- for (ref = f->inocache->nodes; ref && ref->next_in_ino; ref = ref->next_in_ino) {
- /* Work out whether it's a data node or a dirent node */
-- if (ref->flash_offset & 1) {
-+ if (ref_obsolete(ref)) {
- /* FIXME: On NAND flash we may need to read these */
-- D1(printk(KERN_DEBUG "node at 0x%08x is obsoleted. Ignoring.\n", ref->flash_offset &~3));
-+ D1(printk(KERN_DEBUG "node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref)));
- continue;
- }
-- err = c->mtd->read(c->mtd, (ref->flash_offset & ~3), min(ref->totlen, sizeof(node)), &retlen, (void *)&node);
-+ /* We can hold a pointer to a non-obsolete node without the spinlock,
-+ but _obsolete_ nodes may disappear at any time, if the block
-+ they're in gets erased */
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ cond_resched();
-+
-+ /* FIXME: point() */
-+ err = jffs2_flash_read(c, (ref_offset(ref)),
-+ min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node)),
-+ &retlen, (void *)&node);
- if (err) {
-- printk(KERN_WARNING "error %d reading node at 0x%08x in get_inode_nodes()\n", err, (ref->flash_offset) & ~3);
-+ printk(KERN_WARNING "error %d reading node at 0x%08x in get_inode_nodes()\n", err, ref_offset(ref));
- goto free_out;
- }
-
-
- /* Check we've managed to read at least the common node header */
-- if (retlen < min(ref->totlen, sizeof(node.u))) {
-+ if (retlen < min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node.u))) {
- printk(KERN_WARNING "short read in get_inode_nodes()\n");
- err = -EIO;
- goto free_out;
- }
-
-- switch (node.u.nodetype) {
-+ switch (je16_to_cpu(node.u.nodetype)) {
- case JFFS2_NODETYPE_DIRENT:
-- D1(printk(KERN_DEBUG "Node at %08x is a dirent node\n", ref->flash_offset &~3));
-+ D1(printk(KERN_DEBUG "Node at %08x (%d) is a dirent node\n", ref_offset(ref), ref_flags(ref)));
-+ if (ref_flags(ref) == REF_UNCHECKED) {
-+ printk(KERN_WARNING "BUG: Dirent node at 0x%08x never got checked? How?\n", ref_offset(ref));
-+ BUG();
-+ }
- if (retlen < sizeof(node.d)) {
- printk(KERN_WARNING "short read in get_inode_nodes()\n");
- err = -EIO;
- goto free_out;
- }
-- if (node.d.version > *highest_version)
-- *highest_version = node.d.version;
-- if (ref->flash_offset & 1) {
-- /* Obsoleted */
-+ /* sanity check */
-+ if (PAD((node.d.nsize + sizeof (node.d))) != PAD(je32_to_cpu (node.d.totlen))) {
-+ printk(KERN_NOTICE "jffs2_get_inode_nodes(): Illegal nsize in node at 0x%08x: nsize 0x%02x, totlen %04x\n",
-+ ref_offset(ref), node.d.nsize, je32_to_cpu(node.d.totlen));
-+ jffs2_mark_node_obsolete(c, ref);
-+ spin_lock(&c->erase_completion_lock);
- continue;
- }
-+ if (je32_to_cpu(node.d.version) > *highest_version)
-+ *highest_version = je32_to_cpu(node.d.version);
-+ if (ref_obsolete(ref)) {
-+ /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
-+ printk(KERN_ERR "Dirent node at 0x%08x became obsolete while we weren't looking\n",
-+ ref_offset(ref));
-+ BUG();
-+ }
-+
- fd = jffs2_alloc_full_dirent(node.d.nsize+1);
- if (!fd) {
- err = -ENOMEM;
-@@ -153,29 +185,30 @@
- }
- memset(fd,0,sizeof(struct jffs2_full_dirent) + node.d.nsize+1);
- fd->raw = ref;
-- fd->version = node.d.version;
-- fd->ino = node.d.ino;
-+ fd->version = je32_to_cpu(node.d.version);
-+ fd->ino = je32_to_cpu(node.d.ino);
- fd->type = node.d.type;
-
- /* Pick out the mctime of the latest dirent */
- if(fd->version > *mctime_ver) {
- *mctime_ver = fd->version;
-- *latest_mctime = node.d.mctime;
-+ *latest_mctime = je32_to_cpu(node.d.mctime);
- }
-
- /* memcpy as much of the name as possible from the raw
- dirent we've already read from the flash
- */
- if (retlen > sizeof(struct jffs2_raw_dirent))
-- memcpy(&fd->name[0], &node.d.name[0], min((__u32)node.d.nsize, (retlen-sizeof(struct jffs2_raw_dirent))));
-+ memcpy(&fd->name[0], &node.d.name[0], min_t(uint32_t, node.d.nsize, (retlen-sizeof(struct jffs2_raw_dirent))));
-
- /* Do we need to copy any more of the name directly
- from the flash?
- */
- if (node.d.nsize + sizeof(struct jffs2_raw_dirent) > retlen) {
-+ /* FIXME: point() */
- int already = retlen - sizeof(struct jffs2_raw_dirent);
-
-- err = c->mtd->read(c->mtd, (ref->flash_offset & ~3) + retlen,
-+ err = jffs2_flash_read(c, (ref_offset(ref)) + retlen,
- node.d.nsize - already, &retlen, &fd->name[already]);
- if (!err && retlen != node.d.nsize - already)
- err = -EIO;
-@@ -196,21 +229,126 @@
- break;
-
- case JFFS2_NODETYPE_INODE:
-- D1(printk(KERN_DEBUG "Node at %08x is a data node\n", ref->flash_offset &~3));
-+ D1(printk(KERN_DEBUG "Node at %08x (%d) is a data node\n", ref_offset(ref), ref_flags(ref)));
- if (retlen < sizeof(node.i)) {
- printk(KERN_WARNING "read too short for dnode\n");
- err = -EIO;
- goto free_out;
- }
-- if (node.i.version > *highest_version)
-- *highest_version = node.i.version;
-- D1(printk(KERN_DEBUG "version %d, highest_version now %d\n", node.i.version, *highest_version));
--
-- if (ref->flash_offset & 1) {
-- D1(printk(KERN_DEBUG "obsoleted\n"));
-- /* Obsoleted */
-+ if (je32_to_cpu(node.i.version) > *highest_version)
-+ *highest_version = je32_to_cpu(node.i.version);
-+ D1(printk(KERN_DEBUG "version %d, highest_version now %d\n", je32_to_cpu(node.i.version), *highest_version));
-+
-+ if (ref_obsolete(ref)) {
-+ /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
-+ printk(KERN_ERR "Inode node at 0x%08x became obsolete while we weren't looking\n",
-+ ref_offset(ref));
-+ BUG();
-+ }
-+
-+ /* If we've never checked the CRCs on this node, check them now. */
-+ if (ref_flags(ref) == REF_UNCHECKED) {
-+ uint32_t crc, len;
-+ struct jffs2_eraseblock *jeb;
-+
-+ crc = crc32(0, &node, sizeof(node.i)-8);
-+ if (crc != je32_to_cpu(node.i.node_crc)) {
-+ printk(KERN_NOTICE "jffs2_get_inode_nodes(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-+ ref_offset(ref), je32_to_cpu(node.i.node_crc), crc);
-+ jffs2_mark_node_obsolete(c, ref);
-+ spin_lock(&c->erase_completion_lock);
- continue;
- }
-+
-+ /* sanity checks */
-+ if ( je32_to_cpu(node.i.offset) > je32_to_cpu(node.i.isize) ||
-+ PAD(je32_to_cpu(node.i.csize) + sizeof (node.i)) != PAD(je32_to_cpu(node.i.totlen))) {
-+ printk(KERN_NOTICE "jffs2_get_inode_nodes(): Inode corrupted at 0x%08x, totlen %d, #ino %d, version %d, isize %d, csize %d, dsize %d \n",
-+ ref_offset(ref), je32_to_cpu(node.i.totlen), je32_to_cpu(node.i.ino),
-+ je32_to_cpu(node.i.version), je32_to_cpu(node.i.isize),
-+ je32_to_cpu(node.i.csize), je32_to_cpu(node.i.dsize));
-+ jffs2_mark_node_obsolete(c, ref);
-+ spin_lock(&c->erase_completion_lock);
-+ continue;
-+ }
-+
-+ if (node.i.compr != JFFS2_COMPR_ZERO && je32_to_cpu(node.i.csize)) {
-+ unsigned char *buf=NULL;
-+ uint32_t pointed = 0;
-+#ifndef __ECOS
-+ if (c->mtd->point) {
-+ err = c->mtd->point (c->mtd, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize),
-+ &retlen, &buf);
-+ if (!err && retlen < je32_to_cpu(node.i.csize)) {
-+ D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen));
-+ c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize));
-+ } else if (err){
-+ D1(printk(KERN_DEBUG "MTD point failed %d\n", err));
-+ } else
-+ pointed = 1; /* succefully pointed to device */
-+ }
-+#endif
-+ if(!pointed){
-+ buf = kmalloc(je32_to_cpu(node.i.csize), GFP_KERNEL);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ err = jffs2_flash_read(c, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize),
-+ &retlen, buf);
-+ if (!err && retlen != je32_to_cpu(node.i.csize))
-+ err = -EIO;
-+ if (err) {
-+ kfree(buf);
-+ return err;
-+ }
-+ }
-+ crc = crc32(0, buf, je32_to_cpu(node.i.csize));
-+ if(!pointed)
-+ kfree(buf);
-+#ifndef __ECOS
-+ else
-+ c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize));
-+#endif
-+
-+ if (crc != je32_to_cpu(node.i.data_crc)) {
-+ printk(KERN_NOTICE "jffs2_get_inode_nodes(): Data CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-+ ref_offset(ref), je32_to_cpu(node.i.data_crc), crc);
-+ jffs2_mark_node_obsolete(c, ref);
-+ spin_lock(&c->erase_completion_lock);
-+ continue;
-+ }
-+
-+ }
-+
-+ /* Mark the node as having been checked and fix the accounting accordingly */
-+ spin_lock(&c->erase_completion_lock);
-+ jeb = &c->blocks[ref->flash_offset / c->sector_size];
-+ len = ref_totlen(c, jeb, ref);
-+
-+ jeb->used_size += len;
-+ jeb->unchecked_size -= len;
-+ c->used_size += len;
-+ c->unchecked_size -= len;
-+
-+ /* If node covers at least a whole page, or if it starts at the
-+ beginning of a page and runs to the end of the file, or if
-+ it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
-+
-+ If it's actually overlapped, it'll get made NORMAL (or OBSOLETE)
-+ when the overlapping node(s) get added to the tree anyway.
-+ */
-+ if ((je32_to_cpu(node.i.dsize) >= PAGE_CACHE_SIZE) ||
-+ ( ((je32_to_cpu(node.i.offset)&(PAGE_CACHE_SIZE-1))==0) &&
-+ (je32_to_cpu(node.i.dsize)+je32_to_cpu(node.i.offset) == je32_to_cpu(node.i.isize)))) {
-+ D1(printk(KERN_DEBUG "Marking node at 0x%08x REF_PRISTINE\n", ref_offset(ref)));
-+ ref->flash_offset = ref_offset(ref) | REF_PRISTINE;
-+ } else {
-+ D1(printk(KERN_DEBUG "Marking node at 0x%08x REF_NORMAL\n", ref_offset(ref)));
-+ ref->flash_offset = ref_offset(ref) | REF_NORMAL;
-+ }
-+ spin_unlock(&c->erase_completion_lock);
-+ }
-+
- tn = jffs2_alloc_tmp_dnode_info();
- if (!tn) {
- D1(printk(KERN_DEBUG "alloc tn failed\n"));
-@@ -225,36 +363,76 @@
- jffs2_free_tmp_dnode_info(tn);
- goto free_out;
- }
-- tn->version = node.i.version;
-- tn->fn->ofs = node.i.offset;
-+ tn->version = je32_to_cpu(node.i.version);
-+ tn->fn->ofs = je32_to_cpu(node.i.offset);
- /* There was a bug where we wrote hole nodes out with
- csize/dsize swapped. Deal with it */
-- if (node.i.compr == JFFS2_COMPR_ZERO && !node.i.dsize && node.i.csize)
-- tn->fn->size = node.i.csize;
-+ if (node.i.compr == JFFS2_COMPR_ZERO && !je32_to_cpu(node.i.dsize) && je32_to_cpu(node.i.csize))
-+ tn->fn->size = je32_to_cpu(node.i.csize);
- else // normal case...
-- tn->fn->size = node.i.dsize;
-+ tn->fn->size = je32_to_cpu(node.i.dsize);
- tn->fn->raw = ref;
-- D1(printk(KERN_DEBUG "dnode @%08x: ver %u, offset %04x, dsize %04x\n", ref->flash_offset &~3, node.i.version, node.i.offset, node.i.dsize));
-+ D1(printk(KERN_DEBUG "dnode @%08x: ver %u, offset %04x, dsize %04x\n",
-+ ref_offset(ref), je32_to_cpu(node.i.version),
-+ je32_to_cpu(node.i.offset), je32_to_cpu(node.i.dsize)));
- jffs2_add_tn_to_list(tn, &ret_tn);
- break;
-
- default:
-- switch(node.u.nodetype & JFFS2_COMPAT_MASK) {
-+ if (ref_flags(ref) == REF_UNCHECKED) {
-+ struct jffs2_eraseblock *jeb;
-+ uint32_t len;
-+
-+ printk(KERN_ERR "Eep. Unknown node type %04x at %08x was marked REF_UNCHECKED\n",
-+ je16_to_cpu(node.u.nodetype), ref_offset(ref));
-+
-+ /* Mark the node as having been checked and fix the accounting accordingly */
-+ spin_lock(&c->erase_completion_lock);
-+ jeb = &c->blocks[ref->flash_offset / c->sector_size];
-+ len = ref_totlen(c, jeb, ref);
-+
-+ jeb->used_size += len;
-+ jeb->unchecked_size -= len;
-+ c->used_size += len;
-+ c->unchecked_size -= len;
-+
-+ mark_ref_normal(ref);
-+ spin_unlock(&c->erase_completion_lock);
-+ }
-+ node.u.nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(node.u.nodetype));
-+ if (crc32(0, &node, sizeof(struct jffs2_unknown_node)-4) != je32_to_cpu(node.u.hdr_crc)) {
-+ /* Hmmm. This should have been caught at scan time. */
-+ printk(KERN_ERR "Node header CRC failed at %08x. But it must have been OK earlier.\n",
-+ ref_offset(ref));
-+ printk(KERN_ERR "Node was: { %04x, %04x, %08x, %08x }\n",
-+ je16_to_cpu(node.u.magic), je16_to_cpu(node.u.nodetype), je32_to_cpu(node.u.totlen),
-+ je32_to_cpu(node.u.hdr_crc));
-+ jffs2_mark_node_obsolete(c, ref);
-+ } else switch(je16_to_cpu(node.u.nodetype) & JFFS2_COMPAT_MASK) {
- case JFFS2_FEATURE_INCOMPAT:
-- printk(KERN_NOTICE "Unknown INCOMPAT nodetype %04X at %08X\n", node.u.nodetype, ref->flash_offset & ~3);
-+ printk(KERN_NOTICE "Unknown INCOMPAT nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
-+ /* EEP */
-+ BUG();
- break;
- case JFFS2_FEATURE_ROCOMPAT:
-- printk(KERN_NOTICE "Unknown ROCOMPAT nodetype %04X at %08X\n", node.u.nodetype, ref->flash_offset & ~3);
-+ printk(KERN_NOTICE "Unknown ROCOMPAT nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
-+ if (!(c->flags & JFFS2_SB_FLAG_RO))
-+ BUG();
- break;
- case JFFS2_FEATURE_RWCOMPAT_COPY:
-- printk(KERN_NOTICE "Unknown RWCOMPAT_COPY nodetype %04X at %08X\n", node.u.nodetype, ref->flash_offset & ~3);
-+ printk(KERN_NOTICE "Unknown RWCOMPAT_COPY nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
- break;
- case JFFS2_FEATURE_RWCOMPAT_DELETE:
-- printk(KERN_NOTICE "Unknown RWCOMPAT_DELETE nodetype %04X at %08X\n", node.u.nodetype, ref->flash_offset & ~3);
-+ printk(KERN_NOTICE "Unknown RWCOMPAT_DELETE nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
-+ jffs2_mark_node_obsolete(c, ref);
- break;
- }
-+
- }
-+ spin_lock(&c->erase_completion_lock);
-+
- }
-+ spin_unlock(&c->erase_completion_lock);
- *tnp = ret_tn;
- *fdp = ret_fd;
-
-@@ -266,19 +444,30 @@
- return err;
- }
-
-+void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state)
-+{
-+ spin_lock(&c->inocache_lock);
-+ ic->state = state;
-+ wake_up(&c->inocache_wq);
-+ spin_unlock(&c->inocache_lock);
-+}
-+
-+/* During mount, this needs no locking. During normal operation, its
-+ callers want to do other stuff while still holding the inocache_lock.
-+ Rather than introducing special case get_ino_cache functions or
-+ callbacks, we just let the caller do the locking itself. */
-+
- struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino)
- {
- struct jffs2_inode_cache *ret;
-
- D2(printk(KERN_DEBUG "jffs2_get_ino_cache(): ino %u\n", ino));
-- spin_lock (&c->inocache_lock);
-+
- ret = c->inocache_list[ino % INOCACHE_HASHSIZE];
- while (ret && ret->ino < ino) {
- ret = ret->next;
- }
-
-- spin_unlock(&c->inocache_lock);
--
- if (ret && ret->ino != ino)
- ret = NULL;
-
-@@ -299,6 +488,7 @@
- }
- new->next = *prev;
- *prev = new;
-+
- spin_unlock(&c->inocache_lock);
- }
-
-@@ -316,6 +506,7 @@
- if ((*prev) == old) {
- *prev = old->next;
- }
-+
- spin_unlock(&c->inocache_lock);
- }
-
-@@ -352,3 +543,128 @@
- }
- }
-
-+struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset)
-+{
-+ /* The common case in lookup is that there will be a node
-+ which precisely matches. So we go looking for that first */
-+ struct rb_node *next;
-+ struct jffs2_node_frag *prev = NULL;
-+ struct jffs2_node_frag *frag = NULL;
-+
-+ D2(printk(KERN_DEBUG "jffs2_lookup_node_frag(%p, %d)\n", fragtree, offset));
-+
-+ next = fragtree->rb_node;
-+
-+ while(next) {
-+ frag = rb_entry(next, struct jffs2_node_frag, rb);
-+
-+ D2(printk(KERN_DEBUG "Considering frag %d-%d (%p). left %p, right %p\n",
-+ frag->ofs, frag->ofs+frag->size, frag, frag->rb.rb_left, frag->rb.rb_right));
-+ if (frag->ofs + frag->size <= offset) {
-+ D2(printk(KERN_DEBUG "Going right from frag %d-%d, before the region we care about\n",
-+ frag->ofs, frag->ofs+frag->size));
-+ /* Remember the closest smaller match on the way down */
-+ if (!prev || frag->ofs > prev->ofs)
-+ prev = frag;
-+ next = frag->rb.rb_right;
-+ } else if (frag->ofs > offset) {
-+ D2(printk(KERN_DEBUG "Going left from frag %d-%d, after the region we care about\n",
-+ frag->ofs, frag->ofs+frag->size));
-+ next = frag->rb.rb_left;
-+ } else {
-+ D2(printk(KERN_DEBUG "Returning frag %d,%d, matched\n",
-+ frag->ofs, frag->ofs+frag->size));
-+ return frag;
-+ }
-+ }
-+
-+ /* Exact match not found. Go back up looking at each parent,
-+ and return the closest smaller one */
-+
-+ if (prev)
-+ D2(printk(KERN_DEBUG "No match. Returning frag %d,%d, closest previous\n",
-+ prev->ofs, prev->ofs+prev->size));
-+ else
-+ D2(printk(KERN_DEBUG "Returning NULL, empty fragtree\n"));
-+
-+ return prev;
-+}
-+
-+/* Pass 'c' argument to indicate that nodes should be marked obsolete as
-+ they're killed. */
-+void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c)
-+{
-+ struct jffs2_node_frag *frag;
-+ struct jffs2_node_frag *parent;
-+
-+ if (!root->rb_node)
-+ return;
-+
-+ frag = (rb_entry(root->rb_node, struct jffs2_node_frag, rb));
-+
-+ while(frag) {
-+ if (frag->rb.rb_left) {
-+ D2(printk(KERN_DEBUG "Going left from frag (%p) %d-%d\n",
-+ frag, frag->ofs, frag->ofs+frag->size));
-+ frag = frag_left(frag);
-+ continue;
-+ }
-+ if (frag->rb.rb_right) {
-+ D2(printk(KERN_DEBUG "Going right from frag (%p) %d-%d\n",
-+ frag, frag->ofs, frag->ofs+frag->size));
-+ frag = frag_right(frag);
-+ continue;
-+ }
-+
-+ D2(printk(KERN_DEBUG "jffs2_kill_fragtree: frag at 0x%x-0x%x: node %p, frags %d--\n",
-+ frag->ofs, frag->ofs+frag->size, frag->node,
-+ frag->node?frag->node->frags:0));
-+
-+ if (frag->node && !(--frag->node->frags)) {
-+ /* Not a hole, and it's the final remaining frag
-+ of this node. Free the node */
-+ if (c)
-+ jffs2_mark_node_obsolete(c, frag->node->raw);
-+
-+ jffs2_free_full_dnode(frag->node);
-+ }
-+ parent = frag_parent(frag);
-+ if (parent) {
-+ if (frag_left(parent) == frag)
-+ parent->rb.rb_left = NULL;
-+ else
-+ parent->rb.rb_right = NULL;
-+ }
-+
-+ jffs2_free_node_frag(frag);
-+ frag = parent;
-+
-+ cond_resched();
-+ }
-+}
-+
-+void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_node_frag *base)
-+{
-+ struct rb_node *parent = &base->rb;
-+ struct rb_node **link = &parent;
-+
-+ D2(printk(KERN_DEBUG "jffs2_fragtree_insert(%p; %d-%d, %p)\n", newfrag,
-+ newfrag->ofs, newfrag->ofs+newfrag->size, base));
-+
-+ while (*link) {
-+ parent = *link;
-+ base = rb_entry(parent, struct jffs2_node_frag, rb);
-+
-+ D2(printk(KERN_DEBUG "fragtree_insert considering frag at 0x%x\n", base->ofs));
-+ if (newfrag->ofs > base->ofs)
-+ link = &base->rb.rb_right;
-+ else if (newfrag->ofs < base->ofs)
-+ link = &base->rb.rb_left;
-+ else {
-+ printk(KERN_CRIT "Duplicate frag at %08x (%p,%p)\n", newfrag->ofs, newfrag, base);
-+ BUG();
-+ }
-+ }
-+
-+ rb_link_node(&newfrag->rb, &base->rb, link);
-+}
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/nodelist.h linux/fs/jffs2/nodelist.h
---- linux-mips-2.4.24-pre2/fs/jffs2/nodelist.h 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/nodelist.h 2004-11-17 18:17:59.000000000 +0100
-@@ -1,48 +1,35 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
-+#ifndef __JFFS2_NODELIST_H__
-+#define __JFFS2_NODELIST_H__
-+
- #include <linux/config.h>
- #include <linux/fs.h>
--
-+#include <linux/types.h>
-+#include <linux/jffs2.h>
- #include <linux/jffs2_fs_sb.h>
- #include <linux/jffs2_fs_i.h>
-
-+#ifdef __ECOS
-+#include "os-ecos.h"
-+#else
-+#include <linux/mtd/compatmac.h> /* For min/max in older kernels */
-+#include "os-linux.h"
-+#endif
-+
- #ifndef CONFIG_JFFS2_FS_DEBUG
--#define CONFIG_JFFS2_FS_DEBUG 2
-+#define CONFIG_JFFS2_FS_DEBUG 1
- #endif
-
- #if CONFIG_JFFS2_FS_DEBUG > 0
-@@ -71,17 +58,21 @@
- for this inode instead. The inode_cache will have NULL in the first
- word so you know when you've got there :) */
- struct jffs2_raw_node_ref *next_phys;
-- // __u32 ino;
-- __u32 flash_offset;
-- __u32 totlen;
--// __u16 nodetype;
-+ uint32_t flash_offset;
-+ uint32_t __totlen; /* This may die; use ref_totlen(c, jeb, ) below */
-+};
-
- /* flash_offset & 3 always has to be zero, because nodes are
- always aligned at 4 bytes. So we have a couple of extra bits
-- to play with. So we set the least significant bit to 1 to
-- signify that the node is obsoleted by later nodes.
-- */
--};
-+ to play with, which indicate the node's status; see below: */
-+#define REF_UNCHECKED 0 /* We haven't yet checked the CRC or built its inode */
-+#define REF_OBSOLETE 1 /* Obsolete, can be completely ignored */
-+#define REF_PRISTINE 2 /* Completely clean. GC without looking */
-+#define REF_NORMAL 3 /* Possibly overlapped. Read the page and write again on GC */
-+#define ref_flags(ref) ((ref)->flash_offset & 3)
-+#define ref_offset(ref) ((ref)->flash_offset & ~3)
-+#define ref_obsolete(ref) (((ref)->flash_offset & 3) == REF_OBSOLETE)
-+#define mark_ref_normal(ref) do { (ref)->flash_offset = ref_offset(ref) | REF_NORMAL; } while(0)
-
- /*
- Used for keeping track of deletion nodes &c, which can only be marked
-@@ -101,19 +92,35 @@
- a pointer to the first physical node which is part of this inode, too.
- */
- struct jffs2_inode_cache {
-- struct jffs2_scan_info *scan; /* Used during scan to hold
-- temporary lists of nodes, and later must be set to
-+ struct jffs2_full_dirent *scan_dents; /* Used during scan to hold
-+ temporary lists of dirents, and later must be set to
- NULL to mark the end of the raw_node_ref->next_in_ino
- chain. */
- struct jffs2_inode_cache *next;
- struct jffs2_raw_node_ref *nodes;
-- __u32 ino;
-+ uint32_t ino;
- int nlink;
-+ int state;
- };
-
-+/* Inode states for 'state' above. We need the 'GC' state to prevent
-+ someone from doing a read_inode() while we're moving a 'REF_PRISTINE'
-+ node without going through all the iget() nonsense */
-+#define INO_STATE_UNCHECKED 0 /* CRC checks not yet done */
-+#define INO_STATE_CHECKING 1 /* CRC checks in progress */
-+#define INO_STATE_PRESENT 2 /* In core */
-+#define INO_STATE_CHECKEDABSENT 3 /* Checked, cleared again */
-+#define INO_STATE_GC 4 /* GCing a 'pristine' node */
-+#define INO_STATE_READING 5 /* In read_inode() */
-+
-+#define INOCACHE_HASHSIZE 128
-+
- struct jffs2_scan_info {
- struct jffs2_full_dirent *dents;
- struct jffs2_tmp_dnode_info *tmpnodes;
-+ /* Latest i_size info */
-+ uint32_t version;
-+ uint32_t isize;
- };
- /*
- Larger representation of a raw node, kept in-core only when the
-@@ -123,9 +130,9 @@
- struct jffs2_full_dnode
- {
- struct jffs2_raw_node_ref *raw;
-- __u32 ofs; /* Don't really need this, but optimisation */
-- __u32 size;
-- __u32 frags; /* Number of fragments which currently refer
-+ uint32_t ofs; /* Don't really need this, but optimisation */
-+ uint32_t size;
-+ uint32_t frags; /* Number of fragments which currently refer
- to this node. When this reaches zero,
- the node is obsolete.
- */
-@@ -140,15 +147,15 @@
- {
- struct jffs2_tmp_dnode_info *next;
- struct jffs2_full_dnode *fn;
-- __u32 version;
-+ uint32_t version;
- };
-
- struct jffs2_full_dirent
- {
- struct jffs2_raw_node_ref *raw;
- struct jffs2_full_dirent *next;
-- __u32 version;
-- __u32 ino; /* == zero for unlink */
-+ uint32_t version;
-+ uint32_t ino; /* == zero for unlink */
- unsigned int nhash;
- unsigned char type;
- unsigned char name[0];
-@@ -159,21 +166,23 @@
- */
- struct jffs2_node_frag
- {
-- struct jffs2_node_frag *next;
-+ struct rb_node rb;
- struct jffs2_full_dnode *node; /* NULL for holes */
-- __u32 size;
-- __u32 ofs; /* Don't really need this, but optimisation */
-+ uint32_t size;
-+ uint32_t ofs; /* Don't really need this, but optimisation */
- };
-
- struct jffs2_eraseblock
- {
- struct list_head list;
- int bad_count;
-- __u32 offset; /* of this block in the MTD */
-+ uint32_t offset; /* of this block in the MTD */
-
-- __u32 used_size;
-- __u32 dirty_size;
-- __u32 free_size; /* Note that sector_size - free_size
-+ uint32_t unchecked_size;
-+ uint32_t used_size;
-+ uint32_t dirty_size;
-+ uint32_t wasted_size;
-+ uint32_t free_size; /* Note that sector_size - free_size
- is the address of the first free space */
- struct jffs2_raw_node_ref *first_node;
- struct jffs2_raw_node_ref *last_node;
-@@ -190,45 +199,134 @@
- };
-
- #define ACCT_SANITY_CHECK(c, jeb) do { \
-- if (jeb->used_size + jeb->dirty_size + jeb->free_size != c->sector_size) { \
-- printk(KERN_NOTICE "Eeep. Space accounting for block at 0x%08x is screwed\n", jeb->offset); \
-- printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x != total %08x\n", \
-- jeb->free_size, jeb->dirty_size, jeb->used_size, c->sector_size); \
-+ struct jffs2_eraseblock *___j = jeb; \
-+ if ((___j) && ___j->used_size + ___j->dirty_size + ___j->free_size + ___j->wasted_size + ___j->unchecked_size != c->sector_size) { \
-+ printk(KERN_NOTICE "Eeep. Space accounting for block at 0x%08x is screwed\n", ___j->offset); \
-+ printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x + wasted %08x + unchecked %08x != total %08x\n", \
-+ ___j->free_size, ___j->dirty_size, ___j->used_size, ___j->wasted_size, ___j->unchecked_size, c->sector_size); \
- BUG(); \
- } \
-- if (c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size != c->flash_size) { \
-+ if (c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size + c->wasted_size + c->unchecked_size != c->flash_size) { \
- printk(KERN_NOTICE "Eeep. Space accounting superblock info is screwed\n"); \
-- printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x + erasing %08x + bad %08x != total %08x\n", \
-- c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size, c->flash_size); \
-+ printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x + erasing %08x + bad %08x + wasted %08x + unchecked %08x != total %08x\n", \
-+ c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size, c->wasted_size, c->unchecked_size, c->flash_size); \
- BUG(); \
- } \
- } while(0)
-
-+static inline void paranoia_failed_dump(struct jffs2_eraseblock *jeb)
-+{
-+ struct jffs2_raw_node_ref *ref;
-+ int i=0;
-+
-+ printk(KERN_NOTICE);
-+ for (ref = jeb->first_node; ref; ref = ref->next_phys) {
-+ printk("%08x->", ref_offset(ref));
-+ if (++i == 8) {
-+ i = 0;
-+ printk("\n" KERN_NOTICE);
-+ }
-+ }
-+ printk("\n");
-+}
-+
-+
- #define ACCT_PARANOIA_CHECK(jeb) do { \
-- __u32 my_used_size = 0; \
-+ uint32_t my_used_size = 0; \
-+ uint32_t my_unchecked_size = 0; \
- struct jffs2_raw_node_ref *ref2 = jeb->first_node; \
- while (ref2) { \
-- if (!(ref2->flash_offset & 1)) \
-- my_used_size += ref2->totlen; \
-+ if (unlikely(ref2->flash_offset < jeb->offset || \
-+ ref2->flash_offset > jeb->offset + c->sector_size)) { \
-+ printk(KERN_NOTICE "Node %08x shouldn't be in block at %08x!\n", \
-+ ref_offset(ref2), jeb->offset); \
-+ paranoia_failed_dump(jeb); \
-+ BUG(); \
-+ } \
-+ if (ref_flags(ref2) == REF_UNCHECKED) \
-+ my_unchecked_size += ref_totlen(c, jeb, ref2); \
-+ else if (!ref_obsolete(ref2)) \
-+ my_used_size += ref_totlen(c, jeb, ref2); \
-+ if (unlikely((!ref2->next_phys) != (ref2 == jeb->last_node))) { \
-+ printk("ref for node at %p (phys %08x) has next_phys->%p (%08x), last_node->%p (phys %08x)\n", \
-+ ref2, ref_offset(ref2), ref2->next_phys, ref_offset(ref2->next_phys), \
-+ jeb->last_node, ref_offset(jeb->last_node)); \
-+ paranoia_failed_dump(jeb); \
-+ BUG(); \
-+ } \
- ref2 = ref2->next_phys; \
- } \
- if (my_used_size != jeb->used_size) { \
- printk(KERN_NOTICE "Calculated used size %08x != stored used size %08x\n", my_used_size, jeb->used_size); \
- BUG(); \
- } \
-+ if (my_unchecked_size != jeb->unchecked_size) { \
-+ printk(KERN_NOTICE "Calculated unchecked size %08x != stored unchecked size %08x\n", my_unchecked_size, jeb->unchecked_size); \
-+ BUG(); \
-+ } \
- } while(0)
-
-+/* Calculate totlen from surrounding nodes or eraseblock */
-+static inline uint32_t __ref_totlen(struct jffs2_sb_info *c,
-+ struct jffs2_eraseblock *jeb,
-+ struct jffs2_raw_node_ref *ref)
-+{
-+ uint32_t ref_end;
-+
-+ if (ref->next_phys)
-+ ref_end = ref_offset(ref->next_phys);
-+ else {
-+ if (!jeb)
-+ jeb = &c->blocks[ref->flash_offset / c->sector_size];
-+
-+ /* Last node in block. Use free_space */
-+ BUG_ON(ref != jeb->last_node);
-+ ref_end = jeb->offset + c->sector_size - jeb->free_size;
-+ }
-+ return ref_end - ref_offset(ref);
-+}
-+
-+static inline uint32_t ref_totlen(struct jffs2_sb_info *c,
-+ struct jffs2_eraseblock *jeb,
-+ struct jffs2_raw_node_ref *ref)
-+{
-+ uint32_t ret;
-+
-+ D1(if (jeb && jeb != &c->blocks[ref->flash_offset / c->sector_size]) {
-+ printk(KERN_CRIT "ref_totlen called with wrong block -- at 0x%08x instead of 0x%08x; ref 0x%08x\n",
-+ jeb->offset, c->blocks[ref->flash_offset / c->sector_size].offset, ref_offset(ref));
-+ BUG();
-+ })
-+
-+#if 1
-+ ret = ref->__totlen;
-+#else
-+ /* This doesn't actually work yet */
-+ ret = __ref_totlen(c, jeb, ref);
-+ if (ret != ref->__totlen) {
-+ printk(KERN_CRIT "Totlen for ref at %p (0x%08x-0x%08x) miscalculated as 0x%x instead of %x\n",
-+ ref, ref_offset(ref), ref_offset(ref)+ref->__totlen,
-+ ret, ref->__totlen);
-+ if (!jeb)
-+ jeb = &c->blocks[ref->flash_offset / c->sector_size];
-+ paranoia_failed_dump(jeb);
-+ BUG();
-+ }
-+#endif
-+ return ret;
-+}
-+
-+
- #define ALLOC_NORMAL 0 /* Normal allocation */
- #define ALLOC_DELETION 1 /* Deletion node. Best to allow it */
- #define ALLOC_GC 2 /* Space requested for GC. Give it or die */
-+#define ALLOC_NORETRY 3 /* For jffs2_write_dnode: On failure, return -EAGAIN instead of retrying */
-
--#define JFFS2_RESERVED_BLOCKS_BASE 3 /* Number of free blocks there must be before we... */
--#define JFFS2_RESERVED_BLOCKS_WRITE (JFFS2_RESERVED_BLOCKS_BASE + 2) /* ... allow a normal filesystem write */
--#define JFFS2_RESERVED_BLOCKS_DELETION (JFFS2_RESERVED_BLOCKS_BASE + 1) /* ... allow a normal filesystem deletion */
--#define JFFS2_RESERVED_BLOCKS_GCTRIGGER (JFFS2_RESERVED_BLOCKS_BASE + 3) /* ... wake up the GC thread */
--#define JFFS2_RESERVED_BLOCKS_GCBAD (JFFS2_RESERVED_BLOCKS_BASE + 1) /* ... pick a block from the bad_list to GC */
--#define JFFS2_RESERVED_BLOCKS_GCMERGE (JFFS2_RESERVED_BLOCKS_BASE) /* ... merge pages when garbage collecting */
-+/* How much dirty space before it goes on the very_dirty_list */
-+#define VERYDIRTY(c, size) ((size) >= ((c)->sector_size / 2))
-
-+/* check if dirty space is more than 255 Byte */
-+#define ISDIRTY(size) ((size) > sizeof (struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN)
-
- #define PAD(x) (((x)+3)&~3)
-
-@@ -241,43 +339,75 @@
- return ((struct jffs2_inode_cache *)raw);
- }
-
-+static inline struct jffs2_node_frag *frag_first(struct rb_root *root)
-+{
-+ struct rb_node *node = root->rb_node;
-+
-+ if (!node)
-+ return NULL;
-+ while(node->rb_left)
-+ node = node->rb_left;
-+ return rb_entry(node, struct jffs2_node_frag, rb);
-+}
-+#define rb_parent(rb) ((rb)->rb_parent)
-+#define frag_next(frag) rb_entry(rb_next(&(frag)->rb), struct jffs2_node_frag, rb)
-+#define frag_prev(frag) rb_entry(rb_prev(&(frag)->rb), struct jffs2_node_frag, rb)
-+#define frag_parent(frag) rb_entry(rb_parent(&(frag)->rb), struct jffs2_node_frag, rb)
-+#define frag_left(frag) rb_entry((frag)->rb.rb_left, struct jffs2_node_frag, rb)
-+#define frag_right(frag) rb_entry((frag)->rb.rb_right, struct jffs2_node_frag, rb)
-+#define frag_erase(frag, list) rb_erase(&frag->rb, list);
-+
- /* nodelist.c */
- D1(void jffs2_print_frag_list(struct jffs2_inode_info *f));
- void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list);
--void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct jffs2_tmp_dnode_info **list);
- int jffs2_get_inode_nodes(struct jffs2_sb_info *c, ino_t ino, struct jffs2_inode_info *f,
- struct jffs2_tmp_dnode_info **tnp, struct jffs2_full_dirent **fdp,
-- __u32 *highest_version, __u32 *latest_mctime,
-- __u32 *mctime_ver);
-+ uint32_t *highest_version, uint32_t *latest_mctime,
-+ uint32_t *mctime_ver);
-+void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state);
- struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino);
- void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new);
- void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old);
- void jffs2_free_ino_caches(struct jffs2_sb_info *c);
- void jffs2_free_raw_node_refs(struct jffs2_sb_info *c);
-+struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset);
-+void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c_delete);
-+void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_node_frag *base);
-+struct rb_node *rb_next(struct rb_node *);
-+struct rb_node *rb_prev(struct rb_node *);
-+void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root);
-
- /* nodemgmt.c */
--int jffs2_reserve_space(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len, int prio);
--int jffs2_reserve_space_gc(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len);
--int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new, __u32 len, int dirty);
-+int jffs2_thread_should_wake(struct jffs2_sb_info *c);
-+int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, int prio);
-+int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len);
-+int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new);
- void jffs2_complete_reservation(struct jffs2_sb_info *c);
- void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *raw);
-+void jffs2_dump_block_lists(struct jffs2_sb_info *c);
-
- /* write.c */
--struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri);
--struct jffs2_full_dnode *jffs2_write_dnode(struct inode *inode, struct jffs2_raw_inode *ri, const unsigned char *data, __u32 datalen, __u32 flash_ofs, __u32 *writelen);
--struct jffs2_full_dirent *jffs2_write_dirent(struct inode *inode, struct jffs2_raw_dirent *rd, const unsigned char *name, __u32 namelen, __u32 flash_ofs, __u32 *writelen);
-+int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri);
-+
-+struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode);
-+struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_dirent *rd, const unsigned char *name, uint32_t namelen, uint32_t flash_ofs, int alloc_mode);
-+int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
-+ struct jffs2_raw_inode *ri, unsigned char *buf,
-+ uint32_t offset, uint32_t writelen, uint32_t *retlen);
-+int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen);
-+int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, const char *name, int namelen, struct jffs2_inode_info *dead_f);
-+int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen);
-+
-
- /* readinode.c */
--void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct jffs2_node_frag **list, __u32 size);
--int jffs2_add_full_dnode_to_fraglist(struct jffs2_sb_info *c, struct jffs2_node_frag **list, struct jffs2_full_dnode *fn);
-+void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size);
- int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn);
--void jffs2_read_inode (struct inode *);
--void jffs2_clear_inode (struct inode *);
-+int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
-+ uint32_t ino, struct jffs2_raw_inode *latest_node);
-+int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
-+void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f);
-
- /* malloc.c */
--void jffs2_free_tmp_dnode_info_list(struct jffs2_tmp_dnode_info *tn);
--void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd);
--
- int jffs2_create_slab_caches(void);
- void jffs2_destroy_slab_caches(void);
-
-@@ -301,54 +431,41 @@
- /* gc.c */
- int jffs2_garbage_collect_pass(struct jffs2_sb_info *c);
-
--/* background.c */
--int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c);
--void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c);
--void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c);
--
--/* dir.c */
--extern struct file_operations jffs2_dir_operations;
--extern struct inode_operations jffs2_dir_inode_operations;
--
--/* file.c */
--extern struct file_operations jffs2_file_operations;
--extern struct inode_operations jffs2_file_inode_operations;
--extern struct address_space_operations jffs2_file_address_operations;
--int jffs2_null_fsync(struct file *, struct dentry *, int);
--int jffs2_setattr (struct dentry *dentry, struct iattr *iattr);
--int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg);
--int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg);
--int jffs2_readpage (struct file *, struct page *);
--int jffs2_prepare_write (struct file *, struct page *, unsigned, unsigned);
--int jffs2_commit_write (struct file *, struct page *, unsigned, unsigned);
--
--/* ioctl.c */
--int jffs2_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
--
- /* read.c */
- int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_full_dnode *fd, unsigned char *buf, int ofs, int len);
-+int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
-+ unsigned char *buf, uint32_t offset, uint32_t len);
-+char *jffs2_getlink(struct jffs2_sb_info *c, struct jffs2_inode_info *f);
-
- /* compr.c */
--unsigned char jffs2_compress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 *datalen, __u32 *cdatalen);
-+unsigned char jffs2_compress(unsigned char *data_in, unsigned char **cpage_out,
-+ uint32_t *datalen, uint32_t *cdatalen);
-+void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig);
- int jffs2_decompress(unsigned char comprtype, unsigned char *cdata_in,
-- unsigned char *data_out, __u32 cdatalen, __u32 datalen);
-+ unsigned char *data_out, uint32_t cdatalen, uint32_t datalen);
-
- /* scan.c */
- int jffs2_scan_medium(struct jffs2_sb_info *c);
-+void jffs2_rotate_lists(struct jffs2_sb_info *c);
-
- /* build.c */
--int jffs2_build_filesystem(struct jffs2_sb_info *c);
--
--/* symlink.c */
--extern struct inode_operations jffs2_symlink_inode_operations;
-+int jffs2_do_mount_fs(struct jffs2_sb_info *c);
-
- /* erase.c */
- void jffs2_erase_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
--void jffs2_erase_pending_blocks(struct jffs2_sb_info *c);
--void jffs2_mark_erased_blocks(struct jffs2_sb_info *c);
--void jffs2_erase_pending_trigger(struct jffs2_sb_info *c);
-+void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count);
-+
-+#ifdef CONFIG_JFFS2_FS_NAND
-+/* wbuf.c */
-+int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino);
-+int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c);
-+int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+int jffs2_nand_read_failcnt(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+#endif
-
- /* compr_zlib.c */
- int jffs2_zlib_init(void);
- void jffs2_zlib_exit(void);
-+
-+#endif /* __JFFS2_NODELIST_H__ */
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/nodemgmt.c linux/fs/jffs2/nodemgmt.c
---- linux-mips-2.4.24-pre2/fs/jffs2/nodemgmt.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/nodemgmt.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,45 +1,21 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/kernel.h>
- #include <linux/slab.h>
--#include <linux/jffs2.h>
- #include <linux/mtd/mtd.h>
--#include <linux/interrupt.h>
-+#include <linux/compiler.h>
-+#include <linux/sched.h> /* For cond_resched() */
- #include "nodelist.h"
-
- /**
-@@ -62,53 +38,95 @@
- * for the requested allocation.
- */
-
--static int jffs2_do_reserve_space(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len);
-+static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len);
-
--int jffs2_reserve_space(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len, int prio)
-+int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, int prio)
- {
- int ret = -EAGAIN;
-- int blocksneeded = JFFS2_RESERVED_BLOCKS_WRITE;
-+ int blocksneeded = c->resv_blocks_write;
- /* align it */
- minsize = PAD(minsize);
-
-- if (prio == ALLOC_DELETION)
-- blocksneeded = JFFS2_RESERVED_BLOCKS_DELETION;
--
- D1(printk(KERN_DEBUG "jffs2_reserve_space(): Requested 0x%x bytes\n", minsize));
- down(&c->alloc_sem);
-
- D1(printk(KERN_DEBUG "jffs2_reserve_space(): alloc sem got\n"));
-
-- spin_lock_bh(&c->erase_completion_lock);
-+ spin_lock(&c->erase_completion_lock);
-
-- /* this needs a little more thought */
-+ /* this needs a little more thought (true <tglx> :)) */
- while(ret == -EAGAIN) {
- while(c->nr_free_blocks + c->nr_erasing_blocks < blocksneeded) {
- int ret;
-+ uint32_t dirty, avail;
-+
-+ /* calculate real dirty size
-+ * dirty_size contains blocks on erase_pending_list
-+ * those blocks are counted in c->nr_erasing_blocks.
-+ * If one block is actually erased, it is not longer counted as dirty_space
-+ * but it is counted in c->nr_erasing_blocks, so we add it and subtract it
-+ * with c->nr_erasing_blocks * c->sector_size again.
-+ * Blocks on erasable_list are counted as dirty_size, but not in c->nr_erasing_blocks
-+ * This helps us to force gc and pick eventually a clean block to spread the load.
-+ * We add unchecked_size here, as we hopefully will find some space to use.
-+ * This will affect the sum only once, as gc first finishes checking
-+ * of nodes.
-+ */
-+ dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size + c->unchecked_size;
-+ if (dirty < c->nospc_dirty_size) {
-+ if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) {
-+ printk(KERN_NOTICE "jffs2_reserve_space(): Low on dirty space to GC, but it's a deletion. Allowing...\n");
-+ break;
-+ }
-+ D1(printk(KERN_DEBUG "dirty size 0x%08x + unchecked_size 0x%08x < nospc_dirty_size 0x%08x, returning -ENOSPC\n",
-+ dirty, c->unchecked_size, c->sector_size));
-+
-+ spin_unlock(&c->erase_completion_lock);
-+ up(&c->alloc_sem);
-+ return -ENOSPC;
-+ }
-
-+ /* Calc possibly available space. Possibly available means that we
-+ * don't know, if unchecked size contains obsoleted nodes, which could give us some
-+ * more usable space. This will affect the sum only once, as gc first finishes checking
-+ * of nodes.
-+ + Return -ENOSPC, if the maximum possibly available space is less or equal than
-+ * blocksneeded * sector_size.
-+ * This blocks endless gc looping on a filesystem, which is nearly full, even if
-+ * the check above passes.
-+ */
-+ avail = c->free_size + c->dirty_size + c->erasing_size + c->unchecked_size;
-+ if ( (avail / c->sector_size) <= blocksneeded) {
-+ if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) {
-+ printk(KERN_NOTICE "jffs2_reserve_space(): Low on possibly available space, but it's a deletion. Allowing...\n");
-+ break;
-+ }
-+
-+ D1(printk(KERN_DEBUG "max. available size 0x%08x < blocksneeded * sector_size 0x%08x, returning -ENOSPC\n",
-+ avail, blocksneeded * c->sector_size));
-+ spin_unlock(&c->erase_completion_lock);
- up(&c->alloc_sem);
-- if (c->dirty_size < c->sector_size) {
-- D1(printk(KERN_DEBUG "Short on space, but total dirty size 0x%08x < sector size 0x%08x, so -ENOSPC\n", c->dirty_size, c->sector_size));
-- spin_unlock_bh(&c->erase_completion_lock);
- return -ENOSPC;
- }
-- D1(printk(KERN_DEBUG "Triggering GC pass. nr_free_blocks %d, nr_erasing_blocks %d, free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x, erasing_size 0x%08x, bad_size 0x%08x (total 0x%08x of 0x%08x)\n",
-- c->nr_free_blocks, c->nr_erasing_blocks, c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size,
-- c->free_size + c->dirty_size + c->used_size + c->erasing_size + c->bad_size, c->flash_size));
-- spin_unlock_bh(&c->erase_completion_lock);
-+
-+ up(&c->alloc_sem);
-+
-+ D1(printk(KERN_DEBUG "Triggering GC pass. nr_free_blocks %d, nr_erasing_blocks %d, free_size 0x%08x, dirty_size 0x%08x, wasted_size 0x%08x, used_size 0x%08x, erasing_size 0x%08x, bad_size 0x%08x (total 0x%08x of 0x%08x)\n",
-+ c->nr_free_blocks, c->nr_erasing_blocks, c->free_size, c->dirty_size, c->wasted_size, c->used_size, c->erasing_size, c->bad_size,
-+ c->free_size + c->dirty_size + c->wasted_size + c->used_size + c->erasing_size + c->bad_size, c->flash_size));
-+ spin_unlock(&c->erase_completion_lock);
-
- ret = jffs2_garbage_collect_pass(c);
- if (ret)
- return ret;
-
-- if (current->need_resched)
-- schedule();
-+ cond_resched();
-
- if (signal_pending(current))
- return -EINTR;
-
- down(&c->alloc_sem);
-- spin_lock_bh(&c->erase_completion_lock);
-+ spin_lock(&c->erase_completion_lock);
- }
-
- ret = jffs2_do_reserve_space(c, minsize, ofs, len);
-@@ -116,45 +134,72 @@
- D1(printk(KERN_DEBUG "jffs2_reserve_space: ret is %d\n", ret));
- }
- }
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
- if (ret)
- up(&c->alloc_sem);
- return ret;
- }
-
--int jffs2_reserve_space_gc(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len)
-+int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len)
- {
- int ret = -EAGAIN;
- minsize = PAD(minsize);
-
- D1(printk(KERN_DEBUG "jffs2_reserve_space_gc(): Requested 0x%x bytes\n", minsize));
-
-- spin_lock_bh(&c->erase_completion_lock);
-+ spin_lock(&c->erase_completion_lock);
- while(ret == -EAGAIN) {
- ret = jffs2_do_reserve_space(c, minsize, ofs, len);
- if (ret) {
- D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret));
- }
- }
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
- return ret;
- }
-
- /* Called with alloc sem _and_ erase_completion_lock */
--static int jffs2_do_reserve_space(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len)
-+static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len)
- {
- struct jffs2_eraseblock *jeb = c->nextblock;
-
- restart:
- if (jeb && minsize > jeb->free_size) {
- /* Skip the end of this block and file it as having some dirty space */
-- c->dirty_size += jeb->free_size;
-+ /* If there's a pending write to it, flush now */
-+ if (jffs2_wbuf_dirty(c)) {
-+ spin_unlock(&c->erase_completion_lock);
-+ D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Flushing write buffer\n"));
-+ jffs2_flush_wbuf_pad(c);
-+ spin_lock(&c->erase_completion_lock);
-+ jeb = c->nextblock;
-+ goto restart;
-+ }
-+ c->wasted_size += jeb->free_size;
- c->free_size -= jeb->free_size;
-- jeb->dirty_size += jeb->free_size;
-+ jeb->wasted_size += jeb->free_size;
- jeb->free_size = 0;
-+
-+ /* Check, if we have a dirty block now, or if it was dirty already */
-+ if (ISDIRTY (jeb->wasted_size + jeb->dirty_size)) {
-+ c->dirty_size += jeb->wasted_size;
-+ c->wasted_size -= jeb->wasted_size;
-+ jeb->dirty_size += jeb->wasted_size;
-+ jeb->wasted_size = 0;
-+ if (VERYDIRTY(c, jeb->dirty_size)) {
-+ D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to very_dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
-+ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
-+ list_add_tail(&jeb->list, &c->very_dirty_list);
-+ } else {
- D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
- jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
- list_add_tail(&jeb->list, &c->dirty_list);
-+ }
-+ } else {
-+ D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
-+ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
-+ list_add_tail(&jeb->list, &c->clean_list);
-+ }
- c->nextblock = jeb = NULL;
- }
-
-@@ -164,33 +209,44 @@
-
- if (list_empty(&c->free_list)) {
-
-- DECLARE_WAITQUEUE(wait, current);
-+ if (!c->nr_erasing_blocks &&
-+ !list_empty(&c->erasable_list)) {
-+ struct jffs2_eraseblock *ejeb;
-+
-+ ejeb = list_entry(c->erasable_list.next, struct jffs2_eraseblock, list);
-+ list_del(&ejeb->list);
-+ list_add_tail(&ejeb->list, &c->erase_pending_list);
-+ c->nr_erasing_blocks++;
-+ jffs2_erase_pending_trigger(c);
-+ D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Triggering erase of erasable block at 0x%08x\n",
-+ ejeb->offset));
-+ }
-+
-+ if (!c->nr_erasing_blocks &&
-+ !list_empty(&c->erasable_pending_wbuf_list)) {
-+ D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Flushing write buffer\n"));
-+ /* c->nextblock is NULL, no update to c->nextblock allowed */
-+ spin_unlock(&c->erase_completion_lock);
-+ jffs2_flush_wbuf_pad(c);
-+ spin_lock(&c->erase_completion_lock);
-+ /* Have another go. It'll be on the erasable_list now */
-+ return -EAGAIN;
-+ }
-
- if (!c->nr_erasing_blocks) {
--// if (list_empty(&c->erasing_list) && list_empty(&c->erase_pending_list) && list_empty(c->erase_complete_list)) {
- /* Ouch. We're in GC, or we wouldn't have got here.
- And there's no space left. At all. */
-- printk(KERN_CRIT "Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasingempty: %s, erasependingempty: %s)\n",
-- c->nr_erasing_blocks, c->nr_free_blocks, list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no");
-+ printk(KERN_CRIT "Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasableempty: %s, erasingempty: %s, erasependingempty: %s)\n",
-+ c->nr_erasing_blocks, c->nr_free_blocks, list_empty(&c->erasable_list)?"yes":"no",
-+ list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no");
- return -ENOSPC;
- }
-- /* Make sure this can't deadlock. Someone has to start the erases
-- of erase_pending blocks */
-- set_current_state(TASK_INTERRUPTIBLE);
-- add_wait_queue(&c->erase_wait, &wait);
-- D1(printk(KERN_DEBUG "Waiting for erases to complete. erasing_blocks is %d. (erasingempty: %s, erasependingempty: %s)\n",
-- c->nr_erasing_blocks, list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no"));
-- if (!list_empty(&c->erase_pending_list)) {
-- D1(printk(KERN_DEBUG "Triggering pending erases\n"));
-- jffs2_erase_pending_trigger(c);
-- }
-- spin_unlock_bh(&c->erase_completion_lock);
-- schedule();
-- remove_wait_queue(&c->erase_wait, &wait);
-- spin_lock_bh(&c->erase_completion_lock);
-- if (signal_pending(current)) {
-- return -EINTR;
-- }
-+
-+ spin_unlock(&c->erase_completion_lock);
-+ /* Don't wait for it; just erase one right now */
-+ jffs2_erase_pending_blocks(c, 1);
-+ spin_lock(&c->erase_completion_lock);
-+
- /* An erase may have failed, decreasing the
- amount of free space available. So we must
- restart from the beginning */
-@@ -201,7 +257,8 @@
- list_del(next);
- c->nextblock = jeb = list_entry(next, struct jffs2_eraseblock, list);
- c->nr_free_blocks--;
-- if (jeb->free_size != c->sector_size - sizeof(struct jffs2_unknown_node)) {
-+
-+ if (jeb->free_size != c->sector_size - c->cleanmarker_size) {
- printk(KERN_WARNING "Eep. Block 0x%08x taken from free_list had free_size of 0x%08x!!\n", jeb->offset, jeb->free_size);
- goto restart;
- }
-@@ -210,6 +267,20 @@
- enough space */
- *ofs = jeb->offset + (c->sector_size - jeb->free_size);
- *len = jeb->free_size;
-+
-+ if (c->cleanmarker_size && jeb->used_size == c->cleanmarker_size &&
-+ !jeb->first_node->next_in_ino) {
-+ /* Only node in it beforehand was a CLEANMARKER node (we think).
-+ So mark it obsolete now that there's going to be another node
-+ in the block. This will reduce used_size to zero but We've
-+ already set c->nextblock so that jffs2_mark_node_obsolete()
-+ won't try to refile it to the dirty_list.
-+ */
-+ spin_unlock(&c->erase_completion_lock);
-+ jffs2_mark_node_obsolete(c, jeb->first_node);
-+ spin_lock(&c->erase_completion_lock);
-+ }
-+
- D1(printk(KERN_DEBUG "jffs2_do_reserve_space(): Giving 0x%x bytes at 0x%x\n", *len, *ofs));
- return 0;
- }
-@@ -217,9 +288,9 @@
- /**
- * jffs2_add_physical_node_ref - add a physical node reference to the list
- * @c: superblock info
-- * @ofs: physical location of this physical node
-+ * @new: new node reference to add
- * @len: length of this physical node
-- * @ino: inode number with which this physical node is associated
-+ * @dirty: dirty flag for new node
- *
- * Should only be used to report nodes for which space has been allocated
- * by jffs2_reserve_space.
-@@ -227,47 +298,58 @@
- * Must be called with the alloc_sem held.
- */
-
--int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new, __u32 len, int dirty)
-+int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new)
- {
- struct jffs2_eraseblock *jeb;
-+ uint32_t len;
-+
-+ jeb = &c->blocks[new->flash_offset / c->sector_size];
-+ len = ref_totlen(c, jeb, new);
-
-- len = PAD(len);
-- jeb = &c->blocks[(new->flash_offset & ~3) / c->sector_size];
-- D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x, size 0x%x\n", new->flash_offset & ~3, len));
-+ D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n", ref_offset(new), ref_flags(new), len));
- #if 1
-- if (jeb != c->nextblock || (new->flash_offset & ~3) != jeb->offset + (c->sector_size - jeb->free_size)) {
-+ if (jeb != c->nextblock || (ref_offset(new)) != jeb->offset + (c->sector_size - jeb->free_size)) {
- printk(KERN_WARNING "argh. node added in wrong place\n");
- jffs2_free_raw_node_ref(new);
- return -EINVAL;
- }
- #endif
-+ spin_lock(&c->erase_completion_lock);
-+
- if (!jeb->first_node)
- jeb->first_node = new;
- if (jeb->last_node)
- jeb->last_node->next_phys = new;
- jeb->last_node = new;
-
-- spin_lock_bh(&c->erase_completion_lock);
- jeb->free_size -= len;
- c->free_size -= len;
-- if (dirty) {
-- new->flash_offset |= 1;
-+ if (ref_obsolete(new)) {
- jeb->dirty_size += len;
- c->dirty_size += len;
- } else {
- jeb->used_size += len;
- c->used_size += len;
- }
-- spin_unlock_bh(&c->erase_completion_lock);
-+
- if (!jeb->free_size && !jeb->dirty_size) {
- /* If it lives on the dirty_list, jffs2_reserve_space will put it there */
- D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
- jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
-+ if (jffs2_wbuf_dirty(c)) {
-+ /* Flush the last write in the block if it's outstanding */
-+ spin_unlock(&c->erase_completion_lock);
-+ jffs2_flush_wbuf_pad(c);
-+ spin_lock(&c->erase_completion_lock);
-+ }
-+
- list_add_tail(&jeb->list, &c->clean_list);
- c->nextblock = NULL;
- }
- ACCT_SANITY_CHECK(c,jeb);
-- ACCT_PARANOIA_CHECK(jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+
-+ spin_unlock(&c->erase_completion_lock);
-
- return 0;
- }
-@@ -280,20 +362,34 @@
- up(&c->alloc_sem);
- }
-
-+static inline int on_list(struct list_head *obj, struct list_head *head)
-+{
-+ struct list_head *this;
-+
-+ list_for_each(this, head) {
-+ if (this == obj) {
-+ D1(printk("%p is on list at %p\n", obj, head));
-+ return 1;
-+
-+ }
-+ }
-+ return 0;
-+}
-+
- void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref)
- {
- struct jffs2_eraseblock *jeb;
- int blocknr;
- struct jffs2_unknown_node n;
-- int ret;
-- ssize_t retlen;
-+ int ret, addedsize;
-+ size_t retlen;
-
- if(!ref) {
- printk(KERN_NOTICE "EEEEEK. jffs2_mark_node_obsolete called with NULL node\n");
- return;
- }
-- if (ref->flash_offset & 1) {
-- D1(printk(KERN_DEBUG "jffs2_mark_node_obsolete called with already obsolete node at 0x%08x\n", ref->flash_offset &~3));
-+ if (ref_obsolete(ref)) {
-+ D1(printk(KERN_DEBUG "jffs2_mark_node_obsolete called with already obsolete node at 0x%08x\n", ref_offset(ref)));
- return;
- }
- blocknr = ref->flash_offset / c->sector_size;
-@@ -302,22 +398,63 @@
- BUG();
- }
- jeb = &c->blocks[blocknr];
-- if (jeb->used_size < ref->totlen) {
-+
-+ spin_lock(&c->erase_completion_lock);
-+
-+ if (ref_flags(ref) == REF_UNCHECKED) {
-+ D1(if (unlikely(jeb->unchecked_size < ref_totlen(c, jeb, ref))) {
-+ printk(KERN_NOTICE "raw unchecked node of size 0x%08x freed from erase block %d at 0x%08x, but unchecked_size was already 0x%08x\n",
-+ ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size);
-+ BUG();
-+ })
-+ D1(printk(KERN_DEBUG "Obsoleting previously unchecked node at 0x%08x of len %x: ", ref_offset(ref), ref_totlen(c, jeb, ref)));
-+ jeb->unchecked_size -= ref_totlen(c, jeb, ref);
-+ c->unchecked_size -= ref_totlen(c, jeb, ref);
-+ } else {
-+ D1(if (unlikely(jeb->used_size < ref_totlen(c, jeb, ref))) {
- printk(KERN_NOTICE "raw node of size 0x%08x freed from erase block %d at 0x%08x, but used_size was already 0x%08x\n",
-- ref->totlen, blocknr, ref->flash_offset, jeb->used_size);
-+ ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size);
- BUG();
-+ })
-+ D1(printk(KERN_DEBUG "Obsoleting node at 0x%08x of len %x: ", ref_offset(ref), ref_totlen(c, jeb, ref)));
-+ jeb->used_size -= ref_totlen(c, jeb, ref);
-+ c->used_size -= ref_totlen(c, jeb, ref);
-+ }
-+
-+ // Take care, that wasted size is taken into concern
-+ if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + ref_totlen(c, jeb, ref))) && jeb != c->nextblock) {
-+ D1(printk("Dirtying\n"));
-+ addedsize = ref_totlen(c, jeb, ref);
-+ jeb->dirty_size += ref_totlen(c, jeb, ref);
-+ c->dirty_size += ref_totlen(c, jeb, ref);
-+
-+ /* Convert wasted space to dirty, if not a bad block */
-+ if (jeb->wasted_size) {
-+ if (on_list(&jeb->list, &c->bad_used_list)) {
-+ D1(printk(KERN_DEBUG "Leaving block at %08x on the bad_used_list\n",
-+ jeb->offset));
-+ addedsize = 0; /* To fool the refiling code later */
-+ } else {
-+ D1(printk(KERN_DEBUG "Converting %d bytes of wasted space to dirty in block at %08x\n",
-+ jeb->wasted_size, jeb->offset));
-+ addedsize += jeb->wasted_size;
-+ jeb->dirty_size += jeb->wasted_size;
-+ c->dirty_size += jeb->wasted_size;
-+ c->wasted_size -= jeb->wasted_size;
-+ jeb->wasted_size = 0;
- }
--
-- spin_lock_bh(&c->erase_completion_lock);
-- jeb->used_size -= ref->totlen;
-- jeb->dirty_size += ref->totlen;
-- c->used_size -= ref->totlen;
-- c->dirty_size += ref->totlen;
-- ref->flash_offset |= 1;
-+ }
-+ } else {
-+ D1(printk("Wasting\n"));
-+ addedsize = 0;
-+ jeb->wasted_size += ref_totlen(c, jeb, ref);
-+ c->wasted_size += ref_totlen(c, jeb, ref);
-+ }
-+ ref->flash_offset = ref_offset(ref) | REF_OBSOLETE;
-
- ACCT_SANITY_CHECK(c, jeb);
-
-- ACCT_PARANOIA_CHECK(jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-
- if (c->flags & JFFS2_SB_FLAG_MOUNTING) {
- /* Mount in progress. Don't muck about with the block
-@@ -325,68 +462,280 @@
- obliterate nodes that look obsolete. If they weren't
- marked obsolete on the flash at the time they _became_
- obsolete, there was probably a reason for that. */
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
- return;
- }
-+
- if (jeb == c->nextblock) {
- D2(printk(KERN_DEBUG "Not moving nextblock 0x%08x to dirty/erase_pending list\n", jeb->offset));
-- } else if (jeb == c->gcblock) {
-- D2(printk(KERN_DEBUG "Not moving gcblock 0x%08x to dirty/erase_pending list\n", jeb->offset));
--#if 0 /* We no longer do this here. It can screw the wear levelling. If you have a lot of static
-- data and a few blocks free, and you just create new files and keep deleting/overwriting
-- them, then you'd keep erasing and reusing those blocks without ever moving stuff around.
-- So we leave completely obsoleted blocks on the dirty_list and let the GC delete them
-- when it finds them there. That way, we still get the 'once in a while, take a clean block'
-- to spread out the flash usage */
-- } else if (!jeb->used_size) {
-+ } else if (!jeb->used_size && !jeb->unchecked_size) {
-+ if (jeb == c->gcblock) {
-+ D1(printk(KERN_DEBUG "gcblock at 0x%08x completely dirtied. Clearing gcblock...\n", jeb->offset));
-+ c->gcblock = NULL;
-+ } else {
- D1(printk(KERN_DEBUG "Eraseblock at 0x%08x completely dirtied. Removing from (dirty?) list...\n", jeb->offset));
- list_del(&jeb->list);
-+ }
-+ if (jffs2_wbuf_dirty(c)) {
-+ D1(printk(KERN_DEBUG "...and adding to erasable_pending_wbuf_list\n"));
-+ list_add_tail(&jeb->list, &c->erasable_pending_wbuf_list);
-+ } else {
-+ if (jiffies & 127) {
-+ /* Most of the time, we just erase it immediately. Otherwise we
-+ spend ages scanning it on mount, etc. */
- D1(printk(KERN_DEBUG "...and adding to erase_pending_list\n"));
- list_add_tail(&jeb->list, &c->erase_pending_list);
- c->nr_erasing_blocks++;
- jffs2_erase_pending_trigger(c);
-- // OFNI_BS_2SFFJ(c)->s_dirt = 1;
-+ } else {
-+ /* Sometimes, however, we leave it elsewhere so it doesn't get
-+ immediately reused, and we spread the load a bit. */
-+ D1(printk(KERN_DEBUG "...and adding to erasable_list\n"));
-+ list_add_tail(&jeb->list, &c->erasable_list);
-+ }
-+ }
- D1(printk(KERN_DEBUG "Done OK\n"));
--#endif
-- } else if (jeb->dirty_size == ref->totlen) {
-+ } else if (jeb == c->gcblock) {
-+ D2(printk(KERN_DEBUG "Not moving gcblock 0x%08x to dirty_list\n", jeb->offset));
-+ } else if (ISDIRTY(jeb->dirty_size) && !ISDIRTY(jeb->dirty_size - addedsize)) {
- D1(printk(KERN_DEBUG "Eraseblock at 0x%08x is freshly dirtied. Removing from clean list...\n", jeb->offset));
- list_del(&jeb->list);
- D1(printk(KERN_DEBUG "...and adding to dirty_list\n"));
- list_add_tail(&jeb->list, &c->dirty_list);
-+ } else if (VERYDIRTY(c, jeb->dirty_size) &&
-+ !VERYDIRTY(c, jeb->dirty_size - addedsize)) {
-+ D1(printk(KERN_DEBUG "Eraseblock at 0x%08x is now very dirty. Removing from dirty list...\n", jeb->offset));
-+ list_del(&jeb->list);
-+ D1(printk(KERN_DEBUG "...and adding to very_dirty_list\n"));
-+ list_add_tail(&jeb->list, &c->very_dirty_list);
-+ } else {
-+ D1(printk(KERN_DEBUG "Eraseblock at 0x%08x not moved anywhere. (free 0x%08x, dirty 0x%08x, used 0x%08x)\n",
-+ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
- }
-- spin_unlock_bh(&c->erase_completion_lock);
-
-- if (c->mtd->type != MTD_NORFLASH && c->mtd->type != MTD_RAM)
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ if (!jffs2_can_mark_obsolete(c))
- return;
-- if (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
-+ if (jffs2_is_readonly(c))
- return;
-
-- D1(printk(KERN_DEBUG "obliterating obsoleted node at 0x%08x\n", ref->flash_offset &~3));
-- ret = c->mtd->read(c->mtd, ref->flash_offset &~3, sizeof(n), &retlen, (char *)&n);
-+ D1(printk(KERN_DEBUG "obliterating obsoleted node at 0x%08x\n", ref_offset(ref)));
-+ ret = jffs2_flash_read(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n);
- if (ret) {
-- printk(KERN_WARNING "Read error reading from obsoleted node at 0x%08x: %d\n", ref->flash_offset &~3, ret);
-+ printk(KERN_WARNING "Read error reading from obsoleted node at 0x%08x: %d\n", ref_offset(ref), ret);
- return;
- }
- if (retlen != sizeof(n)) {
-- printk(KERN_WARNING "Short read from obsoleted node at 0x%08x: %d\n", ref->flash_offset &~3, retlen);
-+ printk(KERN_WARNING "Short read from obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen);
- return;
- }
-- if (PAD(n.totlen) != PAD(ref->totlen)) {
-- printk(KERN_WARNING "Node totlen on flash (0x%08x) != totlen in node ref (0x%08x)\n", n.totlen, ref->totlen);
-+ if (PAD(je32_to_cpu(n.totlen)) != PAD(ref_totlen(c, jeb, ref))) {
-+ printk(KERN_WARNING "Node totlen on flash (0x%08x) != totlen from node ref (0x%08x)\n", je32_to_cpu(n.totlen), ref_totlen(c, jeb, ref));
- return;
- }
-- if (!(n.nodetype & JFFS2_NODE_ACCURATE)) {
-- D1(printk(KERN_DEBUG "Node at 0x%08x was already marked obsolete (nodetype 0x%04x\n", ref->flash_offset &~3, n.nodetype));
-+ if (!(je16_to_cpu(n.nodetype) & JFFS2_NODE_ACCURATE)) {
-+ D1(printk(KERN_DEBUG "Node at 0x%08x was already marked obsolete (nodetype 0x%04x)\n", ref_offset(ref), je16_to_cpu(n.nodetype)));
- return;
- }
-- n.nodetype &= ~JFFS2_NODE_ACCURATE;
-- ret = c->mtd->write(c->mtd, ref->flash_offset&~3, sizeof(n), &retlen, (char *)&n);
-+ /* XXX FIXME: This is ugly now */
-+ n.nodetype = cpu_to_je16(je16_to_cpu(n.nodetype) & ~JFFS2_NODE_ACCURATE);
-+ ret = jffs2_flash_write(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n);
- if (ret) {
-- printk(KERN_WARNING "Write error in obliterating obsoleted node at 0x%08x: %d\n", ref->flash_offset &~3, ret);
-+ printk(KERN_WARNING "Write error in obliterating obsoleted node at 0x%08x: %d\n", ref_offset(ref), ret);
- return;
- }
- if (retlen != sizeof(n)) {
-- printk(KERN_WARNING "Short write in obliterating obsoleted node at 0x%08x: %d\n", ref->flash_offset &~3, retlen);
-+ printk(KERN_WARNING "Short write in obliterating obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen);
- return;
- }
- }
-+
-+#if CONFIG_JFFS2_FS_DEBUG > 0
-+void jffs2_dump_block_lists(struct jffs2_sb_info *c)
-+{
-+
-+
-+ printk(KERN_DEBUG "jffs2_dump_block_lists:\n");
-+ printk(KERN_DEBUG "flash_size: %08x\n", c->flash_size);
-+ printk(KERN_DEBUG "used_size: %08x\n", c->used_size);
-+ printk(KERN_DEBUG "dirty_size: %08x\n", c->dirty_size);
-+ printk(KERN_DEBUG "wasted_size: %08x\n", c->wasted_size);
-+ printk(KERN_DEBUG "unchecked_size: %08x\n", c->unchecked_size);
-+ printk(KERN_DEBUG "free_size: %08x\n", c->free_size);
-+ printk(KERN_DEBUG "erasing_size: %08x\n", c->erasing_size);
-+ printk(KERN_DEBUG "bad_size: %08x\n", c->bad_size);
-+ printk(KERN_DEBUG "sector_size: %08x\n", c->sector_size);
-+ printk(KERN_DEBUG "jffs2_reserved_blocks size: %08x\n",c->sector_size * c->resv_blocks_write);
-+
-+ if (c->nextblock) {
-+ printk(KERN_DEBUG "nextblock: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ c->nextblock->offset, c->nextblock->used_size, c->nextblock->dirty_size, c->nextblock->wasted_size, c->nextblock->unchecked_size, c->nextblock->free_size);
-+ } else {
-+ printk(KERN_DEBUG "nextblock: NULL\n");
-+ }
-+ if (c->gcblock) {
-+ printk(KERN_DEBUG "gcblock: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size, c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
-+ } else {
-+ printk(KERN_DEBUG "gcblock: NULL\n");
-+ }
-+ if (list_empty(&c->clean_list)) {
-+ printk(KERN_DEBUG "clean_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+ int numblocks = 0;
-+ uint32_t dirty = 0;
-+
-+ list_for_each(this, &c->clean_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ numblocks ++;
-+ dirty += jeb->wasted_size;
-+ printk(KERN_DEBUG "clean_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n", jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ printk (KERN_DEBUG "Contains %d blocks with total wasted size %u, average wasted size: %u\n", numblocks, dirty, dirty / numblocks);
-+ }
-+ if (list_empty(&c->very_dirty_list)) {
-+ printk(KERN_DEBUG "very_dirty_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+ int numblocks = 0;
-+ uint32_t dirty = 0;
-+
-+ list_for_each(this, &c->very_dirty_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ numblocks ++;
-+ dirty += jeb->dirty_size;
-+ printk(KERN_DEBUG "very_dirty_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
-+ numblocks, dirty, dirty / numblocks);
-+ }
-+ if (list_empty(&c->dirty_list)) {
-+ printk(KERN_DEBUG "dirty_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+ int numblocks = 0;
-+ uint32_t dirty = 0;
-+
-+ list_for_each(this, &c->dirty_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ numblocks ++;
-+ dirty += jeb->dirty_size;
-+ printk(KERN_DEBUG "dirty_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
-+ numblocks, dirty, dirty / numblocks);
-+ }
-+ if (list_empty(&c->erasable_list)) {
-+ printk(KERN_DEBUG "erasable_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+
-+ list_for_each(this, &c->erasable_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ printk(KERN_DEBUG "erasable_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ }
-+ if (list_empty(&c->erasing_list)) {
-+ printk(KERN_DEBUG "erasing_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+
-+ list_for_each(this, &c->erasing_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ printk(KERN_DEBUG "erasing_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ }
-+ if (list_empty(&c->erase_pending_list)) {
-+ printk(KERN_DEBUG "erase_pending_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+
-+ list_for_each(this, &c->erase_pending_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ printk(KERN_DEBUG "erase_pending_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ }
-+ if (list_empty(&c->erasable_pending_wbuf_list)) {
-+ printk(KERN_DEBUG "erasable_pending_wbuf_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+
-+ list_for_each(this, &c->erasable_pending_wbuf_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ printk(KERN_DEBUG "erasable_pending_wbuf_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ }
-+ if (list_empty(&c->free_list)) {
-+ printk(KERN_DEBUG "free_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+
-+ list_for_each(this, &c->free_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ printk(KERN_DEBUG "free_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ }
-+ if (list_empty(&c->bad_list)) {
-+ printk(KERN_DEBUG "bad_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+
-+ list_for_each(this, &c->bad_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ printk(KERN_DEBUG "bad_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ }
-+ if (list_empty(&c->bad_used_list)) {
-+ printk(KERN_DEBUG "bad_used_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+
-+ list_for_each(this, &c->bad_used_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ printk(KERN_DEBUG "bad_used_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ }
-+}
-+#endif /* CONFIG_JFFS2_FS_DEBUG */
-+
-+int jffs2_thread_should_wake(struct jffs2_sb_info *c)
-+{
-+ int ret = 0;
-+ uint32_t dirty;
-+
-+ if (c->unchecked_size) {
-+ D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): unchecked_size %d, checked_ino #%d\n",
-+ c->unchecked_size, c->checked_ino));
-+ return 1;
-+ }
-+
-+ /* dirty_size contains blocks on erase_pending_list
-+ * those blocks are counted in c->nr_erasing_blocks.
-+ * If one block is actually erased, it is not longer counted as dirty_space
-+ * but it is counted in c->nr_erasing_blocks, so we add it and subtract it
-+ * with c->nr_erasing_blocks * c->sector_size again.
-+ * Blocks on erasable_list are counted as dirty_size, but not in c->nr_erasing_blocks
-+ * This helps us to force gc and pick eventually a clean block to spread the load.
-+ */
-+ dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size;
-+
-+ if (c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_gctrigger &&
-+ (dirty > c->nospc_dirty_size))
-+ ret = 1;
-+
-+ D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x: %s\n",
-+ c->nr_free_blocks, c->nr_erasing_blocks, c->dirty_size, ret?"yes":"no"));
-+
-+ return ret;
-+}
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/os-linux.h linux/fs/jffs2/os-linux.h
---- linux-mips-2.4.24-pre2/fs/jffs2/os-linux.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/jffs2/os-linux.h 2004-11-17 18:17:59.365264368 +0100
-@@ -0,0 +1,212 @@
-+/*
-+ * JFFS2 -- Journalling Flash File System, Version 2.
-+ *
-+ * Copyright (C) 2002-2003 Red Hat, Inc.
-+ *
-+ * Created by David Woodhouse <dwmw2@redhat.com>
-+ *
-+ * For licensing information, see the file 'LICENCE' in this directory.
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+#ifndef __JFFS2_OS_LINUX_H__
-+#define __JFFS2_OS_LINUX_H__
-+#include <linux/version.h>
-+
-+/* JFFS2 uses Linux mode bits natively -- no need for conversion */
-+#define os_to_jffs2_mode(x) (x)
-+#define jffs2_to_os_mode(x) (x)
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,73)
-+#define kstatfs statfs
-+#endif
-+
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
-+#define JFFS2_INODE_INFO(i) (list_entry(i, struct jffs2_inode_info, vfs_inode))
-+#define OFNI_EDONI_2SFFJ(f) (&(f)->vfs_inode)
-+#define JFFS2_SB_INFO(sb) (sb->s_fs_info)
-+#define OFNI_BS_2SFFJ(c) ((struct super_block *)c->os_priv)
-+#elif defined(JFFS2_OUT_OF_KERNEL)
-+#define JFFS2_INODE_INFO(i) ((struct jffs2_inode_info *) &(i)->u)
-+#define OFNI_EDONI_2SFFJ(f) ((struct inode *) ( ((char *)f) - ((char *)(&((struct inode *)NULL)->u)) ) )
-+#define JFFS2_SB_INFO(sb) ((struct jffs2_sb_info *) &(sb)->u)
-+#define OFNI_BS_2SFFJ(c) ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->u)) ) )
-+#else
-+#define JFFS2_INODE_INFO(i) (&i->u.jffs2_i)
-+#define OFNI_EDONI_2SFFJ(f) ((struct inode *) ( ((char *)f) - ((char *)(&((struct inode *)NULL)->u)) ) )
-+#define JFFS2_SB_INFO(sb) (&sb->u.jffs2_sb)
-+#define OFNI_BS_2SFFJ(c) ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->u)) ) )
-+#endif
-+
-+
-+#define JFFS2_F_I_SIZE(f) (OFNI_EDONI_2SFFJ(f)->i_size)
-+#define JFFS2_F_I_MODE(f) (OFNI_EDONI_2SFFJ(f)->i_mode)
-+#define JFFS2_F_I_UID(f) (OFNI_EDONI_2SFFJ(f)->i_uid)
-+#define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid)
-+
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,1)
-+#define JFFS2_F_I_RDEV_MIN(f) (iminor(OFNI_EDONI_2SFFJ(f)))
-+#define JFFS2_F_I_RDEV_MAJ(f) (imajor(OFNI_EDONI_2SFFJ(f)))
-+#else
-+#define JFFS2_F_I_RDEV_MIN(f) (MINOR(to_kdev_t(OFNI_EDONI_2SFFJ(f)->i_rdev)))
-+#define JFFS2_F_I_RDEV_MAJ(f) (MAJOR(to_kdev_t(OFNI_EDONI_2SFFJ(f)->i_rdev)))
-+#endif
-+
-+/* Urgh. The things we do to keep the 2.4 build working */
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,47)
-+#define ITIME(sec) ((struct timespec){sec, 0})
-+#define I_SEC(tv) ((tv).tv_sec)
-+#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime.tv_sec)
-+#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime.tv_sec)
-+#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime.tv_sec)
-+#else
-+#define ITIME(x) (x)
-+#define I_SEC(x) (x)
-+#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime)
-+#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime)
-+#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime)
-+#endif
-+
-+#define sleep_on_spinunlock(wq, s) \
-+ do { \
-+ DECLARE_WAITQUEUE(__wait, current); \
-+ add_wait_queue((wq), &__wait); \
-+ set_current_state(TASK_UNINTERRUPTIBLE); \
-+ spin_unlock(s); \
-+ schedule(); \
-+ remove_wait_queue((wq), &__wait); \
-+ } while(0)
-+
-+static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
-+{
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
-+ f->highest_version = 0;
-+ f->fragtree = RB_ROOT;
-+ f->metadata = NULL;
-+ f->dents = NULL;
-+ f->flags = 0;
-+ f->usercompr = 0;
-+#else
-+ memset(f, 0, sizeof(*f));
-+ init_MUTEX_LOCKED(&f->sem);
-+#endif
-+}
-+
-+#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
-+
-+#ifndef CONFIG_JFFS2_FS_NAND
-+#define jffs2_can_mark_obsolete(c) (1)
-+#define jffs2_cleanmarker_oob(c) (0)
-+#define jffs2_write_nand_cleanmarker(c,jeb) (-EIO)
-+
-+#define jffs2_flash_write(c, ofs, len, retlen, buf) ((c)->mtd->write((c)->mtd, ofs, len, retlen, buf))
-+#define jffs2_flash_read(c, ofs, len, retlen, buf) ((c)->mtd->read((c)->mtd, ofs, len, retlen, buf))
-+#define jffs2_flush_wbuf_pad(c) ({ (void)(c), 0; })
-+#define jffs2_flush_wbuf_gc(c, i) ({ (void)(c), (void) i, 0; })
-+#define jffs2_nand_read_failcnt(c,jeb) do { ; } while(0)
-+#define jffs2_write_nand_badblock(c,jeb) do { ; } while(0)
-+#define jffs2_nand_flash_setup(c) (0)
-+#define jffs2_nand_flash_cleanup(c) do {} while(0)
-+#define jffs2_wbuf_dirty(c) (0)
-+#define jffs2_flash_writev(a,b,c,d,e,f) jffs2_flash_direct_writev(a,b,c,d,e)
-+#define jffs2_wbuf_timeout NULL
-+#define jffs2_wbuf_process NULL
-+
-+#else /* NAND support present */
-+
-+#define jffs2_can_mark_obsolete(c) (c->mtd->type == MTD_NORFLASH || c->mtd->type == MTD_RAM)
-+#define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH)
-+
-+#define jffs2_flash_write_oob(c, ofs, len, retlen, buf) ((c)->mtd->write_oob((c)->mtd, ofs, len, retlen, buf))
-+#define jffs2_flash_read_oob(c, ofs, len, retlen, buf) ((c)->mtd->read_oob((c)->mtd, ofs, len, retlen, buf))
-+#define jffs2_wbuf_dirty(c) (!!(c)->wbuf_len)
-+struct kstatfs;
-+
-+/* wbuf.c */
-+int jffs2_flash_writev(struct jffs2_sb_info *c, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino);
-+int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, const u_char *buf);
-+int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, u_char *buf);
-+int jffs2_check_oob_empty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,int mode);
-+int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+void jffs2_wbuf_timeout(unsigned long data);
-+void jffs2_wbuf_process(void *data);
-+int jffs2_nand_flash_setup(struct jffs2_sb_info *c);
-+void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c);
-+#endif /* NAND */
-+
-+/* erase.c */
-+static inline void jffs2_erase_pending_trigger(struct jffs2_sb_info *c)
-+{
-+ OFNI_BS_2SFFJ(c)->s_dirt = 1;
-+}
-+
-+/* background.c */
-+int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c);
-+void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c);
-+void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c);
-+
-+/* dir.c */
-+extern struct file_operations jffs2_dir_operations;
-+extern struct inode_operations jffs2_dir_inode_operations;
-+
-+/* file.c */
-+extern struct file_operations jffs2_file_operations;
-+extern struct inode_operations jffs2_file_inode_operations;
-+extern struct address_space_operations jffs2_file_address_operations;
-+int jffs2_fsync(struct file *, struct dentry *, int);
-+int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg);
-+int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg);
-+int jffs2_readpage (struct file *, struct page *);
-+int jffs2_prepare_write (struct file *, struct page *, unsigned, unsigned);
-+int jffs2_commit_write (struct file *, struct page *, unsigned, unsigned);
-+
-+/* ioctl.c */
-+int jffs2_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
-+
-+/* symlink.c */
-+extern struct inode_operations jffs2_symlink_inode_operations;
-+
-+/* fs.c */
-+int jffs2_setattr (struct dentry *, struct iattr *);
-+void jffs2_read_inode (struct inode *);
-+void jffs2_clear_inode (struct inode *);
-+void jffs2_dirty_inode(struct inode *inode);
-+struct inode *jffs2_new_inode (struct inode *dir_i, int mode,
-+ struct jffs2_raw_inode *ri);
-+int jffs2_statfs (struct super_block *, struct kstatfs *);
-+void jffs2_write_super (struct super_block *);
-+int jffs2_remount_fs (struct super_block *, int *, char *);
-+int jffs2_do_fill_super(struct super_block *sb, void *data, int silent);
-+void jffs2_gc_release_inode(struct jffs2_sb_info *c,
-+ struct jffs2_inode_info *f);
-+struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
-+ int inum, int nlink);
-+
-+unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
-+ struct jffs2_inode_info *f,
-+ unsigned long offset,
-+ unsigned long *priv);
-+void jffs2_gc_release_page(struct jffs2_sb_info *c,
-+ unsigned char *pg,
-+ unsigned long *priv);
-+
-+
-+/* writev.c */
-+int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct iovec *vecs,
-+ unsigned long count, loff_t to, size_t *retlen);
-+
-+/* Compression config */
-+#define JFFS2_COMPRESSION
-+#undef JFFS2_USE_DYNRUBIN /* Disabled 23/9/1. With zlib it hardly ever gets a look in */
-+#undef JFFS2_USE_RUBINMIPS /* Disabled 26/2/1. Obsoleted by dynrubin */
-+#define JFFS2_USE_ZLIB
-+#define JFFS2_USE_RTIME /* rtime does manage to recompress already-compressed data */
-+
-+
-+#endif /* __JFFS2_OS_LINUX_H__ */
-+
-+
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/pushpull.h linux/fs/jffs2/pushpull.h
---- linux-mips-2.4.24-pre2/fs/jffs2/pushpull.h 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/pushpull.h 2004-11-17 18:17:59.000000000 +0100
-@@ -1,42 +1,21 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001, 2002 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #ifndef __PUSHPULL_H__
- #define __PUSHPULL_H__
-+
-+#include <linux/errno.h>
-+
- struct pushpull {
- unsigned char *buf;
- unsigned int buflen;
-@@ -44,9 +23,36 @@
- unsigned int reserve;
- };
-
--void init_pushpull(struct pushpull *, char *, unsigned, unsigned, unsigned);
--int pushbit(struct pushpull *pp, int bit, int use_reserved);
--int pushedbits(struct pushpull *pp);
-+
-+static inline void init_pushpull(struct pushpull *pp, char *buf, unsigned buflen, unsigned ofs, unsigned reserve)
-+{
-+ pp->buf = buf;
-+ pp->buflen = buflen;
-+ pp->ofs = ofs;
-+ pp->reserve = reserve;
-+}
-+
-+static inline int pushbit(struct pushpull *pp, int bit, int use_reserved)
-+{
-+ if (pp->ofs >= pp->buflen - (use_reserved?0:pp->reserve)) {
-+ return -ENOSPC;
-+ }
-+
-+ if (bit) {
-+ pp->buf[pp->ofs >> 3] |= (1<<(7-(pp->ofs &7)));
-+ }
-+ else {
-+ pp->buf[pp->ofs >> 3] &= ~(1<<(7-(pp->ofs &7)));
-+ }
-+ pp->ofs++;
-+
-+ return 0;
-+}
-+
-+static inline int pushedbits(struct pushpull *pp)
-+{
-+ return pp->ofs;
-+}
-
- static inline int pullbit(struct pushpull *pp)
- {
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/rbtree.c linux/fs/jffs2/rbtree.c
---- linux-mips-2.4.24-pre2/fs/jffs2/rbtree.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/jffs2/rbtree.c 2004-11-17 18:17:59.368263912 +0100
-@@ -0,0 +1,363 @@
-+/*
-+ Red Black Trees
-+ (C) 1999 Andrea Arcangeli <andrea@suse.de>
-+ (C) 2002 David Woodhouse <dwmw2@infradead.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2 of the License, or
-+ (at your option) any later version.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the Free Software
-+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+
-+ $Id$
-+*/
-+
-+#ifdef __ECOS /* This file is _not_ under the eCos licence; it is pure GPL. */
-+#error "Licence problem. eCos has its own rbtree code."
-+#endif
-+
-+#include <linux/version.h>
-+#include <linux/rbtree.h>
-+
-+/* This wasn't present till 2.4.11, wasn't exported till 2.4.19 */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,11) || \
-+ (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) && defined(MODULE))
-+static void __rb_rotate_left(struct rb_node * node, struct rb_root * root)
-+{
-+ struct rb_node * right = node->rb_right;
-+
-+ if ((node->rb_right = right->rb_left))
-+ right->rb_left->rb_parent = node;
-+ right->rb_left = node;
-+
-+ if ((right->rb_parent = node->rb_parent))
-+ {
-+ if (node == node->rb_parent->rb_left)
-+ node->rb_parent->rb_left = right;
-+ else
-+ node->rb_parent->rb_right = right;
-+ }
-+ else
-+ root->rb_node = right;
-+ node->rb_parent = right;
-+}
-+
-+static void __rb_rotate_right(struct rb_node * node, struct rb_root * root)
-+{
-+ struct rb_node * left = node->rb_left;
-+
-+ if ((node->rb_left = left->rb_right))
-+ left->rb_right->rb_parent = node;
-+ left->rb_right = node;
-+
-+ if ((left->rb_parent = node->rb_parent))
-+ {
-+ if (node == node->rb_parent->rb_right)
-+ node->rb_parent->rb_right = left;
-+ else
-+ node->rb_parent->rb_left = left;
-+ }
-+ else
-+ root->rb_node = left;
-+ node->rb_parent = left;
-+}
-+
-+void rb_insert_color(struct rb_node * node, struct rb_root * root)
-+{
-+ struct rb_node * parent, * gparent;
-+
-+ while ((parent = node->rb_parent) && parent->rb_color == RB_RED)
-+ {
-+ gparent = parent->rb_parent;
-+
-+ if (parent == gparent->rb_left)
-+ {
-+ {
-+ register struct rb_node * uncle = gparent->rb_right;
-+ if (uncle && uncle->rb_color == RB_RED)
-+ {
-+ uncle->rb_color = RB_BLACK;
-+ parent->rb_color = RB_BLACK;
-+ gparent->rb_color = RB_RED;
-+ node = gparent;
-+ continue;
-+ }
-+ }
-+
-+ if (parent->rb_right == node)
-+ {
-+ register struct rb_node * tmp;
-+ __rb_rotate_left(parent, root);
-+ tmp = parent;
-+ parent = node;
-+ node = tmp;
-+ }
-+
-+ parent->rb_color = RB_BLACK;
-+ gparent->rb_color = RB_RED;
-+ __rb_rotate_right(gparent, root);
-+ } else {
-+ {
-+ register struct rb_node * uncle = gparent->rb_left;
-+ if (uncle && uncle->rb_color == RB_RED)
-+ {
-+ uncle->rb_color = RB_BLACK;
-+ parent->rb_color = RB_BLACK;
-+ gparent->rb_color = RB_RED;
-+ node = gparent;
-+ continue;
-+ }
-+ }
-+
-+ if (parent->rb_left == node)
-+ {
-+ register struct rb_node * tmp;
-+ __rb_rotate_right(parent, root);
-+ tmp = parent;
-+ parent = node;
-+ node = tmp;
-+ }
-+
-+ parent->rb_color = RB_BLACK;
-+ gparent->rb_color = RB_RED;
-+ __rb_rotate_left(gparent, root);
-+ }
-+ }
-+
-+ root->rb_node->rb_color = RB_BLACK;
-+}
-+
-+static void __rb_erase_color(struct rb_node * node, struct rb_node * parent,
-+ struct rb_root * root)
-+{
-+ struct rb_node * other;
-+
-+ while ((!node || node->rb_color == RB_BLACK) && node != root->rb_node)
-+ {
-+ if (parent->rb_left == node)
-+ {
-+ other = parent->rb_right;
-+ if (other->rb_color == RB_RED)
-+ {
-+ other->rb_color = RB_BLACK;
-+ parent->rb_color = RB_RED;
-+ __rb_rotate_left(parent, root);
-+ other = parent->rb_right;
-+ }
-+ if ((!other->rb_left ||
-+ other->rb_left->rb_color == RB_BLACK)
-+ && (!other->rb_right ||
-+ other->rb_right->rb_color == RB_BLACK))
-+ {
-+ other->rb_color = RB_RED;
-+ node = parent;
-+ parent = node->rb_parent;
-+ }
-+ else
-+ {
-+ if (!other->rb_right ||
-+ other->rb_right->rb_color == RB_BLACK)
-+ {
-+ register struct rb_node * o_left;
-+ if ((o_left = other->rb_left))
-+ o_left->rb_color = RB_BLACK;
-+ other->rb_color = RB_RED;
-+ __rb_rotate_right(other, root);
-+ other = parent->rb_right;
-+ }
-+ other->rb_color = parent->rb_color;
-+ parent->rb_color = RB_BLACK;
-+ if (other->rb_right)
-+ other->rb_right->rb_color = RB_BLACK;
-+ __rb_rotate_left(parent, root);
-+ node = root->rb_node;
-+ break;
-+ }
-+ }
-+ else
-+ {
-+ other = parent->rb_left;
-+ if (other->rb_color == RB_RED)
-+ {
-+ other->rb_color = RB_BLACK;
-+ parent->rb_color = RB_RED;
-+ __rb_rotate_right(parent, root);
-+ other = parent->rb_left;
-+ }
-+ if ((!other->rb_left ||
-+ other->rb_left->rb_color == RB_BLACK)
-+ && (!other->rb_right ||
-+ other->rb_right->rb_color == RB_BLACK))
-+ {
-+ other->rb_color = RB_RED;
-+ node = parent;
-+ parent = node->rb_parent;
-+ }
-+ else
-+ {
-+ if (!other->rb_left ||
-+ other->rb_left->rb_color == RB_BLACK)
-+ {
-+ register struct rb_node * o_right;
-+ if ((o_right = other->rb_right))
-+ o_right->rb_color = RB_BLACK;
-+ other->rb_color = RB_RED;
-+ __rb_rotate_left(other, root);
-+ other = parent->rb_left;
-+ }
-+ other->rb_color = parent->rb_color;
-+ parent->rb_color = RB_BLACK;
-+ if (other->rb_left)
-+ other->rb_left->rb_color = RB_BLACK;
-+ __rb_rotate_right(parent, root);
-+ node = root->rb_node;
-+ break;
-+ }
-+ }
-+ }
-+ if (node)
-+ node->rb_color = RB_BLACK;
-+}
-+
-+void rb_erase(struct rb_node * node, struct rb_root * root)
-+{
-+ struct rb_node * child, * parent;
-+ int color;
-+
-+ if (!node->rb_left)
-+ child = node->rb_right;
-+ else if (!node->rb_right)
-+ child = node->rb_left;
-+ else
-+ {
-+ struct rb_node * old = node, * left;
-+
-+ node = node->rb_right;
-+ while ((left = node->rb_left))
-+ node = left;
-+ child = node->rb_right;
-+ parent = node->rb_parent;
-+ color = node->rb_color;
-+
-+ if (child)
-+ child->rb_parent = parent;
-+ if (parent)
-+ {
-+ if (parent->rb_left == node)
-+ parent->rb_left = child;
-+ else
-+ parent->rb_right = child;
-+ }
-+ else
-+ root->rb_node = child;
-+
-+ if (node->rb_parent == old)
-+ parent = node;
-+ node->rb_parent = old->rb_parent;
-+ node->rb_color = old->rb_color;
-+ node->rb_right = old->rb_right;
-+ node->rb_left = old->rb_left;
-+
-+ if (old->rb_parent)
-+ {
-+ if (old->rb_parent->rb_left == old)
-+ old->rb_parent->rb_left = node;
-+ else
-+ old->rb_parent->rb_right = node;
-+ } else
-+ root->rb_node = node;
-+
-+ old->rb_left->rb_parent = node;
-+ if (old->rb_right)
-+ old->rb_right->rb_parent = node;
-+ goto color;
-+ }
-+
-+ parent = node->rb_parent;
-+ color = node->rb_color;
-+
-+ if (child)
-+ child->rb_parent = parent;
-+ if (parent)
-+ {
-+ if (parent->rb_left == node)
-+ parent->rb_left = child;
-+ else
-+ parent->rb_right = child;
-+ }
-+ else
-+ root->rb_node = child;
-+
-+ color:
-+ if (color == RB_BLACK)
-+ __rb_erase_color(child, parent, root);
-+}
-+#endif /* Before 2.4.11 */
-+
-+ /* These routines haven't made it into 2.4 (yet) */
-+struct rb_node *rb_next(struct rb_node *node)
-+{
-+ /* If we have a right-hand child, go down and then left as far
-+ as we can. */
-+ if (node->rb_right) {
-+ node = node->rb_right;
-+ while (node->rb_left)
-+ node=node->rb_left;
-+ return node;
-+ }
-+
-+ /* No right-hand children. Everything down and left is
-+ smaller than us, so any 'next' node must be in the general
-+ direction of our parent. Go up the tree; any time the
-+ ancestor is a right-hand child of its parent, keep going
-+ up. First time it's a left-hand child of its parent, said
-+ parent is our 'next' node. */
-+ while (node->rb_parent && node == node->rb_parent->rb_right)
-+ node = node->rb_parent;
-+
-+ return node->rb_parent;
-+}
-+
-+struct rb_node *rb_prev(struct rb_node *node)
-+{
-+ if (node->rb_left) {
-+ node = node->rb_left;
-+ while (node->rb_right)
-+ node=node->rb_right;
-+ return node;
-+ }
-+ while (node->rb_parent && node == node->rb_parent->rb_left)
-+ node = node->rb_parent;
-+
-+ return node->rb_parent;
-+}
-+
-+void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root)
-+{
-+ struct rb_node *parent = victim->rb_parent;
-+
-+ /* Set the surrounding nodes to point to the replacement */
-+ if (parent) {
-+ if (victim == parent->rb_left)
-+ parent->rb_left = new;
-+ else
-+ parent->rb_right = new;
-+ } else {
-+ root->rb_node = new;
-+ }
-+ if (victim->rb_left)
-+ victim->rb_left->rb_parent = new;
-+ if (victim->rb_right)
-+ victim->rb_right->rb_parent = new;
-+
-+ /* Copy the pointers/colour from the victim to the replacement */
-+ *new = *victim;
-+}
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/read.c linux/fs/jffs2/read.c
---- linux-mips-2.4.24-pre2/fs/jffs2/read.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/read.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,52 +1,29 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/kernel.h>
- #include <linux/slab.h>
--#include <linux/jffs2.h>
-+#include <linux/crc32.h>
-+#include <linux/pagemap.h>
- #include <linux/mtd/mtd.h>
-+#include <linux/compiler.h>
- #include "nodelist.h"
--#include <linux/crc32.h>
-
- int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_full_dnode *fd, unsigned char *buf, int ofs, int len)
- {
- struct jffs2_raw_inode *ri;
- size_t readlen;
-- __u32 crc;
-+ uint32_t crc;
- unsigned char *decomprbuf = NULL;
- unsigned char *readbuf = NULL;
- int ret = 0;
-@@ -55,35 +32,41 @@
- if (!ri)
- return -ENOMEM;
-
-- ret = c->mtd->read(c->mtd, fd->raw->flash_offset & ~3, sizeof(*ri), &readlen, (char *)ri);
-+ ret = jffs2_flash_read(c, ref_offset(fd->raw), sizeof(*ri), &readlen, (char *)ri);
- if (ret) {
- jffs2_free_raw_inode(ri);
-- printk(KERN_WARNING "Error reading node from 0x%08x: %d\n", fd->raw->flash_offset & ~3, ret);
-+ printk(KERN_WARNING "Error reading node from 0x%08x: %d\n", ref_offset(fd->raw), ret);
- return ret;
- }
- if (readlen != sizeof(*ri)) {
- jffs2_free_raw_inode(ri);
-- printk(KERN_WARNING "Short read from 0x%08x: wanted 0x%x bytes, got 0x%x\n",
-- fd->raw->flash_offset & ~3, sizeof(*ri), readlen);
-+ printk(KERN_WARNING "Short read from 0x%08x: wanted 0x%zx bytes, got 0x%zx\n",
-+ ref_offset(fd->raw), sizeof(*ri), readlen);
- return -EIO;
- }
- crc = crc32(0, ri, sizeof(*ri)-8);
-
-- D1(printk(KERN_DEBUG "Node read from %08x: node_crc %08x, calculated CRC %08x. dsize %x, csize %x, offset %x, buf %p\n", fd->raw->flash_offset & ~3, ri->node_crc, crc, ri->dsize, ri->csize, ri->offset, buf));
-- if (crc != ri->node_crc) {
-- printk(KERN_WARNING "Node CRC %08x != calculated CRC %08x for node at %08x\n", ri->node_crc, crc, fd->raw->flash_offset & ~3);
-+ D1(printk(KERN_DEBUG "Node read from %08x: node_crc %08x, calculated CRC %08x. dsize %x, csize %x, offset %x, buf %p\n",
-+ ref_offset(fd->raw), je32_to_cpu(ri->node_crc),
-+ crc, je32_to_cpu(ri->dsize), je32_to_cpu(ri->csize),
-+ je32_to_cpu(ri->offset), buf));
-+ if (crc != je32_to_cpu(ri->node_crc)) {
-+ printk(KERN_WARNING "Node CRC %08x != calculated CRC %08x for node at %08x\n",
-+ je32_to_cpu(ri->node_crc), crc, ref_offset(fd->raw));
- ret = -EIO;
- goto out_ri;
- }
- /* There was a bug where we wrote hole nodes out with csize/dsize
- swapped. Deal with it */
-- if (ri->compr == JFFS2_COMPR_ZERO && !ri->dsize && ri->csize) {
-+ if (ri->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(ri->dsize) &&
-+ je32_to_cpu(ri->csize)) {
- ri->dsize = ri->csize;
-- ri->csize = 0;
-+ ri->csize = cpu_to_je32(0);
- }
-
-- D1(if(ofs + len > ri->dsize) {
-- printk(KERN_WARNING "jffs2_read_dnode() asked for %d bytes at %d from %d-byte node\n", len, ofs, ri->dsize);
-+ D1(if(ofs + len > je32_to_cpu(ri->dsize)) {
-+ printk(KERN_WARNING "jffs2_read_dnode() asked for %d bytes at %d from %d-byte node\n",
-+ len, ofs, je32_to_cpu(ri->dsize));
- ret = -EINVAL;
- goto out_ri;
- });
-@@ -100,18 +83,18 @@
- Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy
- Reading partial node and it's compressed - read into readbuf, check checksum, decompress to decomprbuf and copy
- */
-- if (ri->compr == JFFS2_COMPR_NONE && len == ri->dsize) {
-+ if (ri->compr == JFFS2_COMPR_NONE && len == je32_to_cpu(ri->dsize)) {
- readbuf = buf;
- } else {
-- readbuf = kmalloc(ri->csize, GFP_KERNEL);
-+ readbuf = kmalloc(je32_to_cpu(ri->csize), GFP_KERNEL);
- if (!readbuf) {
- ret = -ENOMEM;
- goto out_ri;
- }
- }
- if (ri->compr != JFFS2_COMPR_NONE) {
-- if (len < ri->dsize) {
-- decomprbuf = kmalloc(ri->dsize, GFP_KERNEL);
-+ if (len < je32_to_cpu(ri->dsize)) {
-+ decomprbuf = kmalloc(je32_to_cpu(ri->dsize), GFP_KERNEL);
- if (!decomprbuf) {
- ret = -ENOMEM;
- goto out_readbuf;
-@@ -123,31 +106,35 @@
- decomprbuf = readbuf;
- }
-
-- D2(printk(KERN_DEBUG "Read %d bytes to %p\n", ri->csize, readbuf));
-- ret = c->mtd->read(c->mtd, (fd->raw->flash_offset &~3) + sizeof(*ri), ri->csize, &readlen, readbuf);
-+ D2(printk(KERN_DEBUG "Read %d bytes to %p\n", je32_to_cpu(ri->csize),
-+ readbuf));
-+ ret = jffs2_flash_read(c, (ref_offset(fd->raw)) + sizeof(*ri),
-+ je32_to_cpu(ri->csize), &readlen, readbuf);
-
-- if (!ret && readlen != ri->csize)
-+ if (!ret && readlen != je32_to_cpu(ri->csize))
- ret = -EIO;
- if (ret)
- goto out_decomprbuf;
-
-- crc = crc32(0, readbuf, ri->csize);
-- if (crc != ri->data_crc) {
-- printk(KERN_WARNING "Data CRC %08x != calculated CRC %08x for node at %08x\n", ri->data_crc, crc, fd->raw->flash_offset & ~3);
-+ crc = crc32(0, readbuf, je32_to_cpu(ri->csize));
-+ if (crc != je32_to_cpu(ri->data_crc)) {
-+ printk(KERN_WARNING "Data CRC %08x != calculated CRC %08x for node at %08x\n",
-+ je32_to_cpu(ri->data_crc), crc, ref_offset(fd->raw));
- ret = -EIO;
- goto out_decomprbuf;
- }
- D2(printk(KERN_DEBUG "Data CRC matches calculated CRC %08x\n", crc));
- if (ri->compr != JFFS2_COMPR_NONE) {
-- D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %p\n", ri->csize, readbuf, ri->dsize, decomprbuf));
-- ret = jffs2_decompress(ri->compr, readbuf, decomprbuf, ri->csize, ri->dsize);
-+ D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %p\n",
-+ je32_to_cpu(ri->csize), readbuf, je32_to_cpu(ri->dsize), decomprbuf));
-+ ret = jffs2_decompress(ri->compr, readbuf, decomprbuf, je32_to_cpu(ri->csize), je32_to_cpu(ri->dsize));
- if (ret) {
- printk(KERN_WARNING "Error: jffs2_decompress returned %d\n", ret);
- goto out_decomprbuf;
- }
- }
-
-- if (len < ri->dsize) {
-+ if (len < je32_to_cpu(ri->dsize)) {
- memcpy(buf, decomprbuf+ofs, len);
- }
- out_decomprbuf:
-@@ -161,3 +148,96 @@
-
- return ret;
- }
-+
-+int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
-+ unsigned char *buf, uint32_t offset, uint32_t len)
-+{
-+ uint32_t end = offset + len;
-+ struct jffs2_node_frag *frag;
-+ int ret;
-+
-+ D1(printk(KERN_DEBUG "jffs2_read_inode_range: ino #%u, range 0x%08x-0x%08x\n",
-+ f->inocache->ino, offset, offset+len));
-+
-+ frag = jffs2_lookup_node_frag(&f->fragtree, offset);
-+
-+ /* XXX FIXME: Where a single physical node actually shows up in two
-+ frags, we read it twice. Don't do that. */
-+ /* Now we're pointing at the first frag which overlaps our page */
-+ while(offset < end) {
-+ D2(printk(KERN_DEBUG "jffs2_read_inode_range: offset %d, end %d\n", offset, end));
-+ if (unlikely(!frag || frag->ofs > offset)) {
-+ uint32_t holesize = end - offset;
-+ if (frag) {
-+ D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset));
-+ holesize = min(holesize, frag->ofs - offset);
-+ D1(jffs2_print_frag_list(f));
-+ }
-+ D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize));
-+ memset(buf, 0, holesize);
-+ buf += holesize;
-+ offset += holesize;
-+ continue;
-+ } else if (unlikely(!frag->node)) {
-+ uint32_t holeend = min(end, frag->ofs + frag->size);
-+ D1(printk(KERN_DEBUG "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n", offset, holeend, frag->ofs, frag->ofs + frag->size));
-+ memset(buf, 0, holeend - offset);
-+ buf += holeend - offset;
-+ offset = holeend;
-+ frag = frag_next(frag);
-+ continue;
-+ } else {
-+ uint32_t readlen;
-+ uint32_t fragofs; /* offset within the frag to start reading */
-+
-+ fragofs = offset - frag->ofs;
-+ readlen = min(frag->size - fragofs, end - offset);
-+ D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%08x (%d)\n",
-+ frag->ofs+fragofs, frag->ofs+fragofs+readlen,
-+ ref_offset(frag->node->raw), ref_flags(frag->node->raw)));
-+ ret = jffs2_read_dnode(c, frag->node, buf, fragofs + frag->ofs - frag->node->ofs, readlen);
-+ D2(printk(KERN_DEBUG "node read done\n"));
-+ if (ret) {
-+ D1(printk(KERN_DEBUG"jffs2_read_inode_range error %d\n",ret));
-+ memset(buf, 0, readlen);
-+ return ret;
-+ }
-+ buf += readlen;
-+ offset += readlen;
-+ frag = frag_next(frag);
-+ D2(printk(KERN_DEBUG "node read was OK. Looping\n"));
-+ }
-+ }
-+ return 0;
-+}
-+
-+/* Core function to read symlink target. */
-+char *jffs2_getlink(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
-+{
-+ char *buf;
-+ int ret;
-+
-+ down(&f->sem);
-+
-+ if (!f->metadata) {
-+ printk(KERN_NOTICE "No metadata for symlink inode #%u\n", f->inocache->ino);
-+ up(&f->sem);
-+ return ERR_PTR(-EINVAL);
-+ }
-+ buf = kmalloc(f->metadata->size+1, GFP_USER);
-+ if (!buf) {
-+ up(&f->sem);
-+ return ERR_PTR(-ENOMEM);
-+ }
-+ buf[f->metadata->size]=0;
-+
-+ ret = jffs2_read_dnode(c, f->metadata, buf, 0, f->metadata->size);
-+
-+ up(&f->sem);
-+
-+ if (ret) {
-+ kfree(buf);
-+ return ERR_PTR(ret);
-+ }
-+ return buf;
-+}
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/readinode.c linux/fs/jffs2/readinode.c
---- linux-mips-2.4.24-pre2/fs/jffs2/readinode.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/readinode.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,79 +1,122 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
--/* Given an inode, probably with existing list of fragments, add the new node
-- * to the fragment list.
-- */
- #include <linux/kernel.h>
- #include <linux/slab.h>
- #include <linux/fs.h>
-+#include <linux/crc32.h>
-+#include <linux/pagemap.h>
- #include <linux/mtd/mtd.h>
--#include <linux/jffs2.h>
-+#include <linux/compiler.h>
- #include "nodelist.h"
--#include <linux/crc32.h>
-
-+static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag);
-
--D1(void jffs2_print_frag_list(struct jffs2_inode_info *f)
-+#if CONFIG_JFFS2_FS_DEBUG >= 1
-+static void jffs2_print_fragtree(struct rb_root *list, int permitbug)
- {
-- struct jffs2_node_frag *this = f->fraglist;
-+ struct jffs2_node_frag *this = frag_first(list);
-+ uint32_t lastofs = 0;
-+ int buggy = 0;
-
- while(this) {
- if (this->node)
-- printk(KERN_DEBUG "frag %04x-%04x: 0x%08x on flash (*%p->%p)\n", this->ofs, this->ofs+this->size, this->node->raw->flash_offset &~3, this, this->next);
-+ printk(KERN_DEBUG "frag %04x-%04x: 0x%08x(%d) on flash (*%p). left (%p), right (%p), parent (%p)\n",
-+ this->ofs, this->ofs+this->size, ref_offset(this->node->raw), ref_flags(this->node->raw),
-+ this, frag_left(this), frag_right(this), frag_parent(this));
- else
-- printk(KERN_DEBUG "frag %04x-%04x: hole (*%p->%p)\n", this->ofs, this->ofs+this->size, this, this->next);
-- this = this->next;
-+ printk(KERN_DEBUG "frag %04x-%04x: hole (*%p). left (%p} right (%p), parent (%p)\n", this->ofs,
-+ this->ofs+this->size, this, frag_left(this), frag_right(this), frag_parent(this));
-+ if (this->ofs != lastofs)
-+ buggy = 1;
-+ lastofs = this->ofs+this->size;
-+ this = frag_next(this);
-+ }
-+ if (buggy && !permitbug) {
-+ printk(KERN_CRIT "Frag tree got a hole in it\n");
-+ BUG();
- }
-+}
-+
-+void jffs2_print_frag_list(struct jffs2_inode_info *f)
-+{
-+ jffs2_print_fragtree(&f->fragtree, 0);
-+
- if (f->metadata) {
-- printk(KERN_DEBUG "metadata at 0x%08x\n", f->metadata->raw->flash_offset &~3);
-+ printk(KERN_DEBUG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
- }
--})
--
-+}
-
--int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn)
-+static int jffs2_sanitycheck_fragtree(struct jffs2_inode_info *f)
- {
-- int ret;
-- D1(printk(KERN_DEBUG "jffs2_add_full_dnode_to_inode(ino #%u, f %p, fn %p)\n", f->inocache->ino, f, fn));
-+ struct jffs2_node_frag *frag;
-+ int bitched = 0;
-
-- ret = jffs2_add_full_dnode_to_fraglist(c, &f->fraglist, fn);
-+ for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
-
-- D2(jffs2_print_frag_list(f));
-- return ret;
-+ struct jffs2_full_dnode *fn = frag->node;
-+ if (!fn || !fn->raw)
-+ continue;
-+
-+ if (ref_flags(fn->raw) == REF_PRISTINE) {
-+
-+ if (fn->frags > 1) {
-+ printk(KERN_WARNING "REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2\n", ref_offset(fn->raw), fn->frags);
-+ bitched = 1;
-+ }
-+ /* A hole node which isn't multi-page should be garbage-collected
-+ and merged anyway, so we just check for the frag size here,
-+ rather than mucking around with actually reading the node
-+ and checking the compression type, which is the real way
-+ to tell a hole node. */
-+ if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag) && frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) {
-+ printk(KERN_WARNING "REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2\n",
-+ ref_offset(fn->raw));
-+ bitched = 1;
-+ }
-+
-+ if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag) && frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) {
-+ printk(KERN_WARNING "REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2\n",
-+ ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size);
-+ bitched = 1;
-+ }
-+ }
-+ }
-+
-+ if (bitched) {
-+ struct jffs2_node_frag *thisfrag;
-+
-+ printk(KERN_WARNING "Inode is #%u\n", f->inocache->ino);
-+ thisfrag = frag_first(&f->fragtree);
-+ while (thisfrag) {
-+ if (!thisfrag->node) {
-+ printk("Frag @0x%x-0x%x; node-less hole\n",
-+ thisfrag->ofs, thisfrag->size + thisfrag->ofs);
-+ } else if (!thisfrag->node->raw) {
-+ printk("Frag @0x%x-0x%x; raw-less hole\n",
-+ thisfrag->ofs, thisfrag->size + thisfrag->ofs);
-+ } else {
-+ printk("Frag @0x%x-0x%x; raw at 0x%08x(%d) (0x%x-0x%x)\n",
-+ thisfrag->ofs, thisfrag->size + thisfrag->ofs,
-+ ref_offset(thisfrag->node->raw), ref_flags(thisfrag->node->raw),
-+ thisfrag->node->ofs, thisfrag->node->ofs+thisfrag->node->size);
-+ }
-+ thisfrag = frag_next(thisfrag);
-+ }
-+ }
-+ return bitched;
- }
-+#endif /* D1 */
-
- static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this)
- {
-@@ -82,42 +125,38 @@
- if (!this->node->frags) {
- /* The node has no valid frags left. It's totally obsoleted */
- D2(printk(KERN_DEBUG "Marking old node @0x%08x (0x%04x-0x%04x) obsolete\n",
-- this->node->raw->flash_offset &~3, this->node->ofs, this->node->ofs+this->node->size));
-+ ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size));
- jffs2_mark_node_obsolete(c, this->node->raw);
- jffs2_free_full_dnode(this->node);
- } else {
-- D2(printk(KERN_DEBUG "Not marking old node @0x%08x (0x%04x-0x%04x) obsolete. frags is %d\n",
-- this->node->raw->flash_offset &~3, this->node->ofs, this->node->ofs+this->node->size,
-+ D2(printk(KERN_DEBUG "Marking old node @0x%08x (0x%04x-0x%04x) REF_NORMAL. frags is %d\n",
-+ ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size,
- this->node->frags));
-+ mark_ref_normal(this->node->raw);
- }
-
- }
- jffs2_free_node_frag(this);
- }
-
--/* Doesn't set inode->i_size */
--int jffs2_add_full_dnode_to_fraglist(struct jffs2_sb_info *c, struct jffs2_node_frag **list, struct jffs2_full_dnode *fn)
-+/* Given an inode, probably with existing list of fragments, add the new node
-+ * to the fragment list.
-+ */
-+int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn)
- {
-+ int ret;
-+ struct jffs2_node_frag *newfrag;
-
-- struct jffs2_node_frag *this, **prev, *old;
-- struct jffs2_node_frag *newfrag, *newfrag2;
-- __u32 lastend = 0;
--
-+ D1(printk(KERN_DEBUG "jffs2_add_full_dnode_to_inode(ino #%u, f %p, fn %p)\n", f->inocache->ino, f, fn));
-
- newfrag = jffs2_alloc_node_frag();
-- if (!newfrag) {
-+ if (unlikely(!newfrag))
- return -ENOMEM;
-- }
--
-- D2(if (fn->raw)
-- printk(KERN_DEBUG "adding node %04x-%04x @0x%08x on flash, newfrag *%p\n", fn->ofs, fn->ofs+fn->size, fn->raw->flash_offset &~3, newfrag);
-- else
-- printk(KERN_DEBUG "adding hole node %04x-%04x on flash, newfrag *%p\n", fn->ofs, fn->ofs+fn->size, newfrag));
-
-- prev = list;
-- this = *list;
-+ D2(printk(KERN_DEBUG "adding node %04x-%04x @0x%08x on flash, newfrag *%p\n",
-+ fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag));
-
-- if (!fn->size) {
-+ if (unlikely(!fn->size)) {
- jffs2_free_node_frag(newfrag);
- return 0;
- }
-@@ -126,176 +165,358 @@
- newfrag->size = fn->size;
- newfrag->node = fn;
- newfrag->node->frags = 1;
-- newfrag->next = (void *)0xdeadbeef;
-+
-+ ret = jffs2_add_frag_to_fragtree(c, &f->fragtree, newfrag);
-+ if (ret)
-+ return ret;
-+
-+ /* If we now share a page with other nodes, mark either previous
-+ or next node REF_NORMAL, as appropriate. */
-+ if (newfrag->ofs & (PAGE_CACHE_SIZE-1)) {
-+ struct jffs2_node_frag *prev = frag_prev(newfrag);
-+
-+ mark_ref_normal(fn->raw);
-+ /* If we don't start at zero there's _always_ a previous */
-+ if (prev->node)
-+ mark_ref_normal(prev->node->raw);
-+ }
-+
-+ if ((newfrag->ofs+newfrag->size) & (PAGE_CACHE_SIZE-1)) {
-+ struct jffs2_node_frag *next = frag_next(newfrag);
-+
-+ if (next) {
-+ mark_ref_normal(fn->raw);
-+ if (next->node)
-+ mark_ref_normal(next->node->raw);
-+ }
-+ }
-+ D2(if (jffs2_sanitycheck_fragtree(f)) {
-+ printk(KERN_WARNING "Just added node %04x-%04x @0x%08x on flash, newfrag *%p\n",
-+ fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag);
-+ return 0;
-+ })
-+ D2(jffs2_print_frag_list(f));
-+ return 0;
-+}
-+
-+/* Doesn't set inode->i_size */
-+static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag)
-+{
-+ struct jffs2_node_frag *this;
-+ uint32_t lastend;
-
- /* Skip all the nodes which are completed before this one starts */
-- while(this && fn->ofs >= this->ofs+this->size) {
-- lastend = this->ofs + this->size;
-+ this = jffs2_lookup_node_frag(list, newfrag->node->ofs);
-
-- D2(printk(KERN_DEBUG "j_a_f_d_t_f: skipping frag 0x%04x-0x%04x; phys 0x%08x (*%p->%p)\n",
-- this->ofs, this->ofs+this->size, this->node?(this->node->raw->flash_offset &~3):0xffffffff, this, this->next));
-- prev = &this->next;
-- this = this->next;
-+ if (this) {
-+ D2(printk(KERN_DEBUG "j_a_f_d_t_f: Lookup gave frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n",
-+ this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this));
-+ lastend = this->ofs + this->size;
-+ } else {
-+ D2(printk(KERN_DEBUG "j_a_f_d_t_f: Lookup gave no frag\n"));
-+ lastend = 0;
- }
-
- /* See if we ran off the end of the list */
-- if (!this) {
-+ if (lastend <= newfrag->ofs) {
- /* We did */
-- if (lastend < fn->ofs) {
-+
-+ /* Check if 'this' node was on the same page as the new node.
-+ If so, both 'this' and the new node get marked REF_NORMAL so
-+ the GC can take a look.
-+ */
-+ if ((lastend-1) >> PAGE_CACHE_SHIFT == newfrag->ofs >> PAGE_CACHE_SHIFT) {
-+ if (this->node)
-+ mark_ref_normal(this->node->raw);
-+ mark_ref_normal(newfrag->node->raw);
-+ }
-+
-+ if (lastend < newfrag->node->ofs) {
- /* ... and we need to put a hole in before the new node */
- struct jffs2_node_frag *holefrag = jffs2_alloc_node_frag();
-- if (!holefrag)
-+ if (!holefrag) {
-+ jffs2_free_node_frag(newfrag);
- return -ENOMEM;
-+ }
- holefrag->ofs = lastend;
-- holefrag->size = fn->ofs - lastend;
-- holefrag->next = NULL;
-+ holefrag->size = newfrag->node->ofs - lastend;
- holefrag->node = NULL;
-- *prev = holefrag;
-- prev = &holefrag->next;
-+ if (this) {
-+ /* By definition, the 'this' node has no right-hand child,
-+ because there are no frags with offset greater than it.
-+ So that's where we want to put the hole */
-+ D2(printk(KERN_DEBUG "Adding hole frag (%p) on right of node at (%p)\n", holefrag, this));
-+ rb_link_node(&holefrag->rb, &this->rb, &this->rb.rb_right);
-+ } else {
-+ D2(printk(KERN_DEBUG "Adding hole frag (%p) at root of tree\n", holefrag));
-+ rb_link_node(&holefrag->rb, NULL, &list->rb_node);
-+ }
-+ rb_insert_color(&holefrag->rb, list);
-+ this = holefrag;
- }
-- newfrag->next = NULL;
-- *prev = newfrag;
-+ if (this) {
-+ /* By definition, the 'this' node has no right-hand child,
-+ because there are no frags with offset greater than it.
-+ So that's where we want to put the hole */
-+ D2(printk(KERN_DEBUG "Adding new frag (%p) on right of node at (%p)\n", newfrag, this));
-+ rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right);
-+ } else {
-+ D2(printk(KERN_DEBUG "Adding new frag (%p) at root of tree\n", newfrag));
-+ rb_link_node(&newfrag->rb, NULL, &list->rb_node);
-+ }
-+ rb_insert_color(&newfrag->rb, list);
- return 0;
- }
-
-- D2(printk(KERN_DEBUG "j_a_f_d_t_f: dealing with frag 0x%04x-0x%04x; phys 0x%08x (*%p->%p)\n",
-- this->ofs, this->ofs+this->size, this->node?(this->node->raw->flash_offset &~3):0xffffffff, this, this->next));
-+ D2(printk(KERN_DEBUG "j_a_f_d_t_f: dealing with frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n",
-+ this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this));
-
-- /* OK. 'this' is pointing at the first frag that fn->ofs at least partially obsoletes,
-- * - i.e. fn->ofs < this->ofs+this->size && fn->ofs >= this->ofs
-+ /* OK. 'this' is pointing at the first frag that newfrag->ofs at least partially obsoletes,
-+ * - i.e. newfrag->ofs < this->ofs+this->size && newfrag->ofs >= this->ofs
- */
-- if (fn->ofs > this->ofs) {
-+ if (newfrag->ofs > this->ofs) {
- /* This node isn't completely obsoleted. The start of it remains valid */
-- if (this->ofs + this->size > fn->ofs + fn->size) {
-+
-+ /* Mark the new node and the partially covered node REF_NORMAL -- let
-+ the GC take a look at them */
-+ mark_ref_normal(newfrag->node->raw);
-+ if (this->node)
-+ mark_ref_normal(this->node->raw);
-+
-+ if (this->ofs + this->size > newfrag->ofs + newfrag->size) {
- /* The new node splits 'this' frag into two */
-- newfrag2 = jffs2_alloc_node_frag();
-+ struct jffs2_node_frag *newfrag2 = jffs2_alloc_node_frag();
- if (!newfrag2) {
- jffs2_free_node_frag(newfrag);
- return -ENOMEM;
- }
-- D1(printk(KERN_DEBUG "split old frag 0x%04x-0x%04x -->", this->ofs, this->ofs+this->size);
-+ D2(printk(KERN_DEBUG "split old frag 0x%04x-0x%04x -->", this->ofs, this->ofs+this->size);
- if (this->node)
-- printk("phys 0x%08x\n", this->node->raw->flash_offset &~3);
-+ printk("phys 0x%08x\n", ref_offset(this->node->raw));
- else
- printk("hole\n");
- )
-- newfrag2->ofs = fn->ofs + fn->size;
-+
-+ /* New second frag pointing to this's node */
-+ newfrag2->ofs = newfrag->ofs + newfrag->size;
- newfrag2->size = (this->ofs+this->size) - newfrag2->ofs;
-- newfrag2->next = this->next;
- newfrag2->node = this->node;
- if (this->node)
- this->node->frags++;
-- newfrag->next = newfrag2;
-- this->next = newfrag;
-+
-+ /* Adjust size of original 'this' */
- this->size = newfrag->ofs - this->ofs;
-+
-+ /* Now, we know there's no node with offset
-+ greater than this->ofs but smaller than
-+ newfrag2->ofs or newfrag->ofs, for obvious
-+ reasons. So we can do a tree insert from
-+ 'this' to insert newfrag, and a tree insert
-+ from newfrag to insert newfrag2. */
-+ jffs2_fragtree_insert(newfrag, this);
-+ rb_insert_color(&newfrag->rb, list);
-+
-+ jffs2_fragtree_insert(newfrag2, newfrag);
-+ rb_insert_color(&newfrag2->rb, list);
-+
- return 0;
- }
- /* New node just reduces 'this' frag in size, doesn't split it */
-- this->size = fn->ofs - this->ofs;
-- newfrag->next = this->next;
-- this->next = newfrag;
-- this = newfrag->next;
-+ this->size = newfrag->ofs - this->ofs;
-+
-+ /* Again, we know it lives down here in the tree */
-+ jffs2_fragtree_insert(newfrag, this);
-+ rb_insert_color(&newfrag->rb, list);
- } else {
-- D2(printk(KERN_DEBUG "Inserting newfrag (*%p) in before 'this' (*%p)\n", newfrag, this));
-- *prev = newfrag;
-- newfrag->next = this;
-+ /* New frag starts at the same point as 'this' used to. Replace
-+ it in the tree without doing a delete and insertion */
-+ D2(printk(KERN_DEBUG "Inserting newfrag (*%p),%d-%d in before 'this' (*%p),%d-%d\n",
-+ newfrag, newfrag->ofs, newfrag->ofs+newfrag->size,
-+ this, this->ofs, this->ofs+this->size));
-+
-+ rb_replace_node(&this->rb, &newfrag->rb, list);
-+
-+ if (newfrag->ofs + newfrag->size >= this->ofs+this->size) {
-+ D2(printk(KERN_DEBUG "Obsoleting node frag %p (%x-%x)\n", this, this->ofs, this->ofs+this->size));
-+ jffs2_obsolete_node_frag(c, this);
-+ } else {
-+ this->ofs += newfrag->size;
-+ this->size -= newfrag->size;
-+
-+ jffs2_fragtree_insert(this, newfrag);
-+ rb_insert_color(&this->rb, list);
-+ return 0;
- }
-- /* OK, now we have newfrag added in the correct place in the list, but
-- newfrag->next points to a fragment which may be overlapping it
-+ }
-+ /* OK, now we have newfrag added in the correct place in the tree, but
-+ frag_next(newfrag) may be a fragment which is overlapped by it
- */
-- while (this && newfrag->ofs + newfrag->size >= this->ofs + this->size) {
-- /* 'this' frag is obsoleted. */
-- old = this;
-- this = old->next;
-- jffs2_obsolete_node_frag(c, old);
-+ while ((this = frag_next(newfrag)) && newfrag->ofs + newfrag->size >= this->ofs + this->size) {
-+ /* 'this' frag is obsoleted completely. */
-+ D2(printk(KERN_DEBUG "Obsoleting node frag %p (%x-%x) and removing from tree\n", this, this->ofs, this->ofs+this->size));
-+ rb_erase(&this->rb, list);
-+ jffs2_obsolete_node_frag(c, this);
- }
- /* Now we're pointing at the first frag which isn't totally obsoleted by
- the new frag */
-- newfrag->next = this;
-
- if (!this || newfrag->ofs + newfrag->size == this->ofs) {
- return 0;
- }
-- /* Still some overlap */
-+ /* Still some overlap but we don't need to move it in the tree */
- this->size = (this->ofs + this->size) - (newfrag->ofs + newfrag->size);
- this->ofs = newfrag->ofs + newfrag->size;
-+
-+ /* And mark them REF_NORMAL so the GC takes a look at them */
-+ if (this->node)
-+ mark_ref_normal(this->node->raw);
-+ mark_ref_normal(newfrag->node->raw);
-+
- return 0;
- }
-
--void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct jffs2_node_frag **list, __u32 size)
-+void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size)
- {
-+ struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size);
-+
- D1(printk(KERN_DEBUG "Truncating fraglist to 0x%08x bytes\n", size));
-
-- while (*list) {
-- if ((*list)->ofs >= size) {
-- struct jffs2_node_frag *this = *list;
-- *list = this->next;
-- D1(printk(KERN_DEBUG "Removing frag 0x%08x-0x%08x\n", this->ofs, this->ofs+this->size));
-- jffs2_obsolete_node_frag(c, this);
-- continue;
-- } else if ((*list)->ofs + (*list)->size > size) {
-- D1(printk(KERN_DEBUG "Truncating frag 0x%08x-0x%08x\n", (*list)->ofs, (*list)->ofs + (*list)->size));
-- (*list)->size = size - (*list)->ofs;
-- }
-- list = &(*list)->next;
-+ /* We know frag->ofs <= size. That's what lookup does for us */
-+ if (frag && frag->ofs != size) {
-+ if (frag->ofs+frag->size >= size) {
-+ D1(printk(KERN_DEBUG "Truncating frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size));
-+ frag->size = size - frag->ofs;
-+ }
-+ frag = frag_next(frag);
-+ }
-+ while (frag && frag->ofs >= size) {
-+ struct jffs2_node_frag *next = frag_next(frag);
-+
-+ D1(printk(KERN_DEBUG "Removing frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size));
-+ frag_erase(frag, list);
-+ jffs2_obsolete_node_frag(c, frag);
-+ frag = next;
- }
- }
-
- /* Scan the list of all nodes present for this ino, build map of versions, etc. */
-
--void jffs2_read_inode (struct inode *inode)
-+static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
-+ struct jffs2_inode_info *f,
-+ struct jffs2_raw_inode *latest_node);
-+
-+int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
-+ uint32_t ino, struct jffs2_raw_inode *latest_node)
- {
-- struct jffs2_tmp_dnode_info *tn_list, *tn;
-- struct jffs2_full_dirent *fd_list;
-- struct jffs2_inode_info *f;
-- struct jffs2_full_dnode *fn = NULL;
-- struct jffs2_sb_info *c;
-- struct jffs2_raw_inode latest_node;
-- __u32 latest_mctime, mctime_ver;
-- __u32 mdata_ver = 0;
-- int ret;
-- ssize_t retlen;
-+ D2(printk(KERN_DEBUG "jffs2_do_read_inode(): getting inocache\n"));
-
-- D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino));
-+ retry_inocache:
-+ spin_lock(&c->inocache_lock);
-+ f->inocache = jffs2_get_ino_cache(c, ino);
-+
-+ D2(printk(KERN_DEBUG "jffs2_do_read_inode(): Got inocache at %p\n", f->inocache));
-+
-+ if (f->inocache) {
-+ /* Check its state. We may need to wait before we can use it */
-+ switch(f->inocache->state) {
-+ case INO_STATE_UNCHECKED:
-+ case INO_STATE_CHECKEDABSENT:
-+ f->inocache->state = INO_STATE_READING;
-+ break;
-
-- f = JFFS2_INODE_INFO(inode);
-- c = JFFS2_SB_INFO(inode->i_sb);
-+ case INO_STATE_CHECKING:
-+ case INO_STATE_GC:
-+ /* If it's in either of these states, we need
-+ to wait for whoever's got it to finish and
-+ put it back. */
-+ D1(printk(KERN_DEBUG "jffs2_get_ino_cache_read waiting for ino #%u in state %d\n",
-+ ino, f->inocache->state));
-+ sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
-+ goto retry_inocache;
-+
-+ case INO_STATE_READING:
-+ case INO_STATE_PRESENT:
-+ /* Eep. This should never happen. It can
-+ happen if Linux calls read_inode() again
-+ before clear_inode() has finished though. */
-+ printk(KERN_WARNING "Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->state);
-+ /* Fail. That's probably better than allowing it to succeed */
-+ f->inocache = NULL;
-+ break;
-
-- memset(f, 0, sizeof(*f));
-- D2(printk(KERN_DEBUG "getting inocache\n"));
-- init_MUTEX(&f->sem);
-- f->inocache = jffs2_get_ino_cache(c, inode->i_ino);
-- D2(printk(KERN_DEBUG "jffs2_read_inode(): Got inocache at %p\n", f->inocache));
-+ default:
-+ BUG();
-+ }
-+ }
-+ spin_unlock(&c->inocache_lock);
-
-- if (!f->inocache && inode->i_ino == 1) {
-+ if (!f->inocache && ino == 1) {
- /* Special case - no root inode on medium */
- f->inocache = jffs2_alloc_inode_cache();
- if (!f->inocache) {
-- printk(KERN_CRIT "jffs2_read_inode(): Cannot allocate inocache for root inode\n");
-- make_bad_inode(inode);
-- return;
-+ printk(KERN_CRIT "jffs2_do_read_inode(): Cannot allocate inocache for root inode\n");
-+ return -ENOMEM;
- }
-- D1(printk(KERN_DEBUG "jffs2_read_inode(): Creating inocache for root inode\n"));
-+ D1(printk(KERN_DEBUG "jffs2_do_read_inode(): Creating inocache for root inode\n"));
- memset(f->inocache, 0, sizeof(struct jffs2_inode_cache));
- f->inocache->ino = f->inocache->nlink = 1;
- f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
-+ f->inocache->state = INO_STATE_READING;
- jffs2_add_ino_cache(c, f->inocache);
- }
- if (!f->inocache) {
-- printk(KERN_WARNING "jffs2_read_inode() on nonexistent ino %lu\n", (unsigned long)inode->i_ino);
-- make_bad_inode(inode);
-- return;
-+ printk(KERN_WARNING "jffs2_do_read_inode() on nonexistent ino %u\n", ino);
-+ return -ENOENT;
- }
-- D1(printk(KERN_DEBUG "jffs2_read_inode(): ino #%lu nlink is %d\n", (unsigned long)inode->i_ino, f->inocache->nlink));
-- inode->i_nlink = f->inocache->nlink;
-+
-+ return jffs2_do_read_inode_internal(c, f, latest_node);
-+}
-+
-+int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
-+{
-+ struct jffs2_raw_inode n;
-+ struct jffs2_inode_info *f = kmalloc(sizeof(*f), GFP_KERNEL);
-+ int ret;
-+
-+ if (!f)
-+ return -ENOMEM;
-+
-+ memset(f, 0, sizeof(*f));
-+ init_MUTEX_LOCKED(&f->sem);
-+ f->inocache = ic;
-+
-+ ret = jffs2_do_read_inode_internal(c, f, &n);
-+ if (!ret) {
-+ up(&f->sem);
-+ jffs2_do_clear_inode(c, f);
-+ }
-+ kfree (f);
-+ return ret;
-+}
-+
-+static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
-+ struct jffs2_inode_info *f,
-+ struct jffs2_raw_inode *latest_node)
-+{
-+ struct jffs2_tmp_dnode_info *tn_list, *tn;
-+ struct jffs2_full_dirent *fd_list;
-+ struct jffs2_full_dnode *fn = NULL;
-+ uint32_t crc;
-+ uint32_t latest_mctime, mctime_ver;
-+ uint32_t mdata_ver = 0;
-+ size_t retlen;
-+ int ret;
-+
-+ D1(printk(KERN_DEBUG "jffs2_do_read_inode_internal(): ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink));
-
- /* Grab all nodes relevant to this ino */
-- ret = jffs2_get_inode_nodes(c, inode->i_ino, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver);
-+ ret = jffs2_get_inode_nodes(c, f->inocache->ino, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver);
-
- if (ret) {
-- printk(KERN_CRIT "jffs2_get_inode_nodes() for ino %lu returned %d\n", inode->i_ino, ret);
-- make_bad_inode(inode);
-- return;
-+ printk(KERN_CRIT "jffs2_get_inode_nodes() for ino %u returned %d\n", f->inocache->ino, ret);
-+ if (f->inocache->state == INO_STATE_READING)
-+ jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
-+ return ret;
- }
- f->dents = fd_list;
-
-@@ -304,205 +525,169 @@
-
- fn = tn->fn;
-
-- if (f->metadata && tn->version > mdata_ver) {
-- D1(printk(KERN_DEBUG "Obsoleting old metadata at 0x%08x\n", f->metadata->raw->flash_offset &~3));
-+ if (f->metadata) {
-+ if (likely(tn->version >= mdata_ver)) {
-+ D1(printk(KERN_DEBUG "Obsoleting old metadata at 0x%08x\n", ref_offset(f->metadata->raw)));
- jffs2_mark_node_obsolete(c, f->metadata->raw);
- jffs2_free_full_dnode(f->metadata);
- f->metadata = NULL;
-
- mdata_ver = 0;
-+ } else {
-+ /* This should never happen. */
-+ printk(KERN_WARNING "Er. New metadata at 0x%08x with ver %d is actually older than previous ver %d at 0x%08x\n",
-+ ref_offset(fn->raw), tn->version, mdata_ver, ref_offset(f->metadata->raw));
-+ jffs2_mark_node_obsolete(c, fn->raw);
-+ jffs2_free_full_dnode(fn);
-+ /* Fill in latest_node from the metadata, not this one we're about to free... */
-+ fn = f->metadata;
-+ goto next_tn;
-+ }
- }
-
- if (fn->size) {
- jffs2_add_full_dnode_to_inode(c, f, fn);
- } else {
- /* Zero-sized node at end of version list. Just a metadata update */
-- D1(printk(KERN_DEBUG "metadata @%08x: ver %d\n", fn->raw->flash_offset &~3, tn->version));
-+ D1(printk(KERN_DEBUG "metadata @%08x: ver %d\n", ref_offset(fn->raw), tn->version));
- f->metadata = fn;
- mdata_ver = tn->version;
- }
-+ next_tn:
- tn_list = tn->next;
- jffs2_free_tmp_dnode_info(tn);
- }
-+ D1(jffs2_sanitycheck_fragtree(f));
-+
- if (!fn) {
- /* No data nodes for this inode. */
-- if (inode->i_ino != 1) {
-- printk(KERN_WARNING "jffs2_read_inode(): No data nodes found for ino #%lu\n", inode->i_ino);
-+ if (f->inocache->ino != 1) {
-+ printk(KERN_WARNING "jffs2_do_read_inode(): No data nodes found for ino #%u\n", f->inocache->ino);
- if (!fd_list) {
-- make_bad_inode(inode);
-- return;
-- }
-- printk(KERN_WARNING "jffs2_read_inode(): But it has children so we fake some modes for it\n");
-+ if (f->inocache->state == INO_STATE_READING)
-+ jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
-+ return -EIO;
-+ }
-+ printk(KERN_WARNING "jffs2_do_read_inode(): But it has children so we fake some modes for it\n");
-+ }
-+ latest_node->mode = cpu_to_jemode(S_IFDIR|S_IRUGO|S_IWUSR|S_IXUGO);
-+ latest_node->version = cpu_to_je32(0);
-+ latest_node->atime = latest_node->ctime = latest_node->mtime = cpu_to_je32(0);
-+ latest_node->isize = cpu_to_je32(0);
-+ latest_node->gid = cpu_to_je16(0);
-+ latest_node->uid = cpu_to_je16(0);
-+ if (f->inocache->state == INO_STATE_READING)
-+ jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
-+ return 0;
- }
-- inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO;
-- latest_node.version = 0;
-- inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME;
-- inode->i_nlink = f->inocache->nlink;
-- inode->i_size = 0;
-- } else {
-- __u32 crc;
-
-- ret = c->mtd->read(c->mtd, fn->raw->flash_offset & ~3, sizeof(latest_node), &retlen, (void *)&latest_node);
-- if (ret || retlen != sizeof(latest_node)) {
-- printk(KERN_NOTICE "MTD read in jffs2_read_inode() failed: Returned %d, %ld of %d bytes read\n",
-- ret, (long)retlen, sizeof(latest_node));
-- jffs2_clear_inode(inode);
-- make_bad_inode(inode);
-- return;
-- }
--
-- crc = crc32(0, &latest_node, sizeof(latest_node)-8);
-- if (crc != latest_node.node_crc) {
-- printk(KERN_NOTICE "CRC failed for read_inode of inode %ld at physical location 0x%x\n", inode->i_ino, fn->raw->flash_offset & ~3);
-- jffs2_clear_inode(inode);
-- make_bad_inode(inode);
-- return;
-- }
--
-- inode->i_mode = latest_node.mode;
-- inode->i_uid = latest_node.uid;
-- inode->i_gid = latest_node.gid;
-- inode->i_size = latest_node.isize;
-- if (S_ISREG(inode->i_mode))
-- jffs2_truncate_fraglist(c, &f->fraglist, latest_node.isize);
-- inode->i_atime = latest_node.atime;
-- inode->i_mtime = latest_node.mtime;
-- inode->i_ctime = latest_node.ctime;
-- }
--
-- /* OK, now the special cases. Certain inode types should
-- have only one data node, and it's kept as the metadata
-- node */
-- if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode) ||
-- S_ISLNK(inode->i_mode)) {
-- if (f->metadata) {
-- printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o had metadata node\n", inode->i_ino, inode->i_mode);
-- jffs2_clear_inode(inode);
-- make_bad_inode(inode);
-- return;
-- }
-- if (!f->fraglist) {
-- printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o has no fragments\n", inode->i_ino, inode->i_mode);
-- jffs2_clear_inode(inode);
-- make_bad_inode(inode);
-- return;
-- }
-- /* ASSERT: f->fraglist != NULL */
-- if (f->fraglist->next) {
-- printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o had more than one node\n", inode->i_ino, inode->i_mode);
-- /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
-- jffs2_clear_inode(inode);
-- make_bad_inode(inode);
-- return;
-- }
-- /* OK. We're happy */
-- f->metadata = f->fraglist->node;
-- jffs2_free_node_frag(f->fraglist);
-- f->fraglist = NULL;
-+ ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(*latest_node), &retlen, (void *)latest_node);
-+ if (ret || retlen != sizeof(*latest_node)) {
-+ printk(KERN_NOTICE "MTD read in jffs2_do_read_inode() failed: Returned %d, %zd of %zd bytes read\n",
-+ ret, retlen, sizeof(*latest_node));
-+ /* FIXME: If this fails, there seems to be a memory leak. Find it. */
-+ up(&f->sem);
-+ jffs2_do_clear_inode(c, f);
-+ return ret?ret:-EIO;
- }
-
-- inode->i_blksize = PAGE_SIZE;
-- inode->i_blocks = (inode->i_size + 511) >> 9;
--
-- switch (inode->i_mode & S_IFMT) {
-- unsigned short rdev;
--
-- case S_IFLNK:
-- inode->i_op = &jffs2_symlink_inode_operations;
-- /* Hack to work around broken isize in old symlink code.
-- Remove this when dwmw2 comes to his senses and stops
-- symlinks from being an entirely gratuitous special
-- case. */
-- if (!inode->i_size)
-- inode->i_size = latest_node.dsize;
-- break;
-+ crc = crc32(0, latest_node, sizeof(*latest_node)-8);
-+ if (crc != je32_to_cpu(latest_node->node_crc)) {
-+ printk(KERN_NOTICE "CRC failed for read_inode of inode %u at physical location 0x%x\n", f->inocache->ino, ref_offset(fn->raw));
-+ up(&f->sem);
-+ jffs2_do_clear_inode(c, f);
-+ return -EIO;
-+ }
-
-+ switch(jemode_to_cpu(latest_node->mode) & S_IFMT) {
- case S_IFDIR:
-- if (mctime_ver > latest_node.version) {
-+ if (mctime_ver > je32_to_cpu(latest_node->version)) {
- /* The times in the latest_node are actually older than
- mctime in the latest dirent. Cheat. */
-- inode->i_mtime = inode->i_ctime = inode->i_atime =
-- latest_mctime;
-+ latest_node->ctime = latest_node->mtime = cpu_to_je32(latest_mctime);
- }
-- inode->i_op = &jffs2_dir_inode_operations;
-- inode->i_fop = &jffs2_dir_operations;
- break;
-
-+
- case S_IFREG:
-- inode->i_op = &jffs2_file_inode_operations;
-- inode->i_fop = &jffs2_file_operations;
-- inode->i_mapping->a_ops = &jffs2_file_address_operations;
-- inode->i_mapping->nrpages = 0;
-+ /* If it was a regular file, truncate it to the latest node's isize */
-+ jffs2_truncate_fraglist(c, &f->fragtree, je32_to_cpu(latest_node->isize));
- break;
-
-+ case S_IFLNK:
-+ /* Hack to work around broken isize in old symlink code.
-+ Remove this when dwmw2 comes to his senses and stops
-+ symlinks from being an entirely gratuitous special
-+ case. */
-+ if (!je32_to_cpu(latest_node->isize))
-+ latest_node->isize = latest_node->dsize;
-+ /* fall through... */
-+
- case S_IFBLK:
- case S_IFCHR:
-- /* Read the device numbers from the media */
-- D1(printk(KERN_DEBUG "Reading device numbers from flash\n"));
-- if (jffs2_read_dnode(c, f->metadata, (char *)&rdev, 0, sizeof(rdev)) < 0) {
-- /* Eep */
-- printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino);
-- jffs2_clear_inode(inode);
-- make_bad_inode(inode);
-- return;
-+ /* Certain inode types should have only one data node, and it's
-+ kept as the metadata node */
-+ if (f->metadata) {
-+ printk(KERN_WARNING "Argh. Special inode #%u with mode 0%o had metadata node\n",
-+ f->inocache->ino, jemode_to_cpu(latest_node->mode));
-+ up(&f->sem);
-+ jffs2_do_clear_inode(c, f);
-+ return -EIO;
- }
--
-- case S_IFSOCK:
-- case S_IFIFO:
-- inode->i_op = &jffs2_file_inode_operations;
-- init_special_inode(inode, inode->i_mode, kdev_t_to_nr(MKDEV(rdev>>8, rdev&0xff)));
-+ if (!frag_first(&f->fragtree)) {
-+ printk(KERN_WARNING "Argh. Special inode #%u with mode 0%o has no fragments\n",
-+ f->inocache->ino, jemode_to_cpu(latest_node->mode));
-+ up(&f->sem);
-+ jffs2_do_clear_inode(c, f);
-+ return -EIO;
-+ }
-+ /* ASSERT: f->fraglist != NULL */
-+ if (frag_next(frag_first(&f->fragtree))) {
-+ printk(KERN_WARNING "Argh. Special inode #%u with mode 0x%x had more than one node\n",
-+ f->inocache->ino, jemode_to_cpu(latest_node->mode));
-+ /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
-+ up(&f->sem);
-+ jffs2_do_clear_inode(c, f);
-+ return -EIO;
-+ }
-+ /* OK. We're happy */
-+ f->metadata = frag_first(&f->fragtree)->node;
-+ jffs2_free_node_frag(frag_first(&f->fragtree));
-+ f->fragtree = RB_ROOT;
- break;
--
-- default:
-- printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu", inode->i_mode, (unsigned long)inode->i_ino);
- }
-- D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
-+ if (f->inocache->state == INO_STATE_READING)
-+ jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
-+
-+ return 0;
- }
-
--void jffs2_clear_inode (struct inode *inode)
-+void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
- {
-- /* We can forget about this inode for now - drop all
-- * the nodelists associated with it, etc.
-- */
-- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-- struct jffs2_node_frag *frag, *frags;
- struct jffs2_full_dirent *fd, *fds;
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- int deleted;
-
-- D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
--
- down(&f->sem);
- deleted = f->inocache && !f->inocache->nlink;
-
-- frags = f->fraglist;
-- fds = f->dents;
- if (f->metadata) {
- if (deleted)
- jffs2_mark_node_obsolete(c, f->metadata->raw);
- jffs2_free_full_dnode(f->metadata);
- }
-
-- while (frags) {
-- frag = frags;
-- frags = frag->next;
-- D2(printk(KERN_DEBUG "jffs2_clear_inode: frag at 0x%x-0x%x: node %p, frags %d--\n", frag->ofs, frag->ofs+frag->size, frag->node, frag->node?frag->node->frags:0));
-+ jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL);
-
-- if (frag->node && !(--frag->node->frags)) {
-- /* Not a hole, and it's the final remaining frag of this node. Free the node */
-- if (deleted)
-- jffs2_mark_node_obsolete(c, frag->node->raw);
-+ fds = f->dents;
-
-- jffs2_free_full_dnode(frag->node);
-- }
-- jffs2_free_node_frag(frag);
-- }
- while(fds) {
- fd = fds;
- fds = fd->next;
- jffs2_free_full_dirent(fd);
- }
-
-- up(&f->sem);
--};
-+ if (f->inocache && f->inocache->state != INO_STATE_CHECKING)
-+ jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
-
-+ up(&f->sem);
-+}
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/scan.c linux/fs/jffs2/scan.c
---- linux-mips-2.4.24-pre2/fs/jffs2/scan.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/scan.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,47 +1,25 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
- #include <linux/kernel.h>
-+#include <linux/sched.h>
- #include <linux/slab.h>
--#include <linux/jffs2.h>
- #include <linux/mtd/mtd.h>
- #include <linux/pagemap.h>
--#include "nodelist.h"
- #include <linux/crc32.h>
-+#include <linux/compiler.h>
-+#include "nodelist.h"
-
-+#define EMPTY_SCAN_SIZE 1024
-
- #define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
- c->free_size -= _x; c->dirty_size += _x; \
-@@ -51,6 +29,10 @@
- c->free_size -= _x; c->used_size += _x; \
- jeb->free_size -= _x ; jeb->used_size += _x; \
- }while(0)
-+#define UNCHECKED_SPACE(x) do { typeof(x) _x = (x); \
-+ c->free_size -= _x; c->unchecked_size += _x; \
-+ jeb->free_size -= _x ; jeb->unchecked_size += _x; \
-+ }while(0)
-
- #define noisy_printk(noise, args...) do { \
- if (*(noise)) { \
-@@ -63,39 +45,84 @@
- } while(0)
-
- static uint32_t pseudo_random;
--static void jffs2_rotate_lists(struct jffs2_sb_info *c);
-
--static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-+ unsigned char *buf, uint32_t buf_size);
-
- /* These helper functions _must_ increase ofs and also do the dirty/used space accounting.
- * Returning an error will abort the mount - bad checksums etc. should just mark the space
- * as dirty.
- */
--static int jffs2_scan_empty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs, int *noise);
--static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs);
--static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs);
-+static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-+ struct jffs2_raw_inode *ri, uint32_t ofs);
-+static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-+ struct jffs2_raw_dirent *rd, uint32_t ofs);
-+
-+#define BLK_STATE_ALLFF 0
-+#define BLK_STATE_CLEAN 1
-+#define BLK_STATE_PARTDIRTY 2
-+#define BLK_STATE_CLEANMARKER 3
-+#define BLK_STATE_ALLDIRTY 4
-+#define BLK_STATE_BADBLOCK 5
-
-+static inline int min_free(struct jffs2_sb_info *c)
-+{
-+ uint32_t min = 2 * sizeof(struct jffs2_raw_inode);
-+#ifdef CONFIG_JFFS2_FS_NAND
-+ if (!jffs2_can_mark_obsolete(c) && min < c->wbuf_pagesize)
-+ return c->wbuf_pagesize;
-+#endif
-+ return min;
-
-+}
- int jffs2_scan_medium(struct jffs2_sb_info *c)
- {
- int i, ret;
-- __u32 empty_blocks = 0;
--
-- if (!c->blocks) {
-- printk(KERN_WARNING "EEEK! c->blocks is NULL!\n");
-- return -EINVAL;
-+ uint32_t empty_blocks = 0, bad_blocks = 0;
-+ unsigned char *flashbuf = NULL;
-+ uint32_t buf_size = 0;
-+#ifndef __ECOS
-+ size_t pointlen;
-+
-+ if (c->mtd->point) {
-+ ret = c->mtd->point (c->mtd, 0, c->mtd->size, &pointlen, &flashbuf);
-+ if (!ret && pointlen < c->mtd->size) {
-+ /* Don't muck about if it won't let us point to the whole flash */
-+ D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", pointlen));
-+ c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);
-+ flashbuf = NULL;
-+ }
-+ if (ret)
-+ D1(printk(KERN_DEBUG "MTD point failed %d\n", ret));
-+ }
-+#endif
-+ if (!flashbuf) {
-+ /* For NAND it's quicker to read a whole eraseblock at a time,
-+ apparently */
-+ if (jffs2_cleanmarker_oob(c))
-+ buf_size = c->sector_size;
-+ else
-+ buf_size = PAGE_SIZE;
-+
-+ D1(printk(KERN_DEBUG "Allocating readbuf of %d bytes\n", buf_size));
-+ flashbuf = kmalloc(buf_size, GFP_KERNEL);
-+ if (!flashbuf)
-+ return -ENOMEM;
- }
-+
- for (i=0; i<c->nr_blocks; i++) {
- struct jffs2_eraseblock *jeb = &c->blocks[i];
-
-- ret = jffs2_scan_eraseblock(c, jeb);
-+ ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), buf_size);
-+
- if (ret < 0)
-- return ret;
-+ goto out;
-
- ACCT_PARANOIA_CHECK(jeb);
-
- /* Now decide which list to put it on */
-- if (ret == 1) {
-+ switch(ret) {
-+ case BLK_STATE_ALLFF:
- /*
- * Empty block. Since we can't be sure it
- * was entirely erased, we just queue it for erase
-@@ -103,10 +130,12 @@
- * is complete. Meanwhile we still count it as empty
- * for later checks.
- */
-- list_add(&jeb->list, &c->erase_pending_list);
- empty_blocks++;
-+ list_add(&jeb->list, &c->erase_pending_list);
- c->nr_erasing_blocks++;
-- } else if (jeb->used_size == PAD(sizeof(struct jffs2_unknown_node)) && !jeb->first_node->next_in_ino) {
-+ break;
-+
-+ case BLK_STATE_CLEANMARKER:
- /* Only a CLEANMARKER node is valid */
- if (!jeb->dirty_size) {
- /* It's actually free */
-@@ -118,74 +147,227 @@
- list_add(&jeb->list, &c->erase_pending_list);
- c->nr_erasing_blocks++;
- }
-- } else if (jeb->used_size > c->sector_size - (2*sizeof(struct jffs2_raw_inode))) {
-+ break;
-+
-+ case BLK_STATE_CLEAN:
- /* Full (or almost full) of clean data. Clean list */
- list_add(&jeb->list, &c->clean_list);
-- } else if (jeb->used_size) {
-+ break;
-+
-+ case BLK_STATE_PARTDIRTY:
- /* Some data, but not full. Dirty list. */
- /* Except that we want to remember the block with most free space,
- and stick it in the 'nextblock' position to start writing to it.
- Later when we do snapshots, this must be the most recent block,
- not the one with most free space.
- */
-- if (jeb->free_size > 2*sizeof(struct jffs2_raw_inode) &&
-+ if (jeb->free_size > min_free(c) &&
- (!c->nextblock || c->nextblock->free_size < jeb->free_size)) {
- /* Better candidate for the next writes to go to */
-- if (c->nextblock)
-+ if (c->nextblock) {
-+ c->nextblock->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size;
-+ c->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size;
-+ c->free_size -= c->nextblock->free_size;
-+ c->wasted_size -= c->nextblock->wasted_size;
-+ c->nextblock->free_size = c->nextblock->wasted_size = 0;
-+ if (VERYDIRTY(c, c->nextblock->dirty_size)) {
-+ list_add(&c->nextblock->list, &c->very_dirty_list);
-+ } else {
- list_add(&c->nextblock->list, &c->dirty_list);
-+ }
-+ }
- c->nextblock = jeb;
- } else {
-+ jeb->dirty_size += jeb->free_size + jeb->wasted_size;
-+ c->dirty_size += jeb->free_size + jeb->wasted_size;
-+ c->free_size -= jeb->free_size;
-+ c->wasted_size -= jeb->wasted_size;
-+ jeb->free_size = jeb->wasted_size = 0;
-+ if (VERYDIRTY(c, jeb->dirty_size)) {
-+ list_add(&jeb->list, &c->very_dirty_list);
-+ } else {
- list_add(&jeb->list, &c->dirty_list);
- }
-- } else {
-+ }
-+ break;
-+
-+ case BLK_STATE_ALLDIRTY:
- /* Nothing valid - not even a clean marker. Needs erasing. */
- /* For now we just put it on the erasing list. We'll start the erases later */
-- printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset);
-+ D1(printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset));
- list_add(&jeb->list, &c->erase_pending_list);
- c->nr_erasing_blocks++;
-+ break;
-+
-+ case BLK_STATE_BADBLOCK:
-+ D1(printk(KERN_NOTICE "JFFS2: Block at 0x%08x is bad\n", jeb->offset));
-+ list_add(&jeb->list, &c->bad_list);
-+ c->bad_size += c->sector_size;
-+ c->free_size -= c->sector_size;
-+ bad_blocks++;
-+ break;
-+ default:
-+ printk(KERN_WARNING "jffs2_scan_medium(): unknown block state\n");
-+ BUG();
- }
- }
-- /* Rotate the lists by some number to ensure wear levelling */
-- jffs2_rotate_lists(c);
-
-+ /* Nextblock dirty is always seen as wasted, because we cannot recycle it now */
-+ if (c->nextblock && (c->nextblock->dirty_size)) {
-+ c->nextblock->wasted_size += c->nextblock->dirty_size;
-+ c->wasted_size += c->nextblock->dirty_size;
-+ c->dirty_size -= c->nextblock->dirty_size;
-+ c->nextblock->dirty_size = 0;
-+ }
-+#ifdef CONFIG_JFFS2_FS_NAND
-+ if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) {
-+ /* If we're going to start writing into a block which already
-+ contains data, and the end of the data isn't page-aligned,
-+ skip a little and align it. */
-+
-+ uint32_t skip = c->nextblock->free_size & (c->wbuf_pagesize-1);
-+
-+ D1(printk(KERN_DEBUG "jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment\n",
-+ skip));
-+ c->nextblock->wasted_size += skip;
-+ c->wasted_size += skip;
-+
-+ c->nextblock->free_size -= skip;
-+ c->free_size -= skip;
-+ }
-+#endif
- if (c->nr_erasing_blocks) {
-- if (!c->used_size && empty_blocks != c->nr_blocks) {
-+ if ( !c->used_size && ((empty_blocks+bad_blocks)!= c->nr_blocks || bad_blocks == c->nr_blocks) ) {
- printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n");
-- return -EIO;
-+ printk(KERN_NOTICE "empty_blocks %d, bad_blocks %d, c->nr_blocks %d\n",empty_blocks,bad_blocks,c->nr_blocks);
-+ ret = -EIO;
-+ goto out;
- }
- jffs2_erase_pending_trigger(c);
- }
-+ ret = 0;
-+ out:
-+ if (buf_size)
-+ kfree(flashbuf);
-+#ifndef __ECOS
-+ else
-+ c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);
-+#endif
-+ return ret;
-+}
-+
-+static int jffs2_fill_scan_buf (struct jffs2_sb_info *c, unsigned char *buf,
-+ uint32_t ofs, uint32_t len)
-+{
-+ int ret;
-+ size_t retlen;
-+
-+ ret = jffs2_flash_read(c, ofs, len, &retlen, buf);
-+ if (ret) {
-+ D1(printk(KERN_WARNING "mtd->read(0x%x bytes from 0x%x) returned %d\n", len, ofs, ret));
-+ return ret;
-+ }
-+ if (retlen < len) {
-+ D1(printk(KERN_WARNING "Read at 0x%x gave only 0x%zx bytes\n", ofs, retlen));
-+ return -EIO;
-+ }
-+ D2(printk(KERN_DEBUG "Read 0x%x bytes from 0x%08x into buf\n", len, ofs));
-+ D2(printk(KERN_DEBUG "000: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
-+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]));
- return 0;
- }
-
--static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) {
-- struct jffs2_unknown_node node;
-- __u32 ofs, prevofs;
-- __u32 hdr_crc, nodetype;
-+static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-+ unsigned char *buf, uint32_t buf_size) {
-+ struct jffs2_unknown_node *node;
-+ struct jffs2_unknown_node crcnode;
-+ uint32_t ofs, prevofs;
-+ uint32_t hdr_crc, buf_ofs, buf_len;
- int err;
- int noise = 0;
-+ int wasempty = 0;
-+ uint32_t empty_start = 0;
-+#ifdef CONFIG_JFFS2_FS_NAND
-+ int cleanmarkerfound = 0;
-+#endif
-
- ofs = jeb->offset;
- prevofs = jeb->offset - 1;
-
- D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs));
-
-- err = jffs2_scan_empty(c, jeb, &ofs, &noise);
-- if (err) return err;
-- if (ofs == jeb->offset + c->sector_size) {
-+#ifdef CONFIG_JFFS2_FS_NAND
-+ if (jffs2_cleanmarker_oob(c)) {
-+ int ret = jffs2_check_nand_cleanmarker(c, jeb);
-+ D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret));
-+ /* Even if it's not found, we still scan to see
-+ if the block is empty. We use this information
-+ to decide whether to erase it or not. */
-+ switch (ret) {
-+ case 0: cleanmarkerfound = 1; break;
-+ case 1: break;
-+ case 2: return BLK_STATE_BADBLOCK;
-+ case 3: return BLK_STATE_ALLDIRTY; /* Block has failed to erase min. once */
-+ default: return ret;
-+ }
-+ }
-+#endif
-+ buf_ofs = jeb->offset;
-+
-+ if (!buf_size) {
-+ buf_len = c->sector_size;
-+ } else {
-+ buf_len = EMPTY_SCAN_SIZE;
-+ err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
-+ if (err)
-+ return err;
-+ }
-+
-+ /* We temporarily use 'ofs' as a pointer into the buffer/jeb */
-+ ofs = 0;
-+
-+ /* Scan only 4KiB of 0xFF before declaring it's empty */
-+ while(ofs < EMPTY_SCAN_SIZE && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF)
-+ ofs += 4;
-+
-+ if (ofs == EMPTY_SCAN_SIZE) {
-+#ifdef CONFIG_JFFS2_FS_NAND
-+ if (jffs2_cleanmarker_oob(c)) {
-+ /* scan oob, take care of cleanmarker */
-+ int ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound);
-+ D2(printk(KERN_NOTICE "jffs2_check_oob_empty returned %d\n",ret));
-+ switch (ret) {
-+ case 0: return cleanmarkerfound ? BLK_STATE_CLEANMARKER : BLK_STATE_ALLFF;
-+ case 1: return BLK_STATE_ALLDIRTY;
-+ case 2: return BLK_STATE_BADBLOCK; /* case 2/3 are paranoia checks */
-+ case 3: return BLK_STATE_ALLDIRTY; /* Block has failed to erase min. once */
-+ default: return ret;
-+ }
-+ }
-+#endif
- D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset));
-- return 1; /* special return code */
-+ return BLK_STATE_ALLFF; /* OK to erase if all blocks are like this */
-+ }
-+ if (ofs) {
-+ D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset,
-+ jeb->offset + ofs));
-+ DIRTY_SPACE(ofs);
- }
-
-+ /* Now ofs is a complete physical flash offset as it always was... */
-+ ofs += jeb->offset;
-+
- noise = 10;
-
- while(ofs < jeb->offset + c->sector_size) {
-- ssize_t retlen;
-- ACCT_PARANOIA_CHECK(jeb);
-+
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+
-+ cond_resched();
-
- if (ofs & 3) {
- printk(KERN_WARNING "Eep. ofs 0x%08x not word-aligned!\n", ofs);
-- ofs = (ofs+3)&~3;
-+ ofs = PAD(ofs);
- continue;
- }
- if (ofs == prevofs) {
-@@ -196,102 +378,173 @@
- }
- prevofs = ofs;
-
-- if (jeb->offset + c->sector_size < ofs + sizeof(node)) {
-- D1(printk(KERN_DEBUG "Fewer than %d bytes left to end of block. Not reading\n", sizeof(struct jffs2_unknown_node)));
-+ if (jeb->offset + c->sector_size < ofs + sizeof(*node)) {
-+ D1(printk(KERN_DEBUG "Fewer than %zd bytes left to end of block. (%x+%x<%x+%zx) Not reading\n", sizeof(struct jffs2_unknown_node),
-+ jeb->offset, c->sector_size, ofs, sizeof(*node)));
- DIRTY_SPACE((jeb->offset + c->sector_size)-ofs);
- break;
- }
-
-- err = c->mtd->read(c->mtd, ofs, sizeof(node), &retlen, (char *)&node);
--
-- if (err) {
-- D1(printk(KERN_WARNING "mtd->read(0x%x bytes from 0x%x) returned %d\n", sizeof(node), ofs, err));
-+ if (buf_ofs + buf_len < ofs + sizeof(*node)) {
-+ buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
-+ D1(printk(KERN_DEBUG "Fewer than %zd bytes (node header) left to end of buf. Reading 0x%x at 0x%08x\n",
-+ sizeof(struct jffs2_unknown_node), buf_len, ofs));
-+ err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
-+ if (err)
- return err;
-+ buf_ofs = ofs;
- }
-- if (retlen < sizeof(node)) {
-- D1(printk(KERN_WARNING "Read at 0x%x gave only 0x%x bytes\n", ofs, retlen));
-- DIRTY_SPACE(retlen);
-- ofs += retlen;
-- continue;
-+
-+ node = (struct jffs2_unknown_node *)&buf[ofs-buf_ofs];
-+
-+ if (*(uint32_t *)(&buf[ofs-buf_ofs]) == 0xffffffff) {
-+ uint32_t inbuf_ofs = ofs - buf_ofs + 4;
-+ uint32_t scanend;
-+
-+ empty_start = ofs;
-+ ofs += 4;
-+
-+ /* If scanning empty space after only a cleanmarker, don't
-+ bother scanning the whole block */
-+ if (unlikely(empty_start == jeb->offset + c->cleanmarker_size &&
-+ jeb->offset + EMPTY_SCAN_SIZE < buf_ofs + buf_len))
-+ scanend = jeb->offset + EMPTY_SCAN_SIZE - buf_ofs;
-+ else
-+ scanend = buf_len;
-+
-+ D1(printk(KERN_DEBUG "Found empty flash at 0x%08x\n", ofs));
-+ while (inbuf_ofs < scanend) {
-+ if (*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff)
-+ goto emptyends;
-+
-+ inbuf_ofs+=4;
-+ ofs += 4;
- }
-+ /* Ran off end. */
-+ D1(printk(KERN_DEBUG "Empty flash ends normally at 0x%08x\n", ofs));
-
-- if (node.magic == JFFS2_EMPTY_BITMASK && node.nodetype == JFFS2_EMPTY_BITMASK) {
-- D1(printk(KERN_DEBUG "Found empty flash at 0x%x\n", ofs));
-- err = jffs2_scan_empty(c, jeb, &ofs, &noise);
-- if (err) return err;
-+ if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) &&
-+ c->cleanmarker_size && !jeb->first_node->next_in_ino && !jeb->dirty_size)
-+ return BLK_STATE_CLEANMARKER;
-+ wasempty = 1;
-+ continue;
-+ } else if (wasempty) {
-+ emptyends:
-+ printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n", empty_start, ofs);
-+ DIRTY_SPACE(ofs-empty_start);
-+ wasempty = 0;
- continue;
- }
-
-- if (ofs == jeb->offset && node.magic == KSAMTIB_CIGAM_2SFFJ) {
-+ if (ofs == jeb->offset && je16_to_cpu(node->magic) == KSAMTIB_CIGAM_2SFFJ) {
- printk(KERN_WARNING "Magic bitmask is backwards at offset 0x%08x. Wrong endian filesystem?\n", ofs);
- DIRTY_SPACE(4);
- ofs += 4;
- continue;
- }
-- if (node.magic == JFFS2_DIRTY_BITMASK) {
-- D1(printk(KERN_DEBUG "Empty bitmask at 0x%08x\n", ofs));
-+ if (je16_to_cpu(node->magic) == JFFS2_DIRTY_BITMASK) {
-+ D1(printk(KERN_DEBUG "Dirty bitmask at 0x%08x\n", ofs));
- DIRTY_SPACE(4);
- ofs += 4;
- continue;
- }
-- if (node.magic == JFFS2_OLD_MAGIC_BITMASK) {
-+ if (je16_to_cpu(node->magic) == JFFS2_OLD_MAGIC_BITMASK) {
- printk(KERN_WARNING "Old JFFS2 bitmask found at 0x%08x\n", ofs);
- printk(KERN_WARNING "You cannot use older JFFS2 filesystems with newer kernels\n");
- DIRTY_SPACE(4);
- ofs += 4;
- continue;
- }
-- if (node.magic != JFFS2_MAGIC_BITMASK) {
-+ if (je16_to_cpu(node->magic) != JFFS2_MAGIC_BITMASK) {
- /* OK. We're out of possibilities. Whinge and move on */
-- noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n", JFFS2_MAGIC_BITMASK, ofs, node.magic);
-+ noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n",
-+ JFFS2_MAGIC_BITMASK, ofs,
-+ je16_to_cpu(node->magic));
- DIRTY_SPACE(4);
- ofs += 4;
- continue;
- }
- /* We seem to have a node of sorts. Check the CRC */
-- nodetype = node.nodetype;
-- node.nodetype |= JFFS2_NODE_ACCURATE;
-- hdr_crc = crc32(0, &node, sizeof(node)-4);
-- node.nodetype = nodetype;
-- if (hdr_crc != node.hdr_crc) {
-+ crcnode.magic = node->magic;
-+ crcnode.nodetype = cpu_to_je16( je16_to_cpu(node->nodetype) | JFFS2_NODE_ACCURATE);
-+ crcnode.totlen = node->totlen;
-+ hdr_crc = crc32(0, &crcnode, sizeof(crcnode)-4);
-+
-+ if (hdr_crc != je32_to_cpu(node->hdr_crc)) {
- noisy_printk(&noise, "jffs2_scan_eraseblock(): Node at 0x%08x {0x%04x, 0x%04x, 0x%08x) has invalid CRC 0x%08x (calculated 0x%08x)\n",
-- ofs, node.magic, node.nodetype, node.totlen, node.hdr_crc, hdr_crc);
-+ ofs, je16_to_cpu(node->magic),
-+ je16_to_cpu(node->nodetype),
-+ je32_to_cpu(node->totlen),
-+ je32_to_cpu(node->hdr_crc),
-+ hdr_crc);
- DIRTY_SPACE(4);
- ofs += 4;
- continue;
- }
-
-- if (ofs + node.totlen > jeb->offset + c->sector_size) {
-+ if (ofs + je32_to_cpu(node->totlen) >
-+ jeb->offset + c->sector_size) {
- /* Eep. Node goes over the end of the erase block. */
- printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n",
-- ofs, node.totlen);
-+ ofs, je32_to_cpu(node->totlen));
- printk(KERN_WARNING "Perhaps the file system was created with the wrong erase size?\n");
- DIRTY_SPACE(4);
- ofs += 4;
- continue;
- }
-
-- switch(node.nodetype | JFFS2_NODE_ACCURATE) {
-+ if (!(je16_to_cpu(node->nodetype) & JFFS2_NODE_ACCURATE)) {
-+ /* Wheee. This is an obsoleted node */
-+ D2(printk(KERN_DEBUG "Node at 0x%08x is obsolete. Skipping\n", ofs));
-+ DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
-+ ofs += PAD(je32_to_cpu(node->totlen));
-+ continue;
-+ }
-+
-+ switch(je16_to_cpu(node->nodetype)) {
- case JFFS2_NODETYPE_INODE:
-- err = jffs2_scan_inode_node(c, jeb, &ofs);
-+ if (buf_ofs + buf_len < ofs + sizeof(struct jffs2_raw_inode)) {
-+ buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
-+ D1(printk(KERN_DEBUG "Fewer than %zd bytes (inode node) left to end of buf. Reading 0x%x at 0x%08x\n",
-+ sizeof(struct jffs2_raw_inode), buf_len, ofs));
-+ err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
-+ if (err)
-+ return err;
-+ buf_ofs = ofs;
-+ node = (void *)buf;
-+ }
-+ err = jffs2_scan_inode_node(c, jeb, (void *)node, ofs);
- if (err) return err;
-+ ofs += PAD(je32_to_cpu(node->totlen));
- break;
-
- case JFFS2_NODETYPE_DIRENT:
-- err = jffs2_scan_dirent_node(c, jeb, &ofs);
-+ if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) {
-+ buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
-+ D1(printk(KERN_DEBUG "Fewer than %d bytes (dirent node) left to end of buf. Reading 0x%x at 0x%08x\n",
-+ je32_to_cpu(node->totlen), buf_len, ofs));
-+ err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
-+ if (err)
-+ return err;
-+ buf_ofs = ofs;
-+ node = (void *)buf;
-+ }
-+ err = jffs2_scan_dirent_node(c, jeb, (void *)node, ofs);
- if (err) return err;
-+ ofs += PAD(je32_to_cpu(node->totlen));
- break;
-
- case JFFS2_NODETYPE_CLEANMARKER:
-- if (node.totlen != sizeof(struct jffs2_unknown_node)) {
-+ D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs));
-+ if (je32_to_cpu(node->totlen) != c->cleanmarker_size) {
- printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n",
-- ofs, node.totlen, sizeof(struct jffs2_unknown_node));
-+ ofs, je32_to_cpu(node->totlen), c->cleanmarker_size);
- DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
-+ ofs += PAD(sizeof(struct jffs2_unknown_node));
- } else if (jeb->first_node) {
- printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)\n", ofs, jeb->offset);
- DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
- ofs += PAD(sizeof(struct jffs2_unknown_node));
-- continue;
- } else {
- struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref();
- if (!marker_ref) {
-@@ -300,98 +553,80 @@
- }
- marker_ref->next_in_ino = NULL;
- marker_ref->next_phys = NULL;
-- marker_ref->flash_offset = ofs;
-- marker_ref->totlen = sizeof(struct jffs2_unknown_node);
-+ marker_ref->flash_offset = ofs | REF_NORMAL;
-+ marker_ref->__totlen = c->cleanmarker_size;
- jeb->first_node = jeb->last_node = marker_ref;
-
-- USED_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
-+ USED_SPACE(PAD(c->cleanmarker_size));
-+ ofs += PAD(c->cleanmarker_size);
- }
-- ofs += PAD(sizeof(struct jffs2_unknown_node));
-+ break;
-+
-+ case JFFS2_NODETYPE_PADDING:
-+ DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
-+ ofs += PAD(je32_to_cpu(node->totlen));
- break;
-
- default:
-- switch (node.nodetype & JFFS2_COMPAT_MASK) {
-+ switch (je16_to_cpu(node->nodetype) & JFFS2_COMPAT_MASK) {
- case JFFS2_FEATURE_ROCOMPAT:
-- printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
-+ printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs);
- c->flags |= JFFS2_SB_FLAG_RO;
-- if (!(OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY))
-+ if (!(jffs2_is_readonly(c)))
- return -EROFS;
-- DIRTY_SPACE(PAD(node.totlen));
-- ofs += PAD(node.totlen);
-- continue;
-+ DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
-+ ofs += PAD(je32_to_cpu(node->totlen));
-+ break;
-
- case JFFS2_FEATURE_INCOMPAT:
-- printk(KERN_NOTICE "Incompatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
-+ printk(KERN_NOTICE "Incompatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs);
- return -EINVAL;
-
- case JFFS2_FEATURE_RWCOMPAT_DELETE:
-- printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
-- DIRTY_SPACE(PAD(node.totlen));
-- ofs += PAD(node.totlen);
-+ D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs));
-+ DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
-+ ofs += PAD(je32_to_cpu(node->totlen));
- break;
-
- case JFFS2_FEATURE_RWCOMPAT_COPY:
-- printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
-- USED_SPACE(PAD(node.totlen));
-- ofs += PAD(node.totlen);
-+ D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs));
-+ USED_SPACE(PAD(je32_to_cpu(node->totlen)));
-+ ofs += PAD(je32_to_cpu(node->totlen));
- break;
- }
- }
- }
-- D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, used 0x%08x\n", jeb->offset,
-- jeb->free_size, jeb->dirty_size, jeb->used_size));
-- return 0;
--}
-
--/* We're pointing at the first empty word on the flash. Scan and account for the whole dirty region */
--static int jffs2_scan_empty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *startofs, int *noise)
--{
-- __u32 *buf;
-- __u32 scanlen = (jeb->offset + c->sector_size) - *startofs;
-- __u32 curofs = *startofs;
--
-- buf = kmalloc(min((__u32)PAGE_SIZE, scanlen), GFP_KERNEL);
-- if (!buf) {
-- printk(KERN_WARNING "Scan buffer allocation failed\n");
-- return -ENOMEM;
-- }
-- while(scanlen) {
-- ssize_t retlen;
-- int ret, i;
--
-- ret = c->mtd->read(c->mtd, curofs, min((__u32)PAGE_SIZE, scanlen), &retlen, (char *)buf);
-- if(ret) {
-- D1(printk(KERN_WARNING "jffs2_scan_empty(): Read 0x%x bytes at 0x%08x returned %d\n", min((__u32)PAGE_SIZE, scanlen), curofs, ret));
-- kfree(buf);
-- return ret;
-- }
-- if (retlen < 4) {
-- D1(printk(KERN_WARNING "Eep. too few bytes read in scan_empty()\n"));
-- kfree(buf);
-- return -EIO;
-- }
-- for (i=0; i<(retlen / 4); i++) {
-- if (buf[i] != 0xffffffff) {
-- curofs += i*4;
--
-- noisy_printk(noise, "jffs2_scan_empty(): Empty block at 0x%08x ends at 0x%08x (with 0x%08x)! Marking dirty\n", *startofs, curofs, buf[i]);
-- DIRTY_SPACE(curofs - (*startofs));
-- *startofs = curofs;
-- kfree(buf);
-- return 0;
-- }
-- }
-- scanlen -= retlen&~3;
-- curofs += retlen&~3;
-- }
-
-- D1(printk(KERN_DEBUG "Empty flash detected from 0x%08x to 0x%08x\n", *startofs, curofs));
-- kfree(buf);
-- *startofs = curofs;
-- return 0;
-+ D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x\n", jeb->offset,
-+ jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size));
-+
-+ /* mark_node_obsolete can add to wasted !! */
-+ if (jeb->wasted_size) {
-+ jeb->dirty_size += jeb->wasted_size;
-+ c->dirty_size += jeb->wasted_size;
-+ c->wasted_size -= jeb->wasted_size;
-+ jeb->wasted_size = 0;
-+ }
-+
-+ if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size
-+ && (!jeb->first_node || jeb->first_node->next_in_ino) )
-+ return BLK_STATE_CLEANMARKER;
-+
-+ /* move blocks with max 4 byte dirty space to cleanlist */
-+ else if (!ISDIRTY(c->sector_size - (jeb->used_size + jeb->unchecked_size))) {
-+ c->dirty_size -= jeb->dirty_size;
-+ c->wasted_size += jeb->dirty_size;
-+ jeb->wasted_size += jeb->dirty_size;
-+ jeb->dirty_size = 0;
-+ return BLK_STATE_CLEAN;
-+ } else if (jeb->used_size || jeb->unchecked_size)
-+ return BLK_STATE_PARTDIRTY;
-+ else
-+ return BLK_STATE_ALLDIRTY;
- }
-
--static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, __u32 ino)
-+static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino)
- {
- struct jffs2_inode_cache *ic;
-
-@@ -399,137 +634,77 @@
- if (ic)
- return ic;
-
-+ if (ino > c->highest_ino)
-+ c->highest_ino = ino;
-+
- ic = jffs2_alloc_inode_cache();
- if (!ic) {
- printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of inode cache failed\n");
- return NULL;
- }
- memset(ic, 0, sizeof(*ic));
-- ic->scan = kmalloc(sizeof(struct jffs2_scan_info), GFP_KERNEL);
-- if (!ic->scan) {
-- printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of scan info for inode cache failed\n");
-- jffs2_free_inode_cache(ic);
-- return NULL;
-- }
-- memset(ic->scan, 0, sizeof(*ic->scan));
-+
- ic->ino = ino;
- ic->nodes = (void *)ic;
- jffs2_add_ino_cache(c, ic);
- if (ino == 1)
-- ic->nlink=1;
-+ ic->nlink = 1;
- return ic;
- }
-
--static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs)
-+static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-+ struct jffs2_raw_inode *ri, uint32_t ofs)
- {
- struct jffs2_raw_node_ref *raw;
-- struct jffs2_full_dnode *fn;
-- struct jffs2_tmp_dnode_info *tn, **tn_list;
- struct jffs2_inode_cache *ic;
-- struct jffs2_raw_inode ri;
-- __u32 crc;
-- __u16 oldnodetype;
-- int ret;
-- ssize_t retlen;
--
-- D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", *ofs));
--
-- ret = c->mtd->read(c->mtd, *ofs, sizeof(ri), &retlen, (char *)&ri);
-- if (ret) {
-- printk(KERN_NOTICE "jffs2_scan_inode_node(): Read error at 0x%08x: %d\n", *ofs, ret);
-- return ret;
-- }
-- if (retlen != sizeof(ri)) {
-- printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n",
-- retlen, *ofs, sizeof(ri));
-- return -EIO;
-- }
-+ uint32_t ino = je32_to_cpu(ri->ino);
-
-- /* We sort of assume that the node was accurate when it was
-- first written to the medium :) */
-- oldnodetype = ri.nodetype;
-- ri.nodetype |= JFFS2_NODE_ACCURATE;
-- crc = crc32(0, &ri, sizeof(ri)-8);
-- ri.nodetype = oldnodetype;
-+ D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs));
-
-- if(crc != ri.node_crc) {
-- printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-- *ofs, ri.node_crc, crc);
-- /* FIXME: Why do we believe totlen? */
-- DIRTY_SPACE(4);
-- *ofs += 4;
-- return 0;
-- }
-- /* There was a bug where we wrote hole nodes out with csize/dsize
-- swapped. Deal with it */
-- if (ri.compr == JFFS2_COMPR_ZERO && !ri.dsize && ri.csize) {
-- ri.dsize = ri.csize;
-- ri.csize = 0;
-- }
-+ /* We do very little here now. Just check the ino# to which we should attribute
-+ this node; we can do all the CRC checking etc. later. There's a tradeoff here --
-+ we used to scan the flash once only, reading everything we want from it into
-+ memory, then building all our in-core data structures and freeing the extra
-+ information. Now we allow the first part of the mount to complete a lot quicker,
-+ but we have to go _back_ to the flash in order to finish the CRC checking, etc.
-+ Which means that the _full_ amount of time to get to proper write mode with GC
-+ operational may actually be _longer_ than before. Sucks to be me. */
-
-- if (ri.csize) {
-- /* Check data CRC too */
-- unsigned char *dbuf;
-- __u32 crc;
--
-- dbuf = kmalloc(PAGE_CACHE_SIZE, GFP_KERNEL);
-- if (!dbuf) {
-- printk(KERN_NOTICE "jffs2_scan_inode_node(): allocation of temporary data buffer for CRC check failed\n");
-- return -ENOMEM;
-- }
-- ret = c->mtd->read(c->mtd, *ofs+sizeof(ri), ri.csize, &retlen, dbuf);
-- if (ret) {
-- printk(KERN_NOTICE "jffs2_scan_inode_node(): Read error at 0x%08x: %d\n", *ofs+sizeof(ri), ret);
-- kfree(dbuf);
-- return ret;
-- }
-- if (retlen != ri.csize) {
-- printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n",
-- retlen, *ofs+ sizeof(ri), ri.csize);
-- kfree(dbuf);
-- return -EIO;
-- }
-- crc = crc32(0, dbuf, ri.csize);
-- kfree(dbuf);
-- if (crc != ri.data_crc) {
-- printk(KERN_NOTICE "jffs2_scan_inode_node(): Data CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-- *ofs, ri.data_crc, crc);
-- DIRTY_SPACE(PAD(ri.totlen));
-- *ofs += PAD(ri.totlen);
-- return 0;
-- }
-- }
--
-- /* Wheee. It worked */
- raw = jffs2_alloc_raw_node_ref();
- if (!raw) {
- printk(KERN_NOTICE "jffs2_scan_inode_node(): allocation of node reference failed\n");
- return -ENOMEM;
- }
-- tn = jffs2_alloc_tmp_dnode_info();
-- if (!tn) {
-- jffs2_free_raw_node_ref(raw);
-- return -ENOMEM;
-- }
-- fn = jffs2_alloc_full_dnode();
-- if (!fn) {
-- jffs2_free_tmp_dnode_info(tn);
-+
-+ ic = jffs2_get_ino_cache(c, ino);
-+ if (!ic) {
-+ /* Inocache get failed. Either we read a bogus ino# or it's just genuinely the
-+ first node we found for this inode. Do a CRC check to protect against the former
-+ case */
-+ uint32_t crc = crc32(0, ri, sizeof(*ri)-8);
-+
-+ if (crc != je32_to_cpu(ri->node_crc)) {
-+ printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-+ ofs, je32_to_cpu(ri->node_crc), crc);
-+ /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */
-+ DIRTY_SPACE(PAD(je32_to_cpu(ri->totlen)));
- jffs2_free_raw_node_ref(raw);
-- return -ENOMEM;
-+ return 0;
- }
-- ic = jffs2_scan_make_ino_cache(c, ri.ino);
-+ ic = jffs2_scan_make_ino_cache(c, ino);
- if (!ic) {
-- jffs2_free_full_dnode(fn);
-- jffs2_free_tmp_dnode_info(tn);
- jffs2_free_raw_node_ref(raw);
- return -ENOMEM;
- }
-+ }
-
-- /* Build the data structures and file them for later */
-- raw->flash_offset = *ofs;
-- raw->totlen = PAD(ri.totlen);
-+ /* Wheee. It worked */
-+
-+ raw->flash_offset = ofs | REF_UNCHECKED;
-+ raw->__totlen = PAD(je32_to_cpu(ri->totlen));
- raw->next_phys = NULL;
- raw->next_in_ino = ic->nodes;
-+
- ic->nodes = raw;
- if (!jeb->first_node)
- jeb->first_node = raw;
-@@ -538,134 +713,56 @@
- jeb->last_node = raw;
-
- D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n",
-- ri.ino, ri.version, ri.offset, ri.offset+ri.dsize));
--
-- pseudo_random += ri.version;
--
-- for (tn_list = &ic->scan->tmpnodes; *tn_list; tn_list = &((*tn_list)->next)) {
-- if ((*tn_list)->version < ri.version)
-- continue;
-- if ((*tn_list)->version > ri.version)
-- break;
-- /* Wheee. We've found another instance of the same version number.
-- We should obsolete one of them.
-- */
-- D1(printk(KERN_DEBUG "Duplicate version %d found in ino #%u. Previous one is at 0x%08x\n", ri.version, ic->ino, (*tn_list)->fn->raw->flash_offset &~3));
-- if (!jeb->used_size) {
-- D1(printk(KERN_DEBUG "No valid nodes yet found in this eraseblock 0x%08x, so obsoleting the new instance at 0x%08x\n",
-- jeb->offset, raw->flash_offset & ~3));
-- ri.nodetype &= ~JFFS2_NODE_ACCURATE;
-- /* Perhaps we could also mark it as such on the medium. Maybe later */
-- }
-- break;
-- }
--
-- if (ri.nodetype & JFFS2_NODE_ACCURATE) {
-- memset(fn,0,sizeof(*fn));
--
-- fn->ofs = ri.offset;
-- fn->size = ri.dsize;
-- fn->frags = 0;
-- fn->raw = raw;
--
-- tn->next = NULL;
-- tn->fn = fn;
-- tn->version = ri.version;
-+ je32_to_cpu(ri->ino), je32_to_cpu(ri->version),
-+ je32_to_cpu(ri->offset),
-+ je32_to_cpu(ri->offset)+je32_to_cpu(ri->dsize)));
-
-- USED_SPACE(PAD(ri.totlen));
-- jffs2_add_tn_to_list(tn, &ic->scan->tmpnodes);
-- /* Make sure the one we just added is the _last_ in the list
-- with this version number, so the older ones get obsoleted */
-- while (tn->next && tn->next->version == tn->version) {
-+ pseudo_random += je32_to_cpu(ri->version);
-
-- D1(printk(KERN_DEBUG "Shifting new node at 0x%08x after other node at 0x%08x for version %d in list\n",
-- fn->raw->flash_offset&~3, tn->next->fn->raw->flash_offset &~3, ri.version));
--
-- if(tn->fn != fn)
-- BUG();
-- tn->fn = tn->next->fn;
-- tn->next->fn = fn;
-- tn = tn->next;
-- }
-- } else {
-- jffs2_free_full_dnode(fn);
-- jffs2_free_tmp_dnode_info(tn);
-- raw->flash_offset |= 1;
-- DIRTY_SPACE(PAD(ri.totlen));
-- }
-- *ofs += PAD(ri.totlen);
-+ UNCHECKED_SPACE(PAD(je32_to_cpu(ri->totlen)));
- return 0;
- }
-
--static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs)
-+static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-+ struct jffs2_raw_dirent *rd, uint32_t ofs)
- {
- struct jffs2_raw_node_ref *raw;
- struct jffs2_full_dirent *fd;
- struct jffs2_inode_cache *ic;
-- struct jffs2_raw_dirent rd;
-- __u16 oldnodetype;
-- int ret;
-- __u32 crc;
-- ssize_t retlen;
--
-- D1(printk(KERN_DEBUG "jffs2_scan_dirent_node(): Node at 0x%08x\n", *ofs));
-+ uint32_t crc;
-
-- ret = c->mtd->read(c->mtd, *ofs, sizeof(rd), &retlen, (char *)&rd);
-- if (ret) {
-- printk(KERN_NOTICE "jffs2_scan_dirent_node(): Read error at 0x%08x: %d\n", *ofs, ret);
-- return ret;
-- }
-- if (retlen != sizeof(rd)) {
-- printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n",
-- retlen, *ofs, sizeof(rd));
-- return -EIO;
-- }
-+ D1(printk(KERN_DEBUG "jffs2_scan_dirent_node(): Node at 0x%08x\n", ofs));
-
-- /* We sort of assume that the node was accurate when it was
-- first written to the medium :) */
-- oldnodetype = rd.nodetype;
-- rd.nodetype |= JFFS2_NODE_ACCURATE;
-- crc = crc32(0, &rd, sizeof(rd)-8);
-- rd.nodetype = oldnodetype;
-+ /* We don't get here unless the node is still valid, so we don't have to
-+ mask in the ACCURATE bit any more. */
-+ crc = crc32(0, rd, sizeof(*rd)-8);
-
-- if (crc != rd.node_crc) {
-+ if (crc != je32_to_cpu(rd->node_crc)) {
- printk(KERN_NOTICE "jffs2_scan_dirent_node(): Node CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-- *ofs, rd.node_crc, crc);
-- /* FIXME: Why do we believe totlen? */
-- DIRTY_SPACE(4);
-- *ofs += 4;
-+ ofs, je32_to_cpu(rd->node_crc), crc);
-+ /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */
-+ DIRTY_SPACE(PAD(je32_to_cpu(rd->totlen)));
- return 0;
- }
-
-- pseudo_random += rd.version;
-+ pseudo_random += je32_to_cpu(rd->version);
-
-- fd = jffs2_alloc_full_dirent(rd.nsize+1);
-+ fd = jffs2_alloc_full_dirent(rd->nsize+1);
- if (!fd) {
- return -ENOMEM;
--}
-- ret = c->mtd->read(c->mtd, *ofs + sizeof(rd), rd.nsize, &retlen, &fd->name[0]);
-- if (ret) {
-- jffs2_free_full_dirent(fd);
-- printk(KERN_NOTICE "jffs2_scan_dirent_node(): Read error at 0x%08x: %d\n",
-- *ofs + sizeof(rd), ret);
-- return ret;
-- }
-- if (retlen != rd.nsize) {
-- jffs2_free_full_dirent(fd);
-- printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n",
-- retlen, *ofs + sizeof(rd), rd.nsize);
-- return -EIO;
- }
-- crc = crc32(0, fd->name, rd.nsize);
-- if (crc != rd.name_crc) {
-+ memcpy(&fd->name, rd->name, rd->nsize);
-+ fd->name[rd->nsize] = 0;
-+
-+ crc = crc32(0, fd->name, rd->nsize);
-+ if (crc != je32_to_cpu(rd->name_crc)) {
- printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-- *ofs, rd.name_crc, crc);
-- fd->name[rd.nsize]=0;
-- D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, rd.ino));
-+ ofs, je32_to_cpu(rd->name_crc), crc);
-+ D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, je32_to_cpu(rd->ino)));
- jffs2_free_full_dirent(fd);
- /* FIXME: Why do we believe totlen? */
-- DIRTY_SPACE(PAD(rd.totlen));
-- *ofs += PAD(rd.totlen);
-+ /* We believe totlen because the CRC on the node _header_ was OK, just the name failed. */
-+ DIRTY_SPACE(PAD(je32_to_cpu(rd->totlen)));
- return 0;
- }
- raw = jffs2_alloc_raw_node_ref();
-@@ -674,15 +771,15 @@
- printk(KERN_NOTICE "jffs2_scan_dirent_node(): allocation of node reference failed\n");
- return -ENOMEM;
- }
-- ic = jffs2_scan_make_ino_cache(c, rd.pino);
-+ ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(rd->pino));
- if (!ic) {
- jffs2_free_full_dirent(fd);
- jffs2_free_raw_node_ref(raw);
- return -ENOMEM;
- }
-
-- raw->totlen = PAD(rd.totlen);
-- raw->flash_offset = *ofs;
-+ raw->__totlen = PAD(je32_to_cpu(rd->totlen));
-+ raw->flash_offset = ofs | REF_PRISTINE;
- raw->next_phys = NULL;
- raw->next_in_ino = ic->nodes;
- ic->nodes = raw;
-@@ -692,24 +789,15 @@
- jeb->last_node->next_phys = raw;
- jeb->last_node = raw;
-
-- if (rd.nodetype & JFFS2_NODE_ACCURATE) {
- fd->raw = raw;
- fd->next = NULL;
-- fd->version = rd.version;
-- fd->ino = rd.ino;
-- fd->name[rd.nsize]=0;
-- fd->nhash = full_name_hash(fd->name, rd.nsize);
-- fd->type = rd.type;
--
-- USED_SPACE(PAD(rd.totlen));
-- jffs2_add_fd_to_list(c, fd, &ic->scan->dents);
-- } else {
-- raw->flash_offset |= 1;
-- jffs2_free_full_dirent(fd);
-+ fd->version = je32_to_cpu(rd->version);
-+ fd->ino = je32_to_cpu(rd->ino);
-+ fd->nhash = full_name_hash(fd->name, rd->nsize);
-+ fd->type = rd->type;
-+ USED_SPACE(PAD(je32_to_cpu(rd->totlen)));
-+ jffs2_add_fd_to_list(c, fd, &ic->scan_dents);
-
-- DIRTY_SPACE(PAD(rd.totlen));
-- }
-- *ofs += PAD(rd.totlen);
- return 0;
- }
-
-@@ -731,26 +819,90 @@
- struct list_head *n = head->next;
-
- list_del(head);
-- while(count--)
-+ while(count--) {
- n = n->next;
-+ }
- list_add(head, n);
- }
-
--static void jffs2_rotate_lists(struct jffs2_sb_info *c)
-+void jffs2_rotate_lists(struct jffs2_sb_info *c)
- {
- uint32_t x;
-+ uint32_t rotateby;
-
- x = count_list(&c->clean_list);
-- if (x)
-- rotate_list((&c->clean_list), pseudo_random % x);
-+ if (x) {
-+ rotateby = pseudo_random % x;
-+ D1(printk(KERN_DEBUG "Rotating clean_list by %d\n", rotateby));
-+
-+ rotate_list((&c->clean_list), rotateby);
-+
-+ D1(printk(KERN_DEBUG "Erase block at front of clean_list is at %08x\n",
-+ list_entry(c->clean_list.next, struct jffs2_eraseblock, list)->offset));
-+ } else {
-+ D1(printk(KERN_DEBUG "Not rotating empty clean_list\n"));
-+ }
-+
-+ x = count_list(&c->very_dirty_list);
-+ if (x) {
-+ rotateby = pseudo_random % x;
-+ D1(printk(KERN_DEBUG "Rotating very_dirty_list by %d\n", rotateby));
-+
-+ rotate_list((&c->very_dirty_list), rotateby);
-+
-+ D1(printk(KERN_DEBUG "Erase block at front of very_dirty_list is at %08x\n",
-+ list_entry(c->very_dirty_list.next, struct jffs2_eraseblock, list)->offset));
-+ } else {
-+ D1(printk(KERN_DEBUG "Not rotating empty very_dirty_list\n"));
-+ }
-
- x = count_list(&c->dirty_list);
-- if (x)
-- rotate_list((&c->dirty_list), pseudo_random % x);
-+ if (x) {
-+ rotateby = pseudo_random % x;
-+ D1(printk(KERN_DEBUG "Rotating dirty_list by %d\n", rotateby));
-+
-+ rotate_list((&c->dirty_list), rotateby);
-+
-+ D1(printk(KERN_DEBUG "Erase block at front of dirty_list is at %08x\n",
-+ list_entry(c->dirty_list.next, struct jffs2_eraseblock, list)->offset));
-+ } else {
-+ D1(printk(KERN_DEBUG "Not rotating empty dirty_list\n"));
-+ }
-+
-+ x = count_list(&c->erasable_list);
-+ if (x) {
-+ rotateby = pseudo_random % x;
-+ D1(printk(KERN_DEBUG "Rotating erasable_list by %d\n", rotateby));
-
-- if (c->nr_erasing_blocks)
-- rotate_list((&c->erase_pending_list), pseudo_random % c->nr_erasing_blocks);
-+ rotate_list((&c->erasable_list), rotateby);
-
-- if (c->nr_free_blocks) /* Not that it should ever be zero */
-- rotate_list((&c->free_list), pseudo_random % c->nr_free_blocks);
-+ D1(printk(KERN_DEBUG "Erase block at front of erasable_list is at %08x\n",
-+ list_entry(c->erasable_list.next, struct jffs2_eraseblock, list)->offset));
-+ } else {
-+ D1(printk(KERN_DEBUG "Not rotating empty erasable_list\n"));
-+ }
-+
-+ if (c->nr_erasing_blocks) {
-+ rotateby = pseudo_random % c->nr_erasing_blocks;
-+ D1(printk(KERN_DEBUG "Rotating erase_pending_list by %d\n", rotateby));
-+
-+ rotate_list((&c->erase_pending_list), rotateby);
-+
-+ D1(printk(KERN_DEBUG "Erase block at front of erase_pending_list is at %08x\n",
-+ list_entry(c->erase_pending_list.next, struct jffs2_eraseblock, list)->offset));
-+ } else {
-+ D1(printk(KERN_DEBUG "Not rotating empty erase_pending_list\n"));
-+ }
-+
-+ if (c->nr_free_blocks) {
-+ rotateby = pseudo_random % c->nr_free_blocks;
-+ D1(printk(KERN_DEBUG "Rotating free_list by %d\n", rotateby));
-+
-+ rotate_list((&c->free_list), rotateby);
-+
-+ D1(printk(KERN_DEBUG "Erase block at front of free_list is at %08x\n",
-+ list_entry(c->free_list.next, struct jffs2_eraseblock, list)->offset));
-+ } else {
-+ D1(printk(KERN_DEBUG "Not rotating empty free_list\n"));
-+ }
- }
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/super-v24.c linux/fs/jffs2/super-v24.c
---- linux-mips-2.4.24-pre2/fs/jffs2/super-v24.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/jffs2/super-v24.c 2004-11-17 18:17:59.374263000 +0100
-@@ -0,0 +1,167 @@
-+/*
-+ * JFFS2 -- Journalling Flash File System, Version 2.
-+ *
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
-+ *
-+ * Created by David Woodhouse <dwmw2@redhat.com>
-+ *
-+ * For licensing information, see the file 'LICENCE' in this directory.
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/version.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/fs.h>
-+#include <linux/jffs2.h>
-+#include <linux/pagemap.h>
-+#include <linux/mtd/mtd.h>
-+#include "nodelist.h"
-+
-+#ifndef MTD_BLOCK_MAJOR
-+#define MTD_BLOCK_MAJOR 31
-+#endif
-+
-+static void jffs2_put_super (struct super_block *);
-+
-+static struct super_operations jffs2_super_operations =
-+{
-+ .read_inode = jffs2_read_inode,
-+ .put_super = jffs2_put_super,
-+ .write_super = jffs2_write_super,
-+ .statfs = jffs2_statfs,
-+ .remount_fs = jffs2_remount_fs,
-+ .clear_inode = jffs2_clear_inode,
-+ .dirty_inode = jffs2_dirty_inode,
-+};
-+
-+
-+static struct super_block *jffs2_read_super(struct super_block *sb, void *data, int silent)
-+{
-+ struct jffs2_sb_info *c;
-+ int ret;
-+
-+ D1(printk(KERN_DEBUG "jffs2: read_super for device %s\n", kdevname(sb->s_dev)));
-+
-+ if (major(sb->s_dev) != MTD_BLOCK_MAJOR) {
-+ if (!silent)
-+ printk(KERN_DEBUG "jffs2: attempt to mount non-MTD device %s\n", kdevname(sb->s_dev));
-+ return NULL;
-+ }
-+
-+ c = JFFS2_SB_INFO(sb);
-+ memset(c, 0, sizeof(*c));
-+
-+ sb->s_op = &jffs2_super_operations;
-+
-+ c->mtd = get_mtd_device(NULL, minor(sb->s_dev));
-+ if (!c->mtd) {
-+ D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", minor(sb->s_dev)));
-+ return NULL;
-+ }
-+
-+ ret = jffs2_do_fill_super(sb, data, silent);
-+ if (ret) {
-+ put_mtd_device(c->mtd);
-+ return NULL;
-+ }
-+
-+ return sb;
-+}
-+
-+static void jffs2_put_super (struct super_block *sb)
-+{
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-+
-+ D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n"));
-+
-+
-+ if (!(sb->s_flags & MS_RDONLY))
-+ jffs2_stop_garbage_collect_thread(c);
-+ down(&c->alloc_sem);
-+ jffs2_flush_wbuf_pad(c);
-+ up(&c->alloc_sem);
-+ jffs2_free_ino_caches(c);
-+ jffs2_free_raw_node_refs(c);
-+ kfree(c->blocks);
-+ jffs2_nand_flash_cleanup(c);
-+ kfree(c->inocache_list);
-+ if (c->mtd->sync)
-+ c->mtd->sync(c->mtd);
-+ put_mtd_device(c->mtd);
-+
-+ D1(printk(KERN_DEBUG "jffs2_put_super returning\n"));
-+}
-+
-+static DECLARE_FSTYPE_DEV(jffs2_fs_type, "jffs2", jffs2_read_super);
-+
-+static int __init init_jffs2_fs(void)
-+{
-+ int ret;
-+
-+ printk(KERN_INFO "JFFS2 version 2.2."
-+#ifdef CONFIG_FS_JFFS2_NAND
-+ " (NAND)"
-+#endif
-+ " (C) 2001-2003 Red Hat, Inc.\n");
-+
-+#ifdef JFFS2_OUT_OF_KERNEL
-+ /* sanity checks. Could we do these at compile time? */
-+ if (sizeof(struct jffs2_sb_info) > sizeof (((struct super_block *)NULL)->u)) {
-+ printk(KERN_ERR "JFFS2 error: struct jffs2_sb_info (%d bytes) doesn't fit in the super_block union (%d bytes)\n",
-+ sizeof(struct jffs2_sb_info), sizeof (((struct super_block *)NULL)->u));
-+ return -EIO;
-+ }
-+
-+ if (sizeof(struct jffs2_inode_info) > sizeof (((struct inode *)NULL)->u)) {
-+ printk(KERN_ERR "JFFS2 error: struct jffs2_inode_info (%d bytes) doesn't fit in the inode union (%d bytes)\n",
-+ sizeof(struct jffs2_inode_info), sizeof (((struct inode *)NULL)->u));
-+ return -EIO;
-+ }
-+#endif
-+ ret = jffs2_zlib_init();
-+ if (ret) {
-+ printk(KERN_ERR "JFFS2 error: Failed to initialise zlib workspaces\n");
-+ goto out;
-+ }
-+ ret = jffs2_create_slab_caches();
-+ if (ret) {
-+ printk(KERN_ERR "JFFS2 error: Failed to initialise slab caches\n");
-+ goto out_zlib;
-+ }
-+ ret = register_filesystem(&jffs2_fs_type);
-+ if (ret) {
-+ printk(KERN_ERR "JFFS2 error: Failed to register filesystem\n");
-+ goto out_slab;
-+ }
-+ return 0;
-+
-+ out_slab:
-+ jffs2_destroy_slab_caches();
-+ out_zlib:
-+ jffs2_zlib_exit();
-+ out:
-+
-+ return ret;
-+}
-+
-+static void __exit exit_jffs2_fs(void)
-+{
-+ jffs2_destroy_slab_caches();
-+ jffs2_zlib_exit();
-+ unregister_filesystem(&jffs2_fs_type);
-+}
-+
-+module_init(init_jffs2_fs);
-+module_exit(exit_jffs2_fs);
-+
-+MODULE_DESCRIPTION("The Journalling Flash File System, v2");
-+MODULE_AUTHOR("Red Hat, Inc.");
-+MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for
-+ // the sake of this tag. It's Free Software.
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/super.c linux/fs/jffs2/super.c
---- linux-mips-2.4.24-pre2/fs/jffs2/super.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/super.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,291 +1,257 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/config.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
--#include <linux/version.h>
- #include <linux/slab.h>
- #include <linux/init.h>
- #include <linux/list.h>
- #include <linux/fs.h>
-+#include <linux/mount.h>
- #include <linux/jffs2.h>
- #include <linux/pagemap.h>
- #include <linux/mtd/mtd.h>
--#include <linux/interrupt.h>
-+#include <linux/ctype.h>
-+#include <linux/namei.h>
- #include "nodelist.h"
-
--#ifndef MTD_BLOCK_MAJOR
--#define MTD_BLOCK_MAJOR 31
--#endif
-+static void jffs2_put_super(struct super_block *);
-+
-+static kmem_cache_t *jffs2_inode_cachep;
-+
-+static struct inode *jffs2_alloc_inode(struct super_block *sb)
-+{
-+ struct jffs2_inode_info *ei;
-+ ei = (struct jffs2_inode_info *)kmem_cache_alloc(jffs2_inode_cachep, SLAB_KERNEL);
-+ if (!ei)
-+ return NULL;
-+ return &ei->vfs_inode;
-+}
-+
-+static void jffs2_destroy_inode(struct inode *inode)
-+{
-+ kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode));
-+}
-+
-+static void jffs2_i_init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
-+{
-+ struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo;
-
--extern void jffs2_read_inode (struct inode *);
--void jffs2_put_super (struct super_block *);
--void jffs2_write_super (struct super_block *);
--static int jffs2_statfs (struct super_block *, struct statfs *);
--int jffs2_remount_fs (struct super_block *, int *, char *);
--extern void jffs2_clear_inode (struct inode *);
-+ if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
-+ SLAB_CTOR_CONSTRUCTOR) {
-+ init_MUTEX_LOCKED(&ei->sem);
-+ inode_init_once(&ei->vfs_inode);
-+ }
-+}
-
- static struct super_operations jffs2_super_operations =
- {
-- read_inode: jffs2_read_inode,
--// delete_inode: jffs2_delete_inode,
-- put_super: jffs2_put_super,
-- write_super: jffs2_write_super,
-- statfs: jffs2_statfs,
-- remount_fs: jffs2_remount_fs,
-- clear_inode: jffs2_clear_inode
-+ .alloc_inode = jffs2_alloc_inode,
-+ .destroy_inode =jffs2_destroy_inode,
-+ .read_inode = jffs2_read_inode,
-+ .put_super = jffs2_put_super,
-+ .write_super = jffs2_write_super,
-+ .statfs = jffs2_statfs,
-+ .remount_fs = jffs2_remount_fs,
-+ .clear_inode = jffs2_clear_inode,
-+ .dirty_inode = jffs2_dirty_inode,
- };
-
--static int jffs2_statfs(struct super_block *sb, struct statfs *buf)
-+static int jffs2_sb_compare(struct super_block *sb, void *data)
- {
-+ struct jffs2_sb_info *p = data;
- struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-- unsigned long avail;
-
-- buf->f_type = JFFS2_SUPER_MAGIC;
-- buf->f_bsize = 1 << PAGE_SHIFT;
-- buf->f_blocks = c->flash_size >> PAGE_SHIFT;
-- buf->f_files = 0;
-- buf->f_ffree = 0;
-- buf->f_namelen = JFFS2_MAX_NAME_LEN;
--
-- spin_lock_bh(&c->erase_completion_lock);
--
-- avail = c->dirty_size + c->free_size;
-- if (avail > c->sector_size * JFFS2_RESERVED_BLOCKS_WRITE)
-- avail -= c->sector_size * JFFS2_RESERVED_BLOCKS_WRITE;
-- else
-- avail = 0;
--
-- buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT;
--
--#if CONFIG_JFFS2_FS_DEBUG > 0
-- printk(KERN_DEBUG "STATFS:\n");
-- printk(KERN_DEBUG "flash_size: %08x\n", c->flash_size);
-- printk(KERN_DEBUG "used_size: %08x\n", c->used_size);
-- printk(KERN_DEBUG "dirty_size: %08x\n", c->dirty_size);
-- printk(KERN_DEBUG "free_size: %08x\n", c->free_size);
-- printk(KERN_DEBUG "erasing_size: %08x\n", c->erasing_size);
-- printk(KERN_DEBUG "bad_size: %08x\n", c->bad_size);
-- printk(KERN_DEBUG "sector_size: %08x\n", c->sector_size);
--
-- if (c->nextblock) {
-- printk(KERN_DEBUG "nextblock: 0x%08x\n", c->nextblock->offset);
-- } else {
-- printk(KERN_DEBUG "nextblock: NULL\n");
-- }
-- if (c->gcblock) {
-- printk(KERN_DEBUG "gcblock: 0x%08x\n", c->gcblock->offset);
-+ /* The superblocks are considered to be equivalent if the underlying MTD
-+ device is the same one */
-+ if (c->mtd == p->mtd) {
-+ D1(printk(KERN_DEBUG "jffs2_sb_compare: match on device %d (\"%s\")\n", p->mtd->index, p->mtd->name));
-+ return 1;
- } else {
-- printk(KERN_DEBUG "gcblock: NULL\n");
-+ D1(printk(KERN_DEBUG "jffs2_sb_compare: No match, device %d (\"%s\"), device %d (\"%s\")\n",
-+ c->mtd->index, c->mtd->name, p->mtd->index, p->mtd->name));
-+ return 0;
- }
-- if (list_empty(&c->clean_list)) {
-- printk(KERN_DEBUG "clean_list: empty\n");
-- } else {
-- struct list_head *this;
-+}
-
-- list_for_each(this, &c->clean_list) {
-- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-- printk(KERN_DEBUG "clean_list: %08x\n", jeb->offset);
-- }
-- }
-- if (list_empty(&c->dirty_list)) {
-- printk(KERN_DEBUG "dirty_list: empty\n");
-- } else {
-- struct list_head *this;
-+static int jffs2_sb_set(struct super_block *sb, void *data)
-+{
-+ struct jffs2_sb_info *p = data;
-
-- list_for_each(this, &c->dirty_list) {
-- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-- printk(KERN_DEBUG "dirty_list: %08x\n", jeb->offset);
-- }
-- }
-- if (list_empty(&c->erasing_list)) {
-- printk(KERN_DEBUG "erasing_list: empty\n");
-- } else {
-- struct list_head *this;
-+ /* For persistence of NFS exports etc. we use the same s_dev
-+ each time we mount the device, don't just use an anonymous
-+ device */
-+ sb->s_fs_info = p;
-+ p->os_priv = sb;
-+ sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, p->mtd->index);
-
-- list_for_each(this, &c->erasing_list) {
-- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-- printk(KERN_DEBUG "erasing_list: %08x\n", jeb->offset);
-- }
-- }
-- if (list_empty(&c->erase_pending_list)) {
-- printk(KERN_DEBUG "erase_pending_list: empty\n");
-- } else {
-- struct list_head *this;
-+ return 0;
-+}
-
-- list_for_each(this, &c->erase_pending_list) {
-- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-- printk(KERN_DEBUG "erase_pending_list: %08x\n", jeb->offset);
-- }
-- }
-- if (list_empty(&c->free_list)) {
-- printk(KERN_DEBUG "free_list: empty\n");
-- } else {
-- struct list_head *this;
-+static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type,
-+ int flags, const char *dev_name,
-+ void *data, struct mtd_info *mtd)
-+{
-+ struct super_block *sb;
-+ struct jffs2_sb_info *c;
-+ int ret;
-
-- list_for_each(this, &c->free_list) {
-- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-- printk(KERN_DEBUG "free_list: %08x\n", jeb->offset);
-- }
-- }
-- if (list_empty(&c->bad_list)) {
-- printk(KERN_DEBUG "bad_list: empty\n");
-- } else {
-- struct list_head *this;
-+ c = kmalloc(sizeof(*c), GFP_KERNEL);
-+ if (!c)
-+ return ERR_PTR(-ENOMEM);
-+ memset(c, 0, sizeof(*c));
-+ c->mtd = mtd;
-
-- list_for_each(this, &c->bad_list) {
-- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-- printk(KERN_DEBUG "bad_list: %08x\n", jeb->offset);
-- }
-- }
-- if (list_empty(&c->bad_used_list)) {
-- printk(KERN_DEBUG "bad_used_list: empty\n");
-- } else {
-- struct list_head *this;
-+ sb = sget(fs_type, jffs2_sb_compare, jffs2_sb_set, c);
-+
-+ if (IS_ERR(sb))
-+ goto out_put;
-
-- list_for_each(this, &c->bad_used_list) {
-- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-- printk(KERN_DEBUG "bad_used_list: %08x\n", jeb->offset);
-+ if (sb->s_root) {
-+ /* New mountpoint for JFFS2 which is already mounted */
-+ D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): Device %d (\"%s\") is already mounted\n",
-+ mtd->index, mtd->name));
-+ goto out_put;
- }
-+
-+ D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): New superblock for device %d (\"%s\")\n",
-+ mtd->index, mtd->name));
-+
-+ sb->s_op = &jffs2_super_operations;
-+
-+ ret = jffs2_do_fill_super(sb, data, (flags&MS_VERBOSE)?1:0);
-+
-+ if (ret) {
-+ /* Failure case... */
-+ up_write(&sb->s_umount);
-+ deactivate_super(sb);
-+ return ERR_PTR(ret);
- }
--#endif /* CONFIG_JFFS2_FS_DEBUG */
-
-- spin_unlock_bh(&c->erase_completion_lock);
-+ sb->s_flags |= MS_ACTIVE;
-+ return sb;
-
-+ out_put:
-+ kfree(c);
-+ put_mtd_device(mtd);
-
-- return 0;
-+ return sb;
- }
-
--static struct super_block *jffs2_read_super(struct super_block *sb, void *data, int silent)
-+static struct super_block *jffs2_get_sb_mtdnr(struct file_system_type *fs_type,
-+ int flags, const char *dev_name,
-+ void *data, int mtdnr)
- {
-- struct jffs2_sb_info *c;
-- struct inode *root_i;
-- int i;
--
-- D1(printk(KERN_DEBUG "jffs2: read_super for device %s\n", kdevname(sb->s_dev)));
-+ struct mtd_info *mtd;
-
-- if (MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR) {
-- if (!silent)
-- printk(KERN_DEBUG "jffs2: attempt to mount non-MTD device %s\n", kdevname(sb->s_dev));
-- return NULL;
-+ mtd = get_mtd_device(NULL, mtdnr);
-+ if (!mtd) {
-+ D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", mtdnr));
-+ return ERR_PTR(-EINVAL);
- }
-
-- c = JFFS2_SB_INFO(sb);
-- memset(c, 0, sizeof(*c));
-+ return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd);
-+}
-
-- c->mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
-- if (!c->mtd) {
-- D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", MINOR(sb->s_dev)));
-- return NULL;
-+static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
-+ int flags, const char *dev_name,
-+ void *data)
-+{
-+ int err;
-+ struct nameidata nd;
-+ int mtdnr;
-+
-+ if (!dev_name)
-+ return ERR_PTR(-EINVAL);
-+
-+ D1(printk(KERN_DEBUG "jffs2_get_sb(): dev_name \"%s\"\n", dev_name));
-+
-+ /* The preferred way of mounting in future; especially when
-+ CONFIG_BLK_DEV is implemented - we specify the underlying
-+ MTD device by number or by name, so that we don't require
-+ block device support to be present in the kernel. */
-+
-+ /* FIXME: How to do the root fs this way? */
-+
-+ if (dev_name[0] == 'm' && dev_name[1] == 't' && dev_name[2] == 'd') {
-+ /* Probably mounting without the blkdev crap */
-+ if (dev_name[3] == ':') {
-+ struct mtd_info *mtd;
-+
-+ /* Mount by MTD device name */
-+ D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd:%%s, name \"%s\"\n", dev_name+4));
-+ for (mtdnr = 0; mtdnr < MAX_MTD_DEVICES; mtdnr++) {
-+ mtd = get_mtd_device(NULL, mtdnr);
-+ if (mtd) {
-+ if (!strcmp(mtd->name, dev_name+4))
-+ return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd);
-+ put_mtd_device(mtd);
- }
-- c->sector_size = c->mtd->erasesize;
-- c->free_size = c->flash_size = c->mtd->size;
-- c->nr_blocks = c->mtd->size / c->mtd->erasesize;
-- c->blocks = kmalloc(sizeof(struct jffs2_eraseblock) * c->nr_blocks, GFP_KERNEL);
-- if (!c->blocks)
-- goto out_mtd;
-- for (i=0; i<c->nr_blocks; i++) {
-- INIT_LIST_HEAD(&c->blocks[i].list);
-- c->blocks[i].offset = i * c->sector_size;
-- c->blocks[i].free_size = c->sector_size;
-- c->blocks[i].dirty_size = 0;
-- c->blocks[i].used_size = 0;
-- c->blocks[i].first_node = NULL;
-- c->blocks[i].last_node = NULL;
-- }
--
-- spin_lock_init(&c->nodelist_lock);
-- init_MUTEX(&c->alloc_sem);
-- init_waitqueue_head(&c->erase_wait);
-- spin_lock_init(&c->erase_completion_lock);
-- spin_lock_init(&c->inocache_lock);
--
-- INIT_LIST_HEAD(&c->clean_list);
-- INIT_LIST_HEAD(&c->dirty_list);
-- INIT_LIST_HEAD(&c->erasing_list);
-- INIT_LIST_HEAD(&c->erase_pending_list);
-- INIT_LIST_HEAD(&c->erase_complete_list);
-- INIT_LIST_HEAD(&c->free_list);
-- INIT_LIST_HEAD(&c->bad_list);
-- INIT_LIST_HEAD(&c->bad_used_list);
-- c->highest_ino = 1;
--
-- if (jffs2_build_filesystem(c)) {
-- D1(printk(KERN_DEBUG "build_fs failed\n"));
-- goto out_nodes;
- }
-+ printk(KERN_NOTICE "jffs2_get_sb(): MTD device with name \"%s\" not found.\n", dev_name+4);
-+ } else if (isdigit(dev_name[3])) {
-+ /* Mount by MTD device number name */
-+ char *endptr;
-
-- sb->s_op = &jffs2_super_operations;
-+ mtdnr = simple_strtoul(dev_name+3, &endptr, 0);
-+ if (!*endptr) {
-+ /* It was a valid number */
-+ D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd%%d, mtdnr %d\n", mtdnr));
-+ return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr);
-+ }
-+ }
-+ }
-
-- D1(printk(KERN_DEBUG "jffs2_read_super(): Getting root inode\n"));
-- root_i = iget(sb, 1);
-- if (is_bad_inode(root_i)) {
-- D1(printk(KERN_WARNING "get root inode failed\n"));
-- goto out_nodes;
-+ /* Try the old way - the hack where we allowed users to mount
-+ /dev/mtdblock$(n) but didn't actually _use_ the blkdev */
-+
-+ err = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
-+
-+ D1(printk(KERN_DEBUG "jffs2_get_sb(): path_lookup() returned %d, inode %p\n",
-+ err, nd.dentry->d_inode));
-+
-+ if (err)
-+ return ERR_PTR(err);
-+
-+ err = -EINVAL;
-+
-+ if (!S_ISBLK(nd.dentry->d_inode->i_mode))
-+ goto out;
-+
-+ if (nd.mnt->mnt_flags & MNT_NODEV) {
-+ err = -EACCES;
-+ goto out;
- }
-
-- D1(printk(KERN_DEBUG "jffs2_read_super(): d_alloc_root()\n"));
-- sb->s_root = d_alloc_root(root_i);
-- if (!sb->s_root)
-- goto out_root_i;
-+ if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR) {
-+ if (!(flags & MS_VERBOSE)) /* Yes I mean this. Strangely */
-+ printk(KERN_NOTICE "Attempt to mount non-MTD device \"%s\" as JFFS2\n",
-+ dev_name);
-+ goto out;
-+ }
-
--#if LINUX_VERSION_CODE >= 0x20403
-- sb->s_maxbytes = 0xFFFFFFFF;
--#endif
-- sb->s_blocksize = PAGE_CACHE_SIZE;
-- sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-- sb->s_magic = JFFS2_SUPER_MAGIC;
-- if (!(sb->s_flags & MS_RDONLY))
-- jffs2_start_garbage_collect_thread(c);
-- return sb;
-+ mtdnr = iminor(nd.dentry->d_inode);
-+ path_release(&nd);
-
-- out_root_i:
-- iput(root_i);
-- out_nodes:
-- jffs2_free_ino_caches(c);
-- jffs2_free_raw_node_refs(c);
-- kfree(c->blocks);
-- out_mtd:
-- put_mtd_device(c->mtd);
-- return NULL;
-+ return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr);
-+
-+out:
-+ path_release(&nd);
-+ return ERR_PTR(err);
- }
-
--void jffs2_put_super (struct super_block *sb)
-+static void jffs2_put_super (struct super_block *sb)
- {
- struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-
-@@ -293,74 +259,53 @@
-
- if (!(sb->s_flags & MS_RDONLY))
- jffs2_stop_garbage_collect_thread(c);
-+ down(&c->alloc_sem);
-+ jffs2_flush_wbuf_pad(c);
-+ up(&c->alloc_sem);
- jffs2_free_ino_caches(c);
- jffs2_free_raw_node_refs(c);
- kfree(c->blocks);
-+ jffs2_nand_flash_cleanup(c);
-+ kfree(c->inocache_list);
- if (c->mtd->sync)
- c->mtd->sync(c->mtd);
-- put_mtd_device(c->mtd);
-
- D1(printk(KERN_DEBUG "jffs2_put_super returning\n"));
- }
-
--int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
-+static void jffs2_kill_sb(struct super_block *sb)
- {
- struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
--
-- if (c->flags & JFFS2_SB_FLAG_RO && !(sb->s_flags & MS_RDONLY))
-- return -EROFS;
--
-- /* We stop if it was running, then restart if it needs to.
-- This also catches the case where it was stopped and this
-- is just a remount to restart it */
-- if (!(sb->s_flags & MS_RDONLY))
-- jffs2_stop_garbage_collect_thread(c);
--
-- if (!(*flags & MS_RDONLY))
-- jffs2_start_garbage_collect_thread(c);
--
-- sb->s_flags = (sb->s_flags & ~MS_RDONLY)|(*flags & MS_RDONLY);
--
-- return 0;
--}
--
--void jffs2_write_super (struct super_block *sb)
--{
-- struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-- sb->s_dirt = 0;
--
-- if (sb->s_flags & MS_RDONLY)
-- return;
--
-- jffs2_garbage_collect_trigger(c);
-- jffs2_erase_pending_blocks(c);
-- jffs2_mark_erased_blocks(c);
-+ generic_shutdown_super(sb);
-+ put_mtd_device(c->mtd);
-+ kfree(c);
- }
-
--
--static DECLARE_FSTYPE_DEV(jffs2_fs_type, "jffs2", jffs2_read_super);
-+static struct file_system_type jffs2_fs_type = {
-+ .owner = THIS_MODULE,
-+ .name = "jffs2",
-+ .get_sb = jffs2_get_sb,
-+ .kill_sb = jffs2_kill_sb,
-+};
-
- static int __init init_jffs2_fs(void)
- {
- int ret;
-
-- printk(KERN_NOTICE "JFFS2 version 2.1. (C) 2001 Red Hat, Inc., designed by Axis Communications AB.\n");
--
--#ifdef JFFS2_OUT_OF_KERNEL
-- /* sanity checks. Could we do these at compile time? */
-- if (sizeof(struct jffs2_sb_info) > sizeof (((struct super_block *)NULL)->u)) {
-- printk(KERN_ERR "JFFS2 error: struct jffs2_sb_info (%d bytes) doesn't fit in the super_block union (%d bytes)\n",
-- sizeof(struct jffs2_sb_info), sizeof (((struct super_block *)NULL)->u));
-- return -EIO;
-- }
--
-- if (sizeof(struct jffs2_inode_info) > sizeof (((struct inode *)NULL)->u)) {
-- printk(KERN_ERR "JFFS2 error: struct jffs2_inode_info (%d bytes) doesn't fit in the inode union (%d bytes)\n",
-- sizeof(struct jffs2_inode_info), sizeof (((struct inode *)NULL)->u));
-- return -EIO;
-- }
-+ printk(KERN_INFO "JFFS2 version 2.2."
-+#ifdef CONFIG_FS_JFFS2_NAND
-+ " (NAND)"
- #endif
-+ " (C) 2001-2003 Red Hat, Inc.\n");
-
-+ jffs2_inode_cachep = kmem_cache_create("jffs2_i",
-+ sizeof(struct jffs2_inode_info),
-+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
-+ jffs2_i_init_once, NULL);
-+ if (!jffs2_inode_cachep) {
-+ printk(KERN_ERR "JFFS2 error: Failed to initialise inode cache\n");
-+ return -ENOMEM;
-+ }
- ret = jffs2_zlib_init();
- if (ret) {
- printk(KERN_ERR "JFFS2 error: Failed to initialise zlib workspaces\n");
-@@ -388,9 +333,10 @@
-
- static void __exit exit_jffs2_fs(void)
- {
-+ unregister_filesystem(&jffs2_fs_type);
- jffs2_destroy_slab_caches();
- jffs2_zlib_exit();
-- unregister_filesystem(&jffs2_fs_type);
-+ kmem_cache_destroy(jffs2_inode_cachep);
- }
-
- module_init(init_jffs2_fs);
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/symlink.c linux/fs/jffs2/symlink.c
---- linux-mips-2.4.24-pre2/fs/jffs2/symlink.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/symlink.c 2004-11-17 18:17:59.000000000 +0100
-@@ -3,35 +3,11 @@
- *
- * Copyright (C) 2001, 2002 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
-@@ -39,7 +15,6 @@
- #include <linux/kernel.h>
- #include <linux/slab.h>
- #include <linux/fs.h>
--#include <linux/jffs2.h>
- #include "nodelist.h"
-
- int jffs2_readlink(struct dentry *dentry, char *buffer, int buflen);
-@@ -47,45 +22,17 @@
-
- struct inode_operations jffs2_symlink_inode_operations =
- {
-- readlink: jffs2_readlink,
-- follow_link: jffs2_follow_link,
-- setattr: jffs2_setattr
-+ .readlink = jffs2_readlink,
-+ .follow_link = jffs2_follow_link,
-+ .setattr = jffs2_setattr
- };
-
--static char *jffs2_getlink(struct dentry *dentry)
--{
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode);
-- char *buf;
-- int ret;
--
-- down(&f->sem);
-- if (!f->metadata) {
-- up(&f->sem);
-- printk(KERN_NOTICE "No metadata for symlink inode #%lu\n", dentry->d_inode->i_ino);
-- return ERR_PTR(-EINVAL);
-- }
-- buf = kmalloc(f->metadata->size+1, GFP_USER);
-- if (!buf) {
-- up(&f->sem);
-- return ERR_PTR(-ENOMEM);
-- }
-- buf[f->metadata->size]=0;
--
-- ret = jffs2_read_dnode(JFFS2_SB_INFO(dentry->d_inode->i_sb), f->metadata, buf, 0, f->metadata->size);
-- up(&f->sem);
-- if (ret) {
-- kfree(buf);
-- return ERR_PTR(ret);
-- }
-- return buf;
--
--}
- int jffs2_readlink(struct dentry *dentry, char *buffer, int buflen)
- {
- unsigned char *kbuf;
- int ret;
-
-- kbuf = jffs2_getlink(dentry);
-+ kbuf = jffs2_getlink(JFFS2_SB_INFO(dentry->d_inode->i_sb), JFFS2_INODE_INFO(dentry->d_inode));
- if (IS_ERR(kbuf))
- return PTR_ERR(kbuf);
-
-@@ -99,7 +46,7 @@
- unsigned char *buf;
- int ret;
-
-- buf = jffs2_getlink(dentry);
-+ buf = jffs2_getlink(JFFS2_SB_INFO(dentry->d_inode->i_sb), JFFS2_INODE_INFO(dentry->d_inode));
-
- if (IS_ERR(buf))
- return PTR_ERR(buf);
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/wbuf.c linux/fs/jffs2/wbuf.c
---- linux-mips-2.4.24-pre2/fs/jffs2/wbuf.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/jffs2/wbuf.c 2004-11-17 18:17:59.409257680 +0100
-@@ -0,0 +1,1156 @@
-+/*
-+ * JFFS2 -- Journalling Flash File System, Version 2.
-+ *
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
-+ *
-+ * Created by David Woodhouse <dwmw2@redhat.com>
-+ *
-+ * For licensing information, see the file 'LICENCE' in this directory.
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/crc32.h>
-+#include <linux/mtd/nand.h>
-+#include "nodelist.h"
-+
-+/* For testing write failures */
-+#undef BREAKME
-+#undef BREAKMEHEADER
-+
-+#ifdef BREAKME
-+static unsigned char *brokenbuf;
-+#endif
-+
-+/* max. erase failures before we mark a block bad */
-+#define MAX_ERASE_FAILURES 5
-+
-+/* two seconds timeout for timed wbuf-flushing */
-+#define WBUF_FLUSH_TIMEOUT 2 * HZ
-+
-+struct jffs2_inodirty {
-+ uint32_t ino;
-+ struct jffs2_inodirty *next;
-+};
-+
-+static struct jffs2_inodirty inodirty_nomem;
-+
-+static int jffs2_wbuf_pending_for_ino(struct jffs2_sb_info *c, uint32_t ino)
-+{
-+ struct jffs2_inodirty *this = c->wbuf_inodes;
-+
-+ /* If a malloc failed, consider _everything_ dirty */
-+ if (this == &inodirty_nomem)
-+ return 1;
-+
-+ /* If ino == 0, _any_ non-GC writes mean 'yes' */
-+ if (this && !ino)
-+ return 1;
-+
-+ /* Look to see if the inode in question is pending in the wbuf */
-+ while (this) {
-+ if (this->ino == ino)
-+ return 1;
-+ this = this->next;
-+ }
-+ return 0;
-+}
-+
-+static void jffs2_clear_wbuf_ino_list(struct jffs2_sb_info *c)
-+{
-+ struct jffs2_inodirty *this;
-+
-+ this = c->wbuf_inodes;
-+
-+ if (this != &inodirty_nomem) {
-+ while (this) {
-+ struct jffs2_inodirty *next = this->next;
-+ kfree(this);
-+ this = next;
-+ }
-+ }
-+ c->wbuf_inodes = NULL;
-+}
-+
-+static void jffs2_wbuf_dirties_inode(struct jffs2_sb_info *c, uint32_t ino)
-+{
-+ struct jffs2_inodirty *new;
-+
-+ /* Mark the superblock dirty so that kupdated will flush... */
-+ OFNI_BS_2SFFJ(c)->s_dirt = 1;
-+
-+ if (jffs2_wbuf_pending_for_ino(c, ino))
-+ return;
-+
-+ new = kmalloc(sizeof(*new), GFP_KERNEL);
-+ if (!new) {
-+ D1(printk(KERN_DEBUG "No memory to allocate inodirty. Fallback to all considered dirty\n"));
-+ jffs2_clear_wbuf_ino_list(c);
-+ c->wbuf_inodes = &inodirty_nomem;
-+ return;
-+ }
-+ new->ino = ino;
-+ new->next = c->wbuf_inodes;
-+ c->wbuf_inodes = new;
-+ return;
-+}
-+
-+static inline void jffs2_refile_wbuf_blocks(struct jffs2_sb_info *c)
-+{
-+ struct list_head *this, *next;
-+ static int n;
-+
-+ if (list_empty(&c->erasable_pending_wbuf_list))
-+ return;
-+
-+ list_for_each_safe(this, next, &c->erasable_pending_wbuf_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+
-+ D1(printk(KERN_DEBUG "Removing eraseblock at 0x%08x from erasable_pending_wbuf_list...\n", jeb->offset));
-+ list_del(this);
-+ if ((jiffies + (n++)) & 127) {
-+ /* Most of the time, we just erase it immediately. Otherwise we
-+ spend ages scanning it on mount, etc. */
-+ D1(printk(KERN_DEBUG "...and adding to erase_pending_list\n"));
-+ list_add_tail(&jeb->list, &c->erase_pending_list);
-+ c->nr_erasing_blocks++;
-+ jffs2_erase_pending_trigger(c);
-+ } else {
-+ /* Sometimes, however, we leave it elsewhere so it doesn't get
-+ immediately reused, and we spread the load a bit. */
-+ D1(printk(KERN_DEBUG "...and adding to erasable_list\n"));
-+ list_add_tail(&jeb->list, &c->erasable_list);
-+ }
-+ }
-+}
-+
-+/* Recover from failure to write wbuf. Recover the nodes up to the
-+ * wbuf, not the one which we were starting to try to write. */
-+
-+static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
-+{
-+ struct jffs2_eraseblock *jeb, *new_jeb;
-+ struct jffs2_raw_node_ref **first_raw, **raw;
-+ size_t retlen;
-+ int ret;
-+ unsigned char *buf;
-+ uint32_t start, end, ofs, len;
-+
-+ spin_lock(&c->erase_completion_lock);
-+
-+ jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
-+
-+ D1(printk("About to refile bad block at %08x\n", jeb->offset));
-+
-+ D2(jffs2_dump_block_lists(c));
-+ /* File the existing block on the bad_used_list.... */
-+ if (c->nextblock == jeb)
-+ c->nextblock = NULL;
-+ else /* Not sure this should ever happen... need more coffee */
-+ list_del(&jeb->list);
-+ if (jeb->first_node) {
-+ D1(printk("Refiling block at %08x to bad_used_list\n", jeb->offset));
-+ list_add(&jeb->list, &c->bad_used_list);
-+ } else {
-+ BUG();
-+ /* It has to have had some nodes or we couldn't be here */
-+ D1(printk("Refiling block at %08x to erase_pending_list\n", jeb->offset));
-+ list_add(&jeb->list, &c->erase_pending_list);
-+ c->nr_erasing_blocks++;
-+ jffs2_erase_pending_trigger(c);
-+ }
-+ D2(jffs2_dump_block_lists(c));
-+
-+ /* Adjust its size counts accordingly */
-+ c->wasted_size += jeb->free_size;
-+ c->free_size -= jeb->free_size;
-+ jeb->wasted_size += jeb->free_size;
-+ jeb->free_size = 0;
-+
-+ ACCT_SANITY_CHECK(c,jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+
-+ /* Find the first node to be recovered, by skipping over every
-+ node which ends before the wbuf starts, or which is obsolete. */
-+ first_raw = &jeb->first_node;
-+ while (*first_raw &&
-+ (ref_obsolete(*first_raw) ||
-+ (ref_offset(*first_raw)+ref_totlen(c, jeb, *first_raw)) < c->wbuf_ofs)) {
-+ D1(printk(KERN_DEBUG "Skipping node at 0x%08x(%d)-0x%08x which is either before 0x%08x or obsolete\n",
-+ ref_offset(*first_raw), ref_flags(*first_raw),
-+ (ref_offset(*first_raw) + ref_totlen(c, jeb, *first_raw)),
-+ c->wbuf_ofs));
-+ first_raw = &(*first_raw)->next_phys;
-+ }
-+
-+ if (!*first_raw) {
-+ /* All nodes were obsolete. Nothing to recover. */
-+ D1(printk(KERN_DEBUG "No non-obsolete nodes to be recovered. Just filing block bad\n"));
-+ spin_unlock(&c->erase_completion_lock);
-+ return;
-+ }
-+
-+ start = ref_offset(*first_raw);
-+ end = ref_offset(*first_raw) + ref_totlen(c, jeb, *first_raw);
-+
-+ /* Find the last node to be recovered */
-+ raw = first_raw;
-+ while ((*raw)) {
-+ if (!ref_obsolete(*raw))
-+ end = ref_offset(*raw) + ref_totlen(c, jeb, *raw);
-+
-+ raw = &(*raw)->next_phys;
-+ }
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ D1(printk(KERN_DEBUG "wbuf recover %08x-%08x\n", start, end));
-+
-+ buf = NULL;
-+ if (start < c->wbuf_ofs) {
-+ /* First affected node was already partially written.
-+ * Attempt to reread the old data into our buffer. */
-+
-+ buf = kmalloc(end - start, GFP_KERNEL);
-+ if (!buf) {
-+ printk(KERN_CRIT "Malloc failure in wbuf recovery. Data loss ensues.\n");
-+
-+ goto read_failed;
-+ }
-+
-+ /* Do the read... */
-+ ret = c->mtd->read_ecc(c->mtd, start, c->wbuf_ofs - start, &retlen, buf, NULL, c->oobinfo);
-+ if (ret == -EIO && retlen == c->wbuf_ofs - start) {
-+ /* ECC recovered */
-+ ret = 0;
-+ }
-+ if (ret || retlen != c->wbuf_ofs - start) {
-+ printk(KERN_CRIT "Old data are already lost in wbuf recovery. Data loss ensues.\n");
-+
-+ kfree(buf);
-+ buf = NULL;
-+ read_failed:
-+ first_raw = &(*first_raw)->next_phys;
-+ /* If this was the only node to be recovered, give up */
-+ if (!(*first_raw))
-+ return;
-+
-+ /* It wasn't. Go on and try to recover nodes complete in the wbuf */
-+ start = ref_offset(*first_raw);
-+ } else {
-+ /* Read succeeded. Copy the remaining data from the wbuf */
-+ memcpy(buf + (c->wbuf_ofs - start), c->wbuf, end - c->wbuf_ofs);
-+ }
-+ }
-+ /* OK... we're to rewrite (end-start) bytes of data from first_raw onwards.
-+ Either 'buf' contains the data, or we find it in the wbuf */
-+
-+
-+ /* ... and get an allocation of space from a shiny new block instead */
-+ ret = jffs2_reserve_space_gc(c, end-start, &ofs, &len);
-+ if (ret) {
-+ printk(KERN_WARNING "Failed to allocate space for wbuf recovery. Data loss ensues.\n");
-+ if (buf)
-+ kfree(buf);
-+ return;
-+ }
-+ if (end-start >= c->wbuf_pagesize) {
-+ /* Need to do another write immediately. This, btw,
-+ means that we'll be writing from 'buf' and not from
-+ the wbuf. Since if we're writing from the wbuf there
-+ won't be more than a wbuf full of data, now will
-+ there? :) */
-+
-+ uint32_t towrite = (end-start) - ((end-start)%c->wbuf_pagesize);
-+
-+ D1(printk(KERN_DEBUG "Write 0x%x bytes at 0x%08x in wbuf recover\n",
-+ towrite, ofs));
-+
-+#ifdef BREAKMEHEADER
-+ static int breakme;
-+ if (breakme++ == 20) {
-+ printk(KERN_NOTICE "Faking write error at 0x%08x\n", ofs);
-+ breakme = 0;
-+ c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen,
-+ brokenbuf, NULL, c->oobinfo);
-+ ret = -EIO;
-+ } else
-+#endif
-+ ret = c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen,
-+ buf, NULL, c->oobinfo);
-+
-+ if (ret || retlen != towrite) {
-+ /* Argh. We tried. Really we did. */
-+ printk(KERN_CRIT "Recovery of wbuf failed due to a second write error\n");
-+ kfree(buf);
-+
-+ if (retlen) {
-+ struct jffs2_raw_node_ref *raw2;
-+
-+ raw2 = jffs2_alloc_raw_node_ref();
-+ if (!raw2)
-+ return;
-+
-+ raw2->flash_offset = ofs | REF_OBSOLETE;
-+ raw2->__totlen = ref_totlen(c, jeb, *first_raw);
-+ raw2->next_phys = NULL;
-+ raw2->next_in_ino = NULL;
-+
-+ jffs2_add_physical_node_ref(c, raw2);
-+ }
-+ return;
-+ }
-+ printk(KERN_NOTICE "Recovery of wbuf succeeded to %08x\n", ofs);
-+
-+ c->wbuf_len = (end - start) - towrite;
-+ c->wbuf_ofs = ofs + towrite;
-+ memcpy(c->wbuf, buf + towrite, c->wbuf_len);
-+ /* Don't muck about with c->wbuf_inodes. False positives are harmless. */
-+
-+ kfree(buf);
-+ } else {
-+ /* OK, now we're left with the dregs in whichever buffer we're using */
-+ if (buf) {
-+ memcpy(c->wbuf, buf, end-start);
-+ kfree(buf);
-+ } else {
-+ memmove(c->wbuf, c->wbuf + (start - c->wbuf_ofs), end - start);
-+ }
-+ c->wbuf_ofs = ofs;
-+ c->wbuf_len = end - start;
-+ }
-+
-+ /* Now sort out the jffs2_raw_node_refs, moving them from the old to the next block */
-+ new_jeb = &c->blocks[ofs / c->sector_size];
-+
-+ spin_lock(&c->erase_completion_lock);
-+ if (new_jeb->first_node) {
-+ /* Odd, but possible with ST flash later maybe */
-+ new_jeb->last_node->next_phys = *first_raw;
-+ } else {
-+ new_jeb->first_node = *first_raw;
-+ }
-+
-+ raw = first_raw;
-+ while (*raw) {
-+ uint32_t rawlen = ref_totlen(c, jeb, *raw);
-+
-+ D1(printk(KERN_DEBUG "Refiling block of %08x at %08x(%d) to %08x\n",
-+ rawlen, ref_offset(*raw), ref_flags(*raw), ofs));
-+
-+ if (ref_obsolete(*raw)) {
-+ /* Shouldn't really happen much */
-+ new_jeb->dirty_size += rawlen;
-+ new_jeb->free_size -= rawlen;
-+ c->dirty_size += rawlen;
-+ } else {
-+ new_jeb->used_size += rawlen;
-+ new_jeb->free_size -= rawlen;
-+ jeb->dirty_size += rawlen;
-+ jeb->used_size -= rawlen;
-+ c->dirty_size += rawlen;
-+ }
-+ c->free_size -= rawlen;
-+ (*raw)->flash_offset = ofs | ref_flags(*raw);
-+ ofs += rawlen;
-+ new_jeb->last_node = *raw;
-+
-+ raw = &(*raw)->next_phys;
-+ }
-+
-+ /* Fix up the original jeb now it's on the bad_list */
-+ *first_raw = NULL;
-+ if (first_raw == &jeb->first_node) {
-+ jeb->last_node = NULL;
-+ D1(printk(KERN_DEBUG "Failing block at %08x is now empty. Moving to erase_pending_list\n", jeb->offset));
-+ list_del(&jeb->list);
-+ list_add(&jeb->list, &c->erase_pending_list);
-+ c->nr_erasing_blocks++;
-+ jffs2_erase_pending_trigger(c);
-+ }
-+ else
-+ jeb->last_node = container_of(first_raw, struct jffs2_raw_node_ref, next_phys);
-+
-+ ACCT_SANITY_CHECK(c,jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+
-+ ACCT_SANITY_CHECK(c,new_jeb);
-+ D1(ACCT_PARANOIA_CHECK(new_jeb));
-+
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ D1(printk(KERN_DEBUG "wbuf recovery completed OK\n"));
-+}
-+
-+/* Meaning of pad argument:
-+ 0: Do not pad. Probably pointless - we only ever use this when we can't pad anyway.
-+ 1: Pad, do not adjust nextblock free_size
-+ 2: Pad, adjust nextblock free_size
-+*/
-+static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
-+{
-+ int ret;
-+ size_t retlen;
-+
-+ /* Nothing to do if not NAND flash. In particular, we shouldn't
-+ del_timer() the timer we never initialised. */
-+ if (jffs2_can_mark_obsolete(c))
-+ return 0;
-+
-+ if (!down_trylock(&c->alloc_sem)) {
-+ up(&c->alloc_sem);
-+ printk(KERN_CRIT "jffs2_flush_wbuf() called with alloc_sem not locked!\n");
-+ BUG();
-+ }
-+
-+ if(!c->wbuf || !c->wbuf_len)
-+ return 0;
-+
-+ /* claim remaining space on the page
-+ this happens, if we have a change to a new block,
-+ or if fsync forces us to flush the writebuffer.
-+ if we have a switch to next page, we will not have
-+ enough remaining space for this.
-+ */
-+ if (pad) {
-+ c->wbuf_len = PAD(c->wbuf_len);
-+
-+ if ( c->wbuf_len + sizeof(struct jffs2_unknown_node) < c->wbuf_pagesize) {
-+ struct jffs2_unknown_node *padnode = (void *)(c->wbuf + c->wbuf_len);
-+ padnode->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ padnode->nodetype = cpu_to_je16(JFFS2_NODETYPE_PADDING);
-+ padnode->totlen = cpu_to_je32(c->wbuf_pagesize - c->wbuf_len);
-+ padnode->hdr_crc = cpu_to_je32(crc32(0, padnode, sizeof(*padnode)-4));
-+ }
-+ }
-+ /* else jffs2_flash_writev has actually filled in the rest of the
-+ buffer for us, and will deal with the node refs etc. later. */
-+
-+#ifdef BREAKME
-+ static int breakme;
-+ if (breakme++ == 20) {
-+ printk(KERN_NOTICE "Faking write error at 0x%08x\n", c->wbuf_ofs);
-+ breakme = 0;
-+ c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize,
-+ &retlen, brokenbuf, NULL, c->oobinfo);
-+ ret = -EIO;
-+ } else
-+#endif
-+ ret = c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf, NULL, c->oobinfo);
-+
-+
-+ if (ret || retlen != c->wbuf_pagesize) {
-+ if (ret)
-+ printk(KERN_WARNING "jffs2_flush_wbuf(): Write failed with %d\n",ret);
-+ else {
-+ printk(KERN_WARNING "jffs2_flush_wbuf(): Write was short: %zd instead of %d\n",
-+ retlen, c->wbuf_pagesize);
-+ ret = -EIO;
-+ }
-+
-+ jffs2_wbuf_recover(c);
-+
-+ return ret;
-+ }
-+
-+ /* Adjusting free size of next block only, if it's called from fsync ! */
-+ if (pad == 2) {
-+ D1(printk(KERN_DEBUG "jffs2_flush_wbuf() adjusting free_size of c->nextblock\n"));
-+ spin_lock(&c->erase_completion_lock);
-+ if (!c->nextblock)
-+ BUG();
-+ /* wbuf_pagesize - wbuf_len is the amount of space that's to be
-+ padded. If there is less free space in the block than that,
-+ something screwed up */
-+ if (c->nextblock->free_size < (c->wbuf_pagesize - c->wbuf_len)) {
-+ printk(KERN_CRIT "jffs2_flush_wbuf(): Accounting error. wbuf at 0x%08x has 0x%03x bytes, 0x%03x left.\n",
-+ c->wbuf_ofs, c->wbuf_len, c->wbuf_pagesize-c->wbuf_len);
-+ printk(KERN_CRIT "jffs2_flush_wbuf(): But free_size for block at 0x%08x is only 0x%08x\n",
-+ c->nextblock->offset, c->nextblock->free_size);
-+ BUG();
-+ }
-+ c->nextblock->free_size -= (c->wbuf_pagesize - c->wbuf_len);
-+ c->free_size -= (c->wbuf_pagesize - c->wbuf_len);
-+ c->nextblock->wasted_size += (c->wbuf_pagesize - c->wbuf_len);
-+ c->wasted_size += (c->wbuf_pagesize - c->wbuf_len);
-+ spin_unlock(&c->erase_completion_lock);
-+ }
-+
-+ /* Stick any now-obsoleted blocks on the erase_pending_list */
-+ spin_lock(&c->erase_completion_lock);
-+ jffs2_refile_wbuf_blocks(c);
-+ jffs2_clear_wbuf_ino_list(c);
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ memset(c->wbuf,0xff,c->wbuf_pagesize);
-+ /* adjust write buffer offset, else we get a non contiguous write bug */
-+ c->wbuf_ofs += c->wbuf_pagesize;
-+ c->wbuf_len = 0;
-+ return 0;
-+}
-+
-+/* Trigger garbage collection to flush the write-buffer.
-+ If ino arg is zero, do it if _any_ real (i.e. not GC) writes are
-+ outstanding. If ino arg non-zero, do it only if a write for the
-+ given inode is outstanding. */
-+int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino)
-+{
-+ uint32_t old_wbuf_ofs;
-+ uint32_t old_wbuf_len;
-+ int ret = 0;
-+
-+ D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() called for ino #%u...\n", ino));
-+
-+ down(&c->alloc_sem);
-+ if (!jffs2_wbuf_pending_for_ino(c, ino)) {
-+ D1(printk(KERN_DEBUG "Ino #%d not pending in wbuf. Returning\n", ino));
-+ up(&c->alloc_sem);
-+ return 0;
-+ }
-+
-+ old_wbuf_ofs = c->wbuf_ofs;
-+ old_wbuf_len = c->wbuf_len;
-+
-+ if (c->unchecked_size) {
-+ /* GC won't make any progress for a while */
-+ D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() padding. Not finished checking\n"));
-+ ret = __jffs2_flush_wbuf(c, 2);
-+ } else while (old_wbuf_len &&
-+ old_wbuf_ofs == c->wbuf_ofs) {
-+
-+ up(&c->alloc_sem);
-+
-+ D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() calls gc pass\n"));
-+
-+ ret = jffs2_garbage_collect_pass(c);
-+ if (ret) {
-+ /* GC failed. Flush it with padding instead */
-+ down(&c->alloc_sem);
-+ ret = __jffs2_flush_wbuf(c, 2);
-+ break;
-+ }
-+ down(&c->alloc_sem);
-+ }
-+
-+ D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() ends...\n"));
-+
-+ up(&c->alloc_sem);
-+ return ret;
-+}
-+
-+/* Pad write-buffer to end and write it, wasting space. */
-+int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c)
-+{
-+ return __jffs2_flush_wbuf(c, 1);
-+}
-+
-+
-+#define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) )
-+#define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) )
-+int jffs2_flash_writev(struct jffs2_sb_info *c, const struct iovec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino)
-+{
-+ struct iovec outvecs[3];
-+ uint32_t totlen = 0;
-+ uint32_t split_ofs = 0;
-+ uint32_t old_totlen;
-+ int ret, splitvec = -1;
-+ int invec, outvec;
-+ size_t wbuf_retlen;
-+ unsigned char *wbuf_ptr;
-+ size_t donelen = 0;
-+ uint32_t outvec_to = to;
-+
-+ /* If not NAND flash, don't bother */
-+ if (!c->wbuf)
-+ return jffs2_flash_direct_writev(c, invecs, count, to, retlen);
-+
-+ /* If wbuf_ofs is not initialized, set it to target address */
-+ if (c->wbuf_ofs == 0xFFFFFFFF) {
-+ c->wbuf_ofs = PAGE_DIV(to);
-+ c->wbuf_len = PAGE_MOD(to);
-+ memset(c->wbuf,0xff,c->wbuf_pagesize);
-+ }
-+
-+ /* Sanity checks on target address.
-+ It's permitted to write at PAD(c->wbuf_len+c->wbuf_ofs),
-+ and it's permitted to write at the beginning of a new
-+ erase block. Anything else, and you die.
-+ New block starts at xxx000c (0-b = block header)
-+ */
-+ if ( (to & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) {
-+ /* It's a write to a new block */
-+ if (c->wbuf_len) {
-+ D1(printk(KERN_DEBUG "jffs2_flash_writev() to 0x%lx causes flush of wbuf at 0x%08x\n", (unsigned long)to, c->wbuf_ofs));
-+ ret = jffs2_flush_wbuf_pad(c);
-+ if (ret) {
-+ /* the underlying layer has to check wbuf_len to do the cleanup */
-+ D1(printk(KERN_WARNING "jffs2_flush_wbuf() called from jffs2_flash_writev() failed %d\n", ret));
-+ *retlen = 0;
-+ return ret;
-+ }
-+ }
-+ /* set pointer to new block */
-+ c->wbuf_ofs = PAGE_DIV(to);
-+ c->wbuf_len = PAGE_MOD(to);
-+ }
-+
-+ if (to != PAD(c->wbuf_ofs + c->wbuf_len)) {
-+ /* We're not writing immediately after the writebuffer. Bad. */
-+ printk(KERN_CRIT "jffs2_flash_writev(): Non-contiguous write to %08lx\n", (unsigned long)to);
-+ if (c->wbuf_len)
-+ printk(KERN_CRIT "wbuf was previously %08x-%08x\n",
-+ c->wbuf_ofs, c->wbuf_ofs+c->wbuf_len);
-+ BUG();
-+ }
-+
-+ /* Note outvecs[3] above. We know count is never greater than 2 */
-+ if (count > 2) {
-+ printk(KERN_CRIT "jffs2_flash_writev(): count is %ld\n", count);
-+ BUG();
-+ }
-+
-+ invec = 0;
-+ outvec = 0;
-+
-+
-+ /* Fill writebuffer first, if already in use */
-+ if (c->wbuf_len) {
-+ uint32_t invec_ofs = 0;
-+
-+ /* adjust alignment offset */
-+ if (c->wbuf_len != PAGE_MOD(to)) {
-+ c->wbuf_len = PAGE_MOD(to);
-+ /* take care of alignment to next page */
-+ if (!c->wbuf_len)
-+ c->wbuf_len = c->wbuf_pagesize;
-+ }
-+
-+ while(c->wbuf_len < c->wbuf_pagesize) {
-+ uint32_t thislen;
-+
-+ if (invec == count)
-+ goto alldone;
-+
-+ thislen = c->wbuf_pagesize - c->wbuf_len;
-+
-+ if (thislen >= invecs[invec].iov_len)
-+ thislen = invecs[invec].iov_len;
-+
-+ invec_ofs = thislen;
-+
-+ memcpy(c->wbuf + c->wbuf_len, invecs[invec].iov_base, thislen);
-+ c->wbuf_len += thislen;
-+ donelen += thislen;
-+ /* Get next invec, if actual did not fill the buffer */
-+ if (c->wbuf_len < c->wbuf_pagesize)
-+ invec++;
-+ }
-+
-+ /* write buffer is full, flush buffer */
-+ ret = __jffs2_flush_wbuf(c, 0);
-+ if (ret) {
-+ /* the underlying layer has to check wbuf_len to do the cleanup */
-+ D1(printk(KERN_WARNING "jffs2_flush_wbuf() called from jffs2_flash_writev() failed %d\n", ret));
-+ /* Retlen zero to make sure our caller doesn't mark the space dirty.
-+ We've already done everything that's necessary */
-+ *retlen = 0;
-+ return ret;
-+ }
-+ outvec_to += donelen;
-+ c->wbuf_ofs = outvec_to;
-+
-+ /* All invecs done ? */
-+ if (invec == count)
-+ goto alldone;
-+
-+ /* Set up the first outvec, containing the remainder of the
-+ invec we partially used */
-+ if (invecs[invec].iov_len > invec_ofs) {
-+ outvecs[0].iov_base = invecs[invec].iov_base+invec_ofs;
-+ totlen = outvecs[0].iov_len = invecs[invec].iov_len-invec_ofs;
-+ if (totlen > c->wbuf_pagesize) {
-+ splitvec = outvec;
-+ split_ofs = outvecs[0].iov_len - PAGE_MOD(totlen);
-+ }
-+ outvec++;
-+ }
-+ invec++;
-+ }
-+
-+ /* OK, now we've flushed the wbuf and the start of the bits
-+ we have been asked to write, now to write the rest.... */
-+
-+ /* totlen holds the amount of data still to be written */
-+ old_totlen = totlen;
-+ for ( ; invec < count; invec++,outvec++ ) {
-+ outvecs[outvec].iov_base = invecs[invec].iov_base;
-+ totlen += outvecs[outvec].iov_len = invecs[invec].iov_len;
-+ if (PAGE_DIV(totlen) != PAGE_DIV(old_totlen)) {
-+ splitvec = outvec;
-+ split_ofs = outvecs[outvec].iov_len - PAGE_MOD(totlen);
-+ old_totlen = totlen;
-+ }
-+ }
-+
-+ /* Now the outvecs array holds all the remaining data to write */
-+ /* Up to splitvec,split_ofs is to be written immediately. The rest
-+ goes into the (now-empty) wbuf */
-+
-+ if (splitvec != -1) {
-+ uint32_t remainder;
-+ int ret;
-+
-+ remainder = outvecs[splitvec].iov_len - split_ofs;
-+ outvecs[splitvec].iov_len = split_ofs;
-+
-+ /* We did cross a page boundary, so we write some now */
-+ ret = c->mtd->writev_ecc(c->mtd, outvecs, splitvec+1, outvec_to, &wbuf_retlen, NULL, c->oobinfo);
-+ if (ret < 0 || wbuf_retlen != PAGE_DIV(totlen)) {
-+ /* At this point we have no problem,
-+ c->wbuf is empty.
-+ */
-+ *retlen = donelen;
-+ return ret;
-+ }
-+
-+ donelen += wbuf_retlen;
-+ c->wbuf_ofs = PAGE_DIV(outvec_to) + PAGE_DIV(totlen);
-+
-+ if (remainder) {
-+ outvecs[splitvec].iov_base += split_ofs;
-+ outvecs[splitvec].iov_len = remainder;
-+ } else {
-+ splitvec++;
-+ }
-+
-+ } else {
-+ splitvec = 0;
-+ }
-+
-+ /* Now splitvec points to the start of the bits we have to copy
-+ into the wbuf */
-+ wbuf_ptr = c->wbuf;
-+
-+ for ( ; splitvec < outvec; splitvec++) {
-+ /* Don't copy the wbuf into itself */
-+ if (outvecs[splitvec].iov_base == c->wbuf)
-+ continue;
-+ memcpy(wbuf_ptr, outvecs[splitvec].iov_base, outvecs[splitvec].iov_len);
-+ wbuf_ptr += outvecs[splitvec].iov_len;
-+ donelen += outvecs[splitvec].iov_len;
-+ }
-+ c->wbuf_len = wbuf_ptr - c->wbuf;
-+
-+ /* If there's a remainder in the wbuf and it's a non-GC write,
-+ remember that the wbuf affects this ino */
-+alldone:
-+ *retlen = donelen;
-+
-+ if (c->wbuf_len && ino)
-+ jffs2_wbuf_dirties_inode(c, ino);
-+
-+ return 0;
-+}
-+
-+/*
-+ * This is the entry for flash write.
-+ * Check, if we work on NAND FLASH, if so build an iovec and write it via vritev
-+*/
-+int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, const u_char *buf)
-+{
-+ struct iovec vecs[1];
-+
-+ if (jffs2_can_mark_obsolete(c))
-+ return c->mtd->write(c->mtd, ofs, len, retlen, buf);
-+
-+ vecs[0].iov_base = (unsigned char *) buf;
-+ vecs[0].iov_len = len;
-+ return jffs2_flash_writev(c, vecs, 1, ofs, retlen, 0);
-+}
-+
-+/*
-+ Handle readback from writebuffer and ECC failure return
-+*/
-+int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, u_char *buf)
-+{
-+ loff_t orbf = 0, owbf = 0, lwbf = 0;
-+ int ret;
-+
-+ /* Read flash */
-+ if (!jffs2_can_mark_obsolete(c)) {
-+ ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo);
-+
-+ if ( (ret == -EIO) && (*retlen == len) ) {
-+ printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n",
-+ len, ofs);
-+ /*
-+ * We have the raw data without ECC correction in the buffer, maybe
-+ * we are lucky and all data or parts are correct. We check the node.
-+ * If data are corrupted node check will sort it out.
-+ * We keep this block, it will fail on write or erase and the we
-+ * mark it bad. Or should we do that now? But we should give him a chance.
-+ * Maybe we had a system crash or power loss before the ecc write or
-+ * a erase was completed.
-+ * So we return success. :)
-+ */
-+ ret = 0;
-+ }
-+ } else
-+ return c->mtd->read(c->mtd, ofs, len, retlen, buf);
-+
-+ /* if no writebuffer available or write buffer empty, return */
-+ if (!c->wbuf_pagesize || !c->wbuf_len)
-+ return ret;
-+
-+ /* if we read in a different block, return */
-+ if ( (ofs & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) )
-+ return ret;
-+
-+ if (ofs >= c->wbuf_ofs) {
-+ owbf = (ofs - c->wbuf_ofs); /* offset in write buffer */
-+ if (owbf > c->wbuf_len) /* is read beyond write buffer ? */
-+ return ret;
-+ lwbf = c->wbuf_len - owbf; /* number of bytes to copy */
-+ if (lwbf > len)
-+ lwbf = len;
-+ } else {
-+ orbf = (c->wbuf_ofs - ofs); /* offset in read buffer */
-+ if (orbf > len) /* is write beyond write buffer ? */
-+ return ret;
-+ lwbf = len - orbf; /* number of bytes to copy */
-+ if (lwbf > c->wbuf_len)
-+ lwbf = c->wbuf_len;
-+ }
-+ if (lwbf > 0)
-+ memcpy(buf+orbf,c->wbuf+owbf,lwbf);
-+
-+ return ret;
-+}
-+
-+/*
-+ * Check, if the out of band area is empty
-+ */
-+int jffs2_check_oob_empty( struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, int mode)
-+{
-+ unsigned char *buf;
-+ int ret = 0;
-+ int i,len,page;
-+ size_t retlen;
-+ int oob_size;
-+
-+ oob_size = c->mtd->oobsize;
-+
-+ /* allocate a buffer for all oob data in this sector */
-+ len = 4 * oob_size;
-+ buf = kmalloc(len, GFP_KERNEL);
-+ if (!buf) {
-+ printk(KERN_NOTICE "jffs2_check_oob_empty(): allocation of temporary data buffer for oob check failed\n");
-+ return -ENOMEM;
-+ }
-+ /*
-+ * if mode = 0, we scan for a total empty oob area, else we have
-+ * to take care of the cleanmarker in the first page of the block
-+ */
-+ ret = jffs2_flash_read_oob(c, jeb->offset, len , &retlen, buf);
-+ if (ret) {
-+ D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB failed %d for block at %08x\n", ret, jeb->offset));
-+ goto out;
-+ }
-+
-+ if (retlen < len) {
-+ D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB return short read "
-+ "(%zd bytes not %d) for block at %08x\n", retlen, len, jeb->offset));
-+ ret = -EIO;
-+ goto out;
-+ }
-+
-+ /* Special check for first two pages */
-+ for (page = 0; page < 2 * oob_size; page += oob_size) {
-+ /* Check for bad block marker */
-+ if (buf[page+c->badblock_pos] != 0xff) {
-+ D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Bad or failed block at %08x\n",jeb->offset));
-+ /* Return 2 for bad and 3 for failed block
-+ bad goes to list_bad and failed to list_erase */
-+ ret = (!page) ? 2 : 3;
-+ goto out;
-+ }
-+ for(i = 0; i < oob_size ; i++) {
-+ /* Yeah, we know about the cleanmarker. */
-+ if (mode && i >= c->fsdata_pos &&
-+ i < c->fsdata_pos+c->fsdata_len)
-+ continue;
-+
-+ if (buf[page+i] != 0xFF) {
-+ D2(printk(KERN_DEBUG "Found %02x at %x in OOB for %08x\n",
-+ buf[page+i], page+i, jeb->offset));
-+ ret = 1;
-+ goto out;
-+ }
-+ }
-+ /* only the first page can contain a cleanmarker !*/
-+ mode = 0;
-+ }
-+
-+ /* we know, we are aligned :) */
-+ for (; page < len; page += sizeof(long)) {
-+ unsigned long dat = *(unsigned long *)(&buf[page]);
-+ if(dat != -1) {
-+ ret = 1;
-+ goto out;
-+ }
-+ }
-+
-+out:
-+ kfree(buf);
-+
-+ return ret;
-+}
-+
-+/*
-+* Scan for a valid cleanmarker and for bad blocks
-+* For virtual blocks (concatenated physical blocks) check the cleanmarker
-+* only in the first page of the first physical block, but scan for bad blocks in all
-+* physical blocks
-+*/
-+int jffs2_check_nand_cleanmarker (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
-+{
-+ struct jffs2_unknown_node n;
-+ unsigned char buf[32];
-+ unsigned char *p;
-+ int ret, i, cnt, retval = 0;
-+ size_t retlen, offset;
-+ int oob_size;
-+
-+ offset = jeb->offset;
-+ oob_size = c->mtd->oobsize;
-+
-+ /* Loop through the physical blocks */
-+ for (cnt = 0; cnt < (c->sector_size / c->mtd->erasesize); cnt++) {
-+ /*
-+ * We read oob data from page 0 and 1 of the block.
-+ * page 0 contains cleanmarker and badblock info
-+ * page 1 contains failure count of this block
-+ */
-+ ret = c->mtd->read_oob (c->mtd, offset, oob_size << 1, &retlen, buf);
-+
-+ if (ret) {
-+ D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB failed %d for block at %08x\n", ret, jeb->offset));
-+ return ret;
-+ }
-+ if (retlen < (oob_size << 1)) {
-+ D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB return short read (%zd bytes not %d) for block at %08x\n", retlen, oob_size << 1, jeb->offset));
-+ return -EIO;
-+ }
-+
-+ /* Check for bad block marker */
-+ if (buf[c->badblock_pos] != 0xff) {
-+ D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Bad block at %08x (has %02x %02x in badblock_pos %d\n",
-+ jeb->offset, buf[c->badblock_pos], buf[c->badblock_pos + oob_size], c->badblock_pos));
-+ return 2;
-+ }
-+
-+ /* Check for failure counter in the second page */
-+ if (buf[c->badblock_pos + oob_size] != 0xff) {
-+ D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Block marked as failed at %08x, fail count:%d\n", jeb->offset, buf[c->badblock_pos + oob_size]));
-+ return 3;
-+ }
-+
-+ /* Check cleanmarker only on the first physical block */
-+ if (!cnt) {
-+ n.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK);
-+ n.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER);
-+ n.totlen = cpu_to_je32 (8);
-+ p = (unsigned char *) &n;
-+
-+ for (i = 0; i < c->fsdata_len; i++) {
-+ if (buf[c->fsdata_pos + i] != p[i]) {
-+ retval = 1;
-+ }
-+ }
-+ D1(if (retval == 1) {
-+ printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): Cleanmarker node not detected in block at %08x\n", jeb->offset);
-+ printk(KERN_WARNING "OOB at %08x was ", offset);
-+ for (i=0; i < oob_size; i++) {
-+ printk("%02x ", buf[i]);
-+ }
-+ printk("\n");
-+ })
-+ }
-+ offset += c->mtd->erasesize;
-+ }
-+ return retval;
-+}
-+
-+int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
-+{
-+ struct jffs2_unknown_node n;
-+ int ret;
-+ size_t retlen;
-+
-+ n.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
-+ n.totlen = cpu_to_je32(8);
-+
-+ ret = jffs2_flash_write_oob(c, jeb->offset + c->fsdata_pos, c->fsdata_len, &retlen, (unsigned char *)&n);
-+
-+ if (ret) {
-+ D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Write failed for block at %08x: error %d\n", jeb->offset, ret));
-+ return ret;
-+ }
-+ if (retlen != c->fsdata_len) {
-+ D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Short write for block at %08x: %zd not %d\n", jeb->offset, retlen, c->fsdata_len));
-+ return ret;
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * We try to get the failure count of this block.
-+ */
-+int jffs2_nand_read_failcnt(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) {
-+
-+ unsigned char buf[16];
-+ int ret;
-+ size_t retlen;
-+ int oob_size;
-+
-+ oob_size = c->mtd->oobsize;
-+
-+ ret = c->mtd->read_oob(c->mtd, jeb->offset + c->mtd->oobblock, oob_size , &retlen, buf);
-+
-+ if (ret) {
-+ D1(printk(KERN_WARNING "jffs2_nand_read_failcnt(): Read OOB failed %d for block at %08x\n", ret, jeb->offset));
-+ return ret;
-+ }
-+
-+ if (retlen < oob_size) {
-+ D1(printk(KERN_WARNING "jffs2_nand_read_failcnt(): Read OOB return short read (%zd bytes not %d) for block at %08x\n", retlen, oob_size, jeb->offset));
-+ return -EIO;
-+ }
-+
-+ jeb->bad_count = buf[c->badblock_pos];
-+ return 0;
-+}
-+
-+/*
-+ * On NAND we try to mark this block bad. We try to write how often
-+ * the block was erased and mark it finaly bad, if the count
-+ * is > MAX_ERASE_FAILURES. We read this information on mount !
-+ * jeb->bad_count contains the count before this erase.
-+ * Don't care about failures. This block remains on the erase-pending
-+ * or badblock list as long as nobody manipulates the flash with
-+ * a bootloader or something like that.
-+ */
-+
-+int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
-+{
-+ unsigned char buf = 0x0;
-+ int ret;
-+ size_t retlen;
-+
-+ /* if the count is < max, we try to write the counter to the 2nd page oob area */
-+ if( ++jeb->bad_count < MAX_ERASE_FAILURES) {
-+ buf = (unsigned char)jeb->bad_count;
-+ c->badblock_pos += c->mtd->oobblock;
-+ }
-+
-+ ret = jffs2_flash_write_oob(c, jeb->offset + c->badblock_pos, 1, &retlen, &buf);
-+
-+ if (ret) {
-+ D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Write failed for block at %08x: error %d\n", jeb->offset, ret));
-+ return ret;
-+ }
-+ if (retlen != 1) {
-+ D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Short write for block at %08x: %zd not 1\n", jeb->offset, retlen));
-+ return ret;
-+ }
-+ return 0;
-+}
-+
-+#define JFFS2_OOB_ECCPOS0 0
-+#define JFFS2_OOB_ECCPOS1 1
-+#define JFFS2_OOB_ECCPOS2 2
-+#define JFFS2_OOB_ECCPOS3 3
-+#define JFFS2_OOB_ECCPOS4 6
-+#define JFFS2_OOB_ECCPOS5 7
-+
-+#define NAND_JFFS2_OOB8_FSDAPOS 6
-+#define NAND_JFFS2_OOB16_FSDAPOS 8
-+#define NAND_JFFS2_OOB8_FSDALEN 2
-+#define NAND_JFFS2_OOB16_FSDALEN 8
-+
-+static struct nand_oobinfo jffs2_oobinfo_swecc = {
-+ .useecc = 1,
-+ .eccpos = {JFFS2_OOB_ECCPOS0, JFFS2_OOB_ECCPOS1, JFFS2_OOB_ECCPOS2,
-+ JFFS2_OOB_ECCPOS3, JFFS2_OOB_ECCPOS4, JFFS2_OOB_ECCPOS5}
-+};
-+
-+static struct nand_oobinfo jffs2_oobinfo_docecc = {
-+ .useecc = 1,
-+ .eccpos = {0,1,2,3,4,5}
-+};
-+
-+
-+
-+int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
-+{
-+ /* Cleanmarker is out-of-band, so inline size zero */
-+ c->cleanmarker_size = 0;
-+
-+ /* Initialise write buffer */
-+ c->wbuf_pagesize = c->mtd->oobblock;
-+ c->wbuf_ofs = 0xFFFFFFFF;
-+
-+ /* FIXME: If we had a generic way of describing the hardware's
-+ use of OOB area, we could perhaps make this generic too. */
-+ switch(c->mtd->ecctype) {
-+ case MTD_ECC_SW:
-+ D1(printk(KERN_DEBUG "JFFS2 using software ECC\n"));
-+ c->oobinfo = &jffs2_oobinfo_swecc;
-+ if (c->mtd->oobsize == 8) {
-+ c->fsdata_pos = NAND_JFFS2_OOB8_FSDAPOS;
-+ c->fsdata_len = NAND_JFFS2_OOB8_FSDALEN;
-+ } else {
-+ c->fsdata_pos = NAND_JFFS2_OOB16_FSDAPOS;
-+ c->fsdata_len = NAND_JFFS2_OOB16_FSDALEN;
-+ }
-+ c->badblock_pos = NAND_BADBLOCK_POS;
-+ break;
-+
-+ case MTD_ECC_RS_DiskOnChip:
-+ D1(printk(KERN_DEBUG "JFFS2 using DiskOnChip hardware ECC\n"));
-+ c->oobinfo = &jffs2_oobinfo_docecc;
-+ c->fsdata_pos = 6;
-+ c->fsdata_len = NAND_JFFS2_OOB16_FSDALEN;
-+ c->badblock_pos = 15;
-+ break;
-+
-+ default:
-+ printk("JFFS2 doesn't yet know how to handle ECC type %d\n",
-+ c->mtd->ecctype);
-+ return -EINVAL;
-+ }
-+
-+ c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
-+ if (!c->wbuf)
-+ return -ENOMEM;
-+
-+#ifdef BREAKME
-+ if (!brokenbuf)
-+ brokenbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
-+ if (!brokenbuf) {
-+ kfree(c->wbuf);
-+ return -ENOMEM;
-+ }
-+ memset(brokenbuf, 0xdb, c->wbuf_pagesize);
-+#endif
-+ return 0;
-+}
-+
-+void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c)
-+{
-+ kfree(c->wbuf);
-+}
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/write.c linux/fs/jffs2/write.c
---- linux-mips-2.4.24-pre2/fs/jffs2/write.c 2004-11-17 18:05:04.000000000 +0100
-+++ linux/fs/jffs2/write.c 2004-11-17 18:17:59.000000000 +0100
-@@ -1,154 +1,70 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/kernel.h>
- #include <linux/fs.h>
--#include <linux/jffs2.h>
-+#include <linux/crc32.h>
-+#include <linux/slab.h>
-+#include <linux/pagemap.h>
- #include <linux/mtd/mtd.h>
- #include "nodelist.h"
--#include <linux/crc32.h>
-
--/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
-- fill in the raw_inode while you're at it. */
--struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri)
-+
-+int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri)
- {
-- struct inode *inode;
-- struct super_block *sb = dir_i->i_sb;
- struct jffs2_inode_cache *ic;
-- struct jffs2_sb_info *c;
-- struct jffs2_inode_info *f;
--
-- D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode));
--
-- c = JFFS2_SB_INFO(sb);
-- memset(ri, 0, sizeof(*ri));
-
- ic = jffs2_alloc_inode_cache();
- if (!ic) {
-- return ERR_PTR(-ENOMEM);
-+ return -ENOMEM;
- }
-- memset(ic, 0, sizeof(*ic));
--
-- inode = new_inode(sb);
-
-- if (!inode) {
-- jffs2_free_inode_cache(ic);
-- return ERR_PTR(-ENOMEM);
-- }
--
-- /* Alloc jffs2_inode_info when that's split in 2.5 */
-+ memset(ic, 0, sizeof(*ic));
-
-- f = JFFS2_INODE_INFO(inode);
-- memset(f, 0, sizeof(*f));
- init_MUTEX_LOCKED(&f->sem);
- f->inocache = ic;
-- inode->i_nlink = f->inocache->nlink = 1;
-+ f->inocache->nlink = 1;
- f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
-- f->inocache->ino = ri->ino = inode->i_ino = ++c->highest_ino;
-- D1(printk(KERN_DEBUG "jffs2_new_inode(): Assigned ino# %d\n", ri->ino));
-- jffs2_add_ino_cache(c, f->inocache);
-+ f->inocache->ino = ++c->highest_ino;
-+ f->inocache->state = INO_STATE_PRESENT;
-
-- ri->magic = JFFS2_MAGIC_BITMASK;
-- ri->nodetype = JFFS2_NODETYPE_INODE;
-- ri->totlen = PAD(sizeof(*ri));
-- ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
-- ri->mode = mode;
-- f->highest_version = ri->version = 1;
-- ri->uid = current->fsuid;
-- if (dir_i->i_mode & S_ISGID) {
-- ri->gid = dir_i->i_gid;
-- if (S_ISDIR(mode))
-- ri->mode |= S_ISGID;
-- } else {
-- ri->gid = current->fsgid;
-- }
-- inode->i_mode = ri->mode;
-- inode->i_gid = ri->gid;
-- inode->i_uid = ri->uid;
-- inode->i_atime = inode->i_ctime = inode->i_mtime =
-- ri->atime = ri->mtime = ri->ctime = CURRENT_TIME;
-- inode->i_blksize = PAGE_SIZE;
-- inode->i_blocks = 0;
-- inode->i_size = 0;
-+ ri->ino = cpu_to_je32(f->inocache->ino);
-
-- insert_inode_hash(inode);
-+ D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino));
-+ jffs2_add_ino_cache(c, f->inocache);
-
-- return inode;
--}
-+ ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
-+ ri->totlen = cpu_to_je32(PAD(sizeof(*ri)));
-+ ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
-+ ri->mode = cpu_to_jemode(mode);
-
--/* This ought to be in core MTD code. All registered MTD devices
-- without writev should have this put in place. Bug the MTD
-- maintainer */
--static int mtd_fake_writev(struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen)
--{
-- unsigned long i;
-- size_t totlen = 0, thislen;
-- int ret = 0;
-+ f->highest_version = 1;
-+ ri->version = cpu_to_je32(f->highest_version);
-
-- for (i=0; i<count; i++) {
-- ret = mtd->write(mtd, to, vecs[i].iov_len, &thislen, vecs[i].iov_base);
-- totlen += thislen;
-- if (ret || thislen != vecs[i].iov_len)
-- break;
-- to += vecs[i].iov_len;
-- }
-- if (retlen)
-- *retlen = totlen;
-- return ret;
--}
--
--
--static inline int mtd_writev(struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen)
--{
-- if (mtd->writev)
-- return mtd->writev(mtd,vecs,count,to,retlen);
-- else
-- return mtd_fake_writev(mtd, vecs, count, to, retlen);
-+ return 0;
- }
-
--static void writecheck(struct mtd_info *mtd, __u32 ofs)
-+#if CONFIG_JFFS2_FS_DEBUG > 0
-+static void writecheck(struct jffs2_sb_info *c, uint32_t ofs)
- {
- unsigned char buf[16];
-- ssize_t retlen;
-+ size_t retlen;
- int ret, i;
-
-- ret = mtd->read(mtd, ofs, 16, &retlen, buf);
-- if (ret && retlen != 16) {
-- D1(printk(KERN_DEBUG "read failed or short in writecheck(). ret %d, retlen %d\n", ret, retlen));
-+ ret = jffs2_flash_read(c, ofs, 16, &retlen, buf);
-+ if (ret || (retlen != 16)) {
-+ D1(printk(KERN_DEBUG "read failed or short in writecheck(). ret %d, retlen %zd\n", ret, retlen));
- return;
- }
- ret = 0;
-@@ -157,32 +73,31 @@
- ret = 1;
- }
- if (ret) {
-- printk(KERN_WARNING "ARGH. About to write node to 0x%08x on flash, but there's data already there:\n", ofs);
-+ printk(KERN_WARNING "ARGH. About to write node to 0x%08x on flash, but there are data already there:\n", ofs);
- printk(KERN_WARNING "0x%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- ofs,
- buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7],
- buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);
- }
- }
--
--
-+#endif
-
-
- /* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it,
- write it to the flash, link it into the existing inode/fragment list */
-
--struct jffs2_full_dnode *jffs2_write_dnode(struct inode *inode, struct jffs2_raw_inode *ri, const unsigned char *data, __u32 datalen, __u32 flash_ofs, __u32 *writelen)
-+struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode)
-
- {
-- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_raw_node_ref *raw;
- struct jffs2_full_dnode *fn;
-- ssize_t retlen;
-+ size_t retlen;
- struct iovec vecs[2];
- int ret;
-+ int retried = 0;
-+ unsigned long cnt = 2;
-
-- D1(if(ri->hdr_crc != crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)) {
-+ D1(if(je32_to_cpu(ri->hdr_crc) != crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)) {
- printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dnode()\n");
- BUG();
- }
-@@ -192,10 +107,10 @@
- vecs[1].iov_base = (unsigned char *)data;
- vecs[1].iov_len = datalen;
-
-- writecheck(c->mtd, flash_ofs);
-+ D1(writecheck(c, flash_ofs));
-
-- if (ri->totlen != sizeof(*ri) + datalen) {
-- printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08x) + datalen (0x%08x)\n", ri->totlen, sizeof(*ri), datalen);
-+ if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) {
-+ printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen);
- }
- raw = jffs2_alloc_raw_node_ref();
- if (!raw)
-@@ -206,19 +121,28 @@
- jffs2_free_raw_node_ref(raw);
- return ERR_PTR(-ENOMEM);
- }
-- raw->flash_offset = flash_ofs;
-- raw->totlen = PAD(ri->totlen);
-- raw->next_phys = NULL;
-
-- fn->ofs = ri->offset;
-- fn->size = ri->dsize;
-+ fn->ofs = je32_to_cpu(ri->offset);
-+ fn->size = je32_to_cpu(ri->dsize);
- fn->frags = 0;
-+
-+ /* check number of valid vecs */
-+ if (!datalen || !data)
-+ cnt = 1;
-+ retry:
- fn->raw = raw;
-
-- ret = mtd_writev(c->mtd, vecs, 2, flash_ofs, &retlen);
-+ raw->flash_offset = flash_ofs;
-+ raw->__totlen = PAD(sizeof(*ri)+datalen);
-+ raw->next_phys = NULL;
-+
-+ ret = jffs2_flash_writev(c, vecs, cnt, flash_ofs, &retlen,
-+ (alloc_mode==ALLOC_GC)?0:f->inocache->ino);
-+
- if (ret || (retlen != sizeof(*ri) + datalen)) {
-- printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %d\n",
-+ printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
- sizeof(*ri)+datalen, flash_ofs, ret, retlen);
-+
- /* Mark the space as dirtied */
- if (retlen) {
- /* Doesn't belong to any inode */
-@@ -229,48 +153,96 @@
- seem corrupted, in which case the scan would skip over
- any node we write before the original intended end of
- this node */
-- jffs2_add_physical_node_ref(c, raw, sizeof(*ri)+datalen, 1);
-+ raw->flash_offset |= REF_OBSOLETE;
-+ jffs2_add_physical_node_ref(c, raw);
- jffs2_mark_node_obsolete(c, raw);
- } else {
- printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset);
- jffs2_free_raw_node_ref(raw);
- }
-+ if (!retried && alloc_mode != ALLOC_NORETRY && (raw = jffs2_alloc_raw_node_ref())) {
-+ /* Try to reallocate space and retry */
-+ uint32_t dummy;
-+ struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size];
-+
-+ retried = 1;
-+
-+ D1(printk(KERN_DEBUG "Retrying failed write.\n"));
-+
-+ ACCT_SANITY_CHECK(c,jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+
-+ if (alloc_mode == ALLOC_GC) {
-+ ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, &dummy);
-+ } else {
-+ /* Locking pain */
-+ up(&f->sem);
-+ jffs2_complete_reservation(c);
-+
-+ ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs, &dummy, alloc_mode);
-+ down(&f->sem);
-+ }
-+
-+ if (!ret) {
-+ D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs));
-+
-+ ACCT_SANITY_CHECK(c,jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-
-+ goto retry;
-+ }
-+ D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
-+ jffs2_free_raw_node_ref(raw);
-+ }
- /* Release the full_dnode which is now useless, and return */
- jffs2_free_full_dnode(fn);
-- if (writelen)
-- *writelen = retlen;
- return ERR_PTR(ret?ret:-EIO);
- }
- /* Mark the space used */
-- jffs2_add_physical_node_ref(c, raw, retlen, 0);
-+ /* If node covers at least a whole page, or if it starts at the
-+ beginning of a page and runs to the end of the file, or if
-+ it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
-+ */
-+ if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) ||
-+ ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) &&
-+ (je32_to_cpu(ri->dsize)+je32_to_cpu(ri->offset) == je32_to_cpu(ri->isize)))) {
-+ raw->flash_offset |= REF_PRISTINE;
-+ } else {
-+ raw->flash_offset |= REF_NORMAL;
-+ }
-+ jffs2_add_physical_node_ref(c, raw);
-
- /* Link into per-inode list */
- raw->next_in_ino = f->inocache->nodes;
- f->inocache->nodes = raw;
-
-- D1(printk(KERN_DEBUG "jffs2_write_dnode wrote node at 0x%08x with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n", flash_ofs, ri->dsize, ri->csize, ri->node_crc, ri->data_crc, ri->totlen));
-- if (writelen)
-- *writelen = retlen;
-+ D1(printk(KERN_DEBUG "jffs2_write_dnode wrote node at 0x%08x(%d) with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n",
-+ flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize),
-+ je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc),
-+ je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen)));
-+
-+ if (retried) {
-+ ACCT_SANITY_CHECK(c,NULL);
-+ }
-
-- f->inocache->nodes = raw;
- return fn;
- }
-
--struct jffs2_full_dirent *jffs2_write_dirent(struct inode *inode, struct jffs2_raw_dirent *rd, const unsigned char *name, __u32 namelen, __u32 flash_ofs, __u32 *writelen)
-+struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_dirent *rd, const unsigned char *name, uint32_t namelen, uint32_t flash_ofs, int alloc_mode)
- {
-- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_raw_node_ref *raw;
- struct jffs2_full_dirent *fd;
-- ssize_t retlen;
-+ size_t retlen;
- struct iovec vecs[2];
-+ int retried = 0;
- int ret;
-
-- D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n", rd->pino, name, name, rd->ino, rd->name_crc));
-- writecheck(c->mtd, flash_ofs);
-+ D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n",
-+ je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino),
-+ je32_to_cpu(rd->name_crc)));
-+ D1(writecheck(c, flash_ofs));
-
-- D1(if(rd->hdr_crc != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) {
-+ D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) {
- printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n");
- BUG();
- }
-@@ -291,44 +263,414 @@
- jffs2_free_raw_node_ref(raw);
- return ERR_PTR(-ENOMEM);
- }
-- raw->flash_offset = flash_ofs;
-- raw->totlen = PAD(rd->totlen);
-- raw->next_in_ino = f->inocache->nodes;
-- f->inocache->nodes = raw;
-- raw->next_phys = NULL;
-
-- fd->version = rd->version;
-- fd->ino = rd->ino;
-+ fd->version = je32_to_cpu(rd->version);
-+ fd->ino = je32_to_cpu(rd->ino);
- fd->nhash = full_name_hash(name, strlen(name));
- fd->type = rd->type;
- memcpy(fd->name, name, namelen);
- fd->name[namelen]=0;
-+
-+ retry:
- fd->raw = raw;
-
-- ret = mtd_writev(c->mtd, vecs, 2, flash_ofs, &retlen);
-+ raw->flash_offset = flash_ofs;
-+ raw->__totlen = PAD(sizeof(*rd)+namelen);
-+ raw->next_phys = NULL;
-+
-+ ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen,
-+ (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino));
- if (ret || (retlen != sizeof(*rd) + namelen)) {
-- printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %d\n",
-+ printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
- sizeof(*rd)+namelen, flash_ofs, ret, retlen);
- /* Mark the space as dirtied */
- if (retlen) {
-- jffs2_add_physical_node_ref(c, raw, sizeof(*rd)+namelen, 1);
-+ raw->next_in_ino = NULL;
-+ raw->flash_offset |= REF_OBSOLETE;
-+ jffs2_add_physical_node_ref(c, raw);
- jffs2_mark_node_obsolete(c, raw);
- } else {
- printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset);
- jffs2_free_raw_node_ref(raw);
- }
-+ if (!retried && (raw = jffs2_alloc_raw_node_ref())) {
-+ /* Try to reallocate space and retry */
-+ uint32_t dummy;
-+ struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size];
-+
-+ retried = 1;
-+
-+ D1(printk(KERN_DEBUG "Retrying failed write.\n"));
-+
-+ ACCT_SANITY_CHECK(c,jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+
-+ if (alloc_mode == ALLOC_GC) {
-+ ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, &dummy);
-+ } else {
-+ /* Locking pain */
-+ up(&f->sem);
-+ jffs2_complete_reservation(c);
-+
-+ ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs, &dummy, alloc_mode);
-+ down(&f->sem);
-+ }
-
-+ if (!ret) {
-+ D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs));
-+ ACCT_SANITY_CHECK(c,jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+ goto retry;
-+ }
-+ D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
-+ jffs2_free_raw_node_ref(raw);
-+ }
- /* Release the full_dnode which is now useless, and return */
- jffs2_free_full_dirent(fd);
-- if (writelen)
-- *writelen = retlen;
- return ERR_PTR(ret?ret:-EIO);
- }
- /* Mark the space used */
-- jffs2_add_physical_node_ref(c, raw, retlen, 0);
-- if (writelen)
-- *writelen = retlen;
-+ raw->flash_offset |= REF_PRISTINE;
-+ jffs2_add_physical_node_ref(c, raw);
-
-+ raw->next_in_ino = f->inocache->nodes;
- f->inocache->nodes = raw;
-+
-+ if (retried) {
-+ ACCT_SANITY_CHECK(c,NULL);
-+ }
-+
- return fd;
- }
-+
-+/* The OS-specific code fills in the metadata in the jffs2_raw_inode for us, so that
-+ we don't have to go digging in struct inode or its equivalent. It should set:
-+ mode, uid, gid, (starting)isize, atime, ctime, mtime */
-+int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
-+ struct jffs2_raw_inode *ri, unsigned char *buf,
-+ uint32_t offset, uint32_t writelen, uint32_t *retlen)
-+{
-+ int ret = 0;
-+ uint32_t writtenlen = 0;
-+
-+ D1(printk(KERN_DEBUG "jffs2_write_inode_range(): Ino #%u, ofs 0x%x, len 0x%x\n",
-+ f->inocache->ino, offset, writelen));
-+
-+ while(writelen) {
-+ struct jffs2_full_dnode *fn;
-+ unsigned char *comprbuf = NULL;
-+ unsigned char comprtype = JFFS2_COMPR_NONE;
-+ uint32_t phys_ofs, alloclen;
-+ uint32_t datalen, cdatalen;
-+ int retried = 0;
-+
-+ retry:
-+ D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset));
-+
-+ ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL);
-+ if (ret) {
-+ D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret));
-+ break;
-+ }
-+ down(&f->sem);
-+ datalen = min_t(uint32_t, writelen, PAGE_CACHE_SIZE - (offset & (PAGE_CACHE_SIZE-1)));
-+ cdatalen = min_t(uint32_t, alloclen - sizeof(*ri), datalen);
-+
-+ comprtype = jffs2_compress(buf, &comprbuf, &datalen, &cdatalen);
-+
-+ ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
-+ ri->totlen = cpu_to_je32(sizeof(*ri) + cdatalen);
-+ ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
-+
-+ ri->ino = cpu_to_je32(f->inocache->ino);
-+ ri->version = cpu_to_je32(++f->highest_version);
-+ ri->isize = cpu_to_je32(max(je32_to_cpu(ri->isize), offset + datalen));
-+ ri->offset = cpu_to_je32(offset);
-+ ri->csize = cpu_to_je32(cdatalen);
-+ ri->dsize = cpu_to_je32(datalen);
-+ ri->compr = comprtype;
-+ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-+ ri->data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
-+
-+ fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, phys_ofs, ALLOC_NORETRY);
-+
-+ jffs2_free_comprbuf(comprbuf, buf);
-+
-+ if (IS_ERR(fn)) {
-+ ret = PTR_ERR(fn);
-+ up(&f->sem);
-+ jffs2_complete_reservation(c);
-+ if (!retried) {
-+ /* Write error to be retried */
-+ retried = 1;
-+ D1(printk(KERN_DEBUG "Retrying node write in jffs2_write_inode_range()\n"));
-+ goto retry;
-+ }
-+ break;
-+ }
-+ ret = jffs2_add_full_dnode_to_inode(c, f, fn);
-+ if (f->metadata) {
-+ jffs2_mark_node_obsolete(c, f->metadata->raw);
-+ jffs2_free_full_dnode(f->metadata);
-+ f->metadata = NULL;
-+ }
-+ if (ret) {
-+ /* Eep */
-+ D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n", ret));
-+ jffs2_mark_node_obsolete(c, fn->raw);
-+ jffs2_free_full_dnode(fn);
-+
-+ up(&f->sem);
-+ jffs2_complete_reservation(c);
-+ break;
-+ }
-+ up(&f->sem);
-+ jffs2_complete_reservation(c);
-+ if (!datalen) {
-+ printk(KERN_WARNING "Eep. We didn't actually write any data in jffs2_write_inode_range()\n");
-+ ret = -EIO;
-+ break;
-+ }
-+ D1(printk(KERN_DEBUG "increasing writtenlen by %d\n", datalen));
-+ writtenlen += datalen;
-+ offset += datalen;
-+ writelen -= datalen;
-+ buf += datalen;
-+ }
-+ *retlen = writtenlen;
-+ return ret;
-+}
-+
-+int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen)
-+{
-+ struct jffs2_raw_dirent *rd;
-+ struct jffs2_full_dnode *fn;
-+ struct jffs2_full_dirent *fd;
-+ uint32_t alloclen, phys_ofs;
-+ int ret;
-+
-+ /* Try to reserve enough space for both node and dirent.
-+ * Just the node will do for now, though
-+ */
-+ ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);
-+ D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen));
-+ if (ret) {
-+ up(&f->sem);
-+ return ret;
-+ }
-+
-+ ri->data_crc = cpu_to_je32(0);
-+ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-+
-+ fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
-+
-+ D1(printk(KERN_DEBUG "jffs2_do_create created file with mode 0x%x\n",
-+ jemode_to_cpu(ri->mode)));
-+
-+ if (IS_ERR(fn)) {
-+ D1(printk(KERN_DEBUG "jffs2_write_dnode() failed\n"));
-+ /* Eeek. Wave bye bye */
-+ up(&f->sem);
-+ jffs2_complete_reservation(c);
-+ return PTR_ERR(fn);
-+ }
-+ /* No data here. Only a metadata node, which will be
-+ obsoleted by the first data write
-+ */
-+ f->metadata = fn;
-+
-+ up(&f->sem);
-+ jffs2_complete_reservation(c);
-+ ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
-+
-+ if (ret) {
-+ /* Eep. */
-+ D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n"));
-+ return ret;
-+ }
-+
-+ rd = jffs2_alloc_raw_dirent();
-+ if (!rd) {
-+ /* Argh. Now we treat it like a normal delete */
-+ jffs2_complete_reservation(c);
-+ return -ENOMEM;
-+ }
-+
-+ down(&dir_f->sem);
-+
-+ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
-+ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
-+ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
-+
-+ rd->pino = cpu_to_je32(dir_f->inocache->ino);
-+ rd->version = cpu_to_je32(++dir_f->highest_version);
-+ rd->ino = ri->ino;
-+ rd->mctime = ri->ctime;
-+ rd->nsize = namelen;
-+ rd->type = DT_REG;
-+ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
-+ rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
-+
-+ fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL);
-+
-+ jffs2_free_raw_dirent(rd);
-+
-+ if (IS_ERR(fd)) {
-+ /* dirent failed to write. Delete the inode normally
-+ as if it were the final unlink() */
-+ jffs2_complete_reservation(c);
-+ up(&dir_f->sem);
-+ return PTR_ERR(fd);
-+ }
-+
-+ /* Link the fd into the inode's list, obsoleting an old
-+ one if necessary. */
-+ jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-+
-+ jffs2_complete_reservation(c);
-+ up(&dir_f->sem);
-+
-+ return 0;
-+}
-+
-+
-+int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
-+ const char *name, int namelen, struct jffs2_inode_info *dead_f)
-+{
-+ struct jffs2_raw_dirent *rd;
-+ struct jffs2_full_dirent *fd;
-+ uint32_t alloclen, phys_ofs;
-+ int ret;
-+
-+ rd = jffs2_alloc_raw_dirent();
-+ if (!rd)
-+ return -ENOMEM;
-+
-+ ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_DELETION);
-+ if (ret) {
-+ jffs2_free_raw_dirent(rd);
-+ return ret;
-+ }
-+
-+ down(&dir_f->sem);
-+
-+ /* Build a deletion node */
-+ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
-+ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
-+ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
-+
-+ rd->pino = cpu_to_je32(dir_f->inocache->ino);
-+ rd->version = cpu_to_je32(++dir_f->highest_version);
-+ rd->ino = cpu_to_je32(0);
-+ rd->mctime = cpu_to_je32(get_seconds());
-+ rd->nsize = namelen;
-+ rd->type = DT_UNKNOWN;
-+ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
-+ rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
-+
-+ fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_DELETION);
-+
-+ jffs2_free_raw_dirent(rd);
-+
-+ if (IS_ERR(fd)) {
-+ jffs2_complete_reservation(c);
-+ up(&dir_f->sem);
-+ return PTR_ERR(fd);
-+ }
-+
-+ /* File it. This will mark the old one obsolete. */
-+ jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-+
-+ up(&dir_f->sem);
-+
-+ /* dead_f is NULL if this was a rename not a real unlink */
-+ /* Also catch the !f->inocache case, where there was a dirent
-+ pointing to an inode which didn't exist. */
-+ if (dead_f && dead_f->inocache) {
-+
-+ down(&dead_f->sem);
-+
-+ while (dead_f->dents) {
-+ /* There can be only deleted ones */
-+ fd = dead_f->dents;
-+
-+ dead_f->dents = fd->next;
-+
-+ if (fd->ino) {
-+ printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n",
-+ dead_f->inocache->ino, fd->name, fd->ino);
-+ } else {
-+ D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", fd->name, dead_f->inocache->ino));
-+ }
-+ jffs2_mark_node_obsolete(c, fd->raw);
-+ jffs2_free_full_dirent(fd);
-+ }
-+
-+ dead_f->inocache->nlink--;
-+ /* NB: Caller must set inode nlink if appropriate */
-+ up(&dead_f->sem);
-+ }
-+
-+ jffs2_complete_reservation(c);
-+
-+ return 0;
-+}
-+
-+
-+int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen)
-+{
-+ struct jffs2_raw_dirent *rd;
-+ struct jffs2_full_dirent *fd;
-+ uint32_t alloclen, phys_ofs;
-+ int ret;
-+
-+ rd = jffs2_alloc_raw_dirent();
-+ if (!rd)
-+ return -ENOMEM;
-+
-+ ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
-+ if (ret) {
-+ jffs2_free_raw_dirent(rd);
-+ return ret;
-+ }
-+
-+ down(&dir_f->sem);
-+
-+ /* Build a deletion node */
-+ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
-+ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
-+ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
-+
-+ rd->pino = cpu_to_je32(dir_f->inocache->ino);
-+ rd->version = cpu_to_je32(++dir_f->highest_version);
-+ rd->ino = cpu_to_je32(ino);
-+ rd->mctime = cpu_to_je32(get_seconds());
-+ rd->nsize = namelen;
-+
-+ rd->type = type;
-+
-+ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
-+ rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
-+
-+ fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL);
-+
-+ jffs2_free_raw_dirent(rd);
-+
-+ if (IS_ERR(fd)) {
-+ jffs2_complete_reservation(c);
-+ up(&dir_f->sem);
-+ return PTR_ERR(fd);
-+ }
-+
-+ /* File it. This will mark the old one obsolete. */
-+ jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-+
-+ jffs2_complete_reservation(c);
-+ up(&dir_f->sem);
-+
-+ return 0;
-+}
-diff -Nurb linux-mips-2.4.24-pre2/fs/jffs2/writev.c linux/fs/jffs2/writev.c
---- linux-mips-2.4.24-pre2/fs/jffs2/writev.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/jffs2/writev.c 2004-11-17 18:17:59.413257072 +0100
-@@ -0,0 +1,50 @@
-+/*
-+ * JFFS2 -- Journalling Flash File System, Version 2.
-+ *
-+ * Copyright (C) 2001, 2002 Red Hat, Inc.
-+ *
-+ * Created by David Woodhouse <dwmw2@redhat.com>
-+ *
-+ * For licensing information, see the file 'LICENCE' in this directory.
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/mtd/mtd.h>
-+#include "nodelist.h"
-+
-+/* This ought to be in core MTD code. All registered MTD devices
-+ without writev should have this put in place. Bug the MTD
-+ maintainer */
-+static inline int mtd_fake_writev(struct mtd_info *mtd, const struct iovec *vecs,
-+ unsigned long count, loff_t to, size_t *retlen)
-+{
-+ unsigned long i;
-+ size_t totlen = 0, thislen;
-+ int ret = 0;
-+
-+ for (i=0; i<count; i++) {
-+ if (!vecs[i].iov_len)
-+ continue;
-+ ret = mtd->write(mtd, to, vecs[i].iov_len, &thislen, vecs[i].iov_base);
-+ totlen += thislen;
-+ if (ret || thislen != vecs[i].iov_len)
-+ break;
-+ to += vecs[i].iov_len;
-+ }
-+ if (retlen)
-+ *retlen = totlen;
-+ return ret;
-+}
-+
-+int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct iovec *vecs,
-+ unsigned long count, loff_t to, size_t *retlen)
-+{
-+ if (c->mtd->writev)
-+ return c->mtd->writev(c->mtd, vecs, count, to, retlen);
-+ else
-+ return mtd_fake_writev(c->mtd, vecs, count, to, retlen);
-+}
-+
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/jffs2.h linux/include/linux/jffs2.h
---- linux-mips-2.4.24-pre2/include/linux/jffs2.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/jffs2.h 2004-11-17 18:17:59.000000000 +0100
-@@ -1,50 +1,30 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in the
-+ * jffs2 directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #ifndef __LINUX_JFFS2_H__
- #define __LINUX_JFFS2_H__
-
--#include <asm/types.h>
-+/* You must include something which defines the C99 uintXX_t types.
-+ We don't do it from here because this file is used in too many
-+ different environments. */
-+
- #define JFFS2_SUPER_MAGIC 0x72b6
-
- /* Values we may expect to find in the 'magic' field */
- #define JFFS2_OLD_MAGIC_BITMASK 0x1984
- #define JFFS2_MAGIC_BITMASK 0x1985
--#define KSAMTIB_CIGAM_2SFFJ 0x5981 /* For detecting wrong-endian fs */
-+#define KSAMTIB_CIGAM_2SFFJ 0x8519 /* For detecting wrong-endian fs */
- #define JFFS2_EMPTY_BITMASK 0xffff
- #define JFFS2_DIRTY_BITMASK 0x0000
-
-@@ -78,16 +58,12 @@
- #define JFFS2_NODETYPE_DIRENT (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 1)
- #define JFFS2_NODETYPE_INODE (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 2)
- #define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3)
-+#define JFFS2_NODETYPE_PADDING (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 4)
-
- // Maybe later...
- //#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3)
- //#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4)
-
--/* Same as the non_ECC versions, but with extra space for real
-- * ECC instead of just the checksum. For use on NAND flash
-- */
--//#define JFFS2_NODETYPE_DIRENT_ECC (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 5)
--//#define JFFS2_NODETYPE_INODE_ECC (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 6)
-
- #define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at
- mount time, don't wait for it to
-@@ -96,31 +72,79 @@
- compression type */
-
-
-+/* These can go once we've made sure we've caught all uses without
-+ byteswapping */
-+
-+typedef struct {
-+ uint32_t v32;
-+} __attribute__((packed)) jint32_t;
-+
-+typedef struct {
-+ uint32_t m;
-+} __attribute__((packed)) jmode_t;
-+
-+typedef struct {
-+ uint16_t v16;
-+} __attribute__((packed)) jint16_t;
-+
-+#define JFFS2_NATIVE_ENDIAN
-+
-+/* Note we handle mode bits conversion from JFFS2 (i.e. Linux) to/from
-+ whatever OS we're actually running on here too. */
-+
-+#if defined(JFFS2_NATIVE_ENDIAN)
-+#define cpu_to_je16(x) ((jint16_t){x})
-+#define cpu_to_je32(x) ((jint32_t){x})
-+#define cpu_to_jemode(x) ((jmode_t){os_to_jffs2_mode(x)})
-+
-+#define je16_to_cpu(x) ((x).v16)
-+#define je32_to_cpu(x) ((x).v32)
-+#define jemode_to_cpu(x) (jffs2_to_os_mode((x).m))
-+#elif defined(JFFS2_BIG_ENDIAN)
-+#define cpu_to_je16(x) ((jint16_t){cpu_to_be16(x)})
-+#define cpu_to_je32(x) ((jint32_t){cpu_to_be32(x)})
-+#define cpu_to_jemode(x) ((jmode_t){cpu_to_be32(os_to_jffs2_mode(x))})
-+
-+#define je16_to_cpu(x) (be16_to_cpu(x.v16))
-+#define je32_to_cpu(x) (be32_to_cpu(x.v32))
-+#define jemode_to_cpu(x) (be32_to_cpu(jffs2_to_os_mode((x).m)))
-+#elif defined(JFFS2_LITTLE_ENDIAN)
-+#define cpu_to_je16(x) ((jint16_t){cpu_to_le16(x)})
-+#define cpu_to_je32(x) ((jint32_t){cpu_to_le32(x)})
-+#define cpu_to_jemode(x) ((jmode_t){cpu_to_le32(os_to_jffs2_mode(x))})
-+
-+#define je16_to_cpu(x) (le16_to_cpu(x.v16))
-+#define je32_to_cpu(x) (le32_to_cpu(x.v32))
-+#define jemode_to_cpu(x) (le32_to_cpu(jffs2_to_os_mode((x).m)))
-+#else
-+#error wibble
-+#endif
-+
- struct jffs2_unknown_node
- {
- /* All start like this */
-- __u16 magic;
-- __u16 nodetype;
-- __u32 totlen; /* So we can skip over nodes we don't grok */
-- __u32 hdr_crc;
-+ jint16_t magic;
-+ jint16_t nodetype;
-+ jint32_t totlen; /* So we can skip over nodes we don't grok */
-+ jint32_t hdr_crc;
- } __attribute__((packed));
-
- struct jffs2_raw_dirent
- {
-- __u16 magic;
-- __u16 nodetype; /* == JFFS_NODETYPE_DIRENT */
-- __u32 totlen;
-- __u32 hdr_crc;
-- __u32 pino;
-- __u32 version;
-- __u32 ino; /* == zero for unlink */
-- __u32 mctime;
-- __u8 nsize;
-- __u8 type;
-- __u8 unused[2];
-- __u32 node_crc;
-- __u32 name_crc;
-- __u8 name[0];
-+ jint16_t magic;
-+ jint16_t nodetype; /* == JFFS_NODETYPE_DIRENT */
-+ jint32_t totlen;
-+ jint32_t hdr_crc;
-+ jint32_t pino;
-+ jint32_t version;
-+ jint32_t ino; /* == zero for unlink */
-+ jint32_t mctime;
-+ uint8_t nsize;
-+ uint8_t type;
-+ uint8_t unused[2];
-+ jint32_t node_crc;
-+ jint32_t name_crc;
-+ uint8_t name[0];
- } __attribute__((packed));
-
- /* The JFFS2 raw inode structure: Used for storage on physical media. */
-@@ -131,28 +155,28 @@
- */
- struct jffs2_raw_inode
- {
-- __u16 magic; /* A constant magic number. */
-- __u16 nodetype; /* == JFFS_NODETYPE_INODE */
-- __u32 totlen; /* Total length of this node (inc data, etc.) */
-- __u32 hdr_crc;
-- __u32 ino; /* Inode number. */
-- __u32 version; /* Version number. */
-- __u32 mode; /* The file's type or mode. */
-- __u16 uid; /* The file's owner. */
-- __u16 gid; /* The file's group. */
-- __u32 isize; /* Total resultant size of this inode (used for truncations) */
-- __u32 atime; /* Last access time. */
-- __u32 mtime; /* Last modification time. */
-- __u32 ctime; /* Change time. */
-- __u32 offset; /* Where to begin to write. */
-- __u32 csize; /* (Compressed) data size */
-- __u32 dsize; /* Size of the node's data. (after decompression) */
-- __u8 compr; /* Compression algorithm used */
-- __u8 usercompr; /* Compression algorithm requested by the user */
-- __u16 flags; /* See JFFS2_INO_FLAG_* */
-- __u32 data_crc; /* CRC for the (compressed) data. */
-- __u32 node_crc; /* CRC for the raw inode (excluding data) */
--// __u8 data[dsize];
-+ jint16_t magic; /* A constant magic number. */
-+ jint16_t nodetype; /* == JFFS_NODETYPE_INODE */
-+ jint32_t totlen; /* Total length of this node (inc data, etc.) */
-+ jint32_t hdr_crc;
-+ jint32_t ino; /* Inode number. */
-+ jint32_t version; /* Version number. */
-+ jmode_t mode; /* The file's type or mode. */
-+ jint16_t uid; /* The file's owner. */
-+ jint16_t gid; /* The file's group. */
-+ jint32_t isize; /* Total resultant size of this inode (used for truncations) */
-+ jint32_t atime; /* Last access time. */
-+ jint32_t mtime; /* Last modification time. */
-+ jint32_t ctime; /* Change time. */
-+ jint32_t offset; /* Where to begin to write. */
-+ jint32_t csize; /* (Compressed) data size */
-+ jint32_t dsize; /* Size of the node's data. (after decompression) */
-+ uint8_t compr; /* Compression algorithm used */
-+ uint8_t usercompr; /* Compression algorithm requested by the user */
-+ jint16_t flags; /* See JFFS2_INO_FLAG_* */
-+ jint32_t data_crc; /* CRC for the (compressed) data. */
-+ jint32_t node_crc; /* CRC for the raw inode (excluding data) */
-+ uint8_t data[0];
- } __attribute__((packed));
-
- union jffs2_node_union {
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/jffs2_fs_i.h linux/include/linux/jffs2_fs_i.h
---- linux-mips-2.4.24-pre2/include/linux/jffs2_fs_i.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/jffs2_fs_i.h 2004-11-17 18:17:59.000000000 +0100
-@@ -1,22 +1,12 @@
--/* $Id$ */
-+/* $Id$ */
-
- #ifndef _JFFS2_FS_I
- #define _JFFS2_FS_I
-
--/* Include the pipe_inode_info at the beginning so that we can still
-- use the storage space in the inode when we have a pipe inode.
-- This sucks.
--*/
--
--#undef THISSUCKS /* Only for 2.2 */
--#ifdef THISSUCKS
--#include <linux/pipe_fs_i.h>
--#endif
-+#include <linux/version.h>
-+#include <linux/rbtree.h>
-
- struct jffs2_inode_info {
--#ifdef THISSUCKS
-- struct pipe_inode_info pipecrap;
--#endif
- /* We need an internal semaphore similar to inode->i_sem.
- Unfortunately, we can't used the existing one, because
- either the GC would deadlock, or we'd have to release it
-@@ -26,10 +16,10 @@
- struct semaphore sem;
-
- /* The highest (datanode) version number used for this ino */
-- __u32 highest_version;
-+ uint32_t highest_version;
-
- /* List of data fragments which make up the file */
-- struct jffs2_node_frag *fraglist;
-+ struct rb_root fragtree;
-
- /* There may be one datanode which isn't referenced by any of the
- above fragments, if it contains a metadata update but no actual
-@@ -44,19 +34,13 @@
- /* Some stuff we just have to keep in-core at all times, for each inode. */
- struct jffs2_inode_cache *inocache;
-
-- /* Keep a pointer to the last physical node in the list. We don't
-- use the doubly-linked lists because we don't want to increase
-- the memory usage that much. This is simpler */
-- // struct jffs2_raw_node_ref *lastnode;
-- __u16 flags;
-- __u8 usercompr;
--};
--
--#ifdef JFFS2_OUT_OF_KERNEL
--#define JFFS2_INODE_INFO(i) ((struct jffs2_inode_info *) &(i)->u)
--#else
--#define JFFS2_INODE_INFO(i) (&i->u.jffs2_i)
-+ uint16_t flags;
-+ uint8_t usercompr;
-+#if !defined (__ECOS)
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
-+ struct inode vfs_inode;
- #endif
-+#endif
-+};
-
- #endif /* _JFFS2_FS_I */
--
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/jffs2_fs_sb.h linux/include/linux/jffs2_fs_sb.h
---- linux-mips-2.4.24-pre2/include/linux/jffs2_fs_sb.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/jffs2_fs_sb.h 2004-11-17 18:17:59.000000000 +0100
-@@ -1,19 +1,22 @@
--/* $Id$ */
-+/* $Id$ */
-
- #ifndef _JFFS2_FS_SB
- #define _JFFS2_FS_SB
-
- #include <linux/types.h>
- #include <linux/spinlock.h>
-+#include <linux/workqueue.h>
- #include <linux/completion.h>
- #include <asm/semaphore.h>
-+#include <linux/timer.h>
-+#include <linux/wait.h>
- #include <linux/list.h>
-
--#define INOCACHE_HASHSIZE 1
--
- #define JFFS2_SB_FLAG_RO 1
- #define JFFS2_SB_FLAG_MOUNTING 2
-
-+struct jffs2_inodirty;
-+
- /* A struct for the overall file system control. Pointers to
- jffs2_sb_info structs are named `c' in the source code.
- Nee jffs_control
-@@ -21,36 +24,46 @@
- struct jffs2_sb_info {
- struct mtd_info *mtd;
-
-- __u32 highest_ino;
-+ uint32_t highest_ino;
-+ uint32_t checked_ino;
-+
- unsigned int flags;
-- spinlock_t nodelist_lock;
-
-- // pid_t thread_pid; /* GC thread's PID */
- struct task_struct *gc_task; /* GC task struct */
- struct semaphore gc_thread_start; /* GC thread start mutex */
- struct completion gc_thread_exit; /* GC thread exit completion port */
-- // __u32 gc_minfree_threshold; /* GC trigger thresholds */
-- // __u32 gc_maxdirty_threshold;
-
- struct semaphore alloc_sem; /* Used to protect all the following
- fields, and also to protect against
- out-of-order writing of nodes.
- And GC.
- */
-- __u32 flash_size;
-- __u32 used_size;
-- __u32 dirty_size;
-- __u32 free_size;
-- __u32 erasing_size;
-- __u32 bad_size;
-- __u32 sector_size;
-- // __u32 min_free_size;
-- // __u32 max_chunk_size;
-+ uint32_t cleanmarker_size; /* Size of an _inline_ CLEANMARKER
-+ (i.e. zero for OOB CLEANMARKER */
-+
-+ uint32_t flash_size;
-+ uint32_t used_size;
-+ uint32_t dirty_size;
-+ uint32_t wasted_size;
-+ uint32_t free_size;
-+ uint32_t erasing_size;
-+ uint32_t bad_size;
-+ uint32_t sector_size;
-+ uint32_t unchecked_size;
-+
-+ uint32_t nr_free_blocks;
-+ uint32_t nr_erasing_blocks;
-+
-+ /* Number of free blocks there must be before we... */
-+ uint8_t resv_blocks_write; /* ... allow a normal filesystem write */
-+ uint8_t resv_blocks_deletion; /* ... allow a normal filesystem deletion */
-+ uint8_t resv_blocks_gctrigger; /* ... wake up the GC thread */
-+ uint8_t resv_blocks_gcbad; /* ... pick a block from the bad_list to GC */
-+ uint8_t resv_blocks_gcmerge; /* ... merge pages when garbage collecting */
-
-- __u32 nr_free_blocks;
-- __u32 nr_erasing_blocks;
-+ uint32_t nospc_dirty_size;
-
-- __u32 nr_blocks;
-+ uint32_t nr_blocks;
- struct jffs2_eraseblock *blocks; /* The whole array of blocks. Used for getting blocks
- * from the offset (blocks[ofs / sector_size]) */
- struct jffs2_eraseblock *nextblock; /* The block we're currently filling */
-@@ -58,9 +71,12 @@
- struct jffs2_eraseblock *gcblock; /* The block we're currently garbage-collecting */
-
- struct list_head clean_list; /* Blocks 100% full of clean data */
-+ struct list_head very_dirty_list; /* Blocks with lots of dirty space */
- struct list_head dirty_list; /* Blocks with some dirty space */
-+ struct list_head erasable_list; /* Blocks which are completely dirty, and need erasing */
-+ struct list_head erasable_pending_wbuf_list; /* Blocks which need erasing but only after the current wbuf is flushed */
- struct list_head erasing_list; /* Blocks which are currently erasing */
-- struct list_head erase_pending_list; /* Blocks which need erasing */
-+ struct list_head erase_pending_list; /* Blocks which need erasing now */
- struct list_head erase_complete_list; /* Blocks which are erased and need the clean marker written to them */
- struct list_head free_list; /* Blocks which are free and ready to be used */
- struct list_head bad_list; /* Bad blocks. */
-@@ -69,16 +85,33 @@
- spinlock_t erase_completion_lock; /* Protect free_list and erasing_list
- against erase completion handler */
- wait_queue_head_t erase_wait; /* For waiting for erases to complete */
-- struct jffs2_inode_cache *inocache_list[INOCACHE_HASHSIZE];
-+
-+ wait_queue_head_t inocache_wq;
-+ struct jffs2_inode_cache **inocache_list;
- spinlock_t inocache_lock;
--};
-
--#ifdef JFFS2_OUT_OF_KERNEL
--#define JFFS2_SB_INFO(sb) ((struct jffs2_sb_info *) &(sb)->u)
--#else
--#define JFFS2_SB_INFO(sb) (&sb->u.jffs2_sb)
-+ /* Sem to allow jffs2_garbage_collect_deletion_dirent to
-+ drop the erase_completion_lock while it's holding a pointer
-+ to an obsoleted node. I don't like this. Alternatives welcomed. */
-+ struct semaphore erase_free_sem;
-+
-+#ifdef CONFIG_JFFS2_FS_NAND
-+ /* Write-behind buffer for NAND flash */
-+ unsigned char *wbuf;
-+ uint32_t wbuf_ofs;
-+ uint32_t wbuf_len;
-+ uint32_t wbuf_pagesize;
-+ struct jffs2_inodirty *wbuf_inodes;
-+
-+ /* Information about out-of-band area usage... */
-+ struct nand_oobinfo *oobinfo;
-+ uint32_t badblock_pos;
-+ uint32_t fsdata_pos;
-+ uint32_t fsdata_len;
- #endif
-
--#define OFNI_BS_2SFFJ(c) ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->u)) ) )
-+ /* OS-private pointer for getting back to master superblock info */
-+ void *os_priv;
-+};
-
- #endif /* _JFFS2_FB_SB */
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/mtd/blktrans.h linux/include/linux/mtd/blktrans.h
---- linux-mips-2.4.24-pre2/include/linux/mtd/blktrans.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/include/linux/mtd/blktrans.h 2004-11-17 18:17:59.205288688 +0100
-@@ -0,0 +1,72 @@
-+/*
-+ * $Id$
-+ *
-+ * (C) 2003 David Woodhouse <dwmw2@infradead.org>
-+ *
-+ * Interface to Linux block layer for MTD 'translation layers'.
-+ *
-+ */
-+
-+#ifndef __MTD_TRANS_H__
-+#define __MTD_TRANS_H__
-+
-+#include <asm/semaphore.h>
-+
-+struct hd_geometry;
-+struct mtd_info;
-+struct mtd_blktrans_ops;
-+struct file;
-+struct inode;
-+
-+struct mtd_blktrans_dev {
-+ struct mtd_blktrans_ops *tr;
-+ struct list_head list;
-+ struct mtd_info *mtd;
-+ struct semaphore sem;
-+ int devnum;
-+ int blksize;
-+ unsigned long size;
-+ int readonly;
-+ void *blkcore_priv; /* gendisk in 2.5, devfs_handle in 2.4 */
-+};
-+
-+struct blkcore_priv; /* Differs for 2.4 and 2.5 kernels; private */
-+
-+struct mtd_blktrans_ops {
-+ char *name;
-+ int major;
-+ int part_bits;
-+
-+ /* Access functions */
-+ int (*readsect)(struct mtd_blktrans_dev *dev,
-+ unsigned long block, char *buffer);
-+ int (*writesect)(struct mtd_blktrans_dev *dev,
-+ unsigned long block, char *buffer);
-+
-+ /* Block layer ioctls */
-+ int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo);
-+ int (*flush)(struct mtd_blktrans_dev *dev);
-+
-+ /* Called with mtd_table_mutex held; no race with add/remove */
-+ int (*open)(struct mtd_blktrans_dev *dev);
-+ int (*release)(struct mtd_blktrans_dev *dev);
-+
-+ /* Called on {de,}registration and on subsequent addition/removal
-+ of devices, with mtd_table_mutex held. */
-+ void (*add_mtd)(struct mtd_blktrans_ops *tr, struct mtd_info *mtd);
-+ void (*remove_dev)(struct mtd_blktrans_dev *dev);
-+
-+ struct list_head devs;
-+ struct list_head list;
-+ struct module *owner;
-+
-+ struct mtd_blkcore_priv *blkcore_priv;
-+};
-+
-+extern int register_mtd_blktrans(struct mtd_blktrans_ops *tr);
-+extern int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr);
-+extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
-+extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
-+
-+
-+#endif /* __MTD_TRANS_H__ */
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/mtd/cfi.h linux/include/linux/mtd/cfi.h
---- linux-mips-2.4.24-pre2/include/linux/mtd/cfi.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/mtd/cfi.h 2004-11-17 18:17:59.207288384 +0100
-@@ -1,13 +1,14 @@
-
- /* Common Flash Interface structures
- * See http://support.intel.com/design/flash/technote/index.htm
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __MTD_CFI_H__
- #define __MTD_CFI_H__
-
- #include <linux/config.h>
-+#include <linux/version.h>
- #include <linux/delay.h>
- #include <linux/types.h>
- #include <linux/interrupt.h>
-@@ -260,7 +261,8 @@
- __u8 pri[3];
- __u8 MajorVersion;
- __u8 MinorVersion;
-- __u32 FeatureSupport;
-+ __u32 FeatureSupport; /* if bit 31 is set then an additional __u32 feature
-+ block follows - FIXME - not currently supported */
- __u8 SuspendCmdSupport;
- __u16 BlkStatusRegMask;
- __u8 VccOptimal;
-@@ -271,6 +273,25 @@
- __u8 UserProtRegSize;
- } __attribute__((packed));
-
-+/* Vendor-Specific PRI for AMD/Fujitsu Extended Command Set (0x0002) */
-+
-+struct cfi_pri_amdstd {
-+ __u8 pri[3];
-+ __u8 MajorVersion;
-+ __u8 MinorVersion;
-+ __u8 SiliconRevision; /* bits 1-0: Address Sensitive Unlock */
-+ __u8 EraseSuspend;
-+ __u8 BlkProt;
-+ __u8 TmpBlkUnprotect;
-+ __u8 BlkProtUnprot;
-+ __u8 SimultaneousOps;
-+ __u8 BurstMode;
-+ __u8 PageMode;
-+ __u8 VppMin;
-+ __u8 VppMax;
-+ __u8 TopBottom;
-+} __attribute__((packed));
-+
- struct cfi_pri_query {
- __u8 NumFields;
- __u32 ProtField[1]; /* Not host ordered */
-@@ -314,8 +335,6 @@
- struct flchip chips[0]; /* per-chip data structure for each chip */
- };
-
--#define MAX_CFI_CHIPS 8 /* Entirely arbitrary to avoid realloc() */
--
- /*
- * Returns the command address according to the given geometry.
- */
-@@ -387,13 +406,13 @@
- static inline cfi_word cfi_read(struct map_info *map, __u32 addr)
- {
- if (cfi_buswidth_is_1()) {
-- return map->read8(map, addr);
-+ return map_read8(map, addr);
- } else if (cfi_buswidth_is_2()) {
-- return map->read16(map, addr);
-+ return map_read16(map, addr);
- } else if (cfi_buswidth_is_4()) {
-- return map->read32(map, addr);
-+ return map_read32(map, addr);
- } else if (cfi_buswidth_is_8()) {
-- return map->read64(map, addr);
-+ return map_read64(map, addr);
- } else {
- return 0;
- }
-@@ -406,13 +425,13 @@
- static inline void cfi_write(struct map_info *map, cfi_word val, __u32 addr)
- {
- if (cfi_buswidth_is_1()) {
-- map->write8(map, val, addr);
-+ map_write8(map, val, addr);
- } else if (cfi_buswidth_is_2()) {
-- map->write16(map, val, addr);
-+ map_write16(map, val, addr);
- } else if (cfi_buswidth_is_4()) {
-- map->write32(map, val, addr);
-+ map_write32(map, val, addr);
- } else if (cfi_buswidth_is_8()) {
-- map->write64(map, val, addr);
-+ map_write64(map, val, addr);
- }
- }
-
-@@ -443,13 +462,13 @@
- static inline __u8 cfi_read_query(struct map_info *map, __u32 addr)
- {
- if (cfi_buswidth_is_1()) {
-- return map->read8(map, addr);
-+ return map_read8(map, addr);
- } else if (cfi_buswidth_is_2()) {
-- return cfi16_to_cpu(map->read16(map, addr));
-+ return cfi16_to_cpu(map_read16(map, addr));
- } else if (cfi_buswidth_is_4()) {
-- return cfi32_to_cpu(map->read32(map, addr));
-+ return cfi32_to_cpu(map_read32(map, addr));
- } else if (cfi_buswidth_is_8()) {
-- return cfi64_to_cpu(map->read64(map, addr));
-+ return cfi64_to_cpu(map_read64(map, addr));
- } else {
- return 0;
- }
-@@ -479,5 +498,19 @@
- spin_unlock_bh(mutex);
- }
-
-+struct cfi_extquery *cfi_read_pri(struct map_info *map, __u16 adr, __u16 size,
-+ const char* name);
-+
-+struct cfi_fixup {
-+ __u16 mfr;
-+ __u16 id;
-+ void (*fixup)(struct map_info *map, void* param);
-+ void* param;
-+};
-+
-+#define CFI_MFR_ANY 0xffff
-+#define CFI_ID_ANY 0xffff
-+
-+void cfi_fixup(struct map_info *map, struct cfi_fixup* fixups);
-
- #endif /* __MTD_CFI_H__ */
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/mtd/compatmac.h linux/include/linux/mtd/compatmac.h
---- linux-mips-2.4.24-pre2/include/linux/mtd/compatmac.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/mtd/compatmac.h 2004-11-17 18:17:59.210287928 +0100
-@@ -1,573 +1,152 @@
--
- /*
-- * mtd/include/compatmac.h
-- *
-- * $Id$
-+ * $Id$
- *
- * Extensions and omissions from the normal 'linux/compatmac.h'
- * files. hopefully this will end up empty as the 'real' one
- * becomes fully-featured.
- */
-
--
--/* First, include the parts which the kernel is good enough to provide
-- * to us
-- */
--
- #ifndef __LINUX_MTD_COMPATMAC_H__
- #define __LINUX_MTD_COMPATMAC_H__
-
--#include <linux/config.h>
--#include <linux/module.h>
--#ifndef LINUX_VERSION_CODE
- #include <linux/version.h>
--#endif
--
--#ifndef VERSION_CODE
--# define VERSION_CODE(vers,rel,seq) ( ((vers)<<16) | ((rel)<<8) | (seq) )
--#endif
--#ifndef KERNEL_VERSION
--# define KERNEL_VERSION(a,b,c) VERSION_CODE(a,b,c)
--#endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,0,0)
--# error "This kernel is too old: not supported by this file"
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
--#include <linux/types.h> /* used later in this header */
--
--#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
--#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
--
--typedef struct wait_queue * wait_queue_head_t;
--
--#define DECLARE_WAITQUEUE(x,y) struct wait_queue x = {y,NULL}
--#define DECLARE_WAIT_QUEUE_HEAD(x) struct wait_queue *x = NULL
--#define init_waitqueue_head init_waitqueue
--#define DECLARE_MUTEX(x) struct semaphore x = MUTEX
--#define DECLARE_MUTEX_LOCKED(x) struct semaphore x = MUTEX_LOCKED
--
--/* from sysdep-2.1.h */
--# include <asm/segment.h>
--# define access_ok(t,a,sz) (verify_area((t),(a),(sz)) ? 0 : 1)
--# define verify_area_20 verify_area
--# define copy_to_user(t,f,n) (memcpy_tofs(t,f,n), 0)
--# define __copy_to_user(t,f,n) copy_to_user((t),(f),(n))
--# define copy_to_user_ret(t,f,n,r) copy_to_user((t),(f),(n))
--# define copy_from_user(t,f,n) (memcpy_fromfs((t),(f),(n)), 0)
--# define __copy_from_user(t,f,n) copy_from_user((t),(f),(n))
--# define copy_from_user_ret(t,f,n,r) copy_from_user((t),(f),(n))
--//xxx # define PUT_USER(val,add) (put_user((val),(add)), 0)
--# define Put_user(val,add) (put_user((val),(add)), 0)
--# define __PUT_USER(val,add) PUT_USER((val),(add))
--# define PUT_USER_RET(val,add,ret) PUT_USER((val),(add))
--# define GET_USER(dest,add) ((dest)=get_user((add)), 0)
--# define __GET_USER(dest,add) GET_USER((dest),(add))
--# define GET_USER_RET(dest,add,ret) GET_USER((dest),(add))
--
--#define ioremap(offset,size) vremap(offset,size)
--#define iounmap(adr) /* */
--
--#define EXPORT_SYMBOL(s) /* */
--#define EXPORT_SYMBOL_NOVERS(s) /* */
--
--/* 2.1.10 and 2.1.43 introduced new functions. They are worth using */
--
--#if LINUX_VERSION_CODE < VERSION_CODE(2,1,10)
--
--# include <asm/byteorder.h>
--# ifdef __LITTLE_ENDIAN
--# define cpu_to_le16(x) (x)
--# define cpu_to_le32(x) (x)
--# define cpu_to_be16(x) htons((x))
--# define cpu_to_be32(x) htonl((x))
--# else
--# define cpu_to_be16(x) (x)
--# define cpu_to_be32(x) (x)
-- extern inline __u16 cpu_to_le16(__u16 x) { return (x<<8) | (x>>8);}
-- extern inline __u32 cpu_to_le32(__u32 x) { return((x>>24) |
-- ((x>>8)&0xff00) | ((x<<8)&0xff0000) | (x<<24));}
--# endif
--
--# define le16_to_cpu(x) cpu_to_le16(x)
--# define le32_to_cpu(x) cpu_to_le32(x)
--# define be16_to_cpu(x) cpu_to_be16(x)
--# define be32_to_cpu(x) cpu_to_be32(x)
--
--#endif
--
--#if LINUX_VERSION_CODE < VERSION_CODE(2,1,43)
--# define cpu_to_le16p(addr) (cpu_to_le16(*(addr)))
--# define cpu_to_le32p(addr) (cpu_to_le32(*(addr)))
--# define cpu_to_be16p(addr) (cpu_to_be16(*(addr)))
--# define cpu_to_be32p(addr) (cpu_to_be32(*(addr)))
--
-- extern inline void cpu_to_le16s(__u16 *a) {*a = cpu_to_le16(*a);}
-- extern inline void cpu_to_le32s(__u16 *a) {*a = cpu_to_le32(*a);}
-- extern inline void cpu_to_be16s(__u16 *a) {*a = cpu_to_be16(*a);}
-- extern inline void cpu_to_be32s(__u16 *a) {*a = cpu_to_be32(*a);}
--
--# define le16_to_cpup(x) cpu_to_le16p(x)
--# define le32_to_cpup(x) cpu_to_le32p(x)
--# define be16_to_cpup(x) cpu_to_be16p(x)
--# define be32_to_cpup(x) cpu_to_be32p(x)
--
--# define le16_to_cpus(x) cpu_to_le16s(x)
--# define le32_to_cpus(x) cpu_to_le32s(x)
--# define be16_to_cpus(x) cpu_to_be16s(x)
--# define be32_to_cpus(x) cpu_to_be32s(x)
--#endif
--
--// from 2.2, linux/types.h
--#ifndef __BIT_TYPES_DEFINED__
--#define __BIT_TYPES_DEFINED__
--
--typedef __u8 u_int8_t;
--typedef __s8 int8_t;
--typedef __u16 u_int16_t;
--typedef __s16 int16_t;
--typedef __u32 u_int32_t;
--typedef __s32 int32_t;
--
--#endif /* !(__BIT_TYPES_DEFINED__) */
--
--#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
-- typedef struct { } spinlock_t;
-- #define SPIN_LOCK_UNLOCKED (spinlock_t) { }
--#else
-- typedef struct { int gcc_is_buggy; } spinlock_t;
-- #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
--#endif
--
--#define spin_lock_init(lock) do { } while(0)
--#define spin_lock(lock) (void)(lock) /* Not "unused variable". */
--#define spin_trylock(lock) (1)
--#define spin_unlock_wait(lock) do { } while(0)
--#define spin_unlock(lock) do { } while(0)
--#define spin_lock_irq(lock) cli()
--#define spin_unlock_irq(lock) sti()
--
--#define spin_lock_irqsave(lock, flags) \
-- do { save_flags(flags); cli(); } while (0)
--#define spin_unlock_irqrestore(lock, flags) \
-- restore_flags(flags)
--
--// Doesn't work when tqueue.h is included.
--// #define queue_task queue_task_irq_off
--#define tty_flip_buffer_push(tty) queue_task_irq_off(&tty->flip.tqueue, &tq_timer)
--#define signal_pending(current) (current->signal & ~current->blocked)
--#define schedule_timeout(to) do {current->timeout = jiffies + (to);schedule ();} while (0)
--#define time_after(t1,t2) (((long)t1-t2) > 0)
--
--#else
-- #include <linux/compatmac.h>
--#endif // LINUX_VERSION_CODE < 0x020100
--
--
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
--#include <linux/vmalloc.h>
--#endif
--
--/* Modularization issues */
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,18)
--# define __USE_OLD_SYMTAB__
--# define EXPORT_NO_SYMBOLS register_symtab(NULL);
--# define REGISTER_SYMTAB(tab) register_symtab(tab)
--#else
--# define REGISTER_SYMTAB(tab) /* nothing */
--#endif
--
--#ifdef __USE_OLD_SYMTAB__
--# define __MODULE_STRING(s) /* nothing */
--# define MODULE_PARM(v,t) /* nothing */
--# define MODULE_PARM_DESC(v,t) /* nothing */
--# define MODULE_AUTHOR(n) /* nothing */
--# define MODULE_DESCRIPTION(d) /* nothing */
--# define MODULE_SUPPORTED_DEVICE(n) /* nothing */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)
-+#error "This kernel is too old: not supported by this file"
- #endif
-
--/*
-- * "select" changed in 2.1.23. The implementation is twin, but this
-- * header is new
-- */
--#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,22)
--# include <linux/poll.h>
--#else
--# define __USE_OLD_SELECT__
--#endif
-+ /* O(1) scheduler stuff. */
-
--/* Other change in the fops are solved using pseudo-types */
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
--# define lseek_t long long
--# define lseek_off_t long long
--#else
--# define lseek_t int
--# define lseek_off_t off_t
--#endif
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,5) && !defined(__rh_config_h__)
-+#include <linux/sched.h>
-+static inline void __recalc_sigpending(void)
-+{
-+ recalc_sigpending(current);
-+}
-+#undef recalc_sigpending
-+#define recalc_sigpending() __recalc_sigpending ()
-
--/* changed the prototype of read/write */
-+#define set_user_nice(tsk, n) do { (tsk)->nice = n; } while(0)
-
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) || defined(__alpha__)
--# define count_t unsigned long
--# define read_write_t long
--#else
--# define count_t int
--# define read_write_t int
- #endif
-
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,31)
--# define release_t void
--# define release_return(x) return
--#else
--# define release_t int
--# define release_return(x) return (x)
--#endif
--
--#if LINUX_VERSION_CODE < 0x20300
--#define __exit
--#endif
--#if LINUX_VERSION_CODE < 0x20200
--#define __init
--#else
--#include <linux/init.h>
--#endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
--#define init_MUTEX(x) do {*(x) = MUTEX;} while (0)
--#define init_MUTEX_LOCKED(x) do {*(x) = MUTEX_LOCKED;} while (0)
--#endif
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20)
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
--#define RQFUNC_ARG void
--#define blkdev_dequeue_request(req) do {CURRENT = req->next;} while (0)
--#else
--#define RQFUNC_ARG request_queue_t *q
-+#ifndef yield
-+#define yield() do { set_current_state(TASK_RUNNING); schedule(); } while(0)
- #endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,32)
--#define blk_cleanup_queue(nr) do {blk_dev[nr].request_fn = 0;} while(0)
--#define BLK_DEFAULT_QUEUE(nr) (blk_dev[nr].request_fn)
--#define blk_init_queue(q, rq) do {q = rq;} while(0)
-+#ifndef minor
-+#define major(d) (MAJOR(to_kdev_t(d)))
-+#define minor(d) (MINOR(to_kdev_t(d)))
- #endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0)
--#ifdef CONFIG_MODULES
--#define __MOD_INC_USE_COUNT(mod) \
-- (atomic_inc(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED|MOD_USED_ONCE)
--#define __MOD_DEC_USE_COUNT(mod) \
-- (atomic_dec(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED)
--#else
--#define __MOD_INC_USE_COUNT(mod)
--#define __MOD_DEC_USE_COUNT(mod)
--#endif
-+#ifndef mk_kdev
-+#define mk_kdev(ma,mi) MKDEV(ma,mi)
-+#define kdev_t_to_nr(x) (x)
- #endif
-
-+#define need_resched() (current->need_resched)
-+#define cond_resched() do { if need_resched() { yield(); } } while(0)
-
--#ifndef HAVE_INTER_MODULE
--static inline void *inter_module_get(char *x) {return NULL;}
--static inline void *inter_module_get_request(char *x, char *y) {return NULL;}
--static inline void inter_module_put(const char *x) {}
--static inline void inter_module_register(const char *x, struct module *y, const void *z) {}
--static inline void inter_module_unregister(const char *x) {}
-+#endif /* < 2.4.20 */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,73)
-+#define iminor(i) minor((i)->i_rdev)
-+#define imajor(i) major((i)->i_rdev)
-+#define old_encode_dev(d) ( (major(d)<<8) | minor(d) )
-+#define old_decode_dev(rdev) (kdev_t_to_nr(mk_kdev((rdev)>>8, (rdev)&0xff)))
-+#define old_valid_dev(d) (1)
- #endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,61)
-
--#define DECLARE_WAIT_QUEUE_HEAD(x) struct wait_queue *x = NULL
--#define init_waitqueue_head init_waitqueue
-+#include <linux/sched.h>
-
-+#ifdef __rh_config_h__
-+#define sigmask_lock sighand->siglock
-+#define sig sighand
- #endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
--
--static inline int try_inc_mod_count(struct module *mod)
-+static inline void __daemonize_modvers(void)
- {
--#ifdef CONFIG_MODULES
-- if (mod)
-- __MOD_INC_USE_COUNT(mod);
--#endif
-- return 1;
--}
--#endif
-+ daemonize();
-
-+ spin_lock_irq(&current->sigmask_lock);
-+ sigfillset(&current->blocked);
-+ recalc_sigpending();
-+ spin_unlock_irq(&current->sigmask_lock);
-+}
-+#undef daemonize
-+#define daemonize(fmt, ...) do { \
-+ snprintf(current->comm, sizeof(current->comm), fmt ,##__VA_ARGS__); \
-+ __daemonize_modvers(); \
-+ } while(0)
-
--/* Yes, I'm aware that it's a fairly ugly hack.
-- Until the __constant_* macros appear in Linus' own kernels, this is
-- the way it has to be done.
-- DW 19/1/00
-- */
--
--#include <asm/byteorder.h>
--
--#ifndef __constant_cpu_to_le16
--
--#ifdef __BIG_ENDIAN
--#define __constant_cpu_to_le64(x) ___swab64((x))
--#define __constant_le64_to_cpu(x) ___swab64((x))
--#define __constant_cpu_to_le32(x) ___swab32((x))
--#define __constant_le32_to_cpu(x) ___swab32((x))
--#define __constant_cpu_to_le16(x) ___swab16((x))
--#define __constant_le16_to_cpu(x) ___swab16((x))
--#define __constant_cpu_to_be64(x) ((__u64)(x))
--#define __constant_be64_to_cpu(x) ((__u64)(x))
--#define __constant_cpu_to_be32(x) ((__u32)(x))
--#define __constant_be32_to_cpu(x) ((__u32)(x))
--#define __constant_cpu_to_be16(x) ((__u16)(x))
--#define __constant_be16_to_cpu(x) ((__u16)(x))
--#else
--#ifdef __LITTLE_ENDIAN
--#define __constant_cpu_to_le64(x) ((__u64)(x))
--#define __constant_le64_to_cpu(x) ((__u64)(x))
--#define __constant_cpu_to_le32(x) ((__u32)(x))
--#define __constant_le32_to_cpu(x) ((__u32)(x))
--#define __constant_cpu_to_le16(x) ((__u16)(x))
--#define __constant_le16_to_cpu(x) ((__u16)(x))
--#define __constant_cpu_to_be64(x) ___swab64((x))
--#define __constant_be64_to_cpu(x) ___swab64((x))
--#define __constant_cpu_to_be32(x) ___swab32((x))
--#define __constant_be32_to_cpu(x) ___swab32((x))
--#define __constant_cpu_to_be16(x) ___swab16((x))
--#define __constant_be16_to_cpu(x) ___swab16((x))
--#else
--#error No (recognised) endianness defined (unless it,s PDP)
--#endif /* __LITTLE_ENDIAN */
--#endif /* __BIG_ENDIAN */
--
--#endif /* ifndef __constant_cpu_to_le16 */
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-- #define mod_init_t int __init
-- #define mod_exit_t void
--#else
-- #define mod_init_t static int __init
-- #define mod_exit_t static void __exit
--#endif
--
--#ifndef THIS_MODULE
--#ifdef MODULE
--#define THIS_MODULE (&__this_module)
--#else
--#define THIS_MODULE (NULL)
--#endif
--#endif
--
--#if LINUX_VERSION_CODE < 0x20300
--#include <linux/interrupt.h>
--#define spin_lock_bh(lock) do {start_bh_atomic();spin_lock(lock);}while(0)
--#define spin_unlock_bh(lock) do {spin_unlock(lock);end_bh_atomic();}while(0)
--#else
--#include <asm/softirq.h>
--#include <linux/spinlock.h>
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
--#define set_current_state(state_value) \
-- do { current->state = (state_value); } while (0)
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0)
--static inline int invalidate_device(kdev_t dev, int do_sync) {
-+static inline int dequeue_signal_lock(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
-+{
-+ unsigned long flags;
-+ unsigned long ret;
-
-- if (do_sync)
-- fsync_dev(dev);
-+ spin_lock_irqsave(&current->sigmask_lock, flags);
-+ ret = dequeue_signal(mask, info);
-+ spin_unlock_irqrestore(&current->sigmask_lock, flags);
-
-- invalidate_buffers(dev);
-- return 0;
-+ return ret;
- }
--#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,4,5)
--static inline int invalidate_device(kdev_t dev, int do_sync) {
-- struct super_block *sb = get_super(dev);
-- int res = 0;
-
-- if (do_sync)
-- fsync_dev(dev);
--
-- if (sb)
-- res = invalidate_inodes(sb);
-+static inline int allow_signal(int sig)
-+{
-+ if (sig < 1 || sig > _NSIG)
-+ return -EINVAL;
-
-- invalidate_buffers(dev);
-- return res;
-+ spin_lock_irq(&current->sigmask_lock);
-+ sigdelset(&current->blocked, sig);
-+ recalc_sigpending();
-+ /* Make sure the kernel neither eats it now converts to SIGKILL */
-+ current->sig->action[sig-1].sa.sa_handler = (void *)2;
-+ spin_unlock_irq(&current->sigmask_lock);
-+ return 0;
- }
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)
--#undef min
--#undef max
--#undef min_t
--#undef max_t
--/*
-- * min()/max() macros that also do
-- * strict type-checking.. See the
-- * "unnecessary" pointer comparison.
-- */
--#define min(x,y) ({ \
-- const typeof(x) _x = (x); \
-- const typeof(y) _y = (y); \
-- (void) (&_x == &_y); \
-- _x < _y ? _x : _y; })
--
--#define max(x,y) ({ \
-- const typeof(x) _x = (x); \
-- const typeof(y) _y = (y); \
-- (void) (&_x == &_y); \
-- _x > _y ? _x : _y; })
--
--/*
-- * ..and if you can't take the strict
-- * types, you can specify one yourself.
-- *
-- * Or not use min/max at all, of course.
-- */
--#define min_t(type,x,y) \
-- ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
--#define max_t(type,x,y) \
-- ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,7)
--struct completion {
-- struct semaphore s;
--};
--
--#define complete(c) up(&(c)->s)
--#define wait_for_completion(c) down(&(c)->s)
--#define init_completion(c) init_MUTEX_LOCKED(&(c)->s);
--
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)
--/* This came later */
--#define complete_and_exit(c, r) do { complete(c); do_exit(r); } while(0)
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9) || \
-- (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) && !defined(__rh_config_h__))
-+static inline int disallow_signal(int sig)
-+{
-+ if (sig < 1 || sig > _NSIG)
-+ return -EINVAL;
-
--#include <linux/genhd.h>
-+ spin_lock_irq(&current->sigmask_lock);
-+ sigaddset(&current->blocked, sig);
-+ recalc_sigpending();
-
--static inline void add_gendisk(struct gendisk *gp)
--{
-- gp->next = gendisk_head;
-- gendisk_head = gp;
-+ current->sig->action[sig-1].sa.sa_handler = SIG_DFL;
-+ spin_unlock_irq(&current->sigmask_lock);
-+ return 0;
- }
-
--static inline void del_gendisk(struct gendisk *gp)
--{
-- struct gendisk *gd, **gdp;
-+#undef sighand
-+#undef sigmask_lock
-
-- for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
-- if (*gdp == gp) {
-- gd = *gdp; *gdp = gd->next;
-- break;
-- }
--}
-+#define PF_FREEZE 0
-+#define refrigerator(x) do { ; } while(0)
- #endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) && defined(MODULE)
-+ /* Module bits */
-
--#define module_init(func) \
--mod_init_t init_module(void) { \
-- return func(); \
--}
-
--#define module_exit(func) \
--mod_exit_t cleanup_module(void) { \
-- return func(); \
--}
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60)
-+#define try_module_get(m) try_inc_mod_count(m)
-+#define __module_get(m) do { if (!try_inc_mod_count(m)) BUG(); } while(0)
-+#define module_put(m) do { if (m) __MOD_DEC_USE_COUNT((struct module *)(m)); } while(0)
-+#define set_module_owner(x) do { x->owner = THIS_MODULE; } while(0)
- #endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9) || \
-- (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) && !defined(__rh_config_h__))
--#define MODULE_LICENSE(x) /* */
--#endif
-
--/* Removed for 2.4.21 kernel. This really should have been renamed
-- when it was changed -- this is a PITA */
--#if 0 && LINUX_VERSION_CODE < KERNEL_VERSION(2,5,5)
--#include <linux/sched.h>
--static inline void __recalc_sigpending(void)
--{
-- recalc_sigpending(current);
--}
--#undef recalc_sigpending
--#define recalc_sigpending() __recalc_sigpending ()
--#endif
-+ /* Random filesystem stuff, only for JFFS2 really */
-
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,5)
- #define parent_ino(d) ((d)->d_parent->d_inode->i_ino)
- #endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,3)
--#define need_resched() (current->need_resched)
--#define cond_resched() do { if need_resched() schedule(); } while(0)
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)
--#ifndef yield
--#define yield() do { set_current_state(TASK_RUNNING); schedule(); } while(0)
--#endif
--#ifndef minor
--#define major(d) (MAJOR(to_kdev_t(d)))
--#define minor(d) (MINOR(to_kdev_t(d)))
--#endif
--#ifndef mk_kdev
--#define mk_kdev(ma,mi) MKDEV(ma,mi)
--#define kdev_t_to_nr(x) (x)
--#endif
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-- /* Is this right? */
--#define set_user_nice(tsk, n) do { (tsk)->priority = 20-(n); } while(0)
--#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,4,21) && !defined(RED_HAT_LINUX_KERNEL)
--#define set_user_nice(tsk, n) do { (tsk)->nice = n; } while(0)
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,21)
--#define rq_data_dir(x) ((x)->cmd)
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
--
--#define IS_REQ_CMD(req) (1)
--
--#define QUEUE_LOCK(q) (&io_request_lock)
--
--#define BLK_INIT_QUEUE(q, req, lock) blk_init_queue((q), (req))
--
--#else /* > 2.5.0 */
--
--#define IS_REQ_CMD(req) ((req)->flags & REQ_CMD)
--
--#define QUEUE_LOCK(q) ((q)->queue_lock)
--
--#define BLK_INIT_QUEUE(q, req, lock) blk_init_queue((q), (req), (lock))
--
--#endif
--
--/* Removed cos it broke stuff. Where is this required anyway?
-- * #ifndef QUEUE_EMPTY
-- * #define QUEUE_EMPTY (!CURRENT)
-- * #endif
-- */
--#if LINUX_VERSION_CODE < 0x20300
--#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].plug_tq.sync)
--#elif LINUX_VERSION_CODE < 0x20500 //FIXME (Si)
--#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].request_queue.plugged)
--#else
--#define QUEUE_PLUGGED (blk_queue_plugged(QUEUE))
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
--#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
--#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
--#else
--#define BLK_INC_USE_COUNT do {} while(0)
--#define BLK_DEC_USE_COUNT do {} while(0)
--#endif
--
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,12)
- #define PageUptodate(x) Page_Uptodate(x)
- #endif
-@@ -580,4 +159,31 @@
- #define generic_file_readonly_mmap generic_file_mmap
- #endif
-
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,70)
-+
-+#include <linux/kmod.h>
-+#include <linux/string.h>
-+
-+static inline char *strlcpy(char *dest, const char *src, int len)
-+{
-+ dest[len-1] = 0;
-+ return strncpy(dest, src, len-1);
-+}
-+
-+static inline int do_old_request_module(const char *mod)
-+{
-+ return request_module(mod);
-+}
-+#undef request_module
-+#define request_module(fmt, ...) \
-+ ({ char modname[32]; snprintf(modname, 31, fmt ,##__VA_ARGS__); do_old_request_module(modname); })
-+
-+#endif /* 2.5.70 */
-+
-+#ifndef container_of
-+#define container_of(ptr, type, member) ({ \
-+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
-+ (type *)( (char *)__mptr - offsetof(type,member) );})
-+#endif
-+
- #endif /* __LINUX_MTD_COMPATMAC_H__ */
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/mtd/doc2000.h linux/include/linux/mtd/doc2000.h
---- linux-mips-2.4.24-pre2/include/linux/mtd/doc2000.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/mtd/doc2000.h 2004-11-17 18:17:59.212287624 +0100
-@@ -1,13 +1,21 @@
--
--/* Linux driver for Disk-On-Chip 2000 */
--/* (c) 1999 Machine Vision Holdings, Inc. */
--/* Author: David Woodhouse <dwmw2@mvhi.com> */
--/* $Id$ */
-+/*
-+ * Linux driver for Disk-On-Chip devices
-+ *
-+ * Copyright (C) 1999 Machine Vision Holdings, Inc.
-+ * Copyright (C) 2001-2003 David Woodhouse <dwmw2@infradead.org>
-+ * Copyright (C) 2002-2003 Greg Ungerer <gerg@snapgear.com>
-+ * Copyright (C) 2002-2003 SnapGear Inc
-+ *
-+ * $Id$
-+ *
-+ * Released under GPL
-+ */
-
- #ifndef __MTD_DOC2000_H__
- #define __MTD_DOC2000_H__
-
- #include <linux/mtd/mtd.h>
-+#include <asm/semaphore.h>
-
- #define DoC_Sig1 0
- #define DoC_Sig2 1
-@@ -38,18 +46,47 @@
- #define DoC_Mil_CDSN_IO 0x0800
- #define DoC_2k_CDSN_IO 0x1800
-
-+#define DoC_Mplus_NOP 0x1002
-+#define DoC_Mplus_AliasResolution 0x1004
-+#define DoC_Mplus_DOCControl 0x1006
-+#define DoC_Mplus_AccessStatus 0x1008
-+#define DoC_Mplus_DeviceSelect 0x1008
-+#define DoC_Mplus_Configuration 0x100a
-+#define DoC_Mplus_OutputControl 0x100c
-+#define DoC_Mplus_FlashControl 0x1020
-+#define DoC_Mplus_FlashSelect 0x1022
-+#define DoC_Mplus_FlashCmd 0x1024
-+#define DoC_Mplus_FlashAddress 0x1026
-+#define DoC_Mplus_FlashData0 0x1028
-+#define DoC_Mplus_FlashData1 0x1029
-+#define DoC_Mplus_ReadPipeInit 0x102a
-+#define DoC_Mplus_LastDataRead 0x102c
-+#define DoC_Mplus_LastDataRead1 0x102d
-+#define DoC_Mplus_WritePipeTerm 0x102e
-+#define DoC_Mplus_ECCSyndrome0 0x1040
-+#define DoC_Mplus_ECCSyndrome1 0x1041
-+#define DoC_Mplus_ECCSyndrome2 0x1042
-+#define DoC_Mplus_ECCSyndrome3 0x1043
-+#define DoC_Mplus_ECCSyndrome4 0x1044
-+#define DoC_Mplus_ECCSyndrome5 0x1045
-+#define DoC_Mplus_ECCConf 0x1046
-+#define DoC_Mplus_Toggle 0x1046
-+#define DoC_Mplus_DownloadStatus 0x1074
-+#define DoC_Mplus_CtrlConfirm 0x1076
-+#define DoC_Mplus_Power 0x1fff
-+
- /* How to access the device?
- * On ARM, it'll be mmap'd directly with 32-bit wide accesses.
- * On PPC, it's mmap'd and 16-bit wide.
- * Others use readb/writeb
- */
- #if defined(__arm__)
--#define ReadDOC_(adr, reg) ((unsigned char)(*(__u32 *)(((unsigned long)adr)+((reg)<<2))))
--#define WriteDOC_(d, adr, reg) do{ *(__u32 *)(((unsigned long)adr)+((reg)<<2)) = (__u32)d; wmb();} while(0)
-+#define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u32 *)(((unsigned long)adr)+((reg)<<2))))
-+#define WriteDOC_(d, adr, reg) do{ *(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)) = (__u32)d; wmb();} while(0)
- #define DOC_IOREMAP_LEN 0x8000
- #elif defined(__ppc__)
--#define ReadDOC_(adr, reg) ((unsigned char)(*(__u16 *)(((unsigned long)adr)+((reg)<<1))))
--#define WriteDOC_(d, adr, reg) do{ *(__u16 *)(((unsigned long)adr)+((reg)<<1)) = (__u16)d; wmb();} while(0)
-+#define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u16 *)(((unsigned long)adr)+((reg)<<1))))
-+#define WriteDOC_(d, adr, reg) do{ *(volatile __u16 *)(((unsigned long)adr)+((reg)<<1)) = (__u16)d; wmb();} while(0)
- #define DOC_IOREMAP_LEN 0x4000
- #else
- #define ReadDOC_(adr, reg) readb(((unsigned long)adr) + (reg))
-@@ -71,13 +108,21 @@
- #define DOC_MODE_RESERVED1 2
- #define DOC_MODE_RESERVED2 3
-
--#define DOC_MODE_MDWREN 4
- #define DOC_MODE_CLR_ERR 0x80
-+#define DOC_MODE_RST_LAT 0x10
-+#define DOC_MODE_BDECT 0x08
-+#define DOC_MODE_MDWREN 0x04
-
- #define DOC_ChipID_Doc2k 0x20
-+#define DOC_ChipID_Doc2kTSOP 0x21 /* internal number for MTD */
- #define DOC_ChipID_DocMil 0x30
-+#define DOC_ChipID_DocMilPlus32 0x40
-+#define DOC_ChipID_DocMilPlus16 0x41
-
- #define CDSN_CTRL_FR_B 0x80
-+#define CDSN_CTRL_FR_B0 0x40
-+#define CDSN_CTRL_FR_B1 0x80
-+
- #define CDSN_CTRL_ECC_IO 0x20
- #define CDSN_CTRL_FLASH_IO 0x10
- #define CDSN_CTRL_WP 0x08
-@@ -93,6 +138,10 @@
- #define DOC_ECC_RESV 0x02
- #define DOC_ECC_IGNORE 0x01
-
-+#define DOC_FLASH_CE 0x80
-+#define DOC_FLASH_WP 0x40
-+#define DOC_FLASH_BANK 0x02
-+
- /* We have to also set the reserved bit 1 for enable */
- #define DOC_ECC_EN (DOC_ECC__EN | DOC_ECC_RESV)
- #define DOC_ECC_DIS (DOC_ECC_RESV)
-@@ -107,9 +156,12 @@
- #define MAX_FLOORS 4
- #define MAX_CHIPS 4
-
--#define MAX_FLOORS_MIL 4
-+#define MAX_FLOORS_MIL 1
- #define MAX_CHIPS_MIL 1
-
-+#define MAX_FLOORS_MPLUS 2
-+#define MAX_CHIPS_MPLUS 1
-+
- #define ADDR_COLUMN 1
- #define ADDR_PAGE 2
- #define ADDR_COLUMN_PAGE 3
-@@ -118,7 +170,7 @@
- unsigned long physadr;
- unsigned long virtadr;
- unsigned long totlen;
-- char ChipID; /* Type of DiskOnChip */
-+ unsigned char ChipID; /* Type of DiskOnChip */
- int ioreg;
-
- unsigned long mfr; /* Flash IDs - only one type of flash per device */
-@@ -126,6 +178,7 @@
- int chipshift;
- char page256;
- char pageadrlen;
-+ char interleave; /* Internal interleaving - Millennium Plus style */
- unsigned long erasesize;
-
- int curfloor;
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/mtd/flashchip.h linux/include/linux/mtd/flashchip.h
---- linux-mips-2.4.24-pre2/include/linux/mtd/flashchip.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/mtd/flashchip.h 2004-11-17 18:17:59.214287320 +0100
-@@ -6,7 +6,7 @@
- *
- * (C) 2000 Red Hat. GPLd.
- *
-- * $Id$
-+ * $Id$
- *
- */
-
-@@ -58,6 +58,11 @@
- int ref_point_counter;
- flstate_t state;
- flstate_t oldstate;
-+
-+ int write_suspended:1;
-+ int erase_suspended:1;
-+ unsigned long in_progress_block_addr;
-+
- spinlock_t *mutex;
- spinlock_t _spinlock; /* We do it like this because sometimes they'll be shared. */
- wait_queue_head_t wq; /* Wait on here when we're waiting for the chip
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/mtd/gen_probe.h linux/include/linux/mtd/gen_probe.h
---- linux-mips-2.4.24-pre2/include/linux/mtd/gen_probe.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/mtd/gen_probe.h 2004-11-17 18:17:59.216287016 +0100
-@@ -1,7 +1,7 @@
- /*
- * (C) 2001, 2001 Red Hat, Inc.
- * GPL'd
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __LINUX_MTD_GEN_PROBE_H__
-@@ -10,12 +10,12 @@
- #include <linux/mtd/flashchip.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/cfi.h>
-+#include <asm/bitops.h>
-
- struct chip_probe {
- char *name;
- int (*probe_chip)(struct map_info *map, __u32 base,
-- struct flchip *chips, struct cfi_private *cfi);
--
-+ unsigned long *chip_map, struct cfi_private *cfi);
- };
-
- struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp);
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/mtd/inftl.h linux/include/linux/mtd/inftl.h
---- linux-mips-2.4.24-pre2/include/linux/mtd/inftl.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/include/linux/mtd/inftl.h 2004-11-17 18:17:59.219286560 +0100
-@@ -0,0 +1,129 @@
-+/*
-+ * inftl.h -- defines to support the Inverse NAND Flash Translation Layer
-+ *
-+ * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
-+ *
-+ * $Id$
-+ */
-+
-+#ifndef __MTD_INFTL_H__
-+#define __MTD_INFTL_H__
-+
-+#include <linux/mtd/blktrans.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nftl.h>
-+
-+#define OSAK_VERSION 0x5120
-+#define PERCENTUSED 98
-+
-+#define SECTORSIZE 512
-+
-+#ifndef INFTL_MAJOR
-+#define INFTL_MAJOR 94
-+#endif
-+#define INFTL_PARTN_BITS 4
-+
-+/* Block Control Information */
-+
-+struct inftl_bci {
-+ __u8 ECCsig[6];
-+ __u8 Status;
-+ __u8 Status1;
-+} __attribute__((packed));
-+
-+struct inftl_unithead1 {
-+ __u16 virtualUnitNo;
-+ __u16 prevUnitNo;
-+ __u8 ANAC;
-+ __u8 NACs;
-+ __u8 parityPerField;
-+ __u8 discarded;
-+} __attribute__((packed));
-+
-+struct inftl_unithead2 {
-+ __u8 parityPerField;
-+ __u8 ANAC;
-+ __u16 prevUnitNo;
-+ __u16 virtualUnitNo;
-+ __u8 NACs;
-+ __u8 discarded;
-+} __attribute__((packed));
-+
-+struct inftl_unittail {
-+ __u8 Reserved[4];
-+ __u16 EraseMark;
-+ __u16 EraseMark1;
-+} __attribute__((packed));
-+
-+union inftl_uci {
-+ struct inftl_unithead1 a;
-+ struct inftl_unithead2 b;
-+ struct inftl_unittail c;
-+};
-+
-+struct inftl_oob {
-+ struct inftl_bci b;
-+ union inftl_uci u;
-+};
-+
-+
-+/* INFTL Media Header */
-+
-+struct INFTLPartition {
-+ __u32 virtualUnits;
-+ __u32 firstUnit;
-+ __u32 lastUnit;
-+ __u32 flags;
-+ __u32 spareUnits;
-+ __u32 Reserved0;
-+ __u32 Reserved1;
-+} __attribute__((packed));
-+
-+struct INFTLMediaHeader {
-+ char bootRecordID[8];
-+ __u32 NoOfBootImageBlocks;
-+ __u32 NoOfBinaryPartitions;
-+ __u32 NoOfBDTLPartitions;
-+ __u32 BlockMultiplierBits;
-+ __u32 FormatFlags;
-+ __u32 OsakVersion;
-+ __u32 PercentUsed;
-+ struct INFTLPartition Partitions[4];
-+} __attribute__((packed));
-+
-+/* Partition flag types */
-+#define INFTL_BINARY 0x20000000
-+#define INFTL_BDTL 0x40000000
-+#define INFTL_LAST 0x80000000
-+
-+
-+#ifdef __KERNEL__
-+
-+struct INFTLrecord {
-+ struct mtd_blktrans_dev mbd;
-+ __u16 MediaUnit, SpareMediaUnit;
-+ __u32 EraseSize;
-+ struct INFTLMediaHeader MediaHdr;
-+ int usecount;
-+ unsigned char heads;
-+ unsigned char sectors;
-+ unsigned short cylinders;
-+ __u16 numvunits;
-+ __u16 firstEUN;
-+ __u16 lastEUN;
-+ __u16 numfreeEUNs;
-+ __u16 LastFreeEUN; /* To speed up finding a free EUN */
-+ int head,sect,cyl;
-+ __u16 *PUtable; /* Physical Unit Table */
-+ __u16 *VUtable; /* Virtual Unit Table */
-+ unsigned int nb_blocks; /* number of physical blocks */
-+ unsigned int nb_boot_blocks; /* number of blocks used by the bios */
-+ struct erase_info instr;
-+};
-+
-+int INFTL_mount(struct INFTLrecord *s);
-+int INFTL_formatblock(struct INFTLrecord *s, int block);
-+
-+#endif /* __KERNEL__ */
-+
-+#endif /* __MTD_INFTL_H__ */
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/mtd/jedec.h linux/include/linux/mtd/jedec.h
---- linux-mips-2.4.24-pre2/include/linux/mtd/jedec.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/mtd/jedec.h 2004-11-17 18:17:59.220286408 +0100
-@@ -7,14 +7,13 @@
- *
- * See the AMD flash databook for information on how to operate the interface.
- *
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __LINUX_MTD_JEDEC_H__
- #define __LINUX_MTD_JEDEC_H__
-
- #include <linux/types.h>
--#include <linux/mtd/map.h>
-
- #define MAX_JEDEC_CHIPS 16
-
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/mtd/map.h linux/include/linux/mtd/map.h
---- linux-mips-2.4.24-pre2/include/linux/mtd/map.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/mtd/map.h 2004-11-17 18:17:59.221286256 +0100
-@@ -1,14 +1,15 @@
-
- /* Overhauled routines for dealing with different mmap regions of flash */
--/* $Id$ */
-+/* $Id$ */
-
- #ifndef __LINUX_MTD_MAP_H__
- #define __LINUX_MTD_MAP_H__
-
- #include <linux/config.h>
- #include <linux/types.h>
--#include <linux/mtd/mtd.h>
--#include <linux/slab.h>
-+#include <linux/list.h>
-+#include <asm/system.h>
-+#include <asm/io.h>
-
- /* The map stuff is very simple. You fill in your struct map_info with
- a handful of routines for accessing the device, making sure they handle
-@@ -29,39 +30,44 @@
- struct map_info {
- char *name;
- unsigned long size;
-+ unsigned long phys;
-+#define NO_XIP (-1UL)
-+
-+ unsigned long virt;
-+ void *cached;
-+
- int buswidth; /* in octets */
-- __u8 (*read8)(struct map_info *, unsigned long);
-- __u16 (*read16)(struct map_info *, unsigned long);
-- __u32 (*read32)(struct map_info *, unsigned long);
-- __u64 (*read64)(struct map_info *, unsigned long);
-+
-+#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
-+ u8 (*read8)(struct map_info *, unsigned long);
-+ u16 (*read16)(struct map_info *, unsigned long);
-+ u32 (*read32)(struct map_info *, unsigned long);
-+ u64 (*read64)(struct map_info *, unsigned long);
- /* If it returned a 'long' I'd call it readl.
- * It doesn't.
- * I won't.
- * dwmw2 */
-
- void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t);
-- void (*write8)(struct map_info *, __u8, unsigned long);
-- void (*write16)(struct map_info *, __u16, unsigned long);
-- void (*write32)(struct map_info *, __u32, unsigned long);
-- void (*write64)(struct map_info *, __u64, unsigned long);
-+ void (*write8)(struct map_info *, u8, unsigned long);
-+ void (*write16)(struct map_info *, u16, unsigned long);
-+ void (*write32)(struct map_info *, u32, unsigned long);
-+ void (*write64)(struct map_info *, u64, unsigned long);
- void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t);
-
-- u_char * (*point) (struct map_info *, loff_t, size_t);
-- void (*unpoint) (struct map_info *, u_char *, loff_t, size_t);
--
-+ /* We can perhaps put in 'point' and 'unpoint' methods, if we really
-+ want to enable XIP for non-linear mappings. Not yet though. */
-+#endif
-+ /* set_vpp() must handle being reentered -- enable, enable, disable
-+ must leave it enabled. */
- void (*set_vpp)(struct map_info *, int);
-- /* We put these two here rather than a single void *map_priv,
-- because we want mappers to be able to have quickly-accessible
-- cache for the 'currently-mapped page' without the _extra_
-- redirection that would be necessary. If you need more than
-- two longs, turn the second into a pointer. dwmw2 */
-+
- unsigned long map_priv_1;
- unsigned long map_priv_2;
- void *fldrv_priv;
- struct mtd_chip_driver *fldrv;
- };
-
--
- struct mtd_chip_driver {
- struct mtd_info *(*probe)(struct map_info *map);
- void (*destroy)(struct mtd_info *);
-@@ -74,26 +80,93 @@
- void unregister_mtd_chip_driver(struct mtd_chip_driver *);
-
- struct mtd_info *do_map_probe(const char *name, struct map_info *map);
-+void map_destroy(struct mtd_info *mtd);
-+
-+#define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0)
-+#define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0)
-+
-+#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
-+#define map_read8(map, ofs) (map)->read8(map, ofs)
-+#define map_read16(map, ofs) (map)->read16(map, ofs)
-+#define map_read32(map, ofs) (map)->read32(map, ofs)
-+#define map_read64(map, ofs) (map)->read64(map, ofs)
-+#define map_copy_from(map, to, from, len) (map)->copy_from(map, to, from, len)
-+#define map_write8(map, datum, ofs) (map)->write8(map, datum, ofs)
-+#define map_write16(map, datum, ofs) (map)->write16(map, datum, ofs)
-+#define map_write32(map, datum, ofs) (map)->write32(map, datum, ofs)
-+#define map_write64(map, datum, ofs) (map)->write64(map, datum, ofs)
-+#define map_copy_to(map, to, from, len) (map)->copy_to(map, to, from, len)
-
-+extern void simple_map_init(struct map_info *);
-+#define map_is_linear(map) (map->phys != NO_XIP)
-
--/*
-- * Destroy an MTD device which was created for a map device.
-- * Make sure the MTD device is already unregistered before calling this
-- */
--static inline void map_destroy(struct mtd_info *mtd)
--{
-- struct map_info *map = mtd->priv;
--
-- if (map->fldrv->destroy)
-- map->fldrv->destroy(mtd);
--#ifdef CONFIG_MODULES
-- if (map->fldrv->module)
-- __MOD_DEC_USE_COUNT(map->fldrv->module);
-+#else
-+static inline u8 map_read8(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readb(map->virt + ofs);
-+}
-+
-+static inline u16 map_read16(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readw(map->virt + ofs);
-+}
-+
-+static inline u32 map_read32(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readl(map->virt + ofs);
-+}
-+
-+static inline u64 map_read64(struct map_info *map, unsigned long ofs)
-+{
-+#ifndef CONFIG_MTD_CFI_B8 /* 64-bit mappings */
-+ BUG();
-+ return 0;
-+#else
-+ return __raw_readll(map->virt + ofs);
- #endif
-- kfree(mtd);
- }
-
--#define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0)
--#define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0)
-+static inline void map_write8(struct map_info *map, u8 datum, unsigned long ofs)
-+{
-+ __raw_writeb(datum, map->virt + ofs);
-+ mb();
-+}
-+
-+static inline void map_write16(struct map_info *map, u16 datum, unsigned long ofs)
-+{
-+ __raw_writew(datum, map->virt + ofs);
-+ mb();
-+}
-+
-+static inline void map_write32(struct map_info *map, u32 datum, unsigned long ofs)
-+{
-+ __raw_writel(datum, map->virt + ofs);
-+ mb();
-+}
-+
-+static inline void map_write64(struct map_info *map, u64 datum, unsigned long ofs)
-+{
-+#ifndef CONFIG_MTD_CFI_B8 /* 64-bit mappings */
-+ BUG();
-+#else
-+ __raw_writell(datum, map->virt + ofs);
-+ mb();
-+#endif /* CFI_B8 */
-+}
-+
-+static inline void map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-+{
-+ memcpy_fromio(to, map->virt + from, len);
-+}
-+
-+static inline void map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-+{
-+ memcpy_toio(map->virt + to, from, len);
-+}
-+
-+#define simple_map_init(map) do { } while (0)
-+#define map_is_linear(map) (1)
-+
-+#endif /* !CONFIG_MTD_COMPLEX_MAPPINGS */
-
- #endif /* __LINUX_MTD_MAP_H__ */
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/mtd/mtd.h linux/include/linux/mtd/mtd.h
---- linux-mips-2.4.24-pre2/include/linux/mtd/mtd.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/mtd/mtd.h 2004-11-17 18:17:59.234284280 +0100
-@@ -1,5 +1,10 @@
--
--/* $Id$ */
-+/*
-+ * $Id$
-+ *
-+ * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al.
-+ *
-+ * Released under GPL
-+ */
-
- #ifndef __MTD_MTD_H__
- #define __MTD_MTD_H__
-@@ -9,7 +14,6 @@
- #include <linux/config.h>
- #include <linux/version.h>
- #include <linux/types.h>
--#include <linux/mtd/compatmac.h>
- #include <linux/module.h>
- #include <linux/uio.h>
-
-@@ -26,7 +30,6 @@
- unsigned char *ptr;
- };
-
--
- #define MTD_CHAR_MAJOR 90
- #define MTD_BLOCK_MAJOR 31
- #define MAX_MTD_DEVICES 16
-@@ -93,18 +96,23 @@
- #define MEMUNLOCK _IOW('M', 6, struct erase_info_user)
- #define MEMGETREGIONCOUNT _IOR('M', 7, int)
- #define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user)
--#define MEMREADDATA _IOWR('M', 9, struct mtd_oob_buf)
--#define MEMWRITEDATA _IOWR('M', 10, struct mtd_oob_buf)
-+#define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo)
-+
-+struct nand_oobinfo {
-+ int useecc;
-+ int eccpos[6];
-+};
-+
-
- #ifndef __KERNEL__
-
- typedef struct mtd_info_user mtd_info_t;
- typedef struct erase_info_user erase_info_t;
- typedef struct region_info_user region_info_t;
-+typedef struct nand_oobinfo nand_oobinfo_t;
-
- /* User-space ioctl definitions */
-
--
- #else /* __KERNEL__ */
-
-
-@@ -150,10 +158,14 @@
- u_int32_t ecctype;
- u_int32_t eccsize;
-
-+
- // Kernel-only stuff starts here.
- char *name;
- int index;
-
-+ // oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO)
-+ struct nand_oobinfo oobinfo;
-+
- /* Data for variable erase regions. If numeraseregions is zero,
- * it means that the whole device has erasesize as given above.
- */
-@@ -163,7 +175,6 @@
- /* This really shouldn't be here. It can go away in 2.5 */
- u_int32_t bank_size;
-
-- struct module *module;
- int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
-
- /* This stuff for eXecute-In-Place */
-@@ -176,8 +187,8 @@
- int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
- int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
-
-- int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel);
-- int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel);
-+ int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
-+ int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
-
- int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
- int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
-@@ -201,10 +212,10 @@
- */
- int (*readv) (struct mtd_info *mtd, struct iovec *vecs, unsigned long count, loff_t from, size_t *retlen);
- int (*readv_ecc) (struct mtd_info *mtd, struct iovec *vecs, unsigned long count, loff_t from,
-- size_t *retlen, u_char *eccbuf, int oobsel);
-+ size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
- int (*writev) (struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen);
- int (*writev_ecc) (struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to,
-- size_t *retlen, u_char *eccbuf, int oobsel);
-+ size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
-
- /* Sync */
- void (*sync) (struct mtd_info *mtd);
-@@ -218,6 +229,9 @@
- void (*resume) (struct mtd_info *mtd);
-
- void *priv;
-+
-+ struct module *owner;
-+ int usecount;
- };
-
-
-@@ -226,31 +240,15 @@
- extern int add_mtd_device(struct mtd_info *mtd);
- extern int del_mtd_device (struct mtd_info *mtd);
-
--extern struct mtd_info *__get_mtd_device(struct mtd_info *mtd, int num);
--
--static inline struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
--{
-- struct mtd_info *ret;
-+extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
-
-- ret = __get_mtd_device(mtd, num);
--
-- if (ret && ret->module && !try_inc_mod_count(ret->module))
-- return NULL;
--
-- return ret;
--}
--
--static inline void put_mtd_device(struct mtd_info *mtd)
--{
-- if (mtd->module)
-- __MOD_DEC_USE_COUNT(mtd->module);
--}
-+extern void put_mtd_device(struct mtd_info *mtd);
-
-
- struct mtd_notifier {
- void (*add)(struct mtd_info *mtd);
- void (*remove)(struct mtd_info *mtd);
-- struct mtd_notifier *next;
-+ struct list_head list;
- };
-
-
-@@ -263,7 +261,6 @@
- int default_mtd_readv(struct mtd_info *mtd, struct iovec *vecs,
- unsigned long count, loff_t from, size_t *retlen);
-
--#ifndef MTDC
- #define MTD_ERASE(mtd, args...) (*(mtd->erase))(mtd, args)
- #define MTD_POINT(mtd, a,b,c,d) (*(mtd->point))(mtd, a,b,c, (u_char **)(d))
- #define MTD_UNPOINT(mtd, arg) (*(mtd->unpoint))(mtd, (u_char *)arg)
-@@ -276,7 +273,6 @@
- #define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args)
- #define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args)
- #define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0)
--#endif /* MTDC */
-
- /*
- * Debugging macro and defines
-@@ -293,7 +289,8 @@
- printk(KERN_INFO args); \
- } while(0)
- #else /* CONFIG_MTD_DEBUG */
--#define DEBUG(n, args...)
-+#define DEBUG(n, args...) do { } while(0)
-+
- #endif /* CONFIG_MTD_DEBUG */
-
- #endif /* __KERNEL__ */
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/mtd/nand.h linux/include/linux/mtd/nand.h
---- linux-mips-2.4.24-pre2/include/linux/mtd/nand.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/mtd/nand.h 2004-11-17 18:17:59.236283976 +0100
-@@ -2,10 +2,10 @@
- * linux/include/linux/mtd/nand.h
- *
- * Copyright (c) 2000 David Woodhouse <dwmw2@mvhi.com>
-- * Steven J. Hill <sjhill@cotw.com>
-+ * Steven J. Hill <sjhill@realitydiluted.com>
- * Thomas Gleixner <tglx@linutronix.de>
- *
-- * $Id$
-+ * $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
-@@ -49,12 +49,14 @@
- #define __LINUX_MTD_NAND_H
-
- #include <linux/config.h>
--#include <linux/sched.h>
-+#include <linux/wait.h>
-+#include <linux/spinlock.h>
-
-+struct mtd_info;
- /*
- * Searches for a NAND device
- */
--extern int nand_scan (struct mtd_info *mtd);
-+extern int nand_scan (struct mtd_info *mtd, int max_chips);
-
- /*
- * Constants for hardware specific CLE/ALE/NCE function
-@@ -65,6 +67,8 @@
- #define NAND_CTL_CLRCLE 4
- #define NAND_CTL_SETALE 5
- #define NAND_CTL_CLRALE 6
-+#define NAND_CTL_SETWP 7
-+#define NAND_CTL_CLRWP 8
-
- /*
- * Standard NAND flash commands
-@@ -160,24 +164,33 @@
- struct nand_chip {
- unsigned long IO_ADDR_R;
- unsigned long IO_ADDR_W;
-- void (*hwcontrol)(int cmd);
-- int (*dev_ready)(void);
-+
-+ u_char (*read_byte)(struct mtd_info *mtd);
-+ void (*write_byte)(struct mtd_info *mtd, u_char byte);
-+
-+ void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len);
-+ void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len);
-+ int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len);
-+ void (*select_chip)(struct mtd_info *mtd, int chip);
-+ int (*block_bad)(struct mtd_info *mtd, unsigned long pos);
-+ void (*hwcontrol)(struct mtd_info *mtd, int cmd);
-+ int (*dev_ready)(struct mtd_info *mtd);
- void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);
- int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state);
-- void (*calculate_ecc)(const u_char *dat, u_char *ecc_code);
-- int (*correct_data)(u_char *dat, u_char *read_ecc, u_char *calc_ecc);
-- void (*enable_hwecc)(int mode);
-+ void (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code);
-+ int (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
-+ void (*enable_hwecc)(struct mtd_info *mtd, int mode);
- int eccmode;
- int eccsize;
- int chip_delay;
-+ int chipshift;
- spinlock_t chip_lock;
- wait_queue_head_t wq;
- nand_state_t state;
- int page_shift;
- u_char *data_buf;
- u_char *data_poi;
-- u_char *data_cache;
-- int cache_page;
-+ void *priv;
- };
-
- /*
-@@ -241,34 +254,4 @@
- */
- #define NAND_BADBLOCK_POS 5
-
--#define NAND_NONE_OOB 0
--#define NAND_JFFS2_OOB 1
--#define NAND_YAFFS_OOB 2
--
--#define NAND_NOOB_ECCPOS0 0
--#define NAND_NOOB_ECCPOS1 1
--#define NAND_NOOB_ECCPOS2 2
--#define NAND_NOOB_ECCPOS3 3
--#define NAND_NOOB_ECCPOS4 6
--#define NAND_NOOB_ECCPOS5 7
--
--#define NAND_JFFS2_OOB_ECCPOS0 0
--#define NAND_JFFS2_OOB_ECCPOS1 1
--#define NAND_JFFS2_OOB_ECCPOS2 2
--#define NAND_JFFS2_OOB_ECCPOS3 3
--#define NAND_JFFS2_OOB_ECCPOS4 6
--#define NAND_JFFS2_OOB_ECCPOS5 7
--
--#define NAND_YAFFS_OOB_ECCPOS0 8
--#define NAND_YAFFS_OOB_ECCPOS1 9
--#define NAND_YAFFS_OOB_ECCPOS2 10
--#define NAND_YAFFS_OOB_ECCPOS3 13
--#define NAND_YAFFS_OOB_ECCPOS4 14
--#define NAND_YAFFS_OOB_ECCPOS5 15
--
--#define NAND_JFFS2_OOB8_FSDAPOS 6
--#define NAND_JFFS2_OOB16_FSDAPOS 8
--#define NAND_JFFS2_OOB8_FSDALEN 2
--#define NAND_JFFS2_OOB16_FSDALEN 8
--
- #endif /* __LINUX_MTD_NAND_H */
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/mtd/nand_ecc.h linux/include/linux/mtd/nand_ecc.h
---- linux-mips-2.4.24-pre2/include/linux/mtd/nand_ecc.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/mtd/nand_ecc.h 2004-11-17 18:17:59.237283824 +0100
-@@ -1,9 +1,9 @@
- /*
- * drivers/mtd/nand_ecc.h
- *
-- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
-+ * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
- *
-- * $Id$
-+ * $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
-@@ -12,17 +12,19 @@
- * This file is the header for the ECC algorithm.
- */
-
--/*
-- * Creates non-inverted ECC code from line parity
-- */
--void nand_trans_result(u_char reg2, u_char reg3, u_char *ecc_code);
-+#ifndef __MTD_NAND_ECC_H__
-+#define __MTD_NAND_ECC_H__
-+
-+struct mtd_info;
-
- /*
- * Calculate 3 byte ECC code for 256 byte block
- */
--void nand_calculate_ecc (const u_char *dat, u_char *ecc_code);
-+void nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code);
-
- /*
- * Detect and correct a 1 bit error for 256 byte block
- */
--int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc);
-+int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
-+
-+#endif /* __MTD_NAND_ECC_H__ */
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/mtd/nftl.h linux/include/linux/mtd/nftl.h
---- linux-mips-2.4.24-pre2/include/linux/mtd/nftl.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/mtd/nftl.h 2004-11-17 18:17:59.238283672 +0100
-@@ -1,15 +1,14 @@
--
--/* Defines for NAND Flash Translation Layer */
--/* (c) 1999 Machine Vision Holdings, Inc. */
--/* Author: David Woodhouse <dwmw2@mvhi.com> */
--/* $Id$ */
-+/*
-+ * $Id$
-+ *
-+ * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
-+ */
-
- #ifndef __MTD_NFTL_H__
- #define __MTD_NFTL_H__
-
--#ifndef __BOOT__
- #include <linux/mtd/mtd.h>
--#endif
-+#include <linux/mtd/blktrans.h>
-
- /* Block Control Information */
-
-@@ -84,8 +83,7 @@
- #define BLOCK_RESERVED 0xfffc /* bios block or bad block */
-
- struct NFTLrecord {
-- struct mtd_info *mtd;
-- struct semaphore mutex;
-+ struct mtd_blktrans_dev mbd;
- __u16 MediaUnit, SpareMediaUnit;
- __u32 EraseSize;
- struct NFTLMediaHeader MediaHdr;
-@@ -97,7 +95,6 @@
- __u16 lastEUN; /* should be suppressed */
- __u16 numfreeEUNs;
- __u16 LastFreeEUN; /* To speed up finding a free EUN */
-- __u32 nr_sects;
- int head,sect,cyl;
- __u16 *EUNtable; /* [numvunits]: First EUN for each virtual unit */
- __u16 *ReplUnitTable; /* [numEUNs]: ReplUnitNumber for each */
-@@ -114,7 +111,7 @@
- #endif
-
- #define MAX_NFTLS 16
--#define MAX_SECTORS_PER_UNIT 32
-+#define MAX_SECTORS_PER_UNIT 64
- #define NFTL_PARTN_BITS 4
-
- #endif /* __KERNEL__ */
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/mtd/partitions.h linux/include/linux/mtd/partitions.h
---- linux-mips-2.4.24-pre2/include/linux/mtd/partitions.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/mtd/partitions.h 2004-11-17 18:17:59.240283368 +0100
-@@ -5,7 +5,7 @@
- *
- * This code is GPL
- *
-- * $Id$
-+ * $Id$
- */
-
- #ifndef MTD_PARTITIONS_H
-@@ -41,6 +41,7 @@
- u_int32_t size; /* partition size */
- u_int32_t offset; /* offset within the master MTD space */
- u_int32_t mask_flags; /* master MTD flags to mask out for this partition */
-+ struct nand_oobinfo *oobsel; /* out of band layout for this partition (NAND only)*/
- struct mtd_info **mtdp; /* pointer to store the MTD object */
- };
-
-@@ -49,8 +50,27 @@
- #define MTDPART_SIZ_FULL (0)
-
-
--int add_mtd_partitions(struct mtd_info *, struct mtd_partition *, int);
-+int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
- int del_mtd_partitions(struct mtd_info *);
-
-+/*
-+ * Functions dealing with the various ways of partitioning the space
-+ */
-+
-+struct mtd_part_parser {
-+ struct list_head list;
-+ struct module *owner;
-+ const char *name;
-+ int (*parse_fn)(struct mtd_info *, struct mtd_partition **, unsigned long);
-+};
-+
-+extern struct mtd_part_parser *get_partition_parser(const char *name);
-+extern int register_mtd_parser(struct mtd_part_parser *parser);
-+extern int deregister_mtd_parser(struct mtd_part_parser *parser);
-+extern int parse_mtd_partitions(struct mtd_info *master, const char **types,
-+ struct mtd_partition **pparts, unsigned long origin);
-+
-+#define put_partition_parser(p) do { module_put((p)->owner); } while(0)
-+
- #endif
-
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/mtd/physmap.h linux/include/linux/mtd/physmap.h
---- linux-mips-2.4.24-pre2/include/linux/mtd/physmap.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/include/linux/mtd/physmap.h 2004-11-17 18:17:59.241283216 +0100
-@@ -0,0 +1,59 @@
-+/*
-+ * For boards with physically mapped flash and using
-+ * drivers/mtd/maps/physmap.c mapping driver.
-+ *
-+ * Copyright (C) 2003 MontaVista Software Inc.
-+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ *
-+ */
-+
-+#ifndef __LINUX_MTD_PHYSMAP__
-+
-+#include <linux/config.h>
-+
-+#if defined(CONFIG_MTD_PHYSMAP)
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+
-+/*
-+ * The map_info for physmap. Board can override size, buswidth, phys,
-+ * (*set_vpp)(), etc in their initial setup routine.
-+ */
-+extern struct map_info physmap_map;
-+
-+/*
-+ * Board needs to specify the exact mapping during their setup time.
-+ */
-+static inline void physmap_configure(unsigned long addr, unsigned long size, int buswidth, void (*set_vpp)(struct map_info *, int) )
-+{
-+ physmap_map.phys = addr;
-+ physmap_map.size = size;
-+ physmap_map.buswidth = buswidth;
-+ physmap_map.set_vpp = set_vpp;
-+}
-+
-+#if defined(CONFIG_MTD_PARTITIONS)
-+
-+/*
-+ * Machines that wish to do flash partition may want to call this function in
-+ * their setup routine.
-+ *
-+ * physmap_set_partitions(mypartitions, num_parts);
-+ *
-+ * Note that one can always override this hard-coded partition with
-+ * command line partition (you need to enable CONFIG_MTD_CMDLINE_PARTS).
-+ */
-+void physmap_set_partitions(struct mtd_partition *parts, int num_parts);
-+
-+#endif /* defined(CONFIG_MTD_PARTITIONS) */
-+#endif /* defined(CONFIG_MTD) */
-+
-+#endif /* __LINUX_MTD_PHYSMAP__ */
-+
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/rbtree-24.h linux/include/linux/rbtree-24.h
---- linux-mips-2.4.24-pre2/include/linux/rbtree-24.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/include/linux/rbtree-24.h 2004-11-17 18:17:59.443252512 +0100
-@@ -0,0 +1,133 @@
-+/*
-+ Red Black Trees
-+ (C) 1999 Andrea Arcangeli <andrea@suse.de>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2 of the License, or
-+ (at your option) any later version.
-+
-+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+
-+ linux/include/linux/rbtree.h
-+
-+ To use rbtrees you'll have to implement your own insert and search cores.
-+ This will avoid us to use callbacks and to drop drammatically performances.
-+ I know it's not the cleaner way, but in C (not in C++) to get
-+ performances and genericity...
-+
-+ Some example of insert and search follows here. The search is a plain
-+ normal search over an ordered tree. The insert instead must be implemented
-+ int two steps: as first thing the code must insert the element in
-+ order as a red leaf in the tree, then the support library function
-+ rb_insert_color() must be called. Such function will do the
-+ not trivial work to rebalance the rbtree if necessary.
-+
-+-----------------------------------------------------------------------
-+static inline struct page * rb_search_page_cache(struct inode * inode,
-+ unsigned long offset)
-+{
-+ rb_node_t * n = inode->i_rb_page_cache.rb_node;
-+ struct page * page;
-+
-+ while (n)
-+ {
-+ page = rb_entry(n, struct page, rb_page_cache);
-+
-+ if (offset < page->offset)
-+ n = n->rb_left;
-+ else if (offset > page->offset)
-+ n = n->rb_right;
-+ else
-+ return page;
-+ }
-+ return NULL;
-+}
-+
-+static inline struct page * __rb_insert_page_cache(struct inode * inode,
-+ unsigned long offset,
-+ rb_node_t * node)
-+{
-+ rb_node_t ** p = &inode->i_rb_page_cache.rb_node;
-+ rb_node_t * parent = NULL;
-+ struct page * page;
-+
-+ while (*p)
-+ {
-+ parent = *p;
-+ page = rb_entry(parent, struct page, rb_page_cache);
-+
-+ if (offset < page->offset)
-+ p = &(*p)->rb_left;
-+ else if (offset > page->offset)
-+ p = &(*p)->rb_right;
-+ else
-+ return page;
-+ }
-+
-+ rb_link_node(node, parent, p);
-+
-+ return NULL;
-+}
-+
-+static inline struct page * rb_insert_page_cache(struct inode * inode,
-+ unsigned long offset,
-+ rb_node_t * node)
-+{
-+ struct page * ret;
-+ if ((ret = __rb_insert_page_cache(inode, offset, node)))
-+ goto out;
-+ rb_insert_color(node, &inode->i_rb_page_cache);
-+ out:
-+ return ret;
-+}
-+-----------------------------------------------------------------------
-+*/
-+
-+#ifndef _LINUX_RBTREE_H
-+#define _LINUX_RBTREE_H
-+
-+#include <linux/kernel.h>
-+#include <linux/stddef.h>
-+
-+typedef struct rb_node_s
-+{
-+ struct rb_node_s * rb_parent;
-+ int rb_color;
-+#define RB_RED 0
-+#define RB_BLACK 1
-+ struct rb_node_s * rb_right;
-+ struct rb_node_s * rb_left;
-+}
-+rb_node_t;
-+
-+typedef struct rb_root_s
-+{
-+ struct rb_node_s * rb_node;
-+}
-+rb_root_t;
-+
-+#define RB_ROOT (rb_root_t) { NULL, }
-+#define rb_entry(ptr, type, member) \
-+ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
-+
-+extern void rb_insert_color(rb_node_t *, rb_root_t *);
-+extern void rb_erase(rb_node_t *, rb_root_t *);
-+
-+static inline void rb_link_node(rb_node_t * node, rb_node_t * parent, rb_node_t ** rb_link)
-+{
-+ node->rb_parent = parent;
-+ node->rb_color = RB_RED;
-+ node->rb_left = node->rb_right = NULL;
-+
-+ *rb_link = node;
-+}
-+
-+#endif /* _LINUX_RBTREE_H */
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/rbtree.h linux/include/linux/rbtree.h
---- linux-mips-2.4.24-pre2/include/linux/rbtree.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/rbtree.h 2004-11-17 18:17:59.000000000 +0100
-@@ -1,133 +1,25 @@
- /*
-- Red Black Trees
-- (C) 1999 Andrea Arcangeli <andrea@suse.de>
-+ * 2.5 compatibility
-+ * $Id$
-+ */
-+
-+#ifndef __MTD_COMPAT_RBTREE_H__
-+#define __MTD_COMPAT_RBTREE_H__
-+
-+#include <linux/version.h>
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,40)
-+#include_next <linux/rbtree.h>
-+#else
-+#define rb_node_s rb_node
-+#define rb_root_s rb_root
-+
-+#include <linux/rbtree-24.h>
-+
-+/* Find logical next and previous nodes in a tree */
-+extern struct rb_node *rb_next(struct rb_node *);
-+extern struct rb_node *rb_prev(struct rb_node *);
-+extern struct rb_node *rb_first(struct rb_root *);
-+#endif
-
-- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--
-- linux/include/linux/rbtree.h
--
-- To use rbtrees you'll have to implement your own insert and search cores.
-- This will avoid us to use callbacks and to drop drammatically performances.
-- I know it's not the cleaner way, but in C (not in C++) to get
-- performances and genericity...
--
-- Some example of insert and search follows here. The search is a plain
-- normal search over an ordered tree. The insert instead must be implemented
-- int two steps: as first thing the code must insert the element in
-- order as a red leaf in the tree, then the support library function
-- rb_insert_color() must be called. Such function will do the
-- not trivial work to rebalance the rbtree if necessary.
--
-------------------------------------------------------------------------
--static inline struct page * rb_search_page_cache(struct inode * inode,
-- unsigned long offset)
--{
-- rb_node_t * n = inode->i_rb_page_cache.rb_node;
-- struct page * page;
--
-- while (n)
-- {
-- page = rb_entry(n, struct page, rb_page_cache);
--
-- if (offset < page->offset)
-- n = n->rb_left;
-- else if (offset > page->offset)
-- n = n->rb_right;
-- else
-- return page;
-- }
-- return NULL;
--}
--
--static inline struct page * __rb_insert_page_cache(struct inode * inode,
-- unsigned long offset,
-- rb_node_t * node)
--{
-- rb_node_t ** p = &inode->i_rb_page_cache.rb_node;
-- rb_node_t * parent = NULL;
-- struct page * page;
--
-- while (*p)
-- {
-- parent = *p;
-- page = rb_entry(parent, struct page, rb_page_cache);
--
-- if (offset < page->offset)
-- p = &(*p)->rb_left;
-- else if (offset > page->offset)
-- p = &(*p)->rb_right;
-- else
-- return page;
-- }
--
-- rb_link_node(node, parent, p);
--
-- return NULL;
--}
--
--static inline struct page * rb_insert_page_cache(struct inode * inode,
-- unsigned long offset,
-- rb_node_t * node)
--{
-- struct page * ret;
-- if ((ret = __rb_insert_page_cache(inode, offset, node)))
-- goto out;
-- rb_insert_color(node, &inode->i_rb_page_cache);
-- out:
-- return ret;
--}
-------------------------------------------------------------------------
--*/
--
--#ifndef _LINUX_RBTREE_H
--#define _LINUX_RBTREE_H
--
--#include <linux/kernel.h>
--#include <linux/stddef.h>
--
--typedef struct rb_node_s
--{
-- struct rb_node_s * rb_parent;
-- int rb_color;
--#define RB_RED 0
--#define RB_BLACK 1
-- struct rb_node_s * rb_right;
-- struct rb_node_s * rb_left;
--}
--rb_node_t;
--
--typedef struct rb_root_s
--{
-- struct rb_node_s * rb_node;
--}
--rb_root_t;
--
--#define RB_ROOT (rb_root_t) { NULL, }
--#define rb_entry(ptr, type, member) \
-- ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
--
--extern void rb_insert_color(rb_node_t *, rb_root_t *);
--extern void rb_erase(rb_node_t *, rb_root_t *);
--
--static inline void rb_link_node(rb_node_t * node, rb_node_t * parent, rb_node_t ** rb_link)
--{
-- node->rb_parent = parent;
-- node->rb_color = RB_RED;
-- node->rb_left = node->rb_right = NULL;
--
-- *rb_link = node;
--}
--
--#endif /* _LINUX_RBTREE_H */
-+#endif /* __MTD_COMPAT_RBTREE_H__ */
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/suspend.h linux/include/linux/suspend.h
---- linux-mips-2.4.24-pre2/include/linux/suspend.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/include/linux/suspend.h 2004-11-17 18:17:59.450251448 +0100
-@@ -0,0 +1,10 @@
-+/* $Id$ */
-+
-+#ifndef __MTD_COMPAT_VERSION_H__
-+#include <linux/version.h>
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+#include_next <linux/suspend.h>
-+#endif
-+
-+#endif /* __MTD_COMPAT_VERSION_H__ */
-diff -Nurb linux-mips-2.4.24-pre2/include/linux/workqueue.h linux/include/linux/workqueue.h
---- linux-mips-2.4.24-pre2/include/linux/workqueue.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/include/linux/workqueue.h 2004-11-17 18:17:59.451251296 +0100
-@@ -0,0 +1,21 @@
-+/*
-+ * 2.5 compatibility
-+ * $Id$
-+ */
-+
-+#ifndef __MTD_COMPAT_WORKQUEUE_H__
-+#define __MTD_COMPAT_WORKQUEUE_H__
-+
-+#include <linux/version.h>
-+
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,40)
-+#include_next <linux/workqueue.h>
-+#else
-+#include <linux/tqueue.h>
-+#define work_struct tq_struct
-+#define schedule_work(x) schedule_task(x)
-+#define flush_scheduled_work flush_scheduled_tasks
-+#define INIT_WORK(x,y,z) INIT_TQUEUE(x,y,z)
-+#endif
-+
-+#endif /* __MTD_COMPAT_WORKQUEUE_H__ */
diff --git a/linux/linux-mtx-1-2.4.24/02-mtd-mtx-1-map.diff b/linux/linux-mtx-1-2.4.24/02-mtd-mtx-1-map.diff
deleted file mode 100644
index ba24bb1381..0000000000
--- a/linux/linux-mtx-1-2.4.24/02-mtd-mtx-1-map.diff
+++ /dev/null
@@ -1,248 +0,0 @@
-diff -Nurb linux/drivers/mtd/maps/Config.in linux-mips-2.4.24-pre2+mtd-2004-01-27+mtx-map/drivers/mtd/maps/Config.in
---- linux/drivers/mtd/maps/Config.in 2004-11-17 18:17:59.049312400 +0100
-+++ linux-mips-2.4.24-pre2+mtd-2004-01-27+mtx-map/drivers/mtd/maps/Config.in 2004-11-17 18:12:26.000000000 +0100
-@@ -80,6 +80,7 @@
- bool ' Db1x00 boot flash device' CONFIG_MTD_DB1X00_BOOT
- bool ' Db1x00 user flash device (2nd bank)' CONFIG_MTD_DB1X00_USER
- fi
-+ dep_tristate ' MTX-1 flash device' CONFIG_MTD_MTX1 $CONFIG_MIPS_MTX1
- dep_tristate ' Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board' CONFIG_MTD_CSTM_MIPS_IXX $CONFIG_MTD_CFI $CONFIG_MTD_JEDEC $CONFIG_MTD_PARTITIONS
- if [ "$CONFIG_MTD_CSTM_MIPS_IXX" = "y" -o "$CONFIG_MTD_CSTM_MIPS_IXX" = "m" ]; then
- hex ' Physical start address of flash mapping' CONFIG_MTD_CSTM_MIPS_IXX_START 0x8000000
-diff -Nurb linux/drivers/mtd/maps/Makefile linux-mips-2.4.24-pre2+mtd-2004-01-27+mtx-map/drivers/mtd/maps/Makefile
---- linux/drivers/mtd/maps/Makefile 2004-11-17 18:17:59.051312096 +0100
-+++ linux-mips-2.4.24-pre2+mtd-2004-01-27+mtx-map/drivers/mtd/maps/Makefile 2004-11-17 18:12:26.000000000 +0100
-@@ -49,6 +49,7 @@
- obj-$(CONFIG_MTD_PCI) += pci.o
- obj-$(CONFIG_MTD_PB1XXX) += pb1xxx-flash.o
- obj-$(CONFIG_MTD_DB1X00) += db1x00-flash.o
-+obj-$(CONFIG_MTD_MTX1) += mtx-1.o
- obj-$(CONFIG_MTD_LASAT) += lasat.o
- obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o
- obj-$(CONFIG_MTD_EDB7312) += edb7312.o
-diff -Nurb linux/drivers/mtd/maps/mtx-1.c linux-mips-2.4.24-pre2+mtd-2004-01-27+mtx-map/drivers/mtd/maps/mtx-1.c
---- linux/drivers/mtd/maps/mtx-1.c 2004-11-17 18:17:02.689880336 +0100
-+++ linux-mips-2.4.24-pre2+mtd-2004-01-27+mtx-map/drivers/mtd/maps/mtx-1.c 2004-11-17 18:12:26.000000000 +0100
-@@ -1,166 +1,78 @@
- /*
- * Flash memory access on 4G Systems MTX-1 board
- *
-- * (C) 2003 Pete Popov <ppopov@mvista.com>
-- * Bruno Randolf <bruno.randolf@4g-systems.de>
-+ * (C) Bruno Randolf (4G Systeme GmbH) <bruno.randolf@4g-systems.biz>
- */
-
- #include <linux/config.h>
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/partitions.h>
-
- #include <asm/io.h>
--#include <asm/au1000.h>
-
--#ifdef DEBUG_RW
--#define DBG(x...) printk(x)
--#else
--#define DBG(x...)
--#endif
--
--#ifdef CONFIG_MIPS_MTX1
- #define WINDOW_ADDR 0x1E000000
- #define WINDOW_SIZE 0x2000000
--#endif
--
--__u8 physmap_read8(struct map_info *map, unsigned long ofs)
--{
-- __u8 ret;
-- ret = __raw_readb(map->map_priv_1 + ofs);
-- DBG("read8 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--__u16 physmap_read16(struct map_info *map, unsigned long ofs)
--{
-- __u16 ret;
-- ret = __raw_readw(map->map_priv_1 + ofs);
-- DBG("read16 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--__u32 physmap_read32(struct map_info *map, unsigned long ofs)
--{
-- __u32 ret;
-- ret = __raw_readl(map->map_priv_1 + ofs);
-- DBG("read32 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- DBG("physmap_copy from %x to %x\n", (unsigned)from, (unsigned)to);
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void physmap_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- DBG("write8 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- DBG("write16 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- DBG("write32 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- DBG("physmap_copy_to %x from %x\n", (unsigned)to, (unsigned)from);
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
--
--
-+#define BUSWIDTH 4
-
- static struct map_info mtx1_map = {
-- name: "MTX-1 flash",
-- read8: physmap_read8,
-- read16: physmap_read16,
-- read32: physmap_read32,
-- copy_from: physmap_copy_from,
-- write8: physmap_write8,
-- write16: physmap_write16,
-- write32: physmap_write32,
-- copy_to: physmap_copy_to,
-+ .name = "MTX-1 flash",
-+ .size = WINDOW_SIZE,
-+ .buswidth = BUSWIDTH,
-+ .phys = WINDOW_ADDR
- };
-
--
--static unsigned long flash_size = 0x01000000;
--static unsigned char flash_buswidth = 4;
- static struct mtd_partition mtx1_partitions[] = {
- {
-- name: "user fs",
-- size: 0x1c00000,
-- offset: 0,
-+ .name = "user fs",
-+ .size = 0x1c00000,
-+ .offset = 0,
- },{
-- name: "yamon",
-- size: 0x0100000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE
-+ .name = "yamon",
-+ .size = 0x0100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
- },{
-- name: "raw kernel",
-- size: 0x02c0000,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "raw kernel",
-+ .size = 0x02c0000,
-+ .offset = MTDPART_OFS_APPEND,
- },{
-- name: "yamon env vars",
-- size: 0x0040000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE
-+ .name = "yamon environment",
-+ .size = 0x0040000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
- }
- };
-
--
--#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
--
--static struct mtd_partition *parsed_parts;
- static struct mtd_info *mymtd;
-
- int __init mtx1_mtd_init(void)
- {
-- struct mtd_partition *parts;
-- int nb_parts = 0;
-- char *part_type;
-+ printk(KERN_NOTICE "MTX-1 flash: probing %d-bit flash bus at %x\n",
-+ mtx1_map.buswidth*8, WINDOW_ADDR);
-
-- /* Default flash buswidth */
-- mtx1_map.buswidth = flash_buswidth;
-+ mtx1_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-+ if (!mtx1_map.virt) {
-+ printk("mtx_mtd_init: failed to ioremap\n");
-+ return -EIO;
-+ }
-+
-+ simple_map_init(&mtx1_map);
-
-- /*
-- * Static partition definition selection
-- */
-- part_type = "static";
-- parts = mtx1_partitions;
-- nb_parts = NB_OF(mtx1_partitions);
-- mtx1_map.size = flash_size;
--
-- /*
-- * Now let's probe for the actual flash. Do it here since
-- * specific machine settings might have been set above.
-- */
-- printk(KERN_NOTICE "MTX-1 flash: probing %d-bit flash bus\n",
-- mtx1_map.buswidth*8);
-- mtx1_map.map_priv_1 =
-- (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
- mymtd = do_map_probe("cfi_probe", &mtx1_map);
-- if (!mymtd) return -ENXIO;
-- mymtd->module = THIS_MODULE;
-+ if (!mymtd) {
-+ iounmap(mtx1_map.virt);
-+ return -ENXIO;
-+ }
-+
-+ mymtd->owner = THIS_MODULE;
-
-- add_mtd_partitions(mymtd, parts, nb_parts);
-- return 0;
-+ return add_mtd_partitions(mymtd, mtx1_partitions, ARRAY_SIZE(mtx1_partitions));
- }
-
- static void __exit mtx1_mtd_cleanup(void)
-@@ -168,14 +80,14 @@
- if (mymtd) {
- del_mtd_partitions(mymtd);
- map_destroy(mymtd);
-- if (parsed_parts)
-- kfree(parsed_parts);
- }
-+ if (mtx1_map.virt)
-+ iounmap(mtx1_map.virt);
- }
-
- module_init(mtx1_mtd_init);
- module_exit(mtx1_mtd_cleanup);
-
--MODULE_AUTHOR("Pete Popov");
-+MODULE_AUTHOR("Bruno Randolf <bruno.randolf@4g-systems.biz>");
- MODULE_DESCRIPTION("MTX-1 CFI map driver");
- MODULE_LICENSE("GPL");
-
diff --git a/linux/linux-mtx-1-2.4.24/03-mtd-erase-compiler-bug.diff b/linux/linux-mtx-1-2.4.24/03-mtd-erase-compiler-bug.diff
deleted file mode 100644
index 9e310bf327..0000000000
--- a/linux/linux-mtx-1-2.4.24/03-mtd-erase-compiler-bug.diff
+++ /dev/null
@@ -1,21 +0,0 @@
---- linux-mips-2.4.24-pre2+mtd-2004-01-27/fs/jffs2/erase.c 2004-11-17 18:17:59.000000000 +0100
-+++ linux/fs/jffs2/erase.c 2004-11-17 18:44:52.260067088 +0100
-@@ -365,11 +365,13 @@
- jeb->dirty_size = 0;
- jeb->wasted_size = 0;
- } else {
-- struct jffs2_unknown_node marker = {
-- .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
-- .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
-- .totlen = cpu_to_je32(c->cleanmarker_size)
-- };
-+ /* compiler workaround, structure was not initialized before
-+ on mipsel cross compilers
-+ fix by Eugene.Wisor@flukenetworks.com */
-+ struct jffs2_unknown_node marker;
-+ marker.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ marker.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
-+ marker.totlen = cpu_to_je32(c->cleanmarker_size);
-
- marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4));
-
diff --git a/linux/linux-mtx-1-2.4.24/04-zboot-2.4.24.patch b/linux/linux-mtx-1-2.4.24/04-zboot-2.4.24.patch
deleted file mode 100644
index 85f5fc3aa3..0000000000
--- a/linux/linux-mtx-1-2.4.24/04-zboot-2.4.24.patch
+++ /dev/null
@@ -1,5286 +0,0 @@
-diff -Naru linux/arch/mips/Makefile linux-new/arch/mips/Makefile
---- linux/arch/mips/Makefile 2003-10-22 02:58:37.000000000 -0400
-+++ linux-new/arch/mips/Makefile 2003-12-18 14:26:20.000000000 -0500
-@@ -724,15 +724,21 @@
- endif
-
- MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
-+MAKEZBOOT = $(MAKE) -C arch/$(ARCH)/zboot
-+BOOT_TARGETS = zImage zImage.initrd zImage.flash
-
- vmlinux.ecoff: vmlinux
- @$(MAKEBOOT) $@
-
-+ $(BOOT_TARGETS): vmlinux
-+ @$(MAKEZBOOT) $@
-+
- vmlinux.srec: vmlinux
- @$(MAKEBOOT) $@
-
- archclean:
- @$(MAKEBOOT) clean
-+ @$(MAKEZBOOT) clean
- rm -f arch/$(ARCH)/ld.script
- $(MAKE) -C arch/$(ARCH)/tools clean
- $(MAKE) -C arch/mips/baget clean
-diff -Naru linux/arch/mips/zboot/common/au1k_uart.c linux-new/arch/mips/zboot/common/au1k_uart.c
---- linux/arch/mips/zboot/common/au1k_uart.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/common/au1k_uart.c 2003-12-18 14:26:20.000000000 -0500
-@@ -0,0 +1,103 @@
-+/*
-+ * BRIEF MODULE DESCRIPTION
-+ * Simple Au1000 uart routines.
-+ *
-+ * Copyright 2001 MontaVista Software Inc.
-+ * Author: MontaVista Software, Inc.
-+ * ppopov@mvista.com or source@mvista.com
-+ *
-+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
-+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * 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/config.h>
-+#include <asm/io.h>
-+#include <asm/au1000.h>
-+#include "ns16550.h"
-+
-+typedef unsigned char uint8;
-+typedef unsigned int uint32;
-+
-+#define UART16550_BAUD_2400 2400
-+#define UART16550_BAUD_4800 4800
-+#define UART16550_BAUD_9600 9600
-+#define UART16550_BAUD_19200 19200
-+#define UART16550_BAUD_38400 38400
-+#define UART16550_BAUD_57600 57600
-+#define UART16550_BAUD_115200 115200
-+
-+#define UART16550_PARITY_NONE 0
-+#define UART16550_PARITY_ODD 0x08
-+#define UART16550_PARITY_EVEN 0x18
-+#define UART16550_PARITY_MARK 0x28
-+#define UART16550_PARITY_SPACE 0x38
-+
-+#define UART16550_DATA_5BIT 0x0
-+#define UART16550_DATA_6BIT 0x1
-+#define UART16550_DATA_7BIT 0x2
-+#define UART16550_DATA_8BIT 0x3
-+
-+#define UART16550_STOP_1BIT 0x0
-+#define UART16550_STOP_2BIT 0x4
-+
-+/* It would be nice if we had a better way to do this.
-+ * It could be a variable defined in one of the board specific files.
-+ */
-+#undef UART_BASE
-+#ifdef CONFIG_COGENT_CSB250
-+#define UART_BASE UART3_ADDR
-+#else
-+#define UART_BASE UART0_ADDR
-+#endif
-+
-+/* memory-mapped read/write of the port */
-+#define UART16550_READ(y) (readl(UART_BASE + y) & 0xff)
-+#define UART16550_WRITE(y,z) (writel(z&0xff, UART_BASE + y))
-+
-+/*
-+ * We use uart 0, which is already initialized by
-+ * yamon.
-+ */
-+volatile struct NS16550 *
-+serial_init(int chan)
-+{
-+ volatile struct NS16550 *com_port;
-+ com_port = (struct NS16550 *) UART_BASE;
-+ return (com_port);
-+}
-+
-+void
-+serial_putc(volatile struct NS16550 *com_port, unsigned char c)
-+{
-+ while ((UART16550_READ(UART_LSR)&0x40) == 0);
-+ UART16550_WRITE(UART_TX, c);
-+}
-+
-+unsigned char
-+serial_getc(volatile struct NS16550 *com_port)
-+{
-+ while((UART16550_READ(UART_LSR) & 0x1) == 0);
-+ return UART16550_READ(UART_RX);
-+}
-+
-+int
-+serial_tstc(volatile struct NS16550 *com_port)
-+{
-+ return((UART16550_READ(UART_LSR) & LSR_DR) != 0);
-+}
-diff -Naru linux/arch/mips/zboot/common/ctype.c linux-new/arch/mips/zboot/common/ctype.c
---- linux/arch/mips/zboot/common/ctype.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/common/ctype.c 2003-12-18 14:26:20.000000000 -0500
-@@ -0,0 +1,35 @@
-+/*
-+ * linux/lib/ctype.c
-+ *
-+ * Copyright (C) 1991, 1992 Linus Torvalds
-+ */
-+
-+#include <linux/ctype.h>
-+
-+unsigned char _ctype[] = {
-+_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
-+_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
-+_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
-+_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
-+_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
-+_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
-+_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
-+_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
-+_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
-+_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
-+_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
-+_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
-+_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
-+_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
-+_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
-+_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
-+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
-+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
-+_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
-+_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
-+_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
-+_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
-+_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
-+_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
-+
-+
-diff -Naru linux/arch/mips/zboot/common/dummy.c linux-new/arch/mips/zboot/common/dummy.c
---- linux/arch/mips/zboot/common/dummy.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/common/dummy.c 2003-12-18 14:26:20.000000000 -0500
-@@ -0,0 +1,4 @@
-+int main(void)
-+{
-+ return 0;
-+}
-diff -Naru linux/arch/mips/zboot/common/Makefile linux-new/arch/mips/zboot/common/Makefile
---- linux/arch/mips/zboot/common/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/common/Makefile 2003-12-18 14:26:20.000000000 -0500
-@@ -0,0 +1,27 @@
-+#
-+# arch/mips/zboot/common/Makefile
-+#
-+# This file is subject to the terms and conditions of the GNU General Public
-+# License. See the file "COPYING" in the main directory of this archive
-+# for more details.
-+#
-+# Tom Rini January 2001
-+#
-+
-+.c.s:
-+ $(CC) $(CFLAGS) -S -o $*.s $<
-+.s.o:
-+ $(AS) -o $*.o $<
-+.c.o:
-+ $(CC) $(CFLAGS) -c -o $*.o $<
-+.S.s:
-+ $(CPP) $(AFLAGS) -o $*.o $<
-+.S.o:
-+ $(CC) $(AFLAGS) -c -o $*.o $<
-+
-+clean:
-+ rm -rf *.o
-+
-+OBJCOPY_ARGS = -O elf32-tradlittlemips
-+
-+include $(TOPDIR)/Rules.make
-diff -Naru linux/arch/mips/zboot/common/misc-common.c linux-new/arch/mips/zboot/common/misc-common.c
---- linux/arch/mips/zboot/common/misc-common.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/common/misc-common.c 2003-12-18 14:26:20.000000000 -0500
-@@ -0,0 +1,437 @@
-+/*
-+ * arch/mips/zboot/common/misc-common.c
-+ *
-+ * Misc. bootloader code (almost) all platforms can use
-+ *
-+ * Author: Johnnie Peters <jpeters@mvista.com>
-+ * Editor: Tom Rini <trini@mvista.com>
-+ *
-+ * Derived from arch/ppc/boot/prep/misc.c
-+ *
-+ * Ported by Pete Popov <ppopov@mvista.com> to
-+ * support mips board(s). I also got rid of the vga console
-+ * code.
-+ *
-+ * Copyright 2000-2001 MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
-+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * 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/config.h>
-+#include "zlib.h"
-+#include <stdarg.h>
-+
-+extern char *avail_ram;
-+extern char *end_avail;
-+extern char _end[];
-+
-+void puts(const char *);
-+void putc(const char c);
-+void puthex(unsigned long val);
-+void _bcopy(char *src, char *dst, int len);
-+void gunzip(void *, int, unsigned char *, int *);
-+static int _cvt(unsigned long val, char *buf, long radix, char *digits);
-+
-+void _vprintk(void(*)(const char), const char *, va_list ap);
-+
-+struct NS16550 *com_port;
-+
-+int serial_tstc(volatile struct NS16550 *);
-+unsigned char serial_getc(volatile struct NS16550 *);
-+void serial_putc(volatile struct NS16550 *, unsigned char);
-+
-+void pause(void)
-+{
-+ puts("pause\n");
-+}
-+
-+void exit(void)
-+{
-+ puts("exit\n");
-+ while(1);
-+}
-+
-+int tstc(void)
-+{
-+ return (serial_tstc(com_port));
-+}
-+
-+int getc(void)
-+{
-+ while (1) {
-+ if (serial_tstc(com_port))
-+ return (serial_getc(com_port));
-+ }
-+}
-+
-+void
-+putc(const char c)
-+{
-+ int x,y;
-+
-+ serial_putc(com_port, c);
-+ if ( c == '\n' )
-+ serial_putc(com_port, '\r');
-+}
-+
-+void puts(const char *s)
-+{
-+ char c;
-+ while ( ( c = *s++ ) != '\0' ) {
-+ serial_putc(com_port, c);
-+ if ( c == '\n' ) serial_putc(com_port, '\r');
-+ }
-+}
-+
-+void error(char *x)
-+{
-+ puts("\n\n");
-+ puts(x);
-+ puts("\n\n -- System halted");
-+
-+ while(1); /* Halt */
-+}
-+
-+void *zalloc(void *x, unsigned items, unsigned size)
-+{
-+ void *p = avail_ram;
-+
-+ size *= items;
-+ size = (size + 7) & -8;
-+ avail_ram += size;
-+ if (avail_ram > end_avail) {
-+ puts("oops... out of memory\n");
-+ pause();
-+ }
-+ return p;
-+}
-+
-+void zfree(void *x, void *addr, unsigned nb)
-+{
-+}
-+
-+#define HEAD_CRC 2
-+#define EXTRA_FIELD 4
-+#define ORIG_NAME 8
-+#define COMMENT 0x10
-+#define RESERVED 0xe0
-+
-+#define DEFLATED 8
-+
-+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
-+{
-+ z_stream s;
-+ int r, i, flags;
-+
-+ /* skip header */
-+ i = 10;
-+ flags = src[3];
-+ if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
-+ puts("bad gzipped data\n");
-+ exit();
-+ }
-+ if ((flags & EXTRA_FIELD) != 0)
-+ i = 12 + src[10] + (src[11] << 8);
-+ if ((flags & ORIG_NAME) != 0)
-+ while (src[i++] != 0)
-+ ;
-+ if ((flags & COMMENT) != 0)
-+ while (src[i++] != 0)
-+ ;
-+ if ((flags & HEAD_CRC) != 0)
-+ i += 2;
-+ if (i >= *lenp) {
-+ puts("gunzip: ran out of data in header\n");
-+ exit();
-+ }
-+
-+ s.zalloc = zalloc;
-+ s.zfree = zfree;
-+ r = inflateInit2(&s, -MAX_WBITS);
-+ if (r != Z_OK) {
-+ puts("inflateInit2 returned %d\n");
-+ exit();
-+ }
-+ s.next_in = src + i;
-+ s.avail_in = *lenp - i;
-+ s.next_out = dst;
-+ s.avail_out = dstlen;
-+ r = inflate(&s, Z_FINISH);
-+ if (r != Z_OK && r != Z_STREAM_END) {
-+ puts("inflate returned %d\n");
-+ exit();
-+ }
-+ *lenp = s.next_out - (unsigned char *) dst;
-+ inflateEnd(&s);
-+}
-+
-+void
-+puthex(unsigned long val)
-+{
-+
-+ unsigned char buf[10];
-+ int i;
-+ for (i = 7; i >= 0; i--)
-+ {
-+ buf[i] = "0123456789ABCDEF"[val & 0x0F];
-+ val >>= 4;
-+ }
-+ buf[8] = '\0';
-+ puts(buf);
-+}
-+
-+#define FALSE 0
-+#define TRUE 1
-+
-+void
-+_printk(char const *fmt, ...)
-+{
-+ va_list ap;
-+
-+ va_start(ap, fmt);
-+ _vprintk(putc, fmt, ap);
-+ va_end(ap);
-+ return;
-+}
-+
-+#define is_digit(c) ((c >= '0') && (c <= '9'))
-+
-+void
-+_vprintk(void(*putc)(const char), const char *fmt0, va_list ap)
-+{
-+ char c, sign, *cp = 0;
-+ int left_prec, right_prec, zero_fill, length = 0, pad, pad_on_right;
-+ char buf[32];
-+ long val;
-+ while ((c = *fmt0++))
-+ {
-+ if (c == '%')
-+ {
-+ c = *fmt0++;
-+ left_prec = right_prec = pad_on_right = 0;
-+ if (c == '-')
-+ {
-+ c = *fmt0++;
-+ pad_on_right++;
-+ }
-+ if (c == '0')
-+ {
-+ zero_fill = TRUE;
-+ c = *fmt0++;
-+ } else
-+ {
-+ zero_fill = FALSE;
-+ }
-+ while (is_digit(c))
-+ {
-+ left_prec = (left_prec * 10) + (c - '0');
-+ c = *fmt0++;
-+ }
-+ if (c == '.')
-+ {
-+ c = *fmt0++;
-+ zero_fill++;
-+ while (is_digit(c))
-+ {
-+ right_prec = (right_prec * 10) + (c - '0');
-+ c = *fmt0++;
-+ }
-+ } else
-+ {
-+ right_prec = left_prec;
-+ }
-+ sign = '\0';
-+ switch (c)
-+ {
-+ case 'd':
-+ case 'x':
-+ case 'X':
-+ val = va_arg(ap, long);
-+ switch (c)
-+ {
-+ case 'd':
-+ if (val < 0)
-+ {
-+ sign = '-';
-+ val = -val;
-+ }
-+ length = _cvt(val, buf, 10, "0123456789");
-+ break;
-+ case 'x':
-+ length = _cvt(val, buf, 16, "0123456789abcdef");
-+ break;
-+ case 'X':
-+ length = _cvt(val, buf, 16, "0123456789ABCDEF");
-+ break;
-+ }
-+ cp = buf;
-+ break;
-+ case 's':
-+ cp = va_arg(ap, char *);
-+ length = strlen(cp);
-+ break;
-+ case 'c':
-+ c = va_arg(ap, long /*char*/);
-+ (*putc)(c);
-+ continue;
-+ default:
-+ (*putc)('?');
-+ }
-+ pad = left_prec - length;
-+ if (sign != '\0')
-+ {
-+ pad--;
-+ }
-+ if (zero_fill)
-+ {
-+ c = '0';
-+ if (sign != '\0')
-+ {
-+ (*putc)(sign);
-+ sign = '\0';
-+ }
-+ } else
-+ {
-+ c = ' ';
-+ }
-+ if (!pad_on_right)
-+ {
-+ while (pad-- > 0)
-+ {
-+ (*putc)(c);
-+ }
-+ }
-+ if (sign != '\0')
-+ {
-+ (*putc)(sign);
-+ }
-+ while (length-- > 0)
-+ {
-+ (*putc)(c = *cp++);
-+ if (c == '\n')
-+ {
-+ (*putc)('\r');
-+ }
-+ }
-+ if (pad_on_right)
-+ {
-+ while (pad-- > 0)
-+ {
-+ (*putc)(c);
-+ }
-+ }
-+ } else
-+ {
-+ (*putc)(c);
-+ if (c == '\n')
-+ {
-+ (*putc)('\r');
-+ }
-+ }
-+ }
-+}
-+
-+int
-+_cvt(unsigned long val, char *buf, long radix, char *digits)
-+{
-+ char temp[80];
-+ char *cp = temp;
-+ int length = 0;
-+ if (val == 0)
-+ { /* Special case */
-+ *cp++ = '0';
-+ } else
-+ while (val)
-+ {
-+ *cp++ = digits[val % radix];
-+ val /= radix;
-+ }
-+ while (cp != temp)
-+ {
-+ *buf++ = *--cp;
-+ length++;
-+ }
-+ *buf = '\0';
-+ return (length);
-+}
-+
-+void
-+_dump_buf_with_offset(unsigned char *p, int s, unsigned char *base)
-+{
-+ int i, c;
-+ if ((unsigned int)s > (unsigned int)p)
-+ {
-+ s = (unsigned int)s - (unsigned int)p;
-+ }
-+ while (s > 0)
-+ {
-+ if (base)
-+ {
-+ _printk("%06X: ", (int)p - (int)base);
-+ } else
-+ {
-+ _printk("%06X: ", p);
-+ }
-+ for (i = 0; i < 16; i++)
-+ {
-+ if (i < s)
-+ {
-+ _printk("%02X", p[i] & 0xFF);
-+ } else
-+ {
-+ _printk(" ");
-+ }
-+ if ((i % 2) == 1) _printk(" ");
-+ if ((i % 8) == 7) _printk(" ");
-+ }
-+ _printk(" |");
-+ for (i = 0; i < 16; i++)
-+ {
-+ if (i < s)
-+ {
-+ c = p[i] & 0xFF;
-+ if ((c < 0x20) || (c >= 0x7F)) c = '.';
-+ } else
-+ {
-+ c = ' ';
-+ }
-+ _printk("%c", c);
-+ }
-+ _printk("|\n");
-+ s -= 16;
-+ p += 16;
-+ }
-+}
-+
-+void
-+_dump_buf(unsigned char *p, int s)
-+{
-+ _printk("\n");
-+ _dump_buf_with_offset(p, s, 0);
-+}
-+
-+/*
-+ * Local variables:
-+ * c-indent-level: 8
-+ * c-basic-offset: 8
-+ * tab-width: 8
-+ * End:
-+ */
-diff -Naru linux/arch/mips/zboot/common/misc-simple.c linux-new/arch/mips/zboot/common/misc-simple.c
---- linux/arch/mips/zboot/common/misc-simple.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/common/misc-simple.c 2003-12-18 14:26:20.000000000 -0500
-@@ -0,0 +1,127 @@
-+/*
-+ * arch/mips/zboot/common/misc-simple.c
-+ *
-+ * Misc. bootloader code for many machines. This assumes you have are using
-+ * a 6xx/7xx/74xx CPU in your machine. This assumes the chunk of memory
-+ * below 8MB is free. Finally, it assumes you have a NS16550-style uart for
-+ * your serial console. If a machine meets these requirements, it can quite
-+ * likely use this code during boot.
-+ *
-+ * Author: Matt Porter <mporter@mvista.com>
-+ * Derived from arch/ppc/boot/prep/misc.c
-+ *
-+ * Copyright 2001 MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/elf.h>
-+#include <linux/config.h>
-+
-+#include <asm/page.h>
-+#include <asm/processor.h>
-+#include <asm/mmu.h>
-+
-+#include "zlib.h"
-+
-+extern struct NS16550 *com_port;
-+
-+char *avail_ram;
-+char *end_avail;
-+extern char _end[];
-+char *zimage_start;
-+
-+#ifdef CONFIG_CMDLINE
-+#define CMDLINE CONFIG_CMDLINE
-+#else
-+#define CMDLINE ""
-+#endif
-+char cmd_preset[] = CMDLINE;
-+char cmd_buf[256];
-+char *cmd_line = cmd_buf;
-+
-+/* The linker tells us where the image is.
-+*/
-+extern unsigned char __image_begin, __image_end;
-+extern unsigned char __ramdisk_begin, __ramdisk_end;
-+unsigned long initrd_size;
-+
-+extern void puts(const char *);
-+extern void putc(const char c);
-+extern void puthex(unsigned long val);
-+extern void *memcpy(void * __dest, __const void * __src,
-+ __kernel_size_t __n);
-+extern void gunzip(void *, int, unsigned char *, int *);
-+extern void udelay(long delay);
-+extern int tstc(void);
-+extern int getc(void);
-+extern volatile struct NS16550 *serial_init(int chan);
-+
-+void
-+decompress_kernel(unsigned long load_addr, int num_words,
-+ unsigned long cksum, unsigned long *sp)
-+{
-+ int timer = 0;
-+ extern unsigned long start;
-+ char *cp, ch;
-+ int i;
-+ int zimage_size;
-+
-+ com_port = (struct NS16550 *)serial_init(0);
-+
-+ initrd_size = (unsigned long)(&__ramdisk_end) -
-+ (unsigned long)(&__ramdisk_begin);
-+
-+ /*
-+ * Reveal where we were loaded at and where we
-+ * were relocated to.
-+ */
-+ puts("loaded at: "); puthex(load_addr);
-+ puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n");
-+ if ( (unsigned long)load_addr != (unsigned long)&start )
-+ {
-+ puts("relocated to: "); puthex((unsigned long)&start);
-+ puts(" ");
-+ puthex((unsigned long)((unsigned long)&start + (4*num_words)));
-+ puts("\n");
-+ }
-+
-+ /*
-+ * We link ourself to an arbitrary low address. When we run, we
-+ * relocate outself to that address. __image_being points to
-+ * the part of the image where the zImage is. -- Tom
-+ */
-+ zimage_start = (char *)(unsigned long)(&__image_begin);
-+ zimage_size = (unsigned long)(&__image_end) -
-+ (unsigned long)(&__image_begin);
-+
-+ /*
-+ * The zImage and initrd will be between start and _end, so they've
-+ * already been moved once. We're good to go now. -- Tom
-+ */
-+ puts("zimage at: "); puthex((unsigned long)zimage_start);
-+ puts(" "); puthex((unsigned long)(zimage_size+zimage_start));
-+ puts("\n");
-+
-+ if ( initrd_size ) {
-+ puts("initrd at: ");
-+ puthex((unsigned long)(&__ramdisk_begin));
-+ puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n");
-+ }
-+
-+ /* assume the chunk below 8M is free */
-+ avail_ram = (char *)AVAIL_RAM_START;
-+ end_avail = (char *)AVAIL_RAM_END;
-+
-+ /* Display standard Linux/MIPS boot prompt for kernel args */
-+ puts("Uncompressing Linux at load address ");
-+ puthex(LOADADDR);
-+ puts("\n");
-+ /* I don't like this hard coded gunzip size (fixme) */
-+ gunzip((void *)LOADADDR, 0x400000, zimage_start, &zimage_size);
-+ puts("Now booting the kernel\n");
-+}
-diff -Naru linux/arch/mips/zboot/common/no_initrd.c linux-new/arch/mips/zboot/common/no_initrd.c
---- linux/arch/mips/zboot/common/no_initrd.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/common/no_initrd.c 2003-12-18 14:26:20.000000000 -0500
-@@ -0,0 +1,2 @@
-+char initrd_data[1];
-+int initrd_len = 0;
-diff -Naru linux/arch/mips/zboot/common/ns16550.c linux-new/arch/mips/zboot/common/ns16550.c
---- linux/arch/mips/zboot/common/ns16550.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/common/ns16550.c 2003-12-18 14:26:20.000000000 -0500
-@@ -0,0 +1,57 @@
-+/*
-+ * NS16550 support
-+ */
-+
-+#include <linux/config.h>
-+#include <asm/serial.h>
-+#include "ns16550.h"
-+
-+typedef struct NS16550 *NS16550_t;
-+
-+const NS16550_t COM_PORTS[] = { (NS16550_t) COM1,
-+ (NS16550_t) COM2,
-+ (NS16550_t) COM3,
-+ (NS16550_t) COM4 };
-+
-+volatile struct NS16550 *
-+serial_init(int chan)
-+{
-+ volatile struct NS16550 *com_port;
-+ com_port = (struct NS16550 *) COM_PORTS[chan];
-+ /* See if port is present */
-+ com_port->lcr = 0x00;
-+ com_port->ier = 0xFF;
-+#if 0
-+ if (com_port->ier != 0x0F) return ((struct NS16550 *)0);
-+#endif
-+ com_port->ier = 0x00;
-+ com_port->lcr = 0x80; /* Access baud rate */
-+#ifdef CONFIG_SERIAL_CONSOLE_NONSTD
-+ com_port->dll = (BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD);
-+ com_port->dlm = (BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD) >> 8;
-+#endif
-+ com_port->lcr = 0x03; /* 8 data, 1 stop, no parity */
-+ com_port->mcr = 0x03; /* RTS/DTR */
-+ com_port->fcr = 0x07; /* Clear & enable FIFOs */
-+ return (com_port);
-+}
-+
-+void
-+serial_putc(volatile struct NS16550 *com_port, unsigned char c)
-+{
-+ while ((com_port->lsr & LSR_THRE) == 0) ;
-+ com_port->thr = c;
-+}
-+
-+unsigned char
-+serial_getc(volatile struct NS16550 *com_port)
-+{
-+ while ((com_port->lsr & LSR_DR) == 0) ;
-+ return (com_port->rbr);
-+}
-+
-+int
-+serial_tstc(volatile struct NS16550 *com_port)
-+{
-+ return ((com_port->lsr & LSR_DR) != 0);
-+}
---- linux/arch/mips/zboot/common/string.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/common/string.c 2003-12-18 17:11:10.000000000 -0500
-@@ -0,0 +1,497 @@
-+/*
-+ * linux/lib/string.c
-+ *
-+ * Copyright (C) 1991, 1992 Linus Torvalds
-+ */
-+
-+/*
-+ * stupid library routines.. The optimized versions should generally be found
-+ * as inline code in <asm-xx/string.h>
-+ *
-+ * These are buggy as well..
-+ *
-+ * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>
-+ * - Added strsep() which will replace strtok() soon (because strsep() is
-+ * reentrant and should be faster). Use only strsep() in new code, please.
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/string.h>
-+#include <linux/ctype.h>
-+
-+/**
-+ * strnicmp - Case insensitive, length-limited string comparison
-+ * @s1: One string
-+ * @s2: The other string
-+ * @len: the maximum number of characters to compare
-+ */
-+int strnicmp(const char *s1, const char *s2, size_t len)
-+{
-+ /* Yes, Virginia, it had better be unsigned */
-+ unsigned char c1, c2;
-+
-+ c1 = 0; c2 = 0;
-+ if (len) {
-+ do {
-+ c1 = *s1; c2 = *s2;
-+ s1++; s2++;
-+ if (!c1)
-+ break;
-+ if (!c2)
-+ break;
-+ if (c1 == c2)
-+ continue;
-+ c1 = tolower(c1);
-+ c2 = tolower(c2);
-+ if (c1 != c2)
-+ break;
-+ } while (--len);
-+ }
-+ return (int)c1 - (int)c2;
-+}
-+
-+char * ___strtok;
-+
-+#ifndef __HAVE_ARCH_STRCPY
-+/**
-+ * strcpy - Copy a %NUL terminated string
-+ * @dest: Where to copy the string to
-+ * @src: Where to copy the string from
-+ */
-+char * strcpy(char * dest,const char *src)
-+{
-+ char *tmp = dest;
-+
-+ while ((*dest++ = *src++) != '\0')
-+ /* nothing */;
-+ return tmp;
-+}
-+#endif
-+
-+#ifndef __HAVE_ARCH_STRNCPY
-+/**
-+ * strncpy - Copy a length-limited, %NUL-terminated string
-+ * @dest: Where to copy the string to
-+ * @src: Where to copy the string from
-+ * @count: The maximum number of bytes to copy
-+ *
-+ * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
-+ * However, the result is not %NUL-terminated if the source exceeds
-+ * @count bytes.
-+ */
-+char * strncpy(char * dest,const char *src,size_t count)
-+{
-+ char *tmp = dest;
-+
-+ while (count-- && (*dest++ = *src++) != '\0')
-+ /* nothing */;
-+
-+ return tmp;
-+}
-+#endif
-+
-+/**
-+ * strcat - Append one %NUL-terminated string to another
-+ * @dest: The string to be appended to
-+ * @src: The string to append to it
-+ */
-+char * strcat(char * dest, const char * src)
-+{
-+ char *tmp = dest;
-+
-+ while (*dest)
-+ dest++;
-+ while ((*dest++ = *src++) != '\0')
-+ ;
-+
-+ return tmp;
-+}
-+
-+/**
-+ * strncat - Append a length-limited, %NUL-terminated string to another
-+ * @dest: The string to be appended to
-+ * @src: The string to append to it
-+ * @count: The maximum numbers of bytes to copy
-+ *
-+ * Note that in contrast to strncpy, strncat ensures the result is
-+ * terminated.
-+ */
-+char * strncat(char *dest, const char *src, size_t count)
-+{
-+ char *tmp = dest;
-+
-+ if (count) {
-+ while (*dest)
-+ dest++;
-+ while ((*dest++ = *src++)) {
-+ if (--count == 0) {
-+ *dest = '\0';
-+ break;
-+ }
-+ }
-+ }
-+
-+ return tmp;
-+}
-+
-+#ifndef __HAVE_ARCH_STRCMP
-+/**
-+ * strcmp - Compare two strings
-+ * @cs: One string
-+ * @ct: Another string
-+ */
-+int strcmp(const char * cs,const char * ct)
-+{
-+ register signed char __res;
-+
-+ while (1) {
-+ if ((__res = *cs - *ct++) != 0 || !*cs++)
-+ break;
-+ }
-+
-+ return __res;
-+}
-+#endif
-+
-+#ifndef __HAVE_ARCH_STRNCMP
-+/**
-+ * strncmp - Compare two length-limited strings
-+ * @cs: One string
-+ * @ct: Another string
-+ * @count: The maximum number of bytes to compare
-+ */
-+int strncmp(const char * cs,const char * ct,size_t count)
-+{
-+ register signed char __res = 0;
-+
-+ while (count) {
-+ if ((__res = *cs - *ct++) != 0 || !*cs++)
-+ break;
-+ count--;
-+ }
-+
-+ return __res;
-+}
-+#endif
-+
-+/**
-+ * strchr - Find the first occurrence of a character in a string
-+ * @s: The string to be searched
-+ * @c: The character to search for
-+ */
-+char * strchr(const char * s, int c)
-+{
-+ for(; *s != (char) c; ++s)
-+ if (*s == '\0')
-+ return NULL;
-+ return (char *) s;
-+}
-+
-+/**
-+ * strrchr - Find the last occurrence of a character in a string
-+ * @s: The string to be searched
-+ * @c: The character to search for
-+ */
-+char * strrchr(const char * s, int c)
-+{
-+ const char *p = s + strlen(s);
-+ do {
-+ if (*p == (char)c)
-+ return (char *)p;
-+ } while (--p >= s);
-+ return NULL;
-+}
-+
-+/**
-+ * strlen - Find the length of a string
-+ * @s: The string to be sized
-+ */
-+size_t strlen(const char * s)
-+{
-+ const char *sc;
-+
-+ for (sc = s; *sc != '\0'; ++sc)
-+ /* nothing */;
-+ return sc - s;
-+}
-+
-+/**
-+ * strnlen - Find the length of a length-limited string
-+ * @s: The string to be sized
-+ * @count: The maximum number of bytes to search
-+ */
-+size_t strnlen(const char * s, size_t count)
-+{
-+ const char *sc;
-+
-+ for (sc = s; count-- && *sc != '\0'; ++sc)
-+ /* nothing */;
-+ return sc - s;
-+}
-+
-+/**
-+ * strspn - Calculate the length of the initial substring of @s which only
-+ * contain letters in @accept
-+ * @s: The string to be searched
-+ * @accept: The string to search for
-+ */
-+size_t strspn(const char *s, const char *accept)
-+{
-+ const char *p;
-+ const char *a;
-+ size_t count = 0;
-+
-+ for (p = s; *p != '\0'; ++p) {
-+ for (a = accept; *a != '\0'; ++a) {
-+ if (*p == *a)
-+ break;
-+ }
-+ if (*a == '\0')
-+ return count;
-+ ++count;
-+ }
-+
-+ return count;
-+}
-+
-+/**
-+ * strpbrk - Find the first occurrence of a set of characters
-+ * @cs: The string to be searched
-+ * @ct: The characters to search for
-+ */
-+char * strpbrk(const char * cs,const char * ct)
-+{
-+ const char *sc1,*sc2;
-+
-+ for( sc1 = cs; *sc1 != '\0'; ++sc1) {
-+ for( sc2 = ct; *sc2 != '\0'; ++sc2) {
-+ if (*sc1 == *sc2)
-+ return (char *) sc1;
-+ }
-+ }
-+ return NULL;
-+}
-+
-+/**
-+ * strtok - Split a string into tokens
-+ * @s: The string to be searched
-+ * @ct: The characters to search for
-+ *
-+ * WARNING: strtok is deprecated, use strsep instead.
-+ */
-+char * strtok(char * s,const char * ct)
-+{
-+ char *sbegin, *send;
-+
-+ sbegin = s ? s : ___strtok;
-+ if (!sbegin) {
-+ return NULL;
-+ }
-+ sbegin += strspn(sbegin,ct);
-+ if (*sbegin == '\0') {
-+ ___strtok = NULL;
-+ return( NULL );
-+ }
-+ send = strpbrk( sbegin, ct);
-+ if (send && *send != '\0')
-+ *send++ = '\0';
-+ ___strtok = send;
-+ return (sbegin);
-+}
-+
-+/**
-+ * strsep - Split a string into tokens
-+ * @s: The string to be searched
-+ * @ct: The characters to search for
-+ *
-+ * strsep() updates @s to point after the token, ready for the next call.
-+ *
-+ * It returns empty tokens, too, behaving exactly like the libc function
-+ * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
-+ * Same semantics, slimmer shape. ;)
-+ */
-+char * strsep(char **s, const char *ct)
-+{
-+ char *sbegin = *s, *end;
-+
-+ if (sbegin == NULL)
-+ return NULL;
-+
-+ end = strpbrk(sbegin, ct);
-+ if (end)
-+ *end++ = '\0';
-+ *s = end;
-+
-+ return sbegin;
-+}
-+
-+/**
-+ * memset - Fill a region of memory with the given value
-+ * @s: Pointer to the start of the area.
-+ * @c: The byte to fill the area with
-+ * @count: The size of the area.
-+ *
-+ * Do not use memset() to access IO space, use memset_io() instead.
-+ */
-+void * memset(void * s,int c, size_t count)
-+{
-+ char *xs = (char *) s;
-+
-+ while (count--)
-+ *xs++ = c;
-+
-+ return s;
-+}
-+
-+/**
-+ * bcopy - Copy one area of memory to another
-+ * @src: Where to copy from
-+ * @dest: Where to copy to
-+ * @count: The size of the area.
-+ *
-+ * Note that this is the same as memcpy(), with the arguments reversed.
-+ * memcpy() is the standard, bcopy() is a legacy BSD function.
-+ *
-+ * You should not use this function to access IO space, use memcpy_toio()
-+ * or memcpy_fromio() instead.
-+ */
-+char * bcopy(const char * src, char * dest, int count)
-+{
-+ char *tmp = dest;
-+
-+ while (count--)
-+ *tmp++ = *src++;
-+
-+ return dest;
-+}
-+
-+/**
-+ * memcpy - Copy one area of memory to another
-+ * @dest: Where to copy to
-+ * @src: Where to copy from
-+ * @count: The size of the area.
-+ *
-+ * You should not use this function to access IO space, use memcpy_toio()
-+ * or memcpy_fromio() instead.
-+ */
-+void * memcpy(void * dest,const void *src,size_t count)
-+{
-+ char *tmp = (char *) dest, *s = (char *) src;
-+
-+ while (count--)
-+ *tmp++ = *s++;
-+
-+ return dest;
-+}
-+
-+/**
-+ * memmove - Copy one area of memory to another
-+ * @dest: Where to copy to
-+ * @src: Where to copy from
-+ * @count: The size of the area.
-+ *
-+ * Unlike memcpy(), memmove() copes with overlapping areas.
-+ */
-+void * memmove(void * dest,const void *src,size_t count)
-+{
-+ char *tmp, *s;
-+
-+ if (dest <= src) {
-+ tmp = (char *) dest;
-+ s = (char *) src;
-+ while (count--)
-+ *tmp++ = *s++;
-+ }
-+ else {
-+ tmp = (char *) dest + count;
-+ s = (char *) src + count;
-+ while (count--)
-+ *--tmp = *--s;
-+ }
-+
-+ return dest;
-+}
-+
-+/**
-+ * memcmp - Compare two areas of memory
-+ * @cs: One area of memory
-+ * @ct: Another area of memory
-+ * @count: The size of the area.
-+ */
-+int memcmp(const void * cs,const void * ct,size_t count)
-+{
-+ const unsigned char *su1, *su2;
-+ signed char res = 0;
-+
-+ for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
-+ if ((res = *su1 - *su2) != 0)
-+ break;
-+ return res;
-+}
-+
-+#ifndef __HAVE_ARCH_MEMSCAN
-+/**
-+ * memscan - Find a character in an area of memory.
-+ * @addr: The memory area
-+ * @c: The byte to search for
-+ * @size: The size of the area.
-+ *
-+ * returns the address of the first occurrence of @c, or 1 byte past
-+ * the area if @c is not found
-+ */
-+void * memscan(void * addr, int c, size_t size)
-+{
-+ unsigned char * p = (unsigned char *) addr;
-+ unsigned char * e = p + size;
-+
-+ while (p != e) {
-+ if (*p == c)
-+ return (void *) p;
-+ p++;
-+ }
-+
-+ return (void *) p;
-+}
-+#endif
-+
-+/**
-+ * strstr - Find the first substring in a %NUL terminated string
-+ * @s1: The string to be searched
-+ * @s2: The string to search for
-+ */
-+char * strstr(const char * s1,const char * s2)
-+{
-+ int l1, l2;
-+
-+ l2 = strlen(s2);
-+ if (!l2)
-+ return (char *) s1;
-+ l1 = strlen(s1);
-+ while (l1 >= l2) {
-+ l1--;
-+ if (!memcmp(s1,s2,l2))
-+ return (char *) s1;
-+ s1++;
-+ }
-+ return NULL;
-+}
-+
-+/**
-+ * memchr - Find a character in an area of memory.
-+ * @s: The memory area
-+ * @c: The byte to search for
-+ * @n: The size of the area.
-+ *
-+ * returns the address of the first occurrence of @c, or %NULL
-+ * if @c is not found
-+ */
-+void *memchr(const void *s, int c, size_t n)
-+{
-+ const unsigned char *p = s;
-+ while (n-- != 0) {
-+ if ((unsigned char)c == *p++) {
-+ return (void *)(p-1);
-+ }
-+ }
-+ return NULL;
-+}
-diff -Naru linux/arch/mips/zboot/csb250/head.S linux-new/arch/mips/zboot/csb250/head.S
---- linux/arch/mips/zboot/csb250/head.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/csb250/head.S 2003-12-18 14:26:20.000000000 -0500
-@@ -0,0 +1,157 @@
-+/*
-+ * arch/mips/kernel/head.S
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file "COPYING" in the main directory of this archive
-+ * for more details.
-+ *
-+ * Copyright (C) 1994, 1995 Waldorf Electronics
-+ * Written by Ralf Baechle and Andreas Busse
-+ * Copyright (C) 1995 - 1999 Ralf Baechle
-+ * Copyright (C) 1996 Paul M. Antoine
-+ * Modified for DECStation and hence R3000 support by Paul M. Antoine
-+ * Further modifications by David S. Miller and Harald Koerfgen
-+ * Copyright (C) 1999 Silicon Graphics, Inc.
-+ *
-+ * Head.S contains the MIPS exception handler and startup code.
-+ *
-+ **************************************************************************
-+ * 9 Nov, 2000.
-+ * Added Cache Error exception handler and SBDDP EJTAG debug exception.
-+ *
-+ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
-+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
-+ **************************************************************************
-+ */
-+#include <linux/config.h>
-+#include <linux/threads.h>
-+
-+#include <asm/asm.h>
-+#include <asm/cacheops.h>
-+#include <asm/mipsregs.h>
-+#include <asm/offset.h>
-+#include <asm/cachectl.h>
-+#include <asm/regdef.h>
-+
-+#define IndexInvalidate_I 0x00
-+#define IndexWriteBack_D 0x01
-+
-+ .set noreorder
-+ .cprestore
-+ LEAF(start)
-+start:
-+ bal locate
-+ nop
-+
-+ .globl asize /* Someday we'll put the initrd info here. */
-+asize: .word 0
-+ .word 0
-+ .word 0
-+ .word 0
-+
-+locate:
-+ subu s8, ra, 8 /* Where we were loaded */
-+ la sp, (.stack + 8192)
-+
-+ move s0, a0 /* Save boot rom start args */
-+ move s1, a1
-+ move s2, a2
-+ move s3, a3
-+
-+ la a0, start /* Where we were linked to run */
-+
-+ move a1, s8
-+ la a2, _edata
-+ subu t1, a2, a0
-+ srl t1, t1, 2
-+
-+ /* copy text section */
-+ li t0, 0
-+1: lw v0, 0(a1)
-+ nop
-+ sw v0, 0(a0)
-+ xor t0, t0, v0
-+ addu a0, 4
-+ bne a2, a0, 1b
-+ addu a1, 4
-+
-+ /* Clear BSS */
-+ la a0, _edata
-+ la a2, _end
-+2: sw zero, 0(a0)
-+ bne a2, a0, 2b
-+ addu a0, 4
-+
-+ /* push the D-Cache and invalidate I-Cache */
-+ li k0, 0x80000000 # start address
-+ li k1, 0x80004000 # end address (16KB I-Cache)
-+ subu k1, 128
-+
-+1:
-+ .set mips3
-+ cache IndexWriteBack_D, 0(k0)
-+ cache IndexWriteBack_D, 32(k0)
-+ cache IndexWriteBack_D, 64(k0)
-+ cache IndexWriteBack_D, 96(k0)
-+ cache IndexInvalidate_I, 0(k0)
-+ cache IndexInvalidate_I, 32(k0)
-+ cache IndexInvalidate_I, 64(k0)
-+ cache IndexInvalidate_I, 96(k0)
-+ .set mips0
-+
-+ bne k0, k1, 1b
-+ addu k0, k0, 128
-+ /* done */
-+
-+/* move a0, s8 /* load address */
-+ subu a0, s8, 0x1000 /* load address */
-+ move a1, t1 /* length in words */
-+ move a2, t0 /* checksum */
-+ move a3, sp
-+
-+ la ra, 1f
-+ la k0, decompress_kernel
-+ jr k0
-+ nop
-+1:
-+
-+ la a2, __ramdisk_begin
-+ la a3, initrd_size
-+ lw a0, 0(a2)
-+ lw a1, 0(a3)
-+ li k0, KERNEL_ENTRY
-+ jr k0
-+ nop
-+3:
-+ b 3b
-+ END(start)
-+
-+ LEAF(udelay)
-+udelay:
-+ END(udelay)
-+
-+
-+ LEAF(FlushCache)
-+ li k0, 0x80000000 # start address
-+ li k1, 0x80004000 # end address (16KB I-Cache)
-+ subu k1, 128
-+
-+1:
-+ .set mips3
-+ cache IndexWriteBack_D, 0(k0)
-+ cache IndexWriteBack_D, 32(k0)
-+ cache IndexWriteBack_D, 64(k0)
-+ cache IndexWriteBack_D, 96(k0)
-+ cache IndexInvalidate_I, 0(k0)
-+ cache IndexInvalidate_I, 32(k0)
-+ cache IndexInvalidate_I, 64(k0)
-+ cache IndexInvalidate_I, 96(k0)
-+ .set mips0
-+
-+ bne k0, k1, 1b
-+ addu k0, k0, 128
-+ jr ra
-+ nop
-+ END(FlushCache)
-+
-+ .comm .stack,4096*2,4
-diff -Naru linux/arch/mips/zboot/csb250/Makefile linux-new/arch/mips/zboot/csb250/Makefile
---- linux/arch/mips/zboot/csb250/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/csb250/Makefile 2003-12-18 14:26:20.000000000 -0500
-@@ -0,0 +1,90 @@
-+# arch/mips/zboot/pb1xxx/Makefile
-+#
-+# Makefile for Cogent CSB250 Au1500 board.
-+# All of the boot loader code was derived from the ppc
-+# boot code.
-+#
-+# 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.
-+
-+.c.s:
-+ $(CC) $(CFLAGS) -S -o $*.s $<
-+.s.o:
-+ $(AS) -o $*.o $<
-+.c.o:
-+ $(CC) $(CFLAGS) -D__BOOTER__ -c -o $*.o $<
-+.S.s:
-+ $(CPP) $(AFLAGS) -o $*.o $<
-+.S.o:
-+ $(CC) $(AFLAGS) -c -o $*.o $<
-+
-+#########################################################################
-+# START BOARD SPECIFIC VARIABLES
-+BNAME=csb250
-+
-+# These two variables control where the zImage is stored
-+# in flash and loaded in memory. It only controls how the srec
-+# file is generated, the code is the same.
-+RAM_RUN_ADDR = 0x80a00000
-+FLASH_LOAD_ADDR = 0xBFD00000
-+
-+# These two variables specify the free ram region
-+# that can be used for temporary malloc area
-+AVAIL_RAM_START=0x80400000
-+AVAIL_RAM_END=0x80800000
-+
-+# This one must match the LOADADDR in arch/mips/Makefile!
-+LOADADDR=0x80100000
-+# END BOARD SPECIFIC VARIABLES
-+#########################################################################
-+
-+OBJECTS := head.o ../common/misc-common.o ../common/misc-simple.o \
-+ ../common/au1k_uart.o ../common/string.o ../common/ctype.o
-+LIBS := ../lib/zlib.a
-+
-+ENTRY := ../utils/entry
-+OFFSET := ../utils/offset
-+SIZE := ../utils/size
-+
-+LD_ARGS := -T ../ld.script -Ttext $(RAM_RUN_ADDR) -Bstatic
-+OBJCOPY_ARGS = -O elf32-tradbigmips
-+
-+all: zImage
-+
-+clean:
-+ rm -rf *.o vmlinux* zvmlinux.* ../images/*.srec
-+
-+head.o: head.S $(TOPDIR)/vmlinux
-+ $(CC) $(AFLAGS) \
-+ -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) $(TOPDIR)/vmlinux ) \
-+ -c -o $*.o $<
-+
-+../common/misc-simple.o:
-+ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \
-+ -DAVAIL_RAM_START=$(AVAIL_RAM_START) \
-+ -DAVAIL_RAM_END=$(AVAIL_RAM_END) \
-+ -DLOADADDR=$(LOADADDR) \
-+ -DZIMAGE_SIZE=0 -c -o $@ $*.c
-+
-+zvmlinux: $(OBJECTS) $(LIBS) ../ld.script ../images/vmlinux.gz ../common/dummy.o
-+ $(OBJCOPY) \
-+ --add-section=.image=../images/vmlinux.gz \
-+ --set-section-flags=.image=contents,alloc,load,readonly,data \
-+ ../common/dummy.o image.o
-+ $(LD) $(LD_ARGS) -o $@ $(OBJECTS) image.o $(LIBS)
-+ $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr \
-+ -R .initrd -R .sysmap
-+
-+# Here we manipulate the image in order to get it the necessary
-+# srecord file we need.
-+zImage: zvmlinux
-+ mv zvmlinux ../images/zImage.$(BNAME)
-+ $(OBJCOPY) -O binary ../images/zImage.$(BNAME) ../images/$(BNAME).bin
-+
-+zImage.flash: zImage
-+ $(OBJCOPY) -O srec --adjust-vma 0x3ed00000 \
-+ ../images/zImage.$(BNAME) ../images/$(BNAME).flash.srec
-+
-+include $(TOPDIR)/Rules.make
-diff -Naru linux/arch/mips/zboot/images/Makefile linux-new/arch/mips/zboot/images/Makefile
---- linux/arch/mips/zboot/images/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/images/Makefile 2003-12-18 14:26:20.000000000 -0500
-@@ -0,0 +1,10 @@
-+
-+include $(TOPDIR)/Rules.make
-+
-+vmlinux.gz: $(TOPDIR)/vmlinux
-+ $(OBJCOPY) -S -O binary $(TOPDIR)/vmlinux vmlinux
-+ gzip -vf vmlinux
-+
-+clean:
-+ rm -f vmlinux.* zImage.*
-+
-diff -Naru linux/arch/mips/zboot/include/nonstdio.h linux-new/arch/mips/zboot/include/nonstdio.h
---- linux/arch/mips/zboot/include/nonstdio.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/include/nonstdio.h 2003-12-18 14:26:20.000000000 -0500
-@@ -0,0 +1,18 @@
-+/*
-+ * Copyright (C) Paul Mackerras 1997.
-+ *
-+ * 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.
-+ */
-+typedef int FILE;
-+extern FILE *stdin, *stdout;
-+#define NULL ((void *)0)
-+#define EOF (-1)
-+#define fopen(n, m) NULL
-+#define fflush(f) 0
-+#define fclose(f) 0
-+extern char *fgets();
-+
-+#define perror(s) printf("%s: no files!\n", (s))
-diff -Naru linux/arch/mips/zboot/include/ns16550.h linux-new/arch/mips/zboot/include/ns16550.h
---- linux/arch/mips/zboot/include/ns16550.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/include/ns16550.h 2003-12-18 14:26:20.000000000 -0500
-@@ -0,0 +1,49 @@
-+/*
-+ * NS16550 Serial Port
-+ */
-+
-+/*
-+ * Figure out which file will have the definitons of COMx
-+ */
-+#if !defined(CONFIG_AU1X00_UART)
-+#error no serial.h
-+#endif
-+
-+/* Some machines have their uart registers 16 bytes apart. Most don't.
-+ * TODO: Make this work like drivers/char/serial does - Tom */
-+#if !defined(UART_REG_PAD)
-+#define UART_REG_PAD(x)
-+#endif
-+
-+struct NS16550
-+ {
-+ unsigned char rbr; /* 0 */
-+ UART_REG_PAD(rbr)
-+ unsigned char ier; /* 1 */
-+ UART_REG_PAD(ier)
-+ unsigned char fcr; /* 2 */
-+ UART_REG_PAD(fcr)
-+ unsigned char lcr; /* 3 */
-+ UART_REG_PAD(lcr)
-+ unsigned char mcr; /* 4 */
-+ UART_REG_PAD(mcr)
-+ unsigned char lsr; /* 5 */
-+ UART_REG_PAD(lsr)
-+ unsigned char msr; /* 6 */
-+ UART_REG_PAD(msr)
-+ unsigned char scr; /* 7 */
-+ };
-+
-+#define thr rbr
-+#define iir fcr
-+#define dll rbr
-+#define dlm ier
-+
-+#define LSR_DR 0x01 /* Data ready */
-+#define LSR_OE 0x02 /* Overrun */
-+#define LSR_PE 0x04 /* Parity error */
-+#define LSR_FE 0x08 /* Framing error */
-+#define LSR_BI 0x10 /* Break */
-+#define LSR_THRE 0x20 /* Xmit holding register empty */
-+#define LSR_TEMT 0x40 /* Xmitter empty */
-+#define LSR_ERR 0x80 /* Error */
-diff -Naru linux/arch/mips/zboot/include/pb1000_serial.h linux-new/arch/mips/zboot/include/pb1000_serial.h
---- linux/arch/mips/zboot/include/pb1000_serial.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/include/pb1000_serial.h 2003-12-18 14:26:20.000000000 -0500
-@@ -0,0 +1,20 @@
-+/*
-+ * arch/ppc/boot/include/sandpoint_serial.h
-+ *
-+ * Location of the COM ports on Motorola SPS Sandpoint machines
-+ *
-+ * Author: Mark A. Greer
-+ * mgreer@mvista.com
-+ *
-+ * Copyright 2001 MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ */
-+
-+#define COM1 0xfe0003f8
-+#define COM2 0xfe0002f8
-+#define COM3 0x00000000 /* No COM3 */
-+#define COM4 0x00000000 /* No COM4 */
-diff -Naru linux/arch/mips/zboot/include/zlib.h linux-new/arch/mips/zboot/include/zlib.h
---- linux/arch/mips/zboot/include/zlib.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/include/zlib.h 2003-12-18 14:26:21.000000000 -0500
-@@ -0,0 +1,432 @@
-+/* $Id$ */
-+
-+/*
-+ * This file is derived from zlib.h and zconf.h from the zlib-0.95
-+ * distribution by Jean-loup Gailly and Mark Adler, with some additions
-+ * by Paul Mackerras to aid in implementing Deflate compression and
-+ * decompression for PPP packets.
-+ */
-+
-+/*
-+ * ==FILEVERSION 960122==
-+ *
-+ * This marker is used by the Linux installation script to determine
-+ * whether an up-to-date version of this file is already installed.
-+ */
-+
-+/* zlib.h -- interface of the 'zlib' general purpose compression library
-+ version 0.95, Aug 16th, 1995.
-+
-+ Copyright (C) 1995 Jean-loup Gailly and Mark Adler
-+
-+ This software is provided 'as-is', without any express or implied
-+ warranty. In no event will the authors be held liable for any damages
-+ arising from the use of this software.
-+
-+ Permission is granted to anyone to use this software for any purpose,
-+ including commercial applications, and to alter it and redistribute it
-+ freely, subject to the following restrictions:
-+
-+ 1. The origin of this software must not be misrepresented; you must not
-+ claim that you wrote the original software. If you use this software
-+ in a product, an acknowledgment in the product documentation would be
-+ appreciated but is not required.
-+ 2. Altered source versions must be plainly marked as such, and must not be
-+ misrepresented as being the original software.
-+ 3. This notice may not be removed or altered from any source distribution.
-+
-+ Jean-loup Gailly Mark Adler
-+ gzip@prep.ai.mit.edu madler@alumni.caltech.edu
-+ */
-+
-+#ifndef _ZLIB_H
-+#define _ZLIB_H
-+
-+/* #include "zconf.h" */ /* included directly here */
-+
-+/* zconf.h -- configuration of the zlib compression library
-+ * Copyright (C) 1995 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */
-+
-+/*
-+ The library does not install any signal handler. It is recommended to
-+ add at least a handler for SIGSEGV when decompressing; the library checks
-+ the consistency of the input data whenever possible but may go nuts
-+ for some forms of corrupted input.
-+ */
-+
-+/*
-+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
-+ * than 64k bytes at a time (needed on systems with 16-bit int).
-+ * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints
-+ * at addresses which are not a multiple of their size.
-+ * Under DOS, -DFAR=far or -DFAR=__far may be needed.
-+ */
-+
-+#ifndef STDC
-+# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus)
-+# define STDC
-+# endif
-+#endif
-+
-+#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */
-+# include <unix.h>
-+#endif
-+
-+/* Maximum value for memLevel in deflateInit2 */
-+#ifndef MAX_MEM_LEVEL
-+# ifdef MAXSEG_64K
-+# define MAX_MEM_LEVEL 8
-+# else
-+# define MAX_MEM_LEVEL 9
-+# endif
-+#endif
-+
-+#ifndef FAR
-+# define FAR
-+#endif
-+
-+/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
-+#ifndef MAX_WBITS
-+# define MAX_WBITS 15 /* 32K LZ77 window */
-+#endif
-+
-+/* The memory requirements for deflate are (in bytes):
-+ 1 << (windowBits+2) + 1 << (memLevel+9)
-+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
-+ plus a few kilobytes for small objects. For example, if you want to reduce
-+ the default memory requirements from 256K to 128K, compile with
-+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
-+ Of course this will generally degrade compression (there's no free lunch).
-+
-+ The memory requirements for inflate are (in bytes) 1 << windowBits
-+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
-+ for small objects.
-+*/
-+
-+ /* Type declarations */
-+
-+#ifndef OF /* function prototypes */
-+# ifdef STDC
-+# define OF(args) args
-+# else
-+# define OF(args) ()
-+# endif
-+#endif
-+
-+typedef unsigned char Byte; /* 8 bits */
-+typedef unsigned int uInt; /* 16 bits or more */
-+typedef unsigned long uLong; /* 32 bits or more */
-+
-+typedef Byte FAR Bytef;
-+typedef char FAR charf;
-+typedef int FAR intf;
-+typedef uInt FAR uIntf;
-+typedef uLong FAR uLongf;
-+
-+#ifdef STDC
-+ typedef void FAR *voidpf;
-+ typedef void *voidp;
-+#else
-+ typedef Byte FAR *voidpf;
-+ typedef Byte *voidp;
-+#endif
-+
-+/* end of original zconf.h */
-+
-+#define ZLIB_VERSION "0.95P"
-+
-+/*
-+ The 'zlib' compression library provides in-memory compression and
-+ decompression functions, including integrity checks of the uncompressed
-+ data. This version of the library supports only one compression method
-+ (deflation) but other algorithms may be added later and will have the same
-+ stream interface.
-+
-+ For compression the application must provide the output buffer and
-+ may optionally provide the input buffer for optimization. For decompression,
-+ the application must provide the input buffer and may optionally provide
-+ the output buffer for optimization.
-+
-+ Compression can be done in a single step if the buffers are large
-+ enough (for example if an input file is mmap'ed), or can be done by
-+ repeated calls of the compression function. In the latter case, the
-+ application must provide more input and/or consume the output
-+ (providing more output space) before each call.
-+*/
-+
-+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-+typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes));
-+
-+struct internal_state;
-+
-+typedef struct z_stream_s {
-+ Bytef *next_in; /* next input byte */
-+ uInt avail_in; /* number of bytes available at next_in */
-+ uLong total_in; /* total nb of input bytes read so far */
-+
-+ Bytef *next_out; /* next output byte should be put there */
-+ uInt avail_out; /* remaining free space at next_out */
-+ uLong total_out; /* total nb of bytes output so far */
-+
-+ char *msg; /* last error message, NULL if no error */
-+ struct internal_state FAR *state; /* not visible by applications */
-+
-+ alloc_func zalloc; /* used to allocate the internal state */
-+ free_func zfree; /* used to free the internal state */
-+ voidp opaque; /* private data object passed to zalloc and zfree */
-+
-+ Byte data_type; /* best guess about the data type: ascii or binary */
-+
-+} z_stream;
-+
-+/*
-+ The application must update next_in and avail_in when avail_in has
-+ dropped to zero. It must update next_out and avail_out when avail_out
-+ has dropped to zero. The application must initialize zalloc, zfree and
-+ opaque before calling the init function. All other fields are set by the
-+ compression library and must not be updated by the application.
-+
-+ The opaque value provided by the application will be passed as the first
-+ parameter for calls of zalloc and zfree. This can be useful for custom
-+ memory management. The compression library attaches no meaning to the
-+ opaque value.
-+
-+ zalloc must return Z_NULL if there is not enough memory for the object.
-+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
-+ exactly 65536 bytes, but will not be required to allocate more than this
-+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
-+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
-+ have their offset normalized to zero. The default allocation function
-+ provided by this library ensures this (see zutil.c). To reduce memory
-+ requirements and avoid any allocation of 64K objects, at the expense of
-+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-+
-+ The fields total_in and total_out can be used for statistics or
-+ progress reports. After compression, total_in holds the total size of
-+ the uncompressed data and may be saved for use in the decompressor
-+ (particularly if the decompressor wants to decompress everything in
-+ a single step).
-+*/
-+
-+ /* constants */
-+
-+#define Z_NO_FLUSH 0
-+#define Z_PARTIAL_FLUSH 1
-+#define Z_FULL_FLUSH 2
-+#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */
-+#define Z_FINISH 4
-+#define Z_PACKET_FLUSH 5
-+/* See deflate() below for the usage of these constants */
-+
-+#define Z_OK 0
-+#define Z_STREAM_END 1
-+#define Z_ERRNO (-1)
-+#define Z_STREAM_ERROR (-2)
-+#define Z_DATA_ERROR (-3)
-+#define Z_MEM_ERROR (-4)
-+#define Z_BUF_ERROR (-5)
-+/* error codes for the compression/decompression functions */
-+
-+#define Z_BEST_SPEED 1
-+#define Z_BEST_COMPRESSION 9
-+#define Z_DEFAULT_COMPRESSION (-1)
-+/* compression levels */
-+
-+#define Z_FILTERED 1
-+#define Z_HUFFMAN_ONLY 2
-+#define Z_DEFAULT_STRATEGY 0
-+
-+#define Z_BINARY 0
-+#define Z_ASCII 1
-+#define Z_UNKNOWN 2
-+/* Used to set the data_type field */
-+
-+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-+
-+extern char *zlib_version;
-+/* The application can compare zlib_version and ZLIB_VERSION for consistency.
-+ If the first character differs, the library code actually used is
-+ not compatible with the zlib.h header file used by the application.
-+ */
-+
-+ /* basic functions */
-+
-+extern int inflateInit OF((z_stream *strm));
-+/*
-+ Initializes the internal stream state for decompression. The fields
-+ zalloc and zfree must be initialized before by the caller. If zalloc and
-+ zfree are set to Z_NULL, inflateInit updates them to use default allocation
-+ functions.
-+
-+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory. msg is set to null if there is no error message.
-+ inflateInit does not perform any decompression: this will be done by
-+ inflate().
-+*/
-+
-+
-+extern int inflate OF((z_stream *strm, int flush));
-+/*
-+ Performs one or both of the following actions:
-+
-+ - Decompress more input starting at next_in and update next_in and avail_in
-+ accordingly. If not all input can be processed (because there is not
-+ enough room in the output buffer), next_in is updated and processing
-+ will resume at this point for the next call of inflate().
-+
-+ - Provide more output starting at next_out and update next_out and avail_out
-+ accordingly. inflate() always provides as much output as possible
-+ (until there is no more input data or no more space in the output buffer).
-+
-+ Before the call of inflate(), the application should ensure that at least
-+ one of the actions is possible, by providing more input and/or consuming
-+ more output, and updating the next_* and avail_* values accordingly.
-+ The application can consume the uncompressed output when it wants, for
-+ example when the output buffer is full (avail_out == 0), or after each
-+ call of inflate().
-+
-+ If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH,
-+ inflate flushes as much output as possible to the output buffer. The
-+ flushing behavior of inflate is not specified for values of the flush
-+ parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the
-+ current implementation actually flushes as much output as possible
-+ anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data
-+ has been consumed, it is expecting to see the length field of a stored
-+ block; if not, it returns Z_DATA_ERROR.
-+
-+ inflate() should normally be called until it returns Z_STREAM_END or an
-+ error. However if all decompression is to be performed in a single step
-+ (a single call of inflate), the parameter flush should be set to
-+ Z_FINISH. In this case all pending input is processed and all pending
-+ output is flushed; avail_out must be large enough to hold all the
-+ uncompressed data. (The size of the uncompressed data may have been saved
-+ by the compressor for this purpose.) The next operation on this stream must
-+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
-+ is never required, but can be used to inform inflate that a faster routine
-+ may be used for the single inflate() call.
-+
-+ inflate() returns Z_OK if some progress has been made (more input
-+ processed or more output produced), Z_STREAM_END if the end of the
-+ compressed data has been reached and all uncompressed output has been
-+ produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if
-+ the stream structure was inconsistent (for example if next_in or next_out
-+ was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no
-+ progress is possible or if there was not enough room in the output buffer
-+ when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then
-+ call inflateSync to look for a good compression block. */
-+
-+
-+extern int inflateEnd OF((z_stream *strm));
-+/*
-+ All dynamically allocated data structures for this stream are freed.
-+ This function discards any unprocessed input and does not flush any
-+ pending output.
-+
-+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
-+ was inconsistent. In the error case, msg may be set but then points to a
-+ static string (which must not be deallocated).
-+*/
-+
-+ /* advanced functions */
-+
-+extern int inflateInit2 OF((z_stream *strm,
-+ int windowBits));
-+/*
-+ This is another version of inflateInit with more compression options. The
-+ fields next_out, zalloc and zfree must be initialized before by the caller.
-+
-+ The windowBits parameter is the base two logarithm of the maximum window
-+ size (the size of the history buffer). It should be in the range 8..15 for
-+ this version of the library (the value 16 will be allowed soon). The
-+ default value is 15 if inflateInit is used instead. If a compressed stream
-+ with a larger window size is given as input, inflate() will return with
-+ the error code Z_DATA_ERROR instead of trying to allocate a larger window.
-+
-+ If next_out is not null, the library will use this buffer for the history
-+ buffer; the buffer must either be large enough to hold the entire output
-+ data, or have at least 1<<windowBits bytes. If next_out is null, the
-+ library will allocate its own buffer (and leave next_out null). next_in
-+ need not be provided here but must be provided by the application for the
-+ next call of inflate().
-+
-+ If the history buffer is provided by the application, next_out must
-+ never be changed by the application since the decompressor maintains
-+ history information inside this buffer from call to call; the application
-+ can only reset next_out to the beginning of the history buffer when
-+ avail_out is zero and all output has been consumed.
-+
-+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
-+ not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
-+ windowBits < 8). msg is set to null if there is no error message.
-+ inflateInit2 does not perform any decompression: this will be done by
-+ inflate().
-+*/
-+
-+extern int inflateSync OF((z_stream *strm));
-+/*
-+ Skips invalid compressed data until the special marker (see deflate()
-+ above) can be found, or until all available input is skipped. No output
-+ is provided.
-+
-+ inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR
-+ if no more input was provided, Z_DATA_ERROR if no marker has been found,
-+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
-+ case, the application may save the current current value of total_in which
-+ indicates where valid compressed data was found. In the error case, the
-+ application may repeatedly call inflateSync, providing more input each time,
-+ until success or end of the input data.
-+*/
-+
-+extern int inflateReset OF((z_stream *strm));
-+/*
-+ This function is equivalent to inflateEnd followed by inflateInit,
-+ but does not free and reallocate all the internal decompression state.
-+ The stream will keep attributes that may have been set by inflateInit2.
-+
-+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-+ stream state was inconsistent (such as zalloc or state being NULL).
-+*/
-+
-+extern int inflateIncomp OF((z_stream *strm));
-+/*
-+ This function adds the data at next_in (avail_in bytes) to the output
-+ history without performing any output. There must be no pending output,
-+ and the decompressor must be expecting to see the start of a block.
-+ Calling this function is equivalent to decompressing a stored block
-+ containing the data at next_in (except that the data is not output).
-+*/
-+
-+ /* checksum functions */
-+
-+/*
-+ This function is not related to compression but is exported
-+ anyway because it might be useful in applications using the
-+ compression library.
-+*/
-+
-+extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len));
-+
-+/*
-+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
-+ return the updated checksum. If buf is NULL, this function returns
-+ the required initial value for the checksum.
-+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
-+ much faster. Usage example:
-+
-+ uLong adler = adler32(0L, Z_NULL, 0);
-+
-+ while (read_buffer(buffer, length) != EOF) {
-+ adler = adler32(adler, buffer, length);
-+ }
-+ if (adler != original_adler) error();
-+*/
-+
-+#ifndef _Z_UTIL_H
-+ struct internal_state {int dummy;}; /* hack for buggy compilers */
-+#endif
-+
-+#endif /* _ZLIB_H */
-diff -Naru linux/arch/mips/zboot/ld.script linux-new/arch/mips/zboot/ld.script
---- linux/arch/mips/zboot/ld.script 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/ld.script 2003-12-18 14:26:21.000000000 -0500
-@@ -0,0 +1,151 @@
-+OUTPUT_ARCH(mips)
-+ENTRY(start)
-+SECTIONS
-+{
-+ /* Read-only sections, merged into text segment: */
-+ /* . = 0x81000000; */
-+ .init : { *(.init) } =0
-+ .text :
-+ {
-+ _ftext = . ;
-+ *(.text)
-+ *(.rodata)
-+ *(.rodata1)
-+ /* .gnu.warning sections are handled specially by elf32.em. */
-+ *(.gnu.warning)
-+ } =0
-+ .kstrtab : { *(.kstrtab) }
-+
-+ . = ALIGN(16); /* Exception table */
-+ __start___ex_table = .;
-+ __ex_table : { *(__ex_table) }
-+ __stop___ex_table = .;
-+
-+ __start___dbe_table = .; /* Exception table for data bus errors */
-+ __dbe_table : { *(__dbe_table) }
-+ __stop___dbe_table = .;
-+
-+ __start___ksymtab = .; /* Kernel symbol table */
-+ __ksymtab : { *(__ksymtab) }
-+ __stop___ksymtab = .;
-+
-+ _etext = .;
-+
-+ . = ALIGN(8192);
-+ .data.init_task : { *(.data.init_task) }
-+
-+ /* Startup code */
-+ . = ALIGN(4096);
-+ __init_begin = .;
-+ .text.init : { *(.text.init) }
-+ .data.init : { *(.data.init) }
-+ . = ALIGN(16);
-+ __setup_start = .;
-+ .setup.init : { *(.setup.init) }
-+ __setup_end = .;
-+ __initcall_start = .;
-+ .initcall.init : { *(.initcall.init) }
-+ __initcall_end = .;
-+ . = ALIGN(4096); /* Align double page for init_task_union */
-+ __init_end = .;
-+
-+ . = ALIGN(4096);
-+ .data.page_aligned : { *(.data.idt) }
-+
-+ . = ALIGN(32);
-+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
-+
-+ .fini : { *(.fini) } =0
-+ .reginfo : { *(.reginfo) }
-+ /* Adjust the address for the data segment. We want to adjust up to
-+ the same address within the page on the next page up. It would
-+ be more correct to do this:
-+ . = .;
-+ The current expression does not correctly handle the case of a
-+ text segment ending precisely at the end of a page; it causes the
-+ data segment to skip a page. The above expression does not have
-+ this problem, but it will currently (2/95) cause BFD to allocate
-+ a single segment, combining both text and data, for this case.
-+ This will prevent the text segment from being shared among
-+ multiple executions of the program; I think that is more
-+ important than losing a page of the virtual address space (note
-+ that no actual memory is lost; the page which is skipped can not
-+ be referenced). */
-+ . = .;
-+ .data :
-+ {
-+ _fdata = . ;
-+ *(.data)
-+
-+ /* Put the compressed image here, so bss is on the end. */
-+ __image_begin = .;
-+ *(.image)
-+ __image_end = .;
-+ /* Align the initial ramdisk image (INITRD) on page boundaries. */
-+ . = ALIGN(4096);
-+ __ramdisk_begin = .;
-+ *(.initrd)
-+ __ramdisk_end = .;
-+ . = ALIGN(4096);
-+
-+ CONSTRUCTORS
-+ }
-+ .data1 : { *(.data1) }
-+ _gp = . + 0x8000;
-+ .lit8 : { *(.lit8) }
-+ .lit4 : { *(.lit4) }
-+ .ctors : { *(.ctors) }
-+ .dtors : { *(.dtors) }
-+ .got : { *(.got.plt) *(.got) }
-+ .dynamic : { *(.dynamic) }
-+ /* We want the small data sections together, so single-instruction offsets
-+ can access them all, and initialized data all before uninitialized, so
-+ we can shorten the on-disk segment size. */
-+ .sdata : { *(.sdata) }
-+ . = ALIGN(4);
-+ _edata = .;
-+ PROVIDE (edata = .);
-+
-+ __bss_start = .;
-+ _fbss = .;
-+ .sbss : { *(.sbss) *(.scommon) }
-+ .bss :
-+ {
-+ *(.dynbss)
-+ *(.bss)
-+ *(COMMON)
-+ . = ALIGN(4);
-+ _end = . ;
-+ PROVIDE (end = .);
-+ }
-+
-+ /* Sections to be discarded */
-+ /DISCARD/ :
-+ {
-+ *(.text.exit)
-+ *(.data.exit)
-+ *(.exitcall.exit)
-+ }
-+
-+ /* This is the MIPS specific mdebug section. */
-+ .mdebug : { *(.mdebug) }
-+ /* These are needed for ELF backends which have not yet been
-+ converted to the new style linker. */
-+ .stab 0 : { *(.stab) }
-+ .stabstr 0 : { *(.stabstr) }
-+ /* DWARF debug sections.
-+ Symbols in the .debug DWARF section are relative to the beginning of the
-+ section so we begin .debug at 0. It's not clear yet what needs to happen
-+ for the others. */
-+ .debug 0 : { *(.debug) }
-+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
-+ .debug_aranges 0 : { *(.debug_aranges) }
-+ .debug_pubnames 0 : { *(.debug_pubnames) }
-+ .debug_sfnames 0 : { *(.debug_sfnames) }
-+ .line 0 : { *(.line) }
-+ /* These must appear regardless of . */
-+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
-+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
-+ .comment : { *(.comment) }
-+ .note : { *(.note) }
-+}
-diff -Naru linux/arch/mips/zboot/lib/Makefile linux-new/arch/mips/zboot/lib/Makefile
---- linux/arch/mips/zboot/lib/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/lib/Makefile 2003-12-18 14:26:21.000000000 -0500
-@@ -0,0 +1,9 @@
-+#
-+# Makefile for some libs needed by zImage.
-+#
-+
-+L_TARGET := zlib.a
-+
-+obj-y := zlib.o
-+
-+include $(TOPDIR)/Rules.make
-diff -Naru linux/arch/mips/zboot/lib/zlib.c linux-new/arch/mips/zboot/lib/zlib.c
---- linux/arch/mips/zboot/lib/zlib.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/lib/zlib.c 2003-12-18 14:26:21.000000000 -0500
-@@ -0,0 +1,2148 @@
-+/*
-+ * This file is derived from various .h and .c files from the zlib-0.95
-+ * distribution by Jean-loup Gailly and Mark Adler, with some additions
-+ * by Paul Mackerras to aid in implementing Deflate compression and
-+ * decompression for PPP packets. See zlib.h for conditions of
-+ * distribution and use.
-+ *
-+ * Changes that have been made include:
-+ * - changed functions not used outside this file to "local"
-+ * - added minCompression parameter to deflateInit2
-+ * - added Z_PACKET_FLUSH (see zlib.h for details)
-+ * - added inflateIncomp
-+ *
-+ * $Id$
-+ */
-+
-+/*+++++*/
-+/* zutil.h -- internal interface and configuration of the compression library
-+ * Copyright (C) 1995 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */
-+
-+#define _Z_UTIL_H
-+
-+#include "zlib.h"
-+
-+#ifndef local
-+# define local static
-+#endif
-+/* compile with -Dlocal if your debugger can't find static symbols */
-+
-+#define FAR
-+
-+typedef unsigned char uch;
-+typedef uch FAR uchf;
-+typedef unsigned short ush;
-+typedef ush FAR ushf;
-+typedef unsigned long ulg;
-+
-+extern char *z_errmsg[]; /* indexed by 1-zlib_error */
-+
-+#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err)
-+/* To be used only when the state is known to be valid */
-+
-+#ifndef NULL
-+#define NULL ((void *) 0)
-+#endif
-+
-+ /* common constants */
-+
-+#define DEFLATED 8
-+
-+#ifndef DEF_WBITS
-+# define DEF_WBITS MAX_WBITS
-+#endif
-+/* default windowBits for decompression. MAX_WBITS is for compression only */
-+
-+#if MAX_MEM_LEVEL >= 8
-+# define DEF_MEM_LEVEL 8
-+#else
-+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-+#endif
-+/* default memLevel */
-+
-+#define STORED_BLOCK 0
-+#define STATIC_TREES 1
-+#define DYN_TREES 2
-+/* The three kinds of block type */
-+
-+#define MIN_MATCH 3
-+#define MAX_MATCH 258
-+/* The minimum and maximum match lengths */
-+
-+ /* functions */
-+
-+#include <linux/string.h>
-+#define zmemcpy memcpy
-+#define zmemzero(dest, len) memset(dest, 0, len)
-+
-+/* Diagnostic functions */
-+#ifdef DEBUG_ZLIB
-+# include <stdio.h>
-+# ifndef verbose
-+# define verbose 0
-+# endif
-+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-+# define Trace(x) fprintf x
-+# define Tracev(x) {if (verbose) fprintf x ;}
-+# define Tracevv(x) {if (verbose>1) fprintf x ;}
-+# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-+# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
-+#else
-+# define Assert(cond,msg)
-+# define Trace(x)
-+# define Tracev(x)
-+# define Tracevv(x)
-+# define Tracec(c,x)
-+# define Tracecv(c,x)
-+#endif
-+
-+
-+typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len));
-+
-+/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */
-+/* void zcfree OF((voidpf opaque, voidpf ptr)); */
-+
-+#define ZALLOC(strm, items, size) \
-+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
-+#define ZFREE(strm, addr, size) \
-+ (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size))
-+#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);}
-+
-+/* deflate.h -- internal compression state
-+ * Copyright (C) 1995 Jean-loup Gailly
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+/*+++++*/
-+/* infblock.h -- header to use infblock.c
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+struct inflate_blocks_state;
-+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
-+
-+local inflate_blocks_statef * inflate_blocks_new OF((
-+ z_stream *z,
-+ check_func c, /* check function */
-+ uInt w)); /* window size */
-+
-+local int inflate_blocks OF((
-+ inflate_blocks_statef *,
-+ z_stream *,
-+ int)); /* initial return code */
-+
-+local void inflate_blocks_reset OF((
-+ inflate_blocks_statef *,
-+ z_stream *,
-+ uLongf *)); /* check value on output */
-+
-+local int inflate_blocks_free OF((
-+ inflate_blocks_statef *,
-+ z_stream *,
-+ uLongf *)); /* check value on output */
-+
-+local int inflate_addhistory OF((
-+ inflate_blocks_statef *,
-+ z_stream *));
-+
-+local int inflate_packet_flush OF((
-+ inflate_blocks_statef *));
-+
-+/*+++++*/
-+/* inftrees.h -- header to use inftrees.c
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+/* Huffman code lookup table entry--this entry is four bytes for machines
-+ that have 16-bit pointers (e.g. PC's in the small or medium model). */
-+
-+typedef struct inflate_huft_s FAR inflate_huft;
-+
-+struct inflate_huft_s {
-+ union {
-+ struct {
-+ Byte Exop; /* number of extra bits or operation */
-+ Byte Bits; /* number of bits in this code or subcode */
-+ } what;
-+ uInt Nalloc; /* number of these allocated here */
-+ Bytef *pad; /* pad structure to a power of 2 (4 bytes for */
-+ } word; /* 16-bit, 8 bytes for 32-bit machines) */
-+ union {
-+ uInt Base; /* literal, length base, or distance base */
-+ inflate_huft *Next; /* pointer to next level of table */
-+ } more;
-+};
-+
-+#ifdef DEBUG_ZLIB
-+ local uInt inflate_hufts;
-+#endif
-+
-+local int inflate_trees_bits OF((
-+ uIntf *, /* 19 code lengths */
-+ uIntf *, /* bits tree desired/actual depth */
-+ inflate_huft * FAR *, /* bits tree result */
-+ z_stream *)); /* for zalloc, zfree functions */
-+
-+local int inflate_trees_dynamic OF((
-+ uInt, /* number of literal/length codes */
-+ uInt, /* number of distance codes */
-+ uIntf *, /* that many (total) code lengths */
-+ uIntf *, /* literal desired/actual bit depth */
-+ uIntf *, /* distance desired/actual bit depth */
-+ inflate_huft * FAR *, /* literal/length tree result */
-+ inflate_huft * FAR *, /* distance tree result */
-+ z_stream *)); /* for zalloc, zfree functions */
-+
-+local int inflate_trees_fixed OF((
-+ uIntf *, /* literal desired/actual bit depth */
-+ uIntf *, /* distance desired/actual bit depth */
-+ inflate_huft * FAR *, /* literal/length tree result */
-+ inflate_huft * FAR *)); /* distance tree result */
-+
-+local int inflate_trees_free OF((
-+ inflate_huft *, /* tables to free */
-+ z_stream *)); /* for zfree function */
-+
-+
-+/*+++++*/
-+/* infcodes.h -- header to use infcodes.c
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+struct inflate_codes_state;
-+typedef struct inflate_codes_state FAR inflate_codes_statef;
-+
-+local inflate_codes_statef *inflate_codes_new OF((
-+ uInt, uInt,
-+ inflate_huft *, inflate_huft *,
-+ z_stream *));
-+
-+local int inflate_codes OF((
-+ inflate_blocks_statef *,
-+ z_stream *,
-+ int));
-+
-+local void inflate_codes_free OF((
-+ inflate_codes_statef *,
-+ z_stream *));
-+
-+
-+/*+++++*/
-+/* inflate.c -- zlib interface to inflate modules
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* inflate private state */
-+struct internal_state {
-+
-+ /* mode */
-+ enum {
-+ METHOD, /* waiting for method byte */
-+ FLAG, /* waiting for flag byte */
-+ BLOCKS, /* decompressing blocks */
-+ CHECK4, /* four check bytes to go */
-+ CHECK3, /* three check bytes to go */
-+ CHECK2, /* two check bytes to go */
-+ CHECK1, /* one check byte to go */
-+ DONE, /* finished check, done */
-+ BAD} /* got an error--stay here */
-+ mode; /* current inflate mode */
-+
-+ /* mode dependent information */
-+ union {
-+ uInt method; /* if FLAGS, method byte */
-+ struct {
-+ uLong was; /* computed check value */
-+ uLong need; /* stream check value */
-+ } check; /* if CHECK, check values to compare */
-+ uInt marker; /* if BAD, inflateSync's marker bytes count */
-+ } sub; /* submode */
-+
-+ /* mode independent information */
-+ int nowrap; /* flag for no wrapper */
-+ uInt wbits; /* log2(window size) (8..15, defaults to 15) */
-+ inflate_blocks_statef
-+ *blocks; /* current inflate_blocks state */
-+
-+};
-+
-+
-+int inflateReset(z)
-+z_stream *z;
-+{
-+ uLong c;
-+
-+ if (z == Z_NULL || z->state == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ z->total_in = z->total_out = 0;
-+ z->msg = Z_NULL;
-+ z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
-+ inflate_blocks_reset(z->state->blocks, z, &c);
-+ Trace((stderr, "inflate: reset\n"));
-+ return Z_OK;
-+}
-+
-+
-+int inflateEnd(z)
-+z_stream *z;
-+{
-+ uLong c;
-+
-+ if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ if (z->state->blocks != Z_NULL)
-+ inflate_blocks_free(z->state->blocks, z, &c);
-+ ZFREE(z, z->state, sizeof(struct internal_state));
-+ z->state = Z_NULL;
-+ Trace((stderr, "inflate: end\n"));
-+ return Z_OK;
-+}
-+
-+
-+int inflateInit2(z, w)
-+z_stream *z;
-+int w;
-+{
-+ /* initialize state */
-+ if (z == Z_NULL)
-+ return Z_STREAM_ERROR;
-+/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */
-+/* if (z->zfree == Z_NULL) z->zfree = zcfree; */
-+ if ((z->state = (struct internal_state FAR *)
-+ ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
-+ return Z_MEM_ERROR;
-+ z->state->blocks = Z_NULL;
-+
-+ /* handle undocumented nowrap option (no zlib header or check) */
-+ z->state->nowrap = 0;
-+ if (w < 0)
-+ {
-+ w = - w;
-+ z->state->nowrap = 1;
-+ }
-+
-+ /* set window size */
-+ if (w < 8 || w > 15)
-+ {
-+ inflateEnd(z);
-+ return Z_STREAM_ERROR;
-+ }
-+ z->state->wbits = (uInt)w;
-+
-+ /* create inflate_blocks state */
-+ if ((z->state->blocks =
-+ inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w))
-+ == Z_NULL)
-+ {
-+ inflateEnd(z);
-+ return Z_MEM_ERROR;
-+ }
-+ Trace((stderr, "inflate: allocated\n"));
-+
-+ /* reset state */
-+ inflateReset(z);
-+ return Z_OK;
-+}
-+
-+
-+int inflateInit(z)
-+z_stream *z;
-+{
-+ return inflateInit2(z, DEF_WBITS);
-+}
-+
-+
-+#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;}
-+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
-+
-+int inflate(z, f)
-+z_stream *z;
-+int f;
-+{
-+ int r;
-+ uInt b;
-+
-+ if (z == Z_NULL || z->next_in == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ r = Z_BUF_ERROR;
-+ while (1) switch (z->state->mode)
-+ {
-+ case METHOD:
-+ NEEDBYTE
-+ if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = "unknown compression method";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = "invalid window size";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ z->state->mode = FLAG;
-+ case FLAG:
-+ NEEDBYTE
-+ if ((b = NEXTBYTE) & 0x20)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = "invalid reserved bit";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ if (((z->state->sub.method << 8) + b) % 31)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = "incorrect header check";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ Trace((stderr, "inflate: zlib header ok\n"));
-+ z->state->mode = BLOCKS;
-+ case BLOCKS:
-+ r = inflate_blocks(z->state->blocks, z, r);
-+ if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0)
-+ r = inflate_packet_flush(z->state->blocks);
-+ if (r == Z_DATA_ERROR)
-+ {
-+ z->state->mode = BAD;
-+ z->state->sub.marker = 0; /* can try inflateSync */
-+ break;
-+ }
-+ if (r != Z_STREAM_END)
-+ return r;
-+ r = Z_OK;
-+ inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
-+ if (z->state->nowrap)
-+ {
-+ z->state->mode = DONE;
-+ break;
-+ }
-+ z->state->mode = CHECK4;
-+ case CHECK4:
-+ NEEDBYTE
-+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
-+ z->state->mode = CHECK3;
-+ case CHECK3:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
-+ z->state->mode = CHECK2;
-+ case CHECK2:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
-+ z->state->mode = CHECK1;
-+ case CHECK1:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE;
-+
-+ if (z->state->sub.check.was != z->state->sub.check.need)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = "incorrect data check";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ Trace((stderr, "inflate: zlib check ok\n"));
-+ z->state->mode = DONE;
-+ case DONE:
-+ return Z_STREAM_END;
-+ case BAD:
-+ return Z_DATA_ERROR;
-+ default:
-+ return Z_STREAM_ERROR;
-+ }
-+
-+ empty:
-+ if (f != Z_PACKET_FLUSH)
-+ return r;
-+ z->state->mode = BAD;
-+ z->state->sub.marker = 0; /* can try inflateSync */
-+ return Z_DATA_ERROR;
-+}
-+
-+/*
-+ * This subroutine adds the data at next_in/avail_in to the output history
-+ * without performing any output. The output buffer must be "caught up";
-+ * i.e. no pending output (hence s->read equals s->write), and the state must
-+ * be BLOCKS (i.e. we should be willing to see the start of a series of
-+ * BLOCKS). On exit, the output will also be caught up, and the checksum
-+ * will have been updated if need be.
-+ */
-+
-+int inflateIncomp(z)
-+z_stream *z;
-+{
-+ if (z->state->mode != BLOCKS)
-+ return Z_DATA_ERROR;
-+ return inflate_addhistory(z->state->blocks, z);
-+}
-+
-+
-+int inflateSync(z)
-+z_stream *z;
-+{
-+ uInt n; /* number of bytes to look at */
-+ Bytef *p; /* pointer to bytes */
-+ uInt m; /* number of marker bytes found in a row */
-+ uLong r, w; /* temporaries to save total_in and total_out */
-+
-+ /* set up */
-+ if (z == Z_NULL || z->state == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ if (z->state->mode != BAD)
-+ {
-+ z->state->mode = BAD;
-+ z->state->sub.marker = 0;
-+ }
-+ if ((n = z->avail_in) == 0)
-+ return Z_BUF_ERROR;
-+ p = z->next_in;
-+ m = z->state->sub.marker;
-+
-+ /* search */
-+ while (n && m < 4)
-+ {
-+ if (*p == (Byte)(m < 2 ? 0 : 0xff))
-+ m++;
-+ else if (*p)
-+ m = 0;
-+ else
-+ m = 4 - m;
-+ p++, n--;
-+ }
-+
-+ /* restore */
-+ z->total_in += p - z->next_in;
-+ z->next_in = p;
-+ z->avail_in = n;
-+ z->state->sub.marker = m;
-+
-+ /* return no joy or set up to restart on a new block */
-+ if (m != 4)
-+ return Z_DATA_ERROR;
-+ r = z->total_in; w = z->total_out;
-+ inflateReset(z);
-+ z->total_in = r; z->total_out = w;
-+ z->state->mode = BLOCKS;
-+ return Z_OK;
-+}
-+
-+#undef NEEDBYTE
-+#undef NEXTBYTE
-+
-+/*+++++*/
-+/* infutil.h -- types and macros common to blocks and codes
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+/* inflate blocks semi-private state */
-+struct inflate_blocks_state {
-+
-+ /* mode */
-+ enum {
-+ TYPE, /* get type bits (3, including end bit) */
-+ LENS, /* get lengths for stored */
-+ STORED, /* processing stored block */
-+ TABLE, /* get table lengths */
-+ BTREE, /* get bit lengths tree for a dynamic block */
-+ DTREE, /* get length, distance trees for a dynamic block */
-+ CODES, /* processing fixed or dynamic block */
-+ DRY, /* output remaining window bytes */
-+ DONEB, /* finished last block, done */
-+ BADB} /* got a data error--stuck here */
-+ mode; /* current inflate_block mode */
-+
-+ /* mode dependent information */
-+ union {
-+ uInt left; /* if STORED, bytes left to copy */
-+ struct {
-+ uInt table; /* table lengths (14 bits) */
-+ uInt index; /* index into blens (or border) */
-+ uIntf *blens; /* bit lengths of codes */
-+ uInt bb; /* bit length tree depth */
-+ inflate_huft *tb; /* bit length decoding tree */
-+ int nblens; /* # elements allocated at blens */
-+ } trees; /* if DTREE, decoding info for trees */
-+ struct {
-+ inflate_huft *tl, *td; /* trees to free */
-+ inflate_codes_statef
-+ *codes;
-+ } decode; /* if CODES, current state */
-+ } sub; /* submode */
-+ uInt last; /* true if this block is the last block */
-+
-+ /* mode independent information */
-+ uInt bitk; /* bits in bit buffer */
-+ uLong bitb; /* bit buffer */
-+ Bytef *window; /* sliding window */
-+ Bytef *end; /* one byte after sliding window */
-+ Bytef *read; /* window read pointer */
-+ Bytef *write; /* window write pointer */
-+ check_func checkfn; /* check function */
-+ uLong check; /* check on output */
-+
-+};
-+
-+
-+/* defines for inflate input/output */
-+/* update pointers and return */
-+#define UPDBITS {s->bitb=b;s->bitk=k;}
-+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
-+#define UPDOUT {s->write=q;}
-+#define UPDATE {UPDBITS UPDIN UPDOUT}
-+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
-+/* get bytes and bits */
-+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
-+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
-+#define NEXTBYTE (n--,*p++)
-+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-+#define DUMPBITS(j) {b>>=(j);k-=(j);}
-+/* output bytes */
-+#define WAVAIL (q<s->read?s->read-q-1:s->end-q)
-+#define LOADOUT {q=s->write;m=WAVAIL;}
-+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}}
-+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
-+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
-+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
-+/* load local pointers */
-+#define LOAD {LOADIN LOADOUT}
-+
-+/*
-+ * The IBM 150 firmware munges the data right after _etext[]. This
-+ * protects it. -- Cort
-+ */
-+local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0};
-+/* And'ing with mask[n] masks the lower n bits */
-+local uInt inflate_mask[] = {
-+ 0x0000,
-+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
-+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
-+};
-+
-+/* copy as much as possible from the sliding window to the output area */
-+local int inflate_flush OF((
-+ inflate_blocks_statef *,
-+ z_stream *,
-+ int));
-+
-+/*+++++*/
-+/* inffast.h -- header to use inffast.c
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+local int inflate_fast OF((
-+ uInt,
-+ uInt,
-+ inflate_huft *,
-+ inflate_huft *,
-+ inflate_blocks_statef *,
-+ z_stream *));
-+
-+
-+/*+++++*/
-+/* infblock.c -- interpret and process block types to last block
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* Table for deflate from PKZIP's appnote.txt. */
-+local uInt border[] = { /* Order of the bit length code lengths */
-+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-+
-+/*
-+ Notes beyond the 1.93a appnote.txt:
-+
-+ 1. Distance pointers never point before the beginning of the output
-+ stream.
-+ 2. Distance pointers can point back across blocks, up to 32k away.
-+ 3. There is an implied maximum of 7 bits for the bit length table and
-+ 15 bits for the actual data.
-+ 4. If only one code exists, then it is encoded using one bit. (Zero
-+ would be more efficient, but perhaps a little confusing.) If two
-+ codes exist, they are coded using one bit each (0 and 1).
-+ 5. There is no way of sending zero distance codes--a dummy must be
-+ sent if there are none. (History: a pre 2.0 version of PKZIP would
-+ store blocks with no distance codes, but this was discovered to be
-+ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
-+ zero distance codes, which is sent as one code of zero bits in
-+ length.
-+ 6. There are up to 286 literal/length codes. Code 256 represents the
-+ end-of-block. Note however that the static length tree defines
-+ 288 codes just to fill out the Huffman codes. Codes 286 and 287
-+ cannot be used though, since there is no length base or extra bits
-+ defined for them. Similarily, there are up to 30 distance codes.
-+ However, static trees define 32 codes (all 5 bits) to fill out the
-+ Huffman codes, but the last two had better not show up in the data.
-+ 7. Unzip can check dynamic Huffman blocks for complete code sets.
-+ The exception is that a single code would not be complete (see #4).
-+ 8. The five bits following the block type is really the number of
-+ literal codes sent minus 257.
-+ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
-+ (1+6+6). Therefore, to output three times the length, you output
-+ three codes (1+1+1), whereas to output four times the same length,
-+ you only need two codes (1+3). Hmm.
-+ 10. In the tree reconstruction algorithm, Code = Code + Increment
-+ only if BitLength(i) is not zero. (Pretty obvious.)
-+ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
-+ 12. Note: length code 284 can represent 227-258, but length code 285
-+ really is 258. The last length deserves its own, short code
-+ since it gets used a lot in very redundant files. The length
-+ 258 is special since 258 - 3 (the min match length) is 255.
-+ 13. The literal/length and distance code bit lengths are read as a
-+ single stream of lengths. It is possible (and advantageous) for
-+ a repeat code (16, 17, or 18) to go across the boundary between
-+ the two sets of lengths.
-+ */
-+
-+
-+local void inflate_blocks_reset(s, z, c)
-+inflate_blocks_statef *s;
-+z_stream *z;
-+uLongf *c;
-+{
-+ if (s->checkfn != Z_NULL)
-+ *c = s->check;
-+ if (s->mode == BTREE || s->mode == DTREE)
-+ ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
-+ if (s->mode == CODES)
-+ {
-+ inflate_codes_free(s->sub.decode.codes, z);
-+ inflate_trees_free(s->sub.decode.td, z);
-+ inflate_trees_free(s->sub.decode.tl, z);
-+ }
-+ s->mode = TYPE;
-+ s->bitk = 0;
-+ s->bitb = 0;
-+ s->read = s->write = s->window;
-+ if (s->checkfn != Z_NULL)
-+ s->check = (*s->checkfn)(0L, Z_NULL, 0);
-+ Trace((stderr, "inflate: blocks reset\n"));
-+}
-+
-+
-+local inflate_blocks_statef *inflate_blocks_new(z, c, w)
-+z_stream *z;
-+check_func c;
-+uInt w;
-+{
-+ inflate_blocks_statef *s;
-+
-+ if ((s = (inflate_blocks_statef *)ZALLOC
-+ (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
-+ return s;
-+ if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
-+ {
-+ ZFREE(z, s, sizeof(struct inflate_blocks_state));
-+ return Z_NULL;
-+ }
-+ s->end = s->window + w;
-+ s->checkfn = c;
-+ s->mode = TYPE;
-+ Trace((stderr, "inflate: blocks allocated\n"));
-+ inflate_blocks_reset(s, z, &s->check);
-+ return s;
-+}
-+
-+
-+local int inflate_blocks(s, z, r)
-+inflate_blocks_statef *s;
-+z_stream *z;
-+int r;
-+{
-+ uInt t; /* temporary storage */
-+ uLong b; /* bit buffer */
-+ uInt k; /* bits in bit buffer */
-+ Bytef *p; /* input data pointer */
-+ uInt n; /* bytes available there */
-+ Bytef *q; /* output window write pointer */
-+ uInt m; /* bytes to end of window or read pointer */
-+
-+ /* copy input/output information to locals (UPDATE macro restores) */
-+ LOAD
-+
-+ /* process input based on current state */
-+ while (1) switch (s->mode)
-+ {
-+ case TYPE:
-+ NEEDBITS(3)
-+ t = (uInt)b & 7;
-+ s->last = t & 1;
-+ switch (t >> 1)
-+ {
-+ case 0: /* stored */
-+ Trace((stderr, "inflate: stored block%s\n",
-+ s->last ? " (last)" : ""));
-+ DUMPBITS(3)
-+ t = k & 7; /* go to byte boundary */
-+ DUMPBITS(t)
-+ s->mode = LENS; /* get length of stored block */
-+ break;
-+ case 1: /* fixed */
-+ Trace((stderr, "inflate: fixed codes block%s\n",
-+ s->last ? " (last)" : ""));
-+ {
-+ uInt bl, bd;
-+ inflate_huft *tl, *td;
-+
-+ inflate_trees_fixed(&bl, &bd, &tl, &td);
-+ s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
-+ if (s->sub.decode.codes == Z_NULL)
-+ {
-+ r = Z_MEM_ERROR;
-+ LEAVE
-+ }
-+ s->sub.decode.tl = Z_NULL; /* don't try to free these */
-+ s->sub.decode.td = Z_NULL;
-+ }
-+ DUMPBITS(3)
-+ s->mode = CODES;
-+ break;
-+ case 2: /* dynamic */
-+ Trace((stderr, "inflate: dynamic codes block%s\n",
-+ s->last ? " (last)" : ""));
-+ DUMPBITS(3)
-+ s->mode = TABLE;
-+ break;
-+ case 3: /* illegal */
-+ DUMPBITS(3)
-+ s->mode = BADB;
-+ z->msg = "invalid block type";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ }
-+ break;
-+ case LENS:
-+ NEEDBITS(32)
-+ if (((~b) >> 16) != (b & 0xffff))
-+ {
-+ s->mode = BADB;
-+ z->msg = "invalid stored block lengths";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ }
-+ s->sub.left = (uInt)b & 0xffff;
-+ b = k = 0; /* dump bits */
-+ Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
-+ s->mode = s->sub.left ? STORED : TYPE;
-+ break;
-+ case STORED:
-+ if (n == 0)
-+ LEAVE
-+ NEEDOUT
-+ t = s->sub.left;
-+ if (t > n) t = n;
-+ if (t > m) t = m;
-+ zmemcpy(q, p, t);
-+ p += t; n -= t;
-+ q += t; m -= t;
-+ if ((s->sub.left -= t) != 0)
-+ break;
-+ Tracev((stderr, "inflate: stored end, %lu total out\n",
-+ z->total_out + (q >= s->read ? q - s->read :
-+ (s->end - s->read) + (q - s->window))));
-+ s->mode = s->last ? DRY : TYPE;
-+ break;
-+ case TABLE:
-+ NEEDBITS(14)
-+ s->sub.trees.table = t = (uInt)b & 0x3fff;
-+#ifndef PKZIP_BUG_WORKAROUND
-+ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
-+ {
-+ s->mode = BADB;
-+ z->msg = "too many length or distance symbols";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ }
-+#endif
-+ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
-+ if (t < 19)
-+ t = 19;
-+ if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
-+ {
-+ r = Z_MEM_ERROR;
-+ LEAVE
-+ }
-+ s->sub.trees.nblens = t;
-+ DUMPBITS(14)
-+ s->sub.trees.index = 0;
-+ Tracev((stderr, "inflate: table sizes ok\n"));
-+ s->mode = BTREE;
-+ case BTREE:
-+ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
-+ {
-+ NEEDBITS(3)
-+ s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
-+ DUMPBITS(3)
-+ }
-+ while (s->sub.trees.index < 19)
-+ s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
-+ s->sub.trees.bb = 7;
-+ t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
-+ &s->sub.trees.tb, z);
-+ if (t != Z_OK)
-+ {
-+ r = t;
-+ if (r == Z_DATA_ERROR)
-+ s->mode = BADB;
-+ LEAVE
-+ }
-+ s->sub.trees.index = 0;
-+ Tracev((stderr, "inflate: bits tree ok\n"));
-+ s->mode = DTREE;
-+ case DTREE:
-+ while (t = s->sub.trees.table,
-+ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
-+ {
-+ inflate_huft *h;
-+ uInt i, j, c;
-+
-+ t = s->sub.trees.bb;
-+ NEEDBITS(t)
-+ h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
-+ t = h->word.what.Bits;
-+ c = h->more.Base;
-+ if (c < 16)
-+ {
-+ DUMPBITS(t)
-+ s->sub.trees.blens[s->sub.trees.index++] = c;
-+ }
-+ else /* c == 16..18 */
-+ {
-+ i = c == 18 ? 7 : c - 14;
-+ j = c == 18 ? 11 : 3;
-+ NEEDBITS(t + i)
-+ DUMPBITS(t)
-+ j += (uInt)b & inflate_mask[i];
-+ DUMPBITS(i)
-+ i = s->sub.trees.index;
-+ t = s->sub.trees.table;
-+ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
-+ (c == 16 && i < 1))
-+ {
-+ s->mode = BADB;
-+ z->msg = "invalid bit length repeat";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ }
-+ c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
-+ do {
-+ s->sub.trees.blens[i++] = c;
-+ } while (--j);
-+ s->sub.trees.index = i;
-+ }
-+ }
-+ inflate_trees_free(s->sub.trees.tb, z);
-+ s->sub.trees.tb = Z_NULL;
-+ {
-+ uInt bl, bd;
-+ inflate_huft *tl, *td;
-+ inflate_codes_statef *c;
-+
-+ bl = 9; /* must be <= 9 for lookahead assumptions */
-+ bd = 6; /* must be <= 9 for lookahead assumptions */
-+ t = s->sub.trees.table;
-+ t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
-+ s->sub.trees.blens, &bl, &bd, &tl, &td, z);
-+ if (t != Z_OK)
-+ {
-+ if (t == (uInt)Z_DATA_ERROR)
-+ s->mode = BADB;
-+ r = t;
-+ LEAVE
-+ }
-+ Tracev((stderr, "inflate: trees ok\n"));
-+ if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
-+ {
-+ inflate_trees_free(td, z);
-+ inflate_trees_free(tl, z);
-+ r = Z_MEM_ERROR;
-+ LEAVE
-+ }
-+ ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
-+ s->sub.decode.codes = c;
-+ s->sub.decode.tl = tl;
-+ s->sub.decode.td = td;
-+ }
-+ s->mode = CODES;
-+ case CODES:
-+ UPDATE
-+ if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
-+ return inflate_flush(s, z, r);
-+ r = Z_OK;
-+ inflate_codes_free(s->sub.decode.codes, z);
-+ inflate_trees_free(s->sub.decode.td, z);
-+ inflate_trees_free(s->sub.decode.tl, z);
-+ LOAD
-+ Tracev((stderr, "inflate: codes end, %lu total out\n",
-+ z->total_out + (q >= s->read ? q - s->read :
-+ (s->end - s->read) + (q - s->window))));
-+ if (!s->last)
-+ {
-+ s->mode = TYPE;
-+ break;
-+ }
-+ if (k > 7) /* return unused byte, if any */
-+ {
-+ Assert(k < 16, "inflate_codes grabbed too many bytes")
-+ k -= 8;
-+ n++;
-+ p--; /* can always return one */
-+ }
-+ s->mode = DRY;
-+ case DRY:
-+ FLUSH
-+ if (s->read != s->write)
-+ LEAVE
-+ s->mode = DONEB;
-+ case DONEB:
-+ r = Z_STREAM_END;
-+ LEAVE
-+ case BADB:
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ default:
-+ r = Z_STREAM_ERROR;
-+ LEAVE
-+ }
-+}
-+
-+
-+local int inflate_blocks_free(s, z, c)
-+inflate_blocks_statef *s;
-+z_stream *z;
-+uLongf *c;
-+{
-+ inflate_blocks_reset(s, z, c);
-+ ZFREE(z, s->window, s->end - s->window);
-+ ZFREE(z, s, sizeof(struct inflate_blocks_state));
-+ Trace((stderr, "inflate: blocks freed\n"));
-+ return Z_OK;
-+}
-+
-+/*
-+ * This subroutine adds the data at next_in/avail_in to the output history
-+ * without performing any output. The output buffer must be "caught up";
-+ * i.e. no pending output (hence s->read equals s->write), and the state must
-+ * be BLOCKS (i.e. we should be willing to see the start of a series of
-+ * BLOCKS). On exit, the output will also be caught up, and the checksum
-+ * will have been updated if need be.
-+ */
-+local int inflate_addhistory(s, z)
-+inflate_blocks_statef *s;
-+z_stream *z;
-+{
-+ uLong b; /* bit buffer */ /* NOT USED HERE */
-+ uInt k; /* bits in bit buffer */ /* NOT USED HERE */
-+ uInt t; /* temporary storage */
-+ Bytef *p; /* input data pointer */
-+ uInt n; /* bytes available there */
-+ Bytef *q; /* output window write pointer */
-+ uInt m; /* bytes to end of window or read pointer */
-+
-+ if (s->read != s->write)
-+ return Z_STREAM_ERROR;
-+ if (s->mode != TYPE)
-+ return Z_DATA_ERROR;
-+
-+ /* we're ready to rock */
-+ LOAD
-+ /* while there is input ready, copy to output buffer, moving
-+ * pointers as needed.
-+ */
-+ while (n) {
-+ t = n; /* how many to do */
-+ /* is there room until end of buffer? */
-+ if (t > m) t = m;
-+ /* update check information */
-+ if (s->checkfn != Z_NULL)
-+ s->check = (*s->checkfn)(s->check, q, t);
-+ zmemcpy(q, p, t);
-+ q += t;
-+ p += t;
-+ n -= t;
-+ z->total_out += t;
-+ s->read = q; /* drag read pointer forward */
-+/* WRAP */ /* expand WRAP macro by hand to handle s->read */
-+ if (q == s->end) {
-+ s->read = q = s->window;
-+ m = WAVAIL;
-+ }
-+ }
-+ UPDATE
-+ return Z_OK;
-+}
-+
-+
-+/*
-+ * At the end of a Deflate-compressed PPP packet, we expect to have seen
-+ * a `stored' block type value but not the (zero) length bytes.
-+ */
-+local int inflate_packet_flush(s)
-+ inflate_blocks_statef *s;
-+{
-+ if (s->mode != LENS)
-+ return Z_DATA_ERROR;
-+ s->mode = TYPE;
-+ return Z_OK;
-+}
-+
-+
-+/*+++++*/
-+/* inftrees.c -- generate Huffman trees for efficient decoding
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* simplify the use of the inflate_huft type with some defines */
-+#define base more.Base
-+#define next more.Next
-+#define exop word.what.Exop
-+#define bits word.what.Bits
-+
-+
-+local int huft_build OF((
-+ uIntf *, /* code lengths in bits */
-+ uInt, /* number of codes */
-+ uInt, /* number of "simple" codes */
-+ uIntf *, /* list of base values for non-simple codes */
-+ uIntf *, /* list of extra bits for non-simple codes */
-+ inflate_huft * FAR*,/* result: starting table */
-+ uIntf *, /* maximum lookup bits (returns actual) */
-+ z_stream *)); /* for zalloc function */
-+
-+local voidpf falloc OF((
-+ voidpf, /* opaque pointer (not used) */
-+ uInt, /* number of items */
-+ uInt)); /* size of item */
-+
-+local void ffree OF((
-+ voidpf q, /* opaque pointer (not used) */
-+ voidpf p, /* what to free (not used) */
-+ uInt n)); /* number of bytes (not used) */
-+
-+/* Tables for deflate from PKZIP's appnote.txt. */
-+local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */
-+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
-+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
-+ /* actually lengths - 2; also see note #13 above about 258 */
-+local uInt cplext[] = { /* Extra bits for literal codes 257..285 */
-+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
-+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */
-+local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */
-+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
-+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
-+ 8193, 12289, 16385, 24577};
-+local uInt cpdext[] = { /* Extra bits for distance codes */
-+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
-+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
-+ 12, 12, 13, 13};
-+
-+/*
-+ Huffman code decoding is performed using a multi-level table lookup.
-+ The fastest way to decode is to simply build a lookup table whose
-+ size is determined by the longest code. However, the time it takes
-+ to build this table can also be a factor if the data being decoded
-+ is not very long. The most common codes are necessarily the
-+ shortest codes, so those codes dominate the decoding time, and hence
-+ the speed. The idea is you can have a shorter table that decodes the
-+ shorter, more probable codes, and then point to subsidiary tables for
-+ the longer codes. The time it costs to decode the longer codes is
-+ then traded against the time it takes to make longer tables.
-+
-+ This results of this trade are in the variables lbits and dbits
-+ below. lbits is the number of bits the first level table for literal/
-+ length codes can decode in one step, and dbits is the same thing for
-+ the distance codes. Subsequent tables are also less than or equal to
-+ those sizes. These values may be adjusted either when all of the
-+ codes are shorter than that, in which case the longest code length in
-+ bits is used, or when the shortest code is *longer* than the requested
-+ table size, in which case the length of the shortest code in bits is
-+ used.
-+
-+ There are two different values for the two tables, since they code a
-+ different number of possibilities each. The literal/length table
-+ codes 286 possible values, or in a flat code, a little over eight
-+ bits. The distance table codes 30 possible values, or a little less
-+ than five bits, flat. The optimum values for speed end up being
-+ about one bit more than those, so lbits is 8+1 and dbits is 5+1.
-+ The optimum values may differ though from machine to machine, and
-+ possibly even between compilers. Your mileage may vary.
-+ */
-+
-+
-+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
-+#define BMAX 15 /* maximum bit length of any code */
-+#define N_MAX 288 /* maximum number of codes in any set */
-+
-+#ifdef DEBUG_ZLIB
-+ uInt inflate_hufts;
-+#endif
-+
-+local int huft_build(b, n, s, d, e, t, m, zs)
-+uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
-+uInt n; /* number of codes (assumed <= N_MAX) */
-+uInt s; /* number of simple-valued codes (0..s-1) */
-+uIntf *d; /* list of base values for non-simple codes */
-+uIntf *e; /* list of extra bits for non-simple codes */
-+inflate_huft * FAR *t; /* result: starting table */
-+uIntf *m; /* maximum lookup bits, returns actual */
-+z_stream *zs; /* for zalloc function */
-+/* Given a list of code lengths and a maximum table size, make a set of
-+ tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
-+ if the given code set is incomplete (the tables are still built in this
-+ case), Z_DATA_ERROR if the input is invalid (all zero length codes or an
-+ over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */
-+{
-+
-+ uInt a; /* counter for codes of length k */
-+ uInt c[BMAX+1]; /* bit length count table */
-+ uInt f; /* i repeats in table every f entries */
-+ int g; /* maximum code length */
-+ int h; /* table level */
-+ register uInt i; /* counter, current code */
-+ register uInt j; /* counter */
-+ register int k; /* number of bits in current code */
-+ int l; /* bits per table (returned in m) */
-+ register uIntf *p; /* pointer into c[], b[], or v[] */
-+ inflate_huft *q; /* points to current table */
-+ struct inflate_huft_s r; /* table entry for structure assignment */
-+ inflate_huft *u[BMAX]; /* table stack */
-+ uInt v[N_MAX]; /* values in order of bit length */
-+ register int w; /* bits before this table == (l * h) */
-+ uInt x[BMAX+1]; /* bit offsets, then code stack */
-+ uIntf *xp; /* pointer into x */
-+ int y; /* number of dummy codes added */
-+ uInt z; /* number of entries in current table */
-+
-+
-+ /* Generate counts for each bit length */
-+ p = c;
-+#define C0 *p++ = 0;
-+#define C2 C0 C0 C0 C0
-+#define C4 C2 C2 C2 C2
-+ C4 /* clear c[]--assume BMAX+1 is 16 */
-+ p = b; i = n;
-+ do {
-+ c[*p++]++; /* assume all entries <= BMAX */
-+ } while (--i);
-+ if (c[0] == n) /* null input--all zero length codes */
-+ {
-+ *t = (inflate_huft *)Z_NULL;
-+ *m = 0;
-+ return Z_OK;
-+ }
-+
-+
-+ /* Find minimum and maximum length, bound *m by those */
-+ l = *m;
-+ for (j = 1; j <= BMAX; j++)
-+ if (c[j])
-+ break;
-+ k = j; /* minimum code length */
-+ if ((uInt)l < j)
-+ l = j;
-+ for (i = BMAX; i; i--)
-+ if (c[i])
-+ break;
-+ g = i; /* maximum code length */
-+ if ((uInt)l > i)
-+ l = i;
-+ *m = l;
-+
-+
-+ /* Adjust last length count to fill out codes, if needed */
-+ for (y = 1 << j; j < i; j++, y <<= 1)
-+ if ((y -= c[j]) < 0)
-+ return Z_DATA_ERROR;
-+ if ((y -= c[i]) < 0)
-+ return Z_DATA_ERROR;
-+ c[i] += y;
-+
-+
-+ /* Generate starting offsets into the value table for each length */
-+ x[1] = j = 0;
-+ p = c + 1; xp = x + 2;
-+ while (--i) { /* note that i == g from above */
-+ *xp++ = (j += *p++);
-+ }
-+
-+
-+ /* Make a table of values in order of bit lengths */
-+ p = b; i = 0;
-+ do {
-+ if ((j = *p++) != 0)
-+ v[x[j]++] = i;
-+ } while (++i < n);
-+
-+
-+ /* Generate the Huffman codes and for each, make the table entries */
-+ x[0] = i = 0; /* first Huffman code is zero */
-+ p = v; /* grab values in bit order */
-+ h = -1; /* no tables yet--level -1 */
-+ w = -l; /* bits decoded == (l * h) */
-+ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
-+ q = (inflate_huft *)Z_NULL; /* ditto */
-+ z = 0; /* ditto */
-+
-+ /* go through the bit lengths (k already is bits in shortest code) */
-+ for (; k <= g; k++)
-+ {
-+ a = c[k];
-+ while (a--)
-+ {
-+ /* here i is the Huffman code of length k bits for value *p */
-+ /* make tables up to required level */
-+ while (k > w + l)
-+ {
-+ h++;
-+ w += l; /* previous table always l bits */
-+
-+ /* compute minimum size table less than or equal to l bits */
-+ z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */
-+ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
-+ { /* too few codes for k-w bit table */
-+ f -= a + 1; /* deduct codes from patterns left */
-+ xp = c + k;
-+ if (j < z)
-+ while (++j < z) /* try smaller tables up to z bits */
-+ {
-+ if ((f <<= 1) <= *++xp)
-+ break; /* enough codes to use up j bits */
-+ f -= *xp; /* else deduct codes from patterns */
-+ }
-+ }
-+ z = 1 << j; /* table entries for j-bit table */
-+
-+ /* allocate and link in new table */
-+ if ((q = (inflate_huft *)ZALLOC
-+ (zs,z + 1,sizeof(inflate_huft))) == Z_NULL)
-+ {
-+ if (h)
-+ inflate_trees_free(u[0], zs);
-+ return Z_MEM_ERROR; /* not enough memory */
-+ }
-+ q->word.Nalloc = z + 1;
-+#ifdef DEBUG_ZLIB
-+ inflate_hufts += z + 1;
-+#endif
-+ *t = q + 1; /* link to list for huft_free() */
-+ *(t = &(q->next)) = Z_NULL;
-+ u[h] = ++q; /* table starts after link */
-+
-+ /* connect to last table, if there is one */
-+ if (h)
-+ {
-+ x[h] = i; /* save pattern for backing up */
-+ r.bits = (Byte)l; /* bits to dump before this table */
-+ r.exop = (Byte)j; /* bits in this table */
-+ r.next = q; /* pointer to this table */
-+ j = i >> (w - l); /* (get around Turbo C bug) */
-+ u[h-1][j] = r; /* connect to last table */
-+ }
-+ }
-+
-+ /* set up table entry in r */
-+ r.bits = (Byte)(k - w);
-+ if (p >= v + n)
-+ r.exop = 128 + 64; /* out of values--invalid code */
-+ else if (*p < s)
-+ {
-+ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
-+ r.base = *p++; /* simple code is just the value */
-+ }
-+ else
-+ {
-+ r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */
-+ r.base = d[*p++ - s];
-+ }
-+
-+ /* fill code-like entries with r */
-+ f = 1 << (k - w);
-+ for (j = i >> w; j < z; j += f)
-+ q[j] = r;
-+
-+ /* backwards increment the k-bit code i */
-+ for (j = 1 << (k - 1); i & j; j >>= 1)
-+ i ^= j;
-+ i ^= j;
-+
-+ /* backup over finished tables */
-+ while ((i & ((1 << w) - 1)) != x[h])
-+ {
-+ h--; /* don't need to update q */
-+ w -= l;
-+ }
-+ }
-+ }
-+
-+
-+ /* Return Z_BUF_ERROR if we were given an incomplete table */
-+ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
-+}
-+
-+
-+local int inflate_trees_bits(c, bb, tb, z)
-+uIntf *c; /* 19 code lengths */
-+uIntf *bb; /* bits tree desired/actual depth */
-+inflate_huft * FAR *tb; /* bits tree result */
-+z_stream *z; /* for zfree function */
-+{
-+ int r;
-+
-+ r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z);
-+ if (r == Z_DATA_ERROR)
-+ z->msg = "oversubscribed dynamic bit lengths tree";
-+ else if (r == Z_BUF_ERROR)
-+ {
-+ inflate_trees_free(*tb, z);
-+ z->msg = "incomplete dynamic bit lengths tree";
-+ r = Z_DATA_ERROR;
-+ }
-+ return r;
-+}
-+
-+
-+local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z)
-+uInt nl; /* number of literal/length codes */
-+uInt nd; /* number of distance codes */
-+uIntf *c; /* that many (total) code lengths */
-+uIntf *bl; /* literal desired/actual bit depth */
-+uIntf *bd; /* distance desired/actual bit depth */
-+inflate_huft * FAR *tl; /* literal/length tree result */
-+inflate_huft * FAR *td; /* distance tree result */
-+z_stream *z; /* for zfree function */
-+{
-+ int r;
-+
-+ /* build literal/length tree */
-+ if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK)
-+ {
-+ if (r == Z_DATA_ERROR)
-+ z->msg = "oversubscribed literal/length tree";
-+ else if (r == Z_BUF_ERROR)
-+ {
-+ inflate_trees_free(*tl, z);
-+ z->msg = "incomplete literal/length tree";
-+ r = Z_DATA_ERROR;
-+ }
-+ return r;
-+ }
-+
-+ /* build distance tree */
-+ if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK)
-+ {
-+ if (r == Z_DATA_ERROR)
-+ z->msg = "oversubscribed literal/length tree";
-+ else if (r == Z_BUF_ERROR) {
-+#ifdef PKZIP_BUG_WORKAROUND
-+ r = Z_OK;
-+ }
-+#else
-+ inflate_trees_free(*td, z);
-+ z->msg = "incomplete literal/length tree";
-+ r = Z_DATA_ERROR;
-+ }
-+ inflate_trees_free(*tl, z);
-+ return r;
-+#endif
-+ }
-+
-+ /* done */
-+ return Z_OK;
-+}
-+
-+
-+/* build fixed tables only once--keep them here */
-+local int fixed_lock = 0;
-+local int fixed_built = 0;
-+#define FIXEDH 530 /* number of hufts used by fixed tables */
-+local uInt fixed_left = FIXEDH;
-+local inflate_huft fixed_mem[FIXEDH];
-+local uInt fixed_bl;
-+local uInt fixed_bd;
-+local inflate_huft *fixed_tl;
-+local inflate_huft *fixed_td;
-+
-+
-+local voidpf falloc(q, n, s)
-+voidpf q; /* opaque pointer (not used) */
-+uInt n; /* number of items */
-+uInt s; /* size of item */
-+{
-+ Assert(s == sizeof(inflate_huft) && n <= fixed_left,
-+ "inflate_trees falloc overflow");
-+ if (q) s++; /* to make some compilers happy */
-+ fixed_left -= n;
-+ return (voidpf)(fixed_mem + fixed_left);
-+}
-+
-+
-+local void ffree(q, p, n)
-+voidpf q;
-+voidpf p;
-+uInt n;
-+{
-+ Assert(0, "inflate_trees ffree called!");
-+ if (q) q = p; /* to make some compilers happy */
-+}
-+
-+
-+local int inflate_trees_fixed(bl, bd, tl, td)
-+uIntf *bl; /* literal desired/actual bit depth */
-+uIntf *bd; /* distance desired/actual bit depth */
-+inflate_huft * FAR *tl; /* literal/length tree result */
-+inflate_huft * FAR *td; /* distance tree result */
-+{
-+ /* build fixed tables if not built already--lock out other instances */
-+ while (++fixed_lock > 1)
-+ fixed_lock--;
-+ if (!fixed_built)
-+ {
-+ int k; /* temporary variable */
-+ unsigned c[288]; /* length list for huft_build */
-+ z_stream z; /* for falloc function */
-+
-+ /* set up fake z_stream for memory routines */
-+ z.zalloc = falloc;
-+ z.zfree = ffree;
-+ z.opaque = Z_NULL;
-+
-+ /* literal table */
-+ for (k = 0; k < 144; k++)
-+ c[k] = 8;
-+ for (; k < 256; k++)
-+ c[k] = 9;
-+ for (; k < 280; k++)
-+ c[k] = 7;
-+ for (; k < 288; k++)
-+ c[k] = 8;
-+ fixed_bl = 7;
-+ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z);
-+
-+ /* distance table */
-+ for (k = 0; k < 30; k++)
-+ c[k] = 5;
-+ fixed_bd = 5;
-+ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z);
-+
-+ /* done */
-+ fixed_built = 1;
-+ }
-+ fixed_lock--;
-+ *bl = fixed_bl;
-+ *bd = fixed_bd;
-+ *tl = fixed_tl;
-+ *td = fixed_td;
-+ return Z_OK;
-+}
-+
-+
-+local int inflate_trees_free(t, z)
-+inflate_huft *t; /* table to free */
-+z_stream *z; /* for zfree function */
-+/* Free the malloc'ed tables built by huft_build(), which makes a linked
-+ list of the tables it made, with the links in a dummy first entry of
-+ each table. */
-+{
-+ register inflate_huft *p, *q;
-+
-+ /* Go through linked list, freeing from the malloced (t[-1]) address. */
-+ p = t;
-+ while (p != Z_NULL)
-+ {
-+ q = (--p)->next;
-+ ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft));
-+ p = q;
-+ }
-+ return Z_OK;
-+}
-+
-+/*+++++*/
-+/* infcodes.c -- process literals and length/distance pairs
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* simplify the use of the inflate_huft type with some defines */
-+#define base more.Base
-+#define next more.Next
-+#define exop word.what.Exop
-+#define bits word.what.Bits
-+
-+/* inflate codes private state */
-+struct inflate_codes_state {
-+
-+ /* mode */
-+ enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
-+ START, /* x: set up for LEN */
-+ LEN, /* i: get length/literal/eob next */
-+ LENEXT, /* i: getting length extra (have base) */
-+ DIST, /* i: get distance next */
-+ DISTEXT, /* i: getting distance extra */
-+ COPY, /* o: copying bytes in window, waiting for space */
-+ LIT, /* o: got literal, waiting for output space */
-+ WASH, /* o: got eob, possibly still output waiting */
-+ END, /* x: got eob and all data flushed */
-+ BADCODE} /* x: got error */
-+ mode; /* current inflate_codes mode */
-+
-+ /* mode dependent information */
-+ uInt len;
-+ union {
-+ struct {
-+ inflate_huft *tree; /* pointer into tree */
-+ uInt need; /* bits needed */
-+ } code; /* if LEN or DIST, where in tree */
-+ uInt lit; /* if LIT, literal */
-+ struct {
-+ uInt get; /* bits to get for extra */
-+ uInt dist; /* distance back to copy from */
-+ } copy; /* if EXT or COPY, where and how much */
-+ } sub; /* submode */
-+
-+ /* mode independent information */
-+ Byte lbits; /* ltree bits decoded per branch */
-+ Byte dbits; /* dtree bits decoder per branch */
-+ inflate_huft *ltree; /* literal/length/eob tree */
-+ inflate_huft *dtree; /* distance tree */
-+
-+};
-+
-+
-+local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
-+uInt bl, bd;
-+inflate_huft *tl, *td;
-+z_stream *z;
-+{
-+ inflate_codes_statef *c;
-+
-+ if ((c = (inflate_codes_statef *)
-+ ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
-+ {
-+ c->mode = START;
-+ c->lbits = (Byte)bl;
-+ c->dbits = (Byte)bd;
-+ c->ltree = tl;
-+ c->dtree = td;
-+ Tracev((stderr, "inflate: codes new\n"));
-+ }
-+ return c;
-+}
-+
-+
-+local int inflate_codes(s, z, r)
-+inflate_blocks_statef *s;
-+z_stream *z;
-+int r;
-+{
-+ uInt j; /* temporary storage */
-+ inflate_huft *t; /* temporary pointer */
-+ uInt e; /* extra bits or operation */
-+ uLong b; /* bit buffer */
-+ uInt k; /* bits in bit buffer */
-+ Bytef *p; /* input data pointer */
-+ uInt n; /* bytes available there */
-+ Bytef *q; /* output window write pointer */
-+ uInt m; /* bytes to end of window or read pointer */
-+ Bytef *f; /* pointer to copy strings from */
-+ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
-+
-+ /* copy input/output information to locals (UPDATE macro restores) */
-+ LOAD
-+
-+ /* process input and output based on current state */
-+ while (1) switch (c->mode)
-+ { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
-+ case START: /* x: set up for LEN */
-+#ifndef SLOW
-+ if (m >= 258 && n >= 10)
-+ {
-+ UPDATE
-+ r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
-+ LOAD
-+ if (r != Z_OK)
-+ {
-+ c->mode = r == Z_STREAM_END ? WASH : BADCODE;
-+ break;
-+ }
-+ }
-+#endif /* !SLOW */
-+ c->sub.code.need = c->lbits;
-+ c->sub.code.tree = c->ltree;
-+ c->mode = LEN;
-+ case LEN: /* i: get length/literal/eob next */
-+ j = c->sub.code.need;
-+ NEEDBITS(j)
-+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
-+ DUMPBITS(t->bits)
-+ e = (uInt)(t->exop);
-+ if (e == 0) /* literal */
-+ {
-+ c->sub.lit = t->base;
-+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-+ "inflate: literal '%c'\n" :
-+ "inflate: literal 0x%02x\n", t->base));
-+ c->mode = LIT;
-+ break;
-+ }
-+ if (e & 16) /* length */
-+ {
-+ c->sub.copy.get = e & 15;
-+ c->len = t->base;
-+ c->mode = LENEXT;
-+ break;
-+ }
-+ if ((e & 64) == 0) /* next table */
-+ {
-+ c->sub.code.need = e;
-+ c->sub.code.tree = t->next;
-+ break;
-+ }
-+ if (e & 32) /* end of block */
-+ {
-+ Tracevv((stderr, "inflate: end of block\n"));
-+ c->mode = WASH;
-+ break;
-+ }
-+ c->mode = BADCODE; /* invalid code */
-+ z->msg = "invalid literal/length code";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ case LENEXT: /* i: getting length extra (have base) */
-+ j = c->sub.copy.get;
-+ NEEDBITS(j)
-+ c->len += (uInt)b & inflate_mask[j];
-+ DUMPBITS(j)
-+ c->sub.code.need = c->dbits;
-+ c->sub.code.tree = c->dtree;
-+ Tracevv((stderr, "inflate: length %u\n", c->len));
-+ c->mode = DIST;
-+ case DIST: /* i: get distance next */
-+ j = c->sub.code.need;
-+ NEEDBITS(j)
-+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
-+ DUMPBITS(t->bits)
-+ e = (uInt)(t->exop);
-+ if (e & 16) /* distance */
-+ {
-+ c->sub.copy.get = e & 15;
-+ c->sub.copy.dist = t->base;
-+ c->mode = DISTEXT;
-+ break;
-+ }
-+ if ((e & 64) == 0) /* next table */
-+ {
-+ c->sub.code.need = e;
-+ c->sub.code.tree = t->next;
-+ break;
-+ }
-+ c->mode = BADCODE; /* invalid code */
-+ z->msg = "invalid distance code";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ case DISTEXT: /* i: getting distance extra */
-+ j = c->sub.copy.get;
-+ NEEDBITS(j)
-+ c->sub.copy.dist += (uInt)b & inflate_mask[j];
-+ DUMPBITS(j)
-+ Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
-+ c->mode = COPY;
-+ case COPY: /* o: copying bytes in window, waiting for space */
-+#ifndef __TURBOC__ /* Turbo C bug for following expression */
-+ f = (uInt)(q - s->window) < c->sub.copy.dist ?
-+ s->end - (c->sub.copy.dist - (q - s->window)) :
-+ q - c->sub.copy.dist;
-+#else
-+ f = q - c->sub.copy.dist;
-+ if ((uInt)(q - s->window) < c->sub.copy.dist)
-+ f = s->end - (c->sub.copy.dist - (q - s->window));
-+#endif
-+ while (c->len)
-+ {
-+ NEEDOUT
-+ OUTBYTE(*f++)
-+ if (f == s->end)
-+ f = s->window;
-+ c->len--;
-+ }
-+ c->mode = START;
-+ break;
-+ case LIT: /* o: got literal, waiting for output space */
-+ NEEDOUT
-+ OUTBYTE(c->sub.lit)
-+ c->mode = START;
-+ break;
-+ case WASH: /* o: got eob, possibly more output */
-+ FLUSH
-+ if (s->read != s->write)
-+ LEAVE
-+ c->mode = END;
-+ case END:
-+ r = Z_STREAM_END;
-+ LEAVE
-+ case BADCODE: /* x: got error */
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ default:
-+ r = Z_STREAM_ERROR;
-+ LEAVE
-+ }
-+}
-+
-+
-+local void inflate_codes_free(c, z)
-+inflate_codes_statef *c;
-+z_stream *z;
-+{
-+ ZFREE(z, c, sizeof(struct inflate_codes_state));
-+ Tracev((stderr, "inflate: codes free\n"));
-+}
-+
-+/*+++++*/
-+/* inflate_util.c -- data and routines common to blocks and codes
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* copy as much as possible from the sliding window to the output area */
-+local int inflate_flush(s, z, r)
-+inflate_blocks_statef *s;
-+z_stream *z;
-+int r;
-+{
-+ uInt n;
-+ Bytef *p, *q;
-+
-+ /* local copies of source and destination pointers */
-+ p = z->next_out;
-+ q = s->read;
-+
-+ /* compute number of bytes to copy as far as end of window */
-+ n = (uInt)((q <= s->write ? s->write : s->end) - q);
-+ if (n > z->avail_out) n = z->avail_out;
-+ if (n && r == Z_BUF_ERROR) r = Z_OK;
-+
-+ /* update counters */
-+ z->avail_out -= n;
-+ z->total_out += n;
-+
-+ /* update check information */
-+ if (s->checkfn != Z_NULL)
-+ s->check = (*s->checkfn)(s->check, q, n);
-+
-+ /* copy as far as end of window */
-+ zmemcpy(p, q, n);
-+ p += n;
-+ q += n;
-+
-+ /* see if more to copy at beginning of window */
-+ if (q == s->end)
-+ {
-+ /* wrap pointers */
-+ q = s->window;
-+ if (s->write == s->end)
-+ s->write = s->window;
-+
-+ /* compute bytes to copy */
-+ n = (uInt)(s->write - q);
-+ if (n > z->avail_out) n = z->avail_out;
-+ if (n && r == Z_BUF_ERROR) r = Z_OK;
-+
-+ /* update counters */
-+ z->avail_out -= n;
-+ z->total_out += n;
-+
-+ /* update check information */
-+ if (s->checkfn != Z_NULL)
-+ s->check = (*s->checkfn)(s->check, q, n);
-+
-+ /* copy */
-+ zmemcpy(p, q, n);
-+ p += n;
-+ q += n;
-+ }
-+
-+ /* update pointers */
-+ z->next_out = p;
-+ s->read = q;
-+
-+ /* done */
-+ return r;
-+}
-+
-+
-+/*+++++*/
-+/* inffast.c -- process literals and length/distance pairs fast
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* simplify the use of the inflate_huft type with some defines */
-+#define base more.Base
-+#define next more.Next
-+#define exop word.what.Exop
-+#define bits word.what.Bits
-+
-+/* macros for bit input with no checking and for returning unused bytes */
-+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-+#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;}
-+
-+/* Called with number of bytes left to write in window at least 258
-+ (the maximum string length) and number of input bytes available
-+ at least ten. The ten bytes are six bytes for the longest length/
-+ distance pair plus four bytes for overloading the bit buffer. */
-+
-+local int inflate_fast(bl, bd, tl, td, s, z)
-+uInt bl, bd;
-+inflate_huft *tl, *td;
-+inflate_blocks_statef *s;
-+z_stream *z;
-+{
-+ inflate_huft *t; /* temporary pointer */
-+ uInt e; /* extra bits or operation */
-+ uLong b; /* bit buffer */
-+ uInt k; /* bits in bit buffer */
-+ Bytef *p; /* input data pointer */
-+ uInt n; /* bytes available there */
-+ Bytef *q; /* output window write pointer */
-+ uInt m; /* bytes to end of window or read pointer */
-+ uInt ml; /* mask for literal/length tree */
-+ uInt md; /* mask for distance tree */
-+ uInt c; /* bytes to copy */
-+ uInt d; /* distance back to copy from */
-+ Bytef *r; /* copy source pointer */
-+
-+ /* load input, output, bit values */
-+ LOAD
-+
-+ /* initialize masks */
-+ ml = inflate_mask[bl];
-+ md = inflate_mask[bd];
-+
-+ /* do until not enough input or output space for fast loop */
-+ do { /* assume called with m >= 258 && n >= 10 */
-+ /* get literal/length code */
-+ GRABBITS(20) /* max bits for literal/length code */
-+ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
-+ {
-+ DUMPBITS(t->bits)
-+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-+ "inflate: * literal '%c'\n" :
-+ "inflate: * literal 0x%02x\n", t->base));
-+ *q++ = (Byte)t->base;
-+ m--;
-+ continue;
-+ }
-+ do {
-+ DUMPBITS(t->bits)
-+ if (e & 16)
-+ {
-+ /* get extra bits for length */
-+ e &= 15;
-+ c = t->base + ((uInt)b & inflate_mask[e]);
-+ DUMPBITS(e)
-+ Tracevv((stderr, "inflate: * length %u\n", c));
-+
-+ /* decode distance base of block to copy */
-+ GRABBITS(15); /* max bits for distance code */
-+ e = (t = td + ((uInt)b & md))->exop;
-+ do {
-+ DUMPBITS(t->bits)
-+ if (e & 16)
-+ {
-+ /* get extra bits to add to distance base */
-+ e &= 15;
-+ GRABBITS(e) /* get extra bits (up to 13) */
-+ d = t->base + ((uInt)b & inflate_mask[e]);
-+ DUMPBITS(e)
-+ Tracevv((stderr, "inflate: * distance %u\n", d));
-+
-+ /* do the copy */
-+ m -= c;
-+ if ((uInt)(q - s->window) >= d) /* offset before dest */
-+ { /* just copy */
-+ r = q - d;
-+ *q++ = *r++; c--; /* minimum count is three, */
-+ *q++ = *r++; c--; /* so unroll loop a little */
-+ }
-+ else /* else offset after destination */
-+ {
-+ e = d - (q - s->window); /* bytes from offset to end */
-+ r = s->end - e; /* pointer to offset */
-+ if (c > e) /* if source crosses, */
-+ {
-+ c -= e; /* copy to end of window */
-+ do {
-+ *q++ = *r++;
-+ } while (--e);
-+ r = s->window; /* copy rest from start of window */
-+ }
-+ }
-+ do { /* copy all or what's left */
-+ *q++ = *r++;
-+ } while (--c);
-+ break;
-+ }
-+ else if ((e & 64) == 0)
-+ e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
-+ else
-+ {
-+ z->msg = "invalid distance code";
-+ UNGRAB
-+ UPDATE
-+ return Z_DATA_ERROR;
-+ }
-+ } while (1);
-+ break;
-+ }
-+ if ((e & 64) == 0)
-+ {
-+ if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0)
-+ {
-+ DUMPBITS(t->bits)
-+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-+ "inflate: * literal '%c'\n" :
-+ "inflate: * literal 0x%02x\n", t->base));
-+ *q++ = (Byte)t->base;
-+ m--;
-+ break;
-+ }
-+ }
-+ else if (e & 32)
-+ {
-+ Tracevv((stderr, "inflate: * end of block\n"));
-+ UNGRAB
-+ UPDATE
-+ return Z_STREAM_END;
-+ }
-+ else
-+ {
-+ z->msg = "invalid literal/length code";
-+ UNGRAB
-+ UPDATE
-+ return Z_DATA_ERROR;
-+ }
-+ } while (1);
-+ } while (m >= 258 && n >= 10);
-+
-+ /* not enough input or output--restore pointers and return */
-+ UNGRAB
-+ UPDATE
-+ return Z_OK;
-+}
-+
-+
-+/*+++++*/
-+/* zutil.c -- target dependent utility functions for the compression library
-+ * Copyright (C) 1995 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */
-+
-+char *zlib_version = ZLIB_VERSION;
-+
-+char *z_errmsg[] = {
-+"stream end", /* Z_STREAM_END 1 */
-+"", /* Z_OK 0 */
-+"file error", /* Z_ERRNO (-1) */
-+"stream error", /* Z_STREAM_ERROR (-2) */
-+"data error", /* Z_DATA_ERROR (-3) */
-+"insufficient memory", /* Z_MEM_ERROR (-4) */
-+"buffer error", /* Z_BUF_ERROR (-5) */
-+""};
-+
-+
-+/*+++++*/
-+/* adler32.c -- compute the Adler-32 checksum of a data stream
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */
-+
-+#define BASE 65521L /* largest prime smaller than 65536 */
-+#define NMAX 5552
-+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-+
-+#define DO1(buf) {s1 += *buf++; s2 += s1;}
-+#define DO2(buf) DO1(buf); DO1(buf);
-+#define DO4(buf) DO2(buf); DO2(buf);
-+#define DO8(buf) DO4(buf); DO4(buf);
-+#define DO16(buf) DO8(buf); DO8(buf);
-+
-+/* ========================================================================= */
-+uLong adler32(adler, buf, len)
-+ uLong adler;
-+ Bytef *buf;
-+ uInt len;
-+{
-+ unsigned long s1 = adler & 0xffff;
-+ unsigned long s2 = (adler >> 16) & 0xffff;
-+ int k;
-+
-+ if (buf == Z_NULL) return 1L;
-+
-+ while (len > 0) {
-+ k = len < NMAX ? len : NMAX;
-+ len -= k;
-+ while (k >= 16) {
-+ DO16(buf);
-+ k -= 16;
-+ }
-+ if (k != 0) do {
-+ DO1(buf);
-+ } while (--k);
-+ s1 %= BASE;
-+ s2 %= BASE;
-+ }
-+ return (s2 << 16) | s1;
-+}
-diff -Naru linux/arch/mips/zboot/Makefile linux-new/arch/mips/zboot/Makefile
---- linux/arch/mips/zboot/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/Makefile 2003-12-18 14:26:21.000000000 -0500
-@@ -0,0 +1,79 @@
-+#
-+# arch/mips/zboot/Makefile
-+#
-+# This file is subject to the terms and conditions of the GNU General Public
-+# License. See the file "COPYING" in the main directory of this archive
-+# for more details.
-+
-+# Adapted for MIPS Pete Popov, Dan Malek
-+#
-+# Copyright (C) 1994 by Linus Torvalds
-+# Adapted for PowerPC by Gary Thomas
-+# modified by Cort (cort@cs.nmt.edu)
-+#
-+
-+.c.s:
-+ $(CC) $(CFLAGS) -S -o $*.s $<
-+.s.o:
-+ $(AS) -o $*.o $<
-+.c.o:
-+ $(CC) $(CFLAGS) -c -o $*.o $<
-+.S.s:
-+ $(CPP) $(AFLAGS) -o $*.o $<
-+.S.o:
-+ $(CC) $(AFLAGS) -c -o $*.o $<
-+
-+GZIP_FLAGS = -v9f
-+
-+CFLAGS := $(CPPFLAGS) -O2 -D__BOOTER__ \
-+ -fomit-frame-pointer -fno-strict-aliasing -fno-common \
-+ -G 0 -mno-abicalls -fno-pic -mcpu=r4600 -mips2 \
-+ -I$(TOPDIR)/arch/$(ARCH)/zboot/include \
-+ -I$(TOPDIR)/include/asm
-+AFLAGS += -D__BOOTER__
-+
-+BOOT_TARGETS = zImage zImage.initrd zImage.flash zImage.initrd.flash
-+
-+lib/zlib.a:
-+ $(MAKE) -C lib
-+
-+images/vmlinux.gz: $(TOPDIR)/vmlinux
-+ $(MAKE) -C images vmlinux.gz
-+
-+$(BOOT_TARGETS): lib/zlib.a images/vmlinux.gz
-+ifdef CONFIG_MIPS_PB1000
-+ $(MAKE) -C pb1xxx $@
-+endif
-+ifdef CONFIG_MIPS_PB1500
-+ $(MAKE) -C pb1xxx $@
-+endif
-+ifdef CONFIG_MIPS_PB1100
-+ $(MAKE) -C pb1xxx $@
-+endif
-+ifdef CONFIG_MIPS_DB1000
-+ $(MAKE) -C pb1xxx $@
-+endif
-+ifdef CONFIG_MIPS_DB1100
-+ $(MAKE) -C pb1xxx $@
-+endif
-+ifdef CONFIG_MIPS_DB1500
-+ $(MAKE) -C pb1xxx $@
-+endif
-+ifdef CONFIG_MIPS_BOSPORUS
-+ $(MAKE) -C pb1xxx $@
-+endif
-+ifdef CONFIG_COGENT_CSB250
-+ $(MAKE) -C csb250 $@
-+endif
-+ifdef CONFIG_MIPS_XXS1500
-+BOOT_DIR = xxs1500
-+endif
-+
-+# Do the dirs
-+clean:
-+ $(MAKE) -C common clean
-+ $(MAKE) -C images clean
-+ $(MAKE) -C pb1xxx clean
-+ $(MAKE) -C xxs1500 clean
-+
-+include $(TOPDIR)/Rules.make
-diff -Naru linux/arch/mips/zboot/pb1xxx/head.S linux-new/arch/mips/zboot/pb1xxx/head.S
---- linux/arch/mips/zboot/pb1xxx/head.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/pb1xxx/head.S 2003-12-18 14:26:21.000000000 -0500
-@@ -0,0 +1,149 @@
-+/*
-+ * arch/mips/kernel/head.S
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file "COPYING" in the main directory of this archive
-+ * for more details.
-+ *
-+ * Copyright (C) 1994, 1995 Waldorf Electronics
-+ * Written by Ralf Baechle and Andreas Busse
-+ * Copyright (C) 1995 - 1999 Ralf Baechle
-+ * Copyright (C) 1996 Paul M. Antoine
-+ * Modified for DECStation and hence R3000 support by Paul M. Antoine
-+ * Further modifications by David S. Miller and Harald Koerfgen
-+ * Copyright (C) 1999 Silicon Graphics, Inc.
-+ *
-+ * Head.S contains the MIPS exception handler and startup code.
-+ *
-+ **************************************************************************
-+ * 9 Nov, 2000.
-+ * Added Cache Error exception handler and SBDDP EJTAG debug exception.
-+ *
-+ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
-+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
-+ **************************************************************************
-+ */
-+#include <linux/config.h>
-+#include <linux/threads.h>
-+
-+#include <asm/asm.h>
-+#include <asm/cacheops.h>
-+#include <asm/mipsregs.h>
-+#include <asm/offset.h>
-+#include <asm/cachectl.h>
-+#include <asm/regdef.h>
-+
-+#define IndexInvalidate_I 0x00
-+#define IndexWriteBack_D 0x01
-+
-+ .set noreorder
-+ .cprestore
-+ LEAF(start)
-+start:
-+ bal locate
-+ nop
-+locate:
-+ subu s8, ra, 8 /* Where we were loaded */
-+ la sp, (.stack + 8192)
-+
-+ move s0, a0 /* Save boot rom start args */
-+ move s1, a1
-+ move s2, a2
-+ move s3, a3
-+
-+ la a0, start /* Where we were linked to run */
-+
-+ move a1, s8
-+ la a2, _edata
-+ subu t1, a2, a0
-+ srl t1, t1, 2
-+
-+ /* copy text section */
-+ li t0, 0
-+1: lw v0, 0(a1)
-+ nop
-+ sw v0, 0(a0)
-+ xor t0, t0, v0
-+ addu a0, 4
-+ bne a2, a0, 1b
-+ addu a1, 4
-+
-+ /* Clear BSS */
-+ la a0, _edata
-+ la a2, _end
-+2: sw zero, 0(a0)
-+ bne a2, a0, 2b
-+ addu a0, 4
-+
-+ /* push the D-Cache and invalidate I-Cache */
-+ li k0, 0x80000000 # start address
-+ li k1, 0x80004000 # end address (16KB I-Cache)
-+ subu k1, 128
-+
-+1:
-+ .set mips3
-+ cache IndexWriteBack_D, 0(k0)
-+ cache IndexWriteBack_D, 32(k0)
-+ cache IndexWriteBack_D, 64(k0)
-+ cache IndexWriteBack_D, 96(k0)
-+ cache IndexInvalidate_I, 0(k0)
-+ cache IndexInvalidate_I, 32(k0)
-+ cache IndexInvalidate_I, 64(k0)
-+ cache IndexInvalidate_I, 96(k0)
-+ .set mips0
-+
-+ bne k0, k1, 1b
-+ addu k0, k0, 128
-+ /* done */
-+
-+ move a0, s8 /* load address */
-+ move a1, t1 /* length in words */
-+ move a2, t0 /* checksum */
-+ move a3, sp
-+
-+ la ra, 1f
-+ la k0, decompress_kernel
-+ jr k0
-+ nop
-+1:
-+
-+ move a0, s0
-+ move a1, s1
-+ move a2, s2
-+ move a3, s3
-+ li k0, KERNEL_ENTRY
-+ jr k0
-+ nop
-+3:
-+ b 3b
-+ END(start)
-+
-+ LEAF(udelay)
-+udelay:
-+ END(udelay)
-+
-+
-+ LEAF(FlushCache)
-+ li k0, 0x80000000 # start address
-+ li k1, 0x80004000 # end address (16KB I-Cache)
-+ subu k1, 128
-+
-+1:
-+ .set mips3
-+ cache IndexWriteBack_D, 0(k0)
-+ cache IndexWriteBack_D, 32(k0)
-+ cache IndexWriteBack_D, 64(k0)
-+ cache IndexWriteBack_D, 96(k0)
-+ cache IndexInvalidate_I, 0(k0)
-+ cache IndexInvalidate_I, 32(k0)
-+ cache IndexInvalidate_I, 64(k0)
-+ cache IndexInvalidate_I, 96(k0)
-+ .set mips0
-+
-+ bne k0, k1, 1b
-+ addu k0, k0, 128
-+ jr ra
-+ nop
-+ END(FlushCache)
-+
-+ .comm .stack,4096*2,4
-diff -Naru linux/arch/mips/zboot/pb1xxx/Makefile linux-new/arch/mips/zboot/pb1xxx/Makefile
---- linux/arch/mips/zboot/pb1xxx/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/pb1xxx/Makefile 2003-12-18 14:26:21.000000000 -0500
-@@ -0,0 +1,123 @@
-+# arch/mips/zboot/pb1xxx/Makefile
-+#
-+# Makefile for Alchemy Semiconductor Pb1[015]00 boards.
-+# All of the boot loader code was derived from the ppc
-+# boot code.
-+#
-+# Copyright 2001,2002 MontaVista Software Inc.
-+#
-+# Author: Mark A. Greer
-+# mgreer@mvista.com
-+# Ported and modified for mips support by
-+# Pete Popov <ppopov@mvista.com>
-+#
-+# 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.
-+
-+.c.s:
-+ $(CC) $(CFLAGS) -S -o $*.s $<
-+.s.o:
-+ $(AS) -o $*.o $<
-+.c.o:
-+ $(CC) $(CFLAGS) -D__BOOTER__ -c -o $*.o $<
-+.S.s:
-+ $(CPP) $(AFLAGS) -o $*.o $<
-+.S.o:
-+ $(CC) $(AFLAGS) -c -o $*.o $<
-+
-+#########################################################################
-+# START BOARD SPECIFIC VARIABLES
-+ifdef CONFIG_MIPS_PB1000
-+BNAME=pb1000
-+endif
-+
-+ifdef CONFIG_MIPS_PB1100
-+BNAME=pb1100
-+endif
-+
-+ifdef CONFIG_MIPS_PB1500
-+BNAME=pb1500
-+endif
-+
-+ifdef CONFIG_MIPS_DB1000
-+BNAME=db1000
-+endif
-+
-+ifdef CONFIG_MIPS_DB1100
-+BNAME=db1100
-+endif
-+
-+ifdef CONFIG_MIPS_DB1500
-+BNAME=db1500
-+endif
-+
-+ifdef CONFIG_MIPS_BOSPORUS
-+BNAME=bosporus
-+endif
-+
-+# These two variables control where the zImage is stored
-+# in flash and loaded in memory. It only controls how the srec
-+# file is generated, the code is the same.
-+RAM_RUN_ADDR = 0x81000000
-+FLASH_LOAD_ADDR = 0xBFD00000
-+
-+# These two variables specify the free ram region
-+# that can be used for temporary malloc area
-+AVAIL_RAM_START=0x80400000
-+AVAIL_RAM_END=0x80800000
-+
-+# This one must match the LOADADDR in arch/mips/Makefile!
-+LOADADDR=0x80100000
-+# END BOARD SPECIFIC VARIABLES
-+#########################################################################
-+
-+OBJECTS := head.o ../common/misc-common.o ../common/misc-simple.o \
-+ ../common/au1k_uart.o ../common/string.o ../common/ctype.o
-+LIBS := ../lib/zlib.a
-+
-+ENTRY := ../utils/entry
-+OFFSET := ../utils/offset
-+SIZE := ../utils/size
-+
-+LD_ARGS := -T ../ld.script -Ttext $(RAM_RUN_ADDR) -Bstatic
-+OBJCOPY_ARGS = -O elf32-tradlittlemips
-+
-+all: zImage
-+
-+clean:
-+ rm -rf *.o vmlinux* zvmlinux.* ../images/*.srec
-+
-+head.o: head.S $(TOPDIR)/vmlinux
-+ $(CC) $(AFLAGS) \
-+ -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) $(TOPDIR)/vmlinux ) \
-+ -c -o $*.o $<
-+
-+../common/misc-simple.o:
-+ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \
-+ -DAVAIL_RAM_START=$(AVAIL_RAM_START) \
-+ -DAVAIL_RAM_END=$(AVAIL_RAM_END) \
-+ -DLOADADDR=$(LOADADDR) \
-+ -DZIMAGE_SIZE=0 -c -o $@ $*.c
-+
-+zvmlinux: $(OBJECTS) $(LIBS) ../ld.script ../images/vmlinux.gz ../common/dummy.o
-+ $(OBJCOPY) \
-+ --add-section=.image=../images/vmlinux.gz \
-+ --set-section-flags=.image=contents,alloc,load,readonly,data \
-+ ../common/dummy.o image.o
-+ $(LD) $(LD_ARGS) -o $@ $(OBJECTS) image.o $(LIBS)
-+ $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr \
-+ -R .initrd -R .sysmap
-+
-+# Here we manipulate the image in order to get it the necessary
-+# srecord file we need.
-+zImage: zvmlinux
-+ mv zvmlinux ../images/zImage.$(BNAME)
-+ $(OBJCOPY) -O srec ../images/zImage.$(BNAME) ../images/$(BNAME).srec
-+
-+zImage.flash: zImage
-+ $(OBJCOPY) -O srec --adjust-vma 0x3ed00000 \
-+ ../images/zImage.$(BNAME) ../images/$(BNAME).flash.srec
-+
-+include $(TOPDIR)/Rules.make
-diff -Naru linux/arch/mips/zboot/utils/entry linux-new/arch/mips/zboot/utils/entry
---- linux/arch/mips/zboot/utils/entry 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/utils/entry 2003-12-18 14:26:21.000000000 -0500
-@@ -0,0 +1,12 @@
-+#!/bin/sh
-+
-+# grab the kernel_entry address from the vmlinux elf image
-+entry=`$1 $2 | grep kernel_entry`
-+
-+fs=`echo $entry | grep ffffffff` # check toolchain output
-+
-+if [ -n "$fs" ]; then
-+ echo "0x"`$1 $2 | grep kernel_entry | cut -c9- | awk '{print $1}'`
-+else
-+ echo "0x"`$1 $2 | grep kernel_entry | cut -c1- | awk '{print $1}'`
-+fi
-diff -Naru linux/arch/mips/zboot/utils/offset linux-new/arch/mips/zboot/utils/offset
---- linux/arch/mips/zboot/utils/offset 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/utils/offset 2003-12-18 14:26:21.000000000 -0500
-@@ -0,0 +1,3 @@
-+#!/bin/sh
-+
-+echo "0x"`$1 -h $2 | grep $3 | grep -v zvmlinux| awk '{print $6}'`
-diff -Naru linux/arch/mips/zboot/utils/size linux-new/arch/mips/zboot/utils/size
---- linux/arch/mips/zboot/utils/size 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/utils/size 2003-12-18 14:26:21.000000000 -0500
-@@ -0,0 +1,4 @@
-+#!/bin/sh
-+
-+OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux | awk '{print $3}'`
-+echo "0x"$OFFSET
-diff -Naru linux/arch/mips/zboot/xxs1500/head.S linux-new/arch/mips/zboot/xxs1500/head.S
---- linux/arch/mips/zboot/xxs1500/head.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/xxs1500/head.S 2003-12-18 14:26:21.000000000 -0500
-@@ -0,0 +1,137 @@
-+/*
-+ * arch/mips/kernel/head.S
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file "COPYING" in the main directory of this archive
-+ * for more details.
-+ *
-+ * Copyright (C) 1994, 1995 Waldorf Electronics
-+ * Written by Ralf Baechle and Andreas Busse
-+ * Copyright (C) 1995 - 1999 Ralf Baechle
-+ * Copyright (C) 1996 Paul M. Antoine
-+ * Modified for DECStation and hence R3000 support by Paul M. Antoine
-+ * Further modifications by David S. Miller and Harald Koerfgen
-+ * Copyright (C) 1999 Silicon Graphics, Inc.
-+ *
-+ * Head.S contains the MIPS exception handler and startup code.
-+ *
-+ **************************************************************************
-+ * 9 Nov, 2000.
-+ * Added Cache Error exception handler and SBDDP EJTAG debug exception.
-+ *
-+ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
-+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
-+ **************************************************************************
-+ */
-+#include <linux/config.h>
-+#include <linux/threads.h>
-+
-+#include <asm/asm.h>
-+#include <asm/cacheops.h>
-+#include <asm/mipsregs.h>
-+#include <asm/offset.h>
-+#include <asm/cachectl.h>
-+#include <asm/regdef.h>
-+
-+#define IndexInvalidate_I 0x00
-+
-+ .set noreorder
-+ .cprestore
-+ LEAF(start)
-+start:
-+
-+locate:
-+ la sp, .stack
-+ move s0, a0
-+ move s1, a1
-+ move s2, a2
-+ move s3, a3
-+
-+ la a0, start
-+
-+ li a1, FLASH_LOAD_ADDR
-+ la a2, _edata
-+ subu t1, a2, a0
-+ srl t1, t1, 2
-+
-+ /* copy text section */
-+ li t0, 0
-+1: lw v0, 0(a1)
-+ nop
-+ sw v0, 0(a0)
-+ xor t0, t0, v0
-+ addu a0, 4
-+ bne a2, a0, 1b
-+ addu a1, 4
-+
-+ /* Clear BSS */
-+ la a0, _edata
-+ la a2, _end
-+2: sw zero, 0(a0)
-+ bne a2, a0, 2b
-+ addu a0, 4
-+
-+ /* flush the I-Cache */
-+ li k0, 0x80000000 # start address
-+ li k1, 0x80004000 # end address (16KB I-Cache)
-+ subu k1, 128
-+
-+1:
-+ .set mips3
-+ cache IndexInvalidate_I, 0(k0)
-+ cache IndexInvalidate_I, 32(k0)
-+ cache IndexInvalidate_I, 64(k0)
-+ cache IndexInvalidate_I, 96(k0)
-+ .set mips0
-+
-+ bne k0, k1, 1b
-+ addu k0, k0, 128
-+ /* done */
-+
-+ li a0, FLASH_LOAD_ADDR /* load address */
-+ move a1, t1 /* length in words */
-+ move a2, t0 /* checksum */
-+ move a3, sp
-+
-+ la ra, 1f
-+ la k0, decompress_kernel
-+ jr k0
-+ nop
-+1:
-+
-+ move a0, s0
-+ move a1, s1
-+ move a2, s2
-+ move a3, s3
-+ li k0, KERNEL_ENTRY
-+ jr k0
-+ nop
-+3:
-+ b 3b
-+ END(start)
-+
-+ LEAF(udelay)
-+udelay:
-+ END(udelay)
-+
-+
-+ LEAF(FlushCache)
-+ li k0, 0x80000000 # start address
-+ li k1, 0x80004000 # end address (16KB I-Cache)
-+ subu k1, 128
-+
-+1:
-+ .set mips3
-+ cache IndexInvalidate_I, 0(k0)
-+ cache IndexInvalidate_I, 32(k0)
-+ cache IndexInvalidate_I, 64(k0)
-+ cache IndexInvalidate_I, 96(k0)
-+ .set mips0
-+
-+ bne k0, k1, 1b
-+ addu k0, k0, 128
-+ jr ra
-+ nop
-+ END(FlushCache)
-+
-+ .comm .stack,4096*2,4
-diff -Naru linux/arch/mips/zboot/xxs1500/ld.script linux-new/arch/mips/zboot/xxs1500/ld.script
---- linux/arch/mips/zboot/xxs1500/ld.script 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/xxs1500/ld.script 2003-12-18 14:26:21.000000000 -0500
-@@ -0,0 +1,147 @@
-+OUTPUT_ARCH(mips)
-+ENTRY(start)
-+SECTIONS
-+{
-+ /* Read-only sections, merged into text segment: */
-+ /* . = 0x81000000; */
-+ .init : { *(.init) } =0
-+ .text :
-+ {
-+ _ftext = . ;
-+ *(.text)
-+ *(.rodata)
-+ *(.rodata1)
-+ /* .gnu.warning sections are handled specially by elf32.em. */
-+ *(.gnu.warning)
-+ } =0
-+ .kstrtab : { *(.kstrtab) }
-+
-+ . = ALIGN(16); /* Exception table */
-+ __start___ex_table = .;
-+ __ex_table : { *(__ex_table) }
-+ __stop___ex_table = .;
-+
-+ __start___dbe_table = .; /* Exception table for data bus errors */
-+ __dbe_table : { *(__dbe_table) }
-+ __stop___dbe_table = .;
-+
-+ __start___ksymtab = .; /* Kernel symbol table */
-+ __ksymtab : { *(__ksymtab) }
-+ __stop___ksymtab = .;
-+
-+ _etext = .;
-+
-+ . = ALIGN(8192);
-+ .data.init_task : { *(.data.init_task) }
-+
-+ /* Startup code */
-+ . = ALIGN(4096);
-+ __init_begin = .;
-+ .text.init : { *(.text.init) }
-+ .data.init : { *(.data.init) }
-+ . = ALIGN(16);
-+ __setup_start = .;
-+ .setup.init : { *(.setup.init) }
-+ __setup_end = .;
-+ __initcall_start = .;
-+ .initcall.init : { *(.initcall.init) }
-+ __initcall_end = .;
-+ . = ALIGN(4096); /* Align double page for init_task_union */
-+ __init_end = .;
-+
-+ . = ALIGN(4096);
-+ .data.page_aligned : { *(.data.idt) }
-+
-+ . = ALIGN(32);
-+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
-+
-+ .fini : { *(.fini) } =0
-+ .reginfo : { *(.reginfo) }
-+ /* Adjust the address for the data segment. We want to adjust up to
-+ the same address within the page on the next page up. It would
-+ be more correct to do this:
-+ . = .;
-+ The current expression does not correctly handle the case of a
-+ text segment ending precisely at the end of a page; it causes the
-+ data segment to skip a page. The above expression does not have
-+ this problem, but it will currently (2/95) cause BFD to allocate
-+ a single segment, combining both text and data, for this case.
-+ This will prevent the text segment from being shared among
-+ multiple executions of the program; I think that is more
-+ important than losing a page of the virtual address space (note
-+ that no actual memory is lost; the page which is skipped can not
-+ be referenced). */
-+ . = .;
-+ .data :
-+ {
-+ _fdata = . ;
-+ *(.data)
-+
-+ /* Align the initial ramdisk image (INITRD) on page boundaries. */
-+ . = ALIGN(4096);
-+ __rd_start = .;
-+ *(.initrd)
-+ __rd_end = .;
-+ . = ALIGN(4096);
-+
-+ CONSTRUCTORS
-+ }
-+ .data1 : { *(.data1) }
-+ _gp = . + 0x8000;
-+ .lit8 : { *(.lit8) }
-+ .lit4 : { *(.lit4) }
-+ .ctors : { *(.ctors) }
-+ .dtors : { *(.dtors) }
-+ .got : { *(.got.plt) *(.got) }
-+ .dynamic : { *(.dynamic) }
-+ /* We want the small data sections together, so single-instruction offsets
-+ can access them all, and initialized data all before uninitialized, so
-+ we can shorten the on-disk segment size. */
-+ .sdata : { *(.sdata) }
-+ . = ALIGN(4);
-+ _edata = .;
-+ PROVIDE (edata = .);
-+
-+ __bss_start = .;
-+ _fbss = .;
-+ .sbss : { *(.sbss) *(.scommon) }
-+ .bss :
-+ {
-+ *(.dynbss)
-+ *(.bss)
-+ *(COMMON)
-+ . = ALIGN(4);
-+ _end = . ;
-+ PROVIDE (end = .);
-+ }
-+
-+ /* Sections to be discarded */
-+ /DISCARD/ :
-+ {
-+ *(.text.exit)
-+ *(.data.exit)
-+ *(.exitcall.exit)
-+ }
-+
-+ /* This is the MIPS specific mdebug section. */
-+ .mdebug : { *(.mdebug) }
-+ /* These are needed for ELF backends which have not yet been
-+ converted to the new style linker. */
-+ .stab 0 : { *(.stab) }
-+ .stabstr 0 : { *(.stabstr) }
-+ /* DWARF debug sections.
-+ Symbols in the .debug DWARF section are relative to the beginning of the
-+ section so we begin .debug at 0. It's not clear yet what needs to happen
-+ for the others. */
-+ .debug 0 : { *(.debug) }
-+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
-+ .debug_aranges 0 : { *(.debug_aranges) }
-+ .debug_pubnames 0 : { *(.debug_pubnames) }
-+ .debug_sfnames 0 : { *(.debug_sfnames) }
-+ .line 0 : { *(.line) }
-+ /* These must appear regardless of . */
-+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
-+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
-+ .comment : { *(.comment) }
-+ .note : { *(.note) }
-+}
-diff -Naru linux/arch/mips/zboot/xxs1500/Makefile linux-new/arch/mips/zboot/xxs1500/Makefile
---- linux/arch/mips/zboot/xxs1500/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux-new/arch/mips/zboot/xxs1500/Makefile 2003-12-18 14:26:21.000000000 -0500
-@@ -0,0 +1,123 @@
-+# arch/mips/compressed/alchemy/Makefile
-+#
-+# Makefile for Alchemy Semiconductor Pb1[015]00 boards.
-+# All of the boot loader code was derived from the ppc
-+# boot code.
-+#
-+# Copyright 2001,2002 MontaVista Software Inc.
-+#
-+# Author: Mark A. Greer
-+# mgreer@mvista.com
-+# Ported and modified for mips support by
-+# Pete Popov <ppopov@mvista.com>
-+#
-+# 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.
-+
-+.c.s:
-+ $(CC) $(CFLAGS) -S -o $*.s $<
-+.s.o:
-+ $(AS) -o $*.o $<
-+.c.o:
-+ $(CC) $(CFLAGS) -D__BOOTER__ -c -o $*.o $<
-+.S.s:
-+ $(CPP) $(AFLAGS) -o $*.o $<
-+.S.o:
-+ $(CC) $(AFLAGS) -c -o $*.o $<
-+
-+#########################################################################
-+# START BOARD SPECIFIC VARIABLES
-+BNAME=xxs1500
-+
-+
-+# These two variables control where the zImage is stored
-+# in flash and loaded in memory. If you change either one,
-+# be sure to make the appropriate change to the zImage
-+# rule.
-+RAM_LOAD_ADDR = 0x81000000
-+FLASH_LOAD_ADDR = 0xBF000000
-+
-+# These two variables specify the free ram region
-+# that can be used for temporary malloc area
-+AVAIL_RAM_START=0x80400000
-+AVAIL_RAM_END=0x80800000
-+
-+# This one must match the LOADADDR in arch/mips/Makefile!
-+LOADADDR=0x80100000
-+# END BOARD SPECIFIC VARIABLES
-+#########################################################################
-+
-+ZLINKFLAGS = -T ld.script -Ttext $(RAM_LOAD_ADDR)
-+
-+OBJECTS := head.o ../common/misc-common.o ../common/misc-simple.o \
-+ ../common/au1k_uart.o ../common/string.o ../common/ctype.o
-+LIBS := ../lib/zlib.a
-+
-+ENTRY := ../utils/entry
-+OFFSET := ../utils/offset
-+SIZE := ../utils/size
-+
-+all: zImage
-+
-+clean:
-+ rm -rf *.o vmlinux* zvmlinux.*
-+
-+head.o: head.S $(TOPDIR)/vmlinux
-+ $(CC) -DFLASH_LOAD_ADDR=$(FLASH_LOAD_ADDR) $(AFLAGS) \
-+ -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) $(TOPDIR)/vmlinux ) \
-+ -c -o $*.o $<
-+
-+../common/misc-simple.o:
-+ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \
-+ -DAVAIL_RAM_START=$(AVAIL_RAM_START) \
-+ -DAVAIL_RAM_END=$(AVAIL_RAM_END) \
-+ -DLOADADDR=$(LOADADDR) \
-+ -DZIMAGE_SIZE=0 -c -o $@ $*.c
-+
-+# This is the first pass at building the boot loader image,
-+# without knowing the file offset where the vmlinuz.gz
-+# kernel will end up. We build this image, check the offset,
-+# and then rebuild it with the correct offset and size
-+# passed to mips-simple.c
-+zvmlinux.no: $(OBJECTS) $(LIBS) ../images/vmlinux.gz
-+ $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS)
-+ $(OBJCOPY) -R .comment \
-+ --add-section=image=../images/vmlinux.gz \
-+ $@.tmp $@
-+ # rm -f $@.tmp
-+
-+
-+# This is the final image we build, now that we know what
-+# the vmlinuz.gz offset is.
-+zvmlinux: $(OBJECTS) $(LIBS) ../images/vmlinux.gz zvmlinux.no
-+ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \
-+ -DZIMAGE_OFFSET=$(shell sh $(OFFSET) $(OBJDUMP) $@.no image) \
-+ -DZIMAGE_SIZE=$(shell sh $(SIZE) $(OBJDUMP) $@.no image) \
-+ -D__BOOTER__ \
-+ -DAVAIL_RAM_START=$(AVAIL_RAM_START) \
-+ -DAVAIL_RAM_END=$(AVAIL_RAM_END) \
-+ -DLOADADDR=$(LOADADDR) \
-+ -c -o ../common/misc-simple.o ../common/misc-simple.c
-+ $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS)
-+ $(OBJCOPY) -R .comment \
-+ --add-section=image=../images/vmlinux.gz \
-+ $@.tmp $@
-+ $(OBJCOPY) --adjust-section-vma=image+$(RAM_LOAD_ADDR) $@
-+ $(OBJCOPY) --adjust-section-vma=image+$(shell sh $(OFFSET) \
-+ $(OBJDUMP) $@.no image ) $@
-+ # rm -f $@.tmp
-+ # rm -f $@.no
-+
-+
-+# Here we manipulate the image in order to get it the necessary
-+# srecord file we need.
-+zImage: zvmlinux
-+ mv zvmlinux ../images/$@.$(BNAME)
-+ $(OBJCOPY) --set-section-flags=image=alloc,load,code ../images/$@.$(BNAME)
-+ $(OBJCOPY) -O srec --adjust-vma 0x3e000000 \
-+ ../images/$@.$(BNAME) ../images/$@.$(BNAME).srec
-+ # rm ../images/vmlinux.gz
-+
-+include $(TOPDIR)/Rules.make
diff --git a/linux/linux-mtx-1-2.4.24/05-zboot-cflags.diff b/linux/linux-mtx-1-2.4.24/05-zboot-cflags.diff
deleted file mode 100644
index 9ac0c31b45..0000000000
--- a/linux/linux-mtx-1-2.4.24/05-zboot-cflags.diff
+++ /dev/null
@@ -1,15 +0,0 @@
---- linux-mips-2.4.24-pre2+zboot/arch/mips/zboot/Makefile 2004-11-17 19:25:04.538345048 +0100
-+++ linux/arch/mips/zboot/Makefile 2004-11-17 19:21:05.304714088 +0100
-@@ -25,11 +25,7 @@
-
- GZIP_FLAGS = -v9f
-
--CFLAGS := $(CPPFLAGS) -O2 -D__BOOTER__ \
-- -fomit-frame-pointer -fno-strict-aliasing -fno-common \
-- -G 0 -mno-abicalls -fno-pic -mcpu=r4600 -mips2 \
-- -I$(TOPDIR)/arch/$(ARCH)/zboot/include \
-- -I$(TOPDIR)/include/asm
-+CFLAGS += -D__BOOTER__ -I$(TOPDIR)/arch/$(ARCH)/zboot/include
- AFLAGS += -D__BOOTER__
-
- BOOT_TARGETS = zImage zImage.initrd zImage.flash zImage.initrd.flash
diff --git a/linux/linux-mtx-1-2.4.24/06-zboot-mtx.diff b/linux/linux-mtx-1-2.4.24/06-zboot-mtx.diff
deleted file mode 100644
index 82a3295564..0000000000
--- a/linux/linux-mtx-1-2.4.24/06-zboot-mtx.diff
+++ /dev/null
@@ -1,27 +0,0 @@
-diff -urb work/arch/mips/zboot/Makefile mtx/arch/mips/zboot/Makefile
---- work/arch/mips/zboot/Makefile 2003-07-01 20:09:20.000000000 +0200
-+++ mtx/arch/mips/zboot/Makefile 2003-07-01 19:20:29.000000000 +0200
-@@ -64,6 +64,9 @@
- ifdef CONFIG_MIPS_XXS1500
- BOOT_DIR = xxs1500
- endif
-+ifdef CONFIG_MIPS_MTX1
-+ $(MAKE) -C pb1xxx $@
-+endif
-
- # Do the dirs
- clean:
-diff -urb work/arch/mips/zboot/pb1xxx/Makefile mtx/arch/mips/zboot/pb1xxx/Makefile
---- work/arch/mips/zboot/pb1xxx/Makefile 2003-07-01 20:09:20.000000000 +0200
-+++ mtx/arch/mips/zboot/pb1xxx/Makefile 2003-07-01 19:20:37.000000000 +0200
-@@ -57,6 +57,10 @@
- BNAME=bosporus
- endif
-
-+ifdef CONFIG_MIPS_MTX1
-+BNAME=mtx-1
-+endif
-+
- # These two variables control where the zImage is stored
- # in flash and loaded in memory. It only controls how the srec
- # file is generated, the code is the same.
diff --git a/linux/linux-mtx-1-2.4.24/07-zimage-flash-bin.patch b/linux/linux-mtx-1-2.4.24/07-zimage-flash-bin.patch
deleted file mode 100644
index ce13d9add7..0000000000
--- a/linux/linux-mtx-1-2.4.24/07-zimage-flash-bin.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-diff -Nurb oe/tmp/work/linux-mtx-1-2.4.27-r0/linux/arch/mips/zboot/pb1xxx/Makefile linux.m/arch/mips/zboot/pb1xxx/Makefile
---- oe/tmp/work/linux-mtx-1-2.4.27-r0/linux/arch/mips/zboot/pb1xxx/Makefile 2004-10-13 21:08:49.840408328 +0200
-+++ linux.m/arch/mips/zboot/pb1xxx/Makefile 2004-10-13 21:08:29.736464592 +0200
-@@ -123,5 +123,7 @@
- zImage.flash: zImage
- $(OBJCOPY) -O srec --adjust-vma 0x3ed00000 \
- ../images/zImage.$(BNAME) ../images/$(BNAME).flash.srec
-+ $(OBJCOPY) -O binary --adjust-vma 0x3ed00000 \
-+ ../images/zImage.$(BNAME) ../images/$(BNAME).flash.bin
-
- include $(TOPDIR)/Rules.make
diff --git a/linux/linux-mtx-1-2.4.24/08-usb-nonpci-2.4.24.patch b/linux/linux-mtx-1-2.4.24/08-usb-nonpci-2.4.24.patch
deleted file mode 100644
index 89ed24f214..0000000000
--- a/linux/linux-mtx-1-2.4.24/08-usb-nonpci-2.4.24.patch
+++ /dev/null
@@ -1,173 +0,0 @@
-diff -Naru linux/drivers/usb/host/Config.in linux-new/drivers/usb/host/Config.in
---- linux/drivers/usb/host/Config.in 2003-11-16 20:07:42.000000000 -0500
-+++ linux-new/drivers/usb/host/Config.in 2003-12-18 14:19:37.000000000 -0500
-@@ -17,3 +17,4 @@
- dep_tristate ' SL811HS Alternate (x86, StrongARM, isosynchronous mode)' CONFIG_USB_SL811HS_ALT $CONFIG_USB $CONFIG_EXPERIMENTAL
- dep_tristate ' SL811HS (x86, StrongARM) support, old driver' CONFIG_USB_SL811HS $CONFIG_USB $CONFIG_EXPERIMENTAL
- fi
-+dep_tristate ' Non-PCI OHCI support' CONFIG_USB_NON_PCI_OHCI $CONFIG_USB_OHCI
-diff -Naru linux/drivers/usb/host/usb-ohci.c linux-new/drivers/usb/host/usb-ohci.c
---- linux/drivers/usb/host/usb-ohci.c 2003-08-13 13:19:23.000000000 -0400
-+++ linux-new/drivers/usb/host/usb-ohci.c 2003-12-18 14:19:53.000000000 -0500
-@@ -2517,6 +2517,7 @@
- hc_release_ohci (ohci);
- return ret;
- }
-+#ifndef CONFIG_USB_NON_PCI_OHCI
- ohci->flags = id->driver_data;
-
- /* Check for NSC87560. We have to look at the bridge (fn1) to identify
-@@ -2535,6 +2536,7 @@
- printk (KERN_INFO __FILE__ ": Using NSC SuperIO setup\n");
- if (ohci->flags & OHCI_QUIRK_AMD756)
- printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n");
-+#endif
-
- if (hc_reset (ohci) < 0) {
- hc_release_ohci (ohci);
-@@ -2580,8 +2582,10 @@
- int temp;
- int i;
-
-+#ifndef CONFIG_USB_NON_PCI_OHCI
- if (ohci->pci_latency)
- pci_write_config_byte (ohci->ohci_dev, PCI_LATENCY_TIMER, ohci->pci_latency);
-+#endif
-
- ohci->disabled = 1;
- ohci->sleeping = 0;
-@@ -2611,6 +2615,7 @@
-
- /*-------------------------------------------------------------------------*/
-
-+#ifndef CONFIG_USB_NON_PCI_OHCI
- /* configured so that an OHCI device is always provided */
- /* always called with process context; sleeping is OK */
-
-@@ -2658,6 +2663,88 @@
- }
- return status;
- }
-+#else /* CONFIG_USB_NON_PCI_OHCI */
-+
-+// Boot options
-+static int ohci_base=0, ohci_len=0;
-+static int ohci_irq=-1;
-+
-+MODULE_PARM(ohci_base, "i");
-+MODULE_PARM(ohci_len, "i");
-+MODULE_PARM(ohci_irq, "i");
-+MODULE_PARM_DESC(ohci_base, "IO Base address of OHCI Oper. registers");
-+MODULE_PARM_DESC(ohci_len, "IO length of OHCI Oper. registers");
-+MODULE_PARM_DESC(ohci_irq, "IRQ for OHCI interrupts");
-+
-+// bogus pci_dev
-+static struct pci_dev bogus_pcidev;
-+
-+static struct pci_driver ohci_pci_driver = {
-+ name: "usb-ohci",
-+};
-+
-+static int __devinit
-+ohci_non_pci_init (void)
-+{
-+ void *mem_base;
-+
-+ if (!ohci_base || !ohci_len || (ohci_irq < 0))
-+ return -ENODEV;
-+
-+ if (!request_mem_region (ohci_base, ohci_len, ohci_pci_driver.name)) {
-+ dbg ("controller already in use");
-+ return -EBUSY;
-+ }
-+
-+ mem_base = ioremap_nocache (ohci_base, ohci_len);
-+ if (!mem_base) {
-+ err("Error mapping OHCI memory");
-+ return -EFAULT;
-+ }
-+
-+ /*
-+ * Fill in the bogus pci_dev. Only those members actually
-+ * dereferenced in this driver are initialized.
-+ */
-+ memset(&bogus_pcidev, 0, sizeof(struct pci_dev));
-+ strcpy(bogus_pcidev.name, "non-PCI OHCI");
-+ strcpy(bogus_pcidev.slot_name, "builtin");
-+ bogus_pcidev.resource[0].name = "OHCI Operational Registers";
-+ bogus_pcidev.resource[0].start = ohci_base;
-+ bogus_pcidev.resource[0].end = ohci_base + ohci_len;
-+ bogus_pcidev.resource[0].flags = 0;
-+ bogus_pcidev.irq = ohci_irq;
-+
-+ return hc_found_ohci (&bogus_pcidev, bogus_pcidev.irq, mem_base, NULL);
-+}
-+
-+#ifndef MODULE
-+
-+static int __init
-+ohci_setup (char* options)
-+{
-+ char* this_opt;
-+
-+ if (!options || !*options)
-+ return 0;
-+
-+ for(this_opt=strtok(options,",");this_opt;this_opt=strtok(NULL,",")) {
-+ if (!strncmp(this_opt, "base:", 5)) {
-+ ohci_base = simple_strtoul(this_opt+5, NULL, 0);
-+ } else if (!strncmp(this_opt, "len:", 4)) {
-+ ohci_len = simple_strtoul(this_opt+4, NULL, 0);
-+ } else if (!strncmp(this_opt, "irq:", 4)) {
-+ ohci_irq = simple_strtoul(this_opt+4, NULL, 0);
-+ }
-+ }
-+ return 0;
-+}
-+
-+__setup("usb_ohci=", ohci_setup);
-+
-+#endif /* !MODULE */
-+
-+#endif /* CONFIG_USB_NON_PCI_OHCI */
-
- /*-------------------------------------------------------------------------*/
-
-@@ -2698,6 +2785,7 @@
- }
-
-
-+#ifndef CONFIG_USB_NON_PCI_OHCI
- #ifdef CONFIG_PM
-
- /*-------------------------------------------------------------------------*/
-@@ -2936,20 +3024,29 @@
- resume: ohci_pci_resume,
- #endif /* PM */
- };
-+#endif /* CONFIG_USB_NON_PCI_OHCI */
-
-
- /*-------------------------------------------------------------------------*/
-
- static int __init ohci_hcd_init (void)
- {
-+#ifndef CONFIG_USB_NON_PCI_OHCI
- return pci_module_init (&ohci_pci_driver);
-+#else
-+ return ohci_non_pci_init();
-+#endif
- }
-
- /*-------------------------------------------------------------------------*/
-
- static void __exit ohci_hcd_cleanup (void)
- {
-+#ifndef CONFIG_USB_NON_PCI_OHCI
- pci_unregister_driver (&ohci_pci_driver);
-+#else
-+ ohci_pci_remove(&bogus_pcidev);
-+#endif
- }
-
- module_init (ohci_hcd_init);
diff --git a/linux/linux-mtx-1-2.4.24/09-iw-max-spy-32.diff b/linux/linux-mtx-1-2.4.24/09-iw-max-spy-32.diff
deleted file mode 100644
index e782d3d3dc..0000000000
--- a/linux/linux-mtx-1-2.4.24/09-iw-max-spy-32.diff
+++ /dev/null
@@ -1,11 +0,0 @@
---- linux-mips-2.4.24-pre2/include/linux/wireless.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/wireless.h 2004-11-17 19:02:44.370081592 +0100
-@@ -334,7 +334,7 @@
- * a few of them in the struct iw_range. */
-
- /* Maximum of address that you may set with SPY */
--#define IW_MAX_SPY 8
-+#define IW_MAX_SPY 32
-
- /* Maximum of address that you may get in the
- list of access points in range */
diff --git a/linux/linux-mtx-1-2.4.24/10-mtx-pci-slots.diff b/linux/linux-mtx-1-2.4.24/10-mtx-pci-slots.diff
deleted file mode 100644
index 8cdde20440..0000000000
--- a/linux/linux-mtx-1-2.4.24/10-mtx-pci-slots.diff
+++ /dev/null
@@ -1,23 +0,0 @@
---- linux-mips-2.4.24-pre2/arch/mips/au1000/common/pci_fixup.c 2004-11-17 18:04:41.000000000 +0100
-+++ linux/arch/mips/au1000/common/pci_fixup.c 2004-11-18 11:22:03.176289496 +0100
-@@ -118,6 +118,20 @@
- slot = PCI_SLOT(dev->devfn);
- #if defined( CONFIG_SOC_AU1500 )
- switch (slot) {
-+#if defined( CONFIG_MIPS_MTX1 )
-+ case 0:
-+ dev->irq = AU1000_PCI_INTA;
-+ break;
-+ case 1:
-+ dev->irq = AU1000_PCI_INTB;
-+ break;
-+ case 2:
-+ dev->irq = AU1000_PCI_INTC;
-+ break;
-+ case 3:
-+ dev->irq = AU1000_PCI_INTD;
-+ break;
-+#endif
- case 12:
- case 13:
- default:
diff --git a/linux/linux-mtx-1-2.4.24/11-mtx-extraversion.diff b/linux/linux-mtx-1-2.4.24/11-mtx-extraversion.diff
deleted file mode 100644
index c57296981c..0000000000
--- a/linux/linux-mtx-1-2.4.24/11-mtx-extraversion.diff
+++ /dev/null
@@ -1,11 +0,0 @@
---- linux-mips-2.4.24-pre2/Makefile 2004-11-17 18:04:38.000000000 +0100
-+++ linux/Makefile 2004-11-17 18:57:54.314176792 +0100
-@@ -1,7 +1,7 @@
- VERSION = 2
- PATCHLEVEL = 4
- SUBLEVEL = 24
--EXTRAVERSION = -pre2
-+EXTRAVERSION = mtx
-
- KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
-
diff --git a/linux/linux-mtx-1-2.4.24/12-openswan-2.2.0-nat-t.diff b/linux/linux-mtx-1-2.4.24/12-openswan-2.2.0-nat-t.diff
deleted file mode 100644
index 31bcbd8a5a..0000000000
--- a/linux/linux-mtx-1-2.4.24/12-openswan-2.2.0-nat-t.diff
+++ /dev/null
@@ -1,143 +0,0 @@
-diff -Nurb linux-1-11/include/net/sock.h linux/include/net/sock.h
---- linux-1-11/include/net/sock.h 2004-11-18 09:55:07.377211480 +0100
-+++ linux/include/net/sock.h 2004-11-18 09:55:43.605703912 +0100
-@@ -256,6 +256,13 @@
- __u32 end_seq;
- };
-
-+#if 1
-+#define UDP_OPT_IN_SOCK 1
-+struct udp_opt {
-+ __u32 esp_in_udp;
-+};
-+#endif
-+
- struct tcp_opt {
- int tcp_header_len; /* Bytes of tcp header to send */
-
-@@ -601,6 +608,9 @@
- #if defined(CONFIG_SPX) || defined (CONFIG_SPX_MODULE)
- struct spx_opt af_spx;
- #endif /* CONFIG_SPX */
-+#if 1
-+ struct udp_opt af_udp;
-+#endif
-
- } tp_pinfo;
-
-diff -Nurb linux-1-11/net/Config.in linux/net/Config.in
---- linux-1-11/net/Config.in 2004-11-18 09:55:07.545185944 +0100
-+++ linux/net/Config.in 2004-11-18 09:55:43.627700568 +0100
-@@ -102,4 +102,6 @@
- tristate 'Packet Generator (USE WITH CAUTION)' CONFIG_NET_PKTGEN
- endmenu
-
-+bool 'IPSEC NAT-Traversal' CONFIG_IPSEC_NAT_TRAVERSAL
-+
- endmenu
-diff -Nurb linux-1-11/net/ipv4/udp.c linux/net/ipv4/udp.c
---- linux-1-11/net/ipv4/udp.c 2004-11-18 09:55:07.958123168 +0100
-+++ linux/net/ipv4/udp.c 2004-11-18 09:55:43.638698896 +0100
-@@ -804,6 +804,9 @@
-
- static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
- {
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ struct udp_opt *tp = &(sk->tp_pinfo.af_udp);
-+#endif
- /*
- * Charge it to the socket, dropping if the queue is full.
- */
-@@ -821,6 +824,40 @@
- }
- #endif
-
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if (tp->esp_in_udp) {
-+ /*
-+ * Set skb->sk and xmit packet to ipsec_rcv.
-+ *
-+ * If ret != 0, ipsec_rcv refused the packet (not ESPinUDP),
-+ * restore skb->sk and fall back to sock_queue_rcv_skb
-+ */
-+ struct inet_protocol *esp = NULL;
-+
-+#if defined(CONFIG_IPSEC) && !defined(CONFIG_IPSEC_MODULE)
-+ /* optomize only when we know it is statically linked */
-+ extern struct inet_protocol esp_protocol;
-+ esp = &esp_protocol;
-+#else
-+ for (esp = (struct inet_protocol *)inet_protos[IPPROTO_ESP & (MAX_INET_PROTOS - 1)];
-+ (esp) && (esp->protocol != IPPROTO_ESP);
-+ esp = esp->next);
-+#endif
-+
-+ if (esp && esp->handler) {
-+ struct sock *sav_sk = skb->sk;
-+ skb->sk = sk;
-+ if (esp->handler(skb) == 0) {
-+ skb->sk = sav_sk;
-+ /*not sure we might count ESPinUDP as UDP...*/
-+ UDP_INC_STATS_BH(UdpInDatagrams);
-+ return 0;
-+ }
-+ skb->sk = sav_sk;
-+ }
-+ }
-+#endif
-+
- if (sock_queue_rcv_skb(sk,skb)<0) {
- UDP_INC_STATS_BH(UdpInErrors);
- IP_INC_STATS_BH(IpInDiscards);
-@@ -1044,13 +1081,49 @@
- return len;
- }
-
-+static int udp_setsockopt(struct sock *sk, int level, int optname,
-+ char *optval, int optlen)
-+{
-+ struct udp_opt *tp = &(sk->tp_pinfo.af_udp);
-+ int val;
-+ int err = 0;
-+
-+ if (level != SOL_UDP)
-+ return ip_setsockopt(sk, level, optname, optval, optlen);
-+
-+ if(optlen<sizeof(int))
-+ return -EINVAL;
-+
-+ if (get_user(val, (int *)optval))
-+ return -EFAULT;
-+
-+ lock_sock(sk);
-+
-+ switch(optname) {
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+#ifndef UDP_ESPINUDP
-+#define UDP_ESPINUDP 100
-+#endif
-+ case UDP_ESPINUDP:
-+ tp->esp_in_udp = val;
-+ break;
-+#endif
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
- struct proto udp_prot = {
- name: "UDP",
- close: udp_close,
- connect: udp_connect,
- disconnect: udp_disconnect,
- ioctl: udp_ioctl,
-- setsockopt: ip_setsockopt,
-+ setsockopt: udp_setsockopt,
- getsockopt: ip_getsockopt,
- sendmsg: udp_sendmsg,
- recvmsg: udp_recvmsg,
-
diff --git a/linux/linux-mtx-1-2.4.24/13-openswan-2.2.0.patch b/linux/linux-mtx-1-2.4.24/13-openswan-2.2.0.patch
deleted file mode 100644
index db64219eda..0000000000
--- a/linux/linux-mtx-1-2.4.24/13-openswan-2.2.0.patch
+++ /dev/null
@@ -1,61573 +0,0 @@
-make[1]: Entering directory `/data/mtx/oe/tmp/work/openswan-2.2.0-r0/openswan-2.2.0'
-packaging/utils/kernelpatch 2.4
---- linux/Documentation/Configure.help.orig Fri Dec 21 12:41:53 2001
-+++ linux/Documentation/Configure.help Mon Jul 29 16:35:32 2002
-@@ -24237,5 +24237,65 @@
-
--#
-+IP Security Protocol (IPSEC) (EXPERIMENTAL)
-+CONFIG_IPSEC
-+ This unit is experimental code.
-+ Pick 'y' for static linking, 'm' for module support or 'n' for none.
-+ This option adds support for network layer packet encryption and/or
-+ authentication with participating hosts. The standards start with:
-+ RFCs 2411, 2407 and 2401. Others are mentioned where they refer to
-+ specific features below. There are more pending which can be found
-+ at: ftp://ftp.ietf.org/internet-drafts/draft-ietf-ipsec-*.
-+ A description of each document can also be found at:
-+ http://ietf.org/ids.by.wg/ipsec.html.
-+ Their charter can be found at:
-+ http://www.ietf.org/html.charters/ipsec-charter.html
-+ Snapshots and releases of the current work can be found at:
-+ http://www.freeswan.org/
-+
-+IPSEC: IP-in-IP encapsulation
-+CONFIG_IPSEC_IPIP
-+ This option provides support for tunnel mode IPSEC. It is recommended
-+ to enable this.
-+
-+IPSEC: Authentication Header
-+CONFIG_IPSEC_AH
-+ This option provides support for the IPSEC Authentication Header
-+ (IP protocol 51) which provides packet layer sender and content
-+ authentication. It is recommended to enable this. RFC2402
-+
-+HMAC-MD5 algorithm
-+CONFIG_IPSEC_AUTH_HMAC_MD5
-+ Provides support for authentication using the HMAC MD5
-+ algorithm with 96 bits of hash used as the authenticator. RFC2403
-+
-+HMAC-SHA1 algorithm
-+CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ Provides support for Authentication Header using the HMAC SHA1
-+ algorithm with 96 bits of hash used as the authenticator. RFC2404
-+
-+IPSEC: Encapsulating Security Payload
-+CONFIG_IPSEC_ESP
-+ This option provides support for the IPSEC Encapsulation Security
-+ Payload (IP protocol 50) which provides packet layer content
-+ hiding. It is recommended to enable this. RFC2406
-+
-+3DES algorithm
-+CONFIG_IPSEC_ENC_3DES
-+ Provides support for Encapsulation Security Payload protocol, using
-+ the triple DES encryption algorithm. RFC2451
-+
-+IPSEC Debugging Option
-+CONFIG_IPSEC_DEBUG
-+ Enables IPSEC kernel debugging. It is further controlled by the
-+ user space utility 'klipsdebug'.
-+
-+IPSEC Regression Testing option
-+CONFIG_IPSEC_REGRESS
-+ Enables IPSEC regression testing. Creates a number of switches in
-+ /proc/sys/net/ipsec which cause various failure modes in KLIPS.
-+ For more details see FreeSWAN source under
-+ testing/doc/regression_options.txt.
-+
-+#
- # A couple of things I keep forgetting:
- # capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet,
- # Intel, IRQ, ISDN, Linux, MSDOS, NetWare, NetWinder,
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/README.openswan-2 Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,112 @@
-+*
-+* RCSID $Id$
-+*
-+
-+ ****************************************
-+ * IPSEC for Linux, Release 2.xx series *
-+ ****************************************
-+
-+
-+
-+1. Files
-+
-+The contents of linux/net/ipsec/ (see below) join the linux kernel source tree.
-+as provided for higher up.
-+
-+The programs/ directory contains the user-level utilities which you need
-+to run IPSEC. See the top-level top/INSTALL to compile and install them.
-+
-+The testing/ directory contains test scripts.
-+
-+The doc/ directory contains -- what else -- documentation.
-+
-+1.1. Kernel files
-+
-+The following are found in net/ipsec/:
-+
-+Makefile The Makefile
-+Config.in The configuration script for make menuconfig
-+defconfig Configuration defaults for first time.
-+
-+radij.c General-purpose radix-tree operations
-+
-+ipsec_ipcomp.c IPCOMP encapsulate/decapsulate code.
-+ipsec_ah.c Authentication Header (AH) encapsulate/decapsulate code.
-+ipsec_esp.c Encapsulated Security Payload (ESP) encap/decap code.
-+
-+pfkey_v2.c PF_KEYv2 socket interface code.
-+pfkey_v2_parser.c PF_KEYv2 message parsing and processing code.
-+
-+ipsec_init.c Initialization code, /proc interface.
-+ipsec_radij.c Interface with the radix tree code.
-+ipsec_netlink.c Interface with the netlink code.
-+ipsec_xform.c Routines and structures common to transforms.
-+ipsec_tunnel.c The outgoing packet processing code.
-+ipsec_rcv.c The incoming packet processing code.
-+ipsec_md5c.c Somewhat modified RSADSI MD5 C code.
-+ipsec_sha1.c Somewhat modified Steve Reid SHA-1 C code.
-+
-+sysctl_net_ipsec.c /proc/sys/net/ipsec/* variable definitions.
-+
-+version.c symbolic link to project version.
-+
-+radij.h Headers for radij.c
-+
-+ipcomp.h Headers used by IPCOMP code.
-+
-+ipsec_radij.h Interface with the radix tree code.
-+ipsec_netlink.h Headers used by the netlink interface.
-+ipsec_encap.h Headers defining encapsulation structures.
-+ipsec_xform.h Transform headers.
-+ipsec_tunnel.h Headers used by tunneling code.
-+ipsec_ipe4.h Headers for the IP-in-IP code.
-+ipsec_ah.h Headers common to AH transforms.
-+ipsec_md5h.h RSADSI MD5 headers.
-+ipsec_sha1.h SHA-1 headers.
-+ipsec_esp.h Headers common to ESP transfroms.
-+ipsec_rcv.h Headers for incoming packet processing code.
-+
-+1.2. User-level files.
-+
-+The following are found in utils/:
-+
-+eroute.c Create an "extended route" source code
-+spi.c Set up Security Associations source code
-+spigrp.c Link SPIs together source code.
-+tncfg.c Configure the tunneling features of the virtual interface
-+ source code
-+klipsdebug.c Set/reset klips debugging features source code.
-+version.c symbolic link to project version.
-+
-+eroute.8 Create an "extended route" manual page
-+spi.8 Set up Security Associations manual page
-+spigrp.8 Link SPIs together manual page
-+tncfg.8 Configure the tunneling features of the virtual interface
-+ manual page
-+klipsdebug.8 Set/reset klips debugging features manual page
-+
-+eroute.5 /proc/net/ipsec_eroute format manual page
-+spi.5 /proc/net/ipsec_spi format manual page
-+spigrp.5 /proc/net/ipsec_spigrp format manual page
-+tncfg.5 /proc/net/ipsec_tncfg format manual page
-+klipsdebug.5 /proc/net/ipsec_klipsdebug format manual page
-+version.5 /proc/net/ipsec_version format manual page
-+pf_key.5 /proc/net/pf_key format manual page
-+
-+Makefile Utilities makefile.
-+
-+*.8 Manpages for the respective utils.
-+
-+
-+1.3. Test files
-+
-+The test scripts are locate in testing/ and and documentation is found
-+at doc/src/umltesting.html. Automated testing via "make check" is available
-+provided that the User-Mode-Linux patches are available.
-+
-+*
-+* $Log$
-+* Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+* Turn off EOLN_NATIVE flag
-+*
-+* (Logical change 1.5010)
-+*
-+* Revision 1.1 2003/12/10 01:07:49 mcr
-+* documentation for additions.
-+*
-+*
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/aes/Makefile.objs Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,13 @@
-+
-+ASM-$(ARCH_ASM):=1
-+ASM_X86:=$(ASM-i586)$(ASM-i686)
-+
-+ifneq ($(strip $(ASM_X86)),)
-+obj-$(CONFIG_IPSEC_ENC_AES) += aes-i586.o
-+else
-+obj-$(CONFIG_IPSEC_ENC_AES) += aes.o
-+endif
-+
-+obj-$(CONFIG_IPSEC_ENC_AES) += aes_cbc.o
-+obj-$(CONFIG_IPSEC_ENC_AES) += aes_xcbc_mac.o
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/aes/aes-i586.S Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,892 @@
-+//
-+// Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
-+// All rights reserved.
-+//
-+// TERMS
-+//
-+// Redistribution and use in source and binary forms, with or without
-+// modification, are permitted subject to the following conditions:
-+//
-+// 1. Redistributions of source code must retain the above copyright
-+// notice, this list of conditions and the following disclaimer.
-+//
-+// 2. Redistributions in binary form must reproduce the above copyright
-+// notice, this list of conditions and the following disclaimer in the
-+// documentation and/or other materials provided with the distribution.
-+//
-+// 3. The copyright holder's name must not be used to endorse or promote
-+// any products derived from this software without his specific prior
-+// written permission.
-+//
-+// This software is provided 'as is' with no express or implied warranties
-+// of correctness or fitness for purpose.
-+
-+// Modified by Jari Ruusu, December 24 2001
-+// - Converted syntax to GNU CPP/assembler syntax
-+// - C programming interface converted back to "old" API
-+// - Minor portability cleanups and speed optimizations
-+
-+// An AES (Rijndael) implementation for the Pentium. This version only
-+// implements the standard AES block length (128 bits, 16 bytes). This code
-+// does not preserve the eax, ecx or edx registers or the artihmetic status
-+// flags. However, the ebx, esi, edi, and ebp registers are preserved across
-+// calls.
-+
-+// void aes_set_key(aes_context *cx, const unsigned char key[], const int key_len, const int f)
-+// void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
-+// void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
-+
-+#if defined(USE_UNDERLINE)
-+# define aes_set_key _aes_set_key
-+# define aes_encrypt _aes_encrypt
-+# define aes_decrypt _aes_decrypt
-+#endif
-+#if !defined(ALIGN32BYTES)
-+# define ALIGN32BYTES 32
-+#endif
-+
-+ .file "aes-i586.S"
-+ .globl aes_set_key
-+ .globl aes_encrypt
-+ .globl aes_decrypt
-+
-+#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words)
-+
-+// offsets to parameters with one register pushed onto stack
-+
-+#define ctx 8 // AES context structure
-+#define in_blk 12 // input byte array address parameter
-+#define out_blk 16 // output byte array address parameter
-+
-+// offsets in context structure
-+
-+#define nkey 0 // key length, size 4
-+#define nrnd 4 // number of rounds, size 4
-+#define ekey 8 // encryption key schedule base address, size 256
-+#define dkey 264 // decryption key schedule base address, size 256
-+
-+// This macro performs a forward encryption cycle. It is entered with
-+// the first previous round column values in %eax, %ebx, %esi and %edi and
-+// exits with the final values in the same registers.
-+
-+#define fwd_rnd(p1,p2) \
-+ mov %ebx,(%esp) ;\
-+ movzbl %al,%edx ;\
-+ mov %eax,%ecx ;\
-+ mov p2(%ebp),%eax ;\
-+ mov %edi,4(%esp) ;\
-+ mov p2+12(%ebp),%edi ;\
-+ xor p1(,%edx,4),%eax ;\
-+ movzbl %ch,%edx ;\
-+ shr $16,%ecx ;\
-+ mov p2+4(%ebp),%ebx ;\
-+ xor p1+tlen(,%edx,4),%edi ;\
-+ movzbl %cl,%edx ;\
-+ movzbl %ch,%ecx ;\
-+ xor p1+3*tlen(,%ecx,4),%ebx ;\
-+ mov %esi,%ecx ;\
-+ mov p1+2*tlen(,%edx,4),%esi ;\
-+ movzbl %cl,%edx ;\
-+ xor p1(,%edx,4),%esi ;\
-+ movzbl %ch,%edx ;\
-+ shr $16,%ecx ;\
-+ xor p1+tlen(,%edx,4),%ebx ;\
-+ movzbl %cl,%edx ;\
-+ movzbl %ch,%ecx ;\
-+ xor p1+2*tlen(,%edx,4),%eax ;\
-+ mov (%esp),%edx ;\
-+ xor p1+3*tlen(,%ecx,4),%edi ;\
-+ movzbl %dl,%ecx ;\
-+ xor p2+8(%ebp),%esi ;\
-+ xor p1(,%ecx,4),%ebx ;\
-+ movzbl %dh,%ecx ;\
-+ shr $16,%edx ;\
-+ xor p1+tlen(,%ecx,4),%eax ;\
-+ movzbl %dl,%ecx ;\
-+ movzbl %dh,%edx ;\
-+ xor p1+2*tlen(,%ecx,4),%edi ;\
-+ mov 4(%esp),%ecx ;\
-+ xor p1+3*tlen(,%edx,4),%esi ;\
-+ movzbl %cl,%edx ;\
-+ xor p1(,%edx,4),%edi ;\
-+ movzbl %ch,%edx ;\
-+ shr $16,%ecx ;\
-+ xor p1+tlen(,%edx,4),%esi ;\
-+ movzbl %cl,%edx ;\
-+ movzbl %ch,%ecx ;\
-+ xor p1+2*tlen(,%edx,4),%ebx ;\
-+ xor p1+3*tlen(,%ecx,4),%eax
-+
-+// This macro performs an inverse encryption cycle. It is entered with
-+// the first previous round column values in %eax, %ebx, %esi and %edi and
-+// exits with the final values in the same registers.
-+
-+#define inv_rnd(p1,p2) \
-+ movzbl %al,%edx ;\
-+ mov %ebx,(%esp) ;\
-+ mov %eax,%ecx ;\
-+ mov p2(%ebp),%eax ;\
-+ mov %edi,4(%esp) ;\
-+ mov p2+4(%ebp),%ebx ;\
-+ xor p1(,%edx,4),%eax ;\
-+ movzbl %ch,%edx ;\
-+ shr $16,%ecx ;\
-+ mov p2+12(%ebp),%edi ;\
-+ xor p1+tlen(,%edx,4),%ebx ;\
-+ movzbl %cl,%edx ;\
-+ movzbl %ch,%ecx ;\
-+ xor p1+3*tlen(,%ecx,4),%edi ;\
-+ mov %esi,%ecx ;\
-+ mov p1+2*tlen(,%edx,4),%esi ;\
-+ movzbl %cl,%edx ;\
-+ xor p1(,%edx,4),%esi ;\
-+ movzbl %ch,%edx ;\
-+ shr $16,%ecx ;\
-+ xor p1+tlen(,%edx,4),%edi ;\
-+ movzbl %cl,%edx ;\
-+ movzbl %ch,%ecx ;\
-+ xor p1+2*tlen(,%edx,4),%eax ;\
-+ mov (%esp),%edx ;\
-+ xor p1+3*tlen(,%ecx,4),%ebx ;\
-+ movzbl %dl,%ecx ;\
-+ xor p2+8(%ebp),%esi ;\
-+ xor p1(,%ecx,4),%ebx ;\
-+ movzbl %dh,%ecx ;\
-+ shr $16,%edx ;\
-+ xor p1+tlen(,%ecx,4),%esi ;\
-+ movzbl %dl,%ecx ;\
-+ movzbl %dh,%edx ;\
-+ xor p1+2*tlen(,%ecx,4),%edi ;\
-+ mov 4(%esp),%ecx ;\
-+ xor p1+3*tlen(,%edx,4),%eax ;\
-+ movzbl %cl,%edx ;\
-+ xor p1(,%edx,4),%edi ;\
-+ movzbl %ch,%edx ;\
-+ shr $16,%ecx ;\
-+ xor p1+tlen(,%edx,4),%eax ;\
-+ movzbl %cl,%edx ;\
-+ movzbl %ch,%ecx ;\
-+ xor p1+2*tlen(,%edx,4),%ebx ;\
-+ xor p1+3*tlen(,%ecx,4),%esi
-+
-+// AES (Rijndael) Encryption Subroutine
-+
-+ .text
-+ .align ALIGN32BYTES
-+aes_encrypt:
-+ push %ebp
-+ mov ctx(%esp),%ebp // pointer to context
-+ mov in_blk(%esp),%ecx
-+ push %ebx
-+ push %esi
-+ push %edi
-+ mov nrnd(%ebp),%edx // number of rounds
-+ lea ekey+16(%ebp),%ebp // key pointer
-+
-+// input four columns and xor in first round key
-+
-+ mov (%ecx),%eax
-+ mov 4(%ecx),%ebx
-+ mov 8(%ecx),%esi
-+ mov 12(%ecx),%edi
-+ xor -16(%ebp),%eax
-+ xor -12(%ebp),%ebx
-+ xor -8(%ebp),%esi
-+ xor -4(%ebp),%edi
-+
-+ sub $8,%esp // space for register saves on stack
-+
-+ sub $10,%edx
-+ je aes_15
-+ add $32,%ebp
-+ sub $2,%edx
-+ je aes_13
-+ add $32,%ebp
-+
-+ fwd_rnd(aes_ft_tab,-64) // 14 rounds for 256-bit key
-+ fwd_rnd(aes_ft_tab,-48)
-+aes_13: fwd_rnd(aes_ft_tab,-32) // 12 rounds for 192-bit key
-+ fwd_rnd(aes_ft_tab,-16)
-+aes_15: fwd_rnd(aes_ft_tab,0) // 10 rounds for 128-bit key
-+ fwd_rnd(aes_ft_tab,16)
-+ fwd_rnd(aes_ft_tab,32)
-+ fwd_rnd(aes_ft_tab,48)
-+ fwd_rnd(aes_ft_tab,64)
-+ fwd_rnd(aes_ft_tab,80)
-+ fwd_rnd(aes_ft_tab,96)
-+ fwd_rnd(aes_ft_tab,112)
-+ fwd_rnd(aes_ft_tab,128)
-+ fwd_rnd(aes_fl_tab,144) // last round uses a different table
-+
-+// move final values to the output array.
-+
-+ mov out_blk+20(%esp),%ebp
-+ add $8,%esp
-+ mov %eax,(%ebp)
-+ mov %ebx,4(%ebp)
-+ mov %esi,8(%ebp)
-+ mov %edi,12(%ebp)
-+ pop %edi
-+ pop %esi
-+ pop %ebx
-+ pop %ebp
-+ ret
-+
-+
-+// AES (Rijndael) Decryption Subroutine
-+
-+ .align ALIGN32BYTES
-+aes_decrypt:
-+ push %ebp
-+ mov ctx(%esp),%ebp // pointer to context
-+ mov in_blk(%esp),%ecx
-+ push %ebx
-+ push %esi
-+ push %edi
-+ mov nrnd(%ebp),%edx // number of rounds
-+ lea dkey+16(%ebp),%ebp // key pointer
-+
-+// input four columns and xor in first round key
-+
-+ mov (%ecx),%eax
-+ mov 4(%ecx),%ebx
-+ mov 8(%ecx),%esi
-+ mov 12(%ecx),%edi
-+ xor -16(%ebp),%eax
-+ xor -12(%ebp),%ebx
-+ xor -8(%ebp),%esi
-+ xor -4(%ebp),%edi
-+
-+ sub $8,%esp // space for register saves on stack
-+
-+ sub $10,%edx
-+ je aes_25
-+ add $32,%ebp
-+ sub $2,%edx
-+ je aes_23
-+ add $32,%ebp
-+
-+ inv_rnd(aes_it_tab,-64) // 14 rounds for 256-bit key
-+ inv_rnd(aes_it_tab,-48)
-+aes_23: inv_rnd(aes_it_tab,-32) // 12 rounds for 192-bit key
-+ inv_rnd(aes_it_tab,-16)
-+aes_25: inv_rnd(aes_it_tab,0) // 10 rounds for 128-bit key
-+ inv_rnd(aes_it_tab,16)
-+ inv_rnd(aes_it_tab,32)
-+ inv_rnd(aes_it_tab,48)
-+ inv_rnd(aes_it_tab,64)
-+ inv_rnd(aes_it_tab,80)
-+ inv_rnd(aes_it_tab,96)
-+ inv_rnd(aes_it_tab,112)
-+ inv_rnd(aes_it_tab,128)
-+ inv_rnd(aes_il_tab,144) // last round uses a different table
-+
-+// move final values to the output array.
-+
-+ mov out_blk+20(%esp),%ebp
-+ add $8,%esp
-+ mov %eax,(%ebp)
-+ mov %ebx,4(%ebp)
-+ mov %esi,8(%ebp)
-+ mov %edi,12(%ebp)
-+ pop %edi
-+ pop %esi
-+ pop %ebx
-+ pop %ebp
-+ ret
-+
-+// AES (Rijndael) Key Schedule Subroutine
-+
-+// input/output parameters
-+
-+#define aes_cx 12 // AES context
-+#define in_key 16 // key input array address
-+#define key_ln 20 // key length, bytes (16,24,32) or bits (128,192,256)
-+#define ed_flg 24 // 0=create both encr/decr keys, 1=create encr key only
-+
-+// offsets for locals
-+
-+#define cnt -4
-+#define kpf -8
-+#define slen 8
-+
-+// This macro performs a column mixing operation on an input 32-bit
-+// word to give a 32-bit result. It uses each of the 4 bytes in the
-+// the input column to index 4 different tables of 256 32-bit words
-+// that are xored together to form the output value.
-+
-+#define mix_col(p1) \
-+ movzbl %bl,%ecx ;\
-+ mov p1(,%ecx,4),%eax ;\
-+ movzbl %bh,%ecx ;\
-+ ror $16,%ebx ;\
-+ xor p1+tlen(,%ecx,4),%eax ;\
-+ movzbl %bl,%ecx ;\
-+ xor p1+2*tlen(,%ecx,4),%eax ;\
-+ movzbl %bh,%ecx ;\
-+ xor p1+3*tlen(,%ecx,4),%eax
-+
-+// Key Schedule Macros
-+
-+#define ksc4(p1) \
-+ rol $24,%ebx ;\
-+ mix_col(aes_fl_tab) ;\
-+ ror $8,%ebx ;\
-+ xor 4*p1+aes_rcon_tab,%eax ;\
-+ xor %eax,%esi ;\
-+ xor %esi,%ebp ;\
-+ mov %esi,16*p1(%edi) ;\
-+ mov %ebp,16*p1+4(%edi) ;\
-+ xor %ebp,%edx ;\
-+ xor %edx,%ebx ;\
-+ mov %edx,16*p1+8(%edi) ;\
-+ mov %ebx,16*p1+12(%edi)
-+
-+#define ksc6(p1) \
-+ rol $24,%ebx ;\
-+ mix_col(aes_fl_tab) ;\
-+ ror $8,%ebx ;\
-+ xor 4*p1+aes_rcon_tab,%eax ;\
-+ xor 24*p1-24(%edi),%eax ;\
-+ mov %eax,24*p1(%edi) ;\
-+ xor 24*p1-20(%edi),%eax ;\
-+ mov %eax,24*p1+4(%edi) ;\
-+ xor %eax,%esi ;\
-+ xor %esi,%ebp ;\
-+ mov %esi,24*p1+8(%edi) ;\
-+ mov %ebp,24*p1+12(%edi) ;\
-+ xor %ebp,%edx ;\
-+ xor %edx,%ebx ;\
-+ mov %edx,24*p1+16(%edi) ;\
-+ mov %ebx,24*p1+20(%edi)
-+
-+#define ksc8(p1) \
-+ rol $24,%ebx ;\
-+ mix_col(aes_fl_tab) ;\
-+ ror $8,%ebx ;\
-+ xor 4*p1+aes_rcon_tab,%eax ;\
-+ xor 32*p1-32(%edi),%eax ;\
-+ mov %eax,32*p1(%edi) ;\
-+ xor 32*p1-28(%edi),%eax ;\
-+ mov %eax,32*p1+4(%edi) ;\
-+ xor 32*p1-24(%edi),%eax ;\
-+ mov %eax,32*p1+8(%edi) ;\
-+ xor 32*p1-20(%edi),%eax ;\
-+ mov %eax,32*p1+12(%edi) ;\
-+ push %ebx ;\
-+ mov %eax,%ebx ;\
-+ mix_col(aes_fl_tab) ;\
-+ pop %ebx ;\
-+ xor %eax,%esi ;\
-+ xor %esi,%ebp ;\
-+ mov %esi,32*p1+16(%edi) ;\
-+ mov %ebp,32*p1+20(%edi) ;\
-+ xor %ebp,%edx ;\
-+ xor %edx,%ebx ;\
-+ mov %edx,32*p1+24(%edi) ;\
-+ mov %ebx,32*p1+28(%edi)
-+
-+ .align ALIGN32BYTES
-+aes_set_key:
-+ pushfl
-+ push %ebp
-+ mov %esp,%ebp
-+ sub $slen,%esp
-+ push %ebx
-+ push %esi
-+ push %edi
-+
-+ mov aes_cx(%ebp),%edx // edx -> AES context
-+
-+ mov key_ln(%ebp),%ecx // key length
-+ cmpl $128,%ecx
-+ jb aes_30
-+ shr $3,%ecx
-+aes_30: cmpl $32,%ecx
-+ je aes_32
-+ cmpl $24,%ecx
-+ je aes_32
-+ mov $16,%ecx
-+aes_32: shr $2,%ecx
-+ mov %ecx,nkey(%edx)
-+
-+ lea 6(%ecx),%eax // 10/12/14 for 4/6/8 32-bit key length
-+ mov %eax,nrnd(%edx)
-+
-+ mov in_key(%ebp),%esi // key input array
-+ lea ekey(%edx),%edi // key position in AES context
-+ cld
-+ push %ebp
-+ mov %ecx,%eax // save key length in eax
-+ rep ; movsl // words in the key schedule
-+ mov -4(%esi),%ebx // put some values in registers
-+ mov -8(%esi),%edx // to allow faster code
-+ mov -12(%esi),%ebp
-+ mov -16(%esi),%esi
-+
-+ cmpl $4,%eax // jump on key size
-+ je aes_36
-+ cmpl $6,%eax
-+ je aes_35
-+
-+ ksc8(0)
-+ ksc8(1)
-+ ksc8(2)
-+ ksc8(3)
-+ ksc8(4)
-+ ksc8(5)
-+ ksc8(6)
-+ jmp aes_37
-+aes_35: ksc6(0)
-+ ksc6(1)
-+ ksc6(2)
-+ ksc6(3)
-+ ksc6(4)
-+ ksc6(5)
-+ ksc6(6)
-+ ksc6(7)
-+ jmp aes_37
-+aes_36: ksc4(0)
-+ ksc4(1)
-+ ksc4(2)
-+ ksc4(3)
-+ ksc4(4)
-+ ksc4(5)
-+ ksc4(6)
-+ ksc4(7)
-+ ksc4(8)
-+ ksc4(9)
-+aes_37: pop %ebp
-+ mov aes_cx(%ebp),%edx // edx -> AES context
-+ cmpl $0,ed_flg(%ebp)
-+ jne aes_39
-+
-+// compile decryption key schedule from encryption schedule - reverse
-+// order and do mix_column operation on round keys except first and last
-+
-+ mov nrnd(%edx),%eax // kt = cx->d_key + nc * cx->Nrnd
-+ shl $2,%eax
-+ lea dkey(%edx,%eax,4),%edi
-+ lea ekey(%edx),%esi // kf = cx->e_key
-+
-+ movsl // copy first round key (unmodified)
-+ movsl
-+ movsl
-+ movsl
-+ sub $32,%edi
-+ movl $1,cnt(%ebp)
-+aes_38: // do mix column on each column of
-+ lodsl // each round key
-+ mov %eax,%ebx
-+ mix_col(aes_im_tab)
-+ stosl
-+ lodsl
-+ mov %eax,%ebx
-+ mix_col(aes_im_tab)
-+ stosl
-+ lodsl
-+ mov %eax,%ebx
-+ mix_col(aes_im_tab)
-+ stosl
-+ lodsl
-+ mov %eax,%ebx
-+ mix_col(aes_im_tab)
-+ stosl
-+ sub $32,%edi
-+
-+ incl cnt(%ebp)
-+ mov cnt(%ebp),%eax
-+ cmp nrnd(%edx),%eax
-+ jb aes_38
-+
-+ movsl // copy last round key (unmodified)
-+ movsl
-+ movsl
-+ movsl
-+aes_39: pop %edi
-+ pop %esi
-+ pop %ebx
-+ mov %ebp,%esp
-+ pop %ebp
-+ popfl
-+ ret
-+
-+
-+// finite field multiplies by {02}, {04} and {08}
-+
-+#define f2(x) ((x<<1)^(((x>>7)&1)*0x11b))
-+#define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b))
-+#define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b))
-+
-+// finite field multiplies required in table generation
-+
-+#define f3(x) (f2(x) ^ x)
-+#define f9(x) (f8(x) ^ x)
-+#define fb(x) (f8(x) ^ f2(x) ^ x)
-+#define fd(x) (f8(x) ^ f4(x) ^ x)
-+#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
-+
-+// These defines generate the forward table entries
-+
-+#define u0(x) ((f3(x) << 24) | (x << 16) | (x << 8) | f2(x))
-+#define u1(x) ((x << 24) | (x << 16) | (f2(x) << 8) | f3(x))
-+#define u2(x) ((x << 24) | (f2(x) << 16) | (f3(x) << 8) | x)
-+#define u3(x) ((f2(x) << 24) | (f3(x) << 16) | (x << 8) | x)
-+
-+// These defines generate the inverse table entries
-+
-+#define v0(x) ((fb(x) << 24) | (fd(x) << 16) | (f9(x) << 8) | fe(x))
-+#define v1(x) ((fd(x) << 24) | (f9(x) << 16) | (fe(x) << 8) | fb(x))
-+#define v2(x) ((f9(x) << 24) | (fe(x) << 16) | (fb(x) << 8) | fd(x))
-+#define v3(x) ((fe(x) << 24) | (fb(x) << 16) | (fd(x) << 8) | f9(x))
-+
-+// These defines generate entries for the last round tables
-+
-+#define w0(x) (x)
-+#define w1(x) (x << 8)
-+#define w2(x) (x << 16)
-+#define w3(x) (x << 24)
-+
-+// macro to generate inverse mix column tables (needed for the key schedule)
-+
-+#define im_data0(p1) \
-+ .long p1(0x00),p1(0x01),p1(0x02),p1(0x03),p1(0x04),p1(0x05),p1(0x06),p1(0x07) ;\
-+ .long p1(0x08),p1(0x09),p1(0x0a),p1(0x0b),p1(0x0c),p1(0x0d),p1(0x0e),p1(0x0f) ;\
-+ .long p1(0x10),p1(0x11),p1(0x12),p1(0x13),p1(0x14),p1(0x15),p1(0x16),p1(0x17) ;\
-+ .long p1(0x18),p1(0x19),p1(0x1a),p1(0x1b),p1(0x1c),p1(0x1d),p1(0x1e),p1(0x1f)
-+#define im_data1(p1) \
-+ .long p1(0x20),p1(0x21),p1(0x22),p1(0x23),p1(0x24),p1(0x25),p1(0x26),p1(0x27) ;\
-+ .long p1(0x28),p1(0x29),p1(0x2a),p1(0x2b),p1(0x2c),p1(0x2d),p1(0x2e),p1(0x2f) ;\
-+ .long p1(0x30),p1(0x31),p1(0x32),p1(0x33),p1(0x34),p1(0x35),p1(0x36),p1(0x37) ;\
-+ .long p1(0x38),p1(0x39),p1(0x3a),p1(0x3b),p1(0x3c),p1(0x3d),p1(0x3e),p1(0x3f)
-+#define im_data2(p1) \
-+ .long p1(0x40),p1(0x41),p1(0x42),p1(0x43),p1(0x44),p1(0x45),p1(0x46),p1(0x47) ;\
-+ .long p1(0x48),p1(0x49),p1(0x4a),p1(0x4b),p1(0x4c),p1(0x4d),p1(0x4e),p1(0x4f) ;\
-+ .long p1(0x50),p1(0x51),p1(0x52),p1(0x53),p1(0x54),p1(0x55),p1(0x56),p1(0x57) ;\
-+ .long p1(0x58),p1(0x59),p1(0x5a),p1(0x5b),p1(0x5c),p1(0x5d),p1(0x5e),p1(0x5f)
-+#define im_data3(p1) \
-+ .long p1(0x60),p1(0x61),p1(0x62),p1(0x63),p1(0x64),p1(0x65),p1(0x66),p1(0x67) ;\
-+ .long p1(0x68),p1(0x69),p1(0x6a),p1(0x6b),p1(0x6c),p1(0x6d),p1(0x6e),p1(0x6f) ;\
-+ .long p1(0x70),p1(0x71),p1(0x72),p1(0x73),p1(0x74),p1(0x75),p1(0x76),p1(0x77) ;\
-+ .long p1(0x78),p1(0x79),p1(0x7a),p1(0x7b),p1(0x7c),p1(0x7d),p1(0x7e),p1(0x7f)
-+#define im_data4(p1) \
-+ .long p1(0x80),p1(0x81),p1(0x82),p1(0x83),p1(0x84),p1(0x85),p1(0x86),p1(0x87) ;\
-+ .long p1(0x88),p1(0x89),p1(0x8a),p1(0x8b),p1(0x8c),p1(0x8d),p1(0x8e),p1(0x8f) ;\
-+ .long p1(0x90),p1(0x91),p1(0x92),p1(0x93),p1(0x94),p1(0x95),p1(0x96),p1(0x97) ;\
-+ .long p1(0x98),p1(0x99),p1(0x9a),p1(0x9b),p1(0x9c),p1(0x9d),p1(0x9e),p1(0x9f)
-+#define im_data5(p1) \
-+ .long p1(0xa0),p1(0xa1),p1(0xa2),p1(0xa3),p1(0xa4),p1(0xa5),p1(0xa6),p1(0xa7) ;\
-+ .long p1(0xa8),p1(0xa9),p1(0xaa),p1(0xab),p1(0xac),p1(0xad),p1(0xae),p1(0xaf) ;\
-+ .long p1(0xb0),p1(0xb1),p1(0xb2),p1(0xb3),p1(0xb4),p1(0xb5),p1(0xb6),p1(0xb7) ;\
-+ .long p1(0xb8),p1(0xb9),p1(0xba),p1(0xbb),p1(0xbc),p1(0xbd),p1(0xbe),p1(0xbf)
-+#define im_data6(p1) \
-+ .long p1(0xc0),p1(0xc1),p1(0xc2),p1(0xc3),p1(0xc4),p1(0xc5),p1(0xc6),p1(0xc7) ;\
-+ .long p1(0xc8),p1(0xc9),p1(0xca),p1(0xcb),p1(0xcc),p1(0xcd),p1(0xce),p1(0xcf) ;\
-+ .long p1(0xd0),p1(0xd1),p1(0xd2),p1(0xd3),p1(0xd4),p1(0xd5),p1(0xd6),p1(0xd7) ;\
-+ .long p1(0xd8),p1(0xd9),p1(0xda),p1(0xdb),p1(0xdc),p1(0xdd),p1(0xde),p1(0xdf)
-+#define im_data7(p1) \
-+ .long p1(0xe0),p1(0xe1),p1(0xe2),p1(0xe3),p1(0xe4),p1(0xe5),p1(0xe6),p1(0xe7) ;\
-+ .long p1(0xe8),p1(0xe9),p1(0xea),p1(0xeb),p1(0xec),p1(0xed),p1(0xee),p1(0xef) ;\
-+ .long p1(0xf0),p1(0xf1),p1(0xf2),p1(0xf3),p1(0xf4),p1(0xf5),p1(0xf6),p1(0xf7) ;\
-+ .long p1(0xf8),p1(0xf9),p1(0xfa),p1(0xfb),p1(0xfc),p1(0xfd),p1(0xfe),p1(0xff)
-+
-+// S-box data - 256 entries
-+
-+#define sb_data0(p1) \
-+ .long p1(0x63),p1(0x7c),p1(0x77),p1(0x7b),p1(0xf2),p1(0x6b),p1(0x6f),p1(0xc5) ;\
-+ .long p1(0x30),p1(0x01),p1(0x67),p1(0x2b),p1(0xfe),p1(0xd7),p1(0xab),p1(0x76) ;\
-+ .long p1(0xca),p1(0x82),p1(0xc9),p1(0x7d),p1(0xfa),p1(0x59),p1(0x47),p1(0xf0) ;\
-+ .long p1(0xad),p1(0xd4),p1(0xa2),p1(0xaf),p1(0x9c),p1(0xa4),p1(0x72),p1(0xc0)
-+#define sb_data1(p1) \
-+ .long p1(0xb7),p1(0xfd),p1(0x93),p1(0x26),p1(0x36),p1(0x3f),p1(0xf7),p1(0xcc) ;\
-+ .long p1(0x34),p1(0xa5),p1(0xe5),p1(0xf1),p1(0x71),p1(0xd8),p1(0x31),p1(0x15) ;\
-+ .long p1(0x04),p1(0xc7),p1(0x23),p1(0xc3),p1(0x18),p1(0x96),p1(0x05),p1(0x9a) ;\
-+ .long p1(0x07),p1(0x12),p1(0x80),p1(0xe2),p1(0xeb),p1(0x27),p1(0xb2),p1(0x75)
-+#define sb_data2(p1) \
-+ .long p1(0x09),p1(0x83),p1(0x2c),p1(0x1a),p1(0x1b),p1(0x6e),p1(0x5a),p1(0xa0) ;\
-+ .long p1(0x52),p1(0x3b),p1(0xd6),p1(0xb3),p1(0x29),p1(0xe3),p1(0x2f),p1(0x84) ;\
-+ .long p1(0x53),p1(0xd1),p1(0x00),p1(0xed),p1(0x20),p1(0xfc),p1(0xb1),p1(0x5b) ;\
-+ .long p1(0x6a),p1(0xcb),p1(0xbe),p1(0x39),p1(0x4a),p1(0x4c),p1(0x58),p1(0xcf)
-+#define sb_data3(p1) \
-+ .long p1(0xd0),p1(0xef),p1(0xaa),p1(0xfb),p1(0x43),p1(0x4d),p1(0x33),p1(0x85) ;\
-+ .long p1(0x45),p1(0xf9),p1(0x02),p1(0x7f),p1(0x50),p1(0x3c),p1(0x9f),p1(0xa8) ;\
-+ .long p1(0x51),p1(0xa3),p1(0x40),p1(0x8f),p1(0x92),p1(0x9d),p1(0x38),p1(0xf5) ;\
-+ .long p1(0xbc),p1(0xb6),p1(0xda),p1(0x21),p1(0x10),p1(0xff),p1(0xf3),p1(0xd2)
-+#define sb_data4(p1) \
-+ .long p1(0xcd),p1(0x0c),p1(0x13),p1(0xec),p1(0x5f),p1(0x97),p1(0x44),p1(0x17) ;\
-+ .long p1(0xc4),p1(0xa7),p1(0x7e),p1(0x3d),p1(0x64),p1(0x5d),p1(0x19),p1(0x73) ;\
-+ .long p1(0x60),p1(0x81),p1(0x4f),p1(0xdc),p1(0x22),p1(0x2a),p1(0x90),p1(0x88) ;\
-+ .long p1(0x46),p1(0xee),p1(0xb8),p1(0x14),p1(0xde),p1(0x5e),p1(0x0b),p1(0xdb)
-+#define sb_data5(p1) \
-+ .long p1(0xe0),p1(0x32),p1(0x3a),p1(0x0a),p1(0x49),p1(0x06),p1(0x24),p1(0x5c) ;\
-+ .long p1(0xc2),p1(0xd3),p1(0xac),p1(0x62),p1(0x91),p1(0x95),p1(0xe4),p1(0x79) ;\
-+ .long p1(0xe7),p1(0xc8),p1(0x37),p1(0x6d),p1(0x8d),p1(0xd5),p1(0x4e),p1(0xa9) ;\
-+ .long p1(0x6c),p1(0x56),p1(0xf4),p1(0xea),p1(0x65),p1(0x7a),p1(0xae),p1(0x08)
-+#define sb_data6(p1) \
-+ .long p1(0xba),p1(0x78),p1(0x25),p1(0x2e),p1(0x1c),p1(0xa6),p1(0xb4),p1(0xc6) ;\
-+ .long p1(0xe8),p1(0xdd),p1(0x74),p1(0x1f),p1(0x4b),p1(0xbd),p1(0x8b),p1(0x8a) ;\
-+ .long p1(0x70),p1(0x3e),p1(0xb5),p1(0x66),p1(0x48),p1(0x03),p1(0xf6),p1(0x0e) ;\
-+ .long p1(0x61),p1(0x35),p1(0x57),p1(0xb9),p1(0x86),p1(0xc1),p1(0x1d),p1(0x9e)
-+#define sb_data7(p1) \
-+ .long p1(0xe1),p1(0xf8),p1(0x98),p1(0x11),p1(0x69),p1(0xd9),p1(0x8e),p1(0x94) ;\
-+ .long p1(0x9b),p1(0x1e),p1(0x87),p1(0xe9),p1(0xce),p1(0x55),p1(0x28),p1(0xdf) ;\
-+ .long p1(0x8c),p1(0xa1),p1(0x89),p1(0x0d),p1(0xbf),p1(0xe6),p1(0x42),p1(0x68) ;\
-+ .long p1(0x41),p1(0x99),p1(0x2d),p1(0x0f),p1(0xb0),p1(0x54),p1(0xbb),p1(0x16)
-+
-+// Inverse S-box data - 256 entries
-+
-+#define ib_data0(p1) \
-+ .long p1(0x52),p1(0x09),p1(0x6a),p1(0xd5),p1(0x30),p1(0x36),p1(0xa5),p1(0x38) ;\
-+ .long p1(0xbf),p1(0x40),p1(0xa3),p1(0x9e),p1(0x81),p1(0xf3),p1(0xd7),p1(0xfb) ;\
-+ .long p1(0x7c),p1(0xe3),p1(0x39),p1(0x82),p1(0x9b),p1(0x2f),p1(0xff),p1(0x87) ;\
-+ .long p1(0x34),p1(0x8e),p1(0x43),p1(0x44),p1(0xc4),p1(0xde),p1(0xe9),p1(0xcb)
-+#define ib_data1(p1) \
-+ .long p1(0x54),p1(0x7b),p1(0x94),p1(0x32),p1(0xa6),p1(0xc2),p1(0x23),p1(0x3d) ;\
-+ .long p1(0xee),p1(0x4c),p1(0x95),p1(0x0b),p1(0x42),p1(0xfa),p1(0xc3),p1(0x4e) ;\
-+ .long p1(0x08),p1(0x2e),p1(0xa1),p1(0x66),p1(0x28),p1(0xd9),p1(0x24),p1(0xb2) ;\
-+ .long p1(0x76),p1(0x5b),p1(0xa2),p1(0x49),p1(0x6d),p1(0x8b),p1(0xd1),p1(0x25)
-+#define ib_data2(p1) \
-+ .long p1(0x72),p1(0xf8),p1(0xf6),p1(0x64),p1(0x86),p1(0x68),p1(0x98),p1(0x16) ;\
-+ .long p1(0xd4),p1(0xa4),p1(0x5c),p1(0xcc),p1(0x5d),p1(0x65),p1(0xb6),p1(0x92) ;\
-+ .long p1(0x6c),p1(0x70),p1(0x48),p1(0x50),p1(0xfd),p1(0xed),p1(0xb9),p1(0xda) ;\
-+ .long p1(0x5e),p1(0x15),p1(0x46),p1(0x57),p1(0xa7),p1(0x8d),p1(0x9d),p1(0x84)
-+#define ib_data3(p1) \
-+ .long p1(0x90),p1(0xd8),p1(0xab),p1(0x00),p1(0x8c),p1(0xbc),p1(0xd3),p1(0x0a) ;\
-+ .long p1(0xf7),p1(0xe4),p1(0x58),p1(0x05),p1(0xb8),p1(0xb3),p1(0x45),p1(0x06) ;\
-+ .long p1(0xd0),p1(0x2c),p1(0x1e),p1(0x8f),p1(0xca),p1(0x3f),p1(0x0f),p1(0x02) ;\
-+ .long p1(0xc1),p1(0xaf),p1(0xbd),p1(0x03),p1(0x01),p1(0x13),p1(0x8a),p1(0x6b)
-+#define ib_data4(p1) \
-+ .long p1(0x3a),p1(0x91),p1(0x11),p1(0x41),p1(0x4f),p1(0x67),p1(0xdc),p1(0xea) ;\
-+ .long p1(0x97),p1(0xf2),p1(0xcf),p1(0xce),p1(0xf0),p1(0xb4),p1(0xe6),p1(0x73) ;\
-+ .long p1(0x96),p1(0xac),p1(0x74),p1(0x22),p1(0xe7),p1(0xad),p1(0x35),p1(0x85) ;\
-+ .long p1(0xe2),p1(0xf9),p1(0x37),p1(0xe8),p1(0x1c),p1(0x75),p1(0xdf),p1(0x6e)
-+#define ib_data5(p1) \
-+ .long p1(0x47),p1(0xf1),p1(0x1a),p1(0x71),p1(0x1d),p1(0x29),p1(0xc5),p1(0x89) ;\
-+ .long p1(0x6f),p1(0xb7),p1(0x62),p1(0x0e),p1(0xaa),p1(0x18),p1(0xbe),p1(0x1b) ;\
-+ .long p1(0xfc),p1(0x56),p1(0x3e),p1(0x4b),p1(0xc6),p1(0xd2),p1(0x79),p1(0x20) ;\
-+ .long p1(0x9a),p1(0xdb),p1(0xc0),p1(0xfe),p1(0x78),p1(0xcd),p1(0x5a),p1(0xf4)
-+#define ib_data6(p1) \
-+ .long p1(0x1f),p1(0xdd),p1(0xa8),p1(0x33),p1(0x88),p1(0x07),p1(0xc7),p1(0x31) ;\
-+ .long p1(0xb1),p1(0x12),p1(0x10),p1(0x59),p1(0x27),p1(0x80),p1(0xec),p1(0x5f) ;\
-+ .long p1(0x60),p1(0x51),p1(0x7f),p1(0xa9),p1(0x19),p1(0xb5),p1(0x4a),p1(0x0d) ;\
-+ .long p1(0x2d),p1(0xe5),p1(0x7a),p1(0x9f),p1(0x93),p1(0xc9),p1(0x9c),p1(0xef)
-+#define ib_data7(p1) \
-+ .long p1(0xa0),p1(0xe0),p1(0x3b),p1(0x4d),p1(0xae),p1(0x2a),p1(0xf5),p1(0xb0) ;\
-+ .long p1(0xc8),p1(0xeb),p1(0xbb),p1(0x3c),p1(0x83),p1(0x53),p1(0x99),p1(0x61) ;\
-+ .long p1(0x17),p1(0x2b),p1(0x04),p1(0x7e),p1(0xba),p1(0x77),p1(0xd6),p1(0x26) ;\
-+ .long p1(0xe1),p1(0x69),p1(0x14),p1(0x63),p1(0x55),p1(0x21),p1(0x0c),p1(0x7d)
-+
-+// The rcon_table (needed for the key schedule)
-+//
-+// Here is original Dr Brian Gladman's source code:
-+// _rcon_tab:
-+// %assign x 1
-+// %rep 29
-+// dd x
-+// %assign x f2(x)
-+// %endrep
-+//
-+// Here is precomputed output (it's more portable this way):
-+
-+ .align ALIGN32BYTES
-+aes_rcon_tab:
-+ .long 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
-+ .long 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f
-+ .long 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4
-+ .long 0xb3,0x7d,0xfa,0xef,0xc5
-+
-+// The forward xor tables
-+
-+ .align ALIGN32BYTES
-+aes_ft_tab:
-+ sb_data0(u0)
-+ sb_data1(u0)
-+ sb_data2(u0)
-+ sb_data3(u0)
-+ sb_data4(u0)
-+ sb_data5(u0)
-+ sb_data6(u0)
-+ sb_data7(u0)
-+
-+ sb_data0(u1)
-+ sb_data1(u1)
-+ sb_data2(u1)
-+ sb_data3(u1)
-+ sb_data4(u1)
-+ sb_data5(u1)
-+ sb_data6(u1)
-+ sb_data7(u1)
-+
-+ sb_data0(u2)
-+ sb_data1(u2)
-+ sb_data2(u2)
-+ sb_data3(u2)
-+ sb_data4(u2)
-+ sb_data5(u2)
-+ sb_data6(u2)
-+ sb_data7(u2)
-+
-+ sb_data0(u3)
-+ sb_data1(u3)
-+ sb_data2(u3)
-+ sb_data3(u3)
-+ sb_data4(u3)
-+ sb_data5(u3)
-+ sb_data6(u3)
-+ sb_data7(u3)
-+
-+ .align ALIGN32BYTES
-+aes_fl_tab:
-+ sb_data0(w0)
-+ sb_data1(w0)
-+ sb_data2(w0)
-+ sb_data3(w0)
-+ sb_data4(w0)
-+ sb_data5(w0)
-+ sb_data6(w0)
-+ sb_data7(w0)
-+
-+ sb_data0(w1)
-+ sb_data1(w1)
-+ sb_data2(w1)
-+ sb_data3(w1)
-+ sb_data4(w1)
-+ sb_data5(w1)
-+ sb_data6(w1)
-+ sb_data7(w1)
-+
-+ sb_data0(w2)
-+ sb_data1(w2)
-+ sb_data2(w2)
-+ sb_data3(w2)
-+ sb_data4(w2)
-+ sb_data5(w2)
-+ sb_data6(w2)
-+ sb_data7(w2)
-+
-+ sb_data0(w3)
-+ sb_data1(w3)
-+ sb_data2(w3)
-+ sb_data3(w3)
-+ sb_data4(w3)
-+ sb_data5(w3)
-+ sb_data6(w3)
-+ sb_data7(w3)
-+
-+// The inverse xor tables
-+
-+ .align ALIGN32BYTES
-+aes_it_tab:
-+ ib_data0(v0)
-+ ib_data1(v0)
-+ ib_data2(v0)
-+ ib_data3(v0)
-+ ib_data4(v0)
-+ ib_data5(v0)
-+ ib_data6(v0)
-+ ib_data7(v0)
-+
-+ ib_data0(v1)
-+ ib_data1(v1)
-+ ib_data2(v1)
-+ ib_data3(v1)
-+ ib_data4(v1)
-+ ib_data5(v1)
-+ ib_data6(v1)
-+ ib_data7(v1)
-+
-+ ib_data0(v2)
-+ ib_data1(v2)
-+ ib_data2(v2)
-+ ib_data3(v2)
-+ ib_data4(v2)
-+ ib_data5(v2)
-+ ib_data6(v2)
-+ ib_data7(v2)
-+
-+ ib_data0(v3)
-+ ib_data1(v3)
-+ ib_data2(v3)
-+ ib_data3(v3)
-+ ib_data4(v3)
-+ ib_data5(v3)
-+ ib_data6(v3)
-+ ib_data7(v3)
-+
-+ .align ALIGN32BYTES
-+aes_il_tab:
-+ ib_data0(w0)
-+ ib_data1(w0)
-+ ib_data2(w0)
-+ ib_data3(w0)
-+ ib_data4(w0)
-+ ib_data5(w0)
-+ ib_data6(w0)
-+ ib_data7(w0)
-+
-+ ib_data0(w1)
-+ ib_data1(w1)
-+ ib_data2(w1)
-+ ib_data3(w1)
-+ ib_data4(w1)
-+ ib_data5(w1)
-+ ib_data6(w1)
-+ ib_data7(w1)
-+
-+ ib_data0(w2)
-+ ib_data1(w2)
-+ ib_data2(w2)
-+ ib_data3(w2)
-+ ib_data4(w2)
-+ ib_data5(w2)
-+ ib_data6(w2)
-+ ib_data7(w2)
-+
-+ ib_data0(w3)
-+ ib_data1(w3)
-+ ib_data2(w3)
-+ ib_data3(w3)
-+ ib_data4(w3)
-+ ib_data5(w3)
-+ ib_data6(w3)
-+ ib_data7(w3)
-+
-+// The inverse mix column tables
-+
-+ .align ALIGN32BYTES
-+aes_im_tab:
-+ im_data0(v0)
-+ im_data1(v0)
-+ im_data2(v0)
-+ im_data3(v0)
-+ im_data4(v0)
-+ im_data5(v0)
-+ im_data6(v0)
-+ im_data7(v0)
-+
-+ im_data0(v1)
-+ im_data1(v1)
-+ im_data2(v1)
-+ im_data3(v1)
-+ im_data4(v1)
-+ im_data5(v1)
-+ im_data6(v1)
-+ im_data7(v1)
-+
-+ im_data0(v2)
-+ im_data1(v2)
-+ im_data2(v2)
-+ im_data3(v2)
-+ im_data4(v2)
-+ im_data5(v2)
-+ im_data6(v2)
-+ im_data7(v2)
-+
-+ im_data0(v3)
-+ im_data1(v3)
-+ im_data2(v3)
-+ im_data3(v3)
-+ im_data4(v3)
-+ im_data5(v3)
-+ im_data6(v3)
-+ im_data7(v3)
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/aes/aes.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1415 @@
-+// I retain copyright in this code but I encourage its free use provided
-+// that I don't carry any responsibility for the results. I am especially
-+// happy to see it used in free and open source software. If you do use
-+// it I would appreciate an acknowledgement of its origin in the code or
-+// the product that results and I would also appreciate knowing a little
-+// about the use to which it is being put. I am grateful to Frank Yellin
-+// for some ideas that are used in this implementation.
-+//
-+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
-+//
-+// This is an implementation of the AES encryption algorithm (Rijndael)
-+// designed by Joan Daemen and Vincent Rijmen. This version is designed
-+// to provide both fixed and dynamic block and key lengths and can also
-+// run with either big or little endian internal byte order (see aes.h).
-+// It inputs block and key lengths in bytes with the legal values being
-+// 16, 24 and 32.
-+
-+/*
-+ * Modified by Jari Ruusu, May 1 2001
-+ * - Fixed some compile warnings, code was ok but gcc warned anyway.
-+ * - Changed basic types: byte -> unsigned char, word -> u_int32_t
-+ * - Major name space cleanup: Names visible to outside now begin
-+ * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
-+ * - Removed C++ and DLL support as part of name space cleanup.
-+ * - Eliminated unnecessary recomputation of tables. (actual bug fix)
-+ * - Merged precomputed constant tables to aes.c file.
-+ * - Removed data alignment restrictions for portability reasons.
-+ * - Made block and key lengths accept bit count (128/192/256)
-+ * as well byte count (16/24/32).
-+ * - Removed all error checks. This change also eliminated the need
-+ * to preinitialize the context struct to zero.
-+ * - Removed some totally unused constants.
-+ */
-+
-+#include "crypto/aes.h"
-+
-+// CONFIGURATION OPTIONS (see also aes.h)
-+//
-+// 1. Define UNROLL for full loop unrolling in encryption and decryption.
-+// 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption.
-+// 3. Define FIXED_TABLES for compiled rather than dynamic tables.
-+// 4. Define FF_TABLES to use tables for field multiplies and inverses.
-+// Do not enable this without understanding stack space requirements.
-+// 5. Define ARRAYS to use arrays to hold the local state block. If this
-+// is not defined, individually declared 32-bit words are used.
-+// 6. Define FAST_VARIABLE if a high speed variable block implementation
-+// is needed (essentially three separate fixed block size code sequences)
-+// 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven
-+// version using 1 table (2 kbytes of table space) or 4 tables (8
-+// kbytes of table space) for higher speed.
-+// 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed
-+// increase by using tables for the last rounds but with more table
-+// space (2 or 8 kbytes extra).
-+// 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but
-+// slower version is provided.
-+// 10. If fast decryption key scheduling is needed define ONE_IM_TABLE
-+// or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra).
-+
-+#define UNROLL
-+//#define PARTIAL_UNROLL
-+
-+#define FIXED_TABLES
-+//#define FF_TABLES
-+//#define ARRAYS
-+#define FAST_VARIABLE
-+
-+//#define ONE_TABLE
-+#define FOUR_TABLES
-+
-+//#define ONE_LR_TABLE
-+#define FOUR_LR_TABLES
-+
-+//#define ONE_IM_TABLE
-+#define FOUR_IM_TABLES
-+
-+#if defined(UNROLL) && defined (PARTIAL_UNROLL)
-+#error both UNROLL and PARTIAL_UNROLL are defined
-+#endif
-+
-+#if defined(ONE_TABLE) && defined (FOUR_TABLES)
-+#error both ONE_TABLE and FOUR_TABLES are defined
-+#endif
-+
-+#if defined(ONE_LR_TABLE) && defined (FOUR_LR_TABLES)
-+#error both ONE_LR_TABLE and FOUR_LR_TABLES are defined
-+#endif
-+
-+#if defined(ONE_IM_TABLE) && defined (FOUR_IM_TABLES)
-+#error both ONE_IM_TABLE and FOUR_IM_TABLES are defined
-+#endif
-+
-+#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32
-+#error an illegal block size has been specified
-+#endif
-+
-+// upr(x,n): rotates bytes within words by n positions, moving bytes
-+// to higher index positions with wrap around into low positions
-+// ups(x,n): moves bytes by n positions to higher index positions in
-+// words but without wrap around
-+// bval(x,n): extracts a byte from a word
-+
-+#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n))))
-+#define ups(x,n) ((x) << 8 * (n))
-+#define bval(x,n) ((unsigned char)((x) >> 8 * (n)))
-+#define bytes2word(b0, b1, b2, b3) \
-+ ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0))
-+
-+
-+/* little endian processor without data alignment restrictions: AES_LE_OK */
-+/* original code: i386 */
-+#if defined(i386) || defined(_I386) || defined(__i386__) || defined(__i386)
-+#define AES_LE_OK 1
-+/* added (tested): alpha --jjo */
-+#elif defined(__alpha__)|| defined (__alpha)
-+#define AES_LE_OK 1
-+/* added (tested): ia64 --jjo */
-+#elif defined(__ia64__)|| defined (__ia64)
-+#define AES_LE_OK 1
-+#endif
-+
-+#ifdef AES_LE_OK
-+/* little endian processor without data alignment restrictions */
-+#define word_in(x) *(u_int32_t*)(x)
-+#define const_word_in(x) *(const u_int32_t*)(x)
-+#define word_out(x,v) *(u_int32_t*)(x) = (v)
-+#define const_word_out(x,v) *(const u_int32_t*)(x) = (v)
-+#else
-+/* slower but generic big endian or with data alignment restrictions */
-+/* some additional "const" touches to stop "gcc -Wcast-qual" complains --jjo */
-+#define word_in(x) ((u_int32_t)(((unsigned char *)(x))[0])|((u_int32_t)(((unsigned char *)(x))[1])<<8)|((u_int32_t)(((unsigned char *)(x))[2])<<16)|((u_int32_t)(((unsigned char *)(x))[3])<<24))
-+#define const_word_in(x) ((const u_int32_t)(((const unsigned char *)(x))[0])|((const u_int32_t)(((const unsigned char *)(x))[1])<<8)|((const u_int32_t)(((const unsigned char *)(x))[2])<<16)|((const u_int32_t)(((const unsigned char *)(x))[3])<<24))
-+#define word_out(x,v) ((unsigned char *)(x))[0]=(v),((unsigned char *)(x))[1]=((v)>>8),((unsigned char *)(x))[2]=((v)>>16),((unsigned char *)(x))[3]=((v)>>24)
-+#define const_word_out(x,v) ((const unsigned char *)(x))[0]=(v),((const unsigned char *)(x))[1]=((v)>>8),((const unsigned char *)(x))[2]=((v)>>16),((const unsigned char *)(x))[3]=((v)>>24)
-+#endif
-+
-+// Disable at least some poor combinations of options
-+
-+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
-+#define FIXED_TABLES
-+#undef UNROLL
-+#undef ONE_LR_TABLE
-+#undef FOUR_LR_TABLES
-+#undef ONE_IM_TABLE
-+#undef FOUR_IM_TABLES
-+#elif !defined(FOUR_TABLES)
-+#ifdef FOUR_LR_TABLES
-+#undef FOUR_LR_TABLES
-+#define ONE_LR_TABLE
-+#endif
-+#ifdef FOUR_IM_TABLES
-+#undef FOUR_IM_TABLES
-+#define ONE_IM_TABLE
-+#endif
-+#elif !defined(AES_BLOCK_SIZE)
-+#if defined(UNROLL)
-+#define PARTIAL_UNROLL
-+#undef UNROLL
-+#endif
-+#endif
-+
-+// the finite field modular polynomial and elements
-+
-+#define ff_poly 0x011b
-+#define ff_hi 0x80
-+
-+// multiply four bytes in GF(2^8) by 'x' {02} in parallel
-+
-+#define m1 0x80808080
-+#define m2 0x7f7f7f7f
-+#define m3 0x0000001b
-+#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3))
-+
-+// The following defines provide alternative definitions of FFmulX that might
-+// give improved performance if a fast 32-bit multiply is not available. Note
-+// that a temporary variable u needs to be defined where FFmulX is used.
-+
-+// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
-+// #define m4 0x1b1b1b1b
-+// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
-+
-+// perform column mix operation on four bytes in parallel
-+
-+#define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1))
-+
-+#if defined(FIXED_TABLES)
-+
-+// the S-Box table
-+
-+static const unsigned char s_box[256] =
-+{
-+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
-+ 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
-+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
-+ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
-+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
-+ 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
-+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
-+ 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
-+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
-+ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
-+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
-+ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
-+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
-+ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
-+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
-+ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
-+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
-+ 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
-+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
-+ 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
-+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
-+ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
-+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
-+ 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
-+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
-+ 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
-+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
-+ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
-+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
-+ 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
-+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
-+ 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-+};
-+
-+// the inverse S-Box table
-+
-+static const unsigned char inv_s_box[256] =
-+{
-+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
-+ 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
-+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
-+ 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
-+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
-+ 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
-+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
-+ 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
-+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
-+ 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
-+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
-+ 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
-+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
-+ 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
-+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
-+ 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
-+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
-+ 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
-+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
-+ 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
-+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
-+ 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
-+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
-+ 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
-+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
-+ 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
-+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
-+ 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
-+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
-+ 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
-+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
-+ 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-+};
-+
-+#define w0(p) 0x000000##p
-+
-+// Number of elements required in this table for different
-+// block and key lengths is:
-+//
-+// Nk = 4 6 8
-+// ----------
-+// Nb = 4 | 10 8 7
-+// 6 | 19 12 11
-+// 8 | 29 19 14
-+//
-+// this table can be a table of bytes if the key schedule
-+// code is adjusted accordingly
-+
-+static const u_int32_t rcon_tab[29] =
-+{
-+ w0(01), w0(02), w0(04), w0(08),
-+ w0(10), w0(20), w0(40), w0(80),
-+ w0(1b), w0(36), w0(6c), w0(d8),
-+ w0(ab), w0(4d), w0(9a), w0(2f),
-+ w0(5e), w0(bc), w0(63), w0(c6),
-+ w0(97), w0(35), w0(6a), w0(d4),
-+ w0(b3), w0(7d), w0(fa), w0(ef),
-+ w0(c5)
-+};
-+
-+#undef w0
-+
-+#define r0(p,q,r,s) 0x##p##q##r##s
-+#define r1(p,q,r,s) 0x##q##r##s##p
-+#define r2(p,q,r,s) 0x##r##s##p##q
-+#define r3(p,q,r,s) 0x##s##p##q##r
-+#define w0(p) 0x000000##p
-+#define w1(p) 0x0000##p##00
-+#define w2(p) 0x00##p##0000
-+#define w3(p) 0x##p##000000
-+
-+#if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES))
-+
-+// data for forward tables (other than last round)
-+
-+#define f_table \
-+ r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\
-+ r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\
-+ r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56),\
-+ r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec),\
-+ r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa),\
-+ r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb),\
-+ r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45),\
-+ r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b),\
-+ r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c),\
-+ r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83),\
-+ r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9),\
-+ r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a),\
-+ r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d),\
-+ r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f),\
-+ r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df),\
-+ r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea),\
-+ r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34),\
-+ r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b),\
-+ r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d),\
-+ r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13),\
-+ r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1),\
-+ r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6),\
-+ r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72),\
-+ r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85),\
-+ r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed),\
-+ r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11),\
-+ r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe),\
-+ r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b),\
-+ r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05),\
-+ r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1),\
-+ r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42),\
-+ r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf),\
-+ r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3),\
-+ r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e),\
-+ r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a),\
-+ r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6),\
-+ r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3),\
-+ r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b),\
-+ r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28),\
-+ r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad),\
-+ r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14),\
-+ r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8),\
-+ r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4),\
-+ r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2),\
-+ r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da),\
-+ r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49),\
-+ r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf),\
-+ r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10),\
-+ r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c),\
-+ r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97),\
-+ r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e),\
-+ r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f),\
-+ r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc),\
-+ r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c),\
-+ r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69),\
-+ r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27),\
-+ r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22),\
-+ r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33),\
-+ r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9),\
-+ r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5),\
-+ r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a),\
-+ r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0),\
-+ r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\
-+ r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c)
-+
-+// data for inverse tables (other than last round)
-+
-+#define i_table \
-+ r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\
-+ r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\
-+ r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5),\
-+ r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5),\
-+ r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d),\
-+ r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b),\
-+ r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95),\
-+ r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e),\
-+ r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27),\
-+ r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d),\
-+ r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62),\
-+ r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9),\
-+ r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52),\
-+ r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66),\
-+ r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3),\
-+ r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed),\
-+ r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e),\
-+ r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4),\
-+ r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4),\
-+ r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd),\
-+ r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d),\
-+ r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60),\
-+ r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67),\
-+ r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79),\
-+ r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00),\
-+ r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c),\
-+ r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36),\
-+ r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24),\
-+ r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b),\
-+ r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c),\
-+ r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12),\
-+ r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14),\
-+ r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3),\
-+ r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b),\
-+ r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8),\
-+ r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84),\
-+ r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7),\
-+ r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77),\
-+ r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47),\
-+ r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22),\
-+ r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98),\
-+ r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f),\
-+ r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54),\
-+ r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82),\
-+ r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf),\
-+ r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db),\
-+ r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83),\
-+ r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef),\
-+ r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29),\
-+ r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35),\
-+ r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33),\
-+ r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17),\
-+ r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4),\
-+ r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46),\
-+ r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb),\
-+ r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d),\
-+ r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb),\
-+ r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a),\
-+ r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73),\
-+ r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78),\
-+ r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2),\
-+ r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff),\
-+ r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\
-+ r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0)
-+
-+// generate the required tables in the desired endian format
-+
-+#undef r
-+#define r r0
-+
-+#if defined(ONE_TABLE)
-+static const u_int32_t ft_tab[256] =
-+ { f_table };
-+#elif defined(FOUR_TABLES)
-+static const u_int32_t ft_tab[4][256] =
-+{ { f_table },
-+#undef r
-+#define r r1
-+ { f_table },
-+#undef r
-+#define r r2
-+ { f_table },
-+#undef r
-+#define r r3
-+ { f_table }
-+};
-+#endif
-+
-+#undef r
-+#define r r0
-+#if defined(ONE_TABLE)
-+static const u_int32_t it_tab[256] =
-+ { i_table };
-+#elif defined(FOUR_TABLES)
-+static const u_int32_t it_tab[4][256] =
-+{ { i_table },
-+#undef r
-+#define r r1
-+ { i_table },
-+#undef r
-+#define r r2
-+ { i_table },
-+#undef r
-+#define r r3
-+ { i_table }
-+};
-+#endif
-+
-+#endif
-+
-+#if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES))
-+
-+// data for inverse tables (last round)
-+
-+#define li_table \
-+ w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\
-+ w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\
-+ w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87),\
-+ w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb),\
-+ w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d),\
-+ w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e),\
-+ w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2),\
-+ w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25),\
-+ w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16),\
-+ w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92),\
-+ w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da),\
-+ w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84),\
-+ w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a),\
-+ w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06),\
-+ w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02),\
-+ w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b),\
-+ w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea),\
-+ w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73),\
-+ w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85),\
-+ w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e),\
-+ w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89),\
-+ w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b),\
-+ w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20),\
-+ w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4),\
-+ w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31),\
-+ w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f),\
-+ w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d),\
-+ w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef),\
-+ w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0),\
-+ w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61),\
-+ w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\
-+ w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d),
-+
-+// generate the required tables in the desired endian format
-+
-+#undef r
-+#define r(p,q,r,s) w0(q)
-+#if defined(ONE_LR_TABLE)
-+static const u_int32_t fl_tab[256] =
-+ { f_table };
-+#elif defined(FOUR_LR_TABLES)
-+static const u_int32_t fl_tab[4][256] =
-+{ { f_table },
-+#undef r
-+#define r(p,q,r,s) w1(q)
-+ { f_table },
-+#undef r
-+#define r(p,q,r,s) w2(q)
-+ { f_table },
-+#undef r
-+#define r(p,q,r,s) w3(q)
-+ { f_table }
-+};
-+#endif
-+
-+#undef w
-+#define w w0
-+#if defined(ONE_LR_TABLE)
-+static const u_int32_t il_tab[256] =
-+ { li_table };
-+#elif defined(FOUR_LR_TABLES)
-+static const u_int32_t il_tab[4][256] =
-+{ { li_table },
-+#undef w
-+#define w w1
-+ { li_table },
-+#undef w
-+#define w w2
-+ { li_table },
-+#undef w
-+#define w w3
-+ { li_table }
-+};
-+#endif
-+
-+#endif
-+
-+#if defined(FIXED_TABLES) && (defined(ONE_IM_TABLE) || defined(FOUR_IM_TABLES))
-+
-+#define m_table \
-+ r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12),\
-+ r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a),\
-+ r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62),\
-+ r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a),\
-+ r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2),\
-+ r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca),\
-+ r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82),\
-+ r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba),\
-+ r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9),\
-+ r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1),\
-+ r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9),\
-+ r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81),\
-+ r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29),\
-+ r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11),\
-+ r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59),\
-+ r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61),\
-+ r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf),\
-+ r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87),\
-+ r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf),\
-+ r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7),\
-+ r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f),\
-+ r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67),\
-+ r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f),\
-+ r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17),\
-+ r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64),\
-+ r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c),\
-+ r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14),\
-+ r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c),\
-+ r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84),\
-+ r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc),\
-+ r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4),\
-+ r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc),\
-+ r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53),\
-+ r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b),\
-+ r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23),\
-+ r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b),\
-+ r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3),\
-+ r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b),\
-+ r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3),\
-+ r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb),\
-+ r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88),\
-+ r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0),\
-+ r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8),\
-+ r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0),\
-+ r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68),\
-+ r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50),\
-+ r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18),\
-+ r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20),\
-+ r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe),\
-+ r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6),\
-+ r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e),\
-+ r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6),\
-+ r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e),\
-+ r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26),\
-+ r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e),\
-+ r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56),\
-+ r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25),\
-+ r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d),\
-+ r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55),\
-+ r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d),\
-+ r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5),\
-+ r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd),\
-+ r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5),\
-+ r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d)
-+
-+#undef r
-+#define r r0
-+
-+#if defined(ONE_IM_TABLE)
-+static const u_int32_t im_tab[256] =
-+ { m_table };
-+#elif defined(FOUR_IM_TABLES)
-+static const u_int32_t im_tab[4][256] =
-+{ { m_table },
-+#undef r
-+#define r r1
-+ { m_table },
-+#undef r
-+#define r r2
-+ { m_table },
-+#undef r
-+#define r r3
-+ { m_table }
-+};
-+#endif
-+
-+#endif
-+
-+#else
-+
-+static int tab_gen = 0;
-+
-+static unsigned char s_box[256]; // the S box
-+static unsigned char inv_s_box[256]; // the inverse S box
-+static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants
-+
-+#if defined(ONE_TABLE)
-+static u_int32_t ft_tab[256];
-+static u_int32_t it_tab[256];
-+#elif defined(FOUR_TABLES)
-+static u_int32_t ft_tab[4][256];
-+static u_int32_t it_tab[4][256];
-+#endif
-+
-+#if defined(ONE_LR_TABLE)
-+static u_int32_t fl_tab[256];
-+static u_int32_t il_tab[256];
-+#elif defined(FOUR_LR_TABLES)
-+static u_int32_t fl_tab[4][256];
-+static u_int32_t il_tab[4][256];
-+#endif
-+
-+#if defined(ONE_IM_TABLE)
-+static u_int32_t im_tab[256];
-+#elif defined(FOUR_IM_TABLES)
-+static u_int32_t im_tab[4][256];
-+#endif
-+
-+// Generate the tables for the dynamic table option
-+
-+#if !defined(FF_TABLES)
-+
-+// It will generally be sensible to use tables to compute finite
-+// field multiplies and inverses but where memory is scarse this
-+// code might sometimes be better.
-+
-+// return 2 ^ (n - 1) where n is the bit number of the highest bit
-+// set in x with x in the range 1 < x < 0x00000200. This form is
-+// used so that locals within FFinv can be bytes rather than words
-+
-+static unsigned char hibit(const u_int32_t x)
-+{ unsigned char r = (unsigned char)((x >> 1) | (x >> 2));
-+
-+ r |= (r >> 2);
-+ r |= (r >> 4);
-+ return (r + 1) >> 1;
-+}
-+
-+// return the inverse of the finite field element x
-+
-+static unsigned char FFinv(const unsigned char x)
-+{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
-+
-+ if(x < 2) return x;
-+
-+ for(;;)
-+ {
-+ if(!n1) return v1;
-+
-+ while(n2 >= n1)
-+ {
-+ n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
-+ }
-+
-+ if(!n2) return v2;
-+
-+ while(n1 >= n2)
-+ {
-+ n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
-+ }
-+ }
-+}
-+
-+// define the finite field multiplies required for Rijndael
-+
-+#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0))
-+#define FFmul03(x) ((x) ^ FFmul02(x))
-+#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x))))
-+#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x))))
-+#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x))))
-+#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x)))
-+
-+#else
-+
-+#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
-+
-+#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
-+#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
-+#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
-+#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
-+#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
-+#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
-+
-+#endif
-+
-+// The forward and inverse affine transformations used in the S-box
-+
-+#define fwd_affine(x) \
-+ (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8)))
-+
-+#define inv_affine(x) \
-+ (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8)))
-+
-+static void gen_tabs(void)
-+{ u_int32_t i, w;
-+
-+#if defined(FF_TABLES)
-+
-+ unsigned char pow[512], log[256];
-+
-+ // log and power tables for GF(2^8) finite field with
-+ // 0x011b as modular polynomial - the simplest primitive
-+ // root is 0x03, used here to generate the tables
-+
-+ i = 0; w = 1;
-+ do
-+ {
-+ pow[i] = (unsigned char)w;
-+ pow[i + 255] = (unsigned char)w;
-+ log[w] = (unsigned char)i++;
-+ w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
-+ }
-+ while (w != 1);
-+
-+#endif
-+
-+ for(i = 0, w = 1; i < AES_RC_LENGTH; ++i)
-+ {
-+ rcon_tab[i] = bytes2word(w, 0, 0, 0);
-+ w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
-+ }
-+
-+ for(i = 0; i < 256; ++i)
-+ { unsigned char b;
-+
-+ s_box[i] = b = fwd_affine(FFinv((unsigned char)i));
-+
-+ w = bytes2word(b, 0, 0, 0);
-+#if defined(ONE_LR_TABLE)
-+ fl_tab[i] = w;
-+#elif defined(FOUR_LR_TABLES)
-+ fl_tab[0][i] = w;
-+ fl_tab[1][i] = upr(w,1);
-+ fl_tab[2][i] = upr(w,2);
-+ fl_tab[3][i] = upr(w,3);
-+#endif
-+ w = bytes2word(FFmul02(b), b, b, FFmul03(b));
-+#if defined(ONE_TABLE)
-+ ft_tab[i] = w;
-+#elif defined(FOUR_TABLES)
-+ ft_tab[0][i] = w;
-+ ft_tab[1][i] = upr(w,1);
-+ ft_tab[2][i] = upr(w,2);
-+ ft_tab[3][i] = upr(w,3);
-+#endif
-+ inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i));
-+
-+ w = bytes2word(b, 0, 0, 0);
-+#if defined(ONE_LR_TABLE)
-+ il_tab[i] = w;
-+#elif defined(FOUR_LR_TABLES)
-+ il_tab[0][i] = w;
-+ il_tab[1][i] = upr(w,1);
-+ il_tab[2][i] = upr(w,2);
-+ il_tab[3][i] = upr(w,3);
-+#endif
-+ w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b));
-+#if defined(ONE_TABLE)
-+ it_tab[i] = w;
-+#elif defined(FOUR_TABLES)
-+ it_tab[0][i] = w;
-+ it_tab[1][i] = upr(w,1);
-+ it_tab[2][i] = upr(w,2);
-+ it_tab[3][i] = upr(w,3);
-+#endif
-+#if defined(ONE_IM_TABLE)
-+ im_tab[b] = w;
-+#elif defined(FOUR_IM_TABLES)
-+ im_tab[0][b] = w;
-+ im_tab[1][b] = upr(w,1);
-+ im_tab[2][b] = upr(w,2);
-+ im_tab[3][b] = upr(w,3);
-+#endif
-+
-+ }
-+}
-+
-+#endif
-+
-+#define no_table(x,box,vf,rf,c) bytes2word( \
-+ box[bval(vf(x,0,c),rf(0,c))], \
-+ box[bval(vf(x,1,c),rf(1,c))], \
-+ box[bval(vf(x,2,c),rf(2,c))], \
-+ box[bval(vf(x,3,c),rf(3,c))])
-+
-+#define one_table(x,op,tab,vf,rf,c) \
-+ ( tab[bval(vf(x,0,c),rf(0,c))] \
-+ ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
-+ ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
-+ ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
-+
-+#define four_tables(x,tab,vf,rf,c) \
-+ ( tab[0][bval(vf(x,0,c),rf(0,c))] \
-+ ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
-+ ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
-+ ^ tab[3][bval(vf(x,3,c),rf(3,c))])
-+
-+#define vf1(x,r,c) (x)
-+#define rf1(r,c) (r)
-+#define rf2(r,c) ((r-c)&3)
-+
-+#if defined(FOUR_LR_TABLES)
-+#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
-+#elif defined(ONE_LR_TABLE)
-+#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
-+#else
-+#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
-+#endif
-+
-+#if defined(FOUR_IM_TABLES)
-+#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
-+#elif defined(ONE_IM_TABLE)
-+#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
-+#else
-+#define inv_mcol(x) \
-+ (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
-+ f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
-+#endif
-+
-+// Subroutine to set the block size (if variable) in bytes, legal
-+// values being 16, 24 and 32.
-+
-+#if defined(AES_BLOCK_SIZE)
-+#define nc (AES_BLOCK_SIZE / 4)
-+#else
-+#define nc (cx->aes_Ncol)
-+
-+void aes_set_blk(aes_context *cx, int n_bytes)
-+{
-+#if !defined(FIXED_TABLES)
-+ if(!tab_gen) { gen_tabs(); tab_gen = 1; }
-+#endif
-+
-+ switch(n_bytes) {
-+ case 32: /* bytes */
-+ case 256: /* bits */
-+ nc = 8;
-+ break;
-+ case 24: /* bytes */
-+ case 192: /* bits */
-+ nc = 6;
-+ break;
-+ case 16: /* bytes */
-+ case 128: /* bits */
-+ default:
-+ nc = 4;
-+ break;
-+ }
-+}
-+
-+#endif
-+
-+// Initialise the key schedule from the user supplied key. The key
-+// length is now specified in bytes - 16, 24 or 32 as appropriate.
-+// This corresponds to bit lengths of 128, 192 and 256 bits, and
-+// to Nk values of 4, 6 and 8 respectively.
-+
-+#define mx(t,f) (*t++ = inv_mcol(*f),f++)
-+#define cp(t,f) *t++ = *f++
-+
-+#if AES_BLOCK_SIZE == 16
-+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s)
-+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s)
-+#elif AES_BLOCK_SIZE == 24
-+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
-+ cp(d,s); cp(d,s)
-+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
-+ mx(d,s); mx(d,s)
-+#elif AES_BLOCK_SIZE == 32
-+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
-+ cp(d,s); cp(d,s); cp(d,s); cp(d,s)
-+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
-+ mx(d,s); mx(d,s); mx(d,s); mx(d,s)
-+#else
-+
-+#define cpy(d,s) \
-+switch(nc) \
-+{ case 8: cp(d,s); cp(d,s); \
-+ case 6: cp(d,s); cp(d,s); \
-+ case 4: cp(d,s); cp(d,s); \
-+ cp(d,s); cp(d,s); \
-+}
-+
-+#define mix(d,s) \
-+switch(nc) \
-+{ case 8: mx(d,s); mx(d,s); \
-+ case 6: mx(d,s); mx(d,s); \
-+ case 4: mx(d,s); mx(d,s); \
-+ mx(d,s); mx(d,s); \
-+}
-+
-+#endif
-+
-+void aes_set_key(aes_context *cx, const unsigned char in_key[], int n_bytes, const int f)
-+{ u_int32_t *kf, *kt, rci;
-+
-+#if !defined(FIXED_TABLES)
-+ if(!tab_gen) { gen_tabs(); tab_gen = 1; }
-+#endif
-+
-+ switch(n_bytes) {
-+ case 32: /* bytes */
-+ case 256: /* bits */
-+ cx->aes_Nkey = 8;
-+ break;
-+ case 24: /* bytes */
-+ case 192: /* bits */
-+ cx->aes_Nkey = 6;
-+ break;
-+ case 16: /* bytes */
-+ case 128: /* bits */
-+ default:
-+ cx->aes_Nkey = 4;
-+ break;
-+ }
-+
-+ cx->aes_Nrnd = (cx->aes_Nkey > nc ? cx->aes_Nkey : nc) + 6;
-+
-+ cx->aes_e_key[0] = const_word_in(in_key );
-+ cx->aes_e_key[1] = const_word_in(in_key + 4);
-+ cx->aes_e_key[2] = const_word_in(in_key + 8);
-+ cx->aes_e_key[3] = const_word_in(in_key + 12);
-+
-+ kf = cx->aes_e_key;
-+ kt = kf + nc * (cx->aes_Nrnd + 1) - cx->aes_Nkey;
-+ rci = 0;
-+
-+ switch(cx->aes_Nkey)
-+ {
-+ case 4: do
-+ { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++];
-+ kf[5] = kf[1] ^ kf[4];
-+ kf[6] = kf[2] ^ kf[5];
-+ kf[7] = kf[3] ^ kf[6];
-+ kf += 4;
-+ }
-+ while(kf < kt);
-+ break;
-+
-+ case 6: cx->aes_e_key[4] = const_word_in(in_key + 16);
-+ cx->aes_e_key[5] = const_word_in(in_key + 20);
-+ do
-+ { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++];
-+ kf[ 7] = kf[1] ^ kf[ 6];
-+ kf[ 8] = kf[2] ^ kf[ 7];
-+ kf[ 9] = kf[3] ^ kf[ 8];
-+ kf[10] = kf[4] ^ kf[ 9];
-+ kf[11] = kf[5] ^ kf[10];
-+ kf += 6;
-+ }
-+ while(kf < kt);
-+ break;
-+
-+ case 8: cx->aes_e_key[4] = const_word_in(in_key + 16);
-+ cx->aes_e_key[5] = const_word_in(in_key + 20);
-+ cx->aes_e_key[6] = const_word_in(in_key + 24);
-+ cx->aes_e_key[7] = const_word_in(in_key + 28);
-+ do
-+ { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++];
-+ kf[ 9] = kf[1] ^ kf[ 8];
-+ kf[10] = kf[2] ^ kf[ 9];
-+ kf[11] = kf[3] ^ kf[10];
-+ kf[12] = kf[4] ^ ls_box(kf[11],0);
-+ kf[13] = kf[5] ^ kf[12];
-+ kf[14] = kf[6] ^ kf[13];
-+ kf[15] = kf[7] ^ kf[14];
-+ kf += 8;
-+ }
-+ while (kf < kt);
-+ break;
-+ }
-+
-+ if(!f)
-+ { u_int32_t i;
-+
-+ kt = cx->aes_d_key + nc * cx->aes_Nrnd;
-+ kf = cx->aes_e_key;
-+
-+ cpy(kt, kf); kt -= 2 * nc;
-+
-+ for(i = 1; i < cx->aes_Nrnd; ++i)
-+ {
-+#if defined(ONE_TABLE) || defined(FOUR_TABLES)
-+#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES)
-+ u_int32_t f2, f4, f8, f9;
-+#endif
-+ mix(kt, kf);
-+#else
-+ cpy(kt, kf);
-+#endif
-+ kt -= 2 * nc;
-+ }
-+
-+ cpy(kt, kf);
-+ }
-+}
-+
-+// y = output word, x = input word, r = row, c = column
-+// for r = 0, 1, 2 and 3 = column accessed for row r
-+
-+#if defined(ARRAYS)
-+#define s(x,c) x[c]
-+#else
-+#define s(x,c) x##c
-+#endif
-+
-+// I am grateful to Frank Yellin for the following constructions
-+// which, given the column (c) of the output state variable that
-+// is being computed, return the input state variables which are
-+// needed for each row (r) of the state
-+
-+// For the fixed block size options, compilers reduce these two
-+// expressions to fixed variable references. For variable block
-+// size code conditional clauses will sometimes be returned
-+
-+#define unused 77 // Sunset Strip
-+
-+#define fwd_var(x,r,c) \
-+ ( r==0 ? \
-+ ( c==0 ? s(x,0) \
-+ : c==1 ? s(x,1) \
-+ : c==2 ? s(x,2) \
-+ : c==3 ? s(x,3) \
-+ : c==4 ? s(x,4) \
-+ : c==5 ? s(x,5) \
-+ : c==6 ? s(x,6) \
-+ : s(x,7)) \
-+ : r==1 ? \
-+ ( c==0 ? s(x,1) \
-+ : c==1 ? s(x,2) \
-+ : c==2 ? s(x,3) \
-+ : c==3 ? nc==4 ? s(x,0) : s(x,4) \
-+ : c==4 ? s(x,5) \
-+ : c==5 ? nc==8 ? s(x,6) : s(x,0) \
-+ : c==6 ? s(x,7) \
-+ : s(x,0)) \
-+ : r==2 ? \
-+ ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
-+ : c==1 ? nc==8 ? s(x,4) : s(x,3) \
-+ : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
-+ : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
-+ : c==4 ? nc==8 ? s(x,7) : s(x,0) \
-+ : c==5 ? nc==8 ? s(x,0) : s(x,1) \
-+ : c==6 ? s(x,1) \
-+ : s(x,2)) \
-+ : \
-+ ( c==0 ? nc==8 ? s(x,4) : s(x,3) \
-+ : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
-+ : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
-+ : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \
-+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
-+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
-+ : c==6 ? s(x,2) \
-+ : s(x,3)))
-+
-+#define inv_var(x,r,c) \
-+ ( r==0 ? \
-+ ( c==0 ? s(x,0) \
-+ : c==1 ? s(x,1) \
-+ : c==2 ? s(x,2) \
-+ : c==3 ? s(x,3) \
-+ : c==4 ? s(x,4) \
-+ : c==5 ? s(x,5) \
-+ : c==6 ? s(x,6) \
-+ : s(x,7)) \
-+ : r==1 ? \
-+ ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \
-+ : c==1 ? s(x,0) \
-+ : c==2 ? s(x,1) \
-+ : c==3 ? s(x,2) \
-+ : c==4 ? s(x,3) \
-+ : c==5 ? s(x,4) \
-+ : c==6 ? s(x,5) \
-+ : s(x,6)) \
-+ : r==2 ? \
-+ ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
-+ : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
-+ : c==2 ? nc==8 ? s(x,7) : s(x,0) \
-+ : c==3 ? nc==8 ? s(x,0) : s(x,1) \
-+ : c==4 ? nc==8 ? s(x,1) : s(x,2) \
-+ : c==5 ? nc==8 ? s(x,2) : s(x,3) \
-+ : c==6 ? s(x,3) \
-+ : s(x,4)) \
-+ : \
-+ ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \
-+ : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
-+ : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
-+ : c==3 ? nc==8 ? s(x,7) : s(x,0) \
-+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
-+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
-+ : c==6 ? s(x,2) \
-+ : s(x,3)))
-+
-+#define si(y,x,k,c) s(y,c) = const_word_in(x + 4 * c) ^ k[c]
-+#define so(y,x,c) word_out(y + 4 * c, s(x,c))
-+
-+#if defined(FOUR_TABLES)
-+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
-+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
-+#elif defined(ONE_TABLE)
-+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
-+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
-+#else
-+#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
-+#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
-+#endif
-+
-+#if defined(FOUR_LR_TABLES)
-+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
-+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
-+#elif defined(ONE_LR_TABLE)
-+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
-+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
-+#else
-+#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
-+#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
-+#endif
-+
-+#if AES_BLOCK_SIZE == 16
-+
-+#if defined(ARRAYS)
-+#define locals(y,x) x[4],y[4]
-+#else
-+#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
-+// the following defines prevent the compiler requiring the declaration
-+// of generated but unused variables in the fwd_var and inv_var macros
-+#define b04 unused
-+#define b05 unused
-+#define b06 unused
-+#define b07 unused
-+#define b14 unused
-+#define b15 unused
-+#define b16 unused
-+#define b17 unused
-+#endif
-+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
-+ s(y,2) = s(x,2); s(y,3) = s(x,3);
-+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
-+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
-+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
-+
-+#elif AES_BLOCK_SIZE == 24
-+
-+#if defined(ARRAYS)
-+#define locals(y,x) x[6],y[6]
-+#else
-+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
-+ y##0,y##1,y##2,y##3,y##4,y##5
-+#define b06 unused
-+#define b07 unused
-+#define b16 unused
-+#define b17 unused
-+#endif
-+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
-+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
-+ s(y,4) = s(x,4); s(y,5) = s(x,5);
-+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
-+ si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
-+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
-+ so(y,x,3); so(y,x,4); so(y,x,5)
-+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
-+ rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
-+#else
-+
-+#if defined(ARRAYS)
-+#define locals(y,x) x[8],y[8]
-+#else
-+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
-+ y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
-+#endif
-+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
-+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
-+ s(y,4) = s(x,4); s(y,5) = s(x,5); \
-+ s(y,6) = s(x,6); s(y,7) = s(x,7);
-+
-+#if AES_BLOCK_SIZE == 32
-+
-+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
-+ si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
-+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
-+ so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
-+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
-+ rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
-+#else
-+
-+#define state_in(y,x,k) \
-+switch(nc) \
-+{ case 8: si(y,x,k,7); si(y,x,k,6); \
-+ case 6: si(y,x,k,5); si(y,x,k,4); \
-+ case 4: si(y,x,k,3); si(y,x,k,2); \
-+ si(y,x,k,1); si(y,x,k,0); \
-+}
-+
-+#define state_out(y,x) \
-+switch(nc) \
-+{ case 8: so(y,x,7); so(y,x,6); \
-+ case 6: so(y,x,5); so(y,x,4); \
-+ case 4: so(y,x,3); so(y,x,2); \
-+ so(y,x,1); so(y,x,0); \
-+}
-+
-+#if defined(FAST_VARIABLE)
-+
-+#define round(rm,y,x,k) \
-+switch(nc) \
-+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
-+ rm(y,x,k,5); rm(y,x,k,4); \
-+ rm(y,x,k,3); rm(y,x,k,2); \
-+ rm(y,x,k,1); rm(y,x,k,0); \
-+ break; \
-+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
-+ rm(y,x,k,3); rm(y,x,k,2); \
-+ rm(y,x,k,1); rm(y,x,k,0); \
-+ break; \
-+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
-+ rm(y,x,k,1); rm(y,x,k,0); \
-+ break; \
-+}
-+#else
-+
-+#define round(rm,y,x,k) \
-+switch(nc) \
-+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
-+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
-+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
-+ rm(y,x,k,1); rm(y,x,k,0); \
-+}
-+
-+#endif
-+
-+#endif
-+#endif
-+
-+void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
-+{ u_int32_t locals(b0, b1);
-+ const u_int32_t *kp = cx->aes_e_key;
-+
-+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
-+ u_int32_t f2;
-+#endif
-+
-+ state_in(b0, in_blk, kp); kp += nc;
-+
-+#if defined(UNROLL)
-+
-+ switch(cx->aes_Nrnd)
-+ {
-+ case 14: round(fwd_rnd, b1, b0, kp );
-+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
-+ case 12: round(fwd_rnd, b1, b0, kp );
-+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
-+ case 10: round(fwd_rnd, b1, b0, kp );
-+ round(fwd_rnd, b0, b1, kp + nc);
-+ round(fwd_rnd, b1, b0, kp + 2 * nc);
-+ round(fwd_rnd, b0, b1, kp + 3 * nc);
-+ round(fwd_rnd, b1, b0, kp + 4 * nc);
-+ round(fwd_rnd, b0, b1, kp + 5 * nc);
-+ round(fwd_rnd, b1, b0, kp + 6 * nc);
-+ round(fwd_rnd, b0, b1, kp + 7 * nc);
-+ round(fwd_rnd, b1, b0, kp + 8 * nc);
-+ round(fwd_lrnd, b0, b1, kp + 9 * nc);
-+ }
-+
-+#elif defined(PARTIAL_UNROLL)
-+ { u_int32_t rnd;
-+
-+ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
-+ {
-+ round(fwd_rnd, b1, b0, kp);
-+ round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc;
-+ }
-+
-+ round(fwd_rnd, b1, b0, kp);
-+ round(fwd_lrnd, b0, b1, kp + nc);
-+ }
-+#else
-+ { u_int32_t rnd;
-+
-+ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
-+ {
-+ round(fwd_rnd, b1, b0, kp);
-+ l_copy(b0, b1); kp += nc;
-+ }
-+
-+ round(fwd_lrnd, b0, b1, kp);
-+ }
-+#endif
-+
-+ state_out(out_blk, b0);
-+}
-+
-+void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
-+{ u_int32_t locals(b0, b1);
-+ const u_int32_t *kp = cx->aes_d_key;
-+
-+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
-+ u_int32_t f2, f4, f8, f9;
-+#endif
-+
-+ state_in(b0, in_blk, kp); kp += nc;
-+
-+#if defined(UNROLL)
-+
-+ switch(cx->aes_Nrnd)
-+ {
-+ case 14: round(inv_rnd, b1, b0, kp );
-+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
-+ case 12: round(inv_rnd, b1, b0, kp );
-+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
-+ case 10: round(inv_rnd, b1, b0, kp );
-+ round(inv_rnd, b0, b1, kp + nc);
-+ round(inv_rnd, b1, b0, kp + 2 * nc);
-+ round(inv_rnd, b0, b1, kp + 3 * nc);
-+ round(inv_rnd, b1, b0, kp + 4 * nc);
-+ round(inv_rnd, b0, b1, kp + 5 * nc);
-+ round(inv_rnd, b1, b0, kp + 6 * nc);
-+ round(inv_rnd, b0, b1, kp + 7 * nc);
-+ round(inv_rnd, b1, b0, kp + 8 * nc);
-+ round(inv_lrnd, b0, b1, kp + 9 * nc);
-+ }
-+
-+#elif defined(PARTIAL_UNROLL)
-+ { u_int32_t rnd;
-+
-+ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
-+ {
-+ round(inv_rnd, b1, b0, kp);
-+ round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc;
-+ }
-+
-+ round(inv_rnd, b1, b0, kp);
-+ round(inv_lrnd, b0, b1, kp + nc);
-+ }
-+#else
-+ { u_int32_t rnd;
-+
-+ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
-+ {
-+ round(inv_rnd, b1, b0, kp);
-+ l_copy(b0, b1); kp += nc;
-+ }
-+
-+ round(inv_lrnd, b0, b1, kp);
-+ }
-+#endif
-+
-+ state_out(out_blk, b0);
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/aes/aes_cbc.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,43 @@
-+/*
-+// I retain copyright in this code but I encourage its free use provided
-+// that I don't carry any responsibility for the results. I am especially
-+// happy to see it used in free and open source software. If you do use
-+// it I would appreciate an acknowledgement of its origin in the code or
-+// the product that results and I would also appreciate knowing a little
-+// about the use to which it is being put. I am grateful to Frank Yellin
-+// for some ideas that are used in this implementation.
-+//
-+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
-+//
-+// This is an implementation of the AES encryption algorithm (Rijndael)
-+// designed by Joan Daemen and Vincent Rijmen. This version is designed
-+// to provide both fixed and dynamic block and key lengths and can also
-+// run with either big or little endian internal byte order (see aes.h).
-+// It inputs block and key lengths in bytes with the legal values being
-+// 16, 24 and 32.
-+*
-+*/
-+
-+#ifdef __KERNEL__
-+#include <linux/types.h>
-+#else
-+#include <sys/types.h>
-+#endif
-+#include "crypto/aes_cbc.h"
-+#include "crypto/cbc_generic.h"
-+
-+/* returns bool success */
-+int AES_set_key(aes_context *aes_ctx, const u_int8_t *key, int keysize) {
-+ aes_set_key(aes_ctx, key, keysize, 0);
-+ return 1;
-+}
-+CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.1 2004/04/06 02:48:12 mcr
-+ * pullup of AES cipher from alg-branch.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/aes/aes_xcbc_mac.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,67 @@
-+#ifdef __KERNEL__
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#define DEBUG(x)
-+#else
-+#include <stdio.h>
-+#include <sys/types.h>
-+#define DEBUG(x) x
-+#endif
-+
-+#include "crypto/aes.h"
-+#include "crypto/aes_xcbc_mac.h"
-+
-+int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen)
-+{
-+ int ret=1;
-+ aes_block kn[3] = {
-+ { 0x01010101, 0x01010101, 0x01010101, 0x01010101 },
-+ { 0x02020202, 0x02020202, 0x02020202, 0x02020202 },
-+ { 0x03030303, 0x03030303, 0x03030303, 0x03030303 },
-+ };
-+ aes_set_key(&ctxm->ctx_k1, key, keylen, 0);
-+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[0], (u_int8_t *) kn[0]);
-+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[1], (u_int8_t *) ctxm->k2);
-+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[2], (u_int8_t *) ctxm->k3);
-+ aes_set_key(&ctxm->ctx_k1, (u_int8_t *) kn[0], 16, 0);
-+ return ret;
-+}
-+static void do_pad_xor(u_int8_t *out, const u_int8_t *in, int len) {
-+ int pos=0;
-+ for (pos=1; pos <= 16; pos++, in++, out++) {
-+ if (pos <= len)
-+ *out ^= *in;
-+ if (pos > len) {
-+ DEBUG(printf("put 0x80 at pos=%d\n", pos));
-+ *out ^= 0x80;
-+ break;
-+ }
-+ }
-+}
-+static void xor_block(aes_block res, const aes_block op) {
-+ res[0] ^= op[0];
-+ res[1] ^= op[1];
-+ res[2] ^= op[2];
-+ res[3] ^= op[3];
-+}
-+int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]) {
-+ int ret=ilen;
-+ u_int32_t out[4] = { 0, 0, 0, 0 };
-+ for (; ilen > 16 ; ilen-=16) {
-+ xor_block(out, (const u_int32_t*) &in[0]);
-+ aes_encrypt(&ctxm->ctx_k1, in, (u_int8_t *)&out[0]);
-+ in+=16;
-+ }
-+ do_pad_xor((u_int8_t *)&out, in, ilen);
-+ if (ilen==16) {
-+ DEBUG(printf("using k3\n"));
-+ xor_block(out, ctxm->k3);
-+ }
-+ else
-+ {
-+ DEBUG(printf("using k2\n"));
-+ xor_block(out, ctxm->k2);
-+ }
-+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *)out, hash);
-+ return ret;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/aes/test_main.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,41 @@
-+#include <stdio.h>
-+#include <string.h>
-+#include <sys/types.h>
-+#include "aes_cbc.h"
-+#define AES_BLOCK_SIZE 16
-+#define KEY_SIZE 128 /* bits */
-+#define KEY "1234567890123456"
-+#define STR "hola guaso como estaisss ... 012"
-+#define STRSZ (sizeof(STR)-1)
-+
-+#define EMT_AESCBC_BLKLEN AES_BLOCK_SIZE
-+#define AES_CONTEXT_T aes_context
-+#define EMT_ESPAES_KEY_SZ 16
-+int pretty_print(const unsigned char *buf, int count) {
-+ int i=0;
-+ for (;i<count;i++) {
-+ if (i%8==0) putchar(' ');
-+ if (i%16==0) putchar('\n');
-+ printf ("%02hhx ", buf[i]);
-+ }
-+ putchar('\n');
-+ return i;
-+}
-+//#define SIZE STRSZ/2
-+#define SIZE STRSZ
-+int main() {
-+ int ret;
-+ char buf0[SIZE+1], buf1[SIZE+1];
-+ char IV[AES_BLOCK_SIZE]="\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0";
-+ aes_context ac;
-+ AES_set_key(&ac, KEY, KEY_SIZE);
-+ //pretty_print((char *)&ac.aes_e_key, sizeof(ac.aes_e_key));
-+ memset(buf0, 0, sizeof (buf0));
-+ memset(buf1, 0, sizeof (buf1));
-+ ret=AES_cbc_encrypt(&ac, STR, buf0, SIZE, IV, 1);
-+ pretty_print(buf0, SIZE);
-+ printf("size=%d ret=%d\n%s\n", SIZE, ret, buf0);
-+ ret=AES_cbc_encrypt(&ac, buf0, buf1, SIZE, IV, 0);
-+ printf("size=%d ret=%d\n%s\n", SIZE, ret, buf1);
-+ return 0;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/aes/test_main_mac.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,30 @@
-+#include <stdio.h>
-+#include <sys/types.h>
-+#include <string.h>
-+#include "aes.h"
-+#include "aes_xcbc_mac.h"
-+#define STR "Hola guasssso c|mo estais ...012"
-+void print_hash(const __u8 *hash) {
-+ printf("%08x %08x %08x %08x\n",
-+ *(__u32*)(&hash[0]),
-+ *(__u32*)(&hash[4]),
-+ *(__u32*)(&hash[8]),
-+ *(__u32*)(&hash[12]));
-+}
-+int main(int argc, char *argv[]) {
-+ aes_block key= { 0xdeadbeef, 0xceedcaca, 0xcafebabe, 0xff010204 };
-+ __u8 hash[16];
-+ char *str = argv[1];
-+ aes_context_mac ctx;
-+ if (str==NULL) {
-+ fprintf(stderr, "pasame el str\n");
-+ return 255;
-+ }
-+ AES_xcbc_mac_set_key(&ctx, (__u8 *)&key, sizeof(key));
-+ AES_xcbc_mac_hash(&ctx, str, strlen(str), hash);
-+ print_hash(hash);
-+ str[2]='x';
-+ AES_xcbc_mac_hash(&ctx, str, strlen(str), hash);
-+ print_hash(hash);
-+ return 0;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/COPYRIGHT Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,50 @@
-+Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+All rights reserved.
-+
-+This package is an DES implementation written by Eric Young (eay@cryptsoft.com).
-+The implementation was written so as to conform with MIT's libdes.
-+
-+This library is free for commercial and non-commercial use as long as
-+the following conditions are aheared to. The following conditions
-+apply to all code found in this distribution.
-+
-+Copyright remains Eric Young's, and as such any Copyright notices in
-+the code are not to be removed.
-+If this package is used in a product, Eric Young should be given attribution
-+as the author of that the SSL library. This can be in the form of a textual
-+message at program startup or in documentation (online or textual) provided
-+with the package.
-+
-+Redistribution and use in source and binary forms, with or without
-+modification, are permitted provided that the following conditions
-+are met:
-+1. Redistributions of source code must retain the copyright
-+ notice, this list of conditions and the following disclaimer.
-+2. Redistributions in binary form must reproduce the above copyright
-+ notice, this list of conditions and the following disclaimer in the
-+ documentation and/or other materials provided with the distribution.
-+3. All advertising materials mentioning features or use of this software
-+ must display the following acknowledgement:
-+ This product includes software developed by Eric Young (eay@cryptsoft.com)
-+
-+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+SUCH DAMAGE.
-+
-+The license and distribution terms for any publically available version or
-+derivative of this code cannot be changed. i.e. this code cannot simply be
-+copied and put under another distrubution license
-+[including the GNU Public License.]
-+
-+The reason behind this being stated in this direct manner is past
-+experience in code simply being copied and the attribution removed
-+from it and then being distributed as part of other packages. This
-+implementation was a non-trivial and unpaid effort.
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/INSTALL Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,69 @@
-+Check the CC and CFLAGS lines in the makefile
-+
-+If your C library does not support the times(3) function, change the
-+#define TIMES to
-+#undef TIMES in speed.c
-+If it does, check the HZ value for the times(3) function.
-+If your system does not define CLK_TCK it will be assumed to
-+be 100.0.
-+
-+If possible use gcc v 2.7.?
-+Turn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc)
-+In recent times, some system compilers give better performace.
-+
-+type 'make'
-+
-+run './destest' to check things are ok.
-+run './rpw' to check the tty code for reading passwords works.
-+run './speed' to see how fast those optimisations make the library run :-)
-+run './des_opts' to determin the best compile time options.
-+
-+The output from des_opts should be put in the makefile options and des_enc.c
-+should be rebuilt. For 64 bit computers, do not use the DES_PTR option.
-+For the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int'
-+and then you can use the 'DES_PTR' option.
-+
-+The file options.txt has the options listed for best speed on quite a
-+few systems. Look and the options (UNROLL, PTR, RISC2 etc) and then
-+turn on the relevent option in the Makefile
-+
-+There are some special Makefile targets that make life easier.
-+make cc - standard cc build
-+make gcc - standard gcc build
-+make x86-elf - x86 assembler (elf), linux-elf.
-+make x86-out - x86 assembler (a.out), FreeBSD
-+make x86-solaris- x86 assembler
-+make x86-bsdi - x86 assembler (a.out with primative assembler).
-+
-+If at all possible use the assembler (for Windows NT/95, use
-+asm/win32.obj to link with). The x86 assembler is very very fast.
-+
-+A make install will by default install
-+libdes.a in /usr/local/lib/libdes.a
-+des in /usr/local/bin/des
-+des_crypt.man in /usr/local/man/man3/des_crypt.3
-+des.man in /usr/local/man/man1/des.1
-+des.h in /usr/include/des.h
-+
-+des(1) should be compatible with sunOS's but I have been unable to
-+test it.
-+
-+These routines should compile on MSDOS, most 32bit and 64bit version
-+of Unix (BSD and SYSV) and VMS, without modification.
-+The only problems should be #include files that are in the wrong places.
-+
-+These routines can be compiled under MSDOS.
-+I have successfully encrypted files using des(1) under MSDOS and then
-+decrypted the files on a SparcStation.
-+I have been able to compile and test the routines with
-+Microsoft C v 5.1 and Turbo C v 2.0.
-+The code in this library is in no way optimised for the 16bit
-+operation of MSDOS.
-+
-+When building for glibc, ignore all of the above and just unpack into
-+glibc-1.??/des and then gmake as per normal.
-+
-+As a final note on performace. Certain CPUs like sparcs and Alpha often give
-+a %10 speed difference depending on the link order. It is rather anoying
-+when one program reports 'x' DES encrypts a second and another reports
-+'x*0.9' the speed.
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/Makefile.objs Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,20 @@
-+obj-$(CONFIG_IPSEC_ENC_3DES) += cbc_enc.o
-+#obj-$(CONFIG_IPSEC_ENC_3DES) += des_opts.o
-+obj-$(CONFIG_IPSEC_ENC_3DES) += ecb_enc.o
-+#obj-$(CONFIG_IPSEC_ENC_3DES) += fcrypt.o
-+obj-$(CONFIG_IPSEC_ENC_3DES) += set_key.o
-+
-+ifeq ($(strip ${SUBARCH}),)
-+SUBARCH:=${ARCH}
-+endif
-+
-+ifeq (${SUBARCH},i386)
-+obj-$(CONFIG_IPSEC_ENC_3DES) += dx86unix.o
-+else
-+obj-$(CONFIG_IPSEC_ENC_3DES) += des_enc.o
-+endif
-+
-+
-+
-+
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/README Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,54 @@
-+
-+ libdes, Version 4.01 10-Jan-97
-+
-+ Copyright (c) 1997, Eric Young
-+ All rights reserved.
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms specified in COPYRIGHT.
-+
-+--
-+The primary ftp site for this library is
-+ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz
-+libdes is now also shipped with SSLeay. Primary ftp site of
-+ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz
-+
-+The best way to build this library is to build it as part of SSLeay.
-+
-+This kit builds a DES encryption library and a DES encryption program.
-+It supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb,
-+triple cfb, desx, and MIT's pcbc encryption modes and also has a fast
-+implementation of crypt(3).
-+It contains support routines to read keys from a terminal,
-+generate a random key, generate a key from an arbitrary length string,
-+read/write encrypted data from/to a file descriptor.
-+
-+The implementation was written so as to conform with the manual entry
-+for the des_crypt(3) library routines from MIT's project Athena.
-+
-+destest should be run after compilation to test the des routines.
-+rpw should be run after compilation to test the read password routines.
-+The des program is a replacement for the sun des command. I believe it
-+conforms to the sun version.
-+
-+The Imakefile is setup for use in the kerberos distribution.
-+
-+These routines are best compiled with gcc or any other good
-+optimising compiler.
-+Just turn you optimiser up to the highest settings and run destest
-+after the build to make sure everything works.
-+
-+I believe these routines are close to the fastest and most portable DES
-+routines that use small lookup tables (4.5k) that are publicly available.
-+The fcrypt routine is faster than ufc's fcrypt (when compiling with
-+gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines
-+(on a sun3/260 168 vs 336). It is a function of CPU on chip cache size.
-+[ 10-Jan-97 and a function of an incorrect speed testing program in
-+ ufc which gave much better test figures that reality ].
-+
-+It is worth noting that on sparc and Alpha CPUs, performance of the DES
-+library can vary by upto %10 due to the positioning of files after application
-+linkage.
-+
-+Eric Young (eay@cryptsoft.com)
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/README.freeswan Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,33 @@
-+The only changes the FreeS/WAN project has made to libdes-lite 4.04b are:
-+
-+We #ifdef-ed the declaration of DES_LONG in des.h, so it's more efficient
-+on the Alpha, instead of just noting the issue in a comment.
-+
-+We #ifdef-ed out the des_options() function in ecb_enc.c, because we don't
-+use it, and its call to sprintf() can cause subtle difficulties when KLIPS
-+is built as a module (depending on details of Linux configuration options).
-+
-+We changed some instances of CC=$(CC) in the Makefile to CC='$(CC)' to make
-+it cope better with Linux kernel Makefile stupidities, and took out an
-+explicit CC=gcc (unwise on systems with strange compilers).
-+
-+We deleted some references to <stdio.h> and <stdlib.h>, and a declaration
-+of one function found only in the full libdes (not in libdes-lite), to
-+avoid dragging in bits of stdio/stdlib unnecessarily. (Our thanks to Hans
-+Schultz for spotting this and pointing out the fixes.)
-+
-+We deleted a couple of .obj files in the asm subdirectory, which appear to
-+have been included in the original library by accident.
-+
-+We have added an include of our Makefile.inc file, to permit overriding
-+things like choice of compiler (although the libdes Makefile would
-+probably need some work to make this effective).
-+
-+
-+
-+Note that Eric Young is no longer at the email address listed in these
-+files, and is (alas) no longer working on free crypto software.
-+
-+
-+
-+This file is RCSID $Id$
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/VERSION Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,406 @@
-+Version 4.04
-+ Fixed a few tests in destest. Also added x86 assember for
-+ des_ncbc_encrypt() which is the standard cbc mode function.
-+ This makes a very very large performace difference.
-+ Ariel Glenn ariel@columbia.edu reports that the terminal
-+ 'turn echo off' can return (errno == EINVAL) under solaris
-+ when redirection is used. So I now catch that as well as ENOTTY.
-+
-+
-+Version 4.03
-+ Left a static out of enc_write.c, which caused to buffer to be
-+ continiously malloc()ed. Does anyone use these functions? I keep
-+ on feeling like removing them since I only had these in there
-+ for a version of kerberised login. Anyway, this was pointed out
-+ by Theo de Raadt <deraadt@cvs.openbsd.org>
-+ The 'n' bit ofb code was wrong, it was not shifting the shift
-+ register. It worked correctly for n == 64. Thanks to
-+ Gigi Ankeny <Gigi.Ankeny@Eng.Sun.COM> for pointing this one out.
-+
-+Version 4.02
-+ I was doing 'if (memcmp(weak_keys[i],key,sizeof(key)) == 0)'
-+ when checking for weak keys which is wrong :-(, pointed out by
-+ Markus F.X.J. Oberhumer <markus.oberhumer@jk.uni-linz.ac.at>.
-+
-+Version 4.01
-+ Even faster inner loop in the DES assembler for x86 and a modification
-+ for IP/FP which is faster on x86. Both of these changes are
-+ from Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>. His
-+ changes make the assembler run %40 faster on a pentium. This is just
-+ a case of getting the instruction sequence 'just right'.
-+ All credit to 'Svend' :-)
-+ Quite a few special x86 'make' targets.
-+ A libdes-l (lite) distribution.
-+
-+Version 4.00
-+ After a bit of a pause, I'll up the major version number since this
-+ is mostly a performace release. I've added x86 assembler and
-+ added more options for performance. A %28 speedup for gcc
-+ on a pentium and the assembler is a %50 speedup.
-+ MIPS CPU's, sparc and Alpha are the main CPU's with speedups.
-+ Run des_opts to work out which options should be used.
-+ DES_RISC1/DES_RISC2 use alternative inner loops which use
-+ more registers but should give speedups on any CPU that does
-+ dual issue (pentium). DES_UNROLL unrolls the inner loop,
-+ which costs in code size.
-+
-+Version 3.26
-+ I've finally removed one of the shifts in D_ENCRYPT. This
-+ meant I've changed the des_SPtrans table (spr.h), the set_key()
-+ function and some things in des_enc.c. This has definitly
-+ made things faster :-). I've known about this one for some
-+ time but I've been too lazy to follow it up :-).
-+ Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^..
-+ instead of L^=((..)|(..)|(..).. This should save a register at
-+ least.
-+ Assember for x86. The file to replace is des_enc.c, which is replaced
-+ by one of the assembler files found in asm. Look at des/asm/readme
-+ for more info.
-+
-+ /* Modification to fcrypt so it can be compiled to support
-+ HPUX 10.x's long password format, define -DLONGCRYPT to use this.
-+ Thanks to Jens Kupferschmidt <bt1cu@hpboot.rz.uni-leipzig.de>. */
-+
-+ SIGWINCH case put in des_read_passwd() so the function does not
-+ 'exit' if this function is recieved.
-+
-+Version 3.25 17/07/96
-+ Modified read_pwd.c so that stdin can be read if not a tty.
-+ Thanks to Jeff Barber <jeffb@issl.atl.hp.com> for the patches.
-+ des_init_random_number_generator() shortened due to VMS linker
-+ limits.
-+ Added RSA's DESX cbc mode. It is a form of cbc encryption, with 2
-+ 8 byte quantites xored before and after encryption.
-+ des_xcbc_encryption() - the name is funny to preserve the des_
-+ prefix on all functions.
-+
-+Version 3.24 20/04/96
-+ The DES_PTR macro option checked and used by SSLeay configuration
-+
-+Version 3.23 11/04/96
-+ Added DES_LONG. If defined to 'unsigned int' on the DEC Alpha,
-+ it gives a %20 speedup :-)
-+ Fixed the problem with des.pl under perl5. The patches were
-+ sent by Ed Kubaitis (ejk@uiuc.edu).
-+ if fcrypt.c, changed values to handle illegal salt values the way
-+ normal crypt() implementations do. Some programs apparently use
-+ them :-(. The patch was sent by Bjorn Gronvall <bg@sics.se>
-+
-+Version 3.22 29/11/95
-+ Bug in des(1), an error with the uuencoding stuff when the
-+ 'data' is small, thanks to Geoff Keating <keagchon@mehta.anu.edu.au>
-+ for the patch.
-+
-+Version 3.21 22/11/95
-+ After some emailing back and forth with
-+ Colin Plumb <colin@nyx10.cs.du.edu>, I've tweaked a few things
-+ and in a future version I will probably put in some of the
-+ optimisation he suggested for use with the DES_USE_PTR option.
-+ Extra routines from Mark Murray <mark@grondar.za> for use in
-+ freeBSD. They mostly involve random number generation for use
-+ with kerberos. They involve evil machine specific system calls
-+ etc so I would normally suggest pushing this stuff into the
-+ application and/or using RAND_seed()/RAND_bytes() if you are
-+ using this DES library as part of SSLeay.
-+ Redone the read_pw() function so that it is cleaner and
-+ supports termios, thanks to Sameer Parekh <sameer@c2.org>
-+ for the initial patches for this.
-+ Renamed 3ecb_encrypt() to ecb3_encrypt(). This has been
-+ done just to make things more consistent.
-+ I have also now added triple DES versions of cfb and ofb.
-+
-+Version 3.20
-+ Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com,
-+ my des_random_seed() function was only copying 4 bytes of the
-+ passed seed into the init structure. It is now fixed to copy 8.
-+ My own suggestion is to used something like MD5 :-)
-+
-+Version 3.19
-+ While looking at my code one day, I though, why do I keep on
-+ calling des_encrypt(in,out,ks,enc) when every function that
-+ calls it has in and out the same. So I dropped the 'out'
-+ parameter, people should not be using this function.
-+
-+Version 3.18 30/08/95
-+ Fixed a few bit with the distribution and the filenames.
-+ 3.17 had been munged via a move to DOS and back again.
-+ NO CODE CHANGES
-+
-+Version 3.17 14/07/95
-+ Fixed ede3 cbc which I had broken in 3.16. I have also
-+ removed some unneeded variables in 7-8 of the routines.
-+
-+Version 3.16 26/06/95
-+ Added des_encrypt2() which does not use IP/FP, used by triple
-+ des routines. Tweaked things a bit elsewhere. %13 speedup on
-+ sparc and %6 on a R4400 for ede3 cbc mode.
-+
-+Version 3.15 06/06/95
-+ Added des_ncbc_encrypt(), it is des_cbc mode except that it is
-+ 'normal' and copies the new iv value back over the top of the
-+ passed parameter.
-+ CHANGED des_ede3_cbc_encrypt() so that it too now overwrites
-+ the iv. THIS WILL BREAK EXISTING CODE, but since this function
-+ only new, I feel I can change it, not so with des_cbc_encrypt :-(.
-+ I need to update the documentation.
-+
-+Version 3.14 31/05/95
-+ New release upon the world, as part of my SSL implementation.
-+ New copyright and usage stuff. Basically free for all to use
-+ as long as you say it came from me :-)
-+
-+Version 3.13 31/05/95
-+ A fix in speed.c, if HZ is not defined, I set it to 100.0
-+ which is reasonable for most unixes except SunOS 4.x.
-+ I now have a #ifdef sun but timing for SunOS 4.x looked very
-+ good :-(. At my last job where I used SunOS 4.x, it was
-+ defined to be 60.0 (look at the old INSTALL documentation), at
-+ the last release had it changed to 100.0 since I now work with
-+ Solaris2 and SVR4 boxes.
-+ Thanks to Rory Chisholm <rchishol@math.ethz.ch> for pointing this
-+ one out.
-+
-+Version 3.12 08/05/95
-+ As pointed out by The Crypt Keeper <tck@bend.UCSD.EDU>,
-+ my D_ENCRYPT macro in crypt() had an un-necessary variable.
-+ It has been removed.
-+
-+Version 3.11 03/05/95
-+ Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys
-+ and one iv. It is a standard and I needed it for my SSL code.
-+ It makes more sense to use this for triple DES than
-+ 3cbc_encrypt(). I have also added (or should I say tested :-)
-+ cfb64_encrypt() which is cfb64 but it will encrypt a partial
-+ number of bytes - 3 bytes in 3 bytes out. Again this is for
-+ my SSL library, as a form of encryption to use with SSL
-+ telnet.
-+
-+Version 3.10 22/03/95
-+ Fixed a bug in 3cbc_encrypt() :-(. When making repeated calls
-+ to cbc3_encrypt, the 2 iv values that were being returned to
-+ be used in the next call were reversed :-(.
-+ Many thanks to Bill Wade <wade@Stoner.COM> for pointing out
-+ this error.
-+
-+Version 3.09 01/02/95
-+ Fixed des_random_key to far more random, it was rather feeble
-+ with regards to picking the initial seed. The problem was
-+ pointed out by Olaf Kirch <okir@monad.swb.de>.
-+
-+Version 3.08 14/12/94
-+ Added Makefile.PL so libdes can be built into perl5.
-+ Changed des_locl.h so RAND is always defined.
-+
-+Version 3.07 05/12/94
-+ Added GNUmake and stuff so the library can be build with
-+ glibc.
-+
-+Version 3.06 30/08/94
-+ Added rpc_enc.c which contains _des_crypt. This is for use in
-+ secure_rpc v 4.0
-+ Finally fixed the cfb_enc problems.
-+ Fixed a few parameter parsing bugs in des (-3 and -b), thanks
-+ to Rob McMillan <R.McMillan@its.gu.edu.au>
-+
-+Version 3.05 21/04/94
-+ for unsigned long l; gcc does not produce ((l>>34) == 0)
-+ This causes bugs in cfb_enc.
-+ Thanks to Hadmut Danisch <danisch@ira.uka.de>
-+
-+Version 3.04 20/04/94
-+ Added a version number to des.c and libdes.a
-+
-+Version 3.03 12/01/94
-+ Fixed a bug in non zero iv in 3cbc_enc.
-+
-+Version 3.02 29/10/93
-+ I now work in a place where there are 6+ architectures and 14+
-+ OS versions :-).
-+ Fixed TERMIO definition so the most sys V boxes will work :-)
-+
-+Release upon comp.sources.misc
-+Version 3.01 08/10/93
-+ Added des_3cbc_encrypt()
-+
-+Version 3.00 07/10/93
-+ Fixed up documentation.
-+ quad_cksum definitely compatible with MIT's now.
-+
-+Version 2.30 24/08/93
-+ Triple DES now defaults to triple cbc but can do triple ecb
-+ with the -b flag.
-+ Fixed some MSDOS uuen/uudecoding problems, thanks to
-+ Added prototypes.
-+
-+Version 2.22 29/06/93
-+ Fixed a bug in des_is_weak_key() which stopped it working :-(
-+ thanks to engineering@MorningStar.Com.
-+
-+Version 2.21 03/06/93
-+ des(1) with no arguments gives quite a bit of help.
-+ Added -c (generate ckecksum) flag to des(1).
-+ Added -3 (triple DES) flag to des(1).
-+ Added cfb and ofb routines to the library.
-+
-+Version 2.20 11/03/93
-+ Added -u (uuencode) flag to des(1).
-+ I have been playing with byte order in quad_cksum to make it
-+ compatible with MIT's version. All I can say is avid this
-+ function if possible since MIT's output is endian dependent.
-+
-+Version 2.12 14/10/92
-+ Added MSDOS specific macro in ecb_encrypt which gives a %70
-+ speed up when the code is compiled with turbo C.
-+
-+Version 2.11 12/10/92
-+ Speedup in set_key (recoding of PC-1)
-+ I now do it in 47 simple operations, down from 60.
-+ Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
-+ for motivating me to look for a faster system :-)
-+ The speedup is probably less that 1% but it is still 13
-+ instructions less :-).
-+
-+Version 2.10 06/10/92
-+ The code now works on the 64bit ETA10 and CRAY without modifications or
-+ #defines. I believe the code should work on any machine that
-+ defines long, int or short to be 8 bytes long.
-+ Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu)
-+ for helping me fix the code to run on 64bit machines (he had
-+ access to an ETA10).
-+ Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov>
-+ for testing the routines on a CRAY.
-+ read_password.c has been renamed to read_passwd.c
-+ string_to_key.c has been renamed to string2key.c
-+
-+Version 2.00 14/09/92
-+ Made mods so that the library should work on 64bit CPU's.
-+ Removed all my uchar and ulong defs. To many different
-+ versions of unix define them in their header files in too many
-+ different combinations :-)
-+ IRIX - Sillicon Graphics mods (mostly in read_password.c).
-+ Thanks to Andrew Daviel (advax@erich.triumf.ca)
-+
-+Version 1.99 26/08/92
-+ Fixed a bug or 2 in enc_read.c
-+ Fixed a bug in enc_write.c
-+ Fixed a pseudo bug in fcrypt.c (very obscure).
-+
-+Version 1.98 31/07/92
-+ Support for the ETA10. This is a strange machine that defines
-+ longs and ints as 8 bytes and shorts as 4 bytes.
-+ Since I do evil things with long * that assume that they are 4
-+ bytes. Look in the Makefile for the option to compile for
-+ this machine. quad_cksum appears to have problems but I
-+ will don't have the time to fix it right now, and this is not
-+ a function that uses DES and so will not effect the main uses
-+ of the library.
-+
-+Version 1.97 20/05/92 eay
-+ Fixed the Imakefile and made some changes to des.h to fix some
-+ problems when building this package with Kerberos v 4.
-+
-+Version 1.96 18/05/92 eay
-+ Fixed a small bug in string_to_key() where problems could
-+ occur if des_check_key was set to true and the string
-+ generated a weak key.
-+
-+Patch2 posted to comp.sources.misc
-+Version 1.95 13/05/92 eay
-+ Added an alternative version of the D_ENCRYPT macro in
-+ ecb_encrypt and fcrypt. Depending on the compiler, one version or the
-+ other will be faster. This was inspired by
-+ Dana How <how@isl.stanford.edu>, and her pointers about doing the
-+ *(ulong *)((uchar *)ptr+(value&0xfc))
-+ vs
-+ ptr[value&0x3f]
-+ to stop the C compiler doing a <<2 to convert the long array index.
-+
-+Version 1.94 05/05/92 eay
-+ Fixed an incompatibility between my string_to_key and the MIT
-+ version. When the key is longer than 8 chars, I was wrapping
-+ with a different method. To use the old version, define
-+ OLD_STR_TO_KEY in the makefile. Thanks to
-+ viktor@newsu.shearson.com (Viktor Dukhovni).
-+
-+Version 1.93 28/04/92 eay
-+ Fixed the VMS mods so that echo is now turned off in
-+ read_password. Thanks again to brennan@coco.cchs.su.oz.AU.
-+ MSDOS support added. The routines can be compiled with
-+ Turbo C (v2.0) and MSC (v5.1). Make sure MSDOS is defined.
-+
-+Patch1 posted to comp.sources.misc
-+Version 1.92 13/04/92 eay
-+ Changed D_ENCRYPT so that the rotation of R occurs outside of
-+ the loop. This required rotating all the longs in sp.h (now
-+ called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
-+ speed.c has been changed so it will work without SIGALRM. If
-+ times(3) is not present it will try to use ftime() instead.
-+
-+Version 1.91 08/04/92 eay
-+ Added -E/-D options to des(1) so it can use string_to_key.
-+ Added SVR4 mods suggested by witr@rwwa.COM
-+ Added VMS mods suggested by brennan@coco.cchs.su.oz.AU. If
-+ anyone knows how to turn of tty echo in VMS please tell me or
-+ implement it yourself :-).
-+ Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS
-+ does not like IN/OUT being used.
-+
-+Libdes posted to comp.sources.misc
-+Version 1.9 24/03/92 eay
-+ Now contains a fast small crypt replacement.
-+ Added des(1) command.
-+ Added des_rw_mode so people can use cbc encryption with
-+ enc_read and enc_write.
-+
-+Version 1.8 15/10/91 eay
-+ Bug in cbc_cksum.
-+ Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this
-+ one out.
-+
-+Version 1.7 24/09/91 eay
-+ Fixed set_key :-)
-+ set_key is 4 times faster and takes less space.
-+ There are a few minor changes that could be made.
-+
-+Version 1.6 19/09/1991 eay
-+ Finally go IP and FP finished.
-+ Now I need to fix set_key.
-+ This version is quite a bit faster that 1.51
-+
-+Version 1.52 15/06/1991 eay
-+ 20% speedup in ecb_encrypt by changing the E bit selection
-+ to use 2 32bit words. This also required modification of the
-+ sp table. There is still a way to speedup the IP and IP-1
-+ (hints from outer@sq.com) still working on this one :-(.
-+
-+Version 1.51 07/06/1991 eay
-+ Faster des_encrypt by loop unrolling
-+ Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu)
-+
-+Version 1.50 28/05/1991 eay
-+ Optimised the code a bit more for the sparc. I have improved the
-+ speed of the inner des_encrypt by speeding up the initial and
-+ final permutations.
-+
-+Version 1.40 23/10/1990 eay
-+ Fixed des_random_key, it did not produce a random key :-(
-+
-+Version 1.30 2/10/1990 eay
-+ Have made des_quad_cksum the same as MIT's, the full package
-+ should be compatible with MIT's
-+ Have tested on a DECstation 3100
-+ Still need to fix des_set_key (make it faster).
-+ Does des_cbc_encrypts at 70.5k/sec on a 3100.
-+
-+Version 1.20 18/09/1990 eay
-+ Fixed byte order dependencies.
-+ Fixed (I hope) all the word alignment problems.
-+ Speedup in des_ecb_encrypt.
-+
-+Version 1.10 11/09/1990 eay
-+ Added des_enc_read and des_enc_write.
-+ Still need to fix des_quad_cksum.
-+ Still need to document des_enc_read and des_enc_write.
-+
-+Version 1.00 27/08/1990 eay
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/crypt586.pl Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,204 @@
-+#!/usr/bin/perl
-+#
-+# The inner loop instruction sequence and the IP/FP modifications are from
-+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
-+# I've added the stuff needed for crypt() but I've not worried about making
-+# things perfect.
-+#
-+
-+push(@INC,"perlasm","../../perlasm");
-+require "x86asm.pl";
-+
-+&asm_init($ARGV[0],"crypt586.pl");
-+
-+$L="edi";
-+$R="esi";
-+
-+&external_label("des_SPtrans");
-+&fcrypt_body("fcrypt_body");
-+&asm_finish();
-+
-+sub fcrypt_body
-+ {
-+ local($name,$do_ip)=@_;
-+
-+ &function_begin($name,"EXTRN _des_SPtrans:DWORD");
-+
-+ &comment("");
-+ &comment("Load the 2 words");
-+ $ks="ebp";
-+
-+ &xor( $L, $L);
-+ &xor( $R, $R);
-+ &mov($ks,&wparam(1));
-+
-+ &push(25); # add a variable
-+
-+ &set_label("start");
-+ for ($i=0; $i<16; $i+=2)
-+ {
-+ &comment("");
-+ &comment("Round $i");
-+ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
-+
-+ &comment("");
-+ &comment("Round ".sprintf("%d",$i+1));
-+ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
-+ }
-+ &mov("ebx", &swtmp(0));
-+ &mov("eax", $L);
-+ &dec("ebx");
-+ &mov($L, $R);
-+ &mov($R, "eax");
-+ &mov(&swtmp(0), "ebx");
-+ &jnz(&label("start"));
-+
-+ &comment("");
-+ &comment("FP");
-+ &mov("edx",&wparam(0));
-+
-+ &FP_new($R,$L,"eax",3);
-+ &mov(&DWP(0,"edx","",0),"eax");
-+ &mov(&DWP(4,"edx","",0),$L);
-+
-+ &pop("ecx"); # remove variable
-+
-+ &function_end($name);
-+ }
-+
-+sub D_ENCRYPT
-+ {
-+ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
-+
-+ &mov( $u, &wparam(2)); # 2
-+ &mov( $t, $R);
-+ &shr( $t, 16); # 1
-+ &mov( $tmp2, &wparam(3)); # 2
-+ &xor( $t, $R); # 1
-+
-+ &and( $u, $t); # 2
-+ &and( $t, $tmp2); # 2
-+
-+ &mov( $tmp1, $u);
-+ &shl( $tmp1, 16); # 1
-+ &mov( $tmp2, $t);
-+ &shl( $tmp2, 16); # 1
-+ &xor( $u, $tmp1); # 2
-+ &xor( $t, $tmp2); # 2
-+ &mov( $tmp1, &DWP(&n2a($S*4),$ks,"",0)); # 2
-+ &xor( $u, $tmp1);
-+ &mov( $tmp2, &DWP(&n2a(($S+1)*4),$ks,"",0)); # 2
-+ &xor( $u, $R);
-+ &xor( $t, $R);
-+ &xor( $t, $tmp2);
-+
-+ &and( $u, "0xfcfcfcfc" ); # 2
-+ &xor( $tmp1, $tmp1); # 1
-+ &and( $t, "0xcfcfcfcf" ); # 2
-+ &xor( $tmp2, $tmp2);
-+ &movb( &LB($tmp1), &LB($u) );
-+ &movb( &LB($tmp2), &HB($u) );
-+ &rotr( $t, 4 );
-+ &mov( $ks, &DWP(" $desSP",$tmp1,"",0));
-+ &movb( &LB($tmp1), &LB($t) );
-+ &xor( $L, $ks);
-+ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
-+ &xor( $L, $ks);
-+ &movb( &LB($tmp2), &HB($t) );
-+ &shr( $u, 16);
-+ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
-+ &xor( $L, $ks);
-+ &movb( &LB($tmp1), &HB($u) );
-+ &shr( $t, 16);
-+ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
-+ &xor( $L, $ks);
-+ &mov( $ks, &wparam(1));
-+ &movb( &LB($tmp2), &HB($t) );
-+ &and( $u, "0xff" );
-+ &and( $t, "0xff" );
-+ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
-+ &xor( $L, $tmp1);
-+ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
-+ &xor( $L, $tmp1);
-+ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
-+ &xor( $L, $tmp1);
-+ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
-+ &xor( $L, $tmp1);
-+ }
-+
-+sub n2a
-+ {
-+ sprintf("%d",$_[0]);
-+ }
-+
-+# now has a side affect of rotating $a by $shift
-+sub R_PERM_OP
-+ {
-+ local($a,$b,$tt,$shift,$mask,$last)=@_;
-+
-+ &rotl( $a, $shift ) if ($shift != 0);
-+ &mov( $tt, $a );
-+ &xor( $a, $b );
-+ &and( $a, $mask );
-+ if ($notlast eq $b)
-+ {
-+ &xor( $b, $a );
-+ &xor( $tt, $a );
-+ }
-+ else
-+ {
-+ &xor( $tt, $a );
-+ &xor( $b, $a );
-+ }
-+ &comment("");
-+ }
-+
-+sub IP_new
-+ {
-+ local($l,$r,$tt,$lr)=@_;
-+
-+ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
-+ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
-+ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
-+ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
-+ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
-+
-+ if ($lr != 3)
-+ {
-+ if (($lr-3) < 0)
-+ { &rotr($tt, 3-$lr); }
-+ else { &rotl($tt, $lr-3); }
-+ }
-+ if ($lr != 2)
-+ {
-+ if (($lr-2) < 0)
-+ { &rotr($r, 2-$lr); }
-+ else { &rotl($r, $lr-2); }
-+ }
-+ }
-+
-+sub FP_new
-+ {
-+ local($l,$r,$tt,$lr)=@_;
-+
-+ if ($lr != 2)
-+ {
-+ if (($lr-2) < 0)
-+ { &rotl($r, 2-$lr); }
-+ else { &rotr($r, $lr-2); }
-+ }
-+ if ($lr != 3)
-+ {
-+ if (($lr-3) < 0)
-+ { &rotl($l, 3-$lr); }
-+ else { &rotr($l, $lr-3); }
-+ }
-+
-+ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
-+ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
-+ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
-+ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
-+ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
-+ &rotr($tt , 4);
-+ }
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/des-586.pl Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,251 @@
-+#!/usr/bin/perl
-+#
-+# The inner loop instruction sequence and the IP/FP modifications are from
-+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
-+#
-+
-+push(@INC,"perlasm","../../perlasm");
-+require "x86asm.pl";
-+require "cbc.pl";
-+require "desboth.pl";
-+
-+# base code is in microsft
-+# op dest, source
-+# format.
-+#
-+
-+&asm_init($ARGV[0],"des-586.pl");
-+
-+$L="edi";
-+$R="esi";
-+
-+&external_label("des_SPtrans");
-+&des_encrypt("des_encrypt",1);
-+&des_encrypt("des_encrypt2",0);
-+&des_encrypt3("des_encrypt3",1);
-+&des_encrypt3("des_decrypt3",0);
-+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
-+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
-+
-+&asm_finish();
-+
-+sub des_encrypt
-+ {
-+ local($name,$do_ip)=@_;
-+
-+ &function_begin_B($name,"EXTRN _des_SPtrans:DWORD");
-+
-+ &push("esi");
-+ &push("edi");
-+
-+ &comment("");
-+ &comment("Load the 2 words");
-+ $ks="ebp";
-+
-+ if ($do_ip)
-+ {
-+ &mov($R,&wparam(0));
-+ &xor( "ecx", "ecx" );
-+
-+ &push("ebx");
-+ &push("ebp");
-+
-+ &mov("eax",&DWP(0,$R,"",0));
-+ &mov("ebx",&wparam(2)); # get encrypt flag
-+ &mov($L,&DWP(4,$R,"",0));
-+ &comment("");
-+ &comment("IP");
-+ &IP_new("eax",$L,$R,3);
-+ }
-+ else
-+ {
-+ &mov("eax",&wparam(0));
-+ &xor( "ecx", "ecx" );
-+
-+ &push("ebx");
-+ &push("ebp");
-+
-+ &mov($R,&DWP(0,"eax","",0));
-+ &mov("ebx",&wparam(2)); # get encrypt flag
-+ &rotl($R,3);
-+ &mov($L,&DWP(4,"eax","",0));
-+ &rotl($L,3);
-+ }
-+
-+ &mov( $ks, &wparam(1) );
-+ &cmp("ebx","0");
-+ &je(&label("start_decrypt"));
-+
-+ for ($i=0; $i<16; $i+=2)
-+ {
-+ &comment("");
-+ &comment("Round $i");
-+ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
-+
-+ &comment("");
-+ &comment("Round ".sprintf("%d",$i+1));
-+ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
-+ }
-+ &jmp(&label("end"));
-+
-+ &set_label("start_decrypt");
-+
-+ for ($i=15; $i>0; $i-=2)
-+ {
-+ &comment("");
-+ &comment("Round $i");
-+ &D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
-+ &comment("");
-+ &comment("Round ".sprintf("%d",$i-1));
-+ &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
-+ }
-+
-+ &set_label("end");
-+
-+ if ($do_ip)
-+ {
-+ &comment("");
-+ &comment("FP");
-+ &mov("edx",&wparam(0));
-+ &FP_new($L,$R,"eax",3);
-+
-+ &mov(&DWP(0,"edx","",0),"eax");
-+ &mov(&DWP(4,"edx","",0),$R);
-+ }
-+ else
-+ {
-+ &comment("");
-+ &comment("Fixup");
-+ &rotr($L,3); # r
-+ &mov("eax",&wparam(0));
-+ &rotr($R,3); # l
-+ &mov(&DWP(0,"eax","",0),$L);
-+ &mov(&DWP(4,"eax","",0),$R);
-+ }
-+
-+ &pop("ebp");
-+ &pop("ebx");
-+ &pop("edi");
-+ &pop("esi");
-+ &ret();
-+
-+ &function_end_B($name);
-+ }
-+
-+sub D_ENCRYPT
-+ {
-+ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
-+
-+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
-+ &xor( $tmp1, $tmp1);
-+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
-+ &xor( $u, $R);
-+ &xor( $t, $R);
-+ &and( $u, "0xfcfcfcfc" );
-+ &and( $t, "0xcfcfcfcf" );
-+ &movb( &LB($tmp1), &LB($u) );
-+ &movb( &LB($tmp2), &HB($u) );
-+ &rotr( $t, 4 );
-+ &mov( $ks, &DWP(" $desSP",$tmp1,"",0));
-+ &movb( &LB($tmp1), &LB($t) );
-+ &xor( $L, $ks);
-+ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
-+ &xor( $L, $ks); ######
-+ &movb( &LB($tmp2), &HB($t) );
-+ &shr( $u, 16);
-+ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
-+ &xor( $L, $ks); ######
-+ &movb( &LB($tmp1), &HB($u) );
-+ &shr( $t, 16);
-+ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
-+ &xor( $L, $ks);
-+ &mov( $ks, &wparam(1) );
-+ &movb( &LB($tmp2), &HB($t) );
-+ &and( $u, "0xff" );
-+ &and( $t, "0xff" );
-+ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
-+ &xor( $L, $tmp1);
-+ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
-+ &xor( $L, $tmp1);
-+ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
-+ &xor( $L, $tmp1);
-+ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
-+ &xor( $L, $tmp1);
-+ }
-+
-+sub n2a
-+ {
-+ sprintf("%d",$_[0]);
-+ }
-+
-+# now has a side affect of rotating $a by $shift
-+sub R_PERM_OP
-+ {
-+ local($a,$b,$tt,$shift,$mask,$last)=@_;
-+
-+ &rotl( $a, $shift ) if ($shift != 0);
-+ &mov( $tt, $a );
-+ &xor( $a, $b );
-+ &and( $a, $mask );
-+ if (!$last eq $b)
-+ {
-+ &xor( $b, $a );
-+ &xor( $tt, $a );
-+ }
-+ else
-+ {
-+ &xor( $tt, $a );
-+ &xor( $b, $a );
-+ }
-+ &comment("");
-+ }
-+
-+sub IP_new
-+ {
-+ local($l,$r,$tt,$lr)=@_;
-+
-+ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
-+ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
-+ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
-+ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
-+ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
-+
-+ if ($lr != 3)
-+ {
-+ if (($lr-3) < 0)
-+ { &rotr($tt, 3-$lr); }
-+ else { &rotl($tt, $lr-3); }
-+ }
-+ if ($lr != 2)
-+ {
-+ if (($lr-2) < 0)
-+ { &rotr($r, 2-$lr); }
-+ else { &rotl($r, $lr-2); }
-+ }
-+ }
-+
-+sub FP_new
-+ {
-+ local($l,$r,$tt,$lr)=@_;
-+
-+ if ($lr != 2)
-+ {
-+ if (($lr-2) < 0)
-+ { &rotl($r, 2-$lr); }
-+ else { &rotr($r, $lr-2); }
-+ }
-+ if ($lr != 3)
-+ {
-+ if (($lr-3) < 0)
-+ { &rotl($l, 3-$lr); }
-+ else { &rotr($l, $lr-3); }
-+ }
-+
-+ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
-+ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
-+ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
-+ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
-+ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
-+ &rotr($tt , 4);
-+ }
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/des686.pl Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,230 @@
-+#!/usr/bin/perl
-+
-+$prog="des686.pl";
-+
-+# base code is in microsft
-+# op dest, source
-+# format.
-+#
-+
-+# WILL NOT WORK ANYMORE WITH desboth.pl
-+require "desboth.pl";
-+
-+if ( ($ARGV[0] eq "elf"))
-+ { require "x86unix.pl"; }
-+elsif ( ($ARGV[0] eq "a.out"))
-+ { $aout=1; require "x86unix.pl"; }
-+elsif ( ($ARGV[0] eq "sol"))
-+ { $sol=1; require "x86unix.pl"; }
-+elsif ( ($ARGV[0] eq "cpp"))
-+ { $cpp=1; require "x86unix.pl"; }
-+elsif ( ($ARGV[0] eq "win32"))
-+ { require "x86ms.pl"; }
-+else
-+ {
-+ print STDERR <<"EOF";
-+Pick one target type from
-+ elf - linux, FreeBSD etc
-+ a.out - old linux
-+ sol - x86 solaris
-+ cpp - format so x86unix.cpp can be used
-+ win32 - Windows 95/Windows NT
-+EOF
-+ exit(1);
-+ }
-+
-+&comment("Don't even think of reading this code");
-+&comment("It was automatically generated by $prog");
-+&comment("Which is a perl program used to generate the x86 assember for");
-+&comment("any of elf, a.out, Win32, or Solaris");
-+&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
-+&comment("eric <eay\@cryptsoft.com>");
-+&comment("");
-+
-+&file("dx86xxxx");
-+
-+$L="edi";
-+$R="esi";
-+
-+&des_encrypt("des_encrypt",1);
-+&des_encrypt("des_encrypt2",0);
-+
-+&des_encrypt3("des_encrypt3",1);
-+&des_encrypt3("des_decrypt3",0);
-+
-+&file_end();
-+
-+sub des_encrypt
-+ {
-+ local($name,$do_ip)=@_;
-+
-+ &function_begin($name,"EXTRN _des_SPtrans:DWORD");
-+
-+ &comment("");
-+ &comment("Load the 2 words");
-+ &mov("eax",&wparam(0));
-+ &mov($L,&DWP(0,"eax","",0));
-+ &mov($R,&DWP(4,"eax","",0));
-+
-+ $ksp=&wparam(1);
-+
-+ if ($do_ip)
-+ {
-+ &comment("");
-+ &comment("IP");
-+ &IP_new($L,$R,"eax");
-+ }
-+
-+ &comment("");
-+ &comment("fixup rotate");
-+ &rotl($R,3);
-+ &rotl($L,3);
-+ &exch($L,$R);
-+
-+ &comment("");
-+ &comment("load counter, key_schedule and enc flag");
-+ &mov("eax",&wparam(2)); # get encrypt flag
-+ &mov("ebp",&wparam(1)); # get ks
-+ &cmp("eax","0");
-+ &je(&label("start_decrypt"));
-+
-+ # encrypting part
-+
-+ for ($i=0; $i<16; $i+=2)
-+ {
-+ &comment("");
-+ &comment("Round $i");
-+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
-+
-+ &comment("");
-+ &comment("Round ".sprintf("%d",$i+1));
-+ &D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
-+ }
-+ &jmp(&label("end"));
-+
-+ &set_label("start_decrypt");
-+
-+ for ($i=15; $i>0; $i-=2)
-+ {
-+ &comment("");
-+ &comment("Round $i");
-+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
-+ &comment("");
-+ &comment("Round ".sprintf("%d",$i-1));
-+ &D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
-+ }
-+
-+ &set_label("end");
-+
-+ &comment("");
-+ &comment("Fixup");
-+ &rotr($L,3); # r
-+ &rotr($R,3); # l
-+
-+ if ($do_ip)
-+ {
-+ &comment("");
-+ &comment("FP");
-+ &FP_new($R,$L,"eax");
-+ }
-+
-+ &mov("eax",&wparam(0));
-+ &mov(&DWP(0,"eax","",0),$L);
-+ &mov(&DWP(4,"eax","",0),$R);
-+
-+ &function_end($name);
-+ }
-+
-+
-+# The logic is to load R into 2 registers and operate on both at the same time.
-+# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte'
-+# while also masking the other copy and doing a lookup. We then also accumulate the
-+# L value in 2 registers then combine them at the end.
-+sub D_ENCRYPT
-+ {
-+ local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_;
-+
-+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
-+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
-+ &xor( $u, $R );
-+ &xor( $t, $R );
-+ &rotr( $t, 4 );
-+
-+ # the numbers at the end of the line are origional instruction order
-+ &mov( $tmp2, $u ); # 1 2
-+ &mov( $tmp1, $t ); # 1 1
-+ &and( $tmp2, "0xfc" ); # 1 4
-+ &and( $tmp1, "0xfc" ); # 1 3
-+ &shr( $t, 8 ); # 1 5
-+ &xor( $L, &DWP("0x100+$desSP",$tmp1,"",0)); # 1 7
-+ &shr( $u, 8 ); # 1 6
-+ &mov( $tmp1, &DWP(" $desSP",$tmp2,"",0)); # 1 8
-+
-+ &mov( $tmp2, $u ); # 2 2
-+ &xor( $L, $tmp1 ); # 1 9
-+ &and( $tmp2, "0xfc" ); # 2 4
-+ &mov( $tmp1, $t ); # 2 1
-+ &and( $tmp1, "0xfc" ); # 2 3
-+ &shr( $t, 8 ); # 2 5
-+ &xor( $L, &DWP("0x300+$desSP",$tmp1,"",0)); # 2 7
-+ &shr( $u, 8 ); # 2 6
-+ &mov( $tmp1, &DWP("0x200+$desSP",$tmp2,"",0)); # 2 8
-+ &mov( $tmp2, $u ); # 3 2
-+
-+ &xor( $L, $tmp1 ); # 2 9
-+ &and( $tmp2, "0xfc" ); # 3 4
-+
-+ &mov( $tmp1, $t ); # 3 1
-+ &shr( $u, 8 ); # 3 6
-+ &and( $tmp1, "0xfc" ); # 3 3
-+ &shr( $t, 8 ); # 3 5
-+ &xor( $L, &DWP("0x500+$desSP",$tmp1,"",0)); # 3 7
-+ &mov( $tmp1, &DWP("0x400+$desSP",$tmp2,"",0)); # 3 8
-+
-+ &and( $t, "0xfc" ); # 4 1
-+ &xor( $L, $tmp1 ); # 3 9
-+
-+ &and( $u, "0xfc" ); # 4 2
-+ &xor( $L, &DWP("0x700+$desSP",$t,"",0)); # 4 3
-+ &xor( $L, &DWP("0x600+$desSP",$u,"",0)); # 4 4
-+ }
-+
-+sub PERM_OP
-+ {
-+ local($a,$b,$tt,$shift,$mask)=@_;
-+
-+ &mov( $tt, $a );
-+ &shr( $tt, $shift );
-+ &xor( $tt, $b );
-+ &and( $tt, $mask );
-+ &xor( $b, $tt );
-+ &shl( $tt, $shift );
-+ &xor( $a, $tt );
-+ }
-+
-+sub IP_new
-+ {
-+ local($l,$r,$tt)=@_;
-+
-+ &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");
-+ &PERM_OP($l,$r,$tt,16,"0x0000ffff");
-+ &PERM_OP($r,$l,$tt, 2,"0x33333333");
-+ &PERM_OP($l,$r,$tt, 8,"0x00ff00ff");
-+ &PERM_OP($r,$l,$tt, 1,"0x55555555");
-+ }
-+
-+sub FP_new
-+ {
-+ local($l,$r,$tt)=@_;
-+
-+ &PERM_OP($l,$r,$tt, 1,"0x55555555");
-+ &PERM_OP($r,$l,$tt, 8,"0x00ff00ff");
-+ &PERM_OP($l,$r,$tt, 2,"0x33333333");
-+ &PERM_OP($r,$l,$tt,16,"0x0000ffff");
-+ &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");
-+ }
-+
-+sub n2a
-+ {
-+ sprintf("%d",$_[0]);
-+ }
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/desboth.pl Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,79 @@
-+#!/usr/bin/perl
-+
-+$L="edi";
-+$R="esi";
-+
-+sub des_encrypt3
-+ {
-+ local($name,$enc)=@_;
-+
-+ &function_begin_B($name,"");
-+ &push("ebx");
-+ &mov("ebx",&wparam(0));
-+
-+ &push("ebp");
-+ &push("esi");
-+
-+ &push("edi");
-+
-+ &comment("");
-+ &comment("Load the data words");
-+ &mov($L,&DWP(0,"ebx","",0));
-+ &mov($R,&DWP(4,"ebx","",0));
-+ &stack_push(3);
-+
-+ &comment("");
-+ &comment("IP");
-+ &IP_new($L,$R,"edx",0);
-+
-+ # put them back
-+
-+ if ($enc)
-+ {
-+ &mov(&DWP(4,"ebx","",0),$R);
-+ &mov("eax",&wparam(1));
-+ &mov(&DWP(0,"ebx","",0),"edx");
-+ &mov("edi",&wparam(2));
-+ &mov("esi",&wparam(3));
-+ }
-+ else
-+ {
-+ &mov(&DWP(4,"ebx","",0),$R);
-+ &mov("esi",&wparam(1));
-+ &mov(&DWP(0,"ebx","",0),"edx");
-+ &mov("edi",&wparam(2));
-+ &mov("eax",&wparam(3));
-+ }
-+ &mov(&swtmp(2), (($enc)?"1":"0"));
-+ &mov(&swtmp(1), "eax");
-+ &mov(&swtmp(0), "ebx");
-+ &call("des_encrypt2");
-+ &mov(&swtmp(2), (($enc)?"0":"1"));
-+ &mov(&swtmp(1), "edi");
-+ &mov(&swtmp(0), "ebx");
-+ &call("des_encrypt2");
-+ &mov(&swtmp(2), (($enc)?"1":"0"));
-+ &mov(&swtmp(1), "esi");
-+ &mov(&swtmp(0), "ebx");
-+ &call("des_encrypt2");
-+
-+ &stack_pop(3);
-+ &mov($L,&DWP(0,"ebx","",0));
-+ &mov($R,&DWP(4,"ebx","",0));
-+
-+ &comment("");
-+ &comment("FP");
-+ &FP_new($L,$R,"eax",0);
-+
-+ &mov(&DWP(0,"ebx","",0),"eax");
-+ &mov(&DWP(4,"ebx","",0),$R);
-+
-+ &pop("edi");
-+ &pop("esi");
-+ &pop("ebp");
-+ &pop("ebx");
-+ &ret();
-+ &function_end_B($name);
-+ }
-+
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/perlasm/cbc.pl Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,342 @@
-+#!/usr/bin/perl
-+
-+# void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
-+# des_cblock (*input);
-+# des_cblock (*output);
-+# long length;
-+# des_key_schedule schedule;
-+# des_cblock (*ivec);
-+# int enc;
-+#
-+# calls
-+# des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
-+#
-+
-+#&cbc("des_ncbc_encrypt","des_encrypt",0);
-+#&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",
-+# 1,4,5,3,5,-1);
-+#&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",
-+# 0,4,5,3,5,-1);
-+#&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",
-+# 0,6,7,3,4,5);
-+#
-+# When doing a cipher that needs bigendian order,
-+# for encrypt, the iv is kept in bigendian form,
-+# while for decrypt, it is kept in little endian.
-+sub cbc
-+ {
-+ local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_;
-+ # name is the function name
-+ # enc_func and dec_func and the functions to call for encrypt/decrypt
-+ # swap is true if byte order needs to be reversed
-+ # iv_off is parameter number for the iv
-+ # enc_off is parameter number for the encrypt/decrypt flag
-+ # p1,p2,p3 are the offsets for parameters to be passed to the
-+ # underlying calls.
-+
-+ &function_begin_B($name,"");
-+ &comment("");
-+
-+ $in="esi";
-+ $out="edi";
-+ $count="ebp";
-+
-+ &push("ebp");
-+ &push("ebx");
-+ &push("esi");
-+ &push("edi");
-+
-+ $data_off=4;
-+ $data_off+=4 if ($p1 > 0);
-+ $data_off+=4 if ($p2 > 0);
-+ $data_off+=4 if ($p3 > 0);
-+
-+ &mov($count, &wparam(2)); # length
-+
-+ &comment("getting iv ptr from parameter $iv_off");
-+ &mov("ebx", &wparam($iv_off)); # Get iv ptr
-+
-+ &mov($in, &DWP(0,"ebx","",0));# iv[0]
-+ &mov($out, &DWP(4,"ebx","",0));# iv[1]
-+
-+ &push($out);
-+ &push($in);
-+ &push($out); # used in decrypt for iv[1]
-+ &push($in); # used in decrypt for iv[0]
-+
-+ &mov("ebx", "esp"); # This is the address of tin[2]
-+
-+ &mov($in, &wparam(0)); # in
-+ &mov($out, &wparam(1)); # out
-+
-+ # We have loaded them all, how lets push things
-+ &comment("getting encrypt flag from parameter $enc_off");
-+ &mov("ecx", &wparam($enc_off)); # Get enc flag
-+ if ($p3 > 0)
-+ {
-+ &comment("get and push parameter $p3");
-+ if ($enc_off != $p3)
-+ { &mov("eax", &wparam($p3)); &push("eax"); }
-+ else { &push("ecx"); }
-+ }
-+ if ($p2 > 0)
-+ {
-+ &comment("get and push parameter $p2");
-+ if ($enc_off != $p2)
-+ { &mov("eax", &wparam($p2)); &push("eax"); }
-+ else { &push("ecx"); }
-+ }
-+ if ($p1 > 0)
-+ {
-+ &comment("get and push parameter $p1");
-+ if ($enc_off != $p1)
-+ { &mov("eax", &wparam($p1)); &push("eax"); }
-+ else { &push("ecx"); }
-+ }
-+ &push("ebx"); # push data/iv
-+
-+ &cmp("ecx",0);
-+ &jz(&label("decrypt"));
-+
-+ &and($count,0xfffffff8);
-+ &mov("eax", &DWP($data_off,"esp","",0)); # load iv[0]
-+ &mov("ebx", &DWP($data_off+4,"esp","",0)); # load iv[1]
-+
-+ &jz(&label("encrypt_finish"));
-+
-+ #############################################################
-+
-+ &set_label("encrypt_loop");
-+ # encrypt start
-+ # "eax" and "ebx" hold iv (or the last cipher text)
-+
-+ &mov("ecx", &DWP(0,$in,"",0)); # load first 4 bytes
-+ &mov("edx", &DWP(4,$in,"",0)); # second 4 bytes
-+
-+ &xor("eax", "ecx");
-+ &xor("ebx", "edx");
-+
-+ &bswap("eax") if $swap;
-+ &bswap("ebx") if $swap;
-+
-+ &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call
-+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
-+
-+ &call($enc_func);
-+
-+ &mov("eax", &DWP($data_off,"esp","",0));
-+ &mov("ebx", &DWP($data_off+4,"esp","",0));
-+
-+ &bswap("eax") if $swap;
-+ &bswap("ebx") if $swap;
-+
-+ &mov(&DWP(0,$out,"",0),"eax");
-+ &mov(&DWP(4,$out,"",0),"ebx");
-+
-+ # eax and ebx are the next iv.
-+
-+ &add($in, 8);
-+ &add($out, 8);
-+
-+ &sub($count, 8);
-+ &jnz(&label("encrypt_loop"));
-+
-+###################################################################3
-+ &set_label("encrypt_finish");
-+ &mov($count, &wparam(2)); # length
-+ &and($count, 7);
-+ &jz(&label("finish"));
-+ &xor("ecx","ecx");
-+ &xor("edx","edx");
-+ &mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4));
-+ &jmp_ptr($count);
-+
-+&set_label("ej7");
-+ &xor("edx", "edx") if $ppro; # ppro friendly
-+ &movb(&HB("edx"), &BP(6,$in,"",0));
-+ &shl("edx",8);
-+&set_label("ej6");
-+ &movb(&HB("edx"), &BP(5,$in,"",0));
-+&set_label("ej5");
-+ &movb(&LB("edx"), &BP(4,$in,"",0));
-+&set_label("ej4");
-+ &mov("ecx", &DWP(0,$in,"",0));
-+ &jmp(&label("ejend"));
-+&set_label("ej3");
-+ &movb(&HB("ecx"), &BP(2,$in,"",0));
-+ &xor("ecx", "ecx") if $ppro; # ppro friendly
-+ &shl("ecx",8);
-+&set_label("ej2");
-+ &movb(&HB("ecx"), &BP(1,$in,"",0));
-+&set_label("ej1");
-+ &movb(&LB("ecx"), &BP(0,$in,"",0));
-+&set_label("ejend");
-+
-+ &xor("eax", "ecx");
-+ &xor("ebx", "edx");
-+
-+ &bswap("eax") if $swap;
-+ &bswap("ebx") if $swap;
-+
-+ &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call
-+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
-+
-+ &call($enc_func);
-+
-+ &mov("eax", &DWP($data_off,"esp","",0));
-+ &mov("ebx", &DWP($data_off+4,"esp","",0));
-+
-+ &bswap("eax") if $swap;
-+ &bswap("ebx") if $swap;
-+
-+ &mov(&DWP(0,$out,"",0),"eax");
-+ &mov(&DWP(4,$out,"",0),"ebx");
-+
-+ &jmp(&label("finish"));
-+
-+ #############################################################
-+ #############################################################
-+ &set_label("decrypt",1);
-+ # decrypt start
-+ &and($count,0xfffffff8);
-+ # The next 2 instructions are only for if the jz is taken
-+ &mov("eax", &DWP($data_off+8,"esp","",0)); # get iv[0]
-+ &mov("ebx", &DWP($data_off+12,"esp","",0)); # get iv[1]
-+ &jz(&label("decrypt_finish"));
-+
-+ &set_label("decrypt_loop");
-+ &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes
-+ &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes
-+
-+ &bswap("eax") if $swap;
-+ &bswap("ebx") if $swap;
-+
-+ &mov(&DWP($data_off,"esp","",0), "eax"); # put back
-+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
-+
-+ &call($dec_func);
-+
-+ &mov("eax", &DWP($data_off,"esp","",0)); # get return
-+ &mov("ebx", &DWP($data_off+4,"esp","",0)); #
-+
-+ &bswap("eax") if $swap;
-+ &bswap("ebx") if $swap;
-+
-+ &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0]
-+ &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1]
-+
-+ &xor("ecx", "eax");
-+ &xor("edx", "ebx");
-+
-+ &mov("eax", &DWP(0,$in,"",0)); # get old cipher text,
-+ &mov("ebx", &DWP(4,$in,"",0)); # next iv actually
-+
-+ &mov(&DWP(0,$out,"",0),"ecx");
-+ &mov(&DWP(4,$out,"",0),"edx");
-+
-+ &mov(&DWP($data_off+8,"esp","",0), "eax"); # save iv
-+ &mov(&DWP($data_off+12,"esp","",0), "ebx"); #
-+
-+ &add($in, 8);
-+ &add($out, 8);
-+
-+ &sub($count, 8);
-+ &jnz(&label("decrypt_loop"));
-+############################ ENDIT #######################3
-+ &set_label("decrypt_finish");
-+ &mov($count, &wparam(2)); # length
-+ &and($count, 7);
-+ &jz(&label("finish"));
-+
-+ &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes
-+ &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes
-+
-+ &bswap("eax") if $swap;
-+ &bswap("ebx") if $swap;
-+
-+ &mov(&DWP($data_off,"esp","",0), "eax"); # put back
-+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
-+
-+ &call($dec_func);
-+
-+ &mov("eax", &DWP($data_off,"esp","",0)); # get return
-+ &mov("ebx", &DWP($data_off+4,"esp","",0)); #
-+
-+ &bswap("eax") if $swap;
-+ &bswap("ebx") if $swap;
-+
-+ &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0]
-+ &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1]
-+
-+ &xor("ecx", "eax");
-+ &xor("edx", "ebx");
-+
-+ # this is for when we exit
-+ &mov("eax", &DWP(0,$in,"",0)); # get old cipher text,
-+ &mov("ebx", &DWP(4,$in,"",0)); # next iv actually
-+
-+&set_label("dj7");
-+ &rotr("edx", 16);
-+ &movb(&BP(6,$out,"",0), &LB("edx"));
-+ &shr("edx",16);
-+&set_label("dj6");
-+ &movb(&BP(5,$out,"",0), &HB("edx"));
-+&set_label("dj5");
-+ &movb(&BP(4,$out,"",0), &LB("edx"));
-+&set_label("dj4");
-+ &mov(&DWP(0,$out,"",0), "ecx");
-+ &jmp(&label("djend"));
-+&set_label("dj3");
-+ &rotr("ecx", 16);
-+ &movb(&BP(2,$out,"",0), &LB("ecx"));
-+ &shl("ecx",16);
-+&set_label("dj2");
-+ &movb(&BP(1,$in,"",0), &HB("ecx"));
-+&set_label("dj1");
-+ &movb(&BP(0,$in,"",0), &LB("ecx"));
-+&set_label("djend");
-+
-+ # final iv is still in eax:ebx
-+ &jmp(&label("finish"));
-+
-+
-+############################ FINISH #######################3
-+ &set_label("finish",1);
-+ &mov("ecx", &wparam($iv_off)); # Get iv ptr
-+
-+ #################################################
-+ $total=16+4;
-+ $total+=4 if ($p1 > 0);
-+ $total+=4 if ($p2 > 0);
-+ $total+=4 if ($p3 > 0);
-+ &add("esp",$total);
-+
-+ &mov(&DWP(0,"ecx","",0), "eax"); # save iv
-+ &mov(&DWP(4,"ecx","",0), "ebx"); # save iv
-+
-+ &function_end_A($name);
-+
-+ &set_label("cbc_enc_jmp_table",1);
-+ &data_word("0");
-+ &data_word(&label("ej1"));
-+ &data_word(&label("ej2"));
-+ &data_word(&label("ej3"));
-+ &data_word(&label("ej4"));
-+ &data_word(&label("ej5"));
-+ &data_word(&label("ej6"));
-+ &data_word(&label("ej7"));
-+ &set_label("cbc_dec_jmp_table",1);
-+ &data_word("0");
-+ &data_word(&label("dj1"));
-+ &data_word(&label("dj2"));
-+ &data_word(&label("dj3"));
-+ &data_word(&label("dj4"));
-+ &data_word(&label("dj5"));
-+ &data_word(&label("dj6"));
-+ &data_word(&label("dj7"));
-+
-+ &function_end_B($name);
-+
-+ }
-+
-+1;
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/perlasm/readme Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,124 @@
-+The perl scripts in this directory are my 'hack' to generate
-+multiple different assembler formats via the one origional script.
-+
-+The way to use this library is to start with adding the path to this directory
-+and then include it.
-+
-+push(@INC,"perlasm","../../perlasm");
-+require "x86asm.pl";
-+
-+The first thing we do is setup the file and type of assember
-+
-+&asm_init($ARGV[0],$0);
-+
-+The first argument is the 'type'. Currently
-+'cpp', 'sol', 'a.out', 'elf' or 'win32'.
-+Argument 2 is the file name.
-+
-+The reciprocal function is
-+&asm_finish() which should be called at the end.
-+
-+There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler,
-+and x86unix.pl which is the unix (gas) version.
-+
-+Functions of interest are:
-+&external_label("des_SPtrans"); declare and external variable
-+&LB(reg); Low byte for a register
-+&HB(reg); High byte for a register
-+&BP(off,base,index,scale) Byte pointer addressing
-+&DWP(off,base,index,scale) Word pointer addressing
-+&stack_push(num) Basically a 'sub esp, num*4' with extra
-+&stack_pop(num) inverse of stack_push
-+&function_begin(name,extra) Start a function with pushing of
-+ edi, esi, ebx and ebp. extra is extra win32
-+ external info that may be required.
-+&function_begin_B(name,extra) Same as norma function_begin but no pushing.
-+&function_end(name) Call at end of function.
-+&function_end_A(name) Standard pop and ret, for use inside functions
-+&function_end_B(name) Call at end but with poping or 'ret'.
-+&swtmp(num) Address on stack temp word.
-+&wparam(num) Parameter number num, that was push
-+ in C convention. This all works over pushes
-+ and pops.
-+&comment("hello there") Put in a comment.
-+&label("loop") Refer to a label, normally a jmp target.
-+&set_label("loop") Set a label at this point.
-+&data_word(word) Put in a word of data.
-+
-+So how does this all hold together? Given
-+
-+int calc(int len, int *data)
-+ {
-+ int i,j=0;
-+
-+ for (i=0; i<len; i++)
-+ {
-+ j+=other(data[i]);
-+ }
-+ }
-+
-+So a very simple version of this function could be coded as
-+
-+ push(@INC,"perlasm","../../perlasm");
-+ require "x86asm.pl";
-+
-+ &asm_init($ARGV[0],"cacl.pl");
-+
-+ &external_label("other");
-+
-+ $tmp1= "eax";
-+ $j= "edi";
-+ $data= "esi";
-+ $i= "ebp";
-+
-+ &comment("a simple function");
-+ &function_begin("calc");
-+ &mov( $data, &wparam(1)); # data
-+ &xor( $j, $j);
-+ &xor( $i, $i);
-+
-+ &set_label("loop");
-+ &cmp( $i, &wparam(0));
-+ &jge( &label("end"));
-+
-+ &mov( $tmp1, &DWP(0,$data,$i,4));
-+ &push( $tmp1);
-+ &call( "other");
-+ &add( $j, "eax");
-+ &pop( $tmp1);
-+ &inc( $i);
-+ &jmp( &label("loop"));
-+
-+ &set_label("end");
-+ &mov( "eax", $j);
-+
-+ &function_end("calc");
-+
-+ &asm_finish();
-+
-+The above example is very very unoptimised but gives an idea of how
-+things work.
-+
-+There is also a cbc mode function generator in cbc.pl
-+
-+&cbc( $name,
-+ $encrypt_function_name,
-+ $decrypt_function_name,
-+ $true_if_byte_swap_needed,
-+ $parameter_number_for_iv,
-+ $parameter_number_for_encrypt_flag,
-+ $first_parameter_to_pass,
-+ $second_parameter_to_pass,
-+ $third_parameter_to_pass);
-+
-+So for example, given
-+void BF_encrypt(BF_LONG *data,BF_KEY *key);
-+void BF_decrypt(BF_LONG *data,BF_KEY *key);
-+void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
-+ BF_KEY *ks, unsigned char *iv, int enc);
-+
-+&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1);
-+
-+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
-+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/perlasm/x86asm.pl Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,111 @@
-+#!/usr/bin/perl
-+
-+# require 'x86asm.pl';
-+# &asm_init("cpp","des-586.pl");
-+# XXX
-+# XXX
-+# main'asm_finish
-+
-+sub main'asm_finish
-+ {
-+ &file_end();
-+ &asm_finish_cpp() if $cpp;
-+ print &asm_get_output();
-+ }
-+
-+sub main'asm_init
-+ {
-+ ($type,$fn)=@_;
-+ $filename=$fn;
-+
-+ $cpp=$sol=$aout=$win32=0;
-+ if ( ($type eq "elf"))
-+ { require "x86unix.pl"; }
-+ elsif ( ($type eq "a.out"))
-+ { $aout=1; require "x86unix.pl"; }
-+ elsif ( ($type eq "sol"))
-+ { $sol=1; require "x86unix.pl"; }
-+ elsif ( ($type eq "cpp"))
-+ { $cpp=1; require "x86unix.pl"; }
-+ elsif ( ($type eq "win32"))
-+ { $win32=1; require "x86ms.pl"; }
-+ else
-+ {
-+ print STDERR <<"EOF";
-+Pick one target type from
-+ elf - linux, FreeBSD etc
-+ a.out - old linux
-+ sol - x86 solaris
-+ cpp - format so x86unix.cpp can be used
-+ win32 - Windows 95/Windows NT
-+EOF
-+ exit(1);
-+ }
-+
-+ &asm_init_output();
-+
-+&comment("Don't even think of reading this code");
-+&comment("It was automatically generated by $filename");
-+&comment("Which is a perl program used to generate the x86 assember for");
-+&comment("any of elf, a.out, BSDI,Win32, or Solaris");
-+&comment("eric <eay\@cryptsoft.com>");
-+&comment("");
-+
-+ $filename =~ s/\.pl$//;
-+ &file($filename);
-+ }
-+
-+sub asm_finish_cpp
-+ {
-+ return unless $cpp;
-+
-+ local($tmp,$i);
-+ foreach $i (&get_labels())
-+ {
-+ $tmp.="#define $i _$i\n";
-+ }
-+ print <<"EOF";
-+/* Run the C pre-processor over this file with one of the following defined
-+ * ELF - elf object files,
-+ * OUT - a.out object files,
-+ * BSDI - BSDI style a.out object files
-+ * SOL - Solaris style elf
-+ */
-+
-+#define TYPE(a,b) .type a,b
-+#define SIZE(a,b) .size a,b
-+
-+#if defined(OUT) || defined(BSDI)
-+$tmp
-+#endif
-+
-+#ifdef OUT
-+#define OK 1
-+#define ALIGN 4
-+#endif
-+
-+#ifdef BSDI
-+#define OK 1
-+#define ALIGN 4
-+#undef SIZE
-+#undef TYPE
-+#endif
-+
-+#if defined(ELF) || defined(SOL)
-+#define OK 1
-+#define ALIGN 16
-+#endif
-+
-+#ifndef OK
-+You need to define one of
-+ELF - elf systems - linux-elf, NetBSD and DG-UX
-+OUT - a.out systems - linux-a.out and FreeBSD
-+SOL - solaris systems, which are elf with strange comment lines
-+BSDI - a.out with a very primative version of as.
-+#endif
-+
-+/* Let the Assembler begin :-) */
-+EOF
-+ }
-+
-+1;
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/perlasm/x86ms.pl Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,345 @@
-+#!/usr/bin/perl
-+
-+package x86ms;
-+
-+$label="L000";
-+
-+%lb=( 'eax', 'al',
-+ 'ebx', 'bl',
-+ 'ecx', 'cl',
-+ 'edx', 'dl',
-+ 'ax', 'al',
-+ 'bx', 'bl',
-+ 'cx', 'cl',
-+ 'dx', 'dl',
-+ );
-+
-+%hb=( 'eax', 'ah',
-+ 'ebx', 'bh',
-+ 'ecx', 'ch',
-+ 'edx', 'dh',
-+ 'ax', 'ah',
-+ 'bx', 'bh',
-+ 'cx', 'ch',
-+ 'dx', 'dh',
-+ );
-+
-+sub main'asm_init_output { @out=(); }
-+sub main'asm_get_output { return(@out); }
-+sub main'get_labels { return(@labels); }
-+sub main'external_label { push(@labels,@_); }
-+
-+sub main'LB
-+ {
-+ (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
-+ return($lb{$_[0]});
-+ }
-+
-+sub main'HB
-+ {
-+ (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
-+ return($hb{$_[0]});
-+ }
-+
-+sub main'BP
-+ {
-+ &get_mem("BYTE",@_);
-+ }
-+
-+sub main'DWP
-+ {
-+ &get_mem("DWORD",@_);
-+ }
-+
-+sub main'stack_push
-+ {
-+ local($num)=@_;
-+ $stack+=$num*4;
-+ &main'sub("esp",$num*4);
-+ }
-+
-+sub main'stack_pop
-+ {
-+ local($num)=@_;
-+ $stack-=$num*4;
-+ &main'add("esp",$num*4);
-+ }
-+
-+sub get_mem
-+ {
-+ local($size,$addr,$reg1,$reg2,$idx)=@_;
-+ local($t,$post);
-+ local($ret)="$size PTR ";
-+
-+ $addr =~ s/^\s+//;
-+ if ($addr =~ /^(.+)\+(.+)$/)
-+ {
-+ $reg2=&conv($1);
-+ $addr="_$2";
-+ }
-+ elsif ($addr =~ /^[_a-zA-Z]/)
-+ {
-+ $addr="_$addr";
-+ }
-+
-+ $reg1="$regs{$reg1}" if defined($regs{$reg1});
-+ $reg2="$regs{$reg2}" if defined($regs{$reg2});
-+ if (($addr ne "") && ($addr ne 0))
-+ {
-+ if ($addr !~ /^-/)
-+ { $ret.=$addr; }
-+ else { $post=$addr; }
-+ }
-+ if ($reg2 ne "")
-+ {
-+ $t="";
-+ $t="*$idx" if ($idx != 0);
-+ $reg1="+".$reg1 if ("$reg1$post" ne "");
-+ $ret.="[$reg2$t$reg1$post]";
-+ }
-+ else
-+ {
-+ $ret.="[$reg1$post]"
-+ }
-+ return($ret);
-+ }
-+
-+sub main'mov { &out2("mov",@_); }
-+sub main'movb { &out2("mov",@_); }
-+sub main'and { &out2("and",@_); }
-+sub main'or { &out2("or",@_); }
-+sub main'shl { &out2("shl",@_); }
-+sub main'shr { &out2("shr",@_); }
-+sub main'xor { &out2("xor",@_); }
-+sub main'xorb { &out2("xor",@_); }
-+sub main'add { &out2("add",@_); }
-+sub main'adc { &out2("adc",@_); }
-+sub main'sub { &out2("sub",@_); }
-+sub main'rotl { &out2("rol",@_); }
-+sub main'rotr { &out2("ror",@_); }
-+sub main'exch { &out2("xchg",@_); }
-+sub main'cmp { &out2("cmp",@_); }
-+sub main'lea { &out2("lea",@_); }
-+sub main'mul { &out1("mul",@_); }
-+sub main'div { &out1("div",@_); }
-+sub main'dec { &out1("dec",@_); }
-+sub main'inc { &out1("inc",@_); }
-+sub main'jmp { &out1("jmp",@_); }
-+sub main'jmp_ptr { &out1p("jmp",@_); }
-+sub main'je { &out1("je",@_); }
-+sub main'jle { &out1("jle",@_); }
-+sub main'jz { &out1("jz",@_); }
-+sub main'jge { &out1("jge",@_); }
-+sub main'jl { &out1("jl",@_); }
-+sub main'jb { &out1("jb",@_); }
-+sub main'jnz { &out1("jnz",@_); }
-+sub main'jne { &out1("jne",@_); }
-+sub main'push { &out1("push",@_); $stack+=4; }
-+sub main'pop { &out1("pop",@_); $stack-=4; }
-+sub main'bswap { &out1("bswap",@_); &using486(); }
-+sub main'not { &out1("not",@_); }
-+sub main'call { &out1("call",'_'.$_[0]); }
-+sub main'ret { &out0("ret"); }
-+sub main'nop { &out0("nop"); }
-+
-+sub out2
-+ {
-+ local($name,$p1,$p2)=@_;
-+ local($l,$t);
-+
-+ push(@out,"\t$name\t");
-+ $t=&conv($p1).",";
-+ $l=length($t);
-+ push(@out,$t);
-+ $l=4-($l+9)/8;
-+ push(@out,"\t" x $l);
-+ push(@out,&conv($p2));
-+ push(@out,"\n");
-+ }
-+
-+sub out0
-+ {
-+ local($name)=@_;
-+
-+ push(@out,"\t$name\n");
-+ }
-+
-+sub out1
-+ {
-+ local($name,$p1)=@_;
-+ local($l,$t);
-+
-+ push(@out,"\t$name\t".&conv($p1)."\n");
-+ }
-+
-+sub conv
-+ {
-+ local($p)=@_;
-+
-+ $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
-+ return $p;
-+ }
-+
-+sub using486
-+ {
-+ return if $using486;
-+ $using486++;
-+ grep(s/\.386/\.486/,@out);
-+ }
-+
-+sub main'file
-+ {
-+ local($file)=@_;
-+
-+ local($tmp)=<<"EOF";
-+ TITLE $file.asm
-+ .386
-+.model FLAT
-+EOF
-+ push(@out,$tmp);
-+ }
-+
-+sub main'function_begin
-+ {
-+ local($func,$extra)=@_;
-+
-+ push(@labels,$func);
-+
-+ local($tmp)=<<"EOF";
-+_TEXT SEGMENT
-+PUBLIC _$func
-+$extra
-+_$func PROC NEAR
-+ push ebp
-+ push ebx
-+ push esi
-+ push edi
-+EOF
-+ push(@out,$tmp);
-+ $stack=20;
-+ }
-+
-+sub main'function_begin_B
-+ {
-+ local($func,$extra)=@_;
-+
-+ local($tmp)=<<"EOF";
-+_TEXT SEGMENT
-+PUBLIC _$func
-+$extra
-+_$func PROC NEAR
-+EOF
-+ push(@out,$tmp);
-+ $stack=4;
-+ }
-+
-+sub main'function_end
-+ {
-+ local($func)=@_;
-+
-+ local($tmp)=<<"EOF";
-+ pop edi
-+ pop esi
-+ pop ebx
-+ pop ebp
-+ ret
-+_$func ENDP
-+_TEXT ENDS
-+EOF
-+ push(@out,$tmp);
-+ $stack=0;
-+ %label=();
-+ }
-+
-+sub main'function_end_B
-+ {
-+ local($func)=@_;
-+
-+ local($tmp)=<<"EOF";
-+_$func ENDP
-+_TEXT ENDS
-+EOF
-+ push(@out,$tmp);
-+ $stack=0;
-+ %label=();
-+ }
-+
-+sub main'function_end_A
-+ {
-+ local($func)=@_;
-+
-+ local($tmp)=<<"EOF";
-+ pop edi
-+ pop esi
-+ pop ebx
-+ pop ebp
-+ ret
-+EOF
-+ push(@out,$tmp);
-+ }
-+
-+sub main'file_end
-+ {
-+ push(@out,"END\n");
-+ }
-+
-+sub main'wparam
-+ {
-+ local($num)=@_;
-+
-+ return(&main'DWP($stack+$num*4,"esp","",0));
-+ }
-+
-+sub main'swtmp
-+ {
-+ return(&main'DWP($_[0]*4,"esp","",0));
-+ }
-+
-+# Should use swtmp, which is above esp. Linix can trash the stack above esp
-+#sub main'wtmp
-+# {
-+# local($num)=@_;
-+#
-+# return(&main'DWP(-(($num+1)*4),"esp","",0));
-+# }
-+
-+sub main'comment
-+ {
-+ foreach (@_)
-+ {
-+ push(@out,"\t; $_\n");
-+ }
-+ }
-+
-+sub main'label
-+ {
-+ if (!defined($label{$_[0]}))
-+ {
-+ $label{$_[0]}="\$${label}${_[0]}";
-+ $label++;
-+ }
-+ return($label{$_[0]});
-+ }
-+
-+sub main'set_label
-+ {
-+ if (!defined($label{$_[0]}))
-+ {
-+ $label{$_[0]}="${label}${_[0]}";
-+ $label++;
-+ }
-+ push(@out,"$label{$_[0]}:\n");
-+ }
-+
-+sub main'data_word
-+ {
-+ push(@out,"\tDD\t$_[0]\n");
-+ }
-+
-+sub out1p
-+ {
-+ local($name,$p1)=@_;
-+ local($l,$t);
-+
-+ push(@out,"\t$name\t ".&conv($p1)."\n");
-+ }
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/perlasm/x86unix.pl Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,403 @@
-+#!/usr/bin/perl
-+
-+package x86unix;
-+
-+$label="L000";
-+
-+$align=($main'aout)?"4":"16";
-+$under=($main'aout)?"_":"";
-+$com_start=($main'sol)?"/":"#";
-+
-+sub main'asm_init_output { @out=(); }
-+sub main'asm_get_output { return(@out); }
-+sub main'get_labels { return(@labels); }
-+sub main'external_label { push(@labels,@_); }
-+
-+if ($main'cpp)
-+ {
-+ $align="ALIGN";
-+ $under="";
-+ $com_start='/*';
-+ $com_end='*/';
-+ }
-+
-+%lb=( 'eax', '%al',
-+ 'ebx', '%bl',
-+ 'ecx', '%cl',
-+ 'edx', '%dl',
-+ 'ax', '%al',
-+ 'bx', '%bl',
-+ 'cx', '%cl',
-+ 'dx', '%dl',
-+ );
-+
-+%hb=( 'eax', '%ah',
-+ 'ebx', '%bh',
-+ 'ecx', '%ch',
-+ 'edx', '%dh',
-+ 'ax', '%ah',
-+ 'bx', '%bh',
-+ 'cx', '%ch',
-+ 'dx', '%dh',
-+ );
-+
-+%regs=( 'eax', '%eax',
-+ 'ebx', '%ebx',
-+ 'ecx', '%ecx',
-+ 'edx', '%edx',
-+ 'esi', '%esi',
-+ 'edi', '%edi',
-+ 'ebp', '%ebp',
-+ 'esp', '%esp',
-+ );
-+
-+%reg_val=(
-+ 'eax', 0x00,
-+ 'ebx', 0x03,
-+ 'ecx', 0x01,
-+ 'edx', 0x02,
-+ 'esi', 0x06,
-+ 'edi', 0x07,
-+ 'ebp', 0x05,
-+ 'esp', 0x04,
-+ );
-+
-+sub main'LB
-+ {
-+ (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
-+ return($lb{$_[0]});
-+ }
-+
-+sub main'HB
-+ {
-+ (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
-+ return($hb{$_[0]});
-+ }
-+
-+sub main'DWP
-+ {
-+ local($addr,$reg1,$reg2,$idx)=@_;
-+
-+ $ret="";
-+ $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/;
-+ $reg1="$regs{$reg1}" if defined($regs{$reg1});
-+ $reg2="$regs{$reg2}" if defined($regs{$reg2});
-+ $ret.=$addr if ($addr ne "") && ($addr ne 0);
-+ if ($reg2 ne "")
-+ { $ret.="($reg1,$reg2,$idx)"; }
-+ else
-+ { $ret.="($reg1)" }
-+ return($ret);
-+ }
-+
-+sub main'BP
-+ {
-+ return(&main'DWP(@_));
-+ }
-+
-+#sub main'BP
-+# {
-+# local($addr,$reg1,$reg2,$idx)=@_;
-+#
-+# $ret="";
-+#
-+# $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/;
-+# $reg1="$regs{$reg1}" if defined($regs{$reg1});
-+# $reg2="$regs{$reg2}" if defined($regs{$reg2});
-+# $ret.=$addr if ($addr ne "") && ($addr ne 0);
-+# if ($reg2 ne "")
-+# { $ret.="($reg1,$reg2,$idx)"; }
-+# else
-+# { $ret.="($reg1)" }
-+# return($ret);
-+# }
-+
-+sub main'mov { &out2("movl",@_); }
-+sub main'movb { &out2("movb",@_); }
-+sub main'and { &out2("andl",@_); }
-+sub main'or { &out2("orl",@_); }
-+sub main'shl { &out2("sall",@_); }
-+sub main'shr { &out2("shrl",@_); }
-+sub main'xor { &out2("xorl",@_); }
-+sub main'xorb { &out2("xorb",@_); }
-+sub main'add { &out2("addl",@_); }
-+sub main'adc { &out2("adcl",@_); }
-+sub main'sub { &out2("subl",@_); }
-+sub main'rotl { &out2("roll",@_); }
-+sub main'rotr { &out2("rorl",@_); }
-+sub main'exch { &out2("xchg",@_); }
-+sub main'cmp { &out2("cmpl",@_); }
-+sub main'lea { &out2("leal",@_); }
-+sub main'mul { &out1("mull",@_); }
-+sub main'div { &out1("divl",@_); }
-+sub main'jmp { &out1("jmp",@_); }
-+sub main'jmp_ptr { &out1p("jmp",@_); }
-+sub main'je { &out1("je",@_); }
-+sub main'jle { &out1("jle",@_); }
-+sub main'jne { &out1("jne",@_); }
-+sub main'jnz { &out1("jnz",@_); }
-+sub main'jz { &out1("jz",@_); }
-+sub main'jge { &out1("jge",@_); }
-+sub main'jl { &out1("jl",@_); }
-+sub main'jb { &out1("jb",@_); }
-+sub main'dec { &out1("decl",@_); }
-+sub main'inc { &out1("incl",@_); }
-+sub main'push { &out1("pushl",@_); $stack+=4; }
-+sub main'pop { &out1("popl",@_); $stack-=4; }
-+sub main'bswap { &out1("bswapl",@_); }
-+sub main'not { &out1("notl",@_); }
-+sub main'call { &out1("call",$under.$_[0]); }
-+sub main'ret { &out0("ret"); }
-+sub main'nop { &out0("nop"); }
-+
-+sub out2
-+ {
-+ local($name,$p1,$p2)=@_;
-+ local($l,$ll,$t);
-+ local(%special)=( "roll",0xD1C0,"rorl",0xD1C8,
-+ "rcll",0xD1D0,"rcrl",0xD1D8,
-+ "shll",0xD1E0,"shrl",0xD1E8,
-+ "sarl",0xD1F8);
-+
-+ if ((defined($special{$name})) && defined($regs{$p1}) && ($p2 == 1))
-+ {
-+ $op=$special{$name}|$reg_val{$p1};
-+ $tmp1=sprintf ".byte %d\n",($op>>8)&0xff;
-+ $tmp2=sprintf ".byte %d\t",$op &0xff;
-+ push(@out,$tmp1);
-+ push(@out,$tmp2);
-+
-+ $p2=&conv($p2);
-+ $p1=&conv($p1);
-+ &main'comment("$name $p2 $p1");
-+ return;
-+ }
-+
-+ push(@out,"\t$name\t");
-+ $t=&conv($p2).",";
-+ $l=length($t);
-+ push(@out,$t);
-+ $ll=4-($l+9)/8;
-+ $tmp1=sprintf "\t" x $ll;
-+ push(@out,$tmp1);
-+ push(@out,&conv($p1)."\n");
-+ }
-+
-+sub out1
-+ {
-+ local($name,$p1)=@_;
-+ local($l,$t);
-+
-+ push(@out,"\t$name\t".&conv($p1)."\n");
-+ }
-+
-+sub out1p
-+ {
-+ local($name,$p1)=@_;
-+ local($l,$t);
-+
-+ push(@out,"\t$name\t*".&conv($p1)."\n");
-+ }
-+
-+sub out0
-+ {
-+ push(@out,"\t$_[0]\n");
-+ }
-+
-+sub conv
-+ {
-+ local($p)=@_;
-+
-+# $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
-+
-+ $p=$regs{$p} if (defined($regs{$p}));
-+
-+ $p =~ s/^(-{0,1}[0-9A-Fa-f]+)$/\$$1/;
-+ $p =~ s/^(0x[0-9A-Fa-f]+)$/\$$1/;
-+ return $p;
-+ }
-+
-+sub main'file
-+ {
-+ local($file)=@_;
-+
-+ local($tmp)=<<"EOF";
-+ .file "$file.s"
-+ .version "01.01"
-+gcc2_compiled.:
-+EOF
-+ push(@out,$tmp);
-+ }
-+
-+sub main'function_begin
-+ {
-+ local($func)=@_;
-+
-+ $func=$under.$func;
-+
-+ local($tmp)=<<"EOF";
-+.text
-+ .align $align
-+.globl $func
-+EOF
-+ push(@out,$tmp);
-+ if ($main'cpp)
-+ { $tmp=push(@out,"\tTYPE($func,\@function)\n"); }
-+ else { $tmp=push(@out,"\t.type\t$func,\@function\n"); }
-+ push(@out,"$func:\n");
-+ $tmp=<<"EOF";
-+ pushl %ebp
-+ pushl %ebx
-+ pushl %esi
-+ pushl %edi
-+
-+EOF
-+ push(@out,$tmp);
-+ $stack=20;
-+ }
-+
-+sub main'function_begin_B
-+ {
-+ local($func,$extra)=@_;
-+
-+ $func=$under.$func;
-+
-+ local($tmp)=<<"EOF";
-+.text
-+ .align $align
-+.globl $func
-+EOF
-+ push(@out,$tmp);
-+ if ($main'cpp)
-+ { push(@out,"\tTYPE($func,\@function)\n"); }
-+ else { push(@out,"\t.type $func,\@function\n"); }
-+ push(@out,"$func:\n");
-+ $stack=4;
-+ }
-+
-+sub main'function_end
-+ {
-+ local($func)=@_;
-+
-+ $func=$under.$func;
-+
-+ local($tmp)=<<"EOF";
-+ popl %edi
-+ popl %esi
-+ popl %ebx
-+ popl %ebp
-+ ret
-+.${func}_end:
-+EOF
-+ push(@out,$tmp);
-+ if ($main'cpp)
-+ { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); }
-+ else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); }
-+ push(@out,".ident \"$func\"\n");
-+ $stack=0;
-+ %label=();
-+ }
-+
-+sub main'function_end_A
-+ {
-+ local($func)=@_;
-+
-+ local($tmp)=<<"EOF";
-+ popl %edi
-+ popl %esi
-+ popl %ebx
-+ popl %ebp
-+ ret
-+EOF
-+ push(@out,$tmp);
-+ }
-+
-+sub main'function_end_B
-+ {
-+ local($func)=@_;
-+
-+ $func=$under.$func;
-+
-+ push(@out,".${func}_end:\n");
-+ if ($main'cpp)
-+ { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); }
-+ else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); }
-+ push(@out,".ident \"desasm.pl\"\n");
-+ $stack=0;
-+ %label=();
-+ }
-+
-+sub main'wparam
-+ {
-+ local($num)=@_;
-+
-+ return(&main'DWP($stack+$num*4,"esp","",0));
-+ }
-+
-+sub main'stack_push
-+ {
-+ local($num)=@_;
-+ $stack+=$num*4;
-+ &main'sub("esp",$num*4);
-+ }
-+
-+sub main'stack_pop
-+ {
-+ local($num)=@_;
-+ $stack-=$num*4;
-+ &main'add("esp",$num*4);
-+ }
-+
-+sub main'swtmp
-+ {
-+ return(&main'DWP($_[0]*4,"esp","",0));
-+ }
-+
-+# Should use swtmp, which is above esp. Linix can trash the stack above esp
-+#sub main'wtmp
-+# {
-+# local($num)=@_;
-+#
-+# return(&main'DWP(-($num+1)*4,"esp","",0));
-+# }
-+
-+sub main'comment
-+ {
-+ foreach (@_)
-+ {
-+ if (/^\s*$/)
-+ { push(@out,"\n"); }
-+ else
-+ { push(@out,"\t$com_start $_ $com_end\n"); }
-+ }
-+ }
-+
-+sub main'label
-+ {
-+ if (!defined($label{$_[0]}))
-+ {
-+ $label{$_[0]}=".${label}${_[0]}";
-+ $label++;
-+ }
-+ return($label{$_[0]});
-+ }
-+
-+sub main'set_label
-+ {
-+ if (!defined($label{$_[0]}))
-+ {
-+ $label{$_[0]}=".${label}${_[0]}";
-+ $label++;
-+ }
-+ push(@out,".align $align\n") if ($_[1] != 0);
-+ push(@out,"$label{$_[0]}:\n");
-+ }
-+
-+sub main'file_end
-+ {
-+ }
-+
-+sub main'data_word
-+ {
-+ push(@out,"\t.long $_[0]\n");
-+ }
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/readme Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,131 @@
-+First up, let me say I don't like writing in assembler. It is not portable,
-+dependant on the particular CPU architecture release and is generally a pig
-+to debug and get right. Having said that, the x86 architecture is probably
-+the most important for speed due to number of boxes and since
-+it appears to be the worst architecture to to get
-+good C compilers for. So due to this, I have lowered myself to do
-+assembler for the inner DES routines in libdes :-).
-+
-+The file to implement in assembler is des_enc.c. Replace the following
-+4 functions
-+des_encrypt(DES_LONG data[2],des_key_schedule ks, int encrypt);
-+des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt);
-+des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
-+des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
-+
-+They encrypt/decrypt the 64 bits held in 'data' using
-+the 'ks' key schedules. The only difference between the 4 functions is that
-+des_encrypt2() does not perform IP() or FP() on the data (this is an
-+optimization for when doing triple DES and des_encrypt3() and des_decrypt3()
-+perform triple des. The triple DES routines are in here because it does
-+make a big difference to have them located near the des_encrypt2 function
-+at link time..
-+
-+Now as we all know, there are lots of different operating systems running on
-+x86 boxes, and unfortunately they normally try to make sure their assembler
-+formating is not the same as the other peoples.
-+The 4 main formats I know of are
-+Microsoft Windows 95/Windows NT
-+Elf Includes Linux and FreeBSD(?).
-+a.out The older Linux.
-+Solaris Same as Elf but different comments :-(.
-+
-+Now I was not overly keen to write 4 different copies of the same code,
-+so I wrote a few perl routines to output the correct assembler, given
-+a target assembler type. This code is ugly and is just a hack.
-+The libraries are x86unix.pl and x86ms.pl.
-+des586.pl, des686.pl and des-som[23].pl are the programs to actually
-+generate the assembler.
-+
-+So to generate elf assembler
-+perl des-som3.pl elf >dx86-elf.s
-+For Windows 95/NT
-+perl des-som2.pl win32 >win32.asm
-+
-+[ update 4 Jan 1996 ]
-+I have added another way to do things.
-+perl des-som3.pl cpp >dx86-cpp.s
-+generates a file that will be included by dx86unix.cpp when it is compiled.
-+To build for elf, a.out, solaris, bsdi etc,
-+cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o
-+cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o
-+cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o
-+cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o
-+This was done to cut down the number of files in the distribution.
-+
-+Now the ugly part. I acquired my copy of Intels
-+"Optimization's For Intel's 32-Bit Processors" and found a few interesting
-+things. First, the aim of the exersize is to 'extract' one byte at a time
-+from a word and do an array lookup. This involves getting the byte from
-+the 4 locations in the word and moving it to a new word and doing the lookup.
-+The most obvious way to do this is
-+xor eax, eax # clear word
-+movb al, cl # get low byte
-+xor edi DWORD PTR 0x100+des_SP[eax] # xor in word
-+movb al, ch # get next byte
-+xor edi DWORD PTR 0x300+des_SP[eax] # xor in word
-+shr ecx 16
-+which seems ok. For the pentium, this system appears to be the best.
-+One has to do instruction interleaving to keep both functional units
-+operating, but it is basically very efficient.
-+
-+Now the crunch. When a full register is used after a partial write, eg.
-+mov al, cl
-+xor edi, DWORD PTR 0x100+des_SP[eax]
-+386 - 1 cycle stall
-+486 - 1 cycle stall
-+586 - 0 cycle stall
-+686 - at least 7 cycle stall (page 22 of the above mentioned document).
-+
-+So the technique that produces the best results on a pentium, according to
-+the documentation, will produce hideous results on a pentium pro.
-+
-+To get around this, des686.pl will generate code that is not as fast on
-+a pentium, should be very good on a pentium pro.
-+mov eax, ecx # copy word
-+shr ecx, 8 # line up next byte
-+and eax, 0fch # mask byte
-+xor edi DWORD PTR 0x100+des_SP[eax] # xor in array lookup
-+mov eax, ecx # get word
-+shr ecx 8 # line up next byte
-+and eax, 0fch # mask byte
-+xor edi DWORD PTR 0x300+des_SP[eax] # xor in array lookup
-+
-+Due to the execution units in the pentium, this actually works quite well.
-+For a pentium pro it should be very good. This is the type of output
-+Visual C++ generates.
-+
-+There is a third option. instead of using
-+mov al, ch
-+which is bad on the pentium pro, one may be able to use
-+movzx eax, ch
-+which may not incur the partial write penalty. On the pentium,
-+this instruction takes 4 cycles so is not worth using but on the
-+pentium pro it appears it may be worth while. I need access to one to
-+experiment :-).
-+
-+eric (20 Oct 1996)
-+
-+22 Nov 1996 - I have asked people to run the 2 different version on pentium
-+pros and it appears that the intel documentation is wrong. The
-+mov al,bh is still faster on a pentium pro, so just use the des586.pl
-+install des686.pl
-+
-+3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these
-+functions into des_enc.c because it does make a massive performance
-+difference on some boxes to have the functions code located close to
-+the des_encrypt2() function.
-+
-+9 Jan 1997 - des-som2.pl is now the correct perl script to use for
-+pentiums. It contains an inner loop from
-+Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> which does raw ecb DES calls at
-+273,000 per second. He had a previous version at 250,000 and the best
-+I was able to get was 203,000. The content has not changed, this is all
-+due to instruction sequencing (and actual instructions choice) which is able
-+to keep both functional units of the pentium going.
-+We may have lost the ugly register usage restrictions when x86 went 32 bit
-+but for the pentium it has been replaced by evil instruction ordering tricks.
-+
-+13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf.
-+raw DES at 281,000 per second on a pentium 100.
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/cbc_enc.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,135 @@
-+/* crypto/des/cbc_enc.c */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+#include "des_locl.h"
-+
-+void des_cbc_encrypt(input, output, length, schedule, ivec, enc)
-+des_cblock (*input);
-+des_cblock (*output);
-+long length;
-+des_key_schedule schedule;
-+des_cblock (*ivec);
-+int enc;
-+ {
-+ register DES_LONG tin0,tin1;
-+ register DES_LONG tout0,tout1,xor0,xor1;
-+ register unsigned char *in,*out;
-+ register long l=length;
-+ DES_LONG tin[2];
-+ unsigned char *iv;
-+
-+ in=(unsigned char *)input;
-+ out=(unsigned char *)output;
-+ iv=(unsigned char *)ivec;
-+
-+ if (enc)
-+ {
-+ c2l(iv,tout0);
-+ c2l(iv,tout1);
-+ for (l-=8; l>=0; l-=8)
-+ {
-+ c2l(in,tin0);
-+ c2l(in,tin1);
-+ tin0^=tout0; tin[0]=tin0;
-+ tin1^=tout1; tin[1]=tin1;
-+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
-+ tout0=tin[0]; l2c(tout0,out);
-+ tout1=tin[1]; l2c(tout1,out);
-+ }
-+ if (l != -8)
-+ {
-+ c2ln(in,tin0,tin1,l+8);
-+ tin0^=tout0; tin[0]=tin0;
-+ tin1^=tout1; tin[1]=tin1;
-+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
-+ tout0=tin[0]; l2c(tout0,out);
-+ tout1=tin[1]; l2c(tout1,out);
-+ }
-+ }
-+ else
-+ {
-+ c2l(iv,xor0);
-+ c2l(iv,xor1);
-+ for (l-=8; l>=0; l-=8)
-+ {
-+ c2l(in,tin0); tin[0]=tin0;
-+ c2l(in,tin1); tin[1]=tin1;
-+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
-+ tout0=tin[0]^xor0;
-+ tout1=tin[1]^xor1;
-+ l2c(tout0,out);
-+ l2c(tout1,out);
-+ xor0=tin0;
-+ xor1=tin1;
-+ }
-+ if (l != -8)
-+ {
-+ c2l(in,tin0); tin[0]=tin0;
-+ c2l(in,tin1); tin[1]=tin1;
-+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
-+ tout0=tin[0]^xor0;
-+ tout1=tin[1]^xor1;
-+ l2cn(tout0,tout1,out,l+8);
-+ /* xor0=tin0;
-+ xor1=tin1; */
-+ }
-+ }
-+ tin0=tin1=tout0=tout1=xor0=xor1=0;
-+ tin[0]=tin[1]=0;
-+ }
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/des.doc Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,505 @@
-+The DES library.
-+
-+Please note that this library was originally written to operate with
-+eBones, a version of Kerberos that had had encryption removed when it left
-+the USA and then put back in. As such there are some routines that I will
-+advise not using but they are still in the library for historical reasons.
-+For all calls that have an 'input' and 'output' variables, they can be the
-+same.
-+
-+This library requires the inclusion of 'des.h'.
-+
-+All of the encryption functions take what is called a des_key_schedule as an
-+argument. A des_key_schedule is an expanded form of the des key.
-+A des_key is 8 bytes of odd parity, the type used to hold the key is a
-+des_cblock. A des_cblock is an array of 8 bytes, often in this library
-+description I will refer to input bytes when the function specifies
-+des_cblock's as input or output, this just means that the variable should
-+be a multiple of 8 bytes.
-+
-+The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to
-+specify decryption. The functions and global variable are as follows:
-+
-+int des_check_key;
-+ DES keys are supposed to be odd parity. If this variable is set to
-+ a non-zero value, des_set_key() will check that the key has odd
-+ parity and is not one of the known weak DES keys. By default this
-+ variable is turned off;
-+
-+void des_set_odd_parity(
-+des_cblock *key );
-+ This function takes a DES key (8 bytes) and sets the parity to odd.
-+
-+int des_is_weak_key(
-+des_cblock *key );
-+ This function returns a non-zero value if the DES key passed is a
-+ weak, DES key. If it is a weak key, don't use it, try a different
-+ one. If you are using 'random' keys, the chances of hitting a weak
-+ key are 1/2^52 so it is probably not worth checking for them.
-+
-+int des_set_key(
-+des_cblock *key,
-+des_key_schedule schedule);
-+ Des_set_key converts an 8 byte DES key into a des_key_schedule.
-+ A des_key_schedule is an expanded form of the key which is used to
-+ perform actual encryption. It can be regenerated from the DES key
-+ so it only needs to be kept when encryption or decryption is about
-+ to occur. Don't save or pass around des_key_schedule's since they
-+ are CPU architecture dependent, DES keys are not. If des_check_key
-+ is non zero, zero is returned if the key has the wrong parity or
-+ the key is a weak key, else 1 is returned.
-+
-+int des_key_sched(
-+des_cblock *key,
-+des_key_schedule schedule);
-+ An alternative name for des_set_key().
-+
-+int des_rw_mode; /* defaults to DES_PCBC_MODE */
-+ This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default).
-+ This specifies the function to use in the enc_read() and enc_write()
-+ functions.
-+
-+void des_encrypt(
-+unsigned long *data,
-+des_key_schedule ks,
-+int enc);
-+ This is the DES encryption function that gets called by just about
-+ every other DES routine in the library. You should not use this
-+ function except to implement 'modes' of DES. I say this because the
-+ functions that call this routine do the conversion from 'char *' to
-+ long, and this needs to be done to make sure 'non-aligned' memory
-+ access do not occur. The characters are loaded 'little endian',
-+ have a look at my source code for more details on how I use this
-+ function.
-+ Data is a pointer to 2 unsigned long's and ks is the
-+ des_key_schedule to use. enc, is non zero specifies encryption,
-+ zero if decryption.
-+
-+void des_encrypt2(
-+unsigned long *data,
-+des_key_schedule ks,
-+int enc);
-+ This functions is the same as des_encrypt() except that the DES
-+ initial permutation (IP) and final permutation (FP) have been left
-+ out. As for des_encrypt(), you should not use this function.
-+ It is used by the routines in my library that implement triple DES.
-+ IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same
-+ as des_encrypt() des_encrypt() des_encrypt() except faster :-).
-+
-+void des_ecb_encrypt(
-+des_cblock *input,
-+des_cblock *output,
-+des_key_schedule ks,
-+int enc);
-+ This is the basic Electronic Code Book form of DES, the most basic
-+ form. Input is encrypted into output using the key represented by
-+ ks. If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise
-+ decryption occurs. Input is 8 bytes long and output is 8 bytes.
-+ (the des_cblock structure is 8 chars).
-+
-+void des_ecb3_encrypt(
-+des_cblock *input,
-+des_cblock *output,
-+des_key_schedule ks1,
-+des_key_schedule ks2,
-+des_key_schedule ks3,
-+int enc);
-+ This is the 3 key EDE mode of ECB DES. What this means is that
-+ the 8 bytes of input is encrypted with ks1, decrypted with ks2 and
-+ then encrypted again with ks3, before being put into output;
-+ C=E(ks3,D(ks2,E(ks1,M))). There is a macro, des_ecb2_encrypt()
-+ that only takes 2 des_key_schedules that implements,
-+ C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1.
-+
-+void des_cbc_encrypt(
-+des_cblock *input,
-+des_cblock *output,
-+long length,
-+des_key_schedule ks,
-+des_cblock *ivec,
-+int enc);
-+ This routine implements DES in Cipher Block Chaining mode.
-+ Input, which should be a multiple of 8 bytes is encrypted
-+ (or decrypted) to output which will also be a multiple of 8 bytes.
-+ The number of bytes is in length (and from what I've said above,
-+ should be a multiple of 8). If length is not a multiple of 8, I'm
-+ not being held responsible :-). ivec is the initialisation vector.
-+ This function does not modify this variable. To correctly implement
-+ cbc mode, you need to do one of 2 things; copy the last 8 bytes of
-+ cipher text for use as the next ivec in your application,
-+ or use des_ncbc_encrypt().
-+ Only this routine has this problem with updating the ivec, all
-+ other routines that are implementing cbc mode update ivec.
-+
-+void des_ncbc_encrypt(
-+des_cblock *input,
-+des_cblock *output,
-+long length,
-+des_key_schedule sk,
-+des_cblock *ivec,
-+int enc);
-+ For historical reasons, des_cbc_encrypt() did not update the
-+ ivec with the value requires so that subsequent calls to
-+ des_cbc_encrypt() would 'chain'. This was needed so that the same
-+ 'length' values would not need to be used when decrypting.
-+ des_ncbc_encrypt() does the right thing. It is the same as
-+ des_cbc_encrypt accept that ivec is updates with the correct value
-+ to pass in subsequent calls to des_ncbc_encrypt(). I advise using
-+ des_ncbc_encrypt() instead of des_cbc_encrypt();
-+
-+void des_xcbc_encrypt(
-+des_cblock *input,
-+des_cblock *output,
-+long length,
-+des_key_schedule sk,
-+des_cblock *ivec,
-+des_cblock *inw,
-+des_cblock *outw,
-+int enc);
-+ This is RSA's DESX mode of DES. It uses inw and outw to
-+ 'whiten' the encryption. inw and outw are secret (unlike the iv)
-+ and are as such, part of the key. So the key is sort of 24 bytes.
-+ This is much better than cbc des.
-+
-+void des_3cbc_encrypt(
-+des_cblock *input,
-+des_cblock *output,
-+long length,
-+des_key_schedule sk1,
-+des_key_schedule sk2,
-+des_cblock *ivec1,
-+des_cblock *ivec2,
-+int enc);
-+ This function is flawed, do not use it. I have left it in the
-+ library because it is used in my des(1) program and will function
-+ correctly when used by des(1). If I removed the function, people
-+ could end up unable to decrypt files.
-+ This routine implements outer triple cbc encryption using 2 ks and
-+ 2 ivec's. Use des_ede2_cbc_encrypt() instead.
-+
-+void des_ede3_cbc_encrypt(
-+des_cblock *input,
-+des_cblock *output,
-+long length,
-+des_key_schedule ks1,
-+des_key_schedule ks2,
-+des_key_schedule ks3,
-+des_cblock *ivec,
-+int enc);
-+ This function implements inner triple CBC DES encryption with 3
-+ keys. What this means is that each 'DES' operation
-+ inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))).
-+ Again, this is cbc mode so an ivec is requires.
-+ This mode is used by SSL.
-+ There is also a des_ede2_cbc_encrypt() that only uses 2
-+ des_key_schedule's, the first being reused for the final
-+ encryption. C=E(ks1,D(ks2,E(ks1,M))). This form of triple DES
-+ is used by the RSAref library.
-+
-+void des_pcbc_encrypt(
-+des_cblock *input,
-+des_cblock *output,
-+long length,
-+des_key_schedule ks,
-+des_cblock *ivec,
-+int enc);
-+ This is Propagating Cipher Block Chaining mode of DES. It is used
-+ by Kerberos v4. It's parameters are the same as des_ncbc_encrypt().
-+
-+void des_cfb_encrypt(
-+unsigned char *in,
-+unsigned char *out,
-+int numbits,
-+long length,
-+des_key_schedule ks,
-+des_cblock *ivec,
-+int enc);
-+ Cipher Feedback Back mode of DES. This implementation 'feeds back'
-+ in numbit blocks. The input (and output) is in multiples of numbits
-+ bits. numbits should to be a multiple of 8 bits. Length is the
-+ number of bytes input. If numbits is not a multiple of 8 bits,
-+ the extra bits in the bytes will be considered padding. So if
-+ numbits is 12, for each 2 input bytes, the 4 high bits of the
-+ second byte will be ignored. So to encode 72 bits when using
-+ a numbits of 12 take 12 bytes. To encode 72 bits when using
-+ numbits of 9 will take 16 bytes. To encode 80 bits when using
-+ numbits of 16 will take 10 bytes. etc, etc. This padding will
-+ apply to both input and output.
-+
-+
-+void des_cfb64_encrypt(
-+unsigned char *in,
-+unsigned char *out,
-+long length,
-+des_key_schedule ks,
-+des_cblock *ivec,
-+int *num,
-+int enc);
-+ This is one of the more useful functions in this DES library, it
-+ implements CFB mode of DES with 64bit feedback. Why is this
-+ useful you ask? Because this routine will allow you to encrypt an
-+ arbitrary number of bytes, no 8 byte padding. Each call to this
-+ routine will encrypt the input bytes to output and then update ivec
-+ and num. num contains 'how far' we are though ivec. If this does
-+ not make much sense, read more about cfb mode of DES :-).
-+
-+void des_ede3_cfb64_encrypt(
-+unsigned char *in,
-+unsigned char *out,
-+long length,
-+des_key_schedule ks1,
-+des_key_schedule ks2,
-+des_key_schedule ks3,
-+des_cblock *ivec,
-+int *num,
-+int enc);
-+ Same as des_cfb64_encrypt() accept that the DES operation is
-+ triple DES. As usual, there is a macro for
-+ des_ede2_cfb64_encrypt() which reuses ks1.
-+
-+void des_ofb_encrypt(
-+unsigned char *in,
-+unsigned char *out,
-+int numbits,
-+long length,
-+des_key_schedule ks,
-+des_cblock *ivec);
-+ This is a implementation of Output Feed Back mode of DES. It is
-+ the same as des_cfb_encrypt() in that numbits is the size of the
-+ units dealt with during input and output (in bits).
-+
-+void des_ofb64_encrypt(
-+unsigned char *in,
-+unsigned char *out,
-+long length,
-+des_key_schedule ks,
-+des_cblock *ivec,
-+int *num);
-+ The same as des_cfb64_encrypt() except that it is Output Feed Back
-+ mode.
-+
-+void des_ede3_ofb64_encrypt(
-+unsigned char *in,
-+unsigned char *out,
-+long length,
-+des_key_schedule ks1,
-+des_key_schedule ks2,
-+des_key_schedule ks3,
-+des_cblock *ivec,
-+int *num);
-+ Same as des_ofb64_encrypt() accept that the DES operation is
-+ triple DES. As usual, there is a macro for
-+ des_ede2_ofb64_encrypt() which reuses ks1.
-+
-+int des_read_pw_string(
-+char *buf,
-+int length,
-+char *prompt,
-+int verify);
-+ This routine is used to get a password from the terminal with echo
-+ turned off. Buf is where the string will end up and length is the
-+ size of buf. Prompt is a string presented to the 'user' and if
-+ verify is set, the key is asked for twice and unless the 2 copies
-+ match, an error is returned. A return code of -1 indicates a
-+ system error, 1 failure due to use interaction, and 0 is success.
-+
-+unsigned long des_cbc_cksum(
-+des_cblock *input,
-+des_cblock *output,
-+long length,
-+des_key_schedule ks,
-+des_cblock *ivec);
-+ This function produces an 8 byte checksum from input that it puts in
-+ output and returns the last 4 bytes as a long. The checksum is
-+ generated via cbc mode of DES in which only the last 8 byes are
-+ kept. I would recommend not using this function but instead using
-+ the EVP_Digest routines, or at least using MD5 or SHA. This
-+ function is used by Kerberos v4 so that is why it stays in the
-+ library.
-+
-+char *des_fcrypt(
-+const char *buf,
-+const char *salt
-+char *ret);
-+ This is my fast version of the unix crypt(3) function. This version
-+ takes only a small amount of space relative to other fast
-+ crypt() implementations. This is different to the normal crypt
-+ in that the third parameter is the buffer that the return value
-+ is written into. It needs to be at least 14 bytes long. This
-+ function is thread safe, unlike the normal crypt.
-+
-+char *crypt(
-+const char *buf,
-+const char *salt);
-+ This function calls des_fcrypt() with a static array passed as the
-+ third parameter. This emulates the normal non-thread safe semantics
-+ of crypt(3).
-+
-+void des_string_to_key(
-+char *str,
-+des_cblock *key);
-+ This function takes str and converts it into a DES key. I would
-+ recommend using MD5 instead and use the first 8 bytes of output.
-+ When I wrote the first version of these routines back in 1990, MD5
-+ did not exist but I feel these routines are still sound. This
-+ routines is compatible with the one in MIT's libdes.
-+
-+void des_string_to_2keys(
-+char *str,
-+des_cblock *key1,
-+des_cblock *key2);
-+ This function takes str and converts it into 2 DES keys.
-+ I would recommend using MD5 and using the 16 bytes as the 2 keys.
-+ I have nothing against these 2 'string_to_key' routines, it's just
-+ that if you say that your encryption key is generated by using the
-+ 16 bytes of an MD5 hash, every-one knows how you generated your
-+ keys.
-+
-+int des_read_password(
-+des_cblock *key,
-+char *prompt,
-+int verify);
-+ This routine combines des_read_pw_string() with des_string_to_key().
-+
-+int des_read_2passwords(
-+des_cblock *key1,
-+des_cblock *key2,
-+char *prompt,
-+int verify);
-+ This routine combines des_read_pw_string() with des_string_to_2key().
-+
-+void des_random_seed(
-+des_cblock key);
-+ This routine sets a starting point for des_random_key().
-+
-+void des_random_key(
-+des_cblock ret);
-+ This function return a random key. Make sure to 'seed' the random
-+ number generator (with des_random_seed()) before using this function.
-+ I personally now use a MD5 based random number system.
-+
-+int des_enc_read(
-+int fd,
-+char *buf,
-+int len,
-+des_key_schedule ks,
-+des_cblock *iv);
-+ This function will write to a file descriptor the encrypted data
-+ from buf. This data will be preceded by a 4 byte 'byte count' and
-+ will be padded out to 8 bytes. The encryption is either CBC of
-+ PCBC depending on the value of des_rw_mode. If it is DES_PCBC_MODE,
-+ pcbc is used, if DES_CBC_MODE, cbc is used. The default is to use
-+ DES_PCBC_MODE.
-+
-+int des_enc_write(
-+int fd,
-+char *buf,
-+int len,
-+des_key_schedule ks,
-+des_cblock *iv);
-+ This routines read stuff written by des_enc_read() and decrypts it.
-+ I have used these routines quite a lot but I don't believe they are
-+ suitable for non-blocking io. If you are after a full
-+ authentication/encryption over networks, have a look at SSL instead.
-+
-+unsigned long des_quad_cksum(
-+des_cblock *input,
-+des_cblock *output,
-+long length,
-+int out_count,
-+des_cblock *seed);
-+ This is a function from Kerberos v4 that is not anything to do with
-+ DES but was needed. It is a cksum that is quicker to generate than
-+ des_cbc_cksum(); I personally would use MD5 routines now.
-+=====
-+Modes of DES
-+Quite a bit of the following information has been taken from
-+ AS 2805.5.2
-+ Australian Standard
-+ Electronic funds transfer - Requirements for interfaces,
-+ Part 5.2: Modes of operation for an n-bit block cipher algorithm
-+ Appendix A
-+
-+There are several different modes in which DES can be used, they are
-+as follows.
-+
-+Electronic Codebook Mode (ECB) (des_ecb_encrypt())
-+- 64 bits are enciphered at a time.
-+- The order of the blocks can be rearranged without detection.
-+- The same plaintext block always produces the same ciphertext block
-+ (for the same key) making it vulnerable to a 'dictionary attack'.
-+- An error will only affect one ciphertext block.
-+
-+Cipher Block Chaining Mode (CBC) (des_cbc_encrypt())
-+- a multiple of 64 bits are enciphered at a time.
-+- The CBC mode produces the same ciphertext whenever the same
-+ plaintext is encrypted using the same key and starting variable.
-+- The chaining operation makes the ciphertext blocks dependent on the
-+ current and all preceding plaintext blocks and therefore blocks can not
-+ be rearranged.
-+- The use of different starting variables prevents the same plaintext
-+ enciphering to the same ciphertext.
-+- An error will affect the current and the following ciphertext blocks.
-+
-+Cipher Feedback Mode (CFB) (des_cfb_encrypt())
-+- a number of bits (j) <= 64 are enciphered at a time.
-+- The CFB mode produces the same ciphertext whenever the same
-+ plaintext is encrypted using the same key and starting variable.
-+- The chaining operation makes the ciphertext variables dependent on the
-+ current and all preceding variables and therefore j-bit variables are
-+ chained together and can not be rearranged.
-+- The use of different starting variables prevents the same plaintext
-+ enciphering to the same ciphertext.
-+- The strength of the CFB mode depends on the size of k (maximal if
-+ j == k). In my implementation this is always the case.
-+- Selection of a small value for j will require more cycles through
-+ the encipherment algorithm per unit of plaintext and thus cause
-+ greater processing overheads.
-+- Only multiples of j bits can be enciphered.
-+- An error will affect the current and the following ciphertext variables.
-+
-+Output Feedback Mode (OFB) (des_ofb_encrypt())
-+- a number of bits (j) <= 64 are enciphered at a time.
-+- The OFB mode produces the same ciphertext whenever the same
-+ plaintext enciphered using the same key and starting variable. More
-+ over, in the OFB mode the same key stream is produced when the same
-+ key and start variable are used. Consequently, for security reasons
-+ a specific start variable should be used only once for a given key.
-+- The absence of chaining makes the OFB more vulnerable to specific attacks.
-+- The use of different start variables values prevents the same
-+ plaintext enciphering to the same ciphertext, by producing different
-+ key streams.
-+- Selection of a small value for j will require more cycles through
-+ the encipherment algorithm per unit of plaintext and thus cause
-+ greater processing overheads.
-+- Only multiples of j bits can be enciphered.
-+- OFB mode of operation does not extend ciphertext errors in the
-+ resultant plaintext output. Every bit error in the ciphertext causes
-+ only one bit to be in error in the deciphered plaintext.
-+- OFB mode is not self-synchronising. If the two operation of
-+ encipherment and decipherment get out of synchronism, the system needs
-+ to be re-initialised.
-+- Each re-initialisation should use a value of the start variable
-+ different from the start variable values used before with the same
-+ key. The reason for this is that an identical bit stream would be
-+ produced each time from the same parameters. This would be
-+ susceptible to a ' known plaintext' attack.
-+
-+Triple ECB Mode (des_ecb3_encrypt())
-+- Encrypt with key1, decrypt with key2 and encrypt with key3 again.
-+- As for ECB encryption but increases the key length to 168 bits.
-+ There are theoretic attacks that can be used that make the effective
-+ key length 112 bits, but this attack also requires 2^56 blocks of
-+ memory, not very likely, even for the NSA.
-+- If both keys are the same it is equivalent to encrypting once with
-+ just one key.
-+- If the first and last key are the same, the key length is 112 bits.
-+ There are attacks that could reduce the key space to 55 bit's but it
-+ requires 2^56 blocks of memory.
-+- If all 3 keys are the same, this is effectively the same as normal
-+ ecb mode.
-+
-+Triple CBC Mode (des_ede3_cbc_encrypt())
-+- Encrypt with key1, decrypt with key2 and then encrypt with key3.
-+- As for CBC encryption but increases the key length to 168 bits with
-+ the same restrictions as for triple ecb mode.
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/des_crypt.man Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,508 @@
-+.TH DES_CRYPT 3
-+.SH NAME
-+des_read_password, des_read_2password,
-+des_string_to_key, des_string_to_2key, des_read_pw_string,
-+des_random_key, des_set_key,
-+des_key_sched, des_ecb_encrypt, des_ecb3_encrypt, des_cbc_encrypt,
-+des_3cbc_encrypt,
-+des_pcbc_encrypt, des_cfb_encrypt, des_ofb_encrypt,
-+des_cbc_cksum, des_quad_cksum,
-+des_enc_read, des_enc_write, des_set_odd_parity,
-+des_is_weak_key, crypt \- (non USA) DES encryption
-+.SH SYNOPSIS
-+.nf
-+.nj
-+.ft B
-+#include <des.h>
-+.PP
-+.B int des_read_password(key,prompt,verify)
-+des_cblock *key;
-+char *prompt;
-+int verify;
-+.PP
-+.B int des_read_2password(key1,key2,prompt,verify)
-+des_cblock *key1,*key2;
-+char *prompt;
-+int verify;
-+.PP
-+.B int des_string_to_key(str,key)
-+char *str;
-+des_cblock *key;
-+.PP
-+.B int des_string_to_2keys(str,key1,key2)
-+char *str;
-+des_cblock *key1,*key2;
-+.PP
-+.B int des_read_pw_string(buf,length,prompt,verify)
-+char *buf;
-+int length;
-+char *prompt;
-+int verify;
-+.PP
-+.B int des_random_key(key)
-+des_cblock *key;
-+.PP
-+.B int des_set_key(key,schedule)
-+des_cblock *key;
-+des_key_schedule schedule;
-+.PP
-+.B int des_key_sched(key,schedule)
-+des_cblock *key;
-+des_key_schedule schedule;
-+.PP
-+.B int des_ecb_encrypt(input,output,schedule,encrypt)
-+des_cblock *input;
-+des_cblock *output;
-+des_key_schedule schedule;
-+int encrypt;
-+.PP
-+.B int des_ecb3_encrypt(input,output,ks1,ks2,encrypt)
-+des_cblock *input;
-+des_cblock *output;
-+des_key_schedule ks1,ks2;
-+int encrypt;
-+.PP
-+.B int des_cbc_encrypt(input,output,length,schedule,ivec,encrypt)
-+des_cblock *input;
-+des_cblock *output;
-+long length;
-+des_key_schedule schedule;
-+des_cblock *ivec;
-+int encrypt;
-+.PP
-+.B int des_3cbc_encrypt(input,output,length,sk1,sk2,ivec1,ivec2,encrypt)
-+des_cblock *input;
-+des_cblock *output;
-+long length;
-+des_key_schedule sk1;
-+des_key_schedule sk2;
-+des_cblock *ivec1;
-+des_cblock *ivec2;
-+int encrypt;
-+.PP
-+.B int des_pcbc_encrypt(input,output,length,schedule,ivec,encrypt)
-+des_cblock *input;
-+des_cblock *output;
-+long length;
-+des_key_schedule schedule;
-+des_cblock *ivec;
-+int encrypt;
-+.PP
-+.B int des_cfb_encrypt(input,output,numbits,length,schedule,ivec,encrypt)
-+unsigned char *input;
-+unsigned char *output;
-+int numbits;
-+long length;
-+des_key_schedule schedule;
-+des_cblock *ivec;
-+int encrypt;
-+.PP
-+.B int des_ofb_encrypt(input,output,numbits,length,schedule,ivec)
-+unsigned char *input,*output;
-+int numbits;
-+long length;
-+des_key_schedule schedule;
-+des_cblock *ivec;
-+.PP
-+.B unsigned long des_cbc_cksum(input,output,length,schedule,ivec)
-+des_cblock *input;
-+des_cblock *output;
-+long length;
-+des_key_schedule schedule;
-+des_cblock *ivec;
-+.PP
-+.B unsigned long des_quad_cksum(input,output,length,out_count,seed)
-+des_cblock *input;
-+des_cblock *output;
-+long length;
-+int out_count;
-+des_cblock *seed;
-+.PP
-+.B int des_check_key;
-+.PP
-+.B int des_enc_read(fd,buf,len,sched,iv)
-+int fd;
-+char *buf;
-+int len;
-+des_key_schedule sched;
-+des_cblock *iv;
-+.PP
-+.B int des_enc_write(fd,buf,len,sched,iv)
-+int fd;
-+char *buf;
-+int len;
-+des_key_schedule sched;
-+des_cblock *iv;
-+.PP
-+.B extern int des_rw_mode;
-+.PP
-+.B void des_set_odd_parity(key)
-+des_cblock *key;
-+.PP
-+.B int des_is_weak_key(key)
-+des_cblock *key;
-+.PP
-+.B char *crypt(passwd,salt)
-+char *passwd;
-+char *salt;
-+.PP
-+.fi
-+.SH DESCRIPTION
-+This library contains a fast implementation of the DES encryption
-+algorithm.
-+.PP
-+There are two phases to the use of DES encryption.
-+The first is the generation of a
-+.I des_key_schedule
-+from a key,
-+the second is the actual encryption.
-+A des key is of type
-+.I des_cblock.
-+This type is made from 8 characters with odd parity.
-+The least significant bit in the character is the parity bit.
-+The key schedule is an expanded form of the key; it is used to speed the
-+encryption process.
-+.PP
-+.I des_read_password
-+writes the string specified by prompt to the standard output,
-+turns off echo and reads an input string from standard input
-+until terminated with a newline.
-+If verify is non-zero, it prompts and reads the input again and verifies
-+that both entered passwords are the same.
-+The entered string is converted into a des key by using the
-+.I des_string_to_key
-+routine.
-+The new key is placed in the
-+.I des_cblock
-+that was passed (by reference) to the routine.
-+If there were no errors,
-+.I des_read_password
-+returns 0,
-+-1 is returned if there was a terminal error and 1 is returned for
-+any other error.
-+.PP
-+.I des_read_2password
-+operates in the same way as
-+.I des_read_password
-+except that it generates 2 keys by using the
-+.I des_string_to_2key
-+function.
-+.PP
-+.I des_read_pw_string
-+is called by
-+.I des_read_password
-+to read and verify a string from a terminal device.
-+The string is returned in
-+.I buf.
-+The size of
-+.I buf
-+is passed to the routine via the
-+.I length
-+parameter.
-+.PP
-+.I des_string_to_key
-+converts a string into a valid des key.
-+.PP
-+.I des_string_to_2key
-+converts a string into 2 valid des keys.
-+This routine is best suited for used to generate keys for use with
-+.I des_ecb3_encrypt.
-+.PP
-+.I des_random_key
-+returns a random key that is made of a combination of process id,
-+time and an increasing counter.
-+.PP
-+Before a des key can be used it is converted into a
-+.I des_key_schedule
-+via the
-+.I des_set_key
-+routine.
-+If the
-+.I des_check_key
-+flag is non-zero,
-+.I des_set_key
-+will check that the key passed is of odd parity and is not a week or
-+semi-weak key.
-+If the parity is wrong,
-+then -1 is returned.
-+If the key is a weak key,
-+then -2 is returned.
-+If an error is returned,
-+the key schedule is not generated.
-+.PP
-+.I des_key_sched
-+is another name for the
-+.I des_set_key
-+function.
-+.PP
-+The following routines mostly operate on an input and output stream of
-+.I des_cblock's.
-+.PP
-+.I des_ecb_encrypt
-+is the basic DES encryption routine that encrypts or decrypts a single 8-byte
-+.I des_cblock
-+in
-+.I electronic code book
-+mode.
-+It always transforms the input data, pointed to by
-+.I input,
-+into the output data,
-+pointed to by the
-+.I output
-+argument.
-+If the
-+.I encrypt
-+argument is non-zero (DES_ENCRYPT),
-+the
-+.I input
-+(cleartext) is encrypted in to the
-+.I output
-+(ciphertext) using the key_schedule specified by the
-+.I schedule
-+argument,
-+previously set via
-+.I des_set_key.
-+If
-+.I encrypt
-+is zero (DES_DECRYPT),
-+the
-+.I input
-+(now ciphertext)
-+is decrypted into the
-+.I output
-+(now cleartext).
-+Input and output may overlap.
-+No meaningful value is returned.
-+.PP
-+.I des_ecb3_encrypt
-+encrypts/decrypts the
-+.I input
-+block by using triple ecb DES encryption.
-+This involves encrypting the input with
-+.I ks1,
-+decryption with the key schedule
-+.I ks2,
-+and then encryption with the first again.
-+This routine greatly reduces the chances of brute force breaking of
-+DES and has the advantage of if
-+.I ks1
-+and
-+.I ks2
-+are the same, it is equivalent to just encryption using ecb mode and
-+.I ks1
-+as the key.
-+.PP
-+.I des_cbc_encrypt
-+encrypts/decrypts using the
-+.I cipher-block-chaining
-+mode of DES.
-+If the
-+.I encrypt
-+argument is non-zero,
-+the routine cipher-block-chain encrypts the cleartext data pointed to by the
-+.I input
-+argument into the ciphertext pointed to by the
-+.I output
-+argument,
-+using the key schedule provided by the
-+.I schedule
-+argument,
-+and initialisation vector provided by the
-+.I ivec
-+argument.
-+If the
-+.I length
-+argument is not an integral multiple of eight bytes,
-+the last block is copied to a temporary area and zero filled.
-+The output is always
-+an integral multiple of eight bytes.
-+To make multiple cbc encrypt calls on a large amount of data appear to
-+be one
-+.I des_cbc_encrypt
-+call, the
-+.I ivec
-+of subsequent calls should be the last 8 bytes of the output.
-+.PP
-+.I des_3cbc_encrypt
-+encrypts/decrypts the
-+.I input
-+block by using triple cbc DES encryption.
-+This involves encrypting the input with key schedule
-+.I ks1,
-+decryption with the key schedule
-+.I ks2,
-+and then encryption with the first again.
-+2 initialisation vectors are required,
-+.I ivec1
-+and
-+.I ivec2.
-+Unlike
-+.I des_cbc_encrypt,
-+these initialisation vectors are modified by the subroutine.
-+This routine greatly reduces the chances of brute force breaking of
-+DES and has the advantage of if
-+.I ks1
-+and
-+.I ks2
-+are the same, it is equivalent to just encryption using cbc mode and
-+.I ks1
-+as the key.
-+.PP
-+.I des_pcbc_encrypt
-+encrypt/decrypts using a modified block chaining mode.
-+It provides better error propagation characteristics than cbc
-+encryption.
-+.PP
-+.I des_cfb_encrypt
-+encrypt/decrypts using cipher feedback mode. This method takes an
-+array of characters as input and outputs and array of characters. It
-+does not require any padding to 8 character groups. Note: the ivec
-+variable is changed and the new changed value needs to be passed to
-+the next call to this function. Since this function runs a complete
-+DES ecb encryption per numbits, this function is only suggested for
-+use when sending small numbers of characters.
-+.PP
-+.I des_ofb_encrypt
-+encrypt using output feedback mode. This method takes an
-+array of characters as input and outputs and array of characters. It
-+does not require any padding to 8 character groups. Note: the ivec
-+variable is changed and the new changed value needs to be passed to
-+the next call to this function. Since this function runs a complete
-+DES ecb encryption per numbits, this function is only suggested for
-+use when sending small numbers of characters.
-+.PP
-+.I des_cbc_cksum
-+produces an 8 byte checksum based on the input stream (via cbc encryption).
-+The last 4 bytes of the checksum is returned and the complete 8 bytes is
-+placed in
-+.I output.
-+.PP
-+.I des_quad_cksum
-+returns a 4 byte checksum from the input bytes.
-+The algorithm can be iterated over the input,
-+depending on
-+.I out_count,
-+1, 2, 3 or 4 times.
-+If
-+.I output
-+is non-NULL,
-+the 8 bytes generated by each pass are written into
-+.I output.
-+.PP
-+.I des_enc_write
-+is used to write
-+.I len
-+bytes
-+to file descriptor
-+.I fd
-+from buffer
-+.I buf.
-+The data is encrypted via
-+.I pcbc_encrypt
-+(default) using
-+.I sched
-+for the key and
-+.I iv
-+as a starting vector.
-+The actual data send down
-+.I fd
-+consists of 4 bytes (in network byte order) containing the length of the
-+following encrypted data. The encrypted data then follows, padded with random
-+data out to a multiple of 8 bytes.
-+.PP
-+.I des_enc_read
-+is used to read
-+.I len
-+bytes
-+from file descriptor
-+.I fd
-+into buffer
-+.I buf.
-+The data being read from
-+.I fd
-+is assumed to have come from
-+.I des_enc_write
-+and is decrypted using
-+.I sched
-+for the key schedule and
-+.I iv
-+for the initial vector.
-+The
-+.I des_enc_read/des_enc_write
-+pair can be used to read/write to files, pipes and sockets.
-+I have used them in implementing a version of rlogin in which all
-+data is encrypted.
-+.PP
-+.I des_rw_mode
-+is used to specify the encryption mode to use with
-+.I des_enc_read
-+and
-+.I des_end_write.
-+If set to
-+.I DES_PCBC_MODE
-+(the default), des_pcbc_encrypt is used.
-+If set to
-+.I DES_CBC_MODE
-+des_cbc_encrypt is used.
-+These two routines and the variable are not part of the normal MIT library.
-+.PP
-+.I des_set_odd_parity
-+sets the parity of the passed
-+.I key
-+to odd. This routine is not part of the standard MIT library.
-+.PP
-+.I des_is_weak_key
-+returns 1 is the passed key is a weak key (pick again :-),
-+0 if it is ok.
-+This routine is not part of the standard MIT library.
-+.PP
-+.I crypt
-+is a replacement for the normal system crypt.
-+It is much faster than the system crypt.
-+.PP
-+.SH FILES
-+/usr/include/des.h
-+.br
-+/usr/lib/libdes.a
-+.PP
-+The encryption routines have been tested on 16bit, 32bit and 64bit
-+machines of various endian and even works under VMS.
-+.PP
-+.SH BUGS
-+.PP
-+If you think this manual is sparse,
-+read the des_crypt(3) manual from the MIT kerberos (or bones outside
-+of the USA) distribution.
-+.PP
-+.I des_cfb_encrypt
-+and
-+.I des_ofb_encrypt
-+operates on input of 8 bits. What this means is that if you set
-+numbits to 12, and length to 2, the first 12 bits will come from the 1st
-+input byte and the low half of the second input byte. The second 12
-+bits will have the low 8 bits taken from the 3rd input byte and the
-+top 4 bits taken from the 4th input byte. The same holds for output.
-+This function has been implemented this way because most people will
-+be using a multiple of 8 and because once you get into pulling bytes input
-+bytes apart things get ugly!
-+.PP
-+.I des_read_pw_string
-+is the most machine/OS dependent function and normally generates the
-+most problems when porting this code.
-+.PP
-+.I des_string_to_key
-+is probably different from the MIT version since there are lots
-+of fun ways to implement one-way encryption of a text string.
-+.PP
-+The routines are optimised for 32 bit machines and so are not efficient
-+on IBM PCs.
-+.PP
-+NOTE: extensive work has been done on this library since this document
-+was origionally written. Please try to read des.doc from the libdes
-+distribution since it is far more upto date and documents more of the
-+functions. Libdes is now also being shipped as part of SSLeay, a
-+general cryptographic library that amonst other things implements
-+netscapes SSL protocoll. The most recent version can be found in
-+SSLeay distributions.
-+.SH AUTHOR
-+Eric Young (eay@cryptsoft.com)
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/des_enc.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,502 @@
-+/* crypto/des/des_enc.c */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+#include "des_locl.h"
-+
-+void des_encrypt(data, ks, enc)
-+DES_LONG *data;
-+des_key_schedule ks;
-+int enc;
-+ {
-+ register DES_LONG l,r,t,u;
-+#ifdef DES_PTR
-+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
-+#endif
-+#ifndef DES_UNROLL
-+ register int i;
-+#endif
-+ register DES_LONG *s;
-+
-+ r=data[0];
-+ l=data[1];
-+
-+ IP(r,l);
-+ /* Things have been modified so that the initial rotate is
-+ * done outside the loop. This required the
-+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
-+ * One perl script later and things have a 5% speed up on a sparc2.
-+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
-+ * for pointing this out. */
-+ /* clear the top bits on machines with 8byte longs */
-+ /* shift left by 2 */
-+ r=ROTATE(r,29)&0xffffffffL;
-+ l=ROTATE(l,29)&0xffffffffL;
-+
-+ s=(DES_LONG *)ks;
-+ /* I don't know if it is worth the effort of loop unrolling the
-+ * inner loop */
-+ if (enc)
-+ {
-+#ifdef DES_UNROLL
-+ D_ENCRYPT(l,r, 0); /* 1 */
-+ D_ENCRYPT(r,l, 2); /* 2 */
-+ D_ENCRYPT(l,r, 4); /* 3 */
-+ D_ENCRYPT(r,l, 6); /* 4 */
-+ D_ENCRYPT(l,r, 8); /* 5 */
-+ D_ENCRYPT(r,l,10); /* 6 */
-+ D_ENCRYPT(l,r,12); /* 7 */
-+ D_ENCRYPT(r,l,14); /* 8 */
-+ D_ENCRYPT(l,r,16); /* 9 */
-+ D_ENCRYPT(r,l,18); /* 10 */
-+ D_ENCRYPT(l,r,20); /* 11 */
-+ D_ENCRYPT(r,l,22); /* 12 */
-+ D_ENCRYPT(l,r,24); /* 13 */
-+ D_ENCRYPT(r,l,26); /* 14 */
-+ D_ENCRYPT(l,r,28); /* 15 */
-+ D_ENCRYPT(r,l,30); /* 16 */
-+#else
-+ for (i=0; i<32; i+=8)
-+ {
-+ D_ENCRYPT(l,r,i+0); /* 1 */
-+ D_ENCRYPT(r,l,i+2); /* 2 */
-+ D_ENCRYPT(l,r,i+4); /* 3 */
-+ D_ENCRYPT(r,l,i+6); /* 4 */
-+ }
-+#endif
-+ }
-+ else
-+ {
-+#ifdef DES_UNROLL
-+ D_ENCRYPT(l,r,30); /* 16 */
-+ D_ENCRYPT(r,l,28); /* 15 */
-+ D_ENCRYPT(l,r,26); /* 14 */
-+ D_ENCRYPT(r,l,24); /* 13 */
-+ D_ENCRYPT(l,r,22); /* 12 */
-+ D_ENCRYPT(r,l,20); /* 11 */
-+ D_ENCRYPT(l,r,18); /* 10 */
-+ D_ENCRYPT(r,l,16); /* 9 */
-+ D_ENCRYPT(l,r,14); /* 8 */
-+ D_ENCRYPT(r,l,12); /* 7 */
-+ D_ENCRYPT(l,r,10); /* 6 */
-+ D_ENCRYPT(r,l, 8); /* 5 */
-+ D_ENCRYPT(l,r, 6); /* 4 */
-+ D_ENCRYPT(r,l, 4); /* 3 */
-+ D_ENCRYPT(l,r, 2); /* 2 */
-+ D_ENCRYPT(r,l, 0); /* 1 */
-+#else
-+ for (i=30; i>0; i-=8)
-+ {
-+ D_ENCRYPT(l,r,i-0); /* 16 */
-+ D_ENCRYPT(r,l,i-2); /* 15 */
-+ D_ENCRYPT(l,r,i-4); /* 14 */
-+ D_ENCRYPT(r,l,i-6); /* 13 */
-+ }
-+#endif
-+ }
-+
-+ /* rotate and clear the top bits on machines with 8byte longs */
-+ l=ROTATE(l,3)&0xffffffffL;
-+ r=ROTATE(r,3)&0xffffffffL;
-+
-+ FP(r,l);
-+ data[0]=l;
-+ data[1]=r;
-+ l=r=t=u=0;
-+ }
-+
-+void des_encrypt2(data, ks, enc)
-+DES_LONG *data;
-+des_key_schedule ks;
-+int enc;
-+ {
-+ register DES_LONG l,r,t,u;
-+#ifdef DES_PTR
-+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
-+#endif
-+#ifndef DES_UNROLL
-+ register int i;
-+#endif
-+ register DES_LONG *s;
-+
-+ r=data[0];
-+ l=data[1];
-+
-+ /* Things have been modified so that the initial rotate is
-+ * done outside the loop. This required the
-+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
-+ * One perl script later and things have a 5% speed up on a sparc2.
-+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
-+ * for pointing this out. */
-+ /* clear the top bits on machines with 8byte longs */
-+ r=ROTATE(r,29)&0xffffffffL;
-+ l=ROTATE(l,29)&0xffffffffL;
-+
-+ s=(DES_LONG *)ks;
-+ /* I don't know if it is worth the effort of loop unrolling the
-+ * inner loop */
-+ if (enc)
-+ {
-+#ifdef DES_UNROLL
-+ D_ENCRYPT(l,r, 0); /* 1 */
-+ D_ENCRYPT(r,l, 2); /* 2 */
-+ D_ENCRYPT(l,r, 4); /* 3 */
-+ D_ENCRYPT(r,l, 6); /* 4 */
-+ D_ENCRYPT(l,r, 8); /* 5 */
-+ D_ENCRYPT(r,l,10); /* 6 */
-+ D_ENCRYPT(l,r,12); /* 7 */
-+ D_ENCRYPT(r,l,14); /* 8 */
-+ D_ENCRYPT(l,r,16); /* 9 */
-+ D_ENCRYPT(r,l,18); /* 10 */
-+ D_ENCRYPT(l,r,20); /* 11 */
-+ D_ENCRYPT(r,l,22); /* 12 */
-+ D_ENCRYPT(l,r,24); /* 13 */
-+ D_ENCRYPT(r,l,26); /* 14 */
-+ D_ENCRYPT(l,r,28); /* 15 */
-+ D_ENCRYPT(r,l,30); /* 16 */
-+#else
-+ for (i=0; i<32; i+=8)
-+ {
-+ D_ENCRYPT(l,r,i+0); /* 1 */
-+ D_ENCRYPT(r,l,i+2); /* 2 */
-+ D_ENCRYPT(l,r,i+4); /* 3 */
-+ D_ENCRYPT(r,l,i+6); /* 4 */
-+ }
-+#endif
-+ }
-+ else
-+ {
-+#ifdef DES_UNROLL
-+ D_ENCRYPT(l,r,30); /* 16 */
-+ D_ENCRYPT(r,l,28); /* 15 */
-+ D_ENCRYPT(l,r,26); /* 14 */
-+ D_ENCRYPT(r,l,24); /* 13 */
-+ D_ENCRYPT(l,r,22); /* 12 */
-+ D_ENCRYPT(r,l,20); /* 11 */
-+ D_ENCRYPT(l,r,18); /* 10 */
-+ D_ENCRYPT(r,l,16); /* 9 */
-+ D_ENCRYPT(l,r,14); /* 8 */
-+ D_ENCRYPT(r,l,12); /* 7 */
-+ D_ENCRYPT(l,r,10); /* 6 */
-+ D_ENCRYPT(r,l, 8); /* 5 */
-+ D_ENCRYPT(l,r, 6); /* 4 */
-+ D_ENCRYPT(r,l, 4); /* 3 */
-+ D_ENCRYPT(l,r, 2); /* 2 */
-+ D_ENCRYPT(r,l, 0); /* 1 */
-+#else
-+ for (i=30; i>0; i-=8)
-+ {
-+ D_ENCRYPT(l,r,i-0); /* 16 */
-+ D_ENCRYPT(r,l,i-2); /* 15 */
-+ D_ENCRYPT(l,r,i-4); /* 14 */
-+ D_ENCRYPT(r,l,i-6); /* 13 */
-+ }
-+#endif
-+ }
-+ /* rotate and clear the top bits on machines with 8byte longs */
-+ data[0]=ROTATE(l,3)&0xffffffffL;
-+ data[1]=ROTATE(r,3)&0xffffffffL;
-+ l=r=t=u=0;
-+ }
-+
-+void des_encrypt3(data,ks1,ks2,ks3)
-+DES_LONG *data;
-+des_key_schedule ks1;
-+des_key_schedule ks2;
-+des_key_schedule ks3;
-+ {
-+ register DES_LONG l,r;
-+
-+ l=data[0];
-+ r=data[1];
-+ IP(l,r);
-+ data[0]=l;
-+ data[1]=r;
-+ des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
-+ des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
-+ des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
-+ l=data[0];
-+ r=data[1];
-+ FP(r,l);
-+ data[0]=l;
-+ data[1]=r;
-+ }
-+
-+void des_decrypt3(data,ks1,ks2,ks3)
-+DES_LONG *data;
-+des_key_schedule ks1;
-+des_key_schedule ks2;
-+des_key_schedule ks3;
-+ {
-+ register DES_LONG l,r;
-+
-+ l=data[0];
-+ r=data[1];
-+ IP(l,r);
-+ data[0]=l;
-+ data[1]=r;
-+ des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
-+ des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
-+ des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
-+ l=data[0];
-+ r=data[1];
-+ FP(r,l);
-+ data[0]=l;
-+ data[1]=r;
-+ }
-+
-+#ifndef DES_DEFAULT_OPTIONS
-+
-+void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
-+des_cblock (*input);
-+des_cblock (*output);
-+long length;
-+des_key_schedule schedule;
-+des_cblock (*ivec);
-+int enc;
-+ {
-+ register DES_LONG tin0,tin1;
-+ register DES_LONG tout0,tout1,xor0,xor1;
-+ register unsigned char *in,*out;
-+ register long l=length;
-+ DES_LONG tin[2];
-+ unsigned char *iv;
-+
-+ in=(unsigned char *)input;
-+ out=(unsigned char *)output;
-+ iv=(unsigned char *)ivec;
-+
-+ if (enc)
-+ {
-+ c2l(iv,tout0);
-+ c2l(iv,tout1);
-+ for (l-=8; l>=0; l-=8)
-+ {
-+ c2l(in,tin0);
-+ c2l(in,tin1);
-+ tin0^=tout0; tin[0]=tin0;
-+ tin1^=tout1; tin[1]=tin1;
-+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
-+ tout0=tin[0]; l2c(tout0,out);
-+ tout1=tin[1]; l2c(tout1,out);
-+ }
-+ if (l != -8)
-+ {
-+ c2ln(in,tin0,tin1,l+8);
-+ tin0^=tout0; tin[0]=tin0;
-+ tin1^=tout1; tin[1]=tin1;
-+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
-+ tout0=tin[0]; l2c(tout0,out);
-+ tout1=tin[1]; l2c(tout1,out);
-+ }
-+ iv=(unsigned char *)ivec;
-+ l2c(tout0,iv);
-+ l2c(tout1,iv);
-+ }
-+ else
-+ {
-+ c2l(iv,xor0);
-+ c2l(iv,xor1);
-+ for (l-=8; l>=0; l-=8)
-+ {
-+ c2l(in,tin0); tin[0]=tin0;
-+ c2l(in,tin1); tin[1]=tin1;
-+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
-+ tout0=tin[0]^xor0;
-+ tout1=tin[1]^xor1;
-+ l2c(tout0,out);
-+ l2c(tout1,out);
-+ xor0=tin0;
-+ xor1=tin1;
-+ }
-+ if (l != -8)
-+ {
-+ c2l(in,tin0); tin[0]=tin0;
-+ c2l(in,tin1); tin[1]=tin1;
-+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
-+ tout0=tin[0]^xor0;
-+ tout1=tin[1]^xor1;
-+ l2cn(tout0,tout1,out,l+8);
-+ xor0=tin0;
-+ xor1=tin1;
-+ }
-+
-+ iv=(unsigned char *)ivec;
-+ l2c(xor0,iv);
-+ l2c(xor1,iv);
-+ }
-+ tin0=tin1=tout0=tout1=xor0=xor1=0;
-+ tin[0]=tin[1]=0;
-+ }
-+
-+void des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, enc)
-+des_cblock (*input);
-+des_cblock (*output);
-+long length;
-+des_key_schedule ks1;
-+des_key_schedule ks2;
-+des_key_schedule ks3;
-+des_cblock (*ivec);
-+int enc;
-+ {
-+ register DES_LONG tin0,tin1;
-+ register DES_LONG tout0,tout1,xor0,xor1;
-+ register unsigned char *in,*out;
-+ register long l=length;
-+ DES_LONG tin[2];
-+ unsigned char *iv;
-+
-+ in=(unsigned char *)input;
-+ out=(unsigned char *)output;
-+ iv=(unsigned char *)ivec;
-+
-+ if (enc)
-+ {
-+ c2l(iv,tout0);
-+ c2l(iv,tout1);
-+ for (l-=8; l>=0; l-=8)
-+ {
-+ c2l(in,tin0);
-+ c2l(in,tin1);
-+ tin0^=tout0;
-+ tin1^=tout1;
-+
-+ tin[0]=tin0;
-+ tin[1]=tin1;
-+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
-+ tout0=tin[0];
-+ tout1=tin[1];
-+
-+ l2c(tout0,out);
-+ l2c(tout1,out);
-+ }
-+ if (l != -8)
-+ {
-+ c2ln(in,tin0,tin1,l+8);
-+ tin0^=tout0;
-+ tin1^=tout1;
-+
-+ tin[0]=tin0;
-+ tin[1]=tin1;
-+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
-+ tout0=tin[0];
-+ tout1=tin[1];
-+
-+ l2c(tout0,out);
-+ l2c(tout1,out);
-+ }
-+ iv=(unsigned char *)ivec;
-+ l2c(tout0,iv);
-+ l2c(tout1,iv);
-+ }
-+ else
-+ {
-+ register DES_LONG t0,t1;
-+
-+ c2l(iv,xor0);
-+ c2l(iv,xor1);
-+ for (l-=8; l>=0; l-=8)
-+ {
-+ c2l(in,tin0);
-+ c2l(in,tin1);
-+
-+ t0=tin0;
-+ t1=tin1;
-+
-+ tin[0]=tin0;
-+ tin[1]=tin1;
-+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
-+ tout0=tin[0];
-+ tout1=tin[1];
-+
-+ tout0^=xor0;
-+ tout1^=xor1;
-+ l2c(tout0,out);
-+ l2c(tout1,out);
-+ xor0=t0;
-+ xor1=t1;
-+ }
-+ if (l != -8)
-+ {
-+ c2l(in,tin0);
-+ c2l(in,tin1);
-+
-+ t0=tin0;
-+ t1=tin1;
-+
-+ tin[0]=tin0;
-+ tin[1]=tin1;
-+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
-+ tout0=tin[0];
-+ tout1=tin[1];
-+
-+ tout0^=xor0;
-+ tout1^=xor1;
-+ l2cn(tout0,tout1,out,l+8);
-+ xor0=t0;
-+ xor1=t1;
-+ }
-+
-+ iv=(unsigned char *)ivec;
-+ l2c(xor0,iv);
-+ l2c(xor1,iv);
-+ }
-+ tin0=tin1=tout0=tout1=xor0=xor1=0;
-+ tin[0]=tin[1]=0;
-+ }
-+
-+#endif /* DES_DEFAULT_OPTIONS */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/des_locl.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,515 @@
-+/* crypto/des/des_locl.org */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
-+ *
-+ * Always modify des_locl.org since des_locl.h is automatically generated from
-+ * it during SSLeay configuration.
-+ *
-+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
-+ */
-+
-+#ifndef HEADER_DES_LOCL_H
-+#define HEADER_DES_LOCL_H
-+
-+#if defined(WIN32) || defined(WIN16)
-+#ifndef MSDOS
-+#define MSDOS
-+#endif
-+#endif
-+
-+#include "crypto/des.h"
-+
-+#ifndef DES_DEFAULT_OPTIONS
-+/* the following is tweaked from a config script, that is why it is a
-+ * protected undef/define */
-+#ifndef DES_PTR
-+#define DES_PTR
-+#endif
-+
-+/* This helps C compiler generate the correct code for multiple functional
-+ * units. It reduces register dependancies at the expense of 2 more
-+ * registers */
-+#ifndef DES_RISC1
-+#define DES_RISC1
-+#endif
-+
-+#ifndef DES_RISC2
-+#undef DES_RISC2
-+#endif
-+
-+#if defined(DES_RISC1) && defined(DES_RISC2)
-+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
-+#endif
-+
-+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
-+ * Very mucy CPU dependant */
-+#ifndef DES_UNROLL
-+#define DES_UNROLL
-+#endif
-+
-+/* These default values were supplied by
-+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
-+ * They are only used if nothing else has been defined */
-+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
-+/* Special defines which change the way the code is built depending on the
-+ CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
-+ even newer MIPS CPU's, but at the moment one size fits all for
-+ optimization options. Older Sparc's work better with only UNROLL, but
-+ there's no way to tell at compile time what it is you're running on */
-+
-+#if defined( sun ) /* Newer Sparc's */
-+ #define DES_PTR
-+ #define DES_RISC1
-+ #define DES_UNROLL
-+#elif defined( __ultrix ) /* Older MIPS */
-+ #define DES_PTR
-+ #define DES_RISC2
-+ #define DES_UNROLL
-+#elif defined( __osf1__ ) /* Alpha */
-+ #define DES_PTR
-+ #define DES_RISC2
-+#elif defined ( _AIX ) /* RS6000 */
-+ /* Unknown */
-+#elif defined( __hpux ) /* HP-PA */
-+ /* Unknown */
-+#elif defined( __aux ) /* 68K */
-+ /* Unknown */
-+#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
-+ #define DES_UNROLL
-+#elif defined( __sgi ) /* Newer MIPS */
-+ #define DES_PTR
-+ #define DES_RISC2
-+ #define DES_UNROLL
-+#elif defined( i386 ) /* x86 boxes, should be gcc */
-+ #define DES_PTR
-+ #define DES_RISC1
-+ #define DES_UNROLL
-+#endif /* Systems-specific speed defines */
-+#endif
-+
-+#endif /* DES_DEFAULT_OPTIONS */
-+
-+#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */
-+#include <stdlib.h>
-+#include <errno.h>
-+#include <time.h>
-+#include <io.h>
-+#ifndef RAND
-+#define RAND
-+#endif
-+#undef NOPROTO
-+#endif
-+
-+#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
-+#ifndef __KERNEL__
-+#include <string.h>
-+#else
-+#include <linux/string.h>
-+#endif
-+#endif
-+
-+#ifndef RAND
-+#define RAND
-+#endif
-+
-+#ifdef linux
-+#undef RAND
-+#endif
-+
-+#ifdef MSDOS
-+#define getpid() 2
-+#define RAND
-+#undef NOPROTO
-+#endif
-+
-+#if defined(NOCONST)
-+#define const
-+#endif
-+
-+#ifdef __STDC__
-+#undef NOPROTO
-+#endif
-+
-+#ifdef RAND
-+#define srandom(s) srand(s)
-+#define random rand
-+#endif
-+
-+#define ITERATIONS 16
-+#define HALF_ITERATIONS 8
-+
-+/* used in des_read and des_write */
-+#define MAXWRITE (1024*16)
-+#define BSIZE (MAXWRITE+4)
-+
-+#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \
-+ l|=((DES_LONG)(*((c)++)))<< 8L, \
-+ l|=((DES_LONG)(*((c)++)))<<16L, \
-+ l|=((DES_LONG)(*((c)++)))<<24L)
-+
-+/* NOTE - c is not incremented as per c2l */
-+#define c2ln(c,l1,l2,n) { \
-+ c+=n; \
-+ l1=l2=0; \
-+ switch (n) { \
-+ case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
-+ case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
-+ case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
-+ case 5: l2|=((DES_LONG)(*(--(c)))); \
-+ case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
-+ case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
-+ case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
-+ case 1: l1|=((DES_LONG)(*(--(c)))); \
-+ } \
-+ }
-+
-+#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
-+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
-+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
-+ *((c)++)=(unsigned char)(((l)>>24L)&0xff))
-+
-+/* replacements for htonl and ntohl since I have no idea what to do
-+ * when faced with machines with 8 byte longs. */
-+#define HDRSIZE 4
-+
-+#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \
-+ l|=((DES_LONG)(*((c)++)))<<16L, \
-+ l|=((DES_LONG)(*((c)++)))<< 8L, \
-+ l|=((DES_LONG)(*((c)++))))
-+
-+#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
-+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
-+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
-+ *((c)++)=(unsigned char)(((l) )&0xff))
-+
-+/* NOTE - c is not incremented as per l2c */
-+#define l2cn(l1,l2,c,n) { \
-+ c+=n; \
-+ switch (n) { \
-+ case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
-+ case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
-+ case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
-+ case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
-+ case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
-+ case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
-+ case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
-+ case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
-+ } \
-+ }
-+
-+#if defined(WIN32)
-+#define ROTATE(a,n) (_lrotr(a,n))
-+#else
-+#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
-+#endif
-+
-+/* Don't worry about the LOAD_DATA() stuff, that is used by
-+ * fcrypt() to add it's little bit to the front */
-+
-+#ifdef DES_FCRYPT
-+
-+#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
-+ { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
-+
-+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
-+ t=R^(R>>16L); \
-+ u=t&E0; t&=E1; \
-+ tmp=(u<<16); u^=R^s[S ]; u^=tmp; \
-+ tmp=(t<<16); t^=R^s[S+1]; t^=tmp
-+#else
-+#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
-+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
-+ u=R^s[S ]; \
-+ t=R^s[S+1]
-+#endif
-+
-+/* The changes to this macro may help or hinder, depending on the
-+ * compiler and the achitecture. gcc2 always seems to do well :-).
-+ * Inspired by Dana How <how@isl.stanford.edu>
-+ * DO NOT use the alternative version on machines with 8 byte longs.
-+ * It does not seem to work on the Alpha, even when DES_LONG is 4
-+ * bytes, probably an issue of accessing non-word aligned objects :-( */
-+#ifdef DES_PTR
-+
-+/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there
-+ * is no reason to not xor all the sub items together. This potentially
-+ * saves a register since things can be xored directly into L */
-+
-+#if defined(DES_RISC1) || defined(DES_RISC2)
-+#ifdef DES_RISC1
-+#define D_ENCRYPT(LL,R,S) { \
-+ unsigned int u1,u2,u3; \
-+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
-+ u2=(int)u>>8L; \
-+ u1=(int)u&0xfc; \
-+ u2&=0xfc; \
-+ t=ROTATE(t,4); \
-+ u>>=16L; \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
-+ u3=(int)(u>>8L); \
-+ u1=(int)u&0xfc; \
-+ u3&=0xfc; \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \
-+ u2=(int)t>>8L; \
-+ u1=(int)t&0xfc; \
-+ u2&=0xfc; \
-+ t>>=16L; \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
-+ u3=(int)t>>8L; \
-+ u1=(int)t&0xfc; \
-+ u3&=0xfc; \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }
-+#endif
-+#ifdef DES_RISC2
-+#define D_ENCRYPT(LL,R,S) { \
-+ unsigned int u1,u2,s1,s2; \
-+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
-+ u2=(int)u>>8L; \
-+ u1=(int)u&0xfc; \
-+ u2&=0xfc; \
-+ t=ROTATE(t,4); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
-+ s1=(int)(u>>16L); \
-+ s2=(int)(u>>24L); \
-+ s1&=0xfc; \
-+ s2&=0xfc; \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \
-+ u2=(int)t>>8L; \
-+ u1=(int)t&0xfc; \
-+ u2&=0xfc; \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
-+ s1=(int)(t>>16L); \
-+ s2=(int)(t>>24L); \
-+ s1&=0xfc; \
-+ s2&=0xfc; \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }
-+#endif
-+#else
-+#define D_ENCRYPT(LL,R,S) { \
-+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \
-+ t=ROTATE(t,4); \
-+ LL^= \
-+ *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \
-+ *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \
-+ *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \
-+ *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \
-+ *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \
-+ *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \
-+ *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \
-+ *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }
-+#endif
-+
-+#else /* original version */
-+
-+#if defined(DES_RISC1) || defined(DES_RISC2)
-+#ifdef DES_RISC1
-+#define D_ENCRYPT(LL,R,S) {\
-+ unsigned int u1,u2,u3; \
-+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
-+ u>>=2L; \
-+ t=ROTATE(t,6); \
-+ u2=(int)u>>8L; \
-+ u1=(int)u&0x3f; \
-+ u2&=0x3f; \
-+ u>>=16L; \
-+ LL^=des_SPtrans[0][u1]; \
-+ LL^=des_SPtrans[2][u2]; \
-+ u3=(int)u>>8L; \
-+ u1=(int)u&0x3f; \
-+ u3&=0x3f; \
-+ LL^=des_SPtrans[4][u1]; \
-+ LL^=des_SPtrans[6][u3]; \
-+ u2=(int)t>>8L; \
-+ u1=(int)t&0x3f; \
-+ u2&=0x3f; \
-+ t>>=16L; \
-+ LL^=des_SPtrans[1][u1]; \
-+ LL^=des_SPtrans[3][u2]; \
-+ u3=(int)t>>8L; \
-+ u1=(int)t&0x3f; \
-+ u3&=0x3f; \
-+ LL^=des_SPtrans[5][u1]; \
-+ LL^=des_SPtrans[7][u3]; }
-+#endif
-+#ifdef DES_RISC2
-+#define D_ENCRYPT(LL,R,S) {\
-+ unsigned int u1,u2,s1,s2; \
-+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
-+ u>>=2L; \
-+ t=ROTATE(t,6); \
-+ u2=(int)u>>8L; \
-+ u1=(int)u&0x3f; \
-+ u2&=0x3f; \
-+ LL^=des_SPtrans[0][u1]; \
-+ LL^=des_SPtrans[2][u2]; \
-+ s1=(int)u>>16L; \
-+ s2=(int)u>>24L; \
-+ s1&=0x3f; \
-+ s2&=0x3f; \
-+ LL^=des_SPtrans[4][s1]; \
-+ LL^=des_SPtrans[6][s2]; \
-+ u2=(int)t>>8L; \
-+ u1=(int)t&0x3f; \
-+ u2&=0x3f; \
-+ LL^=des_SPtrans[1][u1]; \
-+ LL^=des_SPtrans[3][u2]; \
-+ s1=(int)t>>16; \
-+ s2=(int)t>>24L; \
-+ s1&=0x3f; \
-+ s2&=0x3f; \
-+ LL^=des_SPtrans[5][s1]; \
-+ LL^=des_SPtrans[7][s2]; }
-+#endif
-+
-+#else
-+
-+#define D_ENCRYPT(LL,R,S) {\
-+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \
-+ t=ROTATE(t,4); \
-+ LL^=\
-+ des_SPtrans[0][(u>> 2L)&0x3f]^ \
-+ des_SPtrans[2][(u>>10L)&0x3f]^ \
-+ des_SPtrans[4][(u>>18L)&0x3f]^ \
-+ des_SPtrans[6][(u>>26L)&0x3f]^ \
-+ des_SPtrans[1][(t>> 2L)&0x3f]^ \
-+ des_SPtrans[3][(t>>10L)&0x3f]^ \
-+ des_SPtrans[5][(t>>18L)&0x3f]^ \
-+ des_SPtrans[7][(t>>26L)&0x3f]; }
-+#endif
-+#endif
-+
-+ /* IP and FP
-+ * The problem is more of a geometric problem that random bit fiddling.
-+ 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
-+ 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
-+ 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
-+ 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
-+
-+ 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
-+ 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
-+ 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
-+ 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
-+
-+ The output has been subject to swaps of the form
-+ 0 1 -> 3 1 but the odd and even bits have been put into
-+ 2 3 2 0
-+ different words. The main trick is to remember that
-+ t=((l>>size)^r)&(mask);
-+ r^=t;
-+ l^=(t<<size);
-+ can be used to swap and move bits between words.
-+
-+ So l = 0 1 2 3 r = 16 17 18 19
-+ 4 5 6 7 20 21 22 23
-+ 8 9 10 11 24 25 26 27
-+ 12 13 14 15 28 29 30 31
-+ becomes (for size == 2 and mask == 0x3333)
-+ t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
-+ 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
-+ 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
-+ 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
-+
-+ Thanks for hints from Richard Outerbridge - he told me IP&FP
-+ could be done in 15 xor, 10 shifts and 5 ands.
-+ When I finally started to think of the problem in 2D
-+ I first got ~42 operations without xors. When I remembered
-+ how to use xors :-) I got it to its final state.
-+ */
-+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
-+ (b)^=(t),\
-+ (a)^=((t)<<(n)))
-+
-+#define IP(l,r) \
-+ { \
-+ register DES_LONG tt; \
-+ PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
-+ PERM_OP(l,r,tt,16,0x0000ffffL); \
-+ PERM_OP(r,l,tt, 2,0x33333333L); \
-+ PERM_OP(l,r,tt, 8,0x00ff00ffL); \
-+ PERM_OP(r,l,tt, 1,0x55555555L); \
-+ }
-+
-+#define FP(l,r) \
-+ { \
-+ register DES_LONG tt; \
-+ PERM_OP(l,r,tt, 1,0x55555555L); \
-+ PERM_OP(r,l,tt, 8,0x00ff00ffL); \
-+ PERM_OP(l,r,tt, 2,0x33333333L); \
-+ PERM_OP(r,l,tt,16,0x0000ffffL); \
-+ PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
-+ }
-+
-+extern const DES_LONG des_SPtrans[8][64];
-+
-+#ifndef NOPROTO
-+void fcrypt_body(DES_LONG *out,des_key_schedule ks,
-+ DES_LONG Eswap0, DES_LONG Eswap1);
-+#else
-+void fcrypt_body();
-+#endif
-+
-+#endif
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/des_opts.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,620 @@
-+/* crypto/des/des_opts.c */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
-+ * This is for machines with 64k code segment size restrictions. */
-+
-+#ifndef MSDOS
-+#define TIMES
-+#endif
-+
-+#include <stdio.h>
-+#ifndef MSDOS
-+#include <unistd.h>
-+#else
-+#include <io.h>
-+extern void exit();
-+#endif
-+#include <signal.h>
-+#ifndef VMS
-+#ifndef _IRIX
-+#include <time.h>
-+#endif
-+#ifdef TIMES
-+#include <sys/types.h>
-+#include <sys/times.h>
-+#endif
-+#else /* VMS */
-+#include <types.h>
-+struct tms {
-+ time_t tms_utime;
-+ time_t tms_stime;
-+ time_t tms_uchild; /* I dunno... */
-+ time_t tms_uchildsys; /* so these names are a guess :-) */
-+ }
-+#endif
-+#ifndef TIMES
-+#include <sys/timeb.h>
-+#endif
-+
-+#ifdef sun
-+#include <limits.h>
-+#include <sys/param.h>
-+#endif
-+
-+#include "des_locl.h"
-+#include "spr.h"
-+
-+#define DES_DEFAULT_OPTIONS
-+
-+#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4)
-+#define PART1
-+#define PART2
-+#define PART3
-+#define PART4
-+#endif
-+
-+#ifdef PART1
-+
-+#undef DES_UNROLL
-+#undef DES_RISC1
-+#undef DES_RISC2
-+#undef DES_PTR
-+#undef D_ENCRYPT
-+#define des_encrypt des_encrypt_u4_cisc_idx
-+#define des_encrypt2 des_encrypt2_u4_cisc_idx
-+#define des_encrypt3 des_encrypt3_u4_cisc_idx
-+#define des_decrypt3 des_decrypt3_u4_cisc_idx
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#define DES_UNROLL
-+#undef DES_RISC1
-+#undef DES_RISC2
-+#undef DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u16_cisc_idx
-+#define des_encrypt2 des_encrypt2_u16_cisc_idx
-+#define des_encrypt3 des_encrypt3_u16_cisc_idx
-+#define des_decrypt3 des_decrypt3_u16_cisc_idx
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#undef DES_UNROLL
-+#define DES_RISC1
-+#undef DES_RISC2
-+#undef DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u4_risc1_idx
-+#define des_encrypt2 des_encrypt2_u4_risc1_idx
-+#define des_encrypt3 des_encrypt3_u4_risc1_idx
-+#define des_decrypt3 des_decrypt3_u4_risc1_idx
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#endif
-+
-+#ifdef PART2
-+
-+#undef DES_UNROLL
-+#undef DES_RISC1
-+#define DES_RISC2
-+#undef DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u4_risc2_idx
-+#define des_encrypt2 des_encrypt2_u4_risc2_idx
-+#define des_encrypt3 des_encrypt3_u4_risc2_idx
-+#define des_decrypt3 des_decrypt3_u4_risc2_idx
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#define DES_UNROLL
-+#define DES_RISC1
-+#undef DES_RISC2
-+#undef DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u16_risc1_idx
-+#define des_encrypt2 des_encrypt2_u16_risc1_idx
-+#define des_encrypt3 des_encrypt3_u16_risc1_idx
-+#define des_decrypt3 des_decrypt3_u16_risc1_idx
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#define DES_UNROLL
-+#undef DES_RISC1
-+#define DES_RISC2
-+#undef DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u16_risc2_idx
-+#define des_encrypt2 des_encrypt2_u16_risc2_idx
-+#define des_encrypt3 des_encrypt3_u16_risc2_idx
-+#define des_decrypt3 des_decrypt3_u16_risc2_idx
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#endif
-+
-+#ifdef PART3
-+
-+#undef DES_UNROLL
-+#undef DES_RISC1
-+#undef DES_RISC2
-+#define DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u4_cisc_ptr
-+#define des_encrypt2 des_encrypt2_u4_cisc_ptr
-+#define des_encrypt3 des_encrypt3_u4_cisc_ptr
-+#define des_decrypt3 des_decrypt3_u4_cisc_ptr
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#define DES_UNROLL
-+#undef DES_RISC1
-+#undef DES_RISC2
-+#define DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u16_cisc_ptr
-+#define des_encrypt2 des_encrypt2_u16_cisc_ptr
-+#define des_encrypt3 des_encrypt3_u16_cisc_ptr
-+#define des_decrypt3 des_decrypt3_u16_cisc_ptr
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#undef DES_UNROLL
-+#define DES_RISC1
-+#undef DES_RISC2
-+#define DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u4_risc1_ptr
-+#define des_encrypt2 des_encrypt2_u4_risc1_ptr
-+#define des_encrypt3 des_encrypt3_u4_risc1_ptr
-+#define des_decrypt3 des_decrypt3_u4_risc1_ptr
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#endif
-+
-+#ifdef PART4
-+
-+#undef DES_UNROLL
-+#undef DES_RISC1
-+#define DES_RISC2
-+#define DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u4_risc2_ptr
-+#define des_encrypt2 des_encrypt2_u4_risc2_ptr
-+#define des_encrypt3 des_encrypt3_u4_risc2_ptr
-+#define des_decrypt3 des_decrypt3_u4_risc2_ptr
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#define DES_UNROLL
-+#define DES_RISC1
-+#undef DES_RISC2
-+#define DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u16_risc1_ptr
-+#define des_encrypt2 des_encrypt2_u16_risc1_ptr
-+#define des_encrypt3 des_encrypt3_u16_risc1_ptr
-+#define des_decrypt3 des_decrypt3_u16_risc1_ptr
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#define DES_UNROLL
-+#undef DES_RISC1
-+#define DES_RISC2
-+#define DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u16_risc2_ptr
-+#define des_encrypt2 des_encrypt2_u16_risc2_ptr
-+#define des_encrypt3 des_encrypt3_u16_risc2_ptr
-+#define des_decrypt3 des_decrypt3_u16_risc2_ptr
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#endif
-+
-+/* The following if from times(3) man page. It may need to be changed */
-+#ifndef HZ
-+# ifndef CLK_TCK
-+# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
-+# ifndef VMS
-+# define HZ 100.0
-+# else /* VMS */
-+# define HZ 100.0
-+# endif
-+# else /* _BSD_CLK_TCK_ */
-+# define HZ ((double)_BSD_CLK_TCK_)
-+# endif
-+# else /* CLK_TCK */
-+# define HZ ((double)CLK_TCK)
-+# endif
-+#endif
-+
-+#define BUFSIZE ((long)1024)
-+long run=0;
-+
-+#ifndef NOPROTO
-+double Time_F(int s);
-+#else
-+double Time_F();
-+#endif
-+
-+#ifdef SIGALRM
-+#if defined(__STDC__) || defined(sgi)
-+#define SIGRETTYPE void
-+#else
-+#define SIGRETTYPE int
-+#endif
-+
-+#ifndef NOPROTO
-+SIGRETTYPE sig_done(int sig);
-+#else
-+SIGRETTYPE sig_done();
-+#endif
-+
-+SIGRETTYPE sig_done(sig)
-+int sig;
-+ {
-+ signal(SIGALRM,sig_done);
-+ run=0;
-+#ifdef LINT
-+ sig=sig;
-+#endif
-+ }
-+#endif
-+
-+#define START 0
-+#define STOP 1
-+
-+double Time_F(s)
-+int s;
-+ {
-+ double ret;
-+#ifdef TIMES
-+ static struct tms tstart,tend;
-+
-+ if (s == START)
-+ {
-+ times(&tstart);
-+ return(0);
-+ }
-+ else
-+ {
-+ times(&tend);
-+ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
-+ return((ret == 0.0)?1e-6:ret);
-+ }
-+#else /* !times() */
-+ static struct timeb tstart,tend;
-+ long i;
-+
-+ if (s == START)
-+ {
-+ ftime(&tstart);
-+ return(0);
-+ }
-+ else
-+ {
-+ ftime(&tend);
-+ i=(long)tend.millitm-(long)tstart.millitm;
-+ ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
-+ return((ret == 0.0)?1e-6:ret);
-+ }
-+#endif
-+ }
-+
-+#ifdef SIGALRM
-+#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
-+#else
-+#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
-+#endif
-+
-+#define time_it(func,name,index) \
-+ print_name(name); \
-+ Time_F(START); \
-+ for (count=0,run=1; COND(cb); count++) \
-+ { \
-+ unsigned long d[2]; \
-+ func(d,&(sch[0]),DES_ENCRYPT); \
-+ } \
-+ tm[index]=Time_F(STOP); \
-+ fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
-+ tm[index]=((double)COUNT(cb))/tm[index];
-+
-+#define print_it(name,index) \
-+ fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
-+ tm[index]*8,1.0e6/tm[index]);
-+
-+int main(argc,argv)
-+int argc;
-+char **argv;
-+ {
-+ long count;
-+ static unsigned char buf[BUFSIZE];
-+ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
-+ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
-+ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
-+ des_key_schedule sch,sch2,sch3;
-+ double d,tm[16],max=0;
-+ int rank[16];
-+ char *str[16];
-+ int max_idx=0,i,num=0,j;
-+#ifndef SIGALARM
-+ long ca,cb,cc,cd,ce;
-+#endif
-+
-+ for (i=0; i<12; i++)
-+ {
-+ tm[i]=0.0;
-+ rank[i]=0;
-+ }
-+
-+#ifndef TIMES
-+ fprintf(stderr,"To get the most acurate results, try to run this\n");
-+ fprintf(stderr,"program when this computer is idle.\n");
-+#endif
-+
-+ des_set_key((C_Block *)key,sch);
-+ des_set_key((C_Block *)key2,sch2);
-+ des_set_key((C_Block *)key3,sch3);
-+
-+#ifndef SIGALRM
-+ fprintf(stderr,"First we calculate the approximate speed ...\n");
-+ des_set_key((C_Block *)key,sch);
-+ count=10;
-+ do {
-+ long i;
-+ unsigned long data[2];
-+
-+ count*=2;
-+ Time_F(START);
-+ for (i=count; i; i--)
-+ des_encrypt(data,&(sch[0]),DES_ENCRYPT);
-+ d=Time_F(STOP);
-+ } while (d < 3.0);
-+ ca=count;
-+ cb=count*3;
-+ cc=count*3*8/BUFSIZE+1;
-+ cd=count*8/BUFSIZE+1;
-+
-+ ce=count/20+1;
-+#define COND(d) (count != (d))
-+#define COUNT(d) (d)
-+#else
-+#define COND(c) (run)
-+#define COUNT(d) (count)
-+ signal(SIGALRM,sig_done);
-+ alarm(10);
-+#endif
-+
-+#ifdef PART1
-+ time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx ", 0);
-+ time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1);
-+ time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2);
-+ num+=3;
-+#endif
-+#ifdef PART2
-+ time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3);
-+ time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4);
-+ time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5);
-+ num+=3;
-+#endif
-+#ifdef PART3
-+ time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr ", 6);
-+ time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7);
-+ time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8);
-+ num+=3;
-+#endif
-+#ifdef PART4
-+ time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9);
-+ time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10);
-+ time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11);
-+ num+=3;
-+#endif
-+
-+#ifdef PART1
-+ str[0]=" 4 c i";
-+ print_it("des_encrypt_u4_cisc_idx ",0);
-+ max=tm[0];
-+ max_idx=0;
-+ str[1]="16 c i";
-+ print_it("des_encrypt_u16_cisc_idx ",1);
-+ if (max < tm[1]) { max=tm[1]; max_idx=1; }
-+ str[2]=" 4 r1 i";
-+ print_it("des_encrypt_u4_risc1_idx ",2);
-+ if (max < tm[2]) { max=tm[2]; max_idx=2; }
-+#endif
-+#ifdef PART2
-+ str[3]="16 r1 i";
-+ print_it("des_encrypt_u16_risc1_idx",3);
-+ if (max < tm[3]) { max=tm[3]; max_idx=3; }
-+ str[4]=" 4 r2 i";
-+ print_it("des_encrypt_u4_risc2_idx ",4);
-+ if (max < tm[4]) { max=tm[4]; max_idx=4; }
-+ str[5]="16 r2 i";
-+ print_it("des_encrypt_u16_risc2_idx",5);
-+ if (max < tm[5]) { max=tm[5]; max_idx=5; }
-+#endif
-+#ifdef PART3
-+ str[6]=" 4 c p";
-+ print_it("des_encrypt_u4_cisc_ptr ",6);
-+ if (max < tm[6]) { max=tm[6]; max_idx=6; }
-+ str[7]="16 c p";
-+ print_it("des_encrypt_u16_cisc_ptr ",7);
-+ if (max < tm[7]) { max=tm[7]; max_idx=7; }
-+ str[8]=" 4 r1 p";
-+ print_it("des_encrypt_u4_risc1_ptr ",8);
-+ if (max < tm[8]) { max=tm[8]; max_idx=8; }
-+#endif
-+#ifdef PART4
-+ str[9]="16 r1 p";
-+ print_it("des_encrypt_u16_risc1_ptr",9);
-+ if (max < tm[9]) { max=tm[9]; max_idx=9; }
-+ str[10]=" 4 r2 p";
-+ print_it("des_encrypt_u4_risc2_ptr ",10);
-+ if (max < tm[10]) { max=tm[10]; max_idx=10; }
-+ str[11]="16 r2 p";
-+ print_it("des_encrypt_u16_risc2_ptr",11);
-+ if (max < tm[11]) { max=tm[11]; max_idx=11; }
-+#endif
-+ printf("options des ecb/s\n");
-+ printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
-+ d=tm[max_idx];
-+ tm[max_idx]= -2.0;
-+ max= -1.0;
-+ for (;;)
-+ {
-+ for (i=0; i<12; i++)
-+ {
-+ if (max < tm[i]) { max=tm[i]; j=i; }
-+ }
-+ if (max < 0.0) break;
-+ printf("%s %12.2f %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
-+ tm[j]= -2.0;
-+ max= -1.0;
-+ }
-+
-+ switch (max_idx)
-+ {
-+ case 0:
-+ printf("-DDES_DEFAULT_OPTIONS\n");
-+ break;
-+ case 1:
-+ printf("-DDES_UNROLL\n");
-+ break;
-+ case 2:
-+ printf("-DDES_RISC1\n");
-+ break;
-+ case 3:
-+ printf("-DDES_UNROLL -DDES_RISC1\n");
-+ break;
-+ case 4:
-+ printf("-DDES_RISC2\n");
-+ break;
-+ case 5:
-+ printf("-DDES_UNROLL -DDES_RISC2\n");
-+ break;
-+ case 6:
-+ printf("-DDES_PTR\n");
-+ break;
-+ case 7:
-+ printf("-DDES_UNROLL -DDES_PTR\n");
-+ break;
-+ case 8:
-+ printf("-DDES_RISC1 -DDES_PTR\n");
-+ break;
-+ case 9:
-+ printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n");
-+ break;
-+ case 10:
-+ printf("-DDES_RISC2 -DDES_PTR\n");
-+ break;
-+ case 11:
-+ printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n");
-+ break;
-+ }
-+ exit(0);
-+#if defined(LINT) || defined(MSDOS)
-+ return(0);
-+#endif
-+ }
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/des_ver.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,60 @@
-+/* crypto/des/des_ver.h */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+extern char *DES_version; /* SSLeay version string */
-+extern char *libdes_version; /* old libdes version string */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/destest.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,871 @@
-+/* crypto/des/destest.c */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+#if defined(WIN32) || defined(WIN16) || defined(WINDOWS)
-+#ifndef MSDOS
-+#define MSDOS
-+#endif
-+#endif
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#ifndef MSDOS
-+#include <unistd.h>
-+#else
-+#include <io.h>
-+#endif
-+#include <string.h>
-+#include "des_locl.h"
-+
-+/* tisk tisk - the test keys don't all have odd parity :-( */
-+/* test data */
-+#define NUM_TESTS 34
-+static unsigned char key_data[NUM_TESTS][8]={
-+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
-+ {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
-+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
-+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
-+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-+ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10},
-+ {0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57},
-+ {0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E},
-+ {0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86},
-+ {0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E},
-+ {0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6},
-+ {0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE},
-+ {0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6},
-+ {0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE},
-+ {0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16},
-+ {0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F},
-+ {0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46},
-+ {0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E},
-+ {0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76},
-+ {0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07},
-+ {0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F},
-+ {0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7},
-+ {0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF},
-+ {0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6},
-+ {0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF},
-+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
-+ {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
-+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
-+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
-+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
-+ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}};
-+
-+static unsigned char plain_data[NUM_TESTS][8]={
-+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
-+ {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
-+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
-+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
-+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
-+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
-+ {0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42},
-+ {0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA},
-+ {0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72},
-+ {0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A},
-+ {0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2},
-+ {0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A},
-+ {0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2},
-+ {0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A},
-+ {0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02},
-+ {0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A},
-+ {0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32},
-+ {0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA},
-+ {0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62},
-+ {0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2},
-+ {0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA},
-+ {0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92},
-+ {0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A},
-+ {0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2},
-+ {0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A},
-+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
-+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
-+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
-+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
-+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
-+
-+static unsigned char cipher_data[NUM_TESTS][8]={
-+ {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
-+ {0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58},
-+ {0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B},
-+ {0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33},
-+ {0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D},
-+ {0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD},
-+ {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
-+ {0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4},
-+ {0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B},
-+ {0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71},
-+ {0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A},
-+ {0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A},
-+ {0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95},
-+ {0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B},
-+ {0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09},
-+ {0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A},
-+ {0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F},
-+ {0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88},
-+ {0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77},
-+ {0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A},
-+ {0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56},
-+ {0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56},
-+ {0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56},
-+ {0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC},
-+ {0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A},
-+ {0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41},
-+ {0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93},
-+ {0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00},
-+ {0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06},
-+ {0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7},
-+ {0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51},
-+ {0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE},
-+ {0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D},
-+ {0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}};
-+
-+static unsigned char cipher_ecb2[NUM_TESTS-1][8]={
-+ {0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E},
-+ {0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16},
-+ {0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27},
-+ {0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6},
-+ {0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25},
-+ {0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A},
-+ {0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74},
-+ {0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6},
-+ {0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67},
-+ {0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10},
-+ {0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85},
-+ {0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA},
-+ {0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3},
-+ {0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3},
-+ {0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A},
-+ {0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69},
-+ {0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1},
-+ {0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7},
-+ {0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F},
-+ {0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87},
-+ {0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A},
-+ {0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE},
-+ {0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3},
-+ {0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD},
-+ {0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84},
-+ {0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85},
-+ {0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC},
-+ {0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89},
-+ {0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E},
-+ {0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89},
-+ {0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7},
-+ {0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8},
-+ {0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}};
-+
-+static unsigned char cbc_key [8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
-+static unsigned char cbc2_key[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87};
-+static unsigned char cbc3_key[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
-+static unsigned char cbc_iv [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
-+static char cbc_data[40]="7654321 Now is the time for \0001";
-+
-+static unsigned char cbc_ok[32]={
-+ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
-+ 0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb,
-+ 0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68,
-+ 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
-+
-+static unsigned char xcbc_ok[32]={
-+ 0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48,
-+ 0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD,
-+ 0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76,
-+ 0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2,
-+ };
-+
-+static unsigned char cbc3_ok[32]={
-+ 0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0,
-+ 0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC,
-+ 0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4,
-+ 0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75};
-+
-+static unsigned char pcbc_ok[32]={
-+ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
-+ 0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15,
-+ 0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f,
-+ 0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88};
-+
-+static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
-+static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
-+static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
-+static unsigned char plain[24]=
-+ {
-+ 0x4e,0x6f,0x77,0x20,0x69,0x73,
-+ 0x20,0x74,0x68,0x65,0x20,0x74,
-+ 0x69,0x6d,0x65,0x20,0x66,0x6f,
-+ 0x72,0x20,0x61,0x6c,0x6c,0x20
-+ };
-+static unsigned char cfb_cipher8[24]= {
-+ 0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8,
-+ 0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 };
-+static unsigned char cfb_cipher16[24]={
-+ 0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70,
-+ 0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B };
-+static unsigned char cfb_cipher32[24]={
-+ 0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD,
-+ 0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 };
-+static unsigned char cfb_cipher48[24]={
-+ 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85,
-+ 0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F };
-+static unsigned char cfb_cipher64[24]={
-+ 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B,
-+ 0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 };
-+
-+static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
-+static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
-+static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8];
-+static unsigned char ofb_cipher[24]=
-+ {
-+ 0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51,
-+ 0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f,
-+ 0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3
-+ };
-+
-+DES_LONG cbc_cksum_ret=0xB462FEF7L;
-+unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
-+
-+#ifndef NOPROTO
-+static char *pt(unsigned char *p);
-+static int cfb_test(int bits, unsigned char *cfb_cipher);
-+static int cfb64_test(unsigned char *cfb_cipher);
-+static int ede_cfb64_test(unsigned char *cfb_cipher);
-+#else
-+static char *pt();
-+static int cfb_test();
-+static int cfb64_test();
-+static int ede_cfb64_test();
-+#endif
-+
-+int main(argc,argv)
-+int argc;
-+char *argv[];
-+ {
-+ int i,j,err=0;
-+ des_cblock in,out,outin,iv3;
-+ des_key_schedule ks,ks2,ks3;
-+ unsigned char cbc_in[40];
-+ unsigned char cbc_out[40];
-+ DES_LONG cs;
-+ unsigned char qret[4][4],cret[8];
-+ DES_LONG lqret[4];
-+ int num;
-+ char *str;
-+
-+ printf("Doing ecb\n");
-+ for (i=0; i<NUM_TESTS; i++)
-+ {
-+ if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0)
-+ {
-+ printf("Key error %2d:%d\n",i+1,j);
-+ err=1;
-+ }
-+ memcpy(in,plain_data[i],8);
-+ memset(out,0,8);
-+ memset(outin,0,8);
-+ des_ecb_encrypt((C_Block *)in,(C_Block *)out,ks,DES_ENCRYPT);
-+ des_ecb_encrypt((C_Block *)out,(C_Block *)outin,ks,DES_DECRYPT);
-+
-+ if (memcmp(out,cipher_data[i],8) != 0)
-+ {
-+ printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
-+ i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]),
-+ pt(out));
-+ err=1;
-+ }
-+ if (memcmp(in,outin,8) != 0)
-+ {
-+ printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
-+ i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
-+ err=1;
-+ }
-+ }
-+
-+#ifndef LIBDES_LIT
-+ printf("Doing ede ecb\n");
-+ for (i=0; i<(NUM_TESTS-1); i++)
-+ {
-+ if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0)
-+ {
-+ err=1;
-+ printf("Key error %2d:%d\n",i+1,j);
-+ }
-+ if ((j=des_key_sched((C_Block *)(key_data[i+1]),ks2)) != 0)
-+ {
-+ printf("Key error %2d:%d\n",i+2,j);
-+ err=1;
-+ }
-+ if ((j=des_key_sched((C_Block *)(key_data[i+2]),ks3)) != 0)
-+ {
-+ printf("Key error %2d:%d\n",i+3,j);
-+ err=1;
-+ }
-+ memcpy(in,plain_data[i],8);
-+ memset(out,0,8);
-+ memset(outin,0,8);
-+ des_ecb2_encrypt((C_Block *)in,(C_Block *)out,ks,ks2,
-+ DES_ENCRYPT);
-+ des_ecb2_encrypt((C_Block *)out,(C_Block *)outin,ks,ks2,
-+ DES_DECRYPT);
-+
-+ if (memcmp(out,cipher_ecb2[i],8) != 0)
-+ {
-+ printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
-+ i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]),
-+ pt(out));
-+ err=1;
-+ }
-+ if (memcmp(in,outin,8) != 0)
-+ {
-+ printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
-+ i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
-+ err=1;
-+ }
-+ }
-+#endif
-+
-+ printf("Doing cbc\n");
-+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
-+ {
-+ printf("Key error %d\n",j);
-+ err=1;
-+ }
-+ memset(cbc_out,0,40);
-+ memset(cbc_in,0,40);
-+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
-+ des_ncbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
-+ (long)strlen((char *)cbc_data)+1,ks,
-+ (C_Block *)iv3,DES_ENCRYPT);
-+ if (memcmp(cbc_out,cbc_ok,32) != 0)
-+ printf("cbc_encrypt encrypt error\n");
-+
-+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
-+ des_ncbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
-+ (long)strlen((char *)cbc_data)+1,ks,
-+ (C_Block *)iv3,DES_DECRYPT);
-+ if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)) != 0)
-+ {
-+ printf("cbc_encrypt decrypt error\n");
-+ err=1;
-+ }
-+
-+#ifndef LIBDES_LIT
-+ printf("Doing desx cbc\n");
-+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
-+ {
-+ printf("Key error %d\n",j);
-+ err=1;
-+ }
-+ memset(cbc_out,0,40);
-+ memset(cbc_in,0,40);
-+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
-+ des_xcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
-+ (long)strlen((char *)cbc_data)+1,ks,
-+ (C_Block *)iv3,
-+ (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_ENCRYPT);
-+ if (memcmp(cbc_out,xcbc_ok,32) != 0)
-+ {
-+ printf("des_xcbc_encrypt encrypt error\n");
-+ }
-+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
-+ des_xcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
-+ (long)strlen((char *)cbc_data)+1,ks,
-+ (C_Block *)iv3,
-+ (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_DECRYPT);
-+ if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
-+ {
-+ printf("des_xcbc_encrypt decrypt error\n");
-+ err=1;
-+ }
-+#endif
-+
-+ printf("Doing ede cbc\n");
-+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
-+ {
-+ printf("Key error %d\n",j);
-+ err=1;
-+ }
-+ if ((j=des_key_sched((C_Block *)cbc2_key,ks2)) != 0)
-+ {
-+ printf("Key error %d\n",j);
-+ err=1;
-+ }
-+ if ((j=des_key_sched((C_Block *)cbc3_key,ks3)) != 0)
-+ {
-+ printf("Key error %d\n",j);
-+ err=1;
-+ }
-+ memset(cbc_out,0,40);
-+ memset(cbc_in,0,40);
-+ i=strlen((char *)cbc_data)+1;
-+ /* i=((i+7)/8)*8; */
-+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
-+
-+ des_ede3_cbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
-+ 16L,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT);
-+ des_ede3_cbc_encrypt((C_Block *)&(cbc_data[16]),
-+ (C_Block *)&(cbc_out[16]),
-+ (long)i-16,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT);
-+ if (memcmp(cbc_out,cbc3_ok,
-+ (unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
-+ {
-+ printf("des_ede3_cbc_encrypt encrypt error\n");
-+ err=1;
-+ }
-+
-+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
-+ des_ede3_cbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
-+ (long)i,ks,ks2,ks3,(C_Block *)iv3,DES_DECRYPT);
-+ if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0)
-+ {
-+ printf("des_ede3_cbc_encrypt decrypt error\n");
-+ err=1;
-+ }
-+
-+#ifndef LIBDES_LIT
-+ printf("Doing pcbc\n");
-+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
-+ {
-+ printf("Key error %d\n",j);
-+ err=1;
-+ }
-+ memset(cbc_out,0,40);
-+ memset(cbc_in,0,40);
-+ des_pcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
-+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_ENCRYPT);
-+ if (memcmp(cbc_out,pcbc_ok,32) != 0)
-+ {
-+ printf("pcbc_encrypt encrypt error\n");
-+ err=1;
-+ }
-+ des_pcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
-+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_DECRYPT);
-+ if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0)
-+ {
-+ printf("pcbc_encrypt decrypt error\n");
-+ err=1;
-+ }
-+
-+ printf("Doing ");
-+ printf("cfb8 ");
-+ err+=cfb_test(8,cfb_cipher8);
-+ printf("cfb16 ");
-+ err+=cfb_test(16,cfb_cipher16);
-+ printf("cfb32 ");
-+ err+=cfb_test(32,cfb_cipher32);
-+ printf("cfb48 ");
-+ err+=cfb_test(48,cfb_cipher48);
-+ printf("cfb64 ");
-+ err+=cfb_test(64,cfb_cipher64);
-+
-+ printf("cfb64() ");
-+ err+=cfb64_test(cfb_cipher64);
-+
-+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
-+ for (i=0; i<sizeof(plain); i++)
-+ des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]),
-+ 8,(long)1,ks,(C_Block *)cfb_tmp,DES_ENCRYPT);
-+ if (memcmp(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0)
-+ {
-+ printf("cfb_encrypt small encrypt error\n");
-+ err=1;
-+ }
-+
-+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
-+ for (i=0; i<sizeof(plain); i++)
-+ des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]),
-+ 8,(long)1,ks,(C_Block *)cfb_tmp,DES_DECRYPT);
-+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
-+ {
-+ printf("cfb_encrypt small decrypt error\n");
-+ err=1;
-+ }
-+
-+ printf("ede_cfb64() ");
-+ err+=ede_cfb64_test(cfb_cipher64);
-+
-+ printf("done\n");
-+
-+ printf("Doing ofb\n");
-+ des_key_sched((C_Block *)ofb_key,ks);
-+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
-+ des_ofb_encrypt(plain,ofb_buf1,64,(long)sizeof(plain)/8,ks,
-+ (C_Block *)ofb_tmp);
-+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
-+ {
-+ printf("ofb_encrypt encrypt error\n");
-+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
-+ofb_buf1[8+0], ofb_buf1[8+1], ofb_buf1[8+2], ofb_buf1[8+3],
-+ofb_buf1[8+4], ofb_buf1[8+5], ofb_buf1[8+6], ofb_buf1[8+7]);
-+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
-+ofb_buf1[8+0], ofb_cipher[8+1], ofb_cipher[8+2], ofb_cipher[8+3],
-+ofb_buf1[8+4], ofb_cipher[8+5], ofb_cipher[8+6], ofb_cipher[8+7]);
-+ err=1;
-+ }
-+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
-+ des_ofb_encrypt(ofb_buf1,ofb_buf2,64,(long)sizeof(ofb_buf1)/8,ks,
-+ (C_Block *)ofb_tmp);
-+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
-+ {
-+ printf("ofb_encrypt decrypt error\n");
-+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
-+ofb_buf2[8+0], ofb_buf2[8+1], ofb_buf2[8+2], ofb_buf2[8+3],
-+ofb_buf2[8+4], ofb_buf2[8+5], ofb_buf2[8+6], ofb_buf2[8+7]);
-+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
-+plain[8+0], plain[8+1], plain[8+2], plain[8+3],
-+plain[8+4], plain[8+5], plain[8+6], plain[8+7]);
-+ err=1;
-+ }
-+
-+ printf("Doing ofb64\n");
-+ des_key_sched((C_Block *)ofb_key,ks);
-+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
-+ memset(ofb_buf1,0,sizeof(ofb_buf1));
-+ memset(ofb_buf2,0,sizeof(ofb_buf1));
-+ num=0;
-+ for (i=0; i<sizeof(plain); i++)
-+ {
-+ des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,
-+ (C_Block *)ofb_tmp,&num);
-+ }
-+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
-+ {
-+ printf("ofb64_encrypt encrypt error\n");
-+ err=1;
-+ }
-+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
-+ num=0;
-+ des_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
-+ (C_Block *)ofb_tmp,&num);
-+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
-+ {
-+ printf("ofb64_encrypt decrypt error\n");
-+ err=1;
-+ }
-+
-+ printf("Doing ede_ofb64\n");
-+ des_key_sched((C_Block *)ofb_key,ks);
-+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
-+ memset(ofb_buf1,0,sizeof(ofb_buf1));
-+ memset(ofb_buf2,0,sizeof(ofb_buf1));
-+ num=0;
-+ for (i=0; i<sizeof(plain); i++)
-+ {
-+ des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,ks,
-+ (C_Block *)ofb_tmp,&num);
-+ }
-+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
-+ {
-+ printf("ede_ofb64_encrypt encrypt error\n");
-+ err=1;
-+ }
-+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
-+ num=0;
-+ des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
-+ ks,ks,(C_Block *)ofb_tmp,&num);
-+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
-+ {
-+ printf("ede_ofb64_encrypt decrypt error\n");
-+ err=1;
-+ }
-+
-+ printf("Doing cbc_cksum\n");
-+ des_key_sched((C_Block *)cbc_key,ks);
-+ cs=des_cbc_cksum((C_Block *)cbc_data,(C_Block *)cret,
-+ (long)strlen(cbc_data),ks,(C_Block *)cbc_iv);
-+ if (cs != cbc_cksum_ret)
-+ {
-+ printf("bad return value (%08lX), should be %08lX\n",
-+ (unsigned long)cs,(unsigned long)cbc_cksum_ret);
-+ err=1;
-+ }
-+ if (memcmp(cret,cbc_cksum_data,8) != 0)
-+ {
-+ printf("bad cbc_cksum block returned\n");
-+ err=1;
-+ }
-+
-+ printf("Doing quad_cksum\n");
-+ cs=quad_cksum((C_Block *)cbc_data,(C_Block *)qret,
-+ (long)strlen(cbc_data),2,(C_Block *)cbc_iv);
-+ for (i=0; i<4; i++)
-+ {
-+ lqret[i]=0;
-+ memcpy(&(lqret[i]),&(qret[i][0]),4);
-+ }
-+ { /* Big-endian fix */
-+ static DES_LONG l=1;
-+ static unsigned char *c=(unsigned char *)&l;
-+ DES_LONG ll;
-+
-+ if (!c[0])
-+ {
-+ ll=lqret[0]^lqret[3];
-+ lqret[0]^=ll;
-+ lqret[3]^=ll;
-+ ll=lqret[1]^lqret[2];
-+ lqret[1]^=ll;
-+ lqret[2]^=ll;
-+ }
-+ }
-+ if (cs != 0x70d7a63aL)
-+ {
-+ printf("quad_cksum error, ret %08lx should be 70d7a63a\n",
-+ (unsigned long)cs);
-+ err=1;
-+ }
-+ if (lqret[0] != 0x327eba8dL)
-+ {
-+ printf("quad_cksum error, out[0] %08lx is not %08lx\n",
-+ (unsigned long)lqret[0],0x327eba8dL);
-+ err=1;
-+ }
-+ if (lqret[1] != 0x201a49ccL)
-+ {
-+ printf("quad_cksum error, out[1] %08lx is not %08lx\n",
-+ (unsigned long)lqret[1],0x201a49ccL);
-+ err=1;
-+ }
-+ if (lqret[2] != 0x70d7a63aL)
-+ {
-+ printf("quad_cksum error, out[2] %08lx is not %08lx\n",
-+ (unsigned long)lqret[2],0x70d7a63aL);
-+ err=1;
-+ }
-+ if (lqret[3] != 0x501c2c26L)
-+ {
-+ printf("quad_cksum error, out[3] %08lx is not %08lx\n",
-+ (unsigned long)lqret[3],0x501c2c26L);
-+ err=1;
-+ }
-+#endif
-+
-+ printf("input word alignment test");
-+ for (i=0; i<4; i++)
-+ {
-+ printf(" %d",i);
-+ des_ncbc_encrypt((C_Block *)&(cbc_out[i]),(C_Block *)cbc_in,
-+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,
-+ DES_ENCRYPT);
-+ }
-+ printf("\noutput word alignment test");
-+ for (i=0; i<4; i++)
-+ {
-+ printf(" %d",i);
-+ des_ncbc_encrypt((C_Block *)cbc_out,(C_Block *)&(cbc_in[i]),
-+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,
-+ DES_ENCRYPT);
-+ }
-+ printf("\n");
-+ printf("fast crypt test ");
-+ str=crypt("testing","ef");
-+ if (strcmp("efGnQx2725bI2",str) != 0)
-+ {
-+ printf("fast crypt error, %s should be efGnQx2725bI2\n",str);
-+ err=1;
-+ }
-+ str=crypt("bca76;23","yA");
-+ if (strcmp("yA1Rp/1hZXIJk",str) != 0)
-+ {
-+ printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str);
-+ err=1;
-+ }
-+ printf("\n");
-+ exit(err);
-+ return(0);
-+ }
-+
-+static char *pt(p)
-+unsigned char *p;
-+ {
-+ static char bufs[10][20];
-+ static int bnum=0;
-+ char *ret;
-+ int i;
-+ static char *f="0123456789ABCDEF";
-+
-+ ret= &(bufs[bnum++][0]);
-+ bnum%=10;
-+ for (i=0; i<8; i++)
-+ {
-+ ret[i*2]=f[(p[i]>>4)&0xf];
-+ ret[i*2+1]=f[p[i]&0xf];
-+ }
-+ ret[16]='\0';
-+ return(ret);
-+ }
-+
-+#ifndef LIBDES_LIT
-+
-+static int cfb_test(bits, cfb_cipher)
-+int bits;
-+unsigned char *cfb_cipher;
-+ {
-+ des_key_schedule ks;
-+ int i,err=0;
-+
-+ des_key_sched((C_Block *)cfb_key,ks);
-+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
-+ des_cfb_encrypt(plain,cfb_buf1,bits,(long)sizeof(plain),ks,
-+ (C_Block *)cfb_tmp,DES_ENCRYPT);
-+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
-+ {
-+ err=1;
-+ printf("cfb_encrypt encrypt error\n");
-+ for (i=0; i<24; i+=8)
-+ printf("%s\n",pt(&(cfb_buf1[i])));
-+ }
-+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
-+ des_cfb_encrypt(cfb_buf1,cfb_buf2,bits,(long)sizeof(plain),ks,
-+ (C_Block *)cfb_tmp,DES_DECRYPT);
-+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
-+ {
-+ err=1;
-+ printf("cfb_encrypt decrypt error\n");
-+ for (i=0; i<24; i+=8)
-+ printf("%s\n",pt(&(cfb_buf1[i])));
-+ }
-+ return(err);
-+ }
-+
-+static int cfb64_test(cfb_cipher)
-+unsigned char *cfb_cipher;
-+ {
-+ des_key_schedule ks;
-+ int err=0,i,n;
-+
-+ des_key_sched((C_Block *)cfb_key,ks);
-+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
-+ n=0;
-+ des_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,
-+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
-+ des_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
-+ (long)sizeof(plain)-12,ks,
-+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
-+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
-+ {
-+ err=1;
-+ printf("cfb_encrypt encrypt error\n");
-+ for (i=0; i<24; i+=8)
-+ printf("%s\n",pt(&(cfb_buf1[i])));
-+ }
-+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
-+ n=0;
-+ des_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,
-+ (C_Block *)cfb_tmp,&n,DES_DECRYPT);
-+ des_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
-+ (long)sizeof(plain)-17,ks,
-+ (C_Block *)cfb_tmp,&n,DES_DECRYPT);
-+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
-+ {
-+ err=1;
-+ printf("cfb_encrypt decrypt error\n");
-+ for (i=0; i<24; i+=8)
-+ printf("%s\n",pt(&(cfb_buf2[i])));
-+ }
-+ return(err);
-+ }
-+
-+static int ede_cfb64_test(cfb_cipher)
-+unsigned char *cfb_cipher;
-+ {
-+ des_key_schedule ks;
-+ int err=0,i,n;
-+
-+ des_key_sched((C_Block *)cfb_key,ks);
-+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
-+ n=0;
-+ des_ede3_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,ks,ks,
-+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
-+ des_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
-+ (long)sizeof(plain)-12,ks,ks,ks,
-+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
-+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
-+ {
-+ err=1;
-+ printf("ede_cfb_encrypt encrypt error\n");
-+ for (i=0; i<24; i+=8)
-+ printf("%s\n",pt(&(cfb_buf1[i])));
-+ }
-+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
-+ n=0;
-+ des_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,ks,ks,
-+ (C_Block *)cfb_tmp,&n,DES_DECRYPT);
-+ des_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
-+ (long)sizeof(plain)-17,ks,ks,ks,
-+ (C_Block *)cfb_tmp,&n,DES_DECRYPT);
-+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
-+ {
-+ err=1;
-+ printf("ede_cfb_encrypt decrypt error\n");
-+ for (i=0; i<24; i+=8)
-+ printf("%s\n",pt(&(cfb_buf2[i])));
-+ }
-+ return(err);
-+ }
-+
-+#endif
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/dx86unix.S Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,3160 @@
-+/*
-+ * This file was originally generated by Michael Richardson <mcr@freeswan.org>
-+ * via the perl scripts found in the ASM subdir. It remains copyright of
-+ * Eric Young, see the file COPYRIGHT.
-+ *
-+ * This was last done on October 9, 2002.
-+ *
-+ * While this file does not need to go through cpp, we pass it through
-+ * CPP by naming it dx86unix.S instead of dx86unix.s because there is
-+ * a bug in Rules.make for .s builds - specifically it references EXTRA_CFLAGS
-+ * which may contain stuff that AS doesn't understand instead of
-+ * referencing EXTRA_AFLAGS.
-+ */
-+
-+ .file "dx86unix.S"
-+ .version "01.01"
-+.text
-+ .align 16
-+.globl des_encrypt
-+ .type des_encrypt , @function
-+des_encrypt:
-+ pushl %esi
-+ pushl %edi
-+
-+
-+ movl 12(%esp), %esi
-+ xorl %ecx, %ecx
-+ pushl %ebx
-+ pushl %ebp
-+ movl (%esi), %eax
-+ movl 28(%esp), %ebx
-+ movl 4(%esi), %edi
-+
-+
-+ roll $4, %eax
-+ movl %eax, %esi
-+ xorl %edi, %eax
-+ andl $0xf0f0f0f0, %eax
-+ xorl %eax, %esi
-+ xorl %eax, %edi
-+
-+ roll $20, %edi
-+ movl %edi, %eax
-+ xorl %esi, %edi
-+ andl $0xfff0000f, %edi
-+ xorl %edi, %eax
-+ xorl %edi, %esi
-+
-+ roll $14, %eax
-+ movl %eax, %edi
-+ xorl %esi, %eax
-+ andl $0x33333333, %eax
-+ xorl %eax, %edi
-+ xorl %eax, %esi
-+
-+ roll $22, %esi
-+ movl %esi, %eax
-+ xorl %edi, %esi
-+ andl $0x03fc03fc, %esi
-+ xorl %esi, %eax
-+ xorl %esi, %edi
-+
-+ roll $9, %eax
-+ movl %eax, %esi
-+ xorl %edi, %eax
-+ andl $0xaaaaaaaa, %eax
-+ xorl %eax, %esi
-+ xorl %eax, %edi
-+
-+.byte 209
-+.byte 199
-+ movl 24(%esp), %ebp
-+ cmpl $0, %ebx
-+ je .L000start_decrypt
-+
-+
-+ movl (%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 4(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 8(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 12(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 16(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 20(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 24(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 28(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 32(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 36(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 40(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 44(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 48(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 52(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 56(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 60(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 64(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 68(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 72(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 76(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 80(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 84(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 88(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 92(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 96(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 100(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 104(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 108(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 112(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 116(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 120(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 124(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+ jmp .L001end
-+.L000start_decrypt:
-+
-+
-+ movl 120(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 124(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 112(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 116(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 104(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 108(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 96(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 100(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 88(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 92(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 80(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 84(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 72(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 76(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 64(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 68(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 56(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 60(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 48(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 52(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 40(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 44(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 32(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 36(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 24(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 28(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 16(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 20(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 8(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 12(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl (%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 4(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+.L001end:
-+
-+
-+ movl 20(%esp), %edx
-+.byte 209
-+.byte 206
-+ movl %edi, %eax
-+ xorl %esi, %edi
-+ andl $0xaaaaaaaa, %edi
-+ xorl %edi, %eax
-+ xorl %edi, %esi
-+
-+ roll $23, %eax
-+ movl %eax, %edi
-+ xorl %esi, %eax
-+ andl $0x03fc03fc, %eax
-+ xorl %eax, %edi
-+ xorl %eax, %esi
-+
-+ roll $10, %edi
-+ movl %edi, %eax
-+ xorl %esi, %edi
-+ andl $0x33333333, %edi
-+ xorl %edi, %eax
-+ xorl %edi, %esi
-+
-+ roll $18, %esi
-+ movl %esi, %edi
-+ xorl %eax, %esi
-+ andl $0xfff0000f, %esi
-+ xorl %esi, %edi
-+ xorl %esi, %eax
-+
-+ roll $12, %edi
-+ movl %edi, %esi
-+ xorl %eax, %edi
-+ andl $0xf0f0f0f0, %edi
-+ xorl %edi, %esi
-+ xorl %edi, %eax
-+
-+ rorl $4, %eax
-+ movl %eax, (%edx)
-+ movl %esi, 4(%edx)
-+ popl %ebp
-+ popl %ebx
-+ popl %edi
-+ popl %esi
-+ ret
-+.des_encrypt_end:
-+ .size des_encrypt , .des_encrypt_end-des_encrypt
-+.ident "desasm.pl"
-+.text
-+ .align 16
-+.globl des_encrypt2
-+ .type des_encrypt2 , @function
-+des_encrypt2:
-+ pushl %esi
-+ pushl %edi
-+
-+
-+ movl 12(%esp), %eax
-+ xorl %ecx, %ecx
-+ pushl %ebx
-+ pushl %ebp
-+ movl (%eax), %esi
-+ movl 28(%esp), %ebx
-+ roll $3, %esi
-+ movl 4(%eax), %edi
-+ roll $3, %edi
-+ movl 24(%esp), %ebp
-+ cmpl $0, %ebx
-+ je .L002start_decrypt
-+
-+
-+ movl (%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 4(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 8(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 12(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 16(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 20(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 24(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 28(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 32(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 36(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 40(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 44(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 48(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 52(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 56(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 60(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 64(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 68(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 72(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 76(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 80(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 84(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 88(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 92(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 96(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 100(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 104(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 108(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 112(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 116(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 120(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 124(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+ jmp .L003end
-+.L002start_decrypt:
-+
-+
-+ movl 120(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 124(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 112(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 116(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 104(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 108(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 96(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 100(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 88(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 92(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 80(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 84(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 72(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 76(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 64(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 68(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 56(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 60(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 48(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 52(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 40(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 44(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 32(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 36(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 24(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 28(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 16(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 20(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 8(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 12(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl (%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 4(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+.L003end:
-+
-+
-+ rorl $3, %edi
-+ movl 20(%esp), %eax
-+ rorl $3, %esi
-+ movl %edi, (%eax)
-+ movl %esi, 4(%eax)
-+ popl %ebp
-+ popl %ebx
-+ popl %edi
-+ popl %esi
-+ ret
-+.des_encrypt2_end:
-+ .size des_encrypt2 , .des_encrypt2_end-des_encrypt2
-+.ident "desasm.pl"
-+.text
-+ .align 16
-+.globl des_encrypt3
-+ .type des_encrypt3 , @function
-+des_encrypt3:
-+ pushl %ebx
-+ movl 8(%esp), %ebx
-+ pushl %ebp
-+ pushl %esi
-+ pushl %edi
-+
-+
-+ movl (%ebx), %edi
-+ movl 4(%ebx), %esi
-+ subl $12, %esp
-+
-+
-+ roll $4, %edi
-+ movl %edi, %edx
-+ xorl %esi, %edi
-+ andl $0xf0f0f0f0, %edi
-+ xorl %edi, %edx
-+ xorl %edi, %esi
-+
-+ roll $20, %esi
-+ movl %esi, %edi
-+ xorl %edx, %esi
-+ andl $0xfff0000f, %esi
-+ xorl %esi, %edi
-+ xorl %esi, %edx
-+
-+ roll $14, %edi
-+ movl %edi, %esi
-+ xorl %edx, %edi
-+ andl $0x33333333, %edi
-+ xorl %edi, %esi
-+ xorl %edi, %edx
-+
-+ roll $22, %edx
-+ movl %edx, %edi
-+ xorl %esi, %edx
-+ andl $0x03fc03fc, %edx
-+ xorl %edx, %edi
-+ xorl %edx, %esi
-+
-+ roll $9, %edi
-+ movl %edi, %edx
-+ xorl %esi, %edi
-+ andl $0xaaaaaaaa, %edi
-+ xorl %edi, %edx
-+ xorl %edi, %esi
-+
-+ rorl $3, %edx
-+ rorl $2, %esi
-+ movl %esi, 4(%ebx)
-+ movl 36(%esp), %eax
-+ movl %edx, (%ebx)
-+ movl 40(%esp), %edi
-+ movl 44(%esp), %esi
-+ movl $1, 8(%esp)
-+ movl %eax, 4(%esp)
-+ movl %ebx, (%esp)
-+ call des_encrypt2
-+ movl $0, 8(%esp)
-+ movl %edi, 4(%esp)
-+ movl %ebx, (%esp)
-+ call des_encrypt2
-+ movl $1, 8(%esp)
-+ movl %esi, 4(%esp)
-+ movl %ebx, (%esp)
-+ call des_encrypt2
-+ addl $12, %esp
-+ movl (%ebx), %edi
-+ movl 4(%ebx), %esi
-+
-+
-+ roll $2, %esi
-+ roll $3, %edi
-+ movl %edi, %eax
-+ xorl %esi, %edi
-+ andl $0xaaaaaaaa, %edi
-+ xorl %edi, %eax
-+ xorl %edi, %esi
-+
-+ roll $23, %eax
-+ movl %eax, %edi
-+ xorl %esi, %eax
-+ andl $0x03fc03fc, %eax
-+ xorl %eax, %edi
-+ xorl %eax, %esi
-+
-+ roll $10, %edi
-+ movl %edi, %eax
-+ xorl %esi, %edi
-+ andl $0x33333333, %edi
-+ xorl %edi, %eax
-+ xorl %edi, %esi
-+
-+ roll $18, %esi
-+ movl %esi, %edi
-+ xorl %eax, %esi
-+ andl $0xfff0000f, %esi
-+ xorl %esi, %edi
-+ xorl %esi, %eax
-+
-+ roll $12, %edi
-+ movl %edi, %esi
-+ xorl %eax, %edi
-+ andl $0xf0f0f0f0, %edi
-+ xorl %edi, %esi
-+ xorl %edi, %eax
-+
-+ rorl $4, %eax
-+ movl %eax, (%ebx)
-+ movl %esi, 4(%ebx)
-+ popl %edi
-+ popl %esi
-+ popl %ebp
-+ popl %ebx
-+ ret
-+.des_encrypt3_end:
-+ .size des_encrypt3 , .des_encrypt3_end-des_encrypt3
-+.ident "desasm.pl"
-+.text
-+ .align 16
-+.globl des_decrypt3
-+ .type des_decrypt3 , @function
-+des_decrypt3:
-+ pushl %ebx
-+ movl 8(%esp), %ebx
-+ pushl %ebp
-+ pushl %esi
-+ pushl %edi
-+
-+
-+ movl (%ebx), %edi
-+ movl 4(%ebx), %esi
-+ subl $12, %esp
-+
-+
-+ roll $4, %edi
-+ movl %edi, %edx
-+ xorl %esi, %edi
-+ andl $0xf0f0f0f0, %edi
-+ xorl %edi, %edx
-+ xorl %edi, %esi
-+
-+ roll $20, %esi
-+ movl %esi, %edi
-+ xorl %edx, %esi
-+ andl $0xfff0000f, %esi
-+ xorl %esi, %edi
-+ xorl %esi, %edx
-+
-+ roll $14, %edi
-+ movl %edi, %esi
-+ xorl %edx, %edi
-+ andl $0x33333333, %edi
-+ xorl %edi, %esi
-+ xorl %edi, %edx
-+
-+ roll $22, %edx
-+ movl %edx, %edi
-+ xorl %esi, %edx
-+ andl $0x03fc03fc, %edx
-+ xorl %edx, %edi
-+ xorl %edx, %esi
-+
-+ roll $9, %edi
-+ movl %edi, %edx
-+ xorl %esi, %edi
-+ andl $0xaaaaaaaa, %edi
-+ xorl %edi, %edx
-+ xorl %edi, %esi
-+
-+ rorl $3, %edx
-+ rorl $2, %esi
-+ movl %esi, 4(%ebx)
-+ movl 36(%esp), %esi
-+ movl %edx, (%ebx)
-+ movl 40(%esp), %edi
-+ movl 44(%esp), %eax
-+ movl $0, 8(%esp)
-+ movl %eax, 4(%esp)
-+ movl %ebx, (%esp)
-+ call des_encrypt2
-+ movl $1, 8(%esp)
-+ movl %edi, 4(%esp)
-+ movl %ebx, (%esp)
-+ call des_encrypt2
-+ movl $0, 8(%esp)
-+ movl %esi, 4(%esp)
-+ movl %ebx, (%esp)
-+ call des_encrypt2
-+ addl $12, %esp
-+ movl (%ebx), %edi
-+ movl 4(%ebx), %esi
-+
-+
-+ roll $2, %esi
-+ roll $3, %edi
-+ movl %edi, %eax
-+ xorl %esi, %edi
-+ andl $0xaaaaaaaa, %edi
-+ xorl %edi, %eax
-+ xorl %edi, %esi
-+
-+ roll $23, %eax
-+ movl %eax, %edi
-+ xorl %esi, %eax
-+ andl $0x03fc03fc, %eax
-+ xorl %eax, %edi
-+ xorl %eax, %esi
-+
-+ roll $10, %edi
-+ movl %edi, %eax
-+ xorl %esi, %edi
-+ andl $0x33333333, %edi
-+ xorl %edi, %eax
-+ xorl %edi, %esi
-+
-+ roll $18, %esi
-+ movl %esi, %edi
-+ xorl %eax, %esi
-+ andl $0xfff0000f, %esi
-+ xorl %esi, %edi
-+ xorl %esi, %eax
-+
-+ roll $12, %edi
-+ movl %edi, %esi
-+ xorl %eax, %edi
-+ andl $0xf0f0f0f0, %edi
-+ xorl %edi, %esi
-+ xorl %edi, %eax
-+
-+ rorl $4, %eax
-+ movl %eax, (%ebx)
-+ movl %esi, 4(%ebx)
-+ popl %edi
-+ popl %esi
-+ popl %ebp
-+ popl %ebx
-+ ret
-+.des_decrypt3_end:
-+ .size des_decrypt3 , .des_decrypt3_end-des_decrypt3
-+.ident "desasm.pl"
-+.text
-+ .align 16
-+.globl des_ncbc_encrypt
-+ .type des_ncbc_encrypt , @function
-+des_ncbc_encrypt:
-+
-+ pushl %ebp
-+ pushl %ebx
-+ pushl %esi
-+ pushl %edi
-+ movl 28(%esp), %ebp
-+
-+ movl 36(%esp), %ebx
-+ movl (%ebx), %esi
-+ movl 4(%ebx), %edi
-+ pushl %edi
-+ pushl %esi
-+ pushl %edi
-+ pushl %esi
-+ movl %esp, %ebx
-+ movl 36(%esp), %esi
-+ movl 40(%esp), %edi
-+
-+ movl 56(%esp), %ecx
-+
-+ pushl %ecx
-+
-+ movl 52(%esp), %eax
-+ pushl %eax
-+ pushl %ebx
-+ cmpl $0, %ecx
-+ jz .L004decrypt
-+ andl $4294967288, %ebp
-+ movl 12(%esp), %eax
-+ movl 16(%esp), %ebx
-+ jz .L005encrypt_finish
-+.L006encrypt_loop:
-+ movl (%esi), %ecx
-+ movl 4(%esi), %edx
-+ xorl %ecx, %eax
-+ xorl %edx, %ebx
-+ movl %eax, 12(%esp)
-+ movl %ebx, 16(%esp)
-+ call des_encrypt
-+ movl 12(%esp), %eax
-+ movl 16(%esp), %ebx
-+ movl %eax, (%edi)
-+ movl %ebx, 4(%edi)
-+ addl $8, %esi
-+ addl $8, %edi
-+ subl $8, %ebp
-+ jnz .L006encrypt_loop
-+.L005encrypt_finish:
-+ movl 56(%esp), %ebp
-+ andl $7, %ebp
-+ jz .L007finish
-+ xorl %ecx, %ecx
-+ xorl %edx, %edx
-+ movl .L008cbc_enc_jmp_table(,%ebp,4),%ebp
-+ jmp *%ebp
-+.L009ej7:
-+ movb 6(%esi), %dh
-+ sall $8, %edx
-+.L010ej6:
-+ movb 5(%esi), %dh
-+.L011ej5:
-+ movb 4(%esi), %dl
-+.L012ej4:
-+ movl (%esi), %ecx
-+ jmp .L013ejend
-+.L014ej3:
-+ movb 2(%esi), %ch
-+ sall $8, %ecx
-+.L015ej2:
-+ movb 1(%esi), %ch
-+.L016ej1:
-+ movb (%esi), %cl
-+.L013ejend:
-+ xorl %ecx, %eax
-+ xorl %edx, %ebx
-+ movl %eax, 12(%esp)
-+ movl %ebx, 16(%esp)
-+ call des_encrypt
-+ movl 12(%esp), %eax
-+ movl 16(%esp), %ebx
-+ movl %eax, (%edi)
-+ movl %ebx, 4(%edi)
-+ jmp .L007finish
-+.align 16
-+.L004decrypt:
-+ andl $4294967288, %ebp
-+ movl 20(%esp), %eax
-+ movl 24(%esp), %ebx
-+ jz .L017decrypt_finish
-+.L018decrypt_loop:
-+ movl (%esi), %eax
-+ movl 4(%esi), %ebx
-+ movl %eax, 12(%esp)
-+ movl %ebx, 16(%esp)
-+ call des_encrypt
-+ movl 12(%esp), %eax
-+ movl 16(%esp), %ebx
-+ movl 20(%esp), %ecx
-+ movl 24(%esp), %edx
-+ xorl %eax, %ecx
-+ xorl %ebx, %edx
-+ movl (%esi), %eax
-+ movl 4(%esi), %ebx
-+ movl %ecx, (%edi)
-+ movl %edx, 4(%edi)
-+ movl %eax, 20(%esp)
-+ movl %ebx, 24(%esp)
-+ addl $8, %esi
-+ addl $8, %edi
-+ subl $8, %ebp
-+ jnz .L018decrypt_loop
-+.L017decrypt_finish:
-+ movl 56(%esp), %ebp
-+ andl $7, %ebp
-+ jz .L007finish
-+ movl (%esi), %eax
-+ movl 4(%esi), %ebx
-+ movl %eax, 12(%esp)
-+ movl %ebx, 16(%esp)
-+ call des_encrypt
-+ movl 12(%esp), %eax
-+ movl 16(%esp), %ebx
-+ movl 20(%esp), %ecx
-+ movl 24(%esp), %edx
-+ xorl %eax, %ecx
-+ xorl %ebx, %edx
-+ movl (%esi), %eax
-+ movl 4(%esi), %ebx
-+.L019dj7:
-+ rorl $16, %edx
-+ movb %dl, 6(%edi)
-+ shrl $16, %edx
-+.L020dj6:
-+ movb %dh, 5(%edi)
-+.L021dj5:
-+ movb %dl, 4(%edi)
-+.L022dj4:
-+ movl %ecx, (%edi)
-+ jmp .L023djend
-+.L024dj3:
-+ rorl $16, %ecx
-+ movb %cl, 2(%edi)
-+ sall $16, %ecx
-+.L025dj2:
-+ movb %ch, 1(%esi)
-+.L026dj1:
-+ movb %cl, (%esi)
-+.L023djend:
-+ jmp .L007finish
-+.align 16
-+.L007finish:
-+ movl 64(%esp), %ecx
-+ addl $28, %esp
-+ movl %eax, (%ecx)
-+ movl %ebx, 4(%ecx)
-+ popl %edi
-+ popl %esi
-+ popl %ebx
-+ popl %ebp
-+ ret
-+.align 16
-+.L008cbc_enc_jmp_table:
-+ .long 0
-+ .long .L016ej1
-+ .long .L015ej2
-+ .long .L014ej3
-+ .long .L012ej4
-+ .long .L011ej5
-+ .long .L010ej6
-+ .long .L009ej7
-+.align 16
-+.L027cbc_dec_jmp_table:
-+ .long 0
-+ .long .L026dj1
-+ .long .L025dj2
-+ .long .L024dj3
-+ .long .L022dj4
-+ .long .L021dj5
-+ .long .L020dj6
-+ .long .L019dj7
-+.des_ncbc_encrypt_end:
-+ .size des_ncbc_encrypt , .des_ncbc_encrypt_end-des_ncbc_encrypt
-+.ident "desasm.pl"
-+.text
-+ .align 16
-+.globl des_ede3_cbc_encrypt
-+ .type des_ede3_cbc_encrypt , @function
-+des_ede3_cbc_encrypt:
-+
-+ pushl %ebp
-+ pushl %ebx
-+ pushl %esi
-+ pushl %edi
-+ movl 28(%esp), %ebp
-+
-+ movl 44(%esp), %ebx
-+ movl (%ebx), %esi
-+ movl 4(%ebx), %edi
-+ pushl %edi
-+ pushl %esi
-+ pushl %edi
-+ pushl %esi
-+ movl %esp, %ebx
-+ movl 36(%esp), %esi
-+ movl 40(%esp), %edi
-+
-+ movl 64(%esp), %ecx
-+
-+ movl 56(%esp), %eax
-+ pushl %eax
-+
-+ movl 56(%esp), %eax
-+ pushl %eax
-+
-+ movl 56(%esp), %eax
-+ pushl %eax
-+ pushl %ebx
-+ cmpl $0, %ecx
-+ jz .L028decrypt
-+ andl $4294967288, %ebp
-+ movl 16(%esp), %eax
-+ movl 20(%esp), %ebx
-+ jz .L029encrypt_finish
-+.L030encrypt_loop:
-+ movl (%esi), %ecx
-+ movl 4(%esi), %edx
-+ xorl %ecx, %eax
-+ xorl %edx, %ebx
-+ movl %eax, 16(%esp)
-+ movl %ebx, 20(%esp)
-+ call des_encrypt3
-+ movl 16(%esp), %eax
-+ movl 20(%esp), %ebx
-+ movl %eax, (%edi)
-+ movl %ebx, 4(%edi)
-+ addl $8, %esi
-+ addl $8, %edi
-+ subl $8, %ebp
-+ jnz .L030encrypt_loop
-+.L029encrypt_finish:
-+ movl 60(%esp), %ebp
-+ andl $7, %ebp
-+ jz .L031finish
-+ xorl %ecx, %ecx
-+ xorl %edx, %edx
-+ movl .L032cbc_enc_jmp_table(,%ebp,4),%ebp
-+ jmp *%ebp
-+.L033ej7:
-+ movb 6(%esi), %dh
-+ sall $8, %edx
-+.L034ej6:
-+ movb 5(%esi), %dh
-+.L035ej5:
-+ movb 4(%esi), %dl
-+.L036ej4:
-+ movl (%esi), %ecx
-+ jmp .L037ejend
-+.L038ej3:
-+ movb 2(%esi), %ch
-+ sall $8, %ecx
-+.L039ej2:
-+ movb 1(%esi), %ch
-+.L040ej1:
-+ movb (%esi), %cl
-+.L037ejend:
-+ xorl %ecx, %eax
-+ xorl %edx, %ebx
-+ movl %eax, 16(%esp)
-+ movl %ebx, 20(%esp)
-+ call des_encrypt3
-+ movl 16(%esp), %eax
-+ movl 20(%esp), %ebx
-+ movl %eax, (%edi)
-+ movl %ebx, 4(%edi)
-+ jmp .L031finish
-+.align 16
-+.L028decrypt:
-+ andl $4294967288, %ebp
-+ movl 24(%esp), %eax
-+ movl 28(%esp), %ebx
-+ jz .L041decrypt_finish
-+.L042decrypt_loop:
-+ movl (%esi), %eax
-+ movl 4(%esi), %ebx
-+ movl %eax, 16(%esp)
-+ movl %ebx, 20(%esp)
-+ call des_decrypt3
-+ movl 16(%esp), %eax
-+ movl 20(%esp), %ebx
-+ movl 24(%esp), %ecx
-+ movl 28(%esp), %edx
-+ xorl %eax, %ecx
-+ xorl %ebx, %edx
-+ movl (%esi), %eax
-+ movl 4(%esi), %ebx
-+ movl %ecx, (%edi)
-+ movl %edx, 4(%edi)
-+ movl %eax, 24(%esp)
-+ movl %ebx, 28(%esp)
-+ addl $8, %esi
-+ addl $8, %edi
-+ subl $8, %ebp
-+ jnz .L042decrypt_loop
-+.L041decrypt_finish:
-+ movl 60(%esp), %ebp
-+ andl $7, %ebp
-+ jz .L031finish
-+ movl (%esi), %eax
-+ movl 4(%esi), %ebx
-+ movl %eax, 16(%esp)
-+ movl %ebx, 20(%esp)
-+ call des_decrypt3
-+ movl 16(%esp), %eax
-+ movl 20(%esp), %ebx
-+ movl 24(%esp), %ecx
-+ movl 28(%esp), %edx
-+ xorl %eax, %ecx
-+ xorl %ebx, %edx
-+ movl (%esi), %eax
-+ movl 4(%esi), %ebx
-+.L043dj7:
-+ rorl $16, %edx
-+ movb %dl, 6(%edi)
-+ shrl $16, %edx
-+.L044dj6:
-+ movb %dh, 5(%edi)
-+.L045dj5:
-+ movb %dl, 4(%edi)
-+.L046dj4:
-+ movl %ecx, (%edi)
-+ jmp .L047djend
-+.L048dj3:
-+ rorl $16, %ecx
-+ movb %cl, 2(%edi)
-+ sall $16, %ecx
-+.L049dj2:
-+ movb %ch, 1(%esi)
-+.L050dj1:
-+ movb %cl, (%esi)
-+.L047djend:
-+ jmp .L031finish
-+.align 16
-+.L031finish:
-+ movl 76(%esp), %ecx
-+ addl $32, %esp
-+ movl %eax, (%ecx)
-+ movl %ebx, 4(%ecx)
-+ popl %edi
-+ popl %esi
-+ popl %ebx
-+ popl %ebp
-+ ret
-+.align 16
-+.L032cbc_enc_jmp_table:
-+ .long 0
-+ .long .L040ej1
-+ .long .L039ej2
-+ .long .L038ej3
-+ .long .L036ej4
-+ .long .L035ej5
-+ .long .L034ej6
-+ .long .L033ej7
-+.align 16
-+.L051cbc_dec_jmp_table:
-+ .long 0
-+ .long .L050dj1
-+ .long .L049dj2
-+ .long .L048dj3
-+ .long .L046dj4
-+ .long .L045dj5
-+ .long .L044dj6
-+ .long .L043dj7
-+.des_ede3_cbc_encrypt_end:
-+ .size des_ede3_cbc_encrypt , .des_ede3_cbc_encrypt_end-des_ede3_cbc_encrypt
-+.ident "desasm.pl"
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/ecb_enc.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,128 @@
-+/* crypto/des/ecb_enc.c */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+#include "des_locl.h"
-+#include "spr.h"
-+
-+char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay";
-+char *DES_version="DES part of SSLeay 0.8.2b 08-Jan-1998";
-+
-+/* RCSID $Id$ */
-+/* This function ifdef'ed out for FreeS/WAN project. */
-+#ifdef notdef
-+char *des_options()
-+ {
-+ static int init=1;
-+ static char buf[32];
-+
-+ if (init)
-+ {
-+ char *ptr,*unroll,*risc,*size;
-+
-+ init=0;
-+#ifdef DES_PTR
-+ ptr="ptr";
-+#else
-+ ptr="idx";
-+#endif
-+#if defined(DES_RISC1) || defined(DES_RISC2)
-+#ifdef DES_RISC1
-+ risc="risc1";
-+#endif
-+#ifdef DES_RISC2
-+ risc="risc2";
-+#endif
-+#else
-+ risc="cisc";
-+#endif
-+#ifdef DES_UNROLL
-+ unroll="16";
-+#else
-+ unroll="4";
-+#endif
-+ if (sizeof(DES_LONG) != sizeof(long))
-+ size="int";
-+ else
-+ size="long";
-+ sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size);
-+ }
-+ return(buf);
-+ }
-+#endif
-+
-+
-+void des_ecb_encrypt(input, output, ks, enc)
-+des_cblock (*input);
-+des_cblock (*output);
-+des_key_schedule ks;
-+int enc;
-+ {
-+ register DES_LONG l;
-+ register unsigned char *in,*out;
-+ DES_LONG ll[2];
-+
-+ in=(unsigned char *)input;
-+ out=(unsigned char *)output;
-+ c2l(in,l); ll[0]=l;
-+ c2l(in,l); ll[1]=l;
-+ des_encrypt(ll,ks,enc);
-+ l=ll[0]; l2c(l,out);
-+ l=ll[1]; l2c(l,out);
-+ l=ll[0]=ll[1]=0;
-+ }
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/fcrypt.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,152 @@
-+/* NOCW */
-+
-+/* This version of crypt has been developed from my MIT compatable
-+ * DES library.
-+ * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
-+ * Eric Young (eay@cryptsoft.com)
-+ */
-+
-+/* Modification by Jens Kupferschmidt (Cu)
-+ * I have included directive PARA for shared memory computers.
-+ * I have included a directive LONGCRYPT to using this routine to cipher
-+ * passwords with more then 8 bytes like HP-UX 10.x it used. The MAXPLEN
-+ * definition is the maximum of lenght of password and can changed. I have
-+ * defined 24.
-+ */
-+
-+#include "des_locl.h"
-+
-+/* Added more values to handle illegal salt values the way normal
-+ * crypt() implementations do. The patch was sent by
-+ * Bjorn Gronvall <bg@sics.se>
-+ */
-+static unsigned const char con_salt[128]={
-+0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
-+0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,
-+0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
-+0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,
-+0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
-+0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01,
-+0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
-+0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A,
-+0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,
-+0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,
-+0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,
-+0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24,
-+0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,
-+0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,
-+0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,
-+0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,
-+};
-+
-+static unsigned const char cov_2char[64]={
-+0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
-+0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
-+0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
-+0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
-+0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
-+0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
-+0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
-+0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
-+};
-+
-+#ifndef NOPROTO
-+void fcrypt_body(DES_LONG *out,des_key_schedule ks,
-+ DES_LONG Eswap0, DES_LONG Eswap1);
-+
-+#ifdef PERL5
-+char *des_crypt(const char *buf,const char *salt);
-+#else
-+char *crypt(const char *buf,const char *salt);
-+#endif
-+#else
-+void fcrypt_body();
-+#ifdef PERL5
-+char *des_crypt();
-+#else
-+char *crypt();
-+#endif
-+#endif
-+
-+#ifdef PERL5
-+char *des_crypt(buf,salt)
-+#else
-+char *crypt(buf,salt)
-+#endif
-+const char *buf;
-+const char *salt;
-+ {
-+ static char buff[14];
-+
-+ return(des_fcrypt(buf,salt,buff));
-+ }
-+
-+
-+char *des_fcrypt(buf,salt,ret)
-+const char *buf;
-+const char *salt;
-+char *ret;
-+ {
-+ unsigned int i,j,x,y;
-+ DES_LONG Eswap0,Eswap1;
-+ DES_LONG out[2],ll;
-+ des_cblock key;
-+ des_key_schedule ks;
-+ unsigned char bb[9];
-+ unsigned char *b=bb;
-+ unsigned char c,u;
-+
-+ /* eay 25/08/92
-+ * If you call crypt("pwd","*") as often happens when you
-+ * have * as the pwd field in /etc/passwd, the function
-+ * returns *\0XXXXXXXXX
-+ * The \0 makes the string look like * so the pwd "*" would
-+ * crypt to "*". This was found when replacing the crypt in
-+ * our shared libraries. People found that the disbled
-+ * accounts effectivly had no passwd :-(. */
-+ x=ret[0]=((salt[0] == '\0')?'A':salt[0]);
-+ Eswap0=con_salt[x]<<2;
-+ x=ret[1]=((salt[1] == '\0')?'A':salt[1]);
-+ Eswap1=con_salt[x]<<6;
-+
-+/* EAY
-+r=strlen(buf);
-+r=(r+7)/8;
-+*/
-+ for (i=0; i<8; i++)
-+ {
-+ c= *(buf++);
-+ if (!c) break;
-+ key[i]=(c<<1);
-+ }
-+ for (; i<8; i++)
-+ key[i]=0;
-+
-+ des_set_key((des_cblock *)(key),ks);
-+ fcrypt_body(&(out[0]),ks,Eswap0,Eswap1);
-+
-+ ll=out[0]; l2c(ll,b);
-+ ll=out[1]; l2c(ll,b);
-+ y=0;
-+ u=0x80;
-+ bb[8]=0;
-+ for (i=2; i<13; i++)
-+ {
-+ c=0;
-+ for (j=0; j<6; j++)
-+ {
-+ c<<=1;
-+ if (bb[y] & u) c|=1;
-+ u>>=1;
-+ if (!u)
-+ {
-+ y++;
-+ u=0x80;
-+ }
-+ }
-+ ret[i]=cov_2char[c];
-+ }
-+ ret[13]='\0';
-+ return(ret);
-+ }
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/fcrypt_b.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,148 @@
-+/* crypto/des/fcrypt_b.c */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+/* #include <stdio.h> */
-+
-+/* This version of crypt has been developed from my MIT compatable
-+ * DES library.
-+ * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
-+ * Eric Young (eay@cryptsoft.com)
-+ */
-+
-+#define DES_FCRYPT
-+#include "des_locl.h"
-+#undef DES_FCRYPT
-+
-+#undef PERM_OP
-+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
-+ (b)^=(t),\
-+ (a)^=((t)<<(n)))
-+
-+#undef HPERM_OP
-+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
-+ (a)=(a)^(t)^(t>>(16-(n))))\
-+
-+void fcrypt_body(out, ks, Eswap0, Eswap1)
-+DES_LONG *out;
-+des_key_schedule ks;
-+DES_LONG Eswap0;
-+DES_LONG Eswap1;
-+ {
-+ register DES_LONG l,r,t,u;
-+#ifdef DES_PTR
-+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
-+#endif
-+ register DES_LONG *s;
-+ register int j;
-+ register DES_LONG E0,E1;
-+
-+ l=0;
-+ r=0;
-+
-+ s=(DES_LONG *)ks;
-+ E0=Eswap0;
-+ E1=Eswap1;
-+
-+ for (j=0; j<25; j++)
-+ {
-+#ifdef DES_UNROLL
-+ register int i;
-+
-+ for (i=0; i<32; i+=8)
-+ {
-+ D_ENCRYPT(l,r,i+0); /* 1 */
-+ D_ENCRYPT(r,l,i+2); /* 2 */
-+ D_ENCRYPT(l,r,i+4); /* 1 */
-+ D_ENCRYPT(r,l,i+6); /* 2 */
-+ }
-+#else
-+ D_ENCRYPT(l,r, 0); /* 1 */
-+ D_ENCRYPT(r,l, 2); /* 2 */
-+ D_ENCRYPT(l,r, 4); /* 3 */
-+ D_ENCRYPT(r,l, 6); /* 4 */
-+ D_ENCRYPT(l,r, 8); /* 5 */
-+ D_ENCRYPT(r,l,10); /* 6 */
-+ D_ENCRYPT(l,r,12); /* 7 */
-+ D_ENCRYPT(r,l,14); /* 8 */
-+ D_ENCRYPT(l,r,16); /* 9 */
-+ D_ENCRYPT(r,l,18); /* 10 */
-+ D_ENCRYPT(l,r,20); /* 11 */
-+ D_ENCRYPT(r,l,22); /* 12 */
-+ D_ENCRYPT(l,r,24); /* 13 */
-+ D_ENCRYPT(r,l,26); /* 14 */
-+ D_ENCRYPT(l,r,28); /* 15 */
-+ D_ENCRYPT(r,l,30); /* 16 */
-+#endif
-+
-+ t=l;
-+ l=r;
-+ r=t;
-+ }
-+ l=ROTATE(l,3)&0xffffffffL;
-+ r=ROTATE(r,3)&0xffffffffL;
-+
-+ PERM_OP(l,r,t, 1,0x55555555L);
-+ PERM_OP(r,l,t, 8,0x00ff00ffL);
-+ PERM_OP(l,r,t, 2,0x33333333L);
-+ PERM_OP(r,l,t,16,0x0000ffffL);
-+ PERM_OP(l,r,t, 4,0x0f0f0f0fL);
-+
-+ out[0]=r;
-+ out[1]=l;
-+ }
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/options.txt Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,39 @@
-+Note that the UNROLL option makes the 'inner' des loop unroll all 16 rounds
-+instead of the default 4.
-+RISC1 and RISC2 are 2 alternatives for the inner loop and
-+PTR means to use pointers arithmatic instead of arrays.
-+
-+FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - assembler 577,000 4620k/s
-+IRIX 6.2 - R10000 195mhz - cc (-O3 -n32) - UNROLL RISC2 PTR 496,000 3968k/s
-+solaris 2.5.1 usparc 167mhz?? - SC4.0 - UNROLL RISC1 PTR [1] 459,400 3672k/s
-+FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - UNROLL RISC1 433,000 3468k/s
-+solaris 2.5.1 usparc 167mhz?? - gcc 2.7.2 - UNROLL 380,000 3041k/s
-+linux - pentium 100mhz - gcc 2.7.0 - assembler 281,000 2250k/s
-+NT 4.0 - pentium 100mhz - VC 4.2 - assembler 281,000 2250k/s
-+AIX 4.1? - PPC604 100mhz - cc - UNROLL 275,000 2200k/s
-+IRIX 5.3 - R4400 200mhz - gcc 2.6.3 - UNROLL RISC2 PTR 235,300 1882k/s
-+IRIX 5.3 - R4400 200mhz - cc - UNROLL RISC2 PTR 233,700 1869k/s
-+NT 4.0 - pentium 100mhz - VC 4.2 - UNROLL RISC1 PTR 191,000 1528k/s
-+DEC Alpha 165mhz?? - cc - RISC2 PTR [2] 181,000 1448k/s
-+linux - pentium 100mhz - gcc 2.7.0 - UNROLL RISC1 PTR 158,500 1268k/s
-+HPUX 10 - 9000/887 - cc - UNROLL [3] 148,000 1190k/s
-+solaris 2.5.1 - sparc 10 50mhz - gcc 2.7.2 - UNROLL 123,600 989k/s
-+IRIX 5.3 - R4000 100mhz - cc - UNROLL RISC2 PTR 101,000 808k/s
-+DGUX - 88100 50mhz(?) - gcc 2.6.3 - UNROLL 81,000 648k/s
-+solaris 2.4 486 50mhz - gcc 2.6.3 - assembler 65,000 522k/s
-+HPUX 10 - 9000/887 - k&r cc (default compiler) - UNROLL PTR 76,000 608k/s
-+solaris 2.4 486 50mhz - gcc 2.6.3 - UNROLL RISC2 43,500 344k/s
-+AIX - old slow one :-) - cc - 39,000 312k/s
-+
-+Notes.
-+[1] For the ultra sparc, SunC 4.0
-+ cc -xtarget=ultra -xarch=v8plus -Xa -xO5, running 'des_opts'
-+ gives a speed of 344,000 des/s while 'speed' gives 459,000 des/s.
-+ I'll record the higher since it is coming from the library but it
-+ is all rather weird.
-+[2] Similar to the ultra sparc ([1]), 181,000 for 'des_opts' vs 175,000.
-+[3] I was unable to get access to this machine when it was not heavily loaded.
-+ As such, my timing program was never able to get more that %30 of the CPU.
-+ This would cause the program to give much lower speed numbers because
-+ it would be 'fighting' to stay in the cache with the other CPU burning
-+ processes.
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/podd.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,75 @@
-+/* crypto/des/podd.h */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+static const unsigned char odd_parity[256]={
-+ 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
-+ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
-+ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
-+ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
-+ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
-+ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
-+ 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
-+112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
-+128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
-+145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
-+161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
-+176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
-+193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
-+208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
-+224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
-+241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/set_key.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,246 @@
-+/* crypto/des/set_key.c */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+/* set_key.c v 1.4 eay 24/9/91
-+ * 1.4 Speed up by 400% :-)
-+ * 1.3 added register declarations.
-+ * 1.2 unrolled make_key_sched a bit more
-+ * 1.1 added norm_expand_bits
-+ * 1.0 First working version
-+ */
-+#include "des_locl.h"
-+#include "podd.h"
-+#include "sk.h"
-+
-+#ifndef NOPROTO
-+static int check_parity(des_cblock (*key));
-+#else
-+static int check_parity();
-+#endif
-+
-+int des_check_key=0;
-+
-+void des_set_odd_parity(key)
-+des_cblock (*key);
-+ {
-+ int i;
-+
-+ for (i=0; i<DES_KEY_SZ; i++)
-+ (*key)[i]=odd_parity[(*key)[i]];
-+ }
-+
-+static int check_parity(key)
-+des_cblock (*key);
-+ {
-+ int i;
-+
-+ for (i=0; i<DES_KEY_SZ; i++)
-+ {
-+ if ((*key)[i] != odd_parity[(*key)[i]])
-+ return(0);
-+ }
-+ return(1);
-+ }
-+
-+/* Weak and semi week keys as take from
-+ * %A D.W. Davies
-+ * %A W.L. Price
-+ * %T Security for Computer Networks
-+ * %I John Wiley & Sons
-+ * %D 1984
-+ * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
-+ * (and actual cblock values).
-+ */
-+#define NUM_WEAK_KEY 16
-+static des_cblock weak_keys[NUM_WEAK_KEY]={
-+ /* weak keys */
-+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
-+ {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
-+ {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
-+ {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},
-+ /* semi-weak keys */
-+ {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
-+ {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
-+ {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
-+ {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
-+ {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
-+ {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
-+ {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
-+ {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
-+ {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
-+ {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
-+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
-+ {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
-+
-+int des_is_weak_key(key)
-+des_cblock (*key);
-+ {
-+ int i;
-+
-+ for (i=0; i<NUM_WEAK_KEY; i++)
-+ /* Added == 0 to comparision, I obviously don't run
-+ * this section very often :-(, thanks to
-+ * engineering@MorningStar.Com for the fix
-+ * eay 93/06/29
-+ * Another problem, I was comparing only the first 4
-+ * bytes, 97/03/18 */
-+ if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1);
-+ return(0);
-+ }
-+
-+/* NOW DEFINED IN des_local.h
-+ * See ecb_encrypt.c for a pseudo description of these macros.
-+ * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
-+ * (b)^=(t),\
-+ * (a)=((a)^((t)<<(n))))
-+ */
-+
-+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
-+ (a)=(a)^(t)^(t>>(16-(n))))
-+
-+/* return 0 if key parity is odd (correct),
-+ * return -1 if key parity error,
-+ * return -2 if illegal weak key.
-+ */
-+int des_set_key(key, schedule)
-+des_cblock (*key);
-+des_key_schedule schedule;
-+ {
-+ static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
-+ register DES_LONG c,d,t,s,t2;
-+ register unsigned char *in;
-+ register DES_LONG *k;
-+ register int i;
-+
-+ if (des_check_key)
-+ {
-+ if (!check_parity(key))
-+ return(-1);
-+
-+ if (des_is_weak_key(key))
-+ return(-2);
-+ }
-+
-+ k=(DES_LONG *)schedule;
-+ in=(unsigned char *)key;
-+
-+ c2l(in,c);
-+ c2l(in,d);
-+
-+ /* do PC1 in 60 simple operations */
-+/* PERM_OP(d,c,t,4,0x0f0f0f0fL);
-+ HPERM_OP(c,t,-2, 0xcccc0000L);
-+ HPERM_OP(c,t,-1, 0xaaaa0000L);
-+ HPERM_OP(c,t, 8, 0x00ff0000L);
-+ HPERM_OP(c,t,-1, 0xaaaa0000L);
-+ HPERM_OP(d,t,-8, 0xff000000L);
-+ HPERM_OP(d,t, 8, 0x00ff0000L);
-+ HPERM_OP(d,t, 2, 0x33330000L);
-+ d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
-+ d=(d>>8)|((c&0xf0000000L)>>4);
-+ c&=0x0fffffffL; */
-+
-+ /* I now do it in 47 simple operations :-)
-+ * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
-+ * for the inspiration. :-) */
-+ PERM_OP (d,c,t,4,0x0f0f0f0fL);
-+ HPERM_OP(c,t,-2,0xcccc0000L);
-+ HPERM_OP(d,t,-2,0xcccc0000L);
-+ PERM_OP (d,c,t,1,0x55555555L);
-+ PERM_OP (c,d,t,8,0x00ff00ffL);
-+ PERM_OP (d,c,t,1,0x55555555L);
-+ d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) |
-+ ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
-+ c&=0x0fffffffL;
-+
-+ for (i=0; i<ITERATIONS; i++)
-+ {
-+ if (shifts2[i])
-+ { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
-+ else
-+ { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
-+ c&=0x0fffffffL;
-+ d&=0x0fffffffL;
-+ /* could be a few less shifts but I am to lazy at this
-+ * point in time to investigate */
-+ s= des_skb[0][ (c )&0x3f ]|
-+ des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
-+ des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
-+ des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
-+ ((c>>22L)&0x38)];
-+ t= des_skb[4][ (d )&0x3f ]|
-+ des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
-+ des_skb[6][ (d>>15L)&0x3f ]|
-+ des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
-+
-+ /* table contained 0213 4657 */
-+ t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
-+ *(k++)=ROTATE(t2,30)&0xffffffffL;
-+
-+ t2=((s>>16L)|(t&0xffff0000L));
-+ *(k++)=ROTATE(t2,26)&0xffffffffL;
-+ }
-+ return(0);
-+ }
-+
-+int des_key_sched(key, schedule)
-+des_cblock (*key);
-+des_key_schedule schedule;
-+ {
-+ return(des_set_key(key,schedule));
-+ }
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/sk.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,204 @@
-+/* crypto/des/sk.h */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+static const DES_LONG des_skb[8][64]={
-+{
-+/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
-+0x00000000L,0x00000010L,0x20000000L,0x20000010L,
-+0x00010000L,0x00010010L,0x20010000L,0x20010010L,
-+0x00000800L,0x00000810L,0x20000800L,0x20000810L,
-+0x00010800L,0x00010810L,0x20010800L,0x20010810L,
-+0x00000020L,0x00000030L,0x20000020L,0x20000030L,
-+0x00010020L,0x00010030L,0x20010020L,0x20010030L,
-+0x00000820L,0x00000830L,0x20000820L,0x20000830L,
-+0x00010820L,0x00010830L,0x20010820L,0x20010830L,
-+0x00080000L,0x00080010L,0x20080000L,0x20080010L,
-+0x00090000L,0x00090010L,0x20090000L,0x20090010L,
-+0x00080800L,0x00080810L,0x20080800L,0x20080810L,
-+0x00090800L,0x00090810L,0x20090800L,0x20090810L,
-+0x00080020L,0x00080030L,0x20080020L,0x20080030L,
-+0x00090020L,0x00090030L,0x20090020L,0x20090030L,
-+0x00080820L,0x00080830L,0x20080820L,0x20080830L,
-+0x00090820L,0x00090830L,0x20090820L,0x20090830L,
-+},{
-+/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
-+0x00000000L,0x02000000L,0x00002000L,0x02002000L,
-+0x00200000L,0x02200000L,0x00202000L,0x02202000L,
-+0x00000004L,0x02000004L,0x00002004L,0x02002004L,
-+0x00200004L,0x02200004L,0x00202004L,0x02202004L,
-+0x00000400L,0x02000400L,0x00002400L,0x02002400L,
-+0x00200400L,0x02200400L,0x00202400L,0x02202400L,
-+0x00000404L,0x02000404L,0x00002404L,0x02002404L,
-+0x00200404L,0x02200404L,0x00202404L,0x02202404L,
-+0x10000000L,0x12000000L,0x10002000L,0x12002000L,
-+0x10200000L,0x12200000L,0x10202000L,0x12202000L,
-+0x10000004L,0x12000004L,0x10002004L,0x12002004L,
-+0x10200004L,0x12200004L,0x10202004L,0x12202004L,
-+0x10000400L,0x12000400L,0x10002400L,0x12002400L,
-+0x10200400L,0x12200400L,0x10202400L,0x12202400L,
-+0x10000404L,0x12000404L,0x10002404L,0x12002404L,
-+0x10200404L,0x12200404L,0x10202404L,0x12202404L,
-+},{
-+/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
-+0x00000000L,0x00000001L,0x00040000L,0x00040001L,
-+0x01000000L,0x01000001L,0x01040000L,0x01040001L,
-+0x00000002L,0x00000003L,0x00040002L,0x00040003L,
-+0x01000002L,0x01000003L,0x01040002L,0x01040003L,
-+0x00000200L,0x00000201L,0x00040200L,0x00040201L,
-+0x01000200L,0x01000201L,0x01040200L,0x01040201L,
-+0x00000202L,0x00000203L,0x00040202L,0x00040203L,
-+0x01000202L,0x01000203L,0x01040202L,0x01040203L,
-+0x08000000L,0x08000001L,0x08040000L,0x08040001L,
-+0x09000000L,0x09000001L,0x09040000L,0x09040001L,
-+0x08000002L,0x08000003L,0x08040002L,0x08040003L,
-+0x09000002L,0x09000003L,0x09040002L,0x09040003L,
-+0x08000200L,0x08000201L,0x08040200L,0x08040201L,
-+0x09000200L,0x09000201L,0x09040200L,0x09040201L,
-+0x08000202L,0x08000203L,0x08040202L,0x08040203L,
-+0x09000202L,0x09000203L,0x09040202L,0x09040203L,
-+},{
-+/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
-+0x00000000L,0x00100000L,0x00000100L,0x00100100L,
-+0x00000008L,0x00100008L,0x00000108L,0x00100108L,
-+0x00001000L,0x00101000L,0x00001100L,0x00101100L,
-+0x00001008L,0x00101008L,0x00001108L,0x00101108L,
-+0x04000000L,0x04100000L,0x04000100L,0x04100100L,
-+0x04000008L,0x04100008L,0x04000108L,0x04100108L,
-+0x04001000L,0x04101000L,0x04001100L,0x04101100L,
-+0x04001008L,0x04101008L,0x04001108L,0x04101108L,
-+0x00020000L,0x00120000L,0x00020100L,0x00120100L,
-+0x00020008L,0x00120008L,0x00020108L,0x00120108L,
-+0x00021000L,0x00121000L,0x00021100L,0x00121100L,
-+0x00021008L,0x00121008L,0x00021108L,0x00121108L,
-+0x04020000L,0x04120000L,0x04020100L,0x04120100L,
-+0x04020008L,0x04120008L,0x04020108L,0x04120108L,
-+0x04021000L,0x04121000L,0x04021100L,0x04121100L,
-+0x04021008L,0x04121008L,0x04021108L,0x04121108L,
-+},{
-+/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
-+0x00000000L,0x10000000L,0x00010000L,0x10010000L,
-+0x00000004L,0x10000004L,0x00010004L,0x10010004L,
-+0x20000000L,0x30000000L,0x20010000L,0x30010000L,
-+0x20000004L,0x30000004L,0x20010004L,0x30010004L,
-+0x00100000L,0x10100000L,0x00110000L,0x10110000L,
-+0x00100004L,0x10100004L,0x00110004L,0x10110004L,
-+0x20100000L,0x30100000L,0x20110000L,0x30110000L,
-+0x20100004L,0x30100004L,0x20110004L,0x30110004L,
-+0x00001000L,0x10001000L,0x00011000L,0x10011000L,
-+0x00001004L,0x10001004L,0x00011004L,0x10011004L,
-+0x20001000L,0x30001000L,0x20011000L,0x30011000L,
-+0x20001004L,0x30001004L,0x20011004L,0x30011004L,
-+0x00101000L,0x10101000L,0x00111000L,0x10111000L,
-+0x00101004L,0x10101004L,0x00111004L,0x10111004L,
-+0x20101000L,0x30101000L,0x20111000L,0x30111000L,
-+0x20101004L,0x30101004L,0x20111004L,0x30111004L,
-+},{
-+/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
-+0x00000000L,0x08000000L,0x00000008L,0x08000008L,
-+0x00000400L,0x08000400L,0x00000408L,0x08000408L,
-+0x00020000L,0x08020000L,0x00020008L,0x08020008L,
-+0x00020400L,0x08020400L,0x00020408L,0x08020408L,
-+0x00000001L,0x08000001L,0x00000009L,0x08000009L,
-+0x00000401L,0x08000401L,0x00000409L,0x08000409L,
-+0x00020001L,0x08020001L,0x00020009L,0x08020009L,
-+0x00020401L,0x08020401L,0x00020409L,0x08020409L,
-+0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
-+0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
-+0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
-+0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
-+0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
-+0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
-+0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
-+0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
-+},{
-+/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
-+0x00000000L,0x00000100L,0x00080000L,0x00080100L,
-+0x01000000L,0x01000100L,0x01080000L,0x01080100L,
-+0x00000010L,0x00000110L,0x00080010L,0x00080110L,
-+0x01000010L,0x01000110L,0x01080010L,0x01080110L,
-+0x00200000L,0x00200100L,0x00280000L,0x00280100L,
-+0x01200000L,0x01200100L,0x01280000L,0x01280100L,
-+0x00200010L,0x00200110L,0x00280010L,0x00280110L,
-+0x01200010L,0x01200110L,0x01280010L,0x01280110L,
-+0x00000200L,0x00000300L,0x00080200L,0x00080300L,
-+0x01000200L,0x01000300L,0x01080200L,0x01080300L,
-+0x00000210L,0x00000310L,0x00080210L,0x00080310L,
-+0x01000210L,0x01000310L,0x01080210L,0x01080310L,
-+0x00200200L,0x00200300L,0x00280200L,0x00280300L,
-+0x01200200L,0x01200300L,0x01280200L,0x01280300L,
-+0x00200210L,0x00200310L,0x00280210L,0x00280310L,
-+0x01200210L,0x01200310L,0x01280210L,0x01280310L,
-+},{
-+/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
-+0x00000000L,0x04000000L,0x00040000L,0x04040000L,
-+0x00000002L,0x04000002L,0x00040002L,0x04040002L,
-+0x00002000L,0x04002000L,0x00042000L,0x04042000L,
-+0x00002002L,0x04002002L,0x00042002L,0x04042002L,
-+0x00000020L,0x04000020L,0x00040020L,0x04040020L,
-+0x00000022L,0x04000022L,0x00040022L,0x04040022L,
-+0x00002020L,0x04002020L,0x00042020L,0x04042020L,
-+0x00002022L,0x04002022L,0x00042022L,0x04042022L,
-+0x00000800L,0x04000800L,0x00040800L,0x04040800L,
-+0x00000802L,0x04000802L,0x00040802L,0x04040802L,
-+0x00002800L,0x04002800L,0x00042800L,0x04042800L,
-+0x00002802L,0x04002802L,0x00042802L,0x04042802L,
-+0x00000820L,0x04000820L,0x00040820L,0x04040820L,
-+0x00000822L,0x04000822L,0x00040822L,0x04040822L,
-+0x00002820L,0x04002820L,0x00042820L,0x04042820L,
-+0x00002822L,0x04002822L,0x00042822L,0x04042822L,
-+}};
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/speed.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,329 @@
-+/* crypto/des/speed.c */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */
-+/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */
-+
-+#ifndef MSDOS
-+#define TIMES
-+#endif
-+
-+#include <stdio.h>
-+#ifndef MSDOS
-+#include <unistd.h>
-+#else
-+#include <io.h>
-+extern int exit();
-+#endif
-+#include <signal.h>
-+#ifndef VMS
-+#ifndef _IRIX
-+#include <time.h>
-+#endif
-+#ifdef TIMES
-+#include <sys/types.h>
-+#include <sys/times.h>
-+#endif
-+#else /* VMS */
-+#include <types.h>
-+struct tms {
-+ time_t tms_utime;
-+ time_t tms_stime;
-+ time_t tms_uchild; /* I dunno... */
-+ time_t tms_uchildsys; /* so these names are a guess :-) */
-+ }
-+#endif
-+#ifndef TIMES
-+#include <sys/timeb.h>
-+#endif
-+
-+#ifdef sun
-+#include <limits.h>
-+#include <sys/param.h>
-+#endif
-+
-+#include "des_locl.h"
-+
-+/* The following if from times(3) man page. It may need to be changed */
-+#ifndef HZ
-+# ifndef CLK_TCK
-+# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
-+# ifndef VMS
-+# define HZ 100.0
-+# else /* VMS */
-+# define HZ 100.0
-+# endif
-+# else /* _BSD_CLK_TCK_ */
-+# define HZ ((double)_BSD_CLK_TCK_)
-+# endif
-+# else /* CLK_TCK */
-+# define HZ ((double)CLK_TCK)
-+# endif
-+#endif
-+
-+#define BUFSIZE ((long)1024)
-+long run=0;
-+
-+#ifndef NOPROTO
-+double Time_F(int s);
-+#else
-+double Time_F();
-+#endif
-+
-+#ifdef SIGALRM
-+#if defined(__STDC__) || defined(sgi) || defined(_AIX)
-+#define SIGRETTYPE void
-+#else
-+#define SIGRETTYPE int
-+#endif
-+
-+#ifndef NOPROTO
-+SIGRETTYPE sig_done(int sig);
-+#else
-+SIGRETTYPE sig_done();
-+#endif
-+
-+SIGRETTYPE sig_done(sig)
-+int sig;
-+ {
-+ signal(SIGALRM,sig_done);
-+ run=0;
-+#ifdef LINT
-+ sig=sig;
-+#endif
-+ }
-+#endif
-+
-+#define START 0
-+#define STOP 1
-+
-+double Time_F(s)
-+int s;
-+ {
-+ double ret;
-+#ifdef TIMES
-+ static struct tms tstart,tend;
-+
-+ if (s == START)
-+ {
-+ times(&tstart);
-+ return(0);
-+ }
-+ else
-+ {
-+ times(&tend);
-+ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
-+ return((ret == 0.0)?1e-6:ret);
-+ }
-+#else /* !times() */
-+ static struct timeb tstart,tend;
-+ long i;
-+
-+ if (s == START)
-+ {
-+ ftime(&tstart);
-+ return(0);
-+ }
-+ else
-+ {
-+ ftime(&tend);
-+ i=(long)tend.millitm-(long)tstart.millitm;
-+ ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
-+ return((ret == 0.0)?1e-6:ret);
-+ }
-+#endif
-+ }
-+
-+int main(argc,argv)
-+int argc;
-+char **argv;
-+ {
-+ long count;
-+ static unsigned char buf[BUFSIZE];
-+ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
-+ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
-+ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
-+ des_key_schedule sch,sch2,sch3;
-+ double a,b,c,d,e;
-+#ifndef SIGALRM
-+ long ca,cb,cc,cd,ce;
-+#endif
-+
-+#ifndef TIMES
-+ printf("To get the most acurate results, try to run this\n");
-+ printf("program when this computer is idle.\n");
-+#endif
-+
-+ des_set_key((C_Block *)key2,sch2);
-+ des_set_key((C_Block *)key3,sch3);
-+
-+#ifndef SIGALRM
-+ printf("First we calculate the approximate speed ...\n");
-+ des_set_key((C_Block *)key,sch);
-+ count=10;
-+ do {
-+ long i;
-+ DES_LONG data[2];
-+
-+ count*=2;
-+ Time_F(START);
-+ for (i=count; i; i--)
-+ des_encrypt(data,&(sch[0]),DES_ENCRYPT);
-+ d=Time_F(STOP);
-+ } while (d < 3.0);
-+ ca=count;
-+ cb=count*3;
-+ cc=count*3*8/BUFSIZE+1;
-+ cd=count*8/BUFSIZE+1;
-+ ce=count/20+1;
-+ printf("Doing set_key %ld times\n",ca);
-+#define COND(d) (count != (d))
-+#define COUNT(d) (d)
-+#else
-+#define COND(c) (run)
-+#define COUNT(d) (count)
-+ signal(SIGALRM,sig_done);
-+ printf("Doing set_key for 10 seconds\n");
-+ alarm(10);
-+#endif
-+
-+ Time_F(START);
-+ for (count=0,run=1; COND(ca); count++)
-+ des_set_key((C_Block *)key,sch);
-+ d=Time_F(STOP);
-+ printf("%ld set_key's in %.2f seconds\n",count,d);
-+ a=((double)COUNT(ca))/d;
-+
-+#ifdef SIGALRM
-+ printf("Doing des_encrypt's for 10 seconds\n");
-+ alarm(10);
-+#else
-+ printf("Doing des_encrypt %ld times\n",cb);
-+#endif
-+ Time_F(START);
-+ for (count=0,run=1; COND(cb); count++)
-+ {
-+ DES_LONG data[2];
-+
-+ des_encrypt(data,&(sch[0]),DES_ENCRYPT);
-+ }
-+ d=Time_F(STOP);
-+ printf("%ld des_encrypt's in %.2f second\n",count,d);
-+ b=((double)COUNT(cb)*8)/d;
-+
-+#ifdef SIGALRM
-+ printf("Doing des_cbc_encrypt on %ld byte blocks for 10 seconds\n",
-+ BUFSIZE);
-+ alarm(10);
-+#else
-+ printf("Doing des_cbc_encrypt %ld times on %ld byte blocks\n",cc,
-+ BUFSIZE);
-+#endif
-+ Time_F(START);
-+ for (count=0,run=1; COND(cc); count++)
-+ des_ncbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE,&(sch[0]),
-+ (C_Block *)&(key[0]),DES_ENCRYPT);
-+ d=Time_F(STOP);
-+ printf("%ld des_cbc_encrypt's of %ld byte blocks in %.2f second\n",
-+ count,BUFSIZE,d);
-+ c=((double)COUNT(cc)*BUFSIZE)/d;
-+
-+#ifdef SIGALRM
-+ printf("Doing des_ede_cbc_encrypt on %ld byte blocks for 10 seconds\n",
-+ BUFSIZE);
-+ alarm(10);
-+#else
-+ printf("Doing des_ede_cbc_encrypt %ld times on %ld byte blocks\n",cd,
-+ BUFSIZE);
-+#endif
-+ Time_F(START);
-+ for (count=0,run=1; COND(cd); count++)
-+ des_ede3_cbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE,
-+ &(sch[0]),
-+ &(sch2[0]),
-+ &(sch3[0]),
-+ (C_Block *)&(key[0]),
-+ DES_ENCRYPT);
-+ d=Time_F(STOP);
-+ printf("%ld des_ede_cbc_encrypt's of %ld byte blocks in %.2f second\n",
-+ count,BUFSIZE,d);
-+ d=((double)COUNT(cd)*BUFSIZE)/d;
-+
-+#ifdef SIGALRM
-+ printf("Doing crypt for 10 seconds\n");
-+ alarm(10);
-+#else
-+ printf("Doing crypt %ld times\n",ce);
-+#endif
-+ Time_F(START);
-+ for (count=0,run=1; COND(ce); count++)
-+ crypt("testing1","ef");
-+ e=Time_F(STOP);
-+ printf("%ld crypts in %.2f second\n",count,e);
-+ e=((double)COUNT(ce))/e;
-+
-+ printf("set_key per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a);
-+ printf("DES raw ecb bytes per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b);
-+ printf("DES cbc bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c);
-+ printf("DES ede cbc bytes per sec = %12.2f (%9.3fuS)\n",d,8.0e6/d);
-+ printf("crypt per sec = %12.2f (%9.3fuS)\n",e,1.0e6/e);
-+ exit(0);
-+#if defined(LINT) || defined(MSDOS)
-+ return(0);
-+#endif
-+ }
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/spr.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,204 @@
-+/* crypto/des/spr.h */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+const DES_LONG des_SPtrans[8][64]={
-+{
-+/* nibble 0 */
-+0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
-+0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
-+0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
-+0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
-+0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
-+0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
-+0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
-+0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
-+0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
-+0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
-+0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
-+0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
-+0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
-+0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
-+0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
-+0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
-+},{
-+/* nibble 1 */
-+0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
-+0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
-+0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
-+0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
-+0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
-+0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
-+0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
-+0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
-+0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
-+0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
-+0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
-+0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
-+0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
-+0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
-+0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
-+0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
-+},{
-+/* nibble 2 */
-+0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
-+0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
-+0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
-+0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
-+0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
-+0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
-+0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
-+0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
-+0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
-+0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
-+0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
-+0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
-+0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
-+0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
-+0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
-+0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
-+},{
-+/* nibble 3 */
-+0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
-+0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
-+0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
-+0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
-+0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
-+0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
-+0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
-+0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
-+0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
-+0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
-+0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
-+0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
-+0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
-+0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
-+0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
-+0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
-+},{
-+/* nibble 4 */
-+0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
-+0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
-+0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
-+0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
-+0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
-+0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
-+0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
-+0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
-+0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
-+0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
-+0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
-+0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
-+0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
-+0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
-+0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
-+0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
-+},{
-+/* nibble 5 */
-+0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
-+0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
-+0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
-+0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
-+0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
-+0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
-+0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
-+0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
-+0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
-+0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
-+0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
-+0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
-+0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
-+0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
-+0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
-+0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
-+},{
-+/* nibble 6 */
-+0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
-+0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
-+0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
-+0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
-+0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
-+0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
-+0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
-+0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
-+0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
-+0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
-+0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
-+0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
-+0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
-+0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
-+0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
-+0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
-+},{
-+/* nibble 7 */
-+0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
-+0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
-+0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
-+0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
-+0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
-+0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
-+0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
-+0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
-+0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
-+0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
-+0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
-+0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
-+0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
-+0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
-+0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
-+0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
-+}};
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/crypto/aes.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,97 @@
-+// I retain copyright in this code but I encourage its free use provided
-+// that I don't carry any responsibility for the results. I am especially
-+// happy to see it used in free and open source software. If you do use
-+// it I would appreciate an acknowledgement of its origin in the code or
-+// the product that results and I would also appreciate knowing a little
-+// about the use to which it is being put. I am grateful to Frank Yellin
-+// for some ideas that are used in this implementation.
-+//
-+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
-+//
-+// This is an implementation of the AES encryption algorithm (Rijndael)
-+// designed by Joan Daemen and Vincent Rijmen. This version is designed
-+// to provide both fixed and dynamic block and key lengths and can also
-+// run with either big or little endian internal byte order (see aes.h).
-+// It inputs block and key lengths in bytes with the legal values being
-+// 16, 24 and 32.
-+
-+/*
-+ * Modified by Jari Ruusu, May 1 2001
-+ * - Fixed some compile warnings, code was ok but gcc warned anyway.
-+ * - Changed basic types: byte -> unsigned char, word -> u_int32_t
-+ * - Major name space cleanup: Names visible to outside now begin
-+ * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
-+ * - Removed C++ and DLL support as part of name space cleanup.
-+ * - Eliminated unnecessary recomputation of tables. (actual bug fix)
-+ * - Merged precomputed constant tables to aes.c file.
-+ * - Removed data alignment restrictions for portability reasons.
-+ * - Made block and key lengths accept bit count (128/192/256)
-+ * as well byte count (16/24/32).
-+ * - Removed all error checks. This change also eliminated the need
-+ * to preinitialize the context struct to zero.
-+ * - Removed some totally unused constants.
-+ */
-+
-+#ifndef _AES_H
-+#define _AES_H
-+
-+#if defined(__linux__) && defined(__KERNEL__)
-+# include <linux/types.h>
-+#else
-+# include <sys/types.h>
-+#endif
-+
-+// CONFIGURATION OPTIONS (see also aes.c)
-+//
-+// Define AES_BLOCK_SIZE to set the cipher block size (16, 24 or 32) or
-+// leave this undefined for dynamically variable block size (this will
-+// result in much slower code).
-+// IMPORTANT NOTE: AES_BLOCK_SIZE is in BYTES (16, 24, 32 or undefined). If
-+// left undefined a slower version providing variable block length is compiled
-+
-+#define AES_BLOCK_SIZE 16
-+
-+// The number of key schedule words for different block and key lengths
-+// allowing for method of computation which requires the length to be a
-+// multiple of the key length
-+//
-+// Nk = 4 6 8
-+// -------------
-+// Nb = 4 | 60 60 64
-+// 6 | 96 90 96
-+// 8 | 120 120 120
-+
-+#if !defined(AES_BLOCK_SIZE) || (AES_BLOCK_SIZE == 32)
-+#define AES_KS_LENGTH 120
-+#define AES_RC_LENGTH 29
-+#else
-+#define AES_KS_LENGTH 4 * AES_BLOCK_SIZE
-+#define AES_RC_LENGTH (9 * AES_BLOCK_SIZE) / 8 - 8
-+#endif
-+
-+typedef struct
-+{
-+ u_int32_t aes_Nkey; // the number of words in the key input block
-+ u_int32_t aes_Nrnd; // the number of cipher rounds
-+ u_int32_t aes_e_key[AES_KS_LENGTH]; // the encryption key schedule
-+ u_int32_t aes_d_key[AES_KS_LENGTH]; // the decryption key schedule
-+#if !defined(AES_BLOCK_SIZE)
-+ u_int32_t aes_Ncol; // the number of columns in the cipher state
-+#endif
-+} aes_context;
-+
-+// THE CIPHER INTERFACE
-+
-+#if !defined(AES_BLOCK_SIZE)
-+extern void aes_set_blk(aes_context *, const int);
-+#endif
-+extern void aes_set_key(aes_context *, const unsigned char [], const int, const int);
-+extern void aes_encrypt(const aes_context *, const unsigned char [], unsigned char []);
-+extern void aes_decrypt(const aes_context *, const unsigned char [], unsigned char []);
-+
-+// The block length inputs to aes_set_block and aes_set_key are in numbers
-+// of bytes or bits. The calls to subroutines must be made in the above
-+// order but multiple calls can be made without repeating earlier calls
-+// if their parameters have not changed.
-+
-+#endif // _AES_H
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/crypto/aes_cbc.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,4 @@
-+/* Glue header */
-+#include "aes.h"
-+int AES_set_key(aes_context *aes_ctx, const u_int8_t * key, int keysize);
-+int AES_cbc_encrypt(aes_context *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt);
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/crypto/aes_xcbc_mac.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,12 @@
-+#ifndef _AES_XCBC_MAC_H
-+#define _AES_XCBC_MAC_H
-+
-+typedef u_int32_t aes_block[4];
-+typedef struct {
-+ aes_context ctx_k1;
-+ aes_block k2;
-+ aes_block k3;
-+} aes_context_mac;
-+int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen);
-+int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]);
-+#endif /* _AES_XCBC_MAC_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/crypto/cbc_generic.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,110 @@
-+#ifndef _CBC_GENERIC_H
-+#define _CBC_GENERIC_H
-+/*
-+ * CBC macro helpers
-+ *
-+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ */
-+
-+/*
-+ * Heavily inspired in loop_AES
-+ */
-+#define CBC_IMPL_BLK16(name, ctx_type, addr_type, enc_func, dec_func) \
-+int name(ctx_type *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
-+ int ret=ilen, pos; \
-+ const u_int32_t *iv_i; \
-+ if ((ilen) % 16) return 0; \
-+ if (encrypt) { \
-+ pos=0; \
-+ while(pos<ilen) { \
-+ if (pos==0) \
-+ iv_i=(const u_int32_t*) iv; \
-+ else \
-+ iv_i=(const u_int32_t*) (out-16); \
-+ *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
-+ *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
-+ *((u_int32_t *)(&out[ 8])) = iv_i[2]^*((const u_int32_t *)(&in[ 8])); \
-+ *((u_int32_t *)(&out[12])) = iv_i[3]^*((const u_int32_t *)(&in[12])); \
-+ enc_func(ctx, (addr_type) out, (addr_type) out); \
-+ in+=16; \
-+ out+=16; \
-+ pos+=16; \
-+ } \
-+ } else { \
-+ pos=ilen-16; \
-+ in+=pos; \
-+ out+=pos; \
-+ while(pos>=0) { \
-+ dec_func(ctx, (const addr_type) in, (addr_type) out); \
-+ if (pos==0) \
-+ iv_i=(const u_int32_t*) (iv); \
-+ else \
-+ iv_i=(const u_int32_t*) (in-16); \
-+ *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
-+ *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
-+ *((u_int32_t *)(&out[ 8])) ^= iv_i[2]; \
-+ *((u_int32_t *)(&out[12])) ^= iv_i[3]; \
-+ in-=16; \
-+ out-=16; \
-+ pos-=16; \
-+ } \
-+ } \
-+ return ret; \
-+}
-+#define CBC_IMPL_BLK8(name, ctx_type, addr_type, enc_func, dec_func) \
-+int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
-+ int ret=ilen, pos; \
-+ const u_int32_t *iv_i; \
-+ if ((ilen) % 8) return 0; \
-+ if (encrypt) { \
-+ pos=0; \
-+ while(pos<ilen) { \
-+ if (pos==0) \
-+ iv_i=(const u_int32_t*) iv; \
-+ else \
-+ iv_i=(const u_int32_t*) (out-8); \
-+ *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
-+ *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
-+ enc_func(ctx, (addr_type)out, (addr_type)out); \
-+ in+=8; \
-+ out+=8; \
-+ pos+=8; \
-+ } \
-+ } else { \
-+ pos=ilen-8; \
-+ in+=pos; \
-+ out+=pos; \
-+ while(pos>=0) { \
-+ dec_func(ctx, (const addr_type)in, (addr_type)out); \
-+ if (pos==0) \
-+ iv_i=(const u_int32_t*) (iv); \
-+ else \
-+ iv_i=(const u_int32_t*) (in-8); \
-+ *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
-+ *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
-+ in-=8; \
-+ out-=8; \
-+ pos-=8; \
-+ } \
-+ } \
-+ return ret; \
-+}
-+#define CBC_DECL(name, ctx_type) \
-+int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt)
-+/*
-+Eg.:
-+CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
-+CBC_DECL(AES_cbc_encrypt, aes_context);
-+*/
-+#endif /* _CBC_GENERIC_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/crypto/des.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,298 @@
-+/* crypto/des/des.org */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
-+ *
-+ * Always modify des.org since des.h is automatically generated from
-+ * it during SSLeay configuration.
-+ *
-+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
-+ */
-+
-+#ifndef HEADER_DES_H
-+#define HEADER_DES_H
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+
-+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
-+ * %20 speed up (longs are 8 bytes, int's are 4). */
-+/* Must be unsigned int on ia64/Itanium or DES breaks badly */
-+
-+#ifdef __KERNEL__
-+#include <linux/types.h>
-+#else
-+#include <sys/types.h>
-+#endif
-+
-+#ifndef DES_LONG
-+#define DES_LONG u_int32_t
-+#endif
-+
-+typedef unsigned char des_cblock[8];
-+typedef struct { des_cblock ks; } des_key_schedule[16];
-+
-+#define DES_KEY_SZ (sizeof(des_cblock))
-+#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
-+
-+#define DES_ENCRYPT 1
-+#define DES_DECRYPT 0
-+
-+#define DES_CBC_MODE 0
-+#define DES_PCBC_MODE 1
-+
-+#define des_ecb2_encrypt(i,o,k1,k2,e) \
-+ des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
-+
-+#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
-+ des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
-+
-+#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
-+ des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
-+
-+#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
-+ des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
-+
-+#define C_Block des_cblock
-+#define Key_schedule des_key_schedule
-+#ifdef KERBEROS
-+#define ENCRYPT DES_ENCRYPT
-+#define DECRYPT DES_DECRYPT
-+#endif
-+#define KEY_SZ DES_KEY_SZ
-+#define string_to_key des_string_to_key
-+#define read_pw_string des_read_pw_string
-+#define random_key des_random_key
-+#define pcbc_encrypt des_pcbc_encrypt
-+#define set_key des_set_key
-+#define key_sched des_key_sched
-+#define ecb_encrypt des_ecb_encrypt
-+#define cbc_encrypt des_cbc_encrypt
-+#define ncbc_encrypt des_ncbc_encrypt
-+#define xcbc_encrypt des_xcbc_encrypt
-+#define cbc_cksum des_cbc_cksum
-+#define quad_cksum des_quad_cksum
-+
-+/* For compatibility with the MIT lib - eay 20/05/92 */
-+typedef des_key_schedule bit_64;
-+#define des_fixup_key_parity des_set_odd_parity
-+#define des_check_key_parity check_parity
-+
-+extern int des_check_key; /* defaults to false */
-+extern int des_rw_mode; /* defaults to DES_PCBC_MODE */
-+
-+/* The next line is used to disable full ANSI prototypes, if your
-+ * compiler has problems with the prototypes, make sure this line always
-+ * evaluates to true :-) */
-+#if defined(MSDOS) || defined(__STDC__)
-+#undef NOPROTO
-+#endif
-+#ifndef NOPROTO
-+char *des_options(void);
-+void des_ecb3_encrypt(des_cblock *input,des_cblock *output,
-+ des_key_schedule ks1,des_key_schedule ks2,
-+ des_key_schedule ks3, int enc);
-+DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output,
-+ long length,des_key_schedule schedule,des_cblock *ivec);
-+void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
-+ des_key_schedule schedule,des_cblock *ivec,int enc);
-+void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
-+ des_key_schedule schedule,des_cblock *ivec,int enc);
-+void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,
-+ des_key_schedule schedule,des_cblock *ivec,
-+ des_cblock *inw,des_cblock *outw,int enc);
-+void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
-+ long length,des_key_schedule schedule,des_cblock *ivec,int enc);
-+void des_ecb_encrypt(des_cblock *input,des_cblock *output,
-+ des_key_schedule ks,int enc);
-+void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);
-+void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);
-+void des_encrypt3(DES_LONG *data, des_key_schedule ks1,
-+ des_key_schedule ks2, des_key_schedule ks3);
-+void des_decrypt3(DES_LONG *data, des_key_schedule ks1,
-+ des_key_schedule ks2, des_key_schedule ks3);
-+void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output,
-+ long length, des_key_schedule ks1, des_key_schedule ks2,
-+ des_key_schedule ks3, des_cblock *ivec, int enc);
-+void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
-+ long length, des_key_schedule ks1, des_key_schedule ks2,
-+ des_key_schedule ks3, des_cblock *ivec, int *num, int enc);
-+void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
-+ long length, des_key_schedule ks1, des_key_schedule ks2,
-+ des_key_schedule ks3, des_cblock *ivec, int *num);
-+
-+void des_xwhite_in2out(des_cblock (*des_key), des_cblock (*in_white),
-+ des_cblock (*out_white));
-+
-+int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
-+ des_cblock *iv);
-+int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
-+ des_cblock *iv);
-+char *des_fcrypt(const char *buf,const char *salt, char *ret);
-+#ifdef PERL5
-+char *des_crypt(const char *buf,const char *salt);
-+#else
-+/* some stupid compilers complain because I have declared char instead
-+ * of const char */
-+#ifndef __KERNEL__
-+#ifdef HEADER_DES_LOCL_H
-+char *crypt(const char *buf,const char *salt);
-+#else /* HEADER_DES_LOCL_H */
-+char *crypt(void);
-+#endif /* HEADER_DES_LOCL_H */
-+#endif /* __KERNEL__ */
-+#endif /* PERL5 */
-+void des_ofb_encrypt(unsigned char *in,unsigned char *out,
-+ int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
-+void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
-+ des_key_schedule schedule,des_cblock *ivec,int enc);
-+DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output,
-+ long length,int out_count,des_cblock *seed);
-+void des_random_seed(des_cblock key);
-+void des_random_key(des_cblock ret);
-+int des_read_password(des_cblock *key,char *prompt,int verify);
-+int des_read_2passwords(des_cblock *key1,des_cblock *key2,
-+ char *prompt,int verify);
-+int des_read_pw_string(char *buf,int length,char *prompt,int verify);
-+void des_set_odd_parity(des_cblock *key);
-+int des_is_weak_key(des_cblock *key);
-+int des_set_key(des_cblock *key,des_key_schedule schedule);
-+int des_key_sched(des_cblock *key,des_key_schedule schedule);
-+void des_string_to_key(char *str,des_cblock *key);
-+void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
-+void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
-+ des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
-+void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
-+ des_key_schedule schedule, des_cblock *ivec, int *num);
-+int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify);
-+
-+/* Extra functions from Mark Murray <mark@grondar.za> */
-+/* The following functions are not in the normal unix build or the
-+ * SSLeay build. When using the SSLeay build, use RAND_seed()
-+ * and RAND_bytes() instead. */
-+int des_new_random_key(des_cblock *key);
-+void des_init_random_number_generator(des_cblock *key);
-+void des_set_random_generator_seed(des_cblock *key);
-+void des_set_sequence_number(des_cblock new_sequence_number);
-+void des_generate_random_block(des_cblock *block);
-+
-+#else
-+
-+char *des_options();
-+void des_ecb3_encrypt();
-+DES_LONG des_cbc_cksum();
-+void des_cbc_encrypt();
-+void des_ncbc_encrypt();
-+void des_xcbc_encrypt();
-+void des_cfb_encrypt();
-+void des_ede3_cfb64_encrypt();
-+void des_ede3_ofb64_encrypt();
-+void des_ecb_encrypt();
-+void des_encrypt();
-+void des_encrypt2();
-+void des_encrypt3();
-+void des_decrypt3();
-+void des_ede3_cbc_encrypt();
-+int des_enc_read();
-+int des_enc_write();
-+char *des_fcrypt();
-+#ifdef PERL5
-+char *des_crypt();
-+#else
-+char *crypt();
-+#endif
-+void des_ofb_encrypt();
-+void des_pcbc_encrypt();
-+DES_LONG des_quad_cksum();
-+void des_random_seed();
-+void des_random_key();
-+int des_read_password();
-+int des_read_2passwords();
-+int des_read_pw_string();
-+void des_set_odd_parity();
-+int des_is_weak_key();
-+int des_set_key();
-+int des_key_sched();
-+void des_string_to_key();
-+void des_string_to_2keys();
-+void des_cfb64_encrypt();
-+void des_ofb64_encrypt();
-+int des_read_pw();
-+void des_xwhite_in2out();
-+
-+/* Extra functions from Mark Murray <mark@grondar.za> */
-+/* The following functions are not in the normal unix build or the
-+ * SSLeay build. When using the SSLeay build, use RAND_seed()
-+ * and RAND_bytes() instead. */
-+#ifdef FreeBSD
-+int des_new_random_key();
-+void des_init_random_number_generator();
-+void des_set_random_generator_seed();
-+void des_set_sequence_number();
-+void des_generate_random_block();
-+#endif
-+
-+#endif
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/mast.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,33 @@
-+struct mast_callbacks {
-+ int (*packet_encap)(struct device *mast, void *context,
-+ struct sk_buff *skb, int flowref);
-+ int (*link_inquire)(struct device *mast, void *context);
-+};
-+
-+
-+struct device *mast_init (int family,
-+ struct mast_callbacks *callbacks,
-+ unsigned int flags,
-+ unsigned int desired_unit,
-+ unsigned int max_flowref,
-+ void *context);
-+
-+int mast_destroy(struct device *mast);
-+
-+int mast_recv(struct device *mast, struct sk_buff *skb, int flowref);
-+
-+/* free this skb as being useless, increment failure count. */
-+int mast_toast(struct device *mast, struct sk_buff *skb, int flowref);
-+
-+int mast_linkstat (struct device *mast, int flowref,
-+ int status);
-+
-+int mast_setreference (struct device *mast,
-+ int defaultSA);
-+
-+int mast_setneighbor (struct device *mast,
-+ struct sockaddr *source,
-+ struct sockaddr *destination,
-+ int flowref);
-+
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,513 @@
-+#ifndef _OPENSWAN_H
-+/*
-+ * header file for FreeS/WAN library functions
-+ * Copyright (C) 1998, 1999, 2000 Henry Spencer.
-+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#define _OPENSWAN_H /* seen it, no need to see it again */
-+
-+
-+
-+/*
-+ * We've just got to have some datatypes defined... And annoyingly, just
-+ * where we get them depends on whether we're in userland or not.
-+ */
-+/* things that need to come from one place or the other, depending */
-+#ifdef __KERNEL__
-+#include <linux/types.h>
-+#include <linux/socket.h>
-+#include <linux/in.h>
-+#include <linux/string.h>
-+#include <linux/ctype.h>
-+#define assert(foo) /* nothing */
-+#else
-+#include <sys/types.h>
-+#include <netinet/in.h>
-+#include <string.h>
-+#include <ctype.h>
-+#include <assert.h>
-+#include <stdio.h>
-+
-+# define uint8_t u_int8_t
-+# define uint16_t u_int16_t
-+# define uint32_t u_int32_t
-+# define uint64_t u_int64_t
-+
-+
-+# define DEBUG_NO_STATIC static
-+
-+#endif
-+
-+#include <openswan/ipsec_param.h>
-+
-+
-+/*
-+ * Grab the kernel version to see if we have NET_21, and therefore
-+ * IPv6. Some of this is repeated from ipsec_kversions.h. Of course,
-+ * we aren't really testing if the kernel has IPv6, but rather if the
-+ * the include files do.
-+ */
-+#include <linux/version.h>
-+#ifndef KERNEL_VERSION
-+#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
-+#define NET_21
-+#endif
-+
-+#ifndef IPPROTO_COMP
-+# define IPPROTO_COMP 108
-+#endif /* !IPPROTO_COMP */
-+
-+#ifndef IPPROTO_INT
-+# define IPPROTO_INT 61
-+#endif /* !IPPROTO_INT */
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+#ifndef DEBUG_NO_STATIC
-+# define DEBUG_NO_STATIC
-+#endif
-+#else /* CONFIG_IPSEC_DEBUG */
-+#ifndef DEBUG_NO_STATIC
-+# define DEBUG_NO_STATIC static
-+#endif
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL /* KERNEL ifdef */
-+#ifndef NAT_TRAVERSAL
-+#define NAT_TRAVERSAL
-+#endif
-+#endif
-+#ifdef NAT_TRAVERSAL
-+#define ESPINUDP_WITH_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
-+#define ESPINUDP_WITH_NON_ESP 2 /* draft-ietf-ipsec-nat-t-ike-02 */
-+#endif
-+
-+/*
-+ * Basic data types for the address-handling functions.
-+ * ip_address and ip_subnet are supposed to be opaque types; do not
-+ * use their definitions directly, they are subject to change!
-+ */
-+
-+/* first, some quick fakes in case we're on an old system with no IPv6 */
-+#ifndef s6_addr16
-+struct in6_addr {
-+ union
-+ {
-+ __u8 u6_addr8[16];
-+ __u16 u6_addr16[8];
-+ __u32 u6_addr32[4];
-+ } in6_u;
-+#define s6_addr in6_u.u6_addr8
-+#define s6_addr16 in6_u.u6_addr16
-+#define s6_addr32 in6_u.u6_addr32
-+};
-+struct sockaddr_in6 {
-+ unsigned short int sin6_family; /* AF_INET6 */
-+ __u16 sin6_port; /* Transport layer port # */
-+ __u32 sin6_flowinfo; /* IPv6 flow information */
-+ struct in6_addr sin6_addr; /* IPv6 address */
-+ __u32 sin6_scope_id; /* scope id (new in RFC2553) */
-+};
-+#endif /* !s6_addr16 */
-+
-+/* then the main types */
-+typedef struct {
-+ union {
-+ struct sockaddr_in v4;
-+ struct sockaddr_in6 v6;
-+ } u;
-+} ip_address;
-+typedef struct {
-+ ip_address addr;
-+ int maskbits;
-+} ip_subnet;
-+
-+/* and the SA ID stuff */
-+#ifdef __KERNEL__
-+typedef __u32 ipsec_spi_t;
-+#else
-+typedef u_int32_t ipsec_spi_t;
-+#endif
-+typedef struct { /* to identify an SA, we need: */
-+ ip_address dst; /* A. destination host */
-+ ipsec_spi_t spi; /* B. 32-bit SPI, assigned by dest. host */
-+# define SPI_PASS 256 /* magic values... */
-+# define SPI_DROP 257 /* ...for use... */
-+# define SPI_REJECT 258 /* ...with SA_INT */
-+# define SPI_HOLD 259
-+# define SPI_TRAP 260
-+# define SPI_TRAPSUBNET 261
-+ int proto; /* C. protocol */
-+# define SA_ESP 50 /* IPPROTO_ESP */
-+# define SA_AH 51 /* IPPROTO_AH */
-+# define SA_IPIP 4 /* IPPROTO_IPIP */
-+# define SA_COMP 108 /* IPPROTO_COMP */
-+# define SA_INT 61 /* IANA reserved for internal use */
-+} ip_said;
-+
-+/* misc */
-+typedef const char *err_t; /* error message, or NULL for success */
-+struct prng { /* pseudo-random-number-generator guts */
-+ unsigned char sbox[256];
-+ int i, j;
-+ unsigned long count;
-+};
-+
-+
-+/*
-+ * definitions for user space, taken from freeswan/ipsec_sa.h
-+ */
-+typedef uint32_t IPsecSAref_t;
-+
-+#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
-+
-+#define IPsecSAref2NFmark(x) ((x) << (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
-+#define NFmark2IPsecSAref(x) ((x) >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
-+
-+#define IPSEC_SAREF_NULL (~((IPsecSAref_t)0))
-+
-+/* GCC magic for use in function definitions! */
-+#ifdef GCC_LINT
-+# define PRINTF_LIKE(n) __attribute__ ((format(printf, n, n+1)))
-+# define NEVER_RETURNS __attribute__ ((noreturn))
-+# define UNUSED __attribute__ ((unused))
-+# define BLANK_FORMAT " " /* GCC_LINT whines about empty formats */
-+#else
-+# define PRINTF_LIKE(n) /* ignore */
-+# define NEVER_RETURNS /* ignore */
-+# define UNUSED /* ignore */
-+# define BLANK_FORMAT ""
-+#endif
-+
-+
-+
-+
-+
-+/*
-+ * new IPv6-compatible functions
-+ */
-+
-+/* text conversions */
-+err_t ttoul(const char *src, size_t srclen, int format, unsigned long *dst);
-+size_t ultot(unsigned long src, int format, char *buf, size_t buflen);
-+#define ULTOT_BUF (22+1) /* holds 64 bits in octal */
-+err_t ttoaddr(const char *src, size_t srclen, int af, ip_address *dst);
-+err_t tnatoaddr(const char *src, size_t srclen, int af, ip_address *dst);
-+size_t addrtot(const ip_address *src, int format, char *buf, size_t buflen);
-+/* RFC 1886 old IPv6 reverse-lookup format is the bulkiest */
-+#define ADDRTOT_BUF (32*2 + 3 + 1 + 3 + 1 + 1)
-+err_t ttosubnet(const char *src, size_t srclen, int af, ip_subnet *dst);
-+size_t subnettot(const ip_subnet *src, int format, char *buf, size_t buflen);
-+#define SUBNETTOT_BUF (ADDRTOT_BUF + 1 + 3)
-+size_t subnetporttot(const ip_subnet *src, int format, char *buf, size_t buflen);
-+#define SUBNETPROTOTOT_BUF (SUBNETTOTO_BUF + ULTOT_BUF)
-+err_t ttosa(const char *src, size_t srclen, ip_said *dst);
-+size_t satot(const ip_said *src, int format, char *bufptr, size_t buflen);
-+#define SATOT_BUF (5 + ULTOA_BUF + 1 + ADDRTOT_BUF)
-+err_t ttodata(const char *src, size_t srclen, int base, char *buf,
-+ size_t buflen, size_t *needed);
-+err_t ttodatav(const char *src, size_t srclen, int base,
-+ char *buf, size_t buflen, size_t *needed,
-+ char *errp, size_t errlen, unsigned int flags);
-+#define TTODATAV_BUF 40 /* ttodatav's largest non-literal message */
-+#define TTODATAV_IGNORESPACE (1<<1) /* ignore spaces in base64 encodings*/
-+#define TTODATAV_SPACECOUNTS 0 /* do not ignore spaces in base64 */
-+
-+size_t datatot(const char *src, size_t srclen, int format, char *buf,
-+ size_t buflen);
-+size_t keyblobtoid(const unsigned char *src, size_t srclen, char *dst,
-+ size_t dstlen);
-+size_t splitkeytoid(const unsigned char *e, size_t elen, const unsigned char *m,
-+ size_t mlen, char *dst, size_t dstlen);
-+#define KEYID_BUF 10 /* up to 9 text digits plus NUL */
-+err_t ttoprotoport(char *src, size_t src_len, u_int8_t *proto, u_int16_t *port,
-+ int *has_port_wildcard);
-+
-+/* initializations */
-+void initsaid(const ip_address *addr, ipsec_spi_t spi, int proto, ip_said *dst);
-+err_t loopbackaddr(int af, ip_address *dst);
-+err_t unspecaddr(int af, ip_address *dst);
-+err_t anyaddr(int af, ip_address *dst);
-+err_t initaddr(const unsigned char *src, size_t srclen, int af, ip_address *dst);
-+err_t initsubnet(const ip_address *addr, int maskbits, int clash, ip_subnet *dst);
-+err_t addrtosubnet(const ip_address *addr, ip_subnet *dst);
-+
-+/* misc. conversions and related */
-+err_t rangetosubnet(const ip_address *from, const ip_address *to, ip_subnet *dst);
-+int addrtypeof(const ip_address *src);
-+int subnettypeof(const ip_subnet *src);
-+size_t addrlenof(const ip_address *src);
-+size_t addrbytesptr(const ip_address *src, const unsigned char **dst);
-+size_t addrbytesof(const ip_address *src, unsigned char *dst, size_t dstlen);
-+int masktocount(const ip_address *src);
-+void networkof(const ip_subnet *src, ip_address *dst);
-+void maskof(const ip_subnet *src, ip_address *dst);
-+
-+/* tests */
-+int sameaddr(const ip_address *a, const ip_address *b);
-+int addrcmp(const ip_address *a, const ip_address *b);
-+int samesubnet(const ip_subnet *a, const ip_subnet *b);
-+int addrinsubnet(const ip_address *a, const ip_subnet *s);
-+int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);
-+int subnetishost(const ip_subnet *s);
-+int samesaid(const ip_said *a, const ip_said *b);
-+int sameaddrtype(const ip_address *a, const ip_address *b);
-+int samesubnettype(const ip_subnet *a, const ip_subnet *b);
-+int isanyaddr(const ip_address *src);
-+int isunspecaddr(const ip_address *src);
-+int isloopbackaddr(const ip_address *src);
-+
-+/* low-level grot */
-+int portof(const ip_address *src);
-+void setportof(int port, ip_address *dst);
-+struct sockaddr *sockaddrof(ip_address *src);
-+size_t sockaddrlenof(const ip_address *src);
-+
-+/* PRNG */
-+void prng_init(struct prng *prng, const unsigned char *key, size_t keylen);
-+void prng_bytes(struct prng *prng, unsigned char *dst, size_t dstlen);
-+unsigned long prng_count(struct prng *prng);
-+void prng_final(struct prng *prng);
-+
-+/* odds and ends */
-+const char *ipsec_version_code(void);
-+const char *ipsec_version_string(void);
-+const char **ipsec_copyright_notice(void);
-+
-+const char *dns_string_rr(int rr, char *buf, int bufsize);
-+const char *dns_string_datetime(time_t seconds,
-+ char *buf,
-+ int bufsize);
-+
-+
-+/*
-+ * old functions, to be deleted eventually
-+ */
-+
-+/* unsigned long */
-+const char * /* NULL for success, else string literal */
-+atoul(
-+ const char *src,
-+ size_t srclen, /* 0 means strlen(src) */
-+ int base, /* 0 means figure it out */
-+ unsigned long *resultp
-+);
-+size_t /* space needed for full conversion */
-+ultoa(
-+ unsigned long n,
-+ int base,
-+ char *dst,
-+ size_t dstlen
-+);
-+#define ULTOA_BUF 21 /* just large enough for largest result, */
-+ /* assuming 64-bit unsigned long! */
-+
-+/* Internet addresses */
-+const char * /* NULL for success, else string literal */
-+atoaddr(
-+ const char *src,
-+ size_t srclen, /* 0 means strlen(src) */
-+ struct in_addr *addr
-+);
-+size_t /* space needed for full conversion */
-+addrtoa(
-+ struct in_addr addr,
-+ int format, /* character; 0 means default */
-+ char *dst,
-+ size_t dstlen
-+);
-+#define ADDRTOA_BUF 16 /* just large enough for largest result */
-+
-+/* subnets */
-+const char * /* NULL for success, else string literal */
-+atosubnet(
-+ const char *src,
-+ size_t srclen, /* 0 means strlen(src) */
-+ struct in_addr *addr,
-+ struct in_addr *mask
-+);
-+size_t /* space needed for full conversion */
-+subnettoa(
-+ struct in_addr addr,
-+ struct in_addr mask,
-+ int format, /* character; 0 means default */
-+ char *dst,
-+ size_t dstlen
-+);
-+#define SUBNETTOA_BUF 32 /* large enough for worst case result */
-+
-+/* ranges */
-+const char * /* NULL for success, else string literal */
-+atoasr(
-+ const char *src,
-+ size_t srclen, /* 0 means strlen(src) */
-+ char *type, /* 'a', 's', 'r' */
-+ struct in_addr *addrs /* two-element array */
-+);
-+size_t /* space needed for full conversion */
-+rangetoa(
-+ struct in_addr *addrs, /* two-element array */
-+ int format, /* character; 0 means default */
-+ char *dst,
-+ size_t dstlen
-+);
-+#define RANGETOA_BUF 34 /* large enough for worst case result */
-+
-+/* data types for SA conversion functions */
-+
-+/* generic data, e.g. keys */
-+const char * /* NULL for success, else string literal */
-+atobytes(
-+ const char *src,
-+ size_t srclen, /* 0 means strlen(src) */
-+ char *dst,
-+ size_t dstlen,
-+ size_t *lenp /* NULL means don't bother telling me */
-+);
-+size_t /* 0 failure, else true size */
-+bytestoa(
-+ const char *src,
-+ size_t srclen,
-+ int format, /* character; 0 means default */
-+ char *dst,
-+ size_t dstlen
-+);
-+
-+/* old versions of generic-data functions; deprecated */
-+size_t /* 0 failure, else true size */
-+atodata(
-+ const char *src,
-+ size_t srclen, /* 0 means strlen(src) */
-+ char *dst,
-+ size_t dstlen
-+);
-+size_t /* 0 failure, else true size */
-+datatoa(
-+ const char *src,
-+ size_t srclen,
-+ int format, /* character; 0 means default */
-+ char *dst,
-+ size_t dstlen
-+);
-+
-+/* part extraction and special addresses */
-+struct in_addr
-+subnetof(
-+ struct in_addr addr,
-+ struct in_addr mask
-+);
-+struct in_addr
-+hostof(
-+ struct in_addr addr,
-+ struct in_addr mask
-+);
-+struct in_addr
-+broadcastof(
-+ struct in_addr addr,
-+ struct in_addr mask
-+);
-+
-+/* mask handling */
-+int
-+goodmask(
-+ struct in_addr mask
-+);
-+int
-+masktobits(
-+ struct in_addr mask
-+);
-+struct in_addr
-+bitstomask(
-+ int n
-+);
-+
-+
-+
-+/*
-+ * general utilities
-+ */
-+
-+#ifndef __KERNEL__
-+/* option pickup from files (userland only because of use of FILE) */
-+const char *optionsfrom(const char *filename, int *argcp, char ***argvp,
-+ int optind, FILE *errorreport);
-+
-+/* sanitize a string */
-+extern size_t sanitize_string(char *buf, size_t size);
-+
-+#endif
-+
-+
-+/*
-+ * ENUM of klips debugging values. Not currently used in klips.
-+ * debug flag is actually 32 -bits, but only one bit is ever used,
-+ * so we can actually pack it all into a single 32-bit word.
-+ */
-+enum klips_debug_flags {
-+ KDF_VERBOSE = 0,
-+ KDF_XMIT = 1,
-+ KDF_NETLINK = 2, /* obsolete */
-+ KDF_XFORM = 3,
-+ KDF_EROUTE = 4,
-+ KDF_SPI = 5,
-+ KDF_RADIJ = 6,
-+ KDF_ESP = 7,
-+ KDF_AH = 8, /* obsolete */
-+ KDF_RCV = 9,
-+ KDF_TUNNEL = 10,
-+ KDF_PFKEY = 11,
-+ KDF_COMP = 12
-+};
-+
-+
-+/*
-+ * Debugging levels for pfkey_lib_debug
-+ */
-+#define PF_KEY_DEBUG_PARSE_NONE 0
-+#define PF_KEY_DEBUG_PARSE_PROBLEM 1
-+#define PF_KEY_DEBUG_PARSE_STRUCT 2
-+#define PF_KEY_DEBUG_PARSE_FLOW 4
-+#define PF_KEY_DEBUG_BUILD 8
-+#define PF_KEY_DEBUG_PARSE_MAX 15
-+
-+extern unsigned int pfkey_lib_debug; /* bits selecting what to report */
-+
-+/*
-+ * pluto and lwdnsq need to know the maximum size of the commands to,
-+ * and replies from lwdnsq.
-+ */
-+
-+#define LWDNSQ_CMDBUF_LEN 1024
-+#define LWDNSQ_RESULT_LEN_MAX 4096
-+
-+
-+/* syntax for passthrough SA */
-+#ifndef PASSTHROUGHNAME
-+#define PASSTHROUGHNAME "%passthrough"
-+#define PASSTHROUGH4NAME "%passthrough4"
-+#define PASSTHROUGH6NAME "%passthrough6"
-+#define PASSTHROUGHIS "tun0@0.0.0.0"
-+#define PASSTHROUGH4IS "tun0@0.0.0.0"
-+#define PASSTHROUGH6IS "tun0@::"
-+#define PASSTHROUGHTYPE "tun"
-+#define PASSTHROUGHSPI 0
-+#define PASSTHROUGHDST 0
-+#endif
-+
-+
-+
-+#endif /* _OPENSWAN_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipcomp.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,61 @@
-+/*
-+ * IPCOMP zlib interface code.
-+ * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
-+ * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+
-+ RCSID $Id$
-+
-+ */
-+
-+/* SSS */
-+
-+#ifndef _IPCOMP_H
-+#define _IPCOMP_H
-+
-+/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
-+#ifndef IPCOMP_PREFIX
-+#define IPCOMP_PREFIX
-+#endif /* IPCOMP_PREFIX */
-+
-+#ifndef IPPROTO_COMP
-+#define IPPROTO_COMP 108
-+#endif /* IPPROTO_COMP */
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int sysctl_ipsec_debug_ipcomp;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+struct ipcomphdr { /* IPCOMP header */
-+ __u8 ipcomp_nh; /* Next header (protocol) */
-+ __u8 ipcomp_flags; /* Reserved, must be 0 */
-+ __u16 ipcomp_cpi; /* Compression Parameter Index */
-+};
-+
-+extern struct inet_protocol comp_protocol;
-+extern int sysctl_ipsec_debug_ipcomp;
-+
-+#define IPCOMP_UNCOMPRESSABLE 0x000000001
-+#define IPCOMP_COMPRESSIONERROR 0x000000002
-+#define IPCOMP_PARMERROR 0x000000004
-+#define IPCOMP_DECOMPRESSIONERROR 0x000000008
-+
-+#define IPCOMP_ADAPT_INITIAL_TRIES 8
-+#define IPCOMP_ADAPT_INITIAL_SKIP 4
-+#define IPCOMP_ADAPT_SUBSEQ_TRIES 2
-+#define IPCOMP_ADAPT_SUBSEQ_SKIP 8
-+
-+/* Function prototypes */
-+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
-+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
-+
-+#endif /* _IPCOMP_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_ah.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,190 @@
-+/*
-+ * Authentication Header declarations
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#include "ipsec_md5h.h"
-+#include "ipsec_sha1.h"
-+
-+#ifndef IPPROTO_AH
-+#define IPPROTO_AH 51
-+#endif /* IPPROTO_AH */
-+
-+#include "ipsec_auth.h"
-+
-+#ifdef __KERNEL__
-+
-+extern struct inet_protocol ah_protocol;
-+
-+struct options;
-+
-+struct ahhdr /* Generic AH header */
-+{
-+ __u8 ah_nh; /* Next header (protocol) */
-+ __u8 ah_hl; /* AH length, in 32-bit words */
-+ __u16 ah_rv; /* reserved, must be 0 */
-+ __u32 ah_spi; /* Security Parameters Index */
-+ __u32 ah_rpl; /* Replay prevention */
-+ __u8 ah_data[AHHMAC_HASHLEN];/* Authentication hash */
-+};
-+#define AH_BASIC_LEN 8 /* basic AH header is 8 bytes, nh,hl,rv,spi
-+ * and the ah_hl, says how many bytes after that
-+ * to cover. */
-+
-+extern struct xform_functions ah_xform_funcs[];
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int debug_ah;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#endif /* __KERNEL__ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.23 2004/04/05 19:55:04 mcr
-+ * Moved from linux/include/freeswan/ipsec_ah.h,v
-+ *
-+ * Revision 1.22 2004/04/05 19:41:05 mcr
-+ * merged alg-branch code.
-+ *
-+ * Revision 1.21 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.22 2003/12/11 20:14:58 mcr
-+ * refactored the xmit code, to move all encapsulation
-+ * code into protocol functions. Note that all functions
-+ * are essentially done by a single function, which is probably
-+ * wrong.
-+ * the rcv_functions structures are renamed xform_functions.
-+ *
-+ * Revision 1.21 2003/12/06 21:21:19 mcr
-+ * split up receive path into per-transform files, for
-+ * easier later removal.
-+ *
-+ * Revision 1.20.8.1 2003/12/22 15:25:52 jjo
-+ * Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.20 2003/02/06 02:21:34 rgb
-+ *
-+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
-+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
-+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
-+ *
-+ * Revision 1.19 2002/09/16 21:19:13 mcr
-+ * fixes for west-ah-icmp-01 - length of AH header must be
-+ * calculated properly, and next_header field properly copied.
-+ *
-+ * Revision 1.18 2002/05/14 02:37:02 rgb
-+ * Change reference from _TDB to _IPSA.
-+ *
-+ * Revision 1.17 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_ah.h,v
-+ *
-+ * Revision 1.16 2002/02/20 01:27:06 rgb
-+ * Ditched a pile of structs only used by the old Netlink interface.
-+ *
-+ * Revision 1.15 2001/12/11 02:35:57 rgb
-+ * Change "struct net_device" to "struct device" for 2.2 compatibility.
-+ *
-+ * Revision 1.14 2001/11/26 09:23:47 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.13.2.1 2001/09/25 02:18:24 mcr
-+ * replace "struct device" with "struct netdevice"
-+ *
-+ * Revision 1.13 2001/06/14 19:35:08 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.12 2000/09/12 03:21:20 rgb
-+ * Cleared out unused htonq.
-+ *
-+ * Revision 1.11 2000/09/08 19:12:55 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.10 2000/01/21 06:13:10 rgb
-+ * Tidied up spacing.
-+ * Added macros for HMAC padding magic numbers.(kravietz)
-+ *
-+ * Revision 1.9 1999/12/07 18:16:23 rgb
-+ * Fixed comments at end of #endif lines.
-+ *
-+ * Revision 1.8 1999/04/11 00:28:56 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.7 1999/04/06 04:54:25 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.6 1999/01/26 02:06:01 rgb
-+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
-+ *
-+ * Revision 1.5 1999/01/22 06:17:49 rgb
-+ * Updated macro comments.
-+ * Added context types to support algorithm switch code.
-+ * 64-bit clean-up -- converting 'u long long' to __u64.
-+ *
-+ * Revision 1.4 1998/07/14 15:54:56 rgb
-+ * Add #ifdef __KERNEL__ to protect kernel-only structures.
-+ *
-+ * Revision 1.3 1998/06/30 18:05:16 rgb
-+ * Comment out references to htonq.
-+ *
-+ * Revision 1.2 1998/06/25 19:33:46 rgb
-+ * Add prototype for protocol receive function.
-+ * Rearrange for more logical layout.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:43 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.4 1998/05/18 22:28:43 rgb
-+ * Disable key printing facilities from /proc/net/ipsec_*.
-+ *
-+ * Revision 1.3 1998/04/21 21:29:07 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.2 1998/04/12 22:03:17 rgb
-+ * Updated ESP-3DES-HMAC-MD5-96,
-+ * ESP-DES-HMAC-MD5-96,
-+ * AH-HMAC-MD5-96,
-+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
-+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
-+ *
-+ * Fixed eroute references in /proc/net/ipsec*.
-+ *
-+ * Started to patch module unloading memory leaks in ipsec_netlink and
-+ * radij tree unloading.
-+ *
-+ * Revision 1.1 1998/04/09 03:05:55 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * Added definitions for new AH transforms.
-+ *
-+ * Revision 0.3 1996/11/20 14:35:48 ji
-+ * Minor Cleanup.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_alg.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,260 @@
-+/*
-+ * Modular extensions service and registration functions interface
-+ *
-+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
-+ *
-+ * ipsec_alg.h,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
-+ *
-+ */
-+/*
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+ * for more details.
-+ *
-+ */
-+#ifndef IPSEC_ALG_H
-+#define IPSEC_ALG_H
-+
-+/*
-+ * gcc >= 3.2 has removed __FUNCTION__, replaced by C99 __func__
-+ * *BUT* its a compiler variable.
-+ */
-+#if (__GNUC__ >= 3)
-+#ifndef __FUNCTION__
-+#define __FUNCTION__ __func__
-+#endif
-+#endif
-+
-+/* Version 0.8.1-0 */
-+#define IPSEC_ALG_VERSION 0x00080100
-+
-+#include <linux/types.h>
-+#include <linux/list.h>
-+#include <asm/atomic.h>
-+/*
-+ * The following structs are used via pointers in ipsec_alg object to
-+ * avoid ipsec_alg.h coupling with freeswan headers, thus simplifying
-+ * module development
-+ */
-+struct ipsec_sa;
-+struct esp;
-+
-+/**************************************
-+ *
-+ * Main registration object
-+ *
-+ *************************************/
-+#define IPSEC_ALG_VERSION_QUAD(v) \
-+ (v>>24),((v>>16)&0xff),((v>>8)&0xff),(v&0xff)
-+/*
-+ * Main ipsec_alg objects: "OOPrograming wannabe"
-+ * Hierachy (carefully handled with _minimal_ cast'ing):
-+ *
-+ * ipsec_alg+
-+ * +->ipsec_alg_enc (ixt_alg_type=SADB_EXT_SUPPORTED_ENCRYPT)
-+ * +->ipsec_alg_auth (ixt_alg_type=SADB_EXT_SUPPORTED_AUTH)
-+ */
-+
-+/***************************************************************
-+ *
-+ * INTERFACE object: struct ipsec_alg
-+ *
-+ ***************************************************************/
-+
-+/*
-+ * common part for every struct ipsec_alg_*
-+ * (sortof poor's man OOP)
-+ */
-+#define IPSEC_ALG_STRUCT_COMMON \
-+ unsigned ixt_version; /* only allow this version (or 'near')*/ \
-+ struct list_head ixt_list; /* dlinked list */ \
-+ struct module *ixt_module; /* THIS_MODULE */ \
-+ unsigned ixt_state; /* state flags */ \
-+ atomic_t ixt_refcnt; /* ref. count when pointed from ipsec_sa */ \
-+ char ixt_name[16]; /* descriptive short name, eg. "3des" */ \
-+ void *ixt_data; /* private for algo implementation */ \
-+ uint8_t ixt_blocksize; /* blocksize in bytes */ \
-+ \
-+ /* THIS IS A COPY of struct supported (lib/pfkey.h) \
-+ * please keep in sync until we migrate 'supported' stuff \
-+ * to ipsec_alg \
-+ */ \
-+ uint16_t ixt_alg_type; /* correspond to IPSEC_ALG_{ENCRYPT,AUTH} */ \
-+ uint8_t ixt_alg_id; /* enc. alg. number, eg. ESP_3DES */ \
-+ uint8_t ixt_ivlen; /* ivlen in bits, expected to be multiple of 8! */ \
-+ uint16_t ixt_keyminbits;/* min. keybits (of entropy) */ \
-+ uint16_t ixt_keymaxbits;/* max. keybits (of entropy) */
-+
-+#define ixt_support ixt_alg_type
-+
-+#define IPSEC_ALG_ST_SUPP 0x01
-+#define IPSEC_ALG_ST_REGISTERED 0x02
-+#define IPSEC_ALG_ST_EXCL 0x04
-+struct ipsec_alg {
-+ IPSEC_ALG_STRUCT_COMMON
-+};
-+/*
-+ * Note the const in cbc_encrypt IV arg:
-+ * some ciphers like to toast passed IV (eg. 3DES): make a local IV copy
-+ */
-+struct ipsec_alg_enc {
-+ IPSEC_ALG_STRUCT_COMMON
-+ unsigned ixt_e_keylen; /* raw key length in bytes */
-+ unsigned ixt_e_ctx_size; /* sa_p->key_e_size */
-+ int (*ixt_e_set_key)(struct ipsec_alg_enc *alg, __u8 *key_e, const __u8 *key, size_t keysize);
-+ __u8 *(*ixt_e_new_key)(struct ipsec_alg_enc *alg, const __u8 *key, size_t keysize);
-+ void (*ixt_e_destroy_key)(struct ipsec_alg_enc *alg, __u8 *key_e);
-+ int (*ixt_e_cbc_encrypt)(struct ipsec_alg_enc *alg, __u8 *key_e, __u8 *in, int ilen, const __u8 *iv, int encrypt);
-+};
-+struct ipsec_alg_auth {
-+ IPSEC_ALG_STRUCT_COMMON
-+ unsigned ixt_a_keylen; /* raw key length in bytes */
-+ unsigned ixt_a_ctx_size; /* sa_p->key_a_size */
-+ unsigned ixt_a_authlen; /* 'natural' auth. hash len (bytes) */
-+ int (*ixt_a_hmac_set_key)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *key, int keylen);
-+ int (*ixt_a_hmac_hash)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *dat, int len, __u8 *hash, int hashlen);
-+};
-+/*
-+ * These are _copies_ of SADB_EXT_SUPPORTED_{AUTH,ENCRYPT},
-+ * to avoid header coupling for true constants
-+ * about headers ... "cp is your friend" --Linus
-+ */
-+#define IPSEC_ALG_TYPE_AUTH 14
-+#define IPSEC_ALG_TYPE_ENCRYPT 15
-+
-+/***************************************************************
-+ *
-+ * INTERFACE for module loading,testing, and unloading
-+ *
-+ ***************************************************************/
-+/* - registration calls */
-+int register_ipsec_alg(struct ipsec_alg *);
-+int unregister_ipsec_alg(struct ipsec_alg *);
-+/* - optional (simple test) for algos */
-+int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int testparm);
-+/* inline wrappers (usefull for type validation */
-+static inline int register_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
-+ return register_ipsec_alg((struct ipsec_alg*)ixt);
-+}
-+static inline int unregister_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
-+ return unregister_ipsec_alg((struct ipsec_alg*)ixt);
-+}
-+static inline int register_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
-+ return register_ipsec_alg((struct ipsec_alg*)ixt);
-+}
-+static inline int unregister_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
-+ return unregister_ipsec_alg((struct ipsec_alg*)ixt);
-+}
-+
-+/*****************************************************************
-+ *
-+ * INTERFACE for ENC services: key creation, encrypt function
-+ *
-+ *****************************************************************/
-+
-+#define IPSEC_ALG_ENCRYPT 1
-+#define IPSEC_ALG_DECRYPT 0
-+
-+/* encryption key context creation function */
-+int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p);
-+/*
-+ * ipsec_alg_esp_encrypt(): encrypt ilen bytes in idat returns
-+ * 0 or ERR<0
-+ */
-+int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 *idat, int ilen, const __u8 *iv, int action);
-+
-+/***************************************************************
-+ *
-+ * INTERFACE for AUTH services: key creation, hash functions
-+ *
-+ ***************************************************************/
-+int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p);
-+int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) ;
-+#define ipsec_alg_sa_esp_update(c,k,l) ipsec_alg_sa_esp_hash(c,k,l,NULL,0)
-+
-+/* only called from ipsec_init.c */
-+int ipsec_alg_init(void);
-+
-+/* algo module glue for static algos */
-+void ipsec_alg_static_init(void);
-+typedef int (*ipsec_alg_init_func_t) (void);
-+
-+/**********************************************
-+ *
-+ * INTERFACE for ipsec_sa init and wipe
-+ *
-+ **********************************************/
-+
-+/* returns true if ipsec_sa has ipsec_alg obj attached */
-+/*
-+ * Initializes ipsec_sa's ipsec_alg object, using already loaded
-+ * proto, authalg, encalg.; links ipsec_alg objects (enc, auth)
-+ */
-+int ipsec_alg_sa_init(struct ipsec_sa *sa_p);
-+/*
-+ * Destroys ipsec_sa's ipsec_alg object
-+ * unlinking ipsec_alg objects
-+ */
-+int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p);
-+
-+#define IPSEC_ALG_MODULE_INIT_MOD( func_name ) \
-+ static int func_name(void); \
-+ module_init(func_name); \
-+ static int __init func_name(void)
-+#define IPSEC_ALG_MODULE_EXIT_MOD( func_name ) \
-+ static void func_name(void); \
-+ module_exit(func_name); \
-+ static void __exit func_name(void)
-+
-+#define IPSEC_ALG_MODULE_INIT_STATIC( func_name ) \
-+ extern int func_name(void); \
-+ int func_name(void)
-+#define IPSEC_ALG_MODULE_EXIT_STATIC( func_name ) \
-+ extern void func_name(void); \
-+ void func_name(void)
-+
-+/**********************************************
-+ *
-+ * 2.2 backport for some 2.4 useful module stuff
-+ *
-+ **********************************************/
-+#ifdef MODULE
-+#ifndef THIS_MODULE
-+#define THIS_MODULE (&__this_module)
-+#endif
-+#ifndef module_init
-+typedef int (*__init_module_func_t)(void);
-+typedef void (*__cleanup_module_func_t)(void);
-+
-+#define module_init(x) \
-+ int init_module(void) __attribute__((alias(#x))); \
-+ static inline __init_module_func_t __init_module_inline(void) \
-+ { return x; }
-+#define module_exit(x) \
-+ void cleanup_module(void) __attribute__((alias(#x))); \
-+ static inline __cleanup_module_func_t __cleanup_module_inline(void) \
-+ { return x; }
-+#endif
-+#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_MOD( func_name )
-+#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_MOD( func_name )
-+
-+#else /* not MODULE */
-+#ifndef THIS_MODULE
-+#define THIS_MODULE NULL
-+#endif
-+/*
-+ * I only want module_init() magic
-+ * when algo.c file *is THE MODULE*, in all other
-+ * cases, initialization is called explicitely from ipsec_alg_init()
-+ */
-+#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_STATIC(func_name)
-+#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_STATIC(func_name)
-+#endif
-+
-+#endif /* IPSEC_ALG_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_auth.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,100 @@
-+/*
-+ * Authentication Header declarations
-+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#include "ipsec_md5h.h"
-+#include "ipsec_sha1.h"
-+
-+#ifndef IPSEC_AUTH_H
-+#define IPSEC_AUTH_H
-+
-+#define AH_FLENGTH 12 /* size of fixed part */
-+#define AHMD5_KMAX 64 /* MD5 max 512 bits key */
-+#define AHMD5_AMAX 12 /* MD5 96 bits of authenticator */
-+
-+#define AHMD596_KLEN 16 /* MD5 128 bits key */
-+#define AHSHA196_KLEN 20 /* SHA1 160 bits key */
-+
-+#define AHMD596_ALEN 16 /* MD5 128 bits authentication length */
-+#define AHSHA196_ALEN 20 /* SHA1 160 bits authentication length */
-+
-+#define AHMD596_BLKLEN 64 /* MD5 block length */
-+#define AHSHA196_BLKLEN 64 /* SHA1 block length */
-+#define AHSHA2_256_BLKLEN 64 /* SHA2-256 block length */
-+#define AHSHA2_384_BLKLEN 128 /* SHA2-384 block length (?) */
-+#define AHSHA2_512_BLKLEN 128 /* SHA2-512 block length */
-+
-+#define AH_BLKLEN_MAX 128 /* keep up to date! */
-+
-+
-+#define AH_AMAX AHSHA196_ALEN /* keep up to date! */
-+#define AHHMAC_HASHLEN 12 /* authenticator length of 96bits */
-+#define AHHMAC_RPLLEN 4 /* 32 bit replay counter */
-+
-+#define DB_AH_PKTRX 0x0001
-+#define DB_AH_PKTRX2 0x0002
-+#define DB_AH_DMP 0x0004
-+#define DB_AH_IPSA 0x0010
-+#define DB_AH_XF 0x0020
-+#define DB_AH_INAU 0x0040
-+#define DB_AH_REPLAY 0x0100
-+
-+#ifdef __KERNEL__
-+
-+/* General HMAC algorithm is described in RFC 2104 */
-+
-+#define HMAC_IPAD 0x36
-+#define HMAC_OPAD 0x5C
-+
-+struct md5_ctx {
-+ MD5_CTX ictx; /* context after H(K XOR ipad) */
-+ MD5_CTX octx; /* context after H(K XOR opad) */
-+};
-+
-+struct sha1_ctx {
-+ SHA1_CTX ictx; /* context after H(K XOR ipad) */
-+ SHA1_CTX octx; /* context after H(K XOR opad) */
-+};
-+
-+struct auth_alg {
-+ void (*init)(void *ctx);
-+ void (*update)(void *ctx, unsigned char *bytes, __u32 len);
-+ void (*final)(unsigned char *hash, void *ctx);
-+ int hashlen;
-+};
-+
-+struct options;
-+
-+#endif /* __KERNEL__ */
-+#endif /* IPSEC_AUTH_H */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.3 2004/04/06 02:49:08 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.2 2004/04/05 19:55:04 mcr
-+ * Moved from linux/include/freeswan/ipsec_auth.h,v
-+ *
-+ * Revision 1.1 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.1 2003/12/06 21:21:19 mcr
-+ * split up receive path into per-transform files, for
-+ * easier later removal.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_encap.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,149 @@
-+/*
-+ * declarations relevant to encapsulation-like operations
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifndef _IPSEC_ENCAP_H_
-+
-+#define SENT_IP4 16 /* data is two struct in_addr + proto + ports*/
-+ /* (2 * sizeof(struct in_addr)) */
-+ /* sizeof(struct sockaddr_encap)
-+ - offsetof(struct sockaddr_encap, Sen.Sip4.Src) */
-+
-+struct sockaddr_encap
-+{
-+ __u8 sen_len; /* length */
-+ __u8 sen_family; /* AF_ENCAP */
-+ __u16 sen_type; /* see SENT_* */
-+ union
-+ {
-+ struct /* SENT_IP4 */
-+ {
-+ struct in_addr Src;
-+ struct in_addr Dst;
-+ __u8 Proto;
-+ __u16 Sport;
-+ __u16 Dport;
-+ } Sip4;
-+ } Sen;
-+};
-+
-+#define sen_ip_src Sen.Sip4.Src
-+#define sen_ip_dst Sen.Sip4.Dst
-+#define sen_proto Sen.Sip4.Proto
-+#define sen_sport Sen.Sip4.Sport
-+#define sen_dport Sen.Sip4.Dport
-+
-+#ifndef AF_ENCAP
-+#define AF_ENCAP 26
-+#endif /* AF_ENCAP */
-+
-+#define _IPSEC_ENCAP_H_
-+#endif /* _IPSEC_ENCAP_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.19 2004/04/05 19:55:04 mcr
-+ * Moved from linux/include/freeswan/ipsec_encap.h,v
-+ *
-+ * Revision 1.18 2003/10/31 02:27:05 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.17.30.1 2003/09/21 13:59:38 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.17 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_encap.h,v
-+ *
-+ * Revision 1.16 2001/11/26 09:23:47 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.15.2.1 2001/09/25 02:18:54 mcr
-+ * struct eroute moved to ipsec_eroute.h
-+ *
-+ * Revision 1.15 2001/09/14 16:58:36 rgb
-+ * Added support for storing the first and last packets through a HOLD.
-+ *
-+ * Revision 1.14 2001/09/08 21:13:31 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.13 2001/06/14 19:35:08 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.12 2001/05/27 06:12:10 rgb
-+ * Added structures for pid, packet count and last access time to eroute.
-+ * Added packet count to beginning of /proc/net/ipsec_eroute.
-+ *
-+ * Revision 1.11 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.10 2000/03/22 16:15:36 rgb
-+ * Fixed renaming of dev_get (MB).
-+ *
-+ * Revision 1.9 2000/01/21 06:13:26 rgb
-+ * Added a macro for AF_ENCAP
-+ *
-+ * Revision 1.8 1999/12/31 14:56:55 rgb
-+ * MB fix for 2.3 dev-use-count.
-+ *
-+ * Revision 1.7 1999/11/18 04:09:18 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ *
-+ * Revision 1.6 1999/09/24 00:34:13 rgb
-+ * Add Marc Boucher's support for 2.3.xx+.
-+ *
-+ * Revision 1.5 1999/04/11 00:28:57 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.4 1999/04/06 04:54:25 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.3 1998/10/19 14:44:28 rgb
-+ * Added inclusion of freeswan.h.
-+ * sa_id structure implemented and used: now includes protocol.
-+ *
-+ * Revision 1.2 1998/07/14 18:19:33 rgb
-+ * Added #ifdef __KERNEL__ directives to restrict scope of header.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:44 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.2 1998/04/21 21:29:10 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.1 1998/04/09 03:05:58 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * Minor cosmetic changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:35:48 ji
-+ * Minor Cleanup.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_eroute.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,112 @@
-+/*
-+ * @(#) declarations of eroute structures
-+ *
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ * Copyright (C) 2001 Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ * derived from ipsec_encap.h 1.15 on 2001/9/18 by mcr.
-+ *
-+ */
-+
-+#ifndef _IPSEC_EROUTE_H_
-+
-+#include "radij.h"
-+#include "ipsec_encap.h"
-+#include "ipsec_radij.h"
-+
-+/*
-+ * The "type" is really part of the address as far as the routing
-+ * system is concerned. By using only one bit in the type field
-+ * for each type, we sort-of make sure that different types of
-+ * encapsulation addresses won't be matched against the wrong type.
-+ */
-+
-+/*
-+ * An entry in the radix tree
-+ */
-+
-+struct rjtentry
-+{
-+ struct radij_node rd_nodes[2]; /* tree glue, and other values */
-+#define rd_key(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_key))
-+#define rd_mask(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_mask))
-+ short rd_flags;
-+ short rd_count;
-+};
-+
-+struct ident
-+{
-+ __u16 type; /* identity type */
-+ __u64 id; /* identity id */
-+ __u8 len; /* identity len */
-+ caddr_t data; /* identity data */
-+};
-+
-+/*
-+ * An encapsulation route consists of a pointer to a
-+ * radix tree entry and a SAID (a destination_address/SPI/protocol triple).
-+ */
-+
-+struct eroute
-+{
-+ struct rjtentry er_rjt;
-+ ip_said er_said;
-+ uint32_t er_pid;
-+ uint32_t er_count;
-+ uint64_t er_lasttime;
-+ struct sockaddr_encap er_eaddr; /* MCR get rid of _encap, it is silly*/
-+ struct sockaddr_encap er_emask;
-+ struct ident er_ident_s;
-+ struct ident er_ident_d;
-+ struct sk_buff* er_first;
-+ struct sk_buff* er_last;
-+};
-+
-+#define er_dst er_said.dst
-+#define er_spi er_said.spi
-+
-+#define _IPSEC_EROUTE_H_
-+#endif /* _IPSEC_EROUTE_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.5 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_eroute.h,v
-+ *
-+ * Revision 1.4 2003/10/31 02:27:05 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.3.30.2 2003/10/29 01:10:19 mcr
-+ * elimited "struct sa_id"
-+ *
-+ * Revision 1.3.30.1 2003/09/21 13:59:38 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.3 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_eroute.h,v
-+ *
-+ * Revision 1.2 2001/11/26 09:16:13 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:18:54 mcr
-+ * struct eroute moved to ipsec_eroute.h
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_errs.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,53 @@
-+/*
-+ * @(#) definition of ipsec_errs structure
-+ *
-+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ * and Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ */
-+
-+/*
-+ * This file describes the errors/statistics that FreeSWAN collects.
-+ *
-+ */
-+
-+struct ipsec_errs {
-+ __u32 ips_alg_errs; /* number of algorithm errors */
-+ __u32 ips_auth_errs; /* # of authentication errors */
-+ __u32 ips_encsize_errs; /* # of encryption size errors*/
-+ __u32 ips_encpad_errs; /* # of encryption pad errors*/
-+ __u32 ips_replaywin_errs; /* # of pkt sequence errors */
-+};
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.4 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_errs.h,v
-+ *
-+ * Revision 1.3 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_errs.h,v
-+ *
-+ * Revision 1.2 2001/11/26 09:16:13 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:25:57 mcr
-+ * lifetime structure created and common functions created.
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_esp.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,147 @@
-+/*
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#include "openswan/ipsec_md5h.h"
-+#include "openswan/ipsec_sha1.h"
-+
-+#include "crypto/des.h"
-+
-+#ifndef IPPROTO_ESP
-+#define IPPROTO_ESP 50
-+#endif /* IPPROTO_ESP */
-+
-+#define ESP_HEADER_LEN 8 /* 64 bits header (spi+rpl)*/
-+
-+#define EMT_ESPDESCBC_ULEN 20 /* coming from user mode */
-+#define EMT_ESPDES_KMAX 64 /* 512 bit secret key enough? */
-+#define EMT_ESPDES_KEY_SZ 8 /* 56 bit secret key with parity = 64 bits */
-+#define EMT_ESP3DES_KEY_SZ 24 /* 168 bit secret key with parity = 192 bits */
-+#define EMT_ESPDES_IV_SZ 8 /* IV size */
-+#define ESP_DESCBC_BLKLEN 8 /* DES-CBC block size */
-+
-+#define ESP_IV_MAXSZ 16 /* This is _critical_ */
-+#define ESP_IV_MAXSZ_INT (ESP_IV_MAXSZ/sizeof(int))
-+
-+#define DB_ES_PKTRX 0x0001
-+#define DB_ES_PKTRX2 0x0002
-+#define DB_ES_IPSA 0x0010
-+#define DB_ES_XF 0x0020
-+#define DB_ES_IPAD 0x0040
-+#define DB_ES_INAU 0x0080
-+#define DB_ES_OINFO 0x0100
-+#define DB_ES_OINFO2 0x0200
-+#define DB_ES_OH 0x0400
-+#define DB_ES_REPLAY 0x0800
-+
-+#ifdef __KERNEL__
-+struct des_eks {
-+ des_key_schedule ks;
-+};
-+
-+extern struct inet_protocol esp_protocol;
-+
-+struct options;
-+
-+struct esphdr
-+{
-+ __u32 esp_spi; /* Security Parameters Index */
-+ __u32 esp_rpl; /* Replay counter */
-+ __u8 esp_iv[8]; /* iv */
-+};
-+
-+extern struct xform_functions esp_xform_funcs[];
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int debug_esp;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#endif /* __KERNEL__ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.25 2004/04/06 02:49:08 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.24 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_esp.h,v
-+ *
-+ * Revision 1.23 2004/04/05 19:41:05 mcr
-+ * merged alg-branch code.
-+ *
-+ * Revision 1.22 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.23 2003/12/11 20:14:58 mcr
-+ * refactored the xmit code, to move all encapsulation
-+ * code into protocol functions. Note that all functions
-+ * are essentially done by a single function, which is probably
-+ * wrong.
-+ * the rcv_functions structures are renamed xform_functions.
-+ *
-+ * Revision 1.22 2003/12/06 21:21:19 mcr
-+ * split up receive path into per-transform files, for
-+ * easier later removal.
-+ *
-+ * Revision 1.21.8.1 2003/12/22 15:25:52 jjo
-+ * Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.21 2003/02/06 02:21:34 rgb
-+ *
-+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
-+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
-+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
-+ *
-+ * Revision 1.20 2002/05/14 02:37:02 rgb
-+ * Change reference from _TDB to _IPSA.
-+ *
-+ * Revision 1.19 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.18 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_esp.h,v
-+ *
-+ * Revision 1.17 2002/02/20 01:27:07 rgb
-+ * Ditched a pile of structs only used by the old Netlink interface.
-+ *
-+ * Revision 1.16 2001/12/11 02:35:57 rgb
-+ * Change "struct net_device" to "struct device" for 2.2 compatibility.
-+ *
-+ * Revision 1.15 2001/11/26 09:23:48 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.14.2.3 2001/10/23 04:16:42 mcr
-+ * get definition of des_key_schedule from des.h
-+ *
-+ * Revision 1.14.2.2 2001/10/22 20:33:13 mcr
-+ * use "des_key_schedule" structure instead of cooking our own.
-+ *
-+ * Revision 1.14.2.1 2001/09/25 02:18:25 mcr
-+ * replace "struct device" with "struct netdevice"
-+ *
-+ * Revision 1.14 2001/06/14 19:35:08 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.13 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.12 2000/08/01 14:51:50 rgb
-+ * Removed _all_ remaining traces of DES.
-+ *
-+ * Revision 1.11 2000/01/10 16:36:20 rgb
-+ * Ditch last of EME option flags, including initiator.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_ipcomp.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,91 @@
-+/*
-+ * IP compression header declations
-+ *
-+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifndef IPSEC_IPCOMP_H
-+#define IPSEC_IPCOMP_H
-+
-+#include "openswan/ipsec_auth.h"
-+
-+/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
-+#ifndef IPCOMP_PREFIX
-+#define IPCOMP_PREFIX
-+#endif /* IPCOMP_PREFIX */
-+
-+#ifndef IPPROTO_COMP
-+#define IPPROTO_COMP 108
-+#endif /* IPPROTO_COMP */
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int sysctl_ipsec_debug_ipcomp;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+struct ipcomphdr { /* IPCOMP header */
-+ __u8 ipcomp_nh; /* Next header (protocol) */
-+ __u8 ipcomp_flags; /* Reserved, must be 0 */
-+ __u16 ipcomp_cpi; /* Compression Parameter Index */
-+};
-+
-+extern struct inet_protocol comp_protocol;
-+extern int sysctl_ipsec_debug_ipcomp;
-+
-+#define IPCOMP_UNCOMPRESSABLE 0x000000001
-+#define IPCOMP_COMPRESSIONERROR 0x000000002
-+#define IPCOMP_PARMERROR 0x000000004
-+#define IPCOMP_DECOMPRESSIONERROR 0x000000008
-+
-+#define IPCOMP_ADAPT_INITIAL_TRIES 8
-+#define IPCOMP_ADAPT_INITIAL_SKIP 4
-+#define IPCOMP_ADAPT_SUBSEQ_TRIES 2
-+#define IPCOMP_ADAPT_SUBSEQ_SKIP 8
-+
-+/* Function prototypes */
-+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
-+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
-+
-+extern struct xform_functions ipcomp_xform_funcs[];
-+
-+#endif /* IPSEC_IPCOMP_H */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.3 2004/04/06 02:49:08 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.2 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_ipcomp.h,v
-+ *
-+ * Revision 1.1 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.2 2003/12/11 20:14:58 mcr
-+ * refactored the xmit code, to move all encapsulation
-+ * code into protocol functions. Note that all functions
-+ * are essentially done by a single function, which is probably
-+ * wrong.
-+ * the rcv_functions structures are renamed xform_functions.
-+ *
-+ * Revision 1.1 2003/12/06 21:21:19 mcr
-+ * split up receive path into per-transform files, for
-+ * easier later removal.
-+ *
-+ *
-+ *
-+ */
-+
-+
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_ipe4.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,68 @@
-+/*
-+ * IP-in-IP Header declarations
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+/* The packet header is an IP header! */
-+
-+struct ipe4_xdata /* transform table data */
-+{
-+ struct in_addr i4_src;
-+ struct in_addr i4_dst;
-+};
-+
-+#define EMT_IPE4_ULEN 8 /* coming from user mode */
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.6 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_ipe4.h,v
-+ *
-+ * Revision 1.5 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_ipe4.h,v
-+ *
-+ * Revision 1.4 2001/06/14 19:35:08 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.3 1999/04/11 00:28:57 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.2 1999/04/06 04:54:25 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:47 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.1 1998/04/09 03:06:07 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * No changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:48:53 ji
-+ * Release update only.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_ipip.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,45 @@
-+/*
-+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifndef _IPSEC_IPIP_H_
-+
-+#ifndef IPPROTO_IPIP
-+#define IPPROTO_IPIP 4
-+#endif /* IPPROTO_ESP */
-+
-+extern struct xform_functions ipip_xform_funcs[];
-+
-+#define _IPSEC_IPIP_H_
-+
-+#endif /* _IPSEC_IPIP_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.2 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_ipip.h,v
-+ *
-+ * Revision 1.1 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.1 2003/12/11 20:14:58 mcr
-+ * refactored the xmit code, to move all encapsulation
-+ * code into protocol functions. Note that all functions
-+ * are essentially done by a single function, which is probably
-+ * wrong.
-+ * the rcv_functions structures are renamed xform_functions.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_kversion.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,239 @@
-+#ifndef _FREESWAN_KVERSIONS_H
-+/*
-+ * header file for FreeS/WAN library functions
-+ * Copyright (C) 1998, 1999, 2000 Henry Spencer.
-+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#define _FREESWAN_KVERSIONS_H /* seen it, no need to see it again */
-+
-+/*
-+ * this file contains a series of atomic defines that depend upon
-+ * kernel version numbers. The kernel versions are arranged
-+ * in version-order number (which is often not chronological)
-+ * and each clause enables or disables a feature.
-+ */
-+
-+/*
-+ * First, assorted kernel-version-dependent trickery.
-+ */
-+#include <linux/version.h>
-+#ifndef KERNEL_VERSION
-+#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
-+#define HEADER_CACHE_BIND_21
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
-+#define SPINLOCK
-+#define PROC_FS_21
-+#define NETLINK_SOCK
-+#define NET_21
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,19)
-+#define net_device_stats enet_statistics
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-+#define SPINLOCK_23
-+#define NETDEV_23
-+# ifndef CONFIG_IP_ALIAS
-+# define CONFIG_IP_ALIAS
-+# endif
-+#include <linux/socket.h>
-+#include <linux/skbuff.h>
-+#include <linux/netlink.h>
-+# ifdef NETLINK_XFRM
-+# define NETDEV_25
-+# endif
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,25)
-+#define PROC_FS_2325
-+#undef PROC_FS_21
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30)
-+#define PROC_NO_DUMMY
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,35)
-+#define SKB_COPY_EXPAND
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,37)
-+#define IP_SELECT_IDENT
-+#endif
-+
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,50)) && defined(CONFIG_NETFILTER)
-+#define SKB_RESET_NFCT
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2)
-+#define IP_SELECT_IDENT_NEW
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
-+#define IPH_is_SKB_PULLED
-+#define SKB_COW_NEW
-+#define PROTO_HANDLER_SINGLE_PARM
-+#define IP_FRAGMENT_LINEARIZE 1
-+#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
-+# ifdef REDHAT_BOGOSITY
-+# define IP_SELECT_IDENT_NEW
-+# define IPH_is_SKB_PULLED
-+# define SKB_COW_NEW
-+# define PROTO_HANDLER_SINGLE_PARM
-+# endif /* REDHAT_BOGOSITY */
-+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
-+#define MALLOC_SLAB
-+#define LINUX_KERNEL_HAS_SNPRINTF
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+#define HAVE_NETDEV_PRINTK 1
-+#endif
-+
-+#ifdef NET_21
-+# include <linux/in6.h>
-+#else
-+ /* old kernel in.h has some IPv6 stuff, but not quite enough */
-+# define s6_addr16 s6_addr
-+# define AF_INET6 10
-+# define uint8_t __u8
-+# define uint16_t __u16
-+# define uint32_t __u32
-+# define uint64_t __u64
-+#endif
-+
-+#ifdef NET_21
-+# define ipsec_kfree_skb(a) kfree_skb(a)
-+#else /* NET_21 */
-+# define ipsec_kfree_skb(a) kfree_skb(a, FREE_WRITE)
-+#endif /* NET_21 */
-+
-+#ifdef NETDEV_23
-+# define device net_device
-+# define ipsec_dev_get dev_get_by_name
-+# define __ipsec_dev_get __dev_get_by_name
-+# define ipsec_dev_put(x) dev_put(x)
-+# define __ipsec_dev_put(x) __dev_put(x)
-+# define ipsec_dev_hold(x) dev_hold(x)
-+#else /* NETDEV_23 */
-+# define ipsec_dev_get dev_get
-+# define __ipsec_dev_put(x)
-+# define ipsec_dev_put(x)
-+# define ipsec_dev_hold(x)
-+#endif /* NETDEV_23 */
-+
-+#ifndef SPINLOCK
-+# include <linux/bios32.h>
-+ /* simulate spin locks and read/write locks */
-+ typedef struct {
-+ volatile char lock;
-+ } spinlock_t;
-+
-+ typedef struct {
-+ volatile unsigned int lock;
-+ } rwlock_t;
-+
-+# define spin_lock_init(x) { (x)->lock = 0;}
-+# define rw_lock_init(x) { (x)->lock = 0; }
-+
-+# define spin_lock(x) { while ((x)->lock) barrier(); (x)->lock=1;}
-+# define spin_lock_irq(x) { cli(); spin_lock(x);}
-+# define spin_lock_irqsave(x,flags) { save_flags(flags); spin_lock_irq(x);}
-+
-+# define spin_unlock(x) { (x)->lock=0;}
-+# define spin_unlock_irq(x) { spin_unlock(x); sti();}
-+# define spin_unlock_irqrestore(x,flags) { spin_unlock(x); restore_flags(flags);}
-+
-+# define read_lock(x) spin_lock(x)
-+# define read_lock_irq(x) spin_lock_irq(x)
-+# define read_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
-+
-+# define read_unlock(x) spin_unlock(x)
-+# define read_unlock_irq(x) spin_unlock_irq(x)
-+# define read_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
-+
-+# define write_lock(x) spin_lock(x)
-+# define write_lock_irq(x) spin_lock_irq(x)
-+# define write_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
-+
-+# define write_unlock(x) spin_unlock(x)
-+# define write_unlock_irq(x) spin_unlock_irq(x)
-+# define write_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
-+#endif /* !SPINLOCK */
-+
-+#ifndef SPINLOCK_23
-+# define spin_lock_bh(x) spin_lock_irq(x)
-+# define spin_unlock_bh(x) spin_unlock_irq(x)
-+
-+# define read_lock_bh(x) read_lock_irq(x)
-+# define read_unlock_bh(x) read_unlock_irq(x)
-+
-+# define write_lock_bh(x) write_lock_irq(x)
-+# define write_unlock_bh(x) write_unlock_irq(x)
-+#endif /* !SPINLOCK_23 */
-+
-+#ifndef HAVE_NETDEV_PRINTK
-+#define netdev_printk(sevlevel, netdev, msglevel, format, arg...) \
-+ printk(sevlevel "%s: " format , netdev->name , ## arg)
-+#endif
-+
-+#endif /* _FREESWAN_KVERSIONS_H */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.9 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_kversion.h,v
-+ *
-+ * Revision 1.8 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.7 2003/07/31 22:48:08 mcr
-+ * derive NET25-ness from presence of NETLINK_XFRM macro.
-+ *
-+ * Revision 1.6 2003/06/24 20:22:32 mcr
-+ * added new global: ipsecdevices[] so that we can keep track of
-+ * the ipsecX devices. They will be referenced with dev_hold(),
-+ * so 2.2 may need this as well.
-+ *
-+ * Revision 1.5 2003/04/03 17:38:09 rgb
-+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
-+ *
-+ * Revision 1.4 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_kversion.h,v
-+ *
-+ * Revision 1.3 2002/04/12 03:21:17 mcr
-+ * three parameter version of ip_select_ident appears first
-+ * in 2.4.2 (RH7.1) not 2.4.4.
-+ *
-+ * Revision 1.2 2002/03/08 21:35:22 rgb
-+ * Defined LINUX_KERNEL_HAS_SNPRINTF to shut up compiler warnings after
-+ * 2.4.9. (Andreas Piesk).
-+ *
-+ * Revision 1.1 2002/01/29 02:11:42 mcr
-+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
-+ * updating of IPv6 structures to match latest in6.h version.
-+ * removed dead code from freeswan.h that also duplicated kversions.h
-+ * code.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_life.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,112 @@
-+/*
-+ * Definitions relevant to IPSEC lifetimes
-+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ * and Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
-+ *
-+ */
-+
-+/*
-+ * This file describes the book keeping fields for the
-+ * IPsec Security Association Structure. ("ipsec_sa")
-+ *
-+ * This structure is never allocated directly by kernel code,
-+ * (it is always a static/auto or is part of a structure)
-+ * so it does not have a reference count.
-+ *
-+ */
-+
-+#ifndef _IPSEC_LIFE_H_
-+
-+/*
-+ * _count is total count.
-+ * _hard is hard limit (kill SA after this number)
-+ * _soft is soft limit (try to renew SA after this number)
-+ * _last is used in some special cases.
-+ *
-+ */
-+
-+struct ipsec_lifetime64
-+{
-+ __u64 ipl_count;
-+ __u64 ipl_soft;
-+ __u64 ipl_hard;
-+ __u64 ipl_last;
-+};
-+
-+struct ipsec_lifetimes
-+{
-+ /* number of bytes processed */
-+ struct ipsec_lifetime64 ipl_bytes;
-+
-+ /* number of packets processed */
-+ struct ipsec_lifetime64 ipl_packets;
-+
-+ /* time since SA was added */
-+ struct ipsec_lifetime64 ipl_addtime;
-+
-+ /* time since SA was first used */
-+ struct ipsec_lifetime64 ipl_usetime;
-+
-+ /* from rfc2367:
-+ * For CURRENT, the number of different connections,
-+ * endpoints, or flows that the association has been
-+ * allocated towards. For HARD and SOFT, the number of
-+ * these the association may be allocated towards
-+ * before it expires. The concept of a connection,
-+ * flow, or endpoint is system specific.
-+ *
-+ * mcr(2001-9-18) it is unclear what purpose these serve for FreeSWAN.
-+ * They are maintained for PF_KEY compatibility.
-+ */
-+ struct ipsec_lifetime64 ipl_allocations;
-+};
-+
-+enum ipsec_life_alive {
-+ ipsec_life_harddied = -1,
-+ ipsec_life_softdied = 0,
-+ ipsec_life_okay = 1
-+};
-+
-+enum ipsec_life_type {
-+ ipsec_life_timebased = 1,
-+ ipsec_life_countbased= 0
-+};
-+
-+#define _IPSEC_LIFE_H_
-+#endif /* _IPSEC_LIFE_H_ */
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.4 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_life.h,v
-+ *
-+ * Revision 1.3 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_life.h,v
-+ *
-+ * Revision 1.2 2001/11/26 09:16:14 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:25:58 mcr
-+ * lifetime structure created and common functions created.
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_md5h.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,140 @@
-+/*
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * The rest of this file is Copyright RSA DSI. See the following comments
-+ * for the full Copyright notice.
-+ */
-+
-+#ifndef _IPSEC_MD5H_H_
-+#define _IPSEC_MD5H_H_
-+
-+/* GLOBAL.H - RSAREF types and constants
-+ */
-+
-+/* PROTOTYPES should be set to one if and only if the compiler supports
-+ function argument prototyping.
-+ The following makes PROTOTYPES default to 0 if it has not already
-+ been defined with C compiler flags.
-+ */
-+#ifndef PROTOTYPES
-+#define PROTOTYPES 1
-+#endif /* !PROTOTYPES */
-+
-+/* POINTER defines a generic pointer type */
-+typedef __u8 *POINTER;
-+
-+/* UINT2 defines a two byte word */
-+typedef __u16 UINT2;
-+
-+/* UINT4 defines a four byte word */
-+typedef __u32 UINT4;
-+
-+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
-+ If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
-+ returns an empty list.
-+ */
-+
-+#if PROTOTYPES
-+#define PROTO_LIST(list) list
-+#else /* PROTOTYPES */
-+#define PROTO_LIST(list) ()
-+#endif /* PROTOTYPES */
-+
-+
-+/* MD5.H - header file for MD5C.C
-+ */
-+
-+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-+rights reserved.
-+
-+License to copy and use this software is granted provided that it
-+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-+Algorithm" in all material mentioning or referencing this software
-+or this function.
-+
-+License is also granted to make and use derivative works provided
-+that such works are identified as "derived from the RSA Data
-+Security, Inc. MD5 Message-Digest Algorithm" in all material
-+mentioning or referencing the derived work.
-+
-+RSA Data Security, Inc. makes no representations concerning either
-+the merchantability of this software or the suitability of this
-+software for any particular purpose. It is provided "as is"
-+without express or implied warranty of any kind.
-+
-+These notices must be retained in any copies of any part of this
-+documentation and/or software.
-+ */
-+
-+/* MD5 context. */
-+typedef struct {
-+ UINT4 state[4]; /* state (ABCD) */
-+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
-+ unsigned char buffer[64]; /* input buffer */
-+} MD5_CTX;
-+
-+void MD5Init PROTO_LIST ((void *));
-+void MD5Update PROTO_LIST
-+ ((void *, unsigned char *, __u32));
-+void MD5Final PROTO_LIST ((unsigned char [16], void *));
-+
-+#endif /* _IPSEC_MD5H_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.9 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_md5h.h,v
-+ *
-+ * Revision 1.8 2002/09/10 01:45:09 mcr
-+ * changed type of MD5_CTX and SHA1_CTX to void * so that
-+ * the function prototypes would match, and could be placed
-+ * into a pointer to a function.
-+ *
-+ * Revision 1.7 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_md5h.h,v
-+ *
-+ * Revision 1.6 1999/12/13 13:59:13 rgb
-+ * Quick fix to argument size to Update bugs.
-+ *
-+ * Revision 1.5 1999/12/07 18:16:23 rgb
-+ * Fixed comments at end of #endif lines.
-+ *
-+ * Revision 1.4 1999/04/06 04:54:26 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.3 1999/01/22 06:19:58 rgb
-+ * 64-bit clean-up.
-+ *
-+ * Revision 1.2 1998/11/30 13:22:54 rgb
-+ * Rationalised all the klips kernel file headers. They are much shorter
-+ * now and won't conflict under RH5.2.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:48 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.2 1998/04/23 20:54:03 rgb
-+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
-+ * verified.
-+ *
-+ * Revision 1.1 1998/04/09 03:04:21 henry
-+ * sources moved up from linux/net/ipsec
-+ * these two include files modified not to include others except in kernel
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * No changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:48:53 ji
-+ * Release update only.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_param.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,333 @@
-+/*
-+ * @(#) FreeSWAN tunable paramaters
-+ *
-+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ * and Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ */
-+
-+/*
-+ * This file provides a set of #define's which may be tuned by various
-+ * people/configurations. It keeps all compile-time tunables in one place.
-+ *
-+ * This file should be included before all other IPsec kernel-only files.
-+ *
-+ */
-+
-+#ifndef _IPSEC_PARAM_H_
-+
-+#ifdef __KERNEL__
-+#include "ipsec_kversion.h"
-+
-+/* Set number of ipsecX virtual devices here. */
-+/* This must be < exp(field width of IPSEC_DEV_FORMAT) */
-+/* It must also be reasonable so as not to overload the memory and CPU */
-+/* constraints of the host. */
-+#define IPSEC_NUM_IF 4
-+/* The field width must be < IF_NAM_SIZ - strlen("ipsec") - 1. */
-+/* With "ipsec" being 5 characters, that means 10 is the max field width */
-+/* but machine memory and CPU constraints are not likely to tollerate */
-+/* more than 3 digits. The default is one digit. */
-+/* Update: userland scripts get upset if they can't find "ipsec0", so */
-+/* for now, no "0"-padding should be used (which would have been helpful */
-+/* to make text-searches work */
-+#define IPSEC_DEV_FORMAT "ipsec%d"
-+/* For, say, 500 virtual ipsec devices, I would recommend: */
-+/* #define IPSEC_NUM_IF 500 */
-+/* #define IPSEC_DEV_FORMAT "ipsec%03d" */
-+/* Note that the "interfaces=" line in /etc/ipsec.conf would be, um, challenging. */
-+
-+/* use dynamic ipsecX device allocation */
-+#ifndef CONFIG_IPSEC_DYNDEV
-+#define CONFIG_IPSEC_DYNDEV 1
-+#endif /* CONFIG_IPSEC_DYNDEV */
-+
-+
-+#ifdef CONFIG_IPSEC_BIGGATE
-+# define SADB_HASHMOD 8069
-+#else /* CONFIG_IPSEC_BIGGATE */
-+# define SADB_HASHMOD 257
-+#endif /* CONFIG_IPSEC_BIGGATE */
-+#endif /* __KERNEL__ */
-+
-+/*
-+ * This is for the SA reference table. This number is related to the
-+ * maximum number of SAs that KLIPS can concurrently deal with, plus enough
-+ * space for keeping expired SAs around.
-+ *
-+ * TABLE_MAX_WIDTH is the number of bits that we will use.
-+ * MAIN_TABLE_WIDTH is the number of bits used for the primary index table.
-+ *
-+ */
-+#ifndef IPSEC_SA_REF_TABLE_IDX_WIDTH
-+# define IPSEC_SA_REF_TABLE_IDX_WIDTH 16
-+#endif
-+
-+#ifndef IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
-+# define IPSEC_SA_REF_MAINTABLE_IDX_WIDTH 4
-+#endif
-+
-+#ifndef IPSEC_SA_REF_FREELIST_NUM_ENTRIES
-+# define IPSEC_SA_REF_FREELIST_NUM_ENTRIES 256
-+#endif
-+
-+#ifndef IPSEC_SA_REF_CODE
-+# define IPSEC_SA_REF_CODE 1
-+#endif
-+
-+#ifdef __KERNEL__
-+/* This is defined for 2.4, but not 2.2.... */
-+#ifndef ARPHRD_VOID
-+# define ARPHRD_VOID 0xFFFF
-+#endif
-+
-+/*
-+ * Worry about PROC_FS stuff
-+ */
-+#if defined(PROC_FS_2325)
-+/* kernel 2.4 */
-+# define IPSEC_PROC_LAST_ARG ,int *eof,void *data
-+# define IPSEC_PROCFS_DEBUG_NO_STATIC
-+# define IPSEC_PROC_SUBDIRS
-+#else
-+/* kernel <2.4 */
-+# define IPSEC_PROCFS_DEBUG_NO_STATIC DEBUG_NO_STATIC
-+
-+# ifndef PROC_NO_DUMMY
-+# define IPSEC_PROC_LAST_ARG , int dummy
-+# else
-+# define IPSEC_PROC_LAST_ARG
-+# endif /* !PROC_NO_DUMMY */
-+#endif /* PROC_FS_2325 */
-+
-+#if !defined(LINUX_KERNEL_HAS_SNPRINTF)
-+/* GNU CPP specific! */
-+# define snprintf(buf, len, fmt...) sprintf(buf, ##fmt)
-+#endif /* !LINUX_KERNEL_HAS_SNPRINTF */
-+
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+
-+#ifndef KLIPS_FIXES_DES_PARITY
-+# define KLIPS_FIXES_DES_PARITY 1
-+#endif /* !KLIPS_FIXES_DES_PARITY */
-+
-+/* we don't really want to print these unless there are really big problems */
-+#ifndef KLIPS_DIVULGE_CYPHER_KEY
-+# define KLIPS_DIVULGE_CYPHER_KEY 0
-+#endif /* !KLIPS_DIVULGE_CYPHER_KEY */
-+
-+#ifndef KLIPS_DIVULGE_HMAC_KEY
-+# define KLIPS_DIVULGE_HMAC_KEY 0
-+#endif /* !KLIPS_DIVULGE_HMAC_KEY */
-+
-+#ifndef IPSEC_DISALLOW_IPOPTIONS
-+# define IPSEC_DISALLOW_IPOPTIONS 1
-+#endif /* !KLIPS_DIVULGE_HMAC_KEY */
-+
-+/* extra toggles for regression testing */
-+#ifdef CONFIG_IPSEC_REGRESS
-+
-+/*
-+ * should pfkey_acquire() become 100% lossy?
-+ *
-+ */
-+extern int sysctl_ipsec_regress_pfkey_lossage;
-+#ifndef KLIPS_PFKEY_ACQUIRE_LOSSAGE
-+# ifdef CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE
-+# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 100
-+# else /* CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE */
-+/* not by default! */
-+# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
-+# endif /* CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE */
-+#endif /* KLIPS_PFKEY_ACQUIRE_LOSSAGE */
-+
-+#endif /* CONFIG_IPSEC_REGRESS */
-+
-+
-+/*
-+ * debugging routines.
-+ */
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern void ipsec_print_ip(struct iphdr *ip);
-+
-+ #define KLIPS_PRINT(flag, format, args...) \
-+ ((flag) ? printk(KERN_INFO format , ## args) : 0)
-+ #define KLIPS_PRINTMORE(flag, format, args...) \
-+ ((flag) ? printk(format , ## args) : 0)
-+ #define KLIPS_IP_PRINT(flag, ip) \
-+ ((flag) ? ipsec_print_ip(ip) : 0)
-+#else /* CONFIG_IPSEC_DEBUG */
-+ #define KLIPS_PRINT(flag, format, args...) do ; while(0)
-+ #define KLIPS_PRINTMORE(flag, format, args...) do ; while(0)
-+ #define KLIPS_IP_PRINT(flag, ip) do ; while(0)
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+
-+/*
-+ * Stupid kernel API differences in APIs. Not only do some
-+ * kernels not have ip_select_ident, but some have differing APIs,
-+ * and SuSE has one with one parameter, but no way of checking to
-+ * see what is really what.
-+ */
-+
-+#ifdef SUSE_LINUX_2_4_19_IS_STUPID
-+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
-+#else
-+
-+/* simplest case, nothing */
-+#if !defined(IP_SELECT_IDENT)
-+#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
-+#endif
-+
-+/* kernels > 2.3.37-ish */
-+#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
-+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
-+#endif
-+
-+/* kernels > 2.4.2 */
-+#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
-+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
-+#endif
-+
-+#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
-+
-+/*
-+ * make klips fail test:east-espiv-01.
-+ * exploit is at testing/attacks/espiv
-+ *
-+ */
-+#define KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK 0
-+
-+
-+/* IP_FRAGMENT_LINEARIZE is set in freeswan.h if Kernel > 2.4.4 */
-+#ifndef IP_FRAGMENT_LINEARIZE
-+# define IP_FRAGMENT_LINEARIZE 0
-+#endif /* IP_FRAGMENT_LINEARIZE */
-+#endif /* __KERNEL__ */
-+
-+#define _IPSEC_PARAM_H_
-+#endif /* _IPSEC_PARAM_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.24 2004/04/05 19:55:06 mcr
-+ * Moved from linux/include/freeswan/ipsec_param.h,v
-+ *
-+ * Revision 1.23 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.22 2003/10/31 02:27:05 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.21.4.1 2003/10/29 01:10:19 mcr
-+ * elimited "struct sa_id"
-+ *
-+ * Revision 1.21 2003/04/03 17:38:18 rgb
-+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
-+ * Change indentation for readability.
-+ *
-+ * Revision 1.20 2003/03/14 08:09:26 rgb
-+ * Fixed up CONFIG_IPSEC_DYNDEV definitions.
-+ *
-+ * Revision 1.19 2003/01/30 02:31:43 rgb
-+ *
-+ * Rename SAref table macro names for clarity.
-+ *
-+ * Revision 1.18 2002/09/30 19:06:26 rgb
-+ * Reduce default table to 16 bits width.
-+ *
-+ * Revision 1.17 2002/09/20 15:40:29 rgb
-+ * Define switch to activate new SAref code.
-+ * Prefix macros with "IPSEC_".
-+ * Rework saref freelist.
-+ * Restrict some bits to kernel context for use to klips utils.
-+ *
-+ * Revision 1.16 2002/09/20 05:00:31 rgb
-+ * Define switch to divulge hmac keys for debugging.
-+ * Added IPOPTIONS switch.
-+ *
-+ * Revision 1.15 2002/09/19 02:34:24 mcr
-+ * define IPSEC_PROC_SUBDIRS if we are 2.4, and use that in ipsec_proc.c
-+ * to decide if we are to create /proc/net/ipsec/.
-+ *
-+ * Revision 1.14 2002/08/30 01:20:54 mcr
-+ * reorganized 2.0/2.2/2.4 procfs support macro so match
-+ * 2.4 values/typedefs.
-+ *
-+ * Revision 1.13 2002/07/28 22:03:28 mcr
-+ * added some documentation to SA_REF_*
-+ * turned on fix for ESPIV attack, now that we have the attack code.
-+ *
-+ * Revision 1.12 2002/07/26 08:48:31 rgb
-+ * Added SA ref table code.
-+ *
-+ * Revision 1.11 2002/07/23 02:57:45 rgb
-+ * Define ARPHRD_VOID for < 2.4 kernels.
-+ *
-+ * Revision 1.10 2002/05/27 21:37:28 rgb
-+ * Set the defaults sanely for those adventurous enough to try more than 1
-+ * digit of ipsec devices.
-+ *
-+ * Revision 1.9 2002/05/27 18:56:07 rgb
-+ * Convert to dynamic ipsec device allocation.
-+ *
-+ * Revision 1.8 2002/04/24 07:36:47 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_param.h,v
-+ *
-+ * Revision 1.7 2002/04/20 00:12:25 rgb
-+ * Added esp IV CBC attack fix, disabled.
-+ *
-+ * Revision 1.6 2002/01/29 02:11:42 mcr
-+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
-+ * updating of IPv6 structures to match latest in6.h version.
-+ * removed dead code from freeswan.h that also duplicated kversions.h
-+ * code.
-+ *
-+ * Revision 1.5 2002/01/28 19:22:01 mcr
-+ * by default, turn off LINEARIZE option
-+ * (let kversions.h turn it on)
-+ *
-+ * Revision 1.4 2002/01/20 20:19:36 mcr
-+ * renamed option to IP_FRAGMENT_LINEARIZE.
-+ *
-+ * Revision 1.3 2002/01/12 02:57:25 mcr
-+ * first regression test causes acquire messages to be lost
-+ * 100% of the time. This is to help testing of pluto.
-+ *
-+ * Revision 1.2 2001/11/26 09:16:14 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.3 2001/10/23 04:40:16 mcr
-+ * added #define for DIVULGING session keys in debug output.
-+ *
-+ * Revision 1.1.2.2 2001/10/22 20:53:25 mcr
-+ * added a define to control forcing of DES parity.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:20:19 mcr
-+ * many common kernel configuration questions centralized.
-+ * more things remain that should be moved from freeswan.h.
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_policy.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,216 @@
-+#ifndef _IPSEC_POLICY_H
-+/*
-+ * policy interface file between pluto and applications
-+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#define _IPSEC_POLICY_H /* seen it, no need to see it again */
-+
-+
-+/*
-+ * this file defines an interface between an application (or rather an
-+ * application library) and a key/policy daemon. It provides for inquiries
-+ * as to the current state of a connected socket, as well as for general
-+ * questions.
-+ *
-+ * In general, the interface is defined as a series of functional interfaces,
-+ * and the policy messages should be internal. However, because this is in
-+ * fact an ABI between pieces of the system that may get compiled and revised
-+ * seperately, this ABI must be public and revision controlled.
-+ *
-+ * It is expected that the daemon will always support previous versions.
-+ */
-+
-+#define IPSEC_POLICY_MSG_REVISION (unsigned)200305061
-+
-+enum ipsec_policy_command {
-+ IPSEC_CMD_QUERY_FD = 1,
-+ IPSEC_CMD_QUERY_HOSTPAIR = 2,
-+ IPSEC_CMD_QUERY_DSTONLY = 3,
-+};
-+
-+struct ipsec_policy_msg_head {
-+ u_int32_t ipm_version;
-+ u_int32_t ipm_msg_len;
-+ u_int32_t ipm_msg_type;
-+ u_int32_t ipm_msg_seq;
-+};
-+
-+enum ipsec_privacy_quality {
-+ IPSEC_PRIVACY_NONE = 0,
-+ IPSEC_PRIVACY_INTEGRAL = 4, /* not private at all. AH-like */
-+ IPSEC_PRIVACY_UNKNOWN = 8, /* something is claimed, but details unavail */
-+ IPSEC_PRIVACY_ROT13 = 12, /* trivially breakable, i.e. 1DES */
-+ IPSEC_PRIVACY_GAK = 16, /* known eavesdroppers */
-+ IPSEC_PRIVACY_PRIVATE = 32, /* secure for at least a decade */
-+ IPSEC_PRIVACY_STRONG = 64, /* ridiculously secure */
-+ IPSEC_PRIVACY_TORTOISE = 192, /* even stronger, but very slow */
-+ IPSEC_PRIVACY_OTP = 224, /* some kind of *true* one time pad */
-+};
-+
-+enum ipsec_bandwidth_quality {
-+ IPSEC_QOS_UNKNOWN = 0, /* unknown bandwidth */
-+ IPSEC_QOS_INTERACTIVE = 16, /* reasonably moderate jitter, moderate fast.
-+ Good enough for telnet/ssh. */
-+ IPSEC_QOS_VOIP = 32, /* faster crypto, predicable jitter */
-+ IPSEC_QOS_FTP = 64, /* higher throughput crypto, perhaps hardware
-+ offloaded, but latency/jitter may be bad */
-+ IPSEC_QOS_WIRESPEED = 128, /* expect to be able to fill your pipe */
-+};
-+
-+/* moved from programs/pluto/constants.h */
-+/* IPsec AH transform values
-+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.3
-+ * and in http://www.iana.org/assignments/isakmp-registry
-+ */
-+enum ipsec_authentication_algo {
-+ AH_MD5=2,
-+ AH_SHA=3,
-+ AH_DES=4,
-+ AH_SHA2_256=5,
-+ AH_SHA2_384=6,
-+ AH_SHA2_512=7
-+};
-+
-+/* IPsec ESP transform values
-+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.4
-+ * and from http://www.iana.org/assignments/isakmp-registry
-+ */
-+
-+enum ipsec_cipher_algo {
-+ ESP_reserved=0,
-+ ESP_DES_IV64=1,
-+ ESP_DES=2,
-+ ESP_3DES=3,
-+ ESP_RC5=4,
-+ ESP_IDEA=5,
-+ ESP_CAST=6,
-+ ESP_BLOWFISH=7,
-+ ESP_3IDEA=8,
-+ ESP_DES_IV32=9,
-+ ESP_RC4=10,
-+ ESP_NULL=11,
-+ ESP_AES=12,
-+};
-+
-+/* IPCOMP transform values
-+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.5
-+ */
-+
-+enum ipsec_comp_algo {
-+ IPCOMP_OUI= 1,
-+ IPCOMP_DEFLATE= 2,
-+ IPCOMP_LZS= 3,
-+ IPCOMP_V42BIS= 4
-+};
-+
-+/* Identification type values
-+ * RFC 2407 The Internet IP security Domain of Interpretation for ISAKMP 4.6.2.1
-+ */
-+
-+enum ipsec_id_type {
-+ ID_IMPOSSIBLE= (-2), /* private to Pluto */
-+ ID_MYID= (-1), /* private to Pluto */
-+ ID_NONE= 0, /* private to Pluto */
-+ ID_IPV4_ADDR= 1,
-+ ID_FQDN= 2,
-+ ID_USER_FQDN= 3,
-+ ID_IPV4_ADDR_SUBNET= 4,
-+ ID_IPV6_ADDR= 5,
-+ ID_IPV6_ADDR_SUBNET= 6,
-+ ID_IPV4_ADDR_RANGE= 7,
-+ ID_IPV6_ADDR_RANGE= 8,
-+ ID_DER_ASN1_DN= 9,
-+ ID_DER_ASN1_GN= 10,
-+ ID_KEY_ID= 11
-+};
-+
-+/* Certificate type values
-+ * RFC 2408 ISAKMP, chapter 3.9
-+ */
-+enum ipsec_cert_type {
-+ CERT_NONE= 0, /* none, or guess from file contents */
-+ CERT_PKCS7_WRAPPED_X509= 1, /* self-signed certificate from disk */
-+ CERT_PGP= 2,
-+ CERT_DNS_SIGNED_KEY= 3, /* KEY RR from DNS */
-+ CERT_X509_SIGNATURE= 4,
-+ CERT_X509_KEY_EXCHANGE= 5,
-+ CERT_KERBEROS_TOKENS= 6,
-+ CERT_CRL= 7,
-+ CERT_ARL= 8,
-+ CERT_SPKI= 9,
-+ CERT_X509_ATTRIBUTE= 10,
-+ CERT_RAW_RSA= 11, /* raw RSA from config file */
-+};
-+
-+/* a SIG record in ASCII */
-+struct ipsec_dns_sig {
-+ char fqdn[256];
-+ char dns_sig[768]; /* empty string if not signed */
-+};
-+
-+struct ipsec_raw_key {
-+ char id_name[256];
-+ char fs_keyid[8];
-+};
-+
-+struct ipsec_identity {
-+ enum ipsec_id_type ii_type;
-+ enum ipsec_cert_type ii_format;
-+ union {
-+ struct ipsec_dns_sig ipsec_dns_signed;
-+ /* some thing for PGP */
-+ /* some thing for PKIX */
-+ struct ipsec_raw_key ipsec_raw_key;
-+ } ii_credential;
-+};
-+
-+#define IPSEC_MAX_CREDENTIALS 32
-+
-+struct ipsec_policy_cmd_query {
-+ struct ipsec_policy_msg_head head;
-+
-+ /* Query section */
-+ ip_address query_local; /* us */
-+ ip_address query_remote; /* them */
-+ u_short src_port, dst_port;
-+
-+ /* Answer section */
-+ enum ipsec_privacy_quality strength;
-+ enum ipsec_bandwidth_quality bandwidth;
-+ enum ipsec_authentication_algo auth_detail;
-+ enum ipsec_cipher_algo esp_detail;
-+ enum ipsec_comp_algo comp_detail;
-+
-+ int credential_count;
-+
-+ struct ipsec_identity credentials[IPSEC_MAX_CREDENTIALS];
-+};
-+
-+#define IPSEC_POLICY_SOCKET "/var/run/pluto.info"
-+
-+/* prototypes */
-+extern err_t ipsec_policy_lookup(int fd, struct ipsec_policy_cmd_query *result);
-+extern err_t ipsec_policy_init(void);
-+extern err_t ipsec_policy_final(void);
-+extern err_t ipsec_policy_readmsg(int policysock,
-+ unsigned char *buf, size_t buflen);
-+extern err_t ipsec_policy_sendrecv(unsigned char *buf, size_t buflen);
-+extern err_t ipsec_policy_cgilookup(struct ipsec_policy_cmd_query *result);
-+
-+
-+extern const char *ipsec_policy_version_code(void);
-+extern const char *ipsec_policy_version_string(void);
-+
-+#endif /* _IPSEC_POLICY_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_proto.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,151 @@
-+/*
-+ * @(#) prototypes for FreeSWAN functions
-+ *
-+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ * and Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ */
-+
-+#ifndef _IPSEC_PROTO_H_
-+
-+#include "ipsec_param.h"
-+
-+/*
-+ * This file is a kernel only file that declares prototypes for
-+ * all intra-module function calls and global data structures.
-+ *
-+ * Include this file last.
-+ *
-+ */
-+
-+/* ipsec_init.c */
-+extern struct prng ipsec_prng;
-+
-+/* ipsec_sa.c */
-+extern struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
-+extern spinlock_t tdb_lock;
-+extern int ipsec_sadb_init(void);
-+
-+extern struct ipsec_sa *ipsec_sa_getbyid(ip_said *);
-+extern int ipsec_sa_put(struct ipsec_sa *);
-+extern /* void */ int ipsec_sa_del(struct ipsec_sa *);
-+extern /* void */ int ipsec_sa_delchain(struct ipsec_sa *);
-+extern /* void */ int ipsec_sa_add(struct ipsec_sa *);
-+
-+extern int ipsec_sadb_cleanup(__u8);
-+extern int ipsec_sa_wipe(struct ipsec_sa *);
-+
-+/* debug declarations */
-+
-+/* ipsec_proc.c */
-+extern int ipsec_proc_init(void);
-+extern void ipsec_proc_cleanup(void);
-+
-+/* ipsec_radij.c */
-+extern int ipsec_makeroute(struct sockaddr_encap *ea,
-+ struct sockaddr_encap *em,
-+ ip_said said,
-+ uint32_t pid,
-+ struct sk_buff *skb,
-+ struct ident *ident_s,
-+ struct ident *ident_d);
-+
-+extern int ipsec_breakroute(struct sockaddr_encap *ea,
-+ struct sockaddr_encap *em,
-+ struct sk_buff **first,
-+ struct sk_buff **last);
-+
-+int ipsec_radijinit(void);
-+int ipsec_cleareroutes(void);
-+int ipsec_radijcleanup(void);
-+
-+/* ipsec_life.c */
-+extern enum ipsec_life_alive ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
-+ const char *lifename,
-+ const char *saname,
-+ enum ipsec_life_type ilt,
-+ enum ipsec_direction idir,
-+ struct ipsec_sa *ips);
-+
-+
-+extern int ipsec_lifetime_format(char *buffer,
-+ int buflen,
-+ char *lifename,
-+ enum ipsec_life_type timebaselife,
-+ struct ipsec_lifetime64 *lifetime);
-+
-+extern void ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
-+ __u64 newvalue);
-+
-+extern void ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
-+ __u64 newvalue);
-+
-+
-+
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+
-+extern int debug_xform;
-+extern int debug_eroute;
-+extern int debug_spi;
-+extern int debug_netlink;
-+
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+
-+
-+
-+#define _IPSEC_PROTO_H
-+#endif /* _IPSEC_PROTO_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.8 2004/04/05 19:55:06 mcr
-+ * Moved from linux/include/freeswan/ipsec_proto.h,v
-+ *
-+ * Revision 1.7 2003/10/31 02:27:05 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.6.30.1 2003/10/29 01:10:19 mcr
-+ * elimited "struct sa_id"
-+ *
-+ * Revision 1.6 2002/05/23 07:13:48 rgb
-+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
-+ *
-+ * Revision 1.5 2002/05/14 02:36:40 rgb
-+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
-+ * with "put" usage in the kernel.
-+ *
-+ * Revision 1.4 2002/04/24 07:36:47 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_proto.h,v
-+ *
-+ * Revision 1.3 2002/04/20 00:12:25 rgb
-+ * Added esp IV CBC attack fix, disabled.
-+ *
-+ * Revision 1.2 2001/11/26 09:16:15 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:21:01 mcr
-+ * ipsec_proto.h created to keep prototypes rather than deal with
-+ * cyclic dependancies of structures and prototypes in .h files.
-+ *
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_radij.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,176 @@
-+/*
-+ * @(#) Definitions relevant to the IPSEC <> radij tree interfacing
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifndef _IPSEC_RADIJ_H
-+
-+#include <openswan.h>
-+
-+int ipsec_walk(char *);
-+
-+int ipsec_rj_walker_procprint(struct radij_node *, void *);
-+int ipsec_rj_walker_delete(struct radij_node *, void *);
-+
-+/* This structure is used to pass information between
-+ * ipsec_eroute_get_info and ipsec_rj_walker_procprint
-+ * (through rj_walktree) and between calls of ipsec_rj_walker_procprint.
-+ */
-+struct wsbuf
-+{
-+ /* from caller of ipsec_eroute_get_info: */
-+ char *const buffer; /* start of buffer provided */
-+ const int length; /* length of buffer provided */
-+ const off_t offset; /* file position of first character of interest */
-+ /* accumulated by ipsec_rj_walker_procprint: */
-+ int len; /* number of character filled into buffer */
-+ off_t begin; /* file position contained in buffer[0] (<=offset) */
-+};
-+
-+extern struct radij_node_head *rnh;
-+extern spinlock_t eroute_lock;
-+
-+struct eroute * ipsec_findroute(struct sockaddr_encap *);
-+
-+#define O1(x) (int)(((x)>>24)&0xff)
-+#define O2(x) (int)(((x)>>16)&0xff)
-+#define O3(x) (int)(((x)>>8)&0xff)
-+#define O4(x) (int)(((x))&0xff)
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int debug_radij;
-+void rj_dumptrees(void);
-+
-+#define DB_RJ_DUMPTREES 0x0001
-+#define DB_RJ_FINDROUTE 0x0002
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#define _IPSEC_RADIJ_H
-+#endif
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.21 2004/04/29 11:06:42 ken
-+ * Last bits from 2.06 procfs updates
-+ *
-+ * Revision 1.20 2004/04/06 02:49:08 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.19 2004/04/05 19:55:06 mcr
-+ * Moved from linux/include/freeswan/ipsec_radij.h,v
-+ *
-+ * Revision 1.18 2002/04/24 07:36:47 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_radij.h,v
-+ *
-+ * Revision 1.17 2001/11/26 09:23:49 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.16.2.1 2001/09/25 02:21:17 mcr
-+ * ipsec_proto.h created to keep prototypes rather than deal with
-+ * cyclic dependancies of structures and prototypes in .h files.
-+ *
-+ * Revision 1.16 2001/09/15 16:24:04 rgb
-+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
-+ *
-+ * Revision 1.15 2001/09/14 16:58:37 rgb
-+ * Added support for storing the first and last packets through a HOLD.
-+ *
-+ * Revision 1.14 2001/09/08 21:13:32 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.13 2001/06/14 19:35:09 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.12 2001/05/27 06:12:11 rgb
-+ * Added structures for pid, packet count and last access time to eroute.
-+ * Added packet count to beginning of /proc/net/ipsec_eroute.
-+ *
-+ * Revision 1.11 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.10 1999/11/17 15:53:39 rgb
-+ * Changed all occurrences of #include "../../../lib/freeswan.h"
-+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
-+ * klips/net/ipsec/Makefile.
-+ *
-+ * Revision 1.9 1999/10/01 00:01:23 rgb
-+ * Added eroute structure locking.
-+ *
-+ * Revision 1.8 1999/04/11 00:28:59 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.7 1999/04/06 04:54:26 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.6 1999/01/22 06:23:26 rgb
-+ * Cruft clean-out.
-+ *
-+ * Revision 1.5 1998/10/25 02:42:08 rgb
-+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an
-+ * argument to be able to transmit more infomation about errors.
-+ *
-+ * Revision 1.4 1998/10/19 14:44:29 rgb
-+ * Added inclusion of freeswan.h.
-+ * sa_id structure implemented and used: now includes protocol.
-+ *
-+ * Revision 1.3 1998/07/28 00:03:31 rgb
-+ * Comment out temporary inet_nto4u() kluge.
-+ *
-+ * Revision 1.2 1998/07/14 18:22:00 rgb
-+ * Add function to clear the eroute table.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:49 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.5 1998/05/25 20:30:38 rgb
-+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
-+ *
-+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
-+ * add ipsec_rj_walker_delete.
-+ *
-+ * Revision 1.4 1998/05/21 13:02:56 rgb
-+ * Imported definitions from ipsec_radij.c and radij.c to support /proc 3k
-+ * limit fix.
-+ *
-+ * Revision 1.3 1998/04/21 21:29:09 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.2 1998/04/14 17:30:39 rgb
-+ * Fix up compiling errors for radij tree memory reclamation.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:10 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * No changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:39:04 ji
-+ * Minor cleanups.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_rcv.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,279 @@
-+/*
-+ *
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifndef IPSEC_RCV_H
-+#define IPSEC_RCV_H
-+
-+#include "openswan/ipsec_auth.h"
-+
-+#define DB_RX_PKTRX 0x0001
-+#define DB_RX_PKTRX2 0x0002
-+#define DB_RX_DMP 0x0004
-+#define DB_RX_IPSA 0x0010
-+#define DB_RX_XF 0x0020
-+#define DB_RX_IPAD 0x0040
-+#define DB_RX_INAU 0x0080
-+#define DB_RX_OINFO 0x0100
-+#define DB_RX_OINFO2 0x0200
-+#define DB_RX_OH 0x0400
-+#define DB_RX_REPLAY 0x0800
-+
-+#ifdef __KERNEL__
-+/* struct options; */
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/config.h> /* for CONFIG_IP_FORWARD */
-+#include <linux/version.h>
-+#include <openswan.h>
-+
-+#define IPSEC_BIRTH_TEMPLATE_MAXLEN 256
-+
-+struct ipsec_birth_reply {
-+ int packet_template_len;
-+ unsigned char packet_template[IPSEC_BIRTH_TEMPLATE_MAXLEN];
-+};
-+
-+extern struct ipsec_birth_reply ipsec_ipv4_birth_packet;
-+extern struct ipsec_birth_reply ipsec_ipv6_birth_packet;
-+
-+enum ipsec_rcv_value {
-+ IPSEC_RCV_LASTPROTO=1,
-+ IPSEC_RCV_OK=0,
-+ IPSEC_RCV_BADPROTO=-1,
-+ IPSEC_RCV_BADLEN=-2,
-+ IPSEC_RCV_ESP_BADALG=-3,
-+ IPSEC_RCV_3DES_BADBLOCKING=-4,
-+ IPSEC_RCV_ESP_DECAPFAIL=-5,
-+ IPSEC_RCV_DECAPFAIL=-6,
-+ IPSEC_RCV_SAIDNOTFOUND=-7,
-+ IPSEC_RCV_IPCOMPALONE=-8,
-+ IPSEC_RCV_IPCOMPFAILED=-10,
-+ IPSEC_RCV_SAIDNOTLIVE=-11,
-+ IPSEC_RCV_FAILEDINBOUND=-12,
-+ IPSEC_RCV_LIFETIMEFAILED=-13,
-+ IPSEC_RCV_BADAUTH=-14,
-+ IPSEC_RCV_REPLAYFAILED=-15,
-+ IPSEC_RCV_AUTHFAILED=-16,
-+ IPSEC_RCV_REPLAYROLLED=-17,
-+ IPSEC_RCV_BAD_DECRYPT=-18
-+};
-+
-+struct ipsec_rcv_state {
-+ struct sk_buff *skb;
-+ struct net_device_stats *stats;
-+ struct iphdr *ipp;
-+ struct ipsec_sa *ipsp;
-+ int len;
-+ int ilen;
-+ int authlen;
-+ int hard_header_len;
-+ int iphlen;
-+ struct auth_alg *authfuncs;
-+ ip_said said;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+ __u8 next_header;
-+ __u8 hash[AH_AMAX];
-+ char ipsaddr_txt[ADDRTOA_BUF];
-+ char ipdaddr_txt[ADDRTOA_BUF];
-+ __u8 *octx;
-+ __u8 *ictx;
-+ int ictx_len;
-+ int octx_len;
-+ union {
-+ struct {
-+ struct esphdr *espp;
-+ } espstuff;
-+ struct {
-+ struct ahhdr *ahp;
-+ } ahstuff;
-+ struct {
-+ struct ipcomphdr *compp;
-+ } ipcompstuff;
-+ } protostuff;
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ __u8 natt_type;
-+ __u16 natt_sport;
-+ __u16 natt_dport;
-+ int natt_len;
-+#endif
-+};
-+
-+extern int
-+#ifdef PROTO_HANDLER_SINGLE_PARM
-+ipsec_rcv(struct sk_buff *skb);
-+#else /* PROTO_HANDLER_SINGLE_PARM */
-+ipsec_rcv(struct sk_buff *skb,
-+#ifdef NET_21
-+ unsigned short xlen);
-+#else /* NET_21 */
-+ struct device *dev,
-+ struct options *opt,
-+ __u32 daddr,
-+ unsigned short len,
-+ __u32 saddr,
-+ int redo,
-+ struct inet_protocol *protocol);
-+#endif /* NET_21 */
-+#endif /* PROTO_HANDLER_SINGLE_PARM */
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int debug_rcv;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#define ipsec_rcv_dmp(_x,_y, _z) if (debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp(_x,_y,_z)
-+
-+extern int sysctl_ipsec_inbound_policy_check;
-+#endif /* __KERNEL__ */
-+
-+#endif /* IPSEC_RCV_H */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.21 2004/04/06 02:49:08 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.20 2004/04/05 19:55:06 mcr
-+ * Moved from linux/include/freeswan/ipsec_rcv.h,v
-+ *
-+ * Revision 1.19 2003/12/15 18:13:09 mcr
-+ * when compiling with NAT traversal, don't assume that the
-+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
-+ * is set.
-+ *
-+ * Revision 1.18 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.17 2002/09/03 16:32:32 mcr
-+ * definitions of ipsec_birth_reply.
-+ *
-+ * Revision 1.16 2002/05/14 02:36:00 rgb
-+ * Change references to _TDB to _IPSA.
-+ *
-+ * Revision 1.15 2002/04/24 07:36:47 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_rcv.h,v
-+ *
-+ * Revision 1.14 2001/09/07 22:15:48 rgb
-+ * Fix for removal of transport layer protocol handler arg in 2.4.4.
-+ *
-+ * Revision 1.13 2001/06/14 19:35:09 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.12 2001/03/16 07:36:44 rgb
-+ * Fixed #endif comment to sate compiler.
-+ *
-+ * Revision 1.11 2000/09/21 04:34:21 rgb
-+ * Moved declaration of sysctl_ipsec_inbound_policy_check outside
-+ * CONFIG_IPSEC_DEBUG. (MB)
-+ *
-+ * Revision 1.10 2000/09/18 02:36:10 rgb
-+ * Exported sysctl_ipsec_inbound_policy_check for skb_decompress().
-+ *
-+ * Revision 1.9 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.8 1999/11/18 04:09:19 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ *
-+ * Revision 1.7 1999/05/25 01:45:37 rgb
-+ * Fix version macros for 2.0.x as a module.
-+ *
-+ * Revision 1.6 1999/05/08 21:24:27 rgb
-+ * Add includes for 2.2.x include into net/ipv4/protocol.c
-+ *
-+ * Revision 1.5 1999/05/05 22:02:32 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.4 1999/04/11 00:28:59 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.3 1999/04/06 04:54:27 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.2 1999/01/22 20:06:59 rgb
-+ * Fixed cut-and-paste error from ipsec_esp.h.
-+ *
-+ * Revision 1.1 1999/01/21 20:29:12 rgb
-+ * Converted from transform switching to algorithm switching.
-+ *
-+ * Log: ipsec_esp.h,v
-+ * Revision 1.4 1998/08/12 00:07:32 rgb
-+ * Added data structures for new xforms: null, {,3}dessha1.
-+ *
-+ * Revision 1.3 1998/07/14 15:57:01 rgb
-+ * Add #ifdef __KERNEL__ to protect kernel-only structures.
-+ *
-+ * Revision 1.2 1998/06/25 19:33:46 rgb
-+ * Add prototype for protocol receive function.
-+ * Rearrange for more logical layout.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:45 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.6 1998/06/05 02:28:08 rgb
-+ * Minor comment fix.
-+ *
-+ * Revision 1.5 1998/05/27 22:34:00 rgb
-+ * Changed structures to accomodate key separation.
-+ *
-+ * Revision 1.4 1998/05/18 22:28:43 rgb
-+ * Disable key printing facilities from /proc/net/ipsec_*.
-+ *
-+ * Revision 1.3 1998/04/21 21:29:07 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.2 1998/04/12 22:03:20 rgb
-+ * Updated ESP-3DES-HMAC-MD5-96,
-+ * ESP-DES-HMAC-MD5-96,
-+ * AH-HMAC-MD5-96,
-+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
-+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
-+ *
-+ * Fixed eroute references in /proc/net/ipsec*.
-+ *
-+ * Started to patch module unloading memory leaks in ipsec_netlink and
-+ * radij tree unloading.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:00 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.5 1997/06/03 04:24:48 ji
-+ * Added ESP-3DES-MD5-96 transform.
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * Added definitions for new ESP transforms.
-+ *
-+ * Revision 0.3 1996/11/20 14:35:48 ji
-+ * Minor Cleanup.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
-+
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_sa.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,341 @@
-+/*
-+ * @(#) Definitions of IPsec Security Association (ipsec_sa)
-+ *
-+ * Copyright (C) 2001, 2002, 2003
-+ * Richard Guy Briggs <rgb@freeswan.org>
-+ * and Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
-+ *
-+ */
-+
-+/*
-+ * This file describes the IPsec Security Association Structure.
-+ *
-+ * This structure keeps track of a single transform that may be done
-+ * to a set of packets. It can describe applying the transform or
-+ * apply the reverse. (e.g. compression vs expansion). However, it
-+ * only describes one at a time. To describe both, two structures would
-+ * be used, but since the sides of the transform are performed
-+ * on different machines typically it is usual to have only one side
-+ * of each association.
-+ *
-+ */
-+
-+#ifndef _IPSEC_SA_H_
-+
-+#ifdef __KERNEL__
-+#include "ipsec_stats.h"
-+#include "ipsec_life.h"
-+#include "ipsec_eroute.h"
-+#endif /* __KERNEL__ */
-+#include "ipsec_param.h"
-+
-+
-+/* SAs are held in a table.
-+ * Entries in this table are referenced by IPsecSAref_t values.
-+ * IPsecSAref_t values are conceptually subscripts. Because
-+ * we want to allocate the table piece-meal, the subscripting
-+ * is implemented with two levels, a bit like paged virtual memory.
-+ * This representation mechanism is known as an Iliffe Vector.
-+ *
-+ * The Main table (AKA the refTable) consists of 2^IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
-+ * pointers to subtables.
-+ * Each subtable has 2^IPSEC_SA_REF_SUBTABLE_IDX_WIDTH entries, each of which
-+ * is a pointer to an SA.
-+ *
-+ * An IPsecSAref_t contains either an exceptional value (signified by the
-+ * high-order bit being on) or a reference to a table entry. A table entry
-+ * reference has the subtable subscript in the low-order
-+ * IPSEC_SA_REF_SUBTABLE_IDX_WIDTH bits and the Main table subscript
-+ * in the next lowest IPSEC_SA_REF_MAINTABLE_IDX_WIDTH bits.
-+ *
-+ * The Maintable entry for an IPsecSAref_t x, a pointer to its subtable, is
-+ * IPsecSAref2table(x). It is of type struct IPsecSArefSubTable *.
-+ *
-+ * The pointer to the SA for x is IPsecSAref2SA(x). It is of type
-+ * struct ipsec_sa*. The macro definition clearly shows the two-level
-+ * access needed to find the SA pointer.
-+ *
-+ * The Maintable is allocated when IPsec is initialized.
-+ * Each subtable is allocated when needed, but the first is allocated
-+ * when IPsec is initialized.
-+ *
-+ * IPsecSAref_t is designed to be smaller than an NFmark so that
-+ * they can be stored in NFmarks and still leave a few bits for other
-+ * purposes. The spare bits are in the low order of the NFmark
-+ * but in the high order of the IPsecSAref_t, so conversion is required.
-+ * We pick the upper bits of NFmark on the theory that they are less likely to
-+ * interfere with more pedestrian uses of nfmark.
-+ */
-+
-+
-+typedef unsigned short int IPsecRefTableUnusedCount;
-+
-+#define IPSEC_SA_REF_TABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH)
-+
-+#ifdef __KERNEL__
-+#if ((IPSEC_SA_REF_TABLE_IDX_WIDTH - (1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) < 0)
-+#error "IPSEC_SA_REF_TABLE_IDX_WIDTH("IPSEC_SA_REF_TABLE_IDX_WIDTH") MUST be < 1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH("IPSEC_SA_REF_MAINTABLE_IDX_WIDTH")"
-+#endif
-+
-+#define IPSEC_SA_REF_SUBTABLE_IDX_WIDTH (IPSEC_SA_REF_TABLE_IDX_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
-+
-+#define IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
-+#define IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
-+
-+#ifdef CONFIG_NETFILTER
-+#define IPSEC_SA_REF_HOST_FIELD(x) ((struct sk_buff*)(x))->nfmark
-+#define IPSEC_SA_REF_HOST_FIELD_TYPE typeof(IPSEC_SA_REF_HOST_FIELD(NULL))
-+#else /* CONFIG_NETFILTER */
-+/* just make it work for now, it doesn't matter, since there is no nfmark */
-+#define IPSEC_SA_REF_HOST_FIELD_TYPE unsigned long
-+#endif /* CONFIG_NETFILTER */
-+#define IPSEC_SA_REF_HOST_FIELD_WIDTH (8 * sizeof(IPSEC_SA_REF_HOST_FIELD_TYPE))
-+#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
-+
-+#define IPSEC_SA_REF_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
-+#define IPSEC_SA_REF_TABLE_MASK ((IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
-+#define IPSEC_SA_REF_ENTRY_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_SUBTABLE_IDX_WIDTH))
-+
-+#define IPsecSAref2table(x) (((x) & IPSEC_SA_REF_TABLE_MASK) >> IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
-+#define IPsecSAref2entry(x) ((x) & IPSEC_SA_REF_ENTRY_MASK)
-+#define IPsecSArefBuild(x,y) (((x) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) + (y))
-+
-+#define IPsecSAref2SA(x) (ipsec_sadb.refTable[IPsecSAref2table(x)]->entry[IPsecSAref2entry(x)])
-+#define IPsecSA2SAref(x) ((x)->ips_ref)
-+
-+#define EMT_INBOUND 0x01 /* SA direction, 1=inbound */
-+
-+/* 'struct ipsec_sa' should be 64bit aligned when allocated. */
-+struct ipsec_sa
-+{
-+ IPsecSAref_t ips_ref; /* reference table entry number */
-+ atomic_t ips_refcount; /* reference count for this struct */
-+ struct ipsec_sa *ips_hnext; /* next in hash chain */
-+ struct ipsec_sa *ips_inext; /* pointer to next xform */
-+ struct ipsec_sa *ips_onext; /* pointer to prev xform */
-+
-+ struct ifnet *ips_rcvif; /* related rcv encap interface */
-+
-+ ip_said ips_said; /* SA ID */
-+
-+ __u32 ips_seq; /* seq num of msg that initiated this SA */
-+ __u32 ips_pid; /* PID of process that initiated this SA */
-+ __u8 ips_authalg; /* auth algorithm for this SA */
-+ __u8 ips_encalg; /* enc algorithm for this SA */
-+
-+ struct ipsec_stats ips_errs;
-+
-+ __u8 ips_replaywin; /* replay window size */
-+ __u8 ips_state; /* state of SA */
-+ __u32 ips_replaywin_lastseq; /* last pkt sequence num */
-+ __u64 ips_replaywin_bitmap; /* bitmap of received pkts */
-+ __u32 ips_replaywin_maxdiff; /* max pkt sequence difference */
-+
-+ __u32 ips_flags; /* generic xform flags */
-+
-+
-+ struct ipsec_lifetimes ips_life; /* lifetime records */
-+
-+ /* selector information */
-+ __u8 ips_transport_protocol; /* protocol for this SA, if ports are involved */
-+ struct sockaddr*ips_addr_s; /* src sockaddr */
-+ struct sockaddr*ips_addr_d; /* dst sockaddr */
-+ struct sockaddr*ips_addr_p; /* proxy sockaddr */
-+ __u16 ips_addr_s_size;
-+ __u16 ips_addr_d_size;
-+ __u16 ips_addr_p_size;
-+ ip_address ips_flow_s;
-+ ip_address ips_flow_d;
-+ ip_address ips_mask_s;
-+ ip_address ips_mask_d;
-+
-+ __u16 ips_key_bits_a; /* size of authkey in bits */
-+ __u16 ips_auth_bits; /* size of authenticator in bits */
-+ __u16 ips_key_bits_e; /* size of enckey in bits */
-+ __u16 ips_iv_bits; /* size of IV in bits */
-+ __u8 ips_iv_size;
-+ __u16 ips_key_a_size;
-+ __u16 ips_key_e_size;
-+
-+ caddr_t ips_key_a; /* authentication key */
-+ caddr_t ips_key_e; /* encryption key */
-+ caddr_t ips_iv; /* Initialisation Vector */
-+
-+ struct ident ips_ident_s; /* identity src */
-+ struct ident ips_ident_d; /* identity dst */
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ __u16 ips_comp_adapt_tries; /* ipcomp self-adaption tries */
-+ __u16 ips_comp_adapt_skip; /* ipcomp self-adaption to-skip */
-+ __u64 ips_comp_ratio_cbytes; /* compressed bytes */
-+ __u64 ips_comp_ratio_dbytes; /* decompressed (or uncompressed) bytes */
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ __u8 ips_natt_type;
-+ __u8 ips_natt_reserved[3];
-+ __u16 ips_natt_sport;
-+ __u16 ips_natt_dport;
-+
-+ struct sockaddr *ips_natt_oa;
-+ __u16 ips_natt_oa_size;
-+ __u16 ips_natt_reserved2;
-+#endif
-+
-+#if 0
-+ __u32 ips_sens_dpd;
-+ __u8 ips_sens_sens_level;
-+ __u8 ips_sens_sens_len;
-+ __u64* ips_sens_sens_bitmap;
-+ __u8 ips_sens_integ_level;
-+ __u8 ips_sens_integ_len;
-+ __u64* ips_sens_integ_bitmap;
-+#endif
-+ struct ipsec_alg_enc *ips_alg_enc;
-+ struct ipsec_alg_auth *ips_alg_auth;
-+ IPsecSAref_t ips_ref_rel;
-+};
-+
-+struct IPsecSArefSubTable
-+{
-+ struct ipsec_sa* entry[IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES];
-+};
-+
-+struct ipsec_sadb {
-+ struct IPsecSArefSubTable* refTable[IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES];
-+ IPsecSAref_t refFreeList[IPSEC_SA_REF_FREELIST_NUM_ENTRIES];
-+ int refFreeListHead;
-+ int refFreeListTail;
-+ IPsecSAref_t refFreeListCont;
-+ IPsecSAref_t said_hash[SADB_HASHMOD];
-+ spinlock_t sadb_lock;
-+};
-+
-+extern struct ipsec_sadb ipsec_sadb;
-+
-+extern int ipsec_SAref_recycle(void);
-+extern int ipsec_SArefSubTable_alloc(unsigned table);
-+extern int ipsec_saref_freelist_init(void);
-+extern int ipsec_sadb_init(void);
-+extern struct ipsec_sa *ipsec_sa_alloc(int*error); /* pass in error var by pointer */
-+extern IPsecSAref_t ipsec_SAref_alloc(int*erorr); /* pass in error var by pointer */
-+extern int ipsec_sa_free(struct ipsec_sa* ips);
-+extern int ipsec_sa_put(struct ipsec_sa *ips);
-+extern int ipsec_sa_add(struct ipsec_sa *ips);
-+extern int ipsec_sa_del(struct ipsec_sa *ips);
-+extern int ipsec_sa_delchain(struct ipsec_sa *ips);
-+extern int ipsec_sadb_cleanup(__u8 proto);
-+extern int ipsec_sadb_free(void);
-+extern int ipsec_sa_wipe(struct ipsec_sa *ips);
-+#endif /* __KERNEL__ */
-+
-+enum ipsec_direction {
-+ ipsec_incoming = 1,
-+ ipsec_outgoing = 2
-+};
-+
-+#define _IPSEC_SA_H_
-+#endif /* _IPSEC_SA_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.19 2004/04/05 19:55:06 mcr
-+ * Moved from linux/include/freeswan/ipsec_sa.h,v
-+ *
-+ * Revision 1.18 2004/04/05 19:41:05 mcr
-+ * merged alg-branch code.
-+ *
-+ * Revision 1.17.2.1 2003/12/22 15:25:52 jjo
-+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.17 2003/12/10 01:20:06 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.16 2003/10/31 02:27:05 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.15.4.1 2003/10/29 01:10:19 mcr
-+ * elimited "struct sa_id"
-+ *
-+ * Revision 1.15 2003/05/11 00:53:09 mcr
-+ * IPsecSAref_t and macros were moved to freeswan.h.
-+ *
-+ * Revision 1.14 2003/02/12 19:31:55 rgb
-+ * Fixed bug in "file seen" machinery.
-+ * Updated copyright year.
-+ *
-+ * Revision 1.13 2003/01/30 02:31:52 rgb
-+ *
-+ * Re-wrote comments describing SAref system for accuracy.
-+ * Rename SAref table macro names for clarity.
-+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
-+ * Transmit error code through to caller from callee for better diagnosis of problems.
-+ * Enclose all macro arguments in parens to avoid any possible obscrure bugs.
-+ *
-+ * Revision 1.12 2002/10/07 18:31:19 rgb
-+ * Change comment to reflect the flexible nature of the main and sub-table widths.
-+ * Added a counter for the number of unused entries in each subtable.
-+ * Further break up host field type macro to host field.
-+ * Move field width sanity checks to ipsec_sa.c
-+ * Define a mask for an entire saref.
-+ *
-+ * Revision 1.11 2002/09/20 15:40:33 rgb
-+ * Re-write most of the SAref macros and types to eliminate any pointer references to Entrys.
-+ * Fixed SAref/nfmark macros.
-+ * Rework saref freeslist.
-+ * Place all ipsec sadb globals into one struct.
-+ * Restrict some bits to kernel context for use to klips utils.
-+ *
-+ * Revision 1.10 2002/09/20 05:00:34 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.9 2002/09/17 17:19:29 mcr
-+ * make it compile even if there is no netfilter - we lost
-+ * functionality, but it works, especially on 2.2.
-+ *
-+ * Revision 1.8 2002/07/28 22:59:53 mcr
-+ * clarified/expanded one comment.
-+ *
-+ * Revision 1.7 2002/07/26 08:48:31 rgb
-+ * Added SA ref table code.
-+ *
-+ * Revision 1.6 2002/05/31 17:27:48 rgb
-+ * Comment fix.
-+ *
-+ * Revision 1.5 2002/05/27 18:55:03 rgb
-+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
-+ *
-+ * Revision 1.4 2002/05/23 07:13:36 rgb
-+ * Convert "usecount" to "refcount" to remove ambiguity.
-+ *
-+ * Revision 1.3 2002/04/24 07:36:47 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_sa.h,v
-+ *
-+ * Revision 1.2 2001/11/26 09:16:15 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:24:58 mcr
-+ * struct tdb -> struct ipsec_sa.
-+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
-+ * ipsec_xform.c removed. header file still contains useful things.
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_sha1.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,79 @@
-+/*
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * Here is the original comment from the distribution:
-+
-+SHA-1 in C
-+By Steve Reid <steve@edmweb.com>
-+100% Public Domain
-+
-+ * Adapted for use by the IPSEC code by John Ioannidis
-+ */
-+
-+
-+#ifndef _IPSEC_SHA1_H_
-+#define _IPSEC_SHA1_H_
-+
-+typedef struct
-+{
-+ __u32 state[5];
-+ __u32 count[2];
-+ __u8 buffer[64];
-+} SHA1_CTX;
-+
-+void SHA1Transform(__u32 state[5], __u8 buffer[64]);
-+void SHA1Init(void *context);
-+void SHA1Update(void *context, unsigned char *data, __u32 len);
-+void SHA1Final(unsigned char digest[20], void *context);
-+
-+
-+#endif /* _IPSEC_SHA1_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.8 2004/04/05 19:55:07 mcr
-+ * Moved from linux/include/freeswan/ipsec_sha1.h,v
-+ *
-+ * Revision 1.7 2002/09/10 01:45:09 mcr
-+ * changed type of MD5_CTX and SHA1_CTX to void * so that
-+ * the function prototypes would match, and could be placed
-+ * into a pointer to a function.
-+ *
-+ * Revision 1.6 2002/04/24 07:36:47 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_sha1.h,v
-+ *
-+ * Revision 1.5 1999/12/13 13:59:13 rgb
-+ * Quick fix to argument size to Update bugs.
-+ *
-+ * Revision 1.4 1999/12/07 18:16:23 rgb
-+ * Fixed comments at end of #endif lines.
-+ *
-+ * Revision 1.3 1999/04/06 04:54:27 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.2 1998/11/30 13:22:54 rgb
-+ * Rationalised all the klips kernel file headers. They are much shorter
-+ * now and won't conflict under RH5.2.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:50 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.2 1998/04/23 20:54:05 rgb
-+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
-+ * verified.
-+ *
-+ * Revision 1.1 1998/04/09 03:04:21 henry
-+ * sources moved up from linux/net/ipsec
-+ * these two include files modified not to include others except in kernel
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * New transform
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_stats.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,75 @@
-+/*
-+ * @(#) definition of ipsec_stats structure
-+ *
-+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ * and Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ */
-+
-+/*
-+ * This file describes the errors/statistics that FreeSWAN collects.
-+ */
-+
-+#ifndef _IPSEC_STATS_H_
-+
-+struct ipsec_stats {
-+ __u32 ips_alg_errs; /* number of algorithm errors */
-+ __u32 ips_auth_errs; /* # of authentication errors */
-+ __u32 ips_encsize_errs; /* # of encryption size errors*/
-+ __u32 ips_encpad_errs; /* # of encryption pad errors*/
-+ __u32 ips_replaywin_errs; /* # of pkt sequence errors */
-+};
-+
-+extern int ipsec_snprintf(char * buf, ssize_t size, const char *fmt, ...);
-+
-+#define _IPSEC_STATS_H_
-+#endif /* _IPSEC_STATS_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.6 2004/04/05 19:55:07 mcr
-+ * Moved from linux/include/freeswan/ipsec_stats.h,v
-+ *
-+ * Revision 1.5 2004/04/05 19:41:05 mcr
-+ * merged alg-branch code.
-+ *
-+ * Revision 1.4 2004/03/28 20:27:19 paul
-+ * Included tested and confirmed fixes mcr made and dhr verified for
-+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
-+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
-+ * dhr. (thanks dhr!)
-+ *
-+ * Revision 1.4 2004/03/24 01:58:31 mcr
-+ * sprintf->snprintf for formatting into proc buffer.
-+ *
-+ * Revision 1.3.34.1 2004/04/05 04:30:46 mcr
-+ * patches for alg-branch to compile/work with 2.x openswan
-+ *
-+ * Revision 1.3 2002/04/24 07:36:47 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_stats.h,v
-+ *
-+ * Revision 1.2 2001/11/26 09:16:16 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:27:00 mcr
-+ * statistics moved to seperate structure.
-+ *
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_tunnel.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,265 @@
-+/*
-+ * IPSEC tunneling code
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+
-+#ifdef NET_21
-+# define DEV_QUEUE_XMIT(skb, device, pri) {\
-+ skb->dev = device; \
-+ neigh_compat_output(skb); \
-+ /* skb->dst->output(skb); */ \
-+ }
-+# define ICMP_SEND(skb_in, type, code, info, dev) \
-+ icmp_send(skb_in, type, code, htonl(info))
-+# define IP_SEND(skb, dev) \
-+ ip_send(skb);
-+#else /* NET_21 */
-+# define DEV_QUEUE_XMIT(skb, device, pri) {\
-+ dev_queue_xmit(skb, device, pri); \
-+ }
-+# define ICMP_SEND(skb_in, type, code, info, dev) \
-+ icmp_send(skb_in, type, code, info, dev)
-+# define IP_SEND(skb, dev) \
-+ if(ntohs(iph->tot_len) > physmtu) { \
-+ ip_fragment(NULL, skb, dev, 0); \
-+ ipsec_kfree_skb(skb); \
-+ } else { \
-+ dev_queue_xmit(skb, dev, SOPRI_NORMAL); \
-+ }
-+#endif /* NET_21 */
-+
-+
-+/*
-+ * Heavily based on drivers/net/new_tunnel.c. Lots
-+ * of ideas also taken from the 2.1.x version of drivers/net/shaper.c
-+ */
-+
-+struct ipsectunnelconf
-+{
-+ __u32 cf_cmd;
-+ union
-+ {
-+ char cfu_name[12];
-+ } cf_u;
-+#define cf_name cf_u.cfu_name
-+};
-+
-+#define IPSEC_SET_DEV (SIOCDEVPRIVATE)
-+#define IPSEC_DEL_DEV (SIOCDEVPRIVATE + 1)
-+#define IPSEC_CLR_DEV (SIOCDEVPRIVATE + 2)
-+
-+#ifdef __KERNEL__
-+#include <linux/version.h>
-+#ifndef KERNEL_VERSION
-+# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
-+#endif
-+struct ipsecpriv
-+{
-+ struct sk_buff_head sendq;
-+ struct device *dev;
-+ struct wait_queue *wait_queue;
-+ char locked;
-+ int (*hard_start_xmit) (struct sk_buff *skb,
-+ struct device *dev);
-+ int (*hard_header) (struct sk_buff *skb,
-+ struct device *dev,
-+ unsigned short type,
-+ void *daddr,
-+ void *saddr,
-+ unsigned len);
-+#ifdef NET_21
-+ int (*rebuild_header)(struct sk_buff *skb);
-+#else /* NET_21 */
-+ int (*rebuild_header)(void *buff, struct device *dev,
-+ unsigned long raddr, struct sk_buff *skb);
-+#endif /* NET_21 */
-+ int (*set_mac_address)(struct device *dev, void *addr);
-+#ifndef NET_21
-+ void (*header_cache_bind)(struct hh_cache **hhp, struct device *dev,
-+ unsigned short htype, __u32 daddr);
-+#endif /* !NET_21 */
-+ void (*header_cache_update)(struct hh_cache *hh, struct device *dev, unsigned char * haddr);
-+ struct net_device_stats *(*get_stats)(struct device *dev);
-+ struct net_device_stats mystats;
-+ int mtu; /* What is the desired MTU? */
-+};
-+
-+extern char ipsec_tunnel_c_version[];
-+
-+extern struct device *ipsecdevices[IPSEC_NUM_IF];
-+
-+int ipsec_tunnel_init_devices(void);
-+
-+/* void */ int ipsec_tunnel_cleanup_devices(void);
-+
-+extern /* void */ int ipsec_init(void);
-+
-+extern int ipsec_tunnel_start_xmit(struct sk_buff *skb, struct device *dev);
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int debug_tunnel;
-+extern int sysctl_ipsec_debug_verbose;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#endif /* __KERNEL__ */
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+#define DB_TN_INIT 0x0001
-+#define DB_TN_PROCFS 0x0002
-+#define DB_TN_XMIT 0x0010
-+#define DB_TN_OHDR 0x0020
-+#define DB_TN_CROUT 0x0040
-+#define DB_TN_OXFS 0x0080
-+#define DB_TN_REVEC 0x0100
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.29 2004/04/05 19:55:07 mcr
-+ * Moved from linux/include/freeswan/ipsec_tunnel.h,v
-+ *
-+ * Revision 1.28 2003/06/24 20:22:32 mcr
-+ * added new global: ipsecdevices[] so that we can keep track of
-+ * the ipsecX devices. They will be referenced with dev_hold(),
-+ * so 2.2 may need this as well.
-+ *
-+ * Revision 1.27 2003/04/03 17:38:09 rgb
-+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
-+ *
-+ * Revision 1.26 2003/02/12 19:32:20 rgb
-+ * Updated copyright year.
-+ *
-+ * Revision 1.25 2002/05/27 18:56:07 rgb
-+ * Convert to dynamic ipsec device allocation.
-+ *
-+ * Revision 1.24 2002/04/24 07:36:48 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_tunnel.h,v
-+ *
-+ * Revision 1.23 2001/11/06 19:50:44 rgb
-+ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
-+ * use also by pfkey_v2_parser.c
-+ *
-+ * Revision 1.22 2001/09/15 16:24:05 rgb
-+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
-+ *
-+ * Revision 1.21 2001/06/14 19:35:10 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.20 2000/09/15 11:37:02 rgb
-+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
-+ * IPCOMP zlib deflate code.
-+ *
-+ * Revision 1.19 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.18 2000/07/28 13:50:54 rgb
-+ * Changed enet_statistics to net_device_stats and added back compatibility
-+ * for pre-2.1.19.
-+ *
-+ * Revision 1.17 1999/11/19 01:12:15 rgb
-+ * Purge unneeded proc_info prototypes, now that static linking uses
-+ * dynamic proc_info registration.
-+ *
-+ * Revision 1.16 1999/11/18 18:51:00 rgb
-+ * Changed all device registrations for static linking to
-+ * dynamic to reduce the number and size of patches.
-+ *
-+ * Revision 1.15 1999/11/18 04:14:21 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
-+ * Added Marc Boucher's 2.3.25 proc patches.
-+ *
-+ * Revision 1.14 1999/05/25 02:50:10 rgb
-+ * Fix kernel version macros for 2.0.x static linking.
-+ *
-+ * Revision 1.13 1999/05/25 02:41:06 rgb
-+ * Add ipsec_klipsdebug support for static linking.
-+ *
-+ * Revision 1.12 1999/05/05 22:02:32 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.11 1999/04/29 15:19:50 rgb
-+ * Add return values to init and cleanup functions.
-+ *
-+ * Revision 1.10 1999/04/16 16:02:39 rgb
-+ * Bump up macro to 4 ipsec I/Fs.
-+ *
-+ * Revision 1.9 1999/04/15 15:37:25 rgb
-+ * Forward check changes from POST1_00 branch.
-+ *
-+ * Revision 1.5.2.1 1999/04/02 04:26:14 rgb
-+ * Backcheck from HEAD, pre1.0.
-+ *
-+ * Revision 1.8 1999/04/11 00:29:01 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.7 1999/04/06 04:54:28 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.6 1999/03/31 05:44:48 rgb
-+ * Keep PMTU reduction private.
-+ *
-+ * Revision 1.5 1999/02/10 22:31:20 rgb
-+ * Change rebuild_header member to reflect generality of link layer.
-+ *
-+ * Revision 1.4 1998/12/01 13:22:04 rgb
-+ * Added support for debug printing of version info.
-+ *
-+ * Revision 1.3 1998/07/29 20:42:46 rgb
-+ * Add a macro for clearing all tunnel devices.
-+ * Rearrange structures and declarations for sharing with userspace.
-+ *
-+ * Revision 1.2 1998/06/25 20:01:45 rgb
-+ * Make prototypes available for ipsec_init and ipsec proc_dir_entries
-+ * for static linking.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:50 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.3 1998/05/18 21:51:50 rgb
-+ * Added macros for num of I/F's and a procfs debug switch.
-+ *
-+ * Revision 1.2 1998/04/21 21:29:09 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:13 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:05 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.5 1997/06/03 04:24:48 ji
-+ * Added transport mode.
-+ * Changed the way routing is done.
-+ * Lots of bug fixes.
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * No changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:39:04 ji
-+ * Minor cleanups.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_xform.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,254 @@
-+/*
-+ * Definitions relevant to IPSEC transformations
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ * COpyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifndef _IPSEC_XFORM_H_
-+
-+#include <openswan.h>
-+
-+#define XF_NONE 0 /* No transform set */
-+#define XF_IP4 1 /* IPv4 inside IPv4 */
-+#define XF_AHMD5 2 /* AH MD5 */
-+#define XF_AHSHA 3 /* AH SHA */
-+#define XF_ESP3DES 5 /* ESP DES3-CBC */
-+#define XF_AHHMACMD5 6 /* AH-HMAC-MD5 with opt replay prot */
-+#define XF_AHHMACSHA1 7 /* AH-HMAC-SHA1 with opt replay prot */
-+#define XF_ESP3DESMD5 9 /* triple DES, HMAC-MD-5, 128-bits of authentication */
-+#define XF_ESP3DESMD596 10 /* triple DES, HMAC-MD-5, 96-bits of authentication */
-+#define XF_ESPNULLMD596 12 /* NULL, HMAC-MD-5 with 96-bits of authentication */
-+#define XF_ESPNULLSHA196 13 /* NULL, HMAC-SHA-1 with 96-bits of authentication */
-+#define XF_ESP3DESSHA196 14 /* triple DES, HMAC-SHA-1, 96-bits of authentication */
-+#define XF_IP6 15 /* IPv6 inside IPv6 */
-+#define XF_COMPDEFLATE 16 /* IPCOMP deflate */
-+
-+#define XF_CLR 126 /* Clear SA table */
-+#define XF_DEL 127 /* Delete SA */
-+
-+/* IPsec AH transform values
-+ * RFC 2407
-+ * draft-ietf-ipsec-doi-tc-mib-02.txt
-+ */
-+
-+#define AH_NONE 0
-+#define AH_MD5 2
-+#define AH_SHA 3
-+/* draft-ietf-ipsec-ciph-aes-cbc-03.txt */
-+#define AH_SHA2_256 5
-+#define AH_SHA2_384 6
-+#define AH_SHA2_512 7
-+#define AH_RIPEMD 8
-+#define AH_MAX 15
-+
-+/* IPsec ESP transform values */
-+
-+#define ESP_NONE 0
-+#define ESP_DES 2
-+#define ESP_3DES 3
-+#define ESP_RC5 4
-+#define ESP_IDEA 5
-+#define ESP_CAST 6
-+#define ESP_BLOWFISH 7
-+#define ESP_3IDEA 8
-+#define ESP_RC4 10
-+#define ESP_NULL 11
-+#define ESP_AES 12
-+
-+/* as draft-ietf-ipsec-ciph-aes-cbc-02.txt */
-+#define ESP_MARS 249
-+#define ESP_RC6 250
-+#define ESP_SERPENT 252
-+#define ESP_TWOFISH 253
-+
-+/* IPCOMP transform values */
-+
-+#define IPCOMP_NONE 0
-+#define IPCOMP_OUI 1
-+#define IPCOMP_DEFLAT 2
-+#define IPCOMP_LZS 3
-+#define IPCOMP_V42BIS 4
-+
-+#define XFT_AUTH 0x0001
-+#define XFT_CONF 0x0100
-+
-+/* available if CONFIG_IPSEC_DEBUG is defined */
-+#define DB_XF_INIT 0x0001
-+
-+#define PROTO2TXT(x) \
-+ (x) == IPPROTO_AH ? "AH" : \
-+ (x) == IPPROTO_ESP ? "ESP" : \
-+ (x) == IPPROTO_IPIP ? "IPIP" : \
-+ (x) == IPPROTO_COMP ? "COMP" : \
-+ "UNKNOWN_proto"
-+static inline const char *enc_name_id (unsigned id) {
-+ static char buf[16];
-+ snprintf(buf, sizeof(buf), "_ID%d", id);
-+ return buf;
-+}
-+static inline const char *auth_name_id (unsigned id) {
-+ static char buf[16];
-+ snprintf(buf, sizeof(buf), "_ID%d", id);
-+ return buf;
-+}
-+#define IPS_XFORM_NAME(x) \
-+ PROTO2TXT((x)->ips_said.proto), \
-+ (x)->ips_said.proto == IPPROTO_COMP ? \
-+ ((x)->ips_encalg == SADB_X_CALG_DEFLATE ? \
-+ "_DEFLATE" : "_UNKNOWN_comp") : \
-+ (x)->ips_encalg == ESP_NONE ? "" : \
-+ (x)->ips_encalg == ESP_3DES ? "_3DES" : \
-+ (x)->ips_encalg == ESP_AES ? "_AES" : \
-+ (x)->ips_encalg == ESP_SERPENT ? "_SERPENT" : \
-+ (x)->ips_encalg == ESP_TWOFISH ? "_TWOFISH" : \
-+ enc_name_id(x->ips_encalg)/* "_UNKNOWN_encr" */, \
-+ (x)->ips_authalg == AH_NONE ? "" : \
-+ (x)->ips_authalg == AH_MD5 ? "_HMAC_MD5" : \
-+ (x)->ips_authalg == AH_SHA ? "_HMAC_SHA1" : \
-+ (x)->ips_authalg == AH_SHA2_256 ? "_HMAC_SHA2_256" : \
-+ (x)->ips_authalg == AH_SHA2_384 ? "_HMAC_SHA2_384" : \
-+ (x)->ips_authalg == AH_SHA2_512 ? "_HMAC_SHA2_512" : \
-+ auth_name_id(x->ips_authalg) /* "_UNKNOWN_auth" */ \
-+
-+#ifdef __KERNEL__
-+struct ipsec_rcv_state;
-+struct ipsec_xmit_state;
-+
-+struct xform_functions {
-+ enum ipsec_rcv_value (*rcv_checks)(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb);
-+ enum ipsec_rcv_value (*rcv_decrypt)(struct ipsec_rcv_state *irs);
-+
-+ enum ipsec_rcv_value (*rcv_setup_auth)(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb,
-+ __u32 *replay,
-+ unsigned char **authenticator);
-+ enum ipsec_rcv_value (*rcv_calc_auth)(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb);
-+
-+ enum ipsec_xmit_value (*xmit_setup)(struct ipsec_xmit_state *ixs);
-+ enum ipsec_xmit_value (*xmit_encrypt)(struct ipsec_xmit_state *ixs);
-+
-+ enum ipsec_xmit_value (*xmit_setup_auth)(struct ipsec_xmit_state *ixs,
-+ struct sk_buff *skb,
-+ __u32 *replay,
-+ unsigned char **authenticator);
-+ enum ipsec_xmit_value (*xmit_calc_auth)(struct ipsec_xmit_state *ixs,
-+ struct sk_buff *skb);
-+ int xmit_headroom;
-+ int xmit_needtailroom;
-+};
-+
-+#endif /* __KERNEL__ */
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern void ipsec_dmp(char *s, caddr_t bb, int len);
-+#else /* CONFIG_IPSEC_DEBUG */
-+#define ipsec_dmp(_x, _y, _z)
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+
-+#define _IPSEC_XFORM_H_
-+#endif /* _IPSEC_XFORM_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.40 2004/04/06 02:49:08 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.39 2004/04/05 19:55:07 mcr
-+ * Moved from linux/include/freeswan/ipsec_xform.h,v
-+ *
-+ * Revision 1.38 2004/04/05 19:41:05 mcr
-+ * merged alg-branch code.
-+ *
-+ * Revision 1.37 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.36.34.1 2003/12/22 15:25:52 jjo
-+ * Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.36 2002/04/24 07:36:48 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_xform.h,v
-+ *
-+ * Revision 1.35 2001/11/26 09:23:51 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.33.2.1 2001/09/25 02:24:58 mcr
-+ * struct tdb -> struct ipsec_sa.
-+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
-+ * ipsec_xform.c removed. header file still contains useful things.
-+ *
-+ * Revision 1.34 2001/11/06 19:47:17 rgb
-+ * Changed lifetime_packets to uint32 from uint64.
-+ *
-+ * Revision 1.33 2001/09/08 21:13:34 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.32 2001/07/06 07:40:01 rgb
-+ * Reformatted for readability.
-+ * Added inbound policy checking fields for use with IPIP SAs.
-+ *
-+ * Revision 1.31 2001/06/14 19:35:11 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.30 2001/05/30 08:14:03 rgb
-+ * Removed vestiges of esp-null transforms.
-+ *
-+ * Revision 1.29 2001/01/30 23:42:47 rgb
-+ * Allow pfkey msgs from pid other than user context required for ACQUIRE
-+ * and subsequent ADD or UDATE.
-+ *
-+ * Revision 1.28 2000/11/06 04:30:40 rgb
-+ * Add Svenning's adaptive content compression.
-+ *
-+ * Revision 1.27 2000/09/19 00:38:25 rgb
-+ * Fixed algorithm name bugs introduced for ipcomp.
-+ *
-+ * Revision 1.26 2000/09/17 21:36:48 rgb
-+ * Added proto2txt macro.
-+ *
-+ * Revision 1.25 2000/09/17 18:56:47 rgb
-+ * Added IPCOMP support.
-+ *
-+ * Revision 1.24 2000/09/12 19:34:12 rgb
-+ * Defined XF_IP6 from Gerhard for ipv6 tunnel support.
-+ *
-+ * Revision 1.23 2000/09/12 03:23:14 rgb
-+ * Cleaned out now unused tdb_xform and tdb_xdata members of struct tdb.
-+ *
-+ * Revision 1.22 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.21 2000/09/01 18:32:43 rgb
-+ * Added (disabled) sensitivity members to tdb struct.
-+ *
-+ * Revision 1.20 2000/08/30 05:31:01 rgb
-+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
-+ * Kill remainder of tdb_xform, tdb_xdata, xformsw.
-+ *
-+ * Revision 1.19 2000/08/01 14:51:52 rgb
-+ * Removed _all_ remaining traces of DES.
-+ *
-+ * Revision 1.18 2000/01/21 06:17:45 rgb
-+ * Tidied up spacing.
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_xmit.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,176 @@
-+/*
-+ * IPSEC tunneling code
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#include "openswan/ipsec_sa.h"
-+
-+enum ipsec_xmit_value
-+{
-+ IPSEC_XMIT_STOLEN=2,
-+ IPSEC_XMIT_PASS=1,
-+ IPSEC_XMIT_OK=0,
-+ IPSEC_XMIT_ERRMEMALLOC=-1,
-+ IPSEC_XMIT_ESP_BADALG=-2,
-+ IPSEC_XMIT_BADPROTO=-3,
-+ IPSEC_XMIT_ESP_PUSHPULLERR=-4,
-+ IPSEC_XMIT_BADLEN=-5,
-+ IPSEC_XMIT_AH_BADALG=-6,
-+ IPSEC_XMIT_SAIDNOTFOUND=-7,
-+ IPSEC_XMIT_SAIDNOTLIVE=-8,
-+ IPSEC_XMIT_REPLAYROLLED=-9,
-+ IPSEC_XMIT_LIFETIMEFAILED=-10,
-+ IPSEC_XMIT_CANNOTFRAG=-11,
-+ IPSEC_XMIT_MSSERR=-12,
-+ IPSEC_XMIT_ERRSKBALLOC=-13,
-+ IPSEC_XMIT_ENCAPFAIL=-14,
-+ IPSEC_XMIT_NODEV=-15,
-+ IPSEC_XMIT_NOPRIVDEV=-16,
-+ IPSEC_XMIT_NOPHYSDEV=-17,
-+ IPSEC_XMIT_NOSKB=-18,
-+ IPSEC_XMIT_NOIPV6=-19,
-+ IPSEC_XMIT_NOIPOPTIONS=-20,
-+ IPSEC_XMIT_TTLEXPIRED=-21,
-+ IPSEC_XMIT_BADHHLEN=-22,
-+ IPSEC_XMIT_PUSHPULLERR=-23,
-+ IPSEC_XMIT_ROUTEERR=-24,
-+ IPSEC_XMIT_RECURSDETECT=-25,
-+ IPSEC_XMIT_IPSENDFAILURE=-26,
-+ IPSEC_XMIT_ESPUDP=-27,
-+ IPSEC_XMIT_ESPUDP_BADTYPE=-28,
-+};
-+
-+struct ipsec_xmit_state
-+{
-+ struct sk_buff *skb; /* working skb pointer */
-+ struct device *dev; /* working dev pointer */
-+ struct ipsecpriv *prv; /* Our device' private space */
-+ struct sk_buff *oskb; /* Original skb pointer */
-+ struct net_device_stats *stats; /* This device's statistics */
-+ struct iphdr *iph; /* Our new IP header */
-+ __u32 newdst; /* The other SG's IP address */
-+ __u32 orgdst; /* Original IP destination address */
-+ __u32 orgedst; /* 1st SG's IP address */
-+ __u32 newsrc; /* The new source SG's IP address */
-+ __u32 orgsrc; /* Original IP source address */
-+ __u32 innersrc; /* Innermost IP source address */
-+ int iphlen; /* IP header length */
-+ int pyldsz; /* upper protocol payload size */
-+ int headroom;
-+ int tailroom;
-+ int authlen;
-+ int max_headroom; /* The extra header space needed */
-+ int max_tailroom; /* The extra stuffing needed */
-+ int ll_headroom; /* The extra link layer hard_header space needed */
-+ int tot_headroom; /* The total header space needed */
-+ int tot_tailroom; /* The totalstuffing needed */
-+ __u8 *saved_header; /* saved copy of the hard header */
-+ unsigned short sport, dport;
-+
-+ struct sockaddr_encap matcher; /* eroute search key */
-+ struct eroute *eroute;
-+ struct ipsec_sa *ipsp, *ipsq; /* ipsec_sa pointers */
-+ char sa_txt[SATOT_BUF];
-+ size_t sa_len;
-+ int hard_header_stripped; /* has the hard header been removed yet? */
-+ int hard_header_len;
-+ struct device *physdev;
-+/* struct device *virtdev; */
-+ short physmtu;
-+ short mtudiff;
-+#ifdef NET_21
-+ struct rtable *route;
-+#endif /* NET_21 */
-+ ip_said outgoing_said;
-+#ifdef NET_21
-+ int pass;
-+#endif /* NET_21 */
-+ int error;
-+ uint32_t eroute_pid;
-+ struct ipsec_sa ips;
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ uint8_t natt_type;
-+ uint8_t natt_head;
-+ uint16_t natt_sport;
-+ uint16_t natt_dport;
-+#endif
-+};
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs);
-+
-+extern void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er);
-+
-+
-+extern int ipsec_xmit_trap_count;
-+extern int ipsec_xmit_trap_sendcount;
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int debug_tunnel;
-+extern int sysctl_ipsec_debug_verbose;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#define debug_xmit debug_tunnel
-+
-+#define ipsec_xmit_dmp(_x,_y, _z) if (debug_xmit && sysctl_ipsec_debug_verbose) ipsec_dmp(_x,_y,_z)
-+
-+extern int sysctl_ipsec_icmp;
-+extern int sysctl_ipsec_tos;
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.9 2004/04/06 02:49:08 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.8 2004/04/05 19:55:07 mcr
-+ * Moved from linux/include/freeswan/ipsec_xmit.h,v
-+ *
-+ * Revision 1.7 2004/02/03 03:11:40 mcr
-+ * new xmit type if the UDP encapsulation is wrong.
-+ *
-+ * Revision 1.6 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.5 2003/12/10 01:20:06 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.4 2003/12/06 16:37:04 mcr
-+ * 1.4.7a X.509 patch applied.
-+ *
-+ * Revision 1.3 2003/10/31 02:27:05 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.2.4.2 2003/10/29 01:10:19 mcr
-+ * elimited "struct sa_id"
-+ *
-+ * Revision 1.2.4.1 2003/09/21 13:59:38 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.2 2003/06/20 01:42:13 mcr
-+ * added counters to measure how many ACQUIREs we send to pluto,
-+ * and how many are successfully sent.
-+ *
-+ * Revision 1.1 2003/02/12 19:31:03 rgb
-+ * Refactored from ipsec_tunnel.c
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/passert.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,64 @@
-+/*
-+ * sanitize a string into a printable format.
-+ *
-+ * Copyright (C) 1998-2002 D. Hugh Redelmeier.
-+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#include "openswan.h"
-+
-+/* our versions of assert: log result */
-+
-+#ifdef DEBUG
-+
-+extern void passert_fail(const char *pred_str
-+ , const char *file_str, unsigned long line_no) NEVER_RETURNS;
-+
-+extern void pexpect_log(const char *pred_str
-+ , const char *file_str, unsigned long line_no);
-+
-+# define impossible() passert_fail("impossible", __FILE__, __LINE__)
-+
-+extern void switch_fail(int n
-+ , const char *file_str, unsigned long line_no) NEVER_RETURNS;
-+
-+# define bad_case(n) switch_fail((int) n, __FILE__, __LINE__)
-+
-+# define passert(pred) { \
-+ if (!(pred)) \
-+ passert_fail(#pred, __FILE__, __LINE__); \
-+ }
-+
-+# define pexpect(pred) { \
-+ if (!(pred)) \
-+ pexpect_log(#pred, __FILE__, __LINE__); \
-+ }
-+
-+/* assert that an err_t is NULL; evaluate exactly once */
-+# define happy(x) { \
-+ err_t ugh = x; \
-+ if (ugh != NULL) \
-+ passert_fail(ugh, __FILE__, __LINE__); \
-+ }
-+
-+#else /*!DEBUG*/
-+
-+# define impossible() abort()
-+# define bad_case(n) abort()
-+# define passert(pred) { } /* do nothing */
-+# define happy(x) { (void) x; } /* evaluate non-judgementally */
-+
-+#endif /*!DEBUG*/
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/pfkey_debug.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,54 @@
-+/*
-+ * sanitize a string into a printable format.
-+ *
-+ * Copyright (C) 1998-2002 D. Hugh Redelmeier.
-+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifndef _FREESWAN_PFKEY_DEBUG_H
-+#define _FREESWAN_PFKEY_DEBUG_H
-+
-+#ifdef __KERNEL__
-+
-+/* note, kernel version ignores pfkey levels */
-+# define DEBUGGING(level,args...) \
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:" args)
-+
-+# define ERROR(args...) printk(KERN_ERR "klips:" args)
-+
-+#else
-+
-+extern unsigned int pfkey_lib_debug;
-+
-+extern void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
-+extern void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
-+
-+#define DEBUGGING(level,args...) if(pfkey_lib_debug & level) { \
-+ if(pfkey_debug_func != NULL) { \
-+ (*pfkey_debug_func)("pfkey_lib_debug:" args); \
-+ } else { \
-+ printf("pfkey_lib_debug:" args); \
-+ } }
-+
-+#define ERROR(args...) if(pfkey_error_func != NULL) { \
-+ (*pfkey_error_func)("pfkey_lib_debug:" args); \
-+ }
-+
-+# define MALLOC(size) malloc(size)
-+# define FREE(obj) free(obj)
-+
-+#endif
-+
-+#endif
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/radij.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,280 @@
-+/*
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * This file is defived from ${SRC}/sys/net/radix.h of BSD 4.4lite
-+ *
-+ * Variable and procedure names have been modified so that they don't
-+ * conflict with the original BSD code, as a small number of modifications
-+ * have been introduced and we may want to reuse this code in BSD.
-+ *
-+ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
-+ * chi or a German ch sound (as `doch', not as in `milch'), or even a
-+ * spanish j as in Juan. It is not as far back in the throat like
-+ * the corresponding Hebrew sound, nor is it a soft breath like the English h.
-+ * It has nothing to do with the Dutch ij sound.
-+ *
-+ * Here is the appropriate copyright notice:
-+ */
-+
-+/*
-+ * Copyright (c) 1988, 1989, 1993
-+ * The Regents of the University of California. All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * This product includes software developed by the University of
-+ * California, Berkeley and its contributors.
-+ * 4. Neither the name of the University nor the names of its contributors
-+ * may be used to endorse or promote products derived from this software
-+ * without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * @(#)radix.h 8.1 (Berkeley) 6/10/93
-+ */
-+
-+#ifndef _RADIJ_H_
-+#define _RADIJ_H_
-+
-+/*
-+#define RJ_DEBUG
-+*/
-+
-+#ifdef __KERNEL__
-+
-+#ifndef __P
-+#ifdef __STDC__
-+#define __P(x) x
-+#else
-+#define __P(x) ()
-+#endif
-+#endif
-+
-+/*
-+ * Radix search tree node layout.
-+ */
-+
-+struct radij_node
-+{
-+ struct radij_mask *rj_mklist; /* list of masks contained in subtree */
-+ struct radij_node *rj_p; /* parent */
-+ short rj_b; /* bit offset; -1-index(netmask) */
-+ char rj_bmask; /* node: mask for bit test*/
-+ u_char rj_flags; /* enumerated next */
-+#define RJF_NORMAL 1 /* leaf contains normal route */
-+#define RJF_ROOT 2 /* leaf is root leaf for tree */
-+#define RJF_ACTIVE 4 /* This node is alive (for rtfree) */
-+ union {
-+ struct { /* leaf only data: */
-+ caddr_t rj_Key; /* object of search */
-+ caddr_t rj_Mask; /* netmask, if present */
-+ struct radij_node *rj_Dupedkey;
-+ } rj_leaf;
-+ struct { /* node only data: */
-+ int rj_Off; /* where to start compare */
-+ struct radij_node *rj_L;/* progeny */
-+ struct radij_node *rj_R;/* progeny */
-+ }rj_node;
-+ } rj_u;
-+#ifdef RJ_DEBUG
-+ int rj_info;
-+ struct radij_node *rj_twin;
-+ struct radij_node *rj_ybro;
-+#endif
-+};
-+
-+#define rj_dupedkey rj_u.rj_leaf.rj_Dupedkey
-+#define rj_key rj_u.rj_leaf.rj_Key
-+#define rj_mask rj_u.rj_leaf.rj_Mask
-+#define rj_off rj_u.rj_node.rj_Off
-+#define rj_l rj_u.rj_node.rj_L
-+#define rj_r rj_u.rj_node.rj_R
-+
-+/*
-+ * Annotations to tree concerning potential routes applying to subtrees.
-+ */
-+
-+extern struct radij_mask {
-+ short rm_b; /* bit offset; -1-index(netmask) */
-+ char rm_unused; /* cf. rj_bmask */
-+ u_char rm_flags; /* cf. rj_flags */
-+ struct radij_mask *rm_mklist; /* more masks to try */
-+ caddr_t rm_mask; /* the mask */
-+ int rm_refs; /* # of references to this struct */
-+} *rj_mkfreelist;
-+
-+#define MKGet(m) {\
-+ if (rj_mkfreelist) {\
-+ m = rj_mkfreelist; \
-+ rj_mkfreelist = (m)->rm_mklist; \
-+ } else \
-+ R_Malloc(m, struct radij_mask *, sizeof (*(m))); }\
-+
-+#define MKFree(m) { (m)->rm_mklist = rj_mkfreelist; rj_mkfreelist = (m);}
-+
-+struct radij_node_head {
-+ struct radij_node *rnh_treetop;
-+ int rnh_addrsize; /* permit, but not require fixed keys */
-+ int rnh_pktsize; /* permit, but not require fixed keys */
-+#if 0
-+ struct radij_node *(*rnh_addaddr) /* add based on sockaddr */
-+ __P((void *v, void *mask,
-+ struct radij_node_head *head, struct radij_node nodes[]));
-+#endif
-+ int (*rnh_addaddr) /* add based on sockaddr */
-+ __P((void *v, void *mask,
-+ struct radij_node_head *head, struct radij_node nodes[]));
-+ struct radij_node *(*rnh_addpkt) /* add based on packet hdr */
-+ __P((void *v, void *mask,
-+ struct radij_node_head *head, struct radij_node nodes[]));
-+#if 0
-+ struct radij_node *(*rnh_deladdr) /* remove based on sockaddr */
-+ __P((void *v, void *mask, struct radij_node_head *head));
-+#endif
-+ int (*rnh_deladdr) /* remove based on sockaddr */
-+ __P((void *v, void *mask, struct radij_node_head *head, struct radij_node **node));
-+ struct radij_node *(*rnh_delpkt) /* remove based on packet hdr */
-+ __P((void *v, void *mask, struct radij_node_head *head));
-+ struct radij_node *(*rnh_matchaddr) /* locate based on sockaddr */
-+ __P((void *v, struct radij_node_head *head));
-+ struct radij_node *(*rnh_matchpkt) /* locate based on packet hdr */
-+ __P((void *v, struct radij_node_head *head));
-+ int (*rnh_walktree) /* traverse tree */
-+ __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
-+ struct radij_node rnh_nodes[3]; /* empty tree for common case */
-+};
-+
-+
-+#define Bcmp(a, b, n) memcmp(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
-+#define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
-+#define Bzero(p, n) memset((caddr_t)(p), 0, (unsigned)(n))
-+#define R_Malloc(p, t, n) ((p = (t) kmalloc((size_t)(n), GFP_ATOMIC)), Bzero((p),(n)))
-+#define Free(p) kfree((caddr_t)p);
-+
-+void rj_init __P((void));
-+int rj_inithead __P((void **, int));
-+int rj_refines __P((void *, void *));
-+int rj_walktree __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
-+struct radij_node
-+ *rj_addmask __P((void *, int, int)) /* , rgb */ ;
-+int /* * */ rj_addroute __P((void *, void *, struct radij_node_head *,
-+ struct radij_node [2])) /* , rgb */ ;
-+int /* * */ rj_delete __P((void *, void *, struct radij_node_head *, struct radij_node **)) /* , rgb */ ;
-+struct radij_node /* rgb */
-+ *rj_insert __P((void *, struct radij_node_head *, int *,
-+ struct radij_node [2])),
-+ *rj_match __P((void *, struct radij_node_head *)),
-+ *rj_newpair __P((void *, int, struct radij_node[2])),
-+ *rj_search __P((void *, struct radij_node *)),
-+ *rj_search_m __P((void *, struct radij_node *, void *));
-+
-+void rj_deltree(struct radij_node_head *);
-+void rj_delnodes(struct radij_node *);
-+void rj_free_mkfreelist(void);
-+int radijcleartree(void);
-+int radijcleanup(void);
-+
-+extern struct radij_node_head *mask_rjhead;
-+extern int maj_keylen;
-+#endif /* __KERNEL__ */
-+
-+#endif /* _RADIJ_H_ */
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.13 2004/04/05 19:55:08 mcr
-+ * Moved from linux/include/freeswan/radij.h,v
-+ *
-+ * Revision 1.12 2002/04/24 07:36:48 mcr
-+ * Moved from ./klips/net/ipsec/radij.h,v
-+ *
-+ * Revision 1.11 2001/09/20 15:33:00 rgb
-+ * Min/max cleanup.
-+ *
-+ * Revision 1.10 1999/11/18 04:09:20 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ *
-+ * Revision 1.9 1999/05/05 22:02:33 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.8 1999/04/29 15:24:58 rgb
-+ * Add check for existence of macros min/max.
-+ *
-+ * Revision 1.7 1999/04/11 00:29:02 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.6 1999/04/06 04:54:29 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.5 1999/01/22 06:30:32 rgb
-+ * 64-bit clean-up.
-+ *
-+ * Revision 1.4 1998/11/30 13:22:55 rgb
-+ * Rationalised all the klips kernel file headers. They are much shorter
-+ * now and won't conflict under RH5.2.
-+ *
-+ * Revision 1.3 1998/10/25 02:43:27 rgb
-+ * Change return type on rj_addroute and rj_delete and add and argument
-+ * to the latter to be able to transmit more infomation about errors.
-+ *
-+ * Revision 1.2 1998/07/14 18:09:51 rgb
-+ * Add a routine to clear eroute table.
-+ * Added #ifdef __KERNEL__ directives to restrict scope of header.
-+ *
-+ * Revision 1.1 1998/06/18 21:30:22 henry
-+ * move sources from klips/src to klips/net/ipsec to keep stupid kernel
-+ * build scripts happier about symlinks
-+ *
-+ * Revision 1.4 1998/05/25 20:34:16 rgb
-+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
-+ *
-+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
-+ * add ipsec_rj_walker_delete.
-+ *
-+ * Recover memory for eroute table on unload of module.
-+ *
-+ * Revision 1.3 1998/04/22 16:51:37 rgb
-+ * Tidy up radij debug code from recent rash of modifications to debug code.
-+ *
-+ * Revision 1.2 1998/04/14 17:30:38 rgb
-+ * Fix up compiling errors for radij tree memory reclamation.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:16 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * No changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:44:45 ji
-+ * Release update only.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/pfkey.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,509 @@
-+/*
-+ * FreeS/WAN specific PF_KEY headers
-+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifndef __NET_IPSEC_PF_KEY_H
-+#define __NET_IPSEC_PF_KEY_H
-+#ifdef __KERNEL__
-+extern struct proto_ops pfkey_proto_ops;
-+typedef struct sock pfkey_sock;
-+extern int debug_pfkey;
-+
-+extern /* void */ int pfkey_init(void);
-+extern /* void */ int pfkey_cleanup(void);
-+
-+extern struct sock *pfkey_sock_list;
-+struct socket_list
-+{
-+ struct socket *socketp;
-+ struct socket_list *next;
-+};
-+extern int pfkey_list_insert_socket(struct socket*, struct socket_list**);
-+extern int pfkey_list_remove_socket(struct socket*, struct socket_list**);
-+extern struct socket_list *pfkey_open_sockets;
-+extern struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
-+
-+struct supported
-+{
-+ uint16_t supported_alg_exttype;
-+ uint8_t supported_alg_id;
-+ uint8_t supported_alg_ivlen;
-+ uint16_t supported_alg_minbits;
-+ uint16_t supported_alg_maxbits;
-+};
-+
-+extern struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
-+struct supported_list
-+{
-+ struct supported *supportedp;
-+ struct supported_list *next;
-+};
-+extern int pfkey_list_insert_supported(struct supported*, struct supported_list**);
-+extern int pfkey_list_remove_supported(struct supported*, struct supported_list**);
-+
-+struct sockaddr_key
-+{
-+ uint16_t key_family; /* PF_KEY */
-+ uint16_t key_pad; /* not used */
-+ uint32_t key_pid; /* process ID */
-+};
-+
-+struct pfkey_extracted_data
-+{
-+ struct ipsec_sa* ips;
-+ struct ipsec_sa* ips2;
-+ struct eroute *eroute;
-+};
-+
-+extern int
-+pfkey_alloc_eroute(struct eroute** eroute);
-+
-+extern int
-+pfkey_sa_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_lifetime_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_address_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_key_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_ident_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_sens_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_prop_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_supported_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_spirange_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_x_satype_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_x_debug_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int pfkey_upmsg(struct socket *, struct sadb_msg *);
-+extern int pfkey_expire(struct ipsec_sa *, int);
-+extern int pfkey_acquire(struct ipsec_sa *);
-+#else /* ! __KERNEL__ */
-+
-+extern void (*pfkey_debug_func)(const char *message, ...);
-+extern void (*pfkey_error_func)(const char *message, ...);
-+extern void pfkey_print(struct sadb_msg *msg, FILE *out);
-+
-+
-+#endif /* __KERNEL__ */
-+
-+extern uint8_t satype2proto(uint8_t satype);
-+extern uint8_t proto2satype(uint8_t proto);
-+extern char* satype2name(uint8_t satype);
-+extern char* proto2name(uint8_t proto);
-+
-+struct key_opt
-+{
-+ uint32_t key_pid; /* process ID */
-+ struct sock *sk;
-+};
-+
-+#define key_pid(sk) ((struct key_opt*)&((sk)->protinfo))->key_pid
-+
-+/* XXX-mcr this is not an alignment, this is because the count is in 64-bit
-+ * words.
-+ */
-+#define IPSEC_PFKEYv2_ALIGN (sizeof(uint64_t)/sizeof(uint8_t))
-+#define BITS_PER_OCTET 8
-+#define OCTETBITS 8
-+#define PFKEYBITS 64
-+#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */
-+#define ALIGN_N(x,y) (DIVUP(x,y) * y) /* align on y boundary */
-+
-+#define IPSEC_PFKEYv2_LEN(x) ((x) * IPSEC_PFKEYv2_ALIGN)
-+#define IPSEC_PFKEYv2_WORDS(x) ((x) / IPSEC_PFKEYv2_ALIGN)
-+
-+
-+#define PFKEYv2_MAX_MSGSIZE 4096
-+
-+/*
-+ * PF_KEYv2 permitted and required extensions in and out bitmaps
-+ */
-+struct pf_key_ext_parsers_def {
-+ int (*parser)(struct sadb_ext*);
-+ char *parser_name;
-+};
-+
-+
-+extern unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/];
-+#define EXT_BITS_IN 0
-+#define EXT_BITS_OUT 1
-+#define EXT_BITS_PERM 0
-+#define EXT_BITS_REQ 1
-+
-+extern void pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1]);
-+extern void pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1]);
-+extern void pfkey_msg_free(struct sadb_msg **pfkey_msg);
-+
-+extern int pfkey_msg_parse(struct sadb_msg *pfkey_msg,
-+ struct pf_key_ext_parsers_def *ext_parsers[],
-+ struct sadb_ext **extensions,
-+ int dir);
-+
-+extern int pfkey_register_reply(int satype, struct sadb_msg *sadb_msg);
-+
-+/*
-+ * PF_KEYv2 build function prototypes
-+ */
-+
-+int
-+pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
-+ uint8_t msg_type,
-+ uint8_t satype,
-+ uint8_t msg_errno,
-+ uint32_t seq,
-+ uint32_t pid);
-+
-+int
-+pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext,
-+ uint16_t exttype,
-+ uint32_t spi, /* in network order */
-+ uint8_t replay_window,
-+ uint8_t sa_state,
-+ uint8_t auth,
-+ uint8_t encrypt,
-+ uint32_t flags,
-+ uint32_t/*IPsecSAref_t*/ ref);
-+
-+int
-+pfkey_sa_build(struct sadb_ext ** pfkey_ext,
-+ uint16_t exttype,
-+ uint32_t spi, /* in network order */
-+ uint8_t replay_window,
-+ uint8_t sa_state,
-+ uint8_t auth,
-+ uint8_t encrypt,
-+ uint32_t flags);
-+
-+int
-+pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
-+ uint16_t exttype,
-+ uint32_t allocations,
-+ uint64_t bytes,
-+ uint64_t addtime,
-+ uint64_t usetime,
-+ uint32_t packets);
-+
-+int
-+pfkey_address_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint8_t proto,
-+ uint8_t prefixlen,
-+ struct sockaddr* address);
-+
-+int
-+pfkey_key_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint16_t key_bits,
-+ char* key);
-+
-+int
-+pfkey_ident_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint16_t ident_type,
-+ uint64_t ident_id,
-+ uint8_t ident_len,
-+ char* ident_string);
-+
-+#ifdef NAT_TRAVERSAL
-+#ifdef __KERNEL__
-+extern int pfkey_nat_t_new_mapping(struct ipsec_sa *, struct sockaddr *, __u16);
-+extern int pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
-+extern int pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
-+#endif /* __KERNEL__ */
-+int
-+pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
-+ uint8_t type);
-+int
-+pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint16_t port);
-+#endif
-+
-+int
-+pfkey_sens_build(struct sadb_ext** pfkey_ext,
-+ uint32_t dpd,
-+ uint8_t sens_level,
-+ uint8_t sens_len,
-+ uint64_t* sens_bitmap,
-+ uint8_t integ_level,
-+ uint8_t integ_len,
-+ uint64_t* integ_bitmap);
-+
-+int pfkey_x_protocol_build(struct sadb_ext **, uint8_t);
-+
-+
-+int
-+pfkey_prop_build(struct sadb_ext** pfkey_ext,
-+ uint8_t replay,
-+ unsigned int comb_num,
-+ struct sadb_comb* comb);
-+
-+int
-+pfkey_supported_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ unsigned int alg_num,
-+ struct sadb_alg* alg);
-+
-+int
-+pfkey_spirange_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint32_t min,
-+ uint32_t max);
-+
-+int
-+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext);
-+
-+int
-+pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
-+ uint8_t satype);
-+
-+int
-+pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
-+ uint32_t tunnel,
-+ uint32_t netlink,
-+ uint32_t xform,
-+ uint32_t eroute,
-+ uint32_t spi,
-+ uint32_t radij,
-+ uint32_t esp,
-+ uint32_t ah,
-+ uint32_t rcv,
-+ uint32_t pfkey,
-+ uint32_t ipcomp,
-+ uint32_t verbose);
-+
-+int
-+pfkey_msg_build(struct sadb_msg** pfkey_msg,
-+ struct sadb_ext* extensions[],
-+ int dir);
-+
-+/* in pfkey_v2_debug.c - routines to decode numbers -> strings */
-+const char *
-+pfkey_v2_sadb_ext_string(int extnum);
-+
-+const char *
-+pfkey_v2_sadb_type_string(int sadb_type);
-+
-+
-+#endif /* __NET_IPSEC_PF_KEY_H */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.45 2004/04/06 02:49:00 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.44 2003/12/10 01:20:01 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.43 2003/10/31 02:26:44 mcr
-+ * pulled up port-selector patches.
-+ *
-+ * Revision 1.42.2.2 2003/10/29 01:09:32 mcr
-+ * added debugging for pfkey library.
-+ *
-+ * Revision 1.42.2.1 2003/09/21 13:59:34 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.42 2003/08/25 22:08:19 mcr
-+ * removed pfkey_proto_init() from pfkey.h for 2.6 support.
-+ *
-+ * Revision 1.41 2003/05/07 17:28:57 mcr
-+ * new function pfkey_debug_func added for us in debugging from
-+
-+ * pfkey library.
-+ *
-+ * Revision 1.40 2003/01/30 02:31:34 rgb
-+ *
-+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
-+ *
-+ * Revision 1.39 2002/09/20 15:40:21 rgb
-+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
-+ * Added ref parameter to pfkey_sa_build().
-+ * Cleaned out unused cruft.
-+ *
-+ * Revision 1.38 2002/05/14 02:37:24 rgb
-+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
-+ * ipsec_sa or ipsec_sa.
-+ * Added function prototypes for the functions moved to
-+ * pfkey_v2_ext_process.c.
-+ *
-+ * Revision 1.37 2002/04/24 07:36:49 mcr
-+ * Moved from ./lib/pfkey.h,v
-+ *
-+ * Revision 1.36 2002/01/20 20:34:49 mcr
-+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
-+ *
-+ * Revision 1.35 2001/11/27 05:27:47 mcr
-+ * pfkey parses are now maintained by a structure
-+ * that includes their name for debug purposes.
-+ *
-+ * Revision 1.34 2001/11/26 09:23:53 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.33 2001/11/06 19:47:47 rgb
-+ * Added packet parameter to lifetime and comb structures.
-+ *
-+ * Revision 1.32 2001/09/08 21:13:34 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.31 2001/06/14 19:35:16 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.30 2001/02/27 07:04:52 rgb
-+ * Added satype2name prototype.
-+ *
-+ * Revision 1.29 2001/02/26 19:59:33 rgb
-+ * Ditch unused sadb_satype2proto[], replaced by satype2proto().
-+ *
-+ * Revision 1.28 2000/10/10 20:10:19 rgb
-+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
-+ *
-+ * Revision 1.27 2000/09/21 04:20:45 rgb
-+ * Fixed array size off-by-one error. (Thanks Svenning!)
-+ *
-+ * Revision 1.26 2000/09/12 03:26:05 rgb
-+ * Added pfkey_acquire prototype.
-+ *
-+ * Revision 1.25 2000/09/08 19:21:28 rgb
-+ * Fix pfkey_prop_build() parameter to be only single indirection.
-+ *
-+ * Revision 1.24 2000/09/01 18:46:42 rgb
-+ * Added a supported algorithms array lists, one per satype and registered
-+ * existing algorithms.
-+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
-+ * list.
-+ *
-+ * Revision 1.23 2000/08/27 01:55:26 rgb
-+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
-+ *
-+ * Revision 1.22 2000/08/20 21:39:23 rgb
-+ * Added kernel prototypes for kernel funcitions pfkey_upmsg() and
-+ * pfkey_expire().
-+ *
-+ * Revision 1.21 2000/08/15 17:29:23 rgb
-+ * Fixes from SZI to untested pfkey_prop_build().
-+ *
-+ * Revision 1.20 2000/05/10 20:14:19 rgb
-+ * Fleshed out sensitivity, proposal and supported extensions.
-+ *
-+ * Revision 1.19 2000/03/16 14:07:23 rgb
-+ * Renamed ALIGN macro to avoid fighting with others in kernel.
-+ *
-+ * Revision 1.18 2000/01/22 23:24:06 rgb
-+ * Added prototypes for proto2satype(), satype2proto() and proto2name().
-+ *
-+ * Revision 1.17 2000/01/21 06:26:59 rgb
-+ * Converted from double tdb arguments to one structure (extr)
-+ * containing pointers to all temporary information structures.
-+ * Added klipsdebug switching capability.
-+ * Dropped unused argument to pfkey_x_satype_build().
-+ *
-+ * Revision 1.16 1999/12/29 21:17:41 rgb
-+ * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
-+ * parameter for cleaner manipulation of extensions[] and to guard
-+ * against potential memory leaks.
-+ * Changed the I/F to pfkey_msg_free() for the same reason.
-+ *
-+ * Revision 1.15 1999/12/09 23:12:54 rgb
-+ * Added macro for BITS_PER_OCTET.
-+ * Added argument to pfkey_sa_build() to do eroutes.
-+ *
-+ * Revision 1.14 1999/12/08 20:33:25 rgb
-+ * Changed sa_family_t to uint16_t for 2.0.xx compatibility.
-+ *
-+ * Revision 1.13 1999/12/07 19:53:40 rgb
-+ * Removed unused first argument from extension parsers.
-+ * Changed __u* types to uint* to avoid use of asm/types.h and
-+ * sys/types.h in userspace code.
-+ * Added function prototypes for pfkey message and extensions
-+ * initialisation and cleanup.
-+ *
-+ * Revision 1.12 1999/12/01 22:19:38 rgb
-+ * Change pfkey_sa_build to accept an SPI in network byte order.
-+ *
-+ * Revision 1.11 1999/11/27 11:55:26 rgb
-+ * Added extern sadb_satype2proto to enable moving protocol lookup table
-+ * to lib/pfkey_v2_parse.c.
-+ * Delete unused, moved typedefs.
-+ * Add argument to pfkey_msg_parse() for direction.
-+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
-+ *
-+ * Revision 1.10 1999/11/23 22:29:21 rgb
-+ * This file has been moved in the distribution from klips/net/ipsec to
-+ * lib.
-+ * Add macros for dealing with alignment and rounding up more opaquely.
-+ * The uint<n>_t type defines have been moved to freeswan.h to avoid
-+ * chicken-and-egg problems.
-+ * Add macros for dealing with alignment and rounding up more opaque.
-+ * Added prototypes for using extention header bitmaps.
-+ * Added prototypes of all the build functions.
-+ *
-+ * Revision 1.9 1999/11/20 21:59:48 rgb
-+ * Moved socketlist type declarations and prototypes for shared use.
-+ * Slightly modified scope of sockaddr_key declaration.
-+ *
-+ * Revision 1.8 1999/11/17 14:34:25 rgb
-+ * Protect sa_family_t from being used in userspace with GLIBC<2.
-+ *
-+ * Revision 1.7 1999/10/27 19:40:35 rgb
-+ * Add a maximum PFKEY packet size macro.
-+ *
-+ * Revision 1.6 1999/10/26 16:58:58 rgb
-+ * Created a sockaddr_key and key_opt socket extension structures.
-+ *
-+ * Revision 1.5 1999/06/10 05:24:41 rgb
-+ * Renamed variables to reduce confusion.
-+ *
-+ * Revision 1.4 1999/04/29 15:21:11 rgb
-+ * Add pfkey support to debugging.
-+ * Add return values to init and cleanup functions.
-+ *
-+ * Revision 1.3 1999/04/15 17:58:07 rgb
-+ * Add RCSID labels.
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/pfkeyv2.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,467 @@
-+/*
-+ * RCSID $Id$
-+ */
-+
-+/*
-+RFC 2367 PF_KEY Key Management API July 1998
-+
-+
-+Appendix D: Sample Header File
-+
-+This file defines structures and symbols for the PF_KEY Version 2
-+key management interface. It was written at the U.S. Naval Research
-+Laboratory. This file is in the public domain. The authors ask that
-+you leave this credit intact on any copies of this file.
-+*/
-+#ifndef __PFKEY_V2_H
-+#define __PFKEY_V2_H 1
-+
-+#define PF_KEY_V2 2
-+#define PFKEYV2_REVISION 199806L
-+
-+#define SADB_RESERVED 0
-+#define SADB_GETSPI 1
-+#define SADB_UPDATE 2
-+#define SADB_ADD 3
-+#define SADB_DELETE 4
-+#define SADB_GET 5
-+#define SADB_ACQUIRE 6
-+#define SADB_REGISTER 7
-+#define SADB_EXPIRE 8
-+#define SADB_FLUSH 9
-+#define SADB_DUMP 10
-+#define SADB_X_PROMISC 11
-+#define SADB_X_PCHANGE 12
-+#define SADB_X_GRPSA 13
-+#define SADB_X_ADDFLOW 14
-+#define SADB_X_DELFLOW 15
-+#define SADB_X_DEBUG 16
-+#define SADB_X_NAT_T_NEW_MAPPING 17
-+#define SADB_MAX 17
-+
-+struct sadb_msg {
-+ uint8_t sadb_msg_version;
-+ uint8_t sadb_msg_type;
-+ uint8_t sadb_msg_errno;
-+ uint8_t sadb_msg_satype;
-+ uint16_t sadb_msg_len;
-+ uint16_t sadb_msg_reserved;
-+ uint32_t sadb_msg_seq;
-+ uint32_t sadb_msg_pid;
-+};
-+
-+struct sadb_ext {
-+ uint16_t sadb_ext_len;
-+ uint16_t sadb_ext_type;
-+};
-+
-+struct sadb_sa {
-+ uint16_t sadb_sa_len;
-+ uint16_t sadb_sa_exttype;
-+ uint32_t sadb_sa_spi;
-+ uint8_t sadb_sa_replay;
-+ uint8_t sadb_sa_state;
-+ uint8_t sadb_sa_auth;
-+ uint8_t sadb_sa_encrypt;
-+ uint32_t sadb_sa_flags;
-+ uint32_t /*IPsecSAref_t*/ sadb_x_sa_ref; /* 32 bits */
-+ uint8_t sadb_x_reserved[4];
-+};
-+
-+struct sadb_sa_v1 {
-+ uint16_t sadb_sa_len;
-+ uint16_t sadb_sa_exttype;
-+ uint32_t sadb_sa_spi;
-+ uint8_t sadb_sa_replay;
-+ uint8_t sadb_sa_state;
-+ uint8_t sadb_sa_auth;
-+ uint8_t sadb_sa_encrypt;
-+ uint32_t sadb_sa_flags;
-+};
-+
-+struct sadb_lifetime {
-+ uint16_t sadb_lifetime_len;
-+ uint16_t sadb_lifetime_exttype;
-+ uint32_t sadb_lifetime_allocations;
-+ uint64_t sadb_lifetime_bytes;
-+ uint64_t sadb_lifetime_addtime;
-+ uint64_t sadb_lifetime_usetime;
-+ uint32_t sadb_x_lifetime_packets;
-+ uint32_t sadb_x_lifetime_reserved;
-+};
-+
-+struct sadb_address {
-+ uint16_t sadb_address_len;
-+ uint16_t sadb_address_exttype;
-+ uint8_t sadb_address_proto;
-+ uint8_t sadb_address_prefixlen;
-+ uint16_t sadb_address_reserved;
-+};
-+
-+struct sadb_key {
-+ uint16_t sadb_key_len;
-+ uint16_t sadb_key_exttype;
-+ uint16_t sadb_key_bits;
-+ uint16_t sadb_key_reserved;
-+};
-+
-+struct sadb_ident {
-+ uint16_t sadb_ident_len;
-+ uint16_t sadb_ident_exttype;
-+ uint16_t sadb_ident_type;
-+ uint16_t sadb_ident_reserved;
-+ uint64_t sadb_ident_id;
-+};
-+
-+struct sadb_sens {
-+ uint16_t sadb_sens_len;
-+ uint16_t sadb_sens_exttype;
-+ uint32_t sadb_sens_dpd;
-+ uint8_t sadb_sens_sens_level;
-+ uint8_t sadb_sens_sens_len;
-+ uint8_t sadb_sens_integ_level;
-+ uint8_t sadb_sens_integ_len;
-+ uint32_t sadb_sens_reserved;
-+};
-+
-+struct sadb_prop {
-+ uint16_t sadb_prop_len;
-+ uint16_t sadb_prop_exttype;
-+ uint8_t sadb_prop_replay;
-+ uint8_t sadb_prop_reserved[3];
-+};
-+
-+struct sadb_comb {
-+ uint8_t sadb_comb_auth;
-+ uint8_t sadb_comb_encrypt;
-+ uint16_t sadb_comb_flags;
-+ uint16_t sadb_comb_auth_minbits;
-+ uint16_t sadb_comb_auth_maxbits;
-+ uint16_t sadb_comb_encrypt_minbits;
-+ uint16_t sadb_comb_encrypt_maxbits;
-+ uint32_t sadb_comb_reserved;
-+ uint32_t sadb_comb_soft_allocations;
-+ uint32_t sadb_comb_hard_allocations;
-+ uint64_t sadb_comb_soft_bytes;
-+ uint64_t sadb_comb_hard_bytes;
-+ uint64_t sadb_comb_soft_addtime;
-+ uint64_t sadb_comb_hard_addtime;
-+ uint64_t sadb_comb_soft_usetime;
-+ uint64_t sadb_comb_hard_usetime;
-+ uint32_t sadb_x_comb_soft_packets;
-+ uint32_t sadb_x_comb_hard_packets;
-+};
-+
-+struct sadb_supported {
-+ uint16_t sadb_supported_len;
-+ uint16_t sadb_supported_exttype;
-+ uint32_t sadb_supported_reserved;
-+};
-+
-+struct sadb_alg {
-+ uint8_t sadb_alg_id;
-+ uint8_t sadb_alg_ivlen;
-+ uint16_t sadb_alg_minbits;
-+ uint16_t sadb_alg_maxbits;
-+ uint16_t sadb_alg_reserved;
-+};
-+
-+struct sadb_spirange {
-+ uint16_t sadb_spirange_len;
-+ uint16_t sadb_spirange_exttype;
-+ uint32_t sadb_spirange_min;
-+ uint32_t sadb_spirange_max;
-+ uint32_t sadb_spirange_reserved;
-+};
-+
-+struct sadb_x_kmprivate {
-+ uint16_t sadb_x_kmprivate_len;
-+ uint16_t sadb_x_kmprivate_exttype;
-+ uint32_t sadb_x_kmprivate_reserved;
-+};
-+
-+struct sadb_x_satype {
-+ uint16_t sadb_x_satype_len;
-+ uint16_t sadb_x_satype_exttype;
-+ uint8_t sadb_x_satype_satype;
-+ uint8_t sadb_x_satype_reserved[3];
-+};
-+
-+struct sadb_x_policy {
-+ uint16_t sadb_x_policy_len;
-+ uint16_t sadb_x_policy_exttype;
-+ uint16_t sadb_x_policy_type;
-+ uint8_t sadb_x_policy_dir;
-+ uint8_t sadb_x_policy_reserved;
-+ uint32_t sadb_x_policy_id;
-+ uint32_t sadb_x_policy_reserved2;
-+};
-+
-+struct sadb_x_debug {
-+ uint16_t sadb_x_debug_len;
-+ uint16_t sadb_x_debug_exttype;
-+ uint32_t sadb_x_debug_tunnel;
-+ uint32_t sadb_x_debug_netlink;
-+ uint32_t sadb_x_debug_xform;
-+ uint32_t sadb_x_debug_eroute;
-+ uint32_t sadb_x_debug_spi;
-+ uint32_t sadb_x_debug_radij;
-+ uint32_t sadb_x_debug_esp;
-+ uint32_t sadb_x_debug_ah;
-+ uint32_t sadb_x_debug_rcv;
-+ uint32_t sadb_x_debug_pfkey;
-+ uint32_t sadb_x_debug_ipcomp;
-+ uint32_t sadb_x_debug_verbose;
-+ uint8_t sadb_x_debug_reserved[4];
-+};
-+
-+struct sadb_x_nat_t_type {
-+ uint16_t sadb_x_nat_t_type_len;
-+ uint16_t sadb_x_nat_t_type_exttype;
-+ uint8_t sadb_x_nat_t_type_type;
-+ uint8_t sadb_x_nat_t_type_reserved[3];
-+};
-+struct sadb_x_nat_t_port {
-+ uint16_t sadb_x_nat_t_port_len;
-+ uint16_t sadb_x_nat_t_port_exttype;
-+ uint16_t sadb_x_nat_t_port_port;
-+ uint16_t sadb_x_nat_t_port_reserved;
-+};
-+
-+/*
-+ * A protocol structure for passing through the transport level
-+ * protocol. It contains more fields than are actually used/needed
-+ * but it is this way to be compatible with the structure used in
-+ * OpenBSD (http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h)
-+ */
-+struct sadb_protocol {
-+ uint16_t sadb_protocol_len;
-+ uint16_t sadb_protocol_exttype;
-+ uint8_t sadb_protocol_proto;
-+ uint8_t sadb_protocol_direction;
-+ uint8_t sadb_protocol_flags;
-+ uint8_t sadb_protocol_reserved2;
-+};
-+
-+#define SADB_EXT_RESERVED 0
-+#define SADB_EXT_SA 1
-+#define SADB_EXT_LIFETIME_CURRENT 2
-+#define SADB_EXT_LIFETIME_HARD 3
-+#define SADB_EXT_LIFETIME_SOFT 4
-+#define SADB_EXT_ADDRESS_SRC 5
-+#define SADB_EXT_ADDRESS_DST 6
-+#define SADB_EXT_ADDRESS_PROXY 7
-+#define SADB_EXT_KEY_AUTH 8
-+#define SADB_EXT_KEY_ENCRYPT 9
-+#define SADB_EXT_IDENTITY_SRC 10
-+#define SADB_EXT_IDENTITY_DST 11
-+#define SADB_EXT_SENSITIVITY 12
-+#define SADB_EXT_PROPOSAL 13
-+#define SADB_EXT_SUPPORTED_AUTH 14
-+#define SADB_EXT_SUPPORTED_ENCRYPT 15
-+#define SADB_EXT_SPIRANGE 16
-+#define SADB_X_EXT_KMPRIVATE 17
-+#define SADB_X_EXT_SATYPE2 18
-+#ifdef KERNEL26_HAS_KAME_DUPLICATES
-+#define SADB_X_EXT_POLICY 18
-+#endif
-+#define SADB_X_EXT_SA2 19
-+#define SADB_X_EXT_ADDRESS_DST2 20
-+#define SADB_X_EXT_ADDRESS_SRC_FLOW 21
-+#define SADB_X_EXT_ADDRESS_DST_FLOW 22
-+#define SADB_X_EXT_ADDRESS_SRC_MASK 23
-+#define SADB_X_EXT_ADDRESS_DST_MASK 24
-+#define SADB_X_EXT_DEBUG 25
-+#define SADB_X_EXT_PROTOCOL 26
-+#define SADB_X_EXT_NAT_T_TYPE 27
-+#define SADB_X_EXT_NAT_T_SPORT 28
-+#define SADB_X_EXT_NAT_T_DPORT 29
-+#define SADB_X_EXT_NAT_T_OA 30
-+#define SADB_EXT_MAX 30
-+
-+/* SADB_X_DELFLOW required over and above SADB_X_SAFLAGS_CLEARFLOW */
-+#define SADB_X_EXT_ADDRESS_DELFLOW \
-+ ( (1<<SADB_X_EXT_ADDRESS_SRC_FLOW) \
-+ | (1<<SADB_X_EXT_ADDRESS_DST_FLOW) \
-+ | (1<<SADB_X_EXT_ADDRESS_SRC_MASK) \
-+ | (1<<SADB_X_EXT_ADDRESS_DST_MASK))
-+
-+#define SADB_SATYPE_UNSPEC 0
-+#define SADB_SATYPE_AH 2
-+#define SADB_SATYPE_ESP 3
-+#define SADB_SATYPE_RSVP 5
-+#define SADB_SATYPE_OSPFV2 6
-+#define SADB_SATYPE_RIPV2 7
-+#define SADB_SATYPE_MIP 8
-+#define SADB_X_SATYPE_IPIP 9
-+#ifdef KERNEL26_HAS_KAME_DUPLICATES
-+#define SADB_X_SATYPE_IPCOMP 9 /* ICK! */
-+#endif
-+#define SADB_X_SATYPE_COMP 10
-+#define SADB_X_SATYPE_INT 11
-+#define SADB_SATYPE_MAX 11
-+
-+#define SADB_SASTATE_LARVAL 0
-+#define SADB_SASTATE_MATURE 1
-+#define SADB_SASTATE_DYING 2
-+#define SADB_SASTATE_DEAD 3
-+#define SADB_SASTATE_MAX 3
-+
-+#define SADB_SAFLAGS_PFS 1
-+#define SADB_X_SAFLAGS_REPLACEFLOW 2
-+#define SADB_X_SAFLAGS_CLEARFLOW 4
-+#define SADB_X_SAFLAGS_INFLOW 8
-+
-+/* not obvious, but these are the same values as used in isakmp,
-+ * and in freeswan/ipsec_policy.h. If you need to add any, they
-+ * should be added as according to
-+ * http://www.iana.org/assignments/isakmp-registry
-+ *
-+ * and if not, then please try to use a private-use value, and
-+ * consider asking IANA to assign a value.
-+ */
-+#define SADB_AALG_NONE 0
-+#define SADB_AALG_MD5HMAC 2
-+#define SADB_AALG_SHA1HMAC 3
-+#define SADB_X_AALG_SHA2_256HMAC 5
-+#define SADB_X_AALG_SHA2_384HMAC 6
-+#define SADB_X_AALG_SHA2_512HMAC 7
-+#define SADB_X_AALG_RIPEMD160HMAC 8
-+#define SADB_X_AALG_NULL 251 /* kame */
-+#define SADB_AALG_MAX 251
-+
-+#define SADB_EALG_NONE 0
-+#define SADB_EALG_DESCBC 2
-+#define SADB_EALG_3DESCBC 3
-+#define SADB_X_EALG_CASTCBC 6
-+#define SADB_X_EALG_BLOWFISHCBC 7
-+#define SADB_EALG_NULL 11
-+#define SADB_X_EALG_AESCBC 12
-+#define SADB_EALG_MAX 255
-+
-+#define SADB_X_CALG_NONE 0
-+#define SADB_X_CALG_OUI 1
-+#define SADB_X_CALG_DEFLATE 2
-+#define SADB_X_CALG_LZS 3
-+#define SADB_X_CALG_V42BIS 4
-+#ifdef KERNEL26_HAS_KAME_DUPLICATES
-+#define SADB_X_CALG_LZJH 4
-+#endif
-+#define SADB_X_CALG_MAX 4
-+
-+#define SADB_X_TALG_NONE 0
-+#define SADB_X_TALG_IPv4_in_IPv4 1
-+#define SADB_X_TALG_IPv6_in_IPv4 2
-+#define SADB_X_TALG_IPv4_in_IPv6 3
-+#define SADB_X_TALG_IPv6_in_IPv6 4
-+#define SADB_X_TALG_MAX 4
-+
-+
-+#define SADB_IDENTTYPE_RESERVED 0
-+#define SADB_IDENTTYPE_PREFIX 1
-+#define SADB_IDENTTYPE_FQDN 2
-+#define SADB_IDENTTYPE_USERFQDN 3
-+#define SADB_X_IDENTTYPE_CONNECTION 4
-+#define SADB_IDENTTYPE_MAX 4
-+
-+#define SADB_KEY_FLAGS_MAX 0
-+#endif /* __PFKEY_V2_H */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.30 2004/04/06 02:49:00 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.29 2003/12/22 21:35:58 mcr
-+ * new patches from Dr{Who}.
-+ *
-+ * Revision 1.28 2003/12/22 19:33:15 mcr
-+ * added 0.6c NAT-T patch.
-+ *
-+ * Revision 1.27 2003/12/10 01:20:01 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.26 2003/10/31 02:26:44 mcr
-+ * pulled up port-selector patches.
-+ *
-+ * Revision 1.25.4.1 2003/09/21 13:59:34 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.25 2003/07/31 23:59:17 mcr
-+ * re-introduce kernel 2.6 duplicate values for now.
-+ * hope to get them changed!
-+ *
-+ * Revision 1.24 2003/07/31 22:55:27 mcr
-+ * added some definitions to keep pfkeyv2.h files in sync.
-+ *
-+ * Revision 1.23 2003/05/11 00:43:48 mcr
-+ * added comment about origin of values used
-+ *
-+ * Revision 1.22 2003/01/30 02:31:34 rgb
-+ *
-+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
-+ *
-+ * Revision 1.21 2002/12/16 19:26:49 mcr
-+ * added definition of FS 1.xx sadb structure
-+ *
-+ * Revision 1.20 2002/09/20 15:40:25 rgb
-+ * Added sadb_x_sa_ref to struct sadb_sa.
-+ *
-+ * Revision 1.19 2002/04/24 07:36:49 mcr
-+ * Moved from ./lib/pfkeyv2.h,v
-+ *
-+ * Revision 1.18 2001/11/06 19:47:47 rgb
-+ * Added packet parameter to lifetime and comb structures.
-+ *
-+ * Revision 1.17 2001/09/08 21:13:35 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.16 2001/07/06 19:49:46 rgb
-+ * Added SADB_X_SAFLAGS_INFLOW for supporting incoming policy checks.
-+ *
-+ * Revision 1.15 2001/02/26 20:00:43 rgb
-+ * Added internal IP protocol 61 for magic SAs.
-+ *
-+ * Revision 1.14 2001/02/08 18:51:05 rgb
-+ * Include RFC document title and appendix subsection title.
-+ *
-+ * Revision 1.13 2000/10/10 20:10:20 rgb
-+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
-+ *
-+ * Revision 1.12 2000/09/15 06:41:50 rgb
-+ * Added V42BIS constant.
-+ *
-+ * Revision 1.11 2000/09/12 22:35:37 rgb
-+ * Restructured to remove unused extensions from CLEARFLOW messages.
-+ *
-+ * Revision 1.10 2000/09/12 18:50:09 rgb
-+ * Added IPIP tunnel types as algo support.
-+ *
-+ * Revision 1.9 2000/08/21 16:47:19 rgb
-+ * Added SADB_X_CALG_* macros for IPCOMP.
-+ *
-+ * Revision 1.8 2000/08/09 20:43:34 rgb
-+ * Fixed bitmask value for SADB_X_SAFLAGS_CLEAREROUTE.
-+ *
-+ * Revision 1.7 2000/01/21 06:28:37 rgb
-+ * Added flow add/delete message type macros.
-+ * Added flow address extension type macros.
-+ * Tidied up spacing.
-+ * Added klipsdebug switching capability.
-+ *
-+ * Revision 1.6 1999/11/27 11:56:08 rgb
-+ * Add SADB_X_SATYPE_COMP for compression, eventually.
-+ *
-+ * Revision 1.5 1999/11/23 22:23:16 rgb
-+ * This file has been moved in the distribution from klips/net/ipsec to
-+ * lib.
-+ *
-+ * Revision 1.4 1999/04/29 15:23:29 rgb
-+ * Add GRPSA support.
-+ * Add support for a second SATYPE, SA and DST_ADDRESS.
-+ * Add IPPROTO_IPIP support.
-+ *
-+ * Revision 1.3 1999/04/15 17:58:08 rgb
-+ * Add RCSID labels.
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/zlib/zlib.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,893 @@
-+/* zlib.h -- interface of the 'zlib' general purpose compression library
-+ version 1.1.4, March 11th, 2002
-+
-+ Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
-+
-+ This software is provided 'as-is', without any express or implied
-+ warranty. In no event will the authors be held liable for any damages
-+ arising from the use of this software.
-+
-+ Permission is granted to anyone to use this software for any purpose,
-+ including commercial applications, and to alter it and redistribute it
-+ freely, subject to the following restrictions:
-+
-+ 1. The origin of this software must not be misrepresented; you must not
-+ claim that you wrote the original software. If you use this software
-+ in a product, an acknowledgment in the product documentation would be
-+ appreciated but is not required.
-+ 2. Altered source versions must be plainly marked as such, and must not be
-+ misrepresented as being the original software.
-+ 3. This notice may not be removed or altered from any source distribution.
-+
-+ Jean-loup Gailly Mark Adler
-+ jloup@gzip.org madler@alumni.caltech.edu
-+
-+
-+ The data format used by the zlib library is described by RFCs (Request for
-+ Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
-+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
-+*/
-+
-+#ifndef _ZLIB_H
-+#define _ZLIB_H
-+
-+#include "zconf.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#define ZLIB_VERSION "1.1.4"
-+
-+/*
-+ The 'zlib' compression library provides in-memory compression and
-+ decompression functions, including integrity checks of the uncompressed
-+ data. This version of the library supports only one compression method
-+ (deflation) but other algorithms will be added later and will have the same
-+ stream interface.
-+
-+ Compression can be done in a single step if the buffers are large
-+ enough (for example if an input file is mmap'ed), or can be done by
-+ repeated calls of the compression function. In the latter case, the
-+ application must provide more input and/or consume the output
-+ (providing more output space) before each call.
-+
-+ The library also supports reading and writing files in gzip (.gz) format
-+ with an interface similar to that of stdio.
-+
-+ The library does not install any signal handler. The decoder checks
-+ the consistency of the compressed data, so the library should never
-+ crash even in case of corrupted input.
-+*/
-+
-+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-+typedef void (*free_func) OF((voidpf opaque, voidpf address));
-+
-+struct internal_state;
-+
-+typedef struct z_stream_s {
-+ Bytef *next_in; /* next input byte */
-+ uInt avail_in; /* number of bytes available at next_in */
-+ uLong total_in; /* total nb of input bytes read so far */
-+
-+ Bytef *next_out; /* next output byte should be put there */
-+ uInt avail_out; /* remaining free space at next_out */
-+ uLong total_out; /* total nb of bytes output so far */
-+
-+ const char *msg; /* last error message, NULL if no error */
-+ struct internal_state FAR *state; /* not visible by applications */
-+
-+ alloc_func zalloc; /* used to allocate the internal state */
-+ free_func zfree; /* used to free the internal state */
-+ voidpf opaque; /* private data object passed to zalloc and zfree */
-+
-+ int data_type; /* best guess about the data type: ascii or binary */
-+ uLong adler; /* adler32 value of the uncompressed data */
-+ uLong reserved; /* reserved for future use */
-+} z_stream;
-+
-+typedef z_stream FAR *z_streamp;
-+
-+/*
-+ The application must update next_in and avail_in when avail_in has
-+ dropped to zero. It must update next_out and avail_out when avail_out
-+ has dropped to zero. The application must initialize zalloc, zfree and
-+ opaque before calling the init function. All other fields are set by the
-+ compression library and must not be updated by the application.
-+
-+ The opaque value provided by the application will be passed as the first
-+ parameter for calls of zalloc and zfree. This can be useful for custom
-+ memory management. The compression library attaches no meaning to the
-+ opaque value.
-+
-+ zalloc must return Z_NULL if there is not enough memory for the object.
-+ If zlib is used in a multi-threaded application, zalloc and zfree must be
-+ thread safe.
-+
-+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
-+ exactly 65536 bytes, but will not be required to allocate more than this
-+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
-+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
-+ have their offset normalized to zero. The default allocation function
-+ provided by this library ensures this (see zutil.c). To reduce memory
-+ requirements and avoid any allocation of 64K objects, at the expense of
-+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-+
-+ The fields total_in and total_out can be used for statistics or
-+ progress reports. After compression, total_in holds the total size of
-+ the uncompressed data and may be saved for use in the decompressor
-+ (particularly if the decompressor wants to decompress everything in
-+ a single step).
-+*/
-+
-+ /* constants */
-+
-+#define Z_NO_FLUSH 0
-+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
-+#define Z_SYNC_FLUSH 2
-+#define Z_FULL_FLUSH 3
-+#define Z_FINISH 4
-+/* Allowed flush values; see deflate() below for details */
-+
-+#define Z_OK 0
-+#define Z_STREAM_END 1
-+#define Z_NEED_DICT 2
-+#define Z_ERRNO (-1)
-+#define Z_STREAM_ERROR (-2)
-+#define Z_DATA_ERROR (-3)
-+#define Z_MEM_ERROR (-4)
-+#define Z_BUF_ERROR (-5)
-+#define Z_VERSION_ERROR (-6)
-+/* Return codes for the compression/decompression functions. Negative
-+ * values are errors, positive values are used for special but normal events.
-+ */
-+
-+#define Z_NO_COMPRESSION 0
-+#define Z_BEST_SPEED 1
-+#define Z_BEST_COMPRESSION 9
-+#define Z_DEFAULT_COMPRESSION (-1)
-+/* compression levels */
-+
-+#define Z_FILTERED 1
-+#define Z_HUFFMAN_ONLY 2
-+#define Z_DEFAULT_STRATEGY 0
-+/* compression strategy; see deflateInit2() below for details */
-+
-+#define Z_BINARY 0
-+#define Z_ASCII 1
-+#define Z_UNKNOWN 2
-+/* Possible values of the data_type field */
-+
-+#define Z_DEFLATED 8
-+/* The deflate compression method (the only one supported in this version) */
-+
-+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-+
-+#define zlib_version zlibVersion()
-+/* for compatibility with versions < 1.0.2 */
-+
-+ /* basic functions */
-+
-+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
-+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
-+ If the first character differs, the library code actually used is
-+ not compatible with the zlib.h header file used by the application.
-+ This check is automatically made by deflateInit and inflateInit.
-+ */
-+
-+/*
-+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
-+
-+ Initializes the internal stream state for compression. The fields
-+ zalloc, zfree and opaque must be initialized before by the caller.
-+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to
-+ use default allocation functions.
-+
-+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
-+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
-+ all (the input data is simply copied a block at a time).
-+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
-+ compression (currently equivalent to level 6).
-+
-+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
-+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
-+ with the version assumed by the caller (ZLIB_VERSION).
-+ msg is set to null if there is no error message. deflateInit does not
-+ perform any compression: this will be done by deflate().
-+*/
-+
-+
-+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
-+/*
-+ deflate compresses as much data as possible, and stops when the input
-+ buffer becomes empty or the output buffer becomes full. It may introduce some
-+ output latency (reading input without producing any output) except when
-+ forced to flush.
-+
-+ The detailed semantics are as follows. deflate performs one or both of the
-+ following actions:
-+
-+ - Compress more input starting at next_in and update next_in and avail_in
-+ accordingly. If not all input can be processed (because there is not
-+ enough room in the output buffer), next_in and avail_in are updated and
-+ processing will resume at this point for the next call of deflate().
-+
-+ - Provide more output starting at next_out and update next_out and avail_out
-+ accordingly. This action is forced if the parameter flush is non zero.
-+ Forcing flush frequently degrades the compression ratio, so this parameter
-+ should be set only when necessary (in interactive applications).
-+ Some output may be provided even if flush is not set.
-+
-+ Before the call of deflate(), the application should ensure that at least
-+ one of the actions is possible, by providing more input and/or consuming
-+ more output, and updating avail_in or avail_out accordingly; avail_out
-+ should never be zero before the call. The application can consume the
-+ compressed output when it wants, for example when the output buffer is full
-+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
-+ and with zero avail_out, it must be called again after making room in the
-+ output buffer because there might be more output pending.
-+
-+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
-+ flushed to the output buffer and the output is aligned on a byte boundary, so
-+ that the decompressor can get all input data available so far. (In particular
-+ avail_in is zero after the call if enough output space has been provided
-+ before the call.) Flushing may degrade compression for some compression
-+ algorithms and so it should be used only when necessary.
-+
-+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
-+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
-+ restart from this point if previous compressed data has been damaged or if
-+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
-+ the compression.
-+
-+ If deflate returns with avail_out == 0, this function must be called again
-+ with the same value of the flush parameter and more output space (updated
-+ avail_out), until the flush is complete (deflate returns with non-zero
-+ avail_out).
-+
-+ If the parameter flush is set to Z_FINISH, pending input is processed,
-+ pending output is flushed and deflate returns with Z_STREAM_END if there
-+ was enough output space; if deflate returns with Z_OK, this function must be
-+ called again with Z_FINISH and more output space (updated avail_out) but no
-+ more input data, until it returns with Z_STREAM_END or an error. After
-+ deflate has returned Z_STREAM_END, the only possible operations on the
-+ stream are deflateReset or deflateEnd.
-+
-+ Z_FINISH can be used immediately after deflateInit if all the compression
-+ is to be done in a single step. In this case, avail_out must be at least
-+ 0.1% larger than avail_in plus 12 bytes. If deflate does not return
-+ Z_STREAM_END, then it must be called again as described above.
-+
-+ deflate() sets strm->adler to the adler32 checksum of all input read
-+ so far (that is, total_in bytes).
-+
-+ deflate() may update data_type if it can make a good guess about
-+ the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
-+ binary. This field is only for information purposes and does not affect
-+ the compression algorithm in any manner.
-+
-+ deflate() returns Z_OK if some progress has been made (more input
-+ processed or more output produced), Z_STREAM_END if all input has been
-+ consumed and all output has been produced (only when flush is set to
-+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
-+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
-+ (for example avail_in or avail_out was zero).
-+*/
-+
-+
-+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
-+/*
-+ All dynamically allocated data structures for this stream are freed.
-+ This function discards any unprocessed input and does not flush any
-+ pending output.
-+
-+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
-+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
-+ prematurely (some input or output was discarded). In the error case,
-+ msg may be set but then points to a static string (which must not be
-+ deallocated).
-+*/
-+
-+
-+/*
-+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
-+
-+ Initializes the internal stream state for decompression. The fields
-+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
-+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
-+ value depends on the compression method), inflateInit determines the
-+ compression method from the zlib header and allocates all data structures
-+ accordingly; otherwise the allocation will be deferred to the first call of
-+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
-+ use default allocation functions.
-+
-+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
-+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
-+ version assumed by the caller. msg is set to null if there is no error
-+ message. inflateInit does not perform any decompression apart from reading
-+ the zlib header if present: this will be done by inflate(). (So next_in and
-+ avail_in may be modified, but next_out and avail_out are unchanged.)
-+*/
-+
-+
-+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
-+/*
-+ inflate decompresses as much data as possible, and stops when the input
-+ buffer becomes empty or the output buffer becomes full. It may some
-+ introduce some output latency (reading input without producing any output)
-+ except when forced to flush.
-+
-+ The detailed semantics are as follows. inflate performs one or both of the
-+ following actions:
-+
-+ - Decompress more input starting at next_in and update next_in and avail_in
-+ accordingly. If not all input can be processed (because there is not
-+ enough room in the output buffer), next_in is updated and processing
-+ will resume at this point for the next call of inflate().
-+
-+ - Provide more output starting at next_out and update next_out and avail_out
-+ accordingly. inflate() provides as much output as possible, until there
-+ is no more input data or no more space in the output buffer (see below
-+ about the flush parameter).
-+
-+ Before the call of inflate(), the application should ensure that at least
-+ one of the actions is possible, by providing more input and/or consuming
-+ more output, and updating the next_* and avail_* values accordingly.
-+ The application can consume the uncompressed output when it wants, for
-+ example when the output buffer is full (avail_out == 0), or after each
-+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
-+ must be called again after making room in the output buffer because there
-+ might be more output pending.
-+
-+ If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
-+ output as possible to the output buffer. The flushing behavior of inflate is
-+ not specified for values of the flush parameter other than Z_SYNC_FLUSH
-+ and Z_FINISH, but the current implementation actually flushes as much output
-+ as possible anyway.
-+
-+ inflate() should normally be called until it returns Z_STREAM_END or an
-+ error. However if all decompression is to be performed in a single step
-+ (a single call of inflate), the parameter flush should be set to
-+ Z_FINISH. In this case all pending input is processed and all pending
-+ output is flushed; avail_out must be large enough to hold all the
-+ uncompressed data. (The size of the uncompressed data may have been saved
-+ by the compressor for this purpose.) The next operation on this stream must
-+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
-+ is never required, but can be used to inform inflate that a faster routine
-+ may be used for the single inflate() call.
-+
-+ If a preset dictionary is needed at this point (see inflateSetDictionary
-+ below), inflate sets strm-adler to the adler32 checksum of the
-+ dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
-+ it sets strm->adler to the adler32 checksum of all output produced
-+ so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
-+ an error code as described below. At the end of the stream, inflate()
-+ checks that its computed adler32 checksum is equal to that saved by the
-+ compressor and returns Z_STREAM_END only if the checksum is correct.
-+
-+ inflate() returns Z_OK if some progress has been made (more input processed
-+ or more output produced), Z_STREAM_END if the end of the compressed data has
-+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
-+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
-+ corrupted (input stream not conforming to the zlib format or incorrect
-+ adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
-+ (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
-+ enough memory, Z_BUF_ERROR if no progress is possible or if there was not
-+ enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
-+ case, the application may then call inflateSync to look for a good
-+ compression block.
-+*/
-+
-+
-+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
-+/*
-+ All dynamically allocated data structures for this stream are freed.
-+ This function discards any unprocessed input and does not flush any
-+ pending output.
-+
-+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
-+ was inconsistent. In the error case, msg may be set but then points to a
-+ static string (which must not be deallocated).
-+*/
-+
-+ /* Advanced functions */
-+
-+/*
-+ The following functions are needed only in some special applications.
-+*/
-+
-+/*
-+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
-+ int level,
-+ int method,
-+ int windowBits,
-+ int memLevel,
-+ int strategy));
-+
-+ This is another version of deflateInit with more compression options. The
-+ fields next_in, zalloc, zfree and opaque must be initialized before by
-+ the caller.
-+
-+ The method parameter is the compression method. It must be Z_DEFLATED in
-+ this version of the library.
-+
-+ The windowBits parameter is the base two logarithm of the window size
-+ (the size of the history buffer). It should be in the range 8..15 for this
-+ version of the library. Larger values of this parameter result in better
-+ compression at the expense of memory usage. The default value is 15 if
-+ deflateInit is used instead.
-+
-+ The memLevel parameter specifies how much memory should be allocated
-+ for the internal compression state. memLevel=1 uses minimum memory but
-+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
-+ for optimal speed. The default value is 8. See zconf.h for total memory
-+ usage as a function of windowBits and memLevel.
-+
-+ The strategy parameter is used to tune the compression algorithm. Use the
-+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
-+ filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
-+ string match). Filtered data consists mostly of small values with a
-+ somewhat random distribution. In this case, the compression algorithm is
-+ tuned to compress them better. The effect of Z_FILTERED is to force more
-+ Huffman coding and less string matching; it is somewhat intermediate
-+ between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
-+ the compression ratio but not the correctness of the compressed output even
-+ if it is not set appropriately.
-+
-+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
-+ method). msg is set to null if there is no error message. deflateInit2 does
-+ not perform any compression: this will be done by deflate().
-+*/
-+
-+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
-+ const Bytef *dictionary,
-+ uInt dictLength));
-+/*
-+ Initializes the compression dictionary from the given byte sequence
-+ without producing any compressed output. This function must be called
-+ immediately after deflateInit, deflateInit2 or deflateReset, before any
-+ call of deflate. The compressor and decompressor must use exactly the same
-+ dictionary (see inflateSetDictionary).
-+
-+ The dictionary should consist of strings (byte sequences) that are likely
-+ to be encountered later in the data to be compressed, with the most commonly
-+ used strings preferably put towards the end of the dictionary. Using a
-+ dictionary is most useful when the data to be compressed is short and can be
-+ predicted with good accuracy; the data can then be compressed better than
-+ with the default empty dictionary.
-+
-+ Depending on the size of the compression data structures selected by
-+ deflateInit or deflateInit2, a part of the dictionary may in effect be
-+ discarded, for example if the dictionary is larger than the window size in
-+ deflate or deflate2. Thus the strings most likely to be useful should be
-+ put at the end of the dictionary, not at the front.
-+
-+ Upon return of this function, strm->adler is set to the Adler32 value
-+ of the dictionary; the decompressor may later use this value to determine
-+ which dictionary has been used by the compressor. (The Adler32 value
-+ applies to the whole dictionary even if only a subset of the dictionary is
-+ actually used by the compressor.)
-+
-+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
-+ parameter is invalid (such as NULL dictionary) or the stream state is
-+ inconsistent (for example if deflate has already been called for this stream
-+ or if the compression method is bsort). deflateSetDictionary does not
-+ perform any compression: this will be done by deflate().
-+*/
-+
-+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
-+ z_streamp source));
-+/*
-+ Sets the destination stream as a complete copy of the source stream.
-+
-+ This function can be useful when several compression strategies will be
-+ tried, for example when there are several ways of pre-processing the input
-+ data with a filter. The streams that will be discarded should then be freed
-+ by calling deflateEnd. Note that deflateCopy duplicates the internal
-+ compression state which can be quite large, so this strategy is slow and
-+ can consume lots of memory.
-+
-+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
-+ (such as zalloc being NULL). msg is left unchanged in both source and
-+ destination.
-+*/
-+
-+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
-+/*
-+ This function is equivalent to deflateEnd followed by deflateInit,
-+ but does not free and reallocate all the internal compression state.
-+ The stream will keep the same compression level and any other attributes
-+ that may have been set by deflateInit2.
-+
-+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-+ stream state was inconsistent (such as zalloc or state being NULL).
-+*/
-+
-+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
-+ int level,
-+ int strategy));
-+/*
-+ Dynamically update the compression level and compression strategy. The
-+ interpretation of level and strategy is as in deflateInit2. This can be
-+ used to switch between compression and straight copy of the input data, or
-+ to switch to a different kind of input data requiring a different
-+ strategy. If the compression level is changed, the input available so far
-+ is compressed with the old level (and may be flushed); the new level will
-+ take effect only at the next call of deflate().
-+
-+ Before the call of deflateParams, the stream state must be set as for
-+ a call of deflate(), since the currently available input may have to
-+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
-+
-+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
-+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
-+ if strm->avail_out was zero.
-+*/
-+
-+/*
-+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
-+ int windowBits));
-+
-+ This is another version of inflateInit with an extra parameter. The
-+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
-+ before by the caller.
-+
-+ The windowBits parameter is the base two logarithm of the maximum window
-+ size (the size of the history buffer). It should be in the range 8..15 for
-+ this version of the library. The default value is 15 if inflateInit is used
-+ instead. If a compressed stream with a larger window size is given as
-+ input, inflate() will return with the error code Z_DATA_ERROR instead of
-+ trying to allocate a larger window.
-+
-+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
-+ memLevel). msg is set to null if there is no error message. inflateInit2
-+ does not perform any decompression apart from reading the zlib header if
-+ present: this will be done by inflate(). (So next_in and avail_in may be
-+ modified, but next_out and avail_out are unchanged.)
-+*/
-+
-+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
-+ const Bytef *dictionary,
-+ uInt dictLength));
-+/*
-+ Initializes the decompression dictionary from the given uncompressed byte
-+ sequence. This function must be called immediately after a call of inflate
-+ if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
-+ can be determined from the Adler32 value returned by this call of
-+ inflate. The compressor and decompressor must use exactly the same
-+ dictionary (see deflateSetDictionary).
-+
-+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
-+ parameter is invalid (such as NULL dictionary) or the stream state is
-+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
-+ expected one (incorrect Adler32 value). inflateSetDictionary does not
-+ perform any decompression: this will be done by subsequent calls of
-+ inflate().
-+*/
-+
-+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
-+/*
-+ Skips invalid compressed data until a full flush point (see above the
-+ description of deflate with Z_FULL_FLUSH) can be found, or until all
-+ available input is skipped. No output is provided.
-+
-+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
-+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
-+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
-+ case, the application may save the current current value of total_in which
-+ indicates where valid compressed data was found. In the error case, the
-+ application may repeatedly call inflateSync, providing more input each time,
-+ until success or end of the input data.
-+*/
-+
-+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
-+/*
-+ This function is equivalent to inflateEnd followed by inflateInit,
-+ but does not free and reallocate all the internal decompression state.
-+ The stream will keep attributes that may have been set by inflateInit2.
-+
-+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-+ stream state was inconsistent (such as zalloc or state being NULL).
-+*/
-+
-+
-+ /* utility functions */
-+
-+/*
-+ The following utility functions are implemented on top of the
-+ basic stream-oriented functions. To simplify the interface, some
-+ default options are assumed (compression level and memory usage,
-+ standard memory allocation functions). The source code of these
-+ utility functions can easily be modified if you need special options.
-+*/
-+
-+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
-+ const Bytef *source, uLong sourceLen));
-+/*
-+ Compresses the source buffer into the destination buffer. sourceLen is
-+ the byte length of the source buffer. Upon entry, destLen is the total
-+ size of the destination buffer, which must be at least 0.1% larger than
-+ sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
-+ compressed buffer.
-+ This function can be used to compress a whole file at once if the
-+ input file is mmap'ed.
-+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory, Z_BUF_ERROR if there was not enough room in the output
-+ buffer.
-+*/
-+
-+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
-+ const Bytef *source, uLong sourceLen,
-+ int level));
-+/*
-+ Compresses the source buffer into the destination buffer. The level
-+ parameter has the same meaning as in deflateInit. sourceLen is the byte
-+ length of the source buffer. Upon entry, destLen is the total size of the
-+ destination buffer, which must be at least 0.1% larger than sourceLen plus
-+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
-+
-+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
-+ Z_STREAM_ERROR if the level parameter is invalid.
-+*/
-+
-+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
-+ const Bytef *source, uLong sourceLen));
-+/*
-+ Decompresses the source buffer into the destination buffer. sourceLen is
-+ the byte length of the source buffer. Upon entry, destLen is the total
-+ size of the destination buffer, which must be large enough to hold the
-+ entire uncompressed data. (The size of the uncompressed data must have
-+ been saved previously by the compressor and transmitted to the decompressor
-+ by some mechanism outside the scope of this compression library.)
-+ Upon exit, destLen is the actual size of the compressed buffer.
-+ This function can be used to decompress a whole file at once if the
-+ input file is mmap'ed.
-+
-+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory, Z_BUF_ERROR if there was not enough room in the output
-+ buffer, or Z_DATA_ERROR if the input data was corrupted.
-+*/
-+
-+
-+typedef voidp gzFile;
-+
-+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
-+/*
-+ Opens a gzip (.gz) file for reading or writing. The mode parameter
-+ is as in fopen ("rb" or "wb") but can also include a compression level
-+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
-+ Huffman only compression as in "wb1h". (See the description
-+ of deflateInit2 for more information about the strategy parameter.)
-+
-+ gzopen can be used to read a file which is not in gzip format; in this
-+ case gzread will directly read from the file without decompression.
-+
-+ gzopen returns NULL if the file could not be opened or if there was
-+ insufficient memory to allocate the (de)compression state; errno
-+ can be checked to distinguish the two cases (if errno is zero, the
-+ zlib error is Z_MEM_ERROR). */
-+
-+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
-+/*
-+ gzdopen() associates a gzFile with the file descriptor fd. File
-+ descriptors are obtained from calls like open, dup, creat, pipe or
-+ fileno (in the file has been previously opened with fopen).
-+ The mode parameter is as in gzopen.
-+ The next call of gzclose on the returned gzFile will also close the
-+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
-+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
-+ gzdopen returns NULL if there was insufficient memory to allocate
-+ the (de)compression state.
-+*/
-+
-+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
-+/*
-+ Dynamically update the compression level or strategy. See the description
-+ of deflateInit2 for the meaning of these parameters.
-+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
-+ opened for writing.
-+*/
-+
-+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
-+/*
-+ Reads the given number of uncompressed bytes from the compressed file.
-+ If the input file was not in gzip format, gzread copies the given number
-+ of bytes into the buffer.
-+ gzread returns the number of uncompressed bytes actually read (0 for
-+ end of file, -1 for error). */
-+
-+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
-+ const voidp buf, unsigned len));
-+/*
-+ Writes the given number of uncompressed bytes into the compressed file.
-+ gzwrite returns the number of uncompressed bytes actually written
-+ (0 in case of error).
-+*/
-+
-+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
-+/*
-+ Converts, formats, and writes the args to the compressed file under
-+ control of the format string, as in fprintf. gzprintf returns the number of
-+ uncompressed bytes actually written (0 in case of error).
-+*/
-+
-+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
-+/*
-+ Writes the given null-terminated string to the compressed file, excluding
-+ the terminating null character.
-+ gzputs returns the number of characters written, or -1 in case of error.
-+*/
-+
-+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
-+/*
-+ Reads bytes from the compressed file until len-1 characters are read, or
-+ a newline character is read and transferred to buf, or an end-of-file
-+ condition is encountered. The string is then terminated with a null
-+ character.
-+ gzgets returns buf, or Z_NULL in case of error.
-+*/
-+
-+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
-+/*
-+ Writes c, converted to an unsigned char, into the compressed file.
-+ gzputc returns the value that was written, or -1 in case of error.
-+*/
-+
-+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
-+/*
-+ Reads one byte from the compressed file. gzgetc returns this byte
-+ or -1 in case of end of file or error.
-+*/
-+
-+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
-+/*
-+ Flushes all pending output into the compressed file. The parameter
-+ flush is as in the deflate() function. The return value is the zlib
-+ error number (see function gzerror below). gzflush returns Z_OK if
-+ the flush parameter is Z_FINISH and all output could be flushed.
-+ gzflush should be called only when strictly necessary because it can
-+ degrade compression.
-+*/
-+
-+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
-+ z_off_t offset, int whence));
-+/*
-+ Sets the starting position for the next gzread or gzwrite on the
-+ given compressed file. The offset represents a number of bytes in the
-+ uncompressed data stream. The whence parameter is defined as in lseek(2);
-+ the value SEEK_END is not supported.
-+ If the file is opened for reading, this function is emulated but can be
-+ extremely slow. If the file is opened for writing, only forward seeks are
-+ supported; gzseek then compresses a sequence of zeroes up to the new
-+ starting position.
-+
-+ gzseek returns the resulting offset location as measured in bytes from
-+ the beginning of the uncompressed stream, or -1 in case of error, in
-+ particular if the file is opened for writing and the new starting position
-+ would be before the current position.
-+*/
-+
-+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
-+/*
-+ Rewinds the given file. This function is supported only for reading.
-+
-+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
-+*/
-+
-+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
-+/*
-+ Returns the starting position for the next gzread or gzwrite on the
-+ given compressed file. This position represents a number of bytes in the
-+ uncompressed data stream.
-+
-+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
-+*/
-+
-+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
-+/*
-+ Returns 1 when EOF has previously been detected reading the given
-+ input stream, otherwise zero.
-+*/
-+
-+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
-+/*
-+ Flushes all pending output if necessary, closes the compressed file
-+ and deallocates all the (de)compression state. The return value is the zlib
-+ error number (see function gzerror below).
-+*/
-+
-+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
-+/*
-+ Returns the error message for the last error which occurred on the
-+ given compressed file. errnum is set to zlib error number. If an
-+ error occurred in the file system and not in the compression library,
-+ errnum is set to Z_ERRNO and the application may consult errno
-+ to get the exact error code.
-+*/
-+
-+ /* checksum functions */
-+
-+/*
-+ These functions are not related to compression but are exported
-+ anyway because they might be useful in applications using the
-+ compression library.
-+*/
-+
-+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
-+
-+/*
-+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
-+ return the updated checksum. If buf is NULL, this function returns
-+ the required initial value for the checksum.
-+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
-+ much faster. Usage example:
-+
-+ uLong adler = adler32(0L, Z_NULL, 0);
-+
-+ while (read_buffer(buffer, length) != EOF) {
-+ adler = adler32(adler, buffer, length);
-+ }
-+ if (adler != original_adler) error();
-+*/
-+
-+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
-+/*
-+ Update a running crc with the bytes buf[0..len-1] and return the updated
-+ crc. If buf is NULL, this function returns the required initial value
-+ for the crc. Pre- and post-conditioning (one's complement) is performed
-+ within this function so it shouldn't be done by the application.
-+ Usage example:
-+
-+ uLong crc = crc32(0L, Z_NULL, 0);
-+
-+ while (read_buffer(buffer, length) != EOF) {
-+ crc = crc32(crc, buffer, length);
-+ }
-+ if (crc != original_crc) error();
-+*/
-+
-+
-+ /* various hacks, don't look :) */
-+
-+/* deflateInit and inflateInit are macros to allow checking the zlib version
-+ * and the compiler's view of z_stream:
-+ */
-+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
-+ const char *version, int stream_size));
-+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
-+ const char *version, int stream_size));
-+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
-+ int windowBits, int memLevel,
-+ int strategy, const char *version,
-+ int stream_size));
-+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
-+ const char *version, int stream_size));
-+#define deflateInit(strm, level) \
-+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
-+#define inflateInit(strm) \
-+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
-+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
-+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
-+ (strategy), ZLIB_VERSION, sizeof(z_stream))
-+#define inflateInit2(strm, windowBits) \
-+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
-+
-+
-+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
-+ struct internal_state {int dummy;}; /* hack for buggy compilers */
-+#endif
-+
-+ZEXTERN const char * ZEXPORT zError OF((int err));
-+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
-+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _ZLIB_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/zlib/zutil.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,225 @@
-+/* zutil.h -- internal interface and configuration of the compression library
-+ * Copyright (C) 1995-2002 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+/* @(#) $Id$ */
-+
-+#ifndef _Z_UTIL_H
-+#define _Z_UTIL_H
-+
-+#include "zlib.h"
-+
-+#include <linux/string.h>
-+#define HAVE_MEMCPY
-+
-+#if 0 // #ifdef STDC
-+# include <stddef.h>
-+# include <string.h>
-+# include <stdlib.h>
-+#endif
-+#ifndef __KERNEL__
-+#ifdef NO_ERRNO_H
-+ extern int errno;
-+#else
-+# include <errno.h>
-+#endif
-+#endif
-+
-+#ifndef local
-+# define local static
-+#endif
-+/* compile with -Dlocal if your debugger can't find static symbols */
-+
-+typedef unsigned char uch;
-+typedef uch FAR uchf;
-+typedef unsigned short ush;
-+typedef ush FAR ushf;
-+typedef unsigned long ulg;
-+
-+extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
-+/* (size given to avoid silly warnings with Visual C++) */
-+
-+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
-+
-+#define ERR_RETURN(strm,err) \
-+ return (strm->msg = ERR_MSG(err), (err))
-+/* To be used only when the state is known to be valid */
-+
-+ /* common constants */
-+
-+#ifndef DEF_WBITS
-+# define DEF_WBITS MAX_WBITS
-+#endif
-+/* default windowBits for decompression. MAX_WBITS is for compression only */
-+
-+#if MAX_MEM_LEVEL >= 8
-+# define DEF_MEM_LEVEL 8
-+#else
-+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-+#endif
-+/* default memLevel */
-+
-+#define STORED_BLOCK 0
-+#define STATIC_TREES 1
-+#define DYN_TREES 2
-+/* The three kinds of block type */
-+
-+#define MIN_MATCH 3
-+#define MAX_MATCH 258
-+/* The minimum and maximum match lengths */
-+
-+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-+
-+ /* target dependencies */
-+
-+#ifdef MSDOS
-+# define OS_CODE 0x00
-+# if defined(__TURBOC__) || defined(__BORLANDC__)
-+# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
-+ /* Allow compilation with ANSI keywords only enabled */
-+ void _Cdecl farfree( void *block );
-+ void *_Cdecl farmalloc( unsigned long nbytes );
-+# else
-+# include <alloc.h>
-+# endif
-+# else /* MSC or DJGPP */
-+# include <malloc.h>
-+# endif
-+#endif
-+
-+#ifdef OS2
-+# define OS_CODE 0x06
-+#endif
-+
-+#ifdef WIN32 /* Window 95 & Windows NT */
-+# define OS_CODE 0x0b
-+#endif
-+
-+#if defined(VAXC) || defined(VMS)
-+# define OS_CODE 0x02
-+# define F_OPEN(name, mode) \
-+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
-+#endif
-+
-+#ifdef AMIGA
-+# define OS_CODE 0x01
-+#endif
-+
-+#if defined(ATARI) || defined(atarist)
-+# define OS_CODE 0x05
-+#endif
-+
-+#if defined(MACOS) || defined(TARGET_OS_MAC)
-+# define OS_CODE 0x07
-+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-+# include <unix.h> /* for fdopen */
-+# else
-+# ifndef fdopen
-+# define fdopen(fd,mode) NULL /* No fdopen() */
-+# endif
-+# endif
-+#endif
-+
-+#ifdef __50SERIES /* Prime/PRIMOS */
-+# define OS_CODE 0x0F
-+#endif
-+
-+#ifdef TOPS20
-+# define OS_CODE 0x0a
-+#endif
-+
-+#if defined(_BEOS_) || defined(RISCOS)
-+# define fdopen(fd,mode) NULL /* No fdopen() */
-+#endif
-+
-+#if (defined(_MSC_VER) && (_MSC_VER > 600))
-+# define fdopen(fd,type) _fdopen(fd,type)
-+#endif
-+
-+
-+ /* Common defaults */
-+
-+#ifndef OS_CODE
-+# define OS_CODE 0x03 /* assume Unix */
-+#endif
-+
-+#ifndef F_OPEN
-+# define F_OPEN(name, mode) fopen((name), (mode))
-+#endif
-+
-+ /* functions */
-+
-+#ifdef HAVE_STRERROR
-+ extern char *strerror OF((int));
-+# define zstrerror(errnum) strerror(errnum)
-+#else
-+# define zstrerror(errnum) ""
-+#endif
-+
-+#if defined(pyr)
-+# define NO_MEMCPY
-+#endif
-+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
-+ /* Use our own functions for small and medium model with MSC <= 5.0.
-+ * You may have to use the same strategy for Borland C (untested).
-+ * The __SC__ check is for Symantec.
-+ */
-+# define NO_MEMCPY
-+#endif
-+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
-+# define HAVE_MEMCPY
-+#endif
-+#ifdef HAVE_MEMCPY
-+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
-+# define zmemcpy _fmemcpy
-+# define zmemcmp _fmemcmp
-+# define zmemzero(dest, len) _fmemset(dest, 0, len)
-+# else
-+# define zmemcpy memcpy
-+# define zmemcmp memcmp
-+# define zmemzero(dest, len) memset(dest, 0, len)
-+# endif
-+#else
-+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
-+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
-+ extern void zmemzero OF((Bytef* dest, uInt len));
-+#endif
-+
-+/* Diagnostic functions */
-+#ifdef DEBUG
-+# include <stdio.h>
-+ extern int z_verbose;
-+ extern void z_error OF((char *m));
-+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
-+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
-+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
-+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
-+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
-+#else
-+# define Assert(cond,msg)
-+# define Trace(x)
-+# define Tracev(x)
-+# define Tracevv(x)
-+# define Tracec(c,x)
-+# define Tracecv(c,x)
-+#endif
-+
-+
-+typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
-+ uInt len));
-+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-+void zcfree OF((voidpf opaque, voidpf ptr));
-+
-+#define ZALLOC(strm, items, size) \
-+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
-+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
-+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
-+
-+#endif /* _Z_UTIL_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/Makefile.objs Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,21 @@
-+obj-y += satot.o
-+obj-y += addrtot.o
-+obj-y += ultot.o
-+obj-y += addrtypeof.o
-+obj-y += anyaddr.o
-+obj-y += initaddr.o
-+obj-y += ultoa.o
-+obj-y += addrtoa.o
-+obj-y += subnettoa.o
-+obj-y += subnetof.o
-+obj-y += goodmask.o
-+obj-y += datatot.o
-+obj-y += rangetoa.o
-+obj-y += prng.o
-+obj-y += pfkey_v2_parse.o
-+obj-y += pfkey_v2_build.o
-+obj-y += pfkey_v2_debug.o
-+obj-y += pfkey_v2_ext_bits.o
-+
-+#version.c: ${LIBFREESWANDIR}/version.in.c ${OPENSWANSRCDIR}/Makefile.ver
-+# sed '/"/s/xxx/$(IPSECVERSION)/' ${LIBFREESWANDIR}/version.in.c >$@
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/addrtoa.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,67 @@
-+/*
-+ * addresses to ASCII
-+ * Copyright (C) 1998, 1999 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+#define NBYTES 4 /* bytes in an address */
-+#define PERBYTE 4 /* three digits plus a dot or NUL */
-+#define BUFLEN (NBYTES*PERBYTE)
-+
-+#if BUFLEN != ADDRTOA_BUF
-+#error "ADDRTOA_BUF in openswan.h inconsistent with addrtoa() code"
-+#endif
-+
-+/*
-+ - addrtoa - convert binary address to ASCII dotted decimal
-+ */
-+size_t /* space needed for full conversion */
-+addrtoa(addr, format, dst, dstlen)
-+struct in_addr addr;
-+int format; /* character */
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ unsigned long a = ntohl(addr.s_addr);
-+ int i;
-+ size_t n;
-+ unsigned long byte;
-+ char buf[BUFLEN];
-+ char *p;
-+
-+ switch (format) {
-+ case 0:
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+
-+ p = buf;
-+ for (i = NBYTES-1; i >= 0; i--) {
-+ byte = (a >> (i*8)) & 0xff;
-+ p += ultoa(byte, 10, p, PERBYTE);
-+ if (i != 0)
-+ *(p-1) = '.';
-+ }
-+ n = p - buf;
-+
-+ if (dstlen > 0) {
-+ if (n > dstlen)
-+ buf[dstlen - 1] = '\0';
-+ strcpy(dst, buf);
-+ }
-+ return n;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/addrtot.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,334 @@
-+/*
-+ * addresses to text
-+ * Copyright (C) 2000 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+#define IP4BYTES 4 /* bytes in an IPv4 address */
-+#define PERBYTE 4 /* three digits plus a dot or NUL */
-+#define IP6BYTES 16 /* bytes in an IPv6 address */
-+
-+/* forwards */
-+static size_t normal4(const unsigned char *s, size_t len, char *b, char **dp);
-+static size_t normal6(const unsigned char *s, size_t len, char *b, char **dp, int squish);
-+static size_t reverse4(const unsigned char *s, size_t len, char *b, char **dp);
-+static size_t reverse6(const unsigned char *s, size_t len, char *b, char **dp);
-+
-+/*
-+ - addrtot - convert binary address to text (dotted decimal or IPv6 string)
-+ */
-+size_t /* space needed for full conversion */
-+addrtot(src, format, dst, dstlen)
-+const ip_address *src;
-+int format; /* character */
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ const unsigned char *b;
-+ size_t n;
-+ char buf[1+ADDRTOT_BUF+1]; /* :address: */
-+ char *p;
-+ int t = addrtypeof(src);
-+# define TF(t, f) (((t)<<8) | (f))
-+
-+ n = addrbytesptr(src, &b);
-+ if (n == 0) {
-+ bad:
-+ dst[0]='\0';
-+ strncat(dst, "<invalid>", dstlen);
-+ return sizeof("<invalid>");
-+ }
-+
-+ switch (TF(t, format)) {
-+ case TF(AF_INET, 0):
-+ n = normal4(b, n, buf, &p);
-+ break;
-+ case TF(AF_INET6, 0):
-+ n = normal6(b, n, buf, &p, 1);
-+ break;
-+ case TF(AF_INET, 'Q'):
-+ n = normal4(b, n, buf, &p);
-+ break;
-+ case TF(AF_INET6, 'Q'):
-+ n = normal6(b, n, buf, &p, 0);
-+ break;
-+ case TF(AF_INET, 'r'):
-+ n = reverse4(b, n, buf, &p);
-+ break;
-+ case TF(AF_INET6, 'r'):
-+ n = reverse6(b, n, buf, &p);
-+ break;
-+ default: /* including (AF_INET, 'R') */
-+ goto bad;
-+ break;
-+ }
-+
-+ if (dstlen > 0) {
-+ if (dstlen < n)
-+ p[dstlen - 1] = '\0';
-+ strcpy(dst, p);
-+ }
-+ return n;
-+}
-+
-+/*
-+ - normal4 - normal IPv4 address-text conversion
-+ */
-+static size_t /* size of text, including NUL */
-+normal4(srcp, srclen, buf, dstp)
-+const unsigned char *srcp;
-+size_t srclen;
-+char *buf; /* guaranteed large enough */
-+char **dstp; /* where to put result pointer */
-+{
-+ int i;
-+ char *p;
-+
-+ if (srclen != IP4BYTES) /* "can't happen" */
-+ return 0;
-+ p = buf;
-+ for (i = 0; i < IP4BYTES; i++) {
-+ p += ultot(srcp[i], 10, p, PERBYTE);
-+ if (i != IP4BYTES - 1)
-+ *(p-1) = '.'; /* overwrites the NUL */
-+ }
-+ *dstp = buf;
-+ return p - buf;
-+}
-+
-+/*
-+ - normal6 - normal IPv6 address-text conversion
-+ */
-+static size_t /* size of text, including NUL */
-+normal6(srcp, srclen, buf, dstp, squish)
-+const unsigned char *srcp;
-+size_t srclen;
-+char *buf; /* guaranteed large enough, plus 2 */
-+char **dstp; /* where to put result pointer */
-+int squish; /* whether to squish out 0:0 */
-+{
-+ int i;
-+ unsigned long piece;
-+ char *p;
-+ char *q;
-+
-+ if (srclen != IP6BYTES) /* "can't happen" */
-+ return 0;
-+ p = buf;
-+ *p++ = ':';
-+ for (i = 0; i < IP6BYTES/2; i++) {
-+ piece = (srcp[2*i] << 8) + srcp[2*i + 1];
-+ p += ultot(piece, 16, p, 5); /* 5 = abcd + NUL */
-+ *(p-1) = ':'; /* overwrites the NUL */
-+ }
-+ *p = '\0';
-+ q = strstr(buf, ":0:0:");
-+ if (squish && q != NULL) { /* zero squishing is possible */
-+ p = q + 1;
-+ while (*p == '0' && *(p+1) == ':')
-+ p += 2;
-+ q++;
-+ *q++ = ':'; /* overwrite first 0 */
-+ while (*p != '\0')
-+ *q++ = *p++;
-+ *q = '\0';
-+ if (!(*(q-1) == ':' && *(q-2) == ':'))
-+ *--q = '\0'; /* strip final : unless :: */
-+ p = buf;
-+ if (!(*p == ':' && *(p+1) == ':'))
-+ p++; /* skip initial : unless :: */
-+ } else {
-+ q = p;
-+ *--q = '\0'; /* strip final : */
-+ p = buf + 1; /* skip initial : */
-+ }
-+ *dstp = p;
-+ return q - p + 1;
-+}
-+
-+/*
-+ - reverse4 - IPv4 reverse-lookup conversion
-+ */
-+static size_t /* size of text, including NUL */
-+reverse4(srcp, srclen, buf, dstp)
-+const unsigned char *srcp;
-+size_t srclen;
-+char *buf; /* guaranteed large enough */
-+char **dstp; /* where to put result pointer */
-+{
-+ int i;
-+ char *p;
-+
-+ if (srclen != IP4BYTES) /* "can't happen" */
-+ return 0;
-+ p = buf;
-+ for (i = IP4BYTES-1; i >= 0; i--) {
-+ p += ultot(srcp[i], 10, p, PERBYTE);
-+ *(p-1) = '.'; /* overwrites the NUL */
-+ }
-+ strcpy(p, "IN-ADDR.ARPA.");
-+ *dstp = buf;
-+ return strlen(buf) + 1;
-+}
-+
-+/*
-+ - reverse6 - IPv6 reverse-lookup conversion (RFC 1886)
-+ * A trifle inefficient, really shouldn't use ultot...
-+ */
-+static size_t /* size of text, including NUL */
-+reverse6(srcp, srclen, buf, dstp)
-+const unsigned char *srcp;
-+size_t srclen;
-+char *buf; /* guaranteed large enough */
-+char **dstp; /* where to put result pointer */
-+{
-+ int i;
-+ unsigned long piece;
-+ char *p;
-+
-+ if (srclen != IP6BYTES) /* "can't happen" */
-+ return 0;
-+ p = buf;
-+ for (i = IP6BYTES-1; i >= 0; i--) {
-+ piece = srcp[i];
-+ p += ultot(piece&0xf, 16, p, 2);
-+ *(p-1) = '.';
-+ p += ultot(piece>>4, 16, p, 2);
-+ *(p-1) = '.';
-+ }
-+ strcpy(p, "IP6.ARPA.");
-+ *dstp = buf;
-+ return strlen(buf) + 1;
-+}
-+
-+/*
-+ - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874)
-+ * this version removed as it was obsoleted in the end.
-+ */
-+
-+#ifdef ADDRTOT_MAIN
-+
-+#include <stdio.h>
-+#include <sys/socket.h>
-+#include <netinet/in.h>
-+#include <arpa/inet.h>
-+
-+void regress(void);
-+
-+int
-+main(int argc, char *argv[])
-+{
-+ if (argc < 2) {
-+ fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n",
-+ argv[0]);
-+ exit(2);
-+ }
-+
-+ if (strcmp(argv[1], "-r") == 0) {
-+ regress();
-+ fprintf(stderr, "regress() returned?!?\n");
-+ exit(1);
-+ }
-+ exit(0);
-+}
-+
-+struct rtab {
-+ char *input;
-+ char format;
-+ char *output; /* NULL means error expected */
-+} rtab[] = {
-+ {"1.2.3.0", 0, "1.2.3.0"},
-+ {"1:2::3:4", 0, "1:2::3:4"},
-+ {"1:2::3:4", 'Q', "1:2:0:0:0:0:3:4"},
-+ {"1:2:0:0:3:4:0:0", 0, "1:2::3:4:0:0"},
-+ {"1.2.3.4", 'r' , "4.3.2.1.IN-ADDR.ARPA."},
-+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f */
-+ {"1:2::3:4", 'r', "4.0.0.0.3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.1.0.0.0.IP6.ARPA."},
-+ {NULL, 0, NULL}
-+};
-+
-+void
-+regress()
-+{
-+ struct rtab *r;
-+ int status = 0;
-+ ip_address a;
-+ char in[100];
-+ char buf[100];
-+ const char *oops;
-+ size_t n;
-+
-+ for (r = rtab; r->input != NULL; r++) {
-+ strcpy(in, r->input);
-+
-+ /* convert it *to* internal format */
-+ oops = ttoaddr(in, strlen(in), 0, &a);
-+
-+ /* now convert it back */
-+
-+ n = addrtot(&a, r->format, buf, sizeof(buf));
-+
-+ if (n == 0 && r->output == NULL)
-+ {} /* okay, error expected */
-+
-+ else if (n == 0) {
-+ printf("`%s' atoasr failed\n", r->input);
-+ status = 1;
-+
-+ } else if (r->output == NULL) {
-+ printf("`%s' atoasr succeeded unexpectedly '%c'\n",
-+ r->input, r->format);
-+ status = 1;
-+ } else {
-+ if (strcasecmp(r->output, buf) != 0) {
-+ printf("`%s' '%c' gave `%s', expected `%s'\n",
-+ r->input, r->format, buf, r->output);
-+ status = 1;
-+ }
-+ }
-+ }
-+ exit(status);
-+}
-+
-+#endif /* ADDRTOT_MAIN */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.15 2004/04/11 17:39:25 mcr
-+ * removed internal.h requirements.
-+ *
-+ * Revision 1.14 2004/03/08 01:59:08 ken
-+ * freeswan.h -> openswan.h
-+ *
-+ * Revision 1.13 2004/01/05 23:21:05 mcr
-+ * if the address type is invalid, then return length of <invalid>
-+ * string!
-+ *
-+ * Revision 1.12 2003/12/30 06:42:48 mcr
-+ * added $Log$
-+ * added Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * added Turn off EOLN_NATIVE flag
-+ * added
-+ * added (Logical change 1.5010)
-+ * added
-+ * added Revision 1.15 2004/04/11 17:39:25 mcr
-+ * added removed internal.h requirements.
-+ * added
-+ * added Revision 1.14 2004/03/08 01:59:08 ken
-+ * added freeswan.h -> openswan.h
-+ * added
-+ * added Revision 1.13 2004/01/05 23:21:05 mcr
-+ * added if the address type is invalid, then return length of <invalid>
-+ * added string!
-+ * added
-+ *
-+ *
-+ */
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/addrtypeof.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,93 @@
-+/*
-+ * extract parts of an ip_address
-+ * Copyright (C) 2000 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/*
-+ - addrtypeof - get the type of an ip_address
-+ */
-+int
-+addrtypeof(src)
-+const ip_address *src;
-+{
-+ return src->u.v4.sin_family;
-+}
-+
-+/*
-+ - addrbytesptr - get pointer to the address bytes of an ip_address
-+ */
-+size_t /* 0 for error */
-+addrbytesptr(src, dstp)
-+const ip_address *src;
-+const unsigned char **dstp; /* NULL means just a size query */
-+{
-+ const unsigned char *p;
-+ size_t n;
-+
-+ switch (src->u.v4.sin_family) {
-+ case AF_INET:
-+ p = (const unsigned char *)&src->u.v4.sin_addr.s_addr;
-+ n = 4;
-+ break;
-+ case AF_INET6:
-+ p = (const unsigned char *)&src->u.v6.sin6_addr;
-+ n = 16;
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+
-+ if (dstp != NULL)
-+ *dstp = p;
-+ return n;
-+}
-+
-+/*
-+ - addrlenof - get length of the address bytes of an ip_address
-+ */
-+size_t /* 0 for error */
-+addrlenof(src)
-+const ip_address *src;
-+{
-+ return addrbytesptr(src, NULL);
-+}
-+
-+/*
-+ - addrbytesof - get the address bytes of an ip_address
-+ */
-+size_t /* 0 for error */
-+addrbytesof(src, dst, dstlen)
-+const ip_address *src;
-+unsigned char *dst;
-+size_t dstlen;
-+{
-+ const unsigned char *p;
-+ size_t n;
-+ size_t ncopy;
-+
-+ n = addrbytesptr(src, &p);
-+ if (n == 0)
-+ return 0;
-+
-+ if (dstlen > 0) {
-+ ncopy = n;
-+ if (ncopy > dstlen)
-+ ncopy = dstlen;
-+ memcpy(dst, p, ncopy);
-+ }
-+ return n;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/anyaddr.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,145 @@
-+/*
-+ * special addresses
-+ * Copyright (C) 2000 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/* these are mostly fallbacks for the no-IPv6-support-in-library case */
-+#ifndef IN6ADDR_ANY_INIT
-+#define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
-+#endif
-+#ifndef IN6ADDR_LOOPBACK_INIT
-+#define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}
-+#endif
-+
-+static struct in6_addr v6any = IN6ADDR_ANY_INIT;
-+static struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT;
-+
-+/*
-+ - anyaddr - initialize to the any-address value
-+ */
-+err_t /* NULL for success, else string literal */
-+anyaddr(af, dst)
-+int af; /* address family */
-+ip_address *dst;
-+{
-+ uint32_t v4any = htonl(INADDR_ANY);
-+
-+ switch (af) {
-+ case AF_INET:
-+ return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst);
-+ break;
-+ case AF_INET6:
-+ return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst);
-+ break;
-+ default:
-+ return "unknown address family in anyaddr/unspecaddr";
-+ break;
-+ }
-+}
-+
-+/*
-+ - unspecaddr - initialize to the unspecified-address value
-+ */
-+err_t /* NULL for success, else string literal */
-+unspecaddr(af, dst)
-+int af; /* address family */
-+ip_address *dst;
-+{
-+ return anyaddr(af, dst);
-+}
-+
-+/*
-+ - loopbackaddr - initialize to the loopback-address value
-+ */
-+err_t /* NULL for success, else string literal */
-+loopbackaddr(af, dst)
-+int af; /* address family */
-+ip_address *dst;
-+{
-+ uint32_t v4loop = htonl(INADDR_LOOPBACK);
-+
-+ switch (af) {
-+ case AF_INET:
-+ return initaddr((unsigned char *)&v4loop, sizeof(v4loop), af, dst);
-+ break;
-+ case AF_INET6:
-+ return initaddr((unsigned char *)&v6loop, sizeof(v6loop), af, dst);
-+ break;
-+ default:
-+ return "unknown address family in loopbackaddr";
-+ break;
-+ }
-+}
-+
-+/*
-+ - isanyaddr - test for the any-address value
-+ */
-+int
-+isanyaddr(src)
-+const ip_address *src;
-+{
-+ uint32_t v4any = htonl(INADDR_ANY);
-+ int cmp;
-+
-+ switch (src->u.v4.sin_family) {
-+ case AF_INET:
-+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4any, sizeof(v4any));
-+ break;
-+ case AF_INET6:
-+ cmp = memcmp(&src->u.v6.sin6_addr, &v6any, sizeof(v6any));
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+
-+ return (cmp == 0) ? 1 : 0;
-+}
-+
-+/*
-+ - isunspecaddr - test for the unspecified-address value
-+ */
-+int
-+isunspecaddr(src)
-+const ip_address *src;
-+{
-+ return isanyaddr(src);
-+}
-+
-+/*
-+ - isloopbackaddr - test for the loopback-address value
-+ */
-+int
-+isloopbackaddr(src)
-+const ip_address *src;
-+{
-+ uint32_t v4loop = htonl(INADDR_LOOPBACK);
-+ int cmp;
-+
-+ switch (src->u.v4.sin_family) {
-+ case AF_INET:
-+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4loop, sizeof(v4loop));
-+ break;
-+ case AF_INET6:
-+ cmp = memcmp(&src->u.v6.sin6_addr, &v6loop, sizeof(v6loop));
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+
-+ return (cmp == 0) ? 1 : 0;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/datatot.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,232 @@
-+/*
-+ * convert from binary data (e.g. key) to text form
-+ * Copyright (C) 2000 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+static void convert(const char *src, size_t nreal, int format, char *out);
-+
-+/*
-+ - datatot - convert data bytes to text
-+ */
-+size_t /* true length (with NUL) for success */
-+datatot(src, srclen, format, dst, dstlen)
-+const char *src;
-+size_t srclen;
-+int format; /* character indicating what format */
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ size_t inblocksize; /* process this many bytes at a time */
-+ size_t outblocksize; /* producing this many */
-+ size_t breakevery; /* add a _ every this many (0 means don't) */
-+ size_t sincebreak; /* output bytes since last _ */
-+ char breakchar; /* character used to break between groups */
-+ char inblock[10]; /* enough for any format */
-+ char outblock[10]; /* enough for any format */
-+ char fake[1]; /* fake output area for dstlen == 0 */
-+ size_t needed; /* return value */
-+ char *stop; /* where the terminating NUL will go */
-+ size_t ntodo; /* remaining input */
-+ size_t nreal;
-+ char *out;
-+ char *prefix;
-+
-+ breakevery = 0;
-+ breakchar = '_';
-+
-+ switch (format) {
-+ case 0:
-+ case 'h':
-+ format = 'x';
-+ breakevery = 8;
-+ /* FALLTHROUGH */
-+ case 'x':
-+ inblocksize = 1;
-+ outblocksize = 2;
-+ prefix = "0x";
-+ break;
-+ case ':':
-+ format = 'x';
-+ breakevery = 2;
-+ breakchar = ':';
-+ /* FALLTHROUGH */
-+ case 16:
-+ inblocksize = 1;
-+ outblocksize = 2;
-+ prefix = "";
-+ format = 'x';
-+ break;
-+ case 's':
-+ inblocksize = 3;
-+ outblocksize = 4;
-+ prefix = "0s";
-+ break;
-+ case 64: /* beware, equals ' ' */
-+ inblocksize = 3;
-+ outblocksize = 4;
-+ prefix = "";
-+ format = 's';
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+ assert(inblocksize < sizeof(inblock));
-+ assert(outblocksize < sizeof(outblock));
-+ assert(breakevery % outblocksize == 0);
-+
-+ if (srclen == 0)
-+ return 0;
-+ ntodo = srclen;
-+
-+ if (dstlen == 0) { /* dispose of awkward special case */
-+ dst = fake;
-+ dstlen = 1;
-+ }
-+ stop = dst + dstlen - 1;
-+
-+ nreal = strlen(prefix);
-+ needed = nreal; /* for starters */
-+ if (dstlen <= nreal) { /* prefix won't fit */
-+ strncpy(dst, prefix, dstlen - 1);
-+ dst += dstlen - 1;
-+ } else {
-+ strcpy(dst, prefix);
-+ dst += nreal;
-+ }
-+ assert(dst <= stop);
-+ sincebreak = 0;
-+
-+ while (ntodo > 0) {
-+ if (ntodo < inblocksize) { /* incomplete input */
-+ memset(inblock, 0, sizeof(inblock));
-+ memcpy(inblock, src, ntodo);
-+ src = inblock;
-+ nreal = ntodo;
-+ ntodo = inblocksize;
-+ } else
-+ nreal = inblocksize;
-+ out = (outblocksize > stop - dst) ? outblock : dst;
-+
-+ convert(src, nreal, format, out);
-+ needed += outblocksize;
-+ sincebreak += outblocksize;
-+ if (dst < stop) {
-+ if (out != dst) {
-+ assert(outblocksize > stop - dst);
-+ memcpy(dst, out, stop - dst);
-+ dst = stop;
-+ } else
-+ dst += outblocksize;
-+ }
-+
-+ src += inblocksize;
-+ ntodo -= inblocksize;
-+ if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) {
-+ if (dst < stop)
-+ *dst++ = breakchar;
-+ needed++;
-+ sincebreak = 0;
-+ }
-+ }
-+
-+ assert(dst <= stop);
-+ *dst++ = '\0';
-+ needed++;
-+
-+ return needed;
-+}
-+
-+/*
-+ - convert - convert one input block to one output block
-+ */
-+static void
-+convert(src, nreal, format, out)
-+const char *src;
-+size_t nreal; /* how much of the input block is real */
-+int format;
-+char *out;
-+{
-+ static char hex[] = "0123456789abcdef";
-+ static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-+ "abcdefghijklmnopqrstuvwxyz"
-+ "0123456789+/";
-+ unsigned char c;
-+ unsigned char c1, c2, c3;
-+
-+ assert(nreal > 0);
-+ switch (format) {
-+ case 'x':
-+ assert(nreal == 1);
-+ c = (unsigned char)*src;
-+ *out++ = hex[c >> 4];
-+ *out++ = hex[c & 0xf];
-+ break;
-+ case 's':
-+ c1 = (unsigned char)*src++;
-+ c2 = (unsigned char)*src++;
-+ c3 = (unsigned char)*src++;
-+ *out++ = base64[c1 >> 2]; /* top 6 bits of c1 */
-+ c = (c1 & 0x3) << 4; /* bottom 2 of c1... */
-+ c |= c2 >> 4; /* ...top 4 of c2 */
-+ *out++ = base64[c];
-+ if (nreal == 1)
-+ *out++ = '=';
-+ else {
-+ c = (c2 & 0xf) << 2; /* bottom 4 of c2... */
-+ c |= c3 >> 6; /* ...top 2 of c3 */
-+ *out++ = base64[c];
-+ }
-+ if (nreal <= 2)
-+ *out++ = '=';
-+ else
-+ *out++ = base64[c3 & 0x3f]; /* bottom 6 of c3 */
-+ break;
-+ default:
-+ assert(nreal == 0); /* unknown format */
-+ break;
-+ }
-+}
-+
-+/*
-+ - datatoa - convert data to ASCII
-+ * backward-compatibility synonym for datatot
-+ */
-+size_t /* true length (with NUL) for success */
-+datatoa(src, srclen, format, dst, dstlen)
-+const char *src;
-+size_t srclen;
-+int format; /* character indicating what format */
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ return datatot(src, srclen, format, dst, dstlen);
-+}
-+
-+/*
-+ - bytestoa - convert data bytes to ASCII
-+ * backward-compatibility synonym for datatot
-+ */
-+size_t /* true length (with NUL) for success */
-+bytestoa(src, srclen, format, dst, dstlen)
-+const char *src;
-+size_t srclen;
-+int format; /* character indicating what format */
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ return datatot(src, srclen, format, dst, dstlen);
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/goodmask.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,100 @@
-+/*
-+ * minor utilities for subnet-mask manipulation
-+ * Copyright (C) 1998, 1999 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+#ifndef ABITS
-+#define ABITS 32 /* bits in an IPv4 address */
-+#endif
-+
-+/*
-+ - goodmask - is this a good (^1*0*$) subnet mask?
-+ * You are not expected to understand this. See Henry S. Warren Jr,
-+ * "Functions realizable with word-parallel logical and two's-complement
-+ * addition instructions", CACM 20.6 (June 1977), p.439.
-+ */
-+int /* predicate */
-+goodmask(mask)
-+struct in_addr mask;
-+{
-+ unsigned long x = ntohl(mask.s_addr);
-+ /* clear rightmost contiguous string of 1-bits */
-+# define CRCS1B(x) (((x|(x-1))+1)&x)
-+# define TOPBIT (1UL << 31)
-+
-+ /* either zero, or has one string of 1-bits which is left-justified */
-+ if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT)))
-+ return 1;
-+ return 0;
-+}
-+
-+/*
-+ - masktobits - how many bits in this mask?
-+ * The algorithm is essentially a binary search, but highly optimized
-+ * for this particular task.
-+ */
-+int /* -1 means !goodmask() */
-+masktobits(mask)
-+struct in_addr mask;
-+{
-+ unsigned long m = ntohl(mask.s_addr);
-+ int masklen;
-+
-+ if (!goodmask(mask))
-+ return -1;
-+
-+ if (m&0x00000001UL)
-+ return 32;
-+ masklen = 0;
-+ if (m&(0x0000ffffUL<<1)) { /* <<1 for 1-origin numbering */
-+ masklen |= 0x10;
-+ m <<= 16;
-+ }
-+ if (m&(0x00ff0000UL<<1)) {
-+ masklen |= 0x08;
-+ m <<= 8;
-+ }
-+ if (m&(0x0f000000UL<<1)) {
-+ masklen |= 0x04;
-+ m <<= 4;
-+ }
-+ if (m&(0x30000000UL<<1)) {
-+ masklen |= 0x02;
-+ m <<= 2;
-+ }
-+ if (m&(0x40000000UL<<1))
-+ masklen |= 0x01;
-+
-+ return masklen;
-+}
-+
-+/*
-+ - bitstomask - return a mask with this many high bits on
-+ */
-+struct in_addr
-+bitstomask(n)
-+int n;
-+{
-+ struct in_addr result;
-+
-+ if (n > 0 && n <= ABITS)
-+ result.s_addr = htonl(~((1UL << (ABITS - n)) - 1));
-+ else if (n == 0)
-+ result.s_addr = 0;
-+ else
-+ result.s_addr = 0; /* best error report we can do */
-+ return result;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/initaddr.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,50 @@
-+/*
-+ * initialize address structure
-+ * Copyright (C) 2000 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/*
-+ - initaddr - initialize ip_address from bytes
-+ */
-+err_t /* NULL for success, else string literal */
-+initaddr(src, srclen, af, dst)
-+const unsigned char *src;
-+size_t srclen;
-+int af; /* address family */
-+ip_address *dst;
-+{
-+ switch (af) {
-+ case AF_INET:
-+ if (srclen != 4)
-+ return "IPv4 address must be exactly 4 bytes";
-+ dst->u.v4.sin_family = af;
-+ dst->u.v4.sin_port = 0; /* unused */
-+ memcpy((char *)&dst->u.v4.sin_addr.s_addr, src, srclen);
-+ break;
-+ case AF_INET6:
-+ if (srclen != 16)
-+ return "IPv6 address must be exactly 16 bytes";
-+ dst->u.v6.sin6_family = af;
-+ dst->u.v6.sin6_flowinfo = 0; /* unused */
-+ dst->u.v6.sin6_port = 0; /* unused */
-+ memcpy((char *)&dst->u.v6.sin6_addr, src, srclen);
-+ break;
-+ default:
-+ return "unknown address family in initaddr";
-+ break;
-+ }
-+ return NULL;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/pfkey_v2_build.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1559 @@
-+/*
-+ * RFC2367 PF_KEYv2 Key management API message parser
-+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
-+ */
-+
-+char pfkey_v2_build_c_version[] = "$Id$";
-+
-+/*
-+ * Some ugly stuff to allow consistent debugging code for use in the
-+ * kernel and in user space
-+*/
-+
-+#ifdef __KERNEL__
-+
-+# include <linux/kernel.h> /* for printk */
-+
-+# include "openswan/ipsec_kversion.h" /* for malloc switch */
-+# ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+# else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+# endif /* MALLOC_SLAB */
-+# include <linux/errno.h> /* error codes */
-+# include <linux/types.h> /* size_t */
-+# include <linux/interrupt.h> /* mark_bh */
-+
-+# include <linux/netdevice.h> /* struct device, and other headers */
-+# include <linux/etherdevice.h> /* eth_type_trans */
-+# include <linux/ip.h> /* struct iphdr */
-+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+# include <linux/ipv6.h> /* struct ipv6hdr */
-+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
-+
-+# define MALLOC(size) kmalloc(size, GFP_ATOMIC)
-+# define FREE(obj) kfree(obj)
-+# include <openswan.h>
-+#else /* __KERNEL__ */
-+
-+# include <sys/types.h>
-+# include <linux/types.h>
-+# include <linux/errno.h>
-+# include <malloc.h>
-+# include <string.h> /* memset */
-+
-+# include <openswan.h>
-+
-+#endif /* __KERNEL__ */
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#ifdef __KERNEL__
-+#include "openswan/radij.h" /* rd_nodes */
-+#include "openswan/ipsec_encap.h" /* sockaddr_encap */
-+#endif /* __KERNEL__ */
-+
-+
-+#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
-+#include "openswan/pfkey_debug.h"
-+
-+
-+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
-+
-+void
-+pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
-+{
-+ int i;
-+
-+ for (i = 0; i != SADB_EXT_MAX + 1; i++) {
-+ extensions[i] = NULL;
-+ }
-+}
-+
-+void
-+pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
-+{
-+ int i;
-+
-+ if(!extensions) {
-+ return;
-+ }
-+
-+ if(extensions[0]) {
-+ memset(extensions[0], 0, sizeof(struct sadb_msg));
-+ FREE(extensions[0]);
-+ extensions[0] = NULL;
-+ }
-+
-+ for (i = 1; i != SADB_EXT_MAX + 1; i++) {
-+ if(extensions[i]) {
-+ memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
-+ FREE(extensions[i]);
-+ extensions[i] = NULL;
-+ }
-+ }
-+}
-+
-+void
-+pfkey_msg_free(struct sadb_msg **pfkey_msg)
-+{
-+ if(*pfkey_msg) {
-+ memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
-+ FREE(*pfkey_msg);
-+ *pfkey_msg = NULL;
-+ }
-+}
-+
-+/* Default extension builders taken from the KLIPS code */
-+
-+int
-+pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
-+ uint8_t msg_type,
-+ uint8_t satype,
-+ uint8_t msg_errno,
-+ uint32_t seq,
-+ uint32_t pid)
-+{
-+ int error = 0;
-+ struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_hdr_build:\n");
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_hdr_build: "
-+ "on_entry &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
-+ &pfkey_ext,
-+ pfkey_ext,
-+ *pfkey_ext);
-+ /* sanity checks... */
-+ if(pfkey_msg) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_hdr_build: "
-+ "why is pfkey_msg already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!msg_type) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_hdr_build: "
-+ "msg type not set, must be non-zero..\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(msg_type > SADB_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_hdr_build: "
-+ "msg type too large:%d.\n",
-+ msg_type);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(satype > SADB_SATYPE_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_hdr_build: "
-+ "satype %d > max %d\n",
-+ satype, SADB_SATYPE_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_msg = (struct sadb_msg*)
-+ MALLOC(sizeof(struct sadb_msg)))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_hdr_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_msg, 0, sizeof(struct sadb_msg));
-+
-+ pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
-+
-+ pfkey_msg->sadb_msg_type = msg_type;
-+ pfkey_msg->sadb_msg_satype = satype;
-+
-+ pfkey_msg->sadb_msg_version = PF_KEY_V2;
-+ pfkey_msg->sadb_msg_errno = msg_errno;
-+ pfkey_msg->sadb_msg_reserved = 0;
-+ pfkey_msg->sadb_msg_seq = seq;
-+ pfkey_msg->sadb_msg_pid = pid;
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_hdr_build: "
-+ "on_exit &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
-+ &pfkey_ext,
-+ pfkey_ext,
-+ *pfkey_ext);
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext,
-+ uint16_t exttype,
-+ uint32_t spi,
-+ uint8_t replay_window,
-+ uint8_t sa_state,
-+ uint8_t auth,
-+ uint8_t encrypt,
-+ uint32_t flags,
-+ uint32_t/*IPsecSAref_t*/ ref)
-+{
-+ int error = 0;
-+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n",
-+ ntohl(spi), /* in network order */
-+ replay_window,
-+ sa_state,
-+ auth,
-+ encrypt,
-+ flags);
-+ /* sanity checks... */
-+ if(pfkey_sa) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "why is pfkey_sa already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(exttype != SADB_EXT_SA &&
-+ exttype != SADB_X_EXT_SA2) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "invalid exttype=%d.\n",
-+ exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(replay_window > 64) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "replay window size: %d -- must be 0 <= size <= 64\n",
-+ replay_window);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(auth > SADB_AALG_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "auth=%d > SADB_AALG_MAX=%d.\n",
-+ auth,
-+ SADB_AALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(encrypt > SADB_EALG_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "encrypt=%d > SADB_EALG_MAX=%d.\n",
-+ encrypt,
-+ SADB_EALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(sa_state > SADB_SASTATE_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "sa_state=%d exceeds MAX=%d.\n",
-+ sa_state,
-+ SADB_SASTATE_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(sa_state == SADB_SASTATE_DEAD) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "sa_state=%d is DEAD=%d is not allowed.\n",
-+ sa_state,
-+ SADB_SASTATE_DEAD);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if((IPSEC_SAREF_NULL != ref) && (ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
-+ ref,
-+ IPSEC_SAREF_NULL,
-+ IPSEC_SA_REF_TABLE_NUM_ENTRIES);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_sa = (struct sadb_sa*)
-+ MALLOC(sizeof(struct sadb_sa)))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_sa, 0, sizeof(struct sadb_sa));
-+
-+ pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN;
-+ pfkey_sa->sadb_sa_exttype = exttype;
-+ pfkey_sa->sadb_sa_spi = spi;
-+ pfkey_sa->sadb_sa_replay = replay_window;
-+ pfkey_sa->sadb_sa_state = sa_state;
-+ pfkey_sa->sadb_sa_auth = auth;
-+ pfkey_sa->sadb_sa_encrypt = encrypt;
-+ pfkey_sa->sadb_sa_flags = flags;
-+ pfkey_sa->sadb_x_sa_ref = ref;
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_sa_build(struct sadb_ext ** pfkey_ext,
-+ uint16_t exttype,
-+ uint32_t spi,
-+ uint8_t replay_window,
-+ uint8_t sa_state,
-+ uint8_t auth,
-+ uint8_t encrypt,
-+ uint32_t flags)
-+{
-+ return pfkey_sa_ref_build(pfkey_ext,
-+ exttype,
-+ spi,
-+ replay_window,
-+ sa_state,
-+ auth,
-+ encrypt,
-+ flags,
-+ IPSEC_SAREF_NULL);
-+}
-+
-+int
-+pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
-+ uint16_t exttype,
-+ uint32_t allocations,
-+ uint64_t bytes,
-+ uint64_t addtime,
-+ uint64_t usetime,
-+ uint32_t packets)
-+{
-+ int error = 0;
-+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_lifetime_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_lifetime) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_lifetime_build: "
-+ "why is pfkey_lifetime already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(exttype != SADB_EXT_LIFETIME_CURRENT &&
-+ exttype != SADB_EXT_LIFETIME_HARD &&
-+ exttype != SADB_EXT_LIFETIME_SOFT) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_lifetime_build: "
-+ "invalid exttype=%d.\n",
-+ exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_lifetime = (struct sadb_lifetime*)
-+ MALLOC(sizeof(struct sadb_lifetime)))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_lifetime_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime));
-+
-+ pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN;
-+ pfkey_lifetime->sadb_lifetime_exttype = exttype;
-+ pfkey_lifetime->sadb_lifetime_allocations = allocations;
-+ pfkey_lifetime->sadb_lifetime_bytes = bytes;
-+ pfkey_lifetime->sadb_lifetime_addtime = addtime;
-+ pfkey_lifetime->sadb_lifetime_usetime = usetime;
-+ pfkey_lifetime->sadb_x_lifetime_packets = packets;
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_address_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint8_t proto,
-+ uint8_t prefixlen,
-+ struct sockaddr* address)
-+{
-+ int error = 0;
-+ int saddr_len = 0;
-+ char ipaddr_txt[ADDRTOT_BUF + 6/*extra for port number*/];
-+ struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_address_build: "
-+ "exttype=%d proto=%d prefixlen=%d\n",
-+ exttype,
-+ proto,
-+ prefixlen);
-+ /* sanity checks... */
-+ if(pfkey_address) {
-+ ERROR("pfkey_address_build: "
-+ "why is pfkey_address already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if (!address) {
-+ ERROR("pfkey_address_build: " "address is NULL\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(exttype) {
-+ case SADB_EXT_ADDRESS_SRC:
-+ case SADB_EXT_ADDRESS_DST:
-+ case SADB_EXT_ADDRESS_PROXY:
-+ case SADB_X_EXT_ADDRESS_DST2:
-+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
-+ case SADB_X_EXT_ADDRESS_DST_FLOW:
-+ case SADB_X_EXT_ADDRESS_SRC_MASK:
-+ case SADB_X_EXT_ADDRESS_DST_MASK:
-+#ifdef NAT_TRAVERSAL
-+ case SADB_X_EXT_NAT_T_OA:
-+#endif
-+ break;
-+ default:
-+ ERROR("pfkey_address_build: "
-+ "unrecognised ext_type=%d.\n",
-+ exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(address->sa_family) {
-+ case AF_INET:
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_address_build: "
-+ "found address family AF_INET.\n");
-+ saddr_len = sizeof(struct sockaddr_in);
-+ sprintf(ipaddr_txt, "%d.%d.%d.%d:%d"
-+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 0) & 0xFF
-+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 8) & 0xFF
-+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF
-+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF
-+ , ntohs(((struct sockaddr_in*)address)->sin_port));
-+ break;
-+ case AF_INET6:
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_address_build: "
-+ "found address family AF_INET6.\n");
-+ saddr_len = sizeof(struct sockaddr_in6);
-+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x"
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0])
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1])
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2])
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3])
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4])
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5])
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6])
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7])
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_port));
-+ break;
-+ default:
-+ ERROR("pfkey_address_build: "
-+ "address->sa_family=%d not supported.\n",
-+ address->sa_family);
-+ SENDERR(EPFNOSUPPORT);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_address_build: "
-+ "found address=%s.\n",
-+ ipaddr_txt);
-+ if(prefixlen != 0) {
-+ ERROR("pfkey_address_build: "
-+ "address prefixes not supported yet.\n");
-+ SENDERR(EAFNOSUPPORT); /* not supported yet */
-+ }
-+
-+ /* allocate some memory for the extension */
-+ pfkey_address = (struct sadb_address*)
-+ MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN));
-+ *pfkey_ext = (struct sadb_ext*)pfkey_address;
-+
-+ if(pfkey_address == NULL ) {
-+ ERROR("pfkey_lifetime_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_address,
-+ 0,
-+ ALIGN_N(sizeof(struct sadb_address) + saddr_len,
-+ IPSEC_PFKEYv2_ALIGN));
-+
-+ pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len,
-+ IPSEC_PFKEYv2_ALIGN);
-+
-+ pfkey_address->sadb_address_exttype = exttype;
-+ pfkey_address->sadb_address_proto = proto;
-+ pfkey_address->sadb_address_prefixlen = prefixlen;
-+ pfkey_address->sadb_address_reserved = 0;
-+
-+ memcpy((char*)pfkey_address + sizeof(struct sadb_address),
-+ address,
-+ saddr_len);
-+
-+#if 0
-+ for(i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) {
-+ pfkey_address_s_ska.sin_zero[i] = 0;
-+ }
-+#endif
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_address_build: "
-+ "successful created len: %d.\n", pfkey_address->sadb_address_len);
-+
-+ errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_key_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint16_t key_bits,
-+ char* key)
-+{
-+ int error = 0;
-+ struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_key_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_key) {
-+ ERROR("pfkey_key_build: "
-+ "why is pfkey_key already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!key_bits) {
-+ ERROR("pfkey_key_build: "
-+ "key_bits is zero, it must be non-zero.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) {
-+ ERROR("pfkey_key_build: "
-+ "unsupported extension type=%d.\n",
-+ exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_key = (struct sadb_key*)
-+ MALLOC(sizeof(struct sadb_key) +
-+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN))) {
-+ ERROR("pfkey_key_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_key,
-+ 0,
-+ sizeof(struct sadb_key) +
-+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
-+
-+ pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN + key_bits,
-+ 64);
-+ pfkey_key->sadb_key_exttype = exttype;
-+ pfkey_key->sadb_key_bits = key_bits;
-+ pfkey_key->sadb_key_reserved = 0;
-+ memcpy((char*)pfkey_key + sizeof(struct sadb_key),
-+ key,
-+ DIVUP(key_bits, 8));
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_ident_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint16_t ident_type,
-+ uint64_t ident_id,
-+ uint8_t ident_len,
-+ char* ident_string)
-+{
-+ int error = 0;
-+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext;
-+ int data_len = ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_ident_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_ident) {
-+ ERROR("pfkey_ident_build: "
-+ "why is pfkey_ident already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if( ! ((exttype == SADB_EXT_IDENTITY_SRC) ||
-+ (exttype == SADB_EXT_IDENTITY_DST))) {
-+ ERROR("pfkey_ident_build: "
-+ "unsupported extension type=%d.\n",
-+ exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if((ident_type == SADB_IDENTTYPE_RESERVED)) {
-+ ERROR("pfkey_ident_build: "
-+ "ident_type must be non-zero.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(ident_type > SADB_IDENTTYPE_MAX) {
-+ ERROR("pfkey_ident_build: "
-+ "identtype=%d out of range.\n",
-+ ident_type);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(((ident_type == SADB_IDENTTYPE_PREFIX) ||
-+ (ident_type == SADB_IDENTTYPE_FQDN)) &&
-+ !ident_string) {
-+ ERROR("pfkey_ident_build: "
-+ "string required to allocate size of extension.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+#if 0
-+ if((ident_type == SADB_IDENTTYPE_USERFQDN) ) {
-+ }
-+#endif
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_ident = (struct sadb_ident*)
-+ MALLOC(ident_len * IPSEC_PFKEYv2_ALIGN))) {
-+ ERROR("pfkey_ident_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_ident, 0, ident_len * IPSEC_PFKEYv2_ALIGN);
-+
-+ pfkey_ident->sadb_ident_len = ident_len;
-+ pfkey_ident->sadb_ident_exttype = exttype;
-+ pfkey_ident->sadb_ident_type = ident_type;
-+ pfkey_ident->sadb_ident_reserved = 0;
-+ pfkey_ident->sadb_ident_id = ident_id;
-+ memcpy((char*)pfkey_ident + sizeof(struct sadb_ident),
-+ ident_string,
-+ data_len);
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_sens_build(struct sadb_ext** pfkey_ext,
-+ uint32_t dpd,
-+ uint8_t sens_level,
-+ uint8_t sens_len,
-+ uint64_t* sens_bitmap,
-+ uint8_t integ_level,
-+ uint8_t integ_len,
-+ uint64_t* integ_bitmap)
-+{
-+ int error = 0;
-+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext;
-+ int i;
-+ uint64_t* bitmap;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sens_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_sens) {
-+ ERROR("pfkey_sens_build: "
-+ "why is pfkey_sens already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sens_build: "
-+ "Sorry, I can't build exttype=%d yet.\n",
-+ (*pfkey_ext)->sadb_ext_type);
-+ SENDERR(EINVAL); /* don't process these yet */
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_sens = (struct sadb_sens*)
-+ MALLOC(sizeof(struct sadb_sens) +
-+ (sens_len + integ_len) * sizeof(uint64_t)))) {
-+ ERROR("pfkey_sens_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_sens,
-+ 0,
-+ sizeof(struct sadb_sens) +
-+ (sens_len + integ_len) * sizeof(uint64_t));
-+
-+ pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) +
-+ (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN;
-+ pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY;
-+ pfkey_sens->sadb_sens_dpd = dpd;
-+ pfkey_sens->sadb_sens_sens_level = sens_level;
-+ pfkey_sens->sadb_sens_sens_len = sens_len;
-+ pfkey_sens->sadb_sens_integ_level = integ_level;
-+ pfkey_sens->sadb_sens_integ_len = integ_len;
-+ pfkey_sens->sadb_sens_reserved = 0;
-+
-+ bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens));
-+ for(i = 0; i < sens_len; i++) {
-+ *bitmap = sens_bitmap[i];
-+ bitmap++;
-+ }
-+ for(i = 0; i < integ_len; i++) {
-+ *bitmap = integ_bitmap[i];
-+ bitmap++;
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_prop_build(struct sadb_ext** pfkey_ext,
-+ uint8_t replay,
-+ unsigned int comb_num,
-+ struct sadb_comb* comb)
-+{
-+ int error = 0;
-+ int i;
-+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext;
-+ struct sadb_comb *combp;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_prop_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_prop) {
-+ ERROR("pfkey_prop_build: "
-+ "why is pfkey_prop already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_prop = (struct sadb_prop*)
-+ MALLOC(sizeof(struct sadb_prop) +
-+ comb_num * sizeof(struct sadb_comb)))) {
-+ ERROR("pfkey_prop_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_prop,
-+ 0,
-+ sizeof(struct sadb_prop) +
-+ comb_num * sizeof(struct sadb_comb));
-+
-+ pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
-+ comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN;
-+
-+ pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
-+ pfkey_prop->sadb_prop_replay = replay;
-+
-+ for(i=0; i<3; i++) {
-+ pfkey_prop->sadb_prop_reserved[i] = 0;
-+ }
-+
-+ combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop));
-+ for(i = 0; i < comb_num; i++) {
-+ memcpy (combp, &(comb[i]), sizeof(struct sadb_comb));
-+ combp++;
-+ }
-+
-+#if 0
-+ uint8_t sadb_comb_auth;
-+ uint8_t sadb_comb_encrypt;
-+ uint16_t sadb_comb_flags;
-+ uint16_t sadb_comb_auth_minbits;
-+ uint16_t sadb_comb_auth_maxbits;
-+ uint16_t sadb_comb_encrypt_minbits;
-+ uint16_t sadb_comb_encrypt_maxbits;
-+ uint32_t sadb_comb_reserved;
-+ uint32_t sadb_comb_soft_allocations;
-+ uint32_t sadb_comb_hard_allocations;
-+ uint64_t sadb_comb_soft_bytes;
-+ uint64_t sadb_comb_hard_bytes;
-+ uint64_t sadb_comb_soft_addtime;
-+ uint64_t sadb_comb_hard_addtime;
-+ uint64_t sadb_comb_soft_usetime;
-+ uint64_t sadb_comb_hard_usetime;
-+ uint32_t sadb_comb_soft_packets;
-+ uint32_t sadb_comb_hard_packets;
-+#endif
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_supported_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ unsigned int alg_num,
-+ struct sadb_alg* alg)
-+{
-+ int error = 0;
-+ unsigned int i;
-+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext;
-+ struct sadb_alg *pfkey_alg;
-+
-+ /* sanity checks... */
-+ if(pfkey_supported) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_supported_build: "
-+ "why is pfkey_supported already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_supported_build: "
-+ "unsupported extension type=%d.\n",
-+ exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_supported = (struct sadb_supported*)
-+ MALLOC(sizeof(struct sadb_supported) +
-+ alg_num *
-+ sizeof(struct sadb_alg)))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_supported_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_supported,
-+ 0,
-+ sizeof(struct sadb_supported) +
-+ alg_num *
-+ sizeof(struct sadb_alg));
-+
-+ pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) +
-+ alg_num *
-+ sizeof(struct sadb_alg)) /
-+ IPSEC_PFKEYv2_ALIGN;
-+ pfkey_supported->sadb_supported_exttype = exttype;
-+ pfkey_supported->sadb_supported_reserved = 0;
-+
-+ pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported));
-+ for(i = 0; i < alg_num; i++) {
-+ memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg));
-+ pfkey_alg->sadb_alg_reserved = 0;
-+ pfkey_alg++;
-+ }
-+
-+#if 0
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_supported_build: "
-+ "Sorry, I can't build exttype=%d yet.\n",
-+ (*pfkey_ext)->sadb_ext_type);
-+ SENDERR(EINVAL); /* don't process these yet */
-+
-+ uint8_t sadb_alg_id;
-+ uint8_t sadb_alg_ivlen;
-+ uint16_t sadb_alg_minbits;
-+ uint16_t sadb_alg_maxbits;
-+ uint16_t sadb_alg_reserved;
-+#endif
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_spirange_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint32_t min, /* in network order */
-+ uint32_t max) /* in network order */
-+{
-+ int error = 0;
-+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext;
-+
-+ /* sanity checks... */
-+ if(pfkey_spirange) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_spirange_build: "
-+ "why is pfkey_spirange already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(ntohl(max) < ntohl(min)) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_spirange_build: "
-+ "minspi=%08x must be < maxspi=%08x.\n",
-+ ntohl(min),
-+ ntohl(max));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(ntohl(min) <= 255) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_spirange_build: "
-+ "minspi=%08x must be > 255.\n",
-+ ntohl(min));
-+ SENDERR(EEXIST);
-+ }
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_spirange = (struct sadb_spirange*)
-+ MALLOC(sizeof(struct sadb_spirange)))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_spirange_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_spirange,
-+ 0,
-+ sizeof(struct sadb_spirange));
-+
-+ pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN;
-+
-+ pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
-+ pfkey_spirange->sadb_spirange_min = min;
-+ pfkey_spirange->sadb_spirange_max = max;
-+ pfkey_spirange->sadb_spirange_reserved = 0;
-+ errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext;
-+
-+ /* sanity checks... */
-+ if(pfkey_x_kmprivate) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_kmprivate_build: "
-+ "why is pfkey_x_kmprivate already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_kmprivate_build: "
-+ "Sorry, I can't build exttype=%d yet.\n",
-+ (*pfkey_ext)->sadb_ext_type);
-+ SENDERR(EINVAL); /* don't process these yet */
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_x_kmprivate = (struct sadb_x_kmprivate*)
-+ MALLOC(sizeof(struct sadb_x_kmprivate)))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_kmprivate_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_x_kmprivate,
-+ 0,
-+ sizeof(struct sadb_x_kmprivate));
-+
-+ pfkey_x_kmprivate->sadb_x_kmprivate_len =
-+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN;
-+
-+ pfkey_x_kmprivate->sadb_x_kmprivate_exttype = SADB_X_EXT_KMPRIVATE;
-+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
-+ uint8_t satype)
-+{
-+ int error = 0;
-+ int i;
-+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_satype_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_x_satype) {
-+ ERROR("pfkey_x_satype_build: "
-+ "why is pfkey_x_satype already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!satype) {
-+ ERROR("pfkey_x_satype_build: "
-+ "SA type not set, must be non-zero.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(satype > SADB_SATYPE_MAX) {
-+ ERROR("pfkey_x_satype_build: "
-+ "satype %d > max %d\n",
-+ satype, SADB_SATYPE_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_satype = (struct sadb_x_satype*)
-+ MALLOC(sizeof(struct sadb_x_satype)))) {
-+ ERROR("pfkey_x_satype_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_x_satype,
-+ 0,
-+ sizeof(struct sadb_x_satype));
-+
-+ pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN;
-+
-+ pfkey_x_satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2;
-+ pfkey_x_satype->sadb_x_satype_satype = satype;
-+ for(i=0; i<3; i++) {
-+ pfkey_x_satype->sadb_x_satype_reserved[i] = 0;
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
-+ uint32_t tunnel,
-+ uint32_t netlink,
-+ uint32_t xform,
-+ uint32_t eroute,
-+ uint32_t spi,
-+ uint32_t radij,
-+ uint32_t esp,
-+ uint32_t ah,
-+ uint32_t rcv,
-+ uint32_t pfkey,
-+ uint32_t ipcomp,
-+ uint32_t verbose)
-+{
-+ int error = 0;
-+ int i;
-+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_debug_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_x_debug) {
-+ ERROR("pfkey_x_debug_build: "
-+ "why is pfkey_x_debug already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_debug_build: "
-+ "tunnel=%x netlink=%x xform=%x eroute=%x spi=%x radij=%x esp=%x ah=%x rcv=%x pfkey=%x ipcomp=%x verbose=%x?\n",
-+ tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose);
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_debug = (struct sadb_x_debug*)
-+ MALLOC(sizeof(struct sadb_x_debug)))) {
-+ ERROR("pfkey_x_debug_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+#if 0
-+ memset(pfkey_x_debug,
-+ 0,
-+ sizeof(struct sadb_x_debug));
-+#endif
-+
-+ pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN;
-+ pfkey_x_debug->sadb_x_debug_exttype = SADB_X_EXT_DEBUG;
-+
-+ pfkey_x_debug->sadb_x_debug_tunnel = tunnel;
-+ pfkey_x_debug->sadb_x_debug_netlink = netlink;
-+ pfkey_x_debug->sadb_x_debug_xform = xform;
-+ pfkey_x_debug->sadb_x_debug_eroute = eroute;
-+ pfkey_x_debug->sadb_x_debug_spi = spi;
-+ pfkey_x_debug->sadb_x_debug_radij = radij;
-+ pfkey_x_debug->sadb_x_debug_esp = esp;
-+ pfkey_x_debug->sadb_x_debug_ah = ah;
-+ pfkey_x_debug->sadb_x_debug_rcv = rcv;
-+ pfkey_x_debug->sadb_x_debug_pfkey = pfkey;
-+ pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp;
-+ pfkey_x_debug->sadb_x_debug_verbose = verbose;
-+
-+ for(i=0; i<4; i++) {
-+ pfkey_x_debug->sadb_x_debug_reserved[i] = 0;
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
-+ uint8_t type)
-+{
-+ int error = 0;
-+ int i;
-+ struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_nat_t_type_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_x_nat_t_type) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_nat_t_type_build: "
-+ "why is pfkey_x_nat_t_type already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_nat_t_type_build: "
-+ "type=%d\n", type);
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_type = (struct sadb_x_nat_t_type*)
-+ MALLOC(sizeof(struct sadb_x_nat_t_type)))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_nat_t_type_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+
-+ pfkey_x_nat_t_type->sadb_x_nat_t_type_len = sizeof(struct sadb_x_nat_t_type) / IPSEC_PFKEYv2_ALIGN;
-+ pfkey_x_nat_t_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
-+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type = type;
-+ for(i=0; i<3; i++) {
-+ pfkey_x_nat_t_type->sadb_x_nat_t_type_reserved[i] = 0;
-+ }
-+
-+errlab:
-+ return error;
-+}
-+int
-+pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint16_t port)
-+{
-+ int error = 0;
-+ struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_nat_t_port_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_x_nat_t_port) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_nat_t_port_build: "
-+ "why is pfkey_x_nat_t_port already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(exttype) {
-+ case SADB_X_EXT_NAT_T_SPORT:
-+ case SADB_X_EXT_NAT_T_DPORT:
-+ break;
-+ default:
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_nat_t_port_build: "
-+ "unrecognised ext_type=%d.\n",
-+ exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_nat_t_port_build: "
-+ "ext=%d, port=%d\n", exttype, port);
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_port = (struct sadb_x_nat_t_port*)
-+ MALLOC(sizeof(struct sadb_x_nat_t_port)))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_nat_t_port_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+
-+ pfkey_x_nat_t_port->sadb_x_nat_t_port_len = sizeof(struct sadb_x_nat_t_port) / IPSEC_PFKEYv2_ALIGN;
-+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype = exttype;
-+ pfkey_x_nat_t_port->sadb_x_nat_t_port_port = port;
-+ pfkey_x_nat_t_port->sadb_x_nat_t_port_reserved = 0;
-+
-+errlab:
-+ return error;
-+}
-+
-+int pfkey_x_protocol_build(struct sadb_ext **pfkey_ext,
-+ uint8_t protocol)
-+{
-+ int error = 0;
-+ struct sadb_protocol * p = (struct sadb_protocol *)*pfkey_ext;
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,"pfkey_x_protocol_build: protocol=%u\n", protocol);
-+ /* sanity checks... */
-+ if (p != 0) {
-+ ERROR("pfkey_x_protocol_build: bogus protocol pointer\n");
-+ SENDERR(EINVAL);
-+ }
-+ if ((p = (struct sadb_protocol*)MALLOC(sizeof(*p))) == 0) {
-+ ERROR("pfkey_build: memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ *pfkey_ext = (struct sadb_ext *)p;
-+ p->sadb_protocol_len = sizeof(*p) / sizeof(uint64_t);
-+ p->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
-+ p->sadb_protocol_proto = protocol;
-+ p->sadb_protocol_flags = 0;
-+ p->sadb_protocol_reserved2 = 0;
-+ errlab:
-+ return error;
-+}
-+
-+
-+#if I_DONT_THINK_THIS_WILL_BE_USEFUL
-+int (*ext_default_builders[SADB_EXT_MAX +1])(struct sadb_msg*, struct sadb_ext*)
-+ =
-+{
-+ NULL, /* pfkey_msg_build, */
-+ pfkey_sa_build,
-+ pfkey_lifetime_build,
-+ pfkey_lifetime_build,
-+ pfkey_lifetime_build,
-+ pfkey_address_build,
-+ pfkey_address_build,
-+ pfkey_address_build,
-+ pfkey_key_build,
-+ pfkey_key_build,
-+ pfkey_ident_build,
-+ pfkey_ident_build,
-+ pfkey_sens_build,
-+ pfkey_prop_build,
-+ pfkey_supported_build,
-+ pfkey_supported_build,
-+ pfkey_spirange_build,
-+ pfkey_x_kmprivate_build,
-+ pfkey_x_satype_build,
-+ pfkey_sa_build,
-+ pfkey_address_build,
-+ pfkey_address_build,
-+ pfkey_address_build,
-+ pfkey_address_build,
-+ pfkey_address_build,
-+ pfkey_x_ext_debug_build
-+};
-+#endif
-+
-+int
-+pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir)
-+{
-+ int error = 0;
-+ unsigned ext;
-+ unsigned total_size;
-+ struct sadb_ext *pfkey_ext;
-+ int extensions_seen = 0;
-+#ifndef __KERNEL__
-+ struct sadb_ext *extensions_check[SADB_EXT_MAX + 1];
-+#endif
-+
-+ if(!extensions[0]) {
-+ ERROR("pfkey_msg_build: "
-+ "extensions[0] must be specified (struct sadb_msg).\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* figure out the total size for all the requested extensions */
-+ total_size = IPSEC_PFKEYv2_WORDS(sizeof(struct sadb_msg));
-+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
-+ if(extensions[ext]) {
-+ total_size += (extensions[ext])->sadb_ext_len;
-+ }
-+ }
-+
-+ /* allocate that much space */
-+ *pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN);
-+ if(*pfkey_msg == NULL) {
-+ ERROR("pfkey_msg_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_build: "
-+ "pfkey_msg=0p%p allocated %lu bytes, &(extensions[0])=0p%p\n",
-+ *pfkey_msg,
-+ (unsigned long)(total_size * IPSEC_PFKEYv2_ALIGN),
-+ &(extensions[0]));
-+
-+ memcpy(*pfkey_msg,
-+ extensions[0],
-+ sizeof(struct sadb_msg));
-+ (*pfkey_msg)->sadb_msg_len = total_size;
-+ (*pfkey_msg)->sadb_msg_reserved = 0;
-+ extensions_seen = 1 ;
-+
-+ /*
-+ * point pfkey_ext to immediately after the space for the header,
-+ * i.e. at the first extension location.
-+ */
-+ pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg));
-+
-+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
-+ /* copy from extension[ext] to buffer */
-+ if(extensions[ext]) {
-+ /* Is this type of extension permitted for this type of message? */
-+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type] &
-+ 1<<ext)) {
-+ ERROR("pfkey_msg_build: "
-+ "ext type %d not permitted, exts_perm=%08x, 1<<type=%08x\n",
-+ ext,
-+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
-+ 1<<ext);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_build: "
-+ "copying %lu bytes from extensions[%u] (type=%d)\n",
-+ (unsigned long)(extensions[ext]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN),
-+ ext,
-+ extensions[ext]->sadb_ext_type);
-+
-+ memcpy(pfkey_ext,
-+ extensions[ext],
-+ (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
-+ ((char*)pfkey_ext) += (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN;
-+ /* Mark that we have seen this extension and remember the header location */
-+ extensions_seen |= ( 1 << ext );
-+ }
-+ }
-+
-+ /* check required extensions */
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_build: "
-+ "extensions permitted=%08x, seen=%08x, required=%08x.\n",
-+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
-+ extensions_seen,
-+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]);
-+
-+ if((extensions_seen &
-+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) !=
-+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_build: "
-+ "required extensions missing:%08x.\n",
-+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type] -
-+ (extensions_seen &
-+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) );
-+ SENDERR(EINVAL);
-+ }
-+
-+#ifndef __KERNEL__
-+/*
-+ * this is silly, there is no need to reparse the message that we just built.
-+ *
-+ */
-+ if((error = pfkey_msg_parse(*pfkey_msg, NULL, extensions_check, dir))) {
-+ ERROR(
-+ "pfkey_msg_build: "
-+ "Trouble parsing newly built pfkey message, error=%d.\n",
-+ error);
-+ SENDERR(-error);
-+ }
-+#endif
-+
-+errlab:
-+
-+ return error;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.49 2004/04/12 02:59:06 mcr
-+ * erroneously moved pfkey_v2_build.c
-+ *
-+ * Revision 1.48 2004/04/09 18:00:40 mcr
-+ * Moved from linux/lib/libfreeswan/pfkey_v2_build.c,v
-+ *
-+ * Revision 1.47 2004/03/08 01:59:08 ken
-+ * freeswan.h -> openswan.h
-+ *
-+ * Revision 1.46 2003/12/10 01:20:19 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.45 2003/12/04 23:01:12 mcr
-+ * removed ipsec_netlink.h
-+ *
-+ * Revision 1.44 2003/10/31 02:27:12 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.43.4.2 2003/10/29 01:11:32 mcr
-+ * added debugging for pfkey library.
-+ *
-+ * Revision 1.43.4.1 2003/09/21 13:59:44 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.43 2003/05/07 17:29:17 mcr
-+ * new function pfkey_debug_func added for us in debugging from
-+ * pfkey library.
-+ *
-+ * Revision 1.42 2003/01/30 02:32:09 rgb
-+ *
-+ * Rename SAref table macro names for clarity.
-+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
-+ *
-+ * Revision 1.41 2002/12/13 18:16:02 mcr
-+ * restored sa_ref code
-+ *
-+ * Revision 1.40 2002/12/13 18:06:52 mcr
-+ * temporarily removed sadb_x_sa_ref reference for 2.xx
-+ *
-+ * Revision 1.39 2002/12/13 17:43:28 mcr
-+ * commented out access to sadb_x_sa_ref for 2.xx branch
-+ *
-+ * Revision 1.38 2002/10/09 03:12:05 dhr
-+ *
-+ * [kenb+dhr] 64-bit fixes
-+ *
-+ * Revision 1.37 2002/09/20 15:40:39 rgb
-+ * Added new function pfkey_sa_ref_build() to accomodate saref parameter.
-+ *
-+ * Revision 1.36 2002/09/20 05:01:22 rgb
-+ * Generalise for platform independance: fix (ia64) using unsigned for sizes.
-+ *
-+ * Revision 1.35 2002/07/24 18:44:54 rgb
-+ * Type fiddling to tame ia64 compiler.
-+ *
-+ * Revision 1.34 2002/05/23 07:14:11 rgb
-+ * Cleaned up %p variants to 0p%p for test suite cleanup.
-+ *
-+ * Revision 1.33 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.32 2002/04/24 07:36:40 mcr
-+ * Moved from ./lib/pfkey_v2_build.c,v
-+ *
-+ * Revision 1.31 2002/01/29 22:25:35 rgb
-+ * Re-add ipsec_kversion.h to keep MALLOC happy.
-+ *
-+ * Revision 1.30 2002/01/29 01:59:09 mcr
-+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
-+ * updating of IPv6 structures to match latest in6.h version.
-+ * removed dead code from openswan.h that also duplicated kversions.h
-+ * code.
-+ *
-+ * Revision 1.29 2001/12/19 21:06:09 rgb
-+ * Added port numbers to pfkey_address_build() debugging.
-+ *
-+ * Revision 1.28 2001/11/06 19:47:47 rgb
-+ * Added packet parameter to lifetime and comb structures.
-+ *
-+ * Revision 1.27 2001/10/18 04:45:24 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/openswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.26 2001/09/08 21:13:34 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.25 2001/06/14 19:35:16 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.24 2001/03/20 03:49:45 rgb
-+ * Ditch superfluous debug_pfkey declaration.
-+ * Move misplaced openswan.h inclusion for kernel case.
-+ *
-+ * Revision 1.23 2001/03/16 07:41:50 rgb
-+ * Put openswan.h include before pluto includes.
-+ *
-+ * Revision 1.22 2001/02/27 22:24:56 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.21 2000/11/17 18:10:30 rgb
-+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
-+ * network byte order since this is the way PF_KEYv2 stored spis.
-+ *
-+ * Revision 1.20 2000/10/12 00:02:39 rgb
-+ * Removed 'format, ##' nonsense from debug macros for RH7.0.
-+ *
-+ * Revision 1.19 2000/10/10 20:10:20 rgb
-+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
-+ *
-+ * Revision 1.18 2000/09/12 18:59:54 rgb
-+ * Added Gerhard's IPv6 support to pfkey parts of libopenswan.
-+ *
-+ * Revision 1.17 2000/09/12 03:27:00 rgb
-+ * Moved DEBUGGING definition to compile kernel with debug off.
-+ *
-+ * Revision 1.16 2000/09/08 19:22:12 rgb
-+ * Fixed pfkey_prop_build() parameter to be only single indirection.
-+ * Fixed struct alg copy.
-+ *
-+ * Revision 1.15 2000/08/20 21:40:01 rgb
-+ * Added an address parameter sanity check to pfkey_address_build().
-+ *
-+ * Revision 1.14 2000/08/15 17:29:23 rgb
-+ * Fixes from SZI to untested pfkey_prop_build().
-+ *
-+ * Revision 1.13 2000/06/02 22:54:14 rgb
-+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
-+ *
-+ * Revision 1.12 2000/05/10 19:24:01 rgb
-+ * Fleshed out sensitivity, proposal and supported extensions.
-+ *
-+ * Revision 1.11 2000/03/16 14:07:23 rgb
-+ * Renamed ALIGN macro to avoid fighting with others in kernel.
-+ *
-+ * Revision 1.10 2000/01/24 21:14:35 rgb
-+ * Added disabled pluto pfkey lib debug flag.
-+ *
-+ * Revision 1.9 2000/01/21 06:27:32 rgb
-+ * Added address cases for eroute flows.
-+ * Removed unused code.
-+ * Dropped unused argument to pfkey_x_satype_build().
-+ * Indented compiler directives for readability.
-+ * Added klipsdebug switching capability.
-+ * Fixed SADB_EXT_MAX bug not permitting last extension access.
-+ *
-+ * Revision 1.8 1999/12/29 21:17:41 rgb
-+ * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
-+ * parameter for cleaner manipulation of extensions[] and to guard
-+ * against potential memory leaks.
-+ * Changed the I/F to pfkey_msg_free() for the same reason.
-+ *
-+ * Revision 1.7 1999/12/09 23:12:20 rgb
-+ * Removed unused cruft.
-+ * Added argument to pfkey_sa_build() to do eroutes.
-+ * Fixed exttype check in as yet unused pfkey_lifetime_build().
-+ *
-+ * Revision 1.6 1999/12/07 19:54:29 rgb
-+ * Removed static pluto debug flag.
-+ * Added functions for pfkey message and extensions initialisation
-+ * and cleanup.
-+ *
-+ * Revision 1.5 1999/12/01 22:20:06 rgb
-+ * Changed pfkey_sa_build to accept an SPI in network byte order.
-+ * Added <string.h> to quiet userspace compiler.
-+ * Moved pfkey_lib_debug variable into the library.
-+ * Removed SATYPE check from pfkey_msg_hdr_build so FLUSH will work.
-+ * Added extension assembly debugging.
-+ * Isolated assignment with brackets to be sure of scope.
-+ *
-+ * Revision 1.4 1999/11/27 11:57:35 rgb
-+ * Added ipv6 headers.
-+ * Remove over-zealous algorithm sanity checkers from pfkey_sa_build.
-+ * Debugging error messages added.
-+ * Fixed missing auth and encrypt assignment bug.
-+ * Add argument to pfkey_msg_parse() for direction.
-+ * Move parse-after-build check inside pfkey_msg_build().
-+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
-+ * Add CVS log entry to bottom of file.
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/pfkey_v2_debug.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,176 @@
-+/*
-+ * @(#) pfkey version 2 debugging messages
-+ *
-+ * Copyright (C) 2001 Richard Guy Briggs <rgb@openswan.org>
-+ * and Michael Richardson <mcr@openswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ */
-+
-+#ifdef __KERNEL__
-+
-+# include <linux/kernel.h> /* for printk */
-+
-+# include "openswan/ipsec_kversion.h" /* for malloc switch */
-+# ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+# else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+# endif /* MALLOC_SLAB */
-+# include <linux/errno.h> /* error codes */
-+# include <linux/types.h> /* size_t */
-+# include <linux/interrupt.h> /* mark_bh */
-+
-+# include <linux/netdevice.h> /* struct device, and other headers */
-+# include <linux/etherdevice.h> /* eth_type_trans */
-+extern int debug_pfkey;
-+
-+#else /* __KERNEL__ */
-+
-+# include <sys/types.h>
-+# include <linux/types.h>
-+# include <linux/errno.h>
-+
-+#endif /* __KERNEL__ */
-+
-+#include "openswan.h"
-+#include "pfkeyv2.h"
-+#include "pfkey.h"
-+
-+/*
-+ * This file provides ASCII translations of PF_KEY magic numbers.
-+ *
-+ */
-+
-+static char *pfkey_sadb_ext_strings[]={
-+ "reserved", /* SADB_EXT_RESERVED 0 */
-+ "security-association", /* SADB_EXT_SA 1 */
-+ "lifetime-current", /* SADB_EXT_LIFETIME_CURRENT 2 */
-+ "lifetime-hard", /* SADB_EXT_LIFETIME_HARD 3 */
-+ "lifetime-soft", /* SADB_EXT_LIFETIME_SOFT 4 */
-+ "source-address", /* SADB_EXT_ADDRESS_SRC 5 */
-+ "destination-address", /* SADB_EXT_ADDRESS_DST 6 */
-+ "proxy-address", /* SADB_EXT_ADDRESS_PROXY 7 */
-+ "authentication-key", /* SADB_EXT_KEY_AUTH 8 */
-+ "cipher-key", /* SADB_EXT_KEY_ENCRYPT 9 */
-+ "source-identity", /* SADB_EXT_IDENTITY_SRC 10 */
-+ "destination-identity", /* SADB_EXT_IDENTITY_DST 11 */
-+ "sensitivity-label", /* SADB_EXT_SENSITIVITY 12 */
-+ "proposal", /* SADB_EXT_PROPOSAL 13 */
-+ "supported-auth", /* SADB_EXT_SUPPORTED_AUTH 14 */
-+ "supported-cipher", /* SADB_EXT_SUPPORTED_ENCRYPT 15 */
-+ "spi-range", /* SADB_EXT_SPIRANGE 16 */
-+ "X-kmpprivate", /* SADB_X_EXT_KMPRIVATE 17 */
-+ "X-satype2", /* SADB_X_EXT_SATYPE2 18 */
-+ "X-security-association", /* SADB_X_EXT_SA2 19 */
-+ "X-destination-address2", /* SADB_X_EXT_ADDRESS_DST2 20 */
-+ "X-source-flow-address", /* SADB_X_EXT_ADDRESS_SRC_FLOW 21 */
-+ "X-dest-flow-address", /* SADB_X_EXT_ADDRESS_DST_FLOW 22 */
-+ "X-source-mask", /* SADB_X_EXT_ADDRESS_SRC_MASK 23 */
-+ "X-dest-mask", /* SADB_X_EXT_ADDRESS_DST_MASK 24 */
-+ "X-set-debug", /* SADB_X_EXT_DEBUG 25 */
-+#ifdef NAT_TRAVERSAL
-+ "X-NAT-T-type", /* SADB_X_EXT_NAT_T_TYPE 26 */
-+ "X-NAT-T-sport", /* SADB_X_EXT_NAT_T_SPORT 27 */
-+ "X-NAT-T-dport", /* SADB_X_EXT_NAT_T_DPORT 28 */
-+ "X-NAT-T-OA", /* SADB_X_EXT_NAT_T_OA 29 */
-+#endif
-+};
-+
-+const char *
-+pfkey_v2_sadb_ext_string(int ext)
-+{
-+ if(ext <= SADB_EXT_MAX) {
-+ return pfkey_sadb_ext_strings[ext];
-+ } else {
-+ return "unknown-ext";
-+ }
-+}
-+
-+
-+static char *pfkey_sadb_type_strings[]={
-+ "reserved", /* SADB_RESERVED */
-+ "getspi", /* SADB_GETSPI */
-+ "update", /* SADB_UPDATE */
-+ "add", /* SADB_ADD */
-+ "delete", /* SADB_DELETE */
-+ "get", /* SADB_GET */
-+ "acquire", /* SADB_ACQUIRE */
-+ "register", /* SADB_REGISTER */
-+ "expire", /* SADB_EXPIRE */
-+ "flush", /* SADB_FLUSH */
-+ "dump", /* SADB_DUMP */
-+ "x-promisc", /* SADB_X_PROMISC */
-+ "x-pchange", /* SADB_X_PCHANGE */
-+ "x-groupsa", /* SADB_X_GRPSA */
-+ "x-addflow(eroute)", /* SADB_X_ADDFLOW */
-+ "x-delflow(eroute)", /* SADB_X_DELFLOW */
-+ "x-debug", /* SADB_X_DEBUG */
-+};
-+
-+const char *
-+pfkey_v2_sadb_type_string(int sadb_type)
-+{
-+ if(sadb_type <= SADB_MAX) {
-+ return pfkey_sadb_type_strings[sadb_type];
-+ } else {
-+ return "unknown-sadb-type";
-+ }
-+}
-+
-+
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.9 2004/03/08 01:59:08 ken
-+ * freeswan.h -> openswan.h
-+ *
-+ * Revision 1.8 2003/12/10 01:20:19 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.7 2002/09/20 05:01:26 rgb
-+ * Fixed limit inclusion error in both type and ext string conversion.
-+ *
-+ * Revision 1.6 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.5 2002/04/24 07:36:40 mcr
-+ * Moved from ./lib/pfkey_v2_debug.c,v
-+ *
-+ * Revision 1.4 2002/01/29 22:25:36 rgb
-+ * Re-add ipsec_kversion.h to keep MALLOC happy.
-+ *
-+ * Revision 1.3 2002/01/29 01:59:09 mcr
-+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
-+ * updating of IPv6 structures to match latest in6.h version.
-+ * removed dead code from openswan.h that also duplicated kversions.h
-+ * code.
-+ *
-+ * Revision 1.2 2002/01/20 20:34:50 mcr
-+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
-+ *
-+ * Revision 1.1 2001/11/27 05:30:06 mcr
-+ * initial set of debug strings for pfkey debugging.
-+ * this will eventually only be included for debug builds.
-+ *
-+ * Revision 1.1 2001/09/21 04:12:03 mcr
-+ * first compilable version.
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/pfkey_v2_ext_bits.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,808 @@
-+/*
-+ * RFC2367 PF_KEYv2 Key management API message parser
-+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * Template from klips/net/ipsec/ipsec/ipsec_parse.c.
-+ */
-+
-+char pfkey_v2_ext_bits_c_version[] = "$Id$";
-+
-+/*
-+ * Some ugly stuff to allow consistent debugging code for use in the
-+ * kernel and in user space
-+*/
-+
-+#ifdef __KERNEL__
-+
-+# include <linux/kernel.h> /* for printk */
-+
-+# include "openswan/ipsec_kversion.h" /* for malloc switch */
-+# ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+# else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+# endif /* MALLOC_SLAB */
-+# include <linux/errno.h> /* error codes */
-+# include <linux/types.h> /* size_t */
-+# include <linux/interrupt.h> /* mark_bh */
-+
-+# include <linux/netdevice.h> /* struct device, and other headers */
-+# include <linux/etherdevice.h> /* eth_type_trans */
-+# include <linux/ip.h> /* struct iphdr */
-+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+# include <linux/ipv6.h>
-+# endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
-+
-+#else /* __KERNEL__ */
-+
-+# include <sys/types.h>
-+# include <linux/types.h>
-+# include <linux/errno.h>
-+#endif
-+
-+#include <openswan.h>
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/] = {
-+
-+/* INBOUND EXTENSIONS */
-+{
-+
-+/* PERMITTED IN */
-+{
-+/* SADB_RESERVED */
-+0
-+,
-+/* SADB_GETSPI */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_SPIRANGE
-+,
-+/* SADB_UPDATE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+,
-+/* SADB_ADD */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_X_EXT_NAT_T_TYPE
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+| 1<<SADB_X_EXT_NAT_T_OA
-+,
-+/* SADB_DELETE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_GET */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_ACQUIRE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+,
-+/* SADB_REGISTER */
-+1<<SADB_EXT_RESERVED
-+,
-+/* SADB_EXPIRE */
-+0
-+,
-+/* SADB_FLUSH */
-+1<<SADB_EXT_RESERVED
-+,
-+/* SADB_DUMP */
-+1<<SADB_EXT_RESERVED
-+,
-+/* SADB_X_PROMISC */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+| 1<<SADB_EXT_SPIRANGE
-+| 1<<SADB_X_EXT_KMPRIVATE
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_PCHANGE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+| 1<<SADB_EXT_SPIRANGE
-+| 1<<SADB_X_EXT_KMPRIVATE
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_GRPSA */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_ADDFLOW */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_X_EXT_PROTOCOL
-+,
-+/* SADB_X_DELFLOW */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_X_EXT_PROTOCOL
-+,
-+/* SADB_X_DEBUG */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_X_EXT_DEBUG
-+,
-+/* SADB_X_NAT_T_NEW_MAPPING */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+},
-+
-+/* REQUIRED IN */
-+{
-+/* SADB_RESERVED */
-+0
-+,
-+/* SADB_GETSPI */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_SPIRANGE
-+,
-+/* SADB_UPDATE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+/*| 1<<SADB_EXT_KEY_AUTH*/
-+/*| 1<<SADB_EXT_KEY_ENCRYPT*/
-+,
-+/* SADB_ADD */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+/*| 1<<SADB_EXT_KEY_AUTH*/
-+/*| 1<<SADB_EXT_KEY_ENCRYPT*/
-+,
-+/* SADB_DELETE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_GET */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_ACQUIRE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_PROPOSAL
-+,
-+/* SADB_REGISTER */
-+1<<SADB_EXT_RESERVED
-+,
-+/* SADB_EXPIRE */
-+0
-+,
-+/* SADB_FLUSH */
-+1<<SADB_EXT_RESERVED
-+,
-+/* SADB_DUMP */
-+1<<SADB_EXT_RESERVED
-+,
-+/* SADB_X_PROMISC */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+| 1<<SADB_EXT_SPIRANGE
-+| 1<<SADB_X_EXT_KMPRIVATE
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_PCHANGE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+| 1<<SADB_EXT_SPIRANGE
-+| 1<<SADB_X_EXT_KMPRIVATE
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_GRPSA */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_DST
-+/*| 1<<SADB_X_EXT_SATYPE2*/
-+/*| 1<<SADB_X_EXT_SA2*/
-+/*| 1<<SADB_X_EXT_ADDRESS_DST2*/
-+,
-+/* SADB_X_ADDFLOW */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-+,
-+/* SADB_X_DELFLOW */
-+1<<SADB_EXT_RESERVED
-+/*| 1<<SADB_EXT_SA*/
-+#if 0 /* SADB_X_CLREROUTE doesn't need all these... */
-+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-+#endif
-+,
-+/* SADB_X_DEBUG */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_X_EXT_DEBUG
-+,
-+/* SADB_X_NAT_T_NEW_MAPPING */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+}
-+
-+},
-+
-+/* OUTBOUND EXTENSIONS */
-+{
-+
-+/* PERMITTED OUT */
-+{
-+/* SADB_RESERVED */
-+0
-+,
-+/* SADB_GETSPI */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_UPDATE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+,
-+/* SADB_ADD */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_X_EXT_NAT_T_TYPE
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+| 1<<SADB_X_EXT_NAT_T_OA
-+,
-+/* SADB_DELETE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_GET */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_X_EXT_NAT_T_TYPE
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+| 1<<SADB_X_EXT_NAT_T_OA
-+,
-+/* SADB_ACQUIRE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+,
-+/* SADB_REGISTER */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+,
-+/* SADB_EXPIRE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_FLUSH */
-+1<<SADB_EXT_RESERVED
-+,
-+/* SADB_DUMP */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_X_EXT_NAT_T_TYPE
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+| 1<<SADB_X_EXT_NAT_T_OA
-+,
-+/* SADB_X_PROMISC */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+| 1<<SADB_EXT_SPIRANGE
-+| 1<<SADB_X_EXT_KMPRIVATE
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_PCHANGE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+| 1<<SADB_EXT_SPIRANGE
-+| 1<<SADB_X_EXT_KMPRIVATE
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_GRPSA */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_ADDFLOW */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-+| 1<<SADB_X_EXT_PROTOCOL
-+,
-+/* SADB_X_DELFLOW */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-+| 1<<SADB_X_EXT_PROTOCOL
-+,
-+/* SADB_X_DEBUG */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_X_EXT_DEBUG
-+,
-+/* SADB_X_NAT_T_NEW_MAPPING */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+},
-+
-+/* REQUIRED OUT */
-+{
-+/* SADB_RESERVED */
-+0
-+,
-+/* SADB_GETSPI */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_UPDATE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_ADD */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_DELETE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_GET */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+/* | 1<<SADB_EXT_KEY_AUTH */
-+/* | 1<<SADB_EXT_KEY_ENCRYPT */
-+,
-+/* SADB_ACQUIRE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_PROPOSAL
-+,
-+/* SADB_REGISTER */
-+1<<SADB_EXT_RESERVED
-+/* | 1<<SADB_EXT_SUPPORTED_AUTH
-+ | 1<<SADB_EXT_SUPPORTED_ENCRYPT */
-+,
-+/* SADB_EXPIRE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+/* | 1<<SADB_EXT_LIFETIME_HARD
-+ | 1<<SADB_EXT_LIFETIME_SOFT */
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_FLUSH */
-+1<<SADB_EXT_RESERVED
-+,
-+/* SADB_DUMP */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+,
-+/* SADB_X_PROMISC */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+| 1<<SADB_EXT_SPIRANGE
-+| 1<<SADB_X_EXT_KMPRIVATE
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_PCHANGE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+| 1<<SADB_EXT_SPIRANGE
-+| 1<<SADB_X_EXT_KMPRIVATE
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_GRPSA */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_X_ADDFLOW */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-+,
-+/* SADB_X_DELFLOW */
-+1<<SADB_EXT_RESERVED
-+/*| 1<<SADB_EXT_SA*/
-+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-+,
-+/* SADB_X_DEBUG */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_X_EXT_DEBUG
-+,
-+/* SADB_X_NAT_T_NEW_MAPPING */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+}
-+}
-+};
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.20 2004/03/08 01:59:08 ken
-+ * freeswan.h -> openswan.h
-+ *
-+ * Revision 1.19 2003/12/22 21:38:13 mcr
-+ * removed extraenous #endif.
-+ *
-+ * Revision 1.18 2003/12/22 19:34:41 mcr
-+ * added 0.6c NAT-T patch.
-+ *
-+ * Revision 1.17 2003/12/10 01:20:19 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.16 2003/10/31 02:27:12 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.15.30.1 2003/09/21 13:59:44 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.15 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.14 2002/04/24 07:36:40 mcr
-+ * Moved from ./lib/pfkey_v2_ext_bits.c,v
-+ *
-+ * Revision 1.13 2002/01/29 22:25:36 rgb
-+ * Re-add ipsec_kversion.h to keep MALLOC happy.
-+ *
-+ * Revision 1.12 2002/01/29 01:59:10 mcr
-+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
-+ * updating of IPv6 structures to match latest in6.h version.
-+ * removed dead code from openswan.h that also duplicated kversions.h
-+ * code.
-+ *
-+ * Revision 1.11 2001/10/18 04:45:24 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/openswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.10 2001/09/08 21:13:35 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.9 2001/06/14 19:35:16 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.8 2001/03/26 23:07:36 rgb
-+ * Remove requirement for auth and enc key from UPDATE.
-+ *
-+ * Revision 1.7 2000/09/12 22:35:37 rgb
-+ * Restructured to remove unused extensions from CLEARFLOW messages.
-+ *
-+ * Revision 1.6 2000/09/09 06:39:01 rgb
-+ * Added comments for clarity.
-+ *
-+ * Revision 1.5 2000/06/02 22:54:14 rgb
-+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
-+ *
-+ * Revision 1.4 2000/01/21 06:27:56 rgb
-+ * Added address cases for eroute flows.
-+ * Added comments for each message type.
-+ * Added klipsdebug switching capability.
-+ * Fixed GRPSA bitfields.
-+ *
-+ * Revision 1.3 1999/12/01 22:20:27 rgb
-+ * Remove requirement for a proxy address in an incoming getspi message.
-+ *
-+ * Revision 1.2 1999/11/27 11:57:06 rgb
-+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
-+ * Add CVS log entry to bottom of file.
-+ * Cleaned out unused bits.
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/pfkey_v2_parse.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1820 @@
-+/*
-+ * RFC2367 PF_KEYv2 Key management API message parser
-+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
-+ */
-+
-+char pfkey_v2_parse_c_version[] = "$Id$";
-+
-+/*
-+ * Some ugly stuff to allow consistent debugging code for use in the
-+ * kernel and in user space
-+*/
-+
-+#ifdef __KERNEL__
-+
-+# include <linux/kernel.h> /* for printk */
-+
-+#include "openswan/ipsec_kversion.h" /* for malloc switch */
-+
-+# ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+# else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+# endif /* MALLOC_SLAB */
-+# include <linux/errno.h> /* error codes */
-+# include <linux/types.h> /* size_t */
-+# include <linux/interrupt.h> /* mark_bh */
-+
-+# include <linux/netdevice.h> /* struct device, and other headers */
-+# include <linux/etherdevice.h> /* eth_type_trans */
-+# include <linux/ip.h> /* struct iphdr */
-+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+# include <linux/ipv6.h> /* struct ipv6hdr */
-+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
-+extern int debug_pfkey;
-+
-+# include <openswan.h>
-+
-+#include "openswan/ipsec_encap.h"
-+
-+#else /* __KERNEL__ */
-+
-+# include <sys/types.h>
-+# include <linux/types.h>
-+# include <linux/errno.h>
-+
-+# include <openswan.h>
-+# include "constants.h"
-+# include "programs/pluto/defs.h" /* for PRINTF_LIKE */
-+
-+#endif /* __KERNEL__ */
-+
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
-+
-+/*
-+ * how to handle debugging for pfkey.
-+ */
-+#include <openswan/pfkey_debug.h>
-+
-+unsigned int pfkey_lib_debug = PF_KEY_DEBUG_PARSE_NONE;
-+void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
-+void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
-+
-+
-+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
-+
-+struct satype_tbl {
-+ uint8_t proto;
-+ uint8_t satype;
-+ char* name;
-+} static satype_tbl[] = {
-+#ifdef __KERNEL__
-+ { IPPROTO_ESP, SADB_SATYPE_ESP, "ESP" },
-+ { IPPROTO_AH, SADB_SATYPE_AH, "AH" },
-+ { IPPROTO_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ { IPPROTO_COMP, SADB_X_SATYPE_COMP, "COMP" },
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ { IPPROTO_INT, SADB_X_SATYPE_INT, "INT" },
-+#else /* __KERNEL__ */
-+ { SA_ESP, SADB_SATYPE_ESP, "ESP" },
-+ { SA_AH, SADB_SATYPE_AH, "AH" },
-+ { SA_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
-+ { SA_COMP, SADB_X_SATYPE_COMP, "COMP" },
-+ { SA_INT, SADB_X_SATYPE_INT, "INT" },
-+#endif /* __KERNEL__ */
-+ { 0, 0, "UNKNOWN" }
-+};
-+
-+uint8_t
-+satype2proto(uint8_t satype)
-+{
-+ int i =0;
-+
-+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
-+ i++;
-+ }
-+ return satype_tbl[i].proto;
-+}
-+
-+uint8_t
-+proto2satype(uint8_t proto)
-+{
-+ int i = 0;
-+
-+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
-+ i++;
-+ }
-+ return satype_tbl[i].satype;
-+}
-+
-+char*
-+satype2name(uint8_t satype)
-+{
-+ int i = 0;
-+
-+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
-+ i++;
-+ }
-+ return satype_tbl[i].name;
-+}
-+
-+char*
-+proto2name(uint8_t proto)
-+{
-+ int i = 0;
-+
-+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
-+ i++;
-+ }
-+ return satype_tbl[i].name;
-+}
-+
-+/* Default extension parsers taken from the KLIPS code */
-+
-+DEBUG_NO_STATIC int
-+pfkey_sa_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
-+#if 0
-+ struct sadb_sa sav2;
-+#endif
-+
-+ /* sanity checks... */
-+ if(!pfkey_sa) {
-+ ERROR("pfkey_sa_parse: "
-+ "NULL pointer passed in.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+#if 0
-+ /* check if this structure is short, and if so, fix it up.
-+ * XXX this is NOT the way to do things.
-+ */
-+ if(pfkey_sa->sadb_sa_len == sizeof(struct sadb_sa_v1)/IPSEC_PFKEYv2_ALIGN) {
-+
-+ /* yes, so clear out a temporary structure, and copy first */
-+ memset(&sav2, 0, sizeof(sav2));
-+ memcpy(&sav2, pfkey_sa, sizeof(struct sadb_sa_v1));
-+ sav2.sadb_x_sa_ref=-1;
-+ sav2.sadb_sa_len = sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN;
-+
-+ pfkey_sa = &sav2;
-+ }
-+#endif
-+
-+
-+ if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) {
-+ ERROR(
-+ "pfkey_sa_parse: "
-+ "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n",
-+ pfkey_sa->sadb_sa_len,
-+ (int)sizeof(struct sadb_sa));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) {
-+ ERROR(
-+ "pfkey_sa_parse: "
-+ "pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n",
-+ pfkey_sa->sadb_sa_encrypt,
-+ SADB_EALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) {
-+ ERROR(
-+ "pfkey_sa_parse: "
-+ "pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n",
-+ pfkey_sa->sadb_sa_auth,
-+ SADB_AALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_sa->sadb_sa_state > SADB_SASTATE_MAX) {
-+ ERROR(
-+ "pfkey_sa_parse: "
-+ "state=%d exceeds MAX=%d.\n",
-+ pfkey_sa->sadb_sa_state,
-+ SADB_SASTATE_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_sa->sadb_sa_state == SADB_SASTATE_DEAD) {
-+ ERROR(
-+ "pfkey_sa_parse: "
-+ "state=%d is DEAD=%d.\n",
-+ pfkey_sa->sadb_sa_state,
-+ SADB_SASTATE_DEAD);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_sa->sadb_sa_replay > 64) {
-+ ERROR(
-+ "pfkey_sa_parse: "
-+ "replay window size: %d -- must be 0 <= size <= 64\n",
-+ pfkey_sa->sadb_sa_replay);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(! ((pfkey_sa->sadb_sa_exttype == SADB_EXT_SA) ||
-+ (pfkey_sa->sadb_sa_exttype == SADB_X_EXT_SA2)))
-+ {
-+ ERROR(
-+ "pfkey_sa_parse: "
-+ "unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n",
-+ pfkey_sa->sadb_sa_exttype,
-+ SADB_EXT_SA,
-+ SADB_X_EXT_SA2);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if((IPSEC_SAREF_NULL != pfkey_sa->sadb_x_sa_ref) && (pfkey_sa->sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
-+ ERROR(
-+ "pfkey_sa_parse: "
-+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
-+ pfkey_sa->sadb_x_sa_ref,
-+ IPSEC_SAREF_NULL,
-+ IPSEC_SA_REF_TABLE_NUM_ENTRIES);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_sa_parse: "
-+ "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d ref=%d.\n",
-+ pfkey_sa->sadb_sa_len,
-+ pfkey_sa->sadb_sa_exttype,
-+ pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype),
-+ (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi),
-+ pfkey_sa->sadb_sa_replay,
-+ pfkey_sa->sadb_sa_state,
-+ pfkey_sa->sadb_sa_auth,
-+ pfkey_sa->sadb_sa_encrypt,
-+ pfkey_sa->sadb_sa_flags,
-+ pfkey_sa->sadb_x_sa_ref);
-+
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_lifetime_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-+ "pfkey_lifetime_parse:enter\n");
-+ /* sanity checks... */
-+ if(!pfkey_lifetime) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_lifetime_parse: "
-+ "NULL pointer passed in.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_lifetime->sadb_lifetime_len !=
-+ sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_lifetime_parse: "
-+ "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n",
-+ pfkey_lifetime->sadb_lifetime_len,
-+ (int)sizeof(struct sadb_lifetime));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) &&
-+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) &&
-+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_lifetime_parse: "
-+ "unexpected ext_type=%d.\n",
-+ pfkey_lifetime->sadb_lifetime_exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_lifetime_parse: "
-+ "life_type=%d(%s) alloc=%u bytes=%u add=%u use=%u pkts=%u.\n",
-+ pfkey_lifetime->sadb_lifetime_exttype,
-+ pfkey_v2_sadb_ext_string(pfkey_lifetime->sadb_lifetime_exttype),
-+ pfkey_lifetime->sadb_lifetime_allocations,
-+ (unsigned)pfkey_lifetime->sadb_lifetime_bytes,
-+ (unsigned)pfkey_lifetime->sadb_lifetime_addtime,
-+ (unsigned)pfkey_lifetime->sadb_lifetime_usetime,
-+ pfkey_lifetime->sadb_x_lifetime_packets);
-+errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_address_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ int saddr_len = 0;
-+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
-+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
-+ char ipaddr_txt[ADDRTOT_BUF];
-+
-+ /* sanity checks... */
-+ if(!pfkey_address) {
-+ ERROR(
-+ "pfkey_address_parse: "
-+ "NULL pointer passed in.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_address->sadb_address_len <
-+ (sizeof(struct sadb_address) + sizeof(struct sockaddr))/
-+ IPSEC_PFKEYv2_ALIGN) {
-+ ERROR("pfkey_address_parse: "
-+ "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
-+ pfkey_address->sadb_address_len,
-+ (int)sizeof(struct sadb_address),
-+ (int)sizeof(struct sockaddr));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_address->sadb_address_reserved) {
-+ ERROR("pfkey_address_parse: "
-+ "res=%d, must be zero.\n",
-+ pfkey_address->sadb_address_reserved);
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_address->sadb_address_exttype) {
-+ case SADB_EXT_ADDRESS_SRC:
-+ case SADB_EXT_ADDRESS_DST:
-+ case SADB_EXT_ADDRESS_PROXY:
-+ case SADB_X_EXT_ADDRESS_DST2:
-+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
-+ case SADB_X_EXT_ADDRESS_DST_FLOW:
-+ case SADB_X_EXT_ADDRESS_SRC_MASK:
-+ case SADB_X_EXT_ADDRESS_DST_MASK:
-+#ifdef NAT_TRAVERSAL
-+ case SADB_X_EXT_NAT_T_OA:
-+#endif
-+ break;
-+ default:
-+ ERROR(
-+ "pfkey_address_parse: "
-+ "unexpected ext_type=%d.\n",
-+ pfkey_address->sadb_address_exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(s->sa_family) {
-+ case AF_INET:
-+ saddr_len = sizeof(struct sockaddr_in);
-+ sprintf(ipaddr_txt, "%d.%d.%d.%d"
-+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 0) & 0xFF
-+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 8) & 0xFF
-+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF
-+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF);
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_address_parse: "
-+ "found exttype=%u(%s) family=%d(AF_INET) address=%s proto=%u port=%u.\n",
-+ pfkey_address->sadb_address_exttype,
-+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
-+ s->sa_family,
-+ ipaddr_txt,
-+ pfkey_address->sadb_address_proto,
-+ ntohs(((struct sockaddr_in*)s)->sin_port));
-+ break;
-+ case AF_INET6:
-+ saddr_len = sizeof(struct sockaddr_in6);
-+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x"
-+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0])
-+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1])
-+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2])
-+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3])
-+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4])
-+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5])
-+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6])
-+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7]));
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_address_parse: "
-+ "found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n",
-+ pfkey_address->sadb_address_exttype,
-+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
-+ s->sa_family,
-+ ipaddr_txt,
-+ pfkey_address->sadb_address_proto,
-+ ((struct sockaddr_in6*)s)->sin6_port);
-+ break;
-+ default:
-+ ERROR(
-+ "pfkey_address_parse: "
-+ "s->sa_family=%d not supported.\n",
-+ s->sa_family);
-+ SENDERR(EPFNOSUPPORT);
-+ }
-+
-+ if(pfkey_address->sadb_address_len !=
-+ DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) {
-+ ERROR(
-+ "pfkey_address_parse: "
-+ "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
-+ pfkey_address->sadb_address_len,
-+ (int)sizeof(struct sadb_address),
-+ saddr_len);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_address->sadb_address_prefixlen != 0) {
-+ ERROR(
-+ "pfkey_address_parse: "
-+ "address prefixes not supported yet.\n");
-+ SENDERR(EAFNOSUPPORT); /* not supported yet */
-+ }
-+
-+ /* XXX check if port!=0 */
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-+ "pfkey_address_parse: successful.\n");
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_key_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
-+
-+ /* sanity checks... */
-+
-+ if(!pfkey_key) {
-+ ERROR(
-+ "pfkey_key_parse: "
-+ "NULL pointer passed in.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) {
-+ ERROR(
-+ "pfkey_key_parse: "
-+ "size wrong ext_len=%d, key_ext_len=%d.\n",
-+ pfkey_key->sadb_key_len,
-+ (int)sizeof(struct sadb_key));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!pfkey_key->sadb_key_bits) {
-+ ERROR(
-+ "pfkey_key_parse: "
-+ "key length set to zero, must be non-zero.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_key->sadb_key_len !=
-+ DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits,
-+ PFKEYBITS)) {
-+ ERROR(
-+ "pfkey_key_parse: "
-+ "key length=%d does not agree with extension length=%d.\n",
-+ pfkey_key->sadb_key_bits,
-+ pfkey_key->sadb_key_len);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_key->sadb_key_reserved) {
-+ ERROR(
-+ "pfkey_key_parse: "
-+ "res=%d, must be zero.\n",
-+ pfkey_key->sadb_key_reserved);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(! ( (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_AUTH) ||
-+ (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_ENCRYPT))) {
-+ ERROR(
-+ "pfkey_key_parse: "
-+ "expecting extension type AUTH or ENCRYPT, got %d.\n",
-+ pfkey_key->sadb_key_exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_key_parse: "
-+ "success, found len=%d exttype=%d(%s) bits=%d reserved=%d.\n",
-+ pfkey_key->sadb_key_len,
-+ pfkey_key->sadb_key_exttype,
-+ pfkey_v2_sadb_ext_string(pfkey_key->sadb_key_exttype),
-+ pfkey_key->sadb_key_bits,
-+ pfkey_key->sadb_key_reserved);
-+
-+errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_ident_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
-+
-+ /* sanity checks... */
-+ if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
-+ ERROR(
-+ "pfkey_ident_parse: "
-+ "size wrong ext_len=%d, key_ext_len=%d.\n",
-+ pfkey_ident->sadb_ident_len,
-+ (int)sizeof(struct sadb_ident));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) {
-+ ERROR(
-+ "pfkey_ident_parse: "
-+ "ident_type=%d out of range, must be less than %d.\n",
-+ pfkey_ident->sadb_ident_type,
-+ SADB_IDENTTYPE_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_ident->sadb_ident_reserved) {
-+ ERROR(
-+ "pfkey_ident_parse: "
-+ "res=%d, must be zero.\n",
-+ pfkey_ident->sadb_ident_reserved);
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* string terminator/padding must be zero */
-+ if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
-+ if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) {
-+ ERROR(
-+ "pfkey_ident_parse: "
-+ "string padding must be zero, last is 0x%02x.\n",
-+ *((char*)pfkey_ident +
-+ pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1));
-+ SENDERR(EINVAL);
-+ }
-+ }
-+
-+ if( ! ((pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) ||
-+ (pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_DST))) {
-+ ERROR(
-+ "pfkey_key_parse: "
-+ "expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n",
-+ pfkey_ident->sadb_ident_exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_sens_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext;
-+
-+ /* sanity checks... */
-+ if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_sens_parse: "
-+ "size wrong ext_len=%d, key_ext_len=%d.\n",
-+ pfkey_sens->sadb_sens_len,
-+ (int)sizeof(struct sadb_sens));
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_sens_parse: "
-+ "Sorry, I can't parse exttype=%d yet.\n",
-+ pfkey_ext->sadb_ext_type);
-+#if 0
-+ SENDERR(EINVAL); /* don't process these yet */
-+#endif
-+
-+errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_prop_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ int i, num_comb;
-+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext;
-+ struct sadb_comb *pfkey_comb = (struct sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop));
-+
-+ /* sanity checks... */
-+ if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) ||
-+ (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n",
-+ pfkey_prop->sadb_prop_len,
-+ (int)sizeof(struct sadb_prop),
-+ (int)sizeof(struct sadb_comb));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_prop->sadb_prop_replay > 64) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "replay window size: %d -- must be 0 <= size <= 64\n",
-+ pfkey_prop->sadb_prop_replay);
-+ SENDERR(EINVAL);
-+ }
-+
-+ for(i=0; i<3; i++) {
-+ if(pfkey_prop->sadb_prop_reserved[i]) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "res[%d]=%d, must be zero.\n",
-+ i, pfkey_prop->sadb_prop_reserved[i]);
-+ SENDERR(EINVAL);
-+ }
-+ }
-+
-+ num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb);
-+
-+ for(i = 0; i < num_comb; i++) {
-+ if(pfkey_comb->sadb_comb_auth > SADB_AALG_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_auth=%d > SADB_AALG_MAX=%d.\n",
-+ i,
-+ pfkey_comb->sadb_comb_auth,
-+ SADB_AALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_comb->sadb_comb_auth) {
-+ if(!pfkey_comb->sadb_comb_auth_minbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n",
-+ i);
-+ SENDERR(EINVAL);
-+ }
-+ if(!pfkey_comb->sadb_comb_auth_maxbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n",
-+ i);
-+ SENDERR(EINVAL);
-+ }
-+ if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n",
-+ i,
-+ pfkey_comb->sadb_comb_auth_minbits,
-+ pfkey_comb->sadb_comb_auth_maxbits);
-+ SENDERR(EINVAL);
-+ }
-+ } else {
-+ if(pfkey_comb->sadb_comb_auth_minbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n",
-+ i,
-+ pfkey_comb->sadb_comb_auth_minbits);
-+ SENDERR(EINVAL);
-+ }
-+ if(pfkey_comb->sadb_comb_auth_maxbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n",
-+ i,
-+ pfkey_comb->sadb_comb_auth_maxbits);
-+ SENDERR(EINVAL);
-+ }
-+ }
-+
-+ if(pfkey_comb->sadb_comb_encrypt > SADB_EALG_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_comb_parse: "
-+ "pfkey_comb[%d]->sadb_comb_encrypt=%d > SADB_EALG_MAX=%d.\n",
-+ i,
-+ pfkey_comb->sadb_comb_encrypt,
-+ SADB_EALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_comb->sadb_comb_encrypt) {
-+ if(!pfkey_comb->sadb_comb_encrypt_minbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n",
-+ i);
-+ SENDERR(EINVAL);
-+ }
-+ if(!pfkey_comb->sadb_comb_encrypt_maxbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n",
-+ i);
-+ SENDERR(EINVAL);
-+ }
-+ if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n",
-+ i,
-+ pfkey_comb->sadb_comb_encrypt_minbits,
-+ pfkey_comb->sadb_comb_encrypt_maxbits);
-+ SENDERR(EINVAL);
-+ }
-+ } else {
-+ if(pfkey_comb->sadb_comb_encrypt_minbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n",
-+ i,
-+ pfkey_comb->sadb_comb_encrypt_minbits);
-+ SENDERR(EINVAL);
-+ }
-+ if(pfkey_comb->sadb_comb_encrypt_maxbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n",
-+ i,
-+ pfkey_comb->sadb_comb_encrypt_maxbits);
-+ SENDERR(EINVAL);
-+ }
-+ }
-+
-+ /* XXX do sanity check on flags */
-+
-+ if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n",
-+ i,
-+ pfkey_comb->sadb_comb_soft_allocations,
-+ pfkey_comb->sadb_comb_hard_allocations);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n",
-+ i,
-+ (unsigned long long int)pfkey_comb->sadb_comb_soft_bytes,
-+ (unsigned long long int)pfkey_comb->sadb_comb_hard_bytes);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n",
-+ i,
-+ (unsigned long long int)pfkey_comb->sadb_comb_soft_addtime,
-+ (unsigned long long int)pfkey_comb->sadb_comb_hard_addtime);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n",
-+ i,
-+ (unsigned long long int)pfkey_comb->sadb_comb_soft_usetime,
-+ (unsigned long long int)pfkey_comb->sadb_comb_hard_usetime);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_comb->sadb_x_comb_hard_packets && pfkey_comb->sadb_x_comb_soft_packets > pfkey_comb->sadb_x_comb_hard_packets) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_x_comb_soft_packets=%d > hard_packets=%d, fatal.\n",
-+ i,
-+ pfkey_comb->sadb_x_comb_soft_packets,
-+ pfkey_comb->sadb_x_comb_hard_packets);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_comb->sadb_comb_reserved) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "comb[%d].res=%d, must be zero.\n",
-+ i,
-+ pfkey_comb->sadb_comb_reserved);
-+ SENDERR(EINVAL);
-+ }
-+ pfkey_comb++;
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_supported_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ unsigned int i, num_alg;
-+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext;
-+ struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported));
-+
-+ /* sanity checks... */
-+ if((pfkey_supported->sadb_supported_len <
-+ sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) ||
-+ (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) -
-+ sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) {
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_supported_parse: "
-+ "size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n",
-+ pfkey_supported->sadb_supported_len,
-+ (int)sizeof(struct sadb_supported),
-+ (int)sizeof(struct sadb_alg));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_supported->sadb_supported_reserved) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_supported_parse: "
-+ "res=%d, must be zero.\n",
-+ pfkey_supported->sadb_supported_reserved);
-+ SENDERR(EINVAL);
-+ }
-+
-+ num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg);
-+
-+ for(i = 0; i < num_alg; i++) {
-+ /* process algo description */
-+ if(pfkey_alg->sadb_alg_reserved) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_supported_parse: "
-+ "alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n",
-+ i,
-+ pfkey_alg->sadb_alg_id,
-+ pfkey_alg->sadb_alg_ivlen,
-+ pfkey_alg->sadb_alg_minbits,
-+ pfkey_alg->sadb_alg_maxbits,
-+ pfkey_alg->sadb_alg_reserved);
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* XXX can alg_id auth/enc be determined from info given?
-+ Yes, but OpenBSD's method does not iteroperate with rfc2367.
-+ rgb, 2000-04-06 */
-+
-+ switch(pfkey_supported->sadb_supported_exttype) {
-+ case SADB_EXT_SUPPORTED_AUTH:
-+ if(pfkey_alg->sadb_alg_id > SADB_AALG_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_supported_parse: "
-+ "alg[%d], alg_id=%d > SADB_AALG_MAX=%d, fatal.\n",
-+ i,
-+ pfkey_alg->sadb_alg_id,
-+ SADB_AALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+ break;
-+ case SADB_EXT_SUPPORTED_ENCRYPT:
-+ if(pfkey_alg->sadb_alg_id > SADB_EALG_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_supported_parse: "
-+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
-+ i,
-+ pfkey_alg->sadb_alg_id,
-+ SADB_EALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+ break;
-+ default:
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_supported_parse: "
-+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
-+ i,
-+ pfkey_alg->sadb_alg_id,
-+ SADB_EALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+ pfkey_alg++;
-+ }
-+
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_spirange_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext;
-+
-+ /* sanity checks... */
-+ if(pfkey_spirange->sadb_spirange_len !=
-+ sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_spirange_parse: "
-+ "size wrong ext_len=%d, key_ext_len=%d.\n",
-+ pfkey_spirange->sadb_spirange_len,
-+ (int)sizeof(struct sadb_spirange));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_spirange->sadb_spirange_reserved) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_spirange_parse: "
-+ "reserved=%d must be set to zero.\n",
-+ pfkey_spirange->sadb_spirange_reserved);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_spirange_parse: "
-+ "minspi=%08x must be < maxspi=%08x.\n",
-+ ntohl(pfkey_spirange->sadb_spirange_min),
-+ ntohl(pfkey_spirange->sadb_spirange_max));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_spirange_parse: "
-+ "minspi=%08x must be > 255.\n",
-+ ntohl(pfkey_spirange->sadb_spirange_min));
-+ SENDERR(EEXIST);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_spirange_parse: "
-+ "ext_len=%u ext_type=%u(%s) min=%u max=%u res=%u.\n",
-+ pfkey_spirange->sadb_spirange_len,
-+ pfkey_spirange->sadb_spirange_exttype,
-+ pfkey_v2_sadb_ext_string(pfkey_spirange->sadb_spirange_exttype),
-+ pfkey_spirange->sadb_spirange_min,
-+ pfkey_spirange->sadb_spirange_max,
-+ pfkey_spirange->sadb_spirange_reserved);
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext;
-+
-+ /* sanity checks... */
-+ if(pfkey_x_kmprivate->sadb_x_kmprivate_len <
-+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_kmprivate_parse: "
-+ "size wrong ext_len=%d, key_ext_len=%d.\n",
-+ pfkey_x_kmprivate->sadb_x_kmprivate_len,
-+ (int)sizeof(struct sadb_x_kmprivate));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_kmprivate_parse: "
-+ "reserved=%d must be set to zero.\n",
-+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_kmprivate_parse: "
-+ "Sorry, I can't parse exttype=%d yet.\n",
-+ pfkey_ext->sadb_ext_type);
-+ SENDERR(EINVAL); /* don't process these yet */
-+
-+errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_satype_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ int i;
-+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-+ "pfkey_x_satype_parse: enter\n");
-+ /* sanity checks... */
-+ if(pfkey_x_satype->sadb_x_satype_len !=
-+ sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_satype_parse: "
-+ "size wrong ext_len=%d, key_ext_len=%d.\n",
-+ pfkey_x_satype->sadb_x_satype_len,
-+ (int)sizeof(struct sadb_x_satype));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!pfkey_x_satype->sadb_x_satype_satype) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_satype_parse: "
-+ "satype is zero, must be non-zero.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_x_satype->sadb_x_satype_satype > SADB_SATYPE_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_satype_parse: "
-+ "satype %d > max %d, invalid.\n",
-+ pfkey_x_satype->sadb_x_satype_satype, SADB_SATYPE_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_satype_parse: "
-+ "proto lookup from satype=%d failed.\n",
-+ pfkey_x_satype->sadb_x_satype_satype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ for(i = 0; i < 3; i++) {
-+ if(pfkey_x_satype->sadb_x_satype_reserved[i]) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_satype_parse: "
-+ "reserved[%d]=%d must be set to zero.\n",
-+ i, pfkey_x_satype->sadb_x_satype_reserved[i]);
-+ SENDERR(EINVAL);
-+ }
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_x_satype_parse: "
-+ "len=%u ext=%u(%s) satype=%u(%s) res=%u,%u,%u.\n",
-+ pfkey_x_satype->sadb_x_satype_len,
-+ pfkey_x_satype->sadb_x_satype_exttype,
-+ pfkey_v2_sadb_ext_string(pfkey_x_satype->sadb_x_satype_exttype),
-+ pfkey_x_satype->sadb_x_satype_satype,
-+ satype2name(pfkey_x_satype->sadb_x_satype_satype),
-+ pfkey_x_satype->sadb_x_satype_reserved[0],
-+ pfkey_x_satype->sadb_x_satype_reserved[1],
-+ pfkey_x_satype->sadb_x_satype_reserved[2]);
-+errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ int i;
-+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-+ "pfkey_x_debug_parse: enter\n");
-+ /* sanity checks... */
-+ if(pfkey_x_debug->sadb_x_debug_len !=
-+ sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_debug_parse: "
-+ "size wrong ext_len=%d, key_ext_len=%d.\n",
-+ pfkey_x_debug->sadb_x_debug_len,
-+ (int)sizeof(struct sadb_x_debug));
-+ SENDERR(EINVAL);
-+ }
-+
-+ for(i = 0; i < 4; i++) {
-+ if(pfkey_x_debug->sadb_x_debug_reserved[i]) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_debug_parse: "
-+ "reserved[%d]=%d must be set to zero.\n",
-+ i, pfkey_x_debug->sadb_x_debug_reserved[i]);
-+ SENDERR(EINVAL);
-+ }
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_ext_protocol_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_protocol *p = (struct sadb_protocol *)pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, "pfkey_x_protocol_parse:\n");
-+ /* sanity checks... */
-+
-+ if (p->sadb_protocol_len != sizeof(*p)/IPSEC_PFKEYv2_ALIGN) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_protocol_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
-+ p->sadb_protocol_len, (int)sizeof(*p));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if (p->sadb_protocol_reserved2 != 0) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_protocol_parse: res=%d, must be zero.\n",
-+ p->sadb_protocol_reserved2);
-+ SENDERR(EINVAL);
-+ }
-+
-+ errlab:
-+ return error;
-+}
-+
-+#ifdef NAT_TRAVERSAL
-+DEBUG_NO_STATIC int
-+pfkey_x_ext_nat_t_type_parse(struct sadb_ext *pfkey_ext)
-+{
-+ return 0;
-+}
-+DEBUG_NO_STATIC int
-+pfkey_x_ext_nat_t_port_parse(struct sadb_ext *pfkey_ext)
-+{
-+ return 0;
-+}
-+#endif
-+
-+#define DEFINEPARSER(NAME) static struct pf_key_ext_parsers_def NAME##_def={NAME, #NAME};
-+
-+DEFINEPARSER(pfkey_sa_parse);
-+DEFINEPARSER(pfkey_lifetime_parse);
-+DEFINEPARSER(pfkey_address_parse);
-+DEFINEPARSER(pfkey_key_parse);
-+DEFINEPARSER(pfkey_ident_parse);
-+DEFINEPARSER(pfkey_sens_parse);
-+DEFINEPARSER(pfkey_prop_parse);
-+DEFINEPARSER(pfkey_supported_parse);
-+DEFINEPARSER(pfkey_spirange_parse);
-+DEFINEPARSER(pfkey_x_kmprivate_parse);
-+DEFINEPARSER(pfkey_x_satype_parse);
-+DEFINEPARSER(pfkey_x_ext_debug_parse);
-+DEFINEPARSER(pfkey_x_ext_protocol_parse);
-+#ifdef NAT_TRAVERSAL
-+DEFINEPARSER(pfkey_x_ext_nat_t_type_parse);
-+DEFINEPARSER(pfkey_x_ext_nat_t_port_parse);
-+#endif
-+
-+struct pf_key_ext_parsers_def *ext_default_parsers[]=
-+{
-+ NULL, /* pfkey_msg_parse, */
-+ &pfkey_sa_parse_def,
-+ &pfkey_lifetime_parse_def,
-+ &pfkey_lifetime_parse_def,
-+ &pfkey_lifetime_parse_def,
-+ &pfkey_address_parse_def,
-+ &pfkey_address_parse_def,
-+ &pfkey_address_parse_def,
-+ &pfkey_key_parse_def,
-+ &pfkey_key_parse_def,
-+ &pfkey_ident_parse_def,
-+ &pfkey_ident_parse_def,
-+ &pfkey_sens_parse_def,
-+ &pfkey_prop_parse_def,
-+ &pfkey_supported_parse_def,
-+ &pfkey_supported_parse_def,
-+ &pfkey_spirange_parse_def,
-+ &pfkey_x_kmprivate_parse_def,
-+ &pfkey_x_satype_parse_def,
-+ &pfkey_sa_parse_def,
-+ &pfkey_address_parse_def,
-+ &pfkey_address_parse_def,
-+ &pfkey_address_parse_def,
-+ &pfkey_address_parse_def,
-+ &pfkey_address_parse_def,
-+ &pfkey_x_ext_debug_parse_def,
-+ &pfkey_x_ext_protocol_parse_def
-+#ifdef NAT_TRAVERSAL
-+ ,
-+ &pfkey_x_ext_nat_t_type_parse_def,
-+ &pfkey_x_ext_nat_t_port_parse_def,
-+ &pfkey_x_ext_nat_t_port_parse_def,
-+ &pfkey_address_parse_def
-+#endif
-+};
-+
-+int
-+pfkey_msg_parse(struct sadb_msg *pfkey_msg,
-+ struct pf_key_ext_parsers_def *ext_parsers[],
-+ struct sadb_ext *extensions[],
-+ int dir)
-+{
-+ int error = 0;
-+ int remain;
-+ struct sadb_ext *pfkey_ext;
-+ int extensions_seen = 0;
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_msg_parse: "
-+ "parsing message ver=%d, type=%d(%s), errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
-+ pfkey_msg->sadb_msg_version,
-+ pfkey_msg->sadb_msg_type,
-+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
-+ pfkey_msg->sadb_msg_errno,
-+ pfkey_msg->sadb_msg_satype,
-+ satype2name(pfkey_msg->sadb_msg_satype),
-+ pfkey_msg->sadb_msg_len,
-+ pfkey_msg->sadb_msg_reserved,
-+ pfkey_msg->sadb_msg_seq,
-+ pfkey_msg->sadb_msg_pid);
-+
-+ if(ext_parsers == NULL) ext_parsers = ext_default_parsers;
-+
-+ pfkey_extensions_init(extensions);
-+
-+ remain = pfkey_msg->sadb_msg_len;
-+ remain -= sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
-+
-+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg +
-+ sizeof(struct sadb_msg));
-+
-+ extensions[0] = (struct sadb_ext *) pfkey_msg;
-+
-+
-+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
-+ ERROR("pfkey_msg_parse: "
-+ "not PF_KEY_V2 msg, found %d, should be %d.\n",
-+ pfkey_msg->sadb_msg_version,
-+ PF_KEY_V2);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!pfkey_msg->sadb_msg_type) {
-+ ERROR("pfkey_msg_parse: "
-+ "msg type not set, must be non-zero..\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_msg->sadb_msg_type > SADB_MAX) {
-+ ERROR("pfkey_msg_parse: "
-+ "msg type=%d > max=%d.\n",
-+ pfkey_msg->sadb_msg_type,
-+ SADB_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_msg->sadb_msg_type) {
-+ case SADB_GETSPI:
-+ case SADB_UPDATE:
-+ case SADB_ADD:
-+ case SADB_DELETE:
-+ case SADB_GET:
-+ case SADB_X_GRPSA:
-+ case SADB_X_ADDFLOW:
-+ if(!satype2proto(pfkey_msg->sadb_msg_satype)) {
-+ ERROR("pfkey_msg_parse: "
-+ "satype %d conversion to proto failed for msg_type %d (%s).\n",
-+ pfkey_msg->sadb_msg_satype,
-+ pfkey_msg->sadb_msg_type,
-+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
-+ SENDERR(EINVAL);
-+ } else {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "satype %d(%s) conversion to proto gives %d for msg_type %d(%s).\n",
-+ pfkey_msg->sadb_msg_satype,
-+ satype2name(pfkey_msg->sadb_msg_satype),
-+ satype2proto(pfkey_msg->sadb_msg_satype),
-+ pfkey_msg->sadb_msg_type,
-+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
-+ }
-+ case SADB_ACQUIRE:
-+ case SADB_REGISTER:
-+ case SADB_EXPIRE:
-+ if(!pfkey_msg->sadb_msg_satype) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "satype is zero, must be non-zero for msg_type %d(%s).\n",
-+ pfkey_msg->sadb_msg_type,
-+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
-+ SENDERR(EINVAL);
-+ }
-+ default:
-+ break;
-+ }
-+
-+ /* errno must not be set in downward messages */
-+ /* this is not entirely true... a response to an ACQUIRE could return an error */
-+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "errno set to %d.\n",
-+ pfkey_msg->sadb_msg_errno);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-+ "pfkey_msg_parse: "
-+ "remain=%d, ext_type=%d(%s), ext_len=%d.\n",
-+ remain,
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-+ pfkey_ext->sadb_ext_len);
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-+ "pfkey_msg_parse: "
-+ "extensions permitted=%08x, required=%08x.\n",
-+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
-+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
-+
-+ extensions_seen = 1;
-+
-+ while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) {
-+ /* Is there enough message left to support another extension header? */
-+ if(remain < pfkey_ext->sadb_ext_len) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "remain %d less than ext len %d.\n",
-+ remain, pfkey_ext->sadb_ext_len);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-+ "pfkey_msg_parse: "
-+ "parsing ext type=%d(%s) remain=%d.\n",
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-+ remain);
-+
-+ /* Is the extension header type valid? */
-+ if((pfkey_ext->sadb_ext_type > SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "ext type %d(%s) invalid, SADB_EXT_MAX=%d.\n",
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-+ SADB_EXT_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* Have we already seen this type of extension? */
-+ if((extensions_seen & ( 1 << pfkey_ext->sadb_ext_type )) != 0)
-+ {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "ext type %d(%s) already seen.\n",
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* Do I even know about this type of extension? */
-+ if(ext_parsers[pfkey_ext->sadb_ext_type]==NULL) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "ext type %d(%s) unknown, ignoring.\n",
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
-+ goto next_ext;
-+ }
-+
-+ /* Is this type of extension permitted for this type of message? */
-+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type] &
-+ 1<<pfkey_ext->sadb_ext_type)) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "ext type %d(%s) not permitted, exts_perm_in=%08x, 1<<type=%08x\n",
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
-+ 1<<pfkey_ext->sadb_ext_type);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_msg_parse: "
-+ "remain=%d ext_type=%d(%s) ext_len=%d parsing ext 0p%p with parser %s.\n",
-+ remain,
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-+ pfkey_ext->sadb_ext_len,
-+ pfkey_ext,
-+ ext_parsers[pfkey_ext->sadb_ext_type]->parser_name);
-+
-+ /* Parse the extension */
-+ if((error =
-+ (*ext_parsers[pfkey_ext->sadb_ext_type]->parser)(pfkey_ext))) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "extension parsing for type %d(%s) failed with error %d.\n",
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-+ error);
-+ SENDERR(-error);
-+ }
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-+ "pfkey_msg_parse: "
-+ "Extension %d(%s) parsed.\n",
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
-+
-+ /* Mark that we have seen this extension and remember the header location */
-+ extensions_seen |= ( 1 << pfkey_ext->sadb_ext_type );
-+ extensions[pfkey_ext->sadb_ext_type] = pfkey_ext;
-+
-+ next_ext:
-+ /* Calculate how much message remains */
-+ remain -= pfkey_ext->sadb_ext_len;
-+
-+ if(!remain) {
-+ break;
-+ }
-+ /* Find the next extension header */
-+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext +
-+ pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
-+ }
-+
-+ if(remain) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "unexpected remainder of %d.\n",
-+ remain);
-+ /* why is there still something remaining? */
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* check required extensions */
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_msg_parse: "
-+ "extensions permitted=%08x, seen=%08x, required=%08x.\n",
-+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
-+ extensions_seen,
-+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
-+
-+ /* don't check further if it is an error return message since it
-+ may not have a body */
-+ if(pfkey_msg->sadb_msg_errno) {
-+ SENDERR(-error);
-+ }
-+
-+ if((extensions_seen &
-+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) !=
-+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "required extensions missing:%08x.\n",
-+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type] -
-+ (extensions_seen &
-+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == SADB_X_DELFLOW)
-+ && ((extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW)
-+ != SADB_X_EXT_ADDRESS_DELFLOW)
-+ && (((extensions_seen & (1<<SADB_EXT_SA)) != (1<<SADB_EXT_SA))
-+ || ((((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_flags
-+ & SADB_X_SAFLAGS_CLEARFLOW)
-+ != SADB_X_SAFLAGS_CLEARFLOW))) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "required SADB_X_DELFLOW extensions missing: either %08x must be present or %08x must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n",
-+ SADB_X_EXT_ADDRESS_DELFLOW
-+ - (extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW),
-+ (1<<SADB_EXT_SA) - (extensions_seen & (1<<SADB_EXT_SA)));
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_msg->sadb_msg_type) {
-+ case SADB_ADD:
-+ case SADB_UPDATE:
-+ /* check maturity */
-+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state !=
-+ SADB_SASTATE_MATURE) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "state=%d for add or update should be MATURE=%d.\n",
-+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
-+ SADB_SASTATE_MATURE);
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* check AH and ESP */
-+ switch(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype) {
-+ case SADB_SATYPE_AH:
-+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
-+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth !=
-+ SADB_AALG_NONE)) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "auth alg is zero, must be non-zero for AH SAs.\n");
-+ SENDERR(EINVAL);
-+ }
-+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt !=
-+ SADB_EALG_NONE) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "AH handed encalg=%d, must be zero.\n",
-+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt);
-+ SENDERR(EINVAL);
-+ }
-+ break;
-+ case SADB_SATYPE_ESP:
-+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
-+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
-+ SADB_EALG_NONE)) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n",
-+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
-+ SENDERR(EINVAL);
-+ }
-+ if((((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt ==
-+ SADB_EALG_NULL) &&
-+ (((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth ==
-+ SADB_AALG_NONE) ) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "ESP handed encNULL+authNONE, illegal combination.\n");
-+ SENDERR(EINVAL);
-+ }
-+ break;
-+ case SADB_X_SATYPE_COMP:
-+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
-+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
-+ SADB_EALG_NONE)) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "encrypt alg=%d is zero, must be non-zero for COMP=%d SAs.\n",
-+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
-+ SENDERR(EINVAL);
-+ }
-+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth !=
-+ SADB_AALG_NONE) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "COMP handed auth=%d, must be zero.\n",
-+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth);
-+ SENDERR(EINVAL);
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+ if(ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi) <= 255) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "spi=%08x must be > 255.\n",
-+ ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi));
-+ SENDERR(EINVAL);
-+ }
-+ default:
-+ break;
-+ }
-+errlab:
-+
-+ return error;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.59 2004/04/18 03:03:49 mcr
-+ * renamed common include files from pluto directory.
-+ *
-+ * Revision 1.58 2004/03/08 01:59:08 ken
-+ * freeswan.h -> openswan.h
-+ *
-+ * Revision 1.57 2003/12/10 01:20:19 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.56 2003/12/04 23:01:12 mcr
-+ * removed ipsec_netlink.h
-+ *
-+ * Revision 1.55 2003/11/07 01:30:37 ken
-+ * Cast sizeof() to int to keep things 64bit clean
-+ *
-+ * Revision 1.54 2003/10/31 02:27:12 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.53.20.2 2003/10/29 01:11:32 mcr
-+ * added debugging for pfkey library.
-+ *
-+ * Revision 1.53.20.1 2003/09/21 13:59:44 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.53 2003/01/30 02:32:09 rgb
-+ *
-+ * Rename SAref table macro names for clarity.
-+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
-+ *
-+ * Revision 1.52 2002/12/30 06:53:07 mcr
-+ * deal with short SA structures... #if 0 out for now. Probably
-+ * not quite the right way.
-+ *
-+ * Revision 1.51 2002/12/13 18:16:02 mcr
-+ * restored sa_ref code
-+ *
-+ * Revision 1.50 2002/12/13 18:06:52 mcr
-+ * temporarily removed sadb_x_sa_ref reference for 2.xx
-+ *
-+ * Revision 1.49 2002/10/05 05:02:58 dhr
-+ *
-+ * C labels go on statements
-+ *
-+ * Revision 1.48 2002/09/20 15:40:45 rgb
-+ * Added sadb_x_sa_ref to struct sadb_sa.
-+ *
-+ * Revision 1.47 2002/09/20 05:01:31 rgb
-+ * Fixed usage of pfkey_lib_debug.
-+ * Format for function declaration style consistency.
-+ * Added text labels to elucidate numeric values presented.
-+ * Re-organised debug output to reduce noise in output.
-+ *
-+ * Revision 1.46 2002/07/24 18:44:54 rgb
-+ * Type fiddling to tame ia64 compiler.
-+ *
-+ * Revision 1.45 2002/05/23 07:14:11 rgb
-+ * Cleaned up %p variants to 0p%p for test suite cleanup.
-+ *
-+ * Revision 1.44 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.43 2002/04/24 07:36:40 mcr
-+ * Moved from ./lib/pfkey_v2_parse.c,v
-+ *
-+ * Revision 1.42 2002/01/29 22:25:36 rgb
-+ * Re-add ipsec_kversion.h to keep MALLOC happy.
-+ *
-+ * Revision 1.41 2002/01/29 01:59:10 mcr
-+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
-+ * updating of IPv6 structures to match latest in6.h version.
-+ * removed dead code from openswan.h that also duplicated kversions.h
-+ * code.
-+ *
-+ * Revision 1.40 2002/01/20 20:34:50 mcr
-+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
-+ *
-+ * Revision 1.39 2001/11/27 05:29:22 mcr
-+ * pfkey parses are now maintained by a structure
-+ * that includes their name for debug purposes.
-+ * DEBUGGING() macro changed so that it takes a debug
-+ * level so that pf_key() can use this to decode the
-+ * structures without innundanting humans.
-+ * Also uses pfkey_v2_sadb_ext_string() in messages.
-+ *
-+ * Revision 1.38 2001/11/06 19:47:47 rgb
-+ * Added packet parameter to lifetime and comb structures.
-+ *
-+ * Revision 1.37 2001/10/18 04:45:24 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/openswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.36 2001/06/14 19:35:16 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.35 2001/05/03 19:44:51 rgb
-+ * Standardise on SENDERR() macro.
-+ *
-+ * Revision 1.34 2001/03/16 07:41:51 rgb
-+ * Put openswan.h include before pluto includes.
-+ *
-+ * Revision 1.33 2001/02/27 07:13:51 rgb
-+ * Added satype2name() function.
-+ * Added text to default satype_tbl entry.
-+ * Added satype2name() conversions for most satype debug output.
-+ *
-+ * Revision 1.32 2001/02/26 20:01:09 rgb
-+ * Added internal IP protocol 61 for magic SAs.
-+ * Ditch unused sadb_satype2proto[], replaced by satype2proto().
-+ * Re-formatted debug output (split lines, consistent spacing).
-+ * Removed acquire, register and expire requirements for a known satype.
-+ * Changed message type checking to a switch structure.
-+ * Verify expected NULL auth for IPCOMP.
-+ * Enforced spi > 0x100 requirement, now that pass uses a magic SA for
-+ * appropriate message types.
-+ *
-+ * Revision 1.31 2000/12/01 07:09:00 rgb
-+ * Added ipcomp sanity check to require encalgo is set.
-+ *
-+ * Revision 1.30 2000/11/17 18:10:30 rgb
-+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
-+ * network byte order since this is the way PF_KEYv2 stored spis.
-+ *
-+ * Revision 1.29 2000/10/12 00:02:39 rgb
-+ * Removed 'format, ##' nonsense from debug macros for RH7.0.
-+ *
-+ * Revision 1.28 2000/09/20 16:23:04 rgb
-+ * Remove over-paranoid extension check in the presence of sadb_msg_errno.
-+ *
-+ * Revision 1.27 2000/09/20 04:04:21 rgb
-+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
-+ * oopsen.
-+ *
-+ * Revision 1.26 2000/09/15 11:37:02 rgb
-+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
-+ * IPCOMP zlib deflate code.
-+ *
-+ * Revision 1.25 2000/09/12 22:35:37 rgb
-+ * Restructured to remove unused extensions from CLEARFLOW messages.
-+ *
-+ * Revision 1.24 2000/09/12 18:59:54 rgb
-+ * Added Gerhard's IPv6 support to pfkey parts of libopenswan.
-+ *
-+ * Revision 1.23 2000/09/12 03:27:00 rgb
-+ * Moved DEBUGGING definition to compile kernel with debug off.
-+ *
-+ * Revision 1.22 2000/09/09 06:39:27 rgb
-+ * Restrict pfkey errno check to downward messages only.
-+ *
-+ * Revision 1.21 2000/09/08 19:22:34 rgb
-+ * Enabled pfkey_sens_parse().
-+ * Added check for errno on downward acquire messages only.
-+ *
-+ * Revision 1.20 2000/09/01 18:48:23 rgb
-+ * Fixed reserved check bug and added debug output in
-+ * pfkey_supported_parse().
-+ * Fixed debug output label bug in pfkey_ident_parse().
-+ *
-+ * Revision 1.19 2000/08/27 01:55:26 rgb
-+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
-+ *
-+ * Revision 1.18 2000/08/24 17:00:36 rgb
-+ * Ignore unknown extensions instead of failing.
-+ *
-+ * Revision 1.17 2000/06/02 22:54:14 rgb
-+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
-+ *
-+ * Revision 1.16 2000/05/10 19:25:11 rgb
-+ * Fleshed out proposal and supported extensions.
-+ *
-+ * Revision 1.15 2000/01/24 21:15:31 rgb
-+ * Added disabled pluto pfkey lib debug flag.
-+ * Added algo debugging reporting.
-+ *
-+ * Revision 1.14 2000/01/22 23:24:29 rgb
-+ * Added new functions proto2satype() and satype2proto() and lookup
-+ * table satype_tbl. Also added proto2name() since it was easy.
-+ *
-+ * Revision 1.13 2000/01/21 09:43:59 rgb
-+ * Cast ntohl(spi) as (unsigned long int) to shut up compiler.
-+ *
-+ * Revision 1.12 2000/01/21 06:28:19 rgb
-+ * Added address cases for eroute flows.
-+ * Indented compiler directives for readability.
-+ * Added klipsdebug switching capability.
-+ *
-+ * Revision 1.11 1999/12/29 21:14:59 rgb
-+ * Fixed debug text cut and paste typo.
-+ *
-+ * Revision 1.10 1999/12/10 17:45:24 rgb
-+ * Added address debugging.
-+ *
-+ * Revision 1.9 1999/12/09 23:11:42 rgb
-+ * Ditched <string.h> include since we no longer use memset().
-+ * Use new pfkey_extensions_init() instead of memset().
-+ * Added check for SATYPE in pfkey_msg_build().
-+ * Tidy up comments and debugging comments.
-+ *
-+ * Revision 1.8 1999/12/07 19:55:26 rgb
-+ * Removed unused first argument from extension parsers.
-+ * Removed static pluto debug flag.
-+ * Moved message type and state checking to pfkey_msg_parse().
-+ * Changed print[fk] type from lx to x to quiet compiler.
-+ * Removed redundant remain check.
-+ * Changed __u* types to uint* to avoid use of asm/types.h and
-+ * sys/types.h in userspace code.
-+ *
-+ * Revision 1.7 1999/12/01 22:20:51 rgb
-+ * Moved pfkey_lib_debug variable into the library.
-+ * Added pfkey version check into header parsing.
-+ * Added check for SATYPE only for those extensions that require a
-+ * non-zero value.
-+ *
-+ * Revision 1.6 1999/11/27 11:58:05 rgb
-+ * Added ipv6 headers.
-+ * Moved sadb_satype2proto protocol lookup table from
-+ * klips/net/ipsec/pfkey_v2_parser.c.
-+ * Enable lifetime_current checking.
-+ * Debugging error messages added.
-+ * Add argument to pfkey_msg_parse() for direction.
-+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
-+ * Add CVS log entry to bottom of file.
-+ * Moved auth and enc alg check to pfkey_msg_parse().
-+ * Enable accidentally disabled spirange parsing.
-+ * Moved protocol/algorithm checks from klips/net/ipsec/pfkey_v2_parser.c
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/prng.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,201 @@
-+/*
-+ * crypto-class pseudorandom number generator
-+ * currently uses same algorithm as RC4(TM), from Schneier 2nd ed p397
-+ * Copyright (C) 2002 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/*
-+ - prng_init - initialize PRNG from a key
-+ */
-+void
-+prng_init(prng, key, keylen)
-+struct prng *prng;
-+const unsigned char *key;
-+size_t keylen;
-+{
-+ unsigned char k[256];
-+ int i, j;
-+ unsigned const char *p;
-+ unsigned const char *keyend = key + keylen;
-+ unsigned char t;
-+
-+ for (i = 0; i <= 255; i++)
-+ prng->sbox[i] = i;
-+ p = key;
-+ for (i = 0; i <= 255; i++) {
-+ k[i] = *p++;
-+ if (p >= keyend)
-+ p = key;
-+ }
-+ j = 0;
-+ for (i = 0; i <= 255; i++) {
-+ j = (j + prng->sbox[i] + k[i]) & 0xff;
-+ t = prng->sbox[i];
-+ prng->sbox[i] = prng->sbox[j];
-+ prng->sbox[j] = t;
-+ k[i] = 0; /* clear out key memory */
-+ }
-+ prng->i = 0;
-+ prng->j = 0;
-+ prng->count = 0;
-+}
-+
-+/*
-+ - prng_bytes - get some pseudorandom bytes from PRNG
-+ */
-+void
-+prng_bytes(prng, dst, dstlen)
-+struct prng *prng;
-+unsigned char *dst;
-+size_t dstlen;
-+{
-+ int i, j, t;
-+ unsigned char *p = dst;
-+ size_t remain = dstlen;
-+# define MAX 4000000000ul
-+
-+ while (remain > 0) {
-+ i = (prng->i + 1) & 0xff;
-+ prng->i = i;
-+ j = (prng->j + prng->sbox[i]) & 0xff;
-+ prng->j = j;
-+ t = prng->sbox[i];
-+ prng->sbox[i] = prng->sbox[j];
-+ prng->sbox[j] = t;
-+ t = (t + prng->sbox[i]) & 0xff;
-+ *p++ = prng->sbox[t];
-+ remain--;
-+ }
-+ if (prng->count < MAX - dstlen)
-+ prng->count += dstlen;
-+ else
-+ prng->count = MAX;
-+}
-+
-+/*
-+ - prnt_count - how many bytes have been extracted from PRNG so far?
-+ */
-+unsigned long
-+prng_count(prng)
-+struct prng *prng;
-+{
-+ return prng->count;
-+}
-+
-+/*
-+ - prng_final - clear out PRNG to ensure nothing left in memory
-+ */
-+void
-+prng_final(prng)
-+struct prng *prng;
-+{
-+ int i;
-+
-+ for (i = 0; i <= 255; i++)
-+ prng->sbox[i] = 0;
-+ prng->i = 0;
-+ prng->j = 0;
-+ prng->count = 0; /* just for good measure */
-+}
-+
-+
-+
-+#ifdef PRNG_MAIN
-+
-+#include <stdio.h>
-+
-+void regress();
-+
-+int
-+main(argc, argv)
-+int argc;
-+char *argv[];
-+{
-+ struct prng pr;
-+ unsigned char buf[100];
-+ unsigned char *p;
-+ size_t n;
-+
-+ if (argc < 2) {
-+ fprintf(stderr, "Usage: %s {key|-r}\n", argv[0]);
-+ exit(2);
-+ }
-+
-+ if (strcmp(argv[1], "-r") == 0) {
-+ regress();
-+ fprintf(stderr, "regress() returned?!?\n");
-+ exit(1);
-+ }
-+
-+ prng_init(&pr, argv[1], strlen(argv[1]));
-+ prng_bytes(&pr, buf, 32);
-+ printf("0x");
-+ for (p = buf, n = 32; n > 0; p++, n--)
-+ printf("%02x", *p);
-+ printf("\n%lu bytes\n", prng_count(&pr));
-+ prng_final(&pr);
-+ exit(0);
-+}
-+
-+void
-+regress()
-+{
-+ struct prng pr;
-+ unsigned char buf[100];
-+ unsigned char *p;
-+ size_t n;
-+ /* somewhat non-random sample key */
-+ unsigned char key[] = "here we go gathering nuts in May";
-+ /* first thirty bytes of output from that key */
-+ unsigned char good[] = "\x3f\x02\x8e\x4a\x2a\xea\x23\x18\x92\x7c"
-+ "\x09\x52\x83\x61\xaa\x26\xce\xbb\x9d\x71"
-+ "\x71\xe5\x10\x22\xaf\x60\x54\x8d\x5b\x28";
-+ int nzero, none;
-+ int show = 0;
-+
-+ prng_init(&pr, key, strlen(key));
-+ prng_bytes(&pr, buf, sizeof(buf));
-+ for (p = buf, n = sizeof(buf); n > 0; p++, n--) {
-+ if (*p == 0)
-+ nzero++;
-+ if (*p == 255)
-+ none++;
-+ }
-+ if (nzero > 3 || none > 3) {
-+ fprintf(stderr, "suspiciously non-random output!\n");
-+ show = 1;
-+ }
-+ if (memcmp(buf, good, strlen(good)) != 0) {
-+ fprintf(stderr, "incorrect output!\n");
-+ show = 1;
-+ }
-+ if (show) {
-+ fprintf(stderr, "0x");
-+ for (p = buf, n = sizeof(buf); n > 0; p++, n--)
-+ fprintf(stderr, "%02x", *p);
-+ fprintf(stderr, "\n");
-+ exit(1);
-+ }
-+ if (prng_count(&pr) != sizeof(buf)) {
-+ fprintf(stderr, "got %u bytes, but count is %lu\n",
-+ sizeof(buf), prng_count(&pr));
-+ exit(1);
-+ }
-+ prng_final(&pr);
-+ exit(0);
-+}
-+
-+#endif /* PRNG_MAIN */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/rangetoa.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,60 @@
-+/*
-+ * convert binary form of address range to ASCII
-+ * Copyright (C) 1998, 1999 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/*
-+ - rangetoa - convert address range to ASCII
-+ */
-+size_t /* space needed for full conversion */
-+rangetoa(addrs, format, dst, dstlen)
-+struct in_addr addrs[2];
-+int format; /* character */
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ size_t len;
-+ size_t rest;
-+ int n;
-+ char *p;
-+
-+ switch (format) {
-+ case 0:
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+
-+ len = addrtoa(addrs[0], 0, dst, dstlen);
-+ if (len < dstlen)
-+ for (p = dst + len - 1, n = 3; len < dstlen && n > 0;
-+ p++, len++, n--)
-+ *p = '.';
-+ else
-+ p = NULL;
-+ if (len < dstlen)
-+ rest = dstlen - len;
-+ else {
-+ if (dstlen > 0)
-+ *(dst + dstlen - 1) = '\0';
-+ rest = 0;
-+ }
-+
-+ len += addrtoa(addrs[1], 0, p, rest);
-+
-+ return len;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/satot.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,133 @@
-+/*
-+ * convert from binary form of SA ID to text
-+ * Copyright (C) 2000, 2001 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+static struct typename {
-+ char type;
-+ char *name;
-+} typenames[] = {
-+ { SA_AH, "ah" },
-+ { SA_ESP, "esp" },
-+ { SA_IPIP, "tun" },
-+ { SA_COMP, "comp" },
-+ { SA_INT, "int" },
-+ { 0, NULL }
-+};
-+
-+/*
-+ - satot - convert SA to text "ah507@1.2.3.4"
-+ */
-+size_t /* space needed for full conversion */
-+satot(sa, format, dst, dstlen)
-+const ip_said *sa;
-+int format; /* character */
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ size_t len = 0; /* 0 means "not recognized yet" */
-+ int base;
-+ int showversion; /* use delimiter to show IP version? */
-+ struct typename *tn;
-+ char *p;
-+ char *pre;
-+ char buf[10+1+ULTOT_BUF+ADDRTOT_BUF];
-+ char unk[10];
-+
-+ switch (format) {
-+ case 0:
-+ base = 16;
-+ showversion = 1;
-+ break;
-+ case 'f':
-+ base = 17;
-+ showversion = 1;
-+ break;
-+ case 'x':
-+ base = 'x';
-+ showversion = 0;
-+ break;
-+ case 'd':
-+ base = 10;
-+ showversion = 0;
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+
-+ memset(buf, 0, sizeof(buf));
-+
-+ pre = NULL;
-+ for (tn = typenames; tn->name != NULL; tn++)
-+ if (sa->proto == tn->type) {
-+ pre = tn->name;
-+ break; /* NOTE BREAK OUT */
-+ }
-+ if (pre == NULL) { /* unknown protocol */
-+ strcpy(unk, "unk");
-+ (void) ultot((unsigned char)sa->proto, 10, unk+strlen(unk),
-+ sizeof(unk)-strlen(unk));
-+ pre = unk;
-+ }
-+
-+ if (strcmp(pre, PASSTHROUGHTYPE) == 0 &&
-+ sa->spi == PASSTHROUGHSPI &&
-+ isunspecaddr(&sa->dst)) {
-+ strcpy(buf, (addrtypeof(&sa->dst) == AF_INET) ?
-+ PASSTHROUGH4NAME :
-+ PASSTHROUGH6NAME);
-+ len = strlen(buf);
-+ }
-+
-+ if (sa->proto == SA_INT) {
-+ switch (ntohl(sa->spi)) {
-+ case SPI_PASS: p = "%pass"; break;
-+ case SPI_DROP: p = "%drop"; break;
-+ case SPI_REJECT: p = "%reject"; break;
-+ case SPI_HOLD: p = "%hold"; break;
-+ case SPI_TRAP: p = "%trap"; break;
-+ case SPI_TRAPSUBNET: p = "%trapsubnet"; break;
-+ default: p = NULL; break;
-+ }
-+ if (p != NULL) {
-+ strcpy(buf, p);
-+ len = strlen(buf);
-+ }
-+ }
-+
-+ if (len == 0) { /* general case needed */
-+ strcpy(buf, pre);
-+ len = strlen(buf);
-+ if (showversion) {
-+ *(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' :
-+ ':';
-+ len++;
-+ *(buf+len) = '\0';
-+ }
-+ len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len);
-+ *(buf+len-1) = '@';
-+ len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len);
-+ *(buf+len) = '\0';
-+ }
-+
-+ if (dst != NULL) {
-+ if (len > dstlen)
-+ *(buf+dstlen-1) = '\0';
-+ strcpy(dst, buf);
-+ }
-+ return len;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/subnetof.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,59 @@
-+/*
-+ * minor network-address manipulation utilities
-+ * Copyright (C) 1998, 1999 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/*
-+ - subnetof - given address and mask, return subnet part
-+ */
-+struct in_addr
-+subnetof(addr, mask)
-+struct in_addr addr;
-+struct in_addr mask;
-+{
-+ struct in_addr result;
-+
-+ result.s_addr = addr.s_addr & mask.s_addr;
-+ return result;
-+}
-+
-+/*
-+ - hostof - given address and mask, return host part
-+ */
-+struct in_addr
-+hostof(addr, mask)
-+struct in_addr addr;
-+struct in_addr mask;
-+{
-+ struct in_addr result;
-+
-+ result.s_addr = addr.s_addr & ~mask.s_addr;
-+ return result;
-+}
-+
-+/*
-+ - broadcastof - given (network) address and mask, return broadcast address
-+ */
-+struct in_addr
-+broadcastof(addr, mask)
-+struct in_addr addr;
-+struct in_addr mask;
-+{
-+ struct in_addr result;
-+
-+ result.s_addr = addr.s_addr | ~mask.s_addr;
-+ return result;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/subnettoa.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,61 @@
-+/*
-+ * convert binary form of subnet description to ASCII
-+ * Copyright (C) 1998, 1999 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/*
-+ - subnettoa - convert address and mask to ASCII "addr/mask"
-+ * Output expresses the mask as a bit count if possible, else dotted decimal.
-+ */
-+size_t /* space needed for full conversion */
-+subnettoa(addr, mask, format, dst, dstlen)
-+struct in_addr addr;
-+struct in_addr mask;
-+int format; /* character */
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ size_t len;
-+ size_t rest;
-+ int n;
-+ char *p;
-+
-+ switch (format) {
-+ case 0:
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+
-+ len = addrtoa(addr, 0, dst, dstlen);
-+ if (len < dstlen) {
-+ dst[len - 1] = '/';
-+ p = dst + len;
-+ rest = dstlen - len;
-+ } else {
-+ p = NULL;
-+ rest = 0;
-+ }
-+
-+ n = masktobits(mask);
-+ if (n >= 0)
-+ len += ultoa((unsigned long)n, 10, p, rest);
-+ else
-+ len += addrtoa(mask, 0, p, rest);
-+
-+ return len;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/ultoa.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,66 @@
-+/*
-+ * convert unsigned long to ASCII
-+ * Copyright (C) 1998, 1999 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/*
-+ - ultoa - convert unsigned long to decimal ASCII
-+ */
-+size_t /* length required for full conversion */
-+ultoa(n, base, dst, dstlen)
-+unsigned long n;
-+int base;
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ char buf[3*sizeof(unsigned long) + 1];
-+ char *bufend = buf + sizeof(buf);
-+ size_t len;
-+ char *p;
-+ static char hex[] = "0123456789abcdef";
-+
-+ p = bufend;
-+ *--p = '\0';
-+ if (base == 10) {
-+ do {
-+ *--p = n%10 + '0';
-+ n /= 10;
-+ } while (n != 0);
-+ } else if (base == 16) {
-+ do {
-+ *--p = hex[n&0xf];
-+ n >>= 4;
-+ } while (n != 0);
-+ *--p = 'x';
-+ *--p = '0';
-+ } else if (base == 8) {
-+ do {
-+ *--p = (n&07) + '0';
-+ n >>= 3;
-+ } while (n != 0);
-+ *--p = '0';
-+ } else
-+ *--p = '?';
-+
-+ len = bufend - p;
-+
-+ if (dstlen > 0) {
-+ if (len > dstlen)
-+ *(p + dstlen - 1) = '\0';
-+ strcpy(dst, p);
-+ }
-+ return len;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/ultot.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,82 @@
-+/*
-+ * convert unsigned long to text
-+ * Copyright (C) 2000 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/*
-+ - ultot - convert unsigned long to text
-+ */
-+size_t /* length required for full conversion */
-+ultot(n, base, dst, dstlen)
-+unsigned long n;
-+int base;
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ char buf[3*sizeof(unsigned long) + 1];
-+ char *bufend = buf + sizeof(buf);
-+ size_t len;
-+ char *p;
-+ static char hex[] = "0123456789abcdef";
-+# define HEX32 (32/4)
-+
-+ p = bufend;
-+ *--p = '\0';
-+ switch (base) {
-+ case 10:
-+ case 'd':
-+ do {
-+ *--p = n%10 + '0';
-+ n /= 10;
-+ } while (n != 0);
-+ break;
-+ case 16:
-+ case 17:
-+ case 'x':
-+ do {
-+ *--p = hex[n&0xf];
-+ n >>= 4;
-+ } while (n != 0);
-+ if (base == 17)
-+ while (bufend - p < HEX32 + 1)
-+ *--p = '0';
-+ if (base == 'x') {
-+ *--p = 'x';
-+ *--p = '0';
-+ }
-+ break;
-+ case 8:
-+ case 'o':
-+ do {
-+ *--p = (n&07) + '0';
-+ n >>= 3;
-+ } while (n != 0);
-+ if (base == 'o')
-+ *--p = '0';
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+
-+ len = bufend - p;
-+ if (dstlen > 0) {
-+ if (len > dstlen)
-+ *(p + dstlen - 1) = '\0';
-+ strcpy(dst, p);
-+ }
-+ return len;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/Makefile Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,118 @@
-+# (kernel) Makefile for IPCOMP zlib deflate code
-+# Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+# Copyright (C) 2000 Svenning Soerensen
-+#
-+# 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+#
-+# 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.
-+#
-+# RCSID $Id$
-+#
-+
-+
-+
-+include ../Makefile.inc
-+
-+
-+
-+ifndef TOPDIR
-+TOPDIR := /usr/src/linux
-+endif
-+
-+
-+L_TARGET := zlib.a
-+
-+obj-y :=
-+
-+include Makefile.objs
-+
-+EXTRA_CFLAGS += $(KLIPSCOMPILE)
-+
-+EXTRA_CFLAGS += -Wall
-+#EXTRA_CFLAGS += -Wconversion
-+#EXTRA_CFLAGS += -Wmissing-prototypes
-+EXTRA_CFLAGS += -Wpointer-arith
-+#EXTRA_CFLAGS += -Wcast-qual
-+#EXTRA_CFLAGS += -Wmissing-declarations
-+EXTRA_CFLAGS += -Wstrict-prototypes
-+#EXTRA_CFLAGS += -pedantic
-+#EXTRA_CFLAGS += -W
-+#EXTRA_CFLAGS += -Wwrite-strings
-+EXTRA_CFLAGS += -Wbad-function-cast
-+EXTRA_CFLAGS += -DIPCOMP_PREFIX
-+
-+.S.o:
-+ $(CC) -D__ASSEMBLY__ -DNO_UNDERLINE -traditional -c $< -o $*.o
-+
-+asm-obj-$(CONFIG_M586) += match586.o
-+asm-obj-$(CONFIG_M586TSC) += match586.o
-+asm-obj-$(CONFIG_M586MMX) += match586.o
-+asm-obj-$(CONFIG_M686) += match686.o
-+asm-obj-$(CONFIG_MPENTIUMIII) += match686.o
-+asm-obj-$(CONFIG_MPENTIUM4) += match686.o
-+asm-obj-$(CONFIG_MK6) += match586.o
-+asm-obj-$(CONFIG_MK7) += match686.o
-+asm-obj-$(CONFIG_MCRUSOE) += match586.o
-+asm-obj-$(CONFIG_MWINCHIPC6) += match586.o
-+asm-obj-$(CONFIG_MWINCHIP2) += match686.o
-+asm-obj-$(CONFIG_MWINCHIP3D) += match686.o
-+
-+obj-y += $(asm-obj-y)
-+ifneq ($(strip $(asm-obj-y)),)
-+ EXTRA_CFLAGS += -DASMV
-+endif
-+
-+active-objs := $(sort $(obj-y) $(obj-m))
-+L_OBJS := $(obj-y)
-+M_OBJS := $(obj-m)
-+MIX_OBJS := $(filter $(export-objs), $(active-objs))
-+
-+include $(TOPDIR)/Rules.make
-+
-+$(obj-y) : $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
-+
-+
-+clean:
-+ -rm -f *.o *.a
-+
-+checkprograms:
-+programs: $(L_TARGET)
-+
-+#
-+# $Log$
-+# Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+# Turn off EOLN_NATIVE flag
-+#
-+# (Logical change 1.5010)
-+#
-+# Revision 1.9 2002/04/24 07:55:32 mcr
-+# #include patches and Makefiles for post-reorg compilation.
-+#
-+# Revision 1.8 2002/04/24 07:36:44 mcr
-+# Moved from ./zlib/Makefile,v
-+#
-+# Revision 1.7 2002/03/27 23:34:35 mcr
-+# added programs: target
-+#
-+# Revision 1.6 2001/12/05 20:19:08 henry
-+# use new compile-control variable
-+#
-+# Revision 1.5 2001/11/27 16:38:08 mcr
-+# added new "checkprograms" target to deal with programs that
-+# are required for "make check", but that may not be ready to
-+# build for every user due to external dependancies.
-+#
-+# Revision 1.4 2001/10/24 14:46:24 henry
-+# Makefile.inc
-+#
-+# Revision 1.3 2001/04/21 23:05:24 rgb
-+# Update asm directives for 2.4 style makefiles.
-+#
-+# Revision 1.2 2001/01/29 22:22:00 rgb
-+# Convert to 2.4 new style with back compat.
-+#
-+# Revision 1.1.1.1 2000/09/29 18:51:33 rgb
-+# zlib_beginnings
-+#
-+#
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/Makefile.objs Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,27 @@
-+obj-$(CONFIG_IPSEC_IPCOMP) += adler32.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += deflate.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += infblock.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += infcodes.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += inffast.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += inflate.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += inftrees.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += infutil.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += trees.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += zutil.o
-+
-+asm-obj-$(CONFIG_M586) += ${LIBZLIBSRCDIR}/match586.o
-+asm-obj-$(CONFIG_M586TSC) += ${LIBZLIBSRCDIR}/match586.o
-+asm-obj-$(CONFIG_M586MMX) += ${LIBZLIBSRCDIR}/match586.o
-+asm-obj-$(CONFIG_M686) += ${LIBZLIBSRCDIR}/match686.o
-+asm-obj-$(CONFIG_MPENTIUMIII) += ${LIBZLIBSRCDIR}/match686.o
-+asm-obj-$(CONFIG_MPENTIUM4) += ${LIBZLIBSRCDIR}/match686.o
-+asm-obj-$(CONFIG_MK6) += ${LIBZLIBSRCDIR}/match586.o
-+asm-obj-$(CONFIG_MK7) += ${LIBZLIBSRCDIR}/match686.o
-+asm-obj-$(CONFIG_MCRUSOE) += ${LIBZLIBSRCDIR}/match586.o
-+asm-obj-$(CONFIG_MWINCHIPC6) += ${LIBZLIBSRCDIR}/match586.o
-+asm-obj-$(CONFIG_MWINCHIP2) += ${LIBZLIBSRCDIR}/match686.o
-+asm-obj-$(CONFIG_MWINCHIP3D) += ${LIBZLIBSRCDIR}/match686.o
-+
-+EXTRA_CFLAGS += -DIPCOMP_PREFIX
-+
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/README Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,147 @@
-+zlib 1.1.4 is a general purpose data compression library. All the code
-+is thread safe. The data format used by the zlib library
-+is described by RFCs (Request for Comments) 1950 to 1952 in the files
-+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
-+format) and rfc1952.txt (gzip format). These documents are also available in
-+other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
-+
-+All functions of the compression library are documented in the file zlib.h
-+(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
-+example of the library is given in the file example.c which also tests that
-+the library is working correctly. Another example is given in the file
-+minigzip.c. The compression library itself is composed of all source files
-+except example.c and minigzip.c.
-+
-+To compile all files and run the test program, follow the instructions
-+given at the top of Makefile. In short "make test; make install"
-+should work for most machines. For Unix: "./configure; make test; make install"
-+For MSDOS, use one of the special makefiles such as Makefile.msc.
-+For VMS, use Make_vms.com or descrip.mms.
-+
-+Questions about zlib should be sent to <zlib@gzip.org>, or to
-+Gilles Vollant <info@winimage.com> for the Windows DLL version.
-+The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/
-+Before reporting a problem, please check this site to verify that
-+you have the latest version of zlib; otherwise get the latest version and
-+check whether the problem still exists or not.
-+
-+PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html
-+before asking for help.
-+
-+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
-+issue of Dr. Dobb's Journal; a copy of the article is available in
-+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
-+
-+The changes made in version 1.1.4 are documented in the file ChangeLog.
-+The only changes made since 1.1.3 are bug corrections:
-+
-+- ZFREE was repeated on same allocation on some error conditions.
-+ This creates a security problem described in
-+ http://www.zlib.org/advisory-2002-03-11.txt
-+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
-+- Avoid accesses before window for invalid distances with inflate window
-+ less than 32K.
-+- force windowBits > 8 to avoid a bug in the encoder for a window size
-+ of 256 bytes. (A complete fix will be available in 1.1.5).
-+
-+The beta version 1.1.5beta includes many more changes. A new official
-+version 1.1.5 will be released as soon as extensive testing has been
-+completed on it.
-+
-+
-+Unsupported third party contributions are provided in directory "contrib".
-+
-+A Java implementation of zlib is available in the Java Development Kit
-+http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
-+See the zlib home page http://www.zlib.org for details.
-+
-+A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
-+is in the CPAN (Comprehensive Perl Archive Network) sites
-+http://www.cpan.org/modules/by-module/Compress/
-+
-+A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
-+is available in Python 1.5 and later versions, see
-+http://www.python.org/doc/lib/module-zlib.html
-+
-+A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
-+is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
-+
-+An experimental package to read and write files in .zip format,
-+written on top of zlib by Gilles Vollant <info@winimage.com>, is
-+available at http://www.winimage.com/zLibDll/unzip.html
-+and also in the contrib/minizip directory of zlib.
-+
-+
-+Notes for some targets:
-+
-+- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
-+ and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
-+ The zlib DLL support was initially done by Alessandro Iacopetti and is
-+ now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
-+ home page at http://www.winimage.com/zLibDll
-+
-+ From Visual Basic, you can call the DLL functions which do not take
-+ a structure as argument: compress, uncompress and all gz* functions.
-+ See contrib/visual-basic.txt for more information, or get
-+ http://www.tcfb.com/dowseware/cmp-z-it.zip
-+
-+- For 64-bit Irix, deflate.c must be compiled without any optimization.
-+ With -O, one libpng test fails. The test works in 32 bit mode (with
-+ the -n32 compiler flag). The compiler bug has been reported to SGI.
-+
-+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1
-+ it works when compiled with cc.
-+
-+- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
-+ is necessary to get gzprintf working correctly. This is done by configure.
-+
-+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
-+ with other compilers. Use "make test" to check your compiler.
-+
-+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
-+
-+- For Turbo C the small model is supported only with reduced performance to
-+ avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
-+
-+- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
-+ Per Harald Myrvang <perm@stud.cs.uit.no>
-+
-+
-+Acknowledgments:
-+
-+ The deflate format used by zlib was defined by Phil Katz. The deflate
-+ and zlib specifications were written by L. Peter Deutsch. Thanks to all the
-+ people who reported problems and suggested various improvements in zlib;
-+ they are too numerous to cite here.
-+
-+Copyright notice:
-+
-+ (C) 1995-2002 Jean-loup Gailly and Mark Adler
-+
-+ This software is provided 'as-is', without any express or implied
-+ warranty. In no event will the authors be held liable for any damages
-+ arising from the use of this software.
-+
-+ Permission is granted to anyone to use this software for any purpose,
-+ including commercial applications, and to alter it and redistribute it
-+ freely, subject to the following restrictions:
-+
-+ 1. The origin of this software must not be misrepresented; you must not
-+ claim that you wrote the original software. If you use this software
-+ in a product, an acknowledgment in the product documentation would be
-+ appreciated but is not required.
-+ 2. Altered source versions must be plainly marked as such, and must not be
-+ misrepresented as being the original software.
-+ 3. This notice may not be removed or altered from any source distribution.
-+
-+ Jean-loup Gailly Mark Adler
-+ jloup@gzip.org madler@alumni.caltech.edu
-+
-+If you use the zlib library in a product, we would appreciate *not*
-+receiving lengthy legal documents to sign. The sources are provided
-+for free but without warranty of any kind. The library has been
-+entirely written by Jean-loup Gailly and Mark Adler; it does not
-+include third-party code.
-+
-+If you redistribute modified sources, we would appreciate that you include
-+in the file ChangeLog history information documenting your changes.
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/README.freeswan Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,13 @@
-+The only changes made to these files for use in FreeS/WAN are:
-+
-+ - In zconf.h, macros are defined to prefix global symbols with "ipcomp_"
-+ (or "_ipcomp"), when compiled with -DIPCOMP_PREFIX.
-+ - The copyright strings are defined local (static)
-+
-+ The above changes are made to avoid name collisions with ppp_deflate
-+ and ext2compr.
-+
-+ - Files not needed for FreeS/WAN have been removed
-+
-+ See the "README" file for information about where to obtain the complete
-+ zlib package.
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/adler32.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,49 @@
-+/* adler32.c -- compute the Adler-32 checksum of a data stream
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* @(#) $Id$ */
-+
-+#include <zlib/zlib.h>
-+#include "zconf.h"
-+
-+#define BASE 65521L /* largest prime smaller than 65536 */
-+#define NMAX 5552
-+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-+
-+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
-+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
-+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
-+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
-+#define DO16(buf) DO8(buf,0); DO8(buf,8);
-+
-+/* ========================================================================= */
-+uLong ZEXPORT adler32(adler, buf, len)
-+ uLong adler;
-+ const Bytef *buf;
-+ uInt len;
-+{
-+ unsigned long s1 = adler & 0xffff;
-+ unsigned long s2 = (adler >> 16) & 0xffff;
-+ int k;
-+
-+ if (buf == Z_NULL) return 1L;
-+
-+ while (len > 0) {
-+ k = len < NMAX ? len : NMAX;
-+ len -= k;
-+ while (k >= 16) {
-+ DO16(buf);
-+ buf += 16;
-+ k -= 16;
-+ }
-+ if (k != 0) do {
-+ s1 += *buf++;
-+ s2 += s1;
-+ } while (--k);
-+ s1 %= BASE;
-+ s2 %= BASE;
-+ }
-+ return (s2 << 16) | s1;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/deflate.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1351 @@
-+/* deflate.c -- compress data using the deflation algorithm
-+ * Copyright (C) 1995-2002 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/*
-+ * ALGORITHM
-+ *
-+ * The "deflation" process depends on being able to identify portions
-+ * of the input text which are identical to earlier input (within a
-+ * sliding window trailing behind the input currently being processed).
-+ *
-+ * The most straightforward technique turns out to be the fastest for
-+ * most input files: try all possible matches and select the longest.
-+ * The key feature of this algorithm is that insertions into the string
-+ * dictionary are very simple and thus fast, and deletions are avoided
-+ * completely. Insertions are performed at each input character, whereas
-+ * string matches are performed only when the previous match ends. So it
-+ * is preferable to spend more time in matches to allow very fast string
-+ * insertions and avoid deletions. The matching algorithm for small
-+ * strings is inspired from that of Rabin & Karp. A brute force approach
-+ * is used to find longer strings when a small match has been found.
-+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
-+ * (by Leonid Broukhis).
-+ * A previous version of this file used a more sophisticated algorithm
-+ * (by Fiala and Greene) which is guaranteed to run in linear amortized
-+ * time, but has a larger average cost, uses more memory and is patented.
-+ * However the F&G algorithm may be faster for some highly redundant
-+ * files if the parameter max_chain_length (described below) is too large.
-+ *
-+ * ACKNOWLEDGEMENTS
-+ *
-+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
-+ * I found it in 'freeze' written by Leonid Broukhis.
-+ * Thanks to many people for bug reports and testing.
-+ *
-+ * REFERENCES
-+ *
-+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
-+ * Available in ftp://ds.internic.net/rfc/rfc1951.txt
-+ *
-+ * A description of the Rabin and Karp algorithm is given in the book
-+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
-+ *
-+ * Fiala,E.R., and Greene,D.H.
-+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
-+ *
-+ */
-+
-+/* @(#) $Id$ */
-+
-+#include "deflate.h"
-+
-+local const char deflate_copyright[] =
-+ " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly ";
-+/*
-+ If you use the zlib library in a product, an acknowledgment is welcome
-+ in the documentation of your product. If for some reason you cannot
-+ include such an acknowledgment, I would appreciate that you keep this
-+ copyright string in the executable of your product.
-+ */
-+
-+/* ===========================================================================
-+ * Function prototypes.
-+ */
-+typedef enum {
-+ need_more, /* block not completed, need more input or more output */
-+ block_done, /* block flush performed */
-+ finish_started, /* finish started, need only more output at next deflate */
-+ finish_done /* finish done, accept no more input or output */
-+} block_state;
-+
-+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
-+/* Compression function. Returns the block state after the call. */
-+
-+local void fill_window OF((deflate_state *s));
-+local block_state deflate_stored OF((deflate_state *s, int flush));
-+local block_state deflate_fast OF((deflate_state *s, int flush));
-+local block_state deflate_slow OF((deflate_state *s, int flush));
-+local void lm_init OF((deflate_state *s));
-+local void putShortMSB OF((deflate_state *s, uInt b));
-+local void flush_pending OF((z_streamp strm));
-+local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
-+#ifdef ASMV
-+ void match_init OF((void)); /* asm code initialization */
-+ uInt longest_match OF((deflate_state *s, IPos cur_match));
-+#else
-+local uInt longest_match OF((deflate_state *s, IPos cur_match));
-+#endif
-+
-+#ifdef DEBUG
-+local void check_match OF((deflate_state *s, IPos start, IPos match,
-+ int length));
-+#endif
-+
-+/* ===========================================================================
-+ * Local data
-+ */
-+
-+#define NIL 0
-+/* Tail of hash chains */
-+
-+#ifndef TOO_FAR
-+# define TOO_FAR 4096
-+#endif
-+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-+
-+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-+/* Minimum amount of lookahead, except at the end of the input file.
-+ * See deflate.c for comments about the MIN_MATCH+1.
-+ */
-+
-+/* Values for max_lazy_match, good_match and max_chain_length, depending on
-+ * the desired pack level (0..9). The values given below have been tuned to
-+ * exclude worst case performance for pathological files. Better values may be
-+ * found for specific files.
-+ */
-+typedef struct config_s {
-+ ush good_length; /* reduce lazy search above this match length */
-+ ush max_lazy; /* do not perform lazy search above this match length */
-+ ush nice_length; /* quit search above this match length */
-+ ush max_chain;
-+ compress_func func;
-+} config;
-+
-+local const config configuration_table[10] = {
-+/* good lazy nice chain */
-+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
-+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
-+/* 2 */ {4, 5, 16, 8, deflate_fast},
-+/* 3 */ {4, 6, 32, 32, deflate_fast},
-+
-+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
-+/* 5 */ {8, 16, 32, 32, deflate_slow},
-+/* 6 */ {8, 16, 128, 128, deflate_slow},
-+/* 7 */ {8, 32, 128, 256, deflate_slow},
-+/* 8 */ {32, 128, 258, 1024, deflate_slow},
-+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
-+
-+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
-+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
-+ * meaning.
-+ */
-+
-+#define EQUAL 0
-+/* result of memcmp for equal strings */
-+
-+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
-+
-+/* ===========================================================================
-+ * Update a hash value with the given input byte
-+ * IN assertion: all calls to to UPDATE_HASH are made with consecutive
-+ * input characters, so that a running hash key can be computed from the
-+ * previous key instead of complete recalculation each time.
-+ */
-+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
-+
-+
-+/* ===========================================================================
-+ * Insert string str in the dictionary and set match_head to the previous head
-+ * of the hash chain (the most recent string with same hash key). Return
-+ * the previous length of the hash chain.
-+ * If this file is compiled with -DFASTEST, the compression level is forced
-+ * to 1, and no hash chains are maintained.
-+ * IN assertion: all calls to to INSERT_STRING are made with consecutive
-+ * input characters and the first MIN_MATCH bytes of str are valid
-+ * (except for the last MIN_MATCH-1 bytes of the input file).
-+ */
-+#ifdef FASTEST
-+#define INSERT_STRING(s, str, match_head) \
-+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
-+ match_head = s->head[s->ins_h], \
-+ s->head[s->ins_h] = (Pos)(str))
-+#else
-+#define INSERT_STRING(s, str, match_head) \
-+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
-+ s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
-+ s->head[s->ins_h] = (Pos)(str))
-+#endif
-+
-+/* ===========================================================================
-+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
-+ * prev[] will be initialized on the fly.
-+ */
-+#define CLEAR_HASH(s) \
-+ s->head[s->hash_size-1] = NIL; \
-+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
-+
-+/* ========================================================================= */
-+int ZEXPORT deflateInit_(strm, level, version, stream_size)
-+ z_streamp strm;
-+ int level;
-+ const char *version;
-+ int stream_size;
-+{
-+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
-+ Z_DEFAULT_STRATEGY, version, stream_size);
-+ /* To do: ignore strm->next_in if we use it as window */
-+}
-+
-+/* ========================================================================= */
-+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
-+ version, stream_size)
-+ z_streamp strm;
-+ int level;
-+ int method;
-+ int windowBits;
-+ int memLevel;
-+ int strategy;
-+ const char *version;
-+ int stream_size;
-+{
-+ deflate_state *s;
-+ int noheader = 0;
-+ static const char* my_version = ZLIB_VERSION;
-+
-+ ushf *overlay;
-+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
-+ * output size for (length,distance) codes is <= 24 bits.
-+ */
-+
-+ if (version == Z_NULL || version[0] != my_version[0] ||
-+ stream_size != sizeof(z_stream)) {
-+ return Z_VERSION_ERROR;
-+ }
-+ if (strm == Z_NULL) return Z_STREAM_ERROR;
-+
-+ strm->msg = Z_NULL;
-+ if (strm->zalloc == Z_NULL) {
-+ return Z_STREAM_ERROR;
-+/* strm->zalloc = zcalloc;
-+ strm->opaque = (voidpf)0;*/
-+ }
-+ if (strm->zfree == Z_NULL) return Z_STREAM_ERROR; /* strm->zfree = zcfree; */
-+
-+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
-+#ifdef FASTEST
-+ level = 1;
-+#endif
-+
-+ if (windowBits < 0) { /* undocumented feature: suppress zlib header */
-+ noheader = 1;
-+ windowBits = -windowBits;
-+ }
-+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
-+ windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
-+ strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
-+ return Z_STREAM_ERROR;
-+ }
-+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
-+ if (s == Z_NULL) return Z_MEM_ERROR;
-+ strm->state = (struct internal_state FAR *)s;
-+ s->strm = strm;
-+
-+ s->noheader = noheader;
-+ s->w_bits = windowBits;
-+ s->w_size = 1 << s->w_bits;
-+ s->w_mask = s->w_size - 1;
-+
-+ s->hash_bits = memLevel + 7;
-+ s->hash_size = 1 << s->hash_bits;
-+ s->hash_mask = s->hash_size - 1;
-+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
-+
-+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
-+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
-+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
-+
-+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
-+
-+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
-+ s->pending_buf = (uchf *) overlay;
-+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
-+
-+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
-+ s->pending_buf == Z_NULL) {
-+ strm->msg = ERR_MSG(Z_MEM_ERROR);
-+ deflateEnd (strm);
-+ return Z_MEM_ERROR;
-+ }
-+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
-+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
-+
-+ s->level = level;
-+ s->strategy = strategy;
-+ s->method = (Byte)method;
-+
-+ return deflateReset(strm);
-+}
-+
-+/* ========================================================================= */
-+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
-+ z_streamp strm;
-+ const Bytef *dictionary;
-+ uInt dictLength;
-+{
-+ deflate_state *s;
-+ uInt length = dictLength;
-+ uInt n;
-+ IPos hash_head = 0;
-+
-+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
-+ strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
-+
-+ s = strm->state;
-+ strm->adler = adler32(strm->adler, dictionary, dictLength);
-+
-+ if (length < MIN_MATCH) return Z_OK;
-+ if (length > MAX_DIST(s)) {
-+ length = MAX_DIST(s);
-+#ifndef USE_DICT_HEAD
-+ dictionary += dictLength - length; /* use the tail of the dictionary */
-+#endif
-+ }
-+ zmemcpy(s->window, dictionary, length);
-+ s->strstart = length;
-+ s->block_start = (long)length;
-+
-+ /* Insert all strings in the hash table (except for the last two bytes).
-+ * s->lookahead stays null, so s->ins_h will be recomputed at the next
-+ * call of fill_window.
-+ */
-+ s->ins_h = s->window[0];
-+ UPDATE_HASH(s, s->ins_h, s->window[1]);
-+ for (n = 0; n <= length - MIN_MATCH; n++) {
-+ INSERT_STRING(s, n, hash_head);
-+ }
-+ if (hash_head) hash_head = 0; /* to make compiler happy */
-+ return Z_OK;
-+}
-+
-+/* ========================================================================= */
-+int ZEXPORT deflateReset (strm)
-+ z_streamp strm;
-+{
-+ deflate_state *s;
-+
-+ if (strm == Z_NULL || strm->state == Z_NULL ||
-+ strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
-+
-+ strm->total_in = strm->total_out = 0;
-+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
-+ strm->data_type = Z_UNKNOWN;
-+
-+ s = (deflate_state *)strm->state;
-+ s->pending = 0;
-+ s->pending_out = s->pending_buf;
-+
-+ if (s->noheader < 0) {
-+ s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
-+ }
-+ s->status = s->noheader ? BUSY_STATE : INIT_STATE;
-+ strm->adler = 1;
-+ s->last_flush = Z_NO_FLUSH;
-+
-+ _tr_init(s);
-+ lm_init(s);
-+
-+ return Z_OK;
-+}
-+
-+/* ========================================================================= */
-+int ZEXPORT deflateParams(strm, level, strategy)
-+ z_streamp strm;
-+ int level;
-+ int strategy;
-+{
-+ deflate_state *s;
-+ compress_func func;
-+ int err = Z_OK;
-+
-+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-+ s = strm->state;
-+
-+ if (level == Z_DEFAULT_COMPRESSION) {
-+ level = 6;
-+ }
-+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
-+ return Z_STREAM_ERROR;
-+ }
-+ func = configuration_table[s->level].func;
-+
-+ if (func != configuration_table[level].func && strm->total_in != 0) {
-+ /* Flush the last buffer: */
-+ err = deflate(strm, Z_PARTIAL_FLUSH);
-+ }
-+ if (s->level != level) {
-+ s->level = level;
-+ s->max_lazy_match = configuration_table[level].max_lazy;
-+ s->good_match = configuration_table[level].good_length;
-+ s->nice_match = configuration_table[level].nice_length;
-+ s->max_chain_length = configuration_table[level].max_chain;
-+ }
-+ s->strategy = strategy;
-+ return err;
-+}
-+
-+/* =========================================================================
-+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
-+ * IN assertion: the stream state is correct and there is enough room in
-+ * pending_buf.
-+ */
-+local void putShortMSB (s, b)
-+ deflate_state *s;
-+ uInt b;
-+{
-+ put_byte(s, (Byte)(b >> 8));
-+ put_byte(s, (Byte)(b & 0xff));
-+}
-+
-+/* =========================================================================
-+ * Flush as much pending output as possible. All deflate() output goes
-+ * through this function so some applications may wish to modify it
-+ * to avoid allocating a large strm->next_out buffer and copying into it.
-+ * (See also read_buf()).
-+ */
-+local void flush_pending(strm)
-+ z_streamp strm;
-+{
-+ unsigned len = strm->state->pending;
-+
-+ if (len > strm->avail_out) len = strm->avail_out;
-+ if (len == 0) return;
-+
-+ zmemcpy(strm->next_out, strm->state->pending_out, len);
-+ strm->next_out += len;
-+ strm->state->pending_out += len;
-+ strm->total_out += len;
-+ strm->avail_out -= len;
-+ strm->state->pending -= len;
-+ if (strm->state->pending == 0) {
-+ strm->state->pending_out = strm->state->pending_buf;
-+ }
-+}
-+
-+/* ========================================================================= */
-+int ZEXPORT deflate (strm, flush)
-+ z_streamp strm;
-+ int flush;
-+{
-+ int old_flush; /* value of flush param for previous deflate call */
-+ deflate_state *s;
-+
-+ if (strm == Z_NULL || strm->state == Z_NULL ||
-+ flush > Z_FINISH || flush < 0) {
-+ return Z_STREAM_ERROR;
-+ }
-+ s = strm->state;
-+
-+ if (strm->next_out == Z_NULL ||
-+ (strm->next_in == Z_NULL && strm->avail_in != 0) ||
-+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
-+ ERR_RETURN(strm, Z_STREAM_ERROR);
-+ }
-+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
-+
-+ s->strm = strm; /* just in case */
-+ old_flush = s->last_flush;
-+ s->last_flush = flush;
-+
-+ /* Write the zlib header */
-+ if (s->status == INIT_STATE) {
-+
-+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
-+ uInt level_flags = (s->level-1) >> 1;
-+
-+ if (level_flags > 3) level_flags = 3;
-+ header |= (level_flags << 6);
-+ if (s->strstart != 0) header |= PRESET_DICT;
-+ header += 31 - (header % 31);
-+
-+ s->status = BUSY_STATE;
-+ putShortMSB(s, header);
-+
-+ /* Save the adler32 of the preset dictionary: */
-+ if (s->strstart != 0) {
-+ putShortMSB(s, (uInt)(strm->adler >> 16));
-+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
-+ }
-+ strm->adler = 1L;
-+ }
-+
-+ /* Flush as much pending output as possible */
-+ if (s->pending != 0) {
-+ flush_pending(strm);
-+ if (strm->avail_out == 0) {
-+ /* Since avail_out is 0, deflate will be called again with
-+ * more output space, but possibly with both pending and
-+ * avail_in equal to zero. There won't be anything to do,
-+ * but this is not an error situation so make sure we
-+ * return OK instead of BUF_ERROR at next call of deflate:
-+ */
-+ s->last_flush = -1;
-+ return Z_OK;
-+ }
-+
-+ /* Make sure there is something to do and avoid duplicate consecutive
-+ * flushes. For repeated and useless calls with Z_FINISH, we keep
-+ * returning Z_STREAM_END instead of Z_BUFF_ERROR.
-+ */
-+ } else if (strm->avail_in == 0 && flush <= old_flush &&
-+ flush != Z_FINISH) {
-+ ERR_RETURN(strm, Z_BUF_ERROR);
-+ }
-+
-+ /* User must not provide more input after the first FINISH: */
-+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
-+ ERR_RETURN(strm, Z_BUF_ERROR);
-+ }
-+
-+ /* Start a new block or continue the current one.
-+ */
-+ if (strm->avail_in != 0 || s->lookahead != 0 ||
-+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
-+ block_state bstate;
-+
-+ bstate = (*(configuration_table[s->level].func))(s, flush);
-+
-+ if (bstate == finish_started || bstate == finish_done) {
-+ s->status = FINISH_STATE;
-+ }
-+ if (bstate == need_more || bstate == finish_started) {
-+ if (strm->avail_out == 0) {
-+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
-+ }
-+ return Z_OK;
-+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
-+ * of deflate should use the same flush parameter to make sure
-+ * that the flush is complete. So we don't have to output an
-+ * empty block here, this will be done at next call. This also
-+ * ensures that for a very small output buffer, we emit at most
-+ * one empty block.
-+ */
-+ }
-+ if (bstate == block_done) {
-+ if (flush == Z_PARTIAL_FLUSH) {
-+ _tr_align(s);
-+ } else { /* FULL_FLUSH or SYNC_FLUSH */
-+ _tr_stored_block(s, (char*)0, 0L, 0);
-+ /* For a full flush, this empty block will be recognized
-+ * as a special marker by inflate_sync().
-+ */
-+ if (flush == Z_FULL_FLUSH) {
-+ CLEAR_HASH(s); /* forget history */
-+ }
-+ }
-+ flush_pending(strm);
-+ if (strm->avail_out == 0) {
-+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
-+ return Z_OK;
-+ }
-+ }
-+ }
-+ Assert(strm->avail_out > 0, "bug2");
-+
-+ if (flush != Z_FINISH) return Z_OK;
-+ if (s->noheader) return Z_STREAM_END;
-+
-+ /* Write the zlib trailer (adler32) */
-+ putShortMSB(s, (uInt)(strm->adler >> 16));
-+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
-+ flush_pending(strm);
-+ /* If avail_out is zero, the application will call deflate again
-+ * to flush the rest.
-+ */
-+ s->noheader = -1; /* write the trailer only once! */
-+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
-+}
-+
-+/* ========================================================================= */
-+int ZEXPORT deflateEnd (strm)
-+ z_streamp strm;
-+{
-+ int status;
-+
-+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-+
-+ status = strm->state->status;
-+ if (status != INIT_STATE && status != BUSY_STATE &&
-+ status != FINISH_STATE) {
-+ return Z_STREAM_ERROR;
-+ }
-+
-+ /* Deallocate in reverse order of allocations: */
-+ TRY_FREE(strm, strm->state->pending_buf);
-+ TRY_FREE(strm, strm->state->head);
-+ TRY_FREE(strm, strm->state->prev);
-+ TRY_FREE(strm, strm->state->window);
-+
-+ ZFREE(strm, strm->state);
-+ strm->state = Z_NULL;
-+
-+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
-+}
-+
-+/* =========================================================================
-+ * Copy the source state to the destination state.
-+ * To simplify the source, this is not supported for 16-bit MSDOS (which
-+ * doesn't have enough memory anyway to duplicate compression states).
-+ */
-+int ZEXPORT deflateCopy (dest, source)
-+ z_streamp dest;
-+ z_streamp source;
-+{
-+#ifdef MAXSEG_64K
-+ return Z_STREAM_ERROR;
-+#else
-+ deflate_state *ds;
-+ deflate_state *ss;
-+ ushf *overlay;
-+
-+
-+ if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
-+ return Z_STREAM_ERROR;
-+ }
-+
-+ ss = source->state;
-+
-+ *dest = *source;
-+
-+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
-+ if (ds == Z_NULL) return Z_MEM_ERROR;
-+ dest->state = (struct internal_state FAR *) ds;
-+ *ds = *ss;
-+ ds->strm = dest;
-+
-+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
-+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
-+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
-+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
-+ ds->pending_buf = (uchf *) overlay;
-+
-+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
-+ ds->pending_buf == Z_NULL) {
-+ deflateEnd (dest);
-+ return Z_MEM_ERROR;
-+ }
-+ /* following zmemcpy do not work for 16-bit MSDOS */
-+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
-+ zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
-+ zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
-+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
-+
-+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
-+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
-+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
-+
-+ ds->l_desc.dyn_tree = ds->dyn_ltree;
-+ ds->d_desc.dyn_tree = ds->dyn_dtree;
-+ ds->bl_desc.dyn_tree = ds->bl_tree;
-+
-+ return Z_OK;
-+#endif
-+}
-+
-+/* ===========================================================================
-+ * Read a new buffer from the current input stream, update the adler32
-+ * and total number of bytes read. All deflate() input goes through
-+ * this function so some applications may wish to modify it to avoid
-+ * allocating a large strm->next_in buffer and copying from it.
-+ * (See also flush_pending()).
-+ */
-+local int read_buf(strm, buf, size)
-+ z_streamp strm;
-+ Bytef *buf;
-+ unsigned size;
-+{
-+ unsigned len = strm->avail_in;
-+
-+ if (len > size) len = size;
-+ if (len == 0) return 0;
-+
-+ strm->avail_in -= len;
-+
-+ if (!strm->state->noheader) {
-+ strm->adler = adler32(strm->adler, strm->next_in, len);
-+ }
-+ zmemcpy(buf, strm->next_in, len);
-+ strm->next_in += len;
-+ strm->total_in += len;
-+
-+ return (int)len;
-+}
-+
-+/* ===========================================================================
-+ * Initialize the "longest match" routines for a new zlib stream
-+ */
-+local void lm_init (s)
-+ deflate_state *s;
-+{
-+ s->window_size = (ulg)2L*s->w_size;
-+
-+ CLEAR_HASH(s);
-+
-+ /* Set the default configuration parameters:
-+ */
-+ s->max_lazy_match = configuration_table[s->level].max_lazy;
-+ s->good_match = configuration_table[s->level].good_length;
-+ s->nice_match = configuration_table[s->level].nice_length;
-+ s->max_chain_length = configuration_table[s->level].max_chain;
-+
-+ s->strstart = 0;
-+ s->block_start = 0L;
-+ s->lookahead = 0;
-+ s->match_length = s->prev_length = MIN_MATCH-1;
-+ s->match_available = 0;
-+ s->ins_h = 0;
-+#ifdef ASMV
-+ match_init(); /* initialize the asm code */
-+#endif
-+}
-+
-+/* ===========================================================================
-+ * Set match_start to the longest match starting at the given string and
-+ * return its length. Matches shorter or equal to prev_length are discarded,
-+ * in which case the result is equal to prev_length and match_start is
-+ * garbage.
-+ * IN assertions: cur_match is the head of the hash chain for the current
-+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
-+ * OUT assertion: the match length is not greater than s->lookahead.
-+ */
-+#ifndef ASMV
-+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
-+ * match.S. The code will be functionally equivalent.
-+ */
-+#ifndef FASTEST
-+local uInt longest_match(s, cur_match)
-+ deflate_state *s;
-+ IPos cur_match; /* current match */
-+{
-+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
-+ register Bytef *scan = s->window + s->strstart; /* current string */
-+ register Bytef *match; /* matched string */
-+ register int len; /* length of current match */
-+ int best_len = s->prev_length; /* best match length so far */
-+ int nice_match = s->nice_match; /* stop if match long enough */
-+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
-+ s->strstart - (IPos)MAX_DIST(s) : NIL;
-+ /* Stop when cur_match becomes <= limit. To simplify the code,
-+ * we prevent matches with the string of window index 0.
-+ */
-+ Posf *prev = s->prev;
-+ uInt wmask = s->w_mask;
-+
-+#ifdef UNALIGNED_OK
-+ /* Compare two bytes at a time. Note: this is not always beneficial.
-+ * Try with and without -DUNALIGNED_OK to check.
-+ */
-+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
-+ register ush scan_start = *(ushf*)scan;
-+ register ush scan_end = *(ushf*)(scan+best_len-1);
-+#else
-+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-+ register Byte scan_end1 = scan[best_len-1];
-+ register Byte scan_end = scan[best_len];
-+#endif
-+
-+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
-+ * It is easy to get rid of this optimization if necessary.
-+ */
-+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-+
-+ /* Do not waste too much time if we already have a good match: */
-+ if (s->prev_length >= s->good_match) {
-+ chain_length >>= 2;
-+ }
-+ /* Do not look for matches beyond the end of the input. This is necessary
-+ * to make deflate deterministic.
-+ */
-+ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-+
-+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-+
-+ do {
-+ Assert(cur_match < s->strstart, "no future");
-+ match = s->window + cur_match;
-+
-+ /* Skip to next match if the match length cannot increase
-+ * or if the match length is less than 2:
-+ */
-+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
-+ /* This code assumes sizeof(unsigned short) == 2. Do not use
-+ * UNALIGNED_OK if your compiler uses a different size.
-+ */
-+ if (*(ushf*)(match+best_len-1) != scan_end ||
-+ *(ushf*)match != scan_start) continue;
-+
-+ /* It is not necessary to compare scan[2] and match[2] since they are
-+ * always equal when the other bytes match, given that the hash keys
-+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
-+ * strstart+3, +5, ... up to strstart+257. We check for insufficient
-+ * lookahead only every 4th comparison; the 128th check will be made
-+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
-+ * necessary to put more guard bytes at the end of the window, or
-+ * to check more often for insufficient lookahead.
-+ */
-+ Assert(scan[2] == match[2], "scan[2]?");
-+ scan++, match++;
-+ do {
-+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-+ scan < strend);
-+ /* The funny "do {}" generates better code on most compilers */
-+
-+ /* Here, scan <= window+strstart+257 */
-+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-+ if (*scan == *match) scan++;
-+
-+ len = (MAX_MATCH - 1) - (int)(strend-scan);
-+ scan = strend - (MAX_MATCH-1);
-+
-+#else /* UNALIGNED_OK */
-+
-+ if (match[best_len] != scan_end ||
-+ match[best_len-1] != scan_end1 ||
-+ *match != *scan ||
-+ *++match != scan[1]) continue;
-+
-+ /* The check at best_len-1 can be removed because it will be made
-+ * again later. (This heuristic is not always a win.)
-+ * It is not necessary to compare scan[2] and match[2] since they
-+ * are always equal when the other bytes match, given that
-+ * the hash keys are equal and that HASH_BITS >= 8.
-+ */
-+ scan += 2, match++;
-+ Assert(*scan == *match, "match[2]?");
-+
-+ /* We check for insufficient lookahead only every 8th comparison;
-+ * the 256th check will be made at strstart+258.
-+ */
-+ do {
-+ } while (*++scan == *++match && *++scan == *++match &&
-+ *++scan == *++match && *++scan == *++match &&
-+ *++scan == *++match && *++scan == *++match &&
-+ *++scan == *++match && *++scan == *++match &&
-+ scan < strend);
-+
-+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-+
-+ len = MAX_MATCH - (int)(strend - scan);
-+ scan = strend - MAX_MATCH;
-+
-+#endif /* UNALIGNED_OK */
-+
-+ if (len > best_len) {
-+ s->match_start = cur_match;
-+ best_len = len;
-+ if (len >= nice_match) break;
-+#ifdef UNALIGNED_OK
-+ scan_end = *(ushf*)(scan+best_len-1);
-+#else
-+ scan_end1 = scan[best_len-1];
-+ scan_end = scan[best_len];
-+#endif
-+ }
-+ } while ((cur_match = prev[cur_match & wmask]) > limit
-+ && --chain_length != 0);
-+
-+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
-+ return s->lookahead;
-+}
-+
-+#else /* FASTEST */
-+/* ---------------------------------------------------------------------------
-+ * Optimized version for level == 1 only
-+ */
-+local uInt longest_match(s, cur_match)
-+ deflate_state *s;
-+ IPos cur_match; /* current match */
-+{
-+ register Bytef *scan = s->window + s->strstart; /* current string */
-+ register Bytef *match; /* matched string */
-+ register int len; /* length of current match */
-+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-+
-+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
-+ * It is easy to get rid of this optimization if necessary.
-+ */
-+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-+
-+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-+
-+ Assert(cur_match < s->strstart, "no future");
-+
-+ match = s->window + cur_match;
-+
-+ /* Return failure if the match length is less than 2:
-+ */
-+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
-+
-+ /* The check at best_len-1 can be removed because it will be made
-+ * again later. (This heuristic is not always a win.)
-+ * It is not necessary to compare scan[2] and match[2] since they
-+ * are always equal when the other bytes match, given that
-+ * the hash keys are equal and that HASH_BITS >= 8.
-+ */
-+ scan += 2, match += 2;
-+ Assert(*scan == *match, "match[2]?");
-+
-+ /* We check for insufficient lookahead only every 8th comparison;
-+ * the 256th check will be made at strstart+258.
-+ */
-+ do {
-+ } while (*++scan == *++match && *++scan == *++match &&
-+ *++scan == *++match && *++scan == *++match &&
-+ *++scan == *++match && *++scan == *++match &&
-+ *++scan == *++match && *++scan == *++match &&
-+ scan < strend);
-+
-+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-+
-+ len = MAX_MATCH - (int)(strend - scan);
-+
-+ if (len < MIN_MATCH) return MIN_MATCH - 1;
-+
-+ s->match_start = cur_match;
-+ return len <= s->lookahead ? len : s->lookahead;
-+}
-+#endif /* FASTEST */
-+#endif /* ASMV */
-+
-+#ifdef DEBUG
-+/* ===========================================================================
-+ * Check that the match at match_start is indeed a match.
-+ */
-+local void check_match(s, start, match, length)
-+ deflate_state *s;
-+ IPos start, match;
-+ int length;
-+{
-+ /* check that the match is indeed a match */
-+ if (zmemcmp(s->window + match,
-+ s->window + start, length) != EQUAL) {
-+ fprintf(stderr, " start %u, match %u, length %d\n",
-+ start, match, length);
-+ do {
-+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
-+ } while (--length != 0);
-+ z_error("invalid match");
-+ }
-+ if (z_verbose > 1) {
-+ fprintf(stderr,"\\[%d,%d]", start-match, length);
-+ do { putc(s->window[start++], stderr); } while (--length != 0);
-+ }
-+}
-+#else
-+# define check_match(s, start, match, length)
-+#endif
-+
-+/* ===========================================================================
-+ * Fill the window when the lookahead becomes insufficient.
-+ * Updates strstart and lookahead.
-+ *
-+ * IN assertion: lookahead < MIN_LOOKAHEAD
-+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
-+ * At least one byte has been read, or avail_in == 0; reads are
-+ * performed for at least two bytes (required for the zip translate_eol
-+ * option -- not supported here).
-+ */
-+local void fill_window(s)
-+ deflate_state *s;
-+{
-+ register unsigned n, m;
-+ register Posf *p;
-+ unsigned more; /* Amount of free space at the end of the window. */
-+ uInt wsize = s->w_size;
-+
-+ do {
-+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
-+
-+ /* Deal with !@#$% 64K limit: */
-+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
-+ more = wsize;
-+
-+ } else if (more == (unsigned)(-1)) {
-+ /* Very unlikely, but possible on 16 bit machine if strstart == 0
-+ * and lookahead == 1 (input done one byte at time)
-+ */
-+ more--;
-+
-+ /* If the window is almost full and there is insufficient lookahead,
-+ * move the upper half to the lower one to make room in the upper half.
-+ */
-+ } else if (s->strstart >= wsize+MAX_DIST(s)) {
-+
-+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
-+ s->match_start -= wsize;
-+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
-+ s->block_start -= (long) wsize;
-+
-+ /* Slide the hash table (could be avoided with 32 bit values
-+ at the expense of memory usage). We slide even when level == 0
-+ to keep the hash table consistent if we switch back to level > 0
-+ later. (Using level 0 permanently is not an optimal usage of
-+ zlib, so we don't care about this pathological case.)
-+ */
-+ n = s->hash_size;
-+ p = &s->head[n];
-+ do {
-+ m = *--p;
-+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
-+ } while (--n);
-+
-+ n = wsize;
-+#ifndef FASTEST
-+ p = &s->prev[n];
-+ do {
-+ m = *--p;
-+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
-+ /* If n is not on any hash chain, prev[n] is garbage but
-+ * its value will never be used.
-+ */
-+ } while (--n);
-+#endif
-+ more += wsize;
-+ }
-+ if (s->strm->avail_in == 0) return;
-+
-+ /* If there was no sliding:
-+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
-+ * more == window_size - lookahead - strstart
-+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
-+ * => more >= window_size - 2*WSIZE + 2
-+ * In the BIG_MEM or MMAP case (not yet supported),
-+ * window_size == input_size + MIN_LOOKAHEAD &&
-+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
-+ * Otherwise, window_size == 2*WSIZE so more >= 2.
-+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
-+ */
-+ Assert(more >= 2, "more < 2");
-+
-+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
-+ s->lookahead += n;
-+
-+ /* Initialize the hash value now that we have some input: */
-+ if (s->lookahead >= MIN_MATCH) {
-+ s->ins_h = s->window[s->strstart];
-+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-+#if MIN_MATCH != 3
-+ Call UPDATE_HASH() MIN_MATCH-3 more times
-+#endif
-+ }
-+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
-+ * but this is not important since only literal bytes will be emitted.
-+ */
-+
-+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
-+}
-+
-+/* ===========================================================================
-+ * Flush the current block, with given end-of-file flag.
-+ * IN assertion: strstart is set to the end of the current match.
-+ */
-+#define FLUSH_BLOCK_ONLY(s, eof) { \
-+ _tr_flush_block(s, (s->block_start >= 0L ? \
-+ (charf *)&s->window[(unsigned)s->block_start] : \
-+ (charf *)Z_NULL), \
-+ (ulg)((long)s->strstart - s->block_start), \
-+ (eof)); \
-+ s->block_start = s->strstart; \
-+ flush_pending(s->strm); \
-+ Tracev((stderr,"[FLUSH]")); \
-+}
-+
-+/* Same but force premature exit if necessary. */
-+#define FLUSH_BLOCK(s, eof) { \
-+ FLUSH_BLOCK_ONLY(s, eof); \
-+ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
-+}
-+
-+/* ===========================================================================
-+ * Copy without compression as much as possible from the input stream, return
-+ * the current block state.
-+ * This function does not insert new strings in the dictionary since
-+ * uncompressible data is probably not useful. This function is used
-+ * only for the level=0 compression option.
-+ * NOTE: this function should be optimized to avoid extra copying from
-+ * window to pending_buf.
-+ */
-+local block_state deflate_stored(s, flush)
-+ deflate_state *s;
-+ int flush;
-+{
-+ /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
-+ * to pending_buf_size, and each stored block has a 5 byte header:
-+ */
-+ ulg max_block_size = 0xffff;
-+ ulg max_start;
-+
-+ if (max_block_size > s->pending_buf_size - 5) {
-+ max_block_size = s->pending_buf_size - 5;
-+ }
-+
-+ /* Copy as much as possible from input to output: */
-+ for (;;) {
-+ /* Fill the window as much as possible: */
-+ if (s->lookahead <= 1) {
-+
-+ Assert(s->strstart < s->w_size+MAX_DIST(s) ||
-+ s->block_start >= (long)s->w_size, "slide too late");
-+
-+ fill_window(s);
-+ if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
-+
-+ if (s->lookahead == 0) break; /* flush the current block */
-+ }
-+ Assert(s->block_start >= 0L, "block gone");
-+
-+ s->strstart += s->lookahead;
-+ s->lookahead = 0;
-+
-+ /* Emit a stored block if pending_buf will be full: */
-+ max_start = s->block_start + max_block_size;
-+ if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
-+ /* strstart == 0 is possible when wraparound on 16-bit machine */
-+ s->lookahead = (uInt)(s->strstart - max_start);
-+ s->strstart = (uInt)max_start;
-+ FLUSH_BLOCK(s, 0);
-+ }
-+ /* Flush if we may have to slide, otherwise block_start may become
-+ * negative and the data will be gone:
-+ */
-+ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
-+ FLUSH_BLOCK(s, 0);
-+ }
-+ }
-+ FLUSH_BLOCK(s, flush == Z_FINISH);
-+ return flush == Z_FINISH ? finish_done : block_done;
-+}
-+
-+/* ===========================================================================
-+ * Compress as much as possible from the input stream, return the current
-+ * block state.
-+ * This function does not perform lazy evaluation of matches and inserts
-+ * new strings in the dictionary only for unmatched strings or for short
-+ * matches. It is used only for the fast compression options.
-+ */
-+local block_state deflate_fast(s, flush)
-+ deflate_state *s;
-+ int flush;
-+{
-+ IPos hash_head = NIL; /* head of the hash chain */
-+ int bflush; /* set if current block must be flushed */
-+
-+ for (;;) {
-+ /* Make sure that we always have enough lookahead, except
-+ * at the end of the input file. We need MAX_MATCH bytes
-+ * for the next match, plus MIN_MATCH bytes to insert the
-+ * string following the next match.
-+ */
-+ if (s->lookahead < MIN_LOOKAHEAD) {
-+ fill_window(s);
-+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
-+ return need_more;
-+ }
-+ if (s->lookahead == 0) break; /* flush the current block */
-+ }
-+
-+ /* Insert the string window[strstart .. strstart+2] in the
-+ * dictionary, and set hash_head to the head of the hash chain:
-+ */
-+ if (s->lookahead >= MIN_MATCH) {
-+ INSERT_STRING(s, s->strstart, hash_head);
-+ }
-+
-+ /* Find the longest match, discarding those <= prev_length.
-+ * At this point we have always match_length < MIN_MATCH
-+ */
-+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
-+ /* To simplify the code, we prevent matches with the string
-+ * of window index 0 (in particular we have to avoid a match
-+ * of the string with itself at the start of the input file).
-+ */
-+ if (s->strategy != Z_HUFFMAN_ONLY) {
-+ s->match_length = longest_match (s, hash_head);
-+ }
-+ /* longest_match() sets match_start */
-+ }
-+ if (s->match_length >= MIN_MATCH) {
-+ check_match(s, s->strstart, s->match_start, s->match_length);
-+
-+ _tr_tally_dist(s, s->strstart - s->match_start,
-+ s->match_length - MIN_MATCH, bflush);
-+
-+ s->lookahead -= s->match_length;
-+
-+ /* Insert new strings in the hash table only if the match length
-+ * is not too large. This saves time but degrades compression.
-+ */
-+#ifndef FASTEST
-+ if (s->match_length <= s->max_insert_length &&
-+ s->lookahead >= MIN_MATCH) {
-+ s->match_length--; /* string at strstart already in hash table */
-+ do {
-+ s->strstart++;
-+ INSERT_STRING(s, s->strstart, hash_head);
-+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
-+ * always MIN_MATCH bytes ahead.
-+ */
-+ } while (--s->match_length != 0);
-+ s->strstart++;
-+ } else
-+#endif
-+ {
-+ s->strstart += s->match_length;
-+ s->match_length = 0;
-+ s->ins_h = s->window[s->strstart];
-+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-+#if MIN_MATCH != 3
-+ Call UPDATE_HASH() MIN_MATCH-3 more times
-+#endif
-+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
-+ * matter since it will be recomputed at next deflate call.
-+ */
-+ }
-+ } else {
-+ /* No match, output a literal byte */
-+ Tracevv((stderr,"%c", s->window[s->strstart]));
-+ _tr_tally_lit (s, s->window[s->strstart], bflush);
-+ s->lookahead--;
-+ s->strstart++;
-+ }
-+ if (bflush) FLUSH_BLOCK(s, 0);
-+ }
-+ FLUSH_BLOCK(s, flush == Z_FINISH);
-+ return flush == Z_FINISH ? finish_done : block_done;
-+}
-+
-+/* ===========================================================================
-+ * Same as above, but achieves better compression. We use a lazy
-+ * evaluation for matches: a match is finally adopted only if there is
-+ * no better match at the next window position.
-+ */
-+local block_state deflate_slow(s, flush)
-+ deflate_state *s;
-+ int flush;
-+{
-+ IPos hash_head = NIL; /* head of hash chain */
-+ int bflush; /* set if current block must be flushed */
-+
-+ /* Process the input block. */
-+ for (;;) {
-+ /* Make sure that we always have enough lookahead, except
-+ * at the end of the input file. We need MAX_MATCH bytes
-+ * for the next match, plus MIN_MATCH bytes to insert the
-+ * string following the next match.
-+ */
-+ if (s->lookahead < MIN_LOOKAHEAD) {
-+ fill_window(s);
-+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
-+ return need_more;
-+ }
-+ if (s->lookahead == 0) break; /* flush the current block */
-+ }
-+
-+ /* Insert the string window[strstart .. strstart+2] in the
-+ * dictionary, and set hash_head to the head of the hash chain:
-+ */
-+ if (s->lookahead >= MIN_MATCH) {
-+ INSERT_STRING(s, s->strstart, hash_head);
-+ }
-+
-+ /* Find the longest match, discarding those <= prev_length.
-+ */
-+ s->prev_length = s->match_length, s->prev_match = s->match_start;
-+ s->match_length = MIN_MATCH-1;
-+
-+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
-+ s->strstart - hash_head <= MAX_DIST(s)) {
-+ /* To simplify the code, we prevent matches with the string
-+ * of window index 0 (in particular we have to avoid a match
-+ * of the string with itself at the start of the input file).
-+ */
-+ if (s->strategy != Z_HUFFMAN_ONLY) {
-+ s->match_length = longest_match (s, hash_head);
-+ }
-+ /* longest_match() sets match_start */
-+
-+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
-+ (s->match_length == MIN_MATCH &&
-+ s->strstart - s->match_start > TOO_FAR))) {
-+
-+ /* If prev_match is also MIN_MATCH, match_start is garbage
-+ * but we will ignore the current match anyway.
-+ */
-+ s->match_length = MIN_MATCH-1;
-+ }
-+ }
-+ /* If there was a match at the previous step and the current
-+ * match is not better, output the previous match:
-+ */
-+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
-+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
-+ /* Do not insert strings in hash table beyond this. */
-+
-+ check_match(s, s->strstart-1, s->prev_match, s->prev_length);
-+
-+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
-+ s->prev_length - MIN_MATCH, bflush);
-+
-+ /* Insert in hash table all strings up to the end of the match.
-+ * strstart-1 and strstart are already inserted. If there is not
-+ * enough lookahead, the last two strings are not inserted in
-+ * the hash table.
-+ */
-+ s->lookahead -= s->prev_length-1;
-+ s->prev_length -= 2;
-+ do {
-+ if (++s->strstart <= max_insert) {
-+ INSERT_STRING(s, s->strstart, hash_head);
-+ }
-+ } while (--s->prev_length != 0);
-+ s->match_available = 0;
-+ s->match_length = MIN_MATCH-1;
-+ s->strstart++;
-+
-+ if (bflush) FLUSH_BLOCK(s, 0);
-+
-+ } else if (s->match_available) {
-+ /* If there was no match at the previous position, output a
-+ * single literal. If there was a match but the current match
-+ * is longer, truncate the previous match to a single literal.
-+ */
-+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
-+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
-+ if (bflush) {
-+ FLUSH_BLOCK_ONLY(s, 0);
-+ }
-+ s->strstart++;
-+ s->lookahead--;
-+ if (s->strm->avail_out == 0) return need_more;
-+ } else {
-+ /* There is no previous match to compare with, wait for
-+ * the next step to decide.
-+ */
-+ s->match_available = 1;
-+ s->strstart++;
-+ s->lookahead--;
-+ }
-+ }
-+ Assert (flush != Z_NO_FLUSH, "no flush?");
-+ if (s->match_available) {
-+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
-+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
-+ s->match_available = 0;
-+ }
-+ FLUSH_BLOCK(s, flush == Z_FINISH);
-+ return flush == Z_FINISH ? finish_done : block_done;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/deflate.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,318 @@
-+/* deflate.h -- internal compression state
-+ * Copyright (C) 1995-2002 Jean-loup Gailly
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+/* @(#) $Id$ */
-+
-+#ifndef _DEFLATE_H
-+#define _DEFLATE_H
-+
-+#include "zlib/zutil.h"
-+
-+/* ===========================================================================
-+ * Internal compression state.
-+ */
-+
-+#define LENGTH_CODES 29
-+/* number of length codes, not counting the special END_BLOCK code */
-+
-+#define LITERALS 256
-+/* number of literal bytes 0..255 */
-+
-+#define L_CODES (LITERALS+1+LENGTH_CODES)
-+/* number of Literal or Length codes, including the END_BLOCK code */
-+
-+#define D_CODES 30
-+/* number of distance codes */
-+
-+#define BL_CODES 19
-+/* number of codes used to transfer the bit lengths */
-+
-+#define HEAP_SIZE (2*L_CODES+1)
-+/* maximum heap size */
-+
-+#define MAX_BITS 15
-+/* All codes must not exceed MAX_BITS bits */
-+
-+#define INIT_STATE 42
-+#define BUSY_STATE 113
-+#define FINISH_STATE 666
-+/* Stream status */
-+
-+
-+/* Data structure describing a single value and its code string. */
-+typedef struct ct_data_s {
-+ union {
-+ ush freq; /* frequency count */
-+ ush code; /* bit string */
-+ } fc;
-+ union {
-+ ush dad; /* father node in Huffman tree */
-+ ush len; /* length of bit string */
-+ } dl;
-+} FAR ct_data;
-+
-+#define Freq fc.freq
-+#define Code fc.code
-+#define Dad dl.dad
-+#define Len dl.len
-+
-+typedef struct static_tree_desc_s static_tree_desc;
-+
-+typedef struct tree_desc_s {
-+ ct_data *dyn_tree; /* the dynamic tree */
-+ int max_code; /* largest code with non zero frequency */
-+ static_tree_desc *stat_desc; /* the corresponding static tree */
-+} FAR tree_desc;
-+
-+typedef ush Pos;
-+typedef Pos FAR Posf;
-+typedef unsigned IPos;
-+
-+/* A Pos is an index in the character window. We use short instead of int to
-+ * save space in the various tables. IPos is used only for parameter passing.
-+ */
-+
-+typedef struct internal_state {
-+ z_streamp strm; /* pointer back to this zlib stream */
-+ int status; /* as the name implies */
-+ Bytef *pending_buf; /* output still pending */
-+ ulg pending_buf_size; /* size of pending_buf */
-+ Bytef *pending_out; /* next pending byte to output to the stream */
-+ int pending; /* nb of bytes in the pending buffer */
-+ int noheader; /* suppress zlib header and adler32 */
-+ Byte data_type; /* UNKNOWN, BINARY or ASCII */
-+ Byte method; /* STORED (for zip only) or DEFLATED */
-+ int last_flush; /* value of flush param for previous deflate call */
-+
-+ /* used by deflate.c: */
-+
-+ uInt w_size; /* LZ77 window size (32K by default) */
-+ uInt w_bits; /* log2(w_size) (8..16) */
-+ uInt w_mask; /* w_size - 1 */
-+
-+ Bytef *window;
-+ /* Sliding window. Input bytes are read into the second half of the window,
-+ * and move to the first half later to keep a dictionary of at least wSize
-+ * bytes. With this organization, matches are limited to a distance of
-+ * wSize-MAX_MATCH bytes, but this ensures that IO is always
-+ * performed with a length multiple of the block size. Also, it limits
-+ * the window size to 64K, which is quite useful on MSDOS.
-+ * To do: use the user input buffer as sliding window.
-+ */
-+
-+ ulg window_size;
-+ /* Actual size of window: 2*wSize, except when the user input buffer
-+ * is directly used as sliding window.
-+ */
-+
-+ Posf *prev;
-+ /* Link to older string with same hash index. To limit the size of this
-+ * array to 64K, this link is maintained only for the last 32K strings.
-+ * An index in this array is thus a window index modulo 32K.
-+ */
-+
-+ Posf *head; /* Heads of the hash chains or NIL. */
-+
-+ uInt ins_h; /* hash index of string to be inserted */
-+ uInt hash_size; /* number of elements in hash table */
-+ uInt hash_bits; /* log2(hash_size) */
-+ uInt hash_mask; /* hash_size-1 */
-+
-+ uInt hash_shift;
-+ /* Number of bits by which ins_h must be shifted at each input
-+ * step. It must be such that after MIN_MATCH steps, the oldest
-+ * byte no longer takes part in the hash key, that is:
-+ * hash_shift * MIN_MATCH >= hash_bits
-+ */
-+
-+ long block_start;
-+ /* Window position at the beginning of the current output block. Gets
-+ * negative when the window is moved backwards.
-+ */
-+
-+ uInt match_length; /* length of best match */
-+ IPos prev_match; /* previous match */
-+ int match_available; /* set if previous match exists */
-+ uInt strstart; /* start of string to insert */
-+ uInt match_start; /* start of matching string */
-+ uInt lookahead; /* number of valid bytes ahead in window */
-+
-+ uInt prev_length;
-+ /* Length of the best match at previous step. Matches not greater than this
-+ * are discarded. This is used in the lazy match evaluation.
-+ */
-+
-+ uInt max_chain_length;
-+ /* To speed up deflation, hash chains are never searched beyond this
-+ * length. A higher limit improves compression ratio but degrades the
-+ * speed.
-+ */
-+
-+ uInt max_lazy_match;
-+ /* Attempt to find a better match only when the current match is strictly
-+ * smaller than this value. This mechanism is used only for compression
-+ * levels >= 4.
-+ */
-+# define max_insert_length max_lazy_match
-+ /* Insert new strings in the hash table only if the match length is not
-+ * greater than this length. This saves time but degrades compression.
-+ * max_insert_length is used only for compression levels <= 3.
-+ */
-+
-+ int level; /* compression level (1..9) */
-+ int strategy; /* favor or force Huffman coding*/
-+
-+ uInt good_match;
-+ /* Use a faster search when the previous match is longer than this */
-+
-+ int nice_match; /* Stop searching when current match exceeds this */
-+
-+ /* used by trees.c: */
-+ /* Didn't use ct_data typedef below to supress compiler warning */
-+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
-+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
-+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
-+
-+ struct tree_desc_s l_desc; /* desc. for literal tree */
-+ struct tree_desc_s d_desc; /* desc. for distance tree */
-+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
-+
-+ ush bl_count[MAX_BITS+1];
-+ /* number of codes at each bit length for an optimal tree */
-+
-+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
-+ int heap_len; /* number of elements in the heap */
-+ int heap_max; /* element of largest frequency */
-+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
-+ * The same heap array is used to build all trees.
-+ */
-+
-+ uch depth[2*L_CODES+1];
-+ /* Depth of each subtree used as tie breaker for trees of equal frequency
-+ */
-+
-+ uchf *l_buf; /* buffer for literals or lengths */
-+
-+ uInt lit_bufsize;
-+ /* Size of match buffer for literals/lengths. There are 4 reasons for
-+ * limiting lit_bufsize to 64K:
-+ * - frequencies can be kept in 16 bit counters
-+ * - if compression is not successful for the first block, all input
-+ * data is still in the window so we can still emit a stored block even
-+ * when input comes from standard input. (This can also be done for
-+ * all blocks if lit_bufsize is not greater than 32K.)
-+ * - if compression is not successful for a file smaller than 64K, we can
-+ * even emit a stored file instead of a stored block (saving 5 bytes).
-+ * This is applicable only for zip (not gzip or zlib).
-+ * - creating new Huffman trees less frequently may not provide fast
-+ * adaptation to changes in the input data statistics. (Take for
-+ * example a binary file with poorly compressible code followed by
-+ * a highly compressible string table.) Smaller buffer sizes give
-+ * fast adaptation but have of course the overhead of transmitting
-+ * trees more frequently.
-+ * - I can't count above 4
-+ */
-+
-+ uInt last_lit; /* running index in l_buf */
-+
-+ ushf *d_buf;
-+ /* Buffer for distances. To simplify the code, d_buf and l_buf have
-+ * the same number of elements. To use different lengths, an extra flag
-+ * array would be necessary.
-+ */
-+
-+ ulg opt_len; /* bit length of current block with optimal trees */
-+ ulg static_len; /* bit length of current block with static trees */
-+ uInt matches; /* number of string matches in current block */
-+ int last_eob_len; /* bit length of EOB code for last block */
-+
-+#ifdef DEBUG
-+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
-+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
-+#endif
-+
-+ ush bi_buf;
-+ /* Output buffer. bits are inserted starting at the bottom (least
-+ * significant bits).
-+ */
-+ int bi_valid;
-+ /* Number of valid bits in bi_buf. All bits above the last valid bit
-+ * are always zero.
-+ */
-+
-+} FAR deflate_state;
-+
-+/* Output a byte on the stream.
-+ * IN assertion: there is enough room in pending_buf.
-+ */
-+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
-+
-+
-+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-+/* Minimum amount of lookahead, except at the end of the input file.
-+ * See deflate.c for comments about the MIN_MATCH+1.
-+ */
-+
-+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
-+/* In order to simplify the code, particularly on 16 bit machines, match
-+ * distances are limited to MAX_DIST instead of WSIZE.
-+ */
-+
-+ /* in trees.c */
-+void _tr_init OF((deflate_state *s));
-+int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
-+void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
-+ int eof));
-+void _tr_align OF((deflate_state *s));
-+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
-+ int eof));
-+
-+#define d_code(dist) \
-+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
-+/* Mapping from a distance to a distance code. dist is the distance - 1 and
-+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
-+ * used.
-+ */
-+
-+#ifndef DEBUG
-+/* Inline versions of _tr_tally for speed: */
-+
-+#if defined(GEN_TREES_H) || !defined(STDC)
-+ extern uch _length_code[];
-+ extern uch _dist_code[];
-+#else
-+ extern const uch _length_code[];
-+ extern const uch _dist_code[];
-+#endif
-+
-+# define _tr_tally_lit(s, c, flush) \
-+ { uch cc = (c); \
-+ s->d_buf[s->last_lit] = 0; \
-+ s->l_buf[s->last_lit++] = cc; \
-+ s->dyn_ltree[cc].Freq++; \
-+ flush = (s->last_lit == s->lit_bufsize-1); \
-+ }
-+# define _tr_tally_dist(s, distance, length, flush) \
-+ { uch len = (length); \
-+ ush dist = (distance); \
-+ s->d_buf[s->last_lit] = dist; \
-+ s->l_buf[s->last_lit++] = len; \
-+ dist--; \
-+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
-+ s->dyn_dtree[d_code(dist)].Freq++; \
-+ flush = (s->last_lit == s->lit_bufsize-1); \
-+ }
-+#else
-+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
-+# define _tr_tally_dist(s, distance, length, flush) \
-+ flush = _tr_tally(s, distance, length)
-+#endif
-+
-+#endif /* _DEFLATE_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/infblock.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,403 @@
-+/* infblock.c -- interpret and process block types to last block
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+#include <zlib/zutil.h>
-+#include "infblock.h"
-+#include "inftrees.h"
-+#include "infcodes.h"
-+#include "infutil.h"
-+
-+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-+
-+/* simplify the use of the inflate_huft type with some defines */
-+#define exop word.what.Exop
-+#define bits word.what.Bits
-+
-+/* Table for deflate from PKZIP's appnote.txt. */
-+local const uInt border[] = { /* Order of the bit length code lengths */
-+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-+
-+/*
-+ Notes beyond the 1.93a appnote.txt:
-+
-+ 1. Distance pointers never point before the beginning of the output
-+ stream.
-+ 2. Distance pointers can point back across blocks, up to 32k away.
-+ 3. There is an implied maximum of 7 bits for the bit length table and
-+ 15 bits for the actual data.
-+ 4. If only one code exists, then it is encoded using one bit. (Zero
-+ would be more efficient, but perhaps a little confusing.) If two
-+ codes exist, they are coded using one bit each (0 and 1).
-+ 5. There is no way of sending zero distance codes--a dummy must be
-+ sent if there are none. (History: a pre 2.0 version of PKZIP would
-+ store blocks with no distance codes, but this was discovered to be
-+ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
-+ zero distance codes, which is sent as one code of zero bits in
-+ length.
-+ 6. There are up to 286 literal/length codes. Code 256 represents the
-+ end-of-block. Note however that the static length tree defines
-+ 288 codes just to fill out the Huffman codes. Codes 286 and 287
-+ cannot be used though, since there is no length base or extra bits
-+ defined for them. Similarily, there are up to 30 distance codes.
-+ However, static trees define 32 codes (all 5 bits) to fill out the
-+ Huffman codes, but the last two had better not show up in the data.
-+ 7. Unzip can check dynamic Huffman blocks for complete code sets.
-+ The exception is that a single code would not be complete (see #4).
-+ 8. The five bits following the block type is really the number of
-+ literal codes sent minus 257.
-+ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
-+ (1+6+6). Therefore, to output three times the length, you output
-+ three codes (1+1+1), whereas to output four times the same length,
-+ you only need two codes (1+3). Hmm.
-+ 10. In the tree reconstruction algorithm, Code = Code + Increment
-+ only if BitLength(i) is not zero. (Pretty obvious.)
-+ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
-+ 12. Note: length code 284 can represent 227-258, but length code 285
-+ really is 258. The last length deserves its own, short code
-+ since it gets used a lot in very redundant files. The length
-+ 258 is special since 258 - 3 (the min match length) is 255.
-+ 13. The literal/length and distance code bit lengths are read as a
-+ single stream of lengths. It is possible (and advantageous) for
-+ a repeat code (16, 17, or 18) to go across the boundary between
-+ the two sets of lengths.
-+ */
-+
-+
-+void inflate_blocks_reset(s, z, c)
-+inflate_blocks_statef *s;
-+z_streamp z;
-+uLongf *c;
-+{
-+ if (c != Z_NULL)
-+ *c = s->check;
-+ if (s->mode == BTREE || s->mode == DTREE)
-+ ZFREE(z, s->sub.trees.blens);
-+ if (s->mode == CODES)
-+ inflate_codes_free(s->sub.decode.codes, z);
-+ s->mode = TYPE;
-+ s->bitk = 0;
-+ s->bitb = 0;
-+ s->read = s->write = s->window;
-+ if (s->checkfn != Z_NULL)
-+ z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
-+ Tracev((stderr, "inflate: blocks reset\n"));
-+}
-+
-+
-+inflate_blocks_statef *inflate_blocks_new(z, c, w)
-+z_streamp z;
-+check_func c;
-+uInt w;
-+{
-+ inflate_blocks_statef *s;
-+
-+ if ((s = (inflate_blocks_statef *)ZALLOC
-+ (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
-+ return s;
-+ if ((s->hufts =
-+ (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
-+ {
-+ ZFREE(z, s);
-+ return Z_NULL;
-+ }
-+ if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
-+ {
-+ ZFREE(z, s->hufts);
-+ ZFREE(z, s);
-+ return Z_NULL;
-+ }
-+ s->end = s->window + w;
-+ s->checkfn = c;
-+ s->mode = TYPE;
-+ Tracev((stderr, "inflate: blocks allocated\n"));
-+ inflate_blocks_reset(s, z, Z_NULL);
-+ return s;
-+}
-+
-+
-+int inflate_blocks(s, z, r)
-+inflate_blocks_statef *s;
-+z_streamp z;
-+int r;
-+{
-+ uInt t; /* temporary storage */
-+ uLong b; /* bit buffer */
-+ uInt k; /* bits in bit buffer */
-+ Bytef *p; /* input data pointer */
-+ uInt n; /* bytes available there */
-+ Bytef *q; /* output window write pointer */
-+ uInt m; /* bytes to end of window or read pointer */
-+
-+ /* copy input/output information to locals (UPDATE macro restores) */
-+ LOAD
-+
-+ /* process input based on current state */
-+ while (1) switch (s->mode)
-+ {
-+ case TYPE:
-+ NEEDBITS(3)
-+ t = (uInt)b & 7;
-+ s->last = t & 1;
-+ switch (t >> 1)
-+ {
-+ case 0: /* stored */
-+ Tracev((stderr, "inflate: stored block%s\n",
-+ s->last ? " (last)" : ""));
-+ DUMPBITS(3)
-+ t = k & 7; /* go to byte boundary */
-+ DUMPBITS(t)
-+ s->mode = LENS; /* get length of stored block */
-+ break;
-+ case 1: /* fixed */
-+ Tracev((stderr, "inflate: fixed codes block%s\n",
-+ s->last ? " (last)" : ""));
-+ {
-+ uInt bl, bd;
-+ inflate_huft *tl, *td;
-+
-+ inflate_trees_fixed(&bl, &bd, &tl, &td, z);
-+ s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
-+ if (s->sub.decode.codes == Z_NULL)
-+ {
-+ r = Z_MEM_ERROR;
-+ LEAVE
-+ }
-+ }
-+ DUMPBITS(3)
-+ s->mode = CODES;
-+ break;
-+ case 2: /* dynamic */
-+ Tracev((stderr, "inflate: dynamic codes block%s\n",
-+ s->last ? " (last)" : ""));
-+ DUMPBITS(3)
-+ s->mode = TABLE;
-+ break;
-+ case 3: /* illegal */
-+ DUMPBITS(3)
-+ s->mode = BAD;
-+ z->msg = (char*)"invalid block type";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ }
-+ break;
-+ case LENS:
-+ NEEDBITS(32)
-+ if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
-+ {
-+ s->mode = BAD;
-+ z->msg = (char*)"invalid stored block lengths";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ }
-+ s->sub.left = (uInt)b & 0xffff;
-+ b = k = 0; /* dump bits */
-+ Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
-+ s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
-+ break;
-+ case STORED:
-+ if (n == 0)
-+ LEAVE
-+ NEEDOUT
-+ t = s->sub.left;
-+ if (t > n) t = n;
-+ if (t > m) t = m;
-+ zmemcpy(q, p, t);
-+ p += t; n -= t;
-+ q += t; m -= t;
-+ if ((s->sub.left -= t) != 0)
-+ break;
-+ Tracev((stderr, "inflate: stored end, %lu total out\n",
-+ z->total_out + (q >= s->read ? q - s->read :
-+ (s->end - s->read) + (q - s->window))));
-+ s->mode = s->last ? DRY : TYPE;
-+ break;
-+ case TABLE:
-+ NEEDBITS(14)
-+ s->sub.trees.table = t = (uInt)b & 0x3fff;
-+#ifndef PKZIP_BUG_WORKAROUND
-+ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
-+ {
-+ s->mode = BAD;
-+ z->msg = (char*)"too many length or distance symbols";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ }
-+#endif
-+ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
-+ if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
-+ {
-+ r = Z_MEM_ERROR;
-+ LEAVE
-+ }
-+ DUMPBITS(14)
-+ s->sub.trees.index = 0;
-+ Tracev((stderr, "inflate: table sizes ok\n"));
-+ s->mode = BTREE;
-+ case BTREE:
-+ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
-+ {
-+ NEEDBITS(3)
-+ s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
-+ DUMPBITS(3)
-+ }
-+ while (s->sub.trees.index < 19)
-+ s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
-+ s->sub.trees.bb = 7;
-+ t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
-+ &s->sub.trees.tb, s->hufts, z);
-+ if (t != Z_OK)
-+ {
-+ r = t;
-+ if (r == Z_DATA_ERROR)
-+ {
-+ ZFREE(z, s->sub.trees.blens);
-+ s->mode = BAD;
-+ }
-+ LEAVE
-+ }
-+ s->sub.trees.index = 0;
-+ Tracev((stderr, "inflate: bits tree ok\n"));
-+ s->mode = DTREE;
-+ case DTREE:
-+ while (t = s->sub.trees.table,
-+ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
-+ {
-+ inflate_huft *h;
-+ uInt i, j, c;
-+
-+ t = s->sub.trees.bb;
-+ NEEDBITS(t)
-+ h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
-+ t = h->bits;
-+ c = h->base;
-+ if (c < 16)
-+ {
-+ DUMPBITS(t)
-+ s->sub.trees.blens[s->sub.trees.index++] = c;
-+ }
-+ else /* c == 16..18 */
-+ {
-+ i = c == 18 ? 7 : c - 14;
-+ j = c == 18 ? 11 : 3;
-+ NEEDBITS(t + i)
-+ DUMPBITS(t)
-+ j += (uInt)b & inflate_mask[i];
-+ DUMPBITS(i)
-+ i = s->sub.trees.index;
-+ t = s->sub.trees.table;
-+ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
-+ (c == 16 && i < 1))
-+ {
-+ ZFREE(z, s->sub.trees.blens);
-+ s->mode = BAD;
-+ z->msg = (char*)"invalid bit length repeat";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ }
-+ c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
-+ do {
-+ s->sub.trees.blens[i++] = c;
-+ } while (--j);
-+ s->sub.trees.index = i;
-+ }
-+ }
-+ s->sub.trees.tb = Z_NULL;
-+ {
-+ uInt bl, bd;
-+ inflate_huft *tl, *td;
-+ inflate_codes_statef *c;
-+
-+ bl = 9; /* must be <= 9 for lookahead assumptions */
-+ bd = 6; /* must be <= 9 for lookahead assumptions */
-+ t = s->sub.trees.table;
-+ t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
-+ s->sub.trees.blens, &bl, &bd, &tl, &td,
-+ s->hufts, z);
-+ if (t != Z_OK)
-+ {
-+ if (t == (uInt)Z_DATA_ERROR)
-+ {
-+ ZFREE(z, s->sub.trees.blens);
-+ s->mode = BAD;
-+ }
-+ r = t;
-+ LEAVE
-+ }
-+ Tracev((stderr, "inflate: trees ok\n"));
-+ if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
-+ {
-+ r = Z_MEM_ERROR;
-+ LEAVE
-+ }
-+ s->sub.decode.codes = c;
-+ }
-+ ZFREE(z, s->sub.trees.blens);
-+ s->mode = CODES;
-+ case CODES:
-+ UPDATE
-+ if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
-+ return inflate_flush(s, z, r);
-+ r = Z_OK;
-+ inflate_codes_free(s->sub.decode.codes, z);
-+ LOAD
-+ Tracev((stderr, "inflate: codes end, %lu total out\n",
-+ z->total_out + (q >= s->read ? q - s->read :
-+ (s->end - s->read) + (q - s->window))));
-+ if (!s->last)
-+ {
-+ s->mode = TYPE;
-+ break;
-+ }
-+ s->mode = DRY;
-+ case DRY:
-+ FLUSH
-+ if (s->read != s->write)
-+ LEAVE
-+ s->mode = DONE;
-+ case DONE:
-+ r = Z_STREAM_END;
-+ LEAVE
-+ case BAD:
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ default:
-+ r = Z_STREAM_ERROR;
-+ LEAVE
-+ }
-+}
-+
-+
-+int inflate_blocks_free(s, z)
-+inflate_blocks_statef *s;
-+z_streamp z;
-+{
-+ inflate_blocks_reset(s, z, Z_NULL);
-+ ZFREE(z, s->window);
-+ ZFREE(z, s->hufts);
-+ ZFREE(z, s);
-+ Tracev((stderr, "inflate: blocks freed\n"));
-+ return Z_OK;
-+}
-+
-+
-+void inflate_set_dictionary(s, d, n)
-+inflate_blocks_statef *s;
-+const Bytef *d;
-+uInt n;
-+{
-+ zmemcpy(s->window, d, n);
-+ s->read = s->write = s->window + n;
-+}
-+
-+
-+/* Returns true if inflate is currently at the end of a block generated
-+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH.
-+ * IN assertion: s != Z_NULL
-+ */
-+int inflate_blocks_sync_point(s)
-+inflate_blocks_statef *s;
-+{
-+ return s->mode == LENS;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/infblock.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,39 @@
-+/* infblock.h -- header to use infblock.c
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+struct inflate_blocks_state;
-+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
-+
-+extern inflate_blocks_statef * inflate_blocks_new OF((
-+ z_streamp z,
-+ check_func c, /* check function */
-+ uInt w)); /* window size */
-+
-+extern int inflate_blocks OF((
-+ inflate_blocks_statef *,
-+ z_streamp ,
-+ int)); /* initial return code */
-+
-+extern void inflate_blocks_reset OF((
-+ inflate_blocks_statef *,
-+ z_streamp ,
-+ uLongf *)); /* check value on output */
-+
-+extern int inflate_blocks_free OF((
-+ inflate_blocks_statef *,
-+ z_streamp));
-+
-+extern void inflate_set_dictionary OF((
-+ inflate_blocks_statef *s,
-+ const Bytef *d, /* dictionary */
-+ uInt n)); /* dictionary length */
-+
-+extern int inflate_blocks_sync_point OF((
-+ inflate_blocks_statef *s));
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/infcodes.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,251 @@
-+/* infcodes.c -- process literals and length/distance pairs
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+#include <zlib/zutil.h>
-+#include "inftrees.h"
-+#include "infblock.h"
-+#include "infcodes.h"
-+#include "infutil.h"
-+#include "inffast.h"
-+
-+/* simplify the use of the inflate_huft type with some defines */
-+#define exop word.what.Exop
-+#define bits word.what.Bits
-+
-+typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
-+ START, /* x: set up for LEN */
-+ LEN, /* i: get length/literal/eob next */
-+ LENEXT, /* i: getting length extra (have base) */
-+ DIST, /* i: get distance next */
-+ DISTEXT, /* i: getting distance extra */
-+ COPY, /* o: copying bytes in window, waiting for space */
-+ LIT, /* o: got literal, waiting for output space */
-+ WASH, /* o: got eob, possibly still output waiting */
-+ END, /* x: got eob and all data flushed */
-+ BADCODE} /* x: got error */
-+inflate_codes_mode;
-+
-+/* inflate codes private state */
-+struct inflate_codes_state {
-+
-+ /* mode */
-+ inflate_codes_mode mode; /* current inflate_codes mode */
-+
-+ /* mode dependent information */
-+ uInt len;
-+ union {
-+ struct {
-+ inflate_huft *tree; /* pointer into tree */
-+ uInt need; /* bits needed */
-+ } code; /* if LEN or DIST, where in tree */
-+ uInt lit; /* if LIT, literal */
-+ struct {
-+ uInt get; /* bits to get for extra */
-+ uInt dist; /* distance back to copy from */
-+ } copy; /* if EXT or COPY, where and how much */
-+ } sub; /* submode */
-+
-+ /* mode independent information */
-+ Byte lbits; /* ltree bits decoded per branch */
-+ Byte dbits; /* dtree bits decoder per branch */
-+ inflate_huft *ltree; /* literal/length/eob tree */
-+ inflate_huft *dtree; /* distance tree */
-+
-+};
-+
-+
-+inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
-+uInt bl, bd;
-+inflate_huft *tl;
-+inflate_huft *td; /* need separate declaration for Borland C++ */
-+z_streamp z;
-+{
-+ inflate_codes_statef *c;
-+
-+ if ((c = (inflate_codes_statef *)
-+ ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
-+ {
-+ c->mode = START;
-+ c->lbits = (Byte)bl;
-+ c->dbits = (Byte)bd;
-+ c->ltree = tl;
-+ c->dtree = td;
-+ Tracev((stderr, "inflate: codes new\n"));
-+ }
-+ return c;
-+}
-+
-+
-+int inflate_codes(s, z, r)
-+inflate_blocks_statef *s;
-+z_streamp z;
-+int r;
-+{
-+ uInt j; /* temporary storage */
-+ inflate_huft *t; /* temporary pointer */
-+ uInt e; /* extra bits or operation */
-+ uLong b; /* bit buffer */
-+ uInt k; /* bits in bit buffer */
-+ Bytef *p; /* input data pointer */
-+ uInt n; /* bytes available there */
-+ Bytef *q; /* output window write pointer */
-+ uInt m; /* bytes to end of window or read pointer */
-+ Bytef *f; /* pointer to copy strings from */
-+ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
-+
-+ /* copy input/output information to locals (UPDATE macro restores) */
-+ LOAD
-+
-+ /* process input and output based on current state */
-+ while (1) switch (c->mode)
-+ { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
-+ case START: /* x: set up for LEN */
-+#ifndef SLOW
-+ if (m >= 258 && n >= 10)
-+ {
-+ UPDATE
-+ r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
-+ LOAD
-+ if (r != Z_OK)
-+ {
-+ c->mode = r == Z_STREAM_END ? WASH : BADCODE;
-+ break;
-+ }
-+ }
-+#endif /* !SLOW */
-+ c->sub.code.need = c->lbits;
-+ c->sub.code.tree = c->ltree;
-+ c->mode = LEN;
-+ case LEN: /* i: get length/literal/eob next */
-+ j = c->sub.code.need;
-+ NEEDBITS(j)
-+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
-+ DUMPBITS(t->bits)
-+ e = (uInt)(t->exop);
-+ if (e == 0) /* literal */
-+ {
-+ c->sub.lit = t->base;
-+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-+ "inflate: literal '%c'\n" :
-+ "inflate: literal 0x%02x\n", t->base));
-+ c->mode = LIT;
-+ break;
-+ }
-+ if (e & 16) /* length */
-+ {
-+ c->sub.copy.get = e & 15;
-+ c->len = t->base;
-+ c->mode = LENEXT;
-+ break;
-+ }
-+ if ((e & 64) == 0) /* next table */
-+ {
-+ c->sub.code.need = e;
-+ c->sub.code.tree = t + t->base;
-+ break;
-+ }
-+ if (e & 32) /* end of block */
-+ {
-+ Tracevv((stderr, "inflate: end of block\n"));
-+ c->mode = WASH;
-+ break;
-+ }
-+ c->mode = BADCODE; /* invalid code */
-+ z->msg = (char*)"invalid literal/length code";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ case LENEXT: /* i: getting length extra (have base) */
-+ j = c->sub.copy.get;
-+ NEEDBITS(j)
-+ c->len += (uInt)b & inflate_mask[j];
-+ DUMPBITS(j)
-+ c->sub.code.need = c->dbits;
-+ c->sub.code.tree = c->dtree;
-+ Tracevv((stderr, "inflate: length %u\n", c->len));
-+ c->mode = DIST;
-+ case DIST: /* i: get distance next */
-+ j = c->sub.code.need;
-+ NEEDBITS(j)
-+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
-+ DUMPBITS(t->bits)
-+ e = (uInt)(t->exop);
-+ if (e & 16) /* distance */
-+ {
-+ c->sub.copy.get = e & 15;
-+ c->sub.copy.dist = t->base;
-+ c->mode = DISTEXT;
-+ break;
-+ }
-+ if ((e & 64) == 0) /* next table */
-+ {
-+ c->sub.code.need = e;
-+ c->sub.code.tree = t + t->base;
-+ break;
-+ }
-+ c->mode = BADCODE; /* invalid code */
-+ z->msg = (char*)"invalid distance code";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ case DISTEXT: /* i: getting distance extra */
-+ j = c->sub.copy.get;
-+ NEEDBITS(j)
-+ c->sub.copy.dist += (uInt)b & inflate_mask[j];
-+ DUMPBITS(j)
-+ Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
-+ c->mode = COPY;
-+ case COPY: /* o: copying bytes in window, waiting for space */
-+ f = q - c->sub.copy.dist;
-+ while (f < s->window) /* modulo window size-"while" instead */
-+ f += s->end - s->window; /* of "if" handles invalid distances */
-+ while (c->len)
-+ {
-+ NEEDOUT
-+ OUTBYTE(*f++)
-+ if (f == s->end)
-+ f = s->window;
-+ c->len--;
-+ }
-+ c->mode = START;
-+ break;
-+ case LIT: /* o: got literal, waiting for output space */
-+ NEEDOUT
-+ OUTBYTE(c->sub.lit)
-+ c->mode = START;
-+ break;
-+ case WASH: /* o: got eob, possibly more output */
-+ if (k > 7) /* return unused byte, if any */
-+ {
-+ Assert(k < 16, "inflate_codes grabbed too many bytes")
-+ k -= 8;
-+ n++;
-+ p--; /* can always return one */
-+ }
-+ FLUSH
-+ if (s->read != s->write)
-+ LEAVE
-+ c->mode = END;
-+ case END:
-+ r = Z_STREAM_END;
-+ LEAVE
-+ case BADCODE: /* x: got error */
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ default:
-+ r = Z_STREAM_ERROR;
-+ LEAVE
-+ }
-+#ifdef NEED_DUMMY_RETURN
-+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
-+#endif
-+}
-+
-+
-+void inflate_codes_free(c, z)
-+inflate_codes_statef *c;
-+z_streamp z;
-+{
-+ ZFREE(z, c);
-+ Tracev((stderr, "inflate: codes free\n"));
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/infcodes.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,31 @@
-+/* infcodes.h -- header to use infcodes.c
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+#ifndef _INFCODES_H
-+#define _INFCODES_H
-+
-+struct inflate_codes_state;
-+typedef struct inflate_codes_state FAR inflate_codes_statef;
-+
-+extern inflate_codes_statef *inflate_codes_new OF((
-+ uInt, uInt,
-+ inflate_huft *, inflate_huft *,
-+ z_streamp ));
-+
-+extern int inflate_codes OF((
-+ inflate_blocks_statef *,
-+ z_streamp ,
-+ int));
-+
-+extern void inflate_codes_free OF((
-+ inflate_codes_statef *,
-+ z_streamp ));
-+
-+#endif /* _INFCODES_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/inffast.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,183 @@
-+/* inffast.c -- process literals and length/distance pairs fast
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+#include <zlib/zutil.h>
-+#include "inftrees.h"
-+#include "infblock.h"
-+#include "infcodes.h"
-+#include "infutil.h"
-+#include "inffast.h"
-+
-+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-+
-+/* simplify the use of the inflate_huft type with some defines */
-+#define exop word.what.Exop
-+#define bits word.what.Bits
-+
-+/* macros for bit input with no checking and for returning unused bytes */
-+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-+#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
-+
-+/* Called with number of bytes left to write in window at least 258
-+ (the maximum string length) and number of input bytes available
-+ at least ten. The ten bytes are six bytes for the longest length/
-+ distance pair plus four bytes for overloading the bit buffer. */
-+
-+int inflate_fast(bl, bd, tl, td, s, z)
-+uInt bl, bd;
-+inflate_huft *tl;
-+inflate_huft *td; /* need separate declaration for Borland C++ */
-+inflate_blocks_statef *s;
-+z_streamp z;
-+{
-+ inflate_huft *t; /* temporary pointer */
-+ uInt e; /* extra bits or operation */
-+ uLong b; /* bit buffer */
-+ uInt k; /* bits in bit buffer */
-+ Bytef *p; /* input data pointer */
-+ uInt n; /* bytes available there */
-+ Bytef *q; /* output window write pointer */
-+ uInt m; /* bytes to end of window or read pointer */
-+ uInt ml; /* mask for literal/length tree */
-+ uInt md; /* mask for distance tree */
-+ uInt c; /* bytes to copy */
-+ uInt d; /* distance back to copy from */
-+ Bytef *r; /* copy source pointer */
-+
-+ /* load input, output, bit values */
-+ LOAD
-+
-+ /* initialize masks */
-+ ml = inflate_mask[bl];
-+ md = inflate_mask[bd];
-+
-+ /* do until not enough input or output space for fast loop */
-+ do { /* assume called with m >= 258 && n >= 10 */
-+ /* get literal/length code */
-+ GRABBITS(20) /* max bits for literal/length code */
-+ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
-+ {
-+ DUMPBITS(t->bits)
-+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-+ "inflate: * literal '%c'\n" :
-+ "inflate: * literal 0x%02x\n", t->base));
-+ *q++ = (Byte)t->base;
-+ m--;
-+ continue;
-+ }
-+ do {
-+ DUMPBITS(t->bits)
-+ if (e & 16)
-+ {
-+ /* get extra bits for length */
-+ e &= 15;
-+ c = t->base + ((uInt)b & inflate_mask[e]);
-+ DUMPBITS(e)
-+ Tracevv((stderr, "inflate: * length %u\n", c));
-+
-+ /* decode distance base of block to copy */
-+ GRABBITS(15); /* max bits for distance code */
-+ e = (t = td + ((uInt)b & md))->exop;
-+ do {
-+ DUMPBITS(t->bits)
-+ if (e & 16)
-+ {
-+ /* get extra bits to add to distance base */
-+ e &= 15;
-+ GRABBITS(e) /* get extra bits (up to 13) */
-+ d = t->base + ((uInt)b & inflate_mask[e]);
-+ DUMPBITS(e)
-+ Tracevv((stderr, "inflate: * distance %u\n", d));
-+
-+ /* do the copy */
-+ m -= c;
-+ r = q - d;
-+ if (r < s->window) /* wrap if needed */
-+ {
-+ do {
-+ r += s->end - s->window; /* force pointer in window */
-+ } while (r < s->window); /* covers invalid distances */
-+ e = s->end - r;
-+ if (c > e)
-+ {
-+ c -= e; /* wrapped copy */
-+ do {
-+ *q++ = *r++;
-+ } while (--e);
-+ r = s->window;
-+ do {
-+ *q++ = *r++;
-+ } while (--c);
-+ }
-+ else /* normal copy */
-+ {
-+ *q++ = *r++; c--;
-+ *q++ = *r++; c--;
-+ do {
-+ *q++ = *r++;
-+ } while (--c);
-+ }
-+ }
-+ else /* normal copy */
-+ {
-+ *q++ = *r++; c--;
-+ *q++ = *r++; c--;
-+ do {
-+ *q++ = *r++;
-+ } while (--c);
-+ }
-+ break;
-+ }
-+ else if ((e & 64) == 0)
-+ {
-+ t += t->base;
-+ e = (t += ((uInt)b & inflate_mask[e]))->exop;
-+ }
-+ else
-+ {
-+ z->msg = (char*)"invalid distance code";
-+ UNGRAB
-+ UPDATE
-+ return Z_DATA_ERROR;
-+ }
-+ } while (1);
-+ break;
-+ }
-+ if ((e & 64) == 0)
-+ {
-+ t += t->base;
-+ if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
-+ {
-+ DUMPBITS(t->bits)
-+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-+ "inflate: * literal '%c'\n" :
-+ "inflate: * literal 0x%02x\n", t->base));
-+ *q++ = (Byte)t->base;
-+ m--;
-+ break;
-+ }
-+ }
-+ else if (e & 32)
-+ {
-+ Tracevv((stderr, "inflate: * end of block\n"));
-+ UNGRAB
-+ UPDATE
-+ return Z_STREAM_END;
-+ }
-+ else
-+ {
-+ z->msg = (char*)"invalid literal/length code";
-+ UNGRAB
-+ UPDATE
-+ return Z_DATA_ERROR;
-+ }
-+ } while (1);
-+ } while (m >= 258 && n >= 10);
-+
-+ /* not enough input or output--restore pointers and return */
-+ UNGRAB
-+ UPDATE
-+ return Z_OK;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/inffast.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,22 @@
-+/* inffast.h -- header to use inffast.c
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+#ifndef _INFFAST_H
-+#define _INFFAST_H
-+
-+extern int inflate_fast OF((
-+ uInt,
-+ uInt,
-+ inflate_huft *,
-+ inflate_huft *,
-+ inflate_blocks_statef *,
-+ z_streamp ));
-+
-+#endif /* _INFFAST_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/inffixed.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,151 @@
-+/* inffixed.h -- table for decoding fixed codes
-+ * Generated automatically by the maketree.c program
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+local uInt fixed_bl = 9;
-+local uInt fixed_bd = 5;
-+local inflate_huft fixed_tl[] = {
-+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
-+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
-+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
-+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
-+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
-+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
-+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
-+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
-+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
-+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
-+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
-+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
-+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
-+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
-+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
-+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
-+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
-+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
-+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
-+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
-+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
-+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
-+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
-+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
-+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
-+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
-+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
-+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
-+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
-+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
-+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
-+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
-+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
-+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
-+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
-+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
-+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
-+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
-+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
-+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
-+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
-+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
-+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
-+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
-+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
-+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
-+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
-+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
-+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
-+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
-+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
-+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
-+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
-+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
-+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
-+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
-+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
-+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
-+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
-+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
-+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
-+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
-+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
-+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
-+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
-+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
-+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
-+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
-+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
-+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
-+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
-+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
-+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
-+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
-+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
-+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
-+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
-+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
-+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
-+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
-+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
-+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
-+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
-+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
-+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
-+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
-+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
-+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
-+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
-+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
-+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
-+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
-+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
-+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
-+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
-+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
-+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
-+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
-+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
-+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
-+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
-+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
-+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
-+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
-+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
-+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
-+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
-+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
-+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
-+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
-+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
-+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
-+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
-+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
-+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
-+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
-+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
-+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
-+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
-+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
-+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
-+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
-+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
-+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
-+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
-+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
-+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
-+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
-+ };
-+local inflate_huft fixed_td[] = {
-+ {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
-+ {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
-+ {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
-+ {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
-+ {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
-+ {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
-+ {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
-+ {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
-+ };
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/inflate.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,368 @@
-+/* inflate.c -- zlib interface to inflate modules
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+#include <zlib/zutil.h>
-+#include "infblock.h"
-+
-+struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
-+
-+typedef enum {
-+ METHOD, /* waiting for method byte */
-+ FLAG, /* waiting for flag byte */
-+ DICT4, /* four dictionary check bytes to go */
-+ DICT3, /* three dictionary check bytes to go */
-+ DICT2, /* two dictionary check bytes to go */
-+ DICT1, /* one dictionary check byte to go */
-+ DICT0, /* waiting for inflateSetDictionary */
-+ BLOCKS, /* decompressing blocks */
-+ CHECK4, /* four check bytes to go */
-+ CHECK3, /* three check bytes to go */
-+ CHECK2, /* two check bytes to go */
-+ CHECK1, /* one check byte to go */
-+ DONE, /* finished check, done */
-+ BAD} /* got an error--stay here */
-+inflate_mode;
-+
-+/* inflate private state */
-+struct internal_state {
-+
-+ /* mode */
-+ inflate_mode mode; /* current inflate mode */
-+
-+ /* mode dependent information */
-+ union {
-+ uInt method; /* if FLAGS, method byte */
-+ struct {
-+ uLong was; /* computed check value */
-+ uLong need; /* stream check value */
-+ } check; /* if CHECK, check values to compare */
-+ uInt marker; /* if BAD, inflateSync's marker bytes count */
-+ } sub; /* submode */
-+
-+ /* mode independent information */
-+ int nowrap; /* flag for no wrapper */
-+ uInt wbits; /* log2(window size) (8..15, defaults to 15) */
-+ inflate_blocks_statef
-+ *blocks; /* current inflate_blocks state */
-+
-+};
-+
-+
-+int ZEXPORT inflateReset(z)
-+z_streamp z;
-+{
-+ if (z == Z_NULL || z->state == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ z->total_in = z->total_out = 0;
-+ z->msg = Z_NULL;
-+ z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
-+ inflate_blocks_reset(z->state->blocks, z, Z_NULL);
-+ Tracev((stderr, "inflate: reset\n"));
-+ return Z_OK;
-+}
-+
-+
-+int ZEXPORT inflateEnd(z)
-+z_streamp z;
-+{
-+ if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ if (z->state->blocks != Z_NULL)
-+ inflate_blocks_free(z->state->blocks, z);
-+ ZFREE(z, z->state);
-+ z->state = Z_NULL;
-+ Tracev((stderr, "inflate: end\n"));
-+ return Z_OK;
-+}
-+
-+
-+int ZEXPORT inflateInit2_(z, w, version, stream_size)
-+z_streamp z;
-+int w;
-+const char *version;
-+int stream_size;
-+{
-+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
-+ stream_size != sizeof(z_stream))
-+ return Z_VERSION_ERROR;
-+
-+ /* initialize state */
-+ if (z == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ z->msg = Z_NULL;
-+ if (z->zalloc == Z_NULL)
-+ {
-+ return Z_STREAM_ERROR;
-+/* z->zalloc = zcalloc;
-+ z->opaque = (voidpf)0;
-+*/
-+ }
-+ if (z->zfree == Z_NULL) return Z_STREAM_ERROR; /* z->zfree = zcfree; */
-+ if ((z->state = (struct internal_state FAR *)
-+ ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
-+ return Z_MEM_ERROR;
-+ z->state->blocks = Z_NULL;
-+
-+ /* handle undocumented nowrap option (no zlib header or check) */
-+ z->state->nowrap = 0;
-+ if (w < 0)
-+ {
-+ w = - w;
-+ z->state->nowrap = 1;
-+ }
-+
-+ /* set window size */
-+ if (w < 8 || w > 15)
-+ {
-+ inflateEnd(z);
-+ return Z_STREAM_ERROR;
-+ }
-+ z->state->wbits = (uInt)w;
-+
-+ /* create inflate_blocks state */
-+ if ((z->state->blocks =
-+ inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
-+ == Z_NULL)
-+ {
-+ inflateEnd(z);
-+ return Z_MEM_ERROR;
-+ }
-+ Tracev((stderr, "inflate: allocated\n"));
-+
-+ /* reset state */
-+ inflateReset(z);
-+ return Z_OK;
-+}
-+
-+
-+int ZEXPORT inflateInit_(z, version, stream_size)
-+z_streamp z;
-+const char *version;
-+int stream_size;
-+{
-+ return inflateInit2_(z, DEF_WBITS, version, stream_size);
-+}
-+
-+
-+#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
-+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
-+
-+int ZEXPORT inflate(z, f)
-+z_streamp z;
-+int f;
-+{
-+ int r;
-+ uInt b;
-+
-+ if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
-+ r = Z_BUF_ERROR;
-+ while (1) switch (z->state->mode)
-+ {
-+ case METHOD:
-+ NEEDBYTE
-+ if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = (char*)"unknown compression method";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = (char*)"invalid window size";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ z->state->mode = FLAG;
-+ case FLAG:
-+ NEEDBYTE
-+ b = NEXTBYTE;
-+ if (((z->state->sub.method << 8) + b) % 31)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = (char*)"incorrect header check";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ Tracev((stderr, "inflate: zlib header ok\n"));
-+ if (!(b & PRESET_DICT))
-+ {
-+ z->state->mode = BLOCKS;
-+ break;
-+ }
-+ z->state->mode = DICT4;
-+ case DICT4:
-+ NEEDBYTE
-+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
-+ z->state->mode = DICT3;
-+ case DICT3:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
-+ z->state->mode = DICT2;
-+ case DICT2:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
-+ z->state->mode = DICT1;
-+ case DICT1:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE;
-+ z->adler = z->state->sub.check.need;
-+ z->state->mode = DICT0;
-+ return Z_NEED_DICT;
-+ case DICT0:
-+ z->state->mode = BAD;
-+ z->msg = (char*)"need dictionary";
-+ z->state->sub.marker = 0; /* can try inflateSync */
-+ return Z_STREAM_ERROR;
-+ case BLOCKS:
-+ r = inflate_blocks(z->state->blocks, z, r);
-+ if (r == Z_DATA_ERROR)
-+ {
-+ z->state->mode = BAD;
-+ z->state->sub.marker = 0; /* can try inflateSync */
-+ break;
-+ }
-+ if (r == Z_OK)
-+ r = f;
-+ if (r != Z_STREAM_END)
-+ return r;
-+ r = f;
-+ inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
-+ if (z->state->nowrap)
-+ {
-+ z->state->mode = DONE;
-+ break;
-+ }
-+ z->state->mode = CHECK4;
-+ case CHECK4:
-+ NEEDBYTE
-+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
-+ z->state->mode = CHECK3;
-+ case CHECK3:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
-+ z->state->mode = CHECK2;
-+ case CHECK2:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
-+ z->state->mode = CHECK1;
-+ case CHECK1:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE;
-+
-+ if (z->state->sub.check.was != z->state->sub.check.need)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = (char*)"incorrect data check";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ Tracev((stderr, "inflate: zlib check ok\n"));
-+ z->state->mode = DONE;
-+ case DONE:
-+ return Z_STREAM_END;
-+ case BAD:
-+ return Z_DATA_ERROR;
-+ default:
-+ return Z_STREAM_ERROR;
-+ }
-+#ifdef NEED_DUMMY_RETURN
-+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
-+#endif
-+}
-+
-+
-+int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
-+z_streamp z;
-+const Bytef *dictionary;
-+uInt dictLength;
-+{
-+ uInt length = dictLength;
-+
-+ if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
-+ return Z_STREAM_ERROR;
-+
-+ if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
-+ z->adler = 1L;
-+
-+ if (length >= ((uInt)1<<z->state->wbits))
-+ {
-+ length = (1<<z->state->wbits)-1;
-+ dictionary += dictLength - length;
-+ }
-+ inflate_set_dictionary(z->state->blocks, dictionary, length);
-+ z->state->mode = BLOCKS;
-+ return Z_OK;
-+}
-+
-+
-+int ZEXPORT inflateSync(z)
-+z_streamp z;
-+{
-+ uInt n; /* number of bytes to look at */
-+ Bytef *p; /* pointer to bytes */
-+ uInt m; /* number of marker bytes found in a row */
-+ uLong r, w; /* temporaries to save total_in and total_out */
-+
-+ /* set up */
-+ if (z == Z_NULL || z->state == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ if (z->state->mode != BAD)
-+ {
-+ z->state->mode = BAD;
-+ z->state->sub.marker = 0;
-+ }
-+ if ((n = z->avail_in) == 0)
-+ return Z_BUF_ERROR;
-+ p = z->next_in;
-+ m = z->state->sub.marker;
-+
-+ /* search */
-+ while (n && m < 4)
-+ {
-+ static const Byte mark[4] = {0, 0, 0xff, 0xff};
-+ if (*p == mark[m])
-+ m++;
-+ else if (*p)
-+ m = 0;
-+ else
-+ m = 4 - m;
-+ p++, n--;
-+ }
-+
-+ /* restore */
-+ z->total_in += p - z->next_in;
-+ z->next_in = p;
-+ z->avail_in = n;
-+ z->state->sub.marker = m;
-+
-+ /* return no joy or set up to restart on a new block */
-+ if (m != 4)
-+ return Z_DATA_ERROR;
-+ r = z->total_in; w = z->total_out;
-+ inflateReset(z);
-+ z->total_in = r; z->total_out = w;
-+ z->state->mode = BLOCKS;
-+ return Z_OK;
-+}
-+
-+
-+/* Returns true if inflate is currently at the end of a block generated
-+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
-+ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
-+ * but removes the length bytes of the resulting empty stored block. When
-+ * decompressing, PPP checks that at the end of input packet, inflate is
-+ * waiting for these length bytes.
-+ */
-+int ZEXPORT inflateSyncPoint(z)
-+z_streamp z;
-+{
-+ if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ return inflate_blocks_sync_point(z->state->blocks);
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/inftrees.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,454 @@
-+/* inftrees.c -- generate Huffman trees for efficient decoding
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+#include <zlib/zutil.h>
-+#include "inftrees.h"
-+
-+#if !defined(BUILDFIXED) && !defined(STDC)
-+# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
-+#endif
-+
-+local const char inflate_copyright[] =
-+ " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
-+/*
-+ If you use the zlib library in a product, an acknowledgment is welcome
-+ in the documentation of your product. If for some reason you cannot
-+ include such an acknowledgment, I would appreciate that you keep this
-+ copyright string in the executable of your product.
-+ */
-+struct internal_state {int dummy;}; /* for buggy compilers */
-+
-+/* simplify the use of the inflate_huft type with some defines */
-+#define exop word.what.Exop
-+#define bits word.what.Bits
-+
-+
-+local int huft_build OF((
-+ uIntf *, /* code lengths in bits */
-+ uInt, /* number of codes */
-+ uInt, /* number of "simple" codes */
-+ const uIntf *, /* list of base values for non-simple codes */
-+ const uIntf *, /* list of extra bits for non-simple codes */
-+ inflate_huft * FAR*,/* result: starting table */
-+ uIntf *, /* maximum lookup bits (returns actual) */
-+ inflate_huft *, /* space for trees */
-+ uInt *, /* hufts used in space */
-+ uIntf * )); /* space for values */
-+
-+/* Tables for deflate from PKZIP's appnote.txt. */
-+local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
-+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
-+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
-+ /* see note #13 above about 258 */
-+local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
-+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
-+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
-+local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
-+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
-+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
-+ 8193, 12289, 16385, 24577};
-+local const uInt cpdext[30] = { /* Extra bits for distance codes */
-+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
-+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
-+ 12, 12, 13, 13};
-+
-+/*
-+ Huffman code decoding is performed using a multi-level table lookup.
-+ The fastest way to decode is to simply build a lookup table whose
-+ size is determined by the longest code. However, the time it takes
-+ to build this table can also be a factor if the data being decoded
-+ is not very long. The most common codes are necessarily the
-+ shortest codes, so those codes dominate the decoding time, and hence
-+ the speed. The idea is you can have a shorter table that decodes the
-+ shorter, more probable codes, and then point to subsidiary tables for
-+ the longer codes. The time it costs to decode the longer codes is
-+ then traded against the time it takes to make longer tables.
-+
-+ This results of this trade are in the variables lbits and dbits
-+ below. lbits is the number of bits the first level table for literal/
-+ length codes can decode in one step, and dbits is the same thing for
-+ the distance codes. Subsequent tables are also less than or equal to
-+ those sizes. These values may be adjusted either when all of the
-+ codes are shorter than that, in which case the longest code length in
-+ bits is used, or when the shortest code is *longer* than the requested
-+ table size, in which case the length of the shortest code in bits is
-+ used.
-+
-+ There are two different values for the two tables, since they code a
-+ different number of possibilities each. The literal/length table
-+ codes 286 possible values, or in a flat code, a little over eight
-+ bits. The distance table codes 30 possible values, or a little less
-+ than five bits, flat. The optimum values for speed end up being
-+ about one bit more than those, so lbits is 8+1 and dbits is 5+1.
-+ The optimum values may differ though from machine to machine, and
-+ possibly even between compilers. Your mileage may vary.
-+ */
-+
-+
-+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
-+#define BMAX 15 /* maximum bit length of any code */
-+
-+local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
-+uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
-+uInt n; /* number of codes (assumed <= 288) */
-+uInt s; /* number of simple-valued codes (0..s-1) */
-+const uIntf *d; /* list of base values for non-simple codes */
-+const uIntf *e; /* list of extra bits for non-simple codes */
-+inflate_huft * FAR *t; /* result: starting table */
-+uIntf *m; /* maximum lookup bits, returns actual */
-+inflate_huft *hp; /* space for trees */
-+uInt *hn; /* hufts used in space */
-+uIntf *v; /* working area: values in order of bit length */
-+/* Given a list of code lengths and a maximum table size, make a set of
-+ tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
-+ if the given code set is incomplete (the tables are still built in this
-+ case), or Z_DATA_ERROR if the input is invalid. */
-+{
-+
-+ uInt a; /* counter for codes of length k */
-+ uInt c[BMAX+1]; /* bit length count table */
-+ uInt f; /* i repeats in table every f entries */
-+ int g; /* maximum code length */
-+ int h; /* table level */
-+ register uInt i; /* counter, current code */
-+ register uInt j; /* counter */
-+ register int k; /* number of bits in current code */
-+ int l; /* bits per table (returned in m) */
-+ uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
-+ register uIntf *p; /* pointer into c[], b[], or v[] */
-+ inflate_huft *q; /* points to current table */
-+ struct inflate_huft_s r; /* table entry for structure assignment */
-+ inflate_huft *u[BMAX]; /* table stack */
-+ register int w; /* bits before this table == (l * h) */
-+ uInt x[BMAX+1]; /* bit offsets, then code stack */
-+ uIntf *xp; /* pointer into x */
-+ int y; /* number of dummy codes added */
-+ uInt z; /* number of entries in current table */
-+
-+
-+ /* Generate counts for each bit length */
-+ p = c;
-+#define C0 *p++ = 0;
-+#define C2 C0 C0 C0 C0
-+#define C4 C2 C2 C2 C2
-+ C4 /* clear c[]--assume BMAX+1 is 16 */
-+ p = b; i = n;
-+ do {
-+ c[*p++]++; /* assume all entries <= BMAX */
-+ } while (--i);
-+ if (c[0] == n) /* null input--all zero length codes */
-+ {
-+ *t = (inflate_huft *)Z_NULL;
-+ *m = 0;
-+ return Z_OK;
-+ }
-+
-+
-+ /* Find minimum and maximum length, bound *m by those */
-+ l = *m;
-+ for (j = 1; j <= BMAX; j++)
-+ if (c[j])
-+ break;
-+ k = j; /* minimum code length */
-+ if ((uInt)l < j)
-+ l = j;
-+ for (i = BMAX; i; i--)
-+ if (c[i])
-+ break;
-+ g = i; /* maximum code length */
-+ if ((uInt)l > i)
-+ l = i;
-+ *m = l;
-+
-+
-+ /* Adjust last length count to fill out codes, if needed */
-+ for (y = 1 << j; j < i; j++, y <<= 1)
-+ if ((y -= c[j]) < 0)
-+ return Z_DATA_ERROR;
-+ if ((y -= c[i]) < 0)
-+ return Z_DATA_ERROR;
-+ c[i] += y;
-+
-+
-+ /* Generate starting offsets into the value table for each length */
-+ x[1] = j = 0;
-+ p = c + 1; xp = x + 2;
-+ while (--i) { /* note that i == g from above */
-+ *xp++ = (j += *p++);
-+ }
-+
-+
-+ /* Make a table of values in order of bit lengths */
-+ p = b; i = 0;
-+ do {
-+ if ((j = *p++) != 0)
-+ v[x[j]++] = i;
-+ } while (++i < n);
-+ n = x[g]; /* set n to length of v */
-+
-+
-+ /* Generate the Huffman codes and for each, make the table entries */
-+ x[0] = i = 0; /* first Huffman code is zero */
-+ p = v; /* grab values in bit order */
-+ h = -1; /* no tables yet--level -1 */
-+ w = -l; /* bits decoded == (l * h) */
-+ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
-+ q = (inflate_huft *)Z_NULL; /* ditto */
-+ z = 0; /* ditto */
-+
-+ /* go through the bit lengths (k already is bits in shortest code) */
-+ for (; k <= g; k++)
-+ {
-+ a = c[k];
-+ while (a--)
-+ {
-+ /* here i is the Huffman code of length k bits for value *p */
-+ /* make tables up to required level */
-+ while (k > w + l)
-+ {
-+ h++;
-+ w += l; /* previous table always l bits */
-+
-+ /* compute minimum size table less than or equal to l bits */
-+ z = g - w;
-+ z = z > (uInt)l ? l : z; /* table size upper limit */
-+ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
-+ { /* too few codes for k-w bit table */
-+ f -= a + 1; /* deduct codes from patterns left */
-+ xp = c + k;
-+ if (j < z)
-+ while (++j < z) /* try smaller tables up to z bits */
-+ {
-+ if ((f <<= 1) <= *++xp)
-+ break; /* enough codes to use up j bits */
-+ f -= *xp; /* else deduct codes from patterns */
-+ }
-+ }
-+ z = 1 << j; /* table entries for j-bit table */
-+
-+ /* allocate new table */
-+ if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
-+ return Z_DATA_ERROR; /* overflow of MANY */
-+ u[h] = q = hp + *hn;
-+ *hn += z;
-+
-+ /* connect to last table, if there is one */
-+ if (h)
-+ {
-+ x[h] = i; /* save pattern for backing up */
-+ r.bits = (Byte)l; /* bits to dump before this table */
-+ r.exop = (Byte)j; /* bits in this table */
-+ j = i >> (w - l);
-+ r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
-+ u[h-1][j] = r; /* connect to last table */
-+ }
-+ else
-+ *t = q; /* first table is returned result */
-+ }
-+
-+ /* set up table entry in r */
-+ r.bits = (Byte)(k - w);
-+ if (p >= v + n)
-+ r.exop = 128 + 64; /* out of values--invalid code */
-+ else if (*p < s)
-+ {
-+ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
-+ r.base = *p++; /* simple code is just the value */
-+ }
-+ else
-+ {
-+ r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
-+ r.base = d[*p++ - s];
-+ }
-+
-+ /* fill code-like entries with r */
-+ f = 1 << (k - w);
-+ for (j = i >> w; j < z; j += f)
-+ q[j] = r;
-+
-+ /* backwards increment the k-bit code i */
-+ for (j = 1 << (k - 1); i & j; j >>= 1)
-+ i ^= j;
-+ i ^= j;
-+
-+ /* backup over finished tables */
-+ mask = (1 << w) - 1; /* needed on HP, cc -O bug */
-+ while ((i & mask) != x[h])
-+ {
-+ h--; /* don't need to update q */
-+ w -= l;
-+ mask = (1 << w) - 1;
-+ }
-+ }
-+ }
-+
-+
-+ /* Return Z_BUF_ERROR if we were given an incomplete table */
-+ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
-+}
-+
-+
-+int inflate_trees_bits(c, bb, tb, hp, z)
-+uIntf *c; /* 19 code lengths */
-+uIntf *bb; /* bits tree desired/actual depth */
-+inflate_huft * FAR *tb; /* bits tree result */
-+inflate_huft *hp; /* space for trees */
-+z_streamp z; /* for messages */
-+{
-+ int r;
-+ uInt hn = 0; /* hufts used in space */
-+ uIntf *v; /* work area for huft_build */
-+
-+ if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
-+ return Z_MEM_ERROR;
-+ r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
-+ tb, bb, hp, &hn, v);
-+ if (r == Z_DATA_ERROR)
-+ z->msg = (char*)"oversubscribed dynamic bit lengths tree";
-+ else if (r == Z_BUF_ERROR || *bb == 0)
-+ {
-+ z->msg = (char*)"incomplete dynamic bit lengths tree";
-+ r = Z_DATA_ERROR;
-+ }
-+ ZFREE(z, v);
-+ return r;
-+}
-+
-+
-+int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
-+uInt nl; /* number of literal/length codes */
-+uInt nd; /* number of distance codes */
-+uIntf *c; /* that many (total) code lengths */
-+uIntf *bl; /* literal desired/actual bit depth */
-+uIntf *bd; /* distance desired/actual bit depth */
-+inflate_huft * FAR *tl; /* literal/length tree result */
-+inflate_huft * FAR *td; /* distance tree result */
-+inflate_huft *hp; /* space for trees */
-+z_streamp z; /* for messages */
-+{
-+ int r;
-+ uInt hn = 0; /* hufts used in space */
-+ uIntf *v; /* work area for huft_build */
-+
-+ /* allocate work area */
-+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
-+ return Z_MEM_ERROR;
-+
-+ /* build literal/length tree */
-+ r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
-+ if (r != Z_OK || *bl == 0)
-+ {
-+ if (r == Z_DATA_ERROR)
-+ z->msg = (char*)"oversubscribed literal/length tree";
-+ else if (r != Z_MEM_ERROR)
-+ {
-+ z->msg = (char*)"incomplete literal/length tree";
-+ r = Z_DATA_ERROR;
-+ }
-+ ZFREE(z, v);
-+ return r;
-+ }
-+
-+ /* build distance tree */
-+ r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
-+ if (r != Z_OK || (*bd == 0 && nl > 257))
-+ {
-+ if (r == Z_DATA_ERROR)
-+ z->msg = (char*)"oversubscribed distance tree";
-+ else if (r == Z_BUF_ERROR) {
-+#ifdef PKZIP_BUG_WORKAROUND
-+ r = Z_OK;
-+ }
-+#else
-+ z->msg = (char*)"incomplete distance tree";
-+ r = Z_DATA_ERROR;
-+ }
-+ else if (r != Z_MEM_ERROR)
-+ {
-+ z->msg = (char*)"empty distance tree with lengths";
-+ r = Z_DATA_ERROR;
-+ }
-+ ZFREE(z, v);
-+ return r;
-+#endif
-+ }
-+
-+ /* done */
-+ ZFREE(z, v);
-+ return Z_OK;
-+}
-+
-+
-+/* build fixed tables only once--keep them here */
-+#ifdef BUILDFIXED
-+local int fixed_built = 0;
-+#define FIXEDH 544 /* number of hufts used by fixed tables */
-+local inflate_huft fixed_mem[FIXEDH];
-+local uInt fixed_bl;
-+local uInt fixed_bd;
-+local inflate_huft *fixed_tl;
-+local inflate_huft *fixed_td;
-+#else
-+#include "inffixed.h"
-+#endif
-+
-+
-+int inflate_trees_fixed(bl, bd, tl, td, z)
-+uIntf *bl; /* literal desired/actual bit depth */
-+uIntf *bd; /* distance desired/actual bit depth */
-+inflate_huft * FAR *tl; /* literal/length tree result */
-+inflate_huft * FAR *td; /* distance tree result */
-+z_streamp z; /* for memory allocation */
-+{
-+#ifdef BUILDFIXED
-+ /* build fixed tables if not already */
-+ if (!fixed_built)
-+ {
-+ int k; /* temporary variable */
-+ uInt f = 0; /* number of hufts used in fixed_mem */
-+ uIntf *c; /* length list for huft_build */
-+ uIntf *v; /* work area for huft_build */
-+
-+ /* allocate memory */
-+ if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
-+ return Z_MEM_ERROR;
-+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
-+ {
-+ ZFREE(z, c);
-+ return Z_MEM_ERROR;
-+ }
-+
-+ /* literal table */
-+ for (k = 0; k < 144; k++)
-+ c[k] = 8;
-+ for (; k < 256; k++)
-+ c[k] = 9;
-+ for (; k < 280; k++)
-+ c[k] = 7;
-+ for (; k < 288; k++)
-+ c[k] = 8;
-+ fixed_bl = 9;
-+ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
-+ fixed_mem, &f, v);
-+
-+ /* distance table */
-+ for (k = 0; k < 30; k++)
-+ c[k] = 5;
-+ fixed_bd = 5;
-+ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
-+ fixed_mem, &f, v);
-+
-+ /* done */
-+ ZFREE(z, v);
-+ ZFREE(z, c);
-+ fixed_built = 1;
-+ }
-+#endif
-+ *bl = fixed_bl;
-+ *bd = fixed_bd;
-+ *tl = fixed_tl;
-+ *td = fixed_td;
-+ return Z_OK;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/inftrees.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,63 @@
-+/* inftrees.h -- header to use inftrees.c
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+/* Huffman code lookup table entry--this entry is four bytes for machines
-+ that have 16-bit pointers (e.g. PC's in the small or medium model). */
-+
-+#ifndef _INFTREES_H
-+#define _INFTREES_H
-+
-+typedef struct inflate_huft_s FAR inflate_huft;
-+
-+struct inflate_huft_s {
-+ union {
-+ struct {
-+ Byte Exop; /* number of extra bits or operation */
-+ Byte Bits; /* number of bits in this code or subcode */
-+ } what;
-+ uInt pad; /* pad structure to a power of 2 (4 bytes for */
-+ } word; /* 16-bit, 8 bytes for 32-bit int's) */
-+ uInt base; /* literal, length base, distance base,
-+ or table offset */
-+};
-+
-+/* Maximum size of dynamic tree. The maximum found in a long but non-
-+ exhaustive search was 1004 huft structures (850 for length/literals
-+ and 154 for distances, the latter actually the result of an
-+ exhaustive search). The actual maximum is not known, but the
-+ value below is more than safe. */
-+#define MANY 1440
-+
-+extern int inflate_trees_bits OF((
-+ uIntf *, /* 19 code lengths */
-+ uIntf *, /* bits tree desired/actual depth */
-+ inflate_huft * FAR *, /* bits tree result */
-+ inflate_huft *, /* space for trees */
-+ z_streamp)); /* for messages */
-+
-+extern int inflate_trees_dynamic OF((
-+ uInt, /* number of literal/length codes */
-+ uInt, /* number of distance codes */
-+ uIntf *, /* that many (total) code lengths */
-+ uIntf *, /* literal desired/actual bit depth */
-+ uIntf *, /* distance desired/actual bit depth */
-+ inflate_huft * FAR *, /* literal/length tree result */
-+ inflate_huft * FAR *, /* distance tree result */
-+ inflate_huft *, /* space for trees */
-+ z_streamp)); /* for messages */
-+
-+extern int inflate_trees_fixed OF((
-+ uIntf *, /* literal desired/actual bit depth */
-+ uIntf *, /* distance desired/actual bit depth */
-+ inflate_huft * FAR *, /* literal/length tree result */
-+ inflate_huft * FAR *, /* distance tree result */
-+ z_streamp)); /* for memory allocation */
-+
-+#endif /* _INFTREES_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/infutil.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,87 @@
-+/* inflate_util.c -- data and routines common to blocks and codes
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+#include <zlib/zutil.h>
-+#include "infblock.h"
-+#include "inftrees.h"
-+#include "infcodes.h"
-+#include "infutil.h"
-+
-+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-+
-+/* And'ing with mask[n] masks the lower n bits */
-+uInt inflate_mask[17] = {
-+ 0x0000,
-+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
-+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
-+};
-+
-+
-+/* copy as much as possible from the sliding window to the output area */
-+int inflate_flush(s, z, r)
-+inflate_blocks_statef *s;
-+z_streamp z;
-+int r;
-+{
-+ uInt n;
-+ Bytef *p;
-+ Bytef *q;
-+
-+ /* local copies of source and destination pointers */
-+ p = z->next_out;
-+ q = s->read;
-+
-+ /* compute number of bytes to copy as far as end of window */
-+ n = (uInt)((q <= s->write ? s->write : s->end) - q);
-+ if (n > z->avail_out) n = z->avail_out;
-+ if (n && r == Z_BUF_ERROR) r = Z_OK;
-+
-+ /* update counters */
-+ z->avail_out -= n;
-+ z->total_out += n;
-+
-+ /* update check information */
-+ if (s->checkfn != Z_NULL)
-+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
-+
-+ /* copy as far as end of window */
-+ zmemcpy(p, q, n);
-+ p += n;
-+ q += n;
-+
-+ /* see if more to copy at beginning of window */
-+ if (q == s->end)
-+ {
-+ /* wrap pointers */
-+ q = s->window;
-+ if (s->write == s->end)
-+ s->write = s->window;
-+
-+ /* compute bytes to copy */
-+ n = (uInt)(s->write - q);
-+ if (n > z->avail_out) n = z->avail_out;
-+ if (n && r == Z_BUF_ERROR) r = Z_OK;
-+
-+ /* update counters */
-+ z->avail_out -= n;
-+ z->total_out += n;
-+
-+ /* update check information */
-+ if (s->checkfn != Z_NULL)
-+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
-+
-+ /* copy */
-+ zmemcpy(p, q, n);
-+ p += n;
-+ q += n;
-+ }
-+
-+ /* update pointers */
-+ z->next_out = p;
-+ s->read = q;
-+
-+ /* done */
-+ return r;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/infutil.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,98 @@
-+/* infutil.h -- types and macros common to blocks and codes
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+#ifndef _INFUTIL_H
-+#define _INFUTIL_H
-+
-+typedef enum {
-+ TYPE, /* get type bits (3, including end bit) */
-+ LENS, /* get lengths for stored */
-+ STORED, /* processing stored block */
-+ TABLE, /* get table lengths */
-+ BTREE, /* get bit lengths tree for a dynamic block */
-+ DTREE, /* get length, distance trees for a dynamic block */
-+ CODES, /* processing fixed or dynamic block */
-+ DRY, /* output remaining window bytes */
-+ DONE, /* finished last block, done */
-+ BAD} /* got a data error--stuck here */
-+inflate_block_mode;
-+
-+/* inflate blocks semi-private state */
-+struct inflate_blocks_state {
-+
-+ /* mode */
-+ inflate_block_mode mode; /* current inflate_block mode */
-+
-+ /* mode dependent information */
-+ union {
-+ uInt left; /* if STORED, bytes left to copy */
-+ struct {
-+ uInt table; /* table lengths (14 bits) */
-+ uInt index; /* index into blens (or border) */
-+ uIntf *blens; /* bit lengths of codes */
-+ uInt bb; /* bit length tree depth */
-+ inflate_huft *tb; /* bit length decoding tree */
-+ } trees; /* if DTREE, decoding info for trees */
-+ struct {
-+ inflate_codes_statef
-+ *codes;
-+ } decode; /* if CODES, current state */
-+ } sub; /* submode */
-+ uInt last; /* true if this block is the last block */
-+
-+ /* mode independent information */
-+ uInt bitk; /* bits in bit buffer */
-+ uLong bitb; /* bit buffer */
-+ inflate_huft *hufts; /* single malloc for tree space */
-+ Bytef *window; /* sliding window */
-+ Bytef *end; /* one byte after sliding window */
-+ Bytef *read; /* window read pointer */
-+ Bytef *write; /* window write pointer */
-+ check_func checkfn; /* check function */
-+ uLong check; /* check on output */
-+
-+};
-+
-+
-+/* defines for inflate input/output */
-+/* update pointers and return */
-+#define UPDBITS {s->bitb=b;s->bitk=k;}
-+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
-+#define UPDOUT {s->write=q;}
-+#define UPDATE {UPDBITS UPDIN UPDOUT}
-+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
-+/* get bytes and bits */
-+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
-+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
-+#define NEXTBYTE (n--,*p++)
-+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-+#define DUMPBITS(j) {b>>=(j);k-=(j);}
-+/* output bytes */
-+#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
-+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
-+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
-+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
-+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
-+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
-+/* load local pointers */
-+#define LOAD {LOADIN LOADOUT}
-+
-+/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
-+extern uInt inflate_mask[17];
-+
-+/* copy as much as possible from the sliding window to the output area */
-+extern int inflate_flush OF((
-+ inflate_blocks_statef *,
-+ z_streamp ,
-+ int));
-+
-+struct internal_state {int dummy;}; /* for buggy compilers */
-+
-+#endif /* _INFUTIL_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/match586.S Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,357 @@
-+/* match.s -- Pentium-optimized version of longest_match()
-+ * Written for zlib 1.1.2
-+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
-+ *
-+ * This is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License.
-+ */
-+
-+#ifndef NO_UNDERLINE
-+#define match_init _ipcomp_match_init
-+#define longest_match _ipcomp_longest_match
-+#else
-+#define match_init ipcomp_match_init
-+#define longest_match ipcomp_longest_match
-+#endif
-+
-+#define MAX_MATCH (258)
-+#define MIN_MATCH (3)
-+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
-+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
-+
-+/* stack frame offsets */
-+
-+#define wmask 0 /* local copy of s->wmask */
-+#define window 4 /* local copy of s->window */
-+#define windowbestlen 8 /* s->window + bestlen */
-+#define chainlenscanend 12 /* high word: current chain len */
-+ /* low word: last bytes sought */
-+#define scanstart 16 /* first two bytes of string */
-+#define scanalign 20 /* dword-misalignment of string */
-+#define nicematch 24 /* a good enough match size */
-+#define bestlen 28 /* size of best match so far */
-+#define scan 32 /* ptr to string wanting match */
-+
-+#define LocalVarsSize (36)
-+/* saved ebx 36 */
-+/* saved edi 40 */
-+/* saved esi 44 */
-+/* saved ebp 48 */
-+/* return address 52 */
-+#define deflatestate 56 /* the function arguments */
-+#define curmatch 60
-+
-+/* Offsets for fields in the deflate_state structure. These numbers
-+ * are calculated from the definition of deflate_state, with the
-+ * assumption that the compiler will dword-align the fields. (Thus,
-+ * changing the definition of deflate_state could easily cause this
-+ * program to crash horribly, without so much as a warning at
-+ * compile time. Sigh.)
-+ */
-+#define dsWSize 36
-+#define dsWMask 44
-+#define dsWindow 48
-+#define dsPrev 56
-+#define dsMatchLen 88
-+#define dsPrevMatch 92
-+#define dsStrStart 100
-+#define dsMatchStart 104
-+#define dsLookahead 108
-+#define dsPrevLen 112
-+#define dsMaxChainLen 116
-+#define dsGoodMatch 132
-+#define dsNiceMatch 136
-+
-+
-+.file "match.S"
-+
-+.globl match_init, longest_match
-+
-+.text
-+
-+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
-+
-+longest_match:
-+
-+/* Save registers that the compiler may be using, and adjust %esp to */
-+/* make room for our stack frame. */
-+
-+ pushl %ebp
-+ pushl %edi
-+ pushl %esi
-+ pushl %ebx
-+ subl $LocalVarsSize, %esp
-+
-+/* Retrieve the function arguments. %ecx will hold cur_match */
-+/* throughout the entire function. %edx will hold the pointer to the */
-+/* deflate_state structure during the function's setup (before */
-+/* entering the main loop). */
-+
-+ movl deflatestate(%esp), %edx
-+ movl curmatch(%esp), %ecx
-+
-+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
-+
-+ movl dsNiceMatch(%edx), %eax
-+ movl dsLookahead(%edx), %ebx
-+ cmpl %eax, %ebx
-+ jl LookaheadLess
-+ movl %eax, %ebx
-+LookaheadLess: movl %ebx, nicematch(%esp)
-+
-+/* register Bytef *scan = s->window + s->strstart; */
-+
-+ movl dsWindow(%edx), %esi
-+ movl %esi, window(%esp)
-+ movl dsStrStart(%edx), %ebp
-+ lea (%esi,%ebp), %edi
-+ movl %edi, scan(%esp)
-+
-+/* Determine how many bytes the scan ptr is off from being */
-+/* dword-aligned. */
-+
-+ movl %edi, %eax
-+ negl %eax
-+ andl $3, %eax
-+ movl %eax, scanalign(%esp)
-+
-+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
-+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
-+
-+ movl dsWSize(%edx), %eax
-+ subl $MIN_LOOKAHEAD, %eax
-+ subl %eax, %ebp
-+ jg LimitPositive
-+ xorl %ebp, %ebp
-+LimitPositive:
-+
-+/* unsigned chain_length = s->max_chain_length; */
-+/* if (s->prev_length >= s->good_match) { */
-+/* chain_length >>= 2; */
-+/* } */
-+
-+ movl dsPrevLen(%edx), %eax
-+ movl dsGoodMatch(%edx), %ebx
-+ cmpl %ebx, %eax
-+ movl dsMaxChainLen(%edx), %ebx
-+ jl LastMatchGood
-+ shrl $2, %ebx
-+LastMatchGood:
-+
-+/* chainlen is decremented once beforehand so that the function can */
-+/* use the sign flag instead of the zero flag for the exit test. */
-+/* It is then shifted into the high word, to make room for the scanend */
-+/* scanend value, which it will always accompany. */
-+
-+ decl %ebx
-+ shll $16, %ebx
-+
-+/* int best_len = s->prev_length; */
-+
-+ movl dsPrevLen(%edx), %eax
-+ movl %eax, bestlen(%esp)
-+
-+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
-+
-+ addl %eax, %esi
-+ movl %esi, windowbestlen(%esp)
-+
-+/* register ush scan_start = *(ushf*)scan; */
-+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
-+
-+ movw (%edi), %bx
-+ movw %bx, scanstart(%esp)
-+ movw -1(%edi,%eax), %bx
-+ movl %ebx, chainlenscanend(%esp)
-+
-+/* Posf *prev = s->prev; */
-+/* uInt wmask = s->w_mask; */
-+
-+ movl dsPrev(%edx), %edi
-+ movl dsWMask(%edx), %edx
-+ mov %edx, wmask(%esp)
-+
-+/* Jump into the main loop. */
-+
-+ jmp LoopEntry
-+
-+.balign 16
-+
-+/* do {
-+ * match = s->window + cur_match;
-+ * if (*(ushf*)(match+best_len-1) != scan_end ||
-+ * *(ushf*)match != scan_start) continue;
-+ * [...]
-+ * } while ((cur_match = prev[cur_match & wmask]) > limit
-+ * && --chain_length != 0);
-+ *
-+ * Here is the inner loop of the function. The function will spend the
-+ * majority of its time in this loop, and majority of that time will
-+ * be spent in the first ten instructions.
-+ *
-+ * Within this loop:
-+ * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)
-+ * %ecx = curmatch
-+ * %edx = curmatch & wmask
-+ * %esi = windowbestlen - i.e., (window + bestlen)
-+ * %edi = prev
-+ * %ebp = limit
-+ *
-+ * Two optimization notes on the choice of instructions:
-+ *
-+ * The first instruction uses a 16-bit address, which costs an extra,
-+ * unpairable cycle. This is cheaper than doing a 32-bit access and
-+ * zeroing the high word, due to the 3-cycle misalignment penalty which
-+ * would occur half the time. This also turns out to be cheaper than
-+ * doing two separate 8-bit accesses, as the memory is so rarely in the
-+ * L1 cache.
-+ *
-+ * The window buffer, however, apparently spends a lot of time in the
-+ * cache, and so it is faster to retrieve the word at the end of the
-+ * match string with two 8-bit loads. The instructions that test the
-+ * word at the beginning of the match string, however, are executed
-+ * much less frequently, and there it was cheaper to use 16-bit
-+ * instructions, which avoided the necessity of saving off and
-+ * subsequently reloading one of the other registers.
-+ */
-+LookupLoop:
-+ /* 1 U & V */
-+ movw (%edi,%edx,2), %cx /* 2 U pipe */
-+ movl wmask(%esp), %edx /* 2 V pipe */
-+ cmpl %ebp, %ecx /* 3 U pipe */
-+ jbe LeaveNow /* 3 V pipe */
-+ subl $0x00010000, %ebx /* 4 U pipe */
-+ js LeaveNow /* 4 V pipe */
-+LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */
-+ andl %ecx, %edx /* 5 V pipe */
-+ cmpb %bl, %al /* 6 U pipe */
-+ jnz LookupLoop /* 6 V pipe */
-+ movb (%esi,%ecx), %ah
-+ cmpb %bh, %ah
-+ jnz LookupLoop
-+ movl window(%esp), %eax
-+ movw (%eax,%ecx), %ax
-+ cmpw scanstart(%esp), %ax
-+ jnz LookupLoop
-+
-+/* Store the current value of chainlen. */
-+
-+ movl %ebx, chainlenscanend(%esp)
-+
-+/* Point %edi to the string under scrutiny, and %esi to the string we */
-+/* are hoping to match it up with. In actuality, %esi and %edi are */
-+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
-+/* initialized to -(MAX_MATCH_8 - scanalign). */
-+
-+ movl window(%esp), %esi
-+ movl scan(%esp), %edi
-+ addl %ecx, %esi
-+ movl scanalign(%esp), %eax
-+ movl $(-MAX_MATCH_8), %edx
-+ lea MAX_MATCH_8(%edi,%eax), %edi
-+ lea MAX_MATCH_8(%esi,%eax), %esi
-+
-+/* Test the strings for equality, 8 bytes at a time. At the end,
-+ * adjust %edx so that it is offset to the exact byte that mismatched.
-+ *
-+ * We already know at this point that the first three bytes of the
-+ * strings match each other, and they can be safely passed over before
-+ * starting the compare loop. So what this code does is skip over 0-3
-+ * bytes, as much as necessary in order to dword-align the %edi
-+ * pointer. (%esi will still be misaligned three times out of four.)
-+ *
-+ * It should be confessed that this loop usually does not represent
-+ * much of the total running time. Replacing it with a more
-+ * straightforward "rep cmpsb" would not drastically degrade
-+ * performance.
-+ */
-+LoopCmps:
-+ movl (%esi,%edx), %eax
-+ movl (%edi,%edx), %ebx
-+ xorl %ebx, %eax
-+ jnz LeaveLoopCmps
-+ movl 4(%esi,%edx), %eax
-+ movl 4(%edi,%edx), %ebx
-+ xorl %ebx, %eax
-+ jnz LeaveLoopCmps4
-+ addl $8, %edx
-+ jnz LoopCmps
-+ jmp LenMaximum
-+LeaveLoopCmps4: addl $4, %edx
-+LeaveLoopCmps: testl $0x0000FFFF, %eax
-+ jnz LenLower
-+ addl $2, %edx
-+ shrl $16, %eax
-+LenLower: subb $1, %al
-+ adcl $0, %edx
-+
-+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
-+/* then automatically accept it as the best possible match and leave. */
-+
-+ lea (%edi,%edx), %eax
-+ movl scan(%esp), %edi
-+ subl %edi, %eax
-+ cmpl $MAX_MATCH, %eax
-+ jge LenMaximum
-+
-+/* If the length of the match is not longer than the best match we */
-+/* have so far, then forget it and return to the lookup loop. */
-+
-+ movl deflatestate(%esp), %edx
-+ movl bestlen(%esp), %ebx
-+ cmpl %ebx, %eax
-+ jg LongerMatch
-+ movl chainlenscanend(%esp), %ebx
-+ movl windowbestlen(%esp), %esi
-+ movl dsPrev(%edx), %edi
-+ movl wmask(%esp), %edx
-+ andl %ecx, %edx
-+ jmp LookupLoop
-+
-+/* s->match_start = cur_match; */
-+/* best_len = len; */
-+/* if (len >= nice_match) break; */
-+/* scan_end = *(ushf*)(scan+best_len-1); */
-+
-+LongerMatch: movl nicematch(%esp), %ebx
-+ movl %eax, bestlen(%esp)
-+ movl %ecx, dsMatchStart(%edx)
-+ cmpl %ebx, %eax
-+ jge LeaveNow
-+ movl window(%esp), %esi
-+ addl %eax, %esi
-+ movl %esi, windowbestlen(%esp)
-+ movl chainlenscanend(%esp), %ebx
-+ movw -1(%edi,%eax), %bx
-+ movl dsPrev(%edx), %edi
-+ movl %ebx, chainlenscanend(%esp)
-+ movl wmask(%esp), %edx
-+ andl %ecx, %edx
-+ jmp LookupLoop
-+
-+/* Accept the current string, with the maximum possible length. */
-+
-+LenMaximum: movl deflatestate(%esp), %edx
-+ movl $MAX_MATCH, bestlen(%esp)
-+ movl %ecx, dsMatchStart(%edx)
-+
-+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
-+/* return s->lookahead; */
-+
-+LeaveNow:
-+ movl deflatestate(%esp), %edx
-+ movl bestlen(%esp), %ebx
-+ movl dsLookahead(%edx), %eax
-+ cmpl %eax, %ebx
-+ jg LookaheadRet
-+ movl %ebx, %eax
-+LookaheadRet:
-+
-+/* Restore the stack and return from whence we came. */
-+
-+ addl $LocalVarsSize, %esp
-+ popl %ebx
-+ popl %esi
-+ popl %edi
-+ popl %ebp
-+match_init: ret
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/match686.S Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,330 @@
-+/* match.s -- Pentium-Pro-optimized version of longest_match()
-+ * Written for zlib 1.1.2
-+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
-+ *
-+ * This is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License.
-+ */
-+
-+#ifndef NO_UNDERLINE
-+#define match_init _ipcomp_match_init
-+#define longest_match _ipcomp_longest_match
-+#else
-+#define match_init ipcomp_match_init
-+#define longest_match ipcomp_longest_match
-+#endif
-+
-+#define MAX_MATCH (258)
-+#define MIN_MATCH (3)
-+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
-+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
-+
-+/* stack frame offsets */
-+
-+#define chainlenwmask 0 /* high word: current chain len */
-+ /* low word: s->wmask */
-+#define window 4 /* local copy of s->window */
-+#define windowbestlen 8 /* s->window + bestlen */
-+#define scanstart 16 /* first two bytes of string */
-+#define scanend 12 /* last two bytes of string */
-+#define scanalign 20 /* dword-misalignment of string */
-+#define nicematch 24 /* a good enough match size */
-+#define bestlen 28 /* size of best match so far */
-+#define scan 32 /* ptr to string wanting match */
-+
-+#define LocalVarsSize (36)
-+/* saved ebx 36 */
-+/* saved edi 40 */
-+/* saved esi 44 */
-+/* saved ebp 48 */
-+/* return address 52 */
-+#define deflatestate 56 /* the function arguments */
-+#define curmatch 60
-+
-+/* Offsets for fields in the deflate_state structure. These numbers
-+ * are calculated from the definition of deflate_state, with the
-+ * assumption that the compiler will dword-align the fields. (Thus,
-+ * changing the definition of deflate_state could easily cause this
-+ * program to crash horribly, without so much as a warning at
-+ * compile time. Sigh.)
-+ */
-+#define dsWSize 36
-+#define dsWMask 44
-+#define dsWindow 48
-+#define dsPrev 56
-+#define dsMatchLen 88
-+#define dsPrevMatch 92
-+#define dsStrStart 100
-+#define dsMatchStart 104
-+#define dsLookahead 108
-+#define dsPrevLen 112
-+#define dsMaxChainLen 116
-+#define dsGoodMatch 132
-+#define dsNiceMatch 136
-+
-+
-+.file "match.S"
-+
-+.globl match_init, longest_match
-+
-+.text
-+
-+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
-+
-+longest_match:
-+
-+/* Save registers that the compiler may be using, and adjust %esp to */
-+/* make room for our stack frame. */
-+
-+ pushl %ebp
-+ pushl %edi
-+ pushl %esi
-+ pushl %ebx
-+ subl $LocalVarsSize, %esp
-+
-+/* Retrieve the function arguments. %ecx will hold cur_match */
-+/* throughout the entire function. %edx will hold the pointer to the */
-+/* deflate_state structure during the function's setup (before */
-+/* entering the main loop). */
-+
-+ movl deflatestate(%esp), %edx
-+ movl curmatch(%esp), %ecx
-+
-+/* uInt wmask = s->w_mask; */
-+/* unsigned chain_length = s->max_chain_length; */
-+/* if (s->prev_length >= s->good_match) { */
-+/* chain_length >>= 2; */
-+/* } */
-+
-+ movl dsPrevLen(%edx), %eax
-+ movl dsGoodMatch(%edx), %ebx
-+ cmpl %ebx, %eax
-+ movl dsWMask(%edx), %eax
-+ movl dsMaxChainLen(%edx), %ebx
-+ jl LastMatchGood
-+ shrl $2, %ebx
-+LastMatchGood:
-+
-+/* chainlen is decremented once beforehand so that the function can */
-+/* use the sign flag instead of the zero flag for the exit test. */
-+/* It is then shifted into the high word, to make room for the wmask */
-+/* value, which it will always accompany. */
-+
-+ decl %ebx
-+ shll $16, %ebx
-+ orl %eax, %ebx
-+ movl %ebx, chainlenwmask(%esp)
-+
-+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
-+
-+ movl dsNiceMatch(%edx), %eax
-+ movl dsLookahead(%edx), %ebx
-+ cmpl %eax, %ebx
-+ jl LookaheadLess
-+ movl %eax, %ebx
-+LookaheadLess: movl %ebx, nicematch(%esp)
-+
-+/* register Bytef *scan = s->window + s->strstart; */
-+
-+ movl dsWindow(%edx), %esi
-+ movl %esi, window(%esp)
-+ movl dsStrStart(%edx), %ebp
-+ lea (%esi,%ebp), %edi
-+ movl %edi, scan(%esp)
-+
-+/* Determine how many bytes the scan ptr is off from being */
-+/* dword-aligned. */
-+
-+ movl %edi, %eax
-+ negl %eax
-+ andl $3, %eax
-+ movl %eax, scanalign(%esp)
-+
-+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
-+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
-+
-+ movl dsWSize(%edx), %eax
-+ subl $MIN_LOOKAHEAD, %eax
-+ subl %eax, %ebp
-+ jg LimitPositive
-+ xorl %ebp, %ebp
-+LimitPositive:
-+
-+/* int best_len = s->prev_length; */
-+
-+ movl dsPrevLen(%edx), %eax
-+ movl %eax, bestlen(%esp)
-+
-+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
-+
-+ addl %eax, %esi
-+ movl %esi, windowbestlen(%esp)
-+
-+/* register ush scan_start = *(ushf*)scan; */
-+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
-+/* Posf *prev = s->prev; */
-+
-+ movzwl (%edi), %ebx
-+ movl %ebx, scanstart(%esp)
-+ movzwl -1(%edi,%eax), %ebx
-+ movl %ebx, scanend(%esp)
-+ movl dsPrev(%edx), %edi
-+
-+/* Jump into the main loop. */
-+
-+ movl chainlenwmask(%esp), %edx
-+ jmp LoopEntry
-+
-+.balign 16
-+
-+/* do {
-+ * match = s->window + cur_match;
-+ * if (*(ushf*)(match+best_len-1) != scan_end ||
-+ * *(ushf*)match != scan_start) continue;
-+ * [...]
-+ * } while ((cur_match = prev[cur_match & wmask]) > limit
-+ * && --chain_length != 0);
-+ *
-+ * Here is the inner loop of the function. The function will spend the
-+ * majority of its time in this loop, and majority of that time will
-+ * be spent in the first ten instructions.
-+ *
-+ * Within this loop:
-+ * %ebx = scanend
-+ * %ecx = curmatch
-+ * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
-+ * %esi = windowbestlen - i.e., (window + bestlen)
-+ * %edi = prev
-+ * %ebp = limit
-+ */
-+LookupLoop:
-+ andl %edx, %ecx
-+ movzwl (%edi,%ecx,2), %ecx
-+ cmpl %ebp, %ecx
-+ jbe LeaveNow
-+ subl $0x00010000, %edx
-+ js LeaveNow
-+LoopEntry: movzwl -1(%esi,%ecx), %eax
-+ cmpl %ebx, %eax
-+ jnz LookupLoop
-+ movl window(%esp), %eax
-+ movzwl (%eax,%ecx), %eax
-+ cmpl scanstart(%esp), %eax
-+ jnz LookupLoop
-+
-+/* Store the current value of chainlen. */
-+
-+ movl %edx, chainlenwmask(%esp)
-+
-+/* Point %edi to the string under scrutiny, and %esi to the string we */
-+/* are hoping to match it up with. In actuality, %esi and %edi are */
-+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
-+/* initialized to -(MAX_MATCH_8 - scanalign). */
-+
-+ movl window(%esp), %esi
-+ movl scan(%esp), %edi
-+ addl %ecx, %esi
-+ movl scanalign(%esp), %eax
-+ movl $(-MAX_MATCH_8), %edx
-+ lea MAX_MATCH_8(%edi,%eax), %edi
-+ lea MAX_MATCH_8(%esi,%eax), %esi
-+
-+/* Test the strings for equality, 8 bytes at a time. At the end,
-+ * adjust %edx so that it is offset to the exact byte that mismatched.
-+ *
-+ * We already know at this point that the first three bytes of the
-+ * strings match each other, and they can be safely passed over before
-+ * starting the compare loop. So what this code does is skip over 0-3
-+ * bytes, as much as necessary in order to dword-align the %edi
-+ * pointer. (%esi will still be misaligned three times out of four.)
-+ *
-+ * It should be confessed that this loop usually does not represent
-+ * much of the total running time. Replacing it with a more
-+ * straightforward "rep cmpsb" would not drastically degrade
-+ * performance.
-+ */
-+LoopCmps:
-+ movl (%esi,%edx), %eax
-+ xorl (%edi,%edx), %eax
-+ jnz LeaveLoopCmps
-+ movl 4(%esi,%edx), %eax
-+ xorl 4(%edi,%edx), %eax
-+ jnz LeaveLoopCmps4
-+ addl $8, %edx
-+ jnz LoopCmps
-+ jmp LenMaximum
-+LeaveLoopCmps4: addl $4, %edx
-+LeaveLoopCmps: testl $0x0000FFFF, %eax
-+ jnz LenLower
-+ addl $2, %edx
-+ shrl $16, %eax
-+LenLower: subb $1, %al
-+ adcl $0, %edx
-+
-+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
-+/* then automatically accept it as the best possible match and leave. */
-+
-+ lea (%edi,%edx), %eax
-+ movl scan(%esp), %edi
-+ subl %edi, %eax
-+ cmpl $MAX_MATCH, %eax
-+ jge LenMaximum
-+
-+/* If the length of the match is not longer than the best match we */
-+/* have so far, then forget it and return to the lookup loop. */
-+
-+ movl deflatestate(%esp), %edx
-+ movl bestlen(%esp), %ebx
-+ cmpl %ebx, %eax
-+ jg LongerMatch
-+ movl windowbestlen(%esp), %esi
-+ movl dsPrev(%edx), %edi
-+ movl scanend(%esp), %ebx
-+ movl chainlenwmask(%esp), %edx
-+ jmp LookupLoop
-+
-+/* s->match_start = cur_match; */
-+/* best_len = len; */
-+/* if (len >= nice_match) break; */
-+/* scan_end = *(ushf*)(scan+best_len-1); */
-+
-+LongerMatch: movl nicematch(%esp), %ebx
-+ movl %eax, bestlen(%esp)
-+ movl %ecx, dsMatchStart(%edx)
-+ cmpl %ebx, %eax
-+ jge LeaveNow
-+ movl window(%esp), %esi
-+ addl %eax, %esi
-+ movl %esi, windowbestlen(%esp)
-+ movzwl -1(%edi,%eax), %ebx
-+ movl dsPrev(%edx), %edi
-+ movl %ebx, scanend(%esp)
-+ movl chainlenwmask(%esp), %edx
-+ jmp LookupLoop
-+
-+/* Accept the current string, with the maximum possible length. */
-+
-+LenMaximum: movl deflatestate(%esp), %edx
-+ movl $MAX_MATCH, bestlen(%esp)
-+ movl %ecx, dsMatchStart(%edx)
-+
-+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
-+/* return s->lookahead; */
-+
-+LeaveNow:
-+ movl deflatestate(%esp), %edx
-+ movl bestlen(%esp), %ebx
-+ movl dsLookahead(%edx), %eax
-+ cmpl %eax, %ebx
-+ jg LookaheadRet
-+ movl %ebx, %eax
-+LookaheadRet:
-+
-+/* Restore the stack and return from whence we came. */
-+
-+ addl $LocalVarsSize, %esp
-+ popl %ebx
-+ popl %esi
-+ popl %edi
-+ popl %ebp
-+match_init: ret
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/trees.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1214 @@
-+/* trees.c -- output deflated data using Huffman coding
-+ * Copyright (C) 1995-2002 Jean-loup Gailly
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/*
-+ * ALGORITHM
-+ *
-+ * The "deflation" process uses several Huffman trees. The more
-+ * common source values are represented by shorter bit sequences.
-+ *
-+ * Each code tree is stored in a compressed form which is itself
-+ * a Huffman encoding of the lengths of all the code strings (in
-+ * ascending order by source values). The actual code strings are
-+ * reconstructed from the lengths in the inflate process, as described
-+ * in the deflate specification.
-+ *
-+ * REFERENCES
-+ *
-+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
-+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
-+ *
-+ * Storer, James A.
-+ * Data Compression: Methods and Theory, pp. 49-50.
-+ * Computer Science Press, 1988. ISBN 0-7167-8156-5.
-+ *
-+ * Sedgewick, R.
-+ * Algorithms, p290.
-+ * Addison-Wesley, 1983. ISBN 0-201-06672-6.
-+ */
-+
-+/* @(#) $Id$ */
-+
-+/* #define GEN_TREES_H */
-+
-+#include "deflate.h"
-+
-+#ifdef DEBUG
-+# include <ctype.h>
-+#endif
-+
-+/* ===========================================================================
-+ * Constants
-+ */
-+
-+#define MAX_BL_BITS 7
-+/* Bit length codes must not exceed MAX_BL_BITS bits */
-+
-+#define END_BLOCK 256
-+/* end of block literal code */
-+
-+#define REP_3_6 16
-+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
-+
-+#define REPZ_3_10 17
-+/* repeat a zero length 3-10 times (3 bits of repeat count) */
-+
-+#define REPZ_11_138 18
-+/* repeat a zero length 11-138 times (7 bits of repeat count) */
-+
-+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
-+ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
-+
-+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
-+ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
-+
-+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
-+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
-+
-+local const uch bl_order[BL_CODES]
-+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
-+/* The lengths of the bit length codes are sent in order of decreasing
-+ * probability, to avoid transmitting the lengths for unused bit length codes.
-+ */
-+
-+#define Buf_size (8 * 2*sizeof(char))
-+/* Number of bits used within bi_buf. (bi_buf might be implemented on
-+ * more than 16 bits on some systems.)
-+ */
-+
-+/* ===========================================================================
-+ * Local data. These are initialized only once.
-+ */
-+
-+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
-+
-+#if defined(GEN_TREES_H) || !defined(STDC)
-+/* non ANSI compilers may not accept trees.h */
-+
-+local ct_data static_ltree[L_CODES+2];
-+/* The static literal tree. Since the bit lengths are imposed, there is no
-+ * need for the L_CODES extra codes used during heap construction. However
-+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
-+ * below).
-+ */
-+
-+local ct_data static_dtree[D_CODES];
-+/* The static distance tree. (Actually a trivial tree since all codes use
-+ * 5 bits.)
-+ */
-+
-+uch _dist_code[DIST_CODE_LEN];
-+/* Distance codes. The first 256 values correspond to the distances
-+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
-+ * the 15 bit distances.
-+ */
-+
-+uch _length_code[MAX_MATCH-MIN_MATCH+1];
-+/* length code for each normalized match length (0 == MIN_MATCH) */
-+
-+local int base_length[LENGTH_CODES];
-+/* First normalized length for each code (0 = MIN_MATCH) */
-+
-+local int base_dist[D_CODES];
-+/* First normalized distance for each code (0 = distance of 1) */
-+
-+#else
-+# include "trees.h"
-+#endif /* GEN_TREES_H */
-+
-+struct static_tree_desc_s {
-+ const ct_data *static_tree; /* static tree or NULL */
-+ const intf *extra_bits; /* extra bits for each code or NULL */
-+ int extra_base; /* base index for extra_bits */
-+ int elems; /* max number of elements in the tree */
-+ int max_length; /* max bit length for the codes */
-+};
-+
-+local static_tree_desc static_l_desc =
-+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
-+
-+local static_tree_desc static_d_desc =
-+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
-+
-+local static_tree_desc static_bl_desc =
-+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
-+
-+/* ===========================================================================
-+ * Local (static) routines in this file.
-+ */
-+
-+local void tr_static_init OF((void));
-+local void init_block OF((deflate_state *s));
-+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
-+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
-+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
-+local void build_tree OF((deflate_state *s, tree_desc *desc));
-+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
-+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
-+local int build_bl_tree OF((deflate_state *s));
-+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
-+ int blcodes));
-+local void compress_block OF((deflate_state *s, const ct_data *ltree,
-+ const ct_data *dtree));
-+local void set_data_type OF((deflate_state *s));
-+local unsigned bi_reverse OF((unsigned value, int length));
-+local void bi_windup OF((deflate_state *s));
-+local void bi_flush OF((deflate_state *s));
-+local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
-+ int header));
-+
-+#ifdef GEN_TREES_H
-+local void gen_trees_header OF((void));
-+#endif
-+
-+#ifndef DEBUG
-+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
-+ /* Send a code of the given tree. c and tree must not have side effects */
-+
-+#else /* DEBUG */
-+# define send_code(s, c, tree) \
-+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
-+ send_bits(s, tree[c].Code, tree[c].Len); }
-+#endif
-+
-+/* ===========================================================================
-+ * Output a short LSB first on the stream.
-+ * IN assertion: there is enough room in pendingBuf.
-+ */
-+#define put_short(s, w) { \
-+ put_byte(s, (uch)((w) & 0xff)); \
-+ put_byte(s, (uch)((ush)(w) >> 8)); \
-+}
-+
-+/* ===========================================================================
-+ * Send a value on a given number of bits.
-+ * IN assertion: length <= 16 and value fits in length bits.
-+ */
-+#ifdef DEBUG
-+local void send_bits OF((deflate_state *s, int value, int length));
-+
-+local void send_bits(s, value, length)
-+ deflate_state *s;
-+ int value; /* value to send */
-+ int length; /* number of bits */
-+{
-+ Tracevv((stderr," l %2d v %4x ", length, value));
-+ Assert(length > 0 && length <= 15, "invalid length");
-+ s->bits_sent += (ulg)length;
-+
-+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and
-+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
-+ * unused bits in value.
-+ */
-+ if (s->bi_valid > (int)Buf_size - length) {
-+ s->bi_buf |= (value << s->bi_valid);
-+ put_short(s, s->bi_buf);
-+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
-+ s->bi_valid += length - Buf_size;
-+ } else {
-+ s->bi_buf |= value << s->bi_valid;
-+ s->bi_valid += length;
-+ }
-+}
-+#else /* !DEBUG */
-+
-+#define send_bits(s, value, length) \
-+{ int len = length;\
-+ if (s->bi_valid > (int)Buf_size - len) {\
-+ int val = value;\
-+ s->bi_buf |= (val << s->bi_valid);\
-+ put_short(s, s->bi_buf);\
-+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
-+ s->bi_valid += len - Buf_size;\
-+ } else {\
-+ s->bi_buf |= (value) << s->bi_valid;\
-+ s->bi_valid += len;\
-+ }\
-+}
-+#endif /* DEBUG */
-+
-+
-+#define MAX(a,b) (a >= b ? a : b)
-+/* the arguments must not have side effects */
-+
-+/* ===========================================================================
-+ * Initialize the various 'constant' tables.
-+ */
-+local void tr_static_init()
-+{
-+#if defined(GEN_TREES_H) || !defined(STDC)
-+ static int static_init_done = 0;
-+ int n; /* iterates over tree elements */
-+ int bits; /* bit counter */
-+ int length; /* length value */
-+ int code; /* code value */
-+ int dist; /* distance index */
-+ ush bl_count[MAX_BITS+1];
-+ /* number of codes at each bit length for an optimal tree */
-+
-+ if (static_init_done) return;
-+
-+ /* For some embedded targets, global variables are not initialized: */
-+ static_l_desc.static_tree = static_ltree;
-+ static_l_desc.extra_bits = extra_lbits;
-+ static_d_desc.static_tree = static_dtree;
-+ static_d_desc.extra_bits = extra_dbits;
-+ static_bl_desc.extra_bits = extra_blbits;
-+
-+ /* Initialize the mapping length (0..255) -> length code (0..28) */
-+ length = 0;
-+ for (code = 0; code < LENGTH_CODES-1; code++) {
-+ base_length[code] = length;
-+ for (n = 0; n < (1<<extra_lbits[code]); n++) {
-+ _length_code[length++] = (uch)code;
-+ }
-+ }
-+ Assert (length == 256, "tr_static_init: length != 256");
-+ /* Note that the length 255 (match length 258) can be represented
-+ * in two different ways: code 284 + 5 bits or code 285, so we
-+ * overwrite length_code[255] to use the best encoding:
-+ */
-+ _length_code[length-1] = (uch)code;
-+
-+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
-+ dist = 0;
-+ for (code = 0 ; code < 16; code++) {
-+ base_dist[code] = dist;
-+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
-+ _dist_code[dist++] = (uch)code;
-+ }
-+ }
-+ Assert (dist == 256, "tr_static_init: dist != 256");
-+ dist >>= 7; /* from now on, all distances are divided by 128 */
-+ for ( ; code < D_CODES; code++) {
-+ base_dist[code] = dist << 7;
-+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
-+ _dist_code[256 + dist++] = (uch)code;
-+ }
-+ }
-+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
-+
-+ /* Construct the codes of the static literal tree */
-+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
-+ n = 0;
-+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
-+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
-+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
-+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
-+ /* Codes 286 and 287 do not exist, but we must include them in the
-+ * tree construction to get a canonical Huffman tree (longest code
-+ * all ones)
-+ */
-+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
-+
-+ /* The static distance tree is trivial: */
-+ for (n = 0; n < D_CODES; n++) {
-+ static_dtree[n].Len = 5;
-+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
-+ }
-+ static_init_done = 1;
-+
-+# ifdef GEN_TREES_H
-+ gen_trees_header();
-+# endif
-+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
-+}
-+
-+/* ===========================================================================
-+ * Genererate the file trees.h describing the static trees.
-+ */
-+#ifdef GEN_TREES_H
-+# ifndef DEBUG
-+# include <stdio.h>
-+# endif
-+
-+# define SEPARATOR(i, last, width) \
-+ ((i) == (last)? "\n};\n\n" : \
-+ ((i) % (width) == (width)-1 ? ",\n" : ", "))
-+
-+void gen_trees_header()
-+{
-+ FILE *header = fopen("trees.h", "w");
-+ int i;
-+
-+ Assert (header != NULL, "Can't open trees.h");
-+ fprintf(header,
-+ "/* header created automatically with -DGEN_TREES_H */\n\n");
-+
-+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
-+ for (i = 0; i < L_CODES+2; i++) {
-+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
-+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
-+ }
-+
-+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
-+ for (i = 0; i < D_CODES; i++) {
-+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
-+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
-+ }
-+
-+ fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
-+ for (i = 0; i < DIST_CODE_LEN; i++) {
-+ fprintf(header, "%2u%s", _dist_code[i],
-+ SEPARATOR(i, DIST_CODE_LEN-1, 20));
-+ }
-+
-+ fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
-+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
-+ fprintf(header, "%2u%s", _length_code[i],
-+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
-+ }
-+
-+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
-+ for (i = 0; i < LENGTH_CODES; i++) {
-+ fprintf(header, "%1u%s", base_length[i],
-+ SEPARATOR(i, LENGTH_CODES-1, 20));
-+ }
-+
-+ fprintf(header, "local const int base_dist[D_CODES] = {\n");
-+ for (i = 0; i < D_CODES; i++) {
-+ fprintf(header, "%5u%s", base_dist[i],
-+ SEPARATOR(i, D_CODES-1, 10));
-+ }
-+
-+ fclose(header);
-+}
-+#endif /* GEN_TREES_H */
-+
-+/* ===========================================================================
-+ * Initialize the tree data structures for a new zlib stream.
-+ */
-+void _tr_init(s)
-+ deflate_state *s;
-+{
-+ tr_static_init();
-+
-+ s->l_desc.dyn_tree = s->dyn_ltree;
-+ s->l_desc.stat_desc = &static_l_desc;
-+
-+ s->d_desc.dyn_tree = s->dyn_dtree;
-+ s->d_desc.stat_desc = &static_d_desc;
-+
-+ s->bl_desc.dyn_tree = s->bl_tree;
-+ s->bl_desc.stat_desc = &static_bl_desc;
-+
-+ s->bi_buf = 0;
-+ s->bi_valid = 0;
-+ s->last_eob_len = 8; /* enough lookahead for inflate */
-+#ifdef DEBUG
-+ s->compressed_len = 0L;
-+ s->bits_sent = 0L;
-+#endif
-+
-+ /* Initialize the first block of the first file: */
-+ init_block(s);
-+}
-+
-+/* ===========================================================================
-+ * Initialize a new block.
-+ */
-+local void init_block(s)
-+ deflate_state *s;
-+{
-+ int n; /* iterates over tree elements */
-+
-+ /* Initialize the trees. */
-+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
-+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
-+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
-+
-+ s->dyn_ltree[END_BLOCK].Freq = 1;
-+ s->opt_len = s->static_len = 0L;
-+ s->last_lit = s->matches = 0;
-+}
-+
-+#define SMALLEST 1
-+/* Index within the heap array of least frequent node in the Huffman tree */
-+
-+
-+/* ===========================================================================
-+ * Remove the smallest element from the heap and recreate the heap with
-+ * one less element. Updates heap and heap_len.
-+ */
-+#define pqremove(s, tree, top) \
-+{\
-+ top = s->heap[SMALLEST]; \
-+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
-+ pqdownheap(s, tree, SMALLEST); \
-+}
-+
-+/* ===========================================================================
-+ * Compares to subtrees, using the tree depth as tie breaker when
-+ * the subtrees have equal frequency. This minimizes the worst case length.
-+ */
-+#define smaller(tree, n, m, depth) \
-+ (tree[n].Freq < tree[m].Freq || \
-+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
-+
-+/* ===========================================================================
-+ * Restore the heap property by moving down the tree starting at node k,
-+ * exchanging a node with the smallest of its two sons if necessary, stopping
-+ * when the heap property is re-established (each father smaller than its
-+ * two sons).
-+ */
-+local void pqdownheap(s, tree, k)
-+ deflate_state *s;
-+ ct_data *tree; /* the tree to restore */
-+ int k; /* node to move down */
-+{
-+ int v = s->heap[k];
-+ int j = k << 1; /* left son of k */
-+ while (j <= s->heap_len) {
-+ /* Set j to the smallest of the two sons: */
-+ if (j < s->heap_len &&
-+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
-+ j++;
-+ }
-+ /* Exit if v is smaller than both sons */
-+ if (smaller(tree, v, s->heap[j], s->depth)) break;
-+
-+ /* Exchange v with the smallest son */
-+ s->heap[k] = s->heap[j]; k = j;
-+
-+ /* And continue down the tree, setting j to the left son of k */
-+ j <<= 1;
-+ }
-+ s->heap[k] = v;
-+}
-+
-+/* ===========================================================================
-+ * Compute the optimal bit lengths for a tree and update the total bit length
-+ * for the current block.
-+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
-+ * above are the tree nodes sorted by increasing frequency.
-+ * OUT assertions: the field len is set to the optimal bit length, the
-+ * array bl_count contains the frequencies for each bit length.
-+ * The length opt_len is updated; static_len is also updated if stree is
-+ * not null.
-+ */
-+local void gen_bitlen(s, desc)
-+ deflate_state *s;
-+ tree_desc *desc; /* the tree descriptor */
-+{
-+ ct_data *tree = desc->dyn_tree;
-+ int max_code = desc->max_code;
-+ const ct_data *stree = desc->stat_desc->static_tree;
-+ const intf *extra = desc->stat_desc->extra_bits;
-+ int base = desc->stat_desc->extra_base;
-+ int max_length = desc->stat_desc->max_length;
-+ int h; /* heap index */
-+ int n, m; /* iterate over the tree elements */
-+ int bits; /* bit length */
-+ int xbits; /* extra bits */
-+ ush f; /* frequency */
-+ int overflow = 0; /* number of elements with bit length too large */
-+
-+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
-+
-+ /* In a first pass, compute the optimal bit lengths (which may
-+ * overflow in the case of the bit length tree).
-+ */
-+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
-+
-+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
-+ n = s->heap[h];
-+ bits = tree[tree[n].Dad].Len + 1;
-+ if (bits > max_length) bits = max_length, overflow++;
-+ tree[n].Len = (ush)bits;
-+ /* We overwrite tree[n].Dad which is no longer needed */
-+
-+ if (n > max_code) continue; /* not a leaf node */
-+
-+ s->bl_count[bits]++;
-+ xbits = 0;
-+ if (n >= base) xbits = extra[n-base];
-+ f = tree[n].Freq;
-+ s->opt_len += (ulg)f * (bits + xbits);
-+ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
-+ }
-+ if (overflow == 0) return;
-+
-+ Trace((stderr,"\nbit length overflow\n"));
-+ /* This happens for example on obj2 and pic of the Calgary corpus */
-+
-+ /* Find the first bit length which could increase: */
-+ do {
-+ bits = max_length-1;
-+ while (s->bl_count[bits] == 0) bits--;
-+ s->bl_count[bits]--; /* move one leaf down the tree */
-+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
-+ s->bl_count[max_length]--;
-+ /* The brother of the overflow item also moves one step up,
-+ * but this does not affect bl_count[max_length]
-+ */
-+ overflow -= 2;
-+ } while (overflow > 0);
-+
-+ /* Now recompute all bit lengths, scanning in increasing frequency.
-+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
-+ * lengths instead of fixing only the wrong ones. This idea is taken
-+ * from 'ar' written by Haruhiko Okumura.)
-+ */
-+ for (bits = max_length; bits != 0; bits--) {
-+ n = s->bl_count[bits];
-+ while (n != 0) {
-+ m = s->heap[--h];
-+ if (m > max_code) continue;
-+ if (tree[m].Len != (unsigned) bits) {
-+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
-+ s->opt_len += ((long)bits - (long)tree[m].Len)
-+ *(long)tree[m].Freq;
-+ tree[m].Len = (ush)bits;
-+ }
-+ n--;
-+ }
-+ }
-+}
-+
-+/* ===========================================================================
-+ * Generate the codes for a given tree and bit counts (which need not be
-+ * optimal).
-+ * IN assertion: the array bl_count contains the bit length statistics for
-+ * the given tree and the field len is set for all tree elements.
-+ * OUT assertion: the field code is set for all tree elements of non
-+ * zero code length.
-+ */
-+local void gen_codes (tree, max_code, bl_count)
-+ ct_data *tree; /* the tree to decorate */
-+ int max_code; /* largest code with non zero frequency */
-+ ushf *bl_count; /* number of codes at each bit length */
-+{
-+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
-+ ush code = 0; /* running code value */
-+ int bits; /* bit index */
-+ int n; /* code index */
-+
-+ /* The distribution counts are first used to generate the code values
-+ * without bit reversal.
-+ */
-+ for (bits = 1; bits <= MAX_BITS; bits++) {
-+ next_code[bits] = code = (code + bl_count[bits-1]) << 1;
-+ }
-+ /* Check that the bit counts in bl_count are consistent. The last code
-+ * must be all ones.
-+ */
-+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
-+ "inconsistent bit counts");
-+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-+
-+ for (n = 0; n <= max_code; n++) {
-+ int len = tree[n].Len;
-+ if (len == 0) continue;
-+ /* Now reverse the bits */
-+ tree[n].Code = bi_reverse(next_code[len]++, len);
-+
-+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
-+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
-+ }
-+}
-+
-+/* ===========================================================================
-+ * Construct one Huffman tree and assigns the code bit strings and lengths.
-+ * Update the total bit length for the current block.
-+ * IN assertion: the field freq is set for all tree elements.
-+ * OUT assertions: the fields len and code are set to the optimal bit length
-+ * and corresponding code. The length opt_len is updated; static_len is
-+ * also updated if stree is not null. The field max_code is set.
-+ */
-+local void build_tree(s, desc)
-+ deflate_state *s;
-+ tree_desc *desc; /* the tree descriptor */
-+{
-+ ct_data *tree = desc->dyn_tree;
-+ const ct_data *stree = desc->stat_desc->static_tree;
-+ int elems = desc->stat_desc->elems;
-+ int n, m; /* iterate over heap elements */
-+ int max_code = -1; /* largest code with non zero frequency */
-+ int node; /* new node being created */
-+
-+ /* Construct the initial heap, with least frequent element in
-+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
-+ * heap[0] is not used.
-+ */
-+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
-+
-+ for (n = 0; n < elems; n++) {
-+ if (tree[n].Freq != 0) {
-+ s->heap[++(s->heap_len)] = max_code = n;
-+ s->depth[n] = 0;
-+ } else {
-+ tree[n].Len = 0;
-+ }
-+ }
-+
-+ /* The pkzip format requires that at least one distance code exists,
-+ * and that at least one bit should be sent even if there is only one
-+ * possible code. So to avoid special checks later on we force at least
-+ * two codes of non zero frequency.
-+ */
-+ while (s->heap_len < 2) {
-+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
-+ tree[node].Freq = 1;
-+ s->depth[node] = 0;
-+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
-+ /* node is 0 or 1 so it does not have extra bits */
-+ }
-+ desc->max_code = max_code;
-+
-+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
-+ * establish sub-heaps of increasing lengths:
-+ */
-+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
-+
-+ /* Construct the Huffman tree by repeatedly combining the least two
-+ * frequent nodes.
-+ */
-+ node = elems; /* next internal node of the tree */
-+ do {
-+ pqremove(s, tree, n); /* n = node of least frequency */
-+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
-+
-+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
-+ s->heap[--(s->heap_max)] = m;
-+
-+ /* Create a new node father of n and m */
-+ tree[node].Freq = tree[n].Freq + tree[m].Freq;
-+ s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
-+ tree[n].Dad = tree[m].Dad = (ush)node;
-+#ifdef DUMP_BL_TREE
-+ if (tree == s->bl_tree) {
-+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
-+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
-+ }
-+#endif
-+ /* and insert the new node in the heap */
-+ s->heap[SMALLEST] = node++;
-+ pqdownheap(s, tree, SMALLEST);
-+
-+ } while (s->heap_len >= 2);
-+
-+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
-+
-+ /* At this point, the fields freq and dad are set. We can now
-+ * generate the bit lengths.
-+ */
-+ gen_bitlen(s, (tree_desc *)desc);
-+
-+ /* The field len is now set, we can generate the bit codes */
-+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
-+}
-+
-+/* ===========================================================================
-+ * Scan a literal or distance tree to determine the frequencies of the codes
-+ * in the bit length tree.
-+ */
-+local void scan_tree (s, tree, max_code)
-+ deflate_state *s;
-+ ct_data *tree; /* the tree to be scanned */
-+ int max_code; /* and its largest code of non zero frequency */
-+{
-+ int n; /* iterates over all tree elements */
-+ int prevlen = -1; /* last emitted length */
-+ int curlen; /* length of current code */
-+ int nextlen = tree[0].Len; /* length of next code */
-+ int count = 0; /* repeat count of the current code */
-+ int max_count = 7; /* max repeat count */
-+ int min_count = 4; /* min repeat count */
-+
-+ if (nextlen == 0) max_count = 138, min_count = 3;
-+ tree[max_code+1].Len = (ush)0xffff; /* guard */
-+
-+ for (n = 0; n <= max_code; n++) {
-+ curlen = nextlen; nextlen = tree[n+1].Len;
-+ if (++count < max_count && curlen == nextlen) {
-+ continue;
-+ } else if (count < min_count) {
-+ s->bl_tree[curlen].Freq += count;
-+ } else if (curlen != 0) {
-+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
-+ s->bl_tree[REP_3_6].Freq++;
-+ } else if (count <= 10) {
-+ s->bl_tree[REPZ_3_10].Freq++;
-+ } else {
-+ s->bl_tree[REPZ_11_138].Freq++;
-+ }
-+ count = 0; prevlen = curlen;
-+ if (nextlen == 0) {
-+ max_count = 138, min_count = 3;
-+ } else if (curlen == nextlen) {
-+ max_count = 6, min_count = 3;
-+ } else {
-+ max_count = 7, min_count = 4;
-+ }
-+ }
-+}
-+
-+/* ===========================================================================
-+ * Send a literal or distance tree in compressed form, using the codes in
-+ * bl_tree.
-+ */
-+local void send_tree (s, tree, max_code)
-+ deflate_state *s;
-+ ct_data *tree; /* the tree to be scanned */
-+ int max_code; /* and its largest code of non zero frequency */
-+{
-+ int n; /* iterates over all tree elements */
-+ int prevlen = -1; /* last emitted length */
-+ int curlen; /* length of current code */
-+ int nextlen = tree[0].Len; /* length of next code */
-+ int count = 0; /* repeat count of the current code */
-+ int max_count = 7; /* max repeat count */
-+ int min_count = 4; /* min repeat count */
-+
-+ /* tree[max_code+1].Len = -1; */ /* guard already set */
-+ if (nextlen == 0) max_count = 138, min_count = 3;
-+
-+ for (n = 0; n <= max_code; n++) {
-+ curlen = nextlen; nextlen = tree[n+1].Len;
-+ if (++count < max_count && curlen == nextlen) {
-+ continue;
-+ } else if (count < min_count) {
-+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
-+
-+ } else if (curlen != 0) {
-+ if (curlen != prevlen) {
-+ send_code(s, curlen, s->bl_tree); count--;
-+ }
-+ Assert(count >= 3 && count <= 6, " 3_6?");
-+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
-+
-+ } else if (count <= 10) {
-+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
-+
-+ } else {
-+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
-+ }
-+ count = 0; prevlen = curlen;
-+ if (nextlen == 0) {
-+ max_count = 138, min_count = 3;
-+ } else if (curlen == nextlen) {
-+ max_count = 6, min_count = 3;
-+ } else {
-+ max_count = 7, min_count = 4;
-+ }
-+ }
-+}
-+
-+/* ===========================================================================
-+ * Construct the Huffman tree for the bit lengths and return the index in
-+ * bl_order of the last bit length code to send.
-+ */
-+local int build_bl_tree(s)
-+ deflate_state *s;
-+{
-+ int max_blindex; /* index of last bit length code of non zero freq */
-+
-+ /* Determine the bit length frequencies for literal and distance trees */
-+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
-+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
-+
-+ /* Build the bit length tree: */
-+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
-+ /* opt_len now includes the length of the tree representations, except
-+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
-+ */
-+
-+ /* Determine the number of bit length codes to send. The pkzip format
-+ * requires that at least 4 bit length codes be sent. (appnote.txt says
-+ * 3 but the actual value used is 4.)
-+ */
-+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
-+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
-+ }
-+ /* Update opt_len to include the bit length tree and counts */
-+ s->opt_len += 3*(max_blindex+1) + 5+5+4;
-+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
-+ s->opt_len, s->static_len));
-+
-+ return max_blindex;
-+}
-+
-+/* ===========================================================================
-+ * Send the header for a block using dynamic Huffman trees: the counts, the
-+ * lengths of the bit length codes, the literal tree and the distance tree.
-+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
-+ */
-+local void send_all_trees(s, lcodes, dcodes, blcodes)
-+ deflate_state *s;
-+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
-+{
-+ int rank; /* index in bl_order */
-+
-+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
-+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
-+ "too many codes");
-+ Tracev((stderr, "\nbl counts: "));
-+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
-+ send_bits(s, dcodes-1, 5);
-+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
-+ for (rank = 0; rank < blcodes; rank++) {
-+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
-+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
-+ }
-+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
-+
-+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
-+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
-+
-+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
-+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
-+}
-+
-+/* ===========================================================================
-+ * Send a stored block
-+ */
-+void _tr_stored_block(s, buf, stored_len, eof)
-+ deflate_state *s;
-+ charf *buf; /* input block */
-+ ulg stored_len; /* length of input block */
-+ int eof; /* true if this is the last block for a file */
-+{
-+ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
-+#ifdef DEBUG
-+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
-+ s->compressed_len += (stored_len + 4) << 3;
-+#endif
-+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
-+}
-+
-+/* ===========================================================================
-+ * Send one empty static block to give enough lookahead for inflate.
-+ * This takes 10 bits, of which 7 may remain in the bit buffer.
-+ * The current inflate code requires 9 bits of lookahead. If the
-+ * last two codes for the previous block (real code plus EOB) were coded
-+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
-+ * the last real code. In this case we send two empty static blocks instead
-+ * of one. (There are no problems if the previous block is stored or fixed.)
-+ * To simplify the code, we assume the worst case of last real code encoded
-+ * on one bit only.
-+ */
-+void _tr_align(s)
-+ deflate_state *s;
-+{
-+ send_bits(s, STATIC_TREES<<1, 3);
-+ send_code(s, END_BLOCK, static_ltree);
-+#ifdef DEBUG
-+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
-+#endif
-+ bi_flush(s);
-+ /* Of the 10 bits for the empty block, we have already sent
-+ * (10 - bi_valid) bits. The lookahead for the last real code (before
-+ * the EOB of the previous block) was thus at least one plus the length
-+ * of the EOB plus what we have just sent of the empty static block.
-+ */
-+ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
-+ send_bits(s, STATIC_TREES<<1, 3);
-+ send_code(s, END_BLOCK, static_ltree);
-+#ifdef DEBUG
-+ s->compressed_len += 10L;
-+#endif
-+ bi_flush(s);
-+ }
-+ s->last_eob_len = 7;
-+}
-+
-+/* ===========================================================================
-+ * Determine the best encoding for the current block: dynamic trees, static
-+ * trees or store, and output the encoded block to the zip file.
-+ */
-+void _tr_flush_block(s, buf, stored_len, eof)
-+ deflate_state *s;
-+ charf *buf; /* input block, or NULL if too old */
-+ ulg stored_len; /* length of input block */
-+ int eof; /* true if this is the last block for a file */
-+{
-+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
-+ int max_blindex = 0; /* index of last bit length code of non zero freq */
-+
-+ /* Build the Huffman trees unless a stored block is forced */
-+ if (s->level > 0) {
-+
-+ /* Check if the file is ascii or binary */
-+ if (s->data_type == Z_UNKNOWN) set_data_type(s);
-+
-+ /* Construct the literal and distance trees */
-+ build_tree(s, (tree_desc *)(&(s->l_desc)));
-+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
-+ s->static_len));
-+
-+ build_tree(s, (tree_desc *)(&(s->d_desc)));
-+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
-+ s->static_len));
-+ /* At this point, opt_len and static_len are the total bit lengths of
-+ * the compressed block data, excluding the tree representations.
-+ */
-+
-+ /* Build the bit length tree for the above two trees, and get the index
-+ * in bl_order of the last bit length code to send.
-+ */
-+ max_blindex = build_bl_tree(s);
-+
-+ /* Determine the best encoding. Compute first the block length in bytes*/
-+ opt_lenb = (s->opt_len+3+7)>>3;
-+ static_lenb = (s->static_len+3+7)>>3;
-+
-+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
-+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
-+ s->last_lit));
-+
-+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
-+
-+ } else {
-+ Assert(buf != (char*)0, "lost buf");
-+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
-+ }
-+
-+#ifdef FORCE_STORED
-+ if (buf != (char*)0) { /* force stored block */
-+#else
-+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
-+ /* 4: two words for the lengths */
-+#endif
-+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
-+ * Otherwise we can't have processed more than WSIZE input bytes since
-+ * the last block flush, because compression would have been
-+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
-+ * transform a block into a stored block.
-+ */
-+ _tr_stored_block(s, buf, stored_len, eof);
-+
-+#ifdef FORCE_STATIC
-+ } else if (static_lenb >= 0) { /* force static trees */
-+#else
-+ } else if (static_lenb == opt_lenb) {
-+#endif
-+ send_bits(s, (STATIC_TREES<<1)+eof, 3);
-+ compress_block(s, static_ltree, static_dtree);
-+#ifdef DEBUG
-+ s->compressed_len += 3 + s->static_len;
-+#endif
-+ } else {
-+ send_bits(s, (DYN_TREES<<1)+eof, 3);
-+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
-+ max_blindex+1);
-+ compress_block(s, s->dyn_ltree, s->dyn_dtree);
-+#ifdef DEBUG
-+ s->compressed_len += 3 + s->opt_len;
-+#endif
-+ }
-+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
-+ /* The above check is made mod 2^32, for files larger than 512 MB
-+ * and uLong implemented on 32 bits.
-+ */
-+ init_block(s);
-+
-+ if (eof) {
-+ bi_windup(s);
-+#ifdef DEBUG
-+ s->compressed_len += 7; /* align on byte boundary */
-+#endif
-+ }
-+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
-+ s->compressed_len-7*eof));
-+}
-+
-+/* ===========================================================================
-+ * Save the match info and tally the frequency counts. Return true if
-+ * the current block must be flushed.
-+ */
-+int _tr_tally (s, dist, lc)
-+ deflate_state *s;
-+ unsigned dist; /* distance of matched string */
-+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
-+{
-+ s->d_buf[s->last_lit] = (ush)dist;
-+ s->l_buf[s->last_lit++] = (uch)lc;
-+ if (dist == 0) {
-+ /* lc is the unmatched char */
-+ s->dyn_ltree[lc].Freq++;
-+ } else {
-+ s->matches++;
-+ /* Here, lc is the match length - MIN_MATCH */
-+ dist--; /* dist = match distance - 1 */
-+ Assert((ush)dist < (ush)MAX_DIST(s) &&
-+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
-+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
-+
-+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
-+ s->dyn_dtree[d_code(dist)].Freq++;
-+ }
-+
-+#ifdef TRUNCATE_BLOCK
-+ /* Try to guess if it is profitable to stop the current block here */
-+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
-+ /* Compute an upper bound for the compressed length */
-+ ulg out_length = (ulg)s->last_lit*8L;
-+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
-+ int dcode;
-+ for (dcode = 0; dcode < D_CODES; dcode++) {
-+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
-+ (5L+extra_dbits[dcode]);
-+ }
-+ out_length >>= 3;
-+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
-+ s->last_lit, in_length, out_length,
-+ 100L - out_length*100L/in_length));
-+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
-+ }
-+#endif
-+ return (s->last_lit == s->lit_bufsize-1);
-+ /* We avoid equality with lit_bufsize because of wraparound at 64K
-+ * on 16 bit machines and because stored blocks are restricted to
-+ * 64K-1 bytes.
-+ */
-+}
-+
-+/* ===========================================================================
-+ * Send the block data compressed using the given Huffman trees
-+ */
-+local void compress_block(s, ltree, dtree)
-+ deflate_state *s;
-+ const ct_data *ltree; /* literal tree */
-+ const ct_data *dtree; /* distance tree */
-+{
-+ unsigned dist; /* distance of matched string */
-+ int lc; /* match length or unmatched char (if dist == 0) */
-+ unsigned lx = 0; /* running index in l_buf */
-+ unsigned code; /* the code to send */
-+ int extra; /* number of extra bits to send */
-+
-+ if (s->last_lit != 0) do {
-+ dist = s->d_buf[lx];
-+ lc = s->l_buf[lx++];
-+ if (dist == 0) {
-+ send_code(s, lc, ltree); /* send a literal byte */
-+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
-+ } else {
-+ /* Here, lc is the match length - MIN_MATCH */
-+ code = _length_code[lc];
-+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
-+ extra = extra_lbits[code];
-+ if (extra != 0) {
-+ lc -= base_length[code];
-+ send_bits(s, lc, extra); /* send the extra length bits */
-+ }
-+ dist--; /* dist is now the match distance - 1 */
-+ code = d_code(dist);
-+ Assert (code < D_CODES, "bad d_code");
-+
-+ send_code(s, code, dtree); /* send the distance code */
-+ extra = extra_dbits[code];
-+ if (extra != 0) {
-+ dist -= base_dist[code];
-+ send_bits(s, dist, extra); /* send the extra distance bits */
-+ }
-+ } /* literal or match pair ? */
-+
-+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
-+ Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
-+
-+ } while (lx < s->last_lit);
-+
-+ send_code(s, END_BLOCK, ltree);
-+ s->last_eob_len = ltree[END_BLOCK].Len;
-+}
-+
-+/* ===========================================================================
-+ * Set the data type to ASCII or BINARY, using a crude approximation:
-+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
-+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
-+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
-+ */
-+local void set_data_type(s)
-+ deflate_state *s;
-+{
-+ int n = 0;
-+ unsigned ascii_freq = 0;
-+ unsigned bin_freq = 0;
-+ while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
-+ while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
-+ while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
-+ s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
-+}
-+
-+/* ===========================================================================
-+ * Reverse the first len bits of a code, using straightforward code (a faster
-+ * method would use a table)
-+ * IN assertion: 1 <= len <= 15
-+ */
-+local unsigned bi_reverse(code, len)
-+ unsigned code; /* the value to invert */
-+ int len; /* its bit length */
-+{
-+ register unsigned res = 0;
-+ do {
-+ res |= code & 1;
-+ code >>= 1, res <<= 1;
-+ } while (--len > 0);
-+ return res >> 1;
-+}
-+
-+/* ===========================================================================
-+ * Flush the bit buffer, keeping at most 7 bits in it.
-+ */
-+local void bi_flush(s)
-+ deflate_state *s;
-+{
-+ if (s->bi_valid == 16) {
-+ put_short(s, s->bi_buf);
-+ s->bi_buf = 0;
-+ s->bi_valid = 0;
-+ } else if (s->bi_valid >= 8) {
-+ put_byte(s, (Byte)s->bi_buf);
-+ s->bi_buf >>= 8;
-+ s->bi_valid -= 8;
-+ }
-+}
-+
-+/* ===========================================================================
-+ * Flush the bit buffer and align the output on a byte boundary
-+ */
-+local void bi_windup(s)
-+ deflate_state *s;
-+{
-+ if (s->bi_valid > 8) {
-+ put_short(s, s->bi_buf);
-+ } else if (s->bi_valid > 0) {
-+ put_byte(s, (Byte)s->bi_buf);
-+ }
-+ s->bi_buf = 0;
-+ s->bi_valid = 0;
-+#ifdef DEBUG
-+ s->bits_sent = (s->bits_sent+7) & ~7;
-+#endif
-+}
-+
-+/* ===========================================================================
-+ * Copy a stored block, storing first the length and its
-+ * one's complement if requested.
-+ */
-+local void copy_block(s, buf, len, header)
-+ deflate_state *s;
-+ charf *buf; /* the input data */
-+ unsigned len; /* its length */
-+ int header; /* true if block header must be written */
-+{
-+ bi_windup(s); /* align on byte boundary */
-+ s->last_eob_len = 8; /* enough lookahead for inflate */
-+
-+ if (header) {
-+ put_short(s, (ush)len);
-+ put_short(s, (ush)~len);
-+#ifdef DEBUG
-+ s->bits_sent += 2*16;
-+#endif
-+ }
-+#ifdef DEBUG
-+ s->bits_sent += (ulg)len<<3;
-+#endif
-+ while (len--) {
-+ put_byte(s, *buf++);
-+ }
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/trees.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,128 @@
-+/* header created automatically with -DGEN_TREES_H */
-+
-+local const ct_data static_ltree[L_CODES+2] = {
-+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
-+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
-+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
-+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
-+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
-+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
-+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
-+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
-+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
-+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
-+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
-+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
-+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
-+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
-+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
-+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
-+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
-+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
-+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
-+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
-+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
-+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
-+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
-+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
-+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
-+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
-+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
-+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
-+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
-+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
-+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
-+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
-+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
-+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
-+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
-+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
-+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
-+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
-+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
-+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
-+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
-+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
-+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
-+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
-+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
-+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
-+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
-+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
-+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
-+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
-+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
-+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
-+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
-+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
-+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
-+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
-+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
-+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
-+};
-+
-+local const ct_data static_dtree[D_CODES] = {
-+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
-+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
-+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
-+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
-+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
-+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
-+};
-+
-+const uch _dist_code[DIST_CODE_LEN] = {
-+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
-+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
-+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
-+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
-+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
-+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
-+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
-+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
-+};
-+
-+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
-+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
-+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
-+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
-+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
-+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
-+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
-+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
-+};
-+
-+local const int base_length[LENGTH_CODES] = {
-+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
-+64, 80, 96, 112, 128, 160, 192, 224, 0
-+};
-+
-+local const int base_dist[D_CODES] = {
-+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
-+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
-+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
-+};
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/zconf.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,309 @@
-+/* zconf.h -- configuration of the zlib compression library
-+ * Copyright (C) 1995-2002 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* @(#) $Id$ */
-+
-+#ifndef _ZCONF_H
-+#define _ZCONF_H
-+
-+/*
-+ * If you *really* need a unique prefix for all types and library functions,
-+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
-+ */
-+#ifdef IPCOMP_PREFIX
-+# define deflateInit_ ipcomp_deflateInit_
-+# define deflate ipcomp_deflate
-+# define deflateEnd ipcomp_deflateEnd
-+# define inflateInit_ ipcomp_inflateInit_
-+# define inflate ipcomp_inflate
-+# define inflateEnd ipcomp_inflateEnd
-+# define deflateInit2_ ipcomp_deflateInit2_
-+# define deflateSetDictionary ipcomp_deflateSetDictionary
-+# define deflateCopy ipcomp_deflateCopy
-+# define deflateReset ipcomp_deflateReset
-+# define deflateParams ipcomp_deflateParams
-+# define inflateInit2_ ipcomp_inflateInit2_
-+# define inflateSetDictionary ipcomp_inflateSetDictionary
-+# define inflateSync ipcomp_inflateSync
-+# define inflateSyncPoint ipcomp_inflateSyncPoint
-+# define inflateReset ipcomp_inflateReset
-+# define compress ipcomp_compress
-+# define compress2 ipcomp_compress2
-+# define uncompress ipcomp_uncompress
-+# define adler32 ipcomp_adler32
-+# define crc32 ipcomp_crc32
-+# define get_crc_table ipcomp_get_crc_table
-+/* SSS: these also need to be prefixed to avoid clash with ppp_deflate and ext2compression */
-+# define inflate_blocks ipcomp_deflate_blocks
-+# define inflate_blocks_free ipcomp_deflate_blocks_free
-+# define inflate_blocks_new ipcomp_inflate_blocks_new
-+# define inflate_blocks_reset ipcomp_inflate_blocks_reset
-+# define inflate_blocks_sync_point ipcomp_inflate_blocks_sync_point
-+# define inflate_set_dictionary ipcomp_inflate_set_dictionary
-+# define inflate_codes ipcomp_inflate_codes
-+# define inflate_codes_free ipcomp_inflate_codes_free
-+# define inflate_codes_new ipcomp_inflate_codes_new
-+# define inflate_fast ipcomp_inflate_fast
-+# define inflate_trees_bits ipcomp_inflate_trees_bits
-+# define inflate_trees_dynamic ipcomp_inflate_trees_dynamic
-+# define inflate_trees_fixed ipcomp_inflate_trees_fixed
-+# define inflate_flush ipcomp_inflate_flush
-+# define inflate_mask ipcomp_inflate_mask
-+# define _dist_code _ipcomp_dist_code
-+# define _length_code _ipcomp_length_code
-+# define _tr_align _ipcomp_tr_align
-+# define _tr_flush_block _ipcomp_tr_flush_block
-+# define _tr_init _ipcomp_tr_init
-+# define _tr_stored_block _ipcomp_tr_stored_block
-+# define _tr_tally _ipcomp_tr_tally
-+# define zError ipcomp_zError
-+# define z_errmsg ipcomp_z_errmsg
-+# define zlibVersion ipcomp_zlibVersion
-+# define match_init ipcomp_match_init
-+# define longest_match ipcomp_longest_match
-+#endif
-+
-+#ifdef Z_PREFIX
-+# define Byte z_Byte
-+# define uInt z_uInt
-+# define uLong z_uLong
-+# define Bytef z_Bytef
-+# define charf z_charf
-+# define intf z_intf
-+# define uIntf z_uIntf
-+# define uLongf z_uLongf
-+# define voidpf z_voidpf
-+# define voidp z_voidp
-+#endif
-+
-+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-+# define WIN32
-+#endif
-+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
-+# ifndef __32BIT__
-+# define __32BIT__
-+# endif
-+#endif
-+#if defined(__MSDOS__) && !defined(MSDOS)
-+# define MSDOS
-+#endif
-+
-+/*
-+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
-+ * than 64k bytes at a time (needed on systems with 16-bit int).
-+ */
-+#if defined(MSDOS) && !defined(__32BIT__)
-+# define MAXSEG_64K
-+#endif
-+#ifdef MSDOS
-+# define UNALIGNED_OK
-+#endif
-+
-+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
-+# define STDC
-+#endif
-+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
-+# ifndef STDC
-+# define STDC
-+# endif
-+#endif
-+
-+#ifndef STDC
-+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-+# define const
-+# endif
-+#endif
-+
-+/* Some Mac compilers merge all .h files incorrectly: */
-+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
-+# define NO_DUMMY_DECL
-+#endif
-+
-+/* Old Borland C incorrectly complains about missing returns: */
-+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
-+# define NEED_DUMMY_RETURN
-+#endif
-+
-+
-+/* Maximum value for memLevel in deflateInit2 */
-+#ifndef MAX_MEM_LEVEL
-+# ifdef MAXSEG_64K
-+# define MAX_MEM_LEVEL 8
-+# else
-+# define MAX_MEM_LEVEL 9
-+# endif
-+#endif
-+
-+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
-+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
-+ * created by gzip. (Files created by minigzip can still be extracted by
-+ * gzip.)
-+ */
-+#ifndef MAX_WBITS
-+# define MAX_WBITS 15 /* 32K LZ77 window */
-+#endif
-+
-+/* The memory requirements for deflate are (in bytes):
-+ (1 << (windowBits+2)) + (1 << (memLevel+9))
-+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
-+ plus a few kilobytes for small objects. For example, if you want to reduce
-+ the default memory requirements from 256K to 128K, compile with
-+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
-+ Of course this will generally degrade compression (there's no free lunch).
-+
-+ The memory requirements for inflate are (in bytes) 1 << windowBits
-+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
-+ for small objects.
-+*/
-+
-+ /* Type declarations */
-+
-+#ifndef OF /* function prototypes */
-+# ifdef STDC
-+# define OF(args) args
-+# else
-+# define OF(args) ()
-+# endif
-+#endif
-+
-+/* The following definitions for FAR are needed only for MSDOS mixed
-+ * model programming (small or medium model with some far allocations).
-+ * This was tested only with MSC; for other MSDOS compilers you may have
-+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
-+ * just define FAR to be empty.
-+ */
-+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
-+ /* MSC small or medium model */
-+# define SMALL_MEDIUM
-+# ifdef _MSC_VER
-+# define FAR _far
-+# else
-+# define FAR far
-+# endif
-+#endif
-+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
-+# ifndef __32BIT__
-+# define SMALL_MEDIUM
-+# define FAR _far
-+# endif
-+#endif
-+
-+/* Compile with -DZLIB_DLL for Windows DLL support */
-+#if defined(ZLIB_DLL)
-+# if defined(_WINDOWS) || defined(WINDOWS)
-+# ifdef FAR
-+# undef FAR
-+# endif
-+# include <windows.h>
-+# define ZEXPORT WINAPI
-+# ifdef WIN32
-+# define ZEXPORTVA WINAPIV
-+# else
-+# define ZEXPORTVA FAR _cdecl _export
-+# endif
-+# endif
-+# if defined (__BORLANDC__)
-+# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
-+# include <windows.h>
-+# define ZEXPORT __declspec(dllexport) WINAPI
-+# define ZEXPORTRVA __declspec(dllexport) WINAPIV
-+# else
-+# if defined (_Windows) && defined (__DLL__)
-+# define ZEXPORT _export
-+# define ZEXPORTVA _export
-+# endif
-+# endif
-+# endif
-+#endif
-+
-+#if defined (__BEOS__)
-+# if defined (ZLIB_DLL)
-+# define ZEXTERN extern __declspec(dllexport)
-+# else
-+# define ZEXTERN extern __declspec(dllimport)
-+# endif
-+#endif
-+
-+#ifndef ZEXPORT
-+# define ZEXPORT
-+#endif
-+#ifndef ZEXPORTVA
-+# define ZEXPORTVA
-+#endif
-+#ifndef ZEXTERN
-+# define ZEXTERN extern
-+#endif
-+
-+#ifndef FAR
-+# define FAR
-+#endif
-+
-+#if !defined(MACOS) && !defined(TARGET_OS_MAC)
-+typedef unsigned char Byte; /* 8 bits */
-+#endif
-+typedef unsigned int uInt; /* 16 bits or more */
-+typedef unsigned long uLong; /* 32 bits or more */
-+
-+#ifdef SMALL_MEDIUM
-+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
-+# define Bytef Byte FAR
-+#else
-+ typedef Byte FAR Bytef;
-+#endif
-+typedef char FAR charf;
-+typedef int FAR intf;
-+typedef uInt FAR uIntf;
-+typedef uLong FAR uLongf;
-+
-+#ifdef STDC
-+ typedef void FAR *voidpf;
-+ typedef void *voidp;
-+#else
-+ typedef Byte FAR *voidpf;
-+ typedef Byte *voidp;
-+#endif
-+
-+#ifdef HAVE_UNISTD_H
-+# include <sys/types.h> /* for off_t */
-+# include <unistd.h> /* for SEEK_* and off_t */
-+# define z_off_t off_t
-+#endif
-+#ifndef SEEK_SET
-+# define SEEK_SET 0 /* Seek from beginning of file. */
-+# define SEEK_CUR 1 /* Seek from current position. */
-+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
-+#endif
-+#ifndef z_off_t
-+# define z_off_t long
-+#endif
-+
-+/* MVS linker does not support external names larger than 8 bytes */
-+#if defined(__MVS__)
-+# pragma map(deflateInit_,"DEIN")
-+# pragma map(deflateInit2_,"DEIN2")
-+# pragma map(deflateEnd,"DEEND")
-+# pragma map(inflateInit_,"ININ")
-+# pragma map(inflateInit2_,"ININ2")
-+# pragma map(inflateEnd,"INEND")
-+# pragma map(inflateSync,"INSY")
-+# pragma map(inflateSetDictionary,"INSEDI")
-+# pragma map(inflate_blocks,"INBL")
-+# pragma map(inflate_blocks_new,"INBLNE")
-+# pragma map(inflate_blocks_free,"INBLFR")
-+# pragma map(inflate_blocks_reset,"INBLRE")
-+# pragma map(inflate_codes_free,"INCOFR")
-+# pragma map(inflate_codes,"INCO")
-+# pragma map(inflate_fast,"INFA")
-+# pragma map(inflate_flush,"INFLU")
-+# pragma map(inflate_mask,"INMA")
-+# pragma map(inflate_set_dictionary,"INSEDI2")
-+# pragma map(ipcomp_inflate_copyright,"INCOPY")
-+# pragma map(inflate_trees_bits,"INTRBI")
-+# pragma map(inflate_trees_dynamic,"INTRDY")
-+# pragma map(inflate_trees_fixed,"INTRFI")
-+# pragma map(inflate_trees_free,"INTRFR")
-+#endif
-+
-+#endif /* _ZCONF_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/zutil.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,227 @@
-+/* zutil.c -- target dependent utility functions for the compression library
-+ * Copyright (C) 1995-2002 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* @(#) $Id$ */
-+
-+#include <zlib/zutil.h>
-+
-+#define MY_ZCALLOC
-+
-+struct internal_state {int dummy;}; /* for buggy compilers */
-+
-+#ifndef STDC
-+extern void exit OF((int));
-+#endif
-+
-+const char *z_errmsg[10] = {
-+"need dictionary", /* Z_NEED_DICT 2 */
-+"stream end", /* Z_STREAM_END 1 */
-+"", /* Z_OK 0 */
-+"file error", /* Z_ERRNO (-1) */
-+"stream error", /* Z_STREAM_ERROR (-2) */
-+"data error", /* Z_DATA_ERROR (-3) */
-+"insufficient memory", /* Z_MEM_ERROR (-4) */
-+"buffer error", /* Z_BUF_ERROR (-5) */
-+"incompatible version",/* Z_VERSION_ERROR (-6) */
-+""};
-+
-+
-+const char * ZEXPORT zlibVersion()
-+{
-+ return ZLIB_VERSION;
-+}
-+
-+#ifdef DEBUG
-+
-+# ifndef verbose
-+# define verbose 0
-+# endif
-+int z_verbose = verbose;
-+
-+void z_error (m)
-+ char *m;
-+{
-+ fprintf(stderr, "%s\n", m);
-+ exit(1);
-+}
-+#endif
-+
-+/* exported to allow conversion of error code to string for compress() and
-+ * uncompress()
-+ */
-+const char * ZEXPORT zError(err)
-+ int err;
-+{
-+ return ERR_MSG(err);
-+}
-+
-+
-+#ifndef HAVE_MEMCPY
-+
-+void zmemcpy(dest, source, len)
-+ Bytef* dest;
-+ const Bytef* source;
-+ uInt len;
-+{
-+ if (len == 0) return;
-+ do {
-+ *dest++ = *source++; /* ??? to be unrolled */
-+ } while (--len != 0);
-+}
-+
-+int zmemcmp(s1, s2, len)
-+ const Bytef* s1;
-+ const Bytef* s2;
-+ uInt len;
-+{
-+ uInt j;
-+
-+ for (j = 0; j < len; j++) {
-+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
-+ }
-+ return 0;
-+}
-+
-+void zmemzero(dest, len)
-+ Bytef* dest;
-+ uInt len;
-+{
-+ if (len == 0) return;
-+ do {
-+ *dest++ = 0; /* ??? to be unrolled */
-+ } while (--len != 0);
-+}
-+#endif
-+
-+#ifdef __TURBOC__
-+#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
-+/* Small and medium model in Turbo C are for now limited to near allocation
-+ * with reduced MAX_WBITS and MAX_MEM_LEVEL
-+ */
-+# define MY_ZCALLOC
-+
-+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
-+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
-+ * must fix the pointer. Warning: the pointer must be put back to its
-+ * original form in order to free it, use zcfree().
-+ */
-+
-+#define MAX_PTR 10
-+/* 10*64K = 640K */
-+
-+local int next_ptr = 0;
-+
-+typedef struct ptr_table_s {
-+ voidpf org_ptr;
-+ voidpf new_ptr;
-+} ptr_table;
-+
-+local ptr_table table[MAX_PTR];
-+/* This table is used to remember the original form of pointers
-+ * to large buffers (64K). Such pointers are normalized with a zero offset.
-+ * Since MSDOS is not a preemptive multitasking OS, this table is not
-+ * protected from concurrent access. This hack doesn't work anyway on
-+ * a protected system like OS/2. Use Microsoft C instead.
-+ */
-+
-+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-+{
-+ voidpf buf = opaque; /* just to make some compilers happy */
-+ ulg bsize = (ulg)items*size;
-+
-+ /* If we allocate less than 65520 bytes, we assume that farmalloc
-+ * will return a usable pointer which doesn't have to be normalized.
-+ */
-+ if (bsize < 65520L) {
-+ buf = farmalloc(bsize);
-+ if (*(ush*)&buf != 0) return buf;
-+ } else {
-+ buf = farmalloc(bsize + 16L);
-+ }
-+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
-+ table[next_ptr].org_ptr = buf;
-+
-+ /* Normalize the pointer to seg:0 */
-+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
-+ *(ush*)&buf = 0;
-+ table[next_ptr++].new_ptr = buf;
-+ return buf;
-+}
-+
-+void zcfree (voidpf opaque, voidpf ptr)
-+{
-+ int n;
-+ if (*(ush*)&ptr != 0) { /* object < 64K */
-+ farfree(ptr);
-+ return;
-+ }
-+ /* Find the original pointer */
-+ for (n = 0; n < next_ptr; n++) {
-+ if (ptr != table[n].new_ptr) continue;
-+
-+ farfree(table[n].org_ptr);
-+ while (++n < next_ptr) {
-+ table[n-1] = table[n];
-+ }
-+ next_ptr--;
-+ return;
-+ }
-+ ptr = opaque; /* just to make some compilers happy */
-+ Assert(0, "zcfree: ptr not found");
-+}
-+#endif
-+#endif /* __TURBOC__ */
-+
-+
-+#if defined(M_I86) && !defined(__32BIT__)
-+/* Microsoft C in 16-bit mode */
-+
-+# define MY_ZCALLOC
-+
-+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
-+# define _halloc halloc
-+# define _hfree hfree
-+#endif
-+
-+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-+{
-+ if (opaque) opaque = 0; /* to make compiler happy */
-+ return _halloc((long)items, size);
-+}
-+
-+void zcfree (voidpf opaque, voidpf ptr)
-+{
-+ if (opaque) opaque = 0; /* to make compiler happy */
-+ _hfree(ptr);
-+}
-+
-+#endif /* MSC */
-+
-+
-+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
-+
-+#ifndef STDC
-+extern voidp calloc OF((uInt items, uInt size));
-+extern void free OF((voidpf ptr));
-+#endif
-+
-+voidpf zcalloc (opaque, items, size)
-+ voidpf opaque;
-+ unsigned items;
-+ unsigned size;
-+{
-+ if (opaque) items += size - size; /* make compiler happy */
-+ return (voidpf)calloc(items, size);
-+}
-+
-+void zcfree (opaque, ptr)
-+ voidpf opaque;
-+ voidpf ptr;
-+{
-+ free(ptr);
-+ if (opaque) return; /* make compiler happy */
-+}
-+
-+#endif /* MY_ZCALLOC */
---- linux/net/Config.in.orig Fri Feb 9 14:34:13 2001
-+++ linux/net/Config.in Thu Feb 22 19:40:08 2001
-@@ -88,4 +88,9 @@
- #bool 'Network code profiler' CONFIG_NET_PROFILE
- endmenu
-
-+tristate 'IP Security Protocol (FreeS/WAN IPSEC)' CONFIG_IPSEC
-+if [ "$CONFIG_IPSEC" != "n" ]; then
-+ source net/ipsec/Config.in
-+fi
-+
- endmenu
-RCSID $Id$
---- linux/net/Makefile.preipsec Mon Jun 11 22:15:27 2001
-+++ linux/net/Makefile Tue Nov 6 21:07:43 2001
-@@ -17,6 +17,7 @@
- subdir-$(CONFIG_NET) += 802 sched
- subdir-$(CONFIG_INET) += ipv4
- subdir-$(CONFIG_NETFILTER) += ipv4/netfilter
-+subdir-$(CONFIG_IPSEC) += ipsec
- subdir-$(CONFIG_UNIX) += unix
- subdir-$(CONFIG_IPV6) += ipv6
-
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/Config.in Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,76 @@
-+#
-+# IPSEC configuration
-+# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
-+#
-+# 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+#
-+# 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.
-+#
-+# RCSID $Id$
-+
-+comment 'IPSec options (Openswan)'
-+
-+bool ' IPSEC: IP-in-IP encapsulation (tunnel mode)' CONFIG_IPSEC_IPIP
-+
-+bool ' IPSEC: Authentication Header' CONFIG_IPSEC_AH
-+if [ "$CONFIG_IPSEC_AH" = "y" -o "$CONFIG_IPSEC_ESP" = "y" ]; then
-+ bool ' HMAC-MD5 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_MD5
-+ bool ' HMAC-SHA1 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_SHA1
-+fi
-+
-+bool ' IPSEC: Encapsulating Security Payload' CONFIG_IPSEC_ESP
-+if [ "$CONFIG_IPSEC_ESP" = "y" ]; then
-+ bool ' 3DES encryption algorithm' CONFIG_IPSEC_ENC_3DES
-+ bool ' AES encryption algorithm' CONFIG_IPSEC_ENC_AES
-+fi
-+
-+bool ' IPSEC Modular Extensions' CONFIG_IPSEC_ALG
-+if [ "$CONFIG_IPSEC_ALG" != "n" ]; then
-+ source net/ipsec/alg/Config.in
-+fi
-+
-+bool ' IPSEC: IP Compression' CONFIG_IPSEC_IPCOMP
-+
-+bool ' IPSEC Debugging Option' CONFIG_IPSEC_DEBUG
-+
-+#
-+#
-+# $Log$
-+# Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+# Turn off EOLN_NATIVE flag
-+#
-+# (Logical change 1.5010)
-+#
-+# Revision 1.30 2004/06/23 09:49:37 ken
-+# Free -> Open
-+#
-+# Revision 1.29 2004/04/06 02:49:25 mcr
-+# pullup of algo code from alg-branch.
-+#
-+# Revision 1.28 2004/02/03 03:12:26 mcr
-+# remove NAT-traversal option from IPsec config,
-+# as it should be in the kernel configuration if
-+# the NAT-T patch is installed.
-+#
-+# Revision 1.27.2.2 2004/04/05 04:30:46 mcr
-+# patches for alg-branch to compile/work with 2.x openswan
-+#
-+# Revision 1.27.2.1 2003/12/23 12:48:25 jjo
-+# Added missing alg part to linux/net/ipsec/Config.in
-+#
-+# Revision 1.27 2003/12/10 01:14:27 mcr
-+# NAT-traversal patches to KLIPS.
-+#
-+# Revision 1.26 2002/04/24 07:36:26 mcr
-+# Moved from ./klips/net/ipsec/Config.in,v
-+#
-+# Revision 1.25 2002/02/21 19:55:12 mcr
-+# removed all traces of IPSEC_CONFIG_REGRESS because it
-+# screwed up 2.2's "make menuconfig" scripts.
-+#
-+# Revision 1.24 2002/01/28 20:24:31 mcr
-+# commented out IPSEC_REGRESS option from user visible config.
-+#
-+#
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/Makefile Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,337 @@
-+# Makefile for KLIPS kernel code as a module
-+# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
-+# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-+#
-+# This program is free software; you can redistribute it and/or modify it
-+# under the terms of the GNU General Public License as published by the
-+# Free Software Foundation; either version 2 of the License, or (at your
-+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+#
-+# 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.
-+#
-+# RCSID $Id$
-+#
-+# Note! Dependencies are done automagically by 'make dep', which also
-+# removes any old dependencies. DON'T put your own dependencies here
-+# unless it's something special (ie not a .c file).
-+#
-+
-+ifeq ($(strip $(KLIPSMODULE)),)
-+OPENSWANSRCDIR=.
-+else
-+OPENSWANSRCDIR=../../..
-+endif
-+-include ${OPENSWANSRCDIR}/Makefile.ver
-+
-+ifeq ($(strip $(KLIPS_TOP)),)
-+KLIPS_TOP=../..
-+endif
-+
-+ifneq ($(strip $(KLIPSMODULE)),)
-+
-+ifndef TOPDIR
-+TOPDIR:=/usr/src/linux
-+endif
-+export TOPDIR
-+
-+endif
-+
-+#
-+# This magic from User-Mode-Linux list. It gets list of -I options, as
-+# UML needs some extra, that varry by revision.
-+#
-+KERNEL_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(CFLAGS)' )
-+
-+MODULE_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(MODFLAGS)' )
-+
-+subdir- :=
-+subdir-n :=
-+subdir-y :=
-+subdir-m :=
-+
-+
-+MOD_DESTDIR:=net/ipsec
-+
-+export TOPDIR
-+
-+all: ipsec.o
-+
-+foo:
-+ echo KERNEL: ${KERNEL_CFLAGS}
-+ echo MODULE: ${MODULE_CFLAGS}
-+
-+ipsec.o: foo
-+
-+O_TARGET := ipsec.o
-+obj-y := ipsec_init.o ipsec_sa.o ipsec_radij.o radij.o
-+obj-y += ipsec_life.o ipsec_proc.o
-+obj-y += ipsec_tunnel.o ipsec_xmit.o ipsec_rcv.o ipsec_ipip.o
-+obj-y += sysctl_net_ipsec.o
-+obj-y += pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o
-+obj-y += version.o
-+obj-$(CONFIG_IPSEC_AH) += ipsec_ah.o
-+obj-$(CONFIG_IPSEC_ESP) += ipsec_esp.o
-+obj-$(CONFIG_IPSEC_IPCOMP)+= ipsec_ipcomp.o
-+
-+CFLAGS_ipsec_alg.o += -DEXPORT_SYMTAB
-+obj-$(CONFIG_IPSEC_ALG) += ipsec_alg.o
-+obj-$(CONFIG_IPSEC_ENC_AES) += ipsec_alg_aes.o
-+obj-$(CONFIG_IPSEC_ENC_CRYPTOAPI) += ipsec_alg_cryptoapi.o
-+
-+export-objs += ipsec_alg.o
-+
-+
-+LIBDESDIR=${KLIPS_TOP}/crypto/ciphers/des
-+VPATH+= ${LIBDESDIR}
-+
-+include ${LIBDESDIR}/Makefile.objs
-+
-+LIBFREESWANDIR=${KLIPS_TOP}/lib/libfreeswan
-+VPATH+=${LIBFREESWANDIR}
-+
-+include ${LIBFREESWANDIR}/Makefile.objs
-+
-+# IPcomp stuff
-+obj-$(CONFIG_IPSEC_IPCOMP) += ipcomp.o
-+
-+LIBZLIBSRCDIR=${KLIPS_TOP}/lib/zlib
-+VPATH+=${LIBZLIBSRCDIR}
-+
-+LIBAESDIR=$(KLIPS_TOP)/crypto/ciphers/aes
-+VPATH+=${LIBAESDIR}
-+include ${LIBAESDIR}/Makefile.objs
-+
-+# CFLAGS='$(CFLAGS)' \
-+# MODULE_CFLAGS='$(MODULE_CFLAGS)' KERNEL_CFLAGS='$(KERNEL_CFLAGS)' \
-+#
-+include ${LIBZLIBSRCDIR}/Makefile.objs
-+
-+export-objs := radij.o
-+
-+EXTRA_CFLAGS += $(ALGO_FLAGS)
-+
-+
-+# include file with .h-style macros that would otherwise be created by
-+# config. Must occur before other includes.
-+ifneq ($(strip $(MODULE_DEF_INCLUDE)),)
-+EXTRA_CFLAGS += -include ${MODULE_DEF_INCLUDE}
-+endif
-+
-+# 'override CFLAGS' should really be 'EXTRA_CFLAGS'
-+#EXTRA_CFLAGS += -nostdinc
-+EXTRA_CFLAGS += -I${KLIPS_TOP}/include
-+
-+EXTRA_CFLAGS += -I${TOPDIR}/include
-+EXTRA_CFLAGS += -I${LIBZLIBSRCDIR}
-+
-+ifeq ($(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION),2.4.2-2)
-+EXTRA_CFLAGS += -DREDHAT_BOGOSITY
-+endif
-+
-+ifeq ($(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION),2.4.3-12)
-+EXTRA_CFLAGS += -DREDHAT_BOGOSITY
-+endif
-+
-+
-+#ifeq ($(CONFIG_IPSEC_DEBUG),y)
-+#EXTRA_CFLAGS += -g
-+#endif
-+
-+#ifeq ($(CONFIG_IPSEC_ALG), y)
-+EXTRA_CFLAGS += -DCONFIG_IPSEC_ALG
-+#endif
-+# MOST of these flags are in KERNEL_CFLAGS already!
-+
-+EXTRA_CFLAGS += $(KLIPSCOMPILE)
-+EXTRA_CFLAGS += -Wall
-+#EXTRA_CFLAGS += -Werror
-+#EXTRA_CFLAGS += -Wconversion
-+#EXTRA_CFLAGS += -Wmissing-prototypes
-+# cannot use both -Wpointer-arith and -Werror with CONFIG_HIGHMEM
-+# include/linux/highmem.h has an inline function definition that uses void* arithmentic.
-+ifeq ($(CONFIG_NOHIGHMEM),y)
-+EXTRA_CFLAGS += -Wpointer-arith
-+endif
-+#EXTRA_CFLAGS += -Wcast-qual
-+#EXTRA_CFLAGS += -Wmissing-declarations
-+#EXTRA_CFLAGS += -Wstrict-prototypes
-+#EXTRA_CFLAGS += -pedantic
-+#EXTRA_CFLAGS += -O3
-+#EXTRA_CFLAGS += -W
-+#EXTRA_CFLAGS += -Wwrite-strings
-+#EXTRA_CFLAGS += -Wbad-function-cast
-+
-+ifneq ($(strip $(KLIPSMODULE)),)
-+# for when we aren't building in the kernel tree
-+EXTRA_CFLAGS += -DARCH=${ARCH}
-+EXTRA_CFLAGS += -DMODVERSIONS
-+EXTRA_CFLAGS += -include ${TOPDIR}/include/linux/modversions.h
-+EXTRA_CFLAGS += ${MODULE_CFLAGS}
-+endif
-+
-+EXTRA_CFLAGS += ${KERNEL_CFLAGS}
-+
-+#EXTRA_CFLAGS += -DRJ_DEBUG -DRJ_DEBUG2
-+
-+
-+# GCC 3.2 (and we presume any other 3.x) wants -falign-functions
-+# in place of the traditional -malign-functions. Getting this
-+# wrong leads to a warning, which is fatal due to our use of -Werror.
-+ifeq ($(patsubst 3.%,3,$(shell $(CC) -dumpversion)),3)
-+override CFLAGS:=$(subst -malign-functions=,-falign-functions=,$(CFLAGS))
-+endif
-+
-+
-+obj-$(CONFIG_IPSEC_AUTH_HMAC_MD5) += ipsec_md5c.o
-+obj-$(CONFIG_IPSEC_AUTH_HMAC_SHA1) += ipsec_sha1.o
-+
-+###
-+### Pre Rules.make
-+###
-+# undo O_TARGET, obj-y if no static
-+ifneq ($(CONFIG_IPSEC),y)
-+O_TARGET :=
-+ipsec_obj-y := $(obj-y)
-+obj-y :=
-+subdir-y :=
-+endif
-+
-+# Define obj-m if modular ipsec
-+ifeq ($(CONFIG_IPSEC),m)
-+obj-m += ipsec.o
-+endif
-+
-+
-+# These rules translate from new to old makefile rules
-+# Translate to Rules.make lists.
-+multi-used := $(filter $(list-multi), $(obj-y) $(obj-m))
-+multi-objs := $(foreach m, $(multi-used), $($(basename $(m))-objs))
-+active-objs := $(sort $(multi-objs) $(obj-y) $(obj-m))
-+O_OBJS := $(obj-y)
-+M_OBJS := $(obj-m)
-+MIX_OBJS := $(filter $(export-objs), $(active-objs))
-+OX_OBJS := $(export-objs)
-+SUB_DIRS := $(subdir-y)
-+ALL_SUB_DIRS := $(subdir-y) $(subdir-m)
-+MOD_SUB_DIRS := $(subdir-m)
-+
-+# dunno why, but some 2.2 setups may need explicit -DEXPORT_SYMTAB
-+# uncomment next line if ipsec_alg.c compilation fails with
-+# "parse error before `EXPORT_SYMTAB_not_defined'" --Juanjo
-+
-+include $(TOPDIR)/Rules.make
-+
-+###
-+### Post Rules.make
-+###
-+# for modular ipsec, no O_TARGET defined => define ipsec.o creation rules
-+ifeq ($(CONFIG_IPSEC),m)
-+ipsec.o : $(ipsec_obj-y)
-+ rm -f $@
-+ $(LD) $(LD_EXTRAFLAGS) -r $(ipsec_obj-y) -o $@
-+endif
-+
-+$(ipsec_obj-y) $(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
-+
-+#$(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
-+
-+USE_STANDARD_AS_RULE=true
-+
-+clean:
-+ $(MAKE) -C alg clean
-+ -rm -f *.o
-+ -rm -f .*.o.flags
-+ -rm -f version.c
-+
-+tags TAGS: *.c *.h libfreeswan/*.c libfreeswan/*.h
-+ etags *.c ../../include/*.h ../../include/freeswan/*.h
-+ ctags *.c ../../include/*.h ../../include/freeswan/*.h
-+
-+tar:
-+ tar -cvf /dev/f1 .
-+
-+#
-+# $Log$
-+# Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+# Turn off EOLN_NATIVE flag
-+#
-+# (Logical change 1.5010)
-+#
-+# Revision 1.72 2004/06/22 14:44:07 ken
-+# Merge nice version of Nate's CryptoAPI patch
-+#
-+# Revision 1.71 2004/04/18 03:04:21 mcr
-+# removed duplicate version.o reference.
-+#
-+# Revision 1.70 2004/04/14 05:09:39 ken
-+# We need to link version.o
-+#
-+# Revision 1.69 2004/04/12 04:02:39 ken
-+# version.o no longer exists
-+#
-+# Revision 1.68 2004/04/11 17:08:41 mcr
-+# moved PASSTHROUGH definitions to openswan.h
-+# requirement for internal.h removed.
-+# version.c is now generated by patch at patch-time.
-+#
-+# Revision 1.67 2004/04/06 02:49:25 mcr
-+# pullup of algo code from alg-branch.
-+#
-+# Revision 1.66 2004/04/03 19:44:41 ken
-+# FREESWANSRCDIR -> OPENSWANSRCDIR (patch by folken)
-+#
-+# Revision 1.65 2004/02/09 16:22:07 paul
-+# Added -f to rm version.c in clean target to prevent bogus error
-+#
-+# Revision 1.64 2003/12/22 19:40:57 mcr
-+# NAT-T patches 0.6c.
-+#
-+# Revision 1.63 2003/12/13 19:10:21 mcr
-+# refactored rcv and xmit code - same as FS 2.05.
-+#
-+# Revision 1.62.4.2 2004/04/05 04:30:46 mcr
-+# patches for alg-branch to compile/work with 2.x openswan
-+#
-+# Revision 1.62.4.1 2003/12/22 15:25:52 jjo
-+# Merged algo-0.8.1-rc11-test1 into alg-branch
-+#
-+# Revision 1.62 2003/10/31 02:27:55 mcr
-+# pulled up port-selector patches and sa_id elimination.
-+#
-+# Revision 1.61.4.1 2003/10/29 01:30:41 mcr
-+# elimited "struct sa_id".
-+#
-+# Revision 1.61 2003/06/22 21:07:46 mcr
-+# adjusted TAGS target in makefile to be useful in 2.00 source layout.
-+#
-+# Revision 1.60 2003/05/03 23:45:23 mcr
-+# rm .o.flags and generated version.c file.
-+#
-+# Revision 1.59 2003/02/12 19:32:47 rgb
-+# Added ipsec_xmit to the list of object files.
-+#
-+# Revision 1.58 2003/01/03 00:36:44 rgb
-+#
-+# Added emacs compile-command.
-+#
-+# Revision 1.57 2002/11/08 23:49:53 mcr
-+# use KERNEL_CFLAGS and MODULE_CFLAGS to get proper list
-+# of include directories.
-+# This also eliminates some of the guesswork in the kernel
-+# configuration file.
-+#
-+# Revision 1.56 2002/11/08 23:23:18 mcr
-+# attempt to guess kernel compilation flags (i.e. list of -I)
-+# by using some magic targets in the kernel makefile.
-+#
-+# Revision 1.55 2002/11/08 10:13:33 mcr
-+# added additional include directories for module builds for 2.4.19.
-+#
-+# Revision 1.54 2002/10/20 06:10:30 build
-+# CONFIG_NOHIGHMEM for -Wpointer-arith RPM building issues.
-+#
-+# (elided rest of log)
-+#
-+# Local Variables:
-+# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
-+# End Variables:
-+#
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/Config.alg_aes.in Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,3 @@
-+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
-+ tristate ' AES encryption algorithm' CONFIG_IPSEC_ALG_AES
-+fi
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/Config.alg_cryptoapi.in Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,6 @@
-+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
-+ dep_tristate ' CRYPTOAPI ciphers support (needs cryptoapi patch)' CONFIG_IPSEC_ALG_CRYPTOAPI $CONFIG_CRYPTO
-+ if [ "$CONFIG_IPSEC_ALG_CRYPTOAPI" != "n" ]; then
-+ bool ' CRYPTOAPI proprietary ciphers ' CONFIG_IPSEC_ALG_NON_LIBRE
-+ fi
-+fi
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/Config.in Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,3 @@
-+#Placeholder
-+source net/ipsec/alg/Config.alg_aes.in
-+source net/ipsec/alg/Config.alg_cryptoapi.in
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/Makefile Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,112 @@
-+# Makefile,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
-+ifeq ($(strip $(KLIPSMODULE)),)
-+FREESWANSRCDIR=.
-+else
-+FREESWANSRCDIR=../../../..
-+endif
-+ifeq ($(strip $(KLIPS_TOP)),)
-+KLIPS_TOP=../../..
-+override EXTRA_CFLAGS += -I$(KLIPS_TOP)/include
-+endif
-+
-+ifeq ($(CONFIG_IPSEC_DEBUG),y)
-+override EXTRA_CFLAGS += -g
-+endif
-+
-+# LIBCRYPTO normally comes as an argument from "parent" Makefile
-+# (this applies both to FS' "make module" and eg. Linux' "make modules"
-+# But make dep doest follow same evaluations, so we need this default:
-+LIBCRYPTO=$(TOPDIR)/lib/libcrypto
-+
-+override EXTRA_CFLAGS += -I$(LIBCRYPTO)/include
-+override EXTRA_CFLAGS += -Wall -Wpointer-arith -Wstrict-prototypes
-+
-+MOD_LIST_NAME := NET_MISC_MODULES
-+
-+#O_TARGET := static_init.o
-+
-+subdir- :=
-+subdir-n :=
-+subdir-y :=
-+subdir-m :=
-+
-+obj-y := static_init.o
-+
-+ARCH_ASM-y :=
-+ARCH_ASM-$(CONFIG_M586) := i586
-+ARCH_ASM-$(CONFIG_M586TSC) := i586
-+ARCH_ASM-$(CONFIG_M586MMX) := i586
-+ARCH_ASM-$(CONFIG_MK6) := i586
-+ARCH_ASM-$(CONFIG_M686) := i686
-+ARCH_ASM-$(CONFIG_MPENTIUMIII) := i686
-+ARCH_ASM-$(CONFIG_MPENTIUM4) := i686
-+ARCH_ASM-$(CONFIG_MK7) := i686
-+ARCH_ASM-$(CONFIG_MCRUSOE) := i586
-+ARCH_ASM-$(CONFIG_MWINCHIPC6) := i586
-+ARCH_ASM-$(CONFIG_MWINCHIP2) := i586
-+ARCH_ASM-$(CONFIG_MWINCHIP3D) := i586
-+ARCH_ASM-$(CONFIG_USERMODE) := i586
-+
-+ARCH_ASM :=$(ARCH_ASM-y)
-+ifdef NO_ASM
-+ARCH_ASM :=
-+endif
-+
-+# The algorithm makefiles may put dependences, short-circuit them
-+null:
-+
-+makefiles=$(filter-out %.preipsec, $(wildcard Makefile.alg_*))
-+ifneq ($(makefiles),)
-+#include Makefile.alg_aes
-+#include Makefile.alg_aes-opt
-+include $(makefiles)
-+endif
-+
-+# These rules translate from new to old makefile rules
-+# Translate to Rules.make lists.
-+multi-used := $(filter $(list-multi), $(obj-y) $(obj-m))
-+multi-objs := $(foreach m, $(multi-used), $($(basename $(m))-objs))
-+active-objs := $(sort $(multi-objs) $(obj-y) $(obj-m))
-+O_OBJS := $(obj-y)
-+M_OBJS := $(obj-m)
-+MIX_OBJS := $(filter $(export-objs), $(active-objs))
-+#OX_OBJS := $(export-objs)
-+SUB_DIRS := $(subdir-y)
-+ALL_SUB_DIRS := $(subdir-y) $(subdir-m)
-+MOD_SUB_DIRS := $(subdir-m)
-+
-+
-+static_init_mod.o: $(obj-y)
-+ rm -f $@
-+ $(LD) $(LD_EXTRAFLAGS) $(obj-y) -r -o $@
-+
-+perlasm: $(LIBCRYPTO)/perlasm
-+ ln -sf $? $@
-+
-+$(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h
-+$(alg_obj-y) $(alg_obj-m): perlasm $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h
-+
-+
-+all_alg_modules: perlasm $(ALG_MODULES)
-+ @echo "ALG_MODULES=$(ALG_MODULES)"
-+
-+
-+#
-+# Construct alg. init. function: call ipsec_ALGO_init() for every static algo
-+# Needed when there are static algos (with static or modular ipsec.o)
-+#
-+static_init.c: $(TOPDIR)/include/linux/autoconf.h Makefile $(makefiles) scripts/mk-static_init.c.sh
-+ @echo "Re-creating $@"
-+ $(SHELL) scripts/mk-static_init.c.sh $(static_init-func-y) > $@
-+
-+clean:
-+ @for i in $(ALG_SUBDIRS);do test -d $$i && make -C $$i clean;done;exit 0
-+ @find . -type l -exec rm -f {} \;
-+ -rm -f perlasm
-+ -rm -rf $(ALG_SUBDIRS)
-+ -rm -f *.o static_init.c
-+
-+ifdef TOPDIR
-+include $(TOPDIR)/Rules.make
-+endif
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/Makefile.alg_aes Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,23 @@
-+MOD_AES := ipsec_aes.o
-+
-+ALG_MODULES += $(MOD_AES)
-+ALG_SUBDIRS += libaes
-+
-+obj-$(CONFIG_IPSEC_ALG_AES) += $(MOD_AES)
-+static_init-func-$(CONFIG_IPSEC_ALG_AES)+= ipsec_aes_init
-+alg_obj-$(CONFIG_IPSEC_ALG_AES) += ipsec_alg_aes.o
-+
-+AES_OBJS := ipsec_alg_aes.o libaes/libaes.a
-+
-+$(MOD_AES): libaes $(AES_OBJS)
-+ $(LD) $(EXTRA_LDFLAGS) -r $(AES_OBJS) -o $@
-+
-+libaes: $(LIBCRYPTO)/libaes
-+ test -d $@ || mkdir $@ ;exit 0
-+ test -d $@/asm || mkdir $@/asm;exit 0
-+ cd $@ && ln -sf $?/Makefile $?/*.[chS] .
-+ cd $@/asm && ln -sf $?/asm/*.S .
-+
-+libaes/libaes.a: libaes
-+ ( cd libaes && \
-+ $(MAKE) CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' libaes.a ;)
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/Makefile.alg_cryptoapi Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,14 @@
-+MOD_CRYPTOAPI := ipsec_cryptoapi.o
-+
-+ifneq ($(wildcard $(TOPDIR)/include/linux/crypto.h),)
-+ALG_MODULES += $(MOD_CRYPTOAPI)
-+obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += $(MOD_CRYPTOAPI)
-+static_init-func-$(CONFIG_IPSEC_ALG_CRYPTOAPI)+= ipsec_cryptoapi_init
-+alg_obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += ipsec_alg_cryptoapi.o
-+else
-+$(warning "Linux CryptoAPI (2.4.22+ or 2.6.x) not found, not building ipsec_cryptoapi.o")
-+endif
-+
-+CRYPTOAPI_OBJS := ipsec_alg_cryptoapi.o
-+$(MOD_CRYPTOAPI): $(CRYPTOAPI_OBJS)
-+ $(LD) -r $(CRYPTOAPI_OBJS) -o $@
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/ipsec_alg_aes.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,253 @@
-+/*
-+ * ipsec_alg AES cipher stubs
-+ *
-+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
-+ *
-+ * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * Fixes by:
-+ * PK: Pawel Krawczyk <kravietz@aba.krakow.pl>
-+ * Fixes list:
-+ * PK: make XCBC comply with latest draft (keylength)
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+/*
-+ * special case: ipsec core modular with this static algo inside:
-+ * must avoid MODULE magic for this file
-+ */
-+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_AES
-+#undef MODULE
-+#endif
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+
-+#include <linux/kernel.h> /* printk() */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/string.h>
-+
-+/* Check if __exit is defined, if not null it */
-+#ifndef __exit
-+#define __exit
-+#endif
-+
-+/* Low freeswan header coupling */
-+#include "freeswan/ipsec_alg.h"
-+#include "libaes/aes_cbc.h"
-+
-+#define CONFIG_IPSEC_ALG_AES_MAC 1
-+
-+#define AES_CONTEXT_T aes_context
-+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
-+static int debug=0;
-+MODULE_PARM(debug, "i");
-+static int test=0;
-+MODULE_PARM(test, "i");
-+static int excl=0;
-+MODULE_PARM(excl, "i");
-+static int keyminbits=0;
-+MODULE_PARM(keyminbits, "i");
-+static int keymaxbits=0;
-+MODULE_PARM(keymaxbits, "i");
-+
-+#if CONFIG_IPSEC_ALG_AES_MAC
-+#include "libaes/aes_xcbc_mac.h"
-+
-+/*
-+ * Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt).
-+ * We use 9 for non-modular algorithm and none for modular, thus
-+ * forcing user to specify one on module load. -kravietz
-+ */
-+#ifdef MODULE
-+static int auth_id=0;
-+#else
-+static int auth_id=9;
-+#endif
-+MODULE_PARM(auth_id, "i");
-+#endif
-+
-+#define ESP_AES 12 /* truely _constant_ :) */
-+
-+/* 128, 192 or 256 */
-+#define ESP_AES_KEY_SZ_MIN 16 /* 128 bit secret key */
-+#define ESP_AES_KEY_SZ_MAX 32 /* 256 bit secret key */
-+#define ESP_AES_CBC_BLK_LEN 16 /* AES-CBC block size */
-+
-+/* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt
-+ * -kravietz
-+ */
-+#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
-+#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
-+
-+static int _aes_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) {
-+ int ret;
-+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
-+ ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL;
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:_aes_set_key:"
-+ "ret=%d key_e=%p key=%p keysize=%d\n",
-+ ret, key_e, key, keysize);
-+ return ret;
-+}
-+static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
-+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
-+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
-+ key_e, in, ilen, iv, encrypt);
-+ return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt);
-+}
-+#if CONFIG_IPSEC_ALG_AES_MAC
-+static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) {
-+ aes_context_mac *ctxm=(aes_context_mac *)key_a;
-+ return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL;
-+}
-+static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) {
-+ int ret;
-+ char hash_buf[16];
-+ aes_context_mac *ctxm=(aes_context_mac *)key_a;
-+ ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf);
-+ memcpy(hash, hash_buf, hashlen);
-+ return ret;
-+}
-+static struct ipsec_alg_auth ipsec_alg_AES_MAC = {
-+ ixt_version: IPSEC_ALG_VERSION,
-+ ixt_module: THIS_MODULE,
-+ ixt_refcnt: ATOMIC_INIT(0),
-+ ixt_alg_type: IPSEC_ALG_TYPE_AUTH,
-+ ixt_alg_id: 0,
-+ ixt_name: "aes_mac",
-+ ixt_blocksize: ESP_AES_MAC_BLK_LEN,
-+ ixt_keyminbits: ESP_AES_MAC_KEY_SZ*8,
-+ ixt_keymaxbits: ESP_AES_MAC_KEY_SZ*8,
-+ ixt_a_keylen: ESP_AES_MAC_KEY_SZ,
-+ ixt_a_ctx_size: sizeof(aes_context_mac),
-+ ixt_a_hmac_set_key: _aes_mac_set_key,
-+ ixt_a_hmac_hash:_aes_mac_hash,
-+};
-+#endif /* CONFIG_IPSEC_ALG_AES_MAC */
-+static struct ipsec_alg_enc ipsec_alg_AES = {
-+ ixt_version: IPSEC_ALG_VERSION,
-+ ixt_module: THIS_MODULE,
-+ ixt_refcnt: ATOMIC_INIT(0),
-+ ixt_alg_type: IPSEC_ALG_TYPE_ENCRYPT,
-+ ixt_alg_id: ESP_AES,
-+ ixt_name: "aes",
-+ ixt_blocksize: ESP_AES_CBC_BLK_LEN,
-+ ixt_keyminbits: ESP_AES_KEY_SZ_MIN*8,
-+ ixt_keymaxbits: ESP_AES_KEY_SZ_MAX*8,
-+ ixt_e_keylen: ESP_AES_KEY_SZ_MAX,
-+ ixt_e_ctx_size: sizeof(AES_CONTEXT_T),
-+ ixt_e_set_key: _aes_set_key,
-+ ixt_e_cbc_encrypt:_aes_cbc_encrypt,
-+};
-+
-+IPSEC_ALG_MODULE_INIT( ipsec_aes_init )
-+{
-+ int ret, test_ret;
-+ if (keyminbits)
-+ ipsec_alg_AES.ixt_keyminbits=keyminbits;
-+ if (keymaxbits) {
-+ ipsec_alg_AES.ixt_keymaxbits=keymaxbits;
-+ if (keymaxbits*8>ipsec_alg_AES.ixt_keymaxbits)
-+ ipsec_alg_AES.ixt_e_keylen=keymaxbits*8;
-+ }
-+ if (excl) ipsec_alg_AES.ixt_state |= IPSEC_ALG_ST_EXCL;
-+ ret=register_ipsec_alg_enc(&ipsec_alg_AES);
-+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
-+ ipsec_alg_AES.ixt_alg_type,
-+ ipsec_alg_AES.ixt_alg_id,
-+ ipsec_alg_AES.ixt_name,
-+ ret);
-+ if (ret==0 && test) {
-+ test_ret=ipsec_alg_test(
-+ ipsec_alg_AES.ixt_alg_type,
-+ ipsec_alg_AES.ixt_alg_id,
-+ test);
-+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
-+ ipsec_alg_AES.ixt_alg_type,
-+ ipsec_alg_AES.ixt_alg_id,
-+ test_ret);
-+ }
-+#if CONFIG_IPSEC_ALG_AES_MAC
-+ if (auth_id!=0){
-+ int ret;
-+ ipsec_alg_AES_MAC.ixt_alg_id=auth_id;
-+ ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC);
-+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
-+ ipsec_alg_AES_MAC.ixt_alg_type,
-+ ipsec_alg_AES_MAC.ixt_alg_id,
-+ ipsec_alg_AES_MAC.ixt_name,
-+ ret);
-+ if (ret==0 && test) {
-+ test_ret=ipsec_alg_test(
-+ ipsec_alg_AES_MAC.ixt_alg_type,
-+ ipsec_alg_AES_MAC.ixt_alg_id,
-+ test);
-+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
-+ ipsec_alg_AES_MAC.ixt_alg_type,
-+ ipsec_alg_AES_MAC.ixt_alg_id,
-+ test_ret);
-+ }
-+ } else {
-+ printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id);
-+ }
-+#endif /* CONFIG_IPSEC_ALG_AES_MAC */
-+ return ret;
-+}
-+IPSEC_ALG_MODULE_EXIT( ipsec_aes_fini )
-+{
-+#if CONFIG_IPSEC_ALG_AES_MAC
-+ if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC);
-+#endif /* CONFIG_IPSEC_ALG_AES_MAC */
-+ unregister_ipsec_alg_enc(&ipsec_alg_AES);
-+ return;
-+}
-+#ifdef MODULE_LICENSE
-+MODULE_LICENSE("GPL");
-+#endif
-+
-+#if 0+NOT_YET
-+#ifndef MODULE
-+/*
-+ * This is intended for static module setups, currently
-+ * doesn't work for modular ipsec.o with static algos inside
-+ */
-+static int setup_keybits(const char *str)
-+{
-+ unsigned aux;
-+ char *end;
-+
-+ aux = simple_strtoul(str,&end,0);
-+ if (aux != 128 && aux != 192 && aux != 256)
-+ return 0;
-+ keyminbits = aux;
-+
-+ if (*end == 0 || *end != ',')
-+ return 1;
-+ str=end+1;
-+ aux = simple_strtoul(str, NULL, 0);
-+ if (aux != 128 && aux != 192 && aux != 256)
-+ return 0;
-+ if (aux >= keyminbits)
-+ keymaxbits = aux;
-+ return 1;
-+}
-+__setup("ipsec_aes_keybits=", setup_keybits);
-+#endif
-+#endif
-+EXPORT_NO_SYMBOLS;
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,421 @@
-+/*
-+ * ipsec_alg to linux cryptoapi GLUE
-+ *
-+ * Authors: CODE.ar TEAM
-+ * Harpo MAxx <harpo@linuxmendoza.org.ar>
-+ * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
-+ * Luciano Ruete <docemeses@softhome.net>
-+ *
-+ * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * Example usage:
-+ * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
-+ * modprobe ipsec_cryptoapi
-+ * modprobe ipsec_cryptoapi test=1
-+ * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
-+ * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
-+ * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
-+ * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
-+ */
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+/*
-+ * special case: ipsec core modular with this static algo inside:
-+ * must avoid MODULE magic for this file
-+ */
-+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI
-+#undef MODULE
-+#endif
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+
-+#include <linux/kernel.h> /* printk() */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/string.h>
-+
-+/* Check if __exit is defined, if not null it */
-+#ifndef __exit
-+#define __exit
-+#endif
-+
-+/* warn the innocent */
-+#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
-+#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"
-+#define NO_CRYPTOAPI_SUPPORT
-+#endif
-+/* Low freeswan header coupling */
-+#include "freeswan/ipsec_alg.h"
-+
-+#include <linux/crypto.h>
-+#ifdef CRYPTO_API_VERSION_CODE
-+#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
-+#define NO_CRYPTOAPI_SUPPORT
-+#endif
-+
-+#ifdef NO_CRYPTOAPI_SUPPORT
-+#warning "Building an unusable module :P"
-+/* Catch old CryptoAPI by not allowing module to load */
-+IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
-+{
-+ printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
-+ return -EINVAL;
-+}
-+#else
-+#include <asm/scatterlist.h>
-+#include <asm/pgtable.h>
-+#include <linux/mm.h>
-+
-+#define CIPHERNAME_AES "aes"
-+#define CIPHERNAME_3DES "des3_ede"
-+#define CIPHERNAME_BLOWFISH "blowfish"
-+#define CIPHERNAME_CAST "cast5"
-+#define CIPHERNAME_SERPENT "serpent"
-+#define CIPHERNAME_TWOFISH "twofish"
-+
-+#define ESP_3DES 3
-+#define ESP_AES 12
-+#define ESP_BLOWFISH 7 /* truely _constant_ :) */
-+#define ESP_CAST 6 /* quite constant :) */
-+#define ESP_SERPENT 252 /* from ipsec drafts */
-+#define ESP_TWOFISH 253 /* from ipsec drafts */
-+
-+#define AH_MD5 2
-+#define AH_SHA 3
-+#define DIGESTNAME_MD5 "md5"
-+#define DIGESTNAME_SHA1 "sha1"
-+
-+MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
-+static int debug=0;
-+MODULE_PARM(debug, "i");
-+static int test=0;
-+MODULE_PARM(test, "i");
-+static int excl=0;
-+MODULE_PARM(excl, "i");
-+
-+static int noauto = 0;
-+MODULE_PARM(noauto,"i");
-+MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
-+
-+static int des_ede3[] = {-1, -1};
-+static int aes[] = {-1, -1};
-+static int blowfish[] = {-1, -1};
-+static int cast[] = {-1, -1};
-+static int serpent[] = {-1, -1};
-+static int twofish[] = {-1, -1};
-+
-+MODULE_PARM(des_ede3,"1-2i");
-+MODULE_PARM(aes,"1-2i");
-+MODULE_PARM(blowfish,"1-2i");
-+MODULE_PARM(cast,"1-2i");
-+MODULE_PARM(serpent,"1-2i");
-+MODULE_PARM(twofish,"1-2i");
-+MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
-+MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
-+MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
-+MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
-+MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
-+MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
-+
-+struct ipsec_alg_capi_cipher {
-+ const char *ciphername; /* cryptoapi's ciphername */
-+ unsigned blocksize;
-+ unsigned short minbits;
-+ unsigned short maxbits;
-+ int *parm; /* lkm param for this cipher */
-+ struct ipsec_alg_enc alg; /* note it's not a pointer */
-+};
-+static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
-+ { CIPHERNAME_AES , 16, 128, 256, aes , { ixt_alg_id: ESP_AES, }},
-+ { CIPHERNAME_TWOFISH , 16, 128, 256, twofish, { ixt_alg_id: ESP_TWOFISH, }},
-+ { CIPHERNAME_SERPENT , 16, 128, 256, serpent, { ixt_alg_id: ESP_SERPENT, }},
-+ { CIPHERNAME_CAST , 8, 128, 128, cast , { ixt_alg_id: ESP_CAST, }},
-+ { CIPHERNAME_BLOWFISH , 8, 96, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }},
-+ { CIPHERNAME_3DES , 8, 192, 192, des_ede3,{ ixt_alg_id: ESP_3DES, }},
-+ { NULL, 0, 0, 0, NULL, {} }
-+};
-+#ifdef NOT_YET
-+struct ipsec_alg_capi_digest {
-+ const char *digestname; /* cryptoapi's digestname */
-+ struct digest_implementation *di;
-+ struct ipsec_alg_auth alg; /* note it's not a pointer */
-+};
-+static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
-+ { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
-+ { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
-+ { NULL, NULL, {} }
-+};
-+#endif
-+/*
-+ * "generic" linux cryptoapi setup_cipher() function
-+ */
-+int setup_cipher(const char *ciphername)
-+{
-+ return crypto_alg_available(ciphername, 0);
-+}
-+
-+/*
-+ * setups ipsec_alg_capi_cipher "hyper" struct components, calling
-+ * register_ipsec_alg for cointaned ipsec_alg object
-+ */
-+static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
-+static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
-+static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
-+
-+static int
-+setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
-+{
-+ int ret;
-+ cptr->alg.ixt_version = IPSEC_ALG_VERSION;
-+ cptr->alg.ixt_module = THIS_MODULE;
-+ atomic_set (& cptr->alg.ixt_refcnt, 0);
-+ strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name));
-+
-+ cptr->alg.ixt_blocksize=cptr->blocksize;
-+ cptr->alg.ixt_keyminbits=cptr->minbits;
-+ cptr->alg.ixt_keymaxbits=cptr->maxbits;
-+ cptr->alg.ixt_state = 0;
-+ if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL;
-+ cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8;
-+ cptr->alg.ixt_e_ctx_size = 0;
-+ cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT;
-+ cptr->alg.ixt_e_new_key = _capi_new_key;
-+ cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
-+ cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
-+ cptr->alg.ixt_data = cptr;
-+
-+ ret=register_ipsec_alg_enc(&cptr->alg);
-+ printk("setup_ipsec_alg_capi_cipher(): "
-+ "alg_type=%d alg_id=%d name=%s "
-+ "keyminbits=%d keymaxbits=%d, ret=%d\n",
-+ cptr->alg.ixt_alg_type,
-+ cptr->alg.ixt_alg_id,
-+ cptr->alg.ixt_name,
-+ cptr->alg.ixt_keyminbits,
-+ cptr->alg.ixt_keymaxbits,
-+ ret);
-+ return ret;
-+}
-+/*
-+ * called in ipsec_sa_wipe() time, will destroy key contexts
-+ * and do 1 unbind()
-+ */
-+static void
-+_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
-+{
-+ struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
-+
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
-+ "name=%s key_e=%p \n",
-+ alg->ixt_name, key_e);
-+ if (!key_e) {
-+ printk(KERN_ERR "klips_debug: _capi_destroy_key:"
-+ "name=%s NULL key_e!\n",
-+ alg->ixt_name);
-+ return;
-+ }
-+ crypto_free_tfm(tfm);
-+}
-+
-+/*
-+ * create new key context, need alg->ixt_data to know which
-+ * (of many) cipher inside this module is the target
-+ */
-+static __u8 *
-+_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
-+{
-+ struct ipsec_alg_capi_cipher *cptr;
-+ struct crypto_tfm *tfm=NULL;
-+
-+ cptr = alg->ixt_data;
-+ if (!cptr) {
-+ printk(KERN_ERR "_capi_new_key(): "
-+ "NULL ixt_data (?!) for \"%s\" algo\n"
-+ , alg->ixt_name);
-+ goto err;
-+ }
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
-+ "name=%s cptr=%p key=%p keysize=%d\n",
-+ alg->ixt_name, cptr, key, keylen);
-+
-+ /*
-+ * alloc tfm
-+ */
-+ tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);
-+ if (!tfm) {
-+ printk(KERN_ERR "_capi_new_key(): "
-+ "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
-+ , alg->ixt_name, cptr->ciphername);
-+ goto err;
-+ }
-+ if (crypto_cipher_setkey(tfm, key, keylen) < 0) {
-+ printk(KERN_ERR "_capi_new_key(): "
-+ "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
-+ , alg->ixt_name, keylen);
-+ crypto_free_tfm(tfm);
-+ tfm=NULL;
-+ }
-+err:
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
-+ "name=%s key=%p keylen=%d tfm=%p\n",
-+ alg->ixt_name, key, keylen, tfm);
-+ return (__u8 *) tfm;
-+}
-+/*
-+ * core encryption function: will use cx->ci to call actual cipher's
-+ * cbc function
-+ */
-+static int
-+_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
-+ int error =0;
-+ struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
-+ struct scatterlist sg = {
-+ .page = virt_to_page(in),
-+ .offset = (unsigned long)(in) % PAGE_SIZE,
-+ .length=ilen,
-+ };
-+ if (debug > 1)
-+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
-+ "key_e=%p "
-+ "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
-+ , key_e
-+ , in, in, ilen, iv, encrypt);
-+ crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));
-+ if (encrypt)
-+ error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);
-+ else
-+ error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);
-+ if (debug > 1)
-+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
-+ "error=%d\n"
-+ , error);
-+ return (error<0)? error : ilen;
-+}
-+/*
-+ * main initialization loop: for each cipher in list, do
-+ * 1) setup cryptoapi cipher else continue
-+ * 2) register ipsec_alg object
-+ */
-+static int
-+setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
-+{
-+ struct ipsec_alg_capi_cipher *cptr;
-+ /* foreach cipher in list ... */
-+ for (cptr=clist;cptr->ciphername;cptr++) {
-+ /*
-+ * see if cipher has been disabled (0) or
-+ * if noauto set and not enabled (1)
-+ */
-+ if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
-+ if (debug>0)
-+ printk(KERN_INFO "setup_cipher_list(): "
-+ "ciphername=%s skipped at user request: "
-+ "noauto=%d parm[0]=%d parm[1]=%d\n"
-+ , cptr->ciphername
-+ , noauto
-+ , cptr->parm[0]
-+ , cptr->parm[1]);
-+ continue;
-+ }
-+ /*
-+ * use a local ci to avoid touching cptr->ci,
-+ * if register ipsec_alg success then bind cipher
-+ */
-+ if( setup_cipher(cptr->ciphername) ) {
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:"
-+ "setup_cipher_list():"
-+ "ciphername=%s found\n"
-+ , cptr->ciphername);
-+ if (setup_ipsec_alg_capi_cipher(cptr) == 0) {
-+
-+
-+ } else {
-+ printk(KERN_ERR "klips_debug:"
-+ "setup_cipher_list():"
-+ "ciphername=%s failed ipsec_alg_register\n"
-+ , cptr->ciphername);
-+ }
-+ } else {
-+ if (debug>0)
-+ printk(KERN_INFO "setup_cipher_list(): lookup for ciphername=%s: not found \n",
-+ cptr->ciphername);
-+ }
-+ }
-+ return 0;
-+}
-+/*
-+ * deregister ipsec_alg objects and unbind ciphers
-+ */
-+static int
-+unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
-+{
-+ struct ipsec_alg_capi_cipher *cptr;
-+ /* foreach cipher in list ... */
-+ for (cptr=clist;cptr->ciphername;cptr++) {
-+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
-+ unregister_ipsec_alg_enc(&cptr->alg);
-+ }
-+ }
-+ return 0;
-+}
-+/*
-+ * test loop for registered algos
-+ */
-+static int
-+test_cipher_list (struct ipsec_alg_capi_cipher* clist)
-+{
-+ int test_ret;
-+ struct ipsec_alg_capi_cipher *cptr;
-+ /* foreach cipher in list ... */
-+ for (cptr=clist;cptr->ciphername;cptr++) {
-+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
-+ test_ret=ipsec_alg_test(
-+ cptr->alg.ixt_alg_type,
-+ cptr->alg.ixt_alg_id,
-+ test);
-+ printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
-+ cptr->alg.ixt_alg_type,
-+ cptr->alg.ixt_alg_id,
-+ test_ret);
-+ }
-+ }
-+ return 0;
-+}
-+
-+IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
-+{
-+ int ret, test_ret;
-+ if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
-+ return -EPROTONOSUPPORT;
-+ if (ret==0 && test) {
-+ test_ret=test_cipher_list(alg_capi_carray);
-+ }
-+ return ret;
-+}
-+IPSEC_ALG_MODULE_EXIT( ipsec_cryptoapi_fini )
-+{
-+ unsetup_cipher_list(alg_capi_carray);
-+ return;
-+}
-+#ifdef MODULE_LICENSE
-+MODULE_LICENSE("GPL");
-+#endif
-+
-+EXPORT_NO_SYMBOLS;
-+#endif /* NO_CRYPTOAPI_SUPPORT */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/scripts/mk-static_init.c.sh Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,18 @@
-+#!/bin/sh
-+cat << EOF
-+#include <linux/kernel.h>
-+#include <linux/list.h>
-+#include "freeswan/ipsec_alg.h"
-+$(for i in $*; do
-+ test -z "$i" && continue
-+ echo "extern int $i(void);"
-+done)
-+void ipsec_alg_static_init(void){
-+ int __attribute__ ((unused)) err=0;
-+$(for i in $*; do
-+ test -z "$i" && continue
-+ echo " if ((err=$i()) < 0)"
-+ echo " printk(KERN_WARNING \"$i() returned %d\", err);"
-+done)
-+}
-+EOF
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/defconfig Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,146 @@
-+
-+#
-+# RCSID $Id$
-+#
-+
-+#
-+# FreeS/WAN IPSec implementation, KLIPS kernel config defaults
-+#
-+
-+#
-+# First, lets override stuff already set or not in the kernel config.
-+#
-+# We can't even think about leaving this off...
-+CONFIG_INET=y
-+
-+#
-+# This must be on for subnet protection.
-+CONFIG_IP_FORWARD=y
-+
-+# Shut off IPSEC masquerading if it has been enabled, since it will
-+# break the compile. IPPROTO_ESP and IPPROTO_AH were included in
-+# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h.
-+CONFIG_IP_MASQUERADE_IPSEC=n
-+
-+#
-+# Next, lets set the recommended FreeS/WAN configuration.
-+#
-+
-+# To config as static (preferred), 'y'. To config as module, 'm'.
-+CONFIG_IPSEC=y
-+
-+# To do tunnel mode IPSec, this must be enabled.
-+CONFIG_IPSEC_IPIP=y
-+
-+# To enable authentication, say 'y'. (Highly recommended)
-+CONFIG_IPSEC_AH=y
-+
-+# Authentication algorithm(s):
-+CONFIG_IPSEC_AUTH_HMAC_MD5=y
-+CONFIG_IPSEC_AUTH_HMAC_SHA1=y
-+
-+# To enable encryption, say 'y'. (Highly recommended)
-+CONFIG_IPSEC_ESP=y
-+
-+# Encryption algorithm(s):
-+CONFIG_IPSEC_ENC_3DES=y
-+CONFIG_IPSEC_ENC_AES=y
-+
-+# modular algo extensions (and new ALGOs)
-+CONFIG_IPSEC_ALG=y
-+CONFIG_IPSEC_ENC_3DES=y
-+CONFIG_IPSEC_ENC_AES=y
-+
-+CONFIG_IPSEC_ALG_TWOFISH=m
-+CONFIG_IPSEC_ALG_BLOWFISH=m
-+CONFIG_IPSEC_ALG_SERPENT=m
-+CONFIG_IPSEC_ALG_MD5=m
-+CONFIG_IPSEC_ALG_SHA1=m
-+CONFIG_IPSEC_ALG_SHA2=m
-+#CONFIG_IPSEC_ALG_CAST=n
-+#CONFIG_IPSEC_ALG_NULL=n
-+
-+# Use CryptoAPI for ALG? - by default, no.
-+CONFIG_IPSEC_ENC_CRYPTOAPI=n
-+
-+
-+# IP Compression: new, probably still has minor bugs.
-+CONFIG_IPSEC_IPCOMP=y
-+
-+# To enable userspace-switchable KLIPS debugging, say 'y'.
-+CONFIG_IPSEC_DEBUG=y
-+
-+# NAT Traversal
-+CONFIG_IPSEC_NAT_TRAVERSAL=y
-+
-+#
-+#
-+# $Log$
-+# Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+# Turn off EOLN_NATIVE flag
-+#
-+# (Logical change 1.5010)
-+#
-+# Revision 1.25 2004/07/05 01:03:53 mcr
-+# fix for adding cryptoapi code.
-+# keep it off for now, since UMLs do not have it yet.
-+#
-+# Revision 1.24 2004/04/06 02:49:25 mcr
-+# pullup of algo code from alg-branch.
-+#
-+# Revision 1.23.2.2 2004/04/05 04:30:46 mcr
-+# patches for alg-branch to compile/work with 2.x openswan
-+#
-+# Revision 1.23.2.1 2003/12/22 15:25:52 jjo
-+# . Merged algo-0.8.1-rc11-test1 into alg-branch
-+#
-+# Revision 1.23 2003/12/10 01:14:27 mcr
-+# NAT-traversal patches to KLIPS.
-+#
-+# Revision 1.22 2003/02/24 19:37:27 mcr
-+# changed default compilation mode to static.
-+#
-+# Revision 1.21 2002/04/24 07:36:27 mcr
-+# Moved from ./klips/net/ipsec/defconfig,v
-+#
-+# Revision 1.20 2002/04/02 04:07:40 mcr
-+# default build is now 'm'odule for KLIPS
-+#
-+# Revision 1.19 2002/03/08 18:57:17 rgb
-+# Added a blank line at the beginning of the file to make it easier for
-+# other projects to patch ./arch/i386/defconfig, for example
-+# LIDS+grSecurity requested by Jason Pattie.
-+#
-+# Revision 1.18 2000/11/30 17:26:56 rgb
-+# Cleaned out unused options and enabled ipcomp by default.
-+#
-+# Revision 1.17 2000/09/15 11:37:01 rgb
-+# Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
-+# IPCOMP zlib deflate code.
-+#
-+# Revision 1.16 2000/09/08 19:12:55 rgb
-+# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+#
-+# Revision 1.15 2000/05/24 19:37:13 rgb
-+# *** empty log message ***
-+#
-+# Revision 1.14 2000/05/11 21:14:57 henry
-+# just commenting the FOOBAR=y lines out is not enough
-+#
-+# Revision 1.13 2000/05/10 20:17:58 rgb
-+# Comment out netlink defaults, which are no longer needed.
-+#
-+# Revision 1.12 2000/05/10 19:13:38 rgb
-+# Added configure option to shut off no eroute passthrough.
-+#
-+# Revision 1.11 2000/03/16 07:09:46 rgb
-+# Hardcode PF_KEYv2 support.
-+# Disable IPSEC_ICMP by default.
-+# Remove DES config option from defaults file.
-+#
-+# Revision 1.10 2000/01/11 03:09:42 rgb
-+# Added a default of 'y' to PF_KEYv2 keying I/F.
-+#
-+# Revision 1.9 1999/05/08 21:23:12 rgb
-+# Added support for 2.2.x kernels.
-+#
-+# Revision 1.8 1999/04/06 04:54:25 rgb
-+# Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+# patch shell fixes.
-+#
-+#
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipcomp.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,725 @@
-+/*
-+ * IPCOMP zlib interface code.
-+ * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
-+ * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipcomp_c_version[] = "RCSID $Id$";
-+
-+/* SSS */
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h>
-+#include <linux/netdevice.h>
-+#include <linux/ip.h>
-+#include <linux/skbuff.h>
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+
-+#include <openswan.h>
-+
-+#ifdef NET_21
-+# include <net/dst.h>
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define proto_priv cb
-+#endif /* NET21 */
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */
-+#include "openswan/ipcomp.h"
-+#include "zlib/zlib.h"
-+#include "zlib/zutil.h"
-+
-+#include <pfkeyv2.h> /* SADB_X_CALG_DEFLATE */
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int sysctl_ipsec_debug_ipcomp = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+static
-+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask);
-+
-+static
-+voidpf my_zcalloc(voidpf opaque, uInt items, uInt size)
-+{
-+ return (voidpf) kmalloc(items*size, GFP_ATOMIC);
-+}
-+
-+static
-+void my_zfree(voidpf opaque, voidpf address)
-+{
-+ kfree(address);
-+}
-+
-+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
-+{
-+ struct iphdr *iph;
-+ unsigned int iphlen, pyldsz, cpyldsz;
-+ unsigned char *buffer;
-+ z_stream zs;
-+ int zresult;
-+
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: .\n");
-+
-+ if(skb == NULL) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "passed in NULL skb, returning ERROR.\n");
-+ if(flags != NULL) {
-+ *flags |= IPCOMP_PARMERROR;
-+ }
-+ return skb;
-+ }
-+
-+ if(ips == NULL) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "passed in NULL ipsec_sa needed for cpi, returning ERROR.\n");
-+ if(flags) {
-+ *flags |= IPCOMP_PARMERROR;
-+ }
-+ return skb;
-+ }
-+
-+ if (flags == NULL) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "passed in NULL flags, returning ERROR.\n");
-+ ipsec_kfree_skb(skb);
-+ return NULL;
-+ }
-+
-+#ifdef NET_21
-+ iph = skb->nh.iph;
-+#else /* NET_21 */
-+ iph = skb->ip_hdr;
-+#endif /* NET_21 */
-+
-+ switch (iph->protocol) {
-+ case IPPROTO_COMP:
-+ case IPPROTO_AH:
-+ case IPPROTO_ESP:
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "skipping compression of packet with ip protocol %d.\n",
-+ iph->protocol);
-+ *flags |= IPCOMP_UNCOMPRESSABLE;
-+ return skb;
-+ }
-+
-+ /* Don't compress packets already fragmented */
-+ if (iph->frag_off & __constant_htons(IP_MF | IP_OFFSET)) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "skipping compression of fragmented packet.\n");
-+ *flags |= IPCOMP_UNCOMPRESSABLE;
-+ return skb;
-+ }
-+
-+ iphlen = iph->ihl << 2;
-+ pyldsz = ntohs(iph->tot_len) - iphlen;
-+
-+ /* Don't compress less than 90 bytes (rfc 2394) */
-+ if (pyldsz < 90) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "skipping compression of tiny packet, len=%d.\n",
-+ pyldsz);
-+ *flags |= IPCOMP_UNCOMPRESSABLE;
-+ return skb;
-+ }
-+
-+ /* Adaptive decision */
-+ if (ips->ips_comp_adapt_skip) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "skipping compression: ips_comp_adapt_skip=%d.\n",
-+ ips->ips_comp_adapt_skip);
-+ ips->ips_comp_adapt_skip--;
-+ *flags |= IPCOMP_UNCOMPRESSABLE;
-+ return skb;
-+ }
-+
-+ zs.zalloc = my_zcalloc;
-+ zs.zfree = my_zfree;
-+ zs.opaque = 0;
-+
-+ /* We want to use deflateInit2 because we don't want the adler
-+ header. */
-+ zresult = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -11,
-+ DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
-+ if (zresult != Z_OK) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_compress: "
-+ "deflateInit2() returned error %d (%s), "
-+ "skipping compression.\n",
-+ zresult,
-+ zs.msg ? zs.msg : zError(zresult));
-+ *flags |= IPCOMP_COMPRESSIONERROR;
-+ return skb;
-+ }
-+
-+
-+ /* Max output size. Result should be max this size.
-+ * Implementation specific tweak:
-+ * If it's not at least 32 bytes and 6.25% smaller than
-+ * the original packet, it's probably not worth wasting
-+ * the receiver's CPU cycles decompressing it.
-+ * Your mileage may vary.
-+ */
-+ cpyldsz = pyldsz - sizeof(struct ipcomphdr) - (pyldsz <= 512 ? 32 : pyldsz >> 4);
-+
-+ buffer = kmalloc(cpyldsz, GFP_ATOMIC);
-+ if (!buffer) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_compress: "
-+ "unable to kmalloc(%d, GFP_ATOMIC), "
-+ "skipping compression.\n",
-+ cpyldsz);
-+ *flags |= IPCOMP_COMPRESSIONERROR;
-+ deflateEnd(&zs);
-+ return skb;
-+ }
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
-+ __u8 *c;
-+ int i;
-+
-+ c = (__u8*)iph + iphlen;
-+ for(i = 0; i < pyldsz; i++, c++) {
-+ if(!(i % 16)) {
-+ printk(KERN_INFO "skb_compress: before:");
-+ }
-+ printk("%02x ", *c);
-+ if(!((i + 1) % 16)) {
-+ printk("\n");
-+ }
-+ }
-+ if(i % 16) {
-+ printk("\n");
-+ }
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ zs.next_in = (char *) iph + iphlen; /* start of payload */
-+ zs.avail_in = pyldsz;
-+ zs.next_out = buffer; /* start of compressed payload */
-+ zs.avail_out = cpyldsz;
-+
-+ /* Finish compression in one step */
-+ zresult = deflate(&zs, Z_FINISH);
-+
-+ /* Free all dynamically allocated buffers */
-+ deflateEnd(&zs);
-+ if (zresult != Z_STREAM_END) {
-+ *flags |= IPCOMP_UNCOMPRESSABLE;
-+ kfree(buffer);
-+
-+ /* Adjust adaptive counters */
-+ if (++(ips->ips_comp_adapt_tries) == IPCOMP_ADAPT_INITIAL_TRIES) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "first %d packets didn't compress, "
-+ "skipping next %d\n",
-+ IPCOMP_ADAPT_INITIAL_TRIES,
-+ IPCOMP_ADAPT_INITIAL_SKIP);
-+ ips->ips_comp_adapt_skip = IPCOMP_ADAPT_INITIAL_SKIP;
-+ }
-+ else if (ips->ips_comp_adapt_tries == IPCOMP_ADAPT_INITIAL_TRIES + IPCOMP_ADAPT_SUBSEQ_TRIES) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "next %d packets didn't compress, "
-+ "skipping next %d\n",
-+ IPCOMP_ADAPT_SUBSEQ_TRIES,
-+ IPCOMP_ADAPT_SUBSEQ_SKIP);
-+ ips->ips_comp_adapt_skip = IPCOMP_ADAPT_SUBSEQ_SKIP;
-+ ips->ips_comp_adapt_tries = IPCOMP_ADAPT_INITIAL_TRIES;
-+ }
-+
-+ return skb;
-+ }
-+
-+ /* resulting compressed size */
-+ cpyldsz -= zs.avail_out;
-+
-+ /* Insert IPCOMP header */
-+ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_nh = iph->protocol;
-+ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_flags = 0;
-+ /* use the bottom 16 bits of the spi for the cpi. The top 16 bits are
-+ for internal reference only. */
-+ ((struct ipcomphdr*) (((char*)iph) + iphlen))->ipcomp_cpi = htons((__u16)(ntohl(ips->ips_said.spi) & 0x0000ffff));
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: raw=%d, comp=%d.\n",
-+ ntohl(ips->ips_said.spi),
-+ ntohl(ips->ips_said.spi) & 0x0000ffff,
-+ ntohs(((struct ipcomphdr*)(((char*)iph)+iphlen))->ipcomp_cpi),
-+ pyldsz,
-+ cpyldsz);
-+
-+ /* Update IP header */
-+ iph->protocol = IPPROTO_COMP;
-+ iph->tot_len = htons(iphlen + sizeof(struct ipcomphdr) + cpyldsz);
-+#if 1 /* XXX checksum is done by ipsec_tunnel ? */
-+ iph->check = 0;
-+ iph->check = ip_fast_csum((char *) iph, iph->ihl);
-+#endif
-+
-+ /* Copy compressed payload */
-+ memcpy((char *) iph + iphlen + sizeof(struct ipcomphdr),
-+ buffer,
-+ cpyldsz);
-+ kfree(buffer);
-+
-+ /* Update skb length/tail by "unputting" the shrinkage */
-+ skb_put(skb,
-+ cpyldsz + sizeof(struct ipcomphdr) - pyldsz);
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
-+ __u8 *c;
-+ int i;
-+
-+ c = (__u8*)iph + iphlen + sizeof(struct ipcomphdr);
-+ for(i = 0; i < cpyldsz; i++, c++) {
-+ if(!(i % 16)) {
-+ printk(KERN_INFO "skb_compress: result:");
-+ }
-+ printk("%02x ", *c);
-+ if(!((i + 1) % 16)) {
-+ printk("\n");
-+ }
-+ }
-+ if(i % 16) {
-+ printk("\n");
-+ }
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ ips->ips_comp_adapt_skip = 0;
-+ ips->ips_comp_adapt_tries = 0;
-+
-+ return skb;
-+}
-+
-+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
-+{
-+ struct sk_buff *nskb = NULL;
-+
-+ /* original ip header */
-+ struct iphdr *oiph, *iph;
-+ unsigned int iphlen, pyldsz, cpyldsz;
-+ z_stream zs;
-+ int zresult;
-+
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_decompress: .\n");
-+
-+ if(!skb) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "passed in NULL skb, returning ERROR.\n");
-+ if (flags) *flags |= IPCOMP_PARMERROR;
-+ return skb;
-+ }
-+
-+ if(!ips && sysctl_ipsec_inbound_policy_check) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "passed in NULL ipsec_sa needed for comp alg, returning ERROR.\n");
-+ if (flags) *flags |= IPCOMP_PARMERROR;
-+ return skb;
-+ }
-+
-+ if (!flags) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "passed in NULL flags, returning ERROR.\n");
-+ ipsec_kfree_skb(skb);
-+ return NULL;
-+ }
-+
-+#ifdef NET_21
-+ oiph = skb->nh.iph;
-+#else /* NET_21 */
-+ oiph = skb->ip_hdr;
-+#endif /* NET_21 */
-+
-+ iphlen = oiph->ihl << 2;
-+
-+ if (oiph->protocol != IPPROTO_COMP) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "called with non-IPCOMP packet (protocol=%d),"
-+ "skipping decompression.\n",
-+ oiph->protocol);
-+ *flags |= IPCOMP_PARMERROR;
-+ return skb;
-+ }
-+
-+ if ( (((struct ipcomphdr*)((char*) oiph + iphlen))->ipcomp_flags != 0)
-+ || ((((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi
-+ != htons(SADB_X_CALG_DEFLATE))
-+ && sysctl_ipsec_inbound_policy_check
-+ && (!ips || (ips && (ips->ips_encalg != SADB_X_CALG_DEFLATE)))) ) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "called with incompatible IPCOMP packet (flags=%d, "
-+ "cpi=%d), ips-compalg=%d, skipping decompression.\n",
-+ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_flags),
-+ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi),
-+ ips ? ips->ips_encalg : 0);
-+ *flags |= IPCOMP_PARMERROR;
-+
-+ return skb;
-+ }
-+
-+ if (ntohs(oiph->frag_off) & ~0x4000) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "called with fragmented IPCOMP packet, "
-+ "skipping decompression.\n");
-+ *flags |= IPCOMP_PARMERROR;
-+ return skb;
-+ }
-+
-+ /* original compressed payload size */
-+ cpyldsz = ntohs(oiph->tot_len) - iphlen - sizeof(struct ipcomphdr);
-+
-+ zs.zalloc = my_zcalloc;
-+ zs.zfree = my_zfree;
-+ zs.opaque = 0;
-+
-+ zs.next_in = (char *) oiph + iphlen + sizeof(struct ipcomphdr);
-+ zs.avail_in = cpyldsz;
-+
-+ /* Maybe we should be a bit conservative about memory
-+ requirements and use inflateInit2 */
-+ /* Beware, that this might make us unable to decompress packets
-+ from other implementations - HINT: check PGPnet source code */
-+ /* We want to use inflateInit2 because we don't want the adler
-+ header. */
-+ zresult = inflateInit2(&zs, -15);
-+ if (zresult != Z_OK) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "inflateInit2() returned error %d (%s), "
-+ "skipping decompression.\n",
-+ zresult,
-+ zs.msg ? zs.msg : zError(zresult));
-+ *flags |= IPCOMP_DECOMPRESSIONERROR;
-+
-+ return skb;
-+ }
-+
-+ /* We have no way of knowing the exact length of the resulting
-+ decompressed output before we have actually done the decompression.
-+ For now, we guess that the packet will not be bigger than the
-+ attached ipsec device's mtu or 16260, whichever is biggest.
-+ This may be wrong, since the sender's mtu may be bigger yet.
-+ XXX This must be dealt with later XXX
-+ */
-+
-+ /* max payload size */
-+ pyldsz = skb->dev ? (skb->dev->mtu < 16260 ? 16260 : skb->dev->mtu)
-+ : (65520 - iphlen);
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_decompress: "
-+ "max payload size: %d\n", pyldsz);
-+
-+ while (pyldsz > (cpyldsz + sizeof(struct ipcomphdr)) &&
-+ (nskb = skb_copy_ipcomp(skb,
-+ pyldsz - cpyldsz - sizeof(struct ipcomphdr),
-+ GFP_ATOMIC)) == NULL) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "unable to skb_copy_ipcomp(skb, %d, GFP_ATOMIC), "
-+ "trying with less payload size.\n",
-+ (int)(pyldsz - cpyldsz - sizeof(struct ipcomphdr)));
-+ pyldsz >>=1;
-+ }
-+
-+ if (!nskb) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "unable to allocate memory, dropping packet.\n");
-+ *flags |= IPCOMP_DECOMPRESSIONERROR;
-+ inflateEnd(&zs);
-+
-+ return skb;
-+ }
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
-+ __u8 *c;
-+ int i;
-+
-+ c = (__u8*)oiph + iphlen + sizeof(struct ipcomphdr);
-+ for(i = 0; i < cpyldsz; i++, c++) {
-+ if(!(i % 16)) {
-+ printk(KERN_INFO "skb_decompress: before:");
-+ }
-+ printk("%02x ", *c);
-+ if(!((i + 1) % 16)) {
-+ printk("\n");
-+ }
-+ }
-+ if(i % 16) {
-+ printk("\n");
-+ }
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#ifdef NET_21
-+ iph = nskb->nh.iph;
-+#else /* NET_21 */
-+ iph = nskb->ip_hdr;
-+#endif /* NET_21 */
-+ zs.next_out = (char *)iph + iphlen;
-+ zs.avail_out = pyldsz;
-+
-+ zresult = inflate(&zs, Z_SYNC_FLUSH);
-+
-+ /* work around a bug in zlib, which sometimes wants to taste an extra
-+ * byte when being used in the (undocumented) raw deflate mode.
-+ */
-+ if (zresult == Z_OK && !zs.avail_in && zs.avail_out) {
-+ __u8 zerostuff = 0;
-+
-+ zs.next_in = &zerostuff;
-+ zs.avail_in = 1;
-+ zresult = inflate(&zs, Z_FINISH);
-+ }
-+
-+ inflateEnd(&zs);
-+ if (zresult != Z_STREAM_END) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "inflate() returned error %d (%s), "
-+ "skipping decompression.\n",
-+ zresult,
-+ zs.msg ? zs.msg : zError(zresult));
-+ *flags |= IPCOMP_DECOMPRESSIONERROR;
-+ ipsec_kfree_skb(nskb);
-+
-+ return skb;
-+ }
-+
-+ /* Update IP header */
-+ /* resulting decompressed size */
-+ pyldsz -= zs.avail_out;
-+ iph->tot_len = htons(iphlen + pyldsz);
-+ iph->protocol = ((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_nh;
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_decompress: "
-+ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: comp=%d, raw=%d, nh=%d.\n",
-+ ips ? ntohl(ips->ips_said.spi) : 0,
-+ ips ? ntohl(ips->ips_said.spi) & 0x0000ffff : 0,
-+ ntohs(((struct ipcomphdr*)(((char*)oiph)+iphlen))->ipcomp_cpi),
-+ cpyldsz,
-+ pyldsz,
-+ iph->protocol);
-+
-+#if 1 /* XXX checksum is done by ipsec_rcv ? */
-+ iph->check = 0;
-+ iph->check = ip_fast_csum((char*) iph, iph->ihl);
-+#endif
-+
-+ /* Update skb length/tail by "unputting" the unused data area */
-+ skb_put(nskb, -zs.avail_out);
-+
-+ ipsec_kfree_skb(skb);
-+
-+ if (iph->protocol == IPPROTO_COMP)
-+ {
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(sysctl_ipsec_debug_ipcomp)
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_decompress: "
-+ "Eh? inner packet is also compressed, dropping.\n");
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ ipsec_kfree_skb(nskb);
-+ return NULL;
-+ }
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
-+ __u8 *c;
-+ int i;
-+
-+ c = (__u8*)iph + iphlen;
-+ for(i = 0; i < pyldsz; i++, c++) {
-+ if(!(i % 16)) {
-+ printk(KERN_INFO "skb_decompress: result:");
-+ }
-+ printk("%02x ", *c);
-+ if(!((i + 1) % 16)) {
-+ printk("\n");
-+ }
-+ }
-+ if(i % 16) {
-+ printk("\n");
-+ }
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ return nskb;
-+}
-+
-+
-+/* this is derived from skb_copy() in linux 2.2.14 */
-+/* May be incompatible with other kernel versions!! */
-+static
-+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask)
-+{
-+ struct sk_buff *n;
-+ struct iphdr *iph;
-+ unsigned long offset;
-+ unsigned int iphlen;
-+
-+ if(!skb) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_copy_ipcomp: "
-+ "passed in NULL skb, returning NULL.\n");
-+ return NULL;
-+ }
-+
-+ /*
-+ * Allocate the copy buffer
-+ */
-+
-+#ifdef NET_21
-+ iph = skb->nh.iph;
-+#else /* NET_21 */
-+ iph = skb->ip_hdr;
-+#endif /* NET_21 */
-+ if (!iph) return NULL;
-+ iphlen = iph->ihl << 2;
-+
-+ n=alloc_skb(skb->end - skb->head + data_growth, gfp_mask);
-+ if(n==NULL)
-+ return NULL;
-+
-+ /*
-+ * Shift between the two data areas in bytes
-+ */
-+
-+ offset=n->head-skb->head;
-+
-+ /* Set the data pointer */
-+ skb_reserve(n,skb->data-skb->head);
-+ /* Set the tail pointer and length */
-+ skb_put(n,skb->len+data_growth);
-+ /* Copy the bytes up to and including the ip header */
-+ memcpy(n->head,
-+ skb->head,
-+ ((char *)iph - (char *)skb->head) + iphlen);
-+ n->list=NULL;
-+ n->next=NULL;
-+ n->prev=NULL;
-+ n->sk=NULL;
-+ n->dev=skb->dev;
-+ if (skb->h.raw)
-+ n->h.raw=skb->h.raw+offset;
-+ else
-+ n->h.raw=NULL;
-+ n->protocol=skb->protocol;
-+#ifdef NET_21
-+ n->csum = 0;
-+ n->priority=skb->priority;
-+ n->dst=dst_clone(skb->dst);
-+ n->nh.raw=skb->nh.raw+offset;
-+#ifndef NETDEV_23
-+ n->is_clone=0;
-+#endif /* NETDEV_23 */
-+ atomic_set(&n->users, 1);
-+ n->destructor = NULL;
-+ n->security=skb->security;
-+ memcpy(n->cb, skb->cb, sizeof(skb->cb));
-+#ifdef CONFIG_IP_FIREWALL
-+ n->fwmark = skb->fwmark;
-+#endif
-+#else /* NET_21 */
-+ n->link3=NULL;
-+ n->when=skb->when;
-+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
-+ n->saddr=skb->saddr;
-+ n->daddr=skb->daddr;
-+ n->raddr=skb->raddr;
-+ n->seq=skb->seq;
-+ n->end_seq=skb->end_seq;
-+ n->ack_seq=skb->ack_seq;
-+ n->acked=skb->acked;
-+ n->free=1;
-+ n->arp=skb->arp;
-+ n->tries=0;
-+ n->lock=0;
-+ n->users=0;
-+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
-+#endif /* NET_21 */
-+ if (skb->mac.raw)
-+ n->mac.raw=skb->mac.raw+offset;
-+ else
-+ n->mac.raw=NULL;
-+#ifndef NETDEV_23
-+ n->used=skb->used;
-+#endif /* !NETDEV_23 */
-+ n->pkt_type=skb->pkt_type;
-+#ifndef NETDEV_23
-+ n->pkt_bridged=skb->pkt_bridged;
-+#endif /* NETDEV_23 */
-+ n->ip_summed=0;
-+ n->stamp=skb->stamp;
-+#ifndef NETDEV_23 /* this seems to have been removed in 2.4 */
-+#if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE)
-+ n->shapelatency=skb->shapelatency; /* Latency on frame */
-+ n->shapeclock=skb->shapeclock; /* Time it should go out */
-+ n->shapelen=skb->shapelen; /* Frame length in clocks */
-+ n->shapestamp=skb->shapestamp; /* Stamp for shaper */
-+ n->shapepend=skb->shapepend; /* Pending */
-+#endif /* defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) */
-+#endif /* NETDEV_23 */
-+#ifdef CONFIG_HIPPI
-+ n->private.ifield=skb->private.ifield;
-+#endif /* CONFIG_HIPPI */
-+
-+ return n;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_ah.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,363 @@
-+/*
-+ * processing code for AH
-+ * Copyright (C) 2003-2004 Michael Richardson <mcr@xelerance.com>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipsec_ah_c_version[] = "RCSID $Id$";
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define proto_priv cb
-+#endif /* NET21 */
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h"
-+#include "openswan/ipsec_xmit.h"
-+
-+#include "openswan/ipsec_auth.h"
-+
-+#ifdef CONFIG_IPSEC_AH
-+#include "openswan/ipsec_ah.h"
-+#endif /* CONFIG_IPSEC_AH */
-+
-+#include "openswan/ipsec_proto.h"
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_ah = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+__u32 zeroes[AH_AMAX];
-+
-+#ifdef CONFIG_IPSEC_AH
-+enum ipsec_rcv_value
-+ipsec_rcv_ah_checks(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb)
-+{
-+ int ahminlen;
-+
-+ ahminlen = irs->hard_header_len + sizeof(struct iphdr);
-+
-+ /* take care not to deref this pointer until we check the minlen though */
-+ irs->protostuff.ahstuff.ahp = (struct ahhdr *) (skb->data + irs->iphlen);
-+
-+ if((skb->len < ahminlen+sizeof(struct ahhdr)) ||
-+ (skb->len < ahminlen+(irs->protostuff.ahstuff.ahp->ah_hl << 2))) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
-+ "klips_debug:ipsec_rcv: "
-+ "runt ah packet of skb->len=%d received from %s, dropped.\n",
-+ skb->len,
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_BADLEN;
-+ }
-+
-+ irs->said.spi = irs->protostuff.ahstuff.ahp->ah_spi;
-+
-+ /* XXX we only support the one 12-byte authenticator for now */
-+ if(irs->protostuff.ahstuff.ahp->ah_hl != ((AHHMAC_HASHLEN+AHHMAC_RPLLEN) >> 2)) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
-+ "klips_debug:ipsec_rcv: "
-+ "bad authenticator length %ld, expected %lu from %s.\n",
-+ (long)(irs->protostuff.ahstuff.ahp->ah_hl << 2),
-+ (unsigned long) sizeof(struct ahhdr),
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_BADLEN;
-+ }
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+
-+enum ipsec_rcv_value
-+ipsec_rcv_ah_setup_auth(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb,
-+ __u32 *replay,
-+ unsigned char **authenticator)
-+{
-+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
-+
-+ *replay = ntohl(ahp->ah_rpl);
-+ *authenticator = ahp->ah_data;
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+enum ipsec_rcv_value
-+ipsec_rcv_ah_authcalc(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb)
-+{
-+ struct auth_alg *aa;
-+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
-+ union {
-+ MD5_CTX md5;
-+ SHA1_CTX sha1;
-+ } tctx;
-+ struct iphdr ipo;
-+ int ahhlen;
-+
-+ aa = irs->authfuncs;
-+
-+ /* copy the initialized keying material */
-+ memcpy(&tctx, irs->ictx, irs->ictx_len);
-+
-+ ipo = *irs->ipp;
-+ ipo.tos = 0; /* mutable RFC 2402 3.3.3.1.1.1 */
-+ ipo.frag_off = 0;
-+ ipo.ttl = 0;
-+ ipo.check = 0;
-+
-+
-+ /* do the sanitized header */
-+ (*aa->update)((void*)&tctx, (caddr_t)&ipo, sizeof(struct iphdr));
-+
-+ /* XXX we didn't do the options here! */
-+
-+ /* now do the AH header itself */
-+ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
-+ (*aa->update)((void*)&tctx, (caddr_t)ahp, ahhlen - AHHMAC_HASHLEN);
-+
-+ /* now, do some zeroes */
-+ (*aa->update)((void*)&tctx, (caddr_t)zeroes, AHHMAC_HASHLEN);
-+
-+ /* finally, do the packet contents themselves */
-+ (*aa->update)((void*)&tctx,
-+ (caddr_t)skb->data + irs->iphlen + ahhlen,
-+ skb->len - irs->iphlen - ahhlen);
-+
-+ (*aa->final)(irs->hash, (void *)&tctx);
-+
-+ memcpy(&tctx, irs->octx, irs->octx_len);
-+
-+ (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
-+ (*aa->final)(irs->hash, (void *)&tctx);
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+enum ipsec_rcv_value
-+ipsec_rcv_ah_decap(struct ipsec_rcv_state *irs)
-+{
-+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
-+ struct sk_buff *skb;
-+ int ahhlen;
-+
-+ skb=irs->skb;
-+
-+ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
-+
-+ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - ahhlen);
-+ irs->next_header = ahp->ah_nh;
-+
-+ /*
-+ * move the IP header forward by the size of the AH header, which
-+ * will remove the the AH header from the packet.
-+ */
-+ memmove((void *)(skb->data + ahhlen),
-+ (void *)(skb->data), irs->iphlen);
-+
-+ ipsec_rcv_dmp("ah postmove", skb->data, skb->len);
-+
-+ /* skb_pull below, will move up by ahhlen */
-+
-+ /* XXX not clear how this can happen, as the message indicates */
-+ if(skb->len < ahhlen) {
-+ printk(KERN_WARNING
-+ "klips_error:ipsec_rcv: "
-+ "tried to skb_pull ahhlen=%d, %d available. This should never happen, please report.\n",
-+ ahhlen,
-+ (int)(skb->len));
-+ return IPSEC_RCV_DECAPFAIL;
-+ }
-+ skb_pull(skb, ahhlen);
-+
-+ irs->ipp = (struct iphdr *)skb->data;
-+
-+ ipsec_rcv_dmp("ah postpull", skb->data, skb->len);
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_ah_setup(struct ipsec_xmit_state *ixs)
-+{
-+ struct iphdr ipo;
-+ struct ahhdr *ahp;
-+ __u8 hash[AH_AMAX];
-+ union {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ MD5_CTX md5;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ SHA1_CTX sha1;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ } tctx;
-+ unsigned char *dat = (unsigned char *)ixs->iph;
-+
-+ ahp = (struct ahhdr *)(dat + ixs->iphlen);
-+ ahp->ah_spi = ixs->ipsp->ips_said.spi;
-+ ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
-+ ahp->ah_rv = 0;
-+ ahp->ah_nh = ixs->iph->protocol;
-+ ahp->ah_hl = (sizeof(struct ahhdr) >> 2) - sizeof(__u64)/sizeof(__u32);
-+ ixs->iph->protocol = IPPROTO_AH;
-+ ipsec_xmit_dmp("ahp", (char*)ahp, sizeof(*ahp));
-+
-+ ipo = *ixs->iph;
-+ ipo.tos = 0;
-+ ipo.frag_off = 0;
-+ ipo.ttl = 0;
-+ ipo.check = 0;
-+ ipsec_xmit_dmp("ipo", (char*)&ipo, sizeof(ipo));
-+
-+ switch(ixs->ipsp->ips_authalg) {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5:
-+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
-+ ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
-+ ipsec_xmit_dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, (unsigned char *)ahp,
-+ sizeof(struct ahhdr) - sizeof(ahp->ah_data));
-+ ipsec_xmit_dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
-+ ipsec_xmit_dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, dat + ixs->iphlen + sizeof(struct ahhdr),
-+ ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
-+ ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Final(hash, &tctx.md5);
-+ ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
-+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
-+ ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, hash, AHMD596_ALEN);
-+ ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Final(hash, &tctx.md5);
-+ ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
-+
-+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
-+
-+ /* paranoid */
-+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
-+ memset((caddr_t)hash, 0, sizeof(*hash));
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA:
-+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
-+ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
-+ SHA1Update(&tctx.sha1, (unsigned char *)ahp, sizeof(struct ahhdr) - sizeof(ahp->ah_data));
-+ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
-+ SHA1Update(&tctx.sha1, dat + ixs->iphlen + sizeof(struct ahhdr),
-+ ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
-+ SHA1Final(hash, &tctx.sha1);
-+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
-+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
-+ SHA1Final(hash, &tctx.sha1);
-+
-+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
-+
-+ /* paranoid */
-+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
-+ memset((caddr_t)hash, 0, sizeof(*hash));
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_AH_BADALG;
-+ }
-+#ifdef NET_21
-+ ixs->skb->h.raw = (unsigned char*)ahp;
-+#endif /* NET_21 */
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+struct xform_functions ah_xform_funcs[]={
-+ { rcv_checks: ipsec_rcv_ah_checks,
-+ rcv_setup_auth: ipsec_rcv_ah_setup_auth,
-+ rcv_calc_auth: ipsec_rcv_ah_authcalc,
-+ rcv_decrypt: ipsec_rcv_ah_decap,
-+
-+ xmit_setup: ipsec_xmit_ah_setup,
-+ xmit_headroom: sizeof(struct ahhdr),
-+ xmit_needtailroom: 0,
-+ },
-+};
-+
-+struct inet_protocol ah_protocol =
-+{
-+ ipsec_rcv, /* AH handler */
-+ NULL, /* TUNNEL error control */
-+#ifdef NETDEV_25
-+ 1, /* no policy */
-+#else
-+ 0, /* next */
-+ IPPROTO_AH, /* protocol ID */
-+ 0, /* copy */
-+ NULL, /* data */
-+ "AH" /* name */
-+#endif
-+};
-+
-+#endif /* CONFIG_IPSEC_AH */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.2 2004/04/06 02:49:25 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_alg.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,953 @@
-+/*
-+ * Modular extensions service and registration functions
-+ *
-+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
-+ *
-+ * Version: 0.8.1
-+ *
-+ * ipsec_alg.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ */
-+#ifdef CONFIG_IPSEC_ALG
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/in.h>
-+#include <linux/types.h>
-+#include <linux/string.h> /* memcmp() */
-+#include <linux/random.h> /* get_random_bytes() */
-+#include <linux/errno.h> /* error codes */
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define proto_priv cb
-+#endif /* NET21 */
-+#include "openswan/ipsec_param.h"
-+#include <openswan.h>
-+#include "openswan/ipsec_sa.h"
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h"
-+#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH)
-+# include "openswan/ipsec_ah.h"
-+#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */
-+#ifdef CONFIG_IPSEC_ESP
-+# include "openswan/ipsec_esp.h"
-+#endif /* !CONFIG_IPSEC_ESP */
-+#ifdef CONFIG_IPSEC_IPCOMP
-+# include "openswan/ipcomp.h"
-+#endif /* CONFIG_IPSEC_COMP */
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_alg.h"
-+
-+#ifndef CONFIG_IPSEC_ALG
-+#error This file _MUST_ be compiled with CONFIG_IPSEC_ALG enabled !
-+#endif
-+#if SADB_EALG_MAX < 255
-+#warning Compiling with limited ESP support ( SADB_EALG_MAX < 256 )
-+#endif
-+
-+static rwlock_t ipsec_alg_lock = RW_LOCK_UNLOCKED;
-+#define IPSEC_ALG_HASHSZ 16 /* must be power of 2, even 2^0=1 */
-+static struct list_head ipsec_alg_hash_table[IPSEC_ALG_HASHSZ];
-+
-+/* Old gcc's will fail here */
-+#define barf_out(fmt, args...) do { printk(KERN_ERR "%s: (%s) " fmt, __FUNCTION__, ixt->ixt_name , ## args)\
-+ ; goto out; } while(0)
-+
-+/*
-+ * Must be already protected by lock
-+ */
-+static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt) {
-+ if (ixt->ixt_module)
-+ __MOD_INC_USE_COUNT(ixt->ixt_module);
-+ atomic_inc(&ixt->ixt_refcnt);
-+}
-+static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
-+ atomic_dec(&ixt->ixt_refcnt);
-+ if (ixt->ixt_module)
-+ __MOD_DEC_USE_COUNT(ixt->ixt_module);
-+}
-+/*
-+ * simple hash function, optimized for 0-hash (1 list) special
-+ * case
-+ */
-+#if IPSEC_ALG_HASHSZ > 1
-+static inline unsigned ipsec_alg_hashfn(int alg_type, int alg_id) {
-+ return ((alg_type^alg_id)&(IPSEC_ALG_HASHSZ-1));
-+}
-+#else
-+#define ipsec_alg_hashfn(x,y) (0)
-+#endif
-+
-+/*****************************************************************
-+ *
-+ * INTERNAL table handling: insert, delete, find
-+ *
-+ *****************************************************************/
-+
-+/*
-+ * hash table initialization, called from ipsec_alg_init()
-+ */
-+static void ipsec_alg_hash_init(void) {
-+ struct list_head *head = ipsec_alg_hash_table;
-+ int i = IPSEC_ALG_HASHSZ;
-+ do {
-+ INIT_LIST_HEAD(head);
-+ head++;
-+ i--;
-+ } while (i);
-+}
-+/*
-+ * hash list lookup by {alg_type, alg_id} and table head,
-+ * must be already protected by lock
-+ */
-+static struct ipsec_alg *__ipsec_alg_find(unsigned alg_type, unsigned alg_id, struct list_head * head) {
-+ struct list_head *p;
-+ struct ipsec_alg *ixt=NULL;
-+ for (p=head->next; p!=head; p=p->next) {
-+ ixt = list_entry(p, struct ipsec_alg, ixt_list);
-+ if (ixt->ixt_alg_type == alg_type && ixt->ixt_alg_id==alg_id) {
-+ goto out;
-+ }
-+ }
-+ ixt=NULL;
-+out:
-+ return ixt;
-+}
-+/*
-+ * inserts (in front) a new entry in hash table,
-+ * called from ipsec_alg_register() when new algorithm is registered.
-+ */
-+static int ipsec_alg_insert(struct ipsec_alg *ixt) {
-+ int ret=-EINVAL;
-+ unsigned hashval=ipsec_alg_hashfn(ixt->ixt_alg_type, ixt->ixt_alg_id);
-+ struct list_head *head= ipsec_alg_hash_table + hashval;
-+ struct ipsec_alg *ixt_cur;
-+ /* new element must be virgin ... */
-+ if (ixt->ixt_list.next != &ixt->ixt_list ||
-+ ixt->ixt_list.prev != &ixt->ixt_list) {
-+ printk(KERN_ERR "ipsec_alg_insert: ixt object \"%s\" "
-+ "list head not initialized\n",
-+ ixt->ixt_name);
-+ return ret;
-+ }
-+ write_lock_bh(&ipsec_alg_lock);
-+ ixt_cur = __ipsec_alg_find(ixt->ixt_alg_type, ixt->ixt_alg_id, head);
-+ /* if previous (current) ipsec_alg found check excl flag of _anyone_ */
-+ if (ixt_cur && ((ixt->ixt_state|ixt_cur->ixt_state) & IPSEC_ALG_ST_EXCL))
-+ barf_out("ipsec_alg for alg_type=%d, alg_id=%d already exist. "
-+ "Not loaded (ret=%d).\n",
-+ ixt->ixt_alg_type,
-+ ixt->ixt_alg_id, ret=-EEXIST);
-+ list_add(&ixt->ixt_list, head);
-+ ixt->ixt_state |= IPSEC_ALG_ST_REGISTERED;
-+ ret=0;
-+out:
-+ write_unlock_bh(&ipsec_alg_lock);
-+ return ret;
-+}
-+/*
-+ * deletes an existing entry in hash table,
-+ * called from ipsec_alg_unregister() when algorithm is unregistered.
-+ */
-+static int ipsec_alg_delete(struct ipsec_alg *ixt) {
-+ write_lock_bh(&ipsec_alg_lock);
-+ list_del(&ixt->ixt_list);
-+ write_unlock_bh(&ipsec_alg_lock);
-+ return 0;
-+}
-+/*
-+ * here @user context (read-only when @kernel bh context)
-+ * -> no bh disabling
-+ *
-+ * called from ipsec_sa_init() -> ipsec_alg_sa_init()
-+ */
-+static struct ipsec_alg *ipsec_alg_get(int alg_type, int alg_id) {
-+ unsigned hashval=ipsec_alg_hashfn(alg_type, alg_id);
-+ struct list_head *head= ipsec_alg_hash_table + hashval;
-+ struct ipsec_alg *ixt;
-+ read_lock(&ipsec_alg_lock);
-+ ixt=__ipsec_alg_find(alg_type, alg_id, head);
-+ if (ixt) __ipsec_alg_usage_inc(ixt);
-+ read_unlock(&ipsec_alg_lock);
-+ return ixt;
-+}
-+
-+static void ipsec_alg_put(struct ipsec_alg *ixt) {
-+ __ipsec_alg_usage_dec((struct ipsec_alg *)ixt);
-+}
-+
-+/*****************************************************************
-+ *
-+ * INTERFACE for ENC services: key creation, encrypt function
-+ *
-+ *****************************************************************/
-+
-+/*
-+ * main encrypt service entry point
-+ * called from ipsec_rcv() with encrypt=IPSEC_ALG_DECRYPT and
-+ * ipsec_tunnel_start_xmit with encrypt=IPSEC_ALG_ENCRYPT
-+ */
-+int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 * idat, int ilen, const __u8 * iv, int encrypt) {
-+ int ret;
-+ struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
-+ KLIPS_PRINT(debug_rcv||debug_tunnel,
-+ "klips_debug:ipsec_alg_esp_encrypt: "
-+ "entering with encalg=%d, ixt_e=%p\n",
-+ sa_p->ips_encalg, ixt_e);
-+ if (!ixt_e) {
-+ KLIPS_PRINT(debug_rcv||debug_tunnel,
-+ "klips_debug:ipsec_alg_esp_encrypt: "
-+ "NULL ipsec_alg_enc object\n");
-+ return -1;
-+ }
-+ KLIPS_PRINT(debug_rcv||debug_tunnel,
-+ "klips_debug:ipsec_alg_esp_encrypt: "
-+ "calling cbc_encrypt encalg=%d "
-+ "ips_key_e=%p idat=%p ilen=%d iv=%p, encrypt=%d\n",
-+ sa_p->ips_encalg,
-+ sa_p->ips_key_e, idat, ilen, iv, encrypt);
-+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, sa_p->ips_key_e, idat, ilen, iv, encrypt);
-+ KLIPS_PRINT(debug_rcv||debug_tunnel,
-+ "klips_debug:ipsec_alg_esp_encrypt: "
-+ "returned ret=%d\n",
-+ ret);
-+ return ret;
-+}
-+/*
-+ * encryption key context creation function
-+ * called from pfkey_v2_parser.c:pfkey_ips_init()
-+ */
-+int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p) {
-+ int ret=-EINVAL;
-+ int keyminbits, keymaxbits;
-+ caddr_t ekp;
-+ struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_alg_enc_key_create: "
-+ "entering with encalg=%d ixt_e=%p\n",
-+ sa_p->ips_encalg, ixt_e);
-+ if (!ixt_e) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_alg_enc_key_create: "
-+ "NULL ipsec_alg_enc object\n");
-+ return -EPROTO;
-+ }
-+
-+ /*
-+ * grRRR... DES 7bits jurassic stuff ... f*ckk --jjo
-+ */
-+ switch(ixt_e->ixt_alg_id) {
-+ case ESP_3DES:
-+ keyminbits=keymaxbits=192;break;
-+ case ESP_DES:
-+ keyminbits=keymaxbits=64;break;
-+ default:
-+ keyminbits=ixt_e->ixt_keyminbits;
-+ keymaxbits=ixt_e->ixt_keymaxbits;
-+ }
-+ if(sa_p->ips_key_bits_e<keyminbits ||
-+ sa_p->ips_key_bits_e>keymaxbits) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_alg_enc_key_create: "
-+ "incorrect encryption key size for id=%d: %d bits -- "
-+ "must be between %d,%d bits\n" /*octets (bytes)\n"*/,
-+ ixt_e->ixt_alg_id,
-+ sa_p->ips_key_bits_e, keyminbits, keymaxbits);
-+ ret=-EINVAL;
-+ goto ixt_out;
-+ }
-+ /* save encryption key pointer */
-+ ekp = sa_p->ips_key_e;
-+
-+
-+ if (ixt_e->ixt_e_new_key) {
-+ sa_p->ips_key_e = ixt_e->ixt_e_new_key(ixt_e,
-+ ekp, sa_p->ips_key_bits_e/8);
-+ ret = (sa_p->ips_key_e)? 0 : -EINVAL;
-+ } else {
-+ if((sa_p->ips_key_e = (caddr_t)
-+ kmalloc((sa_p->ips_key_e_size = ixt_e->ixt_e_ctx_size),
-+ GFP_ATOMIC)) == NULL) {
-+ ret=-ENOMEM;
-+ goto ixt_out;
-+ }
-+ /* zero-out key_e */
-+ memset(sa_p->ips_key_e, 0, sa_p->ips_key_e_size);
-+
-+ /* I cast here to allow more decoupling in alg module */
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_alg_enc_key_create: about to call:"
-+ "set_key(key_e=%p, ekp=%p, key_size=%d)\n",
-+ (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
-+ ret = ixt_e->ixt_e_set_key(ixt_e, (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
-+ }
-+ /* paranoid */
-+ memset(ekp, 0, sa_p->ips_key_bits_e/8);
-+ kfree(ekp);
-+ixt_out:
-+ return ret;
-+}
-+
-+/***************************************************************
-+ *
-+ * INTERFACE for AUTH services: key creation, hash functions
-+ *
-+ ***************************************************************/
-+
-+/*
-+ * auth key context creation function
-+ * called from pfkey_v2_parser.c:pfkey_ips_init()
-+ */
-+int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p) {
-+ int ret=-EINVAL;
-+ struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
-+ int keyminbits, keymaxbits;
-+ unsigned char *akp;
-+ unsigned int aks;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_alg_auth_key_create: "
-+ "entering with authalg=%d ixt_a=%p\n",
-+ sa_p->ips_authalg, ixt_a);
-+ if (!ixt_a) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_alg_auth_key_create: "
-+ "NULL ipsec_alg_auth object\n");
-+ return -EPROTO;
-+ }
-+ keyminbits=ixt_a->ixt_keyminbits;
-+ keymaxbits=ixt_a->ixt_keymaxbits;
-+ if(sa_p->ips_key_bits_a<keyminbits || sa_p->ips_key_bits_a>keymaxbits) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_alg_auth_key_create: incorrect auth"
-+ "key size: %d bits -- must be between %d,%d bits\n"/*octets (bytes)\n"*/,
-+ sa_p->ips_key_bits_a, keyminbits, keymaxbits);
-+ ret=-EINVAL;
-+ goto ixt_out;
-+ }
-+ /* save auth key pointer */
-+ sa_p->ips_auth_bits = ixt_a->ixt_a_keylen * 8; /* XXX XXX */
-+ akp = sa_p->ips_key_a;
-+ aks = sa_p->ips_key_a_size;
-+
-+ /* will hold: 2 ctx and a blocksize buffer: kb */
-+ sa_p->ips_key_a_size = ixt_a->ixt_a_ctx_size;
-+ if((sa_p->ips_key_a =
-+ (caddr_t) kmalloc(sa_p->ips_key_a_size, GFP_ATOMIC)) == NULL) {
-+ ret=-ENOMEM;
-+ goto ixt_out;
-+ }
-+ ixt_a->ixt_a_hmac_set_key(ixt_a, sa_p->ips_key_a, akp, sa_p->ips_key_bits_a/8); /* XXX XXX */
-+ ret=0;
-+ memset(akp, 0, aks);
-+ kfree(akp);
-+
-+ixt_out:
-+ return ret;
-+}
-+
-+
-+int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) {
-+ struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
-+ if (!ixt_a) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_sa_esp_hash: "
-+ "NULL ipsec_alg_auth object\n");
-+ return -EPROTO;
-+ }
-+ KLIPS_PRINT(debug_tunnel|debug_rcv,
-+ "klips_debug:ipsec_sa_esp_hash: "
-+ "hashing %p (%d bytes) to %p (%d bytes)\n",
-+ espp, len,
-+ hash, hashlen);
-+ ixt_a->ixt_a_hmac_hash(ixt_a,
-+ sa_p->ips_key_a,
-+ espp, len,
-+ hash, hashlen);
-+ return 0;
-+}
-+
-+/***************************************************************
-+ *
-+ * INTERFACE for module loading,testing, and unloading
-+ *
-+ ***************************************************************/
-+
-+/* validation for registering (enc) module */
-+static int check_enc(struct ipsec_alg_enc *ixt) {
-+ int ret=-EINVAL;
-+ if (ixt->ixt_alg_id==0 || ixt->ixt_alg_id > SADB_EALG_MAX)
-+ barf_out("invalid alg_id=%d >= %d\n", ixt->ixt_alg_id, SADB_EALG_MAX);
-+ if (ixt->ixt_blocksize==0) /* || ixt->ixt_blocksize%2) need for ESP_NULL */
-+ barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_blocksize);
-+ if (ixt->ixt_keyminbits==0 && ixt->ixt_keymaxbits==0 && ixt->ixt_e_keylen==0)
-+ goto zero_key_ok;
-+ if (ixt->ixt_keyminbits==0)
-+ barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_keyminbits);
-+ if (ixt->ixt_keymaxbits==0)
-+ barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_keymaxbits);
-+ if (ixt->ixt_e_keylen==0)
-+ barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_e_keylen);
-+zero_key_ok:
-+ if (ixt->ixt_e_ctx_size==0 && ixt->ixt_e_new_key == NULL)
-+ barf_out(KERN_ERR "invalid key_e_size=%d and ixt_e_new_key=NULL\n", ixt->ixt_e_ctx_size);
-+ if (ixt->ixt_e_cbc_encrypt==NULL)
-+ barf_out(KERN_ERR "e_cbc_encrypt() must be not NULL\n");
-+ ret=0;
-+out:
-+ return ret;
-+}
-+
-+/* validation for registering (auth) module */
-+static int check_auth(struct ipsec_alg_auth *ixt)
-+{
-+ int ret=-EINVAL;
-+ if (ixt->ixt_alg_id==0 || ixt->ixt_alg_id > SADB_AALG_MAX)
-+ barf_out("invalid alg_id=%d > %d (SADB_AALG_MAX)\n", ixt->ixt_alg_id, SADB_AALG_MAX);
-+ if (ixt->ixt_blocksize==0 || ixt->ixt_blocksize%2)
-+ barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_blocksize);
-+ if (ixt->ixt_blocksize>AH_BLKLEN_MAX)
-+ barf_out(KERN_ERR "sorry blocksize=%d > %d. "
-+ "Please increase AH_BLKLEN_MAX and recompile\n",
-+ ixt->ixt_blocksize,
-+ AH_BLKLEN_MAX);
-+ if (ixt->ixt_keyminbits==0 && ixt->ixt_keymaxbits==0 && ixt->ixt_a_keylen==0)
-+ goto zero_key_ok;
-+ if (ixt->ixt_keyminbits==0)
-+ barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_keyminbits);
-+ if (ixt->ixt_keymaxbits==0)
-+ barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_keymaxbits);
-+ if (ixt->ixt_keymaxbits!=ixt->ixt_keyminbits)
-+ barf_out(KERN_ERR "keymaxbits must equal keyminbits (not sure).\n");
-+ if (ixt->ixt_a_keylen==0)
-+ barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_a_keylen);
-+zero_key_ok:
-+ if (ixt->ixt_a_ctx_size==0)
-+ barf_out(KERN_ERR "invalid a_ctx_size=%d\n", ixt->ixt_a_ctx_size);
-+ if (ixt->ixt_a_hmac_set_key==NULL)
-+ barf_out(KERN_ERR "a_hmac_set_key() must be not NULL\n");
-+ if (ixt->ixt_a_hmac_hash==NULL)
-+ barf_out(KERN_ERR "a_hmac_hash() must be not NULL\n");
-+ ret=0;
-+out:
-+ return ret;
-+}
-+
-+/*
-+ * Generic (enc, auth) registration entry point
-+ */
-+int register_ipsec_alg(struct ipsec_alg *ixt) {
-+ int ret=-EINVAL;
-+ /* Validation */
-+ if (ixt==NULL)
-+ barf_out("NULL ipsec_alg object passed\n");
-+ if ((ixt->ixt_version&0xffffff00) != (IPSEC_ALG_VERSION&0xffffff00))
-+ barf_out("incorrect version: %d.%d.%d-%d, "
-+ "must be %d.%d.%d[-%d]\n",
-+ IPSEC_ALG_VERSION_QUAD(ixt->ixt_version),
-+ IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION));
-+ switch(ixt->ixt_alg_type) {
-+ case IPSEC_ALG_TYPE_AUTH:
-+ if ((ret=check_auth((struct ipsec_alg_auth *)ixt)<0))
-+ goto out;
-+ break;
-+ case IPSEC_ALG_TYPE_ENCRYPT:
-+ if ((ret=check_enc((struct ipsec_alg_enc *)ixt)<0))
-+ goto out;
-+ /*
-+ * Adapted two lines below:
-+ * ivlen == 0 is possible (NULL enc has blocksize==1)
-+ *
-+ * fixed NULL support by David De Reu <DeReu@tComLabs.com>
-+ */
-+ if (ixt->ixt_ivlen == 0 && ixt->ixt_blocksize > 1)
-+ ixt->ixt_ivlen = ixt->ixt_blocksize*8;
-+ break;
-+ default:
-+ barf_out("alg_type=%d not supported\n", ixt->ixt_alg_type);
-+ }
-+ INIT_LIST_HEAD(&ixt->ixt_list);
-+ ret = ipsec_alg_insert(ixt);
-+ if (ret<0)
-+ barf_out(KERN_WARNING "ipsec_alg for alg_id=%d failed."
-+ "Not loaded (ret=%d).\n",
-+ ixt->ixt_alg_id, ret);
-+
-+ ret = pfkey_list_insert_supported((struct supported *)&ixt->ixt_support, &(pfkey_supported_list[SADB_SATYPE_ESP]));
-+ if (ret==0) {
-+ ixt->ixt_state |= IPSEC_ALG_ST_SUPP;
-+ /* send register event to userspace */
-+ pfkey_register_reply(SADB_SATYPE_ESP, NULL);
-+ } else
-+ printk(KERN_ERR "pfkey_list_insert_supported returned %d. "
-+ "Loading anyway.\n", ret);
-+ ret=0;
-+out:
-+ return ret;
-+}
-+
-+/*
-+ * unregister ipsec_alg object from own tables, if
-+ * success => calls pfkey_list_remove_supported()
-+ */
-+int unregister_ipsec_alg(struct ipsec_alg *ixt) {
-+ int ret= -EINVAL;
-+ switch(ixt->ixt_alg_type) {
-+ case IPSEC_ALG_TYPE_AUTH:
-+ case IPSEC_ALG_TYPE_ENCRYPT:
-+ break;
-+ default:
-+ /* this is not a typo :) */
-+ barf_out("frog found in list (\"%s\"): ixt_p=NULL\n",
-+ ixt->ixt_name);
-+ }
-+
-+ ret=ipsec_alg_delete(ixt);
-+ if (ixt->ixt_state&IPSEC_ALG_ST_SUPP) {
-+ ixt->ixt_state &= ~IPSEC_ALG_ST_SUPP;
-+ pfkey_list_remove_supported((struct supported *)&ixt->ixt_support, &(pfkey_supported_list[SADB_SATYPE_ESP]));
-+ /* send register event to userspace */
-+ pfkey_register_reply(SADB_SATYPE_ESP, NULL);
-+ }
-+
-+out:
-+ return ret;
-+}
-+
-+/*
-+ * Must be called from user context
-+ * used at module load type for testing algo implementation
-+ */
-+static int ipsec_alg_test_encrypt(int enc_alg, int test) {
-+ int ret;
-+ caddr_t buf = NULL;
-+ int iv_size, keysize, key_e_size;
-+ struct ipsec_alg_enc *ixt_e;
-+ void *tmp_key_e = NULL;
-+ #define BUFSZ 1024
-+ #define MARGIN 0
-+ #define test_enc (buf+MARGIN)
-+ #define test_dec (test_enc+BUFSZ+MARGIN)
-+ #define test_tmp (test_dec+BUFSZ+MARGIN)
-+ #define test_key_e (test_tmp+BUFSZ+MARGIN)
-+ #define test_iv (test_key_e+key_e_size+MARGIN)
-+ #define test_key (test_iv+iv_size+MARGIN)
-+ #define test_size (BUFSZ*3+key_e_size+iv_size+keysize+MARGIN*7)
-+ ixt_e=(struct ipsec_alg_enc *)ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, enc_alg);
-+ if (ixt_e==NULL) {
-+ KLIPS_PRINT(1,
-+ "klips_debug: ipsec_alg_test_encrypt: "
-+ "encalg=%d object not found\n",
-+ enc_alg);
-+ ret=-EINVAL;
-+ goto out;
-+ }
-+ iv_size=ixt_e->ixt_ivlen / 8;
-+ key_e_size=ixt_e->ixt_e_ctx_size;
-+ keysize=ixt_e->ixt_e_keylen;
-+ KLIPS_PRINT(1,
-+ "klips_debug: ipsec_alg_test_encrypt: "
-+ "enc_alg=%d blocksize=%d key_e_size=%d keysize=%d\n",
-+ enc_alg, iv_size, key_e_size, keysize);
-+ if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
-+ ret= -ENOMEM;
-+ goto out;
-+ }
-+ get_random_bytes(test_key, keysize);
-+ get_random_bytes(test_iv, iv_size);
-+ if (ixt_e->ixt_e_new_key) {
-+ tmp_key_e = ixt_e->ixt_e_new_key(ixt_e, test_key, keysize);
-+ ret = tmp_key_e ? 0 : -EINVAL;
-+ } else {
-+ tmp_key_e = test_key_e;
-+ ret = ixt_e->ixt_e_set_key(ixt_e, test_key_e, test_key, keysize);
-+ }
-+ if (ret < 0)
-+ goto out;
-+ get_random_bytes(test_enc, BUFSZ);
-+ memcpy(test_tmp, test_enc, BUFSZ);
-+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_enc, BUFSZ, test_iv, 1);
-+ printk(KERN_INFO
-+ "klips_info: ipsec_alg_test_encrypt: "
-+ "cbc_encrypt=1 ret=%d\n",
-+ ret);
-+ ret=memcmp(test_enc, test_tmp, BUFSZ);
-+ printk(KERN_INFO
-+ "klips_info: ipsec_alg_test_encrypt: "
-+ "memcmp(enc, tmp) ret=%d: %s\n", ret,
-+ ret!=0? "OK. (encr->DIFFers)" : "FAIL! (encr->SAME)" );
-+ memcpy(test_dec, test_enc, BUFSZ);
-+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_dec, BUFSZ, test_iv, 0);
-+ printk(KERN_INFO
-+ "klips_info: ipsec_alg_test_encrypt: "
-+ "cbc_encrypt=0 ret=%d\n", ret);
-+ ret=memcmp(test_dec, test_tmp, BUFSZ);
-+ printk(KERN_INFO
-+ "klips_info: ipsec_alg_test_encrypt: "
-+ "memcmp(dec,tmp) ret=%d: %s\n", ret,
-+ ret==0? "OK. (encr->decr->SAME)" : "FAIL! (encr->decr->DIFFers)" );
-+ {
-+ /* Shamelessly taken from drivers/md sources O:) */
-+ unsigned long now;
-+ int i, count, max=0;
-+ int encrypt, speed;
-+ for (encrypt=0; encrypt <2;encrypt ++) {
-+ for (i = 0; i < 5; i++) {
-+ now = jiffies;
-+ count = 0;
-+ while (jiffies == now) {
-+ mb();
-+ ixt_e->ixt_e_cbc_encrypt(ixt_e,
-+ tmp_key_e, test_tmp,
-+ BUFSZ, test_iv, encrypt);
-+ mb();
-+ count++;
-+ mb();
-+ }
-+ if (count > max)
-+ max = count;
-+ }
-+ speed = max * (HZ * BUFSZ / 1024);
-+ printk(KERN_INFO
-+ "klips_info: ipsec_alg_test_encrypt: "
-+ "%s %s speed=%d KB/s\n",
-+ ixt_e->ixt_name,
-+ encrypt? "encrypt": "decrypt", speed);
-+ }
-+ }
-+out:
-+ if (tmp_key_e && ixt_e->ixt_e_destroy_key) ixt_e->ixt_e_destroy_key(ixt_e, tmp_key_e);
-+ if (buf) kfree(buf);
-+ if (ixt_e) ipsec_alg_put((struct ipsec_alg *)ixt_e);
-+ return ret;
-+ #undef test_enc
-+ #undef test_dec
-+ #undef test_tmp
-+ #undef test_key_e
-+ #undef test_iv
-+ #undef test_key
-+ #undef test_size
-+}
-+
-+/*
-+ * Must be called from user context
-+ * used at module load type for testing algo implementation
-+ */
-+static int ipsec_alg_test_auth(int auth_alg, int test) {
-+ int ret;
-+ caddr_t buf = NULL;
-+ int blocksize, keysize, key_a_size;
-+ struct ipsec_alg_auth *ixt_a;
-+ #define BUFSZ 1024
-+ #define MARGIN 0
-+ #define test_auth (buf+MARGIN)
-+ #define test_key_a (test_auth+BUFSZ+MARGIN)
-+ #define test_key (test_key_a+key_a_size+MARGIN)
-+ #define test_hash (test_key+keysize+MARGIN)
-+ #define test_size (BUFSZ+key_a_size+keysize+AHHMAC_HASHLEN+MARGIN*4)
-+ ixt_a=(struct ipsec_alg_auth *)ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, auth_alg);
-+ if (ixt_a==NULL) {
-+ KLIPS_PRINT(1,
-+ "klips_debug: ipsec_alg_test_auth: "
-+ "encalg=%d object not found\n",
-+ auth_alg);
-+ ret=-EINVAL;
-+ goto out;
-+ }
-+ blocksize=ixt_a->ixt_blocksize;
-+ key_a_size=ixt_a->ixt_a_ctx_size;
-+ keysize=ixt_a->ixt_a_keylen;
-+ KLIPS_PRINT(1,
-+ "klips_debug: ipsec_alg_test_auth: "
-+ "auth_alg=%d blocksize=%d key_a_size=%d keysize=%d\n",
-+ auth_alg, blocksize, key_a_size, keysize);
-+ if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
-+ ret= -ENOMEM;
-+ goto out;
-+ }
-+ get_random_bytes(test_key, keysize);
-+ ret = ixt_a->ixt_a_hmac_set_key(ixt_a, test_key_a, test_key, keysize);
-+ if (ret < 0 )
-+ goto out;
-+ get_random_bytes(test_auth, BUFSZ);
-+ ret=ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
-+ printk(KERN_INFO
-+ "klips_info: ipsec_alg_test_auth: "
-+ "ret=%d\n", ret);
-+ {
-+ /* Shamelessly taken from drivers/md sources O:) */
-+ unsigned long now;
-+ int i, count, max=0;
-+ int speed;
-+ for (i = 0; i < 5; i++) {
-+ now = jiffies;
-+ count = 0;
-+ while (jiffies == now) {
-+ mb();
-+ ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
-+ mb();
-+ count++;
-+ mb();
-+ }
-+ if (count > max)
-+ max = count;
-+ }
-+ speed = max * (HZ * BUFSZ / 1024);
-+ printk(KERN_INFO
-+ "klips_info: ipsec_alg_test_auth: "
-+ "%s hash speed=%d KB/s\n",
-+ ixt_a->ixt_name,
-+ speed);
-+ }
-+out:
-+ if (buf) kfree(buf);
-+ if (ixt_a) ipsec_alg_put((struct ipsec_alg *)ixt_a);
-+ return ret;
-+ #undef test_auth
-+ #undef test_key_a
-+ #undef test_key
-+ #undef test_hash
-+ #undef test_size
-+}
-+
-+int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int test) {
-+ switch(alg_type) {
-+ case IPSEC_ALG_TYPE_ENCRYPT:
-+ return ipsec_alg_test_encrypt(alg_id, test);
-+ break;
-+ case IPSEC_ALG_TYPE_AUTH:
-+ return ipsec_alg_test_auth(alg_id, test);
-+ break;
-+ }
-+ printk(KERN_ERR "klips_info: ipsec_alg_test() called incorrectly: "
-+ "alg_type=%d alg_id=%d\n",
-+ alg_type, alg_id);
-+ return -EINVAL;
-+}
-+
-+int ipsec_alg_init(void) {
-+ KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
-+ "KLIPS alg v=%d.%d.%d-%d (EALG_MAX=%d, AALG_MAX=%d)\n",
-+ IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION),
-+ SADB_EALG_MAX, SADB_AALG_MAX);
-+ /* Initialize tables */
-+ write_lock_bh(&ipsec_alg_lock);
-+ ipsec_alg_hash_init();
-+ write_unlock_bh(&ipsec_alg_lock);
-+
-+ /* Initialize static algos */
-+ KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
-+ "calling ipsec_alg_static_init()\n");
-+
-+ /* If we are suppose to use our AES, and don't have CryptoAPI enabled... */
-+#if defined(CONFIG_IPSEC_ENC_AES) && CONFIG_IPSEC_ENC_AES && !defined(CONFIG_IPSEC_ENC_AES_MODULE) && !CONFIG_IPSEC_ENC_CRYPTOAPI && !defined(CONFIG_IPSEC_ENC_CRYPTOAPI_MODULE)
-+ {
-+ extern int ipsec_aes_init(void);
-+ ipsec_aes_init();
-+ }
-+#endif
-+
-+ /* If we are doing CryptoAPI, then init */
-+#if defined(CONFIG_IPSEC_ENC_CRYPTOAPI) && CONFIG_IPSEC_ENC_CRYPTOAPI && !defined(CONFIG_IPSEC_ENC_CRYPTOAPI_MODULE)
-+ {
-+ extern int ipsec_cryptoapi_init(void);
-+ ipsec_cryptoapi_init();
-+ }
-+#endif
-+
-+
-+ return 0;
-+}
-+
-+/**********************************************
-+ *
-+ * INTERFACE for ipsec_sa init and wipe
-+ *
-+ **********************************************/
-+
-+/*
-+ * Called from pluto -> pfkey_v2_parser.c:pfkey_ipsec_sa_init()
-+ */
-+int ipsec_alg_sa_init(struct ipsec_sa *sa_p) {
-+ struct ipsec_alg_enc *ixt_e;
-+ struct ipsec_alg_auth *ixt_a;
-+
-+ /* Only ESP for now ... */
-+ if (sa_p->ips_said.proto != IPPROTO_ESP)
-+ return -EPROTONOSUPPORT;
-+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_init() :"
-+ "entering for encalg=%d, authalg=%d\n",
-+ sa_p->ips_encalg, sa_p->ips_authalg);
-+ if ((ixt_e=(struct ipsec_alg_enc *)
-+ ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, sa_p->ips_encalg))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug: ipsec_alg_sa_init() :"
-+ "found ipsec_alg (ixt_e=%p) for encalg=%d\n",
-+ ixt_e, sa_p->ips_encalg);
-+ sa_p->ips_alg_enc=ixt_e;
-+ }
-+ if ((ixt_a=(struct ipsec_alg_auth *)
-+ ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, sa_p->ips_authalg))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug: ipsec_alg_sa_init() :"
-+ "found ipsec_alg (ixt_a=%p) for auth=%d\n",
-+ ixt_a, sa_p->ips_authalg);
-+ sa_p->ips_alg_auth=ixt_a;
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * Called from pluto -> ipsec_sa.c:ipsec_sa_delchain()
-+ */
-+int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p) {
-+ struct ipsec_alg *ixt;
-+ if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_enc)) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
-+ "unlinking for encalg=%d\n",
-+ ixt->ixt_alg_id);
-+ ipsec_alg_put(ixt);
-+ }
-+ if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_auth)) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
-+ "unlinking for authalg=%d\n",
-+ ixt->ixt_alg_id);
-+ ipsec_alg_put(ixt);
-+ }
-+ return 0;
-+}
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_xform_get_info(char *buffer,
-+ char **start,
-+ off_t offset,
-+ int length IPSEC_PROC_LAST_ARG)
-+{
-+ int len = 0;
-+ off_t begin = 0;
-+ int i;
-+ struct list_head *head;
-+ struct ipsec_alg *ixt;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_tncfg_get_info: "
-+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
-+ buffer,
-+ *start,
-+ (int)offset,
-+ length);
-+
-+ for(i = 0, head = ipsec_alg_hash_table; i< IPSEC_ALG_HASHSZ; i++, head++)
-+ {
-+ struct list_head *p;
-+ for (p=head->next; p!=head; p=p->next)
-+ {
-+ ixt = list_entry(p, struct ipsec_alg, ixt_list);
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ "VERSION=%d TYPE=%d ID=%d NAME=%s REFCNT=%d ",
-+ ixt->ixt_version, ixt->ixt_alg_type, ixt->ixt_alg_id,
-+ ixt->ixt_name, ixt->ixt_refcnt);
-+
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ "STATE=%08x BLOCKSIZE=%d IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
-+ ixt->ixt_state, ixt->ixt_blocksize,
-+ ixt->ixt_ivlen, ixt->ixt_keyminbits, ixt->ixt_keymaxbits);
-+
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ "IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
-+ ixt->ixt_ivlen, ixt->ixt_keyminbits, ixt->ixt_keymaxbits);
-+
-+ switch(ixt->ixt_alg_type)
-+ {
-+ case IPSEC_ALG_TYPE_AUTH:
-+ {
-+ struct ipsec_alg_auth *auth = (struct ipsec_alg_auth *)ixt;
-+
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ "KEYLEN=%d CTXSIZE=%d AUTHLEN=%d ",
-+ auth->ixt_a_keylen, auth->ixt_a_ctx_size,
-+ auth->ixt_a_authlen);
-+ break;
-+ }
-+ case IPSEC_ALG_TYPE_ENCRYPT:
-+ {
-+ struct ipsec_alg_enc *enc = (struct ipsec_alg_enc *)ixt;
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ "KEYLEN=%d CTXSIZE=%d ",
-+ enc->ixt_e_keylen, enc->ixt_e_ctx_size);
-+
-+ break;
-+ }
-+ }
-+
-+ len += ipsec_snprintf(buffer+len, length-len, "\n");
-+ }
-+ }
-+
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ len -= (offset - begin); /* Start slop */
-+ if (len > length)
-+ len = length;
-+ return len;
-+}
-+
-+
-+/*
-+ * As the author of this module, I ONLY ALLOW using it from
-+ * GPL (or same LICENSE TERMS as kernel source) modules.
-+ *
-+ * In respect to hardware crypto engines this means:
-+ * * Closed-source device drivers ARE NOT ALLOWED to use
-+ * this interface.
-+ * * Closed-source VHDL/Verilog firmware running on
-+ * the crypto hardware device IS ALLOWED to use this interface
-+ * via a GPL (or same LICENSE TERMS as kernel source) device driver.
-+ * --Juan Jose Ciarlante 20/03/2002 (thanks RGB for the correct wording)
-+ */
-+
-+/*
-+ * These symbols can only be used from GPL modules
-+ * for now, I'm disabling this because it creates false
-+ * symbol problems for old modutils.
-+ */
-+
-+/* #ifndef EXPORT_SYMBOL_GPL */
-+#undef EXPORT_SYMBOL_GPL
-+#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
-+/* #endif */
-+EXPORT_SYMBOL_GPL(register_ipsec_alg);
-+EXPORT_SYMBOL_GPL(unregister_ipsec_alg);
-+EXPORT_SYMBOL_GPL(ipsec_alg_test);
-+#endif /* CONFIG_IPSEC_ALG */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_alg_aes.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,263 @@
-+/*
-+ * ipsec_alg AES cipher stubs
-+ *
-+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
-+ *
-+ * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * Fixes by:
-+ * PK: Pawel Krawczyk <kravietz@aba.krakow.pl>
-+ * Fixes list:
-+ * PK: make XCBC comply with latest draft (keylength)
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+/*
-+ * special case: ipsec core modular with this static algo inside:
-+ * must avoid MODULE magic for this file
-+ */
-+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_AES
-+#undef MODULE
-+#endif
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+
-+#include <linux/kernel.h> /* printk() */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/string.h>
-+
-+/* Check if __exit is defined, if not null it */
-+#ifndef __exit
-+#define __exit
-+#endif
-+
-+/* Low freeswan header coupling */
-+#include "openswan/ipsec_alg.h"
-+#include "crypto/aes_cbc.h"
-+
-+#define CONFIG_IPSEC_ALG_AES_MAC 1
-+
-+#define AES_CONTEXT_T aes_context
-+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
-+static int debug=0;
-+MODULE_PARM(debug, "i");
-+static int test=0;
-+MODULE_PARM(test, "i");
-+static int excl=0;
-+MODULE_PARM(excl, "i");
-+static int keyminbits=0;
-+MODULE_PARM(keyminbits, "i");
-+static int keymaxbits=0;
-+MODULE_PARM(keymaxbits, "i");
-+
-+#if CONFIG_IPSEC_ALG_AES_MAC
-+#include "crypto/aes_xcbc_mac.h"
-+
-+/*
-+ * Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt).
-+ * We use 9 for non-modular algorithm and none for modular, thus
-+ * forcing user to specify one on module load. -kravietz
-+ */
-+#ifdef MODULE
-+static int auth_id=0;
-+#else
-+static int auth_id=9;
-+#endif
-+MODULE_PARM(auth_id, "i");
-+#endif
-+
-+#define ESP_AES 12 /* truely _constant_ :) */
-+
-+/* 128, 192 or 256 */
-+#define ESP_AES_KEY_SZ_MIN 16 /* 128 bit secret key */
-+#define ESP_AES_KEY_SZ_MAX 32 /* 256 bit secret key */
-+#define ESP_AES_CBC_BLK_LEN 16 /* AES-CBC block size */
-+
-+/* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt
-+ * -kravietz
-+ */
-+#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
-+#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
-+
-+static int _aes_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) {
-+ int ret;
-+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
-+ ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL;
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:_aes_set_key:"
-+ "ret=%d key_e=%p key=%p keysize=%d\n",
-+ ret, key_e, key, keysize);
-+ return ret;
-+}
-+static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
-+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
-+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
-+ key_e, in, ilen, iv, encrypt);
-+ return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt);
-+}
-+#if CONFIG_IPSEC_ALG_AES_MAC
-+static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) {
-+ aes_context_mac *ctxm=(aes_context_mac *)key_a;
-+ return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL;
-+}
-+static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) {
-+ int ret;
-+ char hash_buf[16];
-+ aes_context_mac *ctxm=(aes_context_mac *)key_a;
-+ ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf);
-+ memcpy(hash, hash_buf, hashlen);
-+ return ret;
-+}
-+static struct ipsec_alg_auth ipsec_alg_AES_MAC = {
-+ ixt_version: IPSEC_ALG_VERSION,
-+ ixt_module: THIS_MODULE,
-+ ixt_refcnt: ATOMIC_INIT(0),
-+ ixt_alg_type: IPSEC_ALG_TYPE_AUTH,
-+ ixt_alg_id: 0,
-+ ixt_name: "aes_mac",
-+ ixt_blocksize: ESP_AES_MAC_BLK_LEN,
-+ ixt_keyminbits: ESP_AES_MAC_KEY_SZ*8,
-+ ixt_keymaxbits: ESP_AES_MAC_KEY_SZ*8,
-+ ixt_a_keylen: ESP_AES_MAC_KEY_SZ,
-+ ixt_a_ctx_size: sizeof(aes_context_mac),
-+ ixt_a_hmac_set_key: _aes_mac_set_key,
-+ ixt_a_hmac_hash:_aes_mac_hash,
-+};
-+#endif /* CONFIG_IPSEC_ALG_AES_MAC */
-+static struct ipsec_alg_enc ipsec_alg_AES = {
-+ ixt_version: IPSEC_ALG_VERSION,
-+ ixt_module: THIS_MODULE,
-+ ixt_refcnt: ATOMIC_INIT(0),
-+ ixt_alg_type: IPSEC_ALG_TYPE_ENCRYPT,
-+ ixt_alg_id: ESP_AES,
-+ ixt_name: "aes",
-+ ixt_blocksize: ESP_AES_CBC_BLK_LEN,
-+ ixt_keyminbits: ESP_AES_KEY_SZ_MIN*8,
-+ ixt_keymaxbits: ESP_AES_KEY_SZ_MAX*8,
-+ ixt_e_keylen: ESP_AES_KEY_SZ_MAX,
-+ ixt_e_ctx_size: sizeof(AES_CONTEXT_T),
-+ ixt_e_set_key: _aes_set_key,
-+ ixt_e_cbc_encrypt:_aes_cbc_encrypt,
-+};
-+
-+#if defined(CONFIG_IPSEC_ENC_AES_MODULE)
-+IPSEC_ALG_MODULE_INIT_MOD( ipsec_aes_init )
-+#else
-+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_aes_init )
-+#endif
-+{
-+ int ret, test_ret;
-+
-+ if (keyminbits)
-+ ipsec_alg_AES.ixt_keyminbits=keyminbits;
-+ if (keymaxbits) {
-+ ipsec_alg_AES.ixt_keymaxbits=keymaxbits;
-+ if (keymaxbits*8>ipsec_alg_AES.ixt_keymaxbits)
-+ ipsec_alg_AES.ixt_e_keylen=keymaxbits*8;
-+ }
-+ if (excl) ipsec_alg_AES.ixt_state |= IPSEC_ALG_ST_EXCL;
-+ ret=register_ipsec_alg_enc(&ipsec_alg_AES);
-+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
-+ ipsec_alg_AES.ixt_alg_type,
-+ ipsec_alg_AES.ixt_alg_id,
-+ ipsec_alg_AES.ixt_name,
-+ ret);
-+ if (ret==0 && test) {
-+ test_ret=ipsec_alg_test(
-+ ipsec_alg_AES.ixt_alg_type,
-+ ipsec_alg_AES.ixt_alg_id,
-+ test);
-+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
-+ ipsec_alg_AES.ixt_alg_type,
-+ ipsec_alg_AES.ixt_alg_id,
-+ test_ret);
-+ }
-+#if CONFIG_IPSEC_ALG_AES_MAC
-+ if (auth_id!=0){
-+ int ret;
-+ ipsec_alg_AES_MAC.ixt_alg_id=auth_id;
-+ ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC);
-+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
-+ ipsec_alg_AES_MAC.ixt_alg_type,
-+ ipsec_alg_AES_MAC.ixt_alg_id,
-+ ipsec_alg_AES_MAC.ixt_name,
-+ ret);
-+ if (ret==0 && test) {
-+ test_ret=ipsec_alg_test(
-+ ipsec_alg_AES_MAC.ixt_alg_type,
-+ ipsec_alg_AES_MAC.ixt_alg_id,
-+ test);
-+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
-+ ipsec_alg_AES_MAC.ixt_alg_type,
-+ ipsec_alg_AES_MAC.ixt_alg_id,
-+ test_ret);
-+ }
-+ } else {
-+ printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id);
-+ }
-+#endif /* CONFIG_IPSEC_ALG_AES_MAC */
-+ return ret;
-+}
-+
-+#if defined(CONFIG_IPSEC_ENC_AES_MODULE)
-+IPSEC_ALG_MODULE_EXIT_MOD( ipsec_aes_fini )
-+#else
-+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_aes_fini )
-+#endif
-+{
-+#if CONFIG_IPSEC_ALG_AES_MAC
-+ if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC);
-+#endif /* CONFIG_IPSEC_ALG_AES_MAC */
-+ unregister_ipsec_alg_enc(&ipsec_alg_AES);
-+ return;
-+}
-+#ifdef MODULE_LICENSE
-+MODULE_LICENSE("GPL");
-+#endif
-+
-+#if 0+NOT_YET
-+#ifndef MODULE
-+/*
-+ * This is intended for static module setups, currently
-+ * doesn't work for modular ipsec.o with static algos inside
-+ */
-+static int setup_keybits(const char *str)
-+{
-+ unsigned aux;
-+ char *end;
-+
-+ aux = simple_strtoul(str,&end,0);
-+ if (aux != 128 && aux != 192 && aux != 256)
-+ return 0;
-+ keyminbits = aux;
-+
-+ if (*end == 0 || *end != ',')
-+ return 1;
-+ str=end+1;
-+ aux = simple_strtoul(str, NULL, 0);
-+ if (aux != 128 && aux != 192 && aux != 256)
-+ return 0;
-+ if (aux >= keyminbits)
-+ keymaxbits = aux;
-+ return 1;
-+}
-+__setup("ipsec_aes_keybits=", setup_keybits);
-+#endif
-+#endif
-+EXPORT_NO_SYMBOLS;
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,421 @@
-+/*
-+ * ipsec_alg to linux cryptoapi GLUE
-+ *
-+ * Authors: CODE.ar TEAM
-+ * Harpo MAxx <harpo@linuxmendoza.org.ar>
-+ * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
-+ * Luciano Ruete <docemeses@softhome.net>
-+ *
-+ * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * Example usage:
-+ * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
-+ * modprobe ipsec_cryptoapi
-+ * modprobe ipsec_cryptoapi test=1
-+ * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
-+ * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
-+ * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
-+ * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
-+ */
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+/*
-+ * special case: ipsec core modular with this static algo inside:
-+ * must avoid MODULE magic for this file
-+ */
-+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI
-+#undef MODULE
-+#endif
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+
-+#include <linux/kernel.h> /* printk() */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/string.h>
-+
-+/* Check if __exit is defined, if not null it */
-+#ifndef __exit
-+#define __exit
-+#endif
-+
-+/* warn the innocent */
-+#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
-+#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"
-+#define NO_CRYPTOAPI_SUPPORT
-+#endif
-+/* Low Openswan header coupling */
-+#include "openswan/ipsec_alg.h"
-+
-+#include <linux/crypto.h>
-+#ifdef CRYPTO_API_VERSION_CODE
-+#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
-+#define NO_CRYPTOAPI_SUPPORT
-+#endif
-+
-+#ifdef NO_CRYPTOAPI_SUPPORT
-+#warning "Building an unusable module :P"
-+/* Catch old CryptoAPI by not allowing module to load */
-+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
-+{
-+ printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
-+ return -EINVAL;
-+}
-+#else
-+#include <asm/scatterlist.h>
-+#include <asm/pgtable.h>
-+#include <linux/mm.h>
-+
-+#define CIPHERNAME_AES "aes"
-+#define CIPHERNAME_3DES "des3_ede"
-+#define CIPHERNAME_BLOWFISH "blowfish"
-+#define CIPHERNAME_CAST "cast5"
-+#define CIPHERNAME_SERPENT "serpent"
-+#define CIPHERNAME_TWOFISH "twofish"
-+
-+#define ESP_3DES 3
-+#define ESP_AES 12
-+#define ESP_BLOWFISH 7 /* truely _constant_ :) */
-+#define ESP_CAST 6 /* quite constant :) */
-+#define ESP_SERPENT 252 /* from ipsec drafts */
-+#define ESP_TWOFISH 253 /* from ipsec drafts */
-+
-+#define AH_MD5 2
-+#define AH_SHA 3
-+#define DIGESTNAME_MD5 "md5"
-+#define DIGESTNAME_SHA1 "sha1"
-+
-+MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
-+static int debug=0;
-+MODULE_PARM(debug, "i");
-+static int test=0;
-+MODULE_PARM(test, "i");
-+static int excl=0;
-+MODULE_PARM(excl, "i");
-+
-+static int noauto = 0;
-+MODULE_PARM(noauto,"i");
-+MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
-+
-+static int des_ede3[] = {-1, -1};
-+static int aes[] = {-1, -1};
-+static int blowfish[] = {-1, -1};
-+static int cast[] = {-1, -1};
-+static int serpent[] = {-1, -1};
-+static int twofish[] = {-1, -1};
-+
-+MODULE_PARM(des_ede3,"1-2i");
-+MODULE_PARM(aes,"1-2i");
-+MODULE_PARM(blowfish,"1-2i");
-+MODULE_PARM(cast,"1-2i");
-+MODULE_PARM(serpent,"1-2i");
-+MODULE_PARM(twofish,"1-2i");
-+MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
-+MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
-+MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
-+MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
-+MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
-+MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
-+
-+struct ipsec_alg_capi_cipher {
-+ const char *ciphername; /* cryptoapi's ciphername */
-+ unsigned blocksize;
-+ unsigned short minbits;
-+ unsigned short maxbits;
-+ int *parm; /* lkm param for this cipher */
-+ struct ipsec_alg_enc alg; /* note it's not a pointer */
-+};
-+static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
-+ { CIPHERNAME_AES , 16, 128, 256, aes , { ixt_alg_id: ESP_AES, }},
-+ { CIPHERNAME_TWOFISH , 16, 128, 256, twofish, { ixt_alg_id: ESP_TWOFISH, }},
-+ { CIPHERNAME_SERPENT , 16, 128, 256, serpent, { ixt_alg_id: ESP_SERPENT, }},
-+ { CIPHERNAME_CAST , 8, 128, 128, cast , { ixt_alg_id: ESP_CAST, }},
-+ { CIPHERNAME_BLOWFISH , 8, 96, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }},
-+ { CIPHERNAME_3DES , 8, 192, 192, des_ede3,{ ixt_alg_id: ESP_3DES, }},
-+ { NULL, 0, 0, 0, NULL, {} }
-+};
-+#ifdef NOT_YET
-+struct ipsec_alg_capi_digest {
-+ const char *digestname; /* cryptoapi's digestname */
-+ struct digest_implementation *di;
-+ struct ipsec_alg_auth alg; /* note it's not a pointer */
-+};
-+static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
-+ { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
-+ { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
-+ { NULL, NULL, {} }
-+};
-+#endif
-+/*
-+ * "generic" linux cryptoapi setup_cipher() function
-+ */
-+int setup_cipher(const char *ciphername)
-+{
-+ return crypto_alg_available(ciphername, 0);
-+}
-+
-+/*
-+ * setups ipsec_alg_capi_cipher "hyper" struct components, calling
-+ * register_ipsec_alg for cointaned ipsec_alg object
-+ */
-+static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
-+static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
-+static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
-+
-+static int
-+setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
-+{
-+ int ret;
-+ cptr->alg.ixt_version = IPSEC_ALG_VERSION;
-+ cptr->alg.ixt_module = THIS_MODULE;
-+ atomic_set (& cptr->alg.ixt_refcnt, 0);
-+ strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name));
-+
-+ cptr->alg.ixt_blocksize=cptr->blocksize;
-+ cptr->alg.ixt_keyminbits=cptr->minbits;
-+ cptr->alg.ixt_keymaxbits=cptr->maxbits;
-+ cptr->alg.ixt_state = 0;
-+ if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL;
-+ cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8;
-+ cptr->alg.ixt_e_ctx_size = 0;
-+ cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT;
-+ cptr->alg.ixt_e_new_key = _capi_new_key;
-+ cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
-+ cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
-+ cptr->alg.ixt_data = cptr;
-+
-+ ret=register_ipsec_alg_enc(&cptr->alg);
-+ printk("setup_ipsec_alg_capi_cipher(): "
-+ "alg_type=%d alg_id=%d name=%s "
-+ "keyminbits=%d keymaxbits=%d, ret=%d\n",
-+ cptr->alg.ixt_alg_type,
-+ cptr->alg.ixt_alg_id,
-+ cptr->alg.ixt_name,
-+ cptr->alg.ixt_keyminbits,
-+ cptr->alg.ixt_keymaxbits,
-+ ret);
-+ return ret;
-+}
-+/*
-+ * called in ipsec_sa_wipe() time, will destroy key contexts
-+ * and do 1 unbind()
-+ */
-+static void
-+_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
-+{
-+ struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
-+
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
-+ "name=%s key_e=%p \n",
-+ alg->ixt_name, key_e);
-+ if (!key_e) {
-+ printk(KERN_ERR "klips_debug: _capi_destroy_key:"
-+ "name=%s NULL key_e!\n",
-+ alg->ixt_name);
-+ return;
-+ }
-+ crypto_free_tfm(tfm);
-+}
-+
-+/*
-+ * create new key context, need alg->ixt_data to know which
-+ * (of many) cipher inside this module is the target
-+ */
-+static __u8 *
-+_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
-+{
-+ struct ipsec_alg_capi_cipher *cptr;
-+ struct crypto_tfm *tfm=NULL;
-+
-+ cptr = alg->ixt_data;
-+ if (!cptr) {
-+ printk(KERN_ERR "_capi_new_key(): "
-+ "NULL ixt_data (?!) for \"%s\" algo\n"
-+ , alg->ixt_name);
-+ goto err;
-+ }
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
-+ "name=%s cptr=%p key=%p keysize=%d\n",
-+ alg->ixt_name, cptr, key, keylen);
-+
-+ /*
-+ * alloc tfm
-+ */
-+ tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);
-+ if (!tfm) {
-+ printk(KERN_ERR "_capi_new_key(): "
-+ "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
-+ , alg->ixt_name, cptr->ciphername);
-+ goto err;
-+ }
-+ if (crypto_cipher_setkey(tfm, key, keylen) < 0) {
-+ printk(KERN_ERR "_capi_new_key(): "
-+ "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
-+ , alg->ixt_name, keylen);
-+ crypto_free_tfm(tfm);
-+ tfm=NULL;
-+ }
-+err:
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
-+ "name=%s key=%p keylen=%d tfm=%p\n",
-+ alg->ixt_name, key, keylen, tfm);
-+ return (__u8 *) tfm;
-+}
-+/*
-+ * core encryption function: will use cx->ci to call actual cipher's
-+ * cbc function
-+ */
-+static int
-+_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
-+ int error =0;
-+ struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
-+ struct scatterlist sg = {
-+ .page = virt_to_page(in),
-+ .offset = (unsigned long)(in) % PAGE_SIZE,
-+ .length=ilen,
-+ };
-+ if (debug > 1)
-+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
-+ "key_e=%p "
-+ "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
-+ , key_e
-+ , in, in, ilen, iv, encrypt);
-+ crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));
-+ if (encrypt)
-+ error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);
-+ else
-+ error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);
-+ if (debug > 1)
-+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
-+ "error=%d\n"
-+ , error);
-+ return (error<0)? error : ilen;
-+}
-+/*
-+ * main initialization loop: for each cipher in list, do
-+ * 1) setup cryptoapi cipher else continue
-+ * 2) register ipsec_alg object
-+ */
-+static int
-+setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
-+{
-+ struct ipsec_alg_capi_cipher *cptr;
-+ /* foreach cipher in list ... */
-+ for (cptr=clist;cptr->ciphername;cptr++) {
-+ /*
-+ * see if cipher has been disabled (0) or
-+ * if noauto set and not enabled (1)
-+ */
-+ if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
-+ if (debug>0)
-+ printk(KERN_INFO "setup_cipher_list(): "
-+ "ciphername=%s skipped at user request: "
-+ "noauto=%d parm[0]=%d parm[1]=%d\n"
-+ , cptr->ciphername
-+ , noauto
-+ , cptr->parm[0]
-+ , cptr->parm[1]);
-+ continue;
-+ }
-+ /*
-+ * use a local ci to avoid touching cptr->ci,
-+ * if register ipsec_alg success then bind cipher
-+ */
-+ if( setup_cipher(cptr->ciphername) ) {
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:"
-+ "setup_cipher_list():"
-+ "ciphername=%s found\n"
-+ , cptr->ciphername);
-+ if (setup_ipsec_alg_capi_cipher(cptr) == 0) {
-+
-+
-+ } else {
-+ printk(KERN_ERR "klips_debug:"
-+ "setup_cipher_list():"
-+ "ciphername=%s failed ipsec_alg_register\n"
-+ , cptr->ciphername);
-+ }
-+ } else {
-+ if (debug>0)
-+ printk(KERN_INFO "setup_cipher_list(): lookup for ciphername=%s: not found \n",
-+ cptr->ciphername);
-+ }
-+ }
-+ return 0;
-+}
-+/*
-+ * deregister ipsec_alg objects and unbind ciphers
-+ */
-+static int
-+unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
-+{
-+ struct ipsec_alg_capi_cipher *cptr;
-+ /* foreach cipher in list ... */
-+ for (cptr=clist;cptr->ciphername;cptr++) {
-+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
-+ unregister_ipsec_alg_enc(&cptr->alg);
-+ }
-+ }
-+ return 0;
-+}
-+/*
-+ * test loop for registered algos
-+ */
-+static int
-+test_cipher_list (struct ipsec_alg_capi_cipher* clist)
-+{
-+ int test_ret;
-+ struct ipsec_alg_capi_cipher *cptr;
-+ /* foreach cipher in list ... */
-+ for (cptr=clist;cptr->ciphername;cptr++) {
-+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
-+ test_ret=ipsec_alg_test(
-+ cptr->alg.ixt_alg_type,
-+ cptr->alg.ixt_alg_id,
-+ test);
-+ printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
-+ cptr->alg.ixt_alg_type,
-+ cptr->alg.ixt_alg_id,
-+ test_ret);
-+ }
-+ }
-+ return 0;
-+}
-+
-+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
-+{
-+ int ret, test_ret;
-+ if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
-+ return -EPROTONOSUPPORT;
-+ if (ret==0 && test) {
-+ test_ret=test_cipher_list(alg_capi_carray);
-+ }
-+ return ret;
-+}
-+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_cryptoapi_fini )
-+{
-+ unsetup_cipher_list(alg_capi_carray);
-+ return;
-+}
-+#ifdef MODULE_LICENSE
-+MODULE_LICENSE("GPL");
-+#endif
-+
-+EXPORT_NO_SYMBOLS;
-+#endif /* NO_CRYPTOAPI_SUPPORT */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_esp.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,558 @@
-+/*
-+ * processing code for ESP
-+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipsec_esp_c_version[] = "RCSID $Id$";
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define proto_priv cb
-+#endif /* NET21 */
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h"
-+#include "openswan/ipsec_xmit.h"
-+
-+#include "openswan/ipsec_auth.h"
-+
-+#ifdef CONFIG_IPSEC_ESP
-+#include "openswan/ipsec_esp.h"
-+#endif /* CONFIG_IPSEC_ESP */
-+
-+#include "openswan/ipsec_proto.h"
-+#include "openswan/ipsec_alg.h"
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_esp = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+
-+#ifdef CONFIG_IPSEC_ESP
-+enum ipsec_rcv_value
-+ipsec_rcv_esp_checks(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb)
-+{
-+ __u8 proto;
-+ int len; /* packet length */
-+
-+ len = skb->len;
-+ proto = irs->ipp->protocol;
-+
-+ /* XXX this will need to be 8 for IPv6 */
-+ if ((proto == IPPROTO_ESP) && ((len - irs->iphlen) % 4)) {
-+ printk("klips_error:ipsec_rcv: "
-+ "got packet with content length = %d from %s -- should be on 4 octet boundary, packet dropped\n",
-+ len - irs->iphlen,
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_BADLEN;
-+ }
-+
-+ if(skb->len < (irs->hard_header_len + sizeof(struct iphdr) + sizeof(struct esphdr))) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
-+ "klips_debug:ipsec_rcv: "
-+ "runt esp packet of skb->len=%d received from %s, dropped.\n",
-+ skb->len,
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_BADLEN;
-+ }
-+
-+ irs->protostuff.espstuff.espp = (struct esphdr *)(skb->data + irs->iphlen);
-+ irs->said.spi = irs->protostuff.espstuff.espp->esp_spi;
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+enum ipsec_rcv_value
-+ipsec_rcv_esp_decrypt_setup(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb,
-+ __u32 *replay,
-+ unsigned char **authenticator)
-+{
-+ struct esphdr *espp = irs->protostuff.espstuff.espp;
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "packet from %s received with seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n",
-+ irs->ipsaddr_txt,
-+ (__u32)ntohl(espp->esp_rpl),
-+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) )),
-+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)),
-+ irs->len,
-+ irs->ilen,
-+ irs->sa_len ? irs->sa : " (error)");
-+
-+ *replay = ntohl(espp->esp_rpl);
-+ *authenticator = &(skb->data[irs->len - irs->authlen]);
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+enum ipsec_rcv_value
-+ipsec_rcv_esp_authcalc(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb)
-+{
-+ struct auth_alg *aa;
-+ struct esphdr *espp = irs->protostuff.espstuff.espp;
-+ union {
-+ MD5_CTX md5;
-+ SHA1_CTX sha1;
-+ } tctx;
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if (irs->ipsp->ips_alg_auth) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "ipsec_alg hashing proto=%d... ",
-+ irs->said.proto);
-+ if(irs->said.proto == IPPROTO_ESP) {
-+ ipsec_alg_sa_esp_hash(irs->ipsp,
-+ (caddr_t)espp, irs->ilen,
-+ irs->hash, AHHMAC_HASHLEN);
-+ return IPSEC_RCV_OK;
-+ }
-+ return IPSEC_RCV_BADPROTO;
-+ }
-+#endif
-+ aa = irs->authfuncs;
-+
-+ /* copy the initialized keying material */
-+ memcpy(&tctx, irs->ictx, irs->ictx_len);
-+
-+ (*aa->update)((void *)&tctx, (caddr_t)espp, irs->ilen);
-+
-+ (*aa->final)(irs->hash, (void *)&tctx);
-+
-+ memcpy(&tctx, irs->octx, irs->octx_len);
-+
-+ (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
-+ (*aa->final)(irs->hash, (void *)&tctx);
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+
-+enum ipsec_rcv_value
-+ipsec_rcv_esp_decrypt(struct ipsec_rcv_state *irs)
-+{
-+ struct ipsec_sa *ipsp = irs->ipsp;
-+ struct esphdr *espp = irs->protostuff.espstuff.espp;
-+ int esphlen = 0;
-+ __u8 *idat; /* pointer to content to be decrypted/authenticated */
-+ __u32 iv[2];
-+ int pad = 0, padlen;
-+ int badpad = 0;
-+ int i;
-+ struct sk_buff *skb;
-+#ifdef CONFIG_IPSEC_ALG
-+ struct ipsec_alg_enc *ixt_e=NULL;
-+#endif /* CONFIG_IPSEC_ALG */
-+
-+ skb=irs->skb;
-+
-+ idat = skb->data + irs->iphlen;
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if ((ixt_e=ipsp->ips_alg_enc)) {
-+ esphlen = ESP_HEADER_LEN + ixt_e->ixt_ivlen/8;
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "encalg=%d esphlen=%d\n",
-+ ipsp->ips_encalg, esphlen);
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ipsp->ips_encalg) {
-+ case ESP_3DES:
-+ iv[0] = *((__u32 *)(espp->esp_iv) );
-+ iv[1] = *((__u32 *)(espp->esp_iv) + 1);
-+ esphlen = sizeof(struct esphdr);
-+ break;
-+ default:
-+ ipsp->ips_errs.ips_alg_errs += 1;
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_ESP_BADALG;
-+ }
-+
-+ idat += esphlen;
-+ irs->ilen -= esphlen;
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if (ixt_e)
-+ {
-+ if (ipsec_alg_esp_encrypt(ipsp,
-+ idat, irs->ilen, espp->esp_iv,
-+ IPSEC_ALG_DECRYPT) <= 0)
-+ {
-+ printk("klips_error:ipsec_rcv: "
-+ "got packet with esplen = %d "
-+ "from %s -- should be on "
-+ "ENC(%d) octet boundary, "
-+ "packet dropped\n",
-+ irs->ilen,
-+ irs->ipsaddr_txt,
-+ ipsp->ips_encalg);
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_BAD_DECRYPT;
-+ }
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ipsp->ips_encalg) {
-+ case ESP_3DES:
-+ if ((irs->ilen) % 8) {
-+ ipsp->ips_errs.ips_encsize_errs += 1;
-+ printk("klips_error:ipsec_rcv: "
-+ "got packet with esplen = %d from %s -- should be on 8 octet boundary, packet dropped\n",
-+ irs->ilen,
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_3DES_BADBLOCKING;
-+ }
-+ des_ede3_cbc_encrypt((des_cblock *)idat,
-+ (des_cblock *)idat,
-+ irs->ilen,
-+ ((struct des_eks *)(ipsp->ips_key_e))[0].ks,
-+ ((struct des_eks *)(ipsp->ips_key_e))[1].ks,
-+ ((struct des_eks *)(ipsp->ips_key_e))[2].ks,
-+ (des_cblock *)iv, 0);
-+ break;
-+ }
-+
-+ ipsec_rcv_dmp("postdecrypt", skb->data, skb->len);
-+
-+ irs->next_header = idat[irs->ilen - 1];
-+ padlen = idat[irs->ilen - 2];
-+ pad = padlen + 2 + irs->authlen;
-+
-+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
-+ "klips_debug:ipsec_rcv: "
-+ "padlen=%d, contents: 0x<offset>: 0x<value> 0x<value> ...\n",
-+ padlen);
-+
-+ for (i = 1; i <= padlen; i++) {
-+ if((i % 16) == 1) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
-+ "klips_debug: %02x:",
-+ i - 1);
-+ }
-+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
-+ " %02x",
-+ idat[irs->ilen - 2 - padlen + i - 1]);
-+ if(i != idat[irs->ilen - 2 - padlen + i - 1]) {
-+ badpad = 1;
-+ }
-+ if((i % 16) == 0) {
-+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
-+ "\n");
-+ }
-+ }
-+ if((i % 16) != 1) {
-+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
-+ "\n");
-+ }
-+ if(badpad) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
-+ "klips_debug:ipsec_rcv: "
-+ "warning, decrypted packet from %s has bad padding\n",
-+ irs->ipsaddr_txt);
-+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
-+ "klips_debug:ipsec_rcv: "
-+ "...may be bad decryption -- not dropped\n");
-+ ipsp->ips_errs.ips_encpad_errs += 1;
-+ }
-+
-+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
-+ "klips_debug:ipsec_rcv: "
-+ "packet decrypted from %s: next_header = %d, padding = %d\n",
-+ irs->ipsaddr_txt,
-+ irs->next_header,
-+ pad - 2 - irs->authlen);
-+
-+ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - (esphlen + pad));
-+
-+ /*
-+ * move the IP header forward by the size of the ESP header, which
-+ * will remove the the ESP header from the packet.
-+ */
-+ memmove((void *)(skb->data + esphlen),
-+ (void *)(skb->data), irs->iphlen);
-+
-+ ipsec_rcv_dmp("esp postmove", skb->data, skb->len);
-+
-+ /* skb_pull below, will move up by esphlen */
-+
-+ /* XXX not clear how this can happen, as the message indicates */
-+ if(skb->len < esphlen) {
-+ printk(KERN_WARNING
-+ "klips_error:ipsec_rcv: "
-+ "tried to skb_pull esphlen=%d, %d available. This should never happen, please report.\n",
-+ esphlen, (int)(skb->len));
-+ return IPSEC_RCV_ESP_DECAPFAIL;
-+ }
-+ skb_pull(skb, esphlen);
-+
-+ irs->ipp = (struct iphdr *)skb->data;
-+
-+ ipsec_rcv_dmp("esp postpull", skb->data, skb->len);
-+
-+ /* now, trip off the padding from the end */
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "trimming to %d.\n",
-+ irs->len - esphlen - pad);
-+ if(pad + esphlen <= irs->len) {
-+ skb_trim(skb, irs->len - esphlen - pad);
-+ } else {
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "bogus packet, size is zero or negative, dropping.\n");
-+ return IPSEC_RCV_DECAPFAIL;
-+ }
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_esp_setup(struct ipsec_xmit_state *ixs)
-+{
-+ __u32 iv[2];
-+ struct esphdr *espp;
-+ int ilen = 0;
-+ int padlen = 0, i;
-+ unsigned char *dat;
-+ unsigned char *idat, *pad;
-+ __u8 hash[AH_AMAX];
-+ union {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ MD5_CTX md5;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ SHA1_CTX sha1;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ } tctx;
-+
-+ dat = (unsigned char *)ixs->iph;
-+
-+ espp = (struct esphdr *)(dat + ixs->iphlen);
-+ espp->esp_spi = ixs->ipsp->ips_said.spi;
-+ espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
-+
-+ switch(ixs->ipsp->ips_encalg) {
-+#if defined(CONFIG_IPSEC_ENC_3DES)
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ iv[0] = *((__u32*)&(espp->esp_iv) ) =
-+ ((__u32*)(ixs->ipsp->ips_iv))[0];
-+ iv[1] = *((__u32*)&(espp->esp_iv) + 1) =
-+ ((__u32*)(ixs->ipsp->ips_iv))[1];
-+ break;
-+#endif /* defined(CONFIG_IPSEC_ENC_3DES) */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_BADALG;
-+ }
-+
-+ idat = dat + ixs->iphlen + sizeof(struct esphdr);
-+ ilen = ixs->skb->len - (ixs->iphlen + sizeof(struct esphdr) + ixs->authlen);
-+
-+ /* Self-describing padding */
-+ pad = &dat[ixs->skb->len - ixs->tailroom];
-+ padlen = ixs->tailroom - 2 - ixs->authlen;
-+ for (i = 0; i < padlen; i++) {
-+ pad[i] = i + 1;
-+ }
-+ dat[ixs->skb->len - ixs->authlen - 2] = padlen;
-+
-+ dat[ixs->skb->len - ixs->authlen - 1] = ixs->iph->protocol;
-+ ixs->iph->protocol = IPPROTO_ESP;
-+
-+ switch(ixs->ipsp->ips_encalg) {
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+ des_ede3_cbc_encrypt((des_cblock *)idat,
-+ (des_cblock *)idat,
-+ ilen,
-+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[0].ks,
-+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[1].ks,
-+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[2].ks,
-+ (des_cblock *)iv, 1);
-+ break;
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_BADALG;
-+ }
-+
-+ switch(ixs->ipsp->ips_encalg) {
-+#if defined(CONFIG_IPSEC_ENC_3DES)
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ /* XXX update IV with the last 8 octets of the encryption */
-+#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK
-+ ((__u32*)(ixs->ipsp->ips_iv))[0] =
-+ ((__u32 *)(idat))[(ilen >> 2) - 2];
-+ ((__u32*)(ixs->ipsp->ips_iv))[1] =
-+ ((__u32 *)(idat))[(ilen >> 2) - 1];
-+#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
-+ prng_bytes(&ipsec_prng, (char *)ixs->ipsp->ips_iv, EMT_ESPDES_IV_SZ);
-+#endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
-+ break;
-+#endif /* defined(CONFIG_IPSEC_ENC_3DES) */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_BADALG;
-+ }
-+
-+ switch(ixs->ipsp->ips_authalg) {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5:
-+ ipsec_xmit_dmp("espp", (char*)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
-+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
-+ ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
-+ ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Final(hash, &tctx.md5);
-+ ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
-+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
-+ ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, hash, AHMD596_ALEN);
-+ ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Final(hash, &tctx.md5);
-+ ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
-+ memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
-+
-+ /* paranoid */
-+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
-+ memset((caddr_t)hash, 0, sizeof(*hash));
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA:
-+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
-+ SHA1Update(&tctx.sha1, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
-+ SHA1Final(hash, &tctx.sha1);
-+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
-+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
-+ SHA1Final(hash, &tctx.sha1);
-+ memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
-+
-+ /* paranoid */
-+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
-+ memset((caddr_t)hash, 0, sizeof(*hash));
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ case AH_NONE:
-+ break;
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_AH_BADALG;
-+ }
-+#ifdef NET_21
-+ ixs->skb->h.raw = (unsigned char*)espp;
-+#endif /* NET_21 */
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+
-+struct xform_functions esp_xform_funcs[]={
-+ { rcv_checks: ipsec_rcv_esp_checks,
-+ rcv_setup_auth: ipsec_rcv_esp_decrypt_setup,
-+ rcv_calc_auth: ipsec_rcv_esp_authcalc,
-+ rcv_decrypt: ipsec_rcv_esp_decrypt,
-+
-+ xmit_setup: ipsec_xmit_esp_setup,
-+ xmit_headroom: sizeof(struct esphdr),
-+ xmit_needtailroom: 1,
-+ },
-+};
-+
-+struct inet_protocol esp_protocol =
-+{
-+ ipsec_rcv, /* ESP handler */
-+ NULL, /* TUNNEL error control */
-+#ifdef NETDEV_25
-+ 1, /* no policy */
-+#else
-+ 0, /* next */
-+ IPPROTO_ESP, /* protocol ID */
-+ 0, /* copy */
-+ NULL, /* data */
-+ "ESP" /* name */
-+#endif
-+};
-+
-+
-+
-+#endif /* !CONFIG_IPSEC_ESP */
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.2 2004/04/06 02:49:25 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_init.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,531 @@
-+/*
-+ * @(#) Initialization code.
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998 - 2002 Richard Guy Briggs <rgb@freeswan.org>
-+ * 2001 - 2004 Michael Richardson <mcr@xelerance.com>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * /proc system code was split out into ipsec_proc.c after rev. 1.70.
-+ *
-+ */
-+
-+char ipsec_init_c_version[] = "RCSID $Id$";
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/in.h> /* struct sockaddr_in */
-+#include <linux/skbuff.h>
-+#include <linux/random.h> /* get_random_bytes() */
-+#include <openswan.h>
-+
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* 23_SPINLOCK */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* 23_SPINLOCK */
-+#endif /* SPINLOCK */
-+
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+#endif /* NET_21 */
-+
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#ifdef CONFIG_PROC_FS
-+# include <linux/proc_fs.h>
-+#endif /* CONFIG_PROC_FS */
-+
-+#ifdef NETLINK_SOCK
-+# include <linux/netlink.h>
-+#else
-+# include <net/netlink.h>
-+#endif
-+
-+#include "openswan/radij.h"
-+
-+#include "openswan/ipsec_life.h"
-+#include "openswan/ipsec_stats.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+
-+#include "openswan/ipsec_rcv.h"
-+#include "openswan/ipsec_ah.h"
-+#include "openswan/ipsec_esp.h"
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+# include "openswan/ipcomp.h"
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#include "openswan/ipsec_proto.h"
-+#include "openswan/ipsec_alg.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#if !defined(CONFIG_IPSEC_ESP) && !defined(CONFIG_IPSEC_AH)
-+#error "kernel configuration must include ESP or AH"
-+#endif
-+
-+/*
-+ * seems to be present in 2.4.10 (Linus), but also in some RH and other
-+ * distro kernels of a lower number.
-+ */
-+#ifdef MODULE_LICENSE
-+MODULE_LICENSE("GPL");
-+#endif
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_eroute = 0;
-+int debug_spi = 0;
-+int debug_netlink = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+struct prng ipsec_prng;
-+
-+extern int ipsec_device_event(struct notifier_block *dnot, unsigned long event, void *ptr);
-+/*
-+ * the following structure is required so that we receive
-+ * event notifications when network devices are enabled and
-+ * disabled (ifconfig up and down).
-+ */
-+static struct notifier_block ipsec_dev_notifier={
-+ ipsec_device_event,
-+ NULL,
-+ 0
-+};
-+
-+#ifdef CONFIG_SYSCTL
-+extern int ipsec_sysctl_register(void);
-+extern void ipsec_sysctl_unregister(void);
-+#endif
-+
-+static inline int
-+openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol)
-+{
-+#ifdef NETDEV_25
-+ return inet_add_protocol(prot, protocol);
-+#else
-+ inet_add_protocol(prot);
-+ return 0;
-+#endif
-+}
-+
-+static inline int
-+openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol)
-+{
-+#ifdef NETDEV_25
-+ return inet_del_protocol(prot, protocol);
-+#else
-+ inet_del_protocol(prot);
-+ return 0;
-+#endif
-+}
-+
-+/* void */
-+int
-+ipsec_init(void)
-+{
-+ int error = 0;
-+ unsigned char seed[256];
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ extern int des_check_key;
-+
-+ /* turn off checking of keys */
-+ des_check_key=0;
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+
-+ KLIPS_PRINT(1, "klips_info:ipsec_init: "
-+ "KLIPS startup, Openswan KLIPS IPsec stack version: %s\n",
-+ ipsec_version_code());
-+
-+ error |= ipsec_proc_init();
-+
-+#ifdef SPINLOCK
-+ ipsec_sadb.sadb_lock = SPIN_LOCK_UNLOCKED;
-+#else /* SPINLOCK */
-+ ipsec_sadb.sadb_lock = 0;
-+#endif /* SPINLOCK */
-+
-+#ifndef SPINLOCK
-+ tdb_lock.lock = 0;
-+ eroute_lock.lock = 0;
-+#endif /* !SPINLOCK */
-+
-+ error |= ipsec_sadb_init();
-+ error |= ipsec_radijinit();
-+
-+ error |= pfkey_init();
-+
-+ error |= register_netdevice_notifier(&ipsec_dev_notifier);
-+
-+#ifdef CONFIG_IPSEC_ESP
-+ openswan_inet_add_protocol(&esp_protocol, IPPROTO_ESP);
-+#endif /* CONFIG_IPSEC_ESP */
-+
-+#ifdef CONFIG_IPSEC_AH
-+ openswan_inet_add_protocol(&ah_protocol, IPPROTO_AH);
-+#endif /* CONFIG_IPSEC_AH */
-+
-+/* we never actually link IPCOMP to the stack */
-+#ifdef IPCOMP_USED_ALONE
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ openswan_inet_add_protocol(&comp_protocol, IPPROTO_COMP);
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+#endif
-+
-+ error |= ipsec_tunnel_init_devices();
-+
-+
-+#ifdef CONFIG_SYSCTL
-+ error |= ipsec_sysctl_register();
-+#endif
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ ipsec_alg_init();
-+#endif
-+
-+ get_random_bytes((void *)seed, sizeof(seed));
-+ prng_init(&ipsec_prng, seed, sizeof(seed));
-+
-+ return error;
-+}
-+
-+
-+/* void */
-+int
-+ipsec_cleanup(void)
-+{
-+ int error = 0;
-+
-+#ifdef CONFIG_SYSCTL
-+ ipsec_sysctl_unregister();
-+#endif
-+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
-+ "klips_debug:ipsec_cleanup: "
-+ "calling ipsec_tunnel_cleanup_devices.\n");
-+ error |= ipsec_tunnel_cleanup_devices();
-+
-+ KLIPS_PRINT(debug_netlink, "called ipsec_tunnel_cleanup_devices");
-+
-+/* we never actually link IPCOMP to the stack */
-+#ifdef IPCOMP_USED_ALONE
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ if (openswan_inet_del_protocol(&comp_protocol, IPPROTO_COMP) < 0)
-+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
-+ "comp close: can't remove protocol\n");
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+#endif /* IPCOMP_USED_ALONE */
-+
-+#ifdef CONFIG_IPSEC_AH
-+ if (openswan_inet_del_protocol(&ah_protocol, IPPROTO_AH) < 0)
-+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
-+ "ah close: can't remove protocol\n");
-+#endif /* CONFIG_IPSEC_AH */
-+
-+#ifdef CONFIG_IPSEC_ESP
-+ if (openswan_inet_del_protocol(&esp_protocol, IPPROTO_ESP) < 0)
-+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
-+ "esp close: can't remove protocol\n");
-+#endif /* CONFIG_IPSEC_ESP */
-+
-+ error |= unregister_netdevice_notifier(&ipsec_dev_notifier);
-+
-+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
-+ "klips_debug:ipsec_cleanup: "
-+ "calling ipsec_sadb_cleanup.\n");
-+ error |= ipsec_sadb_cleanup(0);
-+ error |= ipsec_sadb_free();
-+
-+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
-+ "klips_debug:ipsec_cleanup: "
-+ "calling ipsec_radijcleanup.\n");
-+ error |= ipsec_radijcleanup();
-+
-+ KLIPS_PRINT(debug_pfkey, /* debug_tunnel & DB_TN_INIT, */
-+ "klips_debug:ipsec_cleanup: "
-+ "calling pfkey_cleanup.\n");
-+ error |= pfkey_cleanup();
-+
-+ ipsec_proc_cleanup();
-+
-+ prng_final(&ipsec_prng);
-+
-+ return error;
-+}
-+
-+#ifdef MODULE
-+int
-+init_module(void)
-+{
-+ int error = 0;
-+
-+ error |= ipsec_init();
-+
-+ return error;
-+}
-+
-+int
-+cleanup_module(void)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
-+ "klips_debug:cleanup_module: "
-+ "calling ipsec_cleanup.\n");
-+
-+ error |= ipsec_cleanup();
-+
-+ KLIPS_PRINT(1, "klips_info:cleanup_module: "
-+ "ipsec module unloaded.\n");
-+
-+ return error;
-+}
-+#endif /* MODULE */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.93 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.92 2004/03/30 15:30:39 ken
-+ * Proper Capitalization
-+ *
-+ * Revision 1.91 2004/03/22 01:51:51 ken
-+ * We are open
-+ *
-+ * Revision 1.90.4.2 2004/04/05 04:30:46 mcr
-+ * patches for alg-branch to compile/work with 2.x openswan
-+ *
-+ * Revision 1.90.4.1 2003/12/22 15:25:52 jjo
-+ * Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.90 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.89.4.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.89 2003/07/31 22:47:16 mcr
-+ * preliminary (untested by FS-team) 2.5 patches.
-+ *
-+ * Revision 1.88 2003/06/22 20:05:36 mcr
-+ * clarified why IPCOMP was not being registered, and put a new
-+ * #ifdef in rather than #if 0.
-+ *
-+ * Revision 1.87 2002/09/20 15:40:51 rgb
-+ * Added a lock to the global ipsec_sadb struct for future use.
-+ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
-+ * of freeing newly created structures when clearing the reftable upon startup
-+ * to start from a known state.
-+ *
-+ * Revision 1.86 2002/08/15 18:39:15 rgb
-+ * Move ipsec_prng outside debug code.
-+ *
-+ * Revision 1.85 2002/05/14 02:35:29 rgb
-+ * Change reference to tdb to ipsa.
-+ *
-+ * Revision 1.84 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.83 2002/04/24 07:36:28 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_init.c,v
-+ *
-+ * Revision 1.82 2002/04/20 00:12:25 rgb
-+ * Added esp IV CBC attack fix, disabled.
-+ *
-+ * Revision 1.81 2002/04/09 16:13:32 mcr
-+ * switch license to straight GPL.
-+ *
-+ * Revision 1.80 2002/03/24 07:34:08 rgb
-+ * Sanity check for at least one of AH or ESP configured.
-+ *
-+ * Revision 1.79 2002/02/05 22:55:15 mcr
-+ * added MODULE_LICENSE declaration.
-+ * This macro does not appear in all kernel versions (see comment).
-+ *
-+ * Revision 1.78 2002/01/29 17:17:55 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.77 2002/01/29 04:00:51 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.76 2002/01/29 02:13:17 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.75 2001/11/26 09:23:48 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.74 2001/11/22 05:44:11 henry
-+ * new version stuff
-+ *
-+ * Revision 1.71.2.2 2001/10/22 20:51:00 mcr
-+ * explicitely set des_check_key.
-+ *
-+ * Revision 1.71.2.1 2001/09/25 02:19:39 mcr
-+ * /proc manipulation code moved to new ipsec_proc.c
-+ *
-+ * Revision 1.73 2001/11/06 19:47:17 rgb
-+ * Changed lifetime_packets to uint32 from uint64.
-+ *
-+ * Revision 1.72 2001/10/18 04:45:19 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/freeswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.71 2001/09/20 15:32:45 rgb
-+ * Minor pfkey lifetime fixes.
-+ *
-+ * Revision 1.70 2001/07/06 19:51:21 rgb
-+ * Added inbound policy checking code for IPIP SAs.
-+ *
-+ * Revision 1.69 2001/06/14 19:33:26 rgb
-+ * Silence startup message for console, but allow it to be logged.
-+ * Update copyright date.
-+ *
-+ * Revision 1.68 2001/05/29 05:14:36 rgb
-+ * Added PMTU to /proc/net/ipsec_tncfg output. See 'man 5 ipsec_tncfg'.
-+ *
-+ * Revision 1.67 2001/05/04 16:34:52 rgb
-+ * Rremove erroneous checking of return codes for proc_net_* in 2.4.
-+ *
-+ * Revision 1.66 2001/05/03 19:40:34 rgb
-+ * Check error return codes in startup and shutdown.
-+ *
-+ * Revision 1.65 2001/02/28 05:03:27 rgb
-+ * Clean up and rationalise startup messages.
-+ *
-+ * Revision 1.64 2001/02/27 22:24:53 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.63 2000/11/29 20:14:06 rgb
-+ * Add src= to the output of /proc/net/ipsec_spi and delete dst from IPIP.
-+ *
-+ * Revision 1.62 2000/11/06 04:31:24 rgb
-+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
-+ * Fixed longlong for pre-2.4 kernels (Svenning).
-+ * Add Svenning's adaptive content compression.
-+ * Disabled registration of ipcomp handler.
-+ *
-+ * Revision 1.61 2000/10/11 13:37:54 rgb
-+ * #ifdef out debug print that causes proc/net/ipsec_version to oops.
-+ *
-+ * Revision 1.60 2000/09/20 03:59:01 rgb
-+ * Change static info functions to DEBUG_NO_STATIC to reveal function names
-+ * in oopsen.
-+ *
-+ * Revision 1.59 2000/09/16 01:06:26 rgb
-+ * Added cast of var to silence compiler warning about long fed to int
-+ * format.
-+ *
-+ * Revision 1.58 2000/09/15 11:37:01 rgb
-+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
-+ * IPCOMP zlib deflate code.
-+ *
-+ * Revision 1.57 2000/09/12 03:21:50 rgb
-+ * Moved radij_c_version printing to ipsec_version_get_info().
-+ * Reformatted ipsec_version_get_info().
-+ * Added sysctl_{,un}register() calls.
-+ *
-+ * Revision 1.56 2000/09/08 19:16:50 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
-+ *
-+ * Revision 1.55 2000/08/30 05:19:03 rgb
-+ * Cleaned up no longer used spi_next, netlink register/unregister, other
-+ * minor cleanup.
-+ * Removed cruft replaced by TDB_XFORM_NAME.
-+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
-+ * Moved debug version strings to printk when /proc/net/ipsec_version is
-+ * called.
-+ *
-+ * Revision 1.54 2000/08/20 18:31:05 rgb
-+ * Changed cosmetic alignment in spi_info.
-+ * Changed addtime and usetime to use actual value which is relative
-+ * anyways, as intended. (Momchil)
-+ *
-+ * Revision 1.53 2000/08/18 17:37:03 rgb
-+ * Added an (int) cast to shut up the compiler...
-+ *
-+ * Revision 1.52 2000/08/01 14:51:50 rgb
-+ * Removed _all_ remaining traces of DES.
-+ *
-+ * Revision 1.51 2000/07/25 20:41:22 rgb
-+ * Removed duplicate parameter in spi_getinfo.
-+ *
-+ * Revision 1.50 2000/07/17 03:21:45 rgb
-+ * Removed /proc/net/ipsec_spinew.
-+ *
-+ * Revision 1.49 2000/06/28 05:46:51 rgb
-+ * Renamed ivlen to iv_bits for consistency.
-+ * Changed output of add and use times to be relative to now.
-+ *
-+ * Revision 1.48 2000/05/11 18:26:10 rgb
-+ * Commented out calls to netlink_attach/detach to avoid activating netlink
-+ * in the kenrel config.
-+ *
-+ * Revision 1.47 2000/05/10 22:35:26 rgb
-+ * Comment out most of the startup version information.
-+ *
-+ * Revision 1.46 2000/03/22 16:15:36 rgb
-+ * Fixed renaming of dev_get (MB).
-+ *
-+ * Revision 1.45 2000/03/16 06:40:48 rgb
-+ * Hardcode PF_KEYv2 support.
-+ *
-+ * Revision 1.44 2000/01/22 23:19:20 rgb
-+ * Simplified code to use existing macro TDB_XFORM_NAME().
-+ *
-+ * Revision 1.43 2000/01/21 06:14:04 rgb
-+ * Print individual stats only if non-zero.
-+ * Removed 'bits' from each keylength for brevity.
-+ * Shortened lifetimes legend for brevity.
-+ * Changed wording from 'last_used' to the clearer 'idle'.
-+ *
-+ * Revision 1.42 1999/12/31 14:57:19 rgb
-+ * MB fix for new dummy-less proc_get_info in 2.3.35.
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_ipcomp.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,276 @@
-+/*
-+ * processing code for IPCOMP
-+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipsec_ipcomp_c_version[] = "RCSID $Id$";
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define proto_priv cb
-+#endif /* NET21 */
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h"
-+#include "openswan/ipsec_xmit.h"
-+
-+#include "openswan/ipsec_auth.h"
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+#include "openswan/ipsec_ipcomp.h"
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#include "openswan/ipsec_proto.h"
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_ipcomp = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+enum ipsec_rcv_value
-+ipsec_rcv_ipcomp_checks(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb)
-+{
-+ int ipcompminlen;
-+
-+ ipcompminlen = irs->hard_header_len + sizeof(struct iphdr);
-+
-+ if(skb->len < (ipcompminlen + sizeof(struct ipcomphdr))) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
-+ "klips_debug:ipsec_rcv: "
-+ "runt comp packet of skb->len=%d received from %s, dropped.\n",
-+ skb->len,
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_BADLEN;
-+ }
-+
-+ irs->protostuff.ipcompstuff.compp = (struct ipcomphdr *)(skb->data + irs->iphlen);
-+ irs->said.spi = htonl((__u32)ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi));
-+ return IPSEC_RCV_OK;
-+}
-+
-+enum ipsec_rcv_value
-+ipsec_rcv_ipcomp_decomp(struct ipsec_rcv_state *irs)
-+{
-+ unsigned int flags = 0;
-+ struct ipsec_sa *ipsp = irs->ipsp;
-+ struct sk_buff *skb;
-+
-+ skb=irs->skb;
-+
-+ ipsec_xmit_dmp("ipcomp", skb->data, skb->len);
-+
-+ if(ipsp == NULL) {
-+ return IPSEC_RCV_SAIDNOTFOUND;
-+ }
-+
-+#if 0
-+ /* we want to check that this wasn't the first SA on the list, because
-+ * we don't support bare IPCOMP, for unexplained reasons. MCR
-+ */
-+ if (ipsp->ips_onext != NULL) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "Incoming packet with outer IPCOMP header SA:%s: not yet supported by KLIPS, dropped\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+
-+ return IPSEC_RCV_IPCOMPALONE;
-+ }
-+#endif
-+
-+ if(sysctl_ipsec_inbound_policy_check &&
-+ ((((ntohl(ipsp->ips_said.spi) & 0x0000ffff) != ntohl(irs->said.spi)) &&
-+ (ipsp->ips_encalg != ntohl(irs->said.spi)) /* this is a workaround for peer non-compliance with rfc2393 */
-+ ))) {
-+ char sa2[SATOT_BUF];
-+ size_t sa_len2 = 0;
-+
-+ sa_len2 = satot(&ipsp->ips_said, 0, sa2, sizeof(sa2));
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "Incoming packet with SA(IPCA):%s does not match policy SA(IPCA):%s cpi=%04x cpi->spi=%08x spi=%08x, spi->cpi=%04x for SA grouping, dropped.\n",
-+ irs->sa_len ? irs->sa : " (error)",
-+ ipsp != NULL ? (sa_len2 ? sa2 : " (error)") : "NULL",
-+ ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi),
-+ (__u32)ntohl(irs->said.spi),
-+ ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
-+ ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0);
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_SAIDNOTFOUND;
-+ }
-+
-+ ipsp->ips_comp_ratio_cbytes += ntohs(irs->ipp->tot_len);
-+ irs->next_header = irs->protostuff.ipcompstuff.compp->ipcomp_nh;
-+
-+ skb = skb_decompress(skb, ipsp, &flags);
-+ if (!skb || flags) {
-+ spin_unlock(&tdb_lock);
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "skb_decompress() returned error flags=%x, dropped.\n",
-+ flags);
-+ if (irs->stats) {
-+ if (flags)
-+ irs->stats->rx_errors++;
-+ else
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_IPCOMPFAILED;
-+ }
-+
-+ /* make sure we update the pointer */
-+ irs->skb = skb;
-+
-+#ifdef NET_21
-+ irs->ipp = skb->nh.iph;
-+#else /* NET_21 */
-+ irs->ipp = skb->ip_hdr;
-+#endif /* NET_21 */
-+
-+ ipsp->ips_comp_ratio_dbytes += ntohs(irs->ipp->tot_len);
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "packet decompressed SA(IPCA):%s cpi->spi=%08x spi=%08x, spi->cpi=%04x, nh=%d.\n",
-+ irs->sa_len ? irs->sa : " (error)",
-+ (__u32)ntohl(irs->said.spi),
-+ ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
-+ ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0,
-+ irs->next_header);
-+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, irs->ipp);
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_ipcomp_setup(struct ipsec_xmit_state *ixs)
-+{
-+ unsigned int flags = 0;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
-+
-+ ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
-+
-+#ifdef NET_21
-+ ixs->iph = ixs->skb->nh.iph;
-+#else /* NET_21 */
-+ ixs->iph = ixs->skb->ip_hdr;
-+#endif /* NET_21 */
-+
-+ ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (debug_tunnel & DB_TN_CROUT)
-+ {
-+ if (old_tot_len > ntohs(ixs->iph->tot_len))
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_once: "
-+ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
-+ old_tot_len, ntohs(ixs->iph->tot_len),
-+ ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
-+ ntohl(ixs->ipsp->ips_said.spi),
-+ (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
-+ else
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_once: "
-+ "packet did not compress (flags = %d).\n",
-+ flags);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+struct xform_functions ipcomp_xform_funcs[]={
-+ {rcv_checks: ipsec_rcv_ipcomp_checks,
-+ rcv_decrypt: ipsec_rcv_ipcomp_decomp,
-+ xmit_setup: ipsec_xmit_ipcomp_setup,
-+ xmit_headroom: 0,
-+ xmit_needtailroom: 0,
-+ },
-+};
-+
-+#if 0
-+/* We probably don't want to install a pure IPCOMP protocol handler, but
-+ only want to handle IPCOMP if it is encapsulated inside an ESP payload
-+ (which is already handled) */
-+#ifdef CONFIG_IPSEC_IPCOMP
-+struct inet_protocol comp_protocol =
-+{
-+ ipsec_rcv, /* COMP handler */
-+ NULL, /* COMP error control */
-+#ifdef NETDEV_25
-+ 1, /* no policy */
-+#else
-+ 0, /* next */
-+ IPPROTO_COMP, /* protocol ID */
-+ 0, /* copy */
-+ NULL, /* data */
-+ "COMP" /* name */
-+#endif
-+};
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+#endif
-+
-+#endif /* CONFIG_IPSEC_IPCOMP */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_ipip.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,133 @@
-+/*
-+ * processing code for IPIP
-+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipsec_ipip_c_version[] = "RCSID $Id$";
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define proto_priv cb
-+#endif /* NET21 */
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h"
-+#include "openswan/ipsec_xmit.h"
-+
-+#include "openswan/ipsec_auth.h"
-+#include "openswan/ipsec_ipip.h"
-+#include "openswan/ipsec_param.h"
-+
-+#include "openswan/ipsec_proto.h"
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_ipip_setup(struct ipsec_xmit_state *ixs)
-+{
-+ ixs->iph->version = 4;
-+
-+ switch(sysctl_ipsec_tos) {
-+ case 0:
-+#ifdef NET_21
-+ ixs->iph->tos = ixs->skb->nh.iph->tos;
-+#else /* NET_21 */
-+ ixs->iph->tos = ixs->skb->ip_hdr->tos;
-+#endif /* NET_21 */
-+ break;
-+ case 1:
-+ ixs->iph->tos = 0;
-+ break;
-+ default:
-+ break;
-+ }
-+#ifdef NET_21
-+#ifdef NETDEV_23
-+ ixs->iph->ttl = sysctl_ip_default_ttl;
-+#else /* NETDEV_23 */
-+ ixs->iph->ttl = ip_statistics.IpDefaultTTL;
-+#endif /* NETDEV_23 */
-+#else /* NET_21 */
-+ ixs->iph->ttl = 64; /* ip_statistics.IpDefaultTTL; */
-+#endif /* NET_21 */
-+ ixs->iph->frag_off = 0;
-+ ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
-+ ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
-+ ixs->iph->protocol = IPPROTO_IPIP;
-+ ixs->iph->ihl = sizeof(struct iphdr) >> 2;
-+
-+ KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
-+
-+ ixs->newdst = (__u32)ixs->iph->daddr;
-+ ixs->newsrc = (__u32)ixs->iph->saddr;
-+
-+#ifdef NET_21
-+ ixs->skb->h.ipiph = ixs->skb->nh.iph;
-+#endif /* NET_21 */
-+ return IPSEC_XMIT_OK;
-+}
-+
-+struct xform_functions ipip_xform_funcs[]={
-+ { rcv_checks: NULL,
-+ rcv_setup_auth: NULL,
-+ rcv_calc_auth: NULL,
-+ rcv_decrypt: NULL,
-+
-+ xmit_setup: ipsec_xmit_ipip_setup,
-+ xmit_headroom: sizeof(struct iphdr),
-+ xmit_needtailroom: 0,
-+ },
-+};
-+
-+
-+
-+
-+
-+
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_life.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,263 @@
-+/*
-+ * @(#) lifetime structure utilities
-+ *
-+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ * and Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ */
-+
-+/*
-+ * This provides series of utility functions for dealing with lifetime
-+ * structures.
-+ *
-+ * ipsec_check_lifetime - returns -1 hard lifetime exceeded
-+ * 0 soft lifetime exceeded
-+ * 1 everything is okay
-+ * based upon whether or not the count exceeds hard/soft
-+ *
-+ */
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/config.h> /* for CONFIG_IP_FORWARD */
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_life.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_eroute.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+
-+#include "openswan/ipsec_sa.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_ipe4.h"
-+#include "openswan/ipsec_ah.h"
-+#include "openswan/ipsec_esp.h"
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+#include "openswan/ipcomp.h"
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+
-+
-+enum ipsec_life_alive
-+ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
-+ const char *lifename,
-+ const char *saname,
-+ enum ipsec_life_type ilt,
-+ enum ipsec_direction idir,
-+ struct ipsec_sa *ips)
-+{
-+ __u64 count;
-+ const char *dir;
-+
-+ if(saname == NULL) {
-+ saname = "unknown-SA";
-+ }
-+
-+ if(idir == ipsec_incoming) {
-+ dir = "incoming";
-+ } else {
-+ dir = "outgoing";
-+ }
-+
-+
-+ if(ilt == ipsec_life_timebased) {
-+ count = jiffies/HZ - il64->ipl_count;
-+ } else {
-+ count = il64->ipl_count;
-+ }
-+
-+ if(il64->ipl_hard &&
-+ (count > il64->ipl_hard)) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_lifetime_check: "
-+ "hard %s lifetime of SA:<%s%s%s> %s has been reached, SA expired, "
-+ "%s packet dropped.\n",
-+ lifename,
-+ IPS_XFORM_NAME(ips),
-+ saname,
-+ dir);
-+
-+ pfkey_expire(ips, 1);
-+ return ipsec_life_harddied;
-+ }
-+
-+ if(il64->ipl_soft &&
-+ (count > il64->ipl_soft)) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_lifetime_check: "
-+ "soft %s lifetime of SA:<%s%s%s> %s has been reached, SA expiring, "
-+ "soft expire message sent up, %s packet still processed.\n",
-+ lifename,
-+ IPS_XFORM_NAME(ips),
-+ saname,
-+ dir);
-+
-+ if(ips->ips_state != SADB_SASTATE_DYING) {
-+ pfkey_expire(ips, 0);
-+ }
-+ ips->ips_state = SADB_SASTATE_DYING;
-+
-+ return ipsec_life_softdied;
-+ }
-+ return ipsec_life_okay;
-+}
-+
-+
-+/*
-+ * This function takes a buffer (with length), a lifetime name and type,
-+ * and formats a string to represent the current values of the lifetime.
-+ *
-+ * It returns the number of bytes that the format took (or would take,
-+ * if the buffer were large enough: snprintf semantics).
-+ * This is used in /proc routines and in debug output.
-+ */
-+int
-+ipsec_lifetime_format(char *buffer,
-+ int buflen,
-+ char *lifename,
-+ enum ipsec_life_type timebaselife,
-+ struct ipsec_lifetime64 *lifetime)
-+{
-+ int len = 0;
-+ __u64 count;
-+
-+ if(timebaselife == ipsec_life_timebased) {
-+ count = jiffies/HZ - lifetime->ipl_count;
-+ } else {
-+ count = lifetime->ipl_count;
-+ }
-+
-+ if(lifetime->ipl_count > 1 ||
-+ lifetime->ipl_soft ||
-+ lifetime->ipl_hard) {
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
-+ len = ipsec_snprintf(buffer, buflen,
-+ "%s(%Lu,%Lu,%Lu)",
-+ lifename,
-+ count,
-+ lifetime->ipl_soft,
-+ lifetime->ipl_hard);
-+#else /* XXX high 32 bits are not displayed */
-+ len = ipsec_snprintf(buffer, buflen,
-+ "%s(%lu,%lu,%lu)",
-+ lifename,
-+ (unsigned long)count,
-+ (unsigned long)lifetime->ipl_soft,
-+ (unsigned long)lifetime->ipl_hard);
-+#endif
-+ }
-+
-+ return len;
-+}
-+
-+void
-+ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
-+ __u64 newvalue)
-+{
-+ if(newvalue &&
-+ (!lifetime->ipl_hard ||
-+ (newvalue < lifetime->ipl_hard))) {
-+ lifetime->ipl_hard = newvalue;
-+
-+ if(!lifetime->ipl_soft &&
-+ (lifetime->ipl_hard < lifetime->ipl_soft)) {
-+ lifetime->ipl_soft = lifetime->ipl_hard;
-+ }
-+ }
-+}
-+
-+void
-+ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
-+ __u64 newvalue)
-+{
-+ if(newvalue &&
-+ (!lifetime->ipl_soft ||
-+ (newvalue < lifetime->ipl_soft))) {
-+ lifetime->ipl_soft = newvalue;
-+
-+ if(lifetime->ipl_hard &&
-+ (lifetime->ipl_hard < lifetime->ipl_soft)) {
-+ lifetime->ipl_soft = lifetime->ipl_hard;
-+ }
-+ }
-+}
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.12 2004/04/23 20:44:35 ken
-+ * Update comments
-+ *
-+ * Revision 1.11 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.10 2004/03/30 11:03:10 paul
-+ * two more occurances of snprintf, found by Sam from a users oops msg.
-+ *
-+ * Revision 1.9 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.8.4.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.8 2003/02/06 02:00:10 rgb
-+ * Fixed incorrect debugging text label
-+ *
-+ * Revision 1.7 2002/05/23 07:16:26 rgb
-+ * Fixed absolute/relative reference to lifetime count printout.
-+ *
-+ * Revision 1.6 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.5 2002/04/24 07:36:28 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_life.c,v
-+ *
-+ * Revision 1.4 2002/01/29 17:17:55 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.3 2002/01/29 02:13:17 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.2 2001/11/26 09:16:14 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:25:57 mcr
-+ * lifetime structure created and common functions created.
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_mast.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1080 @@
-+/*
-+ * IPSEC MAST code.
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipsec_mast_c_version[] = "RCSID $Id$";
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/config.h> /* for CONFIG_IP_FORWARD */
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "freeswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/tcp.h> /* struct tcphdr */
-+#include <linux/udp.h> /* struct udphdr */
-+#include <linux/skbuff.h>
-+#include <freeswan.h>
-+#include <asm/uaccess.h>
-+#include <linux/in6.h>
-+#include <net/dst.h>
-+#undef dev_kfree_skb
-+#define dev_kfree_skb(a,b) kfree_skb(a)
-+#define PHYSDEV_TYPE
-+#include <asm/checksum.h>
-+#include <net/icmp.h> /* icmp_send() */
-+#include <net/ip.h>
-+#include <linux/netfilter_ipv4.h>
-+
-+#include <linux/if_arp.h>
-+
-+#include "freeswan/radij.h"
-+#include "freeswan/ipsec_life.h"
-+#include "freeswan/ipsec_xform.h"
-+#include "freeswan/ipsec_eroute.h"
-+#include "freeswan/ipsec_encap.h"
-+#include "freeswan/ipsec_radij.h"
-+#include "freeswan/ipsec_sa.h"
-+#include "freeswan/ipsec_tunnel.h"
-+#include "freeswan/ipsec_mast.h"
-+#include "freeswan/ipsec_ipe4.h"
-+#include "freeswan/ipsec_ah.h"
-+#include "freeswan/ipsec_esp.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "freeswan/ipsec_proto.h"
-+
-+int ipsec_maxdevice_count = -1;
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_open(struct device *dev)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ /*
-+ * Can't open until attached.
-+ */
-+
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_open: "
-+ "dev = %s, prv->dev = %s\n",
-+ dev->name, prv->dev?prv->dev->name:"NONE");
-+
-+ if (prv->dev == NULL)
-+ return -ENODEV;
-+
-+ MOD_INC_USE_COUNT;
-+ return 0;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_close(struct device *dev)
-+{
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static inline int ipsec_mast_xmit2(struct sk_buff *skb)
-+{
-+ return ip_send(skb);
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_mast_send(struct ipsec_xmit_state*ixs)
-+{
-+ /* new route/dst cache code from James Morris */
-+ ixs->skb->dev = ixs->physdev;
-+ /*skb_orphan(ixs->skb);*/
-+ if((ixs->error = ip_route_output(&ixs->route,
-+ ixs->skb->nh.iph->daddr,
-+ ixs->pass ? 0 : ixs->skb->nh.iph->saddr,
-+ RT_TOS(ixs->skb->nh.iph->tos),
-+ ixs->physdev->iflink /* rgb: should this be 0? */))) {
-+ ixs->stats->tx_errors++;
-+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
-+ "klips_debug:ipsec_xmit_send: "
-+ "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
-+ ixs->error,
-+ ixs->route->u.dst.dev->name);
-+ return IPSEC_XMIT_ROUTEERR;
-+ }
-+ if(ixs->dev == ixs->route->u.dst.dev) {
-+ ip_rt_put(ixs->route);
-+ /* This is recursion, drop it. */
-+ ixs->stats->tx_errors++;
-+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
-+ "klips_debug:ipsec_xmit_send: "
-+ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
-+ ixs->dev->name);
-+ return IPSEC_XMIT_RECURSDETECT;
-+ }
-+ dst_release(ixs->skb->dst);
-+ ixs->skb->dst = &ixs->route->u.dst;
-+ ixs->stats->tx_bytes += ixs->skb->len;
-+ if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {
-+ ixs->stats->tx_errors++;
-+ printk(KERN_WARNING
-+ "klips_error:ipsec_xmit_send: "
-+ "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
-+ (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),
-+ ixs->skb->len);
-+ return IPSEC_XMIT_PUSHPULLERR;
-+ }
-+ __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);
-+#ifdef SKB_RESET_NFCT
-+ nf_conntrack_put(ixs->skb->nfct);
-+ ixs->skb->nfct = NULL;
-+#ifdef CONFIG_NETFILTER_DEBUG
-+ ixs->skb->nf_debug = 0;
-+#endif /* CONFIG_NETFILTER_DEBUG */
-+#endif /* SKB_RESET_NFCT */
-+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
-+ "klips_debug:ipsec_xmit_send: "
-+ "...done, calling ip_send() on device:%s\n",
-+ ixs->skb->dev ? ixs->skb->dev->name : "NULL");
-+ KLIPS_IP_PRINT(debug_mast & DB_MAST_XMIT, ixs->skb->nh.iph);
-+ {
-+ int err;
-+
-+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,
-+ ipsec_mast_xmit2);
-+ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
-+ if(net_ratelimit())
-+ printk(KERN_ERR
-+ "klips_error:ipsec_xmit_send: "
-+ "ip_send() failed, err=%d\n",
-+ -err);
-+ ixs->stats->tx_errors++;
-+ ixs->stats->tx_aborted_errors++;
-+ ixs->skb = NULL;
-+ return IPSEC_XMIT_IPSENDFAILURE;
-+ }
-+ }
-+ ixs->stats->tx_packets++;
-+
-+ ixs->skb = NULL;
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+void
-+ipsec_mast_cleanup(struct ipsec_xmit_state*ixs)
-+{
-+#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
-+ netif_wake_queue(ixs->dev);
-+#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
-+ ixs->dev->tbusy = 0;
-+#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
-+ if(ixs->saved_header) {
-+ kfree(ixs->saved_header);
-+ }
-+ if(ixs->skb) {
-+ dev_kfree_skb(ixs->skb, FREE_WRITE);
-+ }
-+ if(ixs->oskb) {
-+ dev_kfree_skb(ixs->oskb, FREE_WRITE);
-+ }
-+ if (ixs->ips.ips_ident_s.data) {
-+ kfree(ixs->ips.ips_ident_s.data);
-+ }
-+ if (ixs->ips.ips_ident_d.data) {
-+ kfree(ixs->ips.ips_ident_d.data);
-+ }
-+}
-+
-+#if 0
-+/*
-+ * This function assumes it is being called from dev_queue_xmit()
-+ * and that skb is filled properly by that function.
-+ */
-+int
-+ipsec_mast_start_xmit(struct sk_buff *skb, struct device *dev, IPsecSAref_t SAref)
-+{
-+ struct ipsec_xmit_state ixs_mem;
-+ struct ipsec_xmit_state *ixs = &ixs_mem;
-+ enum ipsec_xmit_value stat = IPSEC_XMIT_OK;
-+
-+ /* dev could be a mast device, but should be optional, I think... */
-+ /* SAref is also optional, but one of the two must be present. */
-+ /* I wonder if it could accept no device or saref and guess? */
-+
-+/* ipsec_xmit_sanity_check_dev(ixs); */
-+
-+ ipsec_xmit_sanity_check_skb(ixs);
-+
-+ ipsec_xmit_adjust_hard_header(ixs);
-+
-+ stat = ipsec_xmit_encap_bundle(ixs);
-+ if(stat != IPSEC_XMIT_OK) {
-+ /* SA processing failed */
-+ }
-+
-+ ipsec_xmit_hard_header_restore();
-+}
-+#endif
-+
-+DEBUG_NO_STATIC struct net_device_stats *
-+ipsec_mast_get_stats(struct device *dev)
-+{
-+ return &(((struct ipsecpriv *)(dev->priv))->mystats);
-+}
-+
-+/*
-+ * Revectored calls.
-+ * For each of these calls, a field exists in our private structure.
-+ */
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_hard_header(struct sk_buff *skb, struct device *dev,
-+ unsigned short type, void *daddr, void *saddr, unsigned len)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+ struct device *tmp;
-+ int ret;
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(skb == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_hard_header: "
-+ "no skb...\n");
-+ return -ENODATA;
-+ }
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_hard_header: "
-+ "no device...\n");
-+ return -ENODEV;
-+ }
-+
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_hard_header: "
-+ "skb->dev=%s dev=%s.\n",
-+ skb->dev ? skb->dev->name : "NULL",
-+ dev->name);
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_hard_header: "
-+ "no private space associated with dev=%s\n",
-+ dev->name ? dev->name : "NULL");
-+ return -ENODEV;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_hard_header: "
-+ "no physical device associated with dev=%s\n",
-+ dev->name ? dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+ /* check if we have to send a IPv6 packet. It might be a Router
-+ Solicitation, where the building of the packet happens in
-+ reverse order:
-+ 1. ll hdr,
-+ 2. IPv6 hdr,
-+ 3. ICMPv6 hdr
-+ -> skb->nh.raw is still uninitialized when this function is
-+ called!! If this is no IPv6 packet, we can print debugging
-+ messages, otherwise we skip all debugging messages and just
-+ build the ll header */
-+ if(type != ETH_P_IPV6) {
-+ /* execute this only, if we don't have to build the
-+ header for a IPv6 packet */
-+ if(!prv->hard_header) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_hard_header: "
-+ "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
-+ saddr,
-+ daddr,
-+ len,
-+ type,
-+ dev->name);
-+ KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->nh.iph->saddr),
-+ (__u32)ntohl(skb->nh.iph->daddr) );
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+#define da ((struct device *)(prv->dev))->dev_addr
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_hard_header: "
-+ "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
-+ saddr,
-+ daddr,
-+ len,
-+ type,
-+ dev->name,
-+ prv->dev->name,
-+ da[0], da[1], da[2], da[3], da[4], da[5]);
-+ KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->nh.iph->saddr),
-+ (__u32)ntohl(skb->nh.iph->daddr) );
-+ } else {
-+ KLIPS_PRINT(debug_mast,
-+ "klips_debug:ipsec_mast_hard_header: "
-+ "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
-+ }
-+ tmp = skb->dev;
-+ skb->dev = prv->dev;
-+ ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
-+ skb->dev = tmp;
-+ return ret;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_rebuild_header(struct sk_buff *skb)
-+{
-+ struct ipsecpriv *prv = skb->dev->priv;
-+ struct device *tmp;
-+ int ret;
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(skb->dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_rebuild_header: "
-+ "no device...");
-+ return -ENODEV;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_rebuild_header: "
-+ "no private space associated with dev=%s",
-+ skb->dev->name ? skb->dev->name : "NULL");
-+ return -ENODEV;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_rebuild_header: "
-+ "no physical device associated with dev=%s",
-+ skb->dev->name ? skb->dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+ if(!prv->rebuild_header) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_rebuild_header: "
-+ "physical device has been detached, packet dropped skb->dev=%s->NULL ",
-+ skb->dev->name);
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->nh.iph->saddr),
-+ (__u32)ntohl(skb->nh.iph->daddr) );
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast: "
-+ "Revectored rebuild_header dev=%s->%s ",
-+ skb->dev->name, prv->dev->name);
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->nh.iph->saddr),
-+ (__u32)ntohl(skb->nh.iph->daddr) );
-+ tmp = skb->dev;
-+ skb->dev = prv->dev;
-+
-+ ret = prv->rebuild_header(skb);
-+ skb->dev = tmp;
-+ return ret;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_set_mac_address(struct device *dev, void *addr)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_set_mac_address: "
-+ "no device...");
-+ return -ENODEV;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_set_mac_address: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return -ENODEV;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_set_mac_address: "
-+ "no physical device associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+ if(!prv->set_mac_address) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_set_mac_address: "
-+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
-+ dev->name);
-+ return -ENODEV;
-+ }
-+
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_set_mac_address: "
-+ "Revectored dev=%s->%s addr=0p%p\n",
-+ dev->name, prv->dev->name, addr);
-+ return prv->set_mac_address(prv->dev, addr);
-+
-+}
-+
-+DEBUG_NO_STATIC void
-+ipsec_mast_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_cache_update: "
-+ "no device...");
-+ return;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_cache_update: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_cache_update: "
-+ "no physical device associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return;
-+ }
-+
-+ if(!prv->header_cache_update) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_cache_update: "
-+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
-+ dev->name);
-+ return;
-+ }
-+
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast: "
-+ "Revectored cache_update\n");
-+ prv->header_cache_update(hh, prv->dev, haddr);
-+ return;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_neigh_setup(struct neighbour *n)
-+{
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_neigh_setup:\n");
-+
-+ if (n->nud_state == NUD_NONE) {
-+ n->ops = &arp_broken_ops;
-+ n->output = n->ops->output;
-+ }
-+ return 0;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_neigh_setup_dev(struct device *dev, struct neigh_parms *p)
-+{
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_neigh_setup_dev: "
-+ "setting up %s\n",
-+ dev ? dev->name : "NULL");
-+
-+ if (p->tbl->family == AF_INET) {
-+ p->neigh_setup = ipsec_mast_neigh_setup;
-+ p->ucast_probes = 0;
-+ p->mcast_probes = 0;
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * We call the attach routine to attach another device.
-+ */
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_attach(struct device *dev, struct device *physdev)
-+{
-+ int i;
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_attach: "
-+ "no device...");
-+ return -ENODEV;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_attach: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return -ENODATA;
-+ }
-+
-+ prv->dev = physdev;
-+ prv->hard_start_xmit = physdev->hard_start_xmit;
-+ prv->get_stats = physdev->get_stats;
-+
-+ if (physdev->hard_header) {
-+ prv->hard_header = physdev->hard_header;
-+ dev->hard_header = ipsec_mast_hard_header;
-+ } else
-+ dev->hard_header = NULL;
-+
-+ if (physdev->rebuild_header) {
-+ prv->rebuild_header = physdev->rebuild_header;
-+ dev->rebuild_header = ipsec_mast_rebuild_header;
-+ } else
-+ dev->rebuild_header = NULL;
-+
-+ if (physdev->set_mac_address) {
-+ prv->set_mac_address = physdev->set_mac_address;
-+ dev->set_mac_address = ipsec_mast_set_mac_address;
-+ } else
-+ dev->set_mac_address = NULL;
-+
-+ if (physdev->header_cache_update) {
-+ prv->header_cache_update = physdev->header_cache_update;
-+ dev->header_cache_update = ipsec_mast_cache_update;
-+ } else
-+ dev->header_cache_update = NULL;
-+
-+ dev->hard_header_len = physdev->hard_header_len;
-+
-+/* prv->neigh_setup = physdev->neigh_setup; */
-+ dev->neigh_setup = ipsec_mast_neigh_setup_dev;
-+ dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
-+ prv->mtu = physdev->mtu;
-+
-+#ifdef PHYSDEV_TYPE
-+ dev->type = physdev->type; /* ARPHRD_MAST; */
-+#endif /* PHYSDEV_TYPE */
-+
-+ dev->addr_len = physdev->addr_len;
-+ for (i=0; i<dev->addr_len; i++) {
-+ dev->dev_addr[i] = physdev->dev_addr[i];
-+ }
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(debug_mast & DB_MAST_INIT) {
-+ printk(KERN_INFO "klips_debug:ipsec_mast_attach: "
-+ "physical device %s being attached has HW address: %2x",
-+ physdev->name, physdev->dev_addr[0]);
-+ for (i=1; i < physdev->addr_len; i++) {
-+ printk(":%02x", physdev->dev_addr[i]);
-+ }
-+ printk("\n");
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ return 0;
-+}
-+
-+/*
-+ * We call the detach routine to detach the ipsec mast from another device.
-+ */
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_detach(struct device *dev)
-+{
-+ int i;
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_detach: "
-+ "no device...");
-+ return -ENODEV;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_detach: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return -ENODATA;
-+ }
-+
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_detach: "
-+ "physical device %s being detached from virtual device %s\n",
-+ prv->dev ? prv->dev->name : "NULL",
-+ dev->name);
-+
-+ prv->dev = NULL;
-+ prv->hard_start_xmit = NULL;
-+ prv->get_stats = NULL;
-+
-+ prv->hard_header = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->hard_header = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+ prv->rebuild_header = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->rebuild_header = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+ prv->set_mac_address = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->set_mac_address = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+ prv->header_cache_update = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->header_cache_update = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+#ifdef DETACH_AND_DOWN
-+ dev->neigh_setup = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+ dev->hard_header_len = 0;
-+#ifdef DETACH_AND_DOWN
-+ dev->mtu = 0;
-+#endif /* DETACH_AND_DOWN */
-+ prv->mtu = 0;
-+ for (i=0; i<MAX_ADDR_LEN; i++) {
-+ dev->dev_addr[i] = 0;
-+ }
-+ dev->addr_len = 0;
-+#ifdef PHYSDEV_TYPE
-+ dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */
-+#endif /* PHYSDEV_TYPE */
-+
-+ return 0;
-+}
-+
-+/*
-+ * We call the clear routine to detach all ipsec masts from other devices.
-+ */
-+DEBUG_NO_STATIC int
-+ipsec_mast_clear(void)
-+{
-+ int i;
-+ struct device *ipsecdev = NULL, *prvdev;
-+ struct ipsecpriv *prv;
-+ char name[9];
-+ int ret;
-+
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_clear: .\n");
-+
-+ for(i = 0; i < IPSEC_NUM_IF; i++) {
-+ sprintf(name, IPSEC_DEV_FORMAT, i);
-+ if((ipsecdev = ipsec_dev_get(name)) != NULL) {
-+ if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
-+ prvdev = (struct device *)(prv->dev);
-+ if(prvdev) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_clear: "
-+ "physical device for device %s is %s\n",
-+ name, prvdev->name);
-+ if((ret = ipsec_mast_detach(ipsecdev))) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_clear: "
-+ "error %d detatching device %s from device %s.\n",
-+ ret, name, prvdev->name);
-+ return ret;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ return 0;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
-+{
-+ struct ipsecmastconf *cf = (struct ipsecmastconf *)&ifr->ifr_data;
-+ struct ipsecpriv *prv = dev->priv;
-+ struct device *them; /* physical device */
-+#ifdef CONFIG_IP_ALIAS
-+ char *colon;
-+ char realphysname[IFNAMSIZ];
-+#endif /* CONFIG_IP_ALIAS */
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "device not supplied.\n");
-+ return -ENODEV;
-+ }
-+
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "tncfg service call #%d for dev=%s\n",
-+ cmd,
-+ dev->name ? dev->name : "NULL");
-+ switch (cmd) {
-+ /* attach a virtual ipsec? device to a physical device */
-+ case IPSEC_SET_DEV:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "calling ipsec_mast_attatch...\n");
-+#ifdef CONFIG_IP_ALIAS
-+ /* If this is an IP alias interface, get its real physical name */
-+ strncpy(realphysname, cf->cf_name, IFNAMSIZ);
-+ realphysname[IFNAMSIZ-1] = 0;
-+ colon = strchr(realphysname, ':');
-+ if (colon) *colon = 0;
-+ them = ipsec_dev_get(realphysname);
-+#else /* CONFIG_IP_ALIAS */
-+ them = ipsec_dev_get(cf->cf_name);
-+#endif /* CONFIG_IP_ALIAS */
-+
-+ if (them == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "physical device %s requested is null\n",
-+ cf->cf_name);
-+ return -ENXIO;
-+ }
-+
-+#if 0
-+ if (them->flags & IFF_UP) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "physical device %s requested is not up.\n",
-+ cf->cf_name);
-+ return -ENXIO;
-+ }
-+#endif
-+
-+ if (prv && prv->dev) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "virtual device is already connected to %s.\n",
-+ prv->dev->name ? prv->dev->name : "NULL");
-+ return -EBUSY;
-+ }
-+ return ipsec_mast_attach(dev, them);
-+
-+ case IPSEC_DEL_DEV:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "calling ipsec_mast_detatch.\n");
-+ if (! prv->dev) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "physical device not connected.\n");
-+ return -ENODEV;
-+ }
-+ return ipsec_mast_detach(dev);
-+
-+ case IPSEC_CLR_DEV:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "calling ipsec_mast_clear.\n");
-+ return ipsec_mast_clear();
-+
-+ default:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "unknown command %d.\n",
-+ cmd);
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+int
-+ipsec_mast_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
-+{
-+ struct device *dev = ptr;
-+ struct device *ipsec_dev;
-+ struct ipsecpriv *priv;
-+ char name[9];
-+ int i;
-+
-+ if (dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "dev=NULL for event type %ld.\n",
-+ event);
-+ return(NOTIFY_DONE);
-+ }
-+
-+ /* check for loopback devices */
-+ if (dev && (dev->flags & IFF_LOOPBACK)) {
-+ return(NOTIFY_DONE);
-+ }
-+
-+ switch (event) {
-+ case NETDEV_DOWN:
-+ /* look very carefully at the scope of these compiler
-+ directives before changing anything... -- RGB */
-+
-+ case NETDEV_UNREGISTER:
-+ switch (event) {
-+ case NETDEV_DOWN:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_DOWN dev=%s flags=%x\n",
-+ dev->name,
-+ dev->flags);
-+ if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
-+ printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
-+ dev->name);
-+ }
-+ break;
-+ case NETDEV_UNREGISTER:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_UNREGISTER dev=%s flags=%x\n",
-+ dev->name,
-+ dev->flags);
-+ break;
-+ }
-+
-+ /* find the attached physical device and detach it. */
-+ for(i = 0; i < IPSEC_NUM_IF; i++) {
-+ sprintf(name, IPSEC_DEV_FORMAT, i);
-+ ipsec_dev = ipsec_dev_get(name);
-+ if(ipsec_dev) {
-+ priv = (struct ipsecpriv *)(ipsec_dev->priv);
-+ if(priv) {
-+ ;
-+ if(((struct device *)(priv->dev)) == dev) {
-+ /* dev_close(ipsec_dev); */
-+ /* return */ ipsec_mast_detach(ipsec_dev);
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "device '%s' has been detached.\n",
-+ ipsec_dev->name);
-+ break;
-+ }
-+ } else {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "device '%s' has no private data space!\n",
-+ ipsec_dev->name);
-+ }
-+ }
-+ }
-+ break;
-+ case NETDEV_UP:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_UP dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_REBOOT:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_REBOOT dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_CHANGE:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_CHANGE dev=%s flags=%x\n",
-+ dev->name,
-+ dev->flags);
-+ break;
-+ case NETDEV_REGISTER:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_REGISTER dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_CHANGEMTU:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
-+ dev->name,
-+ dev->mtu);
-+ break;
-+ case NETDEV_CHANGEADDR:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_CHANGEADDR dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_GOING_DOWN:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_GOING_DOWN dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_CHANGENAME:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_CHANGENAME dev=%s\n",
-+ dev->name);
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "event type %ld unrecognised for dev=%s\n",
-+ event,
-+ dev->name);
-+ break;
-+ }
-+ return NOTIFY_DONE;
-+}
-+
-+/*
-+ * Called when an ipsec mast device is initialized.
-+ * The ipsec mast device structure is passed to us.
-+ */
-+
-+int
-+ipsec_mast_init(struct device *dev)
-+{
-+ int i;
-+
-+ KLIPS_PRINT(debug_mast,
-+ "klips_debug:ipsec_mast_init: "
-+ "allocating %lu bytes initialising device: %s\n",
-+ (unsigned long) sizeof(struct ipsecpriv),
-+ dev->name ? dev->name : "NULL");
-+
-+ /* Add our mast functions to the device */
-+ dev->open = ipsec_mast_open;
-+ dev->stop = ipsec_mast_close;
-+ dev->hard_start_xmit = ipsec_mast_start_xmit;
-+ dev->get_stats = ipsec_mast_get_stats;
-+
-+ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
-+ if (dev->priv == NULL)
-+ return -ENOMEM;
-+ memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
-+
-+ for(i = 0; i < sizeof(zeroes); i++) {
-+ ((__u8*)(zeroes))[i] = 0;
-+ }
-+
-+ dev->set_multicast_list = NULL;
-+ dev->do_ioctl = ipsec_mast_ioctl;
-+ dev->hard_header = NULL;
-+ dev->rebuild_header = NULL;
-+ dev->set_mac_address = NULL;
-+ dev->header_cache_update= NULL;
-+ dev->neigh_setup = ipsec_mast_neigh_setup_dev;
-+ dev->hard_header_len = 0;
-+ dev->mtu = 0;
-+ dev->addr_len = 0;
-+ dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */ /* ARPHRD_ETHER; */
-+ dev->tx_queue_len = 10; /* Small queue */
-+ memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
-+
-+ /* New-style flags. */
-+ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
-+ dev_init_buffers(dev);
-+
-+ /* We're done. Have I forgotten anything? */
-+ return 0;
-+}
-+
-+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-+/* Module specific interface (but it links with the rest of IPSEC) */
-+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-+
-+int
-+ipsec_mast_probe(struct device *dev)
-+{
-+ ipsec_mast_init(dev);
-+ return 0;
-+}
-+
-+int
-+ipsec_mast_init_devices(void)
-+{
-+ return 0;
-+}
-+
-+/* void */
-+int
-+ipsec_mast_cleanup_devices(void)
-+{
-+ int error = 0;
-+ int i;
-+ char name[10];
-+ struct device *dev_mast;
-+
-+ for(i = 0; i < ipsec_mastdevice_count; i++) {
-+ sprintf(name, MAST_DEV_FORMAT, i);
-+ if((dev_mast = ipsec_dev_get(name)) == NULL) {
-+ break;
-+ }
-+ unregister_netdev(dev_mast);
-+ kfree(dev_mast->priv);
-+ dev_mast->priv=NULL;
-+ }
-+ return error;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.3 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.2.4.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.2 2003/06/22 20:06:17 mcr
-+ * refactored mast code still had lots of ipsecX junk in it.
-+ *
-+ * Revision 1.1 2003/02/12 19:31:12 rgb
-+ * Refactored from ipsec_tunnel.c
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_md5c.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,448 @@
-+/*
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic
-+ * changes to accomodate it in the kernel by ji.
-+ */
-+
-+#include <asm/byteorder.h>
-+#include <linux/string.h>
-+
-+#include "openswan/ipsec_md5h.h"
-+
-+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
-+ */
-+
-+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-+rights reserved.
-+
-+License to copy and use this software is granted provided that it
-+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-+Algorithm" in all material mentioning or referencing this software
-+or this function.
-+
-+License is also granted to make and use derivative works provided
-+that such works are identified as "derived from the RSA Data
-+Security, Inc. MD5 Message-Digest Algorithm" in all material
-+mentioning or referencing the derived work.
-+
-+RSA Data Security, Inc. makes no representations concerning either
-+the merchantability of this software or the suitability of this
-+software for any particular purpose. It is provided "as is"
-+without express or implied warranty of any kind.
-+
-+These notices must be retained in any copies of any part of this
-+documentation and/or software.
-+ */
-+
-+/*
-+ * Additions by JI
-+ *
-+ * HAVEMEMCOPY is defined if mem* routines are available
-+ *
-+ * HAVEHTON is defined if htons() and htonl() can be used
-+ * for big/little endian conversions
-+ *
-+ */
-+
-+#define HAVEMEMCOPY
-+#ifdef __LITTLE_ENDIAN
-+#define LITTLENDIAN
-+#endif
-+#ifdef __BIG_ENDIAN
-+#define BIGENDIAN
-+#endif
-+
-+/* Constants for MD5Transform routine.
-+ */
-+
-+#define S11 7
-+#define S12 12
-+#define S13 17
-+#define S14 22
-+#define S21 5
-+#define S22 9
-+#define S23 14
-+#define S24 20
-+#define S31 4
-+#define S32 11
-+#define S33 16
-+#define S34 23
-+#define S41 6
-+#define S42 10
-+#define S43 15
-+#define S44 21
-+
-+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
-+
-+#ifdef LITTLEENDIAN
-+#define Encode MD5_memcpy
-+#define Decode MD5_memcpy
-+#else
-+static void Encode PROTO_LIST
-+ ((unsigned char *, UINT4 *, unsigned int));
-+static void Decode PROTO_LIST
-+ ((UINT4 *, unsigned char *, unsigned int));
-+#endif
-+
-+#ifdef HAVEMEMCOPY
-+/* no need to include <memory.h> here; <linux/string.h> defines these */
-+#define MD5_memcpy memcpy
-+#define MD5_memset memset
-+#else
-+#ifdef HAVEBCOPY
-+#define MD5_memcpy(_a,_b,_c) bcopy((_b),(_a),(_c))
-+#define MD5_memset(_a,_b,_c) bzero((_a),(_c))
-+#else
-+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
-+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
-+#endif
-+#endif
-+static unsigned char PADDING[64] = {
-+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-+};
-+
-+/* F, G, H and I are basic MD5 functions.
-+ */
-+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-+#define H(x, y, z) ((x) ^ (y) ^ (z))
-+#define I(x, y, z) ((y) ^ ((x) | (~z)))
-+
-+/* ROTATE_LEFT rotates x left n bits.
-+ */
-+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-+
-+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
-+Rotation is separate from addition to prevent recomputation.
-+ */
-+#define FF(a, b, c, d, x, s, ac) { \
-+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
-+ (a) = ROTATE_LEFT ((a), (s)); \
-+ (a) += (b); \
-+ }
-+#define GG(a, b, c, d, x, s, ac) { \
-+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
-+ (a) = ROTATE_LEFT ((a), (s)); \
-+ (a) += (b); \
-+ }
-+#define HH(a, b, c, d, x, s, ac) { \
-+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
-+ (a) = ROTATE_LEFT ((a), (s)); \
-+ (a) += (b); \
-+ }
-+#define II(a, b, c, d, x, s, ac) { \
-+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
-+ (a) = ROTATE_LEFT ((a), (s)); \
-+ (a) += (b); \
-+ }
-+
-+/*
-+ * MD5 initialization. Begins an MD5 operation, writing a new context.
-+ */
-+void MD5Init(void *vcontext)
-+{
-+ MD5_CTX *context = vcontext;
-+
-+ context->count[0] = context->count[1] = 0;
-+ /* Load magic initialization constants.
-+*/
-+ context->state[0] = 0x67452301;
-+ context->state[1] = 0xefcdab89;
-+ context->state[2] = 0x98badcfe;
-+ context->state[3] = 0x10325476;
-+}
-+
-+/* MD5 block update operation. Continues an MD5 message-digest
-+ operation, processing another message block, and updating the
-+ context.
-+ */
-+void MD5Update (vcontext, input, inputLen)
-+ void *vcontext;
-+ unsigned char *input; /* input block */
-+ __u32 inputLen; /* length of input block */
-+{
-+ MD5_CTX *context = vcontext;
-+ __u32 i;
-+ unsigned int index, partLen;
-+
-+ /* Compute number of bytes mod 64 */
-+ index = (unsigned int)((context->count[0] >> 3) & 0x3F);
-+
-+ /* Update number of bits */
-+ if ((context->count[0] += ((UINT4)inputLen << 3))
-+ < ((UINT4)inputLen << 3))
-+ context->count[1]++;
-+ context->count[1] += ((UINT4)inputLen >> 29);
-+
-+ partLen = 64 - index;
-+
-+ /* Transform as many times as possible.
-+*/
-+ if (inputLen >= partLen) {
-+ MD5_memcpy
-+ ((POINTER)&context->buffer[index], (POINTER)input, partLen);
-+ MD5Transform (context->state, context->buffer);
-+
-+ for (i = partLen; i + 63 < inputLen; i += 64)
-+ MD5Transform (context->state, &input[i]);
-+
-+ index = 0;
-+ }
-+ else
-+ i = 0;
-+
-+ /* Buffer remaining input */
-+ MD5_memcpy
-+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
-+ inputLen-i);
-+}
-+
-+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
-+ the message digest and zeroizing the context.
-+ */
-+void MD5Final (digest, vcontext)
-+unsigned char digest[16]; /* message digest */
-+void *vcontext; /* context */
-+{
-+ MD5_CTX *context = vcontext;
-+ unsigned char bits[8];
-+ unsigned int index, padLen;
-+
-+ /* Save number of bits */
-+ Encode (bits, context->count, 8);
-+
-+ /* Pad out to 56 mod 64.
-+*/
-+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
-+ padLen = (index < 56) ? (56 - index) : (120 - index);
-+ MD5Update (context, PADDING, padLen);
-+
-+ /* Append length (before padding) */
-+ MD5Update (context, bits, 8);
-+
-+ if (digest != NULL) /* Bill Simpson's padding */
-+ {
-+ /* store state in digest */
-+ Encode (digest, context->state, 16);
-+
-+ /* Zeroize sensitive information.
-+ */
-+ MD5_memset ((POINTER)context, 0, sizeof (*context));
-+ }
-+}
-+
-+/* MD5 basic transformation. Transforms state based on block.
-+ */
-+static void MD5Transform (state, block)
-+UINT4 state[4];
-+unsigned char block[64];
-+{
-+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
-+
-+ Decode (x, block, 64);
-+
-+ /* Round 1 */
-+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
-+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
-+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
-+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
-+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
-+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
-+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
-+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
-+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
-+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
-+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
-+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
-+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
-+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
-+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
-+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
-+
-+ /* Round 2 */
-+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
-+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
-+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
-+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
-+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
-+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
-+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
-+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
-+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
-+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
-+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
-+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
-+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
-+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
-+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
-+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
-+
-+ /* Round 3 */
-+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
-+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
-+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
-+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
-+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
-+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
-+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
-+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
-+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
-+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
-+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
-+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
-+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
-+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
-+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
-+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
-+
-+ /* Round 4 */
-+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
-+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
-+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
-+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
-+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
-+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
-+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
-+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
-+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
-+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
-+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
-+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
-+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
-+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
-+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
-+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
-+
-+ state[0] += a;
-+ state[1] += b;
-+ state[2] += c;
-+ state[3] += d;
-+
-+ /* Zeroize sensitive information.
-+*/
-+ MD5_memset ((POINTER)x, 0, sizeof (x));
-+}
-+
-+#ifndef LITTLEENDIAN
-+
-+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
-+ a multiple of 4.
-+ */
-+static void Encode (output, input, len)
-+unsigned char *output;
-+UINT4 *input;
-+unsigned int len;
-+{
-+ unsigned int i, j;
-+
-+ for (i = 0, j = 0; j < len; i++, j += 4) {
-+ output[j] = (unsigned char)(input[i] & 0xff);
-+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
-+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
-+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
-+ }
-+}
-+
-+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
-+ a multiple of 4.
-+ */
-+static void Decode (output, input, len)
-+UINT4 *output;
-+unsigned char *input;
-+unsigned int len;
-+{
-+ unsigned int i, j;
-+
-+ for (i = 0, j = 0; j < len; i++, j += 4)
-+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
-+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
-+}
-+
-+#endif
-+
-+#ifndef HAVEMEMCOPY
-+#ifndef HAVEBCOPY
-+/* Note: Replace "for loop" with standard memcpy if possible.
-+ */
-+
-+static void MD5_memcpy (output, input, len)
-+POINTER output;
-+POINTER input;
-+unsigned int len;
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < len; i++)
-+
-+ output[i] = input[i];
-+}
-+
-+/* Note: Replace "for loop" with standard memset if possible.
-+ */
-+
-+static void MD5_memset (output, value, len)
-+POINTER output;
-+int value;
-+unsigned int len;
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < len; i++)
-+ ((char *)output)[i] = (char)value;
-+}
-+#endif
-+#endif
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.8 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.7 2002/09/10 01:45:14 mcr
-+ * changed type of MD5_CTX and SHA1_CTX to void * so that
-+ * the function prototypes would match, and could be placed
-+ * into a pointer to a function.
-+ *
-+ * Revision 1.6 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.5 2002/04/24 07:36:28 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_md5c.c,v
-+ *
-+ * Revision 1.4 1999/12/13 13:59:12 rgb
-+ * Quick fix to argument size to Update bugs.
-+ *
-+ * Revision 1.3 1999/05/21 18:09:28 henry
-+ * unnecessary <memory.h> include causes trouble in 2.2
-+ *
-+ * Revision 1.2 1999/04/06 04:54:26 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:48 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.2 1998/04/23 20:54:02 rgb
-+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
-+ * verified.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:08 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.3 1996/11/20 14:48:53 ji
-+ * Release update only.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_proc.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1127 @@
-+/*
-+ * @(#) /proc file system interface code.
-+ *
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ * 2001 Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * Split out from ipsec_init.c version 1.70.
-+ */
-+
-+char ipsec_proc_c_version[] = "RCSID $Id$";
-+
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/in.h> /* struct sockaddr_in */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef SPINLOCK
-+#ifdef SPINLOCK_23
-+#include <linux/spinlock.h> /* *lock* */
-+#else /* SPINLOCK_23 */
-+#include <asm/spinlock.h> /* *lock* */
-+#endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+#include <asm/uaccess.h>
-+#include <linux/in6.h>
-+#endif /* NET_21 */
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+#ifdef CONFIG_PROC_FS
-+#include <linux/proc_fs.h>
-+#endif /* CONFIG_PROC_FS */
-+#ifdef NETLINK_SOCK
-+#include <linux/netlink.h>
-+#else
-+#include <net/netlink.h>
-+#endif
-+
-+#include "openswan/radij.h"
-+
-+#include "openswan/ipsec_life.h"
-+#include "openswan/ipsec_stats.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_xmit.h"
-+
-+#include "openswan/ipsec_rcv.h"
-+#include "openswan/ipsec_ah.h"
-+#include "openswan/ipsec_esp.h"
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+#include "openswan/ipcomp.h"
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#include "openswan/ipsec_proto.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#ifdef CONFIG_PROC_FS
-+
-+#ifdef IPSEC_PROC_SUBDIRS
-+static struct proc_dir_entry *proc_net_ipsec_dir = NULL;
-+static struct proc_dir_entry *proc_eroute_dir = NULL;
-+static struct proc_dir_entry *proc_spi_dir = NULL;
-+static struct proc_dir_entry *proc_spigrp_dir = NULL;
-+static struct proc_dir_entry *proc_birth_dir = NULL;
-+static struct proc_dir_entry *proc_stats_dir = NULL;
-+#endif
-+
-+struct ipsec_birth_reply ipsec_ipv4_birth_packet;
-+struct ipsec_birth_reply ipsec_ipv6_birth_packet;
-+
-+#define DECREMENT_UNSIGNED(X, amount) ((amount < (X)) ? (X)-amount : 0)
-+
-+extern int ipsec_xform_get_info(char *buffer, char **start,
-+ off_t offset, int length IPSEC_PROC_LAST_ARG);
-+
-+
-+/* ipsec_snprintf: like snprintf except
-+ * - size is signed and a negative value is treated as if it were 0
-+ * - the returned result is never negative --
-+ * an error generates a "?" or null output (depending on space).
-+ * (Our callers are too lazy to check for an error return.)
-+ *
-+ * @param buf String buffer
-+ * @param size Size of the string
-+ * @param fmt printf string
-+ * @param ... Variables to be displayed in fmt
-+ * @return int Return code
-+ */
-+int ipsec_snprintf(char *buf, ssize_t size, const char *fmt, ...)
-+{
-+ va_list args;
-+ int i;
-+ size_t possize = size < 0? 0 : size;
-+ va_start(args, fmt);
-+ i = vsnprintf(buf,possize,fmt,args);
-+ va_end(args);
-+ if (i < 0) {
-+ /* create empty output in place of error */
-+ i = 0;
-+ if (size > 0) {
-+ *buf = '\0';
-+ }
-+ }
-+ return i;
-+}
-+
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_eroute_get_info(char *buffer,
-+ char **start,
-+ off_t offset,
-+ int length IPSEC_PROC_LAST_ARG)
-+{
-+ struct wsbuf w = {buffer, length, offset, 0, 0};
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (debug_radij & DB_RJ_DUMPTREES)
-+ rj_dumptrees(); /* XXXXXXXXX */
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_eroute_get_info: "
-+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
-+ buffer,
-+ *start,
-+ (int)offset,
-+ length);
-+
-+ spin_lock_bh(&eroute_lock);
-+
-+ rj_walktree(rnh, ipsec_rj_walker_procprint, &w);
-+/* rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */
-+
-+ spin_unlock_bh(&eroute_lock);
-+
-+ *start = buffer + (offset - w.begin); /* Start of wanted data */
-+ return w.len - (offset - w.begin);
-+}
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_spi_get_info(char *buffer,
-+ char **start,
-+ off_t offset,
-+ int length IPSEC_PROC_LAST_ARG)
-+{
-+ const int max_content = length > 0? length-1 : 0;
-+ int len = 0;
-+ off_t begin = 0;
-+ int i;
-+ struct ipsec_sa *sa_p;
-+ char sa[SATOT_BUF];
-+ char buf_s[SUBNETTOA_BUF];
-+ char buf_d[SUBNETTOA_BUF];
-+ size_t sa_len;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_spi_get_info: "
-+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
-+ buffer,
-+ *start,
-+ (int)offset,
-+ length);
-+
-+ spin_lock_bh(&tdb_lock);
-+
-+ for (i = 0; i < SADB_HASHMOD; i++) {
-+ for (sa_p = ipsec_sadb_hash[i];
-+ sa_p;
-+ sa_p = sa_p->ips_hnext) {
-+ atomic_inc(&sa_p->ips_refcount);
-+ sa_len = satot(&sa_p->ips_said, 'x', sa, sizeof(sa));
-+ len += ipsec_snprintf(buffer+len, length-len, "%s ",
-+ sa_len ? sa : " (error)");
-+
-+ len += ipsec_snprintf(buffer+len, length-len, "%s%s%s",
-+ IPS_XFORM_NAME(sa_p));
-+
-+ len += ipsec_snprintf(buffer+len, length-len, ": dir=%s",
-+ (sa_p->ips_flags & EMT_INBOUND) ?
-+ "in " : "out");
-+
-+ if(sa_p->ips_addr_s) {
-+ addrtoa(((struct sockaddr_in*)(sa_p->ips_addr_s))->sin_addr,
-+ 0, buf_s, sizeof(buf_s));
-+ len += ipsec_snprintf(buffer+len, length-len, " src=%s",
-+ buf_s);
-+ }
-+
-+ if((sa_p->ips_said.proto == IPPROTO_IPIP)
-+ && (sa_p->ips_flags & SADB_X_SAFLAGS_INFLOW)) {
-+ subnettoa(sa_p->ips_flow_s.u.v4.sin_addr,
-+ sa_p->ips_mask_s.u.v4.sin_addr,
-+ 0,
-+ buf_s,
-+ sizeof(buf_s));
-+
-+ subnettoa(sa_p->ips_flow_d.u.v4.sin_addr,
-+ sa_p->ips_mask_d.u.v4.sin_addr,
-+ 0,
-+ buf_d,
-+ sizeof(buf_d));
-+
-+ len += ipsec_snprintf(buffer+len, length-len, " policy=%s->%s",
-+ buf_s, buf_d);
-+ }
-+
-+ if(sa_p->ips_iv_bits) {
-+ int j;
-+ len += ipsec_snprintf(buffer+len, length-len, " iv_bits=%dbits iv=0x",
-+ sa_p->ips_iv_bits);
-+
-+ for(j = 0; j < sa_p->ips_iv_bits / 8; j++) {
-+ len += ipsec_snprintf(buffer+len, length-len, "%02x",
-+ (__u32)((__u8*)(sa_p->ips_iv))[j]);
-+ }
-+ }
-+
-+ if(sa_p->ips_encalg || sa_p->ips_authalg) {
-+ if(sa_p->ips_replaywin) {
-+ len += ipsec_snprintf(buffer+len, length-len, " ooowin=%d",
-+ sa_p->ips_replaywin);
-+ }
-+ if(sa_p->ips_errs.ips_replaywin_errs) {
-+ len += ipsec_snprintf(buffer+len, length-len, " ooo_errs=%d",
-+ sa_p->ips_errs.ips_replaywin_errs);
-+ }
-+ if(sa_p->ips_replaywin_lastseq) {
-+ len += ipsec_snprintf(buffer+len, length-len, " seq=%d",
-+ sa_p->ips_replaywin_lastseq);
-+ }
-+ if(sa_p->ips_replaywin_bitmap) {
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-+ len += ipsec_snprintf(buffer+len, length-len, " bit=0x%Lx",
-+ sa_p->ips_replaywin_bitmap);
-+#else
-+ len += ipsec_snprintf(buffer+len, length-len, " bit=0x%x%08x",
-+ (__u32)(sa_p->ips_replaywin_bitmap >> 32),
-+ (__u32)sa_p->ips_replaywin_bitmap);
-+#endif
-+ }
-+ if(sa_p->ips_replaywin_maxdiff) {
-+ len += ipsec_snprintf(buffer+len, length-len, " max_seq_diff=%d",
-+ sa_p->ips_replaywin_maxdiff);
-+ }
-+ }
-+ if(sa_p->ips_flags & ~EMT_INBOUND) {
-+ len += ipsec_snprintf(buffer+len, length-len, " flags=0x%x",
-+ sa_p->ips_flags & ~EMT_INBOUND);
-+ len += ipsec_snprintf(buffer+len, length-len, "<");
-+ /* flag printing goes here */
-+ len += ipsec_snprintf(buffer+len, length-len, ">");
-+ }
-+ if(sa_p->ips_auth_bits) {
-+ len += ipsec_snprintf(buffer+len, length-len, " alen=%d",
-+ sa_p->ips_auth_bits);
-+ }
-+ if(sa_p->ips_key_bits_a) {
-+ len += ipsec_snprintf(buffer+len, length-len, " aklen=%d",
-+ sa_p->ips_key_bits_a);
-+ }
-+ if(sa_p->ips_errs.ips_auth_errs) {
-+ len += ipsec_snprintf(buffer+len, length-len, " auth_errs=%d",
-+ sa_p->ips_errs.ips_auth_errs);
-+ }
-+ if(sa_p->ips_key_bits_e) {
-+ len += ipsec_snprintf(buffer+len, length-len, " eklen=%d",
-+ sa_p->ips_key_bits_e);
-+ }
-+ if(sa_p->ips_errs.ips_encsize_errs) {
-+ len += ipsec_snprintf(buffer+len, length-len, " encr_size_errs=%d",
-+ sa_p->ips_errs.ips_encsize_errs);
-+ }
-+ if(sa_p->ips_errs.ips_encpad_errs) {
-+ len += ipsec_snprintf(buffer+len, length-len, " encr_pad_errs=%d",
-+ sa_p->ips_errs.ips_encpad_errs);
-+ }
-+
-+ len += ipsec_snprintf(buffer+len, length-len, " life(c,s,h)=");
-+
-+ len += ipsec_lifetime_format(buffer + len,
-+ length - len,
-+ "alloc",
-+ ipsec_life_countbased,
-+ &sa_p->ips_life.ipl_allocations);
-+
-+ len += ipsec_lifetime_format(buffer + len,
-+ length - len,
-+ "bytes",
-+ ipsec_life_countbased,
-+ &sa_p->ips_life.ipl_bytes);
-+
-+ len += ipsec_lifetime_format(buffer + len,
-+ length - len,
-+ "addtime",
-+ ipsec_life_timebased,
-+ &sa_p->ips_life.ipl_addtime);
-+
-+ len += ipsec_lifetime_format(buffer + len,
-+ length - len,
-+ "usetime",
-+ ipsec_life_timebased,
-+ &sa_p->ips_life.ipl_usetime);
-+
-+ len += ipsec_lifetime_format(buffer + len,
-+ length - len,
-+ "packets",
-+ ipsec_life_countbased,
-+ &sa_p->ips_life.ipl_packets);
-+
-+ if(sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-+ len += ipsec_snprintf(buffer+len, length-len, " idle=%Ld",
-+ jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last);
-+#else
-+ len += ipsec_snprintf(buffer+len, length-len, " idle=%lu",
-+ jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last);
-+#endif
-+ }
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ if(sa_p->ips_said.proto == IPPROTO_COMP &&
-+ (sa_p->ips_comp_ratio_dbytes ||
-+ sa_p->ips_comp_ratio_cbytes)) {
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-+ len += ipsec_snprintf(buffer+len, length-len, " ratio=%Ld:%Ld",
-+ sa_p->ips_comp_ratio_dbytes,
-+ sa_p->ips_comp_ratio_cbytes);
-+#else
-+ len += ipsec_snprintf(buffer+len, length-len, " ratio=%lu:%lu",
-+ (unsigned long)sa_p->ips_comp_ratio_dbytes,
-+ (unsigned long)sa_p->ips_comp_ratio_cbytes);
-+#endif
-+ }
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if(sa_p->ips_natt_type != 0) {
-+ char *natttype_name;
-+
-+ switch(sa_p->ips_natt_type)
-+ {
-+ case ESPINUDP_WITH_NON_IKE:
-+ natttype_name="nonike";
-+ break;
-+ case ESPINUDP_WITH_NON_ESP:
-+ natttype_name="nonesp";
-+ break;
-+ default:
-+ natttype_name = "unknown";
-+ break;
-+ }
-+
-+ len += ipsec_snprintf(buffer + len, length-len, " natencap=%s",
-+ natttype_name);
-+
-+ len += ipsec_snprintf(buffer + len, length-len, " natsport=%d",
-+ sa_p->ips_natt_sport);
-+
-+ len += ipsec_snprintf(buffer + len,length-len, " natdport=%d",
-+ sa_p->ips_natt_dport);
-+ }
-+#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
-+
-+ len += ipsec_snprintf(buffer + len,length-len, " refcount=%d",
-+ atomic_read(&sa_p->ips_refcount));
-+
-+ len += ipsec_snprintf(buffer+len, length-len, " ref=%d",
-+ sa_p->ips_ref);
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(debug_xform) {
-+ len += ipsec_snprintf(buffer+len, length-len, " reftable=%lu refentry=%lu",
-+ (unsigned long)IPsecSAref2table(sa_p->ips_ref),
-+ (unsigned long)IPsecSAref2entry(sa_p->ips_ref));
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ len += ipsec_snprintf(buffer+len, length-len, "\n");
-+
-+ atomic_dec(&sa_p->ips_refcount);
-+
-+ if (len >= max_content) {
-+ /* we've done all that can fit -- stop loops */
-+ len = max_content; /* truncate crap */
-+ goto done_spi_i;
-+ } else {
-+ const off_t pos = begin + len; /* file position of end of what we've generated */
-+
-+ if (pos <= offset) {
-+ /* all is before first interesting character:
-+ * discard, but note where we are.
-+ */
-+ len = 0;
-+ begin = pos;
-+ }
-+ }
-+ }
-+ }
-+
-+done_spi_i:
-+ spin_unlock_bh(&tdb_lock);
-+
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ return len - (offset - begin);
-+}
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_spigrp_get_info(char *buffer,
-+ char **start,
-+ off_t offset,
-+ int length IPSEC_PROC_LAST_ARG)
-+{
-+ /* Limit of useful snprintf output */
-+ const int max_content = length > 0? length-1 : 0;
-+
-+ int len = 0;
-+ off_t begin = 0;
-+ int i;
-+ struct ipsec_sa *sa_p, *sa_p2;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_spigrp_get_info: "
-+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
-+ buffer,
-+ *start,
-+ (int)offset,
-+ length);
-+
-+ spin_lock_bh(&tdb_lock);
-+
-+ for (i = 0; i < SADB_HASHMOD; i++) {
-+ for (sa_p = ipsec_sadb_hash[i];
-+ sa_p != NULL;
-+ sa_p = sa_p->ips_hnext)
-+ {
-+ atomic_inc(&sa_p->ips_refcount);
-+ if(sa_p->ips_inext == NULL) {
-+ sa_p2 = sa_p;
-+ while(sa_p2 != NULL) {
-+ atomic_inc(&sa_p2->ips_refcount);
-+ sa_len = satot(&sa_p2->ips_said,
-+ 'x', sa, sizeof(sa));
-+
-+ len += ipsec_snprintf(buffer+len, length-len, "%s ",
-+ sa_len ? sa : " (error)");
-+ atomic_dec(&sa_p2->ips_refcount);
-+ sa_p2 = sa_p2->ips_onext;
-+ }
-+ len += ipsec_snprintf(buffer+len, length-len, "\n");
-+ }
-+
-+ atomic_dec(&sa_p->ips_refcount);
-+
-+ if (len >= max_content) {
-+ /* we've done all that can fit -- stop loops */
-+ len = max_content; /* truncate crap */
-+ goto done_spigrp_i;
-+ } else {
-+ const off_t pos = begin + len;
-+
-+ if (pos <= offset) {
-+ /* all is before first interesting character:
-+ * discard, but note where we are.
-+ */
-+ len = 0;
-+ begin = pos;
-+ }
-+ }
-+ }
-+ }
-+
-+done_spigrp_i:
-+ spin_unlock_bh(&tdb_lock);
-+
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ return len - (offset - begin);
-+}
-+
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_tncfg_get_info(char *buffer,
-+ char **start,
-+ off_t offset,
-+ int length IPSEC_PROC_LAST_ARG)
-+{
-+ /* limit of useful snprintf output */
-+ const int max_content = length > 0? length-1 : 0;
-+ int len = 0;
-+ off_t begin = 0;
-+ int i;
-+ char name[9];
-+ struct device *dev, *privdev;
-+ struct ipsecpriv *priv;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_tncfg_get_info: "
-+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
-+ buffer,
-+ *start,
-+ (int)offset,
-+ length);
-+
-+ for(i = 0; i < IPSEC_NUM_IF; i++) {
-+ ipsec_snprintf(name, (ssize_t) sizeof(name), IPSEC_DEV_FORMAT, i);
-+ dev = __ipsec_dev_get(name);
-+ if(dev) {
-+ priv = (struct ipsecpriv *)(dev->priv);
-+ len += ipsec_snprintf(buffer+len, length-len, "%s",
-+ dev->name);
-+ if(priv) {
-+ privdev = (struct device *)(priv->dev);
-+ len += ipsec_snprintf(buffer+len, length-len, " -> %s",
-+ privdev ? privdev->name : "NULL");
-+ len += ipsec_snprintf(buffer+len, length-len, " mtu=%d(%d) -> %d",
-+ dev->mtu,
-+ priv->mtu,
-+ privdev ? privdev->mtu : 0);
-+ } else {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n",
-+ dev->name);
-+ }
-+ len += ipsec_snprintf(buffer+len, length-len, "\n");
-+
-+ if (len >= max_content) {
-+ /* we've done all that can fit -- stop loop */
-+ len = max_content; /* truncate crap */
-+ break;
-+ } else {
-+ const off_t pos = begin + len;
-+ if (pos <= offset) {
-+ len = 0;
-+ begin = pos;
-+ }
-+ }
-+ }
-+ }
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ len -= (offset - begin); /* Start slop */
-+ if (len > length)
-+ len = length;
-+ return len;
-+}
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_version_get_info(char *buffer,
-+ char **start,
-+ off_t offset,
-+ int length IPSEC_PROC_LAST_ARG)
-+{
-+ int len = 0;
-+ off_t begin = 0;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_version_get_info: "
-+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
-+ buffer,
-+ *start,
-+ (int)offset,
-+ length);
-+
-+ len += ipsec_snprintf(buffer + len,length-len, "Openswan version: %s\n",
-+ ipsec_version_code());
-+#if 0
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_version_get_info: "
-+ "ipsec_init version: %s\n",
-+ ipsec_init_c_version);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_version_get_info: "
-+ "ipsec_tunnel version: %s\n",
-+ ipsec_tunnel_c_version);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_version_get_info: "
-+ "ipsec_netlink version: %s\n",
-+ ipsec_netlink_c_version);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_version_get_info: "
-+ "radij_c_version: %s\n",
-+ radij_c_version);
-+#endif
-+
-+
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ len -= (offset - begin); /* Start slop */
-+ if (len > length)
-+ len = length;
-+ return len;
-+}
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_birth_info(char *page,
-+ char **start,
-+ off_t offset,
-+ int count,
-+ int *eof,
-+ void *data)
-+{
-+ struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
-+ int len;
-+
-+ if(offset >= ibr->packet_template_len) {
-+ if(eof) {
-+ *eof=1;
-+ }
-+ return 0;
-+ }
-+
-+ len = ibr->packet_template_len;
-+ len -= offset;
-+ if (len > count)
-+ len = count;
-+
-+ memcpy(page + offset, ibr->packet_template+offset, len);
-+
-+ return len;
-+}
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_birth_set(struct file *file, const char *buffer,
-+ unsigned long count, void *data)
-+{
-+ struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
-+ int len;
-+
-+ MOD_INC_USE_COUNT;
-+ if(count > IPSEC_BIRTH_TEMPLATE_MAXLEN) {
-+ len = IPSEC_BIRTH_TEMPLATE_MAXLEN;
-+ } else {
-+ len = count;
-+ }
-+
-+ if(copy_from_user(ibr->packet_template, buffer, len)) {
-+ MOD_DEC_USE_COUNT;
-+ return -EFAULT;
-+ }
-+ ibr->packet_template_len = len;
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ return len;
-+}
-+
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_klipsdebug_get_info(char *buffer,
-+ char **start,
-+ off_t offset,
-+ int length IPSEC_PROC_LAST_ARG)
-+{
-+ int len = 0;
-+ off_t begin = 0;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_klipsdebug_get_info: "
-+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
-+ buffer,
-+ *start,
-+ (int)offset,
-+ length);
-+
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_tunnel=%08x.\n", debug_tunnel);
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_xform=%08x.\n", debug_xform);
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_eroute=%08x.\n", debug_eroute);
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_spi=%08x.\n", debug_spi);
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_radij=%08x.\n", debug_radij);
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_esp=%08x.\n", debug_esp);
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_ah=%08x.\n", debug_ah);
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_rcv=%08x.\n", debug_rcv);
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_pfkey=%08x.\n", debug_pfkey);
-+
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ len -= (offset - begin); /* Start slop */
-+ if (len > length)
-+ len = length;
-+ return len;
-+}
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_stats_get_int_info(char *buffer,
-+ char **start,
-+ off_t offset,
-+ int length,
-+ int *eof,
-+ void *data)
-+{
-+
-+ const int max_content = length > 0? length-1 : 0;
-+ int len = 0;
-+ int *thing;
-+
-+ thing = (int *)data;
-+
-+ len = ipsec_snprintf(buffer+len, length-len, "%08x\n", *thing);
-+
-+ if (len >= max_content)
-+ len = max_content; /* truncate crap */
-+
-+ *start = buffer + offset; /* Start of wanted data */
-+ return len > offset? len - offset : 0;
-+
-+}
-+
-+#ifndef PROC_FS_2325
-+struct proc_dir_entry ipsec_eroute =
-+{
-+ 0,
-+ 12, "ipsec_eroute",
-+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
-+ &proc_net_inode_operations,
-+ ipsec_eroute_get_info,
-+ NULL, NULL, NULL, NULL, NULL
-+};
-+
-+struct proc_dir_entry ipsec_spi =
-+{
-+ 0,
-+ 9, "ipsec_spi",
-+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
-+ &proc_net_inode_operations,
-+ ipsec_spi_get_info,
-+ NULL, NULL, NULL, NULL, NULL
-+};
-+
-+struct proc_dir_entry ipsec_spigrp =
-+{
-+ 0,
-+ 12, "ipsec_spigrp",
-+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
-+ &proc_net_inode_operations,
-+ ipsec_spigrp_get_info,
-+ NULL, NULL, NULL, NULL, NULL
-+};
-+
-+struct proc_dir_entry ipsec_tncfg =
-+{
-+ 0,
-+ 11, "ipsec_tncfg",
-+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
-+ &proc_net_inode_operations,
-+ ipsec_tncfg_get_info,
-+ NULL, NULL, NULL, NULL, NULL
-+};
-+
-+struct proc_dir_entry ipsec_version =
-+{
-+ 0,
-+ 13, "ipsec_version",
-+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
-+ &proc_net_inode_operations,
-+ ipsec_version_get_info,
-+ NULL, NULL, NULL, NULL, NULL
-+};
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+struct proc_dir_entry ipsec_klipsdebug =
-+{
-+ 0,
-+ 16, "ipsec_klipsdebug",
-+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
-+ &proc_net_inode_operations,
-+ ipsec_klipsdebug_get_info,
-+ NULL, NULL, NULL, NULL, NULL
-+};
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#endif /* !PROC_FS_2325 */
-+#endif /* CONFIG_PROC_FS */
-+
-+#if defined(PROC_FS_2325)
-+struct ipsec_proc_list {
-+ char *name;
-+ struct proc_dir_entry **parent;
-+ struct proc_dir_entry **dir;
-+ read_proc_t *readthing;
-+ write_proc_t *writething;
-+ void *data;
-+};
-+static struct ipsec_proc_list proc_items[]={
-+#ifdef CONFIG_IPSEC_DEBUG
-+ {"klipsdebug", &proc_net_ipsec_dir, NULL, ipsec_klipsdebug_get_info, NULL, NULL},
-+#endif
-+ {"eroute", &proc_net_ipsec_dir, &proc_eroute_dir, NULL, NULL, NULL},
-+ {"all", &proc_eroute_dir, NULL, ipsec_eroute_get_info, NULL, NULL},
-+ {"spi", &proc_net_ipsec_dir, &proc_spi_dir, NULL, NULL, NULL},
-+ {"all", &proc_spi_dir, NULL, ipsec_spi_get_info, NULL, NULL},
-+ {"spigrp", &proc_net_ipsec_dir, &proc_spigrp_dir, NULL, NULL, NULL},
-+ {"all", &proc_spigrp_dir, NULL, ipsec_spigrp_get_info, NULL, NULL},
-+ {"birth", &proc_net_ipsec_dir, &proc_birth_dir, NULL, NULL, NULL},
-+ {"ipv4", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv4_birth_packet},
-+ {"ipv6", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv6_birth_packet},
-+ {"tncfg", &proc_net_ipsec_dir, NULL, ipsec_tncfg_get_info, NULL, NULL},
-+ {"xforms", &proc_net_ipsec_dir, NULL, ipsec_xform_get_info, NULL, NULL},
-+ {"stats", &proc_net_ipsec_dir, &proc_stats_dir, NULL, NULL, NULL},
-+ {"trap_count", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_count},
-+ {"trap_sendcount", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_sendcount},
-+ {"version", &proc_net_ipsec_dir, NULL, ipsec_version_get_info, NULL, NULL},
-+ {NULL, NULL, NULL, NULL, NULL, NULL}
-+};
-+#endif
-+
-+int
-+ipsec_proc_init()
-+{
-+ int error = 0;
-+#ifdef IPSEC_PROC_SUBDIRS
-+ struct proc_dir_entry *item;
-+#endif
-+
-+ /*
-+ * just complain because pluto won't run without /proc!
-+ */
-+#ifndef CONFIG_PROC_FS
-+#error You must have PROC_FS built in to use KLIPS
-+#endif
-+
-+ /* for 2.0 kernels */
-+#if !defined(PROC_FS_2325) && !defined(PROC_FS_21)
-+ error |= proc_register_dynamic(&proc_net, &ipsec_eroute);
-+ error |= proc_register_dynamic(&proc_net, &ipsec_spi);
-+ error |= proc_register_dynamic(&proc_net, &ipsec_spigrp);
-+ error |= proc_register_dynamic(&proc_net, &ipsec_tncfg);
-+ error |= proc_register_dynamic(&proc_net, &ipsec_version);
-+#ifdef CONFIG_IPSEC_DEBUG
-+ error |= proc_register_dynamic(&proc_net, &ipsec_klipsdebug);
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#endif
-+
-+ /* for 2.2 kernels */
-+#if !defined(PROC_FS_2325) && defined(PROC_FS_21)
-+ error |= proc_register(proc_net, &ipsec_eroute);
-+ error |= proc_register(proc_net, &ipsec_spi);
-+ error |= proc_register(proc_net, &ipsec_spigrp);
-+ error |= proc_register(proc_net, &ipsec_tncfg);
-+ error |= proc_register(proc_net, &ipsec_version);
-+#ifdef CONFIG_IPSEC_DEBUG
-+ error |= proc_register(proc_net, &ipsec_klipsdebug);
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#endif
-+
-+ /* for 2.4 kernels */
-+#if defined(PROC_FS_2325)
-+ /* create /proc/net/ipsec */
-+
-+ /* zero these out before we initialize /proc/net/ipsec/birth/stuff */
-+ memset(&ipsec_ipv4_birth_packet, 0, sizeof(struct ipsec_birth_reply));
-+ memset(&ipsec_ipv6_birth_packet, 0, sizeof(struct ipsec_birth_reply));
-+
-+ proc_net_ipsec_dir = proc_mkdir("ipsec", proc_net);
-+ if(proc_net_ipsec_dir == NULL) {
-+ /* no point in continuing */
-+ return 1;
-+ }
-+
-+ {
-+ struct ipsec_proc_list *it;
-+
-+ it=proc_items;
-+ while(it->name!=NULL) {
-+ if(it->dir) {
-+ /* make a dir instead */
-+ item = proc_mkdir(it->name, *it->parent);
-+ *it->dir = item;
-+ } else {
-+ item = create_proc_entry(it->name, 0400, *it->parent);
-+ }
-+ if(item) {
-+ item->read_proc = it->readthing;
-+ item->write_proc = it->writething;
-+ item->data = it->data;
-+#ifdef MODULE
-+ item->owner = THIS_MODULE;
-+#endif
-+ } else {
-+ error |= 1;
-+ }
-+ it++;
-+ }
-+ }
-+
-+ /* now create some symlinks to provide compatibility */
-+ proc_symlink("ipsec_eroute", proc_net, "ipsec/eroute/all");
-+ proc_symlink("ipsec_spi", proc_net, "ipsec/spi/all");
-+ proc_symlink("ipsec_spigrp", proc_net, "ipsec/spigrp/all");
-+ proc_symlink("ipsec_tncfg", proc_net, "ipsec/tncfg");
-+ proc_symlink("ipsec_version",proc_net, "ipsec/version");
-+ proc_symlink("ipsec_klipsdebug",proc_net,"ipsec/klipsdebug");
-+
-+#endif /* !PROC_FS_2325 */
-+
-+ return error;
-+}
-+
-+void
-+ipsec_proc_cleanup()
-+{
-+
-+ /* for 2.0 and 2.2 kernels */
-+#if !defined(PROC_FS_2325)
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0)
-+ printk("klips_debug:ipsec_cleanup: "
-+ "cannot unregister /proc/net/ipsec_klipsdebug\n");
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ if (proc_net_unregister(ipsec_version.low_ino) != 0)
-+ printk("klips_debug:ipsec_cleanup: "
-+ "cannot unregister /proc/net/ipsec_version\n");
-+ if (proc_net_unregister(ipsec_eroute.low_ino) != 0)
-+ printk("klips_debug:ipsec_cleanup: "
-+ "cannot unregister /proc/net/ipsec_eroute\n");
-+ if (proc_net_unregister(ipsec_spi.low_ino) != 0)
-+ printk("klips_debug:ipsec_cleanup: "
-+ "cannot unregister /proc/net/ipsec_spi\n");
-+ if (proc_net_unregister(ipsec_spigrp.low_ino) != 0)
-+ printk("klips_debug:ipsec_cleanup: "
-+ "cannot unregister /proc/net/ipsec_spigrp\n");
-+ if (proc_net_unregister(ipsec_tncfg.low_ino) != 0)
-+ printk("klips_debug:ipsec_cleanup: "
-+ "cannot unregister /proc/net/ipsec_tncfg\n");
-+#endif
-+
-+ /* for 2.4 kernels */
-+#if defined(PROC_FS_2325)
-+ {
-+ struct ipsec_proc_list *it;
-+
-+ /* find end of list */
-+ it=proc_items;
-+ while(it->name!=NULL) {
-+ it++;
-+ }
-+ it--;
-+
-+ do {
-+ remove_proc_entry(it->name, *it->parent);
-+ it--;
-+ } while(it > proc_items);
-+ }
-+
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ remove_proc_entry("ipsec_klipsdebug", proc_net);
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ remove_proc_entry("ipsec_eroute", proc_net);
-+ remove_proc_entry("ipsec_spi", proc_net);
-+ remove_proc_entry("ipsec_spigrp", proc_net);
-+ remove_proc_entry("ipsec_tncfg", proc_net);
-+ remove_proc_entry("ipsec_version", proc_net);
-+ remove_proc_entry("ipsec", proc_net);
-+#endif /* 2.4 kernel */
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.30 2004/04/25 21:23:11 ken
-+ * Pull in dhr's changes from FreeS/WAN 2.06
-+ *
-+ * Revision 1.29 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.28 2004/03/28 20:29:58 paul
-+ * <hugh_> ssize_t, not ssized_t
-+ *
-+ * Revision 1.27 2004/03/28 20:27:20 paul
-+ * Included tested and confirmed fixes mcr made and dhr verified for
-+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
-+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
-+ * dhr. (thanks dhr!)
-+ *
-+ * Revision 1.26 2004/02/09 22:07:06 mcr
-+ * added information about nat-traversal setting to spi-output.
-+ *
-+ * Revision 1.25.4.1 2004/04/05 04:30:46 mcr
-+ * patches for alg-branch to compile/work with 2.x openswan
-+ *
-+ * Revision 1.25 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.24.4.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.24 2003/06/20 01:42:21 mcr
-+ * added counters to measure how many ACQUIREs we send to pluto,
-+ * and how many are successfully sent.
-+ *
-+ * Revision 1.23 2003/04/03 17:38:09 rgb
-+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
-+ *
-+ * Revision 1.22 2002/09/20 15:40:57 rgb
-+ * Renamed saref macros for consistency and brevity.
-+ *
-+ * Revision 1.21 2002/09/20 05:01:35 rgb
-+ * Print ref and reftable, refentry seperately.
-+ *
-+ * Revision 1.20 2002/09/19 02:35:39 mcr
-+ * do not define structures needed by /proc/net/ipsec/ if we
-+ * aren't going create that directory.
-+ *
-+ * Revision 1.19 2002/09/10 01:43:25 mcr
-+ * fixed problem in /-* comment.
-+ *
-+ * Revision 1.18 2002/09/03 16:22:11 mcr
-+ * fixed initialization of birth/stuff values - some simple
-+ * screw ups in the code.
-+ * removed debugging that was left in by mistake.
-+ *
-+ * Revision 1.17 2002/09/02 17:54:53 mcr
-+ * changed how the table driven /proc entries are created so that
-+ * making subdirs is now explicit rather than implicit.
-+ *
-+ * Revision 1.16 2002/08/30 01:23:37 mcr
-+ * reorganized /proc creating code to clear up ifdefs,
-+ * make the 2.4 code table driven, and put things into
-+ * /proc/net/ipsec subdir. Symlinks are left for compatibility.
-+ *
-+ * Revision 1.15 2002/08/13 19:01:25 mcr
-+ * patches from kenb to permit compilation of FreeSWAN on ia64.
-+ * des library patched to use proper DES_LONG type for ia64.
-+ *
-+ * Revision 1.14 2002/07/26 08:48:31 rgb
-+ * Added SA ref table code.
-+ *
-+ * Revision 1.13 2002/07/24 18:44:54 rgb
-+ * Type fiddling to tame ia64 compiler.
-+ *
-+ * Revision 1.12 2002/05/27 18:56:07 rgb
-+ * Convert to dynamic ipsec device allocation.
-+ *
-+ * Revision 1.11 2002/05/23 07:14:50 rgb
-+ * Added refcount code.
-+ * Cleaned up %p variants to 0p%p for test suite cleanup.
-+ * Convert "usecount" to "refcount" to remove ambiguity.
-+ *
-+ * Revision 1.10 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.9 2002/04/24 07:36:28 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_proc.c,v
-+ *
-+ * Revision 1.8 2002/01/29 17:17:55 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.7 2002/01/29 04:00:52 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.6 2002/01/29 02:13:17 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.5 2002/01/12 02:54:30 mcr
-+ * beginnings of /proc/net/ipsec dir.
-+ *
-+ * Revision 1.4 2001/12/11 02:21:05 rgb
-+ * Don't include module version here, fixing 2.2 compile bug.
-+ *
-+ * Revision 1.3 2001/12/05 07:19:44 rgb
-+ * Fixed extraneous #include "version.c" bug causing modular KLIPS failure.
-+ *
-+ * Revision 1.2 2001/11/26 09:16:14 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.74 2001/11/22 05:44:11 henry
-+ * new version stuff
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:19:40 mcr
-+ * /proc manipulation code moved to new ipsec_proc.c
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_radij.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,869 @@
-+/*
-+ * Interface between the IPSEC code and the radix (radij) tree code
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* 23_SPINLOCK */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* 23_SPINLOCK */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+#endif
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "openswan/ipsec_eroute.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_tunnel.h" /* struct ipsecpriv */
-+#include "openswan/ipsec_xform.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_radij = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+struct radij_node_head *rnh = NULL;
-+#ifdef SPINLOCK
-+spinlock_t eroute_lock = SPIN_LOCK_UNLOCKED;
-+#else /* SPINLOCK */
-+spinlock_t eroute_lock;
-+#endif /* SPINLOCK */
-+
-+int
-+ipsec_radijinit(void)
-+{
-+ maj_keylen = sizeof (struct sockaddr_encap);
-+
-+ rj_init();
-+
-+ if (rj_inithead((void **)&rnh, /*16*/offsetof(struct sockaddr_encap, sen_type) * sizeof(__u8)) == 0) /* 16 is bit offset of sen_type */
-+ return -1;
-+ return 0;
-+}
-+
-+int
-+ipsec_radijcleanup(void)
-+{
-+ int error;
-+
-+ spin_lock_bh(&eroute_lock);
-+
-+ error = radijcleanup();
-+
-+ spin_unlock_bh(&eroute_lock);
-+
-+ return error;
-+}
-+
-+int
-+ipsec_cleareroutes(void)
-+{
-+ int error;
-+
-+ spin_lock_bh(&eroute_lock);
-+
-+ error = radijcleartree();
-+
-+ spin_unlock_bh(&eroute_lock);
-+
-+ return error;
-+}
-+
-+int
-+ipsec_breakroute(struct sockaddr_encap *eaddr,
-+ struct sockaddr_encap *emask,
-+ struct sk_buff **first,
-+ struct sk_buff **last)
-+{
-+ struct eroute *ro;
-+ struct radij_node *rn;
-+ int error;
-+#ifdef CONFIG_IPSEC_DEBUG
-+
-+ if (debug_eroute) {
-+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
-+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_breakroute: "
-+ "attempting to delete eroute for %s:%d->%s:%d %d\n",
-+ buf1, ntohs(eaddr->sen_sport),
-+ buf2, ntohs(eaddr->sen_dport), eaddr->sen_proto);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ spin_lock_bh(&eroute_lock);
-+
-+ if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) {
-+ spin_unlock_bh(&eroute_lock);
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_breakroute: "
-+ "node not found, eroute delete failed.\n");
-+ return error;
-+ }
-+
-+ spin_unlock_bh(&eroute_lock);
-+
-+ ro = (struct eroute *)rn;
-+
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_breakroute: "
-+ "deleted eroute=0p%p, ident=0p%p->0p%p, first=0p%p, last=0p%p\n",
-+ ro,
-+ ro->er_ident_s.data,
-+ ro->er_ident_d.data,
-+ ro->er_first,
-+ ro->er_last);
-+
-+ if (ro->er_ident_s.data != NULL) {
-+ kfree(ro->er_ident_s.data);
-+ }
-+ if (ro->er_ident_d.data != NULL) {
-+ kfree(ro->er_ident_d.data);
-+ }
-+ if (ro->er_first != NULL) {
-+#if 0
-+ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_first->dev->priv))->mystats);
-+ stats->tx_dropped--;
-+#endif
-+ *first = ro->er_first;
-+ }
-+ if (ro->er_last != NULL) {
-+#if 0
-+ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_last->dev->priv))->mystats);
-+ stats->tx_dropped--;
-+#endif
-+ *last = ro->er_last;
-+ }
-+
-+ if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT))
-+ panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n");
-+ memset((caddr_t)rn, 0, sizeof (struct eroute));
-+ kfree(rn);
-+
-+ return 0;
-+}
-+
-+int
-+ipsec_makeroute(struct sockaddr_encap *eaddr,
-+ struct sockaddr_encap *emask,
-+ ip_said said,
-+ uint32_t pid,
-+ struct sk_buff *skb,
-+ struct ident *ident_s,
-+ struct ident *ident_d)
-+{
-+ struct eroute *retrt;
-+ int error;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+
-+ if (debug_eroute) {
-+
-+ {
-+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
-+
-+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
-+ sa_len = satot(&said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_makeroute: "
-+ "attempting to allocate %lu bytes to insert eroute for %s->%s, SA: %s, PID:%d, skb=0p%p, ident:%s->%s\n",
-+ (unsigned long) sizeof(struct eroute),
-+ buf1,
-+ buf2,
-+ sa_len ? sa : " (error)",
-+ pid,
-+ skb,
-+ (ident_s ? (ident_s->data ? ident_s->data : "NULL") : "NULL"),
-+ (ident_d ? (ident_d->data ? ident_d->data : "NULL") : "NULL"));
-+ }
-+ {
-+ char buf1[sizeof(struct sockaddr_encap)*2 + 1],
-+ buf2[sizeof(struct sockaddr_encap)*2 + 1];
-+ int i;
-+ unsigned char *b1 = buf1,
-+ *b2 = buf2,
-+ *ea = (unsigned char *)eaddr,
-+ *em = (unsigned char *)emask;
-+
-+
-+ for (i=0; i<sizeof(struct sockaddr_encap); i++) {
-+ sprintf(b1, "%02x", ea[i]);
-+ sprintf(b2, "%02x", em[i]);
-+ b1+=2;
-+ b2+=2;
-+ }
-+ KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_makeroute: %s / %s \n", buf1, buf2);
-+ }
-+
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ retrt = (struct eroute *)kmalloc(sizeof (struct eroute), GFP_ATOMIC);
-+ if (retrt == NULL) {
-+ printk("klips_error:ipsec_makeroute: "
-+ "not able to allocate kernel memory");
-+ return -ENOMEM;
-+ }
-+ memset((caddr_t)retrt, 0, sizeof (struct eroute));
-+
-+ retrt->er_eaddr = *eaddr;
-+ retrt->er_emask = *emask;
-+ retrt->er_said = said;
-+ retrt->er_pid = pid;
-+ retrt->er_count = 0;
-+ retrt->er_lasttime = jiffies/HZ;
-+ rd_key((&(retrt->er_rjt))) = &(retrt->er_eaddr);
-+
-+ if (ident_s && ident_s->type != SADB_IDENTTYPE_RESERVED) {
-+ int data_len = ident_s->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
-+
-+ retrt->er_ident_s.type = ident_s->type;
-+ retrt->er_ident_s.id = ident_s->id;
-+ retrt->er_ident_s.len = ident_s->len;
-+ if(data_len) {
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_makeroute: "
-+ "attempting to allocate %u bytes for ident_s.\n",
-+ data_len);
-+ if(!(retrt->er_ident_s.data = kmalloc(data_len, GFP_KERNEL))) {
-+ kfree(retrt);
-+ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
-+ return ENOMEM;
-+ }
-+ memcpy(retrt->er_ident_s.data, ident_s->data, data_len);
-+ } else {
-+ retrt->er_ident_s.data = NULL;
-+ }
-+ }
-+
-+ if (ident_d && ident_d->type != SADB_IDENTTYPE_RESERVED) {
-+ int data_len = ident_d->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
-+
-+ retrt->er_ident_d.type = ident_d->type;
-+ retrt->er_ident_d.id = ident_d->id;
-+ retrt->er_ident_d.len = ident_d->len;
-+ if(data_len) {
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_makeroute: "
-+ "attempting to allocate %u bytes for ident_d.\n",
-+ data_len);
-+ if(!(retrt->er_ident_d.data = kmalloc(data_len, GFP_KERNEL))) {
-+ if (retrt->er_ident_s.data)
-+ kfree(retrt->er_ident_s.data);
-+ kfree(retrt);
-+ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
-+ return ENOMEM;
-+ }
-+ memcpy(retrt->er_ident_d.data, ident_d->data, data_len);
-+ } else {
-+ retrt->er_ident_d.data = NULL;
-+ }
-+ }
-+ retrt->er_first = skb;
-+ retrt->er_last = NULL;
-+
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_makeroute: "
-+ "calling rj_addroute now\n");
-+
-+ spin_lock_bh(&eroute_lock);
-+
-+ error = rj_addroute(&(retrt->er_eaddr), &(retrt->er_emask),
-+ rnh, retrt->er_rjt.rd_nodes);
-+
-+ spin_unlock_bh(&eroute_lock);
-+
-+ if(error) {
-+ sa_len = satot(&said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_makeroute: "
-+ "rj_addroute not able to insert eroute for SA:%s (error:%d)\n",
-+ sa_len ? sa : " (error)", error);
-+ if (retrt->er_ident_s.data)
-+ kfree(retrt->er_ident_s.data);
-+ if (retrt->er_ident_d.data)
-+ kfree(retrt->er_ident_d.data);
-+
-+ kfree(retrt);
-+
-+ return error;
-+ }
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (debug_eroute) {
-+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
-+/*
-+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
-+*/
-+ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_src, rd_mask((&(retrt->er_rjt)))->sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_dst, rd_mask((&(retrt->er_rjt)))->sen_ip_dst, 0, buf2, sizeof(buf2));
-+ sa_len = satot(&retrt->er_said, 0, sa, sizeof(sa));
-+
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_makeroute: "
-+ "pid=%05d "
-+ "count=%10d "
-+ "lasttime=%6d "
-+ "%-18s -> %-18s => %s\n",
-+ retrt->er_pid,
-+ retrt->er_count,
-+ (int)(jiffies/HZ - retrt->er_lasttime),
-+ buf1,
-+ buf2,
-+ sa_len ? sa : " (error)");
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_makeroute: "
-+ "succeeded.\n");
-+ return 0;
-+}
-+
-+struct eroute *
-+ipsec_findroute(struct sockaddr_encap *eaddr)
-+{
-+ struct radij_node *rn;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ char buf1[ADDRTOA_BUF], buf2[ADDRTOA_BUF];
-+
-+ if (debug_radij & DB_RJ_FINDROUTE) {
-+ addrtoa(eaddr->sen_ip_src, 0, buf1, sizeof(buf1));
-+ addrtoa(eaddr->sen_ip_dst, 0, buf2, sizeof(buf2));
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_findroute: "
-+ "%s:%d->%s:%d %d\n",
-+ buf1, ntohs(eaddr->sen_sport),
-+ buf2, ntohs(eaddr->sen_dport),
-+ eaddr->sen_proto);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ rn = rj_match((caddr_t)eaddr, rnh);
-+ if(rn) {
-+ KLIPS_PRINT(debug_eroute && sysctl_ipsec_debug_verbose,
-+ "klips_debug:ipsec_findroute: "
-+ "found, points to proto=%d, spi=%x, dst=%x.\n",
-+ ((struct eroute*)rn)->er_said.proto,
-+ ntohl(((struct eroute*)rn)->er_said.spi),
-+ ntohl(((struct eroute*)rn)->er_said.dst.u.v4.sin_addr.s_addr));
-+ }
-+ return (struct eroute *)rn;
-+}
-+
-+#ifdef CONFIG_PROC_FS
-+/** ipsec_rj_walker_procprint: print one line of eroute table output.
-+ *
-+ * Theoretical BUG: if w->length is less than the length
-+ * of some line we should produce, that line will never
-+ * be finished. In effect, the "file" will stop part way
-+ * through that line.
-+ */
-+int
-+ipsec_rj_walker_procprint(struct radij_node *rn, void *w0)
-+{
-+ struct eroute *ro = (struct eroute *)rn;
-+ struct rjtentry *rd = (struct rjtentry *)rn;
-+ struct wsbuf *w = (struct wsbuf *)w0;
-+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
-+ char buf3[16];
-+ char sa[SATOT_BUF];
-+ size_t sa_len, buf_len;
-+ struct sockaddr_encap *key, *mask;
-+
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:ipsec_rj_walker_procprint: "
-+ "rn=0p%p, w0=0p%p\n",
-+ rn,
-+ w0);
-+ if (rn->rj_b >= 0) {
-+ return 0;
-+ }
-+
-+ key = rd_key(rd);
-+ mask = rd_mask(rd);
-+
-+ if (key == NULL || mask == NULL) {
-+ return 0;
-+ }
-+
-+ buf_len = subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
-+ if(key->sen_sport != 0) {
-+ sprintf(buf1+buf_len-1, ":%d", ntohs(key->sen_sport));
-+ }
-+
-+ buf_len = subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
-+ if(key->sen_dport != 0) {
-+ sprintf(buf2+buf_len-1, ":%d", ntohs(key->sen_dport));
-+ }
-+
-+ buf3[0]='\0';
-+ if(key->sen_proto != 0) {
-+ sprintf(buf3, ":%d", key->sen_proto);
-+ }
-+
-+ sa_len = satot(&ro->er_said, 'x', sa, sizeof(sa));
-+ w->len += ipsec_snprintf(w->buffer + w->len,
-+ w->length - w->len,
-+ "%-10d "
-+ "%-18s -> %-18s => %s%s\n",
-+ ro->er_count,
-+ buf1,
-+ buf2,
-+ sa_len ? sa : " (error)",
-+ buf3);
-+
-+ {
-+ /* snprintf can only fill the last character with NUL
-+ * so the maximum useful character is w->length-1.
-+ * However, if w->length == 0, we cannot go back.
-+ * (w->length surely cannot be negative.)
-+ */
-+ int max_content = w->length > 0? w->length-1 : 0;
-+
-+ if (w->len >= max_content) {
-+ /* we've done all that can fit -- stop treewalking */
-+ w->len = max_content; /* truncate crap */
-+ return -ENOBUFS;
-+ } else {
-+ const off_t pos = w->begin + w->len; /* file position of end of what we've generated */
-+
-+ if (pos <= w->offset) {
-+ /* all is before first interesting character:
-+ * discard, but note where we are.
-+ */
-+ w->len = 0;
-+ w->begin = pos;
-+ }
-+ return 0;
-+ }
-+ }
-+}
-+#endif /* CONFIG_PROC_FS */
-+
-+int
-+ipsec_rj_walker_delete(struct radij_node *rn, void *w0)
-+{
-+ struct eroute *ro;
-+ struct rjtentry *rd = (struct rjtentry *)rn;
-+ struct radij_node *rn2;
-+ int error;
-+ struct sockaddr_encap *key, *mask;
-+
-+ key = rd_key(rd);
-+ mask = rd_mask(rd);
-+
-+ if(!key || !mask) {
-+ return -ENODATA;
-+ }
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(debug_radij) {
-+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
-+ subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:ipsec_rj_walker_delete: "
-+ "deleting: %s -> %s\n",
-+ buf1,
-+ buf2);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ if((error = rj_delete(key, mask, rnh, &rn2))) {
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:ipsec_rj_walker_delete: "
-+ "rj_delete failed with error=%d.\n", error);
-+ return error;
-+ }
-+
-+ if(rn2 != rn) {
-+ printk("klips_debug:ipsec_rj_walker_delete: "
-+ "tried to delete a different node?!? This should never happen!\n");
-+ }
-+
-+ ro = (struct eroute *)rn;
-+
-+ if (ro->er_ident_s.data)
-+ kfree(ro->er_ident_s.data);
-+ if (ro->er_ident_d.data)
-+ kfree(ro->er_ident_d.data);
-+
-+ memset((caddr_t)rn, 0, sizeof (struct eroute));
-+ kfree(rn);
-+
-+ return 0;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.70 2004/04/25 21:10:52 ken
-+ * Pull in dhr's changes from FreeS/WAN 2.06
-+ *
-+ * Revision 1.69 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.68 2004/03/28 20:27:20 paul
-+ * Included tested and confirmed fixes mcr made and dhr verified for
-+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
-+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
-+ * dhr. (thanks dhr!)
-+ *
-+ * Revision 1.67.4.1 2004/04/05 04:30:46 mcr
-+ * patches for alg-branch to compile/work with 2.x openswan
-+ *
-+ * Revision 1.67 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.66.24.2 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.66.24.1 2003/09/21 13:59:56 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.66 2002/10/12 23:11:53 dhr
-+ *
-+ * [KenB + DHR] more 64-bit cleanup
-+ *
-+ * Revision 1.65 2002/09/20 05:01:40 rgb
-+ * Added memory allocation debugging.
-+ *
-+ * Revision 1.64 2002/05/31 01:46:05 mcr
-+ * added && sysctl_ipsec_debug_verbose verbose to ipsec_findroute
-+ * as requested in PR#14.
-+ *
-+ * Revision 1.63 2002/05/23 07:14:11 rgb
-+ * Cleaned up %p variants to 0p%p for test suite cleanup.
-+ *
-+ * Revision 1.62 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.61 2002/04/24 07:36:29 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_radij.c,v
-+ *
-+ * Revision 1.60 2002/02/19 23:59:45 rgb
-+ * Removed redundant compiler directives.
-+ *
-+ * Revision 1.59 2002/02/06 04:13:47 mcr
-+ * missing #ifdef CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.58 2002/01/29 17:17:56 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.57 2002/01/29 04:00:52 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.56 2002/01/29 02:13:17 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.55 2001/11/26 09:23:48 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.53.2.1 2001/09/25 02:26:32 mcr
-+ * headers adjusted for new usage.
-+ *
-+ * Revision 1.54 2001/10/18 04:45:20 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/freeswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.53 2001/09/19 17:19:40 rgb
-+ * Debug output bugfix for NetCelo's PF_KEY ident patch.
-+ *
-+ * Revision 1.52 2001/09/19 16:33:37 rgb
-+ * Temporarily disable ident fields to /proc/net/ipsec_eroute.
-+ *
-+ * Revision 1.51 2001/09/15 16:24:04 rgb
-+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
-+ *
-+ * Revision 1.50 2001/09/14 16:58:36 rgb
-+ * Added support for storing the first and last packets through a HOLD.
-+ *
-+ * Revision 1.49 2001/09/08 21:13:32 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.48 2001/06/15 04:12:56 rgb
-+ * Fixed kernel memory allocation error return code polarity bug.
-+ *
-+ * Revision 1.47 2001/06/14 19:35:09 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.46 2001/06/08 08:47:18 rgb
-+ * Fixed for debug disabled.
-+ *
-+ * Revision 1.45 2001/05/27 06:12:11 rgb
-+ * Added structures for pid, packet count and last access time to eroute.
-+ * Added packet count to beginning of /proc/net/ipsec_eroute.
-+ *
-+ * Revision 1.44 2001/05/03 19:41:01 rgb
-+ * Initialise error return variable.
-+ * Use more appropriate return value for ipsec_rj_walker_delete().
-+ *
-+ * Revision 1.43 2001/02/27 22:24:54 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.42 2001/02/27 06:21:57 rgb
-+ * Added findroute success instrumentation.
-+ *
-+ * Revision 1.41 2000/11/06 04:32:08 rgb
-+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
-+ *
-+ * Revision 1.40 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.39 2000/08/30 05:25:20 rgb
-+ * Correct debug text in ipsec_breakroute() from incorrect
-+ * "ipsec_callback".
-+ *
-+ * Revision 1.38 2000/07/28 14:58:31 rgb
-+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
-+ *
-+ * Revision 1.37 2000/03/16 14:02:50 rgb
-+ * Fixed debug scope to enable compilation with debug off.
-+ *
-+ * Revision 1.36 2000/01/21 06:14:46 rgb
-+ * Added debugging text to ipsec_rj_walker_delete().
-+ * Set return code to negative for consistency.
-+ *
-+ * Revision 1.35 1999/11/23 23:05:24 rgb
-+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
-+ *
-+ * Revision 1.34 1999/11/18 04:13:56 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
-+ *
-+ * Revision 1.33 1999/11/17 15:53:39 rgb
-+ * Changed all occurrences of #include "../../../lib/freeswan.h"
-+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
-+ * klips/net/ipsec/Makefile.
-+ *
-+ * Revision 1.32 1999/10/26 13:58:33 rgb
-+ * Put spinlock flags variable declaration outside the debug compiler
-+ * directive to enable compilation with debug shut off.
-+ *
-+ * Revision 1.31 1999/10/15 22:13:29 rgb
-+ * Clean out cruft.
-+ * Align /proc/net/ipsec_eroute output for easier readability.
-+ * Fix double linefeed in radij debug output.
-+ * Fix double locking bug that locks up 2.0.36 but not 2.0.38.
-+ *
-+ * Revision 1.30 1999/10/08 18:37:33 rgb
-+ * Fix end-of-line spacing to sate whining PHMs.
-+ *
-+ * Revision 1.29 1999/10/03 18:52:45 rgb
-+ * Spinlock support for 2.0.xx.
-+ * Dumb return code spin_unlock fix.
-+ *
-+ * Revision 1.28 1999/10/01 16:22:24 rgb
-+ * Switch from assignment init. to functional init. of spinlocks.
-+ *
-+ * Revision 1.27 1999/10/01 15:44:53 rgb
-+ * Move spinlock header include to 2.1> scope.
-+ *
-+ * Revision 1.26 1999/10/01 00:01:23 rgb
-+ * Added eroute structure locking.
-+ *
-+ * Revision 1.25 1999/06/10 16:07:30 rgb
-+ * Silence delete eroute on no debug.
-+ *
-+ * Revision 1.24 1999/05/09 03:25:36 rgb
-+ * Fix bug introduced by 2.2 quick-and-dirty patch.
-+ *
-+ * Revision 1.23 1999/05/05 22:02:31 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.22 1999/04/29 15:17:23 rgb
-+ * Add return values to init and cleanup functions.
-+ * Add sanity checking for null pointer arguments.
-+ *
-+ * Revision 1.21 1999/04/11 00:28:58 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.20 1999/04/06 04:54:26 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.19 1999/02/17 16:50:35 rgb
-+ * Clean out unused cruft.
-+ * Consolidate for space and speed efficiency.
-+ * Convert DEBUG_IPSEC to KLIPS_PRINT
-+ *
-+ * Revision 1.18 1999/01/22 06:22:06 rgb
-+ * Cruft clean-out.
-+ * 64-bit clean-up.
-+ *
-+ * Revision 1.17 1998/12/02 03:09:39 rgb
-+ * Clean up debug printing conditionals to compile with debugging off.
-+ *
-+ * Revision 1.16 1998/12/01 13:49:39 rgb
-+ * Wrap version info printing in debug switches.
-+ *
-+ * Revision 1.15 1998/11/30 13:22:54 rgb
-+ * Rationalised all the klips kernel file headers. They are much shorter
-+ * now and won't conflict under RH5.2.
-+ *
-+ * Revision 1.14 1998/10/31 06:48:17 rgb
-+ * Fixed up comments in #endif directives.
-+ *
-+ * Revision 1.13 1998/10/27 13:48:09 rgb
-+ * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts.
-+ * Fixed less(1) truncated output bug.
-+ * Code clean-up.
-+ *
-+ * Revision 1.12 1998/10/25 02:41:36 rgb
-+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an
-+ * argument to be able to transmit more infomation about errors.
-+ * Fix cut-and-paste debug statement identifier.
-+ *
-+ * Revision 1.11 1998/10/22 06:45:39 rgb
-+ * Cleaned up cruft.
-+ * Convert to use satoa for printk.
-+ *
-+ * Revision 1.10 1998/10/19 14:44:28 rgb
-+ * Added inclusion of freeswan.h.
-+ * sa_id structure implemented and used: now includes protocol.
-+ *
-+ * Revision 1.9 1998/10/09 04:30:52 rgb
-+ * Added 'klips_debug' prefix to all klips printk debug statements.
-+ * Deleted old commented out cruft.
-+ *
-+ * Revision 1.8 1998/08/06 17:24:23 rgb
-+ * Fix addrtoa return code bug from stale manpage advice preventing packets
-+ * from being erouted.
-+ *
-+ * Revision 1.7 1998/08/06 07:44:59 rgb
-+ * Fixed /proc/net/ipsec_eroute subnettoa and addrtoa return value bug that
-+ * ended up in nothing being printed.
-+ *
-+ * Revision 1.6 1998/08/05 22:16:41 rgb
-+ * Cleanup to prevent cosmetic errors (ie. debug output) from being fatal.
-+ *
-+ * Revision 1.5 1998/07/29 20:38:44 rgb
-+ * Debug and fix subnettoa and addrtoa output.
-+ *
-+ * Revision 1.4 1998/07/28 00:02:39 rgb
-+ * Converting to exclusive use of addrtoa.
-+ * Fix eroute delete.
-+ *
-+ * Revision 1.3 1998/07/14 18:21:26 rgb
-+ * Add function to clear the eroute table.
-+ *
-+ * Revision 1.2 1998/06/23 02:59:14 rgb
-+ * Added debugging output to eroute add/delete routines.
-+ *
-+ * Revision 1.9 1998/06/18 21:29:06 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid kernel
-+ * build scripts happier in presence of symbolic links
-+ *
-+ * Revision 1.8 1998/06/05 02:32:26 rgb
-+ * Fix spi ntoh kernel debug output.
-+ *
-+ * Revision 1.7 1998/05/25 20:30:37 rgb
-+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
-+ *
-+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
-+ * add ipsec_rj_walker_delete.
-+ *
-+ * Revision 1.6 1998/05/21 13:08:57 rgb
-+ * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of
-+ * information is available for printout.
-+ *
-+ * Revision 1.5 1998/05/18 21:35:55 rgb
-+ * Clean up output for numerical consistency and readability. Zero freed
-+ * eroute memory.
-+ *
-+ * Revision 1.4 1998/04/21 21:28:58 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.3 1998/04/14 17:30:39 rgb
-+ * Fix up compiling errors for radij tree memory reclamation.
-+ *
-+ * Revision 1.2 1998/04/12 22:03:23 rgb
-+ * Updated ESP-3DES-HMAC-MD5-96,
-+ * ESP-DES-HMAC-MD5-96,
-+ * AH-HMAC-MD5-96,
-+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
-+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
-+ *
-+ * Fixed eroute references in /proc/net/ipsec*.
-+ *
-+ * Started to patch module unloading memory leaks in ipsec_netlink and
-+ * radij tree unloading.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:10 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * No changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:39:04 ji
-+ * Minor cleanups.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_rcv.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1922 @@
-+/*
-+ * receive code
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998-2003 Richard Guy Briggs.
-+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipsec_rcv_c_version[] = "RCSID $Id$";
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <net/udp.h>
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define proto_priv cb
-+#endif /* NET21 */
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h"
-+
-+#include "openswan/ipsec_auth.h"
-+
-+#include "openswan/ipsec_esp.h"
-+
-+#ifdef CONFIG_IPSEC_AH
-+#include "openswan/ipsec_ah.h"
-+#endif /* CONFIG_IPSEC_AH */
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+#include "openswan/ipsec_ipcomp.h"
-+#endif /* CONFIG_IPSEC_COMP */
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+#include "openswan/ipsec_alg.h"
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_rcv = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+int sysctl_ipsec_inbound_policy_check = 1;
-+
-+/* This is a private use protocol, and AT&T should be ashamed. They should have
-+ * used protocol # 59, which is "no next header" instead of 0xFE.
-+ */
-+#ifndef IPPROTO_ATT_HEARTBEAT
-+#define IPPROTO_ATT_HEARTBEAT 0xFE
-+#endif
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+void
-+ipsec_dmp(char *s, caddr_t bb, int len)
-+{
-+ int i;
-+ unsigned char *b = bb;
-+
-+
-+ printk(KERN_INFO "klips_debug:ipsec_tunnel_:dmp: "
-+ "at %s, len=%d:",
-+ s,
-+ len);
-+ for (i=0; i < len; i++) {
-+ if(!(i%16)){
-+ printk("\nklips_debug: ");
-+ }
-+ printk(" %02x", *b++);
-+ }
-+ printk("\n");
-+}
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+/*
-+ * Check-replay-window routine, adapted from the original
-+ * by J. Hughes, from draft-ietf-ipsec-esp-des-md5-03.txt
-+ *
-+ * This is a routine that implements a 64 packet window. This is intend-
-+ * ed on being an implementation sample.
-+ */
-+
-+DEBUG_NO_STATIC int
-+ipsec_checkreplaywindow(struct ipsec_sa*ipsp, __u32 seq)
-+{
-+ __u32 diff;
-+
-+ if (ipsp->ips_replaywin == 0) /* replay shut off */
-+ return 1;
-+ if (seq == 0)
-+ return 0; /* first == 0 or wrapped */
-+
-+ /* new larger sequence number */
-+ if (seq > ipsp->ips_replaywin_lastseq) {
-+ return 1; /* larger is good */
-+ }
-+ diff = ipsp->ips_replaywin_lastseq - seq;
-+
-+ /* too old or wrapped */ /* if wrapped, kill off SA? */
-+ if (diff >= ipsp->ips_replaywin) {
-+ return 0;
-+ }
-+ /* this packet already seen */
-+ if (ipsp->ips_replaywin_bitmap & (1 << diff))
-+ return 0;
-+ return 1; /* out of order but good */
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_updatereplaywindow(struct ipsec_sa*ipsp, __u32 seq)
-+{
-+ __u32 diff;
-+
-+ if (ipsp->ips_replaywin == 0) /* replay shut off */
-+ return 1;
-+ if (seq == 0)
-+ return 0; /* first == 0 or wrapped */
-+
-+ /* new larger sequence number */
-+ if (seq > ipsp->ips_replaywin_lastseq) {
-+ diff = seq - ipsp->ips_replaywin_lastseq;
-+
-+ /* In win, set bit for this pkt */
-+ if (diff < ipsp->ips_replaywin)
-+ ipsp->ips_replaywin_bitmap =
-+ (ipsp->ips_replaywin_bitmap << diff) | 1;
-+ else
-+ /* This packet has way larger seq num */
-+ ipsp->ips_replaywin_bitmap = 1;
-+
-+ if(seq - ipsp->ips_replaywin_lastseq - 1 > ipsp->ips_replaywin_maxdiff) {
-+ ipsp->ips_replaywin_maxdiff = seq - ipsp->ips_replaywin_lastseq - 1;
-+ }
-+ ipsp->ips_replaywin_lastseq = seq;
-+ return 1; /* larger is good */
-+ }
-+ diff = ipsp->ips_replaywin_lastseq - seq;
-+
-+ /* too old or wrapped */ /* if wrapped, kill off SA? */
-+ if (diff >= ipsp->ips_replaywin) {
-+/*
-+ if(seq < 0.25*max && ipsp->ips_replaywin_lastseq > 0.75*max) {
-+ ipsec_sa_delchain(ipsp);
-+ }
-+*/
-+ return 0;
-+ }
-+ /* this packet already seen */
-+ if (ipsp->ips_replaywin_bitmap & (1 << diff))
-+ return 0;
-+ ipsp->ips_replaywin_bitmap |= (1 << diff); /* mark as seen */
-+ return 1; /* out of order but good */
-+}
-+
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+struct auth_alg ipsec_rcv_md5[]={
-+ {MD5Init, MD5Update, MD5Final, AHMD596_ALEN}
-+};
-+
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+struct auth_alg ipsec_rcv_sha1[]={
-+ {SHA1Init, SHA1Update, SHA1Final, AHSHA196_ALEN}
-+};
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+
-+enum ipsec_rcv_value
-+ipsec_rcv_decap_once(struct ipsec_rcv_state *irs, struct xform_functions *proto_funcs)
-+{
-+ int iphlen;
-+ unsigned char *dat;
-+ __u8 proto;
-+ struct in_addr ipsaddr;
-+ struct in_addr ipdaddr;
-+ int replay = 0; /* replay value in AH or ESP packet */
-+ struct ipsec_sa* ipsnext = NULL; /* next SA towards inside of packet */
-+ struct ipsec_sa *newipsp;
-+ struct iphdr *ipp;
-+ struct sk_buff *skb;
-+#ifdef CONFIG_IPSEC_ALG
-+ struct ipsec_alg_auth *ixt_a=NULL;
-+#endif /* CONFIG_IPSEC_ALG */
-+
-+ skb = irs->skb;
-+ irs->len = skb->len;
-+ dat = skb->data;
-+ ipp = irs->ipp;
-+ proto = ipp->protocol;
-+ ipsaddr.s_addr = ipp->saddr;
-+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
-+ ipdaddr.s_addr = ipp->daddr;
-+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
-+
-+ iphlen = ipp->ihl << 2;
-+ irs->iphlen=iphlen;
-+ ipp->check = 0; /* we know the sum is good */
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv_decap_once: "
-+ "decap (%d) from %s -> %s\n",
-+ proto, irs->ipsaddr_txt, irs->ipdaddr_txt);
-+
-+ /*
-+ * Find tunnel control block and (indirectly) call the
-+ * appropriate tranform routine. The resulting sk_buf
-+ * is a valid IP packet ready to go through input processing.
-+ */
-+
-+ irs->said.dst.u.v4.sin_addr.s_addr = ipp->daddr;
-+ irs->said.dst.u.v4.sin_family = AF_INET;
-+
-+ if(proto_funcs->rcv_checks) {
-+ enum ipsec_rcv_value retval =
-+ (*proto_funcs->rcv_checks)(irs, skb);
-+
-+ if(retval < 0) {
-+ return retval;
-+ }
-+ }
-+
-+ irs->said.proto = proto;
-+ irs->sa_len = satot(&irs->said, 0, irs->sa, sizeof(irs->sa));
-+ if(irs->sa_len == 0) {
-+ strcpy(irs->sa, "(error)");
-+ }
-+
-+ newipsp = ipsec_sa_getbyid(&irs->said);
-+ if (newipsp == NULL) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "no ipsec_sa for SA:%s: incoming packet with no SA dropped\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_SAIDNOTFOUND;
-+ }
-+
-+ /* MCR - XXX this is bizarre. ipsec_sa_getbyid returned it, having incremented the refcount,
-+ * why in the world would we decrement it here?
-+
-+ ipsec_sa_put(irs->ipsp);*/ /* incomplete */
-+
-+ /* If it is in larval state, drop the packet, we cannot process yet. */
-+ if(newipsp->ips_state == SADB_SASTATE_LARVAL) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "ipsec_sa in larval state, cannot be used yet, dropping packet.\n");
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ ipsec_sa_put(newipsp);
-+ return IPSEC_RCV_SAIDNOTLIVE;
-+ }
-+
-+ if(newipsp->ips_state == SADB_SASTATE_DEAD) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "ipsec_sa in dead state, cannot be used any more, dropping packet.\n");
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ ipsec_sa_put(newipsp);
-+ return IPSEC_RCV_SAIDNOTLIVE;
-+ }
-+
-+ if(sysctl_ipsec_inbound_policy_check) {
-+ if(irs->ipp->saddr != ((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n",
-+ irs->sa_len ? irs->sa : " (error)",
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ ipsec_sa_put(newipsp);
-+ return IPSEC_RCV_FAILEDINBOUND;
-+ }
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s, src=%s of pkt agrees with expected SA source address policy.\n",
-+ irs->sa_len ? irs->sa : " (error)",
-+ irs->ipsaddr_txt);
-+
-+ /*
-+ * at this point, we have looked up a new SA, and we want to make sure that if this
-+ * isn't the first SA in the list, that the previous SA actually points at this one.
-+ */
-+ if(irs->ipsp) {
-+ if(irs->ipsp->ips_inext != newipsp) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "unexpected SA:%s: does not agree with ips->inext policy, dropped\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ ipsec_sa_put(newipsp);
-+ return IPSEC_RCV_FAILEDINBOUND;
-+ }
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s grouping from previous SA is OK.\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ } else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s First SA in group.\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ }
-+
-+ /*
-+ * previously, at this point, we checked if the back pointer from the new SA that
-+ * we just found matched the back pointer. But, we won't do this check anymore,
-+ * because we want to be able to nest SAs
-+ */
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "natt_type=%u tdbp->ips_natt_type=%u : %s\n",
-+ irs->natt_type, newipsp->ips_natt_type,
-+ (irs->natt_type==newipsp->ips_natt_type)?"ok":"bad");
-+ if (irs->natt_type != newipsp->ips_natt_type) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s does not agree with expected NAT-T policy.\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ ipsec_sa_put(newipsp);
-+ return IPSEC_RCV_FAILEDINBOUND;
-+ }
-+#endif
-+ }
-+
-+ /* okay, SA checks out, so free any previous SA, and record a new one */
-+
-+ if(irs->ipsp) {
-+ ipsec_sa_put(irs->ipsp);
-+ }
-+ irs->ipsp=newipsp;
-+
-+ /* note that the outer code will free the irs->ipsp if there is an error */
-+
-+
-+ /* now check the lifetimes */
-+ if(ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_bytes, "bytes",
-+ irs->sa, ipsec_life_countbased, ipsec_incoming,
-+ irs->ipsp) == ipsec_life_harddied ||
-+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "addtime",
-+ irs->sa, ipsec_life_timebased, ipsec_incoming,
-+ irs->ipsp) == ipsec_life_harddied ||
-+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "usetime",
-+ irs->sa, ipsec_life_timebased, ipsec_incoming,
-+ irs->ipsp) == ipsec_life_harddied ||
-+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_packets, "packets",
-+ irs->sa, ipsec_life_countbased, ipsec_incoming,
-+ irs->ipsp) == ipsec_life_harddied) {
-+ ipsec_sa_delchain(irs->ipsp);
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv_decap_once: "
-+ "decap (%d) failed lifetime check\n",
-+ proto);
-+
-+ return IPSEC_RCV_LIFETIMEFAILED;
-+ }
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if ((irs->natt_type) &&
-+ ( (irs->ipp->saddr != (((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr)) ||
-+ (irs->natt_sport != newipsp->ips_natt_sport)
-+ )) {
-+ struct sockaddr sipaddr;
-+ /** Advertise NAT-T addr change to pluto **/
-+ sipaddr.sa_family = AF_INET;
-+ ((struct sockaddr_in*)&sipaddr)->sin_addr.s_addr = irs->ipp->saddr;
-+ ((struct sockaddr_in*)&sipaddr)->sin_port = htons(irs->natt_sport);
-+ pfkey_nat_t_new_mapping(newipsp, &sipaddr, irs->natt_sport);
-+ /**
-+ * Then allow or block packet depending on
-+ * sysctl_ipsec_inbound_policy_check.
-+ *
-+ * In all cases, pluto will update SA if new mapping is
-+ * accepted.
-+ */
-+ if (sysctl_ipsec_inbound_policy_check) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s, src=%s:%u of pkt does not agree with expected "
-+ "SA source address policy (pluto has been informed).\n",
-+ irs->sa_len ? irs->sa : " (error)",
-+ irs->ipsaddr_txt, irs->natt_sport);
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ ipsec_sa_put(newipsp);
-+ return IPSEC_RCV_FAILEDINBOUND;
-+ }
-+ }
-+#endif
-+
-+ irs->authfuncs=NULL;
-+ /* authenticate, if required */
-+#ifdef CONFIG_IPSEC_ALG
-+ if ((ixt_a=irs->ipsp->ips_alg_auth)) {
-+ irs->authlen = AHHMAC_HASHLEN;
-+ irs->authfuncs = NULL;
-+ irs->ictx = NULL;
-+ irs->octx = NULL;
-+ irs->ictx_len = 0;
-+ irs->octx_len = 0;
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "authalg=%d authlen=%d\n",
-+ irs->ipsp->ips_authalg,
-+ irs->authlen);
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(irs->ipsp->ips_authalg) {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5:
-+ irs->authlen = AHHMAC_HASHLEN;
-+ irs->authfuncs = ipsec_rcv_md5;
-+ irs->ictx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx;
-+ irs->octx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx;
-+ irs->ictx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx);
-+ irs->octx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx);
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA:
-+ irs->authlen = AHHMAC_HASHLEN;
-+ irs->authfuncs = ipsec_rcv_sha1;
-+ irs->ictx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx;
-+ irs->octx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx;
-+ irs->ictx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx);
-+ irs->octx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx);
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ case AH_NONE:
-+ irs->authlen = 0;
-+ irs->authfuncs = NULL;
-+ irs->ictx = NULL;
-+ irs->octx = NULL;
-+ irs->ictx_len = 0;
-+ irs->octx_len = 0;
-+ break;
-+ default:
-+ irs->ipsp->ips_errs.ips_alg_errs += 1;
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_BADAUTH;
-+ }
-+
-+ irs->ilen = irs->len - iphlen - irs->authlen;
-+ if(irs->ilen <= 0) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "runt %s packet with no data, dropping.\n",
-+ (proto == IPPROTO_ESP ? "esp" : "ah"));
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_BADLEN;
-+ }
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if(irs->authfuncs || ixt_a) {
-+#else
-+ if(irs->authfuncs) {
-+#endif
-+ unsigned char *authenticator = NULL;
-+
-+ if(proto_funcs->rcv_setup_auth) {
-+ enum ipsec_rcv_value retval
-+ = (*proto_funcs->rcv_setup_auth)(irs, skb,
-+ &replay,
-+ &authenticator);
-+ if(retval < 0) {
-+ return retval;
-+ }
-+ }
-+
-+ if(!authenticator) {
-+ irs->ipsp->ips_errs.ips_auth_errs += 1;
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_BADAUTH;
-+ }
-+
-+ if(!ipsec_checkreplaywindow(irs->ipsp, replay)) {
-+ irs->ipsp->ips_errs.ips_replaywin_errs += 1;
-+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
-+ "klips_debug:ipsec_rcv: "
-+ "duplicate frame from %s, packet dropped\n",
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_REPLAYFAILED;
-+ }
-+
-+ /*
-+ * verify authenticator
-+ */
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "encalg = %d, authalg = %d.\n",
-+ irs->ipsp->ips_encalg,
-+ irs->ipsp->ips_authalg);
-+
-+ /* calculate authenticator */
-+ if(proto_funcs->rcv_calc_auth == NULL) {
-+ return IPSEC_RCV_BADAUTH;
-+ }
-+ (*proto_funcs->rcv_calc_auth)(irs, skb);
-+
-+ if (memcmp(irs->hash, authenticator, irs->authlen)) {
-+ irs->ipsp->ips_errs.ips_auth_errs += 1;
-+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
-+ "klips_debug:ipsec_rcv: "
-+ "auth failed on incoming packet from %s: hash=%08x%08x%08x auth=%08x%08x%08x, dropped\n",
-+ irs->ipsaddr_txt,
-+ ntohl(*(__u32*)&irs->hash[0]),
-+ ntohl(*(__u32*)&irs->hash[4]),
-+ ntohl(*(__u32*)&irs->hash[8]),
-+ ntohl(*(__u32*)authenticator),
-+ ntohl(*((__u32*)authenticator + 1)),
-+ ntohl(*((__u32*)authenticator + 2)));
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_AUTHFAILED;
-+ } else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "authentication successful.\n");
-+ }
-+
-+ /* Crypto hygiene: clear memory used to calculate autheticator.
-+ * The length varies with the algorithm.
-+ */
-+ memset(irs->hash, 0, irs->authlen);
-+
-+ /* If the sequence number == 0, expire SA, it had rolled */
-+ if(irs->ipsp->ips_replaywin && !replay /* !irs->ipsp->ips_replaywin_lastseq */) {
-+ ipsec_sa_delchain(irs->ipsp);
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "replay window counter rolled, expiring SA.\n");
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_REPLAYROLLED;
-+ }
-+
-+ /* now update the replay counter */
-+ if (!ipsec_updatereplaywindow(irs->ipsp, replay)) {
-+ irs->ipsp->ips_errs.ips_replaywin_errs += 1;
-+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
-+ "klips_debug:ipsec_rcv: "
-+ "duplicate frame from %s, packet dropped\n",
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_REPLAYROLLED;
-+ }
-+ }
-+
-+ if(proto_funcs->rcv_decrypt) {
-+ enum ipsec_rcv_value retval =
-+ (*proto_funcs->rcv_decrypt)(irs);
-+
-+ if(retval != IPSEC_RCV_OK) {
-+ return retval;
-+ }
-+ }
-+
-+ /*
-+ * Adjust pointers
-+ */
-+ skb = irs->skb;
-+ irs->len = skb->len;
-+ dat = skb->data;
-+
-+#ifdef NET_21
-+/* skb->h.ipiph=(struct iphdr *)skb->data; */
-+ skb->nh.raw = skb->data;
-+ skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2);
-+
-+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
-+#else /* NET_21 */
-+ skb->h.iph=(struct iphdr *)skb->data;
-+ skb->ip_hdr=(struct iphdr *)skb->data;
-+ memset(skb->proto_priv, 0, sizeof(struct options));
-+#endif /* NET_21 */
-+
-+ ipp = (struct iphdr *)dat;
-+ ipsaddr.s_addr = ipp->saddr;
-+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
-+ ipdaddr.s_addr = ipp->daddr;
-+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
-+ /*
-+ * Discard the original ESP/AH header
-+ */
-+ ipp->protocol = irs->next_header;
-+
-+ ipp->check = 0; /* NOTE: this will be included in checksum */
-+ ipp->check = ip_fast_csum((unsigned char *)dat, iphlen >> 2);
-+
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "after <%s%s%s>, SA:%s:\n",
-+ IPS_XFORM_NAME(irs->ipsp),
-+ irs->sa_len ? irs->sa : " (error)");
-+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
-+
-+ skb->protocol = htons(ETH_P_IP);
-+ skb->ip_summed = 0;
-+
-+ ipsnext = irs->ipsp->ips_inext;
-+ if(sysctl_ipsec_inbound_policy_check) {
-+ if(ipsnext) {
-+ if(
-+ ipp->protocol != IPPROTO_AH
-+ && ipp->protocol != IPPROTO_ESP
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ && ipp->protocol != IPPROTO_COMP
-+ && (ipsnext->ips_said.proto != IPPROTO_COMP
-+ || ipsnext->ips_inext)
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ && ipp->protocol != IPPROTO_IPIP
-+ && ipp->protocol != 0xFE /* added to support heartbeats to AT&T SIG/GIG */
-+ ) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "packet with incomplete policy dropped, last successful SA:%s.\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_FAILEDINBOUND;
-+ }
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s, Another IPSEC header to process.\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ } else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "No ips_inext from this SA:%s.\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ }
-+ }
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ /* update ipcomp ratio counters, even if no ipcomp packet is present */
-+ if (ipsnext
-+ && ipsnext->ips_said.proto == IPPROTO_COMP
-+ && ipp->protocol != IPPROTO_COMP) {
-+ ipsnext->ips_comp_ratio_cbytes += ntohs(ipp->tot_len);
-+ ipsnext->ips_comp_ratio_dbytes += ntohs(ipp->tot_len);
-+ }
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+ irs->ipsp->ips_life.ipl_bytes.ipl_count += irs->len;
-+ irs->ipsp->ips_life.ipl_bytes.ipl_last = irs->len;
-+
-+ if(!irs->ipsp->ips_life.ipl_usetime.ipl_count) {
-+ irs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
-+ }
-+ irs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
-+ irs->ipsp->ips_life.ipl_packets.ipl_count += 1;
-+
-+#ifdef CONFIG_NETFILTER
-+ if(proto == IPPROTO_ESP || proto == IPPROTO_AH) {
-+ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_MASK))))
-+ | IPsecSAref2NFmark(IPsecSA2SAref(irs->ipsp));
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "%s SA sets skb->nfmark=0x%x.\n",
-+ proto == IPPROTO_ESP ? "ESP" : "AH",
-+ (unsigned)skb->nfmark);
-+ }
-+#endif /* CONFIG_NETFILTER */
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+
-+int
-+#ifdef PROTO_HANDLER_SINGLE_PARM
-+ipsec_rcv(struct sk_buff *skb)
-+#else /* PROTO_HANDLER_SINGLE_PARM */
-+#ifdef NET_21
-+ipsec_rcv(struct sk_buff *skb, unsigned short xlen)
-+#else /* NET_21 */
-+ipsec_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
-+ __u32 daddr_unused, unsigned short xlen, __u32 saddr,
-+ int redo, struct inet_protocol *protocol)
-+#endif /* NET_21 */
-+#endif /* PROTO_HANDLER_SINGLE_PARM */
-+{
-+#ifdef NET_21
-+#ifdef CONFIG_IPSEC_DEBUG
-+ struct device *dev = skb->dev;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#endif /* NET_21 */
-+ unsigned char protoc;
-+ struct iphdr *ipp;
-+ struct ipsec_sa *ipsp = NULL;
-+ struct net_device_stats *stats = NULL; /* This device's statistics */
-+ struct device *ipsecdev = NULL, *prvdev;
-+ struct ipsecpriv *prv;
-+ char name[9];
-+ int i;
-+ struct in_addr ipsaddr;
-+ struct in_addr ipdaddr;
-+
-+ struct ipsec_sa* ipsnext = NULL; /* next SA towards inside of packet */
-+ struct ipsec_rcv_state irs;
-+
-+ /* Don't unlink in the middle of a turnaround */
-+ MOD_INC_USE_COUNT;
-+
-+ memset(&irs, 0, sizeof(struct ipsec_rcv_state));
-+
-+ if (skb == NULL) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NULL skb passed in.\n");
-+ goto rcvleave;
-+ }
-+
-+ if (skb->data == NULL) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NULL skb->data passed in, packet is bogus, dropping.\n");
-+ goto rcvleave;
-+ }
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if (skb->sk && skb->nh.iph && skb->nh.iph->protocol==IPPROTO_UDP) {
-+ /**
-+ * Packet comes from udp_queue_rcv_skb so it is already defrag,
-+ * checksum verified, ... (ie safe to use)
-+ *
-+ * If the packet is not for us, return -1 and udp_queue_rcv_skb
-+ * will continue to handle it (do not kfree skb !!).
-+ */
-+#ifndef UDP_OPT_IN_SOCK
-+ struct udp_opt {
-+ __u32 esp_in_udp;
-+ };
-+ struct udp_opt *tp = (struct udp_opt *)&(skb->sk->tp_pinfo.af_tcp);
-+#else
-+ struct udp_opt *tp = &(skb->sk->tp_pinfo.af_udp);
-+#endif
-+ struct iphdr *ip = (struct iphdr *)skb->nh.iph;
-+ struct udphdr *udp = (struct udphdr *)((__u32 *)ip+ip->ihl);
-+ __u8 *udpdata = (__u8 *)udp + sizeof(struct udphdr);
-+ __u32 *udpdata32 = (__u32 *)udpdata;
-+
-+ irs.natt_sport = ntohs(udp->source);
-+ irs.natt_dport = ntohs(udp->dest);
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "suspected ESPinUDP packet (NAT-Traversal) [%d].\n",
-+ tp->esp_in_udp);
-+ KLIPS_IP_PRINT(debug_rcv, ip);
-+
-+ if (udpdata < skb->tail) {
-+ unsigned int len = skb->tail - udpdata;
-+ if ((len==1) && (udpdata[0]==0xff)) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ /* not IPv6 compliant message */
-+ "NAT-keepalive from %d.%d.%d.%d.\n", NIPQUAD(ip->saddr));
-+ goto rcvleave;
-+ }
-+ else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_IKE) &&
-+ (len > (2*sizeof(__u32) + sizeof(struct esphdr))) &&
-+ (udpdata32[0]==0) && (udpdata32[1]==0) ) {
-+ /* ESP Packet with Non-IKE header */
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "ESPinUDP pkt with Non-IKE - spi=0x%x\n",
-+ ntohl(udpdata32[2]));
-+ irs.natt_type = ESPINUDP_WITH_NON_IKE;
-+ irs.natt_len = sizeof(struct udphdr)+(2*sizeof(__u32));
-+ }
-+ else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_ESP) &&
-+ (len > sizeof(struct esphdr)) &&
-+ (udpdata32[0]!=0) ) {
-+ /* ESP Packet without Non-ESP header */
-+ irs.natt_type = ESPINUDP_WITH_NON_ESP;
-+ irs.natt_len = sizeof(struct udphdr);
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "ESPinUDP pkt without Non-ESP - spi=0x%x\n",
-+ ntohl(udpdata32[0]));
-+ }
-+ else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "IKE packet - not handled here\n");
-+ MOD_DEC_USE_COUNT;
-+ return -1;
-+ }
-+ }
-+ else {
-+ MOD_DEC_USE_COUNT;
-+ return -1;
-+ }
-+ }
-+#endif
-+
-+#ifdef IPH_is_SKB_PULLED
-+ /* In Linux 2.4.4, the IP header has been skb_pull()ed before the
-+ packet is passed to us. So we'll skb_push() to get back to it. */
-+ if (skb->data == skb->h.raw) {
-+ skb_push(skb, skb->h.raw - skb->nh.raw);
-+ }
-+#endif /* IPH_is_SKB_PULLED */
-+
-+ /* dev->hard_header_len is unreliable and should not be used */
-+ irs.hard_header_len = skb->mac.raw ? (skb->data - skb->mac.raw) : 0;
-+ if((irs.hard_header_len < 0) || (irs.hard_header_len > skb_headroom(skb)))
-+ irs.hard_header_len = 0;
-+
-+#ifdef NET_21
-+ /* if skb was cloned (most likely due to a packet sniffer such as
-+ tcpdump being momentarily attached to the interface), make
-+ a copy of our own to modify */
-+ if(skb_cloned(skb)) {
-+ /* include any mac header while copying.. */
-+ if(skb_headroom(skb) < irs.hard_header_len) {
-+ printk(KERN_WARNING "klips_error:ipsec_rcv: "
-+ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
-+ irs.hard_header_len,
-+ skb_headroom(skb));
-+ goto rcvleave;
-+ }
-+ skb_push(skb, irs.hard_header_len);
-+ if
-+#ifdef SKB_COW_NEW
-+ (skb_cow(skb, skb_headroom(skb)) != 0)
-+#else /* SKB_COW_NEW */
-+ ((skb = skb_cow(skb, skb_headroom(skb))) == NULL)
-+#endif /* SKB_COW_NEW */
-+ {
-+ goto rcvleave;
-+ }
-+ if(skb->len < irs.hard_header_len) {
-+ printk(KERN_WARNING "klips_error:ipsec_rcv: "
-+ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
-+ irs.hard_header_len,
-+ skb->len);
-+ goto rcvleave;
-+ }
-+ skb_pull(skb, irs.hard_header_len);
-+ }
-+
-+#endif /* NET_21 */
-+
-+#if IP_FRAGMENT_LINEARIZE
-+ /* In Linux 2.4.4, we may have to reassemble fragments. They are
-+ not assembled automatically to save TCP from having to copy
-+ twice.
-+ */
-+ if (skb_is_nonlinear(skb)) {
-+ if (skb_linearize(skb, GFP_ATOMIC) != 0) {
-+ goto rcvleave;
-+ }
-+ }
-+#endif /* IP_FRAGMENT_LINEARIZE */
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if (irs.natt_len) {
-+ /**
-+ * Now, we are sure packet is ESPinUDP. Remove natt_len bytes from
-+ * packet and modify protocol to ESP.
-+ */
-+ if (((unsigned char *)skb->data > (unsigned char *)skb->nh.iph) &&
-+ ((unsigned char *)skb->nh.iph > (unsigned char *)skb->head)) {
-+ unsigned int _len = (unsigned char *)skb->data -
-+ (unsigned char *)skb->nh.iph;
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: adjusting skb: skb_push(%u)\n",
-+ _len);
-+ skb_push(skb, _len);
-+ }
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "removing %d bytes from ESPinUDP packet\n", irs.natt_len);
-+ ipp = (struct iphdr *)skb->data;
-+ irs.iphlen = ipp->ihl << 2;
-+ ipp->tot_len = htons(ntohs(ipp->tot_len) - irs.natt_len);
-+ if (skb->len < irs.iphlen + irs.natt_len) {
-+ printk(KERN_WARNING
-+ "klips_error:ipsec_rcv: "
-+ "ESPinUDP packet is too small (%d < %d+%d). "
-+ "This should never happen, please report.\n",
-+ (int)(skb->len), irs.iphlen, irs.natt_len);
-+ goto rcvleave;
-+ }
-+ memmove(skb->data + irs.natt_len, skb->data, irs.iphlen);
-+ skb_pull(skb, irs.natt_len);
-+
-+ /* update nh.iph */
-+ ipp = skb->nh.iph = (struct iphdr *)skb->data;
-+
-+ /* modify protocol */
-+ ipp->protocol = IPPROTO_ESP;
-+
-+ skb->sk = NULL;
-+
-+ KLIPS_IP_PRINT(debug_rcv, skb->nh.iph);
-+ }
-+#endif
-+
-+ ipp = skb->nh.iph;
-+ ipsaddr.s_addr = ipp->saddr;
-+ addrtoa(ipsaddr, 0, irs.ipsaddr_txt, sizeof(irs.ipsaddr_txt));
-+ ipdaddr.s_addr = ipp->daddr;
-+ addrtoa(ipdaddr, 0, irs.ipdaddr_txt, sizeof(irs.ipdaddr_txt));
-+ irs.iphlen = ipp->ihl << 2;
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "<<< Info -- ");
-+ KLIPS_PRINTMORE(debug_rcv && skb->dev, "skb->dev=%s ",
-+ skb->dev->name ? skb->dev->name : "NULL");
-+ KLIPS_PRINTMORE(debug_rcv && dev, "dev=%s ",
-+ dev->name ? dev->name : "NULL");
-+ KLIPS_PRINTMORE(debug_rcv, "\n");
-+
-+ KLIPS_PRINT(debug_rcv && !(skb->dev && dev && (skb->dev == dev)),
-+ "klips_debug:ipsec_rcv: "
-+ "Informational -- **if this happens, find out why** skb->dev:%s is not equal to dev:%s\n",
-+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL",
-+ dev ? (dev->name ? dev->name : "NULL") : "NULL");
-+
-+ protoc = ipp->protocol;
-+#ifndef NET_21
-+ if((!protocol) || (protocol->protocol != protoc)) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
-+ "klips_debug:ipsec_rcv: "
-+ "protocol arg is NULL or unequal to the packet contents, this is odd, using value in packet.\n");
-+ }
-+#endif /* !NET_21 */
-+
-+ if( (protoc != IPPROTO_AH) &&
-+#ifdef CONFIG_IPSEC_IPCOMP_disabled_until_we_register_IPCOMP_HANDLER
-+ (protoc != IPPROTO_COMP) &&
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ (protoc != IPPROTO_ESP) ) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
-+ "klips_debug:ipsec_rcv: Why the hell is someone "
-+ "passing me a non-ipsec protocol = %d packet? -- dropped.\n",
-+ protoc);
-+ goto rcvleave;
-+ }
-+
-+ if(skb->dev) {
-+ for(i = 0; i < IPSEC_NUM_IF; i++) {
-+ sprintf(name, IPSEC_DEV_FORMAT, i);
-+ if(!strcmp(name, skb->dev->name)) {
-+ prv = (struct ipsecpriv *)(skb->dev->priv);
-+ if(prv) {
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+ }
-+ ipsecdev = skb->dev;
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "Info -- pkt already proc'ed a group of ipsec headers, processing next group of ipsec headers.\n");
-+ break;
-+ }
-+ if((ipsecdev = __ipsec_dev_get(name)) == NULL) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_error:ipsec_rcv: "
-+ "device %s does not exist\n",
-+ name);
-+ }
-+ prv = ipsecdev ? (struct ipsecpriv *)(ipsecdev->priv) : NULL;
-+ prvdev = prv ? (struct device *)(prv->dev) : NULL;
-+
-+#if 0
-+ KLIPS_PRINT(debug_rcv && prvdev,
-+ "klips_debug:ipsec_rcv: "
-+ "physical device for device %s is %s\n",
-+ name,
-+ prvdev->name);
-+#endif
-+ if(prvdev && skb->dev &&
-+ !strcmp(prvdev->name, skb->dev->name)) {
-+ stats = prv ? ((struct net_device_stats *) &(prv->mystats)) : NULL;
-+ skb->dev = ipsecdev;
-+ KLIPS_PRINT(debug_rcv && prvdev,
-+ "klips_debug:ipsec_rcv: "
-+ "assigning packet ownership to virtual device %s from physical device %s.\n",
-+ name, prvdev->name);
-+ if(stats) {
-+ stats->rx_packets++;
-+ }
-+ break;
-+ }
-+ }
-+ } else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "device supplied with skb is NULL\n");
-+ }
-+
-+ if(stats == NULL) {
-+ KLIPS_PRINT((debug_rcv),
-+ "klips_error:ipsec_rcv: "
-+ "packet received from physical I/F (%s) not connected to ipsec I/F. Cannot record stats. May not have SA for decoding. Is IPSEC traffic expected on this I/F? Check routing.\n",
-+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL");
-+ }
-+
-+ KLIPS_IP_PRINT(debug_rcv, ipp);
-+
-+ /* begin decapsulating loop here */
-+
-+ /*
-+ The spinlock is to prevent any other process from
-+ accessing or deleting the ipsec_sa hash table or any of the
-+ ipsec_sa s while we are using and updating them.
-+
-+ This is not optimal, but was relatively straightforward
-+ at the time. A better way to do it has been planned for
-+ more than a year, to lock the hash table and put reference
-+ counts on each ipsec_sa instead. This is not likely to happen
-+ in KLIPS1 unless a volunteer contributes it, but will be
-+ designed into KLIPS2.
-+ */
-+ spin_lock(&tdb_lock);
-+
-+ /* set up for decap loop */
-+ irs.stats= stats;
-+ irs.ipp = ipp;
-+ irs.ipsp = NULL;
-+ irs.ilen = 0;
-+ irs.authlen=0;
-+ irs.authfuncs=NULL;
-+ irs.skb = skb;
-+
-+ do {
-+ int decap_stat;
-+ struct xform_functions *proto_funcs;
-+
-+ switch(irs.ipp->protocol) {
-+ case IPPROTO_ESP:
-+ proto_funcs = esp_xform_funcs;
-+ break;
-+
-+#ifdef CONFIG_IPSEC_AH
-+ case IPPROTO_AH:
-+ proto_funcs = ah_xform_funcs;
-+ break;
-+#endif /* !CONFIG_IPSEC_AH */
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ case IPPROTO_COMP:
-+ proto_funcs = ipcomp_xform_funcs;
-+ break;
-+#endif /* !CONFIG_IPSEC_IPCOMP */
-+ default:
-+ if(irs.stats) {
-+ irs.stats->rx_errors++;
-+ }
-+ decap_stat = IPSEC_RCV_BADPROTO;
-+ goto rcvleave;
-+ }
-+
-+ decap_stat = ipsec_rcv_decap_once(&irs, proto_funcs);
-+
-+ if(decap_stat != IPSEC_RCV_OK) {
-+ spin_unlock(&tdb_lock);
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: decap_once failed: %d\n",
-+ decap_stat);
-+
-+ goto rcvleave;
-+ }
-+ /* end decapsulation loop here */
-+ } while( (irs.ipp->protocol == IPPROTO_ESP )
-+ || (irs.ipp->protocol == IPPROTO_AH )
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ || (irs.ipp->protocol == IPPROTO_COMP)
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ );
-+
-+ /* set up for decap loop */
-+ ipp =irs.ipp;
-+ ipsp =irs.ipsp;
-+ ipsnext = ipsp->ips_inext;
-+ skb = irs.skb;
-+
-+ /* if there is an IPCOMP, but we don't have an IPPROTO_COMP,
-+ * then we can just skip it
-+ */
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ if(ipsnext && ipsnext->ips_said.proto == IPPROTO_COMP) {
-+ ipsp = ipsnext;
-+ ipsnext = ipsp->ips_inext;
-+ }
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if ((irs.natt_type) && (ipp->protocol != IPPROTO_IPIP)) {
-+ /**
-+ * NAT-Traversal and Transport Mode:
-+ * we need to correct TCP/UDP checksum
-+ *
-+ * If we've got NAT-OA, we can fix checksum without recalculation.
-+ */
-+ __u32 natt_oa = ipsp->ips_natt_oa ?
-+ ((struct sockaddr_in*)(ipsp->ips_natt_oa))->sin_addr.s_addr : 0;
-+ __u16 pkt_len = skb->tail - (unsigned char *)ipp;
-+ __u16 data_len = pkt_len - (ipp->ihl << 2);
-+
-+ switch (ipp->protocol) {
-+ case IPPROTO_TCP:
-+ if (data_len >= sizeof(struct tcphdr)) {
-+ struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ipp+ipp->ihl);
-+ if (natt_oa) {
-+ __u32 buff[2] = { ~natt_oa, ipp->saddr };
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NAT-T & TRANSPORT: "
-+ "fix TCP checksum using NAT-OA\n");
-+ tcp->check = csum_fold(
-+ csum_partial((unsigned char *)buff, sizeof(buff),
-+ tcp->check^0xffff));
-+ }
-+ else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NAT-T & TRANSPORT: recalc TCP checksum\n");
-+ if (pkt_len > (ntohs(ipp->tot_len)))
-+ data_len -= (pkt_len - ntohs(ipp->tot_len));
-+ tcp->check = 0;
-+ tcp->check = csum_tcpudp_magic(ipp->saddr, ipp->daddr,
-+ data_len, IPPROTO_TCP,
-+ csum_partial((unsigned char *)tcp, data_len, 0));
-+ }
-+ }
-+ else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NAT-T & TRANSPORT: can't fix TCP checksum\n");
-+ }
-+ break;
-+ case IPPROTO_UDP:
-+ if (data_len >= sizeof(struct udphdr)) {
-+ struct udphdr *udp = (struct udphdr *)((__u32 *)ipp+ipp->ihl);
-+ if (udp->check == 0) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NAT-T & TRANSPORT: UDP checksum already 0\n");
-+ }
-+ else if (natt_oa) {
-+ __u32 buff[2] = { ~natt_oa, ipp->saddr };
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NAT-T & TRANSPORT: "
-+ "fix UDP checksum using NAT-OA\n");
-+ udp->check = csum_fold(
-+ csum_partial((unsigned char *)buff, sizeof(buff),
-+ udp->check^0xffff));
-+ }
-+ else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NAT-T & TRANSPORT: zero UDP checksum\n");
-+ udp->check = 0;
-+ }
-+ }
-+ else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NAT-T & TRANSPORT: can't fix UDP checksum\n");
-+ }
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");
-+ break;
-+ }
-+ }
-+#endif
-+
-+ /*
-+ * XXX this needs to be locked from when it was first looked
-+ * up in the decapsulation loop. Perhaps it is better to put
-+ * the IPIP decap inside the loop.
-+ */
-+ if(ipsnext) {
-+ ipsp = ipsnext;
-+ irs.sa_len = satot(&irs.said, 0, irs.sa, sizeof(irs.sa));
-+ if((ipp->protocol != IPPROTO_IPIP) &&
-+ ( 0xFE != ipp->protocol)) { /* added to support AT&T heartbeats to SIG/GIG */
-+ spin_unlock(&tdb_lock);
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s, Hey! How did this get through? Dropped.\n",
-+ irs.sa_len ? irs.sa : " (error)");
-+ if(stats) {
-+ stats->rx_dropped++;
-+ }
-+ goto rcvleave;
-+ }
-+ if(sysctl_ipsec_inbound_policy_check) {
-+ if((ipsnext = ipsp->ips_inext)) {
-+ char sa2[SATOT_BUF];
-+ size_t sa_len2;
-+ sa_len2 = satot(&ipsnext->ips_said, 0, sa2, sizeof(sa2));
-+ spin_unlock(&tdb_lock);
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "unexpected SA:%s after IPIP SA:%s\n",
-+ sa_len2 ? sa2 : " (error)",
-+ irs.sa_len ? irs.sa : " (error)");
-+ if(stats) {
-+ stats->rx_dropped++;
-+ }
-+ goto rcvleave;
-+ }
-+ if(ipp->saddr != ((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr.s_addr) {
-+ spin_unlock(&tdb_lock);
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n",
-+ irs.sa_len ? irs.sa : " (error)",
-+ irs.ipsaddr_txt);
-+ if(stats) {
-+ stats->rx_dropped++;
-+ }
-+ goto rcvleave;
-+ }
-+ }
-+
-+ if(ipp->protocol == IPPROTO_IPIP) /* added to support AT&T heartbeats to SIG/GIG */
-+ {
-+ /*
-+ * XXX this needs to be locked from when it was first looked
-+ * up in the decapsulation loop. Perhaps it is better to put
-+ * the IPIP decap inside the loop.
-+ */
-+ ipsp->ips_life.ipl_bytes.ipl_count += skb->len;
-+ ipsp->ips_life.ipl_bytes.ipl_last = skb->len;
-+
-+ if(!ipsp->ips_life.ipl_usetime.ipl_count) {
-+ ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
-+ }
-+ ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
-+ ipsp->ips_life.ipl_packets.ipl_count += 1;
-+
-+ if(skb->len < irs.iphlen) {
-+ spin_unlock(&tdb_lock);
-+ printk(KERN_WARNING "klips_debug:ipsec_rcv: "
-+ "tried to skb_pull iphlen=%d, %d available. This should never happen, please report.\n",
-+ irs.iphlen,
-+ (int)(skb->len));
-+
-+ goto rcvleave;
-+ }
-+ skb_pull(skb, irs.iphlen);
-+
-+#ifdef NET_21
-+ ipp = (struct iphdr *)skb->nh.raw = skb->data;
-+ skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2);
-+
-+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
-+#else /* NET_21 */
-+ ipp = skb->ip_hdr = skb->h.iph = (struct iphdr *)skb->data;
-+
-+ memset(skb->proto_priv, 0, sizeof(struct options));
-+#endif /* NET_21 */
-+ ipsaddr.s_addr = ipp->saddr;
-+ addrtoa(ipsaddr, 0, irs.ipsaddr_txt, sizeof(irs.ipsaddr_txt));
-+ ipdaddr.s_addr = ipp->daddr;
-+ addrtoa(ipdaddr, 0, irs.ipdaddr_txt, sizeof(irs.ipdaddr_txt));
-+
-+ skb->protocol = htons(ETH_P_IP);
-+ skb->ip_summed = 0;
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "IPIP tunnel stripped.\n");
-+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
-+ }
-+
-+ if(sysctl_ipsec_inbound_policy_check
-+ /*
-+ Note: "xor" (^) logically replaces "not equal"
-+ (!=) and "bitwise or" (|) logically replaces
-+ "boolean or" (||). This is done to speed up
-+ execution by doing only bitwise operations and
-+ no branch operations
-+ */
-+ && (((ipp->saddr & ipsp->ips_mask_s.u.v4.sin_addr.s_addr)
-+ ^ ipsp->ips_flow_s.u.v4.sin_addr.s_addr)
-+ | ((ipp->daddr & ipsp->ips_mask_d.u.v4.sin_addr.s_addr)
-+ ^ ipsp->ips_flow_d.u.v4.sin_addr.s_addr)) )
-+ {
-+ char sflow_txt[SUBNETTOA_BUF], dflow_txt[SUBNETTOA_BUF];
-+
-+ subnettoa(ipsp->ips_flow_s.u.v4.sin_addr,
-+ ipsp->ips_mask_s.u.v4.sin_addr,
-+ 0, sflow_txt, sizeof(sflow_txt));
-+ subnettoa(ipsp->ips_flow_d.u.v4.sin_addr,
-+ ipsp->ips_mask_d.u.v4.sin_addr,
-+ 0, dflow_txt, sizeof(dflow_txt));
-+ spin_unlock(&tdb_lock);
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s, inner tunnel policy [%s -> %s] does not agree with pkt contents [%s -> %s].\n",
-+ irs.sa_len ? irs.sa : " (error)",
-+ sflow_txt,
-+ dflow_txt,
-+ irs.ipsaddr_txt,
-+ irs.ipdaddr_txt);
-+ if(stats) {
-+ stats->rx_dropped++;
-+ }
-+ goto rcvleave;
-+ }
-+#ifdef CONFIG_NETFILTER
-+ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_TABLE_MASK))))
-+ | IPsecSAref2NFmark(IPsecSA2SAref(ipsp));
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "IPIP SA sets skb->nfmark=0x%x.\n",
-+ (unsigned)skb->nfmark);
-+#endif /* CONFIG_NETFILTER */
-+ }
-+
-+ spin_unlock(&tdb_lock);
-+
-+#ifdef NET_21
-+ if(stats) {
-+ stats->rx_bytes += skb->len;
-+ }
-+ if(skb->dst) {
-+ dst_release(skb->dst);
-+ skb->dst = NULL;
-+ }
-+ skb->pkt_type = PACKET_HOST;
-+ if(irs.hard_header_len &&
-+ (skb->mac.raw != (skb->data - irs.hard_header_len)) &&
-+ (irs.hard_header_len <= skb_headroom(skb))) {
-+ /* copy back original MAC header */
-+ memmove(skb->data - irs.hard_header_len, skb->mac.raw, irs.hard_header_len);
-+ skb->mac.raw = skb->data - irs.hard_header_len;
-+ }
-+#endif /* NET_21 */
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ if(ipp->protocol == IPPROTO_COMP) {
-+ unsigned int flags = 0;
-+
-+ if(sysctl_ipsec_inbound_policy_check) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "inbound policy checking enabled, IPCOMP follows IPIP, dropped.\n");
-+ if (stats) {
-+ stats->rx_errors++;
-+ }
-+ goto rcvleave;
-+ }
-+ /*
-+ XXX need a ipsec_sa for updating ratio counters but it is not
-+ following policy anyways so it is not a priority
-+ */
-+ skb = skb_decompress(skb, NULL, &flags);
-+ if (!skb || flags) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "skb_decompress() returned error flags: %d, dropped.\n",
-+ flags);
-+ if (stats) {
-+ stats->rx_errors++;
-+ }
-+ goto rcvleave;
-+ }
-+ }
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#ifdef SKB_RESET_NFCT
-+ nf_conntrack_put(skb->nfct);
-+ skb->nfct = NULL;
-+#ifdef CONFIG_NETFILTER_DEBUG
-+ skb->nf_debug = 0;
-+#endif /* CONFIG_NETFILTER_DEBUG */
-+#endif /* SKB_RESET_NFCT */
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "netif_rx() called.\n");
-+ netif_rx(skb);
-+
-+ MOD_DEC_USE_COUNT;
-+ return(0);
-+
-+ rcvleave:
-+ if(skb) {
-+ ipsec_kfree_skb(skb);
-+ }
-+
-+ MOD_DEC_USE_COUNT;
-+ return(0);
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.143.4.2 2004/08/22 03:29:06 mcr
-+ * include udp.h regardless of nat-t support.
-+ *
-+ * Revision 1.143.4.1 2004/08/21 02:14:58 ken
-+ * Patch from Jochen Eisinger for AT&T MTS Heartbeat packet support
-+ *
-+ * Revision 1.143 2004/05/10 22:27:00 mcr
-+ * fix for ESP-3DES-noauth test case.
-+ *
-+ * Revision 1.142 2004/05/10 22:25:57 mcr
-+ * reformat of calls to ipsec_lifetime_check().
-+ *
-+ * Revision 1.141 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.140 2004/02/03 03:12:53 mcr
-+ * removed erroneously, double patched code.
-+ *
-+ * Revision 1.139 2004/01/05 23:21:29 mcr
-+ * initialize sin_family in ipsec_rcv.c
-+ *
-+ * Revision 1.138 2003/12/24 19:46:52 mcr
-+ * if sock.h patch has not been applied, then define appropriate
-+ * structure so we can use it. This is serious inferior, and
-+ * depends upon the concept that the structure in question is
-+ * smaller than the other members of that union.
-+ * getting rid of differing methods is a better solution.
-+ *
-+ * Revision 1.137 2003/12/22 19:40:57 mcr
-+ * NAT-T patches 0.6c.
-+ *
-+ * Revision 1.136 2003/12/15 18:13:12 mcr
-+ * when compiling with NAT traversal, don't assume that the
-+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
-+ * is set.
-+ *
-+ * Revision 1.135 2003/12/13 19:10:21 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.134.2.1 2003/12/22 15:25:52 jjo
-+ * Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.134 2003/12/10 01:14:27 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.133 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.132.2.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.132 2003/09/02 19:51:48 mcr
-+ * fixes for PR#252.
-+ *
-+ * Revision 1.131 2003/07/31 22:47:16 mcr
-+ * preliminary (untested by FS-team) 2.5 patches.
-+ *
-+ * Revision 1.130 2003/04/03 17:38:25 rgb
-+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
-+ * Clarified logic for non-connected devices.
-+ *
-+ * Revision 1.129 2003/02/06 02:21:34 rgb
-+ *
-+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
-+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
-+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
-+ *
-+ * Revision 1.128 2002/12/13 20:58:03 rgb
-+ * Relegated MCR's recent "_dmp" routine to debug_verbose.
-+ * Cleaned up printing of source and destination addresses in debug output.
-+ *
-+ * Revision 1.127 2002/12/04 16:00:16 rgb
-+ *
-+ * Fixed AH decapsulation pointer update bug and added some comments and
-+ * debugging.
-+ * This bug was caught by west-ah-0[12].
-+ *
-+ * Revision 1.126 2002/11/04 05:03:43 mcr
-+ * fixes for IPCOMP. There were two problems:
-+ * 1) the irs->ipp pointer was not being updated properly after
-+ * the ESP descryption. The meant nothing for IPIP, as the
-+ * later IP header overwrote the earlier one.
-+ * 2) the more serious problem was that skb_decompress will
-+ * usually allocate a new SKB, so we have to make sure that
-+ * it doesn't get lost.
-+ * #2 meant removing the skb argument from the ->decrypt routine
-+ * and moving it to the irs->skb, so it could be value/result.
-+ *
-+ * Revision 1.125 2002/11/01 01:53:35 dhr
-+ *
-+ * fix typo
-+ *
-+ * Revision 1.124 2002/10/31 22:49:01 dhr
-+ *
-+ * - eliminate unused variable "hash"
-+ * - reduce scope of variable "authenticator"
-+ * - add comment on a couple of tricky bits
-+ *
-+ * Revision 1.123 2002/10/31 22:39:56 dhr
-+ *
-+ * use correct type for result of function calls
-+ *
-+ * Revision 1.122 2002/10/31 22:36:25 dhr
-+ *
-+ * simplify complex test
-+ *
-+ * Revision 1.121 2002/10/31 22:34:04 dhr
-+ *
-+ * ipsprev is never used: ditch it
-+ *
-+ * Revision 1.120 2002/10/31 22:30:21 dhr
-+ *
-+ * eliminate redundant assignments
-+ *
-+ * Revision 1.119 2002/10/31 22:27:43 dhr
-+ *
-+ * make whitespace canonical
-+ *
-+ * Revision 1.118 2002/10/30 05:47:17 rgb
-+ * Fixed cut-and-paste error mis-identifying comp runt as ah.
-+ *
-+ * Revision 1.117 2002/10/17 16:37:45 rgb
-+ * Remove compp intermediate variable and in-line its contents
-+ * where used
-+ *
-+ * Revision 1.116 2002/10/12 23:11:53 dhr
-+ *
-+ * [KenB + DHR] more 64-bit cleanup
-+ *
-+ * Revision 1.115 2002/10/07 19:06:58 rgb
-+ * Minor fixups and activation to west-rcv-nfmark-set-01 test to check for SA reference properly set on incoming.
-+ *
-+ * Revision 1.114 2002/10/07 18:31:31 rgb
-+ * Set saref on incoming packets.
-+ *
-+ * Revision 1.113 2002/09/16 21:28:12 mcr
-+ * adjust hash length for HMAC calculation - must look at whether
-+ * it is MD5 or SHA1.
-+ *
-+ * Revision 1.112 2002/09/16 21:19:15 mcr
-+ * fixes for west-ah-icmp-01 - length of AH header must be
-+ * calculated properly, and next_header field properly copied.
-+ *
-+ * Revision 1.111 2002/09/10 02:45:56 mcr
-+ * re-factored the ipsec_rcv function into several functions,
-+ * ipsec_rcv_decap_once, and a set of functions for AH, ESP and IPCOMP.
-+ * In addition, the MD5 and SHA1 functions are replaced with pointers.
-+ *
-+ * Revision 1.110 2002/08/30 06:34:33 rgb
-+ * Fix scope of shift in AH header length check.
-+ *
-+ * Revision 1.109 2002/08/27 16:49:20 rgb
-+ * Fixed ESP short packet DOS (and AH and IPCOMP).
-+ *
-+ * Revision 1.108 2002/07/24 18:44:54 rgb
-+ * Type fiddling to tame ia64 compiler.
-+ *
-+ * Revision 1.107 2002/05/27 18:58:18 rgb
-+ * Convert to dynamic ipsec device allocation.
-+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
-+ *
-+ * Revision 1.106 2002/05/23 07:15:21 rgb
-+ * Pointer clean-up.
-+ * Added refcount code.
-+ *
-+ * Revision 1.105 2002/05/14 02:35:06 rgb
-+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
-+ * ipsec_sa or ipsec_sa.
-+ * Change references to _TDB to _IPSA.
-+ *
-+ * Revision 1.104 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.103 2002/04/24 07:36:30 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_rcv.c,v
-+ *
-+ * Revision 1.102 2002/01/29 17:17:56 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.101 2002/01/29 04:00:52 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.100 2002/01/29 02:13:17 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.99 2002/01/28 21:40:59 mcr
-+ * should use #if to test boolean option rather than #ifdef.
-+ *
-+ * Revision 1.98 2002/01/20 20:19:36 mcr
-+ * renamed option to IP_FRAGMENT_LINEARIZE.
-+ *
-+ * Revision 1.97 2002/01/12 02:55:36 mcr
-+ * fix for post-2.4.4 to linearize skb's when ESP packet
-+ * was assembled from fragments.
-+ *
-+ * Revision 1.96 2001/11/26 09:23:49 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.93.2.2 2001/10/22 20:54:07 mcr
-+ * include des.h, removed phony prototypes and fixed calling
-+ * conventions to match real prototypes.
-+ *
-+ * Revision 1.93.2.1 2001/09/25 02:22:22 mcr
-+ * struct tdb -> struct ipsec_sa.
-+ * lifetime checks moved to ipsec_life.c
-+ * some sa(tdb) manipulation functions renamed.
-+ *
-+ * Revision 1.95 2001/11/06 19:49:07 rgb
-+ * Added variable descriptions.
-+ * Removed unauthenticated sequence==0 check to prevent DoS.
-+ *
-+ * Revision 1.94 2001/10/18 04:45:20 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/freeswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.93 2001/09/07 22:17:24 rgb
-+ * Fix for removal of transport layer protocol handler arg in 2.4.4.
-+ * Fix to accomodate peer non-conformance to IPCOMP rfc2393.
-+ *
-+ * Revision 1.92 2001/08/27 19:44:41 rgb
-+ * Fix error in comment.
-+ *
-+ * Revision 1.91 2001/07/20 19:31:48 dhr
-+ * [DHR] fix source and destination subnets of policy in diagnostic
-+ *
-+ * Revision 1.90 2001/07/06 19:51:09 rgb
-+ * Added inbound policy checking code for IPIP SAs.
-+ * Renamed unused function argument for ease and intuitive naming.
-+ *
-+ * Revision 1.89 2001/06/22 19:35:23 rgb
-+ * Disable ipcomp processing if we are handed a ipcomp packet with no esp
-+ * or ah header.
-+ * Print protocol if we are handed a non-ipsec packet.
-+ *
-+ * Revision 1.88 2001/06/20 06:30:47 rgb
-+ * Fixed transport mode IPCOMP policy check bug.
-+ *
-+ * Revision 1.87 2001/06/13 20:58:40 rgb
-+ * Added parentheses around assignment used as truth value to silence
-+ * compiler.
-+ *
-+ * Revision 1.86 2001/06/07 22:25:23 rgb
-+ * Added a source address policy check for tunnel mode. It still does
-+ * not check client addresses and masks.
-+ * Only decapsulate IPIP if it is expected.
-+ *
-+ * Revision 1.85 2001/05/30 08:14:02 rgb
-+ * Removed vestiges of esp-null transforms.
-+ *
-+ * Revision 1.84 2001/05/27 06:12:11 rgb
-+ * Added structures for pid, packet count and last access time to eroute.
-+ * Added packet count to beginning of /proc/net/ipsec_eroute.
-+ *
-+ * Revision 1.83 2001/05/04 16:45:47 rgb
-+ * Remove unneeded code. ipp is not used after this point.
-+ *
-+ * Revision 1.82 2001/05/04 16:36:00 rgb
-+ * Fix skb_cow() call for 2.4.4. (SS)
-+ *
-+ * Revision 1.81 2001/05/02 14:46:53 rgb
-+ * Fix typo for compiler directive to pull IPH back.
-+ *
-+ * Revision 1.80 2001/04/30 19:46:34 rgb
-+ * Update for 2.4.4. We now receive the skb with skb->data pointing to
-+ * h.raw.
-+ *
-+ * Revision 1.79 2001/04/23 15:01:15 rgb
-+ * Added spin_lock() check to prevent double-locking for multiple
-+ * transforms and hence kernel lock-ups with SMP kernels.
-+ * Minor spin_unlock() adjustments to unlock before non-dependant prints
-+ * and IPSEC device stats updates.
-+ *
-+ * Revision 1.78 2001/04/21 23:04:24 rgb
-+ * Check if soft expire has already been sent before sending another to
-+ * prevent ACQUIRE flooding.
-+ *
-+ * Revision 1.77 2001/03/16 07:35:20 rgb
-+ * Ditch extra #if 1 around now permanent policy checking code.
-+ *
-+ * Revision 1.76 2001/02/27 22:24:54 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.75 2001/02/19 22:28:30 rgb
-+ * Minor change to virtual device discovery code to assert which I/F has
-+ * been found.
-+ *
-+ * Revision 1.74 2000/11/25 03:50:36 rgb
-+ * Oops fix by minor re-arrangement of code to avoid accessing a freed tdb.
-+ *
-+ * Revision 1.73 2000/11/09 20:52:15 rgb
-+ * More spinlock shuffling, locking earlier and unlocking later in rcv to
-+ * include ipcomp and prevent races, renaming some tdb variables that got
-+ * forgotten, moving some unlocks to include tdbs and adding a missing
-+ * unlock. Thanks to Svenning for some of these.
-+ *
-+ * Revision 1.72 2000/11/09 20:11:22 rgb
-+ * Minor shuffles to fix non-standard kernel config option selection.
-+ *
-+ * Revision 1.71 2000/11/06 04:36:18 rgb
-+ * Ditched spin_lock_irqsave in favour of spin_lock.
-+ * Minor initial protocol check rewrite.
-+ * Clean up debug printing.
-+ * Clean up tdb handling on ipcomp.
-+ * Fixed transport mode null pointer de-reference without ipcomp.
-+ * Add Svenning's adaptive content compression.
-+ * Disabled registration of ipcomp handler.
-+ *
-+ * Revision 1.70 2000/10/30 23:41:43 henry
-+ * Hans-Joerg Hoexer's null-pointer fix
-+ *
-+ * Revision 1.69 2000/10/10 18:54:16 rgb
-+ * Added a fix for incoming policy check with ipcomp enabled but
-+ * uncompressible.
-+ *
-+ * Revision 1.68 2000/09/22 17:53:12 rgb
-+ * Fixed ipcomp tdb pointers update for policy checking.
-+ *
-+ * Revision 1.67 2000/09/21 03:40:58 rgb
-+ * Added more debugging to try and track down the cpi outward copy problem.
-+ *
-+ * Revision 1.66 2000/09/20 04:00:10 rgb
-+ * Changed static functions to DEBUG_NO_STATIC to reveal function names for
-+ * debugging oopsen.
-+ *
-+ * Revision 1.65 2000/09/19 07:07:16 rgb
-+ * Added debugging to inbound policy check for ipcomp.
-+ * Added missing spin_unlocks (thanks Svenning!).
-+ * Fixed misplaced tdbnext pointers causing mismatched ipip policy check.
-+ * Protect ipcomp policy check following ipip decap with sysctl switch.
-+ *
-+ * Revision 1.64 2000/09/18 21:27:29 rgb
-+ * 2.0 fixes.
-+ *
-+ * Revision 1.63 2000/09/18 02:35:50 rgb
-+ * Added policy checking to ipcomp and re-enabled policy checking by
-+ * default.
-+ * Optimised satoa calls.
-+ *
-+ * Revision 1.62 2000/09/17 21:02:32 rgb
-+ * Clean up debugging, removing slow timestamp debug code.
-+ *
-+ * Revision 1.61 2000/09/16 01:07:55 rgb
-+ * Fixed erroneous ref from struct ipcomp to struct ipcomphdr.
-+ *
-+ * Revision 1.60 2000/09/15 11:37:01 rgb
-+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
-+ * IPCOMP zlib deflate code.
-+ *
-+ * Revision 1.59 2000/09/15 04:56:20 rgb
-+ * Remove redundant satoa() call, reformat comment.
-+ *
-+ * Revision 1.58 2000/09/13 08:00:52 rgb
-+ * Flick on inbound policy checking.
-+ *
-+ * Revision 1.57 2000/09/12 03:22:19 rgb
-+ * Converted inbound_policy_check to sysctl.
-+ * Re-enabled policy backcheck.
-+ * Moved policy checks to top and within tdb lock.
-+ *
-+ * Revision 1.56 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.55 2000/08/28 18:15:46 rgb
-+ * Added MB's nf-debug reset patch.
-+ *
-+ * Revision 1.54 2000/08/27 01:41:26 rgb
-+ * More minor tweaks to the bad padding debug code.
-+ *
-+ * Revision 1.53 2000/08/24 16:54:16 rgb
-+ * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level
-+ * info.
-+ * Tidied up device reporting at the start of ipsec_rcv.
-+ * Tidied up bad padding debugging and processing.
-+ *
-+ * Revision 1.52 2000/08/20 21:36:03 rgb
-+ * Activated pfkey_expire() calls.
-+ * Added a hard/soft expiry parameter to pfkey_expire().
-+ * Added sanity checking to avoid propagating zero or smaller-length skbs
-+ * from a bogus decryption.
-+ * Re-arranged the order of soft and hard expiry to conform to RFC2367.
-+ * Clean up references to CONFIG_IPSEC_PFKEYv2.
-+ *
-+ * Revision 1.51 2000/08/18 21:23:30 rgb
-+ * Improve bad padding warning so that the printk buffer doesn't get
-+ * trampled.
-+ *
-+ * Revision 1.50 2000/08/01 14:51:51 rgb
-+ * Removed _all_ remaining traces of DES.
-+ *
-+ * Revision 1.49 2000/07/28 13:50:53 rgb
-+ * Changed enet_statistics to net_device_stats and added back compatibility
-+ * for pre-2.1.19.
-+ *
-+ * Revision 1.48 2000/05/10 19:14:40 rgb
-+ * Only check usetime against soft and hard limits if the tdb has been
-+ * used.
-+ * Cast output of ntohl so that the broken prototype doesn't make our
-+ * compile noisy.
-+ *
-+ * Revision 1.47 2000/05/09 17:45:43 rgb
-+ * Fix replay bitmap corruption bug upon receipt of bogus packet
-+ * with correct SPI. This was a DoS.
-+ *
-+ * Revision 1.46 2000/03/27 02:31:58 rgb
-+ * Fixed authentication failure printout bug.
-+ *
-+ * Revision 1.45 2000/03/22 16:15:37 rgb
-+ * Fixed renaming of dev_get (MB).
-+ *
-+ * Revision 1.44 2000/03/16 08:17:24 rgb
-+ * Hardcode PF_KEYv2 support.
-+ * Fixed minor bug checking AH header length.
-+ *
-+ * Revision 1.43 2000/03/14 12:26:59 rgb
-+ * Added skb->nfct support for clearing netfilter conntrack bits (MB).
-+ *
-+ * Revision 1.42 2000/01/26 10:04:04 rgb
-+ * Fixed inbound policy checking on transport mode bug.
-+ * Fixed noisy 2.0 printk arguments.
-+ *
-+ * Revision 1.41 2000/01/24 20:58:02 rgb
-+ * Improve debugging/reporting support for (disabled) inbound
-+ * policy checking.
-+ *
-+ * Revision 1.40 2000/01/22 23:20:10 rgb
-+ * Fixed up inboud policy checking code.
-+ * Cleaned out unused crud.
-+ *
-+ * Revision 1.39 2000/01/21 06:15:29 rgb
-+ * Added sanity checks on skb_push(), skb_pull() to prevent panics.
-+ * Fixed cut-and-paste debug_tunnel to debug_rcv.
-+ * Added inbound policy checking code, disabled.
-+ * Simplified output code by updating ipp to post-IPIP decapsulation.
-+ *
-+ * elided pre-2000 comments. Use "cvs log"
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_sa.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1383 @@
-+/*
-+ * Common routines for IPsec SA maintenance routines.
-+ *
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ * This is the file formerly known as "ipsec_xform.h"
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/vmalloc.h> /* vmalloc() */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef SPINLOCK
-+#ifdef SPINLOCK_23
-+#include <linux/spinlock.h> /* *lock* */
-+#else /* SPINLOCK_23 */
-+#include <asm/spinlock.h> /* *lock* */
-+#endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+#include <asm/uaccess.h>
-+#include <linux/in6.h>
-+#endif
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "openswan/radij.h"
-+
-+#include "openswan/ipsec_stats.h"
-+#include "openswan/ipsec_life.h"
-+#include "openswan/ipsec_sa.h"
-+#include "openswan/ipsec_xform.h"
-+
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_ipe4.h"
-+#include "openswan/ipsec_ah.h"
-+#include "openswan/ipsec_esp.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+#include "openswan/ipsec_alg.h"
-+
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_xform = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
-+
-+struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
-+#ifdef SPINLOCK
-+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
-+#else /* SPINLOCK */
-+spinlock_t tdb_lock;
-+#endif /* SPINLOCK */
-+
-+struct ipsec_sadb ipsec_sadb;
-+
-+#if IPSEC_SA_REF_CODE
-+
-+/* the sub table must be narrower (or equal) in bits than the variable type
-+ in the main table to count the number of unused entries in it. */
-+typedef struct {
-+ int testSizeOf_refSubTable :
-+ ((sizeof(IPsecRefTableUnusedCount) * 8) < IPSEC_SA_REF_SUBTABLE_IDX_WIDTH ? -1 : 1);
-+} dummy;
-+
-+
-+/* The field where the saref will be hosted in the skb must be wide enough to
-+ accomodate the information it needs to store. */
-+typedef struct {
-+ int testSizeOf_refField :
-+ (IPSEC_SA_REF_HOST_FIELD_WIDTH < IPSEC_SA_REF_TABLE_IDX_WIDTH ? -1 : 1 );
-+} dummy2;
-+
-+
-+#define IPS_HASH(said) (((said)->spi + (said)->dst.u.v4.sin_addr.s_addr + (said)->proto) % SADB_HASHMOD)
-+
-+
-+void
-+ipsec_SAtest(void)
-+{
-+ IPsecSAref_t SAref = 258;
-+ struct ipsec_sa ips;
-+ ips.ips_ref = 772;
-+
-+ printk("klips_debug:ipsec_SAtest: "
-+ "IPSEC_SA_REF_SUBTABLE_IDX_WIDTH=%u\n"
-+ "IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES=%u\n"
-+ "IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES=%u\n"
-+ "IPSEC_SA_REF_HOST_FIELD_WIDTH=%lu\n"
-+ "IPSEC_SA_REF_TABLE_MASK=%x\n"
-+ "IPSEC_SA_REF_ENTRY_MASK=%x\n"
-+ "IPsecSAref2table(%d)=%u\n"
-+ "IPsecSAref2entry(%d)=%u\n"
-+ "IPsecSAref2NFmark(%d)=%u\n"
-+ "IPsecSAref2SA(%d)=%p\n"
-+ "IPsecSA2SAref(%p)=%d\n"
-+ ,
-+ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
-+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
-+ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
-+ (unsigned long) IPSEC_SA_REF_HOST_FIELD_WIDTH,
-+ IPSEC_SA_REF_TABLE_MASK,
-+ IPSEC_SA_REF_ENTRY_MASK,
-+ SAref, IPsecSAref2table(SAref),
-+ SAref, IPsecSAref2entry(SAref),
-+ SAref, IPsecSAref2NFmark(SAref),
-+ SAref, IPsecSAref2SA(SAref),
-+ (&ips), IPsecSA2SAref((&ips))
-+ );
-+ return;
-+}
-+
-+int
-+ipsec_SAref_recycle(void)
-+{
-+ int table;
-+ int entry;
-+ int error = 0;
-+
-+ ipsec_sadb.refFreeListHead = -1;
-+ ipsec_sadb.refFreeListTail = -1;
-+
-+ if(ipsec_sadb.refFreeListCont == IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_recycle: "
-+ "end of table reached, continuing at start..\n");
-+ ipsec_sadb.refFreeListCont = 0;
-+ }
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_recycle: "
-+ "recycling, continuing from SAref=%d (0p%p), table=%d, entry=%d.\n",
-+ ipsec_sadb.refFreeListCont,
-+ (ipsec_sadb.refTable[IPsecSAref2table(ipsec_sadb.refFreeListCont)] != NULL) ? IPsecSAref2SA(ipsec_sadb.refFreeListCont) : NULL,
-+ IPsecSAref2table(ipsec_sadb.refFreeListCont),
-+ IPsecSAref2entry(ipsec_sadb.refFreeListCont));
-+
-+ for(table = IPsecSAref2table(ipsec_sadb.refFreeListCont);
-+ table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES;
-+ table++) {
-+ if(ipsec_sadb.refTable[table] == NULL) {
-+ error = ipsec_SArefSubTable_alloc(table);
-+ if(error) {
-+ return error;
-+ }
-+ }
-+ for(entry = IPsecSAref2entry(ipsec_sadb.refFreeListCont);
-+ entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES;
-+ entry++) {
-+ if(ipsec_sadb.refTable[table]->entry[entry] == NULL) {
-+ ipsec_sadb.refFreeList[++ipsec_sadb.refFreeListTail] = IPsecSArefBuild(table, entry);
-+ if(ipsec_sadb.refFreeListTail == (IPSEC_SA_REF_FREELIST_NUM_ENTRIES - 1)) {
-+ ipsec_sadb.refFreeListHead = 0;
-+ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_recycle: "
-+ "SArefFreeList refilled.\n");
-+ return 0;
-+ }
-+ }
-+ }
-+ }
-+
-+ if(ipsec_sadb.refFreeListTail == -1) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_recycle: "
-+ "out of room in the SArefTable.\n");
-+
-+ return(-ENOSPC);
-+ }
-+
-+ ipsec_sadb.refFreeListHead = 0;
-+ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_recycle: "
-+ "SArefFreeList partly refilled to %d of %d.\n",
-+ ipsec_sadb.refFreeListTail,
-+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
-+ return 0;
-+}
-+
-+int
-+ipsec_SArefSubTable_alloc(unsigned table)
-+{
-+ unsigned entry;
-+ struct IPsecSArefSubTable* SArefsub;
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SArefSubTable_alloc: "
-+ "allocating %lu bytes for table %u of %u.\n",
-+ (unsigned long) (IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *)),
-+ table,
-+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
-+
-+ /* allocate another sub-table */
-+ SArefsub = vmalloc(IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *));
-+ if(SArefsub == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SArefSubTable_alloc: "
-+ "error allocating memory for table %u of %u!\n",
-+ table,
-+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
-+ return -ENOMEM;
-+ }
-+
-+ /* add this sub-table to the main table */
-+ ipsec_sadb.refTable[table] = SArefsub;
-+
-+ /* initialise each element to NULL */
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SArefSubTable_alloc: "
-+ "initialising %u elements (2 ^ %u) of table %u.\n",
-+ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
-+ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
-+ table);
-+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
-+ SArefsub->entry[entry] = NULL;
-+ }
-+
-+ return 0;
-+}
-+#endif /* IPSEC_SA_REF_CODE */
-+
-+int
-+ipsec_saref_freelist_init(void)
-+{
-+ int i;
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_saref_freelist_init: "
-+ "initialising %u elements of FreeList.\n",
-+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
-+
-+ for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) {
-+ ipsec_sadb.refFreeList[i] = IPSEC_SAREF_NULL;
-+ }
-+ ipsec_sadb.refFreeListHead = -1;
-+ ipsec_sadb.refFreeListCont = 0;
-+ ipsec_sadb.refFreeListTail = -1;
-+
-+ return 0;
-+}
-+
-+int
-+ipsec_sadb_init(void)
-+{
-+ int error = 0;
-+ unsigned i;
-+
-+ for(i = 0; i < SADB_HASHMOD; i++) {
-+ ipsec_sadb_hash[i] = NULL;
-+ }
-+ /* parts above are for the old style SADB hash table */
-+
-+
-+#if IPSEC_SA_REF_CODE
-+ /* initialise SA reference table */
-+
-+ /* initialise the main table */
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_init: "
-+ "initialising main table of size %u (2 ^ %u).\n",
-+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
-+ IPSEC_SA_REF_MAINTABLE_IDX_WIDTH);
-+ {
-+ unsigned table;
-+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
-+ ipsec_sadb.refTable[table] = NULL;
-+ }
-+ }
-+
-+ /* allocate the first sub-table */
-+ error = ipsec_SArefSubTable_alloc(0);
-+ if(error) {
-+ return error;
-+ }
-+
-+ error = ipsec_saref_freelist_init();
-+#endif /* IPSEC_SA_REF_CODE */
-+ return error;
-+}
-+
-+#if IPSEC_SA_REF_CODE
-+IPsecSAref_t
-+ipsec_SAref_alloc(int*error) /* pass in error var by pointer */
-+{
-+ IPsecSAref_t SAref;
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_alloc: "
-+ "SAref requested... head=%d, cont=%d, tail=%d, listsize=%d.\n",
-+ ipsec_sadb.refFreeListHead,
-+ ipsec_sadb.refFreeListCont,
-+ ipsec_sadb.refFreeListTail,
-+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
-+
-+ if(ipsec_sadb.refFreeListHead == -1) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_alloc: "
-+ "FreeList empty, recycling...\n");
-+ *error = ipsec_SAref_recycle();
-+ if(*error) {
-+ return IPSEC_SAREF_NULL;
-+ }
-+ }
-+
-+ SAref = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead];
-+ if(SAref == IPSEC_SAREF_NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_alloc: "
-+ "unexpected error, refFreeListHead = %d points to invalid entry.\n",
-+ ipsec_sadb.refFreeListHead);
-+ *error = -ESPIPE;
-+ return IPSEC_SAREF_NULL;
-+ }
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_alloc: "
-+ "allocating SAref=%d, table=%u, entry=%u of %u.\n",
-+ SAref,
-+ IPsecSAref2table(SAref),
-+ IPsecSAref2entry(SAref),
-+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES);
-+
-+ ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead] = IPSEC_SAREF_NULL;
-+ ipsec_sadb.refFreeListHead++;
-+ if(ipsec_sadb.refFreeListHead > ipsec_sadb.refFreeListTail) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_alloc: "
-+ "last FreeList entry allocated, resetting list head to empty.\n");
-+ ipsec_sadb.refFreeListHead = -1;
-+ }
-+
-+ return SAref;
-+}
-+#endif /* IPSEC_SA_REF_CODE */
-+
-+int
-+ipsec_sa_print(struct ipsec_sa *ips)
-+{
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+ printk(KERN_INFO "klips_debug: SA:");
-+ if(ips == NULL) {
-+ printk("NULL\n");
-+ return -ENOENT;
-+ }
-+ printk(" ref=%d", ips->ips_ref);
-+ printk(" refcount=%d", atomic_read(&ips->ips_refcount));
-+ if(ips->ips_hnext != NULL) {
-+ printk(" hnext=0p%p", ips->ips_hnext);
-+ }
-+ if(ips->ips_inext != NULL) {
-+ printk(" inext=0p%p", ips->ips_inext);
-+ }
-+ if(ips->ips_onext != NULL) {
-+ printk(" onext=0p%p", ips->ips_onext);
-+ }
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ printk(" said=%s", sa_len ? sa : " (error)");
-+ if(ips->ips_seq) {
-+ printk(" seq=%u", ips->ips_seq);
-+ }
-+ if(ips->ips_pid) {
-+ printk(" pid=%u", ips->ips_pid);
-+ }
-+ if(ips->ips_authalg) {
-+ printk(" authalg=%u", ips->ips_authalg);
-+ }
-+ if(ips->ips_encalg) {
-+ printk(" encalg=%u", ips->ips_encalg);
-+ }
-+ printk(" XFORM=%s%s%s", IPS_XFORM_NAME(ips));
-+ if(ips->ips_replaywin) {
-+ printk(" ooowin=%u", ips->ips_replaywin);
-+ }
-+ if(ips->ips_flags) {
-+ printk(" flags=%u", ips->ips_flags);
-+ }
-+ if(ips->ips_addr_s) {
-+ char buf[SUBNETTOA_BUF];
-+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
-+ 0, buf, sizeof(buf));
-+ printk(" src=%s", buf);
-+ }
-+ if(ips->ips_addr_d) {
-+ char buf[SUBNETTOA_BUF];
-+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
-+ 0, buf, sizeof(buf));
-+ printk(" dst=%s", buf);
-+ }
-+ if(ips->ips_addr_p) {
-+ char buf[SUBNETTOA_BUF];
-+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_p))->sin_addr,
-+ 0, buf, sizeof(buf));
-+ printk(" proxy=%s", buf);
-+ }
-+ if(ips->ips_key_bits_a) {
-+ printk(" key_bits_a=%u", ips->ips_key_bits_a);
-+ }
-+ if(ips->ips_key_bits_e) {
-+ printk(" key_bits_e=%u", ips->ips_key_bits_e);
-+ }
-+
-+ printk("\n");
-+ return 0;
-+}
-+
-+struct ipsec_sa*
-+ipsec_sa_alloc(int*error) /* pass in error var by pointer */
-+{
-+ struct ipsec_sa* ips;
-+
-+ if((ips = kmalloc(sizeof(*ips), GFP_ATOMIC) ) == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_alloc: "
-+ "memory allocation error\n");
-+ *error = -ENOMEM;
-+ return NULL;
-+ }
-+ memset((caddr_t)ips, 0, sizeof(*ips));
-+#if IPSEC_SA_REF_CODE
-+ ips->ips_ref = ipsec_SAref_alloc(error); /* pass in error return by pointer */
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_alloc: "
-+ "allocated %lu bytes for ipsec_sa struct=0p%p ref=%d.\n",
-+ (unsigned long) sizeof(*ips),
-+ ips,
-+ ips->ips_ref);
-+ if(ips->ips_ref == IPSEC_SAREF_NULL) {
-+ kfree(ips);
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_alloc: "
-+ "SAref allocation error\n");
-+ return NULL;
-+ }
-+
-+ atomic_inc(&ips->ips_refcount);
-+ IPsecSAref2SA(ips->ips_ref) = ips;
-+#endif /* IPSEC_SA_REF_CODE */
-+
-+ *error = 0;
-+ return(ips);
-+}
-+
-+int
-+ipsec_sa_free(struct ipsec_sa* ips)
-+{
-+ return ipsec_sa_wipe(ips);
-+}
-+
-+struct ipsec_sa *
-+ipsec_sa_getbyid(ip_said *said)
-+{
-+ int hashval;
-+ struct ipsec_sa *ips;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+ if(said == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_error:ipsec_sa_getbyid: "
-+ "null pointer passed in!\n");
-+ return NULL;
-+ }
-+
-+ sa_len = satot(said, 0, sa, sizeof(sa));
-+
-+ hashval = IPS_HASH(said);
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_getbyid: "
-+ "linked entry in ipsec_sa table for hash=%d of SA:%s requested.\n",
-+ hashval,
-+ sa_len ? sa : " (error)");
-+
-+ if((ips = ipsec_sadb_hash[hashval]) == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_getbyid: "
-+ "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
-+ hashval,
-+ sa_len ? sa : " (error)");
-+ return NULL;
-+ }
-+
-+ for (; ips; ips = ips->ips_hnext) {
-+ if ((ips->ips_said.spi == said->spi) &&
-+ (ips->ips_said.dst.u.v4.sin_addr.s_addr == said->dst.u.v4.sin_addr.s_addr) &&
-+ (ips->ips_said.proto == said->proto)) {
-+ atomic_inc(&ips->ips_refcount);
-+ return ips;
-+ }
-+ }
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_getbyid: "
-+ "no entry in linked list for hash=%d of SA:%s.\n",
-+ hashval,
-+ sa_len ? sa : " (error)");
-+ return NULL;
-+}
-+
-+int
-+ipsec_sa_put(struct ipsec_sa *ips)
-+{
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+ if(ips == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_error:ipsec_sa_put: "
-+ "null pointer passed in!\n");
-+ return -1;
-+ }
-+
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_put: "
-+ "ipsec_sa SA:%s, ref:%d reference count decremented.\n",
-+ sa_len ? sa : " (error)",
-+ ips->ips_ref);
-+
-+ atomic_dec(&ips->ips_refcount);
-+
-+ return 0;
-+}
-+
-+/*
-+ The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen
-+*/
-+int
-+ipsec_sa_add(struct ipsec_sa *ips)
-+{
-+ int error = 0;
-+ unsigned int hashval;
-+
-+ if(ips == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_error:ipsec_sa_add: "
-+ "null pointer passed in!\n");
-+ return -ENODATA;
-+ }
-+ hashval = IPS_HASH(&ips->ips_said);
-+
-+ atomic_inc(&ips->ips_refcount);
-+ spin_lock_bh(&tdb_lock);
-+
-+ ips->ips_hnext = ipsec_sadb_hash[hashval];
-+ ipsec_sadb_hash[hashval] = ips;
-+
-+ spin_unlock_bh(&tdb_lock);
-+
-+ return error;
-+}
-+
-+/*
-+ The ipsec_sa table better be locked before it is handed in, or races might happen
-+*/
-+int
-+ipsec_sa_del(struct ipsec_sa *ips)
-+{
-+ unsigned int hashval;
-+ struct ipsec_sa *ipstp;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+ if(ips == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_error:ipsec_sa_del: "
-+ "null pointer passed in!\n");
-+ return -ENODATA;
-+ }
-+
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ if(ips->ips_inext || ips->ips_onext) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_error:ipsec_sa_del: "
-+ "SA:%s still linked!\n",
-+ sa_len ? sa : " (error)");
-+ return -EMLINK;
-+ }
-+
-+ hashval = IPS_HASH(&ips->ips_said);
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_del: "
-+ "deleting SA:%s, hashval=%d.\n",
-+ sa_len ? sa : " (error)",
-+ hashval);
-+ if(ipsec_sadb_hash[hashval] == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_del: "
-+ "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
-+ hashval,
-+ sa_len ? sa : " (error)");
-+ return -ENOENT;
-+ }
-+
-+ if (ips == ipsec_sadb_hash[hashval]) {
-+ ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext;
-+ ips->ips_hnext = NULL;
-+ atomic_dec(&ips->ips_refcount);
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_del: "
-+ "successfully deleted first ipsec_sa in chain.\n");
-+ return 0;
-+ } else {
-+ for (ipstp = ipsec_sadb_hash[hashval];
-+ ipstp;
-+ ipstp = ipstp->ips_hnext) {
-+ if (ipstp->ips_hnext == ips) {
-+ ipstp->ips_hnext = ips->ips_hnext;
-+ ips->ips_hnext = NULL;
-+ atomic_dec(&ips->ips_refcount);
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_del: "
-+ "successfully deleted link in ipsec_sa chain.\n");
-+ return 0;
-+ }
-+ }
-+ }
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_del: "
-+ "no entries in linked list for hash=%d of SA:%s.\n",
-+ hashval,
-+ sa_len ? sa : " (error)");
-+ return -ENOENT;
-+}
-+
-+/*
-+ The ipsec_sa table better be locked before it is handed in, or races
-+ might happen
-+*/
-+int
-+ipsec_sa_delchain(struct ipsec_sa *ips)
-+{
-+ struct ipsec_sa *ipsdel;
-+ int error = 0;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+ if(ips == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_error:ipsec_sa_delchain: "
-+ "null pointer passed in!\n");
-+ return -ENODATA;
-+ }
-+
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_delchain: "
-+ "passed SA:%s\n",
-+ sa_len ? sa : " (error)");
-+ while(ips->ips_onext != NULL) {
-+ ips = ips->ips_onext;
-+ }
-+
-+ while(ips) {
-+ /* XXX send a pfkey message up to advise of deleted ipsec_sa */
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_delchain: "
-+ "unlinking and delting SA:%s",
-+ sa_len ? sa : " (error)");
-+ ipsdel = ips;
-+ ips = ips->ips_inext;
-+ if(ips != NULL) {
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ ", inext=%s",
-+ sa_len ? sa : " (error)");
-+ atomic_dec(&ipsdel->ips_refcount);
-+ ipsdel->ips_inext = NULL;
-+ atomic_dec(&ips->ips_refcount);
-+ ips->ips_onext = NULL;
-+ }
-+ KLIPS_PRINT(debug_xform,
-+ ".\n");
-+ if((error = ipsec_sa_del(ipsdel))) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_delchain: "
-+ "ipsec_sa_del returned error %d.\n", -error);
-+ return error;
-+ }
-+ if((error = ipsec_sa_wipe(ipsdel))) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_delchain: "
-+ "ipsec_sa_wipe returned error %d.\n", -error);
-+ return error;
-+ }
-+ }
-+ return error;
-+}
-+
-+int
-+ipsec_sadb_cleanup(__u8 proto)
-+{
-+ unsigned i;
-+ int error = 0;
-+ struct ipsec_sa *ips, **ipsprev, *ipsdel;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_cleanup: "
-+ "cleaning up proto=%d.\n",
-+ proto);
-+
-+ spin_lock_bh(&tdb_lock);
-+
-+ for (i = 0; i < SADB_HASHMOD; i++) {
-+ ipsprev = &(ipsec_sadb_hash[i]);
-+ ips = ipsec_sadb_hash[i];
-+ if(ips != NULL) {
-+ atomic_inc(&ips->ips_refcount);
-+ }
-+ for(; ips != NULL;) {
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_cleanup: "
-+ "checking SA:%s, hash=%d, ref=%d",
-+ sa_len ? sa : " (error)",
-+ i,
-+ ips->ips_ref);
-+ ipsdel = ips;
-+ ips = ipsdel->ips_hnext;
-+ if(ips != NULL) {
-+ atomic_inc(&ips->ips_refcount);
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ ", hnext=%s",
-+ sa_len ? sa : " (error)");
-+ }
-+ if(*ipsprev != NULL) {
-+ sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ ", *ipsprev=%s",
-+ sa_len ? sa : " (error)");
-+ if((*ipsprev)->ips_hnext) {
-+ sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ ", *ipsprev->ips_hnext=%s",
-+ sa_len ? sa : " (error)");
-+ }
-+ }
-+ KLIPS_PRINT(debug_xform,
-+ ".\n");
-+ if(proto == 0 || (proto == ipsdel->ips_said.proto)) {
-+ sa_len = satot(&ipsdel->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_cleanup: "
-+ "deleting SA chain:%s.\n",
-+ sa_len ? sa : " (error)");
-+ if((error = ipsec_sa_delchain(ipsdel))) {
-+ SENDERR(-error);
-+ }
-+ ipsprev = &(ipsec_sadb_hash[i]);
-+ ips = ipsec_sadb_hash[i];
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_cleanup: "
-+ "deleted SA chain:%s",
-+ sa_len ? sa : " (error)");
-+ if(ips != NULL) {
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ ", ipsec_sadb_hash[%d]=%s",
-+ i,
-+ sa_len ? sa : " (error)");
-+ }
-+ if(*ipsprev != NULL) {
-+ sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ ", *ipsprev=%s",
-+ sa_len ? sa : " (error)");
-+ if((*ipsprev)->ips_hnext != NULL) {
-+ sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ ", *ipsprev->ips_hnext=%s",
-+ sa_len ? sa : " (error)");
-+ }
-+ }
-+ KLIPS_PRINT(debug_xform,
-+ ".\n");
-+ } else {
-+ ipsprev = &ipsdel;
-+ }
-+ if(ipsdel != NULL) {
-+ ipsec_sa_put(ipsdel);
-+ }
-+ }
-+ }
-+ errlab:
-+
-+ spin_unlock_bh(&tdb_lock);
-+
-+
-+#if IPSEC_SA_REF_CODE
-+ /* clean up SA reference table */
-+
-+ /* go through the ref table and clean out all the SAs */
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_cleanup: "
-+ "removing SAref entries and tables.");
-+ {
-+ unsigned table, entry;
-+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_cleanup: "
-+ "cleaning SAref table=%u.\n",
-+ table);
-+ if(ipsec_sadb.refTable[table] == NULL) {
-+ printk("\n");
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_cleanup: "
-+ "cleaned %u used refTables.\n",
-+ table);
-+ break;
-+ }
-+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
-+ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
-+ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
-+ ipsec_sadb.refTable[table]->entry[entry] = NULL;
-+ }
-+ }
-+ }
-+ }
-+#endif /* IPSEC_SA_REF_CODE */
-+
-+ return(error);
-+}
-+
-+int
-+ipsec_sadb_free(void)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_free: "
-+ "freeing SArefTable memory.\n");
-+
-+ /* clean up SA reference table */
-+
-+ /* go through the ref table and clean out all the SAs if any are
-+ left and free table memory */
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_free: "
-+ "removing SAref entries and tables.\n");
-+ {
-+ unsigned table, entry;
-+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_free: "
-+ "removing SAref table=%u.\n",
-+ table);
-+ if(ipsec_sadb.refTable[table] == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_free: "
-+ "removed %u used refTables.\n",
-+ table);
-+ break;
-+ }
-+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
-+ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
-+ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
-+ ipsec_sadb.refTable[table]->entry[entry] = NULL;
-+ }
-+ }
-+ vfree(ipsec_sadb.refTable[table]);
-+ ipsec_sadb.refTable[table] = NULL;
-+ }
-+ }
-+
-+ return(error);
-+}
-+
-+int
-+ipsec_sa_wipe(struct ipsec_sa *ips)
-+{
-+ if(ips == NULL) {
-+ return -ENODATA;
-+ }
-+
-+ /* if(atomic_dec_and_test(ips)) {
-+ }; */
-+
-+#if IPSEC_SA_REF_CODE
-+ /* remove me from the SArefTable */
-+ {
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_wipe: "
-+ "removing SA=%s(0p%p), SAref=%d, table=%d(0p%p), entry=%d from the refTable.\n",
-+ sa_len ? sa : " (error)",
-+ ips,
-+ ips->ips_ref,
-+ IPsecSAref2table(IPsecSA2SAref(ips)),
-+ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))],
-+ IPsecSAref2entry(IPsecSA2SAref(ips)));
-+ }
-+ if(ips->ips_ref == IPSEC_SAREF_NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_wipe: "
-+ "why does this SA not have a valid SAref?.\n");
-+ }
-+ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))]->entry[IPsecSAref2entry(IPsecSA2SAref(ips))] = NULL;
-+ ips->ips_ref = IPSEC_SAREF_NULL;
-+ ipsec_sa_put(ips);
-+#endif /* IPSEC_SA_REF_CODE */
-+
-+ /* paranoid clean up */
-+ if(ips->ips_addr_s != NULL) {
-+ memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size);
-+ kfree(ips->ips_addr_s);
-+ }
-+ ips->ips_addr_s = NULL;
-+
-+ if(ips->ips_addr_d != NULL) {
-+ memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size);
-+ kfree(ips->ips_addr_d);
-+ }
-+ ips->ips_addr_d = NULL;
-+
-+ if(ips->ips_addr_p != NULL) {
-+ memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size);
-+ kfree(ips->ips_addr_p);
-+ }
-+ ips->ips_addr_p = NULL;
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if(ips->ips_natt_oa) {
-+ memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size);
-+ kfree(ips->ips_natt_oa);
-+ }
-+ ips->ips_natt_oa = NULL;
-+#endif
-+
-+ if(ips->ips_key_a != NULL) {
-+ memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size);
-+ kfree(ips->ips_key_a);
-+ }
-+ ips->ips_key_a = NULL;
-+
-+ if(ips->ips_key_e != NULL) {
-+#ifdef CONFIG_IPSEC_ALG
-+ if (ips->ips_alg_enc&&ips->ips_alg_enc->ixt_e_destroy_key) {
-+ ips->ips_alg_enc->ixt_e_destroy_key(ips->ips_alg_enc,
-+ ips->ips_key_e);
-+ } else {
-+#endif /* CONFIG_IPSEC_ALG */
-+ memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size);
-+ kfree(ips->ips_key_e);
-+#ifdef CONFIG_IPSEC_ALG
-+ }
-+#endif /* CONFIG_IPSEC_ALG */
-+ }
-+ ips->ips_key_e = NULL;
-+
-+ if(ips->ips_iv != NULL) {
-+ memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size);
-+ kfree(ips->ips_iv);
-+ }
-+ ips->ips_iv = NULL;
-+
-+ if(ips->ips_ident_s.data != NULL) {
-+ memset((caddr_t)(ips->ips_ident_s.data),
-+ 0,
-+ ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
-+ kfree(ips->ips_ident_s.data);
-+ }
-+ ips->ips_ident_s.data = NULL;
-+
-+ if(ips->ips_ident_d.data != NULL) {
-+ memset((caddr_t)(ips->ips_ident_d.data),
-+ 0,
-+ ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
-+ kfree(ips->ips_ident_d.data);
-+ }
-+ ips->ips_ident_d.data = NULL;
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if (ips->ips_alg_enc||ips->ips_alg_auth) {
-+ ipsec_alg_sa_wipe(ips);
-+ }
-+#endif /* CONFIG_IPSEC_ALG */
-+
-+ memset((caddr_t)ips, 0, sizeof(*ips));
-+ kfree(ips);
-+ ips = NULL;
-+
-+ return 0;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.23 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.22.2.1 2003/12/22 15:25:52 jjo
-+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.22 2003/12/10 01:14:27 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.21 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.20.4.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.20 2003/02/06 01:50:34 rgb
-+ * Fixed initialisation bug for first sadb hash bucket that would only manifest itself on platforms where NULL != 0.
-+ *
-+ * Revision 1.19 2003/01/30 02:32:22 rgb
-+ *
-+ * Rename SAref table macro names for clarity.
-+ * Transmit error code through to caller from callee for better diagnosis of problems.
-+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
-+ *
-+ * Revision 1.18 2002/10/12 23:11:53 dhr
-+ *
-+ * [KenB + DHR] more 64-bit cleanup
-+ *
-+ * Revision 1.17 2002/10/07 18:31:43 rgb
-+ * Move field width sanity checks to ipsec_sa.c
-+ *
-+ * Revision 1.16 2002/09/20 15:41:02 rgb
-+ * Re-wrote most of the SAref code to eliminate Entry pointers.
-+ * Added SAref code compiler directive switch.
-+ * Added a saref test function for testing macros.
-+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
-+ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
-+ * of freeing newly created structures when clearing the reftable upon startup
-+ * to start from a known state.
-+ * Place all ipsec sadb globals into one struct.
-+ * Rework saref freelist.
-+ * Added memory allocation debugging.
-+ *
-+ * Revision 1.15 2002/09/20 05:01:44 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.14 2002/08/13 19:01:25 mcr
-+ * patches from kenb to permit compilation of FreeSWAN on ia64.
-+ * des library patched to use proper DES_LONG type for ia64.
-+ *
-+ * Revision 1.13 2002/07/29 03:06:20 mcr
-+ * get rid of variable not used warnings.
-+ *
-+ * Revision 1.12 2002/07/26 08:48:31 rgb
-+ * Added SA ref table code.
-+ *
-+ * Revision 1.11 2002/06/04 16:48:49 rgb
-+ * Tidied up pointer code for processor independance.
-+ *
-+ * Revision 1.10 2002/05/23 07:16:17 rgb
-+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
-+ * Pointer clean-up.
-+ * Added refcount code.
-+ * Convert "usecount" to "refcount" to remove ambiguity.
-+ *
-+ * Revision 1.9 2002/05/14 02:34:49 rgb
-+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
-+ * with "put" usage in the kernel.
-+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
-+ * ipsec_sa or ipsec_sa.
-+ * Added some preliminary refcount code.
-+ *
-+ * Revision 1.8 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.7 2002/04/24 07:36:30 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_sa.c,v
-+ *
-+ * Revision 1.6 2002/04/20 00:12:25 rgb
-+ * Added esp IV CBC attack fix, disabled.
-+ *
-+ * Revision 1.5 2002/01/29 17:17:56 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.4 2002/01/29 04:00:52 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.3 2002/01/29 02:13:18 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.2 2001/11/26 09:16:15 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.2 2001/10/22 21:05:41 mcr
-+ * removed phony prototype for des_set_key.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:24:57 mcr
-+ * struct tdb -> struct ipsec_sa.
-+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
-+ * ipsec_xform.c removed. header file still contains useful things.
-+ *
-+ *
-+ *
-+ * CLONED from ipsec_xform.c:
-+ * Revision 1.53 2001/09/08 21:13:34 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.52 2001/06/14 19:35:11 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.51 2001/05/30 08:14:03 rgb
-+ * Removed vestiges of esp-null transforms.
-+ *
-+ * Revision 1.50 2001/05/03 19:43:18 rgb
-+ * Initialise error return variable.
-+ * Update SENDERR macro.
-+ * Fix sign of error return code for ipsec_tdbcleanup().
-+ * Use more appropriate return code for ipsec_tdbwipe().
-+ *
-+ * Revision 1.49 2001/04/19 18:56:17 rgb
-+ * Fixed tdb table locking comments.
-+ *
-+ * Revision 1.48 2001/02/27 22:24:55 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.47 2000/11/06 04:32:08 rgb
-+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
-+ *
-+ * Revision 1.46 2000/09/20 16:21:57 rgb
-+ * Cleaned up ident string alloc/free.
-+ *
-+ * Revision 1.45 2000/09/08 19:16:51 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
-+ *
-+ * Revision 1.44 2000/08/30 05:29:04 rgb
-+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
-+ *
-+ * Revision 1.43 2000/08/18 21:30:41 rgb
-+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
-+ *
-+ * Revision 1.42 2000/08/01 14:51:51 rgb
-+ * Removed _all_ remaining traces of DES.
-+ *
-+ * Revision 1.41 2000/07/28 14:58:31 rgb
-+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
-+ *
-+ * Revision 1.40 2000/06/28 05:50:11 rgb
-+ * Actually set iv_bits.
-+ *
-+ * Revision 1.39 2000/05/10 23:11:09 rgb
-+ * Added netlink debugging output.
-+ * Added a cast to quiet down the ntohl bug.
-+ *
-+ * Revision 1.38 2000/05/10 19:18:42 rgb
-+ * Cast output of ntohl so that the broken prototype doesn't make our
-+ * compile noisy.
-+ *
-+ * Revision 1.37 2000/03/16 14:04:59 rgb
-+ * Hardwired CONFIG_IPSEC_PFKEYv2 on.
-+ *
-+ * Revision 1.36 2000/01/26 10:11:28 rgb
-+ * Fixed spacing in error text causing run-in words.
-+ *
-+ * Revision 1.35 2000/01/21 06:17:16 rgb
-+ * Tidied up compiler directive indentation for readability.
-+ * Added ictx,octx vars for simplification.(kravietz)
-+ * Added macros for HMAC padding magic numbers.(kravietz)
-+ * Fixed missing key length reporting bug.
-+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
-+ *
-+ * Revision 1.34 1999/12/08 00:04:19 rgb
-+ * Fixed SA direction overwriting bug for netlink users.
-+ *
-+ * Revision 1.33 1999/12/01 22:16:44 rgb
-+ * Minor formatting changes in ESP MD5 initialisation.
-+ *
-+ * Revision 1.32 1999/11/25 09:06:36 rgb
-+ * Fixed error return messages, should be returning negative numbers.
-+ * Implemented SENDERR macro for propagating error codes.
-+ * Added debug message and separate error code for algorithms not compiled
-+ * in.
-+ *
-+ * Revision 1.31 1999/11/23 23:06:26 rgb
-+ * Sort out pfkey and freeswan headers, putting them in a library path.
-+ *
-+ * Revision 1.30 1999/11/18 04:09:20 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ *
-+ * Revision 1.29 1999/11/17 15:53:40 rgb
-+ * Changed all occurrences of #include "../../../lib/freeswan.h"
-+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
-+ * klips/net/ipsec/Makefile.
-+ *
-+ * Revision 1.28 1999/10/18 20:04:01 rgb
-+ * Clean-out unused cruft.
-+ *
-+ * Revision 1.27 1999/10/03 19:01:03 rgb
-+ * Spinlock support for 2.3.xx and 2.0.xx kernels.
-+ *
-+ * Revision 1.26 1999/10/01 16:22:24 rgb
-+ * Switch from assignment init. to functional init. of spinlocks.
-+ *
-+ * Revision 1.25 1999/10/01 15:44:54 rgb
-+ * Move spinlock header include to 2.1> scope.
-+ *
-+ * Revision 1.24 1999/10/01 00:03:46 rgb
-+ * Added tdb structure locking.
-+ * Minor formatting changes.
-+ * Add function to initialize tdb hash table.
-+ *
-+ * Revision 1.23 1999/05/25 22:42:12 rgb
-+ * Add deltdbchain() debugging.
-+ *
-+ * Revision 1.22 1999/05/25 21:24:31 rgb
-+ * Add debugging statements to deltdbchain().
-+ *
-+ * Revision 1.21 1999/05/25 03:51:48 rgb
-+ * Refix error return code.
-+ *
-+ * Revision 1.20 1999/05/25 03:34:07 rgb
-+ * Fix error return for flush.
-+ *
-+ * Revision 1.19 1999/05/09 03:25:37 rgb
-+ * Fix bug introduced by 2.2 quick-and-dirty patch.
-+ *
-+ * Revision 1.18 1999/05/05 22:02:32 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.17 1999/04/29 15:20:16 rgb
-+ * Change gettdb parameter to a pointer to reduce stack loading and
-+ * facilitate parameter sanity checking.
-+ * Add sanity checking for null pointer arguments.
-+ * Add debugging instrumentation.
-+ * Add function deltdbchain() which will take care of unlinking,
-+ * zeroing and deleting a chain of tdbs.
-+ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
-+ * tdbwipe now actually zeroes the tdb as well as any of its pointed
-+ * structures.
-+ *
-+ * Revision 1.16 1999/04/16 15:36:29 rgb
-+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
-+ *
-+ * Revision 1.15 1999/04/11 00:29:01 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.14 1999/04/06 04:54:28 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.13 1999/02/19 18:23:01 rgb
-+ * Nix debug off compile warning.
-+ *
-+ * Revision 1.12 1999/02/17 16:52:16 rgb
-+ * Consolidate satoa()s for space and speed efficiency.
-+ * Convert DEBUG_IPSEC to KLIPS_PRINT
-+ * Clean out unused cruft.
-+ * Ditch NET_IPIP dependancy.
-+ * Loop for 3des key setting.
-+ *
-+ * Revision 1.11 1999/01/26 02:09:05 rgb
-+ * Remove ah/esp/IPIP switching on include files.
-+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
-+ * Removed dead code.
-+ * Clean up debug code when switched off.
-+ * Remove references to INET_GET_PROTOCOL.
-+ * Added code exclusion macros to reduce code from unused algorithms.
-+ *
-+ * Revision 1.10 1999/01/22 06:28:55 rgb
-+ * Cruft clean-out.
-+ * Put random IV generation in kernel.
-+ * Added algorithm switch code.
-+ * Enhanced debugging.
-+ * 64-bit clean-up.
-+ *
-+ * Revision 1.9 1998/11/30 13:22:55 rgb
-+ * Rationalised all the klips kernel file headers. They are much shorter
-+ * now and won't conflict under RH5.2.
-+ *
-+ * Revision 1.8 1998/11/25 04:59:06 rgb
-+ * Add conditionals for no IPIP tunnel code.
-+ * Delete commented out code.
-+ *
-+ * Revision 1.7 1998/10/31 06:50:41 rgb
-+ * Convert xform ASCII names to no spaces.
-+ * Fixed up comments in #endif directives.
-+ *
-+ * Revision 1.6 1998/10/19 14:44:28 rgb
-+ * Added inclusion of freeswan.h.
-+ * sa_id structure implemented and used: now includes protocol.
-+ *
-+ * Revision 1.5 1998/10/09 04:32:19 rgb
-+ * Added 'klips_debug' prefix to all klips printk debug statements.
-+ *
-+ * Revision 1.4 1998/08/12 00:11:31 rgb
-+ * Added new xform functions to the xform table.
-+ * Fixed minor debug output spelling error.
-+ *
-+ * Revision 1.3 1998/07/09 17:45:31 rgb
-+ * Clarify algorithm not available message.
-+ *
-+ * Revision 1.2 1998/06/23 03:00:51 rgb
-+ * Check for presence of IPIP protocol if it is setup one way (we don't
-+ * know what has been set up the other way and can only assume it will be
-+ * symmetrical with the exception of keys).
-+ *
-+ * Revision 1.1 1998/06/18 21:27:51 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.3 1998/06/11 05:54:59 rgb
-+ * Added transform version string pointer to xformsw initialisations.
-+ *
-+ * Revision 1.2 1998/04/21 21:28:57 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:13 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.5 1997/06/03 04:24:48 ji
-+ * Added ESP-3DES-MD5-96
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * Added new transforms.
-+ *
-+ * Revision 0.3 1996/11/20 14:39:04 ji
-+ * Minor cleanups.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_sha1.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,219 @@
-+/*
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * The rest of the code is derived from sha1.c by Steve Reid, which is
-+ * public domain.
-+ * Minor cosmetic changes to accomodate it in the Linux kernel by ji.
-+ */
-+
-+#include <asm/byteorder.h>
-+#include <linux/string.h>
-+
-+#include "openswan/ipsec_sha1.h"
-+
-+#if defined(rol)
-+#undef rol
-+#endif
-+
-+#define SHA1HANDSOFF
-+
-+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-+
-+/* blk0() and blk() perform the initial expand. */
-+/* I got the idea of expanding during the round function from SSLeay */
-+#ifdef __LITTLE_ENDIAN
-+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
-+ |(rol(block->l[i],8)&0x00FF00FF))
-+#else
-+#define blk0(i) block->l[i]
-+#endif
-+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
-+ ^block->l[(i+2)&15]^block->l[i&15],1))
-+
-+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
-+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
-+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
-+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
-+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
-+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
-+
-+
-+/* Hash a single 512-bit block. This is the core of the algorithm. */
-+
-+void SHA1Transform(__u32 state[5], __u8 buffer[64])
-+{
-+__u32 a, b, c, d, e;
-+typedef union {
-+ unsigned char c[64];
-+ __u32 l[16];
-+} CHAR64LONG16;
-+CHAR64LONG16* block;
-+#ifdef SHA1HANDSOFF
-+static unsigned char workspace[64];
-+ block = (CHAR64LONG16*)workspace;
-+ memcpy(block, buffer, 64);
-+#else
-+ block = (CHAR64LONG16*)buffer;
-+#endif
-+ /* Copy context->state[] to working vars */
-+ a = state[0];
-+ b = state[1];
-+ c = state[2];
-+ d = state[3];
-+ e = state[4];
-+ /* 4 rounds of 20 operations each. Loop unrolled. */
-+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
-+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
-+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
-+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
-+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
-+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
-+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
-+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
-+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
-+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
-+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
-+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
-+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
-+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
-+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
-+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
-+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
-+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
-+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
-+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
-+ /* Add the working vars back into context.state[] */
-+ state[0] += a;
-+ state[1] += b;
-+ state[2] += c;
-+ state[3] += d;
-+ state[4] += e;
-+ /* Wipe variables */
-+ a = b = c = d = e = 0;
-+}
-+
-+
-+/* SHA1Init - Initialize new context */
-+
-+void SHA1Init(void *vcontext)
-+{
-+ SHA1_CTX* context = vcontext;
-+
-+ /* SHA1 initialization constants */
-+ context->state[0] = 0x67452301;
-+ context->state[1] = 0xEFCDAB89;
-+ context->state[2] = 0x98BADCFE;
-+ context->state[3] = 0x10325476;
-+ context->state[4] = 0xC3D2E1F0;
-+ context->count[0] = context->count[1] = 0;
-+}
-+
-+
-+/* Run your data through this. */
-+
-+void SHA1Update(void *vcontext, unsigned char* data, __u32 len)
-+{
-+ SHA1_CTX* context = vcontext;
-+ __u32 i, j;
-+
-+ j = context->count[0];
-+ if ((context->count[0] += len << 3) < j)
-+ context->count[1]++;
-+ context->count[1] += (len>>29);
-+ j = (j >> 3) & 63;
-+ if ((j + len) > 63) {
-+ memcpy(&context->buffer[j], data, (i = 64-j));
-+ SHA1Transform(context->state, context->buffer);
-+ for ( ; i + 63 < len; i += 64) {
-+ SHA1Transform(context->state, &data[i]);
-+ }
-+ j = 0;
-+ }
-+ else i = 0;
-+ memcpy(&context->buffer[j], &data[i], len - i);
-+}
-+
-+
-+/* Add padding and return the message digest. */
-+
-+void SHA1Final(unsigned char digest[20], void *vcontext)
-+{
-+ __u32 i, j;
-+ unsigned char finalcount[8];
-+ SHA1_CTX* context = vcontext;
-+
-+ for (i = 0; i < 8; i++) {
-+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
-+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
-+ }
-+ SHA1Update(context, (unsigned char *)"\200", 1);
-+ while ((context->count[0] & 504) != 448) {
-+ SHA1Update(context, (unsigned char *)"\0", 1);
-+ }
-+ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
-+ for (i = 0; i < 20; i++) {
-+ digest[i] = (unsigned char)
-+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
-+ }
-+ /* Wipe variables */
-+ i = j = 0;
-+ memset(context->buffer, 0, 64);
-+ memset(context->state, 0, 20);
-+ memset(context->count, 0, 8);
-+ memset(&finalcount, 0, 8);
-+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
-+ SHA1Transform(context->state, context->buffer);
-+#endif
-+}
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.9 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.8 2002/09/10 01:45:14 mcr
-+ * changed type of MD5_CTX and SHA1_CTX to void * so that
-+ * the function prototypes would match, and could be placed
-+ * into a pointer to a function.
-+ *
-+ * Revision 1.7 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.6 2002/04/24 07:36:30 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_sha1.c,v
-+ *
-+ * Revision 1.5 1999/12/13 13:59:13 rgb
-+ * Quick fix to argument size to Update bugs.
-+ *
-+ * Revision 1.4 1999/04/11 00:29:00 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.3 1999/04/06 04:54:27 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.2 1999/01/22 06:55:50 rgb
-+ * 64-bit clean-up.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:50 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.2 1998/04/23 20:54:04 rgb
-+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
-+ * verified.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:11 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:05 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * New transform
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_tunnel.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,2645 @@
-+/*
-+ * IPSEC Tunneling code. Heavily based on drivers/net/new_tunnel.c
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipsec_tunnel_c_version[] = "RCSID $Id$";
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/config.h> /* for CONFIG_IP_FORWARD */
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/tcp.h> /* struct tcphdr */
-+#include <linux/udp.h> /* struct udphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define ip_chk_addr inet_addr_type
-+# define IS_MYADDR RTN_LOCAL
-+# include <net/dst.h>
-+# undef dev_kfree_skb
-+# define dev_kfree_skb(a,b) kfree_skb(a)
-+# define PHYSDEV_TYPE
-+#endif /* NET_21 */
-+#include <asm/checksum.h>
-+#include <net/icmp.h> /* icmp_send() */
-+#include <net/ip.h>
-+#ifdef NETDEV_23
-+# include <linux/netfilter_ipv4.h>
-+#endif /* NETDEV_23 */
-+
-+#include <linux/if_arp.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_life.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_eroute.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_sa.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_xmit.h"
-+#include "openswan/ipsec_ipe4.h"
-+#include "openswan/ipsec_ah.h"
-+#include "openswan/ipsec_esp.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+#include <linux/udp.h>
-+#endif
-+
-+static __u32 zeroes[64];
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_tunnel = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_open(struct device *dev)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ /*
-+ * Can't open until attached.
-+ */
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_open: "
-+ "dev = %s, prv->dev = %s\n",
-+ dev->name, prv->dev?prv->dev->name:"NONE");
-+
-+ if (prv->dev == NULL)
-+ return -ENODEV;
-+
-+ MOD_INC_USE_COUNT;
-+ return 0;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_close(struct device *dev)
-+{
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+#ifdef NETDEV_23
-+static inline int ipsec_tunnel_xmit2(struct sk_buff *skb)
-+{
-+#ifdef NETDEV_25 /* 2.6 kernels */
-+ return dst_output(skb);
-+#else
-+ return ip_send(skb);
-+#endif
-+}
-+#endif /* NETDEV_23 */
-+
-+enum ipsec_xmit_value
-+ipsec_tunnel_strip_hard_header(struct ipsec_xmit_state *ixs)
-+{
-+ /* ixs->physdev->hard_header_len is unreliable and should not be used */
-+ ixs->hard_header_len = (unsigned char *)(ixs->iph) - ixs->skb->data;
-+
-+ if(ixs->hard_header_len < 0) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_error:ipsec_xmit_strip_hard_header: "
-+ "Negative hard_header_len (%d)?!\n", ixs->hard_header_len);
-+ ixs->stats->tx_dropped++;
-+ return IPSEC_XMIT_BADHHLEN;
-+ }
-+
-+ /* while ixs->physdev->hard_header_len is unreliable and
-+ * should not be trusted, it accurate and required for ATM, GRE and
-+ * some other interfaces to work. Thanks to Willy Tarreau
-+ * <willy@w.ods.org>.
-+ */
-+ if(ixs->hard_header_len == 0) { /* no hard header present */
-+ ixs->hard_header_stripped = 1;
-+ ixs->hard_header_len = ixs->physdev->hard_header_len;
-+ }
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (debug_tunnel & DB_TN_XMIT) {
-+ int i;
-+ char c;
-+
-+ printk(KERN_INFO "klips_debug:ipsec_xmit_strip_hard_header: "
-+ ">>> skb->len=%ld hard_header_len:%d",
-+ (unsigned long int)ixs->skb->len, ixs->hard_header_len);
-+ c = ' ';
-+ for (i=0; i < ixs->hard_header_len; i++) {
-+ printk("%c%02x", c, ixs->skb->data[i]);
-+ c = ':';
-+ }
-+ printk(" \n");
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_strip_hard_header: "
-+ "Original head,tailroom: %d,%d\n",
-+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_tunnel_SAlookup(struct ipsec_xmit_state *ixs)
-+{
-+ /*
-+ * First things first -- look us up in the erouting tables.
-+ */
-+ ixs->matcher.sen_len = sizeof (struct sockaddr_encap);
-+ ixs->matcher.sen_family = AF_ENCAP;
-+ ixs->matcher.sen_type = SENT_IP4;
-+ ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
-+ ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
-+ ixs->matcher.sen_proto = ixs->iph->protocol;
-+ ipsec_extract_ports(ixs->iph, &ixs->matcher);
-+
-+ /*
-+ * The spinlock is to prevent any other process from accessing or deleting
-+ * the eroute while we are using and updating it.
-+ */
-+ spin_lock(&eroute_lock);
-+
-+ ixs->eroute = ipsec_findroute(&ixs->matcher);
-+
-+ if(ixs->iph->protocol == IPPROTO_UDP) {
-+ if(ixs->skb->sk) {
-+ ixs->sport=ntohs(ixs->skb->sk->sport);
-+ ixs->dport=ntohs(ixs->skb->sk->dport);
-+ } else if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 &&
-+ ((ixs->skb->len - ixs->hard_header_len) >=
-+ ((ixs->iph->ihl << 2) + sizeof(struct udphdr)))) {
-+ ixs->sport=ntohs(((struct udphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)))->source);
-+ ixs->dport=ntohs(((struct udphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl<<2)))->dest);
-+ } else {
-+ ixs->sport=0; ixs->dport=0;
-+ }
-+ }
-+
-+ /* default to a %drop eroute */
-+ ixs->outgoing_said.proto = IPPROTO_INT;
-+ ixs->outgoing_said.spi = htonl(SPI_DROP);
-+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_SAlookup: "
-+ "checking for local udp/500 IKE packet "
-+ "saddr=%x, er=0p%p, daddr=%x, er_dst=%x, proto=%d sport=%d dport=%d\n",
-+ ntohl((unsigned int)ixs->iph->saddr),
-+ ixs->eroute,
-+ ntohl((unsigned int)ixs->iph->daddr),
-+ ixs->eroute ? ntohl((unsigned int)ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr) : 0,
-+ ixs->iph->protocol,
-+ ixs->sport,
-+ ixs->dport);
-+
-+ /*
-+ * Quick cheat for now...are we udp/500? If so, let it through
-+ * without interference since it is most likely an IKE packet.
-+ */
-+
-+ if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR
-+ && (!ixs->eroute
-+ || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr
-+ || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr)
-+
-+ && ((ixs->sport == 500) || (ixs->sport == 4500))) {
-+ /* Whatever the eroute, this is an IKE message
-+ * from us (i.e. not being forwarded).
-+ * Furthermore, if there is a tunnel eroute,
-+ * the destination is the peer for this eroute.
-+ * So %pass the packet: modify the default %drop.
-+ */
-+ ixs->outgoing_said.spi = htonl(SPI_PASS);
-+ if(!(ixs->skb->sk) && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0)) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_SAlookup: "
-+ "local UDP/500 (probably IKE) passthrough: base fragment, rest of fragments will probably get filtered.\n");
-+ }
-+ } else if (ixs->eroute) {
-+ ixs->eroute->er_count++;
-+ ixs->eroute->er_lasttime = jiffies/HZ;
-+ if(ixs->eroute->er_said.proto==IPPROTO_INT
-+ && ixs->eroute->er_said.spi==htonl(SPI_HOLD)) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_SAlookup: "
-+ "shunt SA of HOLD: skb stored in HOLD.\n");
-+ if(ixs->eroute->er_last != NULL) {
-+ kfree_skb(ixs->eroute->er_last);
-+ }
-+ ixs->eroute->er_last = ixs->skb;
-+ ixs->skb = NULL;
-+ ixs->stats->tx_dropped++;
-+ spin_unlock(&eroute_lock);
-+ return IPSEC_XMIT_STOLEN;
-+ }
-+ ixs->outgoing_said = ixs->eroute->er_said;
-+ ixs->eroute_pid = ixs->eroute->er_pid;
-+ /* Copy of the ident for the TRAP/TRAPSUBNET eroutes */
-+ if(ixs->outgoing_said.proto==IPPROTO_INT
-+ && (ixs->outgoing_said.spi==htonl(SPI_TRAP)
-+ || (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)))) {
-+ int len;
-+
-+ ixs->ips.ips_ident_s.type = ixs->eroute->er_ident_s.type;
-+ ixs->ips.ips_ident_s.id = ixs->eroute->er_ident_s.id;
-+ ixs->ips.ips_ident_s.len = ixs->eroute->er_ident_s.len;
-+ if (ixs->ips.ips_ident_s.len) {
-+ len = ixs->ips.ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_SAlookup: "
-+ "allocating %d bytes for ident_s shunt SA of HOLD: skb stored in HOLD.\n",
-+ len);
-+ if ((ixs->ips.ips_ident_s.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
-+ printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
-+ "Failed, tried to allocate %d bytes for source ident.\n",
-+ len);
-+ ixs->stats->tx_dropped++;
-+ spin_unlock(&eroute_lock);
-+ return IPSEC_XMIT_ERRMEMALLOC;
-+ }
-+ memcpy(ixs->ips.ips_ident_s.data, ixs->eroute->er_ident_s.data, len);
-+ }
-+ ixs->ips.ips_ident_d.type = ixs->eroute->er_ident_d.type;
-+ ixs->ips.ips_ident_d.id = ixs->eroute->er_ident_d.id;
-+ ixs->ips.ips_ident_d.len = ixs->eroute->er_ident_d.len;
-+ if (ixs->ips.ips_ident_d.len) {
-+ len = ixs->ips.ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_SAlookup: "
-+ "allocating %d bytes for ident_d shunt SA of HOLD: skb stored in HOLD.\n",
-+ len);
-+ if ((ixs->ips.ips_ident_d.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
-+ printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
-+ "Failed, tried to allocate %d bytes for dest ident.\n",
-+ len);
-+ ixs->stats->tx_dropped++;
-+ spin_unlock(&eroute_lock);
-+ return IPSEC_XMIT_ERRMEMALLOC;
-+ }
-+ memcpy(ixs->ips.ips_ident_d.data, ixs->eroute->er_ident_d.data, len);
-+ }
-+ }
-+ }
-+
-+ spin_unlock(&eroute_lock);
-+ return IPSEC_XMIT_OK;
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_tunnel_restore_hard_header(struct ipsec_xmit_state*ixs)
-+{
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_restore_hard_header: "
-+ "After recursive xforms -- head,tailroom: %d,%d\n",
-+ skb_headroom(ixs->skb),
-+ skb_tailroom(ixs->skb));
-+
-+ if(ixs->saved_header) {
-+ if(skb_headroom(ixs->skb) < ixs->hard_header_len) {
-+ printk(KERN_WARNING
-+ "klips_error:ipsec_xmit_restore_hard_header: "
-+ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
-+ ixs->hard_header_len,
-+ skb_headroom(ixs->skb));
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_PUSHPULLERR;
-+
-+ }
-+ skb_push(ixs->skb, ixs->hard_header_len);
-+ {
-+ int i;
-+ for (i = 0; i < ixs->hard_header_len; i++) {
-+ ixs->skb->data[i] = ixs->saved_header[i];
-+ }
-+ }
-+ }
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if (ixs->natt_type && ixs->natt_head) {
-+ struct iphdr *ipp = ixs->skb->nh.iph;
-+ struct udphdr *udp;
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "encapsuling packet into UDP (NAT-Traversal) (%d %d)\n",
-+ ixs->natt_type, ixs->natt_head);
-+
-+ ixs->iphlen = ipp->ihl << 2;
-+ ipp->tot_len =
-+ htons(ntohs(ipp->tot_len) + ixs->natt_head);
-+ if(skb_tailroom(ixs->skb) < ixs->natt_head) {
-+ printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "
-+ "tried to skb_put %d, %d available. "
-+ "This should never happen, please report.\n",
-+ ixs->natt_head,
-+ skb_tailroom(ixs->skb));
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESPUDP;
-+ }
-+ skb_put(ixs->skb, ixs->natt_head);
-+
-+ udp = (struct udphdr *)((char *)ipp + ixs->iphlen);
-+
-+ /* move ESP hdr after UDP hdr */
-+ memmove((void *)((char *)udp + ixs->natt_head),
-+ (void *)(udp),
-+ ntohs(ipp->tot_len) - ixs->iphlen - ixs->natt_head);
-+
-+ /* clear UDP & Non-IKE Markers (if any) */
-+ memset(udp, 0, ixs->natt_head);
-+
-+ /* fill UDP with usefull informations ;-) */
-+ udp->source = htons(ixs->natt_sport);
-+ udp->dest = htons(ixs->natt_dport);
-+ udp->len = htons(ntohs(ipp->tot_len) - ixs->iphlen);
-+
-+ /* set protocol */
-+ ipp->protocol = IPPROTO_UDP;
-+
-+ /* fix IP checksum */
-+ ipp->check = 0;
-+ ipp->check = ip_fast_csum((unsigned char *)ipp, ipp->ihl);
-+ }
-+#endif
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_restore_hard_header: "
-+ "With hard_header, final head,tailroom: %d,%d\n",
-+ skb_headroom(ixs->skb),
-+ skb_tailroom(ixs->skb));
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_tunnel_send(struct ipsec_xmit_state*ixs)
-+{
-+#ifdef NETDEV_25
-+ struct flowi fl;
-+#endif
-+
-+#ifdef NET_21 /* 2.2 and 2.4 kernels */
-+ /* new route/dst cache code from James Morris */
-+ ixs->skb->dev = ixs->physdev;
-+#ifdef NETDEV_25
-+ fl.oif = ixs->physdev->iflink;
-+ fl.nl_u.ip4_u.daddr = ixs->skb->nh.iph->daddr;
-+ fl.nl_u.ip4_u.saddr = ixs->pass ? 0 : ixs->skb->nh.iph->saddr;
-+ fl.nl_u.ip4_u.tos = RT_TOS(ixs->skb->nh.iph->tos);
-+ fl.proto = ixs->skb->nh.iph->protocol;
-+ if ((ixs->error = ip_route_output_key(&ixs->route, &fl))) {
-+#else
-+ /*skb_orphan(ixs->skb);*/
-+ if((ixs->error = ip_route_output(&ixs->route,
-+ ixs->skb->nh.iph->daddr,
-+ ixs->pass ? 0 : ixs->skb->nh.iph->saddr,
-+ RT_TOS(ixs->skb->nh.iph->tos),
-+ /* mcr->rgb: should this be 0 instead? */
-+ ixs->physdev->iflink))) {
-+#endif
-+ ixs->stats->tx_errors++;
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_send: "
-+ "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
-+ ixs->error,
-+ ixs->route->u.dst.dev->name);
-+ return IPSEC_XMIT_ROUTEERR;
-+ }
-+ if(ixs->dev == ixs->route->u.dst.dev) {
-+ ip_rt_put(ixs->route);
-+ /* This is recursion, drop it. */
-+ ixs->stats->tx_errors++;
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_send: "
-+ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
-+ ixs->dev->name);
-+ return IPSEC_XMIT_RECURSDETECT;
-+ }
-+ dst_release(ixs->skb->dst);
-+ ixs->skb->dst = &ixs->route->u.dst;
-+ ixs->stats->tx_bytes += ixs->skb->len;
-+ if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {
-+ ixs->stats->tx_errors++;
-+ printk(KERN_WARNING
-+ "klips_error:ipsec_xmit_send: "
-+ "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
-+ (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),
-+ ixs->skb->len);
-+ return IPSEC_XMIT_PUSHPULLERR;
-+ }
-+ __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);
-+#ifdef SKB_RESET_NFCT
-+ if(!ixs->pass) {
-+ nf_conntrack_put(ixs->skb->nfct);
-+ ixs->skb->nfct = NULL;
-+ }
-+#ifdef CONFIG_NETFILTER_DEBUG
-+ ixs->skb->nf_debug = 0;
-+#endif /* CONFIG_NETFILTER_DEBUG */
-+#endif /* SKB_RESET_NFCT */
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_send: "
-+ "...done, calling ip_send() on device:%s\n",
-+ ixs->skb->dev ? ixs->skb->dev->name : "NULL");
-+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->skb->nh.iph);
-+#ifdef NETDEV_23 /* 2.4 kernels */
-+ {
-+ int err;
-+
-+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,
-+ ipsec_tunnel_xmit2);
-+ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
-+ if(net_ratelimit())
-+ printk(KERN_ERR
-+ "klips_error:ipsec_xmit_send: "
-+ "ip_send() failed, err=%d\n",
-+ -err);
-+ ixs->stats->tx_errors++;
-+ ixs->stats->tx_aborted_errors++;
-+ ixs->skb = NULL;
-+ return IPSEC_XMIT_IPSENDFAILURE;
-+ }
-+ }
-+#else /* NETDEV_23 */ /* 2.2 kernels */
-+ ip_send(ixs->skb);
-+#endif /* NETDEV_23 */
-+#else /* NET_21 */ /* 2.0 kernels */
-+ ixs->skb->arp = 1;
-+ /* ISDN/ASYNC PPP from Matjaz Godec. */
-+ /* skb->protocol = htons(ETH_P_IP); */
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_send: "
-+ "...done, calling dev_queue_xmit() or ip_fragment().\n");
-+ IP_SEND(ixs->skb, ixs->physdev);
-+#endif /* NET_21 */
-+ ixs->stats->tx_packets++;
-+
-+ ixs->skb = NULL;
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+void
-+ipsec_tunnel_cleanup(struct ipsec_xmit_state*ixs)
-+{
-+#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
-+ netif_wake_queue(ixs->dev);
-+#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
-+ ixs->dev->tbusy = 0;
-+#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
-+ if(ixs->saved_header) {
-+ kfree(ixs->saved_header);
-+ }
-+ if(ixs->skb) {
-+ dev_kfree_skb(ixs->skb, FREE_WRITE);
-+ }
-+ if(ixs->oskb) {
-+ dev_kfree_skb(ixs->oskb, FREE_WRITE);
-+ }
-+ if (ixs->ips.ips_ident_s.data) {
-+ kfree(ixs->ips.ips_ident_s.data);
-+ }
-+ if (ixs->ips.ips_ident_d.data) {
-+ kfree(ixs->ips.ips_ident_d.data);
-+ }
-+}
-+
-+/*
-+ * This function assumes it is being called from dev_queue_xmit()
-+ * and that skb is filled properly by that function.
-+ */
-+int
-+ipsec_tunnel_start_xmit(struct sk_buff *skb, struct device *dev)
-+{
-+ struct ipsec_xmit_state ixs_mem;
-+ struct ipsec_xmit_state *ixs = &ixs_mem;
-+ enum ipsec_xmit_value stat;
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ ixs->natt_type = 0, ixs->natt_head = 0;
-+ ixs->natt_sport = 0, ixs->natt_dport = 0;
-+#endif
-+
-+ memset((caddr_t)ixs, 0, sizeof(*ixs));
-+ ixs->oskb = NULL;
-+ ixs->saved_header = NULL; /* saved copy of the hard header */
-+ ixs->route = NULL;
-+ memset((caddr_t)&(ixs->ips), 0, sizeof(ixs->ips));
-+ ixs->dev = dev;
-+ ixs->skb = skb;
-+
-+ stat = ipsec_xmit_sanity_check_dev(ixs);
-+ if(stat != IPSEC_XMIT_OK) {
-+ goto cleanup;
-+ }
-+
-+ stat = ipsec_xmit_sanity_check_skb(ixs);
-+ if(stat != IPSEC_XMIT_OK) {
-+ goto cleanup;
-+ }
-+
-+ stat = ipsec_tunnel_strip_hard_header(ixs);
-+ if(stat != IPSEC_XMIT_OK) {
-+ goto cleanup;
-+ }
-+
-+ stat = ipsec_tunnel_SAlookup(ixs);
-+ if(stat != IPSEC_XMIT_OK) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_tunnel_start_xmit: SAlookup failed: %d\n",
-+ stat);
-+ goto cleanup;
-+ }
-+
-+ ixs->innersrc = ixs->iph->saddr;
-+ /* start encapsulation loop here XXX */
-+ do {
-+ stat = ipsec_xmit_encap_bundle(ixs);
-+ if(stat != IPSEC_XMIT_OK) {
-+ if(stat == IPSEC_XMIT_PASS) {
-+ goto bypass;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_tunnel_start_xmit: encap_bundle failed: %d\n",
-+ stat);
-+ goto cleanup;
-+ }
-+
-+ ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
-+ ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
-+ ixs->matcher.sen_proto = ixs->iph->protocol;
-+ ipsec_extract_ports(ixs->iph, &ixs->matcher);
-+
-+ spin_lock(&eroute_lock);
-+ ixs->eroute = ipsec_findroute(&ixs->matcher);
-+ if(ixs->eroute) {
-+ ixs->outgoing_said = ixs->eroute->er_said;
-+ ixs->eroute_pid = ixs->eroute->er_pid;
-+ ixs->eroute->er_count++;
-+ ixs->eroute->er_lasttime = jiffies/HZ;
-+ }
-+ spin_unlock(&eroute_lock);
-+
-+ KLIPS_PRINT((debug_tunnel & DB_TN_XMIT) &&
-+ /* ((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc)) */
-+ (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
-+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
-+ ixs->eroute,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "We are recursing here.\n");
-+
-+ } while(/*((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc))*/
-+ (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
-+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
-+ ixs->eroute);
-+
-+ stat = ipsec_tunnel_restore_hard_header(ixs);
-+ if(stat != IPSEC_XMIT_OK) {
-+ goto cleanup;
-+ }
-+
-+ bypass:
-+ stat = ipsec_tunnel_send(ixs);
-+
-+ cleanup:
-+ ipsec_tunnel_cleanup(ixs);
-+
-+ return 0;
-+}
-+
-+DEBUG_NO_STATIC struct net_device_stats *
-+ipsec_tunnel_get_stats(struct device *dev)
-+{
-+ return &(((struct ipsecpriv *)(dev->priv))->mystats);
-+}
-+
-+/*
-+ * Revectored calls.
-+ * For each of these calls, a field exists in our private structure.
-+ */
-+
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_hard_header(struct sk_buff *skb, struct device *dev,
-+ unsigned short type, void *daddr, void *saddr, unsigned len)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+ struct device *tmp;
-+ int ret;
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(skb == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_hard_header: "
-+ "no skb...\n");
-+ return -ENODATA;
-+ }
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_hard_header: "
-+ "no device...\n");
-+ return -ENODEV;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_hard_header: "
-+ "skb->dev=%s dev=%s.\n",
-+ skb->dev ? skb->dev->name : "NULL",
-+ dev->name);
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_hard_header: "
-+ "no private space associated with dev=%s\n",
-+ dev->name ? dev->name : "NULL");
-+ return -ENODEV;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_hard_header: "
-+ "no physical device associated with dev=%s\n",
-+ dev->name ? dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+ /* check if we have to send a IPv6 packet. It might be a Router
-+ Solicitation, where the building of the packet happens in
-+ reverse order:
-+ 1. ll hdr,
-+ 2. IPv6 hdr,
-+ 3. ICMPv6 hdr
-+ -> skb->nh.raw is still uninitialized when this function is
-+ called!! If this is no IPv6 packet, we can print debugging
-+ messages, otherwise we skip all debugging messages and just
-+ build the ll header */
-+ if(type != ETH_P_IPV6) {
-+ /* execute this only, if we don't have to build the
-+ header for a IPv6 packet */
-+ if(!prv->hard_header) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_hard_header: "
-+ "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
-+ saddr,
-+ daddr,
-+ len,
-+ type,
-+ dev->name);
-+#ifdef NET_21
-+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->nh.iph->saddr),
-+ (__u32)ntohl(skb->nh.iph->daddr) );
-+#else /* NET_21 */
-+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->ip_hdr->saddr),
-+ (__u32)ntohl(skb->ip_hdr->daddr) );
-+#endif /* NET_21 */
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+#define da ((struct device *)(prv->dev))->dev_addr
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_hard_header: "
-+ "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
-+ saddr,
-+ daddr,
-+ len,
-+ type,
-+ dev->name,
-+ prv->dev->name,
-+ da[0], da[1], da[2], da[3], da[4], da[5]);
-+#ifdef NET_21
-+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->nh.iph->saddr),
-+ (__u32)ntohl(skb->nh.iph->daddr) );
-+#else /* NET_21 */
-+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->ip_hdr->saddr),
-+ (__u32)ntohl(skb->ip_hdr->daddr) );
-+#endif /* NET_21 */
-+ } else {
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_hard_header: "
-+ "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
-+ }
-+ tmp = skb->dev;
-+ skb->dev = prv->dev;
-+ ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
-+ skb->dev = tmp;
-+ return ret;
-+}
-+
-+DEBUG_NO_STATIC int
-+#ifdef NET_21
-+ipsec_tunnel_rebuild_header(struct sk_buff *skb)
-+#else /* NET_21 */
-+ipsec_tunnel_rebuild_header(void *buff, struct device *dev,
-+ unsigned long raddr, struct sk_buff *skb)
-+#endif /* NET_21 */
-+{
-+ struct ipsecpriv *prv = skb->dev->priv;
-+ struct device *tmp;
-+ int ret;
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(skb->dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_rebuild_header: "
-+ "no device...");
-+ return -ENODEV;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_rebuild_header: "
-+ "no private space associated with dev=%s",
-+ skb->dev->name ? skb->dev->name : "NULL");
-+ return -ENODEV;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_rebuild_header: "
-+ "no physical device associated with dev=%s",
-+ skb->dev->name ? skb->dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+ if(!prv->rebuild_header) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_rebuild_header: "
-+ "physical device has been detached, packet dropped skb->dev=%s->NULL ",
-+ skb->dev->name);
-+#ifdef NET_21
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->nh.iph->saddr),
-+ (__u32)ntohl(skb->nh.iph->daddr) );
-+#else /* NET_21 */
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->ip_hdr->saddr),
-+ (__u32)ntohl(skb->ip_hdr->daddr) );
-+#endif /* NET_21 */
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel: "
-+ "Revectored rebuild_header dev=%s->%s ",
-+ skb->dev->name, prv->dev->name);
-+#ifdef NET_21
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->nh.iph->saddr),
-+ (__u32)ntohl(skb->nh.iph->daddr) );
-+#else /* NET_21 */
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->ip_hdr->saddr),
-+ (__u32)ntohl(skb->ip_hdr->daddr) );
-+#endif /* NET_21 */
-+ tmp = skb->dev;
-+ skb->dev = prv->dev;
-+
-+#ifdef NET_21
-+ ret = prv->rebuild_header(skb);
-+#else /* NET_21 */
-+ ret = prv->rebuild_header(buff, prv->dev, raddr, skb);
-+#endif /* NET_21 */
-+ skb->dev = tmp;
-+ return ret;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_set_mac_address(struct device *dev, void *addr)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_set_mac_address: "
-+ "no device...");
-+ return -ENODEV;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_set_mac_address: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return -ENODEV;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_set_mac_address: "
-+ "no physical device associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+ if(!prv->set_mac_address) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_set_mac_address: "
-+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
-+ dev->name);
-+ return -ENODEV;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_set_mac_address: "
-+ "Revectored dev=%s->%s addr=0p%p\n",
-+ dev->name, prv->dev->name, addr);
-+ return prv->set_mac_address(prv->dev, addr);
-+
-+}
-+
-+#ifndef NET_21
-+DEBUG_NO_STATIC void
-+ipsec_tunnel_cache_bind(struct hh_cache **hhp, struct device *dev,
-+ unsigned short htype, __u32 daddr)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_bind: "
-+ "no device...");
-+ return;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_bind: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_bind: "
-+ "no physical device associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return;
-+ }
-+
-+ if(!prv->header_cache_bind) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_bind: "
-+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
-+ dev->name);
-+ stats->tx_dropped++;
-+ return;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_bind: "
-+ "Revectored \n");
-+ prv->header_cache_bind(hhp, prv->dev, htype, daddr);
-+ return;
-+}
-+#endif /* !NET_21 */
-+
-+
-+DEBUG_NO_STATIC void
-+ipsec_tunnel_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_update: "
-+ "no device...");
-+ return;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_update: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_update: "
-+ "no physical device associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return;
-+ }
-+
-+ if(!prv->header_cache_update) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_update: "
-+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
-+ dev->name);
-+ return;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel: "
-+ "Revectored cache_update\n");
-+ prv->header_cache_update(hh, prv->dev, haddr);
-+ return;
-+}
-+
-+#ifdef NET_21
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_neigh_setup(struct neighbour *n)
-+{
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_neigh_setup:\n");
-+
-+ if (n->nud_state == NUD_NONE) {
-+ n->ops = &arp_broken_ops;
-+ n->output = n->ops->output;
-+ }
-+ return 0;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_neigh_setup_dev(struct device *dev, struct neigh_parms *p)
-+{
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_neigh_setup_dev: "
-+ "setting up %s\n",
-+ dev ? dev->name : "NULL");
-+
-+ if (p->tbl->family == AF_INET) {
-+ p->neigh_setup = ipsec_tunnel_neigh_setup;
-+ p->ucast_probes = 0;
-+ p->mcast_probes = 0;
-+ }
-+ return 0;
-+}
-+#endif /* NET_21 */
-+
-+/*
-+ * We call the attach routine to attach another device.
-+ */
-+
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_attach(struct device *dev, struct device *physdev)
-+{
-+ int i;
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_attach: "
-+ "no device...");
-+ return -ENODEV;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_attach: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return -ENODATA;
-+ }
-+
-+ prv->dev = physdev;
-+ prv->hard_start_xmit = physdev->hard_start_xmit;
-+ prv->get_stats = physdev->get_stats;
-+
-+ if (physdev->hard_header) {
-+ prv->hard_header = physdev->hard_header;
-+ dev->hard_header = ipsec_tunnel_hard_header;
-+ } else
-+ dev->hard_header = NULL;
-+
-+ if (physdev->rebuild_header) {
-+ prv->rebuild_header = physdev->rebuild_header;
-+ dev->rebuild_header = ipsec_tunnel_rebuild_header;
-+ } else
-+ dev->rebuild_header = NULL;
-+
-+ if (physdev->set_mac_address) {
-+ prv->set_mac_address = physdev->set_mac_address;
-+ dev->set_mac_address = ipsec_tunnel_set_mac_address;
-+ } else
-+ dev->set_mac_address = NULL;
-+
-+#ifndef NET_21
-+ if (physdev->header_cache_bind) {
-+ prv->header_cache_bind = physdev->header_cache_bind;
-+ dev->header_cache_bind = ipsec_tunnel_cache_bind;
-+ } else
-+ dev->header_cache_bind = NULL;
-+#endif /* !NET_21 */
-+
-+ if (physdev->header_cache_update) {
-+ prv->header_cache_update = physdev->header_cache_update;
-+ dev->header_cache_update = ipsec_tunnel_cache_update;
-+ } else
-+ dev->header_cache_update = NULL;
-+
-+ dev->hard_header_len = physdev->hard_header_len;
-+
-+#ifdef NET_21
-+/* prv->neigh_setup = physdev->neigh_setup; */
-+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
-+#endif /* NET_21 */
-+ dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
-+ prv->mtu = physdev->mtu;
-+
-+#ifdef PHYSDEV_TYPE
-+ dev->type = physdev->type; /* ARPHRD_TUNNEL; */
-+#endif /* PHYSDEV_TYPE */
-+
-+ dev->addr_len = physdev->addr_len;
-+ for (i=0; i<dev->addr_len; i++) {
-+ dev->dev_addr[i] = physdev->dev_addr[i];
-+ }
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(debug_tunnel & DB_TN_INIT) {
-+ printk(KERN_INFO "klips_debug:ipsec_tunnel_attach: "
-+ "physical device %s being attached has HW address: %2x",
-+ physdev->name, physdev->dev_addr[0]);
-+ for (i=1; i < physdev->addr_len; i++) {
-+ printk(":%02x", physdev->dev_addr[i]);
-+ }
-+ printk("\n");
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ return 0;
-+}
-+
-+/*
-+ * We call the detach routine to detach the ipsec tunnel from another device.
-+ */
-+
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_detach(struct device *dev)
-+{
-+ int i;
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_detach: "
-+ "no device...");
-+ return -ENODEV;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_detach: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return -ENODATA;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_detach: "
-+ "physical device %s being detached from virtual device %s\n",
-+ prv->dev ? prv->dev->name : "NULL",
-+ dev->name);
-+
-+ ipsec_dev_put(prv->dev);
-+ prv->dev = NULL;
-+ prv->hard_start_xmit = NULL;
-+ prv->get_stats = NULL;
-+
-+ prv->hard_header = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->hard_header = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+ prv->rebuild_header = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->rebuild_header = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+ prv->set_mac_address = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->set_mac_address = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+#ifndef NET_21
-+ prv->header_cache_bind = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->header_cache_bind = NULL;
-+#endif /* DETACH_AND_DOWN */
-+#endif /* !NET_21 */
-+
-+ prv->header_cache_update = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->header_cache_update = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+#ifdef NET_21
-+/* prv->neigh_setup = NULL; */
-+#ifdef DETACH_AND_DOWN
-+ dev->neigh_setup = NULL;
-+#endif /* DETACH_AND_DOWN */
-+#endif /* NET_21 */
-+ dev->hard_header_len = 0;
-+#ifdef DETACH_AND_DOWN
-+ dev->mtu = 0;
-+#endif /* DETACH_AND_DOWN */
-+ prv->mtu = 0;
-+ for (i=0; i<MAX_ADDR_LEN; i++) {
-+ dev->dev_addr[i] = 0;
-+ }
-+ dev->addr_len = 0;
-+#ifdef PHYSDEV_TYPE
-+ dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */
-+#endif /* PHYSDEV_TYPE */
-+
-+ return 0;
-+}
-+
-+/*
-+ * We call the clear routine to detach all ipsec tunnels from other devices.
-+ */
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_clear(void)
-+{
-+ int i;
-+ struct device *ipsecdev = NULL, *prvdev;
-+ struct ipsecpriv *prv;
-+ char name[9];
-+ int ret;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_clear: .\n");
-+
-+ for(i = 0; i < IPSEC_NUM_IF; i++) {
-+ ipsecdev = ipsecdevices[i];
-+ if(ipsecdev != NULL) {
-+ if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
-+ prvdev = (struct device *)(prv->dev);
-+ if(prvdev) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_clear: "
-+ "physical device for device %s is %s\n",
-+ name, prvdev->name);
-+ if((ret = ipsec_tunnel_detach(ipsecdev))) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_clear: "
-+ "error %d detatching device %s from device %s.\n",
-+ ret, name, prvdev->name);
-+ return ret;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ return 0;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
-+{
-+ struct ipsectunnelconf *cf = (struct ipsectunnelconf *)&ifr->ifr_data;
-+ struct ipsecpriv *prv = dev->priv;
-+ struct device *them; /* physical device */
-+#ifdef CONFIG_IP_ALIAS
-+ char *colon;
-+ char realphysname[IFNAMSIZ];
-+#endif /* CONFIG_IP_ALIAS */
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "device not supplied.\n");
-+ return -ENODEV;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "tncfg service call #%d for dev=%s\n",
-+ cmd,
-+ dev->name ? dev->name : "NULL");
-+ switch (cmd) {
-+ /* attach a virtual ipsec? device to a physical device */
-+ case IPSEC_SET_DEV:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "calling ipsec_tunnel_attatch...\n");
-+#ifdef CONFIG_IP_ALIAS
-+ /* If this is an IP alias interface, get its real physical name */
-+ strncpy(realphysname, cf->cf_name, IFNAMSIZ);
-+ realphysname[IFNAMSIZ-1] = 0;
-+ colon = strchr(realphysname, ':');
-+ if (colon) *colon = 0;
-+ them = ipsec_dev_get(realphysname);
-+#else /* CONFIG_IP_ALIAS */
-+ them = ipsec_dev_get(cf->cf_name);
-+#endif /* CONFIG_IP_ALIAS */
-+
-+ if (them == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "physical device %s requested is null\n",
-+ cf->cf_name);
-+ ipsec_dev_put(them);
-+ return -ENXIO;
-+ }
-+
-+#if 0
-+ if (them->flags & IFF_UP) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "physical device %s requested is not up.\n",
-+ cf->cf_name);
-+ ipsec_dev_put(them);
-+ return -ENXIO;
-+ }
-+#endif
-+
-+ if (prv && prv->dev) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "virtual device is already connected to %s.\n",
-+ prv->dev->name ? prv->dev->name : "NULL");
-+ ipsec_dev_put(them);
-+ return -EBUSY;
-+ }
-+ return ipsec_tunnel_attach(dev, them);
-+
-+ case IPSEC_DEL_DEV:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "calling ipsec_tunnel_detatch.\n");
-+ if (! prv->dev) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "physical device not connected.\n");
-+ return -ENODEV;
-+ }
-+ return ipsec_tunnel_detach(dev);
-+
-+ case IPSEC_CLR_DEV:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "calling ipsec_tunnel_clear.\n");
-+ return ipsec_tunnel_clear();
-+
-+ default:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "unknown command %d.\n",
-+ cmd);
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+int
-+ipsec_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
-+{
-+ struct device *dev = ptr;
-+ struct device *ipsec_dev;
-+ struct ipsecpriv *priv;
-+ int i;
-+
-+ if (dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "dev=NULL for event type %ld.\n",
-+ event);
-+ return(NOTIFY_DONE);
-+ }
-+
-+ /* check for loopback devices */
-+ if (dev && (dev->flags & IFF_LOOPBACK)) {
-+ return(NOTIFY_DONE);
-+ }
-+
-+ switch (event) {
-+ case NETDEV_DOWN:
-+ /* look very carefully at the scope of these compiler
-+ directives before changing anything... -- RGB */
-+#ifdef NET_21
-+ case NETDEV_UNREGISTER:
-+ switch (event) {
-+ case NETDEV_DOWN:
-+#endif /* NET_21 */
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_DOWN dev=%s flags=%x\n",
-+ dev->name,
-+ dev->flags);
-+ if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
-+ printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
-+ dev->name);
-+ }
-+#ifdef NET_21
-+ break;
-+ case NETDEV_UNREGISTER:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_UNREGISTER dev=%s flags=%x\n",
-+ dev->name,
-+ dev->flags);
-+ break;
-+ }
-+#endif /* NET_21 */
-+
-+ /* find the attached physical device and detach it. */
-+ for(i = 0; i < IPSEC_NUM_IF; i++) {
-+ ipsec_dev = ipsecdevices[i];
-+
-+ if(ipsec_dev) {
-+ priv = (struct ipsecpriv *)(ipsec_dev->priv);
-+ if(priv) {
-+ ;
-+ if(((struct device *)(priv->dev)) == dev) {
-+ /* dev_close(ipsec_dev); */
-+ /* return */ ipsec_tunnel_detach(ipsec_dev);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "device '%s' has been detached.\n",
-+ ipsec_dev->name);
-+ break;
-+ }
-+ } else {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "device '%s' has no private data space!\n",
-+ ipsec_dev->name);
-+ }
-+ }
-+ }
-+ break;
-+ case NETDEV_UP:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_UP dev=%s\n",
-+ dev->name);
-+ break;
-+#ifdef NET_21
-+ case NETDEV_REBOOT:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_REBOOT dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_CHANGE:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_CHANGE dev=%s flags=%x\n",
-+ dev->name,
-+ dev->flags);
-+ break;
-+ case NETDEV_REGISTER:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_REGISTER dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_CHANGEMTU:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
-+ dev->name,
-+ dev->mtu);
-+ break;
-+ case NETDEV_CHANGEADDR:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_CHANGEADDR dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_GOING_DOWN:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_GOING_DOWN dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_CHANGENAME:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_CHANGENAME dev=%s\n",
-+ dev->name);
-+ break;
-+#endif /* NET_21 */
-+ default:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "event type %ld unrecognised for dev=%s\n",
-+ event,
-+ dev->name);
-+ break;
-+ }
-+ return NOTIFY_DONE;
-+}
-+
-+/*
-+ * Called when an ipsec tunnel device is initialized.
-+ * The ipsec tunnel device structure is passed to us.
-+ */
-+
-+int
-+ipsec_tunnel_init(struct device *dev)
-+{
-+ int i;
-+
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_init: "
-+ "allocating %lu bytes initialising device: %s\n",
-+ (unsigned long) sizeof(struct ipsecpriv),
-+ dev->name ? dev->name : "NULL");
-+
-+ /* Add our tunnel functions to the device */
-+ dev->open = ipsec_tunnel_open;
-+ dev->stop = ipsec_tunnel_close;
-+ dev->hard_start_xmit = ipsec_tunnel_start_xmit;
-+ dev->get_stats = ipsec_tunnel_get_stats;
-+
-+ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
-+ if (dev->priv == NULL)
-+ return -ENOMEM;
-+ memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
-+
-+ for(i = 0; i < sizeof(zeroes); i++) {
-+ ((__u8*)(zeroes))[i] = 0;
-+ }
-+
-+#ifndef NET_21
-+ /* Initialize the tunnel device structure */
-+ for (i = 0; i < DEV_NUMBUFFS; i++)
-+ skb_queue_head_init(&dev->buffs[i]);
-+#endif /* !NET_21 */
-+
-+ dev->set_multicast_list = NULL;
-+ dev->do_ioctl = ipsec_tunnel_ioctl;
-+ dev->hard_header = NULL;
-+ dev->rebuild_header = NULL;
-+ dev->set_mac_address = NULL;
-+#ifndef NET_21
-+ dev->header_cache_bind = NULL;
-+#endif /* !NET_21 */
-+ dev->header_cache_update= NULL;
-+
-+#ifdef NET_21
-+/* prv->neigh_setup = NULL; */
-+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
-+#endif /* NET_21 */
-+ dev->hard_header_len = 0;
-+ dev->mtu = 0;
-+ dev->addr_len = 0;
-+ dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */ /* ARPHRD_ETHER; */
-+ dev->tx_queue_len = 10; /* Small queue */
-+ memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
-+
-+ /* New-style flags. */
-+ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
-+#ifdef NET_21
-+ dev_init_buffers(dev);
-+#else /* NET_21 */
-+ dev->family = AF_INET;
-+ dev->pa_addr = 0;
-+ dev->pa_brdaddr = 0;
-+ dev->pa_mask = 0;
-+ dev->pa_alen = 4;
-+#endif /* NET_21 */
-+
-+ /* We're done. Have I forgotten anything? */
-+ return 0;
-+}
-+
-+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-+/* Module specific interface (but it links with the rest of IPSEC) */
-+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-+
-+int
-+ipsec_tunnel_probe(struct device *dev)
-+{
-+ ipsec_tunnel_init(dev);
-+ return 0;
-+}
-+
-+struct device *ipsecdevices[IPSEC_NUM_IF];
-+
-+int
-+ipsec_tunnel_init_devices(void)
-+{
-+ int i;
-+ char name[IFNAMSIZ];
-+ struct device *dev_ipsec;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_init_devices: "
-+ "creating and registering IPSEC_NUM_IF=%u devices, allocating %lu per device, IFNAMSIZ=%u.\n",
-+ IPSEC_NUM_IF,
-+ (unsigned long) (sizeof(struct device) + IFNAMSIZ),
-+ IFNAMSIZ);
-+
-+ for(i = 0; i < IPSEC_NUM_IF; i++) {
-+ sprintf(name, IPSEC_DEV_FORMAT, i);
-+ dev_ipsec = (struct device*)kmalloc(sizeof(struct device), GFP_KERNEL);
-+ if (dev_ipsec == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_init_devices: "
-+ "failed to allocate memory for device %s, quitting device init.\n",
-+ name);
-+ return -ENOMEM;
-+ }
-+ memset((caddr_t)dev_ipsec, 0, sizeof(struct device));
-+#ifdef NETDEV_23
-+ strncpy(dev_ipsec->name, name, sizeof(dev_ipsec->name));
-+#else /* NETDEV_23 */
-+ dev_ipsec->name = (char*)kmalloc(IFNAMSIZ, GFP_KERNEL);
-+ if (dev_ipsec->name == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_init_devices: "
-+ "failed to allocate memory for device %s name, quitting device init.\n",
-+ name);
-+ return -ENOMEM;
-+ }
-+ memset((caddr_t)dev_ipsec->name, 0, IFNAMSIZ);
-+ strncpy(dev_ipsec->name, name, IFNAMSIZ);
-+#endif /* NETDEV_23 */
-+ dev_ipsec->next = NULL;
-+ dev_ipsec->init = &ipsec_tunnel_probe;
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_init_devices: "
-+ "registering device %s\n",
-+ dev_ipsec->name);
-+
-+ /* reference and hold the device reference */
-+ dev_hold(dev_ipsec);
-+ ipsecdevices[i]=dev_ipsec;
-+
-+ if (register_netdev(dev_ipsec) != 0) {
-+ KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_init_devices: "
-+ "registering device %s failed, quitting device init.\n",
-+ dev_ipsec->name);
-+ return -EIO;
-+ } else {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_init_devices: "
-+ "registering device %s succeeded, continuing...\n",
-+ dev_ipsec->name);
-+ }
-+ }
-+ return 0;
-+}
-+
-+/* void */
-+int
-+ipsec_tunnel_cleanup_devices(void)
-+{
-+ int error = 0;
-+ int i;
-+ char name[32];
-+ struct device *dev_ipsec;
-+
-+ for(i = 0; i < IPSEC_NUM_IF; i++) {
-+ dev_ipsec = ipsecdevices[i];
-+ if(dev_ipsec == NULL) {
-+ continue;
-+ }
-+
-+ /* release reference */
-+ ipsecdevices[i]=NULL;
-+ ipsec_dev_put(dev_ipsec);
-+
-+ KLIPS_PRINT(debug_tunnel, "Unregistering %s (refcnt=%d)\n",
-+ name,
-+ atomic_read(&dev_ipsec->refcnt));
-+ unregister_netdev(dev_ipsec);
-+ KLIPS_PRINT(debug_tunnel, "Unregisted %s\n", name);
-+#ifndef NETDEV_23
-+ kfree(dev_ipsec->name);
-+ dev_ipsec->name=NULL;
-+#endif /* !NETDEV_23 */
-+ kfree(dev_ipsec->priv);
-+ dev_ipsec->priv=NULL;
-+ }
-+ return error;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.220 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.219 2004/02/03 03:13:17 mcr
-+ * minor edits for readability, and error reporting.
-+ *
-+ * Revision 1.218 2004/01/27 20:29:20 mcr
-+ * fix for unregister_netdev() problem for underlying eth0.
-+ *
-+ * Revision 1.217 2003/12/10 01:14:27 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.216 2003/12/04 23:01:17 mcr
-+ * removed ipsec_netlink.h
-+ *
-+ * Revision 1.215 2003/12/04 16:35:16 ken
-+ * Fix for ATM devices where physdev->hard_header_len *is* correct
-+ *
-+ * Revision 1.214 2003/11/25 23:52:37 mcr
-+ * fix typo in patch - ixs-> needed.
-+ *
-+ * Revision 1.213 2003/11/24 18:25:49 mcr
-+ * patch from willy@w.ods.org to fix problems with ATM interfaces.
-+ *
-+ * Revision 1.212 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.211.2.2 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.211.2.1 2003/09/21 13:59:56 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.211 2003/09/10 16:46:30 mcr
-+ * patches for 2.4 backport/2.6 existence.
-+ *
-+ * Revision 1.210 2003/07/31 22:47:16 mcr
-+ * preliminary (untested by FS-team) 2.5 patches.
-+ *
-+ * Revision 1.209 2003/06/22 21:28:43 mcr
-+ * inability to unload module was caused by calls to dev_get
-+ * (ipsec_dev_get), to gather a device from a name. There is
-+ * simply no reason to look the devices up - they should be kept
-+ * in a nice array, ready for use.
-+ *
-+ * Revision 1.208 2003/06/22 21:25:07 mcr
-+ * all staticly counted ipsecXXX device support removed.
-+ *
-+ * Revision 1.207 2003/04/02 20:15:37 mcr
-+ * fix for PR#204 - do not clear connection tracking info if we
-+ * the packet is being sent in the clear.
-+ *
-+ * Revision 1.206 2003/02/12 19:32:51 rgb
-+ * Refactored file to:
-+ * ipsec_xmit.c
-+ * ipsec_xmit.h
-+ * ipsec_mast.c
-+ *
-+ * Revision 1.205 2003/02/06 17:47:00 rgb
-+ *
-+ * Remove unused ipsec_tunnel_lock() and ipsec_tunnel_unlock() code.
-+ * Refactor ipsec_tunnel_start_xmit() further into:
-+ * ipsec_xmit_sanity_check_dev()
-+ * ipsec_xmit_sanity_check_skb()
-+ * ipsec_xmit_strip_hard_header()
-+ * ipsec_xmit_restore_hard_header()
-+ * ipsec_xmit_send()
-+ * ipsec_xmit_cleanup()
-+ * and start a skeletal ipsec_mast_start_xmit() .
-+ *
-+ * Revision 1.204 2003/02/06 06:43:46 rgb
-+ *
-+ * Refactor ipsec_tunnel_start_xmit, bringing out:
-+ * ipsec_xmit_SAlookup
-+ * ipsec_xmit_encap_once
-+ * ipsec_xmit_encap_bundle
-+ *
-+ * Revision 1.203 2003/02/06 02:21:34 rgb
-+ *
-+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
-+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
-+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
-+ *
-+ * Revision 1.202 2003/01/03 07:38:01 rgb
-+ *
-+ * Start to refactor ipsec_tunnel_start_xmit() by putting local variables
-+ * into struct ipsec_xmit_state and renaming a few variables to give more
-+ * unique or searchable names.
-+ *
-+ * Revision 1.201 2003/01/03 00:31:28 rgb
-+ *
-+ * Clean up memset usage, including fixing 2 places where keys were not
-+ * properly wiped.
-+ *
-+ * Revision 1.200 2002/12/06 02:24:02 mcr
-+ * patches for compiling against SUSE 8.1 kernels. Requires
-+ * an additional -DSUSE_LINUX_2_4_19_IS_STUPID.
-+ *
-+ * Revision 1.199 2002/10/12 23:11:53 dhr
-+ *
-+ * [KenB + DHR] more 64-bit cleanup
-+ *
-+ * Revision 1.198 2002/10/05 05:02:58 dhr
-+ *
-+ * C labels go on statements
-+ *
-+ * Revision 1.197 2002/09/20 05:01:50 rgb
-+ * Added compiler directive to switch on IP options and fix IP options bug.
-+ * Make ip->ihl treatment consistent using shifts rather than multiplications.
-+ * Check for large enough packet before accessing udp header for IKE bypass.
-+ * Added memory allocation debugging.
-+ * Fixed potential memory allocation failure-induced oops.
-+ *
-+ * Revision 1.196 2002/07/24 18:44:54 rgb
-+ * Type fiddling to tame ia64 compiler.
-+ *
-+ * Revision 1.195 2002/07/23 03:36:07 rgb
-+ * Fixed 2.2 device initialisation hang.
-+ *
-+ * Revision 1.194 2002/05/27 21:40:34 rgb
-+ * Set unused ipsec devices to ARPHRD_VOID to avoid confusing iproute2.
-+ * Cleaned up intermediate step to dynamic device allocation.
-+ *
-+ * Revision 1.193 2002/05/27 19:31:36 rgb
-+ * Convert to dynamic ipsec device allocation.
-+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
-+ *
-+ * Revision 1.192 2002/05/23 07:14:28 rgb
-+ * Added refcount code.
-+ * Cleaned up %p variants to 0p%p for test suite cleanup.
-+ *
-+ * Revision 1.191 2002/05/14 02:34:37 rgb
-+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
-+ * ipsec_sa or ipsec_sa.
-+ *
-+ * Revision 1.190 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.189 2002/04/24 07:36:32 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_tunnel.c,v
-+ *
-+ * Revision 1.188 2002/04/20 00:12:25 rgb
-+ * Added esp IV CBC attack fix, disabled.
-+ *
-+ * Revision 1.187 2002/03/23 19:55:17 rgb
-+ * Fix for 2.2 local IKE fragmentation blackhole. Still won't work if
-+ * iptraf or another pcap app is running.
-+ *
-+ * Revision 1.186 2002/03/19 03:26:22 rgb
-+ * Applied DHR's tunnel patch to streamline IKE/specialSA processing.
-+ *
-+ * Revision 1.185 2002/02/20 04:13:05 rgb
-+ * Send back ICMP_PKT_FILTERED upon %reject.
-+ *
-+ * Revision 1.184 2002/01/29 17:17:56 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.183 2002/01/29 04:00:53 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.182 2002/01/29 02:13:18 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.181 2002/01/07 20:00:33 rgb
-+ * Added IKE destination port debugging.
-+ *
-+ * Revision 1.180 2001/12/21 21:49:54 rgb
-+ * Fixed bug as a result of moving IKE bypass above %trap/%hold code.
-+ *
-+ * Revision 1.179 2001/12/19 21:08:14 rgb
-+ * Added transport protocol ports to ipsec_print_ip().
-+ * Update eroute info for non-SA targets.
-+ * Added obey DF code disabled.
-+ * Fixed formatting bugs in ipsec_tunnel_hard_header().
-+ *
-+ * Revision 1.178 2001/12/05 09:36:10 rgb
-+ * Moved the UDP/500 IKE check just above the %hold/%trap checks to avoid
-+ * IKE packets being stolen by the %hold (and returned to the sending KMd
-+ * in an ACQUIRE, ironically ;-).
-+ *
-+ * Revision 1.177 2001/11/26 09:23:50 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.170.2.1 2001/09/25 02:28:27 mcr
-+ * struct tdb -> struct ipsec_sa.
-+ * lifetime checks moved to common routines.
-+ * cleaned up includes.
-+ *
-+ * Revision 1.170.2.2 2001/10/22 21:08:01 mcr
-+ * include des.h, removed phony prototypes and fixed calling
-+ * conventions to match real prototypes.
-+ *
-+ * Revision 1.176 2001/11/09 18:32:31 rgb
-+ * Added Hans Schultz' fragmented UDP/500 IKE socket port selector.
-+ *
-+ * Revision 1.175 2001/11/06 20:47:00 rgb
-+ * Added Eric Espie's TRAPSUBNET fix, minus spin-lock-bh dabbling.
-+ *
-+ * Revision 1.174 2001/11/06 19:50:43 rgb
-+ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
-+ * use also by pfkey_v2_parser.c
-+ *
-+ * Revision 1.173 2001/10/29 21:53:44 henry
-+ * tone down the device-down message slightly, until we can make it smarter
-+ *
-+ * Revision 1.172 2001/10/26 04:59:37 rgb
-+ * Added a critical level syslog message if an ipsec device goes down.
-+ *
-+ * Revision 1.171 2001/10/18 04:45:21 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/freeswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.170 2001/09/25 00:09:50 rgb
-+ * Added NetCelo's TRAPSUBNET code to convert a new type TRAPSUBNET into a
-+ * HOLD.
-+ *
-+ * Revision 1.169 2001/09/15 16:24:05 rgb
-+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
-+ *
-+ * Revision 1.168 2001/09/14 16:58:37 rgb
-+ * Added support for storing the first and last packets through a HOLD.
-+ *
-+ * Revision 1.167 2001/09/08 21:13:33 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.166 2001/08/27 19:47:59 rgb
-+ * Clear tdb before usage.
-+ * Added comment: clear IF before calling routing?
-+ *
-+ * Revision 1.165 2001/07/03 01:23:53 rgb
-+ * Send back ICMP iff DF set, !ICMP, offset==0, sysctl_icmp, iph->tot_len >
-+ * emtu, and don't drop.
-+ *
-+ * Revision 1.164 2001/06/14 19:35:10 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.163 2001/06/06 20:28:51 rgb
-+ * Added sanity checks for NULL skbs and devices.
-+ * Added more debugging output to various functions.
-+ * Removed redundant dev->priv argument to ipsec_tunnel_{at,de}tach().
-+ * Renamed ipsec_tunnel_attach() virtual and physical device arguments.
-+ * Corrected neigh_setup() device function assignment.
-+ * Keep valid pointers to ipsec_tunnel_*() on detach.
-+ * Set dev->type to the originally-initiallised value.
-+ *
-+ * Revision 1.162 2001/06/01 07:28:04 rgb
-+ * Added sanity checks for detached devices. Don't down virtual devices
-+ * to prevent packets going out in the clear if the detached device comes
-+ * back up.
-+ *
-+ * Revision 1.161 2001/05/30 08:14:52 rgb
-+ * Removed vestiges of esp-null transforms.
-+ * NetDev Notifier instrumentation to track down disappearing devices.
-+ *
-+ * Revision 1.160 2001/05/29 05:15:12 rgb
-+ * Added SS' PMTU patch which notifies sender if packet doesn't fit
-+ * physical MTU (if it wasn't ICMP) and then drops it.
-+ *
-+ * Revision 1.159 2001/05/27 06:12:12 rgb
-+ * Added structures for pid, packet count and last access time to eroute.
-+ * Added packet count to beginning of /proc/net/ipsec_eroute.
-+ *
-+ * Revision 1.158 2001/05/24 05:39:33 rgb
-+ * Applied source zeroing to 2.2 ip_route_output() call as well to enable
-+ * PASS eroutes for opportunism.
-+ *
-+ * Revision 1.157 2001/05/23 22:35:28 rgb
-+ * 2.4 source override simplification.
-+ *
-+ * Revision 1.156 2001/05/23 21:41:31 rgb
-+ * Added error return code printing on ip_route_output().
-+ *
-+ * Revision 1.155 2001/05/23 05:09:13 rgb
-+ * Fixed incorrect ip_route_output() failure message.
-+ *
-+ * Revision 1.154 2001/05/21 14:53:31 rgb
-+ * Added debug statement for case when ip_route_output() fails, causing
-+ * packet to be dropped, but log looked ok.
-+ *
-+ * Revision 1.153 2001/05/19 02:37:54 rgb
-+ * Fixed missing comment termination.
-+ *
-+ * Revision 1.152 2001/05/19 02:35:50 rgb
-+ * Debug code optimisation for non-debug speed.
-+ * Kernel version compiler define comments.
-+ * 2.2 and 2.4 kernel ip_send device and ip debug output added.
-+ *
-+ * Revision 1.151 2001/05/18 16:17:35 rgb
-+ * Changed reference from "magic" to "shunt" SAs.
-+ *
-+ * Revision 1.150 2001/05/18 16:12:19 rgb
-+ * Changed UDP/500 bypass test from 3 nested ifs to one anded if.
-+ *
-+ * Revision 1.149 2001/05/16 04:39:33 rgb
-+ * Add default == eroute.dest to IKE bypass conditions for magic eroutes.
-+ *
-+ * Revision 1.148 2001/05/05 03:31:41 rgb
-+ * IP frag debugging updates and enhancements.
-+ *
-+ * Revision 1.147 2001/05/03 19:41:40 rgb
-+ * Added SS' skb_cow fix for 2.4.4.
-+ *
-+ * Revision 1.146 2001/04/30 19:28:16 rgb
-+ * Update for 2.4.4. ip_select_ident() now has 3 args.
-+ *
-+ * Revision 1.145 2001/04/23 14:56:10 rgb
-+ * Added spin_lock() check to prevent double-locking for multiple
-+ * transforms and hence kernel lock-ups with SMP kernels.
-+ *
-+ * Revision 1.144 2001/04/21 23:04:45 rgb
-+ * Define out skb->used for 2.4 kernels.
-+ * Check if soft expire has already been sent before sending another to
-+ * prevent ACQUIRE flooding.
-+ *
-+ * Revision 1.143 2001/03/16 07:37:21 rgb
-+ * Added comments to all #endifs.
-+ *
-+ * Revision 1.142 2001/02/28 05:03:27 rgb
-+ * Clean up and rationalise startup messages.
-+ *
-+ * Revision 1.141 2001/02/27 22:24:54 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.140 2001/02/27 06:40:12 rgb
-+ * Fixed TRAP->HOLD eroute byte order.
-+ *
-+ * Revision 1.139 2001/02/26 20:38:59 rgb
-+ * Added compiler defines for 2.4.x-specific code.
-+ *
-+ * Revision 1.138 2001/02/26 19:57:27 rgb
-+ * Implement magic SAs %drop, %reject, %trap, %hold, %pass as part
-+ * of the new SPD and to support opportunistic.
-+ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
-+ *
-+ * Revision 1.137 2001/02/19 22:29:49 rgb
-+ * Fixes for presence of active ipv6 segments which share ipsec physical
-+ * device (gg).
-+ *
-+ * Revision 1.136 2001/01/29 22:30:38 rgb
-+ * Fixed minor acquire debug printing bug.
-+ *
-+ * Revision 1.135 2001/01/29 22:19:45 rgb
-+ * Zero source address for 2.4 bypass route lookup.
-+ *
-+ * Revision 1.134 2001/01/23 20:19:49 rgb
-+ * 2.4 fix to remove removed is_clone member.
-+ *
-+ * Revision 1.133 2000/12/09 22:08:35 rgb
-+ * Fix NET_23 bug, should be NETDEV_23.
-+ *
-+ * Revision 1.132 2000/12/01 06:54:50 rgb
-+ * Fix for new 2.4 IP TTL default variable name.
-+ *
-+ * Revision 1.131 2000/11/09 20:52:15 rgb
-+ * More spinlock shuffling, locking earlier and unlocking later in rcv to
-+ * include ipcomp and prevent races, renaming some tdb variables that got
-+ * forgotten, moving some unlocks to include tdbs and adding a missing
-+ * unlock. Thanks to Svenning for some of these.
-+ *
-+ * Revision 1.130 2000/11/09 20:11:22 rgb
-+ * Minor shuffles to fix non-standard kernel config option selection.
-+ *
-+ * Revision 1.129 2000/11/06 04:32:49 rgb
-+ * Clean up debug printing.
-+ * Copy skb->protocol for all kernel versions.
-+ * Ditched spin_lock_irqsave in favour of spin_lock.
-+ * Disabled TTL decrement, done in ip_forward.
-+ * Added debug printing before pfkey_acquire().
-+ * Fixed printk-deltdbchain-spin_lock races (Svenning).
-+ * Use defaultTTL for 2.1+ kernels.
-+ * Add Svenning's adaptive content compression.
-+ * Fix up debug display arguments.
-+ *
-+ * Revision 1.128 2000/09/28 00:58:57 rgb
-+ * Moved the IKE passthrough check after the eroute lookup so we can pass
-+ * IKE through intermediate tunnels.
-+ *
-+ * Revision 1.127 2000/09/22 17:52:11 rgb
-+ * Fixed misleading ipcomp debug output.
-+ *
-+ * Revision 1.126 2000/09/22 04:22:56 rgb
-+ * Fixed dumb spi->cpi conversion error.
-+ *
-+ * Revision 1.125 2000/09/21 04:34:48 rgb
-+ * A few debug-specific things should be hidden under
-+ * CONFIG_IPSEC_DEBUG.(MB)
-+ * Improved ip_send() error handling.(MB)
-+ *
-+ * Revision 1.124 2000/09/21 03:40:58 rgb
-+ * Added more debugging to try and track down the cpi outward copy problem.
-+ *
-+ * Revision 1.123 2000/09/19 07:08:49 rgb
-+ * Added debugging to outgoing compression report.
-+ *
-+ * Revision 1.122 2000/09/18 19:21:26 henry
-+ * RGB-supplied fix for RH5.2 problem
-+ *
-+ * Revision 1.121 2000/09/17 21:05:09 rgb
-+ * Added tdb to skb_compress call to write in cpi.
-+ *
-+ * Revision 1.120 2000/09/17 16:57:16 rgb
-+ * Added Svenning's patch to remove restriction of ipcomp to innermost
-+ * transform.
-+ *
-+ * Revision 1.119 2000/09/15 11:37:01 rgb
-+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
-+ * IPCOMP zlib deflate code.
-+ *
-+ * Revision 1.118 2000/09/15 04:57:16 rgb
-+ * Moved debug output after sanity check.
-+ * Added tos copy sysctl.
-+ *
-+ * Revision 1.117 2000/09/12 03:22:51 rgb
-+ * Converted ipsec_icmp, no_eroute_pass, opportunistic and #if0 debugs to
-+ * sysctl.
-+ *
-+ * Revision 1.116 2000/09/08 19:18:19 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ * Added outgoing opportunistic hook, ifdef'ed out.
-+ *
-+ * Revision 1.115 2000/08/30 05:27:29 rgb
-+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
-+ * Kill remainder of tdb_xform, tdb_xdata, xformsw.
-+ *
-+ * Revision 1.114 2000/08/28 18:15:46 rgb
-+ * Added MB's nf-debug reset patch.
-+ *
-+ * Revision 1.113 2000/08/27 02:26:40 rgb
-+ * Send all no-eroute-bypass, pluto-bypass and passthrough packets through
-+ * fragmentation machinery for 2.0, 2.2 and 2.4 kernels.
-+ *
-+ * Revision 1.112 2000/08/20 21:37:33 rgb
-+ * Activated pfkey_expire() calls.
-+ * Added a hard/soft expiry parameter to pfkey_expire(). (Momchil)
-+ * Re-arranged the order of soft and hard expiry to conform to RFC2367.
-+ * Clean up references to CONFIG_IPSEC_PFKEYv2.
-+ *
-+ * Revision 1.111 2000/08/01 14:51:51 rgb
-+ * Removed _all_ remaining traces of DES.
-+ *
-+ * Revision 1.110 2000/07/28 14:58:31 rgb
-+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
-+ *
-+ * Revision 1.109 2000/07/28 13:50:54 rgb
-+ * Changed enet_statistics to net_device_stats and added back compatibility
-+ * for pre-2.1.19.
-+ *
-+ * Revision 1.108 2000/05/16 03:03:11 rgb
-+ * Updates for 2.3.99pre8 from MB.
-+ *
-+ * Revision 1.107 2000/05/10 23:08:21 rgb
-+ * Print a debug warning about bogus packets received by the outgoing
-+ * processing machinery only when klipsdebug is not set to none.
-+ * Comment out the device initialisation informational messages.
-+ *
-+ * Revision 1.106 2000/05/10 19:17:14 rgb
-+ * Define an IP_SEND macro, intending to have all packet passthroughs
-+ * use fragmentation. This didn't quite work, but is a step in the
-+ * right direction.
-+ * Added buffer allocation debugging statements.
-+ * Added configure option to shut off no eroute passthrough.
-+ * Only check usetime against soft and hard limits if the tdb has been
-+ * used.
-+ * Cast output of ntohl so that the broken prototype doesn't make our
-+ * compile noisy.
-+ *
-+ * Revision 1.105 2000/03/22 16:15:37 rgb
-+ * Fixed renaming of dev_get (MB).
-+ *
-+ * Revision 1.104 2000/03/16 14:04:15 rgb
-+ * Indented headers for readability.
-+ * Fixed debug scope to enable compilation with debug off.
-+ * Added macros for ip_chk_addr and IS_MYADDR for identifying self.
-+ *
-+ * Revision 1.103 2000/03/16 07:11:07 rgb
-+ * Hardcode PF_KEYv2 support.
-+ * Fixed bug which allowed UDP/500 packet from another machine
-+ * through in the clear.
-+ * Added disabled skb->protocol fix for ISDN/ASYNC PPP from Matjaz Godec.
-+ *
-+ * Revision 1.102 2000/03/14 12:26:59 rgb
-+ * Added skb->nfct support for clearing netfilter conntrack bits (MB).
-+ *
-+ * Revision 1.101 2000/02/14 21:05:22 rgb
-+ * Added MB's netif_queue fix for kernels 2.3.43+.
-+ *
-+ * Revision 1.100 2000/01/26 10:04:57 rgb
-+ * Fixed noisy 2.0 printk arguments.
-+ *
-+ * Revision 1.99 2000/01/21 06:16:25 rgb
-+ * Added sanity checks on skb_push(), skb_pull() to prevent panics.
-+ * Switched to AF_ENCAP macro.
-+ * Shortened debug output per packet and re-arranging debug_tunnel
-+ * bitmap flags, while retaining necessary information to avoid
-+ * trampling the kernel print ring buffer.
-+ * Reformatted recursion switch code.
-+ * Changed all references to tdb_proto to tdb_said.proto for clarity.
-+ *
-+ * Revision 1.98 2000/01/13 08:09:31 rgb
-+ * Shuffled debug_tunnel switches to focus output.
-+ * Fixed outgoing recursion bug, limiting to recursing only if the remote
-+ * SG changes and if it is valid, ie. not passthrough.
-+ * Clarified a number of debug messages.
-+ *
-+ * Revision 1.97 2000/01/10 16:37:16 rgb
-+ * MB support for new ip_select_ident() upon disappearance of
-+ * ip_id_count in 2.3.36+.
-+ *
-+ * Revision 1.96 1999/12/31 14:59:08 rgb
-+ * MB fix to use new skb_copy_expand in kernel 2.3.35.
-+ *
-+ * Revision 1.95 1999/12/29 21:15:44 rgb
-+ * Fix tncfg to aliased device bug.
-+ *
-+ * Revision 1.94 1999/12/22 04:26:06 rgb
-+ * Converted all 'static' functions to 'DEBUG_NO_STATIC' to enable
-+ * debugging by providing external labels to all functions with debugging
-+ * turned on.
-+ *
-+ * Revision 1.93 1999/12/13 13:30:14 rgb
-+ * Changed MTU reports and HW address reporting back to debug only.
-+ *
-+ * Revision 1.92 1999/12/07 18:57:56 rgb
-+ * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled.
-+ *
-+ * Revision 1.91 1999/12/01 22:15:36 rgb
-+ * Add checks for LARVAL and DEAD SAs.
-+ * Change state of SA from MATURE to DYING when a soft lifetime is
-+ * reached and print debug warning.
-+ *
-+ * Revision 1.90 1999/11/23 23:04:04 rgb
-+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
-+ * Sort out pfkey and freeswan headers, putting them in a library path.
-+ *
-+ * Revision 1.89 1999/11/18 18:50:59 rgb
-+ * Changed all device registrations for static linking to
-+ * dynamic to reduce the number and size of patches.
-+ *
-+ * Revision 1.88 1999/11/18 04:09:19 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ *
-+ * Revision 1.87 1999/11/17 15:53:40 rgb
-+ * Changed all occurrences of #include "../../../lib/freeswan.h"
-+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
-+ * klips/net/ipsec/Makefile.
-+ *
-+ * Revision 1.86 1999/10/16 18:25:37 rgb
-+ * Moved SA lifetime expiry checks before packet processing.
-+ * Expire SA on replay counter rollover.
-+ *
-+ * Revision 1.85 1999/10/16 04:24:31 rgb
-+ * Add stats for time since last packet.
-+ *
-+ * Revision 1.84 1999/10/16 00:30:47 rgb
-+ * Added SA lifetime counting.
-+ *
-+ * Revision 1.83 1999/10/15 22:15:57 rgb
-+ * Clean out cruft.
-+ * Add debugging.
-+ *
-+ * Revision 1.82 1999/10/08 18:26:19 rgb
-+ * Fix 2.0.3x outgoing fragmented packet memory leak.
-+ *
-+ * Revision 1.81 1999/10/05 02:38:54 rgb
-+ * Lower the default mtu of virtual devices to 16260.
-+ *
-+ * Revision 1.80 1999/10/03 18:56:41 rgb
-+ * Spinlock support for 2.3.xx.
-+ * Don't forget to undo spinlocks on error!
-+ * Check for valid eroute before copying the structure.
-+ *
-+ * Revision 1.79 1999/10/01 15:44:53 rgb
-+ * Move spinlock header include to 2.1> scope.
-+ *
-+ * Revision 1.78 1999/10/01 00:02:43 rgb
-+ * Added tdb structure locking.
-+ * Added eroute structure locking.
-+ *
-+ * Revision 1.77 1999/09/30 02:52:29 rgb
-+ * Add Marc Boucher's Copy-On-Write code (same as ipsec_rcv.c).
-+ *
-+ * Revision 1.76 1999/09/25 19:31:27 rgb
-+ * Refine MSS hack to affect SYN, but not SYN+ACK packets.
-+ *
-+ * Revision 1.75 1999/09/24 22:52:38 rgb
-+ * Fix two things broken in 2.0.38 by trying to fix network notifiers.
-+ *
-+ * Revision 1.74 1999/09/24 00:30:37 rgb
-+ * Add test for changed source as well as destination to check for
-+ * recursion.
-+ *
-+ * Revision 1.73 1999/09/23 20:52:24 rgb
-+ * Add James Morris' MSS hack patch, disabled.
-+ *
-+ * Revision 1.72 1999/09/23 20:22:40 rgb
-+ * Enable, tidy and fix network notifier code.
-+ *
-+ * Revision 1.71 1999/09/23 18:09:05 rgb
-+ * Clean up 2.2.x fragmenting traces.
-+ * Disable dev->type switching, forcing ARPHRD_TUNNEL.
-+ *
-+ * Revision 1.70 1999/09/22 14:14:24 rgb
-+ * Add sanity checks for revectored calls to prevent calling a downed I/F.
-+ *
-+ * Revision 1.69 1999/09/21 15:00:57 rgb
-+ * Add Marc Boucher's packet size check.
-+ * Flesh out network device notifier code.
-+ *
-+ * Revision 1.68 1999/09/18 11:39:57 rgb
-+ * Start to add (disabled) netdevice notifier code.
-+ *
-+ * Revision 1.67 1999/09/17 23:44:40 rgb
-+ * Add a comment warning potential code hackers to stay away from mac.raw.
-+ *
-+ * Revision 1.66 1999/09/17 18:04:02 rgb
-+ * Add fix for unpredictable hard_header_len for ISDN folks (thanks MB).
-+ * Ditch TTL decrement in 2.2 (MB).
-+ *
-+ * Revision 1.65 1999/09/15 23:15:35 henry
-+ * Marc Boucher's PPP fixes
-+ *
-+ * Revision 1.64 1999/09/07 13:40:53 rgb
-+ * Ditch unreliable references to skb->mac.raw.
-+ *
-+ * Revision 1.63 1999/08/28 11:33:09 rgb
-+ * Check for null skb->mac pointer.
-+ *
-+ * Revision 1.62 1999/08/28 02:02:30 rgb
-+ * Add Marc Boucher's fix for properly dealing with skb->sk.
-+ *
-+ * Revision 1.61 1999/08/27 05:23:05 rgb
-+ * Clean up skb->data/raw/nh/h manipulation.
-+ * Add Marc Boucher's mods to aid tcpdump.
-+ * Add sanity checks to skb->raw/nh/h pointer copies in skb_copy_expand.
-+ * Re-order hard_header stripping -- might be able to remove it...
-+ *
-+ * Revision 1.60 1999/08/26 20:01:02 rgb
-+ * Tidy up compiler directives and macros.
-+ * Re-enable ICMP for tunnels where inner_dst != outer_dst.
-+ * Remove unnecessary skb->dev = physdev assignment affecting 2.2.x.
-+ *
-+ * Revision 1.59 1999/08/25 15:44:41 rgb
-+ * Clean up from 2.2.x instrumenting for compilation under 2.0.36.
-+ *
-+ * Revision 1.58 1999/08/25 15:00:54 rgb
-+ * Add dst cache code for 2.2.xx.
-+ * Add sanity check for skb packet header pointers.
-+ * Add/modify debugging instrumentation to *_start_xmit, *_hard_header and
-+ * *_rebuild_header.
-+ * Add neigh_* cache code.
-+ * Change dev->type back to ARPHRD_TUNNEL.
-+ *
-+ * Revision 1.57 1999/08/17 21:50:23 rgb
-+ * Fixed minor debug output bugs.
-+ * Regrouped error recovery exit code.
-+ * Added compiler directives to remove unwanted code and symbols.
-+ * Shut off ICMP messages: to be refined to only send ICMP to remote systems.
-+ * Add debugging code for output function addresses.
-+ * Fix minor bug in (possibly unused) header_cache_bind function.
-+ * Add device neighbour caching code.
-+ * Change dev->type from ARPHRD_TUNNEL to physdev->type.
-+ *
-+ * Revision 1.56 1999/08/03 17:22:56 rgb
-+ * Debug output clarification using KERN_* macros. Other inactive changes
-+ * added.
-+ *
-+ * Revision 1.55 1999/08/03 16:58:46 rgb
-+ * Fix skb_copy_expand size bug. Was getting incorrect size.
-+ *
-+ * Revision 1.54 1999/07/14 19:32:38 rgb
-+ * Fix oversize packet crash and ssh stalling in 2.2.x kernels.
-+ *
-+ * Revision 1.53 1999/06/10 15:44:02 rgb
-+ * Minor reformatting and clean-up.
-+ *
-+ * Revision 1.52 1999/05/09 03:25:36 rgb
-+ * Fix bug introduced by 2.2 quick-and-dirty patch.
-+ *
-+ * Revision 1.51 1999/05/08 21:24:59 rgb
-+ * Add casting to silence the 2.2.x compile.
-+ *
-+ * Revision 1.50 1999/05/05 22:02:32 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.49 1999/04/29 15:18:52 rgb
-+ * Change gettdb parameter to a pointer to reduce stack loading and
-+ * facilitate parameter sanity checking.
-+ * Fix undetected bug that might have tried to access a null pointer.
-+ * Eliminate unnessessary usage of tdb_xform member to further switch
-+ * away from the transform switch to the algorithm switch.
-+ * Add return values to init and cleanup functions.
-+ *
-+ * Revision 1.48 1999/04/16 15:38:00 rgb
-+ * Minor rearrangement of freeing code to avoid memory leaks with impossible or
-+ * rare situations.
-+ *
-+ * Revision 1.47 1999/04/15 15:37:25 rgb
-+ * Forward check changes from POST1_00 branch.
-+ *
-+ * Revision 1.32.2.4 1999/04/13 21:00:18 rgb
-+ * Ditch 'things I wish I had known before...'.
-+ *
-+ * Revision 1.32.2.3 1999/04/13 20:34:38 rgb
-+ * Free skb after fragmentation.
-+ * Use stats more effectively.
-+ * Add I/F to mtu notch-down reporting.
-+ *
-+ * Revision 1.32.2.2 1999/04/02 04:26:14 rgb
-+ * Backcheck from HEAD, pre1.0.
-+ *
-+ * Revision 1.46 1999/04/11 00:29:00 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.45 1999/04/07 15:42:01 rgb
-+ * Fix mtu/ping bug AGAIN!
-+ *
-+ * Revision 1.44 1999/04/06 04:54:27 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.43 1999/04/04 03:57:07 rgb
-+ * ip_fragment() doesn't free the supplied skb. Freed.
-+ *
-+ * Revision 1.42 1999/04/01 23:27:15 rgb
-+ * Preload size of virtual mtu.
-+ *
-+ * Revision 1.41 1999/04/01 09:31:23 rgb
-+ * Invert meaning of ICMP PMTUD config option and clarify.
-+ * Code clean-up.
-+ *
-+ * Revision 1.40 1999/04/01 04:37:17 rgb
-+ * SSH stalling bug fix.
-+ *
-+ * Revision 1.39 1999/03/31 23:44:28 rgb
-+ * Don't send ICMP on DF and frag_off.
-+ *
-+ * Revision 1.38 1999/03/31 15:20:10 rgb
-+ * Quiet down debugging.
-+ *
-+ * Revision 1.37 1999/03/31 08:30:31 rgb
-+ * Add switch to shut off ICMP PMTUD packets.
-+ *
-+ * Revision 1.36 1999/03/31 05:44:47 rgb
-+ * Keep PMTU reduction private.
-+ *
-+ * Revision 1.35 1999/03/27 15:13:02 rgb
-+ * PMTU/fragmentation bug fix.
-+ *
-+ * Revision 1.34 1999/03/17 21:19:26 rgb
-+ * Fix kmalloc nonatomic bug.
-+ *
-+ * Revision 1.33 1999/03/17 15:38:42 rgb
-+ * Code clean-up.
-+ * ESP_NULL IV bug fix.
-+ *
-+ * Revision 1.32 1999/03/01 20:44:25 rgb
-+ * Code clean-up.
-+ * Memory leak bug fix.
-+ *
-+ * Revision 1.31 1999/02/27 00:02:09 rgb
-+ * Tune to report the MTU reduction once, rather than after every recursion
-+ * through the encapsulating code, preventing tcp stream stalling.
-+ *
-+ * Revision 1.30 1999/02/24 20:21:01 rgb
-+ * Reformat debug printk's.
-+ * Fix recursive encapsulation, dynamic MTU bugs and add debugging code.
-+ * Clean-up.
-+ *
-+ * Revision 1.29 1999/02/22 17:08:14 rgb
-+ * Fix recursive encapsulation code.
-+ *
-+ * Revision 1.28 1999/02/19 18:27:02 rgb
-+ * Improve DF, fragmentation and PMTU behaviour and add dynamic MTU discovery.
-+ *
-+ * Revision 1.27 1999/02/17 16:51:37 rgb
-+ * Clean out unused cruft.
-+ * Temporarily tone down volume of debug output.
-+ * Temporarily shut off fragment rejection.
-+ * Disabled temporary failed recursive encapsulation loop.
-+ *
-+ * Revision 1.26 1999/02/12 21:21:26 rgb
-+ * Move KLIPS_PRINT to ipsec_netlink.h for accessibility.
-+ *
-+ * Revision 1.25 1999/02/11 19:38:27 rgb
-+ * More clean-up.
-+ * Add sanity checking for skb_copy_expand() to prevent kernel panics on
-+ * skb_put() values out of range.
-+ * Fix head/tailroom calculation causing skb_put() out-of-range values.
-+ * Fix return values to prevent 'nonatomic alloc_skb' warnings.
-+ * Allocate new skb iff needed.
-+ * Added more debug statements.
-+ * Make headroom depend on structure, not hard-coded values.
-+ *
-+ * Revision 1.24 1999/02/10 23:20:33 rgb
-+ * Shut up annoying 'statement has no effect' compiler warnings with
-+ * debugging compiled out.
-+ *
-+ * Revision 1.23 1999/02/10 22:36:30 rgb
-+ * Clean-up obsolete, unused and messy code.
-+ * Converted most IPSEC_DEBUG statements to KLIPS_PRINT macros.
-+ * Rename ipsec_tunnel_do_xmit to ipsec_tunnel_start_xmit and eliminated
-+ * original ipsec_tunnel_start_xmit.
-+ * Send all packet with different inner and outer destinations directly to
-+ * the attached physical device, rather than back through ip_forward,
-+ * preventing disappearing routes problems.
-+ * Do sanity checking before investing too much CPU in allocating new
-+ * structures.
-+ * Fail on IP header options: We cannot process them yet.
-+ * Add some helpful comments.
-+ * Use virtual device for parameters instead of physical device.
-+ *
-+ * Revision 1.22 1999/02/10 03:03:02 rgb
-+ * Duh. Fixed the TTL bug: forgot to update the checksum.
-+ *
-+ * Revision 1.21 1999/02/09 23:17:53 rgb
-+ * Add structure members to ipsec_print_ip debug function.
-+ * Temporarily fix TTL bug preventing tunnel mode from functioning.
-+ *
-+ * Revision 1.20 1999/02/09 00:14:25 rgb
-+ * Add KLIPSPRINT macro. (Not used yet, though.)
-+ * Delete old ip_tunnel code (BADCODE).
-+ * Decrement TTL in outgoing packet.
-+ * Set TTL on new IPIP_TUNNEL to default, not existing packet TTL.
-+ * Delete ethernet only feature and fix hard-coded hard_header_len.
-+ *
-+ * Revision 1.19 1999/01/29 17:56:22 rgb
-+ * 64-bit re-fix submitted by Peter Onion.
-+ *
-+ * Revision 1.18 1999/01/28 22:43:24 rgb
-+ * Fixed bug in ipsec_print_ip that caused an OOPS, found by P.Onion.
-+ *
-+ * Revision 1.17 1999/01/26 02:08:16 rgb
-+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
-+ * Removed dead code.
-+ *
-+ * Revision 1.16 1999/01/22 06:25:26 rgb
-+ * Cruft clean-out.
-+ * Added algorithm switch code.
-+ * 64-bit clean-up.
-+ * Passthrough on IPIP protocol, spi 0x0 fix.
-+ * Enhanced debugging.
-+ *
-+ * Revision 1.15 1998/12/01 13:22:04 rgb
-+ * Added support for debug printing of version info.
-+ *
-+ * Revision 1.14 1998/11/30 13:22:55 rgb
-+ * Rationalised all the klips kernel file headers. They are much shorter
-+ * now and won't conflict under RH5.2.
-+ *
-+ * Revision 1.13 1998/11/17 21:13:52 rgb
-+ * Put IKE port bypass debug output in user-switched debug statements.
-+ *
-+ * Revision 1.12 1998/11/13 13:20:25 rgb
-+ * Fixed ntohs bug in udp/500 hole for IKE.
-+ *
-+ * Revision 1.11 1998/11/10 08:01:19 rgb
-+ * Kill tcp/500 hole, keep udp/500 hole.
-+ *
-+ * Revision 1.10 1998/11/09 21:29:26 rgb
-+ * If no eroute is found, discard packet and incr. tx_error.
-+ *
-+ * Revision 1.9 1998/10/31 06:50:00 rgb
-+ * Add tcp/udp/500 bypass.
-+ * Fixed up comments in #endif directives.
-+ *
-+ * Revision 1.8 1998/10/27 00:34:31 rgb
-+ * Reformat debug output of IP headers.
-+ * Newlines added before calls to ipsec_print_ip.
-+ *
-+ * Revision 1.7 1998/10/19 14:44:28 rgb
-+ * Added inclusion of freeswan.h.
-+ * sa_id structure implemented and used: now includes protocol.
-+ *
-+ * Revision 1.6 1998/10/09 04:31:35 rgb
-+ * Added 'klips_debug' prefix to all klips printk debug statements.
-+ *
-+ * Revision 1.5 1998/08/28 03:09:51 rgb
-+ * Prevent kernel log spam with default route through ipsec.
-+ *
-+ * Revision 1.4 1998/08/05 22:23:09 rgb
-+ * Change setdev return code to ENXIO for a non-existant physical device.
-+ *
-+ * Revision 1.3 1998/07/29 20:41:11 rgb
-+ * Add ipsec_tunnel_clear to clear all tunnel attachments.
-+ *
-+ * Revision 1.2 1998/06/25 20:00:33 rgb
-+ * Clean up #endif comments.
-+ * Rename dev_ipsec to dev_ipsec0 for consistency.
-+ * Document ipsec device fields.
-+ * Make ipsec_tunnel_probe visible from rest of kernel for static linking.
-+ * Get debugging report for *every* ipsec device initialisation.
-+ * Comment out redundant code.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:50 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.8 1998/06/14 23:49:40 rgb
-+ * Clarify version reporting on module loading.
-+ *
-+ * Revision 1.7 1998/05/27 23:19:20 rgb
-+ * Added version reporting.
-+ *
-+ * Revision 1.6 1998/05/18 21:56:23 rgb
-+ * Clean up for numerical consistency of output and cleaning up debug code.
-+ *
-+ * Revision 1.5 1998/05/12 02:44:23 rgb
-+ * Clarifying 'no e-route to host' message.
-+ *
-+ * Revision 1.4 1998/04/30 15:34:35 rgb
-+ * Enclosed most remaining debugging statements in #ifdef's to make it quieter.
-+ *
-+ * Revision 1.3 1998/04/21 21:28:54 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.2 1998/04/12 22:03:24 rgb
-+ * Updated ESP-3DES-HMAC-MD5-96,
-+ * ESP-DES-HMAC-MD5-96,
-+ * AH-HMAC-MD5-96,
-+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
-+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
-+ *
-+ * Fixed eroute references in /proc/net/ipsec*.
-+ *
-+ * Started to patch module unloading memory leaks in ipsec_netlink and
-+ * radij tree unloading.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:12 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.5 1997/06/03 04:24:48 ji
-+ * Added transport mode.
-+ * Changed the way routing is done.
-+ * Lots of bug fixes.
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * No changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:39:04 ji
-+ * Minor cleanups.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ * Local Variables:
-+ * c-style: linux
-+ * End:
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_xform.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,351 @@
-+/*
-+ * Common routines for IPSEC transformations.
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "freeswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <linux/random.h> /* get_random_bytes() */
-+#include <freeswan.h>
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+#endif
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "freeswan/radij.h"
-+#include "freeswan/ipsec_encap.h"
-+#include "freeswan/ipsec_radij.h"
-+#include "freeswan/ipsec_xform.h"
-+#include "freeswan/ipsec_ipe4.h"
-+#include "freeswan/ipsec_ah.h"
-+#include "freeswan/ipsec_esp.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_xform = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#ifdef SPINLOCK
-+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
-+#else /* SPINLOCK */
-+spinlock_t tdb_lock;
-+#endif /* SPINLOCK */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.63 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.62.30.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.62 2002/05/14 02:34:21 rgb
-+ * Delete stale code.
-+ *
-+ * Revision 1.61 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.60 2002/04/24 07:36:33 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_xform.c,v
-+ *
-+ * Revision 1.59 2002/03/29 15:01:36 rgb
-+ * Delete decommissioned code.
-+ *
-+ * Revision 1.58 2002/01/29 17:17:57 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.57 2002/01/29 04:00:53 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.56 2001/11/27 05:17:22 mcr
-+ * turn off the worst of the per-packet debugging.
-+ *
-+ * Revision 1.55 2001/11/26 09:23:50 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.54 2001/10/18 04:45:21 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/freeswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.53 2001/09/08 21:13:34 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.52 2001/06/14 19:35:11 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.51 2001/05/30 08:14:03 rgb
-+ * Removed vestiges of esp-null transforms.
-+ *
-+ * Revision 1.50 2001/05/03 19:43:18 rgb
-+ * Initialise error return variable.
-+ * Update SENDERR macro.
-+ * Fix sign of error return code for ipsec_tdbcleanup().
-+ * Use more appropriate return code for ipsec_tdbwipe().
-+ *
-+ * Revision 1.49 2001/04/19 18:56:17 rgb
-+ * Fixed tdb table locking comments.
-+ *
-+ * Revision 1.48 2001/02/27 22:24:55 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.47 2000/11/06 04:32:08 rgb
-+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
-+ *
-+ * Revision 1.46 2000/09/20 16:21:57 rgb
-+ * Cleaned up ident string alloc/free.
-+ *
-+ * Revision 1.45 2000/09/08 19:16:51 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
-+ *
-+ * Revision 1.44 2000/08/30 05:29:04 rgb
-+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
-+ *
-+ * Revision 1.43 2000/08/18 21:30:41 rgb
-+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
-+ *
-+ * Revision 1.42 2000/08/01 14:51:51 rgb
-+ * Removed _all_ remaining traces of DES.
-+ *
-+ * Revision 1.41 2000/07/28 14:58:31 rgb
-+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
-+ *
-+ * Revision 1.40 2000/06/28 05:50:11 rgb
-+ * Actually set iv_bits.
-+ *
-+ * Revision 1.39 2000/05/10 23:11:09 rgb
-+ * Added netlink debugging output.
-+ * Added a cast to quiet down the ntohl bug.
-+ *
-+ * Revision 1.38 2000/05/10 19:18:42 rgb
-+ * Cast output of ntohl so that the broken prototype doesn't make our
-+ * compile noisy.
-+ *
-+ * Revision 1.37 2000/03/16 14:04:59 rgb
-+ * Hardwired CONFIG_IPSEC_PFKEYv2 on.
-+ *
-+ * Revision 1.36 2000/01/26 10:11:28 rgb
-+ * Fixed spacing in error text causing run-in words.
-+ *
-+ * Revision 1.35 2000/01/21 06:17:16 rgb
-+ * Tidied up compiler directive indentation for readability.
-+ * Added ictx,octx vars for simplification.(kravietz)
-+ * Added macros for HMAC padding magic numbers.(kravietz)
-+ * Fixed missing key length reporting bug.
-+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
-+ *
-+ * Revision 1.34 1999/12/08 00:04:19 rgb
-+ * Fixed SA direction overwriting bug for netlink users.
-+ *
-+ * Revision 1.33 1999/12/01 22:16:44 rgb
-+ * Minor formatting changes in ESP MD5 initialisation.
-+ *
-+ * Revision 1.32 1999/11/25 09:06:36 rgb
-+ * Fixed error return messages, should be returning negative numbers.
-+ * Implemented SENDERR macro for propagating error codes.
-+ * Added debug message and separate error code for algorithms not compiled
-+ * in.
-+ *
-+ * Revision 1.31 1999/11/23 23:06:26 rgb
-+ * Sort out pfkey and freeswan headers, putting them in a library path.
-+ *
-+ * Revision 1.30 1999/11/18 04:09:20 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ *
-+ * Revision 1.29 1999/11/17 15:53:40 rgb
-+ * Changed all occurrences of #include "../../../lib/freeswan.h"
-+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
-+ * klips/net/ipsec/Makefile.
-+ *
-+ * Revision 1.28 1999/10/18 20:04:01 rgb
-+ * Clean-out unused cruft.
-+ *
-+ * Revision 1.27 1999/10/03 19:01:03 rgb
-+ * Spinlock support for 2.3.xx and 2.0.xx kernels.
-+ *
-+ * Revision 1.26 1999/10/01 16:22:24 rgb
-+ * Switch from assignment init. to functional init. of spinlocks.
-+ *
-+ * Revision 1.25 1999/10/01 15:44:54 rgb
-+ * Move spinlock header include to 2.1> scope.
-+ *
-+ * Revision 1.24 1999/10/01 00:03:46 rgb
-+ * Added tdb structure locking.
-+ * Minor formatting changes.
-+ * Add function to initialize tdb hash table.
-+ *
-+ * Revision 1.23 1999/05/25 22:42:12 rgb
-+ * Add deltdbchain() debugging.
-+ *
-+ * Revision 1.22 1999/05/25 21:24:31 rgb
-+ * Add debugging statements to deltdbchain().
-+ *
-+ * Revision 1.21 1999/05/25 03:51:48 rgb
-+ * Refix error return code.
-+ *
-+ * Revision 1.20 1999/05/25 03:34:07 rgb
-+ * Fix error return for flush.
-+ *
-+ * Revision 1.19 1999/05/09 03:25:37 rgb
-+ * Fix bug introduced by 2.2 quick-and-dirty patch.
-+ *
-+ * Revision 1.18 1999/05/05 22:02:32 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.17 1999/04/29 15:20:16 rgb
-+ * Change gettdb parameter to a pointer to reduce stack loading and
-+ * facilitate parameter sanity checking.
-+ * Add sanity checking for null pointer arguments.
-+ * Add debugging instrumentation.
-+ * Add function deltdbchain() which will take care of unlinking,
-+ * zeroing and deleting a chain of tdbs.
-+ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
-+ * tdbwipe now actually zeroes the tdb as well as any of its pointed
-+ * structures.
-+ *
-+ * Revision 1.16 1999/04/16 15:36:29 rgb
-+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
-+ *
-+ * Revision 1.15 1999/04/11 00:29:01 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.14 1999/04/06 04:54:28 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.13 1999/02/19 18:23:01 rgb
-+ * Nix debug off compile warning.
-+ *
-+ * Revision 1.12 1999/02/17 16:52:16 rgb
-+ * Consolidate satoa()s for space and speed efficiency.
-+ * Convert DEBUG_IPSEC to KLIPS_PRINT
-+ * Clean out unused cruft.
-+ * Ditch NET_IPIP dependancy.
-+ * Loop for 3des key setting.
-+ *
-+ * Revision 1.11 1999/01/26 02:09:05 rgb
-+ * Remove ah/esp/IPIP switching on include files.
-+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
-+ * Removed dead code.
-+ * Clean up debug code when switched off.
-+ * Remove references to INET_GET_PROTOCOL.
-+ * Added code exclusion macros to reduce code from unused algorithms.
-+ *
-+ * Revision 1.10 1999/01/22 06:28:55 rgb
-+ * Cruft clean-out.
-+ * Put random IV generation in kernel.
-+ * Added algorithm switch code.
-+ * Enhanced debugging.
-+ * 64-bit clean-up.
-+ *
-+ * Revision 1.9 1998/11/30 13:22:55 rgb
-+ * Rationalised all the klips kernel file headers. They are much shorter
-+ * now and won't conflict under RH5.2.
-+ *
-+ * Revision 1.8 1998/11/25 04:59:06 rgb
-+ * Add conditionals for no IPIP tunnel code.
-+ * Delete commented out code.
-+ *
-+ * Revision 1.7 1998/10/31 06:50:41 rgb
-+ * Convert xform ASCII names to no spaces.
-+ * Fixed up comments in #endif directives.
-+ *
-+ * Revision 1.6 1998/10/19 14:44:28 rgb
-+ * Added inclusion of freeswan.h.
-+ * sa_id structure implemented and used: now includes protocol.
-+ *
-+ * Revision 1.5 1998/10/09 04:32:19 rgb
-+ * Added 'klips_debug' prefix to all klips printk debug statements.
-+ *
-+ * Revision 1.4 1998/08/12 00:11:31 rgb
-+ * Added new xform functions to the xform table.
-+ * Fixed minor debug output spelling error.
-+ *
-+ * Revision 1.3 1998/07/09 17:45:31 rgb
-+ * Clarify algorithm not available message.
-+ *
-+ * Revision 1.2 1998/06/23 03:00:51 rgb
-+ * Check for presence of IPIP protocol if it is setup one way (we don't
-+ * know what has been set up the other way and can only assume it will be
-+ * symmetrical with the exception of keys).
-+ *
-+ * Revision 1.1 1998/06/18 21:27:51 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.3 1998/06/11 05:54:59 rgb
-+ * Added transform version string pointer to xformsw initialisations.
-+ *
-+ * Revision 1.2 1998/04/21 21:28:57 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:13 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.5 1997/06/03 04:24:48 ji
-+ * Added ESP-3DES-MD5-96
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * Added new transforms.
-+ *
-+ * Revision 0.3 1996/11/20 14:39:04 ji
-+ * Minor cleanups.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_xmit.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1869 @@
-+/*
-+ * IPSEC Transmit code.
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998-2003 Richard Guy Briggs.
-+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipsec_xmit_c_version[] = "RCSID $Id$";
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/config.h> /* for CONFIG_IP_FORWARD */
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/tcp.h> /* struct tcphdr */
-+#include <linux/udp.h> /* struct udphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef NET_21
-+# define MSS_HACK_ /* experimental */
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# include <net/dst.h>
-+# define proto_priv cb
-+#endif /* NET_21 */
-+#include <asm/checksum.h>
-+#include <net/icmp.h> /* icmp_send() */
-+#include <net/ip.h>
-+#ifdef NETDEV_23
-+# include <linux/netfilter_ipv4.h>
-+#endif /* NETDEV_23 */
-+
-+#include <linux/if_arp.h>
-+#ifdef MSS_HACK
-+# include <net/tcp.h> /* TCP options */
-+#endif /* MSS_HACK */
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_life.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_eroute.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xmit.h"
-+#include "openswan/ipsec_sa.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_ipe4.h"
-+#include "openswan/ipsec_ah.h"
-+#include "openswan/ipsec_esp.h"
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+#include "openswan/ipcomp.h"
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+#include "openswan/ipsec_alg.h"
-+
-+
-+/*
-+ * Stupid kernel API differences in APIs. Not only do some
-+ * kernels not have ip_select_ident, but some have differing APIs,
-+ * and SuSE has one with one parameter, but no way of checking to
-+ * see what is really what.
-+ */
-+
-+#ifdef SUSE_LINUX_2_4_19_IS_STUPID
-+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
-+#else
-+
-+/* simplest case, nothing */
-+#if !defined(IP_SELECT_IDENT)
-+#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
-+#endif
-+
-+/* kernels > 2.3.37-ish */
-+#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
-+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
-+#endif
-+
-+/* kernels > 2.4.2 */
-+#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
-+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
-+#endif
-+
-+#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
-+
-+
-+static __u32 zeroes[64];
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int sysctl_ipsec_debug_verbose = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+int ipsec_xmit_trap_count = 0;
-+int ipsec_xmit_trap_sendcount = 0;
-+
-+int sysctl_ipsec_icmp = 0;
-+int sysctl_ipsec_tos = 0;
-+
-+#ifdef CONFIG_IPSEC_DEBUG_
-+DEBUG_NO_STATIC void
-+dmp(char *s, caddr_t bb, int len)
-+{
-+ int i;
-+ unsigned char *b = bb;
-+
-+ if (debug_tunnel) {
-+ printk(KERN_INFO "klips_debug:ipsec_tunnel_:dmp: "
-+ "at %s, len=%d:",
-+ s,
-+ len);
-+ for (i=0; i < len; i++) {
-+ if(!(i%16)){
-+ printk("\nklips_debug: ");
-+ }
-+ printk(" %02x", *b++);
-+ }
-+ printk("\n");
-+ }
-+}
-+#else /* CONFIG_IPSEC_DEBUG */
-+#define dmp(_x, _y, _z)
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#ifndef SKB_COPY_EXPAND
-+/*
-+ * This is mostly skbuff.c:skb_copy().
-+ */
-+struct sk_buff *
-+skb_copy_expand(struct sk_buff *skb, int headroom, int tailroom, int priority)
-+{
-+ struct sk_buff *n;
-+ unsigned long offset;
-+
-+ /*
-+ * Do sanity checking
-+ */
-+ if((headroom < 0) || (tailroom < 0) || ((headroom+tailroom) < 0)) {
-+ printk(KERN_WARNING
-+ "klips_error:skb_copy_expand: "
-+ "Illegal negative head,tailroom %d,%d\n",
-+ headroom,
-+ tailroom);
-+ return NULL;
-+ }
-+ /*
-+ * Allocate the copy buffer
-+ */
-+
-+#ifndef NET_21
-+ IS_SKB(skb);
-+#endif /* !NET_21 */
-+
-+
-+ n=alloc_skb(skb->end - skb->head + headroom + tailroom, priority);
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:skb_copy_expand: "
-+ "allocating %d bytes, head=0p%p data=0p%p tail=0p%p end=0p%p end-head=%d tail-data=%d\n",
-+ skb->end - skb->head + headroom + tailroom,
-+ skb->head,
-+ skb->data,
-+ skb->tail,
-+ skb->end,
-+ skb->end - skb->head,
-+ skb->tail - skb->data);
-+
-+ if(n==NULL)
-+ return NULL;
-+
-+ /*
-+ * Shift between the two data areas in bytes
-+ */
-+
-+ /* Set the data pointer */
-+ skb_reserve(n,skb->data-skb->head+headroom);
-+ /* Set the tail pointer and length */
-+ if(skb_tailroom(n) < skb->len) {
-+ printk(KERN_WARNING "klips_error:skb_copy_expand: "
-+ "tried to skb_put %ld, %d available. This should never happen, please report.\n",
-+ (unsigned long int)skb->len,
-+ skb_tailroom(n));
-+ ipsec_kfree_skb(n);
-+ return NULL;
-+ }
-+ skb_put(n,skb->len);
-+
-+ offset=n->head + headroom - skb->head;
-+
-+ /* Copy the bytes */
-+ memcpy(n->head + headroom, skb->head,skb->end-skb->head);
-+#ifdef NET_21
-+ n->csum=skb->csum;
-+ n->priority=skb->priority;
-+ n->dst=dst_clone(skb->dst);
-+ if(skb->nh.raw)
-+ n->nh.raw=skb->nh.raw+offset;
-+#ifndef NETDEV_23
-+ n->is_clone=0;
-+#endif /* NETDEV_23 */
-+ atomic_set(&n->users, 1);
-+ n->destructor = NULL;
-+ n->security=skb->security;
-+#else /* NET_21 */
-+ n->link3=NULL;
-+ n->when=skb->when;
-+ if(skb->ip_hdr)
-+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
-+ n->saddr=skb->saddr;
-+ n->daddr=skb->daddr;
-+ n->raddr=skb->raddr;
-+ n->seq=skb->seq;
-+ n->end_seq=skb->end_seq;
-+ n->ack_seq=skb->ack_seq;
-+ n->acked=skb->acked;
-+ n->free=1;
-+ n->arp=skb->arp;
-+ n->tries=0;
-+ n->lock=0;
-+ n->users=0;
-+#endif /* NET_21 */
-+ n->protocol=skb->protocol;
-+ n->list=NULL;
-+ n->sk=NULL;
-+ n->dev=skb->dev;
-+ if(skb->h.raw)
-+ n->h.raw=skb->h.raw+offset;
-+ if(skb->mac.raw)
-+ n->mac.raw=skb->mac.raw+offset;
-+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
-+#ifndef NETDEV_23
-+ n->used=skb->used;
-+#endif /* !NETDEV_23 */
-+ n->pkt_type=skb->pkt_type;
-+ n->stamp=skb->stamp;
-+
-+#ifndef NET_21
-+ IS_SKB(n);
-+#endif /* !NET_21 */
-+ return n;
-+}
-+#endif /* !SKB_COPY_EXPAND */
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+void
-+ipsec_print_ip(struct iphdr *ip)
-+{
-+ char buf[ADDRTOA_BUF];
-+
-+ printk(KERN_INFO "klips_debug: IP:");
-+ printk(" ihl:%d", ip->ihl << 2);
-+ printk(" ver:%d", ip->version);
-+ printk(" tos:%d", ip->tos);
-+ printk(" tlen:%d", ntohs(ip->tot_len));
-+ printk(" id:%d", ntohs(ip->id));
-+ printk(" %s%s%sfrag_off:%d",
-+ ip->frag_off & __constant_htons(IP_CE) ? "CE " : "",
-+ ip->frag_off & __constant_htons(IP_DF) ? "DF " : "",
-+ ip->frag_off & __constant_htons(IP_MF) ? "MF " : "",
-+ (ntohs(ip->frag_off) & IP_OFFSET) << 3);
-+ printk(" ttl:%d", ip->ttl);
-+ printk(" proto:%d", ip->protocol);
-+ if(ip->protocol == IPPROTO_UDP)
-+ printk(" (UDP)");
-+ if(ip->protocol == IPPROTO_TCP)
-+ printk(" (TCP)");
-+ if(ip->protocol == IPPROTO_ICMP)
-+ printk(" (ICMP)");
-+ printk(" chk:%d", ntohs(ip->check));
-+ addrtoa(*((struct in_addr*)(&ip->saddr)), 0, buf, sizeof(buf));
-+ printk(" saddr:%s", buf);
-+ if(ip->protocol == IPPROTO_UDP)
-+ printk(":%d",
-+ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
-+ if(ip->protocol == IPPROTO_TCP)
-+ printk(":%d",
-+ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
-+ addrtoa(*((struct in_addr*)(&ip->daddr)), 0, buf, sizeof(buf));
-+ printk(" daddr:%s", buf);
-+ if(ip->protocol == IPPROTO_UDP)
-+ printk(":%d",
-+ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
-+ if(ip->protocol == IPPROTO_TCP)
-+ printk(":%d",
-+ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
-+ if(ip->protocol == IPPROTO_ICMP)
-+ printk(" type:code=%d:%d",
-+ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->type,
-+ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->code);
-+ printk("\n");
-+
-+ if(sysctl_ipsec_debug_verbose) {
-+ __u8 *c;
-+ int i;
-+
-+ c = ((__u8*)ip) + ip->ihl*4;
-+ for(i = 0; i < ntohs(ip->tot_len) - ip->ihl*4; i++ /*, c++*/) {
-+ if(!(i % 16)) {
-+ printk(KERN_INFO
-+ "klips_debug: @%03x:",
-+ i);
-+ }
-+ printk(" %02x", /***/c[i]);
-+ if(!((i + 1) % 16)) {
-+ printk("\n");
-+ }
-+ }
-+ if(i % 16) {
-+ printk("\n");
-+ }
-+ }
-+}
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#ifdef MSS_HACK
-+/*
-+ * Issues:
-+ * 1) Fragments arriving in the tunnel should probably be rejected.
-+ * 2) How does this affect syncookies, mss_cache, dst cache ?
-+ * 3) Path MTU discovery handling needs to be reviewed. For example,
-+ * if we receive an ICMP 'packet too big' message from an intermediate
-+ * router specifying it's next hop MTU, our stack may process this and
-+ * adjust the MSS without taking our AH/ESP overheads into account.
-+ */
-+
-+
-+/*
-+ * Recaclulate checksum using differences between changed datum,
-+ * borrowed from netfilter.
-+ */
-+DEBUG_NO_STATIC u_int16_t
-+ipsec_fast_csum(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
-+{
-+ u_int32_t diffs[] = { oldvalinv, newval };
-+ return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
-+ oldcheck^0xFFFF));
-+}
-+
-+/*
-+ * Determine effective MSS.
-+ *
-+ * Note that we assume that there is always an MSS option for our own
-+ * SYN segments, which is mentioned in tcp_syn_build_options(), kernel 2.2.x.
-+ * This could change, and we should probably parse TCP options instead.
-+ *
-+ */
-+DEBUG_NO_STATIC u_int8_t
-+ipsec_adjust_mss(struct sk_buff *skb, struct tcphdr *tcph, u_int16_t mtu)
-+{
-+ u_int16_t oldmss, newmss;
-+ u_int32_t *mssp;
-+ struct sock *sk = skb->sk;
-+
-+ newmss = tcp_sync_mss(sk, mtu);
-+ printk(KERN_INFO "klips: setting mss to %u\n", newmss);
-+ mssp = (u_int32_t *)tcph + sizeof(struct tcphdr) / sizeof(u_int32_t);
-+ oldmss = ntohl(*mssp) & 0x0000FFFF;
-+ *mssp = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | newmss);
-+ tcph->check = ipsec_fast_csum(htons(~oldmss),
-+ htons(newmss), tcph->check);
-+ return 1;
-+}
-+#endif /* MSS_HACK */
-+
-+/*
-+ * Sanity checks
-+ */
-+enum ipsec_xmit_value
-+ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs)
-+{
-+
-+ if (ixs->dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_error:ipsec_xmit_sanity_check_dev: "
-+ "No device associated with skb!\n" );
-+ return IPSEC_XMIT_NODEV;
-+ }
-+
-+ ixs->prv = ixs->dev->priv;
-+ if (ixs->prv == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_error:ipsec_xmit_sanity_check_dev: "
-+ "Device has no private structure!\n" );
-+ return IPSEC_XMIT_NOPRIVDEV;
-+ }
-+
-+ ixs->physdev = ixs->prv->dev;
-+ if (ixs->physdev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_error:ipsec_xmit_sanity_check_dev: "
-+ "Device is not attached to physical device!\n" );
-+ return IPSEC_XMIT_NOPHYSDEV;
-+ }
-+
-+ ixs->physmtu = ixs->physdev->mtu;
-+
-+ ixs->stats = (struct net_device_stats *) &(ixs->prv->mystats);
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs)
-+{
-+ /*
-+ * Return if there is nothing to do. (Does this ever happen?) XXX
-+ */
-+ if (ixs->skb == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_error:ipsec_xmit_sanity_check_skb: "
-+ "Nothing to do!\n" );
-+ return IPSEC_XMIT_NOSKB;
-+ }
-+#ifdef NET_21
-+ /* if skb was cloned (most likely due to a packet sniffer such as
-+ tcpdump being momentarily attached to the interface), make
-+ a copy of our own to modify */
-+ if(skb_cloned(ixs->skb)) {
-+ if
-+#ifdef SKB_COW_NEW
-+ (skb_cow(ixs->skb, skb_headroom(ixs->skb)) != 0)
-+#else /* SKB_COW_NEW */
-+ ((ixs->skb = skb_cow(ixs->skb, skb_headroom(ixs->skb))) == NULL)
-+#endif /* SKB_COW_NEW */
-+ {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_error:ipsec_xmit_sanity_check_skb: "
-+ "skb_cow failed to allocate buffer, dropping.\n" );
-+ ixs->stats->tx_dropped++;
-+ return IPSEC_XMIT_ERRSKBALLOC;
-+ }
-+ }
-+#endif /* NET_21 */
-+
-+#ifdef NET_21
-+ ixs->iph = ixs->skb->nh.iph;
-+#else /* NET_21 */
-+ ixs->iph = ixs->skb->ip_hdr;
-+#endif /* NET_21 */
-+
-+ /* sanity check for IP version as we can't handle IPv6 right now */
-+ if (ixs->iph->version != 4) {
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_xmit_sanity_check_skb: "
-+ "found IP Version %d but cannot process other IP versions than v4.\n",
-+ ixs->iph->version); /* XXX */
-+ ixs->stats->tx_dropped++;
-+ return IPSEC_XMIT_NOIPV6;
-+ }
-+
-+#if IPSEC_DISALLOW_IPOPTIONS
-+ if ((ixs->iph->ihl << 2) != sizeof (struct iphdr)) {
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_xmit_sanity_check_skb: "
-+ "cannot process IP header options yet. May be mal-formed packet.\n"); /* XXX */
-+ ixs->stats->tx_dropped++;
-+ return IPSEC_XMIT_NOIPOPTIONS;
-+ }
-+#endif /* IPSEC_DISALLOW_IPOPTIONS */
-+
-+#ifndef NET_21
-+ if (ixs->iph->ttl <= 0) {
-+ /* Tell the sender its packet died... */
-+ ICMP_SEND(ixs->skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, ixs->physdev);
-+
-+ KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_xmit_sanity_check_skb: "
-+ "TTL=0, too many hops!\n");
-+ ixs->stats->tx_dropped++;
-+ return IPSEC_XMIT_TTLEXPIRED;
-+ }
-+#endif /* !NET_21 */
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_encap_once(struct ipsec_xmit_state *ixs)
-+{
-+#ifdef CONFIG_IPSEC_ESP
-+ struct esphdr *espp;
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ __u32 iv[ESP_IV_MAXSZ_INT];
-+#endif /* !CONFIG_IPSEC_ENC_3DES */
-+ unsigned char *idat, *pad;
-+ int authlen = 0, padlen = 0, i;
-+#endif /* !CONFIG_IPSEC_ESP */
-+#ifdef CONFIG_IPSEC_AH
-+ struct iphdr ipo;
-+ struct ahhdr *ahp;
-+#endif /* CONFIG_IPSEC_AH */
-+#if defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1)
-+ union {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ MD5_CTX md5;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ SHA1_CTX sha1;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ } tctx;
-+ __u8 hash[AH_AMAX];
-+#endif /* defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1) */
-+ int headroom = 0, tailroom = 0, ilen = 0, len = 0;
-+ unsigned char *dat;
-+ int blocksize = 8; /* XXX: should be inside ixs --jjo */
-+#ifdef CONFIG_IPSEC_ALG
-+ struct ipsec_alg_enc *ixt_e = NULL;
-+ struct ipsec_alg_auth *ixt_a = NULL;
-+#endif /* CONFIG_IPSEC_ALG */
-+
-+ ixs->iphlen = ixs->iph->ihl << 2;
-+ ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
-+ ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, SATOT_BUF);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_OXFS,
-+ "klips_debug:ipsec_xmit_encap_once: "
-+ "calling output for <%s%s%s>, SA:%s\n",
-+ IPS_XFORM_NAME(ixs->ipsp),
-+ ixs->sa_len ? ixs->sa_txt : " (error)");
-+
-+ switch(ixs->ipsp->ips_said.proto) {
-+#ifdef CONFIG_IPSEC_AH
-+ case IPPROTO_AH:
-+ headroom += sizeof(struct ahhdr);
-+ break;
-+#endif /* CONFIG_IPSEC_AH */
-+#ifdef CONFIG_IPSEC_ESP
-+ case IPPROTO_ESP:
-+#ifdef CONFIG_IPSEC_ALG
-+ if ((ixt_e=ixs->ipsp->ips_alg_enc)) {
-+ blocksize = ixt_e->ixt_blocksize;
-+ headroom += ESP_HEADER_LEN + ixt_e->ixt_ivlen/8;
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ixs->ipsp->ips_encalg) {
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+ headroom += sizeof(struct esphdr);
-+ break;
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_BADALG;
-+ }
-+#ifdef CONFIG_IPSEC_ALG
-+ if ((ixt_a=ixs->ipsp->ips_alg_auth)) {
-+ tailroom += AHHMAC_HASHLEN;
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ixs->ipsp->ips_authalg) {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5:
-+ authlen = AHHMAC_HASHLEN;
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA:
-+ authlen = AHHMAC_HASHLEN;
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ case AH_NONE:
-+ break;
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_BADALG;
-+ }
-+#ifdef CONFIG_IPSEC_ALG
-+ tailroom += blocksize != 1 ?
-+ ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 :
-+ ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
-+#else
-+ tailroom += ((8 - ((ixs->pyldsz + 2 * sizeof(unsigned char)) % 8)) % 8) + 2;
-+#endif /* CONFIG_IPSEC_ALG */
-+ tailroom += authlen;
-+ break;
-+#endif /* !CONFIG_IPSEC_ESP */
-+#ifdef CONFIG_IPSEC_IPIP
-+ case IPPROTO_IPIP:
-+ headroom += sizeof(struct iphdr);
-+ ixs->iphlen = sizeof(struct iphdr);
-+ break;
-+#endif /* !CONFIG_IPSEC_IPIP */
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ case IPPROTO_COMP:
-+ break;
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_BADPROTO;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_once: "
-+ "pushing %d bytes, putting %d, proto %d.\n",
-+ headroom, tailroom, ixs->ipsp->ips_said.proto);
-+ if(skb_headroom(ixs->skb) < headroom) {
-+ printk(KERN_WARNING
-+ "klips_error:ipsec_xmit_encap_once: "
-+ "tried to skb_push headroom=%d, %d available. This should never happen, please report.\n",
-+ headroom, skb_headroom(ixs->skb));
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_PUSHPULLERR;
-+ }
-+ dat = skb_push(ixs->skb, headroom);
-+ ilen = ixs->skb->len - tailroom;
-+ if(skb_tailroom(ixs->skb) < tailroom) {
-+ printk(KERN_WARNING
-+ "klips_error:ipsec_xmit_encap_once: "
-+ "tried to skb_put %d, %d available. This should never happen, please report.\n",
-+ tailroom, skb_tailroom(ixs->skb));
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_PUSHPULLERR;
-+ }
-+ skb_put(ixs->skb, tailroom);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_once: "
-+ "head,tailroom: %d,%d before xform.\n",
-+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
-+ len = ixs->skb->len;
-+ if(len > 0xfff0) {
-+ printk(KERN_WARNING "klips_error:ipsec_xmit_encap_once: "
-+ "tot_len (%d) > 65520. This should never happen, please report.\n",
-+ len);
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_BADLEN;
-+ }
-+ memmove((void *)dat, (void *)(dat + headroom), ixs->iphlen);
-+ ixs->iph = (struct iphdr *)dat;
-+ ixs->iph->tot_len = htons(ixs->skb->len);
-+
-+ switch(ixs->ipsp->ips_said.proto) {
-+#ifdef CONFIG_IPSEC_ESP
-+ case IPPROTO_ESP:
-+ espp = (struct esphdr *)(dat + ixs->iphlen);
-+ espp->esp_spi = ixs->ipsp->ips_said.spi;
-+ espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if (!ixt_e)
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ixs->ipsp->ips_encalg) {
-+#if defined(CONFIG_IPSEC_ENC_3DES)
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ iv[0] = *((__u32*)&(espp->esp_iv) ) =
-+ ((__u32*)(ixs->ipsp->ips_iv))[0];
-+ iv[1] = *((__u32*)&(espp->esp_iv) + 1) =
-+ ((__u32*)(ixs->ipsp->ips_iv))[1];
-+ break;
-+#endif /* defined(CONFIG_IPSEC_ENC_3DES) */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_BADALG;
-+ }
-+
-+ idat = dat + ixs->iphlen + headroom;
-+ ilen = len - (ixs->iphlen + headroom + authlen);
-+
-+ /* Self-describing padding */
-+ pad = &dat[len - tailroom];
-+ padlen = tailroom - 2 - authlen;
-+ for (i = 0; i < padlen; i++) {
-+ pad[i] = i + 1;
-+ }
-+ dat[len - authlen - 2] = padlen;
-+
-+ dat[len - authlen - 1] = ixs->iph->protocol;
-+ ixs->iph->protocol = IPPROTO_ESP;
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ /* Do all operations here:
-+ * copy IV->ESP, encrypt, update ips IV
-+ */
-+ if (ixt_e) {
-+ int ret;
-+ memcpy(espp->esp_iv,
-+ ixs->ipsp->ips_iv,
-+ ixt_e->ixt_ivlen/8);
-+ ret=ipsec_alg_esp_encrypt(ixs->ipsp,
-+ idat, ilen, espp->esp_iv,
-+ IPSEC_ALG_ENCRYPT);
-+ memcpy(ixs->ipsp->ips_iv,
-+ idat + ilen - ixt_e->ixt_ivlen/8,
-+ ixt_e->ixt_ivlen/8);
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ixs->ipsp->ips_encalg) {
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+ des_ede3_cbc_encrypt((des_cblock *)idat,
-+ (des_cblock *)idat,
-+ ilen,
-+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[0].ks,
-+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[1].ks,
-+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[2].ks,
-+ (des_cblock *)iv, 1);
-+ break;
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_BADALG;
-+ }
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if (!ixt_e)
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ixs->ipsp->ips_encalg) {
-+#if defined(CONFIG_IPSEC_ENC_3DES)
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ /* XXX update IV with the last 8 octets of the encryption */
-+#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK
-+ ((__u32*)(ixs->ipsp->ips_iv))[0] =
-+ ((__u32 *)(idat))[(ilen >> 2) - 2];
-+ ((__u32*)(ixs->ipsp->ips_iv))[1] =
-+ ((__u32 *)(idat))[(ilen >> 2) - 1];
-+#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
-+ prng_bytes(&ipsec_prng, (char *)ixs->ipsp->ips_iv, EMT_ESPDES_IV_SZ);
-+#endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
-+ break;
-+#endif /* defined(CONFIG_IPSEC_ENC_3DES) */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_BADALG;
-+ }
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if (ixt_a) {
-+ ipsec_alg_sa_esp_hash(ixs->ipsp,
-+ (caddr_t)espp, len - ixs->iphlen - authlen,
-+ &(dat[len - authlen]), authlen);
-+
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ixs->ipsp->ips_authalg) {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5:
-+ dmp("espp", (char*)espp, len - ixs->iphlen - authlen);
-+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
-+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, (caddr_t)espp, len - ixs->iphlen - authlen);
-+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Final(hash, &tctx.md5);
-+ dmp("ictx hash", (char*)&hash, sizeof(hash));
-+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
-+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, hash, AHMD596_ALEN);
-+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Final(hash, &tctx.md5);
-+ dmp("octx hash", (char*)&hash, sizeof(hash));
-+ memcpy(&(dat[len - authlen]), hash, authlen);
-+
-+ /* paranoid */
-+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
-+ memset((caddr_t)hash, 0, sizeof(*hash));
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA:
-+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
-+ SHA1Update(&tctx.sha1, (caddr_t)espp, len - ixs->iphlen - authlen);
-+ SHA1Final(hash, &tctx.sha1);
-+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
-+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
-+ SHA1Final(hash, &tctx.sha1);
-+ memcpy(&(dat[len - authlen]), hash, authlen);
-+
-+ /* paranoid */
-+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
-+ memset((caddr_t)hash, 0, sizeof(*hash));
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ case AH_NONE:
-+ break;
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_AH_BADALG;
-+ }
-+#ifdef NET_21
-+ ixs->skb->h.raw = (unsigned char*)espp;
-+#endif /* NET_21 */
-+ break;
-+#endif /* !CONFIG_IPSEC_ESP */
-+#ifdef CONFIG_IPSEC_AH
-+ case IPPROTO_AH:
-+ ahp = (struct ahhdr *)(dat + ixs->iphlen);
-+ ahp->ah_spi = ixs->ipsp->ips_said.spi;
-+ ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
-+ ahp->ah_rv = 0;
-+ ahp->ah_nh = ixs->iph->protocol;
-+ ahp->ah_hl = (headroom >> 2) - sizeof(__u64)/sizeof(__u32);
-+ ixs->iph->protocol = IPPROTO_AH;
-+ dmp("ahp", (char*)ahp, sizeof(*ahp));
-+
-+ ipo = *ixs->iph;
-+ ipo.tos = 0;
-+ ipo.frag_off = 0;
-+ ipo.ttl = 0;
-+ ipo.check = 0;
-+ dmp("ipo", (char*)&ipo, sizeof(ipo));
-+
-+ switch(ixs->ipsp->ips_authalg) {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5:
-+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
-+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
-+ dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
-+ dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
-+ dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom);
-+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Final(hash, &tctx.md5);
-+ dmp("ictx hash", (char*)&hash, sizeof(hash));
-+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
-+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, hash, AHMD596_ALEN);
-+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Final(hash, &tctx.md5);
-+ dmp("octx hash", (char*)&hash, sizeof(hash));
-+
-+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
-+
-+ /* paranoid */
-+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
-+ memset((caddr_t)hash, 0, sizeof(*hash));
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA:
-+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
-+ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
-+ SHA1Update(&tctx.sha1, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
-+ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
-+ SHA1Update(&tctx.sha1, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom);
-+ SHA1Final(hash, &tctx.sha1);
-+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
-+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
-+ SHA1Final(hash, &tctx.sha1);
-+
-+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
-+
-+ /* paranoid */
-+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
-+ memset((caddr_t)hash, 0, sizeof(*hash));
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_AH_BADALG;
-+ }
-+#ifdef NET_21
-+ ixs->skb->h.raw = (unsigned char*)ahp;
-+#endif /* NET_21 */
-+ break;
-+#endif /* CONFIG_IPSEC_AH */
-+#ifdef CONFIG_IPSEC_IPIP
-+ case IPPROTO_IPIP:
-+ ixs->iph->version = 4;
-+ switch(sysctl_ipsec_tos) {
-+ case 0:
-+#ifdef NET_21
-+ ixs->iph->tos = ixs->skb->nh.iph->tos;
-+#else /* NET_21 */
-+ ixs->iph->tos = ixs->skb->ip_hdr->tos;
-+#endif /* NET_21 */
-+ break;
-+ case 1:
-+ ixs->iph->tos = 0;
-+ break;
-+ default:
-+ break;
-+ }
-+#ifdef NET_21
-+#ifdef NETDEV_23
-+ ixs->iph->ttl = sysctl_ip_default_ttl;
-+#else /* NETDEV_23 */
-+ ixs->iph->ttl = ip_statistics.IpDefaultTTL;
-+#endif /* NETDEV_23 */
-+#else /* NET_21 */
-+ ixs->iph->ttl = 64; /* ip_statistics.IpDefaultTTL; */
-+#endif /* NET_21 */
-+ ixs->iph->frag_off = 0;
-+ ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
-+ ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
-+ ixs->iph->protocol = IPPROTO_IPIP;
-+ ixs->iph->ihl = sizeof(struct iphdr) >> 2;
-+
-+ KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
-+
-+ ixs->newdst = (__u32)ixs->iph->daddr;
-+ ixs->newsrc = (__u32)ixs->iph->saddr;
-+
-+#ifdef NET_21
-+ ixs->skb->h.ipiph = ixs->skb->nh.iph;
-+#endif /* NET_21 */
-+ break;
-+#endif /* !CONFIG_IPSEC_IPIP */
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ case IPPROTO_COMP:
-+ {
-+ unsigned int flags = 0;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
-+
-+ ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
-+
-+#ifdef NET_21
-+ ixs->iph = ixs->skb->nh.iph;
-+#else /* NET_21 */
-+ ixs->iph = ixs->skb->ip_hdr;
-+#endif /* NET_21 */
-+
-+ ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (debug_tunnel & DB_TN_CROUT)
-+ {
-+ if (old_tot_len > ntohs(ixs->iph->tot_len))
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_once: "
-+ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
-+ old_tot_len, ntohs(ixs->iph->tot_len),
-+ ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
-+ ntohl(ixs->ipsp->ips_said.spi),
-+ (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
-+ else
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_once: "
-+ "packet did not compress (flags = %d).\n",
-+ flags);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ }
-+ break;
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_BADPROTO;
-+ }
-+
-+#ifdef NET_21
-+ ixs->skb->nh.raw = ixs->skb->data;
-+#else /* NET_21 */
-+ ixs->skb->ip_hdr = ixs->skb->h.iph = (struct iphdr *) ixs->skb->data;
-+#endif /* NET_21 */
-+ ixs->iph->check = 0;
-+ ixs->iph->check = ip_fast_csum((unsigned char *)ixs->iph, ixs->iph->ihl);
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_once: "
-+ "after <%s%s%s>, SA:%s:\n",
-+ IPS_XFORM_NAME(ixs->ipsp),
-+ ixs->sa_len ? ixs->sa_txt : " (error)");
-+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
-+
-+ ixs->ipsp->ips_life.ipl_bytes.ipl_count += len;
-+ ixs->ipsp->ips_life.ipl_bytes.ipl_last = len;
-+
-+ if(!ixs->ipsp->ips_life.ipl_usetime.ipl_count) {
-+ ixs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
-+ }
-+ ixs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
-+ ixs->ipsp->ips_life.ipl_packets.ipl_count++;
-+
-+ ixs->ipsp = ixs->ipsp->ips_onext;
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+/*
-+ * If the IP packet (iph) is a carrying TCP/UDP, then set the encaps
-+ * source and destination ports to those from the TCP/UDP header.
-+ */
-+void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er)
-+{
-+ struct udphdr *udp;
-+
-+ switch (iph->protocol) {
-+ case IPPROTO_UDP:
-+ case IPPROTO_TCP:
-+ /*
-+ * The ports are at the same offsets in a TCP and UDP
-+ * header so hack it ...
-+ */
-+ udp = (struct udphdr*)(((char*)iph)+(iph->ihl<<2));
-+ er->sen_sport = udp->source;
-+ er->sen_dport = udp->dest;
-+ break;
-+ default:
-+ er->sen_sport = 0;
-+ er->sen_dport = 0;
-+ break;
-+ }
-+}
-+
-+/*
-+ * A TRAP eroute is installed and we want to replace it with a HOLD
-+ * eroute.
-+ */
-+static int create_hold_eroute(struct eroute *origtrap,
-+ struct sk_buff * skb, struct iphdr * iph,
-+ uint32_t eroute_pid)
-+{
-+ struct eroute hold_eroute;
-+ ip_said hold_said;
-+ struct sk_buff *first, *last;
-+ int error;
-+
-+ first = last = NULL;
-+ memset((caddr_t)&hold_eroute, 0, sizeof(hold_eroute));
-+ memset((caddr_t)&hold_said, 0, sizeof(hold_said));
-+
-+ hold_said.proto = IPPROTO_INT;
-+ hold_said.spi = htonl(SPI_HOLD);
-+ hold_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
-+
-+ hold_eroute.er_eaddr.sen_len = sizeof(struct sockaddr_encap);
-+ hold_eroute.er_emask.sen_len = sizeof(struct sockaddr_encap);
-+ hold_eroute.er_eaddr.sen_family = AF_ENCAP;
-+ hold_eroute.er_emask.sen_family = AF_ENCAP;
-+ hold_eroute.er_eaddr.sen_type = SENT_IP4;
-+ hold_eroute.er_emask.sen_type = 255;
-+
-+ hold_eroute.er_eaddr.sen_ip_src.s_addr = iph->saddr;
-+ hold_eroute.er_eaddr.sen_ip_dst.s_addr = iph->daddr;
-+ hold_eroute.er_emask.sen_ip_src.s_addr = INADDR_BROADCAST;
-+ hold_eroute.er_emask.sen_ip_dst.s_addr = INADDR_BROADCAST;
-+ hold_eroute.er_emask.sen_sport = 0;
-+ hold_eroute.er_emask.sen_dport = 0;
-+ hold_eroute.er_pid = eroute_pid;
-+ hold_eroute.er_count = 0;
-+ hold_eroute.er_lasttime = jiffies/HZ;
-+
-+ /*
-+ * if it wasn't captured by a wildcard, then don't record it as
-+ * a wildcard.
-+ */
-+ if(origtrap->er_eaddr.sen_proto != 0) {
-+ hold_eroute.er_eaddr.sen_proto = iph->protocol;
-+
-+ if((iph->protocol == IPPROTO_TCP ||
-+ iph->protocol == IPPROTO_UDP) &&
-+ (origtrap->er_eaddr.sen_sport != 0 ||
-+ origtrap->er_eaddr.sen_dport != 0)) {
-+
-+ if(origtrap->er_eaddr.sen_sport != 0)
-+ hold_eroute.er_emask.sen_sport = ~0;
-+
-+ if(origtrap->er_eaddr.sen_dport != 0)
-+ hold_eroute.er_emask.sen_dport = ~0;
-+
-+ ipsec_extract_ports(iph, &hold_eroute.er_eaddr);
-+ }
-+ }
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (debug_pfkey) {
-+ char buf1[64], buf2[64];
-+ subnettoa(hold_eroute.er_eaddr.sen_ip_src,
-+ hold_eroute.er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(hold_eroute.er_eaddr.sen_ip_dst,
-+ hold_eroute.er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "calling breakeroute and makeroute for %s:%d->%s:%d %d HOLD eroute.\n",
-+ buf1, ntohs(hold_eroute.er_eaddr.sen_sport),
-+ buf2, ntohs(hold_eroute.er_eaddr.sen_dport),
-+ hold_eroute.er_eaddr.sen_proto);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ if (ipsec_breakroute(&(hold_eroute.er_eaddr), &(hold_eroute.er_emask),
-+ &first, &last)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "HOLD breakeroute found nothing.\n");
-+ } else {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "HOLD breakroute deleted %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u %u\n",
-+ NIPQUAD(hold_eroute.er_eaddr.sen_ip_src),
-+ ntohs(hold_eroute.er_eaddr.sen_sport),
-+ NIPQUAD(hold_eroute.er_eaddr.sen_ip_dst),
-+ ntohs(hold_eroute.er_eaddr.sen_dport),
-+ hold_eroute.er_eaddr.sen_proto);
-+ }
-+ if (first != NULL)
-+ kfree_skb(first);
-+ if (last != NULL)
-+ kfree_skb(last);
-+
-+ error = ipsec_makeroute(&(hold_eroute.er_eaddr),
-+ &(hold_eroute.er_emask),
-+ hold_said, eroute_pid, skb, NULL, NULL);
-+ if (error) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "HOLD makeroute returned %d, failed.\n", error);
-+ } else {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "HOLD makeroute call successful.\n");
-+ }
-+ return (error == 0);
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs)
-+{
-+#ifdef CONFIG_IPSEC_ALG
-+ struct ipsec_alg_enc *ixt_e = NULL;
-+ struct ipsec_alg_auth *ixt_a = NULL;
-+ int blocksize = 8;
-+#endif /* CONFIG_IPSEC_ALG */
-+ enum ipsec_xmit_value bundle_stat = IPSEC_XMIT_OK;
-+
-+ ixs->newdst = ixs->orgdst = ixs->iph->daddr;
-+ ixs->newsrc = ixs->orgsrc = ixs->iph->saddr;
-+ ixs->orgedst = ixs->outgoing_said.dst.u.v4.sin_addr.s_addr;
-+ ixs->iphlen = ixs->iph->ihl << 2;
-+ ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
-+ ixs->max_headroom = ixs->max_tailroom = 0;
-+
-+ if (ixs->outgoing_said.proto == IPPROTO_INT) {
-+ switch (ntohl(ixs->outgoing_said.spi)) {
-+ case SPI_DROP:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "shunt SA of DROP or no eroute: dropping.\n");
-+ ixs->stats->tx_dropped++;
-+ break;
-+
-+ case SPI_REJECT:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "shunt SA of REJECT: notifying and dropping.\n");
-+ ICMP_SEND(ixs->skb,
-+ ICMP_DEST_UNREACH,
-+ ICMP_PKT_FILTERED,
-+ 0,
-+ ixs->physdev);
-+ ixs->stats->tx_dropped++;
-+ break;
-+
-+ case SPI_PASS:
-+#ifdef NET_21
-+ ixs->pass = 1;
-+#endif /* NET_21 */
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "PASS: calling dev_queue_xmit\n");
-+ return IPSEC_XMIT_PASS;
-+ goto cleanup;
-+
-+ case SPI_HOLD:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "shunt SA of HOLD: this does not make sense here, dropping.\n");
-+ ixs->stats->tx_dropped++;
-+ break;
-+
-+ case SPI_TRAP:
-+ case SPI_TRAPSUBNET:
-+ {
-+ struct sockaddr_in src, dst;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ char bufsrc[ADDRTOA_BUF], bufdst[ADDRTOA_BUF];
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ /* Signal all listening KMds with a PF_KEY ACQUIRE */
-+
-+ src.sin_family = AF_INET;
-+ dst.sin_family = AF_INET;
-+ src.sin_addr.s_addr = ixs->iph->saddr;
-+ dst.sin_addr.s_addr = ixs->iph->daddr;
-+
-+ ixs->ips.ips_transport_protocol = 0;
-+ src.sin_port = 0;
-+ dst.sin_port = 0;
-+ {
-+ int i;
-+ for(i = 0;
-+ i < sizeof(struct sockaddr_in)
-+ - offsetof(struct sockaddr_in, sin_zero);
-+ i++) {
-+ src.sin_zero[i] = 0;
-+ dst.sin_zero[i] = 0;
-+ }
-+ }
-+
-+ if(ixs->eroute->er_eaddr.sen_proto != 0) {
-+ ixs->ips.ips_transport_protocol = ixs->iph->protocol;
-+
-+ if(ixs->eroute->er_eaddr.sen_sport != 0) {
-+ src.sin_port =
-+ (ixs->iph->protocol == IPPROTO_UDP
-+ ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->source
-+ : (ixs->iph->protocol == IPPROTO_TCP
-+ ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->source
-+ : 0));
-+ }
-+ if(ixs->eroute->er_eaddr.sen_dport != 0) {
-+ dst.sin_port =
-+ (ixs->iph->protocol == IPPROTO_UDP
-+ ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->dest
-+ : (ixs->iph->protocol == IPPROTO_TCP
-+ ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->dest
-+ : 0));
-+ }
-+ }
-+
-+ ixs->ips.ips_addr_s = (struct sockaddr*)(&src);
-+ ixs->ips.ips_addr_d = (struct sockaddr*)(&dst);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "SADB_ACQUIRE sent with src=%s:%d, dst=%s:%d, proto=%d.\n",
-+ addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_addr, 0, bufsrc, sizeof(bufsrc)) <= ADDRTOA_BUF ? bufsrc : "BAD_ADDR",
-+ ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_port),
-+ addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_addr, 0, bufdst, sizeof(bufdst)) <= ADDRTOA_BUF ? bufdst : "BAD_ADDR",
-+ ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_port),
-+ ixs->ips.ips_said.proto);
-+
-+ /* increment count of total traps needed */
-+ ipsec_xmit_trap_count++;
-+
-+ if (pfkey_acquire(&ixs->ips) == 0) {
-+
-+ /* note that we succeeded */
-+ ipsec_xmit_trap_sendcount++;
-+
-+ if (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)) {
-+ /*
-+ * The spinlock is to prevent any other
-+ * process from accessing or deleting
-+ * the eroute while we are using and
-+ * updating it.
-+ */
-+ spin_lock(&eroute_lock);
-+ ixs->eroute = ipsec_findroute(&ixs->matcher);
-+ if(ixs->eroute) {
-+ ixs->eroute->er_said.spi = htonl(SPI_HOLD);
-+ ixs->eroute->er_first = ixs->skb;
-+ ixs->skb = NULL;
-+ }
-+ spin_unlock(&eroute_lock);
-+ } else if (create_hold_eroute(ixs->eroute,
-+ ixs->skb,
-+ ixs->iph,
-+ ixs->eroute_pid)) {
-+ ixs->skb = NULL;
-+ }
-+ /* whether or not the above succeeded, we continue */
-+
-+ }
-+ ixs->stats->tx_dropped++;
-+ }
-+ default:
-+ /* XXX what do we do with an unknown shunt spi? */
-+ break;
-+ } /* switch (ntohl(ixs->outgoing_said.spi)) */
-+ return IPSEC_XMIT_STOLEN;
-+ } /* if (ixs->outgoing_said.proto == IPPROTO_INT) */
-+
-+ /*
-+ The spinlock is to prevent any other process from
-+ accessing or deleting the ipsec_sa hash table or any of the
-+ ipsec_sa s while we are using and updating them.
-+
-+ This is not optimal, but was relatively straightforward
-+ at the time. A better way to do it has been planned for
-+ more than a year, to lock the hash table and put reference
-+ counts on each ipsec_sa instead. This is not likely to happen
-+ in KLIPS1 unless a volunteer contributes it, but will be
-+ designed into KLIPS2.
-+ */
-+ spin_lock(&tdb_lock);
-+
-+ ixs->ipsp = ipsec_sa_getbyid(&ixs->outgoing_said);
-+ ixs->sa_len = satot(&ixs->outgoing_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
-+
-+ if (ixs->ipsp == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "no ipsec_sa for SA%s: outgoing packet with no SA, dropped.\n",
-+ ixs->sa_len ? ixs->sa_txt : " (error)");
-+ ixs->stats->tx_dropped++;
-+ bundle_stat = IPSEC_XMIT_SAIDNOTFOUND;
-+ goto cleanup;
-+ }
-+
-+ ipsec_sa_put(ixs->ipsp); /* incomplete */
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "found ipsec_sa -- SA:<%s%s%s> %s\n",
-+ IPS_XFORM_NAME(ixs->ipsp),
-+ ixs->sa_len ? ixs->sa_txt : " (error)");
-+
-+ /*
-+ * How much headroom do we need to be able to apply
-+ * all the grouped transforms?
-+ */
-+ ixs->ipsq = ixs->ipsp; /* save the head of the ipsec_sa chain */
-+ while (ixs->ipsp) {
-+ ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
-+ if(ixs->sa_len == 0) {
-+ strcpy(ixs->sa_txt, "(error)");
-+ }
-+
-+ /* If it is in larval state, drop the packet, we cannot process yet. */
-+ if(ixs->ipsp->ips_state == SADB_SASTATE_LARVAL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "ipsec_sa in larval state for SA:<%s%s%s> %s, cannot be used yet, dropping packet.\n",
-+ IPS_XFORM_NAME(ixs->ipsp),
-+ ixs->sa_len ? ixs->sa_txt : " (error)");
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
-+ goto cleanup;
-+ }
-+
-+ if(ixs->ipsp->ips_state == SADB_SASTATE_DEAD) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "ipsec_sa in dead state for SA:<%s%s%s> %s, can no longer be used, dropping packet.\n",
-+ IPS_XFORM_NAME(ixs->ipsp),
-+ ixs->sa_len ? ixs->sa_txt : " (error)");
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
-+ goto cleanup;
-+ }
-+
-+ /* If the replay window counter == -1, expire SA, it will roll */
-+ if(ixs->ipsp->ips_replaywin && ixs->ipsp->ips_replaywin_lastseq == -1) {
-+ pfkey_expire(ixs->ipsp, 1);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "replay window counter rolled for SA:<%s%s%s> %s, packet dropped, expiring SA.\n",
-+ IPS_XFORM_NAME(ixs->ipsp),
-+ ixs->sa_len ? ixs->sa_txt : " (error)");
-+ ipsec_sa_delchain(ixs->ipsp);
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_REPLAYROLLED;
-+ goto cleanup;
-+ }
-+
-+ /*
-+ * if this is the first time we are using this SA, mark start time,
-+ * and offset hard/soft counters by "now" for later checking.
-+ */
-+#if 0
-+ if(ixs->ipsp->ips_life.ipl_usetime.count == 0) {
-+ ixs->ipsp->ips_life.ipl_usetime.count = jiffies;
-+ ixs->ipsp->ips_life.ipl_usetime.hard += jiffies;
-+ ixs->ipsp->ips_life.ipl_usetime.soft += jiffies;
-+ }
-+#endif
-+
-+
-+ if(ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_bytes, "bytes", ixs->sa_txt,
-+ ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
-+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_addtime, "addtime",ixs->sa_txt,
-+ ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
-+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_usetime, "usetime",ixs->sa_txt,
-+ ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
-+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_packets, "packets",ixs->sa_txt,
-+ ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied) {
-+
-+ ipsec_sa_delchain(ixs->ipsp);
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_LIFETIMEFAILED;
-+ goto cleanup;
-+ }
-+
-+
-+ ixs->headroom = ixs->tailroom = 0;
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "calling room for <%s%s%s>, SA:%s\n",
-+ IPS_XFORM_NAME(ixs->ipsp),
-+ ixs->sa_len ? ixs->sa_txt : " (error)");
-+ switch(ixs->ipsp->ips_said.proto) {
-+#ifdef CONFIG_IPSEC_AH
-+ case IPPROTO_AH:
-+ ixs->headroom += sizeof(struct ahhdr);
-+ break;
-+#endif /* CONFIG_IPSEC_AH */
-+#ifdef CONFIG_IPSEC_ESP
-+ case IPPROTO_ESP:
-+#ifdef CONFIG_IPSEC_ALG
-+ if ((ixt_e=ixs->ipsp->ips_alg_enc)) {
-+ blocksize = ixt_e->ixt_blocksize;
-+ ixs->headroom += ESP_HEADER_LEN + ixt_e->ixt_ivlen/8;
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ixs->ipsp->ips_encalg) {
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+ ixs->headroom += sizeof(struct esphdr);
-+ break;
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ default:
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_ESP_BADALG;
-+ goto cleanup;
-+ }
-+#ifdef CONFIG_IPSEC_ALG
-+ if ((ixt_a=ixs->ipsp->ips_alg_auth)) {
-+ ixs->tailroom += AHHMAC_HASHLEN;
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ixs->ipsp->ips_authalg) {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5:
-+ ixs->tailroom += AHHMAC_HASHLEN;
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA:
-+ ixs->tailroom += AHHMAC_HASHLEN;
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ case AH_NONE:
-+ break;
-+ default:
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_AH_BADALG;
-+ goto cleanup;
-+ }
-+#ifdef CONFIG_IPSEC_ALG
-+ ixs->tailroom += blocksize != 1 ?
-+ ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 :
-+ ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
-+#else
-+ ixs->tailroom += ((8 - ((ixs->pyldsz + 2 * sizeof(unsigned char)) % 8)) % 8) + 2;
-+#endif /* CONFIG_IPSEC_ALG */
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if ((ixs->ipsp->ips_natt_type) && (!ixs->natt_type)) {
-+ ixs->natt_type = ixs->ipsp->ips_natt_type;
-+ ixs->natt_sport = ixs->ipsp->ips_natt_sport;
-+ ixs->natt_dport = ixs->ipsp->ips_natt_dport;
-+ switch (ixs->natt_type) {
-+ case ESPINUDP_WITH_NON_IKE:
-+ ixs->natt_head = sizeof(struct udphdr)+(2*sizeof(__u32));
-+ break;
-+
-+ case ESPINUDP_WITH_NON_ESP:
-+ ixs->natt_head = sizeof(struct udphdr);
-+ break;
-+
-+ default:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT
-+ , "klips_xmit: invalid nat-t type %d"
-+ , ixs->natt_type);
-+ bundle_stat = IPSEC_XMIT_ESPUDP_BADTYPE;
-+ goto cleanup;
-+
-+ break;
-+ }
-+ ixs->tailroom += ixs->natt_head;
-+ }
-+#endif
-+ break;
-+#endif /* !CONFIG_IPSEC_ESP */
-+#ifdef CONFIG_IPSEC_IPIP
-+ case IPPROTO_IPIP:
-+ ixs->headroom += sizeof(struct iphdr);
-+ break;
-+#endif /* !CONFIG_IPSEC_IPIP */
-+ case IPPROTO_COMP:
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ /*
-+ We can't predict how much the packet will
-+ shrink without doing the actual compression.
-+ We could do it here, if we were the first
-+ encapsulation in the chain. That might save
-+ us a skb_copy_expand, since we might fit
-+ into the existing skb then. However, this
-+ would be a bit unclean (and this hack has
-+ bit us once), so we better not do it. After
-+ all, the skb_copy_expand is cheap in
-+ comparison to the actual compression.
-+ At least we know the packet will not grow.
-+ */
-+ break;
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ default:
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_BADPROTO;
-+ goto cleanup;
-+ }
-+ ixs->ipsp = ixs->ipsp->ips_onext;
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "Required head,tailroom: %d,%d\n",
-+ ixs->headroom, ixs->tailroom);
-+ ixs->max_headroom += ixs->headroom;
-+ ixs->max_tailroom += ixs->tailroom;
-+ ixs->pyldsz += (ixs->headroom + ixs->tailroom);
-+ }
-+ ixs->ipsp = ixs->ipsq; /* restore the head of the ipsec_sa chain */
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "existing head,tailroom: %d,%d before applying xforms with head,tailroom: %d,%d .\n",
-+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb),
-+ ixs->max_headroom, ixs->max_tailroom);
-+
-+ ixs->tot_headroom += ixs->max_headroom;
-+ ixs->tot_tailroom += ixs->max_tailroom;
-+
-+ ixs->mtudiff = ixs->prv->mtu + ixs->tot_headroom + ixs->tot_tailroom - ixs->physmtu;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "mtu:%d physmtu:%d tothr:%d tottr:%d mtudiff:%d ippkttotlen:%d\n",
-+ ixs->prv->mtu, ixs->physmtu,
-+ ixs->tot_headroom, ixs->tot_tailroom, ixs->mtudiff, ntohs(ixs->iph->tot_len));
-+ if(ixs->mtudiff > 0) {
-+ int newmtu = ixs->physmtu - (ixs->tot_headroom + ((ixs->tot_tailroom + 2) & ~7) + 5);
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_info:ipsec_xmit_encap_bundle: "
-+ "dev %s mtu of %d decreased by %d to %d\n",
-+ ixs->dev->name,
-+ ixs->prv->mtu,
-+ ixs->prv->mtu - newmtu,
-+ newmtu);
-+ ixs->prv->mtu = newmtu;
-+#ifdef NET_21
-+#if 0
-+ ixs->skb->dst->pmtu = ixs->prv->mtu; /* RGB */
-+#endif /* 0 */
-+#else /* NET_21 */
-+#if 0
-+ ixs->dev->mtu = ixs->prv->mtu; /* RGB */
-+#endif /* 0 */
-+#endif /* NET_21 */
-+ }
-+
-+ /*
-+ If the sender is doing PMTU discovery, and the
-+ packet doesn't fit within ixs->prv->mtu, notify him
-+ (unless it was an ICMP packet, or it was not the
-+ zero-offset packet) and send it anyways.
-+
-+ Note: buggy firewall configuration may prevent the
-+ ICMP packet from getting back.
-+ */
-+ if(sysctl_ipsec_icmp
-+ && ixs->prv->mtu < ntohs(ixs->iph->tot_len)
-+ && (ixs->iph->frag_off & __constant_htons(IP_DF)) ) {
-+ int notify = ixs->iph->protocol != IPPROTO_ICMP
-+ && (ixs->iph->frag_off & __constant_htons(IP_OFFSET)) == 0;
-+
-+#ifdef IPSEC_obey_DF
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "fragmentation needed and DF set; %sdropping packet\n",
-+ notify ? "sending ICMP and " : "");
-+ if (notify)
-+ ICMP_SEND(ixs->skb,
-+ ICMP_DEST_UNREACH,
-+ ICMP_FRAG_NEEDED,
-+ ixs->prv->mtu,
-+ ixs->physdev);
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_CANNOTFRAG;
-+ goto cleanup;
-+#else /* IPSEC_obey_DF */
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "fragmentation needed and DF set; %spassing packet\n",
-+ notify ? "sending ICMP and " : "");
-+ if (notify)
-+ ICMP_SEND(ixs->skb,
-+ ICMP_DEST_UNREACH,
-+ ICMP_FRAG_NEEDED,
-+ ixs->prv->mtu,
-+ ixs->physdev);
-+#endif /* IPSEC_obey_DF */
-+ }
-+
-+#ifdef MSS_HACK
-+ /*
-+ * If this is a transport mode TCP packet with
-+ * SYN set, determine an effective MSS based on
-+ * AH/ESP overheads determined above.
-+ */
-+ if (ixs->iph->protocol == IPPROTO_TCP
-+ && ixs->outgoing_said.proto != IPPROTO_IPIP) {
-+ struct tcphdr *tcph = ixs->skb->h.th;
-+ if (tcph->syn && !tcph->ack) {
-+ if(!ipsec_adjust_mss(ixs->skb, tcph, ixs->prv->mtu)) {
-+ printk(KERN_WARNING
-+ "klips_warning:ipsec_xmit_encap_bundle: "
-+ "ipsec_adjust_mss() failed\n");
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_MSSERR;
-+ goto cleanup;
-+ }
-+ }
-+ }
-+#endif /* MSS_HACK */
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if ((ixs->natt_type) && (ixs->outgoing_said.proto != IPPROTO_IPIP)) {
-+ /**
-+ * NAT-Traversal and Transport Mode:
-+ * we need to correct TCP/UDP checksum
-+ *
-+ * If we've got NAT-OA, we can fix checksum without recalculation.
-+ * If we don't we can zero udp checksum.
-+ */
-+ __u32 natt_oa = ixs->ipsp->ips_natt_oa ?
-+ ((struct sockaddr_in*)(ixs->ipsp->ips_natt_oa))->sin_addr.s_addr : 0;
-+ __u16 pkt_len = ixs->skb->tail - (unsigned char *)ixs->iph;
-+ __u16 data_len = pkt_len - (ixs->iph->ihl << 2);
-+ switch (ixs->iph->protocol) {
-+ case IPPROTO_TCP:
-+ if (data_len >= sizeof(struct tcphdr)) {
-+ struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);
-+ if (natt_oa) {
-+ __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "NAT-T & TRANSPORT: "
-+ "fix TCP checksum using NAT-OA\n");
-+ tcp->check = csum_fold(
-+ csum_partial((unsigned char *)buff, sizeof(buff),
-+ tcp->check^0xffff));
-+ }
-+ else {
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "NAT-T & TRANSPORT: do not recalc TCP checksum\n");
-+ }
-+ }
-+ else {
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "NAT-T & TRANSPORT: can't fix TCP checksum\n");
-+ }
-+ break;
-+ case IPPROTO_UDP:
-+ if (data_len >= sizeof(struct udphdr)) {
-+ struct udphdr *udp = (struct udphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);
-+ if (udp->check == 0) {
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "NAT-T & TRANSPORT: UDP checksum already 0\n");
-+ }
-+ else if (natt_oa) {
-+ __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "NAT-T & TRANSPORT: "
-+ "fix UDP checksum using NAT-OA\n");
-+ udp->check = csum_fold(
-+ csum_partial((unsigned char *)buff, sizeof(buff),
-+ udp->check^0xffff));
-+ }
-+ else {
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "NAT-T & TRANSPORT: zero UDP checksum\n");
-+ udp->check = 0;
-+ }
-+ }
-+ else {
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "NAT-T & TRANSPORT: can't fix UDP checksum\n");
-+ }
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");
-+ break;
-+ }
-+ }
-+#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
-+
-+ if(!ixs->hard_header_stripped) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "allocating %d bytes for hardheader.\n",
-+ ixs->hard_header_len);
-+ if((ixs->saved_header = kmalloc(ixs->hard_header_len, GFP_ATOMIC)) == NULL) {
-+ printk(KERN_WARNING "klips_debug:ipsec_xmit_encap_bundle: "
-+ "Failed, tried to allocate %d bytes for temp hard_header.\n",
-+ ixs->hard_header_len);
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_ERRMEMALLOC;
-+ goto cleanup;
-+ }
-+ {
-+ int i;
-+ for (i = 0; i < ixs->hard_header_len; i++) {
-+ ixs->saved_header[i] = ixs->skb->data[i];
-+ }
-+ }
-+ if(ixs->skb->len < ixs->hard_header_len) {
-+ printk(KERN_WARNING "klips_error:ipsec_xmit_encap_bundle: "
-+ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
-+ ixs->hard_header_len, (int)(ixs->skb->len));
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_ESP_PUSHPULLERR;
-+ goto cleanup;
-+ }
-+ skb_pull(ixs->skb, ixs->hard_header_len);
-+ ixs->hard_header_stripped = 1;
-+
-+/* ixs->iph = (struct iphdr *) (ixs->skb->data); */
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "head,tailroom: %d,%d after hard_header stripped.\n",
-+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
-+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_CROUT, ixs->iph);
-+ } else {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "hard header already stripped.\n");
-+ }
-+
-+ ixs->ll_headroom = (ixs->hard_header_len + 15) & ~15;
-+
-+ if ((skb_headroom(ixs->skb) >= ixs->max_headroom + 2 * ixs->ll_headroom) &&
-+ (skb_tailroom(ixs->skb) >= ixs->max_tailroom)
-+#ifndef NET_21
-+ && ixs->skb->free
-+#endif /* !NET_21 */
-+ ) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "data fits in existing skb\n");
-+ } else {
-+ struct sk_buff* tskb;
-+
-+ if(!ixs->oskb) {
-+ ixs->oskb = ixs->skb;
-+ }
-+
-+ tskb = skb_copy_expand(ixs->skb,
-+ /* The need for 2 * link layer length here remains unexplained...RGB */
-+ ixs->max_headroom + 2 * ixs->ll_headroom,
-+ ixs->max_tailroom,
-+ GFP_ATOMIC);
-+#ifdef NET_21
-+ if(tskb && ixs->skb->sk) {
-+ skb_set_owner_w(tskb, ixs->skb->sk);
-+ }
-+#endif /* NET_21 */
-+ if(ixs->skb != ixs->oskb) {
-+ ipsec_kfree_skb(ixs->skb);
-+ }
-+ ixs->skb = tskb;
-+ if (!ixs->skb) {
-+ printk(KERN_WARNING
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "Failed, tried to allocate %d head and %d tailroom\n",
-+ ixs->max_headroom, ixs->max_tailroom);
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_ERRSKBALLOC;
-+ goto cleanup;
-+ }
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "head,tailroom: %d,%d after allocation\n",
-+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
-+ }
-+
-+ /*
-+ * Apply grouped transforms to packet
-+ */
-+ while (ixs->ipsp) {
-+ enum ipsec_xmit_value encap_stat = IPSEC_XMIT_OK;
-+
-+ encap_stat = ipsec_xmit_encap_once(ixs);
-+ if(encap_stat != IPSEC_XMIT_OK) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: encap_once failed: %d\n",
-+ encap_stat);
-+
-+ bundle_stat = IPSEC_XMIT_ENCAPFAIL;
-+ goto cleanup;
-+ }
-+ }
-+ /* end encapsulation loop here XXX */
-+ cleanup:
-+ spin_unlock(&tdb_lock);
-+ return bundle_stat;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.8 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.7 2004/02/03 03:13:41 mcr
-+ * mark invalid encapsulation states.
-+ *
-+ * Revision 1.6.2.1 2003/12/22 15:25:52 jjo
-+ * Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.6 2003/12/10 01:14:27 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.5 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.4.4.2 2003/10/29 01:37:39 mcr
-+ * when creating %hold from %trap, only make the %hold as
-+ * specific as the %trap was - so if the protocol and ports
-+ * were wildcards, then the %hold will be too.
-+ *
-+ * Revision 1.4.4.1 2003/09/21 13:59:56 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.4 2003/06/20 02:28:10 mcr
-+ * misstype of variable name, not detected by module build.
-+ *
-+ * Revision 1.3 2003/06/20 01:42:21 mcr
-+ * added counters to measure how many ACQUIREs we send to pluto,
-+ * and how many are successfully sent.
-+ *
-+ * Revision 1.2 2003/04/03 17:38:35 rgb
-+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
-+ * Normalised coding style.
-+ * Simplified logic and reduced duplication of code.
-+ *
-+ * Revision 1.1 2003/02/12 19:31:23 rgb
-+ * Refactored from ipsec_tunnel.c
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/pfkey_v2.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,2126 @@
-+/*
-+ * @(#) RFC2367 PF_KEYv2 Key management API domain socket I/F
-+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * Template from /usr/src/linux-2.0.36/net/unix/af_unix.c.
-+ * Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c.
-+ */
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/version.h>
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+
-+#include "openswan/ipsec_param.h"
-+
-+#include <linux/major.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/stat.h>
-+#include <linux/socket.h>
-+#include <linux/un.h>
-+#include <linux/fcntl.h>
-+#include <linux/termios.h>
-+#include <linux/socket.h>
-+#include <linux/sockios.h>
-+#include <linux/net.h> /* struct socket */
-+#include <linux/in.h>
-+#include <linux/fs.h>
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <asm/segment.h>
-+#include <linux/skbuff.h>
-+#include <linux/netdevice.h>
-+#include <net/sock.h> /* struct sock */
-+/* #include <net/tcp.h> */
-+#include <net/af_unix.h>
-+#ifdef CONFIG_PROC_FS
-+# include <linux/proc_fs.h>
-+#endif /* CONFIG_PROC_FS */
-+
-+#include <linux/types.h>
-+
-+#include <openswan.h>
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+#endif /* NET_21 */
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_pfkey = 0;
-+extern int sysctl_ipsec_debug_verbose;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
-+
-+#ifndef SOCKOPS_WRAPPED
-+#define SOCKOPS_WRAPPED(name) name
-+#endif /* SOCKOPS_WRAPPED */
-+
-+extern struct proto_ops pfkey_ops;
-+struct sock *pfkey_sock_list = NULL;
-+struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
-+
-+struct socket_list *pfkey_open_sockets = NULL;
-+struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
-+
-+int pfkey_msg_interp(struct sock *, struct sadb_msg *, struct sadb_msg **);
-+
-+int
-+pfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets)
-+{
-+ struct socket_list *socket_listp,*prev;
-+
-+ if(!socketp) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_remove_socket: "
-+ "NULL socketp handed in, failed.\n");
-+ return -EINVAL;
-+ }
-+
-+ if(!sockets) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_remove_socket: "
-+ "NULL sockets list handed in, failed.\n");
-+ return -EINVAL;
-+ }
-+
-+ socket_listp = *sockets;
-+ prev = NULL;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_remove_socket: "
-+ "removing sock=0p%p\n",
-+ socketp);
-+
-+ while(socket_listp != NULL) {
-+ if(socket_listp->socketp == socketp) {
-+ if(prev != NULL) {
-+ prev->next = socket_listp->next;
-+ } else {
-+ *sockets = socket_listp->next;
-+ }
-+
-+ kfree((void*)socket_listp);
-+
-+ break;
-+ }
-+ prev = socket_listp;
-+ socket_listp = socket_listp->next;
-+ }
-+
-+ return 0;
-+}
-+
-+int
-+pfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets)
-+{
-+ struct socket_list *socket_listp;
-+
-+ if(!socketp) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_socket: "
-+ "NULL socketp handed in, failed.\n");
-+ return -EINVAL;
-+ }
-+
-+ if(!sockets) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_socket: "
-+ "NULL sockets list handed in, failed.\n");
-+ return -EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_socket: "
-+ "allocating %lu bytes for socketp=0p%p\n",
-+ (unsigned long) sizeof(struct socket_list),
-+ socketp);
-+
-+ if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_socket: "
-+ "memory allocation error.\n");
-+ return -ENOMEM;
-+ }
-+
-+ socket_listp->socketp = socketp;
-+ socket_listp->next = *sockets;
-+ *sockets = socket_listp;
-+
-+ return 0;
-+}
-+
-+int
-+pfkey_list_remove_supported(struct supported *supported, struct supported_list **supported_list)
-+{
-+ struct supported_list *supported_listp = *supported_list, *prev = NULL;
-+
-+ if(!supported) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_remove_supported: "
-+ "NULL supported handed in, failed.\n");
-+ return -EINVAL;
-+ }
-+
-+ if(!supported_list) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_remove_supported: "
-+ "NULL supported_list handed in, failed.\n");
-+ return -EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_remove_supported: "
-+ "removing supported=0p%p\n",
-+ supported);
-+
-+ while(supported_listp != NULL) {
-+ if(supported_listp->supportedp == supported) {
-+ if(prev != NULL) {
-+ prev->next = supported_listp->next;
-+ } else {
-+ *supported_list = supported_listp->next;
-+ }
-+
-+ kfree((void*)supported_listp);
-+
-+ break;
-+ }
-+ prev = supported_listp;
-+ supported_listp = supported_listp->next;
-+ }
-+
-+ return 0;
-+}
-+
-+int
-+pfkey_list_insert_supported(struct supported *supported, struct supported_list **supported_list)
-+{
-+ struct supported_list *supported_listp;
-+
-+ if(!supported) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_supported: "
-+ "NULL supported handed in, failed.\n");
-+ return -EINVAL;
-+ }
-+
-+ if(!supported_list) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_supported: "
-+ "NULL supported_list handed in, failed.\n");
-+ return -EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_supported: "
-+ "allocating %lu bytes for incoming, supported=0p%p, supported_list=0p%p\n",
-+ (unsigned long) sizeof(struct supported_list),
-+ supported,
-+ supported_list);
-+
-+ supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL);
-+ if(supported_listp == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_supported: "
-+ "memory allocation error.\n");
-+ return -ENOMEM;
-+ }
-+
-+ supported_listp->supportedp = supported;
-+ supported_listp->next = *supported_list;
-+ *supported_list = supported_listp;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_supported: "
-+ "outgoing, supported=0p%p, supported_list=0p%p\n",
-+ supported,
-+ supported_list);
-+
-+ return 0;
-+}
-+
-+#ifndef NET_21
-+DEBUG_NO_STATIC void
-+pfkey_state_change(struct sock *sk)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_state_change: .\n");
-+ if(!sk->dead) {
-+ wake_up_interruptible(sk->sleep);
-+ }
-+}
-+#endif /* !NET_21 */
-+
-+#ifndef NET_21
-+DEBUG_NO_STATIC void
-+pfkey_data_ready(struct sock *sk, int len)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_data_ready: "
-+ "sk=0p%p len=%d\n",
-+ sk,
-+ len);
-+ if(!sk->dead) {
-+ wake_up_interruptible(sk->sleep);
-+ sock_wake_async(sk->socket, 1);
-+ }
-+}
-+
-+DEBUG_NO_STATIC void
-+pfkey_write_space(struct sock *sk)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_write_space: .\n");
-+ if(!sk->dead) {
-+ wake_up_interruptible(sk->sleep);
-+ sock_wake_async(sk->socket, 2);
-+ }
-+}
-+#endif /* !NET_21 */
-+
-+DEBUG_NO_STATIC void
-+pfkey_insert_socket(struct sock *sk)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_insert_socket: "
-+ "sk=0p%p\n",
-+ sk);
-+ cli();
-+ sk->next=pfkey_sock_list;
-+ pfkey_sock_list=sk;
-+ sti();
-+}
-+
-+DEBUG_NO_STATIC void
-+pfkey_remove_socket(struct sock *sk)
-+{
-+ struct sock **s;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_remove_socket: .\n");
-+ cli();
-+ s=&pfkey_sock_list;
-+
-+ while(*s!=NULL) {
-+ if(*s==sk) {
-+ *s=sk->next;
-+ sk->next=NULL;
-+ sti();
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_remove_socket: "
-+ "succeeded.\n");
-+ return;
-+ }
-+ s=&((*s)->next);
-+ }
-+ sti();
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_remove_socket: "
-+ "not found.\n");
-+ return;
-+}
-+
-+DEBUG_NO_STATIC void
-+pfkey_destroy_socket(struct sock *sk)
-+{
-+ struct sk_buff *skb;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_destroy_socket: .\n");
-+ pfkey_remove_socket(sk);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_destroy_socket: "
-+ "pfkey_remove_socket called.\n");
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_destroy_socket: "
-+ "sk(0p%p)->(&0p%p)receive_queue.{next=0p%p,prev=0p%p}.\n",
-+ sk,
-+ &(sk->receive_queue),
-+ sk->receive_queue.next,
-+ sk->receive_queue.prev);
-+ while(sk && ((skb=skb_dequeue(&(sk->receive_queue)))!=NULL)) {
-+#ifdef NET_21
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(debug_pfkey && sysctl_ipsec_debug_verbose) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_destroy_socket: "
-+ "skb=0p%p dequeued.\n", skb);
-+ printk(KERN_INFO "klips_debug:pfkey_destroy_socket: "
-+ "pfkey_skb contents:");
-+ printk(" next:0p%p", skb->next);
-+ printk(" prev:0p%p", skb->prev);
-+ printk(" list:0p%p", skb->list);
-+ printk(" sk:0p%p", skb->sk);
-+ printk(" stamp:%ld.%ld", skb->stamp.tv_sec, skb->stamp.tv_usec);
-+ printk(" dev:0p%p", skb->dev);
-+ if(skb->dev) {
-+ if(skb->dev->name) {
-+ printk(" dev->name:%s", skb->dev->name);
-+ } else {
-+ printk(" dev->name:NULL?");
-+ }
-+ } else {
-+ printk(" dev:NULL");
-+ }
-+ printk(" h:0p%p", skb->h.raw);
-+ printk(" nh:0p%p", skb->nh.raw);
-+ printk(" mac:0p%p", skb->mac.raw);
-+ printk(" dst:0p%p", skb->dst);
-+ if(sysctl_ipsec_debug_verbose) {
-+ int i;
-+
-+ printk(" cb");
-+ for(i=0; i<48; i++) {
-+ printk(":%2x", skb->cb[i]);
-+ }
-+ }
-+ printk(" len:%d", skb->len);
-+ printk(" csum:%d", skb->csum);
-+#ifndef NETDEV_23
-+ printk(" used:%d", skb->used);
-+ printk(" is_clone:%d", skb->is_clone);
-+#endif /* NETDEV_23 */
-+ printk(" cloned:%d", skb->cloned);
-+ printk(" pkt_type:%d", skb->pkt_type);
-+ printk(" ip_summed:%d", skb->ip_summed);
-+ printk(" priority:%d", skb->priority);
-+ printk(" protocol:%d", skb->protocol);
-+ printk(" security:%d", skb->security);
-+ printk(" truesize:%d", skb->truesize);
-+ printk(" head:0p%p", skb->head);
-+ printk(" data:0p%p", skb->data);
-+ printk(" tail:0p%p", skb->tail);
-+ printk(" end:0p%p", skb->end);
-+ if(sysctl_ipsec_debug_verbose) {
-+ unsigned char* i;
-+ printk(" data");
-+ for(i = skb->head; i < skb->end; i++) {
-+ printk(":%2x", (unsigned char)(*(i)));
-+ }
-+ }
-+ printk(" destructor:0p%p", skb->destructor);
-+ printk("\n");
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#endif /* NET_21 */
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_destroy_socket: "
-+ "skb=0p%p freed.\n",
-+ skb);
-+ ipsec_kfree_skb(skb);
-+ }
-+
-+ sk->dead = 1;
-+ sk_free(sk);
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_destroy_socket: destroyed.\n");
-+}
-+
-+int
-+pfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg)
-+{
-+ int error = 0;
-+ struct sk_buff * skb = NULL;
-+ struct sock *sk;
-+
-+ if(sock == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_upmsg: "
-+ "NULL socket passed in.\n");
-+ return -EINVAL;
-+ }
-+
-+ if(pfkey_msg == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_upmsg: "
-+ "NULL pfkey_msg passed in.\n");
-+ return -EINVAL;
-+ }
-+
-+#ifdef NET_21
-+ sk = sock->sk;
-+#else /* NET_21 */
-+ sk = sock->data;
-+#endif /* NET_21 */
-+
-+ if(sk == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_upmsg: "
-+ "NULL sock passed in.\n");
-+ return -EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_upmsg: "
-+ "allocating %d bytes...\n",
-+ (int)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN));
-+ if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_upmsg: "
-+ "no buffers left to send up a message.\n");
-+ return -ENOBUFS;
-+ }
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_upmsg: "
-+ "...allocated at 0p%p.\n",
-+ skb);
-+
-+ skb->dev = NULL;
-+
-+ if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
-+ printk(KERN_WARNING "klips_error:pfkey_upmsg: "
-+ "tried to skb_put %ld, %d available. This should never happen, please report.\n",
-+ (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN,
-+ skb_tailroom(skb));
-+ ipsec_kfree_skb(skb);
-+ return -ENOBUFS;
-+ }
-+ skb->h.raw = skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
-+ memcpy(skb->h.raw, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
-+
-+#ifndef NET_21
-+ skb->free = 1;
-+#endif /* !NET_21 */
-+
-+ if((error = sock_queue_rcv_skb(sk, skb)) < 0) {
-+ skb->sk=NULL;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_upmsg: "
-+ "error=%d calling sock_queue_rcv_skb with skb=0p%p.\n",
-+ error,
-+ skb);
-+ ipsec_kfree_skb(skb);
-+ return error;
-+ }
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ if(sock == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_create: "
-+ "socket NULL.\n");
-+ return -EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_create: "
-+ "sock=0p%p type:%d state:%d flags:%ld protocol:%d\n",
-+ sock,
-+ sock->type,
-+ (unsigned int)(sock->state),
-+ sock->flags, protocol);
-+
-+ if(sock->type != SOCK_RAW) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_create: "
-+ "only SOCK_RAW supported.\n");
-+ return -ESOCKTNOSUPPORT;
-+ }
-+
-+ if(protocol != PF_KEY_V2) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_create: "
-+ "protocol not PF_KEY_V2.\n");
-+ return -EPROTONOSUPPORT;
-+ }
-+
-+ if((current->uid != 0)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_create: "
-+ "must be root to open pfkey sockets.\n");
-+ return -EACCES;
-+ }
-+
-+#ifdef NET_21
-+ sock->state = SS_UNCONNECTED;
-+#endif /* NET_21 */
-+ MOD_INC_USE_COUNT;
-+#ifdef NET_21
-+ if((sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1)) == NULL)
-+#else /* NET_21 */
-+ if((sk=(struct sock *)sk_alloc(GFP_KERNEL)) == NULL)
-+#endif /* NET_21 */
-+ {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_create: "
-+ "Out of memory trying to allocate.\n");
-+ MOD_DEC_USE_COUNT;
-+ return -ENOMEM;
-+ }
-+
-+#ifndef NET_21
-+ memset(sk, 0, sizeof(*sk));
-+#endif /* !NET_21 */
-+
-+#ifdef NET_21
-+ sock_init_data(sock, sk);
-+
-+ sk->destruct = NULL;
-+ sk->reuse = 1;
-+ sock->ops = &pfkey_ops;
-+
-+ sk->zapped=0;
-+ sk->family = PF_KEY;
-+/* sk->num = protocol; */
-+ sk->protocol = protocol;
-+ key_pid(sk) = current->pid;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_create: "
-+ "sock->fasync_list=0p%p sk->sleep=0p%p.\n",
-+ sock->fasync_list,
-+ sk->sleep);
-+#else /* NET_21 */
-+ sk->type=sock->type;
-+ init_timer(&sk->timer);
-+ skb_queue_head_init(&sk->write_queue);
-+ skb_queue_head_init(&sk->receive_queue);
-+ skb_queue_head_init(&sk->back_log);
-+ sk->rcvbuf=SK_RMEM_MAX;
-+ sk->sndbuf=SK_WMEM_MAX;
-+ sk->allocation=GFP_KERNEL;
-+ sk->state=TCP_CLOSE;
-+ sk->priority=SOPRI_NORMAL;
-+ sk->state_change=pfkey_state_change;
-+ sk->data_ready=pfkey_data_ready;
-+ sk->write_space=pfkey_write_space;
-+ sk->error_report=pfkey_state_change;
-+ sk->mtu=4096;
-+ sk->socket=sock;
-+ sock->data=(void *)sk;
-+ sk->sleep=sock->wait;
-+#endif /* NET_21 */
-+
-+ pfkey_insert_socket(sk);
-+ pfkey_list_insert_socket(sock, &pfkey_open_sockets);
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_create: "
-+ "Socket sock=0p%p sk=0p%p initialised.\n", sock, sk);
-+ return 0;
-+}
-+
-+#ifndef NET_21
-+DEBUG_NO_STATIC int
-+pfkey_dup(struct socket *newsock, struct socket *oldsock)
-+{
-+ struct sock *sk;
-+
-+ if(newsock==NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_dup: "
-+ "No new socket attached.\n");
-+ return -EINVAL;
-+ }
-+
-+ if(oldsock==NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_dup: "
-+ "No old socket attached.\n");
-+ return -EINVAL;
-+ }
-+
-+#ifdef NET_21
-+ sk=oldsock->sk;
-+#else /* NET_21 */
-+ sk=oldsock->data;
-+#endif /* NET_21 */
-+
-+ /* May not have data attached */
-+ if(sk==NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_dup: "
-+ "No sock attached to old socket.\n");
-+ return -EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_dup: .\n");
-+
-+ return pfkey_create(newsock, sk->protocol);
-+}
-+#endif /* !NET_21 */
-+
-+DEBUG_NO_STATIC int
-+#ifdef NETDEV_23
-+pfkey_release(struct socket *sock)
-+#else /* NETDEV_23 */
-+pfkey_release(struct socket *sock, struct socket *peersock)
-+#endif /* NETDEV_23 */
-+{
-+ struct sock *sk;
-+ int i;
-+
-+ if(sock==NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_release: "
-+ "No socket attached.\n");
-+ return 0; /* -EINVAL; */
-+ }
-+
-+#ifdef NET_21
-+ sk=sock->sk;
-+#else /* NET_21 */
-+ sk=sock->data;
-+#endif /* NET_21 */
-+
-+ /* May not have data attached */
-+ if(sk==NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_release: "
-+ "No sk attached to sock=0p%p.\n", sock);
-+ return 0; /* -EINVAL; */
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_release: "
-+ "sock=0p%p sk=0p%p\n", sock, sk);
-+
-+#ifdef NET_21
-+ if(!sk->dead)
-+#endif /* NET_21 */
-+ if(sk->state_change) {
-+ sk->state_change(sk);
-+ }
-+
-+#ifdef NET_21
-+ sock->sk = NULL;
-+#else /* NET_21 */
-+ sock->data = NULL;
-+#endif /* NET_21 */
-+
-+ /* Try to flush out this socket. Throw out buffers at least */
-+ pfkey_destroy_socket(sk);
-+ pfkey_list_remove_socket(sock, &pfkey_open_sockets);
-+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
-+ pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i]));
-+ }
-+
-+ MOD_DEC_USE_COUNT;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_release: "
-+ "succeeded.\n");
-+
-+ return 0;
-+}
-+
-+#ifndef NET_21
-+DEBUG_NO_STATIC int
-+pfkey_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_bind: "
-+ "operation not supported.\n");
-+ return -EINVAL;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_connect: "
-+ "operation not supported.\n");
-+ return -EINVAL;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_socketpair(struct socket *a, struct socket *b)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_socketpair: "
-+ "operation not supported.\n");
-+ return -EINVAL;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_accept(struct socket *sock, struct socket *newsock, int flags)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_aaccept: "
-+ "operation not supported.\n");
-+ return -EINVAL;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len,
-+ int peer)
-+{
-+ struct sockaddr *ska = (struct sockaddr*)uaddr;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_getname: .\n");
-+ ska->sa_family = PF_KEY;
-+ *uaddr_len = sizeof(*ska);
-+ return 0;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_select(struct socket *sock, int sel_type, select_table *wait)
-+{
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_select: "
-+ ".sock=0p%p sk=0p%p sel_type=%d\n",
-+ sock,
-+ sock->data,
-+ sel_type);
-+ if(sock == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_select: "
-+ "Null socket passed in.\n");
-+ return -EINVAL;
-+ }
-+ return datagram_select(sock->data, sel_type, wait);
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ioctl: "
-+ "not supported.\n");
-+ return -EINVAL;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_listen(struct socket *sock, int backlog)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_listen: "
-+ "not supported.\n");
-+ return -EINVAL;
-+}
-+#endif /* !NET_21 */
-+
-+DEBUG_NO_STATIC int
-+pfkey_shutdown(struct socket *sock, int mode)
-+{
-+ struct sock *sk;
-+
-+ if(sock == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_shutdown: "
-+ "NULL socket passed in.\n");
-+ return -EINVAL;
-+ }
-+
-+#ifdef NET_21
-+ sk=sock->sk;
-+#else /* NET_21 */
-+ sk=sock->data;
-+#endif /* NET_21 */
-+
-+ if(sk == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_shutdown: "
-+ "No sock attached to socket.\n");
-+ return -EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_shutdown: "
-+ "mode=%x.\n", mode);
-+ mode++;
-+
-+ if(mode&SEND_SHUTDOWN) {
-+ sk->shutdown|=SEND_SHUTDOWN;
-+ sk->state_change(sk);
-+ }
-+
-+ if(mode&RCV_SHUTDOWN) {
-+ sk->shutdown|=RCV_SHUTDOWN;
-+ sk->state_change(sk);
-+ }
-+ return 0;
-+}
-+
-+#ifndef NET_21
-+DEBUG_NO_STATIC int
-+pfkey_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
-+{
-+#ifndef NET_21
-+ struct sock *sk;
-+
-+ if(sock == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_setsockopt: "
-+ "Null socket passed in.\n");
-+ return -EINVAL;
-+ }
-+
-+ sk=sock->data;
-+
-+ if(sk == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_setsockopt: "
-+ "Null sock passed in.\n");
-+ return -EINVAL;
-+ }
-+#endif /* !NET_21 */
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_setsockopt: .\n");
-+ if(level!=SOL_SOCKET) {
-+ return -EOPNOTSUPP;
-+ }
-+#ifdef NET_21
-+ return sock_setsockopt(sock, level, optname, optval, optlen);
-+#else /* NET_21 */
-+ return sock_setsockopt(sk, level, optname, optval, optlen);
-+#endif /* NET_21 */
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
-+{
-+#ifndef NET_21
-+ struct sock *sk;
-+
-+ if(sock == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_setsockopt: "
-+ "Null socket passed in.\n");
-+ return -EINVAL;
-+ }
-+
-+ sk=sock->data;
-+
-+ if(sk == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_setsockopt: "
-+ "Null sock passed in.\n");
-+ return -EINVAL;
-+ }
-+#endif /* !NET_21 */
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_getsockopt: .\n");
-+ if(level!=SOL_SOCKET) {
-+ return -EOPNOTSUPP;
-+ }
-+#ifdef NET_21
-+ return sock_getsockopt(sock, level, optname, optval, optlen);
-+#else /* NET_21 */
-+ return sock_getsockopt(sk, level, optname, optval, optlen);
-+#endif /* NET_21 */
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_fcntl: "
-+ "not supported.\n");
-+ return -EINVAL;
-+}
-+#endif /* !NET_21 */
-+
-+/*
-+ * Send PF_KEY data down.
-+ */
-+
-+DEBUG_NO_STATIC int
-+#ifdef NET_21
-+pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
-+#else /* NET_21 */
-+pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nonblock, int flags)
-+#endif /* NET_21 */
-+{
-+ struct sock *sk;
-+ int error = 0;
-+ struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL;
-+
-+ if(sock == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "Null socket passed in.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+#ifdef NET_21
-+ sk = sock->sk;
-+#else /* NET_21 */
-+ sk = sock->data;
-+#endif /* NET_21 */
-+
-+ if(sk == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "Null sock passed in.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(msg == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "Null msghdr passed in.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: .\n");
-+ if(sk->err) {
-+ error = sock_error(sk);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "sk->err is non-zero, returns %d.\n",
-+ error);
-+ SENDERR(-error);
-+ }
-+
-+ if((current->uid != 0)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "must be root to send messages to pfkey sockets.\n");
-+ SENDERR(EACCES);
-+ }
-+
-+#ifdef NET_21
-+ if(msg->msg_control)
-+#else /* NET_21 */
-+ if(flags || msg->msg_control)
-+#endif /* NET_21 */
-+ {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "can't set flags or set msg_control.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(sk->shutdown & SEND_SHUTDOWN) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "shutdown.\n");
-+ send_sig(SIGPIPE, current, 0);
-+ SENDERR(EPIPE);
-+ }
-+
-+ if(len < sizeof(struct sadb_msg)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "bogus msg len of %d, too small.\n", len);
-+ SENDERR(EMSGSIZE);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "allocating %d bytes for downward message.\n",
-+ len);
-+ if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "memory allocation error.\n");
-+ SENDERR(ENOBUFS);
-+ }
-+
-+ memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len);
-+
-+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
-+ KLIPS_PRINT(1 || debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "not PF_KEY_V2 msg, found %d, should be %d.\n",
-+ pfkey_msg->sadb_msg_version,
-+ PF_KEY_V2);
-+ kfree((void*)pfkey_msg);
-+ return -EINVAL;
-+ }
-+
-+ if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "bogus msg len of %d, not %d byte aligned.\n",
-+ len, (int)IPSEC_PFKEYv2_ALIGN);
-+ SENDERR(EMSGSIZE);
-+ }
-+
-+#if 0
-+ /* This check is questionable, since a downward message could be
-+ the result of an ACQUIRE either from kernel (PID==0) or
-+ userspace (some other PID). */
-+ /* check PID */
-+ if(pfkey_msg->sadb_msg_pid != current->pid) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "pid (%d) does not equal sending process pid (%d).\n",
-+ pfkey_msg->sadb_msg_pid, current->pid);
-+ SENDERR(EINVAL);
-+ }
-+#endif
-+
-+ if(pfkey_msg->sadb_msg_reserved) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "reserved field must be zero, set to %d.\n",
-+ pfkey_msg->sadb_msg_reserved);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "msg type too large or small:%d.\n",
-+ pfkey_msg->sadb_msg_type);
-+ SENDERR(EINVAL);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "msg sent for parsing.\n");
-+
-+ if((error = pfkey_msg_interp(sk, pfkey_msg, &pfkey_reply))) {
-+ struct socket_list *pfkey_socketsp;
-+
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
-+ "pfkey_msg_parse returns %d.\n",
-+ error);
-+
-+ if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "memory allocation error.\n");
-+ SENDERR(ENOBUFS);
-+ }
-+ memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg));
-+ pfkey_reply->sadb_msg_errno = -error;
-+ pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
-+
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ int error_upmsg = 0;
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
-+ "sending up error=%d message=0p%p to socket=0p%p.\n",
-+ error,
-+ pfkey_reply,
-+ pfkey_socketsp->socketp);
-+ if((error_upmsg = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
-+ "sending up error message to socket=0p%p failed with error=%d.\n",
-+ pfkey_socketsp->socketp,
-+ error_upmsg);
-+ /* pfkey_msg_free(&pfkey_reply); */
-+ /* SENDERR(-error); */
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
-+ "sending up error message to socket=0p%p succeeded.\n",
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ pfkey_msg_free(&pfkey_reply);
-+
-+ SENDERR(-error);
-+ }
-+
-+ errlab:
-+ if (pfkey_msg) {
-+ kfree((void*)pfkey_msg);
-+ }
-+
-+ if(error) {
-+ return error;
-+ } else {
-+ return len;
-+ }
-+}
-+
-+/*
-+ * Receive PF_KEY data up.
-+ */
-+
-+DEBUG_NO_STATIC int
-+#ifdef NET_21
-+pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm)
-+#else /* NET_21 */
-+pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int noblock, int flags, int *addr_len)
-+#endif /* NET_21 */
-+{
-+ struct sock *sk;
-+#ifdef NET_21
-+ int noblock = flags & MSG_DONTWAIT;
-+#endif /* NET_21 */
-+ struct sk_buff *skb;
-+ int error;
-+
-+ if(sock == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_recvmsg: "
-+ "Null socket passed in.\n");
-+ return -EINVAL;
-+ }
-+
-+#ifdef NET_21
-+ sk = sock->sk;
-+#else /* NET_21 */
-+ sk = sock->data;
-+#endif /* NET_21 */
-+
-+ if(sk == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_recvmsg: "
-+ "Null sock passed in for sock=0p%p.\n", sock);
-+ return -EINVAL;
-+ }
-+
-+ if(msg == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_recvmsg: "
-+ "Null msghdr passed in for sock=0p%p, sk=0p%p.\n",
-+ sock, sk);
-+ return -EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_recvmsg: sock=0p%p sk=0p%p msg=0p%p size=%d.\n",
-+ sock, sk, msg, size);
-+ if(flags & ~MSG_PEEK) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "flags (%d) other than MSG_PEEK not supported.\n",
-+ flags);
-+ return -EOPNOTSUPP;
-+ }
-+
-+#ifdef NET_21
-+ msg->msg_namelen = 0; /* sizeof(*ska); */
-+#else /* NET_21 */
-+ if(addr_len) {
-+ *addr_len = 0; /* sizeof(*ska); */
-+ }
-+#endif /* NET_21 */
-+
-+ if(sk->err) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "sk->err=%d.\n", sk->err);
-+ return sock_error(sk);
-+ }
-+
-+ if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) {
-+ return error;
-+ }
-+
-+ if(size > skb->len) {
-+ size = skb->len;
-+ }
-+#ifdef NET_21
-+ else if(size <skb->len) {
-+ msg->msg_flags |= MSG_TRUNC;
-+ }
-+#endif /* NET_21 */
-+
-+ skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size);
-+ sk->stamp=skb->stamp;
-+
-+ skb_free_datagram(sk, skb);
-+ return size;
-+}
-+
-+#ifdef NET_21
-+struct net_proto_family pfkey_family_ops = {
-+ PF_KEY,
-+ pfkey_create
-+};
-+
-+struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = {
-+#ifdef NETDEV_23
-+ family: PF_KEY,
-+ release: pfkey_release,
-+ bind: sock_no_bind,
-+ connect: sock_no_connect,
-+ socketpair: sock_no_socketpair,
-+ accept: sock_no_accept,
-+ getname: sock_no_getname,
-+ poll: datagram_poll,
-+ ioctl: sock_no_ioctl,
-+ listen: sock_no_listen,
-+ shutdown: pfkey_shutdown,
-+ setsockopt: sock_no_setsockopt,
-+ getsockopt: sock_no_getsockopt,
-+ sendmsg: pfkey_sendmsg,
-+ recvmsg: pfkey_recvmsg,
-+ mmap: sock_no_mmap,
-+#else /* NETDEV_23 */
-+ PF_KEY,
-+ sock_no_dup,
-+ pfkey_release,
-+ sock_no_bind,
-+ sock_no_connect,
-+ sock_no_socketpair,
-+ sock_no_accept,
-+ sock_no_getname,
-+ datagram_poll,
-+ sock_no_ioctl,
-+ sock_no_listen,
-+ pfkey_shutdown,
-+ sock_no_setsockopt,
-+ sock_no_getsockopt,
-+ sock_no_fcntl,
-+ pfkey_sendmsg,
-+ pfkey_recvmsg
-+#endif /* NETDEV_23 */
-+};
-+
-+#ifdef NETDEV_23
-+#include <linux/smp_lock.h>
-+SOCKOPS_WRAP(pfkey, PF_KEY);
-+#endif /* NETDEV_23 */
-+
-+#else /* NET_21 */
-+struct proto_ops pfkey_proto_ops = {
-+ PF_KEY,
-+ pfkey_create,
-+ pfkey_dup,
-+ pfkey_release,
-+ pfkey_bind,
-+ pfkey_connect,
-+ pfkey_socketpair,
-+ pfkey_accept,
-+ pfkey_getname,
-+ pfkey_select,
-+ pfkey_ioctl,
-+ pfkey_listen,
-+ pfkey_shutdown,
-+ pfkey_setsockopt,
-+ pfkey_getsockopt,
-+ pfkey_fcntl,
-+ pfkey_sendmsg,
-+ pfkey_recvmsg
-+};
-+#endif /* NET_21 */
-+
-+#ifdef CONFIG_PROC_FS
-+#ifndef PROC_FS_2325
-+DEBUG_NO_STATIC
-+#endif /* PROC_FS_2325 */
-+int
-+pfkey_get_info(char *buffer, char **start, off_t offset, int length
-+#ifndef PROC_NO_DUMMY
-+, int dummy
-+#endif /* !PROC_NO_DUMMY */
-+)
-+{
-+ const int max_content = length > 0? length-1 : 0;
-+ off_t begin=0;
-+ int len=0;
-+ struct sock *sk=pfkey_sock_list;
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(!sysctl_ipsec_debug_verbose) {
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ len+= snprintf(buffer,length,
-+ " sock pid socket next prev e n p sndbf Flags Type St\n");
-+#ifdef CONFIG_IPSEC_DEBUG
-+ } else {
-+ len+= snprintf(buffer,length,
-+ " sock pid d sleep socket next prev e r z n p sndbf stamp Flags Type St\n");
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ while(sk!=NULL) {
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(!sysctl_ipsec_debug_verbose) {
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ "%8p %5d %8p %8p %8p %d %d %d %5d %08lX %8X %2X\n",
-+ sk,
-+ key_pid(sk),
-+ sk->socket,
-+ sk->next,
-+ sk->prev,
-+ sk->err,
-+ sk->num,
-+ sk->protocol,
-+ sk->sndbuf,
-+ sk->socket->flags,
-+ sk->socket->type,
-+ sk->socket->state);
-+#ifdef CONFIG_IPSEC_DEBUG
-+ } else {
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ "%8p %5d %d %8p %8p %8p %8p %d %d %d %d %d %5d %d.%06d %08lX %8X %2X\n",
-+ sk,
-+ key_pid(sk),
-+ sk->dead,
-+ sk->sleep,
-+ sk->socket,
-+ sk->next,
-+ sk->prev,
-+ sk->err,
-+ sk->reuse,
-+ sk->zapped,
-+ sk->num,
-+ sk->protocol,
-+ sk->sndbuf,
-+ (unsigned int)sk->stamp.tv_sec,
-+ (unsigned int)sk->stamp.tv_usec,
-+ sk->socket->flags,
-+ sk->socket->type,
-+ sk->socket->state);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ if (len >= max_content) {
-+ /* we've done all that can fit -- stop loop */
-+ len = max_content; /* truncate crap */
-+ break;
-+ } else {
-+
-+ const off_t pos = begin + len; /* file position of end of what we've generated */
-+
-+ if (pos <= offset) {
-+ /* all is before first interesting character:
-+ * discard, but note where we are.
-+ */
-+ len = 0;
-+ begin = pos;
-+ }
-+ }
-+ sk=sk->next;
-+
-+ }
-+
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ return len - (offset - begin);
-+
-+}
-+
-+#ifndef PROC_FS_2325
-+DEBUG_NO_STATIC
-+#endif /* PROC_FS_2325 */
-+int
-+pfkey_supported_get_info(char *buffer, char **start, off_t offset, int length
-+#ifndef PROC_NO_DUMMY
-+, int dummy
-+#endif /* !PROC_NO_DUMMY */
-+)
-+{
-+ const int max_content = length > 0? length-1 : 0;
-+ off_t begin=0;
-+ int len=0;
-+ int satype;
-+ struct supported_list *pfkey_supported_p;
-+
-+ len += ipsec_snprintf(buffer, length,
-+ "satype exttype alg_id ivlen minbits maxbits\n");
-+
-+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
-+ pfkey_supported_p = pfkey_supported_list[satype];
-+ while(pfkey_supported_p) {
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ " %2d %2d %2d %3d %3d %3d\n",
-+ satype,
-+ pfkey_supported_p->supportedp->supported_alg_exttype,
-+ pfkey_supported_p->supportedp->supported_alg_id,
-+ pfkey_supported_p->supportedp->supported_alg_ivlen,
-+ pfkey_supported_p->supportedp->supported_alg_minbits,
-+ pfkey_supported_p->supportedp->supported_alg_maxbits);
-+
-+ if (len >= max_content) {
-+ /* we've done all that can fit -- stop loop */
-+ len = max_content; /* truncate crap */
-+ break;
-+ } else {
-+ const off_t pos = begin + len; /* file position of end of what we've generated */
-+
-+ if (pos <= offset) {
-+ /* all is before first interesting character:
-+ * discard, but note where we are.
-+ */
-+ len = 0;
-+ begin = pos;
-+ }
-+ }
-+
-+ pfkey_supported_p = pfkey_supported_p->next;
-+ }
-+ }
-+
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ return len - (offset - begin);
-+
-+}
-+
-+#ifndef PROC_FS_2325
-+DEBUG_NO_STATIC
-+#endif /* PROC_FS_2325 */
-+int
-+pfkey_registered_get_info(char *buffer, char **start, off_t offset, int length
-+#ifndef PROC_NO_DUMMY
-+, int dummy
-+#endif /* !PROC_NO_DUMMY */
-+)
-+{
-+ const int max_content = length > 0? length-1 : 0;
-+ off_t begin=0;
-+ int len=0;
-+ int satype;
-+ struct socket_list *pfkey_sockets;
-+
-+ len += ipsec_snprintf(buffer, length,
-+ "satype socket pid sk\n");
-+
-+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
-+ pfkey_sockets = pfkey_registered_sockets[satype];
-+ while(pfkey_sockets) {
-+#ifdef NET_21
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ " %2d %8p %5d %8p\n",
-+ satype,
-+ pfkey_sockets->socketp,
-+ key_pid(pfkey_sockets->socketp->sk),
-+ pfkey_sockets->socketp->sk);
-+#else /* NET_21 */
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ " %2d %8p N/A %8p\n",
-+ satype,
-+ pfkey_sockets->socketp,
-+#if 0
-+ key_pid((pfkey_sockets->socketp)->data),
-+#endif
-+ (pfkey_sockets->socketp)->data);
-+#endif /* NET_21 */
-+
-+ if (len >= max_content) {
-+ /* we've done all that can fit -- stop loop (could stop two) */
-+ len = max_content; /* truncate crap */
-+ break;
-+ } else {
-+ const off_t pos = begin + len; /* file position of end of what we've generated */
-+
-+ if (pos <= offset) {
-+ /* all is before first interesting character:
-+ * discard, but note where we are.
-+ */
-+ len = 0;
-+ begin = pos;
-+ }
-+ }
-+
-+
-+ pfkey_sockets = pfkey_sockets->next;
-+ }
-+ }
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ return len - (offset - begin);
-+}
-+
-+#ifndef PROC_FS_2325
-+struct proc_dir_entry proc_net_pfkey =
-+{
-+ 0,
-+ 6, "pf_key",
-+ S_IFREG | S_IRUGO, 1, 0, 0,
-+ 0, &proc_net_inode_operations,
-+ pfkey_get_info
-+};
-+struct proc_dir_entry proc_net_pfkey_supported =
-+{
-+ 0,
-+ 16, "pf_key_supported",
-+ S_IFREG | S_IRUGO, 1, 0, 0,
-+ 0, &proc_net_inode_operations,
-+ pfkey_supported_get_info
-+};
-+struct proc_dir_entry proc_net_pfkey_registered =
-+{
-+ 0,
-+ 17, "pf_key_registered",
-+ S_IFREG | S_IRUGO, 1, 0, 0,
-+ 0, &proc_net_inode_operations,
-+ pfkey_registered_get_info
-+};
-+#endif /* !PROC_FS_2325 */
-+#endif /* CONFIG_PROC_FS */
-+
-+DEBUG_NO_STATIC int
-+supported_add_all(int satype, struct supported supported[], int size)
-+{
-+ int i;
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:init_pfkey: "
-+ "sizeof(supported_init_<satype=%d>)[%d]/sizeof(struct supported)[%d]=%d.\n",
-+ satype,
-+ size,
-+ (int)sizeof(struct supported),
-+ (int)(size/sizeof(struct supported)));
-+
-+ for(i = 0; i < size / sizeof(struct supported); i++) {
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:init_pfkey: "
-+ "i=%d inserting satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
-+ i,
-+ satype,
-+ supported[i].supported_alg_exttype,
-+ supported[i].supported_alg_id,
-+ supported[i].supported_alg_ivlen,
-+ supported[i].supported_alg_minbits,
-+ supported[i].supported_alg_maxbits);
-+
-+ error |= pfkey_list_insert_supported(&(supported[i]),
-+ &(pfkey_supported_list[satype]));
-+ }
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+supported_remove_all(int satype)
-+{
-+ int error = 0;
-+ struct supported*supportedp;
-+
-+ while(pfkey_supported_list[satype]) {
-+ supportedp = pfkey_supported_list[satype]->supportedp;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:init_pfkey: "
-+ "removing satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
-+ satype,
-+ supportedp->supported_alg_exttype,
-+ supportedp->supported_alg_id,
-+ supportedp->supported_alg_ivlen,
-+ supportedp->supported_alg_minbits,
-+ supportedp->supported_alg_maxbits);
-+
-+ error |= pfkey_list_remove_supported(supportedp,
-+ &(pfkey_supported_list[satype]));
-+ }
-+ return error;
-+}
-+
-+int
-+pfkey_init(void)
-+{
-+ int error = 0;
-+ int i;
-+
-+ static struct supported supported_init_ah[] = {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160}
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ };
-+ static struct supported supported_init_esp[] = {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160},
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_EALG_3DESCBC, 64, 168, 168},
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ };
-+ static struct supported supported_init_ipip[] = {
-+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv4, 0, 32, 32}
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv4, 0, 128, 32}
-+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv6, 0, 32, 128}
-+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv6, 0, 128, 128}
-+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
-+ };
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ static struct supported supported_init_ipcomp[] = {
-+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_DEFLATE, 0, 1, 1}
-+ };
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#if 0
-+ printk(KERN_INFO
-+ "klips_info:pfkey_init: "
-+ "FreeS/WAN: initialising PF_KEYv2 domain sockets.\n");
-+#endif
-+
-+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
-+ pfkey_registered_sockets[i] = NULL;
-+ pfkey_supported_list[i] = NULL;
-+ }
-+
-+ error |= supported_add_all(SADB_SATYPE_AH, supported_init_ah, sizeof(supported_init_ah));
-+ error |= supported_add_all(SADB_SATYPE_ESP, supported_init_esp, sizeof(supported_init_esp));
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ error |= supported_add_all(SADB_X_SATYPE_COMP, supported_init_ipcomp, sizeof(supported_init_ipcomp));
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ error |= supported_add_all(SADB_X_SATYPE_IPIP, supported_init_ipip, sizeof(supported_init_ipip));
-+
-+#ifdef NET_21
-+ error |= sock_register(&pfkey_family_ops);
-+#else /* NET_21 */
-+ error |= sock_register(pfkey_proto_ops.family, &pfkey_proto_ops);
-+#endif /* NET_21 */
-+
-+#ifdef CONFIG_PROC_FS
-+# ifndef PROC_FS_2325
-+# ifdef PROC_FS_21
-+ error |= proc_register(proc_net, &proc_net_pfkey);
-+ error |= proc_register(proc_net, &proc_net_pfkey_supported);
-+ error |= proc_register(proc_net, &proc_net_pfkey_registered);
-+# else /* PROC_FS_21 */
-+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey);
-+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_supported);
-+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_registered);
-+# endif /* PROC_FS_21 */
-+# else /* !PROC_FS_2325 */
-+ proc_net_create ("pf_key", 0, pfkey_get_info);
-+ proc_net_create ("pf_key_supported", 0, pfkey_supported_get_info);
-+ proc_net_create ("pf_key_registered", 0, pfkey_registered_get_info);
-+# endif /* !PROC_FS_2325 */
-+#endif /* CONFIG_PROC_FS */
-+
-+ return error;
-+}
-+
-+int
-+pfkey_cleanup(void)
-+{
-+ int error = 0;
-+
-+ printk(KERN_INFO "klips_info:pfkey_cleanup: "
-+ "shutting down PF_KEY domain sockets.\n");
-+#ifdef NET_21
-+ error |= sock_unregister(PF_KEY);
-+#else /* NET_21 */
-+ error |= sock_unregister(pfkey_proto_ops.family);
-+#endif /* NET_21 */
-+
-+ error |= supported_remove_all(SADB_SATYPE_AH);
-+ error |= supported_remove_all(SADB_SATYPE_ESP);
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ error |= supported_remove_all(SADB_X_SATYPE_COMP);
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ error |= supported_remove_all(SADB_X_SATYPE_IPIP);
-+
-+#ifdef CONFIG_PROC_FS
-+# ifndef PROC_FS_2325
-+ if (proc_net_unregister(proc_net_pfkey.low_ino) != 0)
-+ printk("klips_debug:pfkey_cleanup: "
-+ "cannot unregister /proc/net/pf_key\n");
-+ if (proc_net_unregister(proc_net_pfkey_supported.low_ino) != 0)
-+ printk("klips_debug:pfkey_cleanup: "
-+ "cannot unregister /proc/net/pf_key_supported\n");
-+ if (proc_net_unregister(proc_net_pfkey_registered.low_ino) != 0)
-+ printk("klips_debug:pfkey_cleanup: "
-+ "cannot unregister /proc/net/pf_key_registered\n");
-+# else /* !PROC_FS_2325 */
-+ proc_net_remove ("pf_key");
-+ proc_net_remove ("pf_key_supported");
-+ proc_net_remove ("pf_key_registered");
-+# endif /* !PROC_FS_2325 */
-+#endif /* CONFIG_PROC_FS */
-+
-+ /* other module unloading cleanup happens here */
-+ return error;
-+}
-+
-+#ifdef MODULE
-+#if 0
-+int
-+init_module(void)
-+{
-+ pfkey_init();
-+ return 0;
-+}
-+
-+void
-+cleanup_module(void)
-+{
-+ pfkey_cleanup();
-+}
-+#endif /* 0 */
-+#else /* MODULE */
-+void
-+pfkey_proto_init(struct net_proto *pro)
-+{
-+ pfkey_init();
-+}
-+#endif /* MODULE */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.81 2004/04/25 21:23:11 ken
-+ * Pull in dhr's changes from FreeS/WAN 2.06
-+ *
-+ * Revision 1.80 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.79.4.1 2003/12/22 15:25:52 jjo
-+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.79 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.78.4.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.78 2003/04/03 17:38:09 rgb
-+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
-+ *
-+ * Revision 1.77 2002/10/17 16:49:36 mcr
-+ * sock->ops should reference the unwrapped options so that
-+ * we get hacked in locking on SMP systems.
-+ *
-+ * Revision 1.76 2002/10/12 23:11:53 dhr
-+ *
-+ * [KenB + DHR] more 64-bit cleanup
-+ *
-+ * Revision 1.75 2002/09/20 05:01:57 rgb
-+ * Added memory allocation debugging.
-+ *
-+ * Revision 1.74 2002/09/19 02:42:50 mcr
-+ * do not define the pfkey_ops function for now.
-+ *
-+ * Revision 1.73 2002/09/17 17:29:23 mcr
-+ * #if 0 out some dead code - pfkey_ops is never used as written.
-+ *
-+ * Revision 1.72 2002/07/24 18:44:54 rgb
-+ * Type fiddling to tame ia64 compiler.
-+ *
-+ * Revision 1.71 2002/05/23 07:14:11 rgb
-+ * Cleaned up %p variants to 0p%p for test suite cleanup.
-+ *
-+ * Revision 1.70 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.69 2002/04/24 07:36:33 mcr
-+ * Moved from ./klips/net/ipsec/pfkey_v2.c,v
-+ *
-+ * Revision 1.68 2002/03/08 01:15:17 mcr
-+ * put some internal structure only debug messages behind
-+ * && sysctl_ipsec_debug_verbose.
-+ *
-+ * Revision 1.67 2002/01/29 17:17:57 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.66 2002/01/29 04:00:54 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.65 2002/01/29 02:13:18 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.64 2001/11/26 09:23:51 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.61.2.1 2001/09/25 02:28:44 mcr
-+ * cleaned up includes.
-+ *
-+ * Revision 1.63 2001/11/12 19:38:00 rgb
-+ * Continue trying other sockets even if one fails and return only original
-+ * error.
-+ *
-+ * Revision 1.62 2001/10/18 04:45:22 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/freeswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.61 2001/09/20 15:32:59 rgb
-+ * Min/max cleanup.
-+ *
-+ * Revision 1.60 2001/06/14 19:35:12 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.59 2001/06/13 15:35:48 rgb
-+ * Fixed #endif comments.
-+ *
-+ * Revision 1.58 2001/05/04 16:37:24 rgb
-+ * Remove erroneous checking of return codes for proc_net_* in 2.4.
-+ *
-+ * Revision 1.57 2001/05/03 19:43:36 rgb
-+ * Initialise error return variable.
-+ * Check error return codes in startup and shutdown.
-+ * Standardise on SENDERR() macro.
-+ *
-+ * Revision 1.56 2001/04/21 23:05:07 rgb
-+ * Define out skb->used for 2.4 kernels.
-+ *
-+ * Revision 1.55 2001/02/28 05:03:28 rgb
-+ * Clean up and rationalise startup messages.
-+ *
-+ * Revision 1.54 2001/02/27 22:24:55 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.53 2001/02/27 06:48:18 rgb
-+ * Fixed pfkey socket unregister log message to reflect type and function.
-+ *
-+ * Revision 1.52 2001/02/26 22:34:38 rgb
-+ * Fix error return code that was getting overwritten by the error return
-+ * code of an upmsg.
-+ *
-+ * Revision 1.51 2001/01/30 23:42:47 rgb
-+ * Allow pfkey msgs from pid other than user context required for ACQUIRE
-+ * and subsequent ADD or UDATE.
-+ *
-+ * Revision 1.50 2001/01/23 20:22:59 rgb
-+ * 2.4 fix to remove removed is_clone member.
-+ *
-+ * Revision 1.49 2000/11/06 04:33:47 rgb
-+ * Changed non-exported functions to DEBUG_NO_STATIC.
-+ *
-+ * Revision 1.48 2000/09/29 19:47:41 rgb
-+ * Update copyright.
-+ *
-+ * Revision 1.47 2000/09/22 04:23:04 rgb
-+ * Added more debugging to pfkey_upmsg() call from pfkey_sendmsg() error.
-+ *
-+ * Revision 1.46 2000/09/21 04:20:44 rgb
-+ * Fixed array size off-by-one error. (Thanks Svenning!)
-+ *
-+ * Revision 1.45 2000/09/20 04:01:26 rgb
-+ * Changed static functions to DEBUG_NO_STATIC for revealing function names
-+ * in oopsen.
-+ *
-+ * Revision 1.44 2000/09/19 00:33:17 rgb
-+ * 2.0 fixes.
-+ *
-+ * Revision 1.43 2000/09/16 01:28:13 rgb
-+ * Fixed use of 0 in p format warning.
-+ *
-+ * Revision 1.42 2000/09/16 01:09:41 rgb
-+ * Fixed debug format warning for pointers that was expecting ints.
-+ *
-+ * Revision 1.41 2000/09/13 15:54:00 rgb
-+ * Rewrote pfkey_get_info(), added pfkey_{supported,registered}_get_info().
-+ * Moved supported algos add and remove to functions.
-+ *
-+ * Revision 1.40 2000/09/12 18:49:28 rgb
-+ * Added IPIP tunnel and IPCOMP register support.
-+ *
-+ * Revision 1.39 2000/09/12 03:23:49 rgb
-+ * Converted #if0 debugs to sysctl.
-+ * Removed debug_pfkey initialisations that prevented no_debug loading or
-+ * linking.
-+ *
-+ * Revision 1.38 2000/09/09 06:38:02 rgb
-+ * Return positive errno in pfkey_reply error message.
-+ *
-+ * Revision 1.37 2000/09/08 19:19:09 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ * Clean-up of long-unused crud...
-+ * Create pfkey error message on on failure.
-+ * Give pfkey_list_{insert,remove}_{socket,supported}() some error
-+ * checking.
-+ *
-+ * Revision 1.36 2000/09/01 18:49:38 rgb
-+ * Reap experimental NET_21_ bits.
-+ * Turned registered sockets list into an array of one list per satype.
-+ * Remove references to deprecated sklist_{insert,remove}_socket.
-+ * Removed leaking socket debugging code.
-+ * Removed duplicate pfkey_insert_socket in pfkey_create.
-+ * Removed all references to pfkey msg->msg_name, since it is not used for
-+ * pfkey.
-+ * Added a supported algorithms array lists, one per satype and registered
-+ * existing algorithms.
-+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
-+ * list.
-+ * Only send pfkey_expire() messages to sockets registered for that satype.
-+ *
-+ * Revision 1.35 2000/08/24 17:03:00 rgb
-+ * Corrected message size error return code for PF_KEYv2.
-+ * Removed downward error prohibition.
-+ *
-+ * Revision 1.34 2000/08/21 16:32:26 rgb
-+ * Re-formatted for cosmetic consistency and readability.
-+ *
-+ * Revision 1.33 2000/08/20 21:38:24 rgb
-+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
-+ * Extended the upward message initiation of pfkey_sendmsg(). (Momchil)
-+ *
-+ * Revision 1.32 2000/07/28 14:58:31 rgb
-+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
-+ *
-+ * Revision 1.31 2000/05/16 03:04:00 rgb
-+ * Updates for 2.3.99pre8 from MB.
-+ *
-+ * Revision 1.30 2000/05/10 19:22:21 rgb
-+ * Use sklist private functions for 2.3.xx compatibility.
-+ *
-+ * Revision 1.29 2000/03/22 16:17:03 rgb
-+ * Fixed SOCKOPS_WRAPPED macro for SMP (MB).
-+ *
-+ * Revision 1.28 2000/02/21 19:30:45 rgb
-+ * Removed references to pkt_bridged for 2.3.47 compatibility.
-+ *
-+ * Revision 1.27 2000/02/14 21:07:00 rgb
-+ * Fixed /proc/net/pf-key legend spacing.
-+ *
-+ * Revision 1.26 2000/01/22 03:46:59 rgb
-+ * Fixed pfkey error return mechanism so that we are able to free the
-+ * local copy of the pfkey_msg, plugging a memory leak and silencing
-+ * the bad object free complaints.
-+ *
-+ * Revision 1.25 2000/01/21 06:19:44 rgb
-+ * Moved pfkey_list_remove_socket() calls to before MOD_USE_DEC_COUNT.
-+ * Added debugging to pfkey_upmsg.
-+ *
-+ * Revision 1.24 2000/01/10 16:38:23 rgb
-+ * MB fixups for 2.3.x.
-+ *
-+ * Revision 1.23 1999/12/09 23:22:16 rgb
-+ * Added more instrumentation for debugging 2.0 socket
-+ * selection/reading.
-+ * Removed erroneous 2.0 wait==NULL check bug in select.
-+ *
-+ * Revision 1.22 1999/12/08 20:32:16 rgb
-+ * Tidied up 2.0.xx support, after major pfkey work, eliminating
-+ * msg->msg_name twiddling in the process, since it is not defined
-+ * for PF_KEYv2.
-+ *
-+ * Revision 1.21 1999/12/01 22:17:19 rgb
-+ * Set skb->dev to zero on new skb in case it is a reused skb.
-+ * Added check for skb_put overflow and freeing to avoid upmsg on error.
-+ * Added check for wrong pfkey version and freeing to avoid upmsg on
-+ * error.
-+ * Shut off content dumping in pfkey_destroy.
-+ * Added debugging message for size of buffer allocated for upmsg.
-+ *
-+ * Revision 1.20 1999/11/27 12:11:00 rgb
-+ * Minor clean-up, enabling quiet operation of pfkey if desired.
-+ *
-+ * Revision 1.19 1999/11/25 19:04:21 rgb
-+ * Update proc_fs code for pfkey to use dynamic registration.
-+ *
-+ * Revision 1.18 1999/11/25 09:07:17 rgb
-+ * Implemented SENDERR macro for propagating error codes.
-+ * Fixed error return code bug.
-+ *
-+ * Revision 1.17 1999/11/23 23:07:20 rgb
-+ * Change name of pfkey_msg_parser to pfkey_msg_interp since it no longer
-+ * parses. (PJO)
-+ * Sort out pfkey and freeswan headers, putting them in a library path.
-+ *
-+ * Revision 1.16 1999/11/20 22:00:22 rgb
-+ * Moved socketlist type declarations and prototypes for shared use.
-+ * Renamed reformatted and generically extended for use by other socket
-+ * lists pfkey_{del,add}_open_socket to pfkey_list_{remove,insert}_socket.
-+ *
-+ * Revision 1.15 1999/11/18 04:15:09 rgb
-+ * Make pfkey_data_ready temporarily available for 2.2.x testing.
-+ * Clean up pfkey_destroy_socket() debugging statements.
-+ * Add Peter Onion's code to send messages up to all listening sockets.
-+ * Changed all occurrences of #include "../../../lib/freeswan.h"
-+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
-+ * klips/net/ipsec/Makefile.
-+ * Replaced all kernel version macros to shorter, readable form.
-+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
-+ *
-+ * Revision 1.14 1999/11/17 16:01:00 rgb
-+ * Make pfkey_data_ready temporarily available for 2.2.x testing.
-+ * Clean up pfkey_destroy_socket() debugging statements.
-+ * Add Peter Onion's code to send messages up to all listening sockets.
-+ * Changed #include "../../../lib/freeswan.h" to #include <freeswan.h>
-+ * which works due to -Ilibfreeswan in the klips/net/ipsec/Makefile.
-+ *
-+ * Revision 1.13 1999/10/27 19:59:51 rgb
-+ * Removed af_unix comments that are no longer relevant.
-+ * Added debug prink statements.
-+ * Added to the /proc output in pfkey_get_info.
-+ * Made most functions non-static to enable oops tracing.
-+ * Re-enable skb dequeueing and freeing.
-+ * Fix skb_alloc() and skb_put() size bug in pfkey_upmsg().
-+ *
-+ * Revision 1.12 1999/10/26 17:05:42 rgb
-+ * Complete re-ordering based on proto_ops structure order.
-+ * Separated out proto_ops structures for 2.0.x and 2.2.x for clarity.
-+ * Simplification to use built-in socket ops where possible for 2.2.x.
-+ * Add shorter macros for compiler directives to visually clean-up.
-+ * Add lots of sk skb dequeueing debugging statements.
-+ * Added to the /proc output in pfkey_get_info.
-+ *
-+ * Revision 1.11 1999/09/30 02:55:10 rgb
-+ * Bogus skb detection.
-+ * Fix incorrect /proc/net/ipsec-eroute printk message.
-+ *
-+ * Revision 1.10 1999/09/21 15:22:13 rgb
-+ * Temporary fix while I figure out the right way to destroy sockets.
-+ *
-+ * Revision 1.9 1999/07/08 19:19:44 rgb
-+ * Fix pointer format warning.
-+ * Fix missing member error under 2.0.xx kernels.
-+ *
-+ * Revision 1.8 1999/06/13 07:24:04 rgb
-+ * Add more debugging.
-+ *
-+ * Revision 1.7 1999/06/10 05:24:17 rgb
-+ * Clarified compiler directives.
-+ * Renamed variables to reduce confusion.
-+ * Used sklist_*_socket() kernel functions to simplify 2.2.x socket support.
-+ * Added lots of sanity checking.
-+ *
-+ * Revision 1.6 1999/06/03 18:59:50 rgb
-+ * More updates to 2.2.x socket support. Almost works, oops at end of call.
-+ *
-+ * Revision 1.5 1999/05/25 22:44:05 rgb
-+ * Start fixing 2.2 sockets.
-+ *
-+ * Revision 1.4 1999/04/29 15:21:34 rgb
-+ * Move log to the end of the file.
-+ * Eliminate min/max redefinition in #include <net/tcp.h>.
-+ * Correct path for pfkey #includes
-+ * Standardise an error return method.
-+ * Add debugging instrumentation.
-+ * Move message type checking to pfkey_msg_parse().
-+ * Add check for errno incorrectly set.
-+ * Add check for valid PID.
-+ * Add check for reserved illegally set.
-+ * Add check for message out of bounds.
-+ *
-+ * Revision 1.3 1999/04/15 17:58:07 rgb
-+ * Add RCSID labels.
-+ *
-+ * Revision 1.2 1999/04/15 15:37:26 rgb
-+ * Forward check changes from POST1_00 branch.
-+ *
-+ * Revision 1.1.2.2 1999/04/13 20:37:12 rgb
-+ * Header Title correction.
-+ *
-+ * Revision 1.1.2.1 1999/03/26 20:58:55 rgb
-+ * Add pfkeyv2 support to KLIPS.
-+ *
-+ *
-+ * RFC 2367
-+ * PF_KEY_v2 Key Management API
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/pfkey_v2_ext_process.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,922 @@
-+/*
-+ * @(#) RFC2367 PF_KEYv2 Key management API message parser
-+ * Copyright (C) 1998-2003 Richard Guy Briggs.
-+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
-+ */
-+
-+char pfkey_v2_ext_process_c_version[] = "$Id$";
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+
-+#include <openswan.h>
-+
-+#include <crypto/des.h>
-+
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define ip_chk_addr inet_addr_type
-+# define IS_MYADDR RTN_LOCAL
-+#endif
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+#ifdef NETLINK_SOCK
-+# include <linux/netlink.h>
-+#else
-+# include <net/netlink.h>
-+#endif
-+
-+#include <linux/random.h> /* get_random_bytes() */
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_ah.h"
-+#include "openswan/ipsec_esp.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h"
-+#include "openswan/ipcomp.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+#include "openswan/ipsec_alg.h"
-+
-+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
-+
-+int
-+pfkey_sa_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
-+ int error = 0;
-+ struct ipsec_sa* ipsp;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sa_process: .\n");
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sa_process: "
-+ "extr or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_ext->sadb_ext_type) {
-+ case SADB_EXT_SA:
-+ ipsp = extr->ips;
-+ break;
-+ case SADB_X_EXT_SA2:
-+ if(extr->ips2 == NULL) {
-+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
-+ }
-+ if(extr->ips2 == NULL) {
-+ SENDERR(-error);
-+ }
-+ ipsp = extr->ips2;
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sa_process: "
-+ "invalid exttype=%d.\n",
-+ pfkey_ext->sadb_ext_type);
-+ SENDERR(EINVAL);
-+ }
-+
-+ ipsp->ips_said.spi = pfkey_sa->sadb_sa_spi;
-+ ipsp->ips_replaywin = pfkey_sa->sadb_sa_replay;
-+ ipsp->ips_state = pfkey_sa->sadb_sa_state;
-+ ipsp->ips_flags = pfkey_sa->sadb_sa_flags;
-+ ipsp->ips_replaywin_lastseq = ipsp->ips_replaywin_bitmap = 0;
-+ ipsp->ips_ref_rel = pfkey_sa->sadb_x_sa_ref;
-+
-+ switch(ipsp->ips_said.proto) {
-+ case IPPROTO_AH:
-+ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
-+ ipsp->ips_encalg = SADB_EALG_NONE;
-+ break;
-+ case IPPROTO_ESP:
-+ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
-+ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
-+#ifdef CONFIG_IPSEC_ALG
-+ ipsec_alg_sa_init(ipsp);
-+#endif /* CONFIG_IPSEC_ALG */
-+ break;
-+ case IPPROTO_IPIP:
-+ ipsp->ips_authalg = AH_NONE;
-+ ipsp->ips_encalg = ESP_NONE;
-+ break;
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ case IPPROTO_COMP:
-+ ipsp->ips_authalg = AH_NONE;
-+ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
-+ break;
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ case IPPROTO_INT:
-+ ipsp->ips_authalg = AH_NONE;
-+ ipsp->ips_encalg = ESP_NONE;
-+ break;
-+ case 0:
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sa_process: "
-+ "unknown proto=%d.\n",
-+ ipsp->ips_said.proto);
-+ SENDERR(EINVAL);
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_lifetime_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_lifetime_process: .\n");
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_lifetime_process: "
-+ "extr or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_lifetime->sadb_lifetime_exttype) {
-+ case SADB_EXT_LIFETIME_CURRENT:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_lifetime_process: "
-+ "lifetime_current not supported yet.\n");
-+ SENDERR(EINVAL);
-+ break;
-+ case SADB_EXT_LIFETIME_HARD:
-+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_allocations,
-+ pfkey_lifetime->sadb_lifetime_allocations);
-+
-+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_bytes,
-+ pfkey_lifetime->sadb_lifetime_bytes);
-+
-+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_addtime,
-+ pfkey_lifetime->sadb_lifetime_addtime);
-+
-+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_usetime,
-+ pfkey_lifetime->sadb_lifetime_usetime);
-+
-+ break;
-+
-+ case SADB_EXT_LIFETIME_SOFT:
-+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_allocations,
-+ pfkey_lifetime->sadb_lifetime_allocations);
-+
-+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_bytes,
-+ pfkey_lifetime->sadb_lifetime_bytes);
-+
-+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_addtime,
-+ pfkey_lifetime->sadb_lifetime_addtime);
-+
-+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_usetime,
-+ pfkey_lifetime->sadb_lifetime_usetime);
-+
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_lifetime_process: "
-+ "invalid exttype=%d.\n",
-+ pfkey_ext->sadb_ext_type);
-+ SENDERR(EINVAL);
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_address_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ int saddr_len = 0;
-+ char ipaddr_txt[ADDRTOA_BUF];
-+ unsigned char **sap;
-+ unsigned short * portp = 0;
-+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
-+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
-+ struct ipsec_sa* ipsp;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process:\n");
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "extr or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(s->sa_family) {
-+ case AF_INET:
-+ saddr_len = sizeof(struct sockaddr_in);
-+ addrtoa(((struct sockaddr_in*)s)->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt));
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found address family=%d, AF_INET, %s.\n",
-+ s->sa_family,
-+ ipaddr_txt);
-+ break;
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+ case AF_INET6:
-+ saddr_len = sizeof(struct sockaddr_in6);
-+ break;
-+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "s->sa_family=%d not supported.\n",
-+ s->sa_family);
-+ SENDERR(EPFNOSUPPORT);
-+ }
-+
-+ switch(pfkey_address->sadb_address_exttype) {
-+ case SADB_EXT_ADDRESS_SRC:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found src address.\n");
-+ sap = (unsigned char **)&(extr->ips->ips_addr_s);
-+ extr->ips->ips_addr_s_size = saddr_len;
-+ break;
-+ case SADB_EXT_ADDRESS_DST:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found dst address.\n");
-+ sap = (unsigned char **)&(extr->ips->ips_addr_d);
-+ extr->ips->ips_addr_d_size = saddr_len;
-+ break;
-+ case SADB_EXT_ADDRESS_PROXY:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found proxy address.\n");
-+ sap = (unsigned char **)&(extr->ips->ips_addr_p);
-+ extr->ips->ips_addr_p_size = saddr_len;
-+ break;
-+ case SADB_X_EXT_ADDRESS_DST2:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found 2nd dst address.\n");
-+ if(extr->ips2 == NULL) {
-+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
-+ }
-+ if(extr->ips2 == NULL) {
-+ SENDERR(-error);
-+ }
-+ sap = (unsigned char **)&(extr->ips2->ips_addr_d);
-+ extr->ips2->ips_addr_d_size = saddr_len;
-+ break;
-+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found src flow address.\n");
-+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
-+ SENDERR(ENOMEM);
-+ }
-+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_src);
-+ portp = &(extr->eroute->er_eaddr.sen_sport);
-+ break;
-+ case SADB_X_EXT_ADDRESS_DST_FLOW:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found dst flow address.\n");
-+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
-+ SENDERR(ENOMEM);
-+ }
-+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_dst);
-+ portp = &(extr->eroute->er_eaddr.sen_dport);
-+ break;
-+ case SADB_X_EXT_ADDRESS_SRC_MASK:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found src mask address.\n");
-+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
-+ SENDERR(ENOMEM);
-+ }
-+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_src);
-+ portp = &(extr->eroute->er_emask.sen_sport);
-+ break;
-+ case SADB_X_EXT_ADDRESS_DST_MASK:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found dst mask address.\n");
-+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
-+ SENDERR(ENOMEM);
-+ }
-+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_dst);
-+ portp = &(extr->eroute->er_emask.sen_dport);
-+ break;
-+#ifdef NAT_TRAVERSAL
-+ case SADB_X_EXT_NAT_T_OA:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found NAT-OA address.\n");
-+ sap = (unsigned char **)&(extr->ips->ips_natt_oa);
-+ extr->ips->ips_natt_oa_size = saddr_len;
-+ break;
-+#endif
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "unrecognised ext_type=%d.\n",
-+ pfkey_address->sadb_address_exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_address->sadb_address_exttype) {
-+ case SADB_EXT_ADDRESS_SRC:
-+ case SADB_EXT_ADDRESS_DST:
-+ case SADB_EXT_ADDRESS_PROXY:
-+ case SADB_X_EXT_ADDRESS_DST2:
-+#ifdef NAT_TRAVERSAL
-+ case SADB_X_EXT_NAT_T_OA:
-+#endif
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "allocating %d bytes for saddr.\n",
-+ saddr_len);
-+ if(!(*sap = kmalloc(saddr_len, GFP_KERNEL))) {
-+ SENDERR(ENOMEM);
-+ }
-+ memcpy(*sap, s, saddr_len);
-+ break;
-+ default:
-+ if(s->sa_family != AF_INET) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "s->sa_family=%d not supported.\n",
-+ s->sa_family);
-+ SENDERR(EPFNOSUPPORT);
-+ }
-+ (unsigned long)(*sap) = ((struct sockaddr_in*)s)->sin_addr.s_addr;
-+ if (portp != 0)
-+ *portp = ((struct sockaddr_in*)s)->sin_port;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(extr->eroute) {
-+ char buf1[64], buf2[64];
-+ if (debug_pfkey) {
-+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
-+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
-+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_parse: "
-+ "extr->eroute set to %s:%d->%s:%d\n",
-+ buf1,
-+ ntohs(extr->eroute->er_eaddr.sen_sport),
-+ buf2,
-+ ntohs(extr->eroute->er_eaddr.sen_dport));
-+ }
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ }
-+
-+ ipsp = extr->ips;
-+ switch(pfkey_address->sadb_address_exttype) {
-+ case SADB_X_EXT_ADDRESS_DST2:
-+ ipsp = extr->ips2;
-+ case SADB_EXT_ADDRESS_DST:
-+ if(s->sa_family == AF_INET) {
-+ ipsp->ips_said.dst.u.v4.sin_addr.s_addr = ((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr.s_addr;
-+ ipsp->ips_said.dst.u.v4.sin_family = AF_INET;
-+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
-+ 0,
-+ ipaddr_txt,
-+ sizeof(ipaddr_txt));
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "ips_said.dst set to %s.\n",
-+ ipaddr_txt);
-+ } else {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "uh, ips_said.dst doesn't do address family=%d yet, said will be invalid.\n",
-+ s->sa_family);
-+ }
-+ default:
-+ break;
-+ }
-+
-+ /* XXX check if port!=0 */
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: successful.\n");
-+ errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_key_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_key_process: .\n");
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_key_process: "
-+ "extr or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_key->sadb_key_exttype) {
-+ case SADB_EXT_KEY_AUTH:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_key_process: "
-+ "allocating %d bytes for authkey.\n",
-+ DIVUP(pfkey_key->sadb_key_bits, 8));
-+ if(!(extr->ips->ips_key_a = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_key_process: "
-+ "memory allocation error.\n");
-+ SENDERR(ENOMEM);
-+ }
-+ extr->ips->ips_key_bits_a = pfkey_key->sadb_key_bits;
-+ extr->ips->ips_key_a_size = DIVUP(pfkey_key->sadb_key_bits, 8);
-+ memcpy(extr->ips->ips_key_a,
-+ (char*)pfkey_key + sizeof(struct sadb_key),
-+ extr->ips->ips_key_a_size);
-+ break;
-+ case SADB_EXT_KEY_ENCRYPT: /* Key(s) */
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_key_process: "
-+ "allocating %d bytes for enckey.\n",
-+ DIVUP(pfkey_key->sadb_key_bits, 8));
-+ if(!(extr->ips->ips_key_e = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_key_process: "
-+ "memory allocation error.\n");
-+ SENDERR(ENOMEM);
-+ }
-+ extr->ips->ips_key_bits_e = pfkey_key->sadb_key_bits;
-+ extr->ips->ips_key_e_size = DIVUP(pfkey_key->sadb_key_bits, 8);
-+ memcpy(extr->ips->ips_key_e,
-+ (char*)pfkey_key + sizeof(struct sadb_key),
-+ extr->ips->ips_key_e_size);
-+ break;
-+ default:
-+ SENDERR(EINVAL);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_key_process: "
-+ "success.\n");
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_ident_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
-+ int data_len;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ident_process: .\n");
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ident_process: "
-+ "extr or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_ident->sadb_ident_exttype) {
-+ case SADB_EXT_IDENTITY_SRC:
-+ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
-+
-+ extr->ips->ips_ident_s.type = pfkey_ident->sadb_ident_type;
-+ extr->ips->ips_ident_s.id = pfkey_ident->sadb_ident_id;
-+ extr->ips->ips_ident_s.len = pfkey_ident->sadb_ident_len;
-+ if(data_len) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ident_process: "
-+ "allocating %d bytes for ident_s.\n",
-+ data_len);
-+ if(!(extr->ips->ips_ident_s.data
-+ = kmalloc(data_len, GFP_KERNEL))) {
-+ SENDERR(ENOMEM);
-+ }
-+ memcpy(extr->ips->ips_ident_s.data,
-+ (char*)pfkey_ident + sizeof(struct sadb_ident),
-+ data_len);
-+ } else {
-+ extr->ips->ips_ident_s.data = NULL;
-+ }
-+ break;
-+ case SADB_EXT_IDENTITY_DST: /* Identity(ies) */
-+ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
-+
-+ extr->ips->ips_ident_d.type = pfkey_ident->sadb_ident_type;
-+ extr->ips->ips_ident_d.id = pfkey_ident->sadb_ident_id;
-+ extr->ips->ips_ident_d.len = pfkey_ident->sadb_ident_len;
-+ if(data_len) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ident_process: "
-+ "allocating %d bytes for ident_d.\n",
-+ data_len);
-+ if(!(extr->ips->ips_ident_d.data
-+ = kmalloc(data_len, GFP_KERNEL))) {
-+ SENDERR(ENOMEM);
-+ }
-+ memcpy(extr->ips->ips_ident_d.data,
-+ (char*)pfkey_ident + sizeof(struct sadb_ident),
-+ data_len);
-+ } else {
-+ extr->ips->ips_ident_d.data = NULL;
-+ }
-+ break;
-+ default:
-+ SENDERR(EINVAL);
-+ }
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_sens_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sens_process: "
-+ "Sorry, I can't process exttype=%d yet.\n",
-+ pfkey_ext->sadb_ext_type);
-+ SENDERR(EINVAL); /* don't process these yet */
-+ errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_prop_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_prop_process: "
-+ "Sorry, I can't process exttype=%d yet.\n",
-+ pfkey_ext->sadb_ext_type);
-+ SENDERR(EINVAL); /* don't process these yet */
-+
-+ errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_supported_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_supported_process: "
-+ "Sorry, I can't process exttype=%d yet.\n",
-+ pfkey_ext->sadb_ext_type);
-+ SENDERR(EINVAL); /* don't process these yet */
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_spirange_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_spirange_process: .\n");
-+/* errlab: */
-+ return error;
-+}
-+
-+int
-+pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_kmprivate_process: "
-+ "Sorry, I can't process exttype=%d yet.\n",
-+ pfkey_ext->sadb_ext_type);
-+ SENDERR(EINVAL); /* don't process these yet */
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_satype_process: .\n");
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_satype_process: "
-+ "extr or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(extr->ips2 == NULL) {
-+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
-+ }
-+ if(extr->ips2 == NULL) {
-+ SENDERR(-error);
-+ }
-+ if(!(extr->ips2->ips_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_satype_process: "
-+ "proto lookup from satype=%d failed.\n",
-+ pfkey_x_satype->sadb_x_satype_satype);
-+ SENDERR(EINVAL);
-+ }
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_satype_process: "
-+ "protocol==%d decoded from satype==%d(%s).\n",
-+ extr->ips2->ips_said.proto,
-+ pfkey_x_satype->sadb_x_satype_satype,
-+ satype2name(pfkey_x_satype->sadb_x_satype_satype));
-+
-+errlab:
-+ return error;
-+}
-+
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+int
-+pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)pfkey_ext;
-+
-+ if(!pfkey_x_nat_t_type) {
-+ printk("klips_debug:pfkey_x_nat_t_type_process: "
-+ "null pointer passed in\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_nat_t_type_process: %d.\n",
-+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_nat_t_type_process: "
-+ "extr or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_x_nat_t_type->sadb_x_nat_t_type_type) {
-+ case ESPINUDP_WITH_NON_IKE: /* with Non-IKE (older version) */
-+ case ESPINUDP_WITH_NON_ESP: /* with Non-ESP */
-+
-+ extr->ips->ips_natt_type = pfkey_x_nat_t_type->sadb_x_nat_t_type_type;
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_nat_t_type_process: "
-+ "unknown type %d.\n",
-+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
-+ SENDERR(EINVAL);
-+ break;
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)pfkey_ext;
-+
-+ if(!pfkey_x_nat_t_port) {
-+ printk("klips_debug:pfkey_x_nat_t_port_process: "
-+ "null pointer passed in\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_nat_t_port_process: %d/%d.\n",
-+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype,
-+ pfkey_x_nat_t_port->sadb_x_nat_t_port_port);
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_nat_t_type_process: "
-+ "extr or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype) {
-+ case SADB_X_EXT_NAT_T_SPORT:
-+ extr->ips->ips_natt_sport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
-+ break;
-+ case SADB_X_EXT_NAT_T_DPORT:
-+ extr->ips->ips_natt_dport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_nat_t_port_process: "
-+ "unknown exttype %d.\n",
-+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype);
-+ SENDERR(EINVAL);
-+ break;
-+ }
-+
-+errlab:
-+ return error;
-+}
-+#endif
-+
-+int
-+pfkey_x_debug_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
-+
-+ if(!pfkey_x_debug) {
-+ printk("klips_debug:pfkey_x_debug_process: "
-+ "null pointer passed in\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_debug_process: .\n");
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(pfkey_x_debug->sadb_x_debug_netlink >>
-+ (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 - 1)) {
-+ pfkey_x_debug->sadb_x_debug_netlink &=
-+ ~(1 << (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 -1));
-+ debug_tunnel |= pfkey_x_debug->sadb_x_debug_tunnel;
-+ debug_netlink |= pfkey_x_debug->sadb_x_debug_netlink;
-+ debug_xform |= pfkey_x_debug->sadb_x_debug_xform;
-+ debug_eroute |= pfkey_x_debug->sadb_x_debug_eroute;
-+ debug_spi |= pfkey_x_debug->sadb_x_debug_spi;
-+ debug_radij |= pfkey_x_debug->sadb_x_debug_radij;
-+ debug_esp |= pfkey_x_debug->sadb_x_debug_esp;
-+ debug_ah |= pfkey_x_debug->sadb_x_debug_ah;
-+ debug_rcv |= pfkey_x_debug->sadb_x_debug_rcv;
-+ debug_pfkey |= pfkey_x_debug->sadb_x_debug_pfkey;
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ sysctl_ipsec_debug_ipcomp |= pfkey_x_debug->sadb_x_debug_ipcomp;
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ sysctl_ipsec_debug_verbose |= pfkey_x_debug->sadb_x_debug_verbose;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_debug_process: "
-+ "set\n");
-+ } else {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_debug_process: "
-+ "unset\n");
-+ debug_tunnel &= pfkey_x_debug->sadb_x_debug_tunnel;
-+ debug_netlink &= pfkey_x_debug->sadb_x_debug_netlink;
-+ debug_xform &= pfkey_x_debug->sadb_x_debug_xform;
-+ debug_eroute &= pfkey_x_debug->sadb_x_debug_eroute;
-+ debug_spi &= pfkey_x_debug->sadb_x_debug_spi;
-+ debug_radij &= pfkey_x_debug->sadb_x_debug_radij;
-+ debug_esp &= pfkey_x_debug->sadb_x_debug_esp;
-+ debug_ah &= pfkey_x_debug->sadb_x_debug_ah;
-+ debug_rcv &= pfkey_x_debug->sadb_x_debug_rcv;
-+ debug_pfkey &= pfkey_x_debug->sadb_x_debug_pfkey;
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ sysctl_ipsec_debug_ipcomp &= pfkey_x_debug->sadb_x_debug_ipcomp;
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ sysctl_ipsec_debug_verbose &= pfkey_x_debug->sadb_x_debug_verbose;
-+ }
-+#else /* CONFIG_IPSEC_DEBUG */
-+ printk("klips_debug:pfkey_x_debug_process: "
-+ "debugging not enabled\n");
-+ SENDERR(EINVAL);
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+errlab:
-+ return error;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.15 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.14 2004/02/03 03:13:59 mcr
-+ * no longer #ifdef out NON_ESP mode. That was a mistake.
-+ *
-+ * Revision 1.13 2003/12/15 18:13:12 mcr
-+ * when compiling with NAT traversal, don't assume that the
-+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
-+ * is set.
-+ *
-+ * Revision 1.12.2.1 2003/12/22 15:25:52 jjo
-+ * Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.12 2003/12/10 01:14:27 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.11 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.10.4.2 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.10.4.1 2003/09/21 13:59:56 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.10 2003/02/06 01:51:41 rgb
-+ * Removed no longer relevant comment
-+ *
-+ * Revision 1.9 2003/01/30 02:32:44 rgb
-+ *
-+ * Transmit error code through to caller from callee for better diagnosis of problems.
-+ *
-+ * Revision 1.8 2002/12/13 22:42:22 mcr
-+ * restored sa_ref code
-+ *
-+ * Revision 1.7 2002/12/13 22:40:48 mcr
-+ * temporarily removed sadb_x_sa_ref reference for 2.xx
-+ *
-+ * Revision 1.6 2002/10/05 05:02:58 dhr
-+ *
-+ * C labels go on statements
-+ *
-+ * Revision 1.5 2002/09/20 15:41:08 rgb
-+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
-+ * Added sadb_x_sa_ref to struct sadb_sa.
-+ *
-+ * Revision 1.4 2002/09/20 05:02:02 rgb
-+ * Added memory allocation debugging.
-+ *
-+ * Revision 1.3 2002/07/24 18:44:54 rgb
-+ * Type fiddling to tame ia64 compiler.
-+ *
-+ * Revision 1.2 2002/05/27 18:55:03 rgb
-+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
-+ *
-+ * Revision 1.1 2002/05/14 02:33:51 rgb
-+ * Moved all the extension processing functions to pfkey_v2_ext_process.c.
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/pfkey_v2_parser.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,4018 @@
-+/*
-+ * @(#) RFC2367 PF_KEYv2 Key management API message parser
-+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
-+ */
-+
-+char pfkey_v2_parser_c_version[] = "$Id$";
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+
-+#include <openswan.h>
-+
-+#include <crypto/des.h>
-+
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define ip_chk_addr inet_addr_type
-+# define IS_MYADDR RTN_LOCAL
-+#endif
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+#ifdef NETLINK_SOCK
-+# include <linux/netlink.h>
-+#else
-+# include <net/netlink.h>
-+#endif
-+
-+#include <linux/random.h> /* get_random_bytes() */
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_ah.h"
-+#include "openswan/ipsec_esp.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h"
-+#include "openswan/ipcomp.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+#include "openswan/ipsec_alg.h"
-+
-+
-+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
-+
-+struct sklist_t {
-+ struct socket *sk;
-+ struct sklist_t* next;
-+} pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev;
-+
-+__u32 pfkey_msg_seq = 0;
-+
-+
-+#if 0
-+#define DUMP_SAID dump_said(&extr->ips->ips_said, __LINE__)
-+#define DUMP_SAID2 dump_said(&extr.ips->ips_said, __LINE__)
-+static void dump_said(ip_said *s, int line)
-+{
-+ char msa[SATOT_BUF];
-+ size_t msa_len;
-+
-+ msa_len = satot(s, 0, msa, sizeof(msa));
-+
-+ printk("line: %d msa: %s\n", line, msa);
-+}
-+#endif
-+
-+
-+int
-+pfkey_alloc_eroute(struct eroute** eroute)
-+{
-+ int error = 0;
-+ if(*eroute) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_alloc_eroute: "
-+ "eroute struct already allocated\n");
-+ SENDERR(EEXIST);
-+ }
-+
-+ if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_alloc_eroute: "
-+ "memory allocation error\n");
-+ SENDERR(ENOMEM);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_alloc_eroute: "
-+ "allocating %lu bytes for an eroute at 0p%p\n",
-+ (unsigned long) sizeof(**eroute), *eroute);
-+
-+ memset((caddr_t)*eroute, 0, sizeof(**eroute));
-+ (*eroute)->er_eaddr.sen_len =
-+ (*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap);
-+ (*eroute)->er_eaddr.sen_family =
-+ (*eroute)->er_emask.sen_family = AF_ENCAP;
-+ (*eroute)->er_eaddr.sen_type = SENT_IP4;
-+ (*eroute)->er_emask.sen_type = 255;
-+ (*eroute)->er_pid = 0;
-+ (*eroute)->er_count = 0;
-+ (*eroute)->er_lasttime = jiffies/HZ;
-+
-+ errlab:
-+ return(error);
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_protocol_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data *extr)
-+{
-+ int error = 0;
-+ struct sadb_protocol * p = (struct sadb_protocol *)pfkey_ext;
-+
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_protocol_process: %p\n", extr);
-+
-+ if (extr == 0) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_protocol_process:"
-+ "extr is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+ if (extr->eroute == 0) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_protocol_process:"
-+ "extr->eroute is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ extr->eroute->er_eaddr.sen_proto = p->sadb_protocol_proto;
-+ extr->eroute->er_emask.sen_proto = p->sadb_protocol_proto ? ~0:0;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_protocol_process: protocol = %d.\n",
-+ p->sadb_protocol_proto);
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_ipsec_sa_init(struct ipsec_sa *ipsp, struct sadb_ext **extensions)
-+{
-+ int i;
-+ int error = 0;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+ char ipaddr_txt[ADDRTOA_BUF];
-+ char ipaddr2_txt[ADDRTOA_BUF];
-+#if defined (CONFIG_IPSEC_AUTH_HMAC_MD5) || defined (CONFIG_IPSEC_AUTH_HMAC_SHA1)
-+ unsigned char kb[AHMD596_BLKLEN];
-+#endif
-+#ifdef CONFIG_IPSEC_ALG
-+ struct ipsec_alg_enc *ixt_e = NULL;
-+ struct ipsec_alg_auth *ixt_a = NULL;
-+#endif /* CONFIG_IPSEC_ALG */
-+
-+ if(ipsp == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "ipsp is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ sa_len = satot(&ipsp->ips_said, 0, sa, sizeof(sa));
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "(pfkey defined) called for SA:%s\n",
-+ sa_len ? sa : " (error)");
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "calling init routine of %s%s%s\n",
-+ IPS_XFORM_NAME(ipsp));
-+
-+ switch(ipsp->ips_said.proto) {
-+
-+#ifdef CONFIG_IPSEC_IPIP
-+ case IPPROTO_IPIP: {
-+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr,
-+ 0,
-+ ipaddr_txt, sizeof(ipaddr_txt));
-+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
-+ 0,
-+ ipaddr2_txt, sizeof(ipaddr_txt));
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "(pfkey defined) IPIP ipsec_sa set for %s->%s.\n",
-+ ipaddr_txt,
-+ ipaddr2_txt);
-+ }
-+ break;
-+#endif /* !CONFIG_IPSEC_IPIP */
-+#ifdef CONFIG_IPSEC_AH
-+ case IPPROTO_AH:
-+ switch(ipsp->ips_authalg) {
-+# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5: {
-+ unsigned char *akp;
-+ unsigned int aks;
-+ MD5_CTX *ictx;
-+ MD5_CTX *octx;
-+
-+ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
-+ ipsp->ips_key_bits_a, AHMD596_KLEN * 8);
-+ SENDERR(EINVAL);
-+ }
-+
-+# if KLIPS_DIVULGE_HMAC_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
-+# endif /* KLIPS_DIVULGE_HMAC_KEY */
-+
-+ ipsp->ips_auth_bits = AHMD596_ALEN * 8;
-+
-+ /* save the pointer to the key material */
-+ akp = ipsp->ips_key_a;
-+ aks = ipsp->ips_key_a_size;
-+
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "allocating %lu bytes for md5_ctx.\n",
-+ (unsigned long) sizeof(struct md5_ctx));
-+ if((ipsp->ips_key_a = (caddr_t)
-+ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
-+ ipsp->ips_key_a = akp;
-+ SENDERR(ENOMEM);
-+ }
-+ ipsp->ips_key_a_size = sizeof(struct md5_ctx);
-+
-+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
-+ kb[i] = akp[i] ^ HMAC_IPAD;
-+ }
-+ for (; i < AHMD596_BLKLEN; i++) {
-+ kb[i] = HMAC_IPAD;
-+ }
-+
-+ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
-+ MD5Init(ictx);
-+ MD5Update(ictx, kb, AHMD596_BLKLEN);
-+
-+ for (i = 0; i < AHMD596_BLKLEN; i++) {
-+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
-+ }
-+
-+ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
-+ MD5Init(octx);
-+ MD5Update(octx, kb, AHMD596_BLKLEN);
-+
-+# if KLIPS_DIVULGE_HMAC_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
-+ ((__u32*)ictx)[0],
-+ ((__u32*)ictx)[1],
-+ ((__u32*)ictx)[2],
-+ ((__u32*)ictx)[3],
-+ ((__u32*)octx)[0],
-+ ((__u32*)octx)[1],
-+ ((__u32*)octx)[2],
-+ ((__u32*)octx)[3] );
-+# endif /* KLIPS_DIVULGE_HMAC_KEY */
-+
-+ /* zero key buffer -- paranoid */
-+ memset(akp, 0, aks);
-+ kfree(akp);
-+ }
-+ break;
-+# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA: {
-+ unsigned char *akp;
-+ unsigned int aks;
-+ SHA1_CTX *ictx;
-+ SHA1_CTX *octx;
-+
-+ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
-+ ipsp->ips_key_bits_a, AHSHA196_KLEN * 8);
-+ SENDERR(EINVAL);
-+ }
-+
-+# if KLIPS_DIVULGE_HMAC_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
-+# endif /* KLIPS_DIVULGE_HMAC_KEY */
-+
-+ ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
-+
-+ /* save the pointer to the key material */
-+ akp = ipsp->ips_key_a;
-+ aks = ipsp->ips_key_a_size;
-+
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "allocating %lu bytes for sha1_ctx.\n",
-+ (unsigned long) sizeof(struct sha1_ctx));
-+ if((ipsp->ips_key_a = (caddr_t)
-+ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
-+ ipsp->ips_key_a = akp;
-+ SENDERR(ENOMEM);
-+ }
-+ ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
-+
-+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
-+ kb[i] = akp[i] ^ HMAC_IPAD;
-+ }
-+ for (; i < AHMD596_BLKLEN; i++) {
-+ kb[i] = HMAC_IPAD;
-+ }
-+
-+ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
-+ SHA1Init(ictx);
-+ SHA1Update(ictx, kb, AHSHA196_BLKLEN);
-+
-+ for (i = 0; i < AHSHA196_BLKLEN; i++) {
-+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
-+ }
-+
-+ octx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->octx);
-+ SHA1Init(octx);
-+ SHA1Update(octx, kb, AHSHA196_BLKLEN);
-+
-+# if KLIPS_DIVULGE_HMAC_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
-+ ((__u32*)ictx)[0],
-+ ((__u32*)ictx)[1],
-+ ((__u32*)ictx)[2],
-+ ((__u32*)ictx)[3],
-+ ((__u32*)octx)[0],
-+ ((__u32*)octx)[1],
-+ ((__u32*)octx)[2],
-+ ((__u32*)octx)[3] );
-+# endif /* KLIPS_DIVULGE_HMAC_KEY */
-+ /* zero key buffer -- paranoid */
-+ memset(akp, 0, aks);
-+ kfree(akp);
-+ }
-+ break;
-+# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "authalg=%d support not available in the kernel",
-+ ipsp->ips_authalg);
-+ SENDERR(EINVAL);
-+ }
-+ break;
-+#endif /* CONFIG_IPSEC_AH */
-+#ifdef CONFIG_IPSEC_ESP
-+ case IPPROTO_ESP: {
-+#if defined (CONFIG_IPSEC_AUTH_HMAC_MD5) || defined (CONFIG_IPSEC_AUTH_HMAC_SHA1)
-+ unsigned char *akp;
-+ unsigned int aks;
-+#endif
-+#if defined (CONFIG_IPSEC_ENC_3DES)
-+ unsigned char *ekp;
-+ unsigned int eks;
-+#endif
-+
-+ ipsp->ips_iv_size = 0;
-+#ifdef CONFIG_IPSEC_ALG
-+ if ((ixt_e=ipsp->ips_alg_enc)) {
-+ ipsp->ips_iv_size = ixt_e->ixt_ivlen/8;
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ipsp->ips_encalg) {
-+# ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+# endif /* CONFIG_IPSEC_ENC_3DES */
-+# if defined(CONFIG_IPSEC_ENC_3DES)
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "allocating %u bytes for iv.\n",
-+ EMT_ESPDES_IV_SZ);
-+ if((ipsp->ips_iv = (caddr_t)
-+ kmalloc((ipsp->ips_iv_size = EMT_ESPDES_IV_SZ), GFP_ATOMIC)) == NULL) {
-+ SENDERR(ENOMEM);
-+ }
-+ prng_bytes(&ipsec_prng, (char *)ipsp->ips_iv, EMT_ESPDES_IV_SZ);
-+ ipsp->ips_iv_bits = ipsp->ips_iv_size * 8;
-+ ipsp->ips_iv_size = EMT_ESPDES_IV_SZ;
-+ break;
-+# endif /* defined(CONFIG_IPSEC_ENC_3DES) */
-+ case ESP_NONE:
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "encalg=%d support not available in the kernel",
-+ ipsp->ips_encalg);
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* Create IV */
-+ if (ipsp->ips_iv_size) {
-+ if((ipsp->ips_iv = (caddr_t)
-+ kmalloc(ipsp->ips_iv_size, GFP_ATOMIC)) == NULL) {
-+ SENDERR(ENOMEM);
-+ }
-+ prng_bytes(&ipsec_prng, (char *)ipsp->ips_iv, ipsp->ips_iv_size);
-+ ipsp->ips_iv_bits = ipsp->ips_iv_size * 8;
-+ }
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if (ixt_e) {
-+ if ((error=ipsec_alg_enc_key_create(ipsp)) < 0)
-+ SENDERR(-error);
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ipsp->ips_encalg) {
-+# ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+ if(ipsp->ips_key_bits_e != (EMT_ESP3DES_KEY_SZ * 8)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "incorrect encryption key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
-+ ipsp->ips_key_bits_e, EMT_ESP3DES_KEY_SZ * 8);
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* save encryption key pointer */
-+ ekp = ipsp->ips_key_e;
-+ eks = ipsp->ips_key_e_size;
-+
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "allocating %lu bytes for 3des.\n",
-+ (unsigned long) (3 * sizeof(struct des_eks)));
-+ if((ipsp->ips_key_e = (caddr_t)
-+ kmalloc(3 * sizeof(struct des_eks), GFP_ATOMIC)) == NULL) {
-+ ipsp->ips_key_e = ekp;
-+ SENDERR(ENOMEM);
-+ }
-+ ipsp->ips_key_e_size = 3 * sizeof(struct des_eks);
-+
-+ for(i = 0; i < 3; i++) {
-+#if KLIPS_DIVULGE_CYPHER_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "3des key %d/3 is 0x%08x%08x\n",
-+ i + 1,
-+ ntohl(*((__u32 *)ekp + i * 2)),
-+ ntohl(*((__u32 *)ekp + i * 2 + 1)));
-+# endif
-+#if KLIPS_FIXES_DES_PARITY
-+ /* force parity */
-+ des_set_odd_parity((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i));
-+#endif
-+ error = des_set_key((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i),
-+ ((struct des_eks *)(ipsp->ips_key_e))[i].ks);
-+ if (error == -1)
-+ printk("klips_debug:pfkey_ipsec_sa_init: "
-+ "parity error in des key %d/3\n",
-+ i + 1);
-+ else if (error == -2)
-+ printk("klips_debug:pfkey_ipsec_sa_init: "
-+ "illegal weak des key %d/3\n", i + 1);
-+ if (error) {
-+ memset(ekp, 0, eks);
-+ kfree(ekp);
-+ SENDERR(EINVAL);
-+ }
-+ }
-+
-+ /* paranoid */
-+ memset(ekp, 0, eks);
-+ kfree(ekp);
-+ break;
-+# endif /* CONFIG_IPSEC_ENC_3DES */
-+ case ESP_NONE:
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "encalg=%d support not available in the kernel",
-+ ipsp->ips_encalg);
-+ SENDERR(EINVAL);
-+ }
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if ((ixt_a=ipsp->ips_alg_auth)) {
-+ if ((error=ipsec_alg_auth_key_create(ipsp)) < 0)
-+ SENDERR(-error);
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+
-+ switch(ipsp->ips_authalg) {
-+# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5: {
-+ MD5_CTX *ictx;
-+ MD5_CTX *octx;
-+
-+ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
-+ ipsp->ips_key_bits_a,
-+ AHMD596_KLEN * 8);
-+ SENDERR(EINVAL);
-+ }
-+
-+# if KLIPS_DIVULGE_HMAC_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
-+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+0)),
-+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+1)),
-+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+2)),
-+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+3)));
-+# endif /* KLIPS_DIVULGE_HMAC_KEY */
-+ ipsp->ips_auth_bits = AHMD596_ALEN * 8;
-+
-+ /* save the pointer to the key material */
-+ akp = ipsp->ips_key_a;
-+ aks = ipsp->ips_key_a_size;
-+
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "allocating %lu bytes for md5_ctx.\n",
-+ (unsigned long) sizeof(struct md5_ctx));
-+ if((ipsp->ips_key_a = (caddr_t)
-+ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
-+ ipsp->ips_key_a = akp;
-+ SENDERR(ENOMEM);
-+ }
-+ ipsp->ips_key_a_size = sizeof(struct md5_ctx);
-+
-+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
-+ kb[i] = akp[i] ^ HMAC_IPAD;
-+ }
-+ for (; i < AHMD596_BLKLEN; i++) {
-+ kb[i] = HMAC_IPAD;
-+ }
-+
-+ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
-+ MD5Init(ictx);
-+ MD5Update(ictx, kb, AHMD596_BLKLEN);
-+
-+ for (i = 0; i < AHMD596_BLKLEN; i++) {
-+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
-+ }
-+
-+ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
-+ MD5Init(octx);
-+ MD5Update(octx, kb, AHMD596_BLKLEN);
-+
-+# if KLIPS_DIVULGE_HMAC_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
-+ ((__u32*)ictx)[0],
-+ ((__u32*)ictx)[1],
-+ ((__u32*)ictx)[2],
-+ ((__u32*)ictx)[3],
-+ ((__u32*)octx)[0],
-+ ((__u32*)octx)[1],
-+ ((__u32*)octx)[2],
-+ ((__u32*)octx)[3] );
-+# endif /* KLIPS_DIVULGE_HMAC_KEY */
-+ /* paranoid */
-+ memset(akp, 0, aks);
-+ kfree(akp);
-+ break;
-+ }
-+# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA: {
-+ SHA1_CTX *ictx;
-+ SHA1_CTX *octx;
-+
-+ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
-+ ipsp->ips_key_bits_a,
-+ AHSHA196_KLEN * 8);
-+ SENDERR(EINVAL);
-+ }
-+
-+# if KLIPS_DIVULGE_HMAC_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
-+# endif /* KLIPS_DIVULGE_HMAC_KEY */
-+ ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
-+
-+ /* save the pointer to the key material */
-+ akp = ipsp->ips_key_a;
-+ aks = ipsp->ips_key_a_size;
-+
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "allocating %lu bytes for sha1_ctx.\n",
-+ (unsigned long) sizeof(struct sha1_ctx));
-+ if((ipsp->ips_key_a = (caddr_t)
-+ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
-+ ipsp->ips_key_a = akp;
-+ SENDERR(ENOMEM);
-+ }
-+ ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
-+
-+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
-+ kb[i] = akp[i] ^ HMAC_IPAD;
-+ }
-+ for (; i < AHMD596_BLKLEN; i++) {
-+ kb[i] = HMAC_IPAD;
-+ }
-+
-+ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
-+ SHA1Init(ictx);
-+ SHA1Update(ictx, kb, AHSHA196_BLKLEN);
-+
-+ for (i = 0; i < AHSHA196_BLKLEN; i++) {
-+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
-+ }
-+
-+ octx = &((struct sha1_ctx*)(ipsp->ips_key_a))->octx;
-+ SHA1Init(octx);
-+ SHA1Update(octx, kb, AHSHA196_BLKLEN);
-+
-+# if KLIPS_DIVULGE_HMAC_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
-+ ((__u32*)ictx)[0],
-+ ((__u32*)ictx)[1],
-+ ((__u32*)ictx)[2],
-+ ((__u32*)ictx)[3],
-+ ((__u32*)octx)[0],
-+ ((__u32*)octx)[1],
-+ ((__u32*)octx)[2],
-+ ((__u32*)octx)[3] );
-+# endif /* KLIPS_DIVULGE_HMAC_KEY */
-+ memset(akp, 0, aks);
-+ kfree(akp);
-+ break;
-+ }
-+# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ case AH_NONE:
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "authalg=%d support not available in the kernel.\n",
-+ ipsp->ips_authalg);
-+ SENDERR(EINVAL);
-+ }
-+ }
-+ break;
-+#endif /* !CONFIG_IPSEC_ESP */
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ case IPPROTO_COMP:
-+ ipsp->ips_comp_adapt_tries = 0;
-+ ipsp->ips_comp_adapt_skip = 0;
-+ ipsp->ips_comp_ratio_cbytes = 0;
-+ ipsp->ips_comp_ratio_dbytes = 0;
-+ break;
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "proto=%d unknown.\n",
-+ ipsp->ips_said.proto);
-+ SENDERR(EINVAL);
-+ }
-+
-+ errlab:
-+ return(error);
-+}
-+
-+
-+int
-+pfkey_safe_build(int error, struct sadb_ext *extensions[SADB_MAX+1])
-+{
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: "
-+ "error=%d\n",
-+ error);
-+ if (!error) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
-+ "success.\n");
-+ return 1;
-+ } else {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
-+ "caught error %d\n",
-+ error);
-+ pfkey_extensions_free(extensions);
-+ return 0;
-+ }
-+}
-+
-+
-+DEBUG_NO_STATIC int
-+pfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L);
-+ int found_avail = 0;
-+ struct ipsec_sa *ipsq;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_getspi_parse: .\n");
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ if(extr == NULL || extr->ips == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_getspi_parse: "
-+ "error, extr or extr->ipsec_sa pointer NULL\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(extensions[SADB_EXT_SPIRANGE]) {
-+ minspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_min;
-+ maxspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_max;
-+ }
-+
-+ if(maxspi == minspi) {
-+ extr->ips->ips_said.spi = maxspi;
-+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
-+ if(ipsq != NULL) {
-+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
-+ ipsec_sa_put(ipsq);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_getspi_parse: "
-+ "EMT_GETSPI found an old ipsec_sa for SA: %s, delete it first.\n",
-+ sa_len ? sa : " (error)");
-+ SENDERR(EEXIST);
-+ } else {
-+ found_avail = 1;
-+ }
-+ } else {
-+ int i = 0;
-+ __u32 rand_val;
-+ __u32 spi_diff;
-+ while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) {
-+ prng_bytes(&ipsec_prng, (char *) &(rand_val),
-+ ( (spi_diff < (2^8)) ? 1 :
-+ ( (spi_diff < (2^16)) ? 2 :
-+ ( (spi_diff < (2^24)) ? 3 :
-+ 4 ) ) ) );
-+ extr->ips->ips_said.spi = htonl(ntohl(minspi) +
-+ (rand_val %
-+ (spi_diff + 1)));
-+ i++;
-+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
-+ if(ipsq == NULL) {
-+ found_avail = 1;
-+ } else {
-+ ipsec_sa_put(ipsq);
-+ }
-+ }
-+ }
-+
-+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
-+
-+ if (!found_avail) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_getspi_parse: "
-+ "found an old ipsec_sa for SA: %s, delete it first.\n",
-+ sa_len ? sa : " (error)");
-+ SENDERR(EEXIST);
-+ }
-+
-+ if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) {
-+ extr->ips->ips_flags |= EMT_INBOUND;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_getspi_parse: "
-+ "existing ipsec_sa not found (this is good) for SA: %s, %s-bound, allocating.\n",
-+ sa_len ? sa : " (error)",
-+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
-+
-+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
-+ extr->ips->ips_rcvif = NULL;
-+ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies/HZ;
-+
-+ extr->ips->ips_state = SADB_SASTATE_LARVAL;
-+
-+ if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
-+ extr->ips->ips_life.ipl_allocations.ipl_count += 1;
-+ }
-+
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_GETSPI,
-+ satype,
-+ 0,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ 0,
-+ SADB_SASTATE_LARVAL,
-+ 0,
-+ 0,
-+ 0,
-+ extr->ips->ips_ref),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_s),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_d),
-+ extensions_reply) )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
-+ "failed to build the getspi reply message extensions\n");
-+ goto errlab;
-+ }
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
-+ "failed to build the getspi reply message\n");
-+ SENDERR(-error);
-+ }
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
-+ "sending up getspi reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
-+ "sending up getspi reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ if((error = ipsec_sa_add(extr->ips))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
-+ "failed to add the larval SA=%s with error=%d.\n",
-+ sa_len ? sa : " (error)",
-+ error);
-+ SENDERR(-error);
-+ }
-+ extr->ips = NULL;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_getspi_parse: "
-+ "successful for SA: %s\n",
-+ sa_len ? sa : " (error)");
-+
-+ errlab:
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct ipsec_sa* ipsq;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ struct ipsec_sa *nat_t_ips_saved = NULL;
-+#endif
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: .\n");
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: "
-+ "error, sa_state=%d must be MATURE=%d\n",
-+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
-+ SADB_SASTATE_MATURE);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(extr == NULL || extr->ips == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: "
-+ "error, extr or extr->ips pointer NULL\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
-+
-+ spin_lock_bh(&tdb_lock);
-+
-+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
-+ if (ipsq == NULL) {
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: "
-+ "reserved ipsec_sa for SA: %s not found. Call SADB_GETSPI first or call SADB_ADD instead.\n",
-+ sa_len ? sa : " (error)");
-+ SENDERR(ENOENT);
-+ }
-+
-+ if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) {
-+ extr->ips->ips_flags |= EMT_INBOUND;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: "
-+ "existing ipsec_sa found (this is good) for SA: %s, %s-bound, updating.\n",
-+ sa_len ? sa : " (error)",
-+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if (extr->ips->ips_natt_sport || extr->ips->ips_natt_dport) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: only updating NAT-T ports "
-+ "(%u:%u -> %u:%u)\n",
-+ ipsq->ips_natt_sport, ipsq->ips_natt_dport,
-+ extr->ips->ips_natt_sport, extr->ips->ips_natt_dport);
-+
-+ if (extr->ips->ips_natt_sport) {
-+ ipsq->ips_natt_sport = extr->ips->ips_natt_sport;
-+ if (ipsq->ips_addr_s->sa_family == AF_INET) {
-+ ((struct sockaddr_in *)(ipsq->ips_addr_s))->sin_port = htons(extr->ips->ips_natt_sport);
-+ }
-+ }
-+
-+ if (extr->ips->ips_natt_dport) {
-+ ipsq->ips_natt_dport = extr->ips->ips_natt_dport;
-+ if (ipsq->ips_addr_d->sa_family == AF_INET) {
-+ ((struct sockaddr_in *)(ipsq->ips_addr_d))->sin_port = htons(extr->ips->ips_natt_dport);
-+ }
-+ }
-+
-+ nat_t_ips_saved = extr->ips;
-+ extr->ips = ipsq;
-+ }
-+ else {
-+#endif
-+
-+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
-+ extr->ips->ips_rcvif = NULL;
-+ if ((error = pfkey_ipsec_sa_init(extr->ips, extensions))) {
-+ ipsec_sa_put(ipsq);
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: "
-+ "not successful for SA: %s, deleting.\n",
-+ sa_len ? sa : " (error)");
-+ SENDERR(-error);
-+ }
-+
-+ extr->ips->ips_life.ipl_addtime.ipl_count = ipsq->ips_life.ipl_addtime.ipl_count;
-+ ipsec_sa_put(ipsq);
-+ if((error = ipsec_sa_delchain(ipsq))) {
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: "
-+ "error=%d, trouble deleting intermediate ipsec_sa for SA=%s.\n",
-+ error,
-+ sa_len ? sa : " (error)");
-+ SENDERR(-error);
-+ }
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ }
-+#endif
-+
-+ spin_unlock_bh(&tdb_lock);
-+
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_UPDATE,
-+ satype,
-+ 0,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ extr->ips->ips_replaywin,
-+ extr->ips->ips_state,
-+ extr->ips->ips_authalg,
-+ extr->ips->ips_encalg,
-+ extr->ips->ips_flags,
-+ extr->ips->ips_ref),
-+ extensions_reply)
-+ /* The 3 lifetime extentions should only be sent if non-zero. */
-+ && (extensions[SADB_EXT_LIFETIME_HARD]
-+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
-+ SADB_EXT_LIFETIME_HARD,
-+ extr->ips->ips_life.ipl_allocations.ipl_hard,
-+ extr->ips->ips_life.ipl_bytes.ipl_hard,
-+ extr->ips->ips_life.ipl_addtime.ipl_hard,
-+ extr->ips->ips_life.ipl_usetime.ipl_hard,
-+ extr->ips->ips_life.ipl_packets.ipl_hard),
-+ extensions_reply) : 1)
-+ && (extensions[SADB_EXT_LIFETIME_SOFT]
-+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
-+ SADB_EXT_LIFETIME_SOFT,
-+ extr->ips->ips_life.ipl_allocations.ipl_count,
-+ extr->ips->ips_life.ipl_bytes.ipl_count,
-+ extr->ips->ips_life.ipl_addtime.ipl_count,
-+ extr->ips->ips_life.ipl_usetime.ipl_count,
-+ extr->ips->ips_life.ipl_packets.ipl_count),
-+ extensions_reply) : 1)
-+ && (extr->ips->ips_life.ipl_allocations.ipl_count
-+ || extr->ips->ips_life.ipl_bytes.ipl_count
-+ || extr->ips->ips_life.ipl_addtime.ipl_count
-+ || extr->ips->ips_life.ipl_usetime.ipl_count
-+ || extr->ips->ips_life.ipl_packets.ipl_count
-+
-+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
-+ SADB_EXT_LIFETIME_CURRENT,
-+ extr->ips->ips_life.ipl_allocations.ipl_count,
-+ extr->ips->ips_life.ipl_bytes.ipl_count,
-+ extr->ips->ips_life.ipl_addtime.ipl_count,
-+ extr->ips->ips_life.ipl_usetime.ipl_count,
-+ extr->ips->ips_life.ipl_packets.ipl_count),
-+ extensions_reply) : 1)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_s),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_d),
-+ extensions_reply)
-+ && (extr->ips->ips_ident_s.data
-+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
-+ SADB_EXT_IDENTITY_SRC,
-+ extr->ips->ips_ident_s.type,
-+ extr->ips->ips_ident_s.id,
-+ extr->ips->ips_ident_s.len,
-+ extr->ips->ips_ident_s.data),
-+ extensions_reply) : 1)
-+ && (extr->ips->ips_ident_d.data
-+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
-+ SADB_EXT_IDENTITY_DST,
-+ extr->ips->ips_ident_d.type,
-+ extr->ips->ips_ident_d.id,
-+ extr->ips->ips_ident_d.len,
-+ extr->ips->ips_ident_d.data),
-+ extensions_reply) : 1)
-+#if 0
-+ /* FIXME: This won't work yet because I have not finished
-+ it. */
-+ && (extr->ips->ips_sens_
-+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
-+ extr->ips->ips_sens_dpd,
-+ extr->ips->ips_sens_sens_level,
-+ extr->ips->ips_sens_sens_len,
-+ extr->ips->ips_sens_sens_bitmap,
-+ extr->ips->ips_sens_integ_level,
-+ extr->ips->ips_sens_integ_len,
-+ extr->ips->ips_sens_integ_bitmap),
-+ extensions_reply) : 1)
-+#endif
-+ )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
-+ "failed to build the update reply message extensions\n");
-+ SENDERR(-error);
-+ }
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
-+ "failed to build the update reply message\n");
-+ SENDERR(-error);
-+ }
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
-+ "sending up update reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
-+ "sending up update reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if (nat_t_ips_saved) {
-+ /**
-+ * As we _really_ update existing SA, we keep tdbq and need to delete
-+ * parsed ips (nat_t_ips_saved, was extr->ips).
-+ *
-+ * goto errlab with extr->ips = nat_t_ips_saved will free it.
-+ */
-+
-+ extr->ips = nat_t_ips_saved;
-+
-+ error = 0;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse (NAT-T ports): "
-+ "successful for SA: %s\n",
-+ sa_len ? sa : " (error)");
-+
-+ goto errlab;
-+ }
-+#endif
-+
-+ if((error = ipsec_sa_add(extr->ips))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
-+ "failed to update the mature SA=%s with error=%d.\n",
-+ sa_len ? sa : " (error)",
-+ error);
-+ SENDERR(-error);
-+ }
-+ extr->ips = NULL;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: "
-+ "successful for SA: %s\n",
-+ sa_len ? sa : " (error)");
-+
-+ errlab:
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_add_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct ipsec_sa* ipsq;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_add_parse: .\n");
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_add_parse: "
-+ "error, sa_state=%d must be MATURE=%d\n",
-+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
-+ SADB_SASTATE_MATURE);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_add_parse: "
-+ "extr or extr->ips pointer NULL\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
-+
-+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
-+ if(ipsq != NULL) {
-+ ipsec_sa_put(ipsq);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_add_parse: "
-+ "found an old ipsec_sa for SA%s, delete it first.\n",
-+ sa_len ? sa : " (error)");
-+ SENDERR(EEXIST);
-+ }
-+
-+ if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) {
-+ extr->ips->ips_flags |= EMT_INBOUND;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_add_parse: "
-+ "existing ipsec_sa not found (this is good) for SA%s, %s-bound, allocating.\n",
-+ sa_len ? sa : " (error)",
-+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
-+
-+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
-+ extr->ips->ips_rcvif = NULL;
-+
-+ if ((error = pfkey_ipsec_sa_init(extr->ips, extensions))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_add_parse: "
-+ "not successful for SA: %s, deleting.\n",
-+ sa_len ? sa : " (error)");
-+ SENDERR(-error);
-+ }
-+
-+ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies / HZ;
-+ if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
-+ extr->ips->ips_life.ipl_allocations.ipl_count += 1;
-+ }
-+
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_ADD,
-+ satype,
-+ 0,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ extr->ips->ips_replaywin,
-+ extr->ips->ips_state,
-+ extr->ips->ips_authalg,
-+ extr->ips->ips_encalg,
-+ extr->ips->ips_flags,
-+ extr->ips->ips_ref),
-+ extensions_reply)
-+ /* The 3 lifetime extentions should only be sent if non-zero. */
-+ && (extensions[SADB_EXT_LIFETIME_HARD]
-+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
-+ SADB_EXT_LIFETIME_HARD,
-+ extr->ips->ips_life.ipl_allocations.ipl_hard,
-+ extr->ips->ips_life.ipl_bytes.ipl_hard,
-+ extr->ips->ips_life.ipl_addtime.ipl_hard,
-+ extr->ips->ips_life.ipl_usetime.ipl_hard,
-+ extr->ips->ips_life.ipl_packets.ipl_hard),
-+ extensions_reply) : 1)
-+ && (extensions[SADB_EXT_LIFETIME_SOFT]
-+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
-+ SADB_EXT_LIFETIME_SOFT,
-+ extr->ips->ips_life.ipl_allocations.ipl_soft,
-+ extr->ips->ips_life.ipl_bytes.ipl_soft,
-+ extr->ips->ips_life.ipl_addtime.ipl_soft,
-+ extr->ips->ips_life.ipl_usetime.ipl_soft,
-+ extr->ips->ips_life.ipl_packets.ipl_soft),
-+ extensions_reply) : 1)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_s),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_d),
-+ extensions_reply)
-+ && (extr->ips->ips_ident_s.data
-+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
-+ SADB_EXT_IDENTITY_SRC,
-+ extr->ips->ips_ident_s.type,
-+ extr->ips->ips_ident_s.id,
-+ extr->ips->ips_ident_s.len,
-+ extr->ips->ips_ident_s.data),
-+ extensions_reply) : 1)
-+ && (extr->ips->ips_ident_d.data
-+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
-+ SADB_EXT_IDENTITY_DST,
-+ extr->ips->ips_ident_d.type,
-+ extr->ips->ips_ident_d.id,
-+ extr->ips->ips_ident_d.len,
-+ extr->ips->ips_ident_d.data),
-+ extensions_reply) : 1)
-+#if 0
-+ /* FIXME: This won't work yet because I have not finished
-+ it. */
-+ && (extr->ips->ips_sens_
-+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
-+ extr->ips->ips_sens_dpd,
-+ extr->ips->ips_sens_sens_level,
-+ extr->ips->ips_sens_sens_len,
-+ extr->ips->ips_sens_sens_bitmap,
-+ extr->ips->ips_sens_integ_level,
-+ extr->ips->ips_sens_integ_len,
-+ extr->ips->ips_sens_integ_bitmap),
-+ extensions_reply) : 1)
-+#endif
-+ )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
-+ "failed to build the add reply message extensions\n");
-+ SENDERR(-error);
-+ }
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
-+ "failed to build the add reply message\n");
-+ SENDERR(-error);
-+ }
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
-+ "sending up add reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
-+ "sending up add reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ if((error = ipsec_sa_add(extr->ips))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
-+ "failed to add the mature SA=%s with error=%d.\n",
-+ sa_len ? sa : " (error)",
-+ error);
-+ SENDERR(-error);
-+ }
-+ extr->ips = NULL;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_add_parse: "
-+ "successful for SA: %s\n",
-+ sa_len ? sa : " (error)");
-+
-+ errlab:
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_delete_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ struct ipsec_sa *ipsp;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+ int error = 0;
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_delete_parse: .\n");
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_delete_parse: "
-+ "extr or extr->ips pointer NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
-+
-+ spin_lock_bh(&tdb_lock);
-+
-+ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
-+ if (ipsp == NULL) {
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_delete_parse: "
-+ "ipsec_sa not found for SA:%s, could not delete.\n",
-+ sa_len ? sa : " (error)");
-+ SENDERR(ESRCH);
-+ }
-+
-+ ipsec_sa_put(ipsp);
-+ if((error = ipsec_sa_delchain(ipsp))) {
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_delete_parse: "
-+ "error=%d returned trying to delete ipsec_sa for SA:%s.\n",
-+ error,
-+ sa_len ? sa : " (error)");
-+ SENDERR(-error);
-+ }
-+ spin_unlock_bh(&tdb_lock);
-+
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_DELETE,
-+ satype,
-+ 0,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ 0,
-+ 0,
-+ 0,
-+ 0,
-+ 0,
-+ extr->ips->ips_ref),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_s),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_d),
-+ extensions_reply)
-+ )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
-+ "failed to build the delete reply message extensions\n");
-+ SENDERR(-error);
-+ }
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
-+ "failed to build the delete reply message\n");
-+ SENDERR(-error);
-+ }
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
-+ "sending up delete reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
-+ "sending up delete reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ errlab:
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_get_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct ipsec_sa *ipsp;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_get_parse: .\n");
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_get_parse: "
-+ "extr or extr->ips pointer NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
-+
-+ spin_lock_bh(&tdb_lock);
-+
-+ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
-+ if (ipsp == NULL) {
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
-+ "ipsec_sa not found for SA=%s, could not get.\n",
-+ sa_len ? sa : " (error)");
-+ SENDERR(ESRCH);
-+ }
-+
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_GET,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype,
-+ 0,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ extr->ips->ips_replaywin,
-+ extr->ips->ips_state,
-+ extr->ips->ips_authalg,
-+ extr->ips->ips_encalg,
-+ extr->ips->ips_flags,
-+ extr->ips->ips_ref),
-+ extensions_reply)
-+ /* The 3 lifetime extentions should only be sent if non-zero. */
-+ && (ipsp->ips_life.ipl_allocations.ipl_count
-+ || ipsp->ips_life.ipl_bytes.ipl_count
-+ || ipsp->ips_life.ipl_addtime.ipl_count
-+ || ipsp->ips_life.ipl_usetime.ipl_count
-+ || ipsp->ips_life.ipl_packets.ipl_count
-+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
-+ SADB_EXT_LIFETIME_CURRENT,
-+ ipsp->ips_life.ipl_allocations.ipl_count,
-+ ipsp->ips_life.ipl_bytes.ipl_count,
-+ ipsp->ips_life.ipl_addtime.ipl_count,
-+ ipsp->ips_life.ipl_usetime.ipl_count,
-+ ipsp->ips_life.ipl_packets.ipl_count),
-+ extensions_reply) : 1)
-+ && (ipsp->ips_life.ipl_allocations.ipl_hard
-+ || ipsp->ips_life.ipl_bytes.ipl_hard
-+ || ipsp->ips_life.ipl_addtime.ipl_hard
-+ || ipsp->ips_life.ipl_usetime.ipl_hard
-+ || ipsp->ips_life.ipl_packets.ipl_hard
-+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
-+ SADB_EXT_LIFETIME_HARD,
-+ ipsp->ips_life.ipl_allocations.ipl_hard,
-+ ipsp->ips_life.ipl_bytes.ipl_hard,
-+ ipsp->ips_life.ipl_addtime.ipl_hard,
-+ ipsp->ips_life.ipl_usetime.ipl_hard,
-+ ipsp->ips_life.ipl_packets.ipl_hard),
-+ extensions_reply) : 1)
-+ && (ipsp->ips_life.ipl_allocations.ipl_soft
-+ || ipsp->ips_life.ipl_bytes.ipl_soft
-+ || ipsp->ips_life.ipl_addtime.ipl_soft
-+ || ipsp->ips_life.ipl_usetime.ipl_soft
-+ || ipsp->ips_life.ipl_packets.ipl_soft
-+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
-+ SADB_EXT_LIFETIME_SOFT,
-+ ipsp->ips_life.ipl_allocations.ipl_soft,
-+ ipsp->ips_life.ipl_bytes.ipl_soft,
-+ ipsp->ips_life.ipl_addtime.ipl_soft,
-+ ipsp->ips_life.ipl_usetime.ipl_soft,
-+ ipsp->ips_life.ipl_packets.ipl_soft),
-+ extensions_reply) : 1)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_s),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_d),
-+ extensions_reply)
-+ && (extr->ips->ips_addr_p
-+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_PROXY],
-+ SADB_EXT_ADDRESS_PROXY,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_p),
-+ extensions_reply) : 1)
-+#if 0
-+ /* FIXME: This won't work yet because the keys are not
-+ stored directly in the ipsec_sa. They are stored as
-+ contexts. */
-+ && (extr->ips->ips_key_a_size
-+ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_AUTH],
-+ SADB_EXT_KEY_AUTH,
-+ extr->ips->ips_key_a_size * 8,
-+ extr->ips->ips_key_a),
-+ extensions_reply) : 1)
-+ /* FIXME: This won't work yet because the keys are not
-+ stored directly in the ipsec_sa. They are stored as
-+ key schedules. */
-+ && (extr->ips->ips_key_e_size
-+ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_ENCRYPT],
-+ SADB_EXT_KEY_ENCRYPT,
-+ extr->ips->ips_key_e_size * 8,
-+ extr->ips->ips_key_e),
-+ extensions_reply) : 1)
-+#endif
-+ && (extr->ips->ips_ident_s.data
-+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
-+ SADB_EXT_IDENTITY_SRC,
-+ extr->ips->ips_ident_s.type,
-+ extr->ips->ips_ident_s.id,
-+ extr->ips->ips_ident_s.len,
-+ extr->ips->ips_ident_s.data),
-+ extensions_reply) : 1)
-+ && (extr->ips->ips_ident_d.data
-+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
-+ SADB_EXT_IDENTITY_DST,
-+ extr->ips->ips_ident_d.type,
-+ extr->ips->ips_ident_d.id,
-+ extr->ips->ips_ident_d.len,
-+ extr->ips->ips_ident_d.data),
-+ extensions_reply) : 1)
-+#if 0
-+ /* FIXME: This won't work yet because I have not finished
-+ it. */
-+ && (extr->ips->ips_sens_
-+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
-+ extr->ips->ips_sens_dpd,
-+ extr->ips->ips_sens_sens_level,
-+ extr->ips->ips_sens_sens_len,
-+ extr->ips->ips_sens_sens_bitmap,
-+ extr->ips->ips_sens_integ_level,
-+ extr->ips->ips_sens_integ_len,
-+ extr->ips->ips_sens_integ_bitmap),
-+ extensions_reply) : 1)
-+#endif
-+ )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
-+ "failed to build the get reply message extensions\n");
-+ ipsec_sa_put(ipsp);
-+ spin_unlock_bh(&tdb_lock);
-+ SENDERR(-error);
-+ }
-+
-+ ipsec_sa_put(ipsp);
-+ spin_unlock_bh(&tdb_lock);
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
-+ "failed to build the get reply message\n");
-+ SENDERR(-error);
-+ }
-+
-+ if((error = pfkey_upmsg(sk->socket, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
-+ "failed to send the get reply message\n");
-+ SENDERR(-error);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
-+ "succeeded in sending get reply message.\n");
-+
-+ errlab:
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_acquire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_acquire_parse: .\n");
-+
-+ /* XXX I don't know if we want an upper bound, since userspace may
-+ want to register itself for an satype > SADB_SATYPE_MAX. */
-+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_acquire_parse: "
-+ "SATYPE=%d invalid.\n",
-+ satype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(pfkey_registered_sockets[satype])) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
-+ "no sockets registered for SAtype=%d(%s).\n",
-+ satype,
-+ satype2name(satype));
-+ SENDERR(EPROTONOSUPPORT);
-+ }
-+
-+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
-+ "sending up acquire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
-+ "sending up acquire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_register_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_parse: .\n");
-+
-+ /* XXX I don't know if we want an upper bound, since userspace may
-+ want to register itself for an satype > SADB_SATYPE_MAX. */
-+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_parse: "
-+ "SATYPE=%d invalid.\n",
-+ satype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!pfkey_list_insert_socket(sk->socket,
-+ &(pfkey_registered_sockets[satype]))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_parse: "
-+ "SATYPE=%02d(%s) successfully registered by KMd (pid=%d).\n",
-+ satype,
-+ satype2name(satype),
-+ key_pid(sk));
-+ };
-+
-+ /* send up register msg with supported SATYPE algos */
-+
-+ error=pfkey_register_reply(satype, (struct sadb_msg*)extensions[SADB_EXT_RESERVED]);
-+ errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_register_reply(int satype, struct sadb_msg *sadb_msg)
-+{
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ struct supported_list *pfkey_supported_listp;
-+ unsigned int alg_num_a = 0, alg_num_e = 0;
-+ struct sadb_alg *alg_a = NULL, *alg_e = NULL, *alg_ap = NULL, *alg_ep = NULL;
-+ int error = 0;
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
-+ "SAtype=%d unspecified or unknown.\n",
-+ satype);
-+ SENDERR(EINVAL);
-+ }
-+ if(!(pfkey_registered_sockets[satype])) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
-+ "no sockets registered for SAtype=%d(%s).\n",
-+ satype,
-+ satype2name(satype));
-+ SENDERR(EPROTONOSUPPORT);
-+ }
-+ /* send up register msg with supported SATYPE algos */
-+ pfkey_supported_listp = pfkey_supported_list[satype];
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "pfkey_supported_list[%d]=0p%p\n",
-+ satype,
-+ pfkey_supported_list[satype]);
-+ while(pfkey_supported_listp) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "checking supported=0p%p\n",
-+ pfkey_supported_listp);
-+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "adding auth alg.\n");
-+ alg_num_a++;
-+ }
-+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "adding encrypt alg.\n");
-+ alg_num_e++;
-+ }
-+ pfkey_supported_listp = pfkey_supported_listp->next;
-+ }
-+
-+ if(alg_num_a) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "allocating %lu bytes for auth algs.\n",
-+ (unsigned long) (alg_num_a * sizeof(struct sadb_alg)));
-+ if((alg_a = kmalloc(alg_num_a * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "auth alg memory allocation error\n");
-+ SENDERR(ENOMEM);
-+ }
-+ alg_ap = alg_a;
-+ }
-+
-+ if(alg_num_e) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "allocating %lu bytes for enc algs.\n",
-+ (unsigned long) (alg_num_e * sizeof(struct sadb_alg)));
-+ if((alg_e = kmalloc(alg_num_e * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "enc alg memory allocation error\n");
-+ SENDERR(ENOMEM);
-+ }
-+ alg_ep = alg_e;
-+ }
-+
-+ pfkey_supported_listp = pfkey_supported_list[satype];
-+ while(pfkey_supported_listp) {
-+ if(alg_num_a) {
-+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) {
-+ alg_ap->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id;
-+ alg_ap->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen;
-+ alg_ap->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits;
-+ alg_ap->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits;
-+ alg_ap->sadb_alg_reserved = 0;
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_register_reply: "
-+ "adding auth=0p%p\n",
-+ alg_ap);
-+ alg_ap++;
-+ }
-+ }
-+ if(alg_num_e) {
-+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
-+ alg_ep->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id;
-+ alg_ep->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen;
-+ alg_ep->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits;
-+ alg_ep->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits;
-+ alg_ep->sadb_alg_reserved = 0;
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_register_reply: "
-+ "adding encrypt=0p%p\n",
-+ alg_ep);
-+ alg_ep++;
-+ }
-+ }
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "found satype=%d(%s) exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_supported_listp->supportedp->supported_alg_exttype,
-+ pfkey_supported_listp->supportedp->supported_alg_id,
-+ pfkey_supported_listp->supportedp->supported_alg_ivlen,
-+ pfkey_supported_listp->supportedp->supported_alg_minbits,
-+ pfkey_supported_listp->supportedp->supported_alg_maxbits);
-+ pfkey_supported_listp = pfkey_supported_listp->next;
-+ }
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_REGISTER,
-+ satype,
-+ 0,
-+ sadb_msg? sadb_msg->sadb_msg_seq : ++pfkey_msg_seq,
-+ sadb_msg? sadb_msg->sadb_msg_pid: current->pid),
-+ extensions_reply) &&
-+ (alg_num_a ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_AUTH],
-+ SADB_EXT_SUPPORTED_AUTH,
-+ alg_num_a,
-+ alg_a),
-+ extensions_reply) : 1) &&
-+ (alg_num_e ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_ENCRYPT],
-+ SADB_EXT_SUPPORTED_ENCRYPT,
-+ alg_num_e,
-+ alg_e),
-+ extensions_reply) : 1))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
-+ "failed to build the register message extensions_reply\n");
-+ SENDERR(-error);
-+ }
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
-+ "failed to build the register message\n");
-+ SENDERR(-error);
-+ }
-+ /* this should go to all registered sockets for that satype only */
-+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
-+ "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
-+ "sending up register message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ errlab:
-+ if(alg_a) {
-+ kfree(alg_a);
-+ }
-+ if(alg_e) {
-+ kfree(alg_e);
-+ }
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_expire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct socket_list *pfkey_socketsp;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_expire_parse: .\n");
-+
-+ if(pfkey_open_sockets) {
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
-+ "sending up expire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
-+ "sending up expire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+ }
-+
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_flush_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+ uint8_t proto = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_flush_parse: "
-+ "flushing type %d SAs\n",
-+ satype);
-+
-+ if(satype && !(proto = satype2proto(satype))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_flush_parse: "
-+ "satype %d lookup failed.\n",
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if ((error = ipsec_sadb_cleanup(proto))) {
-+ SENDERR(-error);
-+ }
-+
-+ if(pfkey_open_sockets) {
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
-+ "sending up flush reply message for satype=%d(%s) (proto=%d) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ proto,
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
-+ "sending up flush reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+ }
-+
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_dump_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_dump_parse: .\n");
-+
-+ SENDERR(ENOSYS);
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_promisc_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_promisc_parse: .\n");
-+
-+ SENDERR(ENOSYS);
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_pchange_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_pchange_parse: .\n");
-+
-+ SENDERR(ENOSYS);
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_grpsa_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ struct ipsec_sa *ips1p, *ips2p, *ipsp;
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+ char sa1[SATOT_BUF], sa2[SATOT_BUF];
-+ size_t sa_len1, sa_len2 = 0;
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: .\n");
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ if(extr == NULL || extr->ips == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: "
-+ "extr or extr->ips is NULL, fatal.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ sa_len1 = satot(&extr->ips->ips_said, 0, sa1, sizeof(sa1));
-+ if(extr->ips2 != NULL) {
-+ sa_len2 = satot(&extr->ips2->ips_said, 0, sa2, sizeof(sa2));
-+ }
-+
-+ spin_lock_bh(&tdb_lock);
-+
-+ ips1p = ipsec_sa_getbyid(&(extr->ips->ips_said));
-+ if(ips1p == NULL) {
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: "
-+ "reserved ipsec_sa for SA1: %s not found. Call SADB_ADD/UPDATE first.\n",
-+ sa_len1 ? sa1 : " (error)");
-+ SENDERR(ENOENT);
-+ }
-+ if(extr->ips2) { /* GRPSA */
-+ ips2p = ipsec_sa_getbyid(&(extr->ips2->ips_said));
-+ if(ips2p == NULL) {
-+ ipsec_sa_put(ips1p);
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: "
-+ "reserved ipsec_sa for SA2: %s not found. Call SADB_ADD/UPDATE first.\n",
-+ sa_len2 ? sa2 : " (error)");
-+ SENDERR(ENOENT);
-+ }
-+
-+ /* Is either one already linked? */
-+ if(ips1p->ips_onext) {
-+ ipsec_sa_put(ips1p);
-+ ipsec_sa_put(ips2p);
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: "
-+ "ipsec_sa for SA: %s is already linked.\n",
-+ sa_len1 ? sa1 : " (error)");
-+ SENDERR(EEXIST);
-+ }
-+ if(ips2p->ips_inext) {
-+ ipsec_sa_put(ips1p);
-+ ipsec_sa_put(ips2p);
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: "
-+ "ipsec_sa for SA: %s is already linked.\n",
-+ sa_len2 ? sa2 : " (error)");
-+ SENDERR(EEXIST);
-+ }
-+
-+ /* Is extr->ips already linked to extr->ips2? */
-+ ipsp = ips2p;
-+ while(ipsp) {
-+ if(ipsp == ips1p) {
-+ ipsec_sa_put(ips1p);
-+ ipsec_sa_put(ips2p);
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: "
-+ "ipsec_sa for SA: %s is already linked to %s.\n",
-+ sa_len1 ? sa1 : " (error)",
-+ sa_len2 ? sa2 : " (error)");
-+ SENDERR(EEXIST);
-+ }
-+ ipsp = ipsp->ips_onext;
-+ }
-+
-+ /* link 'em */
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: "
-+ "linking ipsec_sa SA: %s with %s.\n",
-+ sa_len1 ? sa1 : " (error)",
-+ sa_len2 ? sa2 : " (error)");
-+ ips1p->ips_onext = ips2p;
-+ ips2p->ips_inext = ips1p;
-+ } else { /* UNGRPSA */
-+ ipsec_sa_put(ips1p);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: "
-+ "unlinking ipsec_sa SA: %s.\n",
-+ sa_len1 ? sa1 : " (error)");
-+ while(ips1p->ips_onext) {
-+ ips1p = ips1p->ips_onext;
-+ }
-+ while(ips1p->ips_inext) {
-+ ipsp = ips1p;
-+ ips1p = ips1p->ips_inext;
-+ ipsec_sa_put(ips1p);
-+ ipsp->ips_inext = NULL;
-+ ipsec_sa_put(ipsp);
-+ ips1p->ips_onext = NULL;
-+ }
-+ }
-+
-+ spin_unlock_bh(&tdb_lock);
-+
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_X_GRPSA,
-+ satype,
-+ 0,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ extr->ips->ips_replaywin,
-+ extr->ips->ips_state,
-+ extr->ips->ips_authalg,
-+ extr->ips->ips_encalg,
-+ extr->ips->ips_flags,
-+ extr->ips->ips_ref),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_d),
-+ extensions_reply)
-+ && (extr->ips2
-+ ? (pfkey_safe_build(error = pfkey_x_satype_build(&extensions_reply[SADB_X_EXT_SATYPE2],
-+ ((struct sadb_x_satype*)extensions[SADB_X_EXT_SATYPE2])->sadb_x_satype_satype
-+ /* proto2satype(extr->ips2->ips_said.proto) */),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_X_EXT_SA2],
-+ SADB_X_EXT_SA2,
-+ extr->ips2->ips_said.spi,
-+ extr->ips2->ips_replaywin,
-+ extr->ips2->ips_state,
-+ extr->ips2->ips_authalg,
-+ extr->ips2->ips_encalg,
-+ extr->ips2->ips_flags,
-+ extr->ips2->ips_ref),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST2],
-+ SADB_X_EXT_ADDRESS_DST2,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips2->ips_addr_d),
-+ extensions_reply) ) : 1 )
-+ )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
-+ "failed to build the x_grpsa reply message extensions\n");
-+ SENDERR(-error);
-+ }
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
-+ "failed to build the x_grpsa reply message\n");
-+ SENDERR(-error);
-+ }
-+
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
-+ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
-+ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
-+ "succeeded in sending x_grpsa reply message.\n");
-+
-+ errlab:
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ char buf1[64], buf2[64];
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+ ip_address srcflow, dstflow, srcmask, dstmask;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: .\n");
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ memset((caddr_t)&srcflow, 0, sizeof(srcflow));
-+ memset((caddr_t)&dstflow, 0, sizeof(dstflow));
-+ memset((caddr_t)&srcmask, 0, sizeof(srcmask));
-+ memset((caddr_t)&dstmask, 0, sizeof(dstmask));
-+
-+ if(!extr || !(extr->ips) || !(extr->eroute)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "missing extr, ipsec_sa or eroute data.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ srcflow.u.v4.sin_family = AF_INET;
-+ dstflow.u.v4.sin_family = AF_INET;
-+ srcmask.u.v4.sin_family = AF_INET;
-+ dstmask.u.v4.sin_family = AF_INET;
-+ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
-+ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
-+ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
-+ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (debug_pfkey) {
-+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
-+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
-+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "calling breakeroute and/or makeroute for %s->%s\n",
-+ buf1, buf2);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_INFLOW) {
-+/* if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) */
-+ struct ipsec_sa *ipsp, *ipsq;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
-+ if(ipsq == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "ipsec_sa not found, cannot set incoming policy.\n");
-+ SENDERR(ENOENT);
-+ }
-+
-+ ipsp = ipsq;
-+ while(ipsp && ipsp->ips_said.proto != IPPROTO_IPIP) {
-+ ipsp = ipsp->ips_inext;
-+ }
-+
-+ if(ipsp == NULL) {
-+ ipsec_sa_put(ipsq);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "SA chain does not have an IPIP SA, cannot set incoming policy.\n");
-+ SENDERR(ENOENT);
-+ }
-+
-+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
-+
-+ ipsp->ips_flags |= SADB_X_SAFLAGS_INFLOW;
-+ ipsp->ips_flow_s = srcflow;
-+ ipsp->ips_flow_d = dstflow;
-+ ipsp->ips_mask_s = srcmask;
-+ ipsp->ips_mask_d = dstmask;
-+
-+ ipsec_sa_put(ipsq);
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "inbound eroute, setting incoming policy information in IPIP ipsec_sa for SA: %s.\n",
-+ sa_len ? sa : " (error)");
-+ } else {
-+ struct sk_buff *first = NULL, *last = NULL;
-+
-+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_REPLACEFLOW) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "REPLACEFLOW flag set, calling breakeroute.\n");
-+ if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr),
-+ &(extr->eroute->er_emask),
-+ &first, &last))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "breakeroute returned %d. first=0p%p, last=0p%p\n",
-+ error,
-+ first,
-+ last);
-+ if(first != NULL) {
-+ ipsec_kfree_skb(first);
-+ }
-+ if(last != NULL) {
-+ ipsec_kfree_skb(last);
-+ }
-+ SENDERR(-error);
-+ }
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "calling makeroute.\n");
-+
-+ if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr),
-+ &(extr->eroute->er_emask),
-+ extr->ips->ips_said,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid,
-+ NULL,
-+ &(extr->ips->ips_ident_s),
-+ &(extr->ips->ips_ident_d)))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "makeroute returned %d.\n", error);
-+ SENDERR(-error);
-+ }
-+ if(first != NULL) {
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "first=0p%p HOLD packet re-injected.\n",
-+ first);
-+ DEV_QUEUE_XMIT(first, first->dev, SOPRI_NORMAL);
-+ }
-+ if(last != NULL) {
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "last=0p%p HOLD packet re-injected.\n",
-+ last);
-+ DEV_QUEUE_XMIT(last, last->dev, SOPRI_NORMAL);
-+ }
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "makeroute call successful.\n");
-+
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_X_ADDFLOW,
-+ satype,
-+ 0,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ extr->ips->ips_replaywin,
-+ extr->ips->ips_state,
-+ extr->ips->ips_authalg,
-+ extr->ips->ips_encalg,
-+ extr->ips->ips_flags,
-+ extr->ips->ips_ref),
-+ extensions_reply)
-+ && (extensions[SADB_EXT_ADDRESS_SRC]
-+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_s),
-+ extensions_reply) : 1)
-+ && (extensions[SADB_EXT_ADDRESS_DST]
-+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_d),
-+ extensions_reply) : 1)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
-+ SADB_X_EXT_ADDRESS_SRC_FLOW,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ (struct sockaddr*)&srcflow),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
-+ SADB_X_EXT_ADDRESS_DST_FLOW,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ (struct sockaddr*)&dstflow),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
-+ SADB_X_EXT_ADDRESS_SRC_MASK,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ (struct sockaddr*)&srcmask),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
-+ SADB_X_EXT_ADDRESS_DST_MASK,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ (struct sockaddr*)&dstmask),
-+ extensions_reply)
-+ )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
-+ "failed to build the x_addflow reply message extensions\n");
-+ SENDERR(-error);
-+ }
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
-+ "failed to build the x_addflow reply message\n");
-+ SENDERR(-error);
-+ }
-+
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
-+ "sending up x_addflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
-+ "sending up x_addflow reply message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ extr->ips->ips_said.proto,
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "extr->ips cleaned up and freed.\n");
-+
-+ errlab:
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_delflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ char buf1[64], buf2[64];
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+ ip_address srcflow, dstflow, srcmask, dstmask;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_delflow_parse: .\n");
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ memset((caddr_t)&srcflow, 0, sizeof(srcflow));
-+ memset((caddr_t)&dstflow, 0, sizeof(dstflow));
-+ memset((caddr_t)&srcmask, 0, sizeof(srcmask));
-+ memset((caddr_t)&dstmask, 0, sizeof(dstmask));
-+
-+ if(!extr || !(extr->ips)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_delflow_parse: "
-+ "extr, or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_CLEARFLOW) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_delflow_parse: "
-+ "CLEARFLOW flag set, calling cleareroutes.\n");
-+ if ((error = ipsec_cleareroutes()))
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_delflow_parse: "
-+ "cleareroutes returned %d.\n", error);
-+ SENDERR(-error);
-+ } else {
-+ struct sk_buff *first = NULL, *last = NULL;
-+
-+ if(!(extr->eroute)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_delflow_parse: "
-+ "extr->eroute is NULL, fatal.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ srcflow.u.v4.sin_family = AF_INET;
-+ dstflow.u.v4.sin_family = AF_INET;
-+ srcmask.u.v4.sin_family = AF_INET;
-+ dstmask.u.v4.sin_family = AF_INET;
-+ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
-+ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
-+ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
-+ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (debug_pfkey) {
-+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
-+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
-+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_delflow_parse: "
-+ "calling breakeroute for %s->%s\n",
-+ buf1, buf2);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ error = ipsec_breakroute(&(extr->eroute->er_eaddr),
-+ &(extr->eroute->er_emask),
-+ &first, &last);
-+ if(error) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_delflow_parse: "
-+ "breakeroute returned %d. first=0p%p, last=0p%p\n",
-+ error,
-+ first,
-+ last);
-+ }
-+ if(first != NULL) {
-+ ipsec_kfree_skb(first);
-+ }
-+ if(last != NULL) {
-+ ipsec_kfree_skb(last);
-+ }
-+ if(error) {
-+ SENDERR(-error);
-+ }
-+ }
-+
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_X_DELFLOW,
-+ satype,
-+ 0,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ extr->ips->ips_replaywin,
-+ extr->ips->ips_state,
-+ extr->ips->ips_authalg,
-+ extr->ips->ips_encalg,
-+ extr->ips->ips_flags,
-+ extr->ips->ips_ref),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
-+ SADB_X_EXT_ADDRESS_SRC_FLOW,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ (struct sockaddr*)&srcflow),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
-+ SADB_X_EXT_ADDRESS_DST_FLOW,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ (struct sockaddr*)&dstflow),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
-+ SADB_X_EXT_ADDRESS_SRC_MASK,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ (struct sockaddr*)&srcmask),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
-+ SADB_X_EXT_ADDRESS_DST_MASK,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ (struct sockaddr*)&dstmask),
-+ extensions_reply)
-+ )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
-+ "failed to build the x_delflow reply message extensions\n");
-+ SENDERR(-error);
-+ }
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
-+ "failed to build the x_delflow reply message\n");
-+ SENDERR(-error);
-+ }
-+
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
-+ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
-+ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_delflow_parse: "
-+ "extr->ips cleaned up and freed.\n");
-+
-+ errlab:
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_msg_debug_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_msg_debug_parse: .\n");
-+
-+/* errlab:*/
-+ return error;
-+}
-+
-+/* pfkey_expire expects the ipsec_sa table to be locked before being called. */
-+int
-+pfkey_expire(struct ipsec_sa *ipsp, int hard)
-+{
-+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_msg = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ int error = 0;
-+ uint8_t satype;
-+
-+ pfkey_extensions_init(extensions);
-+
-+ if(!(satype = proto2satype(ipsp->ips_said.proto))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_expire: "
-+ "satype lookup for protocol %d lookup failed.\n",
-+ ipsp->ips_said.proto);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!pfkey_open_sockets) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
-+ "no sockets listening.\n");
-+ SENDERR(EPROTONOSUPPORT);
-+ }
-+
-+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
-+ SADB_EXPIRE,
-+ satype,
-+ 0,
-+ ++pfkey_msg_seq,
-+ 0),
-+ extensions)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ ipsp->ips_said.spi,
-+ ipsp->ips_replaywin,
-+ ipsp->ips_state,
-+ ipsp->ips_authalg,
-+ ipsp->ips_encalg,
-+ ipsp->ips_flags,
-+ ipsp->ips_ref),
-+ extensions)
-+ && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT],
-+ SADB_EXT_LIFETIME_CURRENT,
-+ ipsp->ips_life.ipl_allocations.ipl_count,
-+ ipsp->ips_life.ipl_bytes.ipl_count,
-+ ipsp->ips_life.ipl_addtime.ipl_count,
-+ ipsp->ips_life.ipl_usetime.ipl_count,
-+ ipsp->ips_life.ipl_packets.ipl_count),
-+ extensions)
-+ && (hard ?
-+ pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD],
-+ SADB_EXT_LIFETIME_HARD,
-+ ipsp->ips_life.ipl_allocations.ipl_hard,
-+ ipsp->ips_life.ipl_bytes.ipl_hard,
-+ ipsp->ips_life.ipl_addtime.ipl_hard,
-+ ipsp->ips_life.ipl_usetime.ipl_hard,
-+ ipsp->ips_life.ipl_packets.ipl_hard),
-+ extensions)
-+ : pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT],
-+ SADB_EXT_LIFETIME_SOFT,
-+ ipsp->ips_life.ipl_allocations.ipl_soft,
-+ ipsp->ips_life.ipl_bytes.ipl_soft,
-+ ipsp->ips_life.ipl_addtime.ipl_soft,
-+ ipsp->ips_life.ipl_usetime.ipl_soft,
-+ ipsp->ips_life.ipl_packets.ipl_soft),
-+ extensions))
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ 0, /* ipsp->ips_said.proto, */
-+ 0,
-+ ipsp->ips_addr_s),
-+ extensions)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ 0, /* ipsp->ips_said.proto, */
-+ 0,
-+ ipsp->ips_addr_d),
-+ extensions))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
-+ "failed to build the expire message extensions\n");
-+ spin_unlock(&tdb_lock);
-+ goto errlab;
-+ }
-+
-+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
-+ "failed to build the expire message\n");
-+ SENDERR(-error);
-+ }
-+
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
-+ "sending up expire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
-+ "sending up expire message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ ipsp->ips_said.proto,
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ errlab:
-+ if (pfkey_msg) {
-+ pfkey_msg_free(&pfkey_msg);
-+ }
-+ pfkey_extensions_free(extensions);
-+ return error;
-+}
-+
-+int
-+pfkey_acquire(struct ipsec_sa *ipsp)
-+{
-+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_msg = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ int error = 0;
-+ struct sadb_comb comb[] = {
-+ /* auth; encrypt; flags; */
-+ /* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */
-+ /* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */
-+ /* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */
-+ /* soft_packets; hard_packets; */
-+ { SADB_AALG_MD5HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
-+ 128, 128, 168, 168,
-+ 0, 0, 0, 0, 0,
-+ 57600, 86400, 57600, 86400,
-+ 0, 0 },
-+ { SADB_AALG_SHA1HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
-+ 160, 160, 168, 168,
-+ 0, 0, 0, 0, 0,
-+ 57600, 86400, 57600, 86400,
-+ 0, 0 }
-+ };
-+
-+ /* XXX This should not be hard-coded. It should be taken from the spdb */
-+ uint8_t satype = SADB_SATYPE_ESP;
-+
-+ pfkey_extensions_init(extensions);
-+
-+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
-+ "SAtype=%d unspecified or unknown.\n",
-+ satype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(pfkey_registered_sockets[satype])) {
-+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
-+ "no sockets registered for SAtype=%d(%s).\n",
-+ satype,
-+ satype2name(satype));
-+ SENDERR(EPROTONOSUPPORT);
-+ }
-+
-+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
-+ SADB_ACQUIRE,
-+ satype,
-+ 0,
-+ ++pfkey_msg_seq,
-+ 0),
-+ extensions)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ ipsp->ips_transport_protocol,
-+ 0,
-+ ipsp->ips_addr_s),
-+ extensions)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ ipsp->ips_transport_protocol,
-+ 0,
-+ ipsp->ips_addr_d),
-+ extensions)
-+#if 0
-+ && (ipsp->ips_addr_p
-+ ? pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_PROXY],
-+ SADB_EXT_ADDRESS_PROXY,
-+ ipsp->ips_transport_protocol,
-+ 0,
-+ ipsp->ips_addr_p),
-+ extensions) : 1)
-+#endif
-+ && (ipsp->ips_ident_s.type != SADB_IDENTTYPE_RESERVED
-+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC],
-+ SADB_EXT_IDENTITY_SRC,
-+ ipsp->ips_ident_s.type,
-+ ipsp->ips_ident_s.id,
-+ ipsp->ips_ident_s.len,
-+ ipsp->ips_ident_s.data),
-+ extensions) : 1)
-+
-+ && (ipsp->ips_ident_d.type != SADB_IDENTTYPE_RESERVED
-+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_DST],
-+ SADB_EXT_IDENTITY_DST,
-+ ipsp->ips_ident_d.type,
-+ ipsp->ips_ident_d.id,
-+ ipsp->ips_ident_d.len,
-+ ipsp->ips_ident_d.data),
-+ extensions) : 1)
-+#if 0
-+ /* FIXME: This won't work yet because I have not finished
-+ it. */
-+ && (ipsp->ips_sens_
-+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions[SADB_EXT_SENSITIVITY],
-+ ipsp->ips_sens_dpd,
-+ ipsp->ips_sens_sens_level,
-+ ipsp->ips_sens_sens_len,
-+ ipsp->ips_sens_sens_bitmap,
-+ ipsp->ips_sens_integ_level,
-+ ipsp->ips_sens_integ_len,
-+ ipsp->ips_sens_integ_bitmap),
-+ extensions) : 1)
-+#endif
-+ && pfkey_safe_build(error = pfkey_prop_build(&extensions[SADB_EXT_PROPOSAL],
-+ 64, /* replay */
-+ sizeof(comb)/sizeof(struct sadb_comb),
-+ &(comb[0])),
-+ extensions)
-+ )) {
-+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
-+ "failed to build the acquire message extensions\n");
-+ SENDERR(-error);
-+ }
-+
-+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
-+ "failed to build the acquire message\n");
-+ SENDERR(-error);
-+ }
-+
-+#if KLIPS_PFKEY_ACQUIRE_LOSSAGE > 0
-+ if(sysctl_ipsec_regress_pfkey_lossage) {
-+ return(0);
-+ }
-+#endif
-+
-+ /* this should go to all registered sockets for that satype only */
-+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
-+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
-+ "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
-+ "sending up acquire message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ errlab:
-+ if (pfkey_msg) {
-+ pfkey_msg_free(&pfkey_msg);
-+ }
-+ pfkey_extensions_free(extensions);
-+ return error;
-+}
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+int
-+pfkey_nat_t_new_mapping(struct ipsec_sa *ipsp, struct sockaddr *ipaddr,
-+ __u16 sport)
-+{
-+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_msg = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ int error = 0;
-+ uint8_t satype = (ipsp->ips_said.proto==IPPROTO_ESP) ? SADB_SATYPE_ESP : 0;
-+
-+ /* Construct SADB_X_NAT_T_NEW_MAPPING message */
-+
-+ pfkey_extensions_init(extensions);
-+
-+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
-+ "SAtype=%d unspecified or unknown.\n",
-+ satype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(pfkey_registered_sockets[satype])) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
-+ "no sockets registered for SAtype=%d(%s).\n",
-+ satype,
-+ satype2name(satype));
-+ SENDERR(EPROTONOSUPPORT);
-+ }
-+
-+ if (!(pfkey_safe_build
-+ (error = pfkey_msg_hdr_build(&extensions[0], SADB_X_NAT_T_NEW_MAPPING,
-+ satype, 0, ++pfkey_msg_seq, 0), extensions)
-+ /* SA */
-+ && pfkey_safe_build
-+ (error = pfkey_sa_build(&extensions[SADB_EXT_SA],
-+ SADB_EXT_SA, ipsp->ips_said.spi, 0, 0, 0, 0, 0), extensions)
-+ /* ADDRESS_SRC = old addr */
-+ && pfkey_safe_build
-+ (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC, ipsp->ips_said.proto, 0, ipsp->ips_addr_s),
-+ extensions)
-+ /* NAT_T_SPORT = old port */
-+ && pfkey_safe_build
-+ (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_SPORT],
-+ SADB_X_EXT_NAT_T_SPORT, ipsp->ips_natt_sport), extensions)
-+ /* ADDRESS_DST = new addr */
-+ && pfkey_safe_build
-+ (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST, ipsp->ips_said.proto, 0, ipaddr), extensions)
-+ /* NAT_T_DPORT = new port */
-+ && pfkey_safe_build
-+ (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_DPORT],
-+ SADB_X_EXT_NAT_T_DPORT, sport), extensions)
-+ )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
-+ "failed to build the nat_t_new_mapping message extensions\n");
-+ SENDERR(-error);
-+ }
-+
-+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
-+ "failed to build the nat_t_new_mapping message\n");
-+ SENDERR(-error);
-+ }
-+
-+ /* this should go to all registered sockets for that satype only */
-+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
-+ "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
-+ "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ errlab:
-+ if (pfkey_msg) {
-+ pfkey_msg_free(&pfkey_msg);
-+ }
-+ pfkey_extensions_free(extensions);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_nat_t_new_mapping_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ /* SADB_X_NAT_T_NEW_MAPPING not used in kernel */
-+ return -EINVAL;
-+}
-+#endif
-+
-+DEBUG_NO_STATIC int (*ext_processors[SADB_EXT_MAX+1])(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) =
-+{
-+ NULL, /* pfkey_msg_process, */
-+ pfkey_sa_process,
-+ pfkey_lifetime_process,
-+ pfkey_lifetime_process,
-+ pfkey_lifetime_process,
-+ pfkey_address_process,
-+ pfkey_address_process,
-+ pfkey_address_process,
-+ pfkey_key_process,
-+ pfkey_key_process,
-+ pfkey_ident_process,
-+ pfkey_ident_process,
-+ pfkey_sens_process,
-+ pfkey_prop_process,
-+ pfkey_supported_process,
-+ pfkey_supported_process,
-+ pfkey_spirange_process,
-+ pfkey_x_kmprivate_process,
-+ pfkey_x_satype_process,
-+ pfkey_sa_process,
-+ pfkey_address_process,
-+ pfkey_address_process,
-+ pfkey_address_process,
-+ pfkey_address_process,
-+ pfkey_address_process,
-+ pfkey_x_debug_process,
-+ pfkey_x_protocol_process
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ ,
-+ pfkey_x_nat_t_type_process,
-+ pfkey_x_nat_t_port_process,
-+ pfkey_x_nat_t_port_process,
-+ pfkey_address_process
-+#endif
-+};
-+
-+
-+DEBUG_NO_STATIC int (*msg_parsers[SADB_MAX +1])(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr)
-+ =
-+{
-+ NULL, /* RESERVED */
-+ pfkey_getspi_parse,
-+ pfkey_update_parse,
-+ pfkey_add_parse,
-+ pfkey_delete_parse,
-+ pfkey_get_parse,
-+ pfkey_acquire_parse,
-+ pfkey_register_parse,
-+ pfkey_expire_parse,
-+ pfkey_flush_parse,
-+ pfkey_dump_parse,
-+ pfkey_x_promisc_parse,
-+ pfkey_x_pchange_parse,
-+ pfkey_x_grpsa_parse,
-+ pfkey_x_addflow_parse,
-+ pfkey_x_delflow_parse,
-+ pfkey_x_msg_debug_parse
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ , pfkey_x_nat_t_new_mapping_parse
-+#endif
-+};
-+
-+int
-+pfkey_build_reply(struct sadb_msg *pfkey_msg, struct pfkey_extracted_data *extr,
-+ struct sadb_msg **pfkey_reply)
-+{
-+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
-+ int error = 0;
-+ int msg_type = pfkey_msg->sadb_msg_type;
-+ int seq = pfkey_msg->sadb_msg_seq;
-+
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
-+ "building reply with type: %d\n",
-+ msg_type);
-+ pfkey_extensions_init(extensions);
-+ if (!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
-+ "bad ipsec_sa passed\n");
-+ return EINVAL;
-+ }
-+ error = pfkey_safe_build(pfkey_msg_hdr_build(&extensions[0],
-+ msg_type,
-+ proto2satype(extr->ips->ips_said.proto),
-+ 0,
-+ seq,
-+ pfkey_msg->sadb_msg_pid),
-+ extensions) &&
-+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
-+ 1 << SADB_EXT_SA)
-+ || pfkey_safe_build(pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ extr->ips->ips_replaywin,
-+ extr->ips->ips_state,
-+ extr->ips->ips_authalg,
-+ extr->ips->ips_encalg,
-+ extr->ips->ips_flags,
-+ extr->ips->ips_ref),
-+ extensions)) &&
-+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
-+ 1 << SADB_EXT_LIFETIME_CURRENT)
-+ || pfkey_safe_build(pfkey_lifetime_build(&extensions
-+ [SADB_EXT_LIFETIME_CURRENT],
-+ SADB_EXT_LIFETIME_CURRENT,
-+ extr->ips->ips_life.ipl_allocations.ipl_count,
-+ extr->ips->ips_life.ipl_bytes.ipl_count,
-+ extr->ips->ips_life.ipl_addtime.ipl_count,
-+ extr->ips->ips_life.ipl_usetime.ipl_count,
-+ extr->ips->ips_life.ipl_packets.ipl_count),
-+ extensions)) &&
-+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
-+ 1 << SADB_EXT_ADDRESS_SRC)
-+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ extr->ips->ips_said.proto,
-+ 0,
-+ extr->ips->ips_addr_s),
-+ extensions)) &&
-+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
-+ 1 << SADB_EXT_ADDRESS_DST)
-+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ extr->ips->ips_said.proto,
-+ 0,
-+ extr->ips->ips_addr_d),
-+ extensions));
-+
-+ if (error == 0) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
-+ "building extensions failed\n");
-+ return EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_build_reply: "
-+ "built extensions, proceed to build the message\n");
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_build_reply: "
-+ "extensions[1]=0p%p\n",
-+ extensions[1]);
-+ error = pfkey_msg_build(pfkey_reply, extensions, EXT_BITS_OUT);
-+ pfkey_extensions_free(extensions);
-+
-+ return error;
-+}
-+
-+int
-+pfkey_msg_interp(struct sock *sk, struct sadb_msg *pfkey_msg,
-+ struct sadb_msg **pfkey_reply)
-+{
-+ int error = 0;
-+ int i;
-+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
-+ struct pfkey_extracted_data extr = {NULL, NULL, NULL};
-+
-+ pfkey_extensions_init(extensions);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "parsing message ver=%d, type=%d, errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
-+ pfkey_msg->sadb_msg_version,
-+ pfkey_msg->sadb_msg_type,
-+ pfkey_msg->sadb_msg_errno,
-+ pfkey_msg->sadb_msg_satype,
-+ satype2name(pfkey_msg->sadb_msg_satype),
-+ pfkey_msg->sadb_msg_len,
-+ pfkey_msg->sadb_msg_reserved,
-+ pfkey_msg->sadb_msg_seq,
-+ pfkey_msg->sadb_msg_pid);
-+
-+ extr.ips = ipsec_sa_alloc(&error); /* pass in error var by pointer */
-+ if(extr.ips == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "memory allocation error.\n");
-+ SENDERR(-error);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "allocated extr->ips=0p%p.\n",
-+ extr.ips);
-+
-+ if(pfkey_msg->sadb_msg_satype > SADB_SATYPE_MAX) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "satype %d > max %d\n",
-+ pfkey_msg->sadb_msg_satype,
-+ SADB_SATYPE_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_msg->sadb_msg_type) {
-+ case SADB_GETSPI:
-+ case SADB_UPDATE:
-+ case SADB_ADD:
-+ case SADB_DELETE:
-+ case SADB_X_GRPSA:
-+ case SADB_X_ADDFLOW:
-+
-+ if(!(extr.ips->ips_said.proto = satype2proto(pfkey_msg->sadb_msg_satype))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "satype %d lookup failed.\n",
-+ pfkey_msg->sadb_msg_satype);
-+ SENDERR(EINVAL);
-+ } else {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "satype %d lookups to proto=%d.\n",
-+ pfkey_msg->sadb_msg_satype,
-+ extr.ips->ips_said.proto);
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ /* The NULL below causes the default extension parsers to be used */
-+ /* Parse the extensions */
-+ if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_IN)))
-+ {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "message parsing failed with error %d.\n",
-+ error);
-+ SENDERR(-error);
-+ }
-+
-+ /* Process the extensions */
-+ for(i=1; i <= SADB_EXT_MAX;i++) {
-+ if(extensions[i] != NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "processing ext %d 0p%p with processor 0p%p.\n",
-+ i, extensions[i], ext_processors[i]);
-+ if((error = ext_processors[i](extensions[i], &extr))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "extension processing for type %d failed with error %d.\n",
-+ i,
-+ error);
-+ SENDERR(-error);
-+ }
-+
-+ }
-+
-+ }
-+
-+ /* Parse the message types */
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "parsing message type %d(%s) with msg_parser 0p%p.\n",
-+ pfkey_msg->sadb_msg_type,
-+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
-+ msg_parsers[pfkey_msg->sadb_msg_type]);
-+ if((error = msg_parsers[pfkey_msg->sadb_msg_type](sk, extensions, &extr))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "message parsing failed with error %d.\n",
-+ error);
-+ SENDERR(-error);
-+ }
-+
-+#if 0
-+ error = pfkey_build_reply(pfkey_msg, &extr, pfkey_reply);
-+ if (error) {
-+ *pfkey_reply = NULL;
-+ }
-+#endif
-+ errlab:
-+ if(extr.ips != NULL) {
-+ ipsec_sa_wipe(extr.ips);
-+ }
-+ if(extr.ips2 != NULL) {
-+ ipsec_sa_wipe(extr.ips2);
-+ }
-+ if (extr.eroute != NULL) {
-+ kfree(extr.eroute);
-+ }
-+ return(error);
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.123 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.122.2.2 2004/04/05 04:30:46 mcr
-+ * patches for alg-branch to compile/work with 2.x openswan
-+ *
-+ * Revision 1.122.2.1 2003/12/22 15:25:52 jjo
-+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.122 2003/12/10 01:14:27 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.121 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.120.4.2 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.120.4.1 2003/09/21 13:59:56 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.120 2003/04/03 17:38:09 rgb
-+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
-+ *
-+ * Revision 1.119 2003/02/06 01:52:37 rgb
-+ * Removed no longer relevant comment
-+ *
-+ * Revision 1.118 2003/01/30 02:32:44 rgb
-+ *
-+ * Transmit error code through to caller from callee for better diagnosis of problems.
-+ *
-+ * Revision 1.117 2003/01/16 18:48:13 rgb
-+ *
-+ * Fixed sign bug in error return from an sa allocation call in
-+ * pfkey_msg_interp.
-+ *
-+ * Revision 1.116 2002/10/17 16:38:01 rgb
-+ * Change pfkey_alloc_eroute() to never static since its consumers
-+ * have been moved outside the file.
-+ *
-+ * Revision 1.115 2002/10/12 23:11:53 dhr
-+ *
-+ * [KenB + DHR] more 64-bit cleanup
-+ *
-+ * Revision 1.114 2002/10/05 05:02:58 dhr
-+ *
-+ * C labels go on statements
-+ *
-+ * Revision 1.113 2002/09/30 19:11:22 rgb
-+ * Turn on debugging for upgoing acquire messages to test for reliability.
-+ *
-+ * Revision 1.112 2002/09/20 15:41:16 rgb
-+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
-+ * Added sadb_x_sa_ref to struct sadb_sa.
-+ * Added ref parameter to pfkey_sa_build().
-+ *
-+ * Revision 1.111 2002/09/20 05:02:08 rgb
-+ * Added memory allocation debugging.
-+ * Convert to switch to divulge hmac keys for debugging.
-+ * Added text labels to elucidate numeric values presented.
-+ *
-+ * Revision 1.110 2002/08/03 18:03:05 mcr
-+ * loop that checks for SPI's to have been already linked
-+ * fails to actually step to next pointer, but continuously
-+ * resets to head of list. Wrong pointer used.
-+ * test east-icmp-02 revealed this.
-+ *
-+ * Revision 1.109 2002/07/26 08:48:31 rgb
-+ * Added SA ref table code.
-+ *
-+ * Revision 1.108 2002/05/27 18:55:03 rgb
-+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
-+ *
-+ * Revision 1.107 2002/05/23 07:16:08 rgb
-+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
-+ * Pointer clean-up.
-+ * Added refcount code.
-+ *
-+ * Revision 1.106 2002/05/14 02:34:13 rgb
-+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
-+ * with "put" usage in the kernel.
-+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
-+ * ipsec_sa or ipsec_sa.
-+ * Moved all the extension parsing functions to pfkey_v2_ext_process.c.
-+ *
-+ * Revision 1.105 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.104 2002/04/24 07:36:34 mcr
-+ * Moved from ./klips/net/ipsec/pfkey_v2_parser.c,v
-+ *
-+ * Revision 1.103 2002/04/20 00:12:25 rgb
-+ * Added esp IV CBC attack fix, disabled.
-+ *
-+ * Revision 1.102 2002/03/08 01:15:17 mcr
-+ * put some internal structure only debug messages behind
-+ * && sysctl_ipsec_debug_verbose.
-+ *
-+ * Revision 1.101 2002/01/29 17:17:57 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.100 2002/01/29 04:00:54 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.99 2002/01/29 02:13:19 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.98 2002/01/12 02:57:57 mcr
-+ * first regression test causes acquire messages to be lost
-+ * 100% of the time. This is to help testing of pluto.
-+ *
-+ * Revision 1.97 2001/11/26 09:23:52 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.93.2.4 2001/10/23 04:20:27 mcr
-+ * parity was forced on wrong structure! prototypes help here.
-+ *
-+ * Revision 1.93.2.3 2001/10/22 21:14:59 mcr
-+ * include des.h, removed phony prototypes and fixed calling
-+ * conventions to match real prototypes.
-+ *
-+ * Revision 1.93.2.2 2001/10/15 05:39:03 mcr
-+ * %08lx is not the right format for u32. Use %08x. 64-bit safe? ha.
-+ *
-+ * Revision 1.93.2.1 2001/09/25 02:30:14 mcr
-+ * struct tdb -> struct ipsec_sa.
-+ * use new lifetime structure. common format routines for debug.
-+ *
-+ * Revision 1.96 2001/11/06 20:47:54 rgb
-+ * Fixed user context call to ipsec_dev_start_xmit() bug. Call
-+ * dev_queue_xmit() instead.
-+ *
-+ * Revision 1.95 2001/11/06 19:47:46 rgb
-+ * Added packet parameter to lifetime and comb structures.
-+ *
-+ * Revision 1.94 2001/10/18 04:45:23 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/freeswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.93 2001/09/20 15:32:59 rgb
-+ * Min/max cleanup.
-+ *
-+ * Revision 1.92 2001/09/19 16:35:48 rgb
-+ * PF_KEY ident fix for getspi from NetCelo (puttdb duplication).
-+ *
-+ * Revision 1.91 2001/09/15 16:24:06 rgb
-+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
-+ *
-+ * Revision 1.90 2001/09/14 16:58:38 rgb
-+ * Added support for storing the first and last packets through a HOLD.
-+ *
-+ * Revision 1.89 2001/09/08 21:14:07 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ * Better state coherency (error management) between pf_key and IKE daemon.
-+ * (NetCelo)
-+ *
-+ * Revision 1.88 2001/08/27 19:42:44 rgb
-+ * Fix memory leak of encrypt and auth structs in pfkey register.
-+ *
-+ * Revision 1.87 2001/07/06 19:50:46 rgb
-+ * Removed unused debugging code.
-+ * Added inbound policy checking code for IPIP SAs.
-+ *
-+ * Revision 1.86 2001/06/20 06:26:04 rgb
-+ * Changed missing SA errors from EEXIST to ENOENT and added debug output
-+ * for already linked SAs.
-+ *
-+ * Revision 1.85 2001/06/15 04:57:02 rgb
-+ * Remove single error return condition check and check for all errors in
-+ * the case of a replace eroute delete operation. This means that
-+ * applications must expect to be deleting something before replacing it
-+ * and if nothing is found, complain.
-+ *
-+ * Revision 1.84 2001/06/14 19:35:12 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.83 2001/06/12 00:03:19 rgb
-+ * Silence debug set/unset under normal conditions.
-+ *
-+ * Revision 1.82 2001/05/30 08:14:04 rgb
-+ * Removed vestiges of esp-null transforms.
-+ *
-+ * Revision 1.81 2001/05/27 06:12:12 rgb
-+ * Added structures for pid, packet count and last access time to eroute.
-+ * Added packet count to beginning of /proc/net/ipsec_eroute.
-+ *
-+ * Revision 1.80 2001/05/03 19:43:59 rgb
-+ * Check error return codes for all build function calls.
-+ * Standardise on SENDERR() macro.
-+ *
-+ * Revision 1.79 2001/04/20 21:09:16 rgb
-+ * Cleaned up fixed tdbwipes.
-+ * Free pfkey_reply and clean up extensions_reply for grpsa, addflow and
-+ * delflow (Per Cederqvist) plugging memleaks.
-+ *
-+ * Revision 1.78 2001/04/19 19:02:39 rgb
-+ * Fixed extr.tdb freeing, stealing it for getspi, update and add.
-+ * Refined a couple of spinlocks, fixed the one in update.
-+ *
-+ * Revision 1.77 2001/04/18 20:26:16 rgb
-+ * Wipe/free eroute and both tdbs from extr at end of pfkey_msg_interp()
-+ * instead of inside each message type parser. This fixes two memleaks.
-+ *
-+ * Revision 1.76 2001/04/17 23:51:18 rgb
-+ * Quiet down pfkey_x_debug_process().
-+ *
-+ * Revision 1.75 2001/03/29 01:55:05 rgb
-+ * Fixed pfkey key init memleak.
-+ * Fixed pfkey encryption key debug output.
-+ *
-+ * Revision 1.74 2001/03/27 05:29:14 rgb
-+ * Debug output cleanup/silencing.
-+ *
-+ * Revision 1.73 2001/02/28 05:03:28 rgb
-+ * Clean up and rationalise startup messages.
-+ *
-+ * Revision 1.72 2001/02/27 22:24:56 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.71 2001/02/27 06:59:30 rgb
-+ * Added satype2name() conversions most places satype is debug printed.
-+ *
-+ * Revision 1.70 2001/02/26 22:37:08 rgb
-+ * Fixed 'unknown proto' INT bug in new code.
-+ * Added satype to protocol debugging instrumentation.
-+ *
-+ * Revision 1.69 2001/02/26 19:57:51 rgb
-+ * Re-formatted debug output (split lines, consistent spacing).
-+ * Fixed as yet undetected FLUSH bug which called ipsec_tdbcleanup()
-+ * with an satype instead of proto.
-+ * Checked for satype consistency and fixed minor bugs.
-+ * Fixed undetected ungrpspi bug that tried to upmsg a second tdb.
-+ * Check for satype sanity in pfkey_expire().
-+ * Added satype sanity check to addflow.
-+ *
-+ * Revision 1.68 2001/02/12 23:14:40 rgb
-+ * Remove double spin lock in pfkey_expire().
-+ *
-+ * Revision 1.67 2001/01/31 19:23:40 rgb
-+ * Fixed double-unlock bug introduced by grpsa upmsg (found by Lars Heete).
-+ *
-+ * Revision 1.66 2001/01/29 22:20:04 rgb
-+ * Fix minor add upmsg lifetime bug.
-+ *
-+ * Revision 1.65 2001/01/24 06:12:33 rgb
-+ * Fixed address extension compile bugs just introduced.
-+ *
-+ * Revision 1.64 2001/01/24 00:31:15 rgb
-+ * Added upmsg for addflow/delflow.
-+ *
-+ * Revision 1.63 2001/01/23 22:02:55 rgb
-+ * Added upmsg to x_grpsa.
-+ * Fixed lifetimes extentions to add/update/get upmsg.
-+ *
-+ * Revision 1.62 2000/11/30 21:47:51 rgb
-+ * Fix error return bug after returning from pfkey_tdb_init().
-+ *
-+ * Revision 1.61 2000/11/17 18:10:29 rgb
-+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
-+ * network byte order since this is the way PF_KEYv2 stored spis.
-+ *
-+ * Revision 1.60 2000/11/06 04:34:53 rgb
-+ * Changed non-exported functions to DEBUG_NO_STATIC.
-+ * Add Svenning's adaptive content compression.
-+ * Ditched spin_lock_irqsave in favour of spin_lock/_bh.
-+ * Fixed double unlock bug (Svenning).
-+ * Fixed pfkey_msg uninitialized bug in pfkey_{expire,acquire}().
-+ * Fixed incorrect extension type (prop) in pfkey)acquire().
-+ *
-+ * Revision 1.59 2000/10/11 15:25:12 rgb
-+ * Fixed IPCOMP disabled compile bug.
-+ *
-+ * Revision 1.58 2000/10/11 14:54:03 rgb
-+ * Fixed pfkey_acquire() satype to SADB_SATYPE_ESP and removed pfkey
-+ * protocol violations of setting pfkey_address_build() protocol parameter
-+ * to non-zero except in the case of pfkey_acquire().
-+ *
-+ * Revision 1.57 2000/10/10 20:10:18 rgb
-+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
-+ *
-+ * Revision 1.56 2000/10/06 20:24:36 rgb
-+ * Fixes to pfkey_acquire to initialize extensions[] and use correct
-+ * ipproto.
-+ *
-+ * Revision 1.55 2000/10/03 03:20:57 rgb
-+ * Added brackets to get a?b:c scope right for pfkey_register reply.
-+ *
-+ * Revision 1.54 2000/09/29 19:49:30 rgb
-+ * As-yet-unused-bits cleanup.
-+ *
-+ * Revision 1.53 2000/09/28 00:35:45 rgb
-+ * Padded SATYPE printout in pfkey_register for vertical alignment.
-+ *
-+ * Revision 1.52 2000/09/20 16:21:58 rgb
-+ * Cleaned up ident string alloc/free.
-+ *
-+ * Revision 1.51 2000/09/20 04:04:20 rgb
-+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
-+ * oopsen.
-+ *
-+ * Revision 1.50 2000/09/16 01:10:53 rgb
-+ * Fixed unused var warning with debug off.
-+ *
-+ * Revision 1.49 2000/09/15 11:37:02 rgb
-+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
-+ * IPCOMP zlib deflate code.
-+ *
-+ * Revision 1.48 2000/09/15 04:57:57 rgb
-+ * Cleaned up existing IPCOMP code before svenning addition.
-+ * Initialize pfkey_reply and extensions_reply in case of early error in
-+ * message parsing functions (thanks Kai!).
-+ *
-+ * Revision 1.47 2000/09/13 08:02:56 rgb
-+ * Added KMd registration notification.
-+ *
-+ * Revision 1.46 2000/09/12 22:35:36 rgb
-+ * Restructured to remove unused extensions from CLEARFLOW messages.
-+ *
-+ * Revision 1.45 2000/09/12 03:24:23 rgb
-+ * Converted #if0 debugs to sysctl.
-+ *
-+ * Revision 1.44 2000/09/09 06:38:39 rgb
-+ * Correct SADB message type for update, add and delete.
-+ *
-+ * Revision 1.43 2000/09/08 19:19:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
-+ * Put in sanity checks in most msg type parsers to catch invalid satypes
-+ * and empty socket lists.
-+ * Moved spin-locks in pfkey_get_parse() to simplify.
-+ * Added pfkey_acquire().
-+ * Added upwards messages to update, add, delete, acquire_parse,
-+ * expire_parse and flush.
-+ * Fix pfkey_prop_build() parameter to be only single indirection.
-+ * Changed all replies to use pfkey_reply.
-+ * Check return code on puttdb() and deltdbchain() in getspi, update,
-+ * add, delete.
-+ * Fixed up all pfkey replies to open and registered sockets.
-+ *
-+ * Revision 1.42 2000/09/01 18:50:26 rgb
-+ * Added a supported algorithms array lists, one per satype and registered
-+ * existing algorithms.
-+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
-+ * list.
-+ * Only send pfkey_expire() messages to sockets registered for that satype.
-+ * Added reply to pfkey_getspi_parse().
-+ * Added reply to pfkey_get_parse().
-+ * Fixed debug output label bug in pfkey_lifetime_process().
-+ * Cleaned up pfkey_sa_process a little.
-+ * Moved pfkey_safe_build() above message type parsers to make it available
-+ * for creating replies.
-+ * Added comments for future work in pfkey_acquire_parse().
-+ * Fleshed out guts of pfkey_register_parse().
-+ *
-+ * Revision 1.41 2000/08/24 16:58:11 rgb
-+ * Fixed key debugging variables.
-+ * Fixed error return code for a failed search.
-+ * Changed order of pfkey_get operations.
-+ *
-+ * Revision 1.40 2000/08/21 16:32:27 rgb
-+ * Re-formatted for cosmetic consistency and readability.
-+ *
-+ * Revision 1.39 2000/08/20 21:38:57 rgb
-+ * Bugfixes to as-yet-unused pfkey_update_parse() and
-+ * pfkey_register_parse(). (Momchil)
-+ * Added functions pfkey_safe_build(), pfkey_expire() and
-+ * pfkey_build_reply(). (Momchil)
-+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
-+ *
-+ * Revision 1.38 2000/08/18 21:30:41 rgb
-+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
-+ *
-+ * Revision 1.37 2000/08/18 18:18:02 rgb
-+ * Cosmetic and descriptive changes made to debug test.
-+ * getspi and update fixes from Momchil.
-+ *
-+ * Revision 1.36 2000/08/15 15:41:55 rgb
-+ * Fixed the (as yet unused and untested) pfkey_getspi() routine.
-+ *
-+ * Revision 1.35 2000/08/01 14:51:52 rgb
-+ * Removed _all_ remaining traces of DES.
-+ *
-+ * Revision 1.34 2000/07/28 14:58:32 rgb
-+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
-+ *
-+ * Revision 1.33 2000/06/28 05:50:11 rgb
-+ * Actually set iv_bits.
-+ *
-+ * Revision 1.32 2000/05/30 18:36:56 rgb
-+ * Fix AH auth hash setup bug. This breaks interop with previous PF_KEY
-+ * FreeS/WAN, but fixes interop with other implementations.
-+ *
-+ * Revision 1.31 2000/03/16 14:05:48 rgb
-+ * Fixed brace scope preventing non-debug compile.
-+ * Added null parameter check for pfkey_x_debug().
-+ *
-+ * Revision 1.30 2000/01/22 23:21:13 rgb
-+ * Use new function satype2proto().
-+ *
-+ * Revision 1.29 2000/01/22 08:40:21 rgb
-+ * Invert condition to known value to avoid AF_INET6 in 2.0.36.
-+ *
-+ * Revision 1.28 2000/01/22 07:58:57 rgb
-+ * Fixed REPLACEFLOW bug, missing braces around KLIPS_PRINT *and* SENDERR.
-+ *
-+ * Revision 1.27 2000/01/22 03:48:01 rgb
-+ * Added extr pointer component debugging.
-+ *
-+ * Revision 1.26 2000/01/21 09:41:25 rgb
-+ * Changed a (void*) to (char*) cast to do proper pointer math.
-+ * Don't call tdbwipe if tdb2 is NULL.
-+ *
-+ * Revision 1.25 2000/01/21 06:21:01 rgb
-+ * Added address cases for eroute flows.
-+ * Tidied up compiler directive indentation for readability.
-+ * Added ictx,octx vars for simplification.
-+ * Added macros for HMAC padding magic numbers.
-+ * Converted from double tdb arguments to one structure (extr)
-+ * containing pointers to all temporary information structures
-+ * and checking for valid arguments to all ext processors and
-+ * msg type parsers.
-+ * Added spiungrp'ing.
-+ * Added klipsdebug switching capability.
-+ * Removed sa_process() check for zero protocol.
-+ * Added address case for DST2 for grouping.
-+ * Added/changed minor debugging instrumentation.
-+ * Fixed spigrp for single said, ungrouping case.
-+ * Added code to parse addflow and delflow messages.
-+ * Removed redundant statements duplicating tdbwipe() functionality
-+ * and causing double kfrees.
-+ * Permit addflow to have a protocol of 0.
-+ *
-+ * Revision 1.24 1999/12/09 23:23:00 rgb
-+ * Added check to pfkey_sa_process() to do eroutes.
-+ * Converted to DIVUP() macro.
-+ * Converted if() to switch() in pfkey_register_parse().
-+ * Use new pfkey_extensions_init() instead of memset().
-+ *
-+ * Revision 1.23 1999/12/01 22:18:13 rgb
-+ * Preset minspi and maxspi values in case and spirange extension is not
-+ * included and check for the presence of an spirange extension before
-+ * using it. Initialise tdb_sastate to LARVAL.
-+ * Fixed debugging output typo.
-+ * Fixed authentication context initialisation bugs (4 places).
-+ *
-+ * Revision 1.22 1999/11/27 11:53:08 rgb
-+ * Moved pfkey_msg_parse prototype to pfkey.h
-+ * Moved exts_permitted/required prototype to pfkey.h.
-+ * Moved sadb_satype2proto protocol lookup table to lib/pfkey_v2_parse.c.
-+ * Deleted SADB_X_EXT_SA2 code from pfkey_sa_process() since it will never
-+ * be called.
-+ * Moved protocol/algorithm checks to lib/pfkey_v2_parse.c
-+ * Debugging error messages added.
-+ * Enable lifetime_current checking.
-+ * Remove illegal requirement for SA extension to be present in an
-+ * originating GETSPI call.
-+ * Re-instate requirement for UPDATE or ADD message to be MATURE.
-+ * Add argument to pfkey_msg_parse() for direction.
-+ * Fixed IPIP dst address bug and purged redundant, leaky code.
-+ *
-+ * Revision 1.21 1999/11/24 05:24:20 rgb
-+ * hanged 'void*extensions' to 'struct sadb_ext*extensions'.
-+ * Fixed indention.
-+ * Ditched redundant replay check.
-+ * Fixed debug message text from 'parse' to 'process'.
-+ * Added more debug output.
-+ * Forgot to zero extensions array causing bug, fixed.
-+ *
-+ * Revision 1.20 1999/11/23 23:08:13 rgb
-+ * Move all common parsing code to lib/pfkey_v2_parse.c and rename
-+ * remaining bits to *_process. (PJO)
-+ * Add macros for dealing with alignment and rounding up more opaquely.
-+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
-+ * Sort out pfkey and freeswan headers, putting them in a library path.
-+ * Corrected a couple of bugs in as-yet-inactive code.
-+ *
-+ * Revision 1.19 1999/11/20 22:01:10 rgb
-+ * Add more descriptive error messages for non-zero reserved fields.
-+ * Add more descriptive error message for spirange parsing.
-+ * Start on supported extension parsing.
-+ * Start on register and get message parsing.
-+ *
-+ * Revision 1.18 1999/11/18 04:09:20 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ *
-+ * Revision 1.17 1999/11/17 15:53:41 rgb
-+ * Changed all occurrences of #include "../../../lib/freeswan.h"
-+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
-+ * klips/net/ipsec/Makefile.
-+ *
-+ * Revision 1.16 1999/10/26 16:57:43 rgb
-+ * Add shorter macros for compiler directives to visually clean-up.
-+ * Give ipv6 code meaningful compiler directive.
-+ * Add comments to other #if 0 debug code.
-+ * Remove unused *_bh_atomic() calls.
-+ * Fix mis-placed spinlock.
-+ *
-+ * Revision 1.15 1999/10/16 18:27:10 rgb
-+ * Clean-up unused cruft.
-+ * Fix-up lifetime_allocations_c and lifetime_addtime_c initialisations.
-+ *
-+ * Revision 1.14 1999/10/08 18:37:34 rgb
-+ * Fix end-of-line spacing to sate whining PHMs.
-+ *
-+ * Revision 1.13 1999/10/03 18:49:12 rgb
-+ * Spinlock fixes for 2.0.xx and 2.3.xx.
-+ *
-+ * Revision 1.12 1999/10/01 15:44:54 rgb
-+ * Move spinlock header include to 2.1> scope.
-+ *
-+ * Revision 1.11 1999/10/01 00:05:45 rgb
-+ * Added tdb structure locking.
-+ * Use 'jiffies' instead of do_get_timeofday().
-+ * Fix lifetime assignments.
-+ *
-+ * Revision 1.10 1999/09/21 15:24:45 rgb
-+ * Rework spirange code to save entropy and prevent endless loops.
-+ *
-+ * Revision 1.9 1999/09/16 12:10:21 rgb
-+ * Minor fixes to random spi selection for correctness and entropy conservation.
-+ *
-+ * Revision 1.8 1999/05/25 22:54:46 rgb
-+ * Fix comparison that should be an assignment in an if.
-+ *
-+ * Revision 1.7 1999/05/09 03:25:37 rgb
-+ * Fix bug introduced by 2.2 quick-and-dirty patch.
-+ *
-+ * Revision 1.6 1999/05/08 21:32:30 rgb
-+ * Fix error return reporting.
-+ *
-+ * Revision 1.5 1999/05/05 22:02:33 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.4 1999/04/29 15:22:40 rgb
-+ * Standardise an error return method.
-+ * Add debugging instrumentation.
-+ * Add check for existence of macros min/max.
-+ * Add extensions permitted/required in/out filters.
-+ * Add satype-to-protocol table.
-+ * Add a second tdb pointer to each parser to accomodate GRPSA.
-+ * Move AH & no_algo_set to GETSPI, UPDATE and ADD.
-+ * Add OOO window check.
-+ * Add support for IPPROTO_IPIP and hooks for IPPROTO_COMP.
-+ * Add timestamp to lifetime parse.
-+ * Fix address structure length checking bug.
-+ * Fix address structure allocation bug (forgot to kmalloc!).
-+ * Add checks for extension lengths.
-+ * Add checks for extension reserved illegal values.
-+ * Add check for spirange legal values.
-+ * Add an extension type for parsing a second satype, SA and
-+ * DST_ADDRESS.
-+ * Make changes to tdb_init() template to get pfkey_tdb_init(),
-+ * eliminating any mention of xformsw.
-+ * Implement getspi, update and grpsa (not tested).
-+ * Add stubs for as yet unimplemented message types.
-+ * Add table of message parsers to substitute for msg_parse switch.
-+ *
-+ * Revision 1.3 1999/04/15 17:58:07 rgb
-+ * Add RCSID labels.
-+ *
-+ * Revision 1.2 1999/04/15 15:37:26 rgb
-+ * Forward check changes from POST1_00 branch.
-+ *
-+ * Revision 1.1.2.1 1999/03/26 20:58:56 rgb
-+ * Add pfkeyv2 support to KLIPS.
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/radij.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1225 @@
-+char radij_c_version[] = "RCSID $Id$";
-+
-+/*
-+ * This file is defived from ${SRC}/sys/net/radix.c of BSD 4.4lite
-+ *
-+ * Variable and procedure names have been modified so that they don't
-+ * conflict with the original BSD code, as a small number of modifications
-+ * have been introduced and we may want to reuse this code in BSD.
-+ *
-+ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
-+ * chi or a German ch sound (as `doch', not as in `milch'), or even a
-+ * spanish j as in Juan. It is not as far back in the throat like
-+ * the corresponding Hebrew sound, nor is it a soft breath like the English h.
-+ * It has nothing to do with the Dutch ij sound.
-+ *
-+ * Here is the appropriate copyright notice:
-+ */
-+
-+/*
-+ * Copyright (c) 1988, 1989, 1993
-+ * The Regents of the University of California. All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * This product includes software developed by the University of
-+ * California, Berkeley and its contributors.
-+ * 4. Neither the name of the University nor the names of its contributors
-+ * may be used to endorse or promote products derived from this software
-+ * without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * @(#)radix.c 8.2 (Berkeley) 1/4/94
-+ */
-+
-+/*
-+ * Routines to build and maintain radix trees for routing lookups.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+#endif /* NET_21 */
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include <openswan.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+
-+int maj_keylen;
-+struct radij_mask *rj_mkfreelist;
-+struct radij_node_head *mask_rjhead;
-+static int gotOddMasks;
-+static char *maskedKey;
-+static char *rj_zeroes, *rj_ones;
-+
-+#define rj_masktop (mask_rjhead->rnh_treetop)
-+#ifdef Bcmp
-+# undef Bcmp
-+#endif /* Bcmp */
-+#define Bcmp(a, b, l) (l == 0 ? 0 : memcmp((caddr_t)(b), (caddr_t)(a), (size_t)l))
-+/*
-+ * The data structure for the keys is a radix tree with one way
-+ * branching removed. The index rj_b at an internal node n represents a bit
-+ * position to be tested. The tree is arranged so that all descendants
-+ * of a node n have keys whose bits all agree up to position rj_b - 1.
-+ * (We say the index of n is rj_b.)
-+ *
-+ * There is at least one descendant which has a one bit at position rj_b,
-+ * and at least one with a zero there.
-+ *
-+ * A route is determined by a pair of key and mask. We require that the
-+ * bit-wise logical and of the key and mask to be the key.
-+ * We define the index of a route to associated with the mask to be
-+ * the first bit number in the mask where 0 occurs (with bit number 0
-+ * representing the highest order bit).
-+ *
-+ * We say a mask is normal if every bit is 0, past the index of the mask.
-+ * If a node n has a descendant (k, m) with index(m) == index(n) == rj_b,
-+ * and m is a normal mask, then the route applies to every descendant of n.
-+ * If the index(m) < rj_b, this implies the trailing last few bits of k
-+ * before bit b are all 0, (and hence consequently true of every descendant
-+ * of n), so the route applies to all descendants of the node as well.
-+ *
-+ * The present version of the code makes no use of normal routes,
-+ * but similar logic shows that a non-normal mask m such that
-+ * index(m) <= index(n) could potentially apply to many children of n.
-+ * Thus, for each non-host route, we attach its mask to a list at an internal
-+ * node as high in the tree as we can go.
-+ */
-+
-+struct radij_node *
-+rj_search(v_arg, head)
-+ void *v_arg;
-+ struct radij_node *head;
-+{
-+ register struct radij_node *x;
-+ register caddr_t v;
-+
-+ for (x = head, v = v_arg; x->rj_b >= 0;) {
-+ if (x->rj_bmask & v[x->rj_off])
-+ x = x->rj_r;
-+ else
-+ x = x->rj_l;
-+ }
-+ return (x);
-+};
-+
-+struct radij_node *
-+rj_search_m(v_arg, head, m_arg)
-+ struct radij_node *head;
-+ void *v_arg, *m_arg;
-+{
-+ register struct radij_node *x;
-+ register caddr_t v = v_arg, m = m_arg;
-+
-+ for (x = head; x->rj_b >= 0;) {
-+ if ((x->rj_bmask & m[x->rj_off]) &&
-+ (x->rj_bmask & v[x->rj_off]))
-+ x = x->rj_r;
-+ else
-+ x = x->rj_l;
-+ }
-+ return x;
-+};
-+
-+int
-+rj_refines(m_arg, n_arg)
-+ void *m_arg, *n_arg;
-+{
-+ register caddr_t m = m_arg, n = n_arg;
-+ register caddr_t lim, lim2 = lim = n + *(u_char *)n;
-+ int longer = (*(u_char *)n++) - (int)(*(u_char *)m++);
-+ int masks_are_equal = 1;
-+
-+ if (longer > 0)
-+ lim -= longer;
-+ while (n < lim) {
-+ if (*n & ~(*m))
-+ return 0;
-+ if (*n++ != *m++)
-+ masks_are_equal = 0;
-+
-+ }
-+ while (n < lim2)
-+ if (*n++)
-+ return 0;
-+ if (masks_are_equal && (longer < 0))
-+ for (lim2 = m - longer; m < lim2; )
-+ if (*m++)
-+ return 1;
-+ return (!masks_are_equal);
-+}
-+
-+
-+struct radij_node *
-+rj_match(v_arg, head)
-+ void *v_arg;
-+ struct radij_node_head *head;
-+{
-+ caddr_t v = v_arg;
-+ register struct radij_node *t = head->rnh_treetop, *x;
-+ register caddr_t cp = v, cp2, cp3;
-+ caddr_t cplim, mstart;
-+ struct radij_node *saved_t, *top = t;
-+ int off = t->rj_off, vlen = *(u_char *)cp, matched_off;
-+
-+ /*
-+ * Open code rj_search(v, top) to avoid overhead of extra
-+ * subroutine call.
-+ */
-+ for (; t->rj_b >= 0; ) {
-+ if (t->rj_bmask & cp[t->rj_off])
-+ t = t->rj_r;
-+ else
-+ t = t->rj_l;
-+ }
-+ /*
-+ * See if we match exactly as a host destination
-+ */
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:rj_match: "
-+ "* See if we match exactly as a host destination\n");
-+
-+ cp += off; cp2 = t->rj_key + off; cplim = v + vlen;
-+ for (; cp < cplim; cp++, cp2++)
-+ if (*cp != *cp2)
-+ goto on1;
-+ /*
-+ * This extra grot is in case we are explicitly asked
-+ * to look up the default. Ugh!
-+ */
-+ if ((t->rj_flags & RJF_ROOT) && t->rj_dupedkey)
-+ t = t->rj_dupedkey;
-+ return t;
-+on1:
-+ matched_off = cp - v;
-+ saved_t = t;
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:rj_match: "
-+ "** try to match a leaf, t=0p%p\n", t);
-+ do {
-+ if (t->rj_mask) {
-+ /*
-+ * Even if we don't match exactly as a hosts;
-+ * we may match if the leaf we wound up at is
-+ * a route to a net.
-+ */
-+ cp3 = matched_off + t->rj_mask;
-+ cp2 = matched_off + t->rj_key;
-+ for (; cp < cplim; cp++)
-+ if ((*cp2++ ^ *cp) & *cp3++)
-+ break;
-+ if (cp == cplim)
-+ return t;
-+ cp = matched_off + v;
-+ }
-+ } while ((t = t->rj_dupedkey));
-+ t = saved_t;
-+ /* start searching up the tree */
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:rj_match: "
-+ "*** start searching up the tree, t=0p%p\n",
-+ t);
-+ do {
-+ register struct radij_mask *m;
-+
-+ t = t->rj_p;
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:rj_match: "
-+ "**** t=0p%p\n",
-+ t);
-+ if ((m = t->rj_mklist)) {
-+ /*
-+ * After doing measurements here, it may
-+ * turn out to be faster to open code
-+ * rj_search_m here instead of always
-+ * copying and masking.
-+ */
-+ /* off = min(t->rj_off, matched_off); */
-+ off = t->rj_off;
-+ if (matched_off < off)
-+ off = matched_off;
-+ mstart = maskedKey + off;
-+ do {
-+ cp2 = mstart;
-+ cp3 = m->rm_mask + off;
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:rj_match: "
-+ "***** cp2=0p%p cp3=0p%p\n",
-+ cp2, cp3);
-+ for (cp = v + off; cp < cplim;)
-+ *cp2++ = *cp++ & *cp3++;
-+ x = rj_search(maskedKey, t);
-+ while (x && x->rj_mask != m->rm_mask)
-+ x = x->rj_dupedkey;
-+ if (x &&
-+ (Bcmp(mstart, x->rj_key + off,
-+ vlen - off) == 0))
-+ return x;
-+ } while ((m = m->rm_mklist));
-+ }
-+ } while (t != top);
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:rj_match: "
-+ "***** not found.\n");
-+ return 0;
-+};
-+
-+#ifdef RJ_DEBUG
-+int rj_nodenum;
-+struct radij_node *rj_clist;
-+int rj_saveinfo;
-+DEBUG_NO_STATIC void traverse(struct radij_node *);
-+#ifdef RJ_DEBUG2
-+int rj_debug = 1;
-+#else
-+int rj_debug = 0;
-+#endif /* RJ_DEBUG2 */
-+#endif /* RJ_DEBUG */
-+
-+struct radij_node *
-+rj_newpair(v, b, nodes)
-+ void *v;
-+ int b;
-+ struct radij_node nodes[2];
-+{
-+ register struct radij_node *tt = nodes, *t = tt + 1;
-+ t->rj_b = b; t->rj_bmask = 0x80 >> (b & 7);
-+ t->rj_l = tt; t->rj_off = b >> 3;
-+ tt->rj_b = -1; tt->rj_key = (caddr_t)v; tt->rj_p = t;
-+ tt->rj_flags = t->rj_flags = RJF_ACTIVE;
-+#ifdef RJ_DEBUG
-+ tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
-+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
-+#endif /* RJ_DEBUG */
-+ return t;
-+}
-+
-+struct radij_node *
-+rj_insert(v_arg, head, dupentry, nodes)
-+ void *v_arg;
-+ struct radij_node_head *head;
-+ int *dupentry;
-+ struct radij_node nodes[2];
-+{
-+ caddr_t v = v_arg;
-+ struct radij_node *top = head->rnh_treetop;
-+ int head_off = top->rj_off, vlen = (int)*((u_char *)v);
-+ register struct radij_node *t = rj_search(v_arg, top);
-+ register caddr_t cp = v + head_off;
-+ register int b;
-+ struct radij_node *tt;
-+ /*
-+ *find first bit at which v and t->rj_key differ
-+ */
-+ {
-+ register caddr_t cp2 = t->rj_key + head_off;
-+ register int cmp_res;
-+ caddr_t cplim = v + vlen;
-+
-+ while (cp < cplim)
-+ if (*cp2++ != *cp++)
-+ goto on1;
-+ *dupentry = 1;
-+ return t;
-+on1:
-+ *dupentry = 0;
-+ cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
-+ for (b = (cp - v) << 3; cmp_res; b--)
-+ cmp_res >>= 1;
-+ }
-+ {
-+ register struct radij_node *p, *x = top;
-+ cp = v;
-+ do {
-+ p = x;
-+ if (cp[x->rj_off] & x->rj_bmask)
-+ x = x->rj_r;
-+ else x = x->rj_l;
-+ } while (b > (unsigned) x->rj_b); /* x->rj_b < b && x->rj_b >= 0 */
-+#ifdef RJ_DEBUG
-+ if (rj_debug)
-+ printk("klips_debug:rj_insert: Going In:\n"), traverse(p);
-+#endif /* RJ_DEBUG */
-+ t = rj_newpair(v_arg, b, nodes); tt = t->rj_l;
-+ if ((cp[p->rj_off] & p->rj_bmask) == 0)
-+ p->rj_l = t;
-+ else
-+ p->rj_r = t;
-+ x->rj_p = t; t->rj_p = p; /* frees x, p as temp vars below */
-+ if ((cp[t->rj_off] & t->rj_bmask) == 0) {
-+ t->rj_r = x;
-+ } else {
-+ t->rj_r = tt; t->rj_l = x;
-+ }
-+#ifdef RJ_DEBUG
-+ if (rj_debug)
-+ printk("klips_debug:rj_insert: Coming out:\n"), traverse(p);
-+#endif /* RJ_DEBUG */
-+ }
-+ return (tt);
-+}
-+
-+struct radij_node *
-+rj_addmask(n_arg, search, skip)
-+ int search, skip;
-+ void *n_arg;
-+{
-+ caddr_t netmask = (caddr_t)n_arg;
-+ register struct radij_node *x;
-+ register caddr_t cp, cplim;
-+ register int b, mlen, j;
-+ int maskduplicated;
-+
-+ mlen = *(u_char *)netmask;
-+ if (search) {
-+ x = rj_search(netmask, rj_masktop);
-+ mlen = *(u_char *)netmask;
-+ if (Bcmp(netmask, x->rj_key, mlen) == 0)
-+ return (x);
-+ }
-+ R_Malloc(x, struct radij_node *, maj_keylen + 2 * sizeof (*x));
-+ if (x == 0)
-+ return (0);
-+ Bzero(x, maj_keylen + 2 * sizeof (*x));
-+ cp = (caddr_t)(x + 2);
-+ Bcopy(netmask, cp, mlen);
-+ netmask = cp;
-+ x = rj_insert(netmask, mask_rjhead, &maskduplicated, x);
-+ /*
-+ * Calculate index of mask.
-+ */
-+ cplim = netmask + mlen;
-+ for (cp = netmask + skip; cp < cplim; cp++)
-+ if (*(u_char *)cp != 0xff)
-+ break;
-+ b = (cp - netmask) << 3;
-+ if (cp != cplim) {
-+ if (*cp != 0) {
-+ gotOddMasks = 1;
-+ for (j = 0x80; j; b++, j >>= 1)
-+ if ((j & *cp) == 0)
-+ break;
-+ }
-+ }
-+ x->rj_b = -1 - b;
-+ return (x);
-+}
-+
-+#if 0
-+struct radij_node *
-+#endif
-+int
-+rj_addroute(v_arg, n_arg, head, treenodes)
-+ void *v_arg, *n_arg;
-+ struct radij_node_head *head;
-+ struct radij_node treenodes[2];
-+{
-+ caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
-+ register struct radij_node *t, *x=NULL, *tt;
-+ struct radij_node *saved_tt, *top = head->rnh_treetop;
-+ short b = 0, b_leaf;
-+ int mlen, keyduplicated;
-+ caddr_t cplim;
-+ struct radij_mask *m, **mp;
-+
-+ /*
-+ * In dealing with non-contiguous masks, there may be
-+ * many different routes which have the same mask.
-+ * We will find it useful to have a unique pointer to
-+ * the mask to speed avoiding duplicate references at
-+ * nodes and possibly save time in calculating indices.
-+ */
-+ if (netmask) {
-+ x = rj_search(netmask, rj_masktop);
-+ mlen = *(u_char *)netmask;
-+ if (Bcmp(netmask, x->rj_key, mlen) != 0) {
-+ x = rj_addmask(netmask, 0, top->rj_off);
-+ if (x == 0)
-+ return -ENOMEM; /* (0) rgb */
-+ }
-+ netmask = x->rj_key;
-+ b = -1 - x->rj_b;
-+ }
-+ /*
-+ * Deal with duplicated keys: attach node to previous instance
-+ */
-+ saved_tt = tt = rj_insert(v, head, &keyduplicated, treenodes);
-+#ifdef RJ_DEBUG
-+ printk("addkey: duplicated: %d\n", keyduplicated);
-+#endif
-+ if (keyduplicated) {
-+ do {
-+ if (tt->rj_mask == netmask)
-+ return -EEXIST; /* -ENXIO; (0) rgb */
-+ t = tt;
-+ if (netmask == 0 ||
-+ (tt->rj_mask && rj_refines(netmask, tt->rj_mask)))
-+ break;
-+ } while ((tt = tt->rj_dupedkey));
-+ /*
-+ * If the mask is not duplicated, we wouldn't
-+ * find it among possible duplicate key entries
-+ * anyway, so the above test doesn't hurt.
-+ *
-+ * We sort the masks for a duplicated key the same way as
-+ * in a masklist -- most specific to least specific.
-+ * This may require the unfortunate nuisance of relocating
-+ * the head of the list.
-+ */
-+ if (tt && t == saved_tt) {
-+ struct radij_node *xx = x;
-+ /* link in at head of list */
-+ (tt = treenodes)->rj_dupedkey = t;
-+ tt->rj_flags = t->rj_flags;
-+ tt->rj_p = x = t->rj_p;
-+ if (x->rj_l == t) x->rj_l = tt; else x->rj_r = tt;
-+ saved_tt = tt; x = xx;
-+ } else {
-+ (tt = treenodes)->rj_dupedkey = t->rj_dupedkey;
-+ t->rj_dupedkey = tt;
-+ }
-+#ifdef RJ_DEBUG
-+ t=tt+1; tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
-+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
-+#endif /* RJ_DEBUG */
-+ t = saved_tt;
-+ tt->rj_key = (caddr_t) v;
-+ tt->rj_b = -1;
-+ tt->rj_flags = t->rj_flags & ~RJF_ROOT;
-+ }
-+ /*
-+ * Put mask in tree.
-+ */
-+ if (netmask) {
-+ tt->rj_mask = netmask;
-+ tt->rj_b = x->rj_b;
-+ }
-+ t = saved_tt->rj_p;
-+ b_leaf = -1 - t->rj_b;
-+ if (t->rj_r == saved_tt) x = t->rj_l; else x = t->rj_r;
-+ /* Promote general routes from below */
-+ if (x->rj_b < 0) {
-+ if (x->rj_mask && (x->rj_b >= b_leaf) && x->rj_mklist == 0) {
-+ MKGet(m);
-+ if (m) {
-+ Bzero(m, sizeof *m);
-+ m->rm_b = x->rj_b;
-+ m->rm_mask = x->rj_mask;
-+ x->rj_mklist = t->rj_mklist = m;
-+ }
-+ }
-+ } else if (x->rj_mklist) {
-+ /*
-+ * Skip over masks whose index is > that of new node
-+ */
-+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
-+ if (m->rm_b >= b_leaf)
-+ break;
-+ t->rj_mklist = m; *mp = 0;
-+ }
-+ /* Add new route to highest possible ancestor's list */
-+ if ((netmask == 0) || (b > t->rj_b )) {
-+#ifdef RJ_DEBUG
-+ printk("klips:radij.c: netmask = %p or b(%d)>t->rjb(%d)\n", netmask, b, t->rj_b);
-+#endif
-+ return 0; /* tt rgb */ /* can't lift at all */
-+ }
-+ b_leaf = tt->rj_b;
-+ do {
-+ x = t;
-+ t = t->rj_p;
-+ } while (b <= t->rj_b && x != top);
-+ /*
-+ * Search through routes associated with node to
-+ * insert new route according to index.
-+ * For nodes of equal index, place more specific
-+ * masks first.
-+ */
-+ cplim = netmask + mlen;
-+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) {
-+ if (m->rm_b < b_leaf)
-+ continue;
-+ if (m->rm_b > b_leaf)
-+ break;
-+ if (m->rm_mask == netmask) {
-+ m->rm_refs++;
-+ tt->rj_mklist = m;
-+#ifdef RJ_DEBUG
-+ printk("klips:radij.c: m->rm_mask %p == netmask\n", netmask);
-+#endif
-+ return 0; /* tt rgb */
-+ }
-+ if (rj_refines(netmask, m->rm_mask))
-+ break;
-+ }
-+ MKGet(m);
-+ if (m == 0) {
-+ printk("klips_debug:rj_addroute: "
-+ "Mask for route not entered\n");
-+ return 0; /* (tt) rgb */
-+ }
-+ Bzero(m, sizeof *m);
-+ m->rm_b = b_leaf;
-+ m->rm_mask = netmask;
-+ m->rm_mklist = *mp;
-+ *mp = m;
-+ tt->rj_mklist = m;
-+#ifdef RJ_DEBUG
-+ printk("klips:radij.c: addroute done\n");
-+#endif
-+ return 0; /* tt rgb */
-+}
-+
-+int
-+rj_delete(v_arg, netmask_arg, head, node)
-+ void *v_arg, *netmask_arg;
-+ struct radij_node_head *head;
-+ struct radij_node **node;
-+{
-+ register struct radij_node *t, *p, *x, *tt;
-+ struct radij_mask *m, *saved_m, **mp;
-+ struct radij_node *dupedkey, *saved_tt, *top;
-+ caddr_t v, netmask;
-+ int b, head_off, vlen;
-+
-+ v = v_arg;
-+ netmask = netmask_arg;
-+ x = head->rnh_treetop;
-+ tt = rj_search(v, x);
-+ head_off = x->rj_off;
-+ vlen = *(u_char *)v;
-+ saved_tt = tt;
-+ top = x;
-+ if (tt == 0 ||
-+ Bcmp(v + head_off, tt->rj_key + head_off, vlen - head_off))
-+ return -EFAULT; /* (0) rgb */
-+ /*
-+ * Delete our route from mask lists.
-+ */
-+ if ((dupedkey = tt->rj_dupedkey)) {
-+ if (netmask)
-+ netmask = rj_search(netmask, rj_masktop)->rj_key;
-+ while (tt->rj_mask != netmask)
-+ if ((tt = tt->rj_dupedkey) == 0)
-+ return -ENOENT; /* -ENXIO; (0) rgb */
-+ }
-+ if (tt->rj_mask == 0 || (saved_m = m = tt->rj_mklist) == 0)
-+ goto on1;
-+ if (m->rm_mask != tt->rj_mask) {
-+ printk("klips_debug:rj_delete: "
-+ "inconsistent annotation\n");
-+ goto on1;
-+ }
-+ if (--m->rm_refs >= 0)
-+ goto on1;
-+ b = -1 - tt->rj_b;
-+ t = saved_tt->rj_p;
-+ if (b > t->rj_b)
-+ goto on1; /* Wasn't lifted at all */
-+ do {
-+ x = t;
-+ t = t->rj_p;
-+ } while (b <= t->rj_b && x != top);
-+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
-+ if (m == saved_m) {
-+ *mp = m->rm_mklist;
-+ MKFree(m);
-+ break;
-+ }
-+ if (m == 0)
-+ printk("klips_debug:rj_delete: "
-+ "couldn't find our annotation\n");
-+on1:
-+ /*
-+ * Eliminate us from tree
-+ */
-+ if (tt->rj_flags & RJF_ROOT)
-+ return -EFAULT; /* (0) rgb */
-+#ifdef RJ_DEBUG
-+ /* Get us out of the creation list */
-+ for (t = rj_clist; t && t->rj_ybro != tt; t = t->rj_ybro) {}
-+ if (t) t->rj_ybro = tt->rj_ybro;
-+#endif /* RJ_DEBUG */
-+ t = tt->rj_p;
-+ if (dupedkey) {
-+ if (tt == saved_tt) {
-+ x = dupedkey; x->rj_p = t;
-+ if (t->rj_l == tt) t->rj_l = x; else t->rj_r = x;
-+ } else {
-+ for (x = p = saved_tt; p && p->rj_dupedkey != tt;)
-+ p = p->rj_dupedkey;
-+ if (p) p->rj_dupedkey = tt->rj_dupedkey;
-+ else printk("klips_debug:rj_delete: "
-+ "couldn't find node that we started with\n");
-+ }
-+ t = tt + 1;
-+ if (t->rj_flags & RJF_ACTIVE) {
-+#ifndef RJ_DEBUG
-+ *++x = *t; p = t->rj_p;
-+#else
-+ b = t->rj_info; *++x = *t; t->rj_info = b; p = t->rj_p;
-+#endif /* RJ_DEBUG */
-+ if (p->rj_l == t) p->rj_l = x; else p->rj_r = x;
-+ x->rj_l->rj_p = x; x->rj_r->rj_p = x;
-+ }
-+ goto out;
-+ }
-+ if (t->rj_l == tt) x = t->rj_r; else x = t->rj_l;
-+ p = t->rj_p;
-+ if (p->rj_r == t) p->rj_r = x; else p->rj_l = x;
-+ x->rj_p = p;
-+ /*
-+ * Demote routes attached to us.
-+ */
-+ if (t->rj_mklist) {
-+ if (x->rj_b >= 0) {
-+ for (mp = &x->rj_mklist; (m = *mp);)
-+ mp = &m->rm_mklist;
-+ *mp = t->rj_mklist;
-+ } else {
-+ for (m = t->rj_mklist; m;) {
-+ struct radij_mask *mm = m->rm_mklist;
-+ if (m == x->rj_mklist && (--(m->rm_refs) < 0)) {
-+ x->rj_mklist = 0;
-+ MKFree(m);
-+ } else
-+ printk("klips_debug:rj_delete: "
-+ "Orphaned Mask 0p%p at 0p%p\n", m, x);
-+ m = mm;
-+ }
-+ }
-+ }
-+ /*
-+ * We may be holding an active internal node in the tree.
-+ */
-+ x = tt + 1;
-+ if (t != x) {
-+#ifndef RJ_DEBUG
-+ *t = *x;
-+#else
-+ b = t->rj_info; *t = *x; t->rj_info = b;
-+#endif /* RJ_DEBUG */
-+ t->rj_l->rj_p = t; t->rj_r->rj_p = t;
-+ p = x->rj_p;
-+ if (p->rj_l == x) p->rj_l = t; else p->rj_r = t;
-+ }
-+out:
-+ tt->rj_flags &= ~RJF_ACTIVE;
-+ tt[1].rj_flags &= ~RJF_ACTIVE;
-+ *node = tt;
-+ return 0; /* (tt) rgb */
-+}
-+
-+int
-+rj_walktree(h, f, w)
-+ struct radij_node_head *h;
-+ register int (*f)(struct radij_node *,void *);
-+ void *w;
-+{
-+ int error;
-+ struct radij_node *base, *next;
-+ register struct radij_node *rn;
-+
-+ if(!h || !f /* || !w */) {
-+ return -ENODATA;
-+ }
-+
-+ rn = h->rnh_treetop;
-+ /*
-+ * This gets complicated because we may delete the node
-+ * while applying the function f to it, so we need to calculate
-+ * the successor node in advance.
-+ */
-+ /* First time through node, go left */
-+ while (rn->rj_b >= 0)
-+ rn = rn->rj_l;
-+ for (;;) {
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(debug_radij) {
-+ printk("klips_debug:rj_walktree: "
-+ "for: rn=0p%p rj_b=%d rj_flags=%x",
-+ rn,
-+ rn->rj_b,
-+ rn->rj_flags);
-+ rn->rj_b >= 0 ?
-+ printk(" node off=%x\n",
-+ rn->rj_off) :
-+ printk(" leaf key = %08x->%08x\n",
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
-+ ;
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ base = rn;
-+ /* If at right child go back up, otherwise, go right */
-+ while (rn->rj_p->rj_r == rn && (rn->rj_flags & RJF_ROOT) == 0)
-+ rn = rn->rj_p;
-+ /* Find the next *leaf* since next node might vanish, too */
-+ for (rn = rn->rj_p->rj_r; rn->rj_b >= 0;)
-+ rn = rn->rj_l;
-+ next = rn;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(debug_radij) {
-+ printk("klips_debug:rj_walktree: "
-+ "processing leaves, rn=0p%p rj_b=%d rj_flags=%x",
-+ rn,
-+ rn->rj_b,
-+ rn->rj_flags);
-+ rn->rj_b >= 0 ?
-+ printk(" node off=%x\n",
-+ rn->rj_off) :
-+ printk(" leaf key = %08x->%08x\n",
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
-+ ;
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ /* Process leaves */
-+ while ((rn = base)) {
-+ base = rn->rj_dupedkey;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(debug_radij) {
-+ printk("klips_debug:rj_walktree: "
-+ "while: base=0p%p rn=0p%p rj_b=%d rj_flags=%x",
-+ base,
-+ rn,
-+ rn->rj_b,
-+ rn->rj_flags);
-+ rn->rj_b >= 0 ?
-+ printk(" node off=%x\n",
-+ rn->rj_off) :
-+ printk(" leaf key = %08x->%08x\n",
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
-+ ;
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ if (!(rn->rj_flags & RJF_ROOT) && (error = (*f)(rn, w)))
-+ return (-error);
-+ }
-+ rn = next;
-+ if (rn->rj_flags & RJF_ROOT)
-+ return (0);
-+ }
-+ /* NOTREACHED */
-+}
-+
-+int
-+rj_inithead(head, off)
-+ void **head;
-+ int off;
-+{
-+ register struct radij_node_head *rnh;
-+ register struct radij_node *t, *tt, *ttt;
-+ if (*head)
-+ return (1);
-+ R_Malloc(rnh, struct radij_node_head *, sizeof (*rnh));
-+ if (rnh == NULL)
-+ return (0);
-+ Bzero(rnh, sizeof (*rnh));
-+ *head = rnh;
-+ t = rj_newpair(rj_zeroes, off, rnh->rnh_nodes);
-+ ttt = rnh->rnh_nodes + 2;
-+ t->rj_r = ttt;
-+ t->rj_p = t;
-+ tt = t->rj_l;
-+ tt->rj_flags = t->rj_flags = RJF_ROOT | RJF_ACTIVE;
-+ tt->rj_b = -1 - off;
-+ *ttt = *tt;
-+ ttt->rj_key = rj_ones;
-+ rnh->rnh_addaddr = rj_addroute;
-+ rnh->rnh_deladdr = rj_delete;
-+ rnh->rnh_matchaddr = rj_match;
-+ rnh->rnh_walktree = rj_walktree;
-+ rnh->rnh_treetop = t;
-+ return (1);
-+}
-+
-+void
-+rj_init()
-+{
-+ char *cp, *cplim;
-+
-+ if (maj_keylen == 0) {
-+ printk("klips_debug:rj_init: "
-+ "radij functions require maj_keylen be set\n");
-+ return;
-+ }
-+ R_Malloc(rj_zeroes, char *, 3 * maj_keylen);
-+ if (rj_zeroes == NULL)
-+ panic("rj_init");
-+ Bzero(rj_zeroes, 3 * maj_keylen);
-+ rj_ones = cp = rj_zeroes + maj_keylen;
-+ maskedKey = cplim = rj_ones + maj_keylen;
-+ while (cp < cplim)
-+ *cp++ = -1;
-+ if (rj_inithead((void **)&mask_rjhead, 0) == 0)
-+ panic("rj_init 2");
-+}
-+
-+void
-+rj_preorder(struct radij_node *rn, int l)
-+{
-+ int i;
-+
-+ if (rn == NULL){
-+ printk("klips_debug:rj_preorder: "
-+ "NULL pointer\n");
-+ return;
-+ }
-+
-+ if (rn->rj_b >= 0){
-+ rj_preorder(rn->rj_l, l+1);
-+ rj_preorder(rn->rj_r, l+1);
-+ printk("klips_debug:");
-+ for (i=0; i<l; i++)
-+ printk("*");
-+ printk(" off = %d\n",
-+ rn->rj_off);
-+ } else {
-+ printk("klips_debug:");
-+ for (i=0; i<l; i++)
-+ printk("@");
-+ printk(" flags = %x",
-+ (u_int)rn->rj_flags);
-+ if (rn->rj_flags & RJF_ACTIVE) {
-+ printk(" @key=0p%p",
-+ rn->rj_key);
-+ printk(" key = %08x->%08x",
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr));
-+ printk(" @mask=0p%p",
-+ rn->rj_mask);
-+ if (rn->rj_mask)
-+ printk(" mask = %08x->%08x",
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_src.s_addr),
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_dst.s_addr));
-+ if (rn->rj_dupedkey)
-+ printk(" dupedkey = 0p%p",
-+ rn->rj_dupedkey);
-+ }
-+ printk("\n");
-+ }
-+}
-+
-+#ifdef RJ_DEBUG
-+DEBUG_NO_STATIC void traverse(struct radij_node *p)
-+{
-+ rj_preorder(p, 0);
-+}
-+#endif /* RJ_DEBUG */
-+
-+void
-+rj_dumptrees(void)
-+{
-+ rj_preorder(rnh->rnh_treetop, 0);
-+}
-+
-+void
-+rj_free_mkfreelist(void)
-+{
-+ struct radij_mask *mknp, *mknp2;
-+
-+ mknp = rj_mkfreelist;
-+ while(mknp)
-+ {
-+ mknp2 = mknp;
-+ mknp = mknp->rm_mklist;
-+ kfree(mknp2);
-+ }
-+}
-+
-+int
-+radijcleartree(void)
-+{
-+ return rj_walktree(rnh, ipsec_rj_walker_delete, NULL);
-+}
-+
-+int
-+radijcleanup(void)
-+{
-+ int error = 0;
-+
-+ error = radijcleartree();
-+
-+ rj_free_mkfreelist();
-+
-+/* rj_walktree(mask_rjhead, ipsec_rj_walker_delete, NULL); */
-+ if(mask_rjhead) {
-+ kfree(mask_rjhead);
-+ }
-+
-+ if(rj_zeroes) {
-+ kfree(rj_zeroes);
-+ }
-+
-+ if(rnh) {
-+ kfree(rnh);
-+ }
-+
-+ return error;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.46 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.45 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.44.30.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.44 2002/07/24 18:44:54 rgb
-+ * Type fiddling to tame ia64 compiler.
-+ *
-+ * Revision 1.43 2002/05/23 07:14:11 rgb
-+ * Cleaned up %p variants to 0p%p for test suite cleanup.
-+ *
-+ * Revision 1.42 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.41 2002/04/24 07:36:35 mcr
-+ * Moved from ./klips/net/ipsec/radij.c,v
-+ *
-+ * Revision 1.40 2002/01/29 17:17:58 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.39 2002/01/29 04:00:55 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.38 2002/01/29 02:13:19 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.37 2001/10/18 04:45:23 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/freeswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.36 2001/08/22 13:43:51 henry
-+ * eliminate the single use of min() to avoid problems with Linus changing it
-+ *
-+ * Revision 1.35 2001/06/15 04:57:29 rgb
-+ * Clarified error return codes.
-+ * Changed mask add already exists to EEXIST.
-+ * Changed mask delete did not exist to ENOENT.
-+ *
-+ * Revision 1.34 2001/05/03 19:44:26 rgb
-+ * Fix sign of error return codes for rj_addroute().
-+ *
-+ * Revision 1.33 2001/02/27 22:24:56 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.32 2001/02/27 06:23:15 rgb
-+ * Debug line splitting.
-+ *
-+ * Revision 1.31 2000/11/06 04:35:21 rgb
-+ * Clear table *before* releasing other items in radijcleanup.
-+ *
-+ * Revision 1.30 2000/09/20 04:07:40 rgb
-+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
-+ * oopsen.
-+ *
-+ * Revision 1.29 2000/09/12 03:25:02 rgb
-+ * Moved radij_c_version printing to ipsec_version_get_info().
-+ *
-+ * Revision 1.28 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.27 2000/07/28 14:58:32 rgb
-+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
-+ *
-+ * Revision 1.26 2000/05/10 23:11:37 rgb
-+ * Comment out most of the startup version information.
-+ *
-+ * Revision 1.25 2000/01/21 06:21:47 rgb
-+ * Change return codes to negative on error.
-+ *
-+ * Revision 1.24 1999/11/18 04:09:20 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ *
-+ * Revision 1.23 1999/11/17 15:53:41 rgb
-+ * Changed all occurrences of #include "../../../lib/freeswan.h"
-+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
-+ * klips/net/ipsec/Makefile.
-+ *
-+ * Revision 1.22 1999/10/15 22:17:28 rgb
-+ * Modify radijcleanup() to call radijcleartree().
-+ *
-+ * Revision 1.21 1999/10/08 18:37:34 rgb
-+ * Fix end-of-line spacing to sate whining PHMs.
-+ *
-+ * Revision 1.20 1999/10/01 15:44:54 rgb
-+ * Move spinlock header include to 2.1> scope.
-+ *
-+ * Revision 1.19 1999/10/01 08:35:52 rgb
-+ * Add spinlock include to shut up compiler for 2.0.38.
-+ *
-+ * Revision 1.18 1999/09/23 18:02:52 rgb
-+ * De-alarm the search failure message so it doesn't sound so grave.
-+ *
-+ * Revision 1.17 1999/05/25 21:26:01 rgb
-+ * Fix rj_walktree() sanity checking bug.
-+ *
-+ * Revision 1.16 1999/05/09 03:25:38 rgb
-+ * Fix bug introduced by 2.2 quick-and-dirty patch.
-+ *
-+ * Revision 1.15 1999/05/05 22:02:33 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.14 1999/04/29 15:24:15 rgb
-+ * Add sanity checking for null pointer arguments.
-+ * Standardise an error return method.
-+ *
-+ * Revision 1.13 1999/04/11 00:29:02 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.12 1999/04/06 04:54:28 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.11 1999/02/17 16:52:53 rgb
-+ * Convert DEBUG_IPSEC to KLIPS_PRINT
-+ * Clean out unused cruft.
-+ *
-+ * Revision 1.10 1999/01/22 06:30:05 rgb
-+ * Cruft clean-out.
-+ * 64-bit clean-up.
-+ *
-+ * Revision 1.9 1998/12/01 13:22:04 rgb
-+ * Added support for debug printing of version info.
-+ *
-+ * Revision 1.8 1998/11/30 13:22:55 rgb
-+ * Rationalised all the klips kernel file headers. They are much shorter
-+ * now and won't conflict under RH5.2.
-+ *
-+ * Revision 1.7 1998/10/25 02:43:26 rgb
-+ * Change return type on rj_addroute and rj_delete and add and argument
-+ * to the latter to be able to transmit more infomation about errors.
-+ *
-+ * Revision 1.6 1998/10/19 14:30:06 rgb
-+ * Added inclusion of freeswan.h.
-+ *
-+ * Revision 1.5 1998/10/09 04:33:27 rgb
-+ * Added 'klips_debug' prefix to all klips printk debug statements.
-+ * Fixed output formatting slightly.
-+ *
-+ * Revision 1.4 1998/07/28 00:06:59 rgb
-+ * Add debug detail to tree traversing.
-+ *
-+ * Revision 1.3 1998/07/14 18:07:58 rgb
-+ * Add a routine to clear the eroute tree.
-+ *
-+ * Revision 1.2 1998/06/25 20:03:22 rgb
-+ * Cleanup #endif comments. Debug output for rj_init.
-+ *
-+ * Revision 1.1 1998/06/18 21:30:22 henry
-+ * move sources from klips/src to klips/net/ipsec to keep stupid kernel
-+ * build scripts happier about symlinks
-+ *
-+ * Revision 1.8 1998/05/25 20:34:15 rgb
-+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
-+ *
-+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
-+ * add ipsec_rj_walker_delete.
-+ *
-+ * Recover memory for eroute table on unload of module.
-+ *
-+ * Revision 1.7 1998/05/21 12:58:58 rgb
-+ * Moved 'extern' definitions to ipsec_radij.h to support /proc 3k limit fix.
-+ *
-+ * Revision 1.6 1998/04/23 20:57:29 rgb
-+ * Cleaned up compiler warnings for unused debugging functions.
-+ *
-+ * Revision 1.5 1998/04/22 16:51:38 rgb
-+ * Tidy up radij debug code from recent rash of modifications to debug code.
-+ *
-+ * Revision 1.4 1998/04/21 21:28:56 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.3 1998/04/14 17:30:37 rgb
-+ * Fix up compiling errors for radij tree memory reclamation.
-+ *
-+ * Revision 1.2 1998/04/12 22:03:25 rgb
-+ * Updated ESP-3DES-HMAC-MD5-96,
-+ * ESP-DES-HMAC-MD5-96,
-+ * AH-HMAC-MD5-96,
-+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
-+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
-+ *
-+ * Fixed eroute references in /proc/net/ipsec*.
-+ *
-+ * Started to patch module unloading memory leaks in ipsec_netlink and
-+ * radij tree unloading.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:15 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * No changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:39:04 ji
-+ * Minor cleanups.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/sysctl_net_ipsec.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,196 @@
-+/*
-+ * sysctl interface to net IPSEC subsystem.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+/* -*- linux-c -*-
-+ *
-+ * Initiated April 3, 1998, Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
-+ */
-+
-+#include <linux/mm.h>
-+#include <linux/sysctl.h>
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef CONFIG_SYSCTL
-+
-+#define NET_IPSEC 2112 /* Random number */
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int debug_ah;
-+extern int debug_esp;
-+extern int debug_tunnel;
-+extern int debug_eroute;
-+extern int debug_spi;
-+extern int debug_radij;
-+extern int debug_netlink;
-+extern int debug_xform;
-+extern int debug_rcv;
-+extern int debug_pfkey;
-+extern int sysctl_ipsec_debug_verbose;
-+#ifdef CONFIG_IPSEC_IPCOMP
-+extern int sysctl_ipsec_debug_ipcomp;
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+extern int sysctl_ipsec_icmp;
-+extern int sysctl_ipsec_inbound_policy_check;
-+extern int sysctl_ipsec_tos;
-+int sysctl_ipsec_regress_pfkey_lossage;
-+
-+enum {
-+#ifdef CONFIG_IPSEC_DEBUG
-+ NET_IPSEC_DEBUG_AH=1,
-+ NET_IPSEC_DEBUG_ESP=2,
-+ NET_IPSEC_DEBUG_TUNNEL=3,
-+ NET_IPSEC_DEBUG_EROUTE=4,
-+ NET_IPSEC_DEBUG_SPI=5,
-+ NET_IPSEC_DEBUG_RADIJ=6,
-+ NET_IPSEC_DEBUG_NETLINK=7,
-+ NET_IPSEC_DEBUG_XFORM=8,
-+ NET_IPSEC_DEBUG_RCV=9,
-+ NET_IPSEC_DEBUG_PFKEY=10,
-+ NET_IPSEC_DEBUG_VERBOSE=11,
-+ NET_IPSEC_DEBUG_IPCOMP=12,
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ NET_IPSEC_ICMP=13,
-+ NET_IPSEC_INBOUND_POLICY_CHECK=14,
-+ NET_IPSEC_TOS=15,
-+ NET_IPSEC_REGRESS_PFKEY_LOSSAGE=16,
-+};
-+
-+static ctl_table ipsec_table[] = {
-+#ifdef CONFIG_IPSEC_DEBUG
-+ { NET_IPSEC_DEBUG_AH, "debug_ah", &debug_ah,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_ESP, "debug_esp", &debug_esp,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_TUNNEL, "debug_tunnel", &debug_tunnel,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_EROUTE, "debug_eroute", &debug_eroute,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_SPI, "debug_spi", &debug_spi,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_RADIJ, "debug_radij", &debug_radij,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_NETLINK, "debug_netlink", &debug_netlink,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_XFORM, "debug_xform", &debug_xform,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_RCV, "debug_rcv", &debug_rcv,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_PFKEY, "debug_pfkey", &debug_pfkey,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_VERBOSE, "debug_verbose",&sysctl_ipsec_debug_verbose,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ { NET_IPSEC_DEBUG_IPCOMP, "debug_ipcomp", &sysctl_ipsec_debug_ipcomp,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#ifdef CONFIG_IPSEC_REGRESS
-+ { NET_IPSEC_REGRESS_PFKEY_LOSSAGE, "pfkey_lossage",
-+ &sysctl_ipsec_regress_pfkey_lossage,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+#endif /* CONFIG_IPSEC_REGRESS */
-+
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ { NET_IPSEC_ICMP, "icmp", &sysctl_ipsec_icmp,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_INBOUND_POLICY_CHECK, "inbound_policy_check", &sysctl_ipsec_inbound_policy_check,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_TOS, "tos", &sysctl_ipsec_tos,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ {0}
-+};
-+
-+static ctl_table ipsec_net_table[] = {
-+ { NET_IPSEC, "ipsec", NULL, 0, 0555, ipsec_table },
-+ { 0 }
-+};
-+
-+static ctl_table ipsec_root_table[] = {
-+ { CTL_NET, "net", NULL, 0, 0555, ipsec_net_table },
-+ { 0 }
-+};
-+
-+static struct ctl_table_header *ipsec_table_header;
-+
-+int ipsec_sysctl_register(void)
-+{
-+ ipsec_table_header = register_sysctl_table(ipsec_root_table, 0);
-+ if (!ipsec_table_header) {
-+ return -ENOMEM;
-+ }
-+ return 0;
-+}
-+
-+void ipsec_sysctl_unregister(void)
-+{
-+ unregister_sysctl_table(ipsec_table_header);
-+}
-+
-+#endif /* CONFIG_SYSCTL */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.16 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.15 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.14 2002/04/24 07:36:35 mcr
-+ * Moved from ./klips/net/ipsec/sysctl_net_ipsec.c,v
-+ *
-+ * Revision 1.13 2002/01/12 02:58:32 mcr
-+ * first regression test causes acquire messages to be lost
-+ * 100% of the time. This is to help testing of pluto.
-+ *
-+ * Revision 1.12 2001/06/14 19:35:13 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.11 2001/02/26 19:58:13 rgb
-+ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
-+ *
-+ * Revision 1.10 2000/09/16 01:50:15 rgb
-+ * Protect sysctl_ipsec_debug_ipcomp with compiler defines too so that the
-+ * linker won't blame rj_delete() for missing symbols. ;-> Damn statics...
-+ *
-+ * Revision 1.9 2000/09/15 23:17:51 rgb
-+ * Moved stuff around to compile with debug off.
-+ *
-+ * Revision 1.8 2000/09/15 11:37:02 rgb
-+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
-+ * IPCOMP zlib deflate code.
-+ *
-+ * Revision 1.7 2000/09/15 07:37:15 rgb
-+ * Munged silly log comment that was causing a warning.
-+ *
-+ * Revision 1.6 2000/09/15 04:58:23 rgb
-+ * Added tos runtime switch.
-+ * Removed 'sysctl_ipsec_' prefix from /proc/sys/net/ipsec/ filenames.
-+ *
-+ * Revision 1.5 2000/09/12 03:25:28 rgb
-+ * Filled in and implemented sysctl.
-+ *
-+ * Revision 1.4 1999/04/11 00:29:03 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.3 1999/04/06 04:54:29 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/version.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,44 @@
-+/*
-+ * return IPsec version information
-+ * Copyright (C) 2001 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifdef __KERNEL__
-+#include <linux/netdevice.h>
-+#endif
-+
-+#include "openswan.h"
-+
-+#define V "cvs2002Mar12_01:19:03" /* substituted in by Makefile */
-+static const char openswan_number[] = V;
-+static const char openswan_string[] = "Openswan " V;
-+
-+/*
-+ - ipsec_version_code - return IPsec version number/code, as string
-+ */
-+const char *
-+ipsec_version_code()
-+{
-+ return openswan_number;
-+}
-+
-+/*
-+ - ipsec_version_string - return full version string
-+ */
-+const char *
-+ipsec_version_string()
-+{
-+ return openswan_string;
-+}
-RCSID $Id$
---- ./net/ipv4/af_inet.c.preipsec Wed Apr 26 15:13:17 2000
-+++ ./net/ipv4/af_inet.c Fri Jun 30 15:01:27 2000
-@@ -1019,6 +1019,17 @@
- ip_mr_init();
- #endif
-
-+#if defined(CONFIG_IPSEC)
-+ {
-+ extern /* void */ int ipsec_init(void);
-+ /*
-+ * Initialise AF_INET ESP and AH protocol support including
-+ * e-routing and SA tables
-+ */
-+ ipsec_init();
-+ }
-+#endif /* CONFIG_IPSEC */
-+
- /*
- * Create all the /proc entries.
- */
---- /dev/null Fri May 10 13:59:54 2002
-+++ linux/net/ipsec/Makefile.ver Sun Jul 28 22:10:40 2002
-@@ -0,0 +1 @@
-+IPSECVERSION=cvs2002Mar12_01:19:03
-make[1]: Leaving directory `/data/mtx/oe/tmp/work/openswan-2.2.0-r0/openswan-2.2.0'
diff --git a/linux/linux-mtx-1-2.4.24/14-au1000-eth-vlan.diff b/linux/linux-mtx-1-2.4.24/14-au1000-eth-vlan.diff
deleted file mode 100644
index a4fa3169cc..0000000000
--- a/linux/linux-mtx-1-2.4.24/14-au1000-eth-vlan.diff
+++ /dev/null
@@ -1,10 +0,0 @@
---- linux/drivers/net/au1000_eth.c.orig 2004-11-18 13:44:52.163605416 +0100
-+++ linux/drivers/net/au1000_eth.c 2004-11-18 13:51:42.096286176 +0100
-@@ -1384,6 +1384,7 @@
- control |= MAC_FULL_DUPLEX;
- }
- aup->mac->control = control;
-+ aup->mac->vlan1_tag = 0x8100; /* activate vlan support */
- au_sync();
-
- spin_unlock_irqrestore(&aup->lock, flags);
diff --git a/linux/linux-mtx-1-2.4.24/15-mtd-proc-partition-rw.diff b/linux/linux-mtx-1-2.4.24/15-mtd-proc-partition-rw.diff
deleted file mode 100644
index 54ba5fff98..0000000000
--- a/linux/linux-mtx-1-2.4.24/15-mtd-proc-partition-rw.diff
+++ /dev/null
@@ -1,173 +0,0 @@
-diff -Nurb linux/drivers/mtd/mtdcore.c linux-mtd-rw/drivers/mtd/mtdcore.c
---- linux/drivers/mtd/mtdcore.c 2004-11-18 13:16:00.000000000 +0100
-+++ linux-mtd-rw/drivers/mtd/mtdcore.c 2004-11-18 15:27:13.130036616 +0100
-@@ -25,6 +25,10 @@
-
- #include <linux/mtd/mtd.h>
-
-+/* this symbol is exported by the procfs. */
-+extern struct proc_dir_entry *proc_sys_root;
-+
-+
- /* These are exported solely for the purpose of mtd_blkdevs.c. You
- should not use them for _anything_ else */
- DECLARE_MUTEX(mtd_table_mutex);
-@@ -336,8 +340,83 @@
-
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
- static struct proc_dir_entry *proc_mtd;
-+
-+static struct proc_dir_entry *proc_sys_mtd;
-+static struct proc_dir_entry *proc_sys_mtd_partition[MAX_MTD_DEVICES];
-+static struct proc_dir_entry *proc_sys_mtd_partition_rw[MAX_MTD_DEVICES];
- #endif
-
-+/*===================================0
-+ * mtdproc_read_partition_access
-+ */
-+static int mtdproc_read_partition_access ( char *page, char **start, off_t off,int count,
-+ int *eof, void *data
-+ )
-+{
-+ int partid = (unsigned int)data;
-+ int len = 0;
-+
-+ // NO RETURN FROM HERE UNTIL "up(&mtd_table_mutex)".
-+ down(&mtd_table_mutex);
-+
-+ if (partid < MAX_MTD_DEVICES)
-+ {
-+ struct mtd_info *this = mtd_table[partid];
-+ if (this)
-+ {
-+ page[len] = (this->flags & MTD_WRITEABLE) ? '1' : '0';
-+ len++;
-+ }
-+ }
-+
-+ up(&mtd_table_mutex);
-+
-+ if (off >= len)
-+ return 0;
-+ *start = page + off;
-+ return ((count < len-off) ? count : len-off);
-+}
-+
-+
-+static int mtdproc_write_partition_access (struct file *file, const char *buffer,
-+ unsigned long count, void *data)
-+{
-+ int partid = (unsigned int)data;
-+ int len = 0;
-+
-+ // NO RETURN FROM HERE UNTIL "up(&mtd_table_mutex)".
-+ down(&mtd_table_mutex);
-+
-+ if (partid < MAX_MTD_DEVICES)
-+ {
-+ struct mtd_info *this = mtd_table[partid];
-+ if (this && count > 0)
-+ {
-+ switch (*buffer)
-+ {
-+ case '0':
-+ this->flags &= ~(this->master_flags & MTD_WRITEABLE);
-+ break;
-+
-+ case '1':
-+ this->flags |= ~(this->master_flags & MTD_WRITEABLE);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+ }
-+ }
-+
-+ up(&mtd_table_mutex);
-+
-+ return count;
-+}
-+
-+
-+
-+
-+
- static inline int mtd_proc_info (char *buf, int i)
- {
- struct mtd_info *this = mtd_table[i];
-@@ -349,6 +428,7 @@
- this->erasesize, this->name);
- }
-
-+
- static int mtd_read_proc ( char *page, char **start, off_t off,int count
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
- ,int *eof, void *data_unused
-@@ -404,12 +484,31 @@
- /*====================================================================*/
- /* Init code */
-
-+
- int __init init_mtd(void)
- {
- #ifdef CONFIG_PROC_FS
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-+ int i;
-+
- if ((proc_mtd = create_proc_entry( "mtd", 0, 0 )))
- proc_mtd->read_proc = mtd_read_proc;
-+
-+ proc_sys_mtd = proc_mkdir("mtd", proc_sys_root);
-+ for (i=0; i<MAX_MTD_DEVICES; i++)
-+ {
-+ char partname[10];
-+ sprintf (partname, "%d", i);
-+
-+ proc_sys_mtd_partition[i] = proc_mkdir(partname, proc_sys_mtd);
-+ proc_sys_mtd_partition_rw[i] = create_proc_entry ("rw", S_IFREG | S_IRUGO, proc_sys_mtd_partition[i]);
-+ if (proc_sys_mtd_partition_rw[i])
-+ {
-+ proc_sys_mtd_partition_rw[i]->read_proc = mtdproc_read_partition_access;
-+ proc_sys_mtd_partition_rw[i]->write_proc = mtdproc_write_partition_access;
-+ proc_sys_mtd_partition_rw[i]->data = (void *)i;
-+ }
-+ }
- #else
- proc_register_dynamic(&proc_root,&mtd_proc_entry);
- #endif
-@@ -425,6 +524,8 @@
- return 0;
- }
-
-+
-+
- static void __exit cleanup_mtd(void)
- {
- #ifdef CONFIG_PM
-diff -Nurb linux/drivers/mtd/mtdpart.c linux-mtd-rw/drivers/mtd/mtdpart.c
---- linux/drivers/mtd/mtdpart.c 2004-11-18 13:16:00.000000000 +0100
-+++ linux-mtd-rw/drivers/mtd/mtdpart.c 2004-11-18 15:27:13.131036464 +0100
-@@ -341,6 +341,9 @@
- /* set up the MTD object for this partition */
- slave->mtd.type = master->type;
- slave->mtd.flags = master->flags & ~parts[i].mask_flags;
-+ slave->mtd.master_flags = master->flags;
-+ slave->mtd.mask_flags = parts[i].mask_flags;
-+
- slave->mtd.size = parts[i].size;
- slave->mtd.oobblock = master->oobblock;
- slave->mtd.oobsize = master->oobsize;
-diff -Nurb linux/include/linux/mtd/mtd.h linux-mtd-rw/include/linux/mtd/mtd.h
---- linux/include/linux/mtd/mtd.h 2004-11-18 13:16:31.000000000 +0100
-+++ linux-mtd-rw/include/linux/mtd/mtd.h 2004-11-18 15:27:13.000000000 +0100
-@@ -232,6 +232,9 @@
-
- struct module *owner;
- int usecount;
-+
-+ u_int32_t master_flags;
-+ u_int32_t mask_flags;
- };
-
-
diff --git a/linux/linux-mtx-1-2.4.24/defconfig-mtx-1 b/linux/linux-mtx-1-2.4.24/defconfig-mtx-1
deleted file mode 100644
index 711356c1a9..0000000000
--- a/linux/linux-mtx-1-2.4.24/defconfig-mtx-1
+++ /dev/null
@@ -1,1176 +0,0 @@
-#
-# Automatically generated by make menuconfig: don't edit
-#
-CONFIG_MIPS=y
-CONFIG_MIPS32=y
-# CONFIG_MIPS64 is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# Machine selection
-#
-# CONFIG_ACER_PICA_61 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_HYDROGEN3 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_XXS1500 is not set
-CONFIG_MIPS_MTX1=y
-# CONFIG_COGENT_CSB250 is not set
-# CONFIG_BAGET_MIPS is not set
-# CONFIG_CASIO_E55 is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_EV96100 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_HP_LASERJET is not set
-# CONFIG_IBM_WORKPAD is not set
-# CONFIG_LASAT is not set
-# CONFIG_MIPS_ITE8172 is not set
-# CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MAGNUM_4000 is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_SEAD is not set
-# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_YOSEMITE is not set
-# CONFIG_DDB5074 is not set
-# CONFIG_DDB5476 is not set
-# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
-# CONFIG_NEC_EAGLE is not set
-# CONFIG_OLIVETTI_M700 is not set
-# CONFIG_NINO is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
-# CONFIG_SNI_RM200_PCI is not set
-# CONFIG_TANBAC_TB0226 is not set
-# CONFIG_TANBAC_TB0229 is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_VICTOR_MPC30X is not set
-# CONFIG_ZAO_CAPCELLA is not set
-# CONFIG_HIGHMEM is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_SOC_AU1X00=y
-CONFIG_SOC_AU1500=y
-CONFIG_NEW_TIME_C=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
-CONFIG_NONCOHERENT_IO=y
-# CONFIG_MIPS_AU1000 is not set
-
-#
-# CPU selection
-#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 is not set
-# CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_VR41XX is not set
-# CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_TX49XX is not set
-# CONFIG_CPU_R5000 is not set
-# CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_R6000 is not set
-# CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_R10000 is not set
-# CONFIG_CPU_RM7000 is not set
-# CONFIG_CPU_RM9000 is not set
-# CONFIG_CPU_SB1 is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_CPU_HAS_PREFETCH=y
-# CONFIG_VTAG_ICACHE is not set
-CONFIG_64BIT_PHYS_ADDR=y
-# CONFIG_CPU_ADVANCED is not set
-CONFIG_CPU_HAS_LLSC=y
-# CONFIG_CPU_HAS_LLDSCD is not set
-# CONFIG_CPU_HAS_WB is not set
-CONFIG_CPU_HAS_SYNC=y
-
-#
-# General setup
-#
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_NET=y
-CONFIG_PCI_NAMES=y
-# CONFIG_ISA is not set
-# CONFIG_TC is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-# CONFIG_PCMCIA is not set
-
-#
-# PCI Hotplug Support
-#
-# CONFIG_HOTPLUG_PCI is not set
-# CONFIG_HOTPLUG_PCI_COMPAQ is not set
-# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_MIPS32_COMPAT is not set
-# CONFIG_MIPS32_O32 is not set
-# CONFIG_MIPS32_N32 is not set
-# CONFIG_BINFMT_ELF32 is not set
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_OOM_KILLER is not set
-# CONFIG_PM is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_AMDSTD_RETRY=y
-CONFIG_MTD_CFI_AMDSTD_RETRY_MAX=5
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_DB1X00 is not set
-CONFIG_MTD_MTX1=y
-# CONFIG_MTD_CSTM_MIPS_IXX is not set
-# CONFIG_MTD_OCELOT is not set
-# CONFIG_MTD_LASAT is not set
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PCMCIA is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
-# CONFIG_CISS_MONITOR_THREAD is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=m
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_BLK_STATS is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=m
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_FWMARK=y
-CONFIG_IP_ROUTE_NAT=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_TOS=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-CONFIG_SYN_COOKIES=y
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_UNCLEAN=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_MIRROR=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_NAT_AMANDA=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-CONFIG_IPV6=m
-
-#
-# IPv6: Netfilter Configuration
-#
-CONFIG_IP6_NF_QUEUE=m
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_MATCH_OPTS=m
-CONFIG_IP6_NF_MATCH_FRAG=m
-CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
-CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_AHESP=m
-CONFIG_IP6_NF_MATCH_LENGTH=m
-CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
-# CONFIG_KHTTPD is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-CONFIG_IPV6_SCTP__=m
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-CONFIG_VLAN_8021Q=m
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_DEV_APPLETALK is not set
-# CONFIG_DECNET is not set
-CONFIG_BRIDGE=m
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_CSZ=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_QOS=y
-CONFIG_NET_ESTIMATOR=y
-CONFIG_NET_CLS=y
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_ROUTE=y
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-CONFIG_NET_CLS_POLICE=y
-
-#
-# Network testing
-#
-CONFIG_NET_PKTGEN=m
-CONFIG_IPSEC_NAT_TRAVERSAL=y
-CONFIG_IPSEC=m
-CONFIG_IPSEC_IPIP=y
-CONFIG_IPSEC_AH=y
-CONFIG_IPSEC_AUTH_HMAC_MD5=y
-CONFIG_IPSEC_AUTH_HMAC_SHA1=y
-CONFIG_IPSEC_ESP=y
-CONFIG_IPSEC_ENC_3DES=y
-CONFIG_IPSEC_ENC_AES=y
-CONFIG_IPSEC_ALG=y
-CONFIG_IPSEC_ALG_AES=m
-CONFIG_IPSEC_ALG_CRYPTOAPI=m
-CONFIG_IPSEC_ALG_NON_LIBRE=y
-CONFIG_IPSEC_IPCOMP=y
-CONFIG_IPSEC_DEBUG=y
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-# CONFIG_PHONE_IXJ is not set
-# CONFIG_PHONE_IXJ_PCMCIA is not set
-
-#
-# ATA/IDE/MFM/RLL support
-#
-# CONFIG_IDE is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
-CONFIG_SD_EXTRA_DEVS=40
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_SR_EXTRA_DEVS=2
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_SCSI_DEBUG_QUEUES is not set
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_MEGARAID2 is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_NCR53C8XX is not set
-# CONFIG_SCSI_SYM53C8XX is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_SIM710 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-# CONFIG_FUSION_BOOT is not set
-# CONFIG_FUSION_ISENSE is not set
-# CONFIG_FUSION_CTL is not set
-# CONFIG_FUSION_LAN is not set
-
-#
-# IEEE 1394 (FireWire) support (EXPERIMENTAL)
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_PCI is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-CONFIG_DUMMY=m
-CONFIG_BONDING=m
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MIPS_AU1X00_ENET=y
-# CONFIG_BCM5222_DUAL_PHY is not set
-# CONFIG_SUNLANCE is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNBMAC is not set
-# CONFIG_SUNQE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPPOE=m
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_STRIP is not set
-# CONFIG_WAVELAN is not set
-# CONFIG_ARLAN is not set
-CONFIG_AIRONET4500=m
-CONFIG_AIRONET4500_NONCS=m
-# CONFIG_AIRONET4500_PNP is not set
-CONFIG_AIRONET4500_PCI=y
-# CONFIG_AIRONET4500_ISA is not set
-# CONFIG_AIRONET4500_I365 is not set
-CONFIG_AIRONET4500_PROC=m
-CONFIG_AIRO=m
-# CONFIG_HERMES is not set
-# CONFIG_PLX_HERMES is not set
-# CONFIG_TMD_HERMES is not set
-# CONFIG_PCI_HERMES is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-CONFIG_SHAPER=m
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_UINPUT is not set
-
-#
-# Character devices
-#
-# CONFIG_VT is not set
-# CONFIG_SERIAL is not set
-# CONFIG_SERIAL_EXTENDED is not set
-CONFIG_SERIAL_NONSTANDARD=y
-# CONFIG_COMPUTONE is not set
-# CONFIG_ROCKETPORT is not set
-# CONFIG_CYCLADES is not set
-# CONFIG_DIGIEPCA is not set
-# CONFIG_DIGI is not set
-# CONFIG_ESPSERIAL is not set
-# CONFIG_MOXA_INTELLIO is not set
-# CONFIG_MOXA_SMARTIO is not set
-# CONFIG_ISI is not set
-# CONFIG_SYNCLINK is not set
-# CONFIG_SYNCLINKMP is not set
-# CONFIG_N_HDLC is not set
-# CONFIG_RISCOM8 is not set
-# CONFIG_SPECIALIX is not set
-# CONFIG_SX is not set
-# CONFIG_RIO is not set
-# CONFIG_STALDRV is not set
-# CONFIG_SERIAL_TX3912 is not set
-# CONFIG_SERIAL_TX3912_CONSOLE is not set
-# CONFIG_SERIAL_TXX9 is not set
-# CONFIG_SERIAL_TXX9_CONSOLE is not set
-CONFIG_AU1X00_UART=y
-CONFIG_AU1X00_SERIAL_CONSOLE=y
-# CONFIG_AU1X00_USB_TTY is not set
-# CONFIG_AU1X00_USB_RAW is not set
-# CONFIG_TXX927_SERIAL is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_IPMI_PANIC_EVENT is not set
-# CONFIG_IPMI_DEVICE_INTERFACE is not set
-# CONFIG_IPMI_KCS is not set
-# CONFIG_IPMI_WATCHDOG is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_SCx200_GPIO is not set
-# CONFIG_AMD_PM768 is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_MIPS_RTC=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-
-#
-# Direct Rendering Manager (XFree86 DRI support)
-#
-# CONFIG_DRM is not set
-CONFIG_AU1X00_GPIO=m
-# CONFIG_TS_AU1X00_ADS7846 is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_QFMT_V2 is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BEFS_DEBUG is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=m
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=m
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_CRAMFS is not set
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-# CONFIG_JFS_FS is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-CONFIG_NTFS_FS=m
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=m
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_TRACE is not set
-# CONFIG_XFS_DEBUG is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_TCP is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-CONFIG_ZISOFS_FS=m
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-15"
-CONFIG_NLS_CODEPAGE_437=m
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-CONFIG_NLS_CODEPAGE_850=m
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ISO8859_1=m
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-CONFIG_NLS_ISO8859_15=m
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-CONFIG_NLS_UTF8=m
-
-#
-# Multimedia devices
-#
-CONFIG_VIDEO_DEV=m
-
-#
-# Video For Linux
-#
-CONFIG_VIDEO_PROC_FS=y
-# CONFIG_I2C_PARPORT is not set
-# CONFIG_VIDEO_BT848 is not set
-# CONFIG_VIDEO_PMS is not set
-CONFIG_VIDEO_CPIA=m
-# CONFIG_VIDEO_CPIA_PP is not set
-CONFIG_VIDEO_CPIA_USB=m
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIDEO_ZORAN_BUZ is not set
-# CONFIG_VIDEO_ZORAN_DC10 is not set
-# CONFIG_VIDEO_ZORAN_LML33 is not set
-# CONFIG_VIDEO_ZR36120 is not set
-# CONFIG_VIDEO_MEYE is not set
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_GEMTEK_PCI is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_MAESTRO is not set
-# CONFIG_RADIO_MIROPCM20 is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=m
-# CONFIG_SOUND_ALI5455 is not set
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_FORTE is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_AU1X00 is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-CONFIG_SOUND_OSS=m
-# CONFIG_SOUND_TRACEINIT is not set
-# CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_AD1889 is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_ADLIB is not set
-# CONFIG_SOUND_ACI_MIXER is not set
-# CONFIG_SOUND_CS4232 is not set
-# CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_VMIDI is not set
-# CONFIG_SOUND_TRIX is not set
-# CONFIG_SOUND_MSS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_NM256 is not set
-# CONFIG_SOUND_MAD16 is not set
-# CONFIG_SOUND_PAS is not set
-# CONFIG_PAS_JOYSTICK is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_SB is not set
-# CONFIG_SOUND_AWE32_SYNTH is not set
-# CONFIG_SOUND_KAHLUA is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_OPL3SA2 is not set
-# CONFIG_SOUND_YMFPCI is not set
-# CONFIG_SOUND_YMFPCI_LEGACY is not set
-# CONFIG_SOUND_UART6850 is not set
-# CONFIG_SOUND_AEDSP16 is not set
-# CONFIG_SOUND_TVMIXER is not set
-# CONFIG_SOUND_AD1980 is not set
-# CONFIG_SOUND_WM97XX is not set
-
-#
-# USB support
-#
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-CONFIG_USB_OHCI=y
-CONFIG_USB_NON_PCI_OHCI=y
-CONFIG_USB_AUDIO=m
-CONFIG_USB_EMI26=m
-CONFIG_USB_MIDI=m
-CONFIG_USB_STORAGE=m
-CONFIG_USB_STORAGE_DEBUG=y
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-# CONFIG_USB_STORAGE_ISD200 is not set
-CONFIG_USB_STORAGE_DPCM=y
-CONFIG_USB_STORAGE_HP8200e=y
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
-# CONFIG_USB_HID is not set
-# CONFIG_USB_HIDINPUT is not set
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-CONFIG_USB_DC2XX=m
-CONFIG_USB_MDC800=m
-CONFIG_USB_SCANNER=m
-CONFIG_USB_MICROTEK=m
-CONFIG_USB_HPUSBSCSI=m
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_KONICAWC=m
-CONFIG_USB_OV511=m
-CONFIG_USB_PWC=m
-CONFIG_USB_SE401=m
-CONFIG_USB_STV680=m
-# CONFIG_USB_W9968CF is not set
-CONFIG_USB_VICAM=m
-CONFIG_USB_DSBR=m
-CONFIG_USB_DABUSB=m
-CONFIG_USB_PEGASUS=m
-CONFIG_USB_RTL8150=m
-CONFIG_USB_KAWETH=m
-CONFIG_USB_CATC=m
-CONFIG_USB_AX8817X=m
-CONFIG_USB_CDCETHER=m
-CONFIG_USB_USBNET=m
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-CONFIG_USB_SERIAL=m
-# CONFIG_USB_SERIAL_DEBUG is not set
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_BELKIN=m
-CONFIG_USB_SERIAL_WHITEHEAT=m
-CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
-CONFIG_USB_SERIAL_EMPEG=m
-CONFIG_USB_SERIAL_FTDI_SIO=m
-CONFIG_USB_SERIAL_VISOR=m
-CONFIG_USB_SERIAL_IPAQ=m
-CONFIG_USB_SERIAL_IR=m
-CONFIG_USB_SERIAL_EDGEPORT=m
-CONFIG_USB_SERIAL_EDGEPORT_TI=m
-CONFIG_USB_SERIAL_KEYSPAN_PDA=m
-CONFIG_USB_SERIAL_KEYSPAN=m
-CONFIG_USB_SERIAL_KEYSPAN_USA28=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19=y
-CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
-CONFIG_USB_SERIAL_KEYSPAN_MPR=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
-CONFIG_USB_SERIAL_MCT_U232=m
-CONFIG_USB_SERIAL_KLSI=m
-CONFIG_USB_SERIAL_KOBIL_SCT=m
-CONFIG_USB_SERIAL_PL2303=m
-CONFIG_USB_SERIAL_CYBERJACK=m
-CONFIG_USB_SERIAL_XIRCOM=m
-CONFIG_USB_SERIAL_OMNINET=m
-CONFIG_USB_RIO500=m
-CONFIG_USB_AUERSWALD=m
-CONFIG_USB_TIGL=m
-CONFIG_USB_BRLVGER=m
-CONFIG_USB_LCD=m
-
-#
-# Support for USB gadgets
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# Bluetooth support
-#
-CONFIG_BLUEZ=m
-CONFIG_BLUEZ_L2CAP=m
-CONFIG_BLUEZ_SCO=m
-CONFIG_BLUEZ_RFCOMM=m
-CONFIG_BLUEZ_RFCOMM_TTY=y
-CONFIG_BLUEZ_BNEP=m
-CONFIG_BLUEZ_BNEP_MC_FILTER=y
-CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
-
-#
-# Bluetooth device drivers
-#
-CONFIG_BLUEZ_HCIUSB=m
-CONFIG_BLUEZ_HCIUSB_SCO=y
-CONFIG_BLUEZ_HCIUART=m
-CONFIG_BLUEZ_HCIUART_H4=y
-CONFIG_BLUEZ_HCIUART_BCSP=y
-CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y
-CONFIG_BLUEZ_HCIBFUSB=m
-# CONFIG_BLUEZ_HCIDTL1 is not set
-# CONFIG_BLUEZ_HCIBT3C is not set
-# CONFIG_BLUEZ_HCIBLUECARD is not set
-# CONFIG_BLUEZ_HCIBTUART is not set
-CONFIG_BLUEZ_HCIVHCI=m
-
-#
-# Kernel hacking
-#
-CONFIG_CROSSCOMPILE=y
-# CONFIG_RUNTIME_DEBUG is not set
-# CONFIG_KGDB is not set
-# CONFIG_GDB_CONSOLE is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_MIPS_UNCACHED is not set
-CONFIG_LOG_BUF_SHIFT=0
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_TEST=m
-
-#
-# Library routines
-#
-CONFIG_CRC32=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_FW_LOADER=m
diff --git a/linux/linux-mtx-1-2.4.27/01-mtd-2004-01-27.diff b/linux/linux-mtx-1-2.4.27/01-mtd-2004-01-27.diff
deleted file mode 100644
index 74e6375385..0000000000
--- a/linux/linux-mtx-1-2.4.27/01-mtd-2004-01-27.diff
+++ /dev/null
@@ -1,51503 +0,0 @@
-diff -Nurb linux-mips-2.4.27/drivers/mtd/Config.in linux/drivers/mtd/Config.in
---- linux-mips-2.4.27/drivers/mtd/Config.in 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/Config.in 2004-11-19 10:25:11.607244176 +0100
-@@ -1,5 +1,5 @@
-
--# $Id$
-+# $Id$
-
- mainmenu_option next_comment
- comment 'Memory Technology Devices (MTD)'
-@@ -30,6 +30,7 @@
- if [ "$CONFIG_NFTL" = "y" -o "$CONFIG_NFTL" = "m" ]; then
- bool ' Write support for NFTL (BETA)' CONFIG_NFTL_RW
- fi
-+ dep_tristate ' INFTL (Inverse NAND Flash Translation Layer) support' CONFIG_INFTL $CONFIG_MTD
-
- source drivers/mtd/chips/Config.in
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/Makefile linux/drivers/mtd/Makefile
---- linux-mips-2.4.27/drivers/mtd/Makefile 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/Makefile 2004-11-19 10:25:11.608244024 +0100
-@@ -1,30 +1,7 @@
- #
- # Makefile for the memory technology device drivers.
- #
--# Note! Dependencies are done automagically by 'make dep', which also
--# removes any old dependencies. DON'T put your own dependencies here
--# unless it's something special (ie not a .c file).
--#
--# Note 2! The CFLAGS definitions are now inherited from the
--# parent makes..
--#
--# $Id$
--
--
--obj-y += chips/chipslink.o maps/mapslink.o \
-- devices/devlink.o nand/nandlink.o
--obj-m :=
--obj-n :=
--obj- :=
--
--O_TARGET := mtdlink.o
--
--export-objs := mtdcore.o mtdpart.o redboot.o cmdlinepart.o afs.o mtdconcat.o
--list-multi := nftl.o
--
--mod-subdirs :=
--subdir-y := chips maps devices nand
--subdir-m := $(subdir-y)
-+# $Id$
-
- # *** BIG UGLY NOTE ***
- #
-@@ -52,15 +29,44 @@
-
- # 'Users' - code which presents functionality to userspace.
- obj-$(CONFIG_MTD_CHAR) += mtdchar.o
--obj-$(CONFIG_MTD_BLOCK) += mtdblock.o
--obj-$(CONFIG_MTD_BLOCK_RO) += mtdblock_ro.o
--obj-$(CONFIG_FTL) += ftl.o
--obj-$(CONFIG_NFTL) += nftl.o
-+obj-$(CONFIG_MTD_BLOCK) += mtdblock.o mtd_blkdevs.o
-+obj-$(CONFIG_MTD_BLOCK_RO) += mtdblock_ro.o mtd_blkdevs.o
-+obj-$(CONFIG_FTL) += ftl.o mtd_blkdevs.o
-+obj-$(CONFIG_NFTL) += nftl.o mtd_blkdevs.o
-+obj-$(CONFIG_INFTL) += inftl.o mtd_blkdevs.o
-
- nftl-objs := nftlcore.o nftlmount.o
-+inftl-objs := inftlcore.o inftlmount.o
-+
-+ifeq ($(PATCHLEVEL),4)
-+
-+export-objs := mtdcore.o mtdpart.o redboot.o cmdlinepart.o afs.o \
-+ mtdconcat.o mtd_blkdevs-24.o
-+
-+mtd_blkdevs-objs := mtd_blkdevs-24.o
-+
-+obj-y += chips/chipslink.o maps/mapslink.o \
-+ devices/devlink.o nand/nandlink.o
-+
-+O_TARGET := mtdlink.o
-+
-+list-multi := nftl.o inftl.o mtd_blkdevs.o
-+
-+mod-subdirs :=
-+subdir-y := chips maps devices nand
-+subdir-m := $(subdir-y)
-
- include $(TOPDIR)/Rules.make
-
- nftl.o: $(nftl-objs)
- $(LD) -r -o $@ $(nftl-objs)
-
-+inftl.o: $(inftl-objs)
-+ $(LD) -r -o $@ $(inftl-objs)
-+
-+mtd_blkdevs.o: $(mtd_blkdevs-objs)
-+ $(LD) -r -o $@ $(mtd_blkdevs-objs)
-+
-+else
-+obj-y += chips/ maps/ devices/ nand/
-+endif
-diff -Nurb linux-mips-2.4.27/drivers/mtd/afs.c linux/drivers/mtd/afs.c
---- linux-mips-2.4.27/drivers/mtd/afs.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/afs.c 2004-11-19 10:25:11.610243720 +0100
-@@ -21,7 +21,7 @@
- This is access code for flashes using ARM's flash partitioning
- standards.
-
-- $Id$
-+ $Id$
-
- ======================================================================*/
-
-@@ -76,17 +76,19 @@
- return ret;
- }
-
-+ ret = 1;
-+
- /*
- * Does it contain the magic number?
- */
- if (fs.signature != 0xa0ffff9f)
-- ret = 1;
-+ ret = 0;
-
- /*
- * Don't touch the SIB.
- */
- if (fs.type == 2)
-- ret = 1;
-+ ret = 0;
-
- *iis_start = fs.image_info_base & mask;
- *img_start = fs.image_start & mask;
-@@ -96,14 +98,14 @@
- * be located after the footer structure.
- */
- if (*iis_start >= ptr)
-- ret = 1;
-+ ret = 0;
-
- /*
- * Check the start of this image. The image
- * data can not be located after this block.
- */
- if (*img_start > off)
-- ret = 1;
-+ ret = 0;
-
- return ret;
- }
-@@ -125,7 +127,9 @@
- return ret;
- }
-
--int parse_afs_partitions(struct mtd_info *mtd, struct mtd_partition **pparts)
-+static int parse_afs_partitions(struct mtd_info *mtd,
-+ struct mtd_partition **pparts,
-+ unsigned long origin)
- {
- struct mtd_partition *parts;
- u_int mask, off, idx, sz;
-@@ -150,7 +154,7 @@
- ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask);
- if (ret < 0)
- break;
-- if (ret == 1)
-+ if (ret == 0)
- continue;
-
- ret = afs_read_iis(mtd, &iis, iis_ptr);
-@@ -183,7 +187,7 @@
- ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask);
- if (ret < 0)
- break;
-- if (ret == 1)
-+ if (ret == 0)
- continue;
-
- /* Read the image info block */
-@@ -227,7 +231,25 @@
- return idx ? idx : ret;
- }
-
--EXPORT_SYMBOL(parse_afs_partitions);
-+static struct mtd_part_parser afs_parser = {
-+ .owner = THIS_MODULE,
-+ .parse_fn = parse_afs_partitions,
-+ .name = "afs",
-+};
-+
-+static int __init afs_parser_init(void)
-+{
-+ return register_mtd_parser(&afs_parser);
-+}
-+
-+static void __exit afs_parser_exit(void)
-+{
-+ deregister_mtd_parser(&afs_parser);
-+}
-+
-+module_init(afs_parser_init);
-+module_exit(afs_parser_exit);
-+
-
- MODULE_AUTHOR("ARM Ltd");
- MODULE_DESCRIPTION("ARM Firmware Suite partition parser");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/Config.in linux/drivers/mtd/chips/Config.in
---- linux-mips-2.4.27/drivers/mtd/chips/Config.in 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/chips/Config.in 2004-11-19 10:25:11.712228216 +0100
-@@ -1,6 +1,6 @@
- # drivers/mtd/chips/Config.in
-
--# $Id$
-+# $Id$
-
- mainmenu_option next_comment
-
-@@ -11,13 +11,12 @@
-
- if [ "$CONFIG_MTD_CFI" = "y" -o "$CONFIG_MTD_JEDECPROBE" = "y" ]; then
- define_bool CONFIG_MTD_GEN_PROBE y
--else
-- if [ "$CONFIG_MTD_CFI" = "m" -o "$CONFIG_MTD_JEDECPROBE" = "m" ]; then
-+elif [ "$CONFIG_MTD_CFI" = "m" -o "$CONFIG_MTD_JEDECPROBE" = "m" ]; then
- define_bool CONFIG_MTD_GEN_PROBE m
-- else
-+else
- define_bool CONFIG_MTD_GEN_PROBE n
-- fi
- fi
-+
- if [ "$CONFIG_MTD_GEN_PROBE" = "y" -o "$CONFIG_MTD_GEN_PROBE" = "m" ]; then
- bool ' Flash chip driver advanced configuration options' CONFIG_MTD_CFI_ADV_OPTIONS
- if [ "$CONFIG_MTD_CFI_ADV_OPTIONS" = "y" ]; then
-@@ -44,8 +43,27 @@
- fi
- dep_tristate ' Support for Intel/Sharp flash chips' CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_GEN_PROBE
- dep_tristate ' Support for AMD/Fujitsu flash chips' CONFIG_MTD_CFI_AMDSTD $CONFIG_MTD_GEN_PROBE
-+if [ "$CONFIG_MTD_CFI_AMDSTD" = "y" -o "$CONFIG_MTD_CFI_AMDSTD" = "m" ]; then
-+ bool ' Retry failed commands (erase/program)' CONFIG_MTD_CFI_AMDSTD_RETRY n
-+ if [ "$CONFIG_MTD_CFI_AMDSTD_RETRY" = "y" ]; then
-+ int ' Max retries of failed commands (erase/program)' CONFIG_MTD_CFI_AMDSTD_RETRY_MAX 0
-+ fi
-+fi
-+
- dep_tristate ' Support for ST (Advanced Architecture) flash chips' CONFIG_MTD_CFI_STAA $CONFIG_MTD_GEN_PROBE
-
-+if [ "$CONFIG_MTD_CFI_INTELEXT" = "y" \
-+ -o "$CONFIG_MTD_CFI_AMDSTD" = "y" \
-+ -o "$CONFIG_MTD_CFI_STAA" = "y" ]; then
-+ define_bool CONFIG_MTD_CFI_UTIL y
-+elif [ "$CONFIG_MTD_CFI_INTELEXT" = "m" \
-+ -o "$CONFIG_MTD_CFI_AMDSTD" = "m" \
-+ -o "$CONFIG_MTD_CFI_STAA" = "m" ]; then
-+ define_bool CONFIG_MTD_CFI_UTIL m
-+else
-+ define_bool CONFIG_MTD_CFI_UTIL n
-+fi
-+
- dep_tristate ' Support for RAM chips in bus mapping' CONFIG_MTD_RAM $CONFIG_MTD
- dep_tristate ' Support for ROM chips in bus mapping' CONFIG_MTD_ROM $CONFIG_MTD
- dep_tristate ' Support for absent chips in bus mapping' CONFIG_MTD_ABSENT $CONFIG_MTD
-diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/Makefile linux/drivers/mtd/chips/Makefile
---- linux-mips-2.4.27/drivers/mtd/chips/Makefile 2003-07-05 05:23:38.000000000 +0200
-+++ linux/drivers/mtd/chips/Makefile 2004-11-19 10:25:11.714227912 +0100
-@@ -1,11 +1,12 @@
- #
- # linux/drivers/chips/Makefile
- #
--# $Id$
-+# $Id$
-
-+ifeq ($(PATCHLEVEL),4)
- O_TARGET := chipslink.o
--
--export-objs := chipreg.o gen_probe.o
-+export-objs := chipreg.o gen_probe.o cfi_util.o
-+endif
-
- # *** BIG UGLY NOTE ***
- #
-@@ -17,6 +18,7 @@
- obj-$(CONFIG_MTD) += chipreg.o
- obj-$(CONFIG_MTD_AMDSTD) += amd_flash.o
- obj-$(CONFIG_MTD_CFI) += cfi_probe.o
-+obj-$(CONFIG_MTD_CFI_UTIL) += cfi_util.o
- obj-$(CONFIG_MTD_CFI_STAA) += cfi_cmdset_0020.o
- obj-$(CONFIG_MTD_CFI_AMDSTD) += cfi_cmdset_0002.o
- obj-$(CONFIG_MTD_CFI_INTELEXT) += cfi_cmdset_0001.o
-@@ -28,4 +30,4 @@
- obj-$(CONFIG_MTD_SHARP) += sharp.o
- obj-$(CONFIG_MTD_ABSENT) += map_absent.o
-
--include $(TOPDIR)/Rules.make
-+-include $(TOPDIR)/Rules.make
-diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/amd_flash.c linux/drivers/mtd/chips/amd_flash.c
---- linux-mips-2.4.27/drivers/mtd/chips/amd_flash.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/chips/amd_flash.c 2004-11-19 10:25:11.722226696 +0100
-@@ -3,7 +3,7 @@
- *
- * Author: Jonas Holmberg <jonas.holmberg@axis.com>
- *
-- * $Id$
-+ * $Id$
- *
- * Copyright (c) 2001 Axis Communications AB
- *
-@@ -19,6 +19,7 @@
- #include <linux/slab.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
-+#include <linux/init.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/flashchip.h>
-@@ -125,10 +126,10 @@
-
-
- static struct mtd_chip_driver amd_flash_chipdrv = {
-- probe: amd_flash_probe,
-- destroy: amd_flash_destroy,
-- name: "amd_flash",
-- module: THIS_MODULE
-+ .probe = amd_flash_probe,
-+ .destroy = amd_flash_destroy,
-+ .name = "amd_flash",
-+ .module = THIS_MODULE
- };
-
-
-@@ -140,11 +141,11 @@
- static inline __u32 wide_read(struct map_info *map, __u32 addr)
- {
- if (map->buswidth == 1) {
-- return map->read8(map, addr);
-+ return map_read8(map, addr);
- } else if (map->buswidth == 2) {
-- return map->read16(map, addr);
-+ return map_read16(map, addr);
- } else if (map->buswidth == 4) {
-- return map->read32(map, addr);
-+ return map_read32(map, addr);
- }
-
- return 0;
-@@ -153,11 +154,11 @@
- static inline void wide_write(struct map_info *map, __u32 val, __u32 addr)
- {
- if (map->buswidth == 1) {
-- map->write8(map, val, addr);
-+ map_write8(map, val, addr);
- } else if (map->buswidth == 2) {
-- map->write16(map, val, addr);
-+ map_write16(map, val, addr);
- } else if (map->buswidth == 4) {
-- map->write32(map, val, addr);
-+ map_write32(map, val, addr);
- }
- }
-
-@@ -424,231 +425,228 @@
-
- static struct mtd_info *amd_flash_probe(struct map_info *map)
- {
-- /* Keep this table on the stack so that it gets deallocated after the
-- * probe is done.
-- */
-- const struct amd_flash_info table[] = {
-+ static const struct amd_flash_info table[] = {
- {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV160DT,
-- name: "AMD AM29LV160DT",
-- size: 0x00200000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
-- { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 }
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV160DT,
-+ .name = "AMD AM29LV160DT",
-+ .size = 0x00200000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
-+ { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 }
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV160DB,
-- name: "AMD AM29LV160DB",
-- size: 0x00200000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },
-- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV160DB,
-+ .name = "AMD AM29LV160DB",
-+ .size = 0x00200000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 },
-+ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 }
- }
- }, {
-- mfr_id: MANUFACTURER_TOSHIBA,
-- dev_id: TC58FVT160,
-- name: "Toshiba TC58FVT160",
-- size: 0x00200000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
-- { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 }
-+ .mfr_id = MANUFACTURER_TOSHIBA,
-+ .dev_id = TC58FVT160,
-+ .name = "Toshiba TC58FVT160",
-+ .size = 0x00200000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
-+ { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 }
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV160TE,
-- name: "Fujitsu MBM29LV160TE",
-- size: 0x00200000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
-- { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 }
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV160TE,
-+ .name = "Fujitsu MBM29LV160TE",
-+ .size = 0x00200000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
-+ { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 }
- }
- }, {
-- mfr_id: MANUFACTURER_TOSHIBA,
-- dev_id: TC58FVB160,
-- name: "Toshiba TC58FVB160",
-- size: 0x00200000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },
-- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
-+ .mfr_id = MANUFACTURER_TOSHIBA,
-+ .dev_id = TC58FVB160,
-+ .name = "Toshiba TC58FVB160",
-+ .size = 0x00200000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 },
-+ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 }
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV160BE,
-- name: "Fujitsu MBM29LV160BE",
-- size: 0x00200000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },
-- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV160BE,
-+ .name = "Fujitsu MBM29LV160BE",
-+ .size = 0x00200000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 },
-+ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 }
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV800BB,
-- name: "AMD AM29LV800BB",
-- size: 0x00100000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },
-- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x010000, erasesize: 0x10000, numblocks: 15 }
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV800BB,
-+ .name = "AMD AM29LV800BB",
-+ .size = 0x00100000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 },
-+ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 15 }
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F800BB,
-- name: "AMD AM29F800BB",
-- size: 0x00100000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },
-- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x010000, erasesize: 0x10000, numblocks: 15 }
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F800BB,
-+ .name = "AMD AM29F800BB",
-+ .size = 0x00100000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 },
-+ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 15 }
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV800BT,
-- name: "AMD AM29LV800BT",
-- size: 0x00100000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
-- { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 }
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV800BT,
-+ .name = "AMD AM29LV800BT",
-+ .size = 0x00100000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 },
-+ { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 }
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F800BT,
-- name: "AMD AM29F800BT",
-- size: 0x00100000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
-- { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 }
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F800BT,
-+ .name = "AMD AM29F800BT",
-+ .size = 0x00100000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 },
-+ { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 }
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV800BB,
-- name: "AMD AM29LV800BB",
-- size: 0x00100000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
-- { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 }
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV800BB,
-+ .name = "AMD AM29LV800BB",
-+ .size = 0x00100000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 },
-+ { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 }
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV800BB,
-- name: "Fujitsu MBM29LV800BB",
-- size: 0x00100000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },
-- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x010000, erasesize: 0x10000, numblocks: 15 }
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV800BB,
-+ .name = "Fujitsu MBM29LV800BB",
-+ .size = 0x00100000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 },
-+ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 15 }
- }
- }, {
-- mfr_id: MANUFACTURER_ST,
-- dev_id: M29W800T,
-- name: "ST M29W800T",
-- size: 0x00100000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 15 },
-- { offset: 0x0F0000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x0F8000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x0FC000, erasesize: 0x04000, numblocks: 1 }
-+ .mfr_id = MANUFACTURER_ST,
-+ .dev_id = M29W800T,
-+ .name = "ST M29W800T",
-+ .size = 0x00100000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 15 },
-+ { .offset = 0x0F0000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x0F8000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x0FC000, .erasesize = 0x04000, .numblocks = 1 }
- }
- }, {
-- mfr_id: MANUFACTURER_ST,
-- dev_id: M29W160DT,
-- name: "ST M29W160DT",
-- size: 0x00200000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
-- { offset: 0x1F0000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x1F8000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x1FC000, erasesize: 0x04000, numblocks: 1 }
-+ .mfr_id = MANUFACTURER_ST,
-+ .dev_id = M29W160DT,
-+ .name = "ST M29W160DT",
-+ .size = 0x00200000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
-+ { .offset = 0x1F0000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x1F8000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x1FC000, .erasesize = 0x04000, .numblocks = 1 }
- }
- }, {
-- mfr_id: MANUFACTURER_ST,
-- dev_id: M29W160DB,
-- name: "ST M29W160DB",
-- size: 0x00200000,
-- numeraseregions: 4,
-- regions: {
-- { offset: 0x000000, erasesize: 0x04000, numblocks: 1 },
-- { offset: 0x004000, erasesize: 0x02000, numblocks: 2 },
-- { offset: 0x008000, erasesize: 0x08000, numblocks: 1 },
-- { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
-+ .mfr_id = MANUFACTURER_ST,
-+ .dev_id = M29W160DB,
-+ .name = "ST M29W160DB",
-+ .size = 0x00200000,
-+ .numeraseregions = 4,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x04000, .numblocks = 1 },
-+ { .offset = 0x004000, .erasesize = 0x02000, .numblocks = 2 },
-+ { .offset = 0x008000, .erasesize = 0x08000, .numblocks = 1 },
-+ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 }
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29BDS323D,
-- name: "AMD AM29BDS323D",
-- size: 0x00400000,
-- numeraseregions: 3,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 48 },
-- { offset: 0x300000, erasesize: 0x10000, numblocks: 15 },
-- { offset: 0x3f0000, erasesize: 0x02000, numblocks: 8 },
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29BDS323D,
-+ .name = "AMD AM29BDS323D",
-+ .size = 0x00400000,
-+ .numeraseregions = 3,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 48 },
-+ { .offset = 0x300000, .erasesize = 0x10000, .numblocks = 15 },
-+ { .offset = 0x3f0000, .erasesize = 0x02000, .numblocks = 8 },
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29BDS643D,
-- name: "AMD AM29BDS643D",
-- size: 0x00800000,
-- numeraseregions: 3,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 96 },
-- { offset: 0x600000, erasesize: 0x10000, numblocks: 31 },
-- { offset: 0x7f0000, erasesize: 0x02000, numblocks: 8 },
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29BDS643D,
-+ .name = "AMD AM29BDS643D",
-+ .size = 0x00800000,
-+ .numeraseregions = 3,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 96 },
-+ { .offset = 0x600000, .erasesize = 0x10000, .numblocks = 31 },
-+ { .offset = 0x7f0000, .erasesize = 0x02000, .numblocks = 8 },
- }
- }, {
-- mfr_id: MANUFACTURER_ATMEL,
-- dev_id: AT49xV16x,
-- name: "Atmel AT49xV16x",
-- size: 0x00200000,
-- numeraseregions: 2,
-- regions: {
-- { offset: 0x000000, erasesize: 0x02000, numblocks: 8 },
-- { offset: 0x010000, erasesize: 0x10000, numblocks: 31 }
-+ .mfr_id = MANUFACTURER_ATMEL,
-+ .dev_id = AT49xV16x,
-+ .name = "Atmel AT49xV16x",
-+ .size = 0x00200000,
-+ .numeraseregions = 2,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x02000, .numblocks = 8 },
-+ { .offset = 0x010000, .erasesize = 0x10000, .numblocks = 31 }
- }
- }, {
-- mfr_id: MANUFACTURER_ATMEL,
-- dev_id: AT49xV16xT,
-- name: "Atmel AT49xV16xT",
-- size: 0x00200000,
-- numeraseregions: 2,
-- regions: {
-- { offset: 0x000000, erasesize: 0x10000, numblocks: 31 },
-- { offset: 0x1F0000, erasesize: 0x02000, numblocks: 8 }
-+ .mfr_id = MANUFACTURER_ATMEL,
-+ .dev_id = AT49xV16xT,
-+ .name = "Atmel AT49xV16xT",
-+ .size = 0x00200000,
-+ .numeraseregions = 2,
-+ .regions = {
-+ { .offset = 0x000000, .erasesize = 0x10000, .numblocks = 31 },
-+ { .offset = 0x1F0000, .erasesize = 0x02000, .numblocks = 8 }
- }
- }
- };
-@@ -822,7 +820,7 @@
-
- chip->state = FL_READY;
-
-- map->copy_from(map, buf, adr, len);
-+ map_copy_from(map, buf, adr, len);
-
- wake_up(&chip->wq);
- spin_unlock_bh(chip->mutex);
-@@ -984,7 +982,7 @@
- u_char tmp_buf[4];
- __u32 datum;
-
-- map->copy_from(map, tmp_buf,
-+ map_copy_from(map, tmp_buf,
- bus_ofs + private->chips[chipnum].start,
- map->buswidth);
- while (len && i < map->buswidth)
-@@ -1057,7 +1055,7 @@
- u_char tmp_buf[2];
- __u32 datum;
-
-- map->copy_from(map, tmp_buf,
-+ map_copy_from(map, tmp_buf,
- ofs + private->chips[chipnum].start,
- map->buswidth);
- while (len--) {
-@@ -1178,7 +1176,7 @@
- __u8 verify;
-
- for (address = adr; address < (adr + size); address++) {
-- if ((verify = map->read8(map, address)) != 0xFF) {
-+ if ((verify = map_read8(map, address)) != 0xFF) {
- error = 1;
- break;
- }
-diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/cfi_cmdset_0001.c linux/drivers/mtd/chips/cfi_cmdset_0001.c
---- linux-mips-2.4.27/drivers/mtd/chips/cfi_cmdset_0001.c 2003-07-05 05:23:38.000000000 +0200
-+++ linux/drivers/mtd/chips/cfi_cmdset_0001.c 2004-11-19 10:25:11.733225024 +0100
-@@ -4,7 +4,7 @@
- *
- * (C) 2000 Red Hat. GPL'd
- *
-- * $Id$
-+ * $Id$
- *
- *
- * 10/10/2000 Nicolas Pitre <nico@cam.org>
-@@ -21,6 +21,7 @@
- #include <linux/types.h>
- #include <linux/kernel.h>
- #include <linux/sched.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <asm/byteorder.h>
-
-@@ -29,10 +30,14 @@
- #include <linux/delay.h>
- #include <linux/interrupt.h>
- #include <linux/mtd/map.h>
--#include <linux/mtd/cfi.h>
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/compatmac.h>
-+#include <linux/mtd/cfi.h>
-+
-+/* #define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE */
-
--// debugging, turns off buffer write mode #define FORCE_WORD_WRITE
-+// debugging, turns off buffer write mode if set to 1
-+#define FORCE_WORD_WRITE 0
-
- static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
- static int cfi_intelext_read_user_prot_reg (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
-@@ -52,16 +57,21 @@
-
- static struct mtd_info *cfi_intelext_setup (struct map_info *);
-
--static int do_point (struct mtd_info *mtd, loff_t from, size_t len,
-+static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len,
- size_t *retlen, u_char **mtdbuf);
--static void do_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from,
-+static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from,
- size_t len);
-
-+
-+/*
-+ * *********** SETUP AND PROBE BITS ***********
-+ */
-+
- static struct mtd_chip_driver cfi_intelext_chipdrv = {
-- probe: NULL, /* Not usable directly */
-- destroy: cfi_intelext_destroy,
-- name: "cfi_cmdset_0001",
-- module: THIS_MODULE
-+ .probe = NULL, /* Not usable directly */
-+ .destroy = cfi_intelext_destroy,
-+ .name = "cfi_cmdset_0001",
-+ .module = THIS_MODULE
- };
-
- /* #define DEBUG_LOCK_BITS */
-@@ -102,13 +112,63 @@
- }
-
- printk(" Vcc Logic Supply Optimum Program/Erase Voltage: %d.%d V\n",
-- extp->VccOptimal >> 8, extp->VccOptimal & 0xf);
-+ extp->VccOptimal >> 4, extp->VccOptimal & 0xf);
- if (extp->VppOptimal)
- printk(" Vpp Programming Supply Optimum Program/Erase Voltage: %d.%d V\n",
-- extp->VppOptimal >> 8, extp->VppOptimal & 0xf);
-+ extp->VppOptimal >> 4, extp->VppOptimal & 0xf);
- }
- #endif
-
-+#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
-+/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */
-+static void fixup_intel_strataflash(struct map_info *map, void* param)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ struct cfi_pri_amdstd *extp = cfi->cmdset_priv;
-+
-+ printk(KERN_WARNING "cfi_cmdset_0001: Suspend "
-+ "erase on write disabled.\n");
-+ extp->SuspendCmdSupport &= ~1;
-+}
-+#endif
-+
-+static void fixup_st_m28w320ct(struct map_info *map, void* param)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+
-+ cfi->cfiq->BufWriteTimeoutTyp = 0; /* Not supported */
-+ cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */
-+}
-+
-+static void fixup_st_m28w320cb(struct map_info *map, void* param)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+
-+ /* Note this is done after the region info is endian swapped */
-+ cfi->cfiq->EraseRegionInfo[1] =
-+ (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e;
-+};
-+
-+static struct cfi_fixup fixup_table[] = {
-+#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
-+ {
-+ CFI_MFR_ANY, CFI_ID_ANY,
-+ fixup_intel_strataflash, NULL
-+ },
-+#endif
-+ {
-+ 0x0020, /* STMicroelectronics */
-+ 0x00ba, /* M28W320CT */
-+ fixup_st_m28w320ct, NULL
-+ }, {
-+ 0x0020, /* STMicroelectronics */
-+ 0x00bb, /* M28W320CB */
-+ fixup_st_m28w320cb, NULL
-+ }, {
-+ 0, 0, NULL, NULL
-+ }
-+};
-+
- /* This routine is made available to other mtd code via
- * inter_module_register. It must only be accessed through
- * inter_module_get which will bump the use count of this module. The
-@@ -120,7 +180,6 @@
- {
- struct cfi_private *cfi = map->fldrv_priv;
- int i;
-- __u32 base = cfi->chips[0].start;
-
- if (cfi->cfi_mode == CFI_MODE_CFI) {
- /*
-@@ -130,59 +189,29 @@
- */
- __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
- struct cfi_pri_intelext *extp;
-- int ofs_factor = cfi->interleave * cfi->device_type;
--
-- //printk(" Intel/Sharp Extended Query Table at 0x%4.4X\n", adr);
-- if (!adr)
-- return NULL;
-
-- /* Switch it into Query Mode */
-- cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
--
-- extp = kmalloc(sizeof(*extp), GFP_KERNEL);
-- if (!extp) {
-- printk(KERN_ERR "Failed to allocate memory\n");
-+ extp = (struct cfi_pri_intelext*)cfi_read_pri(map, adr, sizeof(*extp), "Intel/Sharp");
-+ if (!extp)
- return NULL;
-- }
--
-- /* Read in the Extended Query Table */
-- for (i=0; i<sizeof(*extp); i++) {
-- ((unsigned char *)extp)[i] =
-- cfi_read_query(map, (base+((adr+i)*ofs_factor)));
-- }
--
-- if (extp->MajorVersion != '1' ||
-- (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
-- printk(KERN_WARNING " Unknown IntelExt Extended Query "
-- "version %c.%c.\n", extp->MajorVersion,
-- extp->MinorVersion);
-- kfree(extp);
-- return NULL;
-- }
-
- /* Do some byteswapping if necessary */
- extp->FeatureSupport = le32_to_cpu(extp->FeatureSupport);
- extp->BlkStatusRegMask = le16_to_cpu(extp->BlkStatusRegMask);
- extp->ProtRegAddr = le16_to_cpu(extp->ProtRegAddr);
-
-+ /* Install our own private info structure */
-+ cfi->cmdset_priv = extp;
-+
-+ cfi_fixup(map, fixup_table);
-+
- #ifdef DEBUG_CFI_FEATURES
- /* Tell the user about it in lots of lovely detail */
- cfi_tell_features(extp);
- #endif
-
- if(extp->SuspendCmdSupport & 1) {
--//#define CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
--#ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE
--/* Some Intel Strata Flash prior to FPO revision C has bugs in this area */
-- printk(KERN_WARNING "cfi_cmdset_0001: Suspend "
-- "erase on write disabled.\n");
-- extp->SuspendCmdSupport &= ~1;
--#else
- printk(KERN_NOTICE "cfi_cmdset_0001: Erase suspend on write enabled\n");
--#endif
- }
-- /* Install our own private info structure */
-- cfi->cmdset_priv = extp;
- }
-
- for (i=0; i< cfi->numchips; i++) {
-@@ -194,8 +223,6 @@
-
- map->fldrv = &cfi_intelext_chipdrv;
-
-- /* Make sure it's in read mode */
-- cfi_send_gen_cmd(0xff, 0x55, base, map, cfi, cfi->device_type, NULL);
- return cfi_intelext_setup(map);
- }
-
-@@ -261,20 +288,16 @@
- mtd->erase = cfi_intelext_erase_varsize;
- mtd->read = cfi_intelext_read;
-
-- if(map->point && map->unpoint){
-- mtd->point = do_point;
-- mtd->unpoint = do_unpoint;
-+ if (map_is_linear(map)) {
-+ mtd->point = cfi_intelext_point;
-+ mtd->unpoint = cfi_intelext_unpoint;
- }
-
--#ifndef FORCE_WORD_WRITE
-- if ( cfi->cfiq->BufWriteTimeoutTyp ) {
-- printk("Using buffer write method\n" );
-+ if ( cfi->cfiq->BufWriteTimeoutTyp && !FORCE_WORD_WRITE) {
-+ printk(KERN_INFO "Using buffer write method\n" );
- mtd->write = cfi_intelext_write_buffers;
- } else {
--#else
-- {
--#endif
-- printk("Using word write method\n" );
-+ printk(KERN_INFO "Using word write method\n" );
- mtd->write = cfi_intelext_write_words;
- }
- mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg;
-@@ -286,8 +309,8 @@
- mtd->resume = cfi_intelext_resume;
- mtd->flags = MTD_CAP_NORFLASH;
- map->fldrv = &cfi_intelext_chipdrv;
-- MOD_INC_USE_COUNT;
- mtd->name = map->name;
-+ __module_get(THIS_MODULE);
- return mtd;
-
- setup_err:
-@@ -301,78 +324,170 @@
- return NULL;
- }
-
--static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
-+/*
-+ * *********** CHIP ACCESS FUNCTIONS ***********
-+ */
-+
-+static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
- {
-- cfi_word status, status_OK;
-- unsigned long timeo;
- DECLARE_WAITQUEUE(wait, current);
-- unsigned long cmd_addr;
- struct cfi_private *cfi = map->fldrv_priv;
-+ cfi_word status, status_OK = CMD(0x80);
-+ unsigned long timeo;
-+ struct cfi_pri_intelext *cfip = (struct cfi_pri_intelext *)cfi->cmdset_priv;
-
-- adr += chip->start;
--
-- /* Ensure cmd read/writes are aligned. */
-- cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1);
--
-- /* Let's determine this according to the interleave only once */
-- status_OK = CMD(0x80);
--
-+ resettime:
- timeo = jiffies + HZ;
- retry:
-- spin_lock(chip->mutex);
--
-- /* Check that the chip's ready to talk to us.
-- * If it's in FL_ERASING state, suspend it and make it talk now.
-- */
- switch (chip->state) {
-
-- case FL_READY:
-- case FL_POINT:
-+ case FL_STATUS:
-+ for (;;) {
-+ status = cfi_read(map, adr);
-+ if ((status & status_OK) == status_OK)
- break;
-
-+ if (time_after(jiffies, timeo)) {
-+ printk(KERN_ERR "Waiting for chip to be ready timed out. Status %llx\n",
-+ (long long)status);
-+ spin_unlock(chip->mutex);
-+ return -EIO;
-+ }
-+ spin_unlock(chip->mutex);
-+ cfi_udelay(1);
-+ spin_lock(chip->mutex);
-+ /* Someone else might have been playing with it. */
-+ goto retry;
-+ }
-+
-+ case FL_READY:
- case FL_CFI_QUERY:
- case FL_JEDEC_QUERY:
-- cfi_write(map, CMD(0x70), cmd_addr);
-- chip->state = FL_STATUS;
-+ return 0;
-
-- case FL_STATUS:
-- status = cfi_read(map, cmd_addr);
-- if ((status & status_OK) == status_OK) {
-- cfi_write(map, CMD(0xff), cmd_addr);
-- chip->state = FL_READY;
-+ case FL_ERASING:
-+ if (!(cfip->FeatureSupport & 2) ||
-+ !(mode == FL_READY || mode == FL_POINT ||
-+ (mode == FL_WRITING && (cfip->SuspendCmdSupport & 1))))
-+ goto sleep;
-+
-+
-+ /* Erase suspend */
-+ cfi_write(map, CMD(0xB0), adr);
-+
-+ /* If the flash has finished erasing, then 'erase suspend'
-+ * appears to make some (28F320) flash devices switch to
-+ * 'read' mode. Make sure that we switch to 'read status'
-+ * mode so we get the right data. --rmk
-+ */
-+ cfi_write(map, CMD(0x70), adr);
-+ chip->oldstate = FL_ERASING;
-+ chip->state = FL_ERASE_SUSPENDING;
-+ chip->erase_suspended = 1;
-+ for (;;) {
-+ status = cfi_read(map, adr);
-+ if ((status & status_OK) == status_OK)
- break;
-- }
-
-- /* Urgh. Chip not yet ready to talk to us. */
- if (time_after(jiffies, timeo)) {
-- spin_unlock(chip->mutex);
-- printk(KERN_ERR "waiting for chip to be ready timed out in read. WSM status = %llx\n", (__u64)status);
-+ /* Urgh. Resume and pretend we weren't here. */
-+ cfi_write(map, CMD(0xd0), adr);
-+ /* Make sure we're in 'read status' mode if it had finished */
-+ cfi_write(map, CMD(0x70), adr);
-+ chip->state = FL_ERASING;
-+ chip->oldstate = FL_READY;
-+ printk(KERN_ERR "Chip not ready after erase "
-+ "suspended: status = 0x%x\n", status);
- return -EIO;
- }
-
-- /* Latency issues. Drop the lock, wait a while and retry */
- spin_unlock(chip->mutex);
- cfi_udelay(1);
-- goto retry;
-+ spin_lock(chip->mutex);
-+ /* Nobody will touch it while it's in state FL_ERASE_SUSPENDING.
-+ So we can just loop here. */
-+ }
-+ chip->state = FL_STATUS;
-+ return 0;
-+
-+ case FL_POINT:
-+ /* Only if there's no operation suspended... */
-+ if (mode == FL_READY && chip->oldstate == FL_READY)
-+ return 0;
-
- default:
-- /* Stick ourselves on a wait queue to be woken when
-- someone changes the status */
-+ sleep:
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&chip->wq, &wait);
- spin_unlock(chip->mutex);
- schedule();
- remove_wait_queue(&chip->wq, &wait);
-- timeo = jiffies + HZ;
-- goto retry;
-+ spin_lock(chip->mutex);
-+ goto resettime;
- }
-+}
-+
-+static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+
-+ switch(chip->oldstate) {
-+ case FL_ERASING:
-+ chip->state = chip->oldstate;
-+ /* What if one interleaved chip has finished and the
-+ other hasn't? The old code would leave the finished
-+ one in READY mode. That's bad, and caused -EROFS
-+ errors to be returned from do_erase_oneblock because
-+ that's the only bit it checked for at the time.
-+ As the state machine appears to explicitly allow
-+ sending the 0x70 (Read Status) command to an erasing
-+ chip and expecting it to be ignored, that's what we
-+ do. */
-+ cfi_write(map, CMD(0xd0), adr);
-+ cfi_write(map, CMD(0x70), adr);
-+ chip->oldstate = FL_READY;
-+ chip->state = FL_ERASING;
-+ break;
-+
-+ case FL_READY:
-+ case FL_STATUS:
-+ /* We should really make set_vpp() count, rather than doing this */
-+ DISABLE_VPP(map);
-+ break;
-+ default:
-+ printk(KERN_ERR "put_chip() called with oldstate %d!!\n", chip->oldstate);
-+ }
-+ wake_up(&chip->wq);
-+}
-+
-+static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t adr, size_t len)
-+{
-+ unsigned long cmd_addr;
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ int ret = 0;
-+
-+ adr += chip->start;
-+
-+ /* Ensure cmd read/writes are aligned. */
-+ cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1);
-+
-+ spin_lock(chip->mutex);
-+
-+ ret = get_chip(map, chip, cmd_addr, FL_POINT);
-+
-+ if (!ret) {
-+ if (chip->state != FL_POINT && chip->state != FL_READY)
-+ cfi_write(map, CMD(0xff), cmd_addr);
-
- chip->state = FL_POINT;
- chip->ref_point_counter++;
-+ }
- spin_unlock(chip->mutex);
-- return 0;
-+
-+ return ret;
- }
--static int do_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
-+
-+static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf)
- {
- struct map_info *map = mtd->priv;
- struct cfi_private *cfi = map->fldrv_priv;
-@@ -380,12 +495,10 @@
- int chipnum;
- int ret = 0;
-
-- if (from + len > mtd->size)
-+ if (!map->virt || (from + len > mtd->size))
- return -EINVAL;
-
-- *mtdbuf = map->point(map, from, len);
-- if(*mtdbuf == NULL)
-- return -EINVAL; /* can not point this region */
-+ *mtdbuf = (void *)map->virt + from;
- *retlen = 0;
-
- /* Now lock the chip(s) to POINT state */
-@@ -418,14 +531,13 @@
- return 0;
- }
-
--static void do_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
-+static void cfi_intelext_unpoint (struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
- {
- struct map_info *map = mtd->priv;
- struct cfi_private *cfi = map->fldrv_priv;
- unsigned long ofs;
- int chipnum;
-
-- map->unpoint(map, addr, from, len);
- /* Now unlock the chip(s) POINT state */
-
- /* ofs: offset within the first chip that the first read should start */
-@@ -446,13 +558,14 @@
- thislen = len;
-
- spin_lock(chip->mutex);
-- if(chip->state == FL_POINT){
-+ if (chip->state == FL_POINT) {
- chip->ref_point_counter--;
- if(chip->ref_point_counter == 0)
- chip->state = FL_READY;
- } else
-- printk("Warning: unpoint called on non pointed region\n"); /* Should this give an error? */
-- wake_up(&chip->wq);
-+ printk(KERN_ERR "Warning: unpoint called on non pointed region\n"); /* Should this give an error? */
-+
-+ put_chip(map, chip, chip->start);
- spin_unlock(chip->mutex);
-
- len -= thislen;
-@@ -463,136 +576,32 @@
-
- static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
- {
-- cfi_word status, status_OK;
-- unsigned long timeo;
-- DECLARE_WAITQUEUE(wait, current);
-- int suspended = 0;
- unsigned long cmd_addr;
- struct cfi_private *cfi = map->fldrv_priv;
-+ int ret;
-
- adr += chip->start;
-
- /* Ensure cmd read/writes are aligned. */
- cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1);
-
-- /* Let's determine this according to the interleave only once */
-- status_OK = CMD(0x80);
--
-- timeo = jiffies + HZ;
-- retry:
- spin_lock(chip->mutex);
--
-- /* Check that the chip's ready to talk to us.
-- * If it's in FL_ERASING state, suspend it and make it talk now.
-- */
-- switch (chip->state) {
-- case FL_ERASING:
-- if (!cfi->cmdset_priv ||
-- !(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2))
-- goto sleep; /* We don't support erase suspend */
--
-- cfi_write (map, CMD(0xb0), cmd_addr);
-- /* If the flash has finished erasing, then 'erase suspend'
-- * appears to make some (28F320) flash devices switch to
-- * 'read' mode. Make sure that we switch to 'read status'
-- * mode so we get the right data. --rmk
-- */
-- cfi_write(map, CMD(0x70), cmd_addr);
-- chip->oldstate = FL_ERASING;
-- chip->state = FL_ERASE_SUSPENDING;
-- // printk("Erase suspending at 0x%lx\n", cmd_addr);
-- for (;;) {
-- status = cfi_read(map, cmd_addr);
-- if ((status & status_OK) == status_OK)
-- break;
--
-- if (time_after(jiffies, timeo)) {
-- /* Urgh */
-- cfi_write(map, CMD(0xd0), cmd_addr);
-- /* make sure we're in 'read status' mode */
-- cfi_write(map, CMD(0x70), cmd_addr);
-- chip->state = FL_ERASING;
-- spin_unlock(chip->mutex);
-- printk(KERN_ERR "Chip not ready after erase "
-- "suspended: status = 0x%llx\n", (__u64)status);
-- return -EIO;
-- }
--
-+ ret = get_chip(map, chip, cmd_addr, FL_READY);
-+ if (ret) {
- spin_unlock(chip->mutex);
-- cfi_udelay(1);
-- spin_lock(chip->mutex);
-+ return ret;
- }
-
-- suspended = 1;
-+ if (chip->state != FL_POINT && chip->state != FL_READY) {
- cfi_write(map, CMD(0xff), cmd_addr);
-- chip->state = FL_READY;
-- break;
--
--#if 0
-- case FL_WRITING:
-- /* Not quite yet */
--#endif
--
-- case FL_READY:
-- case FL_POINT:
-- break;
--
-- case FL_CFI_QUERY:
-- case FL_JEDEC_QUERY:
-- cfi_write(map, CMD(0x70), cmd_addr);
-- chip->state = FL_STATUS;
-
-- case FL_STATUS:
-- status = cfi_read(map, cmd_addr);
-- if ((status & status_OK) == status_OK) {
-- cfi_write(map, CMD(0xff), cmd_addr);
- chip->state = FL_READY;
-- break;
- }
-
-- /* Urgh. Chip not yet ready to talk to us. */
-- if (time_after(jiffies, timeo)) {
-- spin_unlock(chip->mutex);
-- printk(KERN_ERR "waiting for chip to be ready timed out in read. WSM status = %llx\n", (__u64)status);
-- return -EIO;
-- }
-+ map_copy_from(map, buf, adr, len);
-
-- /* Latency issues. Drop the lock, wait a while and retry */
-- spin_unlock(chip->mutex);
-- cfi_udelay(1);
-- goto retry;
-+ put_chip(map, chip, cmd_addr);
-
-- default:
-- sleep:
-- /* Stick ourselves on a wait queue to be woken when
-- someone changes the status */
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-- spin_unlock(chip->mutex);
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
-- timeo = jiffies + HZ;
-- goto retry;
-- }
--
-- map->copy_from(map, buf, adr, len);
--
-- if (suspended) {
-- chip->state = chip->oldstate;
-- /* What if one interleaved chip has finished and the
-- other hasn't? The old code would leave the finished
-- one in READY mode. That's bad, and caused -EROFS
-- errors to be returned from do_erase_oneblock because
-- that's the only bit it checked for at the time.
-- As the state machine appears to explicitly allow
-- sending the 0x70 (Read Status) command to an erasing
-- chip and expecting it to be ignored, that's what we
-- do. */
-- cfi_write(map, CMD(0xd0), cmd_addr);
-- cfi_write(map, CMD(0x70), cmd_addr);
-- }
--
-- wake_up(&chip->wq);
- spin_unlock(chip->mutex);
- return 0;
- }
-@@ -640,70 +649,52 @@
- {
- struct map_info *map = mtd->priv;
- struct cfi_private *cfi = map->fldrv_priv;
-- struct cfi_pri_intelext *extp=cfi->cmdset_priv;
-- int ofs_factor = cfi->interleave * cfi->device_type;
-- int count=len;
-+ struct cfi_pri_intelext *extp = cfi->cmdset_priv;
- struct flchip *chip;
-- int chip_num,offst;
-- unsigned long timeo;
-- DECLARE_WAITQUEUE(wait, current);
-+ int ofs_factor = cfi->interleave * cfi->device_type;
-+ int count = len;
-+ int chip_num, offst;
-+ int ret;
-
-- chip=0;
-- /* Calculate which chip & protection register offset we need */
-- chip_num=((unsigned int)from/reg_sz);
-- offst=from-(reg_sz*chip_num)+base_offst;
-+ chip_num = ((unsigned int)from/reg_sz);
-+ offst = from - (reg_sz*chip_num)+base_offst;
-
-- while(count){
-+ while (count) {
-+ /* Calculate which chip & protection register offset we need */
-
-- if(chip_num>=cfi->numchips)
-+ if (chip_num >= cfi->numchips)
- goto out;
-
-- /* Make sure that the chip is in the right state */
-+ chip = &cfi->chips[chip_num];
-
-- timeo = jiffies + HZ;
-- chip=&cfi->chips[chip_num];
-- retry:
- spin_lock(chip->mutex);
--
-- switch (chip->state) {
-- case FL_READY:
-- case FL_STATUS:
-- case FL_CFI_QUERY:
-- case FL_JEDEC_QUERY:
-- break;
--
-- default:
-- /* Stick ourselves on a wait queue to be woken when
-- someone changes the status */
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-+ ret = get_chip(map, chip, chip->start, FL_JEDEC_QUERY);
-+ if (ret) {
- spin_unlock(chip->mutex);
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
-- timeo = jiffies + HZ;
-- goto retry;
-+ return (len-count)?:ret;
- }
-
-- /* Now read the data required from this flash */
-+ if (chip->state != FL_JEDEC_QUERY) {
-+ cfi_write(map, CMD(0x90), chip->start);
-+ chip->state = FL_JEDEC_QUERY;
-+ }
-
-- cfi_send_gen_cmd(0x90, 0x55,chip->start, map, cfi, cfi->device_type, NULL);
-- while(count && ((offst-base_offst)<reg_sz)){
-- *buf=map->read8(map,(chip->start+((extp->ProtRegAddr+1)*ofs_factor)+offst));
-+ while (count && ((offst-base_offst) < reg_sz)) {
-+ *buf = map_read8(map,(chip->start+((extp->ProtRegAddr+1)*ofs_factor)+offst));
- buf++;
- offst++;
- count--;
- }
-
-- chip->state=FL_CFI_QUERY;
-+ put_chip(map, chip, chip->start);
- spin_unlock(chip->mutex);
-+
- /* Move on to the next chip */
- chip_num++;
-- offst=base_offst;
--
-+ offst = base_offst;
- }
-
- out:
-- wake_up(&chip->wq);
- return len-count;
- }
-
-@@ -749,103 +740,20 @@
- static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, cfi_word datum)
- {
- struct cfi_private *cfi = map->fldrv_priv;
-- struct cfi_pri_intelext *extp = cfi->cmdset_priv;
-- cfi_word status, status_OK;
-- unsigned long timeo;
-- DECLARE_WAITQUEUE(wait, current);
-- int z, suspended=0, ret=0;
--
-- adr += chip->start;
--
-- /* Let's determine this according to the interleave only once */
-- status_OK = CMD(0x80);
--
-- timeo = jiffies + HZ;
-- retry:
-- spin_lock(chip->mutex);
--
-- /* Check that the chip's ready to talk to us.
-- * Later, we can actually think about interrupting it
-- * if it's in FL_ERASING state.
-- * Not just yet, though.
-- */
-- switch (chip->state) {
-- case FL_READY:
-- break;
--
-- case FL_CFI_QUERY:
-- case FL_JEDEC_QUERY:
-- cfi_write(map, CMD(0x70), adr);
-- chip->state = FL_STATUS;
--
-- case FL_STATUS:
-- status = cfi_read(map, adr);
-- if ((status & status_OK) == status_OK)
-- break;
--
-- /* Urgh. Chip not yet ready to talk to us. */
-- if (time_after(jiffies, timeo)) {
-- spin_unlock(chip->mutex);
-- printk(KERN_ERR "waiting for chip to be ready timed out in read\n");
-- return -EIO;
-- }
--
-- /* Latency issues. Drop the lock, wait a while and retry */
-- spin_unlock(chip->mutex);
-- cfi_udelay(1);
-- goto retry;
--
-- case FL_ERASING:
-- if (!extp ||
-- !((extp->FeatureSupport & 2) && (extp->SuspendCmdSupport & 1)))
-- goto sleep; /* We don't support erase suspend */
--
-- cfi_write (map, CMD(0xb0), adr);
--
-- /* If the flash has finished erasing, then 'erase suspend'
-- * appears to make some (28F320) flash devices switch to
-- * 'read' mode. Make sure that we switch to 'read status'
-- * mode so we get the right data. --rmk
-- */
-- cfi_write(map, CMD(0x70), adr);
-- chip->oldstate = FL_ERASING;
-- chip->state = FL_ERASE_SUSPENDING;
-- for (;;) {
-- status = cfi_read(map, adr);
-- if ((status & status_OK) == status_OK)
-- break;
-+ cfi_word status, status_OK;
-+ unsigned long timeo;
-+ int z, ret=0;
-
-- if (time_after(jiffies, timeo)) {
-- /* Urgh */
-- cfi_write(map, CMD(0xd0), adr);
-- /* make sure we're in 'read status' mode */
-- cfi_write(map, CMD(0x70), adr);
-- chip->state = FL_ERASING;
-- spin_unlock(chip->mutex);
-- printk(KERN_ERR "Chip not ready after erase "
-- "suspended: status = 0x%x\n", status);
-- return -EIO;
-- }
-+ adr += chip->start;
-
-- spin_unlock(chip->mutex);
-- cfi_udelay(1);
-- spin_lock(chip->mutex);
-- }
-- suspended = 1;
-- chip->state = FL_STATUS;
-- break;
-+ /* Let's determine this according to the interleave only once */
-+ status_OK = CMD(0x80);
-
-- default:
-- sleep:
-- /* Stick ourselves on a wait queue to be woken when
-- someone changes the status */
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-+ spin_lock(chip->mutex);
-+ ret = get_chip(map, chip, adr, FL_WRITING);
-+ if (ret) {
- spin_unlock(chip->mutex);
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
-- timeo = jiffies + HZ;
-- goto retry;
-+ return ret;
- }
-
- ENABLE_VPP(map);
-@@ -862,6 +770,8 @@
- for (;;) {
- if (chip->state != FL_WRITING) {
- /* Someone's suspended the write. Sleep */
-+ DECLARE_WAITQUEUE(wait, current);
-+
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&chip->wq, &wait);
- spin_unlock(chip->mutex);
-@@ -879,7 +789,6 @@
- /* OK Still waiting */
- if (time_after(jiffies, timeo)) {
- chip->state = FL_STATUS;
-- DISABLE_VPP(map);
- printk(KERN_ERR "waiting for chip to be ready timed out in word write\n");
- ret = -EIO;
- goto out;
-@@ -908,27 +817,11 @@
- /* put back into read status register mode */
- cfi_write(map, CMD(0x70), adr);
- ret = -EROFS;
-- goto out;
- }
- out:
-- if (suspended) {
-- chip->state = chip->oldstate;
-- /* What if one interleaved chip has finished and the
-- other hasn't? The old code would leave the finished
-- one in READY mode. That's bad, and caused -EROFS
-- errors to be returned from do_erase_oneblock because
-- that's the only bit it checked for at the time.
-- As the state machine appears to explicitly allow
-- sending the 0x70 (Read Status) command to an erasing
-- chip and expecting it to be ignored, that's what we
-- do. */
-- cfi_write(map, CMD(0xd0), adr);
-- cfi_write(map, CMD(0x70), adr);
-- } else
-- DISABLE_VPP(map); /* must not clear the VPP if there is a suspended erase to be resumed */
--
-- wake_up(&chip->wq);
-+ put_chip(map, chip, adr);
- spin_unlock(chip->mutex);
-+
- return ret;
- }
-
-@@ -1059,11 +952,9 @@
- unsigned long adr, const u_char *buf, int len)
- {
- struct cfi_private *cfi = map->fldrv_priv;
-- struct cfi_pri_intelext *extp = cfi->cmdset_priv;
- cfi_word status, status_OK;
- unsigned long cmd_adr, timeo;
-- DECLARE_WAITQUEUE(wait, current);
-- int wbufsize, z, suspended=0, ret=0;
-+ int wbufsize, z, ret=0, bytes, words;
-
- wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize;
- adr += chip->start;
-@@ -1072,91 +963,18 @@
- /* Let's determine this according to the interleave only once */
- status_OK = CMD(0x80);
-
-- timeo = jiffies + HZ;
-- retry:
- spin_lock(chip->mutex);
--
-- /* Check that the chip's ready to talk to us.
-- * Later, we can actually think about interrupting it
-- * if it's in FL_ERASING state.
-- * Not just yet, though.
-- */
-- switch (chip->state) {
-- case FL_READY:
-- case FL_CFI_QUERY:
-- case FL_JEDEC_QUERY:
-- cfi_write(map, CMD(0x70), cmd_adr);
-- chip->state = FL_STATUS;
--
-- case FL_STATUS:
-- status = cfi_read(map, cmd_adr);
-- if ((status & status_OK) == status_OK)
-- break;
-- /* Urgh. Chip not yet ready to talk to us. */
-- if (time_after(jiffies, timeo)) {
-+ ret = get_chip(map, chip, cmd_adr, FL_WRITING);
-+ if (ret) {
- spin_unlock(chip->mutex);
-- printk(KERN_ERR "waiting for chip to be ready timed out in buffer write\n");
-- return -EIO;
-+ return ret;
- }
-
-- /* Latency issues. Drop the lock, wait a while and retry */
-- spin_unlock(chip->mutex);
-- cfi_udelay(1);
-- goto retry;
--
-- case FL_ERASING:
-- if (!extp ||
-- !((extp->FeatureSupport & 2) && (extp->SuspendCmdSupport & 1)))
-- goto sleep; /* We don't support erase suspend */
--
-- cfi_write (map, CMD(0xb0), adr);
--
-- /* If the flash has finished erasing, then 'erase suspend'
-- * appears to make some (28F320) flash devices switch to
-- * 'read' mode. Make sure that we switch to 'read status'
-- * mode so we get the right data. --rmk
-- */
-- cfi_write(map, CMD(0x70), adr);
-- chip->oldstate = FL_ERASING;
-- chip->state = FL_ERASE_SUSPENDING;
-- for (;;) {
-- status = cfi_read(map, adr);
-- if ((status & status_OK) == status_OK)
-- break;
--
-- if (time_after(jiffies, timeo)) {
-- /* Urgh */
-- cfi_write(map, CMD(0xd0), adr);
-- /* make sure we're in 'read status' mode */
-- cfi_write(map, CMD(0x70), adr);
-- chip->state = FL_ERASING;
-- spin_unlock(chip->mutex);
-- printk(KERN_ERR "Chip not ready after erase "
-- "suspended: status = 0x%x\n", status);
-- return -EIO;
-- }
-+ if (chip->state != FL_STATUS)
-+ cfi_write(map, CMD(0x70), cmd_adr);
-
-- spin_unlock(chip->mutex);
-- cfi_udelay(1);
-- spin_lock(chip->mutex);
-- }
-- suspended = 1;
-- chip->state = FL_STATUS;
-- break;
-+ status = cfi_read(map, cmd_adr);
-
-- default:
-- sleep:
-- /* Stick ourselves on a wait queue to be woken when
-- someone changes the status */
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-- spin_unlock(chip->mutex);
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
-- timeo = jiffies + HZ;
-- goto retry;
-- }
-- /* We know we're now in FL_STATUS mode, and 'status' is current */
- /* §4.8 of the 28FxxxJ3A datasheet says "Any time SR.4 and/or SR.5 is set
- [...], the device will not accept any more Write to Buffer commands".
- So we must check here and reset those bits if they're set. Otherwise
-@@ -1185,7 +1003,6 @@
- /* Argh. Not ready for write to buffer */
- cfi_write(map, CMD(0x70), cmd_adr);
- chip->state = FL_STATUS;
-- DISABLE_VPP(map);
- printk(KERN_ERR "Chip not ready for buffer write. Xstatus = %llx, status = %llx\n", (__u64)status, (__u64)cfi_read(map, cmd_adr));
- /* Odd. Clear status bits */
- cfi_write(map, CMD(0x50), cmd_adr);
-@@ -1196,20 +1013,42 @@
- }
-
- /* Write length of data to come */
-- cfi_write(map, CMD(len/CFIDEV_BUSWIDTH-1), cmd_adr );
-+ bytes = len & (CFIDEV_BUSWIDTH-1);
-+ words = len / CFIDEV_BUSWIDTH;
-+ cfi_write(map, CMD(words - !bytes), cmd_adr );
-
- /* Write data */
-- for (z = 0; z < len; z += CFIDEV_BUSWIDTH) {
-+ z = 0;
-+ while(z < words * CFIDEV_BUSWIDTH) {
- if (cfi_buswidth_is_1()) {
-- map->write8 (map, *((__u8*)buf)++, adr+z);
-+ map_write8 (map, *((__u8*)buf)++, adr+z);
- } else if (cfi_buswidth_is_2()) {
-- map->write16 (map, *((__u16*)buf)++, adr+z);
-+ map_write16 (map, *((__u16*)buf)++, adr+z);
- } else if (cfi_buswidth_is_4()) {
-- map->write32 (map, *((__u32*)buf)++, adr+z);
-+ map_write32 (map, *((__u32*)buf)++, adr+z);
- } else if (cfi_buswidth_is_8()) {
-- map->write64 (map, *((__u64*)buf)++, adr+z);
-+ map_write64 (map, *((__u64*)buf)++, adr+z);
-+ } else {
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+ z += CFIDEV_BUSWIDTH;
-+ }
-+ if (bytes) {
-+ int i = 0, n = 0;
-+ u_char tmp_buf[8], *tmp_p = tmp_buf;
-+
-+ while (bytes--)
-+ tmp_buf[i++] = buf[n++];
-+ while (i < CFIDEV_BUSWIDTH)
-+ tmp_buf[i++] = 0xff;
-+ if (cfi_buswidth_is_2()) {
-+ map_write16 (map, *((__u16*)tmp_p)++, adr+z);
-+ } else if (cfi_buswidth_is_4()) {
-+ map_write32 (map, *((__u32*)tmp_p)++, adr+z);
-+ } else if (cfi_buswidth_is_8()) {
-+ map_write64 (map, *((__u64*)tmp_p)++, adr+z);
- } else {
-- DISABLE_VPP(map);
- ret = -EINVAL;
- goto out;
- }
-@@ -1227,6 +1066,7 @@
- for (;;) {
- if (chip->state != FL_WRITING) {
- /* Someone's suspended the write. Sleep */
-+ DECLARE_WAITQUEUE(wait, current);
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&chip->wq, &wait);
- spin_unlock(chip->mutex);
-@@ -1244,7 +1084,6 @@
- /* OK Still waiting */
- if (time_after(jiffies, timeo)) {
- chip->state = FL_STATUS;
-- DISABLE_VPP(map);
- printk(KERN_ERR "waiting for chip to be ready timed out in bufwrite\n");
- ret = -EIO;
- goto out;
-@@ -1266,6 +1105,7 @@
-
- /* Done and happy. */
- chip->state = FL_STATUS;
-+
- /* check for lock bit */
- if (status & CMD(0x02)) {
- /* clear status */
-@@ -1273,26 +1113,10 @@
- /* put back into read status register mode */
- cfi_write(map, CMD(0x70), adr);
- ret = -EROFS;
-- goto out;
- }
-- out:
-- if (suspended) {
-- chip->state = chip->oldstate;
-- /* What if one interleaved chip has finished and the
-- other hasn't? The old code would leave the finished
-- one in READY mode. That's bad, and caused -EROFS
-- errors to be returned from do_erase_oneblock because
-- that's the only bit it checked for at the time.
-- As the state machine appears to explicitly allow
-- sending the 0x70 (Read Status) command to an erasing
-- chip and expecting it to be ignored, that's what we
-- do. */
-- cfi_write(map, CMD(0xd0), adr);
-- cfi_write(map, CMD(0x70), adr);
-- } else
-- DISABLE_VPP(map); /* must not clear the VPP if there is a suspended erase to be resumed */
-
-- wake_up(&chip->wq);
-+ out:
-+ put_chip(map, chip, cmd_adr);
- spin_unlock(chip->mutex);
- return ret;
- }
-@@ -1336,12 +1160,12 @@
- }
-
- /* Write buffer is worth it only if more than one word to write... */
-- while(len > CFIDEV_BUSWIDTH) {
-+ while(len) {
- /* We must not cross write block boundaries */
- int size = wbufsize - (ofs & (wbufsize-1));
-
- if (size > len)
-- size = len & ~(CFIDEV_BUSWIDTH-1);
-+ size = len;
- ret = do_write_buffer(map, &cfi->chips[chipnum],
- ofs, buf, size);
- if (ret)
-@@ -1359,17 +1183,6 @@
- return 0;
- }
- }
--
-- /* ... and write the remaining bytes */
-- if (len > 0) {
-- size_t local_retlen;
-- ret = cfi_intelext_write_words(mtd, ofs + (chipnum << cfi->chipshift),
-- len, &local_retlen, buf);
-- if (ret)
-- return ret;
-- (*retlen) += local_retlen;
-- }
--
- return 0;
- }
-
-@@ -1479,45 +1292,12 @@
- /* Let's determine this according to the interleave only once */
- status_OK = CMD(0x80);
-
-- timeo = jiffies + HZ;
--retry:
-+ retry:
- spin_lock(chip->mutex);
--
-- /* Check that the chip's ready to talk to us. */
-- switch (chip->state) {
-- case FL_CFI_QUERY:
-- case FL_JEDEC_QUERY:
-- case FL_READY:
-- cfi_write(map, CMD(0x70), adr);
-- chip->state = FL_STATUS;
--
-- case FL_STATUS:
-- status = cfi_read(map, adr);
-- if ((status & status_OK) == status_OK)
-- break;
--
-- /* Urgh. Chip not yet ready to talk to us. */
-- if (time_after(jiffies, timeo)) {
-- spin_unlock(chip->mutex);
-- printk(KERN_ERR "waiting for chip to be ready timed out in erase\n");
-- return -EIO;
-- }
--
-- /* Latency issues. Drop the lock, wait a while and retry */
-- spin_unlock(chip->mutex);
-- cfi_udelay(1);
-- goto retry;
--
-- default:
-- /* Stick ourselves on a wait queue to be woken when
-- someone changes the status */
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-+ ret = get_chip(map, chip, adr, FL_ERASING);
-+ if (ret) {
- spin_unlock(chip->mutex);
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
-- timeo = jiffies + HZ;
-- goto retry;
-+ return ret;
- }
-
- ENABLE_VPP(map);
-@@ -1528,7 +1308,7 @@
- cfi_write(map, CMD(0x20), adr);
- cfi_write(map, CMD(0xD0), adr);
- chip->state = FL_ERASING;
-- chip->oldstate = 0;
-+ chip->erase_suspended = 0;
-
- spin_unlock(chip->mutex);
- set_current_state(TASK_UNINTERRUPTIBLE);
-@@ -1550,11 +1330,11 @@
- spin_lock(chip->mutex);
- continue;
- }
-- if (chip->oldstate) {
-+ if (chip->erase_suspended) {
- /* This erase was suspended and resumed.
- Adjust the timeout */
- timeo = jiffies + (HZ*20); /* FIXME */
-- chip->oldstate = 0;
-+ chip->erase_suspended = 0;
- }
-
- status = cfi_read(map, adr);
-@@ -1658,39 +1438,22 @@
- int i;
- struct flchip *chip;
- int ret = 0;
-- DECLARE_WAITQUEUE(wait, current);
-
- for (i=0; !ret && i<cfi->numchips; i++) {
- chip = &cfi->chips[i];
-
-- retry:
- spin_lock(chip->mutex);
-+ ret = get_chip(map, chip, chip->start, FL_SYNCING);
-
-- switch(chip->state) {
-- case FL_READY:
-- case FL_STATUS:
-- case FL_CFI_QUERY:
-- case FL_JEDEC_QUERY:
-+ if (!ret) {
- chip->oldstate = chip->state;
- chip->state = FL_SYNCING;
- /* No need to wake_up() on this state change -
- * as the whole point is that nobody can do anything
- * with the chip now anyway.
- */
-- case FL_SYNCING:
-- spin_unlock(chip->mutex);
-- break;
--
-- default:
-- /* Not an idle state */
-- add_wait_queue(&chip->wq, &wait);
--
-- spin_unlock(chip->mutex);
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
--
-- goto retry;
- }
-+ spin_unlock(chip->mutex);
- }
-
- /* Unlock the chips again */
-@@ -1731,52 +1494,18 @@
- struct cfi_private *cfi = map->fldrv_priv;
- cfi_word status, status_OK;
- unsigned long timeo = jiffies + HZ;
-- DECLARE_WAITQUEUE(wait, current);
-+ int ret;
-
- adr += chip->start;
-
- /* Let's determine this according to the interleave only once */
- status_OK = CMD(0x80);
-
-- timeo = jiffies + HZ;
--retry:
- spin_lock(chip->mutex);
--
-- /* Check that the chip's ready to talk to us. */
-- switch (chip->state) {
-- case FL_CFI_QUERY:
-- case FL_JEDEC_QUERY:
-- case FL_READY:
-- cfi_write(map, CMD(0x70), adr);
-- chip->state = FL_STATUS;
--
-- case FL_STATUS:
-- status = cfi_read(map, adr);
-- if ((status & status_OK) == status_OK)
-- break;
--
-- /* Urgh. Chip not yet ready to talk to us. */
-- if (time_after(jiffies, timeo)) {
-- spin_unlock(chip->mutex);
-- printk(KERN_ERR "%s: waiting for chip to be ready timed out\n", __FUNCTION__);
-- return -EIO;
-- }
--
-- /* Latency issues. Drop the lock, wait a while and retry */
-- spin_unlock(chip->mutex);
-- cfi_udelay(1);
-- goto retry;
--
-- default:
-- /* Stick ourselves on a wait queue to be woken when
-- someone changes the status */
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-+ ret = get_chip(map, chip, adr, FL_LOCKING);
-+ if (ret) {
- spin_unlock(chip->mutex);
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
-- timeo = jiffies + HZ;
-- goto retry;
-+ return ret;
- }
-
- ENABLE_VPP(map);
-@@ -1823,8 +1552,7 @@
-
- /* Done and happy. */
- chip->state = FL_STATUS;
-- DISABLE_VPP(map);
-- wake_up(&chip->wq);
-+ put_chip(map, chip, adr);
- spin_unlock(chip->mutex);
- return 0;
- }
-@@ -1889,22 +1617,23 @@
-
- spin_lock(chip->mutex);
-
-- switch(chip->state) {
-+ switch (chip->state) {
- case FL_READY:
- case FL_STATUS:
- case FL_CFI_QUERY:
- case FL_JEDEC_QUERY:
-+ if (chip->oldstate == FL_READY) {
- chip->oldstate = chip->state;
- chip->state = FL_PM_SUSPENDED;
- /* No need to wake_up() on this state change -
- * as the whole point is that nobody can do anything
- * with the chip now anyway.
- */
-- case FL_PM_SUSPENDED:
-+ }
- break;
--
- default:
- ret = -EAGAIN;
-+ case FL_PM_SUSPENDED:
- break;
- }
- spin_unlock(chip->mutex);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/cfi_cmdset_0002.c linux/drivers/mtd/chips/cfi_cmdset_0002.c
---- linux-mips-2.4.27/drivers/mtd/chips/cfi_cmdset_0002.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/chips/cfi_cmdset_0002.c 2004-11-19 10:25:11.745223200 +0100
-@@ -6,16 +6,22 @@
- *
- * 2_by_8 routines added by Simon Munton
- *
-+ * 4_by_16 work by Carolyn J. Smith
-+ *
-+ * Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
-+ *
- * This code is GPL
- *
-- * $Id$
-+ * $Id$
- *
- */
-
-+#include <linux/config.h>
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
- #include <linux/sched.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <asm/byteorder.h>
-
-@@ -23,16 +29,50 @@
- #include <linux/slab.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
-+#include <linux/mtd/compatmac.h>
- #include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/cfi.h>
-
- #define AMD_BOOTLOC_BUG
-+#define FORCE_WORD_WRITE 0
-+
-+
-+/*
-+ * This is an attempt to coalesce the retry logic in one place - that way
-+ * there aren't #ifdefs scattered throughout.
-+ */
-+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
-+
-+#ifndef CONFIG_MTD_CFI_AMDSTD_RETRY_MAX
-+#define CONFIG_MTD_CFI_AMDSTD_RETRY_MAX 0
-+#endif
-+
-+#define RETRY_CMD_LABEL retry_cmd: do {} while (0)
-+#define HANDLE_WACKY_STATE() handle_wacky_state(__func__, retry_cmd_cnt, adr, datum, prev_oldstatus, prev_status, oldstatus, status)
-+static int retry_cmd_max = CONFIG_MTD_CFI_AMDSTD_RETRY_MAX;
-+#define DECLARE_RETRY_CMD_CNT() int retry_cmd_cnt = 0
-+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
-+#define CHECK_RETRIES() do { if (++retry_cmd_cnt <= retry_cmd_max) goto retry_cmd; } while (0)
-+#endif
-+
-+#else
-+
-+#define RETRY_CMD_LABEL do {} while (0)
-+#define HANDLE_WACKY_STATE() handle_wacky_state(__func__, adr, datum, prev_oldstatus, prev_status, oldstatus, status)
-+#define DECLARE_RETRY_CMD_CNT()
-+#define CHECK_RETRIES()
-+
-+#endif /* !defined(CONFIG_MTD_CFI_AMDSTD_RETRY) */
-+
-
- static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
--static int cfi_amdstd_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
-+static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
-+static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
- static int cfi_amdstd_erase_chip(struct mtd_info *, struct erase_info *);
--static int cfi_amdstd_erase_onesize(struct mtd_info *, struct erase_info *);
- static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *);
-+static int cfi_amdstd_lock_varsize(struct mtd_info *, loff_t, size_t);
-+static int cfi_amdstd_unlock_varsize(struct mtd_info *, loff_t, size_t);
- static void cfi_amdstd_sync (struct mtd_info *);
- static int cfi_amdstd_suspend (struct mtd_info *);
- static void cfi_amdstd_resume (struct mtd_info *);
-@@ -45,55 +85,136 @@
-
-
- static struct mtd_chip_driver cfi_amdstd_chipdrv = {
-- probe: NULL, /* Not usable directly */
-- destroy: cfi_amdstd_destroy,
-- name: "cfi_cmdset_0002",
-- module: THIS_MODULE
-+ .probe = NULL, /* Not usable directly */
-+ .destroy = cfi_amdstd_destroy,
-+ .name = "cfi_cmdset_0002",
-+ .module = THIS_MODULE
- };
-
--struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
-+
-+/* #define DEBUG_LOCK_BITS */
-+/* #define DEBUG_CFI_FEATURES */
-+
-+
-+#ifdef DEBUG_CFI_FEATURES
-+static void cfi_tell_features(struct cfi_pri_amdstd *extp)
- {
-- struct cfi_private *cfi = map->fldrv_priv;
-- unsigned char bootloc;
-- int ofs_factor = cfi->interleave * cfi->device_type;
-- int i;
-- __u8 major, minor;
-- __u32 base = cfi->chips[0].start;
-+ const char* erase_suspend[3] = {
-+ "Not supported", "Read only", "Read/write"
-+ };
-+ const char* top_bottom[6] = {
-+ "No WP", "8x8KiB sectors at top & bottom, no WP",
-+ "Bottom boot", "Top boot",
-+ "Uniform, Bottom WP", "Uniform, Top WP"
-+ };
-+
-+ printk(" Silicon revision: %d\n", extp->SiliconRevision >> 1);
-+ printk(" Address sensitive unlock: %s\n",
-+ (extp->SiliconRevision & 1) ? "Not required" : "Required");
-
-- if (cfi->cfi_mode==CFI_MODE_CFI){
-- __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
-+ if (extp->EraseSuspend < ARRAY_SIZE(erase_suspend))
-+ printk(" Erase Suspend: %s\n", erase_suspend[extp->EraseSuspend]);
-+ else
-+ printk(" Erase Suspend: Unknown value %d\n", extp->EraseSuspend);
-
-- cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
-+ if (extp->BlkProt == 0)
-+ printk(" Block protection: Not supported\n");
-+ else
-+ printk(" Block protection: %d sectors per group\n", extp->BlkProt);
-+
-+
-+ printk(" Temporary block unprotect: %s\n",
-+ extp->TmpBlkUnprotect ? "Supported" : "Not supported");
-+ printk(" Block protect/unprotect scheme: %d\n", extp->BlkProtUnprot);
-+ printk(" Number of simultaneous operations: %d\n", extp->SimultaneousOps);
-+ printk(" Burst mode: %s\n",
-+ extp->BurstMode ? "Supported" : "Not supported");
-+ if (extp->PageMode == 0)
-+ printk(" Page mode: Not supported\n");
-+ else
-+ printk(" Page mode: %d word page\n", extp->PageMode << 2);
-
-- major = cfi_read_query(map, base + (adr+3)*ofs_factor);
-- minor = cfi_read_query(map, base + (adr+4)*ofs_factor);
-+ printk(" Vpp Supply Minimum Program/Erase Voltage: %d.%d V\n",
-+ extp->VppMin >> 4, extp->VppMin & 0xf);
-+ printk(" Vpp Supply Maximum Program/Erase Voltage: %d.%d V\n",
-+ extp->VppMax >> 4, extp->VppMax & 0xf);
-
-- printk(KERN_NOTICE " Amd/Fujitsu Extended Query Table v%c.%c at 0x%4.4X\n",
-- major, minor, adr);
-- cfi_send_gen_cmd(0xf0, 0x55, base, map, cfi, cfi->device_type, NULL);
--
-- cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
-- cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
-- cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
-- cfi->mfr = cfi_read_query(map, base);
-- cfi->id = cfi_read_query(map, base + ofs_factor);
-+ if (extp->TopBottom < ARRAY_SIZE(top_bottom))
-+ printk(" Top/Bottom Boot Block: %s\n", top_bottom[extp->TopBottom]);
-+ else
-+ printk(" Top/Bottom Boot Block: Unknown value %d\n", extp->TopBottom);
-+}
-+#endif
-
-- /* Wheee. Bring me the head of someone at AMD. */
- #ifdef AMD_BOOTLOC_BUG
-+/* Wheee. Bring me the head of someone at AMD. */
-+static void fixup_amd_bootblock(struct map_info *map, void* param)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ struct cfi_pri_amdstd *extp = cfi->cmdset_priv;
-+ __u8 major = extp->MajorVersion;
-+ __u8 minor = extp->MinorVersion;
-+
- if (((major << 8) | minor) < 0x3131) {
- /* CFI version 1.0 => don't trust bootloc */
- if (cfi->id & 0x80) {
- printk(KERN_WARNING "%s: JEDEC Device ID is 0x%02X. Assuming broken CFI table.\n", map->name, cfi->id);
-- bootloc = 3; /* top boot */
-+ extp->TopBottom = 3; /* top boot */
- } else {
-- bootloc = 2; /* bottom boot */
-+ extp->TopBottom = 2; /* bottom boot */
- }
-- } else
-+ }
-+}
- #endif
-+
-+static struct cfi_fixup fixup_table[] = {
-+#ifdef AMD_BOOTLOC_BUG
- {
-- cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
-- bootloc = cfi_read_query(map, base + (adr+15)*ofs_factor);
-+ 0x0001, /* AMD */
-+ CFI_ID_ANY,
-+ fixup_amd_bootblock, NULL
-+ },
-+#endif
-+ { 0, 0, NULL, NULL }
-+};
-+
-+
-+struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ unsigned char bootloc;
-+ int i;
-+
-+ if (cfi->cfi_mode==CFI_MODE_CFI){
-+ /*
-+ * It's a real CFI chip, not one for which the probe
-+ * routine faked a CFI structure. So we read the feature
-+ * table from it.
-+ */
-+ __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
-+ struct cfi_pri_amdstd *extp;
-+
-+ extp = (struct cfi_pri_amdstd*)cfi_read_pri(map, adr, sizeof(*extp), "Amd/Fujitsu");
-+ if (!extp)
-+ return NULL;
-+
-+ /* Install our own private info structure */
-+ cfi->cmdset_priv = extp;
-+
-+ cfi_fixup(map, fixup_table);
-+
-+#ifdef DEBUG_CFI_FEATURES
-+ /* Tell the user about it in lots of lovely detail */
-+ cfi_tell_features(extp);
-+#endif
-+
-+ bootloc = extp->TopBottom;
-+ if ((bootloc != 2) && (bootloc != 3)) {
-+ printk(KERN_WARNING "%s: CFI does not contain boot "
-+ "bank location. Assuming top.\n", map->name);
-+ bootloc = 2;
- }
-+
- if (bootloc == 3 && cfi->cfiq->NumEraseRegions > 1) {
- printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n", map->name);
-
-@@ -106,6 +227,11 @@
- cfi->cfiq->EraseRegionInfo[j] = swap;
- }
- }
-+ /*
-+ * These might already be setup (more correctly) by
-+ * jedec_probe.c - still need it for cfi_probe.c path.
-+ */
-+ if ( ! (cfi->addr_unlock1 && cfi->addr_unlock2) ) {
- switch (cfi->device_type) {
- case CFI_DEVICETYPE_X8:
- cfi->addr_unlock1 = 0x555;
-@@ -125,9 +251,13 @@
- cfi->addr_unlock2 = 0xaaa;
- break;
- default:
-- printk(KERN_NOTICE "Eep. Unknown cfi_cmdset_0002 device type %d\n", cfi->device_type);
-+ printk(KERN_WARNING
-+ "MTD %s(): Unsupported device type %d\n",
-+ __func__, cfi->device_type);
- return NULL;
- }
-+ }
-+
- } /* CFI mode */
-
- for (i=0; i< cfi->numchips; i++) {
-@@ -138,15 +268,17 @@
-
- map->fldrv = &cfi_amdstd_chipdrv;
-
-- cfi_send_gen_cmd(0xf0, 0x55, base, map, cfi, cfi->device_type, NULL);
- return cfi_amdstd_setup(map);
- }
-
-+
- static struct mtd_info *cfi_amdstd_setup(struct map_info *map)
- {
- struct cfi_private *cfi = map->fldrv_priv;
- struct mtd_info *mtd;
- unsigned long devsize = (1<<cfi->cfiq->DevSize) * cfi->interleave;
-+ unsigned long offset = 0;
-+ int i,j;
-
- mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);
- printk(KERN_NOTICE "number of %s chips: %d\n",
-@@ -163,15 +295,9 @@
- /* Also select the correct geometry setup too */
- mtd->size = devsize * cfi->numchips;
-
-- if (cfi->cfiq->NumEraseRegions == 1) {
-- /* No need to muck about with multiple erase sizes */
-- mtd->erasesize = ((cfi->cfiq->EraseRegionInfo[0] >> 8) & ~0xff) * cfi->interleave;
-- } else {
-- unsigned long offset = 0;
-- int i,j;
--
- mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips;
-- mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) * mtd->numeraseregions, GFP_KERNEL);
-+ mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info)
-+ * mtd->numeraseregions, GFP_KERNEL);
- if (!mtd->eraseregions) {
- printk(KERN_WARNING "Failed to allocate memory for MTD erase region info\n");
- goto setup_err;
-@@ -206,39 +332,52 @@
- mtd->eraseregions[i].numblocks);
- }
- #endif
-- }
-
- switch (CFIDEV_BUSWIDTH)
- {
- case 1:
- case 2:
- case 4:
--#if 1
-- if (mtd->numeraseregions > 1)
-- mtd->erase = cfi_amdstd_erase_varsize;
-- else
-+#ifdef CFI_WORD_64
-+ case 8:
- #endif
-- if (((cfi->cfiq->EraseRegionInfo[0] & 0xffff) + 1) == 1)
-+ if (mtd->numeraseregions == 1
-+ && ((cfi->cfiq->EraseRegionInfo[0] & 0xffff) + 1) == 1) {
- mtd->erase = cfi_amdstd_erase_chip;
-- else
-- mtd->erase = cfi_amdstd_erase_onesize;
-+ } else {
-+ mtd->erase = cfi_amdstd_erase_varsize;
-+ mtd->lock = cfi_amdstd_lock_varsize;
-+ mtd->unlock = cfi_amdstd_unlock_varsize;
-+ }
-+
-+ if ( cfi->cfiq->BufWriteTimeoutTyp && !FORCE_WORD_WRITE) {
-+ DEBUG(MTD_DEBUG_LEVEL1, "Using buffer write method\n" );
-+ mtd->write = cfi_amdstd_write_buffers;
-+ } else {
-+ DEBUG(MTD_DEBUG_LEVEL1, "Using word write method\n" );
-+ mtd->write = cfi_amdstd_write_words;
-+ }
-+
- mtd->read = cfi_amdstd_read;
-- mtd->write = cfi_amdstd_write;
- break;
-
- default:
-- printk(KERN_WARNING "Unsupported buswidth\n");
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
- goto setup_err;
- break;
- }
- if (cfi->fast_prog) {
-- /* In cfi_amdstd_write() we frob the protection stuff
-+ /* In cfi_amdstd_write_words() we frob the protection stuff
- without paying any attention to the state machine.
- This upsets in-progress erases. So we turn this flag
- off for now till the code gets fixed. */
- printk(KERN_NOTICE "cfi_cmdset_0002: Disabling fast programming due to code brokenness.\n");
- cfi->fast_prog = 0;
- }
-+ /* FIXME: erase-suspend-program is broken. See
-+ http://lists.infradead.org/pipermail/linux-mtd/2003-December/009001.html */
-+ printk(KERN_NOTICE "cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.\n");
-
-
- /* does this chip have a secsi area? */
-@@ -266,7 +405,7 @@
- mtd->flags = MTD_CAP_NORFLASH;
- map->fldrv = &cfi_amdstd_chipdrv;
- mtd->name = map->name;
-- MOD_INC_USE_COUNT;
-+ __module_get(THIS_MODULE);
- return mtd;
-
- setup_err:
-@@ -280,46 +419,210 @@
- return NULL;
- }
-
--static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
-+
-+/* This is more work to coalesce the retry #ifdefs in one location */
-+static inline void handle_wacky_state(const char *func,
-+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
-+ int retry_cmd_cnt,
-+#endif
-+ unsigned long adr,
-+ cfi_word datum,
-+ cfi_word prev_oldstatus,
-+ cfi_word prev_status,
-+ cfi_word oldstatus,
-+ cfi_word status)
-+{
-+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
-+ if ( retry_cmd_cnt == retry_cmd_max ) {
-+#endif
-+ printk(KERN_WARNING
-+ "MTD %s(): Wacky! Unable to decode failure status\n"
-+ "Possible buggy device - try "
-+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
-+ "increasing retry_cmd_max from %d\n"
-+#else
-+ "enabling CONFIG_MTD_CFI_AMDSTD_RETRY\n"
-+ "in your kernel config and setting driver retry_cmd_max\n"
-+#endif
-+ , func
-+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
-+ , retry_cmd_max
-+#endif
-+ );
-+
-+ printk(KERN_WARNING
-+ "MTD %s(): 0x%.8lx(0x%.8x): 0x%.8x 0x%.8x 0x%.8x 0x%.8x\n",
-+ func, adr, datum,
-+ prev_oldstatus, prev_status,
-+ oldstatus, status);
-+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
-+ }
-+#endif
-+}
-+
-+
-+static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode)
- {
- DECLARE_WAITQUEUE(wait, current);
-- unsigned long timeo = jiffies + HZ;
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ cfi_word status, oldstatus;
-+ cfi_word dq6 = CMD(1<<6);
-+ cfi_word dq2 = CMD(1<<2);
-+ unsigned long timeo;
-+ struct cfi_pri_amdstd *cfip = (struct cfi_pri_amdstd *)cfi->cmdset_priv;
-
-+ resettime:
-+ timeo = jiffies + HZ;
- retry:
-+ switch (chip->state) {
-+
-+ case FL_STATUS:
-+ for (;;) {
-+ oldstatus = cfi_read(map, adr);
-+ status = cfi_read(map, adr);
-+ if (((oldstatus ^ status) & (dq6 | dq2)) == 0)
-+ break;
-+
-+ if (time_after(jiffies, timeo)) {
-+ printk(KERN_ERR "Waiting for chip to be ready timed out. Status %llx\n",
-+ (long long)status);
-+ cfi_spin_unlock(chip->mutex);
-+ return -EIO;
-+ }
-+ cfi_spin_unlock(chip->mutex);
-+ cfi_udelay(1);
- cfi_spin_lock(chip->mutex);
-+ /* Someone else might have been playing with it. */
-+ goto retry;
-+ }
-
-- if (chip->state != FL_READY){
--#if 0
-- printk(KERN_DEBUG "Waiting for chip to read, status = %d\n", chip->state);
--#endif
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-+ case FL_READY:
-+ case FL_CFI_QUERY:
-+ case FL_JEDEC_QUERY:
-+ return 0;
-+
-+ case FL_ERASING:
-+ if (mode == FL_WRITING) /* FIXME: Erase-suspend-program appears broken. */
-+ goto sleep;
-+
-+ if (!(mode == FL_READY || mode == FL_POINT
-+ || (mode == FL_WRITING && (cfip->EraseSuspend & 0x2))
-+ || (mode == FL_WRITING && (cfip->EraseSuspend & 0x1))))
-+ goto sleep;
-+
-+ oldstatus = cfi_read(map, adr);
-+ status = cfi_read(map, adr);
-+ if ((oldstatus ^ status) & dq2) {
-+ printk(KERN_ERR "Can't suspend erase -- block in progress\n");
-+ goto sleep;
-+ }
-+
-+ /* Erase suspend */
-+ /* FIXME - is there a way to verify suspend? */
-+ cfi_write(map, CMD(0xB0), chip->in_progress_block_addr);
-+ chip->oldstate = FL_ERASING;
-+ chip->state = FL_ERASE_SUSPENDING;
-+ chip->erase_suspended = 1;
-+ for (;;) {
-+ oldstatus = cfi_read(map, chip->in_progress_block_addr);
-+ status = cfi_read(map, chip->in_progress_block_addr);
-+ if (((oldstatus ^ status) & dq6) == 0)
-+ break;
-+
-+ if (time_after(jiffies, timeo)) {
-+ /* Urgh. Resume and pretend we weren't here. */
-+ /* FIXME - is there a way to verify resume? */
-+ cfi_write(map, CMD(0x30), chip->in_progress_block_addr);
-+ chip->state = FL_ERASING;
-+ chip->oldstate = FL_READY;
-+ printk(KERN_ERR "Chip not ready after erase "
-+ "suspended: status = 0x%x\n", status);
-+ return -EIO;
-+ }
-
- cfi_spin_unlock(chip->mutex);
-+ cfi_udelay(1);
-+ cfi_spin_lock(chip->mutex);
-+ /* Nobody will touch it while it's in state FL_ERASE_SUSPENDING.
-+ So we can just loop here. */
-+ }
-+ chip->state = FL_READY;
-+ return 0;
-+
-+ case FL_POINT:
-+ /* Only if there's no operation suspended... */
-+ if (mode == FL_READY && chip->oldstate == FL_READY)
-+ return 0;
-
-+ default:
-+ sleep:
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ add_wait_queue(&chip->wq, &wait);
-+ cfi_spin_unlock(chip->mutex);
- schedule();
- remove_wait_queue(&chip->wq, &wait);
--#if 0
-- if(signal_pending(current))
-- return -EINTR;
--#endif
-- timeo = jiffies + HZ;
-+ cfi_spin_lock(chip->mutex);
-+ goto resettime;
-+ }
-+}
-
-- goto retry;
-+
-+static void put_chip(struct map_info *map, struct flchip *chip, unsigned long adr)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+
-+ switch(chip->oldstate) {
-+ case FL_ERASING:
-+ chip->state = chip->oldstate;
-+ cfi_write(map, CMD(0x30), chip->in_progress_block_addr);
-+ chip->oldstate = FL_READY;
-+ chip->state = FL_ERASING;
-+ break;
-+
-+ case FL_READY:
-+ case FL_STATUS:
-+ /* We should really make set_vpp() count, rather than doing this */
-+ DISABLE_VPP(map);
-+ break;
-+ default:
-+ printk(KERN_ERR "MTD: put_chip() called with oldstate %d!!\n", chip->oldstate);
- }
-+ wake_up(&chip->wq);
-+}
-+
-+
-+static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
-+{
-+ unsigned long cmd_addr;
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ int ret;
-
- adr += chip->start;
-
-+ /* Ensure cmd read/writes are aligned. */
-+ cmd_addr = adr & ~(CFIDEV_BUSWIDTH-1);
-+
-+ cfi_spin_lock(chip->mutex);
-+ ret = get_chip(map, chip, cmd_addr, FL_READY);
-+ if (ret) {
-+ cfi_spin_unlock(chip->mutex);
-+ return ret;
-+ }
-+
-+ if (chip->state != FL_POINT && chip->state != FL_READY) {
-+ cfi_write(map, CMD(0xf0), cmd_addr);
- chip->state = FL_READY;
-+ }
-
-- map->copy_from(map, buf, adr, len);
-+ map_copy_from(map, buf, adr, len);
-
-- wake_up(&chip->wq);
-- cfi_spin_unlock(chip->mutex);
-+ put_chip(map, chip, cmd_addr);
-
-+ cfi_spin_unlock(chip->mutex);
- return 0;
- }
-
-+
- static int cfi_amdstd_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
- {
- struct map_info *map = mtd->priv;
-@@ -361,6 +664,7 @@
- return ret;
- }
-
-+
- static inline int do_read_secsi_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
- {
- DECLARE_WAITQUEUE(wait, current);
-@@ -394,12 +698,14 @@
-
- chip->state = FL_READY;
-
-+ /* should these be CFI_DEVICETYPE_X8 instead of cfi->device_type? */
- cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
- cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
-
-- map->copy_from(map, buf, adr, len);
-+ map_copy_from(map, buf, adr, len);
-
-+ /* should these be CFI_DEVICETYPE_X8 instead of cfi->device_type? */
- cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL);
- cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL);
-@@ -454,125 +760,241 @@
- return ret;
- }
-
--static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, __u32 datum, int fast)
-+
-+static int do_write_oneword(struct map_info *map, struct flchip *chip, unsigned long adr, cfi_word datum, int fast)
- {
-- unsigned long timeo = jiffies + HZ;
-- unsigned int oldstatus, status;
-- unsigned int dq6, dq5;
- struct cfi_private *cfi = map->fldrv_priv;
-- DECLARE_WAITQUEUE(wait, current);
-+ unsigned long timeo = jiffies + HZ;
-+ cfi_word oldstatus, status, prev_oldstatus, prev_status;
-+ cfi_word dq6 = CMD(1<<6);
-+ /*
-+ * We use a 1ms + 1 jiffies generic timeout for writes (most devices
-+ * have a max write time of a few hundreds usec). However, we should
-+ * use the maximum timeout value given by the chip at probe time
-+ * instead. Unfortunately, struct flchip does have a field for
-+ * maximum timeout, only for typical which can be far too short
-+ * depending of the conditions. The ' + 1' is to avoid having a
-+ * timeout of 0 jiffies if HZ is smaller than 1000.
-+ */
-+ unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
- int ret = 0;
-+ int ta = 0;
-+ DECLARE_RETRY_CMD_CNT();
-
-- retry:
-- cfi_spin_lock(chip->mutex);
--
-- if (chip->state != FL_READY) {
--#if 0
-- printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", chip->state);
--#endif
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-+ adr += chip->start;
-
-+ cfi_spin_lock(chip->mutex);
-+ ret = get_chip(map, chip, adr, FL_WRITING);
-+ if (ret) {
- cfi_spin_unlock(chip->mutex);
--
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
--#if 0
-- printk(KERN_DEBUG "Wake up to write:\n");
-- if(signal_pending(current))
-- return -EINTR;
--#endif
-- timeo = jiffies + HZ;
--
-- goto retry;
-+ return ret;
- }
-
-- chip->state = FL_WRITING;
-+ RETRY_CMD_LABEL;
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8x)\n",
-+ __func__, adr, datum );
-+
-+ /*
-+ * Check for a NOP for the case when the datum to write is already
-+ * present - it saves time and works around buggy chips that corrupt
-+ * data at other locations when 0xff is written to a location that
-+ * already contains 0xff.
-+ */
-+ status = cfi_read(map, adr);
-+ if (status == datum) {
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): NOP 0x%.8x == 0x%.8x\n",
-+ __func__, status, datum );
-+ goto op_done;
-+ }
-
-- adr += chip->start;
- ENABLE_VPP(map);
- if (fast) { /* Unlock bypass */
- cfi_send_gen_cmd(0xA0, 0, chip->start, map, cfi, cfi->device_type, NULL);
-- }
-- else {
-+ } else {
-+ /*
-+ * The CFI_DEVICETYPE_X8 argument is needed even when
-+ * cfi->device_type != CFI_DEVICETYPE_X8. The addresses for
-+ * command sequences don't scale even when the device is
-+ * wider. This is the case for many of the cfi_send_gen_cmd()
-+ * below. I'm not sure, however, why some use
-+ * cfi->device_type.
-+ */
- cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- }
--
- cfi_write(map, datum, adr);
-+ chip->state = FL_WRITING;
-
- cfi_spin_unlock(chip->mutex);
- cfi_udelay(chip->word_write_time);
- cfi_spin_lock(chip->mutex);
-
-- /* Polling toggle bits instead of reading back many times
-- This ensures that write operation is really completed,
-- or tells us why it failed. */
-- dq6 = CMD(1<<6);
-- dq5 = CMD(1<<5);
-- timeo = jiffies + (HZ/1000); /* setting timeout to 1ms for now */
-+ /*
-+ * Polling toggle bits instead of reading back many times This ensures
-+ * that write operation is really completed, or tells us why it
-+ * failed.
-+ *
-+ * It may appear that the polling and decoding of error state might be
-+ * simplified. Don't do it unless you really know what you are doing.
-+ *
-+ * You must remember that JESD21-C 3.5.3 states that the status must
-+ * be read back an _additional_ two times before a failure is
-+ * determined. This is because these devices have internal state
-+ * machines that are asynchronous to the external data bus. During an
-+ * erase or write the read-back status of the polling bits might be
-+ * transitioning internaly when the external read-back occurs. This
-+ * means that the bits aren't in the final state and they might appear
-+ * to report an error as they are in a transient state: dq7 is
-+ * asynchronous with dq6 and other status bits.
-+ *
-+ * This asynchronous behaviour can cause infrequent errors that will
-+ * usually disappear the next time an erase or write happens (Try
-+ * tracking those errors down!). To ensure that the bits are not in
-+ * transition, the location must be read-back two more times and
-+ * compared against what was written - BOTH reads MUST match what was
-+ * written. Don't think this can be simplified to only the last read
-+ * matching the datum written: status bits *can* match the datum
-+ * written.
-+ *
-+ * If the final comparison fails, error state can *then* be decoded.
-+ *
-+ * - Thayne Harbaugh
-+ */
-+ /* See comment above for timeout value. */
-+ timeo = jiffies + uWriteTimeout;
-+ for (;;) {
-+ if (chip->state != FL_WRITING) {
-+ /* Someone's suspended the write. Sleep */
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ add_wait_queue(&chip->wq, &wait);
-+ cfi_spin_unlock(chip->mutex);
-+ schedule();
-+ remove_wait_queue(&chip->wq, &wait);
-+ timeo = jiffies + (HZ / 2); /* FIXME */
-+ cfi_spin_lock(chip->mutex);
-+ continue;
-+ }
-
- oldstatus = cfi_read(map, adr);
- status = cfi_read(map, adr);
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n",
-+ __func__, oldstatus, status );
-
-- while( (status & dq6) != (oldstatus & dq6) &&
-- (status & dq5) != dq5 &&
-- !time_after(jiffies, timeo) ) {
-+ /*
-+ * This only checks if dq6 is still toggling and that our
-+ * timer hasn't expired. We purposefully ignore the chip's
-+ * internal timer that will assert dq5 and leave dq6 toggling.
-+ * This is done for a variety of reasons:
-+ *
-+ * 1) Not all chips support dq5.
-+ *
-+ * 2) Dealing with asynchronous status bit and data updates
-+ * and reading a device two more times creates _messy_ logic
-+ * when trying to deal with interleaved devices - some may be
-+ * changing while others are still busy.
-+ *
-+ * 3) Checking dq5 only helps to optimize an error case that
-+ * should at worst be infrequent and at best non-existent.
-+ *
-+ * If our timeout occurs _then_ we will check dq5 to see if
-+ * the device also had an internal timeout.
-+ */
-+ if ( (((status ^ oldstatus) & dq6) == 0)
-+ || ( ta = time_after(jiffies, timeo)) )
-+ break;
-
-- if (need_resched()) {
-+ /* Latency issues. Drop the lock, wait a while and retry */
- cfi_spin_unlock(chip->mutex);
-- yield();
-+ cfi_udelay(1);
- cfi_spin_lock(chip->mutex);
-- } else
-- udelay(1);
--
-- oldstatus = cfi_read( map, adr );
-- status = cfi_read( map, adr );
- }
-
-- if( (status & dq6) != (oldstatus & dq6) ) {
-- /* The erasing didn't stop?? */
-- if( (status & dq5) == dq5 ) {
-- /* When DQ5 raises, we must check once again
-- if DQ6 is toggling. If not, the erase has been
-- completed OK. If not, reset chip. */
-+ /*
-+ * Something kicked us out of the read-back loop. We'll check success
-+ * befor checking failure. Even though dq6 might be true data, it is
-+ * unkown if all of the other bits have changed to true data due to
-+ * the asynchronous nature of the internal state machine. We will
-+ * read two more times and use this to either verify that the write
-+ * completed successfully or that something really went wrong. BOTH
-+ * reads must match what was written - this certifies that bits aren't
-+ * still changing and that the status bits erroneously match the datum
-+ * that was written.
-+ */
-+ prev_oldstatus = oldstatus;
-+ prev_status = status;
- oldstatus = cfi_read(map, adr);
- status = cfi_read(map, adr);
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n",
-+ __func__, oldstatus, status );
-
-- if ( (oldstatus & 0x00FF) == (status & 0x00FF) ) {
-- printk(KERN_WARNING "Warning: DQ5 raised while program operation was in progress, however operation completed OK\n" );
-+ if ( oldstatus == datum && status == datum ) {
-+ /* success - do nothing */
-+ goto op_done;
-+ }
-+
-+ if ( ta ) {
-+ /* Only check dq5 on the chips that are still toggling. */
-+ cfi_word dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1;
-+ if ( status & dq5mask ) {
-+ /* dq5 asserted - decode interleave chips */
-+ printk( KERN_WARNING
-+ "MTD %s(): FLASH internal timeout: 0x%.8x 0x%.8x 0x%8x\n",
-+ __func__,
-+ status & dq5mask, status, datum );
- } else {
-- /* DQ5 is active so we can do a reset and stop the erase */
-- cfi_write(map, CMD(0xF0), chip->start);
-- printk(KERN_WARNING "Internal flash device timeout occurred or write operation was performed while flash was programming.\n" );
-+ printk( KERN_WARNING
-+ "MTD %s(): Software timed out during write.\n",
-+ __func__ );
-+ }
-+ goto op_failed;
- }
-- } else {
-- printk(KERN_WARNING "Waiting for write to complete timed out in do_write_oneword.");
-
-+ /*
-+ * If we get to here then it means that something
-+ * is wrong and it's not a timeout. Something
-+ * is seriously wacky! Dump some debug info.
-+ */
-+ /*
-+ * Found a clue about the chips that reach this state.
-+ * Some flash chips (SST >cough<)
-+ * are horribly broken. They do not ignore traffic that is
-+ * destined to other devices. This happens because some solutions
-+ * are on shared busses, the erase and program sequences have
-+ * have multiple commands, and the sequence is interspersed with
-+ * commands destined to other devices. A good flash chip will
-+ * examine the command and destination address and will ignore
-+ * commands that are for other devices.
-+ */
-+ HANDLE_WACKY_STATE();
-+
-+ op_failed:
-+ /* reset on all failures. */
-+ cfi_write( map, CMD(0xF0), chip->start );
-+ /* FIXME - should have reset delay before continuing */
-+ CHECK_RETRIES();
-+ ret = -EIO;
-+
-+ op_done:
- chip->state = FL_READY;
-- wake_up(&chip->wq);
-- cfi_spin_unlock(chip->mutex);
-- DISABLE_VPP(map);
-- ret = -EIO;
-- }
-- }
--
-- DISABLE_VPP(map);
-- chip->state = FL_READY;
-- wake_up(&chip->wq);
-+ put_chip(map, chip, adr);
- cfi_spin_unlock(chip->mutex);
-
- return ret;
- }
-
--static int cfi_amdstd_write (struct mtd_info *mtd, loff_t to , size_t len, size_t *retlen, const u_char *buf)
-+
-+static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf)
- {
- struct map_info *map = mtd->priv;
- struct cfi_private *cfi = map->fldrv_priv;
- int ret = 0;
- int chipnum;
- unsigned long ofs, chipstart;
-+ DECLARE_WAITQUEUE(wait, current);
-
- *retlen = 0;
- if (!len)
-@@ -587,19 +1009,52 @@
- unsigned long bus_ofs = ofs & ~(CFIDEV_BUSWIDTH-1);
- int i = ofs - bus_ofs;
- int n = 0;
-- u_char tmp_buf[4];
-- __u32 datum;
-+ u_char tmp_buf[8];
-+ cfi_word datum;
-+
-+ retry:
-+ cfi_spin_lock(cfi->chips[chipnum].mutex);
-+
-+ if (cfi->chips[chipnum].state != FL_READY) {
-+#if 0
-+ printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", cfi->chips[chipnum].state);
-+#endif
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ add_wait_queue(&cfi->chips[chipnum].wq, &wait);
-+
-+ cfi_spin_unlock(cfi->chips[chipnum].mutex);
-+
-+ schedule();
-+ remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
-+#if 0
-+ if(signal_pending(current))
-+ return -EINTR;
-+#endif
-+ goto retry;
-+ }
-+
-+ map_copy_from(map, tmp_buf, bus_ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
-
-- map->copy_from(map, tmp_buf, bus_ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
-- while (len && i < CFIDEV_BUSWIDTH)
-- tmp_buf[i++] = buf[n++], len--;
-+ cfi_spin_unlock(cfi->chips[chipnum].mutex);
-+
-+ while (len && i < CFIDEV_BUSWIDTH) {
-+ tmp_buf[i++] = buf[n++];
-+ len--;
-+ }
-
-+ /* already know that buswidth > 1 */
- if (cfi_buswidth_is_2()) {
- datum = *(__u16*)tmp_buf;
- } else if (cfi_buswidth_is_4()) {
- datum = *(__u32*)tmp_buf;
-+#ifdef CFI_WORD_64
-+ } else if (cfi_buswidth_is_8()) {
-+ datum = *(__u64*)tmp_buf;
-+#endif
- } else {
-- return -EINVAL; /* should never happen, but be safe */
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
-+ return -EINVAL;
- }
-
- ret = do_write_oneword(map, &cfi->chips[chipnum],
-@@ -628,7 +1083,7 @@
-
- /* We are now aligned, write as much as possible */
- while(len >= CFIDEV_BUSWIDTH) {
-- __u32 datum;
-+ cfi_word datum;
-
- if (cfi_buswidth_is_1()) {
- datum = *(__u8*)buf;
-@@ -636,7 +1091,13 @@
- datum = *(__u16*)buf;
- } else if (cfi_buswidth_is_4()) {
- datum = *(__u32*)buf;
-+#ifdef CFI_WORD_64
-+ } else if (cfi_buswidth_is_8()) {
-+ datum = *(__u64*)buf;
-+#endif
- } else {
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
- return -EINVAL;
- }
- ret = do_write_oneword(map, &cfi->chips[chipnum],
-@@ -685,10 +1146,34 @@
- /* Write the trailing bytes if any */
- if (len & (CFIDEV_BUSWIDTH-1)) {
- int i = 0, n = 0;
-- u_char tmp_buf[4];
-- __u32 datum;
-+ u_char tmp_buf[8];
-+ cfi_word datum;
-+
-+ retry1:
-+ cfi_spin_lock(cfi->chips[chipnum].mutex);
-+
-+ if (cfi->chips[chipnum].state != FL_READY) {
-+#if 0
-+ printk(KERN_DEBUG "Waiting for chip to write, status = %d\n", cfi->chips[chipnum].state);
-+#endif
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ add_wait_queue(&cfi->chips[chipnum].wq, &wait);
-+
-+ cfi_spin_unlock(cfi->chips[chipnum].mutex);
-+
-+ schedule();
-+ remove_wait_queue(&cfi->chips[chipnum].wq, &wait);
-+#if 0
-+ if(signal_pending(current))
-+ return -EINTR;
-+#endif
-+ goto retry1;
-+ }
-+
-+ map_copy_from(map, tmp_buf, ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
-+
-+ cfi_spin_unlock(cfi->chips[chipnum].mutex);
-
-- map->copy_from(map, tmp_buf, ofs + cfi->chips[chipnum].start, CFIDEV_BUSWIDTH);
- while (len--)
- tmp_buf[i++] = buf[n++];
-
-@@ -696,8 +1181,14 @@
- datum = *(__u16*)tmp_buf;
- } else if (cfi_buswidth_is_4()) {
- datum = *(__u32*)tmp_buf;
-+#ifdef CFI_WORD_64
-+ } else if (cfi_buswidth_is_8()) {
-+ datum = *(__u64*)tmp_buf;
-+#endif
- } else {
-- return -EINVAL; /* should never happen, but be safe */
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
-+ return -EINVAL;
- }
-
- ret = do_write_oneword(map, &cfi->chips[chipnum],
-@@ -711,289 +1202,446 @@
- return 0;
- }
-
--static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
-+
-+/*
-+ * FIXME: interleaved mode not tested, and probably not supported!
-+ */
-+static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
-+ unsigned long adr, const u_char *buf, int len)
- {
-- unsigned int oldstatus, status;
-- unsigned int dq6, dq5;
-- unsigned long timeo = jiffies + HZ;
-- unsigned int adr;
- struct cfi_private *cfi = map->fldrv_priv;
-- DECLARE_WAITQUEUE(wait, current);
--
-- retry:
-- cfi_spin_lock(chip->mutex);
-+ unsigned long timeo = jiffies + HZ;
-+ cfi_word oldstatus, status, prev_oldstatus, prev_status;
-+ cfi_word dq6 = CMD(1<<6);
-+ /* see comments in do_write_oneword() regarding uWriteTimeo. */
-+ static unsigned long uWriteTimeout = ( HZ / 1000 ) + 1;
-+ int ret = -EIO;
-+ int ta = 0;
-+ unsigned long cmd_adr;
-+ int z, bytes, words;
-+ cfi_word datum;
-+ DECLARE_RETRY_CMD_CNT();
-
-- if (chip->state != FL_READY){
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-+ adr += chip->start;
-+ cmd_adr = adr;
-
-+ cfi_spin_lock(chip->mutex);
-+ ret = get_chip(map, chip, adr, FL_WRITING);
-+ if (ret) {
- cfi_spin_unlock(chip->mutex);
-+ return ret;
-+ }
-
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
--#if 0
-- if(signal_pending(current))
-- return -EINTR;
-+ if (cfi_buswidth_is_1()) {
-+ datum = *(__u8*)buf;
-+ } else if (cfi_buswidth_is_2()) {
-+ datum = *(__u16*)buf;
-+ } else if (cfi_buswidth_is_4()) {
-+ datum = *(__u32*)buf;
-+#ifdef CFI_WORD_64
-+ } else if (cfi_buswidth_is_8()) {
-+ datum = *(__u64*)buf;
- #endif
-- timeo = jiffies + HZ;
--
-- goto retry;
-+ } else {
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
-+ return -EINVAL;
- }
-
-- chip->state = FL_ERASING;
-+ RETRY_CMD_LABEL;
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE 0x%.8lx(0x%.8x)\n",
-+ __func__, adr, datum );
-
-- /* Handle devices with one erase region, that only implement
-- * the chip erase command.
-- */
- ENABLE_VPP(map);
- cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-- cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-- cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-- cfi_send_gen_cmd(0x10, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-- timeo = jiffies + (HZ*20);
-- adr = cfi->addr_unlock1;
-+ //cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-
-- /* Wait for the end of programing/erasure by using the toggle method.
-- * As long as there is a programming procedure going on, bit 6 of the last
-- * written byte is toggling it's state with each consectuve read.
-- * The toggling stops as soon as the procedure is completed.
-- *
-- * If the process has gone on for too long on the chip bit 5 gets.
-- * After bit5 is set you can kill the operation by sending a reset
-- * command to the chip.
-- */
-- dq6 = CMD(1<<6);
-- dq5 = CMD(1<<5);
-+ /* Write Buffer Load */
-+ cfi_write(map, CMD(0x25), cmd_adr);
-
-- oldstatus = cfi_read(map, adr);
-- status = cfi_read(map, adr);
-- while( ((status & dq6) != (oldstatus & dq6)) &&
-- ((status & dq5) != dq5) &&
-- !time_after(jiffies, timeo)) {
-- int wait_reps;
-+ chip->state = FL_WRITING_TO_BUFFER;
-+
-+ /* Write length of data to come */
-+ bytes = len & (CFIDEV_BUSWIDTH-1);
-+ words = len / CFIDEV_BUSWIDTH;
-+ cfi_write(map, CMD(words - !bytes), cmd_adr );
-+ /* Write data */
-+ z = 0;
-+ while(z < words * CFIDEV_BUSWIDTH) {
-+ if (cfi_buswidth_is_1()) {
-+ datum = *((__u8*)buf);
-+ map_write8 (map, *((__u8*)buf)++, adr+z);
-+ } else if (cfi_buswidth_is_2()) {
-+ datum = *((__u16*)buf);
-+ map_write16 (map, *((__u16*)buf)++, adr+z);
-+ } else if (cfi_buswidth_is_4()) {
-+ datum = *((__u32*)buf);
-+ map_write32 (map, *((__u32*)buf)++, adr+z);
-+#ifdef CFI_WORD_64
-+ } else if (cfi_buswidth_is_8()) {
-+ datum = *((__u64*)buf);
-+ map_write64 (map, *((__u64*)buf)++, adr+z);
-+#endif
-+ } else {
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
-+ ret = -EINVAL;
-+ goto op_failed;
-+ }
-+ z += CFIDEV_BUSWIDTH;
-+ }
-+ if (bytes) {
-+ int i = 0, n = 0;
-+ u_char tmp_buf[8], *tmp_p = tmp_buf;
-+
-+ while (bytes--)
-+ tmp_buf[i++] = buf[n++];
-+ while (i < CFIDEV_BUSWIDTH)
-+ tmp_buf[i++] = 0xff;
-+ if (cfi_buswidth_is_2()) {
-+ datum = *((__u16*)tmp_p);
-+ map_write16 (map, *((__u16*)tmp_p)++, adr+z);
-+ } else if (cfi_buswidth_is_4()) {
-+ datum = *((__u32*)tmp_p);
-+ map_write32 (map, *((__u32*)tmp_p)++, adr+z);
-+#ifdef CFI_WORD_64
-+ } else if (cfi_buswidth_is_8()) {
-+ datum = *((__u64*)tmp_p);
-+ map_write64 (map, *((__u64*)tmp_p)++, adr+z);
-+#endif
-+ } else {
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
-+ ret = -EINVAL;
-+ goto op_failed;
-+ }
-+ } else if (words > 0) {
-+ z -= CFIDEV_BUSWIDTH;
-+ }
-+
-+ adr += z;
-+
-+ /* Write Buffer Program Confirm: GO GO GO */
-+ cfi_write(map, CMD(0x29), cmd_adr);
-+ chip->state = FL_WRITING;
-
-- /* an initial short sleep */
- cfi_spin_unlock(chip->mutex);
-- schedule_timeout(HZ/100);
-+ cfi_udelay(chip->buffer_write_time);
- cfi_spin_lock(chip->mutex);
-
-- if (chip->state != FL_ERASING) {
-- /* Someone's suspended the erase. Sleep */
-+ timeo = jiffies + uWriteTimeout;
-+
-+ for (;;) {
-+ if (chip->state != FL_WRITING) {
-+ /* Someone's suspended the write. Sleep */
-+ DECLARE_WAITQUEUE(wait, current);
-+
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&chip->wq, &wait);
--
- cfi_spin_unlock(chip->mutex);
-- printk("erase suspended. Sleeping\n");
--
- schedule();
- remove_wait_queue(&chip->wq, &wait);
--#if 0
-- if (signal_pending(current))
-- return -EINTR;
--#endif
-- timeo = jiffies + (HZ*2); /* FIXME */
-+ timeo = jiffies + (HZ / 2); /* FIXME */
- cfi_spin_lock(chip->mutex);
- continue;
- }
-
-- /* Busy wait for 1/10 of a milisecond */
-- for(wait_reps = 0;
-- (wait_reps < 100) &&
-- ((status & dq6) != (oldstatus & dq6)) &&
-- ((status & dq5) != dq5);
-- wait_reps++) {
-+ oldstatus = cfi_read(map, adr);
-+ status = cfi_read(map, adr);
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n",
-+ __func__, oldstatus, status );
-+
-+ /* See comments in do_write_oneword() about checking status */
-+ if ( (((status ^ oldstatus) & dq6) == 0)
-+ || ( ta = time_after(jiffies, timeo)) ) {
-+ break;
-+ }
-
- /* Latency issues. Drop the lock, wait a while and retry */
- cfi_spin_unlock(chip->mutex);
--
- cfi_udelay(1);
--
- cfi_spin_lock(chip->mutex);
-- oldstatus = cfi_read(map, adr);
-- status = cfi_read(map, adr);
- }
-+
-+ /* See comments in do_write_oneword() about "two more checks" */
-+ prev_oldstatus = oldstatus;
-+ prev_status = status;
- oldstatus = cfi_read(map, adr);
- status = cfi_read(map, adr);
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n",
-+ __func__, oldstatus, status );
-+
-+ if ( oldstatus == datum && status == datum ) {
-+ /* success - do nothing */
-+ goto op_done;
-+ }
-+
-+ if ( ta ) {
-+ /* Only check dq5 on the chips that are still toggling. */
-+ cfi_word dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1;
-+ if ( status & dq5mask ) {
-+ /* dq5 asserted - decode interleave chips */
-+ printk( KERN_WARNING
-+ "MTD %s(): FLASH internal timeout: 0x%.8x 0x%.8x 0x%8x\n",
-+ __func__,
-+ status & dq5mask, status, datum );
-+ } else {
-+ printk( KERN_WARNING
-+ "MTD %s(): Software timed out during write.\n",
-+ __func__ );
- }
-- if ((status & dq6) != (oldstatus & dq6)) {
-- /* The erasing didn't stop?? */
-- if ((status & dq5) == dq5) {
-- /* dq5 is active so we can do a reset and stop the erase */
-- cfi_write(map, CMD(0xF0), chip->start);
-+ goto op_failed;
- }
-+
-+ HANDLE_WACKY_STATE();
-+
-+ op_failed:
-+ /* reset on all failures. */
-+ cfi_write( map, CMD(0xF0), chip->start );
-+ /* FIXME - should have reset delay before continuing */
-+ CHECK_RETRIES();
-+ ret = -EIO;
-+
-+ op_done:
- chip->state = FL_READY;
-- wake_up(&chip->wq);
-+ put_chip(map, chip, adr);
- cfi_spin_unlock(chip->mutex);
-- printk("waiting for erase to complete timed out.");
-- DISABLE_VPP(map);
-- return -EIO;
-+
-+ return ret;
-+}
-+
-+
-+static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf)
-+{
-+ struct map_info *map = mtd->priv;
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ int wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize;
-+ int ret = 0;
-+ int chipnum;
-+ unsigned long ofs;
-+
-+ *retlen = 0;
-+ if (!len)
-+ return 0;
-+
-+ chipnum = to >> cfi->chipshift;
-+ ofs = to - (chipnum << cfi->chipshift);
-+
-+ /* If it's not bus-aligned, do the first word write */
-+ if (ofs & (CFIDEV_BUSWIDTH-1)) {
-+ size_t local_len = (-ofs)&(CFIDEV_BUSWIDTH-1);
-+ if (local_len > len)
-+ local_len = len;
-+ ret = cfi_amdstd_write_words(mtd, to, local_len,
-+ retlen, buf);
-+ if (ret)
-+ return ret;
-+ ofs += local_len;
-+ buf += local_len;
-+ len -= local_len;
-+
-+ if (ofs >> cfi->chipshift) {
-+ chipnum ++;
-+ ofs = 0;
-+ if (chipnum == cfi->numchips)
-+ return 0;
-+ }
-+ }
-+
-+ /* Write buffer is worth it only if more than one word to write... */
-+ while (len) {
-+ /* We must not cross write block boundaries */
-+ int size = wbufsize - (ofs & (wbufsize-1));
-+
-+ if (size > len)
-+ size = len;
-+ ret = do_write_buffer(map, &cfi->chips[chipnum],
-+ ofs, buf, size);
-+ if (ret)
-+ return ret;
-+
-+ ofs += size;
-+ buf += size;
-+ (*retlen) += size;
-+ len -= size;
-+
-+ if (ofs >> cfi->chipshift) {
-+ chipnum ++;
-+ ofs = 0;
-+ if (chipnum == cfi->numchips)
-+ return 0;
-+ }
- }
-- DISABLE_VPP(map);
-- chip->state = FL_READY;
-- wake_up(&chip->wq);
-- cfi_spin_unlock(chip->mutex);
-
- return 0;
- }
-
--static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr)
-+
-+/*
-+ * Handle devices with one erase region, that only implement
-+ * the chip erase command.
-+ */
-+static inline int do_erase_chip(struct map_info *map, struct flchip *chip)
- {
-- unsigned int oldstatus, status;
-- unsigned int dq6, dq5;
-- unsigned long timeo = jiffies + HZ;
- struct cfi_private *cfi = map->fldrv_priv;
-+ cfi_word oldstatus, status, prev_oldstatus, prev_status;
-+ cfi_word dq6 = CMD(1<<6);
-+ unsigned long timeo = jiffies + HZ;
-+ unsigned long int adr;
- DECLARE_WAITQUEUE(wait, current);
-+ int ret = 0;
-+ int ta = 0;
-+ cfi_word datum = 0;
-+ DECLARE_RETRY_CMD_CNT();
-
-- retry:
-- cfi_spin_lock(chip->mutex);
--
-- if (chip->state != FL_READY){
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- add_wait_queue(&chip->wq, &wait);
-+ adr = cfi->addr_unlock1;
-
-+ cfi_spin_lock(chip->mutex);
-+ ret = get_chip(map, chip, adr, FL_WRITING);
-+ if (ret) {
- cfi_spin_unlock(chip->mutex);
--
-- schedule();
-- remove_wait_queue(&chip->wq, &wait);
--#if 0
-- if(signal_pending(current))
-- return -EINTR;
--#endif
-- timeo = jiffies + HZ;
--
-- goto retry;
-+ return ret;
- }
-
-- chip->state = FL_ERASING;
-+ RETRY_CMD_LABEL;
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
-+ __func__, chip->start );
-
-- adr += chip->start;
- ENABLE_VPP(map);
- cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-- cfi_write(map, CMD(0x30), adr);
--
-- timeo = jiffies + (HZ*20);
--
-- /* Wait for the end of programing/erasure by using the toggle method.
-- * As long as there is a programming procedure going on, bit 6 of the last
-- * written byte is toggling it's state with each consectuve read.
-- * The toggling stops as soon as the procedure is completed.
-- *
-- * If the process has gone on for too long on the chip bit 5 gets.
-- * After bit5 is set you can kill the operation by sending a reset
-- * command to the chip.
-- */
-- dq6 = CMD(1<<6);
-- dq5 = CMD(1<<5);
-+ cfi_send_gen_cmd(0x10, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-
-- oldstatus = cfi_read(map, adr);
-- status = cfi_read(map, adr);
-- while( ((status & dq6) != (oldstatus & dq6)) &&
-- ((status & dq5) != dq5) &&
-- !time_after(jiffies, timeo)) {
-- int wait_reps;
-+ chip->state = FL_ERASING;
-+ chip->erase_suspended = 0;
-+ chip->in_progress_block_addr = adr;
-
-- /* an initial short sleep */
- cfi_spin_unlock(chip->mutex);
-- schedule_timeout(HZ/100);
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ schedule_timeout((chip->erase_time*HZ)/(2*1000));
- cfi_spin_lock(chip->mutex);
-
-+ timeo = jiffies + (HZ*20);
-+
-+ for (;;) {
- if (chip->state != FL_ERASING) {
- /* Someone's suspended the erase. Sleep */
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&chip->wq, &wait);
--
- cfi_spin_unlock(chip->mutex);
-- printk(KERN_DEBUG "erase suspended. Sleeping\n");
--
- schedule();
- remove_wait_queue(&chip->wq, &wait);
--#if 0
-- if (signal_pending(current))
-- return -EINTR;
--#endif
-- timeo = jiffies + (HZ*2); /* FIXME */
- cfi_spin_lock(chip->mutex);
- continue;
- }
-+ if (chip->erase_suspended) {
-+ /* This erase was suspended and resumed.
-+ Adjust the timeout */
-+ timeo = jiffies + (HZ*20); /* FIXME */
-+ chip->erase_suspended = 0;
-+ }
-
-- /* Busy wait for 1/10 of a milisecond */
-- for(wait_reps = 0;
-- (wait_reps < 100) &&
-- ((status & dq6) != (oldstatus & dq6)) &&
-- ((status & dq5) != dq5);
-- wait_reps++) {
-+ oldstatus = cfi_read(map, adr);
-+ status = cfi_read(map, adr);
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n",
-+ __func__, oldstatus, status );
-+ if ( (((status ^ oldstatus) & dq6) == 0)
-+ || ( ta = time_after(jiffies, timeo)) )
-+ break;
-
- /* Latency issues. Drop the lock, wait a while and retry */
- cfi_spin_unlock(chip->mutex);
--
-- cfi_udelay(1);
--
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ schedule_timeout(1);
- cfi_spin_lock(chip->mutex);
-- oldstatus = cfi_read(map, adr);
-- status = cfi_read(map, adr);
- }
-+
-+ prev_oldstatus = oldstatus;
-+ prev_status = status;
- oldstatus = cfi_read(map, adr);
- status = cfi_read(map, adr);
-- }
-- if( (status & dq6) != (oldstatus & dq6) )
-- {
-- /* The erasing didn't stop?? */
-- if( ( status & dq5 ) == dq5 )
-- {
-- /* When DQ5 raises, we must check once again if DQ6 is toggling.
-- If not, the erase has been completed OK. If not, reset chip. */
-- oldstatus = cfi_read( map, adr );
-- status = cfi_read( map, adr );
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n",
-+ __func__, oldstatus, status );
-
-- if( ( oldstatus & 0x00FF ) == ( status & 0x00FF ) )
-- {
-- printk( "Warning: DQ5 raised while erase operation was in progress, but erase completed OK\n" );
-- }
-- else
-- {
-- /* DQ5 is active so we can do a reset and stop the erase */
-- cfi_write(map, CMD(0xF0), chip->start);
-- printk( KERN_WARNING "Internal flash device timeout occured or write operation was performed while flash was erasing\n" );
-+ if ( cfi_buswidth_is_1() ) {
-+ datum = (__u8)~0;
-+ } else if ( cfi_buswidth_is_2() ) {
-+ datum = (__u16)~0;
-+ } else if ( cfi_buswidth_is_4() ) {
-+ datum = (__u32)~0;
-+#ifdef CFI_WORD_64
-+ } else if ( cfi_buswidth_is_8() ) {
-+ datum = (__u64)~0;
-+#endif
-+ } else {
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
-+ goto op_failed;
-+ }
-+
-+ if ( oldstatus == datum && status == datum ) {
-+ /* success - do nothing */
-+ goto op_done;
-+ }
-+
-+ if ( ta ) {
-+ /* Only check dq5 on the chips that are still toggling. */
-+ cfi_word dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1;
-+ if ( status & dq5mask ) {
-+ /* dq5 asserted - decode interleave chips */
-+ printk( KERN_WARNING
-+ "MTD %s(): FLASH internal timeout: 0x%.8x\n",
-+ __func__,
-+ status & dq5mask );
-+ } else {
-+ printk( KERN_WARNING
-+ "MTD %s(): Software timed out during write.\n",
-+ __func__ );
- }
-+ goto op_failed;
- }
-- else
-- {
-- printk( "Waiting for erase to complete timed out in do_erase_oneblock.");
-
-- chip->state = FL_READY;
-- wake_up(&chip->wq);
-- cfi_spin_unlock(chip->mutex);
-- DISABLE_VPP(map);
-- return -EIO;
-- }
-- }
-+ HANDLE_WACKY_STATE();
-
-- DISABLE_VPP(map);
-+ op_failed:
-+ /* reset on all failures. */
-+ cfi_write( map, CMD(0xF0), chip->start );
-+ /* FIXME - should have reset delay before continuing */
-+ CHECK_RETRIES();
-+ ret = -EIO;
-+
-+ op_done:
- chip->state = FL_READY;
-- wake_up(&chip->wq);
-+ put_chip(map, chip, adr);
- cfi_spin_unlock(chip->mutex);
-- return 0;
-+
-+ return ret;
- }
-
--static int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
-+
-+typedef int (*frob_t)(struct map_info *map, struct flchip *chip,
-+ unsigned long adr, void *thunk);
-+
-+
-+static int cfi_amdstd_varsize_frob(struct mtd_info *mtd, frob_t frob,
-+ loff_t ofs, size_t len, void *thunk)
- {
- struct map_info *map = mtd->priv;
- struct cfi_private *cfi = map->fldrv_priv;
-- unsigned long adr, len;
-+ unsigned long adr;
- int chipnum, ret = 0;
- int i, first;
- struct mtd_erase_region_info *regions = mtd->eraseregions;
-
-- if (instr->addr > mtd->size)
-+ if (ofs > mtd->size)
- return -EINVAL;
-
-- if ((instr->len + instr->addr) > mtd->size)
-+ if ((len + ofs) > mtd->size)
- return -EINVAL;
-
- /* Check that both start and end of the requested erase are
-@@ -1008,7 +1656,7 @@
- start of the requested erase, and then go back one.
- */
-
-- while (i < mtd->numeraseregions && instr->addr >= regions[i].offset)
-+ while (i < mtd->numeraseregions && ofs >= regions[i].offset)
- i++;
- i--;
-
-@@ -1018,7 +1666,7 @@
- effect here.
- */
-
-- if (instr->addr & (regions[i].erasesize-1))
-+ if (ofs & (regions[i].erasesize-1))
- return -EINVAL;
-
- /* Remember the erase region we start on */
-@@ -1028,7 +1676,7 @@
- * with the erase region at that address.
- */
-
-- while (i<mtd->numeraseregions && (instr->addr + instr->len) >= regions[i].offset)
-+ while (i<mtd->numeraseregions && (ofs + len) >= regions[i].offset)
- i++;
-
- /* As before, drop back one to point at the region in which
-@@ -1036,17 +1684,16 @@
- */
- i--;
-
-- if ((instr->addr + instr->len) & (regions[i].erasesize-1))
-+ if ((ofs + len) & (regions[i].erasesize-1))
- return -EINVAL;
-
-- chipnum = instr->addr >> cfi->chipshift;
-- adr = instr->addr - (chipnum << cfi->chipshift);
-- len = instr->len;
-+ chipnum = ofs >> cfi->chipshift;
-+ adr = ofs - (chipnum << cfi->chipshift);
-
- i=first;
-
-- while(len) {
-- ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
-+ while (len) {
-+ ret = (*frob)(map, &cfi->chips[chipnum], adr, thunk);
-
- if (ret)
- return ret;
-@@ -1066,50 +1713,171 @@
- }
- }
-
-- instr->state = MTD_ERASE_DONE;
-- if (instr->callback)
-- instr->callback(instr);
--
- return 0;
- }
-
--static int cfi_amdstd_erase_onesize(struct mtd_info *mtd, struct erase_info *instr)
-+
-+static inline int do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, void *thunk)
- {
-- struct map_info *map = mtd->priv;
- struct cfi_private *cfi = map->fldrv_priv;
-- unsigned long adr, len;
-- int chipnum, ret = 0;
-+ cfi_word oldstatus, status, prev_oldstatus, prev_status;
-+ cfi_word dq6 = CMD(1<<6);
-+ unsigned long timeo = jiffies + HZ;
-+ DECLARE_WAITQUEUE(wait, current);
-+ int ret = 0;
-+ int ta = 0;
-+ cfi_word datum = 0;
-+ DECLARE_RETRY_CMD_CNT();
-
-- if (instr->addr & (mtd->erasesize - 1))
-- return -EINVAL;
-+ adr += chip->start;
-
-- if (instr->len & (mtd->erasesize -1))
-- return -EINVAL;
-+ cfi_spin_lock(chip->mutex);
-+ ret = get_chip(map, chip, adr, FL_ERASING);
-+ if (ret) {
-+ cfi_spin_unlock(chip->mutex);
-+ return ret;
-+ }
-
-- if ((instr->len + instr->addr) > mtd->size)
-- return -EINVAL;
-+ RETRY_CMD_LABEL;
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n",
-+ __func__, adr );
-
-- chipnum = instr->addr >> cfi->chipshift;
-- adr = instr->addr - (chipnum << cfi->chipshift);
-- len = instr->len;
-+ ENABLE_VPP(map);
-+ cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-+ cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-+ cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-+ cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-+ cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVICETYPE_X8, NULL);
-+ cfi_write(map, CMD(0x30), adr);
-
-- while(len) {
-- ret = do_erase_oneblock(map, &cfi->chips[chipnum], adr);
-+ chip->state = FL_ERASING;
-+ chip->erase_suspended = 0;
-+ chip->in_progress_block_addr = adr;
-
-- if (ret)
-- return ret;
-+ cfi_spin_unlock(chip->mutex);
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ schedule_timeout((chip->erase_time*HZ)/(2*1000));
-+ cfi_spin_lock(chip->mutex);
-
-- adr += mtd->erasesize;
-- len -= mtd->erasesize;
-+ timeo = jiffies + (HZ*20);
-
-- if (adr >> cfi->chipshift) {
-- adr = 0;
-- chipnum++;
-+ /* Wait for the end of programing/erasure by using the toggle method.
-+ * As long as there is a programming procedure going on, bit 6 is
-+ * toggling its state with each consecutive read. The toggling stops
-+ * as soon as the procedure is completed.
-+ *
-+ * If the process has gone on for too long on the chip, bit 5 gets
-+ * set. After bit5 is set you can kill the operation by sending a
-+ * reset command to the chip.
-+ */
-+ /* See comments in do_write_oneword(). */
-
-- if (chipnum >= cfi->numchips)
-+ for (;;) {
-+ if (chip->state != FL_ERASING) {
-+ /* Someone's suspended the erase. Sleep */
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ add_wait_queue(&chip->wq, &wait);
-+ cfi_spin_unlock(chip->mutex);
-+ schedule();
-+ remove_wait_queue(&chip->wq, &wait);
-+ cfi_spin_lock(chip->mutex);
-+ continue;
-+ }
-+ if (chip->erase_suspended) {
-+ /* This erase was suspended and resumed.
-+ Adjust the timeout */
-+ timeo = jiffies + (HZ*20); /* FIXME */
-+ chip->erase_suspended = 0;
-+ }
-+
-+ oldstatus = cfi_read(map, adr);
-+ status = cfi_read(map, adr);
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n",
-+ __func__, oldstatus, status );
-+ if ( (((status ^ oldstatus) & dq6) == 0)
-+ || ( ta = time_after(jiffies, timeo)) )
- break;
-+
-+ /* Latency issues. Drop the lock, wait a while and retry */
-+ cfi_spin_unlock(chip->mutex);
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ schedule_timeout(1);
-+ cfi_spin_lock(chip->mutex);
- }
-+
-+ prev_oldstatus = oldstatus;
-+ prev_status = status;
-+ oldstatus = cfi_read(map, adr);
-+ status = cfi_read(map, adr);
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.8x 0x%.8x\n",
-+ __func__, oldstatus, status );
-+
-+ if ( cfi_buswidth_is_1() ) {
-+ datum = (__u8)~0;
-+ } else if ( cfi_buswidth_is_2() ) {
-+ datum = (__u16)~0;
-+ } else if ( cfi_buswidth_is_4() ) {
-+ datum = (__u32)~0;
-+#ifdef CFI_WORD_64
-+ } else if ( cfi_buswidth_is_8() ) {
-+ datum = (__u64)~0;
-+#endif
-+ } else {
-+ printk(KERN_WARNING "MTD %s(): Unsupported buswidth %d\n",
-+ __func__, CFIDEV_BUSWIDTH);
-+ goto op_failed;
-+ }
-+
-+ if ( oldstatus == datum && status == datum ) {
-+ /* success - do nothing */
-+ goto op_done;
-+ }
-+
-+ if ( ta ) {
-+ /* Only check dq5 on the chips that are still toggling. */
-+ cfi_word dq5mask = ( ( status ^ oldstatus ) & dq6 ) >> 1;
-+ if ( status & dq5mask ) {
-+ /* dq5 asserted - decode interleave chips */
-+ printk( KERN_WARNING
-+ "MTD %s(): FLASH internal timeout: 0x%.8x\n",
-+ __func__,
-+ status & dq5mask );
-+ } else {
-+ printk( KERN_WARNING
-+ "MTD %s(): Software timed out during write.\n",
-+ __func__ );
- }
-+ goto op_failed;
-+ }
-+
-+ HANDLE_WACKY_STATE();
-+
-+ op_failed:
-+ /* reset on all failures. */
-+ cfi_write( map, CMD(0xF0), chip->start );
-+ /* FIXME - should have reset delay before continuing */
-+ CHECK_RETRIES();
-+ ret = -EIO;
-+
-+ op_done:
-+ chip->state = FL_READY;
-+ put_chip(map, chip, adr);
-+ cfi_spin_unlock(chip->mutex);
-+ return ret;
-+}
-+
-+
-+int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *instr)
-+{
-+ unsigned long ofs, len;
-+ int ret;
-+
-+ ofs = instr->addr;
-+ len = instr->len;
-+
-+ ret = cfi_amdstd_varsize_frob(mtd, do_erase_oneblock, ofs, len, 0);
-+ if (ret)
-+ return ret;
-
- instr->state = MTD_ERASE_DONE;
- if (instr->callback)
-@@ -1118,6 +1886,7 @@
- return 0;
- }
-
-+
- static int cfi_amdstd_erase_chip(struct mtd_info *mtd, struct erase_info *instr)
- {
- struct map_info *map = mtd->priv;
-@@ -1141,6 +1910,7 @@
- return 0;
- }
-
-+
- static void cfi_amdstd_sync (struct mtd_info *mtd)
- {
- struct map_info *map = mtd->priv;
-@@ -1254,6 +2024,7 @@
- return ret;
- }
-
-+
- static void cfi_amdstd_resume(struct mtd_info *mtd)
- {
- struct map_info *map = mtd->priv;
-@@ -1279,6 +2050,137 @@
- }
- }
-
-+
-+#ifdef DEBUG_LOCK_BITS
-+
-+static int do_printlockstatus_oneblock(struct map_info *map,
-+ struct flchip *chip,
-+ unsigned long adr,
-+ void *thunk)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ int ofs_factor = cfi->interleave * cfi->device_type;
-+
-+ cfi_send_gen_cmd(0x90, 0x55, 0, map, cfi, cfi->device_type, NULL);
-+ printk(KERN_DEBUG "block status register for 0x%08lx is %x\n",
-+ adr, cfi_read_query(map, adr+(2*ofs_factor)));
-+ cfi_send_gen_cmd(0xff, 0x55, 0, map, cfi, cfi->device_type, NULL);
-+
-+ return 0;
-+}
-+
-+
-+#define debug_dump_locks(mtd, frob, ofs, len, thunk) \
-+ cfi_amdstd_varsize_frob((mtd), (frob), (ofs), (len), (thunk))
-+
-+#else
-+
-+#define debug_dump_locks(...)
-+
-+#endif /* DEBUG_LOCK_BITS */
-+
-+
-+struct xxlock_thunk {
-+ cfi_word val;
-+ flstate_t state;
-+};
-+
-+
-+#define DO_XXLOCK_ONEBLOCK_LOCK ((struct xxlock_thunk){0x01, FL_LOCKING})
-+#define DO_XXLOCK_ONEBLOCK_UNLOCK ((struct xxlock_thunk){0x00, FL_UNLOCKING})
-+
-+
-+/*
-+ * FIXME - this is *very* specific to a particular chip. It likely won't
-+ * work for all chips that require unlock. It also hasn't been tested
-+ * with interleaved chips.
-+ */
-+static int do_xxlock_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, void *thunk)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ struct xxlock_thunk *xxlt = (struct xxlock_thunk *)thunk;
-+ int ret;
-+
-+ /*
-+ * This is easy because these are writes to registers and not writes
-+ * to flash memory - that means that we don't have to check status
-+ * and timeout.
-+ */
-+
-+ adr += chip->start;
-+ /*
-+ * lock block registers:
-+ * - on 64k boundariesand
-+ * - bit 1 set high
-+ * - block lock registers are 4MiB lower - overflow subtract (danger)
-+ */
-+ adr = ((adr & ~0xffff) | 0x2) + ~0x3fffff;
-+
-+ cfi_spin_lock(chip->mutex);
-+ ret = get_chip(map, chip, adr, FL_LOCKING);
-+ if (ret) {
-+ cfi_spin_unlock(chip->mutex);
-+ return ret;
-+ }
-+
-+ chip->state = xxlt->state;
-+ cfi_write(map, CMD(xxlt->val), adr);
-+
-+ /* Done and happy. */
-+ chip->state = FL_READY;
-+ put_chip(map, chip, adr);
-+ cfi_spin_unlock(chip->mutex);
-+ return 0;
-+}
-+
-+
-+static int cfi_amdstd_lock_varsize(struct mtd_info *mtd,
-+ loff_t ofs,
-+ size_t len)
-+{
-+ int ret;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3,
-+ "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
-+ __func__, ofs, len);
-+ debug_dump_locks(mtd, do_printlockstatus_oneblock, ofs, len, 0);
-+
-+ ret = cfi_amdstd_varsize_frob(mtd, do_xxlock_oneblock, ofs, len,
-+ (void *)&DO_XXLOCK_ONEBLOCK_LOCK);
-+
-+ DEBUG(MTD_DEBUG_LEVEL3,
-+ "%s: lock status after, ret=%d\n",
-+ __func__, ret);
-+
-+ debug_dump_locks(mtd, do_printlockstatus_oneblock, ofs, len, 0);
-+
-+ return ret;
-+}
-+
-+
-+static int cfi_amdstd_unlock_varsize(struct mtd_info *mtd,
-+ loff_t ofs,
-+ size_t len)
-+{
-+ int ret;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3,
-+ "%s: lock status before, ofs=0x%08llx, len=0x%08X\n",
-+ __func__, ofs, len);
-+ debug_dump_locks(mtd, do_printlockstatus_oneblock, ofs, len, 0);
-+
-+ ret = cfi_amdstd_varsize_frob(mtd, do_xxlock_oneblock, ofs, len,
-+ (void *)&DO_XXLOCK_ONEBLOCK_UNLOCK);
-+
-+ DEBUG(MTD_DEBUG_LEVEL3,
-+ "%s: lock status after, ret=%d\n",
-+ __func__, ret);
-+ debug_dump_locks(mtd, do_printlockstatus_oneblock, ofs, len, 0);
-+
-+ return ret;
-+}
-+
-+
- static void cfi_amdstd_destroy(struct mtd_info *mtd)
- {
- struct map_info *map = mtd->priv;
-@@ -1291,17 +2193,20 @@
-
- static char im_name[]="cfi_cmdset_0002";
-
-+
- int __init cfi_amdstd_init(void)
- {
- inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0002);
- return 0;
- }
-
-+
- static void __exit cfi_amdstd_exit(void)
- {
- inter_module_unregister(im_name);
- }
-
-+
- module_init(cfi_amdstd_init);
- module_exit(cfi_amdstd_exit);
-
-@@ -1309,3 +2214,7 @@
- MODULE_AUTHOR("Crossnet Co. <info@crossnet.co.jp> et al.");
- MODULE_DESCRIPTION("MTD chip driver for AMD/Fujitsu flash chips");
-
-+#ifdef CONFIG_MTD_CFI_AMDSTD_RETRY
-+MODULE_PARM(retry_cmd_max, "i");
-+MODULE_PARM_DESC(retry_cmd_max, "Number of times to retry an erase or program command if it fails - should only be needed by buggy hardware: default 0");
-+#endif
-diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/cfi_cmdset_0020.c linux/drivers/mtd/chips/cfi_cmdset_0020.c
---- linux-mips-2.4.27/drivers/mtd/chips/cfi_cmdset_0020.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/chips/cfi_cmdset_0020.c 2004-11-19 10:25:11.747222896 +0100
-@@ -21,16 +21,19 @@
- #include <linux/types.h>
- #include <linux/kernel.h>
- #include <linux/sched.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <asm/byteorder.h>
-
- #include <linux/errno.h>
-+#include <linux/init.h>
- #include <linux/slab.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
-+#include <linux/mtd/compatmac.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/cfi.h>
--#include <linux/mtd/compatmac.h>
-+#include <linux/mtd/mtd.h>
-
-
- static int cfi_staa_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
-@@ -51,10 +54,10 @@
- static struct mtd_info *cfi_staa_setup (struct map_info *);
-
- static struct mtd_chip_driver cfi_staa_chipdrv = {
-- probe: NULL, /* Not usable directly */
-- destroy: cfi_staa_destroy,
-- name: "cfi_cmdset_0020",
-- module: THIS_MODULE
-+ .probe = NULL, /* Not usable directly */
-+ .destroy = cfi_staa_destroy,
-+ .name = "cfi_cmdset_0020",
-+ .module = THIS_MODULE
- };
-
- /* #define DEBUG_LOCK_BITS */
-@@ -113,7 +116,6 @@
- {
- struct cfi_private *cfi = map->fldrv_priv;
- int i;
-- __u32 base = cfi->chips[0].start;
-
- if (cfi->cfi_mode) {
- /*
-@@ -123,35 +125,10 @@
- */
- __u16 adr = primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR;
- struct cfi_pri_intelext *extp;
-- int ofs_factor = cfi->interleave * cfi->device_type;
--
-- printk(" ST Microelectronics Extended Query Table at 0x%4.4X\n", adr);
-- if (!adr)
-- return NULL;
--
-- /* Switch it into Query Mode */
-- cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
--
-- extp = kmalloc(sizeof(*extp), GFP_KERNEL);
-- if (!extp) {
-- printk(KERN_ERR "Failed to allocate memory\n");
-- return NULL;
-- }
--
-- /* Read in the Extended Query Table */
-- for (i=0; i<sizeof(*extp); i++) {
-- ((unsigned char *)extp)[i] =
-- cfi_read_query(map, (base+((adr+i)*ofs_factor)));
-- }
-
-- if (extp->MajorVersion != '1' ||
-- (extp->MinorVersion < '0' || extp->MinorVersion > '2')) {
-- printk(KERN_WARNING " Unknown staa Extended Query "
-- "version %c.%c.\n", extp->MajorVersion,
-- extp->MinorVersion);
-- kfree(extp);
-+ extp = (struct cfi_pri_intelext*)cfi_read_pri(map, adr, sizeof(*extp), "ST Microelectronics");
-+ if (!extp)
- return NULL;
-- }
-
- /* Do some byteswapping if necessary */
- extp->FeatureSupport = cfi32_to_cpu(extp->FeatureSupport);
-@@ -172,11 +149,6 @@
- cfi->chips[i].erase_time = 1024;
- }
-
-- map->fldrv = &cfi_staa_chipdrv;
-- MOD_INC_USE_COUNT;
--
-- /* Make sure it's in read mode */
-- cfi_send_gen_cmd(0xff, 0x55, base, map, cfi, cfi->device_type, NULL);
- return cfi_staa_setup(map);
- }
-
-@@ -208,6 +180,7 @@
- if (!mtd->eraseregions) {
- printk(KERN_ERR "Failed to allocate memory for MTD erase region info\n");
- kfree(cfi->cmdset_priv);
-+ kfree(mtd);
- return NULL;
- }
-
-@@ -232,6 +205,7 @@
- printk(KERN_WARNING "Sum of regions (%lx) != total size of set of interleaved chips (%lx)\n", offset, devsize);
- kfree(mtd->eraseregions);
- kfree(cfi->cmdset_priv);
-+ kfree(mtd);
- return NULL;
- }
-
-@@ -256,7 +230,7 @@
- mtd->flags |= MTD_ECC; /* FIXME: Not all STMicro flashes have this */
- mtd->eccsize = 8; /* FIXME: Should be 0 for STMicro flashes w/out ECC */
- map->fldrv = &cfi_staa_chipdrv;
-- MOD_INC_USE_COUNT;
-+ __module_get(THIS_MODULE);
- mtd->name = map->name;
- return mtd;
- }
-@@ -288,7 +262,7 @@
- */
- switch (chip->state) {
- case FL_ERASING:
-- if (!((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2)
-+ if (!(((struct cfi_pri_intelext *)cfi->cmdset_priv)->FeatureSupport & 2))
- goto sleep; /* We don't support erase suspend */
-
- cfi_write (map, CMD(0xb0), cmd_addr);
-@@ -374,7 +348,7 @@
- goto retry;
- }
-
-- map->copy_from(map, buf, adr, len);
-+ map_copy_from(map, buf, adr, len);
-
- if (suspended) {
- chip->state = chip->oldstate;
-@@ -540,11 +514,11 @@
- /* Write data */
- for (z = 0; z < len; z += CFIDEV_BUSWIDTH) {
- if (cfi_buswidth_is_1()) {
-- map->write8 (map, *((__u8*)buf)++, adr+z);
-+ map_write8 (map, *((__u8*)buf)++, adr+z);
- } else if (cfi_buswidth_is_2()) {
-- map->write16 (map, *((__u16*)buf)++, adr+z);
-+ map_write16 (map, *((__u16*)buf)++, adr+z);
- } else if (cfi_buswidth_is_4()) {
-- map->write32 (map, *((__u32*)buf)++, adr+z);
-+ map_write32 (map, *((__u32*)buf)++, adr+z);
- } else {
- DISABLE_VPP(map);
- return -EINVAL;
-@@ -1436,13 +1410,13 @@
-
- static char im_name[]="cfi_cmdset_0020";
-
--mod_init_t cfi_staa_init(void)
-+int __init cfi_staa_init(void)
- {
- inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0020);
- return 0;
- }
-
--mod_exit_t cfi_staa_exit(void)
-+static void __exit cfi_staa_exit(void)
- {
- inter_module_unregister(im_name);
- }
-diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/cfi_probe.c linux/drivers/mtd/chips/cfi_probe.c
---- linux-mips-2.4.27/drivers/mtd/chips/cfi_probe.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/chips/cfi_probe.c 2004-11-19 10:25:11.766220008 +0100
-@@ -1,13 +1,14 @@
- /*
- Common Flash Interface probe code.
- (C) 2000 Red Hat. GPL'd.
-- $Id$
-+ $Id$
- */
-
- #include <linux/config.h>
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <asm/byteorder.h>
- #include <linux/errno.h>
-@@ -25,7 +26,7 @@
- #endif
-
- static int cfi_probe_chip(struct map_info *map, __u32 base,
-- struct flchip *chips, struct cfi_private *cfi);
-+ unsigned long *chip_map, struct cfi_private *cfi);
- static int cfi_chip_setup(struct map_info *map, struct cfi_private *cfi);
-
- struct mtd_info *cfi_probe(struct map_info *map);
-@@ -48,7 +49,7 @@
- }
-
- static int cfi_probe_chip(struct map_info *map, __u32 base,
-- struct flchip *chips, struct cfi_private *cfi)
-+ unsigned long *chip_map, struct cfi_private *cfi)
- {
- int i;
-
-@@ -77,18 +78,24 @@
- }
-
- /* Check each previous chip to see if it's an alias */
-- for (i=0; i<cfi->numchips; i++) {
-+ for (i=0; i < (base >> cfi->chipshift); i++) {
-+ unsigned long start;
-+ if(!test_bit(i, chip_map)) {
-+ /* Skip location; no valid chip at this address */
-+ continue;
-+ }
-+ start = i << cfi->chipshift;
- /* This chip should be in read mode if it's one
- we've already touched. */
-- if (qry_present(map,chips[i].start,cfi)) {
-+ if (qry_present(map, start, cfi)) {
- /* Eep. This chip also had the QRY marker.
- * Is it an alias for the new one? */
-- cfi_send_gen_cmd(0xF0, 0, chips[i].start, map, cfi, cfi->device_type, NULL);
-+ cfi_send_gen_cmd(0xF0, 0, start, map, cfi, cfi->device_type, NULL);
-
- /* If the QRY marker goes away, it's an alias */
-- if (!qry_present(map, chips[i].start, cfi)) {
-+ if (!qry_present(map, start, cfi)) {
- printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
-- map->name, base, chips[i].start);
-+ map->name, base, start);
- return 0;
- }
- /* Yes, it's actually got QRY for data. Most
-@@ -99,7 +106,7 @@
-
- if (qry_present(map, base, cfi)) {
- printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
-- map->name, base, chips[i].start);
-+ map->name, base, start);
- return 0;
- }
- }
-@@ -107,13 +114,7 @@
-
- /* OK, if we got to here, then none of the previous chips appear to
- be aliases for the current one. */
-- if (cfi->numchips == MAX_CFI_CHIPS) {
-- printk(KERN_WARNING"%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n", map->name, MAX_CFI_CHIPS);
-- /* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */
-- return -1;
-- }
-- chips[cfi->numchips].start = base;
-- chips[cfi->numchips].state = FL_READY;
-+ set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
- cfi->numchips++;
-
- /* Put it back into Read Mode */
-@@ -179,9 +180,28 @@
- (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1);
- #endif
- }
-+
-+ /* Note we put the device back into Read Mode BEFORE going into Auto
-+ * Select Mode, as some devices support nesting of modes, others
-+ * don't. This way should always work.
-+ * On cmdset 0001 the writes of 0xaa and 0x55 are not needed, and
-+ * so should be treated as nops or illegal (and so put the device
-+ * back into Read Mode, which is a nop in this case).
-+ */
-+ cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL);
-+ cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL);
-+ cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL);
-+ cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL);
-+ cfi->mfr = cfi_read_query(map, base);
-+ cfi->id = cfi_read_query(map, base + ofs_factor);
-+
- /* Put it back into Read Mode */
- cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
-
-+ printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit mode\n",
-+ map->name, cfi->interleave, cfi->device_type*8, base,
-+ map->buswidth*8);
-+
- return 1;
- }
-
-@@ -240,11 +260,11 @@
- printk("No Alternate Algorithm Table\n");
-
-
-- printk("Vcc Minimum: %x.%x V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf);
-- printk("Vcc Maximum: %x.%x V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf);
-+ printk("Vcc Minimum: %2d.%d V\n", cfip->VccMin >> 4, cfip->VccMin & 0xf);
-+ printk("Vcc Maximum: %2d.%d V\n", cfip->VccMax >> 4, cfip->VccMax & 0xf);
- if (cfip->VppMin) {
-- printk("Vpp Minimum: %x.%x V\n", cfip->VppMin >> 4, cfip->VppMin & 0xf);
-- printk("Vpp Maximum: %x.%x V\n", cfip->VppMax >> 4, cfip->VppMax & 0xf);
-+ printk("Vpp Minimum: %2d.%d V\n", cfip->VppMin >> 4, cfip->VppMin & 0xf);
-+ printk("Vpp Maximum: %2d.%d V\n", cfip->VppMax >> 4, cfip->VppMax & 0xf);
- }
- else
- printk("No Vpp line\n");
-@@ -303,8 +323,8 @@
- #endif /* DEBUG_CFI */
-
- static struct chip_probe cfi_chip_probe = {
-- name: "CFI",
-- probe_chip: cfi_probe_chip
-+ .name = "CFI",
-+ .probe_chip = cfi_probe_chip
- };
-
- struct mtd_info *cfi_probe(struct map_info *map)
-@@ -317,9 +337,9 @@
- }
-
- static struct mtd_chip_driver cfi_chipdrv = {
-- probe: cfi_probe,
-- name: "cfi_probe",
-- module: THIS_MODULE
-+ .probe = cfi_probe,
-+ .name = "cfi_probe",
-+ .module = THIS_MODULE
- };
-
- int __init cfi_probe_init(void)
-diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/cfi_util.c linux/drivers/mtd/chips/cfi_util.c
---- linux-mips-2.4.27/drivers/mtd/chips/cfi_util.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/chips/cfi_util.c 2004-11-19 10:25:11.767219856 +0100
-@@ -0,0 +1,91 @@
-+/*
-+ * Common Flash Interface support:
-+ * Generic utility functions not dependant on command set
-+ *
-+ * Copyright (C) 2002 Red Hat
-+ * Copyright (C) 2003 STMicroelectronics Limited
-+ *
-+ * This code is covered by the GPL.
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <asm/io.h>
-+#include <asm/byteorder.h>
-+
-+#include <linux/errno.h>
-+#include <linux/slab.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/cfi.h>
-+#include <linux/mtd/compatmac.h>
-+
-+struct cfi_extquery *
-+cfi_read_pri(struct map_info *map, __u16 adr, __u16 size, const char* name)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ __u32 base = 0; // cfi->chips[0].start;
-+ int ofs_factor = cfi->interleave * cfi->device_type;
-+ int i;
-+ struct cfi_extquery *extp = NULL;
-+
-+ printk(" %s Extended Query Table at 0x%4.4X\n", name, adr);
-+ if (!adr)
-+ goto out;
-+
-+ /* Switch it into Query Mode */
-+ cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
-+
-+ extp = kmalloc(size, GFP_KERNEL);
-+ if (!extp) {
-+ printk(KERN_ERR "Failed to allocate memory\n");
-+ goto out;
-+ }
-+
-+ /* Read in the Extended Query Table */
-+ for (i=0; i<size; i++) {
-+ ((unsigned char *)extp)[i] =
-+ cfi_read_query(map, base+((adr+i)*ofs_factor));
-+ }
-+
-+ if (extp->MajorVersion != '1' ||
-+ (extp->MinorVersion < '0' || extp->MinorVersion > '3')) {
-+ printk(KERN_WARNING " Unknown %s Extended Query "
-+ "version %c.%c.\n", name, extp->MajorVersion,
-+ extp->MinorVersion);
-+ kfree(extp);
-+ extp = NULL;
-+ goto out;
-+ }
-+
-+out:
-+ /* Make sure it's in read mode */
-+ cfi_send_gen_cmd(0xf0, 0, base, map, cfi, cfi->device_type, NULL);
-+
-+ return extp;
-+}
-+
-+EXPORT_SYMBOL(cfi_read_pri);
-+
-+void cfi_fixup(struct map_info *map, struct cfi_fixup* fixups)
-+{
-+ struct cfi_private *cfi = map->fldrv_priv;
-+ struct cfi_fixup *f;
-+
-+ for (f=fixups; f->fixup; f++) {
-+ if (((f->mfr == CFI_MFR_ANY) || (f->mfr == cfi->mfr)) &&
-+ ((f->id == CFI_ID_ANY) || (f->id == cfi->id))) {
-+ f->fixup(map, f->param);
-+ }
-+ }
-+}
-+
-+EXPORT_SYMBOL(cfi_fixup);
-+
-+MODULE_LICENSE("GPL");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/chipreg.c linux/drivers/mtd/chips/chipreg.c
---- linux-mips-2.4.27/drivers/mtd/chips/chipreg.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/chips/chipreg.c 2004-11-19 10:25:11.769219552 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Registration for chip drivers
- *
-@@ -7,10 +7,13 @@
-
- #include <linux/kernel.h>
- #include <linux/config.h>
-+#include <linux/module.h>
- #include <linux/kmod.h>
- #include <linux/spinlock.h>
--#include <linux/mtd/compatmac.h>
-+#include <linux/slab.h>
- #include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/compatmac.h>
-
- spinlock_t chip_drvs_lock = SPIN_LOCK_UNLOCKED;
- static LIST_HEAD(chip_drvs_list);
-@@ -44,10 +47,8 @@
- break;
- }
- }
-- if (ret && !try_inc_mod_count(ret->module)) {
-- /* Eep. Failed. */
-+ if (ret && !try_module_get(ret->module))
- ret = NULL;
-- }
-
- spin_unlock(&chip_drvs_lock);
-
-@@ -64,32 +65,46 @@
-
- drv = get_mtd_chip_driver(name);
-
-- if (!drv && !request_module(name))
-+ if (!drv && !request_module("%s", name))
- drv = get_mtd_chip_driver(name);
-
- if (!drv)
- return NULL;
-
- ret = drv->probe(map);
--#ifdef CONFIG_MODULES
-+
- /* We decrease the use count here. It may have been a
- probe-only module, which is no longer required from this
- point, having given us a handle on (and increased the use
- count of) the actual driver code.
- */
-- if(drv->module)
-- __MOD_DEC_USE_COUNT(drv->module);
--#endif
-+ module_put(drv->module);
-
- if (ret)
- return ret;
-
- return NULL;
- }
-+/*
-+ * Destroy an MTD device which was created for a map device.
-+ * Make sure the MTD device is already unregistered before calling this
-+ */
-+void map_destroy(struct mtd_info *mtd)
-+{
-+ struct map_info *map = mtd->priv;
-+
-+ if (map->fldrv->destroy)
-+ map->fldrv->destroy(mtd);
-+
-+ module_put(map->fldrv->module);
-+
-+ kfree(mtd);
-+}
-
- EXPORT_SYMBOL(register_mtd_chip_driver);
- EXPORT_SYMBOL(unregister_mtd_chip_driver);
- EXPORT_SYMBOL(do_map_probe);
-+EXPORT_SYMBOL(map_destroy);
-
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/gen_probe.c linux/drivers/mtd/chips/gen_probe.c
---- linux-mips-2.4.27/drivers/mtd/chips/gen_probe.c 2003-08-13 19:19:18.000000000 +0200
-+++ linux/drivers/mtd/chips/gen_probe.c 2004-11-19 10:25:11.770219400 +0100
-@@ -1,14 +1,17 @@
- /*
- * Routines common to all CFI-type probes.
-- * (C) 2001, 2001 Red Hat, Inc.
-+ * (C) 2001-2003 Red Hat, Inc.
- * GPL'd
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/cfi.h>
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/gen_probe.h>
-
- static struct mtd_info *check_cmd_set(struct map_info *, int);
-@@ -50,11 +53,11 @@
-
- struct cfi_private *genprobe_ident_chips(struct map_info *map, struct chip_probe *cp)
- {
-- unsigned long base=0;
- struct cfi_private cfi;
- struct cfi_private *retcfi;
-- struct flchip chip[MAX_CFI_CHIPS];
-- int i;
-+ unsigned long *chip_map;
-+ int i, j;
-+ int max_chips;
-
- memset(&cfi, 0, sizeof(cfi));
-
-@@ -77,8 +80,6 @@
- return NULL;
- }
- #endif
-- chip[0].start = 0;
-- chip[0].state = FL_READY;
- cfi.chipshift = cfi.cfiq->DevSize;
-
- switch(cfi.interleave) {
-@@ -103,20 +104,28 @@
- cfi.numchips = 1;
-
- /*
-+ * Allocate memory for bitmap of valid chips.
-+ * Align bitmap storage size to full byte.
-+ */
-+ max_chips = map->size >> cfi.chipshift;
-+ chip_map = kmalloc((max_chips / 8) + ((max_chips % 8) ? 1 : 0), GFP_KERNEL);
-+ if (!chip_map) {
-+ printk(KERN_WARNING "%s: kmalloc failed for CFI chip map\n", map->name);
-+ kfree(cfi.cfiq);
-+ return NULL;
-+ }
-+
-+ set_bit(0, chip_map); /* Mark first chip valid */
-+
-+ /*
- * Now probe for other chips, checking sensibly for aliases while
- * we're at it. The new_chip probe above should have let the first
- * chip in read mode.
-- *
-- * NOTE: Here, we're checking if there is room for another chip
-- * the same size within the mapping. Therefore,
-- * base + chipsize <= map->size is the correct thing to do,
-- * because, base + chipsize would be the _first_ byte of the
-- * next chip, not the one we're currently pondering.
- */
-
-- for (base = (1<<cfi.chipshift); base + (1<<cfi.chipshift) <= map->size;
-- base += (1<<cfi.chipshift))
-- cp->probe_chip(map, base, &chip[0], &cfi);
-+ for (i = 1; i < max_chips; i++) {
-+ cp->probe_chip(map, i << cfi.chipshift, chip_map, &cfi);
-+ }
-
- /*
- * Now allocate the space for the structures we need to return to
-@@ -128,19 +137,26 @@
- if (!retcfi) {
- printk(KERN_WARNING "%s: kmalloc failed for CFI private structure\n", map->name);
- kfree(cfi.cfiq);
-+ kfree(chip_map);
- return NULL;
- }
-
- memcpy(retcfi, &cfi, sizeof(cfi));
-- memcpy(&retcfi->chips[0], chip, sizeof(struct flchip) * cfi.numchips);
-+ memset(&retcfi->chips[0], 0, sizeof(struct flchip) * cfi.numchips);
-
-- /* Fix up the stuff that breaks when you move it */
-- for (i=0; i< retcfi->numchips; i++) {
-- init_waitqueue_head(&retcfi->chips[i].wq);
-- spin_lock_init(&retcfi->chips[i]._spinlock);
-- retcfi->chips[i].mutex = &retcfi->chips[i]._spinlock;
-+ for (i = 0, j = 0; (j < cfi.numchips) && (i < max_chips); i++) {
-+ if(test_bit(i, chip_map)) {
-+ struct flchip *pchip = &retcfi->chips[j++];
-+
-+ pchip->start = (i << cfi.chipshift);
-+ pchip->state = FL_READY;
-+ init_waitqueue_head(&pchip->wq);
-+ spin_lock_init(&pchip->_spinlock);
-+ pchip->mutex = &pchip->_spinlock;
-+ }
- }
-
-+ kfree(chip_map);
- return retcfi;
- }
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/jedec.c linux/drivers/mtd/chips/jedec.c
---- linux-mips-2.4.27/drivers/mtd/chips/jedec.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/chips/jedec.c 2004-11-19 10:25:11.772219096 +0100
-@@ -11,10 +11,16 @@
- * not going to guess how to send commands to them, plus I expect they will
- * all speak CFI..
- *
-- * $Id$
-+ * $Id$
- */
-
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
- #include <linux/mtd/jedec.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/compatmac.h>
-
- static struct mtd_info *jedec_probe(struct map_info *);
- static int jedec_probe8(struct map_info *map,unsigned long base,
-@@ -33,14 +39,51 @@
-
- /* Listing of parts and sizes. We need this table to learn the sector
- size of the chip and the total length */
--static const struct JEDECTable JEDEC_table[] =
-- {{0x013D,"AMD Am29F017D",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
-- {0x01AD,"AMD Am29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
-- {0x01D5,"AMD Am29F080",1*1024*1024,64*1024,MTD_CAP_NORFLASH},
-- {0x01A4,"AMD Am29F040",512*1024,64*1024,MTD_CAP_NORFLASH},
-- {0x20E3,"AMD Am29W040B",512*1024,64*1024,MTD_CAP_NORFLASH},
-- {0xC2AD,"Macronix MX29F016",2*1024*1024,64*1024,MTD_CAP_NORFLASH},
-- {}};
-+static const struct JEDECTable JEDEC_table[] = {
-+ {
-+ .jedec = 0x013D,
-+ .name = "AMD Am29F017D",
-+ .size = 2*1024*1024,
-+ .sectorsize = 64*1024,
-+ .capabilities = MTD_CAP_NORFLASH
-+ },
-+ {
-+ .jedec = 0x01AD,
-+ .name = "AMD Am29F016",
-+ .size = 2*1024*1024,
-+ .sectorsize = 64*1024,
-+ .capabilities = MTD_CAP_NORFLASH
-+ },
-+ {
-+ .jedec = 0x01D5,
-+ .name = "AMD Am29F080",
-+ .size = 1*1024*1024,
-+ .sectorsize = 64*1024,
-+ .capabilities = MTD_CAP_NORFLASH
-+ },
-+ {
-+ .jedec = 0x01A4,
-+ .name = "AMD Am29F040",
-+ .size = 512*1024,
-+ .sectorsize = 64*1024,
-+ .capabilities = MTD_CAP_NORFLASH
-+ },
-+ {
-+ .jedec = 0x20E3,
-+ .name = "AMD Am29W040B",
-+ .size = 512*1024,
-+ .sectorsize = 64*1024,
-+ .capabilities = MTD_CAP_NORFLASH
-+ },
-+ {
-+ .jedec = 0xC2AD,
-+ .name = "Macronix MX29F016",
-+ .size = 2*1024*1024,
-+ .sectorsize = 64*1024,
-+ .capabilities = MTD_CAP_NORFLASH
-+ },
-+ { .jedec = 0x0 }
-+};
-
- static const struct JEDECTable *jedec_idtoinf(__u8 mfr,__u8 id);
- static void jedec_sync(struct mtd_info *mtd) {};
-@@ -54,9 +97,9 @@
-
-
- static struct mtd_chip_driver jedec_chipdrv = {
-- probe: jedec_probe,
-- name: "jedec",
-- module: THIS_MODULE
-+ .probe = jedec_probe,
-+ .name = "jedec",
-+ .module = THIS_MODULE
- };
-
- /* Probe entry point */
-@@ -131,8 +174,7 @@
- /* Generate a part name that includes the number of different chips and
- other configuration information */
- count = 1;
-- strncpy(Part,map->name,sizeof(Part)-10);
-- Part[sizeof(Part)-11] = 0;
-+ strlcpy(Part,map->name,sizeof(Part)-10);
- strcat(Part," ");
- Uniq = 0;
- for (I = 0; priv->chips[I].jedec != 0 && I < MAX_JEDEC_CHIPS; I++)
-@@ -209,8 +251,7 @@
- // printk("Part: '%s'\n",Part);
-
- memset(MTD,0,sizeof(*MTD));
-- // strncpy(MTD->name,Part,sizeof(MTD->name));
-- // MTD->name[sizeof(MTD->name)-1] = 0;
-+ // strlcpy(MTD->name,Part,sizeof(MTD->name));
- MTD->name = map->name;
- MTD->type = MTD_NORFLASH;
- MTD->flags = MTD_CAP_NORFLASH;
-@@ -229,7 +270,7 @@
- MTD->priv = map;
- map->fldrv_priv = priv;
- map->fldrv = &jedec_chipdrv;
-- MOD_INC_USE_COUNT;
-+ __module_get(THIS_MODULE);
- return MTD;
- }
-
-@@ -351,8 +392,8 @@
- static int jedec_probe8(struct map_info *map,unsigned long base,
- struct jedec_private *priv)
- {
-- #define flread(x) map->read8(map,base+x)
-- #define flwrite(v,x) map->write8(map,v,base+x)
-+ #define flread(x) map_read8(map,base+x)
-+ #define flwrite(v,x) map_write8(map,v,base+x)
-
- const unsigned long AutoSel1 = 0xAA;
- const unsigned long AutoSel2 = 0x55;
-@@ -411,8 +452,8 @@
- static int jedec_probe32(struct map_info *map,unsigned long base,
- struct jedec_private *priv)
- {
-- #define flread(x) map->read32(map,base+((x)<<2))
-- #define flwrite(v,x) map->write32(map,v,base+((x)<<2))
-+ #define flread(x) map_read32(map,base+((x)<<2))
-+ #define flwrite(v,x) map_write32(map,v,base+((x)<<2))
-
- const unsigned long AutoSel1 = 0xAAAAAAAA;
- const unsigned long AutoSel2 = 0x55555555;
-@@ -490,7 +531,7 @@
- {
- struct map_info *map = (struct map_info *)mtd->priv;
-
-- map->copy_from(map, buf, from, len);
-+ map_copy_from(map, buf, from, len);
- *retlen = len;
- return 0;
- }
-@@ -514,7 +555,7 @@
- get = priv->bank_fill[0] - offset;
-
- bank /= priv->bank_fill[0];
-- map->copy_from(map,buf + *retlen,bank*my_bank_size + offset,get);
-+ map_copy_from(map,buf + *retlen,bank*my_bank_size + offset,get);
-
- len -= get;
- *retlen += get;
-@@ -545,8 +586,8 @@
- static int flash_erase(struct mtd_info *mtd, struct erase_info *instr)
- {
- // Does IO to the currently selected chip
-- #define flread(x) map->read8(map,chip->base+((x)<<chip->addrshift))
-- #define flwrite(v,x) map->write8(map,v,chip->base+((x)<<chip->addrshift))
-+ #define flread(x) map_read8(map,chip->base+((x)<<chip->addrshift))
-+ #define flwrite(v,x) map_write8(map,v,chip->base+((x)<<chip->addrshift))
-
- unsigned long Time = 0;
- unsigned long NoTime = 0;
-@@ -608,7 +649,7 @@
-
- /* Poll the flash for erasure completion, specs say this can take as long
- as 480 seconds to do all the sectors (for a 2 meg flash).
-- Erasure time is dependant on chip age, temp and wear.. */
-+ Erasure time is dependent on chip age, temp and wear.. */
-
- /* This being a generic routine assumes a 32 bit bus. It does read32s
- and bundles interleved chips into the same grouping. This will work
-@@ -651,19 +692,19 @@
- or this is not really flash ;> */
- switch (map->buswidth) {
- case 1:
-- Last[0] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
-- Last[1] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
-- Last[2] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[0] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[1] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[2] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off);
- break;
- case 2:
-- Last[0] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
-- Last[1] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
-- Last[2] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[0] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[1] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[2] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off);
- break;
- case 3:
-- Last[0] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
-- Last[1] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
-- Last[2] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[0] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[1] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[2] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off);
- break;
- }
- Count = 3;
-@@ -699,13 +740,13 @@
-
- switch (map->buswidth) {
- case 1:
-- Last[Count % 4] = map->read8(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[Count % 4] = map_read8(map,(chip->base >> chip->addrshift) + chip->start + off);
- break;
- case 2:
-- Last[Count % 4] = map->read16(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[Count % 4] = map_read16(map,(chip->base >> chip->addrshift) + chip->start + off);
- break;
- case 4:
-- Last[Count % 4] = map->read32(map,(chip->base >> chip->addrshift) + chip->start + off);
-+ Last[Count % 4] = map_read32(map,(chip->base >> chip->addrshift) + chip->start + off);
- break;
- }
- Count++;
-@@ -755,10 +796,10 @@
- size_t *retlen, const u_char *buf)
- {
- /* Does IO to the currently selected chip. It takes the bank addressing
-- base (which is divisable by the chip size) adds the necesary lower bits
-- of addrshift (interleve index) and then adds the control register index. */
-- #define flread(x) map->read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
-- #define flwrite(v,x) map->write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
-+ base (which is divisible by the chip size) adds the necessary lower bits
-+ of addrshift (interleave index) and then adds the control register index. */
-+ #define flread(x) map_read8(map,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
-+ #define flwrite(v,x) map_write8(map,v,base+(off&((1<<chip->addrshift)-1))+((x)<<chip->addrshift))
-
- struct map_info *map = (struct map_info *)mtd->priv;
- struct jedec_private *priv = (struct jedec_private *)map->fldrv_priv;
-@@ -794,7 +835,7 @@
- // Loop over this page
- for (; off != (chip->size << chip->addrshift) && len != 0; start++, len--, off++,buf++)
- {
-- unsigned char oldbyte = map->read8(map,base+off);
-+ unsigned char oldbyte = map_read8(map,base+off);
- unsigned char Last[4];
- unsigned long Count = 0;
-
-@@ -809,10 +850,10 @@
- flwrite(0xAA,0x555);
- flwrite(0x55,0x2AA);
- flwrite(0xA0,0x555);
-- map->write8(map,*buf,base + off);
-- Last[0] = map->read8(map,base + off);
-- Last[1] = map->read8(map,base + off);
-- Last[2] = map->read8(map,base + off);
-+ map_write8(map,*buf,base + off);
-+ Last[0] = map_read8(map,base + off);
-+ Last[1] = map_read8(map,base + off);
-+ Last[2] = map_read8(map,base + off);
-
- /* Wait for the flash to finish the operation. We store the last 4
- status bytes that have been retrieved so we can determine why
-@@ -820,7 +861,7 @@
- failure */
- for (Count = 3; Last[(Count - 1) % 4] != Last[(Count - 2) % 4] &&
- Count < 10000; Count++)
-- Last[Count % 4] = map->read8(map,base + off);
-+ Last[Count % 4] = map_read8(map,base + off);
- if (Last[(Count - 1) % 4] != *buf)
- {
- jedec_flash_failed(Last[(Count - 3) % 4]);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/jedec_probe.c linux/drivers/mtd/chips/jedec_probe.c
---- linux-mips-2.4.27/drivers/mtd/chips/jedec_probe.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/chips/jedec_probe.c 2004-11-19 10:25:11.774218792 +0100
-@@ -1,9 +1,11 @@
- /*
- Common Flash Interface probe code.
- (C) 2000 Red Hat. GPL'd.
-- $Id$
-+ $Id$
- See JEDEC (http://www.jedec.org/) standard JESD21C (section 3.5)
- for the standard this probe goes back to.
-+
-+ Occasionally maintained by Thayne Harbaugh tharbaugh at lnxi dot com
- */
-
- #include <linux/config.h>
-@@ -15,7 +17,9 @@
- #include <linux/errno.h>
- #include <linux/slab.h>
- #include <linux/interrupt.h>
-+#include <linux/init.h>
-
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/cfi.h>
- #include <linux/mtd/gen_probe.h>
-@@ -26,20 +30,24 @@
- #define MANUFACTURER_FUJITSU 0x0004
- #define MANUFACTURER_INTEL 0x0089
- #define MANUFACTURER_MACRONIX 0x00C2
--#define MANUFACTURER_ST 0x0020
-+#define MANUFACTURER_PMC 0x009D
- #define MANUFACTURER_SST 0x00BF
-+#define MANUFACTURER_ST 0x0020
- #define MANUFACTURER_TOSHIBA 0x0098
-+#define MANUFACTURER_WINBOND 0x00da
-
-
- /* AMD */
- #define AM29F800BB 0x2258
- #define AM29F800BT 0x22D6
-+#define AM29LV400BB 0x22BA
-+#define AM29LV400BT 0x22B9
- #define AM29LV800BB 0x225B
- #define AM29LV800BT 0x22DA
- #define AM29LV160DT 0x22C4
- #define AM29LV160DB 0x2249
- #define AM29F017D 0x003D
--#define AM29F016 0x00AD
-+#define AM29F016D 0x00AD
- #define AM29F080 0x00D5
- #define AM29F040 0x00A4
- #define AM29LV040B 0x004F
-@@ -54,6 +62,7 @@
- #define AT49BV32XT 0x00C9
-
- /* Fujitsu */
-+#define MBM29F040C 0x00A4
- #define MBM29LV650UE 0x22D7
- #define MBM29LV320TE 0x22F6
- #define MBM29LV320BE 0x22F9
-@@ -61,6 +70,9 @@
- #define MBM29LV160BE 0x2249
- #define MBM29LV800BA 0x225B
- #define MBM29LV800TA 0x22DA
-+#define MBM29LV400TC 0x22B9
-+#define MBM29LV400BC 0x22BA
-+
-
- /* Intel */
- #define I28F004B3T 0x00d4
-@@ -93,8 +105,14 @@
- #define MX29F004T 0x0045
- #define MX29F004B 0x0046
-
-+/* PMC */
-+#define PM49FL002 0x006D
-+#define PM49FL004 0x006E
-+#define PM49FL008 0x006A
-+
- /* ST - www.st.com */
--#define M29W800T 0x00D7
-+#define M29W800DT 0x00D7
-+#define M29W800DB 0x005B
- #define M29W160DT 0x22C4
- #define M29W160DB 0x2249
- #define M29W040B 0x00E3
-@@ -110,6 +128,7 @@
- #define SST39LF040 0x00D7
- #define SST39SF010A 0x00B5
- #define SST39SF020A 0x00B6
-+#define SST49LF004B 0x0060
- #define SST49LF030A 0x001C
- #define SST49LF040A 0x0051
- #define SST49LF080A 0x005B
-@@ -122,15 +141,87 @@
- #define TC58FVT641 0x0093
- #define TC58FVB641 0x0095
-
-+/* Winbond */
-+#define W49V002A 0x00b0
-+
-+
-+/*
-+ * Unlock address sets for AMD command sets.
-+ * Intel command sets use the MTD_UADDR_UNNECESSARY.
-+ * Each identifier, except MTD_UADDR_UNNECESSARY, and
-+ * MTD_UADDR_NO_SUPPORT must be defined below in unlock_addrs[].
-+ * MTD_UADDR_NOT_SUPPORTED must be 0 so that structure
-+ * initialization need not require initializing all of the
-+ * unlock addresses for all bit widths.
-+ */
-+enum uaddr {
-+ MTD_UADDR_NOT_SUPPORTED = 0, /* data width not supported */
-+ MTD_UADDR_0x0555_0x02AA,
-+ MTD_UADDR_0x0555_0x0AAA,
-+ MTD_UADDR_0x5555_0x2AAA,
-+ MTD_UADDR_0x0AAA_0x0555,
-+ MTD_UADDR_DONT_CARE, /* Requires an arbitrary address */
-+ MTD_UADDR_UNNECESSARY, /* Does not require any address */
-+};
-+
-+
-+struct unlock_addr {
-+ int addr1;
-+ int addr2;
-+};
-+
-+
-+/*
-+ * I don't like the fact that the first entry in unlock_addrs[]
-+ * exists, but is for MTD_UADDR_NOT_SUPPORTED - and, therefore,
-+ * should not be used. The problem is that structures with
-+ * initializers have extra fields initialized to 0. It is _very_
-+ * desireable to have the unlock address entries for unsupported
-+ * data widths automatically initialized - that means that
-+ * MTD_UADDR_NOT_SUPPORTED must be 0 and the first entry here
-+ * must go unused.
-+ */
-+static const struct unlock_addr unlock_addrs[] = {
-+ [MTD_UADDR_NOT_SUPPORTED] = {
-+ .addr1 = 0xffff,
-+ .addr2 = 0xffff
-+ },
-+
-+ [MTD_UADDR_0x0555_0x02AA] = {
-+ .addr1 = 0x0555,
-+ .addr2 = 0x02aa
-+ },
-+
-+ [MTD_UADDR_0x0555_0x0AAA] = {
-+ .addr1 = 0x0555,
-+ .addr2 = 0x0aaa
-+ },
-+
-+ [MTD_UADDR_0x5555_0x2AAA] = {
-+ .addr1 = 0x5555,
-+ .addr2 = 0x2aaa
-+ },
-+
-+ [MTD_UADDR_0x0AAA_0x0555] = {
-+ .addr1 = 0x0AAA,
-+ .addr2 = 0x0555
-+ },
-+
-+ [MTD_UADDR_DONT_CARE] = {
-+ .addr1 = 0x0000, /* Doesn't matter which address */
-+ .addr2 = 0x0000 /* is used - must be last entry */
-+ }
-+};
-+
-
- struct amd_flash_info {
- const __u16 mfr_id;
- const __u16 dev_id;
- const char *name;
- const int DevSize;
-- const int InterfaceDesc;
- const int NumEraseRegions;
- const int CmdSet;
-+ const __u8 uaddr[4]; /* unlock addrs for 8, 16, 32, 64 */
- const ulong regions[4];
- };
-
-@@ -145,760 +236,1214 @@
- #define SIZE_4MiB 22
- #define SIZE_8MiB 23
-
-+
-+/*
-+ * Please keep this list ordered by manufacturer!
-+ * Fortunately, the list isn't searched often and so a
-+ * slow, linear search isn't so bad.
-+ */
- static const struct amd_flash_info jedec_table[] = {
- {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F032B,
-- name: "AMD AM29F032B",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,64)
-- }
-- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV160DT,
-- name: "AMD AM29LV160DT",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,31),
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F032B,
-+ .name = "AMD AM29F032B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,64)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV160DT,
-+ .name = "AMD AM29LV160DT",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,31),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV160DB,
-- name: "AMD AM29LV160DB",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV160DB,
-+ .name = "AMD AM29LV160DB",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x10000,31)
- }
- }, {
-- mfr_id: MANUFACTURER_TOSHIBA,
-- dev_id: TC58FVT160,
-- name: "Toshiba TC58FVT160",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,31),
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV400BB,
-+ .name = "AMD AM29LV400BB",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
-+ ERASEINFO(0x02000,2),
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x10000,7)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV400BT,
-+ .name = "AMD AM29LV400BT",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,7),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_TOSHIBA,
-- dev_id: TC58FVB160,
-- name: "Toshiba TC58FVB160",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV800BB,
-+ .name = "AMD AM29LV800BB",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x08000,1),
-- ERASEINFO(0x10000,31)
-+ ERASEINFO(0x10000,15),
- }
- }, {
-- mfr_id: MANUFACTURER_TOSHIBA,
-- dev_id: TC58FVB321,
-- name: "Toshiba TC58FVB321",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x02000,8),
-- ERASEINFO(0x10000,63)
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F800BB,
-+ .name = "AMD AM29F800BB",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
-+ ERASEINFO(0x02000,2),
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x10000,15),
- }
- }, {
-- mfr_id: MANUFACTURER_TOSHIBA,
-- dev_id: TC58FVT321,
-- name: "Toshiba TC58FVT321",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x10000,63),
-- ERASEINFO(0x02000,8)
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV800BT,
-+ .name = "AMD AM29LV800BT",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,15),
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x02000,2),
-+ ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_TOSHIBA,
-- dev_id: TC58FVB641,
-- name: "Toshiba TC58FVB641",
-- DevSize: SIZE_8MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x02000,8),
-- ERASEINFO(0x10000,127)
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F800BT,
-+ .name = "AMD AM29F800BT",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,15),
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x02000,2),
-+ ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_TOSHIBA,
-- dev_id: TC58FVT641,
-- name: "Toshiba TC58FVT641",
-- DevSize: SIZE_8MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x10000,127),
-- ERASEINFO(0x02000,8)
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F017D,
-+ .name = "AMD AM29F017D",
-+ .uaddr = {
-+ [0] = MTD_UADDR_DONT_CARE /* x8 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,32),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F016D,
-+ .name = "AMD AM29F016D",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,32),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F080,
-+ .name = "AMD AM29F080",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,16),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29F040,
-+ .name = "AMD AM29F040",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,8),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_AMD,
-+ .dev_id = AM29LV040B,
-+ .name = "AMD AM29LV040B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,8),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_ATMEL,
-+ .dev_id = AT49BV512,
-+ .name = "Atmel AT49BV512",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_64KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,1)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_ATMEL,
-+ .dev_id = AT29LV512,
-+ .name = "Atmel AT29LV512",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_64KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x80,256),
-+ ERASEINFO(0x80,256)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_ATMEL,
-+ .dev_id = AT49BV16X,
-+ .name = "Atmel AT49BV16X",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x02000,8),
-+ ERASEINFO(0x10000,31)
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV650UE,
-- name: "Fujitsu MBM29LV650UE",
-- DevSize: SIZE_8MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,128)
-- }
-- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV320TE,
-- name: "Fujitsu MBM29LV320TE",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x10000,63),
-+ .mfr_id = MANUFACTURER_ATMEL,
-+ .dev_id = AT49BV16XT,
-+ .name = "Atmel AT49BV16XT",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x10000,31),
- ERASEINFO(0x02000,8)
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV320BE,
-- name: "Fujitsu MBM29LV320BE",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x02000,8),
-+ .mfr_id = MANUFACTURER_ATMEL,
-+ .dev_id = AT49BV32X,
-+ .name = "Atmel AT49BV32X",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x02000,8),
- ERASEINFO(0x10000,63)
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV160TE,
-- name: "Fujitsu MBM29LV160TE",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,31),
-- ERASEINFO(0x08000,1),
-- ERASEINFO(0x02000,2),
-- ERASEINFO(0x04000,1)
-+ .mfr_id = MANUFACTURER_ATMEL,
-+ .dev_id = AT49BV32XT,
-+ .name = "Atmel AT49BV32XT",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x0AAA, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x0AAA /* x16 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x10000,63),
-+ ERASEINFO(0x02000,8)
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV160BE,
-- name: "Fujitsu MBM29LV160BE",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-- ERASEINFO(0x02000,2),
-- ERASEINFO(0x08000,1),
-- ERASEINFO(0x10000,31)
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29F040C,
-+ .name = "Fujitsu MBM29F040C",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,8)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV650UE,
-+ .name = "Fujitsu MBM29LV650UE",
-+ .uaddr = {
-+ [0] = MTD_UADDR_DONT_CARE /* x16 */
-+ },
-+ .DevSize = SIZE_8MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,128)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV320TE,
-+ .name = "Fujitsu MBM29LV320TE",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x10000,63),
-+ ERASEINFO(0x02000,8)
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV800BA,
-- name: "Fujitsu MBM29LV800BA",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-- ERASEINFO(0x02000,2),
-- ERASEINFO(0x08000,1),
-- ERASEINFO(0x10000,15)
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV320BE,
-+ .name = "Fujitsu MBM29LV320BE",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x02000,8),
-+ ERASEINFO(0x10000,63)
- }
- }, {
-- mfr_id: MANUFACTURER_FUJITSU,
-- dev_id: MBM29LV800TA,
-- name: "Fujitsu MBM29LV800TA",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,15),
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV160TE,
-+ .name = "Fujitsu MBM29LV160TE",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,31),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV800BB,
-- name: "AMD AM29LV800BB",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV160BE,
-+ .name = "Fujitsu MBM29LV160BE",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x08000,1),
-- ERASEINFO(0x10000,15),
-+ ERASEINFO(0x10000,31)
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F800BB,
-- name: "AMD AM29F800BB",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV800BA,
-+ .name = "Fujitsu MBM29LV800BA",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x08000,1),
-- ERASEINFO(0x10000,15),
-+ ERASEINFO(0x10000,15)
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV800BT,
-- name: "AMD AM29LV800BT",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,15),
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV800TA,
-+ .name = "Fujitsu MBM29LV800TA",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,15),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F800BT,
-- name: "AMD AM29F800BT",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,15),
-- ERASEINFO(0x08000,1),
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV400BC,
-+ .name = "Fujitsu MBM29LV400BC",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
- ERASEINFO(0x02000,2),
-- ERASEINFO(0x04000,1)
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x10000,7)
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV800BB,
-- name: "AMD AM29LV800BB",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,15),
-+ .mfr_id = MANUFACTURER_FUJITSU,
-+ .dev_id = MBM29LV400TC,
-+ .name = "Fujitsu MBM29LV400TC",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,7),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F004B3B,
-- name: "Intel 28F004B3B",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F004B3B,
-+ .name = "Intel 28F004B3B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x02000, 8),
- ERASEINFO(0x10000, 7),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F004B3T,
-- name: "Intel 28F004B3T",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F004B3T,
-+ .name = "Intel 28F004B3T",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x10000, 7),
- ERASEINFO(0x02000, 8),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F400B3B,
-- name: "Intel 28F400B3B",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F400B3B,
-+ .name = "Intel 28F400B3B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x02000, 8),
- ERASEINFO(0x10000, 7),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F400B3T,
-- name: "Intel 28F400B3T",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F400B3T,
-+ .name = "Intel 28F400B3T",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x10000, 7),
- ERASEINFO(0x02000, 8),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F008B3B,
-- name: "Intel 28F008B3B",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F008B3B,
-+ .name = "Intel 28F008B3B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x02000, 8),
- ERASEINFO(0x10000, 15),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F008B3T,
-- name: "Intel 28F008B3T",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F008B3T,
-+ .name = "Intel 28F008B3T",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x10000, 15),
- ERASEINFO(0x02000, 8),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F008S5,
-- name: "Intel 28F008S5",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_INTEL_EXT,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,16),
-- }
-- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F016S5,
-- name: "Intel 28F016S5",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_INTEL_EXT,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,32),
-- }
-- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F008SA,
-- name: "Intel 28F008SA",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 1,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F008S5,
-+ .name = "Intel 28F008S5",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_INTEL_EXT,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,16),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F016S5,
-+ .name = "Intel 28F016S5",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_INTEL_EXT,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,32),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F008SA,
-+ .name = "Intel 28F008SA",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
- ERASEINFO(0x10000, 16),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F800B3B,
-- name: "Intel 28F800B3B",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F800B3B,
-+ .name = "Intel 28F800B3B",
-+ .uaddr = {
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x02000, 8),
- ERASEINFO(0x10000, 15),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F800B3T,
-- name: "Intel 28F800B3T",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F800B3T,
-+ .name = "Intel 28F800B3T",
-+ .uaddr = {
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x10000, 15),
- ERASEINFO(0x02000, 8),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F016B3B,
-- name: "Intel 28F016B3B",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F016B3B,
-+ .name = "Intel 28F016B3B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x02000, 8),
- ERASEINFO(0x10000, 31),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F016S3,
-- name: "Intel I28F016S3",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 1,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F016S3,
-+ .name = "Intel I28F016S3",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
- ERASEINFO(0x10000, 32),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F016B3T,
-- name: "Intel 28F016B3T",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F016B3T,
-+ .name = "Intel 28F016B3T",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x10000, 31),
- ERASEINFO(0x02000, 8),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F160B3B,
-- name: "Intel 28F160B3B",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F160B3B,
-+ .name = "Intel 28F160B3B",
-+ .uaddr = {
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x02000, 8),
- ERASEINFO(0x10000, 31),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F160B3T,
-- name: "Intel 28F160B3T",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F160B3T,
-+ .name = "Intel 28F160B3T",
-+ .uaddr = {
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x10000, 31),
- ERASEINFO(0x02000, 8),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F320B3B,
-- name: "Intel 28F320B3B",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F320B3B,
-+ .name = "Intel 28F320B3B",
-+ .uaddr = {
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x02000, 8),
- ERASEINFO(0x10000, 63),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F320B3T,
-- name: "Intel 28F320B3T",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F320B3T,
-+ .name = "Intel 28F320B3T",
-+ .uaddr = {
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x10000, 63),
- ERASEINFO(0x02000, 8),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F640B3B,
-- name: "Intel 28F640B3B",
-- DevSize: SIZE_8MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F640B3B,
-+ .name = "Intel 28F640B3B",
-+ .uaddr = {
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_8MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x02000, 8),
- ERASEINFO(0x10000, 127),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I28F640B3T,
-- name: "Intel 28F640B3T",
-- DevSize: SIZE_8MiB,
-- CmdSet: P_ID_INTEL_STD,
-- NumEraseRegions: 2,
-- regions: {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I28F640B3T,
-+ .name = "Intel 28F640B3T",
-+ .uaddr = {
-+ [1] = MTD_UADDR_UNNECESSARY, /* x16 */
-+ },
-+ .DevSize = SIZE_8MiB,
-+ .CmdSet = P_ID_INTEL_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
- ERASEINFO(0x10000, 127),
- ERASEINFO(0x02000, 8),
- }
- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I82802AB,
-- name: "Intel 82802AB",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_INTEL_EXT,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,8),
-- }
-- }, {
-- mfr_id: MANUFACTURER_INTEL,
-- dev_id: I82802AC,
-- name: "Intel 82802AC",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_INTEL_EXT,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,16),
-- }
-- }, {
-- mfr_id: MANUFACTURER_ST,
-- dev_id: M29W800T,
-- name: "ST M29W800T",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,15),
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I82802AB,
-+ .name = "Intel 82802AB",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_INTEL_EXT,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,8),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_INTEL,
-+ .dev_id = I82802AC,
-+ .name = "Intel 82802AC",
-+ .uaddr = {
-+ [0] = MTD_UADDR_UNNECESSARY, /* x8 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_INTEL_EXT,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,16),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_MACRONIX,
-+ .dev_id = MX29LV160T,
-+ .name = "MXIC MX29LV160T",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,31),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_ST,
-- dev_id: M29W160DT,
-- name: "ST M29W160DT",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,31),
-- ERASEINFO(0x08000,1),
-- ERASEINFO(0x02000,2),
-- ERASEINFO(0x04000,1)
-- }
-- }, {
-- mfr_id: MANUFACTURER_ST,
-- dev_id: M29W160DB,
-- name: "ST M29W160DB",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-+ .mfr_id = MANUFACTURER_MACRONIX,
-+ .dev_id = MX29LV160B,
-+ .name = "MXIC MX29LV160B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x10000,31)
- }
- }, {
-- mfr_id: MANUFACTURER_ATMEL,
-- dev_id: AT49BV512,
-- name: "Atmel AT49BV512",
-- DevSize: SIZE_64KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,1)
-- }
-- }, {
-- mfr_id: MANUFACTURER_ATMEL,
-- dev_id: AT29LV512,
-- name: "Atmel AT29LV512",
-- DevSize: SIZE_64KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {
-- ERASEINFO(0x80,256),
-- ERASEINFO(0x80,256)
-- }
-- }, {
-- mfr_id: MANUFACTURER_ATMEL,
-- dev_id: AT49BV16X,
-- name: "Atmel AT49BV16X",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x02000,8),
-- ERASEINFO(0x10000,31)
-+ .mfr_id = MANUFACTURER_MACRONIX,
-+ .dev_id = MX29F016,
-+ .name = "Macronix MX29F016",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,32),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_MACRONIX,
-+ .dev_id = MX29F004T,
-+ .name = "Macronix MX29F004T",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,7),
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x02000,2),
-+ ERASEINFO(0x04000,1),
- }
- }, {
-- mfr_id: MANUFACTURER_ATMEL,
-- dev_id: AT49BV16XT,
-- name: "Atmel AT49BV16XT",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x10000,31),
-- ERASEINFO(0x02000,8)
-+ .mfr_id = MANUFACTURER_MACRONIX,
-+ .dev_id = MX29F004B,
-+ .name = "Macronix MX29F004B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
-+ ERASEINFO(0x02000,2),
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x10000,7),
- }
- }, {
-- mfr_id: MANUFACTURER_ATMEL,
-- dev_id: AT49BV32X,
-- name: "Atmel AT49BV32X",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x02000,8),
-- ERASEINFO(0x10000,63)
-+ .mfr_id = MANUFACTURER_PMC,
-+ .dev_id = PM49FL002,
-+ .name = "PMC Pm49FL002",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_256KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO( 0x01000, 64 )
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_PMC,
-+ .dev_id = PM49FL004,
-+ .name = "PMC Pm49FL004",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO( 0x01000, 128 )
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_PMC,
-+ .dev_id = PM49FL008,
-+ .name = "PMC Pm49FL008",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO( 0x01000, 256 )
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST39LF512,
-+ .name = "SST 39LF512",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_64KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,16),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST39LF010,
-+ .name = "SST 39LF010",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_128KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,32),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST39LF020,
-+ .name = "SST 39LF020",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_256KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,64),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST39LF040,
-+ .name = "SST 39LF040",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,128),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST39SF010A,
-+ .name = "SST 39SF010A",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_128KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,32),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST39SF020A,
-+ .name = "SST 39SF020A",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_256KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,64),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST49LF004B,
-+ .name = "SST 49LF004B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,128),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST49LF030A,
-+ .name = "SST 49LF030A",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,96),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST49LF040A,
-+ .name = "SST 49LF040A",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,128),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_SST,
-+ .dev_id = SST49LF080A,
-+ .name = "SST 49LF080A",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x01000,256),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
-+ .dev_id = M29W800DT,
-+ .name = "ST M29W800DT",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
-+ [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,15),
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x02000,2),
-+ ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_ATMEL,
-- dev_id: AT49BV32XT,
-- name: "Atmel AT49BV32XT",
-- DevSize: SIZE_4MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 2,
-- regions: {ERASEINFO(0x10000,63),
-- ERASEINFO(0x02000,8)
-+ .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
-+ .dev_id = M29W800DB,
-+ .name = "ST M29W800DB",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA, /* x8 */
-+ [1] = MTD_UADDR_0x5555_0x2AAA /* x16 */
-+ },
-+ .DevSize = SIZE_1MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
-+ ERASEINFO(0x02000,2),
-+ ERASEINFO(0x08000,1),
-+ ERASEINFO(0x10000,15)
- }
- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F017D,
-- name: "AMD AM29F017D",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,32),
-- }
-- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F016,
-- name: "AMD AM29F016",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,32),
-- }
-- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F080,
-- name: "AMD AM29F080",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,16),
-- }
-- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29F040,
-- name: "AMD AM29F040",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,8),
-- }
-- }, {
-- mfr_id: MANUFACTURER_AMD,
-- dev_id: AM29LV040B,
-- name: "AMD AM29LV040B",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,8),
-- }
-- }, {
-- mfr_id: MANUFACTURER_ST,
-- dev_id: M29W040B,
-- name: "ST M29W040B",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,8),
-- }
-- }, {
-- mfr_id: MANUFACTURER_MACRONIX,
-- dev_id: MX29LV160T,
-- name: "MXIC MX29LV160T",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,31),
-+ .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
-+ .dev_id = M29W160DT,
-+ .name = "ST M29W160DT",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,31),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_MACRONIX,
-- dev_id: MX29LV160B,
-- name: "MXIC MX29LV160B",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-+ .mfr_id = MANUFACTURER_ST, /* FIXME - CFI device? */
-+ .dev_id = M29W160DB,
-+ .name = "ST M29W160DB",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x10000,31)
- }
- }, {
-- mfr_id: MANUFACTURER_MACRONIX,
-- dev_id: MX29F016,
-- name: "Macronix MX29F016",
-- DevSize: SIZE_2MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x10000,32),
-- }
-- }, {
-- mfr_id: MANUFACTURER_MACRONIX,
-- dev_id: MX29F004T,
-- name: "Macronix MX29F004T",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x10000,7),
-+ .mfr_id = MANUFACTURER_ST,
-+ .dev_id = M29W040B,
-+ .name = "ST M29W040B",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0555_0x02AA /* x8 */
-+ },
-+ .DevSize = SIZE_512KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 1,
-+ .regions = {
-+ ERASEINFO(0x10000,8),
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_TOSHIBA,
-+ .dev_id = TC58FVT160,
-+ .name = "Toshiba TC58FVT160",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000,31),
- ERASEINFO(0x08000,1),
- ERASEINFO(0x02000,2),
-- ERASEINFO(0x04000,1),
-+ ERASEINFO(0x04000,1)
- }
- }, {
-- mfr_id: MANUFACTURER_MACRONIX,
-- dev_id: MX29F004B,
-- name: "Macronix MX29F004B",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 4,
-- regions: {ERASEINFO(0x04000,1),
-+ .mfr_id = MANUFACTURER_TOSHIBA,
-+ .dev_id = TC58FVB160,
-+ .name = "Toshiba TC58FVB160",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
-+ },
-+ .DevSize = SIZE_2MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x04000,1),
- ERASEINFO(0x02000,2),
- ERASEINFO(0x08000,1),
-- ERASEINFO(0x10000,7),
-+ ERASEINFO(0x10000,31)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_TOSHIBA,
-+ .dev_id = TC58FVB321,
-+ .name = "Toshiba TC58FVB321",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x02000,8),
-+ ERASEINFO(0x10000,63)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_TOSHIBA,
-+ .dev_id = TC58FVT321,
-+ .name = "Toshiba TC58FVT321",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA /* x16 */
-+ },
-+ .DevSize = SIZE_4MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x10000,63),
-+ ERASEINFO(0x02000,8)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_TOSHIBA,
-+ .dev_id = TC58FVB641,
-+ .name = "Toshiba TC58FVB641",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_8MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x02000,8),
-+ ERASEINFO(0x10000,127)
-+ }
-+ }, {
-+ .mfr_id = MANUFACTURER_TOSHIBA,
-+ .dev_id = TC58FVT641,
-+ .name = "Toshiba TC58FVT641",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x0AAA_0x0555, /* x8 */
-+ [1] = MTD_UADDR_0x0555_0x02AA, /* x16 */
-+ },
-+ .DevSize = SIZE_8MiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 2,
-+ .regions = {
-+ ERASEINFO(0x10000,127),
-+ ERASEINFO(0x02000,8)
- }
- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST39LF512,
-- name: "SST 39LF512",
-- DevSize: SIZE_64KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,16),
-- }
-- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST39LF010,
-- name: "SST 39LF010",
-- DevSize: SIZE_128KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,32),
-- }
-- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST39LF020,
-- name: "SST 39LF020",
-- DevSize: SIZE_256KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,64),
-- }
-- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST39LF040,
-- name: "SST 39LF040",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,128),
-- }
-- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST39SF010A,
-- name: "SST 39SF010A",
-- DevSize: SIZE_128KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,32),
-- }
-- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST39SF020A,
-- name: "SST 39SF020A",
-- DevSize: SIZE_256KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,64),
-- }
-- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST49LF030A,
-- name: "SST 49LF030A",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,96),
-- }
-- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST49LF040A,
-- name: "SST 49LF040A",
-- DevSize: SIZE_512KiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,128),
-- }
-- }, {
-- mfr_id: MANUFACTURER_SST,
-- dev_id: SST49LF080A,
-- name: "SST 49LF080A",
-- DevSize: SIZE_1MiB,
-- CmdSet: P_ID_AMD_STD,
-- NumEraseRegions: 1,
-- regions: {ERASEINFO(0x01000,256),
-+ .mfr_id = MANUFACTURER_WINBOND,
-+ .dev_id = W49V002A,
-+ .name = "Winbond W49V002A",
-+ .uaddr = {
-+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */
-+ },
-+ .DevSize = SIZE_256KiB,
-+ .CmdSet = P_ID_AMD_STD,
-+ .NumEraseRegions= 4,
-+ .regions = {
-+ ERASEINFO(0x10000, 3),
-+ ERASEINFO(0x08000, 1),
-+ ERASEINFO(0x02000, 2),
-+ ERASEINFO(0x04000, 1),
- }
- }
- };
-@@ -907,7 +1452,7 @@
- static int cfi_jedec_setup(struct cfi_private *p_cfi, int index);
-
- static int jedec_probe_chip(struct map_info *map, __u32 base,
-- struct flchip *chips, struct cfi_private *cfi);
-+ unsigned long *chip_map, struct cfi_private *cfi);
-
- struct mtd_info *jedec_probe(struct map_info *map);
-
-@@ -944,11 +1489,43 @@
- * this should be safe.
- */
- cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
-+ /* FIXME - should have reset delay before continuing */
-+}
-
-+
-+static inline __u8 finfo_uaddr(const struct amd_flash_info *finfo, int device_type)
-+{
-+ int uaddr_idx;
-+ __u8 uaddr = MTD_UADDR_NOT_SUPPORTED;
-+
-+ switch ( device_type ) {
-+ case CFI_DEVICETYPE_X8: uaddr_idx = 0; break;
-+ case CFI_DEVICETYPE_X16: uaddr_idx = 1; break;
-+ case CFI_DEVICETYPE_X32: uaddr_idx = 2; break;
-+ default:
-+ printk(KERN_NOTICE "MTD: %s(): unknown device_type %d\n",
-+ __func__, device_type);
-+ goto uaddr_done;
-+ }
-+
-+ uaddr = finfo->uaddr[uaddr_idx];
-+
-+ if (uaddr != MTD_UADDR_NOT_SUPPORTED ) {
-+ /* ASSERT("The unlock addresses for non-8-bit mode
-+ are bollocks. We don't really need an array."); */
-+ uaddr = finfo->uaddr[0];
-+ }
-+
-+ uaddr_done:
-+ return uaddr;
- }
-+
-+
- static int cfi_jedec_setup(struct cfi_private *p_cfi, int index)
- {
- int i,num_erase_regions;
-+ unsigned long mask;
-+ __u8 uaddr;
-
- printk("Found: %s\n",jedec_table[index].name);
-
-@@ -971,41 +1548,170 @@
- p_cfi->cfiq->EraseRegionInfo[i] = jedec_table[index].regions[i];
- }
- p_cfi->cmdset_priv = 0;
-+
-+ /* This may be redundant for some cases, but it doesn't hurt */
-+ p_cfi->mfr = jedec_table[index].mfr_id;
-+ p_cfi->id = jedec_table[index].dev_id;
-+
-+ uaddr = finfo_uaddr(&jedec_table[index], p_cfi->device_type);
-+ if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) {
-+ kfree( p_cfi->cfiq );
-+ return 0;
-+ }
-+
-+ /* Mask out address bits which are smaller than the device type */
-+ mask = ~(p_cfi->device_type-1);
-+ p_cfi->addr_unlock1 = unlock_addrs[uaddr].addr1 & mask;
-+ p_cfi->addr_unlock2 = unlock_addrs[uaddr].addr2 & mask;
-+
- return 1; /* ok */
- }
-
--static int jedec_probe_chip(struct map_info *map, __u32 base,
-- struct flchip *chips, struct cfi_private *cfi)
-+
-+/*
-+ * There is a BIG problem properly ID'ing the JEDEC devic and guaranteeing
-+ * the mapped address, unlock addresses, and proper chip ID. This function
-+ * attempts to minimize errors. It is doubtfull that this probe will ever
-+ * be perfect - consequently there should be some module parameters that
-+ * could be manually specified to force the chip info.
-+ */
-+static inline int jedec_match( __u32 base,
-+ struct map_info *map,
-+ struct cfi_private *cfi,
-+ const struct amd_flash_info *finfo )
- {
-- int i;
-- int unlockpass = 0;
-+ int rc = 0; /* failure until all tests pass */
-+ u32 mfr, id;
-+ __u8 uaddr;
-+ unsigned long mask;
-
-- if (!cfi->numchips) {
-+ /*
-+ * The IDs must match. For X16 and X32 devices operating in
-+ * a lower width ( X8 or X16 ), the device ID's are usually just
-+ * the lower byte(s) of the larger device ID for wider mode. If
-+ * a part is found that doesn't fit this assumption (device id for
-+ * smaller width mode is completely unrealated to full-width mode)
-+ * then the jedec_table[] will have to be augmented with the IDs
-+ * for different widths.
-+ */
- switch (cfi->device_type) {
- case CFI_DEVICETYPE_X8:
-- cfi->addr_unlock1 = 0x555;
-- cfi->addr_unlock2 = 0x2aa;
-+ mfr = (__u8)finfo->mfr_id;
-+ id = (__u8)finfo->dev_id;
- break;
- case CFI_DEVICETYPE_X16:
-- cfi->addr_unlock1 = 0xaaa;
-- if (map->buswidth == cfi->interleave) {
-- /* X16 chip(s) in X8 mode */
-- cfi->addr_unlock2 = 0x555;
-- } else {
-- cfi->addr_unlock2 = 0x554;
-- }
-+ mfr = (__u16)finfo->mfr_id;
-+ id = (__u16)finfo->dev_id;
- break;
- case CFI_DEVICETYPE_X32:
-- cfi->addr_unlock1 = 0x1555;
-- cfi->addr_unlock2 = 0xaaa;
-+ mfr = (__u16)finfo->mfr_id;
-+ id = (__u32)finfo->dev_id;
- break;
- default:
-- printk(KERN_NOTICE "Eep. Unknown jedec_probe device type %d\n", cfi->device_type);
-- return 0;
-+ printk(KERN_WARNING
-+ "MTD %s(): Unsupported device type %d\n",
-+ __func__, cfi->device_type);
-+ goto match_done;
-+ }
-+ if ( cfi->mfr != mfr || cfi->id != id ) {
-+ goto match_done;
-+ }
-+
-+ /* the part size must fit in the memory window */
-+ DEBUG( MTD_DEBUG_LEVEL3,
-+ "MTD %s(): Check fit 0x%.8x + 0x%.8x = 0x%.8x\n",
-+ __func__, base, 1 << finfo->DevSize, base + (1 << finfo->DevSize) );
-+ if ( base + cfi->interleave * ( 1 << finfo->DevSize ) > map->size ) {
-+ DEBUG( MTD_DEBUG_LEVEL3,
-+ "MTD %s(): 0x%.4x 0x%.4x %dKiB doesn't fit\n",
-+ __func__, finfo->mfr_id, finfo->dev_id,
-+ 1 << finfo->DevSize );
-+ goto match_done;
-+ }
-+
-+ uaddr = finfo_uaddr(finfo, cfi->device_type);
-+ if ( uaddr == MTD_UADDR_NOT_SUPPORTED ) {
-+ goto match_done;
-+ }
-+
-+ mask = ~(cfi->device_type-1);
-+
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): check unlock addrs 0x%.4x 0x%.4x\n",
-+ __func__, cfi->addr_unlock1, cfi->addr_unlock2 );
-+ if ( MTD_UADDR_UNNECESSARY != uaddr && MTD_UADDR_DONT_CARE != uaddr
-+ && ( (unlock_addrs[uaddr].addr1 & mask) != cfi->addr_unlock1 ||
-+ (unlock_addrs[uaddr].addr2 & mask) != cfi->addr_unlock2 ) ) {
-+ DEBUG( MTD_DEBUG_LEVEL3,
-+ "MTD %s(): 0x%.4x 0x%.4x did not match\n",
-+ __func__,
-+ unlock_addrs[uaddr].addr1 & mask,
-+ unlock_addrs[uaddr].addr2 & mask);
-+ goto match_done;
- }
-+
-+ /*
-+ * Make sure the ID's dissappear when the device is taken out of
-+ * ID mode. The only time this should fail when it should succeed
-+ * is when the ID's are written as data to the same
-+ * addresses. For this rare and unfortunate case the chip
-+ * cannot be probed correctly.
-+ * FIXME - write a driver that takes all of the chip info as
-+ * module parameters, doesn't probe but forces a load.
-+ */
-+ DEBUG( MTD_DEBUG_LEVEL3,
-+ "MTD %s(): check ID's disappear when not in ID mode\n",
-+ __func__ );
-+ jedec_reset( base, map, cfi );
-+ mfr = jedec_read_mfr( map, base, cfi );
-+ id = jedec_read_id( map, base, cfi );
-+ if ( mfr == cfi->mfr && id == cfi->id ) {
-+ DEBUG( MTD_DEBUG_LEVEL3,
-+ "MTD %s(): ID 0x%.2x:0x%.2x did not change after reset:\n"
-+ "You might need to manually specify JEDEC parameters.\n",
-+ __func__, cfi->mfr, cfi->id );
-+ goto match_done;
-+ }
-+
-+ /* all tests passed - mark as success */
-+ rc = 1;
-+
-+ /*
-+ * Put the device back in ID mode - only need to do this if we
-+ * were truly frobbing a real device.
-+ */
-+ DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): return to ID mode\n", __func__ );
-+ if(cfi->addr_unlock1) {
-+ cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
-+ cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
- }
-+ cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
-+ /* FIXME - should have a delay before continuing */
-+
-+ match_done:
-+ return rc;
-+}
-+
-+
-+static int jedec_probe_chip(struct map_info *map, __u32 base,
-+ unsigned long *chip_map, struct cfi_private *cfi)
-+{
-+ int i;
-+ enum uaddr uaddr_idx = MTD_UADDR_NOT_SUPPORTED;
-
- retry:
-+ if (!cfi->numchips) {
-+ unsigned long mask = ~(cfi->device_type-1);
-+
-+ uaddr_idx++;
-+
-+ if (MTD_UADDR_UNNECESSARY == uaddr_idx)
-+ return 0;
-+
-+ /* Mask out address bits which are smaller than the device type */
-+ cfi->addr_unlock1 = unlock_addrs[uaddr_idx].addr1 & mask;
-+ cfi->addr_unlock2 = unlock_addrs[uaddr_idx].addr2 & mask;
-+ }
-+
- /* Make certain we aren't probing past the end of map */
- if (base >= map->size) {
- printk(KERN_NOTICE
-@@ -1038,6 +1744,7 @@
- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
- }
- cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
-+ /* FIXME - should have a delay before continuing */
-
- if (!cfi->numchips) {
- /* This is the first time we're called. Set up the CFI
-@@ -1045,26 +1752,21 @@
-
- cfi->mfr = jedec_read_mfr(map, base, cfi);
- cfi->id = jedec_read_id(map, base, cfi);
-- printk(KERN_INFO "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
-+ DEBUG(MTD_DEBUG_LEVEL3,
-+ "Search for id:(%02x %02x) interleave(%d) type(%d)\n",
- cfi->mfr, cfi->id, cfi->interleave, cfi->device_type);
- for (i=0; i<sizeof(jedec_table)/sizeof(jedec_table[0]); i++) {
-- if (cfi->mfr == jedec_table[i].mfr_id &&
-- cfi->id == jedec_table[i].dev_id) {
-+ if ( jedec_match( base, map, cfi, &jedec_table[i] ) ) {
-+ DEBUG( MTD_DEBUG_LEVEL3,
-+ "MTD %s(): matched device 0x%x,0x%x unlock_addrs: 0x%.4x 0x%.4x\n",
-+ __func__, cfi->mfr, cfi->id,
-+ cfi->addr_unlock1, cfi->addr_unlock2 );
- if (!cfi_jedec_setup(cfi, i))
- return 0;
- goto ok_out;
- }
- }
-- switch(unlockpass++) {
-- case 0:
-- cfi->addr_unlock1 |= cfi->addr_unlock1 << 4;
-- cfi->addr_unlock2 |= cfi->addr_unlock2 << 4;
-- goto retry;
-- case 1:
-- cfi->addr_unlock1 = cfi->addr_unlock2 = 0;
- goto retry;
-- }
-- return 0;
- } else {
- __u16 mfr;
- __u16 id;
-@@ -1081,21 +1783,24 @@
- }
- }
-
-- /* Check each previous chip to see if it's an alias */
-- for (i=0; i<cfi->numchips; i++) {
-- /* This chip should be in read mode if it's one
-- we've already touched. */
-- if (jedec_read_mfr(map, chips[i].start, cfi) == cfi->mfr &&
-- jedec_read_id(map, chips[i].start, cfi) == cfi->id) {
-+ /* Check each previous chip locations to see if it's an alias */
-+ for (i=0; i < (base >> cfi->chipshift); i++) {
-+ unsigned long start;
-+ if(!test_bit(i, chip_map)) {
-+ continue; /* Skip location; no valid chip at this address */
-+ }
-+ start = i << cfi->chipshift;
-+ if (jedec_read_mfr(map, start, cfi) == cfi->mfr &&
-+ jedec_read_id(map, start, cfi) == cfi->id) {
- /* Eep. This chip also looks like it's in autoselect mode.
- Is it an alias for the new one? */
-- jedec_reset(chips[i].start, map, cfi);
-+ jedec_reset(start, map, cfi);
-
- /* If the device IDs go away, it's an alias */
- if (jedec_read_mfr(map, base, cfi) != cfi->mfr ||
- jedec_read_id(map, base, cfi) != cfi->id) {
- printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
-- map->name, base, chips[i].start);
-+ map->name, base, start);
- return 0;
- }
-
-@@ -1107,7 +1812,7 @@
- if (jedec_read_mfr(map, base, cfi) == cfi->mfr &&
- jedec_read_id(map, base, cfi) == cfi->id) {
- printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
-- map->name, base, chips[i].start);
-+ map->name, base, start);
- return 0;
- }
- }
-@@ -1115,13 +1820,7 @@
-
- /* OK, if we got to here, then none of the previous chips appear to
- be aliases for the current one. */
-- if (cfi->numchips == MAX_CFI_CHIPS) {
-- printk(KERN_WARNING"%s: Too many flash chips detected. Increase MAX_CFI_CHIPS from %d.\n", map->name, MAX_CFI_CHIPS);
-- /* Doesn't matter about resetting it to Read Mode - we're not going to talk to it anyway */
-- return -1;
-- }
-- chips[cfi->numchips].start = base;
-- chips[cfi->numchips].state = FL_READY;
-+ set_bit((base >> cfi->chipshift), chip_map); /* Update chip map */
- cfi->numchips++;
-
- ok_out:
-@@ -1136,8 +1835,8 @@
- }
-
- static struct chip_probe jedec_chip_probe = {
-- name: "JEDEC",
-- probe_chip: jedec_probe_chip
-+ .name = "JEDEC",
-+ .probe_chip = jedec_probe_chip
- };
-
- struct mtd_info *jedec_probe(struct map_info *map)
-@@ -1150,9 +1849,9 @@
- }
-
- static struct mtd_chip_driver jedec_chipdrv = {
-- probe: jedec_probe,
-- name: "jedec_probe",
-- module: THIS_MODULE
-+ .probe = jedec_probe,
-+ .name = "jedec_probe",
-+ .module = THIS_MODULE
- };
-
- int __init jedec_probe_init(void)
-diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/map_absent.c linux/drivers/mtd/chips/map_absent.c
---- linux-mips-2.4.27/drivers/mtd/chips/map_absent.c 2001-11-05 21:15:51.000000000 +0100
-+++ linux/drivers/mtd/chips/map_absent.c 2004-11-19 10:25:11.776218488 +0100
-@@ -1,7 +1,7 @@
- /*
- * Common code to handle absent "placeholder" devices
- * Copyright 2001 Resilience Corporation <ebrower@resilience.com>
-- * $Id$
-+ * $Id$
- *
- * This map driver is used to allocate "placeholder" MTD
- * devices on systems that have socketed/removable media.
-@@ -23,9 +23,10 @@
- #include <linux/kernel.h>
- #include <linux/errno.h>
- #include <linux/slab.h>
--
-+#include <linux/init.h>
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
--
-+#include <linux/mtd/compatmac.h>
-
- static int map_absent_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
- static int map_absent_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
-@@ -36,10 +37,10 @@
-
-
- static struct mtd_chip_driver map_absent_chipdrv = {
-- probe: map_absent_probe,
-- destroy: map_absent_destroy,
-- name: "map_absent",
-- module: THIS_MODULE
-+ .probe = map_absent_probe,
-+ .destroy = map_absent_destroy,
-+ .name = "map_absent",
-+ .module = THIS_MODULE
- };
-
- static struct mtd_info *map_absent_probe(struct map_info *map)
-@@ -65,7 +66,7 @@
- mtd->flags = 0;
- mtd->erasesize = PAGE_SIZE;
-
-- MOD_INC_USE_COUNT;
-+ __module_get(THIS_MODULE);
- return mtd;
- }
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/map_ram.c linux/drivers/mtd/chips/map_ram.c
---- linux-mips-2.4.27/drivers/mtd/chips/map_ram.c 2001-11-05 21:15:51.000000000 +0100
-+++ linux/drivers/mtd/chips/map_ram.c 2004-11-19 10:25:11.777218336 +0100
-@@ -1,7 +1,7 @@
- /*
- * Common code to handle map devices which are simple RAM
- * (C) 2000 Red Hat. GPL'd.
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/module.h>
-@@ -11,8 +11,10 @@
- #include <asm/byteorder.h>
- #include <linux/errno.h>
- #include <linux/slab.h>
--
-+#include <linux/init.h>
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-+#include <linux/mtd/compatmac.h>
-
-
- static int mapram_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
-@@ -23,9 +25,9 @@
-
-
- static struct mtd_chip_driver mapram_chipdrv = {
-- probe: map_ram_probe,
-- name: "map_ram",
-- module: THIS_MODULE
-+ .probe = map_ram_probe,
-+ .name = "map_ram",
-+ .module = THIS_MODULE
- };
-
- static struct mtd_info *map_ram_probe(struct map_info *map)
-@@ -34,21 +36,21 @@
-
- /* Check the first byte is RAM */
- #if 0
-- map->write8(map, 0x55, 0);
-- if (map->read8(map, 0) != 0x55)
-+ map_write8(map, 0x55, 0);
-+ if (map_read8(map, 0) != 0x55)
- return NULL;
-
-- map->write8(map, 0xAA, 0);
-- if (map->read8(map, 0) != 0xAA)
-+ map_write8(map, 0xAA, 0);
-+ if (map_read8(map, 0) != 0xAA)
- return NULL;
-
- /* Check the last byte is RAM */
-- map->write8(map, 0x55, map->size-1);
-- if (map->read8(map, map->size-1) != 0x55)
-+ map_write8(map, 0x55, map->size-1);
-+ if (map_read8(map, map->size-1) != 0x55)
- return NULL;
-
-- map->write8(map, 0xAA, map->size-1);
-- if (map->read8(map, map->size-1) != 0xAA)
-+ map_write8(map, 0xAA, map->size-1);
-+ if (map_read8(map, map->size-1) != 0xAA)
- return NULL;
- #endif
- /* OK. It seems to be RAM. */
-@@ -74,7 +76,7 @@
- while(mtd->size & (mtd->erasesize - 1))
- mtd->erasesize >>= 1;
-
-- MOD_INC_USE_COUNT;
-+ __module_get(THIS_MODULE);
- return mtd;
- }
-
-@@ -83,7 +85,7 @@
- {
- struct map_info *map = (struct map_info *)mtd->priv;
-
-- map->copy_from(map, buf, from, len);
-+ map_copy_from(map, buf, from, len);
- *retlen = len;
- return 0;
- }
-@@ -92,7 +94,7 @@
- {
- struct map_info *map = (struct map_info *)mtd->priv;
-
-- map->copy_to(map, to, buf, len);
-+ map_copy_to(map, to, buf, len);
- *retlen = len;
- return 0;
- }
-@@ -105,7 +107,7 @@
- unsigned long i;
-
- for (i=0; i<instr->len; i++)
-- map->write8(map, 0xFF, instr->addr + i);
-+ map_write8(map, 0xFF, instr->addr + i);
-
- if (instr->callback)
- instr->callback(instr);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/map_rom.c linux/drivers/mtd/chips/map_rom.c
---- linux-mips-2.4.27/drivers/mtd/chips/map_rom.c 2001-11-05 21:15:52.000000000 +0100
-+++ linux/drivers/mtd/chips/map_rom.c 2004-11-19 10:25:11.778218184 +0100
-@@ -1,7 +1,7 @@
- /*
- * Common code to handle map devices which are simple ROM
- * (C) 2000 Red Hat. GPL'd.
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/version.h>
-@@ -12,8 +12,10 @@
- #include <asm/byteorder.h>
- #include <linux/errno.h>
- #include <linux/slab.h>
--
-+#include <linux/init.h>
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-+#include <linux/mtd/compatmac.h>
-
- static int maprom_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
- static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
-@@ -21,9 +23,9 @@
- struct mtd_info *map_rom_probe(struct map_info *map);
-
- static struct mtd_chip_driver maprom_chipdrv = {
-- probe: map_rom_probe,
-- name: "map_rom",
-- module: THIS_MODULE
-+ .probe = map_rom_probe,
-+ .name = "map_rom",
-+ .module = THIS_MODULE
- };
-
- struct mtd_info *map_rom_probe(struct map_info *map)
-@@ -49,7 +51,7 @@
- while(mtd->size & (mtd->erasesize - 1))
- mtd->erasesize >>= 1;
-
-- MOD_INC_USE_COUNT;
-+ __module_get(THIS_MODULE);
- return mtd;
- }
-
-@@ -58,7 +60,7 @@
- {
- struct map_info *map = (struct map_info *)mtd->priv;
-
-- map->copy_from(map, buf, from, len);
-+ map_copy_from(map, buf, from, len);
- *retlen = len;
- return 0;
- }
-diff -Nurb linux-mips-2.4.27/drivers/mtd/chips/sharp.c linux/drivers/mtd/chips/sharp.c
---- linux-mips-2.4.27/drivers/mtd/chips/sharp.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/chips/sharp.c 2004-11-19 10:25:11.792216056 +0100
-@@ -4,7 +4,7 @@
- * Copyright 2000,2001 David A. Schleef <ds@schleef.org>
- * 2000,2001 Lineo, Inc.
- *
-- * $Id$
-+ * $Id$
- *
- * Devices supported:
- * LH28F016SCT Symmetrical block flash memory, 2Mx8
-@@ -28,6 +28,7 @@
- #include <linux/errno.h>
- #include <linux/interrupt.h>
- #include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/cfi.h>
- #include <linux/delay.h>
-
-@@ -98,10 +99,10 @@
- static void sharp_destroy(struct mtd_info *mtd);
-
- static struct mtd_chip_driver sharp_chipdrv = {
-- probe: sharp_probe,
-- destroy: sharp_destroy,
-- name: "sharp",
-- module: THIS_MODULE
-+ .probe = sharp_probe,
-+ .destroy = sharp_destroy,
-+ .name = "sharp",
-+ .module = THIS_MODULE
- };
-
-
-@@ -116,8 +117,10 @@
- return NULL;
-
- sharp = kmalloc(sizeof(*sharp), GFP_KERNEL);
-- if(!sharp)
-+ if(!sharp) {
-+ kfree(mtd);
- return NULL;
-+ }
-
- memset(mtd, 0, sizeof(*mtd));
-
-@@ -163,12 +166,12 @@
- u32 read0, read4;
- int width = 4;
-
-- tmp = map->read32(map, base+0);
-+ tmp = map_read32(map, base+0);
-
-- map->write32(map, CMD_READ_ID, base+0);
-+ map_write32(map, CMD_READ_ID, base+0);
-
-- read0=map->read32(map, base+0);
-- read4=map->read32(map, base+4);
-+ read0=map_read32(map, base+0);
-+ read4=map_read32(map, base+4);
- if(read0 == 0x89898989){
- printk("Looks like sharp flash\n");
- switch(read4){
-@@ -196,10 +199,10 @@
- printk("Sort-of looks like sharp flash, 0x%08x 0x%08x\n",
- read0,read4);
- }
-- }else if((map->read32(map, base+0) == CMD_READ_ID)){
-+ }else if((map_read32(map, base+0) == CMD_READ_ID)){
- /* RAM, probably */
- printk("Looks like RAM\n");
-- map->write32(map, tmp, base+0);
-+ map_write32(map, tmp, base+0);
- }else{
- printk("Doesn't look like sharp flash, 0x%08x 0x%08x\n",
- read0,read4);
-@@ -221,10 +224,10 @@
-
- switch(chip->state){
- case FL_READY:
-- map->write32(map,CMD_READ_STATUS,adr);
-+ map_write32(map,CMD_READ_STATUS,adr);
- chip->state = FL_STATUS;
- case FL_STATUS:
-- status = map->read32(map,adr);
-+ status = map_read32(map,adr);
- //printk("status=%08x\n",status);
-
- udelay(100);
-@@ -252,7 +255,7 @@
- goto retry;
- }
-
-- map->write32(map,CMD_RESET, adr);
-+ map_write32(map,CMD_RESET, adr);
-
- chip->state = FL_READY;
-
-@@ -293,7 +296,7 @@
- if(ret<0)
- break;
-
-- map->copy_from(map,buf,ofs,thislen);
-+ map_copy_from(map,buf,ofs,thislen);
-
- sharp_release(&sharp->chips[chipnum]);
-
-@@ -354,17 +357,17 @@
- ret = sharp_wait(map,chip);
-
- for(try=0;try<10;try++){
-- map->write32(map,CMD_BYTE_WRITE,adr);
-+ map_write32(map,CMD_BYTE_WRITE,adr);
- /* cpu_to_le32 -> hack to fix the writel be->le conversion */
-- map->write32(map,cpu_to_le32(datum),adr);
-+ map_write32(map,cpu_to_le32(datum),adr);
-
- chip->state = FL_WRITING;
-
- timeo = jiffies + (HZ/2);
-
-- map->write32(map,CMD_READ_STATUS,adr);
-+ map_write32(map,CMD_READ_STATUS,adr);
- for(i=0;i<100;i++){
-- status = map->read32(map,adr);
-+ status = map_read32(map,adr);
- if((status & SR_READY)==SR_READY)
- break;
- }
-@@ -377,9 +380,9 @@
-
- printk("sharp: error writing byte at addr=%08lx status=%08x\n",adr,status);
-
-- map->write32(map,CMD_CLEAR_STATUS,adr);
-+ map_write32(map,CMD_CLEAR_STATUS,adr);
- }
-- map->write32(map,CMD_RESET,adr);
-+ map_write32(map,CMD_RESET,adr);
- chip->state = FL_READY;
-
- wake_up(&chip->wq);
-@@ -436,14 +439,14 @@
- int status;
- DECLARE_WAITQUEUE(wait, current);
-
-- map->write32(map,CMD_READ_STATUS,adr);
-- status = map->read32(map,adr);
-+ map_write32(map,CMD_READ_STATUS,adr);
-+ status = map_read32(map,adr);
-
- timeo = jiffies + HZ;
-
- while(time_before(jiffies, timeo)){
-- map->write32(map,CMD_READ_STATUS,adr);
-- status = map->read32(map,adr);
-+ map_write32(map,CMD_READ_STATUS,adr);
-+ status = map_read32(map,adr);
- if((status & SR_READY)==SR_READY){
- ret = 0;
- goto out;
-@@ -485,26 +488,26 @@
- sharp_unlock_oneblock(map,chip,adr);
- #endif
-
-- map->write32(map,CMD_BLOCK_ERASE_1,adr);
-- map->write32(map,CMD_BLOCK_ERASE_2,adr);
-+ map_write32(map,CMD_BLOCK_ERASE_1,adr);
-+ map_write32(map,CMD_BLOCK_ERASE_2,adr);
-
- chip->state = FL_ERASING;
-
- ret = sharp_do_wait_for_ready(map,chip,adr);
- if(ret<0)return ret;
-
-- map->write32(map,CMD_READ_STATUS,adr);
-- status = map->read32(map,adr);
-+ map_write32(map,CMD_READ_STATUS,adr);
-+ status = map_read32(map,adr);
-
- if(!(status&SR_ERRORS)){
-- map->write32(map,CMD_RESET,adr);
-+ map_write32(map,CMD_RESET,adr);
- chip->state = FL_READY;
- //spin_unlock_bh(chip->mutex);
- return 0;
- }
-
- printk("sharp: error erasing block at addr=%08lx status=%08x\n",adr,status);
-- map->write32(map,CMD_CLEAR_STATUS,adr);
-+ map_write32(map,CMD_CLEAR_STATUS,adr);
-
- //spin_unlock_bh(chip->mutex);
-
-@@ -518,17 +521,17 @@
- int i;
- int status;
-
-- map->write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr);
-- map->write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr);
-+ map_write32(map,CMD_CLEAR_BLOCK_LOCKS_1,adr);
-+ map_write32(map,CMD_CLEAR_BLOCK_LOCKS_2,adr);
-
- udelay(100);
-
-- status = map->read32(map,adr);
-+ status = map_read32(map,adr);
- printk("status=%08x\n",status);
-
- for(i=0;i<1000;i++){
-- //map->write32(map,CMD_READ_STATUS,adr);
-- status = map->read32(map,adr);
-+ //map_write32(map,CMD_READ_STATUS,adr);
-+ status = map_read32(map,adr);
- if((status & SR_READY)==SR_READY)
- break;
- udelay(100);
-@@ -538,13 +541,13 @@
- }
-
- if(!(status&SR_ERRORS)){
-- map->write32(map,CMD_RESET,adr);
-+ map_write32(map,CMD_RESET,adr);
- chip->state = FL_READY;
- return;
- }
-
- printk("sharp: error unlocking block at addr=%08lx status=%08x\n",adr,status);
-- map->write32(map,CMD_CLEAR_STATUS,adr);
-+ map_write32(map,CMD_CLEAR_STATUS,adr);
- }
- #endif
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/cmdlinepart.c linux/drivers/mtd/cmdlinepart.c
---- linux-mips-2.4.27/drivers/mtd/cmdlinepart.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/cmdlinepart.c 2004-11-19 10:25:11.628240984 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Read flash partition table from command line
- *
-@@ -28,7 +28,7 @@
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/partitions.h>
--#include <asm/setup.h>
-+#include <linux/mtd/compatmac.h>
- #include <linux/bootmem.h>
-
- /* error message prefix */
-@@ -178,8 +178,7 @@
- parts[this_part].mask_flags = mask_flags;
- if (name)
- {
-- strncpy(extra_mem, name, name_len);
-- extra_mem[name_len] = 0;
-+ strlcpy(extra_mem, name, name_len + 1);
- }
- else
- {
-@@ -258,8 +257,7 @@
- this_mtd->parts = parts;
- this_mtd->num_parts = num_parts;
- this_mtd->mtd_id = (char*)(this_mtd + 1);
-- strncpy(this_mtd->mtd_id, mtd_id, mtd_id_len);
-- this_mtd->mtd_id[mtd_id_len] = 0;
-+ strlcpy(this_mtd->mtd_id, mtd_id, mtd_id_len + 1);
-
- /* link into chain */
- this_mtd->next = partitions;
-@@ -291,13 +289,14 @@
- * information. It returns partitions for the requested mtd device, or
- * the first one in the chain if a NULL mtd_id is passed in.
- */
--int parse_cmdline_partitions(struct mtd_info *master,
-+static int parse_cmdline_partitions(struct mtd_info *master,
- struct mtd_partition **pparts,
-- const char *mtd_id)
-+ unsigned long origin)
- {
- unsigned long offset;
- int i;
- struct cmdline_mtd_partition *part;
-+ char *mtd_id = master->name;
-
- if(!cmdline)
- return -EINVAL;
-@@ -349,7 +348,25 @@
-
- __setup("mtdparts=", mtdpart_setup);
-
--EXPORT_SYMBOL(parse_cmdline_partitions);
-+static struct mtd_part_parser cmdline_parser = {
-+ .owner = THIS_MODULE,
-+ .parse_fn = parse_cmdline_partitions,
-+ .name = "cmdlinepart",
-+};
-+
-+static int __init cmdline_parser_init(void)
-+{
-+ return register_mtd_parser(&cmdline_parser);
-+}
-+
-+static void __exit cmdline_parser_exit(void)
-+{
-+ deregister_mtd_parser(&cmdline_parser);
-+}
-+
-+module_init(cmdline_parser_init);
-+module_exit(cmdline_parser_exit);
-+
-
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Marius Groeger <mag@sysgo.de>");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/Config.in linux/drivers/mtd/devices/Config.in
---- linux-mips-2.4.27/drivers/mtd/devices/Config.in 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/devices/Config.in 2004-11-19 10:25:11.811213168 +0100
-@@ -1,6 +1,6 @@
--# drivers/mtd/maps/Config.in
-+# drivers/mtd/devices/Config.in
-
--# $Id$
-+# $Id$
-
- mainmenu_option next_comment
-
-@@ -28,13 +28,13 @@
- dep_tristate ' MTD emulation using block device' CONFIG_MTD_BLKMTD $CONFIG_MTD
-
- comment 'Disk-On-Chip Device Drivers'
-- dep_tristate ' M-Systems Disk-On-Chip 1000' CONFIG_MTD_DOC1000 $CONFIG_MTD
- dep_tristate ' M-Systems Disk-On-Chip 2000 and Millennium' CONFIG_MTD_DOC2000 $CONFIG_MTD
- dep_tristate ' M-Systems Disk-On-Chip Millennium-only alternative driver (see help)' CONFIG_MTD_DOC2001 $CONFIG_MTD
-- if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then
-+ dep_tristate ' M-Systems Disk-On-Chip Millennium Plus driver (see help)' CONFIG_MTD_DOC2001PLUS $CONFIG_MTD
-+ if [ "$CONFIG_MTD_DOC2001PLUS" = "y" -o "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" ]; then
- define_bool CONFIG_MTD_DOCPROBE y
- else
-- if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then
-+ if [ "$CONFIG_MTD_DOC2001PLUS" = "m" -o "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" ]; then
- define_bool CONFIG_MTD_DOCPROBE m
- else
- define_bool CONFIG_MTD_DOCPROBE n
-diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/Makefile linux/drivers/mtd/devices/Makefile
---- linux-mips-2.4.27/drivers/mtd/devices/Makefile 2002-03-30 09:15:50.000000000 +0100
-+++ linux/drivers/mtd/devices/Makefile 2004-11-19 10:25:11.813212864 +0100
-@@ -1,9 +1,12 @@
- #
- # linux/drivers/devices/Makefile
- #
--# $Id$
-+# $Id$
-
-+ifeq ($(PATCHLEVEL),4)
- O_TARGET := devlink.o
-+export-objs := docecc.o
-+endif
-
- # *** BIG UGLY NOTE ***
- #
-@@ -12,15 +15,16 @@
- # here where previously there was none. We now have to ensure that
- # doc200[01].o are linked before docprobe.o
-
--obj-$(CONFIG_MTD_DOC1000) += doc1000.o
- obj-$(CONFIG_MTD_DOC2000) += doc2000.o
- obj-$(CONFIG_MTD_DOC2001) += doc2001.o
-+obj-$(CONFIG_MTD_DOC2001PLUS) += doc2001plus.o
- obj-$(CONFIG_MTD_DOCPROBE) += docprobe.o docecc.o
- obj-$(CONFIG_MTD_SLRAM) += slram.o
-+obj-$(CONFIG_MTD_PHRAM) += phram.o
- obj-$(CONFIG_MTD_PMC551) += pmc551.o
- obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o
- obj-$(CONFIG_MTD_MTDRAM) += mtdram.o
- obj-$(CONFIG_MTD_LART) += lart.o
- obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o
-
--include $(TOPDIR)/Rules.make
-+-include $(TOPDIR)/Rules.make
-diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/blkmtd-25.c linux/drivers/mtd/devices/blkmtd-25.c
---- linux-mips-2.4.27/drivers/mtd/devices/blkmtd-25.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/devices/blkmtd-25.c 2004-11-19 10:25:11.814212712 +0100
-@@ -0,0 +1,827 @@
-+/*
-+ * $Id$
-+ *
-+ * blkmtd.c - use a block device as a fake MTD
-+ *
-+ * Author: Simon Evans <spse@secret.org.uk>
-+ *
-+ * Copyright (C) 2001,2002 Simon Evans
-+ *
-+ * Licence: GPL
-+ *
-+ * How it works:
-+ * The driver uses raw/io to read/write the device and the page
-+ * cache to cache access. Writes update the page cache with the
-+ * new data and mark it dirty and add the page into a BIO which
-+ * is then written out.
-+ *
-+ * It can be loaded Read-Only to prevent erases and writes to the
-+ * medium.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/fs.h>
-+#include <linux/blkdev.h>
-+#include <linux/bio.h>
-+#include <linux/pagemap.h>
-+#include <linux/list.h>
-+#include <linux/init.h>
-+#include <linux/mtd/mtd.h>
-+
-+
-+#define err(format, arg...) printk(KERN_ERR "blkmtd: " format "\n" , ## arg)
-+#define info(format, arg...) printk(KERN_INFO "blkmtd: " format "\n" , ## arg)
-+#define warn(format, arg...) printk(KERN_WARNING "blkmtd: " format "\n" , ## arg)
-+#define crit(format, arg...) printk(KERN_CRIT "blkmtd: " format "\n" , ## arg)
-+
-+
-+/* Default erase size in K, always make it a multiple of PAGE_SIZE */
-+#define CONFIG_MTD_BLKDEV_ERASESIZE (128 << 10) /* 128KiB */
-+#define VERSION "$Revision$"
-+
-+/* Info for the block device */
-+struct blkmtd_dev {
-+ struct list_head list;
-+ struct block_device *blkdev;
-+ struct mtd_info mtd_info;
-+ struct semaphore wrbuf_mutex;
-+};
-+
-+
-+/* Static info about the MTD, used in cleanup_module */
-+static LIST_HEAD(blkmtd_device_list);
-+
-+
-+static void blkmtd_sync(struct mtd_info *mtd);
-+
-+#define MAX_DEVICES 4
-+
-+/* Module parameters passed by insmod/modprobe */
-+char *device[MAX_DEVICES]; /* the block device to use */
-+int erasesz[MAX_DEVICES]; /* optional default erase size */
-+int ro[MAX_DEVICES]; /* optional read only flag */
-+int sync;
-+
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Simon Evans <spse@secret.org.uk>");
-+MODULE_DESCRIPTION("Emulate an MTD using a block device");
-+MODULE_PARM(device, "1-4s");
-+MODULE_PARM_DESC(device, "block device to use");
-+MODULE_PARM(erasesz, "1-4i");
-+MODULE_PARM_DESC(erasesz, "optional erase size to use in KiB. eg 4=4KiB.");
-+MODULE_PARM(ro, "1-4i");
-+MODULE_PARM_DESC(ro, "1=Read only, writes and erases cause errors");
-+MODULE_PARM(sync, "i");
-+MODULE_PARM_DESC(sync, "1=Synchronous writes");
-+
-+
-+/* completion handler for BIO reads */
-+static int bi_read_complete(struct bio *bio, unsigned int bytes_done, int error)
-+{
-+ if (bio->bi_size)
-+ return 1;
-+
-+ complete((struct completion*)bio->bi_private);
-+ return 0;
-+}
-+
-+
-+/* completion handler for BIO writes */
-+static int bi_write_complete(struct bio *bio, unsigned int bytes_done, int error)
-+{
-+ const int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
-+ struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
-+
-+ if (bio->bi_size)
-+ return 1;
-+
-+ if(!uptodate)
-+ err("bi_write_complete: not uptodate\n");
-+
-+ do {
-+ struct page *page = bvec->bv_page;
-+ DEBUG(3, "Cleaning up page %ld\n", page->index);
-+ if (--bvec >= bio->bi_io_vec)
-+ prefetchw(&bvec->bv_page->flags);
-+
-+ if (uptodate) {
-+ SetPageUptodate(page);
-+ } else {
-+ ClearPageUptodate(page);
-+ SetPageError(page);
-+ }
-+ ClearPageDirty(page);
-+ unlock_page(page);
-+ page_cache_release(page);
-+ } while (bvec >= bio->bi_io_vec);
-+
-+ complete((struct completion*)bio->bi_private);
-+ return 0;
-+}
-+
-+
-+/* read one page from the block device */
-+static int blkmtd_readpage(struct blkmtd_dev *dev, struct page *page)
-+{
-+ struct bio *bio;
-+ struct completion event;
-+ int err = -ENOMEM;
-+
-+ if(PageUptodate(page)) {
-+ DEBUG(2, "blkmtd: readpage page %ld is already upto date\n", page->index);
-+ unlock_page(page);
-+ return 0;
-+ }
-+
-+ ClearPageUptodate(page);
-+ ClearPageError(page);
-+
-+ bio = bio_alloc(GFP_KERNEL, 1);
-+ if(bio) {
-+ init_completion(&event);
-+ bio->bi_bdev = dev->blkdev;
-+ bio->bi_sector = page->index << (PAGE_SHIFT-9);
-+ bio->bi_private = &event;
-+ bio->bi_end_io = bi_read_complete;
-+ if(bio_add_page(bio, page, PAGE_SIZE, 0) == PAGE_SIZE) {
-+ submit_bio(READ, bio);
-+ blk_run_queues();
-+ wait_for_completion(&event);
-+ err = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : -EIO;
-+ bio_put(bio);
-+ }
-+ }
-+
-+ if(err)
-+ SetPageError(page);
-+ else
-+ SetPageUptodate(page);
-+ flush_dcache_page(page);
-+ unlock_page(page);
-+ return err;
-+}
-+
-+
-+/* write out the current BIO and wait for it to finish */
-+static int blkmtd_write_out(struct bio *bio)
-+{
-+ struct completion event;
-+ int err;
-+
-+ if(!bio->bi_vcnt) {
-+ bio_put(bio);
-+ return 0;
-+ }
-+
-+ init_completion(&event);
-+ bio->bi_private = &event;
-+ bio->bi_end_io = bi_write_complete;
-+ submit_bio(WRITE, bio);
-+ blk_run_queues();
-+ wait_for_completion(&event);
-+ DEBUG(3, "submit_bio completed, bi_vcnt = %d\n", bio->bi_vcnt);
-+ err = test_bit(BIO_UPTODATE, &bio->bi_flags) ? 0 : -EIO;
-+ bio_put(bio);
-+ return err;
-+}
-+
-+
-+/**
-+ * blkmtd_add_page - add a page to the current BIO
-+ * @bio: bio to add to (NULL to alloc initial bio)
-+ * @blkdev: block device
-+ * @page: page to add
-+ * @pagecnt: pages left to add
-+ *
-+ * Adds a page to the current bio, allocating it if necessary. If it cannot be
-+ * added, the current bio is written out and a new one is allocated. Returns
-+ * the new bio to add or NULL on error
-+ */
-+static struct bio *blkmtd_add_page(struct bio *bio, struct block_device *blkdev,
-+ struct page *page, int pagecnt)
-+{
-+
-+ retry:
-+ if(!bio) {
-+ bio = bio_alloc(GFP_KERNEL, pagecnt);
-+ if(!bio)
-+ return NULL;
-+ bio->bi_sector = page->index << (PAGE_SHIFT-9);
-+ bio->bi_bdev = blkdev;
-+ }
-+
-+ if(bio_add_page(bio, page, PAGE_SIZE, 0) != PAGE_SIZE) {
-+ blkmtd_write_out(bio);
-+ bio = NULL;
-+ goto retry;
-+ }
-+ return bio;
-+}
-+
-+
-+/**
-+ * write_pages - write block of data to device via the page cache
-+ * @dev: device to write to
-+ * @buf: data source or NULL if erase (output is set to 0xff)
-+ * @to: offset into output device
-+ * @len: amount to data to write
-+ * @retlen: amount of data written
-+ *
-+ * Grab pages from the page cache and fill them with the source data.
-+ * Non page aligned start and end result in a readin of the page and
-+ * part of the page being modified. Pages are added to the bio and then written
-+ * out.
-+ */
-+static int write_pages(struct blkmtd_dev *dev, const u_char *buf, loff_t to,
-+ size_t len, size_t *retlen)
-+{
-+ int pagenr, offset;
-+ size_t start_len = 0, end_len;
-+ int pagecnt = 0;
-+ int err = 0;
-+ struct bio *bio = NULL;
-+ size_t thislen = 0;
-+
-+ pagenr = to >> PAGE_SHIFT;
-+ offset = to & ~PAGE_MASK;
-+
-+ DEBUG(2, "blkmtd: write_pages: buf = %p to = %ld len = %d pagenr = %d offset = %d\n",
-+ buf, (long)to, len, pagenr, offset);
-+
-+ /* see if we have to do a partial write at the start */
-+ if(offset) {
-+ start_len = ((offset + len) > PAGE_SIZE) ? PAGE_SIZE - offset : len;
-+ len -= start_len;
-+ }
-+
-+ /* calculate the length of the other two regions */
-+ end_len = len & ~PAGE_MASK;
-+ len -= end_len;
-+
-+ if(start_len)
-+ pagecnt++;
-+
-+ if(len)
-+ pagecnt += len >> PAGE_SHIFT;
-+
-+ if(end_len)
-+ pagecnt++;
-+
-+ down(&dev->wrbuf_mutex);
-+
-+ DEBUG(3, "blkmtd: write: start_len = %d len = %d end_len = %d pagecnt = %d\n",
-+ start_len, len, end_len, pagecnt);
-+
-+ if(start_len) {
-+ /* do partial start region */
-+ struct page *page;
-+
-+ DEBUG(3, "blkmtd: write: doing partial start, page = %d len = %d offset = %d\n",
-+ pagenr, start_len, offset);
-+
-+ BUG_ON(!buf);
-+ page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev);
-+ lock_page(page);
-+ if(PageDirty(page)) {
-+ err("to = %lld start_len = %d len = %d end_len = %d pagenr = %d\n",
-+ to, start_len, len, end_len, pagenr);
-+ BUG();
-+ }
-+ memcpy(page_address(page)+offset, buf, start_len);
-+ SetPageDirty(page);
-+ SetPageUptodate(page);
-+ buf += start_len;
-+ thislen = start_len;
-+ bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt);
-+ if(!bio) {
-+ err = -ENOMEM;
-+ err("bio_add_page failed\n");
-+ goto write_err;
-+ }
-+ pagecnt--;
-+ pagenr++;
-+ }
-+
-+ /* Now do the main loop to a page aligned, n page sized output */
-+ if(len) {
-+ int pagesc = len >> PAGE_SHIFT;
-+ DEBUG(3, "blkmtd: write: whole pages start = %d, count = %d\n",
-+ pagenr, pagesc);
-+ while(pagesc) {
-+ struct page *page;
-+
-+ /* see if page is in the page cache */
-+ DEBUG(3, "blkmtd: write: grabbing page %d from page cache\n", pagenr);
-+ page = grab_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr);
-+ if(PageDirty(page)) {
-+ BUG();
-+ }
-+ if(!page) {
-+ warn("write: cannot grab cache page %d", pagenr);
-+ err = -ENOMEM;
-+ goto write_err;
-+ }
-+ if(!buf) {
-+ memset(page_address(page), 0xff, PAGE_SIZE);
-+ } else {
-+ memcpy(page_address(page), buf, PAGE_SIZE);
-+ buf += PAGE_SIZE;
-+ }
-+ bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt);
-+ if(!bio) {
-+ err = -ENOMEM;
-+ err("bio_add_page failed\n");
-+ goto write_err;
-+ }
-+ pagenr++;
-+ pagecnt--;
-+ SetPageDirty(page);
-+ SetPageUptodate(page);
-+ pagesc--;
-+ thislen += PAGE_SIZE;
-+ }
-+ }
-+
-+ if(end_len) {
-+ /* do the third region */
-+ struct page *page;
-+ DEBUG(3, "blkmtd: write: doing partial end, page = %d len = %d\n",
-+ pagenr, end_len);
-+ BUG_ON(!buf);
-+ page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev);
-+ lock_page(page);
-+ if(PageDirty(page)) {
-+ err("to = %lld start_len = %d len = %d end_len = %d pagenr = %d\n",
-+ to, start_len, len, end_len, pagenr);
-+ BUG();
-+ }
-+ memcpy(page_address(page), buf, end_len);
-+ SetPageDirty(page);
-+ SetPageUptodate(page);
-+ DEBUG(3, "blkmtd: write: writing out partial end\n");
-+ thislen += end_len;
-+ bio = blkmtd_add_page(bio, dev->blkdev, page, pagecnt);
-+ if(!bio) {
-+ err = -ENOMEM;
-+ err("bio_add_page failed\n");
-+ goto write_err;
-+ }
-+ pagenr++;
-+ }
-+
-+ DEBUG(3, "blkmtd: write: got %d vectors to write\n", bio->bi_vcnt);
-+ write_err:
-+ if(bio)
-+ blkmtd_write_out(bio);
-+
-+ DEBUG(2, "blkmtd: write: end, retlen = %d, err = %d\n", *retlen, err);
-+ up(&dev->wrbuf_mutex);
-+
-+ if(retlen)
-+ *retlen = thislen;
-+ return err;
-+}
-+
-+
-+/* erase a specified part of the device */
-+static int blkmtd_erase(struct mtd_info *mtd, struct erase_info *instr)
-+{
-+ struct blkmtd_dev *dev = mtd->priv;
-+ struct mtd_erase_region_info *einfo = mtd->eraseregions;
-+ int numregions = mtd->numeraseregions;
-+ size_t from;
-+ u_long len;
-+ int err = -EIO;
-+ int retlen;
-+
-+ instr->state = MTD_ERASING;
-+ from = instr->addr;
-+ len = instr->len;
-+
-+ /* check erase region has valid start and length */
-+ DEBUG(2, "blkmtd: erase: dev = `%s' from = 0x%x len = 0x%lx\n",
-+ mtd->name+9, from, len);
-+ while(numregions) {
-+ DEBUG(3, "blkmtd: checking erase region = 0x%08X size = 0x%X num = 0x%x\n",
-+ einfo->offset, einfo->erasesize, einfo->numblocks);
-+ if(from >= einfo->offset
-+ && from < einfo->offset + (einfo->erasesize * einfo->numblocks)) {
-+ if(len == einfo->erasesize
-+ && ( (from - einfo->offset) % einfo->erasesize == 0))
-+ break;
-+ }
-+ numregions--;
-+ einfo++;
-+ }
-+
-+ if(!numregions) {
-+ /* Not a valid erase block */
-+ err("erase: invalid erase request 0x%lX @ 0x%08X", len, from);
-+ instr->state = MTD_ERASE_FAILED;
-+ err = -EIO;
-+ }
-+
-+ if(instr->state != MTD_ERASE_FAILED) {
-+ /* do the erase */
-+ DEBUG(3, "Doing erase from = %d len = %ld\n", from, len);
-+ err = write_pages(dev, NULL, from, len, &retlen);
-+ if(err || retlen != len) {
-+ err("erase failed err = %d", err);
-+ instr->state = MTD_ERASE_FAILED;
-+ } else {
-+ instr->state = MTD_ERASE_DONE;
-+ }
-+ }
-+
-+ DEBUG(3, "blkmtd: erase: checking callback\n");
-+ if (instr->callback) {
-+ (*(instr->callback))(instr);
-+ }
-+ DEBUG(2, "blkmtd: erase: finished (err = %d)\n", err);
-+ return err;
-+}
-+
-+
-+/* read a range of the data via the page cache */
-+static int blkmtd_read(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t *retlen, u_char *buf)
-+{
-+ struct blkmtd_dev *dev = mtd->priv;
-+ int err = 0;
-+ int offset;
-+ int pagenr, pages;
-+ size_t thislen = 0;
-+
-+ DEBUG(2, "blkmtd: read: dev = `%s' from = %ld len = %d buf = %p\n",
-+ mtd->name+9, (long int)from, len, buf);
-+
-+ if(from > mtd->size)
-+ return -EINVAL;
-+ if(from + len > mtd->size)
-+ len = mtd->size - from;
-+
-+ pagenr = from >> PAGE_SHIFT;
-+ offset = from - (pagenr << PAGE_SHIFT);
-+
-+ pages = (offset+len+PAGE_SIZE-1) >> PAGE_SHIFT;
-+ DEBUG(3, "blkmtd: read: pagenr = %d offset = %d, pages = %d\n",
-+ pagenr, offset, pages);
-+
-+ while(pages) {
-+ struct page *page;
-+ int cpylen;
-+
-+ DEBUG(3, "blkmtd: read: looking for page: %d\n", pagenr);
-+ page = read_cache_page(dev->blkdev->bd_inode->i_mapping, pagenr, (filler_t *)blkmtd_readpage, dev);
-+ if(IS_ERR(page)) {
-+ err = -EIO;
-+ goto readerr;
-+ }
-+
-+ cpylen = (PAGE_SIZE > len) ? len : PAGE_SIZE;
-+ if(offset+cpylen > PAGE_SIZE)
-+ cpylen = PAGE_SIZE-offset;
-+
-+ memcpy(buf + thislen, page_address(page) + offset, cpylen);
-+ offset = 0;
-+ len -= cpylen;
-+ thislen += cpylen;
-+ pagenr++;
-+ pages--;
-+ if(!PageDirty(page))
-+ page_cache_release(page);
-+ }
-+
-+ readerr:
-+ if(retlen)
-+ *retlen = thislen;
-+ DEBUG(2, "blkmtd: end read: retlen = %d, err = %d\n", thislen, err);
-+ return err;
-+}
-+
-+
-+/* write data to the underlying device */
-+static int blkmtd_write(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf)
-+{
-+ struct blkmtd_dev *dev = mtd->priv;
-+ int err;
-+
-+ if(!len)
-+ return 0;
-+
-+ DEBUG(2, "blkmtd: write: dev = `%s' to = %ld len = %d buf = %p\n",
-+ mtd->name+9, (long int)to, len, buf);
-+
-+ if(to >= mtd->size) {
-+ return -ENOSPC;
-+ }
-+
-+ if(to + len > mtd->size) {
-+ len = mtd->size - to;
-+ }
-+
-+ err = write_pages(dev, buf, to, len, retlen);
-+ if(err > 0)
-+ err = 0;
-+ DEBUG(2, "blkmtd: write: end, err = %d\n", err);
-+ return err;
-+}
-+
-+
-+/* sync the device - wait until the write queue is empty */
-+static void blkmtd_sync(struct mtd_info *mtd)
-+{
-+ /* Currently all writes are synchronous */
-+}
-+
-+
-+static void free_device(struct blkmtd_dev *dev)
-+{
-+ DEBUG(2, "blkmtd: free_device() dev = %p\n", dev);
-+ if(dev) {
-+ if(dev->mtd_info.eraseregions)
-+ kfree(dev->mtd_info.eraseregions);
-+ if(dev->mtd_info.name)
-+ kfree(dev->mtd_info.name);
-+
-+ if(dev->blkdev) {
-+ invalidate_inode_pages(dev->blkdev->bd_inode->i_mapping);
-+ close_bdev_excl(dev->blkdev, BDEV_RAW);
-+ }
-+ kfree(dev);
-+ }
-+}
-+
-+
-+/* For a given size and initial erase size, calculate the number
-+ * and size of each erase region. Goes round the loop twice,
-+ * once to find out how many regions, then allocates space,
-+ * then round the loop again to fill it in.
-+ */
-+static struct mtd_erase_region_info *calc_erase_regions(
-+ size_t erase_size, size_t total_size, int *regions)
-+{
-+ struct mtd_erase_region_info *info = NULL;
-+
-+ DEBUG(2, "calc_erase_regions, es = %d size = %d regions = %d\n",
-+ erase_size, total_size, *regions);
-+ /* Make any user specified erasesize be a power of 2
-+ and at least PAGE_SIZE */
-+ if(erase_size) {
-+ int es = erase_size;
-+ erase_size = 1;
-+ while(es != 1) {
-+ es >>= 1;
-+ erase_size <<= 1;
-+ }
-+ if(erase_size < PAGE_SIZE)
-+ erase_size = PAGE_SIZE;
-+ } else {
-+ erase_size = CONFIG_MTD_BLKDEV_ERASESIZE;
-+ }
-+
-+ *regions = 0;
-+
-+ do {
-+ int tot_size = total_size;
-+ int er_size = erase_size;
-+ int count = 0, offset = 0, regcnt = 0;
-+
-+ while(tot_size) {
-+ count = tot_size / er_size;
-+ if(count) {
-+ tot_size = tot_size % er_size;
-+ if(info) {
-+ DEBUG(2, "adding to erase info off=%d er=%d cnt=%d\n",
-+ offset, er_size, count);
-+ (info+regcnt)->offset = offset;
-+ (info+regcnt)->erasesize = er_size;
-+ (info+regcnt)->numblocks = count;
-+ (*regions)++;
-+ }
-+ regcnt++;
-+ offset += (count * er_size);
-+ }
-+ while(er_size > tot_size)
-+ er_size >>= 1;
-+ }
-+ if(info == NULL) {
-+ info = kmalloc(regcnt * sizeof(struct mtd_erase_region_info), GFP_KERNEL);
-+ if(!info)
-+ break;
-+ }
-+ } while(!(*regions));
-+ DEBUG(2, "calc_erase_regions done, es = %d size = %d regions = %d\n",
-+ erase_size, total_size, *regions);
-+ return info;
-+}
-+
-+
-+extern dev_t __init name_to_dev_t(const char *line);
-+
-+static struct blkmtd_dev *add_device(char *devname, int readonly, int erase_size)
-+{
-+ struct block_device *bdev;
-+ int mode;
-+ struct blkmtd_dev *dev;
-+
-+ if(!devname)
-+ return NULL;
-+
-+ /* Get a handle on the device */
-+
-+
-+#ifdef MODULE
-+ mode = (readonly) ? O_RDONLY : O_RDWR;
-+ bdev = open_bdev_excl(devname, mode, BDEV_RAW, NULL);
-+#else
-+ mode = (readonly) ? FMODE_READ : FMODE_WRITE;
-+ bdev = open_by_devnum(name_to_dev_t(devname), mode, BDEV_RAW);
-+#endif
-+ if(IS_ERR(bdev)) {
-+ err("error: cannot open device %s", devname);
-+ DEBUG(2, "blkmtd: opening bdev returned %ld\n", PTR_ERR(bdev));
-+ return NULL;
-+ }
-+
-+ DEBUG(1, "blkmtd: found a block device major = %d, minor = %d\n",
-+ MAJOR(bdev->bd_dev), MINOR(bdev->bd_dev));
-+
-+ if(MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
-+ err("attempting to use an MTD device as a block device");
-+ blkdev_put(bdev, BDEV_RAW);
-+ return NULL;
-+ }
-+
-+ dev = kmalloc(sizeof(struct blkmtd_dev), GFP_KERNEL);
-+ if(dev == NULL) {
-+ blkdev_put(bdev, BDEV_RAW);
-+ return NULL;
-+ }
-+
-+ memset(dev, 0, sizeof(struct blkmtd_dev));
-+ if(!readonly) {
-+ init_MUTEX(&dev->wrbuf_mutex);
-+ }
-+
-+ dev->blkdev = bdev;
-+ dev->mtd_info.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
-+
-+ /* Setup the MTD structure */
-+ /* make the name contain the block device in */
-+ dev->mtd_info.name = kmalloc(sizeof("blkmtd: ") + strlen(devname), GFP_KERNEL);
-+ if(dev->mtd_info.name == NULL)
-+ goto devinit_err;
-+
-+ sprintf(dev->mtd_info.name, "blkmtd: %s", devname);
-+ dev->mtd_info.eraseregions = calc_erase_regions(erase_size, dev->mtd_info.size,
-+ &dev->mtd_info.numeraseregions);
-+ if(dev->mtd_info.eraseregions == NULL)
-+ goto devinit_err;
-+
-+ dev->mtd_info.erasesize = dev->mtd_info.eraseregions->erasesize;
-+ DEBUG(1, "blkmtd: init: found %d erase regions\n",
-+ dev->mtd_info.numeraseregions);
-+
-+ if(readonly) {
-+ dev->mtd_info.type = MTD_ROM;
-+ dev->mtd_info.flags = MTD_CAP_ROM;
-+ } else {
-+ dev->mtd_info.type = MTD_RAM;
-+ dev->mtd_info.flags = MTD_CAP_RAM;
-+ dev->mtd_info.erase = blkmtd_erase;
-+ dev->mtd_info.write = blkmtd_write;
-+ dev->mtd_info.writev = default_mtd_writev;
-+ dev->mtd_info.sync = blkmtd_sync;
-+ }
-+ dev->mtd_info.read = blkmtd_read;
-+ dev->mtd_info.readv = default_mtd_readv;
-+ dev->mtd_info.priv = dev;
-+ dev->mtd_info.owner = THIS_MODULE;
-+
-+ list_add(&dev->list, &blkmtd_device_list);
-+ if (add_mtd_device(&dev->mtd_info)) {
-+ /* Device didnt get added, so free the entry */
-+ list_del(&dev->list);
-+ goto devinit_err;
-+ } else {
-+ info("mtd%d: [%s] erase_size = %dKiB %s",
-+ dev->mtd_info.index, dev->mtd_info.name + strlen("blkmtd: "),
-+ dev->mtd_info.erasesize >> 10,
-+ readonly ? "(read-only)" : "");
-+ }
-+
-+ return dev;
-+
-+ devinit_err:
-+ free_device(dev);
-+ return NULL;
-+}
-+
-+
-+/* Cleanup and exit - sync the device and kill of the kernel thread */
-+static void __devexit cleanup_blkmtd(void)
-+{
-+ struct list_head *temp1, *temp2;
-+
-+ /* Remove the MTD devices */
-+ list_for_each_safe(temp1, temp2, &blkmtd_device_list) {
-+ struct blkmtd_dev *dev = list_entry(temp1, struct blkmtd_dev,
-+ list);
-+ blkmtd_sync(&dev->mtd_info);
-+ del_mtd_device(&dev->mtd_info);
-+ info("mtd%d: [%s] removed", dev->mtd_info.index,
-+ dev->mtd_info.name + strlen("blkmtd: "));
-+ list_del(&dev->list);
-+ free_device(dev);
-+ }
-+}
-+
-+#ifndef MODULE
-+
-+/* Handle kernel boot params */
-+
-+
-+static int __init param_blkmtd_device(char *str)
-+{
-+ int i;
-+
-+ for(i = 0; i < MAX_DEVICES; i++) {
-+ device[i] = str;
-+ DEBUG(2, "blkmtd: device setup: %d = %s\n", i, device[i]);
-+ strsep(&str, ",");
-+ }
-+ return 1;
-+}
-+
-+
-+static int __init param_blkmtd_erasesz(char *str)
-+{
-+ int i;
-+ for(i = 0; i < MAX_DEVICES; i++) {
-+ char *val = strsep(&str, ",");
-+ if(val)
-+ erasesz[i] = simple_strtoul(val, NULL, 0);
-+ DEBUG(2, "blkmtd: erasesz setup: %d = %d\n", i, erasesz[i]);
-+ }
-+
-+ return 1;
-+}
-+
-+
-+static int __init param_blkmtd_ro(char *str)
-+{
-+ int i;
-+ for(i = 0; i < MAX_DEVICES; i++) {
-+ char *val = strsep(&str, ",");
-+ if(val)
-+ ro[i] = simple_strtoul(val, NULL, 0);
-+ DEBUG(2, "blkmtd: ro setup: %d = %d\n", i, ro[i]);
-+ }
-+
-+ return 1;
-+}
-+
-+
-+static int __init param_blkmtd_sync(char *str)
-+{
-+ if(str[0] == '1')
-+ sync = 1;
-+ return 1;
-+}
-+
-+__setup("blkmtd_device=", param_blkmtd_device);
-+__setup("blkmtd_erasesz=", param_blkmtd_erasesz);
-+__setup("blkmtd_ro=", param_blkmtd_ro);
-+__setup("blkmtd_sync=", param_blkmtd_sync);
-+
-+#endif
-+
-+
-+/* Startup */
-+static int __init init_blkmtd(void)
-+{
-+ int i;
-+
-+ info("version " VERSION);
-+ /* Check args - device[0] is the bare minimum*/
-+ if(!device[0]) {
-+ err("error: missing `device' name\n");
-+ return -EINVAL;
-+ }
-+
-+ for(i = 0; i < MAX_DEVICES; i++)
-+ add_device(device[i], ro[i], erasesz[i] << 10);
-+
-+ if(list_empty(&blkmtd_device_list))
-+ return -EINVAL;
-+
-+ return 0;
-+}
-+
-+module_init(init_blkmtd);
-+module_exit(cleanup_blkmtd);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/blkmtd.c linux/drivers/mtd/devices/blkmtd.c
---- linux-mips-2.4.27/drivers/mtd/devices/blkmtd.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/devices/blkmtd.c 2004-11-19 10:25:11.816212408 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * blkmtd.c - use a block device as a fake MTD
- *
-@@ -143,7 +143,7 @@
- for(cnt = 0; cnt < pages; cnt++) {
- page = grab_cache_page(dev->binding->bd_inode->i_mapping, pagenrs[cnt]);
- pagelst[cnt] = page;
-- if(!PageUptodate(page)) {
-+ if(!Page_Uptodate(page)) {
- iobuf->blocks[iobuf->nr_pages] = pagenrs[cnt];
- iobuf->maplist[iobuf->nr_pages++] = page;
- }
-@@ -912,7 +912,7 @@
- dev->mtd_info.point = 0;
- dev->mtd_info.unpoint = 0;
- dev->mtd_info.priv = dev;
-- dev->mtd_info.module = THIS_MODULE;
-+ dev->mtd_info.owner = THIS_MODULE;
-
- list_add(&dev->list, &blkmtd_device_list);
- if (add_mtd_device(&dev->mtd_info)) {
-diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/doc2000.c linux/drivers/mtd/devices/doc2000.c
---- linux-mips-2.4.27/drivers/mtd/devices/doc2000.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/devices/doc2000.c 2004-11-19 10:25:11.818212104 +0100
-@@ -4,7 +4,7 @@
- * (c) 1999 Machine Vision Holdings, Inc.
- * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/kernel.h>
-@@ -25,6 +25,7 @@
- #include <linux/mtd/doc2000.h>
-
- #define DOC_SUPPORT_2000
-+#define DOC_SUPPORT_2000TSOP
- #define DOC_SUPPORT_MILLENNIUM
-
- #ifdef DOC_SUPPORT_2000
-@@ -33,7 +34,7 @@
- #define DoC_is_2000(doc) (0)
- #endif
-
--#ifdef DOC_SUPPORT_MILLENNIUM
-+#if defined(DOC_SUPPORT_2000TSOP) || defined(DOC_SUPPORT_MILLENNIUM)
- #define DoC_is_Millennium(doc) (doc->ChipID == DOC_ChipID_DocMil)
- #else
- #define DoC_is_Millennium(doc) (0)
-@@ -56,6 +57,9 @@
- size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel);
- static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
- size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel);
-+static int doc_writev_ecc(struct mtd_info *mtd, const struct iovec *vecs,
-+ unsigned long count, loff_t to, size_t *retlen,
-+ u_char *eccbuf, struct nand_oobinfo *oobsel);
- static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
- size_t *retlen, u_char *buf);
- static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-@@ -92,6 +96,10 @@
-
- /* Out-of-line routine to wait for chip response */
- while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
-+ /* issue 2 read from NOP register after reading from CDSNControl register
-+ see Software Requirement 11.4 item 2. */
-+ DoC_Delay(doc, 2);
-+
- if (time_after(jiffies, timeo)) {
- DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
- return -EIO;
-@@ -145,6 +153,8 @@
-
- /* Send the command */
- WriteDOC_(command, docptr, doc->ioreg);
-+ if (DoC_is_Millennium(doc))
-+ WriteDOC(command, docptr, WritePipeTerm);
-
- /* Lower the CLE line */
- WriteDOC(xtraflags | CDSN_CTRL_CE, docptr, CDSNControl);
-@@ -206,6 +216,9 @@
- }
- }
-
-+ if (DoC_is_Millennium(doc))
-+ WriteDOC(ofs & 0xff, docptr, WritePipeTerm);
-+
- DoC_Delay(doc, 2); /* Needed for some slow flash chips. mf. */
-
- /* FIXME: The SlowIO's for millennium could be replaced by
-@@ -344,15 +357,25 @@
-
- /* Read the manufacturer and device id codes from the device */
-
-- /* CDSN Slow IO register see Software Requirement 11.4 item 5. */
-+ if (DoC_is_Millennium(doc)) {
-+ DoC_Delay(doc, 2);
-+ dummy = ReadDOC(doc->virtadr, ReadPipeInit);
-+ mfr = ReadDOC(doc->virtadr, LastDataRead);
-+
-+ DoC_Delay(doc, 2);
-+ dummy = ReadDOC(doc->virtadr, ReadPipeInit);
-+ id = ReadDOC(doc->virtadr, LastDataRead);
-+ } else {
-+ /* CDSN Slow IO register see Software Req 11.4 item 5. */
- dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
- DoC_Delay(doc, 2);
- mfr = ReadDOC_(doc->virtadr, doc->ioreg);
-
-- /* CDSN Slow IO register see Software Requirement 11.4 item 5. */
-+ /* CDSN Slow IO register see Software Req 11.4 item 5. */
- dummy = ReadDOC(doc->virtadr, CDSNSlowIO);
- DoC_Delay(doc, 2);
- id = ReadDOC_(doc->virtadr, doc->ioreg);
-+ }
-
- /* No response - return failure */
- if (mfr == 0xff || mfr == 0)
-@@ -410,20 +433,16 @@
-
- /* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
-
--static void DoC_ScanChips(struct DiskOnChip *this)
-+static void DoC_ScanChips(struct DiskOnChip *this, int maxchips)
- {
- int floor, chip;
- int numchips[MAX_FLOORS];
-- int maxchips = MAX_CHIPS;
- int ret = 1;
-
- this->numchips = 0;
- this->mfr = 0;
- this->id = 0;
-
-- if (DoC_is_Millennium(this))
-- maxchips = MAX_CHIPS_MIL;
--
- /* For each floor, find the number of valid chips it contains */
- for (floor = 0; floor < MAX_FLOORS; floor++) {
- ret = 1;
-@@ -515,6 +534,7 @@
- {
- struct DiskOnChip *this = (struct DiskOnChip *) mtd->priv;
- struct DiskOnChip *old = NULL;
-+ int maxchips;
-
- /* We must avoid being called twice for the same device. */
-
-@@ -538,14 +558,28 @@
-
-
- switch (this->ChipID) {
-+ case DOC_ChipID_Doc2kTSOP:
-+ mtd->name = "DiskOnChip 2000 TSOP";
-+ this->ioreg = DoC_Mil_CDSN_IO;
-+ /* Pretend it's a Millennium */
-+ this->ChipID = DOC_ChipID_DocMil;
-+ maxchips = MAX_CHIPS;
-+ break;
- case DOC_ChipID_Doc2k:
- mtd->name = "DiskOnChip 2000";
- this->ioreg = DoC_2k_CDSN_IO;
-+ maxchips = MAX_CHIPS;
- break;
- case DOC_ChipID_DocMil:
- mtd->name = "DiskOnChip Millennium";
- this->ioreg = DoC_Mil_CDSN_IO;
-+ maxchips = MAX_CHIPS_MIL;
- break;
-+ default:
-+ printk("Unknown ChipID 0x%02x\n", this->ChipID);
-+ kfree(mtd);
-+ iounmap((void *) this->virtadr);
-+ return;
- }
-
- printk(KERN_NOTICE "%s found at address 0x%lX\n", mtd->name,
-@@ -553,11 +587,12 @@
-
- mtd->type = MTD_NANDFLASH;
- mtd->flags = MTD_CAP_NANDFLASH;
-+ mtd->ecctype = MTD_ECC_RS_DiskOnChip;
- mtd->size = 0;
- mtd->erasesize = 0;
- mtd->oobblock = 512;
- mtd->oobsize = 16;
-- mtd->module = THIS_MODULE;
-+ mtd->owner = THIS_MODULE;
- mtd->erase = doc_erase;
- mtd->point = NULL;
- mtd->unpoint = NULL;
-@@ -565,6 +600,7 @@
- mtd->write = doc_write;
- mtd->read_ecc = doc_read_ecc;
- mtd->write_ecc = doc_write_ecc;
-+ mtd->writev_ecc = doc_writev_ecc;
- mtd->read_oob = doc_read_oob;
- mtd->write_oob = doc_write_oob;
- mtd->sync = NULL;
-@@ -577,7 +613,7 @@
- init_MUTEX(&this->lock);
-
- /* Ident all the chips present. */
-- DoC_ScanChips(this);
-+ DoC_ScanChips(this, maxchips);
-
- if (!this->totlen) {
- kfree(mtd);
-@@ -608,6 +644,7 @@
- unsigned char syndrome[6];
- volatile char dummy;
- int i, len256 = 0, ret=0;
-+ size_t left = len;
-
- docptr = this->virtadr;
-
-@@ -617,6 +654,10 @@
-
- down(&this->lock);
-
-+ *retlen = 0;
-+ while (left) {
-+ len = left;
-+
- /* Don't allow a single read to cross a 512-byte block boundary */
- if (from + len > ((from | 0x1ff) + 1))
- len = ((from | 0x1ff) + 1) - from;
-@@ -673,7 +714,7 @@
- DoC_ReadBuf(this, &buf[len256], len - len256);
-
- /* Let the caller know we completed it */
-- *retlen = len;
-+ *retlen += len;
-
- if (eccbuf) {
- /* Read the ECC data through the DiskOnChip ECC logic */
-@@ -730,11 +771,16 @@
-
- /* according to 11.4.1, we need to wait for the busy line
- * drop if we read to the end of the page. */
-- if(0 == ((from + *retlen) & 0x1ff))
-+ if(0 == ((from + len) & 0x1ff))
- {
- DoC_WaitReady(this);
- }
-
-+ from += len;
-+ left -= len;
-+ buf += len;
-+ }
-+
- up(&this->lock);
-
- return ret;
-@@ -757,6 +803,8 @@
- volatile char dummy;
- int len256 = 0;
- struct Nand *mychip;
-+ size_t left = len;
-+ int status;
-
- docptr = this->virtadr;
-
-@@ -766,15 +814,21 @@
-
- down(&this->lock);
-
-+ *retlen = 0;
-+ while (left) {
-+ len = left;
-+
- /* Don't allow a single write to cross a 512-byte block boundary */
- if (to + len > ((to | 0x1ff) + 1))
- len = ((to | 0x1ff) + 1) - to;
-
- /* The ECC will not be calculated correctly if less than 512 is written */
-+/* DBB-
- if (len != 0x200 && eccbuf)
- printk(KERN_WARNING
- "ECC needs a full sector write (adr: %lx size %lx)\n",
- (long) to, (long) len);
-+ -DBB */
-
- /* printk("DoC_Write (adr: %lx size %lx)\n", (long) to, (long) len); */
-
-@@ -853,6 +907,9 @@
- WriteDOC_(0, docptr, this->ioreg);
- }
-
-+ WriteDOC(CDSN_CTRL_ECC_IO | CDSN_CTRL_FLASH_IO | CDSN_CTRL_CE, docptr,
-+ CDSNControl);
-+
- /* Read the ECC data through the DiskOnChip ECC logic */
- for (di = 0; di < 6; di++) {
- eccbuf[di] = ReadDOC(docptr, ECCSyndrome0 + di);
-@@ -874,10 +931,16 @@
- DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
- /* There's an implicit DoC_WaitReady() in DoC_Command */
-
-+ if (DoC_is_Millennium(this)) {
-+ ReadDOC(docptr, ReadPipeInit);
-+ status = ReadDOC(docptr, LastDataRead);
-+ } else {
- dummy = ReadDOC(docptr, CDSNSlowIO);
- DoC_Delay(this, 2);
-+ status = ReadDOC_(docptr, this->ioreg);
-+ }
-
-- if (ReadDOC_(docptr, this->ioreg) & 1) {
-+ if (status & 1) {
- printk(KERN_ERR "Error programming flash\n");
- /* Error in programming */
- *retlen = 0;
-@@ -886,7 +949,7 @@
- }
-
- /* Let the caller know we completed it */
-- *retlen = len;
-+ *retlen += len;
-
- if (eccbuf) {
- unsigned char x[8];
-@@ -901,13 +964,81 @@
- x[7]=0x55;
-
- ret = doc_write_oob_nolock(mtd, to, 8, &dummy, x);
-+ if (ret) {
- up(&this->lock);
- return ret;
- }
-+ }
-+
-+ to += len;
-+ left -= len;
-+ buf += len;
-+ }
-+
- up(&this->lock);
- return 0;
- }
-
-+static int doc_writev_ecc(struct mtd_info *mtd, const struct iovec *vecs,
-+ unsigned long count, loff_t to, size_t *retlen,
-+ u_char *eccbuf, struct nand_oobinfo *oobsel)
-+{
-+ static char static_buf[512];
-+ static DECLARE_MUTEX(writev_buf_sem);
-+
-+ size_t totretlen = 0;
-+ size_t thisvecofs = 0;
-+ int ret= 0;
-+
-+ down(&writev_buf_sem);
-+
-+ while(count) {
-+ size_t thislen, thisretlen;
-+ unsigned char *buf;
-+
-+ buf = vecs->iov_base + thisvecofs;
-+ thislen = vecs->iov_len - thisvecofs;
-+
-+
-+ if (thislen >= 512) {
-+ thislen = thislen & ~(512-1);
-+ thisvecofs += thislen;
-+ } else {
-+ /* Not enough to fill a page. Copy into buf */
-+ memcpy(static_buf, buf, thislen);
-+ buf = &static_buf[thislen];
-+
-+ while(count && thislen < 512) {
-+ vecs++;
-+ count--;
-+ thisvecofs = min((512-thislen), vecs->iov_len);
-+ memcpy(buf, vecs->iov_base, thisvecofs);
-+ thislen += thisvecofs;
-+ buf += thisvecofs;
-+ }
-+ buf = static_buf;
-+ }
-+ if (count && thisvecofs == vecs->iov_len) {
-+ thisvecofs = 0;
-+ vecs++;
-+ count--;
-+ }
-+ ret = doc_write_ecc(mtd, to, thislen, &thisretlen, buf, eccbuf, oobsel);
-+
-+ totretlen += thisretlen;
-+
-+ if (ret || thisretlen != thislen)
-+ break;
-+
-+ to += thislen;
-+ }
-+
-+ up(&writev_buf_sem);
-+ *retlen = totretlen;
-+ return ret;
-+}
-+
-+
- static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
- size_t * retlen, u_char * buf)
- {
-@@ -977,6 +1108,7 @@
- unsigned long docptr = this->virtadr;
- struct Nand *mychip = &this->chips[ofs >> this->chipshift];
- volatile int dummy;
-+ int status;
-
- // printk("doc_write_oob(%lx, %d): %2.2X %2.2X %2.2X %2.2X ... %2.2X %2.2X .. %2.2X %2.2X\n",(long)ofs, len,
- // buf[0], buf[1], buf[2], buf[3], buf[8], buf[9], buf[14],buf[15]);
-@@ -1025,10 +1157,16 @@
- DoC_Command(this, NAND_CMD_STATUS, 0);
- /* DoC_WaitReady() is implicit in DoC_Command */
-
-+ if (DoC_is_Millennium(this)) {
-+ ReadDOC(docptr, ReadPipeInit);
-+ status = ReadDOC(docptr, LastDataRead);
-+ } else {
- dummy = ReadDOC(docptr, CDSNSlowIO);
- DoC_Delay(this, 2);
-+ status = ReadDOC_(docptr, this->ioreg);
-+ }
-
-- if (ReadDOC_(docptr, this->ioreg) & 1) {
-+ if (status & 1) {
- printk(KERN_ERR "Error programming oob data\n");
- /* There was an error */
- *retlen = 0;
-@@ -1044,10 +1182,16 @@
- DoC_Command(this, NAND_CMD_STATUS, 0);
- /* DoC_WaitReady() is implicit in DoC_Command */
-
-+ if (DoC_is_Millennium(this)) {
-+ ReadDOC(docptr, ReadPipeInit);
-+ status = ReadDOC(docptr, LastDataRead);
-+ } else {
- dummy = ReadDOC(docptr, CDSNSlowIO);
- DoC_Delay(this, 2);
-+ status = ReadDOC_(docptr, this->ioreg);
-+ }
-
-- if (ReadDOC_(docptr, this->ioreg) & 1) {
-+ if (status & 1) {
- printk(KERN_ERR "Error programming oob data\n");
- /* There was an error */
- *retlen = 0;
-@@ -1080,6 +1224,7 @@
- volatile int dummy;
- unsigned long docptr;
- struct Nand *mychip;
-+ int status;
-
- down(&this->lock);
-
-@@ -1111,10 +1256,16 @@
-
- DoC_Command(this, NAND_CMD_STATUS, CDSN_CTRL_WP);
-
-+ if (DoC_is_Millennium(this)) {
-+ ReadDOC(docptr, ReadPipeInit);
-+ status = ReadDOC(docptr, LastDataRead);
-+ } else {
- dummy = ReadDOC(docptr, CDSNSlowIO);
- DoC_Delay(this, 2);
-+ status = ReadDOC_(docptr, this->ioreg);
-+ }
-
-- if (ReadDOC_(docptr, this->ioreg) & 1) {
-+ if (status & 1) {
- printk(KERN_ERR "Error erasing at 0x%x\n", ofs);
- /* There was an error */
- instr->state = MTD_ERASE_FAILED;
-diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/doc2001.c linux/drivers/mtd/devices/doc2001.c
---- linux-mips-2.4.27/drivers/mtd/devices/doc2001.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/devices/doc2001.c 2004-11-19 10:25:11.835209520 +0100
-@@ -4,7 +4,7 @@
- * (c) 1999 Machine Vision Holdings, Inc.
- * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/kernel.h>
-@@ -359,14 +359,15 @@
-
- mtd->type = MTD_NANDFLASH;
- mtd->flags = MTD_CAP_NANDFLASH;
-+ mtd->ecctype = MTD_ECC_RS_DiskOnChip;
- mtd->size = 0;
-
-- /* FIXME: erase size is not always 8kB */
-+ /* FIXME: erase size is not always 8KiB */
- mtd->erasesize = 0x2000;
-
- mtd->oobblock = 512;
- mtd->oobsize = 16;
-- mtd->module = THIS_MODULE;
-+ mtd->owner = THIS_MODULE;
- mtd->erase = doc_erase;
- mtd->point = NULL;
- mtd->unpoint = NULL;
-diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/doc2001plus.c linux/drivers/mtd/devices/doc2001plus.c
---- linux-mips-2.4.27/drivers/mtd/devices/doc2001plus.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/devices/doc2001plus.c 2004-11-19 10:25:11.837209216 +0100
-@@ -0,0 +1,1154 @@
-+/*
-+ * Linux driver for Disk-On-Chip Millennium Plus
-+ *
-+ * (c) 2002-2003 Greg Ungerer <gerg@snapgear.com>
-+ * (c) 2002-2003 SnapGear Inc
-+ * (c) 1999 Machine Vision Holdings, Inc.
-+ * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
-+ *
-+ * $Id$
-+ *
-+ * Released under GPL
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <asm/errno.h>
-+#include <asm/io.h>
-+#include <asm/uaccess.h>
-+#include <linux/miscdevice.h>
-+#include <linux/pci.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/doc2000.h>
-+
-+/* #define ECC_DEBUG */
-+
-+/* I have no idea why some DoC chips can not use memcop_form|to_io().
-+ * This may be due to the different revisions of the ASIC controller built-in or
-+ * simplily a QA/Bug issue. Who knows ?? If you have trouble, please uncomment
-+ * this:*/
-+#undef USE_MEMCPY
-+
-+static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t *retlen, u_char *buf);
-+static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf);
-+static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t *retlen, u_char *buf, u_char *eccbuf,
-+ struct nand_oobinfo *oobsel);
-+static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf, u_char *eccbuf,
-+ struct nand_oobinfo *oobsel);
-+static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-+ size_t *retlen, u_char *buf);
-+static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-+ size_t *retlen, const u_char *buf);
-+static int doc_erase (struct mtd_info *mtd, struct erase_info *instr);
-+
-+static struct mtd_info *docmilpluslist = NULL;
-+
-+
-+/* Perform the required delay cycles by writing to the NOP register */
-+static void DoC_Delay(unsigned long docptr, int cycles)
-+{
-+ int i;
-+
-+ for (i = 0; (i < cycles); i++)
-+ WriteDOC(0, docptr, Mplus_NOP);
-+}
-+
-+#define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1)
-+
-+/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
-+static int _DoC_WaitReady(unsigned long docptr)
-+{
-+ unsigned int c = 0xffff;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3,
-+ "_DoC_WaitReady called for out-of-line wait\n");
-+
-+ /* Out-of-line routine to wait for chip response */
-+ while (((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK) && --c)
-+ ;
-+
-+ if (c == 0)
-+ DEBUG(MTD_DEBUG_LEVEL2, "_DoC_WaitReady timed out.\n");
-+
-+ return (c == 0);
-+}
-+
-+static inline int DoC_WaitReady(unsigned long docptr)
-+{
-+ /* This is inline, to optimise the common case, where it's ready instantly */
-+ int ret = 0;
-+
-+ /* read form NOP register should be issued prior to the read from CDSNControl
-+ see Software Requirement 11.4 item 2. */
-+ DoC_Delay(docptr, 4);
-+
-+ if ((ReadDOC(docptr, Mplus_FlashControl) & CDSN_CTRL_FR_B_MASK) != CDSN_CTRL_FR_B_MASK)
-+ /* Call the out-of-line routine to wait */
-+ ret = _DoC_WaitReady(docptr);
-+
-+ return ret;
-+}
-+
-+/* For some reason the Millennium Plus seems to occassionally put itself
-+ * into reset mode. For me this happens randomly, with no pattern that I
-+ * can detect. M-systems suggest always check this on any block level
-+ * operation and setting to normal mode if in reset mode.
-+ */
-+static inline void DoC_CheckASIC(unsigned long docptr)
-+{
-+ /* Make sure the DoC is in normal mode */
-+ if ((ReadDOC(docptr, Mplus_DOCControl) & DOC_MODE_NORMAL) == 0) {
-+ WriteDOC((DOC_MODE_NORMAL | DOC_MODE_MDWREN), docptr, Mplus_DOCControl);
-+ WriteDOC(~(DOC_MODE_NORMAL | DOC_MODE_MDWREN), docptr, Mplus_CtrlConfirm);
-+ }
-+}
-+
-+/* DoC_Command: Send a flash command to the flash chip through the Flash
-+ * command register. Need 2 Write Pipeline Terminates to complete send.
-+ */
-+static inline void DoC_Command(unsigned long docptr, unsigned char command,
-+ unsigned char xtraflags)
-+{
-+ WriteDOC(command, docptr, Mplus_FlashCmd);
-+ WriteDOC(command, docptr, Mplus_WritePipeTerm);
-+ WriteDOC(command, docptr, Mplus_WritePipeTerm);
-+}
-+
-+/* DoC_Address: Set the current address for the flash chip through the Flash
-+ * Address register. Need 2 Write Pipeline Terminates to complete send.
-+ */
-+static inline void DoC_Address(struct DiskOnChip *doc, int numbytes,
-+ unsigned long ofs, unsigned char xtraflags1,
-+ unsigned char xtraflags2)
-+{
-+ unsigned long docptr = doc->virtadr;
-+
-+ /* Allow for possible Mill Plus internal flash interleaving */
-+ ofs >>= doc->interleave;
-+
-+ switch (numbytes) {
-+ case 1:
-+ /* Send single byte, bits 0-7. */
-+ WriteDOC(ofs & 0xff, docptr, Mplus_FlashAddress);
-+ break;
-+ case 2:
-+ /* Send bits 9-16 followed by 17-23 */
-+ WriteDOC((ofs >> 9) & 0xff, docptr, Mplus_FlashAddress);
-+ WriteDOC((ofs >> 17) & 0xff, docptr, Mplus_FlashAddress);
-+ break;
-+ case 3:
-+ /* Send 0-7, 9-16, then 17-23 */
-+ WriteDOC(ofs & 0xff, docptr, Mplus_FlashAddress);
-+ WriteDOC((ofs >> 9) & 0xff, docptr, Mplus_FlashAddress);
-+ WriteDOC((ofs >> 17) & 0xff, docptr, Mplus_FlashAddress);
-+ break;
-+ default:
-+ return;
-+ }
-+
-+ WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-+ WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-+}
-+
-+/* DoC_SelectChip: Select a given flash chip within the current floor */
-+static int DoC_SelectChip(unsigned long docptr, int chip)
-+{
-+ /* No choice for flash chip on Millennium Plus */
-+ return 0;
-+}
-+
-+/* DoC_SelectFloor: Select a given floor (bank of flash chips) */
-+static int DoC_SelectFloor(unsigned long docptr, int floor)
-+{
-+ WriteDOC((floor & 0x3), docptr, Mplus_DeviceSelect);
-+ return 0;
-+}
-+
-+/*
-+ * Translate the given offset into the appropriate command and offset.
-+ * This does the mapping using the 16bit interleave layout defined by
-+ * M-Systems, and looks like this for a sector pair:
-+ * +-----------+-------+-------+-------+--------------+---------+-----------+
-+ * | 0 --- 511 |512-517|518-519|520-521| 522 --- 1033 |1034-1039|1040 - 1055|
-+ * +-----------+-------+-------+-------+--------------+---------+-----------+
-+ * | Data 0 | ECC 0 |Flags0 |Flags1 | Data 1 |ECC 1 | OOB 1 + 2 |
-+ * +-----------+-------+-------+-------+--------------+---------+-----------+
-+ */
-+/* FIXME: This lives in INFTL not here. Other users of flash devices
-+ may not want it */
-+static unsigned int DoC_GetDataOffset(struct mtd_info *mtd, loff_t *from)
-+{
-+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-+
-+ if (this->interleave) {
-+ unsigned int ofs = *from & 0x3ff;
-+ unsigned int cmd;
-+
-+ if (ofs < 512) {
-+ cmd = NAND_CMD_READ0;
-+ ofs &= 0x1ff;
-+ } else if (ofs < 1014) {
-+ cmd = NAND_CMD_READ1;
-+ ofs = (ofs & 0x1ff) + 10;
-+ } else {
-+ cmd = NAND_CMD_READOOB;
-+ ofs = ofs - 1014;
-+ }
-+
-+ *from = (*from & ~0x3ff) | ofs;
-+ return cmd;
-+ } else {
-+ /* No interleave */
-+ if ((*from) & 0x100)
-+ return NAND_CMD_READ1;
-+ return NAND_CMD_READ0;
-+ }
-+}
-+
-+static unsigned int DoC_GetECCOffset(struct mtd_info *mtd, loff_t *from)
-+{
-+ unsigned int ofs, cmd;
-+
-+ if (*from & 0x200) {
-+ cmd = NAND_CMD_READOOB;
-+ ofs = 10 + (*from & 0xf);
-+ } else {
-+ cmd = NAND_CMD_READ1;
-+ ofs = (*from & 0xf);
-+ }
-+
-+ *from = (*from & ~0x3ff) | ofs;
-+ return cmd;
-+}
-+
-+static unsigned int DoC_GetFlagsOffset(struct mtd_info *mtd, loff_t *from)
-+{
-+ unsigned int ofs, cmd;
-+
-+ cmd = NAND_CMD_READ1;
-+ ofs = (*from & 0x200) ? 8 : 6;
-+ *from = (*from & ~0x3ff) | ofs;
-+ return cmd;
-+}
-+
-+static unsigned int DoC_GetHdrOffset(struct mtd_info *mtd, loff_t *from)
-+{
-+ unsigned int ofs, cmd;
-+
-+ cmd = NAND_CMD_READOOB;
-+ ofs = (*from & 0x200) ? 24 : 16;
-+ *from = (*from & ~0x3ff) | ofs;
-+ return cmd;
-+}
-+
-+static inline void MemReadDOC(unsigned long docptr, unsigned char *buf, int len)
-+{
-+#ifndef USE_MEMCPY
-+ int i;
-+ for (i = 0; i < len; i++)
-+ buf[i] = ReadDOC(docptr, Mil_CDSN_IO + i);
-+#else
-+ memcpy_fromio(buf, docptr + DoC_Mil_CDSN_IO, len);
-+#endif
-+}
-+
-+static inline void MemWriteDOC(unsigned long docptr, unsigned char *buf, int len)
-+{
-+#ifndef USE_MEMCPY
-+ int i;
-+ for (i = 0; i < len; i++)
-+ WriteDOC(buf[i], docptr, Mil_CDSN_IO + i);
-+#else
-+ memcpy_toio(docptr + DoC_Mil_CDSN_IO, buf, len);
-+#endif
-+}
-+
-+/* DoC_IdentChip: Identify a given NAND chip given {floor,chip} */
-+static int DoC_IdentChip(struct DiskOnChip *doc, int floor, int chip)
-+{
-+ int mfr, id, i, j;
-+ volatile char dummy;
-+ unsigned long docptr = doc->virtadr;
-+
-+ /* Page in the required floor/chip */
-+ DoC_SelectFloor(docptr, floor);
-+ DoC_SelectChip(docptr, chip);
-+
-+ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-+ WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);
-+
-+ /* Reset the chip, see Software Requirement 11.4 item 1. */
-+ DoC_Command(docptr, NAND_CMD_RESET, 0);
-+ DoC_WaitReady(docptr);
-+
-+ /* Read the NAND chip ID: 1. Send ReadID command */
-+ DoC_Command(docptr, NAND_CMD_READID, 0);
-+
-+ /* Read the NAND chip ID: 2. Send address byte zero */
-+ DoC_Address(doc, 1, 0x00, 0, 0x00);
-+
-+ WriteDOC(0, docptr, Mplus_FlashControl);
-+ DoC_WaitReady(docptr);
-+
-+ /* Read the manufacturer and device id codes of the flash device through
-+ CDSN IO register see Software Requirement 11.4 item 5.*/
-+ dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-+ dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-+
-+ mfr = ReadDOC(docptr, Mil_CDSN_IO);
-+ if (doc->interleave)
-+ dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */
-+
-+ id = ReadDOC(docptr, Mil_CDSN_IO);
-+ if (doc->interleave)
-+ dummy = ReadDOC(docptr, Mil_CDSN_IO); /* 2 way interleave */
-+
-+ dummy = ReadDOC(docptr, Mplus_LastDataRead);
-+ dummy = ReadDOC(docptr, Mplus_LastDataRead);
-+
-+ /* Disable flash internally */
-+ WriteDOC(0, docptr, Mplus_FlashSelect);
-+
-+ /* No response - return failure */
-+ if (mfr == 0xff || mfr == 0)
-+ return 0;
-+
-+ for (i = 0; nand_flash_ids[i].name != NULL; i++) {
-+ if (id == nand_flash_ids[i].id) {
-+ /* Try to identify manufacturer */
-+ for (j = 0; nand_manuf_ids[j].id != 0x0; j++) {
-+ if (nand_manuf_ids[j].id == mfr)
-+ break;
-+ }
-+ printk(KERN_INFO "Flash chip found: Manufacturer ID: %2.2X, "
-+ "Chip ID: %2.2X (%s:%s)\n", mfr, id,
-+ nand_manuf_ids[j].name, nand_flash_ids[i].name);
-+ doc->mfr = mfr;
-+ doc->id = id;
-+ doc->chipshift = nand_flash_ids[i].chipshift;
-+ doc->erasesize = nand_flash_ids[i].erasesize << doc->interleave;
-+ break;
-+ }
-+ }
-+
-+ if (nand_flash_ids[i].name == NULL)
-+ return 0;
-+ return 1;
-+}
-+
-+/* DoC_ScanChips: Find all NAND chips present in a DiskOnChip, and identify them */
-+static void DoC_ScanChips(struct DiskOnChip *this)
-+{
-+ int floor, chip;
-+ int numchips[MAX_FLOORS_MPLUS];
-+ int ret;
-+
-+ this->numchips = 0;
-+ this->mfr = 0;
-+ this->id = 0;
-+
-+ /* Work out the intended interleave setting */
-+ this->interleave = 0;
-+ if (this->ChipID == DOC_ChipID_DocMilPlus32)
-+ this->interleave = 1;
-+
-+ /* Check the ASIC agrees */
-+ if ( (this->interleave << 2) !=
-+ (ReadDOC(this->virtadr, Mplus_Configuration) & 4)) {
-+ u_char conf = ReadDOC(this->virtadr, Mplus_Configuration);
-+ printk(KERN_NOTICE "Setting DiskOnChip Millennium Plus interleave to %s\n",
-+ this->interleave?"on (16-bit)":"off (8-bit)");
-+ conf ^= 4;
-+ WriteDOC(this->virtadr, conf, Mplus_Configuration);
-+ }
-+
-+ /* For each floor, find the number of valid chips it contains */
-+ for (floor = 0,ret = 1; floor < MAX_FLOORS_MPLUS; floor++) {
-+ numchips[floor] = 0;
-+ for (chip = 0; chip < MAX_CHIPS_MPLUS && ret != 0; chip++) {
-+ ret = DoC_IdentChip(this, floor, chip);
-+ if (ret) {
-+ numchips[floor]++;
-+ this->numchips++;
-+ }
-+ }
-+ }
-+ /* If there are none at all that we recognise, bail */
-+ if (!this->numchips) {
-+ printk("No flash chips recognised.\n");
-+ return;
-+ }
-+
-+ /* Allocate an array to hold the information for each chip */
-+ this->chips = kmalloc(sizeof(struct Nand) * this->numchips, GFP_KERNEL);
-+ if (!this->chips){
-+ printk("MTD: No memory for allocating chip info structures\n");
-+ return;
-+ }
-+
-+ /* Fill out the chip array with {floor, chipno} for each
-+ * detected chip in the device. */
-+ for (floor = 0, ret = 0; floor < MAX_FLOORS_MPLUS; floor++) {
-+ for (chip = 0 ; chip < numchips[floor] ; chip++) {
-+ this->chips[ret].floor = floor;
-+ this->chips[ret].chip = chip;
-+ this->chips[ret].curadr = 0;
-+ this->chips[ret].curmode = 0x50;
-+ ret++;
-+ }
-+ }
-+
-+ /* Calculate and print the total size of the device */
-+ this->totlen = this->numchips * (1 << this->chipshift);
-+ printk(KERN_INFO "%d flash chips found. Total DiskOnChip size: %ld MiB\n",
-+ this->numchips ,this->totlen >> 20);
-+}
-+
-+static int DoCMilPlus_is_alias(struct DiskOnChip *doc1, struct DiskOnChip *doc2)
-+{
-+ int tmp1, tmp2, retval;
-+
-+ if (doc1->physadr == doc2->physadr)
-+ return 1;
-+
-+ /* Use the alias resolution register which was set aside for this
-+ * purpose. If it's value is the same on both chips, they might
-+ * be the same chip, and we write to one and check for a change in
-+ * the other. It's unclear if this register is usuable in the
-+ * DoC 2000 (it's in the Millennium docs), but it seems to work. */
-+ tmp1 = ReadDOC(doc1->virtadr, Mplus_AliasResolution);
-+ tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
-+ if (tmp1 != tmp2)
-+ return 0;
-+
-+ WriteDOC((tmp1+1) % 0xff, doc1->virtadr, Mplus_AliasResolution);
-+ tmp2 = ReadDOC(doc2->virtadr, Mplus_AliasResolution);
-+ if (tmp2 == (tmp1+1) % 0xff)
-+ retval = 1;
-+ else
-+ retval = 0;
-+
-+ /* Restore register contents. May not be necessary, but do it just to
-+ * be safe. */
-+ WriteDOC(tmp1, doc1->virtadr, Mplus_AliasResolution);
-+
-+ return retval;
-+}
-+
-+static const char im_name[] = "DoCMilPlus_init";
-+
-+/* This routine is made available to other mtd code via
-+ * inter_module_register. It must only be accessed through
-+ * inter_module_get which will bump the use count of this module. The
-+ * addresses passed back in mtd are valid as long as the use count of
-+ * this module is non-zero, i.e. between inter_module_get and
-+ * inter_module_put. Keith Owens <kaos@ocs.com.au> 29 Oct 2000.
-+ */
-+static void DoCMilPlus_init(struct mtd_info *mtd)
-+{
-+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-+ struct DiskOnChip *old = NULL;
-+
-+ /* We must avoid being called twice for the same device. */
-+ if (docmilpluslist)
-+ old = (struct DiskOnChip *)docmilpluslist->priv;
-+
-+ while (old) {
-+ if (DoCMilPlus_is_alias(this, old)) {
-+ printk(KERN_NOTICE "Ignoring DiskOnChip Millennium "
-+ "Plus at 0x%lX - already configured\n",
-+ this->physadr);
-+ iounmap((void *)this->virtadr);
-+ kfree(mtd);
-+ return;
-+ }
-+ if (old->nextdoc)
-+ old = (struct DiskOnChip *)old->nextdoc->priv;
-+ else
-+ old = NULL;
-+ }
-+
-+ mtd->name = "DiskOnChip Millennium Plus";
-+ printk(KERN_NOTICE "DiskOnChip Millennium Plus found at "
-+ "address 0x%lX\n", this->physadr);
-+
-+ mtd->type = MTD_NANDFLASH;
-+ mtd->flags = MTD_CAP_NANDFLASH;
-+ mtd->ecctype = MTD_ECC_RS_DiskOnChip;
-+ mtd->size = 0;
-+
-+ mtd->erasesize = 0;
-+ mtd->oobblock = 512;
-+ mtd->oobsize = 16;
-+ mtd->owner = THIS_MODULE;
-+ mtd->erase = doc_erase;
-+ mtd->point = NULL;
-+ mtd->unpoint = NULL;
-+ mtd->read = doc_read;
-+ mtd->write = doc_write;
-+ mtd->read_ecc = doc_read_ecc;
-+ mtd->write_ecc = doc_write_ecc;
-+ mtd->read_oob = doc_read_oob;
-+ mtd->write_oob = doc_write_oob;
-+ mtd->sync = NULL;
-+
-+ this->totlen = 0;
-+ this->numchips = 0;
-+ this->curfloor = -1;
-+ this->curchip = -1;
-+
-+ /* Ident all the chips present. */
-+ DoC_ScanChips(this);
-+
-+ if (!this->totlen) {
-+ kfree(mtd);
-+ iounmap((void *)this->virtadr);
-+ } else {
-+ this->nextdoc = docmilpluslist;
-+ docmilpluslist = mtd;
-+ mtd->size = this->totlen;
-+ mtd->erasesize = this->erasesize;
-+ add_mtd_device(mtd);
-+ return;
-+ }
-+}
-+
-+#if 0
-+static int doc_dumpblk(struct mtd_info *mtd, loff_t from)
-+{
-+ int i;
-+ loff_t fofs;
-+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-+ unsigned long docptr = this->virtadr;
-+ struct Nand *mychip = &this->chips[from >> (this->chipshift)];
-+ unsigned char *bp, buf[1056];
-+ char c[32];
-+
-+ from &= ~0x3ff;
-+
-+ /* Don't allow read past end of device */
-+ if (from >= this->totlen)
-+ return -EINVAL;
-+
-+ DoC_CheckASIC(docptr);
-+
-+ /* Find the chip which is to be used and select it */
-+ if (this->curfloor != mychip->floor) {
-+ DoC_SelectFloor(docptr, mychip->floor);
-+ DoC_SelectChip(docptr, mychip->chip);
-+ } else if (this->curchip != mychip->chip) {
-+ DoC_SelectChip(docptr, mychip->chip);
-+ }
-+ this->curfloor = mychip->floor;
-+ this->curchip = mychip->chip;
-+
-+ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-+ WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);
-+
-+ /* Reset the chip, see Software Requirement 11.4 item 1. */
-+ DoC_Command(docptr, NAND_CMD_RESET, 0);
-+ DoC_WaitReady(docptr);
-+
-+ fofs = from;
-+ DoC_Command(docptr, DoC_GetDataOffset(mtd, &fofs), 0);
-+ DoC_Address(this, 3, fofs, 0, 0x00);
-+ WriteDOC(0, docptr, Mplus_FlashControl);
-+ DoC_WaitReady(docptr);
-+
-+ /* disable the ECC engine */
-+ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-+
-+ ReadDOC(docptr, Mplus_ReadPipeInit);
-+ ReadDOC(docptr, Mplus_ReadPipeInit);
-+
-+ /* Read the data via the internal pipeline through CDSN IO
-+ register, see Pipelined Read Operations 11.3 */
-+ MemReadDOC(docptr, buf, 1054);
-+ buf[1054] = ReadDOC(docptr, Mplus_LastDataRead);
-+ buf[1055] = ReadDOC(docptr, Mplus_LastDataRead);
-+
-+ memset(&c[0], 0, sizeof(c));
-+ printk("DUMP OFFSET=%x:\n", (int)from);
-+
-+ for (i = 0, bp = &buf[0]; (i < 1056); i++) {
-+ if ((i % 16) == 0)
-+ printk("%08x: ", i);
-+ printk(" %02x", *bp);
-+ c[(i & 0xf)] = ((*bp >= 0x20) && (*bp <= 0x7f)) ? *bp : '.';
-+ bp++;
-+ if (((i + 1) % 16) == 0)
-+ printk(" %s\n", c);
-+ }
-+ printk("\n");
-+
-+ /* Disable flash internally */
-+ WriteDOC(0, docptr, Mplus_FlashSelect);
-+
-+ return 0;
-+}
-+#endif
-+
-+static int doc_read(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t *retlen, u_char *buf)
-+{
-+ /* Just a special case of doc_read_ecc */
-+ return doc_read_ecc(mtd, from, len, retlen, buf, NULL, NULL);
-+}
-+
-+static int doc_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t *retlen, u_char *buf, u_char *eccbuf,
-+ struct nand_oobinfo *oobsel)
-+{
-+ int ret, i;
-+ volatile char dummy;
-+ loff_t fofs;
-+ unsigned char syndrome[6];
-+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-+ unsigned long docptr = this->virtadr;
-+ struct Nand *mychip = &this->chips[from >> (this->chipshift)];
-+
-+ /* Don't allow read past end of device */
-+ if (from >= this->totlen)
-+ return -EINVAL;
-+
-+ /* Don't allow a single read to cross a 512-byte block boundary */
-+ if (from + len > ((from | 0x1ff) + 1))
-+ len = ((from | 0x1ff) + 1) - from;
-+
-+ DoC_CheckASIC(docptr);
-+
-+ /* Find the chip which is to be used and select it */
-+ if (this->curfloor != mychip->floor) {
-+ DoC_SelectFloor(docptr, mychip->floor);
-+ DoC_SelectChip(docptr, mychip->chip);
-+ } else if (this->curchip != mychip->chip) {
-+ DoC_SelectChip(docptr, mychip->chip);
-+ }
-+ this->curfloor = mychip->floor;
-+ this->curchip = mychip->chip;
-+
-+ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-+ WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);
-+
-+ /* Reset the chip, see Software Requirement 11.4 item 1. */
-+ DoC_Command(docptr, NAND_CMD_RESET, 0);
-+ DoC_WaitReady(docptr);
-+
-+ fofs = from;
-+ DoC_Command(docptr, DoC_GetDataOffset(mtd, &fofs), 0);
-+ DoC_Address(this, 3, fofs, 0, 0x00);
-+ WriteDOC(0, docptr, Mplus_FlashControl);
-+ DoC_WaitReady(docptr);
-+
-+ if (eccbuf) {
-+ /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
-+ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-+ WriteDOC(DOC_ECC_EN, docptr, Mplus_ECCConf);
-+ } else {
-+ /* disable the ECC engine */
-+ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-+ }
-+
-+ /* Let the caller know we completed it */
-+ *retlen = len;
-+ ret = 0;
-+
-+ ReadDOC(docptr, Mplus_ReadPipeInit);
-+ ReadDOC(docptr, Mplus_ReadPipeInit);
-+
-+ if (eccbuf) {
-+ /* Read the data via the internal pipeline through CDSN IO
-+ register, see Pipelined Read Operations 11.3 */
-+ MemReadDOC(docptr, buf, len);
-+
-+ /* Read the ECC data following raw data */
-+ MemReadDOC(docptr, eccbuf, 4);
-+ eccbuf[4] = ReadDOC(docptr, Mplus_LastDataRead);
-+ eccbuf[5] = ReadDOC(docptr, Mplus_LastDataRead);
-+
-+ /* Flush the pipeline */
-+ dummy = ReadDOC(docptr, Mplus_ECCConf);
-+ dummy = ReadDOC(docptr, Mplus_ECCConf);
-+
-+ /* Check the ECC Status */
-+ if (ReadDOC(docptr, Mplus_ECCConf) & 0x80) {
-+ int nb_errors;
-+ /* There was an ECC error */
-+#ifdef ECC_DEBUG
-+ printk("DiskOnChip ECC Error: Read at %lx\n", (long)from);
-+#endif
-+ /* Read the ECC syndrom through the DiskOnChip ECC logic.
-+ These syndrome will be all ZERO when there is no error */
-+ for (i = 0; i < 6; i++)
-+ syndrome[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
-+
-+ nb_errors = doc_decode_ecc(buf, syndrome);
-+#ifdef ECC_DEBUG
-+ printk("ECC Errors corrected: %x\n", nb_errors);
-+#endif
-+ if (nb_errors < 0) {
-+ /* We return error, but have actually done the read. Not that
-+ this can be told to user-space, via sys_read(), but at least
-+ MTD-aware stuff can know about it by checking *retlen */
-+#ifdef ECC_DEBUG
-+ printk("%s(%d): Millennium Plus ECC error (from=0x%x:\n",
-+ __FILE__, __LINE__, (int)from);
-+ printk(" syndrome= %02x:%02x:%02x:%02x:%02x:"
-+ "%02x\n",
-+ syndrome[0], syndrome[1], syndrome[2],
-+ syndrome[3], syndrome[4], syndrome[5]);
-+ printk(" eccbuf= %02x:%02x:%02x:%02x:%02x:"
-+ "%02x\n",
-+ eccbuf[0], eccbuf[1], eccbuf[2],
-+ eccbuf[3], eccbuf[4], eccbuf[5]);
-+#endif
-+ ret = -EIO;
-+ }
-+ }
-+
-+#ifdef PSYCHO_DEBUG
-+ printk("ECC DATA at %lx: %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
-+ (long)from, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
-+ eccbuf[4], eccbuf[5]);
-+#endif
-+
-+ /* disable the ECC engine */
-+ WriteDOC(DOC_ECC_DIS, docptr , Mplus_ECCConf);
-+ } else {
-+ /* Read the data via the internal pipeline through CDSN IO
-+ register, see Pipelined Read Operations 11.3 */
-+ MemReadDOC(docptr, buf, len-2);
-+ buf[len-2] = ReadDOC(docptr, Mplus_LastDataRead);
-+ buf[len-1] = ReadDOC(docptr, Mplus_LastDataRead);
-+ }
-+
-+ /* Disable flash internally */
-+ WriteDOC(0, docptr, Mplus_FlashSelect);
-+
-+ return ret;
-+}
-+
-+static int doc_write(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf)
-+{
-+ char eccbuf[6];
-+ return doc_write_ecc(mtd, to, len, retlen, buf, eccbuf, NULL);
-+}
-+
-+static int doc_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf, u_char *eccbuf,
-+ struct nand_oobinfo *oobsel)
-+{
-+ int i, before, ret = 0;
-+ loff_t fto;
-+ volatile char dummy;
-+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-+ unsigned long docptr = this->virtadr;
-+ struct Nand *mychip = &this->chips[to >> (this->chipshift)];
-+
-+ /* Don't allow write past end of device */
-+ if (to >= this->totlen)
-+ return -EINVAL;
-+
-+ /* Don't allow writes which aren't exactly one block (512 bytes) */
-+ if ((to & 0x1ff) || (len != 0x200))
-+ return -EINVAL;
-+
-+ /* Determine position of OOB flags, before or after data */
-+ before = (this->interleave && (to & 0x200));
-+
-+ DoC_CheckASIC(docptr);
-+
-+ /* Find the chip which is to be used and select it */
-+ if (this->curfloor != mychip->floor) {
-+ DoC_SelectFloor(docptr, mychip->floor);
-+ DoC_SelectChip(docptr, mychip->chip);
-+ } else if (this->curchip != mychip->chip) {
-+ DoC_SelectChip(docptr, mychip->chip);
-+ }
-+ this->curfloor = mychip->floor;
-+ this->curchip = mychip->chip;
-+
-+ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-+ WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);
-+
-+ /* Reset the chip, see Software Requirement 11.4 item 1. */
-+ DoC_Command(docptr, NAND_CMD_RESET, 0);
-+ DoC_WaitReady(docptr);
-+
-+ /* Set device to appropriate plane of flash */
-+ fto = to;
-+ WriteDOC(DoC_GetDataOffset(mtd, &fto), docptr, Mplus_FlashCmd);
-+
-+ /* On interleaved devices the flags for 2nd half 512 are before data */
-+ if (eccbuf && before)
-+ fto -= 2;
-+
-+ /* issue the Serial Data In command to initial the Page Program process */
-+ DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
-+ DoC_Address(this, 3, fto, 0x00, 0x00);
-+
-+ /* Disable the ECC engine */
-+ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-+
-+ if (eccbuf) {
-+ if (before) {
-+ /* Write the block status BLOCK_USED (0x5555) */
-+ WriteDOC(0x55, docptr, Mil_CDSN_IO);
-+ WriteDOC(0x55, docptr, Mil_CDSN_IO);
-+ }
-+
-+ /* init the ECC engine, see Reed-Solomon EDC/ECC 11.1 .*/
-+ WriteDOC(DOC_ECC_EN | DOC_ECC_RW, docptr, Mplus_ECCConf);
-+ }
-+
-+ MemWriteDOC(docptr, (unsigned char *) buf, len);
-+
-+ if (eccbuf) {
-+ /* Write ECC data to flash, the ECC info is generated by
-+ the DiskOnChip ECC logic see Reed-Solomon EDC/ECC 11.1 */
-+ DoC_Delay(docptr, 3);
-+
-+ /* Read the ECC data through the DiskOnChip ECC logic */
-+ for (i = 0; i < 6; i++)
-+ eccbuf[i] = ReadDOC(docptr, Mplus_ECCSyndrome0 + i);
-+
-+ /* disable the ECC engine */
-+ WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
-+
-+ /* Write the ECC data to flash */
-+ MemWriteDOC(docptr, eccbuf, 6);
-+
-+ if (!before) {
-+ /* Write the block status BLOCK_USED (0x5555) */
-+ WriteDOC(0x55, docptr, Mil_CDSN_IO+6);
-+ WriteDOC(0x55, docptr, Mil_CDSN_IO+7);
-+ }
-+
-+#ifdef PSYCHO_DEBUG
-+ printk("OOB data at %lx is %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X\n",
-+ (long) to, eccbuf[0], eccbuf[1], eccbuf[2], eccbuf[3],
-+ eccbuf[4], eccbuf[5]);
-+#endif
-+ }
-+
-+ WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-+ WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-+
-+ /* Commit the Page Program command and wait for ready
-+ see Software Requirement 11.4 item 1.*/
-+ DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
-+ DoC_WaitReady(docptr);
-+
-+ /* Read the status of the flash device through CDSN IO register
-+ see Software Requirement 11.4 item 5.*/
-+ DoC_Command(docptr, NAND_CMD_STATUS, 0);
-+ dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-+ dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-+ DoC_Delay(docptr, 2);
-+ if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
-+ printk("MTD: Error 0x%x programming at 0x%x\n", dummy, (int)to);
-+ /* Error in programming
-+ FIXME: implement Bad Block Replacement (in nftl.c ??) */
-+ *retlen = 0;
-+ ret = -EIO;
-+ }
-+ dummy = ReadDOC(docptr, Mplus_LastDataRead);
-+
-+ /* Disable flash internally */
-+ WriteDOC(0, docptr, Mplus_FlashSelect);
-+
-+ /* Let the caller know we completed it */
-+ *retlen = len;
-+
-+ return ret;
-+}
-+
-+static int doc_read_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-+ size_t *retlen, u_char *buf)
-+{
-+ loff_t fofs, base;
-+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-+ unsigned long docptr = this->virtadr;
-+ struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-+ size_t i, size, got, want;
-+
-+ DoC_CheckASIC(docptr);
-+
-+ /* Find the chip which is to be used and select it */
-+ if (this->curfloor != mychip->floor) {
-+ DoC_SelectFloor(docptr, mychip->floor);
-+ DoC_SelectChip(docptr, mychip->chip);
-+ } else if (this->curchip != mychip->chip) {
-+ DoC_SelectChip(docptr, mychip->chip);
-+ }
-+ this->curfloor = mychip->floor;
-+ this->curchip = mychip->chip;
-+
-+ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-+ WriteDOC((DOC_FLASH_CE | DOC_FLASH_WP), docptr, Mplus_FlashSelect);
-+
-+ /* disable the ECC engine */
-+ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-+ DoC_WaitReady(docptr);
-+
-+ /* Maximum of 16 bytes in the OOB region, so limit read to that */
-+ if (len > 16)
-+ len = 16;
-+ got = 0;
-+ want = len;
-+
-+ for (i = 0; ((i < 3) && (want > 0)); i++) {
-+ /* Figure out which region we are accessing... */
-+ fofs = ofs;
-+ base = ofs & 0xf;
-+ if (!this->interleave) {
-+ DoC_Command(docptr, NAND_CMD_READOOB, 0);
-+ size = 16 - base;
-+ } else if (base < 6) {
-+ DoC_Command(docptr, DoC_GetECCOffset(mtd, &fofs), 0);
-+ size = 6 - base;
-+ } else if (base < 8) {
-+ DoC_Command(docptr, DoC_GetFlagsOffset(mtd, &fofs), 0);
-+ size = 8 - base;
-+ } else {
-+ DoC_Command(docptr, DoC_GetHdrOffset(mtd, &fofs), 0);
-+ size = 16 - base;
-+ }
-+ if (size > want)
-+ size = want;
-+
-+ /* Issue read command */
-+ DoC_Address(this, 3, fofs, 0, 0x00);
-+ WriteDOC(0, docptr, Mplus_FlashControl);
-+ DoC_WaitReady(docptr);
-+
-+ ReadDOC(docptr, Mplus_ReadPipeInit);
-+ ReadDOC(docptr, Mplus_ReadPipeInit);
-+ MemReadDOC(docptr, &buf[got], size - 2);
-+ buf[got + size - 2] = ReadDOC(docptr, Mplus_LastDataRead);
-+ buf[got + size - 1] = ReadDOC(docptr, Mplus_LastDataRead);
-+
-+ ofs += size;
-+ got += size;
-+ want -= size;
-+ }
-+
-+ /* Disable flash internally */
-+ WriteDOC(0, docptr, Mplus_FlashSelect);
-+
-+ *retlen = len;
-+ return 0;
-+}
-+
-+static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, size_t len,
-+ size_t *retlen, const u_char *buf)
-+{
-+ volatile char dummy;
-+ loff_t fofs, base;
-+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-+ unsigned long docptr = this->virtadr;
-+ struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-+ size_t i, size, got, want;
-+ int ret = 0;
-+
-+ DoC_CheckASIC(docptr);
-+
-+ /* Find the chip which is to be used and select it */
-+ if (this->curfloor != mychip->floor) {
-+ DoC_SelectFloor(docptr, mychip->floor);
-+ DoC_SelectChip(docptr, mychip->chip);
-+ } else if (this->curchip != mychip->chip) {
-+ DoC_SelectChip(docptr, mychip->chip);
-+ }
-+ this->curfloor = mychip->floor;
-+ this->curchip = mychip->chip;
-+
-+ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-+ WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);
-+
-+
-+ /* Maximum of 16 bytes in the OOB region, so limit write to that */
-+ if (len > 16)
-+ len = 16;
-+ got = 0;
-+ want = len;
-+
-+ for (i = 0; ((i < 3) && (want > 0)); i++) {
-+ /* Reset the chip, see Software Requirement 11.4 item 1. */
-+ DoC_Command(docptr, NAND_CMD_RESET, 0);
-+ DoC_WaitReady(docptr);
-+
-+ /* Figure out which region we are accessing... */
-+ fofs = ofs;
-+ base = ofs & 0x0f;
-+ if (!this->interleave) {
-+ WriteDOC(NAND_CMD_READOOB, docptr, Mplus_FlashCmd);
-+ size = 16 - base;
-+ } else if (base < 6) {
-+ WriteDOC(DoC_GetECCOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
-+ size = 6 - base;
-+ } else if (base < 8) {
-+ WriteDOC(DoC_GetFlagsOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
-+ size = 8 - base;
-+ } else {
-+ WriteDOC(DoC_GetHdrOffset(mtd, &fofs), docptr, Mplus_FlashCmd);
-+ size = 16 - base;
-+ }
-+ if (size > want)
-+ size = want;
-+
-+ /* Issue the Serial Data In command to initial the Page Program process */
-+ DoC_Command(docptr, NAND_CMD_SEQIN, 0x00);
-+ DoC_Address(this, 3, fofs, 0, 0x00);
-+
-+ /* Disable the ECC engine */
-+ WriteDOC(DOC_ECC_RESET, docptr, Mplus_ECCConf);
-+
-+ /* Write the data via the internal pipeline through CDSN IO
-+ register, see Pipelined Write Operations 11.2 */
-+ MemWriteDOC(docptr, (unsigned char *) &buf[got], size);
-+ WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-+ WriteDOC(0x00, docptr, Mplus_WritePipeTerm);
-+
-+ /* Commit the Page Program command and wait for ready
-+ see Software Requirement 11.4 item 1.*/
-+ DoC_Command(docptr, NAND_CMD_PAGEPROG, 0x00);
-+ DoC_WaitReady(docptr);
-+
-+ /* Read the status of the flash device through CDSN IO register
-+ see Software Requirement 11.4 item 5.*/
-+ DoC_Command(docptr, NAND_CMD_STATUS, 0x00);
-+ dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-+ dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-+ DoC_Delay(docptr, 2);
-+ if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
-+ printk("MTD: Error 0x%x programming oob at 0x%x\n",
-+ dummy, (int)ofs);
-+ /* FIXME: implement Bad Block Replacement */
-+ *retlen = 0;
-+ ret = -EIO;
-+ }
-+ dummy = ReadDOC(docptr, Mplus_LastDataRead);
-+
-+ ofs += size;
-+ got += size;
-+ want -= size;
-+ }
-+
-+ /* Disable flash internally */
-+ WriteDOC(0, docptr, Mplus_FlashSelect);
-+
-+ *retlen = len;
-+ return ret;
-+}
-+
-+int doc_erase(struct mtd_info *mtd, struct erase_info *instr)
-+{
-+ volatile char dummy;
-+ struct DiskOnChip *this = (struct DiskOnChip *)mtd->priv;
-+ __u32 ofs = instr->addr;
-+ __u32 len = instr->len;
-+ unsigned long docptr = this->virtadr;
-+ struct Nand *mychip = &this->chips[ofs >> this->chipshift];
-+
-+ DoC_CheckASIC(docptr);
-+
-+ if (len != mtd->erasesize)
-+ printk(KERN_WARNING "MTD: Erase not right size (%x != %x)n",
-+ len, mtd->erasesize);
-+
-+ /* Find the chip which is to be used and select it */
-+ if (this->curfloor != mychip->floor) {
-+ DoC_SelectFloor(docptr, mychip->floor);
-+ DoC_SelectChip(docptr, mychip->chip);
-+ } else if (this->curchip != mychip->chip) {
-+ DoC_SelectChip(docptr, mychip->chip);
-+ }
-+ this->curfloor = mychip->floor;
-+ this->curchip = mychip->chip;
-+
-+ instr->state = MTD_ERASE_PENDING;
-+
-+ /* Millennium Plus bus cycle sequence as per figure 2, section 2.4 */
-+ WriteDOC(DOC_FLASH_CE, docptr, Mplus_FlashSelect);
-+
-+ DoC_Command(docptr, NAND_CMD_RESET, 0x00);
-+ DoC_WaitReady(docptr);
-+
-+ DoC_Command(docptr, NAND_CMD_ERASE1, 0);
-+ DoC_Address(this, 2, ofs, 0, 0x00);
-+ DoC_Command(docptr, NAND_CMD_ERASE2, 0);
-+ DoC_WaitReady(docptr);
-+ instr->state = MTD_ERASING;
-+
-+ /* Read the status of the flash device through CDSN IO register
-+ see Software Requirement 11.4 item 5. */
-+ DoC_Command(docptr, NAND_CMD_STATUS, 0);
-+ dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-+ dummy = ReadDOC(docptr, Mplus_ReadPipeInit);
-+ if ((dummy = ReadDOC(docptr, Mplus_LastDataRead)) & 1) {
-+ printk("MTD: Error 0x%x erasing at 0x%x\n", dummy, ofs);
-+ /* FIXME: implement Bad Block Replacement (in nftl.c ??) */
-+ instr->state = MTD_ERASE_FAILED;
-+ } else {
-+ instr->state = MTD_ERASE_DONE;
-+ }
-+ dummy = ReadDOC(docptr, Mplus_LastDataRead);
-+
-+ /* Disable flash internally */
-+ WriteDOC(0, docptr, Mplus_FlashSelect);
-+
-+ if (instr->callback)
-+ instr->callback(instr);
-+
-+ return 0;
-+}
-+
-+/****************************************************************************
-+ *
-+ * Module stuff
-+ *
-+ ****************************************************************************/
-+
-+int __init init_doc2001plus(void)
-+{
-+ inter_module_register(im_name, THIS_MODULE, &DoCMilPlus_init);
-+ return 0;
-+}
-+
-+static void __exit cleanup_doc2001plus(void)
-+{
-+ struct mtd_info *mtd;
-+ struct DiskOnChip *this;
-+
-+ while ((mtd=docmilpluslist)) {
-+ this = (struct DiskOnChip *)mtd->priv;
-+ docmilpluslist = this->nextdoc;
-+
-+ del_mtd_device(mtd);
-+
-+ iounmap((void *)this->virtadr);
-+ kfree(this->chips);
-+ kfree(mtd);
-+ }
-+ inter_module_unregister(im_name);
-+}
-+
-+module_exit(cleanup_doc2001plus);
-+module_init(init_doc2001plus);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com> et al.");
-+MODULE_DESCRIPTION("Driver for DiskOnChip Millennium Plus");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/docecc.c linux/drivers/mtd/devices/docecc.c
---- linux-mips-2.4.27/drivers/mtd/devices/docecc.c 2001-11-05 21:15:52.000000000 +0100
-+++ linux/drivers/mtd/devices/docecc.c 2004-11-19 10:25:11.851207088 +0100
-@@ -7,7 +7,7 @@
- * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
- * Copyright (C) 2000 Netgem S.A.
- *
-- * $Id$
-+ * $Id$
- *
- * 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
-@@ -519,6 +519,8 @@
- return nb_errors;
- }
-
-+EXPORT_SYMBOL_GPL(doc_decode_ecc);
-+
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Fabrice Bellard <fabrice.bellard@netgem.com>");
- MODULE_DESCRIPTION("ECC code for correcting errors detected by DiskOnChip 2000 and Millennium ECC hardware");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/docprobe.c linux/drivers/mtd/devices/docprobe.c
---- linux-mips-2.4.27/drivers/mtd/devices/docprobe.c 2003-06-16 01:42:21.000000000 +0200
-+++ linux/drivers/mtd/devices/docprobe.c 2004-11-19 10:25:11.853206784 +0100
-@@ -4,7 +4,7 @@
- /* (C) 1999 Machine Vision Holdings, Inc. */
- /* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> */
-
--/* $Id$ */
-+/* $Id$ */
-
-
-
-@@ -31,14 +31,12 @@
- /* DOC_SINGLE_DRIVER:
- Millennium driver has been merged into DOC2000 driver.
-
-- The newly-merged driver doesn't appear to work for writing. It's the
-- same with the DiskOnChip 2000 and the Millennium. If you have a
-- Millennium and you want write support to work, remove the definition
-- of DOC_SINGLE_DRIVER below to use the old doc2001-specific driver.
--
-- Otherwise, it's left on in the hope that it'll annoy someone with
-- a Millennium enough that they go through and work out what the
-- difference is :)
-+ The old Millennium-only driver has been retained just in case there
-+ are problems with the new code. If the combined driver doesn't work
-+ for you, you can try the old one by undefining DOC_SINGLE_DRIVER
-+ below and also enabling it in your configuration. If this fixes the
-+ problems, please send a report to the MTD mailing list at
-+ <linux-mtd@lists.infradead.org>.
- */
- #define DOC_SINGLE_DRIVER
-
-@@ -47,18 +45,15 @@
- #include <linux/module.h>
- #include <asm/errno.h>
- #include <asm/io.h>
--#include <asm/uaccess.h>
--#include <linux/miscdevice.h>
--#include <linux/pci.h>
- #include <linux/delay.h>
- #include <linux/slab.h>
--#include <linux/sched.h>
- #include <linux/init.h>
- #include <linux/types.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/nand.h>
- #include <linux/mtd/doc2000.h>
-+#include <linux/mtd/compatmac.h>
-
- /* Where to look for the devices? */
- #ifndef CONFIG_MTD_DOCPROBE_ADDRESS
-@@ -92,17 +87,17 @@
- 0xff000000,
- #elif defined(CONFIG_MOMENCO_OCELOT_G) || defined (CONFIG_MOMENCO_OCELOT_C)
- 0xff000000,
--#else
-+##else
- #warning Unknown architecture for DiskOnChip. No default probe locations defined
- #endif
-- 0 };
-+ 0xffffffff };
-
- /* doccheck: Probe a given memory window to see if there's a DiskOnChip present */
-
- static inline int __init doccheck(unsigned long potential, unsigned long physadr)
- {
- unsigned long window=potential;
-- unsigned char tmp, ChipID;
-+ unsigned char tmp, tmpb, tmpc, ChipID;
- #ifndef DOC_PASSIVE_PROBE
- unsigned char tmp2;
- #endif
-@@ -140,26 +135,80 @@
- window, DOCControl);
- #endif /* !DOC_PASSIVE_PROBE */
-
-+ /* We need to read the ChipID register four times. For some
-+ newer DiskOnChip 2000 units, the first three reads will
-+ return the DiskOnChip Millennium ident. Don't ask. */
- ChipID = ReadDOC(window, ChipID);
-
- switch (ChipID) {
- case DOC_ChipID_Doc2k:
- /* Check the TOGGLE bit in the ECC register */
- tmp = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
-- if ((ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT) != tmp)
-+ tmpb = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
-+ tmpc = ReadDOC(window, 2k_ECCStatus) & DOC_TOGGLE_BIT;
-+ if (tmp != tmpb && tmp == tmpc)
- return ChipID;
- break;
-
- case DOC_ChipID_DocMil:
-+ /* Check for the new 2000 with Millennium ASIC */
-+ ReadDOC(window, ChipID);
-+ ReadDOC(window, ChipID);
-+ if (ReadDOC(window, ChipID) != DOC_ChipID_DocMil)
-+ ChipID = DOC_ChipID_Doc2kTSOP;
-+
- /* Check the TOGGLE bit in the ECC register */
- tmp = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
-- if ((ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT) != tmp)
-+ tmpb = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
-+ tmpc = ReadDOC(window, ECCConf) & DOC_TOGGLE_BIT;
-+ if (tmp != tmpb && tmp == tmpc)
-+ return ChipID;
-+ break;
-+
-+ case DOC_ChipID_DocMilPlus16:
-+ case DOC_ChipID_DocMilPlus32:
-+ case 0:
-+ /* Possible Millennium+, need to do more checks */
-+#ifndef DOC_PASSIVE_PROBE
-+ /* Possibly release from power down mode */
-+ for (tmp = 0; (tmp < 4); tmp++)
-+ ReadDOC(window, Mplus_Power);
-+
-+ /* Reset the DiskOnChip ASIC */
-+ tmp = DOC_MODE_RESET | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
-+ DOC_MODE_BDECT;
-+ WriteDOC(tmp, window, Mplus_DOCControl);
-+ WriteDOC(~tmp, window, Mplus_CtrlConfirm);
-+
-+ mdelay(1);
-+ /* Enable the DiskOnChip ASIC */
-+ tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT |
-+ DOC_MODE_BDECT;
-+ WriteDOC(tmp, window, Mplus_DOCControl);
-+ WriteDOC(~tmp, window, Mplus_CtrlConfirm);
-+ mdelay(1);
-+#endif /* !DOC_PASSIVE_PROBE */
-+
-+ ChipID = ReadDOC(window, ChipID);
-+
-+ switch (ChipID) {
-+ case DOC_ChipID_DocMilPlus16:
-+ case DOC_ChipID_DocMilPlus32:
-+ /* Check the TOGGLE bit in the toggle register */
-+ tmp = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT;
-+ tmpb = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT;
-+ tmpc = ReadDOC(window, Mplus_Toggle) & DOC_TOGGLE_BIT;
-+ if (tmp != tmpb && tmp == tmpc)
- return ChipID;
-+ default:
- break;
-+ }
-+ /* FALL TRHU */
-
- default:
--#ifndef CONFIG_MTD_DOCPROBE_55AA
-- printk(KERN_WARNING "Possible DiskOnChip with unknown ChipID %2.2X found at 0x%lx\n",
-+
-+#ifdef CONFIG_MTD_DOCPROBE_55AA
-+ printk(KERN_DEBUG "Possible DiskOnChip with unknown ChipID %2.2X found at 0x%lx\n",
- ChipID, physadr);
- #endif
- #ifndef DOC_PASSIVE_PROBE
-@@ -200,6 +249,12 @@
- return;
-
- if ((ChipID = doccheck(docptr, physadr))) {
-+ if (ChipID == DOC_ChipID_Doc2kTSOP) {
-+ /* Remove this at your own peril. The hardware driver works but nothing prevents you from erasing bad blocks */
-+ printk(KERN_NOTICE "Refusing to drive DiskOnChip 2000 TSOP until Bad Block Table is correctly supported by INFTL\n");
-+ iounmap((void *)docptr);
-+ return;
-+ }
- docfound = 1;
- mtd = kmalloc(sizeof(struct DiskOnChip) + sizeof(struct mtd_info), GFP_KERNEL);
-
-@@ -221,6 +276,12 @@
- sprintf(namebuf, "with ChipID %2.2X", ChipID);
-
- switch(ChipID) {
-+ case DOC_ChipID_Doc2kTSOP:
-+ name="2000 TSOP";
-+ im_funcname = "DoC2k_init";
-+ im_modname = "doc2000";
-+ break;
-+
- case DOC_ChipID_Doc2k:
- name="2000";
- im_funcname = "DoC2k_init";
-@@ -237,6 +298,13 @@
- im_modname = "doc2001";
- #endif /* DOC_SINGLE_DRIVER */
- break;
-+
-+ case DOC_ChipID_DocMilPlus16:
-+ case DOC_ChipID_DocMilPlus32:
-+ name="MillenniumPlus";
-+ im_funcname = "DoCMilPlus_init";
-+ im_modname = "doc2001plus";
-+ break;
- }
-
- if (im_funcname)
-@@ -248,6 +316,7 @@
- return;
- }
- printk(KERN_NOTICE "Cannot find driver for DiskOnChip %s at 0x%lX\n", name, physadr);
-+ kfree(mtd);
- }
- iounmap((void *)docptr);
- }
-@@ -267,7 +336,7 @@
- printk(KERN_INFO "Using configured DiskOnChip probe address 0x%lx\n", doc_config_location);
- DoC_Probe(doc_config_location);
- } else {
-- for (i=0; doc_locations[i]; i++) {
-+ for (i=0; (doc_locations[i] != 0xffffffff); i++) {
- DoC_Probe(doc_locations[i]);
- }
- }
-@@ -275,11 +344,7 @@
- found, so the user knows we at least tried. */
- if (!docfound)
- printk(KERN_INFO "No recognised DiskOnChip devices found\n");
-- /* So it looks like we've been used and we get unloaded */
-- MOD_INC_USE_COUNT;
-- MOD_DEC_USE_COUNT;
-- return 0;
--
-+ return -EAGAIN;
- }
-
- module_init(init_doc);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/lart.c linux/drivers/mtd/devices/lart.c
---- linux-mips-2.4.27/drivers/mtd/devices/lart.c 2001-11-05 21:15:52.000000000 +0100
-+++ linux/drivers/mtd/devices/lart.c 2004-11-19 10:25:11.854206632 +0100
-@@ -2,7 +2,7 @@
- /*
- * MTD driver for the 28F160F3 Flash Memory (non-CFI) on LART.
- *
-- * $Id$
-+ * $Id$
- *
- * Author: Abraham vd Merwe <abraham@2d3d.co.za>
- *
-@@ -584,45 +584,40 @@
-
- static struct mtd_info mtd;
-
--static struct mtd_erase_region_info erase_regions[] =
--{
-+static struct mtd_erase_region_info erase_regions[] = {
- /* parameter blocks */
- {
-- offset: 0x00000000,
-- erasesize: FLASH_BLOCKSIZE_PARAM,
-- numblocks: FLASH_NUMBLOCKS_16m_PARAM
-+ .offset = 0x00000000,
-+ .erasesize = FLASH_BLOCKSIZE_PARAM,
-+ .numblocks = FLASH_NUMBLOCKS_16m_PARAM,
- },
- /* main blocks */
- {
-- offset: FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM,
-- erasesize: FLASH_BLOCKSIZE_MAIN,
-- numblocks: FLASH_NUMBLOCKS_16m_MAIN
-+ .offset = FLASH_BLOCKSIZE_PARAM * FLASH_NUMBLOCKS_16m_PARAM,
-+ .erasesize = FLASH_BLOCKSIZE_MAIN,
-+ .numblocks = FLASH_NUMBLOCKS_16m_MAIN,
- }
- };
-
- #ifdef HAVE_PARTITIONS
--static struct mtd_partition lart_partitions[] =
--{
-+static struct mtd_partition lart_partitions[] = {
- /* blob */
- {
-- name: "blob",
-- offset: BLOB_START,
-- size: BLOB_LEN,
-- mask_flags: 0
-+ .name = "blob",
-+ .offset = BLOB_START,
-+ .size = BLOB_LEN,
- },
- /* kernel */
- {
-- name: "kernel",
-- offset: KERNEL_START, /* MTDPART_OFS_APPEND */
-- size: KERNEL_LEN,
-- mask_flags: 0
-+ .name = "kernel",
-+ .offset = KERNEL_START, /* MTDPART_OFS_APPEND */
-+ .size = KERNEL_LEN,
- },
- /* initial ramdisk / file system */
- {
-- name: "file system",
-- offset: INITRD_START, /* MTDPART_OFS_APPEND */
-- size: INITRD_LEN, /* MTDPART_SIZ_FULL */
-- mask_flags: 0
-+ .name = "file system",
-+ .offset = INITRD_START, /* MTDPART_OFS_APPEND */
-+ .size = INITRD_LEN, /* MTDPART_SIZ_FULL */
- }
- };
- #endif
-@@ -646,10 +641,10 @@
- mtd.erasesize = FLASH_BLOCKSIZE_MAIN;
- mtd.numeraseregions = NB_OF (erase_regions);
- mtd.eraseregions = erase_regions;
-- mtd.module = THIS_MODULE;
- mtd.erase = flash_erase;
- mtd.read = flash_read;
- mtd.write = flash_write;
-+ mtd.owner = THIS_MODULE;
-
- #ifdef LART_DEBUG
- printk (KERN_DEBUG
-diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/ms02-nv.c linux/drivers/mtd/devices/ms02-nv.c
---- linux-mips-2.4.27/drivers/mtd/devices/ms02-nv.c 2004-07-30 12:22:40.000000000 +0200
-+++ linux/drivers/mtd/devices/ms02-nv.c 2004-11-19 10:25:11.856206328 +0100
-@@ -6,7 +6,7 @@
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/init.h>
-@@ -31,7 +31,7 @@
- static char version[] __initdata =
- "ms02-nv.c: v.1.0.0 13 Aug 2001 Maciej W. Rozycki.\n";
-
--MODULE_AUTHOR("Maciej W. Rozycki <macro@linux-mips.org>");
-+MODULE_AUTHOR("Maciej W. Rozycki <macro@ds2.pg.gda.pl>");
- MODULE_DESCRIPTION("DEC MS02-NV NVRAM module driver");
- MODULE_LICENSE("GPL");
-
-@@ -222,7 +222,7 @@
- mtd->flags = MTD_CAP_RAM | MTD_XIP;
- mtd->size = fixsize;
- mtd->name = (char *)ms02nv_name;
-- mtd->module = THIS_MODULE;
-+ mtd->owner = THIS_MODULE;
- mtd->read = ms02nv_read;
- mtd->write = ms02nv_write;
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/mtdram.c linux/drivers/mtd/devices/mtdram.c
---- linux-mips-2.4.27/drivers/mtd/devices/mtdram.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/devices/mtdram.c 2004-11-19 10:25:11.859205872 +0100
-@@ -1,6 +1,6 @@
- /*
- * mtdram - a test mtd device
-- * $Id$
-+ * $Id$
- * Author: Alexander Larsson <alex@cendio.se>
- *
- * Copyright (c) 1999 Alexander Larsson <alex@cendio.se>
-@@ -13,6 +13,8 @@
- #include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/ioport.h>
-+#include <linux/vmalloc.h>
-+#include <linux/init.h>
- #include <linux/mtd/compatmac.h>
- #include <linux/mtd/mtd.h>
-
-@@ -136,7 +138,7 @@
- mtd->erasesize = MTDRAM_ERASE_SIZE;
- mtd->priv = mapped_address;
-
-- mtd->module = THIS_MODULE;
-+ mtd->owner = THIS_MODULE;
- mtd->erase = ram_erase;
- mtd->point = ram_point;
- mtd->unpoint = ram_unpoint;
-diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/phram.c linux/drivers/mtd/devices/phram.c
---- linux-mips-2.4.27/drivers/mtd/devices/phram.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/devices/phram.c 2004-11-19 10:25:11.860205720 +0100
-@@ -0,0 +1,362 @@
-+/**
-+ *
-+ * $Id$
-+ *
-+ * Copyright (c) Jochen Schaeuble <psionic@psionic.de>
-+ * 07/2003 rewritten by Joern Engel <joern@wh.fh-wedel.de>
-+ *
-+ * DISCLAIMER: This driver makes use of Rusty's excellent module code,
-+ * so it will not work for 2.4 without changes and it wont work for 2.4
-+ * as a module without major changes. Oh well!
-+ *
-+ * Usage:
-+ *
-+ * one commend line parameter per device, each in the form:
-+ * phram=<name>,<start>,<len>
-+ * <name> may be up to 63 characters.
-+ * <start> and <len> can be octal, decimal or hexadecimal. If followed
-+ * by "k", "M" or "G", the numbers will be interpreted as kilo, mega or
-+ * gigabytes.
-+ *
-+ */
-+
-+#include <asm/io.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/list.h>
-+#include <linux/module.h>
-+#include <linux/moduleparam.h>
-+#include <linux/mtd/mtd.h>
-+
-+#define ERROR(fmt, args...) printk(KERN_ERR "phram: " fmt , ## args)
-+
-+struct phram_mtd_list {
-+ struct list_head list;
-+ struct mtd_info *mtdinfo;
-+};
-+
-+static LIST_HEAD(phram_list);
-+
-+
-+
-+int phram_erase(struct mtd_info *mtd, struct erase_info *instr)
-+{
-+ u_char *start = (u_char *)mtd->priv;
-+
-+ if (instr->addr + instr->len > mtd->size)
-+ return -EINVAL;
-+
-+ memset(start + instr->addr, 0xff, instr->len);
-+
-+ /* This'll catch a few races. Free the thing before returning :)
-+ * I don't feel at all ashamed. This kind of thing is possible anyway
-+ * with flash, but unlikely.
-+ */
-+
-+ instr->state = MTD_ERASE_DONE;
-+
-+ if (instr->callback)
-+ (*(instr->callback))(instr);
-+ else
-+ kfree(instr);
-+
-+ return 0;
-+}
-+
-+int phram_point(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t *retlen, u_char **mtdbuf)
-+{
-+ u_char *start = (u_char *)mtd->priv;
-+
-+ if (from + len > mtd->size)
-+ return -EINVAL;
-+
-+ *mtdbuf = start + from;
-+ *retlen = len;
-+ return 0;
-+}
-+
-+void phram_unpoint(struct mtd_info *mtd, u_char *addr, loff_t from, size_t len)
-+{
-+}
-+
-+int phram_read(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t *retlen, u_char *buf)
-+{
-+ u_char *start = (u_char *)mtd->priv;
-+
-+ if (from + len > mtd->size)
-+ return -EINVAL;
-+
-+ memcpy(buf, start + from, len);
-+
-+ *retlen = len;
-+ return 0;
-+}
-+
-+int phram_write(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t *retlen, const u_char *buf)
-+{
-+ u_char *start = (u_char *)mtd->priv;
-+
-+ if (to + len > mtd->size)
-+ return -EINVAL;
-+
-+ memcpy(start + to, buf, len);
-+
-+ *retlen = len;
-+ return 0;
-+}
-+
-+
-+
-+static void unregister_devices(void)
-+{
-+ struct phram_mtd_list *this;
-+
-+ list_for_each_entry(this, &phram_list, list) {
-+ del_mtd_device(this->mtdinfo);
-+ iounmap(this->mtdinfo->priv);
-+ kfree(this->mtdinfo);
-+ kfree(this);
-+ }
-+}
-+
-+static int register_device(char *name, unsigned long start, unsigned long len)
-+{
-+ struct phram_mtd_list *new;
-+ int ret = -ENOMEM;
-+
-+ new = kmalloc(sizeof(*new), GFP_KERNEL);
-+ if (!new)
-+ goto out0;
-+
-+ new->mtdinfo = kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
-+ if (!new->mtdinfo)
-+ goto out1;
-+
-+ memset(new->mtdinfo, 0, sizeof(struct mtd_info));
-+
-+ ret = -EIO;
-+ new->mtdinfo->priv = ioremap(start, len);
-+ if (!new->mtdinfo->priv) {
-+ ERROR("ioremap failed\n");
-+ goto out2;
-+ }
-+
-+
-+ new->mtdinfo->name = name;
-+ new->mtdinfo->size = len;
-+ new->mtdinfo->flags = MTD_CAP_RAM | MTD_ERASEABLE | MTD_VOLATILE;
-+ new->mtdinfo->erase = phram_erase;
-+ new->mtdinfo->point = phram_point;
-+ new->mtdinfo->unpoint = phram_unpoint;
-+ new->mtdinfo->read = phram_read;
-+ new->mtdinfo->write = phram_write;
-+ new->mtdinfo->owner = THIS_MODULE;
-+ new->mtdinfo->type = MTD_RAM;
-+ new->mtdinfo->erasesize = 0x0;
-+
-+ ret = -EAGAIN;
-+ if (add_mtd_device(new->mtdinfo)) {
-+ ERROR("Failed to register new device\n");
-+ goto out3;
-+ }
-+
-+ list_add_tail(&new->list, &phram_list);
-+ return 0;
-+
-+out3:
-+ iounmap(new->mtdinfo->priv);
-+out2:
-+ kfree(new->mtdinfo);
-+out1:
-+ kfree(new);
-+out0:
-+ return ret;
-+}
-+
-+static int ustrtoul(const char *cp, char **endp, unsigned int base)
-+{
-+ unsigned long result = simple_strtoul(cp, endp, base);
-+
-+ switch (**endp) {
-+ case 'G':
-+ result *= 1024;
-+ case 'M':
-+ result *= 1024;
-+ case 'k':
-+ result *= 1024;
-+ endp++;
-+ }
-+ return result;
-+}
-+
-+static int parse_num32(uint32_t *num32, const char *token)
-+{
-+ char *endp;
-+ unsigned long n;
-+
-+ n = ustrtoul(token, &endp, 0);
-+ if (*endp)
-+ return -EINVAL;
-+
-+ *num32 = n;
-+ return 0;
-+}
-+
-+static int parse_name(char **pname, const char *token)
-+{
-+ size_t len;
-+ char *name;
-+
-+ len = strlen(token) + 1;
-+ if (len > 64)
-+ return -ENOSPC;
-+
-+ name = kmalloc(len, GFP_KERNEL);
-+ if (!name)
-+ return -ENOMEM;
-+
-+ strcpy(name, token);
-+
-+ *pname = name;
-+ return 0;
-+}
-+
-+#define parse_err(fmt, args...) do { \
-+ ERROR(fmt , ## args); \
-+ return 0; \
-+} while (0)
-+
-+static int phram_setup(const char *val, struct kernel_param *kp)
-+{
-+ char buf[64+12+12], *str = buf;
-+ char *token[3];
-+ char *name;
-+ uint32_t start;
-+ uint32_t len;
-+ int i, ret;
-+
-+ if (strnlen(val, sizeof(str)) >= sizeof(str))
-+ parse_err("parameter too long\n");
-+
-+ strcpy(str, val);
-+
-+ for (i=0; i<3; i++)
-+ token[i] = strsep(&str, ",");
-+
-+ if (str)
-+ parse_err("too many arguments\n");
-+
-+ if (!token[2])
-+ parse_err("not enough arguments\n");
-+
-+ ret = parse_name(&name, token[0]);
-+ if (ret == -ENOMEM)
-+ parse_err("out of memory\n");
-+ if (ret == -ENOSPC)
-+ parse_err("name too long\n");
-+ if (ret)
-+ return 0;
-+
-+ ret = parse_num32(&start, token[1]);
-+ if (ret)
-+ parse_err("illegal start address\n");
-+
-+ ret = parse_num32(&len, token[2]);
-+ if (ret)
-+ parse_err("illegal device length\n");
-+
-+ register_device(name, start, len);
-+
-+ return 0;
-+}
-+
-+module_param_call(phram, phram_setup, NULL, NULL, 000);
-+MODULE_PARM_DESC(phram, "Memory region to map. \"map=<name>,<start><length>\"");
-+
-+/*
-+ * Just for compatibility with slram, this is horrible and should go someday.
-+ */
-+static int __init slram_setup(const char *val, struct kernel_param *kp)
-+{
-+ char buf[256], *str = buf;
-+
-+ if (!val || !val[0])
-+ parse_err("no arguments to \"slram=\"\n");
-+
-+ if (strnlen(val, sizeof(str)) >= sizeof(str))
-+ parse_err("parameter too long\n");
-+
-+ strcpy(str, val);
-+
-+ while (str) {
-+ char *token[3];
-+ char *name;
-+ uint32_t start;
-+ uint32_t len;
-+ int i, ret;
-+
-+ for (i=0; i<3; i++) {
-+ token[i] = strsep(&str, ",");
-+ if (token[i])
-+ continue;
-+ parse_err("wrong number of arguments to \"slram=\"\n");
-+ }
-+
-+ /* name */
-+ ret = parse_name(&name, token[0]);
-+ if (ret == -ENOMEM)
-+ parse_err("of memory\n");
-+ if (ret == -ENOSPC)
-+ parse_err("too long\n");
-+ if (ret)
-+ return 1;
-+
-+ /* start */
-+ ret = parse_num32(&start, token[1]);
-+ if (ret)
-+ parse_err("illegal start address\n");
-+
-+ /* len */
-+ if (token[2][0] == '+')
-+ ret = parse_num32(&len, token[2] + 1);
-+ else
-+ ret = parse_num32(&len, token[2]);
-+
-+ if (ret)
-+ parse_err("illegal device length\n");
-+
-+ if (token[2][0] != '+') {
-+ if (len < start)
-+ parse_err("end < start\n");
-+ len -= start;
-+ }
-+
-+ register_device(name, start, len);
-+ }
-+ return 1;
-+}
-+
-+module_param_call(slram, slram_setup, NULL, NULL, 000);
-+MODULE_PARM_DESC(slram, "List of memory regions to map. \"map=<name>,<start><length/end>\"");
-+
-+
-+int __init init_phram(void)
-+{
-+ printk(KERN_ERR "phram loaded\n");
-+ return 0;
-+}
-+
-+static void __exit cleanup_phram(void)
-+{
-+ unregister_devices();
-+}
-+
-+module_init(init_phram);
-+module_exit(cleanup_phram);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Jörn Engel <joern@wh.fh-wedel.de>");
-+MODULE_DESCRIPTION("MTD driver for physical RAM");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/pmc551.c linux/drivers/mtd/devices/pmc551.c
---- linux-mips-2.4.27/drivers/mtd/devices/pmc551.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/devices/pmc551.c 2004-11-19 10:25:11.862205416 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * PMC551 PCI Mezzanine Ram Device
- *
-@@ -681,11 +681,6 @@
-
- printk(KERN_INFO PMC551_VERSION);
-
-- if(!pci_present()) {
-- printk(KERN_NOTICE "pmc551: PCI not enabled.\n");
-- return -ENODEV;
-- }
--
- /*
- * PCU-bus chipset probe.
- */
-@@ -787,10 +782,10 @@
- mtd->write = pmc551_write;
- mtd->point = pmc551_point;
- mtd->unpoint = pmc551_unpoint;
-- mtd->module = THIS_MODULE;
- mtd->type = MTD_RAM;
- mtd->name = "PMC551 RAM board";
- mtd->erasesize = 0x10000;
-+ mtd->owner = THIS_MODULE;
-
- if (add_mtd_device(mtd)) {
- printk(KERN_NOTICE "pmc551: Failed to register new device\n");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/devices/slram.c linux/drivers/mtd/devices/slram.c
---- linux-mips-2.4.27/drivers/mtd/devices/slram.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/devices/slram.c 2004-11-19 10:25:11.863205264 +0100
-@@ -1,6 +1,6 @@
- /*======================================================================
-
-- $Id$
-+ $Id$
-
- This driver provides a method to access memory not used by the kernel
- itself (i.e. if the kernel commandline mem=xxx is used). To actually
-@@ -199,7 +199,7 @@
- (*curmtd)->mtdinfo->unpoint = slram_unpoint;
- (*curmtd)->mtdinfo->read = slram_read;
- (*curmtd)->mtdinfo->write = slram_write;
-- (*curmtd)->mtdinfo->module = THIS_MODULE;
-+ (*curmtd)->mtdinfo->owner = THIS_MODULE;
- (*curmtd)->mtdinfo->type = MTD_RAM;
- (*curmtd)->mtdinfo->erasesize = 0x0;
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/ftl.c linux/drivers/mtd/ftl.c
---- linux-mips-2.4.27/drivers/mtd/ftl.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/ftl.c 2004-11-19 10:25:11.630240680 +0100
-@@ -1,5 +1,5 @@
- /* This version ported to the Linux-MTD system by dwmw2@infradead.org
-- * $Id$
-+ * $Id$
- *
- * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
-@@ -55,8 +55,8 @@
- contact M-Systems (http://www.m-sys.com) directly.
-
- ======================================================================*/
-+#include <linux/mtd/blktrans.h>
- #include <linux/module.h>
--#include <linux/mtd/compatmac.h>
- #include <linux/mtd/mtd.h>
- /*#define PSYCHO_DEBUG */
-
-@@ -68,43 +68,13 @@
- #include <linux/timer.h>
- #include <linux/major.h>
- #include <linux/fs.h>
--#include <linux/ioctl.h>
-+#include <linux/init.h>
- #include <linux/hdreg.h>
--
--#if (LINUX_VERSION_CODE >= 0x20100)
- #include <linux/vmalloc.h>
--#endif
--#if (LINUX_VERSION_CODE >= 0x20303)
- #include <linux/blkpg.h>
--#endif
-+#include <asm/uaccess.h>
-
- #include <linux/mtd/ftl.h>
--/*====================================================================*/
--/* Stuff which really ought to be in compatmac.h */
--
--#if (LINUX_VERSION_CODE < 0x20328)
--#define register_disk(dev, drive, minors, ops, size) \
-- do { (dev)->part[(drive)*(minors)].nr_sects = size; \
-- if (size == 0) (dev)->part[(drive)*(minors)].start_sect = -1; \
-- resetup_one_dev(dev, drive); } while (0)
--#endif
--
--#if (LINUX_VERSION_CODE < 0x20320)
--#define BLK_DEFAULT_QUEUE(n) blk_dev[n].request_fn
--#define blk_init_queue(q, req) q = (req)
--#define blk_cleanup_queue(q) q = NULL
--#define request_arg_t void
--#else
--#define request_arg_t request_queue_t *q
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
--#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
--#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
--#else
--#define BLK_INC_USE_COUNT do {} while(0)
--#define BLK_DEC_USE_COUNT do {} while(0)
--#endif
-
- /*====================================================================*/
-
-@@ -119,19 +89,6 @@
- #define FTL_MAJOR 44
- #endif
-
--/* Funky stuff for setting up a block device */
--#define MAJOR_NR FTL_MAJOR
--#define DEVICE_NAME "ftl"
--#define DEVICE_REQUEST do_ftl_request
--#define DEVICE_ON(device)
--#define DEVICE_OFF(device)
--
--#define DEVICE_NR(minor) ((minor)>>5)
--#define REGION_NR(minor) (((minor)>>3)&3)
--#define PART_NR(minor) ((minor)&7)
--#define MINOR_NR(dev,reg,part) (((dev)<<5)+((reg)<<3)+(part))
--
--#include <linux/blk.h>
-
- /*====================================================================*/
-
-@@ -142,8 +99,7 @@
- #define MAX_REGION 4
-
- /* Maximum number of partitions in an FTL region */
--#define PART_BITS 3
--#define MAX_PART 8
-+#define PART_BITS 4
-
- /* Maximum number of outstanding erase requests per socket */
- #define MAX_ERASE 8
-@@ -154,7 +110,7 @@
-
- /* Each memory region corresponds to a minor device */
- typedef struct partition_t {
-- struct mtd_info *mtd;
-+ struct mtd_blktrans_dev mbd;
- u_int32_t state;
- u_int32_t *VirtualBlockMap;
- u_int32_t *VirtualPageMap;
-@@ -179,21 +135,10 @@
- region_info_t region;
- memory_handle_t handle;
- #endif
-- atomic_t open;
- } partition_t;
-
--partition_t *myparts[MAX_MTD_DEVICES];
--
--static void ftl_notify_add(struct mtd_info *mtd);
--static void ftl_notify_remove(struct mtd_info *mtd);
--
- void ftl_freepart(partition_t *part);
-
--static struct mtd_notifier ftl_notifier = {
-- add: ftl_notify_add,
-- remove: ftl_notify_remove,
--};
--
- /* Partition state flags */
- #define FTL_FORMATTED 0x01
-
-@@ -204,51 +149,11 @@
- #define XFER_PREPARED 0x03
- #define XFER_FAILED 0x04
-
--static struct hd_struct ftl_hd[MINOR_NR(MAX_DEV, 0, 0)];
--static int ftl_sizes[MINOR_NR(MAX_DEV, 0, 0)];
--static int ftl_blocksizes[MINOR_NR(MAX_DEV, 0, 0)];
--
--static struct gendisk ftl_gendisk = {
-- major: FTL_MAJOR,
-- major_name: "ftl",
-- minor_shift: PART_BITS,
-- max_p: MAX_PART,
--#if (LINUX_VERSION_CODE < 0x20328)
-- max_nr: MAX_DEV*MAX_PART,
--#endif
-- part: ftl_hd,
-- sizes: ftl_sizes,
--};
--
- /*====================================================================*/
-
--static int ftl_ioctl(struct inode *inode, struct file *file,
-- u_int cmd, u_long arg);
--static int ftl_open(struct inode *inode, struct file *file);
--static release_t ftl_close(struct inode *inode, struct file *file);
--static int ftl_reread_partitions(int minor);
-
- static void ftl_erase_callback(struct erase_info *done);
-
--#if LINUX_VERSION_CODE < 0x20326
--static struct file_operations ftl_blk_fops = {
-- open: ftl_open,
-- release: ftl_close,
-- ioctl: ftl_ioctl,
-- read: block_read,
-- write: block_write,
-- fsync: block_fsync
--};
--#else
--static struct block_device_operations ftl_blk_fops = {
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14)
-- owner: THIS_MODULE,
--#endif
-- open: ftl_open,
-- release: ftl_close,
-- ioctl: ftl_ioctl,
--};
--#endif
-
- /*======================================================================
-
-@@ -264,13 +169,13 @@
- loff_t offset, max_offset;
- int ret;
- part->header.FormattedSize = 0;
-- max_offset = (0x100000<part->mtd->size)?0x100000:part->mtd->size;
-+ max_offset = (0x100000<part->mbd.mtd->size)?0x100000:part->mbd.mtd->size;
- /* Search first megabyte for a valid FTL header */
- for (offset = 0;
- (offset + sizeof(header)) < max_offset;
-- offset += part->mtd->erasesize ? : 0x2000) {
-+ offset += part->mbd.mtd->erasesize ? : 0x2000) {
-
-- ret = part->mtd->read(part->mtd, offset, sizeof(header), &ret,
-+ ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &ret,
- (unsigned char *)&header);
-
- if (ret)
-@@ -283,15 +188,15 @@
- printk(KERN_NOTICE "ftl_cs: FTL header not found.\n");
- return -ENOENT;
- }
-- if ((le16_to_cpu(header.NumEraseUnits) > 65536) || header.BlockSize != 9 ||
-+ if (header.BlockSize != 9 ||
- (header.EraseUnitSize < 10) || (header.EraseUnitSize > 31) ||
- (header.NumTransferUnits >= le16_to_cpu(header.NumEraseUnits))) {
- printk(KERN_NOTICE "ftl_cs: FTL header corrupt!\n");
- return -1;
- }
-- if ((1 << header.EraseUnitSize) != part->mtd->erasesize) {
-+ if ((1 << header.EraseUnitSize) != part->mbd.mtd->erasesize) {
- printk(KERN_NOTICE "ftl: FTL EraseUnitSize %x != MTD erasesize %x\n",
-- 1 << header.EraseUnitSize,part->mtd->erasesize);
-+ 1 << header.EraseUnitSize,part->mbd.mtd->erasesize);
- return -1;
- }
- part->header = header;
-@@ -326,7 +231,7 @@
- for (i = 0; i < le16_to_cpu(part->header.NumEraseUnits); i++) {
- offset = ((i + le16_to_cpu(part->header.FirstPhysicalEUN))
- << part->header.EraseUnitSize);
-- ret = part->mtd->read(part->mtd, offset, sizeof(header), &retval,
-+ ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(header), &retval,
- (unsigned char *)&header);
-
- if (ret)
-@@ -391,7 +296,7 @@
- part->EUNInfo[i].Deleted = 0;
- offset = part->EUNInfo[i].Offset + le32_to_cpu(header.BAMOffset);
-
-- ret = part->mtd->read(part->mtd, offset,
-+ ret = part->mbd.mtd->read(part->mbd.mtd, offset,
- part->BlocksPerUnit * sizeof(u_int32_t), &retval,
- (unsigned char *)part->bam_cache);
-
-@@ -456,7 +361,7 @@
- erase->len = 1 << part->header.EraseUnitSize;
- erase->priv = (u_long)part;
-
-- ret = part->mtd->erase(part->mtd, erase);
-+ ret = part->mbd.mtd->erase(part->mbd.mtd, erase);
-
- if (!ret)
- xfer->EraseCount++;
-@@ -523,7 +428,7 @@
- header.LogicalEUN = cpu_to_le16(0xffff);
- header.EraseCount = cpu_to_le32(xfer->EraseCount);
-
-- ret = part->mtd->write(part->mtd, xfer->Offset, sizeof(header),
-+ ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset, sizeof(header),
- &retlen, (u_char *)&header);
-
- if (ret) {
-@@ -539,7 +444,7 @@
-
- for (i = 0; i < nbam; i++, offset += sizeof(u_int32_t)) {
-
-- ret = part->mtd->write(part->mtd, offset, sizeof(u_int32_t),
-+ ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t),
- &retlen, (u_char *)&ctl);
-
- if (ret)
-@@ -586,7 +491,7 @@
-
- offset = eun->Offset + le32_to_cpu(part->header.BAMOffset);
-
-- ret = part->mtd->read(part->mtd, offset,
-+ ret = part->mbd.mtd->read(part->mbd.mtd, offset,
- part->BlocksPerUnit * sizeof(u_int32_t),
- &retlen, (u_char *) (part->bam_cache));
-
-@@ -604,7 +509,7 @@
- offset = xfer->Offset + 20; /* Bad! */
- unit = cpu_to_le16(0x7fff);
-
-- ret = part->mtd->write(part->mtd, offset, sizeof(u_int16_t),
-+ ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int16_t),
- &retlen, (u_char *) &unit);
-
- if (ret) {
-@@ -624,7 +529,7 @@
- break;
- case BLOCK_DATA:
- case BLOCK_REPLACEMENT:
-- ret = part->mtd->read(part->mtd, src, SECTOR_SIZE,
-+ ret = part->mbd.mtd->read(part->mbd.mtd, src, SECTOR_SIZE,
- &retlen, (u_char *) buf);
- if (ret) {
- printk(KERN_WARNING "ftl: Error reading old xfer unit in copy_erase_unit\n");
-@@ -632,7 +537,7 @@
- }
-
-
-- ret = part->mtd->write(part->mtd, dest, SECTOR_SIZE,
-+ ret = part->mbd.mtd->write(part->mbd.mtd, dest, SECTOR_SIZE,
- &retlen, (u_char *) buf);
- if (ret) {
- printk(KERN_WARNING "ftl: Error writing new xfer unit in copy_erase_unit\n");
-@@ -651,7 +556,7 @@
- }
-
- /* Write the BAM to the transfer unit */
-- ret = part->mtd->write(part->mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset),
-+ ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + le32_to_cpu(part->header.BAMOffset),
- part->BlocksPerUnit * sizeof(int32_t), &retlen,
- (u_char *)part->bam_cache);
- if (ret) {
-@@ -661,7 +566,7 @@
-
-
- /* All clear? Then update the LogicalEUN again */
-- ret = part->mtd->write(part->mtd, xfer->Offset + 20, sizeof(u_int16_t),
-+ ret = part->mbd.mtd->write(part->mbd.mtd, xfer->Offset + 20, sizeof(u_int16_t),
- &retlen, (u_char *)&srcunitswap);
-
- if (ret) {
-@@ -749,8 +654,8 @@
- if (queued) {
- DEBUG(1, "ftl_cs: waiting for transfer "
- "unit to be prepared...\n");
-- if (part->mtd->sync)
-- part->mtd->sync(part->mtd);
-+ if (part->mbd.mtd->sync)
-+ part->mbd.mtd->sync(part->mbd.mtd);
- } else {
- static int ne = 0;
- if (++ne < 5)
-@@ -848,7 +753,7 @@
- /* Invalidate cache */
- part->bam_index = 0xffff;
-
-- ret = part->mtd->read(part->mtd,
-+ ret = part->mbd.mtd->read(part->mbd.mtd,
- part->EUNInfo[eun].Offset + le32_to_cpu(part->header.BAMOffset),
- part->BlocksPerUnit * sizeof(u_int32_t),
- &retlen, (u_char *) (part->bam_cache));
-@@ -877,78 +782,6 @@
-
- } /* find_free */
-
--/*======================================================================
--
-- This gets a memory handle for the region corresponding to the
-- minor device number.
--
--======================================================================*/
--
--static int ftl_open(struct inode *inode, struct file *file)
--{
-- int minor = MINOR(inode->i_rdev);
-- partition_t *partition;
--
-- if (minor>>4 >= MAX_MTD_DEVICES)
-- return -ENODEV;
--
-- partition = myparts[minor>>4];
--
-- if (!partition)
-- return -ENODEV;
--
-- if (partition->state != FTL_FORMATTED)
-- return -ENXIO;
--
-- if (ftl_gendisk.part[minor].nr_sects == 0)
-- return -ENXIO;
--
-- BLK_INC_USE_COUNT;
--
-- if (!get_mtd_device(partition->mtd, -1)) {
-- BLK_DEC_USE_COUNT;
-- return -ENXIO;
-- }
--
-- if ((file->f_mode & 2) && !(partition->mtd->flags & MTD_CLEAR_BITS) ) {
-- put_mtd_device(partition->mtd);
-- BLK_DEC_USE_COUNT;
-- return -EROFS;
-- }
--
-- DEBUG(0, "ftl_cs: ftl_open(%d)\n", minor);
--
-- atomic_inc(&partition->open);
--
-- return 0;
--}
--
--/*====================================================================*/
--
--static release_t ftl_close(struct inode *inode, struct file *file)
--{
-- int minor = MINOR(inode->i_rdev);
-- partition_t *part = myparts[minor >> 4];
-- int i;
--
-- DEBUG(0, "ftl_cs: ftl_close(%d)\n", minor);
--
-- /* Wait for any pending erase operations to complete */
-- if (part->mtd->sync)
-- part->mtd->sync(part->mtd);
--
-- for (i = 0; i < part->header.NumTransferUnits; i++) {
-- if (part->XferInfo[i].state == XFER_ERASED)
-- prepare_xfer(part, i);
-- }
--
-- atomic_dec(&part->open);
--
-- put_mtd_device(part->mtd);
-- BLK_DEC_USE_COUNT;
-- release_return(0);
--} /* ftl_close */
--
-
- /*======================================================================
-
-@@ -983,7 +816,7 @@
- else {
- offset = (part->EUNInfo[log_addr / bsize].Offset
- + (log_addr % bsize));
-- ret = part->mtd->read(part->mtd, offset, SECTOR_SIZE,
-+ ret = part->mbd.mtd->read(part->mbd.mtd, offset, SECTOR_SIZE,
- &retlen, (u_char *) buffer);
-
- if (ret) {
-@@ -1022,7 +855,7 @@
- le32_to_cpu(part->header.BAMOffset));
-
- #ifdef PSYCHO_DEBUG
-- ret = part->mtd->read(part->mtd, offset, sizeof(u_int32_t),
-+ ret = part->mbd.mtd->read(part->mbd.mtd, offset, sizeof(u_int32_t),
- &retlen, (u_char *)&old_addr);
- if (ret) {
- printk(KERN_WARNING"ftl: Error reading old_addr in set_bam_entry: %d\n",ret);
-@@ -1059,7 +892,7 @@
- #endif
- part->bam_cache[blk] = le_virt_addr;
- }
-- ret = part->mtd->write(part->mtd, offset, sizeof(u_int32_t),
-+ ret = part->mbd.mtd->write(part->mbd.mtd, offset, sizeof(u_int32_t),
- &retlen, (u_char *)&le_virt_addr);
-
- if (ret) {
-@@ -1119,7 +952,7 @@
- part->EUNInfo[part->bam_index].Deleted++;
- offset = (part->EUNInfo[part->bam_index].Offset +
- blk * SECTOR_SIZE);
-- ret = part->mtd->write(part->mtd, offset, SECTOR_SIZE, &retlen,
-+ ret = part->mbd.mtd->write(part->mbd.mtd, offset, SECTOR_SIZE, &retlen,
- buffer);
-
- if (ret) {
-@@ -1151,164 +984,32 @@
- return 0;
- } /* ftl_write */
-
--/*======================================================================
--
-- IOCTL calls for getting device parameters.
--
--======================================================================*/
--
--static int ftl_ioctl(struct inode *inode, struct file *file,
-- u_int cmd, u_long arg)
-+static int ftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
- {
-- struct hd_geometry *geo = (struct hd_geometry *)arg;
-- int ret = 0, minor = MINOR(inode->i_rdev);
-- partition_t *part= myparts[minor >> 4];
-+ partition_t *part = (void *)dev;
- u_long sect;
-
-- if (!part)
-- return -ENODEV; /* How? */
--
-- switch (cmd) {
-- case HDIO_GETGEO:
-- ret = verify_area(VERIFY_WRITE, (long *)arg, sizeof(*geo));
-- if (ret) return ret;
-- /* Sort of arbitrary: round size down to 4K boundary */
-+ /* Sort of arbitrary: round size down to 4KiB boundary */
- sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE;
-- put_user(1, (char *)&geo->heads);
-- put_user(8, (char *)&geo->sectors);
-- put_user((sect>>3), (short *)&geo->cylinders);
-- put_user(ftl_hd[minor].start_sect, (u_long *)&geo->start);
-- break;
-- case BLKGETSIZE:
-- ret = put_user(ftl_hd[minor].nr_sects, (unsigned long *)arg);
-- break;
--#ifdef BLKGETSIZE64
-- case BLKGETSIZE64:
-- ret = put_user((u64)ftl_hd[minor].nr_sects << 9, (u64 *)arg);
-- break;
--#endif
-- case BLKRRPART:
-- ret = ftl_reread_partitions(minor);
-- break;
--#if (LINUX_VERSION_CODE < 0x20303)
-- case BLKFLSBUF:
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-- if (!capable(CAP_SYS_ADMIN)) return -EACCES;
--#endif
-- fsync_dev(inode->i_rdev);
-- invalidate_buffers(inode->i_rdev);
-- break;
-- RO_IOCTLS(inode->i_rdev, arg);
--#else
-- case BLKROSET:
-- case BLKROGET:
-- case BLKFLSBUF:
-- ret = blk_ioctl(inode->i_rdev, cmd, arg);
-- break;
--#endif
-- default:
-- ret = -EINVAL;
-- }
--
-- return ret;
--} /* ftl_ioctl */
--
--/*======================================================================
-
-- Handler for block device requests
-+ geo->heads = 1;
-+ geo->sectors = 8;
-+ geo->cylinders = sect >> 3;
-
--======================================================================*/
--
--static int ftl_reread_partitions(int minor)
--{
-- partition_t *part = myparts[minor >> 4];
-- int i, whole;
--
-- DEBUG(0, "ftl_cs: ftl_reread_partition(%d)\n", minor);
-- if ((atomic_read(&part->open) > 1)) {
-- return -EBUSY;
-- }
-- whole = minor & ~(MAX_PART-1);
--
-- i = MAX_PART - 1;
-- while (i-- > 0) {
-- if (ftl_hd[whole+i].nr_sects > 0) {
-- kdev_t rdev = MKDEV(FTL_MAJOR, whole+i);
--
-- invalidate_device(rdev, 1);
-- }
-- ftl_hd[whole+i].start_sect = 0;
-- ftl_hd[whole+i].nr_sects = 0;
-- }
--
-- scan_header(part);
--
-- register_disk(&ftl_gendisk, whole >> PART_BITS, MAX_PART,
-- &ftl_blk_fops, le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE);
--
--#ifdef PCMCIA_DEBUG
-- for (i = 0; i < MAX_PART; i++) {
-- if (ftl_hd[whole+i].nr_sects > 0)
-- printk(KERN_INFO " %d: start %ld size %ld\n", i,
-- ftl_hd[whole+i].start_sect,
-- ftl_hd[whole+i].nr_sects);
-- }
--#endif
- return 0;
- }
-
--/*======================================================================
--
-- Handler for block device requests
--
--======================================================================*/
--
--static void do_ftl_request(request_arg_t)
-+static int ftl_readsect(struct mtd_blktrans_dev *dev,
-+ unsigned long block, char *buf)
- {
-- int ret, minor;
-- partition_t *part;
--
-- do {
-- // sti();
-- INIT_REQUEST;
--
-- minor = MINOR(CURRENT->rq_dev);
--
-- part = myparts[minor >> 4];
-- if (part) {
-- ret = 0;
--
-- switch (CURRENT->cmd) {
-- case READ:
-- ret = ftl_read(part, CURRENT->buffer,
-- CURRENT->sector+ftl_hd[minor].start_sect,
-- CURRENT->current_nr_sectors);
-- if (ret) printk("ftl_read returned %d\n", ret);
-- break;
--
-- case WRITE:
-- ret = ftl_write(part, CURRENT->buffer,
-- CURRENT->sector+ftl_hd[minor].start_sect,
-- CURRENT->current_nr_sectors);
-- if (ret) printk("ftl_write returned %d\n", ret);
-- break;
--
-- default:
-- panic("ftl_cs: unknown block command!\n");
--
-- }
-- } else {
-- ret = 1;
-- printk("NULL part in ftl_request\n");
-- }
--
-- if (!ret) {
-- CURRENT->sector += CURRENT->current_nr_sectors;
-- }
-+ return ftl_read((void *)dev, buf, block, 1);
-+}
-
-- end_request((ret == 0) ? 1 : 0);
-- } while (1);
--} /* do_ftl_request */
-+static int ftl_writesect(struct mtd_blktrans_dev *dev,
-+ unsigned long block, char *buf)
-+{
-+ return ftl_write((void *)dev, buf, block, 1);
-+}
-
- /*====================================================================*/
-
-@@ -1337,19 +1038,9 @@
-
- } /* ftl_freepart */
-
--static void ftl_notify_add(struct mtd_info *mtd)
-+static void ftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
- {
- partition_t *partition;
-- int device;
--
-- for (device=0; device < MAX_MTD_DEVICES && myparts[device]; device++)
-- ;
--
-- if (device == MAX_MTD_DEVICES) {
-- printk(KERN_NOTICE "Maximum number of FTL partitions reached\n"
-- "Not scanning <%s>\n", mtd->name);
-- return;
-- }
-
- partition = kmalloc(sizeof(partition_t), GFP_KERNEL);
-
-@@ -1361,92 +1052,55 @@
-
- memset(partition, 0, sizeof(partition_t));
-
-- partition->mtd = mtd;
-+ partition->mbd.mtd = mtd;
-
- if ((scan_header(partition) == 0) &&
- (build_maps(partition) == 0)) {
-
- partition->state = FTL_FORMATTED;
-- atomic_set(&partition->open, 0);
-- myparts[device] = partition;
-- ftl_reread_partitions(device << 4);
- #ifdef PCMCIA_DEBUG
-- printk(KERN_INFO "ftl_cs: opening %d kb FTL partition\n",
-+ printk(KERN_INFO "ftl_cs: opening %d KiB FTL partition\n",
- le32_to_cpu(partition->header.FormattedSize) >> 10);
- #endif
-+ partition->mbd.size = le32_to_cpu(partition->header.FormattedSize) >> 9;
-+ partition->mbd.blksize = SECTOR_SIZE;
-+ partition->mbd.tr = tr;
-+ partition->mbd.devnum = -1;
-+ if (add_mtd_blktrans_dev((void *)partition))
-+ kfree(partition);
-+
- } else
- kfree(partition);
- }
-
--static void ftl_notify_remove(struct mtd_info *mtd)
-+static void ftl_remove_dev(struct mtd_blktrans_dev *dev)
- {
-- int i,j;
--
-- /* Q: What happens if you try to remove a device which has
-- * a currently-open FTL partition on it?
-- *
-- * A: You don't. The ftl_open routine is responsible for
-- * increasing the use count of the driver module which
-- * it uses.
-- */
--
-- /* That's the theory, anyway :) */
--
-- for (i=0; i< MAX_MTD_DEVICES; i++)
-- if (myparts[i] && myparts[i]->mtd == mtd) {
--
-- if (myparts[i]->state == FTL_FORMATTED)
-- ftl_freepart(myparts[i]);
--
-- myparts[i]->state = 0;
-- for (j=0; j<16; j++) {
-- ftl_gendisk.part[j].nr_sects=0;
-- ftl_gendisk.part[j].start_sect=0;
-- }
-- kfree(myparts[i]);
-- myparts[i] = NULL;
-- }
-+ del_mtd_blktrans_dev(dev);
-+ kfree(dev);
- }
-
-+struct mtd_blktrans_ops ftl_tr = {
-+ .name = "ftl",
-+ .major = FTL_MAJOR,
-+ .part_bits = PART_BITS,
-+ .readsect = ftl_readsect,
-+ .writesect = ftl_writesect,
-+ .getgeo = ftl_getgeo,
-+ .add_mtd = ftl_add_mtd,
-+ .remove_dev = ftl_remove_dev,
-+ .owner = THIS_MODULE,
-+};
-+
- int init_ftl(void)
- {
-- int i;
--
-- memset(myparts, 0, sizeof(myparts));
-+ DEBUG(0, "$Id$\n");
-
-- DEBUG(0, "$Id$\n");
--
-- if (register_blkdev(FTL_MAJOR, "ftl", &ftl_blk_fops)) {
-- printk(KERN_NOTICE "ftl_cs: unable to grab major "
-- "device number!\n");
-- return -EAGAIN;
-- }
--
-- for (i = 0; i < MINOR_NR(MAX_DEV, 0, 0); i++)
-- ftl_blocksizes[i] = 1024;
-- for (i = 0; i < MAX_DEV*MAX_PART; i++) {
-- ftl_hd[i].nr_sects = 0;
-- ftl_hd[i].start_sect = 0;
-- }
-- blksize_size[FTL_MAJOR] = ftl_blocksizes;
-- ftl_gendisk.major = FTL_MAJOR;
-- blk_init_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR), &do_ftl_request);
-- add_gendisk(&ftl_gendisk);
--
-- register_mtd_user(&ftl_notifier);
--
-- return 0;
-+ return register_mtd_blktrans(&ftl_tr);
- }
-
- static void __exit cleanup_ftl(void)
- {
-- unregister_mtd_user(&ftl_notifier);
--
-- unregister_blkdev(FTL_MAJOR, "ftl");
-- blk_cleanup_queue(BLK_DEFAULT_QUEUE(FTL_MAJOR));
-- blksize_size[FTL_MAJOR] = NULL;
--
-- del_gendisk(&ftl_gendisk);
-+ deregister_mtd_blktrans(&ftl_tr);
- }
-
- module_init(init_ftl);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/inftlcore.c linux/drivers/mtd/inftlcore.c
---- linux-mips-2.4.27/drivers/mtd/inftlcore.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/inftlcore.c 2004-11-19 10:25:11.632240376 +0100
-@@ -0,0 +1,900 @@
-+/*
-+ * inftlcore.c -- Linux driver for Inverse Flash Translation Layer (INFTL)
-+ *
-+ * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
-+ *
-+ * Based heavily on the nftlcore.c code which is:
-+ * (c) 1999 Machine Vision Holdings, Inc.
-+ * Author: David Woodhouse <dwmw2@infradead.org>
-+ *
-+ * $Id$
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/init.h>
-+#include <linux/kmod.h>
-+#include <linux/hdreg.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nftl.h>
-+#include <linux/mtd/inftl.h>
-+#include <asm/uaccess.h>
-+#include <asm/errno.h>
-+#include <asm/io.h>
-+
-+/*
-+ * Maximum number of loops while examining next block, to have a
-+ * chance to detect consistency problems (they should never happen
-+ * because of the checks done in the mounting.
-+ */
-+#define MAX_LOOPS 10000
-+
-+extern void INFTL_dumptables(struct INFTLrecord *inftl);
-+extern void INFTL_dumpVUchains(struct INFTLrecord *inftl);
-+
-+static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
-+{
-+ struct INFTLrecord *inftl;
-+ unsigned long temp;
-+
-+ if (mtd->ecctype != MTD_ECC_RS_DiskOnChip)
-+ return;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: add_mtd for %s\n", mtd->name);
-+
-+ inftl = kmalloc(sizeof(*inftl), GFP_KERNEL);
-+
-+ if (!inftl) {
-+ printk(KERN_WARNING "INFTL: Out of memory for data structures\n");
-+ return;
-+ }
-+ memset(inftl, 0, sizeof(*inftl));
-+
-+ inftl->mbd.mtd = mtd;
-+ inftl->mbd.devnum = -1;
-+ inftl->mbd.blksize = 512;
-+ inftl->mbd.tr = tr;
-+
-+ if (INFTL_mount(inftl) < 0) {
-+ printk(KERN_WARNING "INFTL: could not mount device\n");
-+ kfree(inftl);
-+ return;
-+ }
-+
-+ /* OK, it's a new one. Set up all the data structures. */
-+
-+ /* Calculate geometry */
-+ inftl->cylinders = 1024;
-+ inftl->heads = 16;
-+
-+ temp = inftl->cylinders * inftl->heads;
-+ inftl->sectors = inftl->mbd.size / temp;
-+ if (inftl->mbd.size % temp) {
-+ inftl->sectors++;
-+ temp = inftl->cylinders * inftl->sectors;
-+ inftl->heads = inftl->mbd.size / temp;
-+
-+ if (inftl->mbd.size % temp) {
-+ inftl->heads++;
-+ temp = inftl->heads * inftl->sectors;
-+ inftl->cylinders = inftl->mbd.size / temp;
-+ }
-+ }
-+
-+ if (inftl->mbd.size != inftl->heads * inftl->cylinders * inftl->sectors) {
-+ /*
-+ Oh no we don't have
-+ mbd.size == heads * cylinders * sectors
-+ */
-+ printk(KERN_WARNING "INFTL: cannot calculate a geometry to "
-+ "match size of 0x%lx.\n", inftl->mbd.size);
-+ printk(KERN_WARNING "INFTL: using C:%d H:%d S:%d "
-+ "(== 0x%lx sects)\n",
-+ inftl->cylinders, inftl->heads , inftl->sectors,
-+ (long)inftl->cylinders * (long)inftl->heads *
-+ (long)inftl->sectors );
-+ }
-+
-+ if (add_mtd_blktrans_dev(&inftl->mbd)) {
-+ if (inftl->PUtable)
-+ kfree(inftl->PUtable);
-+ if (inftl->VUtable)
-+ kfree(inftl->VUtable);
-+ kfree(inftl);
-+ return;
-+ }
-+#ifdef PSYCHO_DEBUG
-+ printk(KERN_INFO "INFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a');
-+#endif
-+ return;
-+}
-+
-+static void inftl_remove_dev(struct mtd_blktrans_dev *dev)
-+{
-+ struct INFTLrecord *inftl = (void *)dev;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: remove_dev (i=%d)\n", dev->devnum);
-+
-+ del_mtd_blktrans_dev(dev);
-+
-+ if (inftl->PUtable)
-+ kfree(inftl->PUtable);
-+ if (inftl->VUtable)
-+ kfree(inftl->VUtable);
-+ kfree(inftl);
-+}
-+
-+/*
-+ * Actual INFTL access routines.
-+ */
-+
-+/*
-+ * INFTL_findfreeblock: Find a free Erase Unit on the INFTL partition.
-+ * This function is used when the give Virtual Unit Chain.
-+ */
-+static u16 INFTL_findfreeblock(struct INFTLrecord *inftl, int desperate)
-+{
-+ u16 pot = inftl->LastFreeEUN;
-+ int silly = inftl->nb_blocks;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_findfreeblock(inftl=0x%x,"
-+ "desperate=%d)\n", (int)inftl, desperate);
-+
-+ /*
-+ * Normally, we force a fold to happen before we run out of free
-+ * blocks completely.
-+ */
-+ if (!desperate && inftl->numfreeEUNs < 2) {
-+ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: there are too few free "
-+ "EUNs (%d)\n", inftl->numfreeEUNs);
-+ return 0xffff;
-+ }
-+
-+ /* Scan for a free block */
-+ do {
-+ if (inftl->PUtable[pot] == BLOCK_FREE) {
-+ inftl->LastFreeEUN = pot;
-+ return pot;
-+ }
-+
-+ if (++pot > inftl->lastEUN)
-+ pot = 0;
-+
-+ if (!silly--) {
-+ printk(KERN_WARNING "INFTL: no free blocks found! "
-+ "EUN range = %d - %d\n", 0, inftl->LastFreeEUN);
-+ return BLOCK_NIL;
-+ }
-+ } while (pot != inftl->LastFreeEUN);
-+
-+ return BLOCK_NIL;
-+}
-+
-+static u16 INFTL_foldchain(struct INFTLrecord *inftl, unsigned thisVUC, unsigned pendingblock)
-+{
-+ u16 BlockMap[MAX_SECTORS_PER_UNIT];
-+ unsigned char BlockDeleted[MAX_SECTORS_PER_UNIT];
-+ unsigned int thisEUN, prevEUN, status;
-+ int block, silly;
-+ unsigned int targetEUN;
-+ struct inftl_oob oob;
-+ size_t retlen;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_foldchain(inftl=0x%x,thisVUC=%d,"
-+ "pending=%d)\n", (int)inftl, thisVUC, pendingblock);
-+
-+ memset(BlockMap, 0xff, sizeof(BlockMap));
-+ memset(BlockDeleted, 0, sizeof(BlockDeleted));
-+
-+ thisEUN = targetEUN = inftl->VUtable[thisVUC];
-+
-+ if (thisEUN == BLOCK_NIL) {
-+ printk(KERN_WARNING "INFTL: trying to fold non-existent "
-+ "Virtual Unit Chain %d!\n", thisVUC);
-+ return BLOCK_NIL;
-+ }
-+
-+ /*
-+ * Scan to find the Erase Unit which holds the actual data for each
-+ * 512-byte block within the Chain.
-+ */
-+ silly = MAX_LOOPS;
-+ while (thisEUN < inftl->nb_blocks) {
-+ for (block = 0; block < inftl->EraseSize/SECTORSIZE; block ++) {
-+ if ((BlockMap[block] != 0xffff) || BlockDeleted[block])
-+ continue;
-+
-+ if (MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize)
-+ + (block * SECTORSIZE), 16 , &retlen,
-+ (char *)&oob) < 0)
-+ status = SECTOR_IGNORE;
-+ else
-+ status = oob.b.Status | oob.b.Status1;
-+
-+ switch(status) {
-+ case SECTOR_FREE:
-+ case SECTOR_IGNORE:
-+ break;
-+ case SECTOR_USED:
-+ BlockMap[block] = thisEUN;
-+ continue;
-+ case SECTOR_DELETED:
-+ BlockDeleted[block] = 1;
-+ continue;
-+ default:
-+ printk(KERN_WARNING "INFTL: unknown status "
-+ "for block %d in EUN %d: %x\n",
-+ block, thisEUN, status);
-+ break;
-+ }
-+ }
-+
-+ if (!silly--) {
-+ printk(KERN_WARNING "INFTL: infinite loop in Virtual "
-+ "Unit Chain 0x%x\n", thisVUC);
-+ return BLOCK_NIL;
-+ }
-+
-+ thisEUN = inftl->PUtable[thisEUN];
-+ }
-+
-+ /*
-+ * OK. We now know the location of every block in the Virtual Unit
-+ * Chain, and the Erase Unit into which we are supposed to be copying.
-+ * Go for it.
-+ */
-+ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: folding chain %d into unit %d\n",
-+ thisVUC, targetEUN);
-+
-+ for (block = 0; block < inftl->EraseSize/SECTORSIZE ; block++) {
-+ unsigned char movebuf[SECTORSIZE];
-+ int ret;
-+
-+ /*
-+ * If it's in the target EUN already, or if it's pending write,
-+ * do nothing.
-+ */
-+ if (BlockMap[block] == targetEUN || (pendingblock ==
-+ (thisVUC * (inftl->EraseSize / SECTORSIZE) + block))) {
-+ continue;
-+ }
-+
-+ /*
-+ * Copy only in non free block (free blocks can only
-+ * happen in case of media errors or deleted blocks).
-+ */
-+ if (BlockMap[block] == BLOCK_NIL)
-+ continue;
-+
-+ ret = MTD_READECC(inftl->mbd.mtd, (inftl->EraseSize *
-+ BlockMap[block]) + (block * SECTORSIZE), SECTORSIZE,
-+ &retlen, movebuf, (char *)&oob, NULL);
-+ if (ret < 0) {
-+ ret = MTD_READECC(inftl->mbd.mtd, (inftl->EraseSize *
-+ BlockMap[block]) + (block * SECTORSIZE),
-+ SECTORSIZE, &retlen, movebuf, (char *)&oob,
-+ NULL);
-+ if (ret != -EIO)
-+ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: error went "
-+ "away on retry?\n");
-+ }
-+ MTD_WRITEECC(inftl->mbd.mtd, (inftl->EraseSize * targetEUN) +
-+ (block * SECTORSIZE), SECTORSIZE, &retlen,
-+ movebuf, (char *)&oob, NULL);
-+ }
-+
-+ /*
-+ * Newest unit in chain now contains data from _all_ older units.
-+ * So go through and erase each unit in chain, oldest first. (This
-+ * is important, by doing oldest first if we crash/reboot then it
-+ * it is relatively simple to clean up the mess).
-+ */
-+ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: want to erase virtual chain %d\n",
-+ thisVUC);
-+
-+ for (;;) {
-+ /* Find oldest unit in chain. */
-+ thisEUN = inftl->VUtable[thisVUC];
-+ prevEUN = BLOCK_NIL;
-+ while (inftl->PUtable[thisEUN] != BLOCK_NIL) {
-+ prevEUN = thisEUN;
-+ thisEUN = inftl->PUtable[thisEUN];
-+ }
-+
-+ /* Check if we are all done */
-+ if (thisEUN == targetEUN)
-+ break;
-+
-+ if (INFTL_formatblock(inftl, thisEUN) < 0) {
-+ /*
-+ * Could not erase : mark block as reserved.
-+ * FixMe: Update Bad Unit Table on disk.
-+ */
-+ inftl->PUtable[thisEUN] = BLOCK_RESERVED;
-+ } else {
-+ /* Correctly erased : mark it as free */
-+ inftl->PUtable[thisEUN] = BLOCK_FREE;
-+ inftl->PUtable[prevEUN] = BLOCK_NIL;
-+ inftl->numfreeEUNs++;
-+ }
-+ }
-+
-+ return targetEUN;
-+}
-+
-+u16 INFTL_makefreeblock(struct INFTLrecord *inftl, unsigned pendingblock)
-+{
-+ /*
-+ * This is the part that needs some cleverness applied.
-+ * For now, I'm doing the minimum applicable to actually
-+ * get the thing to work.
-+ * Wear-levelling and other clever stuff needs to be implemented
-+ * and we also need to do some assessment of the results when
-+ * the system loses power half-way through the routine.
-+ */
-+ u16 LongestChain = 0;
-+ u16 ChainLength = 0, thislen;
-+ u16 chain, EUN;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_makefreeblock(inftl=0x%x,"
-+ "pending=%d)\n", (int)inftl, pendingblock);
-+
-+ for (chain = 0; chain < inftl->nb_blocks; chain++) {
-+ EUN = inftl->VUtable[chain];
-+ thislen = 0;
-+
-+ while (EUN <= inftl->lastEUN) {
-+ thislen++;
-+ EUN = inftl->PUtable[EUN];
-+ if (thislen > 0xff00) {
-+ printk(KERN_WARNING "INFTL: endless loop in "
-+ "Virtual Chain %d: Unit %x\n",
-+ chain, EUN);
-+ /*
-+ * Actually, don't return failure.
-+ * Just ignore this chain and get on with it.
-+ */
-+ thislen = 0;
-+ break;
-+ }
-+ }
-+
-+ if (thislen > ChainLength) {
-+ ChainLength = thislen;
-+ LongestChain = chain;
-+ }
-+ }
-+
-+ if (ChainLength < 2) {
-+ printk(KERN_WARNING "INFTL: no Virtual Unit Chains available "
-+ "for folding. Failing request\n");
-+ return BLOCK_NIL;
-+ }
-+
-+ return INFTL_foldchain(inftl, LongestChain, pendingblock);
-+}
-+
-+static int nrbits(unsigned int val, int bitcount)
-+{
-+ int i, total = 0;
-+
-+ for (i = 0; (i < bitcount); i++)
-+ total += (((0x1 << i) & val) ? 1 : 0);
-+ return total;
-+}
-+
-+/*
-+ * INFTL_findwriteunit: Return the unit number into which we can write
-+ * for this block. Make it available if it isn't already.
-+ */
-+static inline u16 INFTL_findwriteunit(struct INFTLrecord *inftl, unsigned block)
-+{
-+ unsigned int thisVUC = block / (inftl->EraseSize / SECTORSIZE);
-+ unsigned int thisEUN, writeEUN, prev_block, status;
-+ unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize -1);
-+ struct inftl_oob oob;
-+ struct inftl_bci bci;
-+ unsigned char anac, nacs, parity;
-+ size_t retlen;
-+ int silly, silly2 = 3;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_findwriteunit(inftl=0x%x,"
-+ "block=%d)\n", (int)inftl, block);
-+
-+ do {
-+ /*
-+ * Scan the media to find a unit in the VUC which has
-+ * a free space for the block in question.
-+ */
-+ writeEUN = BLOCK_NIL;
-+ thisEUN = inftl->VUtable[thisVUC];
-+ silly = MAX_LOOPS;
-+
-+ while (thisEUN <= inftl->lastEUN) {
-+ MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) +
-+ blockofs, 8, &retlen, (char *)&bci);
-+
-+ status = bci.Status | bci.Status1;
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: status of block %d in "
-+ "EUN %d is %x\n", block , writeEUN, status);
-+
-+ switch(status) {
-+ case SECTOR_FREE:
-+ writeEUN = thisEUN;
-+ break;
-+ case SECTOR_DELETED:
-+ case SECTOR_USED:
-+ /* Can't go any further */
-+ goto hitused;
-+ case SECTOR_IGNORE:
-+ break;
-+ default:
-+ /*
-+ * Invalid block. Don't use it any more.
-+ * Must implement.
-+ */
-+ break;
-+ }
-+
-+ if (!silly--) {
-+ printk(KERN_WARNING "INFTL: infinite loop in "
-+ "Virtual Unit Chain 0x%x\n", thisVUC);
-+ return 0xffff;
-+ }
-+
-+ /* Skip to next block in chain */
-+ thisEUN = inftl->PUtable[thisEUN];
-+ }
-+
-+hitused:
-+ if (writeEUN != BLOCK_NIL)
-+ return writeEUN;
-+
-+
-+ /*
-+ * OK. We didn't find one in the existing chain, or there
-+ * is no existing chain. Allocate a new one.
-+ */
-+ writeEUN = INFTL_findfreeblock(inftl, 0);
-+
-+ if (writeEUN == BLOCK_NIL) {
-+ /*
-+ * That didn't work - there were no free blocks just
-+ * waiting to be picked up. We're going to have to fold
-+ * a chain to make room.
-+ */
-+ thisEUN = INFTL_makefreeblock(inftl, 0xffff);
-+
-+ /*
-+ * Hopefully we free something, lets try again.
-+ * This time we are desperate...
-+ */
-+ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: using desperate==1 "
-+ "to find free EUN to accommodate write to "
-+ "VUC %d\n", thisVUC);
-+ writeEUN = INFTL_findfreeblock(inftl, 1);
-+ if (writeEUN == BLOCK_NIL) {
-+ /*
-+ * Ouch. This should never happen - we should
-+ * always be able to make some room somehow.
-+ * If we get here, we've allocated more storage
-+ * space than actual media, or our makefreeblock
-+ * routine is missing something.
-+ */
-+ printk(KERN_WARNING "INFTL: cannot make free "
-+ "space.\n");
-+#ifdef DEBUG
-+ INFTL_dumptables(inftl);
-+ INFTL_dumpVUchains(inftl);
-+#endif
-+ return BLOCK_NIL;
-+ }
-+ }
-+
-+ /*
-+ * Insert new block into virtual chain. Firstly update the
-+ * block headers in flash...
-+ */
-+ anac = 0;
-+ nacs = 0;
-+ thisEUN = inftl->VUtable[thisVUC];
-+ if (thisEUN != BLOCK_NIL) {
-+ MTD_READOOB(inftl->mbd.mtd, thisEUN * inftl->EraseSize
-+ + 8, 8, &retlen, (char *)&oob.u);
-+ anac = oob.u.a.ANAC + 1;
-+ nacs = oob.u.a.NACs + 1;
-+ }
-+
-+ prev_block = inftl->VUtable[thisVUC];
-+ if (prev_block < inftl->nb_blocks)
-+ prev_block -= inftl->firstEUN;
-+
-+ parity = (nrbits(thisVUC, 16) & 0x1) ? 0x1 : 0;
-+ parity |= (nrbits(prev_block, 16) & 0x1) ? 0x2 : 0;
-+ parity |= (nrbits(anac, 8) & 0x1) ? 0x4 : 0;
-+ parity |= (nrbits(nacs, 8) & 0x1) ? 0x8 : 0;
-+
-+ oob.u.a.virtualUnitNo = cpu_to_le16(thisVUC);
-+ oob.u.a.prevUnitNo = cpu_to_le16(prev_block);
-+ oob.u.a.ANAC = anac;
-+ oob.u.a.NACs = nacs;
-+ oob.u.a.parityPerField = parity;
-+ oob.u.a.discarded = 0xaa;
-+
-+ MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize + 8, 8,
-+ &retlen, (char *)&oob.u);
-+
-+ /* Also back up header... */
-+ oob.u.b.virtualUnitNo = cpu_to_le16(thisVUC);
-+ oob.u.b.prevUnitNo = cpu_to_le16(prev_block);
-+ oob.u.b.ANAC = anac;
-+ oob.u.b.NACs = nacs;
-+ oob.u.b.parityPerField = parity;
-+ oob.u.b.discarded = 0xaa;
-+
-+ MTD_WRITEOOB(inftl->mbd.mtd, writeEUN * inftl->EraseSize +
-+ SECTORSIZE * 4 + 8, 8, &retlen, (char *)&oob.u);
-+
-+ inftl->PUtable[writeEUN] = inftl->VUtable[thisVUC];
-+ inftl->VUtable[thisVUC] = writeEUN;
-+
-+ inftl->numfreeEUNs--;
-+ return writeEUN;
-+
-+ } while (silly2--);
-+
-+ printk(KERN_WARNING "INFTL: error folding to make room for Virtual "
-+ "Unit Chain 0x%x\n", thisVUC);
-+ return 0xffff;
-+}
-+
-+/*
-+ * Given a Virtual Unit Chain, see if it can be deleted, and if so do it.
-+ */
-+static void INFTL_trydeletechain(struct INFTLrecord *inftl, unsigned thisVUC)
-+{
-+ unsigned char BlockUsed[MAX_SECTORS_PER_UNIT];
-+ unsigned char BlockDeleted[MAX_SECTORS_PER_UNIT];
-+ unsigned int thisEUN, status;
-+ int block, silly;
-+ struct inftl_bci bci;
-+ size_t retlen;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_trydeletechain(inftl=0x%x,"
-+ "thisVUC=%d)\n", (int)inftl, thisVUC);
-+
-+ memset(BlockUsed, 0, sizeof(BlockUsed));
-+ memset(BlockDeleted, 0, sizeof(BlockDeleted));
-+
-+ thisEUN = inftl->VUtable[thisVUC];
-+ if (thisEUN == BLOCK_NIL) {
-+ printk(KERN_WARNING "INFTL: trying to delete non-existent "
-+ "Virtual Unit Chain %d!\n", thisVUC);
-+ return;
-+ }
-+
-+ /*
-+ * Scan through the Erase Units to determine whether any data is in
-+ * each of the 512-byte blocks within the Chain.
-+ */
-+ silly = MAX_LOOPS;
-+ while (thisEUN < inftl->nb_blocks) {
-+ for (block = 0; block < inftl->EraseSize/SECTORSIZE; block++) {
-+ if (BlockUsed[block] || BlockDeleted[block])
-+ continue;
-+
-+ if (MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize)
-+ + (block * SECTORSIZE), 8 , &retlen,
-+ (char *)&bci) < 0)
-+ status = SECTOR_IGNORE;
-+ else
-+ status = bci.Status | bci.Status1;
-+
-+ switch(status) {
-+ case SECTOR_FREE:
-+ case SECTOR_IGNORE:
-+ break;
-+ case SECTOR_USED:
-+ BlockUsed[block] = 1;
-+ continue;
-+ case SECTOR_DELETED:
-+ BlockDeleted[block] = 1;
-+ continue;
-+ default:
-+ printk(KERN_WARNING "INFTL: unknown status "
-+ "for block %d in EUN %d: 0x%x\n",
-+ block, thisEUN, status);
-+ }
-+ }
-+
-+ if (!silly--) {
-+ printk(KERN_WARNING "INFTL: infinite loop in Virtual "
-+ "Unit Chain 0x%x\n", thisVUC);
-+ return;
-+ }
-+
-+ thisEUN = inftl->PUtable[thisEUN];
-+ }
-+
-+ for (block = 0; block < inftl->EraseSize/SECTORSIZE; block++)
-+ if (BlockUsed[block])
-+ return;
-+
-+ /*
-+ * For each block in the chain free it and make it available
-+ * for future use. Erase from the oldest unit first.
-+ */
-+ DEBUG(MTD_DEBUG_LEVEL1, "INFTL: deleting empty VUC %d\n", thisVUC);
-+
-+ for (;;) {
-+ u16 *prevEUN = &inftl->VUtable[thisVUC];
-+ thisEUN = *prevEUN;
-+
-+ /* If the chain is all gone already, we're done */
-+ if (thisEUN == BLOCK_NIL) {
-+ DEBUG(MTD_DEBUG_LEVEL2, "INFTL: Empty VUC %d for deletion was already absent\n", thisEUN);
-+ return;
-+ }
-+
-+ /* Find oldest unit in chain. */
-+ while (inftl->PUtable[thisEUN] != BLOCK_NIL) {
-+ BUG_ON(thisEUN >= inftl->nb_blocks);
-+
-+ prevEUN = &inftl->PUtable[thisEUN];
-+ thisEUN = *prevEUN;
-+ }
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "Deleting EUN %d from VUC %d\n",
-+ thisEUN, thisVUC);
-+
-+ if (INFTL_formatblock(inftl, thisEUN) < 0) {
-+ /*
-+ * Could not erase : mark block as reserved.
-+ * FixMe: Update Bad Unit Table on medium.
-+ */
-+ inftl->PUtable[thisEUN] = BLOCK_RESERVED;
-+ } else {
-+ /* Correctly erased : mark it as free */
-+ inftl->PUtable[thisEUN] = BLOCK_FREE;
-+ inftl->numfreeEUNs++;
-+ }
-+
-+ /* Now sort out whatever was pointing to it... */
-+ *prevEUN = BLOCK_NIL;
-+
-+ /* Ideally we'd actually be responsive to new
-+ requests while we're doing this -- if there's
-+ free space why should others be made to wait? */
-+ cond_resched();
-+ }
-+
-+ inftl->VUtable[thisVUC] = BLOCK_NIL;
-+}
-+
-+static int INFTL_deleteblock(struct INFTLrecord *inftl, unsigned block)
-+{
-+ unsigned int thisEUN = inftl->VUtable[block / (inftl->EraseSize / SECTORSIZE)];
-+ unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1);
-+ unsigned int status;
-+ int silly = MAX_LOOPS;
-+ size_t retlen;
-+ struct inftl_bci bci;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_deleteblock(inftl=0x%x,"
-+ "block=%d)\n", (int)inftl, block);
-+
-+ while (thisEUN < inftl->nb_blocks) {
-+ if (MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) +
-+ blockofs, 8, &retlen, (char *)&bci) < 0)
-+ status = SECTOR_IGNORE;
-+ else
-+ status = bci.Status | bci.Status1;
-+
-+ switch (status) {
-+ case SECTOR_FREE:
-+ case SECTOR_IGNORE:
-+ break;
-+ case SECTOR_DELETED:
-+ thisEUN = BLOCK_NIL;
-+ goto foundit;
-+ case SECTOR_USED:
-+ goto foundit;
-+ default:
-+ printk(KERN_WARNING "INFTL: unknown status for "
-+ "block %d in EUN %d: 0x%x\n",
-+ block, thisEUN, status);
-+ break;
-+ }
-+
-+ if (!silly--) {
-+ printk(KERN_WARNING "INFTL: infinite loop in Virtual "
-+ "Unit Chain 0x%x\n",
-+ block / (inftl->EraseSize / SECTORSIZE));
-+ return 1;
-+ }
-+ thisEUN = inftl->PUtable[thisEUN];
-+ }
-+
-+foundit:
-+ if (thisEUN != BLOCK_NIL) {
-+ loff_t ptr = (thisEUN * inftl->EraseSize) + blockofs;
-+
-+ if (MTD_READOOB(inftl->mbd.mtd, ptr, 8, &retlen, (char *)&bci) < 0)
-+ return -EIO;
-+ bci.Status = bci.Status1 = SECTOR_DELETED;
-+ if (MTD_WRITEOOB(inftl->mbd.mtd, ptr, 8, &retlen, (char *)&bci) < 0)
-+ return -EIO;
-+ INFTL_trydeletechain(inftl, block / (inftl->EraseSize / SECTORSIZE));
-+ }
-+ return 0;
-+}
-+
-+static int inftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
-+ char *buffer)
-+{
-+ struct INFTLrecord *inftl = (void *)mbd;
-+ unsigned int writeEUN;
-+ unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1);
-+ size_t retlen;
-+ u8 eccbuf[6];
-+ char *p, *pend;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_writeblock(inftl=0x%x,block=%d,"
-+ "buffer=0x%x)\n", (int)inftl, block, (int)buffer);
-+
-+ /* Is block all zero? */
-+ pend = buffer + SECTORSIZE;
-+ for (p = buffer; p < pend && !*p; p++)
-+ ;
-+
-+ if (p < pend) {
-+ writeEUN = INFTL_findwriteunit(inftl, block);
-+
-+ if (writeEUN == BLOCK_NIL) {
-+ printk(KERN_WARNING "inftl_writeblock(): cannot find "
-+ "block to write to\n");
-+ /*
-+ * If we _still_ haven't got a block to use,
-+ * we're screwed.
-+ */
-+ return 1;
-+ }
-+
-+ MTD_WRITEECC(inftl->mbd.mtd, (writeEUN * inftl->EraseSize) +
-+ blockofs, SECTORSIZE, &retlen, (char *)buffer,
-+ (char *)eccbuf, NULL);
-+ /*
-+ * No need to write SECTOR_USED flags since they are written
-+ * in mtd_writeecc
-+ */
-+ } else {
-+ INFTL_deleteblock(inftl, block);
-+ }
-+
-+ return 0;
-+}
-+
-+static int inftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
-+ char *buffer)
-+{
-+ struct INFTLrecord *inftl = (void *)mbd;
-+ unsigned int thisEUN = inftl->VUtable[block / (inftl->EraseSize / SECTORSIZE)];
-+ unsigned long blockofs = (block * SECTORSIZE) & (inftl->EraseSize - 1);
-+ unsigned int status;
-+ int silly = MAX_LOOPS;
-+ struct inftl_bci bci;
-+ size_t retlen;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: inftl_readblock(inftl=0x%x,block=%d,"
-+ "buffer=0x%x)\n", (int)inftl, block, (int)buffer);
-+
-+ while (thisEUN < inftl->nb_blocks) {
-+ if (MTD_READOOB(inftl->mbd.mtd, (thisEUN * inftl->EraseSize) +
-+ blockofs, 8, &retlen, (char *)&bci) < 0)
-+ status = SECTOR_IGNORE;
-+ else
-+ status = bci.Status | bci.Status1;
-+
-+ switch (status) {
-+ case SECTOR_DELETED:
-+ thisEUN = BLOCK_NIL;
-+ goto foundit;
-+ case SECTOR_USED:
-+ goto foundit;
-+ case SECTOR_FREE:
-+ case SECTOR_IGNORE:
-+ break;
-+ default:
-+ printk(KERN_WARNING "INFTL: unknown status for "
-+ "block %ld in EUN %d: 0x%04x\n",
-+ block, thisEUN, status);
-+ break;
-+ }
-+
-+ if (!silly--) {
-+ printk(KERN_WARNING "INFTL: infinite loop in "
-+ "Virtual Unit Chain 0x%lx\n",
-+ block / (inftl->EraseSize / SECTORSIZE));
-+ return 1;
-+ }
-+
-+ thisEUN = inftl->PUtable[thisEUN];
-+ }
-+
-+foundit:
-+ if (thisEUN == BLOCK_NIL) {
-+ /* The requested block is not on the media, return all 0x00 */
-+ memset(buffer, 0, SECTORSIZE);
-+ } else {
-+ size_t retlen;
-+ loff_t ptr = (thisEUN * inftl->EraseSize) + blockofs;
-+ u_char eccbuf[6];
-+ if (MTD_READECC(inftl->mbd.mtd, ptr, SECTORSIZE, &retlen,
-+ buffer, eccbuf, NULL))
-+ return -EIO;
-+ }
-+ return 0;
-+}
-+
-+static int inftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
-+{
-+ struct INFTLrecord *inftl = (void *)dev;
-+
-+ geo->heads = inftl->heads;
-+ geo->sectors = inftl->sectors;
-+ geo->cylinders = inftl->cylinders;
-+
-+ return 0;
-+}
-+
-+struct mtd_blktrans_ops inftl_tr = {
-+ .name = "inftl",
-+ .major = INFTL_MAJOR,
-+ .part_bits = INFTL_PARTN_BITS,
-+ .getgeo = inftl_getgeo,
-+ .readsect = inftl_readblock,
-+ .writesect = inftl_writeblock,
-+ .add_mtd = inftl_add_mtd,
-+ .remove_dev = inftl_remove_dev,
-+ .owner = THIS_MODULE,
-+};
-+
-+extern char inftlmountrev[];
-+
-+int __init init_inftl(void)
-+{
-+ printk(KERN_INFO "INFTL: inftlcore.c $Revision$, "
-+ "inftlmount.c %s\n", inftlmountrev);
-+
-+ return register_mtd_blktrans(&inftl_tr);
-+}
-+
-+static void __exit cleanup_inftl(void)
-+{
-+ deregister_mtd_blktrans(&inftl_tr);
-+}
-+
-+module_init(init_inftl);
-+module_exit(cleanup_inftl);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>, David Woodhouse <dwmw2@infradead.org>, Fabrice Bellard <fabrice.bellard@netgem.com> et al.");
-+MODULE_DESCRIPTION("Support code for Inverse Flash Translation Layer, used on M-Systems DiskOnChip 2000, Millennium and Millennium Plus");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/inftlmount.c linux/drivers/mtd/inftlmount.c
---- linux-mips-2.4.27/drivers/mtd/inftlmount.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/inftlmount.c 2004-11-19 10:25:11.633240224 +0100
-@@ -0,0 +1,817 @@
-+/*
-+ * inftlmount.c -- INFTL mount code with extensive checks.
-+ *
-+ * Author: Greg Ungerer (gerg@snapgear.com)
-+ * (C) Copyright 2002-2003, Greg Ungerer (gerg@snapgear.com)
-+ *
-+ * Based heavily on the nftlmount.c code which is:
-+ * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
-+ * Copyright (C) 2000 Netgem S.A.
-+ *
-+ * $Id$
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <asm/errno.h>
-+#include <asm/io.h>
-+#include <asm/uaccess.h>
-+#include <linux/miscdevice.h>
-+#include <linux/pci.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/init.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nftl.h>
-+#include <linux/mtd/inftl.h>
-+#include <linux/mtd/compatmac.h>
-+
-+char inftlmountrev[]="$Revision$";
-+
-+/*
-+ * find_boot_record: Find the INFTL Media Header and its Spare copy which
-+ * contains the various device information of the INFTL partition and
-+ * Bad Unit Table. Update the PUtable[] table according to the Bad
-+ * Unit Table. PUtable[] is used for management of Erase Unit in
-+ * other routines in inftlcore.c and inftlmount.c.
-+ */
-+static int find_boot_record(struct INFTLrecord *inftl)
-+{
-+ struct inftl_unittail h1;
-+ //struct inftl_oob oob;
-+ unsigned int i, block, boot_record_count = 0;
-+ u8 buf[SECTORSIZE];
-+ struct INFTLMediaHeader *mh = &inftl->MediaHdr;
-+ struct INFTLPartition *ip;
-+ int retlen;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: find_boot_record(inftl=0x%x)\n",
-+ (int)inftl);
-+
-+ /*
-+ * Assume logical EraseSize == physical erasesize for starting the
-+ * scan. We'll sort it out later if we find a MediaHeader which says
-+ * otherwise.
-+ */
-+ inftl->EraseSize = inftl->mbd.mtd->erasesize;
-+ inftl->nb_blocks = inftl->mbd.mtd->size / inftl->EraseSize;
-+
-+ inftl->MediaUnit = BLOCK_NIL;
-+ inftl->SpareMediaUnit = BLOCK_NIL;
-+
-+ /* Search for a valid boot record */
-+ for (block = 0; block < inftl->nb_blocks; block++) {
-+ int ret;
-+
-+ /*
-+ * Check for BNAND header first. Then whinge if it's found
-+ * but later checks fail.
-+ */
-+ if ((ret = MTD_READ(inftl->mbd.mtd, block * inftl->EraseSize,
-+ SECTORSIZE, &retlen, buf))) {
-+ static int warncount = 5;
-+
-+ if (warncount) {
-+ printk(KERN_WARNING "INFTL: block read at 0x%x "
-+ "of mtd%d failed: %d\n",
-+ block * inftl->EraseSize,
-+ inftl->mbd.mtd->index, ret);
-+ if (!--warncount)
-+ printk(KERN_WARNING "INFTL: further "
-+ "failures for this block will "
-+ "not be printed\n");
-+ }
-+ continue;
-+ }
-+
-+ if (retlen < 6 || memcmp(buf, "BNAND", 6)) {
-+ /* BNAND\0 not found. Continue */
-+ continue;
-+ }
-+
-+ /* To be safer with BIOS, also use erase mark as discriminant */
-+ if ((ret = MTD_READOOB(inftl->mbd.mtd, block * inftl->EraseSize +
-+ SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0)) {
-+ printk(KERN_WARNING "INFTL: ANAND header found at "
-+ "0x%x in mtd%d, but OOB data read failed "
-+ "(err %d)\n", block * inftl->EraseSize,
-+ inftl->mbd.mtd->index, ret);
-+ continue;
-+ }
-+
-+ if (boot_record_count) {
-+ /*
-+ * We've already processed one. So we just check if
-+ * this one is the same as the first one we found.
-+ */
-+ if (memcmp(mh, buf, sizeof(struct INFTLMediaHeader))) {
-+ printk(KERN_WARNING "INFTL: Media Headers at "
-+ "0x%x and 0x%x disagree.\n",
-+ inftl->MediaUnit * inftl->EraseSize,
-+ block * inftl->EraseSize);
-+ return -1;
-+ }
-+ if (boot_record_count == 1)
-+ inftl->SpareMediaUnit = block;
-+
-+ /*
-+ * Mark this boot record (INFTL MediaHeader) block as
-+ * reserved.
-+ */
-+ inftl->PUtable[block] = BLOCK_RESERVED;
-+
-+ boot_record_count++;
-+ continue;
-+ }
-+
-+ /*
-+ * This is the first we've seen.
-+ * Copy the media header structure into place.
-+ */
-+ memcpy(mh, buf, sizeof(struct INFTLMediaHeader));
-+ mh->NoOfBootImageBlocks = le32_to_cpu(mh->NoOfBootImageBlocks);
-+ mh->NoOfBinaryPartitions = le32_to_cpu(mh->NoOfBinaryPartitions);
-+ mh->NoOfBDTLPartitions = le32_to_cpu(mh->NoOfBDTLPartitions);
-+ mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits);
-+ mh->FormatFlags = le32_to_cpu(mh->FormatFlags);
-+ mh->PercentUsed = le32_to_cpu(mh->PercentUsed);
-+
-+#ifdef CONFIG_MTD_DEBUG_VERBOSE
-+ if (CONFIG_MTD_DEBUG_VERBOSE >= 2) {
-+ printk("INFTL: Media Header ->\n"
-+ " bootRecordID = %s\n"
-+ " NoOfBootImageBlocks = %d\n"
-+ " NoOfBinaryPartitions = %d\n"
-+ " NoOfBDTLPartitions = %d\n"
-+ " BlockMultiplerBits = %d\n"
-+ " FormatFlgs = %d\n"
-+ " OsakVersion = 0x%x\n"
-+ " PercentUsed = %d\n",
-+ mh->bootRecordID, mh->NoOfBootImageBlocks,
-+ mh->NoOfBinaryPartitions,
-+ mh->NoOfBDTLPartitions,
-+ mh->BlockMultiplierBits, mh->FormatFlags,
-+ mh->OsakVersion, mh->PercentUsed);
-+ }
-+#endif
-+
-+ if (mh->NoOfBDTLPartitions == 0) {
-+ printk(KERN_WARNING "INFTL: Media Header sanity check "
-+ "failed: NoOfBDTLPartitions (%d) == 0, "
-+ "must be at least 1\n", mh->NoOfBDTLPartitions);
-+ return -1;
-+ }
-+
-+ if ((mh->NoOfBDTLPartitions + mh->NoOfBinaryPartitions) > 4) {
-+ printk(KERN_WARNING "INFTL: Media Header sanity check "
-+ "failed: Total Partitions (%d) > 4, "
-+ "BDTL=%d Binary=%d\n", mh->NoOfBDTLPartitions +
-+ mh->NoOfBinaryPartitions,
-+ mh->NoOfBDTLPartitions,
-+ mh->NoOfBinaryPartitions);
-+ return -1;
-+ }
-+
-+ if (mh->BlockMultiplierBits > 1) {
-+ printk(KERN_WARNING "INFTL: sorry, we don't support "
-+ "UnitSizeFactor 0x%02x\n",
-+ mh->BlockMultiplierBits);
-+ return -1;
-+ } else if (mh->BlockMultiplierBits == 1) {
-+ printk(KERN_WARNING "INFTL: support for INFTL with "
-+ "UnitSizeFactor 0x%02x is experimental\n",
-+ mh->BlockMultiplierBits);
-+ inftl->EraseSize = inftl->mbd.mtd->erasesize <<
-+ (0xff - mh->BlockMultiplierBits);
-+ inftl->nb_blocks = inftl->mbd.mtd->size / inftl->EraseSize;
-+ }
-+
-+ /* Scan the partitions */
-+ for (i = 0; (i < 4); i++) {
-+ ip = &mh->Partitions[i];
-+ ip->virtualUnits = le32_to_cpu(ip->virtualUnits);
-+ ip->firstUnit = le32_to_cpu(ip->firstUnit);
-+ ip->lastUnit = le32_to_cpu(ip->lastUnit);
-+ ip->flags = le32_to_cpu(ip->flags);
-+ ip->spareUnits = le32_to_cpu(ip->spareUnits);
-+ ip->Reserved0 = le32_to_cpu(ip->Reserved0);
-+
-+#ifdef CONFIG_MTD_DEBUG_VERBOSE
-+ if (CONFIG_MTD_DEBUG_VERBOSE >= 2) {
-+ printk(" PARTITION[%d] ->\n"
-+ " virtualUnits = %d\n"
-+ " firstUnit = %d\n"
-+ " lastUnit = %d\n"
-+ " flags = 0x%x\n"
-+ " spareUnits = %d\n",
-+ i, ip->virtualUnits, ip->firstUnit,
-+ ip->lastUnit, ip->flags,
-+ ip->spareUnits);
-+ }
-+#endif
-+
-+ if (ip->Reserved0 != ip->firstUnit) {
-+ struct erase_info *instr = &inftl->instr;
-+
-+ /*
-+ * Most likely this is using the
-+ * undocumented qiuck mount feature.
-+ * We don't support that, we will need
-+ * to erase the hidden block for full
-+ * compatibility.
-+ */
-+ instr->addr = ip->Reserved0 * inftl->EraseSize;
-+ instr->len = inftl->EraseSize;
-+ MTD_ERASE(inftl->mbd.mtd, instr);
-+ }
-+ if ((ip->lastUnit - ip->firstUnit + 1) < ip->virtualUnits) {
-+ printk(KERN_WARNING "INFTL: Media Header "
-+ "Partition %d sanity check failed\n"
-+ " firstUnit %d : lastUnit %d > "
-+ "virtualUnits %d\n", i, ip->lastUnit,
-+ ip->firstUnit, ip->Reserved0);
-+ return -1;
-+ }
-+ if (ip->Reserved1 != 0) {
-+ printk(KERN_WARNING "INFTL: Media Header "
-+ "Partition %d sanity check failed: "
-+ "Reserved1 %d != 0\n",
-+ i, ip->Reserved1);
-+ return -1;
-+ }
-+
-+ if (ip->flags & INFTL_BDTL)
-+ break;
-+ }
-+
-+ if (i >= 4) {
-+ printk(KERN_WARNING "INFTL: Media Header Partition "
-+ "sanity check failed:\n No partition "
-+ "marked as Disk Partition\n");
-+ return -1;
-+ }
-+
-+ inftl->nb_boot_blocks = ip->firstUnit;
-+ inftl->numvunits = ip->virtualUnits;
-+ if (inftl->numvunits > (inftl->nb_blocks -
-+ inftl->nb_boot_blocks - 2)) {
-+ printk(KERN_WARNING "INFTL: Media Header sanity check "
-+ "failed:\n numvunits (%d) > nb_blocks "
-+ "(%d) - nb_boot_blocks(%d) - 2\n",
-+ inftl->numvunits, inftl->nb_blocks,
-+ inftl->nb_boot_blocks);
-+ return -1;
-+ }
-+
-+ inftl->mbd.size = inftl->numvunits *
-+ (inftl->EraseSize / SECTORSIZE);
-+
-+ /*
-+ * Block count is set to last used EUN (we won't need to keep
-+ * any meta-data past that point).
-+ */
-+ inftl->firstEUN = ip->firstUnit;
-+ inftl->lastEUN = ip->lastUnit;
-+ inftl->nb_blocks = ip->lastUnit + 1;
-+
-+ /* Memory alloc */
-+ inftl->PUtable = kmalloc(inftl->nb_blocks * sizeof(u16), GFP_KERNEL);
-+ if (!inftl->PUtable) {
-+ printk(KERN_WARNING "INFTL: allocation of PUtable "
-+ "failed (%d bytes)\n",
-+ inftl->nb_blocks * sizeof(u16));
-+ return -ENOMEM;
-+ }
-+
-+ inftl->VUtable = kmalloc(inftl->nb_blocks * sizeof(u16), GFP_KERNEL);
-+ if (!inftl->VUtable) {
-+ kfree(inftl->PUtable);
-+ printk(KERN_WARNING "INFTL: allocation of VUtable "
-+ "failed (%d bytes)\n",
-+ inftl->nb_blocks * sizeof(u16));
-+ return -ENOMEM;
-+ }
-+
-+ /* Mark the blocks before INFTL MediaHeader as reserved */
-+ for (i = 0; i < inftl->nb_boot_blocks; i++)
-+ inftl->PUtable[i] = BLOCK_RESERVED;
-+ /* Mark all remaining blocks as potentially containing data */
-+ for (; i < inftl->nb_blocks; i++)
-+ inftl->PUtable[i] = BLOCK_NOTEXPLORED;
-+
-+ /* Mark this boot record (NFTL MediaHeader) block as reserved */
-+ inftl->PUtable[block] = BLOCK_RESERVED;
-+
-+#if 0
-+ /* Read Bad Erase Unit Table and modify PUtable[] accordingly */
-+ for (i = 0; i < inftl->nb_blocks; i++) {
-+ if ((i & (SECTORSIZE - 1)) == 0) {
-+ /* read one sector for every SECTORSIZE of blocks */
-+ if ((ret = MTD_READECC(inftl->mbd.mtd,
-+ block * inftl->EraseSize + i + SECTORSIZE,
-+ SECTORSIZE, &retlen, buf,
-+ (char *)&oob, NULL)) < 0) {
-+ printk(KERN_WARNING "INFTL: read of "
-+ "bad sector table failed "
-+ "(err %d)\n", ret);
-+ kfree(inftl->VUtable);
-+ kfree(inftl->PUtable);
-+ return -1;
-+ }
-+ }
-+ /* Mark the Bad Erase Unit as RESERVED in PUtable */
-+ if (buf[i & (SECTORSIZE - 1)] != 0xff)
-+ inftl->PUtable[i] = BLOCK_RESERVED;
-+ }
-+#endif
-+
-+ inftl->MediaUnit = block;
-+ boot_record_count++;
-+ }
-+
-+ return boot_record_count ? 0 : -1;
-+}
-+
-+static int memcmpb(void *a, int c, int n)
-+{
-+ int i;
-+ for (i = 0; i < n; i++) {
-+ if (c != ((unsigned char *)a)[i])
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * check_free_sector: check if a free sector is actually FREE,
-+ * i.e. All 0xff in data and oob area.
-+ */
-+static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address,
-+ int len, int check_oob)
-+{
-+ int i, retlen;
-+ u8 buf[SECTORSIZE];
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: check_free_sectors(inftl=0x%x,"
-+ "address=0x%x,len=%d,check_oob=%d)\n", (int)inftl,
-+ address, len, check_oob);
-+
-+ for (i = 0; i < len; i += SECTORSIZE) {
-+ /*
-+ * We want to read the sector without ECC check here since a
-+ * free sector does not have ECC syndrome on it yet.
-+ */
-+ if (MTD_READ(inftl->mbd.mtd, address, SECTORSIZE, &retlen, buf) < 0)
-+ return -1;
-+ if (memcmpb(buf, 0xff, SECTORSIZE) != 0)
-+ return -1;
-+
-+ if (check_oob) {
-+ if (MTD_READOOB(inftl->mbd.mtd, address,
-+ inftl->mbd.mtd->oobsize, &retlen, buf) < 0)
-+ return -1;
-+ if (memcmpb(buf, 0xff, inftl->mbd.mtd->oobsize) != 0)
-+ return -1;
-+ }
-+ address += SECTORSIZE;
-+ }
-+
-+ return 0;
-+}
-+
-+/*
-+ * INFTL_format: format a Erase Unit by erasing ALL Erase Zones in the Erase
-+ * Unit and Update INFTL metadata. Each erase operation is
-+ * checked with check_free_sectors.
-+ *
-+ * Return: 0 when succeed, -1 on error.
-+ *
-+ * ToDo: 1. Is it neceressary to check_free_sector after erasing ??
-+ * 2. UnitSizeFactor != 0xFF
-+ */
-+int INFTL_formatblock(struct INFTLrecord *inftl, int block)
-+{
-+ int retlen;
-+ struct inftl_unittail uci;
-+ struct erase_info *instr = &inftl->instr;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_formatblock(inftl=0x%x,"
-+ "block=%d)\n", (int)inftl, block);
-+
-+ memset(instr, 0, sizeof(struct erase_info));
-+
-+ /* FIXME: Shouldn't we be setting the 'discarded' flag to zero
-+ _first_? */
-+
-+ /* Use async erase interface, test return code */
-+ instr->addr = block * inftl->EraseSize;
-+ instr->len = inftl->EraseSize;
-+ MTD_ERASE(inftl->mbd.mtd, instr);
-+
-+ if (instr->state == MTD_ERASE_FAILED) {
-+ /*
-+ * Could not format, FixMe: We should update the BadUnitTable
-+ * both in memory and on disk.
-+ */
-+ printk(KERN_WARNING "INFTL: error while formatting block %d\n",
-+ block);
-+ return -1;
-+ }
-+
-+ /*
-+ * Check the "freeness" of Erase Unit before updating metadata.
-+ * FixMe: is this check really necessary? Since we have check the
-+ * return code after the erase operation.
-+ */
-+ if (check_free_sectors(inftl, instr->addr, inftl->EraseSize, 1) != 0)
-+ return -1;
-+
-+ uci.EraseMark = cpu_to_le16(ERASE_MARK);
-+ uci.EraseMark1 = cpu_to_le16(ERASE_MARK);
-+ uci.Reserved[0] = 0;
-+ uci.Reserved[1] = 0;
-+ uci.Reserved[2] = 0;
-+ uci.Reserved[3] = 0;
-+ if (MTD_WRITEOOB(inftl->mbd.mtd, block * inftl->EraseSize + SECTORSIZE * 2 +
-+ 8, 8, &retlen, (char *)&uci) < 0)
-+ return -1;
-+ return 0;
-+}
-+
-+/*
-+ * format_chain: Format an invalid Virtual Unit chain. It frees all the Erase
-+ * Units in a Virtual Unit Chain, i.e. all the units are disconnected.
-+ *
-+ * Since the chain is invalid then we will have to erase it from its
-+ * head (normally for INFTL we go from the oldest). But if it has a
-+ * loop then there is no oldest...
-+ */
-+static void format_chain(struct INFTLrecord *inftl, unsigned int first_block)
-+{
-+ unsigned int block = first_block, block1;
-+
-+ printk(KERN_WARNING "INFTL: formatting chain at block %d\n",
-+ first_block);
-+
-+ for (;;) {
-+ block1 = inftl->PUtable[block];
-+
-+ printk(KERN_WARNING "INFTL: formatting block %d\n", block);
-+ if (INFTL_formatblock(inftl, block) < 0) {
-+ /*
-+ * Cannot format !!!! Mark it as Bad Unit,
-+ * FixMe: update the BadUnitTable on disk.
-+ */
-+ inftl->PUtable[block] = BLOCK_RESERVED;
-+ } else {
-+ inftl->PUtable[block] = BLOCK_FREE;
-+ }
-+
-+ /* Goto next block on the chain */
-+ block = block1;
-+
-+ if (block == BLOCK_NIL || block >= inftl->lastEUN)
-+ break;
-+ }
-+}
-+
-+void INFTL_dumptables(struct INFTLrecord *s)
-+{
-+ int i;
-+
-+ printk("-------------------------------------------"
-+ "----------------------------------\n");
-+
-+ printk("VUtable[%d] ->", s->nb_blocks);
-+ for (i = 0; i < s->nb_blocks; i++) {
-+ if ((i % 8) == 0)
-+ printk("\n%04x: ", i);
-+ printk("%04x ", s->VUtable[i]);
-+ }
-+
-+ printk("\n-------------------------------------------"
-+ "----------------------------------\n");
-+
-+ printk("PUtable[%d-%d=%d] ->", s->firstEUN, s->lastEUN, s->nb_blocks);
-+ for (i = 0; i <= s->lastEUN; i++) {
-+ if ((i % 8) == 0)
-+ printk("\n%04x: ", i);
-+ printk("%04x ", s->PUtable[i]);
-+ }
-+
-+ printk("\n-------------------------------------------"
-+ "----------------------------------\n");
-+
-+ printk("INFTL ->\n"
-+ " EraseSize = %d\n"
-+ " h/s/c = %d/%d/%d\n"
-+ " numvunits = %d\n"
-+ " firstEUN = %d\n"
-+ " lastEUN = %d\n"
-+ " numfreeEUNs = %d\n"
-+ " LastFreeEUN = %d\n"
-+ " nb_blocks = %d\n"
-+ " nb_boot_blocks = %d",
-+ s->EraseSize, s->heads, s->sectors, s->cylinders,
-+ s->numvunits, s->firstEUN, s->lastEUN, s->numfreeEUNs,
-+ s->LastFreeEUN, s->nb_blocks, s->nb_boot_blocks);
-+
-+ printk("\n-------------------------------------------"
-+ "----------------------------------\n");
-+}
-+
-+void INFTL_dumpVUchains(struct INFTLrecord *s)
-+{
-+ int logical, block, i;
-+
-+ printk("-------------------------------------------"
-+ "----------------------------------\n");
-+
-+ printk("INFTL Virtual Unit Chains:\n");
-+ for (logical = 0; logical < s->nb_blocks; logical++) {
-+ block = s->VUtable[logical];
-+ if (block > s->nb_blocks)
-+ continue;
-+ printk(" LOGICAL %d --> %d ", logical, block);
-+ for (i = 0; i < s->nb_blocks; i++) {
-+ if (s->PUtable[block] == BLOCK_NIL)
-+ break;
-+ block = s->PUtable[block];
-+ printk("%d ", block);
-+ }
-+ printk("\n");
-+ }
-+
-+ printk("-------------------------------------------"
-+ "----------------------------------\n");
-+}
-+
-+int INFTL_mount(struct INFTLrecord *s)
-+{
-+ unsigned int block, first_block, prev_block, last_block;
-+ unsigned int first_logical_block, logical_block, erase_mark;
-+ int chain_length, do_format_chain;
-+ struct inftl_unithead1 h0;
-+ struct inftl_unittail h1;
-+ int i, retlen;
-+ u8 *ANACtable, ANAC;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: INFTL_mount(inftl=0x%x)\n", (int)s);
-+
-+ /* Search for INFTL MediaHeader and Spare INFTL Media Header */
-+ if (find_boot_record(s) < 0) {
-+ printk(KERN_WARNING "INFTL: could not find valid boot record?\n");
-+ return -1;
-+ }
-+
-+ /* Init the logical to physical table */
-+ for (i = 0; i < s->nb_blocks; i++)
-+ s->VUtable[i] = BLOCK_NIL;
-+
-+ logical_block = block = BLOCK_NIL;
-+
-+ /* Temporary buffer to store ANAC numbers. */
-+ ANACtable = kmalloc(s->nb_blocks * sizeof(u8), GFP_KERNEL);
-+ memset(ANACtable, 0, s->nb_blocks);
-+
-+ /*
-+ * First pass is to explore each physical unit, and construct the
-+ * virtual chains that exist (newest physical unit goes into VUtable).
-+ * Any block that is in any way invalid will be left in the
-+ * NOTEXPLORED state. Then at the end we will try to format it and
-+ * mark it as free.
-+ */
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 1, explore each unit\n");
-+ for (first_block = s->firstEUN; first_block <= s->lastEUN; first_block++) {
-+ if (s->PUtable[first_block] != BLOCK_NOTEXPLORED)
-+ continue;
-+
-+ do_format_chain = 0;
-+ first_logical_block = BLOCK_NIL;
-+ last_block = BLOCK_NIL;
-+ block = first_block;
-+
-+ for (chain_length = 0; ; chain_length++) {
-+
-+ if ((chain_length == 0) &&
-+ (s->PUtable[block] != BLOCK_NOTEXPLORED)) {
-+ /* Nothing to do here, onto next block */
-+ break;
-+ }
-+
-+ if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8,
-+ 8, &retlen, (char *)&h0) < 0 ||
-+ MTD_READOOB(s->mbd.mtd, block * s->EraseSize +
-+ 2 * SECTORSIZE + 8, 8, &retlen, (char *)&h1) < 0) {
-+ /* Should never happen? */
-+ do_format_chain++;
-+ break;
-+ }
-+
-+ logical_block = le16_to_cpu(h0.virtualUnitNo);
-+ prev_block = le16_to_cpu(h0.prevUnitNo);
-+ erase_mark = le16_to_cpu((h1.EraseMark | h1.EraseMark1));
-+ ANACtable[block] = h0.ANAC;
-+
-+ /* Previous block is relative to start of Partition */
-+ if (prev_block < s->nb_blocks)
-+ prev_block += s->firstEUN;
-+
-+ /* Already explored partial chain? */
-+ if (s->PUtable[block] != BLOCK_NOTEXPLORED) {
-+ /* Check if chain for this logical */
-+ if (logical_block == first_logical_block) {
-+ if (last_block != BLOCK_NIL)
-+ s->PUtable[last_block] = block;
-+ }
-+ break;
-+ }
-+
-+ /* Check for invalid block */
-+ if (erase_mark != ERASE_MARK) {
-+ printk(KERN_WARNING "INFTL: corrupt block %d "
-+ "in chain %d, chain length %d, erase "
-+ "mark 0x%x?\n", block, first_block,
-+ chain_length, erase_mark);
-+ /*
-+ * Assume end of chain, probably incomplete
-+ * fold/erase...
-+ */
-+ if (chain_length == 0)
-+ do_format_chain++;
-+ break;
-+ }
-+
-+ /* Check for it being free already then... */
-+ if ((logical_block == BLOCK_FREE) ||
-+ (logical_block == BLOCK_NIL)) {
-+ s->PUtable[block] = BLOCK_FREE;
-+ break;
-+ }
-+
-+ /* Sanity checks on block numbers */
-+ if ((logical_block >= s->nb_blocks) ||
-+ ((prev_block >= s->nb_blocks) &&
-+ (prev_block != BLOCK_NIL))) {
-+ if (chain_length > 0) {
-+ printk(KERN_WARNING "INFTL: corrupt "
-+ "block %d in chain %d?\n",
-+ block, first_block);
-+ do_format_chain++;
-+ }
-+ break;
-+ }
-+
-+ if (first_logical_block == BLOCK_NIL) {
-+ first_logical_block = logical_block;
-+ } else {
-+ if (first_logical_block != logical_block) {
-+ /* Normal for folded chain... */
-+ break;
-+ }
-+ }
-+
-+ /*
-+ * Current block is valid, so if we followed a virtual
-+ * chain to get here then we can set the previous
-+ * block pointer in our PUtable now. Then move onto
-+ * the previous block in the chain.
-+ */
-+ s->PUtable[block] = BLOCK_NIL;
-+ if (last_block != BLOCK_NIL)
-+ s->PUtable[last_block] = block;
-+ last_block = block;
-+ block = prev_block;
-+
-+ /* Check for end of chain */
-+ if (block == BLOCK_NIL)
-+ break;
-+
-+ /* Validate next block before following it... */
-+ if (block > s->lastEUN) {
-+ printk(KERN_WARNING "INFTL: invalid previous "
-+ "block %d in chain %d?\n", block,
-+ first_block);
-+ do_format_chain++;
-+ break;
-+ }
-+ }
-+
-+ if (do_format_chain) {
-+ format_chain(s, first_block);
-+ continue;
-+ }
-+
-+ /*
-+ * Looks like a valid chain then. It may not really be the
-+ * newest block in the chain, but it is the newest we have
-+ * found so far. We might update it in later iterations of
-+ * this loop if we find something newer.
-+ */
-+ s->VUtable[first_logical_block] = first_block;
-+ logical_block = BLOCK_NIL;
-+ }
-+
-+#ifdef CONFIG_MTD_DEBUG_VERBOSE
-+ if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
-+ INFTL_dumptables(s);
-+#endif
-+
-+ /*
-+ * Second pass, check for infinite loops in chains. These are
-+ * possible because we don't update the previous pointers when
-+ * we fold chains. No big deal, just fix them up in PUtable.
-+ */
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 2, validate virtual chains\n");
-+ for (logical_block = 0; logical_block < s->numvunits; logical_block++) {
-+ block = s->VUtable[logical_block];
-+ last_block = BLOCK_NIL;
-+
-+ /* Check for free/reserved/nil */
-+ if (block >= BLOCK_RESERVED)
-+ continue;
-+
-+ ANAC = ANACtable[block];
-+ for (i = 0; i < s->numvunits; i++) {
-+ if (s->PUtable[block] == BLOCK_NIL)
-+ break;
-+ if (s->PUtable[block] > s->lastEUN) {
-+ printk(KERN_WARNING "INFTL: invalid prev %d, "
-+ "in virtual chain %d\n",
-+ s->PUtable[block], logical_block);
-+ s->PUtable[block] = BLOCK_NIL;
-+
-+ }
-+ if (ANACtable[block] != ANAC) {
-+ /*
-+ * Chain must point back to itself. This is ok,
-+ * but we will need adjust the tables with this
-+ * newest block and oldest block.
-+ */
-+ s->VUtable[logical_block] = block;
-+ s->PUtable[last_block] = BLOCK_NIL;
-+ break;
-+ }
-+
-+ ANAC--;
-+ last_block = block;
-+ block = s->PUtable[block];
-+ }
-+
-+ if (i >= s->nb_blocks) {
-+ /*
-+ * Uhoo, infinite chain with valid ANACS!
-+ * Format whole chain...
-+ */
-+ format_chain(s, first_block);
-+ }
-+ }
-+
-+#ifdef CONFIG_MTD_DEBUG_VERBOSE
-+ if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
-+ INFTL_dumptables(s);
-+ if (CONFIG_MTD_DEBUG_VERBOSE >= 2)
-+ INFTL_dumpVUchains(s);
-+#endif
-+
-+ /*
-+ * Third pass, format unreferenced blocks and init free block count.
-+ */
-+ s->numfreeEUNs = 0;
-+ s->LastFreeEUN = BLOCK_NIL;
-+
-+ DEBUG(MTD_DEBUG_LEVEL3, "INFTL: pass 3, format unused blocks\n");
-+ for (block = s->firstEUN; block <= s->lastEUN; block++) {
-+ if (s->PUtable[block] == BLOCK_NOTEXPLORED) {
-+ printk("INFTL: unreferenced block %d, formatting it\n",
-+ block);
-+ if (INFTL_formatblock(s, block) < 0)
-+ s->PUtable[block] = BLOCK_RESERVED;
-+ else
-+ s->PUtable[block] = BLOCK_FREE;
-+ }
-+ if (s->PUtable[block] == BLOCK_FREE) {
-+ s->numfreeEUNs++;
-+ if (s->LastFreeEUN == BLOCK_NIL)
-+ s->LastFreeEUN = block;
-+ }
-+ }
-+
-+ kfree(ANACtable);
-+ return 0;
-+}
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/Config.in linux/drivers/mtd/maps/Config.in
---- linux-mips-2.4.27/drivers/mtd/maps/Config.in 2004-02-26 01:46:35.000000000 +0100
-+++ linux/drivers/mtd/maps/Config.in 2004-11-19 10:25:11.888201464 +0100
-@@ -1,17 +1,14 @@
- # drivers/mtd/maps/Config.in
-
--# $Id$
-+# $Id$
-
- mainmenu_option next_comment
-
- comment 'Mapping drivers for chip access'
-
--dep_tristate ' CFI Flash device in physical memory map' CONFIG_MTD_PHYSMAP $CONFIG_MTD_GEN_PROBE
--if [ "$CONFIG_MTD_PHYSMAP" = "y" -o "$CONFIG_MTD_PHYSMAP" = "m" ]; then
-- hex ' Physical start address of flash mapping' CONFIG_MTD_PHYSMAP_START 0x8000000
-- hex ' Physical length of flash mapping' CONFIG_MTD_PHYSMAP_LEN 0x4000000
-- int ' Bus width in octets' CONFIG_MTD_PHYSMAP_BUSWIDTH 2
--fi
-+bool ' Support for non-linear mappings of flash chips' CONFIG_MTD_COMPLEX_MAPPINGS
-+
-+bool ' CFI Flash device in physical memory map' CONFIG_MTD_PHYSMAP $CONFIG_MTD_GEN_PROBE
-
- if [ "$CONFIG_SPARC" = "y" -o "$CONFIG_SPARC64" = "y" ]; then
- dep_tristate ' Sun Microsystems userflash support' CONFIG_MTD_SUN_UFLASH $CONFIG_MTD_CFI
-@@ -21,56 +18,68 @@
- dep_tristate ' CFI Flash device mapped on Photron PNC-2000' CONFIG_MTD_PNC2000 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS
- dep_tristate ' CFI Flash device mapped on AMD SC520 CDP' CONFIG_MTD_SC520CDP $CONFIG_MTD_CFI
- dep_tristate ' CFI Flash device mapped on AMD NetSc520' CONFIG_MTD_NETSC520 $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS
-- dep_tristate ' CFI Flash device mapped on Arcom SBC-GXx boards' CONFIG_MTD_SBC_GXX $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS
-- dep_tristate ' CFI Flash device mapped on Arcom ELAN-104NC' CONFIG_MTD_ELAN_104NC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS
-+ dep_tristate ' CFI Flash device mapped on Arcom SBC-GXx boards' CONFIG_MTD_SBC_GXX $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS $CONFIG_MTD_COMPLEX_MAPPINGS
-+ dep_tristate ' CFI Flash device mapped on Arcom ELAN-104NC' CONFIG_MTD_ELAN_104NC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS $CONFIG_MTD_COMPLEX_MAPPINGS
- dep_tristate ' CFI Flash device mapped on DIL/Net PC' CONFIG_MTD_DILNETPC $CONFIG_MTD_CFI_INTELEXT $CONFIG_MTD_PARTITIONS $CONFIG_MTD_CONCAT
- if [ "$CONFIG_MTD_DILNETPC" = "y" -o "$CONFIG_MTD_DILNETPC" = "m" ]; then
- hex ' Size of boot partition' CONFIG_MTD_DILNETPC_BOOTSIZE 0x80000
- fi
-- dep_tristate ' JEDEC Flash device mapped on Mixcom piggyback card' CONFIG_MTD_MIXMEM $CONFIG_MTD_JEDEC
-- dep_tristate ' JEDEC Flash device mapped on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC
-- dep_tristate ' JEDEC Flash device mapped on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC
-+ dep_tristate ' JEDEC Flash device mapped on Octagon 5066 SBC' CONFIG_MTD_OCTAGON $CONFIG_MTD_JEDEC $CONFIG_MTD_COMPLEX_MAPPINGS
-+ dep_tristate ' JEDEC Flash device mapped on Tempustech VMAX SBC301' CONFIG_MTD_VMAX $CONFIG_MTD_JEDEC $CONFIG_MTD_COMPLEX_MAPPINGS
- dep_tristate ' Flash device mapped with DOCCS on NatSemi SCx200' CONFIG_MTD_SCx200_DOCFLASH $CONFIG_MTD_CFI
- dep_tristate ' BIOS flash chip on Intel L440GX boards' CONFIG_MTD_L440GX $CONFIG_MTD_JEDECPROBE
- dep_tristate ' ROM connected to AMD76X southbridge' CONFIG_MTD_AMD76XROM $CONFIG_MTD_GEN_PROBE
-- dep_tristate ' ROM connected to Intel Hub Controller 2' CONFIG_MTD_ICH2ROM $CONFIG_MTD_JEDECPROBE
-+ dep_tristate ' ROM connected to Intel Hub Controller 2/3/4/5' CONFIG_MTD_ICHXROM $CONFIG_MTD_JEDECPROBE $CONFIG_MTD_COMPLEX_MAPPINGS
- dep_tristate ' CFI Flash device mapped on SnapGear/SecureEdge' CONFIG_MTD_NETtel $CONFIG_MTD_PARTITIONS
- dep_tristate ' BIOS flash chip on Intel SCB2 boards' CONFIG_MTD_SCB2_FLASH $CONFIG_MTD_GEN_PROBE
- fi
-
--if [ "$CONFIG_PPC" = "y" ]; then
-- dep_tristate ' CFI Flash device mapped on TQM8XXL' CONFIG_MTD_TQM8XXL $CONFIG_MTD_CFI $CONFIG_TQM8xxL
-+if [ "$CONFIG_PPC32" = "y" ]; then
-+ if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "y" ]; then
-+ dep_tristate ' Flash device on SBC8240' CONFIG_MTD_SBC8240 $CONFIG_MTD_JEDECPROBE
-+ fi
-+ if [ "$CONFIG_8xx" = "y" ]; then
-+ if [ "$CONFIG_TQM8xxL" = "y" ]; then
-+ dep_tristate ' CFI Flash device mapped on TQM8XXL' CONFIG_MTD_TQM8XXL $CONFIG_MTD_CFI
-+ fi
-+ if [ "$CONFIG_RPXLITE" = "y" -o "$CONFIG_RPXCLASSIC" = "y" ]; then
- dep_tristate ' CFI Flash device mapped on RPX Lite or CLLF' CONFIG_MTD_RPXLITE $CONFIG_MTD_CFI
-+ fi
-+ if [ "$CONFIG_MBX" = "y" ]; then
- dep_tristate ' System flash on MBX860 board' CONFIG_MTD_MBX860 $CONFIG_MTD_CFI
-+ fi
-+ if [ "$CONFIG_DBOX2" = "y" ]; then
- dep_tristate ' CFI Flash device mapped on D-Box2' CONFIG_MTD_DBOX2 $CONFIG_MTD_CFI
-+ fi
- dep_tristate ' CFI Flash device mapping on FlagaDM' CONFIG_MTD_CFI_FLAGADM $CONFIG_MTD_CFI
-- dep_tristate ' CFI Flash device mapped on IBM Redwood-4/5' CONFIG_MTD_REDWOOD $CONFIG_MTD_CFI
-+ fi
-+ if [ "$CONFIG_4xx" = "y" ]; then
-+ if [ "$CONFIG_40x" = "y" ]; then
-+ if [ "$CONFIG_REDWOOD_4" = "y" -o "$CONFIG_REDWOOD_5" = "y" -o "$CONFIG_REDWOOD_6" = "y" ]; then
-+ dep_tristate ' CFI Flash device mapped on IBM Redwood' CONFIG_MTD_REDWOOD $CONFIG_MTD_CFI
-+ fi
-+ dep_tristate ' CFI Flash device mapped on IBM Beech' CONFIG_MTD_BEECH $CONFIG_MTD_CFI $CONFIG_BEECH
-+ dep_tristate ' CFI Flash device mapped on IBM Arctic' CONFIG_MTD_ARCTIC $CONFIG_MTD_CFI $CONFIG_ARCTIC2
-+ fi
-+ if [ "$CONFIG_440" = "y" ]; then
-+ dep_tristate ' Flash devices mapped on IBM Ebony' CONFIG_MTD_EBONY $CONFIG_MTD_CFI $CONFIG_EBONY
-+ fi
-+ fi
- fi
-
--if [ "$CONFIG_MIPS" = "y" ]; then
-- dep_tristate ' Pb1000 MTD support' CONFIG_MTD_PB1000 $CONFIG_MIPS_PB1000
-- dep_tristate ' Pb1500 MTD support' CONFIG_MTD_PB1500 $CONFIG_MIPS_PB1500
-- dep_tristate ' Pb1100 MTD support' CONFIG_MTD_PB1100 $CONFIG_MIPS_PB1100
-- dep_tristate ' Bosporus MTD support' CONFIG_MTD_BOSPORUS $CONFIG_MIPS_BOSPORUS
-- dep_tristate ' XXS1500 boot flash device' CONFIG_MTD_XXS1500 $CONFIG_MIPS_XXS1500
-- dep_tristate ' MTX-1 flash device' CONFIG_MTD_MTX1 $CONFIG_MIPS_MTX1
-- if [ "$CONFIG_MTD_PB1500" = "y" -o "$CONFIG_MTD_PB1500" = "m" \
-- -o "$CONFIG_MTD_PB1100" = "y" -o "$CONFIG_MTD_PB1100" = "m" ]; then
-- bool ' Pb[15]00 boot flash device' CONFIG_MTD_PB1500_BOOT
-- bool ' Pb[15]00 user flash device (2nd 32MiB bank)' CONFIG_MTD_PB1500_USER
-+if [ "$CONFIG_MIPS" = "y" -o "$CONFIG_MIPS64" = "y" ]; then
-+ if [ "$CONFIG_MIPS_PB1000" = "y" -o "$CONFIG_MIPS_PB1100" = "y" -o "$CONFIG_MIPS_PB1500" = "y" ]; then
-+ tristate ' Pb1x00 MTD support' CONFIG_MTD_PB1XXX
-+ if [ "$CONFIG_MIPS_PB1500" = "y" -o "$CONFIG_MIPS_PB1100" = "m" ]; then
-+ bool ' Pb1x00 boot flash device' CONFIG_MTD_PB1500_BOOT
-+ bool ' Pb1x00 user flash device (2nd 32MiB bank)' CONFIG_MTD_PB1500_USER
-+ fi
- fi
- tristate ' Db1x00 MTD support' CONFIG_MTD_DB1X00
- if [ "$CONFIG_MTD_DB1X00" = "y" -o "$CONFIG_MTD_DB1X00" = "m" ]; then
- bool ' Db1x00 boot flash device' CONFIG_MTD_DB1X00_BOOT
- bool ' Db1x00 user flash device (2nd bank)' CONFIG_MTD_DB1X00_USER
- fi
-- tristate ' Pb1550 MTD support' CONFIG_MTD_PB1550
-- if [ "$CONFIG_MTD_PB1550" = "y" -o "$CONFIG_MTD_PB1550" = "m" ]; then
-- bool ' Pb1550 Boot Flash' CONFIG_MTD_PB1550_BOOT
-- bool ' Pb1550 User Parameter Flash' CONFIG_MTD_PB1550_USER
-- fi
-- dep_tristate ' Hydrogen 3 MTD support' CONFIG_MTD_HYDROGEN3 $CONFIG_MIPS_HYDROGEN3
-- dep_tristate ' Mirage MTD support' CONFIG_MTD_MIRAGE $CONFIG_MIPS_MIRAGE
- dep_tristate ' Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board' CONFIG_MTD_CSTM_MIPS_IXX $CONFIG_MTD_CFI $CONFIG_MTD_JEDEC $CONFIG_MTD_PARTITIONS
- if [ "$CONFIG_MTD_CSTM_MIPS_IXX" = "y" -o "$CONFIG_MTD_CSTM_MIPS_IXX" = "m" ]; then
- hex ' Physical start address of flash mapping' CONFIG_MTD_CSTM_MIPS_IXX_START 0x8000000
-@@ -78,7 +87,7 @@
- int ' Bus width in octets' CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH 2
- fi
- dep_tristate ' Momenco Ocelot boot flash device' CONFIG_MTD_OCELOT $CONFIG_MOMENCO_OCELOT
-- dep_tristate ' LASAT flash device' CONFIG_MTD_LASAT $CONFIG_MTD_CFI $CONFIG_LASAT
-+ dep_tristate ' LASAT flash device' CONFIG_MTD_LASAT $CONFIG_LASAT
- fi
-
- if [ "$CONFIG_SUPERH" = "y" ]; then
-@@ -90,21 +99,24 @@
- fi
-
- if [ "$CONFIG_ARM" = "y" ]; then
-- dep_tristate ' CFI Flash device mapped on Nora' CONFIG_MTD_NORA $CONFIG_MTD_CFI
- dep_tristate ' CFI Flash device mapped on ARM Integrator/P720T' CONFIG_MTD_ARM_INTEGRATOR $CONFIG_MTD_CFI
- dep_tristate ' Cirrus CDB89712 evaluation board mappings' CONFIG_MTD_CDB89712 $CONFIG_MTD_CFI $CONFIG_ARCH_CDB89712
- dep_tristate ' CFI Flash device mapped on StrongARM SA11x0' CONFIG_MTD_SA1100 $CONFIG_MTD_CFI $CONFIG_ARCH_SA1100 $CONFIG_MTD_PARTITIONS
-- dep_tristate ' CFI Flash device mapped on DC21285 Footbridge' CONFIG_MTD_DC21285 $CONFIG_MTD_CFI $CONFIG_ARCH_FOOTBRIDGE
-+ dep_tristate ' CFI Flash device mapped on DC21285 Footbridge' CONFIG_MTD_DC21285 $CONFIG_MTD_CFI $CONFIG_ARCH_FOOTBRIDGE $CONFIG_MTD_COMPLEX_MAPPINGS
- dep_tristate ' CFI Flash device mapped on the XScale IQ80310 board' CONFIG_MTD_IQ80310 $CONFIG_MTD_CFI $CONFIG_ARCH_IQ80310
-+ dep_tristate ' CFI Flash device mapped on the XScale Lubbock board' CONFIG_MTD_LUBBOCK $CONFIG_MTD_CFI $CONFIG_ARCH_LUBBOCK
-+ dep_tristate ' CFI Flash device mapped on XScale IXP425 systems' CONFIG_MTD_IXP425 $CONFIG_MTD_CFI $CONFIG_MTD_COMPLEX_MAPPINGS
- dep_tristate ' CFI Flash device mapped on Epxa10db' CONFIG_MTD_EPXA10DB $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS $CONFIG_ARCH_CAMELOT
- dep_tristate ' CFI Flash device mapped on the FortuNet board' CONFIG_MTD_FORTUNET $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS $CONFIG_SA1100_FORTUNET
- dep_tristate ' NV-RAM mapping AUTCPU12 board' CONFIG_MTD_AUTCPU12 $CONFIG_ARCH_AUTCPU12
- dep_tristate ' CFI Flash device mapped on EDB7312' CONFIG_MTD_EDB7312 $CONFIG_MTD_CFI
-+ dep_tristate ' CFI Flash device mapped on Hynix evaluation boards' CONFIG_MTD_H720X $CONFIG_MTD_CFI
- dep_tristate ' JEDEC Flash device mapped on impA7' CONFIG_MTD_IMPA7 $CONFIG_MTD_JEDECPROBE
- dep_tristate ' JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame' CONFIG_MTD_CEIVA $CONFIG_MTD_JEDECPROBE $CONFIG_ARCH_CEIVA
-+ dep_tristate ' NOR Flash device on TOTO board' CONFIG_MTD_NOR_TOTO $CONFIG_MTD $CONFIG_OMAP_TOTO
- fi
- if [ "$CONFIG_ALPHA" = "y" ]; then
-- dep_tristate ' Flash chip mapping on TSUNAMI' CONFIG_MTD_TSUNAMI $CONFIG_MTD_GENPROBE
-+ dep_tristate ' Flash chip mapping on TSUNAMI' CONFIG_MTD_TSUNAMI $CONFIG_MTD_GENPROBE $CONFIG_MTD_COMPLEX_MAPPINGS
- fi
-
- if [ "$CONFIG_UCLINUX" = "y" ]; then
-@@ -112,7 +124,7 @@
- fi
-
- # This needs CFI or JEDEC, depending on the cards found.
--dep_tristate ' PCI MTD driver' CONFIG_MTD_PCI $CONFIG_MTD $CONFIG_PCI
--dep_tristate ' PCMCIA MTD driver' CONFIG_MTD_PCMCIA $CONFIG_MTD $CONFIG_PCMCIA
-+dep_tristate ' PCI MTD driver' CONFIG_MTD_PCI $CONFIG_MTD $CONFIG_PCI $CONFIG_MTD_COMPLEX_MAPPINGS
-+dep_tristate ' PCMCIA MTD driver' CONFIG_MTD_PCMCIA $CONFIG_MTD $CONFIG_PCMCIA $CONFIG_MTD_COMPLEX_MAPPINGS
-
- endmenu
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/Makefile linux/drivers/mtd/maps/Makefile
---- linux-mips-2.4.27/drivers/mtd/maps/Makefile 2004-02-26 01:46:35.000000000 +0100
-+++ linux/drivers/mtd/maps/Makefile 2004-11-19 10:25:11.890201160 +0100
-@@ -1,12 +1,16 @@
- #
- # linux/drivers/maps/Makefile
- #
--# $Id$
-+# $Id$
-
--BELOW25 := $(shell echo $(PATCHLEVEL) | sed s/[1234]/y/)
--
--ifeq ($(BELOW25),y)
-+ifeq ($(PATCHLEVEL),4)
- O_TARGET := mapslink.o
-+export-objs := map_funcs.o
-+endif
-+
-+
-+ifeq ($(CONFIG_MTD_COMPLEX_MAPPINGS),y)
-+obj-$(CONFIG_MTD) += map_funcs.o
- endif
-
- # Chip mappings
-@@ -21,19 +25,13 @@
- obj-$(CONFIG_MTD_IQ80310) += iq80310.o
- obj-$(CONFIG_MTD_L440GX) += l440gx.o
- obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o
--obj-$(CONFIG_MTD_ICH2ROM) += ich2rom.o
-+obj-$(CONFIG_MTD_ICHXROM) += ichxrom.o
- obj-$(CONFIG_MTD_TSUNAMI) += tsunami_flash.o
-+obj-$(CONFIG_MTD_LUBBOCK) += lubbock-flash.o
- obj-$(CONFIG_MTD_MBX860) += mbx860.o
--obj-$(CONFIG_MTD_NORA) += nora.o
- obj-$(CONFIG_MTD_CEIVA) += ceiva.o
- obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o
--ifneq ($(CONFIG_MTD_PHYSMAP),n)
-- ifeq ($(CONFIG_MTD_PHYSMAP_BUSWIDTH),8)
-- obj-$(CONFIG_MTD_PHYSMAP) += physmap64.o
-- else
-- obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
-- endif
--endif
-+obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
- obj-$(CONFIG_MTD_PNC2000) += pnc2000.o
- obj-$(CONFIG_MTD_PCMCIA) += pcmciamtd.o
- obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o
-@@ -49,16 +47,9 @@
- obj-$(CONFIG_MTD_OCELOT) += ocelot.o
- obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o
- obj-$(CONFIG_MTD_PCI) += pci.o
--obj-$(CONFIG_MTD_PB1000) += pb1xxx-flash.o
--obj-$(CONFIG_MTD_PB1100) += pb1xxx-flash.o
--obj-$(CONFIG_MTD_PB1500) += pb1xxx-flash.o
--obj-$(CONFIG_MTD_XXS1500) += xxs1500.o
--obj-$(CONFIG_MTD_MTX1) += mtx-1.o
--obj-$(CONFIG_MTD_LASAT) += lasat.o
-+obj-$(CONFIG_MTD_PB1XXX) += pb1xxx-flash.o
- obj-$(CONFIG_MTD_DB1X00) += db1x00-flash.o
--obj-$(CONFIG_MTD_PB1550) += pb1550-flash.o
--obj-$(CONFIG_MTD_HYDROGEN3) += hydrogen3-flash.o
--obj-$(CONFIG_MTD_BOSPORUS) += pb1xxx-flash.o
-+obj-$(CONFIG_MTD_LASAT) += lasat.o
- obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o
- obj-$(CONFIG_MTD_EDB7312) += edb7312.o
- obj-$(CONFIG_MTD_IMPA7) += impa7.o
-@@ -67,6 +58,13 @@
- obj-$(CONFIG_MTD_UCLINUX) += uclinux.o
- obj-$(CONFIG_MTD_NETtel) += nettel.o
- obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o
--obj-$(CONFIG_MTD_MIRAGE) += mirage-flash.o
-+obj-$(CONFIG_MTD_EBONY) += ebony.o
-+obj-$(CONFIG_MTD_BEECH) += beech-mtd.o
-+obj-$(CONFIG_MTD_ARCTIC) += arctic-mtd.o
-+obj-$(CONFIG_MTD_H720X) += h720x-flash.o
-+obj-$(CONFIG_MTD_SBC8240) += sbc8240.o
-+obj-$(CONFIG_MTD_NOR_TOTO) += omap-toto-flash.o
-+obj-$(CONFIG_MTD_MPC1211) += mpc1211.o
-+obj-$(CONFIG_MTD_IXP425) += ixp425.o
-
--include $(TOPDIR)/Rules.make
-+-include $(TOPDIR)/Rules.make
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/amd76xrom.c linux/drivers/mtd/maps/amd76xrom.c
---- linux-mips-2.4.27/drivers/mtd/maps/amd76xrom.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/maps/amd76xrom.c 2004-11-19 10:25:11.891201008 +0100
-@@ -2,12 +2,13 @@
- * amd76xrom.c
- *
- * Normal mappings of chips in physical memory
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -16,77 +17,59 @@
- #include <linux/pci_ids.h>
-
-
-+#define xstr(s) str(s)
-+#define str(s) #s
-+#define MOD_NAME xstr(KBUILD_BASENAME)
-+
-+#define MTD_DEV_NAME_LENGTH 16
-+
- struct amd76xrom_map_info {
- struct map_info map;
- struct mtd_info *mtd;
- unsigned long window_addr;
- u32 window_start, window_size;
- struct pci_dev *pdev;
-+ struct resource window_rsrc;
-+ struct resource rom_rsrc;
-+ char mtd_name[MTD_DEV_NAME_LENGTH];
- };
-
--static __u8 amd76xrom_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--static __u16 amd76xrom_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
-
--static __u32 amd76xrom_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
-+static struct amd76xrom_map_info amd76xrom_map = {
-+ .map = {
-+ .name = MOD_NAME,
-+ .size = 0,
-+ .buswidth = 1,
-+ }
-+ /* remaining fields of structure are initialized to 0 */
-+};
-
--static void amd76xrom_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
-
--static void amd76xrom_write8(struct map_info *map, __u8 d, unsigned long adr)
-+static void amd76xrom_cleanup(struct amd76xrom_map_info *info)
- {
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
-+ u8 byte;
-
--static void amd76xrom_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
-+ /* Disable writes through the rom window */
-+ pci_read_config_byte(info->pdev, 0x40, &byte);
-+ pci_write_config_byte(info->pdev, 0x40, byte & ~1);
-
--static void amd76xrom_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
-+ if (info->mtd) {
-+ del_mtd_device(info->mtd);
-+ map_destroy(info->mtd);
-+ info->mtd = NULL;
-+ info->map.virt = 0;
-+ }
-+ if (info->rom_rsrc.parent)
-+ release_resource(&info->rom_rsrc);
-+ if (info->window_rsrc.parent)
-+ release_resource(&info->window_rsrc);
-
--static void amd76xrom_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
-+ if (info->window_addr) {
-+ iounmap((void *)(info->window_addr));
-+ info->window_addr = 0;
-+ }
- }
-
--static struct amd76xrom_map_info amd76xrom_map = {
-- map: {
-- name: "AMD76X rom",
-- size: 0,
-- buswidth: 1,
-- read8: amd76xrom_read8,
-- read16: amd76xrom_read16,
-- read32: amd76xrom_read32,
-- copy_from: amd76xrom_copy_from,
-- write8: amd76xrom_write8,
-- write16: amd76xrom_write16,
-- write32: amd76xrom_write32,
-- copy_to: amd76xrom_copy_to,
-- /* The standard rom socket is for single power supply chips
-- * that don't have an extra vpp.
-- */
-- },
-- mtd: 0,
-- window_addr: 0,
--};
-
- static int __devinit amd76xrom_init_one (struct pci_dev *pdev,
- const struct pci_device_id *ent)
-@@ -97,6 +80,10 @@
- u8 segen_bits;
- };
- static struct rom_window rom_window[] = {
-+ /*
-+ * Need the 5MiB window for chips that have block lock/unlock
-+ * registers located below 4MiB window.
-+ */
- { 0xffb00000, 5*1024*1024, (1<<7) | (1<<6), },
- { 0xffc00000, 4*1024*1024, (1<<7), },
- { 0xffff0000, 64*1024, 0 },
-@@ -112,19 +99,29 @@
- int i;
- u32 rom_size;
-
-+ info->pdev = pdev;
- window = &rom_window[0];
--#if 0
-- while(window->size) {
-- if (request_mem_region(window->start, window->size, "amd76xrom")) {
-- break;
-- }
-- window++;
-- }
-- if (!window->size) {
-- printk(KERN_ERR "amd76xrom: cannot reserve rom window\n");
-- goto err_out_none;
-+
-+ while (window->size) {
-+ /*
-+ * Try to reserve the window mem region. If this fails then
-+ * it is likely due to a fragment of the window being
-+ * "reseved" by the BIOS. In the case that the
-+ * request_mem_region() fails then once the rom size is
-+ * discovered we will try to reserve the unreserved fragment.
-+ */
-+ info->window_rsrc.name = MOD_NAME;
-+ info->window_rsrc.start = window->start;
-+ info->window_rsrc.end = window->start + window->size - 1;
-+ info->window_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-+ if (request_resource(&iomem_resource, &info->window_rsrc)) {
-+ info->window_rsrc.parent = NULL;
-+ printk(KERN_ERR MOD_NAME
-+ " %s(): Unable to register resource"
-+ " 0x%.08lx-0x%.08lx - kernel bug?\n",
-+ __func__,
-+ info->window_rsrc.start, info->window_rsrc.end);
- }
--#endif
-
- /* Enable the selected rom window */
- pci_read_config_byte(pdev, 0x43, &byte);
-@@ -136,49 +133,94 @@
-
- /* FIXME handle registers 0x80 - 0x8C the bios region locks */
-
-- printk(KERN_NOTICE "amd76xrom window : %x at %x\n",
-+ printk(KERN_NOTICE MOD_NAME " window : %x at %x\n",
- window->size, window->start);
- /* For write accesses caches are useless */
-- info->window_addr = (unsigned long)ioremap_nocache(window->start, window->size);
-+ info->window_addr =
-+ (unsigned long)ioremap_nocache(window->start,
-+ window->size);
-
- if (!info->window_addr) {
- printk(KERN_ERR "Failed to ioremap\n");
-- goto err_out_free_mmio_region;
-+ continue;
- }
-- info->mtd = 0;
-+
-+ info->mtd = NULL;
-+
- for(i = 0; (rom_size = rom_probe_sizes[i]); i++) {
- char **chip_type;
- if (rom_size > window->size) {
- continue;
- }
-- info->map.map_priv_1 =
-+ info->map.phys = window->start + window->size - rom_size;
-+ info->map.virt =
- info->window_addr + window->size - rom_size;
- info->map.size = rom_size;
-+ simple_map_init(&info->map);
- chip_type = rom_probe_types;
- for(; !info->mtd && *chip_type; chip_type++) {
- info->mtd = do_map_probe(*chip_type, &amd76xrom_map.map);
- }
-- if (info->mtd) {
-- break;
-- }
-+ if (info->mtd) goto found_mtd;
- }
-- if (!info->mtd) {
-- goto err_out_iounmap;
-+ iounmap((void *)(info->window_addr));
-+ info->window_addr = 0;
-+
-+ /* Disable writes through the rom window */
-+ pci_read_config_byte(pdev, 0x40, &byte);
-+ pci_write_config_byte(pdev, 0x40, byte & ~1);
-+
-+ window++;
- }
-- printk(KERN_NOTICE "amd76xrom chip at offset: %x\n",
-+ goto failed;
-+
-+ found_mtd:
-+ printk(KERN_NOTICE MOD_NAME " chip at offset: 0x%x\n",
- window->size - rom_size);
-
-- info->mtd->module = THIS_MODULE;
-+ info->mtd->owner = THIS_MODULE;
-+
-+ if (!info->window_rsrc.parent) {
-+ /* failed to reserve entire window - try fragments */
-+ info->window_rsrc.name = MOD_NAME;
-+ info->window_rsrc.start = window->start;
-+ info->window_rsrc.end = window->start + window->size - rom_size - 1;
-+ info->window_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-+ if (request_resource(&iomem_resource, &info->window_rsrc)) {
-+ printk(KERN_ERR MOD_NAME
-+ ": cannot reserve window resource fragment\n");
-+ goto failed;
-+ }
-+ }
-+
- add_mtd_device(info->mtd);
- info->window_start = window->start;
- info->window_size = window->size;
-+
-+ if (info->window_rsrc.parent) {
-+ /*
-+ * Registering the MTD device in iomem may not be possible
-+ * if there is a BIOS "reserved" and BUSY range. If this
-+ * fails then continue anyway.
-+ */
-+ snprintf(info->mtd_name, MTD_DEV_NAME_LENGTH,
-+ "mtd%d", info->mtd->index);
-+
-+ info->rom_rsrc.name = info->mtd_name;
-+ info->rom_rsrc.start = window->start + window->size - rom_size;
-+ info->rom_rsrc.end = window->start + window->size - 1;
-+ info->rom_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-+ if (request_resource(&info->window_rsrc, &info->rom_rsrc)) {
-+ printk(KERN_ERR MOD_NAME
-+ ": cannot reserve MTD resource\n");
-+ info->rom_rsrc.parent = NULL;
-+ }
-+ }
-+
- return 0;
-
--err_out_iounmap:
-- iounmap((void *)(info->window_addr));
--err_out_free_mmio_region:
-- release_mem_region(window->start, window->size);
--err_out_none:
-+ failed:
-+ amd76xrom_cleanup(info);
- return -ENODEV;
- }
-
-@@ -186,21 +228,8 @@
- static void __devexit amd76xrom_remove_one (struct pci_dev *pdev)
- {
- struct amd76xrom_map_info *info = &amd76xrom_map;
-- u8 byte;
--
-- del_mtd_device(info->mtd);
-- map_destroy(info->mtd);
-- info->mtd = 0;
-- info->map.map_priv_1 = 0;
--
-- iounmap((void *)(info->window_addr));
-- info->window_addr = 0;
--
-- /* Disable writes through the rom window */
-- pci_read_config_byte(pdev, 0x40, &byte);
-- pci_write_config_byte(pdev, 0x40, byte & ~1);
-
-- release_mem_region(info->window_start, info->window_size);
-+ amd76xrom_cleanup(info);
- }
-
- static struct pci_device_id amd76xrom_pci_tbl[] __devinitdata = {
-@@ -208,6 +237,7 @@
- PCI_ANY_ID, PCI_ANY_ID, },
- { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7440,
- PCI_ANY_ID, PCI_ANY_ID, },
-+ { PCI_VENDOR_ID_AMD, 0x7468 }, /* amd8111 support */
- { 0, }
- };
-
-@@ -215,10 +245,10 @@
-
- #if 0
- static struct pci_driver amd76xrom_driver = {
-- name: "amd76xrom",
-- id_table: amd76xrom_pci_tbl,
-- probe: amd76xrom_init_one,
-- remove: amd76xrom_remove_one,
-+ .name = MOD_NAME,
-+ .id_table = amd76xrom_pci_tbl,
-+ .probe = amd76xrom_init_one,
-+ .remove = amd76xrom_remove_one,
- };
- #endif
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/arctic-mtd.c linux/drivers/mtd/maps/arctic-mtd.c
---- linux-mips-2.4.27/drivers/mtd/maps/arctic-mtd.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/arctic-mtd.c 2004-11-19 10:25:11.893200704 +0100
-@@ -0,0 +1,135 @@
-+/*
-+ * $Id$
-+ *
-+ * drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for
-+ * IBM 405LP Arctic boards.
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Copyright (C) 2002, International Business Machines Corporation
-+ * All Rights Reserved.
-+ *
-+ * Bishop Brock
-+ * IBM Research, Austin Center for Low-Power Computing
-+ * bcbrock@us.ibm.com
-+ * March 2002
-+ *
-+ * modified for Arctic by,
-+ * David Gibson
-+ * IBM OzLabs, Canberra, Australia
-+ * <arctic@gibson.dropbear.id.au>
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/init.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+
-+#include <asm/io.h>
-+#include <asm/ibm4xx.h>
-+
-+/*
-+ * 0 : 0xFE00 0000 - 0xFEFF FFFF : Filesystem 1 (16MiB)
-+ * 1 : 0xFF00 0000 - 0xFF4F FFFF : kernel (5.12MiB)
-+ * 2 : 0xFF50 0000 - 0xFFF5 FFFF : Filesystem 2 (10.624MiB) (if non-XIP)
-+ * 3 : 0xFFF6 0000 - 0xFFFF FFFF : PIBS Firmware (640KiB)
-+ */
-+
-+#define FFS1_SIZE 0x01000000 /* 16MiB */
-+#define KERNEL_SIZE 0x00500000 /* 5.12MiB */
-+#define FFS2_SIZE 0x00a60000 /* 10.624MiB */
-+#define FIRMWARE_SIZE 0x000a0000 /* 640KiB */
-+
-+
-+#define NAME "Arctic Linux Flash"
-+#define PADDR SUBZERO_BOOTFLASH_PADDR
-+#define BUSWIDTH 2
-+#define SIZE SUBZERO_BOOTFLASH_SIZE
-+#define PARTITIONS 4
-+
-+/* Flash memories on these boards are memory resources, accessed big-endian. */
-+
-+{
-+ /* do nothing for now */
-+}
-+
-+static struct map_info arctic_mtd_map = {
-+ .name = NAME,
-+ .size = SIZE,
-+ .buswidth = BUSWIDTH,
-+ .phys = PADDR,
-+};
-+
-+static struct mtd_info *arctic_mtd;
-+
-+static struct mtd_partition arctic_partitions[PARTITIONS] = {
-+ { .name = "Filesystem",
-+ .size = FFS1_SIZE,
-+ .offset = 0,},
-+ { .name = "Kernel",
-+ .size = KERNEL_SIZE,
-+ .offset = FFS1_SIZE,},
-+ { .name = "Filesystem",
-+ .size = FFS2_SIZE,
-+ .offset = FFS1_SIZE + KERNEL_SIZE,},
-+ { .name = "Firmware",
-+ .size = FIRMWARE_SIZE,
-+ .offset = SUBZERO_BOOTFLASH_SIZE - FIRMWARE_SIZE,},
-+};
-+
-+static int __init
-+init_arctic_mtd(void)
-+{
-+ printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
-+
-+ arctic_mtd_map.virt = (unsigned long) ioremap(PADDR, SIZE);
-+
-+ if (!arctic_mtd_map.virt) {
-+ printk("%s: failed to ioremap 0x%x\n", NAME, PADDR);
-+ return -EIO;
-+ }
-+ simple_map_init(&arctic_mtd_map);
-+
-+ printk("%s: probing %d-bit flash bus\n", NAME, BUSWIDTH * 8);
-+ arctic_mtd = do_map_probe("cfi_probe", &arctic_mtd_map);
-+
-+ if (!arctic_mtd)
-+ return -ENXIO;
-+
-+ arctic_mtd->owner = THIS_MODULE;
-+
-+ return add_mtd_partitions(arctic_mtd, arctic_partitions, PARTITIONS);
-+}
-+
-+static void __exit
-+cleanup_arctic_mtd(void)
-+{
-+ if (arctic_mtd) {
-+ del_mtd_partitions(arctic_mtd);
-+ map_destroy(arctic_mtd);
-+ iounmap((void *) arctic_mtd_map.virt);
-+ }
-+}
-+
-+module_init(init_arctic_mtd);
-+module_exit(cleanup_arctic_mtd);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("David Gibson <arctic@gibson.dropbear.id.au>");
-+MODULE_DESCRIPTION("MTD map and partitions for IBM 405LP Arctic boards");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/autcpu12-nvram.c linux/drivers/mtd/maps/autcpu12-nvram.c
---- linux-mips-2.4.27/drivers/mtd/maps/autcpu12-nvram.c 2002-06-27 00:35:50.000000000 +0200
-+++ linux/drivers/mtd/maps/autcpu12-nvram.c 2004-11-19 10:25:11.894200552 +0100
-@@ -2,7 +2,7 @@
- * NV-RAM memory access on autcpu12
- * (C) 2002 Thomas Gleixner (gleixner@autronix.de)
- *
-- * $Id$
-+ * $Id$
- *
- * 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
-@@ -24,6 +24,7 @@
- #include <linux/types.h>
- #include <linux/kernel.h>
- #include <linux/ioport.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <asm/sizes.h>
- #include <asm/hardware.h>
-@@ -32,80 +33,27 @@
- #include <linux/mtd/map.h>
- #include <linux/mtd/partitions.h>
-
--__u8 autcpu12_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 autcpu12_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 autcpu12_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void autcpu12_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void autcpu12_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void autcpu12_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void autcpu12_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void autcpu12_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- while(len) {
-- __raw_writeb(*(unsigned char *) from, map->map_priv_1 + to);
-- from++;
-- to++;
-- len--;
-- }
--}
-
- static struct mtd_info *sram_mtd;
-
- struct map_info autcpu12_sram_map = {
-- name: "SRAM",
-- size: 32768,
-- buswidth: 8,
-- read8: autcpu12_read8,
-- read16: autcpu12_read16,
-- read32: autcpu12_read32,
-- copy_from: autcpu12_copy_from,
-- write8: autcpu12_write8,
-- write16: autcpu12_write16,
-- write32: autcpu12_write32,
-- copy_to: autcpu12_copy_to
-+ .name = "SRAM",
-+ .size = 32768,
-+ .buswidth = 4,
-+ .phys = 0x12000000,
- };
-
- static int __init init_autcpu12_sram (void)
- {
- int err, save0, save1;
-
-- autcpu12_sram_map.map_priv_1 = (unsigned long)ioremap(0x12000000, SZ_128K);
-- if (!autcpu12_sram_map.map_priv_1) {
-+ autcpu12_sram_map.virt = (unsigned long)ioremap(0x12000000, SZ_128K);
-+ if (!autcpu12_sram_map.virt) {
- printk("Failed to ioremap autcpu12 NV-RAM space\n");
- err = -EIO;
- goto out;
- }
-+ simple_map_init(&autcpu_sram_map);
-
- /*
- * Check for 32K/128K
-@@ -115,20 +63,20 @@
- * Read and check result on ofs 0x0
- * Restore contents
- */
-- save0 = autcpu12_read32(&autcpu12_sram_map,0);
-- save1 = autcpu12_read32(&autcpu12_sram_map,0x10000);
-- autcpu12_write32(&autcpu12_sram_map,~save0,0x10000);
-+ save0 = map_read32(&autcpu12_sram_map,0);
-+ save1 = map_read32(&autcpu12_sram_map,0x10000);
-+ map_write32(&autcpu12_sram_map,~save0,0x10000);
- /* if we find this pattern on 0x0, we have 32K size
- * restore contents and exit
- */
-- if ( autcpu12_read32(&autcpu12_sram_map,0) != save0) {
-- autcpu12_write32(&autcpu12_sram_map,save0,0x0);
-+ if ( map_read32(&autcpu12_sram_map,0) != save0) {
-+ map_write32(&autcpu12_sram_map,save0,0x0);
- goto map;
- }
- /* We have a 128K found, restore 0x10000 and set size
- * to 128K
- */
-- autcpu12_write32(&autcpu12_sram_map,save1,0x10000);
-+ ma[_write32(&autcpu12_sram_map,save1,0x10000);
- autcpu12_sram_map.size = SZ_128K;
-
- map:
-@@ -139,7 +87,7 @@
- goto out_ioremap;
- }
-
-- sram_mtd->module = THIS_MODULE;
-+ sram_mtd->owner = THIS_MODULE;
- sram_mtd->erasesize = 16;
-
- if (add_mtd_device(sram_mtd)) {
-@@ -148,7 +96,7 @@
- goto out_probe;
- }
-
-- printk("NV-RAM device size %ldK registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K);
-+ printk("NV-RAM device size %ldKiB registered on AUTCPU12\n",autcpu12_sram_map.size/SZ_1K);
-
- return 0;
-
-@@ -157,7 +105,7 @@
- sram_mtd = 0;
-
- out_ioremap:
-- iounmap((void *)autcpu12_sram_map.map_priv_1);
-+ iounmap((void *)autcpu12_sram_map.virt);
- out:
- return err;
- }
-@@ -167,7 +115,7 @@
- if (sram_mtd) {
- del_mtd_device(sram_mtd);
- map_destroy(sram_mtd);
-- iounmap((void *)autcpu12_sram_map.map_priv_1);
-+ iounmap((void *)autcpu12_sram_map.virt);
- }
- }
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/beech-mtd.c linux/drivers/mtd/maps/beech-mtd.c
---- linux-mips-2.4.27/drivers/mtd/maps/beech-mtd.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/beech-mtd.c 2004-11-19 10:25:11.895200400 +0100
-@@ -0,0 +1,112 @@
-+/*
-+ * $Id$
-+ *
-+ * drivers/mtd/maps/beech-mtd.c MTD mappings and partition tables for
-+ * IBM 405LP Beech boards.
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Copyright (C) 2002, International Business Machines Corporation
-+ * All Rights Reserved.
-+ *
-+ * Bishop Brock
-+ * IBM Research, Austin Center for Low-Power Computing
-+ * bcbrock@us.ibm.com
-+ * March 2002
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/init.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+
-+#include <asm/io.h>
-+#include <asm/ibm4xx.h>
-+
-+#define NAME "Beech Linux Flash"
-+#define PADDR BEECH_BIGFLASH_PADDR
-+#define SIZE BEECH_BIGFLASH_SIZE
-+#define BUSWIDTH 1
-+
-+/* Flash memories on these boards are memory resources, accessed big-endian. */
-+
-+
-+static struct map_info beech_mtd_map = {
-+ .name = NAME,
-+ .size = SIZE,
-+ .buswidth = BUSWIDTH,
-+ .phys = PADDR
-+};
-+
-+static struct mtd_info *beech_mtd;
-+
-+static struct mtd_partition beech_partitions[2] = {
-+ {
-+ .name = "Linux Kernel",
-+ .size = BEECH_KERNEL_SIZE,
-+ .offset = BEECH_KERNEL_OFFSET
-+ }, {
-+ .name = "Free Area",
-+ .size = BEECH_FREE_AREA_SIZE,
-+ .offset = BEECH_FREE_AREA_OFFSET
-+ }
-+};
-+
-+static int __init
-+init_beech_mtd(void)
-+{
-+ printk("%s: 0x%08x at 0x%08x\n", NAME, SIZE, PADDR);
-+
-+ beech_mtd_map.virt = (unsigned long) ioremap(PADDR, SIZE);
-+
-+ if (!beech_mtd_map.virt) {
-+ printk("%s: failed to ioremap 0x%x\n", NAME, PADDR);
-+ return -EIO;
-+ }
-+
-+ simple_map_init(&beech_mtd_map);
-+
-+ printk("%s: probing %d-bit flash bus\n", NAME, BUSWIDTH * 8);
-+ beech_mtd = do_map_probe("cfi_probe", &beech_mtd_map);
-+
-+ if (!beech_mtd)
-+ return -ENXIO;
-+
-+ beech_mtd->owner = THIS_MODULE;
-+
-+ return add_mtd_partitions(beech_mtd, beech_partitions, 2);
-+}
-+
-+static void __exit
-+cleanup_beech_mtd(void)
-+{
-+ if (beech_mtd) {
-+ del_mtd_partitions(beech_mtd);
-+ map_destroy(beech_mtd);
-+ iounmap((void *) beech_mtd_map.virt);
-+ }
-+}
-+
-+module_init(init_beech_mtd);
-+module_exit(cleanup_beech_mtd);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Bishop Brock <bcbrock@us.ibm.com>");
-+MODULE_DESCRIPTION("MTD map and partitions for IBM 405LP Beech boards");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/cdb89712.c linux/drivers/mtd/maps/cdb89712.c
---- linux-mips-2.4.27/drivers/mtd/maps/cdb89712.c 2001-11-05 21:15:52.000000000 +0100
-+++ linux/drivers/mtd/maps/cdb89712.c 2004-11-19 10:25:11.897200096 +0100
-@@ -1,13 +1,14 @@
- /*
- * Flash on Cirrus CDB89712
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
- #include <linux/ioport.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <asm/arch/hardware.h>
- #include <linux/mtd/mtd.h>
-@@ -16,77 +17,21 @@
-
-
-
--__u8 cdb89712_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 cdb89712_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 cdb89712_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void cdb89712_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void cdb89712_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void cdb89712_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void cdb89712_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- // printk ("cdb89712_copy_from: 0x%x@0x%x -> 0x%x\n", len, from, to);
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void cdb89712_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- while(len) {
-- __raw_writeb(*(unsigned char *) from, map->map_priv_1 + to);
-- from++;
-- to++;
-- len--;
-- }
--}
--
-
- static struct mtd_info *flash_mtd;
-
- struct map_info cdb89712_flash_map = {
-- name: "flash",
-- size: FLASH_SIZE,
-- buswidth: FLASH_WIDTH,
-- read8: cdb89712_read8,
-- read16: cdb89712_read16,
-- read32: cdb89712_read32,
-- copy_from: cdb89712_copy_from,
-- write8: cdb89712_write8,
-- write16: cdb89712_write16,
-- write32: cdb89712_write32,
-- copy_to: cdb89712_copy_to
-+ .name = "flash",
-+ .size = FLASH_SIZE,
-+ .buswidth = FLASH_WIDTH,
-+ .phys = FLASH_START,
- };
-
- struct resource cdb89712_flash_resource = {
-- name: "Flash",
-- start: FLASH_START,
-- end: FLASH_START + FLASH_SIZE - 1,
-- flags: IORESOURCE_IO | IORESOURCE_BUSY,
-+ .name = "Flash",
-+ .start = FLASH_START,
-+ .end = FLASH_START + FLASH_SIZE - 1,
-+ .flags = IORESOURCE_IO | IORESOURCE_BUSY,
- };
-
- static int __init init_cdb89712_flash (void)
-@@ -99,13 +44,13 @@
- goto out;
- }
-
-- cdb89712_flash_map.map_priv_1 = (unsigned long)ioremap(FLASH_START, FLASH_SIZE);
-- if (!cdb89712_flash_map.map_priv_1) {
-+ cdb89712_flash_map.virt = (unsigned long)ioremap(FLASH_START, FLASH_SIZE);
-+ if (!cdb89712_flash_map.virt) {
- printk(KERN_NOTICE "Failed to ioremap Cdb89712 FLASH space\n");
- err = -EIO;
- goto out_resource;
- }
--
-+ simple_map_init(&cdb89712_flash_map);
- flash_mtd = do_map_probe("cfi_probe", &cdb89712_flash_map);
- if (!flash_mtd) {
- flash_mtd = do_map_probe("map_rom", &cdb89712_flash_map);
-@@ -118,7 +63,7 @@
- goto out_ioremap;
- }
-
-- flash_mtd->module = THIS_MODULE;
-+ flash_mtd->owner = THIS_MODULE;
-
- if (add_mtd_device(flash_mtd)) {
- printk("FLASH device addition failed\n");
-@@ -132,7 +77,7 @@
- map_destroy(flash_mtd);
- flash_mtd = 0;
- out_ioremap:
-- iounmap((void *)cdb89712_flash_map.map_priv_1);
-+ iounmap((void *)cdb89712_flash_map.virt);
- out_resource:
- release_resource (&cdb89712_flash_resource);
- out:
-@@ -146,24 +91,17 @@
- static struct mtd_info *sram_mtd;
-
- struct map_info cdb89712_sram_map = {
-- name: "SRAM",
-- size: SRAM_SIZE,
-- buswidth: SRAM_WIDTH,
-- read8: cdb89712_read8,
-- read16: cdb89712_read16,
-- read32: cdb89712_read32,
-- copy_from: cdb89712_copy_from,
-- write8: cdb89712_write8,
-- write16: cdb89712_write16,
-- write32: cdb89712_write32,
-- copy_to: cdb89712_copy_to
-+ .name = "SRAM",
-+ .size = SRAM_SIZE,
-+ .buswidth = SRAM_WIDTH,
-+ .phys = SRAM_START,
- };
-
- struct resource cdb89712_sram_resource = {
-- name: "SRAM",
-- start: SRAM_START,
-- end: SRAM_START + SRAM_SIZE - 1,
-- flags: IORESOURCE_IO | IORESOURCE_BUSY,
-+ .name = "SRAM",
-+ .start = SRAM_START,
-+ .end = SRAM_START + SRAM_SIZE - 1,
-+ .flags = IORESOURCE_IO | IORESOURCE_BUSY,
- };
-
- static int __init init_cdb89712_sram (void)
-@@ -176,13 +114,13 @@
- goto out;
- }
-
-- cdb89712_sram_map.map_priv_1 = (unsigned long)ioremap(SRAM_START, SRAM_SIZE);
-- if (!cdb89712_sram_map.map_priv_1) {
-+ cdb89712_sram_map.virt = (unsigned long)ioremap(SRAM_START, SRAM_SIZE);
-+ if (!cdb89712_sram_map.virt) {
- printk(KERN_NOTICE "Failed to ioremap Cdb89712 SRAM space\n");
- err = -EIO;
- goto out_resource;
- }
--
-+ simple_map_init(&cdb89712_sram_map);
- sram_mtd = do_map_probe("map_ram", &cdb89712_sram_map);
- if (!sram_mtd) {
- printk("SRAM probe failed\n");
-@@ -190,7 +128,7 @@
- goto out_ioremap;
- }
-
-- sram_mtd->module = THIS_MODULE;
-+ sram_mtd->owner = THIS_MODULE;
- sram_mtd->erasesize = 16;
-
- if (add_mtd_device(sram_mtd)) {
-@@ -205,7 +143,7 @@
- map_destroy(sram_mtd);
- sram_mtd = 0;
- out_ioremap:
-- iounmap((void *)cdb89712_sram_map.map_priv_1);
-+ iounmap((void *)cdb89712_sram_map.virt);
- out_resource:
- release_resource (&cdb89712_sram_resource);
- out:
-@@ -221,20 +159,17 @@
- static struct mtd_info *bootrom_mtd;
-
- struct map_info cdb89712_bootrom_map = {
-- name: "BootROM",
-- size: BOOTROM_SIZE,
-- buswidth: BOOTROM_WIDTH,
-- read8: cdb89712_read8,
-- read16: cdb89712_read16,
-- read32: cdb89712_read32,
-- copy_from: cdb89712_copy_from,
-+ .name = "BootROM",
-+ .size = BOOTROM_SIZE,
-+ .buswidth = BOOTROM_WIDTH,
-+ .phys = BOOTROM_START,
- };
-
- struct resource cdb89712_bootrom_resource = {
-- name: "BootROM",
-- start: BOOTROM_START,
-- end: BOOTROM_START + BOOTROM_SIZE - 1,
-- flags: IORESOURCE_IO | IORESOURCE_BUSY,
-+ .name = "BootROM",
-+ .start = BOOTROM_START,
-+ .end = BOOTROM_START + BOOTROM_SIZE - 1,
-+ .flags = IORESOURCE_IO | IORESOURCE_BUSY,
- };
-
- static int __init init_cdb89712_bootrom (void)
-@@ -247,13 +182,13 @@
- goto out;
- }
-
-- cdb89712_bootrom_map.map_priv_1 = (unsigned long)ioremap(BOOTROM_START, BOOTROM_SIZE);
-- if (!cdb89712_bootrom_map.map_priv_1) {
-+ cdb89712_bootrom_map.virt = (unsigned long)ioremap(BOOTROM_START, BOOTROM_SIZE);
-+ if (!cdb89712_bootrom_map.virt) {
- printk(KERN_NOTICE "Failed to ioremap Cdb89712 BootROM space\n");
- err = -EIO;
- goto out_resource;
- }
--
-+ simple_map_init(&cdb89712_bootrom_map);
- bootrom_mtd = do_map_probe("map_rom", &cdb89712_bootrom_map);
- if (!bootrom_mtd) {
- printk("BootROM probe failed\n");
-@@ -261,7 +196,7 @@
- goto out_ioremap;
- }
-
-- bootrom_mtd->module = THIS_MODULE;
-+ bootrom_mtd->owner = THIS_MODULE;
- bootrom_mtd->erasesize = 0x10000;
-
- if (add_mtd_device(bootrom_mtd)) {
-@@ -276,7 +211,7 @@
- map_destroy(bootrom_mtd);
- bootrom_mtd = 0;
- out_ioremap:
-- iounmap((void *)cdb89712_bootrom_map.map_priv_1);
-+ iounmap((void *)cdb89712_bootrom_map.virt);
- out_resource:
- release_resource (&cdb89712_bootrom_resource);
- out:
-@@ -306,21 +241,21 @@
- if (sram_mtd) {
- del_mtd_device(sram_mtd);
- map_destroy(sram_mtd);
-- iounmap((void *)cdb89712_sram_map.map_priv_1);
-+ iounmap((void *)cdb89712_sram_map.virt);
- release_resource (&cdb89712_sram_resource);
- }
-
- if (flash_mtd) {
- del_mtd_device(flash_mtd);
- map_destroy(flash_mtd);
-- iounmap((void *)cdb89712_flash_map.map_priv_1);
-+ iounmap((void *)cdb89712_flash_map.virt);
- release_resource (&cdb89712_flash_resource);
- }
-
- if (bootrom_mtd) {
- del_mtd_device(bootrom_mtd);
- map_destroy(bootrom_mtd);
-- iounmap((void *)cdb89712_bootrom_map.map_priv_1);
-+ iounmap((void *)cdb89712_bootrom_map.virt);
- release_resource (&cdb89712_bootrom_resource);
- }
- }
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/ceiva.c linux/drivers/mtd/maps/ceiva.c
---- linux-mips-2.4.27/drivers/mtd/maps/ceiva.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/maps/ceiva.c 2004-11-19 10:25:11.898199944 +0100
-@@ -11,7 +11,7 @@
- *
- * (C) 2000 Nicolas Pitre <nico@cam.org>
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
-@@ -19,6 +19,7 @@
- #include <linux/types.h>
- #include <linux/ioport.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -31,62 +32,10 @@
- #include <asm/sizes.h>
-
- /*
-- * This isnt complete yet, so...
-+ * This isn't complete yet, so...
- */
- #define CONFIG_MTD_CEIVA_STATICMAP
-
--static __u8 clps_read8(struct map_info *map, unsigned long ofs)
--{
-- return readb(map->map_priv_1 + ofs);
--}
--
--static __u16 clps_read16(struct map_info *map, unsigned long ofs)
--{
-- return readw(map->map_priv_1 + ofs);
--}
--
--static __u32 clps_read32(struct map_info *map, unsigned long ofs)
--{
-- return readl(map->map_priv_1 + ofs);
--}
--
--static void clps_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy(to, (void *)(map->map_priv_1 + from), len);
--}
--
--static void clps_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- writeb(d, map->map_priv_1 + adr);
--}
--
--static void clps_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- writew(d, map->map_priv_1 + adr);
--}
--
--static void clps_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- writel(d, map->map_priv_1 + adr);
--}
--
--static void clps_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy((void *)(map->map_priv_1 + to), from, len);
--}
--
--static struct map_info clps_map __initdata = {
-- name: "clps flash",
-- read8: clps_read8,
-- read16: clps_read16,
-- read32: clps_read32,
-- copy_from: clps_copy_from,
-- write8: clps_write8,
-- write16: clps_write16,
-- write32: clps_write32,
-- copy_to: clps_copy_to,
--};
--
- #ifdef CONFIG_MTD_CEIVA_STATICMAP
- /*
- * See include/linux/mtd/partitions.h for definition of the mtd_partition
-@@ -176,7 +125,7 @@
- maps = kmalloc(sizeof(struct map_info) * nr, GFP_KERNEL);
- if (!maps)
- return -ENOMEM;
--
-+ memset(maps, 0, sizeof(struct map_info) * nr);
- /*
- * Claim and then map the memory regions.
- */
-@@ -191,7 +140,9 @@
- }
-
- clps[i].map = maps + i;
-- memcpy(clps[i].map, &clps_map, sizeof(struct map_info));
-+
-+ clps[i].map->name = "clps flash";
-+ clps[i].map->phys = clps[i].base;
-
- clps[i].vbase = ioremap(clps[i].base, clps[i].size);
- if (!clps[i].vbase) {
-@@ -199,16 +150,18 @@
- break;
- }
-
-- clps[i].map->map_priv_1 = (unsigned long)clps[i].vbase;
-+ clps[i].map->virt = (unsigned long)clps[i].vbase;
- clps[i].map->buswidth = clps[i].width;
- clps[i].map->size = clps[i].size;
-
-+ simple_map_init(&clps[i].map);
-+
- clps[i].mtd = do_map_probe("jedec_probe", clps[i].map);
- if (clps[i].mtd == NULL) {
- ret = -ENXIO;
- break;
- }
-- clps[i].mtd->module = THIS_MODULE;
-+ clps[i].mtd->owner = THIS_MODULE;
- subdev[i] = clps[i].mtd;
-
- printk(KERN_INFO "clps flash: JEDEC device at 0x%08lx, %dMiB, "
-@@ -318,10 +271,8 @@
- return nr;
- }
-
--extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
--extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, char *);
--
- static struct mtd_partition *parsed_parts;
-+static const char *probes[] = { "cmdlinepart", "RedBoot", NULL };
-
- static void __init clps_locate_partitions(struct mtd_info *mtd)
- {
-@@ -331,20 +282,11 @@
- /*
- * Partition selection stuff.
- */
--#ifdef CONFIG_MTD_CMDLINE_PARTS
-- nr_parts = parse_cmdline_partitions(mtd, &parsed_parts, "clps");
-+ nr_parts = parse_mtd_partitions(mtd, probes, &parsed_parts, 0);
- if (nr_parts > 0) {
- part_type = "command line";
- break;
- }
--#endif
--#ifdef CONFIG_MTD_REDBOOT_PARTS
-- nr_parts = parse_redboot_partitions(mtd, &parsed_parts);
-- if (nr_parts > 0) {
-- part_type = "RedBoot";
-- break;
-- }
--#endif
- #ifdef CONFIG_MTD_CEIVA_STATICMAP
- nr_parts = clps_static_partitions(&parsed_parts);
- if (nr_parts > 0) {
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/cfi_flagadm.c linux/drivers/mtd/maps/cfi_flagadm.c
---- linux-mips-2.4.27/drivers/mtd/maps/cfi_flagadm.c 2001-11-05 21:15:52.000000000 +0100
-+++ linux/drivers/mtd/maps/cfi_flagadm.c 2004-11-19 10:25:11.900199640 +0100
-@@ -1,7 +1,7 @@
- /*
- * Copyright © 2001 Flaga hf. Medical Devices, Kári Davíðsson <kd@flaga.is>
- *
-- * $Id$
-+ * $Id$
- *
- * 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
-@@ -27,6 +27,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -55,83 +56,33 @@
- #define FLASH_PARTITION3_ADDR 0x00240000
- #define FLASH_PARTITION3_SIZE 0x001C0000
-
--__u8 flagadm_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 flagadm_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 flagadm_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void flagadm_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void flagadm_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void flagadm_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void flagadm_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void flagadm_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
-
- struct map_info flagadm_map = {
-- name: "FlagaDM flash device",
-- size: FLASH_SIZE,
-- buswidth: 2,
-- read8: flagadm_read8,
-- read16: flagadm_read16,
-- read32: flagadm_read32,
-- copy_from: flagadm_copy_from,
-- write8: flagadm_write8,
-- write16: flagadm_write16,
-- write32: flagadm_write32,
-- copy_to: flagadm_copy_to
-+ .name = "FlagaDM flash device",
-+ .size = FLASH_SIZE,
-+ .buswidth = 2,
- };
-
- struct mtd_partition flagadm_parts[] = {
- {
-- name : "Bootloader",
-- offset : FLASH_PARTITION0_ADDR,
-- size : FLASH_PARTITION0_SIZE
-+ .name = "Bootloader",
-+ .offset = FLASH_PARTITION0_ADDR,
-+ .size = FLASH_PARTITION0_SIZE
- },
- {
-- name : "Kernel image",
-- offset : FLASH_PARTITION1_ADDR,
-- size : FLASH_PARTITION1_SIZE
-+ .name = "Kernel image",
-+ .offset = FLASH_PARTITION1_ADDR,
-+ .size = FLASH_PARTITION1_SIZE
- },
- {
-- name : "Initial ramdisk image",
-- offset : FLASH_PARTITION2_ADDR,
-- size : FLASH_PARTITION2_SIZE
-+ .name = "Initial ramdisk image",
-+ .offset = FLASH_PARTITION2_ADDR,
-+ .size = FLASH_PARTITION2_SIZE
- },
- {
-- name : "Persistant storage",
-- offset : FLASH_PARTITION3_ADDR,
-- size : FLASH_PARTITION3_SIZE
-+ .name = "Persistant storage",
-+ .offset = FLASH_PARTITION3_ADDR,
-+ .size = FLASH_PARTITION3_SIZE
- }
- };
-
-@@ -144,22 +95,26 @@
- printk(KERN_NOTICE "FlagaDM flash device: %x at %x\n",
- FLASH_SIZE, FLASH_PHYS_ADDR);
-
-- flagadm_map.map_priv_1 = (unsigned long)ioremap(FLASH_PHYS_ADDR,
-+ flagadm_map.phys = FLASH_PHYS_ADDR;
-+ flagadm_map.virt = (unsigned long)ioremap(FLASH_PHYS_ADDR,
- FLASH_SIZE);
-
-- if (!flagadm_map.map_priv_1) {
-+ if (!flagadm_map.virt) {
- printk("Failed to ioremap\n");
- return -EIO;
- }
-+
-+ simple_map_init(&flagadm_map);
-+
- mymtd = do_map_probe("cfi_probe", &flagadm_map);
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
- add_mtd_partitions(mymtd, flagadm_parts, PARTITION_COUNT);
- printk(KERN_NOTICE "FlagaDM flash device initialized\n");
- return 0;
- }
-
-- iounmap((void *)flagadm_map.map_priv_1);
-+ iounmap((void *)flagadm_map.virt);
- return -ENXIO;
- }
-
-@@ -169,9 +124,9 @@
- del_mtd_partitions(mymtd);
- map_destroy(mymtd);
- }
-- if (flagadm_map.map_priv_1) {
-- iounmap((void *)flagadm_map.map_priv_1);
-- flagadm_map.map_priv_1 = 0;
-+ if (flagadm_map.virt) {
-+ iounmap((void *)flagadm_map.virt);
-+ flagadm_map.virt = 0;
- }
- }
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/cstm_mips_ixx.c linux/drivers/mtd/maps/cstm_mips_ixx.c
---- linux-mips-2.4.27/drivers/mtd/maps/cstm_mips_ixx.c 2001-11-05 21:15:52.000000000 +0100
-+++ linux/drivers/mtd/maps/cstm_mips_ixx.c 2004-11-19 10:25:11.901199488 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Mapping of a custom board with both AMD CFI and JEDEC flash in partitions.
- * Config with both CFI and JEDEC device support.
-@@ -33,55 +33,13 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/partitions.h>
- #include <linux/config.h>
--
--#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
- #include <linux/delay.h>
--#endif
--
--__u8 cstm_mips_ixx_read8(struct map_info *map, unsigned long ofs)
--{
-- return *(__u8 *)(map->map_priv_1 + ofs);
--}
--
--__u16 cstm_mips_ixx_read16(struct map_info *map, unsigned long ofs)
--{
-- return *(__u16 *)(map->map_priv_1 + ofs);
--}
--
--__u32 cstm_mips_ixx_read32(struct map_info *map, unsigned long ofs)
--{
-- return *(__u32 *)(map->map_priv_1 + ofs);
--}
--
--void cstm_mips_ixx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void cstm_mips_ixx_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- *(__u8 *)(map->map_priv_1 + adr) = d;
--}
--
--void cstm_mips_ixx_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- *(__u16 *)(map->map_priv_1 + adr) = d;
--}
--
--void cstm_mips_ixx_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- *(__u32 *)(map->map_priv_1 + adr) = d;
--}
--
--void cstm_mips_ixx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
-
- #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
- #define CC_GCR 0xB4013818
-@@ -97,10 +55,17 @@
- #define CC_GPAICR 0xB4013804
- #endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */
-
-+#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
- void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp)
- {
-+ static spinlock_t vpp_lock = SPIN_LOCK_UNLOCKED;
-+ static int vpp_count = 0;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&vpp_lock, flags);
-+
- if (vpp) {
--#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
-+ if (!vpp_count++) {
- __u16 data;
- __u8 data1;
- static u8 first = 1;
-@@ -116,10 +81,9 @@
- enabling vpp after powerup */
- udelay(40);
- }
--#endif /* CONFIG_MIPS_ITE8172 */
- }
-- else {
--#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
-+ } else {
-+ if (!--vpp_count) {
- __u16 data;
-
- // Set GPIO port B pin3 to high
-@@ -127,26 +91,11 @@
- data = (data & 0xff3f) | 0x0040;
- *(__u16 *)CC_GPBCR = data;
- *(__u8 *)CC_GPBDR = (*(__u8*)CC_GPBDR) & 0xf7;
--#endif /* CONFIG_MIPS_ITE8172 */
- }
-+ }
-+ spin_unlock_irqrestore(&vpp_lock, flags);
- }
--
--const struct map_info basic_cstm_mips_ixx_map = {
-- NULL,
-- 0,
-- 0,
-- cstm_mips_ixx_read8,
-- cstm_mips_ixx_read16,
-- cstm_mips_ixx_read32,
-- cstm_mips_ixx_copy_from,
-- cstm_mips_ixx_write8,
-- cstm_mips_ixx_write16,
-- cstm_mips_ixx_write32,
-- cstm_mips_ixx_copy_to,
-- cstm_mips_ixx_set_vpp,
-- 0,
-- 0
--};
-+#endif
-
- /* board and partition description */
-
-@@ -175,9 +124,9 @@
- static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {
- { // 28F128J3A in 2x16 configuration
- {
-- name: "main partition ",
-- size: 0x02000000, // 128 x 2 x 128k byte sectors
-- offset: 0,
-+ .name = "main partition ",
-+ .size = 0x02000000, // 128 x 2 x 128k byte sectors
-+ .offset = 0,
- },
- },
- };
-@@ -197,9 +146,9 @@
- static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {
- {
- {
-- name: "main partition",
-- size: CONFIG_MTD_CSTM_MIPS_IXX_LEN,
-- offset: 0,
-+ .name = "main partition",
-+ .size = CONFIG_MTD_CSTM_MIPS_IXX_LEN,
-+ .offset = 0,
- },
- },
- };
-@@ -216,17 +165,24 @@
-
- /* Initialize mapping */
- for (i=0;i<PHYSMAP_NUMBER;i++) {
-- printk(KERN_NOTICE "cstm_mips_ixx flash device: %lx at %lx\n", cstm_mips_ixx_board_desc[i].window_size, cstm_mips_ixx_board_desc[i].window_addr);
-- memcpy((char *)&cstm_mips_ixx_map[i],(char *)&basic_cstm_mips_ixx_map,sizeof(struct map_info));
-- cstm_mips_ixx_map[i].map_priv_1 = (unsigned long)ioremap(cstm_mips_ixx_board_desc[i].window_addr, cstm_mips_ixx_board_desc[i].window_size);
-- if (!cstm_mips_ixx_map[i].map_priv_1) {
-+ printk(KERN_NOTICE "cstm_mips_ixx flash device: 0x%lx at 0x%lx\n",
-+ cstm_mips_ixx_board_desc[i].window_size, cstm_mips_ixx_board_desc[i].window_addr);
-+
-+
-+ cstm_mips_ixx_map[i].phys = cstm_mips_ixx_board_desc[i].window_addr;
-+ cstm_mips_ixx_map[i].virt = (unsigned long)ioremap(cstm_mips_ixx_board_desc[i].window_addr, cstm_mips_ixx_board_desc[i].window_size);
-+ if (!cstm_mips_ixx_map[i].virt) {
- printk(KERN_WARNING "Failed to ioremap\n");
- return -EIO;
- }
- cstm_mips_ixx_map[i].name = cstm_mips_ixx_board_desc[i].name;
- cstm_mips_ixx_map[i].size = cstm_mips_ixx_board_desc[i].window_size;
- cstm_mips_ixx_map[i].buswidth = cstm_mips_ixx_board_desc[i].buswidth;
-- //printk(KERN_NOTICE "cstm_mips_ixx: ioremap is %x\n",(unsigned int)(cstm_mips_ixx_map[i].map_priv_1));
-+#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
-+ cstm_mips_ixx_map[i].set_vpp = cstm_mips_ixx_set_vpp;
-+#endif
-+ simple_map_init(&cstm_mips_ixx_map[i]);
-+ //printk(KERN_NOTICE "cstm_mips_ixx: ioremap is %x\n",(unsigned int)(cstm_mips_ixx_map[i].virt));
- }
-
- #if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)
-@@ -244,7 +200,7 @@
- printk(KERN_NOTICE "cstm_mips_ixx %d jedec: mymtd is %x\n",i,(unsigned int)mymtd);
- }
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
- cstm_mips_ixx_map[i].map_priv_2 = (unsigned long)mymtd;
- add_mtd_partitions(mymtd, parts, cstm_mips_ixx_board_desc[i].num_partitions);
-@@ -266,9 +222,9 @@
- del_mtd_partitions(mymtd);
- map_destroy(mymtd);
- }
-- if (cstm_mips_ixx_map[i].map_priv_1) {
-- iounmap((void *)cstm_mips_ixx_map[i].map_priv_1);
-- cstm_mips_ixx_map[i].map_priv_1 = 0;
-+ if (cstm_mips_ixx_map[i].virt) {
-+ iounmap((void *)cstm_mips_ixx_map[i].virt);
-+ cstm_mips_ixx_map[i].virt = 0;
- }
- }
- }
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/db1x00-flash.c linux/drivers/mtd/maps/db1x00-flash.c
---- linux-mips-2.4.27/drivers/mtd/maps/db1x00-flash.c 2003-02-16 07:25:24.000000000 +0100
-+++ linux/drivers/mtd/maps/db1x00-flash.c 2004-11-19 10:25:11.903199184 +0100
-@@ -8,6 +8,7 @@
- #include <linux/config.h>
- #include <linux/module.h>
- #include <linux/types.h>
-+#include <linux/init.h>
- #include <linux/kernel.h>
-
- #include <linux/mtd/mtd.h>
-@@ -29,76 +30,6 @@
- static unsigned long flash_size;
-
- static BCSR * const bcsr = (BCSR *)0xAE000000;
--
--__u8 physmap_read8(struct map_info *map, unsigned long ofs)
--{
-- __u8 ret;
-- ret = __raw_readb(map->map_priv_1 + ofs);
-- DBG("read8 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--__u16 physmap_read16(struct map_info *map, unsigned long ofs)
--{
-- __u16 ret;
-- ret = __raw_readw(map->map_priv_1 + ofs);
-- DBG("read16 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--__u32 physmap_read32(struct map_info *map, unsigned long ofs)
--{
-- __u32 ret;
-- ret = __raw_readl(map->map_priv_1 + ofs);
-- DBG("read32 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- DBG("physmap_copy from %x to %x\n", (unsigned)from, (unsigned)to);
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void physmap_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- DBG("write8 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- DBG("write16 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- DBG("write32 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- DBG("physmap_copy_to %x from %x\n", (unsigned)to, (unsigned)from);
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
--
--static struct map_info db1x00_map = {
-- name: "Db1x00 flash",
-- read8: physmap_read8,
-- read16: physmap_read16,
-- read32: physmap_read32,
-- copy_from: physmap_copy_from,
-- write8: physmap_write8,
-- write16: physmap_write16,
-- write32: physmap_write32,
-- copy_to: physmap_copy_to,
--};
--
- static unsigned char flash_buswidth = 4;
-
- /*
-@@ -115,58 +46,62 @@
- */
- static struct mtd_partition db1x00_partitions[] = {
- {
-- name: "User FS",
-- size: 0x1c00000,
-- offset: 0x0000000
-+ .name = "User FS",
-+ .size = 0x1c00000,
-+ .offset = 0x0000000
- },{
-- name: "yamon",
-- size: 0x0100000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE
-+ .name = "yamon",
-+ .size = 0x0100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE
- },{
-- name: "raw kernel",
-- size: (0x300000-0x40000), /* last 256KB is yamon env */
-- offset: MTDPART_OFS_APPEND,
-+ .name = "raw kernel",
-+ .size = (0x300000-0x40000), /* last 256KB is env */
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #elif defined(DB1X00_BOOT_ONLY)
- static struct mtd_partition db1x00_partitions[] = {
- {
-- name: "User FS",
-- size: 0x00c00000,
-- offset: 0x0000000
-+ .name = "User FS",
-+ .size = 0x00c00000,
-+ .offset = 0x0000000
- },{
-- name: "yamon",
-- size: 0x0100000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE
-+ .name = "yamon",
-+ .size = 0x0100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE
- },{
-- name: "raw kernel",
-- size: (0x300000-0x40000), /* last 256KB is yamon env */
-- offset: MTDPART_OFS_APPEND,
-+ .name = "raw kernel",
-+ .size = (0x300000-0x40000), /* last 256KB is env */
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #elif defined(DB1X00_USER_ONLY)
- static struct mtd_partition db1x00_partitions[] = {
- {
-- name: "User FS",
-- size: 0x0e00000,
-- offset: 0x0000000
-+ .name = "User FS",
-+ .size = 0x0e00000,
-+ .offset = 0x0000000
- },{
-- name: "raw kernel",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "raw kernel",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #else
- #error MTD_DB1X00 define combo error /* should never happen */
- #endif
-+#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
-
-+#define NAME "Db1x00 Linux Flash"
-
--#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
-+static struct map_info db1xxx_mtd_map = {
-+ .name = NAME,
-+};
-
- static struct mtd_partition *parsed_parts;
--static struct mtd_info *mymtd;
-+static struct mtd_info *db1xxx_mtd;
-
- /*
- * Probe the flash density and setup window address and size
-@@ -174,7 +109,7 @@
- * want the MTD driver to be probing the boot or user flash,
- * so having the option to enable only one bank is important.
- */
--int setup_flash_params()
-+int setup_flash_params(void)
- {
- switch ((bcsr->status >> 14) & 0x3) {
- case 0: /* 64Mbit devices */
-@@ -228,6 +163,10 @@
- default:
- return 1;
- }
-+ db1xxx_mtd_map.size = window_size;
-+ db1xxx_mtd_map.buswidth = flash_buswidth;
-+ db1xxx_mtd_map.phys = window_addr;
-+ db1xxx_mtd_map.buswidth = flash_buswidth;
- return 0;
- }
-
-@@ -235,10 +174,6 @@
- {
- struct mtd_partition *parts;
- int nb_parts = 0;
-- char *part_type;
--
-- /* Default flash buswidth */
-- db1x00_map.buswidth = flash_buswidth;
-
- if (setup_flash_params())
- return -ENXIO;
-@@ -246,32 +181,29 @@
- /*
- * Static partition definition selection
- */
-- part_type = "static";
- parts = db1x00_partitions;
- nb_parts = NB_OF(db1x00_partitions);
-- db1x00_map.size = window_size;
-
- /*
- * Now let's probe for the actual flash. Do it here since
- * specific machine settings might have been set above.
- */
- printk(KERN_NOTICE "Db1xxx flash: probing %d-bit flash bus\n",
-- db1x00_map.buswidth*8);
-- db1x00_map.map_priv_1 =
-- (unsigned long)ioremap(window_addr, window_size);
-- mymtd = do_map_probe("cfi_probe", &db1x00_map);
-- if (!mymtd) return -ENXIO;
-- mymtd->module = THIS_MODULE;
-+ db1xxx_mtd_map.buswidth*8);
-+ db1xxx_mtd_map.virt = (unsigned long)ioremap(window_addr, window_size);
-+ db1xxx_mtd = do_map_probe("cfi_probe", &db1xxx_mtd_map);
-+ if (!db1xxx_mtd) return -ENXIO;
-+ db1xxx_mtd->owner = THIS_MODULE;
-
-- add_mtd_partitions(mymtd, parts, nb_parts);
-+ add_mtd_partitions(db1xxx_mtd, parts, nb_parts);
- return 0;
- }
-
- static void __exit db1x00_mtd_cleanup(void)
- {
-- if (mymtd) {
-- del_mtd_partitions(mymtd);
-- map_destroy(mymtd);
-+ if (db1xxx_mtd) {
-+ del_mtd_partitions(db1xxx_mtd);
-+ map_destroy(db1xxx_mtd);
- if (parsed_parts)
- kfree(parsed_parts);
- }
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/dbox2-flash.c linux/drivers/mtd/maps/dbox2-flash.c
---- linux-mips-2.4.27/drivers/mtd/maps/dbox2-flash.c 2001-11-05 21:15:52.000000000 +0100
-+++ linux/drivers/mtd/maps/dbox2-flash.c 2004-11-19 10:25:11.904199032 +0100
-@@ -1,12 +1,13 @@
- /*
-- * $Id$
-+ * $Id$
- *
-- * Nokia / Sagem D-Box 2 flash driver
-+ * D-Box 2 flash driver
- */
-
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -16,22 +17,44 @@
- /* partition_info gives details on the logical partitions that the split the
- * single flash device into. If the size if zero we use up to the end of the
- * device. */
--static struct mtd_partition partition_info[]= {{name: "BR bootloader", // raw
-- size: 128 * 1024,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE},
-- {name: "PPC bootloader", // flfs
-- size: 128 * 1024,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: 0},
-- {name: "Kernel", // idxfs
-- size: 768 * 1024,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: 0},
-- {name: "System", // jffs
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: 0}};
-+static struct mtd_partition partition_info[]= {
-+ {
-+ .name = "BR bootloader",
-+ .size = 128 * 1024,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE
-+ },
-+ {
-+ .name = "flfs (ppcboot)",
-+ .size = 128 * 1024,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = 0
-+ },
-+ {
-+ .name = "root (cramfs)",
-+ .size = 7040 * 1024,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = 0
-+ },
-+ {
-+ .name = "var (jffs2)",
-+ .size = 896 * 1024,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = 0
-+ },
-+ {
-+ .name = "flash without bootloader",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = 128 * 1024,
-+ .mask_flags = 0
-+ },
-+ {
-+ .name = "complete flash",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE
-+ }
-+};
-
- #define NUM_PARTITIONS (sizeof(partition_info) / sizeof(partition_info[0]))
-
-@@ -40,72 +63,24 @@
-
- static struct mtd_info *mymtd;
-
--__u8 dbox2_flash_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 dbox2_flash_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 dbox2_flash_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void dbox2_flash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void dbox2_flash_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void dbox2_flash_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void dbox2_flash_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void dbox2_flash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
-
- struct map_info dbox2_flash_map = {
-- name: "D-Box 2 flash memory",
-- size: WINDOW_SIZE,
-- buswidth: 4,
-- read8: dbox2_flash_read8,
-- read16: dbox2_flash_read16,
-- read32: dbox2_flash_read32,
-- copy_from: dbox2_flash_copy_from,
-- write8: dbox2_flash_write8,
-- write16: dbox2_flash_write16,
-- write32: dbox2_flash_write32,
-- copy_to: dbox2_flash_copy_to
-+ .name = "D-Box 2 flash memory",
-+ .size = WINDOW_SIZE,
-+ .buswidth = 4,
-+ .phys = WINDOW_ADDR,
- };
-
- int __init init_dbox2_flash(void)
- {
- printk(KERN_NOTICE "D-Box 2 flash driver (size->0x%X mem->0x%X)\n", WINDOW_SIZE, WINDOW_ADDR);
-- dbox2_flash_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-+ dbox2_flash_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-
-- if (!dbox2_flash_map.map_priv_1) {
-+ if (!dbox2_flash_map.virt) {
- printk("Failed to ioremap\n");
- return -EIO;
- }
-+ simple_map_init(&dbox2_flash_map);
-
- // Probe for dual Intel 28F320 or dual AMD
- mymtd = do_map_probe("cfi_probe", &dbox2_flash_map);
-@@ -117,7 +92,7 @@
- }
-
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
- /* Create MTD devices for each partition. */
- add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
-@@ -125,7 +100,7 @@
- return 0;
- }
-
-- iounmap((void *)dbox2_flash_map.map_priv_1);
-+ iounmap((void *)dbox2_flash_map.virt);
- return -ENXIO;
- }
-
-@@ -135,9 +110,9 @@
- del_mtd_partitions(mymtd);
- map_destroy(mymtd);
- }
-- if (dbox2_flash_map.map_priv_1) {
-- iounmap((void *)dbox2_flash_map.map_priv_1);
-- dbox2_flash_map.map_priv_1 = 0;
-+ if (dbox2_flash_map.virt) {
-+ iounmap((void *)dbox2_flash_map.virt);
-+ dbox2_flash_map.virt = 0;
- }
- }
-
-@@ -146,5 +121,5 @@
-
-
- MODULE_LICENSE("GPL");
--MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>");
--MODULE_DESCRIPTION("MTD map driver for Nokia/Sagem D-Box 2 board");
-+MODULE_AUTHOR("Kári Davíðsson <kd@flaga.is>, Bastian Blank <waldi@tuxbox.org>, Alexander Wild <wild@te-elektronik.com>");
-+MODULE_DESCRIPTION("MTD map driver for D-Box 2 board");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/dc21285.c linux/drivers/mtd/maps/dc21285.c
---- linux-mips-2.4.27/drivers/mtd/maps/dc21285.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/maps/dc21285.c 2004-11-19 10:25:11.906198728 +0100
-@@ -5,12 +5,13 @@
- *
- * This code is GPL
- *
-- * $Id$
-+ * $Id$
- */
- #include <linux/config.h>
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -92,26 +93,42 @@
- }
-
- struct map_info dc21285_map = {
-- name: "DC21285 flash",
-- size: 16*1024*1024,
-- read8: dc21285_read8,
-- read16: dc21285_read16,
-- read32: dc21285_read32,
-- copy_from: dc21285_copy_from,
-- write8: dc21285_write8,
-- write16: dc21285_write16,
-- write32: dc21285_write32,
-- copy_to: dc21285_copy_to
-+ .name = "DC21285 flash",
-+ .phys = NO_XIP,
-+ .size = 16*1024*1024,
-+ .read8 = dc21285_read8,
-+ .read16 = dc21285_read16,
-+ .read32 = dc21285_read32,
-+ .copy_from = dc21285_copy_from,
-+ .write8 = dc21285_write8,
-+ .write16 = dc21285_write16,
-+ .write32 = dc21285_write32,
-+ .copy_to = dc21285_copy_to
- };
-
-
- /* Partition stuff */
- static struct mtd_partition *dc21285_parts;
--
--extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **);
-+#ifdef CONFIG_MTD_PARTITIONS
-+static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-+#endif
-
- int __init init_dc21285(void)
- {
-+
-+ /*
-+ * Flash timing is determined with bits 19-16 of the
-+ * CSR_SA110_CNTL. The value is the number of wait cycles, or
-+ * 0 for 16 cycles (the default). Cycles are 20 ns.
-+ * Here we use 7 for 140 ns flash chips.
-+ */
-+ /* access time */
-+ *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x000f0000) | (7 << 16));
-+ /* burst time */
-+ *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x00f00000) | (7 << 20));
-+ /* tristate time */
-+ *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24));
-+
- /* Determine buswidth */
- switch (*CSR_SA110_CNTL & (3<<14)) {
- case SA110_CNTL_ROMWIDTH_8:
-@@ -141,33 +158,18 @@
- if (mymtd) {
- int nrparts = 0;
-
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
- /* partition fixup */
-
--#ifdef CONFIG_MTD_REDBOOT_PARTS
-- nrparts = parse_redboot_partitions(mymtd, &dc21285_parts);
--#endif
-+#ifdef CONFIG_MTD_PARTITIONS
-+ nrparts = parse_mtd_partitions(mymtd, probes, &dc21285_parts, (void *)0);
- if (nrparts > 0) {
- add_mtd_partitions(mymtd, dc21285_parts, nrparts);
-- } else if (nrparts == 0) {
-- printk(KERN_NOTICE "RedBoot partition table failed\n");
-- add_mtd_device(mymtd);
-+ return 0;
- }
--
-- /*
-- * Flash timing is determined with bits 19-16 of the
-- * CSR_SA110_CNTL. The value is the number of wait cycles, or
-- * 0 for 16 cycles (the default). Cycles are 20 ns.
-- * Here we use 7 for 140 ns flash chips.
-- */
-- /* access time */
-- *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x000f0000) | (7 << 16));
-- /* burst time */
-- *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x00f00000) | (7 << 20));
-- /* tristate time */
-- *CSR_SA110_CNTL = ((*CSR_SA110_CNTL & ~0x0f000000) | (7 << 24));
--
-+#endif
-+ add_mtd_device(mymtd);
- return 0;
- }
-
-@@ -177,17 +179,16 @@
-
- static void __exit cleanup_dc21285(void)
- {
-- if (mymtd) {
-+#ifdef CONFIG_MTD_PARTITIONS
-+ if (dc21285_parts) {
-+ del_mtd_partitions(mymtd);
-+ kfree(dc21285_parts);
-+ } else
-+#endif
- del_mtd_device(mymtd);
-+
- map_destroy(mymtd);
-- mymtd = NULL;
-- }
-- if (dc21285_map.map_priv_1) {
- iounmap((void *)dc21285_map.map_priv_1);
-- dc21285_map.map_priv_1 = 0;
-- }
-- if(dc21285_parts)
-- kfree(dc21285_parts);
- }
-
- module_init(init_dc21285);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/dilnetpc.c linux/drivers/mtd/maps/dilnetpc.c
---- linux-mips-2.4.27/drivers/mtd/maps/dilnetpc.c 2002-06-27 00:35:50.000000000 +0200
-+++ linux/drivers/mtd/maps/dilnetpc.c 2004-11-19 10:25:11.907198576 +0100
-@@ -14,7 +14,7 @@
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
-- * $Id$
-+ * $Id$
- *
- * The DIL/Net PC is a tiny embedded PC board made by SSV Embedded Systems
- * featuring the AMD Elan SC410 processor. There are two variants of this
-@@ -29,6 +29,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -36,7 +37,7 @@
- #include <linux/mtd/concat.h>
-
- /*
--** The DIL/NetPC keeps it's BIOS in two distinct flash blocks.
-+** The DIL/NetPC keeps its BIOS in two distinct flash blocks.
- ** Destroying any of these blocks transforms the DNPC into
- ** a paperweight (albeit not a very useful one, considering
- ** it only weighs a few grams).
-@@ -189,45 +190,6 @@
- }
-
-
--static __u8 dnpc_read8(struct map_info *map, unsigned long ofs)
--{
-- return readb(map->map_priv_1 + ofs);
--}
--
--static __u16 dnpc_read16(struct map_info *map, unsigned long ofs)
--{
-- return readw(map->map_priv_1 + ofs);
--}
--
--static __u32 dnpc_read32(struct map_info *map, unsigned long ofs)
--{
-- return readl(map->map_priv_1 + ofs);
--}
--
--static void dnpc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
--}
--
--static void dnpc_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- writeb(d, map->map_priv_1 + adr);
--}
--
--static void dnpc_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- writew(d, map->map_priv_1 + adr);
--}
--
--static void dnpc_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- writel(d, map->map_priv_1 + adr);
--}
--
--static void dnpc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio((void *)(map->map_priv_1 + to), from, len);
--}
-
- /*
- ************************************************************
-@@ -288,19 +250,11 @@
- #define WINDOW_ADDR FLASH_BASE
-
- static struct map_info dnpc_map = {
-- name: "ADNP Flash Bank",
-- size: ADNP_WINDOW_SIZE,
-- buswidth: 1,
-- read8: dnpc_read8,
-- read16: dnpc_read16,
-- read32: dnpc_read32,
-- copy_from: dnpc_copy_from,
-- write8: dnpc_write8,
-- write16: dnpc_write16,
-- write32: dnpc_write32,
-- copy_to: dnpc_copy_to,
-- set_vpp: adnp_set_vpp,
-- map_priv_2: WINDOW_ADDR
-+ .name = "ADNP Flash Bank",
-+ .size = ADNP_WINDOW_SIZE,
-+ .buswidth = 1,
-+ .set_vpp = adnp_set_vpp,
-+ .phys = WINDOW_ADDR
- };
-
- /*
-@@ -316,29 +270,29 @@
- static struct mtd_partition partition_info[]=
- {
- {
-- name: "ADNP boot",
-- offset: 0,
-- size: 0xf0000,
-+ .name = "ADNP boot",
-+ .offset = 0,
-+ .size = 0xf0000,
- },
- {
-- name: "ADNP system BIOS",
-- offset: MTDPART_OFS_NXTBLK,
-- size: 0x10000,
-+ .name = "ADNP system BIOS",
-+ .offset = MTDPART_OFS_NXTBLK,
-+ .size = 0x10000,
- #ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
-- mask_flags: MTD_WRITEABLE,
-+ .mask_flags = MTD_WRITEABLE,
- #endif
- },
- {
-- name: "ADNP file system",
-- offset: MTDPART_OFS_NXTBLK,
-- size: 0x2f0000,
-+ .name = "ADNP file system",
-+ .offset = MTDPART_OFS_NXTBLK,
-+ .size = 0x2f0000,
- },
- {
-- name: "ADNP system BIOS entry",
-- offset: MTDPART_OFS_NXTBLK,
-- size: MTDPART_SIZ_FULL,
-+ .name = "ADNP system BIOS entry",
-+ .offset = MTDPART_OFS_NXTBLK,
-+ .size = MTDPART_SIZ_FULL,
- #ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
-- mask_flags: MTD_WRITEABLE,
-+ .mask_flags = MTD_WRITEABLE,
- #endif
- },
- };
-@@ -369,21 +323,21 @@
- static struct mtd_partition higlvl_partition_info[]=
- {
- {
-- name: "ADNP boot block",
-- offset: 0,
-- size: CONFIG_MTD_DILNETPC_BOOTSIZE,
-+ .name = "ADNP boot block",
-+ .offset = 0,
-+ .size = CONFIG_MTD_DILNETPC_BOOTSIZE,
- },
- {
-- name: "ADNP file system space",
-- offset: MTDPART_OFS_NXTBLK,
-- size: ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000,
-+ .name = "ADNP file system space",
-+ .offset = MTDPART_OFS_NXTBLK,
-+ .size = ADNP_WINDOW_SIZE-CONFIG_MTD_DILNETPC_BOOTSIZE-0x20000,
- },
- {
-- name: "ADNP system BIOS + BIOS Entry",
-- offset: MTDPART_OFS_NXTBLK,
-- size: MTDPART_SIZ_FULL,
-+ .name = "ADNP system BIOS + BIOS Entry",
-+ .offset = MTDPART_OFS_NXTBLK,
-+ .size = MTDPART_SIZ_FULL,
- #ifdef DNPC_BIOS_BLOCKS_WRITEPROTECTED
-- mask_flags: MTD_WRITEABLE,
-+ .mask_flags = MTD_WRITEABLE,
- #endif
- },
- };
-@@ -447,18 +401,19 @@
- }
-
- printk(KERN_NOTICE "DIL/Net %s flash: 0x%lx at 0x%lx\n",
-- is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.map_priv_2);
-+ is_dnp ? "DNPC" : "ADNP", dnpc_map.size, dnpc_map.phys);
-
-- dnpc_map.map_priv_1 = (unsigned long)ioremap_nocache(dnpc_map.map_priv_2, dnpc_map.size);
-+ dnpc_map.virt = (unsigned long)ioremap_nocache(dnpc_map.phys, dnpc_map.size);
-
-- dnpc_map_flash(dnpc_map.map_priv_2, dnpc_map.size);
-+ dnpc_map_flash(dnpc_map.phys, dnpc_map.size);
-
-- if (!dnpc_map.map_priv_1) {
-+ if (!dnpc_map.virt) {
- printk("Failed to ioremap_nocache\n");
- return -EIO;
- }
-+ simple_map_init(&dnpc_map);
-
-- printk("FLASH virtual address: 0x%lx\n", dnpc_map.map_priv_1);
-+ printk("FLASH virtual address: 0x%lx\n", dnpc_map.virt);
-
- mymtd = do_map_probe("jedec_probe", &dnpc_map);
-
-@@ -475,11 +430,11 @@
- mymtd->erasesize = 0x10000;
-
- if (!mymtd) {
-- iounmap((void *)dnpc_map.map_priv_1);
-+ iounmap((void *)dnpc_map.virt);
- return -ENXIO;
- }
-
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
- /*
- ** Supply pointers to lowlvl_parts[] array to add_mtd_partitions()
-@@ -525,10 +480,10 @@
- del_mtd_partitions(mymtd);
- map_destroy(mymtd);
- }
-- if (dnpc_map.map_priv_1) {
-- iounmap((void *)dnpc_map.map_priv_1);
-+ if (dnpc_map.virt) {
-+ iounmap((void *)dnpc_map.virt);
- dnpc_unmap_flash();
-- dnpc_map.map_priv_1 = 0;
-+ dnpc_map.virt = 0;
- }
- }
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/ebony.c linux/drivers/mtd/maps/ebony.c
---- linux-mips-2.4.27/drivers/mtd/maps/ebony.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/ebony.c 2004-11-19 10:25:11.909198272 +0100
-@@ -0,0 +1,164 @@
-+/*
-+ * $Id$
-+ *
-+ * Mapping for Ebony user flash
-+ *
-+ * Matt Porter <mporter@mvista.com>
-+ *
-+ * Copyright 2002 MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/config.h>
-+#include <asm/io.h>
-+#include <asm/ibm440.h>
-+#include <platforms/ebony.h>
-+
-+static struct mtd_info *flash;
-+
-+static struct map_info ebony_small_map = {
-+ .name = "Ebony small flash",
-+ .size = EBONY_SMALL_FLASH_SIZE,
-+ .buswidth = 1,
-+};
-+
-+static struct map_info ebony_large_map = {
-+ .name = "Ebony large flash",
-+ .size = EBONY_LARGE_FLASH_SIZE,
-+ .buswidth = 1,
-+};
-+
-+static struct mtd_partition ebony_small_partitions[] = {
-+ {
-+ .name = "OpenBIOS",
-+ .offset = 0x0,
-+ .size = 0x80000,
-+ }
-+};
-+
-+static struct mtd_partition ebony_large_partitions[] = {
-+ {
-+ .name = "fs",
-+ .offset = 0,
-+ .size = 0x380000,
-+ },
-+ {
-+ .name = "firmware",
-+ .offset = 0x380000,
-+ .size = 0x80000,
-+ }
-+};
-+
-+int __init init_ebony(void)
-+{
-+ u8 fpga0_reg;
-+ unsigned long fpga0_adr;
-+ unsigned long long small_flash_base, large_flash_base;
-+
-+ fpga0_adr = ioremap64(EBONY_FPGA_ADDR, 16);
-+ if (!fpga0_adr)
-+ return -ENOMEM;
-+
-+ fpga0_reg = readb(fpga0_adr);
-+ iounmap64(fpga0_adr);
-+
-+ if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
-+ !EBONY_FLASH_SEL(fpga0_reg))
-+ small_flash_base = EBONY_SMALL_FLASH_HIGH2;
-+ else if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
-+ EBONY_FLASH_SEL(fpga0_reg))
-+ small_flash_base = EBONY_SMALL_FLASH_HIGH1;
-+ else if (!EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
-+ !EBONY_FLASH_SEL(fpga0_reg))
-+ small_flash_base = EBONY_SMALL_FLASH_LOW2;
-+ else
-+ small_flash_base = EBONY_SMALL_FLASH_LOW1;
-+
-+ if (EBONY_BOOT_SMALL_FLASH(fpga0_reg) &&
-+ !EBONY_ONBRD_FLASH_EN(fpga0_reg))
-+ large_flash_base = EBONY_LARGE_FLASH_LOW;
-+ else
-+ large_flash_base = EBONY_LARGE_FLASH_HIGH;
-+
-+ ebony_small_map.phys = small_flash_base;
-+ ebony_small_map.virt =
-+ (unsigned long)ioremap64(small_flash_base,
-+ ebony_small_map.size);
-+
-+ if (!ebony_small_map.virt) {
-+ printk("Failed to ioremap flash\n");
-+ return -EIO;
-+ }
-+
-+ simple_map_init(&ebony_small_map);
-+
-+ flash = do_map_probe("map_rom", &ebony_small_map);
-+ if (flash) {
-+ flash->owner = THIS_MODULE;
-+ add_mtd_partitions(flash, ebony_small_partitions,
-+ ARRAY_SIZE(ebony_small_partitions));
-+ } else {
-+ printk("map probe failed for flash\n");
-+ return -ENXIO;
-+ }
-+
-+ ebony_large_map.phys = large_flash_base;
-+ ebony_large_map.virt =
-+ (unsigned long)ioremap64(large_flash_base,
-+ ebony_large_map.size);
-+
-+ if (!ebony_large_map.virt) {
-+ printk("Failed to ioremap flash\n");
-+ return -EIO;
-+ }
-+
-+ simple_map_init(&ebony_large_map);
-+
-+ flash = do_map_probe("cfi_probe", &ebony_large_map);
-+ if (flash) {
-+ flash->owner = THIS_MODULE;
-+ add_mtd_partitions(flash, ebony_large_partitions,
-+ ARRAY_SIZE(ebony_large_partitions));
-+ } else {
-+ printk("map probe failed for flash\n");
-+ return -ENXIO;
-+ }
-+
-+ return 0;
-+}
-+
-+static void __exit cleanup_ebony(void)
-+{
-+ if (flash) {
-+ del_mtd_partitions(flash);
-+ map_destroy(flash);
-+ }
-+
-+ if (ebony_small_map.virt) {
-+ iounmap((void *)ebony_small_map.virt);
-+ ebony_small_map.virt = 0;
-+ }
-+
-+ if (ebony_large_map.virt) {
-+ iounmap((void *)ebony_large_map.virt);
-+ ebony_large_map.virt = 0;
-+ }
-+}
-+
-+module_init(init_ebony);
-+module_exit(cleanup_ebony);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Matt Porter <mporter@mvista.com>");
-+MODULE_DESCRIPTION("MTD map and partitions for IBM 440GP Ebony boards");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/edb7312.c linux/drivers/mtd/maps/edb7312.c
---- linux-mips-2.4.27/drivers/mtd/maps/edb7312.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/maps/edb7312.c 2004-11-19 10:25:11.910198120 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Handle mapping of the NOR flash on Cogent EDB7312 boards
- *
-@@ -13,6 +13,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -35,61 +36,11 @@
-
- static struct mtd_info *mymtd;
-
--__u8 edb7312nor_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 edb7312nor_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 edb7312nor_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void edb7312nor_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void edb7312nor_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void edb7312nor_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void edb7312nor_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void edb7312nor_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
--
- struct map_info edb7312nor_map = {
-- name: "NOR flash on EDB7312",
-- size: WINDOW_SIZE,
-- buswidth: BUSWIDTH,
-- read8: edb7312nor_read8,
-- read16: edb7312nor_read16,
-- read32: edb7312nor_read32,
-- copy_from: edb7312nor_copy_from,
-- write8: edb7312nor_write8,
-- write16: edb7312nor_write16,
-- write32: edb7312nor_write32,
-- copy_to: edb7312nor_copy_to
-+ .name = "NOR flash on EDB7312",
-+ .size = WINDOW_SIZE,
-+ .buswidth = BUSWIDTH,
-+ .phys = WINDOW_ADDR,
- };
-
- #ifdef CONFIG_MTD_PARTITIONS
-@@ -100,29 +51,23 @@
- static struct mtd_partition static_partitions[3] =
- {
- {
-- name: "ARMboot",
-- size: 0x40000,
-- offset: 0
-+ .name = "ARMboot",
-+ .size = 0x40000,
-+ .offset = 0
- },
- {
-- name: "Kernel",
-- size: 0x200000,
-- offset: 0x40000
-+ .name = "Kernel",
-+ .size = 0x200000,
-+ .offset = 0x40000
- },
- {
-- name: "RootFS",
-- size: 0xDC0000,
-- offset: 0x240000
-+ .name = "RootFS",
-+ .size = 0xDC0000,
-+ .offset = 0x240000
- },
- };
-
--#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
--
--#ifdef CONFIG_MTD_CMDLINE_PARTS
--int parse_cmdline_partitions(struct mtd_info *master,
-- struct mtd_partition **pparts,
-- const char *mtd_id);
--#endif
-+static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-
- #endif
-
-@@ -137,32 +82,33 @@
-
- printk(KERN_NOTICE MSG_PREFIX "0x%08x at 0x%08x\n",
- WINDOW_SIZE, WINDOW_ADDR);
-- edb7312nor_map.map_priv_1 = (unsigned long)
-+ edb7312nor_map.virt = (unsigned long)
- ioremap(WINDOW_ADDR, WINDOW_SIZE);
-
-- if (!edb7312nor_map.map_priv_1) {
-+ if (!edb7312nor_map.virt) {
- printk(MSG_PREFIX "failed to ioremap\n");
- return -EIO;
- }
-
-+ simple_map_init(&edb7312nor_map);
-+
- mymtd = 0;
- type = rom_probe_types;
- for(; !mymtd && *type; type++) {
- mymtd = do_map_probe(*type, &edb7312nor_map);
- }
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
- #ifdef CONFIG_MTD_PARTITIONS
--#ifdef CONFIG_MTD_CMDLINE_PARTS
-- mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts, MTDID);
-+ mtd_parts_nb = parse_mtd_partitions(mymtd, probes, &mtd_parts, MTDID);
- if (mtd_parts_nb > 0)
-- part_type = "command line";
--#endif
-+ part_type = "detected";
-+
- if (mtd_parts_nb == 0)
- {
- mtd_parts = static_partitions;
-- mtd_parts_nb = NB_OF(static_partitions);
-+ mtd_parts_nb = ARRAY_SIZE(static_partitions);
- part_type = "static";
- }
- #endif
-@@ -178,7 +124,7 @@
- return 0;
- }
-
-- iounmap((void *)edb7312nor_map.map_priv_1);
-+ iounmap((void *)edb7312nor_map.virt);
- return -ENXIO;
- }
-
-@@ -188,9 +134,9 @@
- del_mtd_device(mymtd);
- map_destroy(mymtd);
- }
-- if (edb7312nor_map.map_priv_1) {
-- iounmap((void *)edb7312nor_map.map_priv_1);
-- edb7312nor_map.map_priv_1 = 0;
-+ if (edb7312nor_map.virt) {
-+ iounmap((void *)edb7312nor_map.virt);
-+ edb7312nor_map.virt = 0;
- }
- }
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/elan-104nc.c linux/drivers/mtd/maps/elan-104nc.c
---- linux-mips-2.4.27/drivers/mtd/maps/elan-104nc.c 2002-06-27 00:35:50.000000000 +0200
-+++ linux/drivers/mtd/maps/elan-104nc.c 2004-11-19 10:25:11.912197816 +0100
-@@ -16,7 +16,7 @@
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-- $Id$
-+ $Id$
-
- The ELAN-104NC has up to 8 Mibyte of Intel StrataFlash (28F320/28F640) in x16
- mode. This drivers uses the CFI probe and Intel Extended Command Set drivers.
-@@ -40,6 +40,7 @@
- #include <asm/io.h>
-
- #include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
- #include <linux/mtd/partitions.h>
-
- #define WINDOW_START 0xb0000
-@@ -59,14 +60,14 @@
- * single flash device into. If the size if zero we use up to the end of the
- * device. */
- static struct mtd_partition partition_info[]={
-- { name: "ELAN-104NC flash boot partition",
-- offset: 0,
-- size: 640*1024 },
-- { name: "ELAN-104NC flash partition 1",
-- offset: 640*1024,
-- size: 896*1024 },
-- { name: "ELAN-104NC flash partition 2",
-- offset: (640+896)*1024 }
-+ { .name = "ELAN-104NC flash boot partition",
-+ .offset = 0,
-+ .size = 640*1024 },
-+ { .name = "ELAN-104NC flash partition 1",
-+ .offset = 640*1024,
-+ .size = 896*1024 },
-+ { .name = "ELAN-104NC flash partition 2",
-+ .offset = (640+896)*1024 }
- };
- #define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0]))
-
-@@ -195,19 +196,20 @@
- }
-
- static struct map_info elan_104nc_map = {
-- name: "ELAN-104NC flash",
-- size: 8*1024*1024, /* this must be set to a maximum possible amount
-+ .name = "ELAN-104NC flash",
-+ .phys = NO_XIP,
-+ .size = 8*1024*1024, /* this must be set to a maximum possible amount
- of flash so the cfi probe routines find all
- the chips */
-- buswidth: 2,
-- read8: elan_104nc_read8,
-- read16: elan_104nc_read16,
-- read32: elan_104nc_read32,
-- copy_from: elan_104nc_copy_from,
-- write8: elan_104nc_write8,
-- write16: elan_104nc_write16,
-- write32: elan_104nc_write32,
-- copy_to: elan_104nc_copy_to
-+ .buswidth = 2,
-+ .read8 = elan_104nc_read8,
-+ .read16 = elan_104nc_read16,
-+ .read32 = elan_104nc_read32,
-+ .copy_from = elan_104nc_copy_from,
-+ .write8 = elan_104nc_write8,
-+ .write16 = elan_104nc_write16,
-+ .write32 = elan_104nc_write32,
-+ .copy_to = elan_104nc_copy_to
- };
-
- /* MTD device for all of the flash. */
-@@ -221,20 +223,13 @@
- }
-
- iounmap((void *)iomapadr);
-- release_region(PAGE_IO,PAGE_IO_SIZE);
- }
-
- int __init init_elan_104nc(void)
- {
-- /* Urg! We use I/O port 0x22 without request_region()ing it */
-- /*
-- if (check_region(PAGE_IO,PAGE_IO_SIZE) != 0) {
-- printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
-- elan_104nc_map.name,
-- PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 );
-- return -EAGAIN;
-- }
-- */
-+ /* Urg! We use I/O port 0x22 without request_region()ing it,
-+ because it's already allocated to the PIC. */
-+
- iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH);
- if (!iomapadr) {
- printk( KERN_ERR"%s: failed to ioremap memory region\n",
-@@ -242,10 +237,6 @@
- return -EIO;
- }
-
-- /*
-- request_region( PAGE_IO, PAGE_IO_SIZE, "ELAN-104NC flash" );
-- */
--
- printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
- elan_104nc_map.name,
- PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1,
-@@ -260,7 +251,7 @@
- return -ENXIO;
- }
-
-- all_mtd->module=THIS_MODULE;
-+ all_mtd->owner = THIS_MODULE;
-
- /* Create MTD devices for each partition. */
- add_mtd_partitions( all_mtd, partition_info, NUM_PARTITIONS );
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/epxa10db-flash.c linux/drivers/mtd/maps/epxa10db-flash.c
---- linux-mips-2.4.27/drivers/mtd/maps/epxa10db-flash.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/maps/epxa10db-flash.c 2004-11-19 10:25:11.913197664 +0100
-@@ -5,7 +5,7 @@
- * Copyright (C) 2001 Altera Corporation
- * Copyright (C) 2001 Red Hat, Inc.
- *
-- * $Id$
-+ * $Id$
- *
- * 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
-@@ -26,6 +26,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -43,87 +44,38 @@
-
- static struct mtd_info *mymtd;
-
--extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **);
- static int epxa_default_partitions(struct mtd_info *master, struct mtd_partition **pparts);
-
--static __u8 epxa_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--static __u16 epxa_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--static __u32 epxa_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--static void epxa_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
--}
--
--static void epxa_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void epxa_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void epxa_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void epxa_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio((void *)(map->map_priv_1 + to), from, len);
--}
--
--
-
- static struct map_info epxa_map = {
-- name: "EPXA flash",
-- size: FLASH_SIZE,
-- buswidth: 2,
-- read8: epxa_read8,
-- read16: epxa_read16,
-- read32: epxa_read32,
-- copy_from: epxa_copy_from,
-- write8: epxa_write8,
-- write16: epxa_write16,
-- write32: epxa_write32,
-- copy_to: epxa_copy_to
-+ .name = "EPXA flash",
-+ .size = FLASH_SIZE,
-+ .buswidth = 2,
-+ .phys = FLASH_START,
- };
-
-+static const char *probes[] = { "RedBoot", "afs", NULL };
-
- static int __init epxa_mtd_init(void)
- {
- int i;
-
-- printk(KERN_NOTICE "%s flash device: %x at %x\n", BOARD_NAME, FLASH_SIZE, FLASH_START);
-- epxa_map.map_priv_1 = (unsigned long)ioremap(FLASH_START, FLASH_SIZE);
-- if (!epxa_map.map_priv_1) {
-+ printk(KERN_NOTICE "%s flash device: 0x%x at 0x%x\n", BOARD_NAME, FLASH_SIZE, FLASH_START);
-+
-+ epxa_map.virt = (unsigned long)ioremap(FLASH_START, FLASH_SIZE);
-+ if (!epxa_map.virt) {
- printk("Failed to ioremap %s flash\n",BOARD_NAME);
- return -EIO;
- }
-+ simple_map_init(&epxa_map);
-
- mymtd = do_map_probe("cfi_probe", &epxa_map);
- if (!mymtd) {
-- iounmap((void *)epxa_map.map_priv_1);
-+ iounmap((void *)epxa_map.virt);
- return -ENXIO;
- }
-
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
- /* Unlock the flash device. */
- if(mymtd->unlock){
-@@ -135,23 +87,14 @@
- }
- }
-
--#ifdef CONFIG_MTD_REDBOOT_PARTS
-- nr_parts = parse_redboot_partitions(mymtd, &parts);
--
-- if (nr_parts > 0) {
-- add_mtd_partitions(mymtd, parts, nr_parts);
-- return 0;
-- }
--#endif
--#ifdef CONFIG_MTD_AFS_PARTS
-- nr_parts = parse_afs_partitions(mymtd, &parts);
-+#ifdef CONFIG_MTD_PARTITIONS
-+ nr_parts = parse_mtd_partitions(mymtd, probes, &parts, 0);
-
- if (nr_parts > 0) {
- add_mtd_partitions(mymtd, parts, nr_parts);
- return 0;
- }
- #endif
--
- /* No recognised partitioning schemes found - use defaults */
- nr_parts = epxa_default_partitions(mymtd, &parts);
- if (nr_parts > 0) {
-@@ -173,9 +116,9 @@
- del_mtd_device(mymtd);
- map_destroy(mymtd);
- }
-- if (epxa_map.map_priv_1) {
-- iounmap((void *)epxa_map.map_priv_1);
-- epxa_map.map_priv_1 = 0;
-+ if (epxa_map.virt) {
-+ iounmap((void *)epxa_map.virt);
-+ epxa_map.virt = 0;
- }
- }
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/fortunet.c linux/drivers/mtd/maps/fortunet.c
---- linux-mips-2.4.27/drivers/mtd/maps/fortunet.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/maps/fortunet.c 2004-11-19 10:25:11.915197360 +0100
-@@ -1,11 +1,12 @@
- /* fortunet.c memory map
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -23,7 +24,7 @@
-
- struct map_region
- {
-- int window_addr_phyical;
-+ int window_addr_physical;
- int altbuswidth;
- struct map_info map_info;
- struct mtd_info *mymtd;
-@@ -37,57 +38,10 @@
- static int map_regions_parts[MAX_NUM_REGIONS] = {0,0,0,0};
-
-
--__u8 fortunet_read8(struct map_info *map, unsigned long ofs)
--{
-- return *(__u8 *)(map->map_priv_1 + ofs);
--}
--
--__u16 fortunet_read16(struct map_info *map, unsigned long ofs)
--{
-- return *(__u16 *)(map->map_priv_1 + ofs);
--}
--
--__u32 fortunet_read32(struct map_info *map, unsigned long ofs)
--{
-- return *(__u32 *)(map->map_priv_1 + ofs);
--}
--
--void fortunet_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy(to, (void *)(map->map_priv_1 + from), len);
--}
--
--void fortunet_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- *(__u8 *)(map->map_priv_1 + adr) = d;
--}
--
--void fortunet_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- *(__u16 *)(map->map_priv_1 + adr) = d;
--}
--
--void fortunet_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- *(__u32 *)(map->map_priv_1 + adr) = d;
--}
--
--void fortunet_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy((void *)(map->map_priv_1 + to), from, len);
--}
-
- struct map_info default_map = {
-- size: DEF_WINDOW_SIZE,
-- buswidth: 4,
-- read8: fortunet_read8,
-- read16: fortunet_read16,
-- read32: fortunet_read32,
-- copy_from: fortunet_copy_from,
-- write8: fortunet_write8,
-- write16: fortunet_write16,
-- write32: fortunet_write32,
-- copy_to: fortunet_copy_to
-+ .size = DEF_WINDOW_SIZE,
-+ .buswidth = 4,
- };
-
- static char * __init get_string_option(char *dest,int dest_size,char *sor)
-@@ -147,7 +101,7 @@
- get_options (get_string_option(string,sizeof(string),line),6,params);
- if(params[0]<1)
- {
-- printk(MTD_FORTUNET_PK "Bad paramters for MTD Region "
-+ printk(MTD_FORTUNET_PK "Bad parameters for MTD Region "
- " name,region-number[,base,size,buswidth,altbuswidth]\n");
- return 1;
- }
-@@ -161,14 +115,14 @@
- memcpy(&map_regions[params[1]].map_info,
- &default_map,sizeof(map_regions[params[1]].map_info));
- map_regions_set[params[1]] = 1;
-- map_regions[params[1]].window_addr_phyical = DEF_WINDOW_ADDR_PHY;
-+ map_regions[params[1]].window_addr_physical = DEF_WINDOW_ADDR_PHY;
- map_regions[params[1]].altbuswidth = 2;
- map_regions[params[1]].mymtd = NULL;
- map_regions[params[1]].map_info.name = map_regions[params[1]].map_name;
- strcpy(map_regions[params[1]].map_info.name,string);
- if(params[0]>1)
- {
-- map_regions[params[1]].window_addr_phyical = params[2];
-+ map_regions[params[1]].window_addr_physical = params[2];
- }
- if(params[0]>2)
- {
-@@ -185,14 +139,14 @@
- return 1;
- }
-
--static int __init MTD_New_Partion(char *line)
-+static int __init MTD_New_Partition(char *line)
- {
- char string[MAX_NAME_SIZE];
- int params[4];
- get_options (get_string_option(string,sizeof(string),line),4,params);
- if(params[0]<3)
- {
-- printk(MTD_FORTUNET_PK "Bad paramters for MTD Partion "
-+ printk(MTD_FORTUNET_PK "Bad parameters for MTD Partition "
- " name,region-number,size,offset\n");
- return 1;
- }
-@@ -204,7 +158,7 @@
- }
- if(map_regions_parts[params[1]]>=MAX_NUM_PARTITIONS)
- {
-- printk(MTD_FORTUNET_PK "Out of space for partion in this region\n");
-+ printk(MTD_FORTUNET_PK "Out of space for partition in this region\n");
- return 1;
- }
- map_regions[params[1]].parts[map_regions_parts[params[1]]].name =
-@@ -220,7 +174,10 @@
- }
-
- __setup("MTD_Region=", MTD_New_Region);
--__setup("MTD_Partion=", MTD_New_Partion);
-+__setup("MTD_Partition=", MTD_New_Partition);
-+
-+/* Backwards-spelling-compatibility */
-+__setup("MTD_Partion=", MTD_New_Partition);
-
- int __init init_fortunet(void)
- {
-@@ -229,13 +186,13 @@
- {
- if(map_regions_parts[ix]&&(!map_regions_set[ix]))
- {
-- printk(MTD_FORTUNET_PK "Region %d is not setup (Seting to default)\n",
-+ printk(MTD_FORTUNET_PK "Region %d is not setup (Setting to default)\n",
- ix);
- memset(&map_regions[ix],0,sizeof(map_regions[ix]));
- memcpy(&map_regions[ix].map_info,&default_map,
- sizeof(map_regions[ix].map_info));
- map_regions_set[ix] = 1;
-- map_regions[ix].window_addr_phyical = DEF_WINDOW_ADDR_PHY;
-+ map_regions[ix].window_addr_physical = DEF_WINDOW_ADDR_PHY;
- map_regions[ix].altbuswidth = 2;
- map_regions[ix].mymtd = NULL;
- map_regions[ix].map_info.name = map_regions[ix].map_name;
-@@ -244,30 +201,35 @@
- if(map_regions_set[ix])
- {
- iy++;
-- printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at phyicaly "
-+ printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at physically "
- " address %x size %x\n",
- map_regions[ix].map_info.name,
-- map_regions[ix].window_addr_phyical,
-+ map_regions[ix].window_addr_physical,
- map_regions[ix].map_info.size);
-- map_regions[ix].map_info.map_priv_1 =
-+
-+ map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical,
-+
-+ map_regions[ix].map_info.virt =
- (int)ioremap_nocache(
-- map_regions[ix].window_addr_phyical,
-+ map_regions[ix].window_addr_physical,
- map_regions[ix].map_info.size);
-- if(!map_regions[ix].map_info.map_priv_1)
-+ if(!map_regions[ix].map_info.virt)
- {
- printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n",
- map_regions[ix].map_info.name);
- return -ENXIO;
- }
-- printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is veritualy at: %x\n",
-+ simple_map_init(&map_regions[ix].map_info);
-+
-+ printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is virtually at: %x\n",
- map_regions[ix].map_info.name,
-- map_regions[ix].map_info.map_priv_1);
-+ map_regions[ix].map_info.virt);
- map_regions[ix].mymtd = do_map_probe("cfi_probe",
- &map_regions[ix].map_info);
- if((!map_regions[ix].mymtd)&&(
- map_regions[ix].altbuswidth!=map_regions[ix].map_info.buswidth))
- {
-- printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternet buswidth "
-+ printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternate buswidth "
- "for %s flash.\n",
- map_regions[ix].map_info.name);
- map_regions[ix].map_info.buswidth =
-@@ -275,7 +237,7 @@
- map_regions[ix].mymtd = do_map_probe("cfi_probe",
- &map_regions[ix].map_info);
- }
-- map_regions[ix].mymtd->module = THIS_MODULE;
-+ map_regions[ix].mymtd->owner = THIS_MODULE;
- add_mtd_partitions(map_regions[ix].mymtd,
- map_regions[ix].parts,map_regions_parts[ix]);
- }
-@@ -297,7 +259,7 @@
- del_mtd_partitions( map_regions[ix].mymtd );
- map_destroy( map_regions[ix].mymtd );
- }
-- iounmap((void *)map_regions[ix].map_info.map_priv_1);
-+ iounmap((void *)map_regions[ix].map_info.virt);
- }
- }
- }
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/h720x-flash.c linux/drivers/mtd/maps/h720x-flash.c
---- linux-mips-2.4.27/drivers/mtd/maps/h720x-flash.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/h720x-flash.c 2004-11-19 10:25:11.917197056 +0100
-@@ -0,0 +1,142 @@
-+/*
-+ * Flash memory access on Hynix GMS30C7201/HMS30C7202 based
-+ * evaluation boards
-+ *
-+ * (C) 2002 Jungjun Kim <jungjun.kim@hynix.com>
-+ * 2003 Thomas Gleixner <tglx@linutronix.de>
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/slab.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+
-+static struct mtd_info *mymtd;
-+
-+static struct map_info h720x_map = {
-+ .name = "H720X",
-+ .buswidth = 4,
-+ .size = FLASH_SIZE,
-+ .phys = FLASH_PHYS,
-+};
-+
-+static struct mtd_partition h720x_partitions[] = {
-+ {
-+ .name = "ArMon",
-+ .size = 0x00080000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE
-+ },{
-+ .name = "Env",
-+ .size = 0x00040000,
-+ .offset = 0x00080000,
-+ .mask_flags = MTD_WRITEABLE
-+ },{
-+ .name = "Kernel",
-+ .size = 0x00180000,
-+ .offset = 0x000c0000,
-+ .mask_flags = MTD_WRITEABLE
-+ },{
-+ .name = "Ramdisk",
-+ .size = 0x00400000,
-+ .offset = 0x00240000,
-+ .mask_flags = MTD_WRITEABLE
-+ },{
-+ .name = "jffs2",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND
-+ }
-+};
-+
-+#define NUM_PARTITIONS (sizeof(h720x_partitions)/sizeof(h720x_partitions[0]))
-+
-+static int nr_mtd_parts;
-+static struct mtd_partition *mtd_parts;
-+static const char *probes[] = { "cmdlinepart", NULL };
-+
-+/*
-+ * Initialize FLASH support
-+ */
-+int __init h720x_mtd_init(void)
-+{
-+
-+ char *part_type = NULL;
-+
-+ h720x_map.virt = (unsigned long)ioremap(FLASH_PHYS, FLASH_SIZE);
-+
-+ if (!h720x_map.virt) {
-+ printk(KERN_ERR "H720x-MTD: ioremap failed\n");
-+ return -EIO;
-+ }
-+
-+ simple_map_init(&h720x_map);
-+
-+ // Probe for flash buswidth 4
-+ printk (KERN_INFO "H720x-MTD probing 32bit FLASH\n");
-+ mymtd = do_map_probe("cfi_probe", &h720x_map);
-+ if (!mymtd) {
-+ printk (KERN_INFO "H720x-MTD probing 16bit FLASH\n");
-+ // Probe for buswidth 2
-+ h720x_map.buswidth = 2;
-+ mymtd = do_map_probe("cfi_probe", &h720x_map);
-+ }
-+
-+ if (mymtd) {
-+ mymtd->owner = THIS_MODULE;
-+
-+#ifdef CONFIG_MTD_PARTITIONS
-+ nr_mtd_parts = parse_mtd_partitions(mymtd, probes, &mtd_parts, 0);
-+ if (nr_mtd_parts > 0)
-+ part_type = "command line";
-+#endif
-+ if (nr_mtd_parts <= 0) {
-+ mtd_parts = h720x_partitions;
-+ nr_mtd_parts = NUM_PARTITIONS;
-+ part_type = "builtin";
-+ }
-+ printk(KERN_INFO "Using %s partition table\n", part_type);
-+ add_mtd_partitions(mymtd, mtd_parts, nr_mtd_parts);
-+ return 0;
-+ }
-+
-+ iounmap((void *)h720x_map.virt);
-+ return -ENXIO;
-+}
-+
-+/*
-+ * Cleanup
-+ */
-+static void __exit h720x_mtd_cleanup(void)
-+{
-+
-+ if (mymtd) {
-+ del_mtd_partitions(mymtd);
-+ map_destroy(mymtd);
-+ }
-+
-+ /* Free partition info, if commandline partition was used */
-+ if (mtd_parts && (mtd_parts != h720x_partitions))
-+ kfree (mtd_parts);
-+
-+ if (h720x_map.virt) {
-+ iounmap((void *)h720x_map.virt);
-+ h720x_map.virt = 0;
-+ }
-+}
-+
-+
-+module_init(h720x_mtd_init);
-+module_exit(h720x_mtd_cleanup);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Thomas Gleixner <tglx@linutronix.de>");
-+MODULE_DESCRIPTION("MTD map driver for Hynix evaluation boards");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/ichxrom.c linux/drivers/mtd/maps/ichxrom.c
---- linux-mips-2.4.27/drivers/mtd/maps/ichxrom.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/ichxrom.c 2004-11-19 10:25:11.918196904 +0100
-@@ -0,0 +1,380 @@
-+/*
-+ * ichxrom.c
-+ *
-+ * Normal mappings of chips in physical memory
-+ * $Id$
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <asm/io.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/config.h>
-+#include <linux/pci.h>
-+#include <linux/pci_ids.h>
-+
-+#define xstr(s) str(s)
-+#define str(s) #s
-+#define MOD_NAME xstr(KBUILD_BASENAME)
-+
-+#define MTD_DEV_NAME_LENGTH 16
-+
-+#define RESERVE_MEM_REGION 0
-+
-+#define ICHX_FWH_REGION_START 0xFF000000UL
-+#define ICHX_FWH_REGION_SIZE 0x01000000UL
-+#define BIOS_CNTL 0x4e
-+#define FWH_DEC_EN1 0xE3
-+#define FWH_DEC_EN2 0xF0
-+#define FWH_SEL1 0xE8
-+#define FWH_SEL2 0xEE
-+
-+struct ichxrom_map_info {
-+ struct map_info map;
-+ struct mtd_info *mtd;
-+ unsigned long window_addr;
-+ struct pci_dev *pdev;
-+ struct resource window_rsrc;
-+ struct resource rom_rsrc;
-+ char mtd_name[MTD_DEV_NAME_LENGTH];
-+};
-+
-+static inline unsigned long addr(struct map_info *map, unsigned long ofs)
-+{
-+ unsigned long offset;
-+ offset = ((8*1024*1024) - map->size) + ofs;
-+ if (offset >= (4*1024*1024)) {
-+ offset += 0x400000;
-+ }
-+ return map->map_priv_1 + 0x400000 + offset;
-+}
-+
-+static inline unsigned long dbg_addr(struct map_info *map, unsigned long addr)
-+{
-+ return addr - map->map_priv_1 + ICHX_FWH_REGION_START;
-+}
-+
-+static __u8 ichxrom_read8(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readb(addr(map, ofs));
-+}
-+
-+static __u16 ichxrom_read16(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readw(addr(map, ofs));
-+}
-+
-+static __u32 ichxrom_read32(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readl(addr(map, ofs));
-+}
-+
-+static void ichxrom_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-+{
-+ memcpy_fromio(to, addr(map, from), len);
-+}
-+
-+static void ichxrom_write8(struct map_info *map, __u8 d, unsigned long ofs)
-+{
-+ __raw_writeb(d, addr(map,ofs));
-+ mb();
-+}
-+
-+static void ichxrom_write16(struct map_info *map, __u16 d, unsigned long ofs)
-+{
-+ __raw_writew(d, addr(map, ofs));
-+ mb();
-+}
-+
-+static void ichxrom_write32(struct map_info *map, __u32 d, unsigned long ofs)
-+{
-+ __raw_writel(d, addr(map, ofs));
-+ mb();
-+}
-+
-+static void ichxrom_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-+{
-+ memcpy_toio(addr(map, to), from, len);
-+}
-+
-+static struct ichxrom_map_info ichxrom_map = {
-+ .map = {
-+ .name = MOD_NAME,
-+ .phys = NO_XIP,
-+ .size = 0,
-+ .buswidth = 1,
-+ .read8 = ichxrom_read8,
-+ .read16 = ichxrom_read16,
-+ .read32 = ichxrom_read32,
-+ .copy_from = ichxrom_copy_from,
-+ .write8 = ichxrom_write8,
-+ .write16 = ichxrom_write16,
-+ .write32 = ichxrom_write32,
-+ .copy_to = ichxrom_copy_to,
-+ /* Firmware hubs only use vpp when being programmed
-+ * in a factory setting. So in-place programming
-+ * needs to use a different method.
-+ */
-+ },
-+ /* remaining fields of structure are initialized to 0 */
-+};
-+
-+enum fwh_lock_state {
-+ FWH_DENY_WRITE = 1,
-+ FWH_IMMUTABLE = 2,
-+ FWH_DENY_READ = 4,
-+};
-+
-+static void ichxrom_cleanup(struct ichxrom_map_info *info)
-+{
-+ u16 word;
-+
-+ /* Disable writes through the rom window */
-+ pci_read_config_word(info->pdev, BIOS_CNTL, &word);
-+ pci_write_config_word(info->pdev, BIOS_CNTL, word & ~1);
-+
-+ if (info->mtd) {
-+ del_mtd_device(info->mtd);
-+ map_destroy(info->mtd);
-+ info->mtd = NULL;
-+ info->map.virt = 0;
-+ }
-+ if (info->rom_rsrc.parent)
-+ release_resource(&info->rom_rsrc);
-+ if (info->window_rsrc.parent)
-+ release_resource(&info->window_rsrc);
-+
-+ if (info->window_addr) {
-+ iounmap((void *)(info->window_addr));
-+ info->window_addr = 0;
-+ }
-+}
-+
-+
-+static int ichxrom_set_lock_state(struct mtd_info *mtd, loff_t ofs, size_t len,
-+ enum fwh_lock_state state)
-+{
-+ struct map_info *map = mtd->priv;
-+ unsigned long start = ofs;
-+ unsigned long end = start + len -1;
-+
-+ /* FIXME do I need to guard against concurrency here? */
-+ /* round down to 64K boundaries */
-+ start = start & ~0xFFFF;
-+ end = end & ~0xFFFF;
-+ while (start <= end) {
-+ unsigned long ctrl_addr;
-+ ctrl_addr = addr(map, start) - 0x400000 + 2;
-+ writeb(state, ctrl_addr);
-+ start = start + 0x10000;
-+ }
-+ return 0;
-+}
-+
-+static int ichxrom_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
-+{
-+ return ichxrom_set_lock_state(mtd, ofs, len, FWH_DENY_WRITE);
-+}
-+
-+static int ichxrom_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
-+{
-+ return ichxrom_set_lock_state(mtd, ofs, len, 0);
-+}
-+
-+static int __devinit ichxrom_init_one (struct pci_dev *pdev,
-+ const struct pci_device_id *ent)
-+{
-+ u16 word;
-+ struct ichxrom_map_info *info = &ichxrom_map;
-+ unsigned long map_size;
-+
-+ /* For now I just handle the ichx and I assume there
-+ * are not a lot of resources up at the top of the address
-+ * space. It is possible to handle other devices in the
-+ * top 16MB but it is very painful. Also since
-+ * you can only really attach a FWH to an ICHX there
-+ * a number of simplifications you can make.
-+ *
-+ * Also you can page firmware hubs if an 8MB window isn't enough
-+ * but don't currently handle that case either.
-+ */
-+
-+ info->pdev = pdev;
-+
-+ /*
-+ * Try to reserve the window mem region. If this fails then
-+ * it is likely due to the window being "reseved" by the BIOS.
-+ */
-+ info->window_rsrc.name = MOD_NAME;
-+ info->window_rsrc.start = ICHX_FWH_REGION_START;
-+ info->window_rsrc.end = ICHX_FWH_REGION_START + ICHX_FWH_REGION_SIZE - 1;
-+ info->window_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-+ if (request_resource(&iomem_resource, &info->window_rsrc)) {
-+ info->window_rsrc.parent = NULL;
-+ printk(KERN_ERR MOD_NAME
-+ " %s(): Unable to register resource"
-+ " 0x%.08lx-0x%.08lx - kernel bug?\n",
-+ __func__,
-+ info->window_rsrc.start, info->window_rsrc.end);
-+ }
-+
-+ /* Enable writes through the rom window */
-+ pci_read_config_word(pdev, BIOS_CNTL, &word);
-+ if (!(word & 1) && (word & (1<<1))) {
-+ /* The BIOS will generate an error if I enable
-+ * this device, so don't even try.
-+ */
-+ printk(KERN_ERR MOD_NAME ": firmware access control, I can't enable writes\n");
-+ goto failed;
-+ }
-+ pci_write_config_word(pdev, BIOS_CNTL, word | 1);
-+
-+
-+ /* Map the firmware hub into my address space. */
-+ /* Does this use too much virtual address space? */
-+ info->window_addr = (unsigned long)ioremap(
-+ ICHX_FWH_REGION_START, ICHX_FWH_REGION_SIZE);
-+ if (!info->window_addr) {
-+ printk(KERN_ERR "Failed to ioremap\n");
-+ goto failed;
-+ }
-+
-+ /* For now assume the firmware has setup all relevant firmware
-+ * windows. We don't have enough information to handle this case
-+ * intelligently.
-+ */
-+
-+ /* FIXME select the firmware hub and enable a window to it. */
-+
-+ info->mtd = 0;
-+ info->map.map_priv_1 = info->window_addr;
-+
-+ map_size = ICHX_FWH_REGION_SIZE;
-+ while(!info->mtd && (map_size > 0)) {
-+ info->map.size = map_size;
-+ info->mtd = do_map_probe("jedec_probe", &ichxrom_map.map);
-+ map_size -= 512*1024;
-+ }
-+ if (!info->mtd) {
-+ goto failed;
-+ }
-+ /* I know I can only be a firmware hub here so put
-+ * in the special lock and unlock routines.
-+ */
-+ info->mtd->lock = ichxrom_lock;
-+ info->mtd->unlock = ichxrom_unlock;
-+
-+ info->mtd->owner = THIS_MODULE;
-+ add_mtd_device(info->mtd);
-+
-+ if (info->window_rsrc.parent) {
-+ /*
-+ * Registering the MTD device in iomem may not be possible
-+ * if there is a BIOS "reserved" and BUSY range. If this
-+ * fails then continue anyway.
-+ */
-+ snprintf(info->mtd_name, MTD_DEV_NAME_LENGTH,
-+ "mtd%d", info->mtd->index);
-+
-+ info->rom_rsrc.name = info->mtd_name;
-+ info->rom_rsrc.start = ICHX_FWH_REGION_START
-+ + ICHX_FWH_REGION_SIZE - map_size;
-+ info->rom_rsrc.end = ICHX_FWH_REGION_START
-+ + ICHX_FWH_REGION_SIZE;
-+ info->rom_rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-+ if (request_resource(&info->window_rsrc, &info->rom_rsrc)) {
-+ printk(KERN_ERR MOD_NAME
-+ ": cannot reserve MTD resource\n");
-+ info->rom_rsrc.parent = NULL;
-+ }
-+ }
-+
-+ return 0;
-+
-+ failed:
-+ ichxrom_cleanup(info);
-+ return -ENODEV;
-+}
-+
-+
-+static void __devexit ichxrom_remove_one (struct pci_dev *pdev)
-+{
-+ struct ichxrom_map_info *info = &ichxrom_map;
-+ u16 word;
-+
-+ del_mtd_device(info->mtd);
-+ map_destroy(info->mtd);
-+ info->mtd = 0;
-+ info->map.map_priv_1 = 0;
-+
-+ iounmap((void *)(info->window_addr));
-+ info->window_addr = 0;
-+
-+ /* Disable writes through the rom window */
-+ pci_read_config_word(pdev, BIOS_CNTL, &word);
-+ pci_write_config_word(pdev, BIOS_CNTL, word & ~1);
-+
-+#if RESERVE_MEM_REGION
-+ release_mem_region(ICHX_FWH_REGION_START, ICHX_FWH_REGION_SIZE);
-+#endif
-+}
-+
-+static struct pci_device_id ichxrom_pci_tbl[] __devinitdata = {
-+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0,
-+ PCI_ANY_ID, PCI_ANY_ID, },
-+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0,
-+ PCI_ANY_ID, PCI_ANY_ID, },
-+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0,
-+ PCI_ANY_ID, PCI_ANY_ID, },
-+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0,
-+ PCI_ANY_ID, PCI_ANY_ID, },
-+ { 0, },
-+};
-+
-+MODULE_DEVICE_TABLE(pci, ichxrom_pci_tbl);
-+
-+#if 0
-+static struct pci_driver ichxrom_driver = {
-+ .name = MOD_NAME,
-+ .id_table = ichxrom_pci_tbl,
-+ .probe = ichxrom_init_one,
-+ .remove = ichxrom_remove_one,
-+};
-+#endif
-+
-+static struct pci_dev *mydev;
-+int __init init_ichxrom(void)
-+{
-+ struct pci_dev *pdev;
-+ struct pci_device_id *id;
-+ pdev = 0;
-+ for(id = ichxrom_pci_tbl; id->vendor; id++) {
-+ pdev = pci_find_device(id->vendor, id->device, 0);
-+ if (pdev) {
-+ break;
-+ }
-+ }
-+ if (pdev) {
-+ mydev = pdev;
-+ return ichxrom_init_one(pdev, &ichxrom_pci_tbl[0]);
-+ }
-+ return -ENXIO;
-+#if 0
-+ return pci_module_init(&ichxrom_driver);
-+#endif
-+}
-+
-+static void __exit cleanup_ichxrom(void)
-+{
-+ ichxrom_remove_one(mydev);
-+}
-+
-+module_init(init_ichxrom);
-+module_exit(cleanup_ichxrom);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Eric Biederman <ebiederman@lnxi.com>");
-+MODULE_DESCRIPTION("MTD map driver for BIOS chips on the ICHX southbridge");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/impa7.c linux/drivers/mtd/maps/impa7.c
---- linux-mips-2.4.27/drivers/mtd/maps/impa7.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/maps/impa7.c 2004-11-19 10:25:11.920196600 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Handle mapping of the NOR flash on implementa A7 boards
- *
-@@ -13,6 +13,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -37,75 +38,17 @@
-
- static struct mtd_info *impa7_mtd[NUM_FLASHBANKS] = { 0 };
-
--__u8 impa7_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 impa7_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 impa7_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void impa7_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void impa7_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void impa7_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void impa7_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void impa7_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
-
- static struct map_info impa7_map[NUM_FLASHBANKS] = {
- {
-- name: "impA7 NOR Flash Bank #0",
-- size: WINDOW_SIZE0,
-- buswidth: BUSWIDTH,
-- read8: impa7_read8,
-- read16: impa7_read16,
-- read32: impa7_read32,
-- copy_from: impa7_copy_from,
-- write8: impa7_write8,
-- write16: impa7_write16,
-- write32: impa7_write32,
-- copy_to: impa7_copy_to
-+ .name = "impA7 NOR Flash Bank #0",
-+ .size = WINDOW_SIZE0,
-+ .buswidth = BUSWIDTH,
- },
- {
-- name: "impA7 NOR Flash Bank #1",
-- size: WINDOW_SIZE1,
-- buswidth: BUSWIDTH,
-- read8: impa7_read8,
-- read16: impa7_read16,
-- read32: impa7_read32,
-- copy_from: impa7_copy_from,
-- write8: impa7_write8,
-- write16: impa7_write16,
-- write32: impa7_write32,
-- copy_to: impa7_copy_to
-+ .name = "impA7 NOR Flash Bank #1",
-+ .size = WINDOW_SIZE1,
-+ .buswidth = BUSWIDTH,
- },
- };
-
-@@ -117,24 +60,18 @@
- static struct mtd_partition static_partitions[] =
- {
- {
-- name: "FileSystem",
-- size: 0x800000,
-- offset: 0x00000000
-+ .name = "FileSystem",
-+ .size = 0x800000,
-+ .offset = 0x00000000
- },
- };
-
--#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
-+static int mtd_parts_nb[NUM_FLASHBANKS];
-+static struct mtd_partition *mtd_parts[NUM_FLASHBANKS];
-
--#ifdef CONFIG_MTD_CMDLINE_PARTS
--int parse_cmdline_partitions(struct mtd_info *master,
-- struct mtd_partition **pparts,
-- const char *mtd_id);
- #endif
-
--#endif
--
--static int mtd_parts_nb = 0;
--static struct mtd_partition *mtd_parts = 0;
-+static const char *probes[] = { "cmdlinepart", NULL };
-
- int __init init_impa7(void)
- {
-@@ -146,20 +83,21 @@
- { WINDOW_ADDR0, WINDOW_SIZE0 },
- { WINDOW_ADDR1, WINDOW_SIZE1 },
- };
-- char mtdid[10];
- int devicesfound = 0;
-
- for(i=0; i<NUM_FLASHBANKS; i++)
- {
- printk(KERN_NOTICE MSG_PREFIX "probing 0x%08lx at 0x%08lx\n",
- pt[i].size, pt[i].addr);
-- impa7_map[i].map_priv_1 = (unsigned long)
-- ioremap(pt[i].addr, pt[i].size);
-
-- if (!impa7_map[i].map_priv_1) {
-+ impa7_map[i].phys = pt[i].addr;
-+ impa7_map[i].virt = (unsigned long)
-+ ioremap(pt[i].addr, pt[i].size);
-+ if (!impa7_map[i].virt) {
- printk(MSG_PREFIX "failed to ioremap\n");
- return -EIO;
- }
-+ simple_map_init(&impa7_map[i]);
-
- impa7_mtd[i] = 0;
- type = rom_probe_types;
-@@ -167,43 +105,34 @@
- impa7_mtd[i] = do_map_probe(*type, &impa7_map[i]);
- }
-
-- if (impa7_mtd[i])
-- {
-- impa7_mtd[i]->module = THIS_MODULE;
-- add_mtd_device(impa7_mtd[i]);
-+ if (impa7_mtd[i]) {
-+ impa7_mtd[i]->owner = THIS_MODULE;
- devicesfound++;
- #ifdef CONFIG_MTD_PARTITIONS
--#ifdef CONFIG_MTD_CMDLINE_PARTS
-- sprintf(mtdid, MTDID, i);
-- mtd_parts_nb = parse_cmdline_partitions(impa7_mtd[i],
-- &mtd_parts,
-- mtdid);
-- if (mtd_parts_nb > 0)
-+ mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i],
-+ probes,
-+ &mtd_parts[i],
-+ 0);
-+ if (mtd_parts_nb[i] > 0) {
- part_type = "command line";
--#endif
-- if (mtd_parts_nb <= 0)
-- {
-- mtd_parts = static_partitions;
-- mtd_parts_nb = NB_OF(static_partitions);
-+ } else {
-+ mtd_parts[i] = static_partitions;
-+ mtd_parts_nb[i] = ARRAY_SIZE(static_partitions);
- part_type = "static";
- }
-- if (mtd_parts_nb <= 0)
-- {
-- printk(KERN_NOTICE MSG_PREFIX
-- "no partition info available\n");
-- }
-- else
-- {
-+
- printk(KERN_NOTICE MSG_PREFIX
- "using %s partition definition\n",
- part_type);
- add_mtd_partitions(impa7_mtd[i],
-- mtd_parts, mtd_parts_nb);
-- }
-+ mtd_parts[i], mtd_parts_nb[i]);
-+#else
-+ add_mtd_device(impa7_mtd[i]);
-+
- #endif
- }
- else
-- iounmap((void *)impa7_map[i].map_priv_1);
-+ iounmap((void *)impa7_map[i].virt);
- }
- return devicesfound == 0 ? -ENXIO : 0;
- }
-@@ -211,17 +140,16 @@
- static void __exit cleanup_impa7(void)
- {
- int i;
-- for (i=0; i<NUM_FLASHBANKS; i++)
-- {
-- if (impa7_mtd[i])
-- {
-+ for (i=0; i<NUM_FLASHBANKS; i++) {
-+ if (impa7_mtd[i]) {
-+#ifdef CONFIG_MTD_PARTITIONS
-+ del_mtd_partitions(impa7_mtd[i]);
-+#else
- del_mtd_device(impa7_mtd[i]);
-+#endif
- map_destroy(impa7_mtd[i]);
-- }
-- if (impa7_map[i].map_priv_1)
-- {
-- iounmap((void *)impa7_map[i].map_priv_1);
-- impa7_map[i].map_priv_1 = 0;
-+ iounmap((void *)impa7_map[i].virt);
-+ impa7_map[i].virt = 0;
- }
- }
- }
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/integrator-flash-v24.c linux/drivers/mtd/maps/integrator-flash-v24.c
---- linux-mips-2.4.27/drivers/mtd/maps/integrator-flash-v24.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/integrator-flash-v24.c 2004-11-19 10:25:11.921196448 +0100
-@@ -0,0 +1,258 @@
-+/*======================================================================
-+
-+ drivers/mtd/maps/armflash.c: ARM Flash Layout/Partitioning
-+
-+ Copyright (C) 2000 ARM Limited
-+
-+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+
-+ This is access code for flashes using ARM's flash partitioning
-+ standards.
-+
-+ $Id$
-+
-+======================================================================*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/ioport.h>
-+#include <linux/init.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/system.h>
-+
-+// board specific stuff - sorry, it should be in arch/arm/mach-*.
-+#ifdef CONFIG_ARCH_INTEGRATOR
-+
-+#define FLASH_BASE INTEGRATOR_FLASH_BASE
-+#define FLASH_SIZE INTEGRATOR_FLASH_SIZE
-+
-+#define FLASH_PART_SIZE 0x400000
-+
-+#define SC_CTRLC (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
-+#define SC_CTRLS (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
-+#define EBI_CSR1 (IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_CSR1_OFFSET)
-+#define EBI_LOCK (IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_LOCK_OFFSET)
-+
-+/*
-+ * Initialise the flash access systems:
-+ * - Disable VPP
-+ * - Assert WP
-+ * - Set write enable bit in EBI reg
-+ */
-+static void armflash_flash_init(void)
-+{
-+ unsigned int tmp;
-+
-+ __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
-+
-+ tmp = __raw_readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE;
-+ __raw_writel(tmp, EBI_CSR1);
-+
-+ if (!(__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) {
-+ __raw_writel(0xa05f, EBI_LOCK);
-+ __raw_writel(tmp, EBI_CSR1);
-+ __raw_writel(0, EBI_LOCK);
-+ }
-+}
-+
-+/*
-+ * Shutdown the flash access systems:
-+ * - Disable VPP
-+ * - Assert WP
-+ * - Clear write enable bit in EBI reg
-+ */
-+static void armflash_flash_exit(void)
-+{
-+ unsigned int tmp;
-+
-+ __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
-+
-+ /*
-+ * Clear the write enable bit in system controller EBI register.
-+ */
-+ tmp = __raw_readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE;
-+ __raw_writel(tmp, EBI_CSR1);
-+
-+ if (__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) {
-+ __raw_writel(0xa05f, EBI_LOCK);
-+ __raw_writel(tmp, EBI_CSR1);
-+ __raw_writel(0, EBI_LOCK);
-+ }
-+}
-+
-+static void armflash_flash_wp(int on)
-+{
-+ unsigned int reg;
-+
-+ if (on)
-+ reg = SC_CTRLC;
-+ else
-+ reg = SC_CTRLS;
-+
-+ __raw_writel(INTEGRATOR_SC_CTRL_nFLWP, reg);
-+}
-+
-+static void armflash_set_vpp(struct map_info *map, int on)
-+{
-+ unsigned int reg;
-+
-+ if (on)
-+ reg = SC_CTRLS;
-+ else
-+ reg = SC_CTRLC;
-+
-+ __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg);
-+}
-+#endif
-+
-+#ifdef CONFIG_ARCH_P720T
-+
-+#define FLASH_BASE (0x04000000)
-+#define FLASH_SIZE (64*1024*1024)
-+
-+#define FLASH_PART_SIZE (4*1024*1024)
-+#define FLASH_BLOCK_SIZE (128*1024)
-+
-+static void armflash_flash_init(void)
-+{
-+}
-+
-+static void armflash_flash_exit(void)
-+{
-+}
-+
-+static void armflash_flash_wp(int on)
-+{
-+}
-+
-+static void armflash_set_vpp(struct map_info *map, int on)
-+{
-+}
-+#endif
-+
-+
-+static struct map_info armflash_map =
-+{
-+ .name = "AFS",
-+ .set_vpp = armflash_set_vpp,
-+ .phys = FLASH_BASE,
-+};
-+
-+static struct mtd_info *mtd;
-+static struct mtd_partition *parts;
-+static const char *probes[] = { "RedBoot", "afs", NULL };
-+
-+static int __init armflash_cfi_init(void *base, u_int size)
-+{
-+ int ret;
-+
-+ armflash_flash_init();
-+ armflash_flash_wp(1);
-+
-+ /*
-+ * look for CFI based flash parts fitted to this board
-+ */
-+ armflash_map.size = size;
-+ armflash_map.buswidth = 4;
-+ armflash_map.virt = (unsigned long) base;
-+
-+ simple_map_init(&armflash_map);
-+
-+ /*
-+ * Also, the CFI layer automatically works out what size
-+ * of chips we have, and does the necessary identification
-+ * for us automatically.
-+ */
-+ mtd = do_map_probe("cfi_probe", &armflash_map);
-+ if (!mtd)
-+ return -ENXIO;
-+
-+ mtd->owner = THIS_MODULE;
-+
-+ ret = parse_mtd_partitions(mtd, probes, &parts, (void *)0);
-+ if (ret > 0) {
-+ ret = add_mtd_partitions(mtd, parts, ret);
-+ if (ret)
-+ printk(KERN_ERR "mtd partition registration "
-+ "failed: %d\n", ret);
-+ }
-+
-+ /*
-+ * If we got an error, free all resources.
-+ */
-+ if (ret < 0) {
-+ del_mtd_partitions(mtd);
-+ map_destroy(mtd);
-+ }
-+
-+ return ret;
-+}
-+
-+static void armflash_cfi_exit(void)
-+{
-+ if (mtd) {
-+ del_mtd_partitions(mtd);
-+ map_destroy(mtd);
-+ }
-+ if (parts)
-+ kfree(parts);
-+}
-+
-+static int __init armflash_init(void)
-+{
-+ int err = -EBUSY;
-+ void *base;
-+
-+ if (request_mem_region(FLASH_BASE, FLASH_SIZE, "flash") == NULL)
-+ goto out;
-+
-+ base = ioremap(FLASH_BASE, FLASH_SIZE);
-+ err = -ENOMEM;
-+ if (base == NULL)
-+ goto release;
-+
-+ err = armflash_cfi_init(base, FLASH_SIZE);
-+ if (err) {
-+ iounmap(base);
-+release:
-+ release_mem_region(FLASH_BASE, FLASH_SIZE);
-+ }
-+out:
-+ return err;
-+}
-+
-+static void __exit armflash_exit(void)
-+{
-+ armflash_cfi_exit();
-+ iounmap((void *)armflash_map.virt);
-+ release_mem_region(FLASH_BASE, FLASH_SIZE);
-+ armflash_flash_exit();
-+}
-+
-+module_init(armflash_init);
-+module_exit(armflash_exit);
-+
-+MODULE_AUTHOR("ARM Ltd");
-+MODULE_DESCRIPTION("ARM Integrator CFI map driver");
-+MODULE_LICENSE("GPL");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/integrator-flash.c linux/drivers/mtd/maps/integrator-flash.c
---- linux-mips-2.4.27/drivers/mtd/maps/integrator-flash.c 2002-06-27 00:35:50.000000000 +0200
-+++ linux/drivers/mtd/maps/integrator-flash.c 2004-11-19 10:25:11.923196144 +0100
-@@ -1,8 +1,9 @@
- /*======================================================================
-
-- drivers/mtd/maps/armflash.c: ARM Flash Layout/Partitioning
-+ drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver
-
- Copyright (C) 2000 ARM Limited
-+ Copyright (C) 2003 Deep Blue Solutions Ltd.
-
- 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
-@@ -21,7 +22,7 @@
- This is access code for flashes using ARM's flash partitioning
- standards.
-
-- $Id$
-+ $Id$
-
- ======================================================================*/
-
-@@ -31,268 +32,181 @@
- #include <linux/kernel.h>
- #include <linux/slab.h>
- #include <linux/ioport.h>
-+#include <linux/device.h>
- #include <linux/init.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/partitions.h>
-
-+#include <asm/mach/flash.h>
- #include <asm/hardware.h>
- #include <asm/io.h>
- #include <asm/system.h>
-
--extern int parse_afs_partitions(struct mtd_info *, struct mtd_partition **);
--
--// board specific stuff - sorry, it should be in arch/arm/mach-*.
--#ifdef CONFIG_ARCH_INTEGRATOR
--
--#define FLASH_BASE INTEGRATOR_FLASH_BASE
--#define FLASH_SIZE INTEGRATOR_FLASH_SIZE
--
--#define FLASH_PART_SIZE 0x400000
--
--#define SC_CTRLC (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
--#define SC_CTRLS (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
--#define EBI_CSR1 (IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_CSR1_OFFSET)
--#define EBI_LOCK (IO_ADDRESS(INTEGRATOR_EBI_BASE) + INTEGRATOR_EBI_LOCK_OFFSET)
--
--/*
-- * Initialise the flash access systems:
-- * - Disable VPP
-- * - Assert WP
-- * - Set write enable bit in EBI reg
-- */
--static void armflash_flash_init(void)
--{
-- unsigned int tmp;
--
-- __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
--
-- tmp = __raw_readl(EBI_CSR1) | INTEGRATOR_EBI_WRITE_ENABLE;
-- __raw_writel(tmp, EBI_CSR1);
--
-- if (!(__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE)) {
-- __raw_writel(0xa05f, EBI_LOCK);
-- __raw_writel(tmp, EBI_CSR1);
-- __raw_writel(0, EBI_LOCK);
-- }
--}
--
--/*
-- * Shutdown the flash access systems:
-- * - Disable VPP
-- * - Assert WP
-- * - Clear write enable bit in EBI reg
-- */
--static void armflash_flash_exit(void)
--{
-- unsigned int tmp;
--
-- __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN | INTEGRATOR_SC_CTRL_nFLWP, SC_CTRLC);
--
-- /*
-- * Clear the write enable bit in system controller EBI register.
-- */
-- tmp = __raw_readl(EBI_CSR1) & ~INTEGRATOR_EBI_WRITE_ENABLE;
-- __raw_writel(tmp, EBI_CSR1);
--
-- if (__raw_readl(EBI_CSR1) & INTEGRATOR_EBI_WRITE_ENABLE) {
-- __raw_writel(0xa05f, EBI_LOCK);
-- __raw_writel(tmp, EBI_CSR1);
-- __raw_writel(0, EBI_LOCK);
-- }
--}
--
--static void armflash_flash_wp(int on)
--{
-- unsigned int reg;
--
-- if (on)
-- reg = SC_CTRLC;
-- else
-- reg = SC_CTRLS;
--
-- __raw_writel(INTEGRATOR_SC_CTRL_nFLWP, reg);
--}
--
--static void armflash_set_vpp(struct map_info *map, int on)
--{
-- unsigned int reg;
--
-- if (on)
-- reg = SC_CTRLS;
-- else
-- reg = SC_CTRLC;
--
-- __raw_writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg);
--}
--#endif
--
- #ifdef CONFIG_ARCH_P720T
--
- #define FLASH_BASE (0x04000000)
- #define FLASH_SIZE (64*1024*1024)
--
--#define FLASH_PART_SIZE (4*1024*1024)
--#define FLASH_BLOCK_SIZE (128*1024)
--
--static void armflash_flash_init(void)
--{
--}
--
--static void armflash_flash_exit(void)
--{
--}
--
--static void armflash_flash_wp(int on)
--{
--}
--
--static void armflash_set_vpp(struct map_info *map, int on)
--{
--}
- #endif
-
--static __u8 armflash_read8(struct map_info *map, unsigned long ofs)
--{
-- return readb(ofs + map->map_priv_2);
--}
--
--static __u16 armflash_read16(struct map_info *map, unsigned long ofs)
--{
-- return readw(ofs + map->map_priv_2);
--}
-+struct armflash_info {
-+ struct flash_platform_data *plat;
-+ struct resource *res;
-+ struct mtd_partition *parts;
-+ struct mtd_info *mtd;
-+ struct map_info map;
-+};
-
--static __u32 armflash_read32(struct map_info *map, unsigned long ofs)
-+static void armflash_set_vpp(struct map_info *map, int on)
- {
-- return readl(ofs + map->map_priv_2);
--}
-+ struct armflash_info *info = container_of(map, struct armflash_info, map);
-
--static void armflash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy(to, (void *) (from + map->map_priv_2), len);
-+ if (info->plat && info->plat->set_vpp)
-+ info->plat->set_vpp(on);
- }
-
--static void armflash_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- writeb(d, adr + map->map_priv_2);
--}
--
--static void armflash_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- writew(d, adr + map->map_priv_2);
--}
-+static const char *probes[] = { "RedBoot", "afs", NULL };
-
--static void armflash_write32(struct map_info *map, __u32 d, unsigned long adr)
-+static int armflash_probe(struct device *_dev)
- {
-- writel(d, adr + map->map_priv_2);
--}
-+ struct platform_device *dev = to_platform_device(_dev);
-+ struct flash_platform_data *plat = dev->dev.platform_data;
-+ struct resource *res = dev->resource;
-+ unsigned int size = res->end - res->start + 1;
-+ struct armflash_info *info;
-+ int err;
-+ void *base;
-
--static void armflash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy((void *) (to + map->map_priv_2), from, len);
--}
-+ info = kmalloc(sizeof(struct armflash_info), GFP_KERNEL);
-+ if (!info) {
-+ err = -ENOMEM;
-+ goto out;
-+ }
-
--static struct map_info armflash_map =
--{
-- name: "AFS",
-- read8: armflash_read8,
-- read16: armflash_read16,
-- read32: armflash_read32,
-- copy_from: armflash_copy_from,
-- write8: armflash_write8,
-- write16: armflash_write16,
-- write32: armflash_write32,
-- copy_to: armflash_copy_to,
-- set_vpp: armflash_set_vpp,
--};
-+ memset(info, 0, sizeof(struct armflash_info));
-
--static struct mtd_info *mtd;
--static struct mtd_partition *parts;
-+ info->plat = plat;
-+ if (plat && plat->init) {
-+ err = plat->init();
-+ if (err)
-+ goto no_resource;
-+ }
-
--static int __init armflash_cfi_init(void *base, u_int size)
--{
-- int ret;
-+ info->res = request_mem_region(res->start, size, "armflash");
-+ if (!info->res) {
-+ err = -EBUSY;
-+ goto no_resource;
-+ }
-
-- armflash_flash_init();
-- armflash_flash_wp(1);
-+ base = ioremap(res->start, size);
-+ if (!base) {
-+ err = -ENOMEM;
-+ goto no_mem;
-+ }
-
- /*
- * look for CFI based flash parts fitted to this board
- */
-- armflash_map.size = size;
-- armflash_map.buswidth = 4;
-- armflash_map.map_priv_2 = (unsigned long) base;
-+ info->map.size = size;
-+ info->map.buswidth = plat->width;
-+ info->map.phys = res->start;
-+ info->map.virt = (unsigned long) base;
-+ info->map.name = dev->dev.bus_id;
-+ info->map.set_vpp = armflash_set_vpp;
-+
-+ simple_map_init(&info->map);
-
- /*
- * Also, the CFI layer automatically works out what size
- * of chips we have, and does the necessary identification
- * for us automatically.
- */
-- mtd = do_map_probe("cfi_probe", &armflash_map);
-- if (!mtd)
-- return -ENXIO;
--
-- mtd->module = THIS_MODULE;
--
-- ret = parse_afs_partitions(mtd, &parts);
-- if (ret > 0) {
-- ret = add_mtd_partitions(mtd, parts, ret);
-- if (ret)
-- printk(KERN_ERR "mtd partition registration "
-- "failed: %d\n", ret);
-+ info->mtd = do_map_probe(plat->map_name, &info->map);
-+ if (!info->mtd) {
-+ err = -ENXIO;
-+ goto no_device;
- }
-
-+ info->mtd->owner = THIS_MODULE;
-+
-+ err = parse_mtd_partitions(info->mtd, probes, &info->parts, 0);
-+ if (err > 0) {
-+ err = add_mtd_partitions(info->mtd, info->parts, err);
-+ if (err)
-+ printk(KERN_ERR
-+ "mtd partition registration failed: %d\n", err);
-+ }
-+
-+ if (err == 0)
-+ dev_set_drvdata(&dev->dev, info);
-+
- /*
- * If we got an error, free all resources.
- */
-- if (ret < 0) {
-- del_mtd_partitions(mtd);
-- map_destroy(mtd);
-+ if (err < 0) {
-+ if (info->mtd) {
-+ del_mtd_partitions(info->mtd);
-+ map_destroy(info->mtd);
- }
-+ if (info->parts)
-+ kfree(info->parts);
-
-- return ret;
--}
--
--static void armflash_cfi_exit(void)
--{
-- if (mtd) {
-- del_mtd_partitions(mtd);
-- map_destroy(mtd);
-+ no_device:
-+ iounmap(base);
-+ no_mem:
-+ release_mem_region(res->start, size);
-+ no_resource:
-+ if (plat && plat->exit)
-+ plat->exit();
-+ kfree(info);
- }
-- if (parts)
-- kfree(parts);
-+ out:
-+ return err;
- }
-
--static int __init armflash_init(void)
-+static int armflash_remove(struct device *_dev)
- {
-- int err = -EBUSY;
-- void *base;
-+ struct platform_device *dev = to_platform_device(_dev);
-+ struct armflash_info *info = dev_get_drvdata(&dev->dev);
-
-- if (request_mem_region(FLASH_BASE, FLASH_SIZE, "flash") == NULL)
-- goto out;
-+ dev_set_drvdata(&dev->dev, NULL);
-
-- base = ioremap(FLASH_BASE, FLASH_SIZE);
-- err = -ENOMEM;
-- if (base == NULL)
-- goto release;
-+ if (info) {
-+ if (info->mtd) {
-+ del_mtd_partitions(info->mtd);
-+ map_destroy(info->mtd);
-+ }
-+ if (info->parts)
-+ kfree(info->parts);
-
-- err = armflash_cfi_init(base, FLASH_SIZE);
-- if (err) {
-- iounmap(base);
--release:
-- release_mem_region(FLASH_BASE, FLASH_SIZE);
-+ iounmap((void *)info->map.virt);
-+ release_resource(info->res);
-+ kfree(info->res);
-+
-+ if (info->plat && info->plat->exit)
-+ info->plat->exit();
-+
-+ kfree(info);
- }
--out:
-- return err;
-+
-+ return 0;
-+}
-+
-+static struct device_driver armflash_driver = {
-+ .name = "armflash",
-+ .bus = &platform_bus_type,
-+ .probe = armflash_probe,
-+ .remove = armflash_remove,
-+};
-+
-+static int __init armflash_init(void)
-+{
-+ return driver_register(&armflash_driver);
- }
-
- static void __exit armflash_exit(void)
- {
-- armflash_cfi_exit();
-- iounmap((void *)armflash_map.map_priv_2);
-- release_mem_region(FLASH_BASE, FLASH_SIZE);
-- armflash_flash_exit();
-+ driver_unregister(&armflash_driver);
- }
-
- module_init(armflash_init);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/iq80310.c linux/drivers/mtd/maps/iq80310.c
---- linux-mips-2.4.27/drivers/mtd/maps/iq80310.c 2002-06-27 00:35:50.000000000 +0200
-+++ linux/drivers/mtd/maps/iq80310.c 2004-11-19 10:25:11.924195992 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Mapping for the Intel XScale IQ80310 evaluation board
- *
-@@ -14,6 +14,8 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -26,127 +28,72 @@
-
- static struct mtd_info *mymtd;
-
--static __u8 iq80310_read8(struct map_info *map, unsigned long ofs)
--{
-- return *(__u8 *)(map->map_priv_1 + ofs);
--}
--
--static __u16 iq80310_read16(struct map_info *map, unsigned long ofs)
--{
-- return *(__u16 *)(map->map_priv_1 + ofs);
--}
--
--static __u32 iq80310_read32(struct map_info *map, unsigned long ofs)
--{
-- return *(__u32 *)(map->map_priv_1 + ofs);
--}
--
--static void iq80310_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy(to, (void *)(map->map_priv_1 + from), len);
--}
--
--static void iq80310_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- *(__u8 *)(map->map_priv_1 + adr) = d;
--}
--
--static void iq80310_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- *(__u16 *)(map->map_priv_1 + adr) = d;
--}
--
--static void iq80310_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- *(__u32 *)(map->map_priv_1 + adr) = d;
--}
--
--static void iq80310_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy((void *)(map->map_priv_1 + to), from, len);
--}
--
- static struct map_info iq80310_map = {
-- name: "IQ80310 flash",
-- size: WINDOW_SIZE,
-- buswidth: BUSWIDTH,
-- read8: iq80310_read8,
-- read16: iq80310_read16,
-- read32: iq80310_read32,
-- copy_from: iq80310_copy_from,
-- write8: iq80310_write8,
-- write16: iq80310_write16,
-- write32: iq80310_write32,
-- copy_to: iq80310_copy_to
-+ .name = "IQ80310 flash",
-+ .size = WINDOW_SIZE,
-+ .buswidth = BUSWIDTH,
-+ .phys = WINDOW_ADDR
- };
-
- static struct mtd_partition iq80310_partitions[4] = {
- {
-- name: "Firmware",
-- size: 0x00080000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE /* force read-only */
-+ .name = "Firmware",
-+ .size = 0x00080000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
- },{
-- name: "Kernel",
-- size: 0x000a0000,
-- offset: 0x00080000,
-+ .name = "Kernel",
-+ .size = 0x000a0000,
-+ .offset = 0x00080000,
- },{
-- name: "Filesystem",
-- size: 0x00600000,
-- offset: 0x00120000
-+ .name = "Filesystem",
-+ .size = 0x00600000,
-+ .offset = 0x00120000
- },{
-- name: "RedBoot",
-- size: 0x000e0000,
-- offset: 0x00720000,
-- mask_flags: MTD_WRITEABLE
-+ .name = "RedBoot",
-+ .size = 0x000e0000,
-+ .offset = 0x00720000,
-+ .mask_flags = MTD_WRITEABLE
- }
- };
-
--#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
--
- static struct mtd_info *mymtd;
- static struct mtd_partition *parsed_parts;
--
--extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
-+static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-
- static int __init init_iq80310(void)
- {
- struct mtd_partition *parts;
- int nb_parts = 0;
- int parsed_nr_parts = 0;
-- char *part_type = "static";
-+ int ret;
-
-- iq80310_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-- if (!iq80310_map.map_priv_1) {
-+ iq80310_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-+ if (!iq80310_map.virt) {
- printk("Failed to ioremap\n");
- return -EIO;
- }
-+ simple_map_init(&iq80310_map);
-+
- mymtd = do_map_probe("cfi_probe", &iq80310_map);
- if (!mymtd) {
-- iounmap((void *)iq80310_map.map_priv_1);
-+ iounmap((void *)iq80310_map.virt);
- return -ENXIO;
- }
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
--#ifdef CONFIG_MTD_REDBOOT_PARTS
-- if (parsed_nr_parts == 0) {
-- int ret = parse_redboot_partitions(mymtd, &parsed_parts);
-+ ret = parse_mtd_partitions(mymtd, probes, &parsed_parts, 0);
-
-- if (ret > 0) {
-- part_type = "RedBoot";
-+ if (ret > 0)
- parsed_nr_parts = ret;
-- }
-- }
--#endif
-
- if (parsed_nr_parts > 0) {
- parts = parsed_parts;
- nb_parts = parsed_nr_parts;
- } else {
- parts = iq80310_partitions;
-- nb_parts = NB_OF(iq80310_partitions);
-+ nb_parts = ARRAY_SIZE(iq80310_partitions);
- }
-- printk(KERN_NOTICE "Using %s partition definition\n", part_type);
- add_mtd_partitions(mymtd, parts, nb_parts);
- return 0;
- }
-@@ -159,8 +106,8 @@
- if (parsed_parts)
- kfree(parsed_parts);
- }
-- if (iq80310_map.map_priv_1)
-- iounmap((void *)iq80310_map.map_priv_1);
-+ if (iq80310_map.virt)
-+ iounmap((void *)iq80310_map.virt);
- }
-
- module_init(init_iq80310);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/ixp425.c linux/drivers/mtd/maps/ixp425.c
---- linux-mips-2.4.27/drivers/mtd/maps/ixp425.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/ixp425.c 2004-11-19 10:25:11.925195840 +0100
-@@ -0,0 +1,220 @@
-+/*
-+ * $Id$
-+ *
-+ * drivers/mtd/maps/ixp425.c
-+ *
-+ * MTD Map file for IXP425 based systems. Please do not make per-board
-+ * map driver as the code will be 90% identical. For now just add
-+ * if(machine_is_XXX()) checks to the code. I'll clean this stuff to
-+ * use platform_data in the the future so we can get rid of that too.
-+ *
-+ * Original Author: Intel Corporation
-+ * Maintainer: Deepak Saxena <dsaxena@mvista.com>
-+ *
-+ * Copyright (C) 2002 Intel Corporation
-+ * Copyright (C) 2003 MontaVista Software, Inc.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/string.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/ioport.h>
-+#include <asm/io.h>
-+#include <asm/mach-types.h>
-+
-+#include <linux/reboot.h>
-+
-+#define WINDOW_ADDR 0x50000000
-+#define BUSWIDTH 2
-+
-+#ifndef __ARMEB__
-+#define BYTE0(h) ((h) & 0xFF)
-+#define BYTE1(h) (((h) >> 8) & 0xFF)
-+#else
-+#define BYTE0(h) (((h) >> 8) & 0xFF)
-+#define BYTE1(h) ((h) & 0xFF)
-+#endif
-+
-+static __u16
-+ixp425_read16(struct map_info *map, unsigned long ofs)
-+{
-+ return *(__u16 *) (map->map_priv_1 + ofs);
-+}
-+
-+/*
-+ * The IXP425 expansion bus only allows 16-bit wide acceses
-+ * when attached to a 16-bit wide device (such as the 28F128J3A),
-+ * so we can't just memcpy_fromio().
-+ */
-+static void
-+ixp425_copy_from(struct map_info *map, void *to,
-+ unsigned long from, ssize_t len)
-+{
-+ int i;
-+ u8 *dest = (u8 *) to;
-+ u16 *src = (u16 *) (map->map_priv_1 + from);
-+ u16 data;
-+
-+ for (i = 0; i < (len / 2); i++) {
-+ data = src[i];
-+ dest[i * 2] = BYTE0(data);
-+ dest[i * 2 + 1] = BYTE1(data);
-+ }
-+
-+ if (len & 1)
-+ dest[len - 1] = BYTE0(src[i]);
-+}
-+
-+static void
-+ixp425_write16(struct map_info *map, __u16 d, unsigned long adr)
-+{
-+ *(__u16 *) (map->map_priv_1 + adr) = d;
-+}
-+
-+static struct map_info ixp425_map = {
-+ .name = "IXP425 Flash",
-+ .buswidth = BUSWIDTH,
-+ .read16 = ixp425_read16,
-+ .copy_from = ixp425_copy_from,
-+ .write16 = ixp425_write16,
-+};
-+
-+/*
-+ * Put flash back in read mode so RedBoot can boot properly.
-+ */
-+int ixp425_mtd_reboot(struct notifier_block *n, unsigned long code, void *p)
-+{
-+ if (code != SYS_RESTART)
-+ return NOTIFY_DONE;
-+
-+ ixp425_write16(&ixp425_map, 0xff, 0x55 * 0x2);
-+ return NOTIFY_DONE;
-+}
-+
-+static struct notifier_block ixp425_mtd_notifier = {
-+ notifier_call:ixp425_mtd_reboot,
-+ next:NULL,
-+ priority:0
-+};
-+
-+static struct mtd_partition *parsed_parts;
-+static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-+
-+static struct mtd_partition ixp425_partitions[] = {
-+ {
-+ .name = "image",
-+ .offset = 0x00040000,
-+ .size = 0x00400000,
-+ }, {
-+ .name = "user",
-+ .offset = 0x00440000,
-+ .size = MTDPART_SIZ_FULL
-+ }
-+};
-+
-+#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
-+
-+static struct mtd_info *ixp425_mtd;
-+static struct resource *mtd_resource;
-+
-+static void
-+ixp425_exit(void)
-+{
-+ if (ixp425_mtd) {
-+ del_mtd_partitions(ixp425_mtd);
-+ map_destroy(ixp425_mtd);
-+ }
-+ if (ixp425_map.map_priv_1)
-+ iounmap((void *) ixp425_map.map_priv_1);
-+ if (mtd_resource)
-+ release_mem_region(WINDOW_ADDR, ixp425_map.size);
-+
-+ if (parsed_parts)
-+ kfree(parsed_parts);
-+
-+ unregister_reboot_notifier(&ixp425_mtd_notifier);
-+
-+ /* Disable flash write */
-+ *IXP425_EXP_CS0 &= ~IXP425_FLASH_WRITABLE;
-+
-+ if(machine_is_adi_coyote())
-+ *IXP425_EXP_CS1 &= ~IXP425_FLASH_WRITABLE;
-+}
-+
-+static int __init
-+ixp425_init(void)
-+{
-+ int res = -1, npart;
-+
-+ /* Enable flash write */
-+ *IXP425_EXP_CS0 |= IXP425_FLASH_WRITABLE;
-+
-+ /*
-+ * Coyote requires CS1 write to be enabled and has 32MB flash.
-+ * This will move to the platform init code in 2.6
-+ */
-+ if(machine_is_adi_coyote()) {
-+ *IXP425_EXP_CS1 |= IXP425_FLASH_WRITABLE;
-+ ixp425_map.size = 0x02000000;
-+ } else
-+ ixp425_map.size = 0x01000000;
-+
-+ ixp425_map.map_priv_1 = 0;
-+ mtd_resource =
-+ request_mem_region(WINDOW_ADDR, ixp425_map.size, "IXP425 Flash");
-+ if (!mtd_resource) {
-+ printk(KERN_ERR
-+ "ixp425 flash: Could not request mem region.\n");
-+ res = -ENOMEM;
-+ goto Error;
-+ }
-+
-+ ixp425_map.map_priv_1 =
-+ (unsigned long) ioremap(WINDOW_ADDR, ixp425_map.size);
-+ if (!ixp425_map.map_priv_1) {
-+ printk("ixp425 Flash: Failed to map IO region. (ioremap)\n");
-+ res = -EIO;
-+ goto Error;
-+ }
-+
-+ ixp425_mtd = do_map_probe("cfi_probe", &ixp425_map);
-+ if (!ixp425_mtd) {
-+ res = -ENXIO;
-+ goto Error;
-+ }
-+ ixp425_mtd->owner = THIS_MODULE;
-+
-+ /* Try to parse RedBoot partitions */
-+ npart = parse_mtd_partitions(ixp425_mtd, probes, &parsed_parts, 0);
-+ if (npart > 0)
-+ res = add_mtd_partitions(ixp425_mtd, parsed_parts, npart);
-+ else {
-+ printk("IXP425 Flash: Using static MTD partitions.\n");
-+ res = add_mtd_partitions(ixp425_mtd, ixp425_partitions,
-+ NB_OF(ixp425_partitions));
-+ }
-+
-+ if (res)
-+ goto Error;
-+
-+ register_reboot_notifier(&ixp425_mtd_notifier);
-+
-+ return res;
-+
-+Error:
-+ ixp425_exit();
-+ return res;
-+}
-+
-+module_init(ixp425_init);
-+module_exit(ixp425_exit);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("MTD map driver for ixp425 evaluation board");
-+MODULE_AUTHOR("Deepak Saxena");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/l440gx.c linux/drivers/mtd/maps/l440gx.c
---- linux-mips-2.4.27/drivers/mtd/maps/l440gx.c 2002-06-27 00:35:50.000000000 +0200
-+++ linux/drivers/mtd/maps/l440gx.c 2004-11-19 10:25:11.927195536 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * BIOS Flash chip on Intel 440GX board.
- *
-@@ -9,6 +9,7 @@
- #include <linux/module.h>
- #include <linux/pci.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -27,48 +28,6 @@
-
- static struct mtd_info *mymtd;
-
--__u8 l440gx_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 l440gx_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 l440gx_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void l440gx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void l440gx_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void l440gx_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void l440gx_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void l440gx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
-
- /* Is this really the vpp port? */
- void l440gx_set_vpp(struct map_info *map, int vpp)
-@@ -85,22 +44,15 @@
- }
-
- struct map_info l440gx_map = {
-- name: "L440GX BIOS",
-- size: WINDOW_SIZE,
-- buswidth: BUSWIDTH,
-- read8: l440gx_read8,
-- read16: l440gx_read16,
-- read32: l440gx_read32,
-- copy_from: l440gx_copy_from,
-- write8: l440gx_write8,
-- write16: l440gx_write16,
-- write32: l440gx_write32,
-- copy_to: l440gx_copy_to,
-+ .name = "L440GX BIOS",
-+ .size = WINDOW_SIZE,
-+ .buswidth = BUSWIDTH,
-+ .phys = WINDOW_ADDR,
- #if 0
- /* FIXME verify that this is the
- * appripriate code for vpp enable/disable
- */
-- set_vpp: l440gx_set_vpp
-+ .set_vpp = l440gx_set_vpp
- #endif
- };
-
-@@ -113,7 +65,6 @@
- dev = pci_find_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB_0, NULL);
-
--
- pm_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
-
-@@ -122,15 +73,14 @@
- return -ENODEV;
- }
-
-+ l440gx_map.virt = (unsigned long)ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE);
-
-- l440gx_map.map_priv_1 = (unsigned long)ioremap_nocache(WINDOW_ADDR, WINDOW_SIZE);
--
-- if (!l440gx_map.map_priv_1) {
-+ if (!l440gx_map.virt) {
- printk(KERN_WARNING "Failed to ioremap L440GX flash region\n");
- return -ENOMEM;
- }
--
-- printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.map_priv_1);
-+ simple_map_init(&l440gx_map);
-+ printk(KERN_NOTICE "window_addr = 0x%08lx\n", (unsigned long)l440gx_map.virt);
-
- /* Setup the pm iobase resource
- * This code should move into some kind of generic bridge
-@@ -153,7 +103,7 @@
- /* Allocate the resource region */
- if (pci_assign_resource(pm_dev, PIIXE_IOBASE_RESOURCE) != 0) {
- printk(KERN_WARNING "Could not allocate pm iobase resource\n");
-- iounmap((void *)l440gx_map.map_priv_1);
-+ iounmap((void *)l440gx_map.virt);
- return -ENXIO;
- }
- }
-@@ -181,13 +131,13 @@
- mymtd = do_map_probe("map_rom", &l440gx_map);
- }
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
- add_mtd_device(mymtd);
- return 0;
- }
-
-- iounmap((void *)l440gx_map.map_priv_1);
-+ iounmap((void *)l440gx_map.virt);
- return -ENXIO;
- }
-
-@@ -196,7 +146,7 @@
- del_mtd_device(mymtd);
- map_destroy(mymtd);
-
-- iounmap((void *)l440gx_map.map_priv_1);
-+ iounmap((void *)l440gx_map.virt);
- }
-
- module_init(init_l440gx);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/lasat.c linux/drivers/mtd/maps/lasat.c
---- linux-mips-2.4.27/drivers/mtd/maps/lasat.c 2003-08-18 04:59:02.000000000 +0200
-+++ linux/drivers/mtd/maps/lasat.c 2004-11-19 10:25:11.928195384 +0100
-@@ -1,11 +1,20 @@
- /*
-- * Flash device on lasat 100 and 200 boards
-+ * Flash device on Lasat 100 and 200 boards
-+ *
-+ * (C) 2002 Brian Murphy <brian@murphy.dk>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License version
-+ * 2 as published by the Free Software Foundation.
-+ *
-+ * $Id$
- *
- */
-
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -13,123 +22,80 @@
- #include <linux/config.h>
- #include <asm/lasat/lasat.h>
-
--static struct mtd_info *mymtd;
--
--static __u8 sp_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--static __u16 sp_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--static __u32 sp_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--static void sp_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
-+static struct mtd_info *lasat_mtd;
-
--static void sp_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void sp_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void sp_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
-+static struct mtd_partition partition_info[LASAT_MTD_LAST];
-+static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Filesystem", "Config"};
-
--static void sp_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-+static void lasat_set_vpp(struct map_info *map, int vpp)
- {
-- memcpy_toio(map->map_priv_1 + to, from, len);
-+ if (vpp)
-+ *lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit;
-+ else
-+ *lasat_misc->flash_wp_reg &= ~(1 << lasat_misc->flash_wp_bit);
- }
-
--static struct map_info sp_map = {
-- name: "SP flash",
-- buswidth: 4,
-- read8: sp_read8,
-- read16: sp_read16,
-- read32: sp_read32,
-- copy_from: sp_copy_from,
-- write8: sp_write8,
-- write16: sp_write16,
-- write32: sp_write32,
-- copy_to: sp_copy_to
-+static struct map_info lasat_map = {
-+ .name = "LASAT flash",
-+ .buswidth = 4,
-+ .set_vpp = lasat_set_vpp
- };
-
--static struct mtd_partition partition_info[LASAT_MTD_LAST];
--static char *lasat_mtd_partnames[] = {"Bootloader", "Service", "Normal", "Config", "Filesystem"};
--
--static int __init init_sp(void)
-+static int __init init_lasat(void)
- {
- int i;
-- int nparts = 0;
-- /* this does not play well with the old flash code which
-- * protects and uprotects the flash when necessary */
-+ /* since we use AMD chips and set_vpp is not implimented
-+ * for these (yet) we still have to permanently enable flash write */
- printk(KERN_NOTICE "Unprotecting flash\n");
-- *lasat_misc->flash_wp_reg |= 1 << lasat_misc->flash_wp_bit;
-+ ENABLE_VPP((&lasat_map));
-
-- sp_map.map_priv_1 = ioremap_nocache(
-- lasat_flash_partition_start(LASAT_MTD_BOOTLOADER),
-- lasat_board_info.li_flash_size);
-- sp_map.size = lasat_board_info.li_flash_size;
-+ lasat_map.phys = lasat_flash_partition_start(LASAT_MTD_BOOTLOADER);
-+ lasat_map.virt = (unsigned long)ioremap_nocache(
-+ lasat_map.phys, lasat_board_info.li_flash_size);
-+ lasat_map.size = lasat_board_info.li_flash_size;
-
-- printk(KERN_NOTICE "sp flash device: %lx at %lx\n",
-- sp_map.size, sp_map.map_priv_1);
-+ simple_map_init(&lasat_map);
-
- for (i=0; i < LASAT_MTD_LAST; i++)
- partition_info[i].name = lasat_mtd_partnames[i];
-
-- mymtd = do_map_probe("cfi_probe", &sp_map);
-- if (mymtd) {
-+ lasat_mtd = do_map_probe("cfi_probe", &lasat_map);
-+
-+ if (!lasat_mtd)
-+ lasat_mtd = do_map_probe("jedec_probe", &lasat_map);
-+
-+ if (lasat_mtd) {
- u32 size, offset = 0;
-
-- mymtd->module = THIS_MODULE;
-+ lasat_mtd->owner = THIS_MODULE;
-
- for (i=0; i < LASAT_MTD_LAST; i++) {
- size = lasat_flash_partition_size(i);
-- if (size != 0) {
-- nparts++;
- partition_info[i].size = size;
- partition_info[i].offset = offset;
- offset += size;
- }
-- }
-
-- add_mtd_partitions( mymtd, partition_info, nparts );
-+ add_mtd_partitions( lasat_mtd, partition_info, LASAT_MTD_LAST );
- return 0;
- }
-
- return -ENXIO;
- }
-
--static void __exit cleanup_sp(void)
-+static void __exit cleanup_lasat(void)
- {
-- if (mymtd) {
-- del_mtd_partitions(mymtd);
-- map_destroy(mymtd);
-+ if (lasat_mtd) {
-+ del_mtd_partitions(lasat_mtd);
-+ map_destroy(lasat_mtd);
- }
-- if (sp_map.map_priv_1) {
-- sp_map.map_priv_1 = 0;
-+ if (lasat_map.virt) {
-+ lasat_map.virt = 0;
- }
- }
-
--module_init(init_sp);
--module_exit(cleanup_sp);
-+module_init(init_lasat);
-+module_exit(cleanup_lasat);
-
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Brian Murphy <brian@murphy.dk>");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/lubbock-flash.c linux/drivers/mtd/maps/lubbock-flash.c
---- linux-mips-2.4.27/drivers/mtd/maps/lubbock-flash.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/lubbock-flash.c 2004-11-19 10:25:11.930195080 +0100
-@@ -0,0 +1,151 @@
-+/*
-+ * $Id$
-+ *
-+ * Map driver for the Lubbock developer platform.
-+ *
-+ * Author: Nicolas Pitre
-+ * Copyright: (C) 2001 MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <asm/io.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+#include <asm/hardware.h>
-+
-+
-+#define ROM_ADDR 0x00000000
-+#define FLASH_ADDR 0x04000000
-+
-+#define WINDOW_SIZE 64*1024*1024
-+
-+static struct map_info lubbock_maps[2] = { {
-+ .size = WINDOW_SIZE,
-+ .phys = 0x00000000,
-+}, {
-+ .size = WINDOW_SIZE,
-+ .phys = 0x04000000,
-+} };
-+
-+static struct mtd_partition lubbock_partitions[] = {
-+ {
-+ .name = "Bootloader",
-+ .size = 0x00040000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
-+ },{
-+ .name = "Kernel",
-+ .size = 0x00100000,
-+ .offset = 0x00040000,
-+ },{
-+ .name = "Filesystem",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = 0x00140000
-+ }
-+};
-+
-+static struct mtd_info *mymtds[2];
-+static struct mtd_partition *parsed_parts[2];
-+static int nr_parsed_parts[2];
-+
-+static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-+
-+static int __init init_lubbock(void)
-+{
-+ int flashboot = (CONF_SWITCHES & 1);
-+ int ret = 0, i;
-+
-+ lubbock_maps[0].buswidth = lubbock_maps[1].buswidth =
-+ (BOOT_DEF & 1) ? 2 : 4;
-+
-+ /* Compensate for the nROMBT switch which swaps the flash banks */
-+ printk(KERN_NOTICE "Lubbock configured to boot from %s (bank %d)\n",
-+ flashboot?"Flash":"ROM", flashboot);
-+
-+ lubbock_maps[flashboot^1].name = "Lubbock Application Flash";
-+ lubbock_maps[flashboot].name = "Lubbock Boot ROM";
-+
-+ for (i = 0; i < 2; i++) {
-+ lubbock_maps[i].virt = (unsigned long)__ioremap(lubbock_maps[i].phys, WINDOW_SIZE, 0);
-+ if (!lubbock_maps[i].virt) {
-+ printk(KERN_WARNING "Failed to ioremap %s\n", lubbock_maps[i].name);
-+ if (!ret)
-+ ret = -ENOMEM;
-+ continue;
-+ }
-+ simple_map_init(&lubbock_maps[i]);
-+
-+ printk(KERN_NOTICE "Probing %s at physical address 0x%08lx (%d-bit buswidth)\n",
-+ lubbock_maps[i].name, lubbock_maps[i].phys,
-+ lubbock_maps[i].buswidth * 8);
-+
-+ mymtds[i] = do_map_probe("cfi_probe", &lubbock_maps[i]);
-+
-+ if (!mymtds[i]) {
-+ iounmap((void *)lubbock_maps[i].virt);
-+ if (!ret)
-+ ret = -EIO;
-+ continue;
-+ }
-+ mymtds[i]->owner = THIS_MODULE;
-+
-+ int ret = parse_mtd_partitions(mymtds[i], probes,
-+ &parsed_parts[i], 0);
-+
-+ if (ret > 0)
-+ nr_parsed_parts[i] = ret;
-+ }
-+
-+ if (!mymtds[0] && !mymtds[1])
-+ return ret;
-+
-+ for (i = 0; i < 2; i++) {
-+ if (!mymtds[i]) {
-+ printk(KERN_WARNING "%s is absent. Skipping\n", lubbock_maps[i].name);
-+ } else if (nr_parsed_parts[i]) {
-+ add_mtd_partitions(mymtds[i], parsed_parts[i], nr_parsed_parts[i]);
-+ } else if (!i) {
-+ printk("Using static partitions on %s\n", lubbock_maps[i].name);
-+ add_mtd_partitions(mymtds[i], lubbock_partitions, ARRAY_SIZE(lubbock_partitions));
-+ } else {
-+ printk("Registering %s as whole device\n", lubbock_maps[i].name);
-+ add_mtd_device(mymtds[i]);
-+ }
-+ }
-+ return 0;
-+}
-+
-+static void __exit cleanup_lubbock(void)
-+{
-+ int i;
-+ for (i = 0; i < 2; i++) {
-+ if (!mymtds[i])
-+ continue;
-+
-+ if (nr_parsed_parts[i] || !i)
-+ del_mtd_partitions(mymtds[i]);
-+ else
-+ del_mtd_device(mymtds[i]);
-+
-+ map_destroy(mymtds[i]);
-+ iounmap((void *)lubbock_maps[i].virt);
-+
-+ if (parsed_parts[i])
-+ kfree(parsed_parts[i]);
-+ }
-+}
-+
-+module_init(init_lubbock);
-+module_exit(cleanup_lubbock);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
-+MODULE_DESCRIPTION("MTD map driver for Intel Lubbock");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/map_funcs.c linux/drivers/mtd/maps/map_funcs.c
---- linux-mips-2.4.27/drivers/mtd/maps/map_funcs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/map_funcs.c 2004-11-19 10:25:11.931194928 +0100
-@@ -0,0 +1,96 @@
-+/*
-+ * $Id$
-+ *
-+ * Out-of-line map I/O functions for simple maps when CONFIG_COMPLEX_MAPPINGS
-+ * is enabled.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/config.h>
-+#include <linux/types.h>
-+#include <linux/string.h>
-+#include <asm/io.h>
-+
-+#include <linux/mtd/map.h>
-+
-+static u8 simple_map_read8(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readb(map->virt + ofs);
-+}
-+
-+static u16 simple_map_read16(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readw(map->virt + ofs);
-+}
-+
-+static u32 simple_map_read32(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readl(map->virt + ofs);
-+}
-+
-+static u64 simple_map_read64(struct map_info *map, unsigned long ofs)
-+{
-+#ifndef CONFIG_MTD_CFI_B8 /* 64-bit mappings */
-+ BUG();
-+ return 0;
-+#else
-+ return __raw_readll(map->virt + ofs);
-+#endif
-+}
-+
-+static void simple_map_write8(struct map_info *map, u8 datum, unsigned long ofs)
-+{
-+ __raw_writeb(datum, map->virt + ofs);
-+ mb();
-+}
-+
-+static void simple_map_write16(struct map_info *map, u16 datum, unsigned long ofs)
-+{
-+ __raw_writew(datum, map->virt + ofs);
-+ mb();
-+}
-+
-+static void simple_map_write32(struct map_info *map, u32 datum, unsigned long ofs)
-+{
-+ __raw_writel(datum, map->virt + ofs);
-+ mb();
-+}
-+
-+static void simple_map_write64(struct map_info *map, u64 datum, unsigned long ofs)
-+{
-+#ifndef CONFIG_MTD_CFI_B8 /* 64-bit mappings */
-+ BUG();
-+#else
-+ __raw_writell(datum, map->virt + ofs);
-+ mb();
-+#endif /* CFI_B8 */
-+}
-+
-+static void simple_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-+{
-+ memcpy_fromio(to, map->virt + from, len);
-+}
-+
-+static void simple_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-+{
-+ memcpy_toio(map->virt + to, from, len);
-+}
-+
-+void simple_map_init(struct map_info *map)
-+{
-+ map->read8 = simple_map_read8;
-+ map->read16 = simple_map_read16;
-+ map->read32 = simple_map_read32;
-+ map->read64 = simple_map_read64;
-+ map->write8 = simple_map_write8;
-+ map->write16 = simple_map_write16;
-+ map->write32 = simple_map_write32;
-+ map->write64 = simple_map_write64;
-+ map->copy_from = simple_map_copy_from;
-+ map->copy_to = simple_map_copy_to;
-+}
-+
-+EXPORT_SYMBOL(simple_map_init);
-+
-+MODULE_LICENSE("GPL");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/mbx860.c linux/drivers/mtd/maps/mbx860.c
---- linux-mips-2.4.27/drivers/mtd/maps/mbx860.c 2002-06-27 00:35:50.000000000 +0200
-+++ linux/drivers/mtd/maps/mbx860.c 2004-11-19 10:25:11.933194624 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Handle mapping of the flash on MBX860 boards
- *
-@@ -15,6 +15,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -36,91 +37,46 @@
- * single flash device into. If the size if zero we use up to the end of the
- * device. */
- static struct mtd_partition partition_info[]={
-- { name: "MBX flash BOOT partition",
-- offset: 0,
-- size: BOOT_PARTITION_SIZE_KiB*1024 },
-- { name: "MBX flash DATA partition",
-- offset: BOOT_PARTITION_SIZE_KiB*1024,
-- size: (KERNEL_PARTITION_SIZE_KiB)*1024 },
-- { name: "MBX flash APPLICATION partition",
-- offset: (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 }
-+ { .name = "MBX flash BOOT partition",
-+ .offset = 0,
-+ .size = BOOT_PARTITION_SIZE_KiB*1024 },
-+ { .name = "MBX flash DATA partition",
-+ .offset = BOOT_PARTITION_SIZE_KiB*1024,
-+ .size = (KERNEL_PARTITION_SIZE_KiB)*1024 },
-+ { .name = "MBX flash APPLICATION partition",
-+ .offset = (BOOT_PARTITION_SIZE_KiB+KERNEL_PARTITION_SIZE_KiB)*1024 }
- };
-
-
- static struct mtd_info *mymtd;
-
--__u8 mbx_read8(struct map_info *map, unsigned long ofs)
--{
-- return readb(map->map_priv_1 + ofs);
--}
--
--__u16 mbx_read16(struct map_info *map, unsigned long ofs)
--{
-- return readw(map->map_priv_1 + ofs);
--}
--
--__u32 mbx_read32(struct map_info *map, unsigned long ofs)
--{
-- return readl(map->map_priv_1 + ofs);
--}
--
--void mbx_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
--}
--
--void mbx_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- writeb(d, map->map_priv_1 + adr);
--}
--
--void mbx_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- writew(d, map->map_priv_1 + adr);
--}
--
--void mbx_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- writel(d, map->map_priv_1 + adr);
--}
--
--void mbx_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio((void *)(map->map_priv_1 + to), from, len);
--}
--
- struct map_info mbx_map = {
-- name: "MBX flash",
-- size: WINDOW_SIZE,
-- buswidth: 4,
-- read8: mbx_read8,
-- read16: mbx_read16,
-- read32: mbx_read32,
-- copy_from: mbx_copy_from,
-- write8: mbx_write8,
-- write16: mbx_write16,
-- write32: mbx_write32,
-- copy_to: mbx_copy_to
-+ .name = "MBX flash",
-+ .size = WINDOW_SIZE,
-+ .phys = WINDOW_ADDR,
-+ .buswidth = 4,
- };
-
- int __init init_mbx(void)
- {
-- printk(KERN_NOTICE "Motorola MBX flash device: %x at %x\n", WINDOW_SIZE*4, WINDOW_ADDR);
-- mbx_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4);
-+ printk(KERN_NOTICE "Motorola MBX flash device: 0x%x at 0x%x\n", WINDOW_SIZE*4, WINDOW_ADDR);
-+ mbx_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4);
-
-- if (!mbx_map.map_priv_1) {
-+ if (!mbx_map.virt) {
- printk("Failed to ioremap\n");
- return -EIO;
- }
-+ simple_map_init(&mbx_map);
-+
- mymtd = do_map_probe("jedec_probe", &mbx_map);
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
- add_mtd_device(mymtd);
- add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
- return 0;
- }
-
-- iounmap((void *)mbx_map.map_priv_1);
-+ iounmap((void *)mbx_map.virt);
- return -ENXIO;
- }
-
-@@ -130,9 +86,9 @@
- del_mtd_device(mymtd);
- map_destroy(mymtd);
- }
-- if (mbx_map.map_priv_1) {
-- iounmap((void *)mbx_map.map_priv_1);
-- mbx_map.map_priv_1 = 0;
-+ if (mbx_map.virt) {
-+ iounmap((void *)mbx_map.virt);
-+ mbx_map.virt = 0;
- }
- }
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/mpc1211.c linux/drivers/mtd/maps/mpc1211.c
---- linux-mips-2.4.27/drivers/mtd/maps/mpc1211.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/mpc1211.c 2004-11-19 10:25:11.934194472 +0100
-@@ -0,0 +1,79 @@
-+/*
-+ * Flash on MPC-1211
-+ *
-+ * (C) 2002 Interface, Saito.K & Jeanne
-+ *
-+ * GPL'd
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <asm/io.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/config.h>
-+
-+static struct mtd_info *flash_mtd;
-+static struct mtd_partition *parsed_parts;
-+
-+struct map_info mpc1211_flash_map = {
-+ .name = "MPC-1211 FLASH",
-+ .size = 0x80000,
-+ .buswidth = 1,
-+};
-+
-+static struct mtd_partition mpc1211_partitions[] = {
-+ {
-+ .name = "IPL & ETH-BOOT",
-+ .offset = 0x00000000,
-+ .size = 0x10000,
-+ },
-+ {
-+ .name = "Flash FS",
-+ .offset = 0x00010000,
-+ .size = MTDPART_SIZ_FULL,
-+ }
-+};
-+
-+static int __init init_mpc1211_maps(void)
-+{
-+ int nr_parts;
-+
-+ mpc1211_flash_map.phys = 0;
-+ mpc1211_flash_map.virt = P2SEGADDR(0);
-+
-+ simple_map_init(&mpc1211_flash_map);
-+
-+ printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n");
-+ flash_mtd = do_map_probe("jedec_probe", &mpc1211_flash_map);
-+ if (!flash_mtd) {
-+ printk(KERN_NOTICE "Flash chips not detected at either possible location.\n");
-+ return -ENXIO;
-+ }
-+ printk(KERN_NOTICE "MPC-1211: Flash at 0x%08lx\n", mpc1211_flash_map.virt & 0x1fffffff);
-+ flash_mtd->module = THIS_MODULE;
-+
-+ parsed_parts = mpc1211_partitions;
-+ nr_parts = ARRAY_SIZE(mpc1211_partitions);
-+
-+ add_mtd_partitions(flash_mtd, parsed_parts, nr_parts);
-+ return 0;
-+}
-+
-+static void __exit cleanup_mpc1211_maps(void)
-+{
-+ if (parsed_parts)
-+ del_mtd_partitions(flash_mtd);
-+ else
-+ del_mtd_device(flash_mtd);
-+ map_destroy(flash_mtd);
-+}
-+
-+module_init(init_mpc1211_maps);
-+module_exit(cleanup_mpc1211_maps);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Saito.K & Jeanne <ksaito@interface.co.jp>");
-+MODULE_DESCRIPTION("MTD map driver for MPC-1211 boards. Interface");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/netsc520.c linux/drivers/mtd/maps/netsc520.c
---- linux-mips-2.4.27/drivers/mtd/maps/netsc520.c 2001-11-05 21:15:52.000000000 +0100
-+++ linux/drivers/mtd/maps/netsc520.c 2004-11-19 10:25:11.935194320 +0100
-@@ -3,7 +3,7 @@
- * Copyright (C) 2001 Mark Langsdorf (mark.langsdorf@amd.com)
- * based on sc520cdp.c by Sysgo Real-Time Solutions GmbH
- *
-- * $Id$
-+ * $Id$
- *
- * 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
-@@ -27,6 +27,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -50,95 +51,41 @@
- ** recoverable afterwards.
- */
-
--static __u8 netsc520_read8(struct map_info *map, unsigned long ofs)
--{
-- return readb(map->map_priv_1 + ofs);
--}
--
--static __u16 netsc520_read16(struct map_info *map, unsigned long ofs)
--{
-- return readw(map->map_priv_1 + ofs);
--}
--
--static __u32 netsc520_read32(struct map_info *map, unsigned long ofs)
--{
-- return readl(map->map_priv_1 + ofs);
--}
--
--static void netsc520_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
--}
--
--static void netsc520_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- writeb(d, map->map_priv_1 + adr);
--}
--
--static void netsc520_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- writew(d, map->map_priv_1 + adr);
--}
--
--static void netsc520_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- writel(d, map->map_priv_1 + adr);
--}
--
--static void netsc520_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio((void *)(map->map_priv_1 + to), from, len);
--}
--
- /* partition_info gives details on the logical partitions that the split the
- * single flash device into. If the size if zero we use up to the end of the
- * device. */
- static struct mtd_partition partition_info[]={
- {
-- name: "NetSc520 boot kernel",
-- offset: 0,
-- size: 0xc0000
-+ .name = "NetSc520 boot kernel",
-+ .offset = 0,
-+ .size = 0xc0000
- },
- {
-- name: "NetSc520 Low BIOS",
-- offset: 0xc0000,
-- size: 0x40000
-+ .name = "NetSc520 Low BIOS",
-+ .offset = 0xc0000,
-+ .size = 0x40000
- },
- {
-- name: "NetSc520 file system",
-- offset: 0x100000,
-- size: 0xe80000
-+ .name = "NetSc520 file system",
-+ .offset = 0x100000,
-+ .size = 0xe80000
- },
- {
-- name: "NetSc520 High BIOS",
-- offset: 0xf80000,
-- size: 0x80000
-+ .name = "NetSc520 High BIOS",
-+ .offset = 0xf80000,
-+ .size = 0x80000
- },
- };
- #define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0]))
-
--/*
-- * If no idea what is going on here. This is taken from the FlashFX stuff.
-- */
--#define ROMCS 1
--
--
- #define WINDOW_SIZE 0x00100000
- #define WINDOW_ADDR 0x00200000
-
- static struct map_info netsc520_map = {
-- name: "netsc520 Flash Bank",
-- size: WINDOW_SIZE,
-- buswidth: 4,
-- read8: netsc520_read8,
-- read16: netsc520_read16,
-- read32: netsc520_read32,
-- copy_from: netsc520_copy_from,
-- write8: netsc520_write8,
-- write16: netsc520_write16,
-- write32: netsc520_write32,
-- copy_to: netsc520_copy_to,
-- map_priv_2: WINDOW_ADDR
-+ .name = "netsc520 Flash Bank",
-+ .size = WINDOW_SIZE,
-+ .buswidth = 4,
-+ .phys = WINDOW_ADDR,
- };
-
- #define NUM_FLASH_BANKS (sizeof(netsc520_map)/sizeof(struct map_info))
-@@ -147,13 +94,16 @@
-
- static int __init init_netsc520(void)
- {
-- printk(KERN_NOTICE "NetSc520 flash device: %lx at %lx\n", netsc520_map.size, netsc520_map.map_priv_2);
-- netsc520_map.map_priv_1 = (unsigned long)ioremap_nocache(netsc520_map.map_priv_2, netsc520_map.size);
-+ printk(KERN_NOTICE "NetSc520 flash device: 0x%lx at 0x%lx\n", netsc520_map.size, netsc520_map.phys);
-+ netsc520_map.virt = (unsigned long)ioremap_nocache(netsc520_map.phys, netsc520_map.size);
-
-- if (!netsc520_map.map_priv_1) {
-+ if (!netsc520_map.virt) {
- printk("Failed to ioremap_nocache\n");
- return -EIO;
- }
-+
-+ simple_map_init(&netsc520_map);
-+
- mymtd = do_map_probe("cfi_probe", &netsc520_map);
- if(!mymtd)
- mymtd = do_map_probe("map_ram", &netsc520_map);
-@@ -161,11 +111,11 @@
- mymtd = do_map_probe("map_rom", &netsc520_map);
-
- if (!mymtd) {
-- iounmap((void *)netsc520_map.map_priv_1);
-+ iounmap((void *)netsc520_map.virt);
- return -ENXIO;
- }
-
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
- add_mtd_partitions( mymtd, partition_info, NUM_PARTITIONS );
- return 0;
- }
-@@ -176,9 +126,9 @@
- del_mtd_partitions(mymtd);
- map_destroy(mymtd);
- }
-- if (netsc520_map.map_priv_1) {
-- iounmap((void *)netsc520_map.map_priv_1);
-- netsc520_map.map_priv_1 = 0;
-+ if (netsc520_map.virt) {
-+ iounmap((void *)netsc520_map.virt);
-+ netsc520_map.virt = 0;
- }
- }
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/nettel.c linux/drivers/mtd/maps/nettel.c
---- linux-mips-2.4.27/drivers/mtd/maps/nettel.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/maps/nettel.c 2004-11-19 10:25:11.937194016 +0100
-@@ -6,7 +6,7 @@
- * (C) Copyright 2000-2001, Greg Ungerer (gerg@snapgear.com)
- * (C) Copyright 2001-2002, SnapGear (www.snapgear.com)
- *
-- * $Id$
-+ * $Id$
- */
-
- /****************************************************************************/
-@@ -59,128 +59,72 @@
-
- /****************************************************************************/
-
--static __u8 nettel_read8(struct map_info *map, unsigned long ofs)
--{
-- return(readb(map->map_priv_1 + ofs));
--}
--
--static __u16 nettel_read16(struct map_info *map, unsigned long ofs)
--{
-- return(readw(map->map_priv_1 + ofs));
--}
--
--static __u32 nettel_read32(struct map_info *map, unsigned long ofs)
--{
-- return(readl(map->map_priv_1 + ofs));
--}
--
--static void nettel_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--static void nettel_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- writeb(d, map->map_priv_1 + adr);
--}
--
--static void nettel_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- writew(d, map->map_priv_1 + adr);
--}
--
--static void nettel_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- writel(d, map->map_priv_1 + adr);
--}
--
--static void nettel_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
--
- /****************************************************************************/
-
- #ifdef CONFIG_MTD_CFI_INTELEXT
- static struct map_info nettel_intel_map = {
-- name: "SnapGear Intel",
-- size: 0,
-- buswidth: INTEL_BUSWIDTH,
-- read8: nettel_read8,
-- read16: nettel_read16,
-- read32: nettel_read32,
-- copy_from: nettel_copy_from,
-- write8: nettel_write8,
-- write16: nettel_write16,
-- write32: nettel_write32,
-- copy_to: nettel_copy_to
-+ .name = "SnapGear Intel",
-+ .size = 0,
-+ .buswidth = INTEL_BUSWIDTH,
- };
-
- static struct mtd_partition nettel_intel_partitions[] = {
- {
-- name: "SnapGear kernel",
-- offset: 0,
-- size: 0x000e0000
-+ .name = "SnapGear kernel",
-+ .offset = 0,
-+ .size = 0x000e0000
- },
- {
-- name: "SnapGear filesystem",
-- offset: 0x00100000,
-+ .name = "SnapGear filesystem",
-+ .offset = 0x00100000,
- },
- {
-- name: "SnapGear config",
-- offset: 0x000e0000,
-- size: 0x00020000
-+ .name = "SnapGear config",
-+ .offset = 0x000e0000,
-+ .size = 0x00020000
- },
- {
-- name: "SnapGear Intel",
-- offset: 0
-+ .name = "SnapGear Intel",
-+ .offset = 0
- },
- {
-- name: "SnapGear BIOS Config",
-- offset: 0x007e0000,
-- size: 0x00020000
-+ .name = "SnapGear BIOS Config",
-+ .offset = 0x007e0000,
-+ .size = 0x00020000
- },
- {
-- name: "SnapGear BIOS",
-- offset: 0x007e0000,
-- size: 0x00020000
-+ .name = "SnapGear BIOS",
-+ .offset = 0x007e0000,
-+ .size = 0x00020000
- },
- };
- #endif
-
- static struct map_info nettel_amd_map = {
-- name: "SnapGear AMD",
-- size: AMD_WINDOW_MAXSIZE,
-- buswidth: AMD_BUSWIDTH,
-- read8: nettel_read8,
-- read16: nettel_read16,
-- read32: nettel_read32,
-- copy_from: nettel_copy_from,
-- write8: nettel_write8,
-- write16: nettel_write16,
-- write32: nettel_write32,
-- copy_to: nettel_copy_to
-+ .name = "SnapGear AMD",
-+ .size = AMD_WINDOW_MAXSIZE,
-+ .buswidth = AMD_BUSWIDTH,
- };
-
- static struct mtd_partition nettel_amd_partitions[] = {
- {
-- name: "SnapGear BIOS config",
-- offset: 0x000e0000,
-- size: 0x00010000
-+ .name = "SnapGear BIOS config",
-+ .offset = 0x000e0000,
-+ .size = 0x00010000
- },
- {
-- name: "SnapGear BIOS",
-- offset: 0x000f0000,
-- size: 0x00010000
-+ .name = "SnapGear BIOS",
-+ .offset = 0x000f0000,
-+ .size = 0x00010000
- },
- {
-- name: "SnapGear AMD",
-- offset: 0
-+ .name = "SnapGear AMD",
-+ .offset = 0
- },
- {
-- name: "SnapGear high BIOS",
-- offset: 0x001f0000,
-- size: 0x00010000
-+ .name = "SnapGear high BIOS",
-+ .offset = 0x001f0000,
-+ .size = 0x00010000
- }
- };
-
-@@ -328,18 +272,20 @@
- *amdpar = SC520_PAR(SC520_PAR_BOOTCS, amdaddr, maxsize);
- __asm__ ("wbinvd");
-
-- nettel_amd_map.map_priv_1 = (unsigned long)
-+ nettel_amd_map.phys = amdaddr;
-+ nettel_amd_map.virt = (unsigned long)
- ioremap_nocache(amdaddr, maxsize);
-- if (!nettel_amd_map.map_priv_1) {
-+ if (!nettel_amd_map.virt) {
- printk("SNAPGEAR: failed to ioremap() BOOTCS\n");
- return(-EIO);
- }
-+ simple_map_init(&nettel_amd_map);
-
- if ((amd_mtd = do_map_probe("jedec_probe", &nettel_amd_map))) {
- printk(KERN_NOTICE "SNAPGEAR: AMD flash device size = %dK\n",
- amd_mtd->size>>10);
-
-- amd_mtd->module = THIS_MODULE;
-+ amd_mtd->owner = THIS_MODULE;
-
- /* The high BIOS partition is only present for 2MB units */
- num_amd_partitions = NUM_AMD_PARTITIONS;
-@@ -387,8 +333,8 @@
-
- /* Destroy useless AMD MTD mapping */
- amd_mtd = NULL;
-- iounmap((void *) nettel_amd_map.map_priv_1);
-- nettel_amd_map.map_priv_1 = (unsigned long) NULL;
-+ iounmap((void *) nettel_amd_map.virt);
-+ nettel_amd_map.virt = (unsigned long) NULL;
- #else
- /* Only AMD flash supported */
- return(-ENXIO);
-@@ -411,16 +357,18 @@
-
- /* Probe for the the size of the first Intel flash */
- nettel_intel_map.size = maxsize;
-- nettel_intel_map.map_priv_1 = (unsigned long)
-+ nettel_intel_map.phys = intel0addr;
-+ nettel_intel_map.virt = (unsigned long)
- ioremap_nocache(intel0addr, maxsize);
-- if (!nettel_intel_map.map_priv_1) {
-+ if (!nettel_intel_map.virt) {
- printk("SNAPGEAR: failed to ioremap() ROMCS1\n");
- return(-EIO);
- }
-+ simple_map_init(&nettel_intel_map);
-
- intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
- if (! intel_mtd) {
-- iounmap((void *) nettel_intel_map.map_priv_1);
-+ iounmap((void *) nettel_intel_map.virt);
- return(-ENXIO);
- }
-
-@@ -441,19 +389,19 @@
- /* Delete the old map and probe again to do both chips */
- map_destroy(intel_mtd);
- intel_mtd = NULL;
-- iounmap((void *) nettel_intel_map.map_priv_1);
-+ iounmap((void *) nettel_intel_map.virt);
-
- nettel_intel_map.size = maxsize;
-- nettel_intel_map.map_priv_1 = (unsigned long)
-+ nettel_intel_map.virt = (unsigned long)
- ioremap_nocache(intel0addr, maxsize);
-- if (!nettel_intel_map.map_priv_1) {
-+ if (!nettel_intel_map.virt) {
- printk("SNAPGEAR: failed to ioremap() ROMCS1/2\n");
- return(-EIO);
- }
-
- intel_mtd = do_map_probe("cfi_probe", &nettel_intel_map);
- if (! intel_mtd) {
-- iounmap((void *) nettel_intel_map.map_priv_1);
-+ iounmap((void *) nettel_intel_map.virt);
- return(-ENXIO);
- }
-
-@@ -468,7 +416,7 @@
- printk(KERN_NOTICE "SNAPGEAR: Intel flash device size = %dK\n",
- (intel_mtd->size >> 10));
-
-- intel_mtd->module = THIS_MODULE;
-+ intel_mtd->owner = THIS_MODULE;
-
- #ifndef CONFIG_BLK_DEV_INITRD
- ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, 1);
-@@ -523,18 +471,18 @@
- del_mtd_partitions(amd_mtd);
- map_destroy(amd_mtd);
- }
-- if (nettel_amd_map.map_priv_1) {
-- iounmap((void *)nettel_amd_map.map_priv_1);
-- nettel_amd_map.map_priv_1 = 0;
-+ if (nettel_amd_map.virt) {
-+ iounmap((void *)nettel_amd_map.virt);
-+ nettel_amd_map.virt = 0;
- }
- #ifdef CONFIG_MTD_CFI_INTELEXT
- if (intel_mtd) {
- del_mtd_partitions(intel_mtd);
- map_destroy(intel_mtd);
- }
-- if (nettel_intel_map.map_priv_1) {
-- iounmap((void *)nettel_intel_map.map_priv_1);
-- nettel_intel_map.map_priv_1 = 0;
-+ if (nettel_intel_map.virt) {
-+ iounmap((void *)nettel_intel_map.virt);
-+ nettel_intel_map.virt = 0;
- }
- #endif
- }
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/ocelot.c linux/drivers/mtd/maps/ocelot.c
---- linux-mips-2.4.27/drivers/mtd/maps/ocelot.c 2001-11-05 21:15:52.000000000 +0100
-+++ linux/drivers/mtd/maps/ocelot.c 2004-11-19 10:25:11.938193864 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Flash on Momenco Ocelot
- */
-@@ -7,6 +7,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -20,47 +21,23 @@
- #define NVRAM_WINDOW_SIZE 0x00007FF0
- #define NVRAM_BUSWIDTH 1
-
--extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
--
- static unsigned int cacheflush = 0;
-
- static struct mtd_info *flash_mtd;
- static struct mtd_info *nvram_mtd;
-
--__u8 ocelot_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--void ocelot_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- cacheflush = 1;
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void ocelot_copy_from_cache(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- if (cacheflush) {
-- dma_cache_inv(map->map_priv_2, map->size);
-- cacheflush = 0;
-- }
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void ocelot_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-+static void ocelot_ram_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
- {
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
-+ struct map_info *map = (struct map_info *)mtd->priv;
-+ size_t done = 0;
-
--void ocelot_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
- /* If we use memcpy, it does word-wide writes. Even though we told the
- GT64120A that it's an 8-bit wide region, word-wide writes don't work.
- We end up just writing the first byte of the four to all four bytes.
- So we have this loop instead */
-+ *retlen = len;
- while(len) {
-- __raw_writeb(*(unsigned char *) from, map->map_priv_1 + to);
-+ __raw_writeb(*(unsigned char *) from, map->virt + to);
- from++;
- to++;
- len--;
-@@ -70,24 +47,21 @@
- static struct mtd_partition *parsed_parts;
-
- struct map_info ocelot_flash_map = {
-- name: "Ocelot boot flash",
-- size: FLASH_WINDOW_SIZE,
-- buswidth: FLASH_BUSWIDTH,
-- read8: ocelot_read8,
-- copy_from: ocelot_copy_from_cache,
-- write8: ocelot_write8,
-+ .name = "Ocelot boot flash",
-+ .size = FLASH_WINDOW_SIZE,
-+ .buswidth = FLASH_BUSWIDTH,
-+ .phys = FLASH_WINDOW_ADDR,
- };
-
- struct map_info ocelot_nvram_map = {
-- name: "Ocelot NVRAM",
-- size: NVRAM_WINDOW_SIZE,
-- buswidth: NVRAM_BUSWIDTH,
-- read8: ocelot_read8,
-- copy_from: ocelot_copy_from,
-- write8: ocelot_write8,
-- copy_to: ocelot_copy_to
-+ .name = "Ocelot NVRAM",
-+ .size = NVRAM_WINDOW_SIZE,
-+ .buswidth = NVRAM_BUSWIDTH,
-+ .phys = NVRAM_WINDOW_ADDR,
- };
-
-+static const char *probes[] = { "RedBoot", NULL };
-+
- static int __init init_ocelot_maps(void)
- {
- void *pld;
-@@ -107,12 +81,13 @@
- iounmap(pld);
-
- /* Now ioremap the NVRAM space */
-- ocelot_nvram_map.map_priv_1 = (unsigned long)ioremap_nocache(NVRAM_WINDOW_ADDR, NVRAM_WINDOW_SIZE);
-- if (!ocelot_nvram_map.map_priv_1) {
-+ ocelot_nvram_map.virt = (unsigned long)ioremap_nocache(NVRAM_WINDOW_ADDR, NVRAM_WINDOW_SIZE);
-+ if (!ocelot_nvram_map.virt) {
- printk(KERN_NOTICE "Failed to ioremap Ocelot NVRAM space\n");
- return -EIO;
- }
-- // ocelot_nvram_map.map_priv_2 = ocelot_nvram_map.map_priv_1;
-+
-+ simple_map_init(&ocelot_nvram_map);
-
- /* And do the RAM probe on it to get an MTD device */
- nvram_mtd = do_map_probe("map_ram", &ocelot_nvram_map);
-@@ -120,22 +95,21 @@
- printk("NVRAM probe failed\n");
- goto fail_1;
- }
-- nvram_mtd->module = THIS_MODULE;
-+ nvram_mtd->owner = THIS_MODULE;
- nvram_mtd->erasesize = 16;
-+ /* Override the write() method */
-+ nvram_mtd->write = ocelot_ram_write;
-
- /* Now map the flash space */
-- ocelot_flash_map.map_priv_1 = (unsigned long)ioremap_nocache(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE);
-- if (!ocelot_flash_map.map_priv_1) {
-+ ocelot_flash_map.virt = (unsigned long)ioremap_nocache(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE);
-+ if (!ocelot_flash_map.virt) {
- printk(KERN_NOTICE "Failed to ioremap Ocelot flash space\n");
- goto fail_2;
- }
- /* Now the cached version */
-- ocelot_flash_map.map_priv_2 = (unsigned long)__ioremap(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE, 0);
-+ ocelot_flash_map.cached = (unsigned long)__ioremap(FLASH_WINDOW_ADDR, FLASH_WINDOW_SIZE, 0);
-
-- if (!ocelot_flash_map.map_priv_2) {
-- /* Doesn't matter if it failed. Just use the uncached version */
-- ocelot_flash_map.map_priv_2 = ocelot_flash_map.map_priv_1;
-- }
-+ simple_map_init(&ocelot_flash_map);
-
- /* Only probe for flash if the write jumper is present */
- if (brd_status & 0x40) {
-@@ -155,10 +129,10 @@
-
- add_mtd_device(nvram_mtd);
-
-- flash_mtd->module = THIS_MODULE;
-- nr_parts = parse_redboot_partitions(flash_mtd, &parsed_parts);
-+ flash_mtd->owner = THIS_MODULE;
-+ nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_parts, 0);
-
-- if (nr_parts)
-+ if (nr_parts > 0)
- add_mtd_partitions(flash_mtd, parsed_parts, nr_parts);
- else
- add_mtd_device(flash_mtd);
-@@ -166,14 +140,13 @@
- return 0;
-
- fail3:
-- iounmap((void *)ocelot_flash_map.map_priv_1);
-- if (ocelot_flash_map.map_priv_2 &&
-- ocelot_flash_map.map_priv_2 != ocelot_flash_map.map_priv_1)
-- iounmap((void *)ocelot_flash_map.map_priv_2);
-+ iounmap((void *)ocelot_flash_map.virt);
-+ if (ocelot_flash_map.cached)
-+ iounmap((void *)ocelot_flash_map.cached);
- fail_2:
- map_destroy(nvram_mtd);
- fail_1:
-- iounmap((void *)ocelot_nvram_map.map_priv_1);
-+ iounmap((void *)ocelot_nvram_map.virt);
-
- return -ENXIO;
- }
-@@ -182,16 +155,16 @@
- {
- del_mtd_device(nvram_mtd);
- map_destroy(nvram_mtd);
-- iounmap((void *)ocelot_nvram_map.map_priv_1);
-+ iounmap((void *)ocelot_nvram_map.virt);
-
- if (parsed_parts)
- del_mtd_partitions(flash_mtd);
- else
- del_mtd_device(flash_mtd);
- map_destroy(flash_mtd);
-- iounmap((void *)ocelot_flash_map.map_priv_1);
-- if (ocelot_flash_map.map_priv_2 != ocelot_flash_map.map_priv_1)
-- iounmap((void *)ocelot_flash_map.map_priv_2);
-+ iounmap((void *)ocelot_flash_map.virt);
-+ if (ocelot_flash_map.cached)
-+ iounmap((void *)ocelot_flash_map.cached);
- }
-
- module_init(init_ocelot_maps);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/octagon-5066.c linux/drivers/mtd/maps/octagon-5066.c
---- linux-mips-2.4.27/drivers/mtd/maps/octagon-5066.c 2003-08-13 19:19:18.000000000 +0200
-+++ linux/drivers/mtd/maps/octagon-5066.c 2004-11-19 10:25:11.940193560 +0100
-@@ -1,4 +1,4 @@
--// $Id$
-+// $Id$
- /* ######################################################################
-
- Octagon 5066 MTD Driver.
-@@ -31,6 +31,7 @@
- #include <asm/io.h>
-
- #include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
-
- #define WINDOW_START 0xe8000
- #define WINDOW_LENGTH 0x8000
-@@ -151,32 +152,34 @@
-
- static struct map_info oct5066_map[2] = {
- {
-- name: "Octagon 5066 Socket",
-- size: 512 * 1024,
-- buswidth: 1,
-- read8: oct5066_read8,
-- read16: oct5066_read16,
-- read32: oct5066_read32,
-- copy_from: oct5066_copy_from,
-- write8: oct5066_write8,
-- write16: oct5066_write16,
-- write32: oct5066_write32,
-- copy_to: oct5066_copy_to,
-- map_priv_1: 1<<6
-+ .name = "Octagon 5066 Socket",
-+ .phys = NO_XIP,
-+ .size = 512 * 1024,
-+ .buswidth = 1,
-+ .read8 = oct5066_read8,
-+ .read16 = oct5066_read16,
-+ .read32 = oct5066_read32,
-+ .copy_from = oct5066_copy_from,
-+ .write8 = oct5066_write8,
-+ .write16 = oct5066_write16,
-+ .write32 = oct5066_write32,
-+ .copy_to = oct5066_copy_to,
-+ .map_priv_1 = 1<<6
- },
- {
-- name: "Octagon 5066 Internal Flash",
-- size: 2 * 1024 * 1024,
-- buswidth: 1,
-- read8: oct5066_read8,
-- read16: oct5066_read16,
-- read32: oct5066_read32,
-- copy_from: oct5066_copy_from,
-- write8: oct5066_write8,
-- write16: oct5066_write16,
-- write32: oct5066_write32,
-- copy_to: oct5066_copy_to,
-- map_priv_1: 2<<6
-+ .name = "Octagon 5066 Internal Flash",
-+ .phys = NO_XIP,
-+ .size = 2 * 1024 * 1024,
-+ .buswidth = 1,
-+ .read8 = oct5066_read8,
-+ .read16 = oct5066_read16,
-+ .read32 = oct5066_read32,
-+ .copy_from = oct5066_copy_from,
-+ .write8 = oct5066_write8,
-+ .write16 = oct5066_write16,
-+ .write32 = oct5066_write32,
-+ .copy_to = oct5066_copy_to,
-+ .map_priv_1 = 2<<6
- }
- };
-
-@@ -244,6 +247,7 @@
- }
- if (OctProbe() != 0) {
- printk(KERN_NOTICE "5066: Octagon Probe Failed, is this an Octagon 5066 SBC?\n");
-+ iounmap((void *)iomapadr);
- ret = -EAGAIN;
- goto out_unmap;
- }
-@@ -261,7 +265,7 @@
- if (!oct5066_mtd[i])
- oct5066_mtd[i] = do_map_probe("map_rom", &oct5066_map[i]);
- if (oct5066_mtd[i]) {
-- oct5066_mtd[i]->module = THIS_MODULE;
-+ oct5066_mtd[i]->owner = THIS_MODULE;
- add_mtd_device(oct5066_mtd[i]);
- }
- }
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/omap-toto-flash.c linux/drivers/mtd/maps/omap-toto-flash.c
---- linux-mips-2.4.27/drivers/mtd/maps/omap-toto-flash.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/omap-toto-flash.c 2004-11-19 10:25:11.941193408 +0100
-@@ -0,0 +1,137 @@
-+/*
-+ * NOR Flash memory access on TI Toto board
-+ *
-+ * jzhang@ti.com (C) 2003 Texas Instruments.
-+ *
-+ * (C) 2002 MontVista Software, Inc.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+
-+
-+#ifndef CONFIG_ARCH_OMAP
-+#error This is for OMAP architecture only
-+#endif
-+
-+//these lines need be moved to a hardware header file
-+#define OMAP_TOTO_FLASH_BASE 0xd8000000
-+#define OMAP_TOTO_FLASH_SIZE 0x80000
-+
-+static struct map_info omap_toto_map_flash = {
-+ .name = "OMAP Toto flash",
-+ .buswidth = 2,
-+ .virt = OMAP_TOTO_FLASH_BASE,
-+};
-+
-+
-+static struct mtd_partition toto_flash_partitions[] = {
-+ {
-+ .name = "BootLoader",
-+ .size = 0x00040000, /* hopefully u-boot will stay 128k + 128*/
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "ReservedSpace",
-+ .size = 0x00030000,
-+ .offset = MTDPART_OFS_APPEND,
-+ //mask_flags: MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "EnvArea", /* bottom 64KiB for env vars */
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
-+ }
-+};
-+
-+static struct mtd_partition *parsed_parts;
-+
-+static struct mtd_info *flash_mtd;
-+
-+static int __init init_flash (void)
-+{
-+
-+ struct mtd_partition *parts;
-+ int nb_parts = 0;
-+ int parsed_nr_parts = 0;
-+ const char *part_type;
-+
-+ /*
-+ * Static partition definition selection
-+ */
-+ part_type = "static";
-+
-+ parts = toto_flash_partitions;
-+ nb_parts = ARRAY_SIZE(toto_flash_partitions);
-+ omap_toto_map_flash.size = OMAP_TOTO_FLASH_SIZE;
-+ omap_toto_map_flash.phys = virt_to_phys(OMAP_TOTO_FLASH_BASE);
-+
-+ simple_map_init(&omap_toto_map_flash);
-+ /*
-+ * Now let's probe for the actual flash. Do it here since
-+ * specific machine settings might have been set above.
-+ */
-+ printk(KERN_NOTICE "OMAP toto flash: probing %d-bit flash bus\n",
-+ omap_toto_map_flash.buswidth*8);
-+ flash_mtd = do_map_probe("jedec_probe", &omap_toto_map_flash);
-+ if (!flash_mtd)
-+ return -ENXIO;
-+
-+ if (parsed_nr_parts > 0) {
-+ parts = parsed_parts;
-+ nb_parts = parsed_nr_parts;
-+ }
-+
-+ if (nb_parts == 0) {
-+ printk(KERN_NOTICE "OMAP toto flash: no partition info available,"
-+ "registering whole flash at once\n");
-+ if (add_mtd_device(flash_mtd)){
-+ return -ENXIO;
-+ }
-+ } else {
-+ printk(KERN_NOTICE "Using %s partition definition\n",
-+ part_type);
-+ return add_mtd_partitions(flash_mtd, parts, nb_parts);
-+ }
-+ return 0;
-+}
-+
-+int __init omap_toto_mtd_init(void)
-+{
-+ int status;
-+
-+ if (status = init_flash()) {
-+ printk(KERN_ERR "OMAP Toto Flash: unable to init map for toto flash\n");
-+ }
-+ return status;
-+}
-+
-+static void __exit omap_toto_mtd_cleanup(void)
-+{
-+ if (flash_mtd) {
-+ del_mtd_partitions(flash_mtd);
-+ map_destroy(flash_mtd);
-+ if (parsed_parts)
-+ kfree(parsed_parts);
-+ }
-+}
-+
-+module_init(omap_toto_mtd_init);
-+module_exit(omap_toto_mtd_cleanup);
-+
-+MODULE_AUTHOR("Jian Zhang");
-+MODULE_DESCRIPTION("OMAP Toto board map driver");
-+MODULE_LICENSE("GPL");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/pb1xxx-flash.c linux/drivers/mtd/maps/pb1xxx-flash.c
---- linux-mips-2.4.27/drivers/mtd/maps/pb1xxx-flash.c 2003-05-19 08:27:22.000000000 +0200
-+++ linux/drivers/mtd/maps/pb1xxx-flash.c 2004-11-19 10:25:11.943193104 +0100
-@@ -3,12 +3,13 @@
- *
- * (C) 2001 Pete Popov <ppopov@mvista.com>
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
- #include <linux/module.h>
- #include <linux/types.h>
-+#include <linux/init.h>
- #include <linux/kernel.h>
-
- #include <linux/mtd/mtd.h>
-@@ -25,210 +26,110 @@
- #endif
-
- #ifdef CONFIG_MIPS_PB1000
-+
- #define WINDOW_ADDR 0x1F800000
- #define WINDOW_SIZE 0x800000
--#endif
--
--__u8 physmap_read8(struct map_info *map, unsigned long ofs)
--{
-- __u8 ret;
-- ret = __raw_readb(map->map_priv_1 + ofs);
-- DBG("read8 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--__u16 physmap_read16(struct map_info *map, unsigned long ofs)
--{
-- __u16 ret;
-- ret = __raw_readw(map->map_priv_1 + ofs);
-- DBG("read16 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--__u32 physmap_read32(struct map_info *map, unsigned long ofs)
--{
-- __u32 ret;
-- ret = __raw_readl(map->map_priv_1 + ofs);
-- DBG("read32 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- DBG("physmap_copy from %x to %x\n", (unsigned)from, (unsigned)to);
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void physmap_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- DBG("write8 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- DBG("write16 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- DBG("write32 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- DBG("physmap_copy_to %x from %x\n", (unsigned)to, (unsigned)from);
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
--
--
--
--static struct map_info pb1xxx_map = {
-- name: "Pb1xxx flash",
-- read8: physmap_read8,
-- read16: physmap_read16,
-- read32: physmap_read32,
-- copy_from: physmap_copy_from,
-- write8: physmap_write8,
-- write16: physmap_write16,
-- write32: physmap_write32,
-- copy_to: physmap_copy_to,
--};
-
--
--#ifdef CONFIG_MIPS_PB1000
--
--static unsigned long flash_size = 0x00800000;
--static unsigned char flash_buswidth = 4;
- static struct mtd_partition pb1xxx_partitions[] = {
- {
-- name: "yamon env",
-- size: 0x00020000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE
-- },{
-- name: "User FS",
-- size: 0x003e0000,
-- offset: 0x20000,
-- },{
-- name: "boot code",
-- size: 0x100000,
-- offset: 0x400000,
-- mask_flags: MTD_WRITEABLE
-- },{
-- name: "raw/kernel",
-- size: 0x300000,
-- offset: 0x500000
-- }
-+ .name = "yamon env",
-+ .size = 0x00020000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE},
-+ {
-+ .name = "User FS",
-+ .size = 0x003e0000,
-+ .offset = 0x20000,},
-+ {
-+ .name = "boot code",
-+ .size = 0x100000,
-+ .offset = 0x400000,
-+ .mask_flags = MTD_WRITEABLE},
-+ {
-+ .name = "raw/kernel",
-+ .size = 0x300000,
-+ .offset = 0x500000}
- };
-
- #elif defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_PB1100)
-
--static unsigned char flash_buswidth = 4;
- #if defined(CONFIG_MTD_PB1500_BOOT) && defined(CONFIG_MTD_PB1500_USER)
--/* both 32MiB banks will be used. Combine the first 32MiB bank and the
-- * first 28MiB of the second bank together into a single jffs/jffs2
-+/* both 32MB banks will be used. Combine the first 32MB bank and the
-+ * first 28MB of the second bank together into a single jffs/jffs2
- * partition.
- */
--static unsigned long flash_size = 0x04000000;
- #define WINDOW_ADDR 0x1C000000
- #define WINDOW_SIZE 0x4000000
- static struct mtd_partition pb1xxx_partitions[] = {
- {
-- name: "User FS",
-- size: 0x3c00000,
-- offset: 0x0000000
-- },{
-- name: "yamon",
-- size: 0x0100000,
-- offset: 0x3c00000,
-- mask_flags: MTD_WRITEABLE
-- },{
-- name: "raw kernel",
-- size: 0x02c0000,
-- offset: 0x3d00000
-+ .name = "User FS",
-+ .size = 0x3c00000,
-+ .offset = 0x0000000
-+ },{
-+ .name = "yamon",
-+ .size = 0x0100000,
-+ .offset = 0x3c00000,
-+ .mask_flags = MTD_WRITEABLE
-+ },{
-+ .name = "raw kernel",
-+ .size = 0x02c0000,
-+ .offset = 0x3d00000
- }
- };
- #elif defined(CONFIG_MTD_PB1500_BOOT) && !defined(CONFIG_MTD_PB1500_USER)
--static unsigned long flash_size = 0x02000000;
- #define WINDOW_ADDR 0x1E000000
- #define WINDOW_SIZE 0x2000000
- static struct mtd_partition pb1xxx_partitions[] = {
- {
-- name: "User FS",
-- size: 0x1c00000,
-- offset: 0x0000000
-- },{
-- name: "yamon",
-- size: 0x0100000,
-- offset: 0x1c00000,
-- mask_flags: MTD_WRITEABLE
-- },{
-- name: "raw kernel",
-- size: 0x02c0000,
-- offset: 0x1d00000
-+ .name = "User FS",
-+ .size = 0x1c00000,
-+ .offset = 0x0000000
-+ },{
-+ .name = "yamon",
-+ .size = 0x0100000,
-+ .offset = 0x1c00000,
-+ .mask_flags = MTD_WRITEABLE
-+ },{
-+ .name = "raw kernel",
-+ .size = 0x02c0000,
-+ .offset = 0x1d00000
- }
- };
- #elif !defined(CONFIG_MTD_PB1500_BOOT) && defined(CONFIG_MTD_PB1500_USER)
--static unsigned long flash_size = 0x02000000;
- #define WINDOW_ADDR 0x1C000000
- #define WINDOW_SIZE 0x2000000
- static struct mtd_partition pb1xxx_partitions[] = {
- {
-- name: "User FS",
-- size: 0x1e00000,
-- offset: 0x0000000
-- },{
-- name: "raw kernel",
-- size: 0x0200000,
-- offset: 0x1e00000,
-+ .name = "User FS",
-+ .size = 0x1e00000,
-+ .offset = 0x0000000
-+ },{
-+ .name = "raw kernel",
-+ .size = 0x0200000,
-+ .offset = 0x1e00000,
- }
- };
- #else
- #error MTD_PB1500 define combo error /* should never happen */
- #endif
--#elif defined(CONFIG_MTD_BOSPORUS)
--static unsigned char flash_buswidth = 2;
--static unsigned long flash_size = 0x02000000;
--#define WINDOW_ADDR 0x1F000000
--#define WINDOW_SIZE 0x2000000
--static struct mtd_partition pb1xxx_partitions[] = {
-- {
-- name: "User FS",
-- size: 0x00400000,
-- offset: 0x00000000,
-- },{
-- name: "Yamon-2",
-- size: 0x00100000,
-- offset: 0x00400000,
-- },{
-- name: "Root FS",
-- size: 0x00700000,
-- offset: 0x00500000,
-- },{
-- name: "Yamon-1",
-- size: 0x00100000,
-- offset: 0x00C00000,
-- },{
-- name: "Kernel",
-- size: 0x00300000,
-- offset: 0x00D00000,
-- }
--};
- #else
- #error Unsupported board
- #endif
-
-+#define NAME "Pb1x00 Linux Flash"
-+#define PADDR WINDOW_ADDR
-+#define BUSWIDTH 4
-+#define SIZE WINDOW_SIZE
-+#define PARTITIONS 4
-+
-+static struct map_info pb1xxx_mtd_map = {
-+ .name = NAME,
-+ .size = SIZE,
-+ .buswidth = BUSWIDTH,
-+ .phys = PADDR,
-+};
-
--#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
--
--static struct mtd_partition *parsed_parts;
--static struct mtd_info *mymtd;
-+static struct mtd_info *pb1xxx_mtd;
-
- int __init pb1xxx_mtd_init(void)
- {
-@@ -236,40 +137,37 @@
- int nb_parts = 0;
- char *part_type;
-
-- /* Default flash buswidth */
-- pb1xxx_map.buswidth = flash_buswidth;
--
- /*
- * Static partition definition selection
- */
- part_type = "static";
- parts = pb1xxx_partitions;
-- nb_parts = NB_OF(pb1xxx_partitions);
-- pb1xxx_map.size = flash_size;
-+ nb_parts = ARRAY_SIZE(pb1xxx_partitions);
-
- /*
- * Now let's probe for the actual flash. Do it here since
- * specific machine settings might have been set above.
- */
- printk(KERN_NOTICE "Pb1xxx flash: probing %d-bit flash bus\n",
-- pb1xxx_map.buswidth*8);
-- pb1xxx_map.map_priv_1 =
-- (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-- mymtd = do_map_probe("cfi_probe", &pb1xxx_map);
-- if (!mymtd) return -ENXIO;
-- mymtd->module = THIS_MODULE;
-+ BUSWIDTH*8);
-+ pb1xxx_mtd_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-+
-+ simple_map_init(&pb1xxx_mtd_map);
-+
-+ pb1xxx_mtd = do_map_probe("cfi_probe", &pb1xxx_mtd_map);
-+ if (!pb1xxx_mtd) return -ENXIO;
-+ pb1xxx_mtd->owner = THIS_MODULE;
-
-- add_mtd_partitions(mymtd, parts, nb_parts);
-+ add_mtd_partitions(pb1xxx_mtd, parts, nb_parts);
- return 0;
- }
-
- static void __exit pb1xxx_mtd_cleanup(void)
- {
-- if (mymtd) {
-- del_mtd_partitions(mymtd);
-- map_destroy(mymtd);
-- if (parsed_parts)
-- kfree(parsed_parts);
-+ if (pb1xxx_mtd) {
-+ del_mtd_partitions(pb1xxx_mtd);
-+ map_destroy(pb1xxx_mtd);
-+ iounmap((void *) pb1xxx_mtd_map.virt);
- }
- }
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/pci.c linux/drivers/mtd/maps/pci.c
---- linux-mips-2.4.27/drivers/mtd/maps/pci.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/maps/pci.c 2004-11-19 10:25:11.944192952 +0100
-@@ -7,7 +7,7 @@
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-- * $Id$
-+ * $Id$
- *
- * Generic PCI memory map driver. We support the following boards:
- * - Intel IQ80310 ATU.
-@@ -98,10 +98,10 @@
- }
-
- static struct mtd_pci_info intel_iq80310_info = {
-- init: intel_iq80310_init,
-- exit: intel_iq80310_exit,
-- translate: intel_iq80310_translate,
-- map_name: "cfi_probe",
-+ .init = intel_iq80310_init,
-+ .exit = intel_iq80310_exit,
-+ .translate = intel_iq80310_translate,
-+ .map_name = "cfi_probe",
- };
-
- /*
-@@ -181,10 +181,10 @@
- }
-
- static struct mtd_pci_info intel_dc21285_info = {
-- init: intel_dc21285_init,
-- exit: intel_dc21285_exit,
-- translate: intel_dc21285_translate,
-- map_name: "jedec_probe",
-+ .init = intel_dc21285_init,
-+ .exit = intel_dc21285_exit,
-+ .translate = intel_dc21285_translate,
-+ .map_name = "jedec_probe",
- };
-
- /*
-@@ -193,22 +193,20 @@
-
- static struct pci_device_id mtd_pci_ids[] __devinitdata = {
- {
-- vendor: PCI_VENDOR_ID_INTEL,
-- device: 0x530d,
-- subvendor: PCI_ANY_ID,
-- subdevice: PCI_ANY_ID,
-- class: PCI_CLASS_MEMORY_OTHER << 8,
-- class_mask: 0xffff00,
-- driver_data: (unsigned long)&intel_iq80310_info,
-+ .vendor = PCI_VENDOR_ID_INTEL,
-+ .device = 0x530d,
-+ .subvendor = PCI_ANY_ID,
-+ .subdevice = PCI_ANY_ID,
-+ .class = PCI_CLASS_MEMORY_OTHER << 8,
-+ .class_mask = 0xffff00,
-+ .driver_data = (unsigned long)&intel_iq80310_info,
- },
- {
-- vendor: PCI_VENDOR_ID_DEC,
-- device: PCI_DEVICE_ID_DEC_21285,
-- subvendor: 0, /* DC21285 defaults to 0 on reset */
-- subdevice: 0, /* DC21285 defaults to 0 on reset */
-- class: 0,
-- class_mask: 0,
-- driver_data: (unsigned long)&intel_dc21285_info,
-+ .vendor = PCI_VENDOR_ID_DEC,
-+ .device = PCI_DEVICE_ID_DEC_21285,
-+ .subvendor = 0, /* DC21285 defaults to 0 on reset */
-+ .subdevice = 0, /* DC21285 defaults to 0 on reset */
-+ .driver_data = (unsigned long)&intel_dc21285_info,
- },
- { 0, }
- };
-@@ -275,14 +273,15 @@
- }
-
- static struct map_info mtd_pci_map = {
-- read8: mtd_pci_read8,
-- read16: mtd_pci_read16,
-- read32: mtd_pci_read32,
-- copy_from: mtd_pci_copyfrom,
-- write8: mtd_pci_write8,
-- write16: mtd_pci_write16,
-- write32: mtd_pci_write32,
-- copy_to: mtd_pci_copyto,
-+ .phys = NO_XIP,
-+ .read8 = mtd_pci_read8,
-+ .read16 = mtd_pci_read16,
-+ .read32 = mtd_pci_read32,
-+ .copy_from = mtd_pci_copyfrom,
-+ .write8 = mtd_pci_write8,
-+ .write16 = mtd_pci_write16,
-+ .write32 = mtd_pci_write32,
-+ .copy_to = mtd_pci_copyto,
- };
-
- static int __devinit
-@@ -322,7 +321,7 @@
- if (!mtd)
- goto release;
-
-- mtd->module = THIS_MODULE;
-+ mtd->owner = THIS_MODULE;
- add_mtd_device(mtd);
-
- pci_set_drvdata(dev, mtd);
-@@ -359,10 +358,10 @@
- }
-
- static struct pci_driver mtd_pci_driver = {
-- name: "MTD PCI",
-- probe: mtd_pci_probe,
-- remove: __devexit_p(mtd_pci_remove),
-- id_table: mtd_pci_ids,
-+ .name = "MTD PCI",
-+ .probe = mtd_pci_probe,
-+ .remove = __devexit_p(mtd_pci_remove),
-+ .id_table = mtd_pci_ids,
- };
-
- static int __init mtd_pci_maps_init(void)
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/pcmciamtd.c linux/drivers/mtd/maps/pcmciamtd.c
---- linux-mips-2.4.27/drivers/mtd/maps/pcmciamtd.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/maps/pcmciamtd.c 2004-11-19 10:25:11.946192648 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * pcmciamtd.c - MTD driver for PCMCIA flash memory cards
- *
-@@ -14,6 +14,7 @@
- #include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/timer.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <asm/system.h>
-
-@@ -24,6 +25,7 @@
- #include <pcmcia/ds.h>
-
- #include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
-
- #ifdef CONFIG_MTD_DEBUG
- static int debug = CONFIG_MTD_DEBUG_VERBOSE;
-@@ -47,7 +49,7 @@
-
-
- #define DRIVER_DESC "PCMCIA Flash memory card driver"
--#define DRIVER_VERSION "$Revision$"
-+#define DRIVER_VERSION "$Revision$"
-
- /* Size of the PCMCIA address space: 26 bits = 64 MB */
- #define MAX_PCMCIA_ADDR 0x4000000
-@@ -96,7 +98,7 @@
- MODULE_PARM(mem_speed, "i");
- MODULE_PARM_DESC(mem_speed, "Set memory access speed in ns");
- MODULE_PARM(force_size, "i");
--MODULE_PARM_DESC(force_size, "Force size of card in MB (1-64)");
-+MODULE_PARM_DESC(force_size, "Force size of card in MiB (1-64)");
- MODULE_PARM(setvpp, "i");
- MODULE_PARM_DESC(setvpp, "Set Vpp (0=Never, 1=On writes, 2=Always on, default=0)");
- MODULE_PARM(vpp, "i");
-@@ -106,11 +108,13 @@
-
-
-
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)
- static inline void cs_error(client_handle_t handle, int func, int ret)
- {
- error_info_t err = { func, ret };
- CardServices(ReportError, handle, &err);
- }
-+#endif
-
-
- /* read/write{8,16} copy_{from,to} routines with window remapping to access whole card */
-@@ -529,6 +533,7 @@
-
- card_settings(dev, link, &new_name);
-
-+ dev->pcmcia_map.phys = NO_XIP;
- dev->pcmcia_map.read8 = pcmcia_read8_remap;
- dev->pcmcia_map.read16 = pcmcia_read16_remap;
- dev->pcmcia_map.copy_from = pcmcia_copy_from_remap;
-@@ -539,7 +544,7 @@
- dev->pcmcia_map.set_vpp = pcmciamtd_set_vpp;
-
- /* Request a memory window for PCMCIA. Some architeures can map windows upto the maximum
-- that PCMCIA can support (64Mb) - this is ideal and we aim for a window the size of the
-+ that PCMCIA can support (64MiB) - this is ideal and we aim for a window the size of the
- whole card - otherwise we try smaller windows until we succeed */
-
- req.Attributes = WIN_MEMORY_TYPE_CM | WIN_ENABLE;
-@@ -552,7 +557,7 @@
-
- do {
- int ret;
-- DEBUG(2, "requesting window with size = %dKB memspeed = %d",
-+ DEBUG(2, "requesting window with size = %dKiB memspeed = %d",
- req.Size >> 10, req.AccessSpeed);
- link->win = (window_handle_t)link->handle;
- ret = CardServices(RequestWindow, &link->win, &req);
-@@ -560,7 +565,7 @@
- if(ret) {
- req.Size >>= 1;
- } else {
-- DEBUG(2, "Got window of size %dKB", req.Size >> 10);
-+ DEBUG(2, "Got window of size %dKiB", req.Size >> 10);
- dev->win_size = req.Size;
- break;
- }
-@@ -573,7 +578,7 @@
- pcmciamtd_release((u_long)link);
- return;
- }
-- DEBUG(1, "Allocated a window of %dKB", dev->win_size >> 10);
-+ DEBUG(1, "Allocated a window of %dKiB", dev->win_size >> 10);
-
- /* Get write protect status */
- CS_CHECK(GetStatus, link->handle, &status);
-@@ -642,21 +647,21 @@
- }
-
- dev->mtd_info = mtd;
-- mtd->module = THIS_MODULE;
-+ mtd->owner = THIS_MODULE;
-
- if(new_name) {
- int size = 0;
- char unit = ' ';
- /* Since we are using a default name, make it better by adding in the
- size */
-- if(mtd->size < 1048576) { /* <1MB in size, show size in K */
-+ if(mtd->size < 1048576) { /* <1MiB in size, show size in KiB */
- size = mtd->size >> 10;
- unit = 'K';
- } else {
- size = mtd->size >> 20;
- unit = 'M';
- }
-- snprintf(dev->mtd_name, sizeof(dev->mtd_name), "%d%cB %s", size, unit, "PCMCIA Memory card");
-+ snprintf(dev->mtd_name, sizeof(dev->mtd_name), "%d%ciB %s", size, unit, "PCMCIA Memory card");
- }
-
- /* If the memory found is fits completely into the mapped PCMCIA window,
-@@ -828,16 +833,20 @@
- }
-
-
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,68)
-+static struct pcmcia_driver pcmciamtd_driver = {
-+ .drv = {
-+ .name = "pcmciamtd"
-+ },
-+ .attach = pcmciamtd_attach,
-+ .detach = pcmciamtd_detach,
-+ .owner = THIS_MODULE
-+};
-+#endif
-+
-+
- static int __init init_pcmciamtd(void)
- {
-- servinfo_t serv;
--
-- info(DRIVER_DESC " " DRIVER_VERSION);
-- CardServices(GetCardServicesInfo, &serv);
-- if (serv.Revision != CS_RELEASE_CODE) {
-- err("Card Services release does not match!");
-- return -1;
-- }
-
- if(buswidth && buswidth != 1 && buswidth != 2) {
- info("bad buswidth (%d), using default", buswidth);
-@@ -851,15 +860,24 @@
- info("bad mem_type (%d), using default", mem_type);
- mem_type = 0;
- }
-+
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,68)
-+ return pcmcia_register_driver(&pcmciamtd_driver);
-+#else
- register_pccard_driver(&dev_info, &pcmciamtd_attach, &pcmciamtd_detach);
- return 0;
-+#endif
- }
-
-
- static void __exit exit_pcmciamtd(void)
- {
- DEBUG(1, DRIVER_DESC " unloading");
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,68)
-+ pcmcia_unregister_driver(&pcmciamtd_driver);
-+#else
- unregister_pccard_driver(&dev_info);
-+#endif
-
- while(dev_list) {
- dev_link_t *link = dev_list;
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/physmap.c linux/drivers/mtd/maps/physmap.c
---- linux-mips-2.4.27/drivers/mtd/maps/physmap.c 2003-02-26 01:53:50.000000000 +0100
-+++ linux/drivers/mtd/maps/physmap.c 2004-11-19 10:25:11.947192496 +0100
-@@ -1,179 +1,114 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Normal mappings of chips in physical memory
-+ *
-+ * Copyright (C) 2003 MontaVista Software Inc.
-+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
-+ *
-+ * 031022 - [jsun] add run-time configure and partition setup
- */
-
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
- #include <linux/config.h>
--
--#ifdef CONFIG_MTD_PARTITIONS
- #include <linux/mtd/partitions.h>
--#endif
--
--#define WINDOW_ADDR CONFIG_MTD_PHYSMAP_START
--#define WINDOW_SIZE CONFIG_MTD_PHYSMAP_LEN
--#define BUSWIDTH CONFIG_MTD_PHYSMAP_BUSWIDTH
-
- static struct mtd_info *mymtd;
-
--__u8 physmap_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 physmap_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 physmap_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
-+struct map_info physmap_map = {.name = "phys_mapped_flash"};
-
--void physmap_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
-+#ifdef CONFIG_MTD_PARTITIONS
-+static struct mtd_partition *mtd_parts;
-+static int mtd_parts_nb;
-
--void physmap_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
-+static int num_physmap_partitions;
-+static struct mtd_partition *physmap_partitions;
-
--void physmap_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
-+char *part_probes[] __initdata = {"cmdlinepart", "RedBoot", NULL};
-
--void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-+void physmap_set_partitions(struct mtd_partition *parts, int num_parts)
- {
-- memcpy_toio(map->map_priv_1 + to, from, len);
-+ physmap_partitions=parts;
-+ num_physmap_partitions=num_parts;
- }
--
--struct map_info physmap_map = {
-- name: "Physically mapped flash",
-- size: WINDOW_SIZE,
-- buswidth: BUSWIDTH,
-- read8: physmap_read8,
-- read16: physmap_read16,
-- read32: physmap_read32,
-- copy_from: physmap_copy_from,
-- write8: physmap_write8,
-- write16: physmap_write16,
-- write32: physmap_write32,
-- copy_to: physmap_copy_to
--};
--
--#ifdef CONFIG_MTD_PARTITIONS
--#ifdef CONFIG_MTD_CMDLINE_PARTS
--static struct mtd_partition *mtd_parts = 0;
--static int mtd_parts_nb = 0;
--#else
--static struct mtd_partition physmap_partitions[] = {
--/* Put your own partition definitions here */
--#if 0
-- {
-- name: "bootROM",
-- size: 0x80000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "zImage",
-- size: 0x100000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "ramdisk.gz",
-- size: 0x300000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "User FS",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-- }
--#endif
--};
--
--#define NUM_PARTITIONS (sizeof(physmap_partitions)/sizeof(struct mtd_partition))
--
--#endif
--#endif
-+#endif /* CONFIG_MTD_PARTITIONS */
-
- int __init init_physmap(void)
- {
- static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", 0 };
- const char **type;
-
-- printk(KERN_NOTICE "physmap flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
-- physmap_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-+ printk(KERN_NOTICE "physmap flash device: %lx at %lx\n", physmap_map.size, physmap_map.phys);
-+ physmap_map.virt = (unsigned long)ioremap(physmap_map.phys, physmap_map.size);
-
-- if (!physmap_map.map_priv_1) {
-+ if (!physmap_map.virt) {
- printk("Failed to ioremap\n");
- return -EIO;
- }
-
-+ simple_map_init(&physmap_map);
-+
- mymtd = 0;
- type = rom_probe_types;
- for(; !mymtd && *type; type++) {
- mymtd = do_map_probe(*type, &physmap_map);
- }
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
-- add_mtd_device(mymtd);
- #ifdef CONFIG_MTD_PARTITIONS
--#ifdef CONFIG_MTD_CMDLINE_PARTS
-- mtd_parts_nb = parse_cmdline_partitions(mymtd, &mtd_parts,
-- "phys");
-+ mtd_parts_nb = parse_mtd_partitions(mymtd, part_probes,
-+ &mtd_parts, 0);
-+
- if (mtd_parts_nb > 0)
- {
-- printk(KERN_NOTICE
-- "Using command line partition definition\n");
- add_mtd_partitions (mymtd, mtd_parts, mtd_parts_nb);
-+ return 0;
- }
--#else
-- if (NUM_PARTITIONS != 0)
-+
-+ if (num_physmap_partitions != 0)
- {
- printk(KERN_NOTICE
- "Using physmap partition definition\n");
-- add_mtd_partitions (mymtd, physmap_partitions, NUM_PARTITIONS);
-+ add_mtd_partitions (mymtd, physmap_partitions, num_physmap_partitions);
-+ return 0;
- }
-
- #endif
--#endif
-+ add_mtd_device(mymtd);
-+
- return 0;
- }
-
-- iounmap((void *)physmap_map.map_priv_1);
-+ iounmap((void *)physmap_map.virt);
- return -ENXIO;
- }
-
- static void __exit cleanup_physmap(void)
- {
-- if (mymtd) {
-+#ifdef CONFIG_MTD_PARTITIONS
-+ if (mtd_parts_nb) {
-+ del_mtd_partitions(mymtd);
-+ kfree(mtd_parts);
-+ } else if (num_physmap_partitions) {
-+ del_mtd_partitions(mymtd);
-+ } else {
- del_mtd_device(mymtd);
-- map_destroy(mymtd);
-- }
-- if (physmap_map.map_priv_1) {
-- iounmap((void *)physmap_map.map_priv_1);
-- physmap_map.map_priv_1 = 0;
- }
-+#else
-+ del_mtd_device(mymtd);
-+#endif
-+ map_destroy(mymtd);
-+
-+ iounmap((void *)physmap_map.virt);
-+ physmap_map.virt = 0;
- }
-
- module_init(init_physmap);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/pnc2000.c linux/drivers/mtd/maps/pnc2000.c
---- linux-mips-2.4.27/drivers/mtd/maps/pnc2000.c 2001-11-05 21:15:52.000000000 +0100
-+++ linux/drivers/mtd/maps/pnc2000.c 2004-11-19 10:25:11.949192192 +0100
-@@ -5,12 +5,13 @@
- *
- * This code is GPL
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -24,58 +25,13 @@
- * MAP DRIVER STUFF
- */
-
--__u8 pnc_read8(struct map_info *map, unsigned long ofs)
--{
-- return *(__u8 *)(WINDOW_ADDR + ofs);
--}
--
--__u16 pnc_read16(struct map_info *map, unsigned long ofs)
--{
-- return *(__u16 *)(WINDOW_ADDR + ofs);
--}
--
--__u32 pnc_read32(struct map_info *map, unsigned long ofs)
--{
-- return *(volatile unsigned int *)(WINDOW_ADDR + ofs);
--}
--
--void pnc_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy(to, (void *)(WINDOW_ADDR + from), len);
--}
--
--void pnc_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- *(__u8 *)(WINDOW_ADDR + adr) = d;
--}
--
--void pnc_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- *(__u16 *)(WINDOW_ADDR + adr) = d;
--}
--
--void pnc_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- *(__u32 *)(WINDOW_ADDR + adr) = d;
--}
--
--void pnc_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy((void *)(WINDOW_ADDR + to), from, len);
--}
-
- struct map_info pnc_map = {
-- name: "PNC-2000",
-- size: WINDOW_SIZE,
-- buswidth: 4,
-- read8: pnc_read8,
-- read16: pnc_read16,
-- read32: pnc_read32,
-- copy_from: pnc_copy_from,
-- write8: pnc_write8,
-- write16: pnc_write16,
-- write32: pnc_write32,
-- copy_to: pnc_copy_to
-+ .name = "PNC-2000",
-+ .size = WINDOW_SIZE,
-+ .buswidth = 4,
-+ .phys = 0xFFFFFFFF,
-+ .virt = WINDOW_ADDR,
- };
-
-
-@@ -84,19 +40,19 @@
- */
- static struct mtd_partition pnc_partitions[3] = {
- {
-- name: "PNC-2000 boot firmware",
-- size: 0x20000,
-- offset: 0
-+ .name = "PNC-2000 boot firmware",
-+ .size = 0x20000,
-+ .offset = 0
- },
- {
-- name: "PNC-2000 kernel",
-- size: 0x1a0000,
-- offset: 0x20000
-+ .name = "PNC-2000 kernel",
-+ .size = 0x1a0000,
-+ .offset = 0x20000
- },
- {
-- name: "PNC-2000 filesystem",
-- size: 0x240000,
-- offset: 0x1c0000
-+ .name = "PNC-2000 filesystem",
-+ .size = 0x240000,
-+ .offset = 0x1c0000
- }
- };
-
-@@ -110,9 +66,11 @@
- {
- printk(KERN_NOTICE "Photron PNC-2000 flash mapping: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
-
-+ simple_map_init(&pnc_map);
-+
- mymtd = do_map_probe("cfi_probe", &pnc_map);
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
- return add_mtd_partitions(mymtd, pnc_partitions, 3);
- }
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/redwood.c linux/drivers/mtd/maps/redwood.c
---- linux-mips-2.4.27/drivers/mtd/maps/redwood.c 2003-02-26 01:53:50.000000000 +0100
-+++ linux/drivers/mtd/maps/redwood.c 2004-11-19 10:25:11.962190216 +0100
-@@ -1,38 +1,23 @@
- /*
-- * $Id:
-+ * $Id$
- *
-- * redwood.c - mapper for IBM Redwood-4/5 board.
-+ * drivers/mtd/maps/redwood.c
- *
-- * Copyright 2001 MontaVista Softare Inc.
-+ * FLASH map for the IBM Redwood 4/5/6 boards.
- *
-- * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
-- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
-- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-- *
-- * 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.
-- *
-- * History: 12/17/2001 - Armin
-- * migrated to use do_map_probe
-+ * Author: MontaVista Software, Inc. <source@mvista.com>
- *
-+ * 2001-2003 (c) MontaVista, Software, Inc. This file is licensed under
-+ * the terms of the GNU General Public License version 2. This program
-+ * is licensed "as is" without any warranty of any kind, whether express
-+ * or implied.
- */
-
-+#include <linux/config.h>
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -40,96 +25,102 @@
-
- #include <asm/io.h>
-
-+#if !defined (CONFIG_REDWOOD_6)
-+
- #define WINDOW_ADDR 0xffc00000
- #define WINDOW_SIZE 0x00400000
-
--__u8 redwood_flash_read8(struct map_info *map, unsigned long ofs)
--{
-- return *(__u8 *)(map->map_priv_1 + ofs);
--}
--
--__u16 redwood_flash_read16(struct map_info *map, unsigned long ofs)
--{
-- return *(__u16 *)(map->map_priv_1 + ofs);
--}
--
--__u32 redwood_flash_read32(struct map_info *map, unsigned long ofs)
--{
-- return *(volatile unsigned int *)(map->map_priv_1 + ofs);
--}
--
--void redwood_flash_copy_from(struct map_info *map, void *to,
-- unsigned long from, ssize_t len)
--{
-- memcpy(to, (void *)(map->map_priv_1 + from), len);
--}
--
--void redwood_flash_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- *(__u8 *)(map->map_priv_1 + adr) = d;
--}
--
--void redwood_flash_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- *(__u16 *)(map->map_priv_1 + adr) = d;
--}
--
--void redwood_flash_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- *(__u32 *)(map->map_priv_1 + adr) = d;
--}
--
--void redwood_flash_copy_to(struct map_info *map, unsigned long to,
-- const void *from, ssize_t len)
--{
-- memcpy((void *)(map->map_priv_1 + to), from, len);
--}
-+#define RW_PART0_OF 0
-+#define RW_PART0_SZ 0x10000
-+#define RW_PART1_OF RW_PART0_SZ
-+#define RW_PART1_SZ 0x200000 - 0x10000
-+#define RW_PART2_OF 0x200000
-+#define RW_PART2_SZ 0x10000
-+#define RW_PART3_OF 0x210000
-+#define RW_PART3_SZ 0x200000 - (0x10000 + 0x20000)
-+#define RW_PART4_OF 0x3e0000
-+#define RW_PART4_SZ 0x20000
-
--struct map_info redwood_flash_map = {
-- name: "IBM Redwood",
-- size: WINDOW_SIZE,
-- buswidth: 2,
-- read8: redwood_flash_read8,
-- read16: redwood_flash_read16,
-- read32: redwood_flash_read32,
-- copy_from: redwood_flash_copy_from,
-- write8: redwood_flash_write8,
-- write16: redwood_flash_write16,
-- write32: redwood_flash_write32,
-- copy_to: redwood_flash_copy_to
-+static struct mtd_partition redwood_flash_partitions[] = {
-+ {
-+ .name = "Redwood OpenBIOS Vital Product Data",
-+ .offset = RW_PART0_OF,
-+ .size = RW_PART0_SZ,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
-+ },
-+ {
-+ .name = "Redwood kernel",
-+ .offset = RW_PART1_OF,
-+ .size = RW_PART1_SZ
-+ },
-+ {
-+ .name = "Redwood OpenBIOS non-volatile storage",
-+ .offset = RW_PART2_OF,
-+ .size = RW_PART2_SZ,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
-+ },
-+ {
-+ .name = "Redwood filesystem",
-+ .offset = RW_PART3_OF,
-+ .size = RW_PART3_SZ
-+ },
-+ {
-+ .name = "Redwood OpenBIOS",
-+ .offset = RW_PART4_OF,
-+ .size = RW_PART4_SZ,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
-+ }
- };
-
-+#else /* CONFIG_REDWOOD_6 */
-+/* FIXME: the window is bigger - armin */
-+#define WINDOW_ADDR 0xff800000
-+#define WINDOW_SIZE 0x00800000
-+
-+#define RW_PART0_OF 0
-+#define RW_PART0_SZ 0x400000 /* 4 MiB data */
-+#define RW_PART1_OF RW_PART0_OF + RW_PART0_SZ
-+#define RW_PART1_SZ 0x10000 /* 64K VPD */
-+#define RW_PART2_OF RW_PART1_OF + RW_PART1_SZ
-+#define RW_PART2_SZ 0x400000 - (0x10000 + 0x20000)
-+#define RW_PART3_OF RW_PART2_OF + RW_PART2_SZ
-+#define RW_PART3_SZ 0x20000
-
- static struct mtd_partition redwood_flash_partitions[] = {
- {
-- name: "Redwood OpenBIOS Vital Product Data",
-- offset: 0,
-- size: 0x10000,
-- mask_flags: MTD_WRITEABLE /* force read-only */
-+ .name = "Redwood filesystem",
-+ .offset = RW_PART0_OF,
-+ .size = RW_PART0_SZ
- },
- {
-- name: "Redwood kernel",
-- offset: 0x10000,
-- size: 0x200000 - 0x10000
-+ .name = "Redwood OpenBIOS Vital Product Data",
-+ .offset = RW_PART1_OF,
-+ .size = RW_PART1_SZ,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
- },
- {
-- name: "Redwood OpenBIOS non-volatile storage",
-- offset: 0x200000,
-- size: 0x10000,
-- mask_flags: MTD_WRITEABLE /* force read-only */
-+ .name = "Redwood kernel",
-+ .offset = RW_PART2_OF,
-+ .size = RW_PART2_SZ
- },
- {
-- name: "Redwood filesystem",
-- offset: 0x210000,
-- size: 0x200000 - (0x10000 + 0x20000)
-- },
-- {
-- name: "Redwood OpenBIOS",
-- offset: 0x3e0000,
-- size: 0x20000,
-- mask_flags: MTD_WRITEABLE /* force read-only */
-+ .name = "Redwood OpenBIOS",
-+ .offset = RW_PART3_OF,
-+ .size = RW_PART3_SZ,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
- }
- };
-+
-+#endif /* CONFIG_REDWOOD_6 */
-+
-+struct map_info redwood_flash_map = {
-+ .name = "IBM Redwood",
-+ .size = WINDOW_SIZE,
-+ .buswidth = 2,
-+ .phys = WINDOW_ADDR,
-+};
-+
-+
- #define NUM_REDWOOD_FLASH_PARTITIONS \
- (sizeof(redwood_flash_partitions)/sizeof(redwood_flash_partitions[0]))
-
-@@ -140,18 +131,19 @@
- printk(KERN_NOTICE "redwood: flash mapping: %x at %x\n",
- WINDOW_SIZE, WINDOW_ADDR);
-
-- redwood_flash_map.map_priv_1 =
-+ redwood_flash_map.virt =
- (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-
-- if (!redwood_flash_map.map_priv_1) {
-+ if (!redwood_flash_map.virt) {
- printk("init_redwood_flash: failed to ioremap\n");
- return -EIO;
- }
-+ simple_map_init(&redwood_flash_map);
-
- redwood_mtd = do_map_probe("cfi_probe",&redwood_flash_map);
-
- if (redwood_mtd) {
-- redwood_mtd->module = THIS_MODULE;
-+ redwood_mtd->owner = THIS_MODULE;
- return add_mtd_partitions(redwood_mtd,
- redwood_flash_partitions,
- NUM_REDWOOD_FLASH_PARTITIONS);
-@@ -164,10 +156,15 @@
- {
- if (redwood_mtd) {
- del_mtd_partitions(redwood_mtd);
-- iounmap((void *)redwood_flash_map.map_priv_1);
-+ /* moved iounmap after map_destroy - armin */
- map_destroy(redwood_mtd);
-+ iounmap((void *)redwood_flash_map.virt);
- }
- }
-
- module_init(init_redwood_flash);
- module_exit(cleanup_redwood_flash);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("MontaVista Software <source@mvista.com>");
-+MODULE_DESCRIPTION("MTD map driver for the IBM Redwood reference boards");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/rpxlite.c linux/drivers/mtd/maps/rpxlite.c
---- linux-mips-2.4.27/drivers/mtd/maps/rpxlite.c 2001-11-05 21:15:52.000000000 +0100
-+++ linux/drivers/mtd/maps/rpxlite.c 2004-11-19 10:25:11.963190064 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Handle mapping of the flash on the RPX Lite and CLLF boards
- */
-@@ -7,6 +7,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -17,80 +18,31 @@
-
- static struct mtd_info *mymtd;
-
--__u8 rpxlite_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--__u16 rpxlite_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--__u32 rpxlite_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void rpxlite_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
--}
--
--void rpxlite_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void rpxlite_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void rpxlite_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void rpxlite_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio((void *)(map->map_priv_1 + to), from, len);
--}
--
--struct map_info rpxlite_map = {
-- name: "RPX",
-- size: WINDOW_SIZE,
-- buswidth: 4,
-- read8: rpxlite_read8,
-- read16: rpxlite_read16,
-- read32: rpxlite_read32,
-- copy_from: rpxlite_copy_from,
-- write8: rpxlite_write8,
-- write16: rpxlite_write16,
-- write32: rpxlite_write32,
-- copy_to: rpxlite_copy_to
-+static struct map_info rpxlite_map = {
-+ .name = "RPX",
-+ .size = WINDOW_SIZE,
-+ .buswidth = 4,
-+ .phys = WINDOW_ADDR,
- };
-
- int __init init_rpxlite(void)
- {
- printk(KERN_NOTICE "RPX Lite or CLLF flash device: %x at %x\n", WINDOW_SIZE*4, WINDOW_ADDR);
-- rpxlite_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4);
-+ rpxlite_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE * 4);
-
-- if (!rpxlite_map.map_priv_1) {
-+ if (!rpxlite_map.virt) {
- printk("Failed to ioremap\n");
- return -EIO;
- }
-+ simple_map_init(&rpxlite_map);
- mymtd = do_map_probe("cfi_probe", &rpxlite_map);
- if (mymtd) {
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
- add_mtd_device(mymtd);
- return 0;
- }
-
-- iounmap((void *)rpxlite_map.map_priv_1);
-+ iounmap((void *)rpxlite_map.virt);
- return -ENXIO;
- }
-
-@@ -100,9 +52,9 @@
- del_mtd_device(mymtd);
- map_destroy(mymtd);
- }
-- if (rpxlite_map.map_priv_1) {
-- iounmap((void *)rpxlite_map.map_priv_1);
-- rpxlite_map.map_priv_1 = 0;
-+ if (rpxlite_map.virt) {
-+ iounmap((void *)rpxlite_map.virt);
-+ rpxlite_map.virt = 0;
- }
- }
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/sa1100-flash.c linux/drivers/mtd/maps/sa1100-flash.c
---- linux-mips-2.4.27/drivers/mtd/maps/sa1100-flash.c 2003-02-26 01:53:50.000000000 +0100
-+++ linux/drivers/mtd/maps/sa1100-flash.c 2004-11-19 10:25:11.966189608 +0100
-@@ -3,7 +3,7 @@
- *
- * (C) 2000 Nicolas Pitre <nico@cam.org>
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
-@@ -11,278 +11,212 @@
- #include <linux/types.h>
- #include <linux/ioport.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/slab.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/partitions.h>
-+#include <linux/mtd/concat.h>
-
- #include <asm/hardware.h>
-+#include <asm/mach-types.h>
- #include <asm/io.h>
-+#include <asm/sizes.h>
-
-+#include <asm/arch/h3600.h>
-
- #ifndef CONFIG_ARCH_SA1100
- #error This is for SA1100 architecture only
- #endif
-
-+/*
-+ * This isnt complete yet, so...
-+ */
-+#define CONFIG_MTD_SA1100_STATICMAP 1
-
--#define WINDOW_ADDR 0xe8000000
--
--static __u8 sa1100_read8(struct map_info *map, unsigned long ofs)
--{
-- return readb(map->map_priv_1 + ofs);
--}
--
--static __u16 sa1100_read16(struct map_info *map, unsigned long ofs)
--{
-- return readw(map->map_priv_1 + ofs);
--}
--
--static __u32 sa1100_read32(struct map_info *map, unsigned long ofs)
--{
-- return readl(map->map_priv_1 + ofs);
--}
--
--static void sa1100_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy(to, (void *)(map->map_priv_1 + from), len);
--}
--
--static void sa1100_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- writeb(d, map->map_priv_1 + adr);
--}
--
--static void sa1100_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- writew(d, map->map_priv_1 + adr);
--}
--
--static void sa1100_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- writel(d, map->map_priv_1 + adr);
--}
--
--static void sa1100_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy((void *)(map->map_priv_1 + to), from, len);
--}
--
--static struct map_info sa1100_map = {
-- name: "SA1100 flash",
-- read8: sa1100_read8,
-- read16: sa1100_read16,
-- read32: sa1100_read32,
-- copy_from: sa1100_copy_from,
-- write8: sa1100_write8,
-- write16: sa1100_write16,
-- write32: sa1100_write32,
-- copy_to: sa1100_copy_to,
--
-- map_priv_1: WINDOW_ADDR,
-- map_priv_2: -1,
--};
--
--
-+#ifdef CONFIG_MTD_SA1100_STATICMAP
- /*
- * Here are partition information for all known SA1100-based devices.
- * See include/linux/mtd/partitions.h for definition of the mtd_partition
- * structure.
- *
-- * The *_max_flash_size is the maximum possible mapped flash size which
-- * is not necessarily the actual flash size. It must be no more than
-- * the value specified in the "struct map_desc *_io_desc" mapping
-- * definition for the corresponding machine.
-+ * Please note:
-+ * 1. We no longer support static flash mappings via the machine io_desc
-+ * structure.
-+ * 2. The flash size given should be the largest flash size that can
-+ * be accommodated.
-+ *
-+ * The MTD layer will detect flash chip aliasing and reduce the size of
-+ * the map accordingly.
- *
- * Please keep these in alphabetical order, and formatted as per existing
- * entries. Thanks.
- */
-
- #ifdef CONFIG_SA1100_ADSBITSY
--#define ADSBITSY_FLASH_SIZE 0x02000000
- static struct mtd_partition adsbitsy_partitions[] = {
- {
-- name: "bootROM",
-- size: 0x80000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "zImage",
-- size: 0x100000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "ramdisk.gz",
-- size: 0x300000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "User FS",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "bootROM",
-+ .size = 0x80000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "zImage",
-+ .size = 0x100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "ramdisk.gz",
-+ .size = 0x300000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "User FS",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_ASSABET
- /* Phase 4 Assabet has two 28F160B3 flash parts in bank 0: */
--#define ASSABET4_FLASH_SIZE 0x00400000
- static struct mtd_partition assabet4_partitions[] = {
- {
-- name: "bootloader",
-- size: 0x00020000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "bootloader params",
-- size: 0x00020000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "jffs",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "bootloader",
-+ .size = 0x00020000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "bootloader params",
-+ .size = 0x00020000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "jffs",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
-
- /* Phase 5 Assabet has two 28F128J3A flash parts in bank 0: */
--#define ASSABET5_FLASH_SIZE 0x02000000
- static struct mtd_partition assabet5_partitions[] = {
- {
-- name: "bootloader",
-- size: 0x00040000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "bootloader params",
-- size: 0x00040000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "jffs",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "bootloader",
-+ .size = 0x00040000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "bootloader params",
-+ .size = 0x00040000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "jffs",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
-
--#define ASSABET_FLASH_SIZE ASSABET5_FLASH_SIZE
- #define assabet_partitions assabet5_partitions
- #endif
-
- #ifdef CONFIG_SA1100_BADGE4
--
- /*
-- * 1 x Intel 28F320C3BA100 Advanced+ Boot Block Flash (32 Mi bit)
-+ * 1 x Intel 28F320C3 Advanced+ Boot Block Flash (32 Mi bit)
- * Eight 4 KiW Parameter Bottom Blocks (64 KiB)
- * Sixty-three 32 KiW Main Blocks (4032 Ki b)
-+ *
-+ * <or>
-+ *
-+ * 1 x Intel 28F640C3 Advanced+ Boot Block Flash (64 Mi bit)
-+ * Eight 4 KiW Parameter Bottom Blocks (64 KiB)
-+ * One-hundred-twenty-seven 32 KiW Main Blocks (8128 Ki b)
- */
--#define BADGE4_FLASH_SIZE 0x00400000
- static struct mtd_partition badge4_partitions[] = {
- {
-- name: "BLOB boot loader",
-- offset: 0,
-- size: 0x0000A000
-- }, {
-- name: "params",
-- offset: MTDPART_OFS_APPEND,
-- size: 0x00006000
-- }, {
-- name: "kernel",
-- offset: MTDPART_OFS_APPEND,
-- size: 0x00100000
-- }, {
-- name: "root",
-- offset: MTDPART_OFS_APPEND,
-- size: MTDPART_SIZ_FULL
-+ .name = "BLOB boot loader",
-+ .offset = 0,
-+ .size = 0x0000A000
-+ }, {
-+ .name = "params",
-+ .offset = MTDPART_OFS_APPEND,
-+ .size = 0x00006000
-+ }, {
-+ .name = "root",
-+ .offset = MTDPART_OFS_APPEND,
-+ .size = MTDPART_SIZ_FULL
- }
- };
--
- #endif
-
-
- #ifdef CONFIG_SA1100_CERF
- #ifdef CONFIG_SA1100_CERF_FLASH_32MB
--#define CERF_FLASH_SIZE 0x02000000
--static struct mtd_partition cerf_partitions[] = {
-- {
-- name: "firmware",
-- size: 0x00040000,
-- offset: 0,
-- }, {
-- name: "params",
-- size: 0x00040000,
-- offset: 0x00040000,
-- }, {
-- name: "kernel",
-- size: 0x00100000,
-- offset: 0x00080000,
-- }, {
-- name: "rootdisk",
-- size: 0x01E80000,
-- offset: 0x00180000,
-- }
--};
-+# define CERF_FLASH_SIZE 0x02000000
- #elif defined CONFIG_SA1100_CERF_FLASH_16MB
--#define CERF_FLASH_SIZE 0x01000000
-+# define CERF_FLASH_SIZE 0x01000000
-+#elif defined CONFIG_SA1100_CERF_FLASH_8MB
-+# define CERF_FLASH_SIZE 0x00800000
-+#else
-+# error "Undefined flash size for CERF in sa1100-flash.c"
-+#endif
-+
- static struct mtd_partition cerf_partitions[] = {
- {
-- name: "firmware",
-- size: 0x00020000,
-- offset: 0,
-- }, {
-- name: "params",
-- size: 0x00020000,
-- offset: 0x00020000,
-- }, {
-- name: "kernel",
-- size: 0x00100000,
-- offset: 0x00040000,
-- }, {
-- name: "rootdisk",
-- size: 0x00EC0000,
-- offset: 0x00140000,
-+ .name = "Bootloader",
-+ .size = 0x00020000,
-+ .offset = 0x00000000,
-+ }, {
-+ .name = "Params",
-+ .size = 0x00040000,
-+ .offset = 0x00020000,
-+ }, {
-+ .name = "Kernel",
-+ .size = 0x00100000,
-+ .offset = 0x00060000,
-+ }, {
-+ .name = "Filesystem",
-+ .size = CERF_FLASH_SIZE-0x00160000,
-+ .offset = 0x00160000,
- }
- };
--#elif defined CONFIG_SA1100_CERF_FLASH_8MB
--# error "Unwritten type definition"
--#else
--# error "Undefined memory orientation for CERF in sa1100-flash.c"
--#endif
- #endif
-
- #ifdef CONFIG_SA1100_CONSUS
--#define CONSUS_FLASH_SIZE 0x02000000
- static struct mtd_partition consus_partitions[] = {
- {
-- name: "Consus boot firmware",
-- offset: 0,
-- size: 0x00040000,
-- mask_flags: MTD_WRITABLE, /* force read-only */
-- }, {
-- name: "Consus kernel",
-- offset: 0x00040000,
-- size: 0x00100000,
-- mask_flags: 0,
-+ .name = "Consus boot firmware",
-+ .offset = 0,
-+ .size = 0x00040000,
-+ .mask_flags = MTD_WRITABLE, /* force read-only */
-+ }, {
-+ .name = "Consus kernel",
-+ .offset = 0x00040000,
-+ .size = 0x00100000,
-+ .mask_flags = 0,
- }, {
-- name: "Consus disk",
-- offset: 0x00140000,
-+ .name = "Consus disk",
-+ .offset = 0x00140000,
- /* The rest (up to 16M) for jffs. We could put 0 and
- make it find the size automatically, but right now
- i have 32 megs. jffs will use all 32 megs if given
- the chance, and this leads to horrible problems
- when you try to re-flash the image because blob
- won't erase the whole partition. */
-- size: 0x01000000 - 0x00140000,
-- mask_flags: 0,
-+ .size = 0x01000000 - 0x00140000,
-+ .mask_flags = 0,
- }, {
- /* this disk is a secondary disk, which can be used as
- needed, for simplicity, make it the size of the other
- consus partition, although realistically it could be
- the remainder of the disk (depending on the file
- system used) */
-- name: "Consus disk2",
-- offset: 0x01000000,
-- size: 0x01000000 - 0x00140000,
-- mask_flags: 0,
-+ .name = "Consus disk2",
-+ .offset = 0x01000000,
-+ .size = 0x01000000 - 0x00140000,
-+ .mask_flags = 0,
- }
- };
- #endif
-@@ -292,96 +226,95 @@
- #define FLEXANET_FLASH_SIZE 0x02000000
- static struct mtd_partition flexanet_partitions[] = {
- {
-- name: "bootloader",
-- size: 0x00040000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "bootloader params",
-- size: 0x00040000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "kernel",
-- size: 0x000C0000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "altkernel",
-- size: 0x000C0000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "root",
-- size: 0x00400000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "free1",
-- size: 0x00300000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "free2",
-- size: 0x00300000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-- }, {
-- name: "free3",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE,
-+ .name = "bootloader",
-+ .size = 0x00040000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "bootloader params",
-+ .size = 0x00040000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "kernel",
-+ .size = 0x000C0000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "altkernel",
-+ .size = 0x000C0000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "root",
-+ .size = 0x00400000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "free1",
-+ .size = 0x00300000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "free2",
-+ .size = 0x00300000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
-+ }, {
-+ .name = "free3",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE,
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_FREEBIRD
--#define FREEBIRD_FLASH_SIZE 0x02000000
- static struct mtd_partition freebird_partitions[] = {
--#if CONFIG_SA1100_FREEBIRD_NEW
-+#ifdef CONFIG_SA1100_FREEBIRD_NEW
- {
-- name: "firmware",
-- size: 0x00040000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "kernel",
-- size: 0x00080000,
-- offset: 0x00040000,
-- }, {
-- name: "params",
-- size: 0x00040000,
-- offset: 0x000C0000,
-- }, {
-- name: "initrd",
-- size: 0x00100000,
-- offset: 0x00100000,
-- }, {
-- name: "root cramfs",
-- size: 0x00300000,
-- offset: 0x00200000,
-- }, {
-- name: "usr cramfs",
-- size: 0x00C00000,
-- offset: 0x00500000,
-- }, {
-- name: "local",
-- size: MTDPART_SIZ_FULL,
-- offset: 0x01100000,
-+ .name = "firmware",
-+ .size = 0x00040000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "kernel",
-+ .size = 0x00080000,
-+ .offset = 0x00040000,
-+ }, {
-+ .name = "params",
-+ .size = 0x00040000,
-+ .offset = 0x000C0000,
-+ }, {
-+ .name = "initrd",
-+ .size = 0x00100000,
-+ .offset = 0x00100000,
-+ }, {
-+ .name = "root cramfs",
-+ .size = 0x00300000,
-+ .offset = 0x00200000,
-+ }, {
-+ .name = "usr cramfs",
-+ .size = 0x00C00000,
-+ .offset = 0x00500000,
-+ }, {
-+ .name = "local",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = 0x01100000,
- }
- #else
- {
-- size: 0x00040000,
-- offset: 0,
-+ .size = 0x00040000,
-+ .offset = 0,
- }, {
-- size: 0x000c0000,
-- offset: MTDPART_OFS_APPEND,
-+ .size = 0x000c0000,
-+ .offset = MTDPART_OFS_APPEND,
- }, {
-- size: 0x00400000,
-- offset: MTDPART_OFS_APPEND,
-+ .size = 0x00400000,
-+ .offset = MTDPART_OFS_APPEND,
- }, {
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- #endif
- };
-@@ -389,178 +322,215 @@
-
- #ifdef CONFIG_SA1100_FRODO
- /* Frodo has 2 x 16M 28F128J3A flash chips in bank 0: */
--#define FRODO_FLASH_SIZE 0x02000000
- static struct mtd_partition frodo_partitions[] =
- {
- {
-- name: "Boot Loader",
-- size: 0x00040000,
-- offset: 0x00000000
-- }, {
-- name: "Parameter Block",
-- size: 0x00040000,
-- offset: MTDPART_OFS_APPEND
-- }, {
-- name: "Linux Kernel",
-- size: 0x00100000,
-- offset: MTDPART_OFS_APPEND
-- }, {
-- name: "Ramdisk",
-- size: 0x00680000,
-- offset: MTDPART_OFS_APPEND
-- }, {
-- name: "Flash File System",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND
-+ .name = "bootloader",
-+ .size = 0x00040000,
-+ .offset = 0x00000000,
-+ .mask_flags = MTD_WRITEABLE
-+ }, {
-+ .name = "bootloader params",
-+ .size = 0x00040000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE
-+ }, {
-+ .name = "kernel",
-+ .size = 0x00100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE
-+ }, {
-+ .name = "ramdisk",
-+ .size = 0x00400000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE
-+ }, {
-+ .name = "file system",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_GRAPHICSCLIENT
--#define GRAPHICSCLIENT_FLASH_SIZE 0x02000000
- static struct mtd_partition graphicsclient_partitions[] = {
- {
-- name: "zImage",
-- size: 0x100000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "ramdisk.gz",
-- size: 0x300000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "User FS",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "zImage",
-+ .size = 0x100000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "ramdisk.gz",
-+ .size = 0x300000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "User FS",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_GRAPHICSMASTER
--#define GRAPHICSMASTER_FLASH_SIZE 0x01000000
- static struct mtd_partition graphicsmaster_partitions[] = {
- {
-- name: "zImage",
-- size: 0x100000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-+ .name = "zImage",
-+ .size = 0x100000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
- {
-- name: "ramdisk.gz",
-- size: 0x300000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-+ .name = "ramdisk.gz",
-+ .size = 0x300000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
- {
-- name: "User FS",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "User FS",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #endif
-
--#ifdef CONFIG_SA1100_H3600
--#define H3600_FLASH_SIZE 0x02000000
--static struct mtd_partition h3600_partitions[] = {
-+#ifdef CONFIG_SA1100_H3XXX
-+static struct mtd_partition h3xxx_partitions[] = {
- {
-- name: "H3600 boot firmware",
-- size: 0x00040000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "H3600 kernel",
-- size: 0x00080000,
-- offset: 0x00040000,
-+ .name = "H3XXX boot firmware",
-+ .size = 0x00040000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
-- name: "H3600 params",
-- size: 0x00040000,
-- offset: 0x000C0000,
-+#ifdef CONFIG_MTD_2PARTS_IPAQ
-+ .name = "H3XXX root jffs2",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = 0x00040000,
-+#else
-+ .name = "H3XXX kernel",
-+ .size = 0x00080000,
-+ .offset = 0x00040000,
-+ }, {
-+ .name = "H3XXX params",
-+ .size = 0x00040000,
-+ .offset = 0x000C0000,
- }, {
- #ifdef CONFIG_JFFS2_FS
-- name: "H3600 root jffs2",
-- size: MTDPART_SIZ_FULL,
-- offset: 0x00100000,
-+ .name = "H3XXX root jffs2",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = 0x00100000,
- #else
-- name: "H3600 initrd",
-- size: 0x00100000,
-- offset: 0x00100000,
-+ .name = "H3XXX initrd",
-+ .size = 0x00100000,
-+ .offset = 0x00100000,
- }, {
-- name: "H3600 root cramfs",
-- size: 0x00300000,
-- offset: 0x00200000,
-+ .name = "H3XXX root cramfs",
-+ .size = 0x00300000,
-+ .offset = 0x00200000,
- }, {
-- name: "H3600 usr cramfs",
-- size: 0x00800000,
-- offset: 0x00500000,
-+ .name = "H3XXX usr cramfs",
-+ .size = 0x00800000,
-+ .offset = 0x00500000,
- }, {
-- name: "H3600 usr local",
-- size: MTDPART_SIZ_FULL,
-- offset: 0x00d00000,
-+ .name = "H3XXX usr local",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = 0x00d00000,
-+#endif
- #endif
- }
- };
-
--static void h3600_set_vpp(struct map_info *map, int vpp)
-+static void h3xxx_set_vpp(struct map_info *map, int vpp)
- {
- assign_h3600_egpio(IPAQ_EGPIO_VPP_ON, vpp);
- }
-+#else
-+#define h3xxx_set_vpp NULL
-+#endif
-+
-+#ifdef CONFIG_SA1100_HACKKIT
-+static struct mtd_partition hackkit_partitions[] = {
-+ {
-+ .name = "BLOB",
-+ .size = 0x00040000,
-+ .offset = 0x00000000,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "config",
-+ .size = 0x00040000,
-+ .offset = MTDPART_OFS_APPEND,
-+ }, {
-+ .name = "kernel",
-+ .size = 0x00100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ }, {
-+ .name = "initrd",
-+ .size = 0x00180000,
-+ .offset = MTDPART_OFS_APPEND,
-+ }, {
-+ .name = "rootfs",
-+ .size = 0x700000,
-+ .offset = MTDPART_OFS_APPEND,
-+ }, {
-+ .name = "data",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
-+ }
-+};
- #endif
-
- #ifdef CONFIG_SA1100_HUW_WEBPANEL
--#define HUW_WEBPANEL_FLASH_SIZE 0x01000000
- static struct mtd_partition huw_webpanel_partitions[] = {
- {
-- name: "Loader",
-- size: 0x00040000,
-- offset: 0,
-- }, {
-- name: "Sector 1",
-- size: 0x00040000,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "Loader",
-+ .size = 0x00040000,
-+ .offset = 0,
-+ }, {
-+ .name = "Sector 1",
-+ .size = 0x00040000,
-+ .offset = MTDPART_OFS_APPEND,
- }, {
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_JORNADA720
--#define JORNADA720_FLASH_SIZE 0x02000000
- static struct mtd_partition jornada720_partitions[] = {
- {
-- name: "JORNADA720 boot firmware",
-- size: 0x00040000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-+ .name = "JORNADA720 boot firmware",
-+ .size = 0x00040000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
-- name: "JORNADA720 kernel",
-- size: 0x000c0000,
-- offset: 0x00040000,
-+ .name = "JORNADA720 kernel",
-+ .size = 0x000c0000,
-+ .offset = 0x00040000,
- }, {
-- name: "JORNADA720 params",
-- size: 0x00040000,
-- offset: 0x00100000,
-+ .name = "JORNADA720 params",
-+ .size = 0x00040000,
-+ .offset = 0x00100000,
- }, {
-- name: "JORNADA720 initrd",
-- size: 0x00100000,
-- offset: 0x00140000,
-+ .name = "JORNADA720 initrd",
-+ .size = 0x00100000,
-+ .offset = 0x00140000,
- }, {
-- name: "JORNADA720 root cramfs",
-- size: 0x00300000,
-- offset: 0x00240000,
-+ .name = "JORNADA720 root cramfs",
-+ .size = 0x00300000,
-+ .offset = 0x00240000,
- }, {
-- name: "JORNADA720 usr cramfs",
-- size: 0x00800000,
-- offset: 0x00540000,
-+ .name = "JORNADA720 usr cramfs",
-+ .size = 0x00800000,
-+ .offset = 0x00540000,
- }, {
-- name: "JORNADA720 usr local",
-- size: 0 /* will expand to the end of the flash */
-- offset: 0x00d00000,
-+ .name = "JORNADA720 usr local",
-+ .size = 0, /* will expand to the end of the flash */
-+ .offset = 0x00d00000,
- }
- };
-
--static void jornada720_set_vpp(int vpp)
-+static void jornada720_set_vpp(struct map_info *map, int vpp)
- {
- if (vpp)
- PPSR |= 0x80;
-@@ -568,454 +538,811 @@
- PPSR &= ~0x80;
- PPDR |= 0x80;
- }
--
-+#else
-+#define jornada720_set_vpp NULL
- #endif
-
- #ifdef CONFIG_SA1100_PANGOLIN
--#define PANGOLIN_FLASH_SIZE 0x04000000
- static struct mtd_partition pangolin_partitions[] = {
- {
-- name: "boot firmware",
-- size: 0x00080000,
-- offset: 0x00000000,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "kernel",
-- size: 0x00100000,
-- offset: 0x00080000,
-- }, {
-- name: "initrd",
-- size: 0x00280000,
-- offset: 0x00180000,
-- }, {
-- name: "initrd-test",
-- size: 0x03C00000,
-- offset: 0x00400000,
-+ .name = "boot firmware",
-+ .size = 0x00080000,
-+ .offset = 0x00000000,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "kernel",
-+ .size = 0x00100000,
-+ .offset = 0x00080000,
-+ }, {
-+ .name = "initrd",
-+ .size = 0x00280000,
-+ .offset = 0x00180000,
-+ }, {
-+ .name = "initrd-test",
-+ .size = 0x03C00000,
-+ .offset = 0x00400000,
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_PT_SYSTEM3
- /* erase size is 0x40000 == 256k partitions have to have this boundary */
--#define SYSTEM3_FLASH_SIZE 0x01000000
- static struct mtd_partition system3_partitions[] = {
- {
-- name: "BLOB",
-- size: 0x00040000,
-- offset: 0x00000000,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "config",
-- size: 0x00040000,
-- offset: MTDPART_OFS_APPEND,
-- }, {
-- name: "kernel",
-- size: 0x00100000,
-- offset: MTDPART_OFS_APPEND,
-- }, {
-- name: "root",
-- size: MTDPART_SIZ_FULL,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "BLOB",
-+ .size = 0x00040000,
-+ .offset = 0x00000000,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "config",
-+ .size = 0x00040000,
-+ .offset = MTDPART_OFS_APPEND,
-+ }, {
-+ .name = "kernel",
-+ .size = 0x00100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ }, {
-+ .name = "root",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_SHANNON
--#define SHANNON_FLASH_SIZE 0x00400000
- static struct mtd_partition shannon_partitions[] = {
- {
-- name: "BLOB boot loader",
-- offset: 0,
-- size: 0x20000
-+ .name = "BLOB boot loader",
-+ .offset = 0,
-+ .size = 0x20000
- },
- {
-- name: "kernel",
-- offset: MTDPART_OFS_APPEND,
-- size: 0xe0000
-+ .name = "kernel",
-+ .offset = MTDPART_OFS_APPEND,
-+ .size = 0xe0000
- },
- {
-- name: "initrd",
-- offset: MTDPART_OFS_APPEND,
-- size: MTDPART_SIZ_FULL
-+ .name = "initrd",
-+ .offset = MTDPART_OFS_APPEND,
-+ .size = MTDPART_SIZ_FULL
- }
- };
-
- #endif
-
- #ifdef CONFIG_SA1100_SHERMAN
--#define SHERMAN_FLASH_SIZE 0x02000000
- static struct mtd_partition sherman_partitions[] = {
- {
-- size: 0x50000,
-- offset: 0,
-+ .size = 0x50000,
-+ .offset = 0,
- }, {
-- size: 0x70000,
-- offset: MTDPART_OFS_APPEND,
-+ .size = 0x70000,
-+ .offset = MTDPART_OFS_APPEND,
- }, {
-- size: 0x600000,
-- offset: MTDPART_OFS_APPEND,
-+ .size = 0x600000,
-+ .offset = MTDPART_OFS_APPEND,
- }, {
-- size: 0xA0000,
-- offset: MTDPART_OFS_APPEND,
-+ .size = 0xA0000,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_SIMPAD
--#define SIMPAD_FLASH_SIZE 0x02000000
- static struct mtd_partition simpad_partitions[] = {
- {
-- name: "SIMpad boot firmware",
-- size: 0x00080000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "SIMpad kernel",
-- size: 0x00100000,
-- offset: 0x00080000,
-- }, {
--#ifdef CONFIG_JFFS2_FS
-- name: "SIMpad root jffs2",
-- size: MTDPART_SIZ_FULL,
-- offset: 0x00180000,
-+ .name = "SIMpad boot firmware",
-+ .size = 0x00080000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "SIMpad kernel",
-+ .size = 0x00100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ }, {
-+#ifdef CONFIG_ROOT_CRAMFS
-+ .name = "SIMpad root cramfs",
-+ .size =0x00D80000,
-+ .offset = MTDPART_OFS_APPEND
-+
-+ }, {
-+ .name = "SIMpad local jffs2",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND
- #else
-- name: "SIMpad initrd",
-- size: 0x00300000,
-- offset: 0x00180000,
-- }, {
-- name: "SIMpad root cramfs",
-- size: 0x00300000,
-- offset: 0x00480000,
-- }, {
-- name: "SIMpad usr cramfs",
-- size: 0x005c0000,
-- offset: 0x00780000,
-- }, {
-- name: "SIMpad usr local",
-- size: MTDPART_SIZ_FULL,
-- offset: 0x00d40000,
-+ .name = "SIMpad root jffs2",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND
- #endif
- }
- };
- #endif /* CONFIG_SA1100_SIMPAD */
-
- #ifdef CONFIG_SA1100_STORK
--#define STORK_FLASH_SIZE 0x02000000
- static struct mtd_partition stork_partitions[] = {
- {
-- name: "STORK boot firmware",
-- size: 0x00040000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "STORK params",
-- size: 0x00040000,
-- offset: 0x00040000,
-- }, {
-- name: "STORK kernel",
-- size: 0x00100000,
-- offset: 0x00080000,
-+ .name = "STORK boot firmware",
-+ .size = 0x00040000,
-+ .offset = 0,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ .name = "STORK params",
-+ .size = 0x00040000,
-+ .offset = 0x00040000,
-+ }, {
-+ .name = "STORK kernel",
-+ .size = 0x00100000,
-+ .offset = 0x00080000,
- }, {
- #ifdef CONFIG_JFFS2_FS
-- name: "STORK root jffs2",
-- offset: 0x00180000,
-- size: MTDPART_SIZ_FULL,
-+ .name = "STORK root jffs2",
-+ .offset = 0x00180000,
-+ .size = MTDPART_SIZ_FULL,
- #else
-- name: "STORK initrd",
-- size: 0x00100000,
-- offset: 0x00180000,
-- }, {
-- name: "STORK root cramfs",
-- size: 0x00300000,
-- offset: 0x00280000,
-- }, {
-- name: "STORK usr cramfs",
-- size: 0x00800000,
-- offset: 0x00580000,
-- }, {
-- name: "STORK usr local",
-- offset: 0x00d80000,
-- size: MTDPART_SIZ_FULL,
-+ .name = "STORK initrd",
-+ .size = 0x00100000,
-+ .offset = 0x00180000,
-+ }, {
-+ .name = "STORK root cramfs",
-+ .size = 0x00300000,
-+ .offset = 0x00280000,
-+ }, {
-+ .name = "STORK usr cramfs",
-+ .size = 0x00800000,
-+ .offset = 0x00580000,
-+ }, {
-+ .name = "STORK usr local",
-+ .offset = 0x00d80000,
-+ .size = MTDPART_SIZ_FULL,
-+#endif
-+ }
-+};
- #endif
-+
-+#ifdef CONFIG_SA1100_TRIZEPS
-+static struct mtd_partition trizeps_partitions[] = {
-+ {
-+ .name = "Bootloader",
-+ .size = 0x00100000,
-+ .offset = 0,
-+ }, {
-+ .name = "Kernel",
-+ .size = 0x00100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ }, {
-+ .name = "root",
-+ .size = MTDPART_SIZ_FULL,
-+ .offset = MTDPART_OFS_APPEND,
- }
- };
- #endif
-
- #ifdef CONFIG_SA1100_YOPY
--#define YOPY_FLASH_SIZE 0x08000000
- static struct mtd_partition yopy_partitions[] = {
- {
-- name: "boot firmware",
-- size: 0x00040000,
-- offset: 0x00000000,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-+ .name = "boot firmware",
-+ .size = 0x00040000,
-+ .offset = 0x00000000,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
- }, {
-- name: "kernel",
-- size: 0x00080000,
-- offset: 0x00080000,
-+ .name = "kernel",
-+ .size = 0x00080000,
-+ .offset = 0x00080000,
- }, {
-- name: "initrd",
-- size: 0x00300000,
-- offset: 0x00100000,
-+ .name = "initrd",
-+ .size = 0x00300000,
-+ .offset = 0x00100000,
- }, {
-- name: "root",
-- size: 0x01000000,
-- offset: 0x00400000,
-+ .name = "root",
-+ .size = 0x01000000,
-+ .offset = 0x00400000,
- }
- };
- #endif
-
--extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
--extern int parse_bootldr_partitions(struct mtd_info *master, struct mtd_partition **pparts);
--
--static struct mtd_partition *parsed_parts;
--static struct mtd_info *mymtd;
--
--int __init sa1100_mtd_init(void)
-+static int __init sa1100_static_partitions(struct mtd_partition **parts)
- {
-- struct mtd_partition *parts;
-- int nb_parts = 0, ret;
-- int parsed_nr_parts = 0;
-- const char *part_type;
-- unsigned long base = -1UL;
--
-- /* Default flash buswidth */
-- sa1100_map.buswidth = (MSC0 & MSC_RBW) ? 2 : 4;
--
-- /*
-- * Static partition definition selection
-- */
-- part_type = "static";
-+ int nb_parts = 0;
-
- #ifdef CONFIG_SA1100_ADSBITSY
- if (machine_is_adsbitsy()) {
-- parts = adsbitsy_partitions;
-+ *parts = adsbitsy_partitions;
- nb_parts = ARRAY_SIZE(adsbitsy_partitions);
-- sa1100_map.size = ADSBITSY_FLASH_SIZE;
-- sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2 : 4;
- }
- #endif
- #ifdef CONFIG_SA1100_ASSABET
- if (machine_is_assabet()) {
-- parts = assabet_partitions;
-+ *parts = assabet_partitions;
- nb_parts = ARRAY_SIZE(assabet_partitions);
-- sa1100_map.size = ASSABET_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_BADGE4
- if (machine_is_badge4()) {
-- parts = badge4_partitions;
-+ *parts = badge4_partitions;
- nb_parts = ARRAY_SIZE(badge4_partitions);
-- sa1100_map.size = BADGE4_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_CERF
- if (machine_is_cerf()) {
-- parts = cerf_partitions;
-+ *parts = cerf_partitions;
- nb_parts = ARRAY_SIZE(cerf_partitions);
-- sa1100_map.size = CERF_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_CONSUS
- if (machine_is_consus()) {
-- parts = consus_partitions;
-+ *parts = consus_partitions;
- nb_parts = ARRAY_SIZE(consus_partitions);
-- sa1100_map.size = CONSUS_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_FLEXANET
- if (machine_is_flexanet()) {
-- parts = flexanet_partitions;
-+ *parts = flexanet_partitions;
- nb_parts = ARRAY_SIZE(flexanet_partitions);
-- sa1100_map.size = FLEXANET_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_FREEBIRD
- if (machine_is_freebird()) {
-- parts = freebird_partitions;
-+ *parts = freebird_partitions;
- nb_parts = ARRAY_SIZE(freebird_partitions);
-- sa1100_map.size = FREEBIRD_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_FRODO
- if (machine_is_frodo()) {
-- parts = frodo_partitions;
-+ *parts = frodo_partitions;
- nb_parts = ARRAY_SIZE(frodo_partitions);
-- sa1100_map.size = FRODO_FLASH_SIZE;
-- base = 0x00000000;
- }
- #endif
- #ifdef CONFIG_SA1100_GRAPHICSCLIENT
- if (machine_is_graphicsclient()) {
-- parts = graphicsclient_partitions;
-+ *parts = graphicsclient_partitions;
- nb_parts = ARRAY_SIZE(graphicsclient_partitions);
-- sa1100_map.size = GRAPHICSCLIENT_FLASH_SIZE;
-- sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2:4;
- }
- #endif
- #ifdef CONFIG_SA1100_GRAPHICSMASTER
- if (machine_is_graphicsmaster()) {
-- parts = graphicsmaster_partitions;
-+ *parts = graphicsmaster_partitions;
- nb_parts = ARRAY_SIZE(graphicsmaster_partitions);
-- sa1100_map.size = GRAPHICSMASTER_FLASH_SIZE;
-- sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2:4;
- }
- #endif
--#ifdef CONFIG_SA1100_H3600
-- if (machine_is_h3600()) {
-- parts = h3600_partitions;
-- nb_parts = ARRAY_SIZE(h3600_partitions);
-- sa1100_map.size = H3600_FLASH_SIZE;
-- sa1100_map.set_vpp = h3600_set_vpp;
-+#ifdef CONFIG_SA1100_H3XXX
-+ if (machine_is_h3xxx()) {
-+ *parts = h3xxx_partitions;
-+ nb_parts = ARRAY_SIZE(h3xxx_partitions);
-+ }
-+#endif
-+#ifdef CONFIG_SA1100_HACKKIT
-+ if (machine_is_hackkit()) {
-+ *parts = hackkit_partitions;
-+ nb_parts = ARRAY_SIZE(hackkit_partitions);
- }
- #endif
- #ifdef CONFIG_SA1100_HUW_WEBPANEL
- if (machine_is_huw_webpanel()) {
-- parts = huw_webpanel_partitions;
-+ *parts = huw_webpanel_partitions;
- nb_parts = ARRAY_SIZE(huw_webpanel_partitions);
-- sa1100_map.size = HUW_WEBPANEL_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_JORNADA720
- if (machine_is_jornada720()) {
-- parts = jornada720_partitions;
-+ *parts = jornada720_partitions;
- nb_parts = ARRAY_SIZE(jornada720_partitions);
-- sa1100_map.size = JORNADA720_FLASH_SIZE;
-- sa1100_map.set_vpp = jornada720_set_vpp;
- }
- #endif
- #ifdef CONFIG_SA1100_PANGOLIN
- if (machine_is_pangolin()) {
-- parts = pangolin_partitions;
-+ *parts = pangolin_partitions;
- nb_parts = ARRAY_SIZE(pangolin_partitions);
-- sa1100_map.size = PANGOLIN_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_PT_SYSTEM3
- if (machine_is_pt_system3()) {
-- parts = system3_partitions;
-+ *parts = system3_partitions;
- nb_parts = ARRAY_SIZE(system3_partitions);
-- sa1100_map.size = SYSTEM3_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_SHANNON
- if (machine_is_shannon()) {
-- parts = shannon_partitions;
-+ *parts = shannon_partitions;
- nb_parts = ARRAY_SIZE(shannon_partitions);
-- sa1100_map.size = SHANNON_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_SHERMAN
- if (machine_is_sherman()) {
-- parts = sherman_partitions;
-+ *parts = sherman_partitions;
- nb_parts = ARRAY_SIZE(sherman_partitions);
-- sa1100_map.size = SHERMAN_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_SIMPAD
- if (machine_is_simpad()) {
-- parts = simpad_partitions;
-+ *parts = simpad_partitions;
- nb_parts = ARRAY_SIZE(simpad_partitions);
-- sa1100_map.size = SIMPAD_FLASH_SIZE;
- }
- #endif
- #ifdef CONFIG_SA1100_STORK
- if (machine_is_stork()) {
-- parts = stork_partitions;
-+ *parts = stork_partitions;
- nb_parts = ARRAY_SIZE(stork_partitions);
-- sa1100_map.size = STORK_FLASH_SIZE;
-+ }
-+#endif
-+#ifdef CONFIG_SA1100_TRIZEPS
-+ if (machine_is_trizeps()) {
-+ *parts = trizeps_partitions;
-+ nb_parts = ARRAY_SIZE(trizeps_partitions);
- }
- #endif
- #ifdef CONFIG_SA1100_YOPY
- if (machine_is_yopy()) {
-- parts = yopy_partitions;
-+ *parts = yopy_partitions;
- nb_parts = ARRAY_SIZE(yopy_partitions);
-- sa1100_map.size = YOPY_FLASH_SIZE;
- }
- #endif
-
-+ return nb_parts;
-+}
-+#endif
-+
-+struct sa_info {
-+ unsigned long base;
-+ unsigned long size;
-+ int width;
-+ void *vbase;
-+ void (*set_vpp)(struct map_info *, int);
-+ struct map_info *map;
-+ struct mtd_info *mtd;
-+ struct resource *res;
-+};
-+
-+#define NR_SUBMTD 4
-+
-+static struct sa_info info[NR_SUBMTD];
-+
-+static int __init sa1100_setup_mtd(struct sa_info *sa, int nr, struct mtd_info **rmtd)
-+{
-+ struct mtd_info *subdev[nr];
-+ struct map_info *maps;
-+ int i, found = 0, ret = 0;
-+
- /*
-- * For simple flash devices, use ioremap to map the flash.
-+ * Allocate the map_info structs in one go.
- */
-- if (base != (unsigned long)-1) {
-- if (!request_mem_region(base, sa1100_map.size, "flash"))
-- return -EBUSY;
-- sa1100_map.map_priv_2 = base;
-- sa1100_map.map_priv_1 = (unsigned long)
-- ioremap(base, sa1100_map.size);
-+ maps = kmalloc(sizeof(struct map_info) * nr, GFP_KERNEL);
-+ if (!maps)
-+ return -ENOMEM;
-+
-+ memset(maps, 0, sizeof(struct map_info) * nr);
-+
-+ /*
-+ * Claim and then map the memory regions.
-+ */
-+ for (i = 0; i < nr; i++) {
-+ if (sa[i].base == (unsigned long)-1)
-+ break;
-+
-+ sa[i].res = request_mem_region(sa[i].base, sa[i].size, "sa1100 flash");
-+ if (!sa[i].res) {
-+ ret = -EBUSY;
-+ break;
-+ }
-+
-+ sa[i].map = maps + i;
-+
-+ sa[i].vbase = ioremap(sa[i].base, sa[i].size);
-+ if (!sa[i].vbase) {
- ret = -ENOMEM;
-- if (!sa1100_map.map_priv_1)
-- goto out_err;
-+ break;
- }
-
-+ sa[i].map->virt = (unsigned long)sa[i].vbase;
-+ sa[i].map->phys = sa[i].base;
-+ sa[i].map->set_vpp = sa[i].set_vpp;
-+ sa[i].map->buswidth = sa[i].width;
-+ sa[i].map->size = sa[i].size;
-+
-+ simple_map_init(sa[i].map);
-+
- /*
- * Now let's probe for the actual flash. Do it here since
- * specific machine settings might have been set above.
- */
-- printk(KERN_NOTICE "SA1100 flash: probing %d-bit flash bus\n", sa1100_map.buswidth*8);
-- mymtd = do_map_probe("cfi_probe", &sa1100_map);
-+ sa[i].mtd = do_map_probe("cfi_probe", sa[i].map);
-+ if (sa[i].mtd == NULL) {
- ret = -ENXIO;
-- if (!mymtd)
-- goto out_err;
-- mymtd->module = THIS_MODULE;
-+ break;
-+ }
-+ sa[i].mtd->owner = THIS_MODULE;
-+ subdev[i] = sa[i].mtd;
-+
-+ printk(KERN_INFO "SA1100 flash: CFI device at 0x%08lx, %dMiB, "
-+ "%d-bit\n", sa[i].base, sa[i].mtd->size >> 20,
-+ sa[i].width * 8);
-+ found += 1;
-+ }
-
- /*
-- * Dynamic partition selection stuff (might override the static ones)
-+ * ENXIO is special. It means we didn't find a chip when
-+ * we probed. We need to tear down the mapping, free the
-+ * resource and mark it as such.
- */
--#ifdef CONFIG_MTD_REDBOOT_PARTS
-- if (parsed_nr_parts == 0) {
-- int ret = parse_redboot_partitions(mymtd, &parsed_parts);
-+ if (ret == -ENXIO) {
-+ iounmap(sa[i].vbase);
-+ sa[i].vbase = NULL;
-+ release_resource(sa[i].res);
-+ sa[i].res = NULL;
-+ }
-
-- if (ret > 0) {
-- part_type = "RedBoot";
-- parsed_nr_parts = ret;
-+ /*
-+ * If we found one device, don't bother with concat support.
-+ * If we found multiple devices, use concat if we have it
-+ * available, otherwise fail.
-+ */
-+ if (ret == 0 || ret == -ENXIO) {
-+ if (found == 1) {
-+ *rmtd = subdev[0];
-+ ret = 0;
-+ } else if (found > 1) {
-+ /*
-+ * We detected multiple devices. Concatenate
-+ * them together.
-+ */
-+#ifdef CONFIG_MTD_CONCAT
-+ *rmtd = mtd_concat_create(subdev, found,
-+ "sa1100 flash");
-+ if (*rmtd == NULL)
-+ ret = -ENXIO;
-+#else
-+ printk(KERN_ERR "SA1100 flash: multiple devices "
-+ "found but MTD concat support disabled.\n");
-+ ret = -ENXIO;
-+#endif
- }
- }
-+
-+ /*
-+ * If we failed, clean up.
-+ */
-+ if (ret) {
-+ do {
-+ if (sa[i].mtd)
-+ map_destroy(sa[i].mtd);
-+ if (sa[i].vbase)
-+ iounmap(sa[i].vbase);
-+ if (sa[i].res)
-+ release_resource(sa[i].res);
-+ } while (i--);
-+
-+ kfree(maps);
-+ }
-+
-+ return ret;
-+}
-+
-+static void __exit sa1100_destroy_mtd(struct sa_info *sa, struct mtd_info *mtd)
-+{
-+ int i;
-+
-+ del_mtd_partitions(mtd);
-+
-+#ifdef CONFIG_MTD_CONCAT
-+ if (mtd != sa[0].mtd)
-+ mtd_concat_destroy(mtd);
- #endif
--#ifdef CONFIG_MTD_CMDLINE_PARTS
-- if (parsed_nr_parts == 0) {
-- int ret = parse_cmdline_partitions(mymtd, &parsed_parts, "sa1100");
-- if (ret > 0) {
-- part_type = "Command Line";
-- parsed_nr_parts = ret;
-+
-+ for (i = NR_SUBMTD; i >= 0; i--) {
-+ if (sa[i].mtd)
-+ map_destroy(sa[i].mtd);
-+ if (sa[i].vbase)
-+ iounmap(sa[i].vbase);
-+ if (sa[i].res)
-+ release_resource(sa[i].res);
- }
-+ kfree(sa[0].map);
-+}
-+
-+/*
-+ * A Thought: can we automatically detect the flash?
-+ * - Check to see if the region is busy (yes -> failure)
-+ * - Is the MSC setup for flash (no -> failure)
-+ * - Probe for flash
-+ */
-+
-+static struct map_info sa1100_probe_map __initdata = {
-+ .name = "SA1100-flash",
-+};
-+
-+static void __init sa1100_probe_one_cs(unsigned int msc, unsigned long phys)
-+{
-+ struct mtd_info *mtd;
-+
-+ printk(KERN_INFO "* Probing 0x%08lx: MSC = 0x%04x %d bit ",
-+ phys, msc & 0xffff, msc & MSC_RBW ? 16 : 32);
-+
-+ if (check_mem_region(phys, 0x08000000)) {
-+ printk("busy\n");
-+ return;
- }
--#endif
-
-- if (parsed_nr_parts > 0) {
-- parts = parsed_parts;
-- nb_parts = parsed_nr_parts;
-+ if ((msc & 3) == 1) {
-+ printk("wrong type\n");
-+ return;
- }
-
-- if (nb_parts == 0) {
-- printk(KERN_NOTICE "SA1100 flash: no partition info available, registering whole flash at once\n");
-- add_mtd_device(mymtd);
-- } else {
-- printk(KERN_NOTICE "Using %s partition definition\n", part_type);
-- add_mtd_partitions(mymtd, parts, nb_parts);
-+ sa1100_probe_map.buswidth = msc & MSC_RBW ? 2 : 4;
-+ sa1100_probe_map.size = SZ_1M;
-+ sa1100_probe_map.phys = phys;
-+ sa1100_probe_map.virt = (unsigned long)ioremap(phys, SZ_1M);
-+ if (sa1100_probe_map.virt == 0)
-+ goto fail;
-+ simple_map_init(&sa1100_probe_map);
-+
-+ /* Shame cfi_probe blurts out kernel messages... */
-+ mtd = do_map_probe("cfi_probe", &sa1100_probe_map);
-+ if (mtd)
-+ map_destroy(mtd);
-+ iounmap((void *)sa1100_probe_map.virt);
-+
-+ if (!mtd)
-+ goto fail;
-+
-+ printk("pass\n");
-+ return;
-+
-+ fail:
-+ printk("failed\n");
-+}
-+
-+static void __init sa1100_probe_flash(void)
-+{
-+ printk(KERN_INFO "-- SA11xx Flash probe. Please report results.\n");
-+ sa1100_probe_one_cs(MSC0, SA1100_CS0_PHYS);
-+ sa1100_probe_one_cs(MSC0 >> 16, SA1100_CS1_PHYS);
-+ sa1100_probe_one_cs(MSC1, SA1100_CS2_PHYS);
-+ sa1100_probe_one_cs(MSC1 >> 16, SA1100_CS3_PHYS);
-+ sa1100_probe_one_cs(MSC2, SA1100_CS4_PHYS);
-+ sa1100_probe_one_cs(MSC2 >> 16, SA1100_CS5_PHYS);
-+ printk(KERN_INFO "-- SA11xx Flash probe complete.\n");
-+}
-+
-+static int __init sa1100_locate_flash(void)
-+{
-+ int i, nr = -ENODEV;
-+
-+ sa1100_probe_flash();
-+
-+ if (machine_is_adsbitsy()) {
-+ info[0].base = SA1100_CS1_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_assabet()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ info[1].base = SA1100_CS1_PHYS; /* neponset */
-+ info[1].size = SZ_32M;
-+ nr = 2;
-+ }
-+ if (machine_is_badge4()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_64M;
-+ nr = 1;
-+ }
-+ if (machine_is_cerf()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_consus()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_flexanet()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_freebird()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_frodo()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_graphicsclient()) {
-+ info[0].base = SA1100_CS1_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
- }
-- return 0;
-+ if (machine_is_graphicsmaster()) {
-+ info[0].base = SA1100_CS1_PHYS;
-+ info[0].size = SZ_16M;
-+ nr = 1;
-+ }
-+ if (machine_is_h3xxx()) {
-+ info[0].set_vpp = h3xxx_set_vpp;
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_huw_webpanel()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_16M;
-+ nr = 1;
-+ }
-+ if (machine_is_itsy()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_jornada720()) {
-+ info[0].set_vpp = jornada720_set_vpp;
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_nanoengine()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[1].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_pangolin()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_64M;
-+ nr = 1;
-+ }
-+ if (machine_is_pfs168()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_pleb()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_4M;
-+ info[1].base = SA1100_CS1_PHYS;
-+ info[1].size = SZ_4M;
-+ nr = 2;
-+ }
-+ if (machine_is_pt_system3()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_16M;
-+ nr = 1;
-+ }
-+ if (machine_is_shannon()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_4M;
-+ nr = 1;
-+ }
-+ if (machine_is_sherman()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_simpad()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_16M;
-+ info[1].base = SA1100_CS1_PHYS;
-+ info[1].size = SZ_16M;
-+ nr = 2;
-+ }
-+ if (machine_is_stork()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_32M;
-+ nr = 1;
-+ }
-+ if (machine_is_trizeps()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_16M;
-+ nr = 1;
-+ }
-+ if (machine_is_victor()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_2M;
-+ nr = 1;
-+ }
-+ if (machine_is_yopy()) {
-+ info[0].base = SA1100_CS0_PHYS;
-+ info[0].size = SZ_64M;
-+ info[1].base = SA1100_CS1_PHYS;
-+ info[1].size = SZ_64M;
-+ nr = 2;
-+ }
-+
-+ if (nr < 0)
-+ return nr;
-
-- out_err:
-- if (sa1100_map.map_priv_2 != -1) {
-- iounmap((void *)sa1100_map.map_priv_1);
-- release_mem_region(sa1100_map.map_priv_2, sa1100_map.size);
-+ /*
-+ * Retrieve the buswidth from the MSC registers.
-+ * We currently only implement CS0 and CS1 here.
-+ */
-+ for (i = 0; i < nr; i++) {
-+ switch (info[i].base) {
-+ default:
-+ printk(KERN_WARNING "SA1100 flash: unknown base address "
-+ "0x%08lx, assuming CS0\n", info[i].base);
-+ case SA1100_CS0_PHYS:
-+ info[i].width = (MSC0 & MSC_RBW) ? 2 : 4;
-+ break;
-+
-+ case SA1100_CS1_PHYS:
-+ info[i].width = ((MSC0 >> 16) & MSC_RBW) ? 2 : 4;
-+ break;
- }
-- return ret;
-+ }
-+
-+ return nr;
- }
-
--static void __exit sa1100_mtd_cleanup(void)
-+static struct mtd_partition *parsed_parts;
-+const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
-+
-+static void __init sa1100_locate_partitions(struct mtd_info *mtd)
- {
-- if (mymtd) {
-- del_mtd_partitions(mymtd);
-- map_destroy(mymtd);
-- if (parsed_parts)
-- kfree(parsed_parts);
-+ const char *part_type = NULL;
-+ int nr_parts = 0;
-+
-+ do {
-+ /*
-+ * Partition selection stuff.
-+ */
-+#ifdef CONFIG_MTD_PARTITIONS
-+ nr_parts = parse_mtd_partitions(mtd, part_probes, &parsed_parts, 0);
-+ if (nr_parts > 0) {
-+ part_type = "dynamic";
-+ break;
- }
-- if (sa1100_map.map_priv_2 != -1) {
-- iounmap((void *)sa1100_map.map_priv_1);
-- release_mem_region(sa1100_map.map_priv_2, sa1100_map.size);
-+#endif
-+#ifdef CONFIG_MTD_SA1100_STATICMAP
-+ nr_parts = sa1100_static_partitions(&parsed_parts);
-+ if (nr_parts > 0) {
-+ part_type = "static";
-+ break;
- }
-+#endif
-+ } while (0);
-+
-+ if (nr_parts == 0) {
-+ printk(KERN_NOTICE "SA1100 flash: no partition info "
-+ "available, registering whole flash\n");
-+ add_mtd_device(mtd);
-+ } else {
-+ printk(KERN_NOTICE "SA1100 flash: using %s partition "
-+ "definition\n", part_type);
-+ add_mtd_partitions(mtd, parsed_parts, nr_parts);
-+ }
-+
-+ /* Always succeeds. */
-+}
-+
-+static void __exit sa1100_destroy_partitions(void)
-+{
-+ if (parsed_parts)
-+ kfree(parsed_parts);
-+}
-+
-+static struct mtd_info *mymtd;
-+
-+static int __init sa1100_mtd_init(void)
-+{
-+ int ret;
-+ int nr;
-+
-+ nr = sa1100_locate_flash();
-+ if (nr < 0)
-+ return nr;
-+
-+ ret = sa1100_setup_mtd(info, nr, &mymtd);
-+ if (ret == 0)
-+ sa1100_locate_partitions(mymtd);
-+
-+ return ret;
-+}
-+
-+static void __exit sa1100_mtd_cleanup(void)
-+{
-+ sa1100_destroy_mtd(info, mymtd);
-+ sa1100_destroy_partitions();
- }
-
- module_init(sa1100_mtd_init);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/sbc8240.c linux/drivers/mtd/maps/sbc8240.c
---- linux-mips-2.4.27/drivers/mtd/maps/sbc8240.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/maps/sbc8240.c 2004-11-19 10:25:11.967189456 +0100
-@@ -0,0 +1,417 @@
-+/*
-+ * Handle mapping of the flash memory access routines on the SBC8240 board.
-+ *
-+ * Carolyn Smith, Tektronix, Inc.
-+ *
-+ * This code is GPLed
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+/*
-+ * The SBC8240 has 2 flash banks.
-+ * Bank 0 is a 512 KiB AMD AM29F040B; 8 x 64 KiB sectors.
-+ * It contains the U-Boot code (7 sectors) and the environment (1 sector).
-+ * Bank 1 is 4 x 1 MiB AMD AM29LV800BT; 15 x 64 KiB sectors, 1 x 32 KiB sector,
-+ * 2 x 8 KiB sectors, 1 x 16 KiB sectors.
-+ * Both parts are JEDEC compatible.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <asm/io.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/cfi.h>
-+
-+#ifdef CONFIG_MTD_PARTITIONS
-+#include <linux/mtd/partitions.h>
-+#endif
-+
-+#define DEBUG
-+
-+#ifdef DEBUG
-+# define debugk(fmt,args...) printk(fmt ,##args)
-+#else
-+# define debugk(fmt,args...)
-+#endif
-+
-+
-+#define WINDOW_ADDR0 0xFFF00000 /* 512 KiB */
-+#define WINDOW_SIZE0 0x00080000
-+#define BUSWIDTH0 1
-+
-+#define WINDOW_ADDR1 0xFF000000 /* 4 MiB */
-+#define WINDOW_SIZE1 0x00400000
-+#define BUSWIDTH1 8
-+
-+#define MSG_PREFIX "sbc8240:" /* prefix for our printk()'s */
-+#define MTDID "sbc8240-%d" /* for mtdparts= partitioning */
-+
-+
-+static __u8 sbc8240_read8 (struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readb(map->map_priv_1 + ofs);
-+}
-+
-+static __u16 sbc8240_read16 (struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readw(map->map_priv_1 + ofs);
-+}
-+
-+static __u32 sbc8240_read32 (struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readl(map->map_priv_1 + ofs);
-+}
-+
-+unsigned long long result64;
-+
-+static __u64 sbc8240_read64 (struct map_info *map, unsigned long ofs)
-+{
-+ unsigned long flags, msr, saved_msr;
-+ volatile long saved_fr[2];
-+ volatile unsigned long long result;
-+ volatile unsigned long *p;
-+
-+ save_flags(flags);
-+ cli();
-+
-+ /* turn off floating point unavailable exceptions */
-+
-+ __asm__ __volatile__ (
-+ "mfmsr %0"
-+ : "=r" (msr) :);
-+
-+ saved_msr = msr;
-+ msr |= MSR_FP;
-+ msr &= ~(MSR_FE0 | MSR_FE1);
-+
-+ __asm__ __volatile__ (
-+ "mtmsr %0\n"
-+ "isync\n"
-+ : : "r" (msr));
-+
-+ /* read the data via a floating point register */
-+
-+ ofs = map->map_priv_1 + ofs;
-+ p = (unsigned long *) &result64;
-+
-+ __asm__ __volatile__ (
-+ "lfd 1,0(%1)\n"
-+ "stfd 1,0(%0)\n"
-+ : : "r" (p), "r" (ofs)
-+ );
-+
-+ /* restore state */
-+
-+ __asm__ __volatile__ (
-+ "mtmsr %0\n"
-+ "isync\n"
-+ : : "r" (saved_msr));
-+
-+ restore_flags(flags);
-+
-+ p = (unsigned long *) &result64;
-+ debugk("sbc8240_read64 ofs 0x%x result 0x%08x%08x\n", ofs, *p, *(p+1));
-+
-+ return result64;
-+}
-+
-+static void sbc8240_copy_from (struct map_info *map,
-+ void *to, unsigned long from, ssize_t len)
-+{
-+ memcpy_fromio (to, (void *) (map->map_priv_1 + from), len);
-+}
-+
-+static void sbc8240_write8 (struct map_info *map, __u8 d, unsigned long adr)
-+{
-+ __raw_writeb(d, map->map_priv_1 + adr);
-+ mb();
-+}
-+
-+static void sbc8240_write16 (struct map_info *map, __u16 d,
-+ unsigned long adr)
-+{
-+ __raw_writew(d, map->map_priv_1 + adr);
-+ mb();
-+}
-+
-+static void sbc8240_write32 (struct map_info *map, __u32 d,
-+ unsigned long adr)
-+{
-+ __raw_writel(d, map->map_priv_1 + adr);
-+ mb();
-+}
-+
-+static void sbc8240_write64 (struct map_info *map, __u64 data,
-+ unsigned long adr)
-+{
-+ unsigned long long tmp;
-+ unsigned long flags, msr, saved_msr, *p;
-+ volatile long saved_fr[2];
-+
-+ save_flags(flags);
-+ cli();
-+
-+ /* turn off floating point unavailable exceptions */
-+
-+ __asm__ __volatile__ (
-+ "mfmsr %0"
-+ : "=r" (msr) :);
-+
-+ saved_msr = msr;
-+ msr |= MSR_FP;
-+ msr &= ~(MSR_FE0 | MSR_FE1);
-+
-+ __asm__ __volatile__ (
-+ "mtmsr %0\n"
-+ "isync\n"
-+ : : "r" (msr));
-+
-+
-+ /* write the data via a floating point register */
-+
-+ tmp = data;
-+ p = (unsigned long *) &tmp;
-+ adr = map->map_priv_1 + adr;
-+ debugk("sbc8240_write64 adr 0x%x data 0x%08x%08x\n", adr, *p, *(p+1));
-+
-+ __asm__ __volatile__ (
-+ "stfd 1,0(%2)\n"
-+ "lfd 1,0(%0)\n"
-+ "stfd 1,0(%1)\n"
-+ "lfd 1,0(%2)\n"
-+ : : "r" (p), "r" (adr), "b" (saved_fr)
-+ );
-+
-+ /* restore state */
-+
-+ __asm__ __volatile__ (
-+ "mtmsr %0\n"
-+ "isync\n"
-+ : : "r" (saved_msr));
-+
-+ restore_flags(flags);
-+}
-+
-+static void sbc8240_copy_to (struct map_info *map,
-+ unsigned long to, const void *from, ssize_t len)
-+{
-+ memcpy_toio ((void *) (map->map_priv_1 + to), from, len);
-+}
-+
-+static struct map_info sbc8240_map[2] = {
-+ {
-+ .name = "sbc8240 Flash Bank #0",
-+ .size = WINDOW_SIZE0,
-+ .buswidth = BUSWIDTH0,
-+ .read8 = sbc8240_read8,
-+ .read16 = sbc8240_read16,
-+ .read32 = sbc8240_read32,
-+ .read64 = sbc8240_read64,
-+ .copy_from = sbc8240_copy_from,
-+ .write8 = sbc8240_write8,
-+ .write16 = sbc8240_write16,
-+ .write32 = sbc8240_write32,
-+ .write64 = sbc8240_write64,
-+ .copy_to = sbc8240_copy_to
-+ },
-+ {
-+ .name = "sbc8240 Flash Bank #1",
-+ .size = WINDOW_SIZE1,
-+ .buswidth = BUSWIDTH1,
-+ .read8 = sbc8240_read8,
-+ .read16 = sbc8240_read16,
-+ .read32 = sbc8240_read32,
-+ .read64 = sbc8240_read64,
-+ .copy_from = sbc8240_copy_from,
-+ .write8 = sbc8240_write8,
-+ .write16 = sbc8240_write16,
-+ .write32 = sbc8240_write32,
-+ .write64 = sbc8240_write64,
-+ .copy_to = sbc8240_copy_to
-+ }
-+};
-+
-+#define NUM_FLASH_BANKS (sizeof(sbc8240_map) / sizeof(struct map_info))
-+
-+/*
-+ * The following defines the partition layout of SBC8240 boards.
-+ *
-+ * See include/linux/mtd/partitions.h for definition of the
-+ * mtd_partition structure.
-+ *
-+ * The *_max_flash_size is the maximum possible mapped flash size
-+ * which is not necessarily the actual flash size. It must correspond
-+ * to the value specified in the mapping definition defined by the
-+ * "struct map_desc *_io_desc" for the corresponding machine.
-+ */
-+
-+#ifdef CONFIG_MTD_PARTITIONS
-+
-+static struct mtd_partition sbc8240_uboot_partitions [] = {
-+ /* Bank 0 */
-+ {
-+ .name = "U-boot", /* U-Boot Firmware */
-+ .offset = 0,
-+ .size = 0x00070000, /* 7 x 64 KiB sectors */
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
-+ },
-+ {
-+ .name = "environment", /* U-Boot environment */
-+ .offset = 0x00070000,
-+ .size = 0x00010000, /* 1 x 64 KiB sector */
-+ },
-+};
-+
-+static struct mtd_partition sbc8240_fs_partitions [] = {
-+ {
-+ .name = "jffs", /* JFFS filesystem */
-+ .offset = 0,
-+ .size = 0x003C0000, /* 4 * 15 * 64KiB */
-+ },
-+ {
-+ .name = "tmp32",
-+ .offset = 0x003C0000,
-+ .size = 0x00020000, /* 4 * 32KiB */
-+ },
-+ {
-+ .name = "tmp8a",
-+ .offset = 0x003E0000,
-+ .size = 0x00008000, /* 4 * 8KiB */
-+ },
-+ {
-+ .name = "tmp8b",
-+ .offset = 0x003E8000,
-+ .size = 0x00008000, /* 4 * 8KiB */
-+ },
-+ {
-+ .name = "tmp16",
-+ .offset = 0x003F0000,
-+ .size = 0x00010000, /* 4 * 16KiB */
-+ }
-+};
-+
-+#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
-+
-+/* trivial struct to describe partition information */
-+struct mtd_part_def
-+{
-+ int nums;
-+ unsigned char *type;
-+ struct mtd_partition* mtd_part;
-+};
-+
-+static struct mtd_info *sbc8240_mtd[NUM_FLASH_BANKS];
-+static struct mtd_part_def sbc8240_part_banks[NUM_FLASH_BANKS];
-+
-+
-+#endif /* CONFIG_MTD_PARTITIONS */
-+
-+
-+int __init init_sbc8240_mtd (void)
-+{
-+ static struct _cjs {
-+ u_long addr;
-+ u_long size;
-+ } pt[NUM_FLASH_BANKS] = {
-+ {
-+ .addr = WINDOW_ADDR0,
-+ .size = WINDOW_SIZE0
-+ },
-+ {
-+ .addr = WINDOW_ADDR1,
-+ .size = WINDOW_SIZE1
-+ },
-+ };
-+
-+ int devicesfound = 0;
-+ int i;
-+
-+ for (i = 0; i < NUM_FLASH_BANKS; i++) {
-+ printk (KERN_NOTICE MSG_PREFIX
-+ "Probing 0x%08lx at 0x%08lx\n", pt[i].size, pt[i].addr);
-+
-+ sbc8240_map[i].map_priv_1 =
-+ (unsigned long) ioremap (pt[i].addr, pt[i].size);
-+ if (!sbc8240_map[i].map_priv_1) {
-+ printk (MSG_PREFIX "failed to ioremap\n");
-+ return -EIO;
-+ }
-+
-+ sbc8240_mtd[i] = do_map_probe("jedec_probe", &sbc8240_map[i]);
-+
-+ if (sbc8240_mtd[i]) {
-+ sbc8240_mtd[i]->module = THIS_MODULE;
-+ devicesfound++;
-+ }
-+ }
-+
-+ if (!devicesfound) {
-+ printk(KERN_NOTICE MSG_PREFIX
-+ "No suppported flash chips found!\n");
-+ return -ENXIO;
-+ }
-+
-+#ifdef CONFIG_MTD_PARTITIONS
-+ sbc8240_part_banks[0].mtd_part = sbc8240_uboot_partitions;
-+ sbc8240_part_banks[0].type = "static image";
-+ sbc8240_part_banks[0].nums = NB_OF(sbc8240_uboot_partitions);
-+ sbc8240_part_banks[1].mtd_part = sbc8240_fs_partitions;
-+ sbc8240_part_banks[1].type = "static file system";
-+ sbc8240_part_banks[1].nums = NB_OF(sbc8240_fs_partitions);
-+
-+ for (i = 0; i < NUM_FLASH_BANKS; i++) {
-+
-+ if (!sbc8240_mtd[i]) continue;
-+ if (sbc8240_part_banks[i].nums == 0) {
-+ printk (KERN_NOTICE MSG_PREFIX
-+ "No partition info available, registering whole device\n");
-+ add_mtd_device(sbc8240_mtd[i]);
-+ } else {
-+ printk (KERN_NOTICE MSG_PREFIX
-+ "Using %s partition definition\n", sbc8240_part_banks[i].mtd_part->name);
-+ add_mtd_partitions (sbc8240_mtd[i],
-+ sbc8240_part_banks[i].mtd_part,
-+ sbc8240_part_banks[i].nums);
-+ }
-+ }
-+#else
-+ printk(KERN_NOTICE MSG_PREFIX
-+ "Registering %d flash banks at once\n", devicesfound);
-+
-+ for (i = 0; i < devicesfound; i++) {
-+ add_mtd_device(sbc8240_mtd[i]);
-+ }
-+#endif /* CONFIG_MTD_PARTITIONS */
-+
-+ return devicesfound == 0 ? -ENXIO : 0;
-+}
-+
-+static void __exit cleanup_sbc8240_mtd (void)
-+{
-+ int i;
-+
-+ for (i = 0; i < NUM_FLASH_BANKS; i++) {
-+ if (sbc8240_mtd[i]) {
-+ del_mtd_device (sbc8240_mtd[i]);
-+ map_destroy (sbc8240_mtd[i]);
-+ }
-+ if (sbc8240_map[i].map_priv_1) {
-+ iounmap ((void *) sbc8240_map[i].map_priv_1);
-+ sbc8240_map[i].map_priv_1 = 0;
-+ }
-+ }
-+}
-+
-+module_init (init_sbc8240_mtd);
-+module_exit (cleanup_sbc8240_mtd);
-+
-+MODULE_LICENSE ("GPL");
-+MODULE_AUTHOR ("Carolyn Smith <carolyn.smith@tektronix.com>");
-+MODULE_DESCRIPTION ("MTD map driver for SBC8240 boards");
-+
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/sbc_gxx.c linux/drivers/mtd/maps/sbc_gxx.c
---- linux-mips-2.4.27/drivers/mtd/maps/sbc_gxx.c 2003-02-26 01:53:50.000000000 +0100
-+++ linux/drivers/mtd/maps/sbc_gxx.c 2004-11-19 10:25:11.969189152 +0100
-@@ -17,7 +17,7 @@
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
-
-- $Id$
-+ $Id$
-
- The SBC-MediaGX / SBC-GXx has up to 16 MiB of
- Intel StrataFlash (28F320/28F640) in x8 mode.
-@@ -91,14 +91,14 @@
- * single flash device into. If the size if zero we use up to the end of the
- * device. */
- static struct mtd_partition partition_info[]={
-- { name: "SBC-GXx flash boot partition",
-- offset: 0,
-- size: BOOT_PARTITION_SIZE_KiB*1024 },
-- { name: "SBC-GXx flash data partition",
-- offset: BOOT_PARTITION_SIZE_KiB*1024,
-- size: (DATA_PARTITION_SIZE_KiB)*1024 },
-- { name: "SBC-GXx flash application partition",
-- offset: (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 }
-+ { .name = "SBC-GXx flash boot partition",
-+ .offset = 0,
-+ .size = BOOT_PARTITION_SIZE_KiB*1024 },
-+ { .name = "SBC-GXx flash data partition",
-+ .offset = BOOT_PARTITION_SIZE_KiB*1024,
-+ .size = (DATA_PARTITION_SIZE_KiB)*1024 },
-+ { .name = "SBC-GXx flash application partition",
-+ .offset = (BOOT_PARTITION_SIZE_KiB+DATA_PARTITION_SIZE_KiB)*1024 }
- };
-
- #define NUM_PARTITIONS 3
-@@ -203,19 +203,20 @@
- }
-
- static struct map_info sbc_gxx_map = {
-- name: "SBC-GXx flash",
-- size: MAX_SIZE_KiB*1024, /* this must be set to a maximum possible amount
-+ .name = "SBC-GXx flash",
-+ .phys = NO_XIP,
-+ .size = MAX_SIZE_KiB*1024, /* this must be set to a maximum possible amount
- of flash so the cfi probe routines find all
- the chips */
-- buswidth: 1,
-- read8: sbc_gxx_read8,
-- read16: sbc_gxx_read16,
-- read32: sbc_gxx_read32,
-- copy_from: sbc_gxx_copy_from,
-- write8: sbc_gxx_write8,
-- write16: sbc_gxx_write16,
-- write32: sbc_gxx_write32,
-- copy_to: sbc_gxx_copy_to
-+ .buswidth = 1,
-+ .read8 = sbc_gxx_read8,
-+ .read16 = sbc_gxx_read16,
-+ .read32 = sbc_gxx_read32,
-+ .copy_from = sbc_gxx_copy_from,
-+ .write8 = sbc_gxx_write8,
-+ .write16 = sbc_gxx_write16,
-+ .write32 = sbc_gxx_write32,
-+ .copy_to = sbc_gxx_copy_to
- };
-
- /* MTD device for all of the flash. */
-@@ -234,12 +235,6 @@
-
- int __init init_sbc_gxx(void)
- {
-- if (check_region(PAGE_IO,PAGE_IO_SIZE) != 0) {
-- printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
-- sbc_gxx_map.name,
-- PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 );
-- return -EAGAIN;
-- }
- iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH);
- if (!iomapadr) {
- printk( KERN_ERR"%s: failed to ioremap memory region\n",
-@@ -247,7 +242,14 @@
- return -EIO;
- }
-
-- request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash" );
-+ if (!request_region( PAGE_IO, PAGE_IO_SIZE, "SBC-GXx flash")) {
-+ printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
-+ sbc_gxx_map.name,
-+ PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 );
-+ iounmap((void *)iomapadr);
-+ return -EAGAIN;
-+ }
-+
-
- printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
- sbc_gxx_map.name,
-@@ -261,7 +263,7 @@
- return -ENXIO;
- }
-
-- all_mtd->module=THIS_MODULE;
-+ all_mtd->owner = THIS_MODULE;
-
- /* Create MTD devices for each partition. */
- add_mtd_partitions(all_mtd, partition_info, NUM_PARTITIONS );
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/sc520cdp.c linux/drivers/mtd/maps/sc520cdp.c
---- linux-mips-2.4.27/drivers/mtd/maps/sc520cdp.c 2002-06-27 00:35:50.000000000 +0200
-+++ linux/drivers/mtd/maps/sc520cdp.c 2004-11-19 10:25:11.970189000 +0100
-@@ -16,7 +16,7 @@
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
-- * $Id$
-+ * $Id$
- *
- *
- * The SC520CDP is an evaluation board for the Elan SC520 processor available
-@@ -29,6 +29,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -84,88 +85,25 @@
- #define WINDOW_SIZE_1 0x00800000
- #define WINDOW_SIZE_2 0x00080000
-
--static __u8 sc520cdp_read8(struct map_info *map, unsigned long ofs)
--{
-- return readb(map->map_priv_1 + ofs);
--}
--
--static __u16 sc520cdp_read16(struct map_info *map, unsigned long ofs)
--{
-- return readw(map->map_priv_1 + ofs);
--}
--
--static __u32 sc520cdp_read32(struct map_info *map, unsigned long ofs)
--{
-- return readl(map->map_priv_1 + ofs);
--}
--
--static void sc520cdp_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
--}
--
--static void sc520cdp_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- writeb(d, map->map_priv_1 + adr);
--}
--
--static void sc520cdp_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- writew(d, map->map_priv_1 + adr);
--}
--
--static void sc520cdp_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- writel(d, map->map_priv_1 + adr);
--}
--
--static void sc520cdp_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio((void *)(map->map_priv_1 + to), from, len);
--}
-
- static struct map_info sc520cdp_map[] = {
- {
-- name: "SC520CDP Flash Bank #0",
-- size: WINDOW_SIZE_0,
-- buswidth: 4,
-- read8: sc520cdp_read8,
-- read16: sc520cdp_read16,
-- read32: sc520cdp_read32,
-- copy_from: sc520cdp_copy_from,
-- write8: sc520cdp_write8,
-- write16: sc520cdp_write16,
-- write32: sc520cdp_write32,
-- copy_to: sc520cdp_copy_to,
-- map_priv_2: WINDOW_ADDR_0
-+ .name = "SC520CDP Flash Bank #0",
-+ .size = WINDOW_SIZE_0,
-+ .buswidth = 4,
-+ .phys = WINDOW_ADDR_0
- },
- {
-- name: "SC520CDP Flash Bank #1",
-- size: WINDOW_SIZE_1,
-- buswidth: 4,
-- read8: sc520cdp_read8,
-- read16: sc520cdp_read16,
-- read32: sc520cdp_read32,
-- copy_from: sc520cdp_copy_from,
-- write8: sc520cdp_write8,
-- write16: sc520cdp_write16,
-- write32: sc520cdp_write32,
-- copy_to: sc520cdp_copy_to,
-- map_priv_2: WINDOW_ADDR_1
-+ .name = "SC520CDP Flash Bank #1",
-+ .size = WINDOW_SIZE_1,
-+ .buswidth = 4,
-+ .phys = WINDOW_ADDR_1
- },
- {
-- name: "SC520CDP DIL Flash",
-- size: WINDOW_SIZE_2,
-- buswidth: 1,
-- read8: sc520cdp_read8,
-- read16: sc520cdp_read16,
-- read32: sc520cdp_read32,
-- copy_from: sc520cdp_copy_from,
-- write8: sc520cdp_write8,
-- write16: sc520cdp_write16,
-- write32: sc520cdp_write32,
-- copy_to: sc520cdp_copy_to,
-- map_priv_2: WINDOW_ADDR_2
-+ .name = "SC520CDP DIL Flash",
-+ .size = WINDOW_SIZE_2,
-+ .buswidth = 1,
-+ .phys = WINDOW_ADDR_2
- },
- };
-
-@@ -255,9 +193,9 @@
- /* map in SC520's MMCR area */
- mmcr = (unsigned long *)ioremap_nocache(SC520_MMCR_BASE, SC520_MMCR_EXTENT);
- if(!mmcr) { /* ioremap_nocache failed: skip the PAR reprogramming */
-- /* force map_priv_2 fields to BIOS defaults: */
-+ /* force physical address fields to BIOS defaults: */
- for(i = 0; i < NUM_FLASH_BANKS; i++)
-- sc520cdp_map[i].map_priv_2 = par_table[i].default_address;
-+ sc520cdp_map[i].phys = par_table[i].default_address;
- return;
- }
-
-@@ -282,7 +220,7 @@
- sc520cdp_map[i].name);
- printk(KERN_NOTICE "Trying default address 0x%lx\n",
- par_table[i].default_address);
-- sc520cdp_map[i].map_priv_2 = par_table[i].default_address;
-+ sc520cdp_map[i].phys = par_table[i].default_address;
- }
- }
- iounmap((void *)mmcr);
-@@ -300,13 +238,18 @@
- #endif
-
- for (i = 0; i < NUM_FLASH_BANKS; i++) {
-- printk(KERN_NOTICE "SC520 CDP flash device: %lx at %lx\n", sc520cdp_map[i].size, sc520cdp_map[i].map_priv_2);
-- sc520cdp_map[i].map_priv_1 = (unsigned long)ioremap_nocache(sc520cdp_map[i].map_priv_2, sc520cdp_map[i].size);
-+ printk(KERN_NOTICE "SC520 CDP flash device: 0x%lx at 0x%lx\n",
-+ sc520cdp_map[i].size, sc520cdp_map[i].phys);
-
-- if (!sc520cdp_map[i].map_priv_1) {
-+ sc520cdp_map[i].virt = (unsigned long)ioremap_nocache(sc520cdp_map[i].phys, sc520cdp_map[i].size);
-+
-+ if (!sc520cdp_map[i].virt) {
- printk("Failed to ioremap_nocache\n");
- return -EIO;
- }
-+
-+ simple_map_init(&sc520cdp_map[i]);
-+
- mymtd[i] = do_map_probe("cfi_probe", &sc520cdp_map[i]);
- if(!mymtd[i])
- mymtd[i] = do_map_probe("jedec_probe", &sc520cdp_map[i]);
-@@ -314,11 +257,11 @@
- mymtd[i] = do_map_probe("map_rom", &sc520cdp_map[i]);
-
- if (mymtd[i]) {
-- mymtd[i]->module = THIS_MODULE;
-+ mymtd[i]->owner = THIS_MODULE;
- ++devices_found;
- }
- else {
-- iounmap((void *)sc520cdp_map[i].map_priv_1);
-+ iounmap((void *)sc520cdp_map[i].virt);
- }
- }
- if(devices_found >= 2) {
-@@ -346,9 +289,9 @@
- for (i = 0; i < NUM_FLASH_BANKS; i++) {
- if (mymtd[i])
- map_destroy(mymtd[i]);
-- if (sc520cdp_map[i].map_priv_1) {
-- iounmap((void *)sc520cdp_map[i].map_priv_1);
-- sc520cdp_map[i].map_priv_1 = 0;
-+ if (sc520cdp_map[i].virt) {
-+ iounmap((void *)sc520cdp_map[i].virt);
-+ sc520cdp_map[i].virt = 0;
- }
- }
- }
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/scb2_flash.c linux/drivers/mtd/maps/scb2_flash.c
---- linux-mips-2.4.27/drivers/mtd/maps/scb2_flash.c 2003-02-26 01:53:50.000000000 +0100
-+++ linux/drivers/mtd/maps/scb2_flash.c 2004-11-19 10:25:11.972188696 +0100
-@@ -1,6 +1,6 @@
- /*
- * MTD map driver for BIOS Flash on Intel SCB2 boards
-- * $Id$
-+ * $Id$
- * Copyright (C) 2002 Sun Microsystems, Inc.
- * Tim Hockin <thockin@sun.com>
- *
-@@ -14,7 +14,7 @@
- * try to request it here, but if it fails, we carry on anyway.
- *
- * This is how the chip is attached, so said the schematic:
-- * * a 4 MiB (32 Mb) 16 bit chip
-+ * * a 4 MiB (32 Mib) 16 bit chip
- * * a 1 MiB memory region
- * * A20 and A21 pulled up
- * * D8-D15 ignored
-@@ -48,6 +48,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -60,65 +61,13 @@
- #define SCB2_ADDR 0xfff00000
- #define SCB2_WINDOW 0x00100000
-
--static __u8 scb2_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--static __u16 scb2_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--static __u32 scb2_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--static void scb2_copy_from(struct map_info *map, void *to,
-- unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--static void scb2_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void scb2_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void scb2_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void scb2_copy_to(struct map_info *map, unsigned long to,
-- const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
-
- static void *scb2_ioaddr;
- static struct mtd_info *scb2_mtd;
- struct map_info scb2_map = {
-- name: "SCB2 BIOS Flash",
-- size: 0,
-- buswidth: 1,
-- read8: scb2_read8,
-- read16: scb2_read16,
-- read32: scb2_read32,
-- copy_from: scb2_copy_from,
-- write8: scb2_write8,
-- write16: scb2_write16,
-- write32: scb2_write32,
-- copy_to: scb2_copy_to,
-+ .name = "SCB2 BIOS Flash",
-+ .size = 0,
-+ .buswidth = 1,
- };
- static int region_fail;
-
-@@ -137,6 +86,8 @@
- return -1;
- }
-
-+ /* I wasn't here. I didn't see. dwmw2. */
-+
- /* the chip is sometimes bigger than the map - what a waste */
- mtd->size = map->size;
-
-@@ -211,9 +162,12 @@
- return -ENOMEM;
- }
-
-- scb2_map.map_priv_1 = (unsigned long)scb2_ioaddr;
-+ scb2_map.phys = SCB2_ADDR;
-+ scb2_map.virt = (unsigned long)scb2_ioaddr;
- scb2_map.size = SCB2_WINDOW;
-
-+ simple_map_init(&scb2_map);
-+
- /* try to find a chip */
- scb2_mtd = do_map_probe("cfi_probe", &scb2_map);
-
-@@ -225,7 +179,7 @@
- return -ENODEV;
- }
-
-- scb2_mtd->module = THIS_MODULE;
-+ scb2_mtd->owner = THIS_MODULE;
- if (scb2_fixup_mtd(scb2_mtd) < 0) {
- del_mtd_device(scb2_mtd);
- map_destroy(scb2_mtd);
-@@ -235,7 +189,7 @@
- return -ENODEV;
- }
-
-- printk(KERN_NOTICE MODNAME ": chip size %x at offset %x\n",
-+ printk(KERN_NOTICE MODNAME ": chip size 0x%x at offset 0x%x\n",
- scb2_mtd->size, SCB2_WINDOW - scb2_mtd->size);
-
- add_mtd_device(scb2_mtd);
-@@ -266,19 +220,19 @@
-
- static struct pci_device_id scb2_flash_pci_ids[] __devinitdata = {
- {
-- vendor: PCI_VENDOR_ID_SERVERWORKS,
-- device: PCI_DEVICE_ID_SERVERWORKS_CSB5,
-- subvendor: PCI_ANY_ID,
-- subdevice: PCI_ANY_ID
-+ .vendor = PCI_VENDOR_ID_SERVERWORKS,
-+ .device = PCI_DEVICE_ID_SERVERWORKS_CSB5,
-+ .subvendor = PCI_ANY_ID,
-+ .subdevice = PCI_ANY_ID
- },
- { 0, }
- };
-
- static struct pci_driver scb2_flash_driver = {
-- name: "Intel SCB2 BIOS Flash",
-- id_table: scb2_flash_pci_ids,
-- probe: scb2_flash_probe,
-- remove: __devexit_p(scb2_flash_remove),
-+ .name = "Intel SCB2 BIOS Flash",
-+ .id_table = scb2_flash_pci_ids,
-+ .probe = scb2_flash_probe,
-+ .remove = __devexit_p(scb2_flash_remove),
- };
-
- static int __init
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/scx200_docflash.c linux/drivers/mtd/maps/scx200_docflash.c
---- linux-mips-2.4.27/drivers/mtd/maps/scx200_docflash.c 2003-02-26 01:53:50.000000000 +0100
-+++ linux/drivers/mtd/maps/scx200_docflash.c 2004-11-19 10:25:11.973188544 +0100
-@@ -2,7 +2,7 @@
-
- Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
-
-- $Id$
-+ $Id$
-
- National Semiconductor SCx200 flash mapped with DOCCS
- */
-@@ -11,6 +11,7 @@
- #include <linux/config.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -75,46 +76,9 @@
- #define NUM_PARTITIONS (sizeof(partition_info)/sizeof(partition_info[0]))
- #endif
-
--static __u8 scx200_docflash_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--static __u16 scx200_docflash_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--static void scx200_docflash_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--static void scx200_docflash_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void scx200_docflash_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void scx200_docflash_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
-
- static struct map_info scx200_docflash_map = {
- .name = "NatSemi SCx200 DOCCS Flash",
-- .read8 = scx200_docflash_read8,
-- .read16 = scx200_docflash_read16,
-- .copy_from = scx200_docflash_copy_from,
-- .write8 = scx200_docflash_write8,
-- .write16 = scx200_docflash_write16,
-- .copy_to = scx200_docflash_copy_to
- };
-
- int __init init_scx200_docflash(void)
-@@ -213,8 +177,11 @@
- else
- scx200_docflash_map.buswidth = 2;
-
-- scx200_docflash_map.map_priv_1 = (unsigned long)ioremap(docmem.start, scx200_docflash_map.size);
-- if (!scx200_docflash_map.map_priv_1) {
-+ simple_map_init(&scx200_docflash_map);
-+
-+ scx200_docflash_map.phys = docmem.start;
-+ scx200_docflash_map.virt = (unsigned long)ioremap(docmem.start, scx200_docflash_map.size);
-+ if (!scx200_docflash_map.virt) {
- printk(KERN_ERR NAME ": failed to ioremap the flash\n");
- release_resource(&docmem);
- return -EIO;
-@@ -223,7 +190,7 @@
- mymtd = do_map_probe(flashtype, &scx200_docflash_map);
- if (!mymtd) {
- printk(KERN_ERR NAME ": unable to detect flash\n");
-- iounmap((void *)scx200_docflash_map.map_priv_1);
-+ iounmap((void *)scx200_docflash_map.virt);
- release_resource(&docmem);
- return -ENXIO;
- }
-@@ -231,7 +198,7 @@
- if (size < mymtd->size)
- printk(KERN_WARNING NAME ": warning, flash mapping is smaller than flash size\n");
-
-- mymtd->module = THIS_MODULE;
-+ mymtd->owner = THIS_MODULE;
-
- #if PARTITION
- partition_info[3].offset = mymtd->size-partition_info[3].size;
-@@ -253,8 +220,8 @@
- #endif
- map_destroy(mymtd);
- }
-- if (scx200_docflash_map.map_priv_1) {
-- iounmap((void *)scx200_docflash_map.map_priv_1);
-+ if (scx200_docflash_map.virt) {
-+ iounmap((void *)scx200_docflash_map.virt);
- release_resource(&docmem);
- }
- }
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/solutionengine.c linux/drivers/mtd/maps/solutionengine.c
---- linux-mips-2.4.27/drivers/mtd/maps/solutionengine.c 2002-06-27 00:35:50.000000000 +0200
-+++ linux/drivers/mtd/maps/solutionengine.c 2004-11-19 10:25:11.975188240 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Flash and EPROM on Hitachi Solution Engine and similar boards.
- *
-@@ -11,6 +11,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
-@@ -18,60 +19,39 @@
- #include <linux/config.h>
-
-
--extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
--
--__u32 soleng_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--void soleng_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void soleng_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--
- static struct mtd_info *flash_mtd;
- static struct mtd_info *eprom_mtd;
-
- static struct mtd_partition *parsed_parts;
-
- struct map_info soleng_eprom_map = {
-- name: "Solution Engine EPROM",
-- size: 0x400000,
-- buswidth: 4,
-- copy_from: soleng_copy_from,
-+ .name = "Solution Engine EPROM",
-+ .size = 0x400000,
-+ .buswidth = 4,
- };
-
- struct map_info soleng_flash_map = {
-- name: "Solution Engine FLASH",
-- size: 0x400000,
-- buswidth: 4,
-- read32: soleng_read32,
-- copy_from: soleng_copy_from,
-- write32: soleng_write32,
-+ .name = "Solution Engine FLASH",
-+ .size = 0x400000,
-+ .buswidth = 4,
- };
-
-+static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-+
- #ifdef CONFIG_MTD_SUPERH_RESERVE
- static struct mtd_partition superh_se_partitions[] = {
- /* Reserved for boot code, read-only */
- {
-- name: "flash_boot",
-- offset: 0x00000000,
-- size: CONFIG_MTD_SUPERH_RESERVE,
-- mask_flags: MTD_WRITEABLE,
-+ .name = "flash_boot",
-+ .offset = 0x00000000,
-+ .size = CONFIG_MTD_SUPERH_RESERVE,
-+ .mask_flags = MTD_WRITEABLE,
- },
- /* All else is writable (e.g. JFFS) */
- {
-- name: "Flash FS",
-- offset: MTDPART_OFS_NXTBLK,
-- size: MTDPART_SIZ_FULL,
-+ .name = "Flash FS",
-+ .offset = MTDPART_OFS_NXTBLK,
-+ .size = MTDPART_SIZ_FULL,
- }
- };
- #endif /* CONFIG_MTD_SUPERH_RESERVE */
-@@ -81,16 +61,22 @@
- int nr_parts = 0;
-
- /* First probe at offset 0 */
-- soleng_flash_map.map_priv_1 = P2SEGADDR(0);
-- soleng_eprom_map.map_priv_1 = P1SEGADDR(0x01000000);
-+ soleng_flash_map.phys = 0;
-+ soleng_flash_map.virt = P2SEGADDR(0);
-+ soleng_eprom_map.phys = 0x01000000;
-+ soleng_eprom_map.virt = P1SEGADDR(0x01000000);
-+ simple_map_init(&soleng_eprom_map);
-+ simple_map_init(&soleng_flash_map);
-
- printk(KERN_NOTICE "Probing for flash chips at 0x00000000:\n");
- flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map);
- if (!flash_mtd) {
- /* Not there. Try swapping */
- printk(KERN_NOTICE "Probing for flash chips at 0x01000000:\n");
-- soleng_flash_map.map_priv_1 = P2SEGADDR(0x01000000);
-- soleng_eprom_map.map_priv_1 = P1SEGADDR(0);
-+ soleng_flash_map.phys = 0x01000000;
-+ soleng_flash_map.virt = P2SEGADDR(0x01000000);
-+ soleng_eprom_map.phys = 0;
-+ soleng_eprom_map.virt = P1SEGADDR(0);
- flash_mtd = do_map_probe("cfi_probe", &soleng_flash_map);
- if (!flash_mtd) {
- /* Eep. */
-@@ -99,25 +85,20 @@
- }
- }
- printk(KERN_NOTICE "Solution Engine: Flash at 0x%08lx, EPROM at 0x%08lx\n",
-- soleng_flash_map.map_priv_1 & 0x1fffffff,
-- soleng_eprom_map.map_priv_1 & 0x1fffffff);
-- flash_mtd->module = THIS_MODULE;
-+ soleng_flash_map.phys & 0x1fffffff,
-+ soleng_eprom_map.phys & 0x1fffffff);
-+ flash_mtd->owner = THIS_MODULE;
-
- eprom_mtd = do_map_probe("map_rom", &soleng_eprom_map);
- if (eprom_mtd) {
-- eprom_mtd->module = THIS_MODULE;
-+ eprom_mtd->owner = THIS_MODULE;
- add_mtd_device(eprom_mtd);
- }
-
--#ifdef CONFIG_MTD_REDBOOT_PARTS
-- nr_parts = parse_redboot_partitions(flash_mtd, &parsed_parts);
-- if (nr_parts > 0)
-- printk(KERN_NOTICE "Found RedBoot partition table.\n");
-- else if (nr_parts < 0)
-- printk(KERN_NOTICE "Error looking for RedBoot partitions.\n");
--#endif /* CONFIG_MTD_REDBOOT_PARTS */
-+ nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_parts, 0);
-+
- #if CONFIG_MTD_SUPERH_RESERVE
-- if (nr_parts == 0) {
-+ if (nr_parts <= 0) {
- printk(KERN_NOTICE "Using configured partition at 0x%08x.\n",
- CONFIG_MTD_SUPERH_RESERVE);
- parsed_parts = superh_se_partitions;
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/sun_uflash.c linux/drivers/mtd/maps/sun_uflash.c
---- linux-mips-2.4.27/drivers/mtd/maps/sun_uflash.c 2001-11-05 21:15:52.000000000 +0100
-+++ linux/drivers/mtd/maps/sun_uflash.c 2004-11-19 10:25:11.976188088 +0100
-@@ -1,4 +1,4 @@
--/* $Id$
-+/* $Id$
- *
- * sun_uflash - Driver implementation for user-programmable flash
- * present on many Sun Microsystems SME boardsets.
-@@ -48,60 +48,11 @@
- struct list_head list;
- };
-
--__u8 uflash_read8(struct map_info *map, unsigned long ofs)
--{
-- return(__raw_readb(map->map_priv_1 + ofs));
--}
--
--__u16 uflash_read16(struct map_info *map, unsigned long ofs)
--{
-- return(__raw_readw(map->map_priv_1 + ofs));
--}
--
--__u32 uflash_read32(struct map_info *map, unsigned long ofs)
--{
-- return(__raw_readl(map->map_priv_1 + ofs));
--}
--
--void uflash_copy_from(struct map_info *map, void *to, unsigned long from,
-- ssize_t len)
--{
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void uflash_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
--}
--
--void uflash_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
--}
--
--void uflash_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
--}
--
--void uflash_copy_to(struct map_info *map, unsigned long to, const void *from,
-- ssize_t len)
--{
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
-
- struct map_info uflash_map_templ = {
-- name: "SUNW,???-????",
-- size: UFLASH_WINDOW_SIZE,
-- buswidth: UFLASH_BUSWIDTH,
-- read8: uflash_read8,
-- read16: uflash_read16,
-- read32: uflash_read32,
-- copy_from: uflash_copy_from,
-- write8: uflash_write8,
-- write16: uflash_write16,
-- write32: uflash_write32,
-- copy_to: uflash_copy_to
-+ .name = "SUNW,???-????",
-+ .size = UFLASH_WINDOW_SIZE,
-+ .buswidth = UFLASH_BUSWIDTH,
- };
-
- int uflash_devinit(struct linux_ebus_device* edev)
-@@ -145,20 +96,22 @@
- if(0 != pdev->name && 0 < strlen(pdev->name)) {
- pdev->map.name = pdev->name;
- }
--
-- pdev->map.map_priv_1 =
-+ pdev->phys = edev->resource[0].start;
-+ pdev->virt =
- (unsigned long)ioremap_nocache(edev->resource[0].start, pdev->map.size);
-- if(0 == pdev->map.map_priv_1) {
-+ if(0 == pdev->map.virt) {
- printk("%s: failed to map device\n", __FUNCTION__);
- kfree(pdev->name);
- kfree(pdev);
- return(-1);
- }
-
-+ simple_map_init(&pdev->map);
-+
- /* MTD registration */
- pdev->mtd = do_map_probe("cfi_probe", &pdev->map);
- if(0 == pdev->mtd) {
-- iounmap((void *)pdev->map.map_priv_1);
-+ iounmap((void *)pdev->map.virt);
- kfree(pdev->name);
- kfree(pdev);
- return(-ENXIO);
-@@ -166,7 +119,7 @@
-
- list_add(&pdev->list, &device_list);
-
-- pdev->mtd->module = THIS_MODULE;
-+ pdev->mtd->owner = THIS_MODULE;
-
- add_mtd_device(pdev->mtd);
- return(0);
-@@ -211,9 +164,9 @@
- del_mtd_device(udev->mtd);
- map_destroy(udev->mtd);
- }
-- if(0 != udev->map.map_priv_1) {
-- iounmap((void*)udev->map.map_priv_1);
-- udev->map.map_priv_1 = 0;
-+ if(0 != udev->map.virt) {
-+ iounmap((void*)udev->map.virt);
-+ udev->map.virt = 0;
- }
- if(0 != udev->name) {
- kfree(udev->name);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/tqm8xxl.c linux/drivers/mtd/maps/tqm8xxl.c
---- linux-mips-2.4.27/drivers/mtd/maps/tqm8xxl.c 2003-02-26 01:53:50.000000000 +0100
-+++ linux/drivers/mtd/maps/tqm8xxl.c 2004-11-19 10:25:11.978187784 +0100
-@@ -2,7 +2,7 @@
- * Handle mapping of the flash memory access routines
- * on TQM8xxL based devices.
- *
-- * $Id$
-+ * $Id$
- *
- * based on rpxlite.c
- *
-@@ -26,6 +26,7 @@
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
- #include <asm/io.h>
-
- #include <linux/mtd/mtd.h>
-@@ -51,46 +52,6 @@
- static unsigned long num_banks;
- static unsigned long start_scan_addr;
-
--__u8 tqm8xxl_read8(struct map_info *map, unsigned long ofs)
--{
-- return *((__u8 *)(map->map_priv_1 + ofs));
--}
--
--__u16 tqm8xxl_read16(struct map_info *map, unsigned long ofs)
--{
-- return *((__u16 *)(map->map_priv_1 + ofs));
--}
--
--__u32 tqm8xxl_read32(struct map_info *map, unsigned long ofs)
--{
-- return *((__u32 *)(map->map_priv_1 + ofs));
--}
--
--void tqm8xxl_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
--}
--
--void tqm8xxl_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- *((__u8 *)(map->map_priv_1 + adr)) = d;
--}
--
--void tqm8xxl_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- *((__u16 *)( map->map_priv_1 + adr)) = d;
--}
--
--void tqm8xxl_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- *((__u32 *)(map->map_priv_1 + adr)) = d;
--}
--
--void tqm8xxl_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio((void *)(map->map_priv_1 + to), from, len);
--}
--
- /*
- * Here are partition information for all known TQM8xxL series devices.
- * See include/linux/mtd/partitions.h for definition of the mtd_partition
-@@ -107,50 +68,48 @@
- static unsigned long tqm8xxl_max_flash_size = 0x00800000;
-
- /* partition definition for first flash bank
-- * also ref. to "drivers\char\flash_config.c"
-+ * (cf. "drivers/char/flash_config.c")
- */
- static struct mtd_partition tqm8xxl_partitions[] = {
- {
-- name: "ppcboot",
-- offset: 0x00000000,
-- size: 0x00020000, /* 128KB */
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-+ .name = "ppcboot",
-+ .offset = 0x00000000,
-+ .size = 0x00020000, /* 128KB */
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
- {
-- name: "kernel", /* default kernel image */
-- offset: 0x00020000,
-- size: 0x000e0000,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-+ .name = "kernel", /* default kernel image */
-+ .offset = 0x00020000,
-+ .size = 0x000e0000,
-+ .mask_flags = MTD_WRITEABLE, /* force read-only */
- },
- {
-- name: "user",
-- offset: 0x00100000,
-- size: 0x00100000,
-+ .name = "user",
-+ .offset = 0x00100000,
-+ .size = 0x00100000,
- },
- {
-- name: "initrd",
-- offset: 0x00200000,
-- size: 0x00200000,
-+ .name = "initrd",
-+ .offset = 0x00200000,
-+ .size = 0x00200000,
- }
- };
--/* partition definition for second flahs bank */
-+/* partition definition for second flash bank */
- static struct mtd_partition tqm8xxl_fs_partitions[] = {
- {
-- name: "cramfs",
-- offset: 0x00000000,
-- size: 0x00200000,
-+ .name = "cramfs",
-+ .offset = 0x00000000,
-+ .size = 0x00200000,
- },
- {
-- name: "jffs",
-- offset: 0x00200000,
-- size: 0x00200000,
-- //size: MTDPART_SIZ_FULL,
-+ .name = "jffs",
-+ .offset = 0x00200000,
-+ .size = 0x00200000,
-+ .//size = MTDPART_SIZ_FULL,
- }
- };
- #endif
-
--#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
--
- int __init init_tqm_mtd(void)
- {
- int idx = 0, ret = 0;
-@@ -160,67 +119,73 @@
-
- flash_addr = bd->bi_flashstart;
- flash_size = bd->bi_flashsize;
-- //request maximum flash size address spzce
-+
-+ //request maximum flash size address space
- start_scan_addr = (unsigned long)ioremap(flash_addr, flash_size);
- if (!start_scan_addr) {
-- //printk("%s:Failed to ioremap address:0x%x\n", __FUNCTION__, FLASH_ADDR);
-- printk("%s:Failed to ioremap address:0x%x\n", __FUNCTION__, flash_addr);
-+ printk(KERN_WARNING "%s:Failed to ioremap address:0x%x\n", __FUNCTION__, flash_addr);
- return -EIO;
- }
-- for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++)
-- {
-+
-+ for (idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
- if(mtd_size >= flash_size)
- break;
-
-- printk("%s: chip probing count %d\n", __FUNCTION__, idx);
-+ printk(KERN_INFO "%s: chip probing count %d\n", __FUNCTION__, idx);
-
- map_banks[idx] = (struct map_info *)kmalloc(sizeof(struct map_info), GFP_KERNEL);
-- if(map_banks[idx] == NULL)
-- {
-- //return -ENOMEM;
-+ if(map_banks[idx] == NULL) {
- ret = -ENOMEM;
-+ /* FIXME: What if some MTD devices were probed already? */
- goto error_mem;
- }
-+
- memset((void *)map_banks[idx], 0, sizeof(struct map_info));
- map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL);
-- if(map_banks[idx]->name == NULL)
-- {
-- //return -ENOMEM;
-+
-+ if (!map_banks[idx]->name) {
- ret = -ENOMEM;
-+ /* FIXME: What if some MTD devices were probed already? */
- goto error_mem;
- }
-- memset((void *)map_banks[idx]->name, 0, 16);
--
- sprintf(map_banks[idx]->name, "TQM8xxL%d", idx);
-+
- map_banks[idx]->size = flash_size;
- map_banks[idx]->buswidth = 4;
-- map_banks[idx]->read8 = tqm8xxl_read8;
-- map_banks[idx]->read16 = tqm8xxl_read16;
-- map_banks[idx]->read32 = tqm8xxl_read32;
-- map_banks[idx]->copy_from = tqm8xxl_copy_from;
-- map_banks[idx]->write8 = tqm8xxl_write8;
-- map_banks[idx]->write16 = tqm8xxl_write16;
-- map_banks[idx]->write32 = tqm8xxl_write32;
-- map_banks[idx]->copy_to = tqm8xxl_copy_to;
-+
-+ simple_map_init(map_banks[idx]);
-+
-+ map_banks[idx]->virt = start_scan_addr;
-+ map_banks[idx]->phys = flash_addr;
-+ /* FIXME: This looks utterly bogus, but I'm trying to
-+ preserve the behaviour of the original (shown here)...
-+
- map_banks[idx]->map_priv_1 =
- start_scan_addr + ((idx > 0) ?
- (mtd_banks[idx-1] ? mtd_banks[idx-1]->size : 0) : 0);
-+ */
-+
-+ if (idx && mtd_banks[idx-1]) {
-+ map_banks[idx]->virt += mtd_banks[idx-1]->size;
-+ map_banks[idx]->phys += mtd_banks[idx-1]->size;
-+ }
-+
- //start to probe flash chips
- mtd_banks[idx] = do_map_probe("cfi_probe", map_banks[idx]);
-- if(mtd_banks[idx])
-- {
-- mtd_banks[idx]->module = THIS_MODULE;
-+
-+ if (mtd_banks[idx]) {
-+ mtd_banks[idx]->owner = THIS_MODULE;
- mtd_size += mtd_banks[idx]->size;
- num_banks++;
-- printk("%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks,
-+
-+ printk(KERN_INFO "%s: bank%d, name:%s, size:%dbytes \n", __FUNCTION__, num_banks,
- mtd_banks[idx]->name, mtd_banks[idx]->size);
- }
- }
-
- /* no supported flash chips found */
-- if(!num_banks)
-- {
-- printk("TQM8xxL: No support flash chips found!\n");
-+ if (!num_banks) {
-+ printk(KERN_NOTICE "TQM8xxL: No support flash chips found!\n");
- ret = -ENXIO;
- goto error_mem;
- }
-@@ -231,12 +196,13 @@
- */
- part_banks[0].mtd_part = tqm8xxl_partitions;
- part_banks[0].type = "Static image";
-- part_banks[0].nums = NB_OF(tqm8xxl_partitions);
-+ part_banks[0].nums = ARRAY_SIZE(tqm8xxl_partitions);
-+
- part_banks[1].mtd_part = tqm8xxl_fs_partitions;
- part_banks[1].type = "Static file system";
-- part_banks[1].nums = NB_OF(tqm8xxl_fs_partitions);
-- for(idx = 0; idx < num_banks ; idx++)
-- {
-+ part_banks[1].nums = ARRAY_SIZE(tqm8xxl_fs_partitions);
-+
-+ for(idx = 0; idx < num_banks ; idx++) {
- if (part_banks[idx].nums == 0) {
- printk(KERN_NOTICE "TQM flash%d: no partition info available, registering whole flash at once\n", idx);
- add_mtd_device(mtd_banks[idx]);
-@@ -254,12 +220,9 @@
- #endif
- return 0;
- error_mem:
-- for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++)
-- {
-- if(map_banks[idx] != NULL)
-- {
-- if(map_banks[idx]->name != NULL)
-- {
-+ for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
-+ if(map_banks[idx] != NULL) {
-+ if(map_banks[idx]->name != NULL) {
- kfree(map_banks[idx]->name);
- map_banks[idx]->name = NULL;
- }
-@@ -267,18 +230,15 @@
- map_banks[idx] = NULL;
- }
- }
-- //return -ENOMEM;
- error:
- iounmap((void *)start_scan_addr);
-- //return -ENXIO;
- return ret;
- }
-
- static void __exit cleanup_tqm_mtd(void)
- {
- unsigned int idx = 0;
-- for(idx = 0 ; idx < num_banks ; idx++)
-- {
-+ for(idx = 0 ; idx < num_banks ; idx++) {
- /* destroy mtd_info previously allocated */
- if (mtd_banks[idx]) {
- del_mtd_partitions(mtd_banks[idx]);
-@@ -288,6 +248,7 @@
- kfree(map_banks[idx]->name);
- kfree(map_banks[idx]);
- }
-+
- if (start_scan_addr) {
- iounmap((void *)start_scan_addr);
- start_scan_addr = 0;
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/tsunami_flash.c linux/drivers/mtd/maps/tsunami_flash.c
---- linux-mips-2.4.27/drivers/mtd/maps/tsunami_flash.c 2002-06-27 00:35:50.000000000 +0200
-+++ linux/drivers/mtd/maps/tsunami_flash.c 2004-11-19 10:25:11.979187632 +0100
-@@ -2,11 +2,13 @@
- * tsunami_flash.c
- *
- * flash chip on alpha ds10...
-- * $Id$
-+ * $Id$
- */
- #include <asm/io.h>
- #include <asm/core_tsunami.h>
-+#include <linux/init.h>
- #include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
-
- #define FLASH_ENABLE_PORT 0x00C00001
- #define FLASH_ENABLE_BYTE 0x01
-@@ -58,18 +60,12 @@
- static struct map_info tsunami_flash_map = {
- .name = "flash chip on the Tsunami TIG bus",
- .size = MAX_TIG_FLASH_SIZE,
-+ .phys = NO_XIP;
- .buswidth = 1,
- .read8 = tsunami_flash_read8,
-- .read16 = 0,
-- .read32 = 0,
- .copy_from = tsunami_flash_copy_from,
- .write8 = tsunami_flash_write8,
-- .write16 = 0,
-- .write32 = 0,
- .copy_to = tsunami_flash_copy_to,
-- .set_vpp = 0,
-- .map_priv_1 = 0,
--
- };
-
- static struct mtd_info *tsunami_flash_mtd;
-@@ -99,7 +95,7 @@
- tsunami_flash_mtd = do_map_probe(*type, &tsunami_flash_map);
- }
- if (tsunami_flash_mtd) {
-- tsunami_flash_mtd->module = THIS_MODULE;
-+ tsunami_flash_mtd->owner = THIS_MODULE;
- add_mtd_device(tsunami_flash_mtd);
- return 0;
- }
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/uclinux.c linux/drivers/mtd/maps/uclinux.c
---- linux-mips-2.4.27/drivers/mtd/maps/uclinux.c 2003-02-26 01:53:50.000000000 +0100
-+++ linux/drivers/mtd/maps/uclinux.c 2004-11-19 10:25:11.980187480 +0100
-@@ -5,7 +5,7 @@
- *
- * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
- *
-- * $Id$
-+ * $Id$
- */
-
- /****************************************************************************/
-@@ -24,58 +24,11 @@
-
- /****************************************************************************/
-
--__u8 uclinux_read8(struct map_info *map, unsigned long ofs)
--{
-- return(*((__u8 *) (map->map_priv_1 + ofs)));
--}
--
--__u16 uclinux_read16(struct map_info *map, unsigned long ofs)
--{
-- return(*((__u16 *) (map->map_priv_1 + ofs)));
--}
--
--__u32 uclinux_read32(struct map_info *map, unsigned long ofs)
--{
-- return(*((__u32 *) (map->map_priv_1 + ofs)));
--}
--
--void uclinux_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy(to, (void *)(map->map_priv_1 + from), len);
--}
--
--void uclinux_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- *((__u8 *) (map->map_priv_1 + adr)) = d;
--}
--
--void uclinux_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- *((__u16 *) (map->map_priv_1 + adr)) = d;
--}
--
--void uclinux_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- *((__u32 *) (map->map_priv_1 + adr)) = d;
--}
--
--void uclinux_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy((void *) (map->map_priv_1 + to), from, len);
--}
-
- /****************************************************************************/
-
- struct map_info uclinux_ram_map = {
-- name: "RAM",
-- read8: uclinux_read8,
-- read16: uclinux_read16,
-- read32: uclinux_read32,
-- copy_from: uclinux_copy_from,
-- write8: uclinux_write8,
-- write16: uclinux_write16,
-- write32: uclinux_write32,
-- copy_to: uclinux_copy_to,
-+ .name = "RAM",
- };
-
- struct mtd_info *uclinux_ram_mtdinfo;
-@@ -83,7 +36,7 @@
- /****************************************************************************/
-
- struct mtd_partition uclinux_romfs[] = {
-- { name: "ROMfs", offset: 0 }
-+ { .name = "ROMfs" }
- };
-
- #define NUM_PARTITIONS (sizeof(uclinux_romfs) / sizeof(uclinux_romfs[0]))
-@@ -94,7 +47,7 @@
- size_t *retlen, u_char **mtdbuf)
- {
- struct map_info *map = (struct map_info *) mtd->priv;
-- *mtdbuf = (u_char *) (map->map_priv_1 + ((int) from));
-+ *mtdbuf = (u_char *) (map->virt + ((int) from));
- *retlen = len;
- return(0);
- }
-@@ -108,29 +61,31 @@
- extern char _ebss;
-
- mapp = &uclinux_ram_map;
-- mapp->map_priv_2 = (unsigned long) &_ebss;
-+ mapp->phys = (unsigned long) &_ebss;
- mapp->size = PAGE_ALIGN(*((unsigned long *)((&_ebss) + 8)));
- mapp->buswidth = 4;
-
- printk("uclinux[mtd]: RAM probe address=0x%x size=0x%x\n",
- (int) mapp->map_priv_2, (int) mapp->size);
-
-- mapp->map_priv_1 = (unsigned long)
-- ioremap_nocache(mapp->map_priv_2, mapp->size);
-+ mapp->virt = (unsigned long)
-+ ioremap_nocache(mapp->phys, mapp->size);
-
-- if (mapp->map_priv_1 == 0) {
-+ if (mapp->virt == 0) {
- printk("uclinux[mtd]: ioremap_nocache() failed\n");
- return(-EIO);
- }
-
-+ simple_map_init(mapp);
-+
- mtd = do_map_probe("map_ram", mapp);
- if (!mtd) {
- printk("uclinux[mtd]: failed to find a mapping?\n");
-- iounmap((void *) mapp->map_priv_1);
-+ iounmap((void *) mapp->virt);
- return(-ENXIO);
- }
-
-- mtd->module = THIS_MODULE;
-+ mtd->owner = THIS_MODULE;
- mtd->point = uclinux_point;
- mtd->priv = mapp;
-
-@@ -155,8 +110,8 @@
- uclinux_ram_mtdinfo = NULL;
- }
- if (uclinux_ram_map.map_priv_1) {
-- iounmap((void *) uclinux_ram_map.map_priv_1);
-- uclinux_ram_map.map_priv_1 = 0;
-+ iounmap((void *) uclinux_ram_map.virt);
-+ uclinux_ram_map.virt = 0;
- }
- }
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/maps/vmax301.c linux/drivers/mtd/maps/vmax301.c
---- linux-mips-2.4.27/drivers/mtd/maps/vmax301.c 2001-11-05 21:15:52.000000000 +0100
-+++ linux/drivers/mtd/maps/vmax301.c 2004-11-19 10:25:11.982187176 +0100
-@@ -1,4 +1,4 @@
--// $Id$
-+// $Id$
- /* ######################################################################
-
- Tempustech VMAX SBC301 MTD Driver.
-@@ -24,6 +24,7 @@
- #include <asm/io.h>
-
- #include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
-
-
- #define WINDOW_START 0xd8000
-@@ -142,34 +143,36 @@
-
- static struct map_info vmax_map[2] = {
- {
-- name: "VMAX301 Internal Flash",
-- size: 3*2*1024*1024,
-- buswidth: 1,
-- read8: vmax301_read8,
-- read16: vmax301_read16,
-- read32: vmax301_read32,
-- copy_from: vmax301_copy_from,
-- write8: vmax301_write8,
-- write16: vmax301_write16,
-- write32: vmax301_write32,
-- copy_to: vmax301_copy_to,
-- map_priv_1: WINDOW_START + WINDOW_LENGTH,
-- map_priv_2: 0xFFFFFFFF
-+ .name = "VMAX301 Internal Flash",
-+ .phys = NO_XIP,
-+ .size = 3*2*1024*1024,
-+ .buswidth = 1,
-+ .read8 = vmax301_read8,
-+ .read16 = vmax301_read16,
-+ .read32 = vmax301_read32,
-+ .copy_from = vmax301_copy_from,
-+ .write8 = vmax301_write8,
-+ .write16 = vmax301_write16,
-+ .write32 = vmax301_write32,
-+ .copy_to = vmax301_copy_to,
-+ .map_priv_1 = WINDOW_START + WINDOW_LENGTH,
-+ .map_priv_2 = 0xFFFFFFFF
- },
- {
-- name: "VMAX301 Socket",
-- size: 0,
-- buswidth: 1,
-- read8: vmax301_read8,
-- read16: vmax301_read16,
-- read32: vmax301_read32,
-- copy_from: vmax301_copy_from,
-- write8: vmax301_write8,
-- write16: vmax301_write16,
-- write32: vmax301_write32,
-- copy_to: vmax301_copy_to,
-- map_priv_1: WINDOW_START + (3*WINDOW_LENGTH),
-- map_priv_2: 0xFFFFFFFF
-+ .name = "VMAX301 Socket",
-+ .phys = NO_XIP,
-+ .size = 0,
-+ .buswidth = 1,
-+ .read8 = vmax301_read8,
-+ .read16 = vmax301_read16,
-+ .read32 = vmax301_read32,
-+ .copy_from = vmax301_copy_from,
-+ .write8 = vmax301_write8,
-+ .write16 = vmax301_write16,
-+ .write32 = vmax301_write32,
-+ .copy_to = vmax301_copy_to,
-+ .map_priv_1 = WINDOW_START + (3*WINDOW_LENGTH),
-+ .map_priv_2 = 0xFFFFFFFF
- }
- };
-
-@@ -206,8 +209,8 @@
- address of the first half, because it's used more
- often.
- */
-- vmax_map[0].map_priv_1 = iomapadr + WINDOW_START;
-- vmax_map[1].map_priv_1 = iomapadr + (3*WINDOW_START);
-+ vmax_map[0].map_priv_2 = iomapadr + WINDOW_START;
-+ vmax_map[1].map_priv_2 = iomapadr + (3*WINDOW_START);
-
- for (i=0; i<2; i++) {
- vmax_mtd[i] = do_map_probe("cfi_probe", &vmax_map[i]);
-@@ -218,7 +221,7 @@
- if (!vmax_mtd[i])
- vmax_mtd[i] = do_map_probe("map_rom", &vmax_map[i]);
- if (vmax_mtd[i]) {
-- vmax_mtd[i]->module = THIS_MODULE;
-+ vmax_mtd[i]->owner = THIS_MODULE;
- add_mtd_device(vmax_mtd[i]);
- }
- }
-diff -Nurb linux-mips-2.4.27/drivers/mtd/mtd_blkdevs-24.c linux/drivers/mtd/mtd_blkdevs-24.c
---- linux-mips-2.4.27/drivers/mtd/mtd_blkdevs-24.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/mtd_blkdevs-24.c 2004-11-19 10:25:11.640239160 +0100
-@@ -0,0 +1,699 @@
-+/*
-+ * $Id$
-+ *
-+ * (C) 2003 David Woodhouse <dwmw2@infradead.org>
-+ *
-+ * Interface to Linux 2.4 block layer for MTD 'translation layers'.
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/list.h>
-+#include <linux/fs.h>
-+#include <linux/mtd/blktrans.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/blkdev.h>
-+#include <linux/blk.h>
-+#include <linux/blkpg.h>
-+#include <linux/spinlock.h>
-+#include <linux/hdreg.h>
-+#include <linux/init.h>
-+#include <asm/semaphore.h>
-+#include <asm/uaccess.h>
-+
-+static LIST_HEAD(blktrans_majors);
-+
-+extern struct semaphore mtd_table_mutex;
-+extern struct mtd_info *mtd_table[];
-+
-+struct mtd_blkcore_priv {
-+ devfs_handle_t devfs_dir_handle;
-+ int blksizes[256];
-+ int sizes[256];
-+ struct hd_struct part_table[256];
-+ struct gendisk gd;
-+ spinlock_t devs_lock; /* See comment in _request function */
-+ struct completion thread_dead;
-+ int exiting;
-+ wait_queue_head_t thread_wq;
-+};
-+
-+static inline struct mtd_blktrans_dev *tr_get_dev(struct mtd_blktrans_ops *tr,
-+ int devnum)
-+{
-+ struct list_head *this;
-+ struct mtd_blktrans_dev *d;
-+
-+ list_for_each(this, &tr->devs) {
-+ d = list_entry(this, struct mtd_blktrans_dev, list);
-+
-+ if (d->devnum == devnum)
-+ return d;
-+ }
-+ return NULL;
-+}
-+
-+static inline struct mtd_blktrans_ops *get_tr(int major)
-+{
-+ struct list_head *this;
-+ struct mtd_blktrans_ops *t;
-+
-+ list_for_each(this, &blktrans_majors) {
-+ t = list_entry(this, struct mtd_blktrans_ops, list);
-+
-+ if (t->major == major)
-+ return t;
-+ }
-+ return NULL;
-+}
-+
-+static int do_blktrans_request(struct mtd_blktrans_ops *tr,
-+ struct mtd_blktrans_dev *dev,
-+ struct request *req)
-+{
-+ unsigned long block, nsect;
-+ char *buf;
-+ int minor;
-+
-+ minor = MINOR(req->rq_dev);
-+ block = req->sector;
-+ nsect = req->current_nr_sectors;
-+ buf = req->buffer;
-+
-+ if (block + nsect > tr->blkcore_priv->part_table[minor].nr_sects) {
-+ printk(KERN_WARNING "Access beyond end of device.\n");
-+ return 0;
-+ }
-+ block += tr->blkcore_priv->part_table[minor].start_sect;
-+
-+ switch(req->cmd) {
-+ case READ:
-+ for (; nsect > 0; nsect--, block++, buf += 512)
-+ if (tr->readsect(dev, block, buf))
-+ return 0;
-+ return 1;
-+
-+ case WRITE:
-+ if (!tr->writesect)
-+ return 0;
-+
-+ for (; nsect > 0; nsect--, block++, buf += 512)
-+ if (tr->writesect(dev, block, buf))
-+ return 0;
-+ return 1;
-+
-+ default:
-+ printk(KERN_NOTICE "Unknown request cmd %d\n", req->cmd);
-+ return 0;
-+ }
-+}
-+
-+static int mtd_blktrans_thread(void *arg)
-+{
-+ struct mtd_blktrans_ops *tr = arg;
-+ struct request_queue *rq = BLK_DEFAULT_QUEUE(tr->major);
-+
-+ /* we might get involved when memory gets low, so use PF_MEMALLOC */
-+ current->flags |= PF_MEMALLOC;
-+
-+ snprintf(current->comm, sizeof(current->comm), "%sd", tr->name);
-+
-+ /* daemonize() doesn't do this for us since some kernel threads
-+ actually want to deal with signals. We can't just call
-+ exit_sighand() since that'll cause an oops when we finally
-+ do exit. */
-+
-+#ifndef __rh_config_h__ /* HAVE_NPTL */
-+ spin_lock_irq(&current->sigmask_lock);
-+ sigfillset(&current->blocked);
-+ recalc_sigpending(current);
-+ spin_unlock_irq(&current->sigmask_lock);
-+#else
-+ spin_lock_irq(&current->sighand->siglock);
-+ sigfillset(&current->blocked);
-+ recalc_sigpending();
-+ spin_unlock_irq(&current->sighand->siglock);
-+#endif
-+ daemonize();
-+
-+ while (!tr->blkcore_priv->exiting) {
-+ struct request *req;
-+ struct mtd_blktrans_dev *dev;
-+ int devnum;
-+ int res = 0;
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+ spin_lock_irq(&io_request_lock);
-+
-+ if (list_empty(&rq->queue_head)) {
-+
-+ add_wait_queue(&tr->blkcore_priv->thread_wq, &wait);
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ spin_unlock_irq(&io_request_lock);
-+
-+ schedule();
-+ remove_wait_queue(&tr->blkcore_priv->thread_wq, &wait);
-+
-+ continue;
-+ }
-+
-+ req = blkdev_entry_next_request(&rq->queue_head);
-+
-+ devnum = MINOR(req->rq_dev) >> tr->part_bits;
-+
-+ /* The ll_rw_blk code knows not to touch the request
-+ at the head of the queue */
-+ spin_unlock_irq(&io_request_lock);
-+
-+ /* FIXME: Where can we store the dev, on which
-+ we already have a refcount anyway? We need to
-+ lock against concurrent addition/removal of devices,
-+ but if we use the mtd_table_mutex we deadlock when
-+ grok_partitions is called from the registration
-+ callbacks. */
-+ spin_lock(&tr->blkcore_priv->devs_lock);
-+ dev = tr_get_dev(tr, devnum);
-+ spin_unlock(&tr->blkcore_priv->devs_lock);
-+
-+ BUG_ON(!dev);
-+
-+ /* Ensure serialisation of requests */
-+ down(&dev->sem);
-+
-+ res = do_blktrans_request(tr, dev, req);
-+ up(&dev->sem);
-+
-+ if (!end_that_request_first(req, res, tr->name)) {
-+ spin_lock_irq(&io_request_lock);
-+ blkdev_dequeue_request(req);
-+ end_that_request_last(req);
-+ spin_unlock_irq(&io_request_lock);
-+ }
-+ }
-+ complete_and_exit(&tr->blkcore_priv->thread_dead, 0);
-+}
-+
-+static void mtd_blktrans_request(struct request_queue *rq)
-+{
-+ struct mtd_blktrans_ops *tr = rq->queuedata;
-+ wake_up(&tr->blkcore_priv->thread_wq);
-+}
-+
-+int blktrans_open(struct inode *i, struct file *f)
-+{
-+ struct mtd_blktrans_ops *tr = NULL;
-+ struct mtd_blktrans_dev *dev = NULL;
-+ int major_nr = MAJOR(i->i_rdev);
-+ int minor_nr = MINOR(i->i_rdev);
-+ int devnum;
-+ int ret = -ENODEV;
-+
-+ if (is_read_only(i->i_rdev) && (f->f_mode & FMODE_WRITE))
-+ return -EROFS;
-+
-+ down(&mtd_table_mutex);
-+
-+ tr = get_tr(major_nr);
-+
-+ if (!tr)
-+ goto out;
-+
-+ devnum = minor_nr >> tr->part_bits;
-+
-+ dev = tr_get_dev(tr, devnum);
-+
-+ if (!dev)
-+ goto out;
-+
-+ if (!tr->blkcore_priv->part_table[minor_nr].nr_sects) {
-+ ret = -ENODEV;
-+ goto out;
-+ }
-+
-+ if (!try_inc_mod_count(dev->mtd->owner))
-+ goto out;
-+
-+ if (!try_inc_mod_count(tr->owner))
-+ goto out_tr;
-+
-+ dev->mtd->usecount++;
-+
-+ ret = 0;
-+ if (tr->open && (ret = tr->open(dev))) {
-+ dev->mtd->usecount--;
-+ if (dev->mtd->owner)
-+ __MOD_DEC_USE_COUNT(dev->mtd->owner);
-+ out_tr:
-+ if (tr->owner)
-+ __MOD_DEC_USE_COUNT(tr->owner);
-+ }
-+ out:
-+ up(&mtd_table_mutex);
-+
-+ return ret;
-+}
-+
-+int blktrans_release(struct inode *i, struct file *f)
-+{
-+ struct mtd_blktrans_dev *dev;
-+ struct mtd_blktrans_ops *tr;
-+ int ret = 0;
-+ int devnum;
-+
-+ down(&mtd_table_mutex);
-+
-+ tr = get_tr(MAJOR(i->i_rdev));
-+ if (!tr) {
-+ up(&mtd_table_mutex);
-+ return -ENODEV;
-+ }
-+
-+ devnum = MINOR(i->i_rdev) >> tr->part_bits;
-+ dev = tr_get_dev(tr, devnum);
-+
-+ if (!dev) {
-+ up(&mtd_table_mutex);
-+ return -ENODEV;
-+ }
-+
-+ if (tr->release)
-+ ret = tr->release(dev);
-+
-+ if (!ret) {
-+ dev->mtd->usecount--;
-+ if (dev->mtd->owner)
-+ __MOD_DEC_USE_COUNT(dev->mtd->owner);
-+ if (tr->owner)
-+ __MOD_DEC_USE_COUNT(tr->owner);
-+ }
-+
-+ up(&mtd_table_mutex);
-+
-+ return ret;
-+}
-+
-+static int mtd_blktrans_rrpart(kdev_t rdev, struct mtd_blktrans_ops *tr,
-+ struct mtd_blktrans_dev *dev)
-+{
-+ struct gendisk *gd = &(tr->blkcore_priv->gd);
-+ int i;
-+ int minor = MINOR(rdev);
-+
-+ if (minor & ((1<<tr->part_bits)-1) || !tr->part_bits) {
-+ /* BLKRRPART on a partition. Go away. */
-+ return -ENOTTY;
-+ }
-+
-+ if (!capable(CAP_SYS_ADMIN))
-+ return -EACCES;
-+
-+ /* We are required to prevent simultaneous open() ourselves.
-+ The core doesn't do that for us. Did I ever mention how
-+ much the Linux block layer sucks? Sledgehammer approach... */
-+ down(&mtd_table_mutex);
-+
-+ for (i=0; i < (1<<tr->part_bits); i++) {
-+ invalidate_device(MKDEV(tr->major, minor+i), 1);
-+ gd->part[minor + i].start_sect = 0;
-+ gd->part[minor + i].nr_sects = 0;
-+ }
-+
-+ grok_partitions(gd, minor, 1 << tr->part_bits,
-+ tr->blkcore_priv->sizes[minor]);
-+ up(&mtd_table_mutex);
-+
-+ return 0;
-+}
-+
-+static int blktrans_ioctl(struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ struct mtd_blktrans_dev *dev;
-+ struct mtd_blktrans_ops *tr;
-+ int devnum;
-+
-+ switch(cmd) {
-+ case BLKGETSIZE:
-+ case BLKGETSIZE64:
-+ case BLKBSZSET:
-+ case BLKBSZGET:
-+ case BLKROSET:
-+ case BLKROGET:
-+ case BLKRASET:
-+ case BLKRAGET:
-+ case BLKPG:
-+ case BLKELVGET:
-+ case BLKELVSET:
-+ return blk_ioctl(inode->i_rdev, cmd, arg);
-+ }
-+
-+ down(&mtd_table_mutex);
-+
-+ tr = get_tr(MAJOR(inode->i_rdev));
-+ if (!tr) {
-+ up(&mtd_table_mutex);
-+ return -ENODEV;
-+ }
-+
-+ devnum = MINOR(inode->i_rdev) >> tr->part_bits;
-+ dev = tr_get_dev(tr, devnum);
-+
-+ up(&mtd_table_mutex);
-+
-+ if (!dev)
-+ return -ENODEV;
-+
-+ switch(cmd) {
-+ case BLKRRPART:
-+ return mtd_blktrans_rrpart(inode->i_rdev, tr, dev);
-+
-+ case BLKFLSBUF:
-+ blk_ioctl(inode->i_rdev, cmd, arg);
-+ if (tr->flush)
-+ return tr->flush(dev);
-+ /* The core code did the work, we had nothing to do. */
-+ return 0;
-+
-+ case HDIO_GETGEO:
-+ if (tr->getgeo) {
-+ struct hd_geometry g;
-+ struct gendisk *gd = &(tr->blkcore_priv->gd);
-+ int ret;
-+
-+ memset(&g, 0, sizeof(g));
-+ ret = tr->getgeo(dev, &g);
-+ if (ret)
-+ return ret;
-+
-+ g.start = gd->part[MINOR(inode->i_rdev)].start_sect;
-+ if (copy_to_user((void *)arg, &g, sizeof(g)))
-+ return -EFAULT;
-+ return 0;
-+ } /* else */
-+ default:
-+ return -ENOTTY;
-+ }
-+}
-+
-+struct block_device_operations mtd_blktrans_ops = {
-+ .owner = THIS_MODULE,
-+ .open = blktrans_open,
-+ .release = blktrans_release,
-+ .ioctl = blktrans_ioctl,
-+};
-+
-+int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
-+{
-+ struct mtd_blktrans_ops *tr = new->tr;
-+ struct list_head *this;
-+ int last_devnum = -1;
-+ int i;
-+
-+ if (!down_trylock(&mtd_table_mutex)) {
-+ up(&mtd_table_mutex);
-+ BUG();
-+ }
-+
-+ spin_lock(&tr->blkcore_priv->devs_lock);
-+
-+ list_for_each(this, &tr->devs) {
-+ struct mtd_blktrans_dev *d = list_entry(this, struct mtd_blktrans_dev, list);
-+ if (new->devnum == -1) {
-+ /* Use first free number */
-+ if (d->devnum != last_devnum+1) {
-+ /* Found a free devnum. Plug it in here */
-+ new->devnum = last_devnum+1;
-+ list_add_tail(&new->list, &d->list);
-+ goto added;
-+ }
-+ } else if (d->devnum == new->devnum) {
-+ /* Required number taken */
-+ spin_unlock(&tr->blkcore_priv->devs_lock);
-+ return -EBUSY;
-+ } else if (d->devnum > new->devnum) {
-+ /* Required number was free */
-+ list_add_tail(&new->list, &d->list);
-+ goto added;
-+ }
-+ last_devnum = d->devnum;
-+ }
-+ if (new->devnum == -1)
-+ new->devnum = last_devnum+1;
-+
-+ if ((new->devnum << tr->part_bits) > 256) {
-+ spin_unlock(&tr->blkcore_priv->devs_lock);
-+ return -EBUSY;
-+ }
-+
-+ init_MUTEX(&new->sem);
-+ list_add_tail(&new->list, &tr->devs);
-+ added:
-+ spin_unlock(&tr->blkcore_priv->devs_lock);
-+
-+ if (!tr->writesect)
-+ new->readonly = 1;
-+
-+ for (i = new->devnum << tr->part_bits;
-+ i < (new->devnum+1) << tr->part_bits;
-+ i++) {
-+ set_device_ro(MKDEV(tr->major, i), new->readonly);
-+ tr->blkcore_priv->blksizes[i] = new->blksize;
-+ tr->blkcore_priv->sizes[i] = 0;
-+ tr->blkcore_priv->part_table[i].nr_sects = 0;
-+ tr->blkcore_priv->part_table[i].start_sect = 0;
-+ }
-+
-+ /*
-+ <viro_zzz> dwmw2: BLOCK_SIZE_BITS has nothing to do with block devices
-+ <viro> dwmw2: any code which sets blk_size[][] should be
-+ size >> 10 /+ 2.4 and its dumb units */
-+
-+ tr->blkcore_priv->sizes[new->devnum << tr->part_bits] =
-+ (new->size * new->blksize) >> 10; /* 2.4 and its dumb units */
-+
-+ /* But this is still in device's sectors? $DEITY knows */
-+ tr->blkcore_priv->part_table[new->devnum << tr->part_bits].nr_sects = new->size;
-+
-+ if (tr->part_bits) {
-+ grok_partitions(&tr->blkcore_priv->gd, new->devnum,
-+ 1 << tr->part_bits, new->size);
-+ }
-+#ifdef CONFIG_DEVFS_FS
-+ if (!tr->part_bits) {
-+ char name[2];
-+
-+ name[0] = '0' + new->devnum;
-+ name[1] = 0;
-+
-+ new->blkcore_priv =
-+ devfs_register(tr->blkcore_priv->devfs_dir_handle,
-+ name, DEVFS_FL_DEFAULT, tr->major,
-+ new->devnum, S_IFBLK|S_IRUGO|S_IWUGO,
-+ &mtd_blktrans_ops, NULL);
-+ }
-+#endif
-+ return 0;
-+}
-+
-+int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
-+{
-+ struct mtd_blktrans_ops *tr = old->tr;
-+ int i;
-+
-+ if (!down_trylock(&mtd_table_mutex)) {
-+ up(&mtd_table_mutex);
-+ BUG();
-+ }
-+
-+#ifdef CONFIG_DEVFS_FS
-+ if (!tr->part_bits) {
-+ devfs_unregister(old->blkcore_priv);
-+ old->blkcore_priv = NULL;
-+ } else {
-+ devfs_register_partitions(&tr->blkcore_priv->gd,
-+ old->devnum << tr->part_bits, 1);
-+ }
-+#endif
-+ spin_lock(&tr->blkcore_priv->devs_lock);
-+ list_del(&old->list);
-+ spin_unlock(&tr->blkcore_priv->devs_lock);
-+
-+ for (i = (old->devnum << tr->part_bits);
-+ i < ((old->devnum+1) << tr->part_bits); i++) {
-+ tr->blkcore_priv->sizes[i] = 0;
-+ tr->blkcore_priv->part_table[i].nr_sects = 0;
-+ tr->blkcore_priv->part_table[i].start_sect = 0;
-+ }
-+
-+ return 0;
-+}
-+
-+void blktrans_notify_remove(struct mtd_info *mtd)
-+{
-+ struct list_head *this, *this2, *next;
-+
-+ list_for_each(this, &blktrans_majors) {
-+ struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);
-+
-+ list_for_each_safe(this2, next, &tr->devs) {
-+ struct mtd_blktrans_dev *dev = list_entry(this2, struct mtd_blktrans_dev, list);
-+
-+ if (dev->mtd == mtd)
-+ tr->remove_dev(dev);
-+ }
-+ }
-+}
-+
-+void blktrans_notify_add(struct mtd_info *mtd)
-+{
-+ struct list_head *this;
-+
-+ if (mtd->type == MTD_ABSENT)
-+ return;
-+
-+ list_for_each(this, &blktrans_majors) {
-+ struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);
-+
-+ tr->add_mtd(tr, mtd);
-+ }
-+
-+}
-+
-+static struct mtd_notifier blktrans_notifier = {
-+ .add = blktrans_notify_add,
-+ .remove = blktrans_notify_remove,
-+};
-+
-+int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
-+{
-+ int ret, i;
-+
-+ /* Register the notifier if/when the first device type is
-+ registered, to prevent the link/init ordering from fucking
-+ us over. */
-+ if (!blktrans_notifier.list.next)
-+ register_mtd_user(&blktrans_notifier);
-+
-+ tr->blkcore_priv = kmalloc(sizeof(*tr->blkcore_priv), GFP_KERNEL);
-+ if (!tr->blkcore_priv)
-+ return -ENOMEM;
-+
-+ memset(tr->blkcore_priv, 0, sizeof(*tr->blkcore_priv));
-+
-+ down(&mtd_table_mutex);
-+
-+ ret = devfs_register_blkdev(tr->major, tr->name, &mtd_blktrans_ops);
-+ if (ret) {
-+ printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n",
-+ tr->name, tr->major, ret);
-+ kfree(tr->blkcore_priv);
-+ up(&mtd_table_mutex);
-+ return ret;
-+ }
-+
-+ blk_init_queue(BLK_DEFAULT_QUEUE(tr->major), &mtd_blktrans_request);
-+ (BLK_DEFAULT_QUEUE(tr->major))->queuedata = tr;
-+
-+ init_completion(&tr->blkcore_priv->thread_dead);
-+ init_waitqueue_head(&tr->blkcore_priv->thread_wq);
-+
-+ ret = kernel_thread(mtd_blktrans_thread, tr,
-+ CLONE_FS|CLONE_FILES|CLONE_SIGHAND);
-+ if (ret < 0) {
-+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(tr->major));
-+ devfs_unregister_blkdev(tr->major, tr->name);
-+ kfree(tr->blkcore_priv);
-+ up(&mtd_table_mutex);
-+ return ret;
-+ }
-+
-+ tr->blkcore_priv->devfs_dir_handle =
-+ devfs_mk_dir(NULL, tr->name, NULL);
-+
-+ blksize_size[tr->major] = tr->blkcore_priv->blksizes;
-+ blk_size[tr->major] = tr->blkcore_priv->sizes;
-+
-+ tr->blkcore_priv->gd.major = tr->major;
-+ tr->blkcore_priv->gd.major_name = tr->name;
-+ tr->blkcore_priv->gd.minor_shift = tr->part_bits;
-+ tr->blkcore_priv->gd.max_p = (1<<tr->part_bits) - 1;
-+ tr->blkcore_priv->gd.part = tr->blkcore_priv->part_table;
-+ tr->blkcore_priv->gd.sizes = tr->blkcore_priv->sizes;
-+ tr->blkcore_priv->gd.nr_real = 256 >> tr->part_bits;
-+
-+ spin_lock_init(&tr->blkcore_priv->devs_lock);
-+
-+ add_gendisk(&tr->blkcore_priv->gd);
-+
-+ INIT_LIST_HEAD(&tr->devs);
-+ list_add(&tr->list, &blktrans_majors);
-+
-+ for (i=0; i<MAX_MTD_DEVICES; i++) {
-+ if (mtd_table[i] && mtd_table[i]->type != MTD_ABSENT)
-+ tr->add_mtd(tr, mtd_table[i]);
-+ }
-+ up(&mtd_table_mutex);
-+
-+ return 0;
-+}
-+
-+int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
-+{
-+ struct list_head *this, *next;
-+
-+ down(&mtd_table_mutex);
-+
-+ /* Clean up the kernel thread */
-+ tr->blkcore_priv->exiting = 1;
-+ wake_up(&tr->blkcore_priv->thread_wq);
-+ wait_for_completion(&tr->blkcore_priv->thread_dead);
-+
-+ /* Remove it from the list of active majors */
-+ list_del(&tr->list);
-+
-+ /* Remove each of its devices */
-+ list_for_each_safe(this, next, &tr->devs) {
-+ struct mtd_blktrans_dev *dev = list_entry(this, struct mtd_blktrans_dev, list);
-+ tr->remove_dev(dev);
-+ }
-+
-+ blksize_size[tr->major] = NULL;
-+ blk_size[tr->major] = NULL;
-+
-+ del_gendisk(&tr->blkcore_priv->gd);
-+
-+ blk_cleanup_queue(BLK_DEFAULT_QUEUE(tr->major));
-+ devfs_unregister_blkdev(tr->major, tr->name);
-+
-+ devfs_unregister(tr->blkcore_priv->devfs_dir_handle);
-+
-+ up(&mtd_table_mutex);
-+
-+ kfree(tr->blkcore_priv);
-+
-+ if (!list_empty(&tr->devs))
-+ BUG();
-+ return 0;
-+}
-+
-+static void __exit mtd_blktrans_exit(void)
-+{
-+ /* No race here -- if someone's currently in register_mtd_blktrans
-+ we're screwed anyway. */
-+ if (blktrans_notifier.list.next)
-+ unregister_mtd_user(&blktrans_notifier);
-+}
-+
-+module_exit(mtd_blktrans_exit);
-+
-+EXPORT_SYMBOL_GPL(register_mtd_blktrans);
-+EXPORT_SYMBOL_GPL(deregister_mtd_blktrans);
-+EXPORT_SYMBOL_GPL(add_mtd_blktrans_dev);
-+EXPORT_SYMBOL_GPL(del_mtd_blktrans_dev);
-+
-+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("Common interface to block layer for MTD 'translation layers'");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/mtd_blkdevs.c linux/drivers/mtd/mtd_blkdevs.c
---- linux-mips-2.4.27/drivers/mtd/mtd_blkdevs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/mtd_blkdevs.c 2004-11-19 10:25:11.642238856 +0100
-@@ -0,0 +1,479 @@
-+/*
-+ * $Id$
-+ *
-+ * (C) 2003 David Woodhouse <dwmw2@infradead.org>
-+ *
-+ * Interface to Linux 2.5 block layer for MTD 'translation layers'.
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/list.h>
-+#include <linux/fs.h>
-+#include <linux/mtd/blktrans.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/blkdev.h>
-+#include <linux/blk.h>
-+#include <linux/blkpg.h>
-+#include <linux/spinlock.h>
-+#include <linux/hdreg.h>
-+#include <linux/init.h>
-+#include <asm/semaphore.h>
-+#include <asm/uaccess.h>
-+#include <linux/devfs_fs_kernel.h>
-+
-+static LIST_HEAD(blktrans_majors);
-+
-+extern struct semaphore mtd_table_mutex;
-+extern struct mtd_info *mtd_table[];
-+
-+struct mtd_blkcore_priv {
-+ struct completion thread_dead;
-+ int exiting;
-+ wait_queue_head_t thread_wq;
-+ struct request_queue *rq;
-+ spinlock_t queue_lock;
-+};
-+
-+static int do_blktrans_request(struct mtd_blktrans_ops *tr,
-+ struct mtd_blktrans_dev *dev,
-+ struct request *req)
-+{
-+ unsigned long block, nsect;
-+ char *buf;
-+
-+ block = req->sector;
-+ nsect = req->current_nr_sectors;
-+ buf = req->buffer;
-+
-+ if (!(req->flags & REQ_CMD))
-+ return 0;
-+
-+ if (block + nsect > get_capacity(req->rq_disk))
-+ return 0;
-+
-+ switch(rq_data_dir(req)) {
-+ case READ:
-+ for (; nsect > 0; nsect--, block++, buf += 512)
-+ if (tr->readsect(dev, block, buf))
-+ return 0;
-+ return 1;
-+
-+ case WRITE:
-+ if (!tr->writesect)
-+ return 0;
-+
-+ for (; nsect > 0; nsect--, block++, buf += 512)
-+ if (tr->writesect(dev, block, buf))
-+ return 0;
-+ return 1;
-+
-+ default:
-+ printk(KERN_NOTICE "Unknown request %ld\n", rq_data_dir(req));
-+ return 0;
-+ }
-+}
-+
-+static int mtd_blktrans_thread(void *arg)
-+{
-+ struct mtd_blktrans_ops *tr = arg;
-+ struct request_queue *rq = tr->blkcore_priv->rq;
-+
-+ /* we might get involved when memory gets low, so use PF_MEMALLOC */
-+ current->flags |= PF_MEMALLOC;
-+
-+ daemonize("%sd", tr->name);
-+
-+ /* daemonize() doesn't do this for us since some kernel threads
-+ actually want to deal with signals. We can't just call
-+ exit_sighand() since that'll cause an oops when we finally
-+ do exit. */
-+ spin_lock_irq(&current->sighand->siglock);
-+ sigfillset(&current->blocked);
-+ recalc_sigpending();
-+ spin_unlock_irq(&current->sighand->siglock);
-+
-+ spin_lock_irq(rq->queue_lock);
-+
-+ while (!tr->blkcore_priv->exiting) {
-+ struct request *req;
-+ struct mtd_blktrans_dev *dev;
-+ int res = 0;
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+ req = elv_next_request(rq);
-+
-+ if (!req) {
-+ add_wait_queue(&tr->blkcore_priv->thread_wq, &wait);
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ spin_unlock_irq(rq->queue_lock);
-+
-+ schedule();
-+ remove_wait_queue(&tr->blkcore_priv->thread_wq, &wait);
-+
-+ spin_lock_irq(rq->queue_lock);
-+
-+ continue;
-+ }
-+
-+ dev = req->rq_disk->private_data;
-+ tr = dev->tr;
-+
-+ spin_unlock_irq(rq->queue_lock);
-+
-+ down(&dev->sem);
-+ res = do_blktrans_request(tr, dev, req);
-+ up(&dev->sem);
-+
-+ spin_lock_irq(rq->queue_lock);
-+
-+ end_request(req, res);
-+ }
-+ complete_and_exit(&tr->blkcore_priv->thread_dead, 0);
-+}
-+
-+static void mtd_blktrans_request(struct request_queue *rq)
-+{
-+ struct mtd_blktrans_ops *tr = rq->queuedata;
-+ wake_up(&tr->blkcore_priv->thread_wq);
-+}
-+
-+
-+int blktrans_open(struct inode *i, struct file *f)
-+{
-+ struct mtd_blktrans_dev *dev;
-+ struct mtd_blktrans_ops *tr;
-+ int ret = -ENODEV;
-+
-+ dev = i->i_bdev->bd_disk->private_data;
-+ tr = dev->tr;
-+
-+ if (!try_module_get(dev->mtd->owner))
-+ goto out;
-+
-+ if (!try_module_get(tr->owner))
-+ goto out_tr;
-+
-+ /* FIXME: Locking. A hot pluggable device can go away
-+ (del_mtd_device can be called for it) without its module
-+ being unloaded. */
-+ dev->mtd->usecount++;
-+
-+ ret = 0;
-+ if (tr->open && (ret = tr->open(dev))) {
-+ dev->mtd->usecount--;
-+ module_put(dev->mtd->owner);
-+ out_tr:
-+ module_put(tr->owner);
-+ }
-+ out:
-+ return ret;
-+}
-+
-+int blktrans_release(struct inode *i, struct file *f)
-+{
-+ struct mtd_blktrans_dev *dev;
-+ struct mtd_blktrans_ops *tr;
-+ int ret = 0;
-+
-+ dev = i->i_bdev->bd_disk->private_data;
-+ tr = dev->tr;
-+
-+ if (tr->release)
-+ ret = tr->release(dev);
-+
-+ if (!ret) {
-+ dev->mtd->usecount--;
-+ module_put(dev->mtd->owner);
-+ module_put(tr->owner);
-+ }
-+
-+ return ret;
-+}
-+
-+
-+static int blktrans_ioctl(struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data;
-+ struct mtd_blktrans_ops *tr = dev->tr;
-+
-+ switch (cmd) {
-+ case BLKFLSBUF:
-+ if (tr->flush)
-+ return tr->flush(dev);
-+ /* The core code did the work, we had nothing to do. */
-+ return 0;
-+
-+ case HDIO_GETGEO:
-+ if (tr->getgeo) {
-+ struct hd_geometry g;
-+ int ret;
-+
-+ memset(&g, 0, sizeof(g));
-+ ret = tr->getgeo(dev, &g);
-+
-+ if (ret)
-+ return ret;
-+
-+ g.start = get_start_sect(inode->i_bdev);
-+ if (copy_to_user((void *)arg, &g, sizeof(g)))
-+ return -EFAULT;
-+ return 0;
-+ } /* else */
-+ default:
-+ return -ENOTTY;
-+ }
-+}
-+
-+struct block_device_operations mtd_blktrans_ops = {
-+ .owner = THIS_MODULE,
-+ .open = blktrans_open,
-+ .release = blktrans_release,
-+ .ioctl = blktrans_ioctl,
-+};
-+
-+int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
-+{
-+ struct mtd_blktrans_ops *tr = new->tr;
-+ struct list_head *this;
-+ int last_devnum = -1;
-+ struct gendisk *gd;
-+
-+ if (!down_trylock(&mtd_table_mutex)) {
-+ up(&mtd_table_mutex);
-+ BUG();
-+ }
-+
-+ list_for_each(this, &tr->devs) {
-+ struct mtd_blktrans_dev *d = list_entry(this, struct mtd_blktrans_dev, list);
-+ if (new->devnum == -1) {
-+ /* Use first free number */
-+ if (d->devnum != last_devnum+1) {
-+ /* Found a free devnum. Plug it in here */
-+ new->devnum = last_devnum+1;
-+ list_add_tail(&new->list, &d->list);
-+ goto added;
-+ }
-+ } else if (d->devnum == new->devnum) {
-+ /* Required number taken */
-+ return -EBUSY;
-+ } else if (d->devnum > new->devnum) {
-+ /* Required number was free */
-+ list_add_tail(&new->list, &d->list);
-+ goto added;
-+ }
-+ last_devnum = d->devnum;
-+ }
-+ if (new->devnum == -1)
-+ new->devnum = last_devnum+1;
-+
-+ if ((new->devnum << tr->part_bits) > 256) {
-+ return -EBUSY;
-+ }
-+
-+ init_MUTEX(&new->sem);
-+ list_add_tail(&new->list, &tr->devs);
-+ added:
-+ if (!tr->writesect)
-+ new->readonly = 1;
-+
-+ gd = alloc_disk(1 << tr->part_bits);
-+ if (!gd) {
-+ list_del(&new->list);
-+ return -ENOMEM;
-+ }
-+ gd->major = tr->major;
-+ gd->first_minor = (new->devnum) << tr->part_bits;
-+ gd->fops = &mtd_blktrans_ops;
-+
-+ snprintf(gd->disk_name, sizeof(gd->disk_name),
-+ "%s%c", tr->name, (tr->part_bits?'a':'0') + new->devnum);
-+ snprintf(gd->devfs_name, sizeof(gd->devfs_name),
-+ "%s/%c", tr->name, (tr->part_bits?'a':'0') + new->devnum);
-+
-+ /* 2.5 has capacity in units of 512 bytes while still
-+ having BLOCK_SIZE_BITS set to 10. Just to keep us amused. */
-+ set_capacity(gd, (new->size * new->blksize) >> 9);
-+
-+ gd->private_data = new;
-+ new->blkcore_priv = gd;
-+ gd->queue = tr->blkcore_priv->rq;
-+
-+ if (new->readonly)
-+ set_disk_ro(gd, 1);
-+
-+ add_disk(gd);
-+
-+ return 0;
-+}
-+
-+int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old)
-+{
-+ if (!down_trylock(&mtd_table_mutex)) {
-+ up(&mtd_table_mutex);
-+ BUG();
-+ }
-+
-+ list_del(&old->list);
-+
-+ del_gendisk(old->blkcore_priv);
-+ put_disk(old->blkcore_priv);
-+
-+ return 0;
-+}
-+
-+void blktrans_notify_remove(struct mtd_info *mtd)
-+{
-+ struct list_head *this, *this2, *next;
-+
-+ list_for_each(this, &blktrans_majors) {
-+ struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);
-+
-+ list_for_each_safe(this2, next, &tr->devs) {
-+ struct mtd_blktrans_dev *dev = list_entry(this2, struct mtd_blktrans_dev, list);
-+
-+ if (dev->mtd == mtd)
-+ tr->remove_dev(dev);
-+ }
-+ }
-+}
-+
-+void blktrans_notify_add(struct mtd_info *mtd)
-+{
-+ struct list_head *this;
-+
-+ if (mtd->type == MTD_ABSENT)
-+ return;
-+
-+ list_for_each(this, &blktrans_majors) {
-+ struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);
-+
-+ tr->add_mtd(tr, mtd);
-+ }
-+
-+}
-+
-+static struct mtd_notifier blktrans_notifier = {
-+ .add = blktrans_notify_add,
-+ .remove = blktrans_notify_remove,
-+};
-+
-+int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
-+{
-+ int ret, i;
-+
-+ /* Register the notifier if/when the first device type is
-+ registered, to prevent the link/init ordering from fucking
-+ us over. */
-+ if (!blktrans_notifier.list.next)
-+ register_mtd_user(&blktrans_notifier);
-+
-+ tr->blkcore_priv = kmalloc(sizeof(*tr->blkcore_priv), GFP_KERNEL);
-+ if (!tr->blkcore_priv)
-+ return -ENOMEM;
-+
-+ memset(tr->blkcore_priv, 0, sizeof(*tr->blkcore_priv));
-+
-+ down(&mtd_table_mutex);
-+
-+ ret = register_blkdev(tr->major, tr->name);
-+ if (ret) {
-+ printk(KERN_WARNING "Unable to register %s block device on major %d: %d\n",
-+ tr->name, tr->major, ret);
-+ kfree(tr->blkcore_priv);
-+ up(&mtd_table_mutex);
-+ return ret;
-+ }
-+ spin_lock_init(&tr->blkcore_priv->queue_lock);
-+ init_completion(&tr->blkcore_priv->thread_dead);
-+ init_waitqueue_head(&tr->blkcore_priv->thread_wq);
-+
-+ tr->blkcore_priv->rq = blk_init_queue(mtd_blktrans_request, &tr->blkcore_priv->queue_lock);
-+ if (!tr->blkcore_priv->rq) {
-+ unregister_blkdev(tr->major, tr->name);
-+ kfree(tr->blkcore_priv);
-+ up(&mtd_table_mutex);
-+ return -ENOMEM;
-+ }
-+
-+ tr->blkcore_priv->rq->queuedata = tr;
-+
-+ ret = kernel_thread(mtd_blktrans_thread, tr,
-+ CLONE_FS|CLONE_FILES|CLONE_SIGHAND);
-+ if (ret < 0) {
-+ blk_cleanup_queue(tr->blkcore_priv->rq);
-+ unregister_blkdev(tr->major, tr->name);
-+ kfree(tr->blkcore_priv);
-+ up(&mtd_table_mutex);
-+ return ret;
-+ }
-+
-+ devfs_mk_dir(tr->name);
-+
-+ INIT_LIST_HEAD(&tr->devs);
-+ list_add(&tr->list, &blktrans_majors);
-+
-+ for (i=0; i<MAX_MTD_DEVICES; i++) {
-+ if (mtd_table[i] && mtd_table[i]->type != MTD_ABSENT)
-+ tr->add_mtd(tr, mtd_table[i]);
-+ }
-+
-+ up(&mtd_table_mutex);
-+
-+ return 0;
-+}
-+
-+int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr)
-+{
-+ struct list_head *this, *next;
-+
-+ down(&mtd_table_mutex);
-+
-+ /* Clean up the kernel thread */
-+ tr->blkcore_priv->exiting = 1;
-+ wake_up(&tr->blkcore_priv->thread_wq);
-+ wait_for_completion(&tr->blkcore_priv->thread_dead);
-+
-+ /* Remove it from the list of active majors */
-+ list_del(&tr->list);
-+
-+ list_for_each_safe(this, next, &tr->devs) {
-+ struct mtd_blktrans_dev *dev = list_entry(this, struct mtd_blktrans_dev, list);
-+ tr->remove_dev(dev);
-+ }
-+
-+ devfs_remove(tr->name);
-+ blk_cleanup_queue(tr->blkcore_priv->rq);
-+ unregister_blkdev(tr->major, tr->name);
-+
-+ up(&mtd_table_mutex);
-+
-+ kfree(tr->blkcore_priv);
-+
-+ if (!list_empty(&tr->devs))
-+ BUG();
-+ return 0;
-+}
-+
-+static void __exit mtd_blktrans_exit(void)
-+{
-+ /* No race here -- if someone's currently in register_mtd_blktrans
-+ we're screwed anyway. */
-+ if (blktrans_notifier.list.next)
-+ unregister_mtd_user(&blktrans_notifier);
-+}
-+
-+module_exit(mtd_blktrans_exit);
-+
-+EXPORT_SYMBOL_GPL(register_mtd_blktrans);
-+EXPORT_SYMBOL_GPL(deregister_mtd_blktrans);
-+EXPORT_SYMBOL_GPL(add_mtd_blktrans_dev);
-+EXPORT_SYMBOL_GPL(del_mtd_blktrans_dev);
-+
-+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("Common interface to block layer for MTD 'translation layers'");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/mtdblock.c linux/drivers/mtd/mtdblock.c
---- linux-mips-2.4.27/drivers/mtd/mtdblock.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/mtdblock.c 2004-11-19 10:25:11.643238704 +0100
-@@ -1,52 +1,25 @@
- /*
- * Direct MTD block device access
- *
-- * $Id$
-+ * $Id$
- *
-- * 02-nov-2000 Nicolas Pitre Added read-modify-write with cache
-+ * (C) 2000-2003 Nicolas Pitre <nico@cam.org>
-+ * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
- */
-
- #include <linux/config.h>
- #include <linux/types.h>
- #include <linux/module.h>
- #include <linux/kernel.h>
-+#include <linux/fs.h>
-+#include <linux/init.h>
- #include <linux/slab.h>
-+#include <linux/vmalloc.h>
- #include <linux/mtd/mtd.h>
--#include <linux/mtd/compatmac.h>
--
--#define MAJOR_NR MTD_BLOCK_MAJOR
--#define DEVICE_NAME "mtdblock"
--#define DEVICE_REQUEST mtdblock_request
--#define DEVICE_NR(device) (device)
--#define DEVICE_ON(device)
--#define DEVICE_OFF(device)
--#define DEVICE_NO_RANDOM
--#include <linux/blk.h>
--/* for old kernels... */
--#ifndef QUEUE_EMPTY
--#define QUEUE_EMPTY (!CURRENT)
--#endif
--#if LINUX_VERSION_CODE < 0x20300
--#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].plug_tq.sync)
--#else
--#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].request_queue.plugged)
--#endif
--
--#ifdef CONFIG_DEVFS_FS
--#include <linux/devfs_fs_kernel.h>
--static void mtd_notify_add(struct mtd_info* mtd);
--static void mtd_notify_remove(struct mtd_info* mtd);
--static struct mtd_notifier notifier = {
-- mtd_notify_add,
-- mtd_notify_remove,
-- NULL
--};
--static devfs_handle_t devfs_dir_handle = NULL;
--static devfs_handle_t devfs_rw_handle[MAX_MTD_DEVICES];
--#endif
-+#include <linux/mtd/blktrans.h>
-
- static struct mtdblk_dev {
-- struct mtd_info *mtd; /* Locked */
-+ struct mtd_info *mtd;
- int count;
- struct semaphore cache_sem;
- unsigned char *cache_data;
-@@ -55,19 +28,6 @@
- enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state;
- } *mtdblks[MAX_MTD_DEVICES];
-
--static spinlock_t mtdblks_lock;
--
--static int mtd_sizes[MAX_MTD_DEVICES];
--static int mtd_blksizes[MAX_MTD_DEVICES];
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
--#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
--#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
--#else
--#define BLK_INC_USE_COUNT do {} while(0)
--#define BLK_DEC_USE_COUNT do {} while(0)
--#endif
--
- /*
- * Cache stuff...
- *
-@@ -151,7 +111,7 @@
- return ret;
-
- /*
-- * Here we could argably set the cache state to STATE_CLEAN.
-+ * Here we could argubly set the cache state to STATE_CLEAN.
- * However this could lead to inconsistency since we will not
- * be notified if this content is altered on the flash by other
- * means. Let's declare it empty and leave buffering tasks to
-@@ -277,57 +237,47 @@
- return 0;
- }
-
-+static int mtdblock_readsect(struct mtd_blktrans_dev *dev,
-+ unsigned long block, char *buf)
-+{
-+ struct mtdblk_dev *mtdblk = mtdblks[dev->devnum];
-+ return do_cached_read(mtdblk, block<<9, 512, buf);
-+}
-
-+static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
-+ unsigned long block, char *buf)
-+{
-+ struct mtdblk_dev *mtdblk = mtdblks[dev->devnum];
-+ if (unlikely(!mtdblk->cache_data)) {
-+ mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize);
-+ if (!mtdblk->cache_data)
-+ return -EINTR;
-+ /* -EINTR is not really correct, but it is the best match
-+ * documented in man 2 write for all cases. We could also
-+ * return -EAGAIN sometimes, but why bother?
-+ */
-+ }
-+ return do_cached_write(mtdblk, block<<9, 512, buf);
-+}
-
--static int mtdblock_open(struct inode *inode, struct file *file)
-+static int mtdblock_open(struct mtd_blktrans_dev *mbd)
- {
- struct mtdblk_dev *mtdblk;
-- struct mtd_info *mtd;
-- int dev;
-+ struct mtd_info *mtd = mbd->mtd;
-+ int dev = mbd->devnum;
-
- DEBUG(MTD_DEBUG_LEVEL1,"mtdblock_open\n");
-
-- if (!inode)
-- return -EINVAL;
--
-- dev = MINOR(inode->i_rdev);
-- if (dev >= MAX_MTD_DEVICES)
-- return -EINVAL;
--
-- BLK_INC_USE_COUNT;
--
-- mtd = get_mtd_device(NULL, dev);
-- if (!mtd)
-- return -ENODEV;
-- if (MTD_ABSENT == mtd->type) {
-- put_mtd_device(mtd);
-- BLK_DEC_USE_COUNT;
-- return -ENODEV;
-- }
--
-- spin_lock(&mtdblks_lock);
--
-- /* If it's already open, no need to piss about. */
- if (mtdblks[dev]) {
- mtdblks[dev]->count++;
-- spin_unlock(&mtdblks_lock);
-- put_mtd_device(mtd);
- return 0;
- }
-
-- /* OK, it's not open. Try to find it */
--
-- /* First we have to drop the lock, because we have to
-- to things which might sleep.
-- */
-- spin_unlock(&mtdblks_lock);
--
-+ /* OK, it's not open. Create cache info for it */
- mtdblk = kmalloc(sizeof(struct mtdblk_dev), GFP_KERNEL);
-- if (!mtdblk) {
-- put_mtd_device(mtd);
-- BLK_DEC_USE_COUNT;
-+ if (!mtdblk)
- return -ENOMEM;
-- }
-+
- memset(mtdblk, 0, sizeof(*mtdblk));
- mtdblk->count = 1;
- mtdblk->mtd = mtd;
-@@ -337,336 +287,102 @@
- if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM &&
- mtdblk->mtd->erasesize) {
- mtdblk->cache_size = mtdblk->mtd->erasesize;
-- mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize);
-- if (!mtdblk->cache_data) {
-- put_mtd_device(mtdblk->mtd);
-- kfree(mtdblk);
-- BLK_DEC_USE_COUNT;
-- return -ENOMEM;
-- }
-- }
--
-- /* OK, we've created a new one. Add it to the list. */
--
-- spin_lock(&mtdblks_lock);
--
-- if (mtdblks[dev]) {
-- /* Another CPU made one at the same time as us. */
-- mtdblks[dev]->count++;
-- spin_unlock(&mtdblks_lock);
-- put_mtd_device(mtdblk->mtd);
-- vfree(mtdblk->cache_data);
-- kfree(mtdblk);
-- return 0;
-+ mtdblk->cache_data = NULL;
- }
-
- mtdblks[dev] = mtdblk;
-- mtd_sizes[dev] = mtdblk->mtd->size/1024;
-- if (mtdblk->mtd->erasesize)
-- mtd_blksizes[dev] = mtdblk->mtd->erasesize;
-- if (mtd_blksizes[dev] > PAGE_SIZE)
-- mtd_blksizes[dev] = PAGE_SIZE;
-- set_device_ro (inode->i_rdev, !(mtdblk->mtd->flags & MTD_WRITEABLE));
--
-- spin_unlock(&mtdblks_lock);
-
- DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
-
- return 0;
- }
-
--static release_t mtdblock_release(struct inode *inode, struct file *file)
-+static int mtdblock_release(struct mtd_blktrans_dev *mbd)
- {
-- int dev;
-- struct mtdblk_dev *mtdblk;
-- DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n");
-+ int dev = mbd->devnum;
-+ struct mtdblk_dev *mtdblk = mtdblks[dev];
-
-- if (inode == NULL)
-- release_return(-ENODEV);
--
-- dev = MINOR(inode->i_rdev);
-- mtdblk = mtdblks[dev];
-+ DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n");
-
- down(&mtdblk->cache_sem);
- write_cached_data(mtdblk);
- up(&mtdblk->cache_sem);
-
-- spin_lock(&mtdblks_lock);
- if (!--mtdblk->count) {
- /* It was the last usage. Free the device */
- mtdblks[dev] = NULL;
-- spin_unlock(&mtdblks_lock);
- if (mtdblk->mtd->sync)
- mtdblk->mtd->sync(mtdblk->mtd);
-- put_mtd_device(mtdblk->mtd);
- vfree(mtdblk->cache_data);
- kfree(mtdblk);
-- } else {
-- spin_unlock(&mtdblks_lock);
- }
--
- DEBUG(MTD_DEBUG_LEVEL1, "ok\n");
-
-- BLK_DEC_USE_COUNT;
-- release_return(0);
--}
--
--
--/*
-- * This is a special request_fn because it is executed in a process context
-- * to be able to sleep independently of the caller. The io_request_lock
-- * is held upon entry and exit.
-- * The head of our request queue is considered active so there is no need
-- * to dequeue requests before we are done.
-- */
--static void handle_mtdblock_request(void)
--{
-- struct request *req;
-- struct mtdblk_dev *mtdblk;
-- unsigned int res;
--
-- for (;;) {
-- INIT_REQUEST;
-- req = CURRENT;
-- spin_unlock_irq(&io_request_lock);
-- mtdblk = mtdblks[MINOR(req->rq_dev)];
-- res = 0;
--
-- if (MINOR(req->rq_dev) >= MAX_MTD_DEVICES)
-- panic("%s: minor out of bounds", __FUNCTION__);
--
-- if ((req->sector + req->current_nr_sectors) > (mtdblk->mtd->size >> 9))
-- goto end_req;
--
-- // Handle the request
-- switch (req->cmd)
-- {
-- int err;
--
-- case READ:
-- down(&mtdblk->cache_sem);
-- err = do_cached_read (mtdblk, req->sector << 9,
-- req->current_nr_sectors << 9,
-- req->buffer);
-- up(&mtdblk->cache_sem);
-- if (!err)
-- res = 1;
-- break;
--
-- case WRITE:
-- // Read only device
-- if ( !(mtdblk->mtd->flags & MTD_WRITEABLE) )
-- break;
--
-- // Do the write
-- down(&mtdblk->cache_sem);
-- err = do_cached_write (mtdblk, req->sector << 9,
-- req->current_nr_sectors << 9,
-- req->buffer);
-- up(&mtdblk->cache_sem);
-- if (!err)
-- res = 1;
-- break;
-- }
--
--end_req:
-- spin_lock_irq(&io_request_lock);
-- end_request(res);
-- }
--}
--
--static volatile int leaving = 0;
--static DECLARE_MUTEX_LOCKED(thread_sem);
--static DECLARE_WAIT_QUEUE_HEAD(thr_wq);
--
--int mtdblock_thread(void *dummy)
--{
-- struct task_struct *tsk = current;
-- DECLARE_WAITQUEUE(wait, tsk);
--
-- /* we might get involved when memory gets low, so use PF_MEMALLOC */
-- tsk->flags |= PF_MEMALLOC;
-- strcpy(tsk->comm, "mtdblockd");
-- spin_lock_irq(&tsk->sigmask_lock);
-- sigfillset(&tsk->blocked);
-- recalc_sigpending(tsk);
-- spin_unlock_irq(&tsk->sigmask_lock);
-- daemonize();
--
-- while (!leaving) {
-- add_wait_queue(&thr_wq, &wait);
-- set_current_state(TASK_INTERRUPTIBLE);
-- spin_lock_irq(&io_request_lock);
-- if (QUEUE_EMPTY || QUEUE_PLUGGED) {
-- spin_unlock_irq(&io_request_lock);
-- schedule();
-- remove_wait_queue(&thr_wq, &wait);
-- } else {
-- remove_wait_queue(&thr_wq, &wait);
-- set_current_state(TASK_RUNNING);
-- handle_mtdblock_request();
-- spin_unlock_irq(&io_request_lock);
-- }
-- }
--
-- up(&thread_sem);
- return 0;
- }
-
--#if LINUX_VERSION_CODE < 0x20300
--#define RQFUNC_ARG void
--#else
--#define RQFUNC_ARG request_queue_t *q
--#endif
--
--static void mtdblock_request(RQFUNC_ARG)
-+static int mtdblock_flush(struct mtd_blktrans_dev *dev)
- {
-- /* Don't do anything, except wake the thread if necessary */
-- wake_up(&thr_wq);
--}
-+ struct mtdblk_dev *mtdblk = mtdblks[dev->devnum];
-
--
--static int mtdblock_ioctl(struct inode * inode, struct file * file,
-- unsigned int cmd, unsigned long arg)
--{
-- struct mtdblk_dev *mtdblk;
--
-- mtdblk = mtdblks[MINOR(inode->i_rdev)];
--
--#ifdef PARANOIA
-- if (!mtdblk)
-- BUG();
--#endif
--
-- switch (cmd) {
-- case BLKGETSIZE: /* Return device size */
-- return put_user((mtdblk->mtd->size >> 9), (unsigned long *) arg);
--
--#ifdef BLKGETSIZE64
-- case BLKGETSIZE64:
-- return put_user((u64)mtdblk->mtd->size, (u64 *)arg);
--#endif
--
-- case BLKFLSBUF:
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-- if(!capable(CAP_SYS_ADMIN))
-- return -EACCES;
--#endif
-- fsync_dev(inode->i_rdev);
-- invalidate_buffers(inode->i_rdev);
- down(&mtdblk->cache_sem);
- write_cached_data(mtdblk);
- up(&mtdblk->cache_sem);
-+
- if (mtdblk->mtd->sync)
- mtdblk->mtd->sync(mtdblk->mtd);
- return 0;
--
-- default:
-- return -EINVAL;
-- }
- }
-
--#if LINUX_VERSION_CODE < 0x20326
--static struct file_operations mtd_fops =
-+static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
- {
-- open: mtdblock_open,
-- ioctl: mtdblock_ioctl,
-- release: mtdblock_release,
-- read: block_read,
-- write: block_write
--};
--#else
--static struct block_device_operations mtd_fops =
--{
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14)
-- owner: THIS_MODULE,
--#endif
-- open: mtdblock_open,
-- release: mtdblock_release,
-- ioctl: mtdblock_ioctl
--};
--#endif
-+ struct mtd_blktrans_dev *dev = kmalloc(sizeof(*dev), GFP_KERNEL);
-
--#ifdef CONFIG_DEVFS_FS
--/* Notification that a new device has been added. Create the devfs entry for
-- * it. */
--
--static void mtd_notify_add(struct mtd_info* mtd)
--{
-- char name[8];
--
-- if (!mtd || mtd->type == MTD_ABSENT)
-+ if (!dev)
- return;
-
-- sprintf(name, "%d", mtd->index);
-- devfs_rw_handle[mtd->index] = devfs_register(devfs_dir_handle, name,
-- DEVFS_FL_DEFAULT, MTD_BLOCK_MAJOR, mtd->index,
-- S_IFBLK | S_IRUGO | S_IWUGO,
-- &mtd_fops, NULL);
--}
--
--static void mtd_notify_remove(struct mtd_info* mtd)
--{
-- if (!mtd || mtd->type == MTD_ABSENT)
-- return;
-+ memset(dev, 0, sizeof(*dev));
-
-- devfs_unregister(devfs_rw_handle[mtd->index]);
--}
--#endif
-+ dev->mtd = mtd;
-+ dev->devnum = mtd->index;
-+ dev->blksize = 512;
-+ dev->size = mtd->size >> 9;
-+ dev->tr = tr;
-+
-+ if (!(mtd->flags & MTD_WRITEABLE))
-+ dev->readonly = 1;
-+
-+ add_mtd_blktrans_dev(dev);
-+}
-+
-+static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
-+{
-+ del_mtd_blktrans_dev(dev);
-+ kfree(dev);
-+}
-+
-+struct mtd_blktrans_ops mtdblock_tr = {
-+ .name = "mtdblock",
-+ .major = 31,
-+ .part_bits = 0,
-+ .open = mtdblock_open,
-+ .flush = mtdblock_flush,
-+ .release = mtdblock_release,
-+ .readsect = mtdblock_readsect,
-+ .writesect = mtdblock_writesect,
-+ .add_mtd = mtdblock_add_mtd,
-+ .remove_dev = mtdblock_remove_dev,
-+ .owner = THIS_MODULE,
-+};
-
- int __init init_mtdblock(void)
- {
-- int i;
--
-- spin_lock_init(&mtdblks_lock);
--#ifdef CONFIG_DEVFS_FS
-- if (devfs_register_blkdev(MTD_BLOCK_MAJOR, DEVICE_NAME, &mtd_fops))
-- {
-- printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
-- MTD_BLOCK_MAJOR);
-- return -EAGAIN;
-- }
--
-- devfs_dir_handle = devfs_mk_dir(NULL, DEVICE_NAME, NULL);
-- register_mtd_user(&notifier);
--#else
-- if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) {
-- printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
-- MTD_BLOCK_MAJOR);
-- return -EAGAIN;
-- }
--#endif
--
-- /* We fill it in at open() time. */
-- for (i=0; i< MAX_MTD_DEVICES; i++) {
-- mtd_sizes[i] = 0;
-- mtd_blksizes[i] = BLOCK_SIZE;
-- }
-- init_waitqueue_head(&thr_wq);
-- /* Allow the block size to default to BLOCK_SIZE. */
-- blksize_size[MAJOR_NR] = mtd_blksizes;
-- blk_size[MAJOR_NR] = mtd_sizes;
--
-- blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request);
-- kernel_thread (mtdblock_thread, NULL, CLONE_FS|CLONE_FILES|CLONE_SIGHAND);
-- return 0;
-+ return register_mtd_blktrans(&mtdblock_tr);
- }
-
- static void __exit cleanup_mtdblock(void)
- {
-- leaving = 1;
-- wake_up(&thr_wq);
-- down(&thread_sem);
--#ifdef CONFIG_DEVFS_FS
-- unregister_mtd_user(&notifier);
-- devfs_unregister(devfs_dir_handle);
-- devfs_unregister_blkdev(MTD_BLOCK_MAJOR, DEVICE_NAME);
--#else
-- unregister_blkdev(MAJOR_NR,DEVICE_NAME);
--#endif
-- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-- blksize_size[MAJOR_NR] = NULL;
-- blk_size[MAJOR_NR] = NULL;
-+ deregister_mtd_blktrans(&mtdblock_tr);
- }
-
- module_init(init_mtdblock);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/mtdblock_ro.c linux/drivers/mtd/mtdblock_ro.c
---- linux-mips-2.4.27/drivers/mtd/mtdblock_ro.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/mtdblock_ro.c 2004-11-19 10:25:11.645238400 +0100
-@@ -1,301 +1,87 @@
- /*
-- * $Id$
-+ * $Id$
- *
-- * Read-only version of the mtdblock device, without the
-- * read/erase/modify/writeback stuff
-+ * (C) 2003 David Woodhouse <dwmw2@infradead.org>
-+ *
-+ * Simple read-only (writable only for RAM) mtdblock driver
- */
-
--#ifdef MTDBLOCK_DEBUG
--#define DEBUGLVL debug
--#endif
--
--
--#include <linux/module.h>
--#include <linux/types.h>
--
-+#include <linux/init.h>
-+#include <linux/slab.h>
- #include <linux/mtd/mtd.h>
--#include <linux/mtd/compatmac.h>
--
--#define MAJOR_NR MTD_BLOCK_MAJOR
--#define DEVICE_NAME "mtdblock"
--#define DEVICE_REQUEST mtdblock_request
--#define DEVICE_NR(device) (device)
--#define DEVICE_ON(device)
--#define DEVICE_OFF(device)
--#define DEVICE_NO_RANDOM
--#include <linux/blk.h>
--
--#if LINUX_VERSION_CODE < 0x20300
--#define RQFUNC_ARG void
--#define blkdev_dequeue_request(req) do {CURRENT = req->next;} while (0)
--#else
--#define RQFUNC_ARG request_queue_t *q
--#endif
--
--#ifdef MTDBLOCK_DEBUG
--static int debug = MTDBLOCK_DEBUG;
--MODULE_PARM(debug, "i");
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
--#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
--#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
--#else
--#define BLK_INC_USE_COUNT do {} while(0)
--#define BLK_DEC_USE_COUNT do {} while(0)
--#endif
--
--static int mtd_sizes[MAX_MTD_DEVICES];
-+#include <linux/mtd/blktrans.h>
-
--
--static int mtdblock_open(struct inode *inode, struct file *file)
-+static int mtdblock_readsect(struct mtd_blktrans_dev *dev,
-+ unsigned long block, char *buf)
- {
-- struct mtd_info *mtd = NULL;
--
-- int dev;
--
-- DEBUG(1,"mtdblock_open\n");
--
-- if (inode == 0)
-- return -EINVAL;
--
-- dev = MINOR(inode->i_rdev);
--
-- mtd = get_mtd_device(NULL, dev);
-- if (!mtd)
-- return -EINVAL;
-- if (MTD_ABSENT == mtd->type) {
-- put_mtd_device(mtd);
-- return -EINVAL;
-- }
--
-- BLK_INC_USE_COUNT;
--
-- mtd_sizes[dev] = mtd->size>>9;
--
-- DEBUG(1, "ok\n");
-+ size_t retlen;
-
-+ if (dev->mtd->read(dev->mtd, (block * 512), 512, &retlen, buf))
-+ return 1;
- return 0;
- }
-
--static release_t mtdblock_release(struct inode *inode, struct file *file)
-+static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
-+ unsigned long block, char *buf)
- {
-- int dev;
-- struct mtd_info *mtd;
--
-- DEBUG(1, "mtdblock_release\n");
--
-- if (inode == NULL)
-- release_return(-ENODEV);
--
-- dev = MINOR(inode->i_rdev);
-- mtd = __get_mtd_device(NULL, dev);
--
-- if (!mtd) {
-- printk(KERN_WARNING "MTD device is absent on mtd_release!\n");
-- BLK_DEC_USE_COUNT;
-- release_return(-ENODEV);
-- }
--
-- if (mtd->sync)
-- mtd->sync(mtd);
--
-- put_mtd_device(mtd);
--
-- DEBUG(1, "ok\n");
-+ size_t retlen;
-
-- BLK_DEC_USE_COUNT;
-- release_return(0);
-+ if (dev->mtd->write(dev->mtd, (block * 512), 512, &retlen, buf))
-+ return 1;
-+ return 0;
- }
-
--
--static void mtdblock_request(RQFUNC_ARG)
-+static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
- {
-- struct request *current_request;
-- unsigned int res = 0;
-- struct mtd_info *mtd;
--
-- while (1)
-- {
-- /* Grab the Request and unlink it from the request list, INIT_REQUEST
-- will execute a return if we are done. */
-- INIT_REQUEST;
-- current_request = CURRENT;
--
-- if (MINOR(current_request->rq_dev) >= MAX_MTD_DEVICES)
-- {
-- printk("mtd: Unsupported device!\n");
-- end_request(0);
-- continue;
-- }
--
-- // Grab our MTD structure
--
-- mtd = __get_mtd_device(NULL, MINOR(current_request->rq_dev));
-- if (!mtd) {
-- printk("MTD device %d doesn't appear to exist any more\n", CURRENT_DEV);
-- end_request(0);
-- }
--
-- if (current_request->sector << 9 > mtd->size ||
-- (current_request->sector + current_request->current_nr_sectors) << 9 > mtd->size)
-- {
-- printk("mtd: Attempt to read past end of device!\n");
-- printk("size: %x, sector: %lx, nr_sectors %lx\n", mtd->size,
-- current_request->sector, current_request->current_nr_sectors);
-- end_request(0);
-- continue;
-- }
--
-- /* Remove the request we are handling from the request list so nobody messes
-- with it */
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-- /* Now drop the lock that the ll_rw_blk functions grabbed for us
-- and process the request. This is necessary due to the extreme time
-- we spend processing it. */
-- spin_unlock_irq(&io_request_lock);
--#endif
--
-- // Handle the request
-- switch (current_request->cmd)
-- {
-- size_t retlen;
-+ struct mtd_blktrans_dev *dev = kmalloc(sizeof(*dev), GFP_KERNEL);
-
-- case READ:
-- if (MTD_READ(mtd,current_request->sector<<9,
-- current_request->current_nr_sectors << 9,
-- &retlen, current_request->buffer) == 0)
-- res = 1;
-- else
-- res = 0;
-- break;
-+ if (!dev)
-+ return;
-
-- case WRITE:
-+ memset(dev, 0, sizeof(*dev));
-
-- /* printk("mtdblock_request WRITE sector=%d(%d)\n",current_request->sector,
-- current_request->current_nr_sectors);
-- */
-+ dev->mtd = mtd;
-+ dev->devnum = mtd->index;
-+ dev->blksize = 512;
-+ dev->size = mtd->size >> 9;
-+ dev->tr = tr;
-+ if ((mtd->flags & (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEABLE)) !=
-+ (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEABLE))
-+ dev->readonly = 1;
-
-- // Read only device
-- if ((mtd->flags & MTD_CAP_RAM) == 0)
-- {
-- res = 0;
-- break;
-- }
--
-- // Do the write
-- if (MTD_WRITE(mtd,current_request->sector<<9,
-- current_request->current_nr_sectors << 9,
-- &retlen, current_request->buffer) == 0)
-- res = 1;
-- else
-- res = 0;
-- break;
--
-- // Shouldn't happen
-- default:
-- printk("mtd: unknown request\n");
-- break;
-- }
--
-- // Grab the lock and re-thread the item onto the linked list
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-- spin_lock_irq(&io_request_lock);
--#endif
-- end_request(res);
-- }
-+ add_mtd_blktrans_dev(dev);
- }
-
--
--
--static int mtdblock_ioctl(struct inode * inode, struct file * file,
-- unsigned int cmd, unsigned long arg)
-+static void mtdblock_remove_dev(struct mtd_blktrans_dev *dev)
- {
-- struct mtd_info *mtd;
--
-- mtd = __get_mtd_device(NULL, MINOR(inode->i_rdev));
--
-- if (!mtd) return -EINVAL;
--
-- switch (cmd) {
-- case BLKGETSIZE: /* Return device size */
-- return put_user((mtd->size >> 9), (unsigned long *) arg);
--
--#ifdef BLKGETSIZE64
-- case BLKGETSIZE64:
-- return put_user((u64)mtd->size, (u64 *)arg);
--#endif
--
-- case BLKFLSBUF:
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-- if(!capable(CAP_SYS_ADMIN)) return -EACCES;
--#endif
-- fsync_dev(inode->i_rdev);
-- invalidate_buffers(inode->i_rdev);
-- if (mtd->sync)
-- mtd->sync(mtd);
-- return 0;
--
-- default:
-- return -ENOTTY;
-- }
-+ del_mtd_blktrans_dev(dev);
-+ kfree(dev);
- }
-
--#if LINUX_VERSION_CODE < 0x20326
--static struct file_operations mtd_fops =
--{
-- open: mtdblock_open,
-- ioctl: mtdblock_ioctl,
-- release: mtdblock_release,
-- read: block_read,
-- write: block_write
--};
--#else
--static struct block_device_operations mtd_fops =
--{
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14)
-- owner: THIS_MODULE,
--#endif
-- open: mtdblock_open,
-- release: mtdblock_release,
-- ioctl: mtdblock_ioctl
-+struct mtd_blktrans_ops mtdblock_tr = {
-+ .name = "mtdblock",
-+ .major = 31,
-+ .part_bits = 0,
-+ .readsect = mtdblock_readsect,
-+ .writesect = mtdblock_writesect,
-+ .add_mtd = mtdblock_add_mtd,
-+ .remove_dev = mtdblock_remove_dev,
-+ .owner = THIS_MODULE,
- };
--#endif
-
--int __init init_mtdblock(void)
-+static int __init mtdblock_init(void)
- {
-- int i;
--
-- if (register_blkdev(MAJOR_NR,DEVICE_NAME,&mtd_fops)) {
-- printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
-- MTD_BLOCK_MAJOR);
-- return -EAGAIN;
-- }
--
-- /* We fill it in at open() time. */
-- for (i=0; i< MAX_MTD_DEVICES; i++) {
-- mtd_sizes[i] = 0;
-- }
--
-- /* Allow the block size to default to BLOCK_SIZE. */
-- blksize_size[MAJOR_NR] = NULL;
-- blk_size[MAJOR_NR] = mtd_sizes;
--
-- blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &mtdblock_request);
-- return 0;
-+ return register_mtd_blktrans(&mtdblock_tr);
- }
-
--static void __exit cleanup_mtdblock(void)
-+static void __exit mtdblock_exit(void)
- {
-- unregister_blkdev(MAJOR_NR,DEVICE_NAME);
-- blk_size[MAJOR_NR] = NULL;
-- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
-+ deregister_mtd_blktrans(&mtdblock_tr);
- }
-
--module_init(init_mtdblock);
--module_exit(cleanup_mtdblock);
--
-+module_init(mtdblock_init);
-+module_exit(mtdblock_exit);
-
- MODULE_LICENSE("GPL");
--MODULE_AUTHOR("Erwin Authried <eauth@softsys.co.at> et al.");
-+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
- MODULE_DESCRIPTION("Simple read-only block device emulation access to MTD devices");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/mtdchar.c linux/drivers/mtd/mtdchar.c
---- linux-mips-2.4.27/drivers/mtd/mtdchar.c 2004-08-14 20:38:51.000000000 +0200
-+++ linux/drivers/mtd/mtdchar.c 2004-11-19 10:25:11.647238096 +0100
-@@ -1,8 +1,7 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Character-device access to raw MTD devices.
-- * Pure 2.4 version - compatibility cruft removed to mtdchar-compat.c
- *
- */
-
-@@ -10,7 +9,11 @@
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/mtd/mtd.h>
-+#include <linux/mtd/compatmac.h>
- #include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/fs.h>
-+#include <asm/uaccess.h>
-
- #ifdef CONFIG_DEVFS_FS
- #include <linux/devfs_fs_kernel.h>
-@@ -18,8 +21,8 @@
- static void mtd_notify_remove(struct mtd_info* mtd);
-
- static struct mtd_notifier notifier = {
-- add: mtd_notify_add,
-- remove: mtd_notify_remove,
-+ .add = mtd_notify_add,
-+ .remove = mtd_notify_remove,
- };
-
- static devfs_handle_t devfs_dir_handle;
-@@ -60,7 +63,7 @@
-
- static int mtd_open(struct inode *inode, struct file *file)
- {
-- int minor = minor(inode->i_rdev);
-+ int minor = iminor(inode);
- int devnum = minor >> 1;
- struct mtd_info *mtd;
-
-@@ -125,15 +128,11 @@
- int ret=0;
- int len;
- char *kbuf;
-- loff_t pos = *ppos;
-
- DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n");
-
-- if (pos < 0 || pos > mtd->size)
-- return 0;
--
-- if (count > mtd->size - pos)
-- count = mtd->size - pos;
-+ if (*ppos + count > mtd->size)
-+ count = mtd->size - *ppos;
-
- if (!count)
- return 0;
-@@ -150,9 +149,9 @@
- if (!kbuf)
- return -ENOMEM;
-
-- ret = MTD_READ(mtd, pos, len, &retlen, kbuf);
-+ ret = MTD_READ(mtd, *ppos, len, &retlen, kbuf);
- if (!ret) {
-- pos += retlen;
-+ *ppos += retlen;
- if (copy_to_user(buf, kbuf, retlen)) {
- kfree(kbuf);
- return -EFAULT;
-@@ -171,8 +170,6 @@
- kfree(kbuf);
- }
-
-- *ppos = pos;
--
- return total_retlen;
- } /* mtd_read */
-
-@@ -182,17 +179,16 @@
- char *kbuf;
- size_t retlen;
- size_t total_retlen=0;
-- loff_t pos = *ppos;
- int ret=0;
- int len;
-
- DEBUG(MTD_DEBUG_LEVEL0,"MTD_write\n");
-
-- if (pos < 0 || pos >= mtd->size)
-+ if (*ppos == mtd->size)
- return -ENOSPC;
-
-- if (count > mtd->size - pos)
-- count = mtd->size - pos;
-+ if (*ppos + count > mtd->size)
-+ count = mtd->size - *ppos;
-
- if (!count)
- return 0;
-@@ -214,9 +210,9 @@
- return -EFAULT;
- }
-
-- ret = (*(mtd->write))(mtd, pos, len, &retlen, kbuf);
-+ ret = (*(mtd->write))(mtd, *ppos, len, &retlen, kbuf);
- if (!ret) {
-- pos += retlen;
-+ *ppos += retlen;
- total_retlen += retlen;
- count -= retlen;
- buf += retlen;
-@@ -228,7 +224,6 @@
-
- kfree(kbuf);
- }
-- *ppos = pos;
-
- return total_retlen;
- } /* mtd_write */
-@@ -450,81 +445,13 @@
- break;
- }
-
-- case MEMWRITEDATA:
-- {
-- struct mtd_oob_buf buf;
-- void *databuf;
-- ssize_t retlen;
--
-- if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf)))
-- return -EFAULT;
--
-- if (buf.length > 0x4096)
-- return -EINVAL;
--
-- if (!mtd->write_ecc)
-- ret = -EOPNOTSUPP;
-- else
-- ret = verify_area(VERIFY_READ, (char *)buf.ptr, buf.length);
--
-- if (ret)
-- return ret;
--
-- databuf = kmalloc(buf.length, GFP_KERNEL);
-- if (!databuf)
-- return -ENOMEM;
--
-- if (copy_from_user(databuf, buf.ptr, buf.length)) {
-- kfree(databuf);
-- return -EFAULT;
-- }
--
-- ret = (mtd->write_ecc)(mtd, buf.start, buf.length, &retlen, databuf, NULL, 0);
--
-- if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t)))
-- ret = -EFAULT;
--
-- kfree(databuf);
-- break;
--
-- }
--
-- case MEMREADDATA:
-+ case MEMSETOOBSEL:
- {
-- struct mtd_oob_buf buf;
-- void *databuf;
-- ssize_t retlen = 0;
--
-- if (copy_from_user(&buf, (struct mtd_oob_buf *)arg, sizeof(struct mtd_oob_buf)))
-+ if (copy_from_user(&mtd->oobinfo ,(void *)arg, sizeof(struct nand_oobinfo)))
- return -EFAULT;
--
-- if (buf.length > 0x4096)
-- return -EINVAL;
--
-- if (!mtd->read_ecc)
-- ret = -EOPNOTSUPP;
-- else
-- ret = verify_area(VERIFY_WRITE, (char *)buf.ptr, buf.length);
--
-- if (ret)
-- return ret;
--
-- databuf = kmalloc(buf.length, GFP_KERNEL);
-- if (!databuf)
-- return -ENOMEM;
--
-- ret = (mtd->read_ecc)(mtd, buf.start, buf.length, &retlen, databuf, NULL, 0);
--
-- if (copy_to_user((void *)arg + sizeof(u_int32_t), &retlen, sizeof(u_int32_t)))
-- ret = -EFAULT;
-- else if (retlen && copy_to_user(buf.ptr, databuf, retlen))
-- ret = -EFAULT;
--
-- kfree(databuf);
- break;
- }
-
--
- default:
- DEBUG(MTD_DEBUG_LEVEL0, "Invalid ioctl %x (MEMGETINFO = %x)\n", cmd, MEMGETINFO);
- ret = -ENOTTY;
-@@ -534,13 +461,13 @@
- } /* memory_ioctl */
-
- static struct file_operations mtd_fops = {
-- owner: THIS_MODULE,
-- llseek: mtd_lseek, /* lseek */
-- read: mtd_read, /* read */
-- write: mtd_write, /* write */
-- ioctl: mtd_ioctl, /* ioctl */
-- open: mtd_open, /* open */
-- release: mtd_close, /* release */
-+ .owner = THIS_MODULE,
-+ .llseek = mtd_lseek,
-+ .read = mtd_read,
-+ .write = mtd_write,
-+ .ioctl = mtd_ioctl,
-+ .open = mtd_open,
-+ .release = mtd_close,
- };
-
-
-@@ -580,26 +507,18 @@
-
- static int __init init_mtdchar(void)
- {
--#ifdef CONFIG_DEVFS_FS
-- if (devfs_register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops))
-+ if (register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops))
- {
- printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
- MTD_CHAR_MAJOR);
- return -EAGAIN;
- }
-
-+#ifdef CONFIG_DEVFS_FS
- devfs_dir_handle = devfs_mk_dir(NULL, "mtd", NULL);
-
- register_mtd_user(&notifier);
--#else
-- if (register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops))
-- {
-- printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
-- MTD_CHAR_MAJOR);
-- return -EAGAIN;
-- }
- #endif
--
- return 0;
- }
-
-@@ -608,10 +527,8 @@
- #ifdef CONFIG_DEVFS_FS
- unregister_mtd_user(&notifier);
- devfs_unregister(devfs_dir_handle);
-- devfs_unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
--#else
-- unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
- #endif
-+ unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
- }
-
- module_init(init_mtdchar);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/mtdconcat.c linux/drivers/mtd/mtdconcat.c
---- linux-mips-2.4.27/drivers/mtd/mtdconcat.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/mtdconcat.c 2004-11-19 10:25:11.649237792 +0100
-@@ -3,9 +3,11 @@
- *
- * (C) 2002 Robert Kaiser <rkaiser@sysgo.de>
- *
-+ * NAND support by Christian Gan <cgan@iders.ca>
-+ *
- * This code is GPL
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/module.h>
-@@ -35,21 +37,20 @@
- #define SIZEOF_STRUCT_MTD_CONCAT(num_subdev) \
- ((sizeof(struct mtd_concat) + (num_subdev) * sizeof(struct mtd_info *)))
-
--
- /*
- * Given a pointer to the MTD object in the mtd_concat structure,
- * we can retrieve the pointer to that structure with this macro.
- */
- #define CONCAT(x) ((struct mtd_concat *)(x))
-
--
- /*
- * MTD methods which look up the relevant subdevice, translate the
- * effective address and pass through to the subdevice.
- */
-
--static int concat_read (struct mtd_info *mtd, loff_t from, size_t len,
-- size_t *retlen, u_char *buf)
-+static int
-+concat_read(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t * retlen, u_char * buf)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- int err = -EINVAL;
-@@ -57,43 +58,43 @@
-
- *retlen = 0;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- size_t size, retsize;
-
-- if (from >= subdev->size)
-- {
-+ if (from >= subdev->size) {
-+ /* Not destined for this subdev */
- size = 0;
- from -= subdev->size;
-+ continue;
- }
-- else
-- {
- if (from + len > subdev->size)
-+ /* First part goes into this subdev */
- size = subdev->size - from;
- else
-+ /* Entire transaction goes into this subdev */
- size = len;
-
- err = subdev->read(subdev, from, size, &retsize, buf);
-
-- if(err)
-+ if (err)
- break;
-
- *retlen += retsize;
- len -= size;
-- if(len == 0)
-+ if (len == 0)
- break;
-
- err = -EINVAL;
- buf += size;
- from = 0;
- }
-- }
- return err;
- }
-
--static int concat_write (struct mtd_info *mtd, loff_t to, size_t len,
-- size_t *retlen, const u_char *buf)
-+static int
-+concat_write(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t * retlen, const u_char * buf)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- int err = -EINVAL;
-@@ -104,18 +105,15 @@
-
- *retlen = 0;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- size_t size, retsize;
-
-- if (to >= subdev->size)
-- {
-+ if (to >= subdev->size) {
- size = 0;
- to -= subdev->size;
-+ continue;
- }
-- else
-- {
- if (to + len > subdev->size)
- size = subdev->size - to;
- else
-@@ -126,25 +124,232 @@
- else
- err = subdev->write(subdev, to, size, &retsize, buf);
-
-- if(err)
-+ if (err)
- break;
-
- *retlen += retsize;
- len -= size;
-- if(len == 0)
-+ if (len == 0)
- break;
-
- err = -EINVAL;
- buf += size;
- to = 0;
- }
-+ return err;
-+}
-+
-+static int
-+concat_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t * retlen, u_char * buf, u_char * eccbuf,
-+ struct nand_oobinfo *oobsel)
-+{
-+ struct mtd_concat *concat = CONCAT(mtd);
-+ int err = -EINVAL;
-+ int i;
-+
-+ *retlen = 0;
-+
-+ for (i = 0; i < concat->num_subdev; i++) {
-+ struct mtd_info *subdev = concat->subdev[i];
-+ size_t size, retsize;
-+
-+ if (from >= subdev->size) {
-+ /* Not destined for this subdev */
-+ size = 0;
-+ from -= subdev->size;
-+ continue;
-+ }
-+
-+ if (from + len > subdev->size)
-+ /* First part goes into this subdev */
-+ size = subdev->size - from;
-+ else
-+ /* Entire transaction goes into this subdev */
-+ size = len;
-+
-+ if (subdev->read_ecc)
-+ err = subdev->read_ecc(subdev, from, size,
-+ &retsize, buf, eccbuf, oobsel);
-+ else
-+ err = -EINVAL;
-+
-+ if (err)
-+ break;
-+
-+ *retlen += retsize;
-+ len -= size;
-+ if (len == 0)
-+ break;
-+
-+ err = -EINVAL;
-+ buf += size;
-+ if (eccbuf) {
-+ eccbuf += subdev->oobsize;
-+ /* in nand.c at least, eccbufs are
-+ tagged with 2 (int)eccstatus'; we
-+ must account for these */
-+ eccbuf += 2 * (sizeof (int));
-+ }
-+ from = 0;
- }
- return err;
- }
-
--static void concat_erase_callback (struct erase_info *instr)
-+static int
-+concat_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t * retlen, const u_char * buf, u_char * eccbuf,
-+ struct nand_oobinfo *oobsel)
- {
-- wake_up((wait_queue_head_t *)instr->priv);
-+ struct mtd_concat *concat = CONCAT(mtd);
-+ int err = -EINVAL;
-+ int i;
-+
-+ if (!(mtd->flags & MTD_WRITEABLE))
-+ return -EROFS;
-+
-+ *retlen = 0;
-+
-+ for (i = 0; i < concat->num_subdev; i++) {
-+ struct mtd_info *subdev = concat->subdev[i];
-+ size_t size, retsize;
-+
-+ if (to >= subdev->size) {
-+ size = 0;
-+ to -= subdev->size;
-+ continue;
-+ }
-+ if (to + len > subdev->size)
-+ size = subdev->size - to;
-+ else
-+ size = len;
-+
-+ if (!(subdev->flags & MTD_WRITEABLE))
-+ err = -EROFS;
-+ else if (subdev->write_ecc)
-+ err = subdev->write_ecc(subdev, to, size,
-+ &retsize, buf, eccbuf, oobsel);
-+ else
-+ err = -EINVAL;
-+
-+ if (err)
-+ break;
-+
-+ *retlen += retsize;
-+ len -= size;
-+ if (len == 0)
-+ break;
-+
-+ err = -EINVAL;
-+ buf += size;
-+ if (eccbuf)
-+ eccbuf += subdev->oobsize;
-+ to = 0;
-+ }
-+ return err;
-+}
-+
-+static int
-+concat_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t * retlen, u_char * buf)
-+{
-+ struct mtd_concat *concat = CONCAT(mtd);
-+ int err = -EINVAL;
-+ int i;
-+
-+ *retlen = 0;
-+
-+ for (i = 0; i < concat->num_subdev; i++) {
-+ struct mtd_info *subdev = concat->subdev[i];
-+ size_t size, retsize;
-+
-+ if (from >= subdev->size) {
-+ /* Not destined for this subdev */
-+ size = 0;
-+ from -= subdev->size;
-+ continue;
-+ }
-+ if (from + len > subdev->size)
-+ /* First part goes into this subdev */
-+ size = subdev->size - from;
-+ else
-+ /* Entire transaction goes into this subdev */
-+ size = len;
-+
-+ if (subdev->read_oob)
-+ err = subdev->read_oob(subdev, from, size,
-+ &retsize, buf);
-+ else
-+ err = -EINVAL;
-+
-+ if (err)
-+ break;
-+
-+ *retlen += retsize;
-+ len -= size;
-+ if (len == 0)
-+ break;
-+
-+ err = -EINVAL;
-+ buf += size;
-+ from = 0;
-+ }
-+ return err;
-+}
-+
-+static int
-+concat_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t * retlen, const u_char * buf)
-+{
-+ struct mtd_concat *concat = CONCAT(mtd);
-+ int err = -EINVAL;
-+ int i;
-+
-+ if (!(mtd->flags & MTD_WRITEABLE))
-+ return -EROFS;
-+
-+ *retlen = 0;
-+
-+ for (i = 0; i < concat->num_subdev; i++) {
-+ struct mtd_info *subdev = concat->subdev[i];
-+ size_t size, retsize;
-+
-+ if (to >= subdev->size) {
-+ size = 0;
-+ to -= subdev->size;
-+ continue;
-+ }
-+ if (to + len > subdev->size)
-+ size = subdev->size - to;
-+ else
-+ size = len;
-+
-+ if (!(subdev->flags & MTD_WRITEABLE))
-+ err = -EROFS;
-+ else if (subdev->write_oob)
-+ err = subdev->write_oob(subdev, to, size, &retsize,
-+ buf);
-+ else
-+ err = -EINVAL;
-+
-+ if (err)
-+ break;
-+
-+ *retlen += retsize;
-+ len -= size;
-+ if (len == 0)
-+ break;
-+
-+ err = -EINVAL;
-+ buf += size;
-+ to = 0;
-+ }
-+ return err;
-+}
-+
-+static void concat_erase_callback(struct erase_info *instr)
-+{
-+ wake_up((wait_queue_head_t *) instr->priv);
- }
-
- static int concat_dev_erase(struct mtd_info *mtd, struct erase_info *erase)
-@@ -160,18 +365,18 @@
-
- erase->mtd = mtd;
- erase->callback = concat_erase_callback;
-- erase->priv = (unsigned long)&waitq;
-+ erase->priv = (unsigned long) &waitq;
-
- /*
- * FIXME: Allow INTERRUPTIBLE. Which means
- * not having the wait_queue head on the stack.
- */
- err = mtd->erase(mtd, erase);
-- if (!err)
-- {
-+ if (!err) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- add_wait_queue(&waitq, &wait);
-- if (erase->state != MTD_ERASE_DONE && erase->state != MTD_ERASE_FAILED)
-+ if (erase->state != MTD_ERASE_DONE
-+ && erase->state != MTD_ERASE_FAILED)
- schedule();
- remove_wait_queue(&waitq, &wait);
- set_current_state(TASK_RUNNING);
-@@ -181,7 +386,7 @@
- return err;
- }
-
--static int concat_erase (struct mtd_info *mtd, struct erase_info *instr)
-+static int concat_erase(struct mtd_info *mtd, struct erase_info *instr)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- struct mtd_info *subdev;
-@@ -192,10 +397,10 @@
- if (!(mtd->flags & MTD_WRITEABLE))
- return -EROFS;
-
-- if(instr->addr > concat->mtd.size)
-+ if (instr->addr > concat->mtd.size)
- return -EINVAL;
-
-- if(instr->len + instr->addr > concat->mtd.size)
-+ if (instr->len + instr->addr > concat->mtd.size)
- return -EINVAL;
-
- /*
-@@ -204,23 +409,22 @@
- * region info rather than looking at each particular sub-device
- * in turn.
- */
-- if (!concat->mtd.numeraseregions)
-- { /* the easy case: device has uniform erase block size */
-- if(instr->addr & (concat->mtd.erasesize - 1))
-+ if (!concat->mtd.numeraseregions) {
-+ /* the easy case: device has uniform erase block size */
-+ if (instr->addr & (concat->mtd.erasesize - 1))
- return -EINVAL;
-- if(instr->len & (concat->mtd.erasesize - 1))
-+ if (instr->len & (concat->mtd.erasesize - 1))
- return -EINVAL;
-- }
-- else
-- { /* device has variable erase size */
-- struct mtd_erase_region_info *erase_regions = concat->mtd.eraseregions;
-+ } else {
-+ /* device has variable erase size */
-+ struct mtd_erase_region_info *erase_regions =
-+ concat->mtd.eraseregions;
-
- /*
- * Find the erase region where the to-be-erased area begins:
- */
-- for(i = 0; i < concat->mtd.numeraseregions &&
-- instr->addr >= erase_regions[i].offset; i++)
-- ;
-+ for (i = 0; i < concat->mtd.numeraseregions &&
-+ instr->addr >= erase_regions[i].offset; i++) ;
- --i;
-
- /*
-@@ -228,25 +432,26 @@
- * to-be-erased area begins. Verify that the starting
- * offset is aligned to this region's erase size:
- */
-- if (instr->addr & (erase_regions[i].erasesize-1))
-+ if (instr->addr & (erase_regions[i].erasesize - 1))
- return -EINVAL;
-
- /*
- * now find the erase region where the to-be-erased area ends:
- */
-- for(; i < concat->mtd.numeraseregions &&
-- (instr->addr + instr->len) >= erase_regions[i].offset ; ++i)
-- ;
-+ for (; i < concat->mtd.numeraseregions &&
-+ (instr->addr + instr->len) >= erase_regions[i].offset;
-+ ++i) ;
- --i;
- /*
- * check if the ending offset is aligned to this region's erase size
- */
-- if ((instr->addr + instr->len) & (erase_regions[i].erasesize-1))
-+ if ((instr->addr + instr->len) & (erase_regions[i].erasesize -
-+ 1))
- return -EINVAL;
- }
-
- /* make a local copy of instr to avoid modifying the caller's struct */
-- erase = kmalloc(sizeof(struct erase_info),GFP_KERNEL);
-+ erase = kmalloc(sizeof (struct erase_info), GFP_KERNEL);
-
- if (!erase)
- return -ENOMEM;
-@@ -258,39 +463,40 @@
- * find the subdevice where the to-be-erased area begins, adjust
- * starting offset to be relative to the subdevice start
- */
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- subdev = concat->subdev[i];
-- if(subdev->size <= erase->addr)
-+ if (subdev->size <= erase->addr)
- erase->addr -= subdev->size;
- else
- break;
- }
-- if(i >= concat->num_subdev) /* must never happen since size */
-- BUG(); /* limit has been verified above */
-+
-+ /* must never happen since size limit has been verified above */
-+ if (i >= concat->num_subdev)
-+ BUG();
-
- /* now do the erase: */
- err = 0;
-- for(;length > 0; i++) /* loop for all subevices affected by this request */
-- {
-+ for (; length > 0; i++) {
-+ /* loop for all subdevices affected by this request */
- subdev = concat->subdev[i]; /* get current subdevice */
-
- /* limit length to subdevice's size: */
-- if(erase->addr + length > subdev->size)
-+ if (erase->addr + length > subdev->size)
- erase->len = subdev->size - erase->addr;
- else
- erase->len = length;
-
-- if (!(subdev->flags & MTD_WRITEABLE))
-- {
-+ if (!(subdev->flags & MTD_WRITEABLE)) {
- err = -EROFS;
- break;
- }
- length -= erase->len;
-- if ((err = concat_dev_erase(subdev, erase)))
-- {
-- if(err == -EINVAL) /* sanity check: must never happen since */
-- BUG(); /* block alignment has been checked above */
-+ if ((err = concat_dev_erase(subdev, erase))) {
-+ /* sanity check: should never happen since
-+ * block alignment has been checked above */
-+ if (err == -EINVAL)
-+ BUG();
- break;
- }
- /*
-@@ -313,7 +519,7 @@
- return 0;
- }
-
--static int concat_lock (struct mtd_info *mtd, loff_t ofs, size_t len)
-+static int concat_lock(struct mtd_info *mtd, loff_t ofs, size_t len)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- int i, err = -EINVAL;
-@@ -321,18 +527,15 @@
- if ((len + ofs) > mtd->size)
- return -EINVAL;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- size_t size;
-
-- if (ofs >= subdev->size)
-- {
-+ if (ofs >= subdev->size) {
- size = 0;
- ofs -= subdev->size;
-+ continue;
- }
-- else
-- {
- if (ofs + len > subdev->size)
- size = subdev->size - ofs;
- else
-@@ -340,21 +543,21 @@
-
- err = subdev->lock(subdev, ofs, size);
-
-- if(err)
-+ if (err)
- break;
-
- len -= size;
-- if(len == 0)
-+ if (len == 0)
- break;
-
- err = -EINVAL;
- ofs = 0;
- }
-- }
-+
- return err;
- }
-
--static int concat_unlock (struct mtd_info *mtd, loff_t ofs, size_t len)
-+static int concat_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)
- {
- struct mtd_concat *concat = CONCAT(mtd);
- int i, err = 0;
-@@ -362,18 +565,15 @@
- if ((len + ofs) > mtd->size)
- return -EINVAL;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- size_t size;
-
-- if (ofs >= subdev->size)
-- {
-+ if (ofs >= subdev->size) {
- size = 0;
- ofs -= subdev->size;
-+ continue;
- }
-- else
-- {
- if (ofs + len > subdev->size)
- size = subdev->size - ofs;
- else
-@@ -381,17 +581,17 @@
-
- err = subdev->unlock(subdev, ofs, size);
-
-- if(err)
-+ if (err)
- break;
-
- len -= size;
-- if(len == 0)
-+ if (len == 0)
- break;
-
- err = -EINVAL;
- ofs = 0;
- }
-- }
-+
- return err;
- }
-
-@@ -400,8 +600,7 @@
- struct mtd_concat *concat = CONCAT(mtd);
- int i;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- subdev->sync(subdev);
- }
-@@ -412,10 +611,9 @@
- struct mtd_concat *concat = CONCAT(mtd);
- int i, rc = 0;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
-- if((rc = subdev->suspend(subdev)) < 0)
-+ if ((rc = subdev->suspend(subdev)) < 0)
- return rc;
- }
- return rc;
-@@ -426,8 +624,7 @@
- struct mtd_concat *concat = CONCAT(mtd);
- int i;
-
-- for(i = 0; i < concat->num_subdev; i++)
-- {
-+ for (i = 0; i < concat->num_subdev; i++) {
- struct mtd_info *subdev = concat->subdev[i];
- subdev->resume(subdev);
- }
-@@ -439,11 +636,10 @@
- * stored to *new_dev upon success. This function does _not_
- * register any devices: this is the caller's responsibility.
- */
--struct mtd_info *mtd_concat_create(
-- struct mtd_info *subdev[], /* subdevices to concatenate */
-+struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to concatenate */
- int num_devs, /* number of subdevices */
-- char *name) /* name for the new device */
--{
-+ char *name)
-+{ /* name for the new device */
- int i;
- size_t size;
- struct mtd_concat *concat;
-@@ -451,21 +647,21 @@
- int num_erase_region;
-
- printk(KERN_NOTICE "Concatenating MTD devices:\n");
-- for(i = 0; i < num_devs; i++)
-+ for (i = 0; i < num_devs; i++)
- printk(KERN_NOTICE "(%d): \"%s\"\n", i, subdev[i]->name);
- printk(KERN_NOTICE "into device \"%s\"\n", name);
-
- /* allocate the device structure */
- size = SIZEOF_STRUCT_MTD_CONCAT(num_devs);
-- concat = kmalloc (size, GFP_KERNEL);
-- if(!concat)
-- {
-- printk ("memory allocation error while creating concatenated device \"%s\"\n",
-+ concat = kmalloc(size, GFP_KERNEL);
-+ if (!concat) {
-+ printk
-+ ("memory allocation error while creating concatenated device \"%s\"\n",
- name);
- return NULL;
- }
- memset(concat, 0, size);
-- concat->subdev = (struct mtd_info **)(concat + 1);
-+ concat->subdev = (struct mtd_info **) (concat + 1);
-
- /*
- * Set up the new "super" device's MTD object structure, check for
-@@ -479,39 +675,53 @@
- concat->mtd.oobsize = subdev[0]->oobsize;
- concat->mtd.ecctype = subdev[0]->ecctype;
- concat->mtd.eccsize = subdev[0]->eccsize;
-+ if (subdev[0]->read_ecc)
-+ concat->mtd.read_ecc = concat_read_ecc;
-+ if (subdev[0]->write_ecc)
-+ concat->mtd.write_ecc = concat_write_ecc;
-+ if (subdev[0]->read_oob)
-+ concat->mtd.read_oob = concat_read_oob;
-+ if (subdev[0]->write_oob)
-+ concat->mtd.write_oob = concat_write_oob;
-
- concat->subdev[0] = subdev[0];
-
-- for(i = 1; i < num_devs; i++)
-- {
-- if(concat->mtd.type != subdev[i]->type)
-- {
-+ for (i = 1; i < num_devs; i++) {
-+ if (concat->mtd.type != subdev[i]->type) {
- kfree(concat);
-- printk ("Incompatible device type on \"%s\"\n", subdev[i]->name);
-+ printk("Incompatible device type on \"%s\"\n",
-+ subdev[i]->name);
- return NULL;
- }
-- if(concat->mtd.flags != subdev[i]->flags)
-- { /*
-- * Expect all flags except MTD_WRITEABLE to be equal on
-- * all subdevices.
-+ if (concat->mtd.flags != subdev[i]->flags) {
-+ /*
-+ * Expect all flags except MTD_WRITEABLE to be
-+ * equal on all subdevices.
- */
-- if((concat->mtd.flags ^ subdev[i]->flags) & ~MTD_WRITEABLE)
-- {
-+ if ((concat->mtd.flags ^ subdev[i]->
-+ flags) & ~MTD_WRITEABLE) {
- kfree(concat);
-- printk ("Incompatible device flags on \"%s\"\n", subdev[i]->name);
-+ printk("Incompatible device flags on \"%s\"\n",
-+ subdev[i]->name);
- return NULL;
-- }
-- else /* if writeable attribute differs, make super device writeable */
-- concat->mtd.flags |= subdev[i]->flags & MTD_WRITEABLE;
-+ } else
-+ /* if writeable attribute differs,
-+ make super device writeable */
-+ concat->mtd.flags |=
-+ subdev[i]->flags & MTD_WRITEABLE;
- }
- concat->mtd.size += subdev[i]->size;
-- if(concat->mtd.oobblock != subdev[i]->oobblock ||
-+ if (concat->mtd.oobblock != subdev[i]->oobblock ||
- concat->mtd.oobsize != subdev[i]->oobsize ||
- concat->mtd.ecctype != subdev[i]->ecctype ||
-- concat->mtd.eccsize != subdev[i]->eccsize)
-- {
-+ concat->mtd.eccsize != subdev[i]->eccsize ||
-+ !concat->mtd.read_ecc != !subdev[i]->read_ecc ||
-+ !concat->mtd.write_ecc != !subdev[i]->write_ecc ||
-+ !concat->mtd.read_oob != !subdev[i]->read_oob ||
-+ !concat->mtd.write_oob != !subdev[i]->write_oob) {
- kfree(concat);
-- printk ("Incompatible OOB or ECC data on \"%s\"\n", subdev[i]->name);
-+ printk("Incompatible OOB or ECC data on \"%s\"\n",
-+ subdev[i]->name);
- return NULL;
- }
- concat->subdev[i] = subdev[i];
-@@ -535,7 +745,6 @@
- concat->mtd.suspend = concat_suspend;
- concat->mtd.resume = concat_resume;
-
--
- /*
- * Combine the erase block size info of the subdevices:
- *
-@@ -544,44 +753,44 @@
- */
- max_erasesize = curr_erasesize = subdev[0]->erasesize;
- num_erase_region = 1;
-- for(i = 0; i < num_devs; i++)
-- {
-- if(subdev[i]->numeraseregions == 0)
-- { /* current subdevice has uniform erase size */
-- if(subdev[i]->erasesize != curr_erasesize)
-- { /* if it differs from the last subdevice's erase size, count it */
-+ for (i = 0; i < num_devs; i++) {
-+ if (subdev[i]->numeraseregions == 0) {
-+ /* current subdevice has uniform erase size */
-+ if (subdev[i]->erasesize != curr_erasesize) {
-+ /* if it differs from the last subdevice's erase size, count it */
- ++num_erase_region;
- curr_erasesize = subdev[i]->erasesize;
-- if(curr_erasesize > max_erasesize)
-+ if (curr_erasesize > max_erasesize)
- max_erasesize = curr_erasesize;
- }
-- }
-- else
-- { /* current subdevice has variable erase size */
-+ } else {
-+ /* current subdevice has variable erase size */
- int j;
-- for(j = 0; j < subdev[i]->numeraseregions; j++)
-- { /* walk the list of erase regions, count any changes */
-- if(subdev[i]->eraseregions[j].erasesize != curr_erasesize)
-- {
-+ for (j = 0; j < subdev[i]->numeraseregions; j++) {
-+
-+ /* walk the list of erase regions, count any changes */
-+ if (subdev[i]->eraseregions[j].erasesize !=
-+ curr_erasesize) {
- ++num_erase_region;
-- curr_erasesize = subdev[i]->eraseregions[j].erasesize;
-- if(curr_erasesize > max_erasesize)
-+ curr_erasesize =
-+ subdev[i]->eraseregions[j].
-+ erasesize;
-+ if (curr_erasesize > max_erasesize)
- max_erasesize = curr_erasesize;
- }
- }
- }
- }
-
-- if(num_erase_region == 1)
-- { /*
-+ if (num_erase_region == 1) {
-+ /*
- * All subdevices have the same uniform erase size.
- * This is easy:
- */
- concat->mtd.erasesize = curr_erasesize;
- concat->mtd.numeraseregions = 0;
-- }
-- else
-- { /*
-+ } else {
-+ /*
- * erase block size varies across the subdevices: allocate
- * space to store the data describing the variable erase regions
- */
-@@ -590,12 +799,13 @@
-
- concat->mtd.erasesize = max_erasesize;
- concat->mtd.numeraseregions = num_erase_region;
-- concat->mtd.eraseregions = erase_region_p = kmalloc (
-- num_erase_region * sizeof(struct mtd_erase_region_info), GFP_KERNEL);
-- if(!erase_region_p)
-- {
-+ concat->mtd.eraseregions = erase_region_p =
-+ kmalloc(num_erase_region *
-+ sizeof (struct mtd_erase_region_info), GFP_KERNEL);
-+ if (!erase_region_p) {
- kfree(concat);
-- printk ("memory allocation error while creating erase region list"
-+ printk
-+ ("memory allocation error while creating erase region list"
- " for device \"%s\"\n", name);
- return NULL;
- }
-@@ -606,41 +816,48 @@
- */
- curr_erasesize = subdev[0]->erasesize;
- begin = position = 0;
-- for(i = 0; i < num_devs; i++)
-- {
-- if(subdev[i]->numeraseregions == 0)
-- { /* current subdevice has uniform erase size */
-- if(subdev[i]->erasesize != curr_erasesize)
-- { /*
-+ for (i = 0; i < num_devs; i++) {
-+ if (subdev[i]->numeraseregions == 0) {
-+ /* current subdevice has uniform erase size */
-+ if (subdev[i]->erasesize != curr_erasesize) {
-+ /*
- * fill in an mtd_erase_region_info structure for the area
- * we have walked so far:
- */
- erase_region_p->offset = begin;
-- erase_region_p->erasesize = curr_erasesize;
-- erase_region_p->numblocks = (position - begin) / curr_erasesize;
-+ erase_region_p->erasesize =
-+ curr_erasesize;
-+ erase_region_p->numblocks =
-+ (position - begin) / curr_erasesize;
- begin = position;
-
- curr_erasesize = subdev[i]->erasesize;
- ++erase_region_p;
- }
- position += subdev[i]->size;
-- }
-- else
-- { /* current subdevice has variable erase size */
-+ } else {
-+ /* current subdevice has variable erase size */
- int j;
-- for(j = 0; j < subdev[i]->numeraseregions; j++)
-- { /* walk the list of erase regions, count any changes */
-- if(subdev[i]->eraseregions[j].erasesize != curr_erasesize)
-- {
-+ for (j = 0; j < subdev[i]->numeraseregions; j++) {
-+ /* walk the list of erase regions, count any changes */
-+ if (subdev[i]->eraseregions[j].
-+ erasesize != curr_erasesize) {
- erase_region_p->offset = begin;
-- erase_region_p->erasesize = curr_erasesize;
-- erase_region_p->numblocks = (position - begin) / curr_erasesize;
-+ erase_region_p->erasesize =
-+ curr_erasesize;
-+ erase_region_p->numblocks =
-+ (position -
-+ begin) / curr_erasesize;
- begin = position;
-
-- curr_erasesize = subdev[i]->eraseregions[j].erasesize;
-+ curr_erasesize =
-+ subdev[i]->eraseregions[j].
-+ erasesize;
- ++erase_region_p;
- }
-- position += subdev[i]->eraseregions[j].numblocks * curr_erasesize;
-+ position +=
-+ subdev[i]->eraseregions[j].
-+ numblocks * curr_erasesize;
- }
- }
- }
-@@ -660,16 +877,14 @@
- void mtd_concat_destroy(struct mtd_info *mtd)
- {
- struct mtd_concat *concat = CONCAT(mtd);
-- if(concat->mtd.numeraseregions)
-+ if (concat->mtd.numeraseregions)
- kfree(concat->mtd.eraseregions);
- kfree(concat);
- }
-
--
- EXPORT_SYMBOL(mtd_concat_create);
- EXPORT_SYMBOL(mtd_concat_destroy);
-
--
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Robert Kaiser <rkaiser@sysgo.de>");
- MODULE_DESCRIPTION("Generic support for concatenating of MTD devices");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/mtdcore.c linux/drivers/mtd/mtdcore.c
---- linux-mips-2.4.27/drivers/mtd/mtdcore.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/mtdcore.c 2004-11-19 10:25:11.650237640 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Core registration and callback routines for MTD
- * drivers and users.
-@@ -17,6 +17,7 @@
- #include <linux/major.h>
- #include <linux/fs.h>
- #include <linux/ioctl.h>
-+#include <linux/init.h>
- #include <linux/mtd/compatmac.h>
- #ifdef CONFIG_PROC_FS
- #include <linux/proc_fs.h>
-@@ -24,9 +25,15 @@
-
- #include <linux/mtd/mtd.h>
-
--static DECLARE_MUTEX(mtd_table_mutex);
--static struct mtd_info *mtd_table[MAX_MTD_DEVICES];
--static struct mtd_notifier *mtd_notifiers = NULL;
-+/* These are exported solely for the purpose of mtd_blkdevs.c. You
-+ should not use them for _anything_ else */
-+DECLARE_MUTEX(mtd_table_mutex);
-+struct mtd_info *mtd_table[MAX_MTD_DEVICES];
-+
-+EXPORT_SYMBOL_GPL(mtd_table_mutex);
-+EXPORT_SYMBOL_GPL(mtd_table);
-+
-+static LIST_HEAD(mtd_notifiers);
-
- /**
- * add_mtd_device - register an MTD device
-@@ -44,21 +51,28 @@
-
- down(&mtd_table_mutex);
-
-- for (i=0; i< MAX_MTD_DEVICES; i++)
-- if (!mtd_table[i])
-- {
-- struct mtd_notifier *not=mtd_notifiers;
-+ for (i=0; i < MAX_MTD_DEVICES; i++)
-+ if (!mtd_table[i]) {
-+ struct list_head *this;
-
- mtd_table[i] = mtd;
- mtd->index = i;
-+ mtd->usecount = 0;
-+
- DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name);
-- while (not)
-- {
-- (*(not->add))(mtd);
-- not = not->next;
-+ /* No need to get a refcount on the module containing
-+ the notifier, since we hold the mtd_table_mutex */
-+ list_for_each(this, &mtd_notifiers) {
-+ struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);
-+ not->add(mtd);
- }
-+
- up(&mtd_table_mutex);
-- MOD_INC_USE_COUNT;
-+ /* We _know_ we aren't being removed, because
-+ our caller is still holding us here. So none
-+ of this try_ nonsense, and no bitching about it
-+ either. :) */
-+ __module_get(THIS_MODULE);
- return 0;
- }
-
-@@ -78,29 +92,34 @@
-
- int del_mtd_device (struct mtd_info *mtd)
- {
-- struct mtd_notifier *not=mtd_notifiers;
-- int i;
-+ int ret;
-
- down(&mtd_table_mutex);
-
-- for (i=0; i < MAX_MTD_DEVICES; i++)
-- {
-- if (mtd_table[i] == mtd)
-- {
-- while (not)
-- {
-- (*(not->remove))(mtd);
-- not = not->next;
-- }
-- mtd_table[i] = NULL;
-- up (&mtd_table_mutex);
-- MOD_DEC_USE_COUNT;
-- return 0;
-+ if (mtd_table[mtd->index] != mtd) {
-+ ret = -ENODEV;
-+ } else if (mtd->usecount) {
-+ printk(KERN_NOTICE "Removing MTD device #%d (%s) with use count %d\n",
-+ mtd->index, mtd->name, mtd->usecount);
-+ ret = -EBUSY;
-+ } else {
-+ struct list_head *this;
-+
-+ /* No need to get a refcount on the module containing
-+ the notifier, since we hold the mtd_table_mutex */
-+ list_for_each(this, &mtd_notifiers) {
-+ struct mtd_notifier *not = list_entry(this, struct mtd_notifier, list);
-+ not->remove(mtd);
- }
-+
-+ mtd_table[mtd->index] = NULL;
-+
-+ module_put(THIS_MODULE);
-+ ret = 0;
- }
-
- up(&mtd_table_mutex);
-- return 1;
-+ return ret;
- }
-
- /**
-@@ -118,10 +137,9 @@
-
- down(&mtd_table_mutex);
-
-- new->next = mtd_notifiers;
-- mtd_notifiers = new;
-+ list_add(&new->list, &mtd_notifiers);
-
-- MOD_INC_USE_COUNT;
-+ __module_get(THIS_MODULE);
-
- for (i=0; i< MAX_MTD_DEVICES; i++)
- if (mtd_table[i])
-@@ -142,34 +160,24 @@
-
- int unregister_mtd_user (struct mtd_notifier *old)
- {
-- struct mtd_notifier **prev = &mtd_notifiers;
-- struct mtd_notifier *cur;
- int i;
-
- down(&mtd_table_mutex);
-
-- while ((cur = *prev)) {
-- if (cur == old) {
-- *prev = cur->next;
--
-- MOD_DEC_USE_COUNT;
-+ module_put(THIS_MODULE);
-
- for (i=0; i< MAX_MTD_DEVICES; i++)
- if (mtd_table[i])
- old->remove(mtd_table[i]);
-
-+ list_del(&old->list);
- up(&mtd_table_mutex);
- return 0;
-- }
-- prev = &cur->next;
-- }
-- up(&mtd_table_mutex);
-- return 1;
- }
-
-
- /**
-- * __get_mtd_device - obtain a validated handle for an MTD device
-+ * get_mtd_device - obtain a validated handle for an MTD device
- * @mtd: last known address of the required MTD device
- * @num: internal device number of the required MTD device
- *
-@@ -177,11 +185,10 @@
- * table, if any. Given an address and num == -1, search the device table
- * for a device with that address and return if it's still present. Given
- * both, return the num'th driver only if its address matches. Return NULL
-- * if not. get_mtd_device() increases the use count, but
-- * __get_mtd_device() doesn't - you should generally use get_mtd_device().
-+ * if not.
- */
-
--struct mtd_info *__get_mtd_device(struct mtd_info *mtd, int num)
-+struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
- {
- struct mtd_info *ret = NULL;
- int i;
-@@ -198,10 +205,27 @@
- ret = NULL;
- }
-
-+ if (ret && !try_module_get(ret->owner))
-+ ret = NULL;
-+
-+ if (ret)
-+ ret->usecount++;
-+
- up(&mtd_table_mutex);
- return ret;
- }
-
-+void put_mtd_device(struct mtd_info *mtd)
-+{
-+ int c;
-+
-+ down(&mtd_table_mutex);
-+ c = --mtd->usecount;
-+ up(&mtd_table_mutex);
-+ BUG_ON(c < 0);
-+
-+ module_put(mtd->owner);
-+}
-
- /* default_mtd_writev - default mtd writev method for MTD devices that
- * dont implement their own
-@@ -265,7 +289,8 @@
-
- EXPORT_SYMBOL(add_mtd_device);
- EXPORT_SYMBOL(del_mtd_device);
--EXPORT_SYMBOL(__get_mtd_device);
-+EXPORT_SYMBOL(get_mtd_device);
-+EXPORT_SYMBOL(put_mtd_device);
- EXPORT_SYMBOL(register_mtd_user);
- EXPORT_SYMBOL(unregister_mtd_user);
- EXPORT_SYMBOL(default_mtd_writev);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/mtdpart.c linux/drivers/mtd/mtdpart.c
---- linux-mips-2.4.27/drivers/mtd/mtdpart.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/mtdpart.c 2004-11-19 10:25:11.652237336 +0100
-@@ -5,7 +5,7 @@
- *
- * This code is GPL
- *
-- * $Id$
-+ * $Id$
- *
- * 02-21-2002 Thomas Gleixner <gleixner@autronix.de>
- * added support for read_oob, write_oob
-@@ -16,10 +16,11 @@
- #include <linux/kernel.h>
- #include <linux/slab.h>
- #include <linux/list.h>
--
-+#include <linux/config.h>
-+#include <linux/kmod.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/partitions.h>
--
-+#include <linux/mtd/compatmac.h>
-
- /* Our partition linked list */
- static LIST_HEAD(mtd_partitions);
-@@ -54,8 +55,12 @@
- len = 0;
- else if (from + len > mtd->size)
- len = mtd->size - from;
-+ if (part->master->read_ecc == NULL)
- return part->master->read (part->master, from + part->offset,
- len, retlen, buf);
-+ else
-+ return part->master->read_ecc (part->master, from + part->offset,
-+ len, retlen, buf, NULL, &mtd->oobinfo);
- }
-
- static int part_point (struct mtd_info *mtd, loff_t from, size_t len,
-@@ -78,9 +83,11 @@
-
-
- static int part_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
-- size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel)
-+ size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel)
- {
- struct mtd_part *part = PART(mtd);
-+ if (oobsel == NULL)
-+ oobsel = &mtd->oobinfo;
- if (from >= mtd->size)
- len = 0;
- else if (from + len > mtd->size)
-@@ -113,7 +120,7 @@
- size_t *retlen, u_char *buf)
- {
- struct mtd_part *part = PART(mtd);
-- return part->master->read_user_prot_reg (part->master, from,
-+ return part->master->read_fact_prot_reg (part->master, from,
- len, retlen, buf);
- }
-
-@@ -127,17 +134,24 @@
- len = 0;
- else if (to + len > mtd->size)
- len = mtd->size - to;
-+ if (part->master->write_ecc == NULL)
- return part->master->write (part->master, to + part->offset,
- len, retlen, buf);
-+ else
-+ return part->master->write_ecc (part->master, to + part->offset,
-+ len, retlen, buf, NULL, &mtd->oobinfo);
-+
- }
-
- static int part_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
- size_t *retlen, const u_char *buf,
-- u_char *eccbuf, int oobsel)
-+ u_char *eccbuf, struct nand_oobinfo *oobsel)
- {
- struct mtd_part *part = PART(mtd);
- if (!(mtd->flags & MTD_WRITEABLE))
- return -EROFS;
-+ if (oobsel == NULL)
-+ oobsel = &mtd->oobinfo;
- if (to >= mtd->size)
- len = 0;
- else if (to + len > mtd->size)
-@@ -174,25 +188,37 @@
- struct mtd_part *part = PART(mtd);
- if (!(mtd->flags & MTD_WRITEABLE))
- return -EROFS;
-+ if (part->master->writev_ecc == NULL)
- return part->master->writev (part->master, vecs, count,
- to + part->offset, retlen);
-+ else
-+ return part->master->writev_ecc (part->master, vecs, count,
-+ to + part->offset, retlen,
-+ NULL, &mtd->oobinfo);
- }
-
- static int part_readv (struct mtd_info *mtd, struct iovec *vecs,
- unsigned long count, loff_t from, size_t *retlen)
- {
- struct mtd_part *part = PART(mtd);
-+ if (part->master->readv_ecc == NULL)
- return part->master->readv (part->master, vecs, count,
- from + part->offset, retlen);
-+ else
-+ return part->master->readv_ecc (part->master, vecs, count,
-+ from + part->offset, retlen,
-+ NULL, &mtd->oobinfo);
- }
-
- static int part_writev_ecc (struct mtd_info *mtd, const struct iovec *vecs,
- unsigned long count, loff_t to, size_t *retlen,
-- u_char *eccbuf, int oobsel)
-+ u_char *eccbuf, struct nand_oobinfo *oobsel)
- {
- struct mtd_part *part = PART(mtd);
- if (!(mtd->flags & MTD_WRITEABLE))
- return -EROFS;
-+ if (oobsel == NULL)
-+ oobsel = &mtd->oobinfo;
- return part->master->writev_ecc (part->master, vecs, count,
- to + part->offset, retlen,
- eccbuf, oobsel);
-@@ -200,9 +226,11 @@
-
- static int part_readv_ecc (struct mtd_info *mtd, struct iovec *vecs,
- unsigned long count, loff_t from, size_t *retlen,
-- u_char *eccbuf, int oobsel)
-+ u_char *eccbuf, struct nand_oobinfo *oobsel)
- {
- struct mtd_part *part = PART(mtd);
-+ if (oobsel == NULL)
-+ oobsel = &mtd->oobinfo;
- return part->master->readv_ecc (part->master, vecs, count,
- from + part->offset, retlen,
- eccbuf, oobsel);
-@@ -288,7 +316,7 @@
- */
-
- int add_mtd_partitions(struct mtd_info *master,
-- struct mtd_partition *parts,
-+ const struct mtd_partition *parts,
- int nbparts)
- {
- struct mtd_part *slave;
-@@ -321,7 +349,7 @@
-
- slave->mtd.name = parts[i].name;
- slave->mtd.bank_size = master->bank_size;
-- slave->mtd.module = master->module;
-+ slave->mtd.owner = master->owner;
-
- slave->mtd.read = part_read;
- slave->mtd.write = part_write;
-@@ -452,6 +480,75 @@
- EXPORT_SYMBOL(add_mtd_partitions);
- EXPORT_SYMBOL(del_mtd_partitions);
-
-+static spinlock_t part_parser_lock = SPIN_LOCK_UNLOCKED;
-+static LIST_HEAD(part_parsers);
-+
-+struct mtd_part_parser *get_partition_parser(const char *name)
-+{
-+ struct list_head *this;
-+ void *ret = NULL;
-+ spin_lock(&part_parser_lock);
-+
-+ list_for_each(this, &part_parsers) {
-+ struct mtd_part_parser *p = list_entry(this, struct mtd_part_parser, list);
-+
-+ if (!strcmp(p->name, name) && try_module_get(p->owner)) {
-+ ret = p;
-+ break;
-+ }
-+ }
-+ spin_unlock(&part_parser_lock);
-+
-+ return ret;
-+}
-+
-+int register_mtd_parser(struct mtd_part_parser *p)
-+{
-+ spin_lock(&part_parser_lock);
-+ list_add(&p->list, &part_parsers);
-+ spin_unlock(&part_parser_lock);
-+
-+ return 0;
-+}
-+
-+int deregister_mtd_parser(struct mtd_part_parser *p)
-+{
-+ spin_lock(&part_parser_lock);
-+ list_del(&p->list);
-+ spin_unlock(&part_parser_lock);
-+ return 0;
-+}
-+
-+int parse_mtd_partitions(struct mtd_info *master, const char **types,
-+ struct mtd_partition **pparts, unsigned long origin)
-+{
-+ struct mtd_part_parser *parser;
-+ int ret = 0;
-+
-+ for ( ; ret <= 0 && *types; types++) {
-+ parser = get_partition_parser(*types);
-+#ifdef CONFIG_KMOD
-+ if (!parser && !request_module("%s", *types))
-+ parser = get_partition_parser(*types);
-+#endif
-+ if (!parser) {
-+ printk(KERN_NOTICE "%s partition parsing not available\n",
-+ *types);
-+ continue;
-+ }
-+ ret = (*parser->parse_fn)(master, pparts, origin);
-+ if (ret > 0) {
-+ printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
-+ ret, parser->name, master->name);
-+ }
-+ put_partition_parser(parser);
-+ }
-+ return ret;
-+}
-+
-+EXPORT_SYMBOL_GPL(parse_mtd_partitions);
-+EXPORT_SYMBOL_GPL(register_mtd_parser);
-+EXPORT_SYMBOL_GPL(deregister_mtd_parser);
-
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Nicolas Pitre <nico@cam.org>");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/Config.in linux/drivers/mtd/nand/Config.in
---- linux-mips-2.4.27/drivers/mtd/nand/Config.in 2003-02-26 01:53:50.000000000 +0100
-+++ linux/drivers/mtd/nand/Config.in 2004-11-19 10:25:11.987186416 +0100
-@@ -1,6 +1,6 @@
- # drivers/mtd/nand/Config.in
-
--# $Id$
-+# $Id$
-
- mainmenu_option next_comment
-
-@@ -11,26 +11,27 @@
- bool ' Verify NAND page writes' CONFIG_MTD_NAND_VERIFY_WRITE
- fi
-
--if [ "$CONFIG_ARM" = "y" -a "$CONFIG_ARCH_P720T" = "y" ]; then
-- dep_tristate ' NAND Flash device on SPIA board' CONFIG_MTD_NAND_SPIA $CONFIG_MTD_NAND
-+if [ "$CONFIG_ARM" = "y" ]; then
-+ dep_tristate ' NAND Flash device on SPIA board' CONFIG_MTD_NAND_SPIA $CONFIG_MTD_NAND $CONFIG_ARCH_P720T
-+ dep_tristate ' NAND Flash device on TOTO board' CONFIG_MTD_NAND_TOTO $CONFIG_MTD_NAND $CONFIG_ARCH_OMAP
-+ dep_tristate ' SmartMedia Card on AUTCPU12 board' CONFIG_MTD_NAND_AUTCPU12 $CONFIG_MTD_NAND $CONFIG_ARCH_AUTCPU12
-+ dep_tristate ' NAND Flash device on EDP7312 board' CONFIG_MTD_NAND_EDB7312 $CONFIG_MTD_NAND $CONFIG_ARCH_EDB7312
- fi
-
--if [ "$CONFIG_ARCH_AUTCPU12" = "y" ]; then
-- dep_tristate ' SmartMedia Card on AUTCPU12 board' CONFIG_MTD_NAND_AUTCPU12 $CONFIG_MTD_NAND
--fi
--
--if [ "$CONFIG_ARCH_EDB7312" = "y" ]; then
-- dep_tristate ' NAND Flash device on EDP7312 board' CONFIG_MTD_NAND_EDB7312 $CONFIG_MTD_NAND
--fi
--
--if [ "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" -o "$CONFIG_MTD_NAND" = "y" ]; then
-+if [ "$CONFIG_MTD_DOC2001PLUS" = "y" -o "$CONFIG_MTD_DOC2001" = "y" -o "$CONFIG_MTD_DOC2000" = "y" -o "$CONFIG_MTD_NAND" = "y" ]; then
- define_bool CONFIG_MTD_NAND_IDS y
-+else
-+ if [ "$CONFIG_MTD_DOC2001PLUS" = "m" -o "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" -o "$CONFIG_MTD_NAND" = "m" ]; then
-+ define_bool CONFIG_MTD_NAND_IDS m
-+ fi
- fi
-
--if [ "$CONFIG_MTD_NAND_IDS" != "y" ]; then
--if [ "$CONFIG_MTD_DOC2001" = "m" -o "$CONFIG_MTD_DOC2000" = "m" -o "$CONFIG_MTD_NAND" = "m" ]; then
-- define_bool CONFIG_MTD_NAND_IDS m
-+if [ "$CONFIG_TOSHIBA_RBTX4925" = "y" ]; then
-+ dep_tristate ' SmartMedia Card on Toshiba RBTX4925 reference board' CONFIG_MTD_NAND_TX4925NDFMC $CONFIG_MTD_NAND $CONFIG_TOSHIBA_RBTX4925_MPLEX_NAND
- fi
-+
-+if [ "$CONFIG_TOSHIBA_RBTX4938" = "y" ]; then
-+ dep_tristate ' NAND Flash device on Toshiba RBTX4938 reference board' CONFIG_MTD_NAND_TX4938NDFMC $CONFIG_MTD_NAND $CONFIG_TOSHIBA_RBTX4938_MPLEX_NAND
- fi
-
- endmenu
-diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/Makefile linux/drivers/mtd/nand/Makefile
---- linux-mips-2.4.27/drivers/mtd/nand/Makefile 2003-02-26 01:53:50.000000000 +0100
-+++ linux/drivers/mtd/nand/Makefile 2004-11-19 10:25:11.989186112 +0100
-@@ -1,16 +1,20 @@
- #
- # linux/drivers/nand/Makefile
- #
--# $Id$
-+# $Id$
-
-+ifeq ($(PATCHLEVEL),4)
- O_TARGET := nandlink.o
--
- export-objs := nand.o nand_ecc.o nand_ids.o
-+endif
-
- obj-$(CONFIG_MTD_NAND) += nand.o nand_ecc.o
- obj-$(CONFIG_MTD_NAND_SPIA) += spia.o
-+obj-$(CONFIG_MTD_NAND_TOTO) += toto.o
- obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o
- obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o
-+obj-$(CONFIG_MTD_NAND_TX4925NDFMC) += tx4925ndfmc.o
-+obj-$(CONFIG_MTD_NAND_TX4938NDFMC) += tx4938ndfmc.o
- obj-$(CONFIG_MTD_NAND_IDS) += nand_ids.o
-
--include $(TOPDIR)/Rules.make
-+-include $(TOPDIR)/Rules.make
-diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/autcpu12.c linux/drivers/mtd/nand/autcpu12.c
---- linux-mips-2.4.27/drivers/mtd/nand/autcpu12.c 2003-02-26 01:53:50.000000000 +0100
-+++ linux/drivers/mtd/nand/autcpu12.c 2004-11-19 10:25:11.990185960 +0100
-@@ -4,9 +4,9 @@
- * Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de>
- *
- * Derived from drivers/mtd/spia.c
-- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
-+ * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
- *
-- * $Id$
-+ * $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
-@@ -25,10 +25,10 @@
- * added page_cache
- *
- * 10-06-2002 TG 128K card support added
-- *
- */
-
- #include <linux/slab.h>
-+#include <linux/init.h>
- #include <linux/module.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/nand.h>
-@@ -70,6 +70,7 @@
- /*
- * Define partitions for flash devices
- */
-+extern struct nand_oobinfo jffs2_oobinfo;
-
- static struct mtd_partition partition_info16k[] = {
- { name: "AUTCPU12 flash partition 1",
-@@ -95,7 +96,7 @@
- size: 16 * SZ_1M },
- { name: "AUTCPU12 flash partition 2",
- offset: 16 * SZ_1M,
-- size: 48 * SZ_1M},
-+ size: 48 * SZ_1M },
- };
-
- static struct mtd_partition partition_info128k[] = {
-@@ -104,7 +105,7 @@
- size: 16 * SZ_1M },
- { name: "AUTCPU12 flash partition 2",
- offset: 16 * SZ_1M,
-- size: 112 * SZ_1M},
-+ size: 112 * SZ_1M },
- };
-
- #define NUM_PARTITIONS16K 2
-@@ -114,7 +115,7 @@
- /*
- * hardware specific access to control-lines
- */
--void autcpu12_hwcontrol(int cmd)
-+static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd)
- {
-
- switch(cmd){
-@@ -133,7 +134,7 @@
- /*
- * read device ready pin
- */
--int autcpu12_device_ready(void)
-+int autcpu12_device_ready(struct mtd_info *mtd)
- {
-
- return ( (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) & AUTCPU12_SMC_RDY) ? 1 : 0;
-@@ -184,7 +185,7 @@
- this->eccmode = NAND_ECC_SOFT;
-
- /* Scan to find existance of the device */
-- if (nand_scan (autcpu12_mtd)) {
-+ if (nand_scan (autcpu12_mtd, 1)) {
- err = -ENXIO;
- goto out_ior;
- }
-@@ -197,15 +198,6 @@
- goto out_ior;
- }
-
-- /* Allocate memory for internal data buffer */
-- this->data_cache = kmalloc (sizeof(u_char) * (autcpu12_mtd->oobblock + autcpu12_mtd->oobsize), GFP_KERNEL);
-- if (!this->data_cache) {
-- printk ("Unable to allocate NAND data cache for AUTCPU12.\n");
-- err = -ENOMEM;
-- goto out_buf;
-- }
-- this->cache_page = -1;
--
- /* Register the partitions */
- switch(autcpu12_mtd->size){
- case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break;
-@@ -215,13 +207,11 @@
- default: {
- printk ("Unsupported SmartMedia device\n");
- err = -ENXIO;
-- goto out_cac;
-+ goto out_buf;
- }
- }
- goto out;
-
--out_cac:
-- kfree (this->data_cache);
- out_buf:
- kfree (this->data_buf);
- out_ior:
-@@ -250,7 +240,6 @@
-
- /* Free internal data buffers */
- kfree (this->data_buf);
-- kfree (this->data_cache);
-
- /* unmap physical adress */
- iounmap((void *)autcpu12_fio_base);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/diskonchip.c linux/drivers/mtd/nand/diskonchip.c
---- linux-mips-2.4.27/drivers/mtd/nand/diskonchip.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/nand/diskonchip.c 2004-11-19 10:25:11.992185656 +0100
-@@ -0,0 +1,534 @@
-+/*
-+ * drivers/mtd/nand/diskonchip.c
-+ *
-+ * (C) 2003 Red Hat, Inc.
-+ *
-+ * Author: David Woodhouse <dwmw2@infradead.org>
-+ *
-+ * Interface to generic NAND code for M-Systems DiskOnChip devices
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/delay.h>
-+#include <asm/io.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/doc2000.h>
-+#include <linux/mtd/compatmac.h>
-+
-+struct doc_priv {
-+ unsigned long virtadr;
-+ unsigned long physadr;
-+ u_char ChipID;
-+ u_char CDSNControl;
-+ int chips_per_floor; /* The number of chips detected on each floor */
-+ int curfloor;
-+ int curchip;
-+};
-+
-+#define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil)
-+#define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k)
-+
-+static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd);
-+static void doc200x_select_chip(struct mtd_info *mtd, int chip);
-+
-+static int debug=0;
-+MODULE_PARM(debug, "i");
-+
-+static int try_dword=1;
-+MODULE_PARM(try_dword, "i");
-+
-+static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
-+{
-+ volatile char dummy;
-+ int i;
-+
-+ for (i = 0; i < cycles; i++) {
-+ if (DoC_is_Millennium(doc))
-+ dummy = ReadDOC(doc->virtadr, NOP);
-+ else
-+ dummy = ReadDOC(doc->virtadr, DOCStatus);
-+ }
-+
-+}
-+/* DOC_WaitReady: Wait for RDY line to be asserted by the flash chip */
-+static int _DoC_WaitReady(struct doc_priv *doc)
-+{
-+ unsigned long docptr = doc->virtadr;
-+ unsigned long timeo = jiffies + (HZ * 10);
-+
-+ if(debug) printk("_DoC_WaitReady...\n");
-+ /* Out-of-line routine to wait for chip response */
-+ while (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
-+ if (time_after(jiffies, timeo)) {
-+ printk("_DoC_WaitReady timed out.\n");
-+ return -EIO;
-+ }
-+ udelay(1);
-+ cond_resched();
-+ }
-+
-+ return 0;
-+}
-+
-+static inline int DoC_WaitReady(struct doc_priv *doc)
-+{
-+ unsigned long docptr = doc->virtadr;
-+ int ret = 0;
-+
-+ DoC_Delay(doc, 4);
-+
-+ if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B))
-+ /* Call the out-of-line routine to wait */
-+ ret = _DoC_WaitReady(doc);
-+
-+ DoC_Delay(doc, 2);
-+ if(debug) printk("DoC_WaitReady OK\n");
-+ return ret;
-+}
-+
-+static void doc2000_write_byte(struct mtd_info *mtd, u_char datum)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+
-+ if(debug)printk("write_byte %02x\n", datum);
-+ WriteDOC(datum, docptr, CDSNSlowIO);
-+ WriteDOC(datum, docptr, 2k_CDSN_IO);
-+}
-+
-+static u_char doc2000_read_byte(struct mtd_info *mtd)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+
-+ ReadDOC(docptr, CDSNSlowIO);
-+ u_char ret = ReadDOC(docptr, 2k_CDSN_IO);
-+ if (debug) printk("read_byte returns %02x\n", ret);
-+ return ret;
-+}
-+static void doc2000_writebuf(struct mtd_info *mtd,
-+ const u_char *buf, int len)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+ int i;
-+ if (debug)printk("writebuf of %d bytes: ", len);
-+ for (i=0; i < len; i++) {
-+ WriteDOC_(buf[i], docptr, DoC_2k_CDSN_IO + i);
-+ if (debug && i < 16)
-+ printk("%02x ", buf[i]);
-+ }
-+ if (debug) printk("\n");
-+}
-+
-+static void doc2000_readbuf(struct mtd_info *mtd,
-+ u_char *buf, int len)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+ int i;
-+
-+ if (debug)printk("readbuf of %d bytes: ", len);
-+
-+ for (i=0; i < len; i++) {
-+ buf[i] = ReadDOC(docptr, 2k_CDSN_IO + i);
-+ }
-+}
-+
-+static void doc2000_readbuf_dword(struct mtd_info *mtd,
-+ u_char *buf, int len)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+ int i;
-+
-+ if (debug) printk("readbuf_dword of %d bytes: ", len);
-+
-+ if (unlikely((((unsigned long)buf)|len) & 3)) {
-+ for (i=0; i < len; i++) {
-+ *(uint8_t *)(&buf[i]) = ReadDOC(docptr, 2k_CDSN_IO + i);
-+ }
-+ } else {
-+ for (i=0; i < len; i+=4) {
-+ *(uint32_t*)(&buf[i]) = readl(docptr + DoC_2k_CDSN_IO + i);
-+ }
-+ }
-+}
-+
-+static int doc2000_verifybuf(struct mtd_info *mtd,
-+ const u_char *buf, int len)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+ int i;
-+
-+ for (i=0; i < len; i++)
-+ if (buf[i] != ReadDOC(docptr, 2k_CDSN_IO))
-+ return i;
-+ return 0;
-+}
-+
-+static uint16_t doc200x_ident_chip(struct mtd_info *mtd, int nr)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ uint16_t ret;
-+
-+ doc200x_select_chip(mtd, nr);
-+ doc200x_hwcontrol(mtd, NAND_CTL_SETCLE);
-+ this->write_byte(mtd, NAND_CMD_READID);
-+ doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE);
-+ doc200x_hwcontrol(mtd, NAND_CTL_SETALE);
-+ this->write_byte(mtd, 0);
-+ doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
-+
-+ ret = this->read_byte(mtd) << 8;
-+ ret |= this->read_byte(mtd);
-+
-+ if (doc->ChipID == DOC_ChipID_Doc2k && try_dword && !nr) {
-+ /* First chip probe. See if we get same results by 32-bit access */
-+ union {
-+ uint32_t dword;
-+ uint8_t byte[4];
-+ } ident;
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+
-+ doc200x_hwcontrol(mtd, NAND_CTL_SETCLE);
-+ doc2000_write_byte(mtd, NAND_CMD_READID);
-+ doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE);
-+ doc200x_hwcontrol(mtd, NAND_CTL_SETALE);
-+ doc2000_write_byte(mtd, 0);
-+ doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
-+
-+ ident.dword = readl(docptr + DoC_2k_CDSN_IO);
-+ if (((ident.byte[0] << 8) | ident.byte[1]) == ret) {
-+ printk(KERN_INFO "DiskOnChip 2000 responds to DWORD access\n");
-+ this->read_buf = &doc2000_readbuf_dword;
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+static void doc2000_count_chips(struct mtd_info *mtd)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ uint16_t mfrid;
-+ int i;
-+
-+ /* Max 4 chips per floor on DiskOnChip 2000 */
-+ doc->chips_per_floor = 4;
-+
-+ /* Find out what the first chip is */
-+ mfrid = doc200x_ident_chip(mtd, 0);
-+
-+ /* Find how many chips in each floor. */
-+ for (i = 1; i < 4; i++) {
-+ if (doc200x_ident_chip(mtd, i) != mfrid)
-+ break;
-+ }
-+ doc->chips_per_floor = i;
-+}
-+
-+static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
-+{
-+ struct doc_priv *doc = (void *)this->priv;
-+
-+ int status;
-+
-+ DoC_WaitReady(doc);
-+ this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
-+ DoC_WaitReady(doc);
-+ status = (int)this->read_byte(mtd);
-+
-+ return status;
-+}
-+
-+static void doc2001_write_byte(struct mtd_info *mtd, u_char datum)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+
-+ WriteDOC(datum, docptr, CDSNSlowIO);
-+ WriteDOC(datum, docptr, Mil_CDSN_IO);
-+ WriteDOC(datum, docptr, WritePipeTerm);
-+}
-+
-+static u_char doc2001_read_byte(struct mtd_info *mtd)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+
-+ ReadDOC(docptr, CDSNSlowIO);
-+ /* 11.4.5 -- delay twice to allow extended length cycle */
-+ DoC_Delay(doc, 2);
-+ ReadDOC(docptr, ReadPipeInit);
-+ return ReadDOC(docptr, Mil_CDSN_IO);
-+}
-+
-+static void doc2001_writebuf(struct mtd_info *mtd,
-+ const u_char *buf, int len)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+ int i;
-+
-+ for (i=0; i < len; i++)
-+ WriteDOC_(buf[i], docptr, DoC_Mil_CDSN_IO + i);
-+ /* Terminate write pipeline */
-+ WriteDOC(0x00, docptr, WritePipeTerm);
-+}
-+
-+static void doc2001_readbuf(struct mtd_info *mtd,
-+ u_char *buf, int len)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+ int i;
-+
-+ /* Start read pipeline */
-+ ReadDOC(docptr, ReadPipeInit);
-+
-+ for (i=0; i < len-1; i++)
-+ buf[i] = ReadDOC(docptr, Mil_CDSN_IO);
-+
-+ /* Terminate read pipeline */
-+ buf[i] = ReadDOC(docptr, LastDataRead);
-+}
-+static int doc2001_verifybuf(struct mtd_info *mtd,
-+ const u_char *buf, int len)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+ int i;
-+
-+ /* Start read pipeline */
-+ ReadDOC(docptr, ReadPipeInit);
-+
-+ for (i=0; i < len-1; i++)
-+ if (buf[i] != ReadDOC(docptr, Mil_CDSN_IO)) {
-+ ReadDOC(docptr, LastDataRead);
-+ return i;
-+ }
-+ if (buf[i] != ReadDOC(docptr, LastDataRead))
-+ return i;
-+ return 0;
-+}
-+
-+static void doc200x_select_chip(struct mtd_info *mtd, int chip)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+ int floor = 0;
-+
-+ /* 11.4.4 -- deassert CE before changing chip */
-+ doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE);
-+
-+ if(debug)printk("select chip (%d)\n", chip);
-+
-+ if (chip == -1)
-+ return;
-+
-+ floor = chip / doc->chips_per_floor;
-+ chip -= (floor * doc->chips_per_floor);
-+
-+ WriteDOC(floor, docptr, FloorSelect);
-+ WriteDOC(chip, docptr, CDSNDeviceSelect);
-+
-+ doc200x_hwcontrol(mtd, NAND_CTL_SETNCE);
-+
-+ doc->curchip = chip;
-+ doc->curfloor = floor;
-+}
-+
-+static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+
-+ switch(cmd) {
-+ case NAND_CTL_SETNCE:
-+ doc->CDSNControl |= CDSN_CTRL_CE;
-+ break;
-+ case NAND_CTL_CLRNCE:
-+ doc->CDSNControl &= ~CDSN_CTRL_CE;
-+ break;
-+ case NAND_CTL_SETCLE:
-+ doc->CDSNControl |= CDSN_CTRL_CLE;
-+ break;
-+ case NAND_CTL_CLRCLE:
-+ doc->CDSNControl &= ~CDSN_CTRL_CLE;
-+ break;
-+ case NAND_CTL_SETALE:
-+ doc->CDSNControl |= CDSN_CTRL_ALE;
-+ break;
-+ case NAND_CTL_CLRALE:
-+ doc->CDSNControl &= ~CDSN_CTRL_ALE;
-+ break;
-+ case NAND_CTL_SETWP:
-+ doc->CDSNControl |= CDSN_CTRL_WP;
-+ break;
-+ case NAND_CTL_CLRWP:
-+ doc->CDSNControl &= ~CDSN_CTRL_WP;
-+ break;
-+ }
-+ if (debug)printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl);
-+ WriteDOC(doc->CDSNControl, docptr, CDSNControl);
-+ /* 11.4.3 -- 4 NOPs after CSDNControl write */
-+ DoC_Delay(doc, 4);
-+}
-+
-+static int doc200x_dev_ready(struct mtd_info *mtd)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ struct doc_priv *doc = (void *)this->priv;
-+ unsigned long docptr = doc->virtadr;
-+
-+ /* 11.4.2 -- must NOP four times before checking FR/B# */
-+ DoC_Delay(doc, 4);
-+ if (!(ReadDOC(docptr, CDSNControl) & CDSN_CTRL_FR_B)) {
-+ if(debug)
-+ printk("not ready\n");
-+ return 0;
-+ }
-+ /* 11.4.2 -- Must NOP twice if it's ready */
-+ DoC_Delay(doc, 2);
-+ if (debug)printk("was ready\n");
-+ return 1;
-+}
-+
-+static int doc200x_block_bad(struct mtd_info *mtd, unsigned long block)
-+{
-+ /* FIXME: Look it up in the BBT */
-+ return 0;
-+}
-+
-+struct doc_priv mydoc = {
-+ .physadr = 0xd4000,
-+ .curfloor = -1,
-+ .curchip = -1,
-+};
-+
-+u_char mydatabuf[528];
-+
-+struct nand_chip mynand = {
-+ .priv = (void *)&mydoc,
-+ .select_chip = doc200x_select_chip,
-+ .hwcontrol = doc200x_hwcontrol,
-+ .dev_ready = doc200x_dev_ready,
-+ .waitfunc = doc200x_wait,
-+ .block_bad = doc200x_block_bad,
-+ .eccmode = NAND_ECC_SOFT,
-+ .data_buf = mydatabuf,
-+};
-+
-+struct mtd_info mymtd = {
-+ .priv = (void *)&mynand,
-+ .owner = THIS_MODULE,
-+};
-+
-+int __init init_nanddoc(void)
-+{
-+ mydoc.virtadr = (unsigned long)ioremap(mydoc.physadr, DOC_IOREMAP_LEN);
-+ int nrchips = 1;
-+ char *name;
-+
-+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
-+ mydoc.virtadr, DOCControl);
-+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
-+ mydoc.virtadr, DOCControl);
-+
-+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
-+ mydoc.virtadr, DOCControl);
-+ WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
-+ mydoc.virtadr, DOCControl);
-+
-+ mydoc.ChipID = ReadDOC(mydoc.virtadr, ChipID);
-+
-+ switch(mydoc.ChipID) {
-+ case DOC_ChipID_DocMil:
-+ mynand.write_byte = doc2001_write_byte;
-+ mynand.read_byte = doc2001_read_byte;
-+ mynand.write_buf = doc2001_writebuf;
-+ mynand.read_buf = doc2001_readbuf;
-+ mynand.verify_buf = doc2001_verifybuf;
-+
-+ ReadDOC(mydoc.virtadr, ChipID);
-+ ReadDOC(mydoc.virtadr, ChipID);
-+ if (ReadDOC(mydoc.virtadr, ChipID) != DOC_ChipID_DocMil) {
-+ /* It's not a Millennium; it's one of the newer
-+ DiskOnChip 2000 units with a similar ASIC.
-+ Treat it like a Millennium, except that it
-+ can have multiple chips. */
-+ doc2000_count_chips(&mymtd);
-+ nrchips = 4 * mydoc.chips_per_floor;
-+ name = "DiskOnChip 2000 (INFTL Model)";
-+ } else {
-+ /* Bog-standard Millennium */
-+ mydoc.chips_per_floor = 1;
-+ nrchips = 1;
-+ name = "DiskOnChip Millennium";
-+ }
-+ break;
-+
-+ case DOC_ChipID_Doc2k:
-+ mynand.write_byte = doc2000_write_byte;
-+ mynand.read_byte = doc2000_read_byte;
-+ mynand.write_buf = doc2000_writebuf;
-+ mynand.read_buf = doc2000_readbuf;
-+ mynand.verify_buf = doc2000_verifybuf;
-+
-+ doc2000_count_chips(&mymtd);
-+ nrchips = 4 * mydoc.chips_per_floor;
-+ name = "DiskOnChip 2000 (NFTL Model)";
-+ mydoc.CDSNControl |= CDSN_CTRL_FLASH_IO;
-+
-+ break;
-+
-+ default:
-+ return -EIO;
-+ }
-+ if (nand_scan(&mymtd, nrchips)) {
-+ iounmap((void *)mydoc.virtadr);
-+ return -EIO;
-+ }
-+ mymtd.name = name;
-+ add_mtd_device(&mymtd);
-+
-+ return 0;
-+}
-+
-+void __exit cleanup_nanddoc(void)
-+{
-+ del_mtd_device(&mymtd);
-+ iounmap((void *)mydoc.virtadr);
-+}
-+
-+module_init(init_nanddoc);
-+module_exit(cleanup_nanddoc);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-+MODULE_DESCRIPTION("M-Systems DiskOnChip 2000 and Millennium device driver\n");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/edb7312.c linux/drivers/mtd/nand/edb7312.c
---- linux-mips-2.4.27/drivers/mtd/nand/edb7312.c 2003-02-26 01:53:50.000000000 +0100
-+++ linux/drivers/mtd/nand/edb7312.c 2004-11-19 10:25:11.997184896 +0100
-@@ -6,7 +6,7 @@
- * Derived from drivers/mtd/nand/autcpu12.c
- * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
- *
-- * $Id$
-+ * $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
-@@ -20,6 +20,7 @@
-
- #include <linux/slab.h>
- #include <linux/module.h>
-+#include <linux/init.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/nand.h>
- #include <linux/mtd/partitions.h>
-@@ -77,16 +78,13 @@
- };
- #define NUM_PARTITIONS 1
-
--extern int parse_cmdline_partitions(struct mtd_info *master,
-- struct mtd_partition **pparts,
-- const char *mtd_id);
- #endif
-
-
- /*
- * hardware specific access to control-lines
- */
--static void ep7312_hwcontrol(int cmd)
-+static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd)
- {
- switch(cmd) {
-
-@@ -116,10 +114,13 @@
- /*
- * read device ready pin
- */
--static int ep7312_device_ready(void)
-+static int ep7312_device_ready(struct mtd_info *mtd)
- {
- return 1;
- }
-+#ifdef CONFIG_MTD_PARTITIONS
-+const char *part_probes[] = { "cmdlinepart", NULL };
-+#endif
-
- /*
- * Main initialization routine
-@@ -174,7 +175,7 @@
- this->chip_delay = 15;
-
- /* Scan to find existence of the device */
-- if (nand_scan (ep7312_mtd)) {
-+ if (nand_scan (ep7312_mtd, 1)) {
- iounmap((void *)ep7312_fio_base);
- kfree (ep7312_mtd);
- return -ENXIO;
-@@ -189,27 +190,16 @@
- return -ENOMEM;
- }
-
-- /* Allocate memory for internal data buffer */
-- this->data_cache = kmalloc (sizeof(u_char) * (ep7312_mtd->oobblock + ep7312_mtd->oobsize), GFP_KERNEL);
-- if (!this->data_cache) {
-- printk("Unable to allocate NAND data cache for EDB7312.\n");
-- kfree (this->data_buf);
-- iounmap((void *)ep7312_fio_base);
-- kfree (ep7312_mtd);
-- return -ENOMEM;
-- }
-- this->cache_page = -1;
--
--#ifdef CONFIG_MTD_CMDLINE_PARTS
-- mtd_parts_nb = parse_cmdline_partitions(ep7312_mtd, &mtd_parts,
-- "edb7312-nand");
-+#ifdef CONFIG_PARTITIONS
-+ ep7312_mtd->name = "edb7312-nand";
-+ mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes,
-+ &mtd_parts, 0);
- if (mtd_parts_nb > 0)
- part_type = "command line";
- else
- mtd_parts_nb = 0;
- #endif
-- if (mtd_parts_nb == 0)
-- {
-+ if (mtd_parts_nb == 0) {
- mtd_parts = partition_info;
- mtd_parts_nb = NUM_PARTITIONS;
- part_type = "static";
-@@ -236,7 +226,6 @@
-
- /* Free internal data buffer */
- kfree (this->data_buf);
-- kfree (this->data_cache);
-
- /* Free the MTD device structure */
- kfree (ep7312_mtd);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/nand.c linux/drivers/mtd/nand/nand.c
---- linux-mips-2.4.27/drivers/mtd/nand/nand.c 2003-02-26 01:53:50.000000000 +0100
-+++ linux/drivers/mtd/nand/nand.c 2004-11-19 10:25:12.010182920 +0100
-@@ -8,7 +8,7 @@
- * Additional technical information is available on
- * http://www.linux-mtd.infradead.org/tech/nand.html
- *
-- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
-+ * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
- * 2002 Thomas Gleixner (tglx@linutronix.de)
- *
- * 10-29-2001 Thomas Gleixner (tglx@linutronix.de)
-@@ -112,10 +112,27 @@
- * for mtd->read_ecc / mtd->write_ecc
- * some minor cleanups
- *
-- * 12-05-2000 tglx: Dave Ellis (DGE@sixnetio) provided the fix for
-+ * 12-05-2002 tglx: Dave Ellis (DGE@sixnetio) provided the fix for
- * WRITE_VERIFY long time ago. Thanks for remembering me.
- *
-- * $Id$
-+ * 02-14-2003 tglx: Reject non page aligned writes
-+ * Fixed ecc select in nand_write_page to match semantics.
-+ *
-+ * 02-18-2003 tglx: Changed oobsel to pointer. Added a default oob-selector
-+ *
-+ * 02-18-2003 tglx: Implemented oobsel again. Now it uses a pointer to
-+ + a structure, which will be supplied by a filesystem driver
-+ * If NULL is given, then the defaults (none or defaults
-+ * supplied by ioctl (MEMSETOOBSEL) are used.
-+ * For partitions the partition defaults are used (mtdpart.c)
-+ *
-+ * 06-04-2003 tglx: fix compile errors and fix write verify problem for
-+ * some chips, which need either a delay between the readback
-+ * and the next write command or have the CE removed. The
-+ * CE disable/enable is much faster than a 20us delay and
-+ * it should work on all available chips.
-+ *
-+ * $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
-@@ -130,102 +147,151 @@
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/nand.h>
- #include <linux/mtd/nand_ecc.h>
-+#include <linux/mtd/compatmac.h>
- #include <linux/interrupt.h>
- #include <asm/io.h>
-
- /*
-- * Macros for low-level register control
-- */
--#define nand_select() this->hwcontrol(NAND_CTL_SETNCE);
--
--#define nand_deselect() this->hwcontrol(NAND_CTL_CLRNCE);
--
--/*
-- * out of band configuration for different filesystems
-- */
--static int oobconfigs[][6] = {
-- { 0,0,0,0,0,0},
--
-- { NAND_JFFS2_OOB_ECCPOS0, NAND_JFFS2_OOB_ECCPOS1, NAND_JFFS2_OOB_ECCPOS2,
-- NAND_JFFS2_OOB_ECCPOS3, NAND_JFFS2_OOB_ECCPOS4, NAND_JFFS2_OOB_ECCPOS5 },
--
-- { NAND_YAFFS_OOB_ECCPOS0, NAND_YAFFS_OOB_ECCPOS1, NAND_YAFFS_OOB_ECCPOS2,
-- NAND_YAFFS_OOB_ECCPOS3, NAND_YAFFS_OOB_ECCPOS4, NAND_YAFFS_OOB_ECCPOS5 }
--};
--
--/*
- * NAND low-level MTD interface functions
- */
-+static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len);
-+static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len);
-+static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len);
-+
- static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
- static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
-- size_t * retlen, u_char * buf, u_char * eccbuf, int oobsel);
-+ size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
- static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
- static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf);
- static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
-- size_t * retlen, const u_char * buf, u_char * eccbuf, int oobsel);
-+ size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel);
- static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char *buf);
- static int nand_writev (struct mtd_info *mtd, const struct iovec *vecs,
- unsigned long count, loff_t to, size_t * retlen);
- static int nand_writev_ecc (struct mtd_info *mtd, const struct iovec *vecs,
-- unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, int oobsel);
-+ unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
- static int nand_erase (struct mtd_info *mtd, struct erase_info *instr);
- static void nand_sync (struct mtd_info *mtd);
--static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, int col,
-- int last, u_char *oob_buf, int oobsel);
-+static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, struct nand_oobinfo *oobsel);
-+
-+static u_char nand_read_byte(struct mtd_info *mtd)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ return readb(this->IO_ADDR_R);
-+}
-+
-+static void nand_write_byte(struct mtd_info *mtd, u_char byte)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ writeb(byte, this->IO_ADDR_W);
-+}
-+
-+static void nand_select_chip(struct mtd_info *mtd, int chip)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ switch(chip) {
-+ case -1:
-+ this->hwcontrol(mtd, NAND_CTL_CLRNCE);
-+ break;
-+ case 0:
-+ this->hwcontrol(mtd, NAND_CTL_SETNCE);
-+ break;
-+
-+ default:
-+ BUG();
-+ }
-+}
-+
-+static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ writeb(buf[i], this->IO_ADDR_W);
-+}
-+
-+static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ buf[i] = readb(this->IO_ADDR_R);
-+}
-+
-+static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ if (buf[i] != readb(this->IO_ADDR_R))
-+ return i;
-+
-+ return 0;
-+}
-+
-+/* Appropriate chip should already be selected */
-+static int nand_block_bad(struct mtd_info *mtd, unsigned long page)
-+{
-+ struct nand_chip *this = mtd->priv;
-+
-+ this->cmdfunc (mtd, NAND_CMD_READOOB, NAND_BADBLOCK_POS, page);
-+ if (this->read_byte(mtd) != 0xff)
-+ return 1;
-+
-+ return 0;
-+}
-+
- /*
- * Send command to NAND device
- */
- static void nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
- {
- register struct nand_chip *this = mtd->priv;
-- register unsigned long NAND_IO_ADDR = this->IO_ADDR_W;
-
- /* Begin command latch cycle */
-- this->hwcontrol (NAND_CTL_SETCLE);
-+ this->hwcontrol(mtd, NAND_CTL_SETCLE);
- /*
- * Write out the command to the device.
- */
-- if (command != NAND_CMD_SEQIN)
-- writeb (command, NAND_IO_ADDR);
-- else {
-- if (mtd->oobblock == 256 && column >= 256) {
-- column -= 256;
-- writeb (NAND_CMD_READOOB, NAND_IO_ADDR);
-- writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
-- } else if (mtd->oobblock == 512 && column >= 256) {
-- if (column < 512) {
-- column -= 256;
-- writeb (NAND_CMD_READ1, NAND_IO_ADDR);
-- writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
-- } else {
-- column -= 512;
-- writeb (NAND_CMD_READOOB, NAND_IO_ADDR);
-- writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
-- }
-+ if (command == NAND_CMD_SEQIN) {
-+ int readcmd;
-+
-+ if (column >= mtd->oobblock) {
-+ /* OOB area */
-+ column -= mtd->oobblock;
-+ readcmd = NAND_CMD_READOOB;
-+ } else if (column < 256) {
-+ /* First 256 bytes --> READ0 */
-+ readcmd = NAND_CMD_READ0;
- } else {
-- writeb (NAND_CMD_READ0, NAND_IO_ADDR);
-- writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
-+ column -= 256;
-+ readcmd = NAND_CMD_READ1;
- }
-+ this->write_byte(mtd, readcmd);
- }
-+ this->write_byte(mtd, command);
-
- /* Set ALE and clear CLE to start address cycle */
-- this->hwcontrol (NAND_CTL_CLRCLE);
-+ this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-
- if (column != -1 || page_addr != -1) {
-- this->hwcontrol (NAND_CTL_SETALE);
-+ this->hwcontrol(mtd, NAND_CTL_SETALE);
-
- /* Serially input address */
- if (column != -1)
-- writeb (column, NAND_IO_ADDR);
-+ this->write_byte(mtd, column);
- if (page_addr != -1) {
-- writeb ((unsigned char) (page_addr & 0xff), NAND_IO_ADDR);
-- writeb ((unsigned char) ((page_addr >> 8) & 0xff), NAND_IO_ADDR);
-+ this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
-+ this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
- /* One more address cycle for higher density devices */
- if (mtd->size & 0x0c000000)
-- writeb ((unsigned char) ((page_addr >> 16) & 0x0f), NAND_IO_ADDR);
-+ this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
- }
- /* Latch in address */
-- this->hwcontrol (NAND_CTL_CLRALE);
-+ this->hwcontrol(mtd, NAND_CTL_CLRALE);
- }
-
- /*
-@@ -244,10 +310,11 @@
- case NAND_CMD_RESET:
- if (this->dev_ready)
- break;
-- this->hwcontrol (NAND_CTL_SETCLE);
-- writeb (NAND_CMD_STATUS, NAND_IO_ADDR);
-- this->hwcontrol (NAND_CTL_CLRCLE);
-- while ( !(readb (this->IO_ADDR_R) & 0x40));
-+ udelay(this->chip_delay);
-+ this->hwcontrol(mtd, NAND_CTL_SETCLE);
-+ this->write_byte(mtd, NAND_CMD_STATUS);
-+ this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-+ while ( !(this->read_byte(mtd) & 0x40));
- return;
-
- /* This applies to read commands */
-@@ -263,7 +330,7 @@
- }
-
- /* wait until command is processed */
-- while (!this->dev_ready());
-+ while (!this->dev_ready(mtd));
- }
-
- /*
-@@ -288,17 +355,17 @@
- spin_unlock_bh (&this->chip_lock);
- return;
- }
--
-+#if 0 /* This was broken. And of dubious utility */
- if (this->state == FL_ERASING) {
- if (new_state != FL_ERASING) {
- this->state = new_state;
- spin_unlock_bh (&this->chip_lock);
-- nand_select (); /* select in any case */
-+ this->select_chip(mtd, 0); /* select in any case */
- this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
- return;
- }
- }
--
-+#endif
- set_current_state (TASK_UNINTERRUPTIBLE);
- add_wait_queue (&this->wq, &wait);
- spin_unlock_bh (&this->chip_lock);
-@@ -334,17 +401,17 @@
- return 0;
- }
- if (this->dev_ready) {
-- if (this->dev_ready ())
-+ if (this->dev_ready(mtd))
- break;
- }
-- if (readb (this->IO_ADDR_R) & 0x40)
-+ if (this->read_byte(mtd) & 0x40)
- break;
-
- spin_unlock_bh (&this->chip_lock);
- yield ();
- spin_lock_bh (&this->chip_lock);
- }
-- status = (int) readb (this->IO_ADDR_R);
-+ status = (int) this->read_byte(mtd);
- spin_unlock_bh (&this->chip_lock);
-
- return status;
-@@ -352,14 +419,15 @@
-
- /*
- * Nand_page_program function is used for write and writev !
-+ * This function will always program a full page of data
-+ * If you call it with a non page aligned buffer, you're lost :)
- */
--static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this,
-- int page, int col, int last, u_char *oob_buf, int oobsel)
-+static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, struct nand_oobinfo *oobsel)
- {
- int i, status;
- u_char ecc_code[6], *oob_data;
-- int eccmode = oobsel ? this->eccmode : NAND_ECC_NONE;
-- int *oob_config = oobconfigs[oobsel];
-+ int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
-+ int *oob_config = oobsel->eccpos;
-
- /* pad oob area, if we have no oob buffer from fs-driver */
- if (!oob_buf) {
-@@ -369,66 +437,42 @@
- } else
- oob_data = oob_buf;
-
-- /* software ecc 3 Bytes ECC / 256 Byte Data ? */
-- if (eccmode == NAND_ECC_SOFT) {
-- /* Read back previous written data, if col > 0 */
-- if (col) {
-- this->cmdfunc (mtd, NAND_CMD_READ0, 0, page);
-- for (i = 0; i < col; i++)
-- this->data_poi[i] = readb (this->IO_ADDR_R);
-- }
-- if ((col < this->eccsize) && (last >= this->eccsize)) {
-- this->calculate_ecc (&this->data_poi[0], &(ecc_code[0]));
-- for (i = 0; i < 3; i++)
-- oob_data[oob_config[i]] = ecc_code[i];
-- }
-- /* Calculate and write the second ECC if we have enough data */
-- if ((mtd->oobblock == 512) && (last == 512)) {
-- this->calculate_ecc (&this->data_poi[256], &(ecc_code[3]));
-- for (i = 3; i < 6; i++)
-- oob_data[oob_config[i]] = ecc_code[i];
-- }
-- } else {
-- /* For hardware ECC skip ECC, if we have no full page write */
-- if (eccmode != NAND_ECC_NONE && (col || last != mtd->oobblock))
-- eccmode = NAND_ECC_NONE;
-- }
--
-- /* Prepad for partial page programming !!! */
-- for (i = 0; i < col; i++)
-- this->data_poi[i] = 0xff;
--
-- /* Postpad for partial page programming !!! oob is already padded */
-- for (i = last; i < mtd->oobblock; i++)
-- this->data_poi[i] = 0xff;
--
- /* Send command to begin auto page programming */
- this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page);
-
- /* Write out complete page of data, take care of eccmode */
-- switch (this->eccmode) {
-+ switch (eccmode) {
- /* No ecc and software ecc 3/256, write all */
- case NAND_ECC_NONE:
-+ printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n");
-+ this->write_buf(mtd, this->data_poi, mtd->oobblock);
-+ break;
- case NAND_ECC_SOFT:
-- for (i = 0; i < mtd->oobblock; i++)
-- writeb ( this->data_poi[i] , this->IO_ADDR_W);
-+ this->calculate_ecc(mtd, &this->data_poi[0], &(ecc_code[0]));
-+ for (i = 0; i < 3; i++)
-+ oob_data[oob_config[i]] = ecc_code[i];
-+ /* Calculate and write the second ECC for 512 Byte page size */
-+ if (mtd->oobblock == 512) {
-+ this->calculate_ecc(mtd, &this->data_poi[256], &(ecc_code[3]));
-+ for (i = 3; i < 6; i++)
-+ oob_data[oob_config[i]] = ecc_code[i];
-+ }
-+ this->write_buf(mtd, this->data_poi, mtd->oobblock);
- break;
-
- /* Hardware ecc 3 byte / 256 data, write first half, get ecc, then second, if 512 byte pagesize */
- case NAND_ECC_HW3_256:
-- this->enable_hwecc (NAND_ECC_WRITE); /* enable hardware ecc logic for write */
-- for (i = 0; i < mtd->eccsize; i++)
-- writeb ( this->data_poi[i] , this->IO_ADDR_W);
-+ this->enable_hwecc(mtd, NAND_ECC_WRITE); /* enable hardware ecc logic for write */
-+ this->write_buf(mtd, this->data_poi, mtd->eccsize);
-
-- this->calculate_ecc (NULL, &(ecc_code[0]));
-+ this->calculate_ecc(mtd, NULL, &(ecc_code[0]));
- for (i = 0; i < 3; i++)
- oob_data[oob_config[i]] = ecc_code[i];
-
- if (mtd->oobblock == 512) {
-- this->enable_hwecc (NAND_ECC_WRITE); /* enable hardware ecc logic for write*/
-- for (i = mtd->eccsize; i < mtd->oobblock; i++)
-- writeb ( this->data_poi[i] , this->IO_ADDR_W);
-- this->calculate_ecc (NULL, &(ecc_code[3]));
-+ this->enable_hwecc(mtd, NAND_ECC_WRITE); /* enable hardware ecc logic for write*/
-+ this->write_buf(mtd, &this->data_poi[mtd->eccsize], mtd->oobblock - mtd->eccsize);
-+ this->calculate_ecc(mtd, NULL, &(ecc_code[3]));
- for (i = 3; i < 6; i++)
- oob_data[oob_config[i]] = ecc_code[i];
- }
-@@ -436,20 +480,18 @@
-
- /* Hardware ecc 3 byte / 512 byte data, write full page */
- case NAND_ECC_HW3_512:
-- this->enable_hwecc (NAND_ECC_WRITE); /* enable hardware ecc logic */
-- for (i = 0; i < mtd->oobblock; i++)
-- writeb ( this->data_poi[i] , this->IO_ADDR_W);
-- this->calculate_ecc (NULL, &(ecc_code[0]));
-+ this->enable_hwecc(mtd, NAND_ECC_WRITE); /* enable hardware ecc logic */
-+ this->write_buf(mtd, this->data_poi, mtd->oobblock);
-+ this->calculate_ecc(mtd, NULL, &(ecc_code[0]));
- for (i = 0; i < 3; i++)
- oob_data[oob_config[i]] = ecc_code[i];
- break;
-
- /* Hardware ecc 6 byte / 512 byte data, write full page */
- case NAND_ECC_HW6_512:
-- this->enable_hwecc (NAND_ECC_WRITE); /* enable hardware ecc logic */
-- for (i = 0; i < mtd->oobblock; i++)
-- writeb ( this->data_poi[i] , this->IO_ADDR_W);
-- this->calculate_ecc (NULL, &(ecc_code[0]));
-+ this->enable_hwecc(mtd, NAND_ECC_WRITE); /* enable hardware ecc logic */
-+ this->write_buf(mtd, this->data_poi, mtd->oobblock);
-+ this->calculate_ecc(mtd, NULL, &(ecc_code[0]));
- for (i = 0; i < 6; i++)
- oob_data[oob_config[i]] = ecc_code[i];
- break;
-@@ -460,8 +502,7 @@
- }
-
- /* Write out OOB data */
-- for (i = 0; i < mtd->oobsize; i++)
-- writeb ( oob_data[i] , this->IO_ADDR_W);
-+ this->write_buf(mtd, oob_data, mtd->oobsize);
-
- /* Send command to actually program the data */
- this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1);
-@@ -490,25 +531,21 @@
- */
-
- /* Send command to read back the page */
-- this->cmdfunc (mtd, NAND_CMD_READ0, col, page);
-+ this->cmdfunc (mtd, NAND_CMD_READ0, 0, page);
- /* Loop through and verify the data */
-- for (i = col; i < last; i++) {
-- if (this->data_poi[i] != readb (this->IO_ADDR_R)) {
-+ if (this->verify_buf(mtd, this->data_poi, mtd->oobblock)) {
- DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
- return -EIO;
- }
-- }
-
- /* check, if we have a fs-supplied oob-buffer */
- if (oob_buf) {
-- for (i = 0; i < mtd->oobsize; i++) {
-- if (oob_data[i] != readb (this->IO_ADDR_R)) {
-+ if (this->verify_buf(mtd, oob_data, mtd->oobsize)) {
- DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
- return -EIO;
- }
-- }
- } else {
-- if (eccmode != NAND_ECC_NONE && !col && last == mtd->oobblock) {
-+ if (eccmode != NAND_ECC_NONE) {
- int ecc_bytes = 0;
-
- switch (this->eccmode) {
-@@ -518,8 +555,7 @@
- case NAND_ECC_HW6_512: ecc_bytes = 6; break;
- }
-
-- for (i = 0; i < mtd->oobsize; i++)
-- oob_data[i] = readb (this->IO_ADDR_R);
-+ this->read_buf(mtd, oob_data, mtd->oobsize);
-
- for (i = 0; i < ecc_bytes; i++) {
- if (oob_data[oob_config[i]] != ecc_code[i]) {
-@@ -531,6 +567,13 @@
- }
- }
- }
-+ /*
-+ * Terminate the read command. This is faster than sending a reset command or
-+ * applying a 20us delay before issuing the next programm sequence.
-+ * This is not a problem for all chips, but I have found a bunch of them.
-+ */
-+ this->select_chip(mtd, -1);
-+ this->select_chip(mtd, 0);
- #endif
- return 0;
- }
-@@ -540,7 +583,7 @@
- */
- static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf)
- {
-- return (nand_read_ecc (mtd, from, len, retlen, buf, NULL, 0));
-+ return nand_read_ecc (mtd, from, len, retlen, buf, NULL, NULL);
- }
-
-
-@@ -548,7 +591,7 @@
- * NAND read with ECC
- */
- static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
-- size_t * retlen, u_char * buf, u_char * oob_buf, int oobsel)
-+ size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oobinfo *oobsel)
- {
- int j, col, page, end, ecc;
- int erase_state = 0;
-@@ -557,9 +600,15 @@
- u_char *data_poi, *oob_data = oob_buf;
- u_char ecc_calc[6];
- u_char ecc_code[6];
-- int eccmode = oobsel ? this->eccmode : NAND_ECC_NONE;
-+ int eccmode;
-+ int *oob_config;
-+
-+ // use chip default if zero
-+ if (oobsel == NULL)
-+ oobsel = &mtd->oobinfo;
-
-- int *oob_config = oobconfigs[oobsel];
-+ eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
-+ oob_config = oobsel->eccpos;
-
- DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);
-
-@@ -574,7 +623,7 @@
- nand_get_chip (this, mtd ,FL_READING, &erase_state);
-
- /* Select the NAND device */
-- nand_select ();
-+ this->select_chip(mtd, 0);
-
- /* First we calculate the starting page */
- page = from >> this->page_shift;
-@@ -596,7 +645,7 @@
- if (!this->dev_ready)
- udelay (this->chip_delay);
- else
-- while (!this->dev_ready());
-+ while (!this->dev_ready(mtd));
- }
-
- /*
-@@ -616,39 +665,40 @@
-
- j = 0;
- switch (eccmode) {
-- case NAND_ECC_NONE: /* No ECC, Read in a page */
-- while (j < end)
-- data_poi[j++] = readb (this->IO_ADDR_R);
-+ case NAND_ECC_NONE: { /* No ECC, Read in a page */
-+ static unsigned long lastwhinge = 0;
-+ if ((lastwhinge / HZ) != (jiffies / HZ)) {
-+ printk (KERN_WARNING "Reading data from NAND FLASH without ECC is not recommended\n");
-+ lastwhinge = jiffies;
-+ }
-+ this->read_buf(mtd, data_poi, end);
- break;
-+ }
-
- case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */
-- while (j < end)
-- data_poi[j++] = readb (this->IO_ADDR_R);
-- this->calculate_ecc (&data_poi[0], &ecc_calc[0]);
-+ this->read_buf(mtd, data_poi, end);
-+ this->calculate_ecc(mtd, &data_poi[0], &ecc_calc[0]);
- if (mtd->oobblock == 512)
-- this->calculate_ecc (&data_poi[256], &ecc_calc[3]);
-+ this->calculate_ecc(mtd, &data_poi[256], &ecc_calc[3]);
- break;
-
- case NAND_ECC_HW3_256: /* Hardware ECC 3 byte /256 byte data: Read in first 256 byte, get ecc, */
-- this->enable_hwecc (NAND_ECC_READ);
-- while (j < ecc)
-- data_poi[j++] = readb (this->IO_ADDR_R);
-- this->calculate_ecc (&data_poi[0], &ecc_calc[0]); /* read from hardware */
-+ this->enable_hwecc(mtd, NAND_ECC_READ);
-+ this->read_buf(mtd, data_poi, ecc);
-+ this->calculate_ecc(mtd, &data_poi[0], &ecc_calc[0]); /* read from hardware */
-
- if (mtd->oobblock == 512) { /* read second, if pagesize = 512 */
-- this->enable_hwecc (NAND_ECC_READ);
-- while (j < end)
-- data_poi[j++] = readb (this->IO_ADDR_R);
-- this->calculate_ecc (&data_poi[256], &ecc_calc[3]); /* read from hardware */
-+ this->enable_hwecc(mtd, NAND_ECC_READ);
-+ this->read_buf(mtd, &data_poi[ecc], end-ecc);
-+ this->calculate_ecc(mtd, &data_poi[256], &ecc_calc[3]); /* read from hardware */
- }
- break;
-
- case NAND_ECC_HW3_512:
- case NAND_ECC_HW6_512: /* Hardware ECC 3/6 byte / 512 byte data : Read in a page */
-- this->enable_hwecc (NAND_ECC_READ);
-- while (j < end)
-- data_poi[j++] = readb (this->IO_ADDR_R);
-- this->calculate_ecc (&data_poi[0], &ecc_calc[0]); /* read from hardware */
-+ this->enable_hwecc(mtd, NAND_ECC_READ);
-+ this->read_buf(mtd, data_poi, end);
-+ this->calculate_ecc(mtd, &data_poi[0], &ecc_calc[0]); /* read from hardware */
- break;
-
- default:
-@@ -658,7 +708,7 @@
-
- /* read oobdata */
- for (j = 0; j < mtd->oobsize; j++)
-- oob_data[oob + j] = readb (this->IO_ADDR_R);
-+ oob_data[oob + j] = this->read_byte(mtd);
-
- /* Skip ECC, if not active */
- if (eccmode == NAND_ECC_NONE)
-@@ -669,7 +719,7 @@
- ecc_code[j] = oob_data[oob + oob_config[j]];
-
- /* correct data, if neccecary */
-- ecc_status = this->correct_data (&data_poi[0], &ecc_code[0], &ecc_calc[0]);
-+ ecc_status = this->correct_data(mtd, &data_poi[0], &ecc_code[0], &ecc_calc[0]);
- /* check, if we have a fs supplied oob-buffer */
- if (oob_buf) {
- oob += mtd->oobsize;
-@@ -682,7 +732,7 @@
- }
-
- if (mtd->oobblock == 512 && eccmode != NAND_ECC_HW3_512) {
-- ecc_status = this->correct_data (&data_poi[256], &ecc_code[3], &ecc_calc[3]);
-+ ecc_status = this->correct_data(mtd, &data_poi[256], &ecc_code[3], &ecc_calc[3]);
- if (oob_buf) {
- *((int *)&oob_data[oob]) = ecc_status;
- oob += sizeof(int);
-@@ -705,7 +755,7 @@
- }
-
- /* De-select the NAND device */
-- nand_deselect ();
-+ this->select_chip(mtd, -1);
-
- /* Wake up anyone waiting on the device */
- spin_lock_bh (&this->chip_lock);
-@@ -753,7 +803,7 @@
- nand_get_chip (this, mtd , FL_READING, &erase_state);
-
- /* Select the NAND device */
-- nand_select ();
-+ this->select_chip(mtd, 0);
-
- /* Send the read command */
- this->cmdfunc (mtd, NAND_CMD_READOOB, col, page);
-@@ -761,13 +811,20 @@
- * Read the data, if we read more than one page
- * oob data, let the device transfer the data !
- */
-- for (i = 0; i < len; i++) {
-- buf[i] = readb (this->IO_ADDR_R);
-- if ((col++ & (mtd->oobsize - 1)) == (mtd->oobsize - 1))
-+ i = 0;
-+ while (i < len) {
-+ int thislen = (mtd->oobsize - col) & (mtd->oobsize - 1);
-+ if (!thislen)
-+ thislen = mtd->oobsize;
-+ thislen = min_t(int, thislen, len);
-+ this->read_buf(mtd, &buf[i], thislen);
-+ i += thislen;
-+ col += thislen;
-+ /* Delay between pages */
- udelay (this->chip_delay);
- }
- /* De-select the NAND device */
-- nand_deselect ();
-+ this->select_chip(mtd, -1);
-
- /* Wake up anyone waiting on the device */
- spin_lock_bh (&this->chip_lock);
-@@ -780,45 +837,54 @@
- return 0;
- }
-
-+#define NOTALIGNED(x) (x & (mtd->oobblock-1)) != 0
-+
- /*
- * Use NAND write ECC
- */
- static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
- {
-- return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, 0));
-+ return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL));
- }
- /*
- * NAND write with ECC
- */
- static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
-- size_t * retlen, const u_char * buf, u_char * eccbuf, int oobsel)
-+ size_t * retlen, const u_char * buf, u_char * eccbuf, struct nand_oobinfo *oobsel)
- {
-- int i, page, col, cnt, ret = 0, oob = 0, written = 0;
-+ int page, ret = 0, oob = 0, written = 0;
- struct nand_chip *this = mtd->priv;
-
- DEBUG (MTD_DEBUG_LEVEL3, "nand_write_ecc: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
-
- /* Do not allow write past end of device */
- if ((to + len) > mtd->size) {
-- DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Attempt to write past end of page\n");
-+ DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Attempt to write past end of page\n");
-+ return -EINVAL;
-+ }
-+
-+ /* reject writes, which are not page aligned */
-+ if (NOTALIGNED (to) || NOTALIGNED(len)) {
-+ printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
- return -EINVAL;
- }
-
-+ // if oobsel is NULL, use chip defaults
-+ if (oobsel == NULL)
-+ oobsel = &mtd->oobinfo;
-+
- /* Shift to get page */
- page = ((int) to) >> this->page_shift;
-
-- /* Get the starting column */
-- col = to & (mtd->oobblock - 1);
--
- /* Grab the lock and see if the device is available */
- nand_get_chip (this, mtd, FL_WRITING, NULL);
-
- /* Select the NAND device */
-- nand_select ();
-+ this->select_chip(mtd, 0);
-
- /* Check the WP bit */
- this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
-- if (!(readb (this->IO_ADDR_R) & 0x80)) {
-+ if (!(this->read_byte(mtd) & 0x80)) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Device is write protected!!!\n");
- ret = -EIO;
- goto out;
-@@ -826,42 +892,27 @@
-
- /* Loop until all data is written */
- while (written < len) {
-- /*
-- * Check, if we have a full page write, then we can
-- * use the given buffer, else we have to copy
-- */
-- if (!col && (len - written) >= mtd->oobblock) {
-+ int cnt = mtd->oobblock;
- this->data_poi = (u_char*) &buf[written];
-- cnt = mtd->oobblock;
-- } else {
-- cnt = 0;
-- for (i = col; i < len && i < mtd->oobblock; i++) {
-- this->data_buf[i] = buf[written + i];
-- cnt++;
-- }
-- this->data_poi = this->data_buf;
-- }
-- /* We use the same function for write and writev !) */
-+ /* We use the same function for write and writev */
- if (eccbuf) {
-- ret = nand_write_page (mtd, this, page, col, cnt ,&eccbuf[oob], oobsel);
-+ ret = nand_write_page (mtd, this, page, &eccbuf[oob], oobsel);
- oob += mtd->oobsize;
- } else
-- ret = nand_write_page (mtd, this, page, col, cnt, NULL, oobsel);
-+ ret = nand_write_page (mtd, this, page, NULL, oobsel);
-
- if (ret)
- goto out;
-
- /* Update written bytes count */
- written += cnt;
-- /* Next write is aligned */
-- col = 0;
- /* Increment page address */
- page++;
- }
-
- out:
- /* De-select the NAND device */
-- nand_deselect ();
-+ this->select_chip(mtd, -1);
-
- /* Wake up anyone waiting on the device */
- spin_lock_bh (&this->chip_lock);
-@@ -873,13 +924,21 @@
- return ret;
- }
-
-+static u_char ffchars[] = {
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
-+};
-+
- /*
- * NAND write out-of-band
- */
- static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf)
- {
-- int i, column, page, status, ret = 0;
-+ int column, page, status, ret = 0;
- struct nand_chip *this = mtd->priv;
-+#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
-+ int i;
-+#endif
-
- DEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
-
-@@ -902,27 +961,31 @@
- nand_get_chip (this, mtd, FL_WRITING, NULL);
-
- /* Select the NAND device */
-- nand_select ();
-+ this->select_chip(mtd, 0);
-+
-+ /* Reset the chip. Some chips (like the Toshiba TC5832DC found
-+ in one of my DiskOnChip 2000 test units) will clear the whole
-+ data page too if we don't do this. I have no clue why, but
-+ I seem to have 'fixed' it in the doc2000 driver in
-+ August 1999. dwmw2. */
-+ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
-
- /* Check the WP bit */
- this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
-- if (!(readb (this->IO_ADDR_R) & 0x80)) {
-+ if (!(this->read_byte(mtd) & 0x80)) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Device is write protected!!!\n");
- ret = -EIO;
- goto out;
- }
--
- /* Write out desired data */
- this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page);
-+
- /* prepad 0xff for partial programming */
-- for (i = 0; i < column; i++)
-- writeb (0xff, this->IO_ADDR_W);
-+ this->write_buf(mtd, ffchars, column);
- /* write data */
-- for (i = 0; i < len; i++)
-- writeb (buf[i], this->IO_ADDR_W);
-+ this->write_buf(mtd, buf, len);
- /* postpad 0xff for partial programming */
-- for (i = len + column; i < mtd->oobsize; i++)
-- writeb (0xff, this->IO_ADDR_W);
-+ this->write_buf(mtd, ffchars, mtd->oobsize - (len+column));
-
- /* Send command to program the OOB data */
- this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1);
-@@ -944,7 +1007,7 @@
-
- /* Loop through and verify the data */
- for (i = 0; i < len; i++) {
-- if (buf[i] != readb (this->IO_ADDR_R)) {
-+ if (buf[i] != this->read_byte(mtd)) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
- ret = -EIO;
- goto out;
-@@ -954,7 +1017,7 @@
-
- out:
- /* De-select the NAND device */
-- nand_deselect ();
-+ this->select_chip(mtd, -1);
-
- /* Wake up anyone waiting on the device */
- spin_lock_bh (&this->chip_lock);
-@@ -976,9 +1039,9 @@
- }
-
- static int nand_writev_ecc (struct mtd_info *mtd, const struct iovec *vecs, unsigned long count,
-- loff_t to, size_t * retlen, u_char *eccbuf, int oobsel)
-+ loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobsel)
- {
-- int i, page, col, cnt, len, total_len, ret = 0, written = 0;
-+ int i, page, len, total_len, ret = 0, written = 0;
- struct nand_chip *this = mtd->priv;
-
- /* Calculate total length of data */
-@@ -995,39 +1058,42 @@
- return -EINVAL;
- }
-
-+ /* reject writes, which are not page aligned */
-+ if (NOTALIGNED (to) || NOTALIGNED(total_len)) {
-+ printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligned data\n");
-+ return -EINVAL;
-+ }
-+
-+ // if oobsel is NULL, use chip defaults
-+ if (oobsel == NULL)
-+ oobsel = &mtd->oobinfo;
-+
- /* Shift to get page */
- page = ((int) to) >> this->page_shift;
-
-- /* Get the starting column */
-- col = to & (mtd->oobblock - 1);
--
- /* Grab the lock and see if the device is available */
- nand_get_chip (this, mtd, FL_WRITING, NULL);
-
- /* Select the NAND device */
-- nand_select ();
-+ this->select_chip(mtd, 0);
-
- /* Check the WP bit */
- this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
-- if (!(readb (this->IO_ADDR_R) & 0x80)) {
-+ if (!(this->read_byte(mtd) & 0x80)) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_writev: Device is write protected!!!\n");
- ret = -EIO;
- goto out;
- }
-
- /* Loop until all iovecs' data has been written */
-- cnt = col;
- len = 0;
--
- while (count) {
- /*
-- * Check, if we write from offset 0 and if the tuple
-- * gives us not enough data for a full page write. Then we
-- * can use the iov direct, else we have to copy into
-- * data_buf.
-+ * Check, if the tuple gives us not enough data for a
-+ * full page write. Then we can use the iov direct,
-+ * else we have to copy into data_buf.
- */
-- if (!cnt && (vecs->iov_len - len) >= mtd->oobblock) {
-- cnt = mtd->oobblock;
-+ if ((vecs->iov_len - len) >= mtd->oobblock) {
- this->data_poi = (u_char *) vecs->iov_base;
- this->data_poi += len;
- len += mtd->oobblock;
-@@ -1042,6 +1108,7 @@
- * Read data out of each tuple until we have a full page
- * to write or we've read all the tuples.
- */
-+ int cnt = 0;
- while ((cnt < mtd->oobblock) && count) {
- if (vecs->iov_base != NULL && vecs->iov_len) {
- this->data_buf[cnt++] = ((u_char *) vecs->iov_base)[len++];
-@@ -1057,15 +1124,12 @@
- }
-
- /* We use the same function for write and writev !) */
-- ret = nand_write_page (mtd, this, page, col, cnt, NULL, oobsel);
-+ ret = nand_write_page (mtd, this, page, NULL, oobsel);
- if (ret)
- goto out;
-
- /* Update written bytes count */
-- written += (cnt - col);
--
-- /* Reset written byte counter and column */
-- col = cnt = 0;
-+ written += mtd->oobblock;;
-
- /* Increment page address */
- page++;
-@@ -1073,7 +1137,7 @@
-
- out:
- /* De-select the NAND device */
-- nand_deselect ();
-+ this->select_chip(mtd, -1);
-
- /* Wake up anyone waiting on the device */
- spin_lock_bh (&this->chip_lock);
-@@ -1125,11 +1189,11 @@
- pages_per_block = mtd->erasesize / mtd->oobblock;
-
- /* Select the NAND device */
-- nand_select ();
-+ this->select_chip(mtd, 0);
-
- /* Check the WP bit */
- this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
-- if (!(readb (this->IO_ADDR_R) & 0x80)) {
-+ if (!(this->read_byte(mtd) & 0x80)) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Device is write protected!!!\n");
- instr->state = MTD_ERASE_FAILED;
- goto erase_exit;
-@@ -1142,8 +1206,7 @@
-
- while (len) {
- /* Check if we have a bad block, we do not erase bad blocks ! */
-- this->cmdfunc (mtd, NAND_CMD_READOOB, NAND_BADBLOCK_POS, page);
-- if (readb (this->IO_ADDR_R) != 0xff) {
-+ if (this->block_bad(mtd, page)) {
- printk (KERN_WARNING "nand_erase: attempt to erase a bad block at page 0x%08x\n", page);
- instr->state = MTD_ERASE_FAILED;
- goto erase_exit;
-@@ -1179,7 +1242,7 @@
- if (this->state == FL_ERASING || this->state == FL_READY) {
- /* Select the NAND device again, if we were interrupted */
- this->state = FL_ERASING;
-- nand_select ();
-+ this->select_chip(mtd, 0);
- continue;
- } else {
- set_current_state (TASK_UNINTERRUPTIBLE);
-@@ -1194,7 +1257,7 @@
-
- erase_exit:
- /* De-select the NAND device */
-- nand_deselect ();
-+ this->select_chip(mtd, -1);
- spin_unlock_bh (&this->chip_lock);
-
- ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO;;
-@@ -1205,6 +1268,7 @@
- /* The device is ready */
- spin_lock_bh (&this->chip_lock);
- this->state = FL_READY;
-+ wake_up (&this->wq);
- spin_unlock_bh (&this->chip_lock);
-
- /* Return more or less happy */
-@@ -1259,7 +1323,7 @@
- /*
- * Scan for the NAND device
- */
--int nand_scan (struct mtd_info *mtd)
-+int nand_scan (struct mtd_info *mtd, int maxchips)
- {
- int i, nand_maf_id, nand_dev_id;
- struct nand_chip *this = mtd->priv;
-@@ -1276,23 +1340,38 @@
- if (this->waitfunc == NULL)
- this->waitfunc = nand_wait;
-
-+ if (!this->block_bad)
-+ this->block_bad = nand_block_bad;
-+ if (!this->select_chip)
-+ this->select_chip = nand_select_chip;
-+ if (!this->write_byte)
-+ this->write_byte = nand_write_byte;
-+ if (!this->read_byte)
-+ this->read_byte = nand_read_byte;
-+ if (!this->write_buf)
-+ this->write_buf = nand_write_buf;
-+ if (!this->read_buf)
-+ this->read_buf = nand_read_buf;
-+ if (!this->verify_buf)
-+ this->verify_buf = nand_verify_buf;
-+
- /* Select the device */
-- nand_select ();
-+ this->select_chip(mtd, 0);
-
- /* Send the command for reading device ID */
- this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
-
- /* Read manufacturer and device IDs */
-- nand_maf_id = readb (this->IO_ADDR_R);
-- nand_dev_id = readb (this->IO_ADDR_R);
-+ nand_maf_id = this->read_byte(mtd);
-+ nand_dev_id = this->read_byte(mtd);
-
- /* Print and store flash device information */
- for (i = 0; nand_flash_ids[i].name != NULL; i++) {
- if (nand_dev_id == nand_flash_ids[i].id && !mtd->size) {
- mtd->name = nand_flash_ids[i].name;
- mtd->erasesize = nand_flash_ids[i].erasesize;
-- mtd->size = (1 << nand_flash_ids[i].chipshift);
- mtd->eccsize = 256;
-+ this->chipshift = nand_flash_ids[i].chipshift;
- if (nand_flash_ids[i].page256) {
- mtd->oobblock = 256;
- mtd->oobsize = 8;
-@@ -1307,13 +1386,34 @@
- if (nand_manuf_ids[i].id == nand_maf_id)
- break;
- }
-- printk (KERN_INFO "NAND device: Manufacture ID:"
-+ printk (KERN_INFO "NAND device: Manufacturer ID:"
- " 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,
- nand_manuf_ids[i].name , mtd->name);
- break;
- }
- }
-
-+ if (!mtd->name) {
-+ printk (KERN_WARNING "No NAND device found!!!\n");
-+ return 1;
-+ }
-+
-+ for (i=1; i < maxchips; i++) {
-+ this->select_chip(mtd, i);
-+
-+ /* Send the command for reading device ID */
-+ this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
-+
-+ /* Read manufacturer and device IDs */
-+ if (nand_maf_id != this->read_byte(mtd) ||
-+ nand_dev_id != this->read_byte(mtd))
-+ break;
-+ }
-+ if (i > 1)
-+ printk(KERN_INFO "%d NAND chips detected\n", i);
-+
-+ mtd->size = (1 << this->chipshift) /* * i when we fix the rest of the code */;
-+
- /*
- * check ECC mode, default to software
- * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize
-@@ -1324,6 +1424,7 @@
- switch (this->eccmode) {
-
- case NAND_ECC_HW3_512:
-+ case NAND_ECC_HW6_512:
- if (mtd->oobblock == 256) {
- printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n");
- this->eccmode = NAND_ECC_SOFT;
-@@ -1340,6 +1441,7 @@
- BUG();
-
- case NAND_ECC_NONE:
-+ printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is not recommended !!\n");
- this->eccmode = NAND_ECC_NONE;
- break;
-
-@@ -1359,18 +1461,11 @@
- spin_lock_init (&this->chip_lock);
-
- /* De-select the device */
-- nand_deselect ();
--
-- /* Print warning message for no device */
-- if (!mtd->size) {
-- printk (KERN_WARNING "No NAND device found!!!\n");
-- return 1;
-- }
-+ this->select_chip(mtd, -1);
-
- /* Fill in remaining MTD driver data */
- mtd->type = MTD_NANDFLASH;
- mtd->flags = MTD_CAP_NANDFLASH | MTD_ECC;
-- mtd->module = THIS_MODULE;
- mtd->ecctype = MTD_ECC_SW;
- mtd->erase = nand_erase;
- mtd->point = NULL;
-@@ -1389,6 +1484,7 @@
- mtd->unlock = NULL;
- mtd->suspend = NULL;
- mtd->resume = NULL;
-+ mtd->owner = THIS_MODULE;
-
- /* Return happy */
- return 0;
-@@ -1397,5 +1493,5 @@
- EXPORT_SYMBOL (nand_scan);
-
- MODULE_LICENSE ("GPL");
--MODULE_AUTHOR ("Steven J. Hill <sjhill@cotw.com>, Thomas Gleixner <tglx@linutronix.de>");
-+MODULE_AUTHOR ("Steven J. Hill <sjhill@realitydiluted.com>, Thomas Gleixner <tglx@linutronix.de>");
- MODULE_DESCRIPTION ("Generic NAND flash driver code");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/nand_ecc.c linux/drivers/mtd/nand/nand_ecc.c
---- linux-mips-2.4.27/drivers/mtd/nand/nand_ecc.c 2003-02-26 01:53:50.000000000 +0100
-+++ linux/drivers/mtd/nand/nand_ecc.c 2004-11-19 10:25:12.011182768 +0100
-@@ -1,10 +1,10 @@
- /*
- * drivers/mtd/nand_ecc.c
- *
-- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
-+ * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
- * Toshiba America Electronics Components, Inc.
- *
-- * $Id$
-+ * $Id$
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
-@@ -17,6 +17,7 @@
- #include <linux/types.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
-+#include <linux/mtd/nand_ecc.h>
-
- /*
- * Pre-calculated 256-way 1 byte column parity
-@@ -84,7 +85,7 @@
- /*
- * Calculate 3 byte ECC code for 256 byte block
- */
--void nand_calculate_ecc (const u_char *dat, u_char *ecc_code)
-+void nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
- {
- u_char idx, reg1, reg2, reg3;
- int j;
-@@ -119,7 +120,7 @@
- /*
- * Detect and correct a 1 bit error for 256 byte block
- */
--int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc)
-+int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
- {
- u_char a, b, c, d1, d2, d3, add, bit, i;
-
-@@ -209,5 +210,5 @@
- EXPORT_SYMBOL(nand_correct_data);
-
- MODULE_LICENSE("GPL");
--MODULE_AUTHOR("Steven J. Hill <sjhill@cotw.com>");
-+MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com>");
- MODULE_DESCRIPTION("Generic NAND ECC support");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/nand_ids.c linux/drivers/mtd/nand/nand_ids.c
---- linux-mips-2.4.27/drivers/mtd/nand/nand_ids.c 2003-02-26 01:53:50.000000000 +0100
-+++ linux/drivers/mtd/nand/nand_ids.c 2004-11-19 10:25:12.013182464 +0100
-@@ -4,7 +4,7 @@
- * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de)
- *
- *
-- * $Id$
-+ * $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
-@@ -18,21 +18,21 @@
- * Chip ID list
- */
- struct nand_flash_dev nand_flash_ids[] = {
-- {"NAND 1MB 5V", 0x6e, 20, 0x1000, 1}, // 1Mb 5V
-- {"NAND 2MB 5V", 0x64, 21, 0x1000, 1}, // 2Mb 5V
-- {"NAND 4MB 5V", 0x6b, 22, 0x2000, 0}, // 4Mb 5V
-- {"NAND 1MB 3,3V", 0xe8, 20, 0x1000, 1}, // 1Mb 3.3V
-- {"NAND 1MB 3,3V", 0xec, 20, 0x1000, 1}, // 1Mb 3.3V
-- {"NAND 2MB 3,3V", 0xea, 21, 0x1000, 1}, // 2Mb 3.3V
-- {"NAND 4MB 3,3V", 0xd5, 22, 0x2000, 0}, // 4Mb 3.3V
-- {"NAND 4MB 3,3V", 0xe3, 22, 0x2000, 0}, // 4Mb 3.3V
-- {"NAND 4MB 3,3V", 0xe5, 22, 0x2000, 0}, // 4Mb 3.3V
-- {"NAND 8MB 3,3V", 0xd6, 23, 0x2000, 0}, // 8Mb 3.3V
-- {"NAND 8MB 3,3V", 0xe6, 23, 0x2000, 0}, // 8Mb 3.3V
-- {"NAND 16MB 3,3V", 0x73, 24, 0x4000, 0},// 16Mb 3,3V
-- {"NAND 32MB 3,3V", 0x75, 25, 0x4000, 0}, // 32Mb 3,3V
-- {"NAND 64MB 3,3V", 0x76, 26, 0x4000, 0}, // 64Mb 3,3V
-- {"NAND 128MB 3,3V", 0x79, 27, 0x4000, 0}, // 128Mb 3,3V
-+ {"NAND 1MiB 5V", 0x6e, 20, 0x1000, 1},
-+ {"NAND 2MiB 5V", 0x64, 21, 0x1000, 1},
-+ {"NAND 4MiB 5V", 0x6b, 22, 0x2000, 0},
-+ {"NAND 1MiB 3,3V", 0xe8, 20, 0x1000, 1},
-+ {"NAND 1MiB 3,3V", 0xec, 20, 0x1000, 1},
-+ {"NAND 2MiB 3,3V", 0xea, 21, 0x1000, 1},
-+ {"NAND 4MiB 3,3V", 0xd5, 22, 0x2000, 0},
-+ {"NAND 4MiB 3,3V", 0xe3, 22, 0x2000, 0},
-+ {"NAND 4MiB 3,3V", 0xe5, 22, 0x2000, 0},
-+ {"NAND 8MiB 3,3V", 0xd6, 23, 0x2000, 0},
-+ {"NAND 8MiB 3,3V", 0xe6, 23, 0x2000, 0},
-+ {"NAND 16MiB 3,3V", 0x73, 24, 0x4000, 0},
-+ {"NAND 32MiB 3,3V", 0x75, 25, 0x4000, 0},
-+ {"NAND 64MiB 3,3V", 0x76, 26, 0x4000, 0},
-+ {"NAND 128MiB 3,3V", 0x79, 27, 0x4000, 0},
- {NULL,}
- };
-
-diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/spia.c linux/drivers/mtd/nand/spia.c
---- linux-mips-2.4.27/drivers/mtd/nand/spia.c 2003-02-26 01:53:50.000000000 +0100
-+++ linux/drivers/mtd/nand/spia.c 2004-11-19 10:25:12.014182312 +0100
-@@ -1,14 +1,14 @@
- /*
- * drivers/mtd/nand/spia.c
- *
-- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
-+ * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
- *
- *
- * 10-29-2001 TG change to support hardwarespecific access
- * to controllines (due to change in nand.c)
- * page_cache added
- *
-- * $Id$
-+ * $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
-@@ -20,6 +20,8 @@
- * a 64Mibit (8MiB x 8 bits) NAND flash device.
- */
-
-+#include <linux/kernel.h>
-+#include <linux/init.h>
- #include <linux/slab.h>
- #include <linux/module.h>
- #include <linux/mtd/mtd.h>
-@@ -35,14 +37,14 @@
- /*
- * Values specific to the SPIA board (used with EP7212 processor)
- */
--#define SPIA_IO_ADDR = 0xd0000000 /* Start of EP7212 IO address space */
--#define SPIA_FIO_ADDR = 0xf0000000 /* Address where flash is mapped */
--#define SPIA_PEDR = 0x0080 /*
-+#define SPIA_IO_BASE 0xd0000000 /* Start of EP7212 IO address space */
-+#define SPIA_FIO_BASE 0xf0000000 /* Address where flash is mapped */
-+#define SPIA_PEDR 0x0080 /*
- * IO offset to Port E data register
- * where the CLE, ALE and NCE pins
- * are wired to.
- */
--#define SPIA_PEDDR = 0x00c0 /*
-+#define SPIA_PEDDR 0x00c0 /*
- * IO offset to Port E data direction
- * register so we can control the IO
- * lines.
-@@ -62,21 +64,20 @@
- MODULE_PARM(spia_pedr, "i");
- MODULE_PARM(spia_peddr, "i");
-
--__setup("spia_io_base=",spia_io_base);
--__setup("spia_fio_base=",spia_fio_base);
--__setup("spia_pedr=",spia_pedr);
--__setup("spia_peddr=",spia_peddr);
--
- /*
- * Define partitions for flash device
- */
- const static struct mtd_partition partition_info[] = {
-- { name: "SPIA flash partition 1",
-- offset: 0,
-- size: 2*1024*1024 },
-- { name: "SPIA flash partition 2",
-- offset: 2*1024*1024,
-- size: 6*1024*1024 }
-+ {
-+ .name = "SPIA flash partition 1",
-+ .offset = 0,
-+ .size = 2*1024*1024
-+ },
-+ {
-+ .name = "SPIA flash partition 2",
-+ .offset = 2*1024*1024,
-+ .size = 6*1024*1024
-+ }
- };
- #define NUM_PARTITIONS 2
-
-@@ -84,7 +85,7 @@
- /*
- * hardware specific access to control-lines
- */
--void spia_hwcontrol(int cmd){
-+static void spia_hwcontrol(struct mtd_info *mtd, int cmd){
-
- switch(cmd){
-
-@@ -139,7 +140,7 @@
- this->chip_delay = 15;
-
- /* Scan to find existence of the device */
-- if (nand_scan (spia_mtd)) {
-+ if (nand_scan (spia_mtd, 1)) {
- kfree (spia_mtd);
- return -ENXIO;
- }
-@@ -152,16 +153,6 @@
- return -ENOMEM;
- }
-
-- /* Allocate memory for internal data buffer */
-- this->data_cache = kmalloc (sizeof(u_char) * (spia_mtd->oobblock + spia_mtd->oobsize), GFP_KERNEL);
-- if (!this->data_cache) {
-- printk ("Unable to allocate NAND data cache for SPIA.\n");
-- kfree (this->data_buf);
-- kfree (spia_mtd);
-- return = -ENOMEM;
-- }
-- this->cache_page = -1;
--
- /* Register the partitions */
- add_mtd_partitions(spia_mtd, partition_info, NUM_PARTITIONS);
-
-@@ -183,7 +174,6 @@
-
- /* Free internal data buffer */
- kfree (this->data_buf);
-- kfree (this->page_cache);
-
- /* Free the MTD device structure */
- kfree (spia_mtd);
-@@ -192,5 +182,5 @@
- #endif
-
- MODULE_LICENSE("GPL");
--MODULE_AUTHOR("Steven J. Hill <sjhill@cotw.com");
-+MODULE_AUTHOR("Steven J. Hill <sjhill@realitydiluted.com");
- MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on SPIA board");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/toto.c linux/drivers/mtd/nand/toto.c
---- linux-mips-2.4.27/drivers/mtd/nand/toto.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/nand/toto.c 2004-11-19 10:25:12.016182008 +0100
-@@ -0,0 +1,221 @@
-+/*
-+ * drivers/mtd/nand/toto.c
-+ *
-+ * Copyright (c) 2003 Texas Instruments
-+ *
-+ * Derived from drivers/mtd/autcpu12.c
-+ *
-+ * Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Overview:
-+ * This is a device driver for the NAND flash device found on the
-+ * TI fido board. It supports 32MiB and 64MiB cards
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/partitions.h>
-+#include <asm/io.h>
-+#include <asm/arch/hardware.h>
-+#include <asm/sizes.h>
-+#include <asm/arch/toto.h>
-+#include <asm/arch-omap1510/hardware.h>
-+#include <asm/arch/gpio.h>
-+
-+/*
-+ * MTD structure for TOTO board
-+ */
-+static struct mtd_info *toto_mtd = NULL;
-+
-+static int toto_io_base = OMAP_FLASH_1_BASE;
-+
-+#define CONFIG_NAND_WORKAROUND 1
-+
-+#define NAND_NCE 0x4000
-+#define NAND_CLE 0x1000
-+#define NAND_ALE 0x0002
-+#define NAND_MASK (NAND_CLE | NAND_ALE | NAND_NCE)
-+
-+#define T_NAND_CTL_CLRALE(iob) gpiosetout(NAND_ALE, 0)
-+#define T_NAND_CTL_SETALE(iob) gpiosetout(NAND_ALE, NAND_ALE)
-+#ifdef CONFIG_NAND_WORKAROUND /* "some" dev boards busted, blue wired to rts2 :( */
-+#define T_NAND_CTL_CLRCLE(iob) gpiosetout(NAND_CLE, 0); rts2setout(2, 2)
-+#define T_NAND_CTL_SETCLE(iob) gpiosetout(NAND_CLE, NAND_CLE); rts2setout(2, 0)
-+#else
-+#define T_NAND_CTL_CLRCLE(iob) gpiosetout(NAND_CLE, 0)
-+#define T_NAND_CTL_SETCLE(iob) gpiosetout(NAND_CLE, NAND_CLE)
-+#endif
-+#define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0)
-+#define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE)
-+
-+/*
-+ * Define partitions for flash devices
-+ */
-+
-+static struct mtd_partition partition_info64M[] = {
-+ { .name = "toto kernel partition 1",
-+ .offset = 0,
-+ .size = 2 * SZ_1M },
-+ { .name = "toto file sys partition 2",
-+ .offset = 2 * SZ_1M,
-+ .size = 14 * SZ_1M },
-+ { .name = "toto user partition 3",
-+ .offset = 16 * SZ_1M,
-+ .size = 16 * SZ_1M },
-+ { .name = "toto devboard extra partition 4",
-+ .offset = 32 * SZ_1M,
-+ .size = 32 * SZ_1M },
-+};
-+
-+static struct mtd_partition partition_info32M[] = {
-+ { .name = "toto kernel partition 1",
-+ .offset = 0,
-+ .size = 2 * SZ_1M },
-+ { .name = "toto file sys partition 2",
-+ .offset = 2 * SZ_1M,
-+ .size = 14 * SZ_1M },
-+ { .name = "toto user partition 3",
-+ .offset = 16 * SZ_1M,
-+ .size = 16 * SZ_1M },
-+};
-+
-+#define NUM_PARTITIONS32M 3
-+#define NUM_PARTITIONS64M 4
-+/*
-+ * hardware specific access to control-lines
-+*/
-+
-+static void toto_hwcontrol(struct mtd_info *mtd, int cmd)
-+{
-+
-+ udelay(1); /* hopefully enough time for tc make proceding write to clear */
-+ switch(cmd){
-+
-+ case NAND_CTL_SETCLE: T_NAND_CTL_SETCLE(cmd); break;
-+ case NAND_CTL_CLRCLE: T_NAND_CTL_CLRCLE(cmd); break;
-+
-+ case NAND_CTL_SETALE: T_NAND_CTL_SETALE(cmd); break;
-+ case NAND_CTL_CLRALE: T_NAND_CTL_CLRALE(cmd); break;
-+
-+ case NAND_CTL_SETNCE: T_NAND_CTL_SETNCE(cmd); break;
-+ case NAND_CTL_CLRNCE: T_NAND_CTL_CLRNCE(cmd); break;
-+ }
-+ udelay(1); /* allow time to ensure gpio state to over take memory write */
-+}
-+
-+/*
-+ * Main initialization routine
-+ */
-+int __init toto_init (void)
-+{
-+ struct nand_chip *this;
-+ int err = 0;
-+
-+ /* Allocate memory for MTD device structure and private data */
-+ toto_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
-+ GFP_KERNEL);
-+ if (!toto_mtd) {
-+ printk (KERN_WARNING "Unable to allocate toto NAND MTD device structure.\n");
-+ err = -ENOMEM;
-+ goto out;
-+ }
-+
-+ /* Get pointer to private data */
-+ this = (struct nand_chip *) (&toto_mtd[1]);
-+
-+ /* Initialize structures */
-+ memset((char *) toto_mtd, 0, sizeof(struct mtd_info));
-+ memset((char *) this, 0, sizeof(struct nand_chip));
-+
-+ /* Link the private data with the MTD structure */
-+ toto_mtd->priv = this;
-+
-+ /* Set address of NAND IO lines */
-+ this->IO_ADDR_R = toto_io_base;
-+ this->IO_ADDR_W = toto_io_base;
-+ this->hwcontrol = toto_hwcontrol;
-+ this->dev_ready = NULL;
-+ /* 25 us command delay time */
-+ this->chip_delay = 30;
-+ this->eccmode = NAND_ECC_SOFT;
-+
-+ /* Scan to find existance of the device */
-+ if (nand_scan (toto_mtd, 1)) {
-+ err = -ENXIO;
-+ goto out_mtd;
-+ }
-+
-+ /* Allocate memory for internal data buffer */
-+ this->data_buf = kmalloc (sizeof(u_char) * (toto_mtd->oobblock + toto_mtd->oobsize), GFP_KERNEL);
-+ if (!this->data_buf) {
-+ printk (KERN_WARNING "Unable to allocate NAND data buffer for toto.\n");
-+ err = -ENOMEM;
-+ goto out_mtd;
-+ }
-+
-+ /* Register the partitions */
-+ switch(toto_mtd->size){
-+ case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break;
-+ case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break;
-+ default: {
-+ printk (KERN_WARNING "Unsupported Nand device\n");
-+ err = -ENXIO;
-+ goto out_buf;
-+ }
-+ }
-+
-+ gpioreserve(NAND_MASK); /* claim our gpios */
-+ archflashwp(0,0); /* open up flash for writing */
-+
-+ goto out;
-+
-+out_buf:
-+ kfree (this->data_buf);
-+out_mtd:
-+ kfree (toto_mtd);
-+out:
-+ return err;
-+}
-+
-+module_init(toto_init);
-+
-+/*
-+ * Clean up routine
-+ */
-+static void __exit toto_cleanup (void)
-+{
-+ struct nand_chip *this = (struct nand_chip *) &toto_mtd[1];
-+
-+ /* Unregister partitions */
-+ del_mtd_partitions(toto_mtd);
-+
-+ /* Unregister the device */
-+ del_mtd_device (toto_mtd);
-+
-+ /* Free internal data buffers */
-+ kfree (this->data_buf);
-+
-+ /* Free the MTD device structure */
-+ kfree (toto_mtd);
-+
-+ /* stop flash writes */
-+ archflashwp(0,1);
-+
-+ /* release gpios to system */
-+ gpiorelease(NAND_MASK);
-+}
-+module_exit(toto_cleanup);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Richard Woodruff <r-woodruff2@ti.com>");
-+MODULE_DESCRIPTION("Glue layer for NAND flash on toto board");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/tx4925ndfmc.c linux/drivers/mtd/nand/tx4925ndfmc.c
---- linux-mips-2.4.27/drivers/mtd/nand/tx4925ndfmc.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/nand/tx4925ndfmc.c 2004-11-19 10:25:12.017181856 +0100
-@@ -0,0 +1,442 @@
-+/*
-+ * drivers/mtd/tx4925ndfmc.c
-+ *
-+ * Overview:
-+ * This is a device driver for the NAND flash device found on the
-+ * Toshiba RBTX4925 reference board, which is a SmartMediaCard. It supports
-+ * 16MiB, 32MiB and 64MiB cards.
-+ *
-+ * Author: MontaVista Software, Inc. source@mvista.com
-+ *
-+ * Derived from drivers/mtd/autcpu12.c
-+ * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
-+ *
-+ * $Id$
-+ *
-+ * Copyright (C) 2001 Toshiba Corporation
-+ *
-+ * 2003 (c) MontaVista Software, Inc. This file is licensed under
-+ * the terms of the GNU General Public License version 2. This program
-+ * is licensed "as is" without any warranty of any kind, whether express
-+ * or implied.
-+ *
-+ */
-+
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/partitions.h>
-+#include <linux/delay.h>
-+#include <asm/io.h>
-+#include <asm/tx4925/tx4925_nand.h>
-+
-+extern struct nand_oobinfo jffs2_oobinfo;
-+
-+/*
-+ * MTD structure for RBTX4925 board
-+ */
-+static struct mtd_info *tx4925ndfmc_mtd = NULL;
-+
-+/*
-+ * Module stuff
-+ */
-+#if LINUX_VERSION_CODE < 0x20212 && defined(MODULE)
-+#define tx4925ndfmc_init init_module
-+#define tx4925ndfmc_cleanup cleanup_module
-+#endif
-+
-+/*
-+ * Define partitions for flash devices
-+ */
-+
-+static struct mtd_partition partition_info16k[] = {
-+ { .name = "RBTX4925 flash partition 1",
-+ .offset = 0,
-+ .size = 8 * 0x00100000 },
-+ { .name = "RBTX4925 flash partition 2",
-+ .offset = 8 * 0x00100000,
-+ .size = 8 * 0x00100000 },
-+};
-+
-+static struct mtd_partition partition_info32k[] = {
-+ { .name = "RBTX4925 flash partition 1",
-+ .offset = 0,
-+ .size = 8 * 0x00100000 },
-+ { .name = "RBTX4925 flash partition 2",
-+ .offset = 8 * 0x00100000,
-+ .size = 24 * 0x00100000 },
-+};
-+
-+static struct mtd_partition partition_info64k[] = {
-+ { .name = "User FS",
-+ .offset = 0,
-+ .size = 16 * 0x00100000 },
-+ { .name = "RBTX4925 flash partition 2",
-+ .offset = 16 * 0x00100000,
-+ .size = 48 * 0x00100000},
-+};
-+
-+static struct mtd_partition partition_info128k[] = {
-+ { .name = "Skip bad section",
-+ .offset = 0,
-+ .size = 16 * 0x00100000 },
-+ { .name = "User FS",
-+ .offset = 16 * 0x00100000,
-+ .size = 112 * 0x00100000 },
-+};
-+#define NUM_PARTITIONS16K 2
-+#define NUM_PARTITIONS32K 2
-+#define NUM_PARTITIONS64K 2
-+#define NUM_PARTITIONS128K 2
-+
-+/*
-+ * hardware specific access to control-lines
-+*/
-+static void tx4925ndfmc_hwcontrol(struct mtd_info *mtd, int cmd)
-+{
-+
-+ switch(cmd){
-+
-+ case NAND_CTL_SETCLE:
-+ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_CLE;
-+ break;
-+ case NAND_CTL_CLRCLE:
-+ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_CLE;
-+ break;
-+ case NAND_CTL_SETALE:
-+ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ALE;
-+ break;
-+ case NAND_CTL_CLRALE:
-+ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ALE;
-+ break;
-+ case NAND_CTL_SETNCE:
-+ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_CE;
-+ break;
-+ case NAND_CTL_CLRNCE:
-+ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_CE;
-+ break;
-+ case NAND_CTL_SETWP:
-+ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_WE;
-+ break;
-+ case NAND_CTL_CLRWP:
-+ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_WE;
-+ break;
-+ }
-+}
-+
-+/*
-+* read device ready pin
-+*/
-+static int tx4925ndfmc_device_ready(struct mtd_info *mtd)
-+{
-+ int ready;
-+ ready = (tx4925_ndfmcptr->sr & TX4925_NDSFR_BUSY) ? 0 : 1;
-+ return ready;
-+}
-+void tx4925ndfmc_enable_hwecc(struct mtd_info *mtd, int mode)
-+{
-+ /* reset first */
-+ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_MASK;
-+ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
-+ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_ENAB;
-+}
-+static void tx4925ndfmc_disable_ecc(void)
-+{
-+ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
-+}
-+static void tx4925ndfmc_enable_read_ecc(void)
-+{
-+ tx4925_ndfmcptr->mcr &= ~TX4925_NDFMCR_ECC_CNTL_MASK;
-+ tx4925_ndfmcptr->mcr |= TX4925_NDFMCR_ECC_CNTL_READ;
-+}
-+void tx4925ndfmc_readecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code){
-+ int i;
-+ u_char *ecc = ecc_code;
-+ tx4925ndfmc_enable_read_ecc();
-+ for (i = 0;i < 6;i++,ecc++)
-+ *ecc = tx4925_read_nfmc(&(tx4925_ndfmcptr->dtr));
-+ tx4925ndfmc_disable_ecc();
-+}
-+void tx4925ndfmc_device_setup(void)
-+{
-+
-+ *(unsigned char *)0xbb005000 &= ~0x08;
-+
-+ /* reset NDFMC */
-+ tx4925_ndfmcptr->rstr |= TX4925_NDFRSTR_RST;
-+ while (tx4925_ndfmcptr->rstr & TX4925_NDFRSTR_RST);
-+
-+ /* setup BusSeparete, Hold Time, Strobe Pulse Width */
-+ tx4925_ndfmcptr->mcr = TX4925_BSPRT ? TX4925_NDFMCR_BSPRT : 0;
-+ tx4925_ndfmcptr->spr = TX4925_HOLD << 4 | TX4925_SPW;
-+}
-+static u_char tx4925ndfmc_nand_read_byte(struct mtd_info *mtd)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ return tx4925_read_nfmc(this->IO_ADDR_R);
-+}
-+
-+static void tx4925ndfmc_nand_write_byte(struct mtd_info *mtd, u_char byte)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ tx4925_write_nfmc(byte, this->IO_ADDR_W);
-+}
-+
-+static void tx4925ndfmc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ tx4925_write_nfmc(buf[i], this->IO_ADDR_W);
-+}
-+
-+static void tx4925ndfmc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ buf[i] = tx4925_read_nfmc(this->IO_ADDR_R);
-+}
-+
-+static int tx4925ndfmc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ if (buf[i] != tx4925_read_nfmc(this->IO_ADDR_R))
-+ return i;
-+
-+ return 0;
-+}
-+
-+/*
-+ * Send command to NAND device
-+ */
-+static void tx4925ndfmc_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
-+{
-+ register struct nand_chip *this = mtd->priv;
-+
-+ /* Begin command latch cycle */
-+ this->hwcontrol(mtd, NAND_CTL_SETCLE);
-+ /*
-+ * Write out the command to the device.
-+ */
-+ if (command == NAND_CMD_SEQIN) {
-+ int readcmd;
-+
-+ if (column >= mtd->oobblock) {
-+ /* OOB area */
-+ column -= mtd->oobblock;
-+ readcmd = NAND_CMD_READOOB;
-+ } else if (column < 256) {
-+ /* First 256 bytes --> READ0 */
-+ readcmd = NAND_CMD_READ0;
-+ } else {
-+ column -= 256;
-+ readcmd = NAND_CMD_READ1;
-+ }
-+ this->write_byte(mtd, readcmd);
-+ }
-+ this->write_byte(mtd, command);
-+
-+ /* Set ALE and clear CLE to start address cycle */
-+ this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-+
-+ if (column != -1 || page_addr != -1) {
-+ this->hwcontrol(mtd, NAND_CTL_SETALE);
-+
-+ /* Serially input address */
-+ if (column != -1)
-+ this->write_byte(mtd, column);
-+ if (page_addr != -1) {
-+ this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
-+ this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
-+ /* One more address cycle for higher density devices */
-+ if (mtd->size & 0x0c000000)
-+ this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
-+ }
-+ /* Latch in address */
-+ this->hwcontrol(mtd, NAND_CTL_CLRALE);
-+ }
-+
-+ /*
-+ * program and erase have their own busy handlers
-+ * status and sequential in needs no delay
-+ */
-+ switch (command) {
-+
-+ case NAND_CMD_PAGEPROG:
-+ /* Turn off WE */
-+ this->hwcontrol (mtd, NAND_CTL_CLRWP);
-+ return;
-+
-+ case NAND_CMD_SEQIN:
-+ /* Turn on WE */
-+ this->hwcontrol (mtd, NAND_CTL_SETWP);
-+ return;
-+
-+ case NAND_CMD_ERASE1:
-+ case NAND_CMD_ERASE2:
-+ case NAND_CMD_STATUS:
-+ return;
-+
-+ case NAND_CMD_RESET:
-+ if (this->dev_ready)
-+ break;
-+ this->hwcontrol(mtd, NAND_CTL_SETCLE);
-+ this->write_byte(mtd, NAND_CMD_STATUS);
-+ this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-+ while ( !(this->read_byte(mtd) & 0x40));
-+ return;
-+
-+ /* This applies to read commands */
-+ default:
-+ /*
-+ * If we don't have access to the busy pin, we apply the given
-+ * command delay
-+ */
-+ if (!this->dev_ready) {
-+ udelay (this->chip_delay);
-+ return;
-+ }
-+ }
-+
-+ /* wait until command is processed */
-+ while (!this->dev_ready(mtd));
-+}
-+
-+#ifdef CONFIG_MTD_CMDLINE_PARTS
-+extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partitio
-+n **pparts, char *);
-+#endif
-+
-+/*
-+ * Main initialization routine
-+ */
-+extern int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
-+int __init tx4925ndfmc_init (void)
-+{
-+ struct nand_chip *this;
-+ int err = 0;
-+
-+ /* Allocate memory for MTD device structure and private data */
-+ tx4925ndfmc_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
-+ GFP_KERNEL);
-+ if (!tx4925ndfmc_mtd) {
-+ printk ("Unable to allocate RBTX4925 NAND MTD device structure.\n");
-+ err = -ENOMEM;
-+ goto out;
-+ }
-+
-+ tx4925ndfmc_device_setup();
-+
-+ /* io is indirect via a register so don't need to ioremap address */
-+
-+ /* Get pointer to private data */
-+ this = (struct nand_chip *) (&tx4925ndfmc_mtd[1]);
-+
-+ /* Initialize structures */
-+ memset((char *) tx4925ndfmc_mtd, 0, sizeof(struct mtd_info));
-+ memset((char *) this, 0, sizeof(struct nand_chip));
-+
-+ /* Link the private data with the MTD structure */
-+ tx4925ndfmc_mtd->priv = this;
-+
-+ /* Set address of NAND IO lines */
-+ this->IO_ADDR_R = (unsigned long)&(tx4925_ndfmcptr->dtr);
-+ this->IO_ADDR_W = (unsigned long)&(tx4925_ndfmcptr->dtr);
-+ this->hwcontrol = tx4925ndfmc_hwcontrol;
-+ this->enable_hwecc = tx4925ndfmc_enable_hwecc;
-+ this->calculate_ecc = tx4925ndfmc_readecc;
-+ this->correct_data = nand_correct_data;
-+ this->eccmode = NAND_ECC_HW6_512;
-+ this->dev_ready = tx4925ndfmc_device_ready;
-+ /* 20 us command delay time */
-+ this->chip_delay = 20;
-+ this->read_byte = tx4925ndfmc_nand_read_byte;
-+ this->write_byte = tx4925ndfmc_nand_write_byte;
-+ this->cmdfunc = tx4925ndfmc_nand_command;
-+ this->write_buf = tx4925ndfmc_nand_write_buf;
-+ this->read_buf = tx4925ndfmc_nand_read_buf;
-+ this->verify_buf = tx4925ndfmc_nand_verify_buf;
-+
-+ /* Scan to find existance of the device */
-+ if (nand_scan (tx4925ndfmc_mtd, 1)) {
-+ err = -ENXIO;
-+ goto out_ior;
-+ }
-+
-+ /* Allocate memory for internal data buffer */
-+ this->data_buf = kmalloc (sizeof(u_char) * (tx4925ndfmc_mtd->oobblock + tx4925ndfmc_mtd->oobsize), GFP_KERNEL);
-+ if (!this->data_buf) {
-+ printk ("Unable to allocate NAND data buffer for RBTX4925.\n");
-+ err = -ENOMEM;
-+ goto out_ior;
-+ }
-+
-+ /* Register the partitions */
-+#ifdef CONFIG_MTD_CMDLINE_PARTS
-+ {
-+ int mtd_parts_nb = 0;
-+ struct mtd_partition *mtd_parts = 0;
-+ mtd_parts_nb = parse_cmdline_partitions(tx4925ndfmc_mtd, &mtd_parts, "tx4925ndfmc");
-+ if (mtd_parts_nb > 0)
-+ add_mtd_partitions(tx4925ndfmc_mtd, mtd_parts, mtd_parts_nb);
-+ else
-+ add_mtd_device(tx4925ndfmc_mtd);
-+ }
-+#else /* ifdef CONFIG_MTD_CMDLINE_PARTS */
-+ switch(tx4925ndfmc_mtd->size){
-+ case 0x01000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info16k, NUM_PARTITIONS16K); break;
-+ case 0x02000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info32k, NUM_PARTITIONS32K); break;
-+ case 0x04000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info64k, NUM_PARTITIONS64K); break;
-+ case 0x08000000: add_mtd_partitions(tx4925ndfmc_mtd, partition_info128k, NUM_PARTITIONS128K); break;
-+ default: {
-+ printk ("Unsupported SmartMedia device\n");
-+ err = -ENXIO;
-+ goto out_buf;
-+ }
-+ }
-+#endif /* ifdef CONFIG_MTD_CMDLINE_PARTS */
-+ goto out;
-+
-+out_buf:
-+ kfree (this->data_buf);
-+out_ior:
-+out:
-+ return err;
-+}
-+
-+module_init(tx4925ndfmc_init);
-+
-+/*
-+ * Clean up routine
-+ */
-+#ifdef MODULE
-+static void __exit tx4925ndfmc_cleanup (void)
-+{
-+ struct nand_chip *this = (struct nand_chip *) &tx4925ndfmc_mtd[1];
-+
-+ /* Unregister partitions */
-+ del_mtd_partitions(tx4925ndfmc_mtd);
-+
-+ /* Unregister the device */
-+ del_mtd_device (tx4925ndfmc_mtd);
-+
-+ /* Free internal data buffers */
-+ kfree (this->data_buf);
-+
-+ /* Free the MTD device structure */
-+ kfree (tx4925ndfmc_mtd);
-+}
-+module_exit(tx4925ndfmc_cleanup);
-+#endif
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Alice Hennessy <ahennessy@mvista.com>");
-+MODULE_DESCRIPTION("Glue layer for SmartMediaCard on Toshiba RBTX4925");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/nand/tx4938ndfmc.c linux/drivers/mtd/nand/tx4938ndfmc.c
---- linux-mips-2.4.27/drivers/mtd/nand/tx4938ndfmc.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/mtd/nand/tx4938ndfmc.c 2004-11-19 10:25:12.019181552 +0100
-@@ -0,0 +1,422 @@
-+/*
-+ * drivers/mtd/nand/tx4938ndfmc.c
-+ *
-+ * Overview:
-+ * This is a device driver for the NAND flash device connected to
-+ * TX4938 internal NAND Memory Controller.
-+ * TX4938 NDFMC is almost same as TX4925 NDFMC, but register size are 64 bit.
-+ *
-+ * Author: source@mvista.com
-+ *
-+ * Based on spia.c by Steven J. Hill
-+ *
-+ * $Id$
-+ *
-+ * Copyright (C) 2000-2001 Toshiba Corporation
-+ *
-+ * 2003 (c) MontaVista Software, Inc. This file is licensed under the
-+ * terms of the GNU General Public License version 2. This program is
-+ * licensed "as is" without any warranty of any kind, whether express
-+ * or implied.
-+ */
-+#include <linux/config.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/nand_ecc.h>
-+#include <linux/mtd/partitions.h>
-+#include <asm/io.h>
-+#include <asm/bootinfo.h>
-+#include <linux/delay.h>
-+#include <asm/tx4938/rbtx4938.h>
-+
-+extern struct nand_oobinfo jffs2_oobinfo;
-+
-+/*
-+ * MTD structure for TX4938 NDFMC
-+ */
-+static struct mtd_info *tx4938ndfmc_mtd;
-+
-+/*
-+ * Define partitions for flash device
-+ */
-+#define flush_wb() (void)tx4938_ndfmcptr->mcr;
-+
-+#define NUM_PARTITIONS 3
-+#define NUMBER_OF_CIS_BLOCKS 24
-+#define SIZE_OF_BLOCK 0x00004000
-+#define NUMBER_OF_BLOCK_PER_ZONE 1024
-+#define SIZE_OF_ZONE (NUMBER_OF_BLOCK_PER_ZONE * SIZE_OF_BLOCK)
-+#ifndef CONFIG_MTD_CMDLINE_PARTS
-+/*
-+ * You can use the following sample of MTD partitions
-+ * on the NAND Flash Memory 32MB or more.
-+ *
-+ * The following figure shows the image of the sample partition on
-+ * the 32MB NAND Flash Memory.
-+ *
-+ * Block No.
-+ * 0 +-----------------------------+ ------
-+ * | CIS | ^
-+ * 24 +-----------------------------+ |
-+ * | kernel image | | Zone 0
-+ * | | |
-+ * +-----------------------------+ |
-+ * 1023 | unused area | v
-+ * +-----------------------------+ ------
-+ * 1024 | JFFS2 | ^
-+ * | | |
-+ * | | | Zone 1
-+ * | | |
-+ * | | |
-+ * | | v
-+ * 2047 +-----------------------------+ ------
-+ *
-+ */
-+static struct mtd_partition partition_info[NUM_PARTITIONS] = {
-+ {
-+ .name = "RBTX4938 CIS Area",
-+ .offset = 0,
-+ .size = (NUMBER_OF_CIS_BLOCKS * SIZE_OF_BLOCK),
-+ .mask_flags = MTD_WRITEABLE /* This partition is NOT writable */
-+ },
-+ {
-+ .name = "RBTX4938 kernel image",
-+ .offset = MTDPART_OFS_APPEND,
-+ .size = 8 * 0x00100000, /* 8MB (Depends on size of kernel image) */
-+ .mask_flags = MTD_WRITEABLE /* This partition is NOT writable */
-+ },
-+ {
-+ .name = "Root FS (JFFS2)",
-+ .offset = (0 + SIZE_OF_ZONE), /* start address of next zone */
-+ .size = MTDPART_SIZ_FULL
-+ },
-+};
-+#endif
-+
-+static void tx4938ndfmc_hwcontrol(struct mtd_info *mtd, int cmd)
-+{
-+ switch (cmd) {
-+ case NAND_CTL_SETCLE:
-+ tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_CLE;
-+ break;
-+ case NAND_CTL_CLRCLE:
-+ tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_CLE;
-+ break;
-+ case NAND_CTL_SETALE:
-+ tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_ALE;
-+ break;
-+ case NAND_CTL_CLRALE:
-+ tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_ALE;
-+ break;
-+ /* TX4938_NDFMCR_CE bit is 0:high 1:low */
-+ case NAND_CTL_SETNCE:
-+ tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_CE;
-+ break;
-+ case NAND_CTL_CLRNCE:
-+ tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_CE;
-+ break;
-+ case NAND_CTL_SETWP:
-+ tx4938_ndfmcptr->mcr |= TX4938_NDFMCR_WE;
-+ break;
-+ case NAND_CTL_CLRWP:
-+ tx4938_ndfmcptr->mcr &= ~TX4938_NDFMCR_WE;
-+ break;
-+ }
-+}
-+static int tx4938ndfmc_dev_ready(struct mtd_info *mtd)
-+{
-+ flush_wb();
-+ return !(tx4938_ndfmcptr->sr & TX4938_NDFSR_BUSY);
-+}
-+static void tx4938ndfmc_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
-+{
-+ u32 mcr = tx4938_ndfmcptr->mcr;
-+ mcr &= ~TX4938_NDFMCR_ECC_ALL;
-+ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
-+ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_READ;
-+ ecc_code[1] = tx4938_ndfmcptr->dtr;
-+ ecc_code[0] = tx4938_ndfmcptr->dtr;
-+ ecc_code[2] = tx4938_ndfmcptr->dtr;
-+ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
-+}
-+static void tx4938ndfmc_enable_hwecc(struct mtd_info *mtd, int mode)
-+{
-+ u32 mcr = tx4938_ndfmcptr->mcr;
-+ mcr &= ~TX4938_NDFMCR_ECC_ALL;
-+ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_RESET;
-+ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_OFF;
-+ tx4938_ndfmcptr->mcr = mcr | TX4938_NDFMCR_ECC_ON;
-+}
-+
-+static u_char tx4938ndfmc_nand_read_byte(struct mtd_info *mtd)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ return tx4938_read_nfmc(this->IO_ADDR_R);
-+}
-+
-+static void tx4938ndfmc_nand_write_byte(struct mtd_info *mtd, u_char byte)
-+{
-+ struct nand_chip *this = mtd->priv;
-+ tx4938_write_nfmc(byte, this->IO_ADDR_W);
-+}
-+
-+static void tx4938ndfmc_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ tx4938_write_nfmc(buf[i], this->IO_ADDR_W);
-+}
-+
-+static void tx4938ndfmc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ buf[i] = tx4938_read_nfmc(this->IO_ADDR_R);
-+}
-+
-+static int tx4938ndfmc_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
-+{
-+ int i;
-+ struct nand_chip *this = mtd->priv;
-+
-+ for (i=0; i<len; i++)
-+ if (buf[i] != tx4938_read_nfmc(this->IO_ADDR_R))
-+ return i;
-+
-+ return 0;
-+}
-+
-+/*
-+ * Send command to NAND device
-+ */
-+static void tx4938ndfmc_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
-+{
-+ register struct nand_chip *this = mtd->priv;
-+
-+ /* Begin command latch cycle */
-+ this->hwcontrol(mtd, NAND_CTL_SETCLE);
-+ /*
-+ * Write out the command to the device.
-+ */
-+ if (command == NAND_CMD_SEQIN) {
-+ int readcmd;
-+
-+ if (column >= mtd->oobblock) {
-+ /* OOB area */
-+ column -= mtd->oobblock;
-+ readcmd = NAND_CMD_READOOB;
-+ } else if (column < 256) {
-+ /* First 256 bytes --> READ0 */
-+ readcmd = NAND_CMD_READ0;
-+ } else {
-+ column -= 256;
-+ readcmd = NAND_CMD_READ1;
-+ }
-+ this->write_byte(mtd, readcmd);
-+ }
-+ this->write_byte(mtd, command);
-+
-+ /* Set ALE and clear CLE to start address cycle */
-+ this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-+
-+ if (column != -1 || page_addr != -1) {
-+ this->hwcontrol(mtd, NAND_CTL_SETALE);
-+
-+ /* Serially input address */
-+ if (column != -1)
-+ this->write_byte(mtd, column);
-+ if (page_addr != -1) {
-+ this->write_byte(mtd, (unsigned char) (page_addr & 0xff));
-+ this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff));
-+ /* One more address cycle for higher density devices */
-+ if (mtd->size & 0x0c000000)
-+ this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f));
-+ }
-+ /* Latch in address */
-+ this->hwcontrol(mtd, NAND_CTL_CLRALE);
-+ }
-+
-+ /*
-+ * program and erase have their own busy handlers
-+ * status and sequential in needs no delay
-+ */
-+ switch (command) {
-+
-+ case NAND_CMD_PAGEPROG:
-+ /* Turn off WE */
-+ this->hwcontrol (mtd, NAND_CTL_CLRWP);
-+ return;
-+
-+ case NAND_CMD_SEQIN:
-+ /* Turn on WE */
-+ this->hwcontrol (mtd, NAND_CTL_SETWP);
-+ return;
-+
-+ case NAND_CMD_ERASE1:
-+ case NAND_CMD_ERASE2:
-+ case NAND_CMD_STATUS:
-+ return;
-+
-+ case NAND_CMD_RESET:
-+ if (this->dev_ready)
-+ break;
-+ this->hwcontrol(mtd, NAND_CTL_SETCLE);
-+ this->write_byte(mtd, NAND_CMD_STATUS);
-+ this->hwcontrol(mtd, NAND_CTL_CLRCLE);
-+ while ( !(this->read_byte(mtd) & 0x40));
-+ return;
-+
-+ /* This applies to read commands */
-+ default:
-+ /*
-+ * If we don't have access to the busy pin, we apply the given
-+ * command delay
-+ */
-+ if (!this->dev_ready) {
-+ udelay (this->chip_delay);
-+ return;
-+ }
-+ }
-+
-+ /* wait until command is processed */
-+ while (!this->dev_ready(mtd));
-+}
-+
-+#ifdef CONFIG_MTD_CMDLINE_PARTS
-+extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, char *);
-+#endif
-+/*
-+ * Main initialization routine
-+ */
-+int __init tx4938ndfmc_init (void)
-+{
-+ struct nand_chip *this;
-+ int bsprt = 0, hold = 0xf, spw = 0xf;
-+ int protected = 0;
-+
-+ if ((*rbtx4938_piosel_ptr & 0x0c) != 0x08) {
-+ printk("TX4938 NDFMC: disabled by IOC PIOSEL\n");
-+ return -ENODEV;
-+ }
-+ bsprt = 1;
-+ hold = 2;
-+ spw = 9 - 1; /* 8 GBUSCLK = 80ns (@ GBUSCLK 100MHz) */
-+
-+ if ((tx4938_ccfgptr->pcfg &
-+ (TX4938_PCFG_ATA_SEL|TX4938_PCFG_ISA_SEL|TX4938_PCFG_NDF_SEL))
-+ != TX4938_PCFG_NDF_SEL) {
-+ printk("TX4938 NDFMC: disabled by PCFG.\n");
-+ return -ENODEV;
-+ }
-+
-+ /* reset NDFMC */
-+ tx4938_ndfmcptr->rstr |= TX4938_NDFRSTR_RST;
-+ while (tx4938_ndfmcptr->rstr & TX4938_NDFRSTR_RST)
-+ ;
-+ /* setup BusSeparete, Hold Time, Strobe Pulse Width */
-+ tx4938_ndfmcptr->mcr = bsprt ? TX4938_NDFMCR_BSPRT : 0;
-+ tx4938_ndfmcptr->spr = hold << 4 | spw;
-+
-+ /* Allocate memory for MTD device structure and private data */
-+ tx4938ndfmc_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
-+ GFP_KERNEL);
-+ if (!tx4938ndfmc_mtd) {
-+ printk ("Unable to allocate TX4938 NDFMC MTD device structure.\n");
-+ return -ENOMEM;
-+ }
-+
-+ /* Get pointer to private data */
-+ this = (struct nand_chip *) (&tx4938ndfmc_mtd[1]);
-+
-+ /* Initialize structures */
-+ memset((char *) tx4938ndfmc_mtd, 0, sizeof(struct mtd_info));
-+ memset((char *) this, 0, sizeof(struct nand_chip));
-+
-+ /* Link the private data with the MTD structure */
-+ tx4938ndfmc_mtd->priv = this;
-+
-+ /* Set address of NAND IO lines */
-+ this->IO_ADDR_R = (unsigned long)&tx4938_ndfmcptr->dtr;
-+ this->IO_ADDR_W = (unsigned long)&tx4938_ndfmcptr->dtr;
-+ this->hwcontrol = tx4938ndfmc_hwcontrol;
-+ this->dev_ready = tx4938ndfmc_dev_ready;
-+ this->calculate_ecc = tx4938ndfmc_calculate_ecc;
-+ this->correct_data = nand_correct_data;
-+ this->enable_hwecc = tx4938ndfmc_enable_hwecc;
-+ this->eccmode = NAND_ECC_HW3_256;
-+ this->chip_delay = 100;
-+ this->read_byte = tx4938ndfmc_nand_read_byte;
-+ this->write_byte = tx4938ndfmc_nand_write_byte;
-+ this->cmdfunc = tx4938ndfmc_nand_command;
-+ this->write_buf = tx4938ndfmc_nand_write_buf;
-+ this->read_buf = tx4938ndfmc_nand_read_buf;
-+ this->verify_buf = tx4938ndfmc_nand_verify_buf;
-+
-+ /* Scan to find existance of the device */
-+ if (nand_scan (tx4938ndfmc_mtd, 1)) {
-+ kfree (tx4938ndfmc_mtd);
-+ return -ENXIO;
-+ }
-+
-+ /* Allocate memory for internal data buffer */
-+ this->data_buf = kmalloc (sizeof(u_char) * (tx4938ndfmc_mtd->oobblock + tx4938ndfmc_mtd->oobsize), GFP_KERNEL);
-+ if (!this->data_buf) {
-+ printk ("Unable to allocate NAND data buffer for TX4938.\n");
-+ kfree (tx4938ndfmc_mtd);
-+ return -ENOMEM;
-+ }
-+
-+ if (protected) {
-+ printk(KERN_INFO "TX4938 NDFMC: write protected.\n");
-+ tx4938ndfmc_mtd->flags &= ~(MTD_WRITEABLE | MTD_ERASEABLE);
-+ }
-+
-+#ifdef CONFIG_MTD_CMDLINE_PARTS
-+ {
-+ int mtd_parts_nb = 0;
-+ struct mtd_partition *mtd_parts = 0;
-+ mtd_parts_nb = parse_cmdline_partitions(tx4938ndfmc_mtd, &mtd_parts, "tx4938ndfmc");
-+ if (mtd_parts_nb > 0)
-+ add_mtd_partitions(tx4938ndfmc_mtd, mtd_parts, mtd_parts_nb);
-+ else
-+ add_mtd_device(tx4938ndfmc_mtd);
-+ }
-+#else
-+ add_mtd_partitions(tx4938ndfmc_mtd, partition_info, NUM_PARTITIONS );
-+#endif
-+
-+ return 0;
-+}
-+module_init(tx4938ndfmc_init);
-+
-+/*
-+ * Clean up routine
-+ */
-+static void __exit tx4938ndfmc_cleanup (void)
-+{
-+ struct nand_chip *this = (struct nand_chip *) tx4938ndfmc_mtd->priv;
-+
-+ /* Unregister the device */
-+#ifdef CONFIG_MTD_CMDLINE_PARTS
-+ del_mtd_partitions(tx4938ndfmc_mtd);
-+#endif
-+ del_mtd_device (tx4938ndfmc_mtd);
-+
-+ /* Free the MTD device structure */
-+ kfree (tx4938ndfmc_mtd);
-+
-+ /* Free internal data buffer */
-+ kfree (this->data_buf);
-+}
-+module_exit(tx4938ndfmc_cleanup);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Alice Hennessy <ahennessy@mvista.com>");
-+MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on TX4938 NDFMC");
-diff -Nurb linux-mips-2.4.27/drivers/mtd/nftlcore.c linux/drivers/mtd/nftlcore.c
---- linux-mips-2.4.27/drivers/mtd/nftlcore.c 2003-02-26 01:53:49.000000000 +0100
-+++ linux/drivers/mtd/nftlcore.c 2004-11-19 10:25:11.653237184 +0100
-@@ -1,7 +1,7 @@
- /* Linux driver for NAND Flash Translation Layer */
- /* (c) 1999 Machine Vision Holdings, Inc. */
- /* Author: David Woodhouse <dwmw2@infradead.org> */
--/* $Id$ */
-+/* $Id$ */
-
- /*
- The contents of this file are distributed under the GNU General
-@@ -23,15 +23,13 @@
- #include <linux/slab.h>
- #include <linux/sched.h>
- #include <linux/init.h>
--#include <linux/blkpg.h>
-+#include <linux/hdreg.h>
-
--#ifdef CONFIG_KMOD
- #include <linux/kmod.h>
--#endif
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/nand.h>
- #include <linux/mtd/nftl.h>
--#include <linux/mtd/compatmac.h>
-+#include <linux/mtd/blktrans.h>
-
- /* maximum number of loops while examining next block, to have a
- chance to detect consistency problems (they should never happen
-@@ -39,187 +37,95 @@
-
- #define MAX_LOOPS 10000
-
--/* NFTL block device stuff */
--#define MAJOR_NR NFTL_MAJOR
--#define DEVICE_REQUEST nftl_request
--#define DEVICE_OFF(device)
--
--
--#include <linux/blk.h>
--#include <linux/hdreg.h>
--
--/* Linux-specific block device functions */
--
--/* I _HATE_ the Linux block device setup more than anything else I've ever
-- * encountered, except ...
-- */
--
--static int nftl_sizes[256];
--static int nftl_blocksizes[256];
--
--/* .. for the Linux partition table handling. */
--struct hd_struct part_table[256];
--
--#if LINUX_VERSION_CODE < 0x20328
--static void dummy_init (struct gendisk *crap)
--{}
--#endif
--
--static struct gendisk nftl_gendisk = {
-- major: MAJOR_NR,
-- major_name: "nftl",
-- minor_shift: NFTL_PARTN_BITS, /* Bits to shift to get real from partition */
-- max_p: (1<<NFTL_PARTN_BITS)-1, /* Number of partitions per real */
--#if LINUX_VERSION_CODE < 0x20328
-- max_nr: MAX_NFTLS, /* maximum number of real */
-- init: dummy_init, /* init function */
--#endif
-- part: part_table, /* hd struct */
-- sizes: nftl_sizes, /* block sizes */
--};
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
--#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
--#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
--#else
--#define BLK_INC_USE_COUNT do {} while(0)
--#define BLK_DEC_USE_COUNT do {} while(0)
--#endif
--
--struct NFTLrecord *NFTLs[MAX_NFTLS];
-
--static void NFTL_setup(struct mtd_info *mtd)
-+static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
- {
-- int i;
- struct NFTLrecord *nftl;
- unsigned long temp;
-- int firstfree = -1;
--
-- DEBUG(MTD_DEBUG_LEVEL1,"NFTL_setup\n");
-
-- for (i = 0; i < MAX_NFTLS; i++) {
-- if (!NFTLs[i] && firstfree == -1)
-- firstfree = i;
-- else if (NFTLs[i] && NFTLs[i]->mtd == mtd) {
-- /* This is a Spare Media Header for an NFTL we've already found */
-- DEBUG(MTD_DEBUG_LEVEL1, "MTD already mounted as NFTL\n");
-+ if (mtd->ecctype != MTD_ECC_RS_DiskOnChip)
- return;
-- }
-- }
-- if (firstfree == -1) {
-- printk(KERN_WARNING "No more NFTL slot available\n");
-- return;
-- }
-+
-+ DEBUG(MTD_DEBUG_LEVEL1, "NFTL: add_mtd for %s\n", mtd->name);
-
- nftl = kmalloc(sizeof(struct NFTLrecord), GFP_KERNEL);
-+
- if (!nftl) {
-- printk(KERN_WARNING "Out of memory for NFTL data structures\n");
-+ printk(KERN_WARNING "NFTL: out of memory for data structures\n");
- return;
- }
-+ memset(nftl, 0, sizeof(*nftl));
-
-- init_MUTEX(&nftl->mutex);
--
-- nftl->mtd = mtd;
-+ nftl->mbd.mtd = mtd;
-+ nftl->mbd.devnum = -1;
-+ nftl->mbd.blksize = 512;
-+ nftl->mbd.tr = tr;
-
- if (NFTL_mount(nftl) < 0) {
-- printk(KERN_WARNING "Could not mount NFTL device\n");
-+ printk(KERN_WARNING "NFTL: could not mount device\n");
- kfree(nftl);
- return;
- }
-
- /* OK, it's a new one. Set up all the data structures. */
--#ifdef PSYCHO_DEBUG
-- printk("Found new NFTL nftl%c\n", firstfree + 'a');
--#endif
-
-- /* linux stuff */
-- nftl->usecount = 0;
-+ /* Calculate geometry */
- nftl->cylinders = 1024;
- nftl->heads = 16;
-
- temp = nftl->cylinders * nftl->heads;
-- nftl->sectors = nftl->nr_sects / temp;
-- if (nftl->nr_sects % temp) {
-+ nftl->sectors = nftl->mbd.size / temp;
-+ if (nftl->mbd.size % temp) {
- nftl->sectors++;
- temp = nftl->cylinders * nftl->sectors;
-- nftl->heads = nftl->nr_sects / temp;
-+ nftl->heads = nftl->mbd.size / temp;
-
-- if (nftl->nr_sects % temp) {
-+ if (nftl->mbd.size % temp) {
- nftl->heads++;
- temp = nftl->heads * nftl->sectors;
-- nftl->cylinders = nftl->nr_sects / temp;
-+ nftl->cylinders = nftl->mbd.size / temp;
- }
- }
-
-- if (nftl->nr_sects != nftl->heads * nftl->cylinders * nftl->sectors) {
-- printk(KERN_WARNING "Cannot calculate an NFTL geometry to "
-- "match size of 0x%x.\n", nftl->nr_sects);
-- printk(KERN_WARNING "Using C:%d H:%d S:%d (== 0x%lx sects)\n",
-+ if (nftl->mbd.size != nftl->heads * nftl->cylinders * nftl->sectors) {
-+ /*
-+ Oh no we don't have
-+ mbd.size == heads * cylinders * sectors
-+ */
-+ printk(KERN_WARNING "NFTL: cannot calculate a geometry to "
-+ "match size of 0x%lx.\n", nftl->mbd.size);
-+ printk(KERN_WARNING "NFTL: using C:%d H:%d S:%d "
-+ "(== 0x%lx sects)\n",
- nftl->cylinders, nftl->heads , nftl->sectors,
-- (long)nftl->cylinders * (long)nftl->heads * (long)nftl->sectors );
--
-- /* Oh no we don't have nftl->nr_sects = nftl->heads * nftl->cylinders * nftl->sectors; */
-+ (long)nftl->cylinders * (long)nftl->heads *
-+ (long)nftl->sectors );
- }
-- NFTLs[firstfree] = nftl;
-- /* Finally, set up the block device sizes */
-- nftl_sizes[firstfree * 16] = nftl->nr_sects;
-- //nftl_blocksizes[firstfree*16] = 512;
-- part_table[firstfree * 16].nr_sects = nftl->nr_sects;
--
-- nftl_gendisk.nr_real++;
--
-- /* partition check ... */
--#if LINUX_VERSION_CODE < 0x20328
-- resetup_one_dev(&nftl_gendisk, firstfree);
--#else
-- grok_partitions(&nftl_gendisk, firstfree, 1<<NFTL_PARTN_BITS, nftl->nr_sects);
--#endif
--}
--
--static void NFTL_unsetup(int i)
--{
-- struct NFTLrecord *nftl = NFTLs[i];
--
-- DEBUG(MTD_DEBUG_LEVEL1, "NFTL_unsetup %d\n", i);
--
-- NFTLs[i] = NULL;
-
-+ if (add_mtd_blktrans_dev(&nftl->mbd)) {
- if (nftl->ReplUnitTable)
- kfree(nftl->ReplUnitTable);
- if (nftl->EUNtable)
- kfree(nftl->EUNtable);
--
-- nftl_gendisk.nr_real--;
- kfree(nftl);
--}
--
--/* Search the MTD device for NFTL partitions */
--static void NFTL_notify_add(struct mtd_info *mtd)
--{
-- DEBUG(MTD_DEBUG_LEVEL1, "NFTL_notify_add for %s\n", mtd->name);
--
-- if (mtd) {
-- if (!mtd->read_oob) {
-- /* If this MTD doesn't have out-of-band data,
-- then there's no point continuing */
-- DEBUG(MTD_DEBUG_LEVEL1, "No OOB data, quitting\n");
- return;
- }
-- DEBUG(MTD_DEBUG_LEVEL3, "mtd->read = %p, size = %d, erasesize = %d\n",
-- mtd->read, mtd->size, mtd->erasesize);
--
-- NFTL_setup(mtd);
-- }
-+#ifdef PSYCHO_DEBUG
-+ printk(KERN_INFO "NFTL: Found new nftl%c\n", nftl->mbd.devnum + 'a');
-+#endif
- }
-
--static void NFTL_notify_remove(struct mtd_info *mtd)
-+static void nftl_remove_dev(struct mtd_blktrans_dev *dev)
- {
-- int i;
-+ struct NFTLrecord *nftl = (void *)dev;
-
-- for (i = 0; i < MAX_NFTLS; i++) {
-- if (NFTLs[i] && NFTLs[i]->mtd == mtd)
-- NFTL_unsetup(i);
-- }
-+ DEBUG(MTD_DEBUG_LEVEL1, "NFTL: remove_dev (i=%d)\n", dev->devnum);
-+
-+ del_mtd_blktrans_dev(dev);
-+ if (nftl->ReplUnitTable)
-+ kfree(nftl->ReplUnitTable);
-+ if (nftl->EUNtable)
-+ kfree(nftl->EUNtable);
-+ kfree(nftl);
- }
-
- #ifdef CONFIG_NFTL_RW
-@@ -303,7 +209,7 @@
-
- targetEUN = thisEUN;
- for (block = 0; block < nftl->EraseSize / 512; block ++) {
-- MTD_READOOB(nftl->mtd,
-+ MTD_READOOB(nftl->mbd.mtd,
- (thisEUN * nftl->EraseSize) + (block * 512),
- 16 , &retlen, (char *)&oob);
- if (block == 2) {
-@@ -420,7 +326,7 @@
- chain by selecting the longer one */
- oob.u.c.FoldMark = oob.u.c.FoldMark1 = cpu_to_le16(FOLD_MARK_IN_PROGRESS);
- oob.u.c.unused = 0xffffffff;
-- MTD_WRITEOOB(nftl->mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8,
-+ MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 2 * 512 + 8,
- 8, &retlen, (char *)&oob.u);
- }
-
-@@ -444,16 +350,16 @@
- if (BlockMap[block] == BLOCK_NIL)
- continue;
-
-- ret = MTD_READECC(nftl->mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512),
-+ ret = MTD_READECC(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block]) + (block * 512),
- 512, &retlen, movebuf, (char *)&oob, NAND_ECC_DISKONCHIP);
- if (ret < 0) {
-- ret = MTD_READECC(nftl->mtd, (nftl->EraseSize * BlockMap[block])
-+ ret = MTD_READECC(nftl->mbd.mtd, (nftl->EraseSize * BlockMap[block])
- + (block * 512), 512, &retlen,
- movebuf, (char *)&oob, NAND_ECC_DISKONCHIP);
- if (ret != -EIO)
- printk("Error went away on retry.\n");
- }
-- MTD_WRITEECC(nftl->mtd, (nftl->EraseSize * targetEUN) + (block * 512),
-+ MTD_WRITEECC(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + (block * 512),
- 512, &retlen, movebuf, (char *)&oob, NAND_ECC_DISKONCHIP);
- }
-
-@@ -462,7 +368,7 @@
- = cpu_to_le16(thisVUC);
- oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum = 0xffff;
-
-- MTD_WRITEOOB(nftl->mtd, (nftl->EraseSize * targetEUN) + 8,
-+ MTD_WRITEOOB(nftl->mbd.mtd, (nftl->EraseSize * targetEUN) + 8,
- 8, &retlen, (char *)&oob.u);
-
- /* OK. We've moved the whole lot into the new block. Now we have to free the original blocks. */
-@@ -582,7 +488,7 @@
-
- lastEUN = writeEUN;
-
-- MTD_READOOB(nftl->mtd, (writeEUN * nftl->EraseSize) + blockofs,
-+ MTD_READOOB(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs,
- 8, &retlen, (char *)&bci);
-
- DEBUG(MTD_DEBUG_LEVEL2, "Status of block %d in EUN %d is %x\n",
-@@ -670,12 +576,12 @@
- nftl->ReplUnitTable[writeEUN] = BLOCK_NIL;
-
- /* ... and on the flash itself */
-- MTD_READOOB(nftl->mtd, writeEUN * nftl->EraseSize + 8, 8,
-+ MTD_READOOB(nftl->mbd.mtd, writeEUN * nftl->EraseSize + 8, 8,
- &retlen, (char *)&oob.u);
-
- oob.u.a.VirtUnitNum = oob.u.a.SpareVirtUnitNum = cpu_to_le16(thisVUC);
-
-- MTD_WRITEOOB(nftl->mtd, writeEUN * nftl->EraseSize + 8, 8,
-+ MTD_WRITEOOB(nftl->mbd.mtd, writeEUN * nftl->EraseSize + 8, 8,
- &retlen, (char *)&oob.u);
-
- /* we link the new block to the chain only after the
-@@ -685,13 +591,13 @@
- /* Both in our cache... */
- nftl->ReplUnitTable[lastEUN] = writeEUN;
- /* ... and on the flash itself */
-- MTD_READOOB(nftl->mtd, (lastEUN * nftl->EraseSize) + 8,
-+ MTD_READOOB(nftl->mbd.mtd, (lastEUN * nftl->EraseSize) + 8,
- 8, &retlen, (char *)&oob.u);
-
- oob.u.a.ReplUnitNum = oob.u.a.SpareReplUnitNum
- = cpu_to_le16(writeEUN);
-
-- MTD_WRITEOOB(nftl->mtd, (lastEUN * nftl->EraseSize) + 8,
-+ MTD_WRITEOOB(nftl->mbd.mtd, (lastEUN * nftl->EraseSize) + 8,
- 8, &retlen, (char *)&oob.u);
- }
-
-@@ -704,8 +610,10 @@
- return 0xffff;
- }
-
--static int NFTL_writeblock(struct NFTLrecord *nftl, unsigned block, char *buffer)
-+static int nftl_writeblock(struct mtd_blktrans_dev *mbd, unsigned long block,
-+ char *buffer)
- {
-+ struct NFTLrecord *nftl = (void *)mbd;
- u16 writeEUN;
- unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1);
- size_t retlen;
-@@ -720,7 +628,7 @@
- return 1;
- }
-
-- MTD_WRITEECC(nftl->mtd, (writeEUN * nftl->EraseSize) + blockofs,
-+ MTD_WRITEECC(nftl->mbd.mtd, (writeEUN * nftl->EraseSize) + blockofs,
- 512, &retlen, (char *)buffer, (char *)eccbuf, NAND_ECC_DISKONCHIP);
- /* no need to write SECTOR_USED flags since they are written in mtd_writeecc */
-
-@@ -728,8 +636,10 @@
- }
- #endif /* CONFIG_NFTL_RW */
-
--static int NFTL_readblock(struct NFTLrecord *nftl, unsigned block, char *buffer)
-+static int nftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
-+ char *buffer)
- {
-+ struct NFTLrecord *nftl = (void *)mbd;
- u16 lastgoodEUN;
- u16 thisEUN = nftl->EUNtable[block / (nftl->EraseSize / 512)];
- unsigned long blockofs = (block * 512) & (nftl->EraseSize - 1);
-@@ -742,7 +652,7 @@
-
- if (thisEUN != BLOCK_NIL) {
- while (thisEUN < nftl->nb_blocks) {
-- if (MTD_READOOB(nftl->mtd, (thisEUN * nftl->EraseSize) + blockofs,
-+ if (MTD_READOOB(nftl->mbd.mtd, (thisEUN * nftl->EraseSize) + blockofs,
- 8, &retlen, (char *)&bci) < 0)
- status = SECTOR_IGNORE;
- else
-@@ -761,13 +671,13 @@
- case SECTOR_IGNORE:
- break;
- default:
-- printk("Unknown status for block %d in EUN %d: %x\n",
-+ printk("Unknown status for block %ld in EUN %d: %x\n",
- block, thisEUN, status);
- break;
- }
-
- if (!silly--) {
-- printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%x\n",
-+ printk(KERN_WARNING "Infinite loop in Virtual Unit Chain 0x%lx\n",
- block / (nftl->EraseSize / 512));
- return 1;
- }
-@@ -783,264 +693,22 @@
- loff_t ptr = (lastgoodEUN * nftl->EraseSize) + blockofs;
- size_t retlen;
- u_char eccbuf[6];
-- if (MTD_READECC(nftl->mtd, ptr, 512, &retlen, buffer, eccbuf, NAND_ECC_DISKONCHIP))
-+ if (MTD_READECC(nftl->mbd.mtd, ptr, 512, &retlen, buffer, eccbuf, NAND_ECC_DISKONCHIP))
- return -EIO;
- }
- return 0;
- }
-
--static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
--{
-- struct NFTLrecord *nftl;
-- int p;
--
-- nftl = NFTLs[MINOR(inode->i_rdev) >> NFTL_PARTN_BITS];
--
-- if (!nftl) return -EINVAL;
--
-- switch (cmd) {
-- case HDIO_GETGEO: {
-- struct hd_geometry g;
--
-- g.heads = nftl->heads;
-- g.sectors = nftl->sectors;
-- g.cylinders = nftl->cylinders;
-- g.start = part_table[MINOR(inode->i_rdev)].start_sect;
-- return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0;
-- }
-- case BLKGETSIZE: /* Return device size */
-- return put_user(part_table[MINOR(inode->i_rdev)].nr_sects,
-- (unsigned long *) arg);
--
--#ifdef BLKGETSIZE64
-- case BLKGETSIZE64:
-- return put_user((u64)part_table[MINOR(inode->i_rdev)].nr_sects << 9,
-- (u64 *)arg);
--#endif
--
-- case BLKFLSBUF:
-- if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-- fsync_dev(inode->i_rdev);
-- invalidate_buffers(inode->i_rdev);
-- if (nftl->mtd->sync)
-- nftl->mtd->sync(nftl->mtd);
-- return 0;
--
-- case BLKRRPART:
-- if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-- if (nftl->usecount > 1) return -EBUSY;
-- /*
-- * We have to flush all buffers and invalidate caches,
-- * or we won't be able to re-use the partitions,
-- * if there was a change and we don't want to reboot
-- */
-- p = (1<<NFTL_PARTN_BITS) - 1;
-- while (p-- > 0) {
-- kdev_t devp = MKDEV(MAJOR(inode->i_dev), MINOR(inode->i_dev)+p);
-- if (part_table[p].nr_sects > 0)
-- invalidate_device (devp, 1);
--
-- part_table[MINOR(inode->i_dev)+p].start_sect = 0;
-- part_table[MINOR(inode->i_dev)+p].nr_sects = 0;
-- }
--
--#if LINUX_VERSION_CODE < 0x20328
-- resetup_one_dev(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS);
--#else
-- grok_partitions(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS,
-- 1<<NFTL_PARTN_BITS, nftl->nr_sects);
--#endif
-- return 0;
--
--#if (LINUX_VERSION_CODE < 0x20303)
-- RO_IOCTLS(inode->i_rdev, arg); /* ref. linux/blk.h */
--#else
-- case BLKROSET:
-- case BLKROGET:
-- case BLKSSZGET:
-- return blk_ioctl(inode->i_rdev, cmd, arg);
--#endif
--
-- default:
-- return -EINVAL;
-- }
--}
--
--void nftl_request(RQFUNC_ARG)
--{
-- unsigned int dev, block, nsect;
-- struct NFTLrecord *nftl;
-- char *buffer;
-- struct request *req;
-- int res;
--
-- while (1) {
-- INIT_REQUEST; /* blk.h */
-- req = CURRENT;
--
-- /* We can do this because the generic code knows not to
-- touch the request at the head of the queue */
-- spin_unlock_irq(&io_request_lock);
--
-- DEBUG(MTD_DEBUG_LEVEL2, "NFTL_request\n");
-- DEBUG(MTD_DEBUG_LEVEL3, "NFTL %s request, from sector 0x%04lx for 0x%04lx sectors\n",
-- (req->cmd == READ) ? "Read " : "Write",
-- req->sector, req->current_nr_sectors);
--
-- dev = MINOR(req->rq_dev);
-- block = req->sector;
-- nsect = req->current_nr_sectors;
-- buffer = req->buffer;
-- res = 1; /* succeed */
--
-- if (dev >= MAX_NFTLS * (1<<NFTL_PARTN_BITS)) {
-- /* there is no such partition */
-- printk("nftl: bad minor number: device = %s\n",
-- kdevname(req->rq_dev));
-- res = 0; /* fail */
-- goto repeat;
-- }
--
-- nftl = NFTLs[dev / (1<<NFTL_PARTN_BITS)];
-- DEBUG(MTD_DEBUG_LEVEL3, "Waiting for mutex\n");
-- down(&nftl->mutex);
-- DEBUG(MTD_DEBUG_LEVEL3, "Got mutex\n");
--
-- if (block + nsect > part_table[dev].nr_sects) {
-- /* access past the end of device */
-- printk("nftl%c%d: bad access: block = %d, count = %d\n",
-- (MINOR(req->rq_dev)>>6)+'a', dev & 0xf, block, nsect);
-- up(&nftl->mutex);
-- res = 0; /* fail */
-- goto repeat;
-- }
--
-- block += part_table[dev].start_sect;
--
-- if (req->cmd == READ) {
-- DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request of 0x%x sectors @ %x "
-- "(req->nr_sectors == %lx)\n", nsect, block, req->nr_sectors);
--
-- for ( ; nsect > 0; nsect-- , block++, buffer += 512) {
-- /* Read a single sector to req->buffer + (512 * i) */
-- if (NFTL_readblock(nftl, block, buffer)) {
-- DEBUG(MTD_DEBUG_LEVEL2, "NFTL read request failed\n");
-- up(&nftl->mutex);
-- res = 0;
-- goto repeat;
-- }
-- }
--
-- DEBUG(MTD_DEBUG_LEVEL2,"NFTL read request completed OK\n");
-- up(&nftl->mutex);
-- goto repeat;
-- } else if (req->cmd == WRITE) {
-- DEBUG(MTD_DEBUG_LEVEL2, "NFTL write request of 0x%x sectors @ %x "
-- "(req->nr_sectors == %lx)\n", nsect, block,
-- req->nr_sectors);
--#ifdef CONFIG_NFTL_RW
-- for ( ; nsect > 0; nsect-- , block++, buffer += 512) {
-- /* Read a single sector to req->buffer + (512 * i) */
-- if (NFTL_writeblock(nftl, block, buffer)) {
-- DEBUG(MTD_DEBUG_LEVEL1,"NFTL write request failed\n");
-- up(&nftl->mutex);
-- res = 0;
-- goto repeat;
-- }
-- }
-- DEBUG(MTD_DEBUG_LEVEL2,"NFTL write request completed OK\n");
--#else
-- res = 0; /* Writes always fail */
--#endif /* CONFIG_NFTL_RW */
-- up(&nftl->mutex);
-- goto repeat;
-- } else {
-- DEBUG(MTD_DEBUG_LEVEL0, "NFTL unknown request\n");
-- up(&nftl->mutex);
-- res = 0;
-- goto repeat;
-- }
-- repeat:
-- DEBUG(MTD_DEBUG_LEVEL3, "end_request(%d)\n", res);
-- spin_lock_irq(&io_request_lock);
-- end_request(res);
-- }
--}
--
--static int nftl_open(struct inode *ip, struct file *fp)
--{
-- int nftlnum = MINOR(ip->i_rdev) >> NFTL_PARTN_BITS;
-- struct NFTLrecord *thisNFTL;
-- thisNFTL = NFTLs[nftlnum];
--
-- DEBUG(MTD_DEBUG_LEVEL2,"NFTL_open\n");
--
--#ifdef CONFIG_KMOD
-- if (!thisNFTL && nftlnum == 0) {
-- request_module("docprobe");
-- thisNFTL = NFTLs[nftlnum];
-- }
--#endif
-- if (!thisNFTL) {
-- DEBUG(MTD_DEBUG_LEVEL2,"ENODEV: thisNFTL = %d, minor = %d, ip = %p, fp = %p\n",
-- nftlnum, ip->i_rdev, ip, fp);
-- return -ENODEV;
-- }
--
--#ifndef CONFIG_NFTL_RW
-- if (fp->f_mode & FMODE_WRITE)
-- return -EROFS;
--#endif /* !CONFIG_NFTL_RW */
--
-- thisNFTL->usecount++;
-- BLK_INC_USE_COUNT;
-- if (!get_mtd_device(thisNFTL->mtd, -1)) {
-- BLK_DEC_USE_COUNT;
-- return -ENXIO;
-- }
--
-- return 0;
--}
--
--static int nftl_release(struct inode *inode, struct file *fp)
-+static int nftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
- {
-- struct NFTLrecord *thisNFTL;
--
-- thisNFTL = NFTLs[MINOR(inode->i_rdev) / 16];
--
-- DEBUG(MTD_DEBUG_LEVEL2, "NFTL_release\n");
--
-- if (thisNFTL->mtd->sync)
-- thisNFTL->mtd->sync(thisNFTL->mtd);
-- thisNFTL->usecount--;
-- BLK_DEC_USE_COUNT;
-+ struct NFTLrecord *nftl = (void *)dev;
-
-- put_mtd_device(thisNFTL->mtd);
-+ geo->heads = nftl->heads;
-+ geo->sectors = nftl->sectors;
-+ geo->cylinders = nftl->cylinders;
-
- return 0;
- }
--#if LINUX_VERSION_CODE < 0x20326
--static struct file_operations nftl_fops = {
-- read: block_read,
-- write: block_write,
-- ioctl: nftl_ioctl,
-- open: nftl_open,
-- release: nftl_release,
-- fsync: block_fsync,
--};
--#else
--static struct block_device_operations nftl_fops =
--{
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14)
-- owner: THIS_MODULE,
--#endif
-- open: nftl_open,
-- release: nftl_release,
-- ioctl: nftl_ioctl
--};
--#endif
--
--
-
- /****************************************************************************
- *
-@@ -1048,49 +716,33 @@
- *
- ****************************************************************************/
-
--static struct mtd_notifier nftl_notifier = {
-- add: NFTL_notify_add,
-- remove: NFTL_notify_remove
-+
-+struct mtd_blktrans_ops nftl_tr = {
-+ .name = "nftl",
-+ .major = NFTL_MAJOR,
-+ .part_bits = NFTL_PARTN_BITS,
-+ .getgeo = nftl_getgeo,
-+ .readsect = nftl_readblock,
-+#ifdef CONFIG_NFTL_RW
-+ .writesect = nftl_writeblock,
-+#endif
-+ .add_mtd = nftl_add_mtd,
-+ .remove_dev = nftl_remove_dev,
-+ .owner = THIS_MODULE,
- };
-
- extern char nftlmountrev[];
-
- int __init init_nftl(void)
- {
-- int i;
--
--#ifdef PRERELEASE
-- printk(KERN_INFO "NFTL driver: nftlcore.c $Revision$, nftlmount.c %s\n", nftlmountrev);
--#endif
--
-- if (register_blkdev(MAJOR_NR, "nftl", &nftl_fops)){
-- printk("unable to register NFTL block device on major %d\n", MAJOR_NR);
-- return -EBUSY;
-- } else {
-- blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), &nftl_request);
-+ printk(KERN_INFO "NFTL driver: nftlcore.c $Revision$, nftlmount.c %s\n", nftlmountrev);
-
-- /* set block size to 1kB each */
-- for (i = 0; i < 256; i++) {
-- nftl_blocksizes[i] = 1024;
-- }
-- blksize_size[MAJOR_NR] = nftl_blocksizes;
--
-- add_gendisk(&nftl_gendisk);
-- }
--
-- register_mtd_user(&nftl_notifier);
--
-- return 0;
-+ return register_mtd_blktrans(&nftl_tr);
- }
-
- static void __exit cleanup_nftl(void)
- {
-- unregister_mtd_user(&nftl_notifier);
-- unregister_blkdev(MAJOR_NR, "nftl");
--
-- blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
--
-- del_gendisk(&nftl_gendisk);
-+ deregister_mtd_blktrans(&nftl_tr);
- }
-
- module_init(init_nftl);
-diff -Nurb linux-mips-2.4.27/drivers/mtd/nftlmount.c linux/drivers/mtd/nftlmount.c
---- linux-mips-2.4.27/drivers/mtd/nftlmount.c 2003-07-05 05:23:38.000000000 +0200
-+++ linux/drivers/mtd/nftlmount.c 2004-11-19 10:25:11.655236880 +0100
-@@ -4,7 +4,7 @@
- * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
- * Copyright (C) 2000 Netgem S.A.
- *
-- * $Id$
-+ * $Id$
- *
- * 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
-@@ -21,26 +21,17 @@
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
--#define __NO_VERSION__
- #include <linux/kernel.h>
--#include <linux/module.h>
- #include <asm/errno.h>
--#include <asm/io.h>
--#include <asm/uaccess.h>
--#include <linux/miscdevice.h>
--#include <linux/pci.h>
- #include <linux/delay.h>
- #include <linux/slab.h>
--#include <linux/sched.h>
--#include <linux/init.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/nand.h>
- #include <linux/mtd/nftl.h>
--#include <linux/mtd/compatmac.h>
-
- #define SECTORSIZE 512
-
--char nftlmountrev[]="$Revision$";
-+char nftlmountrev[]="$Revision$";
-
- /* find_boot_record: Find the NFTL Media Header and its Spare copy which contains the
- * various device information of the NFTL partition and Bad Unit Table. Update
-@@ -59,8 +50,8 @@
-
- /* Assume logical EraseSize == physical erasesize for starting the scan.
- We'll sort it out later if we find a MediaHeader which says otherwise */
-- nftl->EraseSize = nftl->mtd->erasesize;
-- nftl->nb_blocks = nftl->mtd->size / nftl->EraseSize;
-+ nftl->EraseSize = nftl->mbd.mtd->erasesize;
-+ nftl->nb_blocks = nftl->mbd.mtd->size / nftl->EraseSize;
-
- nftl->MediaUnit = BLOCK_NIL;
- nftl->SpareMediaUnit = BLOCK_NIL;
-@@ -71,12 +62,12 @@
-
- /* Check for ANAND header first. Then can whinge if it's found but later
- checks fail */
-- if ((ret = MTD_READ(nftl->mtd, block * nftl->EraseSize, SECTORSIZE, &retlen, buf))) {
-+ if ((ret = MTD_READ(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE, &retlen, buf))) {
- static int warncount = 5;
-
- if (warncount) {
- printk(KERN_WARNING "Block read at 0x%x of mtd%d failed: %d\n",
-- block * nftl->EraseSize, nftl->mtd->index, ret);
-+ block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
- if (!--warncount)
- printk(KERN_WARNING "Further failures for this block will not be printed\n");
- }
-@@ -87,16 +78,16 @@
- /* ANAND\0 not found. Continue */
- #if 0
- printk(KERN_DEBUG "ANAND header not found at 0x%x in mtd%d\n",
-- block * nftl->EraseSize, nftl->mtd->index);
-+ block * nftl->EraseSize, nftl->mbd.mtd->index);
- #endif
- continue;
- }
-
- /* To be safer with BIOS, also use erase mark as discriminant */
-- if ((ret = MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8,
-- 8, &retlen, (char *)&h1)) < 0) {
-+ if ((ret = MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8,
-+ 8, &retlen, (char *)&h1) < 0)) {
- printk(KERN_WARNING "ANAND header found at 0x%x in mtd%d, but OOB data read failed (err %d)\n",
-- block * nftl->EraseSize, nftl->mtd->index, ret);
-+ block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
- continue;
- }
-
-@@ -106,23 +97,23 @@
- */
- if (le16_to_cpu(h1.EraseMark | h1.EraseMark1) != ERASE_MARK) {
- printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but erase mark not present (0x%04x,0x%04x instead)\n",
-- block * nftl->EraseSize, nftl->mtd->index,
-+ block * nftl->EraseSize, nftl->mbd.mtd->index,
- le16_to_cpu(h1.EraseMark), le16_to_cpu(h1.EraseMark1));
- continue;
- }
-
- /* Finally reread to check ECC */
-- if ((ret = MTD_READECC(nftl->mtd, block * nftl->EraseSize, SECTORSIZE,
-- &retlen, buf, (char *)&oob, NAND_ECC_DISKONCHIP)) < 0) {
-+ if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize, SECTORSIZE,
-+ &retlen, buf, (char *)&oob, NAND_ECC_DISKONCHIP) < 0)) {
- printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but ECC read failed (err %d)\n",
-- block * nftl->EraseSize, nftl->mtd->index, ret);
-+ block * nftl->EraseSize, nftl->mbd.mtd->index, ret);
- continue;
- }
-
- /* Paranoia. Check the ANAND header is still there after the ECC read */
- if (memcmp(buf, "ANAND", 6)) {
- printk(KERN_NOTICE "ANAND header found at 0x%x in mtd%d, but went away on reread!\n",
-- block * nftl->EraseSize, nftl->mtd->index);
-+ block * nftl->EraseSize, nftl->mbd.mtd->index);
- printk(KERN_NOTICE "New data are: %02x %02x %02x %02x %02x %02x\n",
- buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
- continue;
-@@ -137,8 +128,12 @@
- printk(KERN_NOTICE "NFTL Media Headers at 0x%x and 0x%x disagree.\n",
- nftl->MediaUnit * nftl->EraseSize, block * nftl->EraseSize);
- /* if (debug) Print both side by side */
-+ if (boot_record_count < 2) {
-+ /* We haven't yet seen two real ones */
- return -1;
- }
-+ continue;
-+ }
- if (boot_record_count == 1)
- nftl->SpareMediaUnit = block;
-
-@@ -163,8 +158,8 @@
- } else if (mh->UnitSizeFactor != 0xff) {
- printk(KERN_NOTICE "WARNING: Support for NFTL with UnitSizeFactor 0x%02x is experimental\n",
- mh->UnitSizeFactor);
-- nftl->EraseSize = nftl->mtd->erasesize << (0xff - mh->UnitSizeFactor);
-- nftl->nb_blocks = nftl->mtd->size / nftl->EraseSize;
-+ nftl->EraseSize = nftl->mbd.mtd->erasesize << (0xff - mh->UnitSizeFactor);
-+ nftl->nb_blocks = nftl->mbd.mtd->size / nftl->EraseSize;
- }
- nftl->nb_boot_blocks = le16_to_cpu(mh->FirstPhysicalEUN);
- if ((nftl->nb_boot_blocks + 2) >= nftl->nb_blocks) {
-@@ -182,7 +177,7 @@
- return -1;
- }
-
-- nftl->nr_sects = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
-+ nftl->mbd.size = nftl->numvunits * (nftl->EraseSize / SECTORSIZE);
-
- /* If we're not using the last sectors in the device for some reason,
- reduce nb_blocks accordingly so we forget they're there */
-@@ -220,7 +215,7 @@
- for (i = 0; i < nftl->nb_blocks; i++) {
- if ((i & (SECTORSIZE - 1)) == 0) {
- /* read one sector for every SECTORSIZE of blocks */
-- if ((ret = MTD_READECC(nftl->mtd, block * nftl->EraseSize +
-+ if ((ret = MTD_READECC(nftl->mbd.mtd, block * nftl->EraseSize +
- i + SECTORSIZE, SECTORSIZE, &retlen, buf,
- (char *)&oob, NAND_ECC_DISKONCHIP)) < 0) {
- printk(KERN_NOTICE "Read of bad sector table failed (err %d)\n",
-@@ -263,16 +258,16 @@
- for (i = 0; i < len; i += SECTORSIZE) {
- /* we want to read the sector without ECC check here since a free
- sector does not have ECC syndrome on it yet */
-- if (MTD_READ(nftl->mtd, address, SECTORSIZE, &retlen, buf) < 0)
-+ if (MTD_READ(nftl->mbd.mtd, address, SECTORSIZE, &retlen, buf) < 0)
- return -1;
- if (memcmpb(buf, 0xff, SECTORSIZE) != 0)
- return -1;
-
- if (check_oob) {
-- if (MTD_READOOB(nftl->mtd, address, nftl->mtd->oobsize,
-+ if (MTD_READOOB(nftl->mbd.mtd, address, nftl->mbd.mtd->oobsize,
- &retlen, buf) < 0)
- return -1;
-- if (memcmpb(buf, 0xff, nftl->mtd->oobsize) != 0)
-+ if (memcmpb(buf, 0xff, nftl->mbd.mtd->oobsize) != 0)
- return -1;
- }
- address += SECTORSIZE;
-@@ -297,7 +292,7 @@
- struct erase_info *instr = &nftl->instr;
-
- /* Read the Unit Control Information #1 for Wear-Leveling */
-- if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8,
-+ if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8,
- 8, &retlen, (char *)&uci) < 0)
- goto default_uci1;
-
-@@ -314,7 +309,7 @@
- /* XXX: use async erase interface, XXX: test return code */
- instr->addr = block * nftl->EraseSize;
- instr->len = nftl->EraseSize;
-- MTD_ERASE(nftl->mtd, instr);
-+ MTD_ERASE(nftl->mbd.mtd, instr);
-
- if (instr->state == MTD_ERASE_FAILED) {
- /* could not format, FixMe: We should update the BadUnitTable
-@@ -337,7 +332,7 @@
- return -1;
-
- uci.WearInfo = le32_to_cpu(nb_erases);
-- if (MTD_WRITEOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
-+ if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
- &retlen, (char *)&uci) < 0)
- return -1;
- return 0;
-@@ -363,7 +358,7 @@
- block = first_block;
- for (;;) {
- for (i = 0; i < sectors_per_block; i++) {
-- if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + i * SECTORSIZE,
-+ if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i * SECTORSIZE,
- 8, &retlen, (char *)&bci) < 0)
- status = SECTOR_IGNORE;
- else
-@@ -383,7 +378,7 @@
- /* sector not free actually : mark it as SECTOR_IGNORE */
- bci.Status = SECTOR_IGNORE;
- bci.Status1 = SECTOR_IGNORE;
-- MTD_WRITEOOB(nftl->mtd,
-+ MTD_WRITEOOB(nftl->mbd.mtd,
- block * nftl->EraseSize + i * SECTORSIZE,
- 8, &retlen, (char *)&bci);
- }
-@@ -476,7 +471,7 @@
- size_t retlen;
-
- /* check erase mark. */
-- if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
-+ if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
- &retlen, (char *)&h1) < 0)
- return -1;
-
-@@ -491,7 +486,7 @@
- h1.EraseMark = cpu_to_le16(ERASE_MARK);
- h1.EraseMark1 = cpu_to_le16(ERASE_MARK);
- h1.WearInfo = cpu_to_le32(0);
-- if (MTD_WRITEOOB(nftl->mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
-+ if (MTD_WRITEOOB(nftl->mbd.mtd, block * nftl->EraseSize + SECTORSIZE + 8, 8,
- &retlen, (char *)&h1) < 0)
- return -1;
- } else {
-@@ -503,7 +498,7 @@
- SECTORSIZE, 0) != 0)
- return -1;
-
-- if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + i,
-+ if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + i,
- 16, &retlen, buf) < 0)
- return -1;
- if (i == SECTORSIZE) {
-@@ -533,7 +528,7 @@
- struct nftl_uci2 uci;
- size_t retlen;
-
-- if (MTD_READOOB(nftl->mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8,
-+ if (MTD_READOOB(nftl->mbd.mtd, block * nftl->EraseSize + 2 * SECTORSIZE + 8,
- 8, &retlen, (char *)&uci) < 0)
- return 0;
-
-@@ -572,9 +567,9 @@
-
- for (;;) {
- /* read the block header. If error, we format the chain */
-- if (MTD_READOOB(s->mtd, block * s->EraseSize + 8, 8,
-+ if (MTD_READOOB(s->mbd.mtd, block * s->EraseSize + 8, 8,
- &retlen, (char *)&h0) < 0 ||
-- MTD_READOOB(s->mtd, block * s->EraseSize + SECTORSIZE + 8, 8,
-+ MTD_READOOB(s->mbd.mtd, block * s->EraseSize + SECTORSIZE + 8, 8,
- &retlen, (char *)&h1) < 0) {
- s->ReplUnitTable[block] = BLOCK_NIL;
- do_format_chain = 1;
-diff -Nurb linux-mips-2.4.27/drivers/mtd/redboot.c linux/drivers/mtd/redboot.c
---- linux-mips-2.4.27/drivers/mtd/redboot.c 2001-12-02 12:34:42.000000000 +0100
-+++ linux/drivers/mtd/redboot.c 2004-11-19 10:25:11.656236728 +0100
-@@ -1,5 +1,5 @@
- /*
-- * $Id$
-+ * $Id$
- *
- * Parse RedBoot-style Flash Image System (FIS) tables and
- * produce a Linux partition array to match.
-@@ -7,6 +7,7 @@
-
- #include <linux/kernel.h>
- #include <linux/slab.h>
-+#include <linux/init.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/partitions.h>
-@@ -34,7 +35,9 @@
- return 1;
- }
-
--int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts)
-+static int parse_redboot_partitions(struct mtd_info *master,
-+ struct mtd_partition **pparts,
-+ unsigned long fis_origin)
- {
- int nrparts = 0;
- struct fis_image_desc *buf;
-@@ -43,7 +46,9 @@
- int ret, i;
- size_t retlen;
- char *names;
-+ char *nullname;
- int namelen = 0;
-+ static char nullstring[] = "unallocated";
-
- buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-
-@@ -90,7 +95,11 @@
- goto out;
- }
- new_fl->img = &buf[i];
-+ if (fis_origin) {
-+ buf[i].flash_base -= fis_origin;
-+ } else {
- buf[i].flash_base &= master->size-1;
-+ }
-
- /* I'm sure the JFFS2 code has done me permanent damage.
- * I now think the following is _normal_
-@@ -110,18 +119,24 @@
- if (tmp_fl->img->flash_base + tmp_fl->img->size + master->erasesize < tmp_fl->next->img->flash_base)
- nrparts++;
- }
-- parts = kmalloc(sizeof(*parts)*nrparts + namelen, GFP_KERNEL);
-+ parts = kmalloc(sizeof(*parts)*nrparts + sizeof(nullstring) + namelen, GFP_KERNEL);
-
- if (!parts) {
- ret = -ENOMEM;
- goto out;
- }
-- names = (char *)&parts[nrparts];
-+
- memset(parts, 0, sizeof(*parts)*nrparts + namelen);
-+
-+ /* FIXME: Include nullname only if it's used */
-+ nullname = (char *)&parts[nrparts];
-+ sprintf(nullname, nullstring);
-+ names = nullname + sizeof(nullstring);
-+
- i=0;
-
- if (fl->img->flash_base) {
-- parts[0].name = "unallocated space";
-+ parts[0].name = nullname;
- parts[0].size = fl->img->flash_base;
- parts[0].offset = 0;
- }
-@@ -133,11 +148,11 @@
- strcpy(names, fl->img->name);
- names += strlen(names)+1;
-
-- if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize < fl->next->img->flash_base) {
-+ if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) {
- i++;
- parts[i].offset = parts[i-1].size + parts[i-1].offset;
- parts[i].size = fl->next->img->flash_base - parts[i].offset;
-- parts[i].name = "unallocated space";
-+ parts[i].name = nullname;
- }
- tmp_fl = fl;
- fl = fl->next;
-@@ -155,7 +170,24 @@
- return ret;
- }
-
--EXPORT_SYMBOL(parse_redboot_partitions);
-+static struct mtd_part_parser redboot_parser = {
-+ .owner = THIS_MODULE,
-+ .parse_fn = parse_redboot_partitions,
-+ .name = "RedBoot",
-+};
-+
-+static int __init redboot_parser_init(void)
-+{
-+ return register_mtd_parser(&redboot_parser);
-+}
-+
-+static void __exit redboot_parser_exit(void)
-+{
-+ deregister_mtd_parser(&redboot_parser);
-+}
-+
-+module_init(redboot_parser_init);
-+module_exit(redboot_parser_exit);
-
- MODULE_LICENSE("GPL");
- MODULE_AUTHOR("Red Hat, Inc. - David Woodhouse <dwmw2@cambridge.redhat.com>");
-diff -Nurb linux-mips-2.4.27/fs/Config.in linux/fs/Config.in
---- linux-mips-2.4.27/fs/Config.in 2004-02-20 02:22:19.000000000 +0100
-+++ linux/fs/Config.in 2004-11-19 10:25:12.229149632 +0100
-@@ -49,6 +49,7 @@
- dep_tristate 'Journalling Flash File System v2 (JFFS2) support' CONFIG_JFFS2_FS $CONFIG_MTD
- if [ "$CONFIG_JFFS2_FS" = "y" -o "$CONFIG_JFFS2_FS" = "m" ] ; then
- int 'JFFS2 debugging verbosity (0 = quiet, 2 = noisy)' CONFIG_JFFS2_FS_DEBUG 0
-+ bool 'JFFS2 support for NAND chips' CONFIG_JFFS2_FS_NAND
- fi
- tristate 'Compressed ROM file system support' CONFIG_CRAMFS
- bool 'Virtual memory file system support (former shm fs)' CONFIG_TMPFS
-diff -Nurb linux-mips-2.4.27/fs/jffs2/Makefile linux/fs/jffs2/Makefile
---- linux-mips-2.4.27/fs/jffs2/Makefile 2003-08-13 19:19:25.000000000 +0200
-+++ linux/fs/jffs2/Makefile 2004-11-19 10:25:12.071173648 +0100
-@@ -1,7 +1,7 @@
- #
- # Makefile for the linux Journalling Flash FileSystem (JFFS) routines.
- #
--# $Id$
-+# $Id$
- #
- # Note! Dependencies are done automagically by 'make dep', which also
- # removes any old dependencies. DON'T put your own dependencies here
-@@ -10,16 +10,31 @@
- # Note 2! The CFLAGS definitions are now in the main makefile...
-
-
--COMPR_OBJS := compr.o compr_rubin.o compr_rtime.o pushpull.o \
-- compr_zlib.o
-+obj-$(CONFIG_JFFS2_FS) := jffs2.o
-+
-+COMPR_OBJS := compr.o compr_rubin.o compr_rtime.o compr_zlib.o
- JFFS2_OBJS := dir.o file.o ioctl.o nodelist.o malloc.o \
-- read.o nodemgmt.o readinode.o super.o write.o scan.o gc.o \
-- symlink.o build.o erase.o background.o
-+ read.o nodemgmt.o readinode.o write.o scan.o gc.o \
-+ symlink.o build.o erase.o background.o fs.o writev.o
-
--O_TARGET := jffs2.o
-+BELOW25 := $(shell echo $(PATCHLEVEL) | sed s/[1234]/y/)
-+
-+ifeq ($(BELOW25),y)
-+LINUX_OBJS := super-v24.o crc32.o rbtree.o
-+else
-+LINUX_OBJS := super.o
-+endif
-
--obj-y := $(COMPR_OBJS) $(JFFS2_OBJS)
--obj-m := $(O_TARGET)
-+NAND_OBJS-$(CONFIG_JFFS2_FS_NAND) := wbuf.o
-
-+jffs2-objs := $(COMPR_OBJS) $(JFFS2_OBJS) $(VERS_OBJS) $(NAND_OBJS-y) \
-+ $(LINUX_OBJS)
-+
-+
-+# 2.4 build compatibility
-+ifeq ($(BELOW25),y)
-+obj-y := $(jffs2-objs)
-+O_TARGET := jffs2.o
- include $(TOPDIR)/Rules.make
-+endif
-
-diff -Nurb linux-mips-2.4.27/fs/jffs2/background.c linux/fs/jffs2/background.c
---- linux-mips-2.4.27/fs/jffs2/background.c 2001-11-06 08:56:10.000000000 +0100
-+++ linux/fs/jffs2/background.c 2004-11-19 10:25:12.072173496 +0100
-@@ -1,61 +1,36 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #define __KERNEL_SYSCALLS__
-
- #include <linux/kernel.h>
--#include <linux/sched.h>
--#include <linux/unistd.h>
- #include <linux/jffs2.h>
- #include <linux/mtd/mtd.h>
--#include <linux/interrupt.h>
- #include <linux/completion.h>
-+#include <linux/sched.h>
-+#include <linux/unistd.h>
-+#include <linux/suspend.h>
- #include "nodelist.h"
-
-
- static int jffs2_garbage_collect_thread(void *);
--static int thread_should_wake(struct jffs2_sb_info *c);
-
- void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c)
- {
-- spin_lock_bh(&c->erase_completion_lock);
-- if (c->gc_task && thread_should_wake(c))
-+ spin_lock(&c->erase_completion_lock);
-+ if (c->gc_task && jffs2_thread_should_wake(c))
- send_sig(SIGHUP, c->gc_task, 1);
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
- }
-
- /* This must only ever be called when no GC thread is currently running */
-@@ -86,12 +61,12 @@
-
- void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c)
- {
-- spin_lock_bh(&c->erase_completion_lock);
-+ spin_lock(&c->erase_completion_lock);
- if (c->gc_task) {
- D1(printk(KERN_DEBUG "jffs2: Killing GC task %d\n", c->gc_task->pid));
- send_sig(SIGKILL, c->gc_task, 1);
- }
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
- wait_for_completion(&c->gc_thread_exit);
- }
-
-@@ -99,34 +74,37 @@
- {
- struct jffs2_sb_info *c = _c;
-
-- daemonize();
-- current->tty = NULL;
-+ daemonize("jffs2_gcd_mtd%d", c->mtd->index);
-+ allow_signal(SIGKILL);
-+ allow_signal(SIGSTOP);
-+ allow_signal(SIGCONT);
-+
- c->gc_task = current;
- up(&c->gc_thread_start);
-
-- sprintf(current->comm, "jffs2_gcd_mtd%d", c->mtd->index);
--
-- /* FIXME in the 2.2 backport */
-- current->nice = 10;
-+ set_user_nice(current, 10);
-
- for (;;) {
-- spin_lock_irq(&current->sigmask_lock);
-- siginitsetinv (&current->blocked, sigmask(SIGHUP) | sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGCONT));
-- recalc_sigpending(current);
-- spin_unlock_irq(&current->sigmask_lock);
-+ allow_signal(SIGHUP);
-
-- if (!thread_should_wake(c)) {
-+ if (!jffs2_thread_should_wake(c)) {
- set_current_state (TASK_INTERRUPTIBLE);
- D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread sleeping...\n"));
-- /* Yes, there's a race here; we checked thread_should_wake() before
-- setting current->state to TASK_INTERRUPTIBLE. But it doesn't
-+ /* Yes, there's a race here; we checked jffs2_thread_should_wake()
-+ before setting current->state to TASK_INTERRUPTIBLE. But it doesn't
- matter - We don't care if we miss a wakeup, because the GC thread
- is only an optimisation anyway. */
- schedule();
- }
-
-- if (current->need_resched)
-- schedule();
-+ if (current->flags & PF_FREEZE) {
-+ refrigerator(0);
-+ /* refrigerator() should recalc sigpending for us
-+ but doesn't. No matter - allow_signal() will. */
-+ continue;
-+ }
-+
-+ cond_resched();
-
- /* Put_super will send a SIGKILL and then wait on the sem.
- */
-@@ -134,9 +112,7 @@
- siginfo_t info;
- unsigned long signr;
-
-- spin_lock_irq(&current->sigmask_lock);
-- signr = dequeue_signal(&current->blocked, &info);
-- spin_unlock_irq(&current->sigmask_lock);
-+ signr = dequeue_signal_lock(current, &current->blocked, &info);
-
- switch(signr) {
- case SIGSTOP:
-@@ -147,9 +123,10 @@
-
- case SIGKILL:
- D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread(): SIGKILL received.\n"));
-- spin_lock_bh(&c->erase_completion_lock);
-+ die:
-+ spin_lock(&c->erase_completion_lock);
- c->gc_task = NULL;
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
- complete_and_exit(&c->gc_thread_exit, 0);
-
- case SIGHUP:
-@@ -157,27 +134,15 @@
- break;
- default:
- D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread(): signal %ld received\n", signr));
--
- }
- }
- /* We don't want SIGHUP to interrupt us. STOP and KILL are OK though. */
-- spin_lock_irq(&current->sigmask_lock);
-- siginitsetinv (&current->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGCONT));
-- recalc_sigpending(current);
-- spin_unlock_irq(&current->sigmask_lock);
-+ disallow_signal(SIGHUP);
-
- D1(printk(KERN_DEBUG "jffs2_garbage_collect_thread(): pass\n"));
-- jffs2_garbage_collect_pass(c);
-+ if (jffs2_garbage_collect_pass(c) == -ENOSPC) {
-+ printk(KERN_NOTICE "No space for garbage collection. Aborting GC thread\n");
-+ goto die;
-+ }
- }
--}
--
--static int thread_should_wake(struct jffs2_sb_info *c)
--{
-- D1(printk(KERN_DEBUG "thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x\n",
-- c->nr_free_blocks, c->nr_erasing_blocks, c->dirty_size));
-- if (c->nr_free_blocks + c->nr_erasing_blocks < JFFS2_RESERVED_BLOCKS_GCTRIGGER &&
-- c->dirty_size > c->sector_size)
-- return 1;
-- else
-- return 0;
- }
-diff -Nurb linux-mips-2.4.27/fs/jffs2/build.c linux/fs/jffs2/build.c
---- linux-mips-2.4.27/fs/jffs2/build.c 2003-07-05 05:23:44.000000000 +0200
-+++ linux/fs/jffs2/build.c 2004-11-19 10:25:12.073173344 +0100
-@@ -1,47 +1,22 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/kernel.h>
--#include <linux/jffs2.h>
-+#include <linux/sched.h>
- #include <linux/slab.h>
- #include "nodelist.h"
-
--int jffs2_build_inode_pass1(struct jffs2_sb_info *, struct jffs2_inode_cache *);
--int jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *, struct jffs2_inode_cache *);
-+static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *, struct jffs2_inode_cache *, struct jffs2_full_dirent **);
-
- static inline struct jffs2_inode_cache *
- first_inode_chain(int *i, struct jffs2_sb_info *c)
-@@ -68,16 +43,52 @@
- ic; \
- ic = next_inode(&i, ic, (c)))
-
-+
-+static inline void jffs2_build_inode_pass1(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
-+{
-+ struct jffs2_full_dirent *fd;
-+
-+ D1(printk(KERN_DEBUG "jffs2_build_inode building directory inode #%u\n", ic->ino));
-+
-+ /* For each child, increase nlink */
-+ for(fd = ic->scan_dents; fd; fd = fd->next) {
-+ struct jffs2_inode_cache *child_ic;
-+ if (!fd->ino)
-+ continue;
-+
-+ /* XXX: Can get high latency here with huge directories */
-+
-+ child_ic = jffs2_get_ino_cache(c, fd->ino);
-+ if (!child_ic) {
-+ printk(KERN_NOTICE "Eep. Child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n",
-+ fd->name, fd->ino, ic->ino);
-+ continue;
-+ }
-+
-+ if (child_ic->nlink++ && fd->type == DT_DIR) {
-+ printk(KERN_NOTICE "Child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", fd->name, fd->ino, ic->ino);
-+ if (fd->ino == 1 && ic->ino == 1) {
-+ printk(KERN_NOTICE "This is mostly harmless, and probably caused by creating a JFFS2 image\n");
-+ printk(KERN_NOTICE "using a buggy version of mkfs.jffs2. Use at least v1.17.\n");
-+ }
-+ /* What do we do about it? */
-+ }
-+ D1(printk(KERN_DEBUG "Increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino));
-+ /* Can't free them. We might need them in pass 2 */
-+ }
-+}
-+
- /* Scan plan:
- - Scan physical nodes. Build map of inodes/dirents. Allocate inocaches as we go
- - Scan directory tree from top down, setting nlink in inocaches
- - Scan inocaches for inodes with nlink==0
- */
--int jffs2_build_filesystem(struct jffs2_sb_info *c)
-+static int jffs2_build_filesystem(struct jffs2_sb_info *c)
- {
- int ret;
- int i;
- struct jffs2_inode_cache *ic;
-+ struct jffs2_full_dirent *dead_fds = NULL;
-
- /* First, scan the medium and build all the inode caches with
- lists of physical nodes */
-@@ -90,14 +101,17 @@
- return ret;
-
- D1(printk(KERN_DEBUG "Scanned flash completely\n"));
-- /* Now build the data map for each inode, marking obsoleted nodes
-- as such, and also increase nlink of any children. */
-+ D1(jffs2_dump_block_lists(c));
-+
-+ /* Now scan the directory tree, increasing nlink according to every dirent found. */
- for_each_inode(i, c, ic) {
- D1(printk(KERN_DEBUG "Pass 1: ino #%u\n", ic->ino));
-- ret = jffs2_build_inode_pass1(c, ic);
-- if (ret) {
-- D1(printk(KERN_WARNING "Eep. jffs2_build_inode_pass1 for ino %d returned %d\n", ic->ino, ret));
-- return ret;
-+
-+ D1(BUG_ON(ic->ino > c->highest_ino));
-+
-+ if (ic->scan_dents) {
-+ jffs2_build_inode_pass1(c, ic);
-+ cond_resched();
- }
- }
- D1(printk(KERN_DEBUG "Pass 1 complete\n"));
-@@ -107,181 +121,226 @@
- children too, and repeat the scan. As that's going to be
- a fairly uncommon occurrence, it's not so evil to do it this
- way. Recursion bad. */
-- do {
-- D1(printk(KERN_DEBUG "Pass 2 (re)starting\n"));
-- ret = 0;
-+ D1(printk(KERN_DEBUG "Pass 2 starting\n"));
-+
- for_each_inode(i, c, ic) {
- D1(printk(KERN_DEBUG "Pass 2: ino #%u, nlink %d, ic %p, nodes %p\n", ic->ino, ic->nlink, ic, ic->nodes));
- if (ic->nlink)
- continue;
-
-- ret = jffs2_build_remove_unlinked_inode(c, ic);
-- if (ret)
-- break;
-- /* -EAGAIN means the inode's nlink was zero, so we deleted it,
-- and furthermore that it had children and their nlink has now
-- gone to zero too. So we have to restart the scan. */
-+ jffs2_build_remove_unlinked_inode(c, ic, &dead_fds);
-+ cond_resched();
-+ }
-+
-+ D1(printk(KERN_DEBUG "Pass 2a starting\n"));
-+
-+ while (dead_fds) {
-+ struct jffs2_inode_cache *ic;
-+ struct jffs2_full_dirent *fd = dead_fds;
-+
-+ dead_fds = fd->next;
-+
-+ ic = jffs2_get_ino_cache(c, fd->ino);
-+ D1(printk(KERN_DEBUG "Removing dead_fd ino #%u (\"%s\"), ic at %p\n", fd->ino, fd->name, ic));
-+
-+ if (ic)
-+ jffs2_build_remove_unlinked_inode(c, ic, &dead_fds);
-+ jffs2_free_full_dirent(fd);
- }
-- } while(ret == -EAGAIN);
-
- D1(printk(KERN_DEBUG "Pass 2 complete\n"));
-
-- /* Finally, we can scan again and free the dirent nodes and scan_info structs */
-+ /* Finally, we can scan again and free the dirent structs */
- for_each_inode(i, c, ic) {
-- struct jffs2_scan_info *scan = ic->scan;
- struct jffs2_full_dirent *fd;
- D1(printk(KERN_DEBUG "Pass 3: ino #%u, ic %p, nodes %p\n", ic->ino, ic, ic->nodes));
-- if (!scan) {
-- if (ic->nlink) {
-- D1(printk(KERN_WARNING "Why no scan struct for ino #%u which has nlink %d?\n", ic->ino, ic->nlink));
-- }
-- continue;
-- }
-- ic->scan = NULL;
-- while(scan->dents) {
-- fd = scan->dents;
-- scan->dents = fd->next;
-+
-+ while(ic->scan_dents) {
-+ fd = ic->scan_dents;
-+ ic->scan_dents = fd->next;
- jffs2_free_full_dirent(fd);
- }
-- kfree(scan);
-+ ic->scan_dents = NULL;
-+ cond_resched();
- }
- D1(printk(KERN_DEBUG "Pass 3 complete\n"));
-+ D1(jffs2_dump_block_lists(c));
-+
-+ /* Rotate the lists by some number to ensure wear levelling */
-+ jffs2_rotate_lists(c);
-
- return ret;
- }
-
--int jffs2_build_inode_pass1(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
-+static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, struct jffs2_full_dirent **dead_fds)
- {
-- struct jffs2_tmp_dnode_info *tn;
-+ struct jffs2_raw_node_ref *raw;
- struct jffs2_full_dirent *fd;
-- struct jffs2_node_frag *fraglist = NULL;
-- struct jffs2_tmp_dnode_info *metadata = NULL;
--
-- D1(printk(KERN_DEBUG "jffs2_build_inode building inode #%u\n", ic->ino));
-- if (ic->ino > c->highest_ino)
-- c->highest_ino = ic->ino;
-
-- if (!ic->scan->tmpnodes && ic->ino != 1) {
-- D1(printk(KERN_DEBUG "jffs2_build_inode: ino #%u has no data nodes!\n", ic->ino));
-- }
-- /* Build the list to make sure any obsolete nodes are marked as such */
-- while(ic->scan->tmpnodes) {
-- tn = ic->scan->tmpnodes;
-- ic->scan->tmpnodes = tn->next;
--
-- if (metadata && tn->version > metadata->version) {
-- D1(printk(KERN_DEBUG "jffs2_build_inode_pass1 ignoring old metadata at 0x%08x\n",
-- metadata->fn->raw->flash_offset &~3));
-+ D1(printk(KERN_DEBUG "JFFS2: Removing ino #%u with nlink == zero.\n", ic->ino));
-
-- jffs2_free_full_dnode(metadata->fn);
-- jffs2_free_tmp_dnode_info(metadata);
-- metadata = NULL;
-+ for (raw = ic->nodes; raw != (void *)ic; raw = raw->next_in_ino) {
-+ D1(printk(KERN_DEBUG "obsoleting node at 0x%08x\n", ref_offset(raw)));
-+ jffs2_mark_node_obsolete(c, raw);
- }
-
-- if (tn->fn->size) {
-- jffs2_add_full_dnode_to_fraglist (c, &fraglist, tn->fn);
-- jffs2_free_tmp_dnode_info(tn);
-- } else {
-- if (!metadata) {
-- metadata = tn;
-- } else {
-- D1(printk(KERN_DEBUG "jffs2_build_inode_pass1 ignoring new metadata at 0x%08x\n",
-- tn->fn->raw->flash_offset &~3));
--
-- jffs2_free_full_dnode(tn->fn);
-- jffs2_free_tmp_dnode_info(tn);
-- }
-- }
-- }
-+ if (ic->scan_dents) {
-+ int whinged = 0;
-+ D1(printk(KERN_DEBUG "Inode #%u was a directory which may have children...\n", ic->ino));
-
-- /* OK. Now clear up */
-- if (metadata) {
-- jffs2_free_full_dnode(metadata->fn);
-- jffs2_free_tmp_dnode_info(metadata);
-- }
-- metadata = NULL;
-+ while(ic->scan_dents) {
-+ struct jffs2_inode_cache *child_ic;
-
-- while (fraglist) {
-- struct jffs2_node_frag *frag;
-- frag = fraglist;
-- fraglist = fraglist->next;
-+ fd = ic->scan_dents;
-+ ic->scan_dents = fd->next;
-
-- if (frag->node && !(--frag->node->frags)) {
-- jffs2_free_full_dnode(frag->node);
-+ if (!fd->ino) {
-+ /* It's a deletion dirent. Ignore it */
-+ D1(printk(KERN_DEBUG "Child \"%s\" is a deletion dirent, skipping...\n", fd->name));
-+ jffs2_free_full_dirent(fd);
-+ continue;
- }
-- jffs2_free_node_frag(frag);
-+ if (!whinged) {
-+ whinged = 1;
-+ printk(KERN_NOTICE "Inode #%u was a directory with children - removing those too...\n", ic->ino);
- }
-
-- /* Now for each child, increase nlink */
-- for(fd=ic->scan->dents; fd; fd = fd->next) {
-- struct jffs2_inode_cache *child_ic;
-- if (!fd->ino)
-- continue;
-+ D1(printk(KERN_DEBUG "Removing child \"%s\", ino #%u\n",
-+ fd->name, fd->ino));
-
- child_ic = jffs2_get_ino_cache(c, fd->ino);
- if (!child_ic) {
-- printk(KERN_NOTICE "Eep. Child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n",
-- fd->name, fd->ino, ic->ino);
-+ printk(KERN_NOTICE "Cannot remove child \"%s\", ino #%u, because it doesn't exist\n", fd->name, fd->ino);
-+ jffs2_free_full_dirent(fd);
- continue;
- }
-
-- if (child_ic->nlink++ && fd->type == DT_DIR) {
-- printk(KERN_NOTICE "Child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", fd->name, fd->ino, ic->ino);
-- if (fd->ino == 1 && ic->ino == 1) {
-- printk(KERN_NOTICE "This is mostly harmless, and probably caused by creating a JFFS2 image\n");
-- printk(KERN_NOTICE "using a buggy version of mkfs.jffs2. Use at least v1.17.\n");
-+ /* Reduce nlink of the child. If it's now zero, stick it on the
-+ dead_fds list to be cleaned up later. Else just free the fd */
-+
-+ child_ic->nlink--;
-+
-+ if (!child_ic->nlink) {
-+ D1(printk(KERN_DEBUG "Inode #%u (\"%s\") has now got zero nlink. Adding to dead_fds list.\n",
-+ fd->ino, fd->name));
-+ fd->next = *dead_fds;
-+ *dead_fds = fd;
-+ } else {
-+ D1(printk(KERN_DEBUG "Inode #%u (\"%s\") has now got nlink %d. Ignoring.\n",
-+ fd->ino, fd->name, child_ic->nlink));
-+ jffs2_free_full_dirent(fd);
- }
-- /* What do we do about it? */
- }
-- D1(printk(KERN_DEBUG "Increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino));
-- /* Can't free them. We might need them in pass 2 */
- }
-- return 0;
-+
-+ /*
-+ We don't delete the inocache from the hash list and free it yet.
-+ The erase code will do that, when all the nodes are completely gone.
-+ */
- }
-
--int jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
-+static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c)
- {
-- struct jffs2_raw_node_ref *raw;
-- struct jffs2_full_dirent *fd;
-- int ret = 0;
-+ uint32_t size;
-
-- if(!ic->scan) {
-- D1(printk(KERN_DEBUG "ino #%u was already removed\n", ic->ino));
-- return 0;
-- }
-+ /* Deletion should almost _always_ be allowed. We're fairly
-+ buggered once we stop allowing people to delete stuff
-+ because there's not enough free space... */
-+ c->resv_blocks_deletion = 2;
-+
-+ /* Be conservative about how much space we need before we allow writes.
-+ On top of that which is required for deletia, require an extra 2%
-+ of the medium to be available, for overhead caused by nodes being
-+ split across blocks, etc. */
-+
-+ size = c->flash_size / 50; /* 2% of flash size */
-+ size += c->nr_blocks * 100; /* And 100 bytes per eraseblock */
-+ size += c->sector_size - 1; /* ... and round up */
-+
-+ c->resv_blocks_write = c->resv_blocks_deletion + (size / c->sector_size);
-+
-+ /* When do we let the GC thread run in the background */
-+
-+ c->resv_blocks_gctrigger = c->resv_blocks_write + 1;
-+
-+ /* When do we allow garbage collection to merge nodes to make
-+ long-term progress at the expense of short-term space exhaustion? */
-+ c->resv_blocks_gcmerge = c->resv_blocks_deletion + 1;
-+
-+ /* When do we allow garbage collection to eat from bad blocks rather
-+ than actually making progress? */
-+ c->resv_blocks_gcbad = 0;//c->resv_blocks_deletion + 2;
-+
-+ /* If there's less than this amount of dirty space, don't bother
-+ trying to GC to make more space. It'll be a fruitless task */
-+ c->nospc_dirty_size = c->sector_size + (c->flash_size / 100);
-+
-+ D1(printk(KERN_DEBUG "JFFS2 trigger levels (size %d KiB, block size %d KiB, %d blocks)\n",
-+ c->flash_size / 1024, c->sector_size / 1024, c->nr_blocks));
-+ D1(printk(KERN_DEBUG "Blocks required to allow deletion: %d (%d KiB)\n",
-+ c->resv_blocks_deletion, c->resv_blocks_deletion*c->sector_size/1024));
-+ D1(printk(KERN_DEBUG "Blocks required to allow writes: %d (%d KiB)\n",
-+ c->resv_blocks_write, c->resv_blocks_write*c->sector_size/1024));
-+ D1(printk(KERN_DEBUG "Blocks required to quiesce GC thread: %d (%d KiB)\n",
-+ c->resv_blocks_gctrigger, c->resv_blocks_gctrigger*c->sector_size/1024));
-+ D1(printk(KERN_DEBUG "Blocks required to allow GC merges: %d (%d KiB)\n",
-+ c->resv_blocks_gcmerge, c->resv_blocks_gcmerge*c->sector_size/1024));
-+ D1(printk(KERN_DEBUG "Blocks required to GC bad blocks: %d (%d KiB)\n",
-+ c->resv_blocks_gcbad, c->resv_blocks_gcbad*c->sector_size/1024));
-+ D1(printk(KERN_DEBUG "Amount of dirty space required to GC: %d bytes\n",
-+ c->nospc_dirty_size));
-+}
-
-- D1(printk(KERN_DEBUG "JFFS2: Removing ino #%u with nlink == zero.\n", ic->ino));
-+int jffs2_do_mount_fs(struct jffs2_sb_info *c)
-+{
-+ int i;
-
-- for (raw = ic->nodes; raw != (void *)ic; raw = raw->next_in_ino) {
-- D1(printk(KERN_DEBUG "obsoleting node at 0x%08x\n", raw->flash_offset&~3));
-- jffs2_mark_node_obsolete(c, raw);
-+ c->free_size = c->flash_size;
-+ c->nr_blocks = c->flash_size / c->sector_size;
-+ c->blocks = kmalloc(sizeof(struct jffs2_eraseblock) * c->nr_blocks, GFP_KERNEL);
-+ if (!c->blocks)
-+ return -ENOMEM;
-+ for (i=0; i<c->nr_blocks; i++) {
-+ INIT_LIST_HEAD(&c->blocks[i].list);
-+ c->blocks[i].offset = i * c->sector_size;
-+ c->blocks[i].free_size = c->sector_size;
-+ c->blocks[i].dirty_size = 0;
-+ c->blocks[i].wasted_size = 0;
-+ c->blocks[i].unchecked_size = 0;
-+ c->blocks[i].used_size = 0;
-+ c->blocks[i].first_node = NULL;
-+ c->blocks[i].last_node = NULL;
-+ }
-+
-+ init_MUTEX(&c->alloc_sem);
-+ init_MUTEX(&c->erase_free_sem);
-+ init_waitqueue_head(&c->erase_wait);
-+ init_waitqueue_head(&c->inocache_wq);
-+ spin_lock_init(&c->erase_completion_lock);
-+ spin_lock_init(&c->inocache_lock);
-+
-+ INIT_LIST_HEAD(&c->clean_list);
-+ INIT_LIST_HEAD(&c->very_dirty_list);
-+ INIT_LIST_HEAD(&c->dirty_list);
-+ INIT_LIST_HEAD(&c->erasable_list);
-+ INIT_LIST_HEAD(&c->erasing_list);
-+ INIT_LIST_HEAD(&c->erase_pending_list);
-+ INIT_LIST_HEAD(&c->erasable_pending_wbuf_list);
-+ INIT_LIST_HEAD(&c->erase_complete_list);
-+ INIT_LIST_HEAD(&c->free_list);
-+ INIT_LIST_HEAD(&c->bad_list);
-+ INIT_LIST_HEAD(&c->bad_used_list);
-+ c->highest_ino = 1;
-+
-+ if (jffs2_build_filesystem(c)) {
-+ D1(printk(KERN_DEBUG "build_fs failed\n"));
-+ jffs2_free_ino_caches(c);
-+ jffs2_free_raw_node_refs(c);
-+ kfree(c->blocks);
-+ return -EIO;
- }
-
-- if (ic->scan->dents) {
-- printk(KERN_NOTICE "Inode #%u was a directory with children - removing those too...\n", ic->ino);
--
-- while(ic->scan->dents) {
-- struct jffs2_inode_cache *child_ic;
-+ jffs2_calc_trigger_levels(c);
-
-- fd = ic->scan->dents;
-- ic->scan->dents = fd->next;
--
-- D1(printk(KERN_DEBUG "Removing child \"%s\", ino #%u\n",
-- fd->name, fd->ino));
--
-- child_ic = jffs2_get_ino_cache(c, fd->ino);
-- if (!child_ic) {
-- printk(KERN_NOTICE "Cannot remove child \"%s\", ino #%u, because it doesn't exist\n", fd->name, fd->ino);
-- continue;
-- }
-- jffs2_free_full_dirent(fd);
-- child_ic->nlink--;
-- }
-- ret = -EAGAIN;
-- }
-- kfree(ic->scan);
-- ic->scan = NULL;
-- // jffs2_del_ino_cache(c, ic);
-- // jffs2_free_inode_cache(ic);
-- return ret;
-+ return 0;
- }
-diff -Nurb linux-mips-2.4.27/fs/jffs2/compr.c linux/fs/jffs2/compr.c
---- linux-mips-2.4.27/fs/jffs2/compr.c 2001-11-05 21:16:18.000000000 +0100
-+++ linux/fs/jffs2/compr.c 2004-11-19 10:25:12.085171520 +0100
-@@ -1,59 +1,37 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
- * Created by Arjan van de Ven <arjanv@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/kernel.h>
- #include <linux/string.h>
--#include <linux/types.h>
- #include <linux/errno.h>
-+#include <linux/types.h>
-+#include <linux/slab.h>
- #include <linux/jffs2.h>
-+#include "nodelist.h"
-
--int zlib_compress(unsigned char *data_in, unsigned char *cpage_out, __u32 *sourcelen, __u32 *dstlen);
--void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, __u32 srclen, __u32 destlen);
--int rtime_compress(unsigned char *data_in, unsigned char *cpage_out, __u32 *sourcelen, __u32 *dstlen);
--void rtime_decompress(unsigned char *data_in, unsigned char *cpage_out, __u32 srclen, __u32 destlen);
--int rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out, __u32 *sourcelen, __u32 *dstlen);
--void rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out, __u32 srclen, __u32 destlen);
--int dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out, __u32 *sourcelen, __u32 *dstlen);
--void dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, __u32 srclen, __u32 destlen);
-+int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen);
-+void jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen);
-+int jffs2_rtime_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen);
-+void jffs2_rtime_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen);
-+int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen);
-+void jffs2_rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen);
-+int jffs2_dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen);
-+void jffs2_dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, uint32_t srclen, uint32_t destlen);
-
-
- /* jffs2_compress:
- * @data: Pointer to uncompressed data
-- * @cdata: Pointer to buffer for compressed data
-+ * @cdata: Pointer to returned pointer to buffer for compressed data
- * @datalen: On entry, holds the amount of data available for compression.
- * On exit, expected to hold the amount of data actually compressed.
- * @cdatalen: On entry, holds the amount of space available for compressed
-@@ -68,47 +46,59 @@
- * jffs2_compress should compress as much as will fit, and should set
- * *datalen accordingly to show the amount of data which were compressed.
- */
--unsigned char jffs2_compress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 *datalen, __u32 *cdatalen)
-+unsigned char jffs2_compress(unsigned char *data_in, unsigned char **cpage_out,
-+ uint32_t *datalen, uint32_t *cdatalen)
- {
-+#ifdef JFFS2_COMPRESSION
- int ret;
-
-- ret = zlib_compress(data_in, cpage_out, datalen, cdatalen);
-+ *cpage_out = kmalloc(*cdatalen, GFP_KERNEL);
-+ if (!*cpage_out) {
-+ printk(KERN_WARNING "No memory for compressor allocation. Compression failed\n");
-+ goto out;
-+ }
-+
-+#ifdef JFFS2_USE_ZLIB
-+ ret = jffs2_zlib_compress(data_in, *cpage_out, datalen, cdatalen);
- if (!ret) {
- return JFFS2_COMPR_ZLIB;
- }
--#if 0 /* Disabled 23/9/1. With zlib it hardly ever gets a look in */
-- ret = dynrubin_compress(data_in, cpage_out, datalen, cdatalen);
-+#endif
-+#ifdef JFFS2_USE_DYNRUBIN
-+ ret = jffs2_dynrubin_compress(data_in, *cpage_out, datalen, cdatalen);
- if (!ret) {
- return JFFS2_COMPR_DYNRUBIN;
- }
- #endif
--#if 0 /* Disabled 26/2/1. Obsoleted by dynrubin */
-- ret = rubinmips_compress(data_in, cpage_out, datalen, cdatalen);
-+#ifdef JFFS2_USE_RUBINMIPS
-+ ret = jffs2_rubinmips_compress(data_in, *cpage_out, datalen, cdatalen);
- if (!ret) {
- return JFFS2_COMPR_RUBINMIPS;
- }
- #endif
-+#ifdef JFFS2_USE_RTIME
- /* rtime does manage to recompress already-compressed data */
-- ret = rtime_compress(data_in, cpage_out, datalen, cdatalen);
-+ ret = jffs2_rtime_compress(data_in, *cpage_out, datalen, cdatalen);
- if (!ret) {
- return JFFS2_COMPR_RTIME;
- }
--#if 0
-- /* We don't need to copy. Let the caller special-case the COMPR_NONE case. */
-- /* If we get here, no compression is going to work */
-- /* But we might want to use the fragmentation part -- Arjan */
-- memcpy(cpage_out,data_in,min(*datalen,*cdatalen));
-- if (*datalen > *cdatalen)
-- *datalen = *cdatalen;
- #endif
-+ kfree(*cpage_out);
-+#endif /* Compression */
-+ out:
-+ *cpage_out = data_in;
-+ *datalen = *cdatalen;
- return JFFS2_COMPR_NONE; /* We failed to compress */
--
- }
-
-+void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig)
-+{
-+ if (orig != comprbuf)
-+ kfree(comprbuf);
-+}
-
- int jffs2_decompress(unsigned char comprtype, unsigned char *cdata_in,
-- unsigned char *data_out, __u32 cdatalen, __u32 datalen)
-+ unsigned char *data_out, uint32_t cdatalen, uint32_t datalen)
- {
- switch (comprtype) {
- case JFFS2_COMPR_NONE:
-@@ -119,30 +109,27 @@
- case JFFS2_COMPR_ZERO:
- memset(data_out, 0, datalen);
- break;
--
-+#ifdef JFFS2_USE_ZLIB
- case JFFS2_COMPR_ZLIB:
-- zlib_decompress(cdata_in, data_out, cdatalen, datalen);
-+ jffs2_zlib_decompress(cdata_in, data_out, cdatalen, datalen);
- break;
--
-+#endif
-+#ifdef JFFS2_USE_RTIME
- case JFFS2_COMPR_RTIME:
-- rtime_decompress(cdata_in, data_out, cdatalen, datalen);
-+ jffs2_rtime_decompress(cdata_in, data_out, cdatalen, datalen);
- break;
--
-- case JFFS2_COMPR_RUBINMIPS:
--#if 0 /* Disabled 23/9/1 */
-- rubinmips_decompress(cdata_in, data_out, cdatalen, datalen);
--#else
-- printk(KERN_WARNING "JFFS2: Rubinmips compression encountered but support not compiled in!\n");
- #endif
-+#ifdef JFFS2_USE_RUBINMIPS
-+ case JFFS2_COMPR_RUBINMIPS:
-+ jffs2_rubinmips_decompress(cdata_in, data_out, cdatalen, datalen);
- break;
-- case JFFS2_COMPR_DYNRUBIN:
--#if 1 /* Phase this one out */
-- dynrubin_decompress(cdata_in, data_out, cdatalen, datalen);
--#else
-- printk(KERN_WARNING "JFFS2: Dynrubin compression encountered but support not compiled in!\n");
- #endif
-- break;
-+#ifdef JFFS2_USE_DYNRUBIN
-+ case JFFS2_COMPR_DYNRUBIN:
-
-+ jffs2_dynrubin_decompress(cdata_in, data_out, cdatalen, datalen);
-+ break;
-+#endif
- default:
- printk(KERN_NOTICE "Unknown JFFS2 compression type 0x%02x\n", comprtype);
- return -EIO;
-diff -Nurb linux-mips-2.4.27/fs/jffs2/compr_rtime.c linux/fs/jffs2/compr_rtime.c
---- linux-mips-2.4.27/fs/jffs2/compr_rtime.c 2001-10-19 03:24:56.000000000 +0200
-+++ linux/fs/jffs2/compr_rtime.c 2004-11-19 10:25:12.087171216 +0100
-@@ -1,43 +1,19 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
- * Created by Arjan van de Ven <arjanv@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- *
- * Very simple lz77-ish encoder.
- *
- * Theory of operation: Both encoder and decoder have a list of "last
-- * occurances" for every possible source-value; after sending the
-+ * occurrences" for every possible source-value; after sending the
- * first source-byte, the second byte indicated the "run" length of
- * matches
- *
-@@ -51,10 +27,10 @@
- #include <linux/string.h>
-
- /* _compress returns the compressed size, -1 if bigger */
--int rtime_compress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 *sourcelen, __u32 *dstlen)
-+int jffs2_rtime_compress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t *sourcelen, uint32_t *dstlen)
- {
-- int positions[256];
-+ short positions[256];
- int outpos = 0;
- int pos=0;
-
-@@ -91,10 +67,10 @@
- }
-
-
--void rtime_decompress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 srclen, __u32 destlen)
-+void jffs2_rtime_decompress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t srclen, uint32_t destlen)
- {
-- int positions[256];
-+ short positions[256];
- int outpos = 0;
- int pos=0;
-
-diff -Nurb linux-mips-2.4.27/fs/jffs2/compr_rubin.c linux/fs/jffs2/compr_rubin.c
---- linux-mips-2.4.27/fs/jffs2/compr_rubin.c 2001-11-05 21:16:18.000000000 +0100
-+++ linux/fs/jffs2/compr_rubin.c 2004-11-19 10:25:12.088171064 +0100
-@@ -1,37 +1,13 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001, 2002 Red Hat, Inc.
- *
- * Created by Arjan van de Ven <arjanv@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
-@@ -43,7 +19,7 @@
-
-
-
--void init_rubin(struct rubin_state *rs, int div, int *bits)
-+static void init_rubin(struct rubin_state *rs, int div, int *bits)
- {
- int c;
-
-@@ -56,7 +32,7 @@
- }
-
-
--int encode(struct rubin_state *rs, long A, long B, int symbol)
-+static int encode(struct rubin_state *rs, long A, long B, int symbol)
- {
-
- long i0, i1;
-@@ -91,7 +67,7 @@
- }
-
-
--void end_rubin(struct rubin_state *rs)
-+static void end_rubin(struct rubin_state *rs)
- {
-
- int i;
-@@ -104,7 +80,7 @@
- }
-
-
--void init_decode(struct rubin_state *rs, int div, int *bits)
-+static void init_decode(struct rubin_state *rs, int div, int *bits)
- {
- init_rubin(rs, div, bits);
-
-@@ -151,7 +127,7 @@
- rs->rec_q = rec_q;
- }
-
--int decode(struct rubin_state *rs, long A, long B)
-+static int decode(struct rubin_state *rs, long A, long B)
- {
- unsigned long p = rs->p, q = rs->q;
- long i0, threshold;
-@@ -212,8 +188,8 @@
-
-
-
--int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in,
-- unsigned char *cpage_out, __u32 *sourcelen, __u32 *dstlen)
-+static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in,
-+ unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen)
- {
- int outpos = 0;
- int pos=0;
-@@ -246,20 +222,20 @@
- }
- #if 0
- /* _compress returns the compressed size, -1 if bigger */
--int rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 *sourcelen, __u32 *dstlen)
-+int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t *sourcelen, uint32_t *dstlen)
- {
- return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen);
- }
- #endif
--int dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 *sourcelen, __u32 *dstlen)
-+int jffs2_dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t *sourcelen, uint32_t *dstlen)
- {
- int bits[8];
- unsigned char histo[256];
- int i;
- int ret;
-- __u32 mysrclen, mydstlen;
-+ uint32_t mysrclen, mydstlen;
-
- mysrclen = *sourcelen;
- mydstlen = *dstlen - 8;
-@@ -315,8 +291,8 @@
- return 0;
- }
-
--void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata_in,
-- unsigned char *page_out, __u32 srclen, __u32 destlen)
-+static void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata_in,
-+ unsigned char *page_out, uint32_t srclen, uint32_t destlen)
- {
- int outpos = 0;
- struct rubin_state rs;
-@@ -330,14 +306,14 @@
- }
-
-
--void rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 sourcelen, __u32 dstlen)
-+void jffs2_rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t sourcelen, uint32_t dstlen)
- {
- rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen);
- }
-
--void dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 sourcelen, __u32 dstlen)
-+void jffs2_dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t sourcelen, uint32_t dstlen)
- {
- int bits[8];
- int c;
-diff -Nurb linux-mips-2.4.27/fs/jffs2/compr_rubin.h linux/fs/jffs2/compr_rubin.h
---- linux-mips-2.4.27/fs/jffs2/compr_rubin.h 2001-10-19 03:24:56.000000000 +0200
-+++ linux/fs/jffs2/compr_rubin.h 2004-11-19 10:25:12.090170760 +0100
-@@ -1,7 +1,7 @@
- /* Rubin encoder/decoder header */
- /* work started at : aug 3, 1994 */
- /* last modification : aug 15, 1994 */
--/* $Id$ */
-+/* $Id$ */
-
- #include "pushpull.h"
-
-@@ -19,10 +19,3 @@
- int bit_divider;
- int bits[8];
- };
--
--
--void init_rubin (struct rubin_state *rs, int div, int *bits);
--int encode (struct rubin_state *, long, long, int);
--void end_rubin (struct rubin_state *);
--void init_decode (struct rubin_state *, int div, int *bits);
--int decode (struct rubin_state *, long, long);
-diff -Nurb linux-mips-2.4.27/fs/jffs2/compr_zlib.c linux/fs/jffs2/compr_zlib.c
---- linux-mips-2.4.27/fs/jffs2/compr_zlib.c 2003-01-11 18:53:17.000000000 +0100
-+++ linux/fs/jffs2/compr_zlib.c 2004-11-19 10:25:12.091170608 +0100
-@@ -1,50 +1,26 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001, 2002 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
--#ifndef __KERNEL__
-+#if !defined(__KERNEL__) && !defined(__ECOS)
- #error "The userspace support got too messy and was removed. Update your mkfs.jffs2"
- #endif
-
- #include <linux/config.h>
- #include <linux/kernel.h>
--#include <linux/mtd/compatmac.h> /* for min() */
- #include <linux/slab.h>
--#include <linux/jffs2.h>
- #include <linux/zlib.h>
-+#include <linux/zutil.h>
-+#include <asm/semaphore.h>
- #include "nodelist.h"
-
- /* Plan: call deflate() with avail_in == *sourcelen,
-@@ -58,21 +34,24 @@
-
- static DECLARE_MUTEX(deflate_sem);
- static DECLARE_MUTEX(inflate_sem);
--static void *deflate_workspace;
--static void *inflate_workspace;
-+static z_stream inf_strm, def_strm;
-+
-+#ifdef __KERNEL__ /* Linux-only */
-+#include <linux/vmalloc.h>
-+#include <linux/init.h>
-
- int __init jffs2_zlib_init(void)
- {
-- deflate_workspace = vmalloc(zlib_deflate_workspacesize());
-- if (!deflate_workspace) {
-+ def_strm.workspace = vmalloc(zlib_deflate_workspacesize());
-+ if (!def_strm.workspace) {
- printk(KERN_WARNING "Failed to allocate %d bytes for deflate workspace\n", zlib_deflate_workspacesize());
- return -ENOMEM;
- }
- D1(printk(KERN_DEBUG "Allocated %d bytes for deflate workspace\n", zlib_deflate_workspacesize()));
-- inflate_workspace = vmalloc(zlib_inflate_workspacesize());
-- if (!inflate_workspace) {
-+ inf_strm.workspace = vmalloc(zlib_inflate_workspacesize());
-+ if (!inf_strm.workspace) {
- printk(KERN_WARNING "Failed to allocate %d bytes for inflate workspace\n", zlib_inflate_workspacesize());
-- vfree(deflate_workspace);
-+ vfree(def_strm.workspace);
- return -ENOMEM;
- }
- D1(printk(KERN_DEBUG "Allocated %d bytes for inflate workspace\n", zlib_inflate_workspacesize()));
-@@ -81,97 +60,120 @@
-
- void jffs2_zlib_exit(void)
- {
-- vfree(deflate_workspace);
-- vfree(inflate_workspace);
-+ vfree(def_strm.workspace);
-+ vfree(inf_strm.workspace);
- }
-+#endif /* __KERNEL__ */
-
--int zlib_compress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 *sourcelen, __u32 *dstlen)
-+int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t *sourcelen, uint32_t *dstlen)
- {
-- z_stream strm;
- int ret;
-
- if (*dstlen <= STREAM_END_SPACE)
- return -1;
-
- down(&deflate_sem);
-- strm.workspace = deflate_workspace;
-
-- if (Z_OK != zlib_deflateInit(&strm, 3)) {
-+ if (Z_OK != zlib_deflateInit(&def_strm, 3)) {
- printk(KERN_WARNING "deflateInit failed\n");
- up(&deflate_sem);
- return -1;
- }
-
-- strm.next_in = data_in;
-- strm.total_in = 0;
-+ def_strm.next_in = data_in;
-+ def_strm.total_in = 0;
-
-- strm.next_out = cpage_out;
-- strm.total_out = 0;
-+ def_strm.next_out = cpage_out;
-+ def_strm.total_out = 0;
-
-- while (strm.total_out < *dstlen - STREAM_END_SPACE && strm.total_in < *sourcelen) {
-- strm.avail_out = *dstlen - (strm.total_out + STREAM_END_SPACE);
-- strm.avail_in = min((unsigned)(*sourcelen-strm.total_in), strm.avail_out);
-+ while (def_strm.total_out < *dstlen - STREAM_END_SPACE && def_strm.total_in < *sourcelen) {
-+ def_strm.avail_out = *dstlen - (def_strm.total_out + STREAM_END_SPACE);
-+ def_strm.avail_in = min((unsigned)(*sourcelen-def_strm.total_in), def_strm.avail_out);
- D1(printk(KERN_DEBUG "calling deflate with avail_in %d, avail_out %d\n",
-- strm.avail_in, strm.avail_out));
-- ret = zlib_deflate(&strm, Z_PARTIAL_FLUSH);
-+ def_strm.avail_in, def_strm.avail_out));
-+ ret = zlib_deflate(&def_strm, Z_PARTIAL_FLUSH);
- D1(printk(KERN_DEBUG "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n",
-- strm.avail_in, strm.avail_out, strm.total_in, strm.total_out));
-+ def_strm.avail_in, def_strm.avail_out, def_strm.total_in, def_strm.total_out));
- if (ret != Z_OK) {
- D1(printk(KERN_DEBUG "deflate in loop returned %d\n", ret));
-- zlib_deflateEnd(&strm);
-+ zlib_deflateEnd(&def_strm);
- up(&deflate_sem);
- return -1;
- }
- }
-- strm.avail_out += STREAM_END_SPACE;
-- strm.avail_in = 0;
-- ret = zlib_deflate(&strm, Z_FINISH);
-- zlib_deflateEnd(&strm);
-- up(&deflate_sem);
-+ def_strm.avail_out += STREAM_END_SPACE;
-+ def_strm.avail_in = 0;
-+ ret = zlib_deflate(&def_strm, Z_FINISH);
-+ zlib_deflateEnd(&def_strm);
-+
- if (ret != Z_STREAM_END) {
- D1(printk(KERN_DEBUG "final deflate returned %d\n", ret));
-- return -1;
-+ ret = -1;
-+ goto out;
- }
-
-- D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld\n",
-- strm.total_in, strm.total_out));
-+ if (def_strm.total_out >= def_strm.total_in) {
-+ D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld; failing\n",
-+ def_strm.total_in, def_strm.total_out));
-+ ret = -1;
-+ goto out;
-+ }
-
-- if (strm.total_out >= strm.total_in)
-- return -1;
-+ D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld\n",
-+ def_strm.total_in, def_strm.total_out));
-
-- *dstlen = strm.total_out;
-- *sourcelen = strm.total_in;
-- return 0;
-+ *dstlen = def_strm.total_out;
-+ *sourcelen = def_strm.total_in;
-+ ret = 0;
-+ out:
-+ up(&deflate_sem);
-+ return ret;
- }
-
--void zlib_decompress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 srclen, __u32 destlen)
-+void jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out,
-+ uint32_t srclen, uint32_t destlen)
- {
-- z_stream strm;
- int ret;
-+ int wbits = MAX_WBITS;
-
- down(&inflate_sem);
-- strm.workspace = inflate_workspace;
-
-- if (Z_OK != zlib_inflateInit(&strm)) {
-+ inf_strm.next_in = data_in;
-+ inf_strm.avail_in = srclen;
-+ inf_strm.total_in = 0;
-+
-+ inf_strm.next_out = cpage_out;
-+ inf_strm.avail_out = destlen;
-+ inf_strm.total_out = 0;
-+
-+ /* If it's deflate, and it's got no preset dictionary, then
-+ we can tell zlib to skip the adler32 check. */
-+ if (srclen > 2 && !(data_in[1] & PRESET_DICT) &&
-+ ((data_in[0] & 0x0f) == Z_DEFLATED) &&
-+ !(((data_in[0]<<8) + data_in[1]) % 31)) {
-+
-+ D2(printk(KERN_DEBUG "inflate skipping adler32\n"));
-+ wbits = -((data_in[0] >> 4) + 8);
-+ inf_strm.next_in += 2;
-+ inf_strm.avail_in -= 2;
-+ } else {
-+ /* Let this remain D1 for now -- it should never happen */
-+ D1(printk(KERN_DEBUG "inflate not skipping adler32\n"));
-+ }
-+
-+
-+ if (Z_OK != zlib_inflateInit2(&inf_strm, wbits)) {
- printk(KERN_WARNING "inflateInit failed\n");
- up(&inflate_sem);
- return;
- }
-- strm.next_in = data_in;
-- strm.avail_in = srclen;
-- strm.total_in = 0;
--
-- strm.next_out = cpage_out;
-- strm.avail_out = destlen;
-- strm.total_out = 0;
-
-- while((ret = zlib_inflate(&strm, Z_FINISH)) == Z_OK)
-+ while((ret = zlib_inflate(&inf_strm, Z_FINISH)) == Z_OK)
- ;
- if (ret != Z_STREAM_END) {
- printk(KERN_NOTICE "inflate returned %d\n", ret);
- }
-- zlib_inflateEnd(&strm);
-+ zlib_inflateEnd(&inf_strm);
- up(&inflate_sem);
- }
-diff -Nurb linux-mips-2.4.27/fs/jffs2/comprtest.c linux/fs/jffs2/comprtest.c
---- linux-mips-2.4.27/fs/jffs2/comprtest.c 2001-10-19 03:24:56.000000000 +0200
-+++ linux/fs/jffs2/comprtest.c 2004-11-19 10:25:12.093170304 +0100
-@@ -1,4 +1,4 @@
--/* $Id$ */
-+/* $Id$ */
-
- #include <linux/kernel.h>
- #include <linux/string.h>
-@@ -266,13 +266,13 @@
- static unsigned char decomprbuf[TESTDATA_LEN];
-
- int jffs2_decompress(unsigned char comprtype, unsigned char *cdata_in,
-- unsigned char *data_out, __u32 cdatalen, __u32 datalen);
-+ unsigned char *data_out, uint32_t cdatalen, uint32_t datalen);
- unsigned char jffs2_compress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 *datalen, __u32 *cdatalen);
-+ uint32_t *datalen, uint32_t *cdatalen);
-
- int init_module(void ) {
- unsigned char comprtype;
-- __u32 c, d;
-+ uint32_t c, d;
- int ret;
-
- printk("Original data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
-diff -Nurb linux-mips-2.4.27/fs/jffs2/crc32.c linux/fs/jffs2/crc32.c
---- linux-mips-2.4.27/fs/jffs2/crc32.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/jffs2/crc32.c 2004-11-19 10:25:12.095170000 +0100
-@@ -0,0 +1,97 @@
-+/*
-+ * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
-+ * code or tables extracted from it, as desired without restriction.
-+ *
-+ * First, the polynomial itself and its table of feedback terms. The
-+ * polynomial is
-+ * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
-+ *
-+ * Note that we take it "backwards" and put the highest-order term in
-+ * the lowest-order bit. The X^32 term is "implied"; the LSB is the
-+ * X^31 term, etc. The X^0 term (usually shown as "+1") results in
-+ * the MSB being 1
-+ *
-+ * Note that the usual hardware shift register implementation, which
-+ * is what we're using (we're merely optimizing it by doing eight-bit
-+ * chunks at a time) shifts bits into the lowest-order term. In our
-+ * implementation, that means shifting towards the right. Why do we
-+ * do it this way? Because the calculated CRC must be transmitted in
-+ * order from highest-order term to lowest-order term. UARTs transmit
-+ * characters in order from LSB to MSB. By storing the CRC this way
-+ * we hand it to the UART in the order low-byte to high-byte; the UART
-+ * sends each low-bit to hight-bit; and the result is transmission bit
-+ * by bit from highest- to lowest-order term without requiring any bit
-+ * shuffling on our part. Reception works similarly
-+ *
-+ * The feedback terms table consists of 256, 32-bit entries. Notes
-+ *
-+ * The table can be generated at runtime if desired; code to do so
-+ * is shown later. It might not be obvious, but the feedback
-+ * terms simply represent the results of eight shift/xor opera
-+ * tions for all combinations of data and CRC register values
-+ *
-+ * The values must be right-shifted by eight bits by the "updcrc
-+ * logic; the shift must be unsigned (bring in zeroes). On some
-+ * hardware you could probably optimize the shift in assembler by
-+ * using byte-swap instructions
-+ * polynomial $edb88320
-+ */
-+
-+/* $Id$ */
-+
-+#include "crc32.h"
-+
-+const uint32_t crc32_table[256] = {
-+ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
-+ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
-+ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
-+ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
-+ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
-+ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
-+ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
-+ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
-+ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
-+ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
-+ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
-+ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
-+ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
-+ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
-+ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
-+ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
-+ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
-+ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
-+ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
-+ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
-+ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
-+ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
-+ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
-+ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
-+ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
-+ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
-+ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
-+ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
-+ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
-+ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
-+ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
-+ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
-+ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
-+ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
-+ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
-+ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
-+ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
-+ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
-+ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
-+ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
-+ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
-+ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
-+ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
-+ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
-+ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
-+ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
-+ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
-+ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
-+ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
-+ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
-+ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
-+ 0x2d02ef8dL
-+};
-diff -Nurb linux-mips-2.4.27/fs/jffs2/crc32.h linux/fs/jffs2/crc32.h
---- linux-mips-2.4.27/fs/jffs2/crc32.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/jffs2/crc32.h 2004-11-19 10:25:12.096169848 +0100
-@@ -0,0 +1,21 @@
-+#ifndef CRC32_H
-+#define CRC32_H
-+
-+/* $Id$ */
-+
-+#include <linux/types.h>
-+
-+extern const uint32_t crc32_table[256];
-+
-+/* Return a 32-bit CRC of the contents of the buffer. */
-+
-+static inline uint32_t
-+crc32(uint32_t val, const void *ss, int len)
-+{
-+ const unsigned char *s = ss;
-+ while (--len >= 0)
-+ val = crc32_table[(val ^ *s++) & 0xff] ^ (val >> 8);
-+ return val;
-+}
-+
-+#endif
-diff -Nurb linux-mips-2.4.27/fs/jffs2/dir.c linux/fs/jffs2/dir.c
---- linux-mips-2.4.27/fs/jffs2/dir.c 2003-11-17 02:07:44.000000000 +0100
-+++ linux/fs/jffs2/dir.c 2004-11-19 10:25:12.097169696 +0100
-@@ -1,84 +1,73 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/kernel.h>
- #include <linux/slab.h>
-+#include <linux/sched.h>
- #include <linux/fs.h>
--#include <linux/mtd/compatmac.h> /* For completion */
-+#include <linux/crc32.h>
- #include <linux/jffs2.h>
- #include <linux/jffs2_fs_i.h>
- #include <linux/jffs2_fs_sb.h>
-+#include <linux/time.h>
- #include "nodelist.h"
--#include <linux/crc32.h>
-+
-+/* Urgh. Please tell me there's a nicer way of doing these. */
-+#include <linux/version.h>
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,48)
-+typedef int mknod_arg_t;
-+#define NAMEI_COMPAT(x) ((void *)x)
-+#else
-+typedef dev_t mknod_arg_t;
-+#define NAMEI_COMPAT(x) (x)
-+#endif
-
- static int jffs2_readdir (struct file *, void *, filldir_t);
-
--static int jffs2_create (struct inode *,struct dentry *,int);
--static struct dentry *jffs2_lookup (struct inode *,struct dentry *);
-+static int jffs2_create (struct inode *,struct dentry *,int,
-+ struct nameidata *);
-+static struct dentry *jffs2_lookup (struct inode *,struct dentry *,
-+ struct nameidata *);
- static int jffs2_link (struct dentry *,struct inode *,struct dentry *);
- static int jffs2_unlink (struct inode *,struct dentry *);
- static int jffs2_symlink (struct inode *,struct dentry *,const char *);
- static int jffs2_mkdir (struct inode *,struct dentry *,int);
- static int jffs2_rmdir (struct inode *,struct dentry *);
--static int jffs2_mknod (struct inode *,struct dentry *,int,int);
-+static int jffs2_mknod (struct inode *,struct dentry *,int,mknod_arg_t);
- static int jffs2_rename (struct inode *, struct dentry *,
- struct inode *, struct dentry *);
-
- struct file_operations jffs2_dir_operations =
- {
-- read: generic_read_dir,
-- readdir: jffs2_readdir,
-- ioctl: jffs2_ioctl,
-- fsync: jffs2_null_fsync
-+ .read = generic_read_dir,
-+ .readdir = jffs2_readdir,
-+ .ioctl = jffs2_ioctl,
-+ .fsync = jffs2_fsync
- };
-
-
- struct inode_operations jffs2_dir_inode_operations =
- {
-- create: jffs2_create,
-- lookup: jffs2_lookup,
-- link: jffs2_link,
-- unlink: jffs2_unlink,
-- symlink: jffs2_symlink,
-- mkdir: jffs2_mkdir,
-- rmdir: jffs2_rmdir,
-- mknod: jffs2_mknod,
-- rename: jffs2_rename,
-- setattr: jffs2_setattr,
-+ .create = NAMEI_COMPAT(jffs2_create),
-+ .lookup = NAMEI_COMPAT(jffs2_lookup),
-+ .link = jffs2_link,
-+ .unlink = jffs2_unlink,
-+ .symlink = jffs2_symlink,
-+ .mkdir = jffs2_mkdir,
-+ .rmdir = jffs2_rmdir,
-+ .mknod = jffs2_mknod,
-+ .rename = jffs2_rename,
-+ .setattr = jffs2_setattr,
- };
-
- /***********************************************************************/
-@@ -88,12 +77,13 @@
- and we use the same hash function as the dentries. Makes this
- nice and simple
- */
--static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target)
-+static struct dentry *jffs2_lookup(struct inode *dir_i, struct dentry *target,
-+ struct nameidata *nd)
- {
- struct jffs2_inode_info *dir_f;
- struct jffs2_sb_info *c;
- struct jffs2_full_dirent *fd = NULL, *fd_list;
-- __u32 ino = 0;
-+ uint32_t ino = 0;
- struct inode *inode = NULL;
-
- D1(printk(KERN_DEBUG "jffs2_lookup()\n"));
-@@ -153,8 +143,9 @@
- offset++;
- }
- if (offset == 1) {
-- D1(printk(KERN_DEBUG "Dirent 1: \"..\", ino #%lu\n", filp->f_dentry->d_parent->d_inode->i_ino));
-- if (filldir(dirent, "..", 2, 1, filp->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
-+ unsigned long pino = parent_ino(filp->f_dentry);
-+ D1(printk(KERN_DEBUG "Dirent 1: \"..\", ino #%lu\n", pino));
-+ if (filldir(dirent, "..", 2, 1, pino, DT_DIR) < 0)
- goto out;
- offset++;
- }
-@@ -188,18 +179,14 @@
-
- /***********************************************************************/
-
--static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode)
-+
-+static int jffs2_create(struct inode *dir_i, struct dentry *dentry, int mode,
-+ struct nameidata *nd)
- {
-+ struct jffs2_raw_inode *ri;
- struct jffs2_inode_info *f, *dir_f;
- struct jffs2_sb_info *c;
- struct inode *inode;
-- struct jffs2_raw_inode *ri;
-- struct jffs2_raw_dirent *rd;
-- struct jffs2_full_dnode *fn;
-- struct jffs2_full_dirent *fd;
-- int namelen;
-- __u32 alloclen, phys_ofs;
-- __u32 writtenlen;
- int ret;
-
- ri = jffs2_alloc_raw_inode();
-@@ -210,23 +197,11 @@
-
- D1(printk(KERN_DEBUG "jffs2_create()\n"));
-
-- /* Try to reserve enough space for both node and dirent.
-- * Just the node will do for now, though
-- */
-- namelen = dentry->d_name.len;
-- ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);
-- D1(printk(KERN_DEBUG "jffs2_create(): reserved 0x%x bytes\n", alloclen));
-- if (ret) {
-- jffs2_free_raw_inode(ri);
-- return ret;
-- }
--
- inode = jffs2_new_inode(dir_i, mode, ri);
-
- if (IS_ERR(inode)) {
- D1(printk(KERN_DEBUG "jffs2_new_inode() failed\n"));
- jffs2_free_raw_inode(ri);
-- jffs2_complete_reservation(c);
- return PTR_ERR(inode);
- }
-
-@@ -236,93 +211,22 @@
- inode->i_mapping->nrpages = 0;
-
- f = JFFS2_INODE_INFO(inode);
-+ dir_f = JFFS2_INODE_INFO(dir_i);
-
-- ri->data_crc = 0;
-- ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
--
-- fn = jffs2_write_dnode(inode, ri, NULL, 0, phys_ofs, &writtenlen);
-- D1(printk(KERN_DEBUG "jffs2_create created file with mode 0x%x\n", ri->mode));
-- jffs2_free_raw_inode(ri);
--
-- if (IS_ERR(fn)) {
-- D1(printk(KERN_DEBUG "jffs2_write_dnode() failed\n"));
-- /* Eeek. Wave bye bye */
-- up(&f->sem);
-- jffs2_complete_reservation(c);
-- jffs2_clear_inode(inode);
-- return PTR_ERR(fn);
-- }
-- /* No data here. Only a metadata node, which will be
-- obsoleted by the first data write
-- */
-- f->metadata = fn;
--
-- /* Work out where to put the dirent node now. */
-- writtenlen = PAD(writtenlen);
-- phys_ofs += writtenlen;
-- alloclen -= writtenlen;
-- up(&f->sem);
--
-- if (alloclen < sizeof(*rd)+namelen) {
-- /* Not enough space left in this chunk. Get some more */
-- jffs2_complete_reservation(c);
-- ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
-+ ret = jffs2_do_create(c, dir_f, f, ri,
-+ dentry->d_name.name, dentry->d_name.len);
-
- if (ret) {
-- /* Eep. */
-- D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n"));
- jffs2_clear_inode(inode);
-+ make_bad_inode(inode);
-+ iput(inode);
-+ jffs2_free_raw_inode(ri);
- return ret;
- }
-- }
-
-- rd = jffs2_alloc_raw_dirent();
-- if (!rd) {
-- /* Argh. Now we treat it like a normal delete */
-- jffs2_complete_reservation(c);
-- jffs2_clear_inode(inode);
-- return -ENOMEM;
-- }
--
-- dir_f = JFFS2_INODE_INFO(dir_i);
-- down(&dir_f->sem);
--
-- rd->magic = JFFS2_MAGIC_BITMASK;
-- rd->nodetype = JFFS2_NODETYPE_DIRENT;
-- rd->totlen = sizeof(*rd) + namelen;
-- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
--
-- rd->pino = dir_i->i_ino;
-- rd->version = ++dir_f->highest_version;
-- rd->ino = inode->i_ino;
-- rd->mctime = CURRENT_TIME;
-- rd->nsize = namelen;
-- rd->type = DT_REG;
-- rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
-- rd->name_crc = crc32(0, dentry->d_name.name, namelen);
--
-- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
--
-- jffs2_complete_reservation(c);
--
-- if (IS_ERR(fd)) {
-- /* dirent failed to write. Delete the inode normally
-- as if it were the final unlink() */
-- jffs2_free_raw_dirent(rd);
-- up(&dir_f->sem);
-- jffs2_clear_inode(inode);
-- return PTR_ERR(fd);
-- }
--
-- dir_i->i_mtime = dir_i->i_ctime = rd->mctime;
--
-- jffs2_free_raw_dirent(rd);
--
-- /* Link the fd into the inode's list, obsoleting an old
-- one if necessary. */
-- jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-- up(&dir_f->sem);
-+ dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(ri->ctime));
-
-+ jffs2_free_raw_inode(ri);
- d_instantiate(dentry, inode);
-
- D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n",
-@@ -332,173 +236,48 @@
-
- /***********************************************************************/
-
--static int jffs2_do_unlink(struct inode *dir_i, struct dentry *dentry, int rename)
--{
-- struct jffs2_inode_info *dir_f, *f;
-- struct jffs2_sb_info *c;
-- struct jffs2_raw_dirent *rd;
-- struct jffs2_full_dirent *fd;
-- __u32 alloclen, phys_ofs;
-- int ret;
--
-- c = JFFS2_SB_INFO(dir_i->i_sb);
--
-- rd = jffs2_alloc_raw_dirent();
-- if (!rd)
-- return -ENOMEM;
--
-- ret = jffs2_reserve_space(c, sizeof(*rd)+dentry->d_name.len, &phys_ofs, &alloclen, ALLOC_DELETION);
-- if (ret) {
-- jffs2_free_raw_dirent(rd);
-- return ret;
-- }
--
-- dir_f = JFFS2_INODE_INFO(dir_i);
-- down(&dir_f->sem);
--
-- /* Build a deletion node */
-- rd->magic = JFFS2_MAGIC_BITMASK;
-- rd->nodetype = JFFS2_NODETYPE_DIRENT;
-- rd->totlen = sizeof(*rd) + dentry->d_name.len;
-- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
--
-- rd->pino = dir_i->i_ino;
-- rd->version = ++dir_f->highest_version;
-- rd->ino = 0;
-- rd->mctime = CURRENT_TIME;
-- rd->nsize = dentry->d_name.len;
-- rd->type = DT_UNKNOWN;
-- rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
-- rd->name_crc = crc32(0, dentry->d_name.name, dentry->d_name.len);
--
-- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, dentry->d_name.len, phys_ofs, NULL);
--
-- jffs2_complete_reservation(c);
-- jffs2_free_raw_dirent(rd);
--
-- if (IS_ERR(fd)) {
-- up(&dir_f->sem);
-- return PTR_ERR(fd);
-- }
--
-- /* File it. This will mark the old one obsolete. */
-- jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-- up(&dir_f->sem);
--
-- if (!rename) {
-- f = JFFS2_INODE_INFO(dentry->d_inode);
-- down(&f->sem);
--
-- while (f->dents) {
-- /* There can be only deleted ones */
-- fd = f->dents;
--
-- f->dents = fd->next;
--
-- if (fd->ino) {
-- printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n",
-- f->inocache->ino, fd->name, fd->ino);
-- } else {
-- D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", fd->name, f->inocache->ino));
-- }
-- jffs2_mark_node_obsolete(c, fd->raw);
-- jffs2_free_full_dirent(fd);
-- }
-- /* Don't oops on unlinking a bad inode */
-- if (f->inocache)
-- f->inocache->nlink--;
-- dentry->d_inode->i_nlink--;
-- up(&f->sem);
-- }
--
-- return 0;
--}
-
- static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry)
- {
-- return jffs2_do_unlink(dir_i, dentry, 0);
--}
--/***********************************************************************/
--
--static int jffs2_do_link (struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry, int rename)
--{
-- struct jffs2_inode_info *dir_f, *f;
-- struct jffs2_sb_info *c;
-- struct jffs2_raw_dirent *rd;
-- struct jffs2_full_dirent *fd;
-- __u32 alloclen, phys_ofs;
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(dir_i->i_sb);
-+ struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
-+ struct jffs2_inode_info *dead_f = JFFS2_INODE_INFO(dentry->d_inode);
- int ret;
-
-- c = JFFS2_SB_INFO(dir_i->i_sb);
--
-- rd = jffs2_alloc_raw_dirent();
-- if (!rd)
-- return -ENOMEM;
--
-- ret = jffs2_reserve_space(c, sizeof(*rd)+dentry->d_name.len, &phys_ofs, &alloclen, ALLOC_NORMAL);
-- if (ret) {
-- jffs2_free_raw_dirent(rd);
-+ ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,
-+ dentry->d_name.len, dead_f);
-+ if (dead_f->inocache)
-+ dentry->d_inode->i_nlink = dead_f->inocache->nlink;
- return ret;
-- }
--
-- dir_f = JFFS2_INODE_INFO(dir_i);
-- down(&dir_f->sem);
--
-- /* Build a deletion node */
-- rd->magic = JFFS2_MAGIC_BITMASK;
-- rd->nodetype = JFFS2_NODETYPE_DIRENT;
-- rd->totlen = sizeof(*rd) + dentry->d_name.len;
-- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
--
-- rd->pino = dir_i->i_ino;
-- rd->version = ++dir_f->highest_version;
-- rd->ino = old_dentry->d_inode->i_ino;
-- rd->mctime = CURRENT_TIME;
-- rd->nsize = dentry->d_name.len;
--
-- /* XXX: This is ugly. */
-- rd->type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
-- if (!rd->type) rd->type = DT_REG;
--
-- rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
-- rd->name_crc = crc32(0, dentry->d_name.name, dentry->d_name.len);
--
-- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, dentry->d_name.len, phys_ofs, NULL);
--
-- jffs2_complete_reservation(c);
-- jffs2_free_raw_dirent(rd);
--
-- if (IS_ERR(fd)) {
-- up(&dir_f->sem);
-- return PTR_ERR(fd);
-- }
--
-- /* File it. This will mark the old one obsolete. */
-- jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-- up(&dir_f->sem);
--
-- if (!rename) {
-- f = JFFS2_INODE_INFO(old_dentry->d_inode);
-- down(&f->sem);
-- old_dentry->d_inode->i_nlink = ++f->inocache->nlink;
-- up(&f->sem);
-- }
-- return 0;
- }
-+/***********************************************************************/
-+
-
- static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry)
- {
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dentry->d_inode->i_sb);
-+ struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode);
-+ struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
- int ret;
-+ uint8_t type;
-
-- /* Can't link a bad inode. */
-- if (!JFFS2_INODE_INFO(old_dentry->d_inode)->inocache)
-+ /* Don't let people make hard links to bad inodes. */
-+ if (!f->inocache)
- return -EIO;
-
- if (S_ISDIR(old_dentry->d_inode->i_mode))
- return -EPERM;
-
-- ret = jffs2_do_link(old_dentry, dir_i, dentry, 0);
-+ /* XXX: This is ugly */
-+ type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
-+ if (!type) type = DT_REG;
-+
-+ ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len);
-+
- if (!ret) {
-+ down(&f->sem);
-+ old_dentry->d_inode->i_nlink = ++f->inocache->nlink;
-+ up(&f->sem);
- d_instantiate(dentry, old_dentry->d_inode);
- atomic_inc(&old_dentry->d_inode->i_count);
- }
-@@ -517,8 +296,7 @@
- struct jffs2_full_dnode *fn;
- struct jffs2_full_dirent *fd;
- int namelen;
-- __u32 alloclen, phys_ofs;
-- __u32 writtenlen;
-+ uint32_t alloclen, phys_ofs;
- int ret;
-
- /* FIXME: If you care. We'd need to use frags for the target
-@@ -556,15 +334,16 @@
-
- f = JFFS2_INODE_INFO(inode);
-
-- inode->i_size = ri->isize = ri->dsize = ri->csize = strlen(target);
-- ri->totlen = sizeof(*ri) + ri->dsize;
-- ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
-+ inode->i_size = strlen(target);
-+ ri->isize = ri->dsize = ri->csize = cpu_to_je32(inode->i_size);
-+ ri->totlen = cpu_to_je32(sizeof(*ri) + inode->i_size);
-+ ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
-
- ri->compr = JFFS2_COMPR_NONE;
-- ri->data_crc = crc32(0, target, strlen(target));
-- ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
-+ ri->data_crc = cpu_to_je32(crc32(0, target, strlen(target)));
-+ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-
-- fn = jffs2_write_dnode(inode, ri, target, strlen(target), phys_ofs, &writtenlen);
-+ fn = jffs2_write_dnode(c, f, ri, target, strlen(target), phys_ofs, ALLOC_NORMAL);
-
- jffs2_free_raw_inode(ri);
-
-@@ -581,13 +360,6 @@
- f->metadata = fn;
- up(&f->sem);
-
-- /* Work out where to put the dirent node now. */
-- writtenlen = (writtenlen+3)&~3;
-- phys_ofs += writtenlen;
-- alloclen -= writtenlen;
--
-- if (alloclen < sizeof(*rd)+namelen) {
-- /* Not enough space left in this chunk. Get some more */
- jffs2_complete_reservation(c);
- ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
- if (ret) {
-@@ -595,7 +367,6 @@
- jffs2_clear_inode(inode);
- return ret;
- }
-- }
-
- rd = jffs2_alloc_raw_dirent();
- if (!rd) {
-@@ -608,41 +379,42 @@
- dir_f = JFFS2_INODE_INFO(dir_i);
- down(&dir_f->sem);
-
-- rd->magic = JFFS2_MAGIC_BITMASK;
-- rd->nodetype = JFFS2_NODETYPE_DIRENT;
-- rd->totlen = sizeof(*rd) + namelen;
-- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
--
-- rd->pino = dir_i->i_ino;
-- rd->version = ++dir_f->highest_version;
-- rd->ino = inode->i_ino;
-- rd->mctime = CURRENT_TIME;
-+ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
-+ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
-+ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
-+
-+ rd->pino = cpu_to_je32(dir_i->i_ino);
-+ rd->version = cpu_to_je32(++dir_f->highest_version);
-+ rd->ino = cpu_to_je32(inode->i_ino);
-+ rd->mctime = cpu_to_je32(get_seconds());
- rd->nsize = namelen;
- rd->type = DT_LNK;
-- rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
-- rd->name_crc = crc32(0, dentry->d_name.name, namelen);
-+ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
-+ rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
-
-- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
--
-- jffs2_complete_reservation(c);
-+ fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
-
- if (IS_ERR(fd)) {
- /* dirent failed to write. Delete the inode normally
- as if it were the final unlink() */
-+ jffs2_complete_reservation(c);
- jffs2_free_raw_dirent(rd);
- up(&dir_f->sem);
- jffs2_clear_inode(inode);
- return PTR_ERR(fd);
- }
-
-- dir_i->i_mtime = dir_i->i_ctime = rd->mctime;
-+ dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime));
-
- jffs2_free_raw_dirent(rd);
-
- /* Link the fd into the inode's list, obsoleting an old
- one if necessary. */
- jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-+
- up(&dir_f->sem);
-+ jffs2_complete_reservation(c);
-
- d_instantiate(dentry, inode);
- return 0;
-@@ -659,8 +431,7 @@
- struct jffs2_full_dnode *fn;
- struct jffs2_full_dirent *fd;
- int namelen;
-- __u32 alloclen, phys_ofs;
-- __u32 writtenlen;
-+ uint32_t alloclen, phys_ofs;
- int ret;
-
- mode |= S_IFDIR;
-@@ -692,13 +463,15 @@
-
- inode->i_op = &jffs2_dir_inode_operations;
- inode->i_fop = &jffs2_dir_operations;
-+ /* Directories get nlink 2 at start */
-+ inode->i_nlink = 2;
-
- f = JFFS2_INODE_INFO(inode);
-
-- ri->data_crc = 0;
-- ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
-+ ri->data_crc = cpu_to_je32(0);
-+ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-
-- fn = jffs2_write_dnode(inode, ri, NULL, 0, phys_ofs, &writtenlen);
-+ fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
-
- jffs2_free_raw_inode(ri);
-
-@@ -715,13 +488,6 @@
- f->metadata = fn;
- up(&f->sem);
-
-- /* Work out where to put the dirent node now. */
-- writtenlen = PAD(writtenlen);
-- phys_ofs += writtenlen;
-- alloclen -= writtenlen;
--
-- if (alloclen < sizeof(*rd)+namelen) {
-- /* Not enough space left in this chunk. Get some more */
- jffs2_complete_reservation(c);
- ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
- if (ret) {
-@@ -729,7 +495,6 @@
- jffs2_clear_inode(inode);
- return ret;
- }
-- }
-
- rd = jffs2_alloc_raw_dirent();
- if (!rd) {
-@@ -742,41 +507,43 @@
- dir_f = JFFS2_INODE_INFO(dir_i);
- down(&dir_f->sem);
-
-- rd->magic = JFFS2_MAGIC_BITMASK;
-- rd->nodetype = JFFS2_NODETYPE_DIRENT;
-- rd->totlen = sizeof(*rd) + namelen;
-- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
--
-- rd->pino = dir_i->i_ino;
-- rd->version = ++dir_f->highest_version;
-- rd->ino = inode->i_ino;
-- rd->mctime = CURRENT_TIME;
-+ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
-+ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
-+ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
-+
-+ rd->pino = cpu_to_je32(dir_i->i_ino);
-+ rd->version = cpu_to_je32(++dir_f->highest_version);
-+ rd->ino = cpu_to_je32(inode->i_ino);
-+ rd->mctime = cpu_to_je32(get_seconds());
- rd->nsize = namelen;
- rd->type = DT_DIR;
-- rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
-- rd->name_crc = crc32(0, dentry->d_name.name, namelen);
-+ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
-+ rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
-
-- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
--
-- jffs2_complete_reservation(c);
-+ fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
-
- if (IS_ERR(fd)) {
- /* dirent failed to write. Delete the inode normally
- as if it were the final unlink() */
-+ jffs2_complete_reservation(c);
- jffs2_free_raw_dirent(rd);
- up(&dir_f->sem);
- jffs2_clear_inode(inode);
- return PTR_ERR(fd);
- }
-
-- dir_i->i_mtime = dir_i->i_ctime = rd->mctime;
-+ dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime));
-+ dir_i->i_nlink++;
-
- jffs2_free_raw_dirent(rd);
-
- /* Link the fd into the inode's list, obsoleting an old
- one if necessary. */
- jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-+
- up(&dir_f->sem);
-+ jffs2_complete_reservation(c);
-
- d_instantiate(dentry, inode);
- return 0;
-@@ -786,15 +553,19 @@
- {
- struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode);
- struct jffs2_full_dirent *fd;
-+ int ret;
-
- for (fd = f->dents ; fd; fd = fd->next) {
- if (fd->ino)
- return -ENOTEMPTY;
- }
-- return jffs2_unlink(dir_i, dentry);
-+ ret = jffs2_unlink(dir_i, dentry);
-+ if (!ret)
-+ dir_i->i_nlink--;
-+ return ret;
- }
-
--static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, int rdev)
-+static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, mknod_arg_t rdev)
- {
- struct jffs2_inode_info *f, *dir_f;
- struct jffs2_sb_info *c;
-@@ -804,12 +575,14 @@
- struct jffs2_full_dnode *fn;
- struct jffs2_full_dirent *fd;
- int namelen;
-- unsigned short dev;
-+ jint16_t dev;
- int devlen = 0;
-- __u32 alloclen, phys_ofs;
-- __u32 writtenlen;
-+ uint32_t alloclen, phys_ofs;
- int ret;
-
-+ if (!old_valid_dev(rdev))
-+ return -EINVAL;
-+
- ri = jffs2_alloc_raw_inode();
- if (!ri)
- return -ENOMEM;
-@@ -817,7 +590,7 @@
- c = JFFS2_SB_INFO(dir_i->i_sb);
-
- if (S_ISBLK(mode) || S_ISCHR(mode)) {
-- dev = (MAJOR(to_kdev_t(rdev)) << 8) | MINOR(to_kdev_t(rdev));
-+ dev = cpu_to_je16(old_encode_dev(rdev));
- devlen = sizeof(dev);
- }
-
-@@ -844,15 +617,15 @@
-
- f = JFFS2_INODE_INFO(inode);
-
-- ri->dsize = ri->csize = devlen;
-- ri->totlen = sizeof(*ri) + ri->csize;
-- ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
-+ ri->dsize = ri->csize = cpu_to_je32(devlen);
-+ ri->totlen = cpu_to_je32(sizeof(*ri) + devlen);
-+ ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
-
- ri->compr = JFFS2_COMPR_NONE;
-- ri->data_crc = crc32(0, &dev, devlen);
-- ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
-+ ri->data_crc = cpu_to_je32(crc32(0, &dev, devlen));
-+ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-
-- fn = jffs2_write_dnode(inode, ri, (char *)&dev, devlen, phys_ofs, &writtenlen);
-+ fn = jffs2_write_dnode(c, f, ri, (char *)&dev, devlen, phys_ofs, ALLOC_NORMAL);
-
- jffs2_free_raw_inode(ri);
-
-@@ -869,13 +642,6 @@
- f->metadata = fn;
- up(&f->sem);
-
-- /* Work out where to put the dirent node now. */
-- writtenlen = (writtenlen+3)&~3;
-- phys_ofs += writtenlen;
-- alloclen -= writtenlen;
--
-- if (alloclen < sizeof(*rd)+namelen) {
-- /* Not enough space left in this chunk. Get some more */
- jffs2_complete_reservation(c);
- ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
- if (ret) {
-@@ -883,7 +649,6 @@
- jffs2_clear_inode(inode);
- return ret;
- }
-- }
-
- rd = jffs2_alloc_raw_dirent();
- if (!rd) {
-@@ -896,44 +661,45 @@
- dir_f = JFFS2_INODE_INFO(dir_i);
- down(&dir_f->sem);
-
-- rd->magic = JFFS2_MAGIC_BITMASK;
-- rd->nodetype = JFFS2_NODETYPE_DIRENT;
-- rd->totlen = sizeof(*rd) + namelen;
-- rd->hdr_crc = crc32(0, rd, sizeof(struct jffs2_unknown_node)-4);
--
-- rd->pino = dir_i->i_ino;
-- rd->version = ++dir_f->highest_version;
-- rd->ino = inode->i_ino;
-- rd->mctime = CURRENT_TIME;
-+ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
-+ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
-+ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
-+
-+ rd->pino = cpu_to_je32(dir_i->i_ino);
-+ rd->version = cpu_to_je32(++dir_f->highest_version);
-+ rd->ino = cpu_to_je32(inode->i_ino);
-+ rd->mctime = cpu_to_je32(get_seconds());
- rd->nsize = namelen;
-
- /* XXX: This is ugly. */
- rd->type = (mode & S_IFMT) >> 12;
-
-- rd->node_crc = crc32(0, rd, sizeof(*rd)-8);
-- rd->name_crc = crc32(0, dentry->d_name.name, namelen);
--
-- fd = jffs2_write_dirent(dir_i, rd, dentry->d_name.name, namelen, phys_ofs, &writtenlen);
-+ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
-+ rd->name_crc = cpu_to_je32(crc32(0, dentry->d_name.name, namelen));
-
-- jffs2_complete_reservation(c);
-+ fd = jffs2_write_dirent(c, dir_f, rd, dentry->d_name.name, namelen, phys_ofs, ALLOC_NORMAL);
-
- if (IS_ERR(fd)) {
- /* dirent failed to write. Delete the inode normally
- as if it were the final unlink() */
-+ jffs2_complete_reservation(c);
- jffs2_free_raw_dirent(rd);
- up(&dir_f->sem);
- jffs2_clear_inode(inode);
- return PTR_ERR(fd);
- }
-
-- dir_i->i_mtime = dir_i->i_ctime = rd->mctime;
-+ dir_i->i_mtime = dir_i->i_ctime = ITIME(je32_to_cpu(rd->mctime));
-
- jffs2_free_raw_dirent(rd);
-
- /* Link the fd into the inode's list, obsoleting an old
- one if necessary. */
- jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-+
- up(&dir_f->sem);
-+ jffs2_complete_reservation(c);
-
- d_instantiate(dentry, inode);
-
-@@ -944,7 +710,9 @@
- struct inode *new_dir_i, struct dentry *new_dentry)
- {
- int ret;
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
- struct jffs2_inode_info *victim_f = NULL;
-+ uint8_t type;
-
- /* The VFS will check for us and prevent trying to rename a
- * file over a directory and vice versa, but if it's a directory,
-@@ -973,7 +741,15 @@
- */
-
- /* Make a hard link */
-- ret = jffs2_do_link(old_dentry, new_dir_i, new_dentry, 1);
-+
-+ /* XXX: This is ugly */
-+ type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
-+ if (!type) type = DT_REG;
-+
-+ ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i),
-+ old_dentry->d_inode->i_ino, type,
-+ new_dentry->d_name.name, new_dentry->d_name.len);
-+
- if (ret)
- return ret;
-
-@@ -989,22 +765,36 @@
- }
- }
-
-+ /* If it was a directory we moved, and there was no victim,
-+ increase i_nlink on its new parent */
-+ if (S_ISDIR(old_dentry->d_inode->i_mode) && !victim_f)
-+ new_dir_i->i_nlink++;
-+
- /* Unlink the original */
-- ret = jffs2_do_unlink(old_dir_i, old_dentry, 1);
-+ ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
-+ old_dentry->d_name.name, old_dentry->d_name.len, NULL);
-+
-+ /* We don't touch inode->i_nlink */
-
- if (ret) {
- /* Oh shit. We really ought to make a single node which can do both atomically */
- struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_dentry->d_inode);
- down(&f->sem);
-+ old_dentry->d_inode->i_nlink++;
- if (f->inocache)
-- old_dentry->d_inode->i_nlink = f->inocache->nlink++;
-+ f->inocache->nlink++;
- up(&f->sem);
-
- printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ret);
- /* Might as well let the VFS know */
- d_instantiate(new_dentry, old_dentry->d_inode);
- atomic_inc(&old_dentry->d_inode->i_count);
-- }
- return ret;
-+ }
-+
-+ if (S_ISDIR(old_dentry->d_inode->i_mode))
-+ old_dir_i->i_nlink--;
-+
-+ return 0;
- }
-
-diff -Nurb linux-mips-2.4.27/fs/jffs2/erase.c linux/fs/jffs2/erase.c
---- linux-mips-2.4.27/fs/jffs2/erase.c 2003-11-17 02:07:44.000000000 +0100
-+++ linux/fs/jffs2/erase.c 2004-11-19 10:25:12.099169392 +0100
-@@ -1,68 +1,60 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-+
- #include <linux/kernel.h>
- #include <linux/slab.h>
- #include <linux/mtd/mtd.h>
--#include <linux/jffs2.h>
--#include <linux/interrupt.h>
--#include "nodelist.h"
-+#include <linux/compiler.h>
- #include <linux/crc32.h>
-+#include <linux/sched.h>
-+#include <linux/pagemap.h>
-+#include "nodelist.h"
-
- struct erase_priv_struct {
- struct jffs2_eraseblock *jeb;
- struct jffs2_sb_info *c;
- };
-
-+#ifndef __ECOS
- static void jffs2_erase_callback(struct erase_info *);
-+#endif
-+static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
- static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-
- void jffs2_erase_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
- {
-- struct erase_info *instr;
- int ret;
-+#ifdef __ECOS
-+ ret = jffs2_flash_erase(c, jeb);
-+ if (!ret) {
-+ jffs2_erase_succeeded(c, jeb);
-+ return;
-+ }
-+#else /* Linux */
-+ struct erase_info *instr;
-
- instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL);
- if (!instr) {
- printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n");
-- spin_lock_bh(&c->erase_completion_lock);
-+ spin_lock(&c->erase_completion_lock);
- list_del(&jeb->list);
- list_add(&jeb->list, &c->erase_pending_list);
- c->erasing_size -= c->sector_size;
-- spin_unlock_bh(&c->erase_completion_lock);
-+ c->dirty_size += c->sector_size;
-+ jeb->dirty_size = c->sector_size;
-+ spin_unlock(&c->erase_completion_lock);
- return;
- }
-
-@@ -77,19 +69,27 @@
- ((struct erase_priv_struct *)instr->priv)->jeb = jeb;
- ((struct erase_priv_struct *)instr->priv)->c = c;
-
-+ /* NAND , read out the fail counter, if possible */
-+ if (!jffs2_can_mark_obsolete(c))
-+ jffs2_nand_read_failcnt(c,jeb);
-+
- ret = c->mtd->erase(c->mtd, instr);
-- if (!ret) {
-+ if (!ret)
- return;
-- }
-+
-+ kfree(instr);
-+#endif /* __ECOS */
-+
- if (ret == -ENOMEM || ret == -EAGAIN) {
- /* Erase failed immediately. Refile it on the list */
- D1(printk(KERN_DEBUG "Erase at 0x%08x failed: %d. Refiling on erase_pending_list\n", jeb->offset, ret));
-- spin_lock_bh(&c->erase_completion_lock);
-+ spin_lock(&c->erase_completion_lock);
- list_del(&jeb->list);
- list_add(&jeb->list, &c->erase_pending_list);
- c->erasing_size -= c->sector_size;
-- spin_unlock_bh(&c->erase_completion_lock);
-- kfree(instr);
-+ c->dirty_size += c->sector_size;
-+ jeb->dirty_size = c->sector_size;
-+ spin_unlock(&c->erase_completion_lock);
- return;
- }
-
-@@ -97,74 +97,101 @@
- printk(KERN_WARNING "Erase at 0x%08x failed immediately: -EROFS. Is the sector locked?\n", jeb->offset);
- else
- printk(KERN_WARNING "Erase at 0x%08x failed immediately: errno %d\n", jeb->offset, ret);
-- spin_lock_bh(&c->erase_completion_lock);
-- list_del(&jeb->list);
-- list_add(&jeb->list, &c->bad_list);
-- c->nr_erasing_blocks--;
-- c->bad_size += c->sector_size;
-- c->erasing_size -= c->sector_size;
-- spin_unlock_bh(&c->erase_completion_lock);
-- wake_up(&c->erase_wait);
-- kfree(instr);
-+
-+ jffs2_erase_failed(c, jeb);
- }
-
--void jffs2_erase_pending_blocks(struct jffs2_sb_info *c)
-+void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count)
- {
- struct jffs2_eraseblock *jeb;
-
-- spin_lock_bh(&c->erase_completion_lock);
-- while (!list_empty(&c->erase_pending_list)) {
-+ down(&c->erase_free_sem);
-
-- jeb = list_entry(c->erase_pending_list.next, struct jffs2_eraseblock, list);
-+ spin_lock(&c->erase_completion_lock);
-
-- D1(printk(KERN_DEBUG "Starting erase of pending block 0x%08x\n", jeb->offset));
-+ while (!list_empty(&c->erase_complete_list) ||
-+ !list_empty(&c->erase_pending_list)) {
-
-+ if (!list_empty(&c->erase_complete_list)) {
-+ jeb = list_entry(c->erase_complete_list.next, struct jffs2_eraseblock, list);
-+ list_del(&jeb->list);
-+ spin_unlock(&c->erase_completion_lock);
-+ jffs2_mark_erased_block(c, jeb);
-+
-+ if (!--count) {
-+ D1(printk(KERN_DEBUG "Count reached. jffs2_erase_pending_blocks leaving\n"));
-+ goto done;
-+ }
-+
-+ } else if (!list_empty(&c->erase_pending_list)) {
-+ jeb = list_entry(c->erase_pending_list.next, struct jffs2_eraseblock, list);
-+ D1(printk(KERN_DEBUG "Starting erase of pending block 0x%08x\n", jeb->offset));
- list_del(&jeb->list);
- c->erasing_size += c->sector_size;
-+ c->wasted_size -= jeb->wasted_size;
- c->free_size -= jeb->free_size;
- c->used_size -= jeb->used_size;
- c->dirty_size -= jeb->dirty_size;
-- jeb->used_size = jeb->dirty_size = jeb->free_size = 0;
-+ jeb->wasted_size = jeb->used_size = jeb->dirty_size = jeb->free_size = 0;
- jffs2_free_all_node_refs(c, jeb);
- list_add(&jeb->list, &c->erasing_list);
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
-
- jffs2_erase_block(c, jeb);
-+
-+ } else {
-+ BUG();
-+ }
-+
- /* Be nice */
-- if (current->need_resched)
-- schedule();
-- spin_lock_bh(&c->erase_completion_lock);
-+ cond_resched();
-+ spin_lock(&c->erase_completion_lock);
- }
-- spin_unlock_bh(&c->erase_completion_lock);
-+
-+ spin_unlock(&c->erase_completion_lock);
-+ done:
- D1(printk(KERN_DEBUG "jffs2_erase_pending_blocks completed\n"));
-+
-+ up(&c->erase_free_sem);
-+}
-+
-+static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
-+{
-+ D1(printk(KERN_DEBUG "Erase completed successfully at 0x%08x\n", jeb->offset));
-+ spin_lock(&c->erase_completion_lock);
-+ list_del(&jeb->list);
-+ list_add_tail(&jeb->list, &c->erase_complete_list);
-+ spin_unlock(&c->erase_completion_lock);
-+ /* Ensure that kupdated calls us again to mark them clean */
-+ jffs2_erase_pending_trigger(c);
- }
-
-+static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
-+{
-+ spin_lock(&c->erase_completion_lock);
-+ c->erasing_size -= c->sector_size;
-+ c->bad_size += c->sector_size;
-+ list_del(&jeb->list);
-+ list_add(&jeb->list, &c->bad_list);
-+ c->nr_erasing_blocks--;
-+ spin_unlock(&c->erase_completion_lock);
-+ wake_up(&c->erase_wait);
-+}
-
-+#ifndef __ECOS
- static void jffs2_erase_callback(struct erase_info *instr)
- {
- struct erase_priv_struct *priv = (void *)instr->priv;
-
- if(instr->state != MTD_ERASE_DONE) {
- printk(KERN_WARNING "Erase at 0x%08x finished, but state != MTD_ERASE_DONE. State is 0x%x instead.\n", instr->addr, instr->state);
-- spin_lock(&priv->c->erase_completion_lock);
-- priv->c->erasing_size -= priv->c->sector_size;
-- priv->c->bad_size += priv->c->sector_size;
-- list_del(&priv->jeb->list);
-- list_add(&priv->jeb->list, &priv->c->bad_list);
-- priv->c->nr_erasing_blocks--;
-- spin_unlock(&priv->c->erase_completion_lock);
-- wake_up(&priv->c->erase_wait);
-+ jffs2_erase_failed(priv->c, priv->jeb);
- } else {
-- D1(printk(KERN_DEBUG "Erase completed successfully at 0x%08x\n", instr->addr));
-- spin_lock(&priv->c->erase_completion_lock);
-- list_del(&priv->jeb->list);
-- list_add_tail(&priv->jeb->list, &priv->c->erase_complete_list);
-- spin_unlock(&priv->c->erase_completion_lock);
-+ jffs2_erase_succeeded(priv->c, priv->jeb);
- }
-- /* Make sure someone picks up the block off the erase_complete list */
-- OFNI_BS_2SFFJ(priv->c)->s_dirt = 1;
- kfree(instr);
- }
-+#endif /* !__ECOS */
-
- /* Hmmm. Maybe we should accept the extra space it takes and make
- this a standard doubly-linked list? */
-@@ -221,7 +248,7 @@
- this = ic->nodes;
-
- while(this) {
-- printk( "0x%08x(%d)->", this->flash_offset & ~3, this->flash_offset &3);
-+ printk( "0x%08x(%d)->", ref_offset(this), ref_flags(this));
- if (++i == 5) {
- printk("\n" KERN_DEBUG);
- i=0;
-@@ -256,54 +283,43 @@
- jeb->last_node = NULL;
- }
-
--void jffs2_erase_pending_trigger(struct jffs2_sb_info *c)
-+static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
- {
-- OFNI_BS_2SFFJ(c)->s_dirt = 1;
--}
--
--void jffs2_mark_erased_blocks(struct jffs2_sb_info *c)
--{
-- static struct jffs2_unknown_node marker = {JFFS2_MAGIC_BITMASK, JFFS2_NODETYPE_CLEANMARKER, sizeof(struct jffs2_unknown_node)};
-- struct jffs2_eraseblock *jeb;
-- struct jffs2_raw_node_ref *marker_ref;
-+ struct jffs2_raw_node_ref *marker_ref = NULL;
- unsigned char *ebuf;
-- ssize_t retlen;
-+ size_t retlen;
- int ret;
-
-- marker.hdr_crc = crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4);
--
-- spin_lock_bh(&c->erase_completion_lock);
-- while (!list_empty(&c->erase_complete_list)) {
-- jeb = list_entry(c->erase_complete_list.next, struct jffs2_eraseblock, list);
-- list_del(&jeb->list);
-- spin_unlock_bh(&c->erase_completion_lock);
--
-+ if (!jffs2_cleanmarker_oob(c)) {
- marker_ref = jffs2_alloc_raw_node_ref();
- if (!marker_ref) {
- printk(KERN_WARNING "Failed to allocate raw node ref for clean marker\n");
-- /* Come back later */
-+ /* Stick it back on the list from whence it came and come back later */
- jffs2_erase_pending_trigger(c);
-+ spin_lock(&c->erase_completion_lock);
-+ list_add(&jeb->list, &c->erase_complete_list);
-+ spin_unlock(&c->erase_completion_lock);
- return;
- }
--
-+ }
- ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
- if (!ebuf) {
- printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Assuming it worked\n", jeb->offset);
- } else {
-- __u32 ofs = jeb->offset;
-+ uint32_t ofs = jeb->offset;
-
- D1(printk(KERN_DEBUG "Verifying erase at 0x%08x\n", jeb->offset));
- while(ofs < jeb->offset + c->sector_size) {
-- __u32 readlen = min((__u32)PAGE_SIZE, jeb->offset + c->sector_size - ofs);
-+ uint32_t readlen = min((uint32_t)PAGE_SIZE, jeb->offset + c->sector_size - ofs);
- int i;
-
-- ret = c->mtd->read(c->mtd, ofs, readlen, &retlen, ebuf);
-- if (ret < 0) {
-+ ret = jffs2_flash_read(c, ofs, readlen, &retlen, ebuf);
-+ if (ret) {
- printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret);
- goto bad;
- }
- if (retlen != readlen) {
-- printk(KERN_WARNING "Short read from newly-erased block at 0x%08x. Wanted %d, got %d\n", ofs, readlen, retlen);
-+ printk(KERN_WARNING "Short read from newly-erased block at 0x%08x. Wanted %d, got %zd\n", ofs, readlen, retlen);
- goto bad;
- }
- for (i=0; i<readlen; i += sizeof(unsigned long)) {
-@@ -312,62 +328,89 @@
- if (datum + 1) {
- printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", datum, ofs + i);
- bad:
-+ if (!jffs2_cleanmarker_oob(c))
- jffs2_free_raw_node_ref(marker_ref);
-+ else
-+ jffs2_write_nand_badblock( c ,jeb );
- kfree(ebuf);
- bad2:
-- spin_lock_bh(&c->erase_completion_lock);
-+ spin_lock(&c->erase_completion_lock);
- c->erasing_size -= c->sector_size;
- c->bad_size += c->sector_size;
-
- list_add_tail(&jeb->list, &c->bad_list);
- c->nr_erasing_blocks--;
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
- wake_up(&c->erase_wait);
- return;
- }
- }
- ofs += readlen;
-+ cond_resched();
- }
- kfree(ebuf);
- }
-
- /* Write the erase complete marker */
- D1(printk(KERN_DEBUG "Writing erased marker to block at 0x%08x\n", jeb->offset));
-- ret = c->mtd->write(c->mtd, jeb->offset, sizeof(marker), &retlen, (char *)&marker);
-+ if (jffs2_cleanmarker_oob(c)) {
-+
-+ if (jffs2_write_nand_cleanmarker(c, jeb))
-+ goto bad2;
-+
-+ jeb->first_node = jeb->last_node = NULL;
-+
-+ jeb->free_size = c->sector_size;
-+ jeb->used_size = 0;
-+ jeb->dirty_size = 0;
-+ jeb->wasted_size = 0;
-+ } else {
-+ struct jffs2_unknown_node marker = {
-+ .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
-+ .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
-+ .totlen = cpu_to_je32(c->cleanmarker_size)
-+ };
-+
-+ marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4));
-+
-+ /* We only write the header; the rest was noise or padding anyway */
-+ ret = jffs2_flash_write(c, jeb->offset, sizeof(marker), &retlen, (char *)&marker);
- if (ret) {
- printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n",
- jeb->offset, ret);
- goto bad2;
- }
- if (retlen != sizeof(marker)) {
-- printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %d, got %d\n",
-+ printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %d, got %zd\n",
- jeb->offset, sizeof(marker), retlen);
- goto bad2;
- }
-
- marker_ref->next_in_ino = NULL;
- marker_ref->next_phys = NULL;
-- marker_ref->flash_offset = jeb->offset;
-- marker_ref->totlen = PAD(sizeof(marker));
-+ marker_ref->flash_offset = jeb->offset | REF_NORMAL;
-+ marker_ref->__totlen = c->cleanmarker_size;
-
- jeb->first_node = jeb->last_node = marker_ref;
-
-- jeb->free_size = c->sector_size - marker_ref->totlen;
-- jeb->used_size = marker_ref->totlen;
-+ jeb->free_size = c->sector_size - c->cleanmarker_size;
-+ jeb->used_size = c->cleanmarker_size;
- jeb->dirty_size = 0;
-+ jeb->wasted_size = 0;
-+ }
-
-- spin_lock_bh(&c->erase_completion_lock);
-+ spin_lock(&c->erase_completion_lock);
- c->erasing_size -= c->sector_size;
- c->free_size += jeb->free_size;
- c->used_size += jeb->used_size;
-
- ACCT_SANITY_CHECK(c,jeb);
-- ACCT_PARANOIA_CHECK(jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-
- list_add_tail(&jeb->list, &c->free_list);
- c->nr_erasing_blocks--;
- c->nr_free_blocks++;
-+ spin_unlock(&c->erase_completion_lock);
- wake_up(&c->erase_wait);
-- }
-- spin_unlock_bh(&c->erase_completion_lock);
- }
-+
-diff -Nurb linux-mips-2.4.27/fs/jffs2/file.c linux/fs/jffs2/file.c
---- linux-mips-2.4.27/fs/jffs2/file.c 2003-11-17 02:07:44.000000000 +0100
-+++ linux/fs/jffs2/file.c 2004-11-19 10:25:12.101169088 +0100
-@@ -1,319 +1,106 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
-+#include <linux/version.h>
- #include <linux/kernel.h>
--#include <linux/mtd/compatmac.h> /* for min() */
- #include <linux/slab.h>
- #include <linux/fs.h>
-+#include <linux/time.h>
- #include <linux/pagemap.h>
-+#include <linux/highmem.h>
-+#include <linux/crc32.h>
- #include <linux/jffs2.h>
- #include "nodelist.h"
--#include <linux/crc32.h>
-
- extern int generic_file_open(struct inode *, struct file *) __attribute__((weak));
- extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin) __attribute__((weak));
-
-
--int jffs2_null_fsync(struct file *filp, struct dentry *dentry, int datasync)
-+int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync)
- {
-- /* Move along. Nothing to see here */
-+ struct inode *inode = dentry->d_inode;
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-+
-+ /* Trigger GC to flush any pending writes for this inode */
-+ jffs2_flush_wbuf_gc(c, inode->i_ino);
-+
- return 0;
- }
-
- struct file_operations jffs2_file_operations =
- {
-- llseek: generic_file_llseek,
-- open: generic_file_open,
-- read: generic_file_read,
-- write: generic_file_write,
-- ioctl: jffs2_ioctl,
-- mmap: generic_file_mmap,
-- fsync: jffs2_null_fsync
-+ .llseek = generic_file_llseek,
-+ .open = generic_file_open,
-+ .read = generic_file_read,
-+ .write = generic_file_write,
-+ .ioctl = jffs2_ioctl,
-+ .mmap = generic_file_readonly_mmap,
-+ .fsync = jffs2_fsync,
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,29)
-+ .sendfile = generic_file_sendfile
-+#endif
- };
-
- /* jffs2_file_inode_operations */
-
- struct inode_operations jffs2_file_inode_operations =
- {
-- setattr: jffs2_setattr
-+ .setattr = jffs2_setattr
- };
-
- struct address_space_operations jffs2_file_address_operations =
- {
-- readpage: jffs2_readpage,
-- prepare_write: jffs2_prepare_write,
-- commit_write: jffs2_commit_write
-+ .readpage = jffs2_readpage,
-+ .prepare_write =jffs2_prepare_write,
-+ .commit_write = jffs2_commit_write
- };
-
--int jffs2_setattr (struct dentry *dentry, struct iattr *iattr)
--{
-- struct jffs2_full_dnode *old_metadata, *new_metadata;
-- struct inode *inode = dentry->d_inode;
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
-- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-- struct jffs2_raw_inode *ri;
-- unsigned short dev;
-- unsigned char *mdata = NULL;
-- int mdatalen = 0;
-- unsigned int ivalid;
-- __u32 phys_ofs, alloclen;
-- int ret;
-- D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino));
-- ret = inode_change_ok(inode, iattr);
-- if (ret)
-- return ret;
--
-- /* Special cases - we don't want more than one data node
-- for these types on the medium at any time. So setattr
-- must read the original data associated with the node
-- (i.e. the device numbers or the target name) and write
-- it out again with the appropriate data attached */
-- if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
-- /* For these, we don't actually need to read the old node */
-- dev = (MAJOR(to_kdev_t(dentry->d_inode->i_rdev)) << 8) |
-- MINOR(to_kdev_t(dentry->d_inode->i_rdev));
-- mdata = (char *)&dev;
-- mdatalen = sizeof(dev);
-- D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen));
-- } else if (S_ISLNK(inode->i_mode)) {
-- mdatalen = f->metadata->size;
-- mdata = kmalloc(f->metadata->size, GFP_USER);
-- if (!mdata)
-- return -ENOMEM;
-- ret = jffs2_read_dnode(c, f->metadata, mdata, 0, mdatalen);
-- if (ret) {
-- kfree(mdata);
-- return ret;
-- }
-- D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen));
-- }
--
-- ri = jffs2_alloc_raw_inode();
-- if (!ri) {
-- if (S_ISLNK(inode->i_mode))
-- kfree(mdata);
-- return -ENOMEM;
-- }
--
-- ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, ALLOC_NORMAL);
-- if (ret) {
-- jffs2_free_raw_inode(ri);
-- if (S_ISLNK(inode->i_mode))
-- kfree(mdata);
-- return ret;
-- }
-- down(&f->sem);
-- ivalid = iattr->ia_valid;
--
-- ri->magic = JFFS2_MAGIC_BITMASK;
-- ri->nodetype = JFFS2_NODETYPE_INODE;
-- ri->totlen = sizeof(*ri) + mdatalen;
-- ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
--
-- ri->ino = inode->i_ino;
-- ri->version = ++f->highest_version;
--
-- ri->mode = (ivalid & ATTR_MODE)?iattr->ia_mode:inode->i_mode;
-- ri->uid = (ivalid & ATTR_UID)?iattr->ia_uid:inode->i_uid;
-- ri->gid = (ivalid & ATTR_GID)?iattr->ia_gid:inode->i_gid;
--
-- if (ivalid & ATTR_MODE && ri->mode & S_ISGID &&
-- !in_group_p(ri->gid) && !capable(CAP_FSETID))
-- ri->mode &= ~S_ISGID;
--
-- ri->isize = (ivalid & ATTR_SIZE)?iattr->ia_size:inode->i_size;
-- ri->atime = (ivalid & ATTR_ATIME)?iattr->ia_atime:inode->i_atime;
-- ri->mtime = (ivalid & ATTR_MTIME)?iattr->ia_mtime:inode->i_mtime;
-- ri->ctime = (ivalid & ATTR_CTIME)?iattr->ia_ctime:inode->i_ctime;
--
-- ri->offset = 0;
-- ri->csize = ri->dsize = mdatalen;
-- ri->compr = JFFS2_COMPR_NONE;
-- if (inode->i_size < ri->isize) {
-- /* It's an extension. Make it a hole node */
-- ri->compr = JFFS2_COMPR_ZERO;
-- ri->dsize = ri->isize - inode->i_size;
-- ri->offset = inode->i_size;
-- }
-- ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
-- if (mdatalen)
-- ri->data_crc = crc32(0, mdata, mdatalen);
-- else
-- ri->data_crc = 0;
--
-- new_metadata = jffs2_write_dnode(inode, ri, mdata, mdatalen, phys_ofs, NULL);
-- if (S_ISLNK(inode->i_mode))
-- kfree(mdata);
--
-- jffs2_complete_reservation(c);
--
-- if (IS_ERR(new_metadata)) {
-- jffs2_free_raw_inode(ri);
-- up(&f->sem);
-- return PTR_ERR(new_metadata);
-- }
-- /* It worked. Update the inode */
-- inode->i_atime = ri->atime;
-- inode->i_ctime = ri->ctime;
-- inode->i_mtime = ri->mtime;
-- inode->i_mode = ri->mode;
-- inode->i_uid = ri->uid;
-- inode->i_gid = ri->gid;
--
--
-- old_metadata = f->metadata;
--
-- if (inode->i_size > ri->isize) {
-- vmtruncate(inode, ri->isize);
-- jffs2_truncate_fraglist (c, &f->fraglist, ri->isize);
-- }
--
-- if (inode->i_size < ri->isize) {
-- jffs2_add_full_dnode_to_inode(c, f, new_metadata);
-- inode->i_size = ri->isize;
-- f->metadata = NULL;
-- } else {
-- f->metadata = new_metadata;
-- }
-- if (old_metadata) {
-- jffs2_mark_node_obsolete(c, old_metadata->raw);
-- jffs2_free_full_dnode(old_metadata);
-- }
-- jffs2_free_raw_inode(ri);
-- up(&f->sem);
-- return 0;
--}
--
- int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg)
- {
- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-- struct jffs2_node_frag *frag = f->fraglist;
-- __u32 offset = pg->index << PAGE_CACHE_SHIFT;
-- __u32 end = offset + PAGE_CACHE_SIZE;
- unsigned char *pg_buf;
- int ret;
-
-- D1(printk(KERN_DEBUG "jffs2_do_readpage_nolock(): ino #%lu, page at offset 0x%x\n", inode->i_ino, offset));
-+ D2(printk(KERN_DEBUG "jffs2_do_readpage_nolock(): ino #%lu, page at offset 0x%lx\n", inode->i_ino, pg->index << PAGE_CACHE_SHIFT));
-
- if (!PageLocked(pg))
- PAGE_BUG(pg);
-
-- while(frag && frag->ofs + frag->size <= offset) {
-- // D1(printk(KERN_DEBUG "skipping frag %d-%d; before the region we care about\n", frag->ofs, frag->ofs + frag->size));
-- frag = frag->next;
-- }
--
- pg_buf = kmap(pg);
-+ /* FIXME: Can kmap fail? */
-
-- /* XXX FIXME: Where a single physical node actually shows up in two
-- frags, we read it twice. Don't do that. */
-- /* Now we're pointing at the first frag which overlaps our page */
-- while(offset < end) {
-- D2(printk(KERN_DEBUG "jffs2_readpage: offset %d, end %d\n", offset, end));
-- if (!frag || frag->ofs > offset) {
-- __u32 holesize = end - offset;
-- if (frag) {
-- D1(printk(KERN_NOTICE "Eep. Hole in ino %ld fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", inode->i_ino, frag->ofs, offset));
-- holesize = min(holesize, frag->ofs - offset);
-- D1(jffs2_print_frag_list(f));
-- }
-- D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize));
-- memset(pg_buf, 0, holesize);
-- pg_buf += holesize;
-- offset += holesize;
-- continue;
-- } else if (frag->ofs < offset && (offset & (PAGE_CACHE_SIZE-1)) != 0) {
-- D1(printk(KERN_NOTICE "Eep. Overlap in ino #%ld fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n",
-- inode->i_ino, frag->ofs, offset));
-- D1(jffs2_print_frag_list(f));
-- memset(pg_buf, 0, end - offset);
-- ClearPageUptodate(pg);
-- SetPageError(pg);
-- kunmap(pg);
-- return -EIO;
-- } else if (!frag->node) {
-- __u32 holeend = min(end, frag->ofs + frag->size);
-- D1(printk(KERN_DEBUG "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n", offset, holeend, frag->ofs, frag->ofs + frag->size));
-- memset(pg_buf, 0, holeend - offset);
-- pg_buf += holeend - offset;
-- offset = holeend;
-- frag = frag->next;
-- continue;
-- } else {
-- __u32 readlen;
-- __u32 fragofs; /* offset within the frag to start reading */
-+ ret = jffs2_read_inode_range(c, f, pg_buf, pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE);
-
-- fragofs = offset - frag->ofs;
-- readlen = min(frag->size - fragofs, end - offset);
-- D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%x\n", frag->ofs+fragofs,
-- fragofs+frag->ofs+readlen, frag->node->raw->flash_offset & ~3));
-- ret = jffs2_read_dnode(c, frag->node, pg_buf, fragofs + frag->ofs - frag->node->ofs, readlen);
-- D2(printk(KERN_DEBUG "node read done\n"));
- if (ret) {
-- D1(printk(KERN_DEBUG"jffs2_readpage error %d\n",ret));
-- memset(pg_buf, 0, readlen);
- ClearPageUptodate(pg);
- SetPageError(pg);
-- kunmap(pg);
-- return ret;
-- }
--
-- pg_buf += readlen;
-- offset += readlen;
-- frag = frag->next;
-- D2(printk(KERN_DEBUG "node read was OK. Looping\n"));
-- }
-- }
-- D2(printk(KERN_DEBUG "readpage finishing\n"));
-+ } else {
- SetPageUptodate(pg);
- ClearPageError(pg);
-+ }
-
- flush_dcache_page(pg);
--
- kunmap(pg);
-- D1(printk(KERN_DEBUG "readpage finished\n"));
-+
-+ D2(printk(KERN_DEBUG "readpage finished\n"));
- return 0;
- }
-
- int jffs2_do_readpage_unlock(struct inode *inode, struct page *pg)
- {
- int ret = jffs2_do_readpage_nolock(inode, pg);
-- UnlockPage(pg);
-+ unlock_page(pg);
- return ret;
- }
-
-@@ -333,17 +120,17 @@
- {
- struct inode *inode = pg->mapping->host;
- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
-- __u32 pageofs = pg->index << PAGE_CACHE_SHIFT;
-+ uint32_t pageofs = pg->index << PAGE_CACHE_SHIFT;
- int ret = 0;
-
-- D1(printk(KERN_DEBUG "jffs2_prepare_write() nrpages %ld\n", inode->i_mapping->nrpages));
-+ D1(printk(KERN_DEBUG "jffs2_prepare_write()\n"));
-
- if (pageofs > inode->i_size) {
- /* Make new hole frag from old EOF to new page */
- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
- struct jffs2_raw_inode ri;
- struct jffs2_full_dnode *fn;
-- __u32 phys_ofs, alloc_len;
-+ uint32_t phys_ofs, alloc_len;
-
- D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
- (unsigned int)inode->i_size, pageofs));
-@@ -355,29 +142,30 @@
- down(&f->sem);
- memset(&ri, 0, sizeof(ri));
-
-- ri.magic = JFFS2_MAGIC_BITMASK;
-- ri.nodetype = JFFS2_NODETYPE_INODE;
-- ri.totlen = sizeof(ri);
-- ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4);
--
-- ri.ino = f->inocache->ino;
-- ri.version = ++f->highest_version;
-- ri.mode = inode->i_mode;
-- ri.uid = inode->i_uid;
-- ri.gid = inode->i_gid;
-- ri.isize = max((__u32)inode->i_size, pageofs);
-- ri.atime = ri.ctime = ri.mtime = CURRENT_TIME;
-- ri.offset = inode->i_size;
-- ri.dsize = pageofs - inode->i_size;
-- ri.csize = 0;
-+ ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
-+ ri.totlen = cpu_to_je32(sizeof(ri));
-+ ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4));
-+
-+ ri.ino = cpu_to_je32(f->inocache->ino);
-+ ri.version = cpu_to_je32(++f->highest_version);
-+ ri.mode = cpu_to_jemode(inode->i_mode);
-+ ri.uid = cpu_to_je16(inode->i_uid);
-+ ri.gid = cpu_to_je16(inode->i_gid);
-+ ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs));
-+ ri.atime = ri.ctime = ri.mtime = cpu_to_je32(get_seconds());
-+ ri.offset = cpu_to_je32(inode->i_size);
-+ ri.dsize = cpu_to_je32(pageofs - inode->i_size);
-+ ri.csize = cpu_to_je32(0);
- ri.compr = JFFS2_COMPR_ZERO;
-- ri.node_crc = crc32(0, &ri, sizeof(ri)-8);
-- ri.data_crc = 0;
-+ ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
-+ ri.data_crc = cpu_to_je32(0);
-+
-+ fn = jffs2_write_dnode(c, f, &ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
-
-- fn = jffs2_write_dnode(inode, &ri, NULL, 0, phys_ofs, NULL);
-- jffs2_complete_reservation(c);
- if (IS_ERR(fn)) {
- ret = PTR_ERR(fn);
-+ jffs2_complete_reservation(c);
- up(&f->sem);
- return ret;
- }
-@@ -391,16 +179,17 @@
- D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in prepare_write, returned %d\n", ret));
- jffs2_mark_node_obsolete(c, fn->raw);
- jffs2_free_full_dnode(fn);
-+ jffs2_complete_reservation(c);
- up(&f->sem);
- return ret;
- }
-+ jffs2_complete_reservation(c);
- inode->i_size = pageofs;
- up(&f->sem);
- }
-
--
- /* Read in the page if it wasn't already present, unless it's a whole page */
-- if (!Page_Uptodate(pg) && (start || end < PAGE_CACHE_SIZE)) {
-+ if (!PageUptodate(pg) && (start || end < PAGE_CACHE_SIZE)) {
- down(&f->sem);
- ret = jffs2_do_readpage_nolock(inode, pg);
- up(&f->sem);
-@@ -417,14 +206,12 @@
- struct inode *inode = pg->mapping->host;
- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-- __u32 newsize = max_t(__u32, filp->f_dentry->d_inode->i_size, (pg->index << PAGE_CACHE_SHIFT) + end);
-- __u32 file_ofs = (pg->index << PAGE_CACHE_SHIFT);
-- __u32 writelen = min((__u32)PAGE_CACHE_SIZE, newsize - file_ofs);
- struct jffs2_raw_inode *ri;
- int ret = 0;
-- ssize_t writtenlen = 0;
-+ uint32_t writtenlen = 0;
-
-- D1(printk(KERN_DEBUG "jffs2_commit_write(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n", inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags));
-+ D1(printk(KERN_DEBUG "jffs2_commit_write(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n",
-+ inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags));
-
- if (!start && end == PAGE_CACHE_SIZE) {
- /* We need to avoid deadlock with page_cache_read() in
-@@ -435,109 +222,47 @@
- }
-
- ri = jffs2_alloc_raw_inode();
-- if (!ri)
-- return -ENOMEM;
--
-- while(writelen) {
-- struct jffs2_full_dnode *fn;
-- unsigned char *comprbuf = NULL;
-- unsigned char comprtype = JFFS2_COMPR_NONE;
-- __u32 phys_ofs, alloclen;
-- __u32 datalen, cdatalen;
-
-- D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, file_ofs));
--
-- ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL);
-- if (ret) {
-- SetPageError(pg);
-- D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret));
-- break;
-+ if (!ri) {
-+ D1(printk(KERN_DEBUG "jffs2_commit_write(): Allocation of raw inode failed\n"));
-+ return -ENOMEM;
- }
-- down(&f->sem);
-- datalen = writelen;
-- cdatalen = min(alloclen - sizeof(*ri), writelen);
--
-- comprbuf = kmalloc(cdatalen, GFP_KERNEL);
-- if (comprbuf) {
-- comprtype = jffs2_compress(page_address(pg)+ (file_ofs & (PAGE_CACHE_SIZE-1)), comprbuf, &datalen, &cdatalen);
-- }
-- if (comprtype == JFFS2_COMPR_NONE) {
-- /* Either compression failed, or the allocation of comprbuf failed */
-- if (comprbuf)
-- kfree(comprbuf);
-- comprbuf = page_address(pg) + (file_ofs & (PAGE_CACHE_SIZE -1));
-- datalen = cdatalen;
-- }
-- /* Now comprbuf points to the data to be written, be it compressed or not.
-- comprtype holds the compression type, and comprtype == JFFS2_COMPR_NONE means
-- that the comprbuf doesn't need to be kfree()d.
-- */
--
-- ri->magic = JFFS2_MAGIC_BITMASK;
-- ri->nodetype = JFFS2_NODETYPE_INODE;
-- ri->totlen = sizeof(*ri) + cdatalen;
-- ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
--
-- ri->ino = inode->i_ino;
-- ri->version = ++f->highest_version;
-- ri->mode = inode->i_mode;
-- ri->uid = inode->i_uid;
-- ri->gid = inode->i_gid;
-- ri->isize = max((__u32)inode->i_size, file_ofs + datalen);
-- ri->atime = ri->ctime = ri->mtime = CURRENT_TIME;
-- ri->offset = file_ofs;
-- ri->csize = cdatalen;
-- ri->dsize = datalen;
-- ri->compr = comprtype;
-- ri->node_crc = crc32(0, ri, sizeof(*ri)-8);
-- ri->data_crc = crc32(0, comprbuf, cdatalen);
--
-- fn = jffs2_write_dnode(inode, ri, comprbuf, cdatalen, phys_ofs, NULL);
-
-- jffs2_complete_reservation(c);
-+ /* Set the fields that the generic jffs2_write_inode_range() code can't find */
-+ ri->ino = cpu_to_je32(inode->i_ino);
-+ ri->mode = cpu_to_jemode(inode->i_mode);
-+ ri->uid = cpu_to_je16(inode->i_uid);
-+ ri->gid = cpu_to_je16(inode->i_gid);
-+ ri->isize = cpu_to_je32((uint32_t)inode->i_size);
-+ ri->atime = ri->ctime = ri->mtime = cpu_to_je32(get_seconds());
-+
-+ /* In 2.4, it was already kmapped by generic_file_write(). Doesn't
-+ hurt to do it again. The alternative is ifdefs, which are ugly. */
-+ kmap(pg);
-+
-+ ret = jffs2_write_inode_range(c, f, ri, page_address(pg) + start,
-+ (pg->index << PAGE_CACHE_SHIFT) + start,
-+ end - start, &writtenlen);
-
-- if (comprtype != JFFS2_COMPR_NONE)
-- kfree(comprbuf);
-+ kunmap(pg);
-
-- if (IS_ERR(fn)) {
-- ret = PTR_ERR(fn);
-- up(&f->sem);
-- SetPageError(pg);
-- break;
-- }
-- ret = jffs2_add_full_dnode_to_inode(c, f, fn);
-- if (f->metadata) {
-- jffs2_mark_node_obsolete(c, f->metadata->raw);
-- jffs2_free_full_dnode(f->metadata);
-- f->metadata = NULL;
-- }
-- up(&f->sem);
- if (ret) {
-- /* Eep */
-- D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n", ret));
-- jffs2_mark_node_obsolete(c, fn->raw);
-- jffs2_free_full_dnode(fn);
-+ /* There was an error writing. */
- SetPageError(pg);
-- break;
- }
-- inode->i_size = ri->isize;
-+
-+ if (writtenlen) {
-+ if (inode->i_size < (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen) {
-+ inode->i_size = (pg->index << PAGE_CACHE_SHIFT) + start + writtenlen;
- inode->i_blocks = (inode->i_size + 511) >> 9;
-- inode->i_ctime = inode->i_mtime = ri->ctime;
-- if (!datalen) {
-- printk(KERN_WARNING "Eep. We didn't actually write any bloody data\n");
-- ret = -EIO;
-- SetPageError(pg);
-- break;
-+
-+ inode->i_ctime = inode->i_mtime = ITIME(je32_to_cpu(ri->ctime));
- }
-- D1(printk(KERN_DEBUG "increasing writtenlen by %d\n", datalen));
-- writtenlen += datalen;
-- file_ofs += datalen;
-- writelen -= datalen;
- }
-
- jffs2_free_raw_inode(ri);
-
-- if (writtenlen < end) {
-+ if (start+writtenlen < end) {
- /* generic_file_write has written more to the page cache than we've
- actually written to the medium. Mark the page !Uptodate so that
- it gets reread */
-@@ -545,13 +270,7 @@
- SetPageError(pg);
- ClearPageUptodate(pg);
- }
-- if (writtenlen <= start) {
-- /* We didn't even get to the start of the affected part */
-- ret = ret?ret:-ENOSPC;
-- D1(printk(KERN_DEBUG "jffs2_commit_write(): Only %x bytes written to page. start (%x) not reached, returning %d\n", writtenlen, start, ret));
-- }
-- writtenlen = min(end-start, writtenlen-start);
-
-- D1(printk(KERN_DEBUG "jffs2_commit_write() returning %d. nrpages is %ld\n",writtenlen?writtenlen:ret, inode->i_mapping->nrpages));
-+ D1(printk(KERN_DEBUG "jffs2_commit_write() returning %d\n",writtenlen?writtenlen:ret));
- return writtenlen?writtenlen:ret;
- }
-diff -Nurb linux-mips-2.4.27/fs/jffs2/fs.c linux/fs/jffs2/fs.c
---- linux-mips-2.4.27/fs/jffs2/fs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/jffs2/fs.c 2004-11-19 10:25:12.102168936 +0100
-@@ -0,0 +1,618 @@
-+/*
-+ * JFFS2 -- Journalling Flash File System, Version 2.
-+ *
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
-+ *
-+ * Created by David Woodhouse <dwmw2@redhat.com>
-+ *
-+ * For licensing information, see the file 'LICENCE' in this directory.
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+#include <linux/version.h>
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/fs.h>
-+#include <linux/list.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/pagemap.h>
-+#include <linux/slab.h>
-+#include <linux/vfs.h>
-+#include <linux/crc32.h>
-+#include "nodelist.h"
-+
-+
-+static int jffs2_do_setattr (struct inode *inode, struct iattr *iattr)
-+{
-+ struct jffs2_full_dnode *old_metadata, *new_metadata;
-+ struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-+ struct jffs2_raw_inode *ri;
-+ unsigned short dev;
-+ unsigned char *mdata = NULL;
-+ int mdatalen = 0;
-+ unsigned int ivalid;
-+ uint32_t phys_ofs, alloclen;
-+ int ret;
-+ D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino));
-+ ret = inode_change_ok(inode, iattr);
-+ if (ret)
-+ return ret;
-+
-+ /* Special cases - we don't want more than one data node
-+ for these types on the medium at any time. So setattr
-+ must read the original data associated with the node
-+ (i.e. the device numbers or the target name) and write
-+ it out again with the appropriate data attached */
-+ if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
-+ /* For these, we don't actually need to read the old node */
-+ dev = old_encode_dev(inode->i_rdev);
-+ mdata = (char *)&dev;
-+ mdatalen = sizeof(dev);
-+ D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen));
-+ } else if (S_ISLNK(inode->i_mode)) {
-+ mdatalen = f->metadata->size;
-+ mdata = kmalloc(f->metadata->size, GFP_USER);
-+ if (!mdata)
-+ return -ENOMEM;
-+ ret = jffs2_read_dnode(c, f->metadata, mdata, 0, mdatalen);
-+ if (ret) {
-+ kfree(mdata);
-+ return ret;
-+ }
-+ D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen));
-+ }
-+
-+ ri = jffs2_alloc_raw_inode();
-+ if (!ri) {
-+ if (S_ISLNK(inode->i_mode))
-+ kfree(mdata);
-+ return -ENOMEM;
-+ }
-+
-+ ret = jffs2_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, ALLOC_NORMAL);
-+ if (ret) {
-+ jffs2_free_raw_inode(ri);
-+ if (S_ISLNK(inode->i_mode & S_IFMT))
-+ kfree(mdata);
-+ return ret;
-+ }
-+ down(&f->sem);
-+ ivalid = iattr->ia_valid;
-+
-+ ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
-+ ri->totlen = cpu_to_je32(sizeof(*ri) + mdatalen);
-+ ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
-+
-+ ri->ino = cpu_to_je32(inode->i_ino);
-+ ri->version = cpu_to_je32(++f->highest_version);
-+
-+ ri->uid = cpu_to_je16((ivalid & ATTR_UID)?iattr->ia_uid:inode->i_uid);
-+ ri->gid = cpu_to_je16((ivalid & ATTR_GID)?iattr->ia_gid:inode->i_gid);
-+
-+ if (ivalid & ATTR_MODE)
-+ if (iattr->ia_mode & S_ISGID &&
-+ !in_group_p(je16_to_cpu(ri->gid)) && !capable(CAP_FSETID))
-+ ri->mode = cpu_to_jemode(iattr->ia_mode & ~S_ISGID);
-+ else
-+ ri->mode = cpu_to_jemode(iattr->ia_mode);
-+ else
-+ ri->mode = cpu_to_jemode(inode->i_mode);
-+
-+
-+ ri->isize = cpu_to_je32((ivalid & ATTR_SIZE)?iattr->ia_size:inode->i_size);
-+ ri->atime = cpu_to_je32(I_SEC((ivalid & ATTR_ATIME)?iattr->ia_atime:inode->i_atime));
-+ ri->mtime = cpu_to_je32(I_SEC((ivalid & ATTR_MTIME)?iattr->ia_mtime:inode->i_mtime));
-+ ri->ctime = cpu_to_je32(I_SEC((ivalid & ATTR_CTIME)?iattr->ia_ctime:inode->i_ctime));
-+
-+ ri->offset = cpu_to_je32(0);
-+ ri->csize = ri->dsize = cpu_to_je32(mdatalen);
-+ ri->compr = JFFS2_COMPR_NONE;
-+ if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
-+ /* It's an extension. Make it a hole node */
-+ ri->compr = JFFS2_COMPR_ZERO;
-+ ri->dsize = cpu_to_je32(iattr->ia_size - inode->i_size);
-+ ri->offset = cpu_to_je32(inode->i_size);
-+ }
-+ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-+ if (mdatalen)
-+ ri->data_crc = cpu_to_je32(crc32(0, mdata, mdatalen));
-+ else
-+ ri->data_crc = cpu_to_je32(0);
-+
-+ new_metadata = jffs2_write_dnode(c, f, ri, mdata, mdatalen, phys_ofs, ALLOC_NORMAL);
-+ if (S_ISLNK(inode->i_mode))
-+ kfree(mdata);
-+
-+ if (IS_ERR(new_metadata)) {
-+ jffs2_complete_reservation(c);
-+ jffs2_free_raw_inode(ri);
-+ up(&f->sem);
-+ return PTR_ERR(new_metadata);
-+ }
-+ /* It worked. Update the inode */
-+ inode->i_atime = ITIME(je32_to_cpu(ri->atime));
-+ inode->i_ctime = ITIME(je32_to_cpu(ri->ctime));
-+ inode->i_mtime = ITIME(je32_to_cpu(ri->mtime));
-+ inode->i_mode = jemode_to_cpu(ri->mode);
-+ inode->i_uid = je16_to_cpu(ri->uid);
-+ inode->i_gid = je16_to_cpu(ri->gid);
-+
-+
-+ old_metadata = f->metadata;
-+
-+ if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size)
-+ jffs2_truncate_fraglist (c, &f->fragtree, iattr->ia_size);
-+
-+ if (ivalid & ATTR_SIZE && inode->i_size < iattr->ia_size) {
-+ jffs2_add_full_dnode_to_inode(c, f, new_metadata);
-+ inode->i_size = iattr->ia_size;
-+ f->metadata = NULL;
-+ } else {
-+ f->metadata = new_metadata;
-+ }
-+ if (old_metadata) {
-+ jffs2_mark_node_obsolete(c, old_metadata->raw);
-+ jffs2_free_full_dnode(old_metadata);
-+ }
-+ jffs2_free_raw_inode(ri);
-+
-+ up(&f->sem);
-+ jffs2_complete_reservation(c);
-+
-+ /* We have to do the vmtruncate() without f->sem held, since
-+ some pages may be locked and waiting for it in readpage().
-+ We are protected from a simultaneous write() extending i_size
-+ back past iattr->ia_size, because do_truncate() holds the
-+ generic inode semaphore. */
-+ if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size)
-+ vmtruncate(inode, iattr->ia_size);
-+
-+ return 0;
-+}
-+
-+int jffs2_setattr(struct dentry *dentry, struct iattr *iattr)
-+{
-+ return jffs2_do_setattr(dentry->d_inode, iattr);
-+}
-+
-+int jffs2_statfs(struct super_block *sb, struct kstatfs *buf)
-+{
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-+ unsigned long avail;
-+
-+ buf->f_type = JFFS2_SUPER_MAGIC;
-+ buf->f_bsize = 1 << PAGE_SHIFT;
-+ buf->f_blocks = c->flash_size >> PAGE_SHIFT;
-+ buf->f_files = 0;
-+ buf->f_ffree = 0;
-+ buf->f_namelen = JFFS2_MAX_NAME_LEN;
-+
-+ spin_lock(&c->erase_completion_lock);
-+
-+ avail = c->dirty_size + c->free_size;
-+ if (avail > c->sector_size * c->resv_blocks_write)
-+ avail -= c->sector_size * c->resv_blocks_write;
-+ else
-+ avail = 0;
-+
-+ buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT;
-+
-+ D1(jffs2_dump_block_lists(c));
-+
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ return 0;
-+}
-+
-+
-+void jffs2_clear_inode (struct inode *inode)
-+{
-+ /* We can forget about this inode for now - drop all
-+ * the nodelists associated with it, etc.
-+ */
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-+ struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
-+
-+ D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
-+
-+ jffs2_do_clear_inode(c, f);
-+}
-+
-+void jffs2_read_inode (struct inode *inode)
-+{
-+ struct jffs2_inode_info *f;
-+ struct jffs2_sb_info *c;
-+ struct jffs2_raw_inode latest_node;
-+ int ret;
-+
-+ D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino));
-+
-+ f = JFFS2_INODE_INFO(inode);
-+ c = JFFS2_SB_INFO(inode->i_sb);
-+
-+ jffs2_init_inode_info(f);
-+
-+ ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
-+
-+ if (ret) {
-+ make_bad_inode(inode);
-+ up(&f->sem);
-+ return;
-+ }
-+ inode->i_mode = jemode_to_cpu(latest_node.mode);
-+ inode->i_uid = je16_to_cpu(latest_node.uid);
-+ inode->i_gid = je16_to_cpu(latest_node.gid);
-+ inode->i_size = je32_to_cpu(latest_node.isize);
-+ inode->i_atime = ITIME(je32_to_cpu(latest_node.atime));
-+ inode->i_mtime = ITIME(je32_to_cpu(latest_node.mtime));
-+ inode->i_ctime = ITIME(je32_to_cpu(latest_node.ctime));
-+
-+ inode->i_nlink = f->inocache->nlink;
-+
-+ inode->i_blksize = PAGE_SIZE;
-+ inode->i_blocks = (inode->i_size + 511) >> 9;
-+
-+ switch (inode->i_mode & S_IFMT) {
-+ jint16_t rdev;
-+
-+ case S_IFLNK:
-+ inode->i_op = &jffs2_symlink_inode_operations;
-+ break;
-+
-+ case S_IFDIR:
-+ {
-+ struct jffs2_full_dirent *fd;
-+
-+ for (fd=f->dents; fd; fd = fd->next) {
-+ if (fd->type == DT_DIR && fd->ino)
-+ inode->i_nlink++;
-+ }
-+ /* and '..' */
-+ inode->i_nlink++;
-+ /* Root dir gets i_nlink 3 for some reason */
-+ if (inode->i_ino == 1)
-+ inode->i_nlink++;
-+
-+ inode->i_op = &jffs2_dir_inode_operations;
-+ inode->i_fop = &jffs2_dir_operations;
-+ break;
-+ }
-+ case S_IFREG:
-+ inode->i_op = &jffs2_file_inode_operations;
-+ inode->i_fop = &jffs2_file_operations;
-+ inode->i_mapping->a_ops = &jffs2_file_address_operations;
-+ inode->i_mapping->nrpages = 0;
-+ break;
-+
-+ case S_IFBLK:
-+ case S_IFCHR:
-+ /* Read the device numbers from the media */
-+ D1(printk(KERN_DEBUG "Reading device numbers from flash\n"));
-+ if (jffs2_read_dnode(c, f->metadata, (char *)&rdev, 0, sizeof(rdev)) < 0) {
-+ /* Eep */
-+ printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino);
-+ up(&f->sem);
-+ jffs2_do_clear_inode(c, f);
-+ make_bad_inode(inode);
-+ return;
-+ }
-+
-+ case S_IFSOCK:
-+ case S_IFIFO:
-+ inode->i_op = &jffs2_file_inode_operations;
-+ init_special_inode(inode, inode->i_mode,
-+ old_decode_dev((je16_to_cpu(rdev))));
-+ break;
-+
-+ default:
-+ printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu\n", inode->i_mode, (unsigned long)inode->i_ino);
-+ }
-+
-+ up(&f->sem);
-+
-+ D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
-+}
-+
-+void jffs2_dirty_inode(struct inode *inode)
-+{
-+ struct iattr iattr;
-+
-+ if (!(inode->i_state & I_DIRTY_DATASYNC)) {
-+ D2(printk(KERN_DEBUG "jffs2_dirty_inode() not calling setattr() for ino #%lu\n", inode->i_ino));
-+ return;
-+ }
-+
-+ D1(printk(KERN_DEBUG "jffs2_dirty_inode() calling setattr() for ino #%lu\n", inode->i_ino));
-+
-+ iattr.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_MTIME|ATTR_CTIME;
-+ iattr.ia_mode = inode->i_mode;
-+ iattr.ia_uid = inode->i_uid;
-+ iattr.ia_gid = inode->i_gid;
-+ iattr.ia_atime = inode->i_atime;
-+ iattr.ia_mtime = inode->i_mtime;
-+ iattr.ia_ctime = inode->i_ctime;
-+
-+ jffs2_do_setattr(inode, &iattr);
-+}
-+
-+int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
-+{
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-+
-+ if (c->flags & JFFS2_SB_FLAG_RO && !(sb->s_flags & MS_RDONLY))
-+ return -EROFS;
-+
-+ /* We stop if it was running, then restart if it needs to.
-+ This also catches the case where it was stopped and this
-+ is just a remount to restart it */
-+ if (!(sb->s_flags & MS_RDONLY))
-+ jffs2_stop_garbage_collect_thread(c);
-+
-+ if (!(*flags & MS_RDONLY))
-+ jffs2_start_garbage_collect_thread(c);
-+
-+ sb->s_flags = (sb->s_flags & ~MS_RDONLY)|(*flags & MS_RDONLY);
-+
-+ return 0;
-+}
-+
-+void jffs2_write_super (struct super_block *sb)
-+{
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-+ sb->s_dirt = 0;
-+
-+ if (sb->s_flags & MS_RDONLY)
-+ return;
-+
-+ D1(printk(KERN_DEBUG "jffs2_write_super()\n"));
-+ jffs2_garbage_collect_trigger(c);
-+ jffs2_erase_pending_blocks(c, 0);
-+ jffs2_flush_wbuf_gc(c, 0);
-+}
-+
-+
-+/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
-+ fill in the raw_inode while you're at it. */
-+struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri)
-+{
-+ struct inode *inode;
-+ struct super_block *sb = dir_i->i_sb;
-+ struct jffs2_sb_info *c;
-+ struct jffs2_inode_info *f;
-+ int ret;
-+
-+ D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode));
-+
-+ c = JFFS2_SB_INFO(sb);
-+
-+ inode = new_inode(sb);
-+
-+ if (!inode)
-+ return ERR_PTR(-ENOMEM);
-+
-+ f = JFFS2_INODE_INFO(inode);
-+ jffs2_init_inode_info(f);
-+
-+ memset(ri, 0, sizeof(*ri));
-+ /* Set OS-specific defaults for new inodes */
-+ ri->uid = cpu_to_je16(current->fsuid);
-+
-+ if (dir_i->i_mode & S_ISGID) {
-+ ri->gid = cpu_to_je16(dir_i->i_gid);
-+ if (S_ISDIR(mode))
-+ mode |= S_ISGID;
-+ } else {
-+ ri->gid = cpu_to_je16(current->fsgid);
-+ }
-+ ri->mode = cpu_to_jemode(mode);
-+ ret = jffs2_do_new_inode (c, f, mode, ri);
-+ if (ret) {
-+ make_bad_inode(inode);
-+ iput(inode);
-+ return ERR_PTR(ret);
-+ }
-+ inode->i_nlink = 1;
-+ inode->i_ino = je32_to_cpu(ri->ino);
-+ inode->i_mode = jemode_to_cpu(ri->mode);
-+ inode->i_gid = je16_to_cpu(ri->gid);
-+ inode->i_uid = je16_to_cpu(ri->uid);
-+ inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME;
-+ ri->atime = ri->mtime = ri->ctime = cpu_to_je32(I_SEC(inode->i_mtime));
-+
-+ inode->i_blksize = PAGE_SIZE;
-+ inode->i_blocks = 0;
-+ inode->i_size = 0;
-+
-+ insert_inode_hash(inode);
-+
-+ return inode;
-+}
-+
-+
-+int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
-+{
-+ struct jffs2_sb_info *c;
-+ struct inode *root_i;
-+ int ret;
-+ size_t blocks;
-+
-+ c = JFFS2_SB_INFO(sb);
-+
-+ c->flash_size = c->mtd->size;
-+
-+ /*
-+ * Check, if we have to concatenate physical blocks to larger virtual blocks
-+ * to reduce the memorysize for c->blocks. (kmalloc allows max. 128K allocation)
-+ */
-+ blocks = c->flash_size / c->mtd->erasesize;
-+ while ((blocks * sizeof (struct jffs2_eraseblock)) > (128 * 1024))
-+ blocks >>= 1;
-+
-+ c->sector_size = c->flash_size / blocks;
-+ if (c->sector_size != c->mtd->erasesize)
-+ printk(KERN_INFO "jffs2: Erase block size too small (%dKiB). Using virtual blocks size (%dKiB) instead\n",
-+ c->mtd->erasesize / 1024, c->sector_size / 1024);
-+
-+ if (c->flash_size < 5*c->sector_size) {
-+ printk(KERN_ERR "jffs2: Too few erase blocks (%d)\n", c->flash_size / c->sector_size);
-+ return -EINVAL;
-+ }
-+
-+ c->cleanmarker_size = sizeof(struct jffs2_unknown_node);
-+ /* Joern -- stick alignment for weird 8-byte-page flash here */
-+
-+ if (jffs2_cleanmarker_oob(c)) {
-+ /* NAND (or other bizarre) flash... do setup accordingly */
-+ ret = jffs2_nand_flash_setup(c);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ c->inocache_list = kmalloc(INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *), GFP_KERNEL);
-+ if (!c->inocache_list) {
-+ ret = -ENOMEM;
-+ goto out_wbuf;
-+ }
-+ memset(c->inocache_list, 0, INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *));
-+
-+ if ((ret = jffs2_do_mount_fs(c)))
-+ goto out_inohash;
-+
-+ ret = -EINVAL;
-+
-+ D1(printk(KERN_DEBUG "jffs2_do_fill_super(): Getting root inode\n"));
-+ root_i = iget(sb, 1);
-+ if (is_bad_inode(root_i)) {
-+ D1(printk(KERN_WARNING "get root inode failed\n"));
-+ goto out_nodes;
-+ }
-+
-+ D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n"));
-+ sb->s_root = d_alloc_root(root_i);
-+ if (!sb->s_root)
-+ goto out_root_i;
-+
-+#if LINUX_VERSION_CODE >= 0x20403
-+ sb->s_maxbytes = 0xFFFFFFFF;
-+#endif
-+ sb->s_blocksize = PAGE_CACHE_SIZE;
-+ sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-+ sb->s_magic = JFFS2_SUPER_MAGIC;
-+ if (!(sb->s_flags & MS_RDONLY))
-+ jffs2_start_garbage_collect_thread(c);
-+ return 0;
-+
-+ out_root_i:
-+ iput(root_i);
-+ out_nodes:
-+ jffs2_free_ino_caches(c);
-+ jffs2_free_raw_node_refs(c);
-+ kfree(c->blocks);
-+ out_inohash:
-+ kfree(c->inocache_list);
-+ out_wbuf:
-+ jffs2_nand_flash_cleanup(c);
-+
-+ return ret;
-+}
-+
-+void jffs2_gc_release_inode(struct jffs2_sb_info *c,
-+ struct jffs2_inode_info *f)
-+{
-+ iput(OFNI_EDONI_2SFFJ(f));
-+}
-+
-+struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
-+ int inum, int nlink)
-+{
-+ struct inode *inode;
-+ struct jffs2_inode_cache *ic;
-+ if (!nlink) {
-+ /* The inode has zero nlink but its nodes weren't yet marked
-+ obsolete. This has to be because we're still waiting for
-+ the final (close() and) iput() to happen.
-+
-+ There's a possibility that the final iput() could have
-+ happened while we were contemplating. In order to ensure
-+ that we don't cause a new read_inode() (which would fail)
-+ for the inode in question, we use ilookup() in this case
-+ instead of iget().
-+
-+ The nlink can't _become_ zero at this point because we're
-+ holding the alloc_sem, and jffs2_do_unlink() would also
-+ need that while decrementing nlink on any inode.
-+ */
-+ inode = ilookup(OFNI_BS_2SFFJ(c), inum);
-+ if (!inode) {
-+ D1(printk(KERN_DEBUG "ilookup() failed for ino #%u; inode is probably deleted.\n",
-+ inum));
-+
-+ spin_lock(&c->inocache_lock);
-+ ic = jffs2_get_ino_cache(c, inum);
-+ if (!ic) {
-+ D1(printk(KERN_DEBUG "Inode cache for ino #%u is gone.\n", inum));
-+ spin_unlock(&c->inocache_lock);
-+ return NULL;
-+ }
-+ if (ic->state != INO_STATE_CHECKEDABSENT) {
-+ /* Wait for progress. Don't just loop */
-+ D1(printk(KERN_DEBUG "Waiting for ino #%u in state %d\n",
-+ ic->ino, ic->state));
-+ sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
-+ } else {
-+ spin_unlock(&c->inocache_lock);
-+ }
-+
-+ return NULL;
-+ }
-+ } else {
-+ /* Inode has links to it still; they're not going away because
-+ jffs2_do_unlink() would need the alloc_sem and we have it.
-+ Just iget() it, and if read_inode() is necessary that's OK.
-+ */
-+ inode = iget(OFNI_BS_2SFFJ(c), inum);
-+ if (!inode)
-+ return ERR_PTR(-ENOMEM);
-+ }
-+ if (is_bad_inode(inode)) {
-+ printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. nlink %d\n",
-+ inum, nlink);
-+ /* NB. This will happen again. We need to do something appropriate here. */
-+ iput(inode);
-+ return ERR_PTR(-EIO);
-+ }
-+
-+ return JFFS2_INODE_INFO(inode);
-+}
-+
-+unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
-+ struct jffs2_inode_info *f,
-+ unsigned long offset,
-+ unsigned long *priv)
-+{
-+ struct inode *inode = OFNI_EDONI_2SFFJ(f);
-+ struct page *pg;
-+
-+ pg = read_cache_page(inode->i_mapping, offset >> PAGE_CACHE_SHIFT,
-+ (void *)jffs2_do_readpage_unlock, inode);
-+ if (IS_ERR(pg))
-+ return (void *)pg;
-+
-+ *priv = (unsigned long)pg;
-+ return kmap(pg);
-+}
-+
-+void jffs2_gc_release_page(struct jffs2_sb_info *c,
-+ unsigned char *ptr,
-+ unsigned long *priv)
-+{
-+ struct page *pg = (void *)*priv;
-+
-+ kunmap(pg);
-+ page_cache_release(pg);
-+}
-diff -Nurb linux-mips-2.4.27/fs/jffs2/gc.c linux/fs/jffs2/gc.c
---- linux-mips-2.4.27/fs/jffs2/gc.c 2003-11-17 02:07:44.000000000 +0100
-+++ linux/fs/jffs2/gc.c 2004-11-19 10:25:12.104168632 +0100
-@@ -1,76 +1,67 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/kernel.h>
- #include <linux/mtd/mtd.h>
- #include <linux/slab.h>
--#include <linux/jffs2.h>
--#include <linux/sched.h>
--#include <linux/interrupt.h>
- #include <linux/pagemap.h>
--#include "nodelist.h"
- #include <linux/crc32.h>
-+#include <linux/compiler.h>
-+#include <linux/stat.h>
-+#include "nodelist.h"
-
-+static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
-+ struct jffs2_inode_cache *ic,
-+ struct jffs2_raw_node_ref *raw);
- static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dnode *fd);
-+ struct jffs2_inode_info *f, struct jffs2_full_dnode *fd);
- static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dirent *fd);
-+ struct jffs2_inode_info *f, struct jffs2_full_dirent *fd);
- static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dirent *fd);
-+ struct jffs2_inode_info *f, struct jffs2_full_dirent *fd);
- static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *indeo, struct jffs2_full_dnode *fn,
-- __u32 start, __u32 end);
-+ struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
-+ uint32_t start, uint32_t end);
- static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dnode *fn,
-- __u32 start, __u32 end);
-+ struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
-+ uint32_t start, uint32_t end);
-+static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-+ struct jffs2_raw_node_ref *raw, struct jffs2_inode_info *f);
-
- /* Called with erase_completion_lock held */
- static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c)
- {
- struct jffs2_eraseblock *ret;
- struct list_head *nextlist = NULL;
-+ int n = jiffies % 128;
-
- /* Pick an eraseblock to garbage collect next. This is where we'll
- put the clever wear-levelling algorithms. Eventually. */
-- if (!list_empty(&c->bad_used_list) && c->nr_free_blocks > JFFS2_RESERVED_BLOCKS_GCBAD) {
-+ /* We possibly want to favour the dirtier blocks more when the
-+ number of free blocks is low. */
-+ if (!list_empty(&c->bad_used_list) && c->nr_free_blocks > c->resv_blocks_gcbad) {
- D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n"));
- nextlist = &c->bad_used_list;
-- } else if (jiffies % 100 && !list_empty(&c->dirty_list)) {
-- /* Most of the time, pick one off the dirty list */
-+ } else if (n < 50 && !list_empty(&c->erasable_list)) {
-+ /* Note that most of them will have gone directly to be erased.
-+ So don't favour the erasable_list _too_ much. */
-+ D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next\n"));
-+ nextlist = &c->erasable_list;
-+ } else if (n < 110 && !list_empty(&c->very_dirty_list)) {
-+ /* Most of the time, pick one off the very_dirty list */
-+ D1(printk(KERN_DEBUG "Picking block from very_dirty_list to GC next\n"));
-+ nextlist = &c->very_dirty_list;
-+ } else if (n < 126 && !list_empty(&c->dirty_list)) {
- D1(printk(KERN_DEBUG "Picking block from dirty_list to GC next\n"));
- nextlist = &c->dirty_list;
- } else if (!list_empty(&c->clean_list)) {
-@@ -80,9 +71,16 @@
- D1(printk(KERN_DEBUG "Picking block from dirty_list to GC next (clean_list was empty)\n"));
-
- nextlist = &c->dirty_list;
-+ } else if (!list_empty(&c->very_dirty_list)) {
-+ D1(printk(KERN_DEBUG "Picking block from very_dirty_list to GC next (clean_list and dirty_list were empty)\n"));
-+ nextlist = &c->very_dirty_list;
-+ } else if (!list_empty(&c->erasable_list)) {
-+ D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next (clean_list and {very_,}dirty_list were empty)\n"));
-+
-+ nextlist = &c->erasable_list;
- } else {
-- /* Eep. Both were empty */
-- printk(KERN_NOTICE "jffs2: No clean _or_ dirty blocks to GC from! Where are they all?\n");
-+ /* Eep. All were empty */
-+ printk(KERN_NOTICE "jffs2: No clean, dirty _or_ erasable blocks to GC from! Where are they all?\n");
- return NULL;
- }
-
-@@ -94,6 +92,17 @@
- printk(KERN_WARNING "Eep. ret->gc_node for block at 0x%08x is NULL\n", ret->offset);
- BUG();
- }
-+
-+ /* Have we accidentally picked a clean block with wasted space ? */
-+ if (ret->wasted_size) {
-+ D1(printk(KERN_DEBUG "Converting wasted_size %08x to dirty_size\n", ret->wasted_size));
-+ ret->dirty_size += ret->wasted_size;
-+ c->wasted_size -= ret->wasted_size;
-+ c->dirty_size += ret->wasted_size;
-+ ret->wasted_size = 0;
-+ }
-+
-+ D1(jffs2_dump_block_lists(c));
- return ret;
- }
-
-@@ -103,21 +112,90 @@
- */
- int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
- {
-- struct jffs2_eraseblock *jeb;
- struct jffs2_inode_info *f;
-- struct jffs2_raw_node_ref *raw;
-- struct jffs2_node_frag *frag;
-- struct jffs2_full_dnode *fn = NULL;
-- struct jffs2_full_dirent *fd;
- struct jffs2_inode_cache *ic;
-- __u32 start = 0, end = 0, nrfrags = 0;
-- struct inode *inode;
-- int ret = 0;
-+ struct jffs2_eraseblock *jeb;
-+ struct jffs2_raw_node_ref *raw;
-+ int ret = 0, inum, nlink;
-
- if (down_interruptible(&c->alloc_sem))
- return -EINTR;
-
-- spin_lock_bh(&c->erase_completion_lock);
-+ for (;;) {
-+ spin_lock(&c->erase_completion_lock);
-+ if (!c->unchecked_size)
-+ break;
-+
-+ /* We can't start doing GC yet. We haven't finished checking
-+ the node CRCs etc. Do it now. */
-+
-+ /* checked_ino is protected by the alloc_sem */
-+ if (c->checked_ino > c->highest_ino) {
-+ printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n",
-+ c->unchecked_size);
-+ D1(jffs2_dump_block_lists(c));
-+ spin_unlock(&c->erase_completion_lock);
-+ BUG();
-+ }
-+
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ spin_lock(&c->inocache_lock);
-+
-+ ic = jffs2_get_ino_cache(c, c->checked_ino++);
-+
-+ if (!ic) {
-+ spin_unlock(&c->inocache_lock);
-+ continue;
-+ }
-+
-+ if (!ic->nlink) {
-+ D1(printk(KERN_DEBUG "Skipping check of ino #%d with nlink zero\n",
-+ ic->ino));
-+ spin_unlock(&c->inocache_lock);
-+ continue;
-+ }
-+ switch(ic->state) {
-+ case INO_STATE_CHECKEDABSENT:
-+ case INO_STATE_PRESENT:
-+ D1(printk(KERN_DEBUG "Skipping ino #%u already checked\n", ic->ino));
-+ spin_unlock(&c->inocache_lock);
-+ continue;
-+
-+ case INO_STATE_GC:
-+ case INO_STATE_CHECKING:
-+ printk(KERN_WARNING "Inode #%u is in state %d during CRC check phase!\n", ic->ino, ic->state);
-+ spin_unlock(&c->inocache_lock);
-+ BUG();
-+
-+ case INO_STATE_READING:
-+ /* We need to wait for it to finish, lest we move on
-+ and trigger the BUG() above while we haven't yet
-+ finished checking all its nodes */
-+ D1(printk(KERN_DEBUG "Waiting for ino #%u to finish reading\n", ic->ino));
-+ up(&c->alloc_sem);
-+ sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
-+ return 0;
-+
-+ default:
-+ BUG();
-+
-+ case INO_STATE_UNCHECKED:
-+ ;
-+ }
-+ ic->state = INO_STATE_CHECKING;
-+ spin_unlock(&c->inocache_lock);
-+
-+ D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() triggering inode scan of ino#%u\n", ic->ino));
-+
-+ ret = jffs2_do_crccheck_inode(c, ic);
-+ if (ret)
-+ printk(KERN_WARNING "Returned error for crccheck of ino #%u. Expect badness...\n", ic->ino);
-+
-+ jffs2_set_inocache_state(c, ic, INO_STATE_CHECKEDABSENT);
-+ up(&c->alloc_sem);
-+ return ret;
-+ }
-
- /* First, work out which block we're garbage-collecting */
- jeb = c->gcblock;
-@@ -127,12 +205,14 @@
-
- if (!jeb) {
- printk(KERN_NOTICE "jffs2: Couldn't find erase block to garbage collect!\n");
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
- up(&c->alloc_sem);
- return -EIO;
- }
-
-- D1(printk(KERN_DEBUG "garbage collect from block at phys 0x%08x\n", jeb->offset));
-+ D1(printk(KERN_DEBUG "GC from block %08x, used_size %08x, dirty_size %08x, free_size %08x\n", jeb->offset, jeb->used_size, jeb->dirty_size, jeb->free_size));
-+ D1(if (c->nextblock)
-+ printk(KERN_DEBUG "Nextblock at %08x, used_size %08x, dirty_size %08x, wasted_size %08x, free_size %08x\n", c->nextblock->offset, c->nextblock->used_size, c->nextblock->dirty_size, c->nextblock->wasted_size, c->nextblock->free_size));
-
- if (!jeb->used_size) {
- up(&c->alloc_sem);
-@@ -141,92 +221,211 @@
-
- raw = jeb->gc_node;
-
-- while(raw->flash_offset & 1) {
-- D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", raw->flash_offset &~3));
-- jeb->gc_node = raw = raw->next_phys;
-- if (!raw) {
-+ while(ref_obsolete(raw)) {
-+ D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", ref_offset(raw)));
-+ raw = raw->next_phys;
-+ if (unlikely(!raw)) {
- printk(KERN_WARNING "eep. End of raw list while still supposedly nodes to GC\n");
- printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n",
- jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size);
-- spin_unlock_bh(&c->erase_completion_lock);
-+ jeb->gc_node = raw;
-+ spin_unlock(&c->erase_completion_lock);
- up(&c->alloc_sem);
- BUG();
- }
- }
-- D1(printk(KERN_DEBUG "Going to garbage collect node at 0x%08x\n", raw->flash_offset &~3));
-+ jeb->gc_node = raw;
-+
-+ D1(printk(KERN_DEBUG "Going to garbage collect node at 0x%08x\n", ref_offset(raw)));
-+
- if (!raw->next_in_ino) {
- /* Inode-less node. Clean marker, snapshot or something like that */
-- spin_unlock_bh(&c->erase_completion_lock);
-+ /* FIXME: If it's something that needs to be copied, including something
-+ we don't grok that has JFFS2_NODETYPE_RWCOMPAT_COPY, we should do so */
-+ spin_unlock(&c->erase_completion_lock);
- jffs2_mark_node_obsolete(c, raw);
- up(&c->alloc_sem);
- goto eraseit_lock;
- }
-
- ic = jffs2_raw_ref_to_ic(raw);
-- D1(printk(KERN_DEBUG "Inode number is #%u\n", ic->ino));
--
-- spin_unlock_bh(&c->erase_completion_lock);
-
-- D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass collecting from block @0x%08x. Node @0x%08x, ino #%u\n", jeb->offset, raw->flash_offset&~3, ic->ino));
-- if (!ic->nlink) {
-- /* The inode has zero nlink but its nodes weren't yet marked
-- obsolete. This has to be because we're still waiting for
-- the final (close() and) iput() to happen.
--
-- There's a possibility that the final iput() could have
-- happened while we were contemplating. In order to ensure
-- that we don't cause a new read_inode() (which would fail)
-- for the inode in question, we use ilookup() in this case
-- instead of iget().
--
-- The nlink can't _become_ zero at this point because we're
-- holding the alloc_sem, and jffs2_do_unlink() would also
-- need that while decrementing nlink on any inode.
-+ /* We need to hold the inocache. Either the erase_completion_lock or
-+ the inocache_lock are sufficient; we trade down since the inocache_lock
-+ causes less contention. */
-+ spin_lock(&c->inocache_lock);
-+
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass collecting from block @0x%08x. Node @0x%08x(%d), ino #%u\n", jeb->offset, ref_offset(raw), ref_flags(raw), ic->ino));
-+
-+ /* Three possibilities:
-+ 1. Inode is already in-core. We must iget it and do proper
-+ updating to its fragtree, etc.
-+ 2. Inode is not in-core, node is REF_PRISTINE. We lock the
-+ inocache to prevent a read_inode(), copy the node intact.
-+ 3. Inode is not in-core, node is not pristine. We must iget()
-+ and take the slow path.
- */
-- inode = ilookup(OFNI_BS_2SFFJ(c), ic->ino);
-- if (!inode) {
-- D1(printk(KERN_DEBUG "ilookup() failed for ino #%u; inode is probably deleted.\n",
-+
-+ switch(ic->state) {
-+ case INO_STATE_CHECKEDABSENT:
-+ /* It's been checked, but it's not currently in-core.
-+ We can just copy any pristine nodes, but have
-+ to prevent anyone else from doing read_inode() while
-+ we're at it, so we set the state accordingly */
-+ if (ref_flags(raw) == REF_PRISTINE)
-+ ic->state = INO_STATE_GC;
-+ else {
-+ D1(printk(KERN_DEBUG "Ino #%u is absent but node not REF_PRISTINE. Reading.\n",
- ic->ino));
-- up(&c->alloc_sem);
-- return 0;
- }
-- } else {
-- /* Inode has links to it still; they're not going away because
-- jffs2_do_unlink() would need the alloc_sem and we have it.
-- Just iget() it, and if read_inode() is necessary that's OK.
-+ break;
-+
-+ case INO_STATE_PRESENT:
-+ /* It's in-core. GC must iget() it. */
-+ break;
-+
-+ case INO_STATE_UNCHECKED:
-+ case INO_STATE_CHECKING:
-+ case INO_STATE_GC:
-+ /* Should never happen. We should have finished checking
-+ by the time we actually start doing any GC, and since
-+ we're holding the alloc_sem, no other garbage collection
-+ can happen.
- */
-- inode = iget(OFNI_BS_2SFFJ(c), ic->ino);
-- if (!inode) {
-+ printk(KERN_CRIT "Inode #%u already in state %d in jffs2_garbage_collect_pass()!\n",
-+ ic->ino, ic->state);
- up(&c->alloc_sem);
-- return -ENOMEM;
-+ spin_unlock(&c->inocache_lock);
-+ BUG();
-+
-+ case INO_STATE_READING:
-+ /* Someone's currently trying to read it. We must wait for
-+ them to finish and then go through the full iget() route
-+ to do the GC. However, sometimes read_inode() needs to get
-+ the alloc_sem() (for marking nodes invalid) so we must
-+ drop the alloc_sem before sleeping. */
-+
-+ up(&c->alloc_sem);
-+ D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() waiting for ino #%u in state %d\n",
-+ ic->ino, ic->state));
-+ sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
-+ /* And because we dropped the alloc_sem we must start again from the
-+ beginning. Ponder chance of livelock here -- we're returning success
-+ without actually making any progress.
-+
-+ Q: What are the chances that the inode is back in INO_STATE_READING
-+ again by the time we next enter this function? And that this happens
-+ enough times to cause a real delay?
-+
-+ A: Small enough that I don't care :)
-+ */
-+ return 0;
- }
-+
-+ /* OK. Now if the inode is in state INO_STATE_GC, we are going to copy the
-+ node intact, and we don't have to muck about with the fragtree etc.
-+ because we know it's not in-core. If it _was_ in-core, we go through
-+ all the iget() crap anyway */
-+
-+ if (ic->state == INO_STATE_GC) {
-+ spin_unlock(&c->inocache_lock);
-+
-+ ret = jffs2_garbage_collect_pristine(c, ic, raw);
-+
-+ spin_lock(&c->inocache_lock);
-+ ic->state = INO_STATE_CHECKEDABSENT;
-+ wake_up(&c->inocache_wq);
-+
-+ if (ret != -EBADFD) {
-+ spin_unlock(&c->inocache_lock);
-+ goto release_sem;
- }
-- if (is_bad_inode(inode)) {
-- printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u\n", ic->ino);
-- /* NB. This will happen again. We need to do something appropriate here. */
-+
-+ /* Fall through if it wanted us to, with inocache_lock held */
-+ }
-+
-+ /* Prevent the fairly unlikely race where the gcblock is
-+ entirely obsoleted by the final close of a file which had
-+ the only valid nodes in the block, followed by erasure,
-+ followed by freeing of the ic because the erased block(s)
-+ held _all_ the nodes of that inode.... never been seen but
-+ it's vaguely possible. */
-+
-+ inum = ic->ino;
-+ nlink = ic->nlink;
-+ spin_unlock(&c->inocache_lock);
-+
-+ f = jffs2_gc_fetch_inode(c, inum, nlink);
-+ if (IS_ERR(f))
-+ return PTR_ERR(f);
-+ if (!f)
-+ return 0;
-+
-+ ret = jffs2_garbage_collect_live(c, jeb, raw, f);
-+
-+ jffs2_gc_release_inode(c, f);
-+
-+ release_sem:
- up(&c->alloc_sem);
-- iput(inode);
-- return -EIO;
-+
-+ eraseit_lock:
-+ /* If we've finished this block, start it erasing */
-+ spin_lock(&c->erase_completion_lock);
-+
-+ eraseit:
-+ if (c->gcblock && !c->gcblock->used_size) {
-+ D1(printk(KERN_DEBUG "Block at 0x%08x completely obsoleted by GC. Moving to erase_pending_list\n", c->gcblock->offset));
-+ /* We're GC'ing an empty block? */
-+ list_add_tail(&c->gcblock->list, &c->erase_pending_list);
-+ c->gcblock = NULL;
-+ c->nr_erasing_blocks++;
-+ jffs2_erase_pending_trigger(c);
- }
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ return ret;
-+}
-+
-+static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-+ struct jffs2_raw_node_ref *raw, struct jffs2_inode_info *f)
-+{
-+ struct jffs2_node_frag *frag;
-+ struct jffs2_full_dnode *fn = NULL;
-+ struct jffs2_full_dirent *fd;
-+ uint32_t start = 0, end = 0, nrfrags = 0;
-+ int ret = 0;
-
-- f = JFFS2_INODE_INFO(inode);
- down(&f->sem);
-+
- /* Now we have the lock for this inode. Check that it's still the one at the head
- of the list. */
-
-- if (raw->flash_offset & 1) {
-+ spin_lock(&c->erase_completion_lock);
-+
-+ if (c->gcblock != jeb) {
-+ spin_unlock(&c->erase_completion_lock);
-+ D1(printk(KERN_DEBUG "GC block is no longer gcblock. Restart\n"));
-+ goto upnout;
-+ }
-+ if (ref_obsolete(raw)) {
-+ spin_unlock(&c->erase_completion_lock);
- D1(printk(KERN_DEBUG "node to be GC'd was obsoleted in the meantime.\n"));
- /* They'll call again */
- goto upnout;
- }
-+ spin_unlock(&c->erase_completion_lock);
-+
- /* OK. Looks safe. And nobody can get us now because we have the semaphore. Move the block */
- if (f->metadata && f->metadata->raw == raw) {
- fn = f->metadata;
-- ret = jffs2_garbage_collect_metadata(c, jeb, inode, fn);
-+ ret = jffs2_garbage_collect_metadata(c, jeb, f, fn);
- goto upnout;
- }
-
-- for (frag = f->fraglist; frag; frag = frag->next) {
-+ /* FIXME. Read node and do lookup? */
-+ for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
- if (frag->node && frag->node->raw == raw) {
- fn = frag->node;
- end = frag->ofs + frag->size;
-@@ -237,13 +436,22 @@
- }
- }
- if (fn) {
-+ if (ref_flags(raw) == REF_PRISTINE) {
-+ ret = jffs2_garbage_collect_pristine(c, f->inocache, raw);
-+ if (!ret) {
-+ /* Urgh. Return it sensibly. */
-+ frag->node->raw = f->inocache->nodes;
-+ }
-+ if (ret != -EBADFD)
-+ goto upnout;
-+ }
- /* We found a datanode. Do the GC */
- if((start >> PAGE_CACHE_SHIFT) < ((end-1) >> PAGE_CACHE_SHIFT)) {
- /* It crosses a page boundary. Therefore, it must be a hole. */
-- ret = jffs2_garbage_collect_hole(c, jeb, inode, fn, start, end);
-+ ret = jffs2_garbage_collect_hole(c, jeb, f, fn, start, end);
- } else {
- /* It could still be a hole. But we GC the page this way anyway */
-- ret = jffs2_garbage_collect_dnode(c, jeb, inode, fn, start, end);
-+ ret = jffs2_garbage_collect_dnode(c, jeb, f, fn, start, end);
- }
- goto upnout;
- }
-@@ -255,12 +463,13 @@
- }
-
- if (fd && fd->ino) {
-- ret = jffs2_garbage_collect_dirent(c, jeb, inode, fd);
-+ ret = jffs2_garbage_collect_dirent(c, jeb, f, fd);
- } else if (fd) {
-- ret = jffs2_garbage_collect_deletion_dirent(c, jeb, inode, fd);
-+ ret = jffs2_garbage_collect_deletion_dirent(c, jeb, f, fd);
- } else {
-- printk(KERN_WARNING "Raw node at 0x%08x wasn't in node lists for ino #%lu\n", raw->flash_offset&~3, inode->i_ino);
-- if (raw->flash_offset & 1) {
-+ printk(KERN_WARNING "Raw node at 0x%08x wasn't in node lists for ino #%u\n",
-+ ref_offset(raw), f->inocache->ino);
-+ if (ref_obsolete(raw)) {
- printk(KERN_WARNING "But it's obsolete so we don't mind too much\n");
- } else {
- ret = -EIO;
-@@ -268,46 +477,197 @@
- }
- upnout:
- up(&f->sem);
-- up(&c->alloc_sem);
-- iput(inode);
-
-- eraseit_lock:
-- /* If we've finished this block, start it erasing */
-- spin_lock_bh(&c->erase_completion_lock);
-+ return ret;
-+}
-
-- eraseit:
-- if (c->gcblock && !c->gcblock->used_size) {
-- D1(printk(KERN_DEBUG "Block at 0x%08x completely obsoleted by GC. Moving to erase_pending_list\n", c->gcblock->offset));
-- /* We're GC'ing an empty block? */
-- list_add_tail(&c->gcblock->list, &c->erase_pending_list);
-- c->gcblock = NULL;
-- c->nr_erasing_blocks++;
-- jffs2_erase_pending_trigger(c);
-+static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
-+ struct jffs2_inode_cache *ic,
-+ struct jffs2_raw_node_ref *raw)
-+{
-+ union jffs2_node_union *node;
-+ struct jffs2_raw_node_ref *nraw;
-+ size_t retlen;
-+ int ret;
-+ uint32_t phys_ofs, alloclen;
-+ uint32_t crc, rawlen;
-+ int retried = 0;
-+
-+ D1(printk(KERN_DEBUG "Going to GC REF_PRISTINE node at 0x%08x\n", ref_offset(raw)));
-+
-+ rawlen = ref_totlen(c, c->gcblock, raw);
-+
-+ /* Ask for a small amount of space (or the totlen if smaller) because we
-+ don't want to force wastage of the end of a block if splitting would
-+ work. */
-+ ret = jffs2_reserve_space_gc(c, min_t(uint32_t, sizeof(struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN,
-+ rawlen), &phys_ofs, &alloclen);
-+ if (ret)
-+ return ret;
-+
-+ if (alloclen < rawlen) {
-+ /* Doesn't fit untouched. We'll go the old route and split it */
-+ return -EBADFD;
-+ }
-+
-+ node = kmalloc(rawlen, GFP_KERNEL);
-+ if (!node)
-+ return -ENOMEM;
-+
-+ ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (char *)node);
-+ if (!ret && retlen != rawlen)
-+ ret = -EIO;
-+ if (ret)
-+ goto out_node;
-+
-+ crc = crc32(0, node, sizeof(struct jffs2_unknown_node)-4);
-+ if (je32_to_cpu(node->u.hdr_crc) != crc) {
-+ printk(KERN_WARNING "Header CRC failed on REF_PRISTINE node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-+ ref_offset(raw), je32_to_cpu(node->u.hdr_crc), crc);
-+ goto bail;
-+ }
-+
-+ switch(je16_to_cpu(node->u.nodetype)) {
-+ case JFFS2_NODETYPE_INODE:
-+ crc = crc32(0, node, sizeof(node->i)-8);
-+ if (je32_to_cpu(node->i.node_crc) != crc) {
-+ printk(KERN_WARNING "Node CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-+ ref_offset(raw), je32_to_cpu(node->i.node_crc), crc);
-+ goto bail;
-+ }
-+
-+ if (je32_to_cpu(node->i.dsize)) {
-+ crc = crc32(0, node->i.data, je32_to_cpu(node->i.csize));
-+ if (je32_to_cpu(node->i.data_crc) != crc) {
-+ printk(KERN_WARNING "Data CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-+ ref_offset(raw), je32_to_cpu(node->i.data_crc), crc);
-+ goto bail;
- }
-- spin_unlock_bh(&c->erase_completion_lock);
-+ }
-+ break;
-+
-+ case JFFS2_NODETYPE_DIRENT:
-+ crc = crc32(0, node, sizeof(node->d)-8);
-+ if (je32_to_cpu(node->d.node_crc) != crc) {
-+ printk(KERN_WARNING "Node CRC failed on REF_PRISTINE dirent node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-+ ref_offset(raw), je32_to_cpu(node->d.node_crc), crc);
-+ goto bail;
-+ }
-+
-+ if (node->d.nsize) {
-+ crc = crc32(0, node->d.name, node->d.nsize);
-+ if (je32_to_cpu(node->d.name_crc) != crc) {
-+ printk(KERN_WARNING "Name CRC failed on REF_PRISTINE dirent ode at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-+ ref_offset(raw), je32_to_cpu(node->d.name_crc), crc);
-+ goto bail;
-+ }
-+ }
-+ break;
-+ default:
-+ printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n",
-+ ref_offset(raw), je16_to_cpu(node->u.nodetype));
-+ goto bail;
-+ }
-+
-+ nraw = jffs2_alloc_raw_node_ref();
-+ if (!nraw) {
-+ ret = -ENOMEM;
-+ goto out_node;
-+ }
-+
-+ /* OK, all the CRCs are good; this node can just be copied as-is. */
-+ retry:
-+ nraw->flash_offset = phys_ofs;
-+ nraw->__totlen = rawlen;
-+ nraw->next_phys = NULL;
-+
-+ ret = jffs2_flash_write(c, phys_ofs, rawlen, &retlen, (char *)node);
-+
-+ if (ret || (retlen != rawlen)) {
-+ printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n",
-+ rawlen, phys_ofs, ret, retlen);
-+ if (retlen) {
-+ /* Doesn't belong to any inode */
-+ nraw->next_in_ino = NULL;
-+
-+ nraw->flash_offset |= REF_OBSOLETE;
-+ jffs2_add_physical_node_ref(c, nraw);
-+ jffs2_mark_node_obsolete(c, nraw);
-+ } else {
-+ printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", nraw->flash_offset);
-+ jffs2_free_raw_node_ref(nraw);
-+ }
-+ if (!retried && (nraw == jffs2_alloc_raw_node_ref())) {
-+ /* Try to reallocate space and retry */
-+ uint32_t dummy;
-+ struct jffs2_eraseblock *jeb = &c->blocks[phys_ofs / c->sector_size];
-+
-+ retried = 1;
-+
-+ D1(printk(KERN_DEBUG "Retrying failed write of REF_PRISTINE node.\n"));
-+
-+ ACCT_SANITY_CHECK(c,jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+
-+ ret = jffs2_reserve_space_gc(c, rawlen, &phys_ofs, &dummy);
-+
-+ if (!ret) {
-+ D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", phys_ofs));
-
-+ ACCT_SANITY_CHECK(c,jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+
-+ goto retry;
-+ }
-+ D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
-+ jffs2_free_raw_node_ref(nraw);
-+ }
-+
-+ if (!ret)
-+ ret = -EIO;
-+ goto out_node;
-+ }
-+ nraw->flash_offset |= REF_PRISTINE;
-+ jffs2_add_physical_node_ref(c, nraw);
-+
-+ /* Link into per-inode list. This is safe because of the ic
-+ state being INO_STATE_GC. Note that if we're doing this
-+ for an inode which is in-code, the 'nraw' pointer is then
-+ going to be fetched from ic->nodes by our caller. */
-+ nraw->next_in_ino = ic->nodes;
-+ ic->nodes = nraw;
-+
-+ jffs2_mark_node_obsolete(c, raw);
-+ D1(printk(KERN_DEBUG "WHEEE! GC REF_PRISTINE node at 0x%08x succeeded\n", ref_offset(raw)));
-+
-+ out_node:
-+ kfree(node);
- return ret;
-+ bail:
-+ ret = -EBADFD;
-+ goto out_node;
- }
-
- static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dnode *fn)
-+ struct jffs2_inode_info *f, struct jffs2_full_dnode *fn)
- {
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_full_dnode *new_fn;
- struct jffs2_raw_inode ri;
-- unsigned short dev;
-+ jint16_t dev;
- char *mdata = NULL, mdatalen = 0;
-- __u32 alloclen, phys_ofs;
-+ uint32_t alloclen, phys_ofs;
- int ret;
-
-- if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
-+ if (S_ISBLK(JFFS2_F_I_MODE(f)) ||
-+ S_ISCHR(JFFS2_F_I_MODE(f)) ) {
- /* For these, we don't actually need to read the old node */
-- dev = (MAJOR(to_kdev_t(inode->i_rdev)) << 8) |
-- MINOR(to_kdev_t(inode->i_rdev));
-+ /* FIXME: for minor or major > 255. */
-+ dev = cpu_to_je16(((JFFS2_F_I_RDEV_MAJ(f) << 8) |
-+ JFFS2_F_I_RDEV_MIN(f)));
- mdata = (char *)&dev;
- mdatalen = sizeof(dev);
- D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bytes of kdev_t\n", mdatalen));
-- } else if (S_ISLNK(inode->i_mode)) {
-+ } else if (S_ISLNK(JFFS2_F_I_MODE(f))) {
- mdatalen = fn->size;
- mdata = kmalloc(fn->size, GFP_KERNEL);
- if (!mdata) {
-@@ -326,34 +686,34 @@
-
- ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen);
- if (ret) {
-- printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_metadata failed: %d\n",
-+ printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_metadata failed: %d\n",
- sizeof(ri)+ mdatalen, ret);
- goto out;
- }
-
- memset(&ri, 0, sizeof(ri));
-- ri.magic = JFFS2_MAGIC_BITMASK;
-- ri.nodetype = JFFS2_NODETYPE_INODE;
-- ri.totlen = sizeof(ri) + mdatalen;
-- ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4);
--
-- ri.ino = inode->i_ino;
-- ri.version = ++f->highest_version;
-- ri.mode = inode->i_mode;
-- ri.uid = inode->i_uid;
-- ri.gid = inode->i_gid;
-- ri.isize = inode->i_size;
-- ri.atime = inode->i_atime;
-- ri.ctime = inode->i_ctime;
-- ri.mtime = inode->i_mtime;
-- ri.offset = 0;
-- ri.csize = mdatalen;
-- ri.dsize = mdatalen;
-+ ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
-+ ri.totlen = cpu_to_je32(sizeof(ri) + mdatalen);
-+ ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4));
-+
-+ ri.ino = cpu_to_je32(f->inocache->ino);
-+ ri.version = cpu_to_je32(++f->highest_version);
-+ ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
-+ ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
-+ ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
-+ ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f));
-+ ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
-+ ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
-+ ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f));
-+ ri.offset = cpu_to_je32(0);
-+ ri.csize = cpu_to_je32(mdatalen);
-+ ri.dsize = cpu_to_je32(mdatalen);
- ri.compr = JFFS2_COMPR_NONE;
-- ri.node_crc = crc32(0, &ri, sizeof(ri)-8);
-- ri.data_crc = crc32(0, mdata, mdatalen);
-+ ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
-+ ri.data_crc = cpu_to_je32(crc32(0, mdata, mdatalen));
-
-- new_fn = jffs2_write_dnode(inode, &ri, mdata, mdatalen, phys_ofs, NULL);
-+ new_fn = jffs2_write_dnode(c, f, &ri, mdata, mdatalen, phys_ofs, ALLOC_GC);
-
- if (IS_ERR(new_fn)) {
- printk(KERN_WARNING "Error writing new dnode: %ld\n", PTR_ERR(new_fn));
-@@ -364,41 +724,40 @@
- jffs2_free_full_dnode(fn);
- f->metadata = new_fn;
- out:
-- if (S_ISLNK(inode->i_mode))
-+ if (S_ISLNK(JFFS2_F_I_MODE(f)))
- kfree(mdata);
- return ret;
- }
-
- static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dirent *fd)
-+ struct jffs2_inode_info *f, struct jffs2_full_dirent *fd)
- {
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_full_dirent *new_fd;
- struct jffs2_raw_dirent rd;
-- __u32 alloclen, phys_ofs;
-+ uint32_t alloclen, phys_ofs;
- int ret;
-
-- rd.magic = JFFS2_MAGIC_BITMASK;
-- rd.nodetype = JFFS2_NODETYPE_DIRENT;
-+ rd.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ rd.nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
- rd.nsize = strlen(fd->name);
-- rd.totlen = sizeof(rd) + rd.nsize;
-- rd.hdr_crc = crc32(0, &rd, sizeof(struct jffs2_unknown_node)-4);
-+ rd.totlen = cpu_to_je32(sizeof(rd) + rd.nsize);
-+ rd.hdr_crc = cpu_to_je32(crc32(0, &rd, sizeof(struct jffs2_unknown_node)-4));
-
-- rd.pino = inode->i_ino;
-- rd.version = ++f->highest_version;
-- rd.ino = fd->ino;
-- rd.mctime = max(inode->i_mtime, inode->i_ctime);
-+ rd.pino = cpu_to_je32(f->inocache->ino);
-+ rd.version = cpu_to_je32(++f->highest_version);
-+ rd.ino = cpu_to_je32(fd->ino);
-+ rd.mctime = cpu_to_je32(max(JFFS2_F_I_MTIME(f), JFFS2_F_I_CTIME(f)));
- rd.type = fd->type;
-- rd.node_crc = crc32(0, &rd, sizeof(rd)-8);
-- rd.name_crc = crc32(0, fd->name, rd.nsize);
-+ rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8));
-+ rd.name_crc = cpu_to_je32(crc32(0, fd->name, rd.nsize));
-
- ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &phys_ofs, &alloclen);
- if (ret) {
-- printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_dirent failed: %d\n",
-+ printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dirent failed: %d\n",
- sizeof(rd)+rd.nsize, ret);
- return ret;
- }
-- new_fd = jffs2_write_dirent(inode, &rd, fd->name, rd.nsize, phys_ofs, NULL);
-+ new_fd = jffs2_write_dirent(c, f, &rd, fd->name, rd.nsize, phys_ofs, ALLOC_GC);
-
- if (IS_ERR(new_fd)) {
- printk(KERN_WARNING "jffs2_write_dirent in garbage_collect_dirent failed: %ld\n", PTR_ERR(new_fd));
-@@ -409,19 +768,98 @@
- }
-
- static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dirent *fd)
-+ struct jffs2_inode_info *f, struct jffs2_full_dirent *fd)
- {
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_full_dirent **fdp = &f->dents;
- int found = 0;
-
-- /* FIXME: When we run on NAND flash, we need to work out whether
-- this deletion dirent is still needed to actively delete a
-- 'real' dirent with the same name that's still somewhere else
-- on the flash. For now, we know that we've actually obliterated
-- all the older dirents when they became obsolete, so we didn't
-- really need to write the deletion to flash in the first place.
-- */
-+ /* On a medium where we can't actually mark nodes obsolete
-+ pernamently, such as NAND flash, we need to work out
-+ whether this deletion dirent is still needed to actively
-+ delete a 'real' dirent with the same name that's still
-+ somewhere else on the flash. */
-+ if (!jffs2_can_mark_obsolete(c)) {
-+ struct jffs2_raw_dirent *rd;
-+ struct jffs2_raw_node_ref *raw;
-+ int ret;
-+ size_t retlen;
-+ int name_len = strlen(fd->name);
-+ uint32_t name_crc = crc32(0, fd->name, name_len);
-+ uint32_t rawlen = ref_totlen(c, jeb, fd->raw);
-+
-+ rd = kmalloc(rawlen, GFP_KERNEL);
-+ if (!rd)
-+ return -ENOMEM;
-+
-+ /* Prevent the erase code from nicking the obsolete node refs while
-+ we're looking at them. I really don't like this extra lock but
-+ can't see any alternative. Suggestions on a postcard to... */
-+ down(&c->erase_free_sem);
-+
-+ for (raw = f->inocache->nodes; raw != (void *)f->inocache; raw = raw->next_in_ino) {
-+
-+ /* We only care about obsolete ones */
-+ if (!(ref_obsolete(raw)))
-+ continue;
-+
-+ /* Any dirent with the same name is going to have the same length... */
-+ if (ref_totlen(c, NULL, raw) != rawlen)
-+ continue;
-+
-+ /* Doesn't matter if there's one in the same erase block. We're going to
-+ delete it too at the same time. */
-+ if ((raw->flash_offset & ~(c->sector_size-1)) ==
-+ (fd->raw->flash_offset & ~(c->sector_size-1)))
-+ continue;
-+
-+ D1(printk(KERN_DEBUG "Check potential deletion dirent at %08x\n", ref_offset(raw)));
-+
-+ /* This is an obsolete node belonging to the same directory, and it's of the right
-+ length. We need to take a closer look...*/
-+ ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (char *)rd);
-+ if (ret) {
-+ printk(KERN_WARNING "jffs2_g_c_deletion_dirent(): Read error (%d) reading obsolete node at %08x\n", ret, ref_offset(raw));
-+ /* If we can't read it, we don't need to continue to obsolete it. Continue */
-+ continue;
-+ }
-+ if (retlen != rawlen) {
-+ printk(KERN_WARNING "jffs2_g_c_deletion_dirent(): Short read (%zd not %zd) reading header from obsolete node at %08x\n",
-+ retlen, rawlen, ref_offset(raw));
-+ continue;
-+ }
-+
-+ if (je16_to_cpu(rd->nodetype) != JFFS2_NODETYPE_DIRENT)
-+ continue;
-+
-+ /* If the name CRC doesn't match, skip */
-+ if (je32_to_cpu(rd->name_crc) != name_crc)
-+ continue;
-+
-+ /* If the name length doesn't match, or it's another deletion dirent, skip */
-+ if (rd->nsize != name_len || !je32_to_cpu(rd->ino))
-+ continue;
-+
-+ /* OK, check the actual name now */
-+ if (memcmp(rd->name, fd->name, name_len))
-+ continue;
-+
-+ /* OK. The name really does match. There really is still an older node on
-+ the flash which our deletion dirent obsoletes. So we have to write out
-+ a new deletion dirent to replace it */
-+ up(&c->erase_free_sem);
-+
-+ D1(printk(KERN_DEBUG "Deletion dirent at %08x still obsoletes real dirent \"%s\" at %08x for ino #%u\n",
-+ ref_offset(fd->raw), fd->name, ref_offset(raw), je32_to_cpu(rd->ino)));
-+ kfree(rd);
-+
-+ return jffs2_garbage_collect_dirent(c, jeb, f, fd);
-+ }
-+
-+ up(&c->erase_free_sem);
-+ kfree(rd);
-+ }
-+
-+ /* No need for it any more. Just mark it obsolete and remove it from the list */
- while (*fdp) {
- if ((*fdp) == fd) {
- found = 1;
-@@ -431,7 +869,7 @@
- fdp = &(*fdp)->next;
- }
- if (!found) {
-- printk(KERN_WARNING "Deletion dirent \"%s\" not found in list for ino #%lu\n", fd->name, inode->i_ino);
-+ printk(KERN_WARNING "Deletion dirent \"%s\" not found in list for ino #%u\n", fd->name, f->inocache->ino);
- }
- jffs2_mark_node_obsolete(c, fd->raw);
- jffs2_free_full_dirent(fd);
-@@ -439,93 +877,95 @@
- }
-
- static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dnode *fn,
-- __u32 start, __u32 end)
-+ struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
-+ uint32_t start, uint32_t end)
- {
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_raw_inode ri;
- struct jffs2_node_frag *frag;
- struct jffs2_full_dnode *new_fn;
-- __u32 alloclen, phys_ofs;
-+ uint32_t alloclen, phys_ofs;
- int ret;
-
-- D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%lu from offset 0x%x to 0x%x\n",
-- inode->i_ino, start, end));
-+ D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n",
-+ f->inocache->ino, start, end));
-
- memset(&ri, 0, sizeof(ri));
-
- if(fn->frags > 1) {
- size_t readlen;
-- __u32 crc;
-+ uint32_t crc;
- /* It's partially obsoleted by a later write. So we have to
- write it out again with the _same_ version as before */
-- ret = c->mtd->read(c->mtd, fn->raw->flash_offset & ~3, sizeof(ri), &readlen, (char *)&ri);
-+ ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(ri), &readlen, (char *)&ri);
- if (readlen != sizeof(ri) || ret) {
-- printk(KERN_WARNING "Node read failed in jffs2_garbage_collect_hole. Ret %d, retlen %d. Data will be lost by writing new hold node\n", ret, readlen);
-+ printk(KERN_WARNING "Node read failed in jffs2_garbage_collect_hole. Ret %d, retlen %zd. Data will be lost by writing new hole node\n", ret, readlen);
- goto fill;
- }
-- if (ri.nodetype != JFFS2_NODETYPE_INODE) {
-+ if (je16_to_cpu(ri.nodetype) != JFFS2_NODETYPE_INODE) {
- printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had node type 0x%04x instead of JFFS2_NODETYPE_INODE(0x%04x)\n",
-- fn->raw->flash_offset & ~3, ri.nodetype, JFFS2_NODETYPE_INODE);
-+ ref_offset(fn->raw),
-+ je16_to_cpu(ri.nodetype), JFFS2_NODETYPE_INODE);
- return -EIO;
- }
-- if (ri.totlen != sizeof(ri)) {
-- printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had totlen 0x%x instead of expected 0x%x\n",
-- fn->raw->flash_offset & ~3, ri.totlen, sizeof(ri));
-+ if (je32_to_cpu(ri.totlen) != sizeof(ri)) {
-+ printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had totlen 0x%x instead of expected 0x%zx\n",
-+ ref_offset(fn->raw),
-+ je32_to_cpu(ri.totlen), sizeof(ri));
- return -EIO;
- }
- crc = crc32(0, &ri, sizeof(ri)-8);
-- if (crc != ri.node_crc) {
-+ if (crc != je32_to_cpu(ri.node_crc)) {
- printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had CRC 0x%08x which doesn't match calculated CRC 0x%08x\n",
-- fn->raw->flash_offset & ~3, ri.node_crc, crc);
-+ ref_offset(fn->raw),
-+ je32_to_cpu(ri.node_crc), crc);
- /* FIXME: We could possibly deal with this by writing new holes for each frag */
-- printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%lu will be lost\n",
-- start, end, inode->i_ino);
-+ printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n",
-+ start, end, f->inocache->ino);
- goto fill;
- }
- if (ri.compr != JFFS2_COMPR_ZERO) {
-- printk(KERN_WARNING "jffs2_garbage_collect_hole: Node 0x%08x wasn't a hole node!\n", fn->raw->flash_offset & ~3);
-- printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%lu will be lost\n",
-- start, end, inode->i_ino);
-+ printk(KERN_WARNING "jffs2_garbage_collect_hole: Node 0x%08x wasn't a hole node!\n", ref_offset(fn->raw));
-+ printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n",
-+ start, end, f->inocache->ino);
- goto fill;
- }
- } else {
- fill:
-- ri.magic = JFFS2_MAGIC_BITMASK;
-- ri.nodetype = JFFS2_NODETYPE_INODE;
-- ri.totlen = sizeof(ri);
-- ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4);
--
-- ri.ino = inode->i_ino;
-- ri.version = ++f->highest_version;
-- ri.offset = start;
-- ri.dsize = end - start;
-- ri.csize = 0;
-+ ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
-+ ri.totlen = cpu_to_je32(sizeof(ri));
-+ ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4));
-+
-+ ri.ino = cpu_to_je32(f->inocache->ino);
-+ ri.version = cpu_to_je32(++f->highest_version);
-+ ri.offset = cpu_to_je32(start);
-+ ri.dsize = cpu_to_je32(end - start);
-+ ri.csize = cpu_to_je32(0);
- ri.compr = JFFS2_COMPR_ZERO;
- }
-- ri.mode = inode->i_mode;
-- ri.uid = inode->i_uid;
-- ri.gid = inode->i_gid;
-- ri.isize = inode->i_size;
-- ri.atime = inode->i_atime;
-- ri.ctime = inode->i_ctime;
-- ri.mtime = inode->i_mtime;
-- ri.data_crc = 0;
-- ri.node_crc = crc32(0, &ri, sizeof(ri)-8);
-+ ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
-+ ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
-+ ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
-+ ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f));
-+ ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
-+ ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
-+ ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f));
-+ ri.data_crc = cpu_to_je32(0);
-+ ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
-
- ret = jffs2_reserve_space_gc(c, sizeof(ri), &phys_ofs, &alloclen);
- if (ret) {
-- printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_hole failed: %d\n",
-+ printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_hole failed: %d\n",
- sizeof(ri), ret);
- return ret;
- }
-- new_fn = jffs2_write_dnode(inode, &ri, NULL, 0, phys_ofs, NULL);
-+ new_fn = jffs2_write_dnode(c, f, &ri, NULL, 0, phys_ofs, ALLOC_GC);
-
- if (IS_ERR(new_fn)) {
- printk(KERN_WARNING "Error writing new hole node: %ld\n", PTR_ERR(new_fn));
- return PTR_ERR(new_fn);
- }
-- if (ri.version == f->highest_version) {
-+ if (je32_to_cpu(ri.version) == f->highest_version) {
- jffs2_add_full_dnode_to_inode(c, f, new_fn);
- if (f->metadata) {
- jffs2_mark_node_obsolete(c, f->metadata->raw);
-@@ -541,12 +981,17 @@
- * number as before. (Except in case of error -- see 'goto fill;'
- * above.)
- */
-- D1(if(fn->frags <= 1) {
-+ D1(if(unlikely(fn->frags <= 1)) {
- printk(KERN_WARNING "jffs2_garbage_collect_hole: Replacing fn with %d frag(s) but new ver %d != highest_version %d of ino #%d\n",
-- fn->frags, ri.version, f->highest_version, ri.ino);
-+ fn->frags, je32_to_cpu(ri.version), f->highest_version,
-+ je32_to_cpu(ri.ino));
- });
-
-- for (frag = f->fraglist; frag; frag = frag->next) {
-+ /* This is a partially-overlapped hole node. Mark it REF_NORMAL not REF_PRISTINE */
-+ mark_ref_normal(new_fn->raw);
-+
-+ for (frag = jffs2_lookup_node_frag(&f->fragtree, fn->ofs);
-+ frag; frag = frag_next(frag)) {
- if (frag->ofs > fn->size + fn->ofs)
- break;
- if (frag->node == fn) {
-@@ -571,49 +1016,146 @@
- }
-
- static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-- struct inode *inode, struct jffs2_full_dnode *fn,
-- __u32 start, __u32 end)
-+ struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
-+ uint32_t start, uint32_t end)
- {
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_full_dnode *new_fn;
- struct jffs2_raw_inode ri;
-- __u32 alloclen, phys_ofs, offset, orig_end;
-+ uint32_t alloclen, phys_ofs, offset, orig_end, orig_start;
- int ret = 0;
- unsigned char *comprbuf = NULL, *writebuf;
-- struct page *pg;
-+ unsigned long pg;
- unsigned char *pg_ptr;
-
--
- memset(&ri, 0, sizeof(ri));
-
-- D1(printk(KERN_DEBUG "Writing replacement dnode for ino #%lu from offset 0x%x to 0x%x\n",
-- inode->i_ino, start, end));
-+ D1(printk(KERN_DEBUG "Writing replacement dnode for ino #%u from offset 0x%x to 0x%x\n",
-+ f->inocache->ino, start, end));
-
- orig_end = end;
-+ orig_start = start;
-
-+ if (c->nr_free_blocks + c->nr_erasing_blocks > c->resv_blocks_gcmerge) {
-+ /* Attempt to do some merging. But only expand to cover logically
-+ adjacent frags if the block containing them is already considered
-+ to be dirty. Otherwise we end up with GC just going round in
-+ circles dirtying the nodes it already wrote out, especially
-+ on NAND where we have small eraseblocks and hence a much higher
-+ chance of nodes having to be split to cross boundaries. */
-
-- /* If we're looking at the last node in the block we're
-- garbage-collecting, we allow ourselves to merge as if the
-- block was already erasing. We're likely to be GC'ing a
-- partial page, and the next block we GC is likely to have
-- the other half of this page right at the beginning, which
-- means we'd expand it _then_, as nr_erasing_blocks would have
-- increased since we checked, and in doing so would obsolete
-- the partial node which we'd have written here. Meaning that
-- the GC would churn and churn, and just leave dirty blocks in
-- it's wake.
-- */
-- if(c->nr_free_blocks + c->nr_erasing_blocks > JFFS2_RESERVED_BLOCKS_GCMERGE - (fn->raw->next_phys?0:1)) {
-- /* Shitloads of space */
-- /* FIXME: Integrate this properly with GC calculations */
-- start &= ~(PAGE_CACHE_SIZE-1);
-- end = min_t(__u32, start + PAGE_CACHE_SIZE, inode->i_size);
-- D1(printk(KERN_DEBUG "Plenty of free space, so expanding to write from offset 0x%x to 0x%x\n",
-- start, end));
-- if (end < orig_end) {
-- printk(KERN_WARNING "Eep. jffs2_garbage_collect_dnode extended node to write, but it got smaller: start 0x%x, orig_end 0x%x, end 0x%x\n", start, orig_end, end);
-- end = orig_end;
-+ struct jffs2_node_frag *frag;
-+ uint32_t min, max;
-+
-+ min = start & ~(PAGE_CACHE_SIZE-1);
-+ max = min + PAGE_CACHE_SIZE;
-+
-+ frag = jffs2_lookup_node_frag(&f->fragtree, start);
-+
-+ /* BUG_ON(!frag) but that'll happen anyway... */
-+
-+ BUG_ON(frag->ofs != start);
-+
-+ /* First grow down... */
-+ while((frag = frag_prev(frag)) && frag->ofs >= min) {
-+
-+ /* If the previous frag doesn't even reach the beginning, there's
-+ excessive fragmentation. Just merge. */
-+ if (frag->ofs > min) {
-+ D1(printk(KERN_DEBUG "Expanding down to cover partial frag (0x%x-0x%x)\n",
-+ frag->ofs, frag->ofs+frag->size));
-+ start = frag->ofs;
-+ continue;
-+ }
-+ /* OK. This frag holds the first byte of the page. */
-+ if (!frag->node || !frag->node->raw) {
-+ D1(printk(KERN_DEBUG "First frag in page is hole (0x%x-0x%x). Not expanding down.\n",
-+ frag->ofs, frag->ofs+frag->size));
-+ break;
-+ } else {
-+
-+ /* OK, it's a frag which extends to the beginning of the page. Does it live
-+ in a block which is still considered clean? If so, don't obsolete it.
-+ If not, cover it anyway. */
-+
-+ struct jffs2_raw_node_ref *raw = frag->node->raw;
-+ struct jffs2_eraseblock *jeb;
-+
-+ jeb = &c->blocks[raw->flash_offset / c->sector_size];
-+
-+ if (jeb == c->gcblock) {
-+ D1(printk(KERN_DEBUG "Expanding down to cover frag (0x%x-0x%x) in gcblock at %08x\n",
-+ frag->ofs, frag->ofs+frag->size, ref_offset(raw)));
-+ start = frag->ofs;
-+ break;
- }
-+ if (!ISDIRTY(jeb->dirty_size + jeb->wasted_size)) {
-+ D1(printk(KERN_DEBUG "Not expanding down to cover frag (0x%x-0x%x) in clean block %08x\n",
-+ frag->ofs, frag->ofs+frag->size, jeb->offset));
-+ break;
-+ }
-+
-+ D1(printk(KERN_DEBUG "Expanding down to cover frag (0x%x-0x%x) in dirty block %08x\n",
-+ frag->ofs, frag->ofs+frag->size, jeb->offset));
-+ start = frag->ofs;
-+ break;
-+ }
-+ }
-+
-+ /* ... then up */
-+
-+ /* Find last frag which is actually part of the node we're to GC. */
-+ frag = jffs2_lookup_node_frag(&f->fragtree, end-1);
-+
-+ while((frag = frag_next(frag)) && frag->ofs+frag->size <= max) {
-+
-+ /* If the previous frag doesn't even reach the beginning, there's lots
-+ of fragmentation. Just merge. */
-+ if (frag->ofs+frag->size < max) {
-+ D1(printk(KERN_DEBUG "Expanding up to cover partial frag (0x%x-0x%x)\n",
-+ frag->ofs, frag->ofs+frag->size));
-+ end = frag->ofs + frag->size;
-+ continue;
-+ }
-+
-+ if (!frag->node || !frag->node->raw) {
-+ D1(printk(KERN_DEBUG "Last frag in page is hole (0x%x-0x%x). Not expanding up.\n",
-+ frag->ofs, frag->ofs+frag->size));
-+ break;
-+ } else {
-+
-+ /* OK, it's a frag which extends to the beginning of the page. Does it live
-+ in a block which is still considered clean? If so, don't obsolete it.
-+ If not, cover it anyway. */
-+
-+ struct jffs2_raw_node_ref *raw = frag->node->raw;
-+ struct jffs2_eraseblock *jeb;
-+
-+ jeb = &c->blocks[raw->flash_offset / c->sector_size];
-+
-+ if (jeb == c->gcblock) {
-+ D1(printk(KERN_DEBUG "Expanding up to cover frag (0x%x-0x%x) in gcblock at %08x\n",
-+ frag->ofs, frag->ofs+frag->size, ref_offset(raw)));
-+ end = frag->ofs + frag->size;
-+ break;
-+ }
-+ if (!ISDIRTY(jeb->dirty_size + jeb->wasted_size)) {
-+ D1(printk(KERN_DEBUG "Not expanding up to cover frag (0x%x-0x%x) in clean block %08x\n",
-+ frag->ofs, frag->ofs+frag->size, jeb->offset));
-+ break;
-+ }
-+
-+ D1(printk(KERN_DEBUG "Expanding up to cover frag (0x%x-0x%x) in dirty block %08x\n",
-+ frag->ofs, frag->ofs+frag->size, jeb->offset));
-+ end = frag->ofs + frag->size;
-+ break;
-+ }
-+ }
-+ D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n",
-+ orig_start, orig_end, start, end));
-+
-+ BUG_ON(end > JFFS2_F_I_SIZE(f));
-+ BUG_ON(end < orig_end);
-+ BUG_ON(start > orig_start);
- }
-
- /* First, use readpage() to read the appropriate page into the page cache */
-@@ -623,63 +1165,57 @@
- * page OK. We'll actually write it out again in commit_write, which is a little
- * suboptimal, but at least we're correct.
- */
-- pg = read_cache_page(inode->i_mapping, start >> PAGE_CACHE_SHIFT, (void *)jffs2_do_readpage_unlock, inode);
-+ pg_ptr = jffs2_gc_fetch_page(c, f, start, &pg);
-
-- if (IS_ERR(pg)) {
-- printk(KERN_WARNING "read_cache_page() returned error: %ld\n", PTR_ERR(pg));
-- return PTR_ERR(pg);
-+ if (IS_ERR(pg_ptr)) {
-+ printk(KERN_WARNING "read_cache_page() returned error: %ld\n", PTR_ERR(pg_ptr));
-+ return PTR_ERR(pg_ptr);
- }
-- pg_ptr = (char *)kmap(pg);
-- comprbuf = kmalloc(end - start, GFP_KERNEL);
-
- offset = start;
- while(offset < orig_end) {
-- __u32 datalen;
-- __u32 cdatalen;
-+ uint32_t datalen;
-+ uint32_t cdatalen;
- char comprtype = JFFS2_COMPR_NONE;
-
- ret = jffs2_reserve_space_gc(c, sizeof(ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen);
-
- if (ret) {
-- printk(KERN_WARNING "jffs2_reserve_space_gc of %d bytes for garbage_collect_dnode failed: %d\n",
-+ printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dnode failed: %d\n",
- sizeof(ri)+ JFFS2_MIN_DATA_LEN, ret);
- break;
- }
-- cdatalen = min(alloclen - sizeof(ri), end - offset);
-+ cdatalen = min_t(uint32_t, alloclen - sizeof(ri), end - offset);
- datalen = end - offset;
-
- writebuf = pg_ptr + (offset & (PAGE_CACHE_SIZE -1));
-
-- if (comprbuf) {
-- comprtype = jffs2_compress(writebuf, comprbuf, &datalen, &cdatalen);
-- }
-- if (comprtype) {
-- writebuf = comprbuf;
-- } else {
-- datalen = cdatalen;
-- }
-- ri.magic = JFFS2_MAGIC_BITMASK;
-- ri.nodetype = JFFS2_NODETYPE_INODE;
-- ri.totlen = sizeof(ri) + cdatalen;
-- ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4);
--
-- ri.ino = inode->i_ino;
-- ri.version = ++f->highest_version;
-- ri.mode = inode->i_mode;
-- ri.uid = inode->i_uid;
-- ri.gid = inode->i_gid;
-- ri.isize = inode->i_size;
-- ri.atime = inode->i_atime;
-- ri.ctime = inode->i_ctime;
-- ri.mtime = inode->i_mtime;
-- ri.offset = offset;
-- ri.csize = cdatalen;
-- ri.dsize = datalen;
-+ comprtype = jffs2_compress(writebuf, &comprbuf, &datalen, &cdatalen);
-+
-+ ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
-+ ri.totlen = cpu_to_je32(sizeof(ri) + cdatalen);
-+ ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4));
-+
-+ ri.ino = cpu_to_je32(f->inocache->ino);
-+ ri.version = cpu_to_je32(++f->highest_version);
-+ ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
-+ ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
-+ ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
-+ ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f));
-+ ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
-+ ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
-+ ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f));
-+ ri.offset = cpu_to_je32(offset);
-+ ri.csize = cpu_to_je32(cdatalen);
-+ ri.dsize = cpu_to_je32(datalen);
- ri.compr = comprtype;
-- ri.node_crc = crc32(0, &ri, sizeof(ri)-8);
-- ri.data_crc = crc32(0, writebuf, cdatalen);
-+ ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
-+ ri.data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
-+
-+ new_fn = jffs2_write_dnode(c, f, &ri, comprbuf, cdatalen, phys_ofs, ALLOC_GC);
-
-- new_fn = jffs2_write_dnode(inode, &ri, writebuf, cdatalen, phys_ofs, NULL);
-+ jffs2_free_comprbuf(comprbuf, writebuf);
-
- if (IS_ERR(new_fn)) {
- printk(KERN_WARNING "Error writing new dnode: %ld\n", PTR_ERR(new_fn));
-@@ -694,12 +1230,8 @@
- f->metadata = NULL;
- }
- }
-- if (comprbuf) kfree(comprbuf);
-
-- kunmap(pg);
-- /* XXX: Does the page get freed automatically? */
-- /* AAA: Judging by the unmount getting stuck in __wait_on_page, nope. */
-- page_cache_release(pg);
-+ jffs2_gc_release_page(c, pg_ptr, &pg);
- return ret;
- }
-
-diff -Nurb linux-mips-2.4.27/fs/jffs2/ioctl.c linux/fs/jffs2/ioctl.c
---- linux-mips-2.4.27/fs/jffs2/ioctl.c 2001-10-19 03:24:56.000000000 +0200
-+++ linux/fs/jffs2/ioctl.c 2004-11-19 10:25:12.108168024 +0100
-@@ -1,37 +1,13 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
-@@ -42,6 +18,6 @@
- {
- /* Later, this will provide for lsattr.jffs2 and chattr.jffs2, which
- will include compression support etc. */
-- return -EINVAL;
-+ return -ENOTTY;
- }
-
-diff -Nurb linux-mips-2.4.27/fs/jffs2/malloc.c linux/fs/jffs2/malloc.c
---- linux-mips-2.4.27/fs/jffs2/malloc.c 2001-10-19 03:24:56.000000000 +0200
-+++ linux/fs/jffs2/malloc.c 2004-11-19 10:25:12.110167720 +0100
-@@ -1,37 +1,13 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
-@@ -47,6 +23,9 @@
- #define JFFS2_SLAB_POISON 0
- #endif
-
-+// replace this by #define D3 (x) x for cache debugging
-+#define D3(x)
-+
- /* These are initialised to NULL in the kernel startup code.
- If you're porting to other operating systems, beware */
- static kmem_cache_t *full_dnode_slab;
-@@ -57,57 +36,47 @@
- static kmem_cache_t *node_frag_slab;
- static kmem_cache_t *inode_cache_slab;
-
--void jffs2_free_tmp_dnode_info_list(struct jffs2_tmp_dnode_info *tn)
--{
-- struct jffs2_tmp_dnode_info *next;
--
-- while (tn) {
-- next = tn;
-- tn = tn->next;
-- jffs2_free_full_dnode(next->fn);
-- jffs2_free_tmp_dnode_info(next);
-- }
--}
--
--void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
--{
-- struct jffs2_full_dirent *next;
--
-- while (fd) {
-- next = fd->next;
-- jffs2_free_full_dirent(fd);
-- fd = next;
-- }
--}
--
- int __init jffs2_create_slab_caches(void)
- {
-- full_dnode_slab = kmem_cache_create("jffs2_full_dnode", sizeof(struct jffs2_full_dnode), 0, JFFS2_SLAB_POISON, NULL, NULL);
-+ full_dnode_slab = kmem_cache_create("jffs2_full_dnode",
-+ sizeof(struct jffs2_full_dnode),
-+ 0, JFFS2_SLAB_POISON, NULL, NULL);
- if (!full_dnode_slab)
- goto err;
-
-- raw_dirent_slab = kmem_cache_create("jffs2_raw_dirent", sizeof(struct jffs2_raw_dirent), 0, JFFS2_SLAB_POISON, NULL, NULL);
-+ raw_dirent_slab = kmem_cache_create("jffs2_raw_dirent",
-+ sizeof(struct jffs2_raw_dirent),
-+ 0, JFFS2_SLAB_POISON, NULL, NULL);
- if (!raw_dirent_slab)
- goto err;
-
-- raw_inode_slab = kmem_cache_create("jffs2_raw_inode", sizeof(struct jffs2_raw_inode), 0, JFFS2_SLAB_POISON, NULL, NULL);
-+ raw_inode_slab = kmem_cache_create("jffs2_raw_inode",
-+ sizeof(struct jffs2_raw_inode),
-+ 0, JFFS2_SLAB_POISON, NULL, NULL);
- if (!raw_inode_slab)
- goto err;
-
-- tmp_dnode_info_slab = kmem_cache_create("jffs2_tmp_dnode", sizeof(struct jffs2_tmp_dnode_info), 0, JFFS2_SLAB_POISON, NULL, NULL);
-+ tmp_dnode_info_slab = kmem_cache_create("jffs2_tmp_dnode",
-+ sizeof(struct jffs2_tmp_dnode_info),
-+ 0, JFFS2_SLAB_POISON, NULL, NULL);
- if (!tmp_dnode_info_slab)
- goto err;
-
-- raw_node_ref_slab = kmem_cache_create("jffs2_raw_node_ref", sizeof(struct jffs2_raw_node_ref), 0, JFFS2_SLAB_POISON, NULL, NULL);
-+ raw_node_ref_slab = kmem_cache_create("jffs2_raw_node_ref",
-+ sizeof(struct jffs2_raw_node_ref),
-+ 0, JFFS2_SLAB_POISON, NULL, NULL);
- if (!raw_node_ref_slab)
- goto err;
-
-- node_frag_slab = kmem_cache_create("jffs2_node_frag", sizeof(struct jffs2_node_frag), 0, JFFS2_SLAB_POISON, NULL, NULL);
-+ node_frag_slab = kmem_cache_create("jffs2_node_frag",
-+ sizeof(struct jffs2_node_frag),
-+ 0, JFFS2_SLAB_POISON, NULL, NULL);
- if (!node_frag_slab)
- goto err;
-
-- inode_cache_slab = kmem_cache_create("jffs2_inode_cache", sizeof(struct jffs2_inode_cache), 0, JFFS2_SLAB_POISON, NULL, NULL);
--
-+ inode_cache_slab = kmem_cache_create("jffs2_inode_cache",
-+ sizeof(struct jffs2_inode_cache),
-+ 0, JFFS2_SLAB_POISON, NULL, NULL);
- if (inode_cache_slab)
- return 0;
- err:
-@@ -131,7 +100,6 @@
- kmem_cache_destroy(node_frag_slab);
- if(inode_cache_slab)
- kmem_cache_destroy(inode_cache_slab);
--
- }
-
- struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize)
-@@ -146,75 +114,92 @@
-
- struct jffs2_full_dnode *jffs2_alloc_full_dnode(void)
- {
-- void *ret = kmem_cache_alloc(full_dnode_slab, GFP_KERNEL);
-+ struct jffs2_full_dnode *ret = kmem_cache_alloc(full_dnode_slab, GFP_KERNEL);
-+ D3 (printk (KERN_DEBUG "alloc_full_dnode at %p\n", ret));
- return ret;
- }
-
- void jffs2_free_full_dnode(struct jffs2_full_dnode *x)
- {
-+ D3 (printk (KERN_DEBUG "free full_dnode at %p\n", x));
- kmem_cache_free(full_dnode_slab, x);
- }
-
- struct jffs2_raw_dirent *jffs2_alloc_raw_dirent(void)
- {
-- return kmem_cache_alloc(raw_dirent_slab, GFP_KERNEL);
-+ struct jffs2_raw_dirent *ret = kmem_cache_alloc(raw_dirent_slab, GFP_KERNEL);
-+ D3 (printk (KERN_DEBUG "alloc_raw_dirent\n", ret));
-+ return ret;
- }
-
- void jffs2_free_raw_dirent(struct jffs2_raw_dirent *x)
- {
-+ D3 (printk (KERN_DEBUG "free_raw_dirent at %p\n", x));
- kmem_cache_free(raw_dirent_slab, x);
- }
-
- struct jffs2_raw_inode *jffs2_alloc_raw_inode(void)
- {
-- return kmem_cache_alloc(raw_inode_slab, GFP_KERNEL);
-+ struct jffs2_raw_inode *ret = kmem_cache_alloc(raw_inode_slab, GFP_KERNEL);
-+ D3 (printk (KERN_DEBUG "alloc_raw_inode at %p\n", ret));
-+ return ret;
- }
-
- void jffs2_free_raw_inode(struct jffs2_raw_inode *x)
- {
-+ D3 (printk (KERN_DEBUG "free_raw_inode at %p\n", x));
- kmem_cache_free(raw_inode_slab, x);
- }
-
- struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void)
- {
-- return kmem_cache_alloc(tmp_dnode_info_slab, GFP_KERNEL);
-+ struct jffs2_tmp_dnode_info *ret = kmem_cache_alloc(tmp_dnode_info_slab, GFP_KERNEL);
-+ D3 (printk (KERN_DEBUG "alloc_tmp_dnode_info at %p\n", ret));
-+ return ret;
- }
-
- void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x)
- {
-+ D3 (printk (KERN_DEBUG "free_tmp_dnode_info at %p\n", x));
- kmem_cache_free(tmp_dnode_info_slab, x);
- }
-
- struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void)
- {
-- return kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL);
-+ struct jffs2_raw_node_ref *ret = kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL);
-+ D3 (printk (KERN_DEBUG "alloc_raw_node_ref at %p\n", ret));
-+ return ret;
- }
-
- void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x)
- {
-+ D3 (printk (KERN_DEBUG "free_raw_node_ref at %p\n", x));
- kmem_cache_free(raw_node_ref_slab, x);
- }
-
- struct jffs2_node_frag *jffs2_alloc_node_frag(void)
- {
-- return kmem_cache_alloc(node_frag_slab, GFP_KERNEL);
-+ struct jffs2_node_frag *ret = kmem_cache_alloc(node_frag_slab, GFP_KERNEL);
-+ D3 (printk (KERN_DEBUG "alloc_node_frag at %p\n", ret));
-+ return ret;
- }
-
- void jffs2_free_node_frag(struct jffs2_node_frag *x)
- {
-+ D3 (printk (KERN_DEBUG "free_node_frag at %p\n", x));
- kmem_cache_free(node_frag_slab, x);
- }
-
- struct jffs2_inode_cache *jffs2_alloc_inode_cache(void)
- {
- struct jffs2_inode_cache *ret = kmem_cache_alloc(inode_cache_slab, GFP_KERNEL);
-- D1(printk(KERN_DEBUG "Allocated inocache at %p\n", ret));
-+ D3 (printk(KERN_DEBUG "Allocated inocache at %p\n", ret));
- return ret;
- }
-
- void jffs2_free_inode_cache(struct jffs2_inode_cache *x)
- {
-- D1(printk(KERN_DEBUG "Freeing inocache at %p\n", x));
-+ D3 (printk(KERN_DEBUG "Freeing inocache at %p\n", x));
- kmem_cache_free(inode_cache_slab, x);
- }
-
-diff -Nurb linux-mips-2.4.27/fs/jffs2/nodelist.c linux/fs/jffs2/nodelist.c
---- linux-mips-2.4.27/fs/jffs2/nodelist.c 2003-07-05 05:23:44.000000000 +0200
-+++ linux/fs/jffs2/nodelist.c 2004-11-19 10:25:12.112167416 +0100
-@@ -1,44 +1,24 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001, 2002 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/kernel.h>
--#include <linux/jffs2.h>
-+#include <linux/sched.h>
- #include <linux/fs.h>
- #include <linux/mtd/mtd.h>
-+#include <linux/rbtree.h>
-+#include <linux/crc32.h>
-+#include <linux/slab.h>
-+#include <linux/pagemap.h>
- #include "nodelist.h"
-
- void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list)
-@@ -78,7 +58,7 @@
- /* Put a new tmp_dnode_info into the list, keeping the list in
- order of increasing version
- */
--void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct jffs2_tmp_dnode_info **list)
-+static void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct jffs2_tmp_dnode_info **list)
- {
- struct jffs2_tmp_dnode_info **prev = list;
-
-@@ -89,13 +69,37 @@
- *prev = tn;
- }
-
-+static void jffs2_free_tmp_dnode_info_list(struct jffs2_tmp_dnode_info *tn)
-+{
-+ struct jffs2_tmp_dnode_info *next;
-+
-+ while (tn) {
-+ next = tn;
-+ tn = tn->next;
-+ jffs2_free_full_dnode(next->fn);
-+ jffs2_free_tmp_dnode_info(next);
-+ }
-+}
-+
-+static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
-+{
-+ struct jffs2_full_dirent *next;
-+
-+ while (fd) {
-+ next = fd->next;
-+ jffs2_free_full_dirent(fd);
-+ fd = next;
-+ }
-+}
-+
-+
- /* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated
- with this ino, returning the former in order of version */
-
- int jffs2_get_inode_nodes(struct jffs2_sb_info *c, ino_t ino, struct jffs2_inode_info *f,
- struct jffs2_tmp_dnode_info **tnp, struct jffs2_full_dirent **fdp,
-- __u32 *highest_version, __u32 *latest_mctime,
-- __u32 *mctime_ver)
-+ uint32_t *highest_version, uint32_t *latest_mctime,
-+ uint32_t *mctime_ver)
- {
- struct jffs2_raw_node_ref *ref = f->inocache->nodes;
- struct jffs2_tmp_dnode_info *tn, *ret_tn = NULL;
-@@ -109,43 +113,71 @@
-
- D1(printk(KERN_DEBUG "jffs2_get_inode_nodes(): ino #%lu\n", ino));
- if (!f->inocache->nodes) {
-- printk(KERN_WARNING "Eep. no nodes for ino #%lu\n", ino);
-+ printk(KERN_WARNING "Eep. no nodes for ino #%lu\n", (unsigned long)ino);
- }
-+
-+ spin_lock(&c->erase_completion_lock);
-+
- for (ref = f->inocache->nodes; ref && ref->next_in_ino; ref = ref->next_in_ino) {
- /* Work out whether it's a data node or a dirent node */
-- if (ref->flash_offset & 1) {
-+ if (ref_obsolete(ref)) {
- /* FIXME: On NAND flash we may need to read these */
-- D1(printk(KERN_DEBUG "node at 0x%08x is obsoleted. Ignoring.\n", ref->flash_offset &~3));
-+ D1(printk(KERN_DEBUG "node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref)));
- continue;
- }
-- err = c->mtd->read(c->mtd, (ref->flash_offset & ~3), min(ref->totlen, sizeof(node)), &retlen, (void *)&node);
-+ /* We can hold a pointer to a non-obsolete node without the spinlock,
-+ but _obsolete_ nodes may disappear at any time, if the block
-+ they're in gets erased */
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ cond_resched();
-+
-+ /* FIXME: point() */
-+ err = jffs2_flash_read(c, (ref_offset(ref)),
-+ min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node)),
-+ &retlen, (void *)&node);
- if (err) {
-- printk(KERN_WARNING "error %d reading node at 0x%08x in get_inode_nodes()\n", err, (ref->flash_offset) & ~3);
-+ printk(KERN_WARNING "error %d reading node at 0x%08x in get_inode_nodes()\n", err, ref_offset(ref));
- goto free_out;
- }
-
-
- /* Check we've managed to read at least the common node header */
-- if (retlen < min(ref->totlen, sizeof(node.u))) {
-+ if (retlen < min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node.u))) {
- printk(KERN_WARNING "short read in get_inode_nodes()\n");
- err = -EIO;
- goto free_out;
- }
-
-- switch (node.u.nodetype) {
-+ switch (je16_to_cpu(node.u.nodetype)) {
- case JFFS2_NODETYPE_DIRENT:
-- D1(printk(KERN_DEBUG "Node at %08x is a dirent node\n", ref->flash_offset &~3));
-+ D1(printk(KERN_DEBUG "Node at %08x (%d) is a dirent node\n", ref_offset(ref), ref_flags(ref)));
-+ if (ref_flags(ref) == REF_UNCHECKED) {
-+ printk(KERN_WARNING "BUG: Dirent node at 0x%08x never got checked? How?\n", ref_offset(ref));
-+ BUG();
-+ }
- if (retlen < sizeof(node.d)) {
- printk(KERN_WARNING "short read in get_inode_nodes()\n");
- err = -EIO;
- goto free_out;
- }
-- if (node.d.version > *highest_version)
-- *highest_version = node.d.version;
-- if (ref->flash_offset & 1) {
-- /* Obsoleted */
-+ /* sanity check */
-+ if (PAD((node.d.nsize + sizeof (node.d))) != PAD(je32_to_cpu (node.d.totlen))) {
-+ printk(KERN_NOTICE "jffs2_get_inode_nodes(): Illegal nsize in node at 0x%08x: nsize 0x%02x, totlen %04x\n",
-+ ref_offset(ref), node.d.nsize, je32_to_cpu(node.d.totlen));
-+ jffs2_mark_node_obsolete(c, ref);
-+ spin_lock(&c->erase_completion_lock);
- continue;
- }
-+ if (je32_to_cpu(node.d.version) > *highest_version)
-+ *highest_version = je32_to_cpu(node.d.version);
-+ if (ref_obsolete(ref)) {
-+ /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
-+ printk(KERN_ERR "Dirent node at 0x%08x became obsolete while we weren't looking\n",
-+ ref_offset(ref));
-+ BUG();
-+ }
-+
- fd = jffs2_alloc_full_dirent(node.d.nsize+1);
- if (!fd) {
- err = -ENOMEM;
-@@ -153,29 +185,30 @@
- }
- memset(fd,0,sizeof(struct jffs2_full_dirent) + node.d.nsize+1);
- fd->raw = ref;
-- fd->version = node.d.version;
-- fd->ino = node.d.ino;
-+ fd->version = je32_to_cpu(node.d.version);
-+ fd->ino = je32_to_cpu(node.d.ino);
- fd->type = node.d.type;
-
- /* Pick out the mctime of the latest dirent */
- if(fd->version > *mctime_ver) {
- *mctime_ver = fd->version;
-- *latest_mctime = node.d.mctime;
-+ *latest_mctime = je32_to_cpu(node.d.mctime);
- }
-
- /* memcpy as much of the name as possible from the raw
- dirent we've already read from the flash
- */
- if (retlen > sizeof(struct jffs2_raw_dirent))
-- memcpy(&fd->name[0], &node.d.name[0], min((__u32)node.d.nsize, (retlen-sizeof(struct jffs2_raw_dirent))));
-+ memcpy(&fd->name[0], &node.d.name[0], min_t(uint32_t, node.d.nsize, (retlen-sizeof(struct jffs2_raw_dirent))));
-
- /* Do we need to copy any more of the name directly
- from the flash?
- */
- if (node.d.nsize + sizeof(struct jffs2_raw_dirent) > retlen) {
-+ /* FIXME: point() */
- int already = retlen - sizeof(struct jffs2_raw_dirent);
-
-- err = c->mtd->read(c->mtd, (ref->flash_offset & ~3) + retlen,
-+ err = jffs2_flash_read(c, (ref_offset(ref)) + retlen,
- node.d.nsize - already, &retlen, &fd->name[already]);
- if (!err && retlen != node.d.nsize - already)
- err = -EIO;
-@@ -196,21 +229,126 @@
- break;
-
- case JFFS2_NODETYPE_INODE:
-- D1(printk(KERN_DEBUG "Node at %08x is a data node\n", ref->flash_offset &~3));
-+ D1(printk(KERN_DEBUG "Node at %08x (%d) is a data node\n", ref_offset(ref), ref_flags(ref)));
- if (retlen < sizeof(node.i)) {
- printk(KERN_WARNING "read too short for dnode\n");
- err = -EIO;
- goto free_out;
- }
-- if (node.i.version > *highest_version)
-- *highest_version = node.i.version;
-- D1(printk(KERN_DEBUG "version %d, highest_version now %d\n", node.i.version, *highest_version));
--
-- if (ref->flash_offset & 1) {
-- D1(printk(KERN_DEBUG "obsoleted\n"));
-- /* Obsoleted */
-+ if (je32_to_cpu(node.i.version) > *highest_version)
-+ *highest_version = je32_to_cpu(node.i.version);
-+ D1(printk(KERN_DEBUG "version %d, highest_version now %d\n", je32_to_cpu(node.i.version), *highest_version));
-+
-+ if (ref_obsolete(ref)) {
-+ /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */
-+ printk(KERN_ERR "Inode node at 0x%08x became obsolete while we weren't looking\n",
-+ ref_offset(ref));
-+ BUG();
-+ }
-+
-+ /* If we've never checked the CRCs on this node, check them now. */
-+ if (ref_flags(ref) == REF_UNCHECKED) {
-+ uint32_t crc, len;
-+ struct jffs2_eraseblock *jeb;
-+
-+ crc = crc32(0, &node, sizeof(node.i)-8);
-+ if (crc != je32_to_cpu(node.i.node_crc)) {
-+ printk(KERN_NOTICE "jffs2_get_inode_nodes(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-+ ref_offset(ref), je32_to_cpu(node.i.node_crc), crc);
-+ jffs2_mark_node_obsolete(c, ref);
-+ spin_lock(&c->erase_completion_lock);
- continue;
- }
-+
-+ /* sanity checks */
-+ if ( je32_to_cpu(node.i.offset) > je32_to_cpu(node.i.isize) ||
-+ PAD(je32_to_cpu(node.i.csize) + sizeof (node.i)) != PAD(je32_to_cpu(node.i.totlen))) {
-+ printk(KERN_NOTICE "jffs2_get_inode_nodes(): Inode corrupted at 0x%08x, totlen %d, #ino %d, version %d, isize %d, csize %d, dsize %d \n",
-+ ref_offset(ref), je32_to_cpu(node.i.totlen), je32_to_cpu(node.i.ino),
-+ je32_to_cpu(node.i.version), je32_to_cpu(node.i.isize),
-+ je32_to_cpu(node.i.csize), je32_to_cpu(node.i.dsize));
-+ jffs2_mark_node_obsolete(c, ref);
-+ spin_lock(&c->erase_completion_lock);
-+ continue;
-+ }
-+
-+ if (node.i.compr != JFFS2_COMPR_ZERO && je32_to_cpu(node.i.csize)) {
-+ unsigned char *buf=NULL;
-+ uint32_t pointed = 0;
-+#ifndef __ECOS
-+ if (c->mtd->point) {
-+ err = c->mtd->point (c->mtd, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize),
-+ &retlen, &buf);
-+ if (!err && retlen < je32_to_cpu(node.i.csize)) {
-+ D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", retlen));
-+ c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize));
-+ } else if (err){
-+ D1(printk(KERN_DEBUG "MTD point failed %d\n", err));
-+ } else
-+ pointed = 1; /* succefully pointed to device */
-+ }
-+#endif
-+ if(!pointed){
-+ buf = kmalloc(je32_to_cpu(node.i.csize), GFP_KERNEL);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ err = jffs2_flash_read(c, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize),
-+ &retlen, buf);
-+ if (!err && retlen != je32_to_cpu(node.i.csize))
-+ err = -EIO;
-+ if (err) {
-+ kfree(buf);
-+ return err;
-+ }
-+ }
-+ crc = crc32(0, buf, je32_to_cpu(node.i.csize));
-+ if(!pointed)
-+ kfree(buf);
-+#ifndef __ECOS
-+ else
-+ c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(node.i), je32_to_cpu(node.i.csize));
-+#endif
-+
-+ if (crc != je32_to_cpu(node.i.data_crc)) {
-+ printk(KERN_NOTICE "jffs2_get_inode_nodes(): Data CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-+ ref_offset(ref), je32_to_cpu(node.i.data_crc), crc);
-+ jffs2_mark_node_obsolete(c, ref);
-+ spin_lock(&c->erase_completion_lock);
-+ continue;
-+ }
-+
-+ }
-+
-+ /* Mark the node as having been checked and fix the accounting accordingly */
-+ spin_lock(&c->erase_completion_lock);
-+ jeb = &c->blocks[ref->flash_offset / c->sector_size];
-+ len = ref_totlen(c, jeb, ref);
-+
-+ jeb->used_size += len;
-+ jeb->unchecked_size -= len;
-+ c->used_size += len;
-+ c->unchecked_size -= len;
-+
-+ /* If node covers at least a whole page, or if it starts at the
-+ beginning of a page and runs to the end of the file, or if
-+ it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
-+
-+ If it's actually overlapped, it'll get made NORMAL (or OBSOLETE)
-+ when the overlapping node(s) get added to the tree anyway.
-+ */
-+ if ((je32_to_cpu(node.i.dsize) >= PAGE_CACHE_SIZE) ||
-+ ( ((je32_to_cpu(node.i.offset)&(PAGE_CACHE_SIZE-1))==0) &&
-+ (je32_to_cpu(node.i.dsize)+je32_to_cpu(node.i.offset) == je32_to_cpu(node.i.isize)))) {
-+ D1(printk(KERN_DEBUG "Marking node at 0x%08x REF_PRISTINE\n", ref_offset(ref)));
-+ ref->flash_offset = ref_offset(ref) | REF_PRISTINE;
-+ } else {
-+ D1(printk(KERN_DEBUG "Marking node at 0x%08x REF_NORMAL\n", ref_offset(ref)));
-+ ref->flash_offset = ref_offset(ref) | REF_NORMAL;
-+ }
-+ spin_unlock(&c->erase_completion_lock);
-+ }
-+
- tn = jffs2_alloc_tmp_dnode_info();
- if (!tn) {
- D1(printk(KERN_DEBUG "alloc tn failed\n"));
-@@ -225,36 +363,76 @@
- jffs2_free_tmp_dnode_info(tn);
- goto free_out;
- }
-- tn->version = node.i.version;
-- tn->fn->ofs = node.i.offset;
-+ tn->version = je32_to_cpu(node.i.version);
-+ tn->fn->ofs = je32_to_cpu(node.i.offset);
- /* There was a bug where we wrote hole nodes out with
- csize/dsize swapped. Deal with it */
-- if (node.i.compr == JFFS2_COMPR_ZERO && !node.i.dsize && node.i.csize)
-- tn->fn->size = node.i.csize;
-+ if (node.i.compr == JFFS2_COMPR_ZERO && !je32_to_cpu(node.i.dsize) && je32_to_cpu(node.i.csize))
-+ tn->fn->size = je32_to_cpu(node.i.csize);
- else // normal case...
-- tn->fn->size = node.i.dsize;
-+ tn->fn->size = je32_to_cpu(node.i.dsize);
- tn->fn->raw = ref;
-- D1(printk(KERN_DEBUG "dnode @%08x: ver %u, offset %04x, dsize %04x\n", ref->flash_offset &~3, node.i.version, node.i.offset, node.i.dsize));
-+ D1(printk(KERN_DEBUG "dnode @%08x: ver %u, offset %04x, dsize %04x\n",
-+ ref_offset(ref), je32_to_cpu(node.i.version),
-+ je32_to_cpu(node.i.offset), je32_to_cpu(node.i.dsize)));
- jffs2_add_tn_to_list(tn, &ret_tn);
- break;
-
- default:
-- switch(node.u.nodetype & JFFS2_COMPAT_MASK) {
-+ if (ref_flags(ref) == REF_UNCHECKED) {
-+ struct jffs2_eraseblock *jeb;
-+ uint32_t len;
-+
-+ printk(KERN_ERR "Eep. Unknown node type %04x at %08x was marked REF_UNCHECKED\n",
-+ je16_to_cpu(node.u.nodetype), ref_offset(ref));
-+
-+ /* Mark the node as having been checked and fix the accounting accordingly */
-+ spin_lock(&c->erase_completion_lock);
-+ jeb = &c->blocks[ref->flash_offset / c->sector_size];
-+ len = ref_totlen(c, jeb, ref);
-+
-+ jeb->used_size += len;
-+ jeb->unchecked_size -= len;
-+ c->used_size += len;
-+ c->unchecked_size -= len;
-+
-+ mark_ref_normal(ref);
-+ spin_unlock(&c->erase_completion_lock);
-+ }
-+ node.u.nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(node.u.nodetype));
-+ if (crc32(0, &node, sizeof(struct jffs2_unknown_node)-4) != je32_to_cpu(node.u.hdr_crc)) {
-+ /* Hmmm. This should have been caught at scan time. */
-+ printk(KERN_ERR "Node header CRC failed at %08x. But it must have been OK earlier.\n",
-+ ref_offset(ref));
-+ printk(KERN_ERR "Node was: { %04x, %04x, %08x, %08x }\n",
-+ je16_to_cpu(node.u.magic), je16_to_cpu(node.u.nodetype), je32_to_cpu(node.u.totlen),
-+ je32_to_cpu(node.u.hdr_crc));
-+ jffs2_mark_node_obsolete(c, ref);
-+ } else switch(je16_to_cpu(node.u.nodetype) & JFFS2_COMPAT_MASK) {
- case JFFS2_FEATURE_INCOMPAT:
-- printk(KERN_NOTICE "Unknown INCOMPAT nodetype %04X at %08X\n", node.u.nodetype, ref->flash_offset & ~3);
-+ printk(KERN_NOTICE "Unknown INCOMPAT nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
-+ /* EEP */
-+ BUG();
- break;
- case JFFS2_FEATURE_ROCOMPAT:
-- printk(KERN_NOTICE "Unknown ROCOMPAT nodetype %04X at %08X\n", node.u.nodetype, ref->flash_offset & ~3);
-+ printk(KERN_NOTICE "Unknown ROCOMPAT nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
-+ if (!(c->flags & JFFS2_SB_FLAG_RO))
-+ BUG();
- break;
- case JFFS2_FEATURE_RWCOMPAT_COPY:
-- printk(KERN_NOTICE "Unknown RWCOMPAT_COPY nodetype %04X at %08X\n", node.u.nodetype, ref->flash_offset & ~3);
-+ printk(KERN_NOTICE "Unknown RWCOMPAT_COPY nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
- break;
- case JFFS2_FEATURE_RWCOMPAT_DELETE:
-- printk(KERN_NOTICE "Unknown RWCOMPAT_DELETE nodetype %04X at %08X\n", node.u.nodetype, ref->flash_offset & ~3);
-+ printk(KERN_NOTICE "Unknown RWCOMPAT_DELETE nodetype %04X at %08x\n", je16_to_cpu(node.u.nodetype), ref_offset(ref));
-+ jffs2_mark_node_obsolete(c, ref);
- break;
- }
-+
- }
-+ spin_lock(&c->erase_completion_lock);
-+
- }
-+ spin_unlock(&c->erase_completion_lock);
- *tnp = ret_tn;
- *fdp = ret_fd;
-
-@@ -266,19 +444,30 @@
- return err;
- }
-
-+void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state)
-+{
-+ spin_lock(&c->inocache_lock);
-+ ic->state = state;
-+ wake_up(&c->inocache_wq);
-+ spin_unlock(&c->inocache_lock);
-+}
-+
-+/* During mount, this needs no locking. During normal operation, its
-+ callers want to do other stuff while still holding the inocache_lock.
-+ Rather than introducing special case get_ino_cache functions or
-+ callbacks, we just let the caller do the locking itself. */
-+
- struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino)
- {
- struct jffs2_inode_cache *ret;
-
- D2(printk(KERN_DEBUG "jffs2_get_ino_cache(): ino %u\n", ino));
-- spin_lock (&c->inocache_lock);
-+
- ret = c->inocache_list[ino % INOCACHE_HASHSIZE];
- while (ret && ret->ino < ino) {
- ret = ret->next;
- }
-
-- spin_unlock(&c->inocache_lock);
--
- if (ret && ret->ino != ino)
- ret = NULL;
-
-@@ -299,6 +488,7 @@
- }
- new->next = *prev;
- *prev = new;
-+
- spin_unlock(&c->inocache_lock);
- }
-
-@@ -316,6 +506,7 @@
- if ((*prev) == old) {
- *prev = old->next;
- }
-+
- spin_unlock(&c->inocache_lock);
- }
-
-@@ -352,3 +543,128 @@
- }
- }
-
-+struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset)
-+{
-+ /* The common case in lookup is that there will be a node
-+ which precisely matches. So we go looking for that first */
-+ struct rb_node *next;
-+ struct jffs2_node_frag *prev = NULL;
-+ struct jffs2_node_frag *frag = NULL;
-+
-+ D2(printk(KERN_DEBUG "jffs2_lookup_node_frag(%p, %d)\n", fragtree, offset));
-+
-+ next = fragtree->rb_node;
-+
-+ while(next) {
-+ frag = rb_entry(next, struct jffs2_node_frag, rb);
-+
-+ D2(printk(KERN_DEBUG "Considering frag %d-%d (%p). left %p, right %p\n",
-+ frag->ofs, frag->ofs+frag->size, frag, frag->rb.rb_left, frag->rb.rb_right));
-+ if (frag->ofs + frag->size <= offset) {
-+ D2(printk(KERN_DEBUG "Going right from frag %d-%d, before the region we care about\n",
-+ frag->ofs, frag->ofs+frag->size));
-+ /* Remember the closest smaller match on the way down */
-+ if (!prev || frag->ofs > prev->ofs)
-+ prev = frag;
-+ next = frag->rb.rb_right;
-+ } else if (frag->ofs > offset) {
-+ D2(printk(KERN_DEBUG "Going left from frag %d-%d, after the region we care about\n",
-+ frag->ofs, frag->ofs+frag->size));
-+ next = frag->rb.rb_left;
-+ } else {
-+ D2(printk(KERN_DEBUG "Returning frag %d,%d, matched\n",
-+ frag->ofs, frag->ofs+frag->size));
-+ return frag;
-+ }
-+ }
-+
-+ /* Exact match not found. Go back up looking at each parent,
-+ and return the closest smaller one */
-+
-+ if (prev)
-+ D2(printk(KERN_DEBUG "No match. Returning frag %d,%d, closest previous\n",
-+ prev->ofs, prev->ofs+prev->size));
-+ else
-+ D2(printk(KERN_DEBUG "Returning NULL, empty fragtree\n"));
-+
-+ return prev;
-+}
-+
-+/* Pass 'c' argument to indicate that nodes should be marked obsolete as
-+ they're killed. */
-+void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c)
-+{
-+ struct jffs2_node_frag *frag;
-+ struct jffs2_node_frag *parent;
-+
-+ if (!root->rb_node)
-+ return;
-+
-+ frag = (rb_entry(root->rb_node, struct jffs2_node_frag, rb));
-+
-+ while(frag) {
-+ if (frag->rb.rb_left) {
-+ D2(printk(KERN_DEBUG "Going left from frag (%p) %d-%d\n",
-+ frag, frag->ofs, frag->ofs+frag->size));
-+ frag = frag_left(frag);
-+ continue;
-+ }
-+ if (frag->rb.rb_right) {
-+ D2(printk(KERN_DEBUG "Going right from frag (%p) %d-%d\n",
-+ frag, frag->ofs, frag->ofs+frag->size));
-+ frag = frag_right(frag);
-+ continue;
-+ }
-+
-+ D2(printk(KERN_DEBUG "jffs2_kill_fragtree: frag at 0x%x-0x%x: node %p, frags %d--\n",
-+ frag->ofs, frag->ofs+frag->size, frag->node,
-+ frag->node?frag->node->frags:0));
-+
-+ if (frag->node && !(--frag->node->frags)) {
-+ /* Not a hole, and it's the final remaining frag
-+ of this node. Free the node */
-+ if (c)
-+ jffs2_mark_node_obsolete(c, frag->node->raw);
-+
-+ jffs2_free_full_dnode(frag->node);
-+ }
-+ parent = frag_parent(frag);
-+ if (parent) {
-+ if (frag_left(parent) == frag)
-+ parent->rb.rb_left = NULL;
-+ else
-+ parent->rb.rb_right = NULL;
-+ }
-+
-+ jffs2_free_node_frag(frag);
-+ frag = parent;
-+
-+ cond_resched();
-+ }
-+}
-+
-+void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_node_frag *base)
-+{
-+ struct rb_node *parent = &base->rb;
-+ struct rb_node **link = &parent;
-+
-+ D2(printk(KERN_DEBUG "jffs2_fragtree_insert(%p; %d-%d, %p)\n", newfrag,
-+ newfrag->ofs, newfrag->ofs+newfrag->size, base));
-+
-+ while (*link) {
-+ parent = *link;
-+ base = rb_entry(parent, struct jffs2_node_frag, rb);
-+
-+ D2(printk(KERN_DEBUG "fragtree_insert considering frag at 0x%x\n", base->ofs));
-+ if (newfrag->ofs > base->ofs)
-+ link = &base->rb.rb_right;
-+ else if (newfrag->ofs < base->ofs)
-+ link = &base->rb.rb_left;
-+ else {
-+ printk(KERN_CRIT "Duplicate frag at %08x (%p,%p)\n", newfrag->ofs, newfrag, base);
-+ BUG();
-+ }
-+ }
-+
-+ rb_link_node(&newfrag->rb, &base->rb, link);
-+}
-diff -Nurb linux-mips-2.4.27/fs/jffs2/nodelist.h linux/fs/jffs2/nodelist.h
---- linux-mips-2.4.27/fs/jffs2/nodelist.h 2003-11-17 02:07:44.000000000 +0100
-+++ linux/fs/jffs2/nodelist.h 2004-11-19 10:25:12.113167264 +0100
-@@ -1,48 +1,35 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
-+#ifndef __JFFS2_NODELIST_H__
-+#define __JFFS2_NODELIST_H__
-+
- #include <linux/config.h>
- #include <linux/fs.h>
--
-+#include <linux/types.h>
-+#include <linux/jffs2.h>
- #include <linux/jffs2_fs_sb.h>
- #include <linux/jffs2_fs_i.h>
-
-+#ifdef __ECOS
-+#include "os-ecos.h"
-+#else
-+#include <linux/mtd/compatmac.h> /* For min/max in older kernels */
-+#include "os-linux.h"
-+#endif
-+
- #ifndef CONFIG_JFFS2_FS_DEBUG
--#define CONFIG_JFFS2_FS_DEBUG 2
-+#define CONFIG_JFFS2_FS_DEBUG 1
- #endif
-
- #if CONFIG_JFFS2_FS_DEBUG > 0
-@@ -71,17 +58,21 @@
- for this inode instead. The inode_cache will have NULL in the first
- word so you know when you've got there :) */
- struct jffs2_raw_node_ref *next_phys;
-- // __u32 ino;
-- __u32 flash_offset;
-- __u32 totlen;
--// __u16 nodetype;
-+ uint32_t flash_offset;
-+ uint32_t __totlen; /* This may die; use ref_totlen(c, jeb, ) below */
-+};
-
- /* flash_offset & 3 always has to be zero, because nodes are
- always aligned at 4 bytes. So we have a couple of extra bits
-- to play with. So we set the least significant bit to 1 to
-- signify that the node is obsoleted by later nodes.
-- */
--};
-+ to play with, which indicate the node's status; see below: */
-+#define REF_UNCHECKED 0 /* We haven't yet checked the CRC or built its inode */
-+#define REF_OBSOLETE 1 /* Obsolete, can be completely ignored */
-+#define REF_PRISTINE 2 /* Completely clean. GC without looking */
-+#define REF_NORMAL 3 /* Possibly overlapped. Read the page and write again on GC */
-+#define ref_flags(ref) ((ref)->flash_offset & 3)
-+#define ref_offset(ref) ((ref)->flash_offset & ~3)
-+#define ref_obsolete(ref) (((ref)->flash_offset & 3) == REF_OBSOLETE)
-+#define mark_ref_normal(ref) do { (ref)->flash_offset = ref_offset(ref) | REF_NORMAL; } while(0)
-
- /*
- Used for keeping track of deletion nodes &c, which can only be marked
-@@ -101,19 +92,35 @@
- a pointer to the first physical node which is part of this inode, too.
- */
- struct jffs2_inode_cache {
-- struct jffs2_scan_info *scan; /* Used during scan to hold
-- temporary lists of nodes, and later must be set to
-+ struct jffs2_full_dirent *scan_dents; /* Used during scan to hold
-+ temporary lists of dirents, and later must be set to
- NULL to mark the end of the raw_node_ref->next_in_ino
- chain. */
- struct jffs2_inode_cache *next;
- struct jffs2_raw_node_ref *nodes;
-- __u32 ino;
-+ uint32_t ino;
- int nlink;
-+ int state;
- };
-
-+/* Inode states for 'state' above. We need the 'GC' state to prevent
-+ someone from doing a read_inode() while we're moving a 'REF_PRISTINE'
-+ node without going through all the iget() nonsense */
-+#define INO_STATE_UNCHECKED 0 /* CRC checks not yet done */
-+#define INO_STATE_CHECKING 1 /* CRC checks in progress */
-+#define INO_STATE_PRESENT 2 /* In core */
-+#define INO_STATE_CHECKEDABSENT 3 /* Checked, cleared again */
-+#define INO_STATE_GC 4 /* GCing a 'pristine' node */
-+#define INO_STATE_READING 5 /* In read_inode() */
-+
-+#define INOCACHE_HASHSIZE 128
-+
- struct jffs2_scan_info {
- struct jffs2_full_dirent *dents;
- struct jffs2_tmp_dnode_info *tmpnodes;
-+ /* Latest i_size info */
-+ uint32_t version;
-+ uint32_t isize;
- };
- /*
- Larger representation of a raw node, kept in-core only when the
-@@ -123,9 +130,9 @@
- struct jffs2_full_dnode
- {
- struct jffs2_raw_node_ref *raw;
-- __u32 ofs; /* Don't really need this, but optimisation */
-- __u32 size;
-- __u32 frags; /* Number of fragments which currently refer
-+ uint32_t ofs; /* Don't really need this, but optimisation */
-+ uint32_t size;
-+ uint32_t frags; /* Number of fragments which currently refer
- to this node. When this reaches zero,
- the node is obsolete.
- */
-@@ -140,15 +147,15 @@
- {
- struct jffs2_tmp_dnode_info *next;
- struct jffs2_full_dnode *fn;
-- __u32 version;
-+ uint32_t version;
- };
-
- struct jffs2_full_dirent
- {
- struct jffs2_raw_node_ref *raw;
- struct jffs2_full_dirent *next;
-- __u32 version;
-- __u32 ino; /* == zero for unlink */
-+ uint32_t version;
-+ uint32_t ino; /* == zero for unlink */
- unsigned int nhash;
- unsigned char type;
- unsigned char name[0];
-@@ -159,21 +166,23 @@
- */
- struct jffs2_node_frag
- {
-- struct jffs2_node_frag *next;
-+ struct rb_node rb;
- struct jffs2_full_dnode *node; /* NULL for holes */
-- __u32 size;
-- __u32 ofs; /* Don't really need this, but optimisation */
-+ uint32_t size;
-+ uint32_t ofs; /* Don't really need this, but optimisation */
- };
-
- struct jffs2_eraseblock
- {
- struct list_head list;
- int bad_count;
-- __u32 offset; /* of this block in the MTD */
-+ uint32_t offset; /* of this block in the MTD */
-
-- __u32 used_size;
-- __u32 dirty_size;
-- __u32 free_size; /* Note that sector_size - free_size
-+ uint32_t unchecked_size;
-+ uint32_t used_size;
-+ uint32_t dirty_size;
-+ uint32_t wasted_size;
-+ uint32_t free_size; /* Note that sector_size - free_size
- is the address of the first free space */
- struct jffs2_raw_node_ref *first_node;
- struct jffs2_raw_node_ref *last_node;
-@@ -190,45 +199,134 @@
- };
-
- #define ACCT_SANITY_CHECK(c, jeb) do { \
-- if (jeb->used_size + jeb->dirty_size + jeb->free_size != c->sector_size) { \
-- printk(KERN_NOTICE "Eeep. Space accounting for block at 0x%08x is screwed\n", jeb->offset); \
-- printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x != total %08x\n", \
-- jeb->free_size, jeb->dirty_size, jeb->used_size, c->sector_size); \
-+ struct jffs2_eraseblock *___j = jeb; \
-+ if ((___j) && ___j->used_size + ___j->dirty_size + ___j->free_size + ___j->wasted_size + ___j->unchecked_size != c->sector_size) { \
-+ printk(KERN_NOTICE "Eeep. Space accounting for block at 0x%08x is screwed\n", ___j->offset); \
-+ printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x + wasted %08x + unchecked %08x != total %08x\n", \
-+ ___j->free_size, ___j->dirty_size, ___j->used_size, ___j->wasted_size, ___j->unchecked_size, c->sector_size); \
- BUG(); \
- } \
-- if (c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size != c->flash_size) { \
-+ if (c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size + c->wasted_size + c->unchecked_size != c->flash_size) { \
- printk(KERN_NOTICE "Eeep. Space accounting superblock info is screwed\n"); \
-- printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x + erasing %08x + bad %08x != total %08x\n", \
-- c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size, c->flash_size); \
-+ printk(KERN_NOTICE "free 0x%08x + dirty 0x%08x + used %08x + erasing %08x + bad %08x + wasted %08x + unchecked %08x != total %08x\n", \
-+ c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size, c->wasted_size, c->unchecked_size, c->flash_size); \
- BUG(); \
- } \
- } while(0)
-
-+static inline void paranoia_failed_dump(struct jffs2_eraseblock *jeb)
-+{
-+ struct jffs2_raw_node_ref *ref;
-+ int i=0;
-+
-+ printk(KERN_NOTICE);
-+ for (ref = jeb->first_node; ref; ref = ref->next_phys) {
-+ printk("%08x->", ref_offset(ref));
-+ if (++i == 8) {
-+ i = 0;
-+ printk("\n" KERN_NOTICE);
-+ }
-+ }
-+ printk("\n");
-+}
-+
-+
- #define ACCT_PARANOIA_CHECK(jeb) do { \
-- __u32 my_used_size = 0; \
-+ uint32_t my_used_size = 0; \
-+ uint32_t my_unchecked_size = 0; \
- struct jffs2_raw_node_ref *ref2 = jeb->first_node; \
- while (ref2) { \
-- if (!(ref2->flash_offset & 1)) \
-- my_used_size += ref2->totlen; \
-+ if (unlikely(ref2->flash_offset < jeb->offset || \
-+ ref2->flash_offset > jeb->offset + c->sector_size)) { \
-+ printk(KERN_NOTICE "Node %08x shouldn't be in block at %08x!\n", \
-+ ref_offset(ref2), jeb->offset); \
-+ paranoia_failed_dump(jeb); \
-+ BUG(); \
-+ } \
-+ if (ref_flags(ref2) == REF_UNCHECKED) \
-+ my_unchecked_size += ref_totlen(c, jeb, ref2); \
-+ else if (!ref_obsolete(ref2)) \
-+ my_used_size += ref_totlen(c, jeb, ref2); \
-+ if (unlikely((!ref2->next_phys) != (ref2 == jeb->last_node))) { \
-+ printk("ref for node at %p (phys %08x) has next_phys->%p (%08x), last_node->%p (phys %08x)\n", \
-+ ref2, ref_offset(ref2), ref2->next_phys, ref_offset(ref2->next_phys), \
-+ jeb->last_node, ref_offset(jeb->last_node)); \
-+ paranoia_failed_dump(jeb); \
-+ BUG(); \
-+ } \
- ref2 = ref2->next_phys; \
- } \
- if (my_used_size != jeb->used_size) { \
- printk(KERN_NOTICE "Calculated used size %08x != stored used size %08x\n", my_used_size, jeb->used_size); \
- BUG(); \
- } \
-+ if (my_unchecked_size != jeb->unchecked_size) { \
-+ printk(KERN_NOTICE "Calculated unchecked size %08x != stored unchecked size %08x\n", my_unchecked_size, jeb->unchecked_size); \
-+ BUG(); \
-+ } \
- } while(0)
-
-+/* Calculate totlen from surrounding nodes or eraseblock */
-+static inline uint32_t __ref_totlen(struct jffs2_sb_info *c,
-+ struct jffs2_eraseblock *jeb,
-+ struct jffs2_raw_node_ref *ref)
-+{
-+ uint32_t ref_end;
-+
-+ if (ref->next_phys)
-+ ref_end = ref_offset(ref->next_phys);
-+ else {
-+ if (!jeb)
-+ jeb = &c->blocks[ref->flash_offset / c->sector_size];
-+
-+ /* Last node in block. Use free_space */
-+ BUG_ON(ref != jeb->last_node);
-+ ref_end = jeb->offset + c->sector_size - jeb->free_size;
-+ }
-+ return ref_end - ref_offset(ref);
-+}
-+
-+static inline uint32_t ref_totlen(struct jffs2_sb_info *c,
-+ struct jffs2_eraseblock *jeb,
-+ struct jffs2_raw_node_ref *ref)
-+{
-+ uint32_t ret;
-+
-+ D1(if (jeb && jeb != &c->blocks[ref->flash_offset / c->sector_size]) {
-+ printk(KERN_CRIT "ref_totlen called with wrong block -- at 0x%08x instead of 0x%08x; ref 0x%08x\n",
-+ jeb->offset, c->blocks[ref->flash_offset / c->sector_size].offset, ref_offset(ref));
-+ BUG();
-+ })
-+
-+#if 1
-+ ret = ref->__totlen;
-+#else
-+ /* This doesn't actually work yet */
-+ ret = __ref_totlen(c, jeb, ref);
-+ if (ret != ref->__totlen) {
-+ printk(KERN_CRIT "Totlen for ref at %p (0x%08x-0x%08x) miscalculated as 0x%x instead of %x\n",
-+ ref, ref_offset(ref), ref_offset(ref)+ref->__totlen,
-+ ret, ref->__totlen);
-+ if (!jeb)
-+ jeb = &c->blocks[ref->flash_offset / c->sector_size];
-+ paranoia_failed_dump(jeb);
-+ BUG();
-+ }
-+#endif
-+ return ret;
-+}
-+
-+
- #define ALLOC_NORMAL 0 /* Normal allocation */
- #define ALLOC_DELETION 1 /* Deletion node. Best to allow it */
- #define ALLOC_GC 2 /* Space requested for GC. Give it or die */
-+#define ALLOC_NORETRY 3 /* For jffs2_write_dnode: On failure, return -EAGAIN instead of retrying */
-
--#define JFFS2_RESERVED_BLOCKS_BASE 3 /* Number of free blocks there must be before we... */
--#define JFFS2_RESERVED_BLOCKS_WRITE (JFFS2_RESERVED_BLOCKS_BASE + 2) /* ... allow a normal filesystem write */
--#define JFFS2_RESERVED_BLOCKS_DELETION (JFFS2_RESERVED_BLOCKS_BASE + 1) /* ... allow a normal filesystem deletion */
--#define JFFS2_RESERVED_BLOCKS_GCTRIGGER (JFFS2_RESERVED_BLOCKS_BASE + 3) /* ... wake up the GC thread */
--#define JFFS2_RESERVED_BLOCKS_GCBAD (JFFS2_RESERVED_BLOCKS_BASE + 1) /* ... pick a block from the bad_list to GC */
--#define JFFS2_RESERVED_BLOCKS_GCMERGE (JFFS2_RESERVED_BLOCKS_BASE) /* ... merge pages when garbage collecting */
-+/* How much dirty space before it goes on the very_dirty_list */
-+#define VERYDIRTY(c, size) ((size) >= ((c)->sector_size / 2))
-
-+/* check if dirty space is more than 255 Byte */
-+#define ISDIRTY(size) ((size) > sizeof (struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN)
-
- #define PAD(x) (((x)+3)&~3)
-
-@@ -241,43 +339,75 @@
- return ((struct jffs2_inode_cache *)raw);
- }
-
-+static inline struct jffs2_node_frag *frag_first(struct rb_root *root)
-+{
-+ struct rb_node *node = root->rb_node;
-+
-+ if (!node)
-+ return NULL;
-+ while(node->rb_left)
-+ node = node->rb_left;
-+ return rb_entry(node, struct jffs2_node_frag, rb);
-+}
-+#define rb_parent(rb) ((rb)->rb_parent)
-+#define frag_next(frag) rb_entry(rb_next(&(frag)->rb), struct jffs2_node_frag, rb)
-+#define frag_prev(frag) rb_entry(rb_prev(&(frag)->rb), struct jffs2_node_frag, rb)
-+#define frag_parent(frag) rb_entry(rb_parent(&(frag)->rb), struct jffs2_node_frag, rb)
-+#define frag_left(frag) rb_entry((frag)->rb.rb_left, struct jffs2_node_frag, rb)
-+#define frag_right(frag) rb_entry((frag)->rb.rb_right, struct jffs2_node_frag, rb)
-+#define frag_erase(frag, list) rb_erase(&frag->rb, list);
-+
- /* nodelist.c */
- D1(void jffs2_print_frag_list(struct jffs2_inode_info *f));
- void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list);
--void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct jffs2_tmp_dnode_info **list);
- int jffs2_get_inode_nodes(struct jffs2_sb_info *c, ino_t ino, struct jffs2_inode_info *f,
- struct jffs2_tmp_dnode_info **tnp, struct jffs2_full_dirent **fdp,
-- __u32 *highest_version, __u32 *latest_mctime,
-- __u32 *mctime_ver);
-+ uint32_t *highest_version, uint32_t *latest_mctime,
-+ uint32_t *mctime_ver);
-+void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state);
- struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino);
- void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new);
- void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old);
- void jffs2_free_ino_caches(struct jffs2_sb_info *c);
- void jffs2_free_raw_node_refs(struct jffs2_sb_info *c);
-+struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset);
-+void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c_delete);
-+void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_node_frag *base);
-+struct rb_node *rb_next(struct rb_node *);
-+struct rb_node *rb_prev(struct rb_node *);
-+void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root);
-
- /* nodemgmt.c */
--int jffs2_reserve_space(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len, int prio);
--int jffs2_reserve_space_gc(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len);
--int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new, __u32 len, int dirty);
-+int jffs2_thread_should_wake(struct jffs2_sb_info *c);
-+int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, int prio);
-+int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len);
-+int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new);
- void jffs2_complete_reservation(struct jffs2_sb_info *c);
- void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *raw);
-+void jffs2_dump_block_lists(struct jffs2_sb_info *c);
-
- /* write.c */
--struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri);
--struct jffs2_full_dnode *jffs2_write_dnode(struct inode *inode, struct jffs2_raw_inode *ri, const unsigned char *data, __u32 datalen, __u32 flash_ofs, __u32 *writelen);
--struct jffs2_full_dirent *jffs2_write_dirent(struct inode *inode, struct jffs2_raw_dirent *rd, const unsigned char *name, __u32 namelen, __u32 flash_ofs, __u32 *writelen);
-+int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri);
-+
-+struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode);
-+struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_dirent *rd, const unsigned char *name, uint32_t namelen, uint32_t flash_ofs, int alloc_mode);
-+int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
-+ struct jffs2_raw_inode *ri, unsigned char *buf,
-+ uint32_t offset, uint32_t writelen, uint32_t *retlen);
-+int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen);
-+int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, const char *name, int namelen, struct jffs2_inode_info *dead_f);
-+int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen);
-+
-
- /* readinode.c */
--void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct jffs2_node_frag **list, __u32 size);
--int jffs2_add_full_dnode_to_fraglist(struct jffs2_sb_info *c, struct jffs2_node_frag **list, struct jffs2_full_dnode *fn);
-+void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size);
- int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn);
--void jffs2_read_inode (struct inode *);
--void jffs2_clear_inode (struct inode *);
-+int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
-+ uint32_t ino, struct jffs2_raw_inode *latest_node);
-+int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
-+void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f);
-
- /* malloc.c */
--void jffs2_free_tmp_dnode_info_list(struct jffs2_tmp_dnode_info *tn);
--void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd);
--
- int jffs2_create_slab_caches(void);
- void jffs2_destroy_slab_caches(void);
-
-@@ -301,54 +431,41 @@
- /* gc.c */
- int jffs2_garbage_collect_pass(struct jffs2_sb_info *c);
-
--/* background.c */
--int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c);
--void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c);
--void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c);
--
--/* dir.c */
--extern struct file_operations jffs2_dir_operations;
--extern struct inode_operations jffs2_dir_inode_operations;
--
--/* file.c */
--extern struct file_operations jffs2_file_operations;
--extern struct inode_operations jffs2_file_inode_operations;
--extern struct address_space_operations jffs2_file_address_operations;
--int jffs2_null_fsync(struct file *, struct dentry *, int);
--int jffs2_setattr (struct dentry *dentry, struct iattr *iattr);
--int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg);
--int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg);
--int jffs2_readpage (struct file *, struct page *);
--int jffs2_prepare_write (struct file *, struct page *, unsigned, unsigned);
--int jffs2_commit_write (struct file *, struct page *, unsigned, unsigned);
--
--/* ioctl.c */
--int jffs2_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
--
- /* read.c */
- int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_full_dnode *fd, unsigned char *buf, int ofs, int len);
-+int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
-+ unsigned char *buf, uint32_t offset, uint32_t len);
-+char *jffs2_getlink(struct jffs2_sb_info *c, struct jffs2_inode_info *f);
-
- /* compr.c */
--unsigned char jffs2_compress(unsigned char *data_in, unsigned char *cpage_out,
-- __u32 *datalen, __u32 *cdatalen);
-+unsigned char jffs2_compress(unsigned char *data_in, unsigned char **cpage_out,
-+ uint32_t *datalen, uint32_t *cdatalen);
-+void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig);
- int jffs2_decompress(unsigned char comprtype, unsigned char *cdata_in,
-- unsigned char *data_out, __u32 cdatalen, __u32 datalen);
-+ unsigned char *data_out, uint32_t cdatalen, uint32_t datalen);
-
- /* scan.c */
- int jffs2_scan_medium(struct jffs2_sb_info *c);
-+void jffs2_rotate_lists(struct jffs2_sb_info *c);
-
- /* build.c */
--int jffs2_build_filesystem(struct jffs2_sb_info *c);
--
--/* symlink.c */
--extern struct inode_operations jffs2_symlink_inode_operations;
-+int jffs2_do_mount_fs(struct jffs2_sb_info *c);
-
- /* erase.c */
- void jffs2_erase_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
--void jffs2_erase_pending_blocks(struct jffs2_sb_info *c);
--void jffs2_mark_erased_blocks(struct jffs2_sb_info *c);
--void jffs2_erase_pending_trigger(struct jffs2_sb_info *c);
-+void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count);
-+
-+#ifdef CONFIG_JFFS2_FS_NAND
-+/* wbuf.c */
-+int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino);
-+int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c);
-+int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+int jffs2_nand_read_failcnt(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+#endif
-
- /* compr_zlib.c */
- int jffs2_zlib_init(void);
- void jffs2_zlib_exit(void);
-+
-+#endif /* __JFFS2_NODELIST_H__ */
-diff -Nurb linux-mips-2.4.27/fs/jffs2/nodemgmt.c linux/fs/jffs2/nodemgmt.c
---- linux-mips-2.4.27/fs/jffs2/nodemgmt.c 2002-06-27 00:36:20.000000000 +0200
-+++ linux/fs/jffs2/nodemgmt.c 2004-11-19 10:25:12.115166960 +0100
-@@ -1,45 +1,21 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/kernel.h>
- #include <linux/slab.h>
--#include <linux/jffs2.h>
- #include <linux/mtd/mtd.h>
--#include <linux/interrupt.h>
-+#include <linux/compiler.h>
-+#include <linux/sched.h> /* For cond_resched() */
- #include "nodelist.h"
-
- /**
-@@ -62,53 +38,95 @@
- * for the requested allocation.
- */
-
--static int jffs2_do_reserve_space(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len);
-+static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len);
-
--int jffs2_reserve_space(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len, int prio)
-+int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, int prio)
- {
- int ret = -EAGAIN;
-- int blocksneeded = JFFS2_RESERVED_BLOCKS_WRITE;
-+ int blocksneeded = c->resv_blocks_write;
- /* align it */
- minsize = PAD(minsize);
-
-- if (prio == ALLOC_DELETION)
-- blocksneeded = JFFS2_RESERVED_BLOCKS_DELETION;
--
- D1(printk(KERN_DEBUG "jffs2_reserve_space(): Requested 0x%x bytes\n", minsize));
- down(&c->alloc_sem);
-
- D1(printk(KERN_DEBUG "jffs2_reserve_space(): alloc sem got\n"));
-
-- spin_lock_bh(&c->erase_completion_lock);
-+ spin_lock(&c->erase_completion_lock);
-
-- /* this needs a little more thought */
-+ /* this needs a little more thought (true <tglx> :)) */
- while(ret == -EAGAIN) {
- while(c->nr_free_blocks + c->nr_erasing_blocks < blocksneeded) {
- int ret;
-+ uint32_t dirty, avail;
-+
-+ /* calculate real dirty size
-+ * dirty_size contains blocks on erase_pending_list
-+ * those blocks are counted in c->nr_erasing_blocks.
-+ * If one block is actually erased, it is not longer counted as dirty_space
-+ * but it is counted in c->nr_erasing_blocks, so we add it and subtract it
-+ * with c->nr_erasing_blocks * c->sector_size again.
-+ * Blocks on erasable_list are counted as dirty_size, but not in c->nr_erasing_blocks
-+ * This helps us to force gc and pick eventually a clean block to spread the load.
-+ * We add unchecked_size here, as we hopefully will find some space to use.
-+ * This will affect the sum only once, as gc first finishes checking
-+ * of nodes.
-+ */
-+ dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size + c->unchecked_size;
-+ if (dirty < c->nospc_dirty_size) {
-+ if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) {
-+ printk(KERN_NOTICE "jffs2_reserve_space(): Low on dirty space to GC, but it's a deletion. Allowing...\n");
-+ break;
-+ }
-+ D1(printk(KERN_DEBUG "dirty size 0x%08x + unchecked_size 0x%08x < nospc_dirty_size 0x%08x, returning -ENOSPC\n",
-+ dirty, c->unchecked_size, c->sector_size));
-+
-+ spin_unlock(&c->erase_completion_lock);
-+ up(&c->alloc_sem);
-+ return -ENOSPC;
-+ }
-
-+ /* Calc possibly available space. Possibly available means that we
-+ * don't know, if unchecked size contains obsoleted nodes, which could give us some
-+ * more usable space. This will affect the sum only once, as gc first finishes checking
-+ * of nodes.
-+ + Return -ENOSPC, if the maximum possibly available space is less or equal than
-+ * blocksneeded * sector_size.
-+ * This blocks endless gc looping on a filesystem, which is nearly full, even if
-+ * the check above passes.
-+ */
-+ avail = c->free_size + c->dirty_size + c->erasing_size + c->unchecked_size;
-+ if ( (avail / c->sector_size) <= blocksneeded) {
-+ if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) {
-+ printk(KERN_NOTICE "jffs2_reserve_space(): Low on possibly available space, but it's a deletion. Allowing...\n");
-+ break;
-+ }
-+
-+ D1(printk(KERN_DEBUG "max. available size 0x%08x < blocksneeded * sector_size 0x%08x, returning -ENOSPC\n",
-+ avail, blocksneeded * c->sector_size));
-+ spin_unlock(&c->erase_completion_lock);
- up(&c->alloc_sem);
-- if (c->dirty_size < c->sector_size) {
-- D1(printk(KERN_DEBUG "Short on space, but total dirty size 0x%08x < sector size 0x%08x, so -ENOSPC\n", c->dirty_size, c->sector_size));
-- spin_unlock_bh(&c->erase_completion_lock);
- return -ENOSPC;
- }
-- D1(printk(KERN_DEBUG "Triggering GC pass. nr_free_blocks %d, nr_erasing_blocks %d, free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x, erasing_size 0x%08x, bad_size 0x%08x (total 0x%08x of 0x%08x)\n",
-- c->nr_free_blocks, c->nr_erasing_blocks, c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size,
-- c->free_size + c->dirty_size + c->used_size + c->erasing_size + c->bad_size, c->flash_size));
-- spin_unlock_bh(&c->erase_completion_lock);
-+
-+ up(&c->alloc_sem);
-+
-+ D1(printk(KERN_DEBUG "Triggering GC pass. nr_free_blocks %d, nr_erasing_blocks %d, free_size 0x%08x, dirty_size 0x%08x, wasted_size 0x%08x, used_size 0x%08x, erasing_size 0x%08x, bad_size 0x%08x (total 0x%08x of 0x%08x)\n",
-+ c->nr_free_blocks, c->nr_erasing_blocks, c->free_size, c->dirty_size, c->wasted_size, c->used_size, c->erasing_size, c->bad_size,
-+ c->free_size + c->dirty_size + c->wasted_size + c->used_size + c->erasing_size + c->bad_size, c->flash_size));
-+ spin_unlock(&c->erase_completion_lock);
-
- ret = jffs2_garbage_collect_pass(c);
- if (ret)
- return ret;
-
-- if (current->need_resched)
-- schedule();
-+ cond_resched();
-
- if (signal_pending(current))
- return -EINTR;
-
- down(&c->alloc_sem);
-- spin_lock_bh(&c->erase_completion_lock);
-+ spin_lock(&c->erase_completion_lock);
- }
-
- ret = jffs2_do_reserve_space(c, minsize, ofs, len);
-@@ -116,45 +134,72 @@
- D1(printk(KERN_DEBUG "jffs2_reserve_space: ret is %d\n", ret));
- }
- }
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
- if (ret)
- up(&c->alloc_sem);
- return ret;
- }
-
--int jffs2_reserve_space_gc(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len)
-+int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len)
- {
- int ret = -EAGAIN;
- minsize = PAD(minsize);
-
- D1(printk(KERN_DEBUG "jffs2_reserve_space_gc(): Requested 0x%x bytes\n", minsize));
-
-- spin_lock_bh(&c->erase_completion_lock);
-+ spin_lock(&c->erase_completion_lock);
- while(ret == -EAGAIN) {
- ret = jffs2_do_reserve_space(c, minsize, ofs, len);
- if (ret) {
- D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret));
- }
- }
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
- return ret;
- }
-
- /* Called with alloc sem _and_ erase_completion_lock */
--static int jffs2_do_reserve_space(struct jffs2_sb_info *c, __u32 minsize, __u32 *ofs, __u32 *len)
-+static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len)
- {
- struct jffs2_eraseblock *jeb = c->nextblock;
-
- restart:
- if (jeb && minsize > jeb->free_size) {
- /* Skip the end of this block and file it as having some dirty space */
-- c->dirty_size += jeb->free_size;
-+ /* If there's a pending write to it, flush now */
-+ if (jffs2_wbuf_dirty(c)) {
-+ spin_unlock(&c->erase_completion_lock);
-+ D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Flushing write buffer\n"));
-+ jffs2_flush_wbuf_pad(c);
-+ spin_lock(&c->erase_completion_lock);
-+ jeb = c->nextblock;
-+ goto restart;
-+ }
-+ c->wasted_size += jeb->free_size;
- c->free_size -= jeb->free_size;
-- jeb->dirty_size += jeb->free_size;
-+ jeb->wasted_size += jeb->free_size;
- jeb->free_size = 0;
-+
-+ /* Check, if we have a dirty block now, or if it was dirty already */
-+ if (ISDIRTY (jeb->wasted_size + jeb->dirty_size)) {
-+ c->dirty_size += jeb->wasted_size;
-+ c->wasted_size -= jeb->wasted_size;
-+ jeb->dirty_size += jeb->wasted_size;
-+ jeb->wasted_size = 0;
-+ if (VERYDIRTY(c, jeb->dirty_size)) {
-+ D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to very_dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
-+ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
-+ list_add_tail(&jeb->list, &c->very_dirty_list);
-+ } else {
- D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
- jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
- list_add_tail(&jeb->list, &c->dirty_list);
-+ }
-+ } else {
-+ D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
-+ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
-+ list_add_tail(&jeb->list, &c->clean_list);
-+ }
- c->nextblock = jeb = NULL;
- }
-
-@@ -164,33 +209,44 @@
-
- if (list_empty(&c->free_list)) {
-
-- DECLARE_WAITQUEUE(wait, current);
-+ if (!c->nr_erasing_blocks &&
-+ !list_empty(&c->erasable_list)) {
-+ struct jffs2_eraseblock *ejeb;
-+
-+ ejeb = list_entry(c->erasable_list.next, struct jffs2_eraseblock, list);
-+ list_del(&ejeb->list);
-+ list_add_tail(&ejeb->list, &c->erase_pending_list);
-+ c->nr_erasing_blocks++;
-+ jffs2_erase_pending_trigger(c);
-+ D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Triggering erase of erasable block at 0x%08x\n",
-+ ejeb->offset));
-+ }
-+
-+ if (!c->nr_erasing_blocks &&
-+ !list_empty(&c->erasable_pending_wbuf_list)) {
-+ D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Flushing write buffer\n"));
-+ /* c->nextblock is NULL, no update to c->nextblock allowed */
-+ spin_unlock(&c->erase_completion_lock);
-+ jffs2_flush_wbuf_pad(c);
-+ spin_lock(&c->erase_completion_lock);
-+ /* Have another go. It'll be on the erasable_list now */
-+ return -EAGAIN;
-+ }
-
- if (!c->nr_erasing_blocks) {
--// if (list_empty(&c->erasing_list) && list_empty(&c->erase_pending_list) && list_empty(c->erase_complete_list)) {
- /* Ouch. We're in GC, or we wouldn't have got here.
- And there's no space left. At all. */
-- printk(KERN_CRIT "Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasingempty: %s, erasependingempty: %s)\n",
-- c->nr_erasing_blocks, c->nr_free_blocks, list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no");
-+ printk(KERN_CRIT "Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasableempty: %s, erasingempty: %s, erasependingempty: %s)\n",
-+ c->nr_erasing_blocks, c->nr_free_blocks, list_empty(&c->erasable_list)?"yes":"no",
-+ list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no");
- return -ENOSPC;
- }
-- /* Make sure this can't deadlock. Someone has to start the erases
-- of erase_pending blocks */
-- set_current_state(TASK_INTERRUPTIBLE);
-- add_wait_queue(&c->erase_wait, &wait);
-- D1(printk(KERN_DEBUG "Waiting for erases to complete. erasing_blocks is %d. (erasingempty: %s, erasependingempty: %s)\n",
-- c->nr_erasing_blocks, list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no"));
-- if (!list_empty(&c->erase_pending_list)) {
-- D1(printk(KERN_DEBUG "Triggering pending erases\n"));
-- jffs2_erase_pending_trigger(c);
-- }
-- spin_unlock_bh(&c->erase_completion_lock);
-- schedule();
-- remove_wait_queue(&c->erase_wait, &wait);
-- spin_lock_bh(&c->erase_completion_lock);
-- if (signal_pending(current)) {
-- return -EINTR;
-- }
-+
-+ spin_unlock(&c->erase_completion_lock);
-+ /* Don't wait for it; just erase one right now */
-+ jffs2_erase_pending_blocks(c, 1);
-+ spin_lock(&c->erase_completion_lock);
-+
- /* An erase may have failed, decreasing the
- amount of free space available. So we must
- restart from the beginning */
-@@ -201,7 +257,8 @@
- list_del(next);
- c->nextblock = jeb = list_entry(next, struct jffs2_eraseblock, list);
- c->nr_free_blocks--;
-- if (jeb->free_size != c->sector_size - sizeof(struct jffs2_unknown_node)) {
-+
-+ if (jeb->free_size != c->sector_size - c->cleanmarker_size) {
- printk(KERN_WARNING "Eep. Block 0x%08x taken from free_list had free_size of 0x%08x!!\n", jeb->offset, jeb->free_size);
- goto restart;
- }
-@@ -210,6 +267,20 @@
- enough space */
- *ofs = jeb->offset + (c->sector_size - jeb->free_size);
- *len = jeb->free_size;
-+
-+ if (c->cleanmarker_size && jeb->used_size == c->cleanmarker_size &&
-+ !jeb->first_node->next_in_ino) {
-+ /* Only node in it beforehand was a CLEANMARKER node (we think).
-+ So mark it obsolete now that there's going to be another node
-+ in the block. This will reduce used_size to zero but We've
-+ already set c->nextblock so that jffs2_mark_node_obsolete()
-+ won't try to refile it to the dirty_list.
-+ */
-+ spin_unlock(&c->erase_completion_lock);
-+ jffs2_mark_node_obsolete(c, jeb->first_node);
-+ spin_lock(&c->erase_completion_lock);
-+ }
-+
- D1(printk(KERN_DEBUG "jffs2_do_reserve_space(): Giving 0x%x bytes at 0x%x\n", *len, *ofs));
- return 0;
- }
-@@ -217,9 +288,9 @@
- /**
- * jffs2_add_physical_node_ref - add a physical node reference to the list
- * @c: superblock info
-- * @ofs: physical location of this physical node
-+ * @new: new node reference to add
- * @len: length of this physical node
-- * @ino: inode number with which this physical node is associated
-+ * @dirty: dirty flag for new node
- *
- * Should only be used to report nodes for which space has been allocated
- * by jffs2_reserve_space.
-@@ -227,47 +298,58 @@
- * Must be called with the alloc_sem held.
- */
-
--int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new, __u32 len, int dirty)
-+int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new)
- {
- struct jffs2_eraseblock *jeb;
-+ uint32_t len;
-+
-+ jeb = &c->blocks[new->flash_offset / c->sector_size];
-+ len = ref_totlen(c, jeb, new);
-
-- len = PAD(len);
-- jeb = &c->blocks[(new->flash_offset & ~3) / c->sector_size];
-- D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x, size 0x%x\n", new->flash_offset & ~3, len));
-+ D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n", ref_offset(new), ref_flags(new), len));
- #if 1
-- if (jeb != c->nextblock || (new->flash_offset & ~3) != jeb->offset + (c->sector_size - jeb->free_size)) {
-+ if (jeb != c->nextblock || (ref_offset(new)) != jeb->offset + (c->sector_size - jeb->free_size)) {
- printk(KERN_WARNING "argh. node added in wrong place\n");
- jffs2_free_raw_node_ref(new);
- return -EINVAL;
- }
- #endif
-+ spin_lock(&c->erase_completion_lock);
-+
- if (!jeb->first_node)
- jeb->first_node = new;
- if (jeb->last_node)
- jeb->last_node->next_phys = new;
- jeb->last_node = new;
-
-- spin_lock_bh(&c->erase_completion_lock);
- jeb->free_size -= len;
- c->free_size -= len;
-- if (dirty) {
-- new->flash_offset |= 1;
-+ if (ref_obsolete(new)) {
- jeb->dirty_size += len;
- c->dirty_size += len;
- } else {
- jeb->used_size += len;
- c->used_size += len;
- }
-- spin_unlock_bh(&c->erase_completion_lock);
-+
- if (!jeb->free_size && !jeb->dirty_size) {
- /* If it lives on the dirty_list, jffs2_reserve_space will put it there */
- D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
- jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
-+ if (jffs2_wbuf_dirty(c)) {
-+ /* Flush the last write in the block if it's outstanding */
-+ spin_unlock(&c->erase_completion_lock);
-+ jffs2_flush_wbuf_pad(c);
-+ spin_lock(&c->erase_completion_lock);
-+ }
-+
- list_add_tail(&jeb->list, &c->clean_list);
- c->nextblock = NULL;
- }
- ACCT_SANITY_CHECK(c,jeb);
-- ACCT_PARANOIA_CHECK(jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+
-+ spin_unlock(&c->erase_completion_lock);
-
- return 0;
- }
-@@ -280,20 +362,34 @@
- up(&c->alloc_sem);
- }
-
-+static inline int on_list(struct list_head *obj, struct list_head *head)
-+{
-+ struct list_head *this;
-+
-+ list_for_each(this, head) {
-+ if (this == obj) {
-+ D1(printk("%p is on list at %p\n", obj, head));
-+ return 1;
-+
-+ }
-+ }
-+ return 0;
-+}
-+
- void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref)
- {
- struct jffs2_eraseblock *jeb;
- int blocknr;
- struct jffs2_unknown_node n;
-- int ret;
-- ssize_t retlen;
-+ int ret, addedsize;
-+ size_t retlen;
-
- if(!ref) {
- printk(KERN_NOTICE "EEEEEK. jffs2_mark_node_obsolete called with NULL node\n");
- return;
- }
-- if (ref->flash_offset & 1) {
-- D1(printk(KERN_DEBUG "jffs2_mark_node_obsolete called with already obsolete node at 0x%08x\n", ref->flash_offset &~3));
-+ if (ref_obsolete(ref)) {
-+ D1(printk(KERN_DEBUG "jffs2_mark_node_obsolete called with already obsolete node at 0x%08x\n", ref_offset(ref)));
- return;
- }
- blocknr = ref->flash_offset / c->sector_size;
-@@ -302,22 +398,63 @@
- BUG();
- }
- jeb = &c->blocks[blocknr];
-- if (jeb->used_size < ref->totlen) {
-+
-+ spin_lock(&c->erase_completion_lock);
-+
-+ if (ref_flags(ref) == REF_UNCHECKED) {
-+ D1(if (unlikely(jeb->unchecked_size < ref_totlen(c, jeb, ref))) {
-+ printk(KERN_NOTICE "raw unchecked node of size 0x%08x freed from erase block %d at 0x%08x, but unchecked_size was already 0x%08x\n",
-+ ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size);
-+ BUG();
-+ })
-+ D1(printk(KERN_DEBUG "Obsoleting previously unchecked node at 0x%08x of len %x: ", ref_offset(ref), ref_totlen(c, jeb, ref)));
-+ jeb->unchecked_size -= ref_totlen(c, jeb, ref);
-+ c->unchecked_size -= ref_totlen(c, jeb, ref);
-+ } else {
-+ D1(if (unlikely(jeb->used_size < ref_totlen(c, jeb, ref))) {
- printk(KERN_NOTICE "raw node of size 0x%08x freed from erase block %d at 0x%08x, but used_size was already 0x%08x\n",
-- ref->totlen, blocknr, ref->flash_offset, jeb->used_size);
-+ ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size);
- BUG();
-+ })
-+ D1(printk(KERN_DEBUG "Obsoleting node at 0x%08x of len %x: ", ref_offset(ref), ref_totlen(c, jeb, ref)));
-+ jeb->used_size -= ref_totlen(c, jeb, ref);
-+ c->used_size -= ref_totlen(c, jeb, ref);
-+ }
-+
-+ // Take care, that wasted size is taken into concern
-+ if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + ref_totlen(c, jeb, ref))) && jeb != c->nextblock) {
-+ D1(printk("Dirtying\n"));
-+ addedsize = ref_totlen(c, jeb, ref);
-+ jeb->dirty_size += ref_totlen(c, jeb, ref);
-+ c->dirty_size += ref_totlen(c, jeb, ref);
-+
-+ /* Convert wasted space to dirty, if not a bad block */
-+ if (jeb->wasted_size) {
-+ if (on_list(&jeb->list, &c->bad_used_list)) {
-+ D1(printk(KERN_DEBUG "Leaving block at %08x on the bad_used_list\n",
-+ jeb->offset));
-+ addedsize = 0; /* To fool the refiling code later */
-+ } else {
-+ D1(printk(KERN_DEBUG "Converting %d bytes of wasted space to dirty in block at %08x\n",
-+ jeb->wasted_size, jeb->offset));
-+ addedsize += jeb->wasted_size;
-+ jeb->dirty_size += jeb->wasted_size;
-+ c->dirty_size += jeb->wasted_size;
-+ c->wasted_size -= jeb->wasted_size;
-+ jeb->wasted_size = 0;
- }
--
-- spin_lock_bh(&c->erase_completion_lock);
-- jeb->used_size -= ref->totlen;
-- jeb->dirty_size += ref->totlen;
-- c->used_size -= ref->totlen;
-- c->dirty_size += ref->totlen;
-- ref->flash_offset |= 1;
-+ }
-+ } else {
-+ D1(printk("Wasting\n"));
-+ addedsize = 0;
-+ jeb->wasted_size += ref_totlen(c, jeb, ref);
-+ c->wasted_size += ref_totlen(c, jeb, ref);
-+ }
-+ ref->flash_offset = ref_offset(ref) | REF_OBSOLETE;
-
- ACCT_SANITY_CHECK(c, jeb);
-
-- ACCT_PARANOIA_CHECK(jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-
- if (c->flags & JFFS2_SB_FLAG_MOUNTING) {
- /* Mount in progress. Don't muck about with the block
-@@ -325,68 +462,280 @@
- obliterate nodes that look obsolete. If they weren't
- marked obsolete on the flash at the time they _became_
- obsolete, there was probably a reason for that. */
-- spin_unlock_bh(&c->erase_completion_lock);
-+ spin_unlock(&c->erase_completion_lock);
- return;
- }
-+
- if (jeb == c->nextblock) {
- D2(printk(KERN_DEBUG "Not moving nextblock 0x%08x to dirty/erase_pending list\n", jeb->offset));
-- } else if (jeb == c->gcblock) {
-- D2(printk(KERN_DEBUG "Not moving gcblock 0x%08x to dirty/erase_pending list\n", jeb->offset));
--#if 0 /* We no longer do this here. It can screw the wear levelling. If you have a lot of static
-- data and a few blocks free, and you just create new files and keep deleting/overwriting
-- them, then you'd keep erasing and reusing those blocks without ever moving stuff around.
-- So we leave completely obsoleted blocks on the dirty_list and let the GC delete them
-- when it finds them there. That way, we still get the 'once in a while, take a clean block'
-- to spread out the flash usage */
-- } else if (!jeb->used_size) {
-+ } else if (!jeb->used_size && !jeb->unchecked_size) {
-+ if (jeb == c->gcblock) {
-+ D1(printk(KERN_DEBUG "gcblock at 0x%08x completely dirtied. Clearing gcblock...\n", jeb->offset));
-+ c->gcblock = NULL;
-+ } else {
- D1(printk(KERN_DEBUG "Eraseblock at 0x%08x completely dirtied. Removing from (dirty?) list...\n", jeb->offset));
- list_del(&jeb->list);
-+ }
-+ if (jffs2_wbuf_dirty(c)) {
-+ D1(printk(KERN_DEBUG "...and adding to erasable_pending_wbuf_list\n"));
-+ list_add_tail(&jeb->list, &c->erasable_pending_wbuf_list);
-+ } else {
-+ if (jiffies & 127) {
-+ /* Most of the time, we just erase it immediately. Otherwise we
-+ spend ages scanning it on mount, etc. */
- D1(printk(KERN_DEBUG "...and adding to erase_pending_list\n"));
- list_add_tail(&jeb->list, &c->erase_pending_list);
- c->nr_erasing_blocks++;
- jffs2_erase_pending_trigger(c);
-- // OFNI_BS_2SFFJ(c)->s_dirt = 1;
-+ } else {
-+ /* Sometimes, however, we leave it elsewhere so it doesn't get
-+ immediately reused, and we spread the load a bit. */
-+ D1(printk(KERN_DEBUG "...and adding to erasable_list\n"));
-+ list_add_tail(&jeb->list, &c->erasable_list);
-+ }
-+ }
- D1(printk(KERN_DEBUG "Done OK\n"));
--#endif
-- } else if (jeb->dirty_size == ref->totlen) {
-+ } else if (jeb == c->gcblock) {
-+ D2(printk(KERN_DEBUG "Not moving gcblock 0x%08x to dirty_list\n", jeb->offset));
-+ } else if (ISDIRTY(jeb->dirty_size) && !ISDIRTY(jeb->dirty_size - addedsize)) {
- D1(printk(KERN_DEBUG "Eraseblock at 0x%08x is freshly dirtied. Removing from clean list...\n", jeb->offset));
- list_del(&jeb->list);
- D1(printk(KERN_DEBUG "...and adding to dirty_list\n"));
- list_add_tail(&jeb->list, &c->dirty_list);
-+ } else if (VERYDIRTY(c, jeb->dirty_size) &&
-+ !VERYDIRTY(c, jeb->dirty_size - addedsize)) {
-+ D1(printk(KERN_DEBUG "Eraseblock at 0x%08x is now very dirty. Removing from dirty list...\n", jeb->offset));
-+ list_del(&jeb->list);
-+ D1(printk(KERN_DEBUG "...and adding to very_dirty_list\n"));
-+ list_add_tail(&jeb->list, &c->very_dirty_list);
-+ } else {
-+ D1(printk(KERN_DEBUG "Eraseblock at 0x%08x not moved anywhere. (free 0x%08x, dirty 0x%08x, used 0x%08x)\n",
-+ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
- }
-- spin_unlock_bh(&c->erase_completion_lock);
-
-- if (c->mtd->type != MTD_NORFLASH && c->mtd->type != MTD_RAM)
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ if (!jffs2_can_mark_obsolete(c))
- return;
-- if (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
-+ if (jffs2_is_readonly(c))
- return;
-
-- D1(printk(KERN_DEBUG "obliterating obsoleted node at 0x%08x\n", ref->flash_offset &~3));
-- ret = c->mtd->read(c->mtd, ref->flash_offset &~3, sizeof(n), &retlen, (char *)&n);
-+ D1(printk(KERN_DEBUG "obliterating obsoleted node at 0x%08x\n", ref_offset(ref)));
-+ ret = jffs2_flash_read(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n);
- if (ret) {
-- printk(KERN_WARNING "Read error reading from obsoleted node at 0x%08x: %d\n", ref->flash_offset &~3, ret);
-+ printk(KERN_WARNING "Read error reading from obsoleted node at 0x%08x: %d\n", ref_offset(ref), ret);
- return;
- }
- if (retlen != sizeof(n)) {
-- printk(KERN_WARNING "Short read from obsoleted node at 0x%08x: %d\n", ref->flash_offset &~3, retlen);
-+ printk(KERN_WARNING "Short read from obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen);
- return;
- }
-- if (PAD(n.totlen) != PAD(ref->totlen)) {
-- printk(KERN_WARNING "Node totlen on flash (0x%08x) != totlen in node ref (0x%08x)\n", n.totlen, ref->totlen);
-+ if (PAD(je32_to_cpu(n.totlen)) != PAD(ref_totlen(c, jeb, ref))) {
-+ printk(KERN_WARNING "Node totlen on flash (0x%08x) != totlen from node ref (0x%08x)\n", je32_to_cpu(n.totlen), ref_totlen(c, jeb, ref));
- return;
- }
-- if (!(n.nodetype & JFFS2_NODE_ACCURATE)) {
-- D1(printk(KERN_DEBUG "Node at 0x%08x was already marked obsolete (nodetype 0x%04x\n", ref->flash_offset &~3, n.nodetype));
-+ if (!(je16_to_cpu(n.nodetype) & JFFS2_NODE_ACCURATE)) {
-+ D1(printk(KERN_DEBUG "Node at 0x%08x was already marked obsolete (nodetype 0x%04x)\n", ref_offset(ref), je16_to_cpu(n.nodetype)));
- return;
- }
-- n.nodetype &= ~JFFS2_NODE_ACCURATE;
-- ret = c->mtd->write(c->mtd, ref->flash_offset&~3, sizeof(n), &retlen, (char *)&n);
-+ /* XXX FIXME: This is ugly now */
-+ n.nodetype = cpu_to_je16(je16_to_cpu(n.nodetype) & ~JFFS2_NODE_ACCURATE);
-+ ret = jffs2_flash_write(c, ref_offset(ref), sizeof(n), &retlen, (char *)&n);
- if (ret) {
-- printk(KERN_WARNING "Write error in obliterating obsoleted node at 0x%08x: %d\n", ref->flash_offset &~3, ret);
-+ printk(KERN_WARNING "Write error in obliterating obsoleted node at 0x%08x: %d\n", ref_offset(ref), ret);
- return;
- }
- if (retlen != sizeof(n)) {
-- printk(KERN_WARNING "Short write in obliterating obsoleted node at 0x%08x: %d\n", ref->flash_offset &~3, retlen);
-+ printk(KERN_WARNING "Short write in obliterating obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen);
- return;
- }
- }
-+
-+#if CONFIG_JFFS2_FS_DEBUG > 0
-+void jffs2_dump_block_lists(struct jffs2_sb_info *c)
-+{
-+
-+
-+ printk(KERN_DEBUG "jffs2_dump_block_lists:\n");
-+ printk(KERN_DEBUG "flash_size: %08x\n", c->flash_size);
-+ printk(KERN_DEBUG "used_size: %08x\n", c->used_size);
-+ printk(KERN_DEBUG "dirty_size: %08x\n", c->dirty_size);
-+ printk(KERN_DEBUG "wasted_size: %08x\n", c->wasted_size);
-+ printk(KERN_DEBUG "unchecked_size: %08x\n", c->unchecked_size);
-+ printk(KERN_DEBUG "free_size: %08x\n", c->free_size);
-+ printk(KERN_DEBUG "erasing_size: %08x\n", c->erasing_size);
-+ printk(KERN_DEBUG "bad_size: %08x\n", c->bad_size);
-+ printk(KERN_DEBUG "sector_size: %08x\n", c->sector_size);
-+ printk(KERN_DEBUG "jffs2_reserved_blocks size: %08x\n",c->sector_size * c->resv_blocks_write);
-+
-+ if (c->nextblock) {
-+ printk(KERN_DEBUG "nextblock: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ c->nextblock->offset, c->nextblock->used_size, c->nextblock->dirty_size, c->nextblock->wasted_size, c->nextblock->unchecked_size, c->nextblock->free_size);
-+ } else {
-+ printk(KERN_DEBUG "nextblock: NULL\n");
-+ }
-+ if (c->gcblock) {
-+ printk(KERN_DEBUG "gcblock: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size, c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size);
-+ } else {
-+ printk(KERN_DEBUG "gcblock: NULL\n");
-+ }
-+ if (list_empty(&c->clean_list)) {
-+ printk(KERN_DEBUG "clean_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+ int numblocks = 0;
-+ uint32_t dirty = 0;
-+
-+ list_for_each(this, &c->clean_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ numblocks ++;
-+ dirty += jeb->wasted_size;
-+ printk(KERN_DEBUG "clean_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n", jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ printk (KERN_DEBUG "Contains %d blocks with total wasted size %u, average wasted size: %u\n", numblocks, dirty, dirty / numblocks);
-+ }
-+ if (list_empty(&c->very_dirty_list)) {
-+ printk(KERN_DEBUG "very_dirty_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+ int numblocks = 0;
-+ uint32_t dirty = 0;
-+
-+ list_for_each(this, &c->very_dirty_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ numblocks ++;
-+ dirty += jeb->dirty_size;
-+ printk(KERN_DEBUG "very_dirty_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
-+ numblocks, dirty, dirty / numblocks);
-+ }
-+ if (list_empty(&c->dirty_list)) {
-+ printk(KERN_DEBUG "dirty_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+ int numblocks = 0;
-+ uint32_t dirty = 0;
-+
-+ list_for_each(this, &c->dirty_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ numblocks ++;
-+ dirty += jeb->dirty_size;
-+ printk(KERN_DEBUG "dirty_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ printk (KERN_DEBUG "Contains %d blocks with total dirty size %u, average dirty size: %u\n",
-+ numblocks, dirty, dirty / numblocks);
-+ }
-+ if (list_empty(&c->erasable_list)) {
-+ printk(KERN_DEBUG "erasable_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+
-+ list_for_each(this, &c->erasable_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ printk(KERN_DEBUG "erasable_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ }
-+ if (list_empty(&c->erasing_list)) {
-+ printk(KERN_DEBUG "erasing_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+
-+ list_for_each(this, &c->erasing_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ printk(KERN_DEBUG "erasing_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ }
-+ if (list_empty(&c->erase_pending_list)) {
-+ printk(KERN_DEBUG "erase_pending_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+
-+ list_for_each(this, &c->erase_pending_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ printk(KERN_DEBUG "erase_pending_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ }
-+ if (list_empty(&c->erasable_pending_wbuf_list)) {
-+ printk(KERN_DEBUG "erasable_pending_wbuf_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+
-+ list_for_each(this, &c->erasable_pending_wbuf_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ printk(KERN_DEBUG "erasable_pending_wbuf_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ }
-+ if (list_empty(&c->free_list)) {
-+ printk(KERN_DEBUG "free_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+
-+ list_for_each(this, &c->free_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ printk(KERN_DEBUG "free_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ }
-+ if (list_empty(&c->bad_list)) {
-+ printk(KERN_DEBUG "bad_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+
-+ list_for_each(this, &c->bad_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ printk(KERN_DEBUG "bad_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ }
-+ if (list_empty(&c->bad_used_list)) {
-+ printk(KERN_DEBUG "bad_used_list: empty\n");
-+ } else {
-+ struct list_head *this;
-+
-+ list_for_each(this, &c->bad_used_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+ printk(KERN_DEBUG "bad_used_list: %08x (used %08x, dirty %08x, wasted %08x, unchecked %08x, free %08x)\n",
-+ jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, jeb->unchecked_size, jeb->free_size);
-+ }
-+ }
-+}
-+#endif /* CONFIG_JFFS2_FS_DEBUG */
-+
-+int jffs2_thread_should_wake(struct jffs2_sb_info *c)
-+{
-+ int ret = 0;
-+ uint32_t dirty;
-+
-+ if (c->unchecked_size) {
-+ D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): unchecked_size %d, checked_ino #%d\n",
-+ c->unchecked_size, c->checked_ino));
-+ return 1;
-+ }
-+
-+ /* dirty_size contains blocks on erase_pending_list
-+ * those blocks are counted in c->nr_erasing_blocks.
-+ * If one block is actually erased, it is not longer counted as dirty_space
-+ * but it is counted in c->nr_erasing_blocks, so we add it and subtract it
-+ * with c->nr_erasing_blocks * c->sector_size again.
-+ * Blocks on erasable_list are counted as dirty_size, but not in c->nr_erasing_blocks
-+ * This helps us to force gc and pick eventually a clean block to spread the load.
-+ */
-+ dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size;
-+
-+ if (c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_gctrigger &&
-+ (dirty > c->nospc_dirty_size))
-+ ret = 1;
-+
-+ D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x: %s\n",
-+ c->nr_free_blocks, c->nr_erasing_blocks, c->dirty_size, ret?"yes":"no"));
-+
-+ return ret;
-+}
-diff -Nurb linux-mips-2.4.27/fs/jffs2/os-linux.h linux/fs/jffs2/os-linux.h
---- linux-mips-2.4.27/fs/jffs2/os-linux.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/jffs2/os-linux.h 2004-11-19 10:25:12.116166808 +0100
-@@ -0,0 +1,212 @@
-+/*
-+ * JFFS2 -- Journalling Flash File System, Version 2.
-+ *
-+ * Copyright (C) 2002-2003 Red Hat, Inc.
-+ *
-+ * Created by David Woodhouse <dwmw2@redhat.com>
-+ *
-+ * For licensing information, see the file 'LICENCE' in this directory.
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+#ifndef __JFFS2_OS_LINUX_H__
-+#define __JFFS2_OS_LINUX_H__
-+#include <linux/version.h>
-+
-+/* JFFS2 uses Linux mode bits natively -- no need for conversion */
-+#define os_to_jffs2_mode(x) (x)
-+#define jffs2_to_os_mode(x) (x)
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,73)
-+#define kstatfs statfs
-+#endif
-+
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
-+#define JFFS2_INODE_INFO(i) (list_entry(i, struct jffs2_inode_info, vfs_inode))
-+#define OFNI_EDONI_2SFFJ(f) (&(f)->vfs_inode)
-+#define JFFS2_SB_INFO(sb) (sb->s_fs_info)
-+#define OFNI_BS_2SFFJ(c) ((struct super_block *)c->os_priv)
-+#elif defined(JFFS2_OUT_OF_KERNEL)
-+#define JFFS2_INODE_INFO(i) ((struct jffs2_inode_info *) &(i)->u)
-+#define OFNI_EDONI_2SFFJ(f) ((struct inode *) ( ((char *)f) - ((char *)(&((struct inode *)NULL)->u)) ) )
-+#define JFFS2_SB_INFO(sb) ((struct jffs2_sb_info *) &(sb)->u)
-+#define OFNI_BS_2SFFJ(c) ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->u)) ) )
-+#else
-+#define JFFS2_INODE_INFO(i) (&i->u.jffs2_i)
-+#define OFNI_EDONI_2SFFJ(f) ((struct inode *) ( ((char *)f) - ((char *)(&((struct inode *)NULL)->u)) ) )
-+#define JFFS2_SB_INFO(sb) (&sb->u.jffs2_sb)
-+#define OFNI_BS_2SFFJ(c) ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->u)) ) )
-+#endif
-+
-+
-+#define JFFS2_F_I_SIZE(f) (OFNI_EDONI_2SFFJ(f)->i_size)
-+#define JFFS2_F_I_MODE(f) (OFNI_EDONI_2SFFJ(f)->i_mode)
-+#define JFFS2_F_I_UID(f) (OFNI_EDONI_2SFFJ(f)->i_uid)
-+#define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid)
-+
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,1)
-+#define JFFS2_F_I_RDEV_MIN(f) (iminor(OFNI_EDONI_2SFFJ(f)))
-+#define JFFS2_F_I_RDEV_MAJ(f) (imajor(OFNI_EDONI_2SFFJ(f)))
-+#else
-+#define JFFS2_F_I_RDEV_MIN(f) (MINOR(to_kdev_t(OFNI_EDONI_2SFFJ(f)->i_rdev)))
-+#define JFFS2_F_I_RDEV_MAJ(f) (MAJOR(to_kdev_t(OFNI_EDONI_2SFFJ(f)->i_rdev)))
-+#endif
-+
-+/* Urgh. The things we do to keep the 2.4 build working */
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,47)
-+#define ITIME(sec) ((struct timespec){sec, 0})
-+#define I_SEC(tv) ((tv).tv_sec)
-+#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime.tv_sec)
-+#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime.tv_sec)
-+#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime.tv_sec)
-+#else
-+#define ITIME(x) (x)
-+#define I_SEC(x) (x)
-+#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime)
-+#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime)
-+#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime)
-+#endif
-+
-+#define sleep_on_spinunlock(wq, s) \
-+ do { \
-+ DECLARE_WAITQUEUE(__wait, current); \
-+ add_wait_queue((wq), &__wait); \
-+ set_current_state(TASK_UNINTERRUPTIBLE); \
-+ spin_unlock(s); \
-+ schedule(); \
-+ remove_wait_queue((wq), &__wait); \
-+ } while(0)
-+
-+static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
-+{
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
-+ f->highest_version = 0;
-+ f->fragtree = RB_ROOT;
-+ f->metadata = NULL;
-+ f->dents = NULL;
-+ f->flags = 0;
-+ f->usercompr = 0;
-+#else
-+ memset(f, 0, sizeof(*f));
-+ init_MUTEX_LOCKED(&f->sem);
-+#endif
-+}
-+
-+#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
-+
-+#ifndef CONFIG_JFFS2_FS_NAND
-+#define jffs2_can_mark_obsolete(c) (1)
-+#define jffs2_cleanmarker_oob(c) (0)
-+#define jffs2_write_nand_cleanmarker(c,jeb) (-EIO)
-+
-+#define jffs2_flash_write(c, ofs, len, retlen, buf) ((c)->mtd->write((c)->mtd, ofs, len, retlen, buf))
-+#define jffs2_flash_read(c, ofs, len, retlen, buf) ((c)->mtd->read((c)->mtd, ofs, len, retlen, buf))
-+#define jffs2_flush_wbuf_pad(c) ({ (void)(c), 0; })
-+#define jffs2_flush_wbuf_gc(c, i) ({ (void)(c), (void) i, 0; })
-+#define jffs2_nand_read_failcnt(c,jeb) do { ; } while(0)
-+#define jffs2_write_nand_badblock(c,jeb) do { ; } while(0)
-+#define jffs2_nand_flash_setup(c) (0)
-+#define jffs2_nand_flash_cleanup(c) do {} while(0)
-+#define jffs2_wbuf_dirty(c) (0)
-+#define jffs2_flash_writev(a,b,c,d,e,f) jffs2_flash_direct_writev(a,b,c,d,e)
-+#define jffs2_wbuf_timeout NULL
-+#define jffs2_wbuf_process NULL
-+
-+#else /* NAND support present */
-+
-+#define jffs2_can_mark_obsolete(c) (c->mtd->type == MTD_NORFLASH || c->mtd->type == MTD_RAM)
-+#define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH)
-+
-+#define jffs2_flash_write_oob(c, ofs, len, retlen, buf) ((c)->mtd->write_oob((c)->mtd, ofs, len, retlen, buf))
-+#define jffs2_flash_read_oob(c, ofs, len, retlen, buf) ((c)->mtd->read_oob((c)->mtd, ofs, len, retlen, buf))
-+#define jffs2_wbuf_dirty(c) (!!(c)->wbuf_len)
-+struct kstatfs;
-+
-+/* wbuf.c */
-+int jffs2_flash_writev(struct jffs2_sb_info *c, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino);
-+int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, const u_char *buf);
-+int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, u_char *buf);
-+int jffs2_check_oob_empty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,int mode);
-+int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+void jffs2_wbuf_timeout(unsigned long data);
-+void jffs2_wbuf_process(void *data);
-+int jffs2_nand_flash_setup(struct jffs2_sb_info *c);
-+void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c);
-+#endif /* NAND */
-+
-+/* erase.c */
-+static inline void jffs2_erase_pending_trigger(struct jffs2_sb_info *c)
-+{
-+ OFNI_BS_2SFFJ(c)->s_dirt = 1;
-+}
-+
-+/* background.c */
-+int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c);
-+void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c);
-+void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c);
-+
-+/* dir.c */
-+extern struct file_operations jffs2_dir_operations;
-+extern struct inode_operations jffs2_dir_inode_operations;
-+
-+/* file.c */
-+extern struct file_operations jffs2_file_operations;
-+extern struct inode_operations jffs2_file_inode_operations;
-+extern struct address_space_operations jffs2_file_address_operations;
-+int jffs2_fsync(struct file *, struct dentry *, int);
-+int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg);
-+int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg);
-+int jffs2_readpage (struct file *, struct page *);
-+int jffs2_prepare_write (struct file *, struct page *, unsigned, unsigned);
-+int jffs2_commit_write (struct file *, struct page *, unsigned, unsigned);
-+
-+/* ioctl.c */
-+int jffs2_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
-+
-+/* symlink.c */
-+extern struct inode_operations jffs2_symlink_inode_operations;
-+
-+/* fs.c */
-+int jffs2_setattr (struct dentry *, struct iattr *);
-+void jffs2_read_inode (struct inode *);
-+void jffs2_clear_inode (struct inode *);
-+void jffs2_dirty_inode(struct inode *inode);
-+struct inode *jffs2_new_inode (struct inode *dir_i, int mode,
-+ struct jffs2_raw_inode *ri);
-+int jffs2_statfs (struct super_block *, struct kstatfs *);
-+void jffs2_write_super (struct super_block *);
-+int jffs2_remount_fs (struct super_block *, int *, char *);
-+int jffs2_do_fill_super(struct super_block *sb, void *data, int silent);
-+void jffs2_gc_release_inode(struct jffs2_sb_info *c,
-+ struct jffs2_inode_info *f);
-+struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
-+ int inum, int nlink);
-+
-+unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
-+ struct jffs2_inode_info *f,
-+ unsigned long offset,
-+ unsigned long *priv);
-+void jffs2_gc_release_page(struct jffs2_sb_info *c,
-+ unsigned char *pg,
-+ unsigned long *priv);
-+
-+
-+/* writev.c */
-+int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct iovec *vecs,
-+ unsigned long count, loff_t to, size_t *retlen);
-+
-+/* Compression config */
-+#define JFFS2_COMPRESSION
-+#undef JFFS2_USE_DYNRUBIN /* Disabled 23/9/1. With zlib it hardly ever gets a look in */
-+#undef JFFS2_USE_RUBINMIPS /* Disabled 26/2/1. Obsoleted by dynrubin */
-+#define JFFS2_USE_ZLIB
-+#define JFFS2_USE_RTIME /* rtime does manage to recompress already-compressed data */
-+
-+
-+#endif /* __JFFS2_OS_LINUX_H__ */
-+
-+
-diff -Nurb linux-mips-2.4.27/fs/jffs2/pushpull.h linux/fs/jffs2/pushpull.h
---- linux-mips-2.4.27/fs/jffs2/pushpull.h 2001-11-05 21:16:19.000000000 +0100
-+++ linux/fs/jffs2/pushpull.h 2004-11-19 10:25:12.118166504 +0100
-@@ -1,42 +1,21 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001, 2002 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #ifndef __PUSHPULL_H__
- #define __PUSHPULL_H__
-+
-+#include <linux/errno.h>
-+
- struct pushpull {
- unsigned char *buf;
- unsigned int buflen;
-@@ -44,9 +23,36 @@
- unsigned int reserve;
- };
-
--void init_pushpull(struct pushpull *, char *, unsigned, unsigned, unsigned);
--int pushbit(struct pushpull *pp, int bit, int use_reserved);
--int pushedbits(struct pushpull *pp);
-+
-+static inline void init_pushpull(struct pushpull *pp, char *buf, unsigned buflen, unsigned ofs, unsigned reserve)
-+{
-+ pp->buf = buf;
-+ pp->buflen = buflen;
-+ pp->ofs = ofs;
-+ pp->reserve = reserve;
-+}
-+
-+static inline int pushbit(struct pushpull *pp, int bit, int use_reserved)
-+{
-+ if (pp->ofs >= pp->buflen - (use_reserved?0:pp->reserve)) {
-+ return -ENOSPC;
-+ }
-+
-+ if (bit) {
-+ pp->buf[pp->ofs >> 3] |= (1<<(7-(pp->ofs &7)));
-+ }
-+ else {
-+ pp->buf[pp->ofs >> 3] &= ~(1<<(7-(pp->ofs &7)));
-+ }
-+ pp->ofs++;
-+
-+ return 0;
-+}
-+
-+static inline int pushedbits(struct pushpull *pp)
-+{
-+ return pp->ofs;
-+}
-
- static inline int pullbit(struct pushpull *pp)
- {
-diff -Nurb linux-mips-2.4.27/fs/jffs2/rbtree.c linux/fs/jffs2/rbtree.c
---- linux-mips-2.4.27/fs/jffs2/rbtree.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/jffs2/rbtree.c 2004-11-19 10:25:12.120166200 +0100
-@@ -0,0 +1,363 @@
-+/*
-+ Red Black Trees
-+ (C) 1999 Andrea Arcangeli <andrea@suse.de>
-+ (C) 2002 David Woodhouse <dwmw2@infradead.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2 of the License, or
-+ (at your option) any later version.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the Free Software
-+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+
-+ $Id$
-+*/
-+
-+#ifdef __ECOS /* This file is _not_ under the eCos licence; it is pure GPL. */
-+#error "Licence problem. eCos has its own rbtree code."
-+#endif
-+
-+#include <linux/version.h>
-+#include <linux/rbtree.h>
-+
-+/* This wasn't present till 2.4.11, wasn't exported till 2.4.19 */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,11) || \
-+ (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) && defined(MODULE))
-+static void __rb_rotate_left(struct rb_node * node, struct rb_root * root)
-+{
-+ struct rb_node * right = node->rb_right;
-+
-+ if ((node->rb_right = right->rb_left))
-+ right->rb_left->rb_parent = node;
-+ right->rb_left = node;
-+
-+ if ((right->rb_parent = node->rb_parent))
-+ {
-+ if (node == node->rb_parent->rb_left)
-+ node->rb_parent->rb_left = right;
-+ else
-+ node->rb_parent->rb_right = right;
-+ }
-+ else
-+ root->rb_node = right;
-+ node->rb_parent = right;
-+}
-+
-+static void __rb_rotate_right(struct rb_node * node, struct rb_root * root)
-+{
-+ struct rb_node * left = node->rb_left;
-+
-+ if ((node->rb_left = left->rb_right))
-+ left->rb_right->rb_parent = node;
-+ left->rb_right = node;
-+
-+ if ((left->rb_parent = node->rb_parent))
-+ {
-+ if (node == node->rb_parent->rb_right)
-+ node->rb_parent->rb_right = left;
-+ else
-+ node->rb_parent->rb_left = left;
-+ }
-+ else
-+ root->rb_node = left;
-+ node->rb_parent = left;
-+}
-+
-+void rb_insert_color(struct rb_node * node, struct rb_root * root)
-+{
-+ struct rb_node * parent, * gparent;
-+
-+ while ((parent = node->rb_parent) && parent->rb_color == RB_RED)
-+ {
-+ gparent = parent->rb_parent;
-+
-+ if (parent == gparent->rb_left)
-+ {
-+ {
-+ register struct rb_node * uncle = gparent->rb_right;
-+ if (uncle && uncle->rb_color == RB_RED)
-+ {
-+ uncle->rb_color = RB_BLACK;
-+ parent->rb_color = RB_BLACK;
-+ gparent->rb_color = RB_RED;
-+ node = gparent;
-+ continue;
-+ }
-+ }
-+
-+ if (parent->rb_right == node)
-+ {
-+ register struct rb_node * tmp;
-+ __rb_rotate_left(parent, root);
-+ tmp = parent;
-+ parent = node;
-+ node = tmp;
-+ }
-+
-+ parent->rb_color = RB_BLACK;
-+ gparent->rb_color = RB_RED;
-+ __rb_rotate_right(gparent, root);
-+ } else {
-+ {
-+ register struct rb_node * uncle = gparent->rb_left;
-+ if (uncle && uncle->rb_color == RB_RED)
-+ {
-+ uncle->rb_color = RB_BLACK;
-+ parent->rb_color = RB_BLACK;
-+ gparent->rb_color = RB_RED;
-+ node = gparent;
-+ continue;
-+ }
-+ }
-+
-+ if (parent->rb_left == node)
-+ {
-+ register struct rb_node * tmp;
-+ __rb_rotate_right(parent, root);
-+ tmp = parent;
-+ parent = node;
-+ node = tmp;
-+ }
-+
-+ parent->rb_color = RB_BLACK;
-+ gparent->rb_color = RB_RED;
-+ __rb_rotate_left(gparent, root);
-+ }
-+ }
-+
-+ root->rb_node->rb_color = RB_BLACK;
-+}
-+
-+static void __rb_erase_color(struct rb_node * node, struct rb_node * parent,
-+ struct rb_root * root)
-+{
-+ struct rb_node * other;
-+
-+ while ((!node || node->rb_color == RB_BLACK) && node != root->rb_node)
-+ {
-+ if (parent->rb_left == node)
-+ {
-+ other = parent->rb_right;
-+ if (other->rb_color == RB_RED)
-+ {
-+ other->rb_color = RB_BLACK;
-+ parent->rb_color = RB_RED;
-+ __rb_rotate_left(parent, root);
-+ other = parent->rb_right;
-+ }
-+ if ((!other->rb_left ||
-+ other->rb_left->rb_color == RB_BLACK)
-+ && (!other->rb_right ||
-+ other->rb_right->rb_color == RB_BLACK))
-+ {
-+ other->rb_color = RB_RED;
-+ node = parent;
-+ parent = node->rb_parent;
-+ }
-+ else
-+ {
-+ if (!other->rb_right ||
-+ other->rb_right->rb_color == RB_BLACK)
-+ {
-+ register struct rb_node * o_left;
-+ if ((o_left = other->rb_left))
-+ o_left->rb_color = RB_BLACK;
-+ other->rb_color = RB_RED;
-+ __rb_rotate_right(other, root);
-+ other = parent->rb_right;
-+ }
-+ other->rb_color = parent->rb_color;
-+ parent->rb_color = RB_BLACK;
-+ if (other->rb_right)
-+ other->rb_right->rb_color = RB_BLACK;
-+ __rb_rotate_left(parent, root);
-+ node = root->rb_node;
-+ break;
-+ }
-+ }
-+ else
-+ {
-+ other = parent->rb_left;
-+ if (other->rb_color == RB_RED)
-+ {
-+ other->rb_color = RB_BLACK;
-+ parent->rb_color = RB_RED;
-+ __rb_rotate_right(parent, root);
-+ other = parent->rb_left;
-+ }
-+ if ((!other->rb_left ||
-+ other->rb_left->rb_color == RB_BLACK)
-+ && (!other->rb_right ||
-+ other->rb_right->rb_color == RB_BLACK))
-+ {
-+ other->rb_color = RB_RED;
-+ node = parent;
-+ parent = node->rb_parent;
-+ }
-+ else
-+ {
-+ if (!other->rb_left ||
-+ other->rb_left->rb_color == RB_BLACK)
-+ {
-+ register struct rb_node * o_right;
-+ if ((o_right = other->rb_right))
-+ o_right->rb_color = RB_BLACK;
-+ other->rb_color = RB_RED;
-+ __rb_rotate_left(other, root);
-+ other = parent->rb_left;
-+ }
-+ other->rb_color = parent->rb_color;
-+ parent->rb_color = RB_BLACK;
-+ if (other->rb_left)
-+ other->rb_left->rb_color = RB_BLACK;
-+ __rb_rotate_right(parent, root);
-+ node = root->rb_node;
-+ break;
-+ }
-+ }
-+ }
-+ if (node)
-+ node->rb_color = RB_BLACK;
-+}
-+
-+void rb_erase(struct rb_node * node, struct rb_root * root)
-+{
-+ struct rb_node * child, * parent;
-+ int color;
-+
-+ if (!node->rb_left)
-+ child = node->rb_right;
-+ else if (!node->rb_right)
-+ child = node->rb_left;
-+ else
-+ {
-+ struct rb_node * old = node, * left;
-+
-+ node = node->rb_right;
-+ while ((left = node->rb_left))
-+ node = left;
-+ child = node->rb_right;
-+ parent = node->rb_parent;
-+ color = node->rb_color;
-+
-+ if (child)
-+ child->rb_parent = parent;
-+ if (parent)
-+ {
-+ if (parent->rb_left == node)
-+ parent->rb_left = child;
-+ else
-+ parent->rb_right = child;
-+ }
-+ else
-+ root->rb_node = child;
-+
-+ if (node->rb_parent == old)
-+ parent = node;
-+ node->rb_parent = old->rb_parent;
-+ node->rb_color = old->rb_color;
-+ node->rb_right = old->rb_right;
-+ node->rb_left = old->rb_left;
-+
-+ if (old->rb_parent)
-+ {
-+ if (old->rb_parent->rb_left == old)
-+ old->rb_parent->rb_left = node;
-+ else
-+ old->rb_parent->rb_right = node;
-+ } else
-+ root->rb_node = node;
-+
-+ old->rb_left->rb_parent = node;
-+ if (old->rb_right)
-+ old->rb_right->rb_parent = node;
-+ goto color;
-+ }
-+
-+ parent = node->rb_parent;
-+ color = node->rb_color;
-+
-+ if (child)
-+ child->rb_parent = parent;
-+ if (parent)
-+ {
-+ if (parent->rb_left == node)
-+ parent->rb_left = child;
-+ else
-+ parent->rb_right = child;
-+ }
-+ else
-+ root->rb_node = child;
-+
-+ color:
-+ if (color == RB_BLACK)
-+ __rb_erase_color(child, parent, root);
-+}
-+#endif /* Before 2.4.11 */
-+
-+ /* These routines haven't made it into 2.4 (yet) */
-+struct rb_node *rb_next(struct rb_node *node)
-+{
-+ /* If we have a right-hand child, go down and then left as far
-+ as we can. */
-+ if (node->rb_right) {
-+ node = node->rb_right;
-+ while (node->rb_left)
-+ node=node->rb_left;
-+ return node;
-+ }
-+
-+ /* No right-hand children. Everything down and left is
-+ smaller than us, so any 'next' node must be in the general
-+ direction of our parent. Go up the tree; any time the
-+ ancestor is a right-hand child of its parent, keep going
-+ up. First time it's a left-hand child of its parent, said
-+ parent is our 'next' node. */
-+ while (node->rb_parent && node == node->rb_parent->rb_right)
-+ node = node->rb_parent;
-+
-+ return node->rb_parent;
-+}
-+
-+struct rb_node *rb_prev(struct rb_node *node)
-+{
-+ if (node->rb_left) {
-+ node = node->rb_left;
-+ while (node->rb_right)
-+ node=node->rb_right;
-+ return node;
-+ }
-+ while (node->rb_parent && node == node->rb_parent->rb_left)
-+ node = node->rb_parent;
-+
-+ return node->rb_parent;
-+}
-+
-+void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root)
-+{
-+ struct rb_node *parent = victim->rb_parent;
-+
-+ /* Set the surrounding nodes to point to the replacement */
-+ if (parent) {
-+ if (victim == parent->rb_left)
-+ parent->rb_left = new;
-+ else
-+ parent->rb_right = new;
-+ } else {
-+ root->rb_node = new;
-+ }
-+ if (victim->rb_left)
-+ victim->rb_left->rb_parent = new;
-+ if (victim->rb_right)
-+ victim->rb_right->rb_parent = new;
-+
-+ /* Copy the pointers/colour from the victim to the replacement */
-+ *new = *victim;
-+}
-diff -Nurb linux-mips-2.4.27/fs/jffs2/read.c linux/fs/jffs2/read.c
---- linux-mips-2.4.27/fs/jffs2/read.c 2003-11-17 02:07:44.000000000 +0100
-+++ linux/fs/jffs2/read.c 2004-11-19 10:25:12.121166048 +0100
-@@ -1,52 +1,29 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/kernel.h>
- #include <linux/slab.h>
--#include <linux/jffs2.h>
-+#include <linux/crc32.h>
-+#include <linux/pagemap.h>
- #include <linux/mtd/mtd.h>
-+#include <linux/compiler.h>
- #include "nodelist.h"
--#include <linux/crc32.h>
-
- int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_full_dnode *fd, unsigned char *buf, int ofs, int len)
- {
- struct jffs2_raw_inode *ri;
- size_t readlen;
-- __u32 crc;
-+ uint32_t crc;
- unsigned char *decomprbuf = NULL;
- unsigned char *readbuf = NULL;
- int ret = 0;
-@@ -55,35 +32,41 @@
- if (!ri)
- return -ENOMEM;
-
-- ret = c->mtd->read(c->mtd, fd->raw->flash_offset & ~3, sizeof(*ri), &readlen, (char *)ri);
-+ ret = jffs2_flash_read(c, ref_offset(fd->raw), sizeof(*ri), &readlen, (char *)ri);
- if (ret) {
- jffs2_free_raw_inode(ri);
-- printk(KERN_WARNING "Error reading node from 0x%08x: %d\n", fd->raw->flash_offset & ~3, ret);
-+ printk(KERN_WARNING "Error reading node from 0x%08x: %d\n", ref_offset(fd->raw), ret);
- return ret;
- }
- if (readlen != sizeof(*ri)) {
- jffs2_free_raw_inode(ri);
-- printk(KERN_WARNING "Short read from 0x%08x: wanted 0x%x bytes, got 0x%x\n",
-- fd->raw->flash_offset & ~3, sizeof(*ri), readlen);
-+ printk(KERN_WARNING "Short read from 0x%08x: wanted 0x%zx bytes, got 0x%zx\n",
-+ ref_offset(fd->raw), sizeof(*ri), readlen);
- return -EIO;
- }
- crc = crc32(0, ri, sizeof(*ri)-8);
-
-- D1(printk(KERN_DEBUG "Node read from %08x: node_crc %08x, calculated CRC %08x. dsize %x, csize %x, offset %x, buf %p\n", fd->raw->flash_offset & ~3, ri->node_crc, crc, ri->dsize, ri->csize, ri->offset, buf));
-- if (crc != ri->node_crc) {
-- printk(KERN_WARNING "Node CRC %08x != calculated CRC %08x for node at %08x\n", ri->node_crc, crc, fd->raw->flash_offset & ~3);
-+ D1(printk(KERN_DEBUG "Node read from %08x: node_crc %08x, calculated CRC %08x. dsize %x, csize %x, offset %x, buf %p\n",
-+ ref_offset(fd->raw), je32_to_cpu(ri->node_crc),
-+ crc, je32_to_cpu(ri->dsize), je32_to_cpu(ri->csize),
-+ je32_to_cpu(ri->offset), buf));
-+ if (crc != je32_to_cpu(ri->node_crc)) {
-+ printk(KERN_WARNING "Node CRC %08x != calculated CRC %08x for node at %08x\n",
-+ je32_to_cpu(ri->node_crc), crc, ref_offset(fd->raw));
- ret = -EIO;
- goto out_ri;
- }
- /* There was a bug where we wrote hole nodes out with csize/dsize
- swapped. Deal with it */
-- if (ri->compr == JFFS2_COMPR_ZERO && !ri->dsize && ri->csize) {
-+ if (ri->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(ri->dsize) &&
-+ je32_to_cpu(ri->csize)) {
- ri->dsize = ri->csize;
-- ri->csize = 0;
-+ ri->csize = cpu_to_je32(0);
- }
-
-- D1(if(ofs + len > ri->dsize) {
-- printk(KERN_WARNING "jffs2_read_dnode() asked for %d bytes at %d from %d-byte node\n", len, ofs, ri->dsize);
-+ D1(if(ofs + len > je32_to_cpu(ri->dsize)) {
-+ printk(KERN_WARNING "jffs2_read_dnode() asked for %d bytes at %d from %d-byte node\n",
-+ len, ofs, je32_to_cpu(ri->dsize));
- ret = -EINVAL;
- goto out_ri;
- });
-@@ -100,18 +83,18 @@
- Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy
- Reading partial node and it's compressed - read into readbuf, check checksum, decompress to decomprbuf and copy
- */
-- if (ri->compr == JFFS2_COMPR_NONE && len == ri->dsize) {
-+ if (ri->compr == JFFS2_COMPR_NONE && len == je32_to_cpu(ri->dsize)) {
- readbuf = buf;
- } else {
-- readbuf = kmalloc(ri->csize, GFP_KERNEL);
-+ readbuf = kmalloc(je32_to_cpu(ri->csize), GFP_KERNEL);
- if (!readbuf) {
- ret = -ENOMEM;
- goto out_ri;
- }
- }
- if (ri->compr != JFFS2_COMPR_NONE) {
-- if (len < ri->dsize) {
-- decomprbuf = kmalloc(ri->dsize, GFP_KERNEL);
-+ if (len < je32_to_cpu(ri->dsize)) {
-+ decomprbuf = kmalloc(je32_to_cpu(ri->dsize), GFP_KERNEL);
- if (!decomprbuf) {
- ret = -ENOMEM;
- goto out_readbuf;
-@@ -123,31 +106,35 @@
- decomprbuf = readbuf;
- }
-
-- D2(printk(KERN_DEBUG "Read %d bytes to %p\n", ri->csize, readbuf));
-- ret = c->mtd->read(c->mtd, (fd->raw->flash_offset &~3) + sizeof(*ri), ri->csize, &readlen, readbuf);
-+ D2(printk(KERN_DEBUG "Read %d bytes to %p\n", je32_to_cpu(ri->csize),
-+ readbuf));
-+ ret = jffs2_flash_read(c, (ref_offset(fd->raw)) + sizeof(*ri),
-+ je32_to_cpu(ri->csize), &readlen, readbuf);
-
-- if (!ret && readlen != ri->csize)
-+ if (!ret && readlen != je32_to_cpu(ri->csize))
- ret = -EIO;
- if (ret)
- goto out_decomprbuf;
-
-- crc = crc32(0, readbuf, ri->csize);
-- if (crc != ri->data_crc) {
-- printk(KERN_WARNING "Data CRC %08x != calculated CRC %08x for node at %08x\n", ri->data_crc, crc, fd->raw->flash_offset & ~3);
-+ crc = crc32(0, readbuf, je32_to_cpu(ri->csize));
-+ if (crc != je32_to_cpu(ri->data_crc)) {
-+ printk(KERN_WARNING "Data CRC %08x != calculated CRC %08x for node at %08x\n",
-+ je32_to_cpu(ri->data_crc), crc, ref_offset(fd->raw));
- ret = -EIO;
- goto out_decomprbuf;
- }
- D2(printk(KERN_DEBUG "Data CRC matches calculated CRC %08x\n", crc));
- if (ri->compr != JFFS2_COMPR_NONE) {
-- D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %p\n", ri->csize, readbuf, ri->dsize, decomprbuf));
-- ret = jffs2_decompress(ri->compr, readbuf, decomprbuf, ri->csize, ri->dsize);
-+ D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %p\n",
-+ je32_to_cpu(ri->csize), readbuf, je32_to_cpu(ri->dsize), decomprbuf));
-+ ret = jffs2_decompress(ri->compr, readbuf, decomprbuf, je32_to_cpu(ri->csize), je32_to_cpu(ri->dsize));
- if (ret) {
- printk(KERN_WARNING "Error: jffs2_decompress returned %d\n", ret);
- goto out_decomprbuf;
- }
- }
-
-- if (len < ri->dsize) {
-+ if (len < je32_to_cpu(ri->dsize)) {
- memcpy(buf, decomprbuf+ofs, len);
- }
- out_decomprbuf:
-@@ -161,3 +148,96 @@
-
- return ret;
- }
-+
-+int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
-+ unsigned char *buf, uint32_t offset, uint32_t len)
-+{
-+ uint32_t end = offset + len;
-+ struct jffs2_node_frag *frag;
-+ int ret;
-+
-+ D1(printk(KERN_DEBUG "jffs2_read_inode_range: ino #%u, range 0x%08x-0x%08x\n",
-+ f->inocache->ino, offset, offset+len));
-+
-+ frag = jffs2_lookup_node_frag(&f->fragtree, offset);
-+
-+ /* XXX FIXME: Where a single physical node actually shows up in two
-+ frags, we read it twice. Don't do that. */
-+ /* Now we're pointing at the first frag which overlaps our page */
-+ while(offset < end) {
-+ D2(printk(KERN_DEBUG "jffs2_read_inode_range: offset %d, end %d\n", offset, end));
-+ if (unlikely(!frag || frag->ofs > offset)) {
-+ uint32_t holesize = end - offset;
-+ if (frag) {
-+ D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset));
-+ holesize = min(holesize, frag->ofs - offset);
-+ D1(jffs2_print_frag_list(f));
-+ }
-+ D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize));
-+ memset(buf, 0, holesize);
-+ buf += holesize;
-+ offset += holesize;
-+ continue;
-+ } else if (unlikely(!frag->node)) {
-+ uint32_t holeend = min(end, frag->ofs + frag->size);
-+ D1(printk(KERN_DEBUG "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n", offset, holeend, frag->ofs, frag->ofs + frag->size));
-+ memset(buf, 0, holeend - offset);
-+ buf += holeend - offset;
-+ offset = holeend;
-+ frag = frag_next(frag);
-+ continue;
-+ } else {
-+ uint32_t readlen;
-+ uint32_t fragofs; /* offset within the frag to start reading */
-+
-+ fragofs = offset - frag->ofs;
-+ readlen = min(frag->size - fragofs, end - offset);
-+ D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%08x (%d)\n",
-+ frag->ofs+fragofs, frag->ofs+fragofs+readlen,
-+ ref_offset(frag->node->raw), ref_flags(frag->node->raw)));
-+ ret = jffs2_read_dnode(c, frag->node, buf, fragofs + frag->ofs - frag->node->ofs, readlen);
-+ D2(printk(KERN_DEBUG "node read done\n"));
-+ if (ret) {
-+ D1(printk(KERN_DEBUG"jffs2_read_inode_range error %d\n",ret));
-+ memset(buf, 0, readlen);
-+ return ret;
-+ }
-+ buf += readlen;
-+ offset += readlen;
-+ frag = frag_next(frag);
-+ D2(printk(KERN_DEBUG "node read was OK. Looping\n"));
-+ }
-+ }
-+ return 0;
-+}
-+
-+/* Core function to read symlink target. */
-+char *jffs2_getlink(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
-+{
-+ char *buf;
-+ int ret;
-+
-+ down(&f->sem);
-+
-+ if (!f->metadata) {
-+ printk(KERN_NOTICE "No metadata for symlink inode #%u\n", f->inocache->ino);
-+ up(&f->sem);
-+ return ERR_PTR(-EINVAL);
-+ }
-+ buf = kmalloc(f->metadata->size+1, GFP_USER);
-+ if (!buf) {
-+ up(&f->sem);
-+ return ERR_PTR(-ENOMEM);
-+ }
-+ buf[f->metadata->size]=0;
-+
-+ ret = jffs2_read_dnode(c, f->metadata, buf, 0, f->metadata->size);
-+
-+ up(&f->sem);
-+
-+ if (ret) {
-+ kfree(buf);
-+ return ERR_PTR(ret);
-+ }
-+ return buf;
-+}
-diff -Nurb linux-mips-2.4.27/fs/jffs2/readinode.c linux/fs/jffs2/readinode.c
---- linux-mips-2.4.27/fs/jffs2/readinode.c 2003-11-17 02:07:44.000000000 +0100
-+++ linux/fs/jffs2/readinode.c 2004-11-19 10:25:12.123165744 +0100
-@@ -1,79 +1,122 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
--/* Given an inode, probably with existing list of fragments, add the new node
-- * to the fragment list.
-- */
- #include <linux/kernel.h>
- #include <linux/slab.h>
- #include <linux/fs.h>
-+#include <linux/crc32.h>
-+#include <linux/pagemap.h>
- #include <linux/mtd/mtd.h>
--#include <linux/jffs2.h>
-+#include <linux/compiler.h>
- #include "nodelist.h"
--#include <linux/crc32.h>
-
-+static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag);
-
--D1(void jffs2_print_frag_list(struct jffs2_inode_info *f)
-+#if CONFIG_JFFS2_FS_DEBUG >= 1
-+static void jffs2_print_fragtree(struct rb_root *list, int permitbug)
- {
-- struct jffs2_node_frag *this = f->fraglist;
-+ struct jffs2_node_frag *this = frag_first(list);
-+ uint32_t lastofs = 0;
-+ int buggy = 0;
-
- while(this) {
- if (this->node)
-- printk(KERN_DEBUG "frag %04x-%04x: 0x%08x on flash (*%p->%p)\n", this->ofs, this->ofs+this->size, this->node->raw->flash_offset &~3, this, this->next);
-+ printk(KERN_DEBUG "frag %04x-%04x: 0x%08x(%d) on flash (*%p). left (%p), right (%p), parent (%p)\n",
-+ this->ofs, this->ofs+this->size, ref_offset(this->node->raw), ref_flags(this->node->raw),
-+ this, frag_left(this), frag_right(this), frag_parent(this));
- else
-- printk(KERN_DEBUG "frag %04x-%04x: hole (*%p->%p)\n", this->ofs, this->ofs+this->size, this, this->next);
-- this = this->next;
-+ printk(KERN_DEBUG "frag %04x-%04x: hole (*%p). left (%p} right (%p), parent (%p)\n", this->ofs,
-+ this->ofs+this->size, this, frag_left(this), frag_right(this), frag_parent(this));
-+ if (this->ofs != lastofs)
-+ buggy = 1;
-+ lastofs = this->ofs+this->size;
-+ this = frag_next(this);
-+ }
-+ if (buggy && !permitbug) {
-+ printk(KERN_CRIT "Frag tree got a hole in it\n");
-+ BUG();
- }
-+}
-+
-+void jffs2_print_frag_list(struct jffs2_inode_info *f)
-+{
-+ jffs2_print_fragtree(&f->fragtree, 0);
-+
- if (f->metadata) {
-- printk(KERN_DEBUG "metadata at 0x%08x\n", f->metadata->raw->flash_offset &~3);
-+ printk(KERN_DEBUG "metadata at 0x%08x\n", ref_offset(f->metadata->raw));
- }
--})
--
-+}
-
--int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn)
-+static int jffs2_sanitycheck_fragtree(struct jffs2_inode_info *f)
- {
-- int ret;
-- D1(printk(KERN_DEBUG "jffs2_add_full_dnode_to_inode(ino #%u, f %p, fn %p)\n", f->inocache->ino, f, fn));
-+ struct jffs2_node_frag *frag;
-+ int bitched = 0;
-
-- ret = jffs2_add_full_dnode_to_fraglist(c, &f->fraglist, fn);
-+ for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
-
-- D2(jffs2_print_frag_list(f));
-- return ret;
-+ struct jffs2_full_dnode *fn = frag->node;
-+ if (!fn || !fn->raw)
-+ continue;
-+
-+ if (ref_flags(fn->raw) == REF_PRISTINE) {
-+
-+ if (fn->frags > 1) {
-+ printk(KERN_WARNING "REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2\n", ref_offset(fn->raw), fn->frags);
-+ bitched = 1;
-+ }
-+ /* A hole node which isn't multi-page should be garbage-collected
-+ and merged anyway, so we just check for the frag size here,
-+ rather than mucking around with actually reading the node
-+ and checking the compression type, which is the real way
-+ to tell a hole node. */
-+ if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag) && frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) {
-+ printk(KERN_WARNING "REF_PRISTINE node at 0x%08x had a previous non-hole frag in the same page. Tell dwmw2\n",
-+ ref_offset(fn->raw));
-+ bitched = 1;
-+ }
-+
-+ if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag) && frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) {
-+ printk(KERN_WARNING "REF_PRISTINE node at 0x%08x (%08x-%08x) had a following non-hole frag in the same page. Tell dwmw2\n",
-+ ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size);
-+ bitched = 1;
-+ }
-+ }
-+ }
-+
-+ if (bitched) {
-+ struct jffs2_node_frag *thisfrag;
-+
-+ printk(KERN_WARNING "Inode is #%u\n", f->inocache->ino);
-+ thisfrag = frag_first(&f->fragtree);
-+ while (thisfrag) {
-+ if (!thisfrag->node) {
-+ printk("Frag @0x%x-0x%x; node-less hole\n",
-+ thisfrag->ofs, thisfrag->size + thisfrag->ofs);
-+ } else if (!thisfrag->node->raw) {
-+ printk("Frag @0x%x-0x%x; raw-less hole\n",
-+ thisfrag->ofs, thisfrag->size + thisfrag->ofs);
-+ } else {
-+ printk("Frag @0x%x-0x%x; raw at 0x%08x(%d) (0x%x-0x%x)\n",
-+ thisfrag->ofs, thisfrag->size + thisfrag->ofs,
-+ ref_offset(thisfrag->node->raw), ref_flags(thisfrag->node->raw),
-+ thisfrag->node->ofs, thisfrag->node->ofs+thisfrag->node->size);
-+ }
-+ thisfrag = frag_next(thisfrag);
-+ }
-+ }
-+ return bitched;
- }
-+#endif /* D1 */
-
- static void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this)
- {
-@@ -82,42 +125,38 @@
- if (!this->node->frags) {
- /* The node has no valid frags left. It's totally obsoleted */
- D2(printk(KERN_DEBUG "Marking old node @0x%08x (0x%04x-0x%04x) obsolete\n",
-- this->node->raw->flash_offset &~3, this->node->ofs, this->node->ofs+this->node->size));
-+ ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size));
- jffs2_mark_node_obsolete(c, this->node->raw);
- jffs2_free_full_dnode(this->node);
- } else {
-- D2(printk(KERN_DEBUG "Not marking old node @0x%08x (0x%04x-0x%04x) obsolete. frags is %d\n",
-- this->node->raw->flash_offset &~3, this->node->ofs, this->node->ofs+this->node->size,
-+ D2(printk(KERN_DEBUG "Marking old node @0x%08x (0x%04x-0x%04x) REF_NORMAL. frags is %d\n",
-+ ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size,
- this->node->frags));
-+ mark_ref_normal(this->node->raw);
- }
-
- }
- jffs2_free_node_frag(this);
- }
-
--/* Doesn't set inode->i_size */
--int jffs2_add_full_dnode_to_fraglist(struct jffs2_sb_info *c, struct jffs2_node_frag **list, struct jffs2_full_dnode *fn)
-+/* Given an inode, probably with existing list of fragments, add the new node
-+ * to the fragment list.
-+ */
-+int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn)
- {
-+ int ret;
-+ struct jffs2_node_frag *newfrag;
-
-- struct jffs2_node_frag *this, **prev, *old;
-- struct jffs2_node_frag *newfrag, *newfrag2;
-- __u32 lastend = 0;
--
-+ D1(printk(KERN_DEBUG "jffs2_add_full_dnode_to_inode(ino #%u, f %p, fn %p)\n", f->inocache->ino, f, fn));
-
- newfrag = jffs2_alloc_node_frag();
-- if (!newfrag) {
-+ if (unlikely(!newfrag))
- return -ENOMEM;
-- }
--
-- D2(if (fn->raw)
-- printk(KERN_DEBUG "adding node %04x-%04x @0x%08x on flash, newfrag *%p\n", fn->ofs, fn->ofs+fn->size, fn->raw->flash_offset &~3, newfrag);
-- else
-- printk(KERN_DEBUG "adding hole node %04x-%04x on flash, newfrag *%p\n", fn->ofs, fn->ofs+fn->size, newfrag));
-
-- prev = list;
-- this = *list;
-+ D2(printk(KERN_DEBUG "adding node %04x-%04x @0x%08x on flash, newfrag *%p\n",
-+ fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag));
-
-- if (!fn->size) {
-+ if (unlikely(!fn->size)) {
- jffs2_free_node_frag(newfrag);
- return 0;
- }
-@@ -126,176 +165,358 @@
- newfrag->size = fn->size;
- newfrag->node = fn;
- newfrag->node->frags = 1;
-- newfrag->next = (void *)0xdeadbeef;
-+
-+ ret = jffs2_add_frag_to_fragtree(c, &f->fragtree, newfrag);
-+ if (ret)
-+ return ret;
-+
-+ /* If we now share a page with other nodes, mark either previous
-+ or next node REF_NORMAL, as appropriate. */
-+ if (newfrag->ofs & (PAGE_CACHE_SIZE-1)) {
-+ struct jffs2_node_frag *prev = frag_prev(newfrag);
-+
-+ mark_ref_normal(fn->raw);
-+ /* If we don't start at zero there's _always_ a previous */
-+ if (prev->node)
-+ mark_ref_normal(prev->node->raw);
-+ }
-+
-+ if ((newfrag->ofs+newfrag->size) & (PAGE_CACHE_SIZE-1)) {
-+ struct jffs2_node_frag *next = frag_next(newfrag);
-+
-+ if (next) {
-+ mark_ref_normal(fn->raw);
-+ if (next->node)
-+ mark_ref_normal(next->node->raw);
-+ }
-+ }
-+ D2(if (jffs2_sanitycheck_fragtree(f)) {
-+ printk(KERN_WARNING "Just added node %04x-%04x @0x%08x on flash, newfrag *%p\n",
-+ fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag);
-+ return 0;
-+ })
-+ D2(jffs2_print_frag_list(f));
-+ return 0;
-+}
-+
-+/* Doesn't set inode->i_size */
-+static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag)
-+{
-+ struct jffs2_node_frag *this;
-+ uint32_t lastend;
-
- /* Skip all the nodes which are completed before this one starts */
-- while(this && fn->ofs >= this->ofs+this->size) {
-- lastend = this->ofs + this->size;
-+ this = jffs2_lookup_node_frag(list, newfrag->node->ofs);
-
-- D2(printk(KERN_DEBUG "j_a_f_d_t_f: skipping frag 0x%04x-0x%04x; phys 0x%08x (*%p->%p)\n",
-- this->ofs, this->ofs+this->size, this->node?(this->node->raw->flash_offset &~3):0xffffffff, this, this->next));
-- prev = &this->next;
-- this = this->next;
-+ if (this) {
-+ D2(printk(KERN_DEBUG "j_a_f_d_t_f: Lookup gave frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n",
-+ this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this));
-+ lastend = this->ofs + this->size;
-+ } else {
-+ D2(printk(KERN_DEBUG "j_a_f_d_t_f: Lookup gave no frag\n"));
-+ lastend = 0;
- }
-
- /* See if we ran off the end of the list */
-- if (!this) {
-+ if (lastend <= newfrag->ofs) {
- /* We did */
-- if (lastend < fn->ofs) {
-+
-+ /* Check if 'this' node was on the same page as the new node.
-+ If so, both 'this' and the new node get marked REF_NORMAL so
-+ the GC can take a look.
-+ */
-+ if ((lastend-1) >> PAGE_CACHE_SHIFT == newfrag->ofs >> PAGE_CACHE_SHIFT) {
-+ if (this->node)
-+ mark_ref_normal(this->node->raw);
-+ mark_ref_normal(newfrag->node->raw);
-+ }
-+
-+ if (lastend < newfrag->node->ofs) {
- /* ... and we need to put a hole in before the new node */
- struct jffs2_node_frag *holefrag = jffs2_alloc_node_frag();
-- if (!holefrag)
-+ if (!holefrag) {
-+ jffs2_free_node_frag(newfrag);
- return -ENOMEM;
-+ }
- holefrag->ofs = lastend;
-- holefrag->size = fn->ofs - lastend;
-- holefrag->next = NULL;
-+ holefrag->size = newfrag->node->ofs - lastend;
- holefrag->node = NULL;
-- *prev = holefrag;
-- prev = &holefrag->next;
-+ if (this) {
-+ /* By definition, the 'this' node has no right-hand child,
-+ because there are no frags with offset greater than it.
-+ So that's where we want to put the hole */
-+ D2(printk(KERN_DEBUG "Adding hole frag (%p) on right of node at (%p)\n", holefrag, this));
-+ rb_link_node(&holefrag->rb, &this->rb, &this->rb.rb_right);
-+ } else {
-+ D2(printk(KERN_DEBUG "Adding hole frag (%p) at root of tree\n", holefrag));
-+ rb_link_node(&holefrag->rb, NULL, &list->rb_node);
-+ }
-+ rb_insert_color(&holefrag->rb, list);
-+ this = holefrag;
- }
-- newfrag->next = NULL;
-- *prev = newfrag;
-+ if (this) {
-+ /* By definition, the 'this' node has no right-hand child,
-+ because there are no frags with offset greater than it.
-+ So that's where we want to put the hole */
-+ D2(printk(KERN_DEBUG "Adding new frag (%p) on right of node at (%p)\n", newfrag, this));
-+ rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right);
-+ } else {
-+ D2(printk(KERN_DEBUG "Adding new frag (%p) at root of tree\n", newfrag));
-+ rb_link_node(&newfrag->rb, NULL, &list->rb_node);
-+ }
-+ rb_insert_color(&newfrag->rb, list);
- return 0;
- }
-
-- D2(printk(KERN_DEBUG "j_a_f_d_t_f: dealing with frag 0x%04x-0x%04x; phys 0x%08x (*%p->%p)\n",
-- this->ofs, this->ofs+this->size, this->node?(this->node->raw->flash_offset &~3):0xffffffff, this, this->next));
-+ D2(printk(KERN_DEBUG "j_a_f_d_t_f: dealing with frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n",
-+ this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this));
-
-- /* OK. 'this' is pointing at the first frag that fn->ofs at least partially obsoletes,
-- * - i.e. fn->ofs < this->ofs+this->size && fn->ofs >= this->ofs
-+ /* OK. 'this' is pointing at the first frag that newfrag->ofs at least partially obsoletes,
-+ * - i.e. newfrag->ofs < this->ofs+this->size && newfrag->ofs >= this->ofs
- */
-- if (fn->ofs > this->ofs) {
-+ if (newfrag->ofs > this->ofs) {
- /* This node isn't completely obsoleted. The start of it remains valid */
-- if (this->ofs + this->size > fn->ofs + fn->size) {
-+
-+ /* Mark the new node and the partially covered node REF_NORMAL -- let
-+ the GC take a look at them */
-+ mark_ref_normal(newfrag->node->raw);
-+ if (this->node)
-+ mark_ref_normal(this->node->raw);
-+
-+ if (this->ofs + this->size > newfrag->ofs + newfrag->size) {
- /* The new node splits 'this' frag into two */
-- newfrag2 = jffs2_alloc_node_frag();
-+ struct jffs2_node_frag *newfrag2 = jffs2_alloc_node_frag();
- if (!newfrag2) {
- jffs2_free_node_frag(newfrag);
- return -ENOMEM;
- }
-- D1(printk(KERN_DEBUG "split old frag 0x%04x-0x%04x -->", this->ofs, this->ofs+this->size);
-+ D2(printk(KERN_DEBUG "split old frag 0x%04x-0x%04x -->", this->ofs, this->ofs+this->size);
- if (this->node)
-- printk("phys 0x%08x\n", this->node->raw->flash_offset &~3);
-+ printk("phys 0x%08x\n", ref_offset(this->node->raw));
- else
- printk("hole\n");
- )
-- newfrag2->ofs = fn->ofs + fn->size;
-+
-+ /* New second frag pointing to this's node */
-+ newfrag2->ofs = newfrag->ofs + newfrag->size;
- newfrag2->size = (this->ofs+this->size) - newfrag2->ofs;
-- newfrag2->next = this->next;
- newfrag2->node = this->node;
- if (this->node)
- this->node->frags++;
-- newfrag->next = newfrag2;
-- this->next = newfrag;
-+
-+ /* Adjust size of original 'this' */
- this->size = newfrag->ofs - this->ofs;
-+
-+ /* Now, we know there's no node with offset
-+ greater than this->ofs but smaller than
-+ newfrag2->ofs or newfrag->ofs, for obvious
-+ reasons. So we can do a tree insert from
-+ 'this' to insert newfrag, and a tree insert
-+ from newfrag to insert newfrag2. */
-+ jffs2_fragtree_insert(newfrag, this);
-+ rb_insert_color(&newfrag->rb, list);
-+
-+ jffs2_fragtree_insert(newfrag2, newfrag);
-+ rb_insert_color(&newfrag2->rb, list);
-+
- return 0;
- }
- /* New node just reduces 'this' frag in size, doesn't split it */
-- this->size = fn->ofs - this->ofs;
-- newfrag->next = this->next;
-- this->next = newfrag;
-- this = newfrag->next;
-+ this->size = newfrag->ofs - this->ofs;
-+
-+ /* Again, we know it lives down here in the tree */
-+ jffs2_fragtree_insert(newfrag, this);
-+ rb_insert_color(&newfrag->rb, list);
- } else {
-- D2(printk(KERN_DEBUG "Inserting newfrag (*%p) in before 'this' (*%p)\n", newfrag, this));
-- *prev = newfrag;
-- newfrag->next = this;
-+ /* New frag starts at the same point as 'this' used to. Replace
-+ it in the tree without doing a delete and insertion */
-+ D2(printk(KERN_DEBUG "Inserting newfrag (*%p),%d-%d in before 'this' (*%p),%d-%d\n",
-+ newfrag, newfrag->ofs, newfrag->ofs+newfrag->size,
-+ this, this->ofs, this->ofs+this->size));
-+
-+ rb_replace_node(&this->rb, &newfrag->rb, list);
-+
-+ if (newfrag->ofs + newfrag->size >= this->ofs+this->size) {
-+ D2(printk(KERN_DEBUG "Obsoleting node frag %p (%x-%x)\n", this, this->ofs, this->ofs+this->size));
-+ jffs2_obsolete_node_frag(c, this);
-+ } else {
-+ this->ofs += newfrag->size;
-+ this->size -= newfrag->size;
-+
-+ jffs2_fragtree_insert(this, newfrag);
-+ rb_insert_color(&this->rb, list);
-+ return 0;
- }
-- /* OK, now we have newfrag added in the correct place in the list, but
-- newfrag->next points to a fragment which may be overlapping it
-+ }
-+ /* OK, now we have newfrag added in the correct place in the tree, but
-+ frag_next(newfrag) may be a fragment which is overlapped by it
- */
-- while (this && newfrag->ofs + newfrag->size >= this->ofs + this->size) {
-- /* 'this' frag is obsoleted. */
-- old = this;
-- this = old->next;
-- jffs2_obsolete_node_frag(c, old);
-+ while ((this = frag_next(newfrag)) && newfrag->ofs + newfrag->size >= this->ofs + this->size) {
-+ /* 'this' frag is obsoleted completely. */
-+ D2(printk(KERN_DEBUG "Obsoleting node frag %p (%x-%x) and removing from tree\n", this, this->ofs, this->ofs+this->size));
-+ rb_erase(&this->rb, list);
-+ jffs2_obsolete_node_frag(c, this);
- }
- /* Now we're pointing at the first frag which isn't totally obsoleted by
- the new frag */
-- newfrag->next = this;
-
- if (!this || newfrag->ofs + newfrag->size == this->ofs) {
- return 0;
- }
-- /* Still some overlap */
-+ /* Still some overlap but we don't need to move it in the tree */
- this->size = (this->ofs + this->size) - (newfrag->ofs + newfrag->size);
- this->ofs = newfrag->ofs + newfrag->size;
-+
-+ /* And mark them REF_NORMAL so the GC takes a look at them */
-+ if (this->node)
-+ mark_ref_normal(this->node->raw);
-+ mark_ref_normal(newfrag->node->raw);
-+
- return 0;
- }
-
--void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct jffs2_node_frag **list, __u32 size)
-+void jffs2_truncate_fraglist (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size)
- {
-+ struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size);
-+
- D1(printk(KERN_DEBUG "Truncating fraglist to 0x%08x bytes\n", size));
-
-- while (*list) {
-- if ((*list)->ofs >= size) {
-- struct jffs2_node_frag *this = *list;
-- *list = this->next;
-- D1(printk(KERN_DEBUG "Removing frag 0x%08x-0x%08x\n", this->ofs, this->ofs+this->size));
-- jffs2_obsolete_node_frag(c, this);
-- continue;
-- } else if ((*list)->ofs + (*list)->size > size) {
-- D1(printk(KERN_DEBUG "Truncating frag 0x%08x-0x%08x\n", (*list)->ofs, (*list)->ofs + (*list)->size));
-- (*list)->size = size - (*list)->ofs;
-- }
-- list = &(*list)->next;
-+ /* We know frag->ofs <= size. That's what lookup does for us */
-+ if (frag && frag->ofs != size) {
-+ if (frag->ofs+frag->size >= size) {
-+ D1(printk(KERN_DEBUG "Truncating frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size));
-+ frag->size = size - frag->ofs;
-+ }
-+ frag = frag_next(frag);
-+ }
-+ while (frag && frag->ofs >= size) {
-+ struct jffs2_node_frag *next = frag_next(frag);
-+
-+ D1(printk(KERN_DEBUG "Removing frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size));
-+ frag_erase(frag, list);
-+ jffs2_obsolete_node_frag(c, frag);
-+ frag = next;
- }
- }
-
- /* Scan the list of all nodes present for this ino, build map of versions, etc. */
-
--void jffs2_read_inode (struct inode *inode)
-+static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
-+ struct jffs2_inode_info *f,
-+ struct jffs2_raw_inode *latest_node);
-+
-+int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
-+ uint32_t ino, struct jffs2_raw_inode *latest_node)
- {
-- struct jffs2_tmp_dnode_info *tn_list, *tn;
-- struct jffs2_full_dirent *fd_list;
-- struct jffs2_inode_info *f;
-- struct jffs2_full_dnode *fn = NULL;
-- struct jffs2_sb_info *c;
-- struct jffs2_raw_inode latest_node;
-- __u32 latest_mctime, mctime_ver;
-- __u32 mdata_ver = 0;
-- int ret;
-- ssize_t retlen;
-+ D2(printk(KERN_DEBUG "jffs2_do_read_inode(): getting inocache\n"));
-
-- D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino));
-+ retry_inocache:
-+ spin_lock(&c->inocache_lock);
-+ f->inocache = jffs2_get_ino_cache(c, ino);
-+
-+ D2(printk(KERN_DEBUG "jffs2_do_read_inode(): Got inocache at %p\n", f->inocache));
-+
-+ if (f->inocache) {
-+ /* Check its state. We may need to wait before we can use it */
-+ switch(f->inocache->state) {
-+ case INO_STATE_UNCHECKED:
-+ case INO_STATE_CHECKEDABSENT:
-+ f->inocache->state = INO_STATE_READING;
-+ break;
-
-- f = JFFS2_INODE_INFO(inode);
-- c = JFFS2_SB_INFO(inode->i_sb);
-+ case INO_STATE_CHECKING:
-+ case INO_STATE_GC:
-+ /* If it's in either of these states, we need
-+ to wait for whoever's got it to finish and
-+ put it back. */
-+ D1(printk(KERN_DEBUG "jffs2_get_ino_cache_read waiting for ino #%u in state %d\n",
-+ ino, f->inocache->state));
-+ sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
-+ goto retry_inocache;
-+
-+ case INO_STATE_READING:
-+ case INO_STATE_PRESENT:
-+ /* Eep. This should never happen. It can
-+ happen if Linux calls read_inode() again
-+ before clear_inode() has finished though. */
-+ printk(KERN_WARNING "Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->state);
-+ /* Fail. That's probably better than allowing it to succeed */
-+ f->inocache = NULL;
-+ break;
-
-- memset(f, 0, sizeof(*f));
-- D2(printk(KERN_DEBUG "getting inocache\n"));
-- init_MUTEX(&f->sem);
-- f->inocache = jffs2_get_ino_cache(c, inode->i_ino);
-- D2(printk(KERN_DEBUG "jffs2_read_inode(): Got inocache at %p\n", f->inocache));
-+ default:
-+ BUG();
-+ }
-+ }
-+ spin_unlock(&c->inocache_lock);
-
-- if (!f->inocache && inode->i_ino == 1) {
-+ if (!f->inocache && ino == 1) {
- /* Special case - no root inode on medium */
- f->inocache = jffs2_alloc_inode_cache();
- if (!f->inocache) {
-- printk(KERN_CRIT "jffs2_read_inode(): Cannot allocate inocache for root inode\n");
-- make_bad_inode(inode);
-- return;
-+ printk(KERN_CRIT "jffs2_do_read_inode(): Cannot allocate inocache for root inode\n");
-+ return -ENOMEM;
- }
-- D1(printk(KERN_DEBUG "jffs2_read_inode(): Creating inocache for root inode\n"));
-+ D1(printk(KERN_DEBUG "jffs2_do_read_inode(): Creating inocache for root inode\n"));
- memset(f->inocache, 0, sizeof(struct jffs2_inode_cache));
- f->inocache->ino = f->inocache->nlink = 1;
- f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
-+ f->inocache->state = INO_STATE_READING;
- jffs2_add_ino_cache(c, f->inocache);
- }
- if (!f->inocache) {
-- printk(KERN_WARNING "jffs2_read_inode() on nonexistent ino %lu\n", (unsigned long)inode->i_ino);
-- make_bad_inode(inode);
-- return;
-+ printk(KERN_WARNING "jffs2_do_read_inode() on nonexistent ino %u\n", ino);
-+ return -ENOENT;
- }
-- D1(printk(KERN_DEBUG "jffs2_read_inode(): ino #%lu nlink is %d\n", (unsigned long)inode->i_ino, f->inocache->nlink));
-- inode->i_nlink = f->inocache->nlink;
-+
-+ return jffs2_do_read_inode_internal(c, f, latest_node);
-+}
-+
-+int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
-+{
-+ struct jffs2_raw_inode n;
-+ struct jffs2_inode_info *f = kmalloc(sizeof(*f), GFP_KERNEL);
-+ int ret;
-+
-+ if (!f)
-+ return -ENOMEM;
-+
-+ memset(f, 0, sizeof(*f));
-+ init_MUTEX_LOCKED(&f->sem);
-+ f->inocache = ic;
-+
-+ ret = jffs2_do_read_inode_internal(c, f, &n);
-+ if (!ret) {
-+ up(&f->sem);
-+ jffs2_do_clear_inode(c, f);
-+ }
-+ kfree (f);
-+ return ret;
-+}
-+
-+static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
-+ struct jffs2_inode_info *f,
-+ struct jffs2_raw_inode *latest_node)
-+{
-+ struct jffs2_tmp_dnode_info *tn_list, *tn;
-+ struct jffs2_full_dirent *fd_list;
-+ struct jffs2_full_dnode *fn = NULL;
-+ uint32_t crc;
-+ uint32_t latest_mctime, mctime_ver;
-+ uint32_t mdata_ver = 0;
-+ size_t retlen;
-+ int ret;
-+
-+ D1(printk(KERN_DEBUG "jffs2_do_read_inode_internal(): ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink));
-
- /* Grab all nodes relevant to this ino */
-- ret = jffs2_get_inode_nodes(c, inode->i_ino, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver);
-+ ret = jffs2_get_inode_nodes(c, f->inocache->ino, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver);
-
- if (ret) {
-- printk(KERN_CRIT "jffs2_get_inode_nodes() for ino %lu returned %d\n", inode->i_ino, ret);
-- make_bad_inode(inode);
-- return;
-+ printk(KERN_CRIT "jffs2_get_inode_nodes() for ino %u returned %d\n", f->inocache->ino, ret);
-+ if (f->inocache->state == INO_STATE_READING)
-+ jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
-+ return ret;
- }
- f->dents = fd_list;
-
-@@ -304,205 +525,169 @@
-
- fn = tn->fn;
-
-- if (f->metadata && tn->version > mdata_ver) {
-- D1(printk(KERN_DEBUG "Obsoleting old metadata at 0x%08x\n", f->metadata->raw->flash_offset &~3));
-+ if (f->metadata) {
-+ if (likely(tn->version >= mdata_ver)) {
-+ D1(printk(KERN_DEBUG "Obsoleting old metadata at 0x%08x\n", ref_offset(f->metadata->raw)));
- jffs2_mark_node_obsolete(c, f->metadata->raw);
- jffs2_free_full_dnode(f->metadata);
- f->metadata = NULL;
-
- mdata_ver = 0;
-+ } else {
-+ /* This should never happen. */
-+ printk(KERN_WARNING "Er. New metadata at 0x%08x with ver %d is actually older than previous ver %d at 0x%08x\n",
-+ ref_offset(fn->raw), tn->version, mdata_ver, ref_offset(f->metadata->raw));
-+ jffs2_mark_node_obsolete(c, fn->raw);
-+ jffs2_free_full_dnode(fn);
-+ /* Fill in latest_node from the metadata, not this one we're about to free... */
-+ fn = f->metadata;
-+ goto next_tn;
-+ }
- }
-
- if (fn->size) {
- jffs2_add_full_dnode_to_inode(c, f, fn);
- } else {
- /* Zero-sized node at end of version list. Just a metadata update */
-- D1(printk(KERN_DEBUG "metadata @%08x: ver %d\n", fn->raw->flash_offset &~3, tn->version));
-+ D1(printk(KERN_DEBUG "metadata @%08x: ver %d\n", ref_offset(fn->raw), tn->version));
- f->metadata = fn;
- mdata_ver = tn->version;
- }
-+ next_tn:
- tn_list = tn->next;
- jffs2_free_tmp_dnode_info(tn);
- }
-+ D1(jffs2_sanitycheck_fragtree(f));
-+
- if (!fn) {
- /* No data nodes for this inode. */
-- if (inode->i_ino != 1) {
-- printk(KERN_WARNING "jffs2_read_inode(): No data nodes found for ino #%lu\n", inode->i_ino);
-+ if (f->inocache->ino != 1) {
-+ printk(KERN_WARNING "jffs2_do_read_inode(): No data nodes found for ino #%u\n", f->inocache->ino);
- if (!fd_list) {
-- make_bad_inode(inode);
-- return;
-- }
-- printk(KERN_WARNING "jffs2_read_inode(): But it has children so we fake some modes for it\n");
-+ if (f->inocache->state == INO_STATE_READING)
-+ jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
-+ return -EIO;
-+ }
-+ printk(KERN_WARNING "jffs2_do_read_inode(): But it has children so we fake some modes for it\n");
-+ }
-+ latest_node->mode = cpu_to_jemode(S_IFDIR|S_IRUGO|S_IWUSR|S_IXUGO);
-+ latest_node->version = cpu_to_je32(0);
-+ latest_node->atime = latest_node->ctime = latest_node->mtime = cpu_to_je32(0);
-+ latest_node->isize = cpu_to_je32(0);
-+ latest_node->gid = cpu_to_je16(0);
-+ latest_node->uid = cpu_to_je16(0);
-+ if (f->inocache->state == INO_STATE_READING)
-+ jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
-+ return 0;
- }
-- inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO;
-- latest_node.version = 0;
-- inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME;
-- inode->i_nlink = f->inocache->nlink;
-- inode->i_size = 0;
-- } else {
-- __u32 crc;
-
-- ret = c->mtd->read(c->mtd, fn->raw->flash_offset & ~3, sizeof(latest_node), &retlen, (void *)&latest_node);
-- if (ret || retlen != sizeof(latest_node)) {
-- printk(KERN_NOTICE "MTD read in jffs2_read_inode() failed: Returned %d, %ld of %d bytes read\n",
-- ret, (long)retlen, sizeof(latest_node));
-- jffs2_clear_inode(inode);
-- make_bad_inode(inode);
-- return;
-- }
--
-- crc = crc32(0, &latest_node, sizeof(latest_node)-8);
-- if (crc != latest_node.node_crc) {
-- printk(KERN_NOTICE "CRC failed for read_inode of inode %ld at physical location 0x%x\n", inode->i_ino, fn->raw->flash_offset & ~3);
-- jffs2_clear_inode(inode);
-- make_bad_inode(inode);
-- return;
-- }
--
-- inode->i_mode = latest_node.mode;
-- inode->i_uid = latest_node.uid;
-- inode->i_gid = latest_node.gid;
-- inode->i_size = latest_node.isize;
-- if (S_ISREG(inode->i_mode))
-- jffs2_truncate_fraglist(c, &f->fraglist, latest_node.isize);
-- inode->i_atime = latest_node.atime;
-- inode->i_mtime = latest_node.mtime;
-- inode->i_ctime = latest_node.ctime;
-- }
--
-- /* OK, now the special cases. Certain inode types should
-- have only one data node, and it's kept as the metadata
-- node */
-- if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode) ||
-- S_ISLNK(inode->i_mode)) {
-- if (f->metadata) {
-- printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o had metadata node\n", inode->i_ino, inode->i_mode);
-- jffs2_clear_inode(inode);
-- make_bad_inode(inode);
-- return;
-- }
-- if (!f->fraglist) {
-- printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o has no fragments\n", inode->i_ino, inode->i_mode);
-- jffs2_clear_inode(inode);
-- make_bad_inode(inode);
-- return;
-- }
-- /* ASSERT: f->fraglist != NULL */
-- if (f->fraglist->next) {
-- printk(KERN_WARNING "Argh. Special inode #%lu with mode 0%o had more than one node\n", inode->i_ino, inode->i_mode);
-- /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
-- jffs2_clear_inode(inode);
-- make_bad_inode(inode);
-- return;
-- }
-- /* OK. We're happy */
-- f->metadata = f->fraglist->node;
-- jffs2_free_node_frag(f->fraglist);
-- f->fraglist = NULL;
-+ ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(*latest_node), &retlen, (void *)latest_node);
-+ if (ret || retlen != sizeof(*latest_node)) {
-+ printk(KERN_NOTICE "MTD read in jffs2_do_read_inode() failed: Returned %d, %zd of %zd bytes read\n",
-+ ret, retlen, sizeof(*latest_node));
-+ /* FIXME: If this fails, there seems to be a memory leak. Find it. */
-+ up(&f->sem);
-+ jffs2_do_clear_inode(c, f);
-+ return ret?ret:-EIO;
- }
-
-- inode->i_blksize = PAGE_SIZE;
-- inode->i_blocks = (inode->i_size + 511) >> 9;
--
-- switch (inode->i_mode & S_IFMT) {
-- unsigned short rdev;
--
-- case S_IFLNK:
-- inode->i_op = &jffs2_symlink_inode_operations;
-- /* Hack to work around broken isize in old symlink code.
-- Remove this when dwmw2 comes to his senses and stops
-- symlinks from being an entirely gratuitous special
-- case. */
-- if (!inode->i_size)
-- inode->i_size = latest_node.dsize;
-- break;
-+ crc = crc32(0, latest_node, sizeof(*latest_node)-8);
-+ if (crc != je32_to_cpu(latest_node->node_crc)) {
-+ printk(KERN_NOTICE "CRC failed for read_inode of inode %u at physical location 0x%x\n", f->inocache->ino, ref_offset(fn->raw));
-+ up(&f->sem);
-+ jffs2_do_clear_inode(c, f);
-+ return -EIO;
-+ }
-
-+ switch(jemode_to_cpu(latest_node->mode) & S_IFMT) {
- case S_IFDIR:
-- if (mctime_ver > latest_node.version) {
-+ if (mctime_ver > je32_to_cpu(latest_node->version)) {
- /* The times in the latest_node are actually older than
- mctime in the latest dirent. Cheat. */
-- inode->i_mtime = inode->i_ctime = inode->i_atime =
-- latest_mctime;
-+ latest_node->ctime = latest_node->mtime = cpu_to_je32(latest_mctime);
- }
-- inode->i_op = &jffs2_dir_inode_operations;
-- inode->i_fop = &jffs2_dir_operations;
- break;
-
-+
- case S_IFREG:
-- inode->i_op = &jffs2_file_inode_operations;
-- inode->i_fop = &jffs2_file_operations;
-- inode->i_mapping->a_ops = &jffs2_file_address_operations;
-- inode->i_mapping->nrpages = 0;
-+ /* If it was a regular file, truncate it to the latest node's isize */
-+ jffs2_truncate_fraglist(c, &f->fragtree, je32_to_cpu(latest_node->isize));
- break;
-
-+ case S_IFLNK:
-+ /* Hack to work around broken isize in old symlink code.
-+ Remove this when dwmw2 comes to his senses and stops
-+ symlinks from being an entirely gratuitous special
-+ case. */
-+ if (!je32_to_cpu(latest_node->isize))
-+ latest_node->isize = latest_node->dsize;
-+ /* fall through... */
-+
- case S_IFBLK:
- case S_IFCHR:
-- /* Read the device numbers from the media */
-- D1(printk(KERN_DEBUG "Reading device numbers from flash\n"));
-- if (jffs2_read_dnode(c, f->metadata, (char *)&rdev, 0, sizeof(rdev)) < 0) {
-- /* Eep */
-- printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino);
-- jffs2_clear_inode(inode);
-- make_bad_inode(inode);
-- return;
-+ /* Certain inode types should have only one data node, and it's
-+ kept as the metadata node */
-+ if (f->metadata) {
-+ printk(KERN_WARNING "Argh. Special inode #%u with mode 0%o had metadata node\n",
-+ f->inocache->ino, jemode_to_cpu(latest_node->mode));
-+ up(&f->sem);
-+ jffs2_do_clear_inode(c, f);
-+ return -EIO;
- }
--
-- case S_IFSOCK:
-- case S_IFIFO:
-- inode->i_op = &jffs2_file_inode_operations;
-- init_special_inode(inode, inode->i_mode, kdev_t_to_nr(MKDEV(rdev>>8, rdev&0xff)));
-+ if (!frag_first(&f->fragtree)) {
-+ printk(KERN_WARNING "Argh. Special inode #%u with mode 0%o has no fragments\n",
-+ f->inocache->ino, jemode_to_cpu(latest_node->mode));
-+ up(&f->sem);
-+ jffs2_do_clear_inode(c, f);
-+ return -EIO;
-+ }
-+ /* ASSERT: f->fraglist != NULL */
-+ if (frag_next(frag_first(&f->fragtree))) {
-+ printk(KERN_WARNING "Argh. Special inode #%u with mode 0x%x had more than one node\n",
-+ f->inocache->ino, jemode_to_cpu(latest_node->mode));
-+ /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
-+ up(&f->sem);
-+ jffs2_do_clear_inode(c, f);
-+ return -EIO;
-+ }
-+ /* OK. We're happy */
-+ f->metadata = frag_first(&f->fragtree)->node;
-+ jffs2_free_node_frag(frag_first(&f->fragtree));
-+ f->fragtree = RB_ROOT;
- break;
--
-- default:
-- printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu", inode->i_mode, (unsigned long)inode->i_ino);
- }
-- D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
-+ if (f->inocache->state == INO_STATE_READING)
-+ jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT);
-+
-+ return 0;
- }
-
--void jffs2_clear_inode (struct inode *inode)
-+void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
- {
-- /* We can forget about this inode for now - drop all
-- * the nodelists associated with it, etc.
-- */
-- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-- struct jffs2_node_frag *frag, *frags;
- struct jffs2_full_dirent *fd, *fds;
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- int deleted;
-
-- D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
--
- down(&f->sem);
- deleted = f->inocache && !f->inocache->nlink;
-
-- frags = f->fraglist;
-- fds = f->dents;
- if (f->metadata) {
- if (deleted)
- jffs2_mark_node_obsolete(c, f->metadata->raw);
- jffs2_free_full_dnode(f->metadata);
- }
-
-- while (frags) {
-- frag = frags;
-- frags = frag->next;
-- D2(printk(KERN_DEBUG "jffs2_clear_inode: frag at 0x%x-0x%x: node %p, frags %d--\n", frag->ofs, frag->ofs+frag->size, frag->node, frag->node?frag->node->frags:0));
-+ jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL);
-
-- if (frag->node && !(--frag->node->frags)) {
-- /* Not a hole, and it's the final remaining frag of this node. Free the node */
-- if (deleted)
-- jffs2_mark_node_obsolete(c, frag->node->raw);
-+ fds = f->dents;
-
-- jffs2_free_full_dnode(frag->node);
-- }
-- jffs2_free_node_frag(frag);
-- }
- while(fds) {
- fd = fds;
- fds = fd->next;
- jffs2_free_full_dirent(fd);
- }
-
-- up(&f->sem);
--};
-+ if (f->inocache && f->inocache->state != INO_STATE_CHECKING)
-+ jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
-
-+ up(&f->sem);
-+}
-diff -Nurb linux-mips-2.4.27/fs/jffs2/scan.c linux/fs/jffs2/scan.c
---- linux-mips-2.4.27/fs/jffs2/scan.c 2003-11-17 02:07:44.000000000 +0100
-+++ linux/fs/jffs2/scan.c 2004-11-19 10:25:12.124165592 +0100
-@@ -1,47 +1,25 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
- #include <linux/kernel.h>
-+#include <linux/sched.h>
- #include <linux/slab.h>
--#include <linux/jffs2.h>
- #include <linux/mtd/mtd.h>
- #include <linux/pagemap.h>
--#include "nodelist.h"
- #include <linux/crc32.h>
-+#include <linux/compiler.h>
-+#include "nodelist.h"
-
-+#define EMPTY_SCAN_SIZE 1024
-
- #define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
- c->free_size -= _x; c->dirty_size += _x; \
-@@ -51,6 +29,10 @@
- c->free_size -= _x; c->used_size += _x; \
- jeb->free_size -= _x ; jeb->used_size += _x; \
- }while(0)
-+#define UNCHECKED_SPACE(x) do { typeof(x) _x = (x); \
-+ c->free_size -= _x; c->unchecked_size += _x; \
-+ jeb->free_size -= _x ; jeb->unchecked_size += _x; \
-+ }while(0)
-
- #define noisy_printk(noise, args...) do { \
- if (*(noise)) { \
-@@ -63,39 +45,84 @@
- } while(0)
-
- static uint32_t pseudo_random;
--static void jffs2_rotate_lists(struct jffs2_sb_info *c);
-
--static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
-+static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-+ unsigned char *buf, uint32_t buf_size);
-
- /* These helper functions _must_ increase ofs and also do the dirty/used space accounting.
- * Returning an error will abort the mount - bad checksums etc. should just mark the space
- * as dirty.
- */
--static int jffs2_scan_empty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs, int *noise);
--static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs);
--static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs);
-+static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-+ struct jffs2_raw_inode *ri, uint32_t ofs);
-+static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-+ struct jffs2_raw_dirent *rd, uint32_t ofs);
-+
-+#define BLK_STATE_ALLFF 0
-+#define BLK_STATE_CLEAN 1
-+#define BLK_STATE_PARTDIRTY 2
-+#define BLK_STATE_CLEANMARKER 3
-+#define BLK_STATE_ALLDIRTY 4
-+#define BLK_STATE_BADBLOCK 5
-
-+static inline int min_free(struct jffs2_sb_info *c)
-+{
-+ uint32_t min = 2 * sizeof(struct jffs2_raw_inode);
-+#ifdef CONFIG_JFFS2_FS_NAND
-+ if (!jffs2_can_mark_obsolete(c) && min < c->wbuf_pagesize)
-+ return c->wbuf_pagesize;
-+#endif
-+ return min;
-
-+}
- int jffs2_scan_medium(struct jffs2_sb_info *c)
- {
- int i, ret;
-- __u32 empty_blocks = 0;
--
-- if (!c->blocks) {
-- printk(KERN_WARNING "EEEK! c->blocks is NULL!\n");
-- return -EINVAL;
-+ uint32_t empty_blocks = 0, bad_blocks = 0;
-+ unsigned char *flashbuf = NULL;
-+ uint32_t buf_size = 0;
-+#ifndef __ECOS
-+ size_t pointlen;
-+
-+ if (c->mtd->point) {
-+ ret = c->mtd->point (c->mtd, 0, c->mtd->size, &pointlen, &flashbuf);
-+ if (!ret && pointlen < c->mtd->size) {
-+ /* Don't muck about if it won't let us point to the whole flash */
-+ D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", pointlen));
-+ c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);
-+ flashbuf = NULL;
-+ }
-+ if (ret)
-+ D1(printk(KERN_DEBUG "MTD point failed %d\n", ret));
-+ }
-+#endif
-+ if (!flashbuf) {
-+ /* For NAND it's quicker to read a whole eraseblock at a time,
-+ apparently */
-+ if (jffs2_cleanmarker_oob(c))
-+ buf_size = c->sector_size;
-+ else
-+ buf_size = PAGE_SIZE;
-+
-+ D1(printk(KERN_DEBUG "Allocating readbuf of %d bytes\n", buf_size));
-+ flashbuf = kmalloc(buf_size, GFP_KERNEL);
-+ if (!flashbuf)
-+ return -ENOMEM;
- }
-+
- for (i=0; i<c->nr_blocks; i++) {
- struct jffs2_eraseblock *jeb = &c->blocks[i];
-
-- ret = jffs2_scan_eraseblock(c, jeb);
-+ ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), buf_size);
-+
- if (ret < 0)
-- return ret;
-+ goto out;
-
- ACCT_PARANOIA_CHECK(jeb);
-
- /* Now decide which list to put it on */
-- if (ret == 1) {
-+ switch(ret) {
-+ case BLK_STATE_ALLFF:
- /*
- * Empty block. Since we can't be sure it
- * was entirely erased, we just queue it for erase
-@@ -103,10 +130,12 @@
- * is complete. Meanwhile we still count it as empty
- * for later checks.
- */
-- list_add(&jeb->list, &c->erase_pending_list);
- empty_blocks++;
-+ list_add(&jeb->list, &c->erase_pending_list);
- c->nr_erasing_blocks++;
-- } else if (jeb->used_size == PAD(sizeof(struct jffs2_unknown_node)) && !jeb->first_node->next_in_ino) {
-+ break;
-+
-+ case BLK_STATE_CLEANMARKER:
- /* Only a CLEANMARKER node is valid */
- if (!jeb->dirty_size) {
- /* It's actually free */
-@@ -118,74 +147,227 @@
- list_add(&jeb->list, &c->erase_pending_list);
- c->nr_erasing_blocks++;
- }
-- } else if (jeb->used_size > c->sector_size - (2*sizeof(struct jffs2_raw_inode))) {
-+ break;
-+
-+ case BLK_STATE_CLEAN:
- /* Full (or almost full) of clean data. Clean list */
- list_add(&jeb->list, &c->clean_list);
-- } else if (jeb->used_size) {
-+ break;
-+
-+ case BLK_STATE_PARTDIRTY:
- /* Some data, but not full. Dirty list. */
- /* Except that we want to remember the block with most free space,
- and stick it in the 'nextblock' position to start writing to it.
- Later when we do snapshots, this must be the most recent block,
- not the one with most free space.
- */
-- if (jeb->free_size > 2*sizeof(struct jffs2_raw_inode) &&
-+ if (jeb->free_size > min_free(c) &&
- (!c->nextblock || c->nextblock->free_size < jeb->free_size)) {
- /* Better candidate for the next writes to go to */
-- if (c->nextblock)
-+ if (c->nextblock) {
-+ c->nextblock->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size;
-+ c->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size;
-+ c->free_size -= c->nextblock->free_size;
-+ c->wasted_size -= c->nextblock->wasted_size;
-+ c->nextblock->free_size = c->nextblock->wasted_size = 0;
-+ if (VERYDIRTY(c, c->nextblock->dirty_size)) {
-+ list_add(&c->nextblock->list, &c->very_dirty_list);
-+ } else {
- list_add(&c->nextblock->list, &c->dirty_list);
-+ }
-+ }
- c->nextblock = jeb;
- } else {
-+ jeb->dirty_size += jeb->free_size + jeb->wasted_size;
-+ c->dirty_size += jeb->free_size + jeb->wasted_size;
-+ c->free_size -= jeb->free_size;
-+ c->wasted_size -= jeb->wasted_size;
-+ jeb->free_size = jeb->wasted_size = 0;
-+ if (VERYDIRTY(c, jeb->dirty_size)) {
-+ list_add(&jeb->list, &c->very_dirty_list);
-+ } else {
- list_add(&jeb->list, &c->dirty_list);
- }
-- } else {
-+ }
-+ break;
-+
-+ case BLK_STATE_ALLDIRTY:
- /* Nothing valid - not even a clean marker. Needs erasing. */
- /* For now we just put it on the erasing list. We'll start the erases later */
-- printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset);
-+ D1(printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset));
- list_add(&jeb->list, &c->erase_pending_list);
- c->nr_erasing_blocks++;
-+ break;
-+
-+ case BLK_STATE_BADBLOCK:
-+ D1(printk(KERN_NOTICE "JFFS2: Block at 0x%08x is bad\n", jeb->offset));
-+ list_add(&jeb->list, &c->bad_list);
-+ c->bad_size += c->sector_size;
-+ c->free_size -= c->sector_size;
-+ bad_blocks++;
-+ break;
-+ default:
-+ printk(KERN_WARNING "jffs2_scan_medium(): unknown block state\n");
-+ BUG();
- }
- }
-- /* Rotate the lists by some number to ensure wear levelling */
-- jffs2_rotate_lists(c);
-
-+ /* Nextblock dirty is always seen as wasted, because we cannot recycle it now */
-+ if (c->nextblock && (c->nextblock->dirty_size)) {
-+ c->nextblock->wasted_size += c->nextblock->dirty_size;
-+ c->wasted_size += c->nextblock->dirty_size;
-+ c->dirty_size -= c->nextblock->dirty_size;
-+ c->nextblock->dirty_size = 0;
-+ }
-+#ifdef CONFIG_JFFS2_FS_NAND
-+ if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) {
-+ /* If we're going to start writing into a block which already
-+ contains data, and the end of the data isn't page-aligned,
-+ skip a little and align it. */
-+
-+ uint32_t skip = c->nextblock->free_size & (c->wbuf_pagesize-1);
-+
-+ D1(printk(KERN_DEBUG "jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment\n",
-+ skip));
-+ c->nextblock->wasted_size += skip;
-+ c->wasted_size += skip;
-+
-+ c->nextblock->free_size -= skip;
-+ c->free_size -= skip;
-+ }
-+#endif
- if (c->nr_erasing_blocks) {
-- if (!c->used_size && empty_blocks != c->nr_blocks) {
-+ if ( !c->used_size && ((empty_blocks+bad_blocks)!= c->nr_blocks || bad_blocks == c->nr_blocks) ) {
- printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n");
-- return -EIO;
-+ printk(KERN_NOTICE "empty_blocks %d, bad_blocks %d, c->nr_blocks %d\n",empty_blocks,bad_blocks,c->nr_blocks);
-+ ret = -EIO;
-+ goto out;
- }
- jffs2_erase_pending_trigger(c);
- }
-+ ret = 0;
-+ out:
-+ if (buf_size)
-+ kfree(flashbuf);
-+#ifndef __ECOS
-+ else
-+ c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size);
-+#endif
-+ return ret;
-+}
-+
-+static int jffs2_fill_scan_buf (struct jffs2_sb_info *c, unsigned char *buf,
-+ uint32_t ofs, uint32_t len)
-+{
-+ int ret;
-+ size_t retlen;
-+
-+ ret = jffs2_flash_read(c, ofs, len, &retlen, buf);
-+ if (ret) {
-+ D1(printk(KERN_WARNING "mtd->read(0x%x bytes from 0x%x) returned %d\n", len, ofs, ret));
-+ return ret;
-+ }
-+ if (retlen < len) {
-+ D1(printk(KERN_WARNING "Read at 0x%x gave only 0x%zx bytes\n", ofs, retlen));
-+ return -EIO;
-+ }
-+ D2(printk(KERN_DEBUG "Read 0x%x bytes from 0x%08x into buf\n", len, ofs));
-+ D2(printk(KERN_DEBUG "000: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
-+ buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]));
- return 0;
- }
-
--static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) {
-- struct jffs2_unknown_node node;
-- __u32 ofs, prevofs;
-- __u32 hdr_crc, nodetype;
-+static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-+ unsigned char *buf, uint32_t buf_size) {
-+ struct jffs2_unknown_node *node;
-+ struct jffs2_unknown_node crcnode;
-+ uint32_t ofs, prevofs;
-+ uint32_t hdr_crc, buf_ofs, buf_len;
- int err;
- int noise = 0;
-+ int wasempty = 0;
-+ uint32_t empty_start = 0;
-+#ifdef CONFIG_JFFS2_FS_NAND
-+ int cleanmarkerfound = 0;
-+#endif
-
- ofs = jeb->offset;
- prevofs = jeb->offset - 1;
-
- D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs));
-
-- err = jffs2_scan_empty(c, jeb, &ofs, &noise);
-- if (err) return err;
-- if (ofs == jeb->offset + c->sector_size) {
-+#ifdef CONFIG_JFFS2_FS_NAND
-+ if (jffs2_cleanmarker_oob(c)) {
-+ int ret = jffs2_check_nand_cleanmarker(c, jeb);
-+ D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret));
-+ /* Even if it's not found, we still scan to see
-+ if the block is empty. We use this information
-+ to decide whether to erase it or not. */
-+ switch (ret) {
-+ case 0: cleanmarkerfound = 1; break;
-+ case 1: break;
-+ case 2: return BLK_STATE_BADBLOCK;
-+ case 3: return BLK_STATE_ALLDIRTY; /* Block has failed to erase min. once */
-+ default: return ret;
-+ }
-+ }
-+#endif
-+ buf_ofs = jeb->offset;
-+
-+ if (!buf_size) {
-+ buf_len = c->sector_size;
-+ } else {
-+ buf_len = EMPTY_SCAN_SIZE;
-+ err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
-+ if (err)
-+ return err;
-+ }
-+
-+ /* We temporarily use 'ofs' as a pointer into the buffer/jeb */
-+ ofs = 0;
-+
-+ /* Scan only 4KiB of 0xFF before declaring it's empty */
-+ while(ofs < EMPTY_SCAN_SIZE && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF)
-+ ofs += 4;
-+
-+ if (ofs == EMPTY_SCAN_SIZE) {
-+#ifdef CONFIG_JFFS2_FS_NAND
-+ if (jffs2_cleanmarker_oob(c)) {
-+ /* scan oob, take care of cleanmarker */
-+ int ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound);
-+ D2(printk(KERN_NOTICE "jffs2_check_oob_empty returned %d\n",ret));
-+ switch (ret) {
-+ case 0: return cleanmarkerfound ? BLK_STATE_CLEANMARKER : BLK_STATE_ALLFF;
-+ case 1: return BLK_STATE_ALLDIRTY;
-+ case 2: return BLK_STATE_BADBLOCK; /* case 2/3 are paranoia checks */
-+ case 3: return BLK_STATE_ALLDIRTY; /* Block has failed to erase min. once */
-+ default: return ret;
-+ }
-+ }
-+#endif
- D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset));
-- return 1; /* special return code */
-+ return BLK_STATE_ALLFF; /* OK to erase if all blocks are like this */
-+ }
-+ if (ofs) {
-+ D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset,
-+ jeb->offset + ofs));
-+ DIRTY_SPACE(ofs);
- }
-
-+ /* Now ofs is a complete physical flash offset as it always was... */
-+ ofs += jeb->offset;
-+
- noise = 10;
-
- while(ofs < jeb->offset + c->sector_size) {
-- ssize_t retlen;
-- ACCT_PARANOIA_CHECK(jeb);
-+
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+
-+ cond_resched();
-
- if (ofs & 3) {
- printk(KERN_WARNING "Eep. ofs 0x%08x not word-aligned!\n", ofs);
-- ofs = (ofs+3)&~3;
-+ ofs = PAD(ofs);
- continue;
- }
- if (ofs == prevofs) {
-@@ -196,102 +378,173 @@
- }
- prevofs = ofs;
-
-- if (jeb->offset + c->sector_size < ofs + sizeof(node)) {
-- D1(printk(KERN_DEBUG "Fewer than %d bytes left to end of block. Not reading\n", sizeof(struct jffs2_unknown_node)));
-+ if (jeb->offset + c->sector_size < ofs + sizeof(*node)) {
-+ D1(printk(KERN_DEBUG "Fewer than %zd bytes left to end of block. (%x+%x<%x+%zx) Not reading\n", sizeof(struct jffs2_unknown_node),
-+ jeb->offset, c->sector_size, ofs, sizeof(*node)));
- DIRTY_SPACE((jeb->offset + c->sector_size)-ofs);
- break;
- }
-
-- err = c->mtd->read(c->mtd, ofs, sizeof(node), &retlen, (char *)&node);
--
-- if (err) {
-- D1(printk(KERN_WARNING "mtd->read(0x%x bytes from 0x%x) returned %d\n", sizeof(node), ofs, err));
-+ if (buf_ofs + buf_len < ofs + sizeof(*node)) {
-+ buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
-+ D1(printk(KERN_DEBUG "Fewer than %zd bytes (node header) left to end of buf. Reading 0x%x at 0x%08x\n",
-+ sizeof(struct jffs2_unknown_node), buf_len, ofs));
-+ err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
-+ if (err)
- return err;
-+ buf_ofs = ofs;
- }
-- if (retlen < sizeof(node)) {
-- D1(printk(KERN_WARNING "Read at 0x%x gave only 0x%x bytes\n", ofs, retlen));
-- DIRTY_SPACE(retlen);
-- ofs += retlen;
-- continue;
-+
-+ node = (struct jffs2_unknown_node *)&buf[ofs-buf_ofs];
-+
-+ if (*(uint32_t *)(&buf[ofs-buf_ofs]) == 0xffffffff) {
-+ uint32_t inbuf_ofs = ofs - buf_ofs + 4;
-+ uint32_t scanend;
-+
-+ empty_start = ofs;
-+ ofs += 4;
-+
-+ /* If scanning empty space after only a cleanmarker, don't
-+ bother scanning the whole block */
-+ if (unlikely(empty_start == jeb->offset + c->cleanmarker_size &&
-+ jeb->offset + EMPTY_SCAN_SIZE < buf_ofs + buf_len))
-+ scanend = jeb->offset + EMPTY_SCAN_SIZE - buf_ofs;
-+ else
-+ scanend = buf_len;
-+
-+ D1(printk(KERN_DEBUG "Found empty flash at 0x%08x\n", ofs));
-+ while (inbuf_ofs < scanend) {
-+ if (*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff)
-+ goto emptyends;
-+
-+ inbuf_ofs+=4;
-+ ofs += 4;
- }
-+ /* Ran off end. */
-+ D1(printk(KERN_DEBUG "Empty flash ends normally at 0x%08x\n", ofs));
-
-- if (node.magic == JFFS2_EMPTY_BITMASK && node.nodetype == JFFS2_EMPTY_BITMASK) {
-- D1(printk(KERN_DEBUG "Found empty flash at 0x%x\n", ofs));
-- err = jffs2_scan_empty(c, jeb, &ofs, &noise);
-- if (err) return err;
-+ if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) &&
-+ c->cleanmarker_size && !jeb->first_node->next_in_ino && !jeb->dirty_size)
-+ return BLK_STATE_CLEANMARKER;
-+ wasempty = 1;
-+ continue;
-+ } else if (wasempty) {
-+ emptyends:
-+ printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n", empty_start, ofs);
-+ DIRTY_SPACE(ofs-empty_start);
-+ wasempty = 0;
- continue;
- }
-
-- if (ofs == jeb->offset && node.magic == KSAMTIB_CIGAM_2SFFJ) {
-+ if (ofs == jeb->offset && je16_to_cpu(node->magic) == KSAMTIB_CIGAM_2SFFJ) {
- printk(KERN_WARNING "Magic bitmask is backwards at offset 0x%08x. Wrong endian filesystem?\n", ofs);
- DIRTY_SPACE(4);
- ofs += 4;
- continue;
- }
-- if (node.magic == JFFS2_DIRTY_BITMASK) {
-- D1(printk(KERN_DEBUG "Empty bitmask at 0x%08x\n", ofs));
-+ if (je16_to_cpu(node->magic) == JFFS2_DIRTY_BITMASK) {
-+ D1(printk(KERN_DEBUG "Dirty bitmask at 0x%08x\n", ofs));
- DIRTY_SPACE(4);
- ofs += 4;
- continue;
- }
-- if (node.magic == JFFS2_OLD_MAGIC_BITMASK) {
-+ if (je16_to_cpu(node->magic) == JFFS2_OLD_MAGIC_BITMASK) {
- printk(KERN_WARNING "Old JFFS2 bitmask found at 0x%08x\n", ofs);
- printk(KERN_WARNING "You cannot use older JFFS2 filesystems with newer kernels\n");
- DIRTY_SPACE(4);
- ofs += 4;
- continue;
- }
-- if (node.magic != JFFS2_MAGIC_BITMASK) {
-+ if (je16_to_cpu(node->magic) != JFFS2_MAGIC_BITMASK) {
- /* OK. We're out of possibilities. Whinge and move on */
-- noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n", JFFS2_MAGIC_BITMASK, ofs, node.magic);
-+ noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n",
-+ JFFS2_MAGIC_BITMASK, ofs,
-+ je16_to_cpu(node->magic));
- DIRTY_SPACE(4);
- ofs += 4;
- continue;
- }
- /* We seem to have a node of sorts. Check the CRC */
-- nodetype = node.nodetype;
-- node.nodetype |= JFFS2_NODE_ACCURATE;
-- hdr_crc = crc32(0, &node, sizeof(node)-4);
-- node.nodetype = nodetype;
-- if (hdr_crc != node.hdr_crc) {
-+ crcnode.magic = node->magic;
-+ crcnode.nodetype = cpu_to_je16( je16_to_cpu(node->nodetype) | JFFS2_NODE_ACCURATE);
-+ crcnode.totlen = node->totlen;
-+ hdr_crc = crc32(0, &crcnode, sizeof(crcnode)-4);
-+
-+ if (hdr_crc != je32_to_cpu(node->hdr_crc)) {
- noisy_printk(&noise, "jffs2_scan_eraseblock(): Node at 0x%08x {0x%04x, 0x%04x, 0x%08x) has invalid CRC 0x%08x (calculated 0x%08x)\n",
-- ofs, node.magic, node.nodetype, node.totlen, node.hdr_crc, hdr_crc);
-+ ofs, je16_to_cpu(node->magic),
-+ je16_to_cpu(node->nodetype),
-+ je32_to_cpu(node->totlen),
-+ je32_to_cpu(node->hdr_crc),
-+ hdr_crc);
- DIRTY_SPACE(4);
- ofs += 4;
- continue;
- }
-
-- if (ofs + node.totlen > jeb->offset + c->sector_size) {
-+ if (ofs + je32_to_cpu(node->totlen) >
-+ jeb->offset + c->sector_size) {
- /* Eep. Node goes over the end of the erase block. */
- printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n",
-- ofs, node.totlen);
-+ ofs, je32_to_cpu(node->totlen));
- printk(KERN_WARNING "Perhaps the file system was created with the wrong erase size?\n");
- DIRTY_SPACE(4);
- ofs += 4;
- continue;
- }
-
-- switch(node.nodetype | JFFS2_NODE_ACCURATE) {
-+ if (!(je16_to_cpu(node->nodetype) & JFFS2_NODE_ACCURATE)) {
-+ /* Wheee. This is an obsoleted node */
-+ D2(printk(KERN_DEBUG "Node at 0x%08x is obsolete. Skipping\n", ofs));
-+ DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
-+ ofs += PAD(je32_to_cpu(node->totlen));
-+ continue;
-+ }
-+
-+ switch(je16_to_cpu(node->nodetype)) {
- case JFFS2_NODETYPE_INODE:
-- err = jffs2_scan_inode_node(c, jeb, &ofs);
-+ if (buf_ofs + buf_len < ofs + sizeof(struct jffs2_raw_inode)) {
-+ buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
-+ D1(printk(KERN_DEBUG "Fewer than %zd bytes (inode node) left to end of buf. Reading 0x%x at 0x%08x\n",
-+ sizeof(struct jffs2_raw_inode), buf_len, ofs));
-+ err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
-+ if (err)
-+ return err;
-+ buf_ofs = ofs;
-+ node = (void *)buf;
-+ }
-+ err = jffs2_scan_inode_node(c, jeb, (void *)node, ofs);
- if (err) return err;
-+ ofs += PAD(je32_to_cpu(node->totlen));
- break;
-
- case JFFS2_NODETYPE_DIRENT:
-- err = jffs2_scan_dirent_node(c, jeb, &ofs);
-+ if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) {
-+ buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
-+ D1(printk(KERN_DEBUG "Fewer than %d bytes (dirent node) left to end of buf. Reading 0x%x at 0x%08x\n",
-+ je32_to_cpu(node->totlen), buf_len, ofs));
-+ err = jffs2_fill_scan_buf(c, buf, ofs, buf_len);
-+ if (err)
-+ return err;
-+ buf_ofs = ofs;
-+ node = (void *)buf;
-+ }
-+ err = jffs2_scan_dirent_node(c, jeb, (void *)node, ofs);
- if (err) return err;
-+ ofs += PAD(je32_to_cpu(node->totlen));
- break;
-
- case JFFS2_NODETYPE_CLEANMARKER:
-- if (node.totlen != sizeof(struct jffs2_unknown_node)) {
-+ D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs));
-+ if (je32_to_cpu(node->totlen) != c->cleanmarker_size) {
- printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n",
-- ofs, node.totlen, sizeof(struct jffs2_unknown_node));
-+ ofs, je32_to_cpu(node->totlen), c->cleanmarker_size);
- DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
-+ ofs += PAD(sizeof(struct jffs2_unknown_node));
- } else if (jeb->first_node) {
- printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)\n", ofs, jeb->offset);
- DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
- ofs += PAD(sizeof(struct jffs2_unknown_node));
-- continue;
- } else {
- struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref();
- if (!marker_ref) {
-@@ -300,98 +553,80 @@
- }
- marker_ref->next_in_ino = NULL;
- marker_ref->next_phys = NULL;
-- marker_ref->flash_offset = ofs;
-- marker_ref->totlen = sizeof(struct jffs2_unknown_node);
-+ marker_ref->flash_offset = ofs | REF_NORMAL;
-+ marker_ref->__totlen = c->cleanmarker_size;
- jeb->first_node = jeb->last_node = marker_ref;
-
-- USED_SPACE(PAD(sizeof(struct jffs2_unknown_node)));
-+ USED_SPACE(PAD(c->cleanmarker_size));
-+ ofs += PAD(c->cleanmarker_size);
- }
-- ofs += PAD(sizeof(struct jffs2_unknown_node));
-+ break;
-+
-+ case JFFS2_NODETYPE_PADDING:
-+ DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
-+ ofs += PAD(je32_to_cpu(node->totlen));
- break;
-
- default:
-- switch (node.nodetype & JFFS2_COMPAT_MASK) {
-+ switch (je16_to_cpu(node->nodetype) & JFFS2_COMPAT_MASK) {
- case JFFS2_FEATURE_ROCOMPAT:
-- printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
-+ printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs);
- c->flags |= JFFS2_SB_FLAG_RO;
-- if (!(OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY))
-+ if (!(jffs2_is_readonly(c)))
- return -EROFS;
-- DIRTY_SPACE(PAD(node.totlen));
-- ofs += PAD(node.totlen);
-- continue;
-+ DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
-+ ofs += PAD(je32_to_cpu(node->totlen));
-+ break;
-
- case JFFS2_FEATURE_INCOMPAT:
-- printk(KERN_NOTICE "Incompatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
-+ printk(KERN_NOTICE "Incompatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs);
- return -EINVAL;
-
- case JFFS2_FEATURE_RWCOMPAT_DELETE:
-- printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
-- DIRTY_SPACE(PAD(node.totlen));
-- ofs += PAD(node.totlen);
-+ D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs));
-+ DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
-+ ofs += PAD(je32_to_cpu(node->totlen));
- break;
-
- case JFFS2_FEATURE_RWCOMPAT_COPY:
-- printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
-- USED_SPACE(PAD(node.totlen));
-- ofs += PAD(node.totlen);
-+ D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs));
-+ USED_SPACE(PAD(je32_to_cpu(node->totlen)));
-+ ofs += PAD(je32_to_cpu(node->totlen));
- break;
- }
- }
- }
-- D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, used 0x%08x\n", jeb->offset,
-- jeb->free_size, jeb->dirty_size, jeb->used_size));
-- return 0;
--}
-
--/* We're pointing at the first empty word on the flash. Scan and account for the whole dirty region */
--static int jffs2_scan_empty(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *startofs, int *noise)
--{
-- __u32 *buf;
-- __u32 scanlen = (jeb->offset + c->sector_size) - *startofs;
-- __u32 curofs = *startofs;
--
-- buf = kmalloc(min((__u32)PAGE_SIZE, scanlen), GFP_KERNEL);
-- if (!buf) {
-- printk(KERN_WARNING "Scan buffer allocation failed\n");
-- return -ENOMEM;
-- }
-- while(scanlen) {
-- ssize_t retlen;
-- int ret, i;
--
-- ret = c->mtd->read(c->mtd, curofs, min((__u32)PAGE_SIZE, scanlen), &retlen, (char *)buf);
-- if(ret) {
-- D1(printk(KERN_WARNING "jffs2_scan_empty(): Read 0x%x bytes at 0x%08x returned %d\n", min((__u32)PAGE_SIZE, scanlen), curofs, ret));
-- kfree(buf);
-- return ret;
-- }
-- if (retlen < 4) {
-- D1(printk(KERN_WARNING "Eep. too few bytes read in scan_empty()\n"));
-- kfree(buf);
-- return -EIO;
-- }
-- for (i=0; i<(retlen / 4); i++) {
-- if (buf[i] != 0xffffffff) {
-- curofs += i*4;
--
-- noisy_printk(noise, "jffs2_scan_empty(): Empty block at 0x%08x ends at 0x%08x (with 0x%08x)! Marking dirty\n", *startofs, curofs, buf[i]);
-- DIRTY_SPACE(curofs - (*startofs));
-- *startofs = curofs;
-- kfree(buf);
-- return 0;
-- }
-- }
-- scanlen -= retlen&~3;
-- curofs += retlen&~3;
-- }
-
-- D1(printk(KERN_DEBUG "Empty flash detected from 0x%08x to 0x%08x\n", *startofs, curofs));
-- kfree(buf);
-- *startofs = curofs;
-- return 0;
-+ D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x\n", jeb->offset,
-+ jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size));
-+
-+ /* mark_node_obsolete can add to wasted !! */
-+ if (jeb->wasted_size) {
-+ jeb->dirty_size += jeb->wasted_size;
-+ c->dirty_size += jeb->wasted_size;
-+ c->wasted_size -= jeb->wasted_size;
-+ jeb->wasted_size = 0;
-+ }
-+
-+ if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size
-+ && (!jeb->first_node || jeb->first_node->next_in_ino) )
-+ return BLK_STATE_CLEANMARKER;
-+
-+ /* move blocks with max 4 byte dirty space to cleanlist */
-+ else if (!ISDIRTY(c->sector_size - (jeb->used_size + jeb->unchecked_size))) {
-+ c->dirty_size -= jeb->dirty_size;
-+ c->wasted_size += jeb->dirty_size;
-+ jeb->wasted_size += jeb->dirty_size;
-+ jeb->dirty_size = 0;
-+ return BLK_STATE_CLEAN;
-+ } else if (jeb->used_size || jeb->unchecked_size)
-+ return BLK_STATE_PARTDIRTY;
-+ else
-+ return BLK_STATE_ALLDIRTY;
- }
-
--static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, __u32 ino)
-+static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino)
- {
- struct jffs2_inode_cache *ic;
-
-@@ -399,137 +634,77 @@
- if (ic)
- return ic;
-
-+ if (ino > c->highest_ino)
-+ c->highest_ino = ino;
-+
- ic = jffs2_alloc_inode_cache();
- if (!ic) {
- printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of inode cache failed\n");
- return NULL;
- }
- memset(ic, 0, sizeof(*ic));
-- ic->scan = kmalloc(sizeof(struct jffs2_scan_info), GFP_KERNEL);
-- if (!ic->scan) {
-- printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of scan info for inode cache failed\n");
-- jffs2_free_inode_cache(ic);
-- return NULL;
-- }
-- memset(ic->scan, 0, sizeof(*ic->scan));
-+
- ic->ino = ino;
- ic->nodes = (void *)ic;
- jffs2_add_ino_cache(c, ic);
- if (ino == 1)
-- ic->nlink=1;
-+ ic->nlink = 1;
- return ic;
- }
-
--static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs)
-+static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-+ struct jffs2_raw_inode *ri, uint32_t ofs)
- {
- struct jffs2_raw_node_ref *raw;
-- struct jffs2_full_dnode *fn;
-- struct jffs2_tmp_dnode_info *tn, **tn_list;
- struct jffs2_inode_cache *ic;
-- struct jffs2_raw_inode ri;
-- __u32 crc;
-- __u16 oldnodetype;
-- int ret;
-- ssize_t retlen;
--
-- D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", *ofs));
--
-- ret = c->mtd->read(c->mtd, *ofs, sizeof(ri), &retlen, (char *)&ri);
-- if (ret) {
-- printk(KERN_NOTICE "jffs2_scan_inode_node(): Read error at 0x%08x: %d\n", *ofs, ret);
-- return ret;
-- }
-- if (retlen != sizeof(ri)) {
-- printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n",
-- retlen, *ofs, sizeof(ri));
-- return -EIO;
-- }
-+ uint32_t ino = je32_to_cpu(ri->ino);
-
-- /* We sort of assume that the node was accurate when it was
-- first written to the medium :) */
-- oldnodetype = ri.nodetype;
-- ri.nodetype |= JFFS2_NODE_ACCURATE;
-- crc = crc32(0, &ri, sizeof(ri)-8);
-- ri.nodetype = oldnodetype;
-+ D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs));
-
-- if(crc != ri.node_crc) {
-- printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-- *ofs, ri.node_crc, crc);
-- /* FIXME: Why do we believe totlen? */
-- DIRTY_SPACE(4);
-- *ofs += 4;
-- return 0;
-- }
-- /* There was a bug where we wrote hole nodes out with csize/dsize
-- swapped. Deal with it */
-- if (ri.compr == JFFS2_COMPR_ZERO && !ri.dsize && ri.csize) {
-- ri.dsize = ri.csize;
-- ri.csize = 0;
-- }
-+ /* We do very little here now. Just check the ino# to which we should attribute
-+ this node; we can do all the CRC checking etc. later. There's a tradeoff here --
-+ we used to scan the flash once only, reading everything we want from it into
-+ memory, then building all our in-core data structures and freeing the extra
-+ information. Now we allow the first part of the mount to complete a lot quicker,
-+ but we have to go _back_ to the flash in order to finish the CRC checking, etc.
-+ Which means that the _full_ amount of time to get to proper write mode with GC
-+ operational may actually be _longer_ than before. Sucks to be me. */
-
-- if (ri.csize) {
-- /* Check data CRC too */
-- unsigned char *dbuf;
-- __u32 crc;
--
-- dbuf = kmalloc(PAGE_CACHE_SIZE, GFP_KERNEL);
-- if (!dbuf) {
-- printk(KERN_NOTICE "jffs2_scan_inode_node(): allocation of temporary data buffer for CRC check failed\n");
-- return -ENOMEM;
-- }
-- ret = c->mtd->read(c->mtd, *ofs+sizeof(ri), ri.csize, &retlen, dbuf);
-- if (ret) {
-- printk(KERN_NOTICE "jffs2_scan_inode_node(): Read error at 0x%08x: %d\n", *ofs+sizeof(ri), ret);
-- kfree(dbuf);
-- return ret;
-- }
-- if (retlen != ri.csize) {
-- printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n",
-- retlen, *ofs+ sizeof(ri), ri.csize);
-- kfree(dbuf);
-- return -EIO;
-- }
-- crc = crc32(0, dbuf, ri.csize);
-- kfree(dbuf);
-- if (crc != ri.data_crc) {
-- printk(KERN_NOTICE "jffs2_scan_inode_node(): Data CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-- *ofs, ri.data_crc, crc);
-- DIRTY_SPACE(PAD(ri.totlen));
-- *ofs += PAD(ri.totlen);
-- return 0;
-- }
-- }
--
-- /* Wheee. It worked */
- raw = jffs2_alloc_raw_node_ref();
- if (!raw) {
- printk(KERN_NOTICE "jffs2_scan_inode_node(): allocation of node reference failed\n");
- return -ENOMEM;
- }
-- tn = jffs2_alloc_tmp_dnode_info();
-- if (!tn) {
-- jffs2_free_raw_node_ref(raw);
-- return -ENOMEM;
-- }
-- fn = jffs2_alloc_full_dnode();
-- if (!fn) {
-- jffs2_free_tmp_dnode_info(tn);
-+
-+ ic = jffs2_get_ino_cache(c, ino);
-+ if (!ic) {
-+ /* Inocache get failed. Either we read a bogus ino# or it's just genuinely the
-+ first node we found for this inode. Do a CRC check to protect against the former
-+ case */
-+ uint32_t crc = crc32(0, ri, sizeof(*ri)-8);
-+
-+ if (crc != je32_to_cpu(ri->node_crc)) {
-+ printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-+ ofs, je32_to_cpu(ri->node_crc), crc);
-+ /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */
-+ DIRTY_SPACE(PAD(je32_to_cpu(ri->totlen)));
- jffs2_free_raw_node_ref(raw);
-- return -ENOMEM;
-+ return 0;
- }
-- ic = jffs2_scan_make_ino_cache(c, ri.ino);
-+ ic = jffs2_scan_make_ino_cache(c, ino);
- if (!ic) {
-- jffs2_free_full_dnode(fn);
-- jffs2_free_tmp_dnode_info(tn);
- jffs2_free_raw_node_ref(raw);
- return -ENOMEM;
- }
-+ }
-
-- /* Build the data structures and file them for later */
-- raw->flash_offset = *ofs;
-- raw->totlen = PAD(ri.totlen);
-+ /* Wheee. It worked */
-+
-+ raw->flash_offset = ofs | REF_UNCHECKED;
-+ raw->__totlen = PAD(je32_to_cpu(ri->totlen));
- raw->next_phys = NULL;
- raw->next_in_ino = ic->nodes;
-+
- ic->nodes = raw;
- if (!jeb->first_node)
- jeb->first_node = raw;
-@@ -538,134 +713,56 @@
- jeb->last_node = raw;
-
- D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n",
-- ri.ino, ri.version, ri.offset, ri.offset+ri.dsize));
--
-- pseudo_random += ri.version;
--
-- for (tn_list = &ic->scan->tmpnodes; *tn_list; tn_list = &((*tn_list)->next)) {
-- if ((*tn_list)->version < ri.version)
-- continue;
-- if ((*tn_list)->version > ri.version)
-- break;
-- /* Wheee. We've found another instance of the same version number.
-- We should obsolete one of them.
-- */
-- D1(printk(KERN_DEBUG "Duplicate version %d found in ino #%u. Previous one is at 0x%08x\n", ri.version, ic->ino, (*tn_list)->fn->raw->flash_offset &~3));
-- if (!jeb->used_size) {
-- D1(printk(KERN_DEBUG "No valid nodes yet found in this eraseblock 0x%08x, so obsoleting the new instance at 0x%08x\n",
-- jeb->offset, raw->flash_offset & ~3));
-- ri.nodetype &= ~JFFS2_NODE_ACCURATE;
-- /* Perhaps we could also mark it as such on the medium. Maybe later */
-- }
-- break;
-- }
--
-- if (ri.nodetype & JFFS2_NODE_ACCURATE) {
-- memset(fn,0,sizeof(*fn));
--
-- fn->ofs = ri.offset;
-- fn->size = ri.dsize;
-- fn->frags = 0;
-- fn->raw = raw;
--
-- tn->next = NULL;
-- tn->fn = fn;
-- tn->version = ri.version;
-+ je32_to_cpu(ri->ino), je32_to_cpu(ri->version),
-+ je32_to_cpu(ri->offset),
-+ je32_to_cpu(ri->offset)+je32_to_cpu(ri->dsize)));
-
-- USED_SPACE(PAD(ri.totlen));
-- jffs2_add_tn_to_list(tn, &ic->scan->tmpnodes);
-- /* Make sure the one we just added is the _last_ in the list
-- with this version number, so the older ones get obsoleted */
-- while (tn->next && tn->next->version == tn->version) {
-+ pseudo_random += je32_to_cpu(ri->version);
-
-- D1(printk(KERN_DEBUG "Shifting new node at 0x%08x after other node at 0x%08x for version %d in list\n",
-- fn->raw->flash_offset&~3, tn->next->fn->raw->flash_offset &~3, ri.version));
--
-- if(tn->fn != fn)
-- BUG();
-- tn->fn = tn->next->fn;
-- tn->next->fn = fn;
-- tn = tn->next;
-- }
-- } else {
-- jffs2_free_full_dnode(fn);
-- jffs2_free_tmp_dnode_info(tn);
-- raw->flash_offset |= 1;
-- DIRTY_SPACE(PAD(ri.totlen));
-- }
-- *ofs += PAD(ri.totlen);
-+ UNCHECKED_SPACE(PAD(je32_to_cpu(ri->totlen)));
- return 0;
- }
-
--static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, __u32 *ofs)
-+static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
-+ struct jffs2_raw_dirent *rd, uint32_t ofs)
- {
- struct jffs2_raw_node_ref *raw;
- struct jffs2_full_dirent *fd;
- struct jffs2_inode_cache *ic;
-- struct jffs2_raw_dirent rd;
-- __u16 oldnodetype;
-- int ret;
-- __u32 crc;
-- ssize_t retlen;
--
-- D1(printk(KERN_DEBUG "jffs2_scan_dirent_node(): Node at 0x%08x\n", *ofs));
-+ uint32_t crc;
-
-- ret = c->mtd->read(c->mtd, *ofs, sizeof(rd), &retlen, (char *)&rd);
-- if (ret) {
-- printk(KERN_NOTICE "jffs2_scan_dirent_node(): Read error at 0x%08x: %d\n", *ofs, ret);
-- return ret;
-- }
-- if (retlen != sizeof(rd)) {
-- printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n",
-- retlen, *ofs, sizeof(rd));
-- return -EIO;
-- }
-+ D1(printk(KERN_DEBUG "jffs2_scan_dirent_node(): Node at 0x%08x\n", ofs));
-
-- /* We sort of assume that the node was accurate when it was
-- first written to the medium :) */
-- oldnodetype = rd.nodetype;
-- rd.nodetype |= JFFS2_NODE_ACCURATE;
-- crc = crc32(0, &rd, sizeof(rd)-8);
-- rd.nodetype = oldnodetype;
-+ /* We don't get here unless the node is still valid, so we don't have to
-+ mask in the ACCURATE bit any more. */
-+ crc = crc32(0, rd, sizeof(*rd)-8);
-
-- if (crc != rd.node_crc) {
-+ if (crc != je32_to_cpu(rd->node_crc)) {
- printk(KERN_NOTICE "jffs2_scan_dirent_node(): Node CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-- *ofs, rd.node_crc, crc);
-- /* FIXME: Why do we believe totlen? */
-- DIRTY_SPACE(4);
-- *ofs += 4;
-+ ofs, je32_to_cpu(rd->node_crc), crc);
-+ /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */
-+ DIRTY_SPACE(PAD(je32_to_cpu(rd->totlen)));
- return 0;
- }
-
-- pseudo_random += rd.version;
-+ pseudo_random += je32_to_cpu(rd->version);
-
-- fd = jffs2_alloc_full_dirent(rd.nsize+1);
-+ fd = jffs2_alloc_full_dirent(rd->nsize+1);
- if (!fd) {
- return -ENOMEM;
--}
-- ret = c->mtd->read(c->mtd, *ofs + sizeof(rd), rd.nsize, &retlen, &fd->name[0]);
-- if (ret) {
-- jffs2_free_full_dirent(fd);
-- printk(KERN_NOTICE "jffs2_scan_dirent_node(): Read error at 0x%08x: %d\n",
-- *ofs + sizeof(rd), ret);
-- return ret;
-- }
-- if (retlen != rd.nsize) {
-- jffs2_free_full_dirent(fd);
-- printk(KERN_NOTICE "Short read: 0x%x bytes at 0x%08x instead of requested %x\n",
-- retlen, *ofs + sizeof(rd), rd.nsize);
-- return -EIO;
- }
-- crc = crc32(0, fd->name, rd.nsize);
-- if (crc != rd.name_crc) {
-+ memcpy(&fd->name, rd->name, rd->nsize);
-+ fd->name[rd->nsize] = 0;
-+
-+ crc = crc32(0, fd->name, rd->nsize);
-+ if (crc != je32_to_cpu(rd->name_crc)) {
- printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
-- *ofs, rd.name_crc, crc);
-- fd->name[rd.nsize]=0;
-- D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, rd.ino));
-+ ofs, je32_to_cpu(rd->name_crc), crc);
-+ D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, je32_to_cpu(rd->ino)));
- jffs2_free_full_dirent(fd);
- /* FIXME: Why do we believe totlen? */
-- DIRTY_SPACE(PAD(rd.totlen));
-- *ofs += PAD(rd.totlen);
-+ /* We believe totlen because the CRC on the node _header_ was OK, just the name failed. */
-+ DIRTY_SPACE(PAD(je32_to_cpu(rd->totlen)));
- return 0;
- }
- raw = jffs2_alloc_raw_node_ref();
-@@ -674,15 +771,15 @@
- printk(KERN_NOTICE "jffs2_scan_dirent_node(): allocation of node reference failed\n");
- return -ENOMEM;
- }
-- ic = jffs2_scan_make_ino_cache(c, rd.pino);
-+ ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(rd->pino));
- if (!ic) {
- jffs2_free_full_dirent(fd);
- jffs2_free_raw_node_ref(raw);
- return -ENOMEM;
- }
-
-- raw->totlen = PAD(rd.totlen);
-- raw->flash_offset = *ofs;
-+ raw->__totlen = PAD(je32_to_cpu(rd->totlen));
-+ raw->flash_offset = ofs | REF_PRISTINE;
- raw->next_phys = NULL;
- raw->next_in_ino = ic->nodes;
- ic->nodes = raw;
-@@ -692,24 +789,15 @@
- jeb->last_node->next_phys = raw;
- jeb->last_node = raw;
-
-- if (rd.nodetype & JFFS2_NODE_ACCURATE) {
- fd->raw = raw;
- fd->next = NULL;
-- fd->version = rd.version;
-- fd->ino = rd.ino;
-- fd->name[rd.nsize]=0;
-- fd->nhash = full_name_hash(fd->name, rd.nsize);
-- fd->type = rd.type;
--
-- USED_SPACE(PAD(rd.totlen));
-- jffs2_add_fd_to_list(c, fd, &ic->scan->dents);
-- } else {
-- raw->flash_offset |= 1;
-- jffs2_free_full_dirent(fd);
-+ fd->version = je32_to_cpu(rd->version);
-+ fd->ino = je32_to_cpu(rd->ino);
-+ fd->nhash = full_name_hash(fd->name, rd->nsize);
-+ fd->type = rd->type;
-+ USED_SPACE(PAD(je32_to_cpu(rd->totlen)));
-+ jffs2_add_fd_to_list(c, fd, &ic->scan_dents);
-
-- DIRTY_SPACE(PAD(rd.totlen));
-- }
-- *ofs += PAD(rd.totlen);
- return 0;
- }
-
-@@ -731,26 +819,90 @@
- struct list_head *n = head->next;
-
- list_del(head);
-- while(count--)
-+ while(count--) {
- n = n->next;
-+ }
- list_add(head, n);
- }
-
--static void jffs2_rotate_lists(struct jffs2_sb_info *c)
-+void jffs2_rotate_lists(struct jffs2_sb_info *c)
- {
- uint32_t x;
-+ uint32_t rotateby;
-
- x = count_list(&c->clean_list);
-- if (x)
-- rotate_list((&c->clean_list), pseudo_random % x);
-+ if (x) {
-+ rotateby = pseudo_random % x;
-+ D1(printk(KERN_DEBUG "Rotating clean_list by %d\n", rotateby));
-+
-+ rotate_list((&c->clean_list), rotateby);
-+
-+ D1(printk(KERN_DEBUG "Erase block at front of clean_list is at %08x\n",
-+ list_entry(c->clean_list.next, struct jffs2_eraseblock, list)->offset));
-+ } else {
-+ D1(printk(KERN_DEBUG "Not rotating empty clean_list\n"));
-+ }
-+
-+ x = count_list(&c->very_dirty_list);
-+ if (x) {
-+ rotateby = pseudo_random % x;
-+ D1(printk(KERN_DEBUG "Rotating very_dirty_list by %d\n", rotateby));
-+
-+ rotate_list((&c->very_dirty_list), rotateby);
-+
-+ D1(printk(KERN_DEBUG "Erase block at front of very_dirty_list is at %08x\n",
-+ list_entry(c->very_dirty_list.next, struct jffs2_eraseblock, list)->offset));
-+ } else {
-+ D1(printk(KERN_DEBUG "Not rotating empty very_dirty_list\n"));
-+ }
-
- x = count_list(&c->dirty_list);
-- if (x)
-- rotate_list((&c->dirty_list), pseudo_random % x);
-+ if (x) {
-+ rotateby = pseudo_random % x;
-+ D1(printk(KERN_DEBUG "Rotating dirty_list by %d\n", rotateby));
-+
-+ rotate_list((&c->dirty_list), rotateby);
-+
-+ D1(printk(KERN_DEBUG "Erase block at front of dirty_list is at %08x\n",
-+ list_entry(c->dirty_list.next, struct jffs2_eraseblock, list)->offset));
-+ } else {
-+ D1(printk(KERN_DEBUG "Not rotating empty dirty_list\n"));
-+ }
-+
-+ x = count_list(&c->erasable_list);
-+ if (x) {
-+ rotateby = pseudo_random % x;
-+ D1(printk(KERN_DEBUG "Rotating erasable_list by %d\n", rotateby));
-
-- if (c->nr_erasing_blocks)
-- rotate_list((&c->erase_pending_list), pseudo_random % c->nr_erasing_blocks);
-+ rotate_list((&c->erasable_list), rotateby);
-
-- if (c->nr_free_blocks) /* Not that it should ever be zero */
-- rotate_list((&c->free_list), pseudo_random % c->nr_free_blocks);
-+ D1(printk(KERN_DEBUG "Erase block at front of erasable_list is at %08x\n",
-+ list_entry(c->erasable_list.next, struct jffs2_eraseblock, list)->offset));
-+ } else {
-+ D1(printk(KERN_DEBUG "Not rotating empty erasable_list\n"));
-+ }
-+
-+ if (c->nr_erasing_blocks) {
-+ rotateby = pseudo_random % c->nr_erasing_blocks;
-+ D1(printk(KERN_DEBUG "Rotating erase_pending_list by %d\n", rotateby));
-+
-+ rotate_list((&c->erase_pending_list), rotateby);
-+
-+ D1(printk(KERN_DEBUG "Erase block at front of erase_pending_list is at %08x\n",
-+ list_entry(c->erase_pending_list.next, struct jffs2_eraseblock, list)->offset));
-+ } else {
-+ D1(printk(KERN_DEBUG "Not rotating empty erase_pending_list\n"));
-+ }
-+
-+ if (c->nr_free_blocks) {
-+ rotateby = pseudo_random % c->nr_free_blocks;
-+ D1(printk(KERN_DEBUG "Rotating free_list by %d\n", rotateby));
-+
-+ rotate_list((&c->free_list), rotateby);
-+
-+ D1(printk(KERN_DEBUG "Erase block at front of free_list is at %08x\n",
-+ list_entry(c->free_list.next, struct jffs2_eraseblock, list)->offset));
-+ } else {
-+ D1(printk(KERN_DEBUG "Not rotating empty free_list\n"));
-+ }
- }
-diff -Nurb linux-mips-2.4.27/fs/jffs2/super-v24.c linux/fs/jffs2/super-v24.c
---- linux-mips-2.4.27/fs/jffs2/super-v24.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/jffs2/super-v24.c 2004-11-19 10:25:12.126165288 +0100
-@@ -0,0 +1,167 @@
-+/*
-+ * JFFS2 -- Journalling Flash File System, Version 2.
-+ *
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
-+ *
-+ * Created by David Woodhouse <dwmw2@redhat.com>
-+ *
-+ * For licensing information, see the file 'LICENCE' in this directory.
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/version.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/list.h>
-+#include <linux/fs.h>
-+#include <linux/jffs2.h>
-+#include <linux/pagemap.h>
-+#include <linux/mtd/mtd.h>
-+#include "nodelist.h"
-+
-+#ifndef MTD_BLOCK_MAJOR
-+#define MTD_BLOCK_MAJOR 31
-+#endif
-+
-+static void jffs2_put_super (struct super_block *);
-+
-+static struct super_operations jffs2_super_operations =
-+{
-+ .read_inode = jffs2_read_inode,
-+ .put_super = jffs2_put_super,
-+ .write_super = jffs2_write_super,
-+ .statfs = jffs2_statfs,
-+ .remount_fs = jffs2_remount_fs,
-+ .clear_inode = jffs2_clear_inode,
-+ .dirty_inode = jffs2_dirty_inode,
-+};
-+
-+
-+static struct super_block *jffs2_read_super(struct super_block *sb, void *data, int silent)
-+{
-+ struct jffs2_sb_info *c;
-+ int ret;
-+
-+ D1(printk(KERN_DEBUG "jffs2: read_super for device %s\n", kdevname(sb->s_dev)));
-+
-+ if (major(sb->s_dev) != MTD_BLOCK_MAJOR) {
-+ if (!silent)
-+ printk(KERN_DEBUG "jffs2: attempt to mount non-MTD device %s\n", kdevname(sb->s_dev));
-+ return NULL;
-+ }
-+
-+ c = JFFS2_SB_INFO(sb);
-+ memset(c, 0, sizeof(*c));
-+
-+ sb->s_op = &jffs2_super_operations;
-+
-+ c->mtd = get_mtd_device(NULL, minor(sb->s_dev));
-+ if (!c->mtd) {
-+ D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", minor(sb->s_dev)));
-+ return NULL;
-+ }
-+
-+ ret = jffs2_do_fill_super(sb, data, silent);
-+ if (ret) {
-+ put_mtd_device(c->mtd);
-+ return NULL;
-+ }
-+
-+ return sb;
-+}
-+
-+static void jffs2_put_super (struct super_block *sb)
-+{
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-+
-+ D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n"));
-+
-+
-+ if (!(sb->s_flags & MS_RDONLY))
-+ jffs2_stop_garbage_collect_thread(c);
-+ down(&c->alloc_sem);
-+ jffs2_flush_wbuf_pad(c);
-+ up(&c->alloc_sem);
-+ jffs2_free_ino_caches(c);
-+ jffs2_free_raw_node_refs(c);
-+ kfree(c->blocks);
-+ jffs2_nand_flash_cleanup(c);
-+ kfree(c->inocache_list);
-+ if (c->mtd->sync)
-+ c->mtd->sync(c->mtd);
-+ put_mtd_device(c->mtd);
-+
-+ D1(printk(KERN_DEBUG "jffs2_put_super returning\n"));
-+}
-+
-+static DECLARE_FSTYPE_DEV(jffs2_fs_type, "jffs2", jffs2_read_super);
-+
-+static int __init init_jffs2_fs(void)
-+{
-+ int ret;
-+
-+ printk(KERN_INFO "JFFS2 version 2.2."
-+#ifdef CONFIG_FS_JFFS2_NAND
-+ " (NAND)"
-+#endif
-+ " (C) 2001-2003 Red Hat, Inc.\n");
-+
-+#ifdef JFFS2_OUT_OF_KERNEL
-+ /* sanity checks. Could we do these at compile time? */
-+ if (sizeof(struct jffs2_sb_info) > sizeof (((struct super_block *)NULL)->u)) {
-+ printk(KERN_ERR "JFFS2 error: struct jffs2_sb_info (%d bytes) doesn't fit in the super_block union (%d bytes)\n",
-+ sizeof(struct jffs2_sb_info), sizeof (((struct super_block *)NULL)->u));
-+ return -EIO;
-+ }
-+
-+ if (sizeof(struct jffs2_inode_info) > sizeof (((struct inode *)NULL)->u)) {
-+ printk(KERN_ERR "JFFS2 error: struct jffs2_inode_info (%d bytes) doesn't fit in the inode union (%d bytes)\n",
-+ sizeof(struct jffs2_inode_info), sizeof (((struct inode *)NULL)->u));
-+ return -EIO;
-+ }
-+#endif
-+ ret = jffs2_zlib_init();
-+ if (ret) {
-+ printk(KERN_ERR "JFFS2 error: Failed to initialise zlib workspaces\n");
-+ goto out;
-+ }
-+ ret = jffs2_create_slab_caches();
-+ if (ret) {
-+ printk(KERN_ERR "JFFS2 error: Failed to initialise slab caches\n");
-+ goto out_zlib;
-+ }
-+ ret = register_filesystem(&jffs2_fs_type);
-+ if (ret) {
-+ printk(KERN_ERR "JFFS2 error: Failed to register filesystem\n");
-+ goto out_slab;
-+ }
-+ return 0;
-+
-+ out_slab:
-+ jffs2_destroy_slab_caches();
-+ out_zlib:
-+ jffs2_zlib_exit();
-+ out:
-+
-+ return ret;
-+}
-+
-+static void __exit exit_jffs2_fs(void)
-+{
-+ jffs2_destroy_slab_caches();
-+ jffs2_zlib_exit();
-+ unregister_filesystem(&jffs2_fs_type);
-+}
-+
-+module_init(init_jffs2_fs);
-+module_exit(exit_jffs2_fs);
-+
-+MODULE_DESCRIPTION("The Journalling Flash File System, v2");
-+MODULE_AUTHOR("Red Hat, Inc.");
-+MODULE_LICENSE("GPL"); // Actually dual-licensed, but it doesn't matter for
-+ // the sake of this tag. It's Free Software.
-diff -Nurb linux-mips-2.4.27/fs/jffs2/super.c linux/fs/jffs2/super.c
---- linux-mips-2.4.27/fs/jffs2/super.c 2003-01-11 18:53:17.000000000 +0100
-+++ linux/fs/jffs2/super.c 2004-11-19 10:25:12.127165136 +0100
-@@ -1,291 +1,257 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/config.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
--#include <linux/version.h>
- #include <linux/slab.h>
- #include <linux/init.h>
- #include <linux/list.h>
- #include <linux/fs.h>
-+#include <linux/mount.h>
- #include <linux/jffs2.h>
- #include <linux/pagemap.h>
- #include <linux/mtd/mtd.h>
--#include <linux/interrupt.h>
-+#include <linux/ctype.h>
-+#include <linux/namei.h>
- #include "nodelist.h"
-
--#ifndef MTD_BLOCK_MAJOR
--#define MTD_BLOCK_MAJOR 31
--#endif
-+static void jffs2_put_super(struct super_block *);
-+
-+static kmem_cache_t *jffs2_inode_cachep;
-+
-+static struct inode *jffs2_alloc_inode(struct super_block *sb)
-+{
-+ struct jffs2_inode_info *ei;
-+ ei = (struct jffs2_inode_info *)kmem_cache_alloc(jffs2_inode_cachep, SLAB_KERNEL);
-+ if (!ei)
-+ return NULL;
-+ return &ei->vfs_inode;
-+}
-+
-+static void jffs2_destroy_inode(struct inode *inode)
-+{
-+ kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode));
-+}
-+
-+static void jffs2_i_init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
-+{
-+ struct jffs2_inode_info *ei = (struct jffs2_inode_info *) foo;
-
--extern void jffs2_read_inode (struct inode *);
--void jffs2_put_super (struct super_block *);
--void jffs2_write_super (struct super_block *);
--static int jffs2_statfs (struct super_block *, struct statfs *);
--int jffs2_remount_fs (struct super_block *, int *, char *);
--extern void jffs2_clear_inode (struct inode *);
-+ if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
-+ SLAB_CTOR_CONSTRUCTOR) {
-+ init_MUTEX_LOCKED(&ei->sem);
-+ inode_init_once(&ei->vfs_inode);
-+ }
-+}
-
- static struct super_operations jffs2_super_operations =
- {
-- read_inode: jffs2_read_inode,
--// delete_inode: jffs2_delete_inode,
-- put_super: jffs2_put_super,
-- write_super: jffs2_write_super,
-- statfs: jffs2_statfs,
-- remount_fs: jffs2_remount_fs,
-- clear_inode: jffs2_clear_inode
-+ .alloc_inode = jffs2_alloc_inode,
-+ .destroy_inode =jffs2_destroy_inode,
-+ .read_inode = jffs2_read_inode,
-+ .put_super = jffs2_put_super,
-+ .write_super = jffs2_write_super,
-+ .statfs = jffs2_statfs,
-+ .remount_fs = jffs2_remount_fs,
-+ .clear_inode = jffs2_clear_inode,
-+ .dirty_inode = jffs2_dirty_inode,
- };
-
--static int jffs2_statfs(struct super_block *sb, struct statfs *buf)
-+static int jffs2_sb_compare(struct super_block *sb, void *data)
- {
-+ struct jffs2_sb_info *p = data;
- struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-- unsigned long avail;
-
-- buf->f_type = JFFS2_SUPER_MAGIC;
-- buf->f_bsize = 1 << PAGE_SHIFT;
-- buf->f_blocks = c->flash_size >> PAGE_SHIFT;
-- buf->f_files = 0;
-- buf->f_ffree = 0;
-- buf->f_namelen = JFFS2_MAX_NAME_LEN;
--
-- spin_lock_bh(&c->erase_completion_lock);
--
-- avail = c->dirty_size + c->free_size;
-- if (avail > c->sector_size * JFFS2_RESERVED_BLOCKS_WRITE)
-- avail -= c->sector_size * JFFS2_RESERVED_BLOCKS_WRITE;
-- else
-- avail = 0;
--
-- buf->f_bavail = buf->f_bfree = avail >> PAGE_SHIFT;
--
--#if CONFIG_JFFS2_FS_DEBUG > 0
-- printk(KERN_DEBUG "STATFS:\n");
-- printk(KERN_DEBUG "flash_size: %08x\n", c->flash_size);
-- printk(KERN_DEBUG "used_size: %08x\n", c->used_size);
-- printk(KERN_DEBUG "dirty_size: %08x\n", c->dirty_size);
-- printk(KERN_DEBUG "free_size: %08x\n", c->free_size);
-- printk(KERN_DEBUG "erasing_size: %08x\n", c->erasing_size);
-- printk(KERN_DEBUG "bad_size: %08x\n", c->bad_size);
-- printk(KERN_DEBUG "sector_size: %08x\n", c->sector_size);
--
-- if (c->nextblock) {
-- printk(KERN_DEBUG "nextblock: 0x%08x\n", c->nextblock->offset);
-- } else {
-- printk(KERN_DEBUG "nextblock: NULL\n");
-- }
-- if (c->gcblock) {
-- printk(KERN_DEBUG "gcblock: 0x%08x\n", c->gcblock->offset);
-+ /* The superblocks are considered to be equivalent if the underlying MTD
-+ device is the same one */
-+ if (c->mtd == p->mtd) {
-+ D1(printk(KERN_DEBUG "jffs2_sb_compare: match on device %d (\"%s\")\n", p->mtd->index, p->mtd->name));
-+ return 1;
- } else {
-- printk(KERN_DEBUG "gcblock: NULL\n");
-+ D1(printk(KERN_DEBUG "jffs2_sb_compare: No match, device %d (\"%s\"), device %d (\"%s\")\n",
-+ c->mtd->index, c->mtd->name, p->mtd->index, p->mtd->name));
-+ return 0;
- }
-- if (list_empty(&c->clean_list)) {
-- printk(KERN_DEBUG "clean_list: empty\n");
-- } else {
-- struct list_head *this;
-+}
-
-- list_for_each(this, &c->clean_list) {
-- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-- printk(KERN_DEBUG "clean_list: %08x\n", jeb->offset);
-- }
-- }
-- if (list_empty(&c->dirty_list)) {
-- printk(KERN_DEBUG "dirty_list: empty\n");
-- } else {
-- struct list_head *this;
-+static int jffs2_sb_set(struct super_block *sb, void *data)
-+{
-+ struct jffs2_sb_info *p = data;
-
-- list_for_each(this, &c->dirty_list) {
-- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-- printk(KERN_DEBUG "dirty_list: %08x\n", jeb->offset);
-- }
-- }
-- if (list_empty(&c->erasing_list)) {
-- printk(KERN_DEBUG "erasing_list: empty\n");
-- } else {
-- struct list_head *this;
-+ /* For persistence of NFS exports etc. we use the same s_dev
-+ each time we mount the device, don't just use an anonymous
-+ device */
-+ sb->s_fs_info = p;
-+ p->os_priv = sb;
-+ sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, p->mtd->index);
-
-- list_for_each(this, &c->erasing_list) {
-- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-- printk(KERN_DEBUG "erasing_list: %08x\n", jeb->offset);
-- }
-- }
-- if (list_empty(&c->erase_pending_list)) {
-- printk(KERN_DEBUG "erase_pending_list: empty\n");
-- } else {
-- struct list_head *this;
-+ return 0;
-+}
-
-- list_for_each(this, &c->erase_pending_list) {
-- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-- printk(KERN_DEBUG "erase_pending_list: %08x\n", jeb->offset);
-- }
-- }
-- if (list_empty(&c->free_list)) {
-- printk(KERN_DEBUG "free_list: empty\n");
-- } else {
-- struct list_head *this;
-+static struct super_block *jffs2_get_sb_mtd(struct file_system_type *fs_type,
-+ int flags, const char *dev_name,
-+ void *data, struct mtd_info *mtd)
-+{
-+ struct super_block *sb;
-+ struct jffs2_sb_info *c;
-+ int ret;
-
-- list_for_each(this, &c->free_list) {
-- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-- printk(KERN_DEBUG "free_list: %08x\n", jeb->offset);
-- }
-- }
-- if (list_empty(&c->bad_list)) {
-- printk(KERN_DEBUG "bad_list: empty\n");
-- } else {
-- struct list_head *this;
-+ c = kmalloc(sizeof(*c), GFP_KERNEL);
-+ if (!c)
-+ return ERR_PTR(-ENOMEM);
-+ memset(c, 0, sizeof(*c));
-+ c->mtd = mtd;
-
-- list_for_each(this, &c->bad_list) {
-- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-- printk(KERN_DEBUG "bad_list: %08x\n", jeb->offset);
-- }
-- }
-- if (list_empty(&c->bad_used_list)) {
-- printk(KERN_DEBUG "bad_used_list: empty\n");
-- } else {
-- struct list_head *this;
-+ sb = sget(fs_type, jffs2_sb_compare, jffs2_sb_set, c);
-+
-+ if (IS_ERR(sb))
-+ goto out_put;
-
-- list_for_each(this, &c->bad_used_list) {
-- struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-- printk(KERN_DEBUG "bad_used_list: %08x\n", jeb->offset);
-+ if (sb->s_root) {
-+ /* New mountpoint for JFFS2 which is already mounted */
-+ D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): Device %d (\"%s\") is already mounted\n",
-+ mtd->index, mtd->name));
-+ goto out_put;
- }
-+
-+ D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): New superblock for device %d (\"%s\")\n",
-+ mtd->index, mtd->name));
-+
-+ sb->s_op = &jffs2_super_operations;
-+
-+ ret = jffs2_do_fill_super(sb, data, (flags&MS_VERBOSE)?1:0);
-+
-+ if (ret) {
-+ /* Failure case... */
-+ up_write(&sb->s_umount);
-+ deactivate_super(sb);
-+ return ERR_PTR(ret);
- }
--#endif /* CONFIG_JFFS2_FS_DEBUG */
-
-- spin_unlock_bh(&c->erase_completion_lock);
-+ sb->s_flags |= MS_ACTIVE;
-+ return sb;
-
-+ out_put:
-+ kfree(c);
-+ put_mtd_device(mtd);
-
-- return 0;
-+ return sb;
- }
-
--static struct super_block *jffs2_read_super(struct super_block *sb, void *data, int silent)
-+static struct super_block *jffs2_get_sb_mtdnr(struct file_system_type *fs_type,
-+ int flags, const char *dev_name,
-+ void *data, int mtdnr)
- {
-- struct jffs2_sb_info *c;
-- struct inode *root_i;
-- int i;
--
-- D1(printk(KERN_DEBUG "jffs2: read_super for device %s\n", kdevname(sb->s_dev)));
-+ struct mtd_info *mtd;
-
-- if (MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR) {
-- if (!silent)
-- printk(KERN_DEBUG "jffs2: attempt to mount non-MTD device %s\n", kdevname(sb->s_dev));
-- return NULL;
-+ mtd = get_mtd_device(NULL, mtdnr);
-+ if (!mtd) {
-+ D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", mtdnr));
-+ return ERR_PTR(-EINVAL);
- }
-
-- c = JFFS2_SB_INFO(sb);
-- memset(c, 0, sizeof(*c));
-+ return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd);
-+}
-
-- c->mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
-- if (!c->mtd) {
-- D1(printk(KERN_DEBUG "jffs2: MTD device #%u doesn't appear to exist\n", MINOR(sb->s_dev)));
-- return NULL;
-+static struct super_block *jffs2_get_sb(struct file_system_type *fs_type,
-+ int flags, const char *dev_name,
-+ void *data)
-+{
-+ int err;
-+ struct nameidata nd;
-+ int mtdnr;
-+
-+ if (!dev_name)
-+ return ERR_PTR(-EINVAL);
-+
-+ D1(printk(KERN_DEBUG "jffs2_get_sb(): dev_name \"%s\"\n", dev_name));
-+
-+ /* The preferred way of mounting in future; especially when
-+ CONFIG_BLK_DEV is implemented - we specify the underlying
-+ MTD device by number or by name, so that we don't require
-+ block device support to be present in the kernel. */
-+
-+ /* FIXME: How to do the root fs this way? */
-+
-+ if (dev_name[0] == 'm' && dev_name[1] == 't' && dev_name[2] == 'd') {
-+ /* Probably mounting without the blkdev crap */
-+ if (dev_name[3] == ':') {
-+ struct mtd_info *mtd;
-+
-+ /* Mount by MTD device name */
-+ D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd:%%s, name \"%s\"\n", dev_name+4));
-+ for (mtdnr = 0; mtdnr < MAX_MTD_DEVICES; mtdnr++) {
-+ mtd = get_mtd_device(NULL, mtdnr);
-+ if (mtd) {
-+ if (!strcmp(mtd->name, dev_name+4))
-+ return jffs2_get_sb_mtd(fs_type, flags, dev_name, data, mtd);
-+ put_mtd_device(mtd);
- }
-- c->sector_size = c->mtd->erasesize;
-- c->free_size = c->flash_size = c->mtd->size;
-- c->nr_blocks = c->mtd->size / c->mtd->erasesize;
-- c->blocks = kmalloc(sizeof(struct jffs2_eraseblock) * c->nr_blocks, GFP_KERNEL);
-- if (!c->blocks)
-- goto out_mtd;
-- for (i=0; i<c->nr_blocks; i++) {
-- INIT_LIST_HEAD(&c->blocks[i].list);
-- c->blocks[i].offset = i * c->sector_size;
-- c->blocks[i].free_size = c->sector_size;
-- c->blocks[i].dirty_size = 0;
-- c->blocks[i].used_size = 0;
-- c->blocks[i].first_node = NULL;
-- c->blocks[i].last_node = NULL;
-- }
--
-- spin_lock_init(&c->nodelist_lock);
-- init_MUTEX(&c->alloc_sem);
-- init_waitqueue_head(&c->erase_wait);
-- spin_lock_init(&c->erase_completion_lock);
-- spin_lock_init(&c->inocache_lock);
--
-- INIT_LIST_HEAD(&c->clean_list);
-- INIT_LIST_HEAD(&c->dirty_list);
-- INIT_LIST_HEAD(&c->erasing_list);
-- INIT_LIST_HEAD(&c->erase_pending_list);
-- INIT_LIST_HEAD(&c->erase_complete_list);
-- INIT_LIST_HEAD(&c->free_list);
-- INIT_LIST_HEAD(&c->bad_list);
-- INIT_LIST_HEAD(&c->bad_used_list);
-- c->highest_ino = 1;
--
-- if (jffs2_build_filesystem(c)) {
-- D1(printk(KERN_DEBUG "build_fs failed\n"));
-- goto out_nodes;
- }
-+ printk(KERN_NOTICE "jffs2_get_sb(): MTD device with name \"%s\" not found.\n", dev_name+4);
-+ } else if (isdigit(dev_name[3])) {
-+ /* Mount by MTD device number name */
-+ char *endptr;
-
-- sb->s_op = &jffs2_super_operations;
-+ mtdnr = simple_strtoul(dev_name+3, &endptr, 0);
-+ if (!*endptr) {
-+ /* It was a valid number */
-+ D1(printk(KERN_DEBUG "jffs2_get_sb(): mtd%%d, mtdnr %d\n", mtdnr));
-+ return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr);
-+ }
-+ }
-+ }
-
-- D1(printk(KERN_DEBUG "jffs2_read_super(): Getting root inode\n"));
-- root_i = iget(sb, 1);
-- if (is_bad_inode(root_i)) {
-- D1(printk(KERN_WARNING "get root inode failed\n"));
-- goto out_nodes;
-+ /* Try the old way - the hack where we allowed users to mount
-+ /dev/mtdblock$(n) but didn't actually _use_ the blkdev */
-+
-+ err = path_lookup(dev_name, LOOKUP_FOLLOW, &nd);
-+
-+ D1(printk(KERN_DEBUG "jffs2_get_sb(): path_lookup() returned %d, inode %p\n",
-+ err, nd.dentry->d_inode));
-+
-+ if (err)
-+ return ERR_PTR(err);
-+
-+ err = -EINVAL;
-+
-+ if (!S_ISBLK(nd.dentry->d_inode->i_mode))
-+ goto out;
-+
-+ if (nd.mnt->mnt_flags & MNT_NODEV) {
-+ err = -EACCES;
-+ goto out;
- }
-
-- D1(printk(KERN_DEBUG "jffs2_read_super(): d_alloc_root()\n"));
-- sb->s_root = d_alloc_root(root_i);
-- if (!sb->s_root)
-- goto out_root_i;
-+ if (imajor(nd.dentry->d_inode) != MTD_BLOCK_MAJOR) {
-+ if (!(flags & MS_VERBOSE)) /* Yes I mean this. Strangely */
-+ printk(KERN_NOTICE "Attempt to mount non-MTD device \"%s\" as JFFS2\n",
-+ dev_name);
-+ goto out;
-+ }
-
--#if LINUX_VERSION_CODE >= 0x20403
-- sb->s_maxbytes = 0xFFFFFFFF;
--#endif
-- sb->s_blocksize = PAGE_CACHE_SIZE;
-- sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-- sb->s_magic = JFFS2_SUPER_MAGIC;
-- if (!(sb->s_flags & MS_RDONLY))
-- jffs2_start_garbage_collect_thread(c);
-- return sb;
-+ mtdnr = iminor(nd.dentry->d_inode);
-+ path_release(&nd);
-
-- out_root_i:
-- iput(root_i);
-- out_nodes:
-- jffs2_free_ino_caches(c);
-- jffs2_free_raw_node_refs(c);
-- kfree(c->blocks);
-- out_mtd:
-- put_mtd_device(c->mtd);
-- return NULL;
-+ return jffs2_get_sb_mtdnr(fs_type, flags, dev_name, data, mtdnr);
-+
-+out:
-+ path_release(&nd);
-+ return ERR_PTR(err);
- }
-
--void jffs2_put_super (struct super_block *sb)
-+static void jffs2_put_super (struct super_block *sb)
- {
- struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-
-@@ -293,74 +259,53 @@
-
- if (!(sb->s_flags & MS_RDONLY))
- jffs2_stop_garbage_collect_thread(c);
-+ down(&c->alloc_sem);
-+ jffs2_flush_wbuf_pad(c);
-+ up(&c->alloc_sem);
- jffs2_free_ino_caches(c);
- jffs2_free_raw_node_refs(c);
- kfree(c->blocks);
-+ jffs2_nand_flash_cleanup(c);
-+ kfree(c->inocache_list);
- if (c->mtd->sync)
- c->mtd->sync(c->mtd);
-- put_mtd_device(c->mtd);
-
- D1(printk(KERN_DEBUG "jffs2_put_super returning\n"));
- }
-
--int jffs2_remount_fs (struct super_block *sb, int *flags, char *data)
-+static void jffs2_kill_sb(struct super_block *sb)
- {
- struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
--
-- if (c->flags & JFFS2_SB_FLAG_RO && !(sb->s_flags & MS_RDONLY))
-- return -EROFS;
--
-- /* We stop if it was running, then restart if it needs to.
-- This also catches the case where it was stopped and this
-- is just a remount to restart it */
-- if (!(sb->s_flags & MS_RDONLY))
-- jffs2_stop_garbage_collect_thread(c);
--
-- if (!(*flags & MS_RDONLY))
-- jffs2_start_garbage_collect_thread(c);
--
-- sb->s_flags = (sb->s_flags & ~MS_RDONLY)|(*flags & MS_RDONLY);
--
-- return 0;
--}
--
--void jffs2_write_super (struct super_block *sb)
--{
-- struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
-- sb->s_dirt = 0;
--
-- if (sb->s_flags & MS_RDONLY)
-- return;
--
-- jffs2_garbage_collect_trigger(c);
-- jffs2_erase_pending_blocks(c);
-- jffs2_mark_erased_blocks(c);
-+ generic_shutdown_super(sb);
-+ put_mtd_device(c->mtd);
-+ kfree(c);
- }
-
--
--static DECLARE_FSTYPE_DEV(jffs2_fs_type, "jffs2", jffs2_read_super);
-+static struct file_system_type jffs2_fs_type = {
-+ .owner = THIS_MODULE,
-+ .name = "jffs2",
-+ .get_sb = jffs2_get_sb,
-+ .kill_sb = jffs2_kill_sb,
-+};
-
- static int __init init_jffs2_fs(void)
- {
- int ret;
-
-- printk(KERN_NOTICE "JFFS2 version 2.1. (C) 2001 Red Hat, Inc., designed by Axis Communications AB.\n");
--
--#ifdef JFFS2_OUT_OF_KERNEL
-- /* sanity checks. Could we do these at compile time? */
-- if (sizeof(struct jffs2_sb_info) > sizeof (((struct super_block *)NULL)->u)) {
-- printk(KERN_ERR "JFFS2 error: struct jffs2_sb_info (%d bytes) doesn't fit in the super_block union (%d bytes)\n",
-- sizeof(struct jffs2_sb_info), sizeof (((struct super_block *)NULL)->u));
-- return -EIO;
-- }
--
-- if (sizeof(struct jffs2_inode_info) > sizeof (((struct inode *)NULL)->u)) {
-- printk(KERN_ERR "JFFS2 error: struct jffs2_inode_info (%d bytes) doesn't fit in the inode union (%d bytes)\n",
-- sizeof(struct jffs2_inode_info), sizeof (((struct inode *)NULL)->u));
-- return -EIO;
-- }
-+ printk(KERN_INFO "JFFS2 version 2.2."
-+#ifdef CONFIG_FS_JFFS2_NAND
-+ " (NAND)"
- #endif
-+ " (C) 2001-2003 Red Hat, Inc.\n");
-
-+ jffs2_inode_cachep = kmem_cache_create("jffs2_i",
-+ sizeof(struct jffs2_inode_info),
-+ 0, SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT,
-+ jffs2_i_init_once, NULL);
-+ if (!jffs2_inode_cachep) {
-+ printk(KERN_ERR "JFFS2 error: Failed to initialise inode cache\n");
-+ return -ENOMEM;
-+ }
- ret = jffs2_zlib_init();
- if (ret) {
- printk(KERN_ERR "JFFS2 error: Failed to initialise zlib workspaces\n");
-@@ -388,9 +333,10 @@
-
- static void __exit exit_jffs2_fs(void)
- {
-+ unregister_filesystem(&jffs2_fs_type);
- jffs2_destroy_slab_caches();
- jffs2_zlib_exit();
-- unregister_filesystem(&jffs2_fs_type);
-+ kmem_cache_destroy(jffs2_inode_cachep);
- }
-
- module_init(init_jffs2_fs);
-diff -Nurb linux-mips-2.4.27/fs/jffs2/symlink.c linux/fs/jffs2/symlink.c
---- linux-mips-2.4.27/fs/jffs2/symlink.c 2002-06-27 00:36:20.000000000 +0200
-+++ linux/fs/jffs2/symlink.c 2004-11-19 10:25:12.129164832 +0100
-@@ -3,35 +3,11 @@
- *
- * Copyright (C) 2001, 2002 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
-@@ -39,7 +15,6 @@
- #include <linux/kernel.h>
- #include <linux/slab.h>
- #include <linux/fs.h>
--#include <linux/jffs2.h>
- #include "nodelist.h"
-
- int jffs2_readlink(struct dentry *dentry, char *buffer, int buflen);
-@@ -47,45 +22,17 @@
-
- struct inode_operations jffs2_symlink_inode_operations =
- {
-- readlink: jffs2_readlink,
-- follow_link: jffs2_follow_link,
-- setattr: jffs2_setattr
-+ .readlink = jffs2_readlink,
-+ .follow_link = jffs2_follow_link,
-+ .setattr = jffs2_setattr
- };
-
--static char *jffs2_getlink(struct dentry *dentry)
--{
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode);
-- char *buf;
-- int ret;
--
-- down(&f->sem);
-- if (!f->metadata) {
-- up(&f->sem);
-- printk(KERN_NOTICE "No metadata for symlink inode #%lu\n", dentry->d_inode->i_ino);
-- return ERR_PTR(-EINVAL);
-- }
-- buf = kmalloc(f->metadata->size+1, GFP_USER);
-- if (!buf) {
-- up(&f->sem);
-- return ERR_PTR(-ENOMEM);
-- }
-- buf[f->metadata->size]=0;
--
-- ret = jffs2_read_dnode(JFFS2_SB_INFO(dentry->d_inode->i_sb), f->metadata, buf, 0, f->metadata->size);
-- up(&f->sem);
-- if (ret) {
-- kfree(buf);
-- return ERR_PTR(ret);
-- }
-- return buf;
--
--}
- int jffs2_readlink(struct dentry *dentry, char *buffer, int buflen)
- {
- unsigned char *kbuf;
- int ret;
-
-- kbuf = jffs2_getlink(dentry);
-+ kbuf = jffs2_getlink(JFFS2_SB_INFO(dentry->d_inode->i_sb), JFFS2_INODE_INFO(dentry->d_inode));
- if (IS_ERR(kbuf))
- return PTR_ERR(kbuf);
-
-@@ -99,7 +46,7 @@
- unsigned char *buf;
- int ret;
-
-- buf = jffs2_getlink(dentry);
-+ buf = jffs2_getlink(JFFS2_SB_INFO(dentry->d_inode->i_sb), JFFS2_INODE_INFO(dentry->d_inode));
-
- if (IS_ERR(buf))
- return PTR_ERR(buf);
-diff -Nurb linux-mips-2.4.27/fs/jffs2/wbuf.c linux/fs/jffs2/wbuf.c
---- linux-mips-2.4.27/fs/jffs2/wbuf.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/jffs2/wbuf.c 2004-11-19 10:25:12.131164528 +0100
-@@ -0,0 +1,1156 @@
-+/*
-+ * JFFS2 -- Journalling Flash File System, Version 2.
-+ *
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
-+ *
-+ * Created by David Woodhouse <dwmw2@redhat.com>
-+ *
-+ * For licensing information, see the file 'LICENCE' in this directory.
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/crc32.h>
-+#include <linux/mtd/nand.h>
-+#include "nodelist.h"
-+
-+/* For testing write failures */
-+#undef BREAKME
-+#undef BREAKMEHEADER
-+
-+#ifdef BREAKME
-+static unsigned char *brokenbuf;
-+#endif
-+
-+/* max. erase failures before we mark a block bad */
-+#define MAX_ERASE_FAILURES 5
-+
-+/* two seconds timeout for timed wbuf-flushing */
-+#define WBUF_FLUSH_TIMEOUT 2 * HZ
-+
-+struct jffs2_inodirty {
-+ uint32_t ino;
-+ struct jffs2_inodirty *next;
-+};
-+
-+static struct jffs2_inodirty inodirty_nomem;
-+
-+static int jffs2_wbuf_pending_for_ino(struct jffs2_sb_info *c, uint32_t ino)
-+{
-+ struct jffs2_inodirty *this = c->wbuf_inodes;
-+
-+ /* If a malloc failed, consider _everything_ dirty */
-+ if (this == &inodirty_nomem)
-+ return 1;
-+
-+ /* If ino == 0, _any_ non-GC writes mean 'yes' */
-+ if (this && !ino)
-+ return 1;
-+
-+ /* Look to see if the inode in question is pending in the wbuf */
-+ while (this) {
-+ if (this->ino == ino)
-+ return 1;
-+ this = this->next;
-+ }
-+ return 0;
-+}
-+
-+static void jffs2_clear_wbuf_ino_list(struct jffs2_sb_info *c)
-+{
-+ struct jffs2_inodirty *this;
-+
-+ this = c->wbuf_inodes;
-+
-+ if (this != &inodirty_nomem) {
-+ while (this) {
-+ struct jffs2_inodirty *next = this->next;
-+ kfree(this);
-+ this = next;
-+ }
-+ }
-+ c->wbuf_inodes = NULL;
-+}
-+
-+static void jffs2_wbuf_dirties_inode(struct jffs2_sb_info *c, uint32_t ino)
-+{
-+ struct jffs2_inodirty *new;
-+
-+ /* Mark the superblock dirty so that kupdated will flush... */
-+ OFNI_BS_2SFFJ(c)->s_dirt = 1;
-+
-+ if (jffs2_wbuf_pending_for_ino(c, ino))
-+ return;
-+
-+ new = kmalloc(sizeof(*new), GFP_KERNEL);
-+ if (!new) {
-+ D1(printk(KERN_DEBUG "No memory to allocate inodirty. Fallback to all considered dirty\n"));
-+ jffs2_clear_wbuf_ino_list(c);
-+ c->wbuf_inodes = &inodirty_nomem;
-+ return;
-+ }
-+ new->ino = ino;
-+ new->next = c->wbuf_inodes;
-+ c->wbuf_inodes = new;
-+ return;
-+}
-+
-+static inline void jffs2_refile_wbuf_blocks(struct jffs2_sb_info *c)
-+{
-+ struct list_head *this, *next;
-+ static int n;
-+
-+ if (list_empty(&c->erasable_pending_wbuf_list))
-+ return;
-+
-+ list_for_each_safe(this, next, &c->erasable_pending_wbuf_list) {
-+ struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
-+
-+ D1(printk(KERN_DEBUG "Removing eraseblock at 0x%08x from erasable_pending_wbuf_list...\n", jeb->offset));
-+ list_del(this);
-+ if ((jiffies + (n++)) & 127) {
-+ /* Most of the time, we just erase it immediately. Otherwise we
-+ spend ages scanning it on mount, etc. */
-+ D1(printk(KERN_DEBUG "...and adding to erase_pending_list\n"));
-+ list_add_tail(&jeb->list, &c->erase_pending_list);
-+ c->nr_erasing_blocks++;
-+ jffs2_erase_pending_trigger(c);
-+ } else {
-+ /* Sometimes, however, we leave it elsewhere so it doesn't get
-+ immediately reused, and we spread the load a bit. */
-+ D1(printk(KERN_DEBUG "...and adding to erasable_list\n"));
-+ list_add_tail(&jeb->list, &c->erasable_list);
-+ }
-+ }
-+}
-+
-+/* Recover from failure to write wbuf. Recover the nodes up to the
-+ * wbuf, not the one which we were starting to try to write. */
-+
-+static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
-+{
-+ struct jffs2_eraseblock *jeb, *new_jeb;
-+ struct jffs2_raw_node_ref **first_raw, **raw;
-+ size_t retlen;
-+ int ret;
-+ unsigned char *buf;
-+ uint32_t start, end, ofs, len;
-+
-+ spin_lock(&c->erase_completion_lock);
-+
-+ jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
-+
-+ D1(printk("About to refile bad block at %08x\n", jeb->offset));
-+
-+ D2(jffs2_dump_block_lists(c));
-+ /* File the existing block on the bad_used_list.... */
-+ if (c->nextblock == jeb)
-+ c->nextblock = NULL;
-+ else /* Not sure this should ever happen... need more coffee */
-+ list_del(&jeb->list);
-+ if (jeb->first_node) {
-+ D1(printk("Refiling block at %08x to bad_used_list\n", jeb->offset));
-+ list_add(&jeb->list, &c->bad_used_list);
-+ } else {
-+ BUG();
-+ /* It has to have had some nodes or we couldn't be here */
-+ D1(printk("Refiling block at %08x to erase_pending_list\n", jeb->offset));
-+ list_add(&jeb->list, &c->erase_pending_list);
-+ c->nr_erasing_blocks++;
-+ jffs2_erase_pending_trigger(c);
-+ }
-+ D2(jffs2_dump_block_lists(c));
-+
-+ /* Adjust its size counts accordingly */
-+ c->wasted_size += jeb->free_size;
-+ c->free_size -= jeb->free_size;
-+ jeb->wasted_size += jeb->free_size;
-+ jeb->free_size = 0;
-+
-+ ACCT_SANITY_CHECK(c,jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+
-+ /* Find the first node to be recovered, by skipping over every
-+ node which ends before the wbuf starts, or which is obsolete. */
-+ first_raw = &jeb->first_node;
-+ while (*first_raw &&
-+ (ref_obsolete(*first_raw) ||
-+ (ref_offset(*first_raw)+ref_totlen(c, jeb, *first_raw)) < c->wbuf_ofs)) {
-+ D1(printk(KERN_DEBUG "Skipping node at 0x%08x(%d)-0x%08x which is either before 0x%08x or obsolete\n",
-+ ref_offset(*first_raw), ref_flags(*first_raw),
-+ (ref_offset(*first_raw) + ref_totlen(c, jeb, *first_raw)),
-+ c->wbuf_ofs));
-+ first_raw = &(*first_raw)->next_phys;
-+ }
-+
-+ if (!*first_raw) {
-+ /* All nodes were obsolete. Nothing to recover. */
-+ D1(printk(KERN_DEBUG "No non-obsolete nodes to be recovered. Just filing block bad\n"));
-+ spin_unlock(&c->erase_completion_lock);
-+ return;
-+ }
-+
-+ start = ref_offset(*first_raw);
-+ end = ref_offset(*first_raw) + ref_totlen(c, jeb, *first_raw);
-+
-+ /* Find the last node to be recovered */
-+ raw = first_raw;
-+ while ((*raw)) {
-+ if (!ref_obsolete(*raw))
-+ end = ref_offset(*raw) + ref_totlen(c, jeb, *raw);
-+
-+ raw = &(*raw)->next_phys;
-+ }
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ D1(printk(KERN_DEBUG "wbuf recover %08x-%08x\n", start, end));
-+
-+ buf = NULL;
-+ if (start < c->wbuf_ofs) {
-+ /* First affected node was already partially written.
-+ * Attempt to reread the old data into our buffer. */
-+
-+ buf = kmalloc(end - start, GFP_KERNEL);
-+ if (!buf) {
-+ printk(KERN_CRIT "Malloc failure in wbuf recovery. Data loss ensues.\n");
-+
-+ goto read_failed;
-+ }
-+
-+ /* Do the read... */
-+ ret = c->mtd->read_ecc(c->mtd, start, c->wbuf_ofs - start, &retlen, buf, NULL, c->oobinfo);
-+ if (ret == -EIO && retlen == c->wbuf_ofs - start) {
-+ /* ECC recovered */
-+ ret = 0;
-+ }
-+ if (ret || retlen != c->wbuf_ofs - start) {
-+ printk(KERN_CRIT "Old data are already lost in wbuf recovery. Data loss ensues.\n");
-+
-+ kfree(buf);
-+ buf = NULL;
-+ read_failed:
-+ first_raw = &(*first_raw)->next_phys;
-+ /* If this was the only node to be recovered, give up */
-+ if (!(*first_raw))
-+ return;
-+
-+ /* It wasn't. Go on and try to recover nodes complete in the wbuf */
-+ start = ref_offset(*first_raw);
-+ } else {
-+ /* Read succeeded. Copy the remaining data from the wbuf */
-+ memcpy(buf + (c->wbuf_ofs - start), c->wbuf, end - c->wbuf_ofs);
-+ }
-+ }
-+ /* OK... we're to rewrite (end-start) bytes of data from first_raw onwards.
-+ Either 'buf' contains the data, or we find it in the wbuf */
-+
-+
-+ /* ... and get an allocation of space from a shiny new block instead */
-+ ret = jffs2_reserve_space_gc(c, end-start, &ofs, &len);
-+ if (ret) {
-+ printk(KERN_WARNING "Failed to allocate space for wbuf recovery. Data loss ensues.\n");
-+ if (buf)
-+ kfree(buf);
-+ return;
-+ }
-+ if (end-start >= c->wbuf_pagesize) {
-+ /* Need to do another write immediately. This, btw,
-+ means that we'll be writing from 'buf' and not from
-+ the wbuf. Since if we're writing from the wbuf there
-+ won't be more than a wbuf full of data, now will
-+ there? :) */
-+
-+ uint32_t towrite = (end-start) - ((end-start)%c->wbuf_pagesize);
-+
-+ D1(printk(KERN_DEBUG "Write 0x%x bytes at 0x%08x in wbuf recover\n",
-+ towrite, ofs));
-+
-+#ifdef BREAKMEHEADER
-+ static int breakme;
-+ if (breakme++ == 20) {
-+ printk(KERN_NOTICE "Faking write error at 0x%08x\n", ofs);
-+ breakme = 0;
-+ c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen,
-+ brokenbuf, NULL, c->oobinfo);
-+ ret = -EIO;
-+ } else
-+#endif
-+ ret = c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen,
-+ buf, NULL, c->oobinfo);
-+
-+ if (ret || retlen != towrite) {
-+ /* Argh. We tried. Really we did. */
-+ printk(KERN_CRIT "Recovery of wbuf failed due to a second write error\n");
-+ kfree(buf);
-+
-+ if (retlen) {
-+ struct jffs2_raw_node_ref *raw2;
-+
-+ raw2 = jffs2_alloc_raw_node_ref();
-+ if (!raw2)
-+ return;
-+
-+ raw2->flash_offset = ofs | REF_OBSOLETE;
-+ raw2->__totlen = ref_totlen(c, jeb, *first_raw);
-+ raw2->next_phys = NULL;
-+ raw2->next_in_ino = NULL;
-+
-+ jffs2_add_physical_node_ref(c, raw2);
-+ }
-+ return;
-+ }
-+ printk(KERN_NOTICE "Recovery of wbuf succeeded to %08x\n", ofs);
-+
-+ c->wbuf_len = (end - start) - towrite;
-+ c->wbuf_ofs = ofs + towrite;
-+ memcpy(c->wbuf, buf + towrite, c->wbuf_len);
-+ /* Don't muck about with c->wbuf_inodes. False positives are harmless. */
-+
-+ kfree(buf);
-+ } else {
-+ /* OK, now we're left with the dregs in whichever buffer we're using */
-+ if (buf) {
-+ memcpy(c->wbuf, buf, end-start);
-+ kfree(buf);
-+ } else {
-+ memmove(c->wbuf, c->wbuf + (start - c->wbuf_ofs), end - start);
-+ }
-+ c->wbuf_ofs = ofs;
-+ c->wbuf_len = end - start;
-+ }
-+
-+ /* Now sort out the jffs2_raw_node_refs, moving them from the old to the next block */
-+ new_jeb = &c->blocks[ofs / c->sector_size];
-+
-+ spin_lock(&c->erase_completion_lock);
-+ if (new_jeb->first_node) {
-+ /* Odd, but possible with ST flash later maybe */
-+ new_jeb->last_node->next_phys = *first_raw;
-+ } else {
-+ new_jeb->first_node = *first_raw;
-+ }
-+
-+ raw = first_raw;
-+ while (*raw) {
-+ uint32_t rawlen = ref_totlen(c, jeb, *raw);
-+
-+ D1(printk(KERN_DEBUG "Refiling block of %08x at %08x(%d) to %08x\n",
-+ rawlen, ref_offset(*raw), ref_flags(*raw), ofs));
-+
-+ if (ref_obsolete(*raw)) {
-+ /* Shouldn't really happen much */
-+ new_jeb->dirty_size += rawlen;
-+ new_jeb->free_size -= rawlen;
-+ c->dirty_size += rawlen;
-+ } else {
-+ new_jeb->used_size += rawlen;
-+ new_jeb->free_size -= rawlen;
-+ jeb->dirty_size += rawlen;
-+ jeb->used_size -= rawlen;
-+ c->dirty_size += rawlen;
-+ }
-+ c->free_size -= rawlen;
-+ (*raw)->flash_offset = ofs | ref_flags(*raw);
-+ ofs += rawlen;
-+ new_jeb->last_node = *raw;
-+
-+ raw = &(*raw)->next_phys;
-+ }
-+
-+ /* Fix up the original jeb now it's on the bad_list */
-+ *first_raw = NULL;
-+ if (first_raw == &jeb->first_node) {
-+ jeb->last_node = NULL;
-+ D1(printk(KERN_DEBUG "Failing block at %08x is now empty. Moving to erase_pending_list\n", jeb->offset));
-+ list_del(&jeb->list);
-+ list_add(&jeb->list, &c->erase_pending_list);
-+ c->nr_erasing_blocks++;
-+ jffs2_erase_pending_trigger(c);
-+ }
-+ else
-+ jeb->last_node = container_of(first_raw, struct jffs2_raw_node_ref, next_phys);
-+
-+ ACCT_SANITY_CHECK(c,jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+
-+ ACCT_SANITY_CHECK(c,new_jeb);
-+ D1(ACCT_PARANOIA_CHECK(new_jeb));
-+
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ D1(printk(KERN_DEBUG "wbuf recovery completed OK\n"));
-+}
-+
-+/* Meaning of pad argument:
-+ 0: Do not pad. Probably pointless - we only ever use this when we can't pad anyway.
-+ 1: Pad, do not adjust nextblock free_size
-+ 2: Pad, adjust nextblock free_size
-+*/
-+static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
-+{
-+ int ret;
-+ size_t retlen;
-+
-+ /* Nothing to do if not NAND flash. In particular, we shouldn't
-+ del_timer() the timer we never initialised. */
-+ if (jffs2_can_mark_obsolete(c))
-+ return 0;
-+
-+ if (!down_trylock(&c->alloc_sem)) {
-+ up(&c->alloc_sem);
-+ printk(KERN_CRIT "jffs2_flush_wbuf() called with alloc_sem not locked!\n");
-+ BUG();
-+ }
-+
-+ if(!c->wbuf || !c->wbuf_len)
-+ return 0;
-+
-+ /* claim remaining space on the page
-+ this happens, if we have a change to a new block,
-+ or if fsync forces us to flush the writebuffer.
-+ if we have a switch to next page, we will not have
-+ enough remaining space for this.
-+ */
-+ if (pad) {
-+ c->wbuf_len = PAD(c->wbuf_len);
-+
-+ if ( c->wbuf_len + sizeof(struct jffs2_unknown_node) < c->wbuf_pagesize) {
-+ struct jffs2_unknown_node *padnode = (void *)(c->wbuf + c->wbuf_len);
-+ padnode->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ padnode->nodetype = cpu_to_je16(JFFS2_NODETYPE_PADDING);
-+ padnode->totlen = cpu_to_je32(c->wbuf_pagesize - c->wbuf_len);
-+ padnode->hdr_crc = cpu_to_je32(crc32(0, padnode, sizeof(*padnode)-4));
-+ }
-+ }
-+ /* else jffs2_flash_writev has actually filled in the rest of the
-+ buffer for us, and will deal with the node refs etc. later. */
-+
-+#ifdef BREAKME
-+ static int breakme;
-+ if (breakme++ == 20) {
-+ printk(KERN_NOTICE "Faking write error at 0x%08x\n", c->wbuf_ofs);
-+ breakme = 0;
-+ c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize,
-+ &retlen, brokenbuf, NULL, c->oobinfo);
-+ ret = -EIO;
-+ } else
-+#endif
-+ ret = c->mtd->write_ecc(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen, c->wbuf, NULL, c->oobinfo);
-+
-+
-+ if (ret || retlen != c->wbuf_pagesize) {
-+ if (ret)
-+ printk(KERN_WARNING "jffs2_flush_wbuf(): Write failed with %d\n",ret);
-+ else {
-+ printk(KERN_WARNING "jffs2_flush_wbuf(): Write was short: %zd instead of %d\n",
-+ retlen, c->wbuf_pagesize);
-+ ret = -EIO;
-+ }
-+
-+ jffs2_wbuf_recover(c);
-+
-+ return ret;
-+ }
-+
-+ /* Adjusting free size of next block only, if it's called from fsync ! */
-+ if (pad == 2) {
-+ D1(printk(KERN_DEBUG "jffs2_flush_wbuf() adjusting free_size of c->nextblock\n"));
-+ spin_lock(&c->erase_completion_lock);
-+ if (!c->nextblock)
-+ BUG();
-+ /* wbuf_pagesize - wbuf_len is the amount of space that's to be
-+ padded. If there is less free space in the block than that,
-+ something screwed up */
-+ if (c->nextblock->free_size < (c->wbuf_pagesize - c->wbuf_len)) {
-+ printk(KERN_CRIT "jffs2_flush_wbuf(): Accounting error. wbuf at 0x%08x has 0x%03x bytes, 0x%03x left.\n",
-+ c->wbuf_ofs, c->wbuf_len, c->wbuf_pagesize-c->wbuf_len);
-+ printk(KERN_CRIT "jffs2_flush_wbuf(): But free_size for block at 0x%08x is only 0x%08x\n",
-+ c->nextblock->offset, c->nextblock->free_size);
-+ BUG();
-+ }
-+ c->nextblock->free_size -= (c->wbuf_pagesize - c->wbuf_len);
-+ c->free_size -= (c->wbuf_pagesize - c->wbuf_len);
-+ c->nextblock->wasted_size += (c->wbuf_pagesize - c->wbuf_len);
-+ c->wasted_size += (c->wbuf_pagesize - c->wbuf_len);
-+ spin_unlock(&c->erase_completion_lock);
-+ }
-+
-+ /* Stick any now-obsoleted blocks on the erase_pending_list */
-+ spin_lock(&c->erase_completion_lock);
-+ jffs2_refile_wbuf_blocks(c);
-+ jffs2_clear_wbuf_ino_list(c);
-+ spin_unlock(&c->erase_completion_lock);
-+
-+ memset(c->wbuf,0xff,c->wbuf_pagesize);
-+ /* adjust write buffer offset, else we get a non contiguous write bug */
-+ c->wbuf_ofs += c->wbuf_pagesize;
-+ c->wbuf_len = 0;
-+ return 0;
-+}
-+
-+/* Trigger garbage collection to flush the write-buffer.
-+ If ino arg is zero, do it if _any_ real (i.e. not GC) writes are
-+ outstanding. If ino arg non-zero, do it only if a write for the
-+ given inode is outstanding. */
-+int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino)
-+{
-+ uint32_t old_wbuf_ofs;
-+ uint32_t old_wbuf_len;
-+ int ret = 0;
-+
-+ D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() called for ino #%u...\n", ino));
-+
-+ down(&c->alloc_sem);
-+ if (!jffs2_wbuf_pending_for_ino(c, ino)) {
-+ D1(printk(KERN_DEBUG "Ino #%d not pending in wbuf. Returning\n", ino));
-+ up(&c->alloc_sem);
-+ return 0;
-+ }
-+
-+ old_wbuf_ofs = c->wbuf_ofs;
-+ old_wbuf_len = c->wbuf_len;
-+
-+ if (c->unchecked_size) {
-+ /* GC won't make any progress for a while */
-+ D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() padding. Not finished checking\n"));
-+ ret = __jffs2_flush_wbuf(c, 2);
-+ } else while (old_wbuf_len &&
-+ old_wbuf_ofs == c->wbuf_ofs) {
-+
-+ up(&c->alloc_sem);
-+
-+ D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() calls gc pass\n"));
-+
-+ ret = jffs2_garbage_collect_pass(c);
-+ if (ret) {
-+ /* GC failed. Flush it with padding instead */
-+ down(&c->alloc_sem);
-+ ret = __jffs2_flush_wbuf(c, 2);
-+ break;
-+ }
-+ down(&c->alloc_sem);
-+ }
-+
-+ D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() ends...\n"));
-+
-+ up(&c->alloc_sem);
-+ return ret;
-+}
-+
-+/* Pad write-buffer to end and write it, wasting space. */
-+int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c)
-+{
-+ return __jffs2_flush_wbuf(c, 1);
-+}
-+
-+
-+#define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) )
-+#define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) )
-+int jffs2_flash_writev(struct jffs2_sb_info *c, const struct iovec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino)
-+{
-+ struct iovec outvecs[3];
-+ uint32_t totlen = 0;
-+ uint32_t split_ofs = 0;
-+ uint32_t old_totlen;
-+ int ret, splitvec = -1;
-+ int invec, outvec;
-+ size_t wbuf_retlen;
-+ unsigned char *wbuf_ptr;
-+ size_t donelen = 0;
-+ uint32_t outvec_to = to;
-+
-+ /* If not NAND flash, don't bother */
-+ if (!c->wbuf)
-+ return jffs2_flash_direct_writev(c, invecs, count, to, retlen);
-+
-+ /* If wbuf_ofs is not initialized, set it to target address */
-+ if (c->wbuf_ofs == 0xFFFFFFFF) {
-+ c->wbuf_ofs = PAGE_DIV(to);
-+ c->wbuf_len = PAGE_MOD(to);
-+ memset(c->wbuf,0xff,c->wbuf_pagesize);
-+ }
-+
-+ /* Sanity checks on target address.
-+ It's permitted to write at PAD(c->wbuf_len+c->wbuf_ofs),
-+ and it's permitted to write at the beginning of a new
-+ erase block. Anything else, and you die.
-+ New block starts at xxx000c (0-b = block header)
-+ */
-+ if ( (to & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) {
-+ /* It's a write to a new block */
-+ if (c->wbuf_len) {
-+ D1(printk(KERN_DEBUG "jffs2_flash_writev() to 0x%lx causes flush of wbuf at 0x%08x\n", (unsigned long)to, c->wbuf_ofs));
-+ ret = jffs2_flush_wbuf_pad(c);
-+ if (ret) {
-+ /* the underlying layer has to check wbuf_len to do the cleanup */
-+ D1(printk(KERN_WARNING "jffs2_flush_wbuf() called from jffs2_flash_writev() failed %d\n", ret));
-+ *retlen = 0;
-+ return ret;
-+ }
-+ }
-+ /* set pointer to new block */
-+ c->wbuf_ofs = PAGE_DIV(to);
-+ c->wbuf_len = PAGE_MOD(to);
-+ }
-+
-+ if (to != PAD(c->wbuf_ofs + c->wbuf_len)) {
-+ /* We're not writing immediately after the writebuffer. Bad. */
-+ printk(KERN_CRIT "jffs2_flash_writev(): Non-contiguous write to %08lx\n", (unsigned long)to);
-+ if (c->wbuf_len)
-+ printk(KERN_CRIT "wbuf was previously %08x-%08x\n",
-+ c->wbuf_ofs, c->wbuf_ofs+c->wbuf_len);
-+ BUG();
-+ }
-+
-+ /* Note outvecs[3] above. We know count is never greater than 2 */
-+ if (count > 2) {
-+ printk(KERN_CRIT "jffs2_flash_writev(): count is %ld\n", count);
-+ BUG();
-+ }
-+
-+ invec = 0;
-+ outvec = 0;
-+
-+
-+ /* Fill writebuffer first, if already in use */
-+ if (c->wbuf_len) {
-+ uint32_t invec_ofs = 0;
-+
-+ /* adjust alignment offset */
-+ if (c->wbuf_len != PAGE_MOD(to)) {
-+ c->wbuf_len = PAGE_MOD(to);
-+ /* take care of alignment to next page */
-+ if (!c->wbuf_len)
-+ c->wbuf_len = c->wbuf_pagesize;
-+ }
-+
-+ while(c->wbuf_len < c->wbuf_pagesize) {
-+ uint32_t thislen;
-+
-+ if (invec == count)
-+ goto alldone;
-+
-+ thislen = c->wbuf_pagesize - c->wbuf_len;
-+
-+ if (thislen >= invecs[invec].iov_len)
-+ thislen = invecs[invec].iov_len;
-+
-+ invec_ofs = thislen;
-+
-+ memcpy(c->wbuf + c->wbuf_len, invecs[invec].iov_base, thislen);
-+ c->wbuf_len += thislen;
-+ donelen += thislen;
-+ /* Get next invec, if actual did not fill the buffer */
-+ if (c->wbuf_len < c->wbuf_pagesize)
-+ invec++;
-+ }
-+
-+ /* write buffer is full, flush buffer */
-+ ret = __jffs2_flush_wbuf(c, 0);
-+ if (ret) {
-+ /* the underlying layer has to check wbuf_len to do the cleanup */
-+ D1(printk(KERN_WARNING "jffs2_flush_wbuf() called from jffs2_flash_writev() failed %d\n", ret));
-+ /* Retlen zero to make sure our caller doesn't mark the space dirty.
-+ We've already done everything that's necessary */
-+ *retlen = 0;
-+ return ret;
-+ }
-+ outvec_to += donelen;
-+ c->wbuf_ofs = outvec_to;
-+
-+ /* All invecs done ? */
-+ if (invec == count)
-+ goto alldone;
-+
-+ /* Set up the first outvec, containing the remainder of the
-+ invec we partially used */
-+ if (invecs[invec].iov_len > invec_ofs) {
-+ outvecs[0].iov_base = invecs[invec].iov_base+invec_ofs;
-+ totlen = outvecs[0].iov_len = invecs[invec].iov_len-invec_ofs;
-+ if (totlen > c->wbuf_pagesize) {
-+ splitvec = outvec;
-+ split_ofs = outvecs[0].iov_len - PAGE_MOD(totlen);
-+ }
-+ outvec++;
-+ }
-+ invec++;
-+ }
-+
-+ /* OK, now we've flushed the wbuf and the start of the bits
-+ we have been asked to write, now to write the rest.... */
-+
-+ /* totlen holds the amount of data still to be written */
-+ old_totlen = totlen;
-+ for ( ; invec < count; invec++,outvec++ ) {
-+ outvecs[outvec].iov_base = invecs[invec].iov_base;
-+ totlen += outvecs[outvec].iov_len = invecs[invec].iov_len;
-+ if (PAGE_DIV(totlen) != PAGE_DIV(old_totlen)) {
-+ splitvec = outvec;
-+ split_ofs = outvecs[outvec].iov_len - PAGE_MOD(totlen);
-+ old_totlen = totlen;
-+ }
-+ }
-+
-+ /* Now the outvecs array holds all the remaining data to write */
-+ /* Up to splitvec,split_ofs is to be written immediately. The rest
-+ goes into the (now-empty) wbuf */
-+
-+ if (splitvec != -1) {
-+ uint32_t remainder;
-+ int ret;
-+
-+ remainder = outvecs[splitvec].iov_len - split_ofs;
-+ outvecs[splitvec].iov_len = split_ofs;
-+
-+ /* We did cross a page boundary, so we write some now */
-+ ret = c->mtd->writev_ecc(c->mtd, outvecs, splitvec+1, outvec_to, &wbuf_retlen, NULL, c->oobinfo);
-+ if (ret < 0 || wbuf_retlen != PAGE_DIV(totlen)) {
-+ /* At this point we have no problem,
-+ c->wbuf is empty.
-+ */
-+ *retlen = donelen;
-+ return ret;
-+ }
-+
-+ donelen += wbuf_retlen;
-+ c->wbuf_ofs = PAGE_DIV(outvec_to) + PAGE_DIV(totlen);
-+
-+ if (remainder) {
-+ outvecs[splitvec].iov_base += split_ofs;
-+ outvecs[splitvec].iov_len = remainder;
-+ } else {
-+ splitvec++;
-+ }
-+
-+ } else {
-+ splitvec = 0;
-+ }
-+
-+ /* Now splitvec points to the start of the bits we have to copy
-+ into the wbuf */
-+ wbuf_ptr = c->wbuf;
-+
-+ for ( ; splitvec < outvec; splitvec++) {
-+ /* Don't copy the wbuf into itself */
-+ if (outvecs[splitvec].iov_base == c->wbuf)
-+ continue;
-+ memcpy(wbuf_ptr, outvecs[splitvec].iov_base, outvecs[splitvec].iov_len);
-+ wbuf_ptr += outvecs[splitvec].iov_len;
-+ donelen += outvecs[splitvec].iov_len;
-+ }
-+ c->wbuf_len = wbuf_ptr - c->wbuf;
-+
-+ /* If there's a remainder in the wbuf and it's a non-GC write,
-+ remember that the wbuf affects this ino */
-+alldone:
-+ *retlen = donelen;
-+
-+ if (c->wbuf_len && ino)
-+ jffs2_wbuf_dirties_inode(c, ino);
-+
-+ return 0;
-+}
-+
-+/*
-+ * This is the entry for flash write.
-+ * Check, if we work on NAND FLASH, if so build an iovec and write it via vritev
-+*/
-+int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, const u_char *buf)
-+{
-+ struct iovec vecs[1];
-+
-+ if (jffs2_can_mark_obsolete(c))
-+ return c->mtd->write(c->mtd, ofs, len, retlen, buf);
-+
-+ vecs[0].iov_base = (unsigned char *) buf;
-+ vecs[0].iov_len = len;
-+ return jffs2_flash_writev(c, vecs, 1, ofs, retlen, 0);
-+}
-+
-+/*
-+ Handle readback from writebuffer and ECC failure return
-+*/
-+int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, u_char *buf)
-+{
-+ loff_t orbf = 0, owbf = 0, lwbf = 0;
-+ int ret;
-+
-+ /* Read flash */
-+ if (!jffs2_can_mark_obsolete(c)) {
-+ ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo);
-+
-+ if ( (ret == -EIO) && (*retlen == len) ) {
-+ printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n",
-+ len, ofs);
-+ /*
-+ * We have the raw data without ECC correction in the buffer, maybe
-+ * we are lucky and all data or parts are correct. We check the node.
-+ * If data are corrupted node check will sort it out.
-+ * We keep this block, it will fail on write or erase and the we
-+ * mark it bad. Or should we do that now? But we should give him a chance.
-+ * Maybe we had a system crash or power loss before the ecc write or
-+ * a erase was completed.
-+ * So we return success. :)
-+ */
-+ ret = 0;
-+ }
-+ } else
-+ return c->mtd->read(c->mtd, ofs, len, retlen, buf);
-+
-+ /* if no writebuffer available or write buffer empty, return */
-+ if (!c->wbuf_pagesize || !c->wbuf_len)
-+ return ret;
-+
-+ /* if we read in a different block, return */
-+ if ( (ofs & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) )
-+ return ret;
-+
-+ if (ofs >= c->wbuf_ofs) {
-+ owbf = (ofs - c->wbuf_ofs); /* offset in write buffer */
-+ if (owbf > c->wbuf_len) /* is read beyond write buffer ? */
-+ return ret;
-+ lwbf = c->wbuf_len - owbf; /* number of bytes to copy */
-+ if (lwbf > len)
-+ lwbf = len;
-+ } else {
-+ orbf = (c->wbuf_ofs - ofs); /* offset in read buffer */
-+ if (orbf > len) /* is write beyond write buffer ? */
-+ return ret;
-+ lwbf = len - orbf; /* number of bytes to copy */
-+ if (lwbf > c->wbuf_len)
-+ lwbf = c->wbuf_len;
-+ }
-+ if (lwbf > 0)
-+ memcpy(buf+orbf,c->wbuf+owbf,lwbf);
-+
-+ return ret;
-+}
-+
-+/*
-+ * Check, if the out of band area is empty
-+ */
-+int jffs2_check_oob_empty( struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, int mode)
-+{
-+ unsigned char *buf;
-+ int ret = 0;
-+ int i,len,page;
-+ size_t retlen;
-+ int oob_size;
-+
-+ oob_size = c->mtd->oobsize;
-+
-+ /* allocate a buffer for all oob data in this sector */
-+ len = 4 * oob_size;
-+ buf = kmalloc(len, GFP_KERNEL);
-+ if (!buf) {
-+ printk(KERN_NOTICE "jffs2_check_oob_empty(): allocation of temporary data buffer for oob check failed\n");
-+ return -ENOMEM;
-+ }
-+ /*
-+ * if mode = 0, we scan for a total empty oob area, else we have
-+ * to take care of the cleanmarker in the first page of the block
-+ */
-+ ret = jffs2_flash_read_oob(c, jeb->offset, len , &retlen, buf);
-+ if (ret) {
-+ D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB failed %d for block at %08x\n", ret, jeb->offset));
-+ goto out;
-+ }
-+
-+ if (retlen < len) {
-+ D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB return short read "
-+ "(%zd bytes not %d) for block at %08x\n", retlen, len, jeb->offset));
-+ ret = -EIO;
-+ goto out;
-+ }
-+
-+ /* Special check for first two pages */
-+ for (page = 0; page < 2 * oob_size; page += oob_size) {
-+ /* Check for bad block marker */
-+ if (buf[page+c->badblock_pos] != 0xff) {
-+ D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Bad or failed block at %08x\n",jeb->offset));
-+ /* Return 2 for bad and 3 for failed block
-+ bad goes to list_bad and failed to list_erase */
-+ ret = (!page) ? 2 : 3;
-+ goto out;
-+ }
-+ for(i = 0; i < oob_size ; i++) {
-+ /* Yeah, we know about the cleanmarker. */
-+ if (mode && i >= c->fsdata_pos &&
-+ i < c->fsdata_pos+c->fsdata_len)
-+ continue;
-+
-+ if (buf[page+i] != 0xFF) {
-+ D2(printk(KERN_DEBUG "Found %02x at %x in OOB for %08x\n",
-+ buf[page+i], page+i, jeb->offset));
-+ ret = 1;
-+ goto out;
-+ }
-+ }
-+ /* only the first page can contain a cleanmarker !*/
-+ mode = 0;
-+ }
-+
-+ /* we know, we are aligned :) */
-+ for (; page < len; page += sizeof(long)) {
-+ unsigned long dat = *(unsigned long *)(&buf[page]);
-+ if(dat != -1) {
-+ ret = 1;
-+ goto out;
-+ }
-+ }
-+
-+out:
-+ kfree(buf);
-+
-+ return ret;
-+}
-+
-+/*
-+* Scan for a valid cleanmarker and for bad blocks
-+* For virtual blocks (concatenated physical blocks) check the cleanmarker
-+* only in the first page of the first physical block, but scan for bad blocks in all
-+* physical blocks
-+*/
-+int jffs2_check_nand_cleanmarker (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
-+{
-+ struct jffs2_unknown_node n;
-+ unsigned char buf[32];
-+ unsigned char *p;
-+ int ret, i, cnt, retval = 0;
-+ size_t retlen, offset;
-+ int oob_size;
-+
-+ offset = jeb->offset;
-+ oob_size = c->mtd->oobsize;
-+
-+ /* Loop through the physical blocks */
-+ for (cnt = 0; cnt < (c->sector_size / c->mtd->erasesize); cnt++) {
-+ /*
-+ * We read oob data from page 0 and 1 of the block.
-+ * page 0 contains cleanmarker and badblock info
-+ * page 1 contains failure count of this block
-+ */
-+ ret = c->mtd->read_oob (c->mtd, offset, oob_size << 1, &retlen, buf);
-+
-+ if (ret) {
-+ D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB failed %d for block at %08x\n", ret, jeb->offset));
-+ return ret;
-+ }
-+ if (retlen < (oob_size << 1)) {
-+ D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Read OOB return short read (%zd bytes not %d) for block at %08x\n", retlen, oob_size << 1, jeb->offset));
-+ return -EIO;
-+ }
-+
-+ /* Check for bad block marker */
-+ if (buf[c->badblock_pos] != 0xff) {
-+ D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Bad block at %08x (has %02x %02x in badblock_pos %d\n",
-+ jeb->offset, buf[c->badblock_pos], buf[c->badblock_pos + oob_size], c->badblock_pos));
-+ return 2;
-+ }
-+
-+ /* Check for failure counter in the second page */
-+ if (buf[c->badblock_pos + oob_size] != 0xff) {
-+ D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): Block marked as failed at %08x, fail count:%d\n", jeb->offset, buf[c->badblock_pos + oob_size]));
-+ return 3;
-+ }
-+
-+ /* Check cleanmarker only on the first physical block */
-+ if (!cnt) {
-+ n.magic = cpu_to_je16 (JFFS2_MAGIC_BITMASK);
-+ n.nodetype = cpu_to_je16 (JFFS2_NODETYPE_CLEANMARKER);
-+ n.totlen = cpu_to_je32 (8);
-+ p = (unsigned char *) &n;
-+
-+ for (i = 0; i < c->fsdata_len; i++) {
-+ if (buf[c->fsdata_pos + i] != p[i]) {
-+ retval = 1;
-+ }
-+ }
-+ D1(if (retval == 1) {
-+ printk(KERN_WARNING "jffs2_check_nand_cleanmarker(): Cleanmarker node not detected in block at %08x\n", jeb->offset);
-+ printk(KERN_WARNING "OOB at %08x was ", offset);
-+ for (i=0; i < oob_size; i++) {
-+ printk("%02x ", buf[i]);
-+ }
-+ printk("\n");
-+ })
-+ }
-+ offset += c->mtd->erasesize;
-+ }
-+ return retval;
-+}
-+
-+int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
-+{
-+ struct jffs2_unknown_node n;
-+ int ret;
-+ size_t retlen;
-+
-+ n.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
-+ n.totlen = cpu_to_je32(8);
-+
-+ ret = jffs2_flash_write_oob(c, jeb->offset + c->fsdata_pos, c->fsdata_len, &retlen, (unsigned char *)&n);
-+
-+ if (ret) {
-+ D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Write failed for block at %08x: error %d\n", jeb->offset, ret));
-+ return ret;
-+ }
-+ if (retlen != c->fsdata_len) {
-+ D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): Short write for block at %08x: %zd not %d\n", jeb->offset, retlen, c->fsdata_len));
-+ return ret;
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * We try to get the failure count of this block.
-+ */
-+int jffs2_nand_read_failcnt(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) {
-+
-+ unsigned char buf[16];
-+ int ret;
-+ size_t retlen;
-+ int oob_size;
-+
-+ oob_size = c->mtd->oobsize;
-+
-+ ret = c->mtd->read_oob(c->mtd, jeb->offset + c->mtd->oobblock, oob_size , &retlen, buf);
-+
-+ if (ret) {
-+ D1(printk(KERN_WARNING "jffs2_nand_read_failcnt(): Read OOB failed %d for block at %08x\n", ret, jeb->offset));
-+ return ret;
-+ }
-+
-+ if (retlen < oob_size) {
-+ D1(printk(KERN_WARNING "jffs2_nand_read_failcnt(): Read OOB return short read (%zd bytes not %d) for block at %08x\n", retlen, oob_size, jeb->offset));
-+ return -EIO;
-+ }
-+
-+ jeb->bad_count = buf[c->badblock_pos];
-+ return 0;
-+}
-+
-+/*
-+ * On NAND we try to mark this block bad. We try to write how often
-+ * the block was erased and mark it finaly bad, if the count
-+ * is > MAX_ERASE_FAILURES. We read this information on mount !
-+ * jeb->bad_count contains the count before this erase.
-+ * Don't care about failures. This block remains on the erase-pending
-+ * or badblock list as long as nobody manipulates the flash with
-+ * a bootloader or something like that.
-+ */
-+
-+int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
-+{
-+ unsigned char buf = 0x0;
-+ int ret;
-+ size_t retlen;
-+
-+ /* if the count is < max, we try to write the counter to the 2nd page oob area */
-+ if( ++jeb->bad_count < MAX_ERASE_FAILURES) {
-+ buf = (unsigned char)jeb->bad_count;
-+ c->badblock_pos += c->mtd->oobblock;
-+ }
-+
-+ ret = jffs2_flash_write_oob(c, jeb->offset + c->badblock_pos, 1, &retlen, &buf);
-+
-+ if (ret) {
-+ D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Write failed for block at %08x: error %d\n", jeb->offset, ret));
-+ return ret;
-+ }
-+ if (retlen != 1) {
-+ D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Short write for block at %08x: %zd not 1\n", jeb->offset, retlen));
-+ return ret;
-+ }
-+ return 0;
-+}
-+
-+#define JFFS2_OOB_ECCPOS0 0
-+#define JFFS2_OOB_ECCPOS1 1
-+#define JFFS2_OOB_ECCPOS2 2
-+#define JFFS2_OOB_ECCPOS3 3
-+#define JFFS2_OOB_ECCPOS4 6
-+#define JFFS2_OOB_ECCPOS5 7
-+
-+#define NAND_JFFS2_OOB8_FSDAPOS 6
-+#define NAND_JFFS2_OOB16_FSDAPOS 8
-+#define NAND_JFFS2_OOB8_FSDALEN 2
-+#define NAND_JFFS2_OOB16_FSDALEN 8
-+
-+static struct nand_oobinfo jffs2_oobinfo_swecc = {
-+ .useecc = 1,
-+ .eccpos = {JFFS2_OOB_ECCPOS0, JFFS2_OOB_ECCPOS1, JFFS2_OOB_ECCPOS2,
-+ JFFS2_OOB_ECCPOS3, JFFS2_OOB_ECCPOS4, JFFS2_OOB_ECCPOS5}
-+};
-+
-+static struct nand_oobinfo jffs2_oobinfo_docecc = {
-+ .useecc = 1,
-+ .eccpos = {0,1,2,3,4,5}
-+};
-+
-+
-+
-+int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
-+{
-+ /* Cleanmarker is out-of-band, so inline size zero */
-+ c->cleanmarker_size = 0;
-+
-+ /* Initialise write buffer */
-+ c->wbuf_pagesize = c->mtd->oobblock;
-+ c->wbuf_ofs = 0xFFFFFFFF;
-+
-+ /* FIXME: If we had a generic way of describing the hardware's
-+ use of OOB area, we could perhaps make this generic too. */
-+ switch(c->mtd->ecctype) {
-+ case MTD_ECC_SW:
-+ D1(printk(KERN_DEBUG "JFFS2 using software ECC\n"));
-+ c->oobinfo = &jffs2_oobinfo_swecc;
-+ if (c->mtd->oobsize == 8) {
-+ c->fsdata_pos = NAND_JFFS2_OOB8_FSDAPOS;
-+ c->fsdata_len = NAND_JFFS2_OOB8_FSDALEN;
-+ } else {
-+ c->fsdata_pos = NAND_JFFS2_OOB16_FSDAPOS;
-+ c->fsdata_len = NAND_JFFS2_OOB16_FSDALEN;
-+ }
-+ c->badblock_pos = NAND_BADBLOCK_POS;
-+ break;
-+
-+ case MTD_ECC_RS_DiskOnChip:
-+ D1(printk(KERN_DEBUG "JFFS2 using DiskOnChip hardware ECC\n"));
-+ c->oobinfo = &jffs2_oobinfo_docecc;
-+ c->fsdata_pos = 6;
-+ c->fsdata_len = NAND_JFFS2_OOB16_FSDALEN;
-+ c->badblock_pos = 15;
-+ break;
-+
-+ default:
-+ printk("JFFS2 doesn't yet know how to handle ECC type %d\n",
-+ c->mtd->ecctype);
-+ return -EINVAL;
-+ }
-+
-+ c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
-+ if (!c->wbuf)
-+ return -ENOMEM;
-+
-+#ifdef BREAKME
-+ if (!brokenbuf)
-+ brokenbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
-+ if (!brokenbuf) {
-+ kfree(c->wbuf);
-+ return -ENOMEM;
-+ }
-+ memset(brokenbuf, 0xdb, c->wbuf_pagesize);
-+#endif
-+ return 0;
-+}
-+
-+void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c)
-+{
-+ kfree(c->wbuf);
-+}
-diff -Nurb linux-mips-2.4.27/fs/jffs2/write.c linux/fs/jffs2/write.c
---- linux-mips-2.4.27/fs/jffs2/write.c 2003-11-17 02:07:44.000000000 +0100
-+++ linux/fs/jffs2/write.c 2004-11-19 10:25:12.132164376 +0100
-@@ -1,154 +1,70 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in this directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #include <linux/kernel.h>
- #include <linux/fs.h>
--#include <linux/jffs2.h>
-+#include <linux/crc32.h>
-+#include <linux/slab.h>
-+#include <linux/pagemap.h>
- #include <linux/mtd/mtd.h>
- #include "nodelist.h"
--#include <linux/crc32.h>
-
--/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash,
-- fill in the raw_inode while you're at it. */
--struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri)
-+
-+int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri)
- {
-- struct inode *inode;
-- struct super_block *sb = dir_i->i_sb;
- struct jffs2_inode_cache *ic;
-- struct jffs2_sb_info *c;
-- struct jffs2_inode_info *f;
--
-- D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode));
--
-- c = JFFS2_SB_INFO(sb);
-- memset(ri, 0, sizeof(*ri));
-
- ic = jffs2_alloc_inode_cache();
- if (!ic) {
-- return ERR_PTR(-ENOMEM);
-+ return -ENOMEM;
- }
-- memset(ic, 0, sizeof(*ic));
--
-- inode = new_inode(sb);
-
-- if (!inode) {
-- jffs2_free_inode_cache(ic);
-- return ERR_PTR(-ENOMEM);
-- }
--
-- /* Alloc jffs2_inode_info when that's split in 2.5 */
-+ memset(ic, 0, sizeof(*ic));
-
-- f = JFFS2_INODE_INFO(inode);
-- memset(f, 0, sizeof(*f));
- init_MUTEX_LOCKED(&f->sem);
- f->inocache = ic;
-- inode->i_nlink = f->inocache->nlink = 1;
-+ f->inocache->nlink = 1;
- f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
-- f->inocache->ino = ri->ino = inode->i_ino = ++c->highest_ino;
-- D1(printk(KERN_DEBUG "jffs2_new_inode(): Assigned ino# %d\n", ri->ino));
-- jffs2_add_ino_cache(c, f->inocache);
-+ f->inocache->ino = ++c->highest_ino;
-+ f->inocache->state = INO_STATE_PRESENT;
-
-- ri->magic = JFFS2_MAGIC_BITMASK;
-- ri->nodetype = JFFS2_NODETYPE_INODE;
-- ri->totlen = PAD(sizeof(*ri));
-- ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);
-- ri->mode = mode;
-- f->highest_version = ri->version = 1;
-- ri->uid = current->fsuid;
-- if (dir_i->i_mode & S_ISGID) {
-- ri->gid = dir_i->i_gid;
-- if (S_ISDIR(mode))
-- ri->mode |= S_ISGID;
-- } else {
-- ri->gid = current->fsgid;
-- }
-- inode->i_mode = ri->mode;
-- inode->i_gid = ri->gid;
-- inode->i_uid = ri->uid;
-- inode->i_atime = inode->i_ctime = inode->i_mtime =
-- ri->atime = ri->mtime = ri->ctime = CURRENT_TIME;
-- inode->i_blksize = PAGE_SIZE;
-- inode->i_blocks = 0;
-- inode->i_size = 0;
-+ ri->ino = cpu_to_je32(f->inocache->ino);
-
-- insert_inode_hash(inode);
-+ D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino));
-+ jffs2_add_ino_cache(c, f->inocache);
-
-- return inode;
--}
-+ ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
-+ ri->totlen = cpu_to_je32(PAD(sizeof(*ri)));
-+ ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
-+ ri->mode = cpu_to_jemode(mode);
-
--/* This ought to be in core MTD code. All registered MTD devices
-- without writev should have this put in place. Bug the MTD
-- maintainer */
--static int mtd_fake_writev(struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen)
--{
-- unsigned long i;
-- size_t totlen = 0, thislen;
-- int ret = 0;
-+ f->highest_version = 1;
-+ ri->version = cpu_to_je32(f->highest_version);
-
-- for (i=0; i<count; i++) {
-- ret = mtd->write(mtd, to, vecs[i].iov_len, &thislen, vecs[i].iov_base);
-- totlen += thislen;
-- if (ret || thislen != vecs[i].iov_len)
-- break;
-- to += vecs[i].iov_len;
-- }
-- if (retlen)
-- *retlen = totlen;
-- return ret;
--}
--
--
--static inline int mtd_writev(struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen)
--{
-- if (mtd->writev)
-- return mtd->writev(mtd,vecs,count,to,retlen);
-- else
-- return mtd_fake_writev(mtd, vecs, count, to, retlen);
-+ return 0;
- }
-
--static void writecheck(struct mtd_info *mtd, __u32 ofs)
-+#if CONFIG_JFFS2_FS_DEBUG > 0
-+static void writecheck(struct jffs2_sb_info *c, uint32_t ofs)
- {
- unsigned char buf[16];
-- ssize_t retlen;
-+ size_t retlen;
- int ret, i;
-
-- ret = mtd->read(mtd, ofs, 16, &retlen, buf);
-- if (ret && retlen != 16) {
-- D1(printk(KERN_DEBUG "read failed or short in writecheck(). ret %d, retlen %d\n", ret, retlen));
-+ ret = jffs2_flash_read(c, ofs, 16, &retlen, buf);
-+ if (ret || (retlen != 16)) {
-+ D1(printk(KERN_DEBUG "read failed or short in writecheck(). ret %d, retlen %zd\n", ret, retlen));
- return;
- }
- ret = 0;
-@@ -157,32 +73,31 @@
- ret = 1;
- }
- if (ret) {
-- printk(KERN_WARNING "ARGH. About to write node to 0x%08x on flash, but there's data already there:\n", ofs);
-+ printk(KERN_WARNING "ARGH. About to write node to 0x%08x on flash, but there are data already there:\n", ofs);
- printk(KERN_WARNING "0x%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- ofs,
- buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7],
- buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);
- }
- }
--
--
-+#endif
-
-
- /* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it,
- write it to the flash, link it into the existing inode/fragment list */
-
--struct jffs2_full_dnode *jffs2_write_dnode(struct inode *inode, struct jffs2_raw_inode *ri, const unsigned char *data, __u32 datalen, __u32 flash_ofs, __u32 *writelen)
-+struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode)
-
- {
-- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_raw_node_ref *raw;
- struct jffs2_full_dnode *fn;
-- ssize_t retlen;
-+ size_t retlen;
- struct iovec vecs[2];
- int ret;
-+ int retried = 0;
-+ unsigned long cnt = 2;
-
-- D1(if(ri->hdr_crc != crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)) {
-+ D1(if(je32_to_cpu(ri->hdr_crc) != crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)) {
- printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dnode()\n");
- BUG();
- }
-@@ -192,10 +107,10 @@
- vecs[1].iov_base = (unsigned char *)data;
- vecs[1].iov_len = datalen;
-
-- writecheck(c->mtd, flash_ofs);
-+ D1(writecheck(c, flash_ofs));
-
-- if (ri->totlen != sizeof(*ri) + datalen) {
-- printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08x) + datalen (0x%08x)\n", ri->totlen, sizeof(*ri), datalen);
-+ if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) {
-+ printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen);
- }
- raw = jffs2_alloc_raw_node_ref();
- if (!raw)
-@@ -206,19 +121,28 @@
- jffs2_free_raw_node_ref(raw);
- return ERR_PTR(-ENOMEM);
- }
-- raw->flash_offset = flash_ofs;
-- raw->totlen = PAD(ri->totlen);
-- raw->next_phys = NULL;
-
-- fn->ofs = ri->offset;
-- fn->size = ri->dsize;
-+ fn->ofs = je32_to_cpu(ri->offset);
-+ fn->size = je32_to_cpu(ri->dsize);
- fn->frags = 0;
-+
-+ /* check number of valid vecs */
-+ if (!datalen || !data)
-+ cnt = 1;
-+ retry:
- fn->raw = raw;
-
-- ret = mtd_writev(c->mtd, vecs, 2, flash_ofs, &retlen);
-+ raw->flash_offset = flash_ofs;
-+ raw->__totlen = PAD(sizeof(*ri)+datalen);
-+ raw->next_phys = NULL;
-+
-+ ret = jffs2_flash_writev(c, vecs, cnt, flash_ofs, &retlen,
-+ (alloc_mode==ALLOC_GC)?0:f->inocache->ino);
-+
- if (ret || (retlen != sizeof(*ri) + datalen)) {
-- printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %d\n",
-+ printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
- sizeof(*ri)+datalen, flash_ofs, ret, retlen);
-+
- /* Mark the space as dirtied */
- if (retlen) {
- /* Doesn't belong to any inode */
-@@ -229,48 +153,96 @@
- seem corrupted, in which case the scan would skip over
- any node we write before the original intended end of
- this node */
-- jffs2_add_physical_node_ref(c, raw, sizeof(*ri)+datalen, 1);
-+ raw->flash_offset |= REF_OBSOLETE;
-+ jffs2_add_physical_node_ref(c, raw);
- jffs2_mark_node_obsolete(c, raw);
- } else {
- printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset);
- jffs2_free_raw_node_ref(raw);
- }
-+ if (!retried && alloc_mode != ALLOC_NORETRY && (raw = jffs2_alloc_raw_node_ref())) {
-+ /* Try to reallocate space and retry */
-+ uint32_t dummy;
-+ struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size];
-+
-+ retried = 1;
-+
-+ D1(printk(KERN_DEBUG "Retrying failed write.\n"));
-+
-+ ACCT_SANITY_CHECK(c,jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+
-+ if (alloc_mode == ALLOC_GC) {
-+ ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, &dummy);
-+ } else {
-+ /* Locking pain */
-+ up(&f->sem);
-+ jffs2_complete_reservation(c);
-+
-+ ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs, &dummy, alloc_mode);
-+ down(&f->sem);
-+ }
-+
-+ if (!ret) {
-+ D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs));
-+
-+ ACCT_SANITY_CHECK(c,jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-
-+ goto retry;
-+ }
-+ D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
-+ jffs2_free_raw_node_ref(raw);
-+ }
- /* Release the full_dnode which is now useless, and return */
- jffs2_free_full_dnode(fn);
-- if (writelen)
-- *writelen = retlen;
- return ERR_PTR(ret?ret:-EIO);
- }
- /* Mark the space used */
-- jffs2_add_physical_node_ref(c, raw, retlen, 0);
-+ /* If node covers at least a whole page, or if it starts at the
-+ beginning of a page and runs to the end of the file, or if
-+ it's a hole node, mark it REF_PRISTINE, else REF_NORMAL.
-+ */
-+ if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) ||
-+ ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) &&
-+ (je32_to_cpu(ri->dsize)+je32_to_cpu(ri->offset) == je32_to_cpu(ri->isize)))) {
-+ raw->flash_offset |= REF_PRISTINE;
-+ } else {
-+ raw->flash_offset |= REF_NORMAL;
-+ }
-+ jffs2_add_physical_node_ref(c, raw);
-
- /* Link into per-inode list */
- raw->next_in_ino = f->inocache->nodes;
- f->inocache->nodes = raw;
-
-- D1(printk(KERN_DEBUG "jffs2_write_dnode wrote node at 0x%08x with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n", flash_ofs, ri->dsize, ri->csize, ri->node_crc, ri->data_crc, ri->totlen));
-- if (writelen)
-- *writelen = retlen;
-+ D1(printk(KERN_DEBUG "jffs2_write_dnode wrote node at 0x%08x(%d) with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n",
-+ flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize),
-+ je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc),
-+ je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen)));
-+
-+ if (retried) {
-+ ACCT_SANITY_CHECK(c,NULL);
-+ }
-
-- f->inocache->nodes = raw;
- return fn;
- }
-
--struct jffs2_full_dirent *jffs2_write_dirent(struct inode *inode, struct jffs2_raw_dirent *rd, const unsigned char *name, __u32 namelen, __u32 flash_ofs, __u32 *writelen)
-+struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_dirent *rd, const unsigned char *name, uint32_t namelen, uint32_t flash_ofs, int alloc_mode)
- {
-- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_raw_node_ref *raw;
- struct jffs2_full_dirent *fd;
-- ssize_t retlen;
-+ size_t retlen;
- struct iovec vecs[2];
-+ int retried = 0;
- int ret;
-
-- D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n", rd->pino, name, name, rd->ino, rd->name_crc));
-- writecheck(c->mtd, flash_ofs);
-+ D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n",
-+ je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino),
-+ je32_to_cpu(rd->name_crc)));
-+ D1(writecheck(c, flash_ofs));
-
-- D1(if(rd->hdr_crc != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) {
-+ D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) {
- printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n");
- BUG();
- }
-@@ -291,44 +263,414 @@
- jffs2_free_raw_node_ref(raw);
- return ERR_PTR(-ENOMEM);
- }
-- raw->flash_offset = flash_ofs;
-- raw->totlen = PAD(rd->totlen);
-- raw->next_in_ino = f->inocache->nodes;
-- f->inocache->nodes = raw;
-- raw->next_phys = NULL;
-
-- fd->version = rd->version;
-- fd->ino = rd->ino;
-+ fd->version = je32_to_cpu(rd->version);
-+ fd->ino = je32_to_cpu(rd->ino);
- fd->nhash = full_name_hash(name, strlen(name));
- fd->type = rd->type;
- memcpy(fd->name, name, namelen);
- fd->name[namelen]=0;
-+
-+ retry:
- fd->raw = raw;
-
-- ret = mtd_writev(c->mtd, vecs, 2, flash_ofs, &retlen);
-+ raw->flash_offset = flash_ofs;
-+ raw->__totlen = PAD(sizeof(*rd)+namelen);
-+ raw->next_phys = NULL;
-+
-+ ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen,
-+ (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino));
- if (ret || (retlen != sizeof(*rd) + namelen)) {
-- printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %d\n",
-+ printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n",
- sizeof(*rd)+namelen, flash_ofs, ret, retlen);
- /* Mark the space as dirtied */
- if (retlen) {
-- jffs2_add_physical_node_ref(c, raw, sizeof(*rd)+namelen, 1);
-+ raw->next_in_ino = NULL;
-+ raw->flash_offset |= REF_OBSOLETE;
-+ jffs2_add_physical_node_ref(c, raw);
- jffs2_mark_node_obsolete(c, raw);
- } else {
- printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset);
- jffs2_free_raw_node_ref(raw);
- }
-+ if (!retried && (raw = jffs2_alloc_raw_node_ref())) {
-+ /* Try to reallocate space and retry */
-+ uint32_t dummy;
-+ struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size];
-+
-+ retried = 1;
-+
-+ D1(printk(KERN_DEBUG "Retrying failed write.\n"));
-+
-+ ACCT_SANITY_CHECK(c,jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+
-+ if (alloc_mode == ALLOC_GC) {
-+ ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, &dummy);
-+ } else {
-+ /* Locking pain */
-+ up(&f->sem);
-+ jffs2_complete_reservation(c);
-+
-+ ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs, &dummy, alloc_mode);
-+ down(&f->sem);
-+ }
-
-+ if (!ret) {
-+ D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs));
-+ ACCT_SANITY_CHECK(c,jeb);
-+ D1(ACCT_PARANOIA_CHECK(jeb));
-+ goto retry;
-+ }
-+ D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret));
-+ jffs2_free_raw_node_ref(raw);
-+ }
- /* Release the full_dnode which is now useless, and return */
- jffs2_free_full_dirent(fd);
-- if (writelen)
-- *writelen = retlen;
- return ERR_PTR(ret?ret:-EIO);
- }
- /* Mark the space used */
-- jffs2_add_physical_node_ref(c, raw, retlen, 0);
-- if (writelen)
-- *writelen = retlen;
-+ raw->flash_offset |= REF_PRISTINE;
-+ jffs2_add_physical_node_ref(c, raw);
-
-+ raw->next_in_ino = f->inocache->nodes;
- f->inocache->nodes = raw;
-+
-+ if (retried) {
-+ ACCT_SANITY_CHECK(c,NULL);
-+ }
-+
- return fd;
- }
-+
-+/* The OS-specific code fills in the metadata in the jffs2_raw_inode for us, so that
-+ we don't have to go digging in struct inode or its equivalent. It should set:
-+ mode, uid, gid, (starting)isize, atime, ctime, mtime */
-+int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
-+ struct jffs2_raw_inode *ri, unsigned char *buf,
-+ uint32_t offset, uint32_t writelen, uint32_t *retlen)
-+{
-+ int ret = 0;
-+ uint32_t writtenlen = 0;
-+
-+ D1(printk(KERN_DEBUG "jffs2_write_inode_range(): Ino #%u, ofs 0x%x, len 0x%x\n",
-+ f->inocache->ino, offset, writelen));
-+
-+ while(writelen) {
-+ struct jffs2_full_dnode *fn;
-+ unsigned char *comprbuf = NULL;
-+ unsigned char comprtype = JFFS2_COMPR_NONE;
-+ uint32_t phys_ofs, alloclen;
-+ uint32_t datalen, cdatalen;
-+ int retried = 0;
-+
-+ retry:
-+ D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset));
-+
-+ ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL);
-+ if (ret) {
-+ D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret));
-+ break;
-+ }
-+ down(&f->sem);
-+ datalen = min_t(uint32_t, writelen, PAGE_CACHE_SIZE - (offset & (PAGE_CACHE_SIZE-1)));
-+ cdatalen = min_t(uint32_t, alloclen - sizeof(*ri), datalen);
-+
-+ comprtype = jffs2_compress(buf, &comprbuf, &datalen, &cdatalen);
-+
-+ ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
-+ ri->totlen = cpu_to_je32(sizeof(*ri) + cdatalen);
-+ ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
-+
-+ ri->ino = cpu_to_je32(f->inocache->ino);
-+ ri->version = cpu_to_je32(++f->highest_version);
-+ ri->isize = cpu_to_je32(max(je32_to_cpu(ri->isize), offset + datalen));
-+ ri->offset = cpu_to_je32(offset);
-+ ri->csize = cpu_to_je32(cdatalen);
-+ ri->dsize = cpu_to_je32(datalen);
-+ ri->compr = comprtype;
-+ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-+ ri->data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
-+
-+ fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, phys_ofs, ALLOC_NORETRY);
-+
-+ jffs2_free_comprbuf(comprbuf, buf);
-+
-+ if (IS_ERR(fn)) {
-+ ret = PTR_ERR(fn);
-+ up(&f->sem);
-+ jffs2_complete_reservation(c);
-+ if (!retried) {
-+ /* Write error to be retried */
-+ retried = 1;
-+ D1(printk(KERN_DEBUG "Retrying node write in jffs2_write_inode_range()\n"));
-+ goto retry;
-+ }
-+ break;
-+ }
-+ ret = jffs2_add_full_dnode_to_inode(c, f, fn);
-+ if (f->metadata) {
-+ jffs2_mark_node_obsolete(c, f->metadata->raw);
-+ jffs2_free_full_dnode(f->metadata);
-+ f->metadata = NULL;
-+ }
-+ if (ret) {
-+ /* Eep */
-+ D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n", ret));
-+ jffs2_mark_node_obsolete(c, fn->raw);
-+ jffs2_free_full_dnode(fn);
-+
-+ up(&f->sem);
-+ jffs2_complete_reservation(c);
-+ break;
-+ }
-+ up(&f->sem);
-+ jffs2_complete_reservation(c);
-+ if (!datalen) {
-+ printk(KERN_WARNING "Eep. We didn't actually write any data in jffs2_write_inode_range()\n");
-+ ret = -EIO;
-+ break;
-+ }
-+ D1(printk(KERN_DEBUG "increasing writtenlen by %d\n", datalen));
-+ writtenlen += datalen;
-+ offset += datalen;
-+ writelen -= datalen;
-+ buf += datalen;
-+ }
-+ *retlen = writtenlen;
-+ return ret;
-+}
-+
-+int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen)
-+{
-+ struct jffs2_raw_dirent *rd;
-+ struct jffs2_full_dnode *fn;
-+ struct jffs2_full_dirent *fd;
-+ uint32_t alloclen, phys_ofs;
-+ int ret;
-+
-+ /* Try to reserve enough space for both node and dirent.
-+ * Just the node will do for now, though
-+ */
-+ ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);
-+ D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen));
-+ if (ret) {
-+ up(&f->sem);
-+ return ret;
-+ }
-+
-+ ri->data_crc = cpu_to_je32(0);
-+ ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
-+
-+ fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL);
-+
-+ D1(printk(KERN_DEBUG "jffs2_do_create created file with mode 0x%x\n",
-+ jemode_to_cpu(ri->mode)));
-+
-+ if (IS_ERR(fn)) {
-+ D1(printk(KERN_DEBUG "jffs2_write_dnode() failed\n"));
-+ /* Eeek. Wave bye bye */
-+ up(&f->sem);
-+ jffs2_complete_reservation(c);
-+ return PTR_ERR(fn);
-+ }
-+ /* No data here. Only a metadata node, which will be
-+ obsoleted by the first data write
-+ */
-+ f->metadata = fn;
-+
-+ up(&f->sem);
-+ jffs2_complete_reservation(c);
-+ ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
-+
-+ if (ret) {
-+ /* Eep. */
-+ D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n"));
-+ return ret;
-+ }
-+
-+ rd = jffs2_alloc_raw_dirent();
-+ if (!rd) {
-+ /* Argh. Now we treat it like a normal delete */
-+ jffs2_complete_reservation(c);
-+ return -ENOMEM;
-+ }
-+
-+ down(&dir_f->sem);
-+
-+ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
-+ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
-+ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
-+
-+ rd->pino = cpu_to_je32(dir_f->inocache->ino);
-+ rd->version = cpu_to_je32(++dir_f->highest_version);
-+ rd->ino = ri->ino;
-+ rd->mctime = ri->ctime;
-+ rd->nsize = namelen;
-+ rd->type = DT_REG;
-+ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
-+ rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
-+
-+ fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL);
-+
-+ jffs2_free_raw_dirent(rd);
-+
-+ if (IS_ERR(fd)) {
-+ /* dirent failed to write. Delete the inode normally
-+ as if it were the final unlink() */
-+ jffs2_complete_reservation(c);
-+ up(&dir_f->sem);
-+ return PTR_ERR(fd);
-+ }
-+
-+ /* Link the fd into the inode's list, obsoleting an old
-+ one if necessary. */
-+ jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-+
-+ jffs2_complete_reservation(c);
-+ up(&dir_f->sem);
-+
-+ return 0;
-+}
-+
-+
-+int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
-+ const char *name, int namelen, struct jffs2_inode_info *dead_f)
-+{
-+ struct jffs2_raw_dirent *rd;
-+ struct jffs2_full_dirent *fd;
-+ uint32_t alloclen, phys_ofs;
-+ int ret;
-+
-+ rd = jffs2_alloc_raw_dirent();
-+ if (!rd)
-+ return -ENOMEM;
-+
-+ ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_DELETION);
-+ if (ret) {
-+ jffs2_free_raw_dirent(rd);
-+ return ret;
-+ }
-+
-+ down(&dir_f->sem);
-+
-+ /* Build a deletion node */
-+ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
-+ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
-+ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
-+
-+ rd->pino = cpu_to_je32(dir_f->inocache->ino);
-+ rd->version = cpu_to_je32(++dir_f->highest_version);
-+ rd->ino = cpu_to_je32(0);
-+ rd->mctime = cpu_to_je32(get_seconds());
-+ rd->nsize = namelen;
-+ rd->type = DT_UNKNOWN;
-+ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
-+ rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
-+
-+ fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_DELETION);
-+
-+ jffs2_free_raw_dirent(rd);
-+
-+ if (IS_ERR(fd)) {
-+ jffs2_complete_reservation(c);
-+ up(&dir_f->sem);
-+ return PTR_ERR(fd);
-+ }
-+
-+ /* File it. This will mark the old one obsolete. */
-+ jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-+
-+ up(&dir_f->sem);
-+
-+ /* dead_f is NULL if this was a rename not a real unlink */
-+ /* Also catch the !f->inocache case, where there was a dirent
-+ pointing to an inode which didn't exist. */
-+ if (dead_f && dead_f->inocache) {
-+
-+ down(&dead_f->sem);
-+
-+ while (dead_f->dents) {
-+ /* There can be only deleted ones */
-+ fd = dead_f->dents;
-+
-+ dead_f->dents = fd->next;
-+
-+ if (fd->ino) {
-+ printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n",
-+ dead_f->inocache->ino, fd->name, fd->ino);
-+ } else {
-+ D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", fd->name, dead_f->inocache->ino));
-+ }
-+ jffs2_mark_node_obsolete(c, fd->raw);
-+ jffs2_free_full_dirent(fd);
-+ }
-+
-+ dead_f->inocache->nlink--;
-+ /* NB: Caller must set inode nlink if appropriate */
-+ up(&dead_f->sem);
-+ }
-+
-+ jffs2_complete_reservation(c);
-+
-+ return 0;
-+}
-+
-+
-+int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen)
-+{
-+ struct jffs2_raw_dirent *rd;
-+ struct jffs2_full_dirent *fd;
-+ uint32_t alloclen, phys_ofs;
-+ int ret;
-+
-+ rd = jffs2_alloc_raw_dirent();
-+ if (!rd)
-+ return -ENOMEM;
-+
-+ ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
-+ if (ret) {
-+ jffs2_free_raw_dirent(rd);
-+ return ret;
-+ }
-+
-+ down(&dir_f->sem);
-+
-+ /* Build a deletion node */
-+ rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
-+ rd->totlen = cpu_to_je32(sizeof(*rd) + namelen);
-+ rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4));
-+
-+ rd->pino = cpu_to_je32(dir_f->inocache->ino);
-+ rd->version = cpu_to_je32(++dir_f->highest_version);
-+ rd->ino = cpu_to_je32(ino);
-+ rd->mctime = cpu_to_je32(get_seconds());
-+ rd->nsize = namelen;
-+
-+ rd->type = type;
-+
-+ rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
-+ rd->name_crc = cpu_to_je32(crc32(0, name, namelen));
-+
-+ fd = jffs2_write_dirent(c, dir_f, rd, name, namelen, phys_ofs, ALLOC_NORMAL);
-+
-+ jffs2_free_raw_dirent(rd);
-+
-+ if (IS_ERR(fd)) {
-+ jffs2_complete_reservation(c);
-+ up(&dir_f->sem);
-+ return PTR_ERR(fd);
-+ }
-+
-+ /* File it. This will mark the old one obsolete. */
-+ jffs2_add_fd_to_list(c, fd, &dir_f->dents);
-+
-+ jffs2_complete_reservation(c);
-+ up(&dir_f->sem);
-+
-+ return 0;
-+}
-diff -Nurb linux-mips-2.4.27/fs/jffs2/writev.c linux/fs/jffs2/writev.c
---- linux-mips-2.4.27/fs/jffs2/writev.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux/fs/jffs2/writev.c 2004-11-19 10:25:12.134164072 +0100
-@@ -0,0 +1,50 @@
-+/*
-+ * JFFS2 -- Journalling Flash File System, Version 2.
-+ *
-+ * Copyright (C) 2001, 2002 Red Hat, Inc.
-+ *
-+ * Created by David Woodhouse <dwmw2@redhat.com>
-+ *
-+ * For licensing information, see the file 'LICENCE' in this directory.
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/mtd/mtd.h>
-+#include "nodelist.h"
-+
-+/* This ought to be in core MTD code. All registered MTD devices
-+ without writev should have this put in place. Bug the MTD
-+ maintainer */
-+static inline int mtd_fake_writev(struct mtd_info *mtd, const struct iovec *vecs,
-+ unsigned long count, loff_t to, size_t *retlen)
-+{
-+ unsigned long i;
-+ size_t totlen = 0, thislen;
-+ int ret = 0;
-+
-+ for (i=0; i<count; i++) {
-+ if (!vecs[i].iov_len)
-+ continue;
-+ ret = mtd->write(mtd, to, vecs[i].iov_len, &thislen, vecs[i].iov_base);
-+ totlen += thislen;
-+ if (ret || thislen != vecs[i].iov_len)
-+ break;
-+ to += vecs[i].iov_len;
-+ }
-+ if (retlen)
-+ *retlen = totlen;
-+ return ret;
-+}
-+
-+int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct iovec *vecs,
-+ unsigned long count, loff_t to, size_t *retlen)
-+{
-+ if (c->mtd->writev)
-+ return c->mtd->writev(c->mtd, vecs, count, to, retlen);
-+ else
-+ return mtd_fake_writev(c->mtd, vecs, count, to, retlen);
-+}
-+
-diff -Nurb linux-mips-2.4.27/include/linux/jffs2.h linux/include/linux/jffs2.h
---- linux-mips-2.4.27/include/linux/jffs2.h 2002-06-27 00:36:46.000000000 +0200
-+++ linux/include/linux/jffs2.h 2004-11-19 10:25:12.139163312 +0100
-@@ -1,50 +1,30 @@
- /*
- * JFFS2 -- Journalling Flash File System, Version 2.
- *
-- * Copyright (C) 2001 Red Hat, Inc.
-+ * Copyright (C) 2001-2003 Red Hat, Inc.
- *
-- * Created by David Woodhouse <dwmw2@cambridge.redhat.com>
-+ * Created by David Woodhouse <dwmw2@redhat.com>
- *
-- * The original JFFS, from which the design for JFFS2 was derived,
-- * was designed and implemented by Axis Communications AB.
-+ * For licensing information, see the file 'LICENCE' in the
-+ * jffs2 directory.
- *
-- * The contents of this file are subject to the Red Hat eCos Public
-- * License Version 1.1 (the "Licence"); you may not use this file
-- * except in compliance with the Licence. You may obtain a copy of
-- * the Licence at http://www.redhat.com/
-- *
-- * Software distributed under the Licence is distributed on an "AS IS"
-- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.
-- * See the Licence for the specific language governing rights and
-- * limitations under the Licence.
-- *
-- * The Original Code is JFFS2 - Journalling Flash File System, version 2
-- *
-- * Alternatively, the contents of this file may be used under the
-- * terms of the GNU General Public License version 2 (the "GPL"), in
-- * which case the provisions of the GPL are applicable instead of the
-- * above. If you wish to allow the use of your version of this file
-- * only under the terms of the GPL and not to allow others to use your
-- * version of this file under the RHEPL, indicate your decision by
-- * deleting the provisions above and replace them with the notice and
-- * other provisions required by the GPL. If you do not delete the
-- * provisions above, a recipient may use your version of this file
-- * under either the RHEPL or the GPL.
-- *
-- * $Id$
-+ * $Id$
- *
- */
-
- #ifndef __LINUX_JFFS2_H__
- #define __LINUX_JFFS2_H__
-
--#include <asm/types.h>
-+/* You must include something which defines the C99 uintXX_t types.
-+ We don't do it from here because this file is used in too many
-+ different environments. */
-+
- #define JFFS2_SUPER_MAGIC 0x72b6
-
- /* Values we may expect to find in the 'magic' field */
- #define JFFS2_OLD_MAGIC_BITMASK 0x1984
- #define JFFS2_MAGIC_BITMASK 0x1985
--#define KSAMTIB_CIGAM_2SFFJ 0x5981 /* For detecting wrong-endian fs */
-+#define KSAMTIB_CIGAM_2SFFJ 0x8519 /* For detecting wrong-endian fs */
- #define JFFS2_EMPTY_BITMASK 0xffff
- #define JFFS2_DIRTY_BITMASK 0x0000
-
-@@ -78,16 +58,12 @@
- #define JFFS2_NODETYPE_DIRENT (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 1)
- #define JFFS2_NODETYPE_INODE (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 2)
- #define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3)
-+#define JFFS2_NODETYPE_PADDING (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 4)
-
- // Maybe later...
- //#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3)
- //#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4)
-
--/* Same as the non_ECC versions, but with extra space for real
-- * ECC instead of just the checksum. For use on NAND flash
-- */
--//#define JFFS2_NODETYPE_DIRENT_ECC (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 5)
--//#define JFFS2_NODETYPE_INODE_ECC (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 6)
-
- #define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at
- mount time, don't wait for it to
-@@ -96,31 +72,79 @@
- compression type */
-
-
-+/* These can go once we've made sure we've caught all uses without
-+ byteswapping */
-+
-+typedef struct {
-+ uint32_t v32;
-+} __attribute__((packed)) jint32_t;
-+
-+typedef struct {
-+ uint32_t m;
-+} __attribute__((packed)) jmode_t;
-+
-+typedef struct {
-+ uint16_t v16;
-+} __attribute__((packed)) jint16_t;
-+
-+#define JFFS2_NATIVE_ENDIAN
-+
-+/* Note we handle mode bits conversion from JFFS2 (i.e. Linux) to/from
-+ whatever OS we're actually running on here too. */
-+
-+#if defined(JFFS2_NATIVE_ENDIAN)
-+#define cpu_to_je16(x) ((jint16_t){x})
-+#define cpu_to_je32(x) ((jint32_t){x})
-+#define cpu_to_jemode(x) ((jmode_t){os_to_jffs2_mode(x)})
-+
-+#define je16_to_cpu(x) ((x).v16)
-+#define je32_to_cpu(x) ((x).v32)
-+#define jemode_to_cpu(x) (jffs2_to_os_mode((x).m))
-+#elif defined(JFFS2_BIG_ENDIAN)
-+#define cpu_to_je16(x) ((jint16_t){cpu_to_be16(x)})
-+#define cpu_to_je32(x) ((jint32_t){cpu_to_be32(x)})
-+#define cpu_to_jemode(x) ((jmode_t){cpu_to_be32(os_to_jffs2_mode(x))})
-+
-+#define je16_to_cpu(x) (be16_to_cpu(x.v16))
-+#define je32_to_cpu(x) (be32_to_cpu(x.v32))
-+#define jemode_to_cpu(x) (be32_to_cpu(jffs2_to_os_mode((x).m)))
-+#elif defined(JFFS2_LITTLE_ENDIAN)
-+#define cpu_to_je16(x) ((jint16_t){cpu_to_le16(x)})
-+#define cpu_to_je32(x) ((jint32_t){cpu_to_le32(x)})
-+#define cpu_to_jemode(x) ((jmode_t){cpu_to_le32(os_to_jffs2_mode(x))})
-+
-+#define je16_to_cpu(x) (le16_to_cpu(x.v16))
-+#define je32_to_cpu(x) (le32_to_cpu(x.v32))
-+#define jemode_to_cpu(x) (le32_to_cpu(jffs2_to_os_mode((x).m)))
-+#else
-+#error wibble
-+#endif
-+
- struct jffs2_unknown_node
- {
- /* All start like this */
-- __u16 magic;
-- __u16 nodetype;
-- __u32 totlen; /* So we can skip over nodes we don't grok */
-- __u32 hdr_crc;
-+ jint16_t magic;
-+ jint16_t nodetype;
-+ jint32_t totlen; /* So we can skip over nodes we don't grok */
-+ jint32_t hdr_crc;
- } __attribute__((packed));
-
- struct jffs2_raw_dirent
- {
-- __u16 magic;
-- __u16 nodetype; /* == JFFS_NODETYPE_DIRENT */
-- __u32 totlen;
-- __u32 hdr_crc;
-- __u32 pino;
-- __u32 version;
-- __u32 ino; /* == zero for unlink */
-- __u32 mctime;
-- __u8 nsize;
-- __u8 type;
-- __u8 unused[2];
-- __u32 node_crc;
-- __u32 name_crc;
-- __u8 name[0];
-+ jint16_t magic;
-+ jint16_t nodetype; /* == JFFS_NODETYPE_DIRENT */
-+ jint32_t totlen;
-+ jint32_t hdr_crc;
-+ jint32_t pino;
-+ jint32_t version;
-+ jint32_t ino; /* == zero for unlink */
-+ jint32_t mctime;
-+ uint8_t nsize;
-+ uint8_t type;
-+ uint8_t unused[2];
-+ jint32_t node_crc;
-+ jint32_t name_crc;
-+ uint8_t name[0];
- } __attribute__((packed));
-
- /* The JFFS2 raw inode structure: Used for storage on physical media. */
-@@ -131,28 +155,28 @@
- */
- struct jffs2_raw_inode
- {
-- __u16 magic; /* A constant magic number. */
-- __u16 nodetype; /* == JFFS_NODETYPE_INODE */
-- __u32 totlen; /* Total length of this node (inc data, etc.) */
-- __u32 hdr_crc;
-- __u32 ino; /* Inode number. */
-- __u32 version; /* Version number. */
-- __u32 mode; /* The file's type or mode. */
-- __u16 uid; /* The file's owner. */
-- __u16 gid; /* The file's group. */
-- __u32 isize; /* Total resultant size of this inode (used for truncations) */
-- __u32 atime; /* Last access time. */
-- __u32 mtime; /* Last modification time. */
-- __u32 ctime; /* Change time. */
-- __u32 offset; /* Where to begin to write. */
-- __u32 csize; /* (Compressed) data size */
-- __u32 dsize; /* Size of the node's data. (after decompression) */
-- __u8 compr; /* Compression algorithm used */
-- __u8 usercompr; /* Compression algorithm requested by the user */
-- __u16 flags; /* See JFFS2_INO_FLAG_* */
-- __u32 data_crc; /* CRC for the (compressed) data. */
-- __u32 node_crc; /* CRC for the raw inode (excluding data) */
--// __u8 data[dsize];
-+ jint16_t magic; /* A constant magic number. */
-+ jint16_t nodetype; /* == JFFS_NODETYPE_INODE */
-+ jint32_t totlen; /* Total length of this node (inc data, etc.) */
-+ jint32_t hdr_crc;
-+ jint32_t ino; /* Inode number. */
-+ jint32_t version; /* Version number. */
-+ jmode_t mode; /* The file's type or mode. */
-+ jint16_t uid; /* The file's owner. */
-+ jint16_t gid; /* The file's group. */
-+ jint32_t isize; /* Total resultant size of this inode (used for truncations) */
-+ jint32_t atime; /* Last access time. */
-+ jint32_t mtime; /* Last modification time. */
-+ jint32_t ctime; /* Change time. */
-+ jint32_t offset; /* Where to begin to write. */
-+ jint32_t csize; /* (Compressed) data size */
-+ jint32_t dsize; /* Size of the node's data. (after decompression) */
-+ uint8_t compr; /* Compression algorithm used */
-+ uint8_t usercompr; /* Compression algorithm requested by the user */
-+ jint16_t flags; /* See JFFS2_INO_FLAG_* */
-+ jint32_t data_crc; /* CRC for the (compressed) data. */
-+ jint32_t node_crc; /* CRC for the raw inode (excluding data) */
-+ uint8_t data[0];
- } __attribute__((packed));
-
- union jffs2_node_union {
-diff -Nurb linux-mips-2.4.27/include/linux/jffs2_fs_i.h linux/include/linux/jffs2_fs_i.h
---- linux-mips-2.4.27/include/linux/jffs2_fs_i.h 2001-10-19 03:25:03.000000000 +0200
-+++ linux/include/linux/jffs2_fs_i.h 2004-11-19 10:25:12.141163008 +0100
-@@ -1,22 +1,12 @@
--/* $Id$ */
-+/* $Id$ */
-
- #ifndef _JFFS2_FS_I
- #define _JFFS2_FS_I
-
--/* Include the pipe_inode_info at the beginning so that we can still
-- use the storage space in the inode when we have a pipe inode.
-- This sucks.
--*/
--
--#undef THISSUCKS /* Only for 2.2 */
--#ifdef THISSUCKS
--#include <linux/pipe_fs_i.h>
--#endif
-+#include <linux/version.h>
-+#include <linux/rbtree.h>
-
- struct jffs2_inode_info {
--#ifdef THISSUCKS
-- struct pipe_inode_info pipecrap;
--#endif
- /* We need an internal semaphore similar to inode->i_sem.
- Unfortunately, we can't used the existing one, because
- either the GC would deadlock, or we'd have to release it
-@@ -26,10 +16,10 @@
- struct semaphore sem;
-
- /* The highest (datanode) version number used for this ino */
-- __u32 highest_version;
-+ uint32_t highest_version;
-
- /* List of data fragments which make up the file */
-- struct jffs2_node_frag *fraglist;
-+ struct rb_root fragtree;
-
- /* There may be one datanode which isn't referenced by any of the
- above fragments, if it contains a metadata update but no actual
-@@ -44,19 +34,13 @@
- /* Some stuff we just have to keep in-core at all times, for each inode. */
- struct jffs2_inode_cache *inocache;
-
-- /* Keep a pointer to the last physical node in the list. We don't
-- use the doubly-linked lists because we don't want to increase
-- the memory usage that much. This is simpler */
-- // struct jffs2_raw_node_ref *lastnode;
-- __u16 flags;
-- __u8 usercompr;
--};
--
--#ifdef JFFS2_OUT_OF_KERNEL
--#define JFFS2_INODE_INFO(i) ((struct jffs2_inode_info *) &(i)->u)
--#else
--#define JFFS2_INODE_INFO(i) (&i->u.jffs2_i)
-+ uint16_t flags;
-+ uint8_t usercompr;
-+#if !defined (__ECOS)
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
-+ struct inode vfs_inode;
- #endif
-+#endif
-+};
-
- #endif /* _JFFS2_FS_I */
--
-diff -Nurb linux-mips-2.4.27/include/linux/jffs2_fs_sb.h linux/include/linux/jffs2_fs_sb.h
---- linux-mips-2.4.27/include/linux/jffs2_fs_sb.h 2002-06-27 00:36:46.000000000 +0200
-+++ linux/include/linux/jffs2_fs_sb.h 2004-11-19 10:25:12.142162856 +0100
-@@ -1,19 +1,22 @@
--/* $Id$ */
-+/* $Id$ */
-
- #ifndef _JFFS2_FS_SB
- #define _JFFS2_FS_SB
-
- #include <linux/types.h>
- #include <linux/spinlock.h>
-+#include <linux/workqueue.h>
- #include <linux/completion.h>
- #include <asm/semaphore.h>
-+#include <linux/timer.h>
-+#include <linux/wait.h>
- #include <linux/list.h>
-
--#define INOCACHE_HASHSIZE 1
--
- #define JFFS2_SB_FLAG_RO 1
- #define JFFS2_SB_FLAG_MOUNTING 2
-
-+struct jffs2_inodirty;
-+
- /* A struct for the overall file system control. Pointers to
- jffs2_sb_info structs are named `c' in the source code.
- Nee jffs_control
-@@ -21,36 +24,46 @@
- struct jffs2_sb_info {
- struct mtd_info *mtd;
-
-- __u32 highest_ino;
-+ uint32_t highest_ino;
-+ uint32_t checked_ino;
-+
- unsigned int flags;
-- spinlock_t nodelist_lock;
-
-- // pid_t thread_pid; /* GC thread's PID */
- struct task_struct *gc_task; /* GC task struct */
- struct semaphore gc_thread_start; /* GC thread start mutex */
- struct completion gc_thread_exit; /* GC thread exit completion port */
-- // __u32 gc_minfree_threshold; /* GC trigger thresholds */
-- // __u32 gc_maxdirty_threshold;
-
- struct semaphore alloc_sem; /* Used to protect all the following
- fields, and also to protect against
- out-of-order writing of nodes.
- And GC.
- */
-- __u32 flash_size;
-- __u32 used_size;
-- __u32 dirty_size;
-- __u32 free_size;
-- __u32 erasing_size;
-- __u32 bad_size;
-- __u32 sector_size;
-- // __u32 min_free_size;
-- // __u32 max_chunk_size;
-+ uint32_t cleanmarker_size; /* Size of an _inline_ CLEANMARKER
-+ (i.e. zero for OOB CLEANMARKER */
-+
-+ uint32_t flash_size;
-+ uint32_t used_size;
-+ uint32_t dirty_size;
-+ uint32_t wasted_size;
-+ uint32_t free_size;
-+ uint32_t erasing_size;
-+ uint32_t bad_size;
-+ uint32_t sector_size;
-+ uint32_t unchecked_size;
-+
-+ uint32_t nr_free_blocks;
-+ uint32_t nr_erasing_blocks;
-+
-+ /* Number of free blocks there must be before we... */
-+ uint8_t resv_blocks_write; /* ... allow a normal filesystem write */
-+ uint8_t resv_blocks_deletion; /* ... allow a normal filesystem deletion */
-+ uint8_t resv_blocks_gctrigger; /* ... wake up the GC thread */
-+ uint8_t resv_blocks_gcbad; /* ... pick a block from the bad_list to GC */
-+ uint8_t resv_blocks_gcmerge; /* ... merge pages when garbage collecting */
-
-- __u32 nr_free_blocks;
-- __u32 nr_erasing_blocks;
-+ uint32_t nospc_dirty_size;
-
-- __u32 nr_blocks;
-+ uint32_t nr_blocks;
- struct jffs2_eraseblock *blocks; /* The whole array of blocks. Used for getting blocks
- * from the offset (blocks[ofs / sector_size]) */
- struct jffs2_eraseblock *nextblock; /* The block we're currently filling */
-@@ -58,9 +71,12 @@
- struct jffs2_eraseblock *gcblock; /* The block we're currently garbage-collecting */
-
- struct list_head clean_list; /* Blocks 100% full of clean data */
-+ struct list_head very_dirty_list; /* Blocks with lots of dirty space */
- struct list_head dirty_list; /* Blocks with some dirty space */
-+ struct list_head erasable_list; /* Blocks which are completely dirty, and need erasing */
-+ struct list_head erasable_pending_wbuf_list; /* Blocks which need erasing but only after the current wbuf is flushed */
- struct list_head erasing_list; /* Blocks which are currently erasing */
-- struct list_head erase_pending_list; /* Blocks which need erasing */
-+ struct list_head erase_pending_list; /* Blocks which need erasing now */
- struct list_head erase_complete_list; /* Blocks which are erased and need the clean marker written to them */
- struct list_head free_list; /* Blocks which are free and ready to be used */
- struct list_head bad_list; /* Bad blocks. */
-@@ -69,16 +85,33 @@
- spinlock_t erase_completion_lock; /* Protect free_list and erasing_list
- against erase completion handler */
- wait_queue_head_t erase_wait; /* For waiting for erases to complete */
-- struct jffs2_inode_cache *inocache_list[INOCACHE_HASHSIZE];
-+
-+ wait_queue_head_t inocache_wq;
-+ struct jffs2_inode_cache **inocache_list;
- spinlock_t inocache_lock;
--};
-
--#ifdef JFFS2_OUT_OF_KERNEL
--#define JFFS2_SB_INFO(sb) ((struct jffs2_sb_info *) &(sb)->u)
--#else
--#define JFFS2_SB_INFO(sb) (&sb->u.jffs2_sb)
-+ /* Sem to allow jffs2_garbage_collect_deletion_dirent to
-+ drop the erase_completion_lock while it's holding a pointer
-+ to an obsoleted node. I don't like this. Alternatives welcomed. */
-+ struct semaphore erase_free_sem;
-+
-+#ifdef CONFIG_JFFS2_FS_NAND
-+ /* Write-behind buffer for NAND flash */
-+ unsigned char *wbuf;
-+ uint32_t wbuf_ofs;
-+ uint32_t wbuf_len;
-+ uint32_t wbuf_pagesize;
-+ struct jffs2_inodirty *wbuf_inodes;
-+
-+ /* Information about out-of-band area usage... */
-+ struct nand_oobinfo *oobinfo;
-+ uint32_t badblock_pos;
-+ uint32_t fsdata_pos;
-+ uint32_t fsdata_len;
- #endif
-
--#define OFNI_BS_2SFFJ(c) ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->u)) ) )
-+ /* OS-private pointer for getting back to master superblock info */
-+ void *os_priv;
-+};
-
- #endif /* _JFFS2_FB_SB */
-diff -Nurb linux-mips-2.4.27/include/linux/mtd/blktrans.h linux/include/linux/mtd/blktrans.h
---- linux-mips-2.4.27/include/linux/mtd/blktrans.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/include/linux/mtd/blktrans.h 2004-11-19 10:25:12.037178816 +0100
-@@ -0,0 +1,72 @@
-+/*
-+ * $Id$
-+ *
-+ * (C) 2003 David Woodhouse <dwmw2@infradead.org>
-+ *
-+ * Interface to Linux block layer for MTD 'translation layers'.
-+ *
-+ */
-+
-+#ifndef __MTD_TRANS_H__
-+#define __MTD_TRANS_H__
-+
-+#include <asm/semaphore.h>
-+
-+struct hd_geometry;
-+struct mtd_info;
-+struct mtd_blktrans_ops;
-+struct file;
-+struct inode;
-+
-+struct mtd_blktrans_dev {
-+ struct mtd_blktrans_ops *tr;
-+ struct list_head list;
-+ struct mtd_info *mtd;
-+ struct semaphore sem;
-+ int devnum;
-+ int blksize;
-+ unsigned long size;
-+ int readonly;
-+ void *blkcore_priv; /* gendisk in 2.5, devfs_handle in 2.4 */
-+};
-+
-+struct blkcore_priv; /* Differs for 2.4 and 2.5 kernels; private */
-+
-+struct mtd_blktrans_ops {
-+ char *name;
-+ int major;
-+ int part_bits;
-+
-+ /* Access functions */
-+ int (*readsect)(struct mtd_blktrans_dev *dev,
-+ unsigned long block, char *buffer);
-+ int (*writesect)(struct mtd_blktrans_dev *dev,
-+ unsigned long block, char *buffer);
-+
-+ /* Block layer ioctls */
-+ int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo);
-+ int (*flush)(struct mtd_blktrans_dev *dev);
-+
-+ /* Called with mtd_table_mutex held; no race with add/remove */
-+ int (*open)(struct mtd_blktrans_dev *dev);
-+ int (*release)(struct mtd_blktrans_dev *dev);
-+
-+ /* Called on {de,}registration and on subsequent addition/removal
-+ of devices, with mtd_table_mutex held. */
-+ void (*add_mtd)(struct mtd_blktrans_ops *tr, struct mtd_info *mtd);
-+ void (*remove_dev)(struct mtd_blktrans_dev *dev);
-+
-+ struct list_head devs;
-+ struct list_head list;
-+ struct module *owner;
-+
-+ struct mtd_blkcore_priv *blkcore_priv;
-+};
-+
-+extern int register_mtd_blktrans(struct mtd_blktrans_ops *tr);
-+extern int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr);
-+extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
-+extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
-+
-+
-+#endif /* __MTD_TRANS_H__ */
-diff -Nurb linux-mips-2.4.27/include/linux/mtd/cfi.h linux/include/linux/mtd/cfi.h
---- linux-mips-2.4.27/include/linux/mtd/cfi.h 2003-02-26 01:53:51.000000000 +0100
-+++ linux/include/linux/mtd/cfi.h 2004-11-19 10:25:12.038178664 +0100
-@@ -1,13 +1,14 @@
-
- /* Common Flash Interface structures
- * See http://support.intel.com/design/flash/technote/index.htm
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __MTD_CFI_H__
- #define __MTD_CFI_H__
-
- #include <linux/config.h>
-+#include <linux/version.h>
- #include <linux/delay.h>
- #include <linux/types.h>
- #include <linux/interrupt.h>
-@@ -260,7 +261,8 @@
- __u8 pri[3];
- __u8 MajorVersion;
- __u8 MinorVersion;
-- __u32 FeatureSupport;
-+ __u32 FeatureSupport; /* if bit 31 is set then an additional __u32 feature
-+ block follows - FIXME - not currently supported */
- __u8 SuspendCmdSupport;
- __u16 BlkStatusRegMask;
- __u8 VccOptimal;
-@@ -271,6 +273,25 @@
- __u8 UserProtRegSize;
- } __attribute__((packed));
-
-+/* Vendor-Specific PRI for AMD/Fujitsu Extended Command Set (0x0002) */
-+
-+struct cfi_pri_amdstd {
-+ __u8 pri[3];
-+ __u8 MajorVersion;
-+ __u8 MinorVersion;
-+ __u8 SiliconRevision; /* bits 1-0: Address Sensitive Unlock */
-+ __u8 EraseSuspend;
-+ __u8 BlkProt;
-+ __u8 TmpBlkUnprotect;
-+ __u8 BlkProtUnprot;
-+ __u8 SimultaneousOps;
-+ __u8 BurstMode;
-+ __u8 PageMode;
-+ __u8 VppMin;
-+ __u8 VppMax;
-+ __u8 TopBottom;
-+} __attribute__((packed));
-+
- struct cfi_pri_query {
- __u8 NumFields;
- __u32 ProtField[1]; /* Not host ordered */
-@@ -314,8 +335,6 @@
- struct flchip chips[0]; /* per-chip data structure for each chip */
- };
-
--#define MAX_CFI_CHIPS 8 /* Entirely arbitrary to avoid realloc() */
--
- /*
- * Returns the command address according to the given geometry.
- */
-@@ -387,13 +406,13 @@
- static inline cfi_word cfi_read(struct map_info *map, __u32 addr)
- {
- if (cfi_buswidth_is_1()) {
-- return map->read8(map, addr);
-+ return map_read8(map, addr);
- } else if (cfi_buswidth_is_2()) {
-- return map->read16(map, addr);
-+ return map_read16(map, addr);
- } else if (cfi_buswidth_is_4()) {
-- return map->read32(map, addr);
-+ return map_read32(map, addr);
- } else if (cfi_buswidth_is_8()) {
-- return map->read64(map, addr);
-+ return map_read64(map, addr);
- } else {
- return 0;
- }
-@@ -406,13 +425,13 @@
- static inline void cfi_write(struct map_info *map, cfi_word val, __u32 addr)
- {
- if (cfi_buswidth_is_1()) {
-- map->write8(map, val, addr);
-+ map_write8(map, val, addr);
- } else if (cfi_buswidth_is_2()) {
-- map->write16(map, val, addr);
-+ map_write16(map, val, addr);
- } else if (cfi_buswidth_is_4()) {
-- map->write32(map, val, addr);
-+ map_write32(map, val, addr);
- } else if (cfi_buswidth_is_8()) {
-- map->write64(map, val, addr);
-+ map_write64(map, val, addr);
- }
- }
-
-@@ -443,13 +462,13 @@
- static inline __u8 cfi_read_query(struct map_info *map, __u32 addr)
- {
- if (cfi_buswidth_is_1()) {
-- return map->read8(map, addr);
-+ return map_read8(map, addr);
- } else if (cfi_buswidth_is_2()) {
-- return cfi16_to_cpu(map->read16(map, addr));
-+ return cfi16_to_cpu(map_read16(map, addr));
- } else if (cfi_buswidth_is_4()) {
-- return cfi32_to_cpu(map->read32(map, addr));
-+ return cfi32_to_cpu(map_read32(map, addr));
- } else if (cfi_buswidth_is_8()) {
-- return cfi64_to_cpu(map->read64(map, addr));
-+ return cfi64_to_cpu(map_read64(map, addr));
- } else {
- return 0;
- }
-@@ -479,5 +498,19 @@
- spin_unlock_bh(mutex);
- }
-
-+struct cfi_extquery *cfi_read_pri(struct map_info *map, __u16 adr, __u16 size,
-+ const char* name);
-+
-+struct cfi_fixup {
-+ __u16 mfr;
-+ __u16 id;
-+ void (*fixup)(struct map_info *map, void* param);
-+ void* param;
-+};
-+
-+#define CFI_MFR_ANY 0xffff
-+#define CFI_ID_ANY 0xffff
-+
-+void cfi_fixup(struct map_info *map, struct cfi_fixup* fixups);
-
- #endif /* __MTD_CFI_H__ */
-diff -Nurb linux-mips-2.4.27/include/linux/mtd/compatmac.h linux/include/linux/mtd/compatmac.h
---- linux-mips-2.4.27/include/linux/mtd/compatmac.h 2003-02-26 01:53:51.000000000 +0100
-+++ linux/include/linux/mtd/compatmac.h 2004-11-19 10:25:12.041178208 +0100
-@@ -1,573 +1,152 @@
--
- /*
-- * mtd/include/compatmac.h
-- *
-- * $Id$
-+ * $Id$
- *
- * Extensions and omissions from the normal 'linux/compatmac.h'
- * files. hopefully this will end up empty as the 'real' one
- * becomes fully-featured.
- */
-
--
--/* First, include the parts which the kernel is good enough to provide
-- * to us
-- */
--
- #ifndef __LINUX_MTD_COMPATMAC_H__
- #define __LINUX_MTD_COMPATMAC_H__
-
--#include <linux/config.h>
--#include <linux/module.h>
--#ifndef LINUX_VERSION_CODE
- #include <linux/version.h>
--#endif
--
--#ifndef VERSION_CODE
--# define VERSION_CODE(vers,rel,seq) ( ((vers)<<16) | ((rel)<<8) | (seq) )
--#endif
--#ifndef KERNEL_VERSION
--# define KERNEL_VERSION(a,b,c) VERSION_CODE(a,b,c)
--#endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,0,0)
--# error "This kernel is too old: not supported by this file"
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
--#include <linux/types.h> /* used later in this header */
--
--#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
--#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
--
--typedef struct wait_queue * wait_queue_head_t;
--
--#define DECLARE_WAITQUEUE(x,y) struct wait_queue x = {y,NULL}
--#define DECLARE_WAIT_QUEUE_HEAD(x) struct wait_queue *x = NULL
--#define init_waitqueue_head init_waitqueue
--#define DECLARE_MUTEX(x) struct semaphore x = MUTEX
--#define DECLARE_MUTEX_LOCKED(x) struct semaphore x = MUTEX_LOCKED
--
--/* from sysdep-2.1.h */
--# include <asm/segment.h>
--# define access_ok(t,a,sz) (verify_area((t),(a),(sz)) ? 0 : 1)
--# define verify_area_20 verify_area
--# define copy_to_user(t,f,n) (memcpy_tofs(t,f,n), 0)
--# define __copy_to_user(t,f,n) copy_to_user((t),(f),(n))
--# define copy_to_user_ret(t,f,n,r) copy_to_user((t),(f),(n))
--# define copy_from_user(t,f,n) (memcpy_fromfs((t),(f),(n)), 0)
--# define __copy_from_user(t,f,n) copy_from_user((t),(f),(n))
--# define copy_from_user_ret(t,f,n,r) copy_from_user((t),(f),(n))
--//xxx # define PUT_USER(val,add) (put_user((val),(add)), 0)
--# define Put_user(val,add) (put_user((val),(add)), 0)
--# define __PUT_USER(val,add) PUT_USER((val),(add))
--# define PUT_USER_RET(val,add,ret) PUT_USER((val),(add))
--# define GET_USER(dest,add) ((dest)=get_user((add)), 0)
--# define __GET_USER(dest,add) GET_USER((dest),(add))
--# define GET_USER_RET(dest,add,ret) GET_USER((dest),(add))
--
--#define ioremap(offset,size) vremap(offset,size)
--#define iounmap(adr) /* */
--
--#define EXPORT_SYMBOL(s) /* */
--#define EXPORT_SYMBOL_NOVERS(s) /* */
--
--/* 2.1.10 and 2.1.43 introduced new functions. They are worth using */
--
--#if LINUX_VERSION_CODE < VERSION_CODE(2,1,10)
--
--# include <asm/byteorder.h>
--# ifdef __LITTLE_ENDIAN
--# define cpu_to_le16(x) (x)
--# define cpu_to_le32(x) (x)
--# define cpu_to_be16(x) htons((x))
--# define cpu_to_be32(x) htonl((x))
--# else
--# define cpu_to_be16(x) (x)
--# define cpu_to_be32(x) (x)
-- extern inline __u16 cpu_to_le16(__u16 x) { return (x<<8) | (x>>8);}
-- extern inline __u32 cpu_to_le32(__u32 x) { return((x>>24) |
-- ((x>>8)&0xff00) | ((x<<8)&0xff0000) | (x<<24));}
--# endif
--
--# define le16_to_cpu(x) cpu_to_le16(x)
--# define le32_to_cpu(x) cpu_to_le32(x)
--# define be16_to_cpu(x) cpu_to_be16(x)
--# define be32_to_cpu(x) cpu_to_be32(x)
--
--#endif
--
--#if LINUX_VERSION_CODE < VERSION_CODE(2,1,43)
--# define cpu_to_le16p(addr) (cpu_to_le16(*(addr)))
--# define cpu_to_le32p(addr) (cpu_to_le32(*(addr)))
--# define cpu_to_be16p(addr) (cpu_to_be16(*(addr)))
--# define cpu_to_be32p(addr) (cpu_to_be32(*(addr)))
--
-- extern inline void cpu_to_le16s(__u16 *a) {*a = cpu_to_le16(*a);}
-- extern inline void cpu_to_le32s(__u16 *a) {*a = cpu_to_le32(*a);}
-- extern inline void cpu_to_be16s(__u16 *a) {*a = cpu_to_be16(*a);}
-- extern inline void cpu_to_be32s(__u16 *a) {*a = cpu_to_be32(*a);}
--
--# define le16_to_cpup(x) cpu_to_le16p(x)
--# define le32_to_cpup(x) cpu_to_le32p(x)
--# define be16_to_cpup(x) cpu_to_be16p(x)
--# define be32_to_cpup(x) cpu_to_be32p(x)
--
--# define le16_to_cpus(x) cpu_to_le16s(x)
--# define le32_to_cpus(x) cpu_to_le32s(x)
--# define be16_to_cpus(x) cpu_to_be16s(x)
--# define be32_to_cpus(x) cpu_to_be32s(x)
--#endif
--
--// from 2.2, linux/types.h
--#ifndef __BIT_TYPES_DEFINED__
--#define __BIT_TYPES_DEFINED__
--
--typedef __u8 u_int8_t;
--typedef __s8 int8_t;
--typedef __u16 u_int16_t;
--typedef __s16 int16_t;
--typedef __u32 u_int32_t;
--typedef __s32 int32_t;
--
--#endif /* !(__BIT_TYPES_DEFINED__) */
--
--#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
-- typedef struct { } spinlock_t;
-- #define SPIN_LOCK_UNLOCKED (spinlock_t) { }
--#else
-- typedef struct { int gcc_is_buggy; } spinlock_t;
-- #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
--#endif
--
--#define spin_lock_init(lock) do { } while(0)
--#define spin_lock(lock) (void)(lock) /* Not "unused variable". */
--#define spin_trylock(lock) (1)
--#define spin_unlock_wait(lock) do { } while(0)
--#define spin_unlock(lock) do { } while(0)
--#define spin_lock_irq(lock) cli()
--#define spin_unlock_irq(lock) sti()
--
--#define spin_lock_irqsave(lock, flags) \
-- do { save_flags(flags); cli(); } while (0)
--#define spin_unlock_irqrestore(lock, flags) \
-- restore_flags(flags)
--
--// Doesn't work when tqueue.h is included.
--// #define queue_task queue_task_irq_off
--#define tty_flip_buffer_push(tty) queue_task_irq_off(&tty->flip.tqueue, &tq_timer)
--#define signal_pending(current) (current->signal & ~current->blocked)
--#define schedule_timeout(to) do {current->timeout = jiffies + (to);schedule ();} while (0)
--#define time_after(t1,t2) (((long)t1-t2) > 0)
--
--#else
-- #include <linux/compatmac.h>
--#endif // LINUX_VERSION_CODE < 0x020100
--
--
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
--#include <linux/vmalloc.h>
--#endif
--
--/* Modularization issues */
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,18)
--# define __USE_OLD_SYMTAB__
--# define EXPORT_NO_SYMBOLS register_symtab(NULL);
--# define REGISTER_SYMTAB(tab) register_symtab(tab)
--#else
--# define REGISTER_SYMTAB(tab) /* nothing */
--#endif
--
--#ifdef __USE_OLD_SYMTAB__
--# define __MODULE_STRING(s) /* nothing */
--# define MODULE_PARM(v,t) /* nothing */
--# define MODULE_PARM_DESC(v,t) /* nothing */
--# define MODULE_AUTHOR(n) /* nothing */
--# define MODULE_DESCRIPTION(d) /* nothing */
--# define MODULE_SUPPORTED_DEVICE(n) /* nothing */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)
-+#error "This kernel is too old: not supported by this file"
- #endif
-
--/*
-- * "select" changed in 2.1.23. The implementation is twin, but this
-- * header is new
-- */
--#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,22)
--# include <linux/poll.h>
--#else
--# define __USE_OLD_SELECT__
--#endif
-+ /* O(1) scheduler stuff. */
-
--/* Other change in the fops are solved using pseudo-types */
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
--# define lseek_t long long
--# define lseek_off_t long long
--#else
--# define lseek_t int
--# define lseek_off_t off_t
--#endif
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,5) && !defined(__rh_config_h__)
-+#include <linux/sched.h>
-+static inline void __recalc_sigpending(void)
-+{
-+ recalc_sigpending(current);
-+}
-+#undef recalc_sigpending
-+#define recalc_sigpending() __recalc_sigpending ()
-
--/* changed the prototype of read/write */
-+#define set_user_nice(tsk, n) do { (tsk)->nice = n; } while(0)
-
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) || defined(__alpha__)
--# define count_t unsigned long
--# define read_write_t long
--#else
--# define count_t int
--# define read_write_t int
- #endif
-
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,31)
--# define release_t void
--# define release_return(x) return
--#else
--# define release_t int
--# define release_return(x) return (x)
--#endif
--
--#if LINUX_VERSION_CODE < 0x20300
--#define __exit
--#endif
--#if LINUX_VERSION_CODE < 0x20200
--#define __init
--#else
--#include <linux/init.h>
--#endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
--#define init_MUTEX(x) do {*(x) = MUTEX;} while (0)
--#define init_MUTEX_LOCKED(x) do {*(x) = MUTEX_LOCKED;} while (0)
--#endif
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20)
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
--#define RQFUNC_ARG void
--#define blkdev_dequeue_request(req) do {CURRENT = req->next;} while (0)
--#else
--#define RQFUNC_ARG request_queue_t *q
-+#ifndef yield
-+#define yield() do { set_current_state(TASK_RUNNING); schedule(); } while(0)
- #endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,32)
--#define blk_cleanup_queue(nr) do {blk_dev[nr].request_fn = 0;} while(0)
--#define BLK_DEFAULT_QUEUE(nr) (blk_dev[nr].request_fn)
--#define blk_init_queue(q, rq) do {q = rq;} while(0)
-+#ifndef minor
-+#define major(d) (MAJOR(to_kdev_t(d)))
-+#define minor(d) (MINOR(to_kdev_t(d)))
- #endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0)
--#ifdef CONFIG_MODULES
--#define __MOD_INC_USE_COUNT(mod) \
-- (atomic_inc(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED|MOD_USED_ONCE)
--#define __MOD_DEC_USE_COUNT(mod) \
-- (atomic_dec(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED)
--#else
--#define __MOD_INC_USE_COUNT(mod)
--#define __MOD_DEC_USE_COUNT(mod)
--#endif
-+#ifndef mk_kdev
-+#define mk_kdev(ma,mi) MKDEV(ma,mi)
-+#define kdev_t_to_nr(x) (x)
- #endif
-
-+#define need_resched() (current->need_resched)
-+#define cond_resched() do { if need_resched() { yield(); } } while(0)
-
--#ifndef HAVE_INTER_MODULE
--static inline void *inter_module_get(char *x) {return NULL;}
--static inline void *inter_module_get_request(char *x, char *y) {return NULL;}
--static inline void inter_module_put(const char *x) {}
--static inline void inter_module_register(const char *x, struct module *y, const void *z) {}
--static inline void inter_module_unregister(const char *x) {}
-+#endif /* < 2.4.20 */
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,73)
-+#define iminor(i) minor((i)->i_rdev)
-+#define imajor(i) major((i)->i_rdev)
-+#define old_encode_dev(d) ( (major(d)<<8) | minor(d) )
-+#define old_decode_dev(rdev) (kdev_t_to_nr(mk_kdev((rdev)>>8, (rdev)&0xff)))
-+#define old_valid_dev(d) (1)
- #endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,61)
-
--#define DECLARE_WAIT_QUEUE_HEAD(x) struct wait_queue *x = NULL
--#define init_waitqueue_head init_waitqueue
-+#include <linux/sched.h>
-
-+#ifdef __rh_config_h__
-+#define sigmask_lock sighand->siglock
-+#define sig sighand
- #endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
--
--static inline int try_inc_mod_count(struct module *mod)
-+static inline void __daemonize_modvers(void)
- {
--#ifdef CONFIG_MODULES
-- if (mod)
-- __MOD_INC_USE_COUNT(mod);
--#endif
-- return 1;
--}
--#endif
-+ daemonize();
-
-+ spin_lock_irq(&current->sigmask_lock);
-+ sigfillset(&current->blocked);
-+ recalc_sigpending();
-+ spin_unlock_irq(&current->sigmask_lock);
-+}
-+#undef daemonize
-+#define daemonize(fmt, ...) do { \
-+ snprintf(current->comm, sizeof(current->comm), fmt ,##__VA_ARGS__); \
-+ __daemonize_modvers(); \
-+ } while(0)
-
--/* Yes, I'm aware that it's a fairly ugly hack.
-- Until the __constant_* macros appear in Linus' own kernels, this is
-- the way it has to be done.
-- DW 19/1/00
-- */
--
--#include <asm/byteorder.h>
--
--#ifndef __constant_cpu_to_le16
--
--#ifdef __BIG_ENDIAN
--#define __constant_cpu_to_le64(x) ___swab64((x))
--#define __constant_le64_to_cpu(x) ___swab64((x))
--#define __constant_cpu_to_le32(x) ___swab32((x))
--#define __constant_le32_to_cpu(x) ___swab32((x))
--#define __constant_cpu_to_le16(x) ___swab16((x))
--#define __constant_le16_to_cpu(x) ___swab16((x))
--#define __constant_cpu_to_be64(x) ((__u64)(x))
--#define __constant_be64_to_cpu(x) ((__u64)(x))
--#define __constant_cpu_to_be32(x) ((__u32)(x))
--#define __constant_be32_to_cpu(x) ((__u32)(x))
--#define __constant_cpu_to_be16(x) ((__u16)(x))
--#define __constant_be16_to_cpu(x) ((__u16)(x))
--#else
--#ifdef __LITTLE_ENDIAN
--#define __constant_cpu_to_le64(x) ((__u64)(x))
--#define __constant_le64_to_cpu(x) ((__u64)(x))
--#define __constant_cpu_to_le32(x) ((__u32)(x))
--#define __constant_le32_to_cpu(x) ((__u32)(x))
--#define __constant_cpu_to_le16(x) ((__u16)(x))
--#define __constant_le16_to_cpu(x) ((__u16)(x))
--#define __constant_cpu_to_be64(x) ___swab64((x))
--#define __constant_be64_to_cpu(x) ___swab64((x))
--#define __constant_cpu_to_be32(x) ___swab32((x))
--#define __constant_be32_to_cpu(x) ___swab32((x))
--#define __constant_cpu_to_be16(x) ___swab16((x))
--#define __constant_be16_to_cpu(x) ___swab16((x))
--#else
--#error No (recognised) endianness defined (unless it,s PDP)
--#endif /* __LITTLE_ENDIAN */
--#endif /* __BIG_ENDIAN */
--
--#endif /* ifndef __constant_cpu_to_le16 */
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-- #define mod_init_t int __init
-- #define mod_exit_t void
--#else
-- #define mod_init_t static int __init
-- #define mod_exit_t static void __exit
--#endif
--
--#ifndef THIS_MODULE
--#ifdef MODULE
--#define THIS_MODULE (&__this_module)
--#else
--#define THIS_MODULE (NULL)
--#endif
--#endif
--
--#if LINUX_VERSION_CODE < 0x20300
--#include <linux/interrupt.h>
--#define spin_lock_bh(lock) do {start_bh_atomic();spin_lock(lock);}while(0)
--#define spin_unlock_bh(lock) do {spin_unlock(lock);end_bh_atomic();}while(0)
--#else
--#include <asm/softirq.h>
--#include <linux/spinlock.h>
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)
--#define set_current_state(state_value) \
-- do { current->state = (state_value); } while (0)
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0)
--static inline int invalidate_device(kdev_t dev, int do_sync) {
-+static inline int dequeue_signal_lock(struct task_struct *tsk, sigset_t *mask, siginfo_t *info)
-+{
-+ unsigned long flags;
-+ unsigned long ret;
-
-- if (do_sync)
-- fsync_dev(dev);
-+ spin_lock_irqsave(&current->sigmask_lock, flags);
-+ ret = dequeue_signal(mask, info);
-+ spin_unlock_irqrestore(&current->sigmask_lock, flags);
-
-- invalidate_buffers(dev);
-- return 0;
-+ return ret;
- }
--#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,4,5)
--static inline int invalidate_device(kdev_t dev, int do_sync) {
-- struct super_block *sb = get_super(dev);
-- int res = 0;
-
-- if (do_sync)
-- fsync_dev(dev);
--
-- if (sb)
-- res = invalidate_inodes(sb);
-+static inline int allow_signal(int sig)
-+{
-+ if (sig < 1 || sig > _NSIG)
-+ return -EINVAL;
-
-- invalidate_buffers(dev);
-- return res;
-+ spin_lock_irq(&current->sigmask_lock);
-+ sigdelset(&current->blocked, sig);
-+ recalc_sigpending();
-+ /* Make sure the kernel neither eats it now converts to SIGKILL */
-+ current->sig->action[sig-1].sa.sa_handler = (void *)2;
-+ spin_unlock_irq(&current->sigmask_lock);
-+ return 0;
- }
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)
--#undef min
--#undef max
--#undef min_t
--#undef max_t
--/*
-- * min()/max() macros that also do
-- * strict type-checking.. See the
-- * "unnecessary" pointer comparison.
-- */
--#define min(x,y) ({ \
-- const typeof(x) _x = (x); \
-- const typeof(y) _y = (y); \
-- (void) (&_x == &_y); \
-- _x < _y ? _x : _y; })
--
--#define max(x,y) ({ \
-- const typeof(x) _x = (x); \
-- const typeof(y) _y = (y); \
-- (void) (&_x == &_y); \
-- _x > _y ? _x : _y; })
--
--/*
-- * ..and if you can't take the strict
-- * types, you can specify one yourself.
-- *
-- * Or not use min/max at all, of course.
-- */
--#define min_t(type,x,y) \
-- ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
--#define max_t(type,x,y) \
-- ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,7)
--struct completion {
-- struct semaphore s;
--};
--
--#define complete(c) up(&(c)->s)
--#define wait_for_completion(c) down(&(c)->s)
--#define init_completion(c) init_MUTEX_LOCKED(&(c)->s);
--
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)
--/* This came later */
--#define complete_and_exit(c, r) do { complete(c); do_exit(r); } while(0)
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9) || \
-- (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) && !defined(__rh_config_h__))
-+static inline int disallow_signal(int sig)
-+{
-+ if (sig < 1 || sig > _NSIG)
-+ return -EINVAL;
-
--#include <linux/genhd.h>
-+ spin_lock_irq(&current->sigmask_lock);
-+ sigaddset(&current->blocked, sig);
-+ recalc_sigpending();
-
--static inline void add_gendisk(struct gendisk *gp)
--{
-- gp->next = gendisk_head;
-- gendisk_head = gp;
-+ current->sig->action[sig-1].sa.sa_handler = SIG_DFL;
-+ spin_unlock_irq(&current->sigmask_lock);
-+ return 0;
- }
-
--static inline void del_gendisk(struct gendisk *gp)
--{
-- struct gendisk *gd, **gdp;
-+#undef sighand
-+#undef sigmask_lock
-
-- for (gdp = &gendisk_head; *gdp; gdp = &((*gdp)->next))
-- if (*gdp == gp) {
-- gd = *gdp; *gdp = gd->next;
-- break;
-- }
--}
-+#define PF_FREEZE 0
-+#define refrigerator(x) do { ; } while(0)
- #endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) && defined(MODULE)
-+ /* Module bits */
-
--#define module_init(func) \
--mod_init_t init_module(void) { \
-- return func(); \
--}
-
--#define module_exit(func) \
--mod_exit_t cleanup_module(void) { \
-- return func(); \
--}
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,60)
-+#define try_module_get(m) try_inc_mod_count(m)
-+#define __module_get(m) do { if (!try_inc_mod_count(m)) BUG(); } while(0)
-+#define module_put(m) do { if (m) __MOD_DEC_USE_COUNT((struct module *)(m)); } while(0)
-+#define set_module_owner(x) do { x->owner = THIS_MODULE; } while(0)
- #endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9) || \
-- (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10) && !defined(__rh_config_h__))
--#define MODULE_LICENSE(x) /* */
--#endif
-
--/* Removed for 2.4.21 kernel. This really should have been renamed
-- when it was changed -- this is a PITA */
--#if 0 && LINUX_VERSION_CODE < KERNEL_VERSION(2,5,5)
--#include <linux/sched.h>
--static inline void __recalc_sigpending(void)
--{
-- recalc_sigpending(current);
--}
--#undef recalc_sigpending
--#define recalc_sigpending() __recalc_sigpending ()
--#endif
-+ /* Random filesystem stuff, only for JFFS2 really */
-
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,5)
- #define parent_ino(d) ((d)->d_parent->d_inode->i_ino)
- #endif
-
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,3)
--#define need_resched() (current->need_resched)
--#define cond_resched() do { if need_resched() schedule(); } while(0)
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)
--#ifndef yield
--#define yield() do { set_current_state(TASK_RUNNING); schedule(); } while(0)
--#endif
--#ifndef minor
--#define major(d) (MAJOR(to_kdev_t(d)))
--#define minor(d) (MINOR(to_kdev_t(d)))
--#endif
--#ifndef mk_kdev
--#define mk_kdev(ma,mi) MKDEV(ma,mi)
--#define kdev_t_to_nr(x) (x)
--#endif
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
-- /* Is this right? */
--#define set_user_nice(tsk, n) do { (tsk)->priority = 20-(n); } while(0)
--#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,4,21) && !defined(RED_HAT_LINUX_KERNEL)
--#define set_user_nice(tsk, n) do { (tsk)->nice = n; } while(0)
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,21)
--#define rq_data_dir(x) ((x)->cmd)
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
--
--#define IS_REQ_CMD(req) (1)
--
--#define QUEUE_LOCK(q) (&io_request_lock)
--
--#define BLK_INIT_QUEUE(q, req, lock) blk_init_queue((q), (req))
--
--#else /* > 2.5.0 */
--
--#define IS_REQ_CMD(req) ((req)->flags & REQ_CMD)
--
--#define QUEUE_LOCK(q) ((q)->queue_lock)
--
--#define BLK_INIT_QUEUE(q, req, lock) blk_init_queue((q), (req), (lock))
--
--#endif
--
--/* Removed cos it broke stuff. Where is this required anyway?
-- * #ifndef QUEUE_EMPTY
-- * #define QUEUE_EMPTY (!CURRENT)
-- * #endif
-- */
--#if LINUX_VERSION_CODE < 0x20300
--#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].plug_tq.sync)
--#elif LINUX_VERSION_CODE < 0x20500 //FIXME (Si)
--#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].request_queue.plugged)
--#else
--#define QUEUE_PLUGGED (blk_queue_plugged(QUEUE))
--#endif
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
--#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
--#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
--#else
--#define BLK_INC_USE_COUNT do {} while(0)
--#define BLK_DEC_USE_COUNT do {} while(0)
--#endif
--
- #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,12)
- #define PageUptodate(x) Page_Uptodate(x)
- #endif
-@@ -580,4 +159,31 @@
- #define generic_file_readonly_mmap generic_file_mmap
- #endif
-
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,70)
-+
-+#include <linux/kmod.h>
-+#include <linux/string.h>
-+
-+static inline char *strlcpy(char *dest, const char *src, int len)
-+{
-+ dest[len-1] = 0;
-+ return strncpy(dest, src, len-1);
-+}
-+
-+static inline int do_old_request_module(const char *mod)
-+{
-+ return request_module(mod);
-+}
-+#undef request_module
-+#define request_module(fmt, ...) \
-+ ({ char modname[32]; snprintf(modname, 31, fmt ,##__VA_ARGS__); do_old_request_module(modname); })
-+
-+#endif /* 2.5.70 */
-+
-+#ifndef container_of
-+#define container_of(ptr, type, member) ({ \
-+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
-+ (type *)( (char *)__mptr - offsetof(type,member) );})
-+#endif
-+
- #endif /* __LINUX_MTD_COMPATMAC_H__ */
-diff -Nurb linux-mips-2.4.27/include/linux/mtd/doc2000.h linux/include/linux/mtd/doc2000.h
---- linux-mips-2.4.27/include/linux/mtd/doc2000.h 2001-11-05 21:16:30.000000000 +0100
-+++ linux/include/linux/mtd/doc2000.h 2004-11-19 10:25:12.044177752 +0100
-@@ -1,13 +1,21 @@
--
--/* Linux driver for Disk-On-Chip 2000 */
--/* (c) 1999 Machine Vision Holdings, Inc. */
--/* Author: David Woodhouse <dwmw2@mvhi.com> */
--/* $Id$ */
-+/*
-+ * Linux driver for Disk-On-Chip devices
-+ *
-+ * Copyright (C) 1999 Machine Vision Holdings, Inc.
-+ * Copyright (C) 2001-2003 David Woodhouse <dwmw2@infradead.org>
-+ * Copyright (C) 2002-2003 Greg Ungerer <gerg@snapgear.com>
-+ * Copyright (C) 2002-2003 SnapGear Inc
-+ *
-+ * $Id$
-+ *
-+ * Released under GPL
-+ */
-
- #ifndef __MTD_DOC2000_H__
- #define __MTD_DOC2000_H__
-
- #include <linux/mtd/mtd.h>
-+#include <asm/semaphore.h>
-
- #define DoC_Sig1 0
- #define DoC_Sig2 1
-@@ -38,18 +46,47 @@
- #define DoC_Mil_CDSN_IO 0x0800
- #define DoC_2k_CDSN_IO 0x1800
-
-+#define DoC_Mplus_NOP 0x1002
-+#define DoC_Mplus_AliasResolution 0x1004
-+#define DoC_Mplus_DOCControl 0x1006
-+#define DoC_Mplus_AccessStatus 0x1008
-+#define DoC_Mplus_DeviceSelect 0x1008
-+#define DoC_Mplus_Configuration 0x100a
-+#define DoC_Mplus_OutputControl 0x100c
-+#define DoC_Mplus_FlashControl 0x1020
-+#define DoC_Mplus_FlashSelect 0x1022
-+#define DoC_Mplus_FlashCmd 0x1024
-+#define DoC_Mplus_FlashAddress 0x1026
-+#define DoC_Mplus_FlashData0 0x1028
-+#define DoC_Mplus_FlashData1 0x1029
-+#define DoC_Mplus_ReadPipeInit 0x102a
-+#define DoC_Mplus_LastDataRead 0x102c
-+#define DoC_Mplus_LastDataRead1 0x102d
-+#define DoC_Mplus_WritePipeTerm 0x102e
-+#define DoC_Mplus_ECCSyndrome0 0x1040
-+#define DoC_Mplus_ECCSyndrome1 0x1041
-+#define DoC_Mplus_ECCSyndrome2 0x1042
-+#define DoC_Mplus_ECCSyndrome3 0x1043
-+#define DoC_Mplus_ECCSyndrome4 0x1044
-+#define DoC_Mplus_ECCSyndrome5 0x1045
-+#define DoC_Mplus_ECCConf 0x1046
-+#define DoC_Mplus_Toggle 0x1046
-+#define DoC_Mplus_DownloadStatus 0x1074
-+#define DoC_Mplus_CtrlConfirm 0x1076
-+#define DoC_Mplus_Power 0x1fff
-+
- /* How to access the device?
- * On ARM, it'll be mmap'd directly with 32-bit wide accesses.
- * On PPC, it's mmap'd and 16-bit wide.
- * Others use readb/writeb
- */
- #if defined(__arm__)
--#define ReadDOC_(adr, reg) ((unsigned char)(*(__u32 *)(((unsigned long)adr)+((reg)<<2))))
--#define WriteDOC_(d, adr, reg) do{ *(__u32 *)(((unsigned long)adr)+((reg)<<2)) = (__u32)d; wmb();} while(0)
-+#define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u32 *)(((unsigned long)adr)+((reg)<<2))))
-+#define WriteDOC_(d, adr, reg) do{ *(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)) = (__u32)d; wmb();} while(0)
- #define DOC_IOREMAP_LEN 0x8000
- #elif defined(__ppc__)
--#define ReadDOC_(adr, reg) ((unsigned char)(*(__u16 *)(((unsigned long)adr)+((reg)<<1))))
--#define WriteDOC_(d, adr, reg) do{ *(__u16 *)(((unsigned long)adr)+((reg)<<1)) = (__u16)d; wmb();} while(0)
-+#define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u16 *)(((unsigned long)adr)+((reg)<<1))))
-+#define WriteDOC_(d, adr, reg) do{ *(volatile __u16 *)(((unsigned long)adr)+((reg)<<1)) = (__u16)d; wmb();} while(0)
- #define DOC_IOREMAP_LEN 0x4000
- #else
- #define ReadDOC_(adr, reg) readb(((unsigned long)adr) + (reg))
-@@ -71,13 +108,21 @@
- #define DOC_MODE_RESERVED1 2
- #define DOC_MODE_RESERVED2 3
-
--#define DOC_MODE_MDWREN 4
- #define DOC_MODE_CLR_ERR 0x80
-+#define DOC_MODE_RST_LAT 0x10
-+#define DOC_MODE_BDECT 0x08
-+#define DOC_MODE_MDWREN 0x04
-
- #define DOC_ChipID_Doc2k 0x20
-+#define DOC_ChipID_Doc2kTSOP 0x21 /* internal number for MTD */
- #define DOC_ChipID_DocMil 0x30
-+#define DOC_ChipID_DocMilPlus32 0x40
-+#define DOC_ChipID_DocMilPlus16 0x41
-
- #define CDSN_CTRL_FR_B 0x80
-+#define CDSN_CTRL_FR_B0 0x40
-+#define CDSN_CTRL_FR_B1 0x80
-+
- #define CDSN_CTRL_ECC_IO 0x20
- #define CDSN_CTRL_FLASH_IO 0x10
- #define CDSN_CTRL_WP 0x08
-@@ -93,6 +138,10 @@
- #define DOC_ECC_RESV 0x02
- #define DOC_ECC_IGNORE 0x01
-
-+#define DOC_FLASH_CE 0x80
-+#define DOC_FLASH_WP 0x40
-+#define DOC_FLASH_BANK 0x02
-+
- /* We have to also set the reserved bit 1 for enable */
- #define DOC_ECC_EN (DOC_ECC__EN | DOC_ECC_RESV)
- #define DOC_ECC_DIS (DOC_ECC_RESV)
-@@ -107,9 +156,12 @@
- #define MAX_FLOORS 4
- #define MAX_CHIPS 4
-
--#define MAX_FLOORS_MIL 4
-+#define MAX_FLOORS_MIL 1
- #define MAX_CHIPS_MIL 1
-
-+#define MAX_FLOORS_MPLUS 2
-+#define MAX_CHIPS_MPLUS 1
-+
- #define ADDR_COLUMN 1
- #define ADDR_PAGE 2
- #define ADDR_COLUMN_PAGE 3
-@@ -118,7 +170,7 @@
- unsigned long physadr;
- unsigned long virtadr;
- unsigned long totlen;
-- char ChipID; /* Type of DiskOnChip */
-+ unsigned char ChipID; /* Type of DiskOnChip */
- int ioreg;
-
- unsigned long mfr; /* Flash IDs - only one type of flash per device */
-@@ -126,6 +178,7 @@
- int chipshift;
- char page256;
- char pageadrlen;
-+ char interleave; /* Internal interleaving - Millennium Plus style */
- unsigned long erasesize;
-
- int curfloor;
-diff -Nurb linux-mips-2.4.27/include/linux/mtd/flashchip.h linux/include/linux/mtd/flashchip.h
---- linux-mips-2.4.27/include/linux/mtd/flashchip.h 2003-02-26 01:53:51.000000000 +0100
-+++ linux/include/linux/mtd/flashchip.h 2004-11-19 10:25:12.045177600 +0100
-@@ -6,7 +6,7 @@
- *
- * (C) 2000 Red Hat. GPLd.
- *
-- * $Id$
-+ * $Id$
- *
- */
-
-@@ -58,6 +58,11 @@
- int ref_point_counter;
- flstate_t state;
- flstate_t oldstate;
-+
-+ int write_suspended:1;
-+ int erase_suspended:1;
-+ unsigned long in_progress_block_addr;
-+
- spinlock_t *mutex;
- spinlock_t _spinlock; /* We do it like this because sometimes they'll be shared. */
- wait_queue_head_t wq; /* Wait on here when we're waiting for the chip
-diff -Nurb linux-mips-2.4.27/include/linux/mtd/gen_probe.h linux/include/linux/mtd/gen_probe.h
---- linux-mips-2.4.27/include/linux/mtd/gen_probe.h 2001-11-05 21:16:30.000000000 +0100
-+++ linux/include/linux/mtd/gen_probe.h 2004-11-19 10:25:12.048177144 +0100
-@@ -1,7 +1,7 @@
- /*
- * (C) 2001, 2001 Red Hat, Inc.
- * GPL'd
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __LINUX_MTD_GEN_PROBE_H__
-@@ -10,12 +10,12 @@
- #include <linux/mtd/flashchip.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/cfi.h>
-+#include <asm/bitops.h>
-
- struct chip_probe {
- char *name;
- int (*probe_chip)(struct map_info *map, __u32 base,
-- struct flchip *chips, struct cfi_private *cfi);
--
-+ unsigned long *chip_map, struct cfi_private *cfi);
- };
-
- struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp);
-diff -Nurb linux-mips-2.4.27/include/linux/mtd/inftl.h linux/include/linux/mtd/inftl.h
---- linux-mips-2.4.27/include/linux/mtd/inftl.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/include/linux/mtd/inftl.h 2004-11-19 10:25:12.051176688 +0100
-@@ -0,0 +1,129 @@
-+/*
-+ * inftl.h -- defines to support the Inverse NAND Flash Translation Layer
-+ *
-+ * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
-+ *
-+ * $Id$
-+ */
-+
-+#ifndef __MTD_INFTL_H__
-+#define __MTD_INFTL_H__
-+
-+#include <linux/mtd/blktrans.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nftl.h>
-+
-+#define OSAK_VERSION 0x5120
-+#define PERCENTUSED 98
-+
-+#define SECTORSIZE 512
-+
-+#ifndef INFTL_MAJOR
-+#define INFTL_MAJOR 94
-+#endif
-+#define INFTL_PARTN_BITS 4
-+
-+/* Block Control Information */
-+
-+struct inftl_bci {
-+ __u8 ECCsig[6];
-+ __u8 Status;
-+ __u8 Status1;
-+} __attribute__((packed));
-+
-+struct inftl_unithead1 {
-+ __u16 virtualUnitNo;
-+ __u16 prevUnitNo;
-+ __u8 ANAC;
-+ __u8 NACs;
-+ __u8 parityPerField;
-+ __u8 discarded;
-+} __attribute__((packed));
-+
-+struct inftl_unithead2 {
-+ __u8 parityPerField;
-+ __u8 ANAC;
-+ __u16 prevUnitNo;
-+ __u16 virtualUnitNo;
-+ __u8 NACs;
-+ __u8 discarded;
-+} __attribute__((packed));
-+
-+struct inftl_unittail {
-+ __u8 Reserved[4];
-+ __u16 EraseMark;
-+ __u16 EraseMark1;
-+} __attribute__((packed));
-+
-+union inftl_uci {
-+ struct inftl_unithead1 a;
-+ struct inftl_unithead2 b;
-+ struct inftl_unittail c;
-+};
-+
-+struct inftl_oob {
-+ struct inftl_bci b;
-+ union inftl_uci u;
-+};
-+
-+
-+/* INFTL Media Header */
-+
-+struct INFTLPartition {
-+ __u32 virtualUnits;
-+ __u32 firstUnit;
-+ __u32 lastUnit;
-+ __u32 flags;
-+ __u32 spareUnits;
-+ __u32 Reserved0;
-+ __u32 Reserved1;
-+} __attribute__((packed));
-+
-+struct INFTLMediaHeader {
-+ char bootRecordID[8];
-+ __u32 NoOfBootImageBlocks;
-+ __u32 NoOfBinaryPartitions;
-+ __u32 NoOfBDTLPartitions;
-+ __u32 BlockMultiplierBits;
-+ __u32 FormatFlags;
-+ __u32 OsakVersion;
-+ __u32 PercentUsed;
-+ struct INFTLPartition Partitions[4];
-+} __attribute__((packed));
-+
-+/* Partition flag types */
-+#define INFTL_BINARY 0x20000000
-+#define INFTL_BDTL 0x40000000
-+#define INFTL_LAST 0x80000000
-+
-+
-+#ifdef __KERNEL__
-+
-+struct INFTLrecord {
-+ struct mtd_blktrans_dev mbd;
-+ __u16 MediaUnit, SpareMediaUnit;
-+ __u32 EraseSize;
-+ struct INFTLMediaHeader MediaHdr;
-+ int usecount;
-+ unsigned char heads;
-+ unsigned char sectors;
-+ unsigned short cylinders;
-+ __u16 numvunits;
-+ __u16 firstEUN;
-+ __u16 lastEUN;
-+ __u16 numfreeEUNs;
-+ __u16 LastFreeEUN; /* To speed up finding a free EUN */
-+ int head,sect,cyl;
-+ __u16 *PUtable; /* Physical Unit Table */
-+ __u16 *VUtable; /* Virtual Unit Table */
-+ unsigned int nb_blocks; /* number of physical blocks */
-+ unsigned int nb_boot_blocks; /* number of blocks used by the bios */
-+ struct erase_info instr;
-+};
-+
-+int INFTL_mount(struct INFTLrecord *s);
-+int INFTL_formatblock(struct INFTLrecord *s, int block);
-+
-+#endif /* __KERNEL__ */
-+
-+#endif /* __MTD_INFTL_H__ */
-diff -Nurb linux-mips-2.4.27/include/linux/mtd/jedec.h linux/include/linux/mtd/jedec.h
---- linux-mips-2.4.27/include/linux/mtd/jedec.h 2001-12-02 12:35:00.000000000 +0100
-+++ linux/include/linux/mtd/jedec.h 2004-11-19 10:25:12.052176536 +0100
-@@ -7,14 +7,13 @@
- *
- * See the AMD flash databook for information on how to operate the interface.
- *
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __LINUX_MTD_JEDEC_H__
- #define __LINUX_MTD_JEDEC_H__
-
- #include <linux/types.h>
--#include <linux/mtd/map.h>
-
- #define MAX_JEDEC_CHIPS 16
-
-diff -Nurb linux-mips-2.4.27/include/linux/mtd/map.h linux/include/linux/mtd/map.h
---- linux-mips-2.4.27/include/linux/mtd/map.h 2003-02-26 01:53:51.000000000 +0100
-+++ linux/include/linux/mtd/map.h 2004-11-19 10:25:12.054176232 +0100
-@@ -1,14 +1,15 @@
-
- /* Overhauled routines for dealing with different mmap regions of flash */
--/* $Id$ */
-+/* $Id$ */
-
- #ifndef __LINUX_MTD_MAP_H__
- #define __LINUX_MTD_MAP_H__
-
- #include <linux/config.h>
- #include <linux/types.h>
--#include <linux/mtd/mtd.h>
--#include <linux/slab.h>
-+#include <linux/list.h>
-+#include <asm/system.h>
-+#include <asm/io.h>
-
- /* The map stuff is very simple. You fill in your struct map_info with
- a handful of routines for accessing the device, making sure they handle
-@@ -29,39 +30,44 @@
- struct map_info {
- char *name;
- unsigned long size;
-+ unsigned long phys;
-+#define NO_XIP (-1UL)
-+
-+ unsigned long virt;
-+ void *cached;
-+
- int buswidth; /* in octets */
-- __u8 (*read8)(struct map_info *, unsigned long);
-- __u16 (*read16)(struct map_info *, unsigned long);
-- __u32 (*read32)(struct map_info *, unsigned long);
-- __u64 (*read64)(struct map_info *, unsigned long);
-+
-+#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
-+ u8 (*read8)(struct map_info *, unsigned long);
-+ u16 (*read16)(struct map_info *, unsigned long);
-+ u32 (*read32)(struct map_info *, unsigned long);
-+ u64 (*read64)(struct map_info *, unsigned long);
- /* If it returned a 'long' I'd call it readl.
- * It doesn't.
- * I won't.
- * dwmw2 */
-
- void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t);
-- void (*write8)(struct map_info *, __u8, unsigned long);
-- void (*write16)(struct map_info *, __u16, unsigned long);
-- void (*write32)(struct map_info *, __u32, unsigned long);
-- void (*write64)(struct map_info *, __u64, unsigned long);
-+ void (*write8)(struct map_info *, u8, unsigned long);
-+ void (*write16)(struct map_info *, u16, unsigned long);
-+ void (*write32)(struct map_info *, u32, unsigned long);
-+ void (*write64)(struct map_info *, u64, unsigned long);
- void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t);
-
-- u_char * (*point) (struct map_info *, loff_t, size_t);
-- void (*unpoint) (struct map_info *, u_char *, loff_t, size_t);
--
-+ /* We can perhaps put in 'point' and 'unpoint' methods, if we really
-+ want to enable XIP for non-linear mappings. Not yet though. */
-+#endif
-+ /* set_vpp() must handle being reentered -- enable, enable, disable
-+ must leave it enabled. */
- void (*set_vpp)(struct map_info *, int);
-- /* We put these two here rather than a single void *map_priv,
-- because we want mappers to be able to have quickly-accessible
-- cache for the 'currently-mapped page' without the _extra_
-- redirection that would be necessary. If you need more than
-- two longs, turn the second into a pointer. dwmw2 */
-+
- unsigned long map_priv_1;
- unsigned long map_priv_2;
- void *fldrv_priv;
- struct mtd_chip_driver *fldrv;
- };
-
--
- struct mtd_chip_driver {
- struct mtd_info *(*probe)(struct map_info *map);
- void (*destroy)(struct mtd_info *);
-@@ -74,26 +80,93 @@
- void unregister_mtd_chip_driver(struct mtd_chip_driver *);
-
- struct mtd_info *do_map_probe(const char *name, struct map_info *map);
-+void map_destroy(struct mtd_info *mtd);
-+
-+#define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0)
-+#define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0)
-+
-+#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
-+#define map_read8(map, ofs) (map)->read8(map, ofs)
-+#define map_read16(map, ofs) (map)->read16(map, ofs)
-+#define map_read32(map, ofs) (map)->read32(map, ofs)
-+#define map_read64(map, ofs) (map)->read64(map, ofs)
-+#define map_copy_from(map, to, from, len) (map)->copy_from(map, to, from, len)
-+#define map_write8(map, datum, ofs) (map)->write8(map, datum, ofs)
-+#define map_write16(map, datum, ofs) (map)->write16(map, datum, ofs)
-+#define map_write32(map, datum, ofs) (map)->write32(map, datum, ofs)
-+#define map_write64(map, datum, ofs) (map)->write64(map, datum, ofs)
-+#define map_copy_to(map, to, from, len) (map)->copy_to(map, to, from, len)
-
-+extern void simple_map_init(struct map_info *);
-+#define map_is_linear(map) (map->phys != NO_XIP)
-
--/*
-- * Destroy an MTD device which was created for a map device.
-- * Make sure the MTD device is already unregistered before calling this
-- */
--static inline void map_destroy(struct mtd_info *mtd)
--{
-- struct map_info *map = mtd->priv;
--
-- if (map->fldrv->destroy)
-- map->fldrv->destroy(mtd);
--#ifdef CONFIG_MODULES
-- if (map->fldrv->module)
-- __MOD_DEC_USE_COUNT(map->fldrv->module);
-+#else
-+static inline u8 map_read8(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readb(map->virt + ofs);
-+}
-+
-+static inline u16 map_read16(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readw(map->virt + ofs);
-+}
-+
-+static inline u32 map_read32(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readl(map->virt + ofs);
-+}
-+
-+static inline u64 map_read64(struct map_info *map, unsigned long ofs)
-+{
-+#ifndef CONFIG_MTD_CFI_B8 /* 64-bit mappings */
-+ BUG();
-+ return 0;
-+#else
-+ return __raw_readll(map->virt + ofs);
- #endif
-- kfree(mtd);
- }
-
--#define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0)
--#define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0)
-+static inline void map_write8(struct map_info *map, u8 datum, unsigned long ofs)
-+{
-+ __raw_writeb(datum, map->virt + ofs);
-+ mb();
-+}
-+
-+static inline void map_write16(struct map_info *map, u16 datum, unsigned long ofs)
-+{
-+ __raw_writew(datum, map->virt + ofs);
-+ mb();
-+}
-+
-+static inline void map_write32(struct map_info *map, u32 datum, unsigned long ofs)
-+{
-+ __raw_writel(datum, map->virt + ofs);
-+ mb();
-+}
-+
-+static inline void map_write64(struct map_info *map, u64 datum, unsigned long ofs)
-+{
-+#ifndef CONFIG_MTD_CFI_B8 /* 64-bit mappings */
-+ BUG();
-+#else
-+ __raw_writell(datum, map->virt + ofs);
-+ mb();
-+#endif /* CFI_B8 */
-+}
-+
-+static inline void map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-+{
-+ memcpy_fromio(to, map->virt + from, len);
-+}
-+
-+static inline void map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-+{
-+ memcpy_toio(map->virt + to, from, len);
-+}
-+
-+#define simple_map_init(map) do { } while (0)
-+#define map_is_linear(map) (1)
-+
-+#endif /* !CONFIG_MTD_COMPLEX_MAPPINGS */
-
- #endif /* __LINUX_MTD_MAP_H__ */
-diff -Nurb linux-mips-2.4.27/include/linux/mtd/mtd.h linux/include/linux/mtd/mtd.h
---- linux-mips-2.4.27/include/linux/mtd/mtd.h 2003-08-13 19:19:29.000000000 +0200
-+++ linux/include/linux/mtd/mtd.h 2004-11-19 10:25:12.055176080 +0100
-@@ -1,5 +1,10 @@
--
--/* $Id$ */
-+/*
-+ * $Id$
-+ *
-+ * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al.
-+ *
-+ * Released under GPL
-+ */
-
- #ifndef __MTD_MTD_H__
- #define __MTD_MTD_H__
-@@ -9,7 +14,6 @@
- #include <linux/config.h>
- #include <linux/version.h>
- #include <linux/types.h>
--#include <linux/mtd/compatmac.h>
- #include <linux/module.h>
- #include <linux/uio.h>
-
-@@ -26,7 +30,6 @@
- unsigned char *ptr;
- };
-
--
- #define MTD_CHAR_MAJOR 90
- #define MTD_BLOCK_MAJOR 31
- #define MAX_MTD_DEVICES 16
-@@ -93,18 +96,23 @@
- #define MEMUNLOCK _IOW('M', 6, struct erase_info_user)
- #define MEMGETREGIONCOUNT _IOR('M', 7, int)
- #define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user)
--#define MEMREADDATA _IOWR('M', 9, struct mtd_oob_buf)
--#define MEMWRITEDATA _IOWR('M', 10, struct mtd_oob_buf)
-+#define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo)
-+
-+struct nand_oobinfo {
-+ int useecc;
-+ int eccpos[6];
-+};
-+
-
- #ifndef __KERNEL__
-
- typedef struct mtd_info_user mtd_info_t;
- typedef struct erase_info_user erase_info_t;
- typedef struct region_info_user region_info_t;
-+typedef struct nand_oobinfo nand_oobinfo_t;
-
- /* User-space ioctl definitions */
-
--
- #else /* __KERNEL__ */
-
-
-@@ -150,10 +158,14 @@
- u_int32_t ecctype;
- u_int32_t eccsize;
-
-+
- // Kernel-only stuff starts here.
- char *name;
- int index;
-
-+ // oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO)
-+ struct nand_oobinfo oobinfo;
-+
- /* Data for variable erase regions. If numeraseregions is zero,
- * it means that the whole device has erasesize as given above.
- */
-@@ -163,7 +175,6 @@
- /* This really shouldn't be here. It can go away in 2.5 */
- u_int32_t bank_size;
-
-- struct module *module;
- int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
-
- /* This stuff for eXecute-In-Place */
-@@ -176,8 +187,8 @@
- int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
- int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
-
-- int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, int oobsel);
-- int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, int oobsel);
-+ int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
-+ int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
-
- int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
- int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
-@@ -201,10 +212,10 @@
- */
- int (*readv) (struct mtd_info *mtd, struct iovec *vecs, unsigned long count, loff_t from, size_t *retlen);
- int (*readv_ecc) (struct mtd_info *mtd, struct iovec *vecs, unsigned long count, loff_t from,
-- size_t *retlen, u_char *eccbuf, int oobsel);
-+ size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
- int (*writev) (struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen);
- int (*writev_ecc) (struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to,
-- size_t *retlen, u_char *eccbuf, int oobsel);
-+ size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
-
- /* Sync */
- void (*sync) (struct mtd_info *mtd);
-@@ -218,6 +229,9 @@
- void (*resume) (struct mtd_info *mtd);
-
- void *priv;
-+
-+ struct module *owner;
-+ int usecount;
- };
-
-
-@@ -226,31 +240,15 @@
- extern int add_mtd_device(struct mtd_info *mtd);
- extern int del_mtd_device (struct mtd_info *mtd);
-
--extern struct mtd_info *__get_mtd_device(struct mtd_info *mtd, int num);
--
--static inline struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
--{
-- struct mtd_info *ret;
-+extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
-
-- ret = __get_mtd_device(mtd, num);
--
-- if (ret && ret->module && !try_inc_mod_count(ret->module))
-- return NULL;
--
-- return ret;
--}
--
--static inline void put_mtd_device(struct mtd_info *mtd)
--{
-- if (mtd->module)
-- __MOD_DEC_USE_COUNT(mtd->module);
--}
-+extern void put_mtd_device(struct mtd_info *mtd);
-
-
- struct mtd_notifier {
- void (*add)(struct mtd_info *mtd);
- void (*remove)(struct mtd_info *mtd);
-- struct mtd_notifier *next;
-+ struct list_head list;
- };
-
-
-@@ -263,7 +261,6 @@
- int default_mtd_readv(struct mtd_info *mtd, struct iovec *vecs,
- unsigned long count, loff_t from, size_t *retlen);
-
--#ifndef MTDC
- #define MTD_ERASE(mtd, args...) (*(mtd->erase))(mtd, args)
- #define MTD_POINT(mtd, a,b,c,d) (*(mtd->point))(mtd, a,b,c, (u_char **)(d))
- #define MTD_UNPOINT(mtd, arg) (*(mtd->unpoint))(mtd, (u_char *)arg)
-@@ -276,7 +273,6 @@
- #define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args)
- #define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args)
- #define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0)
--#endif /* MTDC */
-
- /*
- * Debugging macro and defines
-@@ -293,7 +289,8 @@
- printk(KERN_INFO args); \
- } while(0)
- #else /* CONFIG_MTD_DEBUG */
--#define DEBUG(n, args...)
-+#define DEBUG(n, args...) do { } while(0)
-+
- #endif /* CONFIG_MTD_DEBUG */
-
- #endif /* __KERNEL__ */
-diff -Nurb linux-mips-2.4.27/include/linux/mtd/nand.h linux/include/linux/mtd/nand.h
---- linux-mips-2.4.27/include/linux/mtd/nand.h 2003-02-26 01:53:51.000000000 +0100
-+++ linux/include/linux/mtd/nand.h 2004-11-19 10:25:12.057175776 +0100
-@@ -2,10 +2,10 @@
- * linux/include/linux/mtd/nand.h
- *
- * Copyright (c) 2000 David Woodhouse <dwmw2@mvhi.com>
-- * Steven J. Hill <sjhill@cotw.com>
-+ * Steven J. Hill <sjhill@realitydiluted.com>
- * Thomas Gleixner <tglx@linutronix.de>
- *
-- * $Id$
-+ * $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
-@@ -49,12 +49,14 @@
- #define __LINUX_MTD_NAND_H
-
- #include <linux/config.h>
--#include <linux/sched.h>
-+#include <linux/wait.h>
-+#include <linux/spinlock.h>
-
-+struct mtd_info;
- /*
- * Searches for a NAND device
- */
--extern int nand_scan (struct mtd_info *mtd);
-+extern int nand_scan (struct mtd_info *mtd, int max_chips);
-
- /*
- * Constants for hardware specific CLE/ALE/NCE function
-@@ -65,6 +67,8 @@
- #define NAND_CTL_CLRCLE 4
- #define NAND_CTL_SETALE 5
- #define NAND_CTL_CLRALE 6
-+#define NAND_CTL_SETWP 7
-+#define NAND_CTL_CLRWP 8
-
- /*
- * Standard NAND flash commands
-@@ -160,24 +164,33 @@
- struct nand_chip {
- unsigned long IO_ADDR_R;
- unsigned long IO_ADDR_W;
-- void (*hwcontrol)(int cmd);
-- int (*dev_ready)(void);
-+
-+ u_char (*read_byte)(struct mtd_info *mtd);
-+ void (*write_byte)(struct mtd_info *mtd, u_char byte);
-+
-+ void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len);
-+ void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len);
-+ int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len);
-+ void (*select_chip)(struct mtd_info *mtd, int chip);
-+ int (*block_bad)(struct mtd_info *mtd, unsigned long pos);
-+ void (*hwcontrol)(struct mtd_info *mtd, int cmd);
-+ int (*dev_ready)(struct mtd_info *mtd);
- void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);
- int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state);
-- void (*calculate_ecc)(const u_char *dat, u_char *ecc_code);
-- int (*correct_data)(u_char *dat, u_char *read_ecc, u_char *calc_ecc);
-- void (*enable_hwecc)(int mode);
-+ void (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code);
-+ int (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
-+ void (*enable_hwecc)(struct mtd_info *mtd, int mode);
- int eccmode;
- int eccsize;
- int chip_delay;
-+ int chipshift;
- spinlock_t chip_lock;
- wait_queue_head_t wq;
- nand_state_t state;
- int page_shift;
- u_char *data_buf;
- u_char *data_poi;
-- u_char *data_cache;
-- int cache_page;
-+ void *priv;
- };
-
- /*
-@@ -241,34 +254,4 @@
- */
- #define NAND_BADBLOCK_POS 5
-
--#define NAND_NONE_OOB 0
--#define NAND_JFFS2_OOB 1
--#define NAND_YAFFS_OOB 2
--
--#define NAND_NOOB_ECCPOS0 0
--#define NAND_NOOB_ECCPOS1 1
--#define NAND_NOOB_ECCPOS2 2
--#define NAND_NOOB_ECCPOS3 3
--#define NAND_NOOB_ECCPOS4 6
--#define NAND_NOOB_ECCPOS5 7
--
--#define NAND_JFFS2_OOB_ECCPOS0 0
--#define NAND_JFFS2_OOB_ECCPOS1 1
--#define NAND_JFFS2_OOB_ECCPOS2 2
--#define NAND_JFFS2_OOB_ECCPOS3 3
--#define NAND_JFFS2_OOB_ECCPOS4 6
--#define NAND_JFFS2_OOB_ECCPOS5 7
--
--#define NAND_YAFFS_OOB_ECCPOS0 8
--#define NAND_YAFFS_OOB_ECCPOS1 9
--#define NAND_YAFFS_OOB_ECCPOS2 10
--#define NAND_YAFFS_OOB_ECCPOS3 13
--#define NAND_YAFFS_OOB_ECCPOS4 14
--#define NAND_YAFFS_OOB_ECCPOS5 15
--
--#define NAND_JFFS2_OOB8_FSDAPOS 6
--#define NAND_JFFS2_OOB16_FSDAPOS 8
--#define NAND_JFFS2_OOB8_FSDALEN 2
--#define NAND_JFFS2_OOB16_FSDALEN 8
--
- #endif /* __LINUX_MTD_NAND_H */
-diff -Nurb linux-mips-2.4.27/include/linux/mtd/nand_ecc.h linux/include/linux/mtd/nand_ecc.h
---- linux-mips-2.4.27/include/linux/mtd/nand_ecc.h 2001-08-22 05:25:12.000000000 +0200
-+++ linux/include/linux/mtd/nand_ecc.h 2004-11-19 10:25:12.058175624 +0100
-@@ -1,9 +1,9 @@
- /*
- * drivers/mtd/nand_ecc.h
- *
-- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
-+ * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
- *
-- * $Id$
-+ * $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
-@@ -12,17 +12,19 @@
- * This file is the header for the ECC algorithm.
- */
-
--/*
-- * Creates non-inverted ECC code from line parity
-- */
--void nand_trans_result(u_char reg2, u_char reg3, u_char *ecc_code);
-+#ifndef __MTD_NAND_ECC_H__
-+#define __MTD_NAND_ECC_H__
-+
-+struct mtd_info;
-
- /*
- * Calculate 3 byte ECC code for 256 byte block
- */
--void nand_calculate_ecc (const u_char *dat, u_char *ecc_code);
-+void nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code);
-
- /*
- * Detect and correct a 1 bit error for 256 byte block
- */
--int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc);
-+int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
-+
-+#endif /* __MTD_NAND_ECC_H__ */
-diff -Nurb linux-mips-2.4.27/include/linux/mtd/nftl.h linux/include/linux/mtd/nftl.h
---- linux-mips-2.4.27/include/linux/mtd/nftl.h 2003-02-26 01:53:51.000000000 +0100
-+++ linux/include/linux/mtd/nftl.h 2004-11-19 10:25:12.060175320 +0100
-@@ -1,15 +1,14 @@
--
--/* Defines for NAND Flash Translation Layer */
--/* (c) 1999 Machine Vision Holdings, Inc. */
--/* Author: David Woodhouse <dwmw2@mvhi.com> */
--/* $Id$ */
-+/*
-+ * $Id$
-+ *
-+ * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
-+ */
-
- #ifndef __MTD_NFTL_H__
- #define __MTD_NFTL_H__
-
--#ifndef __BOOT__
- #include <linux/mtd/mtd.h>
--#endif
-+#include <linux/mtd/blktrans.h>
-
- /* Block Control Information */
-
-@@ -84,8 +83,7 @@
- #define BLOCK_RESERVED 0xfffc /* bios block or bad block */
-
- struct NFTLrecord {
-- struct mtd_info *mtd;
-- struct semaphore mutex;
-+ struct mtd_blktrans_dev mbd;
- __u16 MediaUnit, SpareMediaUnit;
- __u32 EraseSize;
- struct NFTLMediaHeader MediaHdr;
-@@ -97,7 +95,6 @@
- __u16 lastEUN; /* should be suppressed */
- __u16 numfreeEUNs;
- __u16 LastFreeEUN; /* To speed up finding a free EUN */
-- __u32 nr_sects;
- int head,sect,cyl;
- __u16 *EUNtable; /* [numvunits]: First EUN for each virtual unit */
- __u16 *ReplUnitTable; /* [numEUNs]: ReplUnitNumber for each */
-@@ -114,7 +111,7 @@
- #endif
-
- #define MAX_NFTLS 16
--#define MAX_SECTORS_PER_UNIT 32
-+#define MAX_SECTORS_PER_UNIT 64
- #define NFTL_PARTN_BITS 4
-
- #endif /* __KERNEL__ */
-diff -Nurb linux-mips-2.4.27/include/linux/mtd/partitions.h linux/include/linux/mtd/partitions.h
---- linux-mips-2.4.27/include/linux/mtd/partitions.h 2002-06-27 00:36:47.000000000 +0200
-+++ linux/include/linux/mtd/partitions.h 2004-11-19 10:25:12.061175168 +0100
-@@ -5,7 +5,7 @@
- *
- * This code is GPL
- *
-- * $Id$
-+ * $Id$
- */
-
- #ifndef MTD_PARTITIONS_H
-@@ -41,6 +41,7 @@
- u_int32_t size; /* partition size */
- u_int32_t offset; /* offset within the master MTD space */
- u_int32_t mask_flags; /* master MTD flags to mask out for this partition */
-+ struct nand_oobinfo *oobsel; /* out of band layout for this partition (NAND only)*/
- struct mtd_info **mtdp; /* pointer to store the MTD object */
- };
-
-@@ -49,8 +50,27 @@
- #define MTDPART_SIZ_FULL (0)
-
-
--int add_mtd_partitions(struct mtd_info *, struct mtd_partition *, int);
-+int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
- int del_mtd_partitions(struct mtd_info *);
-
-+/*
-+ * Functions dealing with the various ways of partitioning the space
-+ */
-+
-+struct mtd_part_parser {
-+ struct list_head list;
-+ struct module *owner;
-+ const char *name;
-+ int (*parse_fn)(struct mtd_info *, struct mtd_partition **, unsigned long);
-+};
-+
-+extern struct mtd_part_parser *get_partition_parser(const char *name);
-+extern int register_mtd_parser(struct mtd_part_parser *parser);
-+extern int deregister_mtd_parser(struct mtd_part_parser *parser);
-+extern int parse_mtd_partitions(struct mtd_info *master, const char **types,
-+ struct mtd_partition **pparts, unsigned long origin);
-+
-+#define put_partition_parser(p) do { module_put((p)->owner); } while(0)
-+
- #endif
-
-diff -Nurb linux-mips-2.4.27/include/linux/mtd/physmap.h linux/include/linux/mtd/physmap.h
---- linux-mips-2.4.27/include/linux/mtd/physmap.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/include/linux/mtd/physmap.h 2004-11-19 10:25:12.062175016 +0100
-@@ -0,0 +1,59 @@
-+/*
-+ * For boards with physically mapped flash and using
-+ * drivers/mtd/maps/physmap.c mapping driver.
-+ *
-+ * Copyright (C) 2003 MontaVista Software Inc.
-+ * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ *
-+ */
-+
-+#ifndef __LINUX_MTD_PHYSMAP__
-+
-+#include <linux/config.h>
-+
-+#if defined(CONFIG_MTD_PHYSMAP)
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+
-+/*
-+ * The map_info for physmap. Board can override size, buswidth, phys,
-+ * (*set_vpp)(), etc in their initial setup routine.
-+ */
-+extern struct map_info physmap_map;
-+
-+/*
-+ * Board needs to specify the exact mapping during their setup time.
-+ */
-+static inline void physmap_configure(unsigned long addr, unsigned long size, int buswidth, void (*set_vpp)(struct map_info *, int) )
-+{
-+ physmap_map.phys = addr;
-+ physmap_map.size = size;
-+ physmap_map.buswidth = buswidth;
-+ physmap_map.set_vpp = set_vpp;
-+}
-+
-+#if defined(CONFIG_MTD_PARTITIONS)
-+
-+/*
-+ * Machines that wish to do flash partition may want to call this function in
-+ * their setup routine.
-+ *
-+ * physmap_set_partitions(mypartitions, num_parts);
-+ *
-+ * Note that one can always override this hard-coded partition with
-+ * command line partition (you need to enable CONFIG_MTD_CMDLINE_PARTS).
-+ */
-+void physmap_set_partitions(struct mtd_partition *parts, int num_parts);
-+
-+#endif /* defined(CONFIG_MTD_PARTITIONS) */
-+#endif /* defined(CONFIG_MTD) */
-+
-+#endif /* __LINUX_MTD_PHYSMAP__ */
-+
-diff -Nurb linux-mips-2.4.27/include/linux/rbtree-24.h linux/include/linux/rbtree-24.h
---- linux-mips-2.4.27/include/linux/rbtree-24.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/include/linux/rbtree-24.h 2004-11-19 10:25:12.143162704 +0100
-@@ -0,0 +1,133 @@
-+/*
-+ Red Black Trees
-+ (C) 1999 Andrea Arcangeli <andrea@suse.de>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2 of the License, or
-+ (at your option) any later version.
-+
-+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+
-+ linux/include/linux/rbtree.h
-+
-+ To use rbtrees you'll have to implement your own insert and search cores.
-+ This will avoid us to use callbacks and to drop drammatically performances.
-+ I know it's not the cleaner way, but in C (not in C++) to get
-+ performances and genericity...
-+
-+ Some example of insert and search follows here. The search is a plain
-+ normal search over an ordered tree. The insert instead must be implemented
-+ int two steps: as first thing the code must insert the element in
-+ order as a red leaf in the tree, then the support library function
-+ rb_insert_color() must be called. Such function will do the
-+ not trivial work to rebalance the rbtree if necessary.
-+
-+-----------------------------------------------------------------------
-+static inline struct page * rb_search_page_cache(struct inode * inode,
-+ unsigned long offset)
-+{
-+ rb_node_t * n = inode->i_rb_page_cache.rb_node;
-+ struct page * page;
-+
-+ while (n)
-+ {
-+ page = rb_entry(n, struct page, rb_page_cache);
-+
-+ if (offset < page->offset)
-+ n = n->rb_left;
-+ else if (offset > page->offset)
-+ n = n->rb_right;
-+ else
-+ return page;
-+ }
-+ return NULL;
-+}
-+
-+static inline struct page * __rb_insert_page_cache(struct inode * inode,
-+ unsigned long offset,
-+ rb_node_t * node)
-+{
-+ rb_node_t ** p = &inode->i_rb_page_cache.rb_node;
-+ rb_node_t * parent = NULL;
-+ struct page * page;
-+
-+ while (*p)
-+ {
-+ parent = *p;
-+ page = rb_entry(parent, struct page, rb_page_cache);
-+
-+ if (offset < page->offset)
-+ p = &(*p)->rb_left;
-+ else if (offset > page->offset)
-+ p = &(*p)->rb_right;
-+ else
-+ return page;
-+ }
-+
-+ rb_link_node(node, parent, p);
-+
-+ return NULL;
-+}
-+
-+static inline struct page * rb_insert_page_cache(struct inode * inode,
-+ unsigned long offset,
-+ rb_node_t * node)
-+{
-+ struct page * ret;
-+ if ((ret = __rb_insert_page_cache(inode, offset, node)))
-+ goto out;
-+ rb_insert_color(node, &inode->i_rb_page_cache);
-+ out:
-+ return ret;
-+}
-+-----------------------------------------------------------------------
-+*/
-+
-+#ifndef _LINUX_RBTREE_H
-+#define _LINUX_RBTREE_H
-+
-+#include <linux/kernel.h>
-+#include <linux/stddef.h>
-+
-+typedef struct rb_node_s
-+{
-+ struct rb_node_s * rb_parent;
-+ int rb_color;
-+#define RB_RED 0
-+#define RB_BLACK 1
-+ struct rb_node_s * rb_right;
-+ struct rb_node_s * rb_left;
-+}
-+rb_node_t;
-+
-+typedef struct rb_root_s
-+{
-+ struct rb_node_s * rb_node;
-+}
-+rb_root_t;
-+
-+#define RB_ROOT (rb_root_t) { NULL, }
-+#define rb_entry(ptr, type, member) \
-+ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
-+
-+extern void rb_insert_color(rb_node_t *, rb_root_t *);
-+extern void rb_erase(rb_node_t *, rb_root_t *);
-+
-+static inline void rb_link_node(rb_node_t * node, rb_node_t * parent, rb_node_t ** rb_link)
-+{
-+ node->rb_parent = parent;
-+ node->rb_color = RB_RED;
-+ node->rb_left = node->rb_right = NULL;
-+
-+ *rb_link = node;
-+}
-+
-+#endif /* _LINUX_RBTREE_H */
-diff -Nurb linux-mips-2.4.27/include/linux/rbtree.h linux/include/linux/rbtree.h
---- linux-mips-2.4.27/include/linux/rbtree.h 2001-10-19 03:25:03.000000000 +0200
-+++ linux/include/linux/rbtree.h 2004-11-19 10:25:12.148161944 +0100
-@@ -1,133 +1,25 @@
- /*
-- Red Black Trees
-- (C) 1999 Andrea Arcangeli <andrea@suse.de>
-+ * 2.5 compatibility
-+ * $Id$
-+ */
-+
-+#ifndef __MTD_COMPAT_RBTREE_H__
-+#define __MTD_COMPAT_RBTREE_H__
-+
-+#include <linux/version.h>
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,40)
-+#include_next <linux/rbtree.h>
-+#else
-+#define rb_node_s rb_node
-+#define rb_root_s rb_root
-+
-+#include <linux/rbtree-24.h>
-+
-+/* Find logical next and previous nodes in a tree */
-+extern struct rb_node *rb_next(struct rb_node *);
-+extern struct rb_node *rb_prev(struct rb_node *);
-+extern struct rb_node *rb_first(struct rb_root *);
-+#endif
-
-- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--
-- linux/include/linux/rbtree.h
--
-- To use rbtrees you'll have to implement your own insert and search cores.
-- This will avoid us to use callbacks and to drop drammatically performances.
-- I know it's not the cleaner way, but in C (not in C++) to get
-- performances and genericity...
--
-- Some example of insert and search follows here. The search is a plain
-- normal search over an ordered tree. The insert instead must be implemented
-- int two steps: as first thing the code must insert the element in
-- order as a red leaf in the tree, then the support library function
-- rb_insert_color() must be called. Such function will do the
-- not trivial work to rebalance the rbtree if necessary.
--
-------------------------------------------------------------------------
--static inline struct page * rb_search_page_cache(struct inode * inode,
-- unsigned long offset)
--{
-- rb_node_t * n = inode->i_rb_page_cache.rb_node;
-- struct page * page;
--
-- while (n)
-- {
-- page = rb_entry(n, struct page, rb_page_cache);
--
-- if (offset < page->offset)
-- n = n->rb_left;
-- else if (offset > page->offset)
-- n = n->rb_right;
-- else
-- return page;
-- }
-- return NULL;
--}
--
--static inline struct page * __rb_insert_page_cache(struct inode * inode,
-- unsigned long offset,
-- rb_node_t * node)
--{
-- rb_node_t ** p = &inode->i_rb_page_cache.rb_node;
-- rb_node_t * parent = NULL;
-- struct page * page;
--
-- while (*p)
-- {
-- parent = *p;
-- page = rb_entry(parent, struct page, rb_page_cache);
--
-- if (offset < page->offset)
-- p = &(*p)->rb_left;
-- else if (offset > page->offset)
-- p = &(*p)->rb_right;
-- else
-- return page;
-- }
--
-- rb_link_node(node, parent, p);
--
-- return NULL;
--}
--
--static inline struct page * rb_insert_page_cache(struct inode * inode,
-- unsigned long offset,
-- rb_node_t * node)
--{
-- struct page * ret;
-- if ((ret = __rb_insert_page_cache(inode, offset, node)))
-- goto out;
-- rb_insert_color(node, &inode->i_rb_page_cache);
-- out:
-- return ret;
--}
-------------------------------------------------------------------------
--*/
--
--#ifndef _LINUX_RBTREE_H
--#define _LINUX_RBTREE_H
--
--#include <linux/kernel.h>
--#include <linux/stddef.h>
--
--typedef struct rb_node_s
--{
-- struct rb_node_s * rb_parent;
-- int rb_color;
--#define RB_RED 0
--#define RB_BLACK 1
-- struct rb_node_s * rb_right;
-- struct rb_node_s * rb_left;
--}
--rb_node_t;
--
--typedef struct rb_root_s
--{
-- struct rb_node_s * rb_node;
--}
--rb_root_t;
--
--#define RB_ROOT (rb_root_t) { NULL, }
--#define rb_entry(ptr, type, member) \
-- ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
--
--extern void rb_insert_color(rb_node_t *, rb_root_t *);
--extern void rb_erase(rb_node_t *, rb_root_t *);
--
--static inline void rb_link_node(rb_node_t * node, rb_node_t * parent, rb_node_t ** rb_link)
--{
-- node->rb_parent = parent;
-- node->rb_color = RB_RED;
-- node->rb_left = node->rb_right = NULL;
--
-- *rb_link = node;
--}
--
--#endif /* _LINUX_RBTREE_H */
-+#endif /* __MTD_COMPAT_RBTREE_H__ */
-diff -Nurb linux-mips-2.4.27/include/linux/suspend.h linux/include/linux/suspend.h
---- linux-mips-2.4.27/include/linux/suspend.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/include/linux/suspend.h 2004-11-19 10:25:12.150161640 +0100
-@@ -0,0 +1,10 @@
-+/* $Id$ */
-+
-+#ifndef __MTD_COMPAT_VERSION_H__
-+#include <linux/version.h>
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+#include_next <linux/suspend.h>
-+#endif
-+
-+#endif /* __MTD_COMPAT_VERSION_H__ */
-diff -Nurb linux-mips-2.4.27/include/linux/workqueue.h linux/include/linux/workqueue.h
---- linux-mips-2.4.27/include/linux/workqueue.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux/include/linux/workqueue.h 2004-11-19 10:25:12.152161336 +0100
-@@ -0,0 +1,21 @@
-+/*
-+ * 2.5 compatibility
-+ * $Id$
-+ */
-+
-+#ifndef __MTD_COMPAT_WORKQUEUE_H__
-+#define __MTD_COMPAT_WORKQUEUE_H__
-+
-+#include <linux/version.h>
-+
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,40)
-+#include_next <linux/workqueue.h>
-+#else
-+#include <linux/tqueue.h>
-+#define work_struct tq_struct
-+#define schedule_work(x) schedule_task(x)
-+#define flush_scheduled_work flush_scheduled_tasks
-+#define INIT_WORK(x,y,z) INIT_TQUEUE(x,y,z)
-+#endif
-+
-+#endif /* __MTD_COMPAT_WORKQUEUE_H__ */
diff --git a/linux/linux-mtx-1-2.4.27/02-mtd-mtx-1-map.diff b/linux/linux-mtx-1-2.4.27/02-mtd-mtx-1-map.diff
deleted file mode 100644
index ba24bb1381..0000000000
--- a/linux/linux-mtx-1-2.4.27/02-mtd-mtx-1-map.diff
+++ /dev/null
@@ -1,248 +0,0 @@
-diff -Nurb linux/drivers/mtd/maps/Config.in linux-mips-2.4.24-pre2+mtd-2004-01-27+mtx-map/drivers/mtd/maps/Config.in
---- linux/drivers/mtd/maps/Config.in 2004-11-17 18:17:59.049312400 +0100
-+++ linux-mips-2.4.24-pre2+mtd-2004-01-27+mtx-map/drivers/mtd/maps/Config.in 2004-11-17 18:12:26.000000000 +0100
-@@ -80,6 +80,7 @@
- bool ' Db1x00 boot flash device' CONFIG_MTD_DB1X00_BOOT
- bool ' Db1x00 user flash device (2nd bank)' CONFIG_MTD_DB1X00_USER
- fi
-+ dep_tristate ' MTX-1 flash device' CONFIG_MTD_MTX1 $CONFIG_MIPS_MTX1
- dep_tristate ' Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board' CONFIG_MTD_CSTM_MIPS_IXX $CONFIG_MTD_CFI $CONFIG_MTD_JEDEC $CONFIG_MTD_PARTITIONS
- if [ "$CONFIG_MTD_CSTM_MIPS_IXX" = "y" -o "$CONFIG_MTD_CSTM_MIPS_IXX" = "m" ]; then
- hex ' Physical start address of flash mapping' CONFIG_MTD_CSTM_MIPS_IXX_START 0x8000000
-diff -Nurb linux/drivers/mtd/maps/Makefile linux-mips-2.4.24-pre2+mtd-2004-01-27+mtx-map/drivers/mtd/maps/Makefile
---- linux/drivers/mtd/maps/Makefile 2004-11-17 18:17:59.051312096 +0100
-+++ linux-mips-2.4.24-pre2+mtd-2004-01-27+mtx-map/drivers/mtd/maps/Makefile 2004-11-17 18:12:26.000000000 +0100
-@@ -49,6 +49,7 @@
- obj-$(CONFIG_MTD_PCI) += pci.o
- obj-$(CONFIG_MTD_PB1XXX) += pb1xxx-flash.o
- obj-$(CONFIG_MTD_DB1X00) += db1x00-flash.o
-+obj-$(CONFIG_MTD_MTX1) += mtx-1.o
- obj-$(CONFIG_MTD_LASAT) += lasat.o
- obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o
- obj-$(CONFIG_MTD_EDB7312) += edb7312.o
-diff -Nurb linux/drivers/mtd/maps/mtx-1.c linux-mips-2.4.24-pre2+mtd-2004-01-27+mtx-map/drivers/mtd/maps/mtx-1.c
---- linux/drivers/mtd/maps/mtx-1.c 2004-11-17 18:17:02.689880336 +0100
-+++ linux-mips-2.4.24-pre2+mtd-2004-01-27+mtx-map/drivers/mtd/maps/mtx-1.c 2004-11-17 18:12:26.000000000 +0100
-@@ -1,166 +1,78 @@
- /*
- * Flash memory access on 4G Systems MTX-1 board
- *
-- * (C) 2003 Pete Popov <ppopov@mvista.com>
-- * Bruno Randolf <bruno.randolf@4g-systems.de>
-+ * (C) Bruno Randolf (4G Systeme GmbH) <bruno.randolf@4g-systems.biz>
- */
-
- #include <linux/config.h>
- #include <linux/module.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-+#include <linux/init.h>
-
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/map.h>
- #include <linux/mtd/partitions.h>
-
- #include <asm/io.h>
--#include <asm/au1000.h>
-
--#ifdef DEBUG_RW
--#define DBG(x...) printk(x)
--#else
--#define DBG(x...)
--#endif
--
--#ifdef CONFIG_MIPS_MTX1
- #define WINDOW_ADDR 0x1E000000
- #define WINDOW_SIZE 0x2000000
--#endif
--
--__u8 physmap_read8(struct map_info *map, unsigned long ofs)
--{
-- __u8 ret;
-- ret = __raw_readb(map->map_priv_1 + ofs);
-- DBG("read8 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--__u16 physmap_read16(struct map_info *map, unsigned long ofs)
--{
-- __u16 ret;
-- ret = __raw_readw(map->map_priv_1 + ofs);
-- DBG("read16 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--__u32 physmap_read32(struct map_info *map, unsigned long ofs)
--{
-- __u32 ret;
-- ret = __raw_readl(map->map_priv_1 + ofs);
-- DBG("read32 from %x, %x\n", (unsigned)(map->map_priv_1 + ofs), ret);
-- return ret;
--}
--
--void physmap_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- DBG("physmap_copy from %x to %x\n", (unsigned)from, (unsigned)to);
-- memcpy_fromio(to, map->map_priv_1 + from, len);
--}
--
--void physmap_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- DBG("write8 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- DBG("write16 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- DBG("write32 at %x, %x\n", (unsigned)(map->map_priv_1 + adr), d);
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--void physmap_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- DBG("physmap_copy_to %x from %x\n", (unsigned)to, (unsigned)from);
-- memcpy_toio(map->map_priv_1 + to, from, len);
--}
--
--
-+#define BUSWIDTH 4
-
- static struct map_info mtx1_map = {
-- name: "MTX-1 flash",
-- read8: physmap_read8,
-- read16: physmap_read16,
-- read32: physmap_read32,
-- copy_from: physmap_copy_from,
-- write8: physmap_write8,
-- write16: physmap_write16,
-- write32: physmap_write32,
-- copy_to: physmap_copy_to,
-+ .name = "MTX-1 flash",
-+ .size = WINDOW_SIZE,
-+ .buswidth = BUSWIDTH,
-+ .phys = WINDOW_ADDR
- };
-
--
--static unsigned long flash_size = 0x01000000;
--static unsigned char flash_buswidth = 4;
- static struct mtd_partition mtx1_partitions[] = {
- {
-- name: "user fs",
-- size: 0x1c00000,
-- offset: 0,
-+ .name = "user fs",
-+ .size = 0x1c00000,
-+ .offset = 0,
- },{
-- name: "yamon",
-- size: 0x0100000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE
-+ .name = "yamon",
-+ .size = 0x0100000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
- },{
-- name: "raw kernel",
-- size: 0x02c0000,
-- offset: MTDPART_OFS_APPEND,
-+ .name = "raw kernel",
-+ .size = 0x02c0000,
-+ .offset = MTDPART_OFS_APPEND,
- },{
-- name: "yamon env vars",
-- size: 0x0040000,
-- offset: MTDPART_OFS_APPEND,
-- mask_flags: MTD_WRITEABLE
-+ .name = "yamon environment",
-+ .size = 0x0040000,
-+ .offset = MTDPART_OFS_APPEND,
-+ .mask_flags = MTD_WRITEABLE /* force read-only */
- }
- };
-
--
--#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
--
--static struct mtd_partition *parsed_parts;
- static struct mtd_info *mymtd;
-
- int __init mtx1_mtd_init(void)
- {
-- struct mtd_partition *parts;
-- int nb_parts = 0;
-- char *part_type;
-+ printk(KERN_NOTICE "MTX-1 flash: probing %d-bit flash bus at %x\n",
-+ mtx1_map.buswidth*8, WINDOW_ADDR);
-
-- /* Default flash buswidth */
-- mtx1_map.buswidth = flash_buswidth;
-+ mtx1_map.virt = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
-+ if (!mtx1_map.virt) {
-+ printk("mtx_mtd_init: failed to ioremap\n");
-+ return -EIO;
-+ }
-+
-+ simple_map_init(&mtx1_map);
-
-- /*
-- * Static partition definition selection
-- */
-- part_type = "static";
-- parts = mtx1_partitions;
-- nb_parts = NB_OF(mtx1_partitions);
-- mtx1_map.size = flash_size;
--
-- /*
-- * Now let's probe for the actual flash. Do it here since
-- * specific machine settings might have been set above.
-- */
-- printk(KERN_NOTICE "MTX-1 flash: probing %d-bit flash bus\n",
-- mtx1_map.buswidth*8);
-- mtx1_map.map_priv_1 =
-- (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
- mymtd = do_map_probe("cfi_probe", &mtx1_map);
-- if (!mymtd) return -ENXIO;
-- mymtd->module = THIS_MODULE;
-+ if (!mymtd) {
-+ iounmap(mtx1_map.virt);
-+ return -ENXIO;
-+ }
-+
-+ mymtd->owner = THIS_MODULE;
-
-- add_mtd_partitions(mymtd, parts, nb_parts);
-- return 0;
-+ return add_mtd_partitions(mymtd, mtx1_partitions, ARRAY_SIZE(mtx1_partitions));
- }
-
- static void __exit mtx1_mtd_cleanup(void)
-@@ -168,14 +80,14 @@
- if (mymtd) {
- del_mtd_partitions(mymtd);
- map_destroy(mymtd);
-- if (parsed_parts)
-- kfree(parsed_parts);
- }
-+ if (mtx1_map.virt)
-+ iounmap(mtx1_map.virt);
- }
-
- module_init(mtx1_mtd_init);
- module_exit(mtx1_mtd_cleanup);
-
--MODULE_AUTHOR("Pete Popov");
-+MODULE_AUTHOR("Bruno Randolf <bruno.randolf@4g-systems.biz>");
- MODULE_DESCRIPTION("MTX-1 CFI map driver");
- MODULE_LICENSE("GPL");
-
diff --git a/linux/linux-mtx-1-2.4.27/03-mtd-erase-compiler-bug.diff b/linux/linux-mtx-1-2.4.27/03-mtd-erase-compiler-bug.diff
deleted file mode 100644
index 9e310bf327..0000000000
--- a/linux/linux-mtx-1-2.4.27/03-mtd-erase-compiler-bug.diff
+++ /dev/null
@@ -1,21 +0,0 @@
---- linux-mips-2.4.24-pre2+mtd-2004-01-27/fs/jffs2/erase.c 2004-11-17 18:17:59.000000000 +0100
-+++ linux/fs/jffs2/erase.c 2004-11-17 18:44:52.260067088 +0100
-@@ -365,11 +365,13 @@
- jeb->dirty_size = 0;
- jeb->wasted_size = 0;
- } else {
-- struct jffs2_unknown_node marker = {
-- .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),
-- .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
-- .totlen = cpu_to_je32(c->cleanmarker_size)
-- };
-+ /* compiler workaround, structure was not initialized before
-+ on mipsel cross compilers
-+ fix by Eugene.Wisor@flukenetworks.com */
-+ struct jffs2_unknown_node marker;
-+ marker.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-+ marker.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);
-+ marker.totlen = cpu_to_je32(c->cleanmarker_size);
-
- marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4));
-
diff --git a/linux/linux-mtx-1-2.4.27/04-mtx-1-board-reset.diff b/linux/linux-mtx-1-2.4.27/04-mtx-1-board-reset.diff
deleted file mode 100644
index 9a13c2a403..0000000000
--- a/linux/linux-mtx-1-2.4.27/04-mtx-1-board-reset.diff
+++ /dev/null
@@ -1,15 +0,0 @@
---- linux/arch/mips/au1000/mtx-1/board_setup.c.orig 2004-10-13 19:05:15.340583632 +0200
-+++ linux/arch/mips/au1000/mtx-1/board_setup.c 2004-10-13 19:01:03.402883984 +0200
-@@ -48,6 +48,12 @@
-
- extern struct rtc_ops no_rtc_ops;
-
-+void board_reset (void)
-+{
-+ /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
-+ au_writel(0x00000000, 0xAE00001C);
-+}
-+
- void __init board_setup(void)
- {
- rtc_ops = &no_rtc_ops;
diff --git a/linux/linux-mtx-1-2.4.27/05-mtx-1-pci-irq.diff b/linux/linux-mtx-1-2.4.27/05-mtx-1-pci-irq.diff
deleted file mode 100644
index 4fc6b9e667..0000000000
--- a/linux/linux-mtx-1-2.4.27/05-mtx-1-pci-irq.diff
+++ /dev/null
@@ -1,18 +0,0 @@
-diff -Nurb linux-mips-2.4.27/arch/mips/au1000/mtx-1/irqmap.c linux/arch/mips/au1000/mtx-1/irqmap.c
---- linux-mips-2.4.27/arch/mips/au1000/mtx-1/irqmap.c 2004-04-02 11:04:00.000000000 +0200
-+++ linux/arch/mips/au1000/mtx-1/irqmap.c 2004-11-22 14:15:56.000000000 +0100
-@@ -72,10 +72,10 @@
- * A B C D
- */
- {
-- {INTA, INTB, INTC, INTD}, /* IDSEL 0 */
-- {INTA, INTB, INTC, INTD}, /* IDSEL 1 */
-- {INTA, INTB, INTC, INTD}, /* IDSEL 2 */
-- {INTA, INTB, INTC, INTD}, /* IDSEL 3 */
-+ {INTA, INTB, INTX, INTX}, /* IDSEL 0 */
-+ {INTB, INTA, INTX, INTX}, /* IDSEL 1 */
-+ {INTC, INTD, INTX, INTX}, /* IDSEL 2 */
-+ {INTD, INTC, INTX, INTX}, /* IDSEL 3 */
- };
- const long min_idsel = 0, max_idsel = 3, irqs_per_slot = 4;
- return PCI_IRQ_TABLE_LOOKUP;
diff --git a/linux/linux-mtx-1-2.4.27/06-zboot-2.4.26.patch b/linux/linux-mtx-1-2.4.27/06-zboot-2.4.26.patch
deleted file mode 100644
index 573aa7f0cf..0000000000
--- a/linux/linux-mtx-1-2.4.27/06-zboot-2.4.26.patch
+++ /dev/null
@@ -1,5308 +0,0 @@
-diff -Naru linux/arch/mips/Makefile linux.spi/arch/mips/Makefile
---- linux/arch/mips/Makefile 2004-05-06 15:23:41.000000000 -0400
-+++ linux.spi/arch/mips/Makefile 2004-05-11 23:19:24.000000000 -0400
-@@ -29,6 +29,8 @@
- endif
-
- MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
-+MAKEZBOOT = $(MAKE) -C arch/$(ARCH)/zboot
-+BOOT_TARGETS = zImage zImage.initrd zImage.flash
-
- check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
-
-@@ -757,12 +749,16 @@
-
- vmlinux.ecoff: vmlinux
- @$(MAKEBOOT) $@
-+
-+$(BOOT_TARGETS): vmlinux
-+ @$(MAKEZBOOT) $@
-
- vmlinux.srec: vmlinux
- @$(MAKEBOOT) $@
-
- archclean:
- @$(MAKEBOOT) clean
-+ @$(MAKEZBOOT) clean
- rm -f arch/$(ARCH)/ld.script
- $(MAKE) -C arch/$(ARCH)/tools clean
- $(MAKE) -C arch/mips/baget clean
-diff -Naru linux/arch/mips/zboot/common/au1k_uart.c linux.spi/arch/mips/zboot/common/au1k_uart.c
---- linux/arch/mips/zboot/common/au1k_uart.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/common/au1k_uart.c 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,103 @@
-+/*
-+ * BRIEF MODULE DESCRIPTION
-+ * Simple Au1000 uart routines.
-+ *
-+ * Copyright 2001 MontaVista Software Inc.
-+ * Author: MontaVista Software, Inc.
-+ * ppopov@mvista.com or source@mvista.com
-+ *
-+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
-+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * 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/config.h>
-+#include <asm/io.h>
-+#include <asm/au1000.h>
-+#include "ns16550.h"
-+
-+typedef unsigned char uint8;
-+typedef unsigned int uint32;
-+
-+#define UART16550_BAUD_2400 2400
-+#define UART16550_BAUD_4800 4800
-+#define UART16550_BAUD_9600 9600
-+#define UART16550_BAUD_19200 19200
-+#define UART16550_BAUD_38400 38400
-+#define UART16550_BAUD_57600 57600
-+#define UART16550_BAUD_115200 115200
-+
-+#define UART16550_PARITY_NONE 0
-+#define UART16550_PARITY_ODD 0x08
-+#define UART16550_PARITY_EVEN 0x18
-+#define UART16550_PARITY_MARK 0x28
-+#define UART16550_PARITY_SPACE 0x38
-+
-+#define UART16550_DATA_5BIT 0x0
-+#define UART16550_DATA_6BIT 0x1
-+#define UART16550_DATA_7BIT 0x2
-+#define UART16550_DATA_8BIT 0x3
-+
-+#define UART16550_STOP_1BIT 0x0
-+#define UART16550_STOP_2BIT 0x4
-+
-+/* It would be nice if we had a better way to do this.
-+ * It could be a variable defined in one of the board specific files.
-+ */
-+#undef UART_BASE
-+#ifdef CONFIG_COGENT_CSB250
-+#define UART_BASE UART3_ADDR
-+#else
-+#define UART_BASE UART0_ADDR
-+#endif
-+
-+/* memory-mapped read/write of the port */
-+#define UART16550_READ(y) (readl(UART_BASE + y) & 0xff)
-+#define UART16550_WRITE(y,z) (writel(z&0xff, UART_BASE + y))
-+
-+/*
-+ * We use uart 0, which is already initialized by
-+ * yamon.
-+ */
-+volatile struct NS16550 *
-+serial_init(int chan)
-+{
-+ volatile struct NS16550 *com_port;
-+ com_port = (struct NS16550 *) UART_BASE;
-+ return (com_port);
-+}
-+
-+void
-+serial_putc(volatile struct NS16550 *com_port, unsigned char c)
-+{
-+ while ((UART16550_READ(UART_LSR)&0x40) == 0);
-+ UART16550_WRITE(UART_TX, c);
-+}
-+
-+unsigned char
-+serial_getc(volatile struct NS16550 *com_port)
-+{
-+ while((UART16550_READ(UART_LSR) & 0x1) == 0);
-+ return UART16550_READ(UART_RX);
-+}
-+
-+int
-+serial_tstc(volatile struct NS16550 *com_port)
-+{
-+ return((UART16550_READ(UART_LSR) & LSR_DR) != 0);
-+}
-diff -Naru linux/arch/mips/zboot/common/ctype.c linux.spi/arch/mips/zboot/common/ctype.c
---- linux/arch/mips/zboot/common/ctype.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/common/ctype.c 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,35 @@
-+/*
-+ * linux/lib/ctype.c
-+ *
-+ * Copyright (C) 1991, 1992 Linus Torvalds
-+ */
-+
-+#include <linux/ctype.h>
-+
-+unsigned char _ctype[] = {
-+_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
-+_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
-+_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
-+_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
-+_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
-+_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
-+_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
-+_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
-+_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
-+_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
-+_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
-+_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
-+_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
-+_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
-+_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
-+_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
-+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
-+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
-+_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
-+_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
-+_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
-+_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
-+_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
-+_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
-+
-+
-diff -Naru linux/arch/mips/zboot/common/dummy.c linux.spi/arch/mips/zboot/common/dummy.c
---- linux/arch/mips/zboot/common/dummy.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/common/dummy.c 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,4 @@
-+int main(void)
-+{
-+ return 0;
-+}
-diff -Naru linux/arch/mips/zboot/common/Makefile linux.spi/arch/mips/zboot/common/Makefile
---- linux/arch/mips/zboot/common/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/common/Makefile 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,27 @@
-+#
-+# arch/mips/zboot/common/Makefile
-+#
-+# This file is subject to the terms and conditions of the GNU General Public
-+# License. See the file "COPYING" in the main directory of this archive
-+# for more details.
-+#
-+# Tom Rini January 2001
-+#
-+
-+.c.s:
-+ $(CC) $(CFLAGS) -S -o $*.s $<
-+.s.o:
-+ $(AS) -o $*.o $<
-+.c.o:
-+ $(CC) $(CFLAGS) -c -o $*.o $<
-+.S.s:
-+ $(CPP) $(AFLAGS) -o $*.o $<
-+.S.o:
-+ $(CC) $(AFLAGS) -c -o $*.o $<
-+
-+clean:
-+ rm -rf *.o
-+
-+OBJCOPY_ARGS = -O elf32-tradlittlemips
-+
-+include $(TOPDIR)/Rules.make
-diff -Naru linux/arch/mips/zboot/common/misc-common.c linux.spi/arch/mips/zboot/common/misc-common.c
---- linux/arch/mips/zboot/common/misc-common.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/common/misc-common.c 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,437 @@
-+/*
-+ * arch/mips/zboot/common/misc-common.c
-+ *
-+ * Misc. bootloader code (almost) all platforms can use
-+ *
-+ * Author: Johnnie Peters <jpeters@mvista.com>
-+ * Editor: Tom Rini <trini@mvista.com>
-+ *
-+ * Derived from arch/ppc/boot/prep/misc.c
-+ *
-+ * Ported by Pete Popov <ppopov@mvista.com> to
-+ * support mips board(s). I also got rid of the vga console
-+ * code.
-+ *
-+ * Copyright 2000-2001 MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ *
-+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
-+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * 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/config.h>
-+#include "zlib.h"
-+#include <stdarg.h>
-+
-+extern char *avail_ram;
-+extern char *end_avail;
-+extern char _end[];
-+
-+void puts(const char *);
-+void putc(const char c);
-+void puthex(unsigned long val);
-+void _bcopy(char *src, char *dst, int len);
-+void gunzip(void *, int, unsigned char *, int *);
-+static int _cvt(unsigned long val, char *buf, long radix, char *digits);
-+
-+void _vprintk(void(*)(const char), const char *, va_list ap);
-+
-+struct NS16550 *com_port;
-+
-+int serial_tstc(volatile struct NS16550 *);
-+unsigned char serial_getc(volatile struct NS16550 *);
-+void serial_putc(volatile struct NS16550 *, unsigned char);
-+
-+void pause(void)
-+{
-+ puts("pause\n");
-+}
-+
-+void exit(void)
-+{
-+ puts("exit\n");
-+ while(1);
-+}
-+
-+int tstc(void)
-+{
-+ return (serial_tstc(com_port));
-+}
-+
-+int getc(void)
-+{
-+ while (1) {
-+ if (serial_tstc(com_port))
-+ return (serial_getc(com_port));
-+ }
-+}
-+
-+void
-+putc(const char c)
-+{
-+ int x,y;
-+
-+ serial_putc(com_port, c);
-+ if ( c == '\n' )
-+ serial_putc(com_port, '\r');
-+}
-+
-+void puts(const char *s)
-+{
-+ char c;
-+ while ( ( c = *s++ ) != '\0' ) {
-+ serial_putc(com_port, c);
-+ if ( c == '\n' ) serial_putc(com_port, '\r');
-+ }
-+}
-+
-+void error(char *x)
-+{
-+ puts("\n\n");
-+ puts(x);
-+ puts("\n\n -- System halted");
-+
-+ while(1); /* Halt */
-+}
-+
-+void *zalloc(void *x, unsigned items, unsigned size)
-+{
-+ void *p = avail_ram;
-+
-+ size *= items;
-+ size = (size + 7) & -8;
-+ avail_ram += size;
-+ if (avail_ram > end_avail) {
-+ puts("oops... out of memory\n");
-+ pause();
-+ }
-+ return p;
-+}
-+
-+void zfree(void *x, void *addr, unsigned nb)
-+{
-+}
-+
-+#define HEAD_CRC 2
-+#define EXTRA_FIELD 4
-+#define ORIG_NAME 8
-+#define COMMENT 0x10
-+#define RESERVED 0xe0
-+
-+#define DEFLATED 8
-+
-+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
-+{
-+ z_stream s;
-+ int r, i, flags;
-+
-+ /* skip header */
-+ i = 10;
-+ flags = src[3];
-+ if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
-+ puts("bad gzipped data\n");
-+ exit();
-+ }
-+ if ((flags & EXTRA_FIELD) != 0)
-+ i = 12 + src[10] + (src[11] << 8);
-+ if ((flags & ORIG_NAME) != 0)
-+ while (src[i++] != 0)
-+ ;
-+ if ((flags & COMMENT) != 0)
-+ while (src[i++] != 0)
-+ ;
-+ if ((flags & HEAD_CRC) != 0)
-+ i += 2;
-+ if (i >= *lenp) {
-+ puts("gunzip: ran out of data in header\n");
-+ exit();
-+ }
-+
-+ s.zalloc = zalloc;
-+ s.zfree = zfree;
-+ r = inflateInit2(&s, -MAX_WBITS);
-+ if (r != Z_OK) {
-+ puts("inflateInit2 returned %d\n");
-+ exit();
-+ }
-+ s.next_in = src + i;
-+ s.avail_in = *lenp - i;
-+ s.next_out = dst;
-+ s.avail_out = dstlen;
-+ r = inflate(&s, Z_FINISH);
-+ if (r != Z_OK && r != Z_STREAM_END) {
-+ puts("inflate returned %d\n");
-+ exit();
-+ }
-+ *lenp = s.next_out - (unsigned char *) dst;
-+ inflateEnd(&s);
-+}
-+
-+void
-+puthex(unsigned long val)
-+{
-+
-+ unsigned char buf[10];
-+ int i;
-+ for (i = 7; i >= 0; i--)
-+ {
-+ buf[i] = "0123456789ABCDEF"[val & 0x0F];
-+ val >>= 4;
-+ }
-+ buf[8] = '\0';
-+ puts(buf);
-+}
-+
-+#define FALSE 0
-+#define TRUE 1
-+
-+void
-+_printk(char const *fmt, ...)
-+{
-+ va_list ap;
-+
-+ va_start(ap, fmt);
-+ _vprintk(putc, fmt, ap);
-+ va_end(ap);
-+ return;
-+}
-+
-+#define is_digit(c) ((c >= '0') && (c <= '9'))
-+
-+void
-+_vprintk(void(*putc)(const char), const char *fmt0, va_list ap)
-+{
-+ char c, sign, *cp = 0;
-+ int left_prec, right_prec, zero_fill, length = 0, pad, pad_on_right;
-+ char buf[32];
-+ long val;
-+ while ((c = *fmt0++))
-+ {
-+ if (c == '%')
-+ {
-+ c = *fmt0++;
-+ left_prec = right_prec = pad_on_right = 0;
-+ if (c == '-')
-+ {
-+ c = *fmt0++;
-+ pad_on_right++;
-+ }
-+ if (c == '0')
-+ {
-+ zero_fill = TRUE;
-+ c = *fmt0++;
-+ } else
-+ {
-+ zero_fill = FALSE;
-+ }
-+ while (is_digit(c))
-+ {
-+ left_prec = (left_prec * 10) + (c - '0');
-+ c = *fmt0++;
-+ }
-+ if (c == '.')
-+ {
-+ c = *fmt0++;
-+ zero_fill++;
-+ while (is_digit(c))
-+ {
-+ right_prec = (right_prec * 10) + (c - '0');
-+ c = *fmt0++;
-+ }
-+ } else
-+ {
-+ right_prec = left_prec;
-+ }
-+ sign = '\0';
-+ switch (c)
-+ {
-+ case 'd':
-+ case 'x':
-+ case 'X':
-+ val = va_arg(ap, long);
-+ switch (c)
-+ {
-+ case 'd':
-+ if (val < 0)
-+ {
-+ sign = '-';
-+ val = -val;
-+ }
-+ length = _cvt(val, buf, 10, "0123456789");
-+ break;
-+ case 'x':
-+ length = _cvt(val, buf, 16, "0123456789abcdef");
-+ break;
-+ case 'X':
-+ length = _cvt(val, buf, 16, "0123456789ABCDEF");
-+ break;
-+ }
-+ cp = buf;
-+ break;
-+ case 's':
-+ cp = va_arg(ap, char *);
-+ length = strlen(cp);
-+ break;
-+ case 'c':
-+ c = va_arg(ap, long /*char*/);
-+ (*putc)(c);
-+ continue;
-+ default:
-+ (*putc)('?');
-+ }
-+ pad = left_prec - length;
-+ if (sign != '\0')
-+ {
-+ pad--;
-+ }
-+ if (zero_fill)
-+ {
-+ c = '0';
-+ if (sign != '\0')
-+ {
-+ (*putc)(sign);
-+ sign = '\0';
-+ }
-+ } else
-+ {
-+ c = ' ';
-+ }
-+ if (!pad_on_right)
-+ {
-+ while (pad-- > 0)
-+ {
-+ (*putc)(c);
-+ }
-+ }
-+ if (sign != '\0')
-+ {
-+ (*putc)(sign);
-+ }
-+ while (length-- > 0)
-+ {
-+ (*putc)(c = *cp++);
-+ if (c == '\n')
-+ {
-+ (*putc)('\r');
-+ }
-+ }
-+ if (pad_on_right)
-+ {
-+ while (pad-- > 0)
-+ {
-+ (*putc)(c);
-+ }
-+ }
-+ } else
-+ {
-+ (*putc)(c);
-+ if (c == '\n')
-+ {
-+ (*putc)('\r');
-+ }
-+ }
-+ }
-+}
-+
-+int
-+_cvt(unsigned long val, char *buf, long radix, char *digits)
-+{
-+ char temp[80];
-+ char *cp = temp;
-+ int length = 0;
-+ if (val == 0)
-+ { /* Special case */
-+ *cp++ = '0';
-+ } else
-+ while (val)
-+ {
-+ *cp++ = digits[val % radix];
-+ val /= radix;
-+ }
-+ while (cp != temp)
-+ {
-+ *buf++ = *--cp;
-+ length++;
-+ }
-+ *buf = '\0';
-+ return (length);
-+}
-+
-+void
-+_dump_buf_with_offset(unsigned char *p, int s, unsigned char *base)
-+{
-+ int i, c;
-+ if ((unsigned int)s > (unsigned int)p)
-+ {
-+ s = (unsigned int)s - (unsigned int)p;
-+ }
-+ while (s > 0)
-+ {
-+ if (base)
-+ {
-+ _printk("%06X: ", (int)p - (int)base);
-+ } else
-+ {
-+ _printk("%06X: ", p);
-+ }
-+ for (i = 0; i < 16; i++)
-+ {
-+ if (i < s)
-+ {
-+ _printk("%02X", p[i] & 0xFF);
-+ } else
-+ {
-+ _printk(" ");
-+ }
-+ if ((i % 2) == 1) _printk(" ");
-+ if ((i % 8) == 7) _printk(" ");
-+ }
-+ _printk(" |");
-+ for (i = 0; i < 16; i++)
-+ {
-+ if (i < s)
-+ {
-+ c = p[i] & 0xFF;
-+ if ((c < 0x20) || (c >= 0x7F)) c = '.';
-+ } else
-+ {
-+ c = ' ';
-+ }
-+ _printk("%c", c);
-+ }
-+ _printk("|\n");
-+ s -= 16;
-+ p += 16;
-+ }
-+}
-+
-+void
-+_dump_buf(unsigned char *p, int s)
-+{
-+ _printk("\n");
-+ _dump_buf_with_offset(p, s, 0);
-+}
-+
-+/*
-+ * Local variables:
-+ * c-indent-level: 8
-+ * c-basic-offset: 8
-+ * tab-width: 8
-+ * End:
-+ */
-diff -Naru linux/arch/mips/zboot/common/misc-simple.c linux.spi/arch/mips/zboot/common/misc-simple.c
---- linux/arch/mips/zboot/common/misc-simple.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/common/misc-simple.c 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,127 @@
-+/*
-+ * arch/mips/zboot/common/misc-simple.c
-+ *
-+ * Misc. bootloader code for many machines. This assumes you have are using
-+ * a 6xx/7xx/74xx CPU in your machine. This assumes the chunk of memory
-+ * below 8MB is free. Finally, it assumes you have a NS16550-style uart for
-+ * your serial console. If a machine meets these requirements, it can quite
-+ * likely use this code during boot.
-+ *
-+ * Author: Matt Porter <mporter@mvista.com>
-+ * Derived from arch/ppc/boot/prep/misc.c
-+ *
-+ * Copyright 2001 MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/elf.h>
-+#include <linux/config.h>
-+
-+#include <asm/page.h>
-+#include <asm/processor.h>
-+#include <asm/mmu.h>
-+
-+#include "zlib.h"
-+
-+extern struct NS16550 *com_port;
-+
-+char *avail_ram;
-+char *end_avail;
-+extern char _end[];
-+char *zimage_start;
-+
-+#ifdef CONFIG_CMDLINE
-+#define CMDLINE CONFIG_CMDLINE
-+#else
-+#define CMDLINE ""
-+#endif
-+char cmd_preset[] = CMDLINE;
-+char cmd_buf[256];
-+char *cmd_line = cmd_buf;
-+
-+/* The linker tells us where the image is.
-+*/
-+extern unsigned char __image_begin, __image_end;
-+extern unsigned char __ramdisk_begin, __ramdisk_end;
-+unsigned long initrd_size;
-+
-+extern void puts(const char *);
-+extern void putc(const char c);
-+extern void puthex(unsigned long val);
-+extern void *memcpy(void * __dest, __const void * __src,
-+ __kernel_size_t __n);
-+extern void gunzip(void *, int, unsigned char *, int *);
-+extern void udelay(long delay);
-+extern int tstc(void);
-+extern int getc(void);
-+extern volatile struct NS16550 *serial_init(int chan);
-+
-+void
-+decompress_kernel(unsigned long load_addr, int num_words,
-+ unsigned long cksum, unsigned long *sp)
-+{
-+ int timer = 0;
-+ extern unsigned long start;
-+ char *cp, ch;
-+ int i;
-+ int zimage_size;
-+
-+ com_port = (struct NS16550 *)serial_init(0);
-+
-+ initrd_size = (unsigned long)(&__ramdisk_end) -
-+ (unsigned long)(&__ramdisk_begin);
-+
-+ /*
-+ * Reveal where we were loaded at and where we
-+ * were relocated to.
-+ */
-+ puts("loaded at: "); puthex(load_addr);
-+ puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n");
-+ if ( (unsigned long)load_addr != (unsigned long)&start )
-+ {
-+ puts("relocated to: "); puthex((unsigned long)&start);
-+ puts(" ");
-+ puthex((unsigned long)((unsigned long)&start + (4*num_words)));
-+ puts("\n");
-+ }
-+
-+ /*
-+ * We link ourself to an arbitrary low address. When we run, we
-+ * relocate outself to that address. __image_being points to
-+ * the part of the image where the zImage is. -- Tom
-+ */
-+ zimage_start = (char *)(unsigned long)(&__image_begin);
-+ zimage_size = (unsigned long)(&__image_end) -
-+ (unsigned long)(&__image_begin);
-+
-+ /*
-+ * The zImage and initrd will be between start and _end, so they've
-+ * already been moved once. We're good to go now. -- Tom
-+ */
-+ puts("zimage at: "); puthex((unsigned long)zimage_start);
-+ puts(" "); puthex((unsigned long)(zimage_size+zimage_start));
-+ puts("\n");
-+
-+ if ( initrd_size ) {
-+ puts("initrd at: ");
-+ puthex((unsigned long)(&__ramdisk_begin));
-+ puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n");
-+ }
-+
-+ /* assume the chunk below 8M is free */
-+ avail_ram = (char *)AVAIL_RAM_START;
-+ end_avail = (char *)AVAIL_RAM_END;
-+
-+ /* Display standard Linux/MIPS boot prompt for kernel args */
-+ puts("Uncompressing Linux at load address ");
-+ puthex(LOADADDR);
-+ puts("\n");
-+ /* I don't like this hard coded gunzip size (fixme) */
-+ gunzip((void *)LOADADDR, 0x400000, zimage_start, &zimage_size);
-+ puts("Now booting the kernel\n");
-+}
-diff -Naru linux/arch/mips/zboot/common/no_initrd.c linux.spi/arch/mips/zboot/common/no_initrd.c
---- linux/arch/mips/zboot/common/no_initrd.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/common/no_initrd.c 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,2 @@
-+char initrd_data[1];
-+int initrd_len = 0;
-diff -Naru linux/arch/mips/zboot/common/ns16550.c linux.spi/arch/mips/zboot/common/ns16550.c
---- linux/arch/mips/zboot/common/ns16550.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/common/ns16550.c 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,57 @@
-+/*
-+ * NS16550 support
-+ */
-+
-+#include <linux/config.h>
-+#include <asm/serial.h>
-+#include "ns16550.h"
-+
-+typedef struct NS16550 *NS16550_t;
-+
-+const NS16550_t COM_PORTS[] = { (NS16550_t) COM1,
-+ (NS16550_t) COM2,
-+ (NS16550_t) COM3,
-+ (NS16550_t) COM4 };
-+
-+volatile struct NS16550 *
-+serial_init(int chan)
-+{
-+ volatile struct NS16550 *com_port;
-+ com_port = (struct NS16550 *) COM_PORTS[chan];
-+ /* See if port is present */
-+ com_port->lcr = 0x00;
-+ com_port->ier = 0xFF;
-+#if 0
-+ if (com_port->ier != 0x0F) return ((struct NS16550 *)0);
-+#endif
-+ com_port->ier = 0x00;
-+ com_port->lcr = 0x80; /* Access baud rate */
-+#ifdef CONFIG_SERIAL_CONSOLE_NONSTD
-+ com_port->dll = (BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD);
-+ com_port->dlm = (BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD) >> 8;
-+#endif
-+ com_port->lcr = 0x03; /* 8 data, 1 stop, no parity */
-+ com_port->mcr = 0x03; /* RTS/DTR */
-+ com_port->fcr = 0x07; /* Clear & enable FIFOs */
-+ return (com_port);
-+}
-+
-+void
-+serial_putc(volatile struct NS16550 *com_port, unsigned char c)
-+{
-+ while ((com_port->lsr & LSR_THRE) == 0) ;
-+ com_port->thr = c;
-+}
-+
-+unsigned char
-+serial_getc(volatile struct NS16550 *com_port)
-+{
-+ while ((com_port->lsr & LSR_DR) == 0) ;
-+ return (com_port->rbr);
-+}
-+
-+int
-+serial_tstc(volatile struct NS16550 *com_port)
-+{
-+ return ((com_port->lsr & LSR_DR) != 0);
-+}
-diff -Naru linux/arch/mips/zboot/common/string.c linux.spi/arch/mips/zboot/common/string.c
---- linux/arch/mips/zboot/common/string.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/common/string.c 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,497 @@
-+/*
-+ * linux/lib/string.c
-+ *
-+ * Copyright (C) 1991, 1992 Linus Torvalds
-+ */
-+
-+/*
-+ * stupid library routines.. The optimized versions should generally be found
-+ * as inline code in <asm-xx/string.h>
-+ *
-+ * These are buggy as well..
-+ *
-+ * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>
-+ * - Added strsep() which will replace strtok() soon (because strsep() is
-+ * reentrant and should be faster). Use only strsep() in new code, please.
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/string.h>
-+#include <linux/ctype.h>
-+
-+/**
-+ * strnicmp - Case insensitive, length-limited string comparison
-+ * @s1: One string
-+ * @s2: The other string
-+ * @len: the maximum number of characters to compare
-+ */
-+int strnicmp(const char *s1, const char *s2, size_t len)
-+{
-+ /* Yes, Virginia, it had better be unsigned */
-+ unsigned char c1, c2;
-+
-+ c1 = 0; c2 = 0;
-+ if (len) {
-+ do {
-+ c1 = *s1; c2 = *s2;
-+ s1++; s2++;
-+ if (!c1)
-+ break;
-+ if (!c2)
-+ break;
-+ if (c1 == c2)
-+ continue;
-+ c1 = tolower(c1);
-+ c2 = tolower(c2);
-+ if (c1 != c2)
-+ break;
-+ } while (--len);
-+ }
-+ return (int)c1 - (int)c2;
-+}
-+
-+char * ___strtok;
-+
-+#ifndef __HAVE_ARCH_STRCPY
-+/**
-+ * strcpy - Copy a %NUL terminated string
-+ * @dest: Where to copy the string to
-+ * @src: Where to copy the string from
-+ */
-+char * strcpy(char * dest,const char *src)
-+{
-+ char *tmp = dest;
-+
-+ while ((*dest++ = *src++) != '\0')
-+ /* nothing */;
-+ return tmp;
-+}
-+#endif
-+
-+#ifndef __HAVE_ARCH_STRNCPY
-+/**
-+ * strncpy - Copy a length-limited, %NUL-terminated string
-+ * @dest: Where to copy the string to
-+ * @src: Where to copy the string from
-+ * @count: The maximum number of bytes to copy
-+ *
-+ * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
-+ * However, the result is not %NUL-terminated if the source exceeds
-+ * @count bytes.
-+ */
-+char * strncpy(char * dest,const char *src,size_t count)
-+{
-+ char *tmp = dest;
-+
-+ while (count-- && (*dest++ = *src++) != '\0')
-+ /* nothing */;
-+
-+ return tmp;
-+}
-+#endif
-+
-+/**
-+ * strcat - Append one %NUL-terminated string to another
-+ * @dest: The string to be appended to
-+ * @src: The string to append to it
-+ */
-+char * strcat(char * dest, const char * src)
-+{
-+ char *tmp = dest;
-+
-+ while (*dest)
-+ dest++;
-+ while ((*dest++ = *src++) != '\0')
-+ ;
-+
-+ return tmp;
-+}
-+
-+/**
-+ * strncat - Append a length-limited, %NUL-terminated string to another
-+ * @dest: The string to be appended to
-+ * @src: The string to append to it
-+ * @count: The maximum numbers of bytes to copy
-+ *
-+ * Note that in contrast to strncpy, strncat ensures the result is
-+ * terminated.
-+ */
-+char * strncat(char *dest, const char *src, size_t count)
-+{
-+ char *tmp = dest;
-+
-+ if (count) {
-+ while (*dest)
-+ dest++;
-+ while ((*dest++ = *src++)) {
-+ if (--count == 0) {
-+ *dest = '\0';
-+ break;
-+ }
-+ }
-+ }
-+
-+ return tmp;
-+}
-+
-+#ifndef __HAVE_ARCH_STRCMP
-+/**
-+ * strcmp - Compare two strings
-+ * @cs: One string
-+ * @ct: Another string
-+ */
-+int strcmp(const char * cs,const char * ct)
-+{
-+ register signed char __res;
-+
-+ while (1) {
-+ if ((__res = *cs - *ct++) != 0 || !*cs++)
-+ break;
-+ }
-+
-+ return __res;
-+}
-+#endif
-+
-+#ifndef __HAVE_ARCH_STRNCMP
-+/**
-+ * strncmp - Compare two length-limited strings
-+ * @cs: One string
-+ * @ct: Another string
-+ * @count: The maximum number of bytes to compare
-+ */
-+int strncmp(const char * cs,const char * ct,size_t count)
-+{
-+ register signed char __res = 0;
-+
-+ while (count) {
-+ if ((__res = *cs - *ct++) != 0 || !*cs++)
-+ break;
-+ count--;
-+ }
-+
-+ return __res;
-+}
-+#endif
-+
-+/**
-+ * strchr - Find the first occurrence of a character in a string
-+ * @s: The string to be searched
-+ * @c: The character to search for
-+ */
-+char * strchr(const char * s, int c)
-+{
-+ for(; *s != (char) c; ++s)
-+ if (*s == '\0')
-+ return NULL;
-+ return (char *) s;
-+}
-+
-+/**
-+ * strrchr - Find the last occurrence of a character in a string
-+ * @s: The string to be searched
-+ * @c: The character to search for
-+ */
-+char * strrchr(const char * s, int c)
-+{
-+ const char *p = s + strlen(s);
-+ do {
-+ if (*p == (char)c)
-+ return (char *)p;
-+ } while (--p >= s);
-+ return NULL;
-+}
-+
-+/**
-+ * strlen - Find the length of a string
-+ * @s: The string to be sized
-+ */
-+size_t strlen(const char * s)
-+{
-+ const char *sc;
-+
-+ for (sc = s; *sc != '\0'; ++sc)
-+ /* nothing */;
-+ return sc - s;
-+}
-+
-+/**
-+ * strnlen - Find the length of a length-limited string
-+ * @s: The string to be sized
-+ * @count: The maximum number of bytes to search
-+ */
-+size_t strnlen(const char * s, size_t count)
-+{
-+ const char *sc;
-+
-+ for (sc = s; count-- && *sc != '\0'; ++sc)
-+ /* nothing */;
-+ return sc - s;
-+}
-+
-+/**
-+ * strspn - Calculate the length of the initial substring of @s which only
-+ * contain letters in @accept
-+ * @s: The string to be searched
-+ * @accept: The string to search for
-+ */
-+size_t strspn(const char *s, const char *accept)
-+{
-+ const char *p;
-+ const char *a;
-+ size_t count = 0;
-+
-+ for (p = s; *p != '\0'; ++p) {
-+ for (a = accept; *a != '\0'; ++a) {
-+ if (*p == *a)
-+ break;
-+ }
-+ if (*a == '\0')
-+ return count;
-+ ++count;
-+ }
-+
-+ return count;
-+}
-+
-+/**
-+ * strpbrk - Find the first occurrence of a set of characters
-+ * @cs: The string to be searched
-+ * @ct: The characters to search for
-+ */
-+char * strpbrk(const char * cs,const char * ct)
-+{
-+ const char *sc1,*sc2;
-+
-+ for( sc1 = cs; *sc1 != '\0'; ++sc1) {
-+ for( sc2 = ct; *sc2 != '\0'; ++sc2) {
-+ if (*sc1 == *sc2)
-+ return (char *) sc1;
-+ }
-+ }
-+ return NULL;
-+}
-+
-+/**
-+ * strtok - Split a string into tokens
-+ * @s: The string to be searched
-+ * @ct: The characters to search for
-+ *
-+ * WARNING: strtok is deprecated, use strsep instead.
-+ */
-+char * strtok(char * s,const char * ct)
-+{
-+ char *sbegin, *send;
-+
-+ sbegin = s ? s : ___strtok;
-+ if (!sbegin) {
-+ return NULL;
-+ }
-+ sbegin += strspn(sbegin,ct);
-+ if (*sbegin == '\0') {
-+ ___strtok = NULL;
-+ return( NULL );
-+ }
-+ send = strpbrk( sbegin, ct);
-+ if (send && *send != '\0')
-+ *send++ = '\0';
-+ ___strtok = send;
-+ return (sbegin);
-+}
-+
-+/**
-+ * strsep - Split a string into tokens
-+ * @s: The string to be searched
-+ * @ct: The characters to search for
-+ *
-+ * strsep() updates @s to point after the token, ready for the next call.
-+ *
-+ * It returns empty tokens, too, behaving exactly like the libc function
-+ * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
-+ * Same semantics, slimmer shape. ;)
-+ */
-+char * strsep(char **s, const char *ct)
-+{
-+ char *sbegin = *s, *end;
-+
-+ if (sbegin == NULL)
-+ return NULL;
-+
-+ end = strpbrk(sbegin, ct);
-+ if (end)
-+ *end++ = '\0';
-+ *s = end;
-+
-+ return sbegin;
-+}
-+
-+/**
-+ * memset - Fill a region of memory with the given value
-+ * @s: Pointer to the start of the area.
-+ * @c: The byte to fill the area with
-+ * @count: The size of the area.
-+ *
-+ * Do not use memset() to access IO space, use memset_io() instead.
-+ */
-+void * memset(void * s,int c, size_t count)
-+{
-+ char *xs = (char *) s;
-+
-+ while (count--)
-+ *xs++ = c;
-+
-+ return s;
-+}
-+
-+/**
-+ * bcopy - Copy one area of memory to another
-+ * @src: Where to copy from
-+ * @dest: Where to copy to
-+ * @count: The size of the area.
-+ *
-+ * Note that this is the same as memcpy(), with the arguments reversed.
-+ * memcpy() is the standard, bcopy() is a legacy BSD function.
-+ *
-+ * You should not use this function to access IO space, use memcpy_toio()
-+ * or memcpy_fromio() instead.
-+ */
-+char * bcopy(const char * src, char * dest, int count)
-+{
-+ char *tmp = dest;
-+
-+ while (count--)
-+ *tmp++ = *src++;
-+
-+ return dest;
-+}
-+
-+/**
-+ * memcpy - Copy one area of memory to another
-+ * @dest: Where to copy to
-+ * @src: Where to copy from
-+ * @count: The size of the area.
-+ *
-+ * You should not use this function to access IO space, use memcpy_toio()
-+ * or memcpy_fromio() instead.
-+ */
-+void * memcpy(void * dest,const void *src,size_t count)
-+{
-+ char *tmp = (char *) dest, *s = (char *) src;
-+
-+ while (count--)
-+ *tmp++ = *s++;
-+
-+ return dest;
-+}
-+
-+/**
-+ * memmove - Copy one area of memory to another
-+ * @dest: Where to copy to
-+ * @src: Where to copy from
-+ * @count: The size of the area.
-+ *
-+ * Unlike memcpy(), memmove() copes with overlapping areas.
-+ */
-+void * memmove(void * dest,const void *src,size_t count)
-+{
-+ char *tmp, *s;
-+
-+ if (dest <= src) {
-+ tmp = (char *) dest;
-+ s = (char *) src;
-+ while (count--)
-+ *tmp++ = *s++;
-+ }
-+ else {
-+ tmp = (char *) dest + count;
-+ s = (char *) src + count;
-+ while (count--)
-+ *--tmp = *--s;
-+ }
-+
-+ return dest;
-+}
-+
-+/**
-+ * memcmp - Compare two areas of memory
-+ * @cs: One area of memory
-+ * @ct: Another area of memory
-+ * @count: The size of the area.
-+ */
-+int memcmp(const void * cs,const void * ct,size_t count)
-+{
-+ const unsigned char *su1, *su2;
-+ signed char res = 0;
-+
-+ for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
-+ if ((res = *su1 - *su2) != 0)
-+ break;
-+ return res;
-+}
-+
-+#ifndef __HAVE_ARCH_MEMSCAN
-+/**
-+ * memscan - Find a character in an area of memory.
-+ * @addr: The memory area
-+ * @c: The byte to search for
-+ * @size: The size of the area.
-+ *
-+ * returns the address of the first occurrence of @c, or 1 byte past
-+ * the area if @c is not found
-+ */
-+void * memscan(void * addr, int c, size_t size)
-+{
-+ unsigned char * p = (unsigned char *) addr;
-+ unsigned char * e = p + size;
-+
-+ while (p != e) {
-+ if (*p == c)
-+ return (void *) p;
-+ p++;
-+ }
-+
-+ return (void *) p;
-+}
-+#endif
-+
-+/**
-+ * strstr - Find the first substring in a %NUL terminated string
-+ * @s1: The string to be searched
-+ * @s2: The string to search for
-+ */
-+char * strstr(const char * s1,const char * s2)
-+{
-+ int l1, l2;
-+
-+ l2 = strlen(s2);
-+ if (!l2)
-+ return (char *) s1;
-+ l1 = strlen(s1);
-+ while (l1 >= l2) {
-+ l1--;
-+ if (!memcmp(s1,s2,l2))
-+ return (char *) s1;
-+ s1++;
-+ }
-+ return NULL;
-+}
-+
-+/**
-+ * memchr - Find a character in an area of memory.
-+ * @s: The memory area
-+ * @c: The byte to search for
-+ * @n: The size of the area.
-+ *
-+ * returns the address of the first occurrence of @c, or %NULL
-+ * if @c is not found
-+ */
-+void *memchr(const void *s, int c, size_t n)
-+{
-+ const unsigned char *p = s;
-+ while (n-- != 0) {
-+ if ((unsigned char)c == *p++) {
-+ return (void *)(p-1);
-+ }
-+ }
-+ return NULL;
-+}
-diff -Naru linux/arch/mips/zboot/csb250/head.S linux.spi/arch/mips/zboot/csb250/head.S
---- linux/arch/mips/zboot/csb250/head.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/csb250/head.S 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,157 @@
-+/*
-+ * arch/mips/kernel/head.S
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file "COPYING" in the main directory of this archive
-+ * for more details.
-+ *
-+ * Copyright (C) 1994, 1995 Waldorf Electronics
-+ * Written by Ralf Baechle and Andreas Busse
-+ * Copyright (C) 1995 - 1999 Ralf Baechle
-+ * Copyright (C) 1996 Paul M. Antoine
-+ * Modified for DECStation and hence R3000 support by Paul M. Antoine
-+ * Further modifications by David S. Miller and Harald Koerfgen
-+ * Copyright (C) 1999 Silicon Graphics, Inc.
-+ *
-+ * Head.S contains the MIPS exception handler and startup code.
-+ *
-+ **************************************************************************
-+ * 9 Nov, 2000.
-+ * Added Cache Error exception handler and SBDDP EJTAG debug exception.
-+ *
-+ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
-+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
-+ **************************************************************************
-+ */
-+#include <linux/config.h>
-+#include <linux/threads.h>
-+
-+#include <asm/asm.h>
-+#include <asm/cacheops.h>
-+#include <asm/mipsregs.h>
-+#include <asm/offset.h>
-+#include <asm/cachectl.h>
-+#include <asm/regdef.h>
-+
-+#define IndexInvalidate_I 0x00
-+#define IndexWriteBack_D 0x01
-+
-+ .set noreorder
-+ .cprestore
-+ LEAF(start)
-+start:
-+ bal locate
-+ nop
-+
-+ .globl asize /* Someday we'll put the initrd info here. */
-+asize: .word 0
-+ .word 0
-+ .word 0
-+ .word 0
-+
-+locate:
-+ subu s8, ra, 8 /* Where we were loaded */
-+ la sp, (.stack + 8192)
-+
-+ move s0, a0 /* Save boot rom start args */
-+ move s1, a1
-+ move s2, a2
-+ move s3, a3
-+
-+ la a0, start /* Where we were linked to run */
-+
-+ move a1, s8
-+ la a2, _edata
-+ subu t1, a2, a0
-+ srl t1, t1, 2
-+
-+ /* copy text section */
-+ li t0, 0
-+1: lw v0, 0(a1)
-+ nop
-+ sw v0, 0(a0)
-+ xor t0, t0, v0
-+ addu a0, 4
-+ bne a2, a0, 1b
-+ addu a1, 4
-+
-+ /* Clear BSS */
-+ la a0, _edata
-+ la a2, _end
-+2: sw zero, 0(a0)
-+ bne a2, a0, 2b
-+ addu a0, 4
-+
-+ /* push the D-Cache and invalidate I-Cache */
-+ li k0, 0x80000000 # start address
-+ li k1, 0x80004000 # end address (16KB I-Cache)
-+ subu k1, 128
-+
-+1:
-+ .set mips3
-+ cache IndexWriteBack_D, 0(k0)
-+ cache IndexWriteBack_D, 32(k0)
-+ cache IndexWriteBack_D, 64(k0)
-+ cache IndexWriteBack_D, 96(k0)
-+ cache IndexInvalidate_I, 0(k0)
-+ cache IndexInvalidate_I, 32(k0)
-+ cache IndexInvalidate_I, 64(k0)
-+ cache IndexInvalidate_I, 96(k0)
-+ .set mips0
-+
-+ bne k0, k1, 1b
-+ addu k0, k0, 128
-+ /* done */
-+
-+/* move a0, s8 /* load address */
-+ subu a0, s8, 0x1000 /* load address */
-+ move a1, t1 /* length in words */
-+ move a2, t0 /* checksum */
-+ move a3, sp
-+
-+ la ra, 1f
-+ la k0, decompress_kernel
-+ jr k0
-+ nop
-+1:
-+
-+ la a2, __ramdisk_begin
-+ la a3, initrd_size
-+ lw a0, 0(a2)
-+ lw a1, 0(a3)
-+ li k0, KERNEL_ENTRY
-+ jr k0
-+ nop
-+3:
-+ b 3b
-+ END(start)
-+
-+ LEAF(udelay)
-+udelay:
-+ END(udelay)
-+
-+
-+ LEAF(FlushCache)
-+ li k0, 0x80000000 # start address
-+ li k1, 0x80004000 # end address (16KB I-Cache)
-+ subu k1, 128
-+
-+1:
-+ .set mips3
-+ cache IndexWriteBack_D, 0(k0)
-+ cache IndexWriteBack_D, 32(k0)
-+ cache IndexWriteBack_D, 64(k0)
-+ cache IndexWriteBack_D, 96(k0)
-+ cache IndexInvalidate_I, 0(k0)
-+ cache IndexInvalidate_I, 32(k0)
-+ cache IndexInvalidate_I, 64(k0)
-+ cache IndexInvalidate_I, 96(k0)
-+ .set mips0
-+
-+ bne k0, k1, 1b
-+ addu k0, k0, 128
-+ jr ra
-+ nop
-+ END(FlushCache)
-+
-+ .comm .stack,4096*2,4
-diff -Naru linux/arch/mips/zboot/csb250/Makefile linux.spi/arch/mips/zboot/csb250/Makefile
---- linux/arch/mips/zboot/csb250/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/csb250/Makefile 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,90 @@
-+# arch/mips/zboot/pb1xxx/Makefile
-+#
-+# Makefile for Cogent CSB250 Au1500 board.
-+# All of the boot loader code was derived from the ppc
-+# boot code.
-+#
-+# 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.
-+
-+.c.s:
-+ $(CC) $(CFLAGS) -S -o $*.s $<
-+.s.o:
-+ $(AS) -o $*.o $<
-+.c.o:
-+ $(CC) $(CFLAGS) -D__BOOTER__ -c -o $*.o $<
-+.S.s:
-+ $(CPP) $(AFLAGS) -o $*.o $<
-+.S.o:
-+ $(CC) $(AFLAGS) -c -o $*.o $<
-+
-+#########################################################################
-+# START BOARD SPECIFIC VARIABLES
-+BNAME=csb250
-+
-+# These two variables control where the zImage is stored
-+# in flash and loaded in memory. It only controls how the srec
-+# file is generated, the code is the same.
-+RAM_RUN_ADDR = 0x80a00000
-+FLASH_LOAD_ADDR = 0xBFD00000
-+
-+# These two variables specify the free ram region
-+# that can be used for temporary malloc area
-+AVAIL_RAM_START=0x80400000
-+AVAIL_RAM_END=0x80800000
-+
-+# This one must match the LOADADDR in arch/mips/Makefile!
-+LOADADDR=0x80100000
-+# END BOARD SPECIFIC VARIABLES
-+#########################################################################
-+
-+OBJECTS := head.o ../common/misc-common.o ../common/misc-simple.o \
-+ ../common/au1k_uart.o ../common/string.o ../common/ctype.o
-+LIBS := ../lib/zlib.a
-+
-+ENTRY := ../utils/entry
-+OFFSET := ../utils/offset
-+SIZE := ../utils/size
-+
-+LD_ARGS := -T ../ld.script -Ttext $(RAM_RUN_ADDR) -Bstatic
-+OBJCOPY_ARGS = -O elf32-tradbigmips
-+
-+all: zImage
-+
-+clean:
-+ rm -rf *.o vmlinux* zvmlinux.* ../images/*.srec
-+
-+head.o: head.S $(TOPDIR)/vmlinux
-+ $(CC) $(AFLAGS) \
-+ -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) $(TOPDIR)/vmlinux ) \
-+ -c -o $*.o $<
-+
-+../common/misc-simple.o:
-+ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \
-+ -DAVAIL_RAM_START=$(AVAIL_RAM_START) \
-+ -DAVAIL_RAM_END=$(AVAIL_RAM_END) \
-+ -DLOADADDR=$(LOADADDR) \
-+ -DZIMAGE_SIZE=0 -c -o $@ $*.c
-+
-+zvmlinux: $(OBJECTS) $(LIBS) ../ld.script ../images/vmlinux.gz ../common/dummy.o
-+ $(OBJCOPY) \
-+ --add-section=.image=../images/vmlinux.gz \
-+ --set-section-flags=.image=contents,alloc,load,readonly,data \
-+ ../common/dummy.o image.o
-+ $(LD) $(LD_ARGS) -o $@ $(OBJECTS) image.o $(LIBS)
-+ $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr \
-+ -R .initrd -R .sysmap
-+
-+# Here we manipulate the image in order to get it the necessary
-+# srecord file we need.
-+zImage: zvmlinux
-+ mv zvmlinux ../images/zImage.$(BNAME)
-+ $(OBJCOPY) -O binary ../images/zImage.$(BNAME) ../images/$(BNAME).bin
-+
-+zImage.flash: zImage
-+ $(OBJCOPY) -O srec --adjust-vma 0x3ed00000 \
-+ ../images/zImage.$(BNAME) ../images/$(BNAME).flash.srec
-+
-+include $(TOPDIR)/Rules.make
-diff -Naru linux/arch/mips/zboot/images/Makefile linux.spi/arch/mips/zboot/images/Makefile
---- linux/arch/mips/zboot/images/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/images/Makefile 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,10 @@
-+
-+include $(TOPDIR)/Rules.make
-+
-+vmlinux.gz: $(TOPDIR)/vmlinux
-+ $(OBJCOPY) -S -O binary $(TOPDIR)/vmlinux vmlinux
-+ gzip -vf vmlinux
-+
-+clean:
-+ rm -f vmlinux.* zImage.*
-+
-diff -Naru linux/arch/mips/zboot/include/nonstdio.h linux.spi/arch/mips/zboot/include/nonstdio.h
---- linux/arch/mips/zboot/include/nonstdio.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/include/nonstdio.h 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,18 @@
-+/*
-+ * Copyright (C) Paul Mackerras 1997.
-+ *
-+ * 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.
-+ */
-+typedef int FILE;
-+extern FILE *stdin, *stdout;
-+#define NULL ((void *)0)
-+#define EOF (-1)
-+#define fopen(n, m) NULL
-+#define fflush(f) 0
-+#define fclose(f) 0
-+extern char *fgets();
-+
-+#define perror(s) printf("%s: no files!\n", (s))
-diff -Naru linux/arch/mips/zboot/include/ns16550.h linux.spi/arch/mips/zboot/include/ns16550.h
---- linux/arch/mips/zboot/include/ns16550.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/include/ns16550.h 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,49 @@
-+/*
-+ * NS16550 Serial Port
-+ */
-+
-+/*
-+ * Figure out which file will have the definitons of COMx
-+ */
-+#if !defined(CONFIG_AU1X00_UART)
-+#error no serial.h
-+#endif
-+
-+/* Some machines have their uart registers 16 bytes apart. Most don't.
-+ * TODO: Make this work like drivers/char/serial does - Tom */
-+#if !defined(UART_REG_PAD)
-+#define UART_REG_PAD(x)
-+#endif
-+
-+struct NS16550
-+ {
-+ unsigned char rbr; /* 0 */
-+ UART_REG_PAD(rbr)
-+ unsigned char ier; /* 1 */
-+ UART_REG_PAD(ier)
-+ unsigned char fcr; /* 2 */
-+ UART_REG_PAD(fcr)
-+ unsigned char lcr; /* 3 */
-+ UART_REG_PAD(lcr)
-+ unsigned char mcr; /* 4 */
-+ UART_REG_PAD(mcr)
-+ unsigned char lsr; /* 5 */
-+ UART_REG_PAD(lsr)
-+ unsigned char msr; /* 6 */
-+ UART_REG_PAD(msr)
-+ unsigned char scr; /* 7 */
-+ };
-+
-+#define thr rbr
-+#define iir fcr
-+#define dll rbr
-+#define dlm ier
-+
-+#define LSR_DR 0x01 /* Data ready */
-+#define LSR_OE 0x02 /* Overrun */
-+#define LSR_PE 0x04 /* Parity error */
-+#define LSR_FE 0x08 /* Framing error */
-+#define LSR_BI 0x10 /* Break */
-+#define LSR_THRE 0x20 /* Xmit holding register empty */
-+#define LSR_TEMT 0x40 /* Xmitter empty */
-+#define LSR_ERR 0x80 /* Error */
-diff -Naru linux/arch/mips/zboot/include/pb1000_serial.h linux.spi/arch/mips/zboot/include/pb1000_serial.h
---- linux/arch/mips/zboot/include/pb1000_serial.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/include/pb1000_serial.h 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,20 @@
-+/*
-+ * arch/ppc/boot/include/sandpoint_serial.h
-+ *
-+ * Location of the COM ports on Motorola SPS Sandpoint machines
-+ *
-+ * Author: Mark A. Greer
-+ * mgreer@mvista.com
-+ *
-+ * Copyright 2001 MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version.
-+ */
-+
-+#define COM1 0xfe0003f8
-+#define COM2 0xfe0002f8
-+#define COM3 0x00000000 /* No COM3 */
-+#define COM4 0x00000000 /* No COM4 */
-diff -Naru linux/arch/mips/zboot/include/zlib.h linux.spi/arch/mips/zboot/include/zlib.h
---- linux/arch/mips/zboot/include/zlib.h 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/include/zlib.h 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,432 @@
-+/* $Id$ */
-+
-+/*
-+ * This file is derived from zlib.h and zconf.h from the zlib-0.95
-+ * distribution by Jean-loup Gailly and Mark Adler, with some additions
-+ * by Paul Mackerras to aid in implementing Deflate compression and
-+ * decompression for PPP packets.
-+ */
-+
-+/*
-+ * ==FILEVERSION 960122==
-+ *
-+ * This marker is used by the Linux installation script to determine
-+ * whether an up-to-date version of this file is already installed.
-+ */
-+
-+/* zlib.h -- interface of the 'zlib' general purpose compression library
-+ version 0.95, Aug 16th, 1995.
-+
-+ Copyright (C) 1995 Jean-loup Gailly and Mark Adler
-+
-+ This software is provided 'as-is', without any express or implied
-+ warranty. In no event will the authors be held liable for any damages
-+ arising from the use of this software.
-+
-+ Permission is granted to anyone to use this software for any purpose,
-+ including commercial applications, and to alter it and redistribute it
-+ freely, subject to the following restrictions:
-+
-+ 1. The origin of this software must not be misrepresented; you must not
-+ claim that you wrote the original software. If you use this software
-+ in a product, an acknowledgment in the product documentation would be
-+ appreciated but is not required.
-+ 2. Altered source versions must be plainly marked as such, and must not be
-+ misrepresented as being the original software.
-+ 3. This notice may not be removed or altered from any source distribution.
-+
-+ Jean-loup Gailly Mark Adler
-+ gzip@prep.ai.mit.edu madler@alumni.caltech.edu
-+ */
-+
-+#ifndef _ZLIB_H
-+#define _ZLIB_H
-+
-+/* #include "zconf.h" */ /* included directly here */
-+
-+/* zconf.h -- configuration of the zlib compression library
-+ * Copyright (C) 1995 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */
-+
-+/*
-+ The library does not install any signal handler. It is recommended to
-+ add at least a handler for SIGSEGV when decompressing; the library checks
-+ the consistency of the input data whenever possible but may go nuts
-+ for some forms of corrupted input.
-+ */
-+
-+/*
-+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
-+ * than 64k bytes at a time (needed on systems with 16-bit int).
-+ * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints
-+ * at addresses which are not a multiple of their size.
-+ * Under DOS, -DFAR=far or -DFAR=__far may be needed.
-+ */
-+
-+#ifndef STDC
-+# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus)
-+# define STDC
-+# endif
-+#endif
-+
-+#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */
-+# include <unix.h>
-+#endif
-+
-+/* Maximum value for memLevel in deflateInit2 */
-+#ifndef MAX_MEM_LEVEL
-+# ifdef MAXSEG_64K
-+# define MAX_MEM_LEVEL 8
-+# else
-+# define MAX_MEM_LEVEL 9
-+# endif
-+#endif
-+
-+#ifndef FAR
-+# define FAR
-+#endif
-+
-+/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
-+#ifndef MAX_WBITS
-+# define MAX_WBITS 15 /* 32K LZ77 window */
-+#endif
-+
-+/* The memory requirements for deflate are (in bytes):
-+ 1 << (windowBits+2) + 1 << (memLevel+9)
-+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
-+ plus a few kilobytes for small objects. For example, if you want to reduce
-+ the default memory requirements from 256K to 128K, compile with
-+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
-+ Of course this will generally degrade compression (there's no free lunch).
-+
-+ The memory requirements for inflate are (in bytes) 1 << windowBits
-+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
-+ for small objects.
-+*/
-+
-+ /* Type declarations */
-+
-+#ifndef OF /* function prototypes */
-+# ifdef STDC
-+# define OF(args) args
-+# else
-+# define OF(args) ()
-+# endif
-+#endif
-+
-+typedef unsigned char Byte; /* 8 bits */
-+typedef unsigned int uInt; /* 16 bits or more */
-+typedef unsigned long uLong; /* 32 bits or more */
-+
-+typedef Byte FAR Bytef;
-+typedef char FAR charf;
-+typedef int FAR intf;
-+typedef uInt FAR uIntf;
-+typedef uLong FAR uLongf;
-+
-+#ifdef STDC
-+ typedef void FAR *voidpf;
-+ typedef void *voidp;
-+#else
-+ typedef Byte FAR *voidpf;
-+ typedef Byte *voidp;
-+#endif
-+
-+/* end of original zconf.h */
-+
-+#define ZLIB_VERSION "0.95P"
-+
-+/*
-+ The 'zlib' compression library provides in-memory compression and
-+ decompression functions, including integrity checks of the uncompressed
-+ data. This version of the library supports only one compression method
-+ (deflation) but other algorithms may be added later and will have the same
-+ stream interface.
-+
-+ For compression the application must provide the output buffer and
-+ may optionally provide the input buffer for optimization. For decompression,
-+ the application must provide the input buffer and may optionally provide
-+ the output buffer for optimization.
-+
-+ Compression can be done in a single step if the buffers are large
-+ enough (for example if an input file is mmap'ed), or can be done by
-+ repeated calls of the compression function. In the latter case, the
-+ application must provide more input and/or consume the output
-+ (providing more output space) before each call.
-+*/
-+
-+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-+typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes));
-+
-+struct internal_state;
-+
-+typedef struct z_stream_s {
-+ Bytef *next_in; /* next input byte */
-+ uInt avail_in; /* number of bytes available at next_in */
-+ uLong total_in; /* total nb of input bytes read so far */
-+
-+ Bytef *next_out; /* next output byte should be put there */
-+ uInt avail_out; /* remaining free space at next_out */
-+ uLong total_out; /* total nb of bytes output so far */
-+
-+ char *msg; /* last error message, NULL if no error */
-+ struct internal_state FAR *state; /* not visible by applications */
-+
-+ alloc_func zalloc; /* used to allocate the internal state */
-+ free_func zfree; /* used to free the internal state */
-+ voidp opaque; /* private data object passed to zalloc and zfree */
-+
-+ Byte data_type; /* best guess about the data type: ascii or binary */
-+
-+} z_stream;
-+
-+/*
-+ The application must update next_in and avail_in when avail_in has
-+ dropped to zero. It must update next_out and avail_out when avail_out
-+ has dropped to zero. The application must initialize zalloc, zfree and
-+ opaque before calling the init function. All other fields are set by the
-+ compression library and must not be updated by the application.
-+
-+ The opaque value provided by the application will be passed as the first
-+ parameter for calls of zalloc and zfree. This can be useful for custom
-+ memory management. The compression library attaches no meaning to the
-+ opaque value.
-+
-+ zalloc must return Z_NULL if there is not enough memory for the object.
-+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
-+ exactly 65536 bytes, but will not be required to allocate more than this
-+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
-+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
-+ have their offset normalized to zero. The default allocation function
-+ provided by this library ensures this (see zutil.c). To reduce memory
-+ requirements and avoid any allocation of 64K objects, at the expense of
-+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-+
-+ The fields total_in and total_out can be used for statistics or
-+ progress reports. After compression, total_in holds the total size of
-+ the uncompressed data and may be saved for use in the decompressor
-+ (particularly if the decompressor wants to decompress everything in
-+ a single step).
-+*/
-+
-+ /* constants */
-+
-+#define Z_NO_FLUSH 0
-+#define Z_PARTIAL_FLUSH 1
-+#define Z_FULL_FLUSH 2
-+#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */
-+#define Z_FINISH 4
-+#define Z_PACKET_FLUSH 5
-+/* See deflate() below for the usage of these constants */
-+
-+#define Z_OK 0
-+#define Z_STREAM_END 1
-+#define Z_ERRNO (-1)
-+#define Z_STREAM_ERROR (-2)
-+#define Z_DATA_ERROR (-3)
-+#define Z_MEM_ERROR (-4)
-+#define Z_BUF_ERROR (-5)
-+/* error codes for the compression/decompression functions */
-+
-+#define Z_BEST_SPEED 1
-+#define Z_BEST_COMPRESSION 9
-+#define Z_DEFAULT_COMPRESSION (-1)
-+/* compression levels */
-+
-+#define Z_FILTERED 1
-+#define Z_HUFFMAN_ONLY 2
-+#define Z_DEFAULT_STRATEGY 0
-+
-+#define Z_BINARY 0
-+#define Z_ASCII 1
-+#define Z_UNKNOWN 2
-+/* Used to set the data_type field */
-+
-+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-+
-+extern char *zlib_version;
-+/* The application can compare zlib_version and ZLIB_VERSION for consistency.
-+ If the first character differs, the library code actually used is
-+ not compatible with the zlib.h header file used by the application.
-+ */
-+
-+ /* basic functions */
-+
-+extern int inflateInit OF((z_stream *strm));
-+/*
-+ Initializes the internal stream state for decompression. The fields
-+ zalloc and zfree must be initialized before by the caller. If zalloc and
-+ zfree are set to Z_NULL, inflateInit updates them to use default allocation
-+ functions.
-+
-+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory. msg is set to null if there is no error message.
-+ inflateInit does not perform any decompression: this will be done by
-+ inflate().
-+*/
-+
-+
-+extern int inflate OF((z_stream *strm, int flush));
-+/*
-+ Performs one or both of the following actions:
-+
-+ - Decompress more input starting at next_in and update next_in and avail_in
-+ accordingly. If not all input can be processed (because there is not
-+ enough room in the output buffer), next_in is updated and processing
-+ will resume at this point for the next call of inflate().
-+
-+ - Provide more output starting at next_out and update next_out and avail_out
-+ accordingly. inflate() always provides as much output as possible
-+ (until there is no more input data or no more space in the output buffer).
-+
-+ Before the call of inflate(), the application should ensure that at least
-+ one of the actions is possible, by providing more input and/or consuming
-+ more output, and updating the next_* and avail_* values accordingly.
-+ The application can consume the uncompressed output when it wants, for
-+ example when the output buffer is full (avail_out == 0), or after each
-+ call of inflate().
-+
-+ If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH,
-+ inflate flushes as much output as possible to the output buffer. The
-+ flushing behavior of inflate is not specified for values of the flush
-+ parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the
-+ current implementation actually flushes as much output as possible
-+ anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data
-+ has been consumed, it is expecting to see the length field of a stored
-+ block; if not, it returns Z_DATA_ERROR.
-+
-+ inflate() should normally be called until it returns Z_STREAM_END or an
-+ error. However if all decompression is to be performed in a single step
-+ (a single call of inflate), the parameter flush should be set to
-+ Z_FINISH. In this case all pending input is processed and all pending
-+ output is flushed; avail_out must be large enough to hold all the
-+ uncompressed data. (The size of the uncompressed data may have been saved
-+ by the compressor for this purpose.) The next operation on this stream must
-+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
-+ is never required, but can be used to inform inflate that a faster routine
-+ may be used for the single inflate() call.
-+
-+ inflate() returns Z_OK if some progress has been made (more input
-+ processed or more output produced), Z_STREAM_END if the end of the
-+ compressed data has been reached and all uncompressed output has been
-+ produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if
-+ the stream structure was inconsistent (for example if next_in or next_out
-+ was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no
-+ progress is possible or if there was not enough room in the output buffer
-+ when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then
-+ call inflateSync to look for a good compression block. */
-+
-+
-+extern int inflateEnd OF((z_stream *strm));
-+/*
-+ All dynamically allocated data structures for this stream are freed.
-+ This function discards any unprocessed input and does not flush any
-+ pending output.
-+
-+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
-+ was inconsistent. In the error case, msg may be set but then points to a
-+ static string (which must not be deallocated).
-+*/
-+
-+ /* advanced functions */
-+
-+extern int inflateInit2 OF((z_stream *strm,
-+ int windowBits));
-+/*
-+ This is another version of inflateInit with more compression options. The
-+ fields next_out, zalloc and zfree must be initialized before by the caller.
-+
-+ The windowBits parameter is the base two logarithm of the maximum window
-+ size (the size of the history buffer). It should be in the range 8..15 for
-+ this version of the library (the value 16 will be allowed soon). The
-+ default value is 15 if inflateInit is used instead. If a compressed stream
-+ with a larger window size is given as input, inflate() will return with
-+ the error code Z_DATA_ERROR instead of trying to allocate a larger window.
-+
-+ If next_out is not null, the library will use this buffer for the history
-+ buffer; the buffer must either be large enough to hold the entire output
-+ data, or have at least 1<<windowBits bytes. If next_out is null, the
-+ library will allocate its own buffer (and leave next_out null). next_in
-+ need not be provided here but must be provided by the application for the
-+ next call of inflate().
-+
-+ If the history buffer is provided by the application, next_out must
-+ never be changed by the application since the decompressor maintains
-+ history information inside this buffer from call to call; the application
-+ can only reset next_out to the beginning of the history buffer when
-+ avail_out is zero and all output has been consumed.
-+
-+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
-+ not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
-+ windowBits < 8). msg is set to null if there is no error message.
-+ inflateInit2 does not perform any decompression: this will be done by
-+ inflate().
-+*/
-+
-+extern int inflateSync OF((z_stream *strm));
-+/*
-+ Skips invalid compressed data until the special marker (see deflate()
-+ above) can be found, or until all available input is skipped. No output
-+ is provided.
-+
-+ inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR
-+ if no more input was provided, Z_DATA_ERROR if no marker has been found,
-+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
-+ case, the application may save the current current value of total_in which
-+ indicates where valid compressed data was found. In the error case, the
-+ application may repeatedly call inflateSync, providing more input each time,
-+ until success or end of the input data.
-+*/
-+
-+extern int inflateReset OF((z_stream *strm));
-+/*
-+ This function is equivalent to inflateEnd followed by inflateInit,
-+ but does not free and reallocate all the internal decompression state.
-+ The stream will keep attributes that may have been set by inflateInit2.
-+
-+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-+ stream state was inconsistent (such as zalloc or state being NULL).
-+*/
-+
-+extern int inflateIncomp OF((z_stream *strm));
-+/*
-+ This function adds the data at next_in (avail_in bytes) to the output
-+ history without performing any output. There must be no pending output,
-+ and the decompressor must be expecting to see the start of a block.
-+ Calling this function is equivalent to decompressing a stored block
-+ containing the data at next_in (except that the data is not output).
-+*/
-+
-+ /* checksum functions */
-+
-+/*
-+ This function is not related to compression but is exported
-+ anyway because it might be useful in applications using the
-+ compression library.
-+*/
-+
-+extern uLong adler32 OF((uLong adler, Bytef *buf, uInt len));
-+
-+/*
-+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
-+ return the updated checksum. If buf is NULL, this function returns
-+ the required initial value for the checksum.
-+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
-+ much faster. Usage example:
-+
-+ uLong adler = adler32(0L, Z_NULL, 0);
-+
-+ while (read_buffer(buffer, length) != EOF) {
-+ adler = adler32(adler, buffer, length);
-+ }
-+ if (adler != original_adler) error();
-+*/
-+
-+#ifndef _Z_UTIL_H
-+ struct internal_state {int dummy;}; /* hack for buggy compilers */
-+#endif
-+
-+#endif /* _ZLIB_H */
-diff -Naru linux/arch/mips/zboot/ld.script linux.spi/arch/mips/zboot/ld.script
---- linux/arch/mips/zboot/ld.script 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/ld.script 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,151 @@
-+OUTPUT_ARCH(mips)
-+ENTRY(start)
-+SECTIONS
-+{
-+ /* Read-only sections, merged into text segment: */
-+ /* . = 0x81000000; */
-+ .init : { *(.init) } =0
-+ .text :
-+ {
-+ _ftext = . ;
-+ *(.text)
-+ *(.rodata)
-+ *(.rodata1)
-+ /* .gnu.warning sections are handled specially by elf32.em. */
-+ *(.gnu.warning)
-+ } =0
-+ .kstrtab : { *(.kstrtab) }
-+
-+ . = ALIGN(16); /* Exception table */
-+ __start___ex_table = .;
-+ __ex_table : { *(__ex_table) }
-+ __stop___ex_table = .;
-+
-+ __start___dbe_table = .; /* Exception table for data bus errors */
-+ __dbe_table : { *(__dbe_table) }
-+ __stop___dbe_table = .;
-+
-+ __start___ksymtab = .; /* Kernel symbol table */
-+ __ksymtab : { *(__ksymtab) }
-+ __stop___ksymtab = .;
-+
-+ _etext = .;
-+
-+ . = ALIGN(8192);
-+ .data.init_task : { *(.data.init_task) }
-+
-+ /* Startup code */
-+ . = ALIGN(4096);
-+ __init_begin = .;
-+ .text.init : { *(.text.init) }
-+ .data.init : { *(.data.init) }
-+ . = ALIGN(16);
-+ __setup_start = .;
-+ .setup.init : { *(.setup.init) }
-+ __setup_end = .;
-+ __initcall_start = .;
-+ .initcall.init : { *(.initcall.init) }
-+ __initcall_end = .;
-+ . = ALIGN(4096); /* Align double page for init_task_union */
-+ __init_end = .;
-+
-+ . = ALIGN(4096);
-+ .data.page_aligned : { *(.data.idt) }
-+
-+ . = ALIGN(32);
-+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
-+
-+ .fini : { *(.fini) } =0
-+ .reginfo : { *(.reginfo) }
-+ /* Adjust the address for the data segment. We want to adjust up to
-+ the same address within the page on the next page up. It would
-+ be more correct to do this:
-+ . = .;
-+ The current expression does not correctly handle the case of a
-+ text segment ending precisely at the end of a page; it causes the
-+ data segment to skip a page. The above expression does not have
-+ this problem, but it will currently (2/95) cause BFD to allocate
-+ a single segment, combining both text and data, for this case.
-+ This will prevent the text segment from being shared among
-+ multiple executions of the program; I think that is more
-+ important than losing a page of the virtual address space (note
-+ that no actual memory is lost; the page which is skipped can not
-+ be referenced). */
-+ . = .;
-+ .data :
-+ {
-+ _fdata = . ;
-+ *(.data)
-+
-+ /* Put the compressed image here, so bss is on the end. */
-+ __image_begin = .;
-+ *(.image)
-+ __image_end = .;
-+ /* Align the initial ramdisk image (INITRD) on page boundaries. */
-+ . = ALIGN(4096);
-+ __ramdisk_begin = .;
-+ *(.initrd)
-+ __ramdisk_end = .;
-+ . = ALIGN(4096);
-+
-+ CONSTRUCTORS
-+ }
-+ .data1 : { *(.data1) }
-+ _gp = . + 0x8000;
-+ .lit8 : { *(.lit8) }
-+ .lit4 : { *(.lit4) }
-+ .ctors : { *(.ctors) }
-+ .dtors : { *(.dtors) }
-+ .got : { *(.got.plt) *(.got) }
-+ .dynamic : { *(.dynamic) }
-+ /* We want the small data sections together, so single-instruction offsets
-+ can access them all, and initialized data all before uninitialized, so
-+ we can shorten the on-disk segment size. */
-+ .sdata : { *(.sdata) }
-+ . = ALIGN(4);
-+ _edata = .;
-+ PROVIDE (edata = .);
-+
-+ __bss_start = .;
-+ _fbss = .;
-+ .sbss : { *(.sbss) *(.scommon) }
-+ .bss :
-+ {
-+ *(.dynbss)
-+ *(.bss)
-+ *(COMMON)
-+ . = ALIGN(4);
-+ _end = . ;
-+ PROVIDE (end = .);
-+ }
-+
-+ /* Sections to be discarded */
-+ /DISCARD/ :
-+ {
-+ *(.text.exit)
-+ *(.data.exit)
-+ *(.exitcall.exit)
-+ }
-+
-+ /* This is the MIPS specific mdebug section. */
-+ .mdebug : { *(.mdebug) }
-+ /* These are needed for ELF backends which have not yet been
-+ converted to the new style linker. */
-+ .stab 0 : { *(.stab) }
-+ .stabstr 0 : { *(.stabstr) }
-+ /* DWARF debug sections.
-+ Symbols in the .debug DWARF section are relative to the beginning of the
-+ section so we begin .debug at 0. It's not clear yet what needs to happen
-+ for the others. */
-+ .debug 0 : { *(.debug) }
-+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
-+ .debug_aranges 0 : { *(.debug_aranges) }
-+ .debug_pubnames 0 : { *(.debug_pubnames) }
-+ .debug_sfnames 0 : { *(.debug_sfnames) }
-+ .line 0 : { *(.line) }
-+ /* These must appear regardless of . */
-+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
-+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
-+ .comment : { *(.comment) }
-+ .note : { *(.note) }
-+}
-diff -Naru linux/arch/mips/zboot/lib/Makefile linux.spi/arch/mips/zboot/lib/Makefile
---- linux/arch/mips/zboot/lib/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/lib/Makefile 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,9 @@
-+#
-+# Makefile for some libs needed by zImage.
-+#
-+
-+L_TARGET := zlib.a
-+
-+obj-y := zlib.o
-+
-+include $(TOPDIR)/Rules.make
-diff -Naru linux/arch/mips/zboot/lib/zlib.c linux.spi/arch/mips/zboot/lib/zlib.c
---- linux/arch/mips/zboot/lib/zlib.c 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/lib/zlib.c 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,2148 @@
-+/*
-+ * This file is derived from various .h and .c files from the zlib-0.95
-+ * distribution by Jean-loup Gailly and Mark Adler, with some additions
-+ * by Paul Mackerras to aid in implementing Deflate compression and
-+ * decompression for PPP packets. See zlib.h for conditions of
-+ * distribution and use.
-+ *
-+ * Changes that have been made include:
-+ * - changed functions not used outside this file to "local"
-+ * - added minCompression parameter to deflateInit2
-+ * - added Z_PACKET_FLUSH (see zlib.h for details)
-+ * - added inflateIncomp
-+ *
-+ * $Id$
-+ */
-+
-+/*+++++*/
-+/* zutil.h -- internal interface and configuration of the compression library
-+ * Copyright (C) 1995 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */
-+
-+#define _Z_UTIL_H
-+
-+#include "zlib.h"
-+
-+#ifndef local
-+# define local static
-+#endif
-+/* compile with -Dlocal if your debugger can't find static symbols */
-+
-+#define FAR
-+
-+typedef unsigned char uch;
-+typedef uch FAR uchf;
-+typedef unsigned short ush;
-+typedef ush FAR ushf;
-+typedef unsigned long ulg;
-+
-+extern char *z_errmsg[]; /* indexed by 1-zlib_error */
-+
-+#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err)
-+/* To be used only when the state is known to be valid */
-+
-+#ifndef NULL
-+#define NULL ((void *) 0)
-+#endif
-+
-+ /* common constants */
-+
-+#define DEFLATED 8
-+
-+#ifndef DEF_WBITS
-+# define DEF_WBITS MAX_WBITS
-+#endif
-+/* default windowBits for decompression. MAX_WBITS is for compression only */
-+
-+#if MAX_MEM_LEVEL >= 8
-+# define DEF_MEM_LEVEL 8
-+#else
-+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-+#endif
-+/* default memLevel */
-+
-+#define STORED_BLOCK 0
-+#define STATIC_TREES 1
-+#define DYN_TREES 2
-+/* The three kinds of block type */
-+
-+#define MIN_MATCH 3
-+#define MAX_MATCH 258
-+/* The minimum and maximum match lengths */
-+
-+ /* functions */
-+
-+#include <linux/string.h>
-+#define zmemcpy memcpy
-+#define zmemzero(dest, len) memset(dest, 0, len)
-+
-+/* Diagnostic functions */
-+#ifdef DEBUG_ZLIB
-+# include <stdio.h>
-+# ifndef verbose
-+# define verbose 0
-+# endif
-+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-+# define Trace(x) fprintf x
-+# define Tracev(x) {if (verbose) fprintf x ;}
-+# define Tracevv(x) {if (verbose>1) fprintf x ;}
-+# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-+# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
-+#else
-+# define Assert(cond,msg)
-+# define Trace(x)
-+# define Tracev(x)
-+# define Tracevv(x)
-+# define Tracec(c,x)
-+# define Tracecv(c,x)
-+#endif
-+
-+
-+typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len));
-+
-+/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */
-+/* void zcfree OF((voidpf opaque, voidpf ptr)); */
-+
-+#define ZALLOC(strm, items, size) \
-+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
-+#define ZFREE(strm, addr, size) \
-+ (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size))
-+#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);}
-+
-+/* deflate.h -- internal compression state
-+ * Copyright (C) 1995 Jean-loup Gailly
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+/*+++++*/
-+/* infblock.h -- header to use infblock.c
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+struct inflate_blocks_state;
-+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
-+
-+local inflate_blocks_statef * inflate_blocks_new OF((
-+ z_stream *z,
-+ check_func c, /* check function */
-+ uInt w)); /* window size */
-+
-+local int inflate_blocks OF((
-+ inflate_blocks_statef *,
-+ z_stream *,
-+ int)); /* initial return code */
-+
-+local void inflate_blocks_reset OF((
-+ inflate_blocks_statef *,
-+ z_stream *,
-+ uLongf *)); /* check value on output */
-+
-+local int inflate_blocks_free OF((
-+ inflate_blocks_statef *,
-+ z_stream *,
-+ uLongf *)); /* check value on output */
-+
-+local int inflate_addhistory OF((
-+ inflate_blocks_statef *,
-+ z_stream *));
-+
-+local int inflate_packet_flush OF((
-+ inflate_blocks_statef *));
-+
-+/*+++++*/
-+/* inftrees.h -- header to use inftrees.c
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+/* Huffman code lookup table entry--this entry is four bytes for machines
-+ that have 16-bit pointers (e.g. PC's in the small or medium model). */
-+
-+typedef struct inflate_huft_s FAR inflate_huft;
-+
-+struct inflate_huft_s {
-+ union {
-+ struct {
-+ Byte Exop; /* number of extra bits or operation */
-+ Byte Bits; /* number of bits in this code or subcode */
-+ } what;
-+ uInt Nalloc; /* number of these allocated here */
-+ Bytef *pad; /* pad structure to a power of 2 (4 bytes for */
-+ } word; /* 16-bit, 8 bytes for 32-bit machines) */
-+ union {
-+ uInt Base; /* literal, length base, or distance base */
-+ inflate_huft *Next; /* pointer to next level of table */
-+ } more;
-+};
-+
-+#ifdef DEBUG_ZLIB
-+ local uInt inflate_hufts;
-+#endif
-+
-+local int inflate_trees_bits OF((
-+ uIntf *, /* 19 code lengths */
-+ uIntf *, /* bits tree desired/actual depth */
-+ inflate_huft * FAR *, /* bits tree result */
-+ z_stream *)); /* for zalloc, zfree functions */
-+
-+local int inflate_trees_dynamic OF((
-+ uInt, /* number of literal/length codes */
-+ uInt, /* number of distance codes */
-+ uIntf *, /* that many (total) code lengths */
-+ uIntf *, /* literal desired/actual bit depth */
-+ uIntf *, /* distance desired/actual bit depth */
-+ inflate_huft * FAR *, /* literal/length tree result */
-+ inflate_huft * FAR *, /* distance tree result */
-+ z_stream *)); /* for zalloc, zfree functions */
-+
-+local int inflate_trees_fixed OF((
-+ uIntf *, /* literal desired/actual bit depth */
-+ uIntf *, /* distance desired/actual bit depth */
-+ inflate_huft * FAR *, /* literal/length tree result */
-+ inflate_huft * FAR *)); /* distance tree result */
-+
-+local int inflate_trees_free OF((
-+ inflate_huft *, /* tables to free */
-+ z_stream *)); /* for zfree function */
-+
-+
-+/*+++++*/
-+/* infcodes.h -- header to use infcodes.c
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+struct inflate_codes_state;
-+typedef struct inflate_codes_state FAR inflate_codes_statef;
-+
-+local inflate_codes_statef *inflate_codes_new OF((
-+ uInt, uInt,
-+ inflate_huft *, inflate_huft *,
-+ z_stream *));
-+
-+local int inflate_codes OF((
-+ inflate_blocks_statef *,
-+ z_stream *,
-+ int));
-+
-+local void inflate_codes_free OF((
-+ inflate_codes_statef *,
-+ z_stream *));
-+
-+
-+/*+++++*/
-+/* inflate.c -- zlib interface to inflate modules
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* inflate private state */
-+struct internal_state {
-+
-+ /* mode */
-+ enum {
-+ METHOD, /* waiting for method byte */
-+ FLAG, /* waiting for flag byte */
-+ BLOCKS, /* decompressing blocks */
-+ CHECK4, /* four check bytes to go */
-+ CHECK3, /* three check bytes to go */
-+ CHECK2, /* two check bytes to go */
-+ CHECK1, /* one check byte to go */
-+ DONE, /* finished check, done */
-+ BAD} /* got an error--stay here */
-+ mode; /* current inflate mode */
-+
-+ /* mode dependent information */
-+ union {
-+ uInt method; /* if FLAGS, method byte */
-+ struct {
-+ uLong was; /* computed check value */
-+ uLong need; /* stream check value */
-+ } check; /* if CHECK, check values to compare */
-+ uInt marker; /* if BAD, inflateSync's marker bytes count */
-+ } sub; /* submode */
-+
-+ /* mode independent information */
-+ int nowrap; /* flag for no wrapper */
-+ uInt wbits; /* log2(window size) (8..15, defaults to 15) */
-+ inflate_blocks_statef
-+ *blocks; /* current inflate_blocks state */
-+
-+};
-+
-+
-+int inflateReset(z)
-+z_stream *z;
-+{
-+ uLong c;
-+
-+ if (z == Z_NULL || z->state == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ z->total_in = z->total_out = 0;
-+ z->msg = Z_NULL;
-+ z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
-+ inflate_blocks_reset(z->state->blocks, z, &c);
-+ Trace((stderr, "inflate: reset\n"));
-+ return Z_OK;
-+}
-+
-+
-+int inflateEnd(z)
-+z_stream *z;
-+{
-+ uLong c;
-+
-+ if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ if (z->state->blocks != Z_NULL)
-+ inflate_blocks_free(z->state->blocks, z, &c);
-+ ZFREE(z, z->state, sizeof(struct internal_state));
-+ z->state = Z_NULL;
-+ Trace((stderr, "inflate: end\n"));
-+ return Z_OK;
-+}
-+
-+
-+int inflateInit2(z, w)
-+z_stream *z;
-+int w;
-+{
-+ /* initialize state */
-+ if (z == Z_NULL)
-+ return Z_STREAM_ERROR;
-+/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */
-+/* if (z->zfree == Z_NULL) z->zfree = zcfree; */
-+ if ((z->state = (struct internal_state FAR *)
-+ ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
-+ return Z_MEM_ERROR;
-+ z->state->blocks = Z_NULL;
-+
-+ /* handle undocumented nowrap option (no zlib header or check) */
-+ z->state->nowrap = 0;
-+ if (w < 0)
-+ {
-+ w = - w;
-+ z->state->nowrap = 1;
-+ }
-+
-+ /* set window size */
-+ if (w < 8 || w > 15)
-+ {
-+ inflateEnd(z);
-+ return Z_STREAM_ERROR;
-+ }
-+ z->state->wbits = (uInt)w;
-+
-+ /* create inflate_blocks state */
-+ if ((z->state->blocks =
-+ inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w))
-+ == Z_NULL)
-+ {
-+ inflateEnd(z);
-+ return Z_MEM_ERROR;
-+ }
-+ Trace((stderr, "inflate: allocated\n"));
-+
-+ /* reset state */
-+ inflateReset(z);
-+ return Z_OK;
-+}
-+
-+
-+int inflateInit(z)
-+z_stream *z;
-+{
-+ return inflateInit2(z, DEF_WBITS);
-+}
-+
-+
-+#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;}
-+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
-+
-+int inflate(z, f)
-+z_stream *z;
-+int f;
-+{
-+ int r;
-+ uInt b;
-+
-+ if (z == Z_NULL || z->next_in == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ r = Z_BUF_ERROR;
-+ while (1) switch (z->state->mode)
-+ {
-+ case METHOD:
-+ NEEDBYTE
-+ if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = "unknown compression method";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = "invalid window size";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ z->state->mode = FLAG;
-+ case FLAG:
-+ NEEDBYTE
-+ if ((b = NEXTBYTE) & 0x20)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = "invalid reserved bit";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ if (((z->state->sub.method << 8) + b) % 31)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = "incorrect header check";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ Trace((stderr, "inflate: zlib header ok\n"));
-+ z->state->mode = BLOCKS;
-+ case BLOCKS:
-+ r = inflate_blocks(z->state->blocks, z, r);
-+ if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0)
-+ r = inflate_packet_flush(z->state->blocks);
-+ if (r == Z_DATA_ERROR)
-+ {
-+ z->state->mode = BAD;
-+ z->state->sub.marker = 0; /* can try inflateSync */
-+ break;
-+ }
-+ if (r != Z_STREAM_END)
-+ return r;
-+ r = Z_OK;
-+ inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
-+ if (z->state->nowrap)
-+ {
-+ z->state->mode = DONE;
-+ break;
-+ }
-+ z->state->mode = CHECK4;
-+ case CHECK4:
-+ NEEDBYTE
-+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
-+ z->state->mode = CHECK3;
-+ case CHECK3:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
-+ z->state->mode = CHECK2;
-+ case CHECK2:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
-+ z->state->mode = CHECK1;
-+ case CHECK1:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE;
-+
-+ if (z->state->sub.check.was != z->state->sub.check.need)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = "incorrect data check";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ Trace((stderr, "inflate: zlib check ok\n"));
-+ z->state->mode = DONE;
-+ case DONE:
-+ return Z_STREAM_END;
-+ case BAD:
-+ return Z_DATA_ERROR;
-+ default:
-+ return Z_STREAM_ERROR;
-+ }
-+
-+ empty:
-+ if (f != Z_PACKET_FLUSH)
-+ return r;
-+ z->state->mode = BAD;
-+ z->state->sub.marker = 0; /* can try inflateSync */
-+ return Z_DATA_ERROR;
-+}
-+
-+/*
-+ * This subroutine adds the data at next_in/avail_in to the output history
-+ * without performing any output. The output buffer must be "caught up";
-+ * i.e. no pending output (hence s->read equals s->write), and the state must
-+ * be BLOCKS (i.e. we should be willing to see the start of a series of
-+ * BLOCKS). On exit, the output will also be caught up, and the checksum
-+ * will have been updated if need be.
-+ */
-+
-+int inflateIncomp(z)
-+z_stream *z;
-+{
-+ if (z->state->mode != BLOCKS)
-+ return Z_DATA_ERROR;
-+ return inflate_addhistory(z->state->blocks, z);
-+}
-+
-+
-+int inflateSync(z)
-+z_stream *z;
-+{
-+ uInt n; /* number of bytes to look at */
-+ Bytef *p; /* pointer to bytes */
-+ uInt m; /* number of marker bytes found in a row */
-+ uLong r, w; /* temporaries to save total_in and total_out */
-+
-+ /* set up */
-+ if (z == Z_NULL || z->state == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ if (z->state->mode != BAD)
-+ {
-+ z->state->mode = BAD;
-+ z->state->sub.marker = 0;
-+ }
-+ if ((n = z->avail_in) == 0)
-+ return Z_BUF_ERROR;
-+ p = z->next_in;
-+ m = z->state->sub.marker;
-+
-+ /* search */
-+ while (n && m < 4)
-+ {
-+ if (*p == (Byte)(m < 2 ? 0 : 0xff))
-+ m++;
-+ else if (*p)
-+ m = 0;
-+ else
-+ m = 4 - m;
-+ p++, n--;
-+ }
-+
-+ /* restore */
-+ z->total_in += p - z->next_in;
-+ z->next_in = p;
-+ z->avail_in = n;
-+ z->state->sub.marker = m;
-+
-+ /* return no joy or set up to restart on a new block */
-+ if (m != 4)
-+ return Z_DATA_ERROR;
-+ r = z->total_in; w = z->total_out;
-+ inflateReset(z);
-+ z->total_in = r; z->total_out = w;
-+ z->state->mode = BLOCKS;
-+ return Z_OK;
-+}
-+
-+#undef NEEDBYTE
-+#undef NEXTBYTE
-+
-+/*+++++*/
-+/* infutil.h -- types and macros common to blocks and codes
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+/* inflate blocks semi-private state */
-+struct inflate_blocks_state {
-+
-+ /* mode */
-+ enum {
-+ TYPE, /* get type bits (3, including end bit) */
-+ LENS, /* get lengths for stored */
-+ STORED, /* processing stored block */
-+ TABLE, /* get table lengths */
-+ BTREE, /* get bit lengths tree for a dynamic block */
-+ DTREE, /* get length, distance trees for a dynamic block */
-+ CODES, /* processing fixed or dynamic block */
-+ DRY, /* output remaining window bytes */
-+ DONEB, /* finished last block, done */
-+ BADB} /* got a data error--stuck here */
-+ mode; /* current inflate_block mode */
-+
-+ /* mode dependent information */
-+ union {
-+ uInt left; /* if STORED, bytes left to copy */
-+ struct {
-+ uInt table; /* table lengths (14 bits) */
-+ uInt index; /* index into blens (or border) */
-+ uIntf *blens; /* bit lengths of codes */
-+ uInt bb; /* bit length tree depth */
-+ inflate_huft *tb; /* bit length decoding tree */
-+ int nblens; /* # elements allocated at blens */
-+ } trees; /* if DTREE, decoding info for trees */
-+ struct {
-+ inflate_huft *tl, *td; /* trees to free */
-+ inflate_codes_statef
-+ *codes;
-+ } decode; /* if CODES, current state */
-+ } sub; /* submode */
-+ uInt last; /* true if this block is the last block */
-+
-+ /* mode independent information */
-+ uInt bitk; /* bits in bit buffer */
-+ uLong bitb; /* bit buffer */
-+ Bytef *window; /* sliding window */
-+ Bytef *end; /* one byte after sliding window */
-+ Bytef *read; /* window read pointer */
-+ Bytef *write; /* window write pointer */
-+ check_func checkfn; /* check function */
-+ uLong check; /* check on output */
-+
-+};
-+
-+
-+/* defines for inflate input/output */
-+/* update pointers and return */
-+#define UPDBITS {s->bitb=b;s->bitk=k;}
-+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
-+#define UPDOUT {s->write=q;}
-+#define UPDATE {UPDBITS UPDIN UPDOUT}
-+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
-+/* get bytes and bits */
-+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
-+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
-+#define NEXTBYTE (n--,*p++)
-+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-+#define DUMPBITS(j) {b>>=(j);k-=(j);}
-+/* output bytes */
-+#define WAVAIL (q<s->read?s->read-q-1:s->end-q)
-+#define LOADOUT {q=s->write;m=WAVAIL;}
-+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}}
-+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
-+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
-+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
-+/* load local pointers */
-+#define LOAD {LOADIN LOADOUT}
-+
-+/*
-+ * The IBM 150 firmware munges the data right after _etext[]. This
-+ * protects it. -- Cort
-+ */
-+local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0};
-+/* And'ing with mask[n] masks the lower n bits */
-+local uInt inflate_mask[] = {
-+ 0x0000,
-+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
-+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
-+};
-+
-+/* copy as much as possible from the sliding window to the output area */
-+local int inflate_flush OF((
-+ inflate_blocks_statef *,
-+ z_stream *,
-+ int));
-+
-+/*+++++*/
-+/* inffast.h -- header to use inffast.c
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+local int inflate_fast OF((
-+ uInt,
-+ uInt,
-+ inflate_huft *,
-+ inflate_huft *,
-+ inflate_blocks_statef *,
-+ z_stream *));
-+
-+
-+/*+++++*/
-+/* infblock.c -- interpret and process block types to last block
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* Table for deflate from PKZIP's appnote.txt. */
-+local uInt border[] = { /* Order of the bit length code lengths */
-+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-+
-+/*
-+ Notes beyond the 1.93a appnote.txt:
-+
-+ 1. Distance pointers never point before the beginning of the output
-+ stream.
-+ 2. Distance pointers can point back across blocks, up to 32k away.
-+ 3. There is an implied maximum of 7 bits for the bit length table and
-+ 15 bits for the actual data.
-+ 4. If only one code exists, then it is encoded using one bit. (Zero
-+ would be more efficient, but perhaps a little confusing.) If two
-+ codes exist, they are coded using one bit each (0 and 1).
-+ 5. There is no way of sending zero distance codes--a dummy must be
-+ sent if there are none. (History: a pre 2.0 version of PKZIP would
-+ store blocks with no distance codes, but this was discovered to be
-+ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
-+ zero distance codes, which is sent as one code of zero bits in
-+ length.
-+ 6. There are up to 286 literal/length codes. Code 256 represents the
-+ end-of-block. Note however that the static length tree defines
-+ 288 codes just to fill out the Huffman codes. Codes 286 and 287
-+ cannot be used though, since there is no length base or extra bits
-+ defined for them. Similarily, there are up to 30 distance codes.
-+ However, static trees define 32 codes (all 5 bits) to fill out the
-+ Huffman codes, but the last two had better not show up in the data.
-+ 7. Unzip can check dynamic Huffman blocks for complete code sets.
-+ The exception is that a single code would not be complete (see #4).
-+ 8. The five bits following the block type is really the number of
-+ literal codes sent minus 257.
-+ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
-+ (1+6+6). Therefore, to output three times the length, you output
-+ three codes (1+1+1), whereas to output four times the same length,
-+ you only need two codes (1+3). Hmm.
-+ 10. In the tree reconstruction algorithm, Code = Code + Increment
-+ only if BitLength(i) is not zero. (Pretty obvious.)
-+ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
-+ 12. Note: length code 284 can represent 227-258, but length code 285
-+ really is 258. The last length deserves its own, short code
-+ since it gets used a lot in very redundant files. The length
-+ 258 is special since 258 - 3 (the min match length) is 255.
-+ 13. The literal/length and distance code bit lengths are read as a
-+ single stream of lengths. It is possible (and advantageous) for
-+ a repeat code (16, 17, or 18) to go across the boundary between
-+ the two sets of lengths.
-+ */
-+
-+
-+local void inflate_blocks_reset(s, z, c)
-+inflate_blocks_statef *s;
-+z_stream *z;
-+uLongf *c;
-+{
-+ if (s->checkfn != Z_NULL)
-+ *c = s->check;
-+ if (s->mode == BTREE || s->mode == DTREE)
-+ ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
-+ if (s->mode == CODES)
-+ {
-+ inflate_codes_free(s->sub.decode.codes, z);
-+ inflate_trees_free(s->sub.decode.td, z);
-+ inflate_trees_free(s->sub.decode.tl, z);
-+ }
-+ s->mode = TYPE;
-+ s->bitk = 0;
-+ s->bitb = 0;
-+ s->read = s->write = s->window;
-+ if (s->checkfn != Z_NULL)
-+ s->check = (*s->checkfn)(0L, Z_NULL, 0);
-+ Trace((stderr, "inflate: blocks reset\n"));
-+}
-+
-+
-+local inflate_blocks_statef *inflate_blocks_new(z, c, w)
-+z_stream *z;
-+check_func c;
-+uInt w;
-+{
-+ inflate_blocks_statef *s;
-+
-+ if ((s = (inflate_blocks_statef *)ZALLOC
-+ (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
-+ return s;
-+ if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
-+ {
-+ ZFREE(z, s, sizeof(struct inflate_blocks_state));
-+ return Z_NULL;
-+ }
-+ s->end = s->window + w;
-+ s->checkfn = c;
-+ s->mode = TYPE;
-+ Trace((stderr, "inflate: blocks allocated\n"));
-+ inflate_blocks_reset(s, z, &s->check);
-+ return s;
-+}
-+
-+
-+local int inflate_blocks(s, z, r)
-+inflate_blocks_statef *s;
-+z_stream *z;
-+int r;
-+{
-+ uInt t; /* temporary storage */
-+ uLong b; /* bit buffer */
-+ uInt k; /* bits in bit buffer */
-+ Bytef *p; /* input data pointer */
-+ uInt n; /* bytes available there */
-+ Bytef *q; /* output window write pointer */
-+ uInt m; /* bytes to end of window or read pointer */
-+
-+ /* copy input/output information to locals (UPDATE macro restores) */
-+ LOAD
-+
-+ /* process input based on current state */
-+ while (1) switch (s->mode)
-+ {
-+ case TYPE:
-+ NEEDBITS(3)
-+ t = (uInt)b & 7;
-+ s->last = t & 1;
-+ switch (t >> 1)
-+ {
-+ case 0: /* stored */
-+ Trace((stderr, "inflate: stored block%s\n",
-+ s->last ? " (last)" : ""));
-+ DUMPBITS(3)
-+ t = k & 7; /* go to byte boundary */
-+ DUMPBITS(t)
-+ s->mode = LENS; /* get length of stored block */
-+ break;
-+ case 1: /* fixed */
-+ Trace((stderr, "inflate: fixed codes block%s\n",
-+ s->last ? " (last)" : ""));
-+ {
-+ uInt bl, bd;
-+ inflate_huft *tl, *td;
-+
-+ inflate_trees_fixed(&bl, &bd, &tl, &td);
-+ s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
-+ if (s->sub.decode.codes == Z_NULL)
-+ {
-+ r = Z_MEM_ERROR;
-+ LEAVE
-+ }
-+ s->sub.decode.tl = Z_NULL; /* don't try to free these */
-+ s->sub.decode.td = Z_NULL;
-+ }
-+ DUMPBITS(3)
-+ s->mode = CODES;
-+ break;
-+ case 2: /* dynamic */
-+ Trace((stderr, "inflate: dynamic codes block%s\n",
-+ s->last ? " (last)" : ""));
-+ DUMPBITS(3)
-+ s->mode = TABLE;
-+ break;
-+ case 3: /* illegal */
-+ DUMPBITS(3)
-+ s->mode = BADB;
-+ z->msg = "invalid block type";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ }
-+ break;
-+ case LENS:
-+ NEEDBITS(32)
-+ if (((~b) >> 16) != (b & 0xffff))
-+ {
-+ s->mode = BADB;
-+ z->msg = "invalid stored block lengths";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ }
-+ s->sub.left = (uInt)b & 0xffff;
-+ b = k = 0; /* dump bits */
-+ Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
-+ s->mode = s->sub.left ? STORED : TYPE;
-+ break;
-+ case STORED:
-+ if (n == 0)
-+ LEAVE
-+ NEEDOUT
-+ t = s->sub.left;
-+ if (t > n) t = n;
-+ if (t > m) t = m;
-+ zmemcpy(q, p, t);
-+ p += t; n -= t;
-+ q += t; m -= t;
-+ if ((s->sub.left -= t) != 0)
-+ break;
-+ Tracev((stderr, "inflate: stored end, %lu total out\n",
-+ z->total_out + (q >= s->read ? q - s->read :
-+ (s->end - s->read) + (q - s->window))));
-+ s->mode = s->last ? DRY : TYPE;
-+ break;
-+ case TABLE:
-+ NEEDBITS(14)
-+ s->sub.trees.table = t = (uInt)b & 0x3fff;
-+#ifndef PKZIP_BUG_WORKAROUND
-+ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
-+ {
-+ s->mode = BADB;
-+ z->msg = "too many length or distance symbols";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ }
-+#endif
-+ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
-+ if (t < 19)
-+ t = 19;
-+ if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
-+ {
-+ r = Z_MEM_ERROR;
-+ LEAVE
-+ }
-+ s->sub.trees.nblens = t;
-+ DUMPBITS(14)
-+ s->sub.trees.index = 0;
-+ Tracev((stderr, "inflate: table sizes ok\n"));
-+ s->mode = BTREE;
-+ case BTREE:
-+ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
-+ {
-+ NEEDBITS(3)
-+ s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
-+ DUMPBITS(3)
-+ }
-+ while (s->sub.trees.index < 19)
-+ s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
-+ s->sub.trees.bb = 7;
-+ t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
-+ &s->sub.trees.tb, z);
-+ if (t != Z_OK)
-+ {
-+ r = t;
-+ if (r == Z_DATA_ERROR)
-+ s->mode = BADB;
-+ LEAVE
-+ }
-+ s->sub.trees.index = 0;
-+ Tracev((stderr, "inflate: bits tree ok\n"));
-+ s->mode = DTREE;
-+ case DTREE:
-+ while (t = s->sub.trees.table,
-+ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
-+ {
-+ inflate_huft *h;
-+ uInt i, j, c;
-+
-+ t = s->sub.trees.bb;
-+ NEEDBITS(t)
-+ h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
-+ t = h->word.what.Bits;
-+ c = h->more.Base;
-+ if (c < 16)
-+ {
-+ DUMPBITS(t)
-+ s->sub.trees.blens[s->sub.trees.index++] = c;
-+ }
-+ else /* c == 16..18 */
-+ {
-+ i = c == 18 ? 7 : c - 14;
-+ j = c == 18 ? 11 : 3;
-+ NEEDBITS(t + i)
-+ DUMPBITS(t)
-+ j += (uInt)b & inflate_mask[i];
-+ DUMPBITS(i)
-+ i = s->sub.trees.index;
-+ t = s->sub.trees.table;
-+ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
-+ (c == 16 && i < 1))
-+ {
-+ s->mode = BADB;
-+ z->msg = "invalid bit length repeat";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ }
-+ c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
-+ do {
-+ s->sub.trees.blens[i++] = c;
-+ } while (--j);
-+ s->sub.trees.index = i;
-+ }
-+ }
-+ inflate_trees_free(s->sub.trees.tb, z);
-+ s->sub.trees.tb = Z_NULL;
-+ {
-+ uInt bl, bd;
-+ inflate_huft *tl, *td;
-+ inflate_codes_statef *c;
-+
-+ bl = 9; /* must be <= 9 for lookahead assumptions */
-+ bd = 6; /* must be <= 9 for lookahead assumptions */
-+ t = s->sub.trees.table;
-+ t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
-+ s->sub.trees.blens, &bl, &bd, &tl, &td, z);
-+ if (t != Z_OK)
-+ {
-+ if (t == (uInt)Z_DATA_ERROR)
-+ s->mode = BADB;
-+ r = t;
-+ LEAVE
-+ }
-+ Tracev((stderr, "inflate: trees ok\n"));
-+ if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
-+ {
-+ inflate_trees_free(td, z);
-+ inflate_trees_free(tl, z);
-+ r = Z_MEM_ERROR;
-+ LEAVE
-+ }
-+ ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt));
-+ s->sub.decode.codes = c;
-+ s->sub.decode.tl = tl;
-+ s->sub.decode.td = td;
-+ }
-+ s->mode = CODES;
-+ case CODES:
-+ UPDATE
-+ if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
-+ return inflate_flush(s, z, r);
-+ r = Z_OK;
-+ inflate_codes_free(s->sub.decode.codes, z);
-+ inflate_trees_free(s->sub.decode.td, z);
-+ inflate_trees_free(s->sub.decode.tl, z);
-+ LOAD
-+ Tracev((stderr, "inflate: codes end, %lu total out\n",
-+ z->total_out + (q >= s->read ? q - s->read :
-+ (s->end - s->read) + (q - s->window))));
-+ if (!s->last)
-+ {
-+ s->mode = TYPE;
-+ break;
-+ }
-+ if (k > 7) /* return unused byte, if any */
-+ {
-+ Assert(k < 16, "inflate_codes grabbed too many bytes")
-+ k -= 8;
-+ n++;
-+ p--; /* can always return one */
-+ }
-+ s->mode = DRY;
-+ case DRY:
-+ FLUSH
-+ if (s->read != s->write)
-+ LEAVE
-+ s->mode = DONEB;
-+ case DONEB:
-+ r = Z_STREAM_END;
-+ LEAVE
-+ case BADB:
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ default:
-+ r = Z_STREAM_ERROR;
-+ LEAVE
-+ }
-+}
-+
-+
-+local int inflate_blocks_free(s, z, c)
-+inflate_blocks_statef *s;
-+z_stream *z;
-+uLongf *c;
-+{
-+ inflate_blocks_reset(s, z, c);
-+ ZFREE(z, s->window, s->end - s->window);
-+ ZFREE(z, s, sizeof(struct inflate_blocks_state));
-+ Trace((stderr, "inflate: blocks freed\n"));
-+ return Z_OK;
-+}
-+
-+/*
-+ * This subroutine adds the data at next_in/avail_in to the output history
-+ * without performing any output. The output buffer must be "caught up";
-+ * i.e. no pending output (hence s->read equals s->write), and the state must
-+ * be BLOCKS (i.e. we should be willing to see the start of a series of
-+ * BLOCKS). On exit, the output will also be caught up, and the checksum
-+ * will have been updated if need be.
-+ */
-+local int inflate_addhistory(s, z)
-+inflate_blocks_statef *s;
-+z_stream *z;
-+{
-+ uLong b; /* bit buffer */ /* NOT USED HERE */
-+ uInt k; /* bits in bit buffer */ /* NOT USED HERE */
-+ uInt t; /* temporary storage */
-+ Bytef *p; /* input data pointer */
-+ uInt n; /* bytes available there */
-+ Bytef *q; /* output window write pointer */
-+ uInt m; /* bytes to end of window or read pointer */
-+
-+ if (s->read != s->write)
-+ return Z_STREAM_ERROR;
-+ if (s->mode != TYPE)
-+ return Z_DATA_ERROR;
-+
-+ /* we're ready to rock */
-+ LOAD
-+ /* while there is input ready, copy to output buffer, moving
-+ * pointers as needed.
-+ */
-+ while (n) {
-+ t = n; /* how many to do */
-+ /* is there room until end of buffer? */
-+ if (t > m) t = m;
-+ /* update check information */
-+ if (s->checkfn != Z_NULL)
-+ s->check = (*s->checkfn)(s->check, q, t);
-+ zmemcpy(q, p, t);
-+ q += t;
-+ p += t;
-+ n -= t;
-+ z->total_out += t;
-+ s->read = q; /* drag read pointer forward */
-+/* WRAP */ /* expand WRAP macro by hand to handle s->read */
-+ if (q == s->end) {
-+ s->read = q = s->window;
-+ m = WAVAIL;
-+ }
-+ }
-+ UPDATE
-+ return Z_OK;
-+}
-+
-+
-+/*
-+ * At the end of a Deflate-compressed PPP packet, we expect to have seen
-+ * a `stored' block type value but not the (zero) length bytes.
-+ */
-+local int inflate_packet_flush(s)
-+ inflate_blocks_statef *s;
-+{
-+ if (s->mode != LENS)
-+ return Z_DATA_ERROR;
-+ s->mode = TYPE;
-+ return Z_OK;
-+}
-+
-+
-+/*+++++*/
-+/* inftrees.c -- generate Huffman trees for efficient decoding
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* simplify the use of the inflate_huft type with some defines */
-+#define base more.Base
-+#define next more.Next
-+#define exop word.what.Exop
-+#define bits word.what.Bits
-+
-+
-+local int huft_build OF((
-+ uIntf *, /* code lengths in bits */
-+ uInt, /* number of codes */
-+ uInt, /* number of "simple" codes */
-+ uIntf *, /* list of base values for non-simple codes */
-+ uIntf *, /* list of extra bits for non-simple codes */
-+ inflate_huft * FAR*,/* result: starting table */
-+ uIntf *, /* maximum lookup bits (returns actual) */
-+ z_stream *)); /* for zalloc function */
-+
-+local voidpf falloc OF((
-+ voidpf, /* opaque pointer (not used) */
-+ uInt, /* number of items */
-+ uInt)); /* size of item */
-+
-+local void ffree OF((
-+ voidpf q, /* opaque pointer (not used) */
-+ voidpf p, /* what to free (not used) */
-+ uInt n)); /* number of bytes (not used) */
-+
-+/* Tables for deflate from PKZIP's appnote.txt. */
-+local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */
-+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
-+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
-+ /* actually lengths - 2; also see note #13 above about 258 */
-+local uInt cplext[] = { /* Extra bits for literal codes 257..285 */
-+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
-+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */
-+local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */
-+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
-+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
-+ 8193, 12289, 16385, 24577};
-+local uInt cpdext[] = { /* Extra bits for distance codes */
-+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
-+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
-+ 12, 12, 13, 13};
-+
-+/*
-+ Huffman code decoding is performed using a multi-level table lookup.
-+ The fastest way to decode is to simply build a lookup table whose
-+ size is determined by the longest code. However, the time it takes
-+ to build this table can also be a factor if the data being decoded
-+ is not very long. The most common codes are necessarily the
-+ shortest codes, so those codes dominate the decoding time, and hence
-+ the speed. The idea is you can have a shorter table that decodes the
-+ shorter, more probable codes, and then point to subsidiary tables for
-+ the longer codes. The time it costs to decode the longer codes is
-+ then traded against the time it takes to make longer tables.
-+
-+ This results of this trade are in the variables lbits and dbits
-+ below. lbits is the number of bits the first level table for literal/
-+ length codes can decode in one step, and dbits is the same thing for
-+ the distance codes. Subsequent tables are also less than or equal to
-+ those sizes. These values may be adjusted either when all of the
-+ codes are shorter than that, in which case the longest code length in
-+ bits is used, or when the shortest code is *longer* than the requested
-+ table size, in which case the length of the shortest code in bits is
-+ used.
-+
-+ There are two different values for the two tables, since they code a
-+ different number of possibilities each. The literal/length table
-+ codes 286 possible values, or in a flat code, a little over eight
-+ bits. The distance table codes 30 possible values, or a little less
-+ than five bits, flat. The optimum values for speed end up being
-+ about one bit more than those, so lbits is 8+1 and dbits is 5+1.
-+ The optimum values may differ though from machine to machine, and
-+ possibly even between compilers. Your mileage may vary.
-+ */
-+
-+
-+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
-+#define BMAX 15 /* maximum bit length of any code */
-+#define N_MAX 288 /* maximum number of codes in any set */
-+
-+#ifdef DEBUG_ZLIB
-+ uInt inflate_hufts;
-+#endif
-+
-+local int huft_build(b, n, s, d, e, t, m, zs)
-+uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
-+uInt n; /* number of codes (assumed <= N_MAX) */
-+uInt s; /* number of simple-valued codes (0..s-1) */
-+uIntf *d; /* list of base values for non-simple codes */
-+uIntf *e; /* list of extra bits for non-simple codes */
-+inflate_huft * FAR *t; /* result: starting table */
-+uIntf *m; /* maximum lookup bits, returns actual */
-+z_stream *zs; /* for zalloc function */
-+/* Given a list of code lengths and a maximum table size, make a set of
-+ tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
-+ if the given code set is incomplete (the tables are still built in this
-+ case), Z_DATA_ERROR if the input is invalid (all zero length codes or an
-+ over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */
-+{
-+
-+ uInt a; /* counter for codes of length k */
-+ uInt c[BMAX+1]; /* bit length count table */
-+ uInt f; /* i repeats in table every f entries */
-+ int g; /* maximum code length */
-+ int h; /* table level */
-+ register uInt i; /* counter, current code */
-+ register uInt j; /* counter */
-+ register int k; /* number of bits in current code */
-+ int l; /* bits per table (returned in m) */
-+ register uIntf *p; /* pointer into c[], b[], or v[] */
-+ inflate_huft *q; /* points to current table */
-+ struct inflate_huft_s r; /* table entry for structure assignment */
-+ inflate_huft *u[BMAX]; /* table stack */
-+ uInt v[N_MAX]; /* values in order of bit length */
-+ register int w; /* bits before this table == (l * h) */
-+ uInt x[BMAX+1]; /* bit offsets, then code stack */
-+ uIntf *xp; /* pointer into x */
-+ int y; /* number of dummy codes added */
-+ uInt z; /* number of entries in current table */
-+
-+
-+ /* Generate counts for each bit length */
-+ p = c;
-+#define C0 *p++ = 0;
-+#define C2 C0 C0 C0 C0
-+#define C4 C2 C2 C2 C2
-+ C4 /* clear c[]--assume BMAX+1 is 16 */
-+ p = b; i = n;
-+ do {
-+ c[*p++]++; /* assume all entries <= BMAX */
-+ } while (--i);
-+ if (c[0] == n) /* null input--all zero length codes */
-+ {
-+ *t = (inflate_huft *)Z_NULL;
-+ *m = 0;
-+ return Z_OK;
-+ }
-+
-+
-+ /* Find minimum and maximum length, bound *m by those */
-+ l = *m;
-+ for (j = 1; j <= BMAX; j++)
-+ if (c[j])
-+ break;
-+ k = j; /* minimum code length */
-+ if ((uInt)l < j)
-+ l = j;
-+ for (i = BMAX; i; i--)
-+ if (c[i])
-+ break;
-+ g = i; /* maximum code length */
-+ if ((uInt)l > i)
-+ l = i;
-+ *m = l;
-+
-+
-+ /* Adjust last length count to fill out codes, if needed */
-+ for (y = 1 << j; j < i; j++, y <<= 1)
-+ if ((y -= c[j]) < 0)
-+ return Z_DATA_ERROR;
-+ if ((y -= c[i]) < 0)
-+ return Z_DATA_ERROR;
-+ c[i] += y;
-+
-+
-+ /* Generate starting offsets into the value table for each length */
-+ x[1] = j = 0;
-+ p = c + 1; xp = x + 2;
-+ while (--i) { /* note that i == g from above */
-+ *xp++ = (j += *p++);
-+ }
-+
-+
-+ /* Make a table of values in order of bit lengths */
-+ p = b; i = 0;
-+ do {
-+ if ((j = *p++) != 0)
-+ v[x[j]++] = i;
-+ } while (++i < n);
-+
-+
-+ /* Generate the Huffman codes and for each, make the table entries */
-+ x[0] = i = 0; /* first Huffman code is zero */
-+ p = v; /* grab values in bit order */
-+ h = -1; /* no tables yet--level -1 */
-+ w = -l; /* bits decoded == (l * h) */
-+ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
-+ q = (inflate_huft *)Z_NULL; /* ditto */
-+ z = 0; /* ditto */
-+
-+ /* go through the bit lengths (k already is bits in shortest code) */
-+ for (; k <= g; k++)
-+ {
-+ a = c[k];
-+ while (a--)
-+ {
-+ /* here i is the Huffman code of length k bits for value *p */
-+ /* make tables up to required level */
-+ while (k > w + l)
-+ {
-+ h++;
-+ w += l; /* previous table always l bits */
-+
-+ /* compute minimum size table less than or equal to l bits */
-+ z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */
-+ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
-+ { /* too few codes for k-w bit table */
-+ f -= a + 1; /* deduct codes from patterns left */
-+ xp = c + k;
-+ if (j < z)
-+ while (++j < z) /* try smaller tables up to z bits */
-+ {
-+ if ((f <<= 1) <= *++xp)
-+ break; /* enough codes to use up j bits */
-+ f -= *xp; /* else deduct codes from patterns */
-+ }
-+ }
-+ z = 1 << j; /* table entries for j-bit table */
-+
-+ /* allocate and link in new table */
-+ if ((q = (inflate_huft *)ZALLOC
-+ (zs,z + 1,sizeof(inflate_huft))) == Z_NULL)
-+ {
-+ if (h)
-+ inflate_trees_free(u[0], zs);
-+ return Z_MEM_ERROR; /* not enough memory */
-+ }
-+ q->word.Nalloc = z + 1;
-+#ifdef DEBUG_ZLIB
-+ inflate_hufts += z + 1;
-+#endif
-+ *t = q + 1; /* link to list for huft_free() */
-+ *(t = &(q->next)) = Z_NULL;
-+ u[h] = ++q; /* table starts after link */
-+
-+ /* connect to last table, if there is one */
-+ if (h)
-+ {
-+ x[h] = i; /* save pattern for backing up */
-+ r.bits = (Byte)l; /* bits to dump before this table */
-+ r.exop = (Byte)j; /* bits in this table */
-+ r.next = q; /* pointer to this table */
-+ j = i >> (w - l); /* (get around Turbo C bug) */
-+ u[h-1][j] = r; /* connect to last table */
-+ }
-+ }
-+
-+ /* set up table entry in r */
-+ r.bits = (Byte)(k - w);
-+ if (p >= v + n)
-+ r.exop = 128 + 64; /* out of values--invalid code */
-+ else if (*p < s)
-+ {
-+ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
-+ r.base = *p++; /* simple code is just the value */
-+ }
-+ else
-+ {
-+ r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */
-+ r.base = d[*p++ - s];
-+ }
-+
-+ /* fill code-like entries with r */
-+ f = 1 << (k - w);
-+ for (j = i >> w; j < z; j += f)
-+ q[j] = r;
-+
-+ /* backwards increment the k-bit code i */
-+ for (j = 1 << (k - 1); i & j; j >>= 1)
-+ i ^= j;
-+ i ^= j;
-+
-+ /* backup over finished tables */
-+ while ((i & ((1 << w) - 1)) != x[h])
-+ {
-+ h--; /* don't need to update q */
-+ w -= l;
-+ }
-+ }
-+ }
-+
-+
-+ /* Return Z_BUF_ERROR if we were given an incomplete table */
-+ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
-+}
-+
-+
-+local int inflate_trees_bits(c, bb, tb, z)
-+uIntf *c; /* 19 code lengths */
-+uIntf *bb; /* bits tree desired/actual depth */
-+inflate_huft * FAR *tb; /* bits tree result */
-+z_stream *z; /* for zfree function */
-+{
-+ int r;
-+
-+ r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z);
-+ if (r == Z_DATA_ERROR)
-+ z->msg = "oversubscribed dynamic bit lengths tree";
-+ else if (r == Z_BUF_ERROR)
-+ {
-+ inflate_trees_free(*tb, z);
-+ z->msg = "incomplete dynamic bit lengths tree";
-+ r = Z_DATA_ERROR;
-+ }
-+ return r;
-+}
-+
-+
-+local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z)
-+uInt nl; /* number of literal/length codes */
-+uInt nd; /* number of distance codes */
-+uIntf *c; /* that many (total) code lengths */
-+uIntf *bl; /* literal desired/actual bit depth */
-+uIntf *bd; /* distance desired/actual bit depth */
-+inflate_huft * FAR *tl; /* literal/length tree result */
-+inflate_huft * FAR *td; /* distance tree result */
-+z_stream *z; /* for zfree function */
-+{
-+ int r;
-+
-+ /* build literal/length tree */
-+ if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK)
-+ {
-+ if (r == Z_DATA_ERROR)
-+ z->msg = "oversubscribed literal/length tree";
-+ else if (r == Z_BUF_ERROR)
-+ {
-+ inflate_trees_free(*tl, z);
-+ z->msg = "incomplete literal/length tree";
-+ r = Z_DATA_ERROR;
-+ }
-+ return r;
-+ }
-+
-+ /* build distance tree */
-+ if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK)
-+ {
-+ if (r == Z_DATA_ERROR)
-+ z->msg = "oversubscribed literal/length tree";
-+ else if (r == Z_BUF_ERROR) {
-+#ifdef PKZIP_BUG_WORKAROUND
-+ r = Z_OK;
-+ }
-+#else
-+ inflate_trees_free(*td, z);
-+ z->msg = "incomplete literal/length tree";
-+ r = Z_DATA_ERROR;
-+ }
-+ inflate_trees_free(*tl, z);
-+ return r;
-+#endif
-+ }
-+
-+ /* done */
-+ return Z_OK;
-+}
-+
-+
-+/* build fixed tables only once--keep them here */
-+local int fixed_lock = 0;
-+local int fixed_built = 0;
-+#define FIXEDH 530 /* number of hufts used by fixed tables */
-+local uInt fixed_left = FIXEDH;
-+local inflate_huft fixed_mem[FIXEDH];
-+local uInt fixed_bl;
-+local uInt fixed_bd;
-+local inflate_huft *fixed_tl;
-+local inflate_huft *fixed_td;
-+
-+
-+local voidpf falloc(q, n, s)
-+voidpf q; /* opaque pointer (not used) */
-+uInt n; /* number of items */
-+uInt s; /* size of item */
-+{
-+ Assert(s == sizeof(inflate_huft) && n <= fixed_left,
-+ "inflate_trees falloc overflow");
-+ if (q) s++; /* to make some compilers happy */
-+ fixed_left -= n;
-+ return (voidpf)(fixed_mem + fixed_left);
-+}
-+
-+
-+local void ffree(q, p, n)
-+voidpf q;
-+voidpf p;
-+uInt n;
-+{
-+ Assert(0, "inflate_trees ffree called!");
-+ if (q) q = p; /* to make some compilers happy */
-+}
-+
-+
-+local int inflate_trees_fixed(bl, bd, tl, td)
-+uIntf *bl; /* literal desired/actual bit depth */
-+uIntf *bd; /* distance desired/actual bit depth */
-+inflate_huft * FAR *tl; /* literal/length tree result */
-+inflate_huft * FAR *td; /* distance tree result */
-+{
-+ /* build fixed tables if not built already--lock out other instances */
-+ while (++fixed_lock > 1)
-+ fixed_lock--;
-+ if (!fixed_built)
-+ {
-+ int k; /* temporary variable */
-+ unsigned c[288]; /* length list for huft_build */
-+ z_stream z; /* for falloc function */
-+
-+ /* set up fake z_stream for memory routines */
-+ z.zalloc = falloc;
-+ z.zfree = ffree;
-+ z.opaque = Z_NULL;
-+
-+ /* literal table */
-+ for (k = 0; k < 144; k++)
-+ c[k] = 8;
-+ for (; k < 256; k++)
-+ c[k] = 9;
-+ for (; k < 280; k++)
-+ c[k] = 7;
-+ for (; k < 288; k++)
-+ c[k] = 8;
-+ fixed_bl = 7;
-+ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z);
-+
-+ /* distance table */
-+ for (k = 0; k < 30; k++)
-+ c[k] = 5;
-+ fixed_bd = 5;
-+ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z);
-+
-+ /* done */
-+ fixed_built = 1;
-+ }
-+ fixed_lock--;
-+ *bl = fixed_bl;
-+ *bd = fixed_bd;
-+ *tl = fixed_tl;
-+ *td = fixed_td;
-+ return Z_OK;
-+}
-+
-+
-+local int inflate_trees_free(t, z)
-+inflate_huft *t; /* table to free */
-+z_stream *z; /* for zfree function */
-+/* Free the malloc'ed tables built by huft_build(), which makes a linked
-+ list of the tables it made, with the links in a dummy first entry of
-+ each table. */
-+{
-+ register inflate_huft *p, *q;
-+
-+ /* Go through linked list, freeing from the malloced (t[-1]) address. */
-+ p = t;
-+ while (p != Z_NULL)
-+ {
-+ q = (--p)->next;
-+ ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft));
-+ p = q;
-+ }
-+ return Z_OK;
-+}
-+
-+/*+++++*/
-+/* infcodes.c -- process literals and length/distance pairs
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* simplify the use of the inflate_huft type with some defines */
-+#define base more.Base
-+#define next more.Next
-+#define exop word.what.Exop
-+#define bits word.what.Bits
-+
-+/* inflate codes private state */
-+struct inflate_codes_state {
-+
-+ /* mode */
-+ enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
-+ START, /* x: set up for LEN */
-+ LEN, /* i: get length/literal/eob next */
-+ LENEXT, /* i: getting length extra (have base) */
-+ DIST, /* i: get distance next */
-+ DISTEXT, /* i: getting distance extra */
-+ COPY, /* o: copying bytes in window, waiting for space */
-+ LIT, /* o: got literal, waiting for output space */
-+ WASH, /* o: got eob, possibly still output waiting */
-+ END, /* x: got eob and all data flushed */
-+ BADCODE} /* x: got error */
-+ mode; /* current inflate_codes mode */
-+
-+ /* mode dependent information */
-+ uInt len;
-+ union {
-+ struct {
-+ inflate_huft *tree; /* pointer into tree */
-+ uInt need; /* bits needed */
-+ } code; /* if LEN or DIST, where in tree */
-+ uInt lit; /* if LIT, literal */
-+ struct {
-+ uInt get; /* bits to get for extra */
-+ uInt dist; /* distance back to copy from */
-+ } copy; /* if EXT or COPY, where and how much */
-+ } sub; /* submode */
-+
-+ /* mode independent information */
-+ Byte lbits; /* ltree bits decoded per branch */
-+ Byte dbits; /* dtree bits decoder per branch */
-+ inflate_huft *ltree; /* literal/length/eob tree */
-+ inflate_huft *dtree; /* distance tree */
-+
-+};
-+
-+
-+local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
-+uInt bl, bd;
-+inflate_huft *tl, *td;
-+z_stream *z;
-+{
-+ inflate_codes_statef *c;
-+
-+ if ((c = (inflate_codes_statef *)
-+ ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
-+ {
-+ c->mode = START;
-+ c->lbits = (Byte)bl;
-+ c->dbits = (Byte)bd;
-+ c->ltree = tl;
-+ c->dtree = td;
-+ Tracev((stderr, "inflate: codes new\n"));
-+ }
-+ return c;
-+}
-+
-+
-+local int inflate_codes(s, z, r)
-+inflate_blocks_statef *s;
-+z_stream *z;
-+int r;
-+{
-+ uInt j; /* temporary storage */
-+ inflate_huft *t; /* temporary pointer */
-+ uInt e; /* extra bits or operation */
-+ uLong b; /* bit buffer */
-+ uInt k; /* bits in bit buffer */
-+ Bytef *p; /* input data pointer */
-+ uInt n; /* bytes available there */
-+ Bytef *q; /* output window write pointer */
-+ uInt m; /* bytes to end of window or read pointer */
-+ Bytef *f; /* pointer to copy strings from */
-+ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
-+
-+ /* copy input/output information to locals (UPDATE macro restores) */
-+ LOAD
-+
-+ /* process input and output based on current state */
-+ while (1) switch (c->mode)
-+ { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
-+ case START: /* x: set up for LEN */
-+#ifndef SLOW
-+ if (m >= 258 && n >= 10)
-+ {
-+ UPDATE
-+ r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
-+ LOAD
-+ if (r != Z_OK)
-+ {
-+ c->mode = r == Z_STREAM_END ? WASH : BADCODE;
-+ break;
-+ }
-+ }
-+#endif /* !SLOW */
-+ c->sub.code.need = c->lbits;
-+ c->sub.code.tree = c->ltree;
-+ c->mode = LEN;
-+ case LEN: /* i: get length/literal/eob next */
-+ j = c->sub.code.need;
-+ NEEDBITS(j)
-+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
-+ DUMPBITS(t->bits)
-+ e = (uInt)(t->exop);
-+ if (e == 0) /* literal */
-+ {
-+ c->sub.lit = t->base;
-+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-+ "inflate: literal '%c'\n" :
-+ "inflate: literal 0x%02x\n", t->base));
-+ c->mode = LIT;
-+ break;
-+ }
-+ if (e & 16) /* length */
-+ {
-+ c->sub.copy.get = e & 15;
-+ c->len = t->base;
-+ c->mode = LENEXT;
-+ break;
-+ }
-+ if ((e & 64) == 0) /* next table */
-+ {
-+ c->sub.code.need = e;
-+ c->sub.code.tree = t->next;
-+ break;
-+ }
-+ if (e & 32) /* end of block */
-+ {
-+ Tracevv((stderr, "inflate: end of block\n"));
-+ c->mode = WASH;
-+ break;
-+ }
-+ c->mode = BADCODE; /* invalid code */
-+ z->msg = "invalid literal/length code";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ case LENEXT: /* i: getting length extra (have base) */
-+ j = c->sub.copy.get;
-+ NEEDBITS(j)
-+ c->len += (uInt)b & inflate_mask[j];
-+ DUMPBITS(j)
-+ c->sub.code.need = c->dbits;
-+ c->sub.code.tree = c->dtree;
-+ Tracevv((stderr, "inflate: length %u\n", c->len));
-+ c->mode = DIST;
-+ case DIST: /* i: get distance next */
-+ j = c->sub.code.need;
-+ NEEDBITS(j)
-+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
-+ DUMPBITS(t->bits)
-+ e = (uInt)(t->exop);
-+ if (e & 16) /* distance */
-+ {
-+ c->sub.copy.get = e & 15;
-+ c->sub.copy.dist = t->base;
-+ c->mode = DISTEXT;
-+ break;
-+ }
-+ if ((e & 64) == 0) /* next table */
-+ {
-+ c->sub.code.need = e;
-+ c->sub.code.tree = t->next;
-+ break;
-+ }
-+ c->mode = BADCODE; /* invalid code */
-+ z->msg = "invalid distance code";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ case DISTEXT: /* i: getting distance extra */
-+ j = c->sub.copy.get;
-+ NEEDBITS(j)
-+ c->sub.copy.dist += (uInt)b & inflate_mask[j];
-+ DUMPBITS(j)
-+ Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
-+ c->mode = COPY;
-+ case COPY: /* o: copying bytes in window, waiting for space */
-+#ifndef __TURBOC__ /* Turbo C bug for following expression */
-+ f = (uInt)(q - s->window) < c->sub.copy.dist ?
-+ s->end - (c->sub.copy.dist - (q - s->window)) :
-+ q - c->sub.copy.dist;
-+#else
-+ f = q - c->sub.copy.dist;
-+ if ((uInt)(q - s->window) < c->sub.copy.dist)
-+ f = s->end - (c->sub.copy.dist - (q - s->window));
-+#endif
-+ while (c->len)
-+ {
-+ NEEDOUT
-+ OUTBYTE(*f++)
-+ if (f == s->end)
-+ f = s->window;
-+ c->len--;
-+ }
-+ c->mode = START;
-+ break;
-+ case LIT: /* o: got literal, waiting for output space */
-+ NEEDOUT
-+ OUTBYTE(c->sub.lit)
-+ c->mode = START;
-+ break;
-+ case WASH: /* o: got eob, possibly more output */
-+ FLUSH
-+ if (s->read != s->write)
-+ LEAVE
-+ c->mode = END;
-+ case END:
-+ r = Z_STREAM_END;
-+ LEAVE
-+ case BADCODE: /* x: got error */
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ default:
-+ r = Z_STREAM_ERROR;
-+ LEAVE
-+ }
-+}
-+
-+
-+local void inflate_codes_free(c, z)
-+inflate_codes_statef *c;
-+z_stream *z;
-+{
-+ ZFREE(z, c, sizeof(struct inflate_codes_state));
-+ Tracev((stderr, "inflate: codes free\n"));
-+}
-+
-+/*+++++*/
-+/* inflate_util.c -- data and routines common to blocks and codes
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* copy as much as possible from the sliding window to the output area */
-+local int inflate_flush(s, z, r)
-+inflate_blocks_statef *s;
-+z_stream *z;
-+int r;
-+{
-+ uInt n;
-+ Bytef *p, *q;
-+
-+ /* local copies of source and destination pointers */
-+ p = z->next_out;
-+ q = s->read;
-+
-+ /* compute number of bytes to copy as far as end of window */
-+ n = (uInt)((q <= s->write ? s->write : s->end) - q);
-+ if (n > z->avail_out) n = z->avail_out;
-+ if (n && r == Z_BUF_ERROR) r = Z_OK;
-+
-+ /* update counters */
-+ z->avail_out -= n;
-+ z->total_out += n;
-+
-+ /* update check information */
-+ if (s->checkfn != Z_NULL)
-+ s->check = (*s->checkfn)(s->check, q, n);
-+
-+ /* copy as far as end of window */
-+ zmemcpy(p, q, n);
-+ p += n;
-+ q += n;
-+
-+ /* see if more to copy at beginning of window */
-+ if (q == s->end)
-+ {
-+ /* wrap pointers */
-+ q = s->window;
-+ if (s->write == s->end)
-+ s->write = s->window;
-+
-+ /* compute bytes to copy */
-+ n = (uInt)(s->write - q);
-+ if (n > z->avail_out) n = z->avail_out;
-+ if (n && r == Z_BUF_ERROR) r = Z_OK;
-+
-+ /* update counters */
-+ z->avail_out -= n;
-+ z->total_out += n;
-+
-+ /* update check information */
-+ if (s->checkfn != Z_NULL)
-+ s->check = (*s->checkfn)(s->check, q, n);
-+
-+ /* copy */
-+ zmemcpy(p, q, n);
-+ p += n;
-+ q += n;
-+ }
-+
-+ /* update pointers */
-+ z->next_out = p;
-+ s->read = q;
-+
-+ /* done */
-+ return r;
-+}
-+
-+
-+/*+++++*/
-+/* inffast.c -- process literals and length/distance pairs fast
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* simplify the use of the inflate_huft type with some defines */
-+#define base more.Base
-+#define next more.Next
-+#define exop word.what.Exop
-+#define bits word.what.Bits
-+
-+/* macros for bit input with no checking and for returning unused bytes */
-+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-+#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;}
-+
-+/* Called with number of bytes left to write in window at least 258
-+ (the maximum string length) and number of input bytes available
-+ at least ten. The ten bytes are six bytes for the longest length/
-+ distance pair plus four bytes for overloading the bit buffer. */
-+
-+local int inflate_fast(bl, bd, tl, td, s, z)
-+uInt bl, bd;
-+inflate_huft *tl, *td;
-+inflate_blocks_statef *s;
-+z_stream *z;
-+{
-+ inflate_huft *t; /* temporary pointer */
-+ uInt e; /* extra bits or operation */
-+ uLong b; /* bit buffer */
-+ uInt k; /* bits in bit buffer */
-+ Bytef *p; /* input data pointer */
-+ uInt n; /* bytes available there */
-+ Bytef *q; /* output window write pointer */
-+ uInt m; /* bytes to end of window or read pointer */
-+ uInt ml; /* mask for literal/length tree */
-+ uInt md; /* mask for distance tree */
-+ uInt c; /* bytes to copy */
-+ uInt d; /* distance back to copy from */
-+ Bytef *r; /* copy source pointer */
-+
-+ /* load input, output, bit values */
-+ LOAD
-+
-+ /* initialize masks */
-+ ml = inflate_mask[bl];
-+ md = inflate_mask[bd];
-+
-+ /* do until not enough input or output space for fast loop */
-+ do { /* assume called with m >= 258 && n >= 10 */
-+ /* get literal/length code */
-+ GRABBITS(20) /* max bits for literal/length code */
-+ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
-+ {
-+ DUMPBITS(t->bits)
-+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-+ "inflate: * literal '%c'\n" :
-+ "inflate: * literal 0x%02x\n", t->base));
-+ *q++ = (Byte)t->base;
-+ m--;
-+ continue;
-+ }
-+ do {
-+ DUMPBITS(t->bits)
-+ if (e & 16)
-+ {
-+ /* get extra bits for length */
-+ e &= 15;
-+ c = t->base + ((uInt)b & inflate_mask[e]);
-+ DUMPBITS(e)
-+ Tracevv((stderr, "inflate: * length %u\n", c));
-+
-+ /* decode distance base of block to copy */
-+ GRABBITS(15); /* max bits for distance code */
-+ e = (t = td + ((uInt)b & md))->exop;
-+ do {
-+ DUMPBITS(t->bits)
-+ if (e & 16)
-+ {
-+ /* get extra bits to add to distance base */
-+ e &= 15;
-+ GRABBITS(e) /* get extra bits (up to 13) */
-+ d = t->base + ((uInt)b & inflate_mask[e]);
-+ DUMPBITS(e)
-+ Tracevv((stderr, "inflate: * distance %u\n", d));
-+
-+ /* do the copy */
-+ m -= c;
-+ if ((uInt)(q - s->window) >= d) /* offset before dest */
-+ { /* just copy */
-+ r = q - d;
-+ *q++ = *r++; c--; /* minimum count is three, */
-+ *q++ = *r++; c--; /* so unroll loop a little */
-+ }
-+ else /* else offset after destination */
-+ {
-+ e = d - (q - s->window); /* bytes from offset to end */
-+ r = s->end - e; /* pointer to offset */
-+ if (c > e) /* if source crosses, */
-+ {
-+ c -= e; /* copy to end of window */
-+ do {
-+ *q++ = *r++;
-+ } while (--e);
-+ r = s->window; /* copy rest from start of window */
-+ }
-+ }
-+ do { /* copy all or what's left */
-+ *q++ = *r++;
-+ } while (--c);
-+ break;
-+ }
-+ else if ((e & 64) == 0)
-+ e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop;
-+ else
-+ {
-+ z->msg = "invalid distance code";
-+ UNGRAB
-+ UPDATE
-+ return Z_DATA_ERROR;
-+ }
-+ } while (1);
-+ break;
-+ }
-+ if ((e & 64) == 0)
-+ {
-+ if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0)
-+ {
-+ DUMPBITS(t->bits)
-+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-+ "inflate: * literal '%c'\n" :
-+ "inflate: * literal 0x%02x\n", t->base));
-+ *q++ = (Byte)t->base;
-+ m--;
-+ break;
-+ }
-+ }
-+ else if (e & 32)
-+ {
-+ Tracevv((stderr, "inflate: * end of block\n"));
-+ UNGRAB
-+ UPDATE
-+ return Z_STREAM_END;
-+ }
-+ else
-+ {
-+ z->msg = "invalid literal/length code";
-+ UNGRAB
-+ UPDATE
-+ return Z_DATA_ERROR;
-+ }
-+ } while (1);
-+ } while (m >= 258 && n >= 10);
-+
-+ /* not enough input or output--restore pointers and return */
-+ UNGRAB
-+ UPDATE
-+ return Z_OK;
-+}
-+
-+
-+/*+++++*/
-+/* zutil.c -- target dependent utility functions for the compression library
-+ * Copyright (C) 1995 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */
-+
-+char *zlib_version = ZLIB_VERSION;
-+
-+char *z_errmsg[] = {
-+"stream end", /* Z_STREAM_END 1 */
-+"", /* Z_OK 0 */
-+"file error", /* Z_ERRNO (-1) */
-+"stream error", /* Z_STREAM_ERROR (-2) */
-+"data error", /* Z_DATA_ERROR (-3) */
-+"insufficient memory", /* Z_MEM_ERROR (-4) */
-+"buffer error", /* Z_BUF_ERROR (-5) */
-+""};
-+
-+
-+/*+++++*/
-+/* adler32.c -- compute the Adler-32 checksum of a data stream
-+ * Copyright (C) 1995 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */
-+
-+#define BASE 65521L /* largest prime smaller than 65536 */
-+#define NMAX 5552
-+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-+
-+#define DO1(buf) {s1 += *buf++; s2 += s1;}
-+#define DO2(buf) DO1(buf); DO1(buf);
-+#define DO4(buf) DO2(buf); DO2(buf);
-+#define DO8(buf) DO4(buf); DO4(buf);
-+#define DO16(buf) DO8(buf); DO8(buf);
-+
-+/* ========================================================================= */
-+uLong adler32(adler, buf, len)
-+ uLong adler;
-+ Bytef *buf;
-+ uInt len;
-+{
-+ unsigned long s1 = adler & 0xffff;
-+ unsigned long s2 = (adler >> 16) & 0xffff;
-+ int k;
-+
-+ if (buf == Z_NULL) return 1L;
-+
-+ while (len > 0) {
-+ k = len < NMAX ? len : NMAX;
-+ len -= k;
-+ while (k >= 16) {
-+ DO16(buf);
-+ k -= 16;
-+ }
-+ if (k != 0) do {
-+ DO1(buf);
-+ } while (--k);
-+ s1 %= BASE;
-+ s2 %= BASE;
-+ }
-+ return (s2 << 16) | s1;
-+}
-diff -Naru linux/arch/mips/zboot/Makefile linux.spi/arch/mips/zboot/Makefile
---- linux/arch/mips/zboot/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/Makefile 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,84 @@
-+#
-+# arch/mips/zboot/Makefile
-+#
-+# This file is subject to the terms and conditions of the GNU General Public
-+# License. See the file "COPYING" in the main directory of this archive
-+# for more details.
-+
-+# Adapted for MIPS Pete Popov, Dan Malek
-+#
-+# Copyright (C) 1994 by Linus Torvalds
-+# Adapted for PowerPC by Gary Thomas
-+# modified by Cort (cort@cs.nmt.edu)
-+#
-+
-+.c.s:
-+ $(CC) $(CFLAGS) -S -o $*.s $<
-+.s.o:
-+ $(AS) -o $*.o $<
-+.c.o:
-+ $(CC) $(CFLAGS) -c -o $*.o $<
-+.S.s:
-+ $(CPP) $(AFLAGS) -o $*.o $<
-+.S.o:
-+ $(CC) $(AFLAGS) -c -o $*.o $<
-+
-+GZIP_FLAGS = -v9f
-+
-+CFLAGS += -D__BOOTER__ -I$(TOPDIR)/arch/$(ARCH)/zboot/include
-+AFLAGS += -D__BOOTER__
-+
-+BOOT_TARGETS = zImage zImage.initrd zImage.flash zImage.initrd.flash
-+
-+lib/zlib.a:
-+ $(MAKE) -C lib
-+
-+images/vmlinux.gz: $(TOPDIR)/vmlinux
-+ $(MAKE) -C images vmlinux.gz
-+
-+$(BOOT_TARGETS): lib/zlib.a images/vmlinux.gz
-+ifdef CONFIG_MIPS_PB1000
-+ $(MAKE) -C pb1xxx $@
-+endif
-+ifdef CONFIG_MIPS_PB1500
-+ $(MAKE) -C pb1xxx $@
-+endif
-+ifdef CONFIG_MIPS_PB1100
-+ $(MAKE) -C pb1xxx $@
-+endif
-+ifdef CONFIG_MIPS_PB1550
-+ $(MAKE) -C pb1xxx $@
-+endif
-+ifdef CONFIG_MIPS_DB1000
-+ $(MAKE) -C pb1xxx $@
-+endif
-+ifdef CONFIG_MIPS_DB1100
-+ $(MAKE) -C pb1xxx $@
-+endif
-+ifdef CONFIG_MIPS_DB1500
-+ $(MAKE) -C pb1xxx $@
-+endif
-+ifdef CONFIG_MIPS_BOSPORUS
-+ $(MAKE) -C pb1xxx $@
-+endif
-+ifdef CONFIG_MIPS_MIRAGE
-+ $(MAKE) -C pb1xxx $@
-+endif
-+ifdef CONFIG_MIPS_MTX1
-+ $(MAKE) -C pb1xxx $@
-+endif
-+ifdef CONFIG_COGENT_CSB250
-+ $(MAKE) -C csb250 $@
-+endif
-+ifdef CONFIG_MIPS_XXS1500
-+BOOT_DIR = xxs1500
-+endif
-+
-+# Do the dirs
-+clean:
-+ $(MAKE) -C common clean
-+ $(MAKE) -C images clean
-+ $(MAKE) -C pb1xxx clean
-+ $(MAKE) -C xxs1500 clean
-+
-+include $(TOPDIR)/Rules.make
-diff -Naru linux/arch/mips/zboot/pb1xxx/head.S linux.spi/arch/mips/zboot/pb1xxx/head.S
---- linux/arch/mips/zboot/pb1xxx/head.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/pb1xxx/head.S 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,149 @@
-+/*
-+ * arch/mips/kernel/head.S
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file "COPYING" in the main directory of this archive
-+ * for more details.
-+ *
-+ * Copyright (C) 1994, 1995 Waldorf Electronics
-+ * Written by Ralf Baechle and Andreas Busse
-+ * Copyright (C) 1995 - 1999 Ralf Baechle
-+ * Copyright (C) 1996 Paul M. Antoine
-+ * Modified for DECStation and hence R3000 support by Paul M. Antoine
-+ * Further modifications by David S. Miller and Harald Koerfgen
-+ * Copyright (C) 1999 Silicon Graphics, Inc.
-+ *
-+ * Head.S contains the MIPS exception handler and startup code.
-+ *
-+ **************************************************************************
-+ * 9 Nov, 2000.
-+ * Added Cache Error exception handler and SBDDP EJTAG debug exception.
-+ *
-+ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
-+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
-+ **************************************************************************
-+ */
-+#include <linux/config.h>
-+#include <linux/threads.h>
-+
-+#include <asm/asm.h>
-+#include <asm/cacheops.h>
-+#include <asm/mipsregs.h>
-+#include <asm/offset.h>
-+#include <asm/cachectl.h>
-+#include <asm/regdef.h>
-+
-+#define IndexInvalidate_I 0x00
-+#define IndexWriteBack_D 0x01
-+
-+ .set noreorder
-+ .cprestore
-+ LEAF(start)
-+start:
-+ bal locate
-+ nop
-+locate:
-+ subu s8, ra, 8 /* Where we were loaded */
-+ la sp, (.stack + 8192)
-+
-+ move s0, a0 /* Save boot rom start args */
-+ move s1, a1
-+ move s2, a2
-+ move s3, a3
-+
-+ la a0, start /* Where we were linked to run */
-+
-+ move a1, s8
-+ la a2, _edata
-+ subu t1, a2, a0
-+ srl t1, t1, 2
-+
-+ /* copy text section */
-+ li t0, 0
-+1: lw v0, 0(a1)
-+ nop
-+ sw v0, 0(a0)
-+ xor t0, t0, v0
-+ addu a0, 4
-+ bne a2, a0, 1b
-+ addu a1, 4
-+
-+ /* Clear BSS */
-+ la a0, _edata
-+ la a2, _end
-+2: sw zero, 0(a0)
-+ bne a2, a0, 2b
-+ addu a0, 4
-+
-+ /* push the D-Cache and invalidate I-Cache */
-+ li k0, 0x80000000 # start address
-+ li k1, 0x80004000 # end address (16KB I-Cache)
-+ subu k1, 128
-+
-+1:
-+ .set mips3
-+ cache IndexWriteBack_D, 0(k0)
-+ cache IndexWriteBack_D, 32(k0)
-+ cache IndexWriteBack_D, 64(k0)
-+ cache IndexWriteBack_D, 96(k0)
-+ cache IndexInvalidate_I, 0(k0)
-+ cache IndexInvalidate_I, 32(k0)
-+ cache IndexInvalidate_I, 64(k0)
-+ cache IndexInvalidate_I, 96(k0)
-+ .set mips0
-+
-+ bne k0, k1, 1b
-+ addu k0, k0, 128
-+ /* done */
-+
-+ move a0, s8 /* load address */
-+ move a1, t1 /* length in words */
-+ move a2, t0 /* checksum */
-+ move a3, sp
-+
-+ la ra, 1f
-+ la k0, decompress_kernel
-+ jr k0
-+ nop
-+1:
-+
-+ move a0, s0
-+ move a1, s1
-+ move a2, s2
-+ move a3, s3
-+ li k0, KERNEL_ENTRY
-+ jr k0
-+ nop
-+3:
-+ b 3b
-+ END(start)
-+
-+ LEAF(udelay)
-+udelay:
-+ END(udelay)
-+
-+
-+ LEAF(FlushCache)
-+ li k0, 0x80000000 # start address
-+ li k1, 0x80004000 # end address (16KB I-Cache)
-+ subu k1, 128
-+
-+1:
-+ .set mips3
-+ cache IndexWriteBack_D, 0(k0)
-+ cache IndexWriteBack_D, 32(k0)
-+ cache IndexWriteBack_D, 64(k0)
-+ cache IndexWriteBack_D, 96(k0)
-+ cache IndexInvalidate_I, 0(k0)
-+ cache IndexInvalidate_I, 32(k0)
-+ cache IndexInvalidate_I, 64(k0)
-+ cache IndexInvalidate_I, 96(k0)
-+ .set mips0
-+
-+ bne k0, k1, 1b
-+ addu k0, k0, 128
-+ jr ra
-+ nop
-+ END(FlushCache)
-+
-+ .comm .stack,4096*2,4
-diff -Naru linux/arch/mips/zboot/pb1xxx/Makefile linux.spi/arch/mips/zboot/pb1xxx/Makefile
---- linux/arch/mips/zboot/pb1xxx/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/pb1xxx/Makefile 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,135 @@
-+# arch/mips/zboot/pb1xxx/Makefile
-+#
-+# Makefile for Alchemy Semiconductor Pb1[015]00 boards.
-+# All of the boot loader code was derived from the ppc
-+# boot code.
-+#
-+# Copyright 2001,2002 MontaVista Software Inc.
-+#
-+# Author: Mark A. Greer
-+# mgreer@mvista.com
-+# Ported and modified for mips support by
-+# Pete Popov <ppopov@mvista.com>
-+#
-+# 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.
-+
-+.c.s:
-+ $(CC) $(CFLAGS) -S -o $*.s $<
-+.s.o:
-+ $(AS) -o $*.o $<
-+.c.o:
-+ $(CC) $(CFLAGS) -D__BOOTER__ -c -o $*.o $<
-+.S.s:
-+ $(CPP) $(AFLAGS) -o $*.o $<
-+.S.o:
-+ $(CC) $(AFLAGS) -c -o $*.o $<
-+
-+#########################################################################
-+# START BOARD SPECIFIC VARIABLES
-+ifdef CONFIG_MIPS_PB1000
-+BNAME=pb1000
-+endif
-+
-+ifdef CONFIG_MIPS_PB1100
-+BNAME=pb1100
-+endif
-+
-+ifdef CONFIG_MIPS_PB1500
-+BNAME=pb1500
-+endif
-+
-+ifdef CONFIG_MIPS_PB1550
-+BNAME=pb1550
-+endif
-+
-+ifdef CONFIG_MIPS_DB1000
-+BNAME=db1000
-+endif
-+
-+ifdef CONFIG_MIPS_DB1100
-+BNAME=db1100
-+endif
-+
-+ifdef CONFIG_MIPS_DB1500
-+BNAME=db1500
-+endif
-+
-+ifdef CONFIG_MIPS_BOSPORUS
-+BNAME=bosporus
-+endif
-+
-+ifdef CONFIG_MIPS_MIRAGE
-+BNAME=mirage
-+endif
-+
-+ifdef CONFIG_MIPS_MTX1
-+BNAME=mtx-1
-+endif
-+
-+# These two variables control where the zImage is stored
-+# in flash and loaded in memory. It only controls how the srec
-+# file is generated, the code is the same.
-+RAM_RUN_ADDR = 0x81000000
-+FLASH_LOAD_ADDR = 0xBFD00000
-+
-+# These two variables specify the free ram region
-+# that can be used for temporary malloc area
-+AVAIL_RAM_START=0x80400000
-+AVAIL_RAM_END=0x80800000
-+
-+# This one must match the LOADADDR in arch/mips/Makefile!
-+LOADADDR=0x80100000
-+# END BOARD SPECIFIC VARIABLES
-+#########################################################################
-+
-+OBJECTS := head.o ../common/misc-common.o ../common/misc-simple.o \
-+ ../common/au1k_uart.o ../common/string.o ../common/ctype.o
-+LIBS := ../lib/zlib.a
-+
-+ENTRY := ../utils/entry
-+OFFSET := ../utils/offset
-+SIZE := ../utils/size
-+
-+LD_ARGS := -T ../ld.script -Ttext $(RAM_RUN_ADDR) -Bstatic
-+OBJCOPY_ARGS = -O elf32-tradlittlemips
-+
-+all: zImage
-+
-+clean:
-+ rm -rf *.o vmlinux* zvmlinux.* ../images/*.srec
-+
-+head.o: head.S $(TOPDIR)/vmlinux
-+ $(CC) $(AFLAGS) \
-+ -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) $(TOPDIR)/vmlinux ) \
-+ -c -o $*.o $<
-+
-+../common/misc-simple.o:
-+ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \
-+ -DAVAIL_RAM_START=$(AVAIL_RAM_START) \
-+ -DAVAIL_RAM_END=$(AVAIL_RAM_END) \
-+ -DLOADADDR=$(LOADADDR) \
-+ -DZIMAGE_SIZE=0 -c -o $@ $*.c
-+
-+zvmlinux: $(OBJECTS) $(LIBS) ../ld.script ../images/vmlinux.gz ../common/dummy.o
-+ $(OBJCOPY) \
-+ --add-section=.image=../images/vmlinux.gz \
-+ --set-section-flags=.image=contents,alloc,load,readonly,data \
-+ ../common/dummy.o image.o
-+ $(LD) $(LD_ARGS) -o $@ $(OBJECTS) image.o $(LIBS)
-+ $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R .comment -R .stab -R .stabstr \
-+ -R .initrd -R .sysmap
-+
-+# Here we manipulate the image in order to get it the necessary
-+# srecord file we need.
-+zImage: zvmlinux
-+ mv zvmlinux ../images/zImage.$(BNAME)
-+ $(OBJCOPY) -O srec ../images/zImage.$(BNAME) ../images/$(BNAME).srec
-+
-+zImage.flash: zImage
-+ $(OBJCOPY) -O srec --adjust-vma 0x3ed00000 \
-+ ../images/zImage.$(BNAME) ../images/$(BNAME).flash.srec
-+
-+include $(TOPDIR)/Rules.make
-diff -Naru linux/arch/mips/zboot/utils/entry linux.spi/arch/mips/zboot/utils/entry
---- linux/arch/mips/zboot/utils/entry 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/utils/entry 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,12 @@
-+#!/bin/sh
-+
-+# grab the kernel_entry address from the vmlinux elf image
-+entry=`$1 $2 | grep kernel_entry`
-+
-+fs=`echo $entry | grep ffffffff` # check toolchain output
-+
-+if [ -n "$fs" ]; then
-+ echo "0x"`$1 $2 | grep kernel_entry | cut -c9- | awk '{print $1}'`
-+else
-+ echo "0x"`$1 $2 | grep kernel_entry | cut -c1- | awk '{print $1}'`
-+fi
-diff -Naru linux/arch/mips/zboot/utils/offset linux.spi/arch/mips/zboot/utils/offset
---- linux/arch/mips/zboot/utils/offset 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/utils/offset 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,3 @@
-+#!/bin/sh
-+
-+echo "0x"`$1 -h $2 | grep $3 | grep -v zvmlinux| awk '{print $6}'`
-diff -Naru linux/arch/mips/zboot/utils/size linux.spi/arch/mips/zboot/utils/size
---- linux/arch/mips/zboot/utils/size 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/utils/size 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,4 @@
-+#!/bin/sh
-+
-+OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux | awk '{print $3}'`
-+echo "0x"$OFFSET
-diff -Naru linux/arch/mips/zboot/xxs1500/head.S linux.spi/arch/mips/zboot/xxs1500/head.S
---- linux/arch/mips/zboot/xxs1500/head.S 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/xxs1500/head.S 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,137 @@
-+/*
-+ * arch/mips/kernel/head.S
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file "COPYING" in the main directory of this archive
-+ * for more details.
-+ *
-+ * Copyright (C) 1994, 1995 Waldorf Electronics
-+ * Written by Ralf Baechle and Andreas Busse
-+ * Copyright (C) 1995 - 1999 Ralf Baechle
-+ * Copyright (C) 1996 Paul M. Antoine
-+ * Modified for DECStation and hence R3000 support by Paul M. Antoine
-+ * Further modifications by David S. Miller and Harald Koerfgen
-+ * Copyright (C) 1999 Silicon Graphics, Inc.
-+ *
-+ * Head.S contains the MIPS exception handler and startup code.
-+ *
-+ **************************************************************************
-+ * 9 Nov, 2000.
-+ * Added Cache Error exception handler and SBDDP EJTAG debug exception.
-+ *
-+ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
-+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
-+ **************************************************************************
-+ */
-+#include <linux/config.h>
-+#include <linux/threads.h>
-+
-+#include <asm/asm.h>
-+#include <asm/cacheops.h>
-+#include <asm/mipsregs.h>
-+#include <asm/offset.h>
-+#include <asm/cachectl.h>
-+#include <asm/regdef.h>
-+
-+#define IndexInvalidate_I 0x00
-+
-+ .set noreorder
-+ .cprestore
-+ LEAF(start)
-+start:
-+
-+locate:
-+ la sp, .stack
-+ move s0, a0
-+ move s1, a1
-+ move s2, a2
-+ move s3, a3
-+
-+ la a0, start
-+
-+ li a1, FLASH_LOAD_ADDR
-+ la a2, _edata
-+ subu t1, a2, a0
-+ srl t1, t1, 2
-+
-+ /* copy text section */
-+ li t0, 0
-+1: lw v0, 0(a1)
-+ nop
-+ sw v0, 0(a0)
-+ xor t0, t0, v0
-+ addu a0, 4
-+ bne a2, a0, 1b
-+ addu a1, 4
-+
-+ /* Clear BSS */
-+ la a0, _edata
-+ la a2, _end
-+2: sw zero, 0(a0)
-+ bne a2, a0, 2b
-+ addu a0, 4
-+
-+ /* flush the I-Cache */
-+ li k0, 0x80000000 # start address
-+ li k1, 0x80004000 # end address (16KB I-Cache)
-+ subu k1, 128
-+
-+1:
-+ .set mips3
-+ cache IndexInvalidate_I, 0(k0)
-+ cache IndexInvalidate_I, 32(k0)
-+ cache IndexInvalidate_I, 64(k0)
-+ cache IndexInvalidate_I, 96(k0)
-+ .set mips0
-+
-+ bne k0, k1, 1b
-+ addu k0, k0, 128
-+ /* done */
-+
-+ li a0, FLASH_LOAD_ADDR /* load address */
-+ move a1, t1 /* length in words */
-+ move a2, t0 /* checksum */
-+ move a3, sp
-+
-+ la ra, 1f
-+ la k0, decompress_kernel
-+ jr k0
-+ nop
-+1:
-+
-+ move a0, s0
-+ move a1, s1
-+ move a2, s2
-+ move a3, s3
-+ li k0, KERNEL_ENTRY
-+ jr k0
-+ nop
-+3:
-+ b 3b
-+ END(start)
-+
-+ LEAF(udelay)
-+udelay:
-+ END(udelay)
-+
-+
-+ LEAF(FlushCache)
-+ li k0, 0x80000000 # start address
-+ li k1, 0x80004000 # end address (16KB I-Cache)
-+ subu k1, 128
-+
-+1:
-+ .set mips3
-+ cache IndexInvalidate_I, 0(k0)
-+ cache IndexInvalidate_I, 32(k0)
-+ cache IndexInvalidate_I, 64(k0)
-+ cache IndexInvalidate_I, 96(k0)
-+ .set mips0
-+
-+ bne k0, k1, 1b
-+ addu k0, k0, 128
-+ jr ra
-+ nop
-+ END(FlushCache)
-+
-+ .comm .stack,4096*2,4
-diff -Naru linux/arch/mips/zboot/xxs1500/ld.script linux.spi/arch/mips/zboot/xxs1500/ld.script
---- linux/arch/mips/zboot/xxs1500/ld.script 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/xxs1500/ld.script 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,147 @@
-+OUTPUT_ARCH(mips)
-+ENTRY(start)
-+SECTIONS
-+{
-+ /* Read-only sections, merged into text segment: */
-+ /* . = 0x81000000; */
-+ .init : { *(.init) } =0
-+ .text :
-+ {
-+ _ftext = . ;
-+ *(.text)
-+ *(.rodata)
-+ *(.rodata1)
-+ /* .gnu.warning sections are handled specially by elf32.em. */
-+ *(.gnu.warning)
-+ } =0
-+ .kstrtab : { *(.kstrtab) }
-+
-+ . = ALIGN(16); /* Exception table */
-+ __start___ex_table = .;
-+ __ex_table : { *(__ex_table) }
-+ __stop___ex_table = .;
-+
-+ __start___dbe_table = .; /* Exception table for data bus errors */
-+ __dbe_table : { *(__dbe_table) }
-+ __stop___dbe_table = .;
-+
-+ __start___ksymtab = .; /* Kernel symbol table */
-+ __ksymtab : { *(__ksymtab) }
-+ __stop___ksymtab = .;
-+
-+ _etext = .;
-+
-+ . = ALIGN(8192);
-+ .data.init_task : { *(.data.init_task) }
-+
-+ /* Startup code */
-+ . = ALIGN(4096);
-+ __init_begin = .;
-+ .text.init : { *(.text.init) }
-+ .data.init : { *(.data.init) }
-+ . = ALIGN(16);
-+ __setup_start = .;
-+ .setup.init : { *(.setup.init) }
-+ __setup_end = .;
-+ __initcall_start = .;
-+ .initcall.init : { *(.initcall.init) }
-+ __initcall_end = .;
-+ . = ALIGN(4096); /* Align double page for init_task_union */
-+ __init_end = .;
-+
-+ . = ALIGN(4096);
-+ .data.page_aligned : { *(.data.idt) }
-+
-+ . = ALIGN(32);
-+ .data.cacheline_aligned : { *(.data.cacheline_aligned) }
-+
-+ .fini : { *(.fini) } =0
-+ .reginfo : { *(.reginfo) }
-+ /* Adjust the address for the data segment. We want to adjust up to
-+ the same address within the page on the next page up. It would
-+ be more correct to do this:
-+ . = .;
-+ The current expression does not correctly handle the case of a
-+ text segment ending precisely at the end of a page; it causes the
-+ data segment to skip a page. The above expression does not have
-+ this problem, but it will currently (2/95) cause BFD to allocate
-+ a single segment, combining both text and data, for this case.
-+ This will prevent the text segment from being shared among
-+ multiple executions of the program; I think that is more
-+ important than losing a page of the virtual address space (note
-+ that no actual memory is lost; the page which is skipped can not
-+ be referenced). */
-+ . = .;
-+ .data :
-+ {
-+ _fdata = . ;
-+ *(.data)
-+
-+ /* Align the initial ramdisk image (INITRD) on page boundaries. */
-+ . = ALIGN(4096);
-+ __rd_start = .;
-+ *(.initrd)
-+ __rd_end = .;
-+ . = ALIGN(4096);
-+
-+ CONSTRUCTORS
-+ }
-+ .data1 : { *(.data1) }
-+ _gp = . + 0x8000;
-+ .lit8 : { *(.lit8) }
-+ .lit4 : { *(.lit4) }
-+ .ctors : { *(.ctors) }
-+ .dtors : { *(.dtors) }
-+ .got : { *(.got.plt) *(.got) }
-+ .dynamic : { *(.dynamic) }
-+ /* We want the small data sections together, so single-instruction offsets
-+ can access them all, and initialized data all before uninitialized, so
-+ we can shorten the on-disk segment size. */
-+ .sdata : { *(.sdata) }
-+ . = ALIGN(4);
-+ _edata = .;
-+ PROVIDE (edata = .);
-+
-+ __bss_start = .;
-+ _fbss = .;
-+ .sbss : { *(.sbss) *(.scommon) }
-+ .bss :
-+ {
-+ *(.dynbss)
-+ *(.bss)
-+ *(COMMON)
-+ . = ALIGN(4);
-+ _end = . ;
-+ PROVIDE (end = .);
-+ }
-+
-+ /* Sections to be discarded */
-+ /DISCARD/ :
-+ {
-+ *(.text.exit)
-+ *(.data.exit)
-+ *(.exitcall.exit)
-+ }
-+
-+ /* This is the MIPS specific mdebug section. */
-+ .mdebug : { *(.mdebug) }
-+ /* These are needed for ELF backends which have not yet been
-+ converted to the new style linker. */
-+ .stab 0 : { *(.stab) }
-+ .stabstr 0 : { *(.stabstr) }
-+ /* DWARF debug sections.
-+ Symbols in the .debug DWARF section are relative to the beginning of the
-+ section so we begin .debug at 0. It's not clear yet what needs to happen
-+ for the others. */
-+ .debug 0 : { *(.debug) }
-+ .debug_srcinfo 0 : { *(.debug_srcinfo) }
-+ .debug_aranges 0 : { *(.debug_aranges) }
-+ .debug_pubnames 0 : { *(.debug_pubnames) }
-+ .debug_sfnames 0 : { *(.debug_sfnames) }
-+ .line 0 : { *(.line) }
-+ /* These must appear regardless of . */
-+ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
-+ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
-+ .comment : { *(.comment) }
-+ .note : { *(.note) }
-+}
-diff -Naru linux/arch/mips/zboot/xxs1500/Makefile linux.spi/arch/mips/zboot/xxs1500/Makefile
---- linux/arch/mips/zboot/xxs1500/Makefile 1969-12-31 19:00:00.000000000 -0500
-+++ linux.spi/arch/mips/zboot/xxs1500/Makefile 2004-05-11 23:19:24.000000000 -0400
-@@ -0,0 +1,123 @@
-+# arch/mips/compressed/alchemy/Makefile
-+#
-+# Makefile for Alchemy Semiconductor Pb1[015]00 boards.
-+# All of the boot loader code was derived from the ppc
-+# boot code.
-+#
-+# Copyright 2001,2002 MontaVista Software Inc.
-+#
-+# Author: Mark A. Greer
-+# mgreer@mvista.com
-+# Ported and modified for mips support by
-+# Pete Popov <ppopov@mvista.com>
-+#
-+# 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.
-+
-+.c.s:
-+ $(CC) $(CFLAGS) -S -o $*.s $<
-+.s.o:
-+ $(AS) -o $*.o $<
-+.c.o:
-+ $(CC) $(CFLAGS) -D__BOOTER__ -c -o $*.o $<
-+.S.s:
-+ $(CPP) $(AFLAGS) -o $*.o $<
-+.S.o:
-+ $(CC) $(AFLAGS) -c -o $*.o $<
-+
-+#########################################################################
-+# START BOARD SPECIFIC VARIABLES
-+BNAME=xxs1500
-+
-+
-+# These two variables control where the zImage is stored
-+# in flash and loaded in memory. If you change either one,
-+# be sure to make the appropriate change to the zImage
-+# rule.
-+RAM_LOAD_ADDR = 0x81000000
-+FLASH_LOAD_ADDR = 0xBF000000
-+
-+# These two variables specify the free ram region
-+# that can be used for temporary malloc area
-+AVAIL_RAM_START=0x80400000
-+AVAIL_RAM_END=0x80800000
-+
-+# This one must match the LOADADDR in arch/mips/Makefile!
-+LOADADDR=0x80100000
-+# END BOARD SPECIFIC VARIABLES
-+#########################################################################
-+
-+ZLINKFLAGS = -T ld.script -Ttext $(RAM_LOAD_ADDR)
-+
-+OBJECTS := head.o ../common/misc-common.o ../common/misc-simple.o \
-+ ../common/au1k_uart.o ../common/string.o ../common/ctype.o
-+LIBS := ../lib/zlib.a
-+
-+ENTRY := ../utils/entry
-+OFFSET := ../utils/offset
-+SIZE := ../utils/size
-+
-+all: zImage
-+
-+clean:
-+ rm -rf *.o vmlinux* zvmlinux.*
-+
-+head.o: head.S $(TOPDIR)/vmlinux
-+ $(CC) -DFLASH_LOAD_ADDR=$(FLASH_LOAD_ADDR) $(AFLAGS) \
-+ -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) $(TOPDIR)/vmlinux ) \
-+ -c -o $*.o $<
-+
-+../common/misc-simple.o:
-+ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \
-+ -DAVAIL_RAM_START=$(AVAIL_RAM_START) \
-+ -DAVAIL_RAM_END=$(AVAIL_RAM_END) \
-+ -DLOADADDR=$(LOADADDR) \
-+ -DZIMAGE_SIZE=0 -c -o $@ $*.c
-+
-+# This is the first pass at building the boot loader image,
-+# without knowing the file offset where the vmlinuz.gz
-+# kernel will end up. We build this image, check the offset,
-+# and then rebuild it with the correct offset and size
-+# passed to mips-simple.c
-+zvmlinux.no: $(OBJECTS) $(LIBS) ../images/vmlinux.gz
-+ $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS)
-+ $(OBJCOPY) -R .comment \
-+ --add-section=image=../images/vmlinux.gz \
-+ $@.tmp $@
-+ # rm -f $@.tmp
-+
-+
-+# This is the final image we build, now that we know what
-+# the vmlinuz.gz offset is.
-+zvmlinux: $(OBJECTS) $(LIBS) ../images/vmlinux.gz zvmlinux.no
-+ $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \
-+ -DZIMAGE_OFFSET=$(shell sh $(OFFSET) $(OBJDUMP) $@.no image) \
-+ -DZIMAGE_SIZE=$(shell sh $(SIZE) $(OBJDUMP) $@.no image) \
-+ -D__BOOTER__ \
-+ -DAVAIL_RAM_START=$(AVAIL_RAM_START) \
-+ -DAVAIL_RAM_END=$(AVAIL_RAM_END) \
-+ -DLOADADDR=$(LOADADDR) \
-+ -c -o ../common/misc-simple.o ../common/misc-simple.c
-+ $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS)
-+ $(OBJCOPY) -R .comment \
-+ --add-section=image=../images/vmlinux.gz \
-+ $@.tmp $@
-+ $(OBJCOPY) --adjust-section-vma=image+$(RAM_LOAD_ADDR) $@
-+ $(OBJCOPY) --adjust-section-vma=image+$(shell sh $(OFFSET) \
-+ $(OBJDUMP) $@.no image ) $@
-+ # rm -f $@.tmp
-+ # rm -f $@.no
-+
-+
-+# Here we manipulate the image in order to get it the necessary
-+# srecord file we need.
-+zImage: zvmlinux
-+ mv zvmlinux ../images/$@.$(BNAME)
-+ $(OBJCOPY) --set-section-flags=image=alloc,load,code ../images/$@.$(BNAME)
-+ $(OBJCOPY) -O srec --adjust-vma 0x3e000000 \
-+ ../images/$@.$(BNAME) ../images/$@.$(BNAME).srec
-+ # rm ../images/vmlinux.gz
-+
-+include $(TOPDIR)/Rules.make
diff --git a/linux/linux-mtx-1-2.4.27/07-zboot-zimage-flash-bin.diff b/linux/linux-mtx-1-2.4.27/07-zboot-zimage-flash-bin.diff
deleted file mode 100644
index dca79a3000..0000000000
--- a/linux/linux-mtx-1-2.4.27/07-zboot-zimage-flash-bin.diff
+++ /dev/null
@@ -1,11 +0,0 @@
-diff -Nurb oe/tmp/work/linux-mtx-1-2.4.27-r0/linux/arch/mips/zboot/pb1xxx/Makefile linux.m/arch/mips/zboot/pb1xxx/Makefile
---- oe/tmp/work/linux-mtx-1-2.4.27-r0/linux/arch/mips/zboot/pb1xxx/Makefile 2004-10-13 21:08:49.840408328 +0200
-+++ linux.m/arch/mips/zboot/pb1xxx/Makefile 2004-10-13 21:08:29.736464592 +0200
-@@ -131,5 +131,7 @@
- zImage.flash: zImage
- $(OBJCOPY) -O srec --adjust-vma 0x3ed00000 \
- ../images/zImage.$(BNAME) ../images/$(BNAME).flash.srec
-+ $(OBJCOPY) -O binary --adjust-vma 0x3ed00000 \
-+ ../images/zImage.$(BNAME) ../images/$(BNAME).flash.bin
-
- include $(TOPDIR)/Rules.make
diff --git a/linux/linux-mtx-1-2.4.27/08-usb-nonpci-2.4.24.patch b/linux/linux-mtx-1-2.4.27/08-usb-nonpci-2.4.24.patch
deleted file mode 100644
index ca093e1a67..0000000000
--- a/linux/linux-mtx-1-2.4.27/08-usb-nonpci-2.4.24.patch
+++ /dev/null
@@ -1,3185 +0,0 @@
-diff -Nurb linux-mips-2.4.27/drivers/usb/host/Config.in linux/drivers/usb/host/Config.in
---- linux-mips-2.4.27/drivers/usb/host/Config.in 2003-11-17 02:07:42.000000000 +0100
-+++ linux/drivers/usb/host/Config.in 2004-11-23 11:24:10.599627448 +0100
-@@ -17,3 +17,4 @@
- dep_tristate ' SL811HS Alternate (x86, StrongARM, isosynchronous mode)' CONFIG_USB_SL811HS_ALT $CONFIG_USB $CONFIG_EXPERIMENTAL
- dep_tristate ' SL811HS (x86, StrongARM) support, old driver' CONFIG_USB_SL811HS $CONFIG_USB $CONFIG_EXPERIMENTAL
- fi
-+dep_tristate ' Non-PCI OHCI support' CONFIG_USB_NON_PCI_OHCI $CONFIG_USB_OHCI
-diff -Nurb linux-mips-2.4.27/drivers/usb/host/usb-ohci.c linux/drivers/usb/host/usb-ohci.c
---- linux-mips-2.4.27/drivers/usb/host/usb-ohci.c 2004-04-16 05:14:18.000000000 +0200
-+++ linux/drivers/usb/host/usb-ohci.c 2004-11-23 11:24:10.602626992 +0100
-@@ -2564,6 +2564,7 @@
- hc_release_ohci (ohci);
- return ret;
- }
-+#ifndef CONFIG_USB_NON_PCI_OHCI
- ohci->flags = id->driver_data;
-
- /* Check for NSC87560. We have to look at the bridge (fn1) to identify
-@@ -2582,6 +2583,7 @@
- printk (KERN_INFO __FILE__ ": Using NSC SuperIO setup\n");
- if (ohci->flags & OHCI_QUIRK_AMD756)
- printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n");
-+#endif
-
- if (hc_reset (ohci) < 0) {
- hc_release_ohci (ohci);
-@@ -2627,8 +2629,10 @@
- int temp;
- int i;
-
-+#ifndef CONFIG_USB_NON_PCI_OHCI
- if (ohci->pci_latency)
- pci_write_config_byte (ohci->ohci_dev, PCI_LATENCY_TIMER, ohci->pci_latency);
-+#endif
-
- ohci->disabled = 1;
- ohci->sleeping = 0;
-@@ -2658,6 +2662,7 @@
-
- /*-------------------------------------------------------------------------*/
-
-+#ifndef CONFIG_USB_NON_PCI_OHCI
- /* configured so that an OHCI device is always provided */
- /* always called with process context; sleeping is OK */
-
-@@ -2705,6 +2710,88 @@
- }
- return status;
- }
-+#else /* CONFIG_USB_NON_PCI_OHCI */
-+
-+// Boot options
-+static int ohci_base=0, ohci_len=0;
-+static int ohci_irq=-1;
-+
-+MODULE_PARM(ohci_base, "i");
-+MODULE_PARM(ohci_len, "i");
-+MODULE_PARM(ohci_irq, "i");
-+MODULE_PARM_DESC(ohci_base, "IO Base address of OHCI Oper. registers");
-+MODULE_PARM_DESC(ohci_len, "IO length of OHCI Oper. registers");
-+MODULE_PARM_DESC(ohci_irq, "IRQ for OHCI interrupts");
-+
-+// bogus pci_dev
-+static struct pci_dev bogus_pcidev;
-+
-+static struct pci_driver ohci_pci_driver = {
-+ name: "usb-ohci",
-+};
-+
-+static int __devinit
-+ohci_non_pci_init (void)
-+{
-+ void *mem_base;
-+
-+ if (!ohci_base || !ohci_len || (ohci_irq < 0))
-+ return -ENODEV;
-+
-+ if (!request_mem_region (ohci_base, ohci_len, ohci_pci_driver.name)) {
-+ dbg ("controller already in use");
-+ return -EBUSY;
-+ }
-+
-+ mem_base = ioremap_nocache (ohci_base, ohci_len);
-+ if (!mem_base) {
-+ err("Error mapping OHCI memory");
-+ return -EFAULT;
-+ }
-+
-+ /*
-+ * Fill in the bogus pci_dev. Only those members actually
-+ * dereferenced in this driver are initialized.
-+ */
-+ memset(&bogus_pcidev, 0, sizeof(struct pci_dev));
-+ strcpy(bogus_pcidev.name, "non-PCI OHCI");
-+ strcpy(bogus_pcidev.slot_name, "builtin");
-+ bogus_pcidev.resource[0].name = "OHCI Operational Registers";
-+ bogus_pcidev.resource[0].start = ohci_base;
-+ bogus_pcidev.resource[0].end = ohci_base + ohci_len;
-+ bogus_pcidev.resource[0].flags = 0;
-+ bogus_pcidev.irq = ohci_irq;
-+
-+ return hc_found_ohci (&bogus_pcidev, bogus_pcidev.irq, mem_base, NULL);
-+}
-+
-+#ifndef MODULE
-+
-+static int __init
-+ohci_setup (char* options)
-+{
-+ char* this_opt;
-+
-+ if (!options || !*options)
-+ return 0;
-+
-+ for(this_opt=strtok(options,",");this_opt;this_opt=strtok(NULL,",")) {
-+ if (!strncmp(this_opt, "base:", 5)) {
-+ ohci_base = simple_strtoul(this_opt+5, NULL, 0);
-+ } else if (!strncmp(this_opt, "len:", 4)) {
-+ ohci_len = simple_strtoul(this_opt+4, NULL, 0);
-+ } else if (!strncmp(this_opt, "irq:", 4)) {
-+ ohci_irq = simple_strtoul(this_opt+4, NULL, 0);
-+ }
-+ }
-+ return 0;
-+}
-+
-+__setup("usb_ohci=", ohci_setup);
-+
-+#endif /* !MODULE */
-+
-+#endif /* CONFIG_USB_NON_PCI_OHCI */
-
- /*-------------------------------------------------------------------------*/
-
-@@ -2745,6 +2832,7 @@
- }
-
-
-+#ifndef CONFIG_USB_NON_PCI_OHCI
- #ifdef CONFIG_PM
-
- /*-------------------------------------------------------------------------*/
-@@ -2983,20 +3071,29 @@
- resume: ohci_pci_resume,
- #endif /* PM */
- };
-+#endif /* CONFIG_USB_NON_PCI_OHCI */
-
-
- /*-------------------------------------------------------------------------*/
-
- static int __init ohci_hcd_init (void)
- {
-+#ifndef CONFIG_USB_NON_PCI_OHCI
- return pci_module_init (&ohci_pci_driver);
-+#else
-+ return ohci_non_pci_init();
-+#endif
- }
-
- /*-------------------------------------------------------------------------*/
-
- static void __exit ohci_hcd_cleanup (void)
- {
-+#ifndef CONFIG_USB_NON_PCI_OHCI
- pci_unregister_driver (&ohci_pci_driver);
-+#else
-+ ohci_pci_remove(&bogus_pcidev);
-+#endif
- }
-
- module_init (ohci_hcd_init);
-diff -Nurb linux-mips-2.4.27/drivers/usb/host/usb-ohci.c.orig linux/drivers/usb/host/usb-ohci.c.orig
---- linux-mips-2.4.27/drivers/usb/host/usb-ohci.c.orig 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/usb/host/usb-ohci.c.orig 2004-11-23 11:21:54.984244120 +0100
-@@ -0,0 +1,3008 @@
-+/*
-+ * URB OHCI HCD (Host Controller Driver) for USB.
-+ *
-+ * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
-+ * (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net>
-+ *
-+ * [ Initialisation is based on Linus' ]
-+ * [ uhci code and gregs ohci fragments ]
-+ * [ (C) Copyright 1999 Linus Torvalds ]
-+ * [ (C) Copyright 1999 Gregory P. Smith]
-+ *
-+ *
-+ * History:
-+ *
-+ * 2002/10/22 OHCI_USB_OPER for ALi lockup in IBM i1200 (ALEX <thchou@ali>)
-+ * 2002/03/08 interrupt unlink fix (Matt Hughes), better cleanup on
-+ * load failure (Matthew Frederickson)
-+ * 2002/01/20 async unlink fixes: return -EINPROGRESS (per spec) and
-+ * make interrupt unlink-in-completion work (db)
-+ * 2001/09/19 USB_ZERO_PACKET support (Jean Tourrilhes)
-+ * 2001/07/17 power management and pmac cleanup (Benjamin Herrenschmidt)
-+ * 2001/03/24 td/ed hashing to remove bus_to_virt (Steve Longerbeam);
-+ pci_map_single (db)
-+ * 2001/03/21 td and dev/ed allocation uses new pci_pool API (db)
-+ * 2001/03/07 hcca allocation uses pci_alloc_consistent (Steve Longerbeam)
-+ *
-+ * 2000/09/26 fixed races in removing the private portion of the urb
-+ * 2000/09/07 disable bulk and control lists when unlinking the last
-+ * endpoint descriptor in order to avoid unrecoverable errors on
-+ * the Lucent chips. (rwc@sgi)
-+ * 2000/08/29 use bandwidth claiming hooks (thanks Randy!), fix some
-+ * urb unlink probs, indentation fixes
-+ * 2000/08/11 various oops fixes mostly affecting iso and cleanup from
-+ * device unplugs.
-+ * 2000/06/28 use PCI hotplug framework, for better power management
-+ * and for Cardbus support (David Brownell)
-+ * 2000/earlier: fixes for NEC/Lucent chips; suspend/resume handling
-+ * when the controller loses power; handle UE; cleanup; ...
-+ *
-+ * v5.2 1999/12/07 URB 3rd preview,
-+ * v5.1 1999/11/30 URB 2nd preview, cpia, (usb-scsi)
-+ * v5.0 1999/11/22 URB Technical preview, Paul Mackerras powerbook susp/resume
-+ * i386: HUB, Keyboard, Mouse, Printer
-+ *
-+ * v4.3 1999/10/27 multiple HCs, bulk_request
-+ * v4.2 1999/09/05 ISO API alpha, new dev alloc, neg Error-codes
-+ * v4.1 1999/08/27 Randy Dunlap's - ISO API first impl.
-+ * v4.0 1999/08/18
-+ * v3.0 1999/06/25
-+ * v2.1 1999/05/09 code clean up
-+ * v2.0 1999/05/04
-+ * v1.0 1999/04/27 initial release
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/ioport.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/smp_lock.h>
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+#include <linux/timer.h>
-+#include <linux/list.h>
-+#include <linux/interrupt.h> /* for in_interrupt() */
-+#undef DEBUG
-+#include <linux/usb.h>
-+
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/system.h>
-+#include <asm/unaligned.h>
-+
-+#define OHCI_USE_NPS // force NoPowerSwitching mode
-+// #define OHCI_VERBOSE_DEBUG /* not always helpful */
-+
-+#include "usb-ohci.h"
-+
-+#include "../hcd.h"
-+
-+#ifdef CONFIG_PMAC_PBOOK
-+#include <asm/machdep.h>
-+#include <asm/pmac_feature.h>
-+#include <asm/pci-bridge.h>
-+#ifndef CONFIG_PM
-+#define CONFIG_PM
-+#endif
-+#endif
-+
-+
-+/*
-+ * Version Information
-+ */
-+#define DRIVER_VERSION "v5.3"
-+#define DRIVER_AUTHOR "Roman Weissgaerber <weissg@vienna.at>, David Brownell"
-+#define DRIVER_DESC "USB OHCI Host Controller Driver"
-+
-+/* For initializing controller (mask in an HCFS mode too) */
-+#define OHCI_CONTROL_INIT \
-+ (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
-+
-+#define OHCI_UNLINK_TIMEOUT (HZ / 10)
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* AMD-756 (D2 rev) reports corrupt register contents in some cases.
-+ * The erratum (#4) description is incorrect. AMD's workaround waits
-+ * till some bits (mostly reserved) are clear; ok for all revs.
-+ */
-+#define read_roothub(hc, register, mask) ({ \
-+ u32 temp = readl (&hc->regs->roothub.register); \
-+ if (hc->flags & OHCI_QUIRK_AMD756) \
-+ while (temp & mask) \
-+ temp = readl (&hc->regs->roothub.register); \
-+ temp; })
-+
-+static u32 roothub_a (struct ohci *hc)
-+ { return read_roothub (hc, a, 0xfc0fe000); }
-+static inline u32 roothub_b (struct ohci *hc)
-+ { return readl (&hc->regs->roothub.b); }
-+static inline u32 roothub_status (struct ohci *hc)
-+ { return readl (&hc->regs->roothub.status); }
-+static u32 roothub_portstatus (struct ohci *hc, int i)
-+ { return read_roothub (hc, portstatus [i], 0xffe0fce0); }
-+
-+
-+/*-------------------------------------------------------------------------*
-+ * URB support functions
-+ *-------------------------------------------------------------------------*/
-+
-+static void ohci_complete_add(struct ohci *ohci, struct urb *urb)
-+{
-+
-+ if (urb->hcpriv != NULL) {
-+ printk("completing with non-null priv!\n");
-+ return;
-+ }
-+
-+ if (ohci->complete_tail == NULL) {
-+ ohci->complete_head = urb;
-+ ohci->complete_tail = urb;
-+ } else {
-+ ohci->complete_head->hcpriv = urb;
-+ ohci->complete_tail = urb;
-+ }
-+}
-+
-+static inline struct urb *ohci_complete_get(struct ohci *ohci)
-+{
-+ struct urb *urb;
-+
-+ if ((urb = ohci->complete_head) == NULL)
-+ return NULL;
-+ if (urb == ohci->complete_tail) {
-+ ohci->complete_tail = NULL;
-+ ohci->complete_head = NULL;
-+ } else {
-+ ohci->complete_head = urb->hcpriv;
-+ }
-+ urb->hcpriv = NULL;
-+ return urb;
-+}
-+
-+static inline void ohci_complete(struct ohci *ohci)
-+{
-+ struct urb *urb;
-+
-+ spin_lock(&ohci->ohci_lock);
-+ while ((urb = ohci_complete_get(ohci)) != NULL) {
-+ spin_unlock(&ohci->ohci_lock);
-+ if (urb->dev) {
-+ usb_dec_dev_use (urb->dev);
-+ urb->dev = NULL;
-+ }
-+ if (urb->complete)
-+ (*urb->complete)(urb);
-+ spin_lock(&ohci->ohci_lock);
-+ }
-+ spin_unlock(&ohci->ohci_lock);
-+}
-+
-+/* free HCD-private data associated with this URB */
-+
-+static void urb_free_priv (struct ohci *hc, urb_priv_t * urb_priv)
-+{
-+ int i;
-+ int last = urb_priv->length - 1;
-+ int len;
-+ int dir;
-+ struct td *td;
-+
-+ if (last >= 0) {
-+
-+ /* ISOC, BULK, INTR data buffer starts at td 0
-+ * CTRL setup starts at td 0 */
-+ td = urb_priv->td [0];
-+
-+ len = td->urb->transfer_buffer_length,
-+ dir = usb_pipeout (td->urb->pipe)
-+ ? PCI_DMA_TODEVICE
-+ : PCI_DMA_FROMDEVICE;
-+
-+ /* unmap CTRL URB setup */
-+ if (usb_pipecontrol (td->urb->pipe)) {
-+ pci_unmap_single (hc->ohci_dev,
-+ td->data_dma, 8, PCI_DMA_TODEVICE);
-+
-+ /* CTRL data buffer starts at td 1 if len > 0 */
-+ if (len && last > 0)
-+ td = urb_priv->td [1];
-+ }
-+
-+ /* unmap data buffer */
-+ if (len && td->data_dma)
-+ pci_unmap_single (hc->ohci_dev, td->data_dma, len, dir);
-+
-+ for (i = 0; i <= last; i++) {
-+ td = urb_priv->td [i];
-+ if (td)
-+ td_free (hc, td);
-+ }
-+ }
-+
-+ kfree (urb_priv);
-+}
-+
-+static void urb_rm_priv_locked (struct urb * urb)
-+{
-+ urb_priv_t * urb_priv = urb->hcpriv;
-+
-+ if (urb_priv) {
-+ urb->hcpriv = NULL;
-+
-+#ifdef DO_TIMEOUTS
-+ if (urb->timeout) {
-+ list_del (&urb->urb_list);
-+ urb->timeout -= jiffies;
-+ }
-+#endif
-+
-+ /* Release int/iso bandwidth */
-+ if (urb->bandwidth) {
-+ switch (usb_pipetype(urb->pipe)) {
-+ case PIPE_INTERRUPT:
-+ usb_release_bandwidth (urb->dev, urb, 0);
-+ break;
-+ case PIPE_ISOCHRONOUS:
-+ usb_release_bandwidth (urb->dev, urb, 1);
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+
-+ urb_free_priv ((struct ohci *)urb->dev->bus->hcpriv, urb_priv);
-+ } else {
-+ if (urb->dev != NULL) {
-+ err ("Non-null dev at rm_priv time");
-+ // urb->dev = NULL;
-+ }
-+ }
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+#ifdef DEBUG
-+static int sohci_get_current_frame_number (struct usb_device * dev);
-+
-+/* debug| print the main components of an URB
-+ * small: 0) header + data packets 1) just header */
-+
-+static void urb_print (struct urb * urb, char * str, int small)
-+{
-+ unsigned int pipe= urb->pipe;
-+
-+ if (!urb->dev || !urb->dev->bus) {
-+ dbg("%s URB: no dev", str);
-+ return;
-+ }
-+
-+#ifndef OHCI_VERBOSE_DEBUG
-+ if (urb->status != 0)
-+#endif
-+ dbg("%s URB:[%4x] dev:%2d,ep:%2d-%c,type:%s,flags:%4x,len:%d/%d,stat:%d(%x)",
-+ str,
-+ sohci_get_current_frame_number (urb->dev),
-+ usb_pipedevice (pipe),
-+ usb_pipeendpoint (pipe),
-+ usb_pipeout (pipe)? 'O': 'I',
-+ usb_pipetype (pipe) < 2? (usb_pipeint (pipe)? "INTR": "ISOC"):
-+ (usb_pipecontrol (pipe)? "CTRL": "BULK"),
-+ urb->transfer_flags,
-+ urb->actual_length,
-+ urb->transfer_buffer_length,
-+ urb->status, urb->status);
-+#ifdef OHCI_VERBOSE_DEBUG
-+ if (!small) {
-+ int i, len;
-+
-+ if (usb_pipecontrol (pipe)) {
-+ printk (KERN_DEBUG __FILE__ ": cmd(8):");
-+ for (i = 0; i < 8 ; i++)
-+ printk (" %02x", ((__u8 *) urb->setup_packet) [i]);
-+ printk ("\n");
-+ }
-+ if (urb->transfer_buffer_length > 0 && urb->transfer_buffer) {
-+ printk (KERN_DEBUG __FILE__ ": data(%d/%d):",
-+ urb->actual_length,
-+ urb->transfer_buffer_length);
-+ len = usb_pipeout (pipe)?
-+ urb->transfer_buffer_length: urb->actual_length;
-+ for (i = 0; i < 16 && i < len; i++)
-+ printk (" %02x", ((__u8 *) urb->transfer_buffer) [i]);
-+ printk ("%s stat:%d\n", i < len? "...": "", urb->status);
-+ }
-+ }
-+#endif
-+}
-+
-+/* just for debugging; prints non-empty branches of the int ed tree inclusive iso eds*/
-+void ep_print_int_eds (ohci_t * ohci, char * str) {
-+ int i, j;
-+ __u32 * ed_p;
-+ for (i= 0; i < 32; i++) {
-+ j = 5;
-+ ed_p = &(ohci->hcca->int_table [i]);
-+ if (*ed_p == 0)
-+ continue;
-+ printk (KERN_DEBUG __FILE__ ": %s branch int %2d(%2x):", str, i, i);
-+ while (*ed_p != 0 && j--) {
-+ ed_t *ed = dma_to_ed (ohci, le32_to_cpup(ed_p));
-+ printk (" ed: %4x;", ed->hwINFO);
-+ ed_p = &ed->hwNextED;
-+ }
-+ printk ("\n");
-+ }
-+}
-+
-+
-+static void ohci_dump_intr_mask (char *label, __u32 mask)
-+{
-+ dbg ("%s: 0x%08x%s%s%s%s%s%s%s%s%s",
-+ label,
-+ mask,
-+ (mask & OHCI_INTR_MIE) ? " MIE" : "",
-+ (mask & OHCI_INTR_OC) ? " OC" : "",
-+ (mask & OHCI_INTR_RHSC) ? " RHSC" : "",
-+ (mask & OHCI_INTR_FNO) ? " FNO" : "",
-+ (mask & OHCI_INTR_UE) ? " UE" : "",
-+ (mask & OHCI_INTR_RD) ? " RD" : "",
-+ (mask & OHCI_INTR_SF) ? " SF" : "",
-+ (mask & OHCI_INTR_WDH) ? " WDH" : "",
-+ (mask & OHCI_INTR_SO) ? " SO" : ""
-+ );
-+}
-+
-+static void maybe_print_eds (char *label, __u32 value)
-+{
-+ if (value)
-+ dbg ("%s %08x", label, value);
-+}
-+
-+static char *hcfs2string (int state)
-+{
-+ switch (state) {
-+ case OHCI_USB_RESET: return "reset";
-+ case OHCI_USB_RESUME: return "resume";
-+ case OHCI_USB_OPER: return "operational";
-+ case OHCI_USB_SUSPEND: return "suspend";
-+ }
-+ return "?";
-+}
-+
-+// dump control and status registers
-+static void ohci_dump_status (ohci_t *controller)
-+{
-+ struct ohci_regs *regs = controller->regs;
-+ __u32 temp;
-+
-+ temp = readl (&regs->revision) & 0xff;
-+ if (temp != 0x10)
-+ dbg ("spec %d.%d", (temp >> 4), (temp & 0x0f));
-+
-+ temp = readl (&regs->control);
-+ dbg ("control: 0x%08x%s%s%s HCFS=%s%s%s%s%s CBSR=%d", temp,
-+ (temp & OHCI_CTRL_RWE) ? " RWE" : "",
-+ (temp & OHCI_CTRL_RWC) ? " RWC" : "",
-+ (temp & OHCI_CTRL_IR) ? " IR" : "",
-+ hcfs2string (temp & OHCI_CTRL_HCFS),
-+ (temp & OHCI_CTRL_BLE) ? " BLE" : "",
-+ (temp & OHCI_CTRL_CLE) ? " CLE" : "",
-+ (temp & OHCI_CTRL_IE) ? " IE" : "",
-+ (temp & OHCI_CTRL_PLE) ? " PLE" : "",
-+ temp & OHCI_CTRL_CBSR
-+ );
-+
-+ temp = readl (&regs->cmdstatus);
-+ dbg ("cmdstatus: 0x%08x SOC=%d%s%s%s%s", temp,
-+ (temp & OHCI_SOC) >> 16,
-+ (temp & OHCI_OCR) ? " OCR" : "",
-+ (temp & OHCI_BLF) ? " BLF" : "",
-+ (temp & OHCI_CLF) ? " CLF" : "",
-+ (temp & OHCI_HCR) ? " HCR" : ""
-+ );
-+
-+ ohci_dump_intr_mask ("intrstatus", readl (&regs->intrstatus));
-+ ohci_dump_intr_mask ("intrenable", readl (&regs->intrenable));
-+ // intrdisable always same as intrenable
-+ // ohci_dump_intr_mask ("intrdisable", readl (&regs->intrdisable));
-+
-+ maybe_print_eds ("ed_periodcurrent", readl (&regs->ed_periodcurrent));
-+
-+ maybe_print_eds ("ed_controlhead", readl (&regs->ed_controlhead));
-+ maybe_print_eds ("ed_controlcurrent", readl (&regs->ed_controlcurrent));
-+
-+ maybe_print_eds ("ed_bulkhead", readl (&regs->ed_bulkhead));
-+ maybe_print_eds ("ed_bulkcurrent", readl (&regs->ed_bulkcurrent));
-+
-+ maybe_print_eds ("donehead", readl (&regs->donehead));
-+}
-+
-+static void ohci_dump_roothub (ohci_t *controller, int verbose)
-+{
-+ __u32 temp, ndp, i;
-+
-+ temp = roothub_a (controller);
-+ if (temp == ~(u32)0)
-+ return;
-+ ndp = (temp & RH_A_NDP);
-+
-+ if (verbose) {
-+ dbg ("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp,
-+ ((temp & RH_A_POTPGT) >> 24) & 0xff,
-+ (temp & RH_A_NOCP) ? " NOCP" : "",
-+ (temp & RH_A_OCPM) ? " OCPM" : "",
-+ (temp & RH_A_DT) ? " DT" : "",
-+ (temp & RH_A_NPS) ? " NPS" : "",
-+ (temp & RH_A_PSM) ? " PSM" : "",
-+ ndp
-+ );
-+ temp = roothub_b (controller);
-+ dbg ("roothub.b: %08x PPCM=%04x DR=%04x",
-+ temp,
-+ (temp & RH_B_PPCM) >> 16,
-+ (temp & RH_B_DR)
-+ );
-+ temp = roothub_status (controller);
-+ dbg ("roothub.status: %08x%s%s%s%s%s%s",
-+ temp,
-+ (temp & RH_HS_CRWE) ? " CRWE" : "",
-+ (temp & RH_HS_OCIC) ? " OCIC" : "",
-+ (temp & RH_HS_LPSC) ? " LPSC" : "",
-+ (temp & RH_HS_DRWE) ? " DRWE" : "",
-+ (temp & RH_HS_OCI) ? " OCI" : "",
-+ (temp & RH_HS_LPS) ? " LPS" : ""
-+ );
-+ }
-+
-+ for (i = 0; i < ndp; i++) {
-+ temp = roothub_portstatus (controller, i);
-+ dbg ("roothub.portstatus [%d] = 0x%08x%s%s%s%s%s%s%s%s%s%s%s%s",
-+ i,
-+ temp,
-+ (temp & RH_PS_PRSC) ? " PRSC" : "",
-+ (temp & RH_PS_OCIC) ? " OCIC" : "",
-+ (temp & RH_PS_PSSC) ? " PSSC" : "",
-+ (temp & RH_PS_PESC) ? " PESC" : "",
-+ (temp & RH_PS_CSC) ? " CSC" : "",
-+
-+ (temp & RH_PS_LSDA) ? " LSDA" : "",
-+ (temp & RH_PS_PPS) ? " PPS" : "",
-+ (temp & RH_PS_PRS) ? " PRS" : "",
-+ (temp & RH_PS_POCI) ? " POCI" : "",
-+ (temp & RH_PS_PSS) ? " PSS" : "",
-+
-+ (temp & RH_PS_PES) ? " PES" : "",
-+ (temp & RH_PS_CCS) ? " CCS" : ""
-+ );
-+ }
-+}
-+
-+static void ohci_dump (ohci_t *controller, int verbose)
-+{
-+ dbg ("OHCI controller usb-%s state", controller->ohci_dev->slot_name);
-+
-+ // dumps some of the state we know about
-+ ohci_dump_status (controller);
-+ if (verbose)
-+ ep_print_int_eds (controller, "hcca");
-+ dbg ("hcca frame #%04x", controller->hcca->frame_no);
-+ ohci_dump_roothub (controller, 1);
-+}
-+
-+
-+#endif
-+
-+/*-------------------------------------------------------------------------*
-+ * Interface functions (URB)
-+ *-------------------------------------------------------------------------*/
-+
-+/* return a request to the completion handler */
-+
-+static int sohci_return_urb (struct ohci *hc, struct urb * urb)
-+{
-+ urb_priv_t * urb_priv = urb->hcpriv;
-+ struct urb * urbt;
-+ int i;
-+
-+ if (!urb_priv)
-+ return -1; /* urb already unlinked */
-+
-+ /* just to be sure */
-+ if (!urb->complete) {
-+ urb_rm_priv_locked (urb);
-+ ohci_complete_add(hc, urb); /* Just usb_dec_dev_use */
-+ return -1;
-+ }
-+
-+#ifdef DEBUG
-+ urb_print (urb, "RET", usb_pipeout (urb->pipe));
-+#endif
-+
-+ switch (usb_pipetype (urb->pipe)) {
-+ case PIPE_INTERRUPT:
-+ pci_unmap_single (hc->ohci_dev,
-+ urb_priv->td [0]->data_dma,
-+ urb->transfer_buffer_length,
-+ usb_pipeout (urb->pipe)
-+ ? PCI_DMA_TODEVICE
-+ : PCI_DMA_FROMDEVICE);
-+ if (urb->interval) {
-+ urb->complete (urb);
-+
-+ /* implicitly requeued */
-+ urb->actual_length = 0;
-+ urb->status = -EINPROGRESS;
-+ td_submit_urb (urb);
-+ } else {
-+ urb_rm_priv_locked (urb);
-+ ohci_complete_add(hc, urb);
-+ }
-+ break;
-+
-+ case PIPE_ISOCHRONOUS:
-+ for (urbt = urb->next; urbt && (urbt != urb); urbt = urbt->next);
-+ if (urbt) { /* send the reply and requeue URB */
-+ pci_unmap_single (hc->ohci_dev,
-+ urb_priv->td [0]->data_dma,
-+ urb->transfer_buffer_length,
-+ usb_pipeout (urb->pipe)
-+ ? PCI_DMA_TODEVICE
-+ : PCI_DMA_FROMDEVICE);
-+ urb->complete (urb);
-+ urb->actual_length = 0;
-+ urb->status = USB_ST_URB_PENDING;
-+ urb->start_frame = urb_priv->ed->last_iso + 1;
-+ if (urb_priv->state != URB_DEL) {
-+ for (i = 0; i < urb->number_of_packets; i++) {
-+ urb->iso_frame_desc[i].actual_length = 0;
-+ urb->iso_frame_desc[i].status = -EXDEV;
-+ }
-+ td_submit_urb (urb);
-+ }
-+
-+ } else { /* unlink URB, call complete */
-+ urb_rm_priv_locked (urb);
-+ ohci_complete_add(hc, urb);
-+ }
-+ break;
-+
-+ case PIPE_BULK:
-+ case PIPE_CONTROL: /* unlink URB, call complete */
-+ urb_rm_priv_locked (urb);
-+ ohci_complete_add(hc, urb);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* get a transfer request */
-+
-+static int sohci_submit_urb (struct urb * urb)
-+{
-+ ohci_t * ohci;
-+ ed_t * ed;
-+ urb_priv_t * urb_priv;
-+ unsigned int pipe = urb->pipe;
-+ int maxps = usb_maxpacket (urb->dev, pipe, usb_pipeout (pipe));
-+ int i, size = 0;
-+ unsigned long flags;
-+ int bustime = 0;
-+ int mem_flags = GFP_ATOMIC;
-+
-+ if (!urb->dev || !urb->dev->bus)
-+ return -ENODEV;
-+
-+ if (urb->hcpriv) /* urb already in use */
-+ return -EINVAL;
-+
-+// if(usb_endpoint_halted (urb->dev, usb_pipeendpoint (pipe), usb_pipeout (pipe)))
-+// return -EPIPE;
-+
-+ usb_inc_dev_use (urb->dev);
-+ ohci = (ohci_t *) urb->dev->bus->hcpriv;
-+
-+#ifdef DEBUG
-+ urb_print (urb, "SUB", usb_pipein (pipe));
-+#endif
-+
-+ /* handle a request to the virtual root hub */
-+ if (usb_pipedevice (pipe) == ohci->rh.devnum)
-+ return rh_submit_urb (urb);
-+
-+ spin_lock_irqsave(&ohci->ohci_lock, flags);
-+
-+ /* when controller's hung, permit only roothub cleanup attempts
-+ * such as powering down ports */
-+ if (ohci->disabled) {
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+ usb_dec_dev_use (urb->dev);
-+ return -ESHUTDOWN;
-+ }
-+
-+ /* every endpoint has a ed, locate and fill it */
-+ if (!(ed = ep_add_ed (urb->dev, pipe, urb->interval, 1, mem_flags))) {
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+ usb_dec_dev_use (urb->dev);
-+ return -ENOMEM;
-+ }
-+
-+ /* for the private part of the URB we need the number of TDs (size) */
-+ switch (usb_pipetype (pipe)) {
-+ case PIPE_BULK: /* one TD for every 4096 Byte */
-+ size = (urb->transfer_buffer_length - 1) / 4096 + 1;
-+
-+ /* If the transfer size is multiple of the pipe mtu,
-+ * we may need an extra TD to create a empty frame
-+ * Jean II */
-+ if ((urb->transfer_flags & USB_ZERO_PACKET) &&
-+ usb_pipeout (pipe) &&
-+ (urb->transfer_buffer_length != 0) &&
-+ ((urb->transfer_buffer_length % maxps) == 0))
-+ size++;
-+ break;
-+ case PIPE_ISOCHRONOUS: /* number of packets from URB */
-+ size = urb->number_of_packets;
-+ if (size <= 0) {
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+ usb_dec_dev_use (urb->dev);
-+ return -EINVAL;
-+ }
-+ for (i = 0; i < urb->number_of_packets; i++) {
-+ urb->iso_frame_desc[i].actual_length = 0;
-+ urb->iso_frame_desc[i].status = -EXDEV;
-+ }
-+ break;
-+ case PIPE_CONTROL: /* 1 TD for setup, 1 for ACK and 1 for every 4096 B */
-+ size = (urb->transfer_buffer_length == 0)? 2:
-+ (urb->transfer_buffer_length - 1) / 4096 + 3;
-+ break;
-+ case PIPE_INTERRUPT: /* one TD */
-+ size = 1;
-+ break;
-+ }
-+
-+ /* allocate the private part of the URB */
-+ urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (td_t *),
-+ GFP_ATOMIC);
-+ if (!urb_priv) {
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+ usb_dec_dev_use (urb->dev);
-+ return -ENOMEM;
-+ }
-+ memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (td_t *));
-+
-+ /* fill the private part of the URB */
-+ urb_priv->length = size;
-+ urb_priv->ed = ed;
-+
-+ /* allocate the TDs (updating hash chains) */
-+ for (i = 0; i < size; i++) {
-+ urb_priv->td[i] = td_alloc (ohci, SLAB_ATOMIC);
-+ if (!urb_priv->td[i]) {
-+ urb_priv->length = i;
-+ urb_free_priv (ohci, urb_priv);
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+ usb_dec_dev_use (urb->dev);
-+ return -ENOMEM;
-+ }
-+ }
-+
-+ if (ed->state == ED_NEW || (ed->state & ED_DEL)) {
-+ urb_free_priv (ohci, urb_priv);
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+ usb_dec_dev_use (urb->dev);
-+ return -EINVAL;
-+ }
-+
-+ /* allocate and claim bandwidth if needed; ISO
-+ * needs start frame index if it was't provided.
-+ */
-+ switch (usb_pipetype (pipe)) {
-+ case PIPE_ISOCHRONOUS:
-+ if (urb->transfer_flags & USB_ISO_ASAP) {
-+ urb->start_frame = ((ed->state == ED_OPER)
-+ ? (ed->last_iso + 1)
-+ : (le16_to_cpu (ohci->hcca->frame_no) + 10)) & 0xffff;
-+ }
-+ /* FALLTHROUGH */
-+ case PIPE_INTERRUPT:
-+ if (urb->bandwidth == 0) {
-+ bustime = usb_check_bandwidth (urb->dev, urb);
-+ }
-+ if (bustime < 0) {
-+ urb_free_priv (ohci, urb_priv);
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+ usb_dec_dev_use (urb->dev);
-+ return bustime;
-+ }
-+ usb_claim_bandwidth (urb->dev, urb, bustime, usb_pipeisoc (urb->pipe));
-+#ifdef DO_TIMEOUTS
-+ urb->timeout = 0;
-+#endif
-+ }
-+
-+ urb->actual_length = 0;
-+ urb->hcpriv = urb_priv;
-+ urb->status = USB_ST_URB_PENDING;
-+
-+ /* link the ed into a chain if is not already */
-+ if (ed->state != ED_OPER)
-+ ep_link (ohci, ed);
-+
-+ /* fill the TDs and link it to the ed */
-+ td_submit_urb (urb);
-+
-+#ifdef DO_TIMEOUTS
-+ /* maybe add to ordered list of timeouts */
-+ if (urb->timeout) {
-+ struct list_head *entry;
-+
-+ urb->timeout += jiffies;
-+
-+ list_for_each (entry, &ohci->timeout_list) {
-+ struct urb *next_urb;
-+
-+ next_urb = list_entry (entry, struct urb, urb_list);
-+ if (time_after_eq (urb->timeout, next_urb->timeout))
-+ break;
-+ }
-+ list_add (&urb->urb_list, entry);
-+
-+ /* drive timeouts by SF (messy, but works) */
-+ writel (OHCI_INTR_SF, &ohci->regs->intrenable);
-+ (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */
-+ }
-+#endif
-+
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+
-+ return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* deactivate all TDs and remove the private part of the URB */
-+/* interrupt callers must use async unlink mode */
-+
-+static int sohci_unlink_urb (struct urb * urb)
-+{
-+ unsigned long flags;
-+ ohci_t * ohci;
-+
-+ if (!urb) /* just to be sure */
-+ return -EINVAL;
-+
-+ if (!urb->dev || !urb->dev->bus)
-+ return -ENODEV;
-+
-+ ohci = (ohci_t *) urb->dev->bus->hcpriv;
-+
-+#ifdef DEBUG
-+ urb_print (urb, "UNLINK", 1);
-+#endif
-+
-+ /* handle a request to the virtual root hub */
-+ if (usb_pipedevice (urb->pipe) == ohci->rh.devnum)
-+ return rh_unlink_urb (urb);
-+
-+ spin_lock_irqsave(&ohci->ohci_lock, flags);
-+ if (urb->hcpriv && (urb->status == USB_ST_URB_PENDING)) {
-+ if (!ohci->disabled) {
-+ urb_priv_t * urb_priv;
-+
-+ /* interrupt code may not sleep; it must use
-+ * async status return to unlink pending urbs.
-+ */
-+ if (!(urb->transfer_flags & USB_ASYNC_UNLINK)
-+ && in_interrupt ()) {
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+ err ("bug in call from %p; use async!",
-+ __builtin_return_address(0));
-+ return -EWOULDBLOCK;
-+ }
-+
-+ /* flag the urb and its TDs for deletion in some
-+ * upcoming SF interrupt delete list processing
-+ */
-+ urb_priv = urb->hcpriv;
-+
-+ if (!urb_priv || (urb_priv->state == URB_DEL)) {
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+ return 0;
-+ }
-+
-+ urb_priv->state = URB_DEL;
-+ ep_rm_ed (urb->dev, urb_priv->ed);
-+ urb_priv->ed->state |= ED_URB_DEL;
-+
-+ if (!(urb->transfer_flags & USB_ASYNC_UNLINK)) {
-+ DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup);
-+ DECLARE_WAITQUEUE (wait, current);
-+ int timeout = OHCI_UNLINK_TIMEOUT;
-+
-+ add_wait_queue (&unlink_wakeup, &wait);
-+ urb_priv->wait = &unlink_wakeup;
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+
-+ /* wait until all TDs are deleted */
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ while (timeout && (urb->status == USB_ST_URB_PENDING)) {
-+ timeout = schedule_timeout (timeout);
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue (&unlink_wakeup, &wait);
-+ if (urb->status == USB_ST_URB_PENDING) {
-+ err ("unlink URB timeout");
-+ return -ETIMEDOUT;
-+ }
-+
-+ usb_dec_dev_use (urb->dev);
-+ urb->dev = NULL;
-+ if (urb->complete)
-+ urb->complete (urb);
-+ } else {
-+ /* usb_dec_dev_use done in dl_del_list() */
-+ urb->status = -EINPROGRESS;
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+ return -EINPROGRESS;
-+ }
-+ } else {
-+ urb_rm_priv_locked (urb);
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+ usb_dec_dev_use (urb->dev);
-+ urb->dev = NULL;
-+ if (urb->transfer_flags & USB_ASYNC_UNLINK) {
-+ urb->status = -ECONNRESET;
-+ if (urb->complete)
-+ urb->complete (urb);
-+ } else
-+ urb->status = -ENOENT;
-+ }
-+ } else {
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+ }
-+ return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* allocate private data space for a usb device */
-+
-+static int sohci_alloc_dev (struct usb_device *usb_dev)
-+{
-+ struct ohci_device * dev;
-+
-+ dev = dev_alloc ((struct ohci *) usb_dev->bus->hcpriv, ALLOC_FLAGS);
-+ if (!dev)
-+ return -ENOMEM;
-+
-+ usb_dev->hcpriv = dev;
-+ return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* may be called from interrupt context */
-+/* frees private data space of usb device */
-+
-+static int sohci_free_dev (struct usb_device * usb_dev)
-+{
-+ unsigned long flags;
-+ int i, cnt = 0;
-+ ed_t * ed;
-+ struct ohci_device * dev = usb_to_ohci (usb_dev);
-+ ohci_t * ohci = usb_dev->bus->hcpriv;
-+
-+ if (!dev)
-+ return 0;
-+
-+ if (usb_dev->devnum >= 0) {
-+
-+ /* driver disconnects should have unlinked all urbs
-+ * (freeing all the TDs, unlinking EDs) but we need
-+ * to defend against bugs that prevent that.
-+ */
-+ spin_lock_irqsave(&ohci->ohci_lock, flags);
-+ for(i = 0; i < NUM_EDS; i++) {
-+ ed = &(dev->ed[i]);
-+ if (ed->state != ED_NEW) {
-+ if (ed->state == ED_OPER) {
-+ /* driver on that interface didn't unlink an urb */
-+ dbg ("driver usb-%s dev %d ed 0x%x unfreed URB",
-+ ohci->ohci_dev->slot_name, usb_dev->devnum, i);
-+ ep_unlink (ohci, ed);
-+ }
-+ ep_rm_ed (usb_dev, ed);
-+ ed->state = ED_DEL;
-+ cnt++;
-+ }
-+ }
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+
-+ /* if the controller is running, tds for those unlinked
-+ * urbs get freed by dl_del_list at the next SF interrupt
-+ */
-+ if (cnt > 0) {
-+
-+ if (ohci->disabled) {
-+ /* FIXME: Something like this should kick in,
-+ * though it's currently an exotic case ...
-+ * the controller won't ever be touching
-+ * these lists again!!
-+ dl_del_list (ohci,
-+ le16_to_cpu (ohci->hcca->frame_no) & 1);
-+ */
-+ warn ("TD leak, %d", cnt);
-+
-+ } else if (!in_interrupt ()) {
-+ DECLARE_WAIT_QUEUE_HEAD (freedev_wakeup);
-+ DECLARE_WAITQUEUE (wait, current);
-+ int timeout = OHCI_UNLINK_TIMEOUT;
-+
-+ /* SF interrupt handler calls dl_del_list */
-+ add_wait_queue (&freedev_wakeup, &wait);
-+ dev->wait = &freedev_wakeup;
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ while (timeout && dev->ed_cnt)
-+ timeout = schedule_timeout (timeout);
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue (&freedev_wakeup, &wait);
-+ if (dev->ed_cnt) {
-+ err ("free device %d timeout", usb_dev->devnum);
-+ return -ETIMEDOUT;
-+ }
-+ } else {
-+ /* likely some interface's driver has a refcount bug */
-+ err ("bus %s devnum %d deletion in interrupt",
-+ ohci->ohci_dev->slot_name, usb_dev->devnum);
-+ BUG ();
-+ }
-+ }
-+ }
-+
-+ /* free device, and associated EDs */
-+ dev_free (ohci, dev);
-+
-+ return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* tell us the current USB frame number */
-+
-+static int sohci_get_current_frame_number (struct usb_device *usb_dev)
-+{
-+ ohci_t * ohci = usb_dev->bus->hcpriv;
-+
-+ return le16_to_cpu (ohci->hcca->frame_no);
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+struct usb_operations sohci_device_operations = {
-+ sohci_alloc_dev,
-+ sohci_free_dev,
-+ sohci_get_current_frame_number,
-+ sohci_submit_urb,
-+ sohci_unlink_urb
-+};
-+
-+/*-------------------------------------------------------------------------*
-+ * ED handling functions
-+ *-------------------------------------------------------------------------*/
-+
-+/* search for the right branch to insert an interrupt ed into the int tree
-+ * do some load ballancing;
-+ * returns the branch and
-+ * sets the interval to interval = 2^integer (ld (interval)) */
-+
-+static int ep_int_ballance (ohci_t * ohci, int interval, int load)
-+{
-+ int i, branch = 0;
-+
-+ /* search for the least loaded interrupt endpoint branch of all 32 branches */
-+ for (i = 0; i < 32; i++)
-+ if (ohci->ohci_int_load [branch] > ohci->ohci_int_load [i]) branch = i;
-+
-+ branch = branch % interval;
-+ for (i = branch; i < 32; i += interval) ohci->ohci_int_load [i] += load;
-+
-+ return branch;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* 2^int( ld (inter)) */
-+
-+static int ep_2_n_interval (int inter)
-+{
-+ int i;
-+ for (i = 0; ((inter >> i) > 1 ) && (i < 5); i++);
-+ return 1 << i;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* the int tree is a binary tree
-+ * in order to process it sequentially the indexes of the branches have to be mapped
-+ * the mapping reverses the bits of a word of num_bits length */
-+
-+static int ep_rev (int num_bits, int word)
-+{
-+ int i, wout = 0;
-+
-+ for (i = 0; i < num_bits; i++) wout |= (((word >> i) & 1) << (num_bits - i - 1));
-+ return wout;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* link an ed into one of the HC chains */
-+
-+static int ep_link (ohci_t * ohci, ed_t * edi)
-+{
-+ int int_branch;
-+ int i;
-+ int inter;
-+ int interval;
-+ int load;
-+ __u32 * ed_p;
-+ volatile ed_t * ed = edi;
-+
-+ ed->state = ED_OPER;
-+
-+ switch (ed->type) {
-+ case PIPE_CONTROL:
-+ ed->hwNextED = 0;
-+ if (ohci->ed_controltail == NULL) {
-+ writel (ed->dma, &ohci->regs->ed_controlhead);
-+ } else {
-+ ohci->ed_controltail->hwNextED = cpu_to_le32 (ed->dma);
-+ }
-+ ed->ed_prev = ohci->ed_controltail;
-+ if (!ohci->ed_controltail && !ohci->ed_rm_list[0] &&
-+ !ohci->ed_rm_list[1] && !ohci->sleeping) {
-+ ohci->hc_control |= OHCI_CTRL_CLE;
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ }
-+ ohci->ed_controltail = edi;
-+ break;
-+
-+ case PIPE_BULK:
-+ ed->hwNextED = 0;
-+ if (ohci->ed_bulktail == NULL) {
-+ writel (ed->dma, &ohci->regs->ed_bulkhead);
-+ } else {
-+ ohci->ed_bulktail->hwNextED = cpu_to_le32 (ed->dma);
-+ }
-+ ed->ed_prev = ohci->ed_bulktail;
-+ if (!ohci->ed_bulktail && !ohci->ed_rm_list[0] &&
-+ !ohci->ed_rm_list[1] && !ohci->sleeping) {
-+ ohci->hc_control |= OHCI_CTRL_BLE;
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ }
-+ ohci->ed_bulktail = edi;
-+ break;
-+
-+ case PIPE_INTERRUPT:
-+ load = ed->int_load;
-+ interval = ep_2_n_interval (ed->int_period);
-+ ed->int_interval = interval;
-+ int_branch = ep_int_ballance (ohci, interval, load);
-+ ed->int_branch = int_branch;
-+
-+ for (i = 0; i < ep_rev (6, interval); i += inter) {
-+ inter = 1;
-+ for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i) + int_branch]);
-+ (*ed_p != 0) && ((dma_to_ed (ohci, le32_to_cpup (ed_p)))->int_interval >= interval);
-+ ed_p = &((dma_to_ed (ohci, le32_to_cpup (ed_p)))->hwNextED))
-+ inter = ep_rev (6, (dma_to_ed (ohci, le32_to_cpup (ed_p)))->int_interval);
-+ ed->hwNextED = *ed_p;
-+ *ed_p = cpu_to_le32 (ed->dma);
-+ }
-+#ifdef DEBUG
-+ ep_print_int_eds (ohci, "LINK_INT");
-+#endif
-+ break;
-+
-+ case PIPE_ISOCHRONOUS:
-+ ed->hwNextED = 0;
-+ ed->int_interval = 1;
-+ if (ohci->ed_isotail != NULL) {
-+ ohci->ed_isotail->hwNextED = cpu_to_le32 (ed->dma);
-+ ed->ed_prev = ohci->ed_isotail;
-+ } else {
-+ for ( i = 0; i < 32; i += inter) {
-+ inter = 1;
-+ for (ed_p = &(ohci->hcca->int_table[ep_rev (5, i)]);
-+ *ed_p != 0;
-+ ed_p = &((dma_to_ed (ohci, le32_to_cpup (ed_p)))->hwNextED))
-+ inter = ep_rev (6, (dma_to_ed (ohci, le32_to_cpup (ed_p)))->int_interval);
-+ *ed_p = cpu_to_le32 (ed->dma);
-+ }
-+ ed->ed_prev = NULL;
-+ }
-+ ohci->ed_isotail = edi;
-+#ifdef DEBUG
-+ ep_print_int_eds (ohci, "LINK_ISO");
-+#endif
-+ break;
-+ }
-+ return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* scan the periodic table to find and unlink this ED */
-+static void periodic_unlink (
-+ struct ohci *ohci,
-+ struct ed *ed,
-+ unsigned index,
-+ unsigned period
-+) {
-+ for (; index < NUM_INTS; index += period) {
-+ __u32 *ed_p = &ohci->hcca->int_table [index];
-+
-+ /* ED might have been unlinked through another path */
-+ while (*ed_p != 0) {
-+ if ((dma_to_ed (ohci, le32_to_cpup (ed_p))) == ed) {
-+ *ed_p = ed->hwNextED;
-+ break;
-+ }
-+ ed_p = & ((dma_to_ed (ohci,
-+ le32_to_cpup (ed_p)))->hwNextED);
-+ }
-+ }
-+}
-+
-+/* unlink an ed from one of the HC chains.
-+ * just the link to the ed is unlinked.
-+ * the link from the ed still points to another operational ed or 0
-+ * so the HC can eventually finish the processing of the unlinked ed */
-+
-+static int ep_unlink (ohci_t * ohci, ed_t * ed)
-+{
-+ int i;
-+
-+ ed->hwINFO |= cpu_to_le32 (OHCI_ED_SKIP);
-+
-+ switch (ed->type) {
-+ case PIPE_CONTROL:
-+ if (ed->ed_prev == NULL) {
-+ if (!ed->hwNextED) {
-+ ohci->hc_control &= ~OHCI_CTRL_CLE;
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ }
-+ writel (le32_to_cpup (&ed->hwNextED), &ohci->regs->ed_controlhead);
-+ } else {
-+ ed->ed_prev->hwNextED = ed->hwNextED;
-+ }
-+ if (ohci->ed_controltail == ed) {
-+ ohci->ed_controltail = ed->ed_prev;
-+ } else {
-+ (dma_to_ed (ohci, le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev;
-+ }
-+ break;
-+
-+ case PIPE_BULK:
-+ if (ed->ed_prev == NULL) {
-+ if (!ed->hwNextED) {
-+ ohci->hc_control &= ~OHCI_CTRL_BLE;
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ }
-+ writel (le32_to_cpup (&ed->hwNextED), &ohci->regs->ed_bulkhead);
-+ } else {
-+ ed->ed_prev->hwNextED = ed->hwNextED;
-+ }
-+ if (ohci->ed_bulktail == ed) {
-+ ohci->ed_bulktail = ed->ed_prev;
-+ } else {
-+ (dma_to_ed (ohci, le32_to_cpup (&ed->hwNextED)))->ed_prev = ed->ed_prev;
-+ }
-+ break;
-+
-+ case PIPE_INTERRUPT:
-+ periodic_unlink (ohci, ed, 0, 1);
-+ for (i = ed->int_branch; i < 32; i += ed->int_interval)
-+ ohci->ohci_int_load[i] -= ed->int_load;
-+#ifdef DEBUG
-+ ep_print_int_eds (ohci, "UNLINK_INT");
-+#endif
-+ break;
-+
-+ case PIPE_ISOCHRONOUS:
-+ if (ohci->ed_isotail == ed)
-+ ohci->ed_isotail = ed->ed_prev;
-+ if (ed->hwNextED != 0)
-+ (dma_to_ed (ohci, le32_to_cpup (&ed->hwNextED)))
-+ ->ed_prev = ed->ed_prev;
-+
-+ if (ed->ed_prev != NULL)
-+ ed->ed_prev->hwNextED = ed->hwNextED;
-+ else
-+ periodic_unlink (ohci, ed, 0, 1);
-+#ifdef DEBUG
-+ ep_print_int_eds (ohci, "UNLINK_ISO");
-+#endif
-+ break;
-+ }
-+ ed->state = ED_UNLINK;
-+ return 0;
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* add/reinit an endpoint; this should be done once at the usb_set_configuration command,
-+ * but the USB stack is a little bit stateless so we do it at every transaction
-+ * if the state of the ed is ED_NEW then a dummy td is added and the state is changed to ED_UNLINK
-+ * in all other cases the state is left unchanged
-+ * the ed info fields are setted anyway even though most of them should not change */
-+
-+static ed_t * ep_add_ed (
-+ struct usb_device * usb_dev,
-+ unsigned int pipe,
-+ int interval,
-+ int load,
-+ int mem_flags
-+)
-+{
-+ ohci_t * ohci = usb_dev->bus->hcpriv;
-+ td_t * td;
-+ ed_t * ed_ret;
-+ volatile ed_t * ed;
-+
-+ ed = ed_ret = &(usb_to_ohci (usb_dev)->ed[(usb_pipeendpoint (pipe) << 1) |
-+ (usb_pipecontrol (pipe)? 0: usb_pipeout (pipe))]);
-+
-+ if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL)) {
-+ /* pending delete request */
-+ return NULL;
-+ }
-+
-+ if (ed->state == ED_NEW) {
-+ ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); /* skip ed */
-+ /* dummy td; end of td list for ed */
-+ td = td_alloc (ohci, SLAB_ATOMIC);
-+ /* hash the ed for later reverse mapping */
-+ if (!td || !hash_add_ed (ohci, (ed_t *)ed)) {
-+ /* out of memory */
-+ if (td)
-+ td_free(ohci, td);
-+ return NULL;
-+ }
-+ ed->hwTailP = cpu_to_le32 (td->td_dma);
-+ ed->hwHeadP = ed->hwTailP;
-+ ed->state = ED_UNLINK;
-+ ed->type = usb_pipetype (pipe);
-+ usb_to_ohci (usb_dev)->ed_cnt++;
-+ }
-+
-+ ohci->dev[usb_pipedevice (pipe)] = usb_dev;
-+
-+ ed->hwINFO = cpu_to_le32 (usb_pipedevice (pipe)
-+ | usb_pipeendpoint (pipe) << 7
-+ | (usb_pipeisoc (pipe)? 0x8000: 0)
-+ | (usb_pipecontrol (pipe)? 0: (usb_pipeout (pipe)? 0x800: 0x1000))
-+ | usb_pipeslow (pipe) << 13
-+ | usb_maxpacket (usb_dev, pipe, usb_pipeout (pipe)) << 16);
-+
-+ if (ed->type == PIPE_INTERRUPT && ed->state == ED_UNLINK) {
-+ ed->int_period = interval;
-+ ed->int_load = load;
-+ }
-+
-+ return ed_ret;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* request the removal of an endpoint
-+ * put the ep on the rm_list and request a stop of the bulk or ctrl list
-+ * real removal is done at the next start frame (SF) hardware interrupt */
-+
-+static void ep_rm_ed (struct usb_device * usb_dev, ed_t * ed)
-+{
-+ unsigned int frame;
-+ ohci_t * ohci = usb_dev->bus->hcpriv;
-+
-+ if ((ed->state & ED_DEL) || (ed->state & ED_URB_DEL))
-+ return;
-+
-+ ed->hwINFO |= cpu_to_le32 (OHCI_ED_SKIP);
-+
-+ if (!ohci->disabled) {
-+ switch (ed->type) {
-+ case PIPE_CONTROL: /* stop control list */
-+ ohci->hc_control &= ~OHCI_CTRL_CLE;
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ break;
-+ case PIPE_BULK: /* stop bulk list */
-+ ohci->hc_control &= ~OHCI_CTRL_BLE;
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ break;
-+ }
-+ }
-+
-+ frame = le16_to_cpu (ohci->hcca->frame_no) & 0x1;
-+ ed->ed_rm_list = ohci->ed_rm_list[frame];
-+ ohci->ed_rm_list[frame] = ed;
-+
-+ if (!ohci->disabled && !ohci->sleeping) {
-+ /* enable SOF interrupt */
-+ writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
-+ writel (OHCI_INTR_SF, &ohci->regs->intrenable);
-+ (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */
-+ }
-+}
-+
-+/*-------------------------------------------------------------------------*
-+ * TD handling functions
-+ *-------------------------------------------------------------------------*/
-+
-+/* enqueue next TD for this URB (OHCI spec 5.2.8.2) */
-+
-+static void
-+td_fill (ohci_t * ohci, unsigned int info,
-+ dma_addr_t data, int len,
-+ struct urb * urb, int index)
-+{
-+ volatile td_t * td, * td_pt;
-+ urb_priv_t * urb_priv = urb->hcpriv;
-+
-+ if (index >= urb_priv->length) {
-+ err("internal OHCI error: TD index > length");
-+ return;
-+ }
-+
-+ /* use this td as the next dummy */
-+ td_pt = urb_priv->td [index];
-+ td_pt->hwNextTD = 0;
-+
-+ /* fill the old dummy TD */
-+ td = urb_priv->td [index] = dma_to_td (ohci,
-+ le32_to_cpup (&urb_priv->ed->hwTailP) & ~0xf);
-+
-+ td->ed = urb_priv->ed;
-+ td->next_dl_td = NULL;
-+ td->index = index;
-+ td->urb = urb;
-+ td->data_dma = data;
-+ if (!len)
-+ data = 0;
-+
-+ td->hwINFO = cpu_to_le32 (info);
-+ if ((td->ed->type) == PIPE_ISOCHRONOUS) {
-+ td->hwCBP = cpu_to_le32 (data & 0xFFFFF000);
-+ td->ed->last_iso = info & 0xffff;
-+ } else {
-+ td->hwCBP = cpu_to_le32 (data);
-+ }
-+ if (data)
-+ td->hwBE = cpu_to_le32 (data + len - 1);
-+ else
-+ td->hwBE = 0;
-+ td->hwNextTD = cpu_to_le32 (td_pt->td_dma);
-+ td->hwPSW [0] = cpu_to_le16 ((data & 0x0FFF) | 0xE000);
-+
-+ /* append to queue */
-+ wmb();
-+ td->ed->hwTailP = td->hwNextTD;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* prepare all TDs of a transfer */
-+
-+static void td_submit_urb (struct urb * urb)
-+{
-+ urb_priv_t * urb_priv = urb->hcpriv;
-+ ohci_t * ohci = (ohci_t *) urb->dev->bus->hcpriv;
-+ dma_addr_t data;
-+ int data_len = urb->transfer_buffer_length;
-+ int maxps = usb_maxpacket (urb->dev, urb->pipe, usb_pipeout (urb->pipe));
-+ int cnt = 0;
-+ __u32 info = 0;
-+ unsigned int toggle = 0;
-+
-+ /* OHCI handles the DATA-toggles itself, we just use the USB-toggle bits for reseting */
-+ if(usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe))) {
-+ toggle = TD_T_TOGGLE;
-+ } else {
-+ toggle = TD_T_DATA0;
-+ usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 1);
-+ }
-+
-+ urb_priv->td_cnt = 0;
-+
-+ if (data_len) {
-+ data = pci_map_single (ohci->ohci_dev,
-+ urb->transfer_buffer, data_len,
-+ usb_pipeout (urb->pipe)
-+ ? PCI_DMA_TODEVICE
-+ : PCI_DMA_FROMDEVICE
-+ );
-+ } else
-+ data = 0;
-+
-+ switch (usb_pipetype (urb->pipe)) {
-+ case PIPE_BULK:
-+ info = usb_pipeout (urb->pipe)?
-+ TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ;
-+ while(data_len > 4096) {
-+ td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, 4096, urb, cnt);
-+ data += 4096; data_len -= 4096; cnt++;
-+ }
-+ info = usb_pipeout (urb->pipe)?
-+ TD_CC | TD_DP_OUT : TD_CC | TD_R | TD_DP_IN ;
-+ td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), data, data_len, urb, cnt);
-+ cnt++;
-+
-+ /* If the transfer size is multiple of the pipe mtu,
-+ * we may need an extra TD to create a empty frame
-+ * Note : another way to check this condition is
-+ * to test if(urb_priv->length > cnt) - Jean II */
-+ if ((urb->transfer_flags & USB_ZERO_PACKET) &&
-+ usb_pipeout (urb->pipe) &&
-+ (urb->transfer_buffer_length != 0) &&
-+ ((urb->transfer_buffer_length % maxps) == 0)) {
-+ td_fill (ohci, info | (cnt? TD_T_TOGGLE:toggle), 0, 0, urb, cnt);
-+ cnt++;
-+ }
-+
-+ if (!ohci->sleeping) {
-+ wmb();
-+ writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
-+ (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */
-+ }
-+ break;
-+
-+ case PIPE_INTERRUPT:
-+ info = usb_pipeout (urb->pipe)?
-+ TD_CC | TD_DP_OUT | toggle: TD_CC | TD_R | TD_DP_IN | toggle;
-+ td_fill (ohci, info, data, data_len, urb, cnt++);
-+ break;
-+
-+ case PIPE_CONTROL:
-+ info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
-+ td_fill (ohci, info,
-+ pci_map_single (ohci->ohci_dev,
-+ urb->setup_packet, 8,
-+ PCI_DMA_TODEVICE),
-+ 8, urb, cnt++);
-+ if (data_len > 0) {
-+ info = usb_pipeout (urb->pipe)?
-+ TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1;
-+ /* NOTE: mishandles transfers >8K, some >4K */
-+ td_fill (ohci, info, data, data_len, urb, cnt++);
-+ }
-+ info = usb_pipeout (urb->pipe)?
-+ TD_CC | TD_DP_IN | TD_T_DATA1: TD_CC | TD_DP_OUT | TD_T_DATA1;
-+ td_fill (ohci, info, data, 0, urb, cnt++);
-+ if (!ohci->sleeping) {
-+ wmb();
-+ writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
-+ (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */
-+ }
-+ break;
-+
-+ case PIPE_ISOCHRONOUS:
-+ for (cnt = 0; cnt < urb->number_of_packets; cnt++) {
-+ td_fill (ohci, TD_CC|TD_ISO | ((urb->start_frame + cnt) & 0xffff),
-+ data + urb->iso_frame_desc[cnt].offset,
-+ urb->iso_frame_desc[cnt].length, urb, cnt);
-+ }
-+ break;
-+ }
-+ if (urb_priv->length != cnt)
-+ dbg("TD LENGTH %d != CNT %d", urb_priv->length, cnt);
-+}
-+
-+/*-------------------------------------------------------------------------*
-+ * Done List handling functions
-+ *-------------------------------------------------------------------------*/
-+
-+
-+/* calculate the transfer length and update the urb */
-+
-+static void dl_transfer_length(td_t * td)
-+{
-+ __u32 tdINFO, tdBE, tdCBP;
-+ __u16 tdPSW;
-+ struct urb * urb = td->urb;
-+ urb_priv_t * urb_priv = urb->hcpriv;
-+ int dlen = 0;
-+ int cc = 0;
-+
-+ tdINFO = le32_to_cpup (&td->hwINFO);
-+ tdBE = le32_to_cpup (&td->hwBE);
-+ tdCBP = le32_to_cpup (&td->hwCBP);
-+
-+
-+ if (tdINFO & TD_ISO) {
-+ tdPSW = le16_to_cpu (td->hwPSW[0]);
-+ cc = (tdPSW >> 12) & 0xF;
-+ if (cc < 0xE) {
-+ if (usb_pipeout(urb->pipe)) {
-+ dlen = urb->iso_frame_desc[td->index].length;
-+ } else {
-+ dlen = tdPSW & 0x3ff;
-+ }
-+ urb->actual_length += dlen;
-+ urb->iso_frame_desc[td->index].actual_length = dlen;
-+ if (!(urb->transfer_flags & USB_DISABLE_SPD) && (cc == TD_DATAUNDERRUN))
-+ cc = TD_CC_NOERROR;
-+
-+ urb->iso_frame_desc[td->index].status = cc_to_error[cc];
-+ }
-+ } else { /* BULK, INT, CONTROL DATA */
-+ if (!(usb_pipetype (urb->pipe) == PIPE_CONTROL &&
-+ ((td->index == 0) || (td->index == urb_priv->length - 1)))) {
-+ if (tdBE != 0) {
-+ if (td->hwCBP == 0)
-+ urb->actual_length += tdBE - td->data_dma + 1;
-+ else
-+ urb->actual_length += tdCBP - td->data_dma;
-+ }
-+ }
-+ }
-+}
-+
-+/* handle an urb that is being unlinked */
-+
-+static void dl_del_urb (ohci_t *ohci, struct urb * urb)
-+{
-+ wait_queue_head_t * wait_head = ((urb_priv_t *)(urb->hcpriv))->wait;
-+
-+ urb_rm_priv_locked (urb);
-+
-+ if (urb->transfer_flags & USB_ASYNC_UNLINK) {
-+ urb->status = -ECONNRESET;
-+ ohci_complete_add(ohci, urb);
-+ } else {
-+ urb->status = -ENOENT;
-+
-+ /* unblock sohci_unlink_urb */
-+ if (wait_head)
-+ wake_up (wait_head);
-+ }
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* replies to the request have to be on a FIFO basis so
-+ * we reverse the reversed done-list */
-+
-+static td_t * dl_reverse_done_list (ohci_t * ohci)
-+{
-+ __u32 td_list_hc;
-+ td_t * td_rev = NULL;
-+ td_t * td_list = NULL;
-+ urb_priv_t * urb_priv = NULL;
-+
-+ td_list_hc = le32_to_cpup (&ohci->hcca->done_head) & 0xfffffff0;
-+ ohci->hcca->done_head = 0;
-+
-+ while (td_list_hc) {
-+ td_list = dma_to_td (ohci, td_list_hc);
-+
-+ if (TD_CC_GET (le32_to_cpup (&td_list->hwINFO))) {
-+ urb_priv = (urb_priv_t *) td_list->urb->hcpriv;
-+ dbg(" USB-error/status: %x : %p",
-+ TD_CC_GET (le32_to_cpup (&td_list->hwINFO)), td_list);
-+ if (td_list->ed->hwHeadP & cpu_to_le32 (0x1)) {
-+ if (urb_priv && ((td_list->index + 1) < urb_priv->length)) {
-+ td_list->ed->hwHeadP =
-+ (urb_priv->td[urb_priv->length - 1]->hwNextTD & cpu_to_le32 (0xfffffff0)) |
-+ (td_list->ed->hwHeadP & cpu_to_le32 (0x2));
-+ urb_priv->td_cnt += urb_priv->length - td_list->index - 1;
-+ } else
-+ td_list->ed->hwHeadP &= cpu_to_le32 (0xfffffff2);
-+ }
-+ }
-+
-+ td_list->next_dl_td = td_rev;
-+ td_rev = td_list;
-+ td_list_hc = le32_to_cpup (&td_list->hwNextTD) & 0xfffffff0;
-+ }
-+ return td_list;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* there are some pending requests to remove
-+ * - some of the eds (if ed->state & ED_DEL (set by sohci_free_dev)
-+ * - some URBs/TDs if urb_priv->state == URB_DEL */
-+
-+static void dl_del_list (ohci_t * ohci, unsigned int frame)
-+{
-+ ed_t * ed;
-+ __u32 edINFO;
-+ __u32 tdINFO;
-+ td_t * td = NULL, * td_next = NULL, * tdHeadP = NULL, * tdTailP;
-+ __u32 * td_p;
-+ int ctrl = 0, bulk = 0;
-+
-+ for (ed = ohci->ed_rm_list[frame]; ed != NULL; ed = ed->ed_rm_list) {
-+
-+ tdTailP = dma_to_td (ohci, le32_to_cpup (&ed->hwTailP) & 0xfffffff0);
-+ tdHeadP = dma_to_td (ohci, le32_to_cpup (&ed->hwHeadP) & 0xfffffff0);
-+ edINFO = le32_to_cpup (&ed->hwINFO);
-+ td_p = &ed->hwHeadP;
-+
-+ for (td = tdHeadP; td != tdTailP; td = td_next) {
-+ struct urb * urb = td->urb;
-+ urb_priv_t * urb_priv = td->urb->hcpriv;
-+
-+ td_next = dma_to_td (ohci, le32_to_cpup (&td->hwNextTD) & 0xfffffff0);
-+ if ((urb_priv->state == URB_DEL) || (ed->state & ED_DEL)) {
-+ tdINFO = le32_to_cpup (&td->hwINFO);
-+ if (TD_CC_GET (tdINFO) < 0xE)
-+ dl_transfer_length (td);
-+ *td_p = td->hwNextTD | (*td_p & cpu_to_le32 (0x3));
-+
-+ /* URB is done; clean up */
-+ if (++(urb_priv->td_cnt) == urb_priv->length)
-+ dl_del_urb (ohci, urb);
-+ } else {
-+ td_p = &td->hwNextTD;
-+ }
-+ }
-+
-+ if (ed->state & ED_DEL) { /* set by sohci_free_dev */
-+ struct ohci_device * dev = usb_to_ohci (ohci->dev[edINFO & 0x7F]);
-+ td_free (ohci, tdTailP); /* free dummy td */
-+ ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP);
-+ ed->state = ED_NEW;
-+ hash_free_ed(ohci, ed);
-+ /* if all eds are removed wake up sohci_free_dev */
-+ if (!--dev->ed_cnt) {
-+ wait_queue_head_t *wait_head = dev->wait;
-+
-+ dev->wait = 0;
-+ if (wait_head)
-+ wake_up (wait_head);
-+ }
-+ } else {
-+ ed->state &= ~ED_URB_DEL;
-+ tdHeadP = dma_to_td (ohci, le32_to_cpup (&ed->hwHeadP) & 0xfffffff0);
-+
-+ if (tdHeadP == tdTailP) {
-+ if (ed->state == ED_OPER)
-+ ep_unlink(ohci, ed);
-+ } else
-+ ed->hwINFO &= ~cpu_to_le32 (OHCI_ED_SKIP);
-+ }
-+
-+ switch (ed->type) {
-+ case PIPE_CONTROL:
-+ ctrl = 1;
-+ break;
-+ case PIPE_BULK:
-+ bulk = 1;
-+ break;
-+ }
-+ }
-+
-+ /* maybe reenable control and bulk lists */
-+ if (!ohci->disabled) {
-+ if (ctrl) /* reset control list */
-+ writel (0, &ohci->regs->ed_controlcurrent);
-+ if (bulk) /* reset bulk list */
-+ writel (0, &ohci->regs->ed_bulkcurrent);
-+ if (!ohci->ed_rm_list[!frame] && !ohci->sleeping) {
-+ if (ohci->ed_controltail)
-+ ohci->hc_control |= OHCI_CTRL_CLE;
-+ if (ohci->ed_bulktail)
-+ ohci->hc_control |= OHCI_CTRL_BLE;
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ }
-+ }
-+
-+ ohci->ed_rm_list[frame] = NULL;
-+}
-+
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* td done list */
-+
-+static void dl_done_list (ohci_t * ohci, td_t * td_list)
-+{
-+ td_t * td_list_next = NULL;
-+ ed_t * ed;
-+ int cc = 0;
-+ struct urb * urb;
-+ urb_priv_t * urb_priv;
-+ __u32 tdINFO, edHeadP, edTailP;
-+
-+ while (td_list) {
-+ td_list_next = td_list->next_dl_td;
-+
-+ urb = td_list->urb;
-+ urb_priv = urb->hcpriv;
-+ tdINFO = le32_to_cpup (&td_list->hwINFO);
-+
-+ ed = td_list->ed;
-+
-+ dl_transfer_length(td_list);
-+
-+ /* error code of transfer */
-+ cc = TD_CC_GET (tdINFO);
-+ if (cc == TD_CC_STALL)
-+ usb_endpoint_halt(urb->dev,
-+ usb_pipeendpoint(urb->pipe),
-+ usb_pipeout(urb->pipe));
-+
-+ if (!(urb->transfer_flags & USB_DISABLE_SPD)
-+ && (cc == TD_DATAUNDERRUN))
-+ cc = TD_CC_NOERROR;
-+
-+ if (++(urb_priv->td_cnt) == urb_priv->length) {
-+ if ((ed->state & (ED_OPER | ED_UNLINK))
-+ && (urb_priv->state != URB_DEL)) {
-+ urb->status = cc_to_error[cc];
-+ sohci_return_urb (ohci, urb);
-+ } else {
-+ dl_del_urb (ohci, urb);
-+ }
-+ }
-+
-+ if (ed->state != ED_NEW) {
-+ edHeadP = le32_to_cpup (&ed->hwHeadP) & 0xfffffff0;
-+ edTailP = le32_to_cpup (&ed->hwTailP);
-+
-+ /* unlink eds if they are not busy */
-+ if ((edHeadP == edTailP) && (ed->state == ED_OPER))
-+ ep_unlink (ohci, ed);
-+ }
-+
-+ td_list = td_list_next;
-+ }
-+}
-+
-+
-+
-+
-+/*-------------------------------------------------------------------------*
-+ * Virtual Root Hub
-+ *-------------------------------------------------------------------------*/
-+
-+/* Device descriptor */
-+static __u8 root_hub_dev_des[] =
-+{
-+ 0x12, /* __u8 bLength; */
-+ 0x01, /* __u8 bDescriptorType; Device */
-+ 0x10, /* __u16 bcdUSB; v1.1 */
-+ 0x01,
-+ 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
-+ 0x00, /* __u8 bDeviceSubClass; */
-+ 0x00, /* __u8 bDeviceProtocol; */
-+ 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */
-+ 0x00, /* __u16 idVendor; */
-+ 0x00,
-+ 0x00, /* __u16 idProduct; */
-+ 0x00,
-+ 0x00, /* __u16 bcdDevice; */
-+ 0x00,
-+ 0x00, /* __u8 iManufacturer; */
-+ 0x02, /* __u8 iProduct; */
-+ 0x01, /* __u8 iSerialNumber; */
-+ 0x01 /* __u8 bNumConfigurations; */
-+};
-+
-+
-+/* Configuration descriptor */
-+static __u8 root_hub_config_des[] =
-+{
-+ 0x09, /* __u8 bLength; */
-+ 0x02, /* __u8 bDescriptorType; Configuration */
-+ 0x19, /* __u16 wTotalLength; */
-+ 0x00,
-+ 0x01, /* __u8 bNumInterfaces; */
-+ 0x01, /* __u8 bConfigurationValue; */
-+ 0x00, /* __u8 iConfiguration; */
-+ 0x40, /* __u8 bmAttributes;
-+ Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup, 4..0: resvd */
-+ 0x00, /* __u8 MaxPower; */
-+
-+ /* interface */
-+ 0x09, /* __u8 if_bLength; */
-+ 0x04, /* __u8 if_bDescriptorType; Interface */
-+ 0x00, /* __u8 if_bInterfaceNumber; */
-+ 0x00, /* __u8 if_bAlternateSetting; */
-+ 0x01, /* __u8 if_bNumEndpoints; */
-+ 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */
-+ 0x00, /* __u8 if_bInterfaceSubClass; */
-+ 0x00, /* __u8 if_bInterfaceProtocol; */
-+ 0x00, /* __u8 if_iInterface; */
-+
-+ /* endpoint */
-+ 0x07, /* __u8 ep_bLength; */
-+ 0x05, /* __u8 ep_bDescriptorType; Endpoint */
-+ 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
-+ 0x03, /* __u8 ep_bmAttributes; Interrupt */
-+ 0x02, /* __u16 ep_wMaxPacketSize; ((MAX_ROOT_PORTS + 1) / 8 */
-+ 0x00,
-+ 0xff /* __u8 ep_bInterval; 255 ms */
-+};
-+
-+/* Hub class-specific descriptor is constructed dynamically */
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* prepare Interrupt pipe data; HUB INTERRUPT ENDPOINT */
-+
-+static int rh_send_irq (ohci_t * ohci, void * rh_data, int rh_len)
-+{
-+ int num_ports;
-+ int i;
-+ int ret;
-+ int len;
-+
-+ __u8 data[8];
-+
-+ num_ports = roothub_a (ohci) & RH_A_NDP;
-+ if (num_ports > MAX_ROOT_PORTS) {
-+ err ("bogus NDP=%d for OHCI usb-%s", num_ports,
-+ ohci->ohci_dev->slot_name);
-+ err ("rereads as NDP=%d",
-+ readl (&ohci->regs->roothub.a) & RH_A_NDP);
-+ /* retry later; "should not happen" */
-+ return 0;
-+ }
-+ *(__u8 *) data = (roothub_status (ohci) & (RH_HS_LPSC | RH_HS_OCIC))
-+ ? 1: 0;
-+ ret = *(__u8 *) data;
-+
-+ for ( i = 0; i < num_ports; i++) {
-+ *(__u8 *) (data + (i + 1) / 8) |=
-+ ((roothub_portstatus (ohci, i) &
-+ (RH_PS_CSC | RH_PS_PESC | RH_PS_PSSC | RH_PS_OCIC | RH_PS_PRSC))
-+ ? 1: 0) << ((i + 1) % 8);
-+ ret += *(__u8 *) (data + (i + 1) / 8);
-+ }
-+ len = i/8 + 1;
-+
-+ if (ret > 0) {
-+ memcpy(rh_data, data,
-+ min_t(unsigned int, len,
-+ min_t(unsigned int, rh_len, sizeof(data))));
-+ return len;
-+ }
-+ return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* Virtual Root Hub INTs are polled by this timer every "interval" ms */
-+
-+static void rh_int_timer_do (unsigned long ptr)
-+{
-+ int len;
-+
-+ struct urb * urb = (struct urb *) ptr;
-+ ohci_t * ohci = urb->dev->bus->hcpriv;
-+
-+ if (ohci->disabled)
-+ return;
-+
-+ /* ignore timers firing during PM suspend, etc */
-+ if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER)
-+ goto out;
-+
-+ if(ohci->rh.send) {
-+ len = rh_send_irq (ohci, urb->transfer_buffer, urb->transfer_buffer_length);
-+ if (len > 0) {
-+ urb->actual_length = len;
-+#ifdef DEBUG
-+ urb_print (urb, "RET-t(rh)", usb_pipeout (urb->pipe));
-+#endif
-+ if (urb->complete)
-+ urb->complete (urb);
-+ }
-+ }
-+ out:
-+ rh_init_int_timer (urb);
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* Root Hub INTs are polled by this timer */
-+
-+static int rh_init_int_timer (struct urb * urb)
-+{
-+ ohci_t * ohci = urb->dev->bus->hcpriv;
-+
-+ ohci->rh.interval = urb->interval;
-+ init_timer (&ohci->rh.rh_int_timer);
-+ ohci->rh.rh_int_timer.function = rh_int_timer_do;
-+ ohci->rh.rh_int_timer.data = (unsigned long) urb;
-+ ohci->rh.rh_int_timer.expires =
-+ jiffies + (HZ * (urb->interval < 30? 30: urb->interval)) / 1000;
-+ add_timer (&ohci->rh.rh_int_timer);
-+
-+ return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+#define OK(x) len = (x); break
-+#define WR_RH_STAT(x) writel((x), &ohci->regs->roothub.status)
-+#define WR_RH_PORTSTAT(x) writel((x), &ohci->regs->roothub.portstatus[wIndex-1])
-+#define RD_RH_STAT roothub_status(ohci)
-+#define RD_RH_PORTSTAT roothub_portstatus(ohci,wIndex-1)
-+
-+/* request to virtual root hub */
-+
-+static int rh_submit_urb (struct urb * urb)
-+{
-+ struct usb_device * usb_dev = urb->dev;
-+ ohci_t * ohci = usb_dev->bus->hcpriv;
-+ unsigned int pipe = urb->pipe;
-+ struct usb_ctrlrequest * cmd = (struct usb_ctrlrequest *) urb->setup_packet;
-+ void * data = urb->transfer_buffer;
-+ int leni = urb->transfer_buffer_length;
-+ int len = 0;
-+ int status = TD_CC_NOERROR;
-+ unsigned long flags;
-+
-+ __u32 datab[4];
-+ __u8 * data_buf = (__u8 *) datab;
-+
-+ __u16 bmRType_bReq;
-+ __u16 wValue;
-+ __u16 wIndex;
-+ __u16 wLength;
-+
-+ spin_lock_irqsave(&ohci->ohci_lock, flags);
-+
-+ if (usb_pipeint(pipe)) {
-+ ohci->rh.urb = urb;
-+ ohci->rh.send = 1;
-+ ohci->rh.interval = urb->interval;
-+ rh_init_int_timer(urb);
-+ urb->status = cc_to_error [TD_CC_NOERROR];
-+
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+ return 0;
-+ }
-+
-+ bmRType_bReq = cmd->bRequestType | (cmd->bRequest << 8);
-+ wValue = le16_to_cpu (cmd->wValue);
-+ wIndex = le16_to_cpu (cmd->wIndex);
-+ wLength = le16_to_cpu (cmd->wLength);
-+
-+ switch (bmRType_bReq) {
-+ /* Request Destination:
-+ without flags: Device,
-+ RH_INTERFACE: interface,
-+ RH_ENDPOINT: endpoint,
-+ RH_CLASS means HUB here,
-+ RH_OTHER | RH_CLASS almost ever means HUB_PORT here
-+ */
-+
-+ case RH_GET_STATUS:
-+ *(__u16 *) data_buf = cpu_to_le16 (1); OK (2);
-+ case RH_GET_STATUS | RH_INTERFACE:
-+ *(__u16 *) data_buf = cpu_to_le16 (0); OK (2);
-+ case RH_GET_STATUS | RH_ENDPOINT:
-+ *(__u16 *) data_buf = cpu_to_le16 (0); OK (2);
-+ case RH_GET_STATUS | RH_CLASS:
-+ *(__u32 *) data_buf = cpu_to_le32 (
-+ RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));
-+ OK (4);
-+ case RH_GET_STATUS | RH_OTHER | RH_CLASS:
-+ *(__u32 *) data_buf = cpu_to_le32 (RD_RH_PORTSTAT); OK (4);
-+
-+ case RH_CLEAR_FEATURE | RH_ENDPOINT:
-+ switch (wValue) {
-+ case (RH_ENDPOINT_STALL): OK (0);
-+ }
-+ break;
-+
-+ case RH_CLEAR_FEATURE | RH_CLASS:
-+ switch (wValue) {
-+ case RH_C_HUB_LOCAL_POWER:
-+ OK(0);
-+ case (RH_C_HUB_OVER_CURRENT):
-+ WR_RH_STAT(RH_HS_OCIC); OK (0);
-+ }
-+ break;
-+
-+ case RH_CLEAR_FEATURE | RH_OTHER | RH_CLASS:
-+ switch (wValue) {
-+ case (RH_PORT_ENABLE):
-+ WR_RH_PORTSTAT (RH_PS_CCS ); OK (0);
-+ case (RH_PORT_SUSPEND):
-+ WR_RH_PORTSTAT (RH_PS_POCI); OK (0);
-+ case (RH_PORT_POWER):
-+ WR_RH_PORTSTAT (RH_PS_LSDA); OK (0);
-+ case (RH_C_PORT_CONNECTION):
-+ WR_RH_PORTSTAT (RH_PS_CSC ); OK (0);
-+ case (RH_C_PORT_ENABLE):
-+ WR_RH_PORTSTAT (RH_PS_PESC); OK (0);
-+ case (RH_C_PORT_SUSPEND):
-+ WR_RH_PORTSTAT (RH_PS_PSSC); OK (0);
-+ case (RH_C_PORT_OVER_CURRENT):
-+ WR_RH_PORTSTAT (RH_PS_OCIC); OK (0);
-+ case (RH_C_PORT_RESET):
-+ WR_RH_PORTSTAT (RH_PS_PRSC); OK (0);
-+ }
-+ break;
-+
-+ case RH_SET_FEATURE | RH_OTHER | RH_CLASS:
-+ switch (wValue) {
-+ case (RH_PORT_SUSPEND):
-+ WR_RH_PORTSTAT (RH_PS_PSS ); OK (0);
-+ case (RH_PORT_RESET): /* BUG IN HUP CODE *********/
-+ if (RD_RH_PORTSTAT & RH_PS_CCS)
-+ WR_RH_PORTSTAT (RH_PS_PRS);
-+ OK (0);
-+ case (RH_PORT_POWER):
-+ WR_RH_PORTSTAT (RH_PS_PPS ); OK (0);
-+ case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/
-+ if (RD_RH_PORTSTAT & RH_PS_CCS)
-+ WR_RH_PORTSTAT (RH_PS_PES );
-+ OK (0);
-+ }
-+ break;
-+
-+ case RH_SET_ADDRESS: ohci->rh.devnum = wValue; OK(0);
-+
-+ case RH_GET_DESCRIPTOR:
-+ switch ((wValue & 0xff00) >> 8) {
-+ case (0x01): /* device descriptor */
-+ len = min_t(unsigned int,
-+ leni,
-+ min_t(unsigned int,
-+ sizeof (root_hub_dev_des),
-+ wLength));
-+ data_buf = root_hub_dev_des; OK(len);
-+ case (0x02): /* configuration descriptor */
-+ len = min_t(unsigned int,
-+ leni,
-+ min_t(unsigned int,
-+ sizeof (root_hub_config_des),
-+ wLength));
-+ data_buf = root_hub_config_des; OK(len);
-+ case (0x03): /* string descriptors */
-+ len = usb_root_hub_string (wValue & 0xff,
-+ (int)(long) ohci->regs, "OHCI",
-+ data, wLength);
-+ if (len > 0) {
-+ data_buf = data;
-+ OK(min_t(int, leni, len));
-+ }
-+ // else fallthrough
-+ default:
-+ status = TD_CC_STALL;
-+ }
-+ break;
-+
-+ case RH_GET_DESCRIPTOR | RH_CLASS:
-+ {
-+ __u32 temp = roothub_a (ohci);
-+
-+ data_buf [0] = 9; // min length;
-+ data_buf [1] = 0x29;
-+ data_buf [2] = temp & RH_A_NDP;
-+ data_buf [3] = 0;
-+ if (temp & RH_A_PSM) /* per-port power switching? */
-+ data_buf [3] |= 0x1;
-+ if (temp & RH_A_NOCP) /* no overcurrent reporting? */
-+ data_buf [3] |= 0x10;
-+ else if (temp & RH_A_OCPM) /* per-port overcurrent reporting? */
-+ data_buf [3] |= 0x8;
-+
-+ datab [1] = 0;
-+ data_buf [5] = (temp & RH_A_POTPGT) >> 24;
-+ temp = roothub_b (ohci);
-+ data_buf [7] = temp & RH_B_DR;
-+ if (data_buf [2] < 7) {
-+ data_buf [8] = 0xff;
-+ } else {
-+ data_buf [0] += 2;
-+ data_buf [8] = (temp & RH_B_DR) >> 8;
-+ data_buf [10] = data_buf [9] = 0xff;
-+ }
-+
-+ len = min_t(unsigned int, leni,
-+ min_t(unsigned int, data_buf [0], wLength));
-+ OK (len);
-+ }
-+
-+ case RH_GET_CONFIGURATION: *(__u8 *) data_buf = 0x01; OK (1);
-+
-+ case RH_SET_CONFIGURATION: WR_RH_STAT (0x10000); OK (0);
-+
-+ default:
-+ dbg ("unsupported root hub command");
-+ status = TD_CC_STALL;
-+ }
-+
-+#ifdef DEBUG
-+ // ohci_dump_roothub (ohci, 0);
-+#endif
-+
-+ len = min_t(int, len, leni);
-+ if (data != data_buf)
-+ memcpy (data, data_buf, len);
-+ urb->actual_length = len;
-+ urb->status = cc_to_error [status];
-+
-+#ifdef DEBUG
-+ urb_print (urb, "RET(rh)", usb_pipeout (urb->pipe));
-+#endif
-+
-+ urb->hcpriv = NULL;
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+ usb_dec_dev_use (usb_dev);
-+ urb->dev = NULL;
-+ if (urb->complete)
-+ urb->complete (urb);
-+ return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int rh_unlink_urb (struct urb * urb)
-+{
-+ ohci_t * ohci = urb->dev->bus->hcpriv;
-+ unsigned int flags;
-+
-+ spin_lock_irqsave(&ohci->ohci_lock, flags);
-+ if (ohci->rh.urb == urb) {
-+ ohci->rh.send = 0;
-+ del_timer (&ohci->rh.rh_int_timer);
-+ ohci->rh.urb = NULL;
-+
-+ urb->hcpriv = NULL;
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+ usb_dec_dev_use(urb->dev);
-+ urb->dev = NULL;
-+ if (urb->transfer_flags & USB_ASYNC_UNLINK) {
-+ urb->status = -ECONNRESET;
-+ if (urb->complete)
-+ urb->complete (urb);
-+ } else
-+ urb->status = -ENOENT;
-+ } else {
-+ spin_unlock_irqrestore(&ohci->ohci_lock, flags);
-+ }
-+ return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*
-+ * HC functions
-+ *-------------------------------------------------------------------------*/
-+
-+/* reset the HC and BUS */
-+
-+static int hc_reset (ohci_t * ohci)
-+{
-+ int timeout = 30;
-+ int smm_timeout = 50; /* 0,5 sec */
-+
-+#ifndef __hppa__
-+ /* PA-RISC doesn't have SMM, but PDC might leave IR set */
-+ if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */
-+ writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */
-+ dbg("USB HC TakeOver from SMM");
-+ while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
-+ wait_ms (10);
-+ if (--smm_timeout == 0) {
-+ err("USB HC TakeOver failed!");
-+ return -1;
-+ }
-+ }
-+ }
-+#endif
-+
-+ /* Disable HC interrupts */
-+ writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
-+
-+ dbg("USB HC reset_hc usb-%s: ctrl = 0x%x ;",
-+ ohci->ohci_dev->slot_name,
-+ readl (&ohci->regs->control));
-+
-+ /* Reset USB (needed by some controllers) */
-+ writel (0, &ohci->regs->control);
-+
-+ /* Force a state change from USBRESET to USBOPERATIONAL for ALi */
-+ (void) readl (&ohci->regs->control); /* PCI posting */
-+ writel (ohci->hc_control = OHCI_USB_OPER, &ohci->regs->control);
-+
-+ /* HC Reset requires max 10 ms delay */
-+ writel (OHCI_HCR, &ohci->regs->cmdstatus);
-+ while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
-+ if (--timeout == 0) {
-+ err("USB HC reset timed out!");
-+ return -1;
-+ }
-+ udelay (1);
-+ }
-+ return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* Start an OHCI controller, set the BUS operational
-+ * enable interrupts
-+ * connect the virtual root hub */
-+
-+static int hc_start (ohci_t * ohci)
-+{
-+ __u32 mask;
-+ unsigned int fminterval;
-+ struct usb_device * usb_dev;
-+ struct ohci_device * dev;
-+
-+ ohci->disabled = 1;
-+
-+ /* Tell the controller where the control and bulk lists are
-+ * The lists are empty now. */
-+
-+ writel (0, &ohci->regs->ed_controlhead);
-+ writel (0, &ohci->regs->ed_bulkhead);
-+
-+ writel (ohci->hcca_dma, &ohci->regs->hcca); /* a reset clears this */
-+
-+ fminterval = 0x2edf;
-+ writel ((fminterval * 9) / 10, &ohci->regs->periodicstart);
-+ fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
-+ writel (fminterval, &ohci->regs->fminterval);
-+ writel (0x628, &ohci->regs->lsthresh);
-+
-+ /* start controller operations */
-+ ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
-+ ohci->disabled = 0;
-+ writel (ohci->hc_control, &ohci->regs->control);
-+
-+ /* Choose the interrupts we care about now, others later on demand */
-+ mask = OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO;
-+ writel (mask, &ohci->regs->intrenable);
-+ writel (mask, &ohci->regs->intrstatus);
-+
-+#ifdef OHCI_USE_NPS
-+ if(ohci->flags & OHCI_QUIRK_SUCKYIO)
-+ {
-+ /* NSC 87560 at least requires different setup .. */
-+ writel ((roothub_a (ohci) | RH_A_NOCP) &
-+ ~(RH_A_OCPM | RH_A_POTPGT | RH_A_PSM | RH_A_NPS),
-+ &ohci->regs->roothub.a);
-+ }
-+ else
-+ {
-+ /* required for AMD-756 and some Mac platforms */
-+ writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM,
-+ &ohci->regs->roothub.a);
-+ }
-+ writel (RH_HS_LPSC, &ohci->regs->roothub.status);
-+#endif /* OHCI_USE_NPS */
-+
-+ (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */
-+
-+ // POTPGT delay is bits 24-31, in 2 ms units.
-+ mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
-+
-+ /* connect the virtual root hub */
-+ ohci->rh.devnum = 0;
-+ usb_dev = usb_alloc_dev (NULL, ohci->bus);
-+ if (!usb_dev) {
-+ ohci->disabled = 1;
-+ return -ENOMEM;
-+ }
-+
-+ dev = usb_to_ohci (usb_dev);
-+ ohci->bus->root_hub = usb_dev;
-+ usb_connect (usb_dev);
-+ if (usb_new_device (usb_dev) != 0) {
-+ usb_free_dev (usb_dev);
-+ ohci->disabled = 1;
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* called only from interrupt handler */
-+
-+static void check_timeouts (struct ohci *ohci)
-+{
-+ spin_lock (&ohci->ohci_lock);
-+ while (!list_empty (&ohci->timeout_list)) {
-+ struct urb *urb;
-+
-+ urb = list_entry (ohci->timeout_list.next, struct urb, urb_list);
-+ if (time_after (jiffies, urb->timeout))
-+ break;
-+
-+ list_del_init (&urb->urb_list);
-+ if (urb->status != -EINPROGRESS)
-+ continue;
-+
-+ urb->transfer_flags |= USB_TIMEOUT_KILLED | USB_ASYNC_UNLINK;
-+ spin_unlock (&ohci->ohci_lock);
-+
-+ // outside the interrupt handler (in a timer...)
-+ // this reference would race interrupts
-+ sohci_unlink_urb (urb);
-+
-+ spin_lock (&ohci->ohci_lock);
-+ }
-+ spin_unlock (&ohci->ohci_lock);
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* an interrupt happens */
-+
-+static void hc_interrupt (int irq, void * __ohci, struct pt_regs * r)
-+{
-+ ohci_t * ohci = __ohci;
-+ struct ohci_regs * regs = ohci->regs;
-+ int ints;
-+
-+ spin_lock (&ohci->ohci_lock);
-+
-+ /* avoid (slow) readl if only WDH happened */
-+ if ((ohci->hcca->done_head != 0)
-+ && !(le32_to_cpup (&ohci->hcca->done_head) & 0x01)) {
-+ ints = OHCI_INTR_WDH;
-+
-+ /* cardbus/... hardware gone before remove() */
-+ } else if ((ints = readl (&regs->intrstatus)) == ~(u32)0) {
-+ ohci->disabled++;
-+ spin_unlock (&ohci->ohci_lock);
-+ err ("%s device removed!", ohci->ohci_dev->slot_name);
-+ return;
-+
-+ /* interrupt for some other device? */
-+ } else if ((ints &= readl (&regs->intrenable)) == 0) {
-+ spin_unlock (&ohci->ohci_lock);
-+ return;
-+ }
-+
-+ // dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no));
-+
-+ if (ints & OHCI_INTR_UE) {
-+ ohci->disabled++;
-+ err ("OHCI Unrecoverable Error, controller usb-%s disabled",
-+ ohci->ohci_dev->slot_name);
-+ // e.g. due to PCI Master/Target Abort
-+
-+#ifdef DEBUG
-+ ohci_dump (ohci, 1);
-+#else
-+ // FIXME: be optimistic, hope that bug won't repeat often.
-+ // Make some non-interrupt context restart the controller.
-+ // Count and limit the retries though; either hardware or
-+ // software errors can go forever...
-+#endif
-+ hc_reset (ohci);
-+ }
-+
-+ if (ints & OHCI_INTR_WDH) {
-+ writel (OHCI_INTR_WDH, &regs->intrdisable);
-+ (void)readl (&regs->intrdisable); /* PCI posting flush */
-+ dl_done_list (ohci, dl_reverse_done_list (ohci));
-+ writel (OHCI_INTR_WDH, &regs->intrenable);
-+ (void)readl (&regs->intrdisable); /* PCI posting flush */
-+ }
-+
-+ if (ints & OHCI_INTR_SO) {
-+ dbg("USB Schedule overrun");
-+ writel (OHCI_INTR_SO, &regs->intrenable);
-+ (void)readl (&regs->intrdisable); /* PCI posting flush */
-+ }
-+
-+ // FIXME: this assumes SOF (1/ms) interrupts don't get lost...
-+ if (ints & OHCI_INTR_SF) {
-+ unsigned int frame = le16_to_cpu (ohci->hcca->frame_no) & 1;
-+ writel (OHCI_INTR_SF, &regs->intrdisable);
-+ (void)readl (&regs->intrdisable); /* PCI posting flush */
-+ if (ohci->ed_rm_list[!frame] != NULL) {
-+ dl_del_list (ohci, !frame);
-+ }
-+ if (ohci->ed_rm_list[frame] != NULL) {
-+ writel (OHCI_INTR_SF, &regs->intrenable);
-+ (void)readl (&regs->intrdisable); /* PCI posting flush */
-+ }
-+ }
-+
-+ /*
-+ * Finally, we are done with trashing about our hardware lists
-+ * and other CPUs are allowed in. The festive flipping of the lock
-+ * ensues as we struggle with the check_timeouts disaster.
-+ */
-+ spin_unlock (&ohci->ohci_lock);
-+
-+ if (!list_empty (&ohci->timeout_list)) {
-+ check_timeouts (ohci);
-+// FIXME: enable SF as needed in a timer;
-+// don't make lots of 1ms interrupts
-+// On unloaded USB, think 4k ~= 4-5msec
-+ if (!list_empty (&ohci->timeout_list))
-+ writel (OHCI_INTR_SF, &regs->intrenable);
-+ }
-+
-+ writel (ints, &regs->intrstatus);
-+ writel (OHCI_INTR_MIE, &regs->intrenable);
-+ (void)readl (&regs->intrdisable); /* PCI posting flush */
-+
-+ ohci_complete(ohci);
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* allocate OHCI */
-+
-+static ohci_t * __devinit hc_alloc_ohci (struct pci_dev *dev, void * mem_base)
-+{
-+ ohci_t * ohci;
-+
-+ ohci = (ohci_t *) kmalloc (sizeof *ohci, GFP_KERNEL);
-+ if (!ohci)
-+ return NULL;
-+
-+ memset (ohci, 0, sizeof (ohci_t));
-+
-+ ohci->hcca = pci_alloc_consistent (dev, sizeof *ohci->hcca,
-+ &ohci->hcca_dma);
-+ if (!ohci->hcca) {
-+ kfree (ohci);
-+ return NULL;
-+ }
-+ memset (ohci->hcca, 0, sizeof (struct ohci_hcca));
-+
-+ ohci->disabled = 1;
-+ ohci->sleeping = 0;
-+ ohci->irq = -1;
-+ ohci->regs = mem_base;
-+
-+ ohci->ohci_dev = dev;
-+ pci_set_drvdata(dev, ohci);
-+
-+ INIT_LIST_HEAD (&ohci->timeout_list);
-+ spin_lock_init(&ohci->ohci_lock);
-+
-+ ohci->bus = usb_alloc_bus (&sohci_device_operations);
-+ if (!ohci->bus) {
-+ pci_set_drvdata (dev, NULL);
-+ pci_free_consistent (ohci->ohci_dev, sizeof *ohci->hcca,
-+ ohci->hcca, ohci->hcca_dma);
-+ kfree (ohci);
-+ return NULL;
-+ }
-+ ohci->bus->bus_name = dev->slot_name;
-+ ohci->bus->hcpriv = (void *) ohci;
-+
-+ return ohci;
-+}
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* De-allocate all resources.. */
-+
-+static void hc_release_ohci (ohci_t * ohci)
-+{
-+ dbg ("USB HC release ohci usb-%s", ohci->ohci_dev->slot_name);
-+
-+ /* disconnect all devices */
-+ if (ohci->bus->root_hub)
-+ usb_disconnect (&ohci->bus->root_hub);
-+
-+ if (!ohci->disabled)
-+ hc_reset (ohci);
-+
-+ if (ohci->irq >= 0) {
-+ free_irq (ohci->irq, ohci);
-+ ohci->irq = -1;
-+ }
-+ pci_set_drvdata(ohci->ohci_dev, NULL);
-+ if (ohci->bus) {
-+ if (ohci->bus->busnum != -1)
-+ usb_deregister_bus (ohci->bus);
-+
-+ usb_free_bus (ohci->bus);
-+ }
-+
-+ ohci_mem_cleanup (ohci);
-+
-+ /* unmap the IO address space */
-+ iounmap (ohci->regs);
-+
-+ pci_free_consistent (ohci->ohci_dev, sizeof *ohci->hcca,
-+ ohci->hcca, ohci->hcca_dma);
-+ kfree (ohci);
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* Increment the module usage count, start the control thread and
-+ * return success. */
-+
-+static struct pci_driver ohci_pci_driver;
-+
-+static int __devinit
-+hc_found_ohci (struct pci_dev *dev, int irq,
-+ void *mem_base, const struct pci_device_id *id)
-+{
-+ ohci_t * ohci;
-+ char buf[8], *bufp = buf;
-+ int ret;
-+
-+#ifndef __sparc__
-+ sprintf(buf, "%d", irq);
-+#else
-+ bufp = __irq_itoa(irq);
-+#endif
-+ printk(KERN_INFO __FILE__ ": USB OHCI at membase 0x%lx, IRQ %s\n",
-+ (unsigned long) mem_base, bufp);
-+ printk(KERN_INFO __FILE__ ": usb-%s, %s\n", dev->slot_name, dev->name);
-+
-+ ohci = hc_alloc_ohci (dev, mem_base);
-+ if (!ohci) {
-+ return -ENOMEM;
-+ }
-+ if ((ret = ohci_mem_init (ohci)) < 0) {
-+ hc_release_ohci (ohci);
-+ return ret;
-+ }
-+ ohci->flags = id->driver_data;
-+
-+ /* Check for NSC87560. We have to look at the bridge (fn1) to identify
-+ the USB (fn2). This quirk might apply to more or even all NSC stuff
-+ I don't know.. */
-+
-+ if(dev->vendor == PCI_VENDOR_ID_NS)
-+ {
-+ struct pci_dev *fn1 = pci_find_slot(dev->bus->number, PCI_DEVFN(PCI_SLOT(dev->devfn), 1));
-+ if(fn1 && fn1->vendor == PCI_VENDOR_ID_NS && fn1->device == PCI_DEVICE_ID_NS_87560_LIO)
-+ ohci->flags |= OHCI_QUIRK_SUCKYIO;
-+
-+ }
-+
-+ if (ohci->flags & OHCI_QUIRK_SUCKYIO)
-+ printk (KERN_INFO __FILE__ ": Using NSC SuperIO setup\n");
-+ if (ohci->flags & OHCI_QUIRK_AMD756)
-+ printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n");
-+
-+ if (hc_reset (ohci) < 0) {
-+ hc_release_ohci (ohci);
-+ return -ENODEV;
-+ }
-+
-+ /* FIXME this is a second HC reset; why?? */
-+ writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control);
-+ (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */
-+ wait_ms (10);
-+
-+ usb_register_bus (ohci->bus);
-+
-+ if (request_irq (irq, hc_interrupt, SA_SHIRQ,
-+ ohci_pci_driver.name, ohci) != 0) {
-+ err ("request interrupt %s failed", bufp);
-+ hc_release_ohci (ohci);
-+ return -EBUSY;
-+ }
-+ ohci->irq = irq;
-+
-+ if (hc_start (ohci) < 0) {
-+ err ("can't start usb-%s", dev->slot_name);
-+ hc_release_ohci (ohci);
-+ return -EBUSY;
-+ }
-+
-+#ifdef DEBUG
-+ ohci_dump (ohci, 1);
-+#endif
-+ return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+#ifdef CONFIG_PM
-+
-+/* controller died; cleanup debris, then restart */
-+/* must not be called from interrupt context */
-+
-+static void hc_restart (ohci_t *ohci)
-+{
-+ int temp;
-+ int i;
-+
-+ if (ohci->pci_latency)
-+ pci_write_config_byte (ohci->ohci_dev, PCI_LATENCY_TIMER, ohci->pci_latency);
-+
-+ ohci->disabled = 1;
-+ ohci->sleeping = 0;
-+ if (ohci->bus->root_hub)
-+ usb_disconnect (&ohci->bus->root_hub);
-+
-+ /* empty the interrupt branches */
-+ for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0;
-+ for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table[i] = 0;
-+
-+ /* no EDs to remove */
-+ ohci->ed_rm_list [0] = NULL;
-+ ohci->ed_rm_list [1] = NULL;
-+
-+ /* empty control and bulk lists */
-+ ohci->ed_isotail = NULL;
-+ ohci->ed_controltail = NULL;
-+ ohci->ed_bulktail = NULL;
-+
-+ if ((temp = hc_reset (ohci)) < 0 || (temp = hc_start (ohci)) < 0) {
-+ err ("can't restart usb-%s, %d", ohci->ohci_dev->slot_name, temp);
-+ } else
-+ dbg ("restart usb-%s completed", ohci->ohci_dev->slot_name);
-+}
-+
-+#endif /* CONFIG_PM */
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* configured so that an OHCI device is always provided */
-+/* always called with process context; sleeping is OK */
-+
-+static int __devinit
-+ohci_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
-+{
-+ unsigned long mem_resource, mem_len;
-+ void *mem_base;
-+ int status;
-+
-+ if (pci_enable_device(dev) < 0)
-+ return -ENODEV;
-+
-+ if (!dev->irq) {
-+ err("found OHCI device with no IRQ assigned. check BIOS settings!");
-+ pci_disable_device (dev);
-+ return -ENODEV;
-+ }
-+
-+ /* we read its hardware registers as memory */
-+ mem_resource = pci_resource_start(dev, 0);
-+ mem_len = pci_resource_len(dev, 0);
-+ if (!request_mem_region (mem_resource, mem_len, ohci_pci_driver.name)) {
-+ dbg ("controller already in use");
-+ pci_disable_device (dev);
-+ return -EBUSY;
-+ }
-+
-+ mem_base = ioremap_nocache (mem_resource, mem_len);
-+ if (!mem_base) {
-+ err("Error mapping OHCI memory");
-+ release_mem_region (mem_resource, mem_len);
-+ pci_disable_device (dev);
-+ return -EFAULT;
-+ }
-+
-+ /* controller writes into our memory */
-+ pci_set_master (dev);
-+
-+ status = hc_found_ohci (dev, dev->irq, mem_base, id);
-+ if (status < 0) {
-+ iounmap (mem_base);
-+ release_mem_region (mem_resource, mem_len);
-+ pci_disable_device (dev);
-+ }
-+ return status;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* may be called from interrupt context [interface spec] */
-+/* may be called without controller present */
-+/* may be called with controller, bus, and devices active */
-+
-+static void __devexit
-+ohci_pci_remove (struct pci_dev *dev)
-+{
-+ ohci_t *ohci = pci_get_drvdata(dev);
-+
-+ dbg ("remove %s controller usb-%s%s%s",
-+ hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
-+ dev->slot_name,
-+ ohci->disabled ? " (disabled)" : "",
-+ in_interrupt () ? " in interrupt" : ""
-+ );
-+#ifdef DEBUG
-+ ohci_dump (ohci, 1);
-+#endif
-+
-+ /* don't wake up sleeping controllers, or block in interrupt context */
-+ if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER || in_interrupt ()) {
-+ dbg ("controller being disabled");
-+ ohci->disabled = 1;
-+ }
-+
-+ /* on return, USB will always be reset (if present) */
-+ if (ohci->disabled)
-+ writel (ohci->hc_control = OHCI_USB_RESET,
-+ &ohci->regs->control);
-+
-+ hc_release_ohci (ohci);
-+
-+ release_mem_region (pci_resource_start (dev, 0), pci_resource_len (dev, 0));
-+ pci_disable_device (dev);
-+}
-+
-+
-+#ifdef CONFIG_PM
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int
-+ohci_pci_suspend (struct pci_dev *dev, u32 state)
-+{
-+ ohci_t *ohci = pci_get_drvdata(dev);
-+ unsigned long flags;
-+ u16 cmd;
-+
-+ if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) {
-+ dbg ("can't suspend usb-%s (state is %s)", dev->slot_name,
-+ hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS));
-+ return -EIO;
-+ }
-+
-+ /* act as if usb suspend can always be used */
-+ info ("USB suspend: usb-%s", dev->slot_name);
-+ ohci->sleeping = 1;
-+
-+ /* First stop processing */
-+ spin_lock_irqsave (&ohci->ohci_lock, flags);
-+ ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE);
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
-+ (void) readl (&ohci->regs->intrstatus);
-+ spin_unlock_irqrestore (&ohci->ohci_lock, flags);
-+
-+ /* Wait a frame or two */
-+ mdelay(1);
-+ if (!readl (&ohci->regs->intrstatus) & OHCI_INTR_SF)
-+ mdelay (1);
-+
-+#ifdef CONFIG_PMAC_PBOOK
-+ if (_machine == _MACH_Pmac)
-+ disable_irq (ohci->irq);
-+ /* else, 2.4 assumes shared irqs -- don't disable */
-+#endif
-+ /* Enable remote wakeup */
-+ writel (readl(&ohci->regs->intrenable) | OHCI_INTR_RD, &ohci->regs->intrenable);
-+
-+ /* Suspend chip and let things settle down a bit */
-+ ohci->hc_control = OHCI_USB_SUSPEND;
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ (void) readl (&ohci->regs->control);
-+ mdelay (500); /* No schedule here ! */
-+ switch (readl (&ohci->regs->control) & OHCI_CTRL_HCFS) {
-+ case OHCI_USB_RESET:
-+ dbg("Bus in reset phase ???");
-+ break;
-+ case OHCI_USB_RESUME:
-+ dbg("Bus in resume phase ???");
-+ break;
-+ case OHCI_USB_OPER:
-+ dbg("Bus in operational phase ???");
-+ break;
-+ case OHCI_USB_SUSPEND:
-+ dbg("Bus suspended");
-+ break;
-+ }
-+ /* In some rare situations, Apple's OHCI have happily trashed
-+ * memory during sleep. We disable it's bus master bit during
-+ * suspend
-+ */
-+ pci_read_config_word (dev, PCI_COMMAND, &cmd);
-+ cmd &= ~PCI_COMMAND_MASTER;
-+ pci_write_config_word (dev, PCI_COMMAND, cmd);
-+#ifdef CONFIG_PMAC_PBOOK
-+ {
-+ struct device_node *of_node;
-+
-+ /* Disable USB PAD & cell clock */
-+ of_node = pci_device_to_OF_node (ohci->ohci_dev);
-+ if (of_node)
-+ pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
-+ }
-+#endif
-+ return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int
-+ohci_pci_resume (struct pci_dev *dev)
-+{
-+ ohci_t *ohci = pci_get_drvdata(dev);
-+ int temp;
-+ unsigned long flags;
-+
-+ /* guard against multiple resumes */
-+ atomic_inc (&ohci->resume_count);
-+ if (atomic_read (&ohci->resume_count) != 1) {
-+ err ("concurrent PCI resumes for usb-%s", dev->slot_name);
-+ atomic_dec (&ohci->resume_count);
-+ return 0;
-+ }
-+
-+#ifdef CONFIG_PMAC_PBOOK
-+ {
-+ struct device_node *of_node;
-+
-+ /* Re-enable USB PAD & cell clock */
-+ of_node = pci_device_to_OF_node (ohci->ohci_dev);
-+ if (of_node)
-+ pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 1);
-+ }
-+#endif
-+
-+ /* did we suspend, or were we powered off? */
-+ ohci->hc_control = readl (&ohci->regs->control);
-+ temp = ohci->hc_control & OHCI_CTRL_HCFS;
-+
-+#ifdef DEBUG
-+ /* the registers may look crazy here */
-+ ohci_dump_status (ohci);
-+#endif
-+
-+ /* Re-enable bus mastering */
-+ pci_set_master(ohci->ohci_dev);
-+
-+ switch (temp) {
-+
-+ case OHCI_USB_RESET: // lost power
-+ info ("USB restart: usb-%s", dev->slot_name);
-+ hc_restart (ohci);
-+ break;
-+
-+ case OHCI_USB_SUSPEND: // host wakeup
-+ case OHCI_USB_RESUME: // remote wakeup
-+ info ("USB continue: usb-%s from %s wakeup", dev->slot_name,
-+ (temp == OHCI_USB_SUSPEND)
-+ ? "host" : "remote");
-+ ohci->hc_control = OHCI_USB_RESUME;
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ (void) readl (&ohci->regs->control);
-+ mdelay (20); /* no schedule here ! */
-+ /* Some controllers (lucent) need a longer delay here */
-+ mdelay (15);
-+ temp = readl (&ohci->regs->control);
-+ temp = ohci->hc_control & OHCI_CTRL_HCFS;
-+ if (temp != OHCI_USB_RESUME) {
-+ err ("controller usb-%s won't resume", dev->slot_name);
-+ ohci->disabled = 1;
-+ return -EIO;
-+ }
-+
-+ /* Some chips likes being resumed first */
-+ writel (OHCI_USB_OPER, &ohci->regs->control);
-+ (void) readl (&ohci->regs->control);
-+ mdelay (3);
-+
-+ /* Then re-enable operations */
-+ spin_lock_irqsave (&ohci->ohci_lock, flags);
-+ ohci->disabled = 0;
-+ ohci->sleeping = 0;
-+ ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
-+ if (!ohci->ed_rm_list[0] && !ohci->ed_rm_list[1]) {
-+ if (ohci->ed_controltail)
-+ ohci->hc_control |= OHCI_CTRL_CLE;
-+ if (ohci->ed_bulktail)
-+ ohci->hc_control |= OHCI_CTRL_BLE;
-+ }
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
-+ writel (OHCI_INTR_SF, &ohci->regs->intrenable);
-+ /* Check for a pending done list */
-+ writel (OHCI_INTR_WDH, &ohci->regs->intrdisable);
-+ (void) readl (&ohci->regs->intrdisable);
-+#ifdef CONFIG_PMAC_PBOOK
-+ if (_machine == _MACH_Pmac)
-+ enable_irq (ohci->irq);
-+#endif
-+ if (ohci->hcca->done_head)
-+ dl_done_list (ohci, dl_reverse_done_list (ohci));
-+ writel (OHCI_INTR_WDH, &ohci->regs->intrenable);
-+ writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
-+ writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
-+ spin_unlock_irqrestore (&ohci->ohci_lock, flags);
-+ break;
-+
-+ default:
-+ warn ("odd PCI resume for usb-%s", dev->slot_name);
-+ }
-+
-+ /* controller is operational, extra resumes are harmless */
-+ atomic_dec (&ohci->resume_count);
-+
-+ return 0;
-+}
-+
-+#endif /* CONFIG_PM */
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static const struct pci_device_id __devinitdata ohci_pci_ids [] = { {
-+
-+ /*
-+ * AMD-756 [Viper] USB has a serious erratum when used with
-+ * lowspeed devices like mice.
-+ */
-+ vendor: 0x1022,
-+ device: 0x740c,
-+ subvendor: PCI_ANY_ID,
-+ subdevice: PCI_ANY_ID,
-+
-+ driver_data: OHCI_QUIRK_AMD756,
-+
-+} , {
-+
-+ /* handle any USB OHCI controller */
-+ class: ((PCI_CLASS_SERIAL_USB << 8) | 0x10),
-+ class_mask: ~0,
-+
-+ /* no matter who makes it */
-+ vendor: PCI_ANY_ID,
-+ device: PCI_ANY_ID,
-+ subvendor: PCI_ANY_ID,
-+ subdevice: PCI_ANY_ID,
-+
-+ }, { /* end: all zeroes */ }
-+};
-+
-+MODULE_DEVICE_TABLE (pci, ohci_pci_ids);
-+
-+static struct pci_driver ohci_pci_driver = {
-+ name: "usb-ohci",
-+ id_table: &ohci_pci_ids [0],
-+
-+ probe: ohci_pci_probe,
-+ remove: __devexit_p(ohci_pci_remove),
-+
-+#ifdef CONFIG_PM
-+ suspend: ohci_pci_suspend,
-+ resume: ohci_pci_resume,
-+#endif /* PM */
-+};
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int __init ohci_hcd_init (void)
-+{
-+ return pci_module_init (&ohci_pci_driver);
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static void __exit ohci_hcd_cleanup (void)
-+{
-+ pci_unregister_driver (&ohci_pci_driver);
-+}
-+
-+module_init (ohci_hcd_init);
-+module_exit (ohci_hcd_cleanup);
-+
-+
-+MODULE_AUTHOR( DRIVER_AUTHOR );
-+MODULE_DESCRIPTION( DRIVER_DESC );
-+MODULE_LICENSE("GPL");
diff --git a/linux/linux-mtx-1-2.4.27/09-au1000-eth-vlan.diff b/linux/linux-mtx-1-2.4.27/09-au1000-eth-vlan.diff
deleted file mode 100644
index 2f09c02d5a..0000000000
--- a/linux/linux-mtx-1-2.4.27/09-au1000-eth-vlan.diff
+++ /dev/null
@@ -1,10 +0,0 @@
---- linux/drivers/net/au1000_eth.c.orig 2004-11-18 13:44:52.163605416 +0100
-+++ linux/drivers/net/au1000_eth.c 2004-11-18 13:51:42.096286176 +0100
-@@ -1389,6 +1389,7 @@
- control |= MAC_FULL_DUPLEX;
- }
- aup->mac->control = control;
-+ aup->mac->vlan1_tag = 0x8100; /* activate vlan support */
- au_sync();
-
- spin_unlock_irqrestore(&aup->lock, flags);
diff --git a/linux/linux-mtx-1-2.4.27/10-iw-max-spy-32.diff b/linux/linux-mtx-1-2.4.27/10-iw-max-spy-32.diff
deleted file mode 100644
index e782d3d3dc..0000000000
--- a/linux/linux-mtx-1-2.4.27/10-iw-max-spy-32.diff
+++ /dev/null
@@ -1,11 +0,0 @@
---- linux-mips-2.4.24-pre2/include/linux/wireless.h 2004-11-17 18:05:09.000000000 +0100
-+++ linux/include/linux/wireless.h 2004-11-17 19:02:44.370081592 +0100
-@@ -334,7 +334,7 @@
- * a few of them in the struct iw_range. */
-
- /* Maximum of address that you may set with SPY */
--#define IW_MAX_SPY 8
-+#define IW_MAX_SPY 32
-
- /* Maximum of address that you may get in the
- list of access points in range */
diff --git a/linux/linux-mtx-1-2.4.27/11-mtd-proc-partition-rw.diff b/linux/linux-mtx-1-2.4.27/11-mtd-proc-partition-rw.diff
deleted file mode 100644
index 54ba5fff98..0000000000
--- a/linux/linux-mtx-1-2.4.27/11-mtd-proc-partition-rw.diff
+++ /dev/null
@@ -1,173 +0,0 @@
-diff -Nurb linux/drivers/mtd/mtdcore.c linux-mtd-rw/drivers/mtd/mtdcore.c
---- linux/drivers/mtd/mtdcore.c 2004-11-18 13:16:00.000000000 +0100
-+++ linux-mtd-rw/drivers/mtd/mtdcore.c 2004-11-18 15:27:13.130036616 +0100
-@@ -25,6 +25,10 @@
-
- #include <linux/mtd/mtd.h>
-
-+/* this symbol is exported by the procfs. */
-+extern struct proc_dir_entry *proc_sys_root;
-+
-+
- /* These are exported solely for the purpose of mtd_blkdevs.c. You
- should not use them for _anything_ else */
- DECLARE_MUTEX(mtd_table_mutex);
-@@ -336,8 +340,83 @@
-
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
- static struct proc_dir_entry *proc_mtd;
-+
-+static struct proc_dir_entry *proc_sys_mtd;
-+static struct proc_dir_entry *proc_sys_mtd_partition[MAX_MTD_DEVICES];
-+static struct proc_dir_entry *proc_sys_mtd_partition_rw[MAX_MTD_DEVICES];
- #endif
-
-+/*===================================0
-+ * mtdproc_read_partition_access
-+ */
-+static int mtdproc_read_partition_access ( char *page, char **start, off_t off,int count,
-+ int *eof, void *data
-+ )
-+{
-+ int partid = (unsigned int)data;
-+ int len = 0;
-+
-+ // NO RETURN FROM HERE UNTIL "up(&mtd_table_mutex)".
-+ down(&mtd_table_mutex);
-+
-+ if (partid < MAX_MTD_DEVICES)
-+ {
-+ struct mtd_info *this = mtd_table[partid];
-+ if (this)
-+ {
-+ page[len] = (this->flags & MTD_WRITEABLE) ? '1' : '0';
-+ len++;
-+ }
-+ }
-+
-+ up(&mtd_table_mutex);
-+
-+ if (off >= len)
-+ return 0;
-+ *start = page + off;
-+ return ((count < len-off) ? count : len-off);
-+}
-+
-+
-+static int mtdproc_write_partition_access (struct file *file, const char *buffer,
-+ unsigned long count, void *data)
-+{
-+ int partid = (unsigned int)data;
-+ int len = 0;
-+
-+ // NO RETURN FROM HERE UNTIL "up(&mtd_table_mutex)".
-+ down(&mtd_table_mutex);
-+
-+ if (partid < MAX_MTD_DEVICES)
-+ {
-+ struct mtd_info *this = mtd_table[partid];
-+ if (this && count > 0)
-+ {
-+ switch (*buffer)
-+ {
-+ case '0':
-+ this->flags &= ~(this->master_flags & MTD_WRITEABLE);
-+ break;
-+
-+ case '1':
-+ this->flags |= ~(this->master_flags & MTD_WRITEABLE);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+ }
-+ }
-+
-+ up(&mtd_table_mutex);
-+
-+ return count;
-+}
-+
-+
-+
-+
-+
- static inline int mtd_proc_info (char *buf, int i)
- {
- struct mtd_info *this = mtd_table[i];
-@@ -349,6 +428,7 @@
- this->erasesize, this->name);
- }
-
-+
- static int mtd_read_proc ( char *page, char **start, off_t off,int count
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
- ,int *eof, void *data_unused
-@@ -404,12 +484,31 @@
- /*====================================================================*/
- /* Init code */
-
-+
- int __init init_mtd(void)
- {
- #ifdef CONFIG_PROC_FS
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
-+ int i;
-+
- if ((proc_mtd = create_proc_entry( "mtd", 0, 0 )))
- proc_mtd->read_proc = mtd_read_proc;
-+
-+ proc_sys_mtd = proc_mkdir("mtd", proc_sys_root);
-+ for (i=0; i<MAX_MTD_DEVICES; i++)
-+ {
-+ char partname[10];
-+ sprintf (partname, "%d", i);
-+
-+ proc_sys_mtd_partition[i] = proc_mkdir(partname, proc_sys_mtd);
-+ proc_sys_mtd_partition_rw[i] = create_proc_entry ("rw", S_IFREG | S_IRUGO, proc_sys_mtd_partition[i]);
-+ if (proc_sys_mtd_partition_rw[i])
-+ {
-+ proc_sys_mtd_partition_rw[i]->read_proc = mtdproc_read_partition_access;
-+ proc_sys_mtd_partition_rw[i]->write_proc = mtdproc_write_partition_access;
-+ proc_sys_mtd_partition_rw[i]->data = (void *)i;
-+ }
-+ }
- #else
- proc_register_dynamic(&proc_root,&mtd_proc_entry);
- #endif
-@@ -425,6 +524,8 @@
- return 0;
- }
-
-+
-+
- static void __exit cleanup_mtd(void)
- {
- #ifdef CONFIG_PM
-diff -Nurb linux/drivers/mtd/mtdpart.c linux-mtd-rw/drivers/mtd/mtdpart.c
---- linux/drivers/mtd/mtdpart.c 2004-11-18 13:16:00.000000000 +0100
-+++ linux-mtd-rw/drivers/mtd/mtdpart.c 2004-11-18 15:27:13.131036464 +0100
-@@ -341,6 +341,9 @@
- /* set up the MTD object for this partition */
- slave->mtd.type = master->type;
- slave->mtd.flags = master->flags & ~parts[i].mask_flags;
-+ slave->mtd.master_flags = master->flags;
-+ slave->mtd.mask_flags = parts[i].mask_flags;
-+
- slave->mtd.size = parts[i].size;
- slave->mtd.oobblock = master->oobblock;
- slave->mtd.oobsize = master->oobsize;
-diff -Nurb linux/include/linux/mtd/mtd.h linux-mtd-rw/include/linux/mtd/mtd.h
---- linux/include/linux/mtd/mtd.h 2004-11-18 13:16:31.000000000 +0100
-+++ linux-mtd-rw/include/linux/mtd/mtd.h 2004-11-18 15:27:13.000000000 +0100
-@@ -232,6 +232,9 @@
-
- struct module *owner;
- int usecount;
-+
-+ u_int32_t master_flags;
-+ u_int32_t mask_flags;
- };
-
-
diff --git a/linux/linux-mtx-1-2.4.27/12-openswan-2.2.0-nat-t.diff b/linux/linux-mtx-1-2.4.27/12-openswan-2.2.0-nat-t.diff
deleted file mode 100644
index 2a18d605bf..0000000000
--- a/linux/linux-mtx-1-2.4.27/12-openswan-2.2.0-nat-t.diff
+++ /dev/null
@@ -1,143 +0,0 @@
-diff -Nurb linux-08/include/net/sock.h linux/include/net/sock.h
---- linux-08/include/net/sock.h 2004-11-19 11:37:23.376715120 +0100
-+++ linux/include/net/sock.h 2004-11-19 11:39:29.874484536 +0100
-@@ -256,6 +256,13 @@
- __u32 end_seq;
- };
-
-+#if 1
-+#define UDP_OPT_IN_SOCK 1
-+struct udp_opt {
-+ __u32 esp_in_udp;
-+};
-+#endif
-+
- struct tcp_opt {
- int tcp_header_len; /* Bytes of tcp header to send */
-
-@@ -648,6 +655,9 @@
- #if defined(CONFIG_SPX) || defined (CONFIG_SPX_MODULE)
- struct spx_opt af_spx;
- #endif /* CONFIG_SPX */
-+#if 1
-+ struct udp_opt af_udp;
-+#endif
-
- } tp_pinfo;
-
-diff -Nurb linux-08/net/Config.in linux/net/Config.in
---- linux-08/net/Config.in 2004-11-19 11:37:23.770655232 +0100
-+++ linux/net/Config.in 2004-11-19 11:39:29.874484536 +0100
-@@ -102,4 +102,6 @@
- dep_tristate 'Packet Generator (USE WITH CAUTION)' CONFIG_NET_PKTGEN $CONFIG_PROC_FS
- endmenu
-
-+bool 'IPSEC NAT-Traversal' CONFIG_IPSEC_NAT_TRAVERSAL
-+
- endmenu
-diff -Nurb linux-08/net/ipv4/udp.c linux/net/ipv4/udp.c
---- linux-08/net/ipv4/udp.c 2004-11-19 11:37:23.897635928 +0100
-+++ linux/net/ipv4/udp.c 2004-11-19 11:39:29.875484384 +0100
-@@ -810,6 +810,9 @@
-
- static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
- {
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ struct udp_opt *tp = &(sk->tp_pinfo.af_udp);
-+#endif
- /*
- * Charge it to the socket, dropping if the queue is full.
- */
-@@ -827,6 +830,40 @@
- }
- #endif
-
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if (tp->esp_in_udp) {
-+ /*
-+ * Set skb->sk and xmit packet to ipsec_rcv.
-+ *
-+ * If ret != 0, ipsec_rcv refused the packet (not ESPinUDP),
-+ * restore skb->sk and fall back to sock_queue_rcv_skb
-+ */
-+ struct inet_protocol *esp = NULL;
-+
-+#if defined(CONFIG_IPSEC) && !defined(CONFIG_IPSEC_MODULE)
-+ /* optomize only when we know it is statically linked */
-+ extern struct inet_protocol esp_protocol;
-+ esp = &esp_protocol;
-+#else
-+ for (esp = (struct inet_protocol *)inet_protos[IPPROTO_ESP & (MAX_INET_PROTOS - 1)];
-+ (esp) && (esp->protocol != IPPROTO_ESP);
-+ esp = esp->next);
-+#endif
-+
-+ if (esp && esp->handler) {
-+ struct sock *sav_sk = skb->sk;
-+ skb->sk = sk;
-+ if (esp->handler(skb) == 0) {
-+ skb->sk = sav_sk;
-+ /*not sure we might count ESPinUDP as UDP...*/
-+ UDP_INC_STATS_BH(UdpInDatagrams);
-+ return 0;
-+ }
-+ skb->sk = sav_sk;
-+ }
-+ }
-+#endif
-+
- if (sock_queue_rcv_skb(sk,skb)<0) {
- UDP_INC_STATS_BH(UdpInErrors);
- IP_INC_STATS_BH(IpInDiscards);
-@@ -1050,13 +1087,49 @@
- return len;
- }
-
-+static int udp_setsockopt(struct sock *sk, int level, int optname,
-+ char *optval, int optlen)
-+{
-+ struct udp_opt *tp = &(sk->tp_pinfo.af_udp);
-+ int val;
-+ int err = 0;
-+
-+ if (level != SOL_UDP)
-+ return ip_setsockopt(sk, level, optname, optval, optlen);
-+
-+ if(optlen<sizeof(int))
-+ return -EINVAL;
-+
-+ if (get_user(val, (int *)optval))
-+ return -EFAULT;
-+
-+ lock_sock(sk);
-+
-+ switch(optname) {
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+#ifndef UDP_ESPINUDP
-+#define UDP_ESPINUDP 100
-+#endif
-+ case UDP_ESPINUDP:
-+ tp->esp_in_udp = val;
-+ break;
-+#endif
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
- struct proto udp_prot = {
- name: "UDP",
- close: udp_close,
- connect: udp_connect,
- disconnect: udp_disconnect,
- ioctl: udp_ioctl,
-- setsockopt: ip_setsockopt,
-+ setsockopt: udp_setsockopt,
- getsockopt: ip_getsockopt,
- sendmsg: udp_sendmsg,
- recvmsg: udp_recvmsg,
-
diff --git a/linux/linux-mtx-1-2.4.27/13-openswan-2.2.0.patch b/linux/linux-mtx-1-2.4.27/13-openswan-2.2.0.patch
deleted file mode 100644
index db64219eda..0000000000
--- a/linux/linux-mtx-1-2.4.27/13-openswan-2.2.0.patch
+++ /dev/null
@@ -1,61573 +0,0 @@
-make[1]: Entering directory `/data/mtx/oe/tmp/work/openswan-2.2.0-r0/openswan-2.2.0'
-packaging/utils/kernelpatch 2.4
---- linux/Documentation/Configure.help.orig Fri Dec 21 12:41:53 2001
-+++ linux/Documentation/Configure.help Mon Jul 29 16:35:32 2002
-@@ -24237,5 +24237,65 @@
-
--#
-+IP Security Protocol (IPSEC) (EXPERIMENTAL)
-+CONFIG_IPSEC
-+ This unit is experimental code.
-+ Pick 'y' for static linking, 'm' for module support or 'n' for none.
-+ This option adds support for network layer packet encryption and/or
-+ authentication with participating hosts. The standards start with:
-+ RFCs 2411, 2407 and 2401. Others are mentioned where they refer to
-+ specific features below. There are more pending which can be found
-+ at: ftp://ftp.ietf.org/internet-drafts/draft-ietf-ipsec-*.
-+ A description of each document can also be found at:
-+ http://ietf.org/ids.by.wg/ipsec.html.
-+ Their charter can be found at:
-+ http://www.ietf.org/html.charters/ipsec-charter.html
-+ Snapshots and releases of the current work can be found at:
-+ http://www.freeswan.org/
-+
-+IPSEC: IP-in-IP encapsulation
-+CONFIG_IPSEC_IPIP
-+ This option provides support for tunnel mode IPSEC. It is recommended
-+ to enable this.
-+
-+IPSEC: Authentication Header
-+CONFIG_IPSEC_AH
-+ This option provides support for the IPSEC Authentication Header
-+ (IP protocol 51) which provides packet layer sender and content
-+ authentication. It is recommended to enable this. RFC2402
-+
-+HMAC-MD5 algorithm
-+CONFIG_IPSEC_AUTH_HMAC_MD5
-+ Provides support for authentication using the HMAC MD5
-+ algorithm with 96 bits of hash used as the authenticator. RFC2403
-+
-+HMAC-SHA1 algorithm
-+CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ Provides support for Authentication Header using the HMAC SHA1
-+ algorithm with 96 bits of hash used as the authenticator. RFC2404
-+
-+IPSEC: Encapsulating Security Payload
-+CONFIG_IPSEC_ESP
-+ This option provides support for the IPSEC Encapsulation Security
-+ Payload (IP protocol 50) which provides packet layer content
-+ hiding. It is recommended to enable this. RFC2406
-+
-+3DES algorithm
-+CONFIG_IPSEC_ENC_3DES
-+ Provides support for Encapsulation Security Payload protocol, using
-+ the triple DES encryption algorithm. RFC2451
-+
-+IPSEC Debugging Option
-+CONFIG_IPSEC_DEBUG
-+ Enables IPSEC kernel debugging. It is further controlled by the
-+ user space utility 'klipsdebug'.
-+
-+IPSEC Regression Testing option
-+CONFIG_IPSEC_REGRESS
-+ Enables IPSEC regression testing. Creates a number of switches in
-+ /proc/sys/net/ipsec which cause various failure modes in KLIPS.
-+ For more details see FreeSWAN source under
-+ testing/doc/regression_options.txt.
-+
-+#
- # A couple of things I keep forgetting:
- # capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet,
- # Intel, IRQ, ISDN, Linux, MSDOS, NetWare, NetWinder,
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/README.openswan-2 Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,112 @@
-+*
-+* RCSID $Id$
-+*
-+
-+ ****************************************
-+ * IPSEC for Linux, Release 2.xx series *
-+ ****************************************
-+
-+
-+
-+1. Files
-+
-+The contents of linux/net/ipsec/ (see below) join the linux kernel source tree.
-+as provided for higher up.
-+
-+The programs/ directory contains the user-level utilities which you need
-+to run IPSEC. See the top-level top/INSTALL to compile and install them.
-+
-+The testing/ directory contains test scripts.
-+
-+The doc/ directory contains -- what else -- documentation.
-+
-+1.1. Kernel files
-+
-+The following are found in net/ipsec/:
-+
-+Makefile The Makefile
-+Config.in The configuration script for make menuconfig
-+defconfig Configuration defaults for first time.
-+
-+radij.c General-purpose radix-tree operations
-+
-+ipsec_ipcomp.c IPCOMP encapsulate/decapsulate code.
-+ipsec_ah.c Authentication Header (AH) encapsulate/decapsulate code.
-+ipsec_esp.c Encapsulated Security Payload (ESP) encap/decap code.
-+
-+pfkey_v2.c PF_KEYv2 socket interface code.
-+pfkey_v2_parser.c PF_KEYv2 message parsing and processing code.
-+
-+ipsec_init.c Initialization code, /proc interface.
-+ipsec_radij.c Interface with the radix tree code.
-+ipsec_netlink.c Interface with the netlink code.
-+ipsec_xform.c Routines and structures common to transforms.
-+ipsec_tunnel.c The outgoing packet processing code.
-+ipsec_rcv.c The incoming packet processing code.
-+ipsec_md5c.c Somewhat modified RSADSI MD5 C code.
-+ipsec_sha1.c Somewhat modified Steve Reid SHA-1 C code.
-+
-+sysctl_net_ipsec.c /proc/sys/net/ipsec/* variable definitions.
-+
-+version.c symbolic link to project version.
-+
-+radij.h Headers for radij.c
-+
-+ipcomp.h Headers used by IPCOMP code.
-+
-+ipsec_radij.h Interface with the radix tree code.
-+ipsec_netlink.h Headers used by the netlink interface.
-+ipsec_encap.h Headers defining encapsulation structures.
-+ipsec_xform.h Transform headers.
-+ipsec_tunnel.h Headers used by tunneling code.
-+ipsec_ipe4.h Headers for the IP-in-IP code.
-+ipsec_ah.h Headers common to AH transforms.
-+ipsec_md5h.h RSADSI MD5 headers.
-+ipsec_sha1.h SHA-1 headers.
-+ipsec_esp.h Headers common to ESP transfroms.
-+ipsec_rcv.h Headers for incoming packet processing code.
-+
-+1.2. User-level files.
-+
-+The following are found in utils/:
-+
-+eroute.c Create an "extended route" source code
-+spi.c Set up Security Associations source code
-+spigrp.c Link SPIs together source code.
-+tncfg.c Configure the tunneling features of the virtual interface
-+ source code
-+klipsdebug.c Set/reset klips debugging features source code.
-+version.c symbolic link to project version.
-+
-+eroute.8 Create an "extended route" manual page
-+spi.8 Set up Security Associations manual page
-+spigrp.8 Link SPIs together manual page
-+tncfg.8 Configure the tunneling features of the virtual interface
-+ manual page
-+klipsdebug.8 Set/reset klips debugging features manual page
-+
-+eroute.5 /proc/net/ipsec_eroute format manual page
-+spi.5 /proc/net/ipsec_spi format manual page
-+spigrp.5 /proc/net/ipsec_spigrp format manual page
-+tncfg.5 /proc/net/ipsec_tncfg format manual page
-+klipsdebug.5 /proc/net/ipsec_klipsdebug format manual page
-+version.5 /proc/net/ipsec_version format manual page
-+pf_key.5 /proc/net/pf_key format manual page
-+
-+Makefile Utilities makefile.
-+
-+*.8 Manpages for the respective utils.
-+
-+
-+1.3. Test files
-+
-+The test scripts are locate in testing/ and and documentation is found
-+at doc/src/umltesting.html. Automated testing via "make check" is available
-+provided that the User-Mode-Linux patches are available.
-+
-+*
-+* $Log$
-+* Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+* Turn off EOLN_NATIVE flag
-+*
-+* (Logical change 1.5010)
-+*
-+* Revision 1.1 2003/12/10 01:07:49 mcr
-+* documentation for additions.
-+*
-+*
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/aes/Makefile.objs Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,13 @@
-+
-+ASM-$(ARCH_ASM):=1
-+ASM_X86:=$(ASM-i586)$(ASM-i686)
-+
-+ifneq ($(strip $(ASM_X86)),)
-+obj-$(CONFIG_IPSEC_ENC_AES) += aes-i586.o
-+else
-+obj-$(CONFIG_IPSEC_ENC_AES) += aes.o
-+endif
-+
-+obj-$(CONFIG_IPSEC_ENC_AES) += aes_cbc.o
-+obj-$(CONFIG_IPSEC_ENC_AES) += aes_xcbc_mac.o
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/aes/aes-i586.S Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,892 @@
-+//
-+// Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
-+// All rights reserved.
-+//
-+// TERMS
-+//
-+// Redistribution and use in source and binary forms, with or without
-+// modification, are permitted subject to the following conditions:
-+//
-+// 1. Redistributions of source code must retain the above copyright
-+// notice, this list of conditions and the following disclaimer.
-+//
-+// 2. Redistributions in binary form must reproduce the above copyright
-+// notice, this list of conditions and the following disclaimer in the
-+// documentation and/or other materials provided with the distribution.
-+//
-+// 3. The copyright holder's name must not be used to endorse or promote
-+// any products derived from this software without his specific prior
-+// written permission.
-+//
-+// This software is provided 'as is' with no express or implied warranties
-+// of correctness or fitness for purpose.
-+
-+// Modified by Jari Ruusu, December 24 2001
-+// - Converted syntax to GNU CPP/assembler syntax
-+// - C programming interface converted back to "old" API
-+// - Minor portability cleanups and speed optimizations
-+
-+// An AES (Rijndael) implementation for the Pentium. This version only
-+// implements the standard AES block length (128 bits, 16 bytes). This code
-+// does not preserve the eax, ecx or edx registers or the artihmetic status
-+// flags. However, the ebx, esi, edi, and ebp registers are preserved across
-+// calls.
-+
-+// void aes_set_key(aes_context *cx, const unsigned char key[], const int key_len, const int f)
-+// void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
-+// void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
-+
-+#if defined(USE_UNDERLINE)
-+# define aes_set_key _aes_set_key
-+# define aes_encrypt _aes_encrypt
-+# define aes_decrypt _aes_decrypt
-+#endif
-+#if !defined(ALIGN32BYTES)
-+# define ALIGN32BYTES 32
-+#endif
-+
-+ .file "aes-i586.S"
-+ .globl aes_set_key
-+ .globl aes_encrypt
-+ .globl aes_decrypt
-+
-+#define tlen 1024 // length of each of 4 'xor' arrays (256 32-bit words)
-+
-+// offsets to parameters with one register pushed onto stack
-+
-+#define ctx 8 // AES context structure
-+#define in_blk 12 // input byte array address parameter
-+#define out_blk 16 // output byte array address parameter
-+
-+// offsets in context structure
-+
-+#define nkey 0 // key length, size 4
-+#define nrnd 4 // number of rounds, size 4
-+#define ekey 8 // encryption key schedule base address, size 256
-+#define dkey 264 // decryption key schedule base address, size 256
-+
-+// This macro performs a forward encryption cycle. It is entered with
-+// the first previous round column values in %eax, %ebx, %esi and %edi and
-+// exits with the final values in the same registers.
-+
-+#define fwd_rnd(p1,p2) \
-+ mov %ebx,(%esp) ;\
-+ movzbl %al,%edx ;\
-+ mov %eax,%ecx ;\
-+ mov p2(%ebp),%eax ;\
-+ mov %edi,4(%esp) ;\
-+ mov p2+12(%ebp),%edi ;\
-+ xor p1(,%edx,4),%eax ;\
-+ movzbl %ch,%edx ;\
-+ shr $16,%ecx ;\
-+ mov p2+4(%ebp),%ebx ;\
-+ xor p1+tlen(,%edx,4),%edi ;\
-+ movzbl %cl,%edx ;\
-+ movzbl %ch,%ecx ;\
-+ xor p1+3*tlen(,%ecx,4),%ebx ;\
-+ mov %esi,%ecx ;\
-+ mov p1+2*tlen(,%edx,4),%esi ;\
-+ movzbl %cl,%edx ;\
-+ xor p1(,%edx,4),%esi ;\
-+ movzbl %ch,%edx ;\
-+ shr $16,%ecx ;\
-+ xor p1+tlen(,%edx,4),%ebx ;\
-+ movzbl %cl,%edx ;\
-+ movzbl %ch,%ecx ;\
-+ xor p1+2*tlen(,%edx,4),%eax ;\
-+ mov (%esp),%edx ;\
-+ xor p1+3*tlen(,%ecx,4),%edi ;\
-+ movzbl %dl,%ecx ;\
-+ xor p2+8(%ebp),%esi ;\
-+ xor p1(,%ecx,4),%ebx ;\
-+ movzbl %dh,%ecx ;\
-+ shr $16,%edx ;\
-+ xor p1+tlen(,%ecx,4),%eax ;\
-+ movzbl %dl,%ecx ;\
-+ movzbl %dh,%edx ;\
-+ xor p1+2*tlen(,%ecx,4),%edi ;\
-+ mov 4(%esp),%ecx ;\
-+ xor p1+3*tlen(,%edx,4),%esi ;\
-+ movzbl %cl,%edx ;\
-+ xor p1(,%edx,4),%edi ;\
-+ movzbl %ch,%edx ;\
-+ shr $16,%ecx ;\
-+ xor p1+tlen(,%edx,4),%esi ;\
-+ movzbl %cl,%edx ;\
-+ movzbl %ch,%ecx ;\
-+ xor p1+2*tlen(,%edx,4),%ebx ;\
-+ xor p1+3*tlen(,%ecx,4),%eax
-+
-+// This macro performs an inverse encryption cycle. It is entered with
-+// the first previous round column values in %eax, %ebx, %esi and %edi and
-+// exits with the final values in the same registers.
-+
-+#define inv_rnd(p1,p2) \
-+ movzbl %al,%edx ;\
-+ mov %ebx,(%esp) ;\
-+ mov %eax,%ecx ;\
-+ mov p2(%ebp),%eax ;\
-+ mov %edi,4(%esp) ;\
-+ mov p2+4(%ebp),%ebx ;\
-+ xor p1(,%edx,4),%eax ;\
-+ movzbl %ch,%edx ;\
-+ shr $16,%ecx ;\
-+ mov p2+12(%ebp),%edi ;\
-+ xor p1+tlen(,%edx,4),%ebx ;\
-+ movzbl %cl,%edx ;\
-+ movzbl %ch,%ecx ;\
-+ xor p1+3*tlen(,%ecx,4),%edi ;\
-+ mov %esi,%ecx ;\
-+ mov p1+2*tlen(,%edx,4),%esi ;\
-+ movzbl %cl,%edx ;\
-+ xor p1(,%edx,4),%esi ;\
-+ movzbl %ch,%edx ;\
-+ shr $16,%ecx ;\
-+ xor p1+tlen(,%edx,4),%edi ;\
-+ movzbl %cl,%edx ;\
-+ movzbl %ch,%ecx ;\
-+ xor p1+2*tlen(,%edx,4),%eax ;\
-+ mov (%esp),%edx ;\
-+ xor p1+3*tlen(,%ecx,4),%ebx ;\
-+ movzbl %dl,%ecx ;\
-+ xor p2+8(%ebp),%esi ;\
-+ xor p1(,%ecx,4),%ebx ;\
-+ movzbl %dh,%ecx ;\
-+ shr $16,%edx ;\
-+ xor p1+tlen(,%ecx,4),%esi ;\
-+ movzbl %dl,%ecx ;\
-+ movzbl %dh,%edx ;\
-+ xor p1+2*tlen(,%ecx,4),%edi ;\
-+ mov 4(%esp),%ecx ;\
-+ xor p1+3*tlen(,%edx,4),%eax ;\
-+ movzbl %cl,%edx ;\
-+ xor p1(,%edx,4),%edi ;\
-+ movzbl %ch,%edx ;\
-+ shr $16,%ecx ;\
-+ xor p1+tlen(,%edx,4),%eax ;\
-+ movzbl %cl,%edx ;\
-+ movzbl %ch,%ecx ;\
-+ xor p1+2*tlen(,%edx,4),%ebx ;\
-+ xor p1+3*tlen(,%ecx,4),%esi
-+
-+// AES (Rijndael) Encryption Subroutine
-+
-+ .text
-+ .align ALIGN32BYTES
-+aes_encrypt:
-+ push %ebp
-+ mov ctx(%esp),%ebp // pointer to context
-+ mov in_blk(%esp),%ecx
-+ push %ebx
-+ push %esi
-+ push %edi
-+ mov nrnd(%ebp),%edx // number of rounds
-+ lea ekey+16(%ebp),%ebp // key pointer
-+
-+// input four columns and xor in first round key
-+
-+ mov (%ecx),%eax
-+ mov 4(%ecx),%ebx
-+ mov 8(%ecx),%esi
-+ mov 12(%ecx),%edi
-+ xor -16(%ebp),%eax
-+ xor -12(%ebp),%ebx
-+ xor -8(%ebp),%esi
-+ xor -4(%ebp),%edi
-+
-+ sub $8,%esp // space for register saves on stack
-+
-+ sub $10,%edx
-+ je aes_15
-+ add $32,%ebp
-+ sub $2,%edx
-+ je aes_13
-+ add $32,%ebp
-+
-+ fwd_rnd(aes_ft_tab,-64) // 14 rounds for 256-bit key
-+ fwd_rnd(aes_ft_tab,-48)
-+aes_13: fwd_rnd(aes_ft_tab,-32) // 12 rounds for 192-bit key
-+ fwd_rnd(aes_ft_tab,-16)
-+aes_15: fwd_rnd(aes_ft_tab,0) // 10 rounds for 128-bit key
-+ fwd_rnd(aes_ft_tab,16)
-+ fwd_rnd(aes_ft_tab,32)
-+ fwd_rnd(aes_ft_tab,48)
-+ fwd_rnd(aes_ft_tab,64)
-+ fwd_rnd(aes_ft_tab,80)
-+ fwd_rnd(aes_ft_tab,96)
-+ fwd_rnd(aes_ft_tab,112)
-+ fwd_rnd(aes_ft_tab,128)
-+ fwd_rnd(aes_fl_tab,144) // last round uses a different table
-+
-+// move final values to the output array.
-+
-+ mov out_blk+20(%esp),%ebp
-+ add $8,%esp
-+ mov %eax,(%ebp)
-+ mov %ebx,4(%ebp)
-+ mov %esi,8(%ebp)
-+ mov %edi,12(%ebp)
-+ pop %edi
-+ pop %esi
-+ pop %ebx
-+ pop %ebp
-+ ret
-+
-+
-+// AES (Rijndael) Decryption Subroutine
-+
-+ .align ALIGN32BYTES
-+aes_decrypt:
-+ push %ebp
-+ mov ctx(%esp),%ebp // pointer to context
-+ mov in_blk(%esp),%ecx
-+ push %ebx
-+ push %esi
-+ push %edi
-+ mov nrnd(%ebp),%edx // number of rounds
-+ lea dkey+16(%ebp),%ebp // key pointer
-+
-+// input four columns and xor in first round key
-+
-+ mov (%ecx),%eax
-+ mov 4(%ecx),%ebx
-+ mov 8(%ecx),%esi
-+ mov 12(%ecx),%edi
-+ xor -16(%ebp),%eax
-+ xor -12(%ebp),%ebx
-+ xor -8(%ebp),%esi
-+ xor -4(%ebp),%edi
-+
-+ sub $8,%esp // space for register saves on stack
-+
-+ sub $10,%edx
-+ je aes_25
-+ add $32,%ebp
-+ sub $2,%edx
-+ je aes_23
-+ add $32,%ebp
-+
-+ inv_rnd(aes_it_tab,-64) // 14 rounds for 256-bit key
-+ inv_rnd(aes_it_tab,-48)
-+aes_23: inv_rnd(aes_it_tab,-32) // 12 rounds for 192-bit key
-+ inv_rnd(aes_it_tab,-16)
-+aes_25: inv_rnd(aes_it_tab,0) // 10 rounds for 128-bit key
-+ inv_rnd(aes_it_tab,16)
-+ inv_rnd(aes_it_tab,32)
-+ inv_rnd(aes_it_tab,48)
-+ inv_rnd(aes_it_tab,64)
-+ inv_rnd(aes_it_tab,80)
-+ inv_rnd(aes_it_tab,96)
-+ inv_rnd(aes_it_tab,112)
-+ inv_rnd(aes_it_tab,128)
-+ inv_rnd(aes_il_tab,144) // last round uses a different table
-+
-+// move final values to the output array.
-+
-+ mov out_blk+20(%esp),%ebp
-+ add $8,%esp
-+ mov %eax,(%ebp)
-+ mov %ebx,4(%ebp)
-+ mov %esi,8(%ebp)
-+ mov %edi,12(%ebp)
-+ pop %edi
-+ pop %esi
-+ pop %ebx
-+ pop %ebp
-+ ret
-+
-+// AES (Rijndael) Key Schedule Subroutine
-+
-+// input/output parameters
-+
-+#define aes_cx 12 // AES context
-+#define in_key 16 // key input array address
-+#define key_ln 20 // key length, bytes (16,24,32) or bits (128,192,256)
-+#define ed_flg 24 // 0=create both encr/decr keys, 1=create encr key only
-+
-+// offsets for locals
-+
-+#define cnt -4
-+#define kpf -8
-+#define slen 8
-+
-+// This macro performs a column mixing operation on an input 32-bit
-+// word to give a 32-bit result. It uses each of the 4 bytes in the
-+// the input column to index 4 different tables of 256 32-bit words
-+// that are xored together to form the output value.
-+
-+#define mix_col(p1) \
-+ movzbl %bl,%ecx ;\
-+ mov p1(,%ecx,4),%eax ;\
-+ movzbl %bh,%ecx ;\
-+ ror $16,%ebx ;\
-+ xor p1+tlen(,%ecx,4),%eax ;\
-+ movzbl %bl,%ecx ;\
-+ xor p1+2*tlen(,%ecx,4),%eax ;\
-+ movzbl %bh,%ecx ;\
-+ xor p1+3*tlen(,%ecx,4),%eax
-+
-+// Key Schedule Macros
-+
-+#define ksc4(p1) \
-+ rol $24,%ebx ;\
-+ mix_col(aes_fl_tab) ;\
-+ ror $8,%ebx ;\
-+ xor 4*p1+aes_rcon_tab,%eax ;\
-+ xor %eax,%esi ;\
-+ xor %esi,%ebp ;\
-+ mov %esi,16*p1(%edi) ;\
-+ mov %ebp,16*p1+4(%edi) ;\
-+ xor %ebp,%edx ;\
-+ xor %edx,%ebx ;\
-+ mov %edx,16*p1+8(%edi) ;\
-+ mov %ebx,16*p1+12(%edi)
-+
-+#define ksc6(p1) \
-+ rol $24,%ebx ;\
-+ mix_col(aes_fl_tab) ;\
-+ ror $8,%ebx ;\
-+ xor 4*p1+aes_rcon_tab,%eax ;\
-+ xor 24*p1-24(%edi),%eax ;\
-+ mov %eax,24*p1(%edi) ;\
-+ xor 24*p1-20(%edi),%eax ;\
-+ mov %eax,24*p1+4(%edi) ;\
-+ xor %eax,%esi ;\
-+ xor %esi,%ebp ;\
-+ mov %esi,24*p1+8(%edi) ;\
-+ mov %ebp,24*p1+12(%edi) ;\
-+ xor %ebp,%edx ;\
-+ xor %edx,%ebx ;\
-+ mov %edx,24*p1+16(%edi) ;\
-+ mov %ebx,24*p1+20(%edi)
-+
-+#define ksc8(p1) \
-+ rol $24,%ebx ;\
-+ mix_col(aes_fl_tab) ;\
-+ ror $8,%ebx ;\
-+ xor 4*p1+aes_rcon_tab,%eax ;\
-+ xor 32*p1-32(%edi),%eax ;\
-+ mov %eax,32*p1(%edi) ;\
-+ xor 32*p1-28(%edi),%eax ;\
-+ mov %eax,32*p1+4(%edi) ;\
-+ xor 32*p1-24(%edi),%eax ;\
-+ mov %eax,32*p1+8(%edi) ;\
-+ xor 32*p1-20(%edi),%eax ;\
-+ mov %eax,32*p1+12(%edi) ;\
-+ push %ebx ;\
-+ mov %eax,%ebx ;\
-+ mix_col(aes_fl_tab) ;\
-+ pop %ebx ;\
-+ xor %eax,%esi ;\
-+ xor %esi,%ebp ;\
-+ mov %esi,32*p1+16(%edi) ;\
-+ mov %ebp,32*p1+20(%edi) ;\
-+ xor %ebp,%edx ;\
-+ xor %edx,%ebx ;\
-+ mov %edx,32*p1+24(%edi) ;\
-+ mov %ebx,32*p1+28(%edi)
-+
-+ .align ALIGN32BYTES
-+aes_set_key:
-+ pushfl
-+ push %ebp
-+ mov %esp,%ebp
-+ sub $slen,%esp
-+ push %ebx
-+ push %esi
-+ push %edi
-+
-+ mov aes_cx(%ebp),%edx // edx -> AES context
-+
-+ mov key_ln(%ebp),%ecx // key length
-+ cmpl $128,%ecx
-+ jb aes_30
-+ shr $3,%ecx
-+aes_30: cmpl $32,%ecx
-+ je aes_32
-+ cmpl $24,%ecx
-+ je aes_32
-+ mov $16,%ecx
-+aes_32: shr $2,%ecx
-+ mov %ecx,nkey(%edx)
-+
-+ lea 6(%ecx),%eax // 10/12/14 for 4/6/8 32-bit key length
-+ mov %eax,nrnd(%edx)
-+
-+ mov in_key(%ebp),%esi // key input array
-+ lea ekey(%edx),%edi // key position in AES context
-+ cld
-+ push %ebp
-+ mov %ecx,%eax // save key length in eax
-+ rep ; movsl // words in the key schedule
-+ mov -4(%esi),%ebx // put some values in registers
-+ mov -8(%esi),%edx // to allow faster code
-+ mov -12(%esi),%ebp
-+ mov -16(%esi),%esi
-+
-+ cmpl $4,%eax // jump on key size
-+ je aes_36
-+ cmpl $6,%eax
-+ je aes_35
-+
-+ ksc8(0)
-+ ksc8(1)
-+ ksc8(2)
-+ ksc8(3)
-+ ksc8(4)
-+ ksc8(5)
-+ ksc8(6)
-+ jmp aes_37
-+aes_35: ksc6(0)
-+ ksc6(1)
-+ ksc6(2)
-+ ksc6(3)
-+ ksc6(4)
-+ ksc6(5)
-+ ksc6(6)
-+ ksc6(7)
-+ jmp aes_37
-+aes_36: ksc4(0)
-+ ksc4(1)
-+ ksc4(2)
-+ ksc4(3)
-+ ksc4(4)
-+ ksc4(5)
-+ ksc4(6)
-+ ksc4(7)
-+ ksc4(8)
-+ ksc4(9)
-+aes_37: pop %ebp
-+ mov aes_cx(%ebp),%edx // edx -> AES context
-+ cmpl $0,ed_flg(%ebp)
-+ jne aes_39
-+
-+// compile decryption key schedule from encryption schedule - reverse
-+// order and do mix_column operation on round keys except first and last
-+
-+ mov nrnd(%edx),%eax // kt = cx->d_key + nc * cx->Nrnd
-+ shl $2,%eax
-+ lea dkey(%edx,%eax,4),%edi
-+ lea ekey(%edx),%esi // kf = cx->e_key
-+
-+ movsl // copy first round key (unmodified)
-+ movsl
-+ movsl
-+ movsl
-+ sub $32,%edi
-+ movl $1,cnt(%ebp)
-+aes_38: // do mix column on each column of
-+ lodsl // each round key
-+ mov %eax,%ebx
-+ mix_col(aes_im_tab)
-+ stosl
-+ lodsl
-+ mov %eax,%ebx
-+ mix_col(aes_im_tab)
-+ stosl
-+ lodsl
-+ mov %eax,%ebx
-+ mix_col(aes_im_tab)
-+ stosl
-+ lodsl
-+ mov %eax,%ebx
-+ mix_col(aes_im_tab)
-+ stosl
-+ sub $32,%edi
-+
-+ incl cnt(%ebp)
-+ mov cnt(%ebp),%eax
-+ cmp nrnd(%edx),%eax
-+ jb aes_38
-+
-+ movsl // copy last round key (unmodified)
-+ movsl
-+ movsl
-+ movsl
-+aes_39: pop %edi
-+ pop %esi
-+ pop %ebx
-+ mov %ebp,%esp
-+ pop %ebp
-+ popfl
-+ ret
-+
-+
-+// finite field multiplies by {02}, {04} and {08}
-+
-+#define f2(x) ((x<<1)^(((x>>7)&1)*0x11b))
-+#define f4(x) ((x<<2)^(((x>>6)&1)*0x11b)^(((x>>6)&2)*0x11b))
-+#define f8(x) ((x<<3)^(((x>>5)&1)*0x11b)^(((x>>5)&2)*0x11b)^(((x>>5)&4)*0x11b))
-+
-+// finite field multiplies required in table generation
-+
-+#define f3(x) (f2(x) ^ x)
-+#define f9(x) (f8(x) ^ x)
-+#define fb(x) (f8(x) ^ f2(x) ^ x)
-+#define fd(x) (f8(x) ^ f4(x) ^ x)
-+#define fe(x) (f8(x) ^ f4(x) ^ f2(x))
-+
-+// These defines generate the forward table entries
-+
-+#define u0(x) ((f3(x) << 24) | (x << 16) | (x << 8) | f2(x))
-+#define u1(x) ((x << 24) | (x << 16) | (f2(x) << 8) | f3(x))
-+#define u2(x) ((x << 24) | (f2(x) << 16) | (f3(x) << 8) | x)
-+#define u3(x) ((f2(x) << 24) | (f3(x) << 16) | (x << 8) | x)
-+
-+// These defines generate the inverse table entries
-+
-+#define v0(x) ((fb(x) << 24) | (fd(x) << 16) | (f9(x) << 8) | fe(x))
-+#define v1(x) ((fd(x) << 24) | (f9(x) << 16) | (fe(x) << 8) | fb(x))
-+#define v2(x) ((f9(x) << 24) | (fe(x) << 16) | (fb(x) << 8) | fd(x))
-+#define v3(x) ((fe(x) << 24) | (fb(x) << 16) | (fd(x) << 8) | f9(x))
-+
-+// These defines generate entries for the last round tables
-+
-+#define w0(x) (x)
-+#define w1(x) (x << 8)
-+#define w2(x) (x << 16)
-+#define w3(x) (x << 24)
-+
-+// macro to generate inverse mix column tables (needed for the key schedule)
-+
-+#define im_data0(p1) \
-+ .long p1(0x00),p1(0x01),p1(0x02),p1(0x03),p1(0x04),p1(0x05),p1(0x06),p1(0x07) ;\
-+ .long p1(0x08),p1(0x09),p1(0x0a),p1(0x0b),p1(0x0c),p1(0x0d),p1(0x0e),p1(0x0f) ;\
-+ .long p1(0x10),p1(0x11),p1(0x12),p1(0x13),p1(0x14),p1(0x15),p1(0x16),p1(0x17) ;\
-+ .long p1(0x18),p1(0x19),p1(0x1a),p1(0x1b),p1(0x1c),p1(0x1d),p1(0x1e),p1(0x1f)
-+#define im_data1(p1) \
-+ .long p1(0x20),p1(0x21),p1(0x22),p1(0x23),p1(0x24),p1(0x25),p1(0x26),p1(0x27) ;\
-+ .long p1(0x28),p1(0x29),p1(0x2a),p1(0x2b),p1(0x2c),p1(0x2d),p1(0x2e),p1(0x2f) ;\
-+ .long p1(0x30),p1(0x31),p1(0x32),p1(0x33),p1(0x34),p1(0x35),p1(0x36),p1(0x37) ;\
-+ .long p1(0x38),p1(0x39),p1(0x3a),p1(0x3b),p1(0x3c),p1(0x3d),p1(0x3e),p1(0x3f)
-+#define im_data2(p1) \
-+ .long p1(0x40),p1(0x41),p1(0x42),p1(0x43),p1(0x44),p1(0x45),p1(0x46),p1(0x47) ;\
-+ .long p1(0x48),p1(0x49),p1(0x4a),p1(0x4b),p1(0x4c),p1(0x4d),p1(0x4e),p1(0x4f) ;\
-+ .long p1(0x50),p1(0x51),p1(0x52),p1(0x53),p1(0x54),p1(0x55),p1(0x56),p1(0x57) ;\
-+ .long p1(0x58),p1(0x59),p1(0x5a),p1(0x5b),p1(0x5c),p1(0x5d),p1(0x5e),p1(0x5f)
-+#define im_data3(p1) \
-+ .long p1(0x60),p1(0x61),p1(0x62),p1(0x63),p1(0x64),p1(0x65),p1(0x66),p1(0x67) ;\
-+ .long p1(0x68),p1(0x69),p1(0x6a),p1(0x6b),p1(0x6c),p1(0x6d),p1(0x6e),p1(0x6f) ;\
-+ .long p1(0x70),p1(0x71),p1(0x72),p1(0x73),p1(0x74),p1(0x75),p1(0x76),p1(0x77) ;\
-+ .long p1(0x78),p1(0x79),p1(0x7a),p1(0x7b),p1(0x7c),p1(0x7d),p1(0x7e),p1(0x7f)
-+#define im_data4(p1) \
-+ .long p1(0x80),p1(0x81),p1(0x82),p1(0x83),p1(0x84),p1(0x85),p1(0x86),p1(0x87) ;\
-+ .long p1(0x88),p1(0x89),p1(0x8a),p1(0x8b),p1(0x8c),p1(0x8d),p1(0x8e),p1(0x8f) ;\
-+ .long p1(0x90),p1(0x91),p1(0x92),p1(0x93),p1(0x94),p1(0x95),p1(0x96),p1(0x97) ;\
-+ .long p1(0x98),p1(0x99),p1(0x9a),p1(0x9b),p1(0x9c),p1(0x9d),p1(0x9e),p1(0x9f)
-+#define im_data5(p1) \
-+ .long p1(0xa0),p1(0xa1),p1(0xa2),p1(0xa3),p1(0xa4),p1(0xa5),p1(0xa6),p1(0xa7) ;\
-+ .long p1(0xa8),p1(0xa9),p1(0xaa),p1(0xab),p1(0xac),p1(0xad),p1(0xae),p1(0xaf) ;\
-+ .long p1(0xb0),p1(0xb1),p1(0xb2),p1(0xb3),p1(0xb4),p1(0xb5),p1(0xb6),p1(0xb7) ;\
-+ .long p1(0xb8),p1(0xb9),p1(0xba),p1(0xbb),p1(0xbc),p1(0xbd),p1(0xbe),p1(0xbf)
-+#define im_data6(p1) \
-+ .long p1(0xc0),p1(0xc1),p1(0xc2),p1(0xc3),p1(0xc4),p1(0xc5),p1(0xc6),p1(0xc7) ;\
-+ .long p1(0xc8),p1(0xc9),p1(0xca),p1(0xcb),p1(0xcc),p1(0xcd),p1(0xce),p1(0xcf) ;\
-+ .long p1(0xd0),p1(0xd1),p1(0xd2),p1(0xd3),p1(0xd4),p1(0xd5),p1(0xd6),p1(0xd7) ;\
-+ .long p1(0xd8),p1(0xd9),p1(0xda),p1(0xdb),p1(0xdc),p1(0xdd),p1(0xde),p1(0xdf)
-+#define im_data7(p1) \
-+ .long p1(0xe0),p1(0xe1),p1(0xe2),p1(0xe3),p1(0xe4),p1(0xe5),p1(0xe6),p1(0xe7) ;\
-+ .long p1(0xe8),p1(0xe9),p1(0xea),p1(0xeb),p1(0xec),p1(0xed),p1(0xee),p1(0xef) ;\
-+ .long p1(0xf0),p1(0xf1),p1(0xf2),p1(0xf3),p1(0xf4),p1(0xf5),p1(0xf6),p1(0xf7) ;\
-+ .long p1(0xf8),p1(0xf9),p1(0xfa),p1(0xfb),p1(0xfc),p1(0xfd),p1(0xfe),p1(0xff)
-+
-+// S-box data - 256 entries
-+
-+#define sb_data0(p1) \
-+ .long p1(0x63),p1(0x7c),p1(0x77),p1(0x7b),p1(0xf2),p1(0x6b),p1(0x6f),p1(0xc5) ;\
-+ .long p1(0x30),p1(0x01),p1(0x67),p1(0x2b),p1(0xfe),p1(0xd7),p1(0xab),p1(0x76) ;\
-+ .long p1(0xca),p1(0x82),p1(0xc9),p1(0x7d),p1(0xfa),p1(0x59),p1(0x47),p1(0xf0) ;\
-+ .long p1(0xad),p1(0xd4),p1(0xa2),p1(0xaf),p1(0x9c),p1(0xa4),p1(0x72),p1(0xc0)
-+#define sb_data1(p1) \
-+ .long p1(0xb7),p1(0xfd),p1(0x93),p1(0x26),p1(0x36),p1(0x3f),p1(0xf7),p1(0xcc) ;\
-+ .long p1(0x34),p1(0xa5),p1(0xe5),p1(0xf1),p1(0x71),p1(0xd8),p1(0x31),p1(0x15) ;\
-+ .long p1(0x04),p1(0xc7),p1(0x23),p1(0xc3),p1(0x18),p1(0x96),p1(0x05),p1(0x9a) ;\
-+ .long p1(0x07),p1(0x12),p1(0x80),p1(0xe2),p1(0xeb),p1(0x27),p1(0xb2),p1(0x75)
-+#define sb_data2(p1) \
-+ .long p1(0x09),p1(0x83),p1(0x2c),p1(0x1a),p1(0x1b),p1(0x6e),p1(0x5a),p1(0xa0) ;\
-+ .long p1(0x52),p1(0x3b),p1(0xd6),p1(0xb3),p1(0x29),p1(0xe3),p1(0x2f),p1(0x84) ;\
-+ .long p1(0x53),p1(0xd1),p1(0x00),p1(0xed),p1(0x20),p1(0xfc),p1(0xb1),p1(0x5b) ;\
-+ .long p1(0x6a),p1(0xcb),p1(0xbe),p1(0x39),p1(0x4a),p1(0x4c),p1(0x58),p1(0xcf)
-+#define sb_data3(p1) \
-+ .long p1(0xd0),p1(0xef),p1(0xaa),p1(0xfb),p1(0x43),p1(0x4d),p1(0x33),p1(0x85) ;\
-+ .long p1(0x45),p1(0xf9),p1(0x02),p1(0x7f),p1(0x50),p1(0x3c),p1(0x9f),p1(0xa8) ;\
-+ .long p1(0x51),p1(0xa3),p1(0x40),p1(0x8f),p1(0x92),p1(0x9d),p1(0x38),p1(0xf5) ;\
-+ .long p1(0xbc),p1(0xb6),p1(0xda),p1(0x21),p1(0x10),p1(0xff),p1(0xf3),p1(0xd2)
-+#define sb_data4(p1) \
-+ .long p1(0xcd),p1(0x0c),p1(0x13),p1(0xec),p1(0x5f),p1(0x97),p1(0x44),p1(0x17) ;\
-+ .long p1(0xc4),p1(0xa7),p1(0x7e),p1(0x3d),p1(0x64),p1(0x5d),p1(0x19),p1(0x73) ;\
-+ .long p1(0x60),p1(0x81),p1(0x4f),p1(0xdc),p1(0x22),p1(0x2a),p1(0x90),p1(0x88) ;\
-+ .long p1(0x46),p1(0xee),p1(0xb8),p1(0x14),p1(0xde),p1(0x5e),p1(0x0b),p1(0xdb)
-+#define sb_data5(p1) \
-+ .long p1(0xe0),p1(0x32),p1(0x3a),p1(0x0a),p1(0x49),p1(0x06),p1(0x24),p1(0x5c) ;\
-+ .long p1(0xc2),p1(0xd3),p1(0xac),p1(0x62),p1(0x91),p1(0x95),p1(0xe4),p1(0x79) ;\
-+ .long p1(0xe7),p1(0xc8),p1(0x37),p1(0x6d),p1(0x8d),p1(0xd5),p1(0x4e),p1(0xa9) ;\
-+ .long p1(0x6c),p1(0x56),p1(0xf4),p1(0xea),p1(0x65),p1(0x7a),p1(0xae),p1(0x08)
-+#define sb_data6(p1) \
-+ .long p1(0xba),p1(0x78),p1(0x25),p1(0x2e),p1(0x1c),p1(0xa6),p1(0xb4),p1(0xc6) ;\
-+ .long p1(0xe8),p1(0xdd),p1(0x74),p1(0x1f),p1(0x4b),p1(0xbd),p1(0x8b),p1(0x8a) ;\
-+ .long p1(0x70),p1(0x3e),p1(0xb5),p1(0x66),p1(0x48),p1(0x03),p1(0xf6),p1(0x0e) ;\
-+ .long p1(0x61),p1(0x35),p1(0x57),p1(0xb9),p1(0x86),p1(0xc1),p1(0x1d),p1(0x9e)
-+#define sb_data7(p1) \
-+ .long p1(0xe1),p1(0xf8),p1(0x98),p1(0x11),p1(0x69),p1(0xd9),p1(0x8e),p1(0x94) ;\
-+ .long p1(0x9b),p1(0x1e),p1(0x87),p1(0xe9),p1(0xce),p1(0x55),p1(0x28),p1(0xdf) ;\
-+ .long p1(0x8c),p1(0xa1),p1(0x89),p1(0x0d),p1(0xbf),p1(0xe6),p1(0x42),p1(0x68) ;\
-+ .long p1(0x41),p1(0x99),p1(0x2d),p1(0x0f),p1(0xb0),p1(0x54),p1(0xbb),p1(0x16)
-+
-+// Inverse S-box data - 256 entries
-+
-+#define ib_data0(p1) \
-+ .long p1(0x52),p1(0x09),p1(0x6a),p1(0xd5),p1(0x30),p1(0x36),p1(0xa5),p1(0x38) ;\
-+ .long p1(0xbf),p1(0x40),p1(0xa3),p1(0x9e),p1(0x81),p1(0xf3),p1(0xd7),p1(0xfb) ;\
-+ .long p1(0x7c),p1(0xe3),p1(0x39),p1(0x82),p1(0x9b),p1(0x2f),p1(0xff),p1(0x87) ;\
-+ .long p1(0x34),p1(0x8e),p1(0x43),p1(0x44),p1(0xc4),p1(0xde),p1(0xe9),p1(0xcb)
-+#define ib_data1(p1) \
-+ .long p1(0x54),p1(0x7b),p1(0x94),p1(0x32),p1(0xa6),p1(0xc2),p1(0x23),p1(0x3d) ;\
-+ .long p1(0xee),p1(0x4c),p1(0x95),p1(0x0b),p1(0x42),p1(0xfa),p1(0xc3),p1(0x4e) ;\
-+ .long p1(0x08),p1(0x2e),p1(0xa1),p1(0x66),p1(0x28),p1(0xd9),p1(0x24),p1(0xb2) ;\
-+ .long p1(0x76),p1(0x5b),p1(0xa2),p1(0x49),p1(0x6d),p1(0x8b),p1(0xd1),p1(0x25)
-+#define ib_data2(p1) \
-+ .long p1(0x72),p1(0xf8),p1(0xf6),p1(0x64),p1(0x86),p1(0x68),p1(0x98),p1(0x16) ;\
-+ .long p1(0xd4),p1(0xa4),p1(0x5c),p1(0xcc),p1(0x5d),p1(0x65),p1(0xb6),p1(0x92) ;\
-+ .long p1(0x6c),p1(0x70),p1(0x48),p1(0x50),p1(0xfd),p1(0xed),p1(0xb9),p1(0xda) ;\
-+ .long p1(0x5e),p1(0x15),p1(0x46),p1(0x57),p1(0xa7),p1(0x8d),p1(0x9d),p1(0x84)
-+#define ib_data3(p1) \
-+ .long p1(0x90),p1(0xd8),p1(0xab),p1(0x00),p1(0x8c),p1(0xbc),p1(0xd3),p1(0x0a) ;\
-+ .long p1(0xf7),p1(0xe4),p1(0x58),p1(0x05),p1(0xb8),p1(0xb3),p1(0x45),p1(0x06) ;\
-+ .long p1(0xd0),p1(0x2c),p1(0x1e),p1(0x8f),p1(0xca),p1(0x3f),p1(0x0f),p1(0x02) ;\
-+ .long p1(0xc1),p1(0xaf),p1(0xbd),p1(0x03),p1(0x01),p1(0x13),p1(0x8a),p1(0x6b)
-+#define ib_data4(p1) \
-+ .long p1(0x3a),p1(0x91),p1(0x11),p1(0x41),p1(0x4f),p1(0x67),p1(0xdc),p1(0xea) ;\
-+ .long p1(0x97),p1(0xf2),p1(0xcf),p1(0xce),p1(0xf0),p1(0xb4),p1(0xe6),p1(0x73) ;\
-+ .long p1(0x96),p1(0xac),p1(0x74),p1(0x22),p1(0xe7),p1(0xad),p1(0x35),p1(0x85) ;\
-+ .long p1(0xe2),p1(0xf9),p1(0x37),p1(0xe8),p1(0x1c),p1(0x75),p1(0xdf),p1(0x6e)
-+#define ib_data5(p1) \
-+ .long p1(0x47),p1(0xf1),p1(0x1a),p1(0x71),p1(0x1d),p1(0x29),p1(0xc5),p1(0x89) ;\
-+ .long p1(0x6f),p1(0xb7),p1(0x62),p1(0x0e),p1(0xaa),p1(0x18),p1(0xbe),p1(0x1b) ;\
-+ .long p1(0xfc),p1(0x56),p1(0x3e),p1(0x4b),p1(0xc6),p1(0xd2),p1(0x79),p1(0x20) ;\
-+ .long p1(0x9a),p1(0xdb),p1(0xc0),p1(0xfe),p1(0x78),p1(0xcd),p1(0x5a),p1(0xf4)
-+#define ib_data6(p1) \
-+ .long p1(0x1f),p1(0xdd),p1(0xa8),p1(0x33),p1(0x88),p1(0x07),p1(0xc7),p1(0x31) ;\
-+ .long p1(0xb1),p1(0x12),p1(0x10),p1(0x59),p1(0x27),p1(0x80),p1(0xec),p1(0x5f) ;\
-+ .long p1(0x60),p1(0x51),p1(0x7f),p1(0xa9),p1(0x19),p1(0xb5),p1(0x4a),p1(0x0d) ;\
-+ .long p1(0x2d),p1(0xe5),p1(0x7a),p1(0x9f),p1(0x93),p1(0xc9),p1(0x9c),p1(0xef)
-+#define ib_data7(p1) \
-+ .long p1(0xa0),p1(0xe0),p1(0x3b),p1(0x4d),p1(0xae),p1(0x2a),p1(0xf5),p1(0xb0) ;\
-+ .long p1(0xc8),p1(0xeb),p1(0xbb),p1(0x3c),p1(0x83),p1(0x53),p1(0x99),p1(0x61) ;\
-+ .long p1(0x17),p1(0x2b),p1(0x04),p1(0x7e),p1(0xba),p1(0x77),p1(0xd6),p1(0x26) ;\
-+ .long p1(0xe1),p1(0x69),p1(0x14),p1(0x63),p1(0x55),p1(0x21),p1(0x0c),p1(0x7d)
-+
-+// The rcon_table (needed for the key schedule)
-+//
-+// Here is original Dr Brian Gladman's source code:
-+// _rcon_tab:
-+// %assign x 1
-+// %rep 29
-+// dd x
-+// %assign x f2(x)
-+// %endrep
-+//
-+// Here is precomputed output (it's more portable this way):
-+
-+ .align ALIGN32BYTES
-+aes_rcon_tab:
-+ .long 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80
-+ .long 0x1b,0x36,0x6c,0xd8,0xab,0x4d,0x9a,0x2f
-+ .long 0x5e,0xbc,0x63,0xc6,0x97,0x35,0x6a,0xd4
-+ .long 0xb3,0x7d,0xfa,0xef,0xc5
-+
-+// The forward xor tables
-+
-+ .align ALIGN32BYTES
-+aes_ft_tab:
-+ sb_data0(u0)
-+ sb_data1(u0)
-+ sb_data2(u0)
-+ sb_data3(u0)
-+ sb_data4(u0)
-+ sb_data5(u0)
-+ sb_data6(u0)
-+ sb_data7(u0)
-+
-+ sb_data0(u1)
-+ sb_data1(u1)
-+ sb_data2(u1)
-+ sb_data3(u1)
-+ sb_data4(u1)
-+ sb_data5(u1)
-+ sb_data6(u1)
-+ sb_data7(u1)
-+
-+ sb_data0(u2)
-+ sb_data1(u2)
-+ sb_data2(u2)
-+ sb_data3(u2)
-+ sb_data4(u2)
-+ sb_data5(u2)
-+ sb_data6(u2)
-+ sb_data7(u2)
-+
-+ sb_data0(u3)
-+ sb_data1(u3)
-+ sb_data2(u3)
-+ sb_data3(u3)
-+ sb_data4(u3)
-+ sb_data5(u3)
-+ sb_data6(u3)
-+ sb_data7(u3)
-+
-+ .align ALIGN32BYTES
-+aes_fl_tab:
-+ sb_data0(w0)
-+ sb_data1(w0)
-+ sb_data2(w0)
-+ sb_data3(w0)
-+ sb_data4(w0)
-+ sb_data5(w0)
-+ sb_data6(w0)
-+ sb_data7(w0)
-+
-+ sb_data0(w1)
-+ sb_data1(w1)
-+ sb_data2(w1)
-+ sb_data3(w1)
-+ sb_data4(w1)
-+ sb_data5(w1)
-+ sb_data6(w1)
-+ sb_data7(w1)
-+
-+ sb_data0(w2)
-+ sb_data1(w2)
-+ sb_data2(w2)
-+ sb_data3(w2)
-+ sb_data4(w2)
-+ sb_data5(w2)
-+ sb_data6(w2)
-+ sb_data7(w2)
-+
-+ sb_data0(w3)
-+ sb_data1(w3)
-+ sb_data2(w3)
-+ sb_data3(w3)
-+ sb_data4(w3)
-+ sb_data5(w3)
-+ sb_data6(w3)
-+ sb_data7(w3)
-+
-+// The inverse xor tables
-+
-+ .align ALIGN32BYTES
-+aes_it_tab:
-+ ib_data0(v0)
-+ ib_data1(v0)
-+ ib_data2(v0)
-+ ib_data3(v0)
-+ ib_data4(v0)
-+ ib_data5(v0)
-+ ib_data6(v0)
-+ ib_data7(v0)
-+
-+ ib_data0(v1)
-+ ib_data1(v1)
-+ ib_data2(v1)
-+ ib_data3(v1)
-+ ib_data4(v1)
-+ ib_data5(v1)
-+ ib_data6(v1)
-+ ib_data7(v1)
-+
-+ ib_data0(v2)
-+ ib_data1(v2)
-+ ib_data2(v2)
-+ ib_data3(v2)
-+ ib_data4(v2)
-+ ib_data5(v2)
-+ ib_data6(v2)
-+ ib_data7(v2)
-+
-+ ib_data0(v3)
-+ ib_data1(v3)
-+ ib_data2(v3)
-+ ib_data3(v3)
-+ ib_data4(v3)
-+ ib_data5(v3)
-+ ib_data6(v3)
-+ ib_data7(v3)
-+
-+ .align ALIGN32BYTES
-+aes_il_tab:
-+ ib_data0(w0)
-+ ib_data1(w0)
-+ ib_data2(w0)
-+ ib_data3(w0)
-+ ib_data4(w0)
-+ ib_data5(w0)
-+ ib_data6(w0)
-+ ib_data7(w0)
-+
-+ ib_data0(w1)
-+ ib_data1(w1)
-+ ib_data2(w1)
-+ ib_data3(w1)
-+ ib_data4(w1)
-+ ib_data5(w1)
-+ ib_data6(w1)
-+ ib_data7(w1)
-+
-+ ib_data0(w2)
-+ ib_data1(w2)
-+ ib_data2(w2)
-+ ib_data3(w2)
-+ ib_data4(w2)
-+ ib_data5(w2)
-+ ib_data6(w2)
-+ ib_data7(w2)
-+
-+ ib_data0(w3)
-+ ib_data1(w3)
-+ ib_data2(w3)
-+ ib_data3(w3)
-+ ib_data4(w3)
-+ ib_data5(w3)
-+ ib_data6(w3)
-+ ib_data7(w3)
-+
-+// The inverse mix column tables
-+
-+ .align ALIGN32BYTES
-+aes_im_tab:
-+ im_data0(v0)
-+ im_data1(v0)
-+ im_data2(v0)
-+ im_data3(v0)
-+ im_data4(v0)
-+ im_data5(v0)
-+ im_data6(v0)
-+ im_data7(v0)
-+
-+ im_data0(v1)
-+ im_data1(v1)
-+ im_data2(v1)
-+ im_data3(v1)
-+ im_data4(v1)
-+ im_data5(v1)
-+ im_data6(v1)
-+ im_data7(v1)
-+
-+ im_data0(v2)
-+ im_data1(v2)
-+ im_data2(v2)
-+ im_data3(v2)
-+ im_data4(v2)
-+ im_data5(v2)
-+ im_data6(v2)
-+ im_data7(v2)
-+
-+ im_data0(v3)
-+ im_data1(v3)
-+ im_data2(v3)
-+ im_data3(v3)
-+ im_data4(v3)
-+ im_data5(v3)
-+ im_data6(v3)
-+ im_data7(v3)
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/aes/aes.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1415 @@
-+// I retain copyright in this code but I encourage its free use provided
-+// that I don't carry any responsibility for the results. I am especially
-+// happy to see it used in free and open source software. If you do use
-+// it I would appreciate an acknowledgement of its origin in the code or
-+// the product that results and I would also appreciate knowing a little
-+// about the use to which it is being put. I am grateful to Frank Yellin
-+// for some ideas that are used in this implementation.
-+//
-+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
-+//
-+// This is an implementation of the AES encryption algorithm (Rijndael)
-+// designed by Joan Daemen and Vincent Rijmen. This version is designed
-+// to provide both fixed and dynamic block and key lengths and can also
-+// run with either big or little endian internal byte order (see aes.h).
-+// It inputs block and key lengths in bytes with the legal values being
-+// 16, 24 and 32.
-+
-+/*
-+ * Modified by Jari Ruusu, May 1 2001
-+ * - Fixed some compile warnings, code was ok but gcc warned anyway.
-+ * - Changed basic types: byte -> unsigned char, word -> u_int32_t
-+ * - Major name space cleanup: Names visible to outside now begin
-+ * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
-+ * - Removed C++ and DLL support as part of name space cleanup.
-+ * - Eliminated unnecessary recomputation of tables. (actual bug fix)
-+ * - Merged precomputed constant tables to aes.c file.
-+ * - Removed data alignment restrictions for portability reasons.
-+ * - Made block and key lengths accept bit count (128/192/256)
-+ * as well byte count (16/24/32).
-+ * - Removed all error checks. This change also eliminated the need
-+ * to preinitialize the context struct to zero.
-+ * - Removed some totally unused constants.
-+ */
-+
-+#include "crypto/aes.h"
-+
-+// CONFIGURATION OPTIONS (see also aes.h)
-+//
-+// 1. Define UNROLL for full loop unrolling in encryption and decryption.
-+// 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption.
-+// 3. Define FIXED_TABLES for compiled rather than dynamic tables.
-+// 4. Define FF_TABLES to use tables for field multiplies and inverses.
-+// Do not enable this without understanding stack space requirements.
-+// 5. Define ARRAYS to use arrays to hold the local state block. If this
-+// is not defined, individually declared 32-bit words are used.
-+// 6. Define FAST_VARIABLE if a high speed variable block implementation
-+// is needed (essentially three separate fixed block size code sequences)
-+// 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven
-+// version using 1 table (2 kbytes of table space) or 4 tables (8
-+// kbytes of table space) for higher speed.
-+// 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed
-+// increase by using tables for the last rounds but with more table
-+// space (2 or 8 kbytes extra).
-+// 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but
-+// slower version is provided.
-+// 10. If fast decryption key scheduling is needed define ONE_IM_TABLE
-+// or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra).
-+
-+#define UNROLL
-+//#define PARTIAL_UNROLL
-+
-+#define FIXED_TABLES
-+//#define FF_TABLES
-+//#define ARRAYS
-+#define FAST_VARIABLE
-+
-+//#define ONE_TABLE
-+#define FOUR_TABLES
-+
-+//#define ONE_LR_TABLE
-+#define FOUR_LR_TABLES
-+
-+//#define ONE_IM_TABLE
-+#define FOUR_IM_TABLES
-+
-+#if defined(UNROLL) && defined (PARTIAL_UNROLL)
-+#error both UNROLL and PARTIAL_UNROLL are defined
-+#endif
-+
-+#if defined(ONE_TABLE) && defined (FOUR_TABLES)
-+#error both ONE_TABLE and FOUR_TABLES are defined
-+#endif
-+
-+#if defined(ONE_LR_TABLE) && defined (FOUR_LR_TABLES)
-+#error both ONE_LR_TABLE and FOUR_LR_TABLES are defined
-+#endif
-+
-+#if defined(ONE_IM_TABLE) && defined (FOUR_IM_TABLES)
-+#error both ONE_IM_TABLE and FOUR_IM_TABLES are defined
-+#endif
-+
-+#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32
-+#error an illegal block size has been specified
-+#endif
-+
-+// upr(x,n): rotates bytes within words by n positions, moving bytes
-+// to higher index positions with wrap around into low positions
-+// ups(x,n): moves bytes by n positions to higher index positions in
-+// words but without wrap around
-+// bval(x,n): extracts a byte from a word
-+
-+#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n))))
-+#define ups(x,n) ((x) << 8 * (n))
-+#define bval(x,n) ((unsigned char)((x) >> 8 * (n)))
-+#define bytes2word(b0, b1, b2, b3) \
-+ ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0))
-+
-+
-+/* little endian processor without data alignment restrictions: AES_LE_OK */
-+/* original code: i386 */
-+#if defined(i386) || defined(_I386) || defined(__i386__) || defined(__i386)
-+#define AES_LE_OK 1
-+/* added (tested): alpha --jjo */
-+#elif defined(__alpha__)|| defined (__alpha)
-+#define AES_LE_OK 1
-+/* added (tested): ia64 --jjo */
-+#elif defined(__ia64__)|| defined (__ia64)
-+#define AES_LE_OK 1
-+#endif
-+
-+#ifdef AES_LE_OK
-+/* little endian processor without data alignment restrictions */
-+#define word_in(x) *(u_int32_t*)(x)
-+#define const_word_in(x) *(const u_int32_t*)(x)
-+#define word_out(x,v) *(u_int32_t*)(x) = (v)
-+#define const_word_out(x,v) *(const u_int32_t*)(x) = (v)
-+#else
-+/* slower but generic big endian or with data alignment restrictions */
-+/* some additional "const" touches to stop "gcc -Wcast-qual" complains --jjo */
-+#define word_in(x) ((u_int32_t)(((unsigned char *)(x))[0])|((u_int32_t)(((unsigned char *)(x))[1])<<8)|((u_int32_t)(((unsigned char *)(x))[2])<<16)|((u_int32_t)(((unsigned char *)(x))[3])<<24))
-+#define const_word_in(x) ((const u_int32_t)(((const unsigned char *)(x))[0])|((const u_int32_t)(((const unsigned char *)(x))[1])<<8)|((const u_int32_t)(((const unsigned char *)(x))[2])<<16)|((const u_int32_t)(((const unsigned char *)(x))[3])<<24))
-+#define word_out(x,v) ((unsigned char *)(x))[0]=(v),((unsigned char *)(x))[1]=((v)>>8),((unsigned char *)(x))[2]=((v)>>16),((unsigned char *)(x))[3]=((v)>>24)
-+#define const_word_out(x,v) ((const unsigned char *)(x))[0]=(v),((const unsigned char *)(x))[1]=((v)>>8),((const unsigned char *)(x))[2]=((v)>>16),((const unsigned char *)(x))[3]=((v)>>24)
-+#endif
-+
-+// Disable at least some poor combinations of options
-+
-+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
-+#define FIXED_TABLES
-+#undef UNROLL
-+#undef ONE_LR_TABLE
-+#undef FOUR_LR_TABLES
-+#undef ONE_IM_TABLE
-+#undef FOUR_IM_TABLES
-+#elif !defined(FOUR_TABLES)
-+#ifdef FOUR_LR_TABLES
-+#undef FOUR_LR_TABLES
-+#define ONE_LR_TABLE
-+#endif
-+#ifdef FOUR_IM_TABLES
-+#undef FOUR_IM_TABLES
-+#define ONE_IM_TABLE
-+#endif
-+#elif !defined(AES_BLOCK_SIZE)
-+#if defined(UNROLL)
-+#define PARTIAL_UNROLL
-+#undef UNROLL
-+#endif
-+#endif
-+
-+// the finite field modular polynomial and elements
-+
-+#define ff_poly 0x011b
-+#define ff_hi 0x80
-+
-+// multiply four bytes in GF(2^8) by 'x' {02} in parallel
-+
-+#define m1 0x80808080
-+#define m2 0x7f7f7f7f
-+#define m3 0x0000001b
-+#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3))
-+
-+// The following defines provide alternative definitions of FFmulX that might
-+// give improved performance if a fast 32-bit multiply is not available. Note
-+// that a temporary variable u needs to be defined where FFmulX is used.
-+
-+// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
-+// #define m4 0x1b1b1b1b
-+// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
-+
-+// perform column mix operation on four bytes in parallel
-+
-+#define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1))
-+
-+#if defined(FIXED_TABLES)
-+
-+// the S-Box table
-+
-+static const unsigned char s_box[256] =
-+{
-+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
-+ 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
-+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
-+ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
-+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
-+ 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
-+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
-+ 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
-+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
-+ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
-+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
-+ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
-+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
-+ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
-+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
-+ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
-+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
-+ 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
-+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
-+ 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
-+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
-+ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
-+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
-+ 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
-+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
-+ 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
-+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
-+ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
-+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
-+ 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
-+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
-+ 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-+};
-+
-+// the inverse S-Box table
-+
-+static const unsigned char inv_s_box[256] =
-+{
-+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
-+ 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
-+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
-+ 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
-+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
-+ 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
-+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
-+ 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
-+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
-+ 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
-+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
-+ 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
-+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
-+ 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
-+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
-+ 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
-+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
-+ 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
-+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
-+ 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
-+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
-+ 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
-+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
-+ 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
-+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
-+ 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
-+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
-+ 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
-+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
-+ 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
-+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
-+ 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-+};
-+
-+#define w0(p) 0x000000##p
-+
-+// Number of elements required in this table for different
-+// block and key lengths is:
-+//
-+// Nk = 4 6 8
-+// ----------
-+// Nb = 4 | 10 8 7
-+// 6 | 19 12 11
-+// 8 | 29 19 14
-+//
-+// this table can be a table of bytes if the key schedule
-+// code is adjusted accordingly
-+
-+static const u_int32_t rcon_tab[29] =
-+{
-+ w0(01), w0(02), w0(04), w0(08),
-+ w0(10), w0(20), w0(40), w0(80),
-+ w0(1b), w0(36), w0(6c), w0(d8),
-+ w0(ab), w0(4d), w0(9a), w0(2f),
-+ w0(5e), w0(bc), w0(63), w0(c6),
-+ w0(97), w0(35), w0(6a), w0(d4),
-+ w0(b3), w0(7d), w0(fa), w0(ef),
-+ w0(c5)
-+};
-+
-+#undef w0
-+
-+#define r0(p,q,r,s) 0x##p##q##r##s
-+#define r1(p,q,r,s) 0x##q##r##s##p
-+#define r2(p,q,r,s) 0x##r##s##p##q
-+#define r3(p,q,r,s) 0x##s##p##q##r
-+#define w0(p) 0x000000##p
-+#define w1(p) 0x0000##p##00
-+#define w2(p) 0x00##p##0000
-+#define w3(p) 0x##p##000000
-+
-+#if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES))
-+
-+// data for forward tables (other than last round)
-+
-+#define f_table \
-+ r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\
-+ r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\
-+ r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56),\
-+ r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec),\
-+ r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa),\
-+ r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb),\
-+ r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45),\
-+ r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b),\
-+ r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c),\
-+ r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83),\
-+ r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9),\
-+ r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a),\
-+ r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d),\
-+ r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f),\
-+ r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df),\
-+ r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea),\
-+ r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34),\
-+ r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b),\
-+ r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d),\
-+ r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13),\
-+ r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1),\
-+ r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6),\
-+ r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72),\
-+ r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85),\
-+ r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed),\
-+ r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11),\
-+ r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe),\
-+ r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b),\
-+ r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05),\
-+ r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1),\
-+ r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42),\
-+ r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf),\
-+ r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3),\
-+ r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e),\
-+ r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a),\
-+ r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6),\
-+ r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3),\
-+ r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b),\
-+ r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28),\
-+ r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad),\
-+ r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14),\
-+ r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8),\
-+ r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4),\
-+ r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2),\
-+ r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da),\
-+ r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49),\
-+ r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf),\
-+ r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10),\
-+ r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c),\
-+ r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97),\
-+ r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e),\
-+ r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f),\
-+ r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc),\
-+ r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c),\
-+ r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69),\
-+ r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27),\
-+ r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22),\
-+ r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33),\
-+ r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9),\
-+ r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5),\
-+ r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a),\
-+ r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0),\
-+ r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\
-+ r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c)
-+
-+// data for inverse tables (other than last round)
-+
-+#define i_table \
-+ r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\
-+ r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\
-+ r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5),\
-+ r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5),\
-+ r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d),\
-+ r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b),\
-+ r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95),\
-+ r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e),\
-+ r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27),\
-+ r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d),\
-+ r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62),\
-+ r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9),\
-+ r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52),\
-+ r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66),\
-+ r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3),\
-+ r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed),\
-+ r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e),\
-+ r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4),\
-+ r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4),\
-+ r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd),\
-+ r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d),\
-+ r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60),\
-+ r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67),\
-+ r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79),\
-+ r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00),\
-+ r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c),\
-+ r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36),\
-+ r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24),\
-+ r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b),\
-+ r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c),\
-+ r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12),\
-+ r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14),\
-+ r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3),\
-+ r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b),\
-+ r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8),\
-+ r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84),\
-+ r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7),\
-+ r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77),\
-+ r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47),\
-+ r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22),\
-+ r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98),\
-+ r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f),\
-+ r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54),\
-+ r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82),\
-+ r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf),\
-+ r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db),\
-+ r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83),\
-+ r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef),\
-+ r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29),\
-+ r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35),\
-+ r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33),\
-+ r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17),\
-+ r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4),\
-+ r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46),\
-+ r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb),\
-+ r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d),\
-+ r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb),\
-+ r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a),\
-+ r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73),\
-+ r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78),\
-+ r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2),\
-+ r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff),\
-+ r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\
-+ r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0)
-+
-+// generate the required tables in the desired endian format
-+
-+#undef r
-+#define r r0
-+
-+#if defined(ONE_TABLE)
-+static const u_int32_t ft_tab[256] =
-+ { f_table };
-+#elif defined(FOUR_TABLES)
-+static const u_int32_t ft_tab[4][256] =
-+{ { f_table },
-+#undef r
-+#define r r1
-+ { f_table },
-+#undef r
-+#define r r2
-+ { f_table },
-+#undef r
-+#define r r3
-+ { f_table }
-+};
-+#endif
-+
-+#undef r
-+#define r r0
-+#if defined(ONE_TABLE)
-+static const u_int32_t it_tab[256] =
-+ { i_table };
-+#elif defined(FOUR_TABLES)
-+static const u_int32_t it_tab[4][256] =
-+{ { i_table },
-+#undef r
-+#define r r1
-+ { i_table },
-+#undef r
-+#define r r2
-+ { i_table },
-+#undef r
-+#define r r3
-+ { i_table }
-+};
-+#endif
-+
-+#endif
-+
-+#if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES))
-+
-+// data for inverse tables (last round)
-+
-+#define li_table \
-+ w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\
-+ w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\
-+ w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87),\
-+ w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb),\
-+ w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d),\
-+ w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e),\
-+ w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2),\
-+ w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25),\
-+ w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16),\
-+ w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92),\
-+ w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da),\
-+ w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84),\
-+ w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a),\
-+ w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06),\
-+ w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02),\
-+ w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b),\
-+ w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea),\
-+ w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73),\
-+ w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85),\
-+ w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e),\
-+ w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89),\
-+ w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b),\
-+ w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20),\
-+ w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4),\
-+ w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31),\
-+ w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f),\
-+ w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d),\
-+ w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef),\
-+ w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0),\
-+ w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61),\
-+ w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\
-+ w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d),
-+
-+// generate the required tables in the desired endian format
-+
-+#undef r
-+#define r(p,q,r,s) w0(q)
-+#if defined(ONE_LR_TABLE)
-+static const u_int32_t fl_tab[256] =
-+ { f_table };
-+#elif defined(FOUR_LR_TABLES)
-+static const u_int32_t fl_tab[4][256] =
-+{ { f_table },
-+#undef r
-+#define r(p,q,r,s) w1(q)
-+ { f_table },
-+#undef r
-+#define r(p,q,r,s) w2(q)
-+ { f_table },
-+#undef r
-+#define r(p,q,r,s) w3(q)
-+ { f_table }
-+};
-+#endif
-+
-+#undef w
-+#define w w0
-+#if defined(ONE_LR_TABLE)
-+static const u_int32_t il_tab[256] =
-+ { li_table };
-+#elif defined(FOUR_LR_TABLES)
-+static const u_int32_t il_tab[4][256] =
-+{ { li_table },
-+#undef w
-+#define w w1
-+ { li_table },
-+#undef w
-+#define w w2
-+ { li_table },
-+#undef w
-+#define w w3
-+ { li_table }
-+};
-+#endif
-+
-+#endif
-+
-+#if defined(FIXED_TABLES) && (defined(ONE_IM_TABLE) || defined(FOUR_IM_TABLES))
-+
-+#define m_table \
-+ r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12),\
-+ r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a),\
-+ r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62),\
-+ r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a),\
-+ r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2),\
-+ r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca),\
-+ r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82),\
-+ r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba),\
-+ r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9),\
-+ r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1),\
-+ r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9),\
-+ r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81),\
-+ r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29),\
-+ r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11),\
-+ r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59),\
-+ r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61),\
-+ r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf),\
-+ r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87),\
-+ r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf),\
-+ r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7),\
-+ r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f),\
-+ r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67),\
-+ r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f),\
-+ r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17),\
-+ r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64),\
-+ r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c),\
-+ r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14),\
-+ r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c),\
-+ r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84),\
-+ r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc),\
-+ r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4),\
-+ r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc),\
-+ r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53),\
-+ r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b),\
-+ r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23),\
-+ r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b),\
-+ r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3),\
-+ r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b),\
-+ r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3),\
-+ r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb),\
-+ r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88),\
-+ r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0),\
-+ r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8),\
-+ r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0),\
-+ r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68),\
-+ r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50),\
-+ r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18),\
-+ r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20),\
-+ r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe),\
-+ r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6),\
-+ r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e),\
-+ r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6),\
-+ r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e),\
-+ r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26),\
-+ r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e),\
-+ r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56),\
-+ r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25),\
-+ r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d),\
-+ r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55),\
-+ r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d),\
-+ r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5),\
-+ r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd),\
-+ r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5),\
-+ r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d)
-+
-+#undef r
-+#define r r0
-+
-+#if defined(ONE_IM_TABLE)
-+static const u_int32_t im_tab[256] =
-+ { m_table };
-+#elif defined(FOUR_IM_TABLES)
-+static const u_int32_t im_tab[4][256] =
-+{ { m_table },
-+#undef r
-+#define r r1
-+ { m_table },
-+#undef r
-+#define r r2
-+ { m_table },
-+#undef r
-+#define r r3
-+ { m_table }
-+};
-+#endif
-+
-+#endif
-+
-+#else
-+
-+static int tab_gen = 0;
-+
-+static unsigned char s_box[256]; // the S box
-+static unsigned char inv_s_box[256]; // the inverse S box
-+static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants
-+
-+#if defined(ONE_TABLE)
-+static u_int32_t ft_tab[256];
-+static u_int32_t it_tab[256];
-+#elif defined(FOUR_TABLES)
-+static u_int32_t ft_tab[4][256];
-+static u_int32_t it_tab[4][256];
-+#endif
-+
-+#if defined(ONE_LR_TABLE)
-+static u_int32_t fl_tab[256];
-+static u_int32_t il_tab[256];
-+#elif defined(FOUR_LR_TABLES)
-+static u_int32_t fl_tab[4][256];
-+static u_int32_t il_tab[4][256];
-+#endif
-+
-+#if defined(ONE_IM_TABLE)
-+static u_int32_t im_tab[256];
-+#elif defined(FOUR_IM_TABLES)
-+static u_int32_t im_tab[4][256];
-+#endif
-+
-+// Generate the tables for the dynamic table option
-+
-+#if !defined(FF_TABLES)
-+
-+// It will generally be sensible to use tables to compute finite
-+// field multiplies and inverses but where memory is scarse this
-+// code might sometimes be better.
-+
-+// return 2 ^ (n - 1) where n is the bit number of the highest bit
-+// set in x with x in the range 1 < x < 0x00000200. This form is
-+// used so that locals within FFinv can be bytes rather than words
-+
-+static unsigned char hibit(const u_int32_t x)
-+{ unsigned char r = (unsigned char)((x >> 1) | (x >> 2));
-+
-+ r |= (r >> 2);
-+ r |= (r >> 4);
-+ return (r + 1) >> 1;
-+}
-+
-+// return the inverse of the finite field element x
-+
-+static unsigned char FFinv(const unsigned char x)
-+{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
-+
-+ if(x < 2) return x;
-+
-+ for(;;)
-+ {
-+ if(!n1) return v1;
-+
-+ while(n2 >= n1)
-+ {
-+ n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
-+ }
-+
-+ if(!n2) return v2;
-+
-+ while(n1 >= n2)
-+ {
-+ n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
-+ }
-+ }
-+}
-+
-+// define the finite field multiplies required for Rijndael
-+
-+#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0))
-+#define FFmul03(x) ((x) ^ FFmul02(x))
-+#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x))))
-+#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x))))
-+#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x))))
-+#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x)))
-+
-+#else
-+
-+#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
-+
-+#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
-+#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
-+#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
-+#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
-+#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
-+#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
-+
-+#endif
-+
-+// The forward and inverse affine transformations used in the S-box
-+
-+#define fwd_affine(x) \
-+ (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8)))
-+
-+#define inv_affine(x) \
-+ (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8)))
-+
-+static void gen_tabs(void)
-+{ u_int32_t i, w;
-+
-+#if defined(FF_TABLES)
-+
-+ unsigned char pow[512], log[256];
-+
-+ // log and power tables for GF(2^8) finite field with
-+ // 0x011b as modular polynomial - the simplest primitive
-+ // root is 0x03, used here to generate the tables
-+
-+ i = 0; w = 1;
-+ do
-+ {
-+ pow[i] = (unsigned char)w;
-+ pow[i + 255] = (unsigned char)w;
-+ log[w] = (unsigned char)i++;
-+ w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
-+ }
-+ while (w != 1);
-+
-+#endif
-+
-+ for(i = 0, w = 1; i < AES_RC_LENGTH; ++i)
-+ {
-+ rcon_tab[i] = bytes2word(w, 0, 0, 0);
-+ w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
-+ }
-+
-+ for(i = 0; i < 256; ++i)
-+ { unsigned char b;
-+
-+ s_box[i] = b = fwd_affine(FFinv((unsigned char)i));
-+
-+ w = bytes2word(b, 0, 0, 0);
-+#if defined(ONE_LR_TABLE)
-+ fl_tab[i] = w;
-+#elif defined(FOUR_LR_TABLES)
-+ fl_tab[0][i] = w;
-+ fl_tab[1][i] = upr(w,1);
-+ fl_tab[2][i] = upr(w,2);
-+ fl_tab[3][i] = upr(w,3);
-+#endif
-+ w = bytes2word(FFmul02(b), b, b, FFmul03(b));
-+#if defined(ONE_TABLE)
-+ ft_tab[i] = w;
-+#elif defined(FOUR_TABLES)
-+ ft_tab[0][i] = w;
-+ ft_tab[1][i] = upr(w,1);
-+ ft_tab[2][i] = upr(w,2);
-+ ft_tab[3][i] = upr(w,3);
-+#endif
-+ inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i));
-+
-+ w = bytes2word(b, 0, 0, 0);
-+#if defined(ONE_LR_TABLE)
-+ il_tab[i] = w;
-+#elif defined(FOUR_LR_TABLES)
-+ il_tab[0][i] = w;
-+ il_tab[1][i] = upr(w,1);
-+ il_tab[2][i] = upr(w,2);
-+ il_tab[3][i] = upr(w,3);
-+#endif
-+ w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b));
-+#if defined(ONE_TABLE)
-+ it_tab[i] = w;
-+#elif defined(FOUR_TABLES)
-+ it_tab[0][i] = w;
-+ it_tab[1][i] = upr(w,1);
-+ it_tab[2][i] = upr(w,2);
-+ it_tab[3][i] = upr(w,3);
-+#endif
-+#if defined(ONE_IM_TABLE)
-+ im_tab[b] = w;
-+#elif defined(FOUR_IM_TABLES)
-+ im_tab[0][b] = w;
-+ im_tab[1][b] = upr(w,1);
-+ im_tab[2][b] = upr(w,2);
-+ im_tab[3][b] = upr(w,3);
-+#endif
-+
-+ }
-+}
-+
-+#endif
-+
-+#define no_table(x,box,vf,rf,c) bytes2word( \
-+ box[bval(vf(x,0,c),rf(0,c))], \
-+ box[bval(vf(x,1,c),rf(1,c))], \
-+ box[bval(vf(x,2,c),rf(2,c))], \
-+ box[bval(vf(x,3,c),rf(3,c))])
-+
-+#define one_table(x,op,tab,vf,rf,c) \
-+ ( tab[bval(vf(x,0,c),rf(0,c))] \
-+ ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
-+ ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
-+ ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
-+
-+#define four_tables(x,tab,vf,rf,c) \
-+ ( tab[0][bval(vf(x,0,c),rf(0,c))] \
-+ ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
-+ ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
-+ ^ tab[3][bval(vf(x,3,c),rf(3,c))])
-+
-+#define vf1(x,r,c) (x)
-+#define rf1(r,c) (r)
-+#define rf2(r,c) ((r-c)&3)
-+
-+#if defined(FOUR_LR_TABLES)
-+#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
-+#elif defined(ONE_LR_TABLE)
-+#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
-+#else
-+#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
-+#endif
-+
-+#if defined(FOUR_IM_TABLES)
-+#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
-+#elif defined(ONE_IM_TABLE)
-+#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
-+#else
-+#define inv_mcol(x) \
-+ (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
-+ f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
-+#endif
-+
-+// Subroutine to set the block size (if variable) in bytes, legal
-+// values being 16, 24 and 32.
-+
-+#if defined(AES_BLOCK_SIZE)
-+#define nc (AES_BLOCK_SIZE / 4)
-+#else
-+#define nc (cx->aes_Ncol)
-+
-+void aes_set_blk(aes_context *cx, int n_bytes)
-+{
-+#if !defined(FIXED_TABLES)
-+ if(!tab_gen) { gen_tabs(); tab_gen = 1; }
-+#endif
-+
-+ switch(n_bytes) {
-+ case 32: /* bytes */
-+ case 256: /* bits */
-+ nc = 8;
-+ break;
-+ case 24: /* bytes */
-+ case 192: /* bits */
-+ nc = 6;
-+ break;
-+ case 16: /* bytes */
-+ case 128: /* bits */
-+ default:
-+ nc = 4;
-+ break;
-+ }
-+}
-+
-+#endif
-+
-+// Initialise the key schedule from the user supplied key. The key
-+// length is now specified in bytes - 16, 24 or 32 as appropriate.
-+// This corresponds to bit lengths of 128, 192 and 256 bits, and
-+// to Nk values of 4, 6 and 8 respectively.
-+
-+#define mx(t,f) (*t++ = inv_mcol(*f),f++)
-+#define cp(t,f) *t++ = *f++
-+
-+#if AES_BLOCK_SIZE == 16
-+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s)
-+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s)
-+#elif AES_BLOCK_SIZE == 24
-+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
-+ cp(d,s); cp(d,s)
-+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
-+ mx(d,s); mx(d,s)
-+#elif AES_BLOCK_SIZE == 32
-+#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
-+ cp(d,s); cp(d,s); cp(d,s); cp(d,s)
-+#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
-+ mx(d,s); mx(d,s); mx(d,s); mx(d,s)
-+#else
-+
-+#define cpy(d,s) \
-+switch(nc) \
-+{ case 8: cp(d,s); cp(d,s); \
-+ case 6: cp(d,s); cp(d,s); \
-+ case 4: cp(d,s); cp(d,s); \
-+ cp(d,s); cp(d,s); \
-+}
-+
-+#define mix(d,s) \
-+switch(nc) \
-+{ case 8: mx(d,s); mx(d,s); \
-+ case 6: mx(d,s); mx(d,s); \
-+ case 4: mx(d,s); mx(d,s); \
-+ mx(d,s); mx(d,s); \
-+}
-+
-+#endif
-+
-+void aes_set_key(aes_context *cx, const unsigned char in_key[], int n_bytes, const int f)
-+{ u_int32_t *kf, *kt, rci;
-+
-+#if !defined(FIXED_TABLES)
-+ if(!tab_gen) { gen_tabs(); tab_gen = 1; }
-+#endif
-+
-+ switch(n_bytes) {
-+ case 32: /* bytes */
-+ case 256: /* bits */
-+ cx->aes_Nkey = 8;
-+ break;
-+ case 24: /* bytes */
-+ case 192: /* bits */
-+ cx->aes_Nkey = 6;
-+ break;
-+ case 16: /* bytes */
-+ case 128: /* bits */
-+ default:
-+ cx->aes_Nkey = 4;
-+ break;
-+ }
-+
-+ cx->aes_Nrnd = (cx->aes_Nkey > nc ? cx->aes_Nkey : nc) + 6;
-+
-+ cx->aes_e_key[0] = const_word_in(in_key );
-+ cx->aes_e_key[1] = const_word_in(in_key + 4);
-+ cx->aes_e_key[2] = const_word_in(in_key + 8);
-+ cx->aes_e_key[3] = const_word_in(in_key + 12);
-+
-+ kf = cx->aes_e_key;
-+ kt = kf + nc * (cx->aes_Nrnd + 1) - cx->aes_Nkey;
-+ rci = 0;
-+
-+ switch(cx->aes_Nkey)
-+ {
-+ case 4: do
-+ { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++];
-+ kf[5] = kf[1] ^ kf[4];
-+ kf[6] = kf[2] ^ kf[5];
-+ kf[7] = kf[3] ^ kf[6];
-+ kf += 4;
-+ }
-+ while(kf < kt);
-+ break;
-+
-+ case 6: cx->aes_e_key[4] = const_word_in(in_key + 16);
-+ cx->aes_e_key[5] = const_word_in(in_key + 20);
-+ do
-+ { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++];
-+ kf[ 7] = kf[1] ^ kf[ 6];
-+ kf[ 8] = kf[2] ^ kf[ 7];
-+ kf[ 9] = kf[3] ^ kf[ 8];
-+ kf[10] = kf[4] ^ kf[ 9];
-+ kf[11] = kf[5] ^ kf[10];
-+ kf += 6;
-+ }
-+ while(kf < kt);
-+ break;
-+
-+ case 8: cx->aes_e_key[4] = const_word_in(in_key + 16);
-+ cx->aes_e_key[5] = const_word_in(in_key + 20);
-+ cx->aes_e_key[6] = const_word_in(in_key + 24);
-+ cx->aes_e_key[7] = const_word_in(in_key + 28);
-+ do
-+ { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++];
-+ kf[ 9] = kf[1] ^ kf[ 8];
-+ kf[10] = kf[2] ^ kf[ 9];
-+ kf[11] = kf[3] ^ kf[10];
-+ kf[12] = kf[4] ^ ls_box(kf[11],0);
-+ kf[13] = kf[5] ^ kf[12];
-+ kf[14] = kf[6] ^ kf[13];
-+ kf[15] = kf[7] ^ kf[14];
-+ kf += 8;
-+ }
-+ while (kf < kt);
-+ break;
-+ }
-+
-+ if(!f)
-+ { u_int32_t i;
-+
-+ kt = cx->aes_d_key + nc * cx->aes_Nrnd;
-+ kf = cx->aes_e_key;
-+
-+ cpy(kt, kf); kt -= 2 * nc;
-+
-+ for(i = 1; i < cx->aes_Nrnd; ++i)
-+ {
-+#if defined(ONE_TABLE) || defined(FOUR_TABLES)
-+#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES)
-+ u_int32_t f2, f4, f8, f9;
-+#endif
-+ mix(kt, kf);
-+#else
-+ cpy(kt, kf);
-+#endif
-+ kt -= 2 * nc;
-+ }
-+
-+ cpy(kt, kf);
-+ }
-+}
-+
-+// y = output word, x = input word, r = row, c = column
-+// for r = 0, 1, 2 and 3 = column accessed for row r
-+
-+#if defined(ARRAYS)
-+#define s(x,c) x[c]
-+#else
-+#define s(x,c) x##c
-+#endif
-+
-+// I am grateful to Frank Yellin for the following constructions
-+// which, given the column (c) of the output state variable that
-+// is being computed, return the input state variables which are
-+// needed for each row (r) of the state
-+
-+// For the fixed block size options, compilers reduce these two
-+// expressions to fixed variable references. For variable block
-+// size code conditional clauses will sometimes be returned
-+
-+#define unused 77 // Sunset Strip
-+
-+#define fwd_var(x,r,c) \
-+ ( r==0 ? \
-+ ( c==0 ? s(x,0) \
-+ : c==1 ? s(x,1) \
-+ : c==2 ? s(x,2) \
-+ : c==3 ? s(x,3) \
-+ : c==4 ? s(x,4) \
-+ : c==5 ? s(x,5) \
-+ : c==6 ? s(x,6) \
-+ : s(x,7)) \
-+ : r==1 ? \
-+ ( c==0 ? s(x,1) \
-+ : c==1 ? s(x,2) \
-+ : c==2 ? s(x,3) \
-+ : c==3 ? nc==4 ? s(x,0) : s(x,4) \
-+ : c==4 ? s(x,5) \
-+ : c==5 ? nc==8 ? s(x,6) : s(x,0) \
-+ : c==6 ? s(x,7) \
-+ : s(x,0)) \
-+ : r==2 ? \
-+ ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
-+ : c==1 ? nc==8 ? s(x,4) : s(x,3) \
-+ : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
-+ : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
-+ : c==4 ? nc==8 ? s(x,7) : s(x,0) \
-+ : c==5 ? nc==8 ? s(x,0) : s(x,1) \
-+ : c==6 ? s(x,1) \
-+ : s(x,2)) \
-+ : \
-+ ( c==0 ? nc==8 ? s(x,4) : s(x,3) \
-+ : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
-+ : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
-+ : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \
-+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
-+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
-+ : c==6 ? s(x,2) \
-+ : s(x,3)))
-+
-+#define inv_var(x,r,c) \
-+ ( r==0 ? \
-+ ( c==0 ? s(x,0) \
-+ : c==1 ? s(x,1) \
-+ : c==2 ? s(x,2) \
-+ : c==3 ? s(x,3) \
-+ : c==4 ? s(x,4) \
-+ : c==5 ? s(x,5) \
-+ : c==6 ? s(x,6) \
-+ : s(x,7)) \
-+ : r==1 ? \
-+ ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \
-+ : c==1 ? s(x,0) \
-+ : c==2 ? s(x,1) \
-+ : c==3 ? s(x,2) \
-+ : c==4 ? s(x,3) \
-+ : c==5 ? s(x,4) \
-+ : c==6 ? s(x,5) \
-+ : s(x,6)) \
-+ : r==2 ? \
-+ ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
-+ : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
-+ : c==2 ? nc==8 ? s(x,7) : s(x,0) \
-+ : c==3 ? nc==8 ? s(x,0) : s(x,1) \
-+ : c==4 ? nc==8 ? s(x,1) : s(x,2) \
-+ : c==5 ? nc==8 ? s(x,2) : s(x,3) \
-+ : c==6 ? s(x,3) \
-+ : s(x,4)) \
-+ : \
-+ ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \
-+ : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
-+ : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
-+ : c==3 ? nc==8 ? s(x,7) : s(x,0) \
-+ : c==4 ? nc==8 ? s(x,0) : s(x,1) \
-+ : c==5 ? nc==8 ? s(x,1) : s(x,2) \
-+ : c==6 ? s(x,2) \
-+ : s(x,3)))
-+
-+#define si(y,x,k,c) s(y,c) = const_word_in(x + 4 * c) ^ k[c]
-+#define so(y,x,c) word_out(y + 4 * c, s(x,c))
-+
-+#if defined(FOUR_TABLES)
-+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
-+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
-+#elif defined(ONE_TABLE)
-+#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
-+#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
-+#else
-+#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
-+#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
-+#endif
-+
-+#if defined(FOUR_LR_TABLES)
-+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
-+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
-+#elif defined(ONE_LR_TABLE)
-+#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
-+#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
-+#else
-+#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
-+#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
-+#endif
-+
-+#if AES_BLOCK_SIZE == 16
-+
-+#if defined(ARRAYS)
-+#define locals(y,x) x[4],y[4]
-+#else
-+#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
-+// the following defines prevent the compiler requiring the declaration
-+// of generated but unused variables in the fwd_var and inv_var macros
-+#define b04 unused
-+#define b05 unused
-+#define b06 unused
-+#define b07 unused
-+#define b14 unused
-+#define b15 unused
-+#define b16 unused
-+#define b17 unused
-+#endif
-+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
-+ s(y,2) = s(x,2); s(y,3) = s(x,3);
-+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
-+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
-+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
-+
-+#elif AES_BLOCK_SIZE == 24
-+
-+#if defined(ARRAYS)
-+#define locals(y,x) x[6],y[6]
-+#else
-+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
-+ y##0,y##1,y##2,y##3,y##4,y##5
-+#define b06 unused
-+#define b07 unused
-+#define b16 unused
-+#define b17 unused
-+#endif
-+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
-+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
-+ s(y,4) = s(x,4); s(y,5) = s(x,5);
-+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
-+ si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
-+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
-+ so(y,x,3); so(y,x,4); so(y,x,5)
-+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
-+ rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
-+#else
-+
-+#if defined(ARRAYS)
-+#define locals(y,x) x[8],y[8]
-+#else
-+#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
-+ y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
-+#endif
-+#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
-+ s(y,2) = s(x,2); s(y,3) = s(x,3); \
-+ s(y,4) = s(x,4); s(y,5) = s(x,5); \
-+ s(y,6) = s(x,6); s(y,7) = s(x,7);
-+
-+#if AES_BLOCK_SIZE == 32
-+
-+#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
-+ si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
-+#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
-+ so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
-+#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
-+ rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
-+#else
-+
-+#define state_in(y,x,k) \
-+switch(nc) \
-+{ case 8: si(y,x,k,7); si(y,x,k,6); \
-+ case 6: si(y,x,k,5); si(y,x,k,4); \
-+ case 4: si(y,x,k,3); si(y,x,k,2); \
-+ si(y,x,k,1); si(y,x,k,0); \
-+}
-+
-+#define state_out(y,x) \
-+switch(nc) \
-+{ case 8: so(y,x,7); so(y,x,6); \
-+ case 6: so(y,x,5); so(y,x,4); \
-+ case 4: so(y,x,3); so(y,x,2); \
-+ so(y,x,1); so(y,x,0); \
-+}
-+
-+#if defined(FAST_VARIABLE)
-+
-+#define round(rm,y,x,k) \
-+switch(nc) \
-+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
-+ rm(y,x,k,5); rm(y,x,k,4); \
-+ rm(y,x,k,3); rm(y,x,k,2); \
-+ rm(y,x,k,1); rm(y,x,k,0); \
-+ break; \
-+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
-+ rm(y,x,k,3); rm(y,x,k,2); \
-+ rm(y,x,k,1); rm(y,x,k,0); \
-+ break; \
-+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
-+ rm(y,x,k,1); rm(y,x,k,0); \
-+ break; \
-+}
-+#else
-+
-+#define round(rm,y,x,k) \
-+switch(nc) \
-+{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
-+ case 6: rm(y,x,k,5); rm(y,x,k,4); \
-+ case 4: rm(y,x,k,3); rm(y,x,k,2); \
-+ rm(y,x,k,1); rm(y,x,k,0); \
-+}
-+
-+#endif
-+
-+#endif
-+#endif
-+
-+void aes_encrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
-+{ u_int32_t locals(b0, b1);
-+ const u_int32_t *kp = cx->aes_e_key;
-+
-+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
-+ u_int32_t f2;
-+#endif
-+
-+ state_in(b0, in_blk, kp); kp += nc;
-+
-+#if defined(UNROLL)
-+
-+ switch(cx->aes_Nrnd)
-+ {
-+ case 14: round(fwd_rnd, b1, b0, kp );
-+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
-+ case 12: round(fwd_rnd, b1, b0, kp );
-+ round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
-+ case 10: round(fwd_rnd, b1, b0, kp );
-+ round(fwd_rnd, b0, b1, kp + nc);
-+ round(fwd_rnd, b1, b0, kp + 2 * nc);
-+ round(fwd_rnd, b0, b1, kp + 3 * nc);
-+ round(fwd_rnd, b1, b0, kp + 4 * nc);
-+ round(fwd_rnd, b0, b1, kp + 5 * nc);
-+ round(fwd_rnd, b1, b0, kp + 6 * nc);
-+ round(fwd_rnd, b0, b1, kp + 7 * nc);
-+ round(fwd_rnd, b1, b0, kp + 8 * nc);
-+ round(fwd_lrnd, b0, b1, kp + 9 * nc);
-+ }
-+
-+#elif defined(PARTIAL_UNROLL)
-+ { u_int32_t rnd;
-+
-+ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
-+ {
-+ round(fwd_rnd, b1, b0, kp);
-+ round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc;
-+ }
-+
-+ round(fwd_rnd, b1, b0, kp);
-+ round(fwd_lrnd, b0, b1, kp + nc);
-+ }
-+#else
-+ { u_int32_t rnd;
-+
-+ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
-+ {
-+ round(fwd_rnd, b1, b0, kp);
-+ l_copy(b0, b1); kp += nc;
-+ }
-+
-+ round(fwd_lrnd, b0, b1, kp);
-+ }
-+#endif
-+
-+ state_out(out_blk, b0);
-+}
-+
-+void aes_decrypt(const aes_context *cx, const unsigned char in_blk[], unsigned char out_blk[])
-+{ u_int32_t locals(b0, b1);
-+ const u_int32_t *kp = cx->aes_d_key;
-+
-+#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
-+ u_int32_t f2, f4, f8, f9;
-+#endif
-+
-+ state_in(b0, in_blk, kp); kp += nc;
-+
-+#if defined(UNROLL)
-+
-+ switch(cx->aes_Nrnd)
-+ {
-+ case 14: round(inv_rnd, b1, b0, kp );
-+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
-+ case 12: round(inv_rnd, b1, b0, kp );
-+ round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
-+ case 10: round(inv_rnd, b1, b0, kp );
-+ round(inv_rnd, b0, b1, kp + nc);
-+ round(inv_rnd, b1, b0, kp + 2 * nc);
-+ round(inv_rnd, b0, b1, kp + 3 * nc);
-+ round(inv_rnd, b1, b0, kp + 4 * nc);
-+ round(inv_rnd, b0, b1, kp + 5 * nc);
-+ round(inv_rnd, b1, b0, kp + 6 * nc);
-+ round(inv_rnd, b0, b1, kp + 7 * nc);
-+ round(inv_rnd, b1, b0, kp + 8 * nc);
-+ round(inv_lrnd, b0, b1, kp + 9 * nc);
-+ }
-+
-+#elif defined(PARTIAL_UNROLL)
-+ { u_int32_t rnd;
-+
-+ for(rnd = 0; rnd < (cx->aes_Nrnd >> 1) - 1; ++rnd)
-+ {
-+ round(inv_rnd, b1, b0, kp);
-+ round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc;
-+ }
-+
-+ round(inv_rnd, b1, b0, kp);
-+ round(inv_lrnd, b0, b1, kp + nc);
-+ }
-+#else
-+ { u_int32_t rnd;
-+
-+ for(rnd = 0; rnd < cx->aes_Nrnd - 1; ++rnd)
-+ {
-+ round(inv_rnd, b1, b0, kp);
-+ l_copy(b0, b1); kp += nc;
-+ }
-+
-+ round(inv_lrnd, b0, b1, kp);
-+ }
-+#endif
-+
-+ state_out(out_blk, b0);
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/aes/aes_cbc.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,43 @@
-+/*
-+// I retain copyright in this code but I encourage its free use provided
-+// that I don't carry any responsibility for the results. I am especially
-+// happy to see it used in free and open source software. If you do use
-+// it I would appreciate an acknowledgement of its origin in the code or
-+// the product that results and I would also appreciate knowing a little
-+// about the use to which it is being put. I am grateful to Frank Yellin
-+// for some ideas that are used in this implementation.
-+//
-+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
-+//
-+// This is an implementation of the AES encryption algorithm (Rijndael)
-+// designed by Joan Daemen and Vincent Rijmen. This version is designed
-+// to provide both fixed and dynamic block and key lengths and can also
-+// run with either big or little endian internal byte order (see aes.h).
-+// It inputs block and key lengths in bytes with the legal values being
-+// 16, 24 and 32.
-+*
-+*/
-+
-+#ifdef __KERNEL__
-+#include <linux/types.h>
-+#else
-+#include <sys/types.h>
-+#endif
-+#include "crypto/aes_cbc.h"
-+#include "crypto/cbc_generic.h"
-+
-+/* returns bool success */
-+int AES_set_key(aes_context *aes_ctx, const u_int8_t *key, int keysize) {
-+ aes_set_key(aes_ctx, key, keysize, 0);
-+ return 1;
-+}
-+CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.1 2004/04/06 02:48:12 mcr
-+ * pullup of AES cipher from alg-branch.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/aes/aes_xcbc_mac.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,67 @@
-+#ifdef __KERNEL__
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#define DEBUG(x)
-+#else
-+#include <stdio.h>
-+#include <sys/types.h>
-+#define DEBUG(x) x
-+#endif
-+
-+#include "crypto/aes.h"
-+#include "crypto/aes_xcbc_mac.h"
-+
-+int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen)
-+{
-+ int ret=1;
-+ aes_block kn[3] = {
-+ { 0x01010101, 0x01010101, 0x01010101, 0x01010101 },
-+ { 0x02020202, 0x02020202, 0x02020202, 0x02020202 },
-+ { 0x03030303, 0x03030303, 0x03030303, 0x03030303 },
-+ };
-+ aes_set_key(&ctxm->ctx_k1, key, keylen, 0);
-+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[0], (u_int8_t *) kn[0]);
-+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[1], (u_int8_t *) ctxm->k2);
-+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *) kn[2], (u_int8_t *) ctxm->k3);
-+ aes_set_key(&ctxm->ctx_k1, (u_int8_t *) kn[0], 16, 0);
-+ return ret;
-+}
-+static void do_pad_xor(u_int8_t *out, const u_int8_t *in, int len) {
-+ int pos=0;
-+ for (pos=1; pos <= 16; pos++, in++, out++) {
-+ if (pos <= len)
-+ *out ^= *in;
-+ if (pos > len) {
-+ DEBUG(printf("put 0x80 at pos=%d\n", pos));
-+ *out ^= 0x80;
-+ break;
-+ }
-+ }
-+}
-+static void xor_block(aes_block res, const aes_block op) {
-+ res[0] ^= op[0];
-+ res[1] ^= op[1];
-+ res[2] ^= op[2];
-+ res[3] ^= op[3];
-+}
-+int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]) {
-+ int ret=ilen;
-+ u_int32_t out[4] = { 0, 0, 0, 0 };
-+ for (; ilen > 16 ; ilen-=16) {
-+ xor_block(out, (const u_int32_t*) &in[0]);
-+ aes_encrypt(&ctxm->ctx_k1, in, (u_int8_t *)&out[0]);
-+ in+=16;
-+ }
-+ do_pad_xor((u_int8_t *)&out, in, ilen);
-+ if (ilen==16) {
-+ DEBUG(printf("using k3\n"));
-+ xor_block(out, ctxm->k3);
-+ }
-+ else
-+ {
-+ DEBUG(printf("using k2\n"));
-+ xor_block(out, ctxm->k2);
-+ }
-+ aes_encrypt(&ctxm->ctx_k1, (u_int8_t *)out, hash);
-+ return ret;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/aes/test_main.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,41 @@
-+#include <stdio.h>
-+#include <string.h>
-+#include <sys/types.h>
-+#include "aes_cbc.h"
-+#define AES_BLOCK_SIZE 16
-+#define KEY_SIZE 128 /* bits */
-+#define KEY "1234567890123456"
-+#define STR "hola guaso como estaisss ... 012"
-+#define STRSZ (sizeof(STR)-1)
-+
-+#define EMT_AESCBC_BLKLEN AES_BLOCK_SIZE
-+#define AES_CONTEXT_T aes_context
-+#define EMT_ESPAES_KEY_SZ 16
-+int pretty_print(const unsigned char *buf, int count) {
-+ int i=0;
-+ for (;i<count;i++) {
-+ if (i%8==0) putchar(' ');
-+ if (i%16==0) putchar('\n');
-+ printf ("%02hhx ", buf[i]);
-+ }
-+ putchar('\n');
-+ return i;
-+}
-+//#define SIZE STRSZ/2
-+#define SIZE STRSZ
-+int main() {
-+ int ret;
-+ char buf0[SIZE+1], buf1[SIZE+1];
-+ char IV[AES_BLOCK_SIZE]="\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0";
-+ aes_context ac;
-+ AES_set_key(&ac, KEY, KEY_SIZE);
-+ //pretty_print((char *)&ac.aes_e_key, sizeof(ac.aes_e_key));
-+ memset(buf0, 0, sizeof (buf0));
-+ memset(buf1, 0, sizeof (buf1));
-+ ret=AES_cbc_encrypt(&ac, STR, buf0, SIZE, IV, 1);
-+ pretty_print(buf0, SIZE);
-+ printf("size=%d ret=%d\n%s\n", SIZE, ret, buf0);
-+ ret=AES_cbc_encrypt(&ac, buf0, buf1, SIZE, IV, 0);
-+ printf("size=%d ret=%d\n%s\n", SIZE, ret, buf1);
-+ return 0;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/aes/test_main_mac.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,30 @@
-+#include <stdio.h>
-+#include <sys/types.h>
-+#include <string.h>
-+#include "aes.h"
-+#include "aes_xcbc_mac.h"
-+#define STR "Hola guasssso c|mo estais ...012"
-+void print_hash(const __u8 *hash) {
-+ printf("%08x %08x %08x %08x\n",
-+ *(__u32*)(&hash[0]),
-+ *(__u32*)(&hash[4]),
-+ *(__u32*)(&hash[8]),
-+ *(__u32*)(&hash[12]));
-+}
-+int main(int argc, char *argv[]) {
-+ aes_block key= { 0xdeadbeef, 0xceedcaca, 0xcafebabe, 0xff010204 };
-+ __u8 hash[16];
-+ char *str = argv[1];
-+ aes_context_mac ctx;
-+ if (str==NULL) {
-+ fprintf(stderr, "pasame el str\n");
-+ return 255;
-+ }
-+ AES_xcbc_mac_set_key(&ctx, (__u8 *)&key, sizeof(key));
-+ AES_xcbc_mac_hash(&ctx, str, strlen(str), hash);
-+ print_hash(hash);
-+ str[2]='x';
-+ AES_xcbc_mac_hash(&ctx, str, strlen(str), hash);
-+ print_hash(hash);
-+ return 0;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/COPYRIGHT Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,50 @@
-+Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+All rights reserved.
-+
-+This package is an DES implementation written by Eric Young (eay@cryptsoft.com).
-+The implementation was written so as to conform with MIT's libdes.
-+
-+This library is free for commercial and non-commercial use as long as
-+the following conditions are aheared to. The following conditions
-+apply to all code found in this distribution.
-+
-+Copyright remains Eric Young's, and as such any Copyright notices in
-+the code are not to be removed.
-+If this package is used in a product, Eric Young should be given attribution
-+as the author of that the SSL library. This can be in the form of a textual
-+message at program startup or in documentation (online or textual) provided
-+with the package.
-+
-+Redistribution and use in source and binary forms, with or without
-+modification, are permitted provided that the following conditions
-+are met:
-+1. Redistributions of source code must retain the copyright
-+ notice, this list of conditions and the following disclaimer.
-+2. Redistributions in binary form must reproduce the above copyright
-+ notice, this list of conditions and the following disclaimer in the
-+ documentation and/or other materials provided with the distribution.
-+3. All advertising materials mentioning features or use of this software
-+ must display the following acknowledgement:
-+ This product includes software developed by Eric Young (eay@cryptsoft.com)
-+
-+THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+SUCH DAMAGE.
-+
-+The license and distribution terms for any publically available version or
-+derivative of this code cannot be changed. i.e. this code cannot simply be
-+copied and put under another distrubution license
-+[including the GNU Public License.]
-+
-+The reason behind this being stated in this direct manner is past
-+experience in code simply being copied and the attribution removed
-+from it and then being distributed as part of other packages. This
-+implementation was a non-trivial and unpaid effort.
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/INSTALL Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,69 @@
-+Check the CC and CFLAGS lines in the makefile
-+
-+If your C library does not support the times(3) function, change the
-+#define TIMES to
-+#undef TIMES in speed.c
-+If it does, check the HZ value for the times(3) function.
-+If your system does not define CLK_TCK it will be assumed to
-+be 100.0.
-+
-+If possible use gcc v 2.7.?
-+Turn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc)
-+In recent times, some system compilers give better performace.
-+
-+type 'make'
-+
-+run './destest' to check things are ok.
-+run './rpw' to check the tty code for reading passwords works.
-+run './speed' to see how fast those optimisations make the library run :-)
-+run './des_opts' to determin the best compile time options.
-+
-+The output from des_opts should be put in the makefile options and des_enc.c
-+should be rebuilt. For 64 bit computers, do not use the DES_PTR option.
-+For the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int'
-+and then you can use the 'DES_PTR' option.
-+
-+The file options.txt has the options listed for best speed on quite a
-+few systems. Look and the options (UNROLL, PTR, RISC2 etc) and then
-+turn on the relevent option in the Makefile
-+
-+There are some special Makefile targets that make life easier.
-+make cc - standard cc build
-+make gcc - standard gcc build
-+make x86-elf - x86 assembler (elf), linux-elf.
-+make x86-out - x86 assembler (a.out), FreeBSD
-+make x86-solaris- x86 assembler
-+make x86-bsdi - x86 assembler (a.out with primative assembler).
-+
-+If at all possible use the assembler (for Windows NT/95, use
-+asm/win32.obj to link with). The x86 assembler is very very fast.
-+
-+A make install will by default install
-+libdes.a in /usr/local/lib/libdes.a
-+des in /usr/local/bin/des
-+des_crypt.man in /usr/local/man/man3/des_crypt.3
-+des.man in /usr/local/man/man1/des.1
-+des.h in /usr/include/des.h
-+
-+des(1) should be compatible with sunOS's but I have been unable to
-+test it.
-+
-+These routines should compile on MSDOS, most 32bit and 64bit version
-+of Unix (BSD and SYSV) and VMS, without modification.
-+The only problems should be #include files that are in the wrong places.
-+
-+These routines can be compiled under MSDOS.
-+I have successfully encrypted files using des(1) under MSDOS and then
-+decrypted the files on a SparcStation.
-+I have been able to compile and test the routines with
-+Microsoft C v 5.1 and Turbo C v 2.0.
-+The code in this library is in no way optimised for the 16bit
-+operation of MSDOS.
-+
-+When building for glibc, ignore all of the above and just unpack into
-+glibc-1.??/des and then gmake as per normal.
-+
-+As a final note on performace. Certain CPUs like sparcs and Alpha often give
-+a %10 speed difference depending on the link order. It is rather anoying
-+when one program reports 'x' DES encrypts a second and another reports
-+'x*0.9' the speed.
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/Makefile.objs Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,20 @@
-+obj-$(CONFIG_IPSEC_ENC_3DES) += cbc_enc.o
-+#obj-$(CONFIG_IPSEC_ENC_3DES) += des_opts.o
-+obj-$(CONFIG_IPSEC_ENC_3DES) += ecb_enc.o
-+#obj-$(CONFIG_IPSEC_ENC_3DES) += fcrypt.o
-+obj-$(CONFIG_IPSEC_ENC_3DES) += set_key.o
-+
-+ifeq ($(strip ${SUBARCH}),)
-+SUBARCH:=${ARCH}
-+endif
-+
-+ifeq (${SUBARCH},i386)
-+obj-$(CONFIG_IPSEC_ENC_3DES) += dx86unix.o
-+else
-+obj-$(CONFIG_IPSEC_ENC_3DES) += des_enc.o
-+endif
-+
-+
-+
-+
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/README Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,54 @@
-+
-+ libdes, Version 4.01 10-Jan-97
-+
-+ Copyright (c) 1997, Eric Young
-+ All rights reserved.
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms specified in COPYRIGHT.
-+
-+--
-+The primary ftp site for this library is
-+ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz
-+libdes is now also shipped with SSLeay. Primary ftp site of
-+ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz
-+
-+The best way to build this library is to build it as part of SSLeay.
-+
-+This kit builds a DES encryption library and a DES encryption program.
-+It supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb,
-+triple cfb, desx, and MIT's pcbc encryption modes and also has a fast
-+implementation of crypt(3).
-+It contains support routines to read keys from a terminal,
-+generate a random key, generate a key from an arbitrary length string,
-+read/write encrypted data from/to a file descriptor.
-+
-+The implementation was written so as to conform with the manual entry
-+for the des_crypt(3) library routines from MIT's project Athena.
-+
-+destest should be run after compilation to test the des routines.
-+rpw should be run after compilation to test the read password routines.
-+The des program is a replacement for the sun des command. I believe it
-+conforms to the sun version.
-+
-+The Imakefile is setup for use in the kerberos distribution.
-+
-+These routines are best compiled with gcc or any other good
-+optimising compiler.
-+Just turn you optimiser up to the highest settings and run destest
-+after the build to make sure everything works.
-+
-+I believe these routines are close to the fastest and most portable DES
-+routines that use small lookup tables (4.5k) that are publicly available.
-+The fcrypt routine is faster than ufc's fcrypt (when compiling with
-+gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines
-+(on a sun3/260 168 vs 336). It is a function of CPU on chip cache size.
-+[ 10-Jan-97 and a function of an incorrect speed testing program in
-+ ufc which gave much better test figures that reality ].
-+
-+It is worth noting that on sparc and Alpha CPUs, performance of the DES
-+library can vary by upto %10 due to the positioning of files after application
-+linkage.
-+
-+Eric Young (eay@cryptsoft.com)
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/README.freeswan Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,33 @@
-+The only changes the FreeS/WAN project has made to libdes-lite 4.04b are:
-+
-+We #ifdef-ed the declaration of DES_LONG in des.h, so it's more efficient
-+on the Alpha, instead of just noting the issue in a comment.
-+
-+We #ifdef-ed out the des_options() function in ecb_enc.c, because we don't
-+use it, and its call to sprintf() can cause subtle difficulties when KLIPS
-+is built as a module (depending on details of Linux configuration options).
-+
-+We changed some instances of CC=$(CC) in the Makefile to CC='$(CC)' to make
-+it cope better with Linux kernel Makefile stupidities, and took out an
-+explicit CC=gcc (unwise on systems with strange compilers).
-+
-+We deleted some references to <stdio.h> and <stdlib.h>, and a declaration
-+of one function found only in the full libdes (not in libdes-lite), to
-+avoid dragging in bits of stdio/stdlib unnecessarily. (Our thanks to Hans
-+Schultz for spotting this and pointing out the fixes.)
-+
-+We deleted a couple of .obj files in the asm subdirectory, which appear to
-+have been included in the original library by accident.
-+
-+We have added an include of our Makefile.inc file, to permit overriding
-+things like choice of compiler (although the libdes Makefile would
-+probably need some work to make this effective).
-+
-+
-+
-+Note that Eric Young is no longer at the email address listed in these
-+files, and is (alas) no longer working on free crypto software.
-+
-+
-+
-+This file is RCSID $Id$
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/VERSION Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,406 @@
-+Version 4.04
-+ Fixed a few tests in destest. Also added x86 assember for
-+ des_ncbc_encrypt() which is the standard cbc mode function.
-+ This makes a very very large performace difference.
-+ Ariel Glenn ariel@columbia.edu reports that the terminal
-+ 'turn echo off' can return (errno == EINVAL) under solaris
-+ when redirection is used. So I now catch that as well as ENOTTY.
-+
-+
-+Version 4.03
-+ Left a static out of enc_write.c, which caused to buffer to be
-+ continiously malloc()ed. Does anyone use these functions? I keep
-+ on feeling like removing them since I only had these in there
-+ for a version of kerberised login. Anyway, this was pointed out
-+ by Theo de Raadt <deraadt@cvs.openbsd.org>
-+ The 'n' bit ofb code was wrong, it was not shifting the shift
-+ register. It worked correctly for n == 64. Thanks to
-+ Gigi Ankeny <Gigi.Ankeny@Eng.Sun.COM> for pointing this one out.
-+
-+Version 4.02
-+ I was doing 'if (memcmp(weak_keys[i],key,sizeof(key)) == 0)'
-+ when checking for weak keys which is wrong :-(, pointed out by
-+ Markus F.X.J. Oberhumer <markus.oberhumer@jk.uni-linz.ac.at>.
-+
-+Version 4.01
-+ Even faster inner loop in the DES assembler for x86 and a modification
-+ for IP/FP which is faster on x86. Both of these changes are
-+ from Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>. His
-+ changes make the assembler run %40 faster on a pentium. This is just
-+ a case of getting the instruction sequence 'just right'.
-+ All credit to 'Svend' :-)
-+ Quite a few special x86 'make' targets.
-+ A libdes-l (lite) distribution.
-+
-+Version 4.00
-+ After a bit of a pause, I'll up the major version number since this
-+ is mostly a performace release. I've added x86 assembler and
-+ added more options for performance. A %28 speedup for gcc
-+ on a pentium and the assembler is a %50 speedup.
-+ MIPS CPU's, sparc and Alpha are the main CPU's with speedups.
-+ Run des_opts to work out which options should be used.
-+ DES_RISC1/DES_RISC2 use alternative inner loops which use
-+ more registers but should give speedups on any CPU that does
-+ dual issue (pentium). DES_UNROLL unrolls the inner loop,
-+ which costs in code size.
-+
-+Version 3.26
-+ I've finally removed one of the shifts in D_ENCRYPT. This
-+ meant I've changed the des_SPtrans table (spr.h), the set_key()
-+ function and some things in des_enc.c. This has definitly
-+ made things faster :-). I've known about this one for some
-+ time but I've been too lazy to follow it up :-).
-+ Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^..
-+ instead of L^=((..)|(..)|(..).. This should save a register at
-+ least.
-+ Assember for x86. The file to replace is des_enc.c, which is replaced
-+ by one of the assembler files found in asm. Look at des/asm/readme
-+ for more info.
-+
-+ /* Modification to fcrypt so it can be compiled to support
-+ HPUX 10.x's long password format, define -DLONGCRYPT to use this.
-+ Thanks to Jens Kupferschmidt <bt1cu@hpboot.rz.uni-leipzig.de>. */
-+
-+ SIGWINCH case put in des_read_passwd() so the function does not
-+ 'exit' if this function is recieved.
-+
-+Version 3.25 17/07/96
-+ Modified read_pwd.c so that stdin can be read if not a tty.
-+ Thanks to Jeff Barber <jeffb@issl.atl.hp.com> for the patches.
-+ des_init_random_number_generator() shortened due to VMS linker
-+ limits.
-+ Added RSA's DESX cbc mode. It is a form of cbc encryption, with 2
-+ 8 byte quantites xored before and after encryption.
-+ des_xcbc_encryption() - the name is funny to preserve the des_
-+ prefix on all functions.
-+
-+Version 3.24 20/04/96
-+ The DES_PTR macro option checked and used by SSLeay configuration
-+
-+Version 3.23 11/04/96
-+ Added DES_LONG. If defined to 'unsigned int' on the DEC Alpha,
-+ it gives a %20 speedup :-)
-+ Fixed the problem with des.pl under perl5. The patches were
-+ sent by Ed Kubaitis (ejk@uiuc.edu).
-+ if fcrypt.c, changed values to handle illegal salt values the way
-+ normal crypt() implementations do. Some programs apparently use
-+ them :-(. The patch was sent by Bjorn Gronvall <bg@sics.se>
-+
-+Version 3.22 29/11/95
-+ Bug in des(1), an error with the uuencoding stuff when the
-+ 'data' is small, thanks to Geoff Keating <keagchon@mehta.anu.edu.au>
-+ for the patch.
-+
-+Version 3.21 22/11/95
-+ After some emailing back and forth with
-+ Colin Plumb <colin@nyx10.cs.du.edu>, I've tweaked a few things
-+ and in a future version I will probably put in some of the
-+ optimisation he suggested for use with the DES_USE_PTR option.
-+ Extra routines from Mark Murray <mark@grondar.za> for use in
-+ freeBSD. They mostly involve random number generation for use
-+ with kerberos. They involve evil machine specific system calls
-+ etc so I would normally suggest pushing this stuff into the
-+ application and/or using RAND_seed()/RAND_bytes() if you are
-+ using this DES library as part of SSLeay.
-+ Redone the read_pw() function so that it is cleaner and
-+ supports termios, thanks to Sameer Parekh <sameer@c2.org>
-+ for the initial patches for this.
-+ Renamed 3ecb_encrypt() to ecb3_encrypt(). This has been
-+ done just to make things more consistent.
-+ I have also now added triple DES versions of cfb and ofb.
-+
-+Version 3.20
-+ Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com,
-+ my des_random_seed() function was only copying 4 bytes of the
-+ passed seed into the init structure. It is now fixed to copy 8.
-+ My own suggestion is to used something like MD5 :-)
-+
-+Version 3.19
-+ While looking at my code one day, I though, why do I keep on
-+ calling des_encrypt(in,out,ks,enc) when every function that
-+ calls it has in and out the same. So I dropped the 'out'
-+ parameter, people should not be using this function.
-+
-+Version 3.18 30/08/95
-+ Fixed a few bit with the distribution and the filenames.
-+ 3.17 had been munged via a move to DOS and back again.
-+ NO CODE CHANGES
-+
-+Version 3.17 14/07/95
-+ Fixed ede3 cbc which I had broken in 3.16. I have also
-+ removed some unneeded variables in 7-8 of the routines.
-+
-+Version 3.16 26/06/95
-+ Added des_encrypt2() which does not use IP/FP, used by triple
-+ des routines. Tweaked things a bit elsewhere. %13 speedup on
-+ sparc and %6 on a R4400 for ede3 cbc mode.
-+
-+Version 3.15 06/06/95
-+ Added des_ncbc_encrypt(), it is des_cbc mode except that it is
-+ 'normal' and copies the new iv value back over the top of the
-+ passed parameter.
-+ CHANGED des_ede3_cbc_encrypt() so that it too now overwrites
-+ the iv. THIS WILL BREAK EXISTING CODE, but since this function
-+ only new, I feel I can change it, not so with des_cbc_encrypt :-(.
-+ I need to update the documentation.
-+
-+Version 3.14 31/05/95
-+ New release upon the world, as part of my SSL implementation.
-+ New copyright and usage stuff. Basically free for all to use
-+ as long as you say it came from me :-)
-+
-+Version 3.13 31/05/95
-+ A fix in speed.c, if HZ is not defined, I set it to 100.0
-+ which is reasonable for most unixes except SunOS 4.x.
-+ I now have a #ifdef sun but timing for SunOS 4.x looked very
-+ good :-(. At my last job where I used SunOS 4.x, it was
-+ defined to be 60.0 (look at the old INSTALL documentation), at
-+ the last release had it changed to 100.0 since I now work with
-+ Solaris2 and SVR4 boxes.
-+ Thanks to Rory Chisholm <rchishol@math.ethz.ch> for pointing this
-+ one out.
-+
-+Version 3.12 08/05/95
-+ As pointed out by The Crypt Keeper <tck@bend.UCSD.EDU>,
-+ my D_ENCRYPT macro in crypt() had an un-necessary variable.
-+ It has been removed.
-+
-+Version 3.11 03/05/95
-+ Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys
-+ and one iv. It is a standard and I needed it for my SSL code.
-+ It makes more sense to use this for triple DES than
-+ 3cbc_encrypt(). I have also added (or should I say tested :-)
-+ cfb64_encrypt() which is cfb64 but it will encrypt a partial
-+ number of bytes - 3 bytes in 3 bytes out. Again this is for
-+ my SSL library, as a form of encryption to use with SSL
-+ telnet.
-+
-+Version 3.10 22/03/95
-+ Fixed a bug in 3cbc_encrypt() :-(. When making repeated calls
-+ to cbc3_encrypt, the 2 iv values that were being returned to
-+ be used in the next call were reversed :-(.
-+ Many thanks to Bill Wade <wade@Stoner.COM> for pointing out
-+ this error.
-+
-+Version 3.09 01/02/95
-+ Fixed des_random_key to far more random, it was rather feeble
-+ with regards to picking the initial seed. The problem was
-+ pointed out by Olaf Kirch <okir@monad.swb.de>.
-+
-+Version 3.08 14/12/94
-+ Added Makefile.PL so libdes can be built into perl5.
-+ Changed des_locl.h so RAND is always defined.
-+
-+Version 3.07 05/12/94
-+ Added GNUmake and stuff so the library can be build with
-+ glibc.
-+
-+Version 3.06 30/08/94
-+ Added rpc_enc.c which contains _des_crypt. This is for use in
-+ secure_rpc v 4.0
-+ Finally fixed the cfb_enc problems.
-+ Fixed a few parameter parsing bugs in des (-3 and -b), thanks
-+ to Rob McMillan <R.McMillan@its.gu.edu.au>
-+
-+Version 3.05 21/04/94
-+ for unsigned long l; gcc does not produce ((l>>34) == 0)
-+ This causes bugs in cfb_enc.
-+ Thanks to Hadmut Danisch <danisch@ira.uka.de>
-+
-+Version 3.04 20/04/94
-+ Added a version number to des.c and libdes.a
-+
-+Version 3.03 12/01/94
-+ Fixed a bug in non zero iv in 3cbc_enc.
-+
-+Version 3.02 29/10/93
-+ I now work in a place where there are 6+ architectures and 14+
-+ OS versions :-).
-+ Fixed TERMIO definition so the most sys V boxes will work :-)
-+
-+Release upon comp.sources.misc
-+Version 3.01 08/10/93
-+ Added des_3cbc_encrypt()
-+
-+Version 3.00 07/10/93
-+ Fixed up documentation.
-+ quad_cksum definitely compatible with MIT's now.
-+
-+Version 2.30 24/08/93
-+ Triple DES now defaults to triple cbc but can do triple ecb
-+ with the -b flag.
-+ Fixed some MSDOS uuen/uudecoding problems, thanks to
-+ Added prototypes.
-+
-+Version 2.22 29/06/93
-+ Fixed a bug in des_is_weak_key() which stopped it working :-(
-+ thanks to engineering@MorningStar.Com.
-+
-+Version 2.21 03/06/93
-+ des(1) with no arguments gives quite a bit of help.
-+ Added -c (generate ckecksum) flag to des(1).
-+ Added -3 (triple DES) flag to des(1).
-+ Added cfb and ofb routines to the library.
-+
-+Version 2.20 11/03/93
-+ Added -u (uuencode) flag to des(1).
-+ I have been playing with byte order in quad_cksum to make it
-+ compatible with MIT's version. All I can say is avid this
-+ function if possible since MIT's output is endian dependent.
-+
-+Version 2.12 14/10/92
-+ Added MSDOS specific macro in ecb_encrypt which gives a %70
-+ speed up when the code is compiled with turbo C.
-+
-+Version 2.11 12/10/92
-+ Speedup in set_key (recoding of PC-1)
-+ I now do it in 47 simple operations, down from 60.
-+ Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
-+ for motivating me to look for a faster system :-)
-+ The speedup is probably less that 1% but it is still 13
-+ instructions less :-).
-+
-+Version 2.10 06/10/92
-+ The code now works on the 64bit ETA10 and CRAY without modifications or
-+ #defines. I believe the code should work on any machine that
-+ defines long, int or short to be 8 bytes long.
-+ Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu)
-+ for helping me fix the code to run on 64bit machines (he had
-+ access to an ETA10).
-+ Thanks also to John Fletcher <john_fletcher@lccmail.ocf.llnl.gov>
-+ for testing the routines on a CRAY.
-+ read_password.c has been renamed to read_passwd.c
-+ string_to_key.c has been renamed to string2key.c
-+
-+Version 2.00 14/09/92
-+ Made mods so that the library should work on 64bit CPU's.
-+ Removed all my uchar and ulong defs. To many different
-+ versions of unix define them in their header files in too many
-+ different combinations :-)
-+ IRIX - Sillicon Graphics mods (mostly in read_password.c).
-+ Thanks to Andrew Daviel (advax@erich.triumf.ca)
-+
-+Version 1.99 26/08/92
-+ Fixed a bug or 2 in enc_read.c
-+ Fixed a bug in enc_write.c
-+ Fixed a pseudo bug in fcrypt.c (very obscure).
-+
-+Version 1.98 31/07/92
-+ Support for the ETA10. This is a strange machine that defines
-+ longs and ints as 8 bytes and shorts as 4 bytes.
-+ Since I do evil things with long * that assume that they are 4
-+ bytes. Look in the Makefile for the option to compile for
-+ this machine. quad_cksum appears to have problems but I
-+ will don't have the time to fix it right now, and this is not
-+ a function that uses DES and so will not effect the main uses
-+ of the library.
-+
-+Version 1.97 20/05/92 eay
-+ Fixed the Imakefile and made some changes to des.h to fix some
-+ problems when building this package with Kerberos v 4.
-+
-+Version 1.96 18/05/92 eay
-+ Fixed a small bug in string_to_key() where problems could
-+ occur if des_check_key was set to true and the string
-+ generated a weak key.
-+
-+Patch2 posted to comp.sources.misc
-+Version 1.95 13/05/92 eay
-+ Added an alternative version of the D_ENCRYPT macro in
-+ ecb_encrypt and fcrypt. Depending on the compiler, one version or the
-+ other will be faster. This was inspired by
-+ Dana How <how@isl.stanford.edu>, and her pointers about doing the
-+ *(ulong *)((uchar *)ptr+(value&0xfc))
-+ vs
-+ ptr[value&0x3f]
-+ to stop the C compiler doing a <<2 to convert the long array index.
-+
-+Version 1.94 05/05/92 eay
-+ Fixed an incompatibility between my string_to_key and the MIT
-+ version. When the key is longer than 8 chars, I was wrapping
-+ with a different method. To use the old version, define
-+ OLD_STR_TO_KEY in the makefile. Thanks to
-+ viktor@newsu.shearson.com (Viktor Dukhovni).
-+
-+Version 1.93 28/04/92 eay
-+ Fixed the VMS mods so that echo is now turned off in
-+ read_password. Thanks again to brennan@coco.cchs.su.oz.AU.
-+ MSDOS support added. The routines can be compiled with
-+ Turbo C (v2.0) and MSC (v5.1). Make sure MSDOS is defined.
-+
-+Patch1 posted to comp.sources.misc
-+Version 1.92 13/04/92 eay
-+ Changed D_ENCRYPT so that the rotation of R occurs outside of
-+ the loop. This required rotating all the longs in sp.h (now
-+ called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
-+ speed.c has been changed so it will work without SIGALRM. If
-+ times(3) is not present it will try to use ftime() instead.
-+
-+Version 1.91 08/04/92 eay
-+ Added -E/-D options to des(1) so it can use string_to_key.
-+ Added SVR4 mods suggested by witr@rwwa.COM
-+ Added VMS mods suggested by brennan@coco.cchs.su.oz.AU. If
-+ anyone knows how to turn of tty echo in VMS please tell me or
-+ implement it yourself :-).
-+ Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS
-+ does not like IN/OUT being used.
-+
-+Libdes posted to comp.sources.misc
-+Version 1.9 24/03/92 eay
-+ Now contains a fast small crypt replacement.
-+ Added des(1) command.
-+ Added des_rw_mode so people can use cbc encryption with
-+ enc_read and enc_write.
-+
-+Version 1.8 15/10/91 eay
-+ Bug in cbc_cksum.
-+ Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this
-+ one out.
-+
-+Version 1.7 24/09/91 eay
-+ Fixed set_key :-)
-+ set_key is 4 times faster and takes less space.
-+ There are a few minor changes that could be made.
-+
-+Version 1.6 19/09/1991 eay
-+ Finally go IP and FP finished.
-+ Now I need to fix set_key.
-+ This version is quite a bit faster that 1.51
-+
-+Version 1.52 15/06/1991 eay
-+ 20% speedup in ecb_encrypt by changing the E bit selection
-+ to use 2 32bit words. This also required modification of the
-+ sp table. There is still a way to speedup the IP and IP-1
-+ (hints from outer@sq.com) still working on this one :-(.
-+
-+Version 1.51 07/06/1991 eay
-+ Faster des_encrypt by loop unrolling
-+ Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu)
-+
-+Version 1.50 28/05/1991 eay
-+ Optimised the code a bit more for the sparc. I have improved the
-+ speed of the inner des_encrypt by speeding up the initial and
-+ final permutations.
-+
-+Version 1.40 23/10/1990 eay
-+ Fixed des_random_key, it did not produce a random key :-(
-+
-+Version 1.30 2/10/1990 eay
-+ Have made des_quad_cksum the same as MIT's, the full package
-+ should be compatible with MIT's
-+ Have tested on a DECstation 3100
-+ Still need to fix des_set_key (make it faster).
-+ Does des_cbc_encrypts at 70.5k/sec on a 3100.
-+
-+Version 1.20 18/09/1990 eay
-+ Fixed byte order dependencies.
-+ Fixed (I hope) all the word alignment problems.
-+ Speedup in des_ecb_encrypt.
-+
-+Version 1.10 11/09/1990 eay
-+ Added des_enc_read and des_enc_write.
-+ Still need to fix des_quad_cksum.
-+ Still need to document des_enc_read and des_enc_write.
-+
-+Version 1.00 27/08/1990 eay
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/crypt586.pl Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,204 @@
-+#!/usr/bin/perl
-+#
-+# The inner loop instruction sequence and the IP/FP modifications are from
-+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
-+# I've added the stuff needed for crypt() but I've not worried about making
-+# things perfect.
-+#
-+
-+push(@INC,"perlasm","../../perlasm");
-+require "x86asm.pl";
-+
-+&asm_init($ARGV[0],"crypt586.pl");
-+
-+$L="edi";
-+$R="esi";
-+
-+&external_label("des_SPtrans");
-+&fcrypt_body("fcrypt_body");
-+&asm_finish();
-+
-+sub fcrypt_body
-+ {
-+ local($name,$do_ip)=@_;
-+
-+ &function_begin($name,"EXTRN _des_SPtrans:DWORD");
-+
-+ &comment("");
-+ &comment("Load the 2 words");
-+ $ks="ebp";
-+
-+ &xor( $L, $L);
-+ &xor( $R, $R);
-+ &mov($ks,&wparam(1));
-+
-+ &push(25); # add a variable
-+
-+ &set_label("start");
-+ for ($i=0; $i<16; $i+=2)
-+ {
-+ &comment("");
-+ &comment("Round $i");
-+ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
-+
-+ &comment("");
-+ &comment("Round ".sprintf("%d",$i+1));
-+ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
-+ }
-+ &mov("ebx", &swtmp(0));
-+ &mov("eax", $L);
-+ &dec("ebx");
-+ &mov($L, $R);
-+ &mov($R, "eax");
-+ &mov(&swtmp(0), "ebx");
-+ &jnz(&label("start"));
-+
-+ &comment("");
-+ &comment("FP");
-+ &mov("edx",&wparam(0));
-+
-+ &FP_new($R,$L,"eax",3);
-+ &mov(&DWP(0,"edx","",0),"eax");
-+ &mov(&DWP(4,"edx","",0),$L);
-+
-+ &pop("ecx"); # remove variable
-+
-+ &function_end($name);
-+ }
-+
-+sub D_ENCRYPT
-+ {
-+ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
-+
-+ &mov( $u, &wparam(2)); # 2
-+ &mov( $t, $R);
-+ &shr( $t, 16); # 1
-+ &mov( $tmp2, &wparam(3)); # 2
-+ &xor( $t, $R); # 1
-+
-+ &and( $u, $t); # 2
-+ &and( $t, $tmp2); # 2
-+
-+ &mov( $tmp1, $u);
-+ &shl( $tmp1, 16); # 1
-+ &mov( $tmp2, $t);
-+ &shl( $tmp2, 16); # 1
-+ &xor( $u, $tmp1); # 2
-+ &xor( $t, $tmp2); # 2
-+ &mov( $tmp1, &DWP(&n2a($S*4),$ks,"",0)); # 2
-+ &xor( $u, $tmp1);
-+ &mov( $tmp2, &DWP(&n2a(($S+1)*4),$ks,"",0)); # 2
-+ &xor( $u, $R);
-+ &xor( $t, $R);
-+ &xor( $t, $tmp2);
-+
-+ &and( $u, "0xfcfcfcfc" ); # 2
-+ &xor( $tmp1, $tmp1); # 1
-+ &and( $t, "0xcfcfcfcf" ); # 2
-+ &xor( $tmp2, $tmp2);
-+ &movb( &LB($tmp1), &LB($u) );
-+ &movb( &LB($tmp2), &HB($u) );
-+ &rotr( $t, 4 );
-+ &mov( $ks, &DWP(" $desSP",$tmp1,"",0));
-+ &movb( &LB($tmp1), &LB($t) );
-+ &xor( $L, $ks);
-+ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
-+ &xor( $L, $ks);
-+ &movb( &LB($tmp2), &HB($t) );
-+ &shr( $u, 16);
-+ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
-+ &xor( $L, $ks);
-+ &movb( &LB($tmp1), &HB($u) );
-+ &shr( $t, 16);
-+ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
-+ &xor( $L, $ks);
-+ &mov( $ks, &wparam(1));
-+ &movb( &LB($tmp2), &HB($t) );
-+ &and( $u, "0xff" );
-+ &and( $t, "0xff" );
-+ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
-+ &xor( $L, $tmp1);
-+ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
-+ &xor( $L, $tmp1);
-+ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
-+ &xor( $L, $tmp1);
-+ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
-+ &xor( $L, $tmp1);
-+ }
-+
-+sub n2a
-+ {
-+ sprintf("%d",$_[0]);
-+ }
-+
-+# now has a side affect of rotating $a by $shift
-+sub R_PERM_OP
-+ {
-+ local($a,$b,$tt,$shift,$mask,$last)=@_;
-+
-+ &rotl( $a, $shift ) if ($shift != 0);
-+ &mov( $tt, $a );
-+ &xor( $a, $b );
-+ &and( $a, $mask );
-+ if ($notlast eq $b)
-+ {
-+ &xor( $b, $a );
-+ &xor( $tt, $a );
-+ }
-+ else
-+ {
-+ &xor( $tt, $a );
-+ &xor( $b, $a );
-+ }
-+ &comment("");
-+ }
-+
-+sub IP_new
-+ {
-+ local($l,$r,$tt,$lr)=@_;
-+
-+ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
-+ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
-+ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
-+ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
-+ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
-+
-+ if ($lr != 3)
-+ {
-+ if (($lr-3) < 0)
-+ { &rotr($tt, 3-$lr); }
-+ else { &rotl($tt, $lr-3); }
-+ }
-+ if ($lr != 2)
-+ {
-+ if (($lr-2) < 0)
-+ { &rotr($r, 2-$lr); }
-+ else { &rotl($r, $lr-2); }
-+ }
-+ }
-+
-+sub FP_new
-+ {
-+ local($l,$r,$tt,$lr)=@_;
-+
-+ if ($lr != 2)
-+ {
-+ if (($lr-2) < 0)
-+ { &rotl($r, 2-$lr); }
-+ else { &rotr($r, $lr-2); }
-+ }
-+ if ($lr != 3)
-+ {
-+ if (($lr-3) < 0)
-+ { &rotl($l, 3-$lr); }
-+ else { &rotr($l, $lr-3); }
-+ }
-+
-+ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
-+ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
-+ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
-+ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
-+ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
-+ &rotr($tt , 4);
-+ }
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/des-586.pl Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,251 @@
-+#!/usr/bin/perl
-+#
-+# The inner loop instruction sequence and the IP/FP modifications are from
-+# Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk>
-+#
-+
-+push(@INC,"perlasm","../../perlasm");
-+require "x86asm.pl";
-+require "cbc.pl";
-+require "desboth.pl";
-+
-+# base code is in microsft
-+# op dest, source
-+# format.
-+#
-+
-+&asm_init($ARGV[0],"des-586.pl");
-+
-+$L="edi";
-+$R="esi";
-+
-+&external_label("des_SPtrans");
-+&des_encrypt("des_encrypt",1);
-+&des_encrypt("des_encrypt2",0);
-+&des_encrypt3("des_encrypt3",1);
-+&des_encrypt3("des_decrypt3",0);
-+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
-+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
-+
-+&asm_finish();
-+
-+sub des_encrypt
-+ {
-+ local($name,$do_ip)=@_;
-+
-+ &function_begin_B($name,"EXTRN _des_SPtrans:DWORD");
-+
-+ &push("esi");
-+ &push("edi");
-+
-+ &comment("");
-+ &comment("Load the 2 words");
-+ $ks="ebp";
-+
-+ if ($do_ip)
-+ {
-+ &mov($R,&wparam(0));
-+ &xor( "ecx", "ecx" );
-+
-+ &push("ebx");
-+ &push("ebp");
-+
-+ &mov("eax",&DWP(0,$R,"",0));
-+ &mov("ebx",&wparam(2)); # get encrypt flag
-+ &mov($L,&DWP(4,$R,"",0));
-+ &comment("");
-+ &comment("IP");
-+ &IP_new("eax",$L,$R,3);
-+ }
-+ else
-+ {
-+ &mov("eax",&wparam(0));
-+ &xor( "ecx", "ecx" );
-+
-+ &push("ebx");
-+ &push("ebp");
-+
-+ &mov($R,&DWP(0,"eax","",0));
-+ &mov("ebx",&wparam(2)); # get encrypt flag
-+ &rotl($R,3);
-+ &mov($L,&DWP(4,"eax","",0));
-+ &rotl($L,3);
-+ }
-+
-+ &mov( $ks, &wparam(1) );
-+ &cmp("ebx","0");
-+ &je(&label("start_decrypt"));
-+
-+ for ($i=0; $i<16; $i+=2)
-+ {
-+ &comment("");
-+ &comment("Round $i");
-+ &D_ENCRYPT($i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
-+
-+ &comment("");
-+ &comment("Round ".sprintf("%d",$i+1));
-+ &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
-+ }
-+ &jmp(&label("end"));
-+
-+ &set_label("start_decrypt");
-+
-+ for ($i=15; $i>0; $i-=2)
-+ {
-+ &comment("");
-+ &comment("Round $i");
-+ &D_ENCRYPT(15-$i,$L,$R,$i*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
-+ &comment("");
-+ &comment("Round ".sprintf("%d",$i-1));
-+ &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$ks,"des_SPtrans","eax","ebx","ecx","edx");
-+ }
-+
-+ &set_label("end");
-+
-+ if ($do_ip)
-+ {
-+ &comment("");
-+ &comment("FP");
-+ &mov("edx",&wparam(0));
-+ &FP_new($L,$R,"eax",3);
-+
-+ &mov(&DWP(0,"edx","",0),"eax");
-+ &mov(&DWP(4,"edx","",0),$R);
-+ }
-+ else
-+ {
-+ &comment("");
-+ &comment("Fixup");
-+ &rotr($L,3); # r
-+ &mov("eax",&wparam(0));
-+ &rotr($R,3); # l
-+ &mov(&DWP(0,"eax","",0),$L);
-+ &mov(&DWP(4,"eax","",0),$R);
-+ }
-+
-+ &pop("ebp");
-+ &pop("ebx");
-+ &pop("edi");
-+ &pop("esi");
-+ &ret();
-+
-+ &function_end_B($name);
-+ }
-+
-+sub D_ENCRYPT
-+ {
-+ local($r,$L,$R,$S,$ks,$desSP,$u,$tmp1,$tmp2,$t)=@_;
-+
-+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
-+ &xor( $tmp1, $tmp1);
-+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
-+ &xor( $u, $R);
-+ &xor( $t, $R);
-+ &and( $u, "0xfcfcfcfc" );
-+ &and( $t, "0xcfcfcfcf" );
-+ &movb( &LB($tmp1), &LB($u) );
-+ &movb( &LB($tmp2), &HB($u) );
-+ &rotr( $t, 4 );
-+ &mov( $ks, &DWP(" $desSP",$tmp1,"",0));
-+ &movb( &LB($tmp1), &LB($t) );
-+ &xor( $L, $ks);
-+ &mov( $ks, &DWP("0x200+$desSP",$tmp2,"",0));
-+ &xor( $L, $ks); ######
-+ &movb( &LB($tmp2), &HB($t) );
-+ &shr( $u, 16);
-+ &mov( $ks, &DWP("0x100+$desSP",$tmp1,"",0));
-+ &xor( $L, $ks); ######
-+ &movb( &LB($tmp1), &HB($u) );
-+ &shr( $t, 16);
-+ &mov( $ks, &DWP("0x300+$desSP",$tmp2,"",0));
-+ &xor( $L, $ks);
-+ &mov( $ks, &wparam(1) );
-+ &movb( &LB($tmp2), &HB($t) );
-+ &and( $u, "0xff" );
-+ &and( $t, "0xff" );
-+ &mov( $tmp1, &DWP("0x600+$desSP",$tmp1,"",0));
-+ &xor( $L, $tmp1);
-+ &mov( $tmp1, &DWP("0x700+$desSP",$tmp2,"",0));
-+ &xor( $L, $tmp1);
-+ &mov( $tmp1, &DWP("0x400+$desSP",$u,"",0));
-+ &xor( $L, $tmp1);
-+ &mov( $tmp1, &DWP("0x500+$desSP",$t,"",0));
-+ &xor( $L, $tmp1);
-+ }
-+
-+sub n2a
-+ {
-+ sprintf("%d",$_[0]);
-+ }
-+
-+# now has a side affect of rotating $a by $shift
-+sub R_PERM_OP
-+ {
-+ local($a,$b,$tt,$shift,$mask,$last)=@_;
-+
-+ &rotl( $a, $shift ) if ($shift != 0);
-+ &mov( $tt, $a );
-+ &xor( $a, $b );
-+ &and( $a, $mask );
-+ if (!$last eq $b)
-+ {
-+ &xor( $b, $a );
-+ &xor( $tt, $a );
-+ }
-+ else
-+ {
-+ &xor( $tt, $a );
-+ &xor( $b, $a );
-+ }
-+ &comment("");
-+ }
-+
-+sub IP_new
-+ {
-+ local($l,$r,$tt,$lr)=@_;
-+
-+ &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l);
-+ &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l);
-+ &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r);
-+ &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r);
-+ &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r);
-+
-+ if ($lr != 3)
-+ {
-+ if (($lr-3) < 0)
-+ { &rotr($tt, 3-$lr); }
-+ else { &rotl($tt, $lr-3); }
-+ }
-+ if ($lr != 2)
-+ {
-+ if (($lr-2) < 0)
-+ { &rotr($r, 2-$lr); }
-+ else { &rotl($r, $lr-2); }
-+ }
-+ }
-+
-+sub FP_new
-+ {
-+ local($l,$r,$tt,$lr)=@_;
-+
-+ if ($lr != 2)
-+ {
-+ if (($lr-2) < 0)
-+ { &rotl($r, 2-$lr); }
-+ else { &rotr($r, $lr-2); }
-+ }
-+ if ($lr != 3)
-+ {
-+ if (($lr-3) < 0)
-+ { &rotl($l, 3-$lr); }
-+ else { &rotr($l, $lr-3); }
-+ }
-+
-+ &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r);
-+ &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r);
-+ &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l);
-+ &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l);
-+ &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r);
-+ &rotr($tt , 4);
-+ }
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/des686.pl Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,230 @@
-+#!/usr/bin/perl
-+
-+$prog="des686.pl";
-+
-+# base code is in microsft
-+# op dest, source
-+# format.
-+#
-+
-+# WILL NOT WORK ANYMORE WITH desboth.pl
-+require "desboth.pl";
-+
-+if ( ($ARGV[0] eq "elf"))
-+ { require "x86unix.pl"; }
-+elsif ( ($ARGV[0] eq "a.out"))
-+ { $aout=1; require "x86unix.pl"; }
-+elsif ( ($ARGV[0] eq "sol"))
-+ { $sol=1; require "x86unix.pl"; }
-+elsif ( ($ARGV[0] eq "cpp"))
-+ { $cpp=1; require "x86unix.pl"; }
-+elsif ( ($ARGV[0] eq "win32"))
-+ { require "x86ms.pl"; }
-+else
-+ {
-+ print STDERR <<"EOF";
-+Pick one target type from
-+ elf - linux, FreeBSD etc
-+ a.out - old linux
-+ sol - x86 solaris
-+ cpp - format so x86unix.cpp can be used
-+ win32 - Windows 95/Windows NT
-+EOF
-+ exit(1);
-+ }
-+
-+&comment("Don't even think of reading this code");
-+&comment("It was automatically generated by $prog");
-+&comment("Which is a perl program used to generate the x86 assember for");
-+&comment("any of elf, a.out, Win32, or Solaris");
-+&comment("It can be found in SSLeay 0.6.5+ or in libdes 3.26+");
-+&comment("eric <eay\@cryptsoft.com>");
-+&comment("");
-+
-+&file("dx86xxxx");
-+
-+$L="edi";
-+$R="esi";
-+
-+&des_encrypt("des_encrypt",1);
-+&des_encrypt("des_encrypt2",0);
-+
-+&des_encrypt3("des_encrypt3",1);
-+&des_encrypt3("des_decrypt3",0);
-+
-+&file_end();
-+
-+sub des_encrypt
-+ {
-+ local($name,$do_ip)=@_;
-+
-+ &function_begin($name,"EXTRN _des_SPtrans:DWORD");
-+
-+ &comment("");
-+ &comment("Load the 2 words");
-+ &mov("eax",&wparam(0));
-+ &mov($L,&DWP(0,"eax","",0));
-+ &mov($R,&DWP(4,"eax","",0));
-+
-+ $ksp=&wparam(1);
-+
-+ if ($do_ip)
-+ {
-+ &comment("");
-+ &comment("IP");
-+ &IP_new($L,$R,"eax");
-+ }
-+
-+ &comment("");
-+ &comment("fixup rotate");
-+ &rotl($R,3);
-+ &rotl($L,3);
-+ &exch($L,$R);
-+
-+ &comment("");
-+ &comment("load counter, key_schedule and enc flag");
-+ &mov("eax",&wparam(2)); # get encrypt flag
-+ &mov("ebp",&wparam(1)); # get ks
-+ &cmp("eax","0");
-+ &je(&label("start_decrypt"));
-+
-+ # encrypting part
-+
-+ for ($i=0; $i<16; $i+=2)
-+ {
-+ &comment("");
-+ &comment("Round $i");
-+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
-+
-+ &comment("");
-+ &comment("Round ".sprintf("%d",$i+1));
-+ &D_ENCRYPT($R,$L,($i+1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
-+ }
-+ &jmp(&label("end"));
-+
-+ &set_label("start_decrypt");
-+
-+ for ($i=15; $i>0; $i-=2)
-+ {
-+ &comment("");
-+ &comment("Round $i");
-+ &D_ENCRYPT($L,$R,$i*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
-+ &comment("");
-+ &comment("Round ".sprintf("%d",$i-1));
-+ &D_ENCRYPT($R,$L,($i-1)*2,"ebp","des_SPtrans","ecx","edx","eax","ebx");
-+ }
-+
-+ &set_label("end");
-+
-+ &comment("");
-+ &comment("Fixup");
-+ &rotr($L,3); # r
-+ &rotr($R,3); # l
-+
-+ if ($do_ip)
-+ {
-+ &comment("");
-+ &comment("FP");
-+ &FP_new($R,$L,"eax");
-+ }
-+
-+ &mov("eax",&wparam(0));
-+ &mov(&DWP(0,"eax","",0),$L);
-+ &mov(&DWP(4,"eax","",0),$R);
-+
-+ &function_end($name);
-+ }
-+
-+
-+# The logic is to load R into 2 registers and operate on both at the same time.
-+# We also load the 2 R's into 2 more registers so we can do the 'move word down a byte'
-+# while also masking the other copy and doing a lookup. We then also accumulate the
-+# L value in 2 registers then combine them at the end.
-+sub D_ENCRYPT
-+ {
-+ local($L,$R,$S,$ks,$desSP,$u,$t,$tmp1,$tmp2,$tmp3)=@_;
-+
-+ &mov( $u, &DWP(&n2a($S*4),$ks,"",0));
-+ &mov( $t, &DWP(&n2a(($S+1)*4),$ks,"",0));
-+ &xor( $u, $R );
-+ &xor( $t, $R );
-+ &rotr( $t, 4 );
-+
-+ # the numbers at the end of the line are origional instruction order
-+ &mov( $tmp2, $u ); # 1 2
-+ &mov( $tmp1, $t ); # 1 1
-+ &and( $tmp2, "0xfc" ); # 1 4
-+ &and( $tmp1, "0xfc" ); # 1 3
-+ &shr( $t, 8 ); # 1 5
-+ &xor( $L, &DWP("0x100+$desSP",$tmp1,"",0)); # 1 7
-+ &shr( $u, 8 ); # 1 6
-+ &mov( $tmp1, &DWP(" $desSP",$tmp2,"",0)); # 1 8
-+
-+ &mov( $tmp2, $u ); # 2 2
-+ &xor( $L, $tmp1 ); # 1 9
-+ &and( $tmp2, "0xfc" ); # 2 4
-+ &mov( $tmp1, $t ); # 2 1
-+ &and( $tmp1, "0xfc" ); # 2 3
-+ &shr( $t, 8 ); # 2 5
-+ &xor( $L, &DWP("0x300+$desSP",$tmp1,"",0)); # 2 7
-+ &shr( $u, 8 ); # 2 6
-+ &mov( $tmp1, &DWP("0x200+$desSP",$tmp2,"",0)); # 2 8
-+ &mov( $tmp2, $u ); # 3 2
-+
-+ &xor( $L, $tmp1 ); # 2 9
-+ &and( $tmp2, "0xfc" ); # 3 4
-+
-+ &mov( $tmp1, $t ); # 3 1
-+ &shr( $u, 8 ); # 3 6
-+ &and( $tmp1, "0xfc" ); # 3 3
-+ &shr( $t, 8 ); # 3 5
-+ &xor( $L, &DWP("0x500+$desSP",$tmp1,"",0)); # 3 7
-+ &mov( $tmp1, &DWP("0x400+$desSP",$tmp2,"",0)); # 3 8
-+
-+ &and( $t, "0xfc" ); # 4 1
-+ &xor( $L, $tmp1 ); # 3 9
-+
-+ &and( $u, "0xfc" ); # 4 2
-+ &xor( $L, &DWP("0x700+$desSP",$t,"",0)); # 4 3
-+ &xor( $L, &DWP("0x600+$desSP",$u,"",0)); # 4 4
-+ }
-+
-+sub PERM_OP
-+ {
-+ local($a,$b,$tt,$shift,$mask)=@_;
-+
-+ &mov( $tt, $a );
-+ &shr( $tt, $shift );
-+ &xor( $tt, $b );
-+ &and( $tt, $mask );
-+ &xor( $b, $tt );
-+ &shl( $tt, $shift );
-+ &xor( $a, $tt );
-+ }
-+
-+sub IP_new
-+ {
-+ local($l,$r,$tt)=@_;
-+
-+ &PERM_OP($r,$l,$tt, 4,"0x0f0f0f0f");
-+ &PERM_OP($l,$r,$tt,16,"0x0000ffff");
-+ &PERM_OP($r,$l,$tt, 2,"0x33333333");
-+ &PERM_OP($l,$r,$tt, 8,"0x00ff00ff");
-+ &PERM_OP($r,$l,$tt, 1,"0x55555555");
-+ }
-+
-+sub FP_new
-+ {
-+ local($l,$r,$tt)=@_;
-+
-+ &PERM_OP($l,$r,$tt, 1,"0x55555555");
-+ &PERM_OP($r,$l,$tt, 8,"0x00ff00ff");
-+ &PERM_OP($l,$r,$tt, 2,"0x33333333");
-+ &PERM_OP($r,$l,$tt,16,"0x0000ffff");
-+ &PERM_OP($l,$r,$tt, 4,"0x0f0f0f0f");
-+ }
-+
-+sub n2a
-+ {
-+ sprintf("%d",$_[0]);
-+ }
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/desboth.pl Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,79 @@
-+#!/usr/bin/perl
-+
-+$L="edi";
-+$R="esi";
-+
-+sub des_encrypt3
-+ {
-+ local($name,$enc)=@_;
-+
-+ &function_begin_B($name,"");
-+ &push("ebx");
-+ &mov("ebx",&wparam(0));
-+
-+ &push("ebp");
-+ &push("esi");
-+
-+ &push("edi");
-+
-+ &comment("");
-+ &comment("Load the data words");
-+ &mov($L,&DWP(0,"ebx","",0));
-+ &mov($R,&DWP(4,"ebx","",0));
-+ &stack_push(3);
-+
-+ &comment("");
-+ &comment("IP");
-+ &IP_new($L,$R,"edx",0);
-+
-+ # put them back
-+
-+ if ($enc)
-+ {
-+ &mov(&DWP(4,"ebx","",0),$R);
-+ &mov("eax",&wparam(1));
-+ &mov(&DWP(0,"ebx","",0),"edx");
-+ &mov("edi",&wparam(2));
-+ &mov("esi",&wparam(3));
-+ }
-+ else
-+ {
-+ &mov(&DWP(4,"ebx","",0),$R);
-+ &mov("esi",&wparam(1));
-+ &mov(&DWP(0,"ebx","",0),"edx");
-+ &mov("edi",&wparam(2));
-+ &mov("eax",&wparam(3));
-+ }
-+ &mov(&swtmp(2), (($enc)?"1":"0"));
-+ &mov(&swtmp(1), "eax");
-+ &mov(&swtmp(0), "ebx");
-+ &call("des_encrypt2");
-+ &mov(&swtmp(2), (($enc)?"0":"1"));
-+ &mov(&swtmp(1), "edi");
-+ &mov(&swtmp(0), "ebx");
-+ &call("des_encrypt2");
-+ &mov(&swtmp(2), (($enc)?"1":"0"));
-+ &mov(&swtmp(1), "esi");
-+ &mov(&swtmp(0), "ebx");
-+ &call("des_encrypt2");
-+
-+ &stack_pop(3);
-+ &mov($L,&DWP(0,"ebx","",0));
-+ &mov($R,&DWP(4,"ebx","",0));
-+
-+ &comment("");
-+ &comment("FP");
-+ &FP_new($L,$R,"eax",0);
-+
-+ &mov(&DWP(0,"ebx","",0),"eax");
-+ &mov(&DWP(4,"ebx","",0),$R);
-+
-+ &pop("edi");
-+ &pop("esi");
-+ &pop("ebp");
-+ &pop("ebx");
-+ &ret();
-+ &function_end_B($name);
-+ }
-+
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/perlasm/cbc.pl Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,342 @@
-+#!/usr/bin/perl
-+
-+# void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
-+# des_cblock (*input);
-+# des_cblock (*output);
-+# long length;
-+# des_key_schedule schedule;
-+# des_cblock (*ivec);
-+# int enc;
-+#
-+# calls
-+# des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
-+#
-+
-+#&cbc("des_ncbc_encrypt","des_encrypt",0);
-+#&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",
-+# 1,4,5,3,5,-1);
-+#&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",
-+# 0,4,5,3,5,-1);
-+#&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",
-+# 0,6,7,3,4,5);
-+#
-+# When doing a cipher that needs bigendian order,
-+# for encrypt, the iv is kept in bigendian form,
-+# while for decrypt, it is kept in little endian.
-+sub cbc
-+ {
-+ local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_;
-+ # name is the function name
-+ # enc_func and dec_func and the functions to call for encrypt/decrypt
-+ # swap is true if byte order needs to be reversed
-+ # iv_off is parameter number for the iv
-+ # enc_off is parameter number for the encrypt/decrypt flag
-+ # p1,p2,p3 are the offsets for parameters to be passed to the
-+ # underlying calls.
-+
-+ &function_begin_B($name,"");
-+ &comment("");
-+
-+ $in="esi";
-+ $out="edi";
-+ $count="ebp";
-+
-+ &push("ebp");
-+ &push("ebx");
-+ &push("esi");
-+ &push("edi");
-+
-+ $data_off=4;
-+ $data_off+=4 if ($p1 > 0);
-+ $data_off+=4 if ($p2 > 0);
-+ $data_off+=4 if ($p3 > 0);
-+
-+ &mov($count, &wparam(2)); # length
-+
-+ &comment("getting iv ptr from parameter $iv_off");
-+ &mov("ebx", &wparam($iv_off)); # Get iv ptr
-+
-+ &mov($in, &DWP(0,"ebx","",0));# iv[0]
-+ &mov($out, &DWP(4,"ebx","",0));# iv[1]
-+
-+ &push($out);
-+ &push($in);
-+ &push($out); # used in decrypt for iv[1]
-+ &push($in); # used in decrypt for iv[0]
-+
-+ &mov("ebx", "esp"); # This is the address of tin[2]
-+
-+ &mov($in, &wparam(0)); # in
-+ &mov($out, &wparam(1)); # out
-+
-+ # We have loaded them all, how lets push things
-+ &comment("getting encrypt flag from parameter $enc_off");
-+ &mov("ecx", &wparam($enc_off)); # Get enc flag
-+ if ($p3 > 0)
-+ {
-+ &comment("get and push parameter $p3");
-+ if ($enc_off != $p3)
-+ { &mov("eax", &wparam($p3)); &push("eax"); }
-+ else { &push("ecx"); }
-+ }
-+ if ($p2 > 0)
-+ {
-+ &comment("get and push parameter $p2");
-+ if ($enc_off != $p2)
-+ { &mov("eax", &wparam($p2)); &push("eax"); }
-+ else { &push("ecx"); }
-+ }
-+ if ($p1 > 0)
-+ {
-+ &comment("get and push parameter $p1");
-+ if ($enc_off != $p1)
-+ { &mov("eax", &wparam($p1)); &push("eax"); }
-+ else { &push("ecx"); }
-+ }
-+ &push("ebx"); # push data/iv
-+
-+ &cmp("ecx",0);
-+ &jz(&label("decrypt"));
-+
-+ &and($count,0xfffffff8);
-+ &mov("eax", &DWP($data_off,"esp","",0)); # load iv[0]
-+ &mov("ebx", &DWP($data_off+4,"esp","",0)); # load iv[1]
-+
-+ &jz(&label("encrypt_finish"));
-+
-+ #############################################################
-+
-+ &set_label("encrypt_loop");
-+ # encrypt start
-+ # "eax" and "ebx" hold iv (or the last cipher text)
-+
-+ &mov("ecx", &DWP(0,$in,"",0)); # load first 4 bytes
-+ &mov("edx", &DWP(4,$in,"",0)); # second 4 bytes
-+
-+ &xor("eax", "ecx");
-+ &xor("ebx", "edx");
-+
-+ &bswap("eax") if $swap;
-+ &bswap("ebx") if $swap;
-+
-+ &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call
-+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
-+
-+ &call($enc_func);
-+
-+ &mov("eax", &DWP($data_off,"esp","",0));
-+ &mov("ebx", &DWP($data_off+4,"esp","",0));
-+
-+ &bswap("eax") if $swap;
-+ &bswap("ebx") if $swap;
-+
-+ &mov(&DWP(0,$out,"",0),"eax");
-+ &mov(&DWP(4,$out,"",0),"ebx");
-+
-+ # eax and ebx are the next iv.
-+
-+ &add($in, 8);
-+ &add($out, 8);
-+
-+ &sub($count, 8);
-+ &jnz(&label("encrypt_loop"));
-+
-+###################################################################3
-+ &set_label("encrypt_finish");
-+ &mov($count, &wparam(2)); # length
-+ &and($count, 7);
-+ &jz(&label("finish"));
-+ &xor("ecx","ecx");
-+ &xor("edx","edx");
-+ &mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4));
-+ &jmp_ptr($count);
-+
-+&set_label("ej7");
-+ &xor("edx", "edx") if $ppro; # ppro friendly
-+ &movb(&HB("edx"), &BP(6,$in,"",0));
-+ &shl("edx",8);
-+&set_label("ej6");
-+ &movb(&HB("edx"), &BP(5,$in,"",0));
-+&set_label("ej5");
-+ &movb(&LB("edx"), &BP(4,$in,"",0));
-+&set_label("ej4");
-+ &mov("ecx", &DWP(0,$in,"",0));
-+ &jmp(&label("ejend"));
-+&set_label("ej3");
-+ &movb(&HB("ecx"), &BP(2,$in,"",0));
-+ &xor("ecx", "ecx") if $ppro; # ppro friendly
-+ &shl("ecx",8);
-+&set_label("ej2");
-+ &movb(&HB("ecx"), &BP(1,$in,"",0));
-+&set_label("ej1");
-+ &movb(&LB("ecx"), &BP(0,$in,"",0));
-+&set_label("ejend");
-+
-+ &xor("eax", "ecx");
-+ &xor("ebx", "edx");
-+
-+ &bswap("eax") if $swap;
-+ &bswap("ebx") if $swap;
-+
-+ &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call
-+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
-+
-+ &call($enc_func);
-+
-+ &mov("eax", &DWP($data_off,"esp","",0));
-+ &mov("ebx", &DWP($data_off+4,"esp","",0));
-+
-+ &bswap("eax") if $swap;
-+ &bswap("ebx") if $swap;
-+
-+ &mov(&DWP(0,$out,"",0),"eax");
-+ &mov(&DWP(4,$out,"",0),"ebx");
-+
-+ &jmp(&label("finish"));
-+
-+ #############################################################
-+ #############################################################
-+ &set_label("decrypt",1);
-+ # decrypt start
-+ &and($count,0xfffffff8);
-+ # The next 2 instructions are only for if the jz is taken
-+ &mov("eax", &DWP($data_off+8,"esp","",0)); # get iv[0]
-+ &mov("ebx", &DWP($data_off+12,"esp","",0)); # get iv[1]
-+ &jz(&label("decrypt_finish"));
-+
-+ &set_label("decrypt_loop");
-+ &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes
-+ &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes
-+
-+ &bswap("eax") if $swap;
-+ &bswap("ebx") if $swap;
-+
-+ &mov(&DWP($data_off,"esp","",0), "eax"); # put back
-+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
-+
-+ &call($dec_func);
-+
-+ &mov("eax", &DWP($data_off,"esp","",0)); # get return
-+ &mov("ebx", &DWP($data_off+4,"esp","",0)); #
-+
-+ &bswap("eax") if $swap;
-+ &bswap("ebx") if $swap;
-+
-+ &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0]
-+ &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1]
-+
-+ &xor("ecx", "eax");
-+ &xor("edx", "ebx");
-+
-+ &mov("eax", &DWP(0,$in,"",0)); # get old cipher text,
-+ &mov("ebx", &DWP(4,$in,"",0)); # next iv actually
-+
-+ &mov(&DWP(0,$out,"",0),"ecx");
-+ &mov(&DWP(4,$out,"",0),"edx");
-+
-+ &mov(&DWP($data_off+8,"esp","",0), "eax"); # save iv
-+ &mov(&DWP($data_off+12,"esp","",0), "ebx"); #
-+
-+ &add($in, 8);
-+ &add($out, 8);
-+
-+ &sub($count, 8);
-+ &jnz(&label("decrypt_loop"));
-+############################ ENDIT #######################3
-+ &set_label("decrypt_finish");
-+ &mov($count, &wparam(2)); # length
-+ &and($count, 7);
-+ &jz(&label("finish"));
-+
-+ &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes
-+ &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes
-+
-+ &bswap("eax") if $swap;
-+ &bswap("ebx") if $swap;
-+
-+ &mov(&DWP($data_off,"esp","",0), "eax"); # put back
-+ &mov(&DWP($data_off+4,"esp","",0), "ebx"); #
-+
-+ &call($dec_func);
-+
-+ &mov("eax", &DWP($data_off,"esp","",0)); # get return
-+ &mov("ebx", &DWP($data_off+4,"esp","",0)); #
-+
-+ &bswap("eax") if $swap;
-+ &bswap("ebx") if $swap;
-+
-+ &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0]
-+ &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1]
-+
-+ &xor("ecx", "eax");
-+ &xor("edx", "ebx");
-+
-+ # this is for when we exit
-+ &mov("eax", &DWP(0,$in,"",0)); # get old cipher text,
-+ &mov("ebx", &DWP(4,$in,"",0)); # next iv actually
-+
-+&set_label("dj7");
-+ &rotr("edx", 16);
-+ &movb(&BP(6,$out,"",0), &LB("edx"));
-+ &shr("edx",16);
-+&set_label("dj6");
-+ &movb(&BP(5,$out,"",0), &HB("edx"));
-+&set_label("dj5");
-+ &movb(&BP(4,$out,"",0), &LB("edx"));
-+&set_label("dj4");
-+ &mov(&DWP(0,$out,"",0), "ecx");
-+ &jmp(&label("djend"));
-+&set_label("dj3");
-+ &rotr("ecx", 16);
-+ &movb(&BP(2,$out,"",0), &LB("ecx"));
-+ &shl("ecx",16);
-+&set_label("dj2");
-+ &movb(&BP(1,$in,"",0), &HB("ecx"));
-+&set_label("dj1");
-+ &movb(&BP(0,$in,"",0), &LB("ecx"));
-+&set_label("djend");
-+
-+ # final iv is still in eax:ebx
-+ &jmp(&label("finish"));
-+
-+
-+############################ FINISH #######################3
-+ &set_label("finish",1);
-+ &mov("ecx", &wparam($iv_off)); # Get iv ptr
-+
-+ #################################################
-+ $total=16+4;
-+ $total+=4 if ($p1 > 0);
-+ $total+=4 if ($p2 > 0);
-+ $total+=4 if ($p3 > 0);
-+ &add("esp",$total);
-+
-+ &mov(&DWP(0,"ecx","",0), "eax"); # save iv
-+ &mov(&DWP(4,"ecx","",0), "ebx"); # save iv
-+
-+ &function_end_A($name);
-+
-+ &set_label("cbc_enc_jmp_table",1);
-+ &data_word("0");
-+ &data_word(&label("ej1"));
-+ &data_word(&label("ej2"));
-+ &data_word(&label("ej3"));
-+ &data_word(&label("ej4"));
-+ &data_word(&label("ej5"));
-+ &data_word(&label("ej6"));
-+ &data_word(&label("ej7"));
-+ &set_label("cbc_dec_jmp_table",1);
-+ &data_word("0");
-+ &data_word(&label("dj1"));
-+ &data_word(&label("dj2"));
-+ &data_word(&label("dj3"));
-+ &data_word(&label("dj4"));
-+ &data_word(&label("dj5"));
-+ &data_word(&label("dj6"));
-+ &data_word(&label("dj7"));
-+
-+ &function_end_B($name);
-+
-+ }
-+
-+1;
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/perlasm/readme Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,124 @@
-+The perl scripts in this directory are my 'hack' to generate
-+multiple different assembler formats via the one origional script.
-+
-+The way to use this library is to start with adding the path to this directory
-+and then include it.
-+
-+push(@INC,"perlasm","../../perlasm");
-+require "x86asm.pl";
-+
-+The first thing we do is setup the file and type of assember
-+
-+&asm_init($ARGV[0],$0);
-+
-+The first argument is the 'type'. Currently
-+'cpp', 'sol', 'a.out', 'elf' or 'win32'.
-+Argument 2 is the file name.
-+
-+The reciprocal function is
-+&asm_finish() which should be called at the end.
-+
-+There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler,
-+and x86unix.pl which is the unix (gas) version.
-+
-+Functions of interest are:
-+&external_label("des_SPtrans"); declare and external variable
-+&LB(reg); Low byte for a register
-+&HB(reg); High byte for a register
-+&BP(off,base,index,scale) Byte pointer addressing
-+&DWP(off,base,index,scale) Word pointer addressing
-+&stack_push(num) Basically a 'sub esp, num*4' with extra
-+&stack_pop(num) inverse of stack_push
-+&function_begin(name,extra) Start a function with pushing of
-+ edi, esi, ebx and ebp. extra is extra win32
-+ external info that may be required.
-+&function_begin_B(name,extra) Same as norma function_begin but no pushing.
-+&function_end(name) Call at end of function.
-+&function_end_A(name) Standard pop and ret, for use inside functions
-+&function_end_B(name) Call at end but with poping or 'ret'.
-+&swtmp(num) Address on stack temp word.
-+&wparam(num) Parameter number num, that was push
-+ in C convention. This all works over pushes
-+ and pops.
-+&comment("hello there") Put in a comment.
-+&label("loop") Refer to a label, normally a jmp target.
-+&set_label("loop") Set a label at this point.
-+&data_word(word) Put in a word of data.
-+
-+So how does this all hold together? Given
-+
-+int calc(int len, int *data)
-+ {
-+ int i,j=0;
-+
-+ for (i=0; i<len; i++)
-+ {
-+ j+=other(data[i]);
-+ }
-+ }
-+
-+So a very simple version of this function could be coded as
-+
-+ push(@INC,"perlasm","../../perlasm");
-+ require "x86asm.pl";
-+
-+ &asm_init($ARGV[0],"cacl.pl");
-+
-+ &external_label("other");
-+
-+ $tmp1= "eax";
-+ $j= "edi";
-+ $data= "esi";
-+ $i= "ebp";
-+
-+ &comment("a simple function");
-+ &function_begin("calc");
-+ &mov( $data, &wparam(1)); # data
-+ &xor( $j, $j);
-+ &xor( $i, $i);
-+
-+ &set_label("loop");
-+ &cmp( $i, &wparam(0));
-+ &jge( &label("end"));
-+
-+ &mov( $tmp1, &DWP(0,$data,$i,4));
-+ &push( $tmp1);
-+ &call( "other");
-+ &add( $j, "eax");
-+ &pop( $tmp1);
-+ &inc( $i);
-+ &jmp( &label("loop"));
-+
-+ &set_label("end");
-+ &mov( "eax", $j);
-+
-+ &function_end("calc");
-+
-+ &asm_finish();
-+
-+The above example is very very unoptimised but gives an idea of how
-+things work.
-+
-+There is also a cbc mode function generator in cbc.pl
-+
-+&cbc( $name,
-+ $encrypt_function_name,
-+ $decrypt_function_name,
-+ $true_if_byte_swap_needed,
-+ $parameter_number_for_iv,
-+ $parameter_number_for_encrypt_flag,
-+ $first_parameter_to_pass,
-+ $second_parameter_to_pass,
-+ $third_parameter_to_pass);
-+
-+So for example, given
-+void BF_encrypt(BF_LONG *data,BF_KEY *key);
-+void BF_decrypt(BF_LONG *data,BF_KEY *key);
-+void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
-+ BF_KEY *ks, unsigned char *iv, int enc);
-+
-+&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1);
-+
-+&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
-+&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/perlasm/x86asm.pl Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,111 @@
-+#!/usr/bin/perl
-+
-+# require 'x86asm.pl';
-+# &asm_init("cpp","des-586.pl");
-+# XXX
-+# XXX
-+# main'asm_finish
-+
-+sub main'asm_finish
-+ {
-+ &file_end();
-+ &asm_finish_cpp() if $cpp;
-+ print &asm_get_output();
-+ }
-+
-+sub main'asm_init
-+ {
-+ ($type,$fn)=@_;
-+ $filename=$fn;
-+
-+ $cpp=$sol=$aout=$win32=0;
-+ if ( ($type eq "elf"))
-+ { require "x86unix.pl"; }
-+ elsif ( ($type eq "a.out"))
-+ { $aout=1; require "x86unix.pl"; }
-+ elsif ( ($type eq "sol"))
-+ { $sol=1; require "x86unix.pl"; }
-+ elsif ( ($type eq "cpp"))
-+ { $cpp=1; require "x86unix.pl"; }
-+ elsif ( ($type eq "win32"))
-+ { $win32=1; require "x86ms.pl"; }
-+ else
-+ {
-+ print STDERR <<"EOF";
-+Pick one target type from
-+ elf - linux, FreeBSD etc
-+ a.out - old linux
-+ sol - x86 solaris
-+ cpp - format so x86unix.cpp can be used
-+ win32 - Windows 95/Windows NT
-+EOF
-+ exit(1);
-+ }
-+
-+ &asm_init_output();
-+
-+&comment("Don't even think of reading this code");
-+&comment("It was automatically generated by $filename");
-+&comment("Which is a perl program used to generate the x86 assember for");
-+&comment("any of elf, a.out, BSDI,Win32, or Solaris");
-+&comment("eric <eay\@cryptsoft.com>");
-+&comment("");
-+
-+ $filename =~ s/\.pl$//;
-+ &file($filename);
-+ }
-+
-+sub asm_finish_cpp
-+ {
-+ return unless $cpp;
-+
-+ local($tmp,$i);
-+ foreach $i (&get_labels())
-+ {
-+ $tmp.="#define $i _$i\n";
-+ }
-+ print <<"EOF";
-+/* Run the C pre-processor over this file with one of the following defined
-+ * ELF - elf object files,
-+ * OUT - a.out object files,
-+ * BSDI - BSDI style a.out object files
-+ * SOL - Solaris style elf
-+ */
-+
-+#define TYPE(a,b) .type a,b
-+#define SIZE(a,b) .size a,b
-+
-+#if defined(OUT) || defined(BSDI)
-+$tmp
-+#endif
-+
-+#ifdef OUT
-+#define OK 1
-+#define ALIGN 4
-+#endif
-+
-+#ifdef BSDI
-+#define OK 1
-+#define ALIGN 4
-+#undef SIZE
-+#undef TYPE
-+#endif
-+
-+#if defined(ELF) || defined(SOL)
-+#define OK 1
-+#define ALIGN 16
-+#endif
-+
-+#ifndef OK
-+You need to define one of
-+ELF - elf systems - linux-elf, NetBSD and DG-UX
-+OUT - a.out systems - linux-a.out and FreeBSD
-+SOL - solaris systems, which are elf with strange comment lines
-+BSDI - a.out with a very primative version of as.
-+#endif
-+
-+/* Let the Assembler begin :-) */
-+EOF
-+ }
-+
-+1;
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/perlasm/x86ms.pl Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,345 @@
-+#!/usr/bin/perl
-+
-+package x86ms;
-+
-+$label="L000";
-+
-+%lb=( 'eax', 'al',
-+ 'ebx', 'bl',
-+ 'ecx', 'cl',
-+ 'edx', 'dl',
-+ 'ax', 'al',
-+ 'bx', 'bl',
-+ 'cx', 'cl',
-+ 'dx', 'dl',
-+ );
-+
-+%hb=( 'eax', 'ah',
-+ 'ebx', 'bh',
-+ 'ecx', 'ch',
-+ 'edx', 'dh',
-+ 'ax', 'ah',
-+ 'bx', 'bh',
-+ 'cx', 'ch',
-+ 'dx', 'dh',
-+ );
-+
-+sub main'asm_init_output { @out=(); }
-+sub main'asm_get_output { return(@out); }
-+sub main'get_labels { return(@labels); }
-+sub main'external_label { push(@labels,@_); }
-+
-+sub main'LB
-+ {
-+ (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
-+ return($lb{$_[0]});
-+ }
-+
-+sub main'HB
-+ {
-+ (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
-+ return($hb{$_[0]});
-+ }
-+
-+sub main'BP
-+ {
-+ &get_mem("BYTE",@_);
-+ }
-+
-+sub main'DWP
-+ {
-+ &get_mem("DWORD",@_);
-+ }
-+
-+sub main'stack_push
-+ {
-+ local($num)=@_;
-+ $stack+=$num*4;
-+ &main'sub("esp",$num*4);
-+ }
-+
-+sub main'stack_pop
-+ {
-+ local($num)=@_;
-+ $stack-=$num*4;
-+ &main'add("esp",$num*4);
-+ }
-+
-+sub get_mem
-+ {
-+ local($size,$addr,$reg1,$reg2,$idx)=@_;
-+ local($t,$post);
-+ local($ret)="$size PTR ";
-+
-+ $addr =~ s/^\s+//;
-+ if ($addr =~ /^(.+)\+(.+)$/)
-+ {
-+ $reg2=&conv($1);
-+ $addr="_$2";
-+ }
-+ elsif ($addr =~ /^[_a-zA-Z]/)
-+ {
-+ $addr="_$addr";
-+ }
-+
-+ $reg1="$regs{$reg1}" if defined($regs{$reg1});
-+ $reg2="$regs{$reg2}" if defined($regs{$reg2});
-+ if (($addr ne "") && ($addr ne 0))
-+ {
-+ if ($addr !~ /^-/)
-+ { $ret.=$addr; }
-+ else { $post=$addr; }
-+ }
-+ if ($reg2 ne "")
-+ {
-+ $t="";
-+ $t="*$idx" if ($idx != 0);
-+ $reg1="+".$reg1 if ("$reg1$post" ne "");
-+ $ret.="[$reg2$t$reg1$post]";
-+ }
-+ else
-+ {
-+ $ret.="[$reg1$post]"
-+ }
-+ return($ret);
-+ }
-+
-+sub main'mov { &out2("mov",@_); }
-+sub main'movb { &out2("mov",@_); }
-+sub main'and { &out2("and",@_); }
-+sub main'or { &out2("or",@_); }
-+sub main'shl { &out2("shl",@_); }
-+sub main'shr { &out2("shr",@_); }
-+sub main'xor { &out2("xor",@_); }
-+sub main'xorb { &out2("xor",@_); }
-+sub main'add { &out2("add",@_); }
-+sub main'adc { &out2("adc",@_); }
-+sub main'sub { &out2("sub",@_); }
-+sub main'rotl { &out2("rol",@_); }
-+sub main'rotr { &out2("ror",@_); }
-+sub main'exch { &out2("xchg",@_); }
-+sub main'cmp { &out2("cmp",@_); }
-+sub main'lea { &out2("lea",@_); }
-+sub main'mul { &out1("mul",@_); }
-+sub main'div { &out1("div",@_); }
-+sub main'dec { &out1("dec",@_); }
-+sub main'inc { &out1("inc",@_); }
-+sub main'jmp { &out1("jmp",@_); }
-+sub main'jmp_ptr { &out1p("jmp",@_); }
-+sub main'je { &out1("je",@_); }
-+sub main'jle { &out1("jle",@_); }
-+sub main'jz { &out1("jz",@_); }
-+sub main'jge { &out1("jge",@_); }
-+sub main'jl { &out1("jl",@_); }
-+sub main'jb { &out1("jb",@_); }
-+sub main'jnz { &out1("jnz",@_); }
-+sub main'jne { &out1("jne",@_); }
-+sub main'push { &out1("push",@_); $stack+=4; }
-+sub main'pop { &out1("pop",@_); $stack-=4; }
-+sub main'bswap { &out1("bswap",@_); &using486(); }
-+sub main'not { &out1("not",@_); }
-+sub main'call { &out1("call",'_'.$_[0]); }
-+sub main'ret { &out0("ret"); }
-+sub main'nop { &out0("nop"); }
-+
-+sub out2
-+ {
-+ local($name,$p1,$p2)=@_;
-+ local($l,$t);
-+
-+ push(@out,"\t$name\t");
-+ $t=&conv($p1).",";
-+ $l=length($t);
-+ push(@out,$t);
-+ $l=4-($l+9)/8;
-+ push(@out,"\t" x $l);
-+ push(@out,&conv($p2));
-+ push(@out,"\n");
-+ }
-+
-+sub out0
-+ {
-+ local($name)=@_;
-+
-+ push(@out,"\t$name\n");
-+ }
-+
-+sub out1
-+ {
-+ local($name,$p1)=@_;
-+ local($l,$t);
-+
-+ push(@out,"\t$name\t".&conv($p1)."\n");
-+ }
-+
-+sub conv
-+ {
-+ local($p)=@_;
-+
-+ $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
-+ return $p;
-+ }
-+
-+sub using486
-+ {
-+ return if $using486;
-+ $using486++;
-+ grep(s/\.386/\.486/,@out);
-+ }
-+
-+sub main'file
-+ {
-+ local($file)=@_;
-+
-+ local($tmp)=<<"EOF";
-+ TITLE $file.asm
-+ .386
-+.model FLAT
-+EOF
-+ push(@out,$tmp);
-+ }
-+
-+sub main'function_begin
-+ {
-+ local($func,$extra)=@_;
-+
-+ push(@labels,$func);
-+
-+ local($tmp)=<<"EOF";
-+_TEXT SEGMENT
-+PUBLIC _$func
-+$extra
-+_$func PROC NEAR
-+ push ebp
-+ push ebx
-+ push esi
-+ push edi
-+EOF
-+ push(@out,$tmp);
-+ $stack=20;
-+ }
-+
-+sub main'function_begin_B
-+ {
-+ local($func,$extra)=@_;
-+
-+ local($tmp)=<<"EOF";
-+_TEXT SEGMENT
-+PUBLIC _$func
-+$extra
-+_$func PROC NEAR
-+EOF
-+ push(@out,$tmp);
-+ $stack=4;
-+ }
-+
-+sub main'function_end
-+ {
-+ local($func)=@_;
-+
-+ local($tmp)=<<"EOF";
-+ pop edi
-+ pop esi
-+ pop ebx
-+ pop ebp
-+ ret
-+_$func ENDP
-+_TEXT ENDS
-+EOF
-+ push(@out,$tmp);
-+ $stack=0;
-+ %label=();
-+ }
-+
-+sub main'function_end_B
-+ {
-+ local($func)=@_;
-+
-+ local($tmp)=<<"EOF";
-+_$func ENDP
-+_TEXT ENDS
-+EOF
-+ push(@out,$tmp);
-+ $stack=0;
-+ %label=();
-+ }
-+
-+sub main'function_end_A
-+ {
-+ local($func)=@_;
-+
-+ local($tmp)=<<"EOF";
-+ pop edi
-+ pop esi
-+ pop ebx
-+ pop ebp
-+ ret
-+EOF
-+ push(@out,$tmp);
-+ }
-+
-+sub main'file_end
-+ {
-+ push(@out,"END\n");
-+ }
-+
-+sub main'wparam
-+ {
-+ local($num)=@_;
-+
-+ return(&main'DWP($stack+$num*4,"esp","",0));
-+ }
-+
-+sub main'swtmp
-+ {
-+ return(&main'DWP($_[0]*4,"esp","",0));
-+ }
-+
-+# Should use swtmp, which is above esp. Linix can trash the stack above esp
-+#sub main'wtmp
-+# {
-+# local($num)=@_;
-+#
-+# return(&main'DWP(-(($num+1)*4),"esp","",0));
-+# }
-+
-+sub main'comment
-+ {
-+ foreach (@_)
-+ {
-+ push(@out,"\t; $_\n");
-+ }
-+ }
-+
-+sub main'label
-+ {
-+ if (!defined($label{$_[0]}))
-+ {
-+ $label{$_[0]}="\$${label}${_[0]}";
-+ $label++;
-+ }
-+ return($label{$_[0]});
-+ }
-+
-+sub main'set_label
-+ {
-+ if (!defined($label{$_[0]}))
-+ {
-+ $label{$_[0]}="${label}${_[0]}";
-+ $label++;
-+ }
-+ push(@out,"$label{$_[0]}:\n");
-+ }
-+
-+sub main'data_word
-+ {
-+ push(@out,"\tDD\t$_[0]\n");
-+ }
-+
-+sub out1p
-+ {
-+ local($name,$p1)=@_;
-+ local($l,$t);
-+
-+ push(@out,"\t$name\t ".&conv($p1)."\n");
-+ }
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/perlasm/x86unix.pl Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,403 @@
-+#!/usr/bin/perl
-+
-+package x86unix;
-+
-+$label="L000";
-+
-+$align=($main'aout)?"4":"16";
-+$under=($main'aout)?"_":"";
-+$com_start=($main'sol)?"/":"#";
-+
-+sub main'asm_init_output { @out=(); }
-+sub main'asm_get_output { return(@out); }
-+sub main'get_labels { return(@labels); }
-+sub main'external_label { push(@labels,@_); }
-+
-+if ($main'cpp)
-+ {
-+ $align="ALIGN";
-+ $under="";
-+ $com_start='/*';
-+ $com_end='*/';
-+ }
-+
-+%lb=( 'eax', '%al',
-+ 'ebx', '%bl',
-+ 'ecx', '%cl',
-+ 'edx', '%dl',
-+ 'ax', '%al',
-+ 'bx', '%bl',
-+ 'cx', '%cl',
-+ 'dx', '%dl',
-+ );
-+
-+%hb=( 'eax', '%ah',
-+ 'ebx', '%bh',
-+ 'ecx', '%ch',
-+ 'edx', '%dh',
-+ 'ax', '%ah',
-+ 'bx', '%bh',
-+ 'cx', '%ch',
-+ 'dx', '%dh',
-+ );
-+
-+%regs=( 'eax', '%eax',
-+ 'ebx', '%ebx',
-+ 'ecx', '%ecx',
-+ 'edx', '%edx',
-+ 'esi', '%esi',
-+ 'edi', '%edi',
-+ 'ebp', '%ebp',
-+ 'esp', '%esp',
-+ );
-+
-+%reg_val=(
-+ 'eax', 0x00,
-+ 'ebx', 0x03,
-+ 'ecx', 0x01,
-+ 'edx', 0x02,
-+ 'esi', 0x06,
-+ 'edi', 0x07,
-+ 'ebp', 0x05,
-+ 'esp', 0x04,
-+ );
-+
-+sub main'LB
-+ {
-+ (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
-+ return($lb{$_[0]});
-+ }
-+
-+sub main'HB
-+ {
-+ (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
-+ return($hb{$_[0]});
-+ }
-+
-+sub main'DWP
-+ {
-+ local($addr,$reg1,$reg2,$idx)=@_;
-+
-+ $ret="";
-+ $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/;
-+ $reg1="$regs{$reg1}" if defined($regs{$reg1});
-+ $reg2="$regs{$reg2}" if defined($regs{$reg2});
-+ $ret.=$addr if ($addr ne "") && ($addr ne 0);
-+ if ($reg2 ne "")
-+ { $ret.="($reg1,$reg2,$idx)"; }
-+ else
-+ { $ret.="($reg1)" }
-+ return($ret);
-+ }
-+
-+sub main'BP
-+ {
-+ return(&main'DWP(@_));
-+ }
-+
-+#sub main'BP
-+# {
-+# local($addr,$reg1,$reg2,$idx)=@_;
-+#
-+# $ret="";
-+#
-+# $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/;
-+# $reg1="$regs{$reg1}" if defined($regs{$reg1});
-+# $reg2="$regs{$reg2}" if defined($regs{$reg2});
-+# $ret.=$addr if ($addr ne "") && ($addr ne 0);
-+# if ($reg2 ne "")
-+# { $ret.="($reg1,$reg2,$idx)"; }
-+# else
-+# { $ret.="($reg1)" }
-+# return($ret);
-+# }
-+
-+sub main'mov { &out2("movl",@_); }
-+sub main'movb { &out2("movb",@_); }
-+sub main'and { &out2("andl",@_); }
-+sub main'or { &out2("orl",@_); }
-+sub main'shl { &out2("sall",@_); }
-+sub main'shr { &out2("shrl",@_); }
-+sub main'xor { &out2("xorl",@_); }
-+sub main'xorb { &out2("xorb",@_); }
-+sub main'add { &out2("addl",@_); }
-+sub main'adc { &out2("adcl",@_); }
-+sub main'sub { &out2("subl",@_); }
-+sub main'rotl { &out2("roll",@_); }
-+sub main'rotr { &out2("rorl",@_); }
-+sub main'exch { &out2("xchg",@_); }
-+sub main'cmp { &out2("cmpl",@_); }
-+sub main'lea { &out2("leal",@_); }
-+sub main'mul { &out1("mull",@_); }
-+sub main'div { &out1("divl",@_); }
-+sub main'jmp { &out1("jmp",@_); }
-+sub main'jmp_ptr { &out1p("jmp",@_); }
-+sub main'je { &out1("je",@_); }
-+sub main'jle { &out1("jle",@_); }
-+sub main'jne { &out1("jne",@_); }
-+sub main'jnz { &out1("jnz",@_); }
-+sub main'jz { &out1("jz",@_); }
-+sub main'jge { &out1("jge",@_); }
-+sub main'jl { &out1("jl",@_); }
-+sub main'jb { &out1("jb",@_); }
-+sub main'dec { &out1("decl",@_); }
-+sub main'inc { &out1("incl",@_); }
-+sub main'push { &out1("pushl",@_); $stack+=4; }
-+sub main'pop { &out1("popl",@_); $stack-=4; }
-+sub main'bswap { &out1("bswapl",@_); }
-+sub main'not { &out1("notl",@_); }
-+sub main'call { &out1("call",$under.$_[0]); }
-+sub main'ret { &out0("ret"); }
-+sub main'nop { &out0("nop"); }
-+
-+sub out2
-+ {
-+ local($name,$p1,$p2)=@_;
-+ local($l,$ll,$t);
-+ local(%special)=( "roll",0xD1C0,"rorl",0xD1C8,
-+ "rcll",0xD1D0,"rcrl",0xD1D8,
-+ "shll",0xD1E0,"shrl",0xD1E8,
-+ "sarl",0xD1F8);
-+
-+ if ((defined($special{$name})) && defined($regs{$p1}) && ($p2 == 1))
-+ {
-+ $op=$special{$name}|$reg_val{$p1};
-+ $tmp1=sprintf ".byte %d\n",($op>>8)&0xff;
-+ $tmp2=sprintf ".byte %d\t",$op &0xff;
-+ push(@out,$tmp1);
-+ push(@out,$tmp2);
-+
-+ $p2=&conv($p2);
-+ $p1=&conv($p1);
-+ &main'comment("$name $p2 $p1");
-+ return;
-+ }
-+
-+ push(@out,"\t$name\t");
-+ $t=&conv($p2).",";
-+ $l=length($t);
-+ push(@out,$t);
-+ $ll=4-($l+9)/8;
-+ $tmp1=sprintf "\t" x $ll;
-+ push(@out,$tmp1);
-+ push(@out,&conv($p1)."\n");
-+ }
-+
-+sub out1
-+ {
-+ local($name,$p1)=@_;
-+ local($l,$t);
-+
-+ push(@out,"\t$name\t".&conv($p1)."\n");
-+ }
-+
-+sub out1p
-+ {
-+ local($name,$p1)=@_;
-+ local($l,$t);
-+
-+ push(@out,"\t$name\t*".&conv($p1)."\n");
-+ }
-+
-+sub out0
-+ {
-+ push(@out,"\t$_[0]\n");
-+ }
-+
-+sub conv
-+ {
-+ local($p)=@_;
-+
-+# $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
-+
-+ $p=$regs{$p} if (defined($regs{$p}));
-+
-+ $p =~ s/^(-{0,1}[0-9A-Fa-f]+)$/\$$1/;
-+ $p =~ s/^(0x[0-9A-Fa-f]+)$/\$$1/;
-+ return $p;
-+ }
-+
-+sub main'file
-+ {
-+ local($file)=@_;
-+
-+ local($tmp)=<<"EOF";
-+ .file "$file.s"
-+ .version "01.01"
-+gcc2_compiled.:
-+EOF
-+ push(@out,$tmp);
-+ }
-+
-+sub main'function_begin
-+ {
-+ local($func)=@_;
-+
-+ $func=$under.$func;
-+
-+ local($tmp)=<<"EOF";
-+.text
-+ .align $align
-+.globl $func
-+EOF
-+ push(@out,$tmp);
-+ if ($main'cpp)
-+ { $tmp=push(@out,"\tTYPE($func,\@function)\n"); }
-+ else { $tmp=push(@out,"\t.type\t$func,\@function\n"); }
-+ push(@out,"$func:\n");
-+ $tmp=<<"EOF";
-+ pushl %ebp
-+ pushl %ebx
-+ pushl %esi
-+ pushl %edi
-+
-+EOF
-+ push(@out,$tmp);
-+ $stack=20;
-+ }
-+
-+sub main'function_begin_B
-+ {
-+ local($func,$extra)=@_;
-+
-+ $func=$under.$func;
-+
-+ local($tmp)=<<"EOF";
-+.text
-+ .align $align
-+.globl $func
-+EOF
-+ push(@out,$tmp);
-+ if ($main'cpp)
-+ { push(@out,"\tTYPE($func,\@function)\n"); }
-+ else { push(@out,"\t.type $func,\@function\n"); }
-+ push(@out,"$func:\n");
-+ $stack=4;
-+ }
-+
-+sub main'function_end
-+ {
-+ local($func)=@_;
-+
-+ $func=$under.$func;
-+
-+ local($tmp)=<<"EOF";
-+ popl %edi
-+ popl %esi
-+ popl %ebx
-+ popl %ebp
-+ ret
-+.${func}_end:
-+EOF
-+ push(@out,$tmp);
-+ if ($main'cpp)
-+ { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); }
-+ else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); }
-+ push(@out,".ident \"$func\"\n");
-+ $stack=0;
-+ %label=();
-+ }
-+
-+sub main'function_end_A
-+ {
-+ local($func)=@_;
-+
-+ local($tmp)=<<"EOF";
-+ popl %edi
-+ popl %esi
-+ popl %ebx
-+ popl %ebp
-+ ret
-+EOF
-+ push(@out,$tmp);
-+ }
-+
-+sub main'function_end_B
-+ {
-+ local($func)=@_;
-+
-+ $func=$under.$func;
-+
-+ push(@out,".${func}_end:\n");
-+ if ($main'cpp)
-+ { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); }
-+ else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); }
-+ push(@out,".ident \"desasm.pl\"\n");
-+ $stack=0;
-+ %label=();
-+ }
-+
-+sub main'wparam
-+ {
-+ local($num)=@_;
-+
-+ return(&main'DWP($stack+$num*4,"esp","",0));
-+ }
-+
-+sub main'stack_push
-+ {
-+ local($num)=@_;
-+ $stack+=$num*4;
-+ &main'sub("esp",$num*4);
-+ }
-+
-+sub main'stack_pop
-+ {
-+ local($num)=@_;
-+ $stack-=$num*4;
-+ &main'add("esp",$num*4);
-+ }
-+
-+sub main'swtmp
-+ {
-+ return(&main'DWP($_[0]*4,"esp","",0));
-+ }
-+
-+# Should use swtmp, which is above esp. Linix can trash the stack above esp
-+#sub main'wtmp
-+# {
-+# local($num)=@_;
-+#
-+# return(&main'DWP(-($num+1)*4,"esp","",0));
-+# }
-+
-+sub main'comment
-+ {
-+ foreach (@_)
-+ {
-+ if (/^\s*$/)
-+ { push(@out,"\n"); }
-+ else
-+ { push(@out,"\t$com_start $_ $com_end\n"); }
-+ }
-+ }
-+
-+sub main'label
-+ {
-+ if (!defined($label{$_[0]}))
-+ {
-+ $label{$_[0]}=".${label}${_[0]}";
-+ $label++;
-+ }
-+ return($label{$_[0]});
-+ }
-+
-+sub main'set_label
-+ {
-+ if (!defined($label{$_[0]}))
-+ {
-+ $label{$_[0]}=".${label}${_[0]}";
-+ $label++;
-+ }
-+ push(@out,".align $align\n") if ($_[1] != 0);
-+ push(@out,"$label{$_[0]}:\n");
-+ }
-+
-+sub main'file_end
-+ {
-+ }
-+
-+sub main'data_word
-+ {
-+ push(@out,"\t.long $_[0]\n");
-+ }
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/asm/readme Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,131 @@
-+First up, let me say I don't like writing in assembler. It is not portable,
-+dependant on the particular CPU architecture release and is generally a pig
-+to debug and get right. Having said that, the x86 architecture is probably
-+the most important for speed due to number of boxes and since
-+it appears to be the worst architecture to to get
-+good C compilers for. So due to this, I have lowered myself to do
-+assembler for the inner DES routines in libdes :-).
-+
-+The file to implement in assembler is des_enc.c. Replace the following
-+4 functions
-+des_encrypt(DES_LONG data[2],des_key_schedule ks, int encrypt);
-+des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt);
-+des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
-+des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3);
-+
-+They encrypt/decrypt the 64 bits held in 'data' using
-+the 'ks' key schedules. The only difference between the 4 functions is that
-+des_encrypt2() does not perform IP() or FP() on the data (this is an
-+optimization for when doing triple DES and des_encrypt3() and des_decrypt3()
-+perform triple des. The triple DES routines are in here because it does
-+make a big difference to have them located near the des_encrypt2 function
-+at link time..
-+
-+Now as we all know, there are lots of different operating systems running on
-+x86 boxes, and unfortunately they normally try to make sure their assembler
-+formating is not the same as the other peoples.
-+The 4 main formats I know of are
-+Microsoft Windows 95/Windows NT
-+Elf Includes Linux and FreeBSD(?).
-+a.out The older Linux.
-+Solaris Same as Elf but different comments :-(.
-+
-+Now I was not overly keen to write 4 different copies of the same code,
-+so I wrote a few perl routines to output the correct assembler, given
-+a target assembler type. This code is ugly and is just a hack.
-+The libraries are x86unix.pl and x86ms.pl.
-+des586.pl, des686.pl and des-som[23].pl are the programs to actually
-+generate the assembler.
-+
-+So to generate elf assembler
-+perl des-som3.pl elf >dx86-elf.s
-+For Windows 95/NT
-+perl des-som2.pl win32 >win32.asm
-+
-+[ update 4 Jan 1996 ]
-+I have added another way to do things.
-+perl des-som3.pl cpp >dx86-cpp.s
-+generates a file that will be included by dx86unix.cpp when it is compiled.
-+To build for elf, a.out, solaris, bsdi etc,
-+cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o
-+cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o
-+cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o
-+cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o
-+This was done to cut down the number of files in the distribution.
-+
-+Now the ugly part. I acquired my copy of Intels
-+"Optimization's For Intel's 32-Bit Processors" and found a few interesting
-+things. First, the aim of the exersize is to 'extract' one byte at a time
-+from a word and do an array lookup. This involves getting the byte from
-+the 4 locations in the word and moving it to a new word and doing the lookup.
-+The most obvious way to do this is
-+xor eax, eax # clear word
-+movb al, cl # get low byte
-+xor edi DWORD PTR 0x100+des_SP[eax] # xor in word
-+movb al, ch # get next byte
-+xor edi DWORD PTR 0x300+des_SP[eax] # xor in word
-+shr ecx 16
-+which seems ok. For the pentium, this system appears to be the best.
-+One has to do instruction interleaving to keep both functional units
-+operating, but it is basically very efficient.
-+
-+Now the crunch. When a full register is used after a partial write, eg.
-+mov al, cl
-+xor edi, DWORD PTR 0x100+des_SP[eax]
-+386 - 1 cycle stall
-+486 - 1 cycle stall
-+586 - 0 cycle stall
-+686 - at least 7 cycle stall (page 22 of the above mentioned document).
-+
-+So the technique that produces the best results on a pentium, according to
-+the documentation, will produce hideous results on a pentium pro.
-+
-+To get around this, des686.pl will generate code that is not as fast on
-+a pentium, should be very good on a pentium pro.
-+mov eax, ecx # copy word
-+shr ecx, 8 # line up next byte
-+and eax, 0fch # mask byte
-+xor edi DWORD PTR 0x100+des_SP[eax] # xor in array lookup
-+mov eax, ecx # get word
-+shr ecx 8 # line up next byte
-+and eax, 0fch # mask byte
-+xor edi DWORD PTR 0x300+des_SP[eax] # xor in array lookup
-+
-+Due to the execution units in the pentium, this actually works quite well.
-+For a pentium pro it should be very good. This is the type of output
-+Visual C++ generates.
-+
-+There is a third option. instead of using
-+mov al, ch
-+which is bad on the pentium pro, one may be able to use
-+movzx eax, ch
-+which may not incur the partial write penalty. On the pentium,
-+this instruction takes 4 cycles so is not worth using but on the
-+pentium pro it appears it may be worth while. I need access to one to
-+experiment :-).
-+
-+eric (20 Oct 1996)
-+
-+22 Nov 1996 - I have asked people to run the 2 different version on pentium
-+pros and it appears that the intel documentation is wrong. The
-+mov al,bh is still faster on a pentium pro, so just use the des586.pl
-+install des686.pl
-+
-+3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these
-+functions into des_enc.c because it does make a massive performance
-+difference on some boxes to have the functions code located close to
-+the des_encrypt2() function.
-+
-+9 Jan 1997 - des-som2.pl is now the correct perl script to use for
-+pentiums. It contains an inner loop from
-+Svend Olaf Mikkelsen <svolaf@inet.uni-c.dk> which does raw ecb DES calls at
-+273,000 per second. He had a previous version at 250,000 and the best
-+I was able to get was 203,000. The content has not changed, this is all
-+due to instruction sequencing (and actual instructions choice) which is able
-+to keep both functional units of the pentium going.
-+We may have lost the ugly register usage restrictions when x86 went 32 bit
-+but for the pentium it has been replaced by evil instruction ordering tricks.
-+
-+13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf.
-+raw DES at 281,000 per second on a pentium 100.
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/cbc_enc.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,135 @@
-+/* crypto/des/cbc_enc.c */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+#include "des_locl.h"
-+
-+void des_cbc_encrypt(input, output, length, schedule, ivec, enc)
-+des_cblock (*input);
-+des_cblock (*output);
-+long length;
-+des_key_schedule schedule;
-+des_cblock (*ivec);
-+int enc;
-+ {
-+ register DES_LONG tin0,tin1;
-+ register DES_LONG tout0,tout1,xor0,xor1;
-+ register unsigned char *in,*out;
-+ register long l=length;
-+ DES_LONG tin[2];
-+ unsigned char *iv;
-+
-+ in=(unsigned char *)input;
-+ out=(unsigned char *)output;
-+ iv=(unsigned char *)ivec;
-+
-+ if (enc)
-+ {
-+ c2l(iv,tout0);
-+ c2l(iv,tout1);
-+ for (l-=8; l>=0; l-=8)
-+ {
-+ c2l(in,tin0);
-+ c2l(in,tin1);
-+ tin0^=tout0; tin[0]=tin0;
-+ tin1^=tout1; tin[1]=tin1;
-+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
-+ tout0=tin[0]; l2c(tout0,out);
-+ tout1=tin[1]; l2c(tout1,out);
-+ }
-+ if (l != -8)
-+ {
-+ c2ln(in,tin0,tin1,l+8);
-+ tin0^=tout0; tin[0]=tin0;
-+ tin1^=tout1; tin[1]=tin1;
-+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
-+ tout0=tin[0]; l2c(tout0,out);
-+ tout1=tin[1]; l2c(tout1,out);
-+ }
-+ }
-+ else
-+ {
-+ c2l(iv,xor0);
-+ c2l(iv,xor1);
-+ for (l-=8; l>=0; l-=8)
-+ {
-+ c2l(in,tin0); tin[0]=tin0;
-+ c2l(in,tin1); tin[1]=tin1;
-+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
-+ tout0=tin[0]^xor0;
-+ tout1=tin[1]^xor1;
-+ l2c(tout0,out);
-+ l2c(tout1,out);
-+ xor0=tin0;
-+ xor1=tin1;
-+ }
-+ if (l != -8)
-+ {
-+ c2l(in,tin0); tin[0]=tin0;
-+ c2l(in,tin1); tin[1]=tin1;
-+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
-+ tout0=tin[0]^xor0;
-+ tout1=tin[1]^xor1;
-+ l2cn(tout0,tout1,out,l+8);
-+ /* xor0=tin0;
-+ xor1=tin1; */
-+ }
-+ }
-+ tin0=tin1=tout0=tout1=xor0=xor1=0;
-+ tin[0]=tin[1]=0;
-+ }
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/des.doc Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,505 @@
-+The DES library.
-+
-+Please note that this library was originally written to operate with
-+eBones, a version of Kerberos that had had encryption removed when it left
-+the USA and then put back in. As such there are some routines that I will
-+advise not using but they are still in the library for historical reasons.
-+For all calls that have an 'input' and 'output' variables, they can be the
-+same.
-+
-+This library requires the inclusion of 'des.h'.
-+
-+All of the encryption functions take what is called a des_key_schedule as an
-+argument. A des_key_schedule is an expanded form of the des key.
-+A des_key is 8 bytes of odd parity, the type used to hold the key is a
-+des_cblock. A des_cblock is an array of 8 bytes, often in this library
-+description I will refer to input bytes when the function specifies
-+des_cblock's as input or output, this just means that the variable should
-+be a multiple of 8 bytes.
-+
-+The define DES_ENCRYPT is passed to specify encryption, DES_DECRYPT to
-+specify decryption. The functions and global variable are as follows:
-+
-+int des_check_key;
-+ DES keys are supposed to be odd parity. If this variable is set to
-+ a non-zero value, des_set_key() will check that the key has odd
-+ parity and is not one of the known weak DES keys. By default this
-+ variable is turned off;
-+
-+void des_set_odd_parity(
-+des_cblock *key );
-+ This function takes a DES key (8 bytes) and sets the parity to odd.
-+
-+int des_is_weak_key(
-+des_cblock *key );
-+ This function returns a non-zero value if the DES key passed is a
-+ weak, DES key. If it is a weak key, don't use it, try a different
-+ one. If you are using 'random' keys, the chances of hitting a weak
-+ key are 1/2^52 so it is probably not worth checking for them.
-+
-+int des_set_key(
-+des_cblock *key,
-+des_key_schedule schedule);
-+ Des_set_key converts an 8 byte DES key into a des_key_schedule.
-+ A des_key_schedule is an expanded form of the key which is used to
-+ perform actual encryption. It can be regenerated from the DES key
-+ so it only needs to be kept when encryption or decryption is about
-+ to occur. Don't save or pass around des_key_schedule's since they
-+ are CPU architecture dependent, DES keys are not. If des_check_key
-+ is non zero, zero is returned if the key has the wrong parity or
-+ the key is a weak key, else 1 is returned.
-+
-+int des_key_sched(
-+des_cblock *key,
-+des_key_schedule schedule);
-+ An alternative name for des_set_key().
-+
-+int des_rw_mode; /* defaults to DES_PCBC_MODE */
-+ This flag holds either DES_CBC_MODE or DES_PCBC_MODE (default).
-+ This specifies the function to use in the enc_read() and enc_write()
-+ functions.
-+
-+void des_encrypt(
-+unsigned long *data,
-+des_key_schedule ks,
-+int enc);
-+ This is the DES encryption function that gets called by just about
-+ every other DES routine in the library. You should not use this
-+ function except to implement 'modes' of DES. I say this because the
-+ functions that call this routine do the conversion from 'char *' to
-+ long, and this needs to be done to make sure 'non-aligned' memory
-+ access do not occur. The characters are loaded 'little endian',
-+ have a look at my source code for more details on how I use this
-+ function.
-+ Data is a pointer to 2 unsigned long's and ks is the
-+ des_key_schedule to use. enc, is non zero specifies encryption,
-+ zero if decryption.
-+
-+void des_encrypt2(
-+unsigned long *data,
-+des_key_schedule ks,
-+int enc);
-+ This functions is the same as des_encrypt() except that the DES
-+ initial permutation (IP) and final permutation (FP) have been left
-+ out. As for des_encrypt(), you should not use this function.
-+ It is used by the routines in my library that implement triple DES.
-+ IP() des_encrypt2() des_encrypt2() des_encrypt2() FP() is the same
-+ as des_encrypt() des_encrypt() des_encrypt() except faster :-).
-+
-+void des_ecb_encrypt(
-+des_cblock *input,
-+des_cblock *output,
-+des_key_schedule ks,
-+int enc);
-+ This is the basic Electronic Code Book form of DES, the most basic
-+ form. Input is encrypted into output using the key represented by
-+ ks. If enc is non zero (DES_ENCRYPT), encryption occurs, otherwise
-+ decryption occurs. Input is 8 bytes long and output is 8 bytes.
-+ (the des_cblock structure is 8 chars).
-+
-+void des_ecb3_encrypt(
-+des_cblock *input,
-+des_cblock *output,
-+des_key_schedule ks1,
-+des_key_schedule ks2,
-+des_key_schedule ks3,
-+int enc);
-+ This is the 3 key EDE mode of ECB DES. What this means is that
-+ the 8 bytes of input is encrypted with ks1, decrypted with ks2 and
-+ then encrypted again with ks3, before being put into output;
-+ C=E(ks3,D(ks2,E(ks1,M))). There is a macro, des_ecb2_encrypt()
-+ that only takes 2 des_key_schedules that implements,
-+ C=E(ks1,D(ks2,E(ks1,M))) in that the final encrypt is done with ks1.
-+
-+void des_cbc_encrypt(
-+des_cblock *input,
-+des_cblock *output,
-+long length,
-+des_key_schedule ks,
-+des_cblock *ivec,
-+int enc);
-+ This routine implements DES in Cipher Block Chaining mode.
-+ Input, which should be a multiple of 8 bytes is encrypted
-+ (or decrypted) to output which will also be a multiple of 8 bytes.
-+ The number of bytes is in length (and from what I've said above,
-+ should be a multiple of 8). If length is not a multiple of 8, I'm
-+ not being held responsible :-). ivec is the initialisation vector.
-+ This function does not modify this variable. To correctly implement
-+ cbc mode, you need to do one of 2 things; copy the last 8 bytes of
-+ cipher text for use as the next ivec in your application,
-+ or use des_ncbc_encrypt().
-+ Only this routine has this problem with updating the ivec, all
-+ other routines that are implementing cbc mode update ivec.
-+
-+void des_ncbc_encrypt(
-+des_cblock *input,
-+des_cblock *output,
-+long length,
-+des_key_schedule sk,
-+des_cblock *ivec,
-+int enc);
-+ For historical reasons, des_cbc_encrypt() did not update the
-+ ivec with the value requires so that subsequent calls to
-+ des_cbc_encrypt() would 'chain'. This was needed so that the same
-+ 'length' values would not need to be used when decrypting.
-+ des_ncbc_encrypt() does the right thing. It is the same as
-+ des_cbc_encrypt accept that ivec is updates with the correct value
-+ to pass in subsequent calls to des_ncbc_encrypt(). I advise using
-+ des_ncbc_encrypt() instead of des_cbc_encrypt();
-+
-+void des_xcbc_encrypt(
-+des_cblock *input,
-+des_cblock *output,
-+long length,
-+des_key_schedule sk,
-+des_cblock *ivec,
-+des_cblock *inw,
-+des_cblock *outw,
-+int enc);
-+ This is RSA's DESX mode of DES. It uses inw and outw to
-+ 'whiten' the encryption. inw and outw are secret (unlike the iv)
-+ and are as such, part of the key. So the key is sort of 24 bytes.
-+ This is much better than cbc des.
-+
-+void des_3cbc_encrypt(
-+des_cblock *input,
-+des_cblock *output,
-+long length,
-+des_key_schedule sk1,
-+des_key_schedule sk2,
-+des_cblock *ivec1,
-+des_cblock *ivec2,
-+int enc);
-+ This function is flawed, do not use it. I have left it in the
-+ library because it is used in my des(1) program and will function
-+ correctly when used by des(1). If I removed the function, people
-+ could end up unable to decrypt files.
-+ This routine implements outer triple cbc encryption using 2 ks and
-+ 2 ivec's. Use des_ede2_cbc_encrypt() instead.
-+
-+void des_ede3_cbc_encrypt(
-+des_cblock *input,
-+des_cblock *output,
-+long length,
-+des_key_schedule ks1,
-+des_key_schedule ks2,
-+des_key_schedule ks3,
-+des_cblock *ivec,
-+int enc);
-+ This function implements inner triple CBC DES encryption with 3
-+ keys. What this means is that each 'DES' operation
-+ inside the cbc mode is really an C=E(ks3,D(ks2,E(ks1,M))).
-+ Again, this is cbc mode so an ivec is requires.
-+ This mode is used by SSL.
-+ There is also a des_ede2_cbc_encrypt() that only uses 2
-+ des_key_schedule's, the first being reused for the final
-+ encryption. C=E(ks1,D(ks2,E(ks1,M))). This form of triple DES
-+ is used by the RSAref library.
-+
-+void des_pcbc_encrypt(
-+des_cblock *input,
-+des_cblock *output,
-+long length,
-+des_key_schedule ks,
-+des_cblock *ivec,
-+int enc);
-+ This is Propagating Cipher Block Chaining mode of DES. It is used
-+ by Kerberos v4. It's parameters are the same as des_ncbc_encrypt().
-+
-+void des_cfb_encrypt(
-+unsigned char *in,
-+unsigned char *out,
-+int numbits,
-+long length,
-+des_key_schedule ks,
-+des_cblock *ivec,
-+int enc);
-+ Cipher Feedback Back mode of DES. This implementation 'feeds back'
-+ in numbit blocks. The input (and output) is in multiples of numbits
-+ bits. numbits should to be a multiple of 8 bits. Length is the
-+ number of bytes input. If numbits is not a multiple of 8 bits,
-+ the extra bits in the bytes will be considered padding. So if
-+ numbits is 12, for each 2 input bytes, the 4 high bits of the
-+ second byte will be ignored. So to encode 72 bits when using
-+ a numbits of 12 take 12 bytes. To encode 72 bits when using
-+ numbits of 9 will take 16 bytes. To encode 80 bits when using
-+ numbits of 16 will take 10 bytes. etc, etc. This padding will
-+ apply to both input and output.
-+
-+
-+void des_cfb64_encrypt(
-+unsigned char *in,
-+unsigned char *out,
-+long length,
-+des_key_schedule ks,
-+des_cblock *ivec,
-+int *num,
-+int enc);
-+ This is one of the more useful functions in this DES library, it
-+ implements CFB mode of DES with 64bit feedback. Why is this
-+ useful you ask? Because this routine will allow you to encrypt an
-+ arbitrary number of bytes, no 8 byte padding. Each call to this
-+ routine will encrypt the input bytes to output and then update ivec
-+ and num. num contains 'how far' we are though ivec. If this does
-+ not make much sense, read more about cfb mode of DES :-).
-+
-+void des_ede3_cfb64_encrypt(
-+unsigned char *in,
-+unsigned char *out,
-+long length,
-+des_key_schedule ks1,
-+des_key_schedule ks2,
-+des_key_schedule ks3,
-+des_cblock *ivec,
-+int *num,
-+int enc);
-+ Same as des_cfb64_encrypt() accept that the DES operation is
-+ triple DES. As usual, there is a macro for
-+ des_ede2_cfb64_encrypt() which reuses ks1.
-+
-+void des_ofb_encrypt(
-+unsigned char *in,
-+unsigned char *out,
-+int numbits,
-+long length,
-+des_key_schedule ks,
-+des_cblock *ivec);
-+ This is a implementation of Output Feed Back mode of DES. It is
-+ the same as des_cfb_encrypt() in that numbits is the size of the
-+ units dealt with during input and output (in bits).
-+
-+void des_ofb64_encrypt(
-+unsigned char *in,
-+unsigned char *out,
-+long length,
-+des_key_schedule ks,
-+des_cblock *ivec,
-+int *num);
-+ The same as des_cfb64_encrypt() except that it is Output Feed Back
-+ mode.
-+
-+void des_ede3_ofb64_encrypt(
-+unsigned char *in,
-+unsigned char *out,
-+long length,
-+des_key_schedule ks1,
-+des_key_schedule ks2,
-+des_key_schedule ks3,
-+des_cblock *ivec,
-+int *num);
-+ Same as des_ofb64_encrypt() accept that the DES operation is
-+ triple DES. As usual, there is a macro for
-+ des_ede2_ofb64_encrypt() which reuses ks1.
-+
-+int des_read_pw_string(
-+char *buf,
-+int length,
-+char *prompt,
-+int verify);
-+ This routine is used to get a password from the terminal with echo
-+ turned off. Buf is where the string will end up and length is the
-+ size of buf. Prompt is a string presented to the 'user' and if
-+ verify is set, the key is asked for twice and unless the 2 copies
-+ match, an error is returned. A return code of -1 indicates a
-+ system error, 1 failure due to use interaction, and 0 is success.
-+
-+unsigned long des_cbc_cksum(
-+des_cblock *input,
-+des_cblock *output,
-+long length,
-+des_key_schedule ks,
-+des_cblock *ivec);
-+ This function produces an 8 byte checksum from input that it puts in
-+ output and returns the last 4 bytes as a long. The checksum is
-+ generated via cbc mode of DES in which only the last 8 byes are
-+ kept. I would recommend not using this function but instead using
-+ the EVP_Digest routines, or at least using MD5 or SHA. This
-+ function is used by Kerberos v4 so that is why it stays in the
-+ library.
-+
-+char *des_fcrypt(
-+const char *buf,
-+const char *salt
-+char *ret);
-+ This is my fast version of the unix crypt(3) function. This version
-+ takes only a small amount of space relative to other fast
-+ crypt() implementations. This is different to the normal crypt
-+ in that the third parameter is the buffer that the return value
-+ is written into. It needs to be at least 14 bytes long. This
-+ function is thread safe, unlike the normal crypt.
-+
-+char *crypt(
-+const char *buf,
-+const char *salt);
-+ This function calls des_fcrypt() with a static array passed as the
-+ third parameter. This emulates the normal non-thread safe semantics
-+ of crypt(3).
-+
-+void des_string_to_key(
-+char *str,
-+des_cblock *key);
-+ This function takes str and converts it into a DES key. I would
-+ recommend using MD5 instead and use the first 8 bytes of output.
-+ When I wrote the first version of these routines back in 1990, MD5
-+ did not exist but I feel these routines are still sound. This
-+ routines is compatible with the one in MIT's libdes.
-+
-+void des_string_to_2keys(
-+char *str,
-+des_cblock *key1,
-+des_cblock *key2);
-+ This function takes str and converts it into 2 DES keys.
-+ I would recommend using MD5 and using the 16 bytes as the 2 keys.
-+ I have nothing against these 2 'string_to_key' routines, it's just
-+ that if you say that your encryption key is generated by using the
-+ 16 bytes of an MD5 hash, every-one knows how you generated your
-+ keys.
-+
-+int des_read_password(
-+des_cblock *key,
-+char *prompt,
-+int verify);
-+ This routine combines des_read_pw_string() with des_string_to_key().
-+
-+int des_read_2passwords(
-+des_cblock *key1,
-+des_cblock *key2,
-+char *prompt,
-+int verify);
-+ This routine combines des_read_pw_string() with des_string_to_2key().
-+
-+void des_random_seed(
-+des_cblock key);
-+ This routine sets a starting point for des_random_key().
-+
-+void des_random_key(
-+des_cblock ret);
-+ This function return a random key. Make sure to 'seed' the random
-+ number generator (with des_random_seed()) before using this function.
-+ I personally now use a MD5 based random number system.
-+
-+int des_enc_read(
-+int fd,
-+char *buf,
-+int len,
-+des_key_schedule ks,
-+des_cblock *iv);
-+ This function will write to a file descriptor the encrypted data
-+ from buf. This data will be preceded by a 4 byte 'byte count' and
-+ will be padded out to 8 bytes. The encryption is either CBC of
-+ PCBC depending on the value of des_rw_mode. If it is DES_PCBC_MODE,
-+ pcbc is used, if DES_CBC_MODE, cbc is used. The default is to use
-+ DES_PCBC_MODE.
-+
-+int des_enc_write(
-+int fd,
-+char *buf,
-+int len,
-+des_key_schedule ks,
-+des_cblock *iv);
-+ This routines read stuff written by des_enc_read() and decrypts it.
-+ I have used these routines quite a lot but I don't believe they are
-+ suitable for non-blocking io. If you are after a full
-+ authentication/encryption over networks, have a look at SSL instead.
-+
-+unsigned long des_quad_cksum(
-+des_cblock *input,
-+des_cblock *output,
-+long length,
-+int out_count,
-+des_cblock *seed);
-+ This is a function from Kerberos v4 that is not anything to do with
-+ DES but was needed. It is a cksum that is quicker to generate than
-+ des_cbc_cksum(); I personally would use MD5 routines now.
-+=====
-+Modes of DES
-+Quite a bit of the following information has been taken from
-+ AS 2805.5.2
-+ Australian Standard
-+ Electronic funds transfer - Requirements for interfaces,
-+ Part 5.2: Modes of operation for an n-bit block cipher algorithm
-+ Appendix A
-+
-+There are several different modes in which DES can be used, they are
-+as follows.
-+
-+Electronic Codebook Mode (ECB) (des_ecb_encrypt())
-+- 64 bits are enciphered at a time.
-+- The order of the blocks can be rearranged without detection.
-+- The same plaintext block always produces the same ciphertext block
-+ (for the same key) making it vulnerable to a 'dictionary attack'.
-+- An error will only affect one ciphertext block.
-+
-+Cipher Block Chaining Mode (CBC) (des_cbc_encrypt())
-+- a multiple of 64 bits are enciphered at a time.
-+- The CBC mode produces the same ciphertext whenever the same
-+ plaintext is encrypted using the same key and starting variable.
-+- The chaining operation makes the ciphertext blocks dependent on the
-+ current and all preceding plaintext blocks and therefore blocks can not
-+ be rearranged.
-+- The use of different starting variables prevents the same plaintext
-+ enciphering to the same ciphertext.
-+- An error will affect the current and the following ciphertext blocks.
-+
-+Cipher Feedback Mode (CFB) (des_cfb_encrypt())
-+- a number of bits (j) <= 64 are enciphered at a time.
-+- The CFB mode produces the same ciphertext whenever the same
-+ plaintext is encrypted using the same key and starting variable.
-+- The chaining operation makes the ciphertext variables dependent on the
-+ current and all preceding variables and therefore j-bit variables are
-+ chained together and can not be rearranged.
-+- The use of different starting variables prevents the same plaintext
-+ enciphering to the same ciphertext.
-+- The strength of the CFB mode depends on the size of k (maximal if
-+ j == k). In my implementation this is always the case.
-+- Selection of a small value for j will require more cycles through
-+ the encipherment algorithm per unit of plaintext and thus cause
-+ greater processing overheads.
-+- Only multiples of j bits can be enciphered.
-+- An error will affect the current and the following ciphertext variables.
-+
-+Output Feedback Mode (OFB) (des_ofb_encrypt())
-+- a number of bits (j) <= 64 are enciphered at a time.
-+- The OFB mode produces the same ciphertext whenever the same
-+ plaintext enciphered using the same key and starting variable. More
-+ over, in the OFB mode the same key stream is produced when the same
-+ key and start variable are used. Consequently, for security reasons
-+ a specific start variable should be used only once for a given key.
-+- The absence of chaining makes the OFB more vulnerable to specific attacks.
-+- The use of different start variables values prevents the same
-+ plaintext enciphering to the same ciphertext, by producing different
-+ key streams.
-+- Selection of a small value for j will require more cycles through
-+ the encipherment algorithm per unit of plaintext and thus cause
-+ greater processing overheads.
-+- Only multiples of j bits can be enciphered.
-+- OFB mode of operation does not extend ciphertext errors in the
-+ resultant plaintext output. Every bit error in the ciphertext causes
-+ only one bit to be in error in the deciphered plaintext.
-+- OFB mode is not self-synchronising. If the two operation of
-+ encipherment and decipherment get out of synchronism, the system needs
-+ to be re-initialised.
-+- Each re-initialisation should use a value of the start variable
-+ different from the start variable values used before with the same
-+ key. The reason for this is that an identical bit stream would be
-+ produced each time from the same parameters. This would be
-+ susceptible to a ' known plaintext' attack.
-+
-+Triple ECB Mode (des_ecb3_encrypt())
-+- Encrypt with key1, decrypt with key2 and encrypt with key3 again.
-+- As for ECB encryption but increases the key length to 168 bits.
-+ There are theoretic attacks that can be used that make the effective
-+ key length 112 bits, but this attack also requires 2^56 blocks of
-+ memory, not very likely, even for the NSA.
-+- If both keys are the same it is equivalent to encrypting once with
-+ just one key.
-+- If the first and last key are the same, the key length is 112 bits.
-+ There are attacks that could reduce the key space to 55 bit's but it
-+ requires 2^56 blocks of memory.
-+- If all 3 keys are the same, this is effectively the same as normal
-+ ecb mode.
-+
-+Triple CBC Mode (des_ede3_cbc_encrypt())
-+- Encrypt with key1, decrypt with key2 and then encrypt with key3.
-+- As for CBC encryption but increases the key length to 168 bits with
-+ the same restrictions as for triple ecb mode.
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/des_crypt.man Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,508 @@
-+.TH DES_CRYPT 3
-+.SH NAME
-+des_read_password, des_read_2password,
-+des_string_to_key, des_string_to_2key, des_read_pw_string,
-+des_random_key, des_set_key,
-+des_key_sched, des_ecb_encrypt, des_ecb3_encrypt, des_cbc_encrypt,
-+des_3cbc_encrypt,
-+des_pcbc_encrypt, des_cfb_encrypt, des_ofb_encrypt,
-+des_cbc_cksum, des_quad_cksum,
-+des_enc_read, des_enc_write, des_set_odd_parity,
-+des_is_weak_key, crypt \- (non USA) DES encryption
-+.SH SYNOPSIS
-+.nf
-+.nj
-+.ft B
-+#include <des.h>
-+.PP
-+.B int des_read_password(key,prompt,verify)
-+des_cblock *key;
-+char *prompt;
-+int verify;
-+.PP
-+.B int des_read_2password(key1,key2,prompt,verify)
-+des_cblock *key1,*key2;
-+char *prompt;
-+int verify;
-+.PP
-+.B int des_string_to_key(str,key)
-+char *str;
-+des_cblock *key;
-+.PP
-+.B int des_string_to_2keys(str,key1,key2)
-+char *str;
-+des_cblock *key1,*key2;
-+.PP
-+.B int des_read_pw_string(buf,length,prompt,verify)
-+char *buf;
-+int length;
-+char *prompt;
-+int verify;
-+.PP
-+.B int des_random_key(key)
-+des_cblock *key;
-+.PP
-+.B int des_set_key(key,schedule)
-+des_cblock *key;
-+des_key_schedule schedule;
-+.PP
-+.B int des_key_sched(key,schedule)
-+des_cblock *key;
-+des_key_schedule schedule;
-+.PP
-+.B int des_ecb_encrypt(input,output,schedule,encrypt)
-+des_cblock *input;
-+des_cblock *output;
-+des_key_schedule schedule;
-+int encrypt;
-+.PP
-+.B int des_ecb3_encrypt(input,output,ks1,ks2,encrypt)
-+des_cblock *input;
-+des_cblock *output;
-+des_key_schedule ks1,ks2;
-+int encrypt;
-+.PP
-+.B int des_cbc_encrypt(input,output,length,schedule,ivec,encrypt)
-+des_cblock *input;
-+des_cblock *output;
-+long length;
-+des_key_schedule schedule;
-+des_cblock *ivec;
-+int encrypt;
-+.PP
-+.B int des_3cbc_encrypt(input,output,length,sk1,sk2,ivec1,ivec2,encrypt)
-+des_cblock *input;
-+des_cblock *output;
-+long length;
-+des_key_schedule sk1;
-+des_key_schedule sk2;
-+des_cblock *ivec1;
-+des_cblock *ivec2;
-+int encrypt;
-+.PP
-+.B int des_pcbc_encrypt(input,output,length,schedule,ivec,encrypt)
-+des_cblock *input;
-+des_cblock *output;
-+long length;
-+des_key_schedule schedule;
-+des_cblock *ivec;
-+int encrypt;
-+.PP
-+.B int des_cfb_encrypt(input,output,numbits,length,schedule,ivec,encrypt)
-+unsigned char *input;
-+unsigned char *output;
-+int numbits;
-+long length;
-+des_key_schedule schedule;
-+des_cblock *ivec;
-+int encrypt;
-+.PP
-+.B int des_ofb_encrypt(input,output,numbits,length,schedule,ivec)
-+unsigned char *input,*output;
-+int numbits;
-+long length;
-+des_key_schedule schedule;
-+des_cblock *ivec;
-+.PP
-+.B unsigned long des_cbc_cksum(input,output,length,schedule,ivec)
-+des_cblock *input;
-+des_cblock *output;
-+long length;
-+des_key_schedule schedule;
-+des_cblock *ivec;
-+.PP
-+.B unsigned long des_quad_cksum(input,output,length,out_count,seed)
-+des_cblock *input;
-+des_cblock *output;
-+long length;
-+int out_count;
-+des_cblock *seed;
-+.PP
-+.B int des_check_key;
-+.PP
-+.B int des_enc_read(fd,buf,len,sched,iv)
-+int fd;
-+char *buf;
-+int len;
-+des_key_schedule sched;
-+des_cblock *iv;
-+.PP
-+.B int des_enc_write(fd,buf,len,sched,iv)
-+int fd;
-+char *buf;
-+int len;
-+des_key_schedule sched;
-+des_cblock *iv;
-+.PP
-+.B extern int des_rw_mode;
-+.PP
-+.B void des_set_odd_parity(key)
-+des_cblock *key;
-+.PP
-+.B int des_is_weak_key(key)
-+des_cblock *key;
-+.PP
-+.B char *crypt(passwd,salt)
-+char *passwd;
-+char *salt;
-+.PP
-+.fi
-+.SH DESCRIPTION
-+This library contains a fast implementation of the DES encryption
-+algorithm.
-+.PP
-+There are two phases to the use of DES encryption.
-+The first is the generation of a
-+.I des_key_schedule
-+from a key,
-+the second is the actual encryption.
-+A des key is of type
-+.I des_cblock.
-+This type is made from 8 characters with odd parity.
-+The least significant bit in the character is the parity bit.
-+The key schedule is an expanded form of the key; it is used to speed the
-+encryption process.
-+.PP
-+.I des_read_password
-+writes the string specified by prompt to the standard output,
-+turns off echo and reads an input string from standard input
-+until terminated with a newline.
-+If verify is non-zero, it prompts and reads the input again and verifies
-+that both entered passwords are the same.
-+The entered string is converted into a des key by using the
-+.I des_string_to_key
-+routine.
-+The new key is placed in the
-+.I des_cblock
-+that was passed (by reference) to the routine.
-+If there were no errors,
-+.I des_read_password
-+returns 0,
-+-1 is returned if there was a terminal error and 1 is returned for
-+any other error.
-+.PP
-+.I des_read_2password
-+operates in the same way as
-+.I des_read_password
-+except that it generates 2 keys by using the
-+.I des_string_to_2key
-+function.
-+.PP
-+.I des_read_pw_string
-+is called by
-+.I des_read_password
-+to read and verify a string from a terminal device.
-+The string is returned in
-+.I buf.
-+The size of
-+.I buf
-+is passed to the routine via the
-+.I length
-+parameter.
-+.PP
-+.I des_string_to_key
-+converts a string into a valid des key.
-+.PP
-+.I des_string_to_2key
-+converts a string into 2 valid des keys.
-+This routine is best suited for used to generate keys for use with
-+.I des_ecb3_encrypt.
-+.PP
-+.I des_random_key
-+returns a random key that is made of a combination of process id,
-+time and an increasing counter.
-+.PP
-+Before a des key can be used it is converted into a
-+.I des_key_schedule
-+via the
-+.I des_set_key
-+routine.
-+If the
-+.I des_check_key
-+flag is non-zero,
-+.I des_set_key
-+will check that the key passed is of odd parity and is not a week or
-+semi-weak key.
-+If the parity is wrong,
-+then -1 is returned.
-+If the key is a weak key,
-+then -2 is returned.
-+If an error is returned,
-+the key schedule is not generated.
-+.PP
-+.I des_key_sched
-+is another name for the
-+.I des_set_key
-+function.
-+.PP
-+The following routines mostly operate on an input and output stream of
-+.I des_cblock's.
-+.PP
-+.I des_ecb_encrypt
-+is the basic DES encryption routine that encrypts or decrypts a single 8-byte
-+.I des_cblock
-+in
-+.I electronic code book
-+mode.
-+It always transforms the input data, pointed to by
-+.I input,
-+into the output data,
-+pointed to by the
-+.I output
-+argument.
-+If the
-+.I encrypt
-+argument is non-zero (DES_ENCRYPT),
-+the
-+.I input
-+(cleartext) is encrypted in to the
-+.I output
-+(ciphertext) using the key_schedule specified by the
-+.I schedule
-+argument,
-+previously set via
-+.I des_set_key.
-+If
-+.I encrypt
-+is zero (DES_DECRYPT),
-+the
-+.I input
-+(now ciphertext)
-+is decrypted into the
-+.I output
-+(now cleartext).
-+Input and output may overlap.
-+No meaningful value is returned.
-+.PP
-+.I des_ecb3_encrypt
-+encrypts/decrypts the
-+.I input
-+block by using triple ecb DES encryption.
-+This involves encrypting the input with
-+.I ks1,
-+decryption with the key schedule
-+.I ks2,
-+and then encryption with the first again.
-+This routine greatly reduces the chances of brute force breaking of
-+DES and has the advantage of if
-+.I ks1
-+and
-+.I ks2
-+are the same, it is equivalent to just encryption using ecb mode and
-+.I ks1
-+as the key.
-+.PP
-+.I des_cbc_encrypt
-+encrypts/decrypts using the
-+.I cipher-block-chaining
-+mode of DES.
-+If the
-+.I encrypt
-+argument is non-zero,
-+the routine cipher-block-chain encrypts the cleartext data pointed to by the
-+.I input
-+argument into the ciphertext pointed to by the
-+.I output
-+argument,
-+using the key schedule provided by the
-+.I schedule
-+argument,
-+and initialisation vector provided by the
-+.I ivec
-+argument.
-+If the
-+.I length
-+argument is not an integral multiple of eight bytes,
-+the last block is copied to a temporary area and zero filled.
-+The output is always
-+an integral multiple of eight bytes.
-+To make multiple cbc encrypt calls on a large amount of data appear to
-+be one
-+.I des_cbc_encrypt
-+call, the
-+.I ivec
-+of subsequent calls should be the last 8 bytes of the output.
-+.PP
-+.I des_3cbc_encrypt
-+encrypts/decrypts the
-+.I input
-+block by using triple cbc DES encryption.
-+This involves encrypting the input with key schedule
-+.I ks1,
-+decryption with the key schedule
-+.I ks2,
-+and then encryption with the first again.
-+2 initialisation vectors are required,
-+.I ivec1
-+and
-+.I ivec2.
-+Unlike
-+.I des_cbc_encrypt,
-+these initialisation vectors are modified by the subroutine.
-+This routine greatly reduces the chances of brute force breaking of
-+DES and has the advantage of if
-+.I ks1
-+and
-+.I ks2
-+are the same, it is equivalent to just encryption using cbc mode and
-+.I ks1
-+as the key.
-+.PP
-+.I des_pcbc_encrypt
-+encrypt/decrypts using a modified block chaining mode.
-+It provides better error propagation characteristics than cbc
-+encryption.
-+.PP
-+.I des_cfb_encrypt
-+encrypt/decrypts using cipher feedback mode. This method takes an
-+array of characters as input and outputs and array of characters. It
-+does not require any padding to 8 character groups. Note: the ivec
-+variable is changed and the new changed value needs to be passed to
-+the next call to this function. Since this function runs a complete
-+DES ecb encryption per numbits, this function is only suggested for
-+use when sending small numbers of characters.
-+.PP
-+.I des_ofb_encrypt
-+encrypt using output feedback mode. This method takes an
-+array of characters as input and outputs and array of characters. It
-+does not require any padding to 8 character groups. Note: the ivec
-+variable is changed and the new changed value needs to be passed to
-+the next call to this function. Since this function runs a complete
-+DES ecb encryption per numbits, this function is only suggested for
-+use when sending small numbers of characters.
-+.PP
-+.I des_cbc_cksum
-+produces an 8 byte checksum based on the input stream (via cbc encryption).
-+The last 4 bytes of the checksum is returned and the complete 8 bytes is
-+placed in
-+.I output.
-+.PP
-+.I des_quad_cksum
-+returns a 4 byte checksum from the input bytes.
-+The algorithm can be iterated over the input,
-+depending on
-+.I out_count,
-+1, 2, 3 or 4 times.
-+If
-+.I output
-+is non-NULL,
-+the 8 bytes generated by each pass are written into
-+.I output.
-+.PP
-+.I des_enc_write
-+is used to write
-+.I len
-+bytes
-+to file descriptor
-+.I fd
-+from buffer
-+.I buf.
-+The data is encrypted via
-+.I pcbc_encrypt
-+(default) using
-+.I sched
-+for the key and
-+.I iv
-+as a starting vector.
-+The actual data send down
-+.I fd
-+consists of 4 bytes (in network byte order) containing the length of the
-+following encrypted data. The encrypted data then follows, padded with random
-+data out to a multiple of 8 bytes.
-+.PP
-+.I des_enc_read
-+is used to read
-+.I len
-+bytes
-+from file descriptor
-+.I fd
-+into buffer
-+.I buf.
-+The data being read from
-+.I fd
-+is assumed to have come from
-+.I des_enc_write
-+and is decrypted using
-+.I sched
-+for the key schedule and
-+.I iv
-+for the initial vector.
-+The
-+.I des_enc_read/des_enc_write
-+pair can be used to read/write to files, pipes and sockets.
-+I have used them in implementing a version of rlogin in which all
-+data is encrypted.
-+.PP
-+.I des_rw_mode
-+is used to specify the encryption mode to use with
-+.I des_enc_read
-+and
-+.I des_end_write.
-+If set to
-+.I DES_PCBC_MODE
-+(the default), des_pcbc_encrypt is used.
-+If set to
-+.I DES_CBC_MODE
-+des_cbc_encrypt is used.
-+These two routines and the variable are not part of the normal MIT library.
-+.PP
-+.I des_set_odd_parity
-+sets the parity of the passed
-+.I key
-+to odd. This routine is not part of the standard MIT library.
-+.PP
-+.I des_is_weak_key
-+returns 1 is the passed key is a weak key (pick again :-),
-+0 if it is ok.
-+This routine is not part of the standard MIT library.
-+.PP
-+.I crypt
-+is a replacement for the normal system crypt.
-+It is much faster than the system crypt.
-+.PP
-+.SH FILES
-+/usr/include/des.h
-+.br
-+/usr/lib/libdes.a
-+.PP
-+The encryption routines have been tested on 16bit, 32bit and 64bit
-+machines of various endian and even works under VMS.
-+.PP
-+.SH BUGS
-+.PP
-+If you think this manual is sparse,
-+read the des_crypt(3) manual from the MIT kerberos (or bones outside
-+of the USA) distribution.
-+.PP
-+.I des_cfb_encrypt
-+and
-+.I des_ofb_encrypt
-+operates on input of 8 bits. What this means is that if you set
-+numbits to 12, and length to 2, the first 12 bits will come from the 1st
-+input byte and the low half of the second input byte. The second 12
-+bits will have the low 8 bits taken from the 3rd input byte and the
-+top 4 bits taken from the 4th input byte. The same holds for output.
-+This function has been implemented this way because most people will
-+be using a multiple of 8 and because once you get into pulling bytes input
-+bytes apart things get ugly!
-+.PP
-+.I des_read_pw_string
-+is the most machine/OS dependent function and normally generates the
-+most problems when porting this code.
-+.PP
-+.I des_string_to_key
-+is probably different from the MIT version since there are lots
-+of fun ways to implement one-way encryption of a text string.
-+.PP
-+The routines are optimised for 32 bit machines and so are not efficient
-+on IBM PCs.
-+.PP
-+NOTE: extensive work has been done on this library since this document
-+was origionally written. Please try to read des.doc from the libdes
-+distribution since it is far more upto date and documents more of the
-+functions. Libdes is now also being shipped as part of SSLeay, a
-+general cryptographic library that amonst other things implements
-+netscapes SSL protocoll. The most recent version can be found in
-+SSLeay distributions.
-+.SH AUTHOR
-+Eric Young (eay@cryptsoft.com)
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/des_enc.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,502 @@
-+/* crypto/des/des_enc.c */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+#include "des_locl.h"
-+
-+void des_encrypt(data, ks, enc)
-+DES_LONG *data;
-+des_key_schedule ks;
-+int enc;
-+ {
-+ register DES_LONG l,r,t,u;
-+#ifdef DES_PTR
-+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
-+#endif
-+#ifndef DES_UNROLL
-+ register int i;
-+#endif
-+ register DES_LONG *s;
-+
-+ r=data[0];
-+ l=data[1];
-+
-+ IP(r,l);
-+ /* Things have been modified so that the initial rotate is
-+ * done outside the loop. This required the
-+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
-+ * One perl script later and things have a 5% speed up on a sparc2.
-+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
-+ * for pointing this out. */
-+ /* clear the top bits on machines with 8byte longs */
-+ /* shift left by 2 */
-+ r=ROTATE(r,29)&0xffffffffL;
-+ l=ROTATE(l,29)&0xffffffffL;
-+
-+ s=(DES_LONG *)ks;
-+ /* I don't know if it is worth the effort of loop unrolling the
-+ * inner loop */
-+ if (enc)
-+ {
-+#ifdef DES_UNROLL
-+ D_ENCRYPT(l,r, 0); /* 1 */
-+ D_ENCRYPT(r,l, 2); /* 2 */
-+ D_ENCRYPT(l,r, 4); /* 3 */
-+ D_ENCRYPT(r,l, 6); /* 4 */
-+ D_ENCRYPT(l,r, 8); /* 5 */
-+ D_ENCRYPT(r,l,10); /* 6 */
-+ D_ENCRYPT(l,r,12); /* 7 */
-+ D_ENCRYPT(r,l,14); /* 8 */
-+ D_ENCRYPT(l,r,16); /* 9 */
-+ D_ENCRYPT(r,l,18); /* 10 */
-+ D_ENCRYPT(l,r,20); /* 11 */
-+ D_ENCRYPT(r,l,22); /* 12 */
-+ D_ENCRYPT(l,r,24); /* 13 */
-+ D_ENCRYPT(r,l,26); /* 14 */
-+ D_ENCRYPT(l,r,28); /* 15 */
-+ D_ENCRYPT(r,l,30); /* 16 */
-+#else
-+ for (i=0; i<32; i+=8)
-+ {
-+ D_ENCRYPT(l,r,i+0); /* 1 */
-+ D_ENCRYPT(r,l,i+2); /* 2 */
-+ D_ENCRYPT(l,r,i+4); /* 3 */
-+ D_ENCRYPT(r,l,i+6); /* 4 */
-+ }
-+#endif
-+ }
-+ else
-+ {
-+#ifdef DES_UNROLL
-+ D_ENCRYPT(l,r,30); /* 16 */
-+ D_ENCRYPT(r,l,28); /* 15 */
-+ D_ENCRYPT(l,r,26); /* 14 */
-+ D_ENCRYPT(r,l,24); /* 13 */
-+ D_ENCRYPT(l,r,22); /* 12 */
-+ D_ENCRYPT(r,l,20); /* 11 */
-+ D_ENCRYPT(l,r,18); /* 10 */
-+ D_ENCRYPT(r,l,16); /* 9 */
-+ D_ENCRYPT(l,r,14); /* 8 */
-+ D_ENCRYPT(r,l,12); /* 7 */
-+ D_ENCRYPT(l,r,10); /* 6 */
-+ D_ENCRYPT(r,l, 8); /* 5 */
-+ D_ENCRYPT(l,r, 6); /* 4 */
-+ D_ENCRYPT(r,l, 4); /* 3 */
-+ D_ENCRYPT(l,r, 2); /* 2 */
-+ D_ENCRYPT(r,l, 0); /* 1 */
-+#else
-+ for (i=30; i>0; i-=8)
-+ {
-+ D_ENCRYPT(l,r,i-0); /* 16 */
-+ D_ENCRYPT(r,l,i-2); /* 15 */
-+ D_ENCRYPT(l,r,i-4); /* 14 */
-+ D_ENCRYPT(r,l,i-6); /* 13 */
-+ }
-+#endif
-+ }
-+
-+ /* rotate and clear the top bits on machines with 8byte longs */
-+ l=ROTATE(l,3)&0xffffffffL;
-+ r=ROTATE(r,3)&0xffffffffL;
-+
-+ FP(r,l);
-+ data[0]=l;
-+ data[1]=r;
-+ l=r=t=u=0;
-+ }
-+
-+void des_encrypt2(data, ks, enc)
-+DES_LONG *data;
-+des_key_schedule ks;
-+int enc;
-+ {
-+ register DES_LONG l,r,t,u;
-+#ifdef DES_PTR
-+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
-+#endif
-+#ifndef DES_UNROLL
-+ register int i;
-+#endif
-+ register DES_LONG *s;
-+
-+ r=data[0];
-+ l=data[1];
-+
-+ /* Things have been modified so that the initial rotate is
-+ * done outside the loop. This required the
-+ * des_SPtrans values in sp.h to be rotated 1 bit to the right.
-+ * One perl script later and things have a 5% speed up on a sparc2.
-+ * Thanks to Richard Outerbridge <71755.204@CompuServe.COM>
-+ * for pointing this out. */
-+ /* clear the top bits on machines with 8byte longs */
-+ r=ROTATE(r,29)&0xffffffffL;
-+ l=ROTATE(l,29)&0xffffffffL;
-+
-+ s=(DES_LONG *)ks;
-+ /* I don't know if it is worth the effort of loop unrolling the
-+ * inner loop */
-+ if (enc)
-+ {
-+#ifdef DES_UNROLL
-+ D_ENCRYPT(l,r, 0); /* 1 */
-+ D_ENCRYPT(r,l, 2); /* 2 */
-+ D_ENCRYPT(l,r, 4); /* 3 */
-+ D_ENCRYPT(r,l, 6); /* 4 */
-+ D_ENCRYPT(l,r, 8); /* 5 */
-+ D_ENCRYPT(r,l,10); /* 6 */
-+ D_ENCRYPT(l,r,12); /* 7 */
-+ D_ENCRYPT(r,l,14); /* 8 */
-+ D_ENCRYPT(l,r,16); /* 9 */
-+ D_ENCRYPT(r,l,18); /* 10 */
-+ D_ENCRYPT(l,r,20); /* 11 */
-+ D_ENCRYPT(r,l,22); /* 12 */
-+ D_ENCRYPT(l,r,24); /* 13 */
-+ D_ENCRYPT(r,l,26); /* 14 */
-+ D_ENCRYPT(l,r,28); /* 15 */
-+ D_ENCRYPT(r,l,30); /* 16 */
-+#else
-+ for (i=0; i<32; i+=8)
-+ {
-+ D_ENCRYPT(l,r,i+0); /* 1 */
-+ D_ENCRYPT(r,l,i+2); /* 2 */
-+ D_ENCRYPT(l,r,i+4); /* 3 */
-+ D_ENCRYPT(r,l,i+6); /* 4 */
-+ }
-+#endif
-+ }
-+ else
-+ {
-+#ifdef DES_UNROLL
-+ D_ENCRYPT(l,r,30); /* 16 */
-+ D_ENCRYPT(r,l,28); /* 15 */
-+ D_ENCRYPT(l,r,26); /* 14 */
-+ D_ENCRYPT(r,l,24); /* 13 */
-+ D_ENCRYPT(l,r,22); /* 12 */
-+ D_ENCRYPT(r,l,20); /* 11 */
-+ D_ENCRYPT(l,r,18); /* 10 */
-+ D_ENCRYPT(r,l,16); /* 9 */
-+ D_ENCRYPT(l,r,14); /* 8 */
-+ D_ENCRYPT(r,l,12); /* 7 */
-+ D_ENCRYPT(l,r,10); /* 6 */
-+ D_ENCRYPT(r,l, 8); /* 5 */
-+ D_ENCRYPT(l,r, 6); /* 4 */
-+ D_ENCRYPT(r,l, 4); /* 3 */
-+ D_ENCRYPT(l,r, 2); /* 2 */
-+ D_ENCRYPT(r,l, 0); /* 1 */
-+#else
-+ for (i=30; i>0; i-=8)
-+ {
-+ D_ENCRYPT(l,r,i-0); /* 16 */
-+ D_ENCRYPT(r,l,i-2); /* 15 */
-+ D_ENCRYPT(l,r,i-4); /* 14 */
-+ D_ENCRYPT(r,l,i-6); /* 13 */
-+ }
-+#endif
-+ }
-+ /* rotate and clear the top bits on machines with 8byte longs */
-+ data[0]=ROTATE(l,3)&0xffffffffL;
-+ data[1]=ROTATE(r,3)&0xffffffffL;
-+ l=r=t=u=0;
-+ }
-+
-+void des_encrypt3(data,ks1,ks2,ks3)
-+DES_LONG *data;
-+des_key_schedule ks1;
-+des_key_schedule ks2;
-+des_key_schedule ks3;
-+ {
-+ register DES_LONG l,r;
-+
-+ l=data[0];
-+ r=data[1];
-+ IP(l,r);
-+ data[0]=l;
-+ data[1]=r;
-+ des_encrypt2((DES_LONG *)data,ks1,DES_ENCRYPT);
-+ des_encrypt2((DES_LONG *)data,ks2,DES_DECRYPT);
-+ des_encrypt2((DES_LONG *)data,ks3,DES_ENCRYPT);
-+ l=data[0];
-+ r=data[1];
-+ FP(r,l);
-+ data[0]=l;
-+ data[1]=r;
-+ }
-+
-+void des_decrypt3(data,ks1,ks2,ks3)
-+DES_LONG *data;
-+des_key_schedule ks1;
-+des_key_schedule ks2;
-+des_key_schedule ks3;
-+ {
-+ register DES_LONG l,r;
-+
-+ l=data[0];
-+ r=data[1];
-+ IP(l,r);
-+ data[0]=l;
-+ data[1]=r;
-+ des_encrypt2((DES_LONG *)data,ks3,DES_DECRYPT);
-+ des_encrypt2((DES_LONG *)data,ks2,DES_ENCRYPT);
-+ des_encrypt2((DES_LONG *)data,ks1,DES_DECRYPT);
-+ l=data[0];
-+ r=data[1];
-+ FP(r,l);
-+ data[0]=l;
-+ data[1]=r;
-+ }
-+
-+#ifndef DES_DEFAULT_OPTIONS
-+
-+void des_ncbc_encrypt(input, output, length, schedule, ivec, enc)
-+des_cblock (*input);
-+des_cblock (*output);
-+long length;
-+des_key_schedule schedule;
-+des_cblock (*ivec);
-+int enc;
-+ {
-+ register DES_LONG tin0,tin1;
-+ register DES_LONG tout0,tout1,xor0,xor1;
-+ register unsigned char *in,*out;
-+ register long l=length;
-+ DES_LONG tin[2];
-+ unsigned char *iv;
-+
-+ in=(unsigned char *)input;
-+ out=(unsigned char *)output;
-+ iv=(unsigned char *)ivec;
-+
-+ if (enc)
-+ {
-+ c2l(iv,tout0);
-+ c2l(iv,tout1);
-+ for (l-=8; l>=0; l-=8)
-+ {
-+ c2l(in,tin0);
-+ c2l(in,tin1);
-+ tin0^=tout0; tin[0]=tin0;
-+ tin1^=tout1; tin[1]=tin1;
-+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
-+ tout0=tin[0]; l2c(tout0,out);
-+ tout1=tin[1]; l2c(tout1,out);
-+ }
-+ if (l != -8)
-+ {
-+ c2ln(in,tin0,tin1,l+8);
-+ tin0^=tout0; tin[0]=tin0;
-+ tin1^=tout1; tin[1]=tin1;
-+ des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
-+ tout0=tin[0]; l2c(tout0,out);
-+ tout1=tin[1]; l2c(tout1,out);
-+ }
-+ iv=(unsigned char *)ivec;
-+ l2c(tout0,iv);
-+ l2c(tout1,iv);
-+ }
-+ else
-+ {
-+ c2l(iv,xor0);
-+ c2l(iv,xor1);
-+ for (l-=8; l>=0; l-=8)
-+ {
-+ c2l(in,tin0); tin[0]=tin0;
-+ c2l(in,tin1); tin[1]=tin1;
-+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
-+ tout0=tin[0]^xor0;
-+ tout1=tin[1]^xor1;
-+ l2c(tout0,out);
-+ l2c(tout1,out);
-+ xor0=tin0;
-+ xor1=tin1;
-+ }
-+ if (l != -8)
-+ {
-+ c2l(in,tin0); tin[0]=tin0;
-+ c2l(in,tin1); tin[1]=tin1;
-+ des_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
-+ tout0=tin[0]^xor0;
-+ tout1=tin[1]^xor1;
-+ l2cn(tout0,tout1,out,l+8);
-+ xor0=tin0;
-+ xor1=tin1;
-+ }
-+
-+ iv=(unsigned char *)ivec;
-+ l2c(xor0,iv);
-+ l2c(xor1,iv);
-+ }
-+ tin0=tin1=tout0=tout1=xor0=xor1=0;
-+ tin[0]=tin[1]=0;
-+ }
-+
-+void des_ede3_cbc_encrypt(input, output, length, ks1, ks2, ks3, ivec, enc)
-+des_cblock (*input);
-+des_cblock (*output);
-+long length;
-+des_key_schedule ks1;
-+des_key_schedule ks2;
-+des_key_schedule ks3;
-+des_cblock (*ivec);
-+int enc;
-+ {
-+ register DES_LONG tin0,tin1;
-+ register DES_LONG tout0,tout1,xor0,xor1;
-+ register unsigned char *in,*out;
-+ register long l=length;
-+ DES_LONG tin[2];
-+ unsigned char *iv;
-+
-+ in=(unsigned char *)input;
-+ out=(unsigned char *)output;
-+ iv=(unsigned char *)ivec;
-+
-+ if (enc)
-+ {
-+ c2l(iv,tout0);
-+ c2l(iv,tout1);
-+ for (l-=8; l>=0; l-=8)
-+ {
-+ c2l(in,tin0);
-+ c2l(in,tin1);
-+ tin0^=tout0;
-+ tin1^=tout1;
-+
-+ tin[0]=tin0;
-+ tin[1]=tin1;
-+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
-+ tout0=tin[0];
-+ tout1=tin[1];
-+
-+ l2c(tout0,out);
-+ l2c(tout1,out);
-+ }
-+ if (l != -8)
-+ {
-+ c2ln(in,tin0,tin1,l+8);
-+ tin0^=tout0;
-+ tin1^=tout1;
-+
-+ tin[0]=tin0;
-+ tin[1]=tin1;
-+ des_encrypt3((DES_LONG *)tin,ks1,ks2,ks3);
-+ tout0=tin[0];
-+ tout1=tin[1];
-+
-+ l2c(tout0,out);
-+ l2c(tout1,out);
-+ }
-+ iv=(unsigned char *)ivec;
-+ l2c(tout0,iv);
-+ l2c(tout1,iv);
-+ }
-+ else
-+ {
-+ register DES_LONG t0,t1;
-+
-+ c2l(iv,xor0);
-+ c2l(iv,xor1);
-+ for (l-=8; l>=0; l-=8)
-+ {
-+ c2l(in,tin0);
-+ c2l(in,tin1);
-+
-+ t0=tin0;
-+ t1=tin1;
-+
-+ tin[0]=tin0;
-+ tin[1]=tin1;
-+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
-+ tout0=tin[0];
-+ tout1=tin[1];
-+
-+ tout0^=xor0;
-+ tout1^=xor1;
-+ l2c(tout0,out);
-+ l2c(tout1,out);
-+ xor0=t0;
-+ xor1=t1;
-+ }
-+ if (l != -8)
-+ {
-+ c2l(in,tin0);
-+ c2l(in,tin1);
-+
-+ t0=tin0;
-+ t1=tin1;
-+
-+ tin[0]=tin0;
-+ tin[1]=tin1;
-+ des_decrypt3((DES_LONG *)tin,ks1,ks2,ks3);
-+ tout0=tin[0];
-+ tout1=tin[1];
-+
-+ tout0^=xor0;
-+ tout1^=xor1;
-+ l2cn(tout0,tout1,out,l+8);
-+ xor0=t0;
-+ xor1=t1;
-+ }
-+
-+ iv=(unsigned char *)ivec;
-+ l2c(xor0,iv);
-+ l2c(xor1,iv);
-+ }
-+ tin0=tin1=tout0=tout1=xor0=xor1=0;
-+ tin[0]=tin[1]=0;
-+ }
-+
-+#endif /* DES_DEFAULT_OPTIONS */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/des_locl.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,515 @@
-+/* crypto/des/des_locl.org */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
-+ *
-+ * Always modify des_locl.org since des_locl.h is automatically generated from
-+ * it during SSLeay configuration.
-+ *
-+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
-+ */
-+
-+#ifndef HEADER_DES_LOCL_H
-+#define HEADER_DES_LOCL_H
-+
-+#if defined(WIN32) || defined(WIN16)
-+#ifndef MSDOS
-+#define MSDOS
-+#endif
-+#endif
-+
-+#include "crypto/des.h"
-+
-+#ifndef DES_DEFAULT_OPTIONS
-+/* the following is tweaked from a config script, that is why it is a
-+ * protected undef/define */
-+#ifndef DES_PTR
-+#define DES_PTR
-+#endif
-+
-+/* This helps C compiler generate the correct code for multiple functional
-+ * units. It reduces register dependancies at the expense of 2 more
-+ * registers */
-+#ifndef DES_RISC1
-+#define DES_RISC1
-+#endif
-+
-+#ifndef DES_RISC2
-+#undef DES_RISC2
-+#endif
-+
-+#if defined(DES_RISC1) && defined(DES_RISC2)
-+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
-+#endif
-+
-+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
-+ * Very mucy CPU dependant */
-+#ifndef DES_UNROLL
-+#define DES_UNROLL
-+#endif
-+
-+/* These default values were supplied by
-+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
-+ * They are only used if nothing else has been defined */
-+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
-+/* Special defines which change the way the code is built depending on the
-+ CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
-+ even newer MIPS CPU's, but at the moment one size fits all for
-+ optimization options. Older Sparc's work better with only UNROLL, but
-+ there's no way to tell at compile time what it is you're running on */
-+
-+#if defined( sun ) /* Newer Sparc's */
-+ #define DES_PTR
-+ #define DES_RISC1
-+ #define DES_UNROLL
-+#elif defined( __ultrix ) /* Older MIPS */
-+ #define DES_PTR
-+ #define DES_RISC2
-+ #define DES_UNROLL
-+#elif defined( __osf1__ ) /* Alpha */
-+ #define DES_PTR
-+ #define DES_RISC2
-+#elif defined ( _AIX ) /* RS6000 */
-+ /* Unknown */
-+#elif defined( __hpux ) /* HP-PA */
-+ /* Unknown */
-+#elif defined( __aux ) /* 68K */
-+ /* Unknown */
-+#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
-+ #define DES_UNROLL
-+#elif defined( __sgi ) /* Newer MIPS */
-+ #define DES_PTR
-+ #define DES_RISC2
-+ #define DES_UNROLL
-+#elif defined( i386 ) /* x86 boxes, should be gcc */
-+ #define DES_PTR
-+ #define DES_RISC1
-+ #define DES_UNROLL
-+#endif /* Systems-specific speed defines */
-+#endif
-+
-+#endif /* DES_DEFAULT_OPTIONS */
-+
-+#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */
-+#include <stdlib.h>
-+#include <errno.h>
-+#include <time.h>
-+#include <io.h>
-+#ifndef RAND
-+#define RAND
-+#endif
-+#undef NOPROTO
-+#endif
-+
-+#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
-+#ifndef __KERNEL__
-+#include <string.h>
-+#else
-+#include <linux/string.h>
-+#endif
-+#endif
-+
-+#ifndef RAND
-+#define RAND
-+#endif
-+
-+#ifdef linux
-+#undef RAND
-+#endif
-+
-+#ifdef MSDOS
-+#define getpid() 2
-+#define RAND
-+#undef NOPROTO
-+#endif
-+
-+#if defined(NOCONST)
-+#define const
-+#endif
-+
-+#ifdef __STDC__
-+#undef NOPROTO
-+#endif
-+
-+#ifdef RAND
-+#define srandom(s) srand(s)
-+#define random rand
-+#endif
-+
-+#define ITERATIONS 16
-+#define HALF_ITERATIONS 8
-+
-+/* used in des_read and des_write */
-+#define MAXWRITE (1024*16)
-+#define BSIZE (MAXWRITE+4)
-+
-+#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \
-+ l|=((DES_LONG)(*((c)++)))<< 8L, \
-+ l|=((DES_LONG)(*((c)++)))<<16L, \
-+ l|=((DES_LONG)(*((c)++)))<<24L)
-+
-+/* NOTE - c is not incremented as per c2l */
-+#define c2ln(c,l1,l2,n) { \
-+ c+=n; \
-+ l1=l2=0; \
-+ switch (n) { \
-+ case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \
-+ case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \
-+ case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \
-+ case 5: l2|=((DES_LONG)(*(--(c)))); \
-+ case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \
-+ case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \
-+ case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \
-+ case 1: l1|=((DES_LONG)(*(--(c)))); \
-+ } \
-+ }
-+
-+#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
-+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
-+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
-+ *((c)++)=(unsigned char)(((l)>>24L)&0xff))
-+
-+/* replacements for htonl and ntohl since I have no idea what to do
-+ * when faced with machines with 8 byte longs. */
-+#define HDRSIZE 4
-+
-+#define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \
-+ l|=((DES_LONG)(*((c)++)))<<16L, \
-+ l|=((DES_LONG)(*((c)++)))<< 8L, \
-+ l|=((DES_LONG)(*((c)++))))
-+
-+#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \
-+ *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
-+ *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
-+ *((c)++)=(unsigned char)(((l) )&0xff))
-+
-+/* NOTE - c is not incremented as per l2c */
-+#define l2cn(l1,l2,c,n) { \
-+ c+=n; \
-+ switch (n) { \
-+ case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \
-+ case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \
-+ case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \
-+ case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \
-+ case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \
-+ case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \
-+ case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \
-+ case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \
-+ } \
-+ }
-+
-+#if defined(WIN32)
-+#define ROTATE(a,n) (_lrotr(a,n))
-+#else
-+#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
-+#endif
-+
-+/* Don't worry about the LOAD_DATA() stuff, that is used by
-+ * fcrypt() to add it's little bit to the front */
-+
-+#ifdef DES_FCRYPT
-+
-+#define LOAD_DATA_tmp(R,S,u,t,E0,E1) \
-+ { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); }
-+
-+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
-+ t=R^(R>>16L); \
-+ u=t&E0; t&=E1; \
-+ tmp=(u<<16); u^=R^s[S ]; u^=tmp; \
-+ tmp=(t<<16); t^=R^s[S+1]; t^=tmp
-+#else
-+#define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g)
-+#define LOAD_DATA(R,S,u,t,E0,E1,tmp) \
-+ u=R^s[S ]; \
-+ t=R^s[S+1]
-+#endif
-+
-+/* The changes to this macro may help or hinder, depending on the
-+ * compiler and the achitecture. gcc2 always seems to do well :-).
-+ * Inspired by Dana How <how@isl.stanford.edu>
-+ * DO NOT use the alternative version on machines with 8 byte longs.
-+ * It does not seem to work on the Alpha, even when DES_LONG is 4
-+ * bytes, probably an issue of accessing non-word aligned objects :-( */
-+#ifdef DES_PTR
-+
-+/* It recently occured to me that 0^0^0^0^0^0^0 == 0, so there
-+ * is no reason to not xor all the sub items together. This potentially
-+ * saves a register since things can be xored directly into L */
-+
-+#if defined(DES_RISC1) || defined(DES_RISC2)
-+#ifdef DES_RISC1
-+#define D_ENCRYPT(LL,R,S) { \
-+ unsigned int u1,u2,u3; \
-+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
-+ u2=(int)u>>8L; \
-+ u1=(int)u&0xfc; \
-+ u2&=0xfc; \
-+ t=ROTATE(t,4); \
-+ u>>=16L; \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
-+ u3=(int)(u>>8L); \
-+ u1=(int)u&0xfc; \
-+ u3&=0xfc; \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \
-+ u2=(int)t>>8L; \
-+ u1=(int)t&0xfc; \
-+ u2&=0xfc; \
-+ t>>=16L; \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
-+ u3=(int)t>>8L; \
-+ u1=(int)t&0xfc; \
-+ u3&=0xfc; \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+u3); }
-+#endif
-+#ifdef DES_RISC2
-+#define D_ENCRYPT(LL,R,S) { \
-+ unsigned int u1,u2,s1,s2; \
-+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
-+ u2=(int)u>>8L; \
-+ u1=(int)u&0xfc; \
-+ u2&=0xfc; \
-+ t=ROTATE(t,4); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
-+ s1=(int)(u>>16L); \
-+ s2=(int)(u>>24L); \
-+ s1&=0xfc; \
-+ s2&=0xfc; \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \
-+ u2=(int)t>>8L; \
-+ u1=(int)t&0xfc; \
-+ u2&=0xfc; \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
-+ s1=(int)(t>>16L); \
-+ s2=(int)(t>>24L); \
-+ s1&=0xfc; \
-+ s2&=0xfc; \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \
-+ LL^= *(DES_LONG *)((unsigned char *)des_SP+0x700+s2); }
-+#endif
-+#else
-+#define D_ENCRYPT(LL,R,S) { \
-+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \
-+ t=ROTATE(t,4); \
-+ LL^= \
-+ *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \
-+ *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \
-+ *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \
-+ *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \
-+ *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \
-+ *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \
-+ *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \
-+ *(DES_LONG *)((unsigned char *)des_SP+0x700+((t>>24L)&0xfc)); }
-+#endif
-+
-+#else /* original version */
-+
-+#if defined(DES_RISC1) || defined(DES_RISC2)
-+#ifdef DES_RISC1
-+#define D_ENCRYPT(LL,R,S) {\
-+ unsigned int u1,u2,u3; \
-+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
-+ u>>=2L; \
-+ t=ROTATE(t,6); \
-+ u2=(int)u>>8L; \
-+ u1=(int)u&0x3f; \
-+ u2&=0x3f; \
-+ u>>=16L; \
-+ LL^=des_SPtrans[0][u1]; \
-+ LL^=des_SPtrans[2][u2]; \
-+ u3=(int)u>>8L; \
-+ u1=(int)u&0x3f; \
-+ u3&=0x3f; \
-+ LL^=des_SPtrans[4][u1]; \
-+ LL^=des_SPtrans[6][u3]; \
-+ u2=(int)t>>8L; \
-+ u1=(int)t&0x3f; \
-+ u2&=0x3f; \
-+ t>>=16L; \
-+ LL^=des_SPtrans[1][u1]; \
-+ LL^=des_SPtrans[3][u2]; \
-+ u3=(int)t>>8L; \
-+ u1=(int)t&0x3f; \
-+ u3&=0x3f; \
-+ LL^=des_SPtrans[5][u1]; \
-+ LL^=des_SPtrans[7][u3]; }
-+#endif
-+#ifdef DES_RISC2
-+#define D_ENCRYPT(LL,R,S) {\
-+ unsigned int u1,u2,s1,s2; \
-+ LOAD_DATA(R,S,u,t,E0,E1,u1); \
-+ u>>=2L; \
-+ t=ROTATE(t,6); \
-+ u2=(int)u>>8L; \
-+ u1=(int)u&0x3f; \
-+ u2&=0x3f; \
-+ LL^=des_SPtrans[0][u1]; \
-+ LL^=des_SPtrans[2][u2]; \
-+ s1=(int)u>>16L; \
-+ s2=(int)u>>24L; \
-+ s1&=0x3f; \
-+ s2&=0x3f; \
-+ LL^=des_SPtrans[4][s1]; \
-+ LL^=des_SPtrans[6][s2]; \
-+ u2=(int)t>>8L; \
-+ u1=(int)t&0x3f; \
-+ u2&=0x3f; \
-+ LL^=des_SPtrans[1][u1]; \
-+ LL^=des_SPtrans[3][u2]; \
-+ s1=(int)t>>16; \
-+ s2=(int)t>>24L; \
-+ s1&=0x3f; \
-+ s2&=0x3f; \
-+ LL^=des_SPtrans[5][s1]; \
-+ LL^=des_SPtrans[7][s2]; }
-+#endif
-+
-+#else
-+
-+#define D_ENCRYPT(LL,R,S) {\
-+ LOAD_DATA_tmp(R,S,u,t,E0,E1); \
-+ t=ROTATE(t,4); \
-+ LL^=\
-+ des_SPtrans[0][(u>> 2L)&0x3f]^ \
-+ des_SPtrans[2][(u>>10L)&0x3f]^ \
-+ des_SPtrans[4][(u>>18L)&0x3f]^ \
-+ des_SPtrans[6][(u>>26L)&0x3f]^ \
-+ des_SPtrans[1][(t>> 2L)&0x3f]^ \
-+ des_SPtrans[3][(t>>10L)&0x3f]^ \
-+ des_SPtrans[5][(t>>18L)&0x3f]^ \
-+ des_SPtrans[7][(t>>26L)&0x3f]; }
-+#endif
-+#endif
-+
-+ /* IP and FP
-+ * The problem is more of a geometric problem that random bit fiddling.
-+ 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6
-+ 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4
-+ 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2
-+ 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0
-+
-+ 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7
-+ 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5
-+ 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3
-+ 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1
-+
-+ The output has been subject to swaps of the form
-+ 0 1 -> 3 1 but the odd and even bits have been put into
-+ 2 3 2 0
-+ different words. The main trick is to remember that
-+ t=((l>>size)^r)&(mask);
-+ r^=t;
-+ l^=(t<<size);
-+ can be used to swap and move bits between words.
-+
-+ So l = 0 1 2 3 r = 16 17 18 19
-+ 4 5 6 7 20 21 22 23
-+ 8 9 10 11 24 25 26 27
-+ 12 13 14 15 28 29 30 31
-+ becomes (for size == 2 and mask == 0x3333)
-+ t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
-+ 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
-+ 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
-+ 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
-+
-+ Thanks for hints from Richard Outerbridge - he told me IP&FP
-+ could be done in 15 xor, 10 shifts and 5 ands.
-+ When I finally started to think of the problem in 2D
-+ I first got ~42 operations without xors. When I remembered
-+ how to use xors :-) I got it to its final state.
-+ */
-+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
-+ (b)^=(t),\
-+ (a)^=((t)<<(n)))
-+
-+#define IP(l,r) \
-+ { \
-+ register DES_LONG tt; \
-+ PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \
-+ PERM_OP(l,r,tt,16,0x0000ffffL); \
-+ PERM_OP(r,l,tt, 2,0x33333333L); \
-+ PERM_OP(l,r,tt, 8,0x00ff00ffL); \
-+ PERM_OP(r,l,tt, 1,0x55555555L); \
-+ }
-+
-+#define FP(l,r) \
-+ { \
-+ register DES_LONG tt; \
-+ PERM_OP(l,r,tt, 1,0x55555555L); \
-+ PERM_OP(r,l,tt, 8,0x00ff00ffL); \
-+ PERM_OP(l,r,tt, 2,0x33333333L); \
-+ PERM_OP(r,l,tt,16,0x0000ffffL); \
-+ PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \
-+ }
-+
-+extern const DES_LONG des_SPtrans[8][64];
-+
-+#ifndef NOPROTO
-+void fcrypt_body(DES_LONG *out,des_key_schedule ks,
-+ DES_LONG Eswap0, DES_LONG Eswap1);
-+#else
-+void fcrypt_body();
-+#endif
-+
-+#endif
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/des_opts.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,620 @@
-+/* crypto/des/des_opts.c */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+/* define PART1, PART2, PART3 or PART4 to build only with a few of the options.
-+ * This is for machines with 64k code segment size restrictions. */
-+
-+#ifndef MSDOS
-+#define TIMES
-+#endif
-+
-+#include <stdio.h>
-+#ifndef MSDOS
-+#include <unistd.h>
-+#else
-+#include <io.h>
-+extern void exit();
-+#endif
-+#include <signal.h>
-+#ifndef VMS
-+#ifndef _IRIX
-+#include <time.h>
-+#endif
-+#ifdef TIMES
-+#include <sys/types.h>
-+#include <sys/times.h>
-+#endif
-+#else /* VMS */
-+#include <types.h>
-+struct tms {
-+ time_t tms_utime;
-+ time_t tms_stime;
-+ time_t tms_uchild; /* I dunno... */
-+ time_t tms_uchildsys; /* so these names are a guess :-) */
-+ }
-+#endif
-+#ifndef TIMES
-+#include <sys/timeb.h>
-+#endif
-+
-+#ifdef sun
-+#include <limits.h>
-+#include <sys/param.h>
-+#endif
-+
-+#include "des_locl.h"
-+#include "spr.h"
-+
-+#define DES_DEFAULT_OPTIONS
-+
-+#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4)
-+#define PART1
-+#define PART2
-+#define PART3
-+#define PART4
-+#endif
-+
-+#ifdef PART1
-+
-+#undef DES_UNROLL
-+#undef DES_RISC1
-+#undef DES_RISC2
-+#undef DES_PTR
-+#undef D_ENCRYPT
-+#define des_encrypt des_encrypt_u4_cisc_idx
-+#define des_encrypt2 des_encrypt2_u4_cisc_idx
-+#define des_encrypt3 des_encrypt3_u4_cisc_idx
-+#define des_decrypt3 des_decrypt3_u4_cisc_idx
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#define DES_UNROLL
-+#undef DES_RISC1
-+#undef DES_RISC2
-+#undef DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u16_cisc_idx
-+#define des_encrypt2 des_encrypt2_u16_cisc_idx
-+#define des_encrypt3 des_encrypt3_u16_cisc_idx
-+#define des_decrypt3 des_decrypt3_u16_cisc_idx
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#undef DES_UNROLL
-+#define DES_RISC1
-+#undef DES_RISC2
-+#undef DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u4_risc1_idx
-+#define des_encrypt2 des_encrypt2_u4_risc1_idx
-+#define des_encrypt3 des_encrypt3_u4_risc1_idx
-+#define des_decrypt3 des_decrypt3_u4_risc1_idx
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#endif
-+
-+#ifdef PART2
-+
-+#undef DES_UNROLL
-+#undef DES_RISC1
-+#define DES_RISC2
-+#undef DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u4_risc2_idx
-+#define des_encrypt2 des_encrypt2_u4_risc2_idx
-+#define des_encrypt3 des_encrypt3_u4_risc2_idx
-+#define des_decrypt3 des_decrypt3_u4_risc2_idx
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#define DES_UNROLL
-+#define DES_RISC1
-+#undef DES_RISC2
-+#undef DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u16_risc1_idx
-+#define des_encrypt2 des_encrypt2_u16_risc1_idx
-+#define des_encrypt3 des_encrypt3_u16_risc1_idx
-+#define des_decrypt3 des_decrypt3_u16_risc1_idx
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#define DES_UNROLL
-+#undef DES_RISC1
-+#define DES_RISC2
-+#undef DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u16_risc2_idx
-+#define des_encrypt2 des_encrypt2_u16_risc2_idx
-+#define des_encrypt3 des_encrypt3_u16_risc2_idx
-+#define des_decrypt3 des_decrypt3_u16_risc2_idx
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#endif
-+
-+#ifdef PART3
-+
-+#undef DES_UNROLL
-+#undef DES_RISC1
-+#undef DES_RISC2
-+#define DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u4_cisc_ptr
-+#define des_encrypt2 des_encrypt2_u4_cisc_ptr
-+#define des_encrypt3 des_encrypt3_u4_cisc_ptr
-+#define des_decrypt3 des_decrypt3_u4_cisc_ptr
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#define DES_UNROLL
-+#undef DES_RISC1
-+#undef DES_RISC2
-+#define DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u16_cisc_ptr
-+#define des_encrypt2 des_encrypt2_u16_cisc_ptr
-+#define des_encrypt3 des_encrypt3_u16_cisc_ptr
-+#define des_decrypt3 des_decrypt3_u16_cisc_ptr
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#undef DES_UNROLL
-+#define DES_RISC1
-+#undef DES_RISC2
-+#define DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u4_risc1_ptr
-+#define des_encrypt2 des_encrypt2_u4_risc1_ptr
-+#define des_encrypt3 des_encrypt3_u4_risc1_ptr
-+#define des_decrypt3 des_decrypt3_u4_risc1_ptr
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#endif
-+
-+#ifdef PART4
-+
-+#undef DES_UNROLL
-+#undef DES_RISC1
-+#define DES_RISC2
-+#define DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u4_risc2_ptr
-+#define des_encrypt2 des_encrypt2_u4_risc2_ptr
-+#define des_encrypt3 des_encrypt3_u4_risc2_ptr
-+#define des_decrypt3 des_decrypt3_u4_risc2_ptr
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#define DES_UNROLL
-+#define DES_RISC1
-+#undef DES_RISC2
-+#define DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u16_risc1_ptr
-+#define des_encrypt2 des_encrypt2_u16_risc1_ptr
-+#define des_encrypt3 des_encrypt3_u16_risc1_ptr
-+#define des_decrypt3 des_decrypt3_u16_risc1_ptr
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#define DES_UNROLL
-+#undef DES_RISC1
-+#define DES_RISC2
-+#define DES_PTR
-+#undef D_ENCRYPT
-+#undef des_encrypt
-+#undef des_encrypt2
-+#undef des_encrypt3
-+#undef des_decrypt3
-+#define des_encrypt des_encrypt_u16_risc2_ptr
-+#define des_encrypt2 des_encrypt2_u16_risc2_ptr
-+#define des_encrypt3 des_encrypt3_u16_risc2_ptr
-+#define des_decrypt3 des_decrypt3_u16_risc2_ptr
-+#undef HEADER_DES_LOCL_H
-+#include "des_enc.c"
-+
-+#endif
-+
-+/* The following if from times(3) man page. It may need to be changed */
-+#ifndef HZ
-+# ifndef CLK_TCK
-+# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
-+# ifndef VMS
-+# define HZ 100.0
-+# else /* VMS */
-+# define HZ 100.0
-+# endif
-+# else /* _BSD_CLK_TCK_ */
-+# define HZ ((double)_BSD_CLK_TCK_)
-+# endif
-+# else /* CLK_TCK */
-+# define HZ ((double)CLK_TCK)
-+# endif
-+#endif
-+
-+#define BUFSIZE ((long)1024)
-+long run=0;
-+
-+#ifndef NOPROTO
-+double Time_F(int s);
-+#else
-+double Time_F();
-+#endif
-+
-+#ifdef SIGALRM
-+#if defined(__STDC__) || defined(sgi)
-+#define SIGRETTYPE void
-+#else
-+#define SIGRETTYPE int
-+#endif
-+
-+#ifndef NOPROTO
-+SIGRETTYPE sig_done(int sig);
-+#else
-+SIGRETTYPE sig_done();
-+#endif
-+
-+SIGRETTYPE sig_done(sig)
-+int sig;
-+ {
-+ signal(SIGALRM,sig_done);
-+ run=0;
-+#ifdef LINT
-+ sig=sig;
-+#endif
-+ }
-+#endif
-+
-+#define START 0
-+#define STOP 1
-+
-+double Time_F(s)
-+int s;
-+ {
-+ double ret;
-+#ifdef TIMES
-+ static struct tms tstart,tend;
-+
-+ if (s == START)
-+ {
-+ times(&tstart);
-+ return(0);
-+ }
-+ else
-+ {
-+ times(&tend);
-+ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
-+ return((ret == 0.0)?1e-6:ret);
-+ }
-+#else /* !times() */
-+ static struct timeb tstart,tend;
-+ long i;
-+
-+ if (s == START)
-+ {
-+ ftime(&tstart);
-+ return(0);
-+ }
-+ else
-+ {
-+ ftime(&tend);
-+ i=(long)tend.millitm-(long)tstart.millitm;
-+ ret=((double)(tend.time-tstart.time))+((double)i)/1000.0;
-+ return((ret == 0.0)?1e-6:ret);
-+ }
-+#endif
-+ }
-+
-+#ifdef SIGALRM
-+#define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10);
-+#else
-+#define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb);
-+#endif
-+
-+#define time_it(func,name,index) \
-+ print_name(name); \
-+ Time_F(START); \
-+ for (count=0,run=1; COND(cb); count++) \
-+ { \
-+ unsigned long d[2]; \
-+ func(d,&(sch[0]),DES_ENCRYPT); \
-+ } \
-+ tm[index]=Time_F(STOP); \
-+ fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \
-+ tm[index]=((double)COUNT(cb))/tm[index];
-+
-+#define print_it(name,index) \
-+ fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \
-+ tm[index]*8,1.0e6/tm[index]);
-+
-+int main(argc,argv)
-+int argc;
-+char **argv;
-+ {
-+ long count;
-+ static unsigned char buf[BUFSIZE];
-+ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
-+ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
-+ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
-+ des_key_schedule sch,sch2,sch3;
-+ double d,tm[16],max=0;
-+ int rank[16];
-+ char *str[16];
-+ int max_idx=0,i,num=0,j;
-+#ifndef SIGALARM
-+ long ca,cb,cc,cd,ce;
-+#endif
-+
-+ for (i=0; i<12; i++)
-+ {
-+ tm[i]=0.0;
-+ rank[i]=0;
-+ }
-+
-+#ifndef TIMES
-+ fprintf(stderr,"To get the most acurate results, try to run this\n");
-+ fprintf(stderr,"program when this computer is idle.\n");
-+#endif
-+
-+ des_set_key((C_Block *)key,sch);
-+ des_set_key((C_Block *)key2,sch2);
-+ des_set_key((C_Block *)key3,sch3);
-+
-+#ifndef SIGALRM
-+ fprintf(stderr,"First we calculate the approximate speed ...\n");
-+ des_set_key((C_Block *)key,sch);
-+ count=10;
-+ do {
-+ long i;
-+ unsigned long data[2];
-+
-+ count*=2;
-+ Time_F(START);
-+ for (i=count; i; i--)
-+ des_encrypt(data,&(sch[0]),DES_ENCRYPT);
-+ d=Time_F(STOP);
-+ } while (d < 3.0);
-+ ca=count;
-+ cb=count*3;
-+ cc=count*3*8/BUFSIZE+1;
-+ cd=count*8/BUFSIZE+1;
-+
-+ ce=count/20+1;
-+#define COND(d) (count != (d))
-+#define COUNT(d) (d)
-+#else
-+#define COND(c) (run)
-+#define COUNT(d) (count)
-+ signal(SIGALRM,sig_done);
-+ alarm(10);
-+#endif
-+
-+#ifdef PART1
-+ time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx ", 0);
-+ time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1);
-+ time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2);
-+ num+=3;
-+#endif
-+#ifdef PART2
-+ time_it(des_encrypt_u16_risc1_idx,"des_encrypt_u16_risc1_idx", 3);
-+ time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4);
-+ time_it(des_encrypt_u16_risc2_idx,"des_encrypt_u16_risc2_idx", 5);
-+ num+=3;
-+#endif
-+#ifdef PART3
-+ time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr ", 6);
-+ time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7);
-+ time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8);
-+ num+=3;
-+#endif
-+#ifdef PART4
-+ time_it(des_encrypt_u16_risc1_ptr,"des_encrypt_u16_risc1_ptr", 9);
-+ time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ",10);
-+ time_it(des_encrypt_u16_risc2_ptr,"des_encrypt_u16_risc2_ptr",11);
-+ num+=3;
-+#endif
-+
-+#ifdef PART1
-+ str[0]=" 4 c i";
-+ print_it("des_encrypt_u4_cisc_idx ",0);
-+ max=tm[0];
-+ max_idx=0;
-+ str[1]="16 c i";
-+ print_it("des_encrypt_u16_cisc_idx ",1);
-+ if (max < tm[1]) { max=tm[1]; max_idx=1; }
-+ str[2]=" 4 r1 i";
-+ print_it("des_encrypt_u4_risc1_idx ",2);
-+ if (max < tm[2]) { max=tm[2]; max_idx=2; }
-+#endif
-+#ifdef PART2
-+ str[3]="16 r1 i";
-+ print_it("des_encrypt_u16_risc1_idx",3);
-+ if (max < tm[3]) { max=tm[3]; max_idx=3; }
-+ str[4]=" 4 r2 i";
-+ print_it("des_encrypt_u4_risc2_idx ",4);
-+ if (max < tm[4]) { max=tm[4]; max_idx=4; }
-+ str[5]="16 r2 i";
-+ print_it("des_encrypt_u16_risc2_idx",5);
-+ if (max < tm[5]) { max=tm[5]; max_idx=5; }
-+#endif
-+#ifdef PART3
-+ str[6]=" 4 c p";
-+ print_it("des_encrypt_u4_cisc_ptr ",6);
-+ if (max < tm[6]) { max=tm[6]; max_idx=6; }
-+ str[7]="16 c p";
-+ print_it("des_encrypt_u16_cisc_ptr ",7);
-+ if (max < tm[7]) { max=tm[7]; max_idx=7; }
-+ str[8]=" 4 r1 p";
-+ print_it("des_encrypt_u4_risc1_ptr ",8);
-+ if (max < tm[8]) { max=tm[8]; max_idx=8; }
-+#endif
-+#ifdef PART4
-+ str[9]="16 r1 p";
-+ print_it("des_encrypt_u16_risc1_ptr",9);
-+ if (max < tm[9]) { max=tm[9]; max_idx=9; }
-+ str[10]=" 4 r2 p";
-+ print_it("des_encrypt_u4_risc2_ptr ",10);
-+ if (max < tm[10]) { max=tm[10]; max_idx=10; }
-+ str[11]="16 r2 p";
-+ print_it("des_encrypt_u16_risc2_ptr",11);
-+ if (max < tm[11]) { max=tm[11]; max_idx=11; }
-+#endif
-+ printf("options des ecb/s\n");
-+ printf("%s %12.2f 100.0%%\n",str[max_idx],tm[max_idx]);
-+ d=tm[max_idx];
-+ tm[max_idx]= -2.0;
-+ max= -1.0;
-+ for (;;)
-+ {
-+ for (i=0; i<12; i++)
-+ {
-+ if (max < tm[i]) { max=tm[i]; j=i; }
-+ }
-+ if (max < 0.0) break;
-+ printf("%s %12.2f %4.1f%%\n",str[j],tm[j],tm[j]/d*100.0);
-+ tm[j]= -2.0;
-+ max= -1.0;
-+ }
-+
-+ switch (max_idx)
-+ {
-+ case 0:
-+ printf("-DDES_DEFAULT_OPTIONS\n");
-+ break;
-+ case 1:
-+ printf("-DDES_UNROLL\n");
-+ break;
-+ case 2:
-+ printf("-DDES_RISC1\n");
-+ break;
-+ case 3:
-+ printf("-DDES_UNROLL -DDES_RISC1\n");
-+ break;
-+ case 4:
-+ printf("-DDES_RISC2\n");
-+ break;
-+ case 5:
-+ printf("-DDES_UNROLL -DDES_RISC2\n");
-+ break;
-+ case 6:
-+ printf("-DDES_PTR\n");
-+ break;
-+ case 7:
-+ printf("-DDES_UNROLL -DDES_PTR\n");
-+ break;
-+ case 8:
-+ printf("-DDES_RISC1 -DDES_PTR\n");
-+ break;
-+ case 9:
-+ printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n");
-+ break;
-+ case 10:
-+ printf("-DDES_RISC2 -DDES_PTR\n");
-+ break;
-+ case 11:
-+ printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n");
-+ break;
-+ }
-+ exit(0);
-+#if defined(LINT) || defined(MSDOS)
-+ return(0);
-+#endif
-+ }
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/des_ver.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,60 @@
-+/* crypto/des/des_ver.h */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+extern char *DES_version; /* SSLeay version string */
-+extern char *libdes_version; /* old libdes version string */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/destest.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,871 @@
-+/* crypto/des/destest.c */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+#if defined(WIN32) || defined(WIN16) || defined(WINDOWS)
-+#ifndef MSDOS
-+#define MSDOS
-+#endif
-+#endif
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#ifndef MSDOS
-+#include <unistd.h>
-+#else
-+#include <io.h>
-+#endif
-+#include <string.h>
-+#include "des_locl.h"
-+
-+/* tisk tisk - the test keys don't all have odd parity :-( */
-+/* test data */
-+#define NUM_TESTS 34
-+static unsigned char key_data[NUM_TESTS][8]={
-+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
-+ {0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
-+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
-+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
-+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-+ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10},
-+ {0x7C,0xA1,0x10,0x45,0x4A,0x1A,0x6E,0x57},
-+ {0x01,0x31,0xD9,0x61,0x9D,0xC1,0x37,0x6E},
-+ {0x07,0xA1,0x13,0x3E,0x4A,0x0B,0x26,0x86},
-+ {0x38,0x49,0x67,0x4C,0x26,0x02,0x31,0x9E},
-+ {0x04,0xB9,0x15,0xBA,0x43,0xFE,0xB5,0xB6},
-+ {0x01,0x13,0xB9,0x70,0xFD,0x34,0xF2,0xCE},
-+ {0x01,0x70,0xF1,0x75,0x46,0x8F,0xB5,0xE6},
-+ {0x43,0x29,0x7F,0xAD,0x38,0xE3,0x73,0xFE},
-+ {0x07,0xA7,0x13,0x70,0x45,0xDA,0x2A,0x16},
-+ {0x04,0x68,0x91,0x04,0xC2,0xFD,0x3B,0x2F},
-+ {0x37,0xD0,0x6B,0xB5,0x16,0xCB,0x75,0x46},
-+ {0x1F,0x08,0x26,0x0D,0x1A,0xC2,0x46,0x5E},
-+ {0x58,0x40,0x23,0x64,0x1A,0xBA,0x61,0x76},
-+ {0x02,0x58,0x16,0x16,0x46,0x29,0xB0,0x07},
-+ {0x49,0x79,0x3E,0xBC,0x79,0xB3,0x25,0x8F},
-+ {0x4F,0xB0,0x5E,0x15,0x15,0xAB,0x73,0xA7},
-+ {0x49,0xE9,0x5D,0x6D,0x4C,0xA2,0x29,0xBF},
-+ {0x01,0x83,0x10,0xDC,0x40,0x9B,0x26,0xD6},
-+ {0x1C,0x58,0x7F,0x1C,0x13,0x92,0x4F,0xEF},
-+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
-+ {0x1F,0x1F,0x1F,0x1F,0x0E,0x0E,0x0E,0x0E},
-+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
-+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
-+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
-+ {0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10}};
-+
-+static unsigned char plain_data[NUM_TESTS][8]={
-+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
-+ {0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
-+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
-+ {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11},
-+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
-+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
-+ {0x01,0xA1,0xD6,0xD0,0x39,0x77,0x67,0x42},
-+ {0x5C,0xD5,0x4C,0xA8,0x3D,0xEF,0x57,0xDA},
-+ {0x02,0x48,0xD4,0x38,0x06,0xF6,0x71,0x72},
-+ {0x51,0x45,0x4B,0x58,0x2D,0xDF,0x44,0x0A},
-+ {0x42,0xFD,0x44,0x30,0x59,0x57,0x7F,0xA2},
-+ {0x05,0x9B,0x5E,0x08,0x51,0xCF,0x14,0x3A},
-+ {0x07,0x56,0xD8,0xE0,0x77,0x47,0x61,0xD2},
-+ {0x76,0x25,0x14,0xB8,0x29,0xBF,0x48,0x6A},
-+ {0x3B,0xDD,0x11,0x90,0x49,0x37,0x28,0x02},
-+ {0x26,0x95,0x5F,0x68,0x35,0xAF,0x60,0x9A},
-+ {0x16,0x4D,0x5E,0x40,0x4F,0x27,0x52,0x32},
-+ {0x6B,0x05,0x6E,0x18,0x75,0x9F,0x5C,0xCA},
-+ {0x00,0x4B,0xD6,0xEF,0x09,0x17,0x60,0x62},
-+ {0x48,0x0D,0x39,0x00,0x6E,0xE7,0x62,0xF2},
-+ {0x43,0x75,0x40,0xC8,0x69,0x8F,0x3C,0xFA},
-+ {0x07,0x2D,0x43,0xA0,0x77,0x07,0x52,0x92},
-+ {0x02,0xFE,0x55,0x77,0x81,0x17,0xF1,0x2A},
-+ {0x1D,0x9D,0x5C,0x50,0x18,0xF7,0x28,0xC2},
-+ {0x30,0x55,0x32,0x28,0x6D,0x6F,0x29,0x5A},
-+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
-+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
-+ {0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF},
-+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
-+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-+ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-+ {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}};
-+
-+static unsigned char cipher_data[NUM_TESTS][8]={
-+ {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
-+ {0x73,0x59,0xB2,0x16,0x3E,0x4E,0xDC,0x58},
-+ {0x95,0x8E,0x6E,0x62,0x7A,0x05,0x55,0x7B},
-+ {0xF4,0x03,0x79,0xAB,0x9E,0x0E,0xC5,0x33},
-+ {0x17,0x66,0x8D,0xFC,0x72,0x92,0x53,0x2D},
-+ {0x8A,0x5A,0xE1,0xF8,0x1A,0xB8,0xF2,0xDD},
-+ {0x8C,0xA6,0x4D,0xE9,0xC1,0xB1,0x23,0xA7},
-+ {0xED,0x39,0xD9,0x50,0xFA,0x74,0xBC,0xC4},
-+ {0x69,0x0F,0x5B,0x0D,0x9A,0x26,0x93,0x9B},
-+ {0x7A,0x38,0x9D,0x10,0x35,0x4B,0xD2,0x71},
-+ {0x86,0x8E,0xBB,0x51,0xCA,0xB4,0x59,0x9A},
-+ {0x71,0x78,0x87,0x6E,0x01,0xF1,0x9B,0x2A},
-+ {0xAF,0x37,0xFB,0x42,0x1F,0x8C,0x40,0x95},
-+ {0x86,0xA5,0x60,0xF1,0x0E,0xC6,0xD8,0x5B},
-+ {0x0C,0xD3,0xDA,0x02,0x00,0x21,0xDC,0x09},
-+ {0xEA,0x67,0x6B,0x2C,0xB7,0xDB,0x2B,0x7A},
-+ {0xDF,0xD6,0x4A,0x81,0x5C,0xAF,0x1A,0x0F},
-+ {0x5C,0x51,0x3C,0x9C,0x48,0x86,0xC0,0x88},
-+ {0x0A,0x2A,0xEE,0xAE,0x3F,0xF4,0xAB,0x77},
-+ {0xEF,0x1B,0xF0,0x3E,0x5D,0xFA,0x57,0x5A},
-+ {0x88,0xBF,0x0D,0xB6,0xD7,0x0D,0xEE,0x56},
-+ {0xA1,0xF9,0x91,0x55,0x41,0x02,0x0B,0x56},
-+ {0x6F,0xBF,0x1C,0xAF,0xCF,0xFD,0x05,0x56},
-+ {0x2F,0x22,0xE4,0x9B,0xAB,0x7C,0xA1,0xAC},
-+ {0x5A,0x6B,0x61,0x2C,0xC2,0x6C,0xCE,0x4A},
-+ {0x5F,0x4C,0x03,0x8E,0xD1,0x2B,0x2E,0x41},
-+ {0x63,0xFA,0xC0,0xD0,0x34,0xD9,0xF7,0x93},
-+ {0x61,0x7B,0x3A,0x0C,0xE8,0xF0,0x71,0x00},
-+ {0xDB,0x95,0x86,0x05,0xF8,0xC8,0xC6,0x06},
-+ {0xED,0xBF,0xD1,0xC6,0x6C,0x29,0xCC,0xC7},
-+ {0x35,0x55,0x50,0xB2,0x15,0x0E,0x24,0x51},
-+ {0xCA,0xAA,0xAF,0x4D,0xEA,0xF1,0xDB,0xAE},
-+ {0xD5,0xD4,0x4F,0xF7,0x20,0x68,0x3D,0x0D},
-+ {0x2A,0x2B,0xB0,0x08,0xDF,0x97,0xC2,0xF2}};
-+
-+static unsigned char cipher_ecb2[NUM_TESTS-1][8]={
-+ {0x92,0x95,0xB5,0x9B,0xB3,0x84,0x73,0x6E},
-+ {0x19,0x9E,0x9D,0x6D,0xF3,0x9A,0xA8,0x16},
-+ {0x2A,0x4B,0x4D,0x24,0x52,0x43,0x84,0x27},
-+ {0x35,0x84,0x3C,0x01,0x9D,0x18,0xC5,0xB6},
-+ {0x4A,0x5B,0x2F,0x42,0xAA,0x77,0x19,0x25},
-+ {0xA0,0x6B,0xA9,0xB8,0xCA,0x5B,0x17,0x8A},
-+ {0xAB,0x9D,0xB7,0xFB,0xED,0x95,0xF2,0x74},
-+ {0x3D,0x25,0x6C,0x23,0xA7,0x25,0x2F,0xD6},
-+ {0xB7,0x6F,0xAB,0x4F,0xBD,0xBD,0xB7,0x67},
-+ {0x8F,0x68,0x27,0xD6,0x9C,0xF4,0x1A,0x10},
-+ {0x82,0x57,0xA1,0xD6,0x50,0x5E,0x81,0x85},
-+ {0xA2,0x0F,0x0A,0xCD,0x80,0x89,0x7D,0xFA},
-+ {0xCD,0x2A,0x53,0x3A,0xDB,0x0D,0x7E,0xF3},
-+ {0xD2,0xC2,0xBE,0x27,0xE8,0x1B,0x68,0xE3},
-+ {0xE9,0x24,0xCF,0x4F,0x89,0x3C,0x5B,0x0A},
-+ {0xA7,0x18,0xC3,0x9F,0xFA,0x9F,0xD7,0x69},
-+ {0x77,0x2C,0x79,0xB1,0xD2,0x31,0x7E,0xB1},
-+ {0x49,0xAB,0x92,0x7F,0xD0,0x22,0x00,0xB7},
-+ {0xCE,0x1C,0x6C,0x7D,0x85,0xE3,0x4A,0x6F},
-+ {0xBE,0x91,0xD6,0xE1,0x27,0xB2,0xE9,0x87},
-+ {0x70,0x28,0xAE,0x8F,0xD1,0xF5,0x74,0x1A},
-+ {0xAA,0x37,0x80,0xBB,0xF3,0x22,0x1D,0xDE},
-+ {0xA6,0xC4,0xD2,0x5E,0x28,0x93,0xAC,0xB3},
-+ {0x22,0x07,0x81,0x5A,0xE4,0xB7,0x1A,0xAD},
-+ {0xDC,0xCE,0x05,0xE7,0x07,0xBD,0xF5,0x84},
-+ {0x26,0x1D,0x39,0x2C,0xB3,0xBA,0xA5,0x85},
-+ {0xB4,0xF7,0x0F,0x72,0xFB,0x04,0xF0,0xDC},
-+ {0x95,0xBA,0xA9,0x4E,0x87,0x36,0xF2,0x89},
-+ {0xD4,0x07,0x3A,0xF1,0x5A,0x17,0x82,0x0E},
-+ {0xEF,0x6F,0xAF,0xA7,0x66,0x1A,0x7E,0x89},
-+ {0xC1,0x97,0xF5,0x58,0x74,0x8A,0x20,0xE7},
-+ {0x43,0x34,0xCF,0xDA,0x22,0xC4,0x86,0xC8},
-+ {0x08,0xD7,0xB4,0xFB,0x62,0x9D,0x08,0x85}};
-+
-+static unsigned char cbc_key [8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
-+static unsigned char cbc2_key[8]={0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87};
-+static unsigned char cbc3_key[8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
-+static unsigned char cbc_iv [8]={0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10};
-+static char cbc_data[40]="7654321 Now is the time for \0001";
-+
-+static unsigned char cbc_ok[32]={
-+ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
-+ 0xac,0xd8,0xae,0xfd,0xdf,0xd8,0xa1,0xeb,
-+ 0x46,0x8e,0x91,0x15,0x78,0x88,0xba,0x68,
-+ 0x1d,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
-+
-+static unsigned char xcbc_ok[32]={
-+ 0x86,0x74,0x81,0x0D,0x61,0xA4,0xA5,0x48,
-+ 0xB9,0x93,0x03,0xE1,0xB8,0xBB,0xBD,0xBD,
-+ 0x64,0x30,0x0B,0xB9,0x06,0x65,0x81,0x76,
-+ 0x04,0x1D,0x77,0x62,0x17,0xCA,0x2B,0xD2,
-+ };
-+
-+static unsigned char cbc3_ok[32]={
-+ 0x3F,0xE3,0x01,0xC9,0x62,0xAC,0x01,0xD0,
-+ 0x22,0x13,0x76,0x3C,0x1C,0xBD,0x4C,0xDC,
-+ 0x79,0x96,0x57,0xC0,0x64,0xEC,0xF5,0xD4,
-+ 0x1C,0x67,0x38,0x12,0xCF,0xDE,0x96,0x75};
-+
-+static unsigned char pcbc_ok[32]={
-+ 0xcc,0xd1,0x73,0xff,0xab,0x20,0x39,0xf4,
-+ 0x6d,0xec,0xb4,0x70,0xa0,0xe5,0x6b,0x15,
-+ 0xae,0xa6,0xbf,0x61,0xed,0x7d,0x9c,0x9f,
-+ 0xf7,0x17,0x46,0x3b,0x8a,0xb3,0xcc,0x88};
-+
-+static unsigned char cfb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
-+static unsigned char cfb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
-+static unsigned char cfb_buf1[40],cfb_buf2[40],cfb_tmp[8];
-+static unsigned char plain[24]=
-+ {
-+ 0x4e,0x6f,0x77,0x20,0x69,0x73,
-+ 0x20,0x74,0x68,0x65,0x20,0x74,
-+ 0x69,0x6d,0x65,0x20,0x66,0x6f,
-+ 0x72,0x20,0x61,0x6c,0x6c,0x20
-+ };
-+static unsigned char cfb_cipher8[24]= {
-+ 0xf3,0x1f,0xda,0x07,0x01,0x14, 0x62,0xee,0x18,0x7f,0x43,0xd8,
-+ 0x0a,0x7c,0xd9,0xb5,0xb0,0xd2, 0x90,0xda,0x6e,0x5b,0x9a,0x87 };
-+static unsigned char cfb_cipher16[24]={
-+ 0xF3,0x09,0x87,0x87,0x7F,0x57, 0xF7,0x3C,0x36,0xB6,0xDB,0x70,
-+ 0xD8,0xD5,0x34,0x19,0xD3,0x86, 0xB2,0x23,0xB7,0xB2,0xAD,0x1B };
-+static unsigned char cfb_cipher32[24]={
-+ 0xF3,0x09,0x62,0x49,0xA4,0xDF, 0xA4,0x9F,0x33,0xDC,0x7B,0xAD,
-+ 0x4C,0xC8,0x9F,0x64,0xE4,0x53, 0xE5,0xEC,0x67,0x20,0xDA,0xB6 };
-+static unsigned char cfb_cipher48[24]={
-+ 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x30,0xB5,0x15,0xEC,0xBB,0x85,
-+ 0x97,0x5A,0x13,0x8C,0x68,0x60, 0xE2,0x38,0x34,0x3C,0xDC,0x1F };
-+static unsigned char cfb_cipher64[24]={
-+ 0xF3,0x09,0x62,0x49,0xC7,0xF4, 0x6E,0x51,0xA6,0x9E,0x83,0x9B,
-+ 0x1A,0x92,0xF7,0x84,0x03,0x46, 0x71,0x33,0x89,0x8E,0xA6,0x22 };
-+
-+static unsigned char ofb_key[8]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
-+static unsigned char ofb_iv[8]={0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef};
-+static unsigned char ofb_buf1[24],ofb_buf2[24],ofb_tmp[8];
-+static unsigned char ofb_cipher[24]=
-+ {
-+ 0xf3,0x09,0x62,0x49,0xc7,0xf4,0x6e,0x51,
-+ 0x35,0xf2,0x4a,0x24,0x2e,0xeb,0x3d,0x3f,
-+ 0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3
-+ };
-+
-+DES_LONG cbc_cksum_ret=0xB462FEF7L;
-+unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
-+
-+#ifndef NOPROTO
-+static char *pt(unsigned char *p);
-+static int cfb_test(int bits, unsigned char *cfb_cipher);
-+static int cfb64_test(unsigned char *cfb_cipher);
-+static int ede_cfb64_test(unsigned char *cfb_cipher);
-+#else
-+static char *pt();
-+static int cfb_test();
-+static int cfb64_test();
-+static int ede_cfb64_test();
-+#endif
-+
-+int main(argc,argv)
-+int argc;
-+char *argv[];
-+ {
-+ int i,j,err=0;
-+ des_cblock in,out,outin,iv3;
-+ des_key_schedule ks,ks2,ks3;
-+ unsigned char cbc_in[40];
-+ unsigned char cbc_out[40];
-+ DES_LONG cs;
-+ unsigned char qret[4][4],cret[8];
-+ DES_LONG lqret[4];
-+ int num;
-+ char *str;
-+
-+ printf("Doing ecb\n");
-+ for (i=0; i<NUM_TESTS; i++)
-+ {
-+ if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0)
-+ {
-+ printf("Key error %2d:%d\n",i+1,j);
-+ err=1;
-+ }
-+ memcpy(in,plain_data[i],8);
-+ memset(out,0,8);
-+ memset(outin,0,8);
-+ des_ecb_encrypt((C_Block *)in,(C_Block *)out,ks,DES_ENCRYPT);
-+ des_ecb_encrypt((C_Block *)out,(C_Block *)outin,ks,DES_DECRYPT);
-+
-+ if (memcmp(out,cipher_data[i],8) != 0)
-+ {
-+ printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
-+ i+1,pt(key_data[i]),pt(in),pt(cipher_data[i]),
-+ pt(out));
-+ err=1;
-+ }
-+ if (memcmp(in,outin,8) != 0)
-+ {
-+ printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
-+ i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
-+ err=1;
-+ }
-+ }
-+
-+#ifndef LIBDES_LIT
-+ printf("Doing ede ecb\n");
-+ for (i=0; i<(NUM_TESTS-1); i++)
-+ {
-+ if ((j=des_key_sched((C_Block *)(key_data[i]),ks)) != 0)
-+ {
-+ err=1;
-+ printf("Key error %2d:%d\n",i+1,j);
-+ }
-+ if ((j=des_key_sched((C_Block *)(key_data[i+1]),ks2)) != 0)
-+ {
-+ printf("Key error %2d:%d\n",i+2,j);
-+ err=1;
-+ }
-+ if ((j=des_key_sched((C_Block *)(key_data[i+2]),ks3)) != 0)
-+ {
-+ printf("Key error %2d:%d\n",i+3,j);
-+ err=1;
-+ }
-+ memcpy(in,plain_data[i],8);
-+ memset(out,0,8);
-+ memset(outin,0,8);
-+ des_ecb2_encrypt((C_Block *)in,(C_Block *)out,ks,ks2,
-+ DES_ENCRYPT);
-+ des_ecb2_encrypt((C_Block *)out,(C_Block *)outin,ks,ks2,
-+ DES_DECRYPT);
-+
-+ if (memcmp(out,cipher_ecb2[i],8) != 0)
-+ {
-+ printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n",
-+ i+1,pt(key_data[i]),pt(in),pt(cipher_ecb2[i]),
-+ pt(out));
-+ err=1;
-+ }
-+ if (memcmp(in,outin,8) != 0)
-+ {
-+ printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n",
-+ i+1,pt(key_data[i]),pt(out),pt(in),pt(outin));
-+ err=1;
-+ }
-+ }
-+#endif
-+
-+ printf("Doing cbc\n");
-+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
-+ {
-+ printf("Key error %d\n",j);
-+ err=1;
-+ }
-+ memset(cbc_out,0,40);
-+ memset(cbc_in,0,40);
-+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
-+ des_ncbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
-+ (long)strlen((char *)cbc_data)+1,ks,
-+ (C_Block *)iv3,DES_ENCRYPT);
-+ if (memcmp(cbc_out,cbc_ok,32) != 0)
-+ printf("cbc_encrypt encrypt error\n");
-+
-+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
-+ des_ncbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
-+ (long)strlen((char *)cbc_data)+1,ks,
-+ (C_Block *)iv3,DES_DECRYPT);
-+ if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)) != 0)
-+ {
-+ printf("cbc_encrypt decrypt error\n");
-+ err=1;
-+ }
-+
-+#ifndef LIBDES_LIT
-+ printf("Doing desx cbc\n");
-+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
-+ {
-+ printf("Key error %d\n",j);
-+ err=1;
-+ }
-+ memset(cbc_out,0,40);
-+ memset(cbc_in,0,40);
-+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
-+ des_xcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
-+ (long)strlen((char *)cbc_data)+1,ks,
-+ (C_Block *)iv3,
-+ (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_ENCRYPT);
-+ if (memcmp(cbc_out,xcbc_ok,32) != 0)
-+ {
-+ printf("des_xcbc_encrypt encrypt error\n");
-+ }
-+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
-+ des_xcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
-+ (long)strlen((char *)cbc_data)+1,ks,
-+ (C_Block *)iv3,
-+ (C_Block *)cbc2_key, (C_Block *)cbc3_key, DES_DECRYPT);
-+ if (memcmp(cbc_in,cbc_data,strlen((char *)cbc_data)+1) != 0)
-+ {
-+ printf("des_xcbc_encrypt decrypt error\n");
-+ err=1;
-+ }
-+#endif
-+
-+ printf("Doing ede cbc\n");
-+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
-+ {
-+ printf("Key error %d\n",j);
-+ err=1;
-+ }
-+ if ((j=des_key_sched((C_Block *)cbc2_key,ks2)) != 0)
-+ {
-+ printf("Key error %d\n",j);
-+ err=1;
-+ }
-+ if ((j=des_key_sched((C_Block *)cbc3_key,ks3)) != 0)
-+ {
-+ printf("Key error %d\n",j);
-+ err=1;
-+ }
-+ memset(cbc_out,0,40);
-+ memset(cbc_in,0,40);
-+ i=strlen((char *)cbc_data)+1;
-+ /* i=((i+7)/8)*8; */
-+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
-+
-+ des_ede3_cbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
-+ 16L,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT);
-+ des_ede3_cbc_encrypt((C_Block *)&(cbc_data[16]),
-+ (C_Block *)&(cbc_out[16]),
-+ (long)i-16,ks,ks2,ks3,(C_Block *)iv3,DES_ENCRYPT);
-+ if (memcmp(cbc_out,cbc3_ok,
-+ (unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0)
-+ {
-+ printf("des_ede3_cbc_encrypt encrypt error\n");
-+ err=1;
-+ }
-+
-+ memcpy(iv3,cbc_iv,sizeof(cbc_iv));
-+ des_ede3_cbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
-+ (long)i,ks,ks2,ks3,(C_Block *)iv3,DES_DECRYPT);
-+ if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0)
-+ {
-+ printf("des_ede3_cbc_encrypt decrypt error\n");
-+ err=1;
-+ }
-+
-+#ifndef LIBDES_LIT
-+ printf("Doing pcbc\n");
-+ if ((j=des_key_sched((C_Block *)cbc_key,ks)) != 0)
-+ {
-+ printf("Key error %d\n",j);
-+ err=1;
-+ }
-+ memset(cbc_out,0,40);
-+ memset(cbc_in,0,40);
-+ des_pcbc_encrypt((C_Block *)cbc_data,(C_Block *)cbc_out,
-+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_ENCRYPT);
-+ if (memcmp(cbc_out,pcbc_ok,32) != 0)
-+ {
-+ printf("pcbc_encrypt encrypt error\n");
-+ err=1;
-+ }
-+ des_pcbc_encrypt((C_Block *)cbc_out,(C_Block *)cbc_in,
-+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,DES_DECRYPT);
-+ if (memcmp(cbc_in,cbc_data,strlen(cbc_data)+1) != 0)
-+ {
-+ printf("pcbc_encrypt decrypt error\n");
-+ err=1;
-+ }
-+
-+ printf("Doing ");
-+ printf("cfb8 ");
-+ err+=cfb_test(8,cfb_cipher8);
-+ printf("cfb16 ");
-+ err+=cfb_test(16,cfb_cipher16);
-+ printf("cfb32 ");
-+ err+=cfb_test(32,cfb_cipher32);
-+ printf("cfb48 ");
-+ err+=cfb_test(48,cfb_cipher48);
-+ printf("cfb64 ");
-+ err+=cfb_test(64,cfb_cipher64);
-+
-+ printf("cfb64() ");
-+ err+=cfb64_test(cfb_cipher64);
-+
-+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
-+ for (i=0; i<sizeof(plain); i++)
-+ des_cfb_encrypt(&(plain[i]),&(cfb_buf1[i]),
-+ 8,(long)1,ks,(C_Block *)cfb_tmp,DES_ENCRYPT);
-+ if (memcmp(cfb_cipher8,cfb_buf1,sizeof(plain)) != 0)
-+ {
-+ printf("cfb_encrypt small encrypt error\n");
-+ err=1;
-+ }
-+
-+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
-+ for (i=0; i<sizeof(plain); i++)
-+ des_cfb_encrypt(&(cfb_buf1[i]),&(cfb_buf2[i]),
-+ 8,(long)1,ks,(C_Block *)cfb_tmp,DES_DECRYPT);
-+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
-+ {
-+ printf("cfb_encrypt small decrypt error\n");
-+ err=1;
-+ }
-+
-+ printf("ede_cfb64() ");
-+ err+=ede_cfb64_test(cfb_cipher64);
-+
-+ printf("done\n");
-+
-+ printf("Doing ofb\n");
-+ des_key_sched((C_Block *)ofb_key,ks);
-+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
-+ des_ofb_encrypt(plain,ofb_buf1,64,(long)sizeof(plain)/8,ks,
-+ (C_Block *)ofb_tmp);
-+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
-+ {
-+ printf("ofb_encrypt encrypt error\n");
-+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
-+ofb_buf1[8+0], ofb_buf1[8+1], ofb_buf1[8+2], ofb_buf1[8+3],
-+ofb_buf1[8+4], ofb_buf1[8+5], ofb_buf1[8+6], ofb_buf1[8+7]);
-+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
-+ofb_buf1[8+0], ofb_cipher[8+1], ofb_cipher[8+2], ofb_cipher[8+3],
-+ofb_buf1[8+4], ofb_cipher[8+5], ofb_cipher[8+6], ofb_cipher[8+7]);
-+ err=1;
-+ }
-+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
-+ des_ofb_encrypt(ofb_buf1,ofb_buf2,64,(long)sizeof(ofb_buf1)/8,ks,
-+ (C_Block *)ofb_tmp);
-+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
-+ {
-+ printf("ofb_encrypt decrypt error\n");
-+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
-+ofb_buf2[8+0], ofb_buf2[8+1], ofb_buf2[8+2], ofb_buf2[8+3],
-+ofb_buf2[8+4], ofb_buf2[8+5], ofb_buf2[8+6], ofb_buf2[8+7]);
-+printf("%02X %02X %02X %02X %02X %02X %02X %02X\n",
-+plain[8+0], plain[8+1], plain[8+2], plain[8+3],
-+plain[8+4], plain[8+5], plain[8+6], plain[8+7]);
-+ err=1;
-+ }
-+
-+ printf("Doing ofb64\n");
-+ des_key_sched((C_Block *)ofb_key,ks);
-+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
-+ memset(ofb_buf1,0,sizeof(ofb_buf1));
-+ memset(ofb_buf2,0,sizeof(ofb_buf1));
-+ num=0;
-+ for (i=0; i<sizeof(plain); i++)
-+ {
-+ des_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,
-+ (C_Block *)ofb_tmp,&num);
-+ }
-+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
-+ {
-+ printf("ofb64_encrypt encrypt error\n");
-+ err=1;
-+ }
-+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
-+ num=0;
-+ des_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
-+ (C_Block *)ofb_tmp,&num);
-+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
-+ {
-+ printf("ofb64_encrypt decrypt error\n");
-+ err=1;
-+ }
-+
-+ printf("Doing ede_ofb64\n");
-+ des_key_sched((C_Block *)ofb_key,ks);
-+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
-+ memset(ofb_buf1,0,sizeof(ofb_buf1));
-+ memset(ofb_buf2,0,sizeof(ofb_buf1));
-+ num=0;
-+ for (i=0; i<sizeof(plain); i++)
-+ {
-+ des_ede3_ofb64_encrypt(&(plain[i]),&(ofb_buf1[i]),1,ks,ks,ks,
-+ (C_Block *)ofb_tmp,&num);
-+ }
-+ if (memcmp(ofb_cipher,ofb_buf1,sizeof(ofb_buf1)) != 0)
-+ {
-+ printf("ede_ofb64_encrypt encrypt error\n");
-+ err=1;
-+ }
-+ memcpy(ofb_tmp,ofb_iv,sizeof(ofb_iv));
-+ num=0;
-+ des_ede3_ofb64_encrypt(ofb_buf1,ofb_buf2,(long)sizeof(ofb_buf1),ks,
-+ ks,ks,(C_Block *)ofb_tmp,&num);
-+ if (memcmp(plain,ofb_buf2,sizeof(ofb_buf2)) != 0)
-+ {
-+ printf("ede_ofb64_encrypt decrypt error\n");
-+ err=1;
-+ }
-+
-+ printf("Doing cbc_cksum\n");
-+ des_key_sched((C_Block *)cbc_key,ks);
-+ cs=des_cbc_cksum((C_Block *)cbc_data,(C_Block *)cret,
-+ (long)strlen(cbc_data),ks,(C_Block *)cbc_iv);
-+ if (cs != cbc_cksum_ret)
-+ {
-+ printf("bad return value (%08lX), should be %08lX\n",
-+ (unsigned long)cs,(unsigned long)cbc_cksum_ret);
-+ err=1;
-+ }
-+ if (memcmp(cret,cbc_cksum_data,8) != 0)
-+ {
-+ printf("bad cbc_cksum block returned\n");
-+ err=1;
-+ }
-+
-+ printf("Doing quad_cksum\n");
-+ cs=quad_cksum((C_Block *)cbc_data,(C_Block *)qret,
-+ (long)strlen(cbc_data),2,(C_Block *)cbc_iv);
-+ for (i=0; i<4; i++)
-+ {
-+ lqret[i]=0;
-+ memcpy(&(lqret[i]),&(qret[i][0]),4);
-+ }
-+ { /* Big-endian fix */
-+ static DES_LONG l=1;
-+ static unsigned char *c=(unsigned char *)&l;
-+ DES_LONG ll;
-+
-+ if (!c[0])
-+ {
-+ ll=lqret[0]^lqret[3];
-+ lqret[0]^=ll;
-+ lqret[3]^=ll;
-+ ll=lqret[1]^lqret[2];
-+ lqret[1]^=ll;
-+ lqret[2]^=ll;
-+ }
-+ }
-+ if (cs != 0x70d7a63aL)
-+ {
-+ printf("quad_cksum error, ret %08lx should be 70d7a63a\n",
-+ (unsigned long)cs);
-+ err=1;
-+ }
-+ if (lqret[0] != 0x327eba8dL)
-+ {
-+ printf("quad_cksum error, out[0] %08lx is not %08lx\n",
-+ (unsigned long)lqret[0],0x327eba8dL);
-+ err=1;
-+ }
-+ if (lqret[1] != 0x201a49ccL)
-+ {
-+ printf("quad_cksum error, out[1] %08lx is not %08lx\n",
-+ (unsigned long)lqret[1],0x201a49ccL);
-+ err=1;
-+ }
-+ if (lqret[2] != 0x70d7a63aL)
-+ {
-+ printf("quad_cksum error, out[2] %08lx is not %08lx\n",
-+ (unsigned long)lqret[2],0x70d7a63aL);
-+ err=1;
-+ }
-+ if (lqret[3] != 0x501c2c26L)
-+ {
-+ printf("quad_cksum error, out[3] %08lx is not %08lx\n",
-+ (unsigned long)lqret[3],0x501c2c26L);
-+ err=1;
-+ }
-+#endif
-+
-+ printf("input word alignment test");
-+ for (i=0; i<4; i++)
-+ {
-+ printf(" %d",i);
-+ des_ncbc_encrypt((C_Block *)&(cbc_out[i]),(C_Block *)cbc_in,
-+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,
-+ DES_ENCRYPT);
-+ }
-+ printf("\noutput word alignment test");
-+ for (i=0; i<4; i++)
-+ {
-+ printf(" %d",i);
-+ des_ncbc_encrypt((C_Block *)cbc_out,(C_Block *)&(cbc_in[i]),
-+ (long)strlen(cbc_data)+1,ks,(C_Block *)cbc_iv,
-+ DES_ENCRYPT);
-+ }
-+ printf("\n");
-+ printf("fast crypt test ");
-+ str=crypt("testing","ef");
-+ if (strcmp("efGnQx2725bI2",str) != 0)
-+ {
-+ printf("fast crypt error, %s should be efGnQx2725bI2\n",str);
-+ err=1;
-+ }
-+ str=crypt("bca76;23","yA");
-+ if (strcmp("yA1Rp/1hZXIJk",str) != 0)
-+ {
-+ printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n",str);
-+ err=1;
-+ }
-+ printf("\n");
-+ exit(err);
-+ return(0);
-+ }
-+
-+static char *pt(p)
-+unsigned char *p;
-+ {
-+ static char bufs[10][20];
-+ static int bnum=0;
-+ char *ret;
-+ int i;
-+ static char *f="0123456789ABCDEF";
-+
-+ ret= &(bufs[bnum++][0]);
-+ bnum%=10;
-+ for (i=0; i<8; i++)
-+ {
-+ ret[i*2]=f[(p[i]>>4)&0xf];
-+ ret[i*2+1]=f[p[i]&0xf];
-+ }
-+ ret[16]='\0';
-+ return(ret);
-+ }
-+
-+#ifndef LIBDES_LIT
-+
-+static int cfb_test(bits, cfb_cipher)
-+int bits;
-+unsigned char *cfb_cipher;
-+ {
-+ des_key_schedule ks;
-+ int i,err=0;
-+
-+ des_key_sched((C_Block *)cfb_key,ks);
-+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
-+ des_cfb_encrypt(plain,cfb_buf1,bits,(long)sizeof(plain),ks,
-+ (C_Block *)cfb_tmp,DES_ENCRYPT);
-+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
-+ {
-+ err=1;
-+ printf("cfb_encrypt encrypt error\n");
-+ for (i=0; i<24; i+=8)
-+ printf("%s\n",pt(&(cfb_buf1[i])));
-+ }
-+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
-+ des_cfb_encrypt(cfb_buf1,cfb_buf2,bits,(long)sizeof(plain),ks,
-+ (C_Block *)cfb_tmp,DES_DECRYPT);
-+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
-+ {
-+ err=1;
-+ printf("cfb_encrypt decrypt error\n");
-+ for (i=0; i<24; i+=8)
-+ printf("%s\n",pt(&(cfb_buf1[i])));
-+ }
-+ return(err);
-+ }
-+
-+static int cfb64_test(cfb_cipher)
-+unsigned char *cfb_cipher;
-+ {
-+ des_key_schedule ks;
-+ int err=0,i,n;
-+
-+ des_key_sched((C_Block *)cfb_key,ks);
-+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
-+ n=0;
-+ des_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,
-+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
-+ des_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
-+ (long)sizeof(plain)-12,ks,
-+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
-+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
-+ {
-+ err=1;
-+ printf("cfb_encrypt encrypt error\n");
-+ for (i=0; i<24; i+=8)
-+ printf("%s\n",pt(&(cfb_buf1[i])));
-+ }
-+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
-+ n=0;
-+ des_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,
-+ (C_Block *)cfb_tmp,&n,DES_DECRYPT);
-+ des_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
-+ (long)sizeof(plain)-17,ks,
-+ (C_Block *)cfb_tmp,&n,DES_DECRYPT);
-+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
-+ {
-+ err=1;
-+ printf("cfb_encrypt decrypt error\n");
-+ for (i=0; i<24; i+=8)
-+ printf("%s\n",pt(&(cfb_buf2[i])));
-+ }
-+ return(err);
-+ }
-+
-+static int ede_cfb64_test(cfb_cipher)
-+unsigned char *cfb_cipher;
-+ {
-+ des_key_schedule ks;
-+ int err=0,i,n;
-+
-+ des_key_sched((C_Block *)cfb_key,ks);
-+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
-+ n=0;
-+ des_ede3_cfb64_encrypt(plain,cfb_buf1,(long)12,ks,ks,ks,
-+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
-+ des_ede3_cfb64_encrypt(&(plain[12]),&(cfb_buf1[12]),
-+ (long)sizeof(plain)-12,ks,ks,ks,
-+ (C_Block *)cfb_tmp,&n,DES_ENCRYPT);
-+ if (memcmp(cfb_cipher,cfb_buf1,sizeof(plain)) != 0)
-+ {
-+ err=1;
-+ printf("ede_cfb_encrypt encrypt error\n");
-+ for (i=0; i<24; i+=8)
-+ printf("%s\n",pt(&(cfb_buf1[i])));
-+ }
-+ memcpy(cfb_tmp,cfb_iv,sizeof(cfb_iv));
-+ n=0;
-+ des_ede3_cfb64_encrypt(cfb_buf1,cfb_buf2,(long)17,ks,ks,ks,
-+ (C_Block *)cfb_tmp,&n,DES_DECRYPT);
-+ des_ede3_cfb64_encrypt(&(cfb_buf1[17]),&(cfb_buf2[17]),
-+ (long)sizeof(plain)-17,ks,ks,ks,
-+ (C_Block *)cfb_tmp,&n,DES_DECRYPT);
-+ if (memcmp(plain,cfb_buf2,sizeof(plain)) != 0)
-+ {
-+ err=1;
-+ printf("ede_cfb_encrypt decrypt error\n");
-+ for (i=0; i<24; i+=8)
-+ printf("%s\n",pt(&(cfb_buf2[i])));
-+ }
-+ return(err);
-+ }
-+
-+#endif
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/dx86unix.S Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,3160 @@
-+/*
-+ * This file was originally generated by Michael Richardson <mcr@freeswan.org>
-+ * via the perl scripts found in the ASM subdir. It remains copyright of
-+ * Eric Young, see the file COPYRIGHT.
-+ *
-+ * This was last done on October 9, 2002.
-+ *
-+ * While this file does not need to go through cpp, we pass it through
-+ * CPP by naming it dx86unix.S instead of dx86unix.s because there is
-+ * a bug in Rules.make for .s builds - specifically it references EXTRA_CFLAGS
-+ * which may contain stuff that AS doesn't understand instead of
-+ * referencing EXTRA_AFLAGS.
-+ */
-+
-+ .file "dx86unix.S"
-+ .version "01.01"
-+.text
-+ .align 16
-+.globl des_encrypt
-+ .type des_encrypt , @function
-+des_encrypt:
-+ pushl %esi
-+ pushl %edi
-+
-+
-+ movl 12(%esp), %esi
-+ xorl %ecx, %ecx
-+ pushl %ebx
-+ pushl %ebp
-+ movl (%esi), %eax
-+ movl 28(%esp), %ebx
-+ movl 4(%esi), %edi
-+
-+
-+ roll $4, %eax
-+ movl %eax, %esi
-+ xorl %edi, %eax
-+ andl $0xf0f0f0f0, %eax
-+ xorl %eax, %esi
-+ xorl %eax, %edi
-+
-+ roll $20, %edi
-+ movl %edi, %eax
-+ xorl %esi, %edi
-+ andl $0xfff0000f, %edi
-+ xorl %edi, %eax
-+ xorl %edi, %esi
-+
-+ roll $14, %eax
-+ movl %eax, %edi
-+ xorl %esi, %eax
-+ andl $0x33333333, %eax
-+ xorl %eax, %edi
-+ xorl %eax, %esi
-+
-+ roll $22, %esi
-+ movl %esi, %eax
-+ xorl %edi, %esi
-+ andl $0x03fc03fc, %esi
-+ xorl %esi, %eax
-+ xorl %esi, %edi
-+
-+ roll $9, %eax
-+ movl %eax, %esi
-+ xorl %edi, %eax
-+ andl $0xaaaaaaaa, %eax
-+ xorl %eax, %esi
-+ xorl %eax, %edi
-+
-+.byte 209
-+.byte 199
-+ movl 24(%esp), %ebp
-+ cmpl $0, %ebx
-+ je .L000start_decrypt
-+
-+
-+ movl (%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 4(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 8(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 12(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 16(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 20(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 24(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 28(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 32(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 36(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 40(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 44(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 48(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 52(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 56(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 60(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 64(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 68(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 72(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 76(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 80(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 84(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 88(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 92(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 96(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 100(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 104(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 108(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 112(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 116(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 120(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 124(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+ jmp .L001end
-+.L000start_decrypt:
-+
-+
-+ movl 120(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 124(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 112(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 116(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 104(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 108(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 96(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 100(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 88(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 92(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 80(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 84(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 72(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 76(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 64(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 68(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 56(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 60(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 48(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 52(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 40(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 44(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 32(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 36(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 24(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 28(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 16(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 20(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 8(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 12(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl (%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 4(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+.L001end:
-+
-+
-+ movl 20(%esp), %edx
-+.byte 209
-+.byte 206
-+ movl %edi, %eax
-+ xorl %esi, %edi
-+ andl $0xaaaaaaaa, %edi
-+ xorl %edi, %eax
-+ xorl %edi, %esi
-+
-+ roll $23, %eax
-+ movl %eax, %edi
-+ xorl %esi, %eax
-+ andl $0x03fc03fc, %eax
-+ xorl %eax, %edi
-+ xorl %eax, %esi
-+
-+ roll $10, %edi
-+ movl %edi, %eax
-+ xorl %esi, %edi
-+ andl $0x33333333, %edi
-+ xorl %edi, %eax
-+ xorl %edi, %esi
-+
-+ roll $18, %esi
-+ movl %esi, %edi
-+ xorl %eax, %esi
-+ andl $0xfff0000f, %esi
-+ xorl %esi, %edi
-+ xorl %esi, %eax
-+
-+ roll $12, %edi
-+ movl %edi, %esi
-+ xorl %eax, %edi
-+ andl $0xf0f0f0f0, %edi
-+ xorl %edi, %esi
-+ xorl %edi, %eax
-+
-+ rorl $4, %eax
-+ movl %eax, (%edx)
-+ movl %esi, 4(%edx)
-+ popl %ebp
-+ popl %ebx
-+ popl %edi
-+ popl %esi
-+ ret
-+.des_encrypt_end:
-+ .size des_encrypt , .des_encrypt_end-des_encrypt
-+.ident "desasm.pl"
-+.text
-+ .align 16
-+.globl des_encrypt2
-+ .type des_encrypt2 , @function
-+des_encrypt2:
-+ pushl %esi
-+ pushl %edi
-+
-+
-+ movl 12(%esp), %eax
-+ xorl %ecx, %ecx
-+ pushl %ebx
-+ pushl %ebp
-+ movl (%eax), %esi
-+ movl 28(%esp), %ebx
-+ roll $3, %esi
-+ movl 4(%eax), %edi
-+ roll $3, %edi
-+ movl 24(%esp), %ebp
-+ cmpl $0, %ebx
-+ je .L002start_decrypt
-+
-+
-+ movl (%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 4(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 8(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 12(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 16(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 20(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 24(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 28(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 32(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 36(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 40(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 44(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 48(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 52(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 56(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 60(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 64(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 68(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 72(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 76(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 80(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 84(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 88(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 92(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 96(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 100(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 104(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 108(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 112(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 116(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 120(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 124(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+ jmp .L003end
-+.L002start_decrypt:
-+
-+
-+ movl 120(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 124(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 112(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 116(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 104(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 108(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 96(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 100(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 88(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 92(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 80(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 84(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 72(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 76(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 64(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 68(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 56(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 60(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 48(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 52(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 40(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 44(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 32(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 36(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 24(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 28(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl 16(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 20(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+
-+
-+ movl 8(%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 12(%ebp), %edx
-+ xorl %esi, %eax
-+ xorl %esi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %edi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %edi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %edi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %edi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %edi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %edi
-+
-+
-+ movl (%ebp), %eax
-+ xorl %ebx, %ebx
-+ movl 4(%ebp), %edx
-+ xorl %edi, %eax
-+ xorl %edi, %edx
-+ andl $0xfcfcfcfc, %eax
-+ andl $0xcfcfcfcf, %edx
-+ movb %al, %bl
-+ movb %ah, %cl
-+ rorl $4, %edx
-+ movl des_SPtrans(%ebx),%ebp
-+ movb %dl, %bl
-+ xorl %ebp, %esi
-+ movl 0x200+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movb %dh, %cl
-+ shrl $16, %eax
-+ movl 0x100+des_SPtrans(%ebx),%ebp
-+ xorl %ebp, %esi
-+ movb %ah, %bl
-+ shrl $16, %edx
-+ movl 0x300+des_SPtrans(%ecx),%ebp
-+ xorl %ebp, %esi
-+ movl 24(%esp), %ebp
-+ movb %dh, %cl
-+ andl $0xff, %eax
-+ andl $0xff, %edx
-+ movl 0x600+des_SPtrans(%ebx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x700+des_SPtrans(%ecx),%ebx
-+ xorl %ebx, %esi
-+ movl 0x400+des_SPtrans(%eax),%ebx
-+ xorl %ebx, %esi
-+ movl 0x500+des_SPtrans(%edx),%ebx
-+ xorl %ebx, %esi
-+.L003end:
-+
-+
-+ rorl $3, %edi
-+ movl 20(%esp), %eax
-+ rorl $3, %esi
-+ movl %edi, (%eax)
-+ movl %esi, 4(%eax)
-+ popl %ebp
-+ popl %ebx
-+ popl %edi
-+ popl %esi
-+ ret
-+.des_encrypt2_end:
-+ .size des_encrypt2 , .des_encrypt2_end-des_encrypt2
-+.ident "desasm.pl"
-+.text
-+ .align 16
-+.globl des_encrypt3
-+ .type des_encrypt3 , @function
-+des_encrypt3:
-+ pushl %ebx
-+ movl 8(%esp), %ebx
-+ pushl %ebp
-+ pushl %esi
-+ pushl %edi
-+
-+
-+ movl (%ebx), %edi
-+ movl 4(%ebx), %esi
-+ subl $12, %esp
-+
-+
-+ roll $4, %edi
-+ movl %edi, %edx
-+ xorl %esi, %edi
-+ andl $0xf0f0f0f0, %edi
-+ xorl %edi, %edx
-+ xorl %edi, %esi
-+
-+ roll $20, %esi
-+ movl %esi, %edi
-+ xorl %edx, %esi
-+ andl $0xfff0000f, %esi
-+ xorl %esi, %edi
-+ xorl %esi, %edx
-+
-+ roll $14, %edi
-+ movl %edi, %esi
-+ xorl %edx, %edi
-+ andl $0x33333333, %edi
-+ xorl %edi, %esi
-+ xorl %edi, %edx
-+
-+ roll $22, %edx
-+ movl %edx, %edi
-+ xorl %esi, %edx
-+ andl $0x03fc03fc, %edx
-+ xorl %edx, %edi
-+ xorl %edx, %esi
-+
-+ roll $9, %edi
-+ movl %edi, %edx
-+ xorl %esi, %edi
-+ andl $0xaaaaaaaa, %edi
-+ xorl %edi, %edx
-+ xorl %edi, %esi
-+
-+ rorl $3, %edx
-+ rorl $2, %esi
-+ movl %esi, 4(%ebx)
-+ movl 36(%esp), %eax
-+ movl %edx, (%ebx)
-+ movl 40(%esp), %edi
-+ movl 44(%esp), %esi
-+ movl $1, 8(%esp)
-+ movl %eax, 4(%esp)
-+ movl %ebx, (%esp)
-+ call des_encrypt2
-+ movl $0, 8(%esp)
-+ movl %edi, 4(%esp)
-+ movl %ebx, (%esp)
-+ call des_encrypt2
-+ movl $1, 8(%esp)
-+ movl %esi, 4(%esp)
-+ movl %ebx, (%esp)
-+ call des_encrypt2
-+ addl $12, %esp
-+ movl (%ebx), %edi
-+ movl 4(%ebx), %esi
-+
-+
-+ roll $2, %esi
-+ roll $3, %edi
-+ movl %edi, %eax
-+ xorl %esi, %edi
-+ andl $0xaaaaaaaa, %edi
-+ xorl %edi, %eax
-+ xorl %edi, %esi
-+
-+ roll $23, %eax
-+ movl %eax, %edi
-+ xorl %esi, %eax
-+ andl $0x03fc03fc, %eax
-+ xorl %eax, %edi
-+ xorl %eax, %esi
-+
-+ roll $10, %edi
-+ movl %edi, %eax
-+ xorl %esi, %edi
-+ andl $0x33333333, %edi
-+ xorl %edi, %eax
-+ xorl %edi, %esi
-+
-+ roll $18, %esi
-+ movl %esi, %edi
-+ xorl %eax, %esi
-+ andl $0xfff0000f, %esi
-+ xorl %esi, %edi
-+ xorl %esi, %eax
-+
-+ roll $12, %edi
-+ movl %edi, %esi
-+ xorl %eax, %edi
-+ andl $0xf0f0f0f0, %edi
-+ xorl %edi, %esi
-+ xorl %edi, %eax
-+
-+ rorl $4, %eax
-+ movl %eax, (%ebx)
-+ movl %esi, 4(%ebx)
-+ popl %edi
-+ popl %esi
-+ popl %ebp
-+ popl %ebx
-+ ret
-+.des_encrypt3_end:
-+ .size des_encrypt3 , .des_encrypt3_end-des_encrypt3
-+.ident "desasm.pl"
-+.text
-+ .align 16
-+.globl des_decrypt3
-+ .type des_decrypt3 , @function
-+des_decrypt3:
-+ pushl %ebx
-+ movl 8(%esp), %ebx
-+ pushl %ebp
-+ pushl %esi
-+ pushl %edi
-+
-+
-+ movl (%ebx), %edi
-+ movl 4(%ebx), %esi
-+ subl $12, %esp
-+
-+
-+ roll $4, %edi
-+ movl %edi, %edx
-+ xorl %esi, %edi
-+ andl $0xf0f0f0f0, %edi
-+ xorl %edi, %edx
-+ xorl %edi, %esi
-+
-+ roll $20, %esi
-+ movl %esi, %edi
-+ xorl %edx, %esi
-+ andl $0xfff0000f, %esi
-+ xorl %esi, %edi
-+ xorl %esi, %edx
-+
-+ roll $14, %edi
-+ movl %edi, %esi
-+ xorl %edx, %edi
-+ andl $0x33333333, %edi
-+ xorl %edi, %esi
-+ xorl %edi, %edx
-+
-+ roll $22, %edx
-+ movl %edx, %edi
-+ xorl %esi, %edx
-+ andl $0x03fc03fc, %edx
-+ xorl %edx, %edi
-+ xorl %edx, %esi
-+
-+ roll $9, %edi
-+ movl %edi, %edx
-+ xorl %esi, %edi
-+ andl $0xaaaaaaaa, %edi
-+ xorl %edi, %edx
-+ xorl %edi, %esi
-+
-+ rorl $3, %edx
-+ rorl $2, %esi
-+ movl %esi, 4(%ebx)
-+ movl 36(%esp), %esi
-+ movl %edx, (%ebx)
-+ movl 40(%esp), %edi
-+ movl 44(%esp), %eax
-+ movl $0, 8(%esp)
-+ movl %eax, 4(%esp)
-+ movl %ebx, (%esp)
-+ call des_encrypt2
-+ movl $1, 8(%esp)
-+ movl %edi, 4(%esp)
-+ movl %ebx, (%esp)
-+ call des_encrypt2
-+ movl $0, 8(%esp)
-+ movl %esi, 4(%esp)
-+ movl %ebx, (%esp)
-+ call des_encrypt2
-+ addl $12, %esp
-+ movl (%ebx), %edi
-+ movl 4(%ebx), %esi
-+
-+
-+ roll $2, %esi
-+ roll $3, %edi
-+ movl %edi, %eax
-+ xorl %esi, %edi
-+ andl $0xaaaaaaaa, %edi
-+ xorl %edi, %eax
-+ xorl %edi, %esi
-+
-+ roll $23, %eax
-+ movl %eax, %edi
-+ xorl %esi, %eax
-+ andl $0x03fc03fc, %eax
-+ xorl %eax, %edi
-+ xorl %eax, %esi
-+
-+ roll $10, %edi
-+ movl %edi, %eax
-+ xorl %esi, %edi
-+ andl $0x33333333, %edi
-+ xorl %edi, %eax
-+ xorl %edi, %esi
-+
-+ roll $18, %esi
-+ movl %esi, %edi
-+ xorl %eax, %esi
-+ andl $0xfff0000f, %esi
-+ xorl %esi, %edi
-+ xorl %esi, %eax
-+
-+ roll $12, %edi
-+ movl %edi, %esi
-+ xorl %eax, %edi
-+ andl $0xf0f0f0f0, %edi
-+ xorl %edi, %esi
-+ xorl %edi, %eax
-+
-+ rorl $4, %eax
-+ movl %eax, (%ebx)
-+ movl %esi, 4(%ebx)
-+ popl %edi
-+ popl %esi
-+ popl %ebp
-+ popl %ebx
-+ ret
-+.des_decrypt3_end:
-+ .size des_decrypt3 , .des_decrypt3_end-des_decrypt3
-+.ident "desasm.pl"
-+.text
-+ .align 16
-+.globl des_ncbc_encrypt
-+ .type des_ncbc_encrypt , @function
-+des_ncbc_encrypt:
-+
-+ pushl %ebp
-+ pushl %ebx
-+ pushl %esi
-+ pushl %edi
-+ movl 28(%esp), %ebp
-+
-+ movl 36(%esp), %ebx
-+ movl (%ebx), %esi
-+ movl 4(%ebx), %edi
-+ pushl %edi
-+ pushl %esi
-+ pushl %edi
-+ pushl %esi
-+ movl %esp, %ebx
-+ movl 36(%esp), %esi
-+ movl 40(%esp), %edi
-+
-+ movl 56(%esp), %ecx
-+
-+ pushl %ecx
-+
-+ movl 52(%esp), %eax
-+ pushl %eax
-+ pushl %ebx
-+ cmpl $0, %ecx
-+ jz .L004decrypt
-+ andl $4294967288, %ebp
-+ movl 12(%esp), %eax
-+ movl 16(%esp), %ebx
-+ jz .L005encrypt_finish
-+.L006encrypt_loop:
-+ movl (%esi), %ecx
-+ movl 4(%esi), %edx
-+ xorl %ecx, %eax
-+ xorl %edx, %ebx
-+ movl %eax, 12(%esp)
-+ movl %ebx, 16(%esp)
-+ call des_encrypt
-+ movl 12(%esp), %eax
-+ movl 16(%esp), %ebx
-+ movl %eax, (%edi)
-+ movl %ebx, 4(%edi)
-+ addl $8, %esi
-+ addl $8, %edi
-+ subl $8, %ebp
-+ jnz .L006encrypt_loop
-+.L005encrypt_finish:
-+ movl 56(%esp), %ebp
-+ andl $7, %ebp
-+ jz .L007finish
-+ xorl %ecx, %ecx
-+ xorl %edx, %edx
-+ movl .L008cbc_enc_jmp_table(,%ebp,4),%ebp
-+ jmp *%ebp
-+.L009ej7:
-+ movb 6(%esi), %dh
-+ sall $8, %edx
-+.L010ej6:
-+ movb 5(%esi), %dh
-+.L011ej5:
-+ movb 4(%esi), %dl
-+.L012ej4:
-+ movl (%esi), %ecx
-+ jmp .L013ejend
-+.L014ej3:
-+ movb 2(%esi), %ch
-+ sall $8, %ecx
-+.L015ej2:
-+ movb 1(%esi), %ch
-+.L016ej1:
-+ movb (%esi), %cl
-+.L013ejend:
-+ xorl %ecx, %eax
-+ xorl %edx, %ebx
-+ movl %eax, 12(%esp)
-+ movl %ebx, 16(%esp)
-+ call des_encrypt
-+ movl 12(%esp), %eax
-+ movl 16(%esp), %ebx
-+ movl %eax, (%edi)
-+ movl %ebx, 4(%edi)
-+ jmp .L007finish
-+.align 16
-+.L004decrypt:
-+ andl $4294967288, %ebp
-+ movl 20(%esp), %eax
-+ movl 24(%esp), %ebx
-+ jz .L017decrypt_finish
-+.L018decrypt_loop:
-+ movl (%esi), %eax
-+ movl 4(%esi), %ebx
-+ movl %eax, 12(%esp)
-+ movl %ebx, 16(%esp)
-+ call des_encrypt
-+ movl 12(%esp), %eax
-+ movl 16(%esp), %ebx
-+ movl 20(%esp), %ecx
-+ movl 24(%esp), %edx
-+ xorl %eax, %ecx
-+ xorl %ebx, %edx
-+ movl (%esi), %eax
-+ movl 4(%esi), %ebx
-+ movl %ecx, (%edi)
-+ movl %edx, 4(%edi)
-+ movl %eax, 20(%esp)
-+ movl %ebx, 24(%esp)
-+ addl $8, %esi
-+ addl $8, %edi
-+ subl $8, %ebp
-+ jnz .L018decrypt_loop
-+.L017decrypt_finish:
-+ movl 56(%esp), %ebp
-+ andl $7, %ebp
-+ jz .L007finish
-+ movl (%esi), %eax
-+ movl 4(%esi), %ebx
-+ movl %eax, 12(%esp)
-+ movl %ebx, 16(%esp)
-+ call des_encrypt
-+ movl 12(%esp), %eax
-+ movl 16(%esp), %ebx
-+ movl 20(%esp), %ecx
-+ movl 24(%esp), %edx
-+ xorl %eax, %ecx
-+ xorl %ebx, %edx
-+ movl (%esi), %eax
-+ movl 4(%esi), %ebx
-+.L019dj7:
-+ rorl $16, %edx
-+ movb %dl, 6(%edi)
-+ shrl $16, %edx
-+.L020dj6:
-+ movb %dh, 5(%edi)
-+.L021dj5:
-+ movb %dl, 4(%edi)
-+.L022dj4:
-+ movl %ecx, (%edi)
-+ jmp .L023djend
-+.L024dj3:
-+ rorl $16, %ecx
-+ movb %cl, 2(%edi)
-+ sall $16, %ecx
-+.L025dj2:
-+ movb %ch, 1(%esi)
-+.L026dj1:
-+ movb %cl, (%esi)
-+.L023djend:
-+ jmp .L007finish
-+.align 16
-+.L007finish:
-+ movl 64(%esp), %ecx
-+ addl $28, %esp
-+ movl %eax, (%ecx)
-+ movl %ebx, 4(%ecx)
-+ popl %edi
-+ popl %esi
-+ popl %ebx
-+ popl %ebp
-+ ret
-+.align 16
-+.L008cbc_enc_jmp_table:
-+ .long 0
-+ .long .L016ej1
-+ .long .L015ej2
-+ .long .L014ej3
-+ .long .L012ej4
-+ .long .L011ej5
-+ .long .L010ej6
-+ .long .L009ej7
-+.align 16
-+.L027cbc_dec_jmp_table:
-+ .long 0
-+ .long .L026dj1
-+ .long .L025dj2
-+ .long .L024dj3
-+ .long .L022dj4
-+ .long .L021dj5
-+ .long .L020dj6
-+ .long .L019dj7
-+.des_ncbc_encrypt_end:
-+ .size des_ncbc_encrypt , .des_ncbc_encrypt_end-des_ncbc_encrypt
-+.ident "desasm.pl"
-+.text
-+ .align 16
-+.globl des_ede3_cbc_encrypt
-+ .type des_ede3_cbc_encrypt , @function
-+des_ede3_cbc_encrypt:
-+
-+ pushl %ebp
-+ pushl %ebx
-+ pushl %esi
-+ pushl %edi
-+ movl 28(%esp), %ebp
-+
-+ movl 44(%esp), %ebx
-+ movl (%ebx), %esi
-+ movl 4(%ebx), %edi
-+ pushl %edi
-+ pushl %esi
-+ pushl %edi
-+ pushl %esi
-+ movl %esp, %ebx
-+ movl 36(%esp), %esi
-+ movl 40(%esp), %edi
-+
-+ movl 64(%esp), %ecx
-+
-+ movl 56(%esp), %eax
-+ pushl %eax
-+
-+ movl 56(%esp), %eax
-+ pushl %eax
-+
-+ movl 56(%esp), %eax
-+ pushl %eax
-+ pushl %ebx
-+ cmpl $0, %ecx
-+ jz .L028decrypt
-+ andl $4294967288, %ebp
-+ movl 16(%esp), %eax
-+ movl 20(%esp), %ebx
-+ jz .L029encrypt_finish
-+.L030encrypt_loop:
-+ movl (%esi), %ecx
-+ movl 4(%esi), %edx
-+ xorl %ecx, %eax
-+ xorl %edx, %ebx
-+ movl %eax, 16(%esp)
-+ movl %ebx, 20(%esp)
-+ call des_encrypt3
-+ movl 16(%esp), %eax
-+ movl 20(%esp), %ebx
-+ movl %eax, (%edi)
-+ movl %ebx, 4(%edi)
-+ addl $8, %esi
-+ addl $8, %edi
-+ subl $8, %ebp
-+ jnz .L030encrypt_loop
-+.L029encrypt_finish:
-+ movl 60(%esp), %ebp
-+ andl $7, %ebp
-+ jz .L031finish
-+ xorl %ecx, %ecx
-+ xorl %edx, %edx
-+ movl .L032cbc_enc_jmp_table(,%ebp,4),%ebp
-+ jmp *%ebp
-+.L033ej7:
-+ movb 6(%esi), %dh
-+ sall $8, %edx
-+.L034ej6:
-+ movb 5(%esi), %dh
-+.L035ej5:
-+ movb 4(%esi), %dl
-+.L036ej4:
-+ movl (%esi), %ecx
-+ jmp .L037ejend
-+.L038ej3:
-+ movb 2(%esi), %ch
-+ sall $8, %ecx
-+.L039ej2:
-+ movb 1(%esi), %ch
-+.L040ej1:
-+ movb (%esi), %cl
-+.L037ejend:
-+ xorl %ecx, %eax
-+ xorl %edx, %ebx
-+ movl %eax, 16(%esp)
-+ movl %ebx, 20(%esp)
-+ call des_encrypt3
-+ movl 16(%esp), %eax
-+ movl 20(%esp), %ebx
-+ movl %eax, (%edi)
-+ movl %ebx, 4(%edi)
-+ jmp .L031finish
-+.align 16
-+.L028decrypt:
-+ andl $4294967288, %ebp
-+ movl 24(%esp), %eax
-+ movl 28(%esp), %ebx
-+ jz .L041decrypt_finish
-+.L042decrypt_loop:
-+ movl (%esi), %eax
-+ movl 4(%esi), %ebx
-+ movl %eax, 16(%esp)
-+ movl %ebx, 20(%esp)
-+ call des_decrypt3
-+ movl 16(%esp), %eax
-+ movl 20(%esp), %ebx
-+ movl 24(%esp), %ecx
-+ movl 28(%esp), %edx
-+ xorl %eax, %ecx
-+ xorl %ebx, %edx
-+ movl (%esi), %eax
-+ movl 4(%esi), %ebx
-+ movl %ecx, (%edi)
-+ movl %edx, 4(%edi)
-+ movl %eax, 24(%esp)
-+ movl %ebx, 28(%esp)
-+ addl $8, %esi
-+ addl $8, %edi
-+ subl $8, %ebp
-+ jnz .L042decrypt_loop
-+.L041decrypt_finish:
-+ movl 60(%esp), %ebp
-+ andl $7, %ebp
-+ jz .L031finish
-+ movl (%esi), %eax
-+ movl 4(%esi), %ebx
-+ movl %eax, 16(%esp)
-+ movl %ebx, 20(%esp)
-+ call des_decrypt3
-+ movl 16(%esp), %eax
-+ movl 20(%esp), %ebx
-+ movl 24(%esp), %ecx
-+ movl 28(%esp), %edx
-+ xorl %eax, %ecx
-+ xorl %ebx, %edx
-+ movl (%esi), %eax
-+ movl 4(%esi), %ebx
-+.L043dj7:
-+ rorl $16, %edx
-+ movb %dl, 6(%edi)
-+ shrl $16, %edx
-+.L044dj6:
-+ movb %dh, 5(%edi)
-+.L045dj5:
-+ movb %dl, 4(%edi)
-+.L046dj4:
-+ movl %ecx, (%edi)
-+ jmp .L047djend
-+.L048dj3:
-+ rorl $16, %ecx
-+ movb %cl, 2(%edi)
-+ sall $16, %ecx
-+.L049dj2:
-+ movb %ch, 1(%esi)
-+.L050dj1:
-+ movb %cl, (%esi)
-+.L047djend:
-+ jmp .L031finish
-+.align 16
-+.L031finish:
-+ movl 76(%esp), %ecx
-+ addl $32, %esp
-+ movl %eax, (%ecx)
-+ movl %ebx, 4(%ecx)
-+ popl %edi
-+ popl %esi
-+ popl %ebx
-+ popl %ebp
-+ ret
-+.align 16
-+.L032cbc_enc_jmp_table:
-+ .long 0
-+ .long .L040ej1
-+ .long .L039ej2
-+ .long .L038ej3
-+ .long .L036ej4
-+ .long .L035ej5
-+ .long .L034ej6
-+ .long .L033ej7
-+.align 16
-+.L051cbc_dec_jmp_table:
-+ .long 0
-+ .long .L050dj1
-+ .long .L049dj2
-+ .long .L048dj3
-+ .long .L046dj4
-+ .long .L045dj5
-+ .long .L044dj6
-+ .long .L043dj7
-+.des_ede3_cbc_encrypt_end:
-+ .size des_ede3_cbc_encrypt , .des_ede3_cbc_encrypt_end-des_ede3_cbc_encrypt
-+.ident "desasm.pl"
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/ecb_enc.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,128 @@
-+/* crypto/des/ecb_enc.c */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+#include "des_locl.h"
-+#include "spr.h"
-+
-+char *libdes_version="libdes v 3.24 - 20-Apr-1996 - eay";
-+char *DES_version="DES part of SSLeay 0.8.2b 08-Jan-1998";
-+
-+/* RCSID $Id$ */
-+/* This function ifdef'ed out for FreeS/WAN project. */
-+#ifdef notdef
-+char *des_options()
-+ {
-+ static int init=1;
-+ static char buf[32];
-+
-+ if (init)
-+ {
-+ char *ptr,*unroll,*risc,*size;
-+
-+ init=0;
-+#ifdef DES_PTR
-+ ptr="ptr";
-+#else
-+ ptr="idx";
-+#endif
-+#if defined(DES_RISC1) || defined(DES_RISC2)
-+#ifdef DES_RISC1
-+ risc="risc1";
-+#endif
-+#ifdef DES_RISC2
-+ risc="risc2";
-+#endif
-+#else
-+ risc="cisc";
-+#endif
-+#ifdef DES_UNROLL
-+ unroll="16";
-+#else
-+ unroll="4";
-+#endif
-+ if (sizeof(DES_LONG) != sizeof(long))
-+ size="int";
-+ else
-+ size="long";
-+ sprintf(buf,"des(%s,%s,%s,%s)",ptr,risc,unroll,size);
-+ }
-+ return(buf);
-+ }
-+#endif
-+
-+
-+void des_ecb_encrypt(input, output, ks, enc)
-+des_cblock (*input);
-+des_cblock (*output);
-+des_key_schedule ks;
-+int enc;
-+ {
-+ register DES_LONG l;
-+ register unsigned char *in,*out;
-+ DES_LONG ll[2];
-+
-+ in=(unsigned char *)input;
-+ out=(unsigned char *)output;
-+ c2l(in,l); ll[0]=l;
-+ c2l(in,l); ll[1]=l;
-+ des_encrypt(ll,ks,enc);
-+ l=ll[0]; l2c(l,out);
-+ l=ll[1]; l2c(l,out);
-+ l=ll[0]=ll[1]=0;
-+ }
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/fcrypt.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,152 @@
-+/* NOCW */
-+
-+/* This version of crypt has been developed from my MIT compatable
-+ * DES library.
-+ * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
-+ * Eric Young (eay@cryptsoft.com)
-+ */
-+
-+/* Modification by Jens Kupferschmidt (Cu)
-+ * I have included directive PARA for shared memory computers.
-+ * I have included a directive LONGCRYPT to using this routine to cipher
-+ * passwords with more then 8 bytes like HP-UX 10.x it used. The MAXPLEN
-+ * definition is the maximum of lenght of password and can changed. I have
-+ * defined 24.
-+ */
-+
-+#include "des_locl.h"
-+
-+/* Added more values to handle illegal salt values the way normal
-+ * crypt() implementations do. The patch was sent by
-+ * Bjorn Gronvall <bg@sics.se>
-+ */
-+static unsigned const char con_salt[128]={
-+0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
-+0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,
-+0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
-+0xEA,0xEB,0xEC,0xED,0xEE,0xEF,0xF0,0xF1,
-+0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,
-+0xFA,0xFB,0xFC,0xFD,0xFE,0xFF,0x00,0x01,
-+0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
-+0x0A,0x0B,0x05,0x06,0x07,0x08,0x09,0x0A,
-+0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,
-+0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,
-+0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,
-+0x23,0x24,0x25,0x20,0x21,0x22,0x23,0x24,
-+0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,
-+0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,
-+0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,
-+0x3D,0x3E,0x3F,0x40,0x41,0x42,0x43,0x44,
-+};
-+
-+static unsigned const char cov_2char[64]={
-+0x2E,0x2F,0x30,0x31,0x32,0x33,0x34,0x35,
-+0x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,
-+0x45,0x46,0x47,0x48,0x49,0x4A,0x4B,0x4C,
-+0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,
-+0x55,0x56,0x57,0x58,0x59,0x5A,0x61,0x62,
-+0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,
-+0x6B,0x6C,0x6D,0x6E,0x6F,0x70,0x71,0x72,
-+0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A
-+};
-+
-+#ifndef NOPROTO
-+void fcrypt_body(DES_LONG *out,des_key_schedule ks,
-+ DES_LONG Eswap0, DES_LONG Eswap1);
-+
-+#ifdef PERL5
-+char *des_crypt(const char *buf,const char *salt);
-+#else
-+char *crypt(const char *buf,const char *salt);
-+#endif
-+#else
-+void fcrypt_body();
-+#ifdef PERL5
-+char *des_crypt();
-+#else
-+char *crypt();
-+#endif
-+#endif
-+
-+#ifdef PERL5
-+char *des_crypt(buf,salt)
-+#else
-+char *crypt(buf,salt)
-+#endif
-+const char *buf;
-+const char *salt;
-+ {
-+ static char buff[14];
-+
-+ return(des_fcrypt(buf,salt,buff));
-+ }
-+
-+
-+char *des_fcrypt(buf,salt,ret)
-+const char *buf;
-+const char *salt;
-+char *ret;
-+ {
-+ unsigned int i,j,x,y;
-+ DES_LONG Eswap0,Eswap1;
-+ DES_LONG out[2],ll;
-+ des_cblock key;
-+ des_key_schedule ks;
-+ unsigned char bb[9];
-+ unsigned char *b=bb;
-+ unsigned char c,u;
-+
-+ /* eay 25/08/92
-+ * If you call crypt("pwd","*") as often happens when you
-+ * have * as the pwd field in /etc/passwd, the function
-+ * returns *\0XXXXXXXXX
-+ * The \0 makes the string look like * so the pwd "*" would
-+ * crypt to "*". This was found when replacing the crypt in
-+ * our shared libraries. People found that the disbled
-+ * accounts effectivly had no passwd :-(. */
-+ x=ret[0]=((salt[0] == '\0')?'A':salt[0]);
-+ Eswap0=con_salt[x]<<2;
-+ x=ret[1]=((salt[1] == '\0')?'A':salt[1]);
-+ Eswap1=con_salt[x]<<6;
-+
-+/* EAY
-+r=strlen(buf);
-+r=(r+7)/8;
-+*/
-+ for (i=0; i<8; i++)
-+ {
-+ c= *(buf++);
-+ if (!c) break;
-+ key[i]=(c<<1);
-+ }
-+ for (; i<8; i++)
-+ key[i]=0;
-+
-+ des_set_key((des_cblock *)(key),ks);
-+ fcrypt_body(&(out[0]),ks,Eswap0,Eswap1);
-+
-+ ll=out[0]; l2c(ll,b);
-+ ll=out[1]; l2c(ll,b);
-+ y=0;
-+ u=0x80;
-+ bb[8]=0;
-+ for (i=2; i<13; i++)
-+ {
-+ c=0;
-+ for (j=0; j<6; j++)
-+ {
-+ c<<=1;
-+ if (bb[y] & u) c|=1;
-+ u>>=1;
-+ if (!u)
-+ {
-+ y++;
-+ u=0x80;
-+ }
-+ }
-+ ret[i]=cov_2char[c];
-+ }
-+ ret[13]='\0';
-+ return(ret);
-+ }
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/fcrypt_b.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,148 @@
-+/* crypto/des/fcrypt_b.c */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+/* #include <stdio.h> */
-+
-+/* This version of crypt has been developed from my MIT compatable
-+ * DES library.
-+ * The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au
-+ * Eric Young (eay@cryptsoft.com)
-+ */
-+
-+#define DES_FCRYPT
-+#include "des_locl.h"
-+#undef DES_FCRYPT
-+
-+#undef PERM_OP
-+#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
-+ (b)^=(t),\
-+ (a)^=((t)<<(n)))
-+
-+#undef HPERM_OP
-+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
-+ (a)=(a)^(t)^(t>>(16-(n))))\
-+
-+void fcrypt_body(out, ks, Eswap0, Eswap1)
-+DES_LONG *out;
-+des_key_schedule ks;
-+DES_LONG Eswap0;
-+DES_LONG Eswap1;
-+ {
-+ register DES_LONG l,r,t,u;
-+#ifdef DES_PTR
-+ register unsigned char *des_SP=(unsigned char *)des_SPtrans;
-+#endif
-+ register DES_LONG *s;
-+ register int j;
-+ register DES_LONG E0,E1;
-+
-+ l=0;
-+ r=0;
-+
-+ s=(DES_LONG *)ks;
-+ E0=Eswap0;
-+ E1=Eswap1;
-+
-+ for (j=0; j<25; j++)
-+ {
-+#ifdef DES_UNROLL
-+ register int i;
-+
-+ for (i=0; i<32; i+=8)
-+ {
-+ D_ENCRYPT(l,r,i+0); /* 1 */
-+ D_ENCRYPT(r,l,i+2); /* 2 */
-+ D_ENCRYPT(l,r,i+4); /* 1 */
-+ D_ENCRYPT(r,l,i+6); /* 2 */
-+ }
-+#else
-+ D_ENCRYPT(l,r, 0); /* 1 */
-+ D_ENCRYPT(r,l, 2); /* 2 */
-+ D_ENCRYPT(l,r, 4); /* 3 */
-+ D_ENCRYPT(r,l, 6); /* 4 */
-+ D_ENCRYPT(l,r, 8); /* 5 */
-+ D_ENCRYPT(r,l,10); /* 6 */
-+ D_ENCRYPT(l,r,12); /* 7 */
-+ D_ENCRYPT(r,l,14); /* 8 */
-+ D_ENCRYPT(l,r,16); /* 9 */
-+ D_ENCRYPT(r,l,18); /* 10 */
-+ D_ENCRYPT(l,r,20); /* 11 */
-+ D_ENCRYPT(r,l,22); /* 12 */
-+ D_ENCRYPT(l,r,24); /* 13 */
-+ D_ENCRYPT(r,l,26); /* 14 */
-+ D_ENCRYPT(l,r,28); /* 15 */
-+ D_ENCRYPT(r,l,30); /* 16 */
-+#endif
-+
-+ t=l;
-+ l=r;
-+ r=t;
-+ }
-+ l=ROTATE(l,3)&0xffffffffL;
-+ r=ROTATE(r,3)&0xffffffffL;
-+
-+ PERM_OP(l,r,t, 1,0x55555555L);
-+ PERM_OP(r,l,t, 8,0x00ff00ffL);
-+ PERM_OP(l,r,t, 2,0x33333333L);
-+ PERM_OP(r,l,t,16,0x0000ffffL);
-+ PERM_OP(l,r,t, 4,0x0f0f0f0fL);
-+
-+ out[0]=r;
-+ out[1]=l;
-+ }
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/options.txt Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,39 @@
-+Note that the UNROLL option makes the 'inner' des loop unroll all 16 rounds
-+instead of the default 4.
-+RISC1 and RISC2 are 2 alternatives for the inner loop and
-+PTR means to use pointers arithmatic instead of arrays.
-+
-+FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - assembler 577,000 4620k/s
-+IRIX 6.2 - R10000 195mhz - cc (-O3 -n32) - UNROLL RISC2 PTR 496,000 3968k/s
-+solaris 2.5.1 usparc 167mhz?? - SC4.0 - UNROLL RISC1 PTR [1] 459,400 3672k/s
-+FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - UNROLL RISC1 433,000 3468k/s
-+solaris 2.5.1 usparc 167mhz?? - gcc 2.7.2 - UNROLL 380,000 3041k/s
-+linux - pentium 100mhz - gcc 2.7.0 - assembler 281,000 2250k/s
-+NT 4.0 - pentium 100mhz - VC 4.2 - assembler 281,000 2250k/s
-+AIX 4.1? - PPC604 100mhz - cc - UNROLL 275,000 2200k/s
-+IRIX 5.3 - R4400 200mhz - gcc 2.6.3 - UNROLL RISC2 PTR 235,300 1882k/s
-+IRIX 5.3 - R4400 200mhz - cc - UNROLL RISC2 PTR 233,700 1869k/s
-+NT 4.0 - pentium 100mhz - VC 4.2 - UNROLL RISC1 PTR 191,000 1528k/s
-+DEC Alpha 165mhz?? - cc - RISC2 PTR [2] 181,000 1448k/s
-+linux - pentium 100mhz - gcc 2.7.0 - UNROLL RISC1 PTR 158,500 1268k/s
-+HPUX 10 - 9000/887 - cc - UNROLL [3] 148,000 1190k/s
-+solaris 2.5.1 - sparc 10 50mhz - gcc 2.7.2 - UNROLL 123,600 989k/s
-+IRIX 5.3 - R4000 100mhz - cc - UNROLL RISC2 PTR 101,000 808k/s
-+DGUX - 88100 50mhz(?) - gcc 2.6.3 - UNROLL 81,000 648k/s
-+solaris 2.4 486 50mhz - gcc 2.6.3 - assembler 65,000 522k/s
-+HPUX 10 - 9000/887 - k&r cc (default compiler) - UNROLL PTR 76,000 608k/s
-+solaris 2.4 486 50mhz - gcc 2.6.3 - UNROLL RISC2 43,500 344k/s
-+AIX - old slow one :-) - cc - 39,000 312k/s
-+
-+Notes.
-+[1] For the ultra sparc, SunC 4.0
-+ cc -xtarget=ultra -xarch=v8plus -Xa -xO5, running 'des_opts'
-+ gives a speed of 344,000 des/s while 'speed' gives 459,000 des/s.
-+ I'll record the higher since it is coming from the library but it
-+ is all rather weird.
-+[2] Similar to the ultra sparc ([1]), 181,000 for 'des_opts' vs 175,000.
-+[3] I was unable to get access to this machine when it was not heavily loaded.
-+ As such, my timing program was never able to get more that %30 of the CPU.
-+ This would cause the program to give much lower speed numbers because
-+ it would be 'fighting' to stay in the cache with the other CPU burning
-+ processes.
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/podd.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,75 @@
-+/* crypto/des/podd.h */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+static const unsigned char odd_parity[256]={
-+ 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
-+ 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
-+ 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
-+ 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
-+ 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
-+ 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
-+ 97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
-+112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
-+128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
-+145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
-+161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
-+176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
-+193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
-+208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
-+224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
-+241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254};
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/set_key.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,246 @@
-+/* crypto/des/set_key.c */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+/* set_key.c v 1.4 eay 24/9/91
-+ * 1.4 Speed up by 400% :-)
-+ * 1.3 added register declarations.
-+ * 1.2 unrolled make_key_sched a bit more
-+ * 1.1 added norm_expand_bits
-+ * 1.0 First working version
-+ */
-+#include "des_locl.h"
-+#include "podd.h"
-+#include "sk.h"
-+
-+#ifndef NOPROTO
-+static int check_parity(des_cblock (*key));
-+#else
-+static int check_parity();
-+#endif
-+
-+int des_check_key=0;
-+
-+void des_set_odd_parity(key)
-+des_cblock (*key);
-+ {
-+ int i;
-+
-+ for (i=0; i<DES_KEY_SZ; i++)
-+ (*key)[i]=odd_parity[(*key)[i]];
-+ }
-+
-+static int check_parity(key)
-+des_cblock (*key);
-+ {
-+ int i;
-+
-+ for (i=0; i<DES_KEY_SZ; i++)
-+ {
-+ if ((*key)[i] != odd_parity[(*key)[i]])
-+ return(0);
-+ }
-+ return(1);
-+ }
-+
-+/* Weak and semi week keys as take from
-+ * %A D.W. Davies
-+ * %A W.L. Price
-+ * %T Security for Computer Networks
-+ * %I John Wiley & Sons
-+ * %D 1984
-+ * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference
-+ * (and actual cblock values).
-+ */
-+#define NUM_WEAK_KEY 16
-+static des_cblock weak_keys[NUM_WEAK_KEY]={
-+ /* weak keys */
-+ {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01},
-+ {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},
-+ {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F},
-+ {0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0,0xE0},
-+ /* semi-weak keys */
-+ {0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE},
-+ {0xFE,0x01,0xFE,0x01,0xFE,0x01,0xFE,0x01},
-+ {0x1F,0xE0,0x1F,0xE0,0x0E,0xF1,0x0E,0xF1},
-+ {0xE0,0x1F,0xE0,0x1F,0xF1,0x0E,0xF1,0x0E},
-+ {0x01,0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1},
-+ {0xE0,0x01,0xE0,0x01,0xF1,0x01,0xF1,0x01},
-+ {0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E,0xFE},
-+ {0xFE,0x1F,0xFE,0x1F,0xFE,0x0E,0xFE,0x0E},
-+ {0x01,0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E},
-+ {0x1F,0x01,0x1F,0x01,0x0E,0x01,0x0E,0x01},
-+ {0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1,0xFE},
-+ {0xFE,0xE0,0xFE,0xE0,0xFE,0xF1,0xFE,0xF1}};
-+
-+int des_is_weak_key(key)
-+des_cblock (*key);
-+ {
-+ int i;
-+
-+ for (i=0; i<NUM_WEAK_KEY; i++)
-+ /* Added == 0 to comparision, I obviously don't run
-+ * this section very often :-(, thanks to
-+ * engineering@MorningStar.Com for the fix
-+ * eay 93/06/29
-+ * Another problem, I was comparing only the first 4
-+ * bytes, 97/03/18 */
-+ if (memcmp(weak_keys[i],key,sizeof(des_cblock)) == 0) return(1);
-+ return(0);
-+ }
-+
-+/* NOW DEFINED IN des_local.h
-+ * See ecb_encrypt.c for a pseudo description of these macros.
-+ * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
-+ * (b)^=(t),\
-+ * (a)=((a)^((t)<<(n))))
-+ */
-+
-+#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
-+ (a)=(a)^(t)^(t>>(16-(n))))
-+
-+/* return 0 if key parity is odd (correct),
-+ * return -1 if key parity error,
-+ * return -2 if illegal weak key.
-+ */
-+int des_set_key(key, schedule)
-+des_cblock (*key);
-+des_key_schedule schedule;
-+ {
-+ static int shifts2[16]={0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
-+ register DES_LONG c,d,t,s,t2;
-+ register unsigned char *in;
-+ register DES_LONG *k;
-+ register int i;
-+
-+ if (des_check_key)
-+ {
-+ if (!check_parity(key))
-+ return(-1);
-+
-+ if (des_is_weak_key(key))
-+ return(-2);
-+ }
-+
-+ k=(DES_LONG *)schedule;
-+ in=(unsigned char *)key;
-+
-+ c2l(in,c);
-+ c2l(in,d);
-+
-+ /* do PC1 in 60 simple operations */
-+/* PERM_OP(d,c,t,4,0x0f0f0f0fL);
-+ HPERM_OP(c,t,-2, 0xcccc0000L);
-+ HPERM_OP(c,t,-1, 0xaaaa0000L);
-+ HPERM_OP(c,t, 8, 0x00ff0000L);
-+ HPERM_OP(c,t,-1, 0xaaaa0000L);
-+ HPERM_OP(d,t,-8, 0xff000000L);
-+ HPERM_OP(d,t, 8, 0x00ff0000L);
-+ HPERM_OP(d,t, 2, 0x33330000L);
-+ d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
-+ d=(d>>8)|((c&0xf0000000L)>>4);
-+ c&=0x0fffffffL; */
-+
-+ /* I now do it in 47 simple operations :-)
-+ * Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov)
-+ * for the inspiration. :-) */
-+ PERM_OP (d,c,t,4,0x0f0f0f0fL);
-+ HPERM_OP(c,t,-2,0xcccc0000L);
-+ HPERM_OP(d,t,-2,0xcccc0000L);
-+ PERM_OP (d,c,t,1,0x55555555L);
-+ PERM_OP (c,d,t,8,0x00ff00ffL);
-+ PERM_OP (d,c,t,1,0x55555555L);
-+ d= (((d&0x000000ffL)<<16L)| (d&0x0000ff00L) |
-+ ((d&0x00ff0000L)>>16L)|((c&0xf0000000L)>>4L));
-+ c&=0x0fffffffL;
-+
-+ for (i=0; i<ITERATIONS; i++)
-+ {
-+ if (shifts2[i])
-+ { c=((c>>2L)|(c<<26L)); d=((d>>2L)|(d<<26L)); }
-+ else
-+ { c=((c>>1L)|(c<<27L)); d=((d>>1L)|(d<<27L)); }
-+ c&=0x0fffffffL;
-+ d&=0x0fffffffL;
-+ /* could be a few less shifts but I am to lazy at this
-+ * point in time to investigate */
-+ s= des_skb[0][ (c )&0x3f ]|
-+ des_skb[1][((c>> 6)&0x03)|((c>> 7L)&0x3c)]|
-+ des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
-+ des_skb[3][((c>>20)&0x01)|((c>>21L)&0x06) |
-+ ((c>>22L)&0x38)];
-+ t= des_skb[4][ (d )&0x3f ]|
-+ des_skb[5][((d>> 7L)&0x03)|((d>> 8L)&0x3c)]|
-+ des_skb[6][ (d>>15L)&0x3f ]|
-+ des_skb[7][((d>>21L)&0x0f)|((d>>22L)&0x30)];
-+
-+ /* table contained 0213 4657 */
-+ t2=((t<<16L)|(s&0x0000ffffL))&0xffffffffL;
-+ *(k++)=ROTATE(t2,30)&0xffffffffL;
-+
-+ t2=((s>>16L)|(t&0xffff0000L));
-+ *(k++)=ROTATE(t2,26)&0xffffffffL;
-+ }
-+ return(0);
-+ }
-+
-+int des_key_sched(key, schedule)
-+des_cblock (*key);
-+des_key_schedule schedule;
-+ {
-+ return(des_set_key(key,schedule));
-+ }
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/sk.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,204 @@
-+/* crypto/des/sk.h */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+static const DES_LONG des_skb[8][64]={
-+{
-+/* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
-+0x00000000L,0x00000010L,0x20000000L,0x20000010L,
-+0x00010000L,0x00010010L,0x20010000L,0x20010010L,
-+0x00000800L,0x00000810L,0x20000800L,0x20000810L,
-+0x00010800L,0x00010810L,0x20010800L,0x20010810L,
-+0x00000020L,0x00000030L,0x20000020L,0x20000030L,
-+0x00010020L,0x00010030L,0x20010020L,0x20010030L,
-+0x00000820L,0x00000830L,0x20000820L,0x20000830L,
-+0x00010820L,0x00010830L,0x20010820L,0x20010830L,
-+0x00080000L,0x00080010L,0x20080000L,0x20080010L,
-+0x00090000L,0x00090010L,0x20090000L,0x20090010L,
-+0x00080800L,0x00080810L,0x20080800L,0x20080810L,
-+0x00090800L,0x00090810L,0x20090800L,0x20090810L,
-+0x00080020L,0x00080030L,0x20080020L,0x20080030L,
-+0x00090020L,0x00090030L,0x20090020L,0x20090030L,
-+0x00080820L,0x00080830L,0x20080820L,0x20080830L,
-+0x00090820L,0x00090830L,0x20090820L,0x20090830L,
-+},{
-+/* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
-+0x00000000L,0x02000000L,0x00002000L,0x02002000L,
-+0x00200000L,0x02200000L,0x00202000L,0x02202000L,
-+0x00000004L,0x02000004L,0x00002004L,0x02002004L,
-+0x00200004L,0x02200004L,0x00202004L,0x02202004L,
-+0x00000400L,0x02000400L,0x00002400L,0x02002400L,
-+0x00200400L,0x02200400L,0x00202400L,0x02202400L,
-+0x00000404L,0x02000404L,0x00002404L,0x02002404L,
-+0x00200404L,0x02200404L,0x00202404L,0x02202404L,
-+0x10000000L,0x12000000L,0x10002000L,0x12002000L,
-+0x10200000L,0x12200000L,0x10202000L,0x12202000L,
-+0x10000004L,0x12000004L,0x10002004L,0x12002004L,
-+0x10200004L,0x12200004L,0x10202004L,0x12202004L,
-+0x10000400L,0x12000400L,0x10002400L,0x12002400L,
-+0x10200400L,0x12200400L,0x10202400L,0x12202400L,
-+0x10000404L,0x12000404L,0x10002404L,0x12002404L,
-+0x10200404L,0x12200404L,0x10202404L,0x12202404L,
-+},{
-+/* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
-+0x00000000L,0x00000001L,0x00040000L,0x00040001L,
-+0x01000000L,0x01000001L,0x01040000L,0x01040001L,
-+0x00000002L,0x00000003L,0x00040002L,0x00040003L,
-+0x01000002L,0x01000003L,0x01040002L,0x01040003L,
-+0x00000200L,0x00000201L,0x00040200L,0x00040201L,
-+0x01000200L,0x01000201L,0x01040200L,0x01040201L,
-+0x00000202L,0x00000203L,0x00040202L,0x00040203L,
-+0x01000202L,0x01000203L,0x01040202L,0x01040203L,
-+0x08000000L,0x08000001L,0x08040000L,0x08040001L,
-+0x09000000L,0x09000001L,0x09040000L,0x09040001L,
-+0x08000002L,0x08000003L,0x08040002L,0x08040003L,
-+0x09000002L,0x09000003L,0x09040002L,0x09040003L,
-+0x08000200L,0x08000201L,0x08040200L,0x08040201L,
-+0x09000200L,0x09000201L,0x09040200L,0x09040201L,
-+0x08000202L,0x08000203L,0x08040202L,0x08040203L,
-+0x09000202L,0x09000203L,0x09040202L,0x09040203L,
-+},{
-+/* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
-+0x00000000L,0x00100000L,0x00000100L,0x00100100L,
-+0x00000008L,0x00100008L,0x00000108L,0x00100108L,
-+0x00001000L,0x00101000L,0x00001100L,0x00101100L,
-+0x00001008L,0x00101008L,0x00001108L,0x00101108L,
-+0x04000000L,0x04100000L,0x04000100L,0x04100100L,
-+0x04000008L,0x04100008L,0x04000108L,0x04100108L,
-+0x04001000L,0x04101000L,0x04001100L,0x04101100L,
-+0x04001008L,0x04101008L,0x04001108L,0x04101108L,
-+0x00020000L,0x00120000L,0x00020100L,0x00120100L,
-+0x00020008L,0x00120008L,0x00020108L,0x00120108L,
-+0x00021000L,0x00121000L,0x00021100L,0x00121100L,
-+0x00021008L,0x00121008L,0x00021108L,0x00121108L,
-+0x04020000L,0x04120000L,0x04020100L,0x04120100L,
-+0x04020008L,0x04120008L,0x04020108L,0x04120108L,
-+0x04021000L,0x04121000L,0x04021100L,0x04121100L,
-+0x04021008L,0x04121008L,0x04021108L,0x04121108L,
-+},{
-+/* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
-+0x00000000L,0x10000000L,0x00010000L,0x10010000L,
-+0x00000004L,0x10000004L,0x00010004L,0x10010004L,
-+0x20000000L,0x30000000L,0x20010000L,0x30010000L,
-+0x20000004L,0x30000004L,0x20010004L,0x30010004L,
-+0x00100000L,0x10100000L,0x00110000L,0x10110000L,
-+0x00100004L,0x10100004L,0x00110004L,0x10110004L,
-+0x20100000L,0x30100000L,0x20110000L,0x30110000L,
-+0x20100004L,0x30100004L,0x20110004L,0x30110004L,
-+0x00001000L,0x10001000L,0x00011000L,0x10011000L,
-+0x00001004L,0x10001004L,0x00011004L,0x10011004L,
-+0x20001000L,0x30001000L,0x20011000L,0x30011000L,
-+0x20001004L,0x30001004L,0x20011004L,0x30011004L,
-+0x00101000L,0x10101000L,0x00111000L,0x10111000L,
-+0x00101004L,0x10101004L,0x00111004L,0x10111004L,
-+0x20101000L,0x30101000L,0x20111000L,0x30111000L,
-+0x20101004L,0x30101004L,0x20111004L,0x30111004L,
-+},{
-+/* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
-+0x00000000L,0x08000000L,0x00000008L,0x08000008L,
-+0x00000400L,0x08000400L,0x00000408L,0x08000408L,
-+0x00020000L,0x08020000L,0x00020008L,0x08020008L,
-+0x00020400L,0x08020400L,0x00020408L,0x08020408L,
-+0x00000001L,0x08000001L,0x00000009L,0x08000009L,
-+0x00000401L,0x08000401L,0x00000409L,0x08000409L,
-+0x00020001L,0x08020001L,0x00020009L,0x08020009L,
-+0x00020401L,0x08020401L,0x00020409L,0x08020409L,
-+0x02000000L,0x0A000000L,0x02000008L,0x0A000008L,
-+0x02000400L,0x0A000400L,0x02000408L,0x0A000408L,
-+0x02020000L,0x0A020000L,0x02020008L,0x0A020008L,
-+0x02020400L,0x0A020400L,0x02020408L,0x0A020408L,
-+0x02000001L,0x0A000001L,0x02000009L,0x0A000009L,
-+0x02000401L,0x0A000401L,0x02000409L,0x0A000409L,
-+0x02020001L,0x0A020001L,0x02020009L,0x0A020009L,
-+0x02020401L,0x0A020401L,0x02020409L,0x0A020409L,
-+},{
-+/* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
-+0x00000000L,0x00000100L,0x00080000L,0x00080100L,
-+0x01000000L,0x01000100L,0x01080000L,0x01080100L,
-+0x00000010L,0x00000110L,0x00080010L,0x00080110L,
-+0x01000010L,0x01000110L,0x01080010L,0x01080110L,
-+0x00200000L,0x00200100L,0x00280000L,0x00280100L,
-+0x01200000L,0x01200100L,0x01280000L,0x01280100L,
-+0x00200010L,0x00200110L,0x00280010L,0x00280110L,
-+0x01200010L,0x01200110L,0x01280010L,0x01280110L,
-+0x00000200L,0x00000300L,0x00080200L,0x00080300L,
-+0x01000200L,0x01000300L,0x01080200L,0x01080300L,
-+0x00000210L,0x00000310L,0x00080210L,0x00080310L,
-+0x01000210L,0x01000310L,0x01080210L,0x01080310L,
-+0x00200200L,0x00200300L,0x00280200L,0x00280300L,
-+0x01200200L,0x01200300L,0x01280200L,0x01280300L,
-+0x00200210L,0x00200310L,0x00280210L,0x00280310L,
-+0x01200210L,0x01200310L,0x01280210L,0x01280310L,
-+},{
-+/* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
-+0x00000000L,0x04000000L,0x00040000L,0x04040000L,
-+0x00000002L,0x04000002L,0x00040002L,0x04040002L,
-+0x00002000L,0x04002000L,0x00042000L,0x04042000L,
-+0x00002002L,0x04002002L,0x00042002L,0x04042002L,
-+0x00000020L,0x04000020L,0x00040020L,0x04040020L,
-+0x00000022L,0x04000022L,0x00040022L,0x04040022L,
-+0x00002020L,0x04002020L,0x00042020L,0x04042020L,
-+0x00002022L,0x04002022L,0x00042022L,0x04042022L,
-+0x00000800L,0x04000800L,0x00040800L,0x04040800L,
-+0x00000802L,0x04000802L,0x00040802L,0x04040802L,
-+0x00002800L,0x04002800L,0x00042800L,0x04042800L,
-+0x00002802L,0x04002802L,0x00042802L,0x04042802L,
-+0x00000820L,0x04000820L,0x00040820L,0x04040820L,
-+0x00000822L,0x04000822L,0x00040822L,0x04040822L,
-+0x00002820L,0x04002820L,0x00042820L,0x04042820L,
-+0x00002822L,0x04002822L,0x00042822L,0x04042822L,
-+}};
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/speed.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,329 @@
-+/* crypto/des/speed.c */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */
-+/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */
-+
-+#ifndef MSDOS
-+#define TIMES
-+#endif
-+
-+#include <stdio.h>
-+#ifndef MSDOS
-+#include <unistd.h>
-+#else
-+#include <io.h>
-+extern int exit();
-+#endif
-+#include <signal.h>
-+#ifndef VMS
-+#ifndef _IRIX
-+#include <time.h>
-+#endif
-+#ifdef TIMES
-+#include <sys/types.h>
-+#include <sys/times.h>
-+#endif
-+#else /* VMS */
-+#include <types.h>
-+struct tms {
-+ time_t tms_utime;
-+ time_t tms_stime;
-+ time_t tms_uchild; /* I dunno... */
-+ time_t tms_uchildsys; /* so these names are a guess :-) */
-+ }
-+#endif
-+#ifndef TIMES
-+#include <sys/timeb.h>
-+#endif
-+
-+#ifdef sun
-+#include <limits.h>
-+#include <sys/param.h>
-+#endif
-+
-+#include "des_locl.h"
-+
-+/* The following if from times(3) man page. It may need to be changed */
-+#ifndef HZ
-+# ifndef CLK_TCK
-+# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */
-+# ifndef VMS
-+# define HZ 100.0
-+# else /* VMS */
-+# define HZ 100.0
-+# endif
-+# else /* _BSD_CLK_TCK_ */
-+# define HZ ((double)_BSD_CLK_TCK_)
-+# endif
-+# else /* CLK_TCK */
-+# define HZ ((double)CLK_TCK)
-+# endif
-+#endif
-+
-+#define BUFSIZE ((long)1024)
-+long run=0;
-+
-+#ifndef NOPROTO
-+double Time_F(int s);
-+#else
-+double Time_F();
-+#endif
-+
-+#ifdef SIGALRM
-+#if defined(__STDC__) || defined(sgi) || defined(_AIX)
-+#define SIGRETTYPE void
-+#else
-+#define SIGRETTYPE int
-+#endif
-+
-+#ifndef NOPROTO
-+SIGRETTYPE sig_done(int sig);
-+#else
-+SIGRETTYPE sig_done();
-+#endif
-+
-+SIGRETTYPE sig_done(sig)
-+int sig;
-+ {
-+ signal(SIGALRM,sig_done);
-+ run=0;
-+#ifdef LINT
-+ sig=sig;
-+#endif
-+ }
-+#endif
-+
-+#define START 0
-+#define STOP 1
-+
-+double Time_F(s)
-+int s;
-+ {
-+ double ret;
-+#ifdef TIMES
-+ static struct tms tstart,tend;
-+
-+ if (s == START)
-+ {
-+ times(&tstart);
-+ return(0);
-+ }
-+ else
-+ {
-+ times(&tend);
-+ ret=((double)(tend.tms_utime-tstart.tms_utime))/HZ;
-+ return((ret == 0.0)?1e-6:ret);
-+ }
-+#else /* !times() */
-+ static struct timeb tstart,tend;
-+ long i;
-+
-+ if (s == START)
-+ {
-+ ftime(&tstart);
-+ return(0);
-+ }
-+ else
-+ {
-+ ftime(&tend);
-+ i=(long)tend.millitm-(long)tstart.millitm;
-+ ret=((double)(tend.time-tstart.time))+((double)i)/1e3;
-+ return((ret == 0.0)?1e-6:ret);
-+ }
-+#endif
-+ }
-+
-+int main(argc,argv)
-+int argc;
-+char **argv;
-+ {
-+ long count;
-+ static unsigned char buf[BUFSIZE];
-+ static des_cblock key ={0x12,0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0};
-+ static des_cblock key2={0x34,0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12};
-+ static des_cblock key3={0x56,0x78,0x9a,0xbc,0xde,0xf0,0x12,0x34};
-+ des_key_schedule sch,sch2,sch3;
-+ double a,b,c,d,e;
-+#ifndef SIGALRM
-+ long ca,cb,cc,cd,ce;
-+#endif
-+
-+#ifndef TIMES
-+ printf("To get the most acurate results, try to run this\n");
-+ printf("program when this computer is idle.\n");
-+#endif
-+
-+ des_set_key((C_Block *)key2,sch2);
-+ des_set_key((C_Block *)key3,sch3);
-+
-+#ifndef SIGALRM
-+ printf("First we calculate the approximate speed ...\n");
-+ des_set_key((C_Block *)key,sch);
-+ count=10;
-+ do {
-+ long i;
-+ DES_LONG data[2];
-+
-+ count*=2;
-+ Time_F(START);
-+ for (i=count; i; i--)
-+ des_encrypt(data,&(sch[0]),DES_ENCRYPT);
-+ d=Time_F(STOP);
-+ } while (d < 3.0);
-+ ca=count;
-+ cb=count*3;
-+ cc=count*3*8/BUFSIZE+1;
-+ cd=count*8/BUFSIZE+1;
-+ ce=count/20+1;
-+ printf("Doing set_key %ld times\n",ca);
-+#define COND(d) (count != (d))
-+#define COUNT(d) (d)
-+#else
-+#define COND(c) (run)
-+#define COUNT(d) (count)
-+ signal(SIGALRM,sig_done);
-+ printf("Doing set_key for 10 seconds\n");
-+ alarm(10);
-+#endif
-+
-+ Time_F(START);
-+ for (count=0,run=1; COND(ca); count++)
-+ des_set_key((C_Block *)key,sch);
-+ d=Time_F(STOP);
-+ printf("%ld set_key's in %.2f seconds\n",count,d);
-+ a=((double)COUNT(ca))/d;
-+
-+#ifdef SIGALRM
-+ printf("Doing des_encrypt's for 10 seconds\n");
-+ alarm(10);
-+#else
-+ printf("Doing des_encrypt %ld times\n",cb);
-+#endif
-+ Time_F(START);
-+ for (count=0,run=1; COND(cb); count++)
-+ {
-+ DES_LONG data[2];
-+
-+ des_encrypt(data,&(sch[0]),DES_ENCRYPT);
-+ }
-+ d=Time_F(STOP);
-+ printf("%ld des_encrypt's in %.2f second\n",count,d);
-+ b=((double)COUNT(cb)*8)/d;
-+
-+#ifdef SIGALRM
-+ printf("Doing des_cbc_encrypt on %ld byte blocks for 10 seconds\n",
-+ BUFSIZE);
-+ alarm(10);
-+#else
-+ printf("Doing des_cbc_encrypt %ld times on %ld byte blocks\n",cc,
-+ BUFSIZE);
-+#endif
-+ Time_F(START);
-+ for (count=0,run=1; COND(cc); count++)
-+ des_ncbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE,&(sch[0]),
-+ (C_Block *)&(key[0]),DES_ENCRYPT);
-+ d=Time_F(STOP);
-+ printf("%ld des_cbc_encrypt's of %ld byte blocks in %.2f second\n",
-+ count,BUFSIZE,d);
-+ c=((double)COUNT(cc)*BUFSIZE)/d;
-+
-+#ifdef SIGALRM
-+ printf("Doing des_ede_cbc_encrypt on %ld byte blocks for 10 seconds\n",
-+ BUFSIZE);
-+ alarm(10);
-+#else
-+ printf("Doing des_ede_cbc_encrypt %ld times on %ld byte blocks\n",cd,
-+ BUFSIZE);
-+#endif
-+ Time_F(START);
-+ for (count=0,run=1; COND(cd); count++)
-+ des_ede3_cbc_encrypt((C_Block *)buf,(C_Block *)buf,BUFSIZE,
-+ &(sch[0]),
-+ &(sch2[0]),
-+ &(sch3[0]),
-+ (C_Block *)&(key[0]),
-+ DES_ENCRYPT);
-+ d=Time_F(STOP);
-+ printf("%ld des_ede_cbc_encrypt's of %ld byte blocks in %.2f second\n",
-+ count,BUFSIZE,d);
-+ d=((double)COUNT(cd)*BUFSIZE)/d;
-+
-+#ifdef SIGALRM
-+ printf("Doing crypt for 10 seconds\n");
-+ alarm(10);
-+#else
-+ printf("Doing crypt %ld times\n",ce);
-+#endif
-+ Time_F(START);
-+ for (count=0,run=1; COND(ce); count++)
-+ crypt("testing1","ef");
-+ e=Time_F(STOP);
-+ printf("%ld crypts in %.2f second\n",count,e);
-+ e=((double)COUNT(ce))/e;
-+
-+ printf("set_key per sec = %12.2f (%9.3fuS)\n",a,1.0e6/a);
-+ printf("DES raw ecb bytes per sec = %12.2f (%9.3fuS)\n",b,8.0e6/b);
-+ printf("DES cbc bytes per sec = %12.2f (%9.3fuS)\n",c,8.0e6/c);
-+ printf("DES ede cbc bytes per sec = %12.2f (%9.3fuS)\n",d,8.0e6/d);
-+ printf("crypt per sec = %12.2f (%9.3fuS)\n",e,1.0e6/e);
-+ exit(0);
-+#if defined(LINT) || defined(MSDOS)
-+ return(0);
-+#endif
-+ }
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/crypto/ciphers/des/spr.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,204 @@
-+/* crypto/des/spr.h */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+const DES_LONG des_SPtrans[8][64]={
-+{
-+/* nibble 0 */
-+0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L,
-+0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L,
-+0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L,
-+0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L,
-+0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L,
-+0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L,
-+0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L,
-+0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L,
-+0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L,
-+0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L,
-+0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L,
-+0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L,
-+0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L,
-+0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L,
-+0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L,
-+0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L,
-+},{
-+/* nibble 1 */
-+0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L,
-+0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L,
-+0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L,
-+0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L,
-+0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L,
-+0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L,
-+0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L,
-+0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L,
-+0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L,
-+0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L,
-+0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L,
-+0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L,
-+0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L,
-+0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L,
-+0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L,
-+0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L,
-+},{
-+/* nibble 2 */
-+0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L,
-+0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L,
-+0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L,
-+0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L,
-+0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L,
-+0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L,
-+0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L,
-+0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L,
-+0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L,
-+0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L,
-+0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L,
-+0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L,
-+0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L,
-+0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L,
-+0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L,
-+0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L,
-+},{
-+/* nibble 3 */
-+0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L,
-+0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L,
-+0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L,
-+0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L,
-+0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L,
-+0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L,
-+0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L,
-+0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L,
-+0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L,
-+0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L,
-+0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L,
-+0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L,
-+0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L,
-+0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L,
-+0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L,
-+0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L,
-+},{
-+/* nibble 4 */
-+0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L,
-+0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L,
-+0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L,
-+0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L,
-+0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L,
-+0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L,
-+0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L,
-+0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L,
-+0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L,
-+0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L,
-+0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L,
-+0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L,
-+0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L,
-+0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L,
-+0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L,
-+0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L,
-+},{
-+/* nibble 5 */
-+0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L,
-+0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L,
-+0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L,
-+0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L,
-+0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L,
-+0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L,
-+0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L,
-+0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L,
-+0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L,
-+0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L,
-+0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L,
-+0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L,
-+0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L,
-+0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L,
-+0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L,
-+0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L,
-+},{
-+/* nibble 6 */
-+0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L,
-+0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L,
-+0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L,
-+0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L,
-+0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L,
-+0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L,
-+0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L,
-+0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L,
-+0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L,
-+0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L,
-+0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L,
-+0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L,
-+0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L,
-+0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L,
-+0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L,
-+0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L,
-+},{
-+/* nibble 7 */
-+0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L,
-+0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L,
-+0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L,
-+0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L,
-+0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L,
-+0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L,
-+0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L,
-+0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L,
-+0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L,
-+0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L,
-+0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L,
-+0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L,
-+0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L,
-+0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L,
-+0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L,
-+0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L,
-+}};
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/crypto/aes.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,97 @@
-+// I retain copyright in this code but I encourage its free use provided
-+// that I don't carry any responsibility for the results. I am especially
-+// happy to see it used in free and open source software. If you do use
-+// it I would appreciate an acknowledgement of its origin in the code or
-+// the product that results and I would also appreciate knowing a little
-+// about the use to which it is being put. I am grateful to Frank Yellin
-+// for some ideas that are used in this implementation.
-+//
-+// Dr B. R. Gladman <brg@gladman.uk.net> 6th April 2001.
-+//
-+// This is an implementation of the AES encryption algorithm (Rijndael)
-+// designed by Joan Daemen and Vincent Rijmen. This version is designed
-+// to provide both fixed and dynamic block and key lengths and can also
-+// run with either big or little endian internal byte order (see aes.h).
-+// It inputs block and key lengths in bytes with the legal values being
-+// 16, 24 and 32.
-+
-+/*
-+ * Modified by Jari Ruusu, May 1 2001
-+ * - Fixed some compile warnings, code was ok but gcc warned anyway.
-+ * - Changed basic types: byte -> unsigned char, word -> u_int32_t
-+ * - Major name space cleanup: Names visible to outside now begin
-+ * with "aes_" or "AES_". A lot of stuff moved from aes.h to aes.c
-+ * - Removed C++ and DLL support as part of name space cleanup.
-+ * - Eliminated unnecessary recomputation of tables. (actual bug fix)
-+ * - Merged precomputed constant tables to aes.c file.
-+ * - Removed data alignment restrictions for portability reasons.
-+ * - Made block and key lengths accept bit count (128/192/256)
-+ * as well byte count (16/24/32).
-+ * - Removed all error checks. This change also eliminated the need
-+ * to preinitialize the context struct to zero.
-+ * - Removed some totally unused constants.
-+ */
-+
-+#ifndef _AES_H
-+#define _AES_H
-+
-+#if defined(__linux__) && defined(__KERNEL__)
-+# include <linux/types.h>
-+#else
-+# include <sys/types.h>
-+#endif
-+
-+// CONFIGURATION OPTIONS (see also aes.c)
-+//
-+// Define AES_BLOCK_SIZE to set the cipher block size (16, 24 or 32) or
-+// leave this undefined for dynamically variable block size (this will
-+// result in much slower code).
-+// IMPORTANT NOTE: AES_BLOCK_SIZE is in BYTES (16, 24, 32 or undefined). If
-+// left undefined a slower version providing variable block length is compiled
-+
-+#define AES_BLOCK_SIZE 16
-+
-+// The number of key schedule words for different block and key lengths
-+// allowing for method of computation which requires the length to be a
-+// multiple of the key length
-+//
-+// Nk = 4 6 8
-+// -------------
-+// Nb = 4 | 60 60 64
-+// 6 | 96 90 96
-+// 8 | 120 120 120
-+
-+#if !defined(AES_BLOCK_SIZE) || (AES_BLOCK_SIZE == 32)
-+#define AES_KS_LENGTH 120
-+#define AES_RC_LENGTH 29
-+#else
-+#define AES_KS_LENGTH 4 * AES_BLOCK_SIZE
-+#define AES_RC_LENGTH (9 * AES_BLOCK_SIZE) / 8 - 8
-+#endif
-+
-+typedef struct
-+{
-+ u_int32_t aes_Nkey; // the number of words in the key input block
-+ u_int32_t aes_Nrnd; // the number of cipher rounds
-+ u_int32_t aes_e_key[AES_KS_LENGTH]; // the encryption key schedule
-+ u_int32_t aes_d_key[AES_KS_LENGTH]; // the decryption key schedule
-+#if !defined(AES_BLOCK_SIZE)
-+ u_int32_t aes_Ncol; // the number of columns in the cipher state
-+#endif
-+} aes_context;
-+
-+// THE CIPHER INTERFACE
-+
-+#if !defined(AES_BLOCK_SIZE)
-+extern void aes_set_blk(aes_context *, const int);
-+#endif
-+extern void aes_set_key(aes_context *, const unsigned char [], const int, const int);
-+extern void aes_encrypt(const aes_context *, const unsigned char [], unsigned char []);
-+extern void aes_decrypt(const aes_context *, const unsigned char [], unsigned char []);
-+
-+// The block length inputs to aes_set_block and aes_set_key are in numbers
-+// of bytes or bits. The calls to subroutines must be made in the above
-+// order but multiple calls can be made without repeating earlier calls
-+// if their parameters have not changed.
-+
-+#endif // _AES_H
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/crypto/aes_cbc.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,4 @@
-+/* Glue header */
-+#include "aes.h"
-+int AES_set_key(aes_context *aes_ctx, const u_int8_t * key, int keysize);
-+int AES_cbc_encrypt(aes_context *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt);
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/crypto/aes_xcbc_mac.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,12 @@
-+#ifndef _AES_XCBC_MAC_H
-+#define _AES_XCBC_MAC_H
-+
-+typedef u_int32_t aes_block[4];
-+typedef struct {
-+ aes_context ctx_k1;
-+ aes_block k2;
-+ aes_block k3;
-+} aes_context_mac;
-+int AES_xcbc_mac_set_key(aes_context_mac *ctxm, const u_int8_t *key, int keylen);
-+int AES_xcbc_mac_hash(const aes_context_mac *ctxm, const u_int8_t * in, int ilen, u_int8_t hash[16]);
-+#endif /* _AES_XCBC_MAC_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/crypto/cbc_generic.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,110 @@
-+#ifndef _CBC_GENERIC_H
-+#define _CBC_GENERIC_H
-+/*
-+ * CBC macro helpers
-+ *
-+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ */
-+
-+/*
-+ * Heavily inspired in loop_AES
-+ */
-+#define CBC_IMPL_BLK16(name, ctx_type, addr_type, enc_func, dec_func) \
-+int name(ctx_type *ctx, const u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
-+ int ret=ilen, pos; \
-+ const u_int32_t *iv_i; \
-+ if ((ilen) % 16) return 0; \
-+ if (encrypt) { \
-+ pos=0; \
-+ while(pos<ilen) { \
-+ if (pos==0) \
-+ iv_i=(const u_int32_t*) iv; \
-+ else \
-+ iv_i=(const u_int32_t*) (out-16); \
-+ *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
-+ *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
-+ *((u_int32_t *)(&out[ 8])) = iv_i[2]^*((const u_int32_t *)(&in[ 8])); \
-+ *((u_int32_t *)(&out[12])) = iv_i[3]^*((const u_int32_t *)(&in[12])); \
-+ enc_func(ctx, (addr_type) out, (addr_type) out); \
-+ in+=16; \
-+ out+=16; \
-+ pos+=16; \
-+ } \
-+ } else { \
-+ pos=ilen-16; \
-+ in+=pos; \
-+ out+=pos; \
-+ while(pos>=0) { \
-+ dec_func(ctx, (const addr_type) in, (addr_type) out); \
-+ if (pos==0) \
-+ iv_i=(const u_int32_t*) (iv); \
-+ else \
-+ iv_i=(const u_int32_t*) (in-16); \
-+ *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
-+ *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
-+ *((u_int32_t *)(&out[ 8])) ^= iv_i[2]; \
-+ *((u_int32_t *)(&out[12])) ^= iv_i[3]; \
-+ in-=16; \
-+ out-=16; \
-+ pos-=16; \
-+ } \
-+ } \
-+ return ret; \
-+}
-+#define CBC_IMPL_BLK8(name, ctx_type, addr_type, enc_func, dec_func) \
-+int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt) { \
-+ int ret=ilen, pos; \
-+ const u_int32_t *iv_i; \
-+ if ((ilen) % 8) return 0; \
-+ if (encrypt) { \
-+ pos=0; \
-+ while(pos<ilen) { \
-+ if (pos==0) \
-+ iv_i=(const u_int32_t*) iv; \
-+ else \
-+ iv_i=(const u_int32_t*) (out-8); \
-+ *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0])); \
-+ *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4])); \
-+ enc_func(ctx, (addr_type)out, (addr_type)out); \
-+ in+=8; \
-+ out+=8; \
-+ pos+=8; \
-+ } \
-+ } else { \
-+ pos=ilen-8; \
-+ in+=pos; \
-+ out+=pos; \
-+ while(pos>=0) { \
-+ dec_func(ctx, (const addr_type)in, (addr_type)out); \
-+ if (pos==0) \
-+ iv_i=(const u_int32_t*) (iv); \
-+ else \
-+ iv_i=(const u_int32_t*) (in-8); \
-+ *((u_int32_t *)(&out[ 0])) ^= iv_i[0]; \
-+ *((u_int32_t *)(&out[ 4])) ^= iv_i[1]; \
-+ in-=8; \
-+ out-=8; \
-+ pos-=8; \
-+ } \
-+ } \
-+ return ret; \
-+}
-+#define CBC_DECL(name, ctx_type) \
-+int name(ctx_type *ctx, u_int8_t * in, u_int8_t * out, int ilen, const u_int8_t * iv, int encrypt)
-+/*
-+Eg.:
-+CBC_IMPL_BLK16(AES_cbc_encrypt, aes_context, u_int8_t *, aes_encrypt, aes_decrypt);
-+CBC_DECL(AES_cbc_encrypt, aes_context);
-+*/
-+#endif /* _CBC_GENERIC_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/crypto/des.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,298 @@
-+/* crypto/des/des.org */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
-+ *
-+ * Always modify des.org since des.h is automatically generated from
-+ * it during SSLeay configuration.
-+ *
-+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
-+ */
-+
-+#ifndef HEADER_DES_H
-+#define HEADER_DES_H
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+
-+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
-+ * %20 speed up (longs are 8 bytes, int's are 4). */
-+/* Must be unsigned int on ia64/Itanium or DES breaks badly */
-+
-+#ifdef __KERNEL__
-+#include <linux/types.h>
-+#else
-+#include <sys/types.h>
-+#endif
-+
-+#ifndef DES_LONG
-+#define DES_LONG u_int32_t
-+#endif
-+
-+typedef unsigned char des_cblock[8];
-+typedef struct { des_cblock ks; } des_key_schedule[16];
-+
-+#define DES_KEY_SZ (sizeof(des_cblock))
-+#define DES_SCHEDULE_SZ (sizeof(des_key_schedule))
-+
-+#define DES_ENCRYPT 1
-+#define DES_DECRYPT 0
-+
-+#define DES_CBC_MODE 0
-+#define DES_PCBC_MODE 1
-+
-+#define des_ecb2_encrypt(i,o,k1,k2,e) \
-+ des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e))
-+
-+#define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \
-+ des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e))
-+
-+#define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \
-+ des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e))
-+
-+#define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \
-+ des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n))
-+
-+#define C_Block des_cblock
-+#define Key_schedule des_key_schedule
-+#ifdef KERBEROS
-+#define ENCRYPT DES_ENCRYPT
-+#define DECRYPT DES_DECRYPT
-+#endif
-+#define KEY_SZ DES_KEY_SZ
-+#define string_to_key des_string_to_key
-+#define read_pw_string des_read_pw_string
-+#define random_key des_random_key
-+#define pcbc_encrypt des_pcbc_encrypt
-+#define set_key des_set_key
-+#define key_sched des_key_sched
-+#define ecb_encrypt des_ecb_encrypt
-+#define cbc_encrypt des_cbc_encrypt
-+#define ncbc_encrypt des_ncbc_encrypt
-+#define xcbc_encrypt des_xcbc_encrypt
-+#define cbc_cksum des_cbc_cksum
-+#define quad_cksum des_quad_cksum
-+
-+/* For compatibility with the MIT lib - eay 20/05/92 */
-+typedef des_key_schedule bit_64;
-+#define des_fixup_key_parity des_set_odd_parity
-+#define des_check_key_parity check_parity
-+
-+extern int des_check_key; /* defaults to false */
-+extern int des_rw_mode; /* defaults to DES_PCBC_MODE */
-+
-+/* The next line is used to disable full ANSI prototypes, if your
-+ * compiler has problems with the prototypes, make sure this line always
-+ * evaluates to true :-) */
-+#if defined(MSDOS) || defined(__STDC__)
-+#undef NOPROTO
-+#endif
-+#ifndef NOPROTO
-+char *des_options(void);
-+void des_ecb3_encrypt(des_cblock *input,des_cblock *output,
-+ des_key_schedule ks1,des_key_schedule ks2,
-+ des_key_schedule ks3, int enc);
-+DES_LONG des_cbc_cksum(des_cblock *input,des_cblock *output,
-+ long length,des_key_schedule schedule,des_cblock *ivec);
-+void des_cbc_encrypt(des_cblock *input,des_cblock *output,long length,
-+ des_key_schedule schedule,des_cblock *ivec,int enc);
-+void des_ncbc_encrypt(des_cblock *input,des_cblock *output,long length,
-+ des_key_schedule schedule,des_cblock *ivec,int enc);
-+void des_xcbc_encrypt(des_cblock *input,des_cblock *output,long length,
-+ des_key_schedule schedule,des_cblock *ivec,
-+ des_cblock *inw,des_cblock *outw,int enc);
-+void des_cfb_encrypt(unsigned char *in,unsigned char *out,int numbits,
-+ long length,des_key_schedule schedule,des_cblock *ivec,int enc);
-+void des_ecb_encrypt(des_cblock *input,des_cblock *output,
-+ des_key_schedule ks,int enc);
-+void des_encrypt(DES_LONG *data,des_key_schedule ks, int enc);
-+void des_encrypt2(DES_LONG *data,des_key_schedule ks, int enc);
-+void des_encrypt3(DES_LONG *data, des_key_schedule ks1,
-+ des_key_schedule ks2, des_key_schedule ks3);
-+void des_decrypt3(DES_LONG *data, des_key_schedule ks1,
-+ des_key_schedule ks2, des_key_schedule ks3);
-+void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output,
-+ long length, des_key_schedule ks1, des_key_schedule ks2,
-+ des_key_schedule ks3, des_cblock *ivec, int enc);
-+void des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
-+ long length, des_key_schedule ks1, des_key_schedule ks2,
-+ des_key_schedule ks3, des_cblock *ivec, int *num, int enc);
-+void des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out,
-+ long length, des_key_schedule ks1, des_key_schedule ks2,
-+ des_key_schedule ks3, des_cblock *ivec, int *num);
-+
-+void des_xwhite_in2out(des_cblock (*des_key), des_cblock (*in_white),
-+ des_cblock (*out_white));
-+
-+int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
-+ des_cblock *iv);
-+int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
-+ des_cblock *iv);
-+char *des_fcrypt(const char *buf,const char *salt, char *ret);
-+#ifdef PERL5
-+char *des_crypt(const char *buf,const char *salt);
-+#else
-+/* some stupid compilers complain because I have declared char instead
-+ * of const char */
-+#ifndef __KERNEL__
-+#ifdef HEADER_DES_LOCL_H
-+char *crypt(const char *buf,const char *salt);
-+#else /* HEADER_DES_LOCL_H */
-+char *crypt(void);
-+#endif /* HEADER_DES_LOCL_H */
-+#endif /* __KERNEL__ */
-+#endif /* PERL5 */
-+void des_ofb_encrypt(unsigned char *in,unsigned char *out,
-+ int numbits,long length,des_key_schedule schedule,des_cblock *ivec);
-+void des_pcbc_encrypt(des_cblock *input,des_cblock *output,long length,
-+ des_key_schedule schedule,des_cblock *ivec,int enc);
-+DES_LONG des_quad_cksum(des_cblock *input,des_cblock *output,
-+ long length,int out_count,des_cblock *seed);
-+void des_random_seed(des_cblock key);
-+void des_random_key(des_cblock ret);
-+int des_read_password(des_cblock *key,char *prompt,int verify);
-+int des_read_2passwords(des_cblock *key1,des_cblock *key2,
-+ char *prompt,int verify);
-+int des_read_pw_string(char *buf,int length,char *prompt,int verify);
-+void des_set_odd_parity(des_cblock *key);
-+int des_is_weak_key(des_cblock *key);
-+int des_set_key(des_cblock *key,des_key_schedule schedule);
-+int des_key_sched(des_cblock *key,des_key_schedule schedule);
-+void des_string_to_key(char *str,des_cblock *key);
-+void des_string_to_2keys(char *str,des_cblock *key1,des_cblock *key2);
-+void des_cfb64_encrypt(unsigned char *in, unsigned char *out, long length,
-+ des_key_schedule schedule, des_cblock *ivec, int *num, int enc);
-+void des_ofb64_encrypt(unsigned char *in, unsigned char *out, long length,
-+ des_key_schedule schedule, des_cblock *ivec, int *num);
-+int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify);
-+
-+/* Extra functions from Mark Murray <mark@grondar.za> */
-+/* The following functions are not in the normal unix build or the
-+ * SSLeay build. When using the SSLeay build, use RAND_seed()
-+ * and RAND_bytes() instead. */
-+int des_new_random_key(des_cblock *key);
-+void des_init_random_number_generator(des_cblock *key);
-+void des_set_random_generator_seed(des_cblock *key);
-+void des_set_sequence_number(des_cblock new_sequence_number);
-+void des_generate_random_block(des_cblock *block);
-+
-+#else
-+
-+char *des_options();
-+void des_ecb3_encrypt();
-+DES_LONG des_cbc_cksum();
-+void des_cbc_encrypt();
-+void des_ncbc_encrypt();
-+void des_xcbc_encrypt();
-+void des_cfb_encrypt();
-+void des_ede3_cfb64_encrypt();
-+void des_ede3_ofb64_encrypt();
-+void des_ecb_encrypt();
-+void des_encrypt();
-+void des_encrypt2();
-+void des_encrypt3();
-+void des_decrypt3();
-+void des_ede3_cbc_encrypt();
-+int des_enc_read();
-+int des_enc_write();
-+char *des_fcrypt();
-+#ifdef PERL5
-+char *des_crypt();
-+#else
-+char *crypt();
-+#endif
-+void des_ofb_encrypt();
-+void des_pcbc_encrypt();
-+DES_LONG des_quad_cksum();
-+void des_random_seed();
-+void des_random_key();
-+int des_read_password();
-+int des_read_2passwords();
-+int des_read_pw_string();
-+void des_set_odd_parity();
-+int des_is_weak_key();
-+int des_set_key();
-+int des_key_sched();
-+void des_string_to_key();
-+void des_string_to_2keys();
-+void des_cfb64_encrypt();
-+void des_ofb64_encrypt();
-+int des_read_pw();
-+void des_xwhite_in2out();
-+
-+/* Extra functions from Mark Murray <mark@grondar.za> */
-+/* The following functions are not in the normal unix build or the
-+ * SSLeay build. When using the SSLeay build, use RAND_seed()
-+ * and RAND_bytes() instead. */
-+#ifdef FreeBSD
-+int des_new_random_key();
-+void des_init_random_number_generator();
-+void des_set_random_generator_seed();
-+void des_set_sequence_number();
-+void des_generate_random_block();
-+#endif
-+
-+#endif
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/mast.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,33 @@
-+struct mast_callbacks {
-+ int (*packet_encap)(struct device *mast, void *context,
-+ struct sk_buff *skb, int flowref);
-+ int (*link_inquire)(struct device *mast, void *context);
-+};
-+
-+
-+struct device *mast_init (int family,
-+ struct mast_callbacks *callbacks,
-+ unsigned int flags,
-+ unsigned int desired_unit,
-+ unsigned int max_flowref,
-+ void *context);
-+
-+int mast_destroy(struct device *mast);
-+
-+int mast_recv(struct device *mast, struct sk_buff *skb, int flowref);
-+
-+/* free this skb as being useless, increment failure count. */
-+int mast_toast(struct device *mast, struct sk_buff *skb, int flowref);
-+
-+int mast_linkstat (struct device *mast, int flowref,
-+ int status);
-+
-+int mast_setreference (struct device *mast,
-+ int defaultSA);
-+
-+int mast_setneighbor (struct device *mast,
-+ struct sockaddr *source,
-+ struct sockaddr *destination,
-+ int flowref);
-+
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,513 @@
-+#ifndef _OPENSWAN_H
-+/*
-+ * header file for FreeS/WAN library functions
-+ * Copyright (C) 1998, 1999, 2000 Henry Spencer.
-+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#define _OPENSWAN_H /* seen it, no need to see it again */
-+
-+
-+
-+/*
-+ * We've just got to have some datatypes defined... And annoyingly, just
-+ * where we get them depends on whether we're in userland or not.
-+ */
-+/* things that need to come from one place or the other, depending */
-+#ifdef __KERNEL__
-+#include <linux/types.h>
-+#include <linux/socket.h>
-+#include <linux/in.h>
-+#include <linux/string.h>
-+#include <linux/ctype.h>
-+#define assert(foo) /* nothing */
-+#else
-+#include <sys/types.h>
-+#include <netinet/in.h>
-+#include <string.h>
-+#include <ctype.h>
-+#include <assert.h>
-+#include <stdio.h>
-+
-+# define uint8_t u_int8_t
-+# define uint16_t u_int16_t
-+# define uint32_t u_int32_t
-+# define uint64_t u_int64_t
-+
-+
-+# define DEBUG_NO_STATIC static
-+
-+#endif
-+
-+#include <openswan/ipsec_param.h>
-+
-+
-+/*
-+ * Grab the kernel version to see if we have NET_21, and therefore
-+ * IPv6. Some of this is repeated from ipsec_kversions.h. Of course,
-+ * we aren't really testing if the kernel has IPv6, but rather if the
-+ * the include files do.
-+ */
-+#include <linux/version.h>
-+#ifndef KERNEL_VERSION
-+#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
-+#define NET_21
-+#endif
-+
-+#ifndef IPPROTO_COMP
-+# define IPPROTO_COMP 108
-+#endif /* !IPPROTO_COMP */
-+
-+#ifndef IPPROTO_INT
-+# define IPPROTO_INT 61
-+#endif /* !IPPROTO_INT */
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+#ifndef DEBUG_NO_STATIC
-+# define DEBUG_NO_STATIC
-+#endif
-+#else /* CONFIG_IPSEC_DEBUG */
-+#ifndef DEBUG_NO_STATIC
-+# define DEBUG_NO_STATIC static
-+#endif
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL /* KERNEL ifdef */
-+#ifndef NAT_TRAVERSAL
-+#define NAT_TRAVERSAL
-+#endif
-+#endif
-+#ifdef NAT_TRAVERSAL
-+#define ESPINUDP_WITH_NON_IKE 1 /* draft-ietf-ipsec-nat-t-ike-00/01 */
-+#define ESPINUDP_WITH_NON_ESP 2 /* draft-ietf-ipsec-nat-t-ike-02 */
-+#endif
-+
-+/*
-+ * Basic data types for the address-handling functions.
-+ * ip_address and ip_subnet are supposed to be opaque types; do not
-+ * use their definitions directly, they are subject to change!
-+ */
-+
-+/* first, some quick fakes in case we're on an old system with no IPv6 */
-+#ifndef s6_addr16
-+struct in6_addr {
-+ union
-+ {
-+ __u8 u6_addr8[16];
-+ __u16 u6_addr16[8];
-+ __u32 u6_addr32[4];
-+ } in6_u;
-+#define s6_addr in6_u.u6_addr8
-+#define s6_addr16 in6_u.u6_addr16
-+#define s6_addr32 in6_u.u6_addr32
-+};
-+struct sockaddr_in6 {
-+ unsigned short int sin6_family; /* AF_INET6 */
-+ __u16 sin6_port; /* Transport layer port # */
-+ __u32 sin6_flowinfo; /* IPv6 flow information */
-+ struct in6_addr sin6_addr; /* IPv6 address */
-+ __u32 sin6_scope_id; /* scope id (new in RFC2553) */
-+};
-+#endif /* !s6_addr16 */
-+
-+/* then the main types */
-+typedef struct {
-+ union {
-+ struct sockaddr_in v4;
-+ struct sockaddr_in6 v6;
-+ } u;
-+} ip_address;
-+typedef struct {
-+ ip_address addr;
-+ int maskbits;
-+} ip_subnet;
-+
-+/* and the SA ID stuff */
-+#ifdef __KERNEL__
-+typedef __u32 ipsec_spi_t;
-+#else
-+typedef u_int32_t ipsec_spi_t;
-+#endif
-+typedef struct { /* to identify an SA, we need: */
-+ ip_address dst; /* A. destination host */
-+ ipsec_spi_t spi; /* B. 32-bit SPI, assigned by dest. host */
-+# define SPI_PASS 256 /* magic values... */
-+# define SPI_DROP 257 /* ...for use... */
-+# define SPI_REJECT 258 /* ...with SA_INT */
-+# define SPI_HOLD 259
-+# define SPI_TRAP 260
-+# define SPI_TRAPSUBNET 261
-+ int proto; /* C. protocol */
-+# define SA_ESP 50 /* IPPROTO_ESP */
-+# define SA_AH 51 /* IPPROTO_AH */
-+# define SA_IPIP 4 /* IPPROTO_IPIP */
-+# define SA_COMP 108 /* IPPROTO_COMP */
-+# define SA_INT 61 /* IANA reserved for internal use */
-+} ip_said;
-+
-+/* misc */
-+typedef const char *err_t; /* error message, or NULL for success */
-+struct prng { /* pseudo-random-number-generator guts */
-+ unsigned char sbox[256];
-+ int i, j;
-+ unsigned long count;
-+};
-+
-+
-+/*
-+ * definitions for user space, taken from freeswan/ipsec_sa.h
-+ */
-+typedef uint32_t IPsecSAref_t;
-+
-+#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
-+
-+#define IPsecSAref2NFmark(x) ((x) << (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
-+#define NFmark2IPsecSAref(x) ((x) >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
-+
-+#define IPSEC_SAREF_NULL (~((IPsecSAref_t)0))
-+
-+/* GCC magic for use in function definitions! */
-+#ifdef GCC_LINT
-+# define PRINTF_LIKE(n) __attribute__ ((format(printf, n, n+1)))
-+# define NEVER_RETURNS __attribute__ ((noreturn))
-+# define UNUSED __attribute__ ((unused))
-+# define BLANK_FORMAT " " /* GCC_LINT whines about empty formats */
-+#else
-+# define PRINTF_LIKE(n) /* ignore */
-+# define NEVER_RETURNS /* ignore */
-+# define UNUSED /* ignore */
-+# define BLANK_FORMAT ""
-+#endif
-+
-+
-+
-+
-+
-+/*
-+ * new IPv6-compatible functions
-+ */
-+
-+/* text conversions */
-+err_t ttoul(const char *src, size_t srclen, int format, unsigned long *dst);
-+size_t ultot(unsigned long src, int format, char *buf, size_t buflen);
-+#define ULTOT_BUF (22+1) /* holds 64 bits in octal */
-+err_t ttoaddr(const char *src, size_t srclen, int af, ip_address *dst);
-+err_t tnatoaddr(const char *src, size_t srclen, int af, ip_address *dst);
-+size_t addrtot(const ip_address *src, int format, char *buf, size_t buflen);
-+/* RFC 1886 old IPv6 reverse-lookup format is the bulkiest */
-+#define ADDRTOT_BUF (32*2 + 3 + 1 + 3 + 1 + 1)
-+err_t ttosubnet(const char *src, size_t srclen, int af, ip_subnet *dst);
-+size_t subnettot(const ip_subnet *src, int format, char *buf, size_t buflen);
-+#define SUBNETTOT_BUF (ADDRTOT_BUF + 1 + 3)
-+size_t subnetporttot(const ip_subnet *src, int format, char *buf, size_t buflen);
-+#define SUBNETPROTOTOT_BUF (SUBNETTOTO_BUF + ULTOT_BUF)
-+err_t ttosa(const char *src, size_t srclen, ip_said *dst);
-+size_t satot(const ip_said *src, int format, char *bufptr, size_t buflen);
-+#define SATOT_BUF (5 + ULTOA_BUF + 1 + ADDRTOT_BUF)
-+err_t ttodata(const char *src, size_t srclen, int base, char *buf,
-+ size_t buflen, size_t *needed);
-+err_t ttodatav(const char *src, size_t srclen, int base,
-+ char *buf, size_t buflen, size_t *needed,
-+ char *errp, size_t errlen, unsigned int flags);
-+#define TTODATAV_BUF 40 /* ttodatav's largest non-literal message */
-+#define TTODATAV_IGNORESPACE (1<<1) /* ignore spaces in base64 encodings*/
-+#define TTODATAV_SPACECOUNTS 0 /* do not ignore spaces in base64 */
-+
-+size_t datatot(const char *src, size_t srclen, int format, char *buf,
-+ size_t buflen);
-+size_t keyblobtoid(const unsigned char *src, size_t srclen, char *dst,
-+ size_t dstlen);
-+size_t splitkeytoid(const unsigned char *e, size_t elen, const unsigned char *m,
-+ size_t mlen, char *dst, size_t dstlen);
-+#define KEYID_BUF 10 /* up to 9 text digits plus NUL */
-+err_t ttoprotoport(char *src, size_t src_len, u_int8_t *proto, u_int16_t *port,
-+ int *has_port_wildcard);
-+
-+/* initializations */
-+void initsaid(const ip_address *addr, ipsec_spi_t spi, int proto, ip_said *dst);
-+err_t loopbackaddr(int af, ip_address *dst);
-+err_t unspecaddr(int af, ip_address *dst);
-+err_t anyaddr(int af, ip_address *dst);
-+err_t initaddr(const unsigned char *src, size_t srclen, int af, ip_address *dst);
-+err_t initsubnet(const ip_address *addr, int maskbits, int clash, ip_subnet *dst);
-+err_t addrtosubnet(const ip_address *addr, ip_subnet *dst);
-+
-+/* misc. conversions and related */
-+err_t rangetosubnet(const ip_address *from, const ip_address *to, ip_subnet *dst);
-+int addrtypeof(const ip_address *src);
-+int subnettypeof(const ip_subnet *src);
-+size_t addrlenof(const ip_address *src);
-+size_t addrbytesptr(const ip_address *src, const unsigned char **dst);
-+size_t addrbytesof(const ip_address *src, unsigned char *dst, size_t dstlen);
-+int masktocount(const ip_address *src);
-+void networkof(const ip_subnet *src, ip_address *dst);
-+void maskof(const ip_subnet *src, ip_address *dst);
-+
-+/* tests */
-+int sameaddr(const ip_address *a, const ip_address *b);
-+int addrcmp(const ip_address *a, const ip_address *b);
-+int samesubnet(const ip_subnet *a, const ip_subnet *b);
-+int addrinsubnet(const ip_address *a, const ip_subnet *s);
-+int subnetinsubnet(const ip_subnet *a, const ip_subnet *b);
-+int subnetishost(const ip_subnet *s);
-+int samesaid(const ip_said *a, const ip_said *b);
-+int sameaddrtype(const ip_address *a, const ip_address *b);
-+int samesubnettype(const ip_subnet *a, const ip_subnet *b);
-+int isanyaddr(const ip_address *src);
-+int isunspecaddr(const ip_address *src);
-+int isloopbackaddr(const ip_address *src);
-+
-+/* low-level grot */
-+int portof(const ip_address *src);
-+void setportof(int port, ip_address *dst);
-+struct sockaddr *sockaddrof(ip_address *src);
-+size_t sockaddrlenof(const ip_address *src);
-+
-+/* PRNG */
-+void prng_init(struct prng *prng, const unsigned char *key, size_t keylen);
-+void prng_bytes(struct prng *prng, unsigned char *dst, size_t dstlen);
-+unsigned long prng_count(struct prng *prng);
-+void prng_final(struct prng *prng);
-+
-+/* odds and ends */
-+const char *ipsec_version_code(void);
-+const char *ipsec_version_string(void);
-+const char **ipsec_copyright_notice(void);
-+
-+const char *dns_string_rr(int rr, char *buf, int bufsize);
-+const char *dns_string_datetime(time_t seconds,
-+ char *buf,
-+ int bufsize);
-+
-+
-+/*
-+ * old functions, to be deleted eventually
-+ */
-+
-+/* unsigned long */
-+const char * /* NULL for success, else string literal */
-+atoul(
-+ const char *src,
-+ size_t srclen, /* 0 means strlen(src) */
-+ int base, /* 0 means figure it out */
-+ unsigned long *resultp
-+);
-+size_t /* space needed for full conversion */
-+ultoa(
-+ unsigned long n,
-+ int base,
-+ char *dst,
-+ size_t dstlen
-+);
-+#define ULTOA_BUF 21 /* just large enough for largest result, */
-+ /* assuming 64-bit unsigned long! */
-+
-+/* Internet addresses */
-+const char * /* NULL for success, else string literal */
-+atoaddr(
-+ const char *src,
-+ size_t srclen, /* 0 means strlen(src) */
-+ struct in_addr *addr
-+);
-+size_t /* space needed for full conversion */
-+addrtoa(
-+ struct in_addr addr,
-+ int format, /* character; 0 means default */
-+ char *dst,
-+ size_t dstlen
-+);
-+#define ADDRTOA_BUF 16 /* just large enough for largest result */
-+
-+/* subnets */
-+const char * /* NULL for success, else string literal */
-+atosubnet(
-+ const char *src,
-+ size_t srclen, /* 0 means strlen(src) */
-+ struct in_addr *addr,
-+ struct in_addr *mask
-+);
-+size_t /* space needed for full conversion */
-+subnettoa(
-+ struct in_addr addr,
-+ struct in_addr mask,
-+ int format, /* character; 0 means default */
-+ char *dst,
-+ size_t dstlen
-+);
-+#define SUBNETTOA_BUF 32 /* large enough for worst case result */
-+
-+/* ranges */
-+const char * /* NULL for success, else string literal */
-+atoasr(
-+ const char *src,
-+ size_t srclen, /* 0 means strlen(src) */
-+ char *type, /* 'a', 's', 'r' */
-+ struct in_addr *addrs /* two-element array */
-+);
-+size_t /* space needed for full conversion */
-+rangetoa(
-+ struct in_addr *addrs, /* two-element array */
-+ int format, /* character; 0 means default */
-+ char *dst,
-+ size_t dstlen
-+);
-+#define RANGETOA_BUF 34 /* large enough for worst case result */
-+
-+/* data types for SA conversion functions */
-+
-+/* generic data, e.g. keys */
-+const char * /* NULL for success, else string literal */
-+atobytes(
-+ const char *src,
-+ size_t srclen, /* 0 means strlen(src) */
-+ char *dst,
-+ size_t dstlen,
-+ size_t *lenp /* NULL means don't bother telling me */
-+);
-+size_t /* 0 failure, else true size */
-+bytestoa(
-+ const char *src,
-+ size_t srclen,
-+ int format, /* character; 0 means default */
-+ char *dst,
-+ size_t dstlen
-+);
-+
-+/* old versions of generic-data functions; deprecated */
-+size_t /* 0 failure, else true size */
-+atodata(
-+ const char *src,
-+ size_t srclen, /* 0 means strlen(src) */
-+ char *dst,
-+ size_t dstlen
-+);
-+size_t /* 0 failure, else true size */
-+datatoa(
-+ const char *src,
-+ size_t srclen,
-+ int format, /* character; 0 means default */
-+ char *dst,
-+ size_t dstlen
-+);
-+
-+/* part extraction and special addresses */
-+struct in_addr
-+subnetof(
-+ struct in_addr addr,
-+ struct in_addr mask
-+);
-+struct in_addr
-+hostof(
-+ struct in_addr addr,
-+ struct in_addr mask
-+);
-+struct in_addr
-+broadcastof(
-+ struct in_addr addr,
-+ struct in_addr mask
-+);
-+
-+/* mask handling */
-+int
-+goodmask(
-+ struct in_addr mask
-+);
-+int
-+masktobits(
-+ struct in_addr mask
-+);
-+struct in_addr
-+bitstomask(
-+ int n
-+);
-+
-+
-+
-+/*
-+ * general utilities
-+ */
-+
-+#ifndef __KERNEL__
-+/* option pickup from files (userland only because of use of FILE) */
-+const char *optionsfrom(const char *filename, int *argcp, char ***argvp,
-+ int optind, FILE *errorreport);
-+
-+/* sanitize a string */
-+extern size_t sanitize_string(char *buf, size_t size);
-+
-+#endif
-+
-+
-+/*
-+ * ENUM of klips debugging values. Not currently used in klips.
-+ * debug flag is actually 32 -bits, but only one bit is ever used,
-+ * so we can actually pack it all into a single 32-bit word.
-+ */
-+enum klips_debug_flags {
-+ KDF_VERBOSE = 0,
-+ KDF_XMIT = 1,
-+ KDF_NETLINK = 2, /* obsolete */
-+ KDF_XFORM = 3,
-+ KDF_EROUTE = 4,
-+ KDF_SPI = 5,
-+ KDF_RADIJ = 6,
-+ KDF_ESP = 7,
-+ KDF_AH = 8, /* obsolete */
-+ KDF_RCV = 9,
-+ KDF_TUNNEL = 10,
-+ KDF_PFKEY = 11,
-+ KDF_COMP = 12
-+};
-+
-+
-+/*
-+ * Debugging levels for pfkey_lib_debug
-+ */
-+#define PF_KEY_DEBUG_PARSE_NONE 0
-+#define PF_KEY_DEBUG_PARSE_PROBLEM 1
-+#define PF_KEY_DEBUG_PARSE_STRUCT 2
-+#define PF_KEY_DEBUG_PARSE_FLOW 4
-+#define PF_KEY_DEBUG_BUILD 8
-+#define PF_KEY_DEBUG_PARSE_MAX 15
-+
-+extern unsigned int pfkey_lib_debug; /* bits selecting what to report */
-+
-+/*
-+ * pluto and lwdnsq need to know the maximum size of the commands to,
-+ * and replies from lwdnsq.
-+ */
-+
-+#define LWDNSQ_CMDBUF_LEN 1024
-+#define LWDNSQ_RESULT_LEN_MAX 4096
-+
-+
-+/* syntax for passthrough SA */
-+#ifndef PASSTHROUGHNAME
-+#define PASSTHROUGHNAME "%passthrough"
-+#define PASSTHROUGH4NAME "%passthrough4"
-+#define PASSTHROUGH6NAME "%passthrough6"
-+#define PASSTHROUGHIS "tun0@0.0.0.0"
-+#define PASSTHROUGH4IS "tun0@0.0.0.0"
-+#define PASSTHROUGH6IS "tun0@::"
-+#define PASSTHROUGHTYPE "tun"
-+#define PASSTHROUGHSPI 0
-+#define PASSTHROUGHDST 0
-+#endif
-+
-+
-+
-+#endif /* _OPENSWAN_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipcomp.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,61 @@
-+/*
-+ * IPCOMP zlib interface code.
-+ * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
-+ * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+
-+ RCSID $Id$
-+
-+ */
-+
-+/* SSS */
-+
-+#ifndef _IPCOMP_H
-+#define _IPCOMP_H
-+
-+/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
-+#ifndef IPCOMP_PREFIX
-+#define IPCOMP_PREFIX
-+#endif /* IPCOMP_PREFIX */
-+
-+#ifndef IPPROTO_COMP
-+#define IPPROTO_COMP 108
-+#endif /* IPPROTO_COMP */
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int sysctl_ipsec_debug_ipcomp;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+struct ipcomphdr { /* IPCOMP header */
-+ __u8 ipcomp_nh; /* Next header (protocol) */
-+ __u8 ipcomp_flags; /* Reserved, must be 0 */
-+ __u16 ipcomp_cpi; /* Compression Parameter Index */
-+};
-+
-+extern struct inet_protocol comp_protocol;
-+extern int sysctl_ipsec_debug_ipcomp;
-+
-+#define IPCOMP_UNCOMPRESSABLE 0x000000001
-+#define IPCOMP_COMPRESSIONERROR 0x000000002
-+#define IPCOMP_PARMERROR 0x000000004
-+#define IPCOMP_DECOMPRESSIONERROR 0x000000008
-+
-+#define IPCOMP_ADAPT_INITIAL_TRIES 8
-+#define IPCOMP_ADAPT_INITIAL_SKIP 4
-+#define IPCOMP_ADAPT_SUBSEQ_TRIES 2
-+#define IPCOMP_ADAPT_SUBSEQ_SKIP 8
-+
-+/* Function prototypes */
-+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
-+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
-+
-+#endif /* _IPCOMP_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_ah.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,190 @@
-+/*
-+ * Authentication Header declarations
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#include "ipsec_md5h.h"
-+#include "ipsec_sha1.h"
-+
-+#ifndef IPPROTO_AH
-+#define IPPROTO_AH 51
-+#endif /* IPPROTO_AH */
-+
-+#include "ipsec_auth.h"
-+
-+#ifdef __KERNEL__
-+
-+extern struct inet_protocol ah_protocol;
-+
-+struct options;
-+
-+struct ahhdr /* Generic AH header */
-+{
-+ __u8 ah_nh; /* Next header (protocol) */
-+ __u8 ah_hl; /* AH length, in 32-bit words */
-+ __u16 ah_rv; /* reserved, must be 0 */
-+ __u32 ah_spi; /* Security Parameters Index */
-+ __u32 ah_rpl; /* Replay prevention */
-+ __u8 ah_data[AHHMAC_HASHLEN];/* Authentication hash */
-+};
-+#define AH_BASIC_LEN 8 /* basic AH header is 8 bytes, nh,hl,rv,spi
-+ * and the ah_hl, says how many bytes after that
-+ * to cover. */
-+
-+extern struct xform_functions ah_xform_funcs[];
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int debug_ah;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#endif /* __KERNEL__ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.23 2004/04/05 19:55:04 mcr
-+ * Moved from linux/include/freeswan/ipsec_ah.h,v
-+ *
-+ * Revision 1.22 2004/04/05 19:41:05 mcr
-+ * merged alg-branch code.
-+ *
-+ * Revision 1.21 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.22 2003/12/11 20:14:58 mcr
-+ * refactored the xmit code, to move all encapsulation
-+ * code into protocol functions. Note that all functions
-+ * are essentially done by a single function, which is probably
-+ * wrong.
-+ * the rcv_functions structures are renamed xform_functions.
-+ *
-+ * Revision 1.21 2003/12/06 21:21:19 mcr
-+ * split up receive path into per-transform files, for
-+ * easier later removal.
-+ *
-+ * Revision 1.20.8.1 2003/12/22 15:25:52 jjo
-+ * Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.20 2003/02/06 02:21:34 rgb
-+ *
-+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
-+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
-+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
-+ *
-+ * Revision 1.19 2002/09/16 21:19:13 mcr
-+ * fixes for west-ah-icmp-01 - length of AH header must be
-+ * calculated properly, and next_header field properly copied.
-+ *
-+ * Revision 1.18 2002/05/14 02:37:02 rgb
-+ * Change reference from _TDB to _IPSA.
-+ *
-+ * Revision 1.17 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_ah.h,v
-+ *
-+ * Revision 1.16 2002/02/20 01:27:06 rgb
-+ * Ditched a pile of structs only used by the old Netlink interface.
-+ *
-+ * Revision 1.15 2001/12/11 02:35:57 rgb
-+ * Change "struct net_device" to "struct device" for 2.2 compatibility.
-+ *
-+ * Revision 1.14 2001/11/26 09:23:47 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.13.2.1 2001/09/25 02:18:24 mcr
-+ * replace "struct device" with "struct netdevice"
-+ *
-+ * Revision 1.13 2001/06/14 19:35:08 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.12 2000/09/12 03:21:20 rgb
-+ * Cleared out unused htonq.
-+ *
-+ * Revision 1.11 2000/09/08 19:12:55 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.10 2000/01/21 06:13:10 rgb
-+ * Tidied up spacing.
-+ * Added macros for HMAC padding magic numbers.(kravietz)
-+ *
-+ * Revision 1.9 1999/12/07 18:16:23 rgb
-+ * Fixed comments at end of #endif lines.
-+ *
-+ * Revision 1.8 1999/04/11 00:28:56 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.7 1999/04/06 04:54:25 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.6 1999/01/26 02:06:01 rgb
-+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
-+ *
-+ * Revision 1.5 1999/01/22 06:17:49 rgb
-+ * Updated macro comments.
-+ * Added context types to support algorithm switch code.
-+ * 64-bit clean-up -- converting 'u long long' to __u64.
-+ *
-+ * Revision 1.4 1998/07/14 15:54:56 rgb
-+ * Add #ifdef __KERNEL__ to protect kernel-only structures.
-+ *
-+ * Revision 1.3 1998/06/30 18:05:16 rgb
-+ * Comment out references to htonq.
-+ *
-+ * Revision 1.2 1998/06/25 19:33:46 rgb
-+ * Add prototype for protocol receive function.
-+ * Rearrange for more logical layout.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:43 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.4 1998/05/18 22:28:43 rgb
-+ * Disable key printing facilities from /proc/net/ipsec_*.
-+ *
-+ * Revision 1.3 1998/04/21 21:29:07 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.2 1998/04/12 22:03:17 rgb
-+ * Updated ESP-3DES-HMAC-MD5-96,
-+ * ESP-DES-HMAC-MD5-96,
-+ * AH-HMAC-MD5-96,
-+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
-+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
-+ *
-+ * Fixed eroute references in /proc/net/ipsec*.
-+ *
-+ * Started to patch module unloading memory leaks in ipsec_netlink and
-+ * radij tree unloading.
-+ *
-+ * Revision 1.1 1998/04/09 03:05:55 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * Added definitions for new AH transforms.
-+ *
-+ * Revision 0.3 1996/11/20 14:35:48 ji
-+ * Minor Cleanup.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_alg.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,260 @@
-+/*
-+ * Modular extensions service and registration functions interface
-+ *
-+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
-+ *
-+ * ipsec_alg.h,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
-+ *
-+ */
-+/*
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+ * for more details.
-+ *
-+ */
-+#ifndef IPSEC_ALG_H
-+#define IPSEC_ALG_H
-+
-+/*
-+ * gcc >= 3.2 has removed __FUNCTION__, replaced by C99 __func__
-+ * *BUT* its a compiler variable.
-+ */
-+#if (__GNUC__ >= 3)
-+#ifndef __FUNCTION__
-+#define __FUNCTION__ __func__
-+#endif
-+#endif
-+
-+/* Version 0.8.1-0 */
-+#define IPSEC_ALG_VERSION 0x00080100
-+
-+#include <linux/types.h>
-+#include <linux/list.h>
-+#include <asm/atomic.h>
-+/*
-+ * The following structs are used via pointers in ipsec_alg object to
-+ * avoid ipsec_alg.h coupling with freeswan headers, thus simplifying
-+ * module development
-+ */
-+struct ipsec_sa;
-+struct esp;
-+
-+/**************************************
-+ *
-+ * Main registration object
-+ *
-+ *************************************/
-+#define IPSEC_ALG_VERSION_QUAD(v) \
-+ (v>>24),((v>>16)&0xff),((v>>8)&0xff),(v&0xff)
-+/*
-+ * Main ipsec_alg objects: "OOPrograming wannabe"
-+ * Hierachy (carefully handled with _minimal_ cast'ing):
-+ *
-+ * ipsec_alg+
-+ * +->ipsec_alg_enc (ixt_alg_type=SADB_EXT_SUPPORTED_ENCRYPT)
-+ * +->ipsec_alg_auth (ixt_alg_type=SADB_EXT_SUPPORTED_AUTH)
-+ */
-+
-+/***************************************************************
-+ *
-+ * INTERFACE object: struct ipsec_alg
-+ *
-+ ***************************************************************/
-+
-+/*
-+ * common part for every struct ipsec_alg_*
-+ * (sortof poor's man OOP)
-+ */
-+#define IPSEC_ALG_STRUCT_COMMON \
-+ unsigned ixt_version; /* only allow this version (or 'near')*/ \
-+ struct list_head ixt_list; /* dlinked list */ \
-+ struct module *ixt_module; /* THIS_MODULE */ \
-+ unsigned ixt_state; /* state flags */ \
-+ atomic_t ixt_refcnt; /* ref. count when pointed from ipsec_sa */ \
-+ char ixt_name[16]; /* descriptive short name, eg. "3des" */ \
-+ void *ixt_data; /* private for algo implementation */ \
-+ uint8_t ixt_blocksize; /* blocksize in bytes */ \
-+ \
-+ /* THIS IS A COPY of struct supported (lib/pfkey.h) \
-+ * please keep in sync until we migrate 'supported' stuff \
-+ * to ipsec_alg \
-+ */ \
-+ uint16_t ixt_alg_type; /* correspond to IPSEC_ALG_{ENCRYPT,AUTH} */ \
-+ uint8_t ixt_alg_id; /* enc. alg. number, eg. ESP_3DES */ \
-+ uint8_t ixt_ivlen; /* ivlen in bits, expected to be multiple of 8! */ \
-+ uint16_t ixt_keyminbits;/* min. keybits (of entropy) */ \
-+ uint16_t ixt_keymaxbits;/* max. keybits (of entropy) */
-+
-+#define ixt_support ixt_alg_type
-+
-+#define IPSEC_ALG_ST_SUPP 0x01
-+#define IPSEC_ALG_ST_REGISTERED 0x02
-+#define IPSEC_ALG_ST_EXCL 0x04
-+struct ipsec_alg {
-+ IPSEC_ALG_STRUCT_COMMON
-+};
-+/*
-+ * Note the const in cbc_encrypt IV arg:
-+ * some ciphers like to toast passed IV (eg. 3DES): make a local IV copy
-+ */
-+struct ipsec_alg_enc {
-+ IPSEC_ALG_STRUCT_COMMON
-+ unsigned ixt_e_keylen; /* raw key length in bytes */
-+ unsigned ixt_e_ctx_size; /* sa_p->key_e_size */
-+ int (*ixt_e_set_key)(struct ipsec_alg_enc *alg, __u8 *key_e, const __u8 *key, size_t keysize);
-+ __u8 *(*ixt_e_new_key)(struct ipsec_alg_enc *alg, const __u8 *key, size_t keysize);
-+ void (*ixt_e_destroy_key)(struct ipsec_alg_enc *alg, __u8 *key_e);
-+ int (*ixt_e_cbc_encrypt)(struct ipsec_alg_enc *alg, __u8 *key_e, __u8 *in, int ilen, const __u8 *iv, int encrypt);
-+};
-+struct ipsec_alg_auth {
-+ IPSEC_ALG_STRUCT_COMMON
-+ unsigned ixt_a_keylen; /* raw key length in bytes */
-+ unsigned ixt_a_ctx_size; /* sa_p->key_a_size */
-+ unsigned ixt_a_authlen; /* 'natural' auth. hash len (bytes) */
-+ int (*ixt_a_hmac_set_key)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *key, int keylen);
-+ int (*ixt_a_hmac_hash)(struct ipsec_alg_auth *alg, __u8 *key_a, const __u8 *dat, int len, __u8 *hash, int hashlen);
-+};
-+/*
-+ * These are _copies_ of SADB_EXT_SUPPORTED_{AUTH,ENCRYPT},
-+ * to avoid header coupling for true constants
-+ * about headers ... "cp is your friend" --Linus
-+ */
-+#define IPSEC_ALG_TYPE_AUTH 14
-+#define IPSEC_ALG_TYPE_ENCRYPT 15
-+
-+/***************************************************************
-+ *
-+ * INTERFACE for module loading,testing, and unloading
-+ *
-+ ***************************************************************/
-+/* - registration calls */
-+int register_ipsec_alg(struct ipsec_alg *);
-+int unregister_ipsec_alg(struct ipsec_alg *);
-+/* - optional (simple test) for algos */
-+int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int testparm);
-+/* inline wrappers (usefull for type validation */
-+static inline int register_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
-+ return register_ipsec_alg((struct ipsec_alg*)ixt);
-+}
-+static inline int unregister_ipsec_alg_enc(struct ipsec_alg_enc *ixt) {
-+ return unregister_ipsec_alg((struct ipsec_alg*)ixt);
-+}
-+static inline int register_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
-+ return register_ipsec_alg((struct ipsec_alg*)ixt);
-+}
-+static inline int unregister_ipsec_alg_auth(struct ipsec_alg_auth *ixt) {
-+ return unregister_ipsec_alg((struct ipsec_alg*)ixt);
-+}
-+
-+/*****************************************************************
-+ *
-+ * INTERFACE for ENC services: key creation, encrypt function
-+ *
-+ *****************************************************************/
-+
-+#define IPSEC_ALG_ENCRYPT 1
-+#define IPSEC_ALG_DECRYPT 0
-+
-+/* encryption key context creation function */
-+int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p);
-+/*
-+ * ipsec_alg_esp_encrypt(): encrypt ilen bytes in idat returns
-+ * 0 or ERR<0
-+ */
-+int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 *idat, int ilen, const __u8 *iv, int action);
-+
-+/***************************************************************
-+ *
-+ * INTERFACE for AUTH services: key creation, hash functions
-+ *
-+ ***************************************************************/
-+int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p);
-+int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) ;
-+#define ipsec_alg_sa_esp_update(c,k,l) ipsec_alg_sa_esp_hash(c,k,l,NULL,0)
-+
-+/* only called from ipsec_init.c */
-+int ipsec_alg_init(void);
-+
-+/* algo module glue for static algos */
-+void ipsec_alg_static_init(void);
-+typedef int (*ipsec_alg_init_func_t) (void);
-+
-+/**********************************************
-+ *
-+ * INTERFACE for ipsec_sa init and wipe
-+ *
-+ **********************************************/
-+
-+/* returns true if ipsec_sa has ipsec_alg obj attached */
-+/*
-+ * Initializes ipsec_sa's ipsec_alg object, using already loaded
-+ * proto, authalg, encalg.; links ipsec_alg objects (enc, auth)
-+ */
-+int ipsec_alg_sa_init(struct ipsec_sa *sa_p);
-+/*
-+ * Destroys ipsec_sa's ipsec_alg object
-+ * unlinking ipsec_alg objects
-+ */
-+int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p);
-+
-+#define IPSEC_ALG_MODULE_INIT_MOD( func_name ) \
-+ static int func_name(void); \
-+ module_init(func_name); \
-+ static int __init func_name(void)
-+#define IPSEC_ALG_MODULE_EXIT_MOD( func_name ) \
-+ static void func_name(void); \
-+ module_exit(func_name); \
-+ static void __exit func_name(void)
-+
-+#define IPSEC_ALG_MODULE_INIT_STATIC( func_name ) \
-+ extern int func_name(void); \
-+ int func_name(void)
-+#define IPSEC_ALG_MODULE_EXIT_STATIC( func_name ) \
-+ extern void func_name(void); \
-+ void func_name(void)
-+
-+/**********************************************
-+ *
-+ * 2.2 backport for some 2.4 useful module stuff
-+ *
-+ **********************************************/
-+#ifdef MODULE
-+#ifndef THIS_MODULE
-+#define THIS_MODULE (&__this_module)
-+#endif
-+#ifndef module_init
-+typedef int (*__init_module_func_t)(void);
-+typedef void (*__cleanup_module_func_t)(void);
-+
-+#define module_init(x) \
-+ int init_module(void) __attribute__((alias(#x))); \
-+ static inline __init_module_func_t __init_module_inline(void) \
-+ { return x; }
-+#define module_exit(x) \
-+ void cleanup_module(void) __attribute__((alias(#x))); \
-+ static inline __cleanup_module_func_t __cleanup_module_inline(void) \
-+ { return x; }
-+#endif
-+#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_MOD( func_name )
-+#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_MOD( func_name )
-+
-+#else /* not MODULE */
-+#ifndef THIS_MODULE
-+#define THIS_MODULE NULL
-+#endif
-+/*
-+ * I only want module_init() magic
-+ * when algo.c file *is THE MODULE*, in all other
-+ * cases, initialization is called explicitely from ipsec_alg_init()
-+ */
-+#define IPSEC_ALG_MODULE_INIT( func_name ) IPSEC_ALG_MODULE_INIT_STATIC(func_name)
-+#define IPSEC_ALG_MODULE_EXIT( func_name ) IPSEC_ALG_MODULE_EXIT_STATIC(func_name)
-+#endif
-+
-+#endif /* IPSEC_ALG_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_auth.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,100 @@
-+/*
-+ * Authentication Header declarations
-+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#include "ipsec_md5h.h"
-+#include "ipsec_sha1.h"
-+
-+#ifndef IPSEC_AUTH_H
-+#define IPSEC_AUTH_H
-+
-+#define AH_FLENGTH 12 /* size of fixed part */
-+#define AHMD5_KMAX 64 /* MD5 max 512 bits key */
-+#define AHMD5_AMAX 12 /* MD5 96 bits of authenticator */
-+
-+#define AHMD596_KLEN 16 /* MD5 128 bits key */
-+#define AHSHA196_KLEN 20 /* SHA1 160 bits key */
-+
-+#define AHMD596_ALEN 16 /* MD5 128 bits authentication length */
-+#define AHSHA196_ALEN 20 /* SHA1 160 bits authentication length */
-+
-+#define AHMD596_BLKLEN 64 /* MD5 block length */
-+#define AHSHA196_BLKLEN 64 /* SHA1 block length */
-+#define AHSHA2_256_BLKLEN 64 /* SHA2-256 block length */
-+#define AHSHA2_384_BLKLEN 128 /* SHA2-384 block length (?) */
-+#define AHSHA2_512_BLKLEN 128 /* SHA2-512 block length */
-+
-+#define AH_BLKLEN_MAX 128 /* keep up to date! */
-+
-+
-+#define AH_AMAX AHSHA196_ALEN /* keep up to date! */
-+#define AHHMAC_HASHLEN 12 /* authenticator length of 96bits */
-+#define AHHMAC_RPLLEN 4 /* 32 bit replay counter */
-+
-+#define DB_AH_PKTRX 0x0001
-+#define DB_AH_PKTRX2 0x0002
-+#define DB_AH_DMP 0x0004
-+#define DB_AH_IPSA 0x0010
-+#define DB_AH_XF 0x0020
-+#define DB_AH_INAU 0x0040
-+#define DB_AH_REPLAY 0x0100
-+
-+#ifdef __KERNEL__
-+
-+/* General HMAC algorithm is described in RFC 2104 */
-+
-+#define HMAC_IPAD 0x36
-+#define HMAC_OPAD 0x5C
-+
-+struct md5_ctx {
-+ MD5_CTX ictx; /* context after H(K XOR ipad) */
-+ MD5_CTX octx; /* context after H(K XOR opad) */
-+};
-+
-+struct sha1_ctx {
-+ SHA1_CTX ictx; /* context after H(K XOR ipad) */
-+ SHA1_CTX octx; /* context after H(K XOR opad) */
-+};
-+
-+struct auth_alg {
-+ void (*init)(void *ctx);
-+ void (*update)(void *ctx, unsigned char *bytes, __u32 len);
-+ void (*final)(unsigned char *hash, void *ctx);
-+ int hashlen;
-+};
-+
-+struct options;
-+
-+#endif /* __KERNEL__ */
-+#endif /* IPSEC_AUTH_H */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.3 2004/04/06 02:49:08 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.2 2004/04/05 19:55:04 mcr
-+ * Moved from linux/include/freeswan/ipsec_auth.h,v
-+ *
-+ * Revision 1.1 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.1 2003/12/06 21:21:19 mcr
-+ * split up receive path into per-transform files, for
-+ * easier later removal.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_encap.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,149 @@
-+/*
-+ * declarations relevant to encapsulation-like operations
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifndef _IPSEC_ENCAP_H_
-+
-+#define SENT_IP4 16 /* data is two struct in_addr + proto + ports*/
-+ /* (2 * sizeof(struct in_addr)) */
-+ /* sizeof(struct sockaddr_encap)
-+ - offsetof(struct sockaddr_encap, Sen.Sip4.Src) */
-+
-+struct sockaddr_encap
-+{
-+ __u8 sen_len; /* length */
-+ __u8 sen_family; /* AF_ENCAP */
-+ __u16 sen_type; /* see SENT_* */
-+ union
-+ {
-+ struct /* SENT_IP4 */
-+ {
-+ struct in_addr Src;
-+ struct in_addr Dst;
-+ __u8 Proto;
-+ __u16 Sport;
-+ __u16 Dport;
-+ } Sip4;
-+ } Sen;
-+};
-+
-+#define sen_ip_src Sen.Sip4.Src
-+#define sen_ip_dst Sen.Sip4.Dst
-+#define sen_proto Sen.Sip4.Proto
-+#define sen_sport Sen.Sip4.Sport
-+#define sen_dport Sen.Sip4.Dport
-+
-+#ifndef AF_ENCAP
-+#define AF_ENCAP 26
-+#endif /* AF_ENCAP */
-+
-+#define _IPSEC_ENCAP_H_
-+#endif /* _IPSEC_ENCAP_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.19 2004/04/05 19:55:04 mcr
-+ * Moved from linux/include/freeswan/ipsec_encap.h,v
-+ *
-+ * Revision 1.18 2003/10/31 02:27:05 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.17.30.1 2003/09/21 13:59:38 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.17 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_encap.h,v
-+ *
-+ * Revision 1.16 2001/11/26 09:23:47 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.15.2.1 2001/09/25 02:18:54 mcr
-+ * struct eroute moved to ipsec_eroute.h
-+ *
-+ * Revision 1.15 2001/09/14 16:58:36 rgb
-+ * Added support for storing the first and last packets through a HOLD.
-+ *
-+ * Revision 1.14 2001/09/08 21:13:31 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.13 2001/06/14 19:35:08 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.12 2001/05/27 06:12:10 rgb
-+ * Added structures for pid, packet count and last access time to eroute.
-+ * Added packet count to beginning of /proc/net/ipsec_eroute.
-+ *
-+ * Revision 1.11 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.10 2000/03/22 16:15:36 rgb
-+ * Fixed renaming of dev_get (MB).
-+ *
-+ * Revision 1.9 2000/01/21 06:13:26 rgb
-+ * Added a macro for AF_ENCAP
-+ *
-+ * Revision 1.8 1999/12/31 14:56:55 rgb
-+ * MB fix for 2.3 dev-use-count.
-+ *
-+ * Revision 1.7 1999/11/18 04:09:18 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ *
-+ * Revision 1.6 1999/09/24 00:34:13 rgb
-+ * Add Marc Boucher's support for 2.3.xx+.
-+ *
-+ * Revision 1.5 1999/04/11 00:28:57 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.4 1999/04/06 04:54:25 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.3 1998/10/19 14:44:28 rgb
-+ * Added inclusion of freeswan.h.
-+ * sa_id structure implemented and used: now includes protocol.
-+ *
-+ * Revision 1.2 1998/07/14 18:19:33 rgb
-+ * Added #ifdef __KERNEL__ directives to restrict scope of header.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:44 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.2 1998/04/21 21:29:10 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.1 1998/04/09 03:05:58 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * Minor cosmetic changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:35:48 ji
-+ * Minor Cleanup.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_eroute.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,112 @@
-+/*
-+ * @(#) declarations of eroute structures
-+ *
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ * Copyright (C) 2001 Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ * derived from ipsec_encap.h 1.15 on 2001/9/18 by mcr.
-+ *
-+ */
-+
-+#ifndef _IPSEC_EROUTE_H_
-+
-+#include "radij.h"
-+#include "ipsec_encap.h"
-+#include "ipsec_radij.h"
-+
-+/*
-+ * The "type" is really part of the address as far as the routing
-+ * system is concerned. By using only one bit in the type field
-+ * for each type, we sort-of make sure that different types of
-+ * encapsulation addresses won't be matched against the wrong type.
-+ */
-+
-+/*
-+ * An entry in the radix tree
-+ */
-+
-+struct rjtentry
-+{
-+ struct radij_node rd_nodes[2]; /* tree glue, and other values */
-+#define rd_key(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_key))
-+#define rd_mask(r) ((struct sockaddr_encap *)((r)->rd_nodes->rj_mask))
-+ short rd_flags;
-+ short rd_count;
-+};
-+
-+struct ident
-+{
-+ __u16 type; /* identity type */
-+ __u64 id; /* identity id */
-+ __u8 len; /* identity len */
-+ caddr_t data; /* identity data */
-+};
-+
-+/*
-+ * An encapsulation route consists of a pointer to a
-+ * radix tree entry and a SAID (a destination_address/SPI/protocol triple).
-+ */
-+
-+struct eroute
-+{
-+ struct rjtentry er_rjt;
-+ ip_said er_said;
-+ uint32_t er_pid;
-+ uint32_t er_count;
-+ uint64_t er_lasttime;
-+ struct sockaddr_encap er_eaddr; /* MCR get rid of _encap, it is silly*/
-+ struct sockaddr_encap er_emask;
-+ struct ident er_ident_s;
-+ struct ident er_ident_d;
-+ struct sk_buff* er_first;
-+ struct sk_buff* er_last;
-+};
-+
-+#define er_dst er_said.dst
-+#define er_spi er_said.spi
-+
-+#define _IPSEC_EROUTE_H_
-+#endif /* _IPSEC_EROUTE_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.5 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_eroute.h,v
-+ *
-+ * Revision 1.4 2003/10/31 02:27:05 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.3.30.2 2003/10/29 01:10:19 mcr
-+ * elimited "struct sa_id"
-+ *
-+ * Revision 1.3.30.1 2003/09/21 13:59:38 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.3 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_eroute.h,v
-+ *
-+ * Revision 1.2 2001/11/26 09:16:13 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:18:54 mcr
-+ * struct eroute moved to ipsec_eroute.h
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_errs.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,53 @@
-+/*
-+ * @(#) definition of ipsec_errs structure
-+ *
-+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ * and Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ */
-+
-+/*
-+ * This file describes the errors/statistics that FreeSWAN collects.
-+ *
-+ */
-+
-+struct ipsec_errs {
-+ __u32 ips_alg_errs; /* number of algorithm errors */
-+ __u32 ips_auth_errs; /* # of authentication errors */
-+ __u32 ips_encsize_errs; /* # of encryption size errors*/
-+ __u32 ips_encpad_errs; /* # of encryption pad errors*/
-+ __u32 ips_replaywin_errs; /* # of pkt sequence errors */
-+};
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.4 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_errs.h,v
-+ *
-+ * Revision 1.3 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_errs.h,v
-+ *
-+ * Revision 1.2 2001/11/26 09:16:13 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:25:57 mcr
-+ * lifetime structure created and common functions created.
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_esp.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,147 @@
-+/*
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#include "openswan/ipsec_md5h.h"
-+#include "openswan/ipsec_sha1.h"
-+
-+#include "crypto/des.h"
-+
-+#ifndef IPPROTO_ESP
-+#define IPPROTO_ESP 50
-+#endif /* IPPROTO_ESP */
-+
-+#define ESP_HEADER_LEN 8 /* 64 bits header (spi+rpl)*/
-+
-+#define EMT_ESPDESCBC_ULEN 20 /* coming from user mode */
-+#define EMT_ESPDES_KMAX 64 /* 512 bit secret key enough? */
-+#define EMT_ESPDES_KEY_SZ 8 /* 56 bit secret key with parity = 64 bits */
-+#define EMT_ESP3DES_KEY_SZ 24 /* 168 bit secret key with parity = 192 bits */
-+#define EMT_ESPDES_IV_SZ 8 /* IV size */
-+#define ESP_DESCBC_BLKLEN 8 /* DES-CBC block size */
-+
-+#define ESP_IV_MAXSZ 16 /* This is _critical_ */
-+#define ESP_IV_MAXSZ_INT (ESP_IV_MAXSZ/sizeof(int))
-+
-+#define DB_ES_PKTRX 0x0001
-+#define DB_ES_PKTRX2 0x0002
-+#define DB_ES_IPSA 0x0010
-+#define DB_ES_XF 0x0020
-+#define DB_ES_IPAD 0x0040
-+#define DB_ES_INAU 0x0080
-+#define DB_ES_OINFO 0x0100
-+#define DB_ES_OINFO2 0x0200
-+#define DB_ES_OH 0x0400
-+#define DB_ES_REPLAY 0x0800
-+
-+#ifdef __KERNEL__
-+struct des_eks {
-+ des_key_schedule ks;
-+};
-+
-+extern struct inet_protocol esp_protocol;
-+
-+struct options;
-+
-+struct esphdr
-+{
-+ __u32 esp_spi; /* Security Parameters Index */
-+ __u32 esp_rpl; /* Replay counter */
-+ __u8 esp_iv[8]; /* iv */
-+};
-+
-+extern struct xform_functions esp_xform_funcs[];
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int debug_esp;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#endif /* __KERNEL__ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.25 2004/04/06 02:49:08 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.24 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_esp.h,v
-+ *
-+ * Revision 1.23 2004/04/05 19:41:05 mcr
-+ * merged alg-branch code.
-+ *
-+ * Revision 1.22 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.23 2003/12/11 20:14:58 mcr
-+ * refactored the xmit code, to move all encapsulation
-+ * code into protocol functions. Note that all functions
-+ * are essentially done by a single function, which is probably
-+ * wrong.
-+ * the rcv_functions structures are renamed xform_functions.
-+ *
-+ * Revision 1.22 2003/12/06 21:21:19 mcr
-+ * split up receive path into per-transform files, for
-+ * easier later removal.
-+ *
-+ * Revision 1.21.8.1 2003/12/22 15:25:52 jjo
-+ * Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.21 2003/02/06 02:21:34 rgb
-+ *
-+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
-+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
-+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
-+ *
-+ * Revision 1.20 2002/05/14 02:37:02 rgb
-+ * Change reference from _TDB to _IPSA.
-+ *
-+ * Revision 1.19 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.18 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_esp.h,v
-+ *
-+ * Revision 1.17 2002/02/20 01:27:07 rgb
-+ * Ditched a pile of structs only used by the old Netlink interface.
-+ *
-+ * Revision 1.16 2001/12/11 02:35:57 rgb
-+ * Change "struct net_device" to "struct device" for 2.2 compatibility.
-+ *
-+ * Revision 1.15 2001/11/26 09:23:48 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.14.2.3 2001/10/23 04:16:42 mcr
-+ * get definition of des_key_schedule from des.h
-+ *
-+ * Revision 1.14.2.2 2001/10/22 20:33:13 mcr
-+ * use "des_key_schedule" structure instead of cooking our own.
-+ *
-+ * Revision 1.14.2.1 2001/09/25 02:18:25 mcr
-+ * replace "struct device" with "struct netdevice"
-+ *
-+ * Revision 1.14 2001/06/14 19:35:08 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.13 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.12 2000/08/01 14:51:50 rgb
-+ * Removed _all_ remaining traces of DES.
-+ *
-+ * Revision 1.11 2000/01/10 16:36:20 rgb
-+ * Ditch last of EME option flags, including initiator.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_ipcomp.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,91 @@
-+/*
-+ * IP compression header declations
-+ *
-+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifndef IPSEC_IPCOMP_H
-+#define IPSEC_IPCOMP_H
-+
-+#include "openswan/ipsec_auth.h"
-+
-+/* Prefix all global deflate symbols with "ipcomp_" to avoid collisions with ppp_deflate & ext2comp */
-+#ifndef IPCOMP_PREFIX
-+#define IPCOMP_PREFIX
-+#endif /* IPCOMP_PREFIX */
-+
-+#ifndef IPPROTO_COMP
-+#define IPPROTO_COMP 108
-+#endif /* IPPROTO_COMP */
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int sysctl_ipsec_debug_ipcomp;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+struct ipcomphdr { /* IPCOMP header */
-+ __u8 ipcomp_nh; /* Next header (protocol) */
-+ __u8 ipcomp_flags; /* Reserved, must be 0 */
-+ __u16 ipcomp_cpi; /* Compression Parameter Index */
-+};
-+
-+extern struct inet_protocol comp_protocol;
-+extern int sysctl_ipsec_debug_ipcomp;
-+
-+#define IPCOMP_UNCOMPRESSABLE 0x000000001
-+#define IPCOMP_COMPRESSIONERROR 0x000000002
-+#define IPCOMP_PARMERROR 0x000000004
-+#define IPCOMP_DECOMPRESSIONERROR 0x000000008
-+
-+#define IPCOMP_ADAPT_INITIAL_TRIES 8
-+#define IPCOMP_ADAPT_INITIAL_SKIP 4
-+#define IPCOMP_ADAPT_SUBSEQ_TRIES 2
-+#define IPCOMP_ADAPT_SUBSEQ_SKIP 8
-+
-+/* Function prototypes */
-+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
-+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags);
-+
-+extern struct xform_functions ipcomp_xform_funcs[];
-+
-+#endif /* IPSEC_IPCOMP_H */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.3 2004/04/06 02:49:08 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.2 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_ipcomp.h,v
-+ *
-+ * Revision 1.1 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.2 2003/12/11 20:14:58 mcr
-+ * refactored the xmit code, to move all encapsulation
-+ * code into protocol functions. Note that all functions
-+ * are essentially done by a single function, which is probably
-+ * wrong.
-+ * the rcv_functions structures are renamed xform_functions.
-+ *
-+ * Revision 1.1 2003/12/06 21:21:19 mcr
-+ * split up receive path into per-transform files, for
-+ * easier later removal.
-+ *
-+ *
-+ *
-+ */
-+
-+
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_ipe4.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,68 @@
-+/*
-+ * IP-in-IP Header declarations
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+/* The packet header is an IP header! */
-+
-+struct ipe4_xdata /* transform table data */
-+{
-+ struct in_addr i4_src;
-+ struct in_addr i4_dst;
-+};
-+
-+#define EMT_IPE4_ULEN 8 /* coming from user mode */
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.6 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_ipe4.h,v
-+ *
-+ * Revision 1.5 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_ipe4.h,v
-+ *
-+ * Revision 1.4 2001/06/14 19:35:08 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.3 1999/04/11 00:28:57 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.2 1999/04/06 04:54:25 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:47 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.1 1998/04/09 03:06:07 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * No changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:48:53 ji
-+ * Release update only.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_ipip.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,45 @@
-+/*
-+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifndef _IPSEC_IPIP_H_
-+
-+#ifndef IPPROTO_IPIP
-+#define IPPROTO_IPIP 4
-+#endif /* IPPROTO_ESP */
-+
-+extern struct xform_functions ipip_xform_funcs[];
-+
-+#define _IPSEC_IPIP_H_
-+
-+#endif /* _IPSEC_IPIP_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.2 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_ipip.h,v
-+ *
-+ * Revision 1.1 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.1 2003/12/11 20:14:58 mcr
-+ * refactored the xmit code, to move all encapsulation
-+ * code into protocol functions. Note that all functions
-+ * are essentially done by a single function, which is probably
-+ * wrong.
-+ * the rcv_functions structures are renamed xform_functions.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_kversion.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,239 @@
-+#ifndef _FREESWAN_KVERSIONS_H
-+/*
-+ * header file for FreeS/WAN library functions
-+ * Copyright (C) 1998, 1999, 2000 Henry Spencer.
-+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#define _FREESWAN_KVERSIONS_H /* seen it, no need to see it again */
-+
-+/*
-+ * this file contains a series of atomic defines that depend upon
-+ * kernel version numbers. The kernel versions are arranged
-+ * in version-order number (which is often not chronological)
-+ * and each clause enables or disables a feature.
-+ */
-+
-+/*
-+ * First, assorted kernel-version-dependent trickery.
-+ */
-+#include <linux/version.h>
-+#ifndef KERNEL_VERSION
-+#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
-+#define HEADER_CACHE_BIND_21
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
-+#define SPINLOCK
-+#define PROC_FS_21
-+#define NETLINK_SOCK
-+#define NET_21
-+#endif
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,19)
-+#define net_device_stats enet_statistics
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-+#define SPINLOCK_23
-+#define NETDEV_23
-+# ifndef CONFIG_IP_ALIAS
-+# define CONFIG_IP_ALIAS
-+# endif
-+#include <linux/socket.h>
-+#include <linux/skbuff.h>
-+#include <linux/netlink.h>
-+# ifdef NETLINK_XFRM
-+# define NETDEV_25
-+# endif
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,25)
-+#define PROC_FS_2325
-+#undef PROC_FS_21
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,30)
-+#define PROC_NO_DUMMY
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,35)
-+#define SKB_COPY_EXPAND
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,37)
-+#define IP_SELECT_IDENT
-+#endif
-+
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,50)) && defined(CONFIG_NETFILTER)
-+#define SKB_RESET_NFCT
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,2)
-+#define IP_SELECT_IDENT_NEW
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
-+#define IPH_is_SKB_PULLED
-+#define SKB_COW_NEW
-+#define PROTO_HANDLER_SINGLE_PARM
-+#define IP_FRAGMENT_LINEARIZE 1
-+#else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
-+# ifdef REDHAT_BOGOSITY
-+# define IP_SELECT_IDENT_NEW
-+# define IPH_is_SKB_PULLED
-+# define SKB_COW_NEW
-+# define PROTO_HANDLER_SINGLE_PARM
-+# endif /* REDHAT_BOGOSITY */
-+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4) */
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9)
-+#define MALLOC_SLAB
-+#define LINUX_KERNEL_HAS_SNPRINTF
-+#endif
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-+#define HAVE_NETDEV_PRINTK 1
-+#endif
-+
-+#ifdef NET_21
-+# include <linux/in6.h>
-+#else
-+ /* old kernel in.h has some IPv6 stuff, but not quite enough */
-+# define s6_addr16 s6_addr
-+# define AF_INET6 10
-+# define uint8_t __u8
-+# define uint16_t __u16
-+# define uint32_t __u32
-+# define uint64_t __u64
-+#endif
-+
-+#ifdef NET_21
-+# define ipsec_kfree_skb(a) kfree_skb(a)
-+#else /* NET_21 */
-+# define ipsec_kfree_skb(a) kfree_skb(a, FREE_WRITE)
-+#endif /* NET_21 */
-+
-+#ifdef NETDEV_23
-+# define device net_device
-+# define ipsec_dev_get dev_get_by_name
-+# define __ipsec_dev_get __dev_get_by_name
-+# define ipsec_dev_put(x) dev_put(x)
-+# define __ipsec_dev_put(x) __dev_put(x)
-+# define ipsec_dev_hold(x) dev_hold(x)
-+#else /* NETDEV_23 */
-+# define ipsec_dev_get dev_get
-+# define __ipsec_dev_put(x)
-+# define ipsec_dev_put(x)
-+# define ipsec_dev_hold(x)
-+#endif /* NETDEV_23 */
-+
-+#ifndef SPINLOCK
-+# include <linux/bios32.h>
-+ /* simulate spin locks and read/write locks */
-+ typedef struct {
-+ volatile char lock;
-+ } spinlock_t;
-+
-+ typedef struct {
-+ volatile unsigned int lock;
-+ } rwlock_t;
-+
-+# define spin_lock_init(x) { (x)->lock = 0;}
-+# define rw_lock_init(x) { (x)->lock = 0; }
-+
-+# define spin_lock(x) { while ((x)->lock) barrier(); (x)->lock=1;}
-+# define spin_lock_irq(x) { cli(); spin_lock(x);}
-+# define spin_lock_irqsave(x,flags) { save_flags(flags); spin_lock_irq(x);}
-+
-+# define spin_unlock(x) { (x)->lock=0;}
-+# define spin_unlock_irq(x) { spin_unlock(x); sti();}
-+# define spin_unlock_irqrestore(x,flags) { spin_unlock(x); restore_flags(flags);}
-+
-+# define read_lock(x) spin_lock(x)
-+# define read_lock_irq(x) spin_lock_irq(x)
-+# define read_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
-+
-+# define read_unlock(x) spin_unlock(x)
-+# define read_unlock_irq(x) spin_unlock_irq(x)
-+# define read_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
-+
-+# define write_lock(x) spin_lock(x)
-+# define write_lock_irq(x) spin_lock_irq(x)
-+# define write_lock_irqsave(x,flags) spin_lock_irqsave(x,flags)
-+
-+# define write_unlock(x) spin_unlock(x)
-+# define write_unlock_irq(x) spin_unlock_irq(x)
-+# define write_unlock_irqrestore(x,flags) spin_unlock_irqrestore(x,flags)
-+#endif /* !SPINLOCK */
-+
-+#ifndef SPINLOCK_23
-+# define spin_lock_bh(x) spin_lock_irq(x)
-+# define spin_unlock_bh(x) spin_unlock_irq(x)
-+
-+# define read_lock_bh(x) read_lock_irq(x)
-+# define read_unlock_bh(x) read_unlock_irq(x)
-+
-+# define write_lock_bh(x) write_lock_irq(x)
-+# define write_unlock_bh(x) write_unlock_irq(x)
-+#endif /* !SPINLOCK_23 */
-+
-+#ifndef HAVE_NETDEV_PRINTK
-+#define netdev_printk(sevlevel, netdev, msglevel, format, arg...) \
-+ printk(sevlevel "%s: " format , netdev->name , ## arg)
-+#endif
-+
-+#endif /* _FREESWAN_KVERSIONS_H */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.9 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_kversion.h,v
-+ *
-+ * Revision 1.8 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.7 2003/07/31 22:48:08 mcr
-+ * derive NET25-ness from presence of NETLINK_XFRM macro.
-+ *
-+ * Revision 1.6 2003/06/24 20:22:32 mcr
-+ * added new global: ipsecdevices[] so that we can keep track of
-+ * the ipsecX devices. They will be referenced with dev_hold(),
-+ * so 2.2 may need this as well.
-+ *
-+ * Revision 1.5 2003/04/03 17:38:09 rgb
-+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
-+ *
-+ * Revision 1.4 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_kversion.h,v
-+ *
-+ * Revision 1.3 2002/04/12 03:21:17 mcr
-+ * three parameter version of ip_select_ident appears first
-+ * in 2.4.2 (RH7.1) not 2.4.4.
-+ *
-+ * Revision 1.2 2002/03/08 21:35:22 rgb
-+ * Defined LINUX_KERNEL_HAS_SNPRINTF to shut up compiler warnings after
-+ * 2.4.9. (Andreas Piesk).
-+ *
-+ * Revision 1.1 2002/01/29 02:11:42 mcr
-+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
-+ * updating of IPv6 structures to match latest in6.h version.
-+ * removed dead code from freeswan.h that also duplicated kversions.h
-+ * code.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_life.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,112 @@
-+/*
-+ * Definitions relevant to IPSEC lifetimes
-+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ * and Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
-+ *
-+ */
-+
-+/*
-+ * This file describes the book keeping fields for the
-+ * IPsec Security Association Structure. ("ipsec_sa")
-+ *
-+ * This structure is never allocated directly by kernel code,
-+ * (it is always a static/auto or is part of a structure)
-+ * so it does not have a reference count.
-+ *
-+ */
-+
-+#ifndef _IPSEC_LIFE_H_
-+
-+/*
-+ * _count is total count.
-+ * _hard is hard limit (kill SA after this number)
-+ * _soft is soft limit (try to renew SA after this number)
-+ * _last is used in some special cases.
-+ *
-+ */
-+
-+struct ipsec_lifetime64
-+{
-+ __u64 ipl_count;
-+ __u64 ipl_soft;
-+ __u64 ipl_hard;
-+ __u64 ipl_last;
-+};
-+
-+struct ipsec_lifetimes
-+{
-+ /* number of bytes processed */
-+ struct ipsec_lifetime64 ipl_bytes;
-+
-+ /* number of packets processed */
-+ struct ipsec_lifetime64 ipl_packets;
-+
-+ /* time since SA was added */
-+ struct ipsec_lifetime64 ipl_addtime;
-+
-+ /* time since SA was first used */
-+ struct ipsec_lifetime64 ipl_usetime;
-+
-+ /* from rfc2367:
-+ * For CURRENT, the number of different connections,
-+ * endpoints, or flows that the association has been
-+ * allocated towards. For HARD and SOFT, the number of
-+ * these the association may be allocated towards
-+ * before it expires. The concept of a connection,
-+ * flow, or endpoint is system specific.
-+ *
-+ * mcr(2001-9-18) it is unclear what purpose these serve for FreeSWAN.
-+ * They are maintained for PF_KEY compatibility.
-+ */
-+ struct ipsec_lifetime64 ipl_allocations;
-+};
-+
-+enum ipsec_life_alive {
-+ ipsec_life_harddied = -1,
-+ ipsec_life_softdied = 0,
-+ ipsec_life_okay = 1
-+};
-+
-+enum ipsec_life_type {
-+ ipsec_life_timebased = 1,
-+ ipsec_life_countbased= 0
-+};
-+
-+#define _IPSEC_LIFE_H_
-+#endif /* _IPSEC_LIFE_H_ */
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.4 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_life.h,v
-+ *
-+ * Revision 1.3 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_life.h,v
-+ *
-+ * Revision 1.2 2001/11/26 09:16:14 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:25:58 mcr
-+ * lifetime structure created and common functions created.
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_md5h.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,140 @@
-+/*
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * The rest of this file is Copyright RSA DSI. See the following comments
-+ * for the full Copyright notice.
-+ */
-+
-+#ifndef _IPSEC_MD5H_H_
-+#define _IPSEC_MD5H_H_
-+
-+/* GLOBAL.H - RSAREF types and constants
-+ */
-+
-+/* PROTOTYPES should be set to one if and only if the compiler supports
-+ function argument prototyping.
-+ The following makes PROTOTYPES default to 0 if it has not already
-+ been defined with C compiler flags.
-+ */
-+#ifndef PROTOTYPES
-+#define PROTOTYPES 1
-+#endif /* !PROTOTYPES */
-+
-+/* POINTER defines a generic pointer type */
-+typedef __u8 *POINTER;
-+
-+/* UINT2 defines a two byte word */
-+typedef __u16 UINT2;
-+
-+/* UINT4 defines a four byte word */
-+typedef __u32 UINT4;
-+
-+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
-+ If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
-+ returns an empty list.
-+ */
-+
-+#if PROTOTYPES
-+#define PROTO_LIST(list) list
-+#else /* PROTOTYPES */
-+#define PROTO_LIST(list) ()
-+#endif /* PROTOTYPES */
-+
-+
-+/* MD5.H - header file for MD5C.C
-+ */
-+
-+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-+rights reserved.
-+
-+License to copy and use this software is granted provided that it
-+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-+Algorithm" in all material mentioning or referencing this software
-+or this function.
-+
-+License is also granted to make and use derivative works provided
-+that such works are identified as "derived from the RSA Data
-+Security, Inc. MD5 Message-Digest Algorithm" in all material
-+mentioning or referencing the derived work.
-+
-+RSA Data Security, Inc. makes no representations concerning either
-+the merchantability of this software or the suitability of this
-+software for any particular purpose. It is provided "as is"
-+without express or implied warranty of any kind.
-+
-+These notices must be retained in any copies of any part of this
-+documentation and/or software.
-+ */
-+
-+/* MD5 context. */
-+typedef struct {
-+ UINT4 state[4]; /* state (ABCD) */
-+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
-+ unsigned char buffer[64]; /* input buffer */
-+} MD5_CTX;
-+
-+void MD5Init PROTO_LIST ((void *));
-+void MD5Update PROTO_LIST
-+ ((void *, unsigned char *, __u32));
-+void MD5Final PROTO_LIST ((unsigned char [16], void *));
-+
-+#endif /* _IPSEC_MD5H_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.9 2004/04/05 19:55:05 mcr
-+ * Moved from linux/include/freeswan/ipsec_md5h.h,v
-+ *
-+ * Revision 1.8 2002/09/10 01:45:09 mcr
-+ * changed type of MD5_CTX and SHA1_CTX to void * so that
-+ * the function prototypes would match, and could be placed
-+ * into a pointer to a function.
-+ *
-+ * Revision 1.7 2002/04/24 07:36:46 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_md5h.h,v
-+ *
-+ * Revision 1.6 1999/12/13 13:59:13 rgb
-+ * Quick fix to argument size to Update bugs.
-+ *
-+ * Revision 1.5 1999/12/07 18:16:23 rgb
-+ * Fixed comments at end of #endif lines.
-+ *
-+ * Revision 1.4 1999/04/06 04:54:26 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.3 1999/01/22 06:19:58 rgb
-+ * 64-bit clean-up.
-+ *
-+ * Revision 1.2 1998/11/30 13:22:54 rgb
-+ * Rationalised all the klips kernel file headers. They are much shorter
-+ * now and won't conflict under RH5.2.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:48 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.2 1998/04/23 20:54:03 rgb
-+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
-+ * verified.
-+ *
-+ * Revision 1.1 1998/04/09 03:04:21 henry
-+ * sources moved up from linux/net/ipsec
-+ * these two include files modified not to include others except in kernel
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * No changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:48:53 ji
-+ * Release update only.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_param.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,333 @@
-+/*
-+ * @(#) FreeSWAN tunable paramaters
-+ *
-+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ * and Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ */
-+
-+/*
-+ * This file provides a set of #define's which may be tuned by various
-+ * people/configurations. It keeps all compile-time tunables in one place.
-+ *
-+ * This file should be included before all other IPsec kernel-only files.
-+ *
-+ */
-+
-+#ifndef _IPSEC_PARAM_H_
-+
-+#ifdef __KERNEL__
-+#include "ipsec_kversion.h"
-+
-+/* Set number of ipsecX virtual devices here. */
-+/* This must be < exp(field width of IPSEC_DEV_FORMAT) */
-+/* It must also be reasonable so as not to overload the memory and CPU */
-+/* constraints of the host. */
-+#define IPSEC_NUM_IF 4
-+/* The field width must be < IF_NAM_SIZ - strlen("ipsec") - 1. */
-+/* With "ipsec" being 5 characters, that means 10 is the max field width */
-+/* but machine memory and CPU constraints are not likely to tollerate */
-+/* more than 3 digits. The default is one digit. */
-+/* Update: userland scripts get upset if they can't find "ipsec0", so */
-+/* for now, no "0"-padding should be used (which would have been helpful */
-+/* to make text-searches work */
-+#define IPSEC_DEV_FORMAT "ipsec%d"
-+/* For, say, 500 virtual ipsec devices, I would recommend: */
-+/* #define IPSEC_NUM_IF 500 */
-+/* #define IPSEC_DEV_FORMAT "ipsec%03d" */
-+/* Note that the "interfaces=" line in /etc/ipsec.conf would be, um, challenging. */
-+
-+/* use dynamic ipsecX device allocation */
-+#ifndef CONFIG_IPSEC_DYNDEV
-+#define CONFIG_IPSEC_DYNDEV 1
-+#endif /* CONFIG_IPSEC_DYNDEV */
-+
-+
-+#ifdef CONFIG_IPSEC_BIGGATE
-+# define SADB_HASHMOD 8069
-+#else /* CONFIG_IPSEC_BIGGATE */
-+# define SADB_HASHMOD 257
-+#endif /* CONFIG_IPSEC_BIGGATE */
-+#endif /* __KERNEL__ */
-+
-+/*
-+ * This is for the SA reference table. This number is related to the
-+ * maximum number of SAs that KLIPS can concurrently deal with, plus enough
-+ * space for keeping expired SAs around.
-+ *
-+ * TABLE_MAX_WIDTH is the number of bits that we will use.
-+ * MAIN_TABLE_WIDTH is the number of bits used for the primary index table.
-+ *
-+ */
-+#ifndef IPSEC_SA_REF_TABLE_IDX_WIDTH
-+# define IPSEC_SA_REF_TABLE_IDX_WIDTH 16
-+#endif
-+
-+#ifndef IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
-+# define IPSEC_SA_REF_MAINTABLE_IDX_WIDTH 4
-+#endif
-+
-+#ifndef IPSEC_SA_REF_FREELIST_NUM_ENTRIES
-+# define IPSEC_SA_REF_FREELIST_NUM_ENTRIES 256
-+#endif
-+
-+#ifndef IPSEC_SA_REF_CODE
-+# define IPSEC_SA_REF_CODE 1
-+#endif
-+
-+#ifdef __KERNEL__
-+/* This is defined for 2.4, but not 2.2.... */
-+#ifndef ARPHRD_VOID
-+# define ARPHRD_VOID 0xFFFF
-+#endif
-+
-+/*
-+ * Worry about PROC_FS stuff
-+ */
-+#if defined(PROC_FS_2325)
-+/* kernel 2.4 */
-+# define IPSEC_PROC_LAST_ARG ,int *eof,void *data
-+# define IPSEC_PROCFS_DEBUG_NO_STATIC
-+# define IPSEC_PROC_SUBDIRS
-+#else
-+/* kernel <2.4 */
-+# define IPSEC_PROCFS_DEBUG_NO_STATIC DEBUG_NO_STATIC
-+
-+# ifndef PROC_NO_DUMMY
-+# define IPSEC_PROC_LAST_ARG , int dummy
-+# else
-+# define IPSEC_PROC_LAST_ARG
-+# endif /* !PROC_NO_DUMMY */
-+#endif /* PROC_FS_2325 */
-+
-+#if !defined(LINUX_KERNEL_HAS_SNPRINTF)
-+/* GNU CPP specific! */
-+# define snprintf(buf, len, fmt...) sprintf(buf, ##fmt)
-+#endif /* !LINUX_KERNEL_HAS_SNPRINTF */
-+
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+
-+#ifndef KLIPS_FIXES_DES_PARITY
-+# define KLIPS_FIXES_DES_PARITY 1
-+#endif /* !KLIPS_FIXES_DES_PARITY */
-+
-+/* we don't really want to print these unless there are really big problems */
-+#ifndef KLIPS_DIVULGE_CYPHER_KEY
-+# define KLIPS_DIVULGE_CYPHER_KEY 0
-+#endif /* !KLIPS_DIVULGE_CYPHER_KEY */
-+
-+#ifndef KLIPS_DIVULGE_HMAC_KEY
-+# define KLIPS_DIVULGE_HMAC_KEY 0
-+#endif /* !KLIPS_DIVULGE_HMAC_KEY */
-+
-+#ifndef IPSEC_DISALLOW_IPOPTIONS
-+# define IPSEC_DISALLOW_IPOPTIONS 1
-+#endif /* !KLIPS_DIVULGE_HMAC_KEY */
-+
-+/* extra toggles for regression testing */
-+#ifdef CONFIG_IPSEC_REGRESS
-+
-+/*
-+ * should pfkey_acquire() become 100% lossy?
-+ *
-+ */
-+extern int sysctl_ipsec_regress_pfkey_lossage;
-+#ifndef KLIPS_PFKEY_ACQUIRE_LOSSAGE
-+# ifdef CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE
-+# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 100
-+# else /* CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE */
-+/* not by default! */
-+# define KLIPS_PFKEY_ACQUIRE_LOSSAGE 0
-+# endif /* CONFIG_IPSEC_PFKEY_ACQUIRE_LOSSAGE */
-+#endif /* KLIPS_PFKEY_ACQUIRE_LOSSAGE */
-+
-+#endif /* CONFIG_IPSEC_REGRESS */
-+
-+
-+/*
-+ * debugging routines.
-+ */
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern void ipsec_print_ip(struct iphdr *ip);
-+
-+ #define KLIPS_PRINT(flag, format, args...) \
-+ ((flag) ? printk(KERN_INFO format , ## args) : 0)
-+ #define KLIPS_PRINTMORE(flag, format, args...) \
-+ ((flag) ? printk(format , ## args) : 0)
-+ #define KLIPS_IP_PRINT(flag, ip) \
-+ ((flag) ? ipsec_print_ip(ip) : 0)
-+#else /* CONFIG_IPSEC_DEBUG */
-+ #define KLIPS_PRINT(flag, format, args...) do ; while(0)
-+ #define KLIPS_PRINTMORE(flag, format, args...) do ; while(0)
-+ #define KLIPS_IP_PRINT(flag, ip) do ; while(0)
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+
-+/*
-+ * Stupid kernel API differences in APIs. Not only do some
-+ * kernels not have ip_select_ident, but some have differing APIs,
-+ * and SuSE has one with one parameter, but no way of checking to
-+ * see what is really what.
-+ */
-+
-+#ifdef SUSE_LINUX_2_4_19_IS_STUPID
-+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
-+#else
-+
-+/* simplest case, nothing */
-+#if !defined(IP_SELECT_IDENT)
-+#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
-+#endif
-+
-+/* kernels > 2.3.37-ish */
-+#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
-+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
-+#endif
-+
-+/* kernels > 2.4.2 */
-+#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
-+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
-+#endif
-+
-+#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
-+
-+/*
-+ * make klips fail test:east-espiv-01.
-+ * exploit is at testing/attacks/espiv
-+ *
-+ */
-+#define KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK 0
-+
-+
-+/* IP_FRAGMENT_LINEARIZE is set in freeswan.h if Kernel > 2.4.4 */
-+#ifndef IP_FRAGMENT_LINEARIZE
-+# define IP_FRAGMENT_LINEARIZE 0
-+#endif /* IP_FRAGMENT_LINEARIZE */
-+#endif /* __KERNEL__ */
-+
-+#define _IPSEC_PARAM_H_
-+#endif /* _IPSEC_PARAM_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.24 2004/04/05 19:55:06 mcr
-+ * Moved from linux/include/freeswan/ipsec_param.h,v
-+ *
-+ * Revision 1.23 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.22 2003/10/31 02:27:05 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.21.4.1 2003/10/29 01:10:19 mcr
-+ * elimited "struct sa_id"
-+ *
-+ * Revision 1.21 2003/04/03 17:38:18 rgb
-+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
-+ * Change indentation for readability.
-+ *
-+ * Revision 1.20 2003/03/14 08:09:26 rgb
-+ * Fixed up CONFIG_IPSEC_DYNDEV definitions.
-+ *
-+ * Revision 1.19 2003/01/30 02:31:43 rgb
-+ *
-+ * Rename SAref table macro names for clarity.
-+ *
-+ * Revision 1.18 2002/09/30 19:06:26 rgb
-+ * Reduce default table to 16 bits width.
-+ *
-+ * Revision 1.17 2002/09/20 15:40:29 rgb
-+ * Define switch to activate new SAref code.
-+ * Prefix macros with "IPSEC_".
-+ * Rework saref freelist.
-+ * Restrict some bits to kernel context for use to klips utils.
-+ *
-+ * Revision 1.16 2002/09/20 05:00:31 rgb
-+ * Define switch to divulge hmac keys for debugging.
-+ * Added IPOPTIONS switch.
-+ *
-+ * Revision 1.15 2002/09/19 02:34:24 mcr
-+ * define IPSEC_PROC_SUBDIRS if we are 2.4, and use that in ipsec_proc.c
-+ * to decide if we are to create /proc/net/ipsec/.
-+ *
-+ * Revision 1.14 2002/08/30 01:20:54 mcr
-+ * reorganized 2.0/2.2/2.4 procfs support macro so match
-+ * 2.4 values/typedefs.
-+ *
-+ * Revision 1.13 2002/07/28 22:03:28 mcr
-+ * added some documentation to SA_REF_*
-+ * turned on fix for ESPIV attack, now that we have the attack code.
-+ *
-+ * Revision 1.12 2002/07/26 08:48:31 rgb
-+ * Added SA ref table code.
-+ *
-+ * Revision 1.11 2002/07/23 02:57:45 rgb
-+ * Define ARPHRD_VOID for < 2.4 kernels.
-+ *
-+ * Revision 1.10 2002/05/27 21:37:28 rgb
-+ * Set the defaults sanely for those adventurous enough to try more than 1
-+ * digit of ipsec devices.
-+ *
-+ * Revision 1.9 2002/05/27 18:56:07 rgb
-+ * Convert to dynamic ipsec device allocation.
-+ *
-+ * Revision 1.8 2002/04/24 07:36:47 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_param.h,v
-+ *
-+ * Revision 1.7 2002/04/20 00:12:25 rgb
-+ * Added esp IV CBC attack fix, disabled.
-+ *
-+ * Revision 1.6 2002/01/29 02:11:42 mcr
-+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
-+ * updating of IPv6 structures to match latest in6.h version.
-+ * removed dead code from freeswan.h that also duplicated kversions.h
-+ * code.
-+ *
-+ * Revision 1.5 2002/01/28 19:22:01 mcr
-+ * by default, turn off LINEARIZE option
-+ * (let kversions.h turn it on)
-+ *
-+ * Revision 1.4 2002/01/20 20:19:36 mcr
-+ * renamed option to IP_FRAGMENT_LINEARIZE.
-+ *
-+ * Revision 1.3 2002/01/12 02:57:25 mcr
-+ * first regression test causes acquire messages to be lost
-+ * 100% of the time. This is to help testing of pluto.
-+ *
-+ * Revision 1.2 2001/11/26 09:16:14 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.3 2001/10/23 04:40:16 mcr
-+ * added #define for DIVULGING session keys in debug output.
-+ *
-+ * Revision 1.1.2.2 2001/10/22 20:53:25 mcr
-+ * added a define to control forcing of DES parity.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:20:19 mcr
-+ * many common kernel configuration questions centralized.
-+ * more things remain that should be moved from freeswan.h.
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_policy.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,216 @@
-+#ifndef _IPSEC_POLICY_H
-+/*
-+ * policy interface file between pluto and applications
-+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#define _IPSEC_POLICY_H /* seen it, no need to see it again */
-+
-+
-+/*
-+ * this file defines an interface between an application (or rather an
-+ * application library) and a key/policy daemon. It provides for inquiries
-+ * as to the current state of a connected socket, as well as for general
-+ * questions.
-+ *
-+ * In general, the interface is defined as a series of functional interfaces,
-+ * and the policy messages should be internal. However, because this is in
-+ * fact an ABI between pieces of the system that may get compiled and revised
-+ * seperately, this ABI must be public and revision controlled.
-+ *
-+ * It is expected that the daemon will always support previous versions.
-+ */
-+
-+#define IPSEC_POLICY_MSG_REVISION (unsigned)200305061
-+
-+enum ipsec_policy_command {
-+ IPSEC_CMD_QUERY_FD = 1,
-+ IPSEC_CMD_QUERY_HOSTPAIR = 2,
-+ IPSEC_CMD_QUERY_DSTONLY = 3,
-+};
-+
-+struct ipsec_policy_msg_head {
-+ u_int32_t ipm_version;
-+ u_int32_t ipm_msg_len;
-+ u_int32_t ipm_msg_type;
-+ u_int32_t ipm_msg_seq;
-+};
-+
-+enum ipsec_privacy_quality {
-+ IPSEC_PRIVACY_NONE = 0,
-+ IPSEC_PRIVACY_INTEGRAL = 4, /* not private at all. AH-like */
-+ IPSEC_PRIVACY_UNKNOWN = 8, /* something is claimed, but details unavail */
-+ IPSEC_PRIVACY_ROT13 = 12, /* trivially breakable, i.e. 1DES */
-+ IPSEC_PRIVACY_GAK = 16, /* known eavesdroppers */
-+ IPSEC_PRIVACY_PRIVATE = 32, /* secure for at least a decade */
-+ IPSEC_PRIVACY_STRONG = 64, /* ridiculously secure */
-+ IPSEC_PRIVACY_TORTOISE = 192, /* even stronger, but very slow */
-+ IPSEC_PRIVACY_OTP = 224, /* some kind of *true* one time pad */
-+};
-+
-+enum ipsec_bandwidth_quality {
-+ IPSEC_QOS_UNKNOWN = 0, /* unknown bandwidth */
-+ IPSEC_QOS_INTERACTIVE = 16, /* reasonably moderate jitter, moderate fast.
-+ Good enough for telnet/ssh. */
-+ IPSEC_QOS_VOIP = 32, /* faster crypto, predicable jitter */
-+ IPSEC_QOS_FTP = 64, /* higher throughput crypto, perhaps hardware
-+ offloaded, but latency/jitter may be bad */
-+ IPSEC_QOS_WIRESPEED = 128, /* expect to be able to fill your pipe */
-+};
-+
-+/* moved from programs/pluto/constants.h */
-+/* IPsec AH transform values
-+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.3
-+ * and in http://www.iana.org/assignments/isakmp-registry
-+ */
-+enum ipsec_authentication_algo {
-+ AH_MD5=2,
-+ AH_SHA=3,
-+ AH_DES=4,
-+ AH_SHA2_256=5,
-+ AH_SHA2_384=6,
-+ AH_SHA2_512=7
-+};
-+
-+/* IPsec ESP transform values
-+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.4
-+ * and from http://www.iana.org/assignments/isakmp-registry
-+ */
-+
-+enum ipsec_cipher_algo {
-+ ESP_reserved=0,
-+ ESP_DES_IV64=1,
-+ ESP_DES=2,
-+ ESP_3DES=3,
-+ ESP_RC5=4,
-+ ESP_IDEA=5,
-+ ESP_CAST=6,
-+ ESP_BLOWFISH=7,
-+ ESP_3IDEA=8,
-+ ESP_DES_IV32=9,
-+ ESP_RC4=10,
-+ ESP_NULL=11,
-+ ESP_AES=12,
-+};
-+
-+/* IPCOMP transform values
-+ * RFC2407 The Internet IP security Domain of Interpretation for ISAKMP 4.4.5
-+ */
-+
-+enum ipsec_comp_algo {
-+ IPCOMP_OUI= 1,
-+ IPCOMP_DEFLATE= 2,
-+ IPCOMP_LZS= 3,
-+ IPCOMP_V42BIS= 4
-+};
-+
-+/* Identification type values
-+ * RFC 2407 The Internet IP security Domain of Interpretation for ISAKMP 4.6.2.1
-+ */
-+
-+enum ipsec_id_type {
-+ ID_IMPOSSIBLE= (-2), /* private to Pluto */
-+ ID_MYID= (-1), /* private to Pluto */
-+ ID_NONE= 0, /* private to Pluto */
-+ ID_IPV4_ADDR= 1,
-+ ID_FQDN= 2,
-+ ID_USER_FQDN= 3,
-+ ID_IPV4_ADDR_SUBNET= 4,
-+ ID_IPV6_ADDR= 5,
-+ ID_IPV6_ADDR_SUBNET= 6,
-+ ID_IPV4_ADDR_RANGE= 7,
-+ ID_IPV6_ADDR_RANGE= 8,
-+ ID_DER_ASN1_DN= 9,
-+ ID_DER_ASN1_GN= 10,
-+ ID_KEY_ID= 11
-+};
-+
-+/* Certificate type values
-+ * RFC 2408 ISAKMP, chapter 3.9
-+ */
-+enum ipsec_cert_type {
-+ CERT_NONE= 0, /* none, or guess from file contents */
-+ CERT_PKCS7_WRAPPED_X509= 1, /* self-signed certificate from disk */
-+ CERT_PGP= 2,
-+ CERT_DNS_SIGNED_KEY= 3, /* KEY RR from DNS */
-+ CERT_X509_SIGNATURE= 4,
-+ CERT_X509_KEY_EXCHANGE= 5,
-+ CERT_KERBEROS_TOKENS= 6,
-+ CERT_CRL= 7,
-+ CERT_ARL= 8,
-+ CERT_SPKI= 9,
-+ CERT_X509_ATTRIBUTE= 10,
-+ CERT_RAW_RSA= 11, /* raw RSA from config file */
-+};
-+
-+/* a SIG record in ASCII */
-+struct ipsec_dns_sig {
-+ char fqdn[256];
-+ char dns_sig[768]; /* empty string if not signed */
-+};
-+
-+struct ipsec_raw_key {
-+ char id_name[256];
-+ char fs_keyid[8];
-+};
-+
-+struct ipsec_identity {
-+ enum ipsec_id_type ii_type;
-+ enum ipsec_cert_type ii_format;
-+ union {
-+ struct ipsec_dns_sig ipsec_dns_signed;
-+ /* some thing for PGP */
-+ /* some thing for PKIX */
-+ struct ipsec_raw_key ipsec_raw_key;
-+ } ii_credential;
-+};
-+
-+#define IPSEC_MAX_CREDENTIALS 32
-+
-+struct ipsec_policy_cmd_query {
-+ struct ipsec_policy_msg_head head;
-+
-+ /* Query section */
-+ ip_address query_local; /* us */
-+ ip_address query_remote; /* them */
-+ u_short src_port, dst_port;
-+
-+ /* Answer section */
-+ enum ipsec_privacy_quality strength;
-+ enum ipsec_bandwidth_quality bandwidth;
-+ enum ipsec_authentication_algo auth_detail;
-+ enum ipsec_cipher_algo esp_detail;
-+ enum ipsec_comp_algo comp_detail;
-+
-+ int credential_count;
-+
-+ struct ipsec_identity credentials[IPSEC_MAX_CREDENTIALS];
-+};
-+
-+#define IPSEC_POLICY_SOCKET "/var/run/pluto.info"
-+
-+/* prototypes */
-+extern err_t ipsec_policy_lookup(int fd, struct ipsec_policy_cmd_query *result);
-+extern err_t ipsec_policy_init(void);
-+extern err_t ipsec_policy_final(void);
-+extern err_t ipsec_policy_readmsg(int policysock,
-+ unsigned char *buf, size_t buflen);
-+extern err_t ipsec_policy_sendrecv(unsigned char *buf, size_t buflen);
-+extern err_t ipsec_policy_cgilookup(struct ipsec_policy_cmd_query *result);
-+
-+
-+extern const char *ipsec_policy_version_code(void);
-+extern const char *ipsec_policy_version_string(void);
-+
-+#endif /* _IPSEC_POLICY_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_proto.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,151 @@
-+/*
-+ * @(#) prototypes for FreeSWAN functions
-+ *
-+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ * and Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ */
-+
-+#ifndef _IPSEC_PROTO_H_
-+
-+#include "ipsec_param.h"
-+
-+/*
-+ * This file is a kernel only file that declares prototypes for
-+ * all intra-module function calls and global data structures.
-+ *
-+ * Include this file last.
-+ *
-+ */
-+
-+/* ipsec_init.c */
-+extern struct prng ipsec_prng;
-+
-+/* ipsec_sa.c */
-+extern struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
-+extern spinlock_t tdb_lock;
-+extern int ipsec_sadb_init(void);
-+
-+extern struct ipsec_sa *ipsec_sa_getbyid(ip_said *);
-+extern int ipsec_sa_put(struct ipsec_sa *);
-+extern /* void */ int ipsec_sa_del(struct ipsec_sa *);
-+extern /* void */ int ipsec_sa_delchain(struct ipsec_sa *);
-+extern /* void */ int ipsec_sa_add(struct ipsec_sa *);
-+
-+extern int ipsec_sadb_cleanup(__u8);
-+extern int ipsec_sa_wipe(struct ipsec_sa *);
-+
-+/* debug declarations */
-+
-+/* ipsec_proc.c */
-+extern int ipsec_proc_init(void);
-+extern void ipsec_proc_cleanup(void);
-+
-+/* ipsec_radij.c */
-+extern int ipsec_makeroute(struct sockaddr_encap *ea,
-+ struct sockaddr_encap *em,
-+ ip_said said,
-+ uint32_t pid,
-+ struct sk_buff *skb,
-+ struct ident *ident_s,
-+ struct ident *ident_d);
-+
-+extern int ipsec_breakroute(struct sockaddr_encap *ea,
-+ struct sockaddr_encap *em,
-+ struct sk_buff **first,
-+ struct sk_buff **last);
-+
-+int ipsec_radijinit(void);
-+int ipsec_cleareroutes(void);
-+int ipsec_radijcleanup(void);
-+
-+/* ipsec_life.c */
-+extern enum ipsec_life_alive ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
-+ const char *lifename,
-+ const char *saname,
-+ enum ipsec_life_type ilt,
-+ enum ipsec_direction idir,
-+ struct ipsec_sa *ips);
-+
-+
-+extern int ipsec_lifetime_format(char *buffer,
-+ int buflen,
-+ char *lifename,
-+ enum ipsec_life_type timebaselife,
-+ struct ipsec_lifetime64 *lifetime);
-+
-+extern void ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
-+ __u64 newvalue);
-+
-+extern void ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
-+ __u64 newvalue);
-+
-+
-+
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+
-+extern int debug_xform;
-+extern int debug_eroute;
-+extern int debug_spi;
-+extern int debug_netlink;
-+
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+
-+
-+
-+#define _IPSEC_PROTO_H
-+#endif /* _IPSEC_PROTO_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.8 2004/04/05 19:55:06 mcr
-+ * Moved from linux/include/freeswan/ipsec_proto.h,v
-+ *
-+ * Revision 1.7 2003/10/31 02:27:05 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.6.30.1 2003/10/29 01:10:19 mcr
-+ * elimited "struct sa_id"
-+ *
-+ * Revision 1.6 2002/05/23 07:13:48 rgb
-+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
-+ *
-+ * Revision 1.5 2002/05/14 02:36:40 rgb
-+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
-+ * with "put" usage in the kernel.
-+ *
-+ * Revision 1.4 2002/04/24 07:36:47 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_proto.h,v
-+ *
-+ * Revision 1.3 2002/04/20 00:12:25 rgb
-+ * Added esp IV CBC attack fix, disabled.
-+ *
-+ * Revision 1.2 2001/11/26 09:16:15 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:21:01 mcr
-+ * ipsec_proto.h created to keep prototypes rather than deal with
-+ * cyclic dependancies of structures and prototypes in .h files.
-+ *
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_radij.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,176 @@
-+/*
-+ * @(#) Definitions relevant to the IPSEC <> radij tree interfacing
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifndef _IPSEC_RADIJ_H
-+
-+#include <openswan.h>
-+
-+int ipsec_walk(char *);
-+
-+int ipsec_rj_walker_procprint(struct radij_node *, void *);
-+int ipsec_rj_walker_delete(struct radij_node *, void *);
-+
-+/* This structure is used to pass information between
-+ * ipsec_eroute_get_info and ipsec_rj_walker_procprint
-+ * (through rj_walktree) and between calls of ipsec_rj_walker_procprint.
-+ */
-+struct wsbuf
-+{
-+ /* from caller of ipsec_eroute_get_info: */
-+ char *const buffer; /* start of buffer provided */
-+ const int length; /* length of buffer provided */
-+ const off_t offset; /* file position of first character of interest */
-+ /* accumulated by ipsec_rj_walker_procprint: */
-+ int len; /* number of character filled into buffer */
-+ off_t begin; /* file position contained in buffer[0] (<=offset) */
-+};
-+
-+extern struct radij_node_head *rnh;
-+extern spinlock_t eroute_lock;
-+
-+struct eroute * ipsec_findroute(struct sockaddr_encap *);
-+
-+#define O1(x) (int)(((x)>>24)&0xff)
-+#define O2(x) (int)(((x)>>16)&0xff)
-+#define O3(x) (int)(((x)>>8)&0xff)
-+#define O4(x) (int)(((x))&0xff)
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int debug_radij;
-+void rj_dumptrees(void);
-+
-+#define DB_RJ_DUMPTREES 0x0001
-+#define DB_RJ_FINDROUTE 0x0002
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#define _IPSEC_RADIJ_H
-+#endif
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.21 2004/04/29 11:06:42 ken
-+ * Last bits from 2.06 procfs updates
-+ *
-+ * Revision 1.20 2004/04/06 02:49:08 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.19 2004/04/05 19:55:06 mcr
-+ * Moved from linux/include/freeswan/ipsec_radij.h,v
-+ *
-+ * Revision 1.18 2002/04/24 07:36:47 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_radij.h,v
-+ *
-+ * Revision 1.17 2001/11/26 09:23:49 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.16.2.1 2001/09/25 02:21:17 mcr
-+ * ipsec_proto.h created to keep prototypes rather than deal with
-+ * cyclic dependancies of structures and prototypes in .h files.
-+ *
-+ * Revision 1.16 2001/09/15 16:24:04 rgb
-+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
-+ *
-+ * Revision 1.15 2001/09/14 16:58:37 rgb
-+ * Added support for storing the first and last packets through a HOLD.
-+ *
-+ * Revision 1.14 2001/09/08 21:13:32 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.13 2001/06/14 19:35:09 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.12 2001/05/27 06:12:11 rgb
-+ * Added structures for pid, packet count and last access time to eroute.
-+ * Added packet count to beginning of /proc/net/ipsec_eroute.
-+ *
-+ * Revision 1.11 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.10 1999/11/17 15:53:39 rgb
-+ * Changed all occurrences of #include "../../../lib/freeswan.h"
-+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
-+ * klips/net/ipsec/Makefile.
-+ *
-+ * Revision 1.9 1999/10/01 00:01:23 rgb
-+ * Added eroute structure locking.
-+ *
-+ * Revision 1.8 1999/04/11 00:28:59 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.7 1999/04/06 04:54:26 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.6 1999/01/22 06:23:26 rgb
-+ * Cruft clean-out.
-+ *
-+ * Revision 1.5 1998/10/25 02:42:08 rgb
-+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an
-+ * argument to be able to transmit more infomation about errors.
-+ *
-+ * Revision 1.4 1998/10/19 14:44:29 rgb
-+ * Added inclusion of freeswan.h.
-+ * sa_id structure implemented and used: now includes protocol.
-+ *
-+ * Revision 1.3 1998/07/28 00:03:31 rgb
-+ * Comment out temporary inet_nto4u() kluge.
-+ *
-+ * Revision 1.2 1998/07/14 18:22:00 rgb
-+ * Add function to clear the eroute table.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:49 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.5 1998/05/25 20:30:38 rgb
-+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
-+ *
-+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
-+ * add ipsec_rj_walker_delete.
-+ *
-+ * Revision 1.4 1998/05/21 13:02:56 rgb
-+ * Imported definitions from ipsec_radij.c and radij.c to support /proc 3k
-+ * limit fix.
-+ *
-+ * Revision 1.3 1998/04/21 21:29:09 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.2 1998/04/14 17:30:39 rgb
-+ * Fix up compiling errors for radij tree memory reclamation.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:10 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * No changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:39:04 ji
-+ * Minor cleanups.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_rcv.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,279 @@
-+/*
-+ *
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifndef IPSEC_RCV_H
-+#define IPSEC_RCV_H
-+
-+#include "openswan/ipsec_auth.h"
-+
-+#define DB_RX_PKTRX 0x0001
-+#define DB_RX_PKTRX2 0x0002
-+#define DB_RX_DMP 0x0004
-+#define DB_RX_IPSA 0x0010
-+#define DB_RX_XF 0x0020
-+#define DB_RX_IPAD 0x0040
-+#define DB_RX_INAU 0x0080
-+#define DB_RX_OINFO 0x0100
-+#define DB_RX_OINFO2 0x0200
-+#define DB_RX_OH 0x0400
-+#define DB_RX_REPLAY 0x0800
-+
-+#ifdef __KERNEL__
-+/* struct options; */
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/config.h> /* for CONFIG_IP_FORWARD */
-+#include <linux/version.h>
-+#include <openswan.h>
-+
-+#define IPSEC_BIRTH_TEMPLATE_MAXLEN 256
-+
-+struct ipsec_birth_reply {
-+ int packet_template_len;
-+ unsigned char packet_template[IPSEC_BIRTH_TEMPLATE_MAXLEN];
-+};
-+
-+extern struct ipsec_birth_reply ipsec_ipv4_birth_packet;
-+extern struct ipsec_birth_reply ipsec_ipv6_birth_packet;
-+
-+enum ipsec_rcv_value {
-+ IPSEC_RCV_LASTPROTO=1,
-+ IPSEC_RCV_OK=0,
-+ IPSEC_RCV_BADPROTO=-1,
-+ IPSEC_RCV_BADLEN=-2,
-+ IPSEC_RCV_ESP_BADALG=-3,
-+ IPSEC_RCV_3DES_BADBLOCKING=-4,
-+ IPSEC_RCV_ESP_DECAPFAIL=-5,
-+ IPSEC_RCV_DECAPFAIL=-6,
-+ IPSEC_RCV_SAIDNOTFOUND=-7,
-+ IPSEC_RCV_IPCOMPALONE=-8,
-+ IPSEC_RCV_IPCOMPFAILED=-10,
-+ IPSEC_RCV_SAIDNOTLIVE=-11,
-+ IPSEC_RCV_FAILEDINBOUND=-12,
-+ IPSEC_RCV_LIFETIMEFAILED=-13,
-+ IPSEC_RCV_BADAUTH=-14,
-+ IPSEC_RCV_REPLAYFAILED=-15,
-+ IPSEC_RCV_AUTHFAILED=-16,
-+ IPSEC_RCV_REPLAYROLLED=-17,
-+ IPSEC_RCV_BAD_DECRYPT=-18
-+};
-+
-+struct ipsec_rcv_state {
-+ struct sk_buff *skb;
-+ struct net_device_stats *stats;
-+ struct iphdr *ipp;
-+ struct ipsec_sa *ipsp;
-+ int len;
-+ int ilen;
-+ int authlen;
-+ int hard_header_len;
-+ int iphlen;
-+ struct auth_alg *authfuncs;
-+ ip_said said;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+ __u8 next_header;
-+ __u8 hash[AH_AMAX];
-+ char ipsaddr_txt[ADDRTOA_BUF];
-+ char ipdaddr_txt[ADDRTOA_BUF];
-+ __u8 *octx;
-+ __u8 *ictx;
-+ int ictx_len;
-+ int octx_len;
-+ union {
-+ struct {
-+ struct esphdr *espp;
-+ } espstuff;
-+ struct {
-+ struct ahhdr *ahp;
-+ } ahstuff;
-+ struct {
-+ struct ipcomphdr *compp;
-+ } ipcompstuff;
-+ } protostuff;
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ __u8 natt_type;
-+ __u16 natt_sport;
-+ __u16 natt_dport;
-+ int natt_len;
-+#endif
-+};
-+
-+extern int
-+#ifdef PROTO_HANDLER_SINGLE_PARM
-+ipsec_rcv(struct sk_buff *skb);
-+#else /* PROTO_HANDLER_SINGLE_PARM */
-+ipsec_rcv(struct sk_buff *skb,
-+#ifdef NET_21
-+ unsigned short xlen);
-+#else /* NET_21 */
-+ struct device *dev,
-+ struct options *opt,
-+ __u32 daddr,
-+ unsigned short len,
-+ __u32 saddr,
-+ int redo,
-+ struct inet_protocol *protocol);
-+#endif /* NET_21 */
-+#endif /* PROTO_HANDLER_SINGLE_PARM */
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int debug_rcv;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#define ipsec_rcv_dmp(_x,_y, _z) if (debug_rcv && sysctl_ipsec_debug_verbose) ipsec_dmp(_x,_y,_z)
-+
-+extern int sysctl_ipsec_inbound_policy_check;
-+#endif /* __KERNEL__ */
-+
-+#endif /* IPSEC_RCV_H */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.21 2004/04/06 02:49:08 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.20 2004/04/05 19:55:06 mcr
-+ * Moved from linux/include/freeswan/ipsec_rcv.h,v
-+ *
-+ * Revision 1.19 2003/12/15 18:13:09 mcr
-+ * when compiling with NAT traversal, don't assume that the
-+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
-+ * is set.
-+ *
-+ * Revision 1.18 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.17 2002/09/03 16:32:32 mcr
-+ * definitions of ipsec_birth_reply.
-+ *
-+ * Revision 1.16 2002/05/14 02:36:00 rgb
-+ * Change references to _TDB to _IPSA.
-+ *
-+ * Revision 1.15 2002/04/24 07:36:47 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_rcv.h,v
-+ *
-+ * Revision 1.14 2001/09/07 22:15:48 rgb
-+ * Fix for removal of transport layer protocol handler arg in 2.4.4.
-+ *
-+ * Revision 1.13 2001/06/14 19:35:09 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.12 2001/03/16 07:36:44 rgb
-+ * Fixed #endif comment to sate compiler.
-+ *
-+ * Revision 1.11 2000/09/21 04:34:21 rgb
-+ * Moved declaration of sysctl_ipsec_inbound_policy_check outside
-+ * CONFIG_IPSEC_DEBUG. (MB)
-+ *
-+ * Revision 1.10 2000/09/18 02:36:10 rgb
-+ * Exported sysctl_ipsec_inbound_policy_check for skb_decompress().
-+ *
-+ * Revision 1.9 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.8 1999/11/18 04:09:19 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ *
-+ * Revision 1.7 1999/05/25 01:45:37 rgb
-+ * Fix version macros for 2.0.x as a module.
-+ *
-+ * Revision 1.6 1999/05/08 21:24:27 rgb
-+ * Add includes for 2.2.x include into net/ipv4/protocol.c
-+ *
-+ * Revision 1.5 1999/05/05 22:02:32 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.4 1999/04/11 00:28:59 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.3 1999/04/06 04:54:27 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.2 1999/01/22 20:06:59 rgb
-+ * Fixed cut-and-paste error from ipsec_esp.h.
-+ *
-+ * Revision 1.1 1999/01/21 20:29:12 rgb
-+ * Converted from transform switching to algorithm switching.
-+ *
-+ * Log: ipsec_esp.h,v
-+ * Revision 1.4 1998/08/12 00:07:32 rgb
-+ * Added data structures for new xforms: null, {,3}dessha1.
-+ *
-+ * Revision 1.3 1998/07/14 15:57:01 rgb
-+ * Add #ifdef __KERNEL__ to protect kernel-only structures.
-+ *
-+ * Revision 1.2 1998/06/25 19:33:46 rgb
-+ * Add prototype for protocol receive function.
-+ * Rearrange for more logical layout.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:45 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.6 1998/06/05 02:28:08 rgb
-+ * Minor comment fix.
-+ *
-+ * Revision 1.5 1998/05/27 22:34:00 rgb
-+ * Changed structures to accomodate key separation.
-+ *
-+ * Revision 1.4 1998/05/18 22:28:43 rgb
-+ * Disable key printing facilities from /proc/net/ipsec_*.
-+ *
-+ * Revision 1.3 1998/04/21 21:29:07 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.2 1998/04/12 22:03:20 rgb
-+ * Updated ESP-3DES-HMAC-MD5-96,
-+ * ESP-DES-HMAC-MD5-96,
-+ * AH-HMAC-MD5-96,
-+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
-+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
-+ *
-+ * Fixed eroute references in /proc/net/ipsec*.
-+ *
-+ * Started to patch module unloading memory leaks in ipsec_netlink and
-+ * radij tree unloading.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:00 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.5 1997/06/03 04:24:48 ji
-+ * Added ESP-3DES-MD5-96 transform.
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * Added definitions for new ESP transforms.
-+ *
-+ * Revision 0.3 1996/11/20 14:35:48 ji
-+ * Minor Cleanup.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
-+
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_sa.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,341 @@
-+/*
-+ * @(#) Definitions of IPsec Security Association (ipsec_sa)
-+ *
-+ * Copyright (C) 2001, 2002, 2003
-+ * Richard Guy Briggs <rgb@freeswan.org>
-+ * and Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ * This file derived from ipsec_xform.h on 2001/9/18 by mcr.
-+ *
-+ */
-+
-+/*
-+ * This file describes the IPsec Security Association Structure.
-+ *
-+ * This structure keeps track of a single transform that may be done
-+ * to a set of packets. It can describe applying the transform or
-+ * apply the reverse. (e.g. compression vs expansion). However, it
-+ * only describes one at a time. To describe both, two structures would
-+ * be used, but since the sides of the transform are performed
-+ * on different machines typically it is usual to have only one side
-+ * of each association.
-+ *
-+ */
-+
-+#ifndef _IPSEC_SA_H_
-+
-+#ifdef __KERNEL__
-+#include "ipsec_stats.h"
-+#include "ipsec_life.h"
-+#include "ipsec_eroute.h"
-+#endif /* __KERNEL__ */
-+#include "ipsec_param.h"
-+
-+
-+/* SAs are held in a table.
-+ * Entries in this table are referenced by IPsecSAref_t values.
-+ * IPsecSAref_t values are conceptually subscripts. Because
-+ * we want to allocate the table piece-meal, the subscripting
-+ * is implemented with two levels, a bit like paged virtual memory.
-+ * This representation mechanism is known as an Iliffe Vector.
-+ *
-+ * The Main table (AKA the refTable) consists of 2^IPSEC_SA_REF_MAINTABLE_IDX_WIDTH
-+ * pointers to subtables.
-+ * Each subtable has 2^IPSEC_SA_REF_SUBTABLE_IDX_WIDTH entries, each of which
-+ * is a pointer to an SA.
-+ *
-+ * An IPsecSAref_t contains either an exceptional value (signified by the
-+ * high-order bit being on) or a reference to a table entry. A table entry
-+ * reference has the subtable subscript in the low-order
-+ * IPSEC_SA_REF_SUBTABLE_IDX_WIDTH bits and the Main table subscript
-+ * in the next lowest IPSEC_SA_REF_MAINTABLE_IDX_WIDTH bits.
-+ *
-+ * The Maintable entry for an IPsecSAref_t x, a pointer to its subtable, is
-+ * IPsecSAref2table(x). It is of type struct IPsecSArefSubTable *.
-+ *
-+ * The pointer to the SA for x is IPsecSAref2SA(x). It is of type
-+ * struct ipsec_sa*. The macro definition clearly shows the two-level
-+ * access needed to find the SA pointer.
-+ *
-+ * The Maintable is allocated when IPsec is initialized.
-+ * Each subtable is allocated when needed, but the first is allocated
-+ * when IPsec is initialized.
-+ *
-+ * IPsecSAref_t is designed to be smaller than an NFmark so that
-+ * they can be stored in NFmarks and still leave a few bits for other
-+ * purposes. The spare bits are in the low order of the NFmark
-+ * but in the high order of the IPsecSAref_t, so conversion is required.
-+ * We pick the upper bits of NFmark on the theory that they are less likely to
-+ * interfere with more pedestrian uses of nfmark.
-+ */
-+
-+
-+typedef unsigned short int IPsecRefTableUnusedCount;
-+
-+#define IPSEC_SA_REF_TABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH)
-+
-+#ifdef __KERNEL__
-+#if ((IPSEC_SA_REF_TABLE_IDX_WIDTH - (1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) < 0)
-+#error "IPSEC_SA_REF_TABLE_IDX_WIDTH("IPSEC_SA_REF_TABLE_IDX_WIDTH") MUST be < 1 + IPSEC_SA_REF_MAINTABLE_IDX_WIDTH("IPSEC_SA_REF_MAINTABLE_IDX_WIDTH")"
-+#endif
-+
-+#define IPSEC_SA_REF_SUBTABLE_IDX_WIDTH (IPSEC_SA_REF_TABLE_IDX_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
-+
-+#define IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)
-+#define IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES (1 << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
-+
-+#ifdef CONFIG_NETFILTER
-+#define IPSEC_SA_REF_HOST_FIELD(x) ((struct sk_buff*)(x))->nfmark
-+#define IPSEC_SA_REF_HOST_FIELD_TYPE typeof(IPSEC_SA_REF_HOST_FIELD(NULL))
-+#else /* CONFIG_NETFILTER */
-+/* just make it work for now, it doesn't matter, since there is no nfmark */
-+#define IPSEC_SA_REF_HOST_FIELD_TYPE unsigned long
-+#endif /* CONFIG_NETFILTER */
-+#define IPSEC_SA_REF_HOST_FIELD_WIDTH (8 * sizeof(IPSEC_SA_REF_HOST_FIELD_TYPE))
-+#define IPSEC_SA_REF_FIELD_WIDTH (8 * sizeof(IPsecSAref_t))
-+
-+#define IPSEC_SA_REF_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_TABLE_IDX_WIDTH))
-+#define IPSEC_SA_REF_TABLE_MASK ((IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_MAINTABLE_IDX_WIDTH)) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
-+#define IPSEC_SA_REF_ENTRY_MASK (IPSEC_SAREF_NULL >> (IPSEC_SA_REF_FIELD_WIDTH - IPSEC_SA_REF_SUBTABLE_IDX_WIDTH))
-+
-+#define IPsecSAref2table(x) (((x) & IPSEC_SA_REF_TABLE_MASK) >> IPSEC_SA_REF_SUBTABLE_IDX_WIDTH)
-+#define IPsecSAref2entry(x) ((x) & IPSEC_SA_REF_ENTRY_MASK)
-+#define IPsecSArefBuild(x,y) (((x) << IPSEC_SA_REF_SUBTABLE_IDX_WIDTH) + (y))
-+
-+#define IPsecSAref2SA(x) (ipsec_sadb.refTable[IPsecSAref2table(x)]->entry[IPsecSAref2entry(x)])
-+#define IPsecSA2SAref(x) ((x)->ips_ref)
-+
-+#define EMT_INBOUND 0x01 /* SA direction, 1=inbound */
-+
-+/* 'struct ipsec_sa' should be 64bit aligned when allocated. */
-+struct ipsec_sa
-+{
-+ IPsecSAref_t ips_ref; /* reference table entry number */
-+ atomic_t ips_refcount; /* reference count for this struct */
-+ struct ipsec_sa *ips_hnext; /* next in hash chain */
-+ struct ipsec_sa *ips_inext; /* pointer to next xform */
-+ struct ipsec_sa *ips_onext; /* pointer to prev xform */
-+
-+ struct ifnet *ips_rcvif; /* related rcv encap interface */
-+
-+ ip_said ips_said; /* SA ID */
-+
-+ __u32 ips_seq; /* seq num of msg that initiated this SA */
-+ __u32 ips_pid; /* PID of process that initiated this SA */
-+ __u8 ips_authalg; /* auth algorithm for this SA */
-+ __u8 ips_encalg; /* enc algorithm for this SA */
-+
-+ struct ipsec_stats ips_errs;
-+
-+ __u8 ips_replaywin; /* replay window size */
-+ __u8 ips_state; /* state of SA */
-+ __u32 ips_replaywin_lastseq; /* last pkt sequence num */
-+ __u64 ips_replaywin_bitmap; /* bitmap of received pkts */
-+ __u32 ips_replaywin_maxdiff; /* max pkt sequence difference */
-+
-+ __u32 ips_flags; /* generic xform flags */
-+
-+
-+ struct ipsec_lifetimes ips_life; /* lifetime records */
-+
-+ /* selector information */
-+ __u8 ips_transport_protocol; /* protocol for this SA, if ports are involved */
-+ struct sockaddr*ips_addr_s; /* src sockaddr */
-+ struct sockaddr*ips_addr_d; /* dst sockaddr */
-+ struct sockaddr*ips_addr_p; /* proxy sockaddr */
-+ __u16 ips_addr_s_size;
-+ __u16 ips_addr_d_size;
-+ __u16 ips_addr_p_size;
-+ ip_address ips_flow_s;
-+ ip_address ips_flow_d;
-+ ip_address ips_mask_s;
-+ ip_address ips_mask_d;
-+
-+ __u16 ips_key_bits_a; /* size of authkey in bits */
-+ __u16 ips_auth_bits; /* size of authenticator in bits */
-+ __u16 ips_key_bits_e; /* size of enckey in bits */
-+ __u16 ips_iv_bits; /* size of IV in bits */
-+ __u8 ips_iv_size;
-+ __u16 ips_key_a_size;
-+ __u16 ips_key_e_size;
-+
-+ caddr_t ips_key_a; /* authentication key */
-+ caddr_t ips_key_e; /* encryption key */
-+ caddr_t ips_iv; /* Initialisation Vector */
-+
-+ struct ident ips_ident_s; /* identity src */
-+ struct ident ips_ident_d; /* identity dst */
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ __u16 ips_comp_adapt_tries; /* ipcomp self-adaption tries */
-+ __u16 ips_comp_adapt_skip; /* ipcomp self-adaption to-skip */
-+ __u64 ips_comp_ratio_cbytes; /* compressed bytes */
-+ __u64 ips_comp_ratio_dbytes; /* decompressed (or uncompressed) bytes */
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ __u8 ips_natt_type;
-+ __u8 ips_natt_reserved[3];
-+ __u16 ips_natt_sport;
-+ __u16 ips_natt_dport;
-+
-+ struct sockaddr *ips_natt_oa;
-+ __u16 ips_natt_oa_size;
-+ __u16 ips_natt_reserved2;
-+#endif
-+
-+#if 0
-+ __u32 ips_sens_dpd;
-+ __u8 ips_sens_sens_level;
-+ __u8 ips_sens_sens_len;
-+ __u64* ips_sens_sens_bitmap;
-+ __u8 ips_sens_integ_level;
-+ __u8 ips_sens_integ_len;
-+ __u64* ips_sens_integ_bitmap;
-+#endif
-+ struct ipsec_alg_enc *ips_alg_enc;
-+ struct ipsec_alg_auth *ips_alg_auth;
-+ IPsecSAref_t ips_ref_rel;
-+};
-+
-+struct IPsecSArefSubTable
-+{
-+ struct ipsec_sa* entry[IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES];
-+};
-+
-+struct ipsec_sadb {
-+ struct IPsecSArefSubTable* refTable[IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES];
-+ IPsecSAref_t refFreeList[IPSEC_SA_REF_FREELIST_NUM_ENTRIES];
-+ int refFreeListHead;
-+ int refFreeListTail;
-+ IPsecSAref_t refFreeListCont;
-+ IPsecSAref_t said_hash[SADB_HASHMOD];
-+ spinlock_t sadb_lock;
-+};
-+
-+extern struct ipsec_sadb ipsec_sadb;
-+
-+extern int ipsec_SAref_recycle(void);
-+extern int ipsec_SArefSubTable_alloc(unsigned table);
-+extern int ipsec_saref_freelist_init(void);
-+extern int ipsec_sadb_init(void);
-+extern struct ipsec_sa *ipsec_sa_alloc(int*error); /* pass in error var by pointer */
-+extern IPsecSAref_t ipsec_SAref_alloc(int*erorr); /* pass in error var by pointer */
-+extern int ipsec_sa_free(struct ipsec_sa* ips);
-+extern int ipsec_sa_put(struct ipsec_sa *ips);
-+extern int ipsec_sa_add(struct ipsec_sa *ips);
-+extern int ipsec_sa_del(struct ipsec_sa *ips);
-+extern int ipsec_sa_delchain(struct ipsec_sa *ips);
-+extern int ipsec_sadb_cleanup(__u8 proto);
-+extern int ipsec_sadb_free(void);
-+extern int ipsec_sa_wipe(struct ipsec_sa *ips);
-+#endif /* __KERNEL__ */
-+
-+enum ipsec_direction {
-+ ipsec_incoming = 1,
-+ ipsec_outgoing = 2
-+};
-+
-+#define _IPSEC_SA_H_
-+#endif /* _IPSEC_SA_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.19 2004/04/05 19:55:06 mcr
-+ * Moved from linux/include/freeswan/ipsec_sa.h,v
-+ *
-+ * Revision 1.18 2004/04/05 19:41:05 mcr
-+ * merged alg-branch code.
-+ *
-+ * Revision 1.17.2.1 2003/12/22 15:25:52 jjo
-+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.17 2003/12/10 01:20:06 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.16 2003/10/31 02:27:05 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.15.4.1 2003/10/29 01:10:19 mcr
-+ * elimited "struct sa_id"
-+ *
-+ * Revision 1.15 2003/05/11 00:53:09 mcr
-+ * IPsecSAref_t and macros were moved to freeswan.h.
-+ *
-+ * Revision 1.14 2003/02/12 19:31:55 rgb
-+ * Fixed bug in "file seen" machinery.
-+ * Updated copyright year.
-+ *
-+ * Revision 1.13 2003/01/30 02:31:52 rgb
-+ *
-+ * Re-wrote comments describing SAref system for accuracy.
-+ * Rename SAref table macro names for clarity.
-+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
-+ * Transmit error code through to caller from callee for better diagnosis of problems.
-+ * Enclose all macro arguments in parens to avoid any possible obscrure bugs.
-+ *
-+ * Revision 1.12 2002/10/07 18:31:19 rgb
-+ * Change comment to reflect the flexible nature of the main and sub-table widths.
-+ * Added a counter for the number of unused entries in each subtable.
-+ * Further break up host field type macro to host field.
-+ * Move field width sanity checks to ipsec_sa.c
-+ * Define a mask for an entire saref.
-+ *
-+ * Revision 1.11 2002/09/20 15:40:33 rgb
-+ * Re-write most of the SAref macros and types to eliminate any pointer references to Entrys.
-+ * Fixed SAref/nfmark macros.
-+ * Rework saref freeslist.
-+ * Place all ipsec sadb globals into one struct.
-+ * Restrict some bits to kernel context for use to klips utils.
-+ *
-+ * Revision 1.10 2002/09/20 05:00:34 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.9 2002/09/17 17:19:29 mcr
-+ * make it compile even if there is no netfilter - we lost
-+ * functionality, but it works, especially on 2.2.
-+ *
-+ * Revision 1.8 2002/07/28 22:59:53 mcr
-+ * clarified/expanded one comment.
-+ *
-+ * Revision 1.7 2002/07/26 08:48:31 rgb
-+ * Added SA ref table code.
-+ *
-+ * Revision 1.6 2002/05/31 17:27:48 rgb
-+ * Comment fix.
-+ *
-+ * Revision 1.5 2002/05/27 18:55:03 rgb
-+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
-+ *
-+ * Revision 1.4 2002/05/23 07:13:36 rgb
-+ * Convert "usecount" to "refcount" to remove ambiguity.
-+ *
-+ * Revision 1.3 2002/04/24 07:36:47 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_sa.h,v
-+ *
-+ * Revision 1.2 2001/11/26 09:16:15 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:24:58 mcr
-+ * struct tdb -> struct ipsec_sa.
-+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
-+ * ipsec_xform.c removed. header file still contains useful things.
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_sha1.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,79 @@
-+/*
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * Here is the original comment from the distribution:
-+
-+SHA-1 in C
-+By Steve Reid <steve@edmweb.com>
-+100% Public Domain
-+
-+ * Adapted for use by the IPSEC code by John Ioannidis
-+ */
-+
-+
-+#ifndef _IPSEC_SHA1_H_
-+#define _IPSEC_SHA1_H_
-+
-+typedef struct
-+{
-+ __u32 state[5];
-+ __u32 count[2];
-+ __u8 buffer[64];
-+} SHA1_CTX;
-+
-+void SHA1Transform(__u32 state[5], __u8 buffer[64]);
-+void SHA1Init(void *context);
-+void SHA1Update(void *context, unsigned char *data, __u32 len);
-+void SHA1Final(unsigned char digest[20], void *context);
-+
-+
-+#endif /* _IPSEC_SHA1_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.8 2004/04/05 19:55:07 mcr
-+ * Moved from linux/include/freeswan/ipsec_sha1.h,v
-+ *
-+ * Revision 1.7 2002/09/10 01:45:09 mcr
-+ * changed type of MD5_CTX and SHA1_CTX to void * so that
-+ * the function prototypes would match, and could be placed
-+ * into a pointer to a function.
-+ *
-+ * Revision 1.6 2002/04/24 07:36:47 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_sha1.h,v
-+ *
-+ * Revision 1.5 1999/12/13 13:59:13 rgb
-+ * Quick fix to argument size to Update bugs.
-+ *
-+ * Revision 1.4 1999/12/07 18:16:23 rgb
-+ * Fixed comments at end of #endif lines.
-+ *
-+ * Revision 1.3 1999/04/06 04:54:27 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.2 1998/11/30 13:22:54 rgb
-+ * Rationalised all the klips kernel file headers. They are much shorter
-+ * now and won't conflict under RH5.2.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:50 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.2 1998/04/23 20:54:05 rgb
-+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
-+ * verified.
-+ *
-+ * Revision 1.1 1998/04/09 03:04:21 henry
-+ * sources moved up from linux/net/ipsec
-+ * these two include files modified not to include others except in kernel
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * New transform
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_stats.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,75 @@
-+/*
-+ * @(#) definition of ipsec_stats structure
-+ *
-+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ * and Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ */
-+
-+/*
-+ * This file describes the errors/statistics that FreeSWAN collects.
-+ */
-+
-+#ifndef _IPSEC_STATS_H_
-+
-+struct ipsec_stats {
-+ __u32 ips_alg_errs; /* number of algorithm errors */
-+ __u32 ips_auth_errs; /* # of authentication errors */
-+ __u32 ips_encsize_errs; /* # of encryption size errors*/
-+ __u32 ips_encpad_errs; /* # of encryption pad errors*/
-+ __u32 ips_replaywin_errs; /* # of pkt sequence errors */
-+};
-+
-+extern int ipsec_snprintf(char * buf, ssize_t size, const char *fmt, ...);
-+
-+#define _IPSEC_STATS_H_
-+#endif /* _IPSEC_STATS_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.6 2004/04/05 19:55:07 mcr
-+ * Moved from linux/include/freeswan/ipsec_stats.h,v
-+ *
-+ * Revision 1.5 2004/04/05 19:41:05 mcr
-+ * merged alg-branch code.
-+ *
-+ * Revision 1.4 2004/03/28 20:27:19 paul
-+ * Included tested and confirmed fixes mcr made and dhr verified for
-+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
-+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
-+ * dhr. (thanks dhr!)
-+ *
-+ * Revision 1.4 2004/03/24 01:58:31 mcr
-+ * sprintf->snprintf for formatting into proc buffer.
-+ *
-+ * Revision 1.3.34.1 2004/04/05 04:30:46 mcr
-+ * patches for alg-branch to compile/work with 2.x openswan
-+ *
-+ * Revision 1.3 2002/04/24 07:36:47 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_stats.h,v
-+ *
-+ * Revision 1.2 2001/11/26 09:16:16 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:27:00 mcr
-+ * statistics moved to seperate structure.
-+ *
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_tunnel.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,265 @@
-+/*
-+ * IPSEC tunneling code
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+
-+#ifdef NET_21
-+# define DEV_QUEUE_XMIT(skb, device, pri) {\
-+ skb->dev = device; \
-+ neigh_compat_output(skb); \
-+ /* skb->dst->output(skb); */ \
-+ }
-+# define ICMP_SEND(skb_in, type, code, info, dev) \
-+ icmp_send(skb_in, type, code, htonl(info))
-+# define IP_SEND(skb, dev) \
-+ ip_send(skb);
-+#else /* NET_21 */
-+# define DEV_QUEUE_XMIT(skb, device, pri) {\
-+ dev_queue_xmit(skb, device, pri); \
-+ }
-+# define ICMP_SEND(skb_in, type, code, info, dev) \
-+ icmp_send(skb_in, type, code, info, dev)
-+# define IP_SEND(skb, dev) \
-+ if(ntohs(iph->tot_len) > physmtu) { \
-+ ip_fragment(NULL, skb, dev, 0); \
-+ ipsec_kfree_skb(skb); \
-+ } else { \
-+ dev_queue_xmit(skb, dev, SOPRI_NORMAL); \
-+ }
-+#endif /* NET_21 */
-+
-+
-+/*
-+ * Heavily based on drivers/net/new_tunnel.c. Lots
-+ * of ideas also taken from the 2.1.x version of drivers/net/shaper.c
-+ */
-+
-+struct ipsectunnelconf
-+{
-+ __u32 cf_cmd;
-+ union
-+ {
-+ char cfu_name[12];
-+ } cf_u;
-+#define cf_name cf_u.cfu_name
-+};
-+
-+#define IPSEC_SET_DEV (SIOCDEVPRIVATE)
-+#define IPSEC_DEL_DEV (SIOCDEVPRIVATE + 1)
-+#define IPSEC_CLR_DEV (SIOCDEVPRIVATE + 2)
-+
-+#ifdef __KERNEL__
-+#include <linux/version.h>
-+#ifndef KERNEL_VERSION
-+# define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
-+#endif
-+struct ipsecpriv
-+{
-+ struct sk_buff_head sendq;
-+ struct device *dev;
-+ struct wait_queue *wait_queue;
-+ char locked;
-+ int (*hard_start_xmit) (struct sk_buff *skb,
-+ struct device *dev);
-+ int (*hard_header) (struct sk_buff *skb,
-+ struct device *dev,
-+ unsigned short type,
-+ void *daddr,
-+ void *saddr,
-+ unsigned len);
-+#ifdef NET_21
-+ int (*rebuild_header)(struct sk_buff *skb);
-+#else /* NET_21 */
-+ int (*rebuild_header)(void *buff, struct device *dev,
-+ unsigned long raddr, struct sk_buff *skb);
-+#endif /* NET_21 */
-+ int (*set_mac_address)(struct device *dev, void *addr);
-+#ifndef NET_21
-+ void (*header_cache_bind)(struct hh_cache **hhp, struct device *dev,
-+ unsigned short htype, __u32 daddr);
-+#endif /* !NET_21 */
-+ void (*header_cache_update)(struct hh_cache *hh, struct device *dev, unsigned char * haddr);
-+ struct net_device_stats *(*get_stats)(struct device *dev);
-+ struct net_device_stats mystats;
-+ int mtu; /* What is the desired MTU? */
-+};
-+
-+extern char ipsec_tunnel_c_version[];
-+
-+extern struct device *ipsecdevices[IPSEC_NUM_IF];
-+
-+int ipsec_tunnel_init_devices(void);
-+
-+/* void */ int ipsec_tunnel_cleanup_devices(void);
-+
-+extern /* void */ int ipsec_init(void);
-+
-+extern int ipsec_tunnel_start_xmit(struct sk_buff *skb, struct device *dev);
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int debug_tunnel;
-+extern int sysctl_ipsec_debug_verbose;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#endif /* __KERNEL__ */
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+#define DB_TN_INIT 0x0001
-+#define DB_TN_PROCFS 0x0002
-+#define DB_TN_XMIT 0x0010
-+#define DB_TN_OHDR 0x0020
-+#define DB_TN_CROUT 0x0040
-+#define DB_TN_OXFS 0x0080
-+#define DB_TN_REVEC 0x0100
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.29 2004/04/05 19:55:07 mcr
-+ * Moved from linux/include/freeswan/ipsec_tunnel.h,v
-+ *
-+ * Revision 1.28 2003/06/24 20:22:32 mcr
-+ * added new global: ipsecdevices[] so that we can keep track of
-+ * the ipsecX devices. They will be referenced with dev_hold(),
-+ * so 2.2 may need this as well.
-+ *
-+ * Revision 1.27 2003/04/03 17:38:09 rgb
-+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
-+ *
-+ * Revision 1.26 2003/02/12 19:32:20 rgb
-+ * Updated copyright year.
-+ *
-+ * Revision 1.25 2002/05/27 18:56:07 rgb
-+ * Convert to dynamic ipsec device allocation.
-+ *
-+ * Revision 1.24 2002/04/24 07:36:48 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_tunnel.h,v
-+ *
-+ * Revision 1.23 2001/11/06 19:50:44 rgb
-+ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
-+ * use also by pfkey_v2_parser.c
-+ *
-+ * Revision 1.22 2001/09/15 16:24:05 rgb
-+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
-+ *
-+ * Revision 1.21 2001/06/14 19:35:10 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.20 2000/09/15 11:37:02 rgb
-+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
-+ * IPCOMP zlib deflate code.
-+ *
-+ * Revision 1.19 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.18 2000/07/28 13:50:54 rgb
-+ * Changed enet_statistics to net_device_stats and added back compatibility
-+ * for pre-2.1.19.
-+ *
-+ * Revision 1.17 1999/11/19 01:12:15 rgb
-+ * Purge unneeded proc_info prototypes, now that static linking uses
-+ * dynamic proc_info registration.
-+ *
-+ * Revision 1.16 1999/11/18 18:51:00 rgb
-+ * Changed all device registrations for static linking to
-+ * dynamic to reduce the number and size of patches.
-+ *
-+ * Revision 1.15 1999/11/18 04:14:21 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
-+ * Added Marc Boucher's 2.3.25 proc patches.
-+ *
-+ * Revision 1.14 1999/05/25 02:50:10 rgb
-+ * Fix kernel version macros for 2.0.x static linking.
-+ *
-+ * Revision 1.13 1999/05/25 02:41:06 rgb
-+ * Add ipsec_klipsdebug support for static linking.
-+ *
-+ * Revision 1.12 1999/05/05 22:02:32 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.11 1999/04/29 15:19:50 rgb
-+ * Add return values to init and cleanup functions.
-+ *
-+ * Revision 1.10 1999/04/16 16:02:39 rgb
-+ * Bump up macro to 4 ipsec I/Fs.
-+ *
-+ * Revision 1.9 1999/04/15 15:37:25 rgb
-+ * Forward check changes from POST1_00 branch.
-+ *
-+ * Revision 1.5.2.1 1999/04/02 04:26:14 rgb
-+ * Backcheck from HEAD, pre1.0.
-+ *
-+ * Revision 1.8 1999/04/11 00:29:01 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.7 1999/04/06 04:54:28 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.6 1999/03/31 05:44:48 rgb
-+ * Keep PMTU reduction private.
-+ *
-+ * Revision 1.5 1999/02/10 22:31:20 rgb
-+ * Change rebuild_header member to reflect generality of link layer.
-+ *
-+ * Revision 1.4 1998/12/01 13:22:04 rgb
-+ * Added support for debug printing of version info.
-+ *
-+ * Revision 1.3 1998/07/29 20:42:46 rgb
-+ * Add a macro for clearing all tunnel devices.
-+ * Rearrange structures and declarations for sharing with userspace.
-+ *
-+ * Revision 1.2 1998/06/25 20:01:45 rgb
-+ * Make prototypes available for ipsec_init and ipsec proc_dir_entries
-+ * for static linking.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:50 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.3 1998/05/18 21:51:50 rgb
-+ * Added macros for num of I/F's and a procfs debug switch.
-+ *
-+ * Revision 1.2 1998/04/21 21:29:09 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:13 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:05 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.5 1997/06/03 04:24:48 ji
-+ * Added transport mode.
-+ * Changed the way routing is done.
-+ * Lots of bug fixes.
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * No changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:39:04 ji
-+ * Minor cleanups.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_xform.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,254 @@
-+/*
-+ * Definitions relevant to IPSEC transformations
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ * COpyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifndef _IPSEC_XFORM_H_
-+
-+#include <openswan.h>
-+
-+#define XF_NONE 0 /* No transform set */
-+#define XF_IP4 1 /* IPv4 inside IPv4 */
-+#define XF_AHMD5 2 /* AH MD5 */
-+#define XF_AHSHA 3 /* AH SHA */
-+#define XF_ESP3DES 5 /* ESP DES3-CBC */
-+#define XF_AHHMACMD5 6 /* AH-HMAC-MD5 with opt replay prot */
-+#define XF_AHHMACSHA1 7 /* AH-HMAC-SHA1 with opt replay prot */
-+#define XF_ESP3DESMD5 9 /* triple DES, HMAC-MD-5, 128-bits of authentication */
-+#define XF_ESP3DESMD596 10 /* triple DES, HMAC-MD-5, 96-bits of authentication */
-+#define XF_ESPNULLMD596 12 /* NULL, HMAC-MD-5 with 96-bits of authentication */
-+#define XF_ESPNULLSHA196 13 /* NULL, HMAC-SHA-1 with 96-bits of authentication */
-+#define XF_ESP3DESSHA196 14 /* triple DES, HMAC-SHA-1, 96-bits of authentication */
-+#define XF_IP6 15 /* IPv6 inside IPv6 */
-+#define XF_COMPDEFLATE 16 /* IPCOMP deflate */
-+
-+#define XF_CLR 126 /* Clear SA table */
-+#define XF_DEL 127 /* Delete SA */
-+
-+/* IPsec AH transform values
-+ * RFC 2407
-+ * draft-ietf-ipsec-doi-tc-mib-02.txt
-+ */
-+
-+#define AH_NONE 0
-+#define AH_MD5 2
-+#define AH_SHA 3
-+/* draft-ietf-ipsec-ciph-aes-cbc-03.txt */
-+#define AH_SHA2_256 5
-+#define AH_SHA2_384 6
-+#define AH_SHA2_512 7
-+#define AH_RIPEMD 8
-+#define AH_MAX 15
-+
-+/* IPsec ESP transform values */
-+
-+#define ESP_NONE 0
-+#define ESP_DES 2
-+#define ESP_3DES 3
-+#define ESP_RC5 4
-+#define ESP_IDEA 5
-+#define ESP_CAST 6
-+#define ESP_BLOWFISH 7
-+#define ESP_3IDEA 8
-+#define ESP_RC4 10
-+#define ESP_NULL 11
-+#define ESP_AES 12
-+
-+/* as draft-ietf-ipsec-ciph-aes-cbc-02.txt */
-+#define ESP_MARS 249
-+#define ESP_RC6 250
-+#define ESP_SERPENT 252
-+#define ESP_TWOFISH 253
-+
-+/* IPCOMP transform values */
-+
-+#define IPCOMP_NONE 0
-+#define IPCOMP_OUI 1
-+#define IPCOMP_DEFLAT 2
-+#define IPCOMP_LZS 3
-+#define IPCOMP_V42BIS 4
-+
-+#define XFT_AUTH 0x0001
-+#define XFT_CONF 0x0100
-+
-+/* available if CONFIG_IPSEC_DEBUG is defined */
-+#define DB_XF_INIT 0x0001
-+
-+#define PROTO2TXT(x) \
-+ (x) == IPPROTO_AH ? "AH" : \
-+ (x) == IPPROTO_ESP ? "ESP" : \
-+ (x) == IPPROTO_IPIP ? "IPIP" : \
-+ (x) == IPPROTO_COMP ? "COMP" : \
-+ "UNKNOWN_proto"
-+static inline const char *enc_name_id (unsigned id) {
-+ static char buf[16];
-+ snprintf(buf, sizeof(buf), "_ID%d", id);
-+ return buf;
-+}
-+static inline const char *auth_name_id (unsigned id) {
-+ static char buf[16];
-+ snprintf(buf, sizeof(buf), "_ID%d", id);
-+ return buf;
-+}
-+#define IPS_XFORM_NAME(x) \
-+ PROTO2TXT((x)->ips_said.proto), \
-+ (x)->ips_said.proto == IPPROTO_COMP ? \
-+ ((x)->ips_encalg == SADB_X_CALG_DEFLATE ? \
-+ "_DEFLATE" : "_UNKNOWN_comp") : \
-+ (x)->ips_encalg == ESP_NONE ? "" : \
-+ (x)->ips_encalg == ESP_3DES ? "_3DES" : \
-+ (x)->ips_encalg == ESP_AES ? "_AES" : \
-+ (x)->ips_encalg == ESP_SERPENT ? "_SERPENT" : \
-+ (x)->ips_encalg == ESP_TWOFISH ? "_TWOFISH" : \
-+ enc_name_id(x->ips_encalg)/* "_UNKNOWN_encr" */, \
-+ (x)->ips_authalg == AH_NONE ? "" : \
-+ (x)->ips_authalg == AH_MD5 ? "_HMAC_MD5" : \
-+ (x)->ips_authalg == AH_SHA ? "_HMAC_SHA1" : \
-+ (x)->ips_authalg == AH_SHA2_256 ? "_HMAC_SHA2_256" : \
-+ (x)->ips_authalg == AH_SHA2_384 ? "_HMAC_SHA2_384" : \
-+ (x)->ips_authalg == AH_SHA2_512 ? "_HMAC_SHA2_512" : \
-+ auth_name_id(x->ips_authalg) /* "_UNKNOWN_auth" */ \
-+
-+#ifdef __KERNEL__
-+struct ipsec_rcv_state;
-+struct ipsec_xmit_state;
-+
-+struct xform_functions {
-+ enum ipsec_rcv_value (*rcv_checks)(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb);
-+ enum ipsec_rcv_value (*rcv_decrypt)(struct ipsec_rcv_state *irs);
-+
-+ enum ipsec_rcv_value (*rcv_setup_auth)(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb,
-+ __u32 *replay,
-+ unsigned char **authenticator);
-+ enum ipsec_rcv_value (*rcv_calc_auth)(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb);
-+
-+ enum ipsec_xmit_value (*xmit_setup)(struct ipsec_xmit_state *ixs);
-+ enum ipsec_xmit_value (*xmit_encrypt)(struct ipsec_xmit_state *ixs);
-+
-+ enum ipsec_xmit_value (*xmit_setup_auth)(struct ipsec_xmit_state *ixs,
-+ struct sk_buff *skb,
-+ __u32 *replay,
-+ unsigned char **authenticator);
-+ enum ipsec_xmit_value (*xmit_calc_auth)(struct ipsec_xmit_state *ixs,
-+ struct sk_buff *skb);
-+ int xmit_headroom;
-+ int xmit_needtailroom;
-+};
-+
-+#endif /* __KERNEL__ */
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern void ipsec_dmp(char *s, caddr_t bb, int len);
-+#else /* CONFIG_IPSEC_DEBUG */
-+#define ipsec_dmp(_x, _y, _z)
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+
-+#define _IPSEC_XFORM_H_
-+#endif /* _IPSEC_XFORM_H_ */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.40 2004/04/06 02:49:08 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.39 2004/04/05 19:55:07 mcr
-+ * Moved from linux/include/freeswan/ipsec_xform.h,v
-+ *
-+ * Revision 1.38 2004/04/05 19:41:05 mcr
-+ * merged alg-branch code.
-+ *
-+ * Revision 1.37 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.36.34.1 2003/12/22 15:25:52 jjo
-+ * Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.36 2002/04/24 07:36:48 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_xform.h,v
-+ *
-+ * Revision 1.35 2001/11/26 09:23:51 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.33.2.1 2001/09/25 02:24:58 mcr
-+ * struct tdb -> struct ipsec_sa.
-+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
-+ * ipsec_xform.c removed. header file still contains useful things.
-+ *
-+ * Revision 1.34 2001/11/06 19:47:17 rgb
-+ * Changed lifetime_packets to uint32 from uint64.
-+ *
-+ * Revision 1.33 2001/09/08 21:13:34 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.32 2001/07/06 07:40:01 rgb
-+ * Reformatted for readability.
-+ * Added inbound policy checking fields for use with IPIP SAs.
-+ *
-+ * Revision 1.31 2001/06/14 19:35:11 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.30 2001/05/30 08:14:03 rgb
-+ * Removed vestiges of esp-null transforms.
-+ *
-+ * Revision 1.29 2001/01/30 23:42:47 rgb
-+ * Allow pfkey msgs from pid other than user context required for ACQUIRE
-+ * and subsequent ADD or UDATE.
-+ *
-+ * Revision 1.28 2000/11/06 04:30:40 rgb
-+ * Add Svenning's adaptive content compression.
-+ *
-+ * Revision 1.27 2000/09/19 00:38:25 rgb
-+ * Fixed algorithm name bugs introduced for ipcomp.
-+ *
-+ * Revision 1.26 2000/09/17 21:36:48 rgb
-+ * Added proto2txt macro.
-+ *
-+ * Revision 1.25 2000/09/17 18:56:47 rgb
-+ * Added IPCOMP support.
-+ *
-+ * Revision 1.24 2000/09/12 19:34:12 rgb
-+ * Defined XF_IP6 from Gerhard for ipv6 tunnel support.
-+ *
-+ * Revision 1.23 2000/09/12 03:23:14 rgb
-+ * Cleaned out now unused tdb_xform and tdb_xdata members of struct tdb.
-+ *
-+ * Revision 1.22 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.21 2000/09/01 18:32:43 rgb
-+ * Added (disabled) sensitivity members to tdb struct.
-+ *
-+ * Revision 1.20 2000/08/30 05:31:01 rgb
-+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
-+ * Kill remainder of tdb_xform, tdb_xdata, xformsw.
-+ *
-+ * Revision 1.19 2000/08/01 14:51:52 rgb
-+ * Removed _all_ remaining traces of DES.
-+ *
-+ * Revision 1.18 2000/01/21 06:17:45 rgb
-+ * Tidied up spacing.
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/ipsec_xmit.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,176 @@
-+/*
-+ * IPSEC tunneling code
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#include "openswan/ipsec_sa.h"
-+
-+enum ipsec_xmit_value
-+{
-+ IPSEC_XMIT_STOLEN=2,
-+ IPSEC_XMIT_PASS=1,
-+ IPSEC_XMIT_OK=0,
-+ IPSEC_XMIT_ERRMEMALLOC=-1,
-+ IPSEC_XMIT_ESP_BADALG=-2,
-+ IPSEC_XMIT_BADPROTO=-3,
-+ IPSEC_XMIT_ESP_PUSHPULLERR=-4,
-+ IPSEC_XMIT_BADLEN=-5,
-+ IPSEC_XMIT_AH_BADALG=-6,
-+ IPSEC_XMIT_SAIDNOTFOUND=-7,
-+ IPSEC_XMIT_SAIDNOTLIVE=-8,
-+ IPSEC_XMIT_REPLAYROLLED=-9,
-+ IPSEC_XMIT_LIFETIMEFAILED=-10,
-+ IPSEC_XMIT_CANNOTFRAG=-11,
-+ IPSEC_XMIT_MSSERR=-12,
-+ IPSEC_XMIT_ERRSKBALLOC=-13,
-+ IPSEC_XMIT_ENCAPFAIL=-14,
-+ IPSEC_XMIT_NODEV=-15,
-+ IPSEC_XMIT_NOPRIVDEV=-16,
-+ IPSEC_XMIT_NOPHYSDEV=-17,
-+ IPSEC_XMIT_NOSKB=-18,
-+ IPSEC_XMIT_NOIPV6=-19,
-+ IPSEC_XMIT_NOIPOPTIONS=-20,
-+ IPSEC_XMIT_TTLEXPIRED=-21,
-+ IPSEC_XMIT_BADHHLEN=-22,
-+ IPSEC_XMIT_PUSHPULLERR=-23,
-+ IPSEC_XMIT_ROUTEERR=-24,
-+ IPSEC_XMIT_RECURSDETECT=-25,
-+ IPSEC_XMIT_IPSENDFAILURE=-26,
-+ IPSEC_XMIT_ESPUDP=-27,
-+ IPSEC_XMIT_ESPUDP_BADTYPE=-28,
-+};
-+
-+struct ipsec_xmit_state
-+{
-+ struct sk_buff *skb; /* working skb pointer */
-+ struct device *dev; /* working dev pointer */
-+ struct ipsecpriv *prv; /* Our device' private space */
-+ struct sk_buff *oskb; /* Original skb pointer */
-+ struct net_device_stats *stats; /* This device's statistics */
-+ struct iphdr *iph; /* Our new IP header */
-+ __u32 newdst; /* The other SG's IP address */
-+ __u32 orgdst; /* Original IP destination address */
-+ __u32 orgedst; /* 1st SG's IP address */
-+ __u32 newsrc; /* The new source SG's IP address */
-+ __u32 orgsrc; /* Original IP source address */
-+ __u32 innersrc; /* Innermost IP source address */
-+ int iphlen; /* IP header length */
-+ int pyldsz; /* upper protocol payload size */
-+ int headroom;
-+ int tailroom;
-+ int authlen;
-+ int max_headroom; /* The extra header space needed */
-+ int max_tailroom; /* The extra stuffing needed */
-+ int ll_headroom; /* The extra link layer hard_header space needed */
-+ int tot_headroom; /* The total header space needed */
-+ int tot_tailroom; /* The totalstuffing needed */
-+ __u8 *saved_header; /* saved copy of the hard header */
-+ unsigned short sport, dport;
-+
-+ struct sockaddr_encap matcher; /* eroute search key */
-+ struct eroute *eroute;
-+ struct ipsec_sa *ipsp, *ipsq; /* ipsec_sa pointers */
-+ char sa_txt[SATOT_BUF];
-+ size_t sa_len;
-+ int hard_header_stripped; /* has the hard header been removed yet? */
-+ int hard_header_len;
-+ struct device *physdev;
-+/* struct device *virtdev; */
-+ short physmtu;
-+ short mtudiff;
-+#ifdef NET_21
-+ struct rtable *route;
-+#endif /* NET_21 */
-+ ip_said outgoing_said;
-+#ifdef NET_21
-+ int pass;
-+#endif /* NET_21 */
-+ int error;
-+ uint32_t eroute_pid;
-+ struct ipsec_sa ips;
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ uint8_t natt_type;
-+ uint8_t natt_head;
-+ uint16_t natt_sport;
-+ uint16_t natt_dport;
-+#endif
-+};
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs);
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs);
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs);
-+
-+extern void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er);
-+
-+
-+extern int ipsec_xmit_trap_count;
-+extern int ipsec_xmit_trap_sendcount;
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int debug_tunnel;
-+extern int sysctl_ipsec_debug_verbose;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#define debug_xmit debug_tunnel
-+
-+#define ipsec_xmit_dmp(_x,_y, _z) if (debug_xmit && sysctl_ipsec_debug_verbose) ipsec_dmp(_x,_y,_z)
-+
-+extern int sysctl_ipsec_icmp;
-+extern int sysctl_ipsec_tos;
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.9 2004/04/06 02:49:08 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.8 2004/04/05 19:55:07 mcr
-+ * Moved from linux/include/freeswan/ipsec_xmit.h,v
-+ *
-+ * Revision 1.7 2004/02/03 03:11:40 mcr
-+ * new xmit type if the UDP encapsulation is wrong.
-+ *
-+ * Revision 1.6 2003/12/13 19:10:16 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.5 2003/12/10 01:20:06 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.4 2003/12/06 16:37:04 mcr
-+ * 1.4.7a X.509 patch applied.
-+ *
-+ * Revision 1.3 2003/10/31 02:27:05 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.2.4.2 2003/10/29 01:10:19 mcr
-+ * elimited "struct sa_id"
-+ *
-+ * Revision 1.2.4.1 2003/09/21 13:59:38 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.2 2003/06/20 01:42:13 mcr
-+ * added counters to measure how many ACQUIREs we send to pluto,
-+ * and how many are successfully sent.
-+ *
-+ * Revision 1.1 2003/02/12 19:31:03 rgb
-+ * Refactored from ipsec_tunnel.c
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/passert.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,64 @@
-+/*
-+ * sanitize a string into a printable format.
-+ *
-+ * Copyright (C) 1998-2002 D. Hugh Redelmeier.
-+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#include "openswan.h"
-+
-+/* our versions of assert: log result */
-+
-+#ifdef DEBUG
-+
-+extern void passert_fail(const char *pred_str
-+ , const char *file_str, unsigned long line_no) NEVER_RETURNS;
-+
-+extern void pexpect_log(const char *pred_str
-+ , const char *file_str, unsigned long line_no);
-+
-+# define impossible() passert_fail("impossible", __FILE__, __LINE__)
-+
-+extern void switch_fail(int n
-+ , const char *file_str, unsigned long line_no) NEVER_RETURNS;
-+
-+# define bad_case(n) switch_fail((int) n, __FILE__, __LINE__)
-+
-+# define passert(pred) { \
-+ if (!(pred)) \
-+ passert_fail(#pred, __FILE__, __LINE__); \
-+ }
-+
-+# define pexpect(pred) { \
-+ if (!(pred)) \
-+ pexpect_log(#pred, __FILE__, __LINE__); \
-+ }
-+
-+/* assert that an err_t is NULL; evaluate exactly once */
-+# define happy(x) { \
-+ err_t ugh = x; \
-+ if (ugh != NULL) \
-+ passert_fail(ugh, __FILE__, __LINE__); \
-+ }
-+
-+#else /*!DEBUG*/
-+
-+# define impossible() abort()
-+# define bad_case(n) abort()
-+# define passert(pred) { } /* do nothing */
-+# define happy(x) { (void) x; } /* evaluate non-judgementally */
-+
-+#endif /*!DEBUG*/
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/pfkey_debug.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,54 @@
-+/*
-+ * sanitize a string into a printable format.
-+ *
-+ * Copyright (C) 1998-2002 D. Hugh Redelmeier.
-+ * Copyright (C) 2003 Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifndef _FREESWAN_PFKEY_DEBUG_H
-+#define _FREESWAN_PFKEY_DEBUG_H
-+
-+#ifdef __KERNEL__
-+
-+/* note, kernel version ignores pfkey levels */
-+# define DEBUGGING(level,args...) \
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:" args)
-+
-+# define ERROR(args...) printk(KERN_ERR "klips:" args)
-+
-+#else
-+
-+extern unsigned int pfkey_lib_debug;
-+
-+extern void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
-+extern void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
-+
-+#define DEBUGGING(level,args...) if(pfkey_lib_debug & level) { \
-+ if(pfkey_debug_func != NULL) { \
-+ (*pfkey_debug_func)("pfkey_lib_debug:" args); \
-+ } else { \
-+ printf("pfkey_lib_debug:" args); \
-+ } }
-+
-+#define ERROR(args...) if(pfkey_error_func != NULL) { \
-+ (*pfkey_error_func)("pfkey_lib_debug:" args); \
-+ }
-+
-+# define MALLOC(size) malloc(size)
-+# define FREE(obj) free(obj)
-+
-+#endif
-+
-+#endif
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/openswan/radij.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,280 @@
-+/*
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * This file is defived from ${SRC}/sys/net/radix.h of BSD 4.4lite
-+ *
-+ * Variable and procedure names have been modified so that they don't
-+ * conflict with the original BSD code, as a small number of modifications
-+ * have been introduced and we may want to reuse this code in BSD.
-+ *
-+ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
-+ * chi or a German ch sound (as `doch', not as in `milch'), or even a
-+ * spanish j as in Juan. It is not as far back in the throat like
-+ * the corresponding Hebrew sound, nor is it a soft breath like the English h.
-+ * It has nothing to do with the Dutch ij sound.
-+ *
-+ * Here is the appropriate copyright notice:
-+ */
-+
-+/*
-+ * Copyright (c) 1988, 1989, 1993
-+ * The Regents of the University of California. All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * This product includes software developed by the University of
-+ * California, Berkeley and its contributors.
-+ * 4. Neither the name of the University nor the names of its contributors
-+ * may be used to endorse or promote products derived from this software
-+ * without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * @(#)radix.h 8.1 (Berkeley) 6/10/93
-+ */
-+
-+#ifndef _RADIJ_H_
-+#define _RADIJ_H_
-+
-+/*
-+#define RJ_DEBUG
-+*/
-+
-+#ifdef __KERNEL__
-+
-+#ifndef __P
-+#ifdef __STDC__
-+#define __P(x) x
-+#else
-+#define __P(x) ()
-+#endif
-+#endif
-+
-+/*
-+ * Radix search tree node layout.
-+ */
-+
-+struct radij_node
-+{
-+ struct radij_mask *rj_mklist; /* list of masks contained in subtree */
-+ struct radij_node *rj_p; /* parent */
-+ short rj_b; /* bit offset; -1-index(netmask) */
-+ char rj_bmask; /* node: mask for bit test*/
-+ u_char rj_flags; /* enumerated next */
-+#define RJF_NORMAL 1 /* leaf contains normal route */
-+#define RJF_ROOT 2 /* leaf is root leaf for tree */
-+#define RJF_ACTIVE 4 /* This node is alive (for rtfree) */
-+ union {
-+ struct { /* leaf only data: */
-+ caddr_t rj_Key; /* object of search */
-+ caddr_t rj_Mask; /* netmask, if present */
-+ struct radij_node *rj_Dupedkey;
-+ } rj_leaf;
-+ struct { /* node only data: */
-+ int rj_Off; /* where to start compare */
-+ struct radij_node *rj_L;/* progeny */
-+ struct radij_node *rj_R;/* progeny */
-+ }rj_node;
-+ } rj_u;
-+#ifdef RJ_DEBUG
-+ int rj_info;
-+ struct radij_node *rj_twin;
-+ struct radij_node *rj_ybro;
-+#endif
-+};
-+
-+#define rj_dupedkey rj_u.rj_leaf.rj_Dupedkey
-+#define rj_key rj_u.rj_leaf.rj_Key
-+#define rj_mask rj_u.rj_leaf.rj_Mask
-+#define rj_off rj_u.rj_node.rj_Off
-+#define rj_l rj_u.rj_node.rj_L
-+#define rj_r rj_u.rj_node.rj_R
-+
-+/*
-+ * Annotations to tree concerning potential routes applying to subtrees.
-+ */
-+
-+extern struct radij_mask {
-+ short rm_b; /* bit offset; -1-index(netmask) */
-+ char rm_unused; /* cf. rj_bmask */
-+ u_char rm_flags; /* cf. rj_flags */
-+ struct radij_mask *rm_mklist; /* more masks to try */
-+ caddr_t rm_mask; /* the mask */
-+ int rm_refs; /* # of references to this struct */
-+} *rj_mkfreelist;
-+
-+#define MKGet(m) {\
-+ if (rj_mkfreelist) {\
-+ m = rj_mkfreelist; \
-+ rj_mkfreelist = (m)->rm_mklist; \
-+ } else \
-+ R_Malloc(m, struct radij_mask *, sizeof (*(m))); }\
-+
-+#define MKFree(m) { (m)->rm_mklist = rj_mkfreelist; rj_mkfreelist = (m);}
-+
-+struct radij_node_head {
-+ struct radij_node *rnh_treetop;
-+ int rnh_addrsize; /* permit, but not require fixed keys */
-+ int rnh_pktsize; /* permit, but not require fixed keys */
-+#if 0
-+ struct radij_node *(*rnh_addaddr) /* add based on sockaddr */
-+ __P((void *v, void *mask,
-+ struct radij_node_head *head, struct radij_node nodes[]));
-+#endif
-+ int (*rnh_addaddr) /* add based on sockaddr */
-+ __P((void *v, void *mask,
-+ struct radij_node_head *head, struct radij_node nodes[]));
-+ struct radij_node *(*rnh_addpkt) /* add based on packet hdr */
-+ __P((void *v, void *mask,
-+ struct radij_node_head *head, struct radij_node nodes[]));
-+#if 0
-+ struct radij_node *(*rnh_deladdr) /* remove based on sockaddr */
-+ __P((void *v, void *mask, struct radij_node_head *head));
-+#endif
-+ int (*rnh_deladdr) /* remove based on sockaddr */
-+ __P((void *v, void *mask, struct radij_node_head *head, struct radij_node **node));
-+ struct radij_node *(*rnh_delpkt) /* remove based on packet hdr */
-+ __P((void *v, void *mask, struct radij_node_head *head));
-+ struct radij_node *(*rnh_matchaddr) /* locate based on sockaddr */
-+ __P((void *v, struct radij_node_head *head));
-+ struct radij_node *(*rnh_matchpkt) /* locate based on packet hdr */
-+ __P((void *v, struct radij_node_head *head));
-+ int (*rnh_walktree) /* traverse tree */
-+ __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
-+ struct radij_node rnh_nodes[3]; /* empty tree for common case */
-+};
-+
-+
-+#define Bcmp(a, b, n) memcmp(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
-+#define Bcopy(a, b, n) memmove(((caddr_t)(b)), ((caddr_t)(a)), (unsigned)(n))
-+#define Bzero(p, n) memset((caddr_t)(p), 0, (unsigned)(n))
-+#define R_Malloc(p, t, n) ((p = (t) kmalloc((size_t)(n), GFP_ATOMIC)), Bzero((p),(n)))
-+#define Free(p) kfree((caddr_t)p);
-+
-+void rj_init __P((void));
-+int rj_inithead __P((void **, int));
-+int rj_refines __P((void *, void *));
-+int rj_walktree __P((struct radij_node_head *head, int (*f)(struct radij_node *rn, void *w), void *w));
-+struct radij_node
-+ *rj_addmask __P((void *, int, int)) /* , rgb */ ;
-+int /* * */ rj_addroute __P((void *, void *, struct radij_node_head *,
-+ struct radij_node [2])) /* , rgb */ ;
-+int /* * */ rj_delete __P((void *, void *, struct radij_node_head *, struct radij_node **)) /* , rgb */ ;
-+struct radij_node /* rgb */
-+ *rj_insert __P((void *, struct radij_node_head *, int *,
-+ struct radij_node [2])),
-+ *rj_match __P((void *, struct radij_node_head *)),
-+ *rj_newpair __P((void *, int, struct radij_node[2])),
-+ *rj_search __P((void *, struct radij_node *)),
-+ *rj_search_m __P((void *, struct radij_node *, void *));
-+
-+void rj_deltree(struct radij_node_head *);
-+void rj_delnodes(struct radij_node *);
-+void rj_free_mkfreelist(void);
-+int radijcleartree(void);
-+int radijcleanup(void);
-+
-+extern struct radij_node_head *mask_rjhead;
-+extern int maj_keylen;
-+#endif /* __KERNEL__ */
-+
-+#endif /* _RADIJ_H_ */
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.13 2004/04/05 19:55:08 mcr
-+ * Moved from linux/include/freeswan/radij.h,v
-+ *
-+ * Revision 1.12 2002/04/24 07:36:48 mcr
-+ * Moved from ./klips/net/ipsec/radij.h,v
-+ *
-+ * Revision 1.11 2001/09/20 15:33:00 rgb
-+ * Min/max cleanup.
-+ *
-+ * Revision 1.10 1999/11/18 04:09:20 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ *
-+ * Revision 1.9 1999/05/05 22:02:33 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.8 1999/04/29 15:24:58 rgb
-+ * Add check for existence of macros min/max.
-+ *
-+ * Revision 1.7 1999/04/11 00:29:02 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.6 1999/04/06 04:54:29 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.5 1999/01/22 06:30:32 rgb
-+ * 64-bit clean-up.
-+ *
-+ * Revision 1.4 1998/11/30 13:22:55 rgb
-+ * Rationalised all the klips kernel file headers. They are much shorter
-+ * now and won't conflict under RH5.2.
-+ *
-+ * Revision 1.3 1998/10/25 02:43:27 rgb
-+ * Change return type on rj_addroute and rj_delete and add and argument
-+ * to the latter to be able to transmit more infomation about errors.
-+ *
-+ * Revision 1.2 1998/07/14 18:09:51 rgb
-+ * Add a routine to clear eroute table.
-+ * Added #ifdef __KERNEL__ directives to restrict scope of header.
-+ *
-+ * Revision 1.1 1998/06/18 21:30:22 henry
-+ * move sources from klips/src to klips/net/ipsec to keep stupid kernel
-+ * build scripts happier about symlinks
-+ *
-+ * Revision 1.4 1998/05/25 20:34:16 rgb
-+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
-+ *
-+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
-+ * add ipsec_rj_walker_delete.
-+ *
-+ * Recover memory for eroute table on unload of module.
-+ *
-+ * Revision 1.3 1998/04/22 16:51:37 rgb
-+ * Tidy up radij debug code from recent rash of modifications to debug code.
-+ *
-+ * Revision 1.2 1998/04/14 17:30:38 rgb
-+ * Fix up compiling errors for radij tree memory reclamation.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:16 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * No changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:44:45 ji
-+ * Release update only.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/pfkey.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,509 @@
-+/*
-+ * FreeS/WAN specific PF_KEY headers
-+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifndef __NET_IPSEC_PF_KEY_H
-+#define __NET_IPSEC_PF_KEY_H
-+#ifdef __KERNEL__
-+extern struct proto_ops pfkey_proto_ops;
-+typedef struct sock pfkey_sock;
-+extern int debug_pfkey;
-+
-+extern /* void */ int pfkey_init(void);
-+extern /* void */ int pfkey_cleanup(void);
-+
-+extern struct sock *pfkey_sock_list;
-+struct socket_list
-+{
-+ struct socket *socketp;
-+ struct socket_list *next;
-+};
-+extern int pfkey_list_insert_socket(struct socket*, struct socket_list**);
-+extern int pfkey_list_remove_socket(struct socket*, struct socket_list**);
-+extern struct socket_list *pfkey_open_sockets;
-+extern struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
-+
-+struct supported
-+{
-+ uint16_t supported_alg_exttype;
-+ uint8_t supported_alg_id;
-+ uint8_t supported_alg_ivlen;
-+ uint16_t supported_alg_minbits;
-+ uint16_t supported_alg_maxbits;
-+};
-+
-+extern struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
-+struct supported_list
-+{
-+ struct supported *supportedp;
-+ struct supported_list *next;
-+};
-+extern int pfkey_list_insert_supported(struct supported*, struct supported_list**);
-+extern int pfkey_list_remove_supported(struct supported*, struct supported_list**);
-+
-+struct sockaddr_key
-+{
-+ uint16_t key_family; /* PF_KEY */
-+ uint16_t key_pad; /* not used */
-+ uint32_t key_pid; /* process ID */
-+};
-+
-+struct pfkey_extracted_data
-+{
-+ struct ipsec_sa* ips;
-+ struct ipsec_sa* ips2;
-+ struct eroute *eroute;
-+};
-+
-+extern int
-+pfkey_alloc_eroute(struct eroute** eroute);
-+
-+extern int
-+pfkey_sa_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_lifetime_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_address_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_key_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_ident_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_sens_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_prop_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_supported_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_spirange_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_x_satype_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int
-+pfkey_x_debug_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data* extr);
-+
-+extern int pfkey_upmsg(struct socket *, struct sadb_msg *);
-+extern int pfkey_expire(struct ipsec_sa *, int);
-+extern int pfkey_acquire(struct ipsec_sa *);
-+#else /* ! __KERNEL__ */
-+
-+extern void (*pfkey_debug_func)(const char *message, ...);
-+extern void (*pfkey_error_func)(const char *message, ...);
-+extern void pfkey_print(struct sadb_msg *msg, FILE *out);
-+
-+
-+#endif /* __KERNEL__ */
-+
-+extern uint8_t satype2proto(uint8_t satype);
-+extern uint8_t proto2satype(uint8_t proto);
-+extern char* satype2name(uint8_t satype);
-+extern char* proto2name(uint8_t proto);
-+
-+struct key_opt
-+{
-+ uint32_t key_pid; /* process ID */
-+ struct sock *sk;
-+};
-+
-+#define key_pid(sk) ((struct key_opt*)&((sk)->protinfo))->key_pid
-+
-+/* XXX-mcr this is not an alignment, this is because the count is in 64-bit
-+ * words.
-+ */
-+#define IPSEC_PFKEYv2_ALIGN (sizeof(uint64_t)/sizeof(uint8_t))
-+#define BITS_PER_OCTET 8
-+#define OCTETBITS 8
-+#define PFKEYBITS 64
-+#define DIVUP(x,y) ((x + y -1) / y) /* divide, rounding upwards */
-+#define ALIGN_N(x,y) (DIVUP(x,y) * y) /* align on y boundary */
-+
-+#define IPSEC_PFKEYv2_LEN(x) ((x) * IPSEC_PFKEYv2_ALIGN)
-+#define IPSEC_PFKEYv2_WORDS(x) ((x) / IPSEC_PFKEYv2_ALIGN)
-+
-+
-+#define PFKEYv2_MAX_MSGSIZE 4096
-+
-+/*
-+ * PF_KEYv2 permitted and required extensions in and out bitmaps
-+ */
-+struct pf_key_ext_parsers_def {
-+ int (*parser)(struct sadb_ext*);
-+ char *parser_name;
-+};
-+
-+
-+extern unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/];
-+#define EXT_BITS_IN 0
-+#define EXT_BITS_OUT 1
-+#define EXT_BITS_PERM 0
-+#define EXT_BITS_REQ 1
-+
-+extern void pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1]);
-+extern void pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1]);
-+extern void pfkey_msg_free(struct sadb_msg **pfkey_msg);
-+
-+extern int pfkey_msg_parse(struct sadb_msg *pfkey_msg,
-+ struct pf_key_ext_parsers_def *ext_parsers[],
-+ struct sadb_ext **extensions,
-+ int dir);
-+
-+extern int pfkey_register_reply(int satype, struct sadb_msg *sadb_msg);
-+
-+/*
-+ * PF_KEYv2 build function prototypes
-+ */
-+
-+int
-+pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
-+ uint8_t msg_type,
-+ uint8_t satype,
-+ uint8_t msg_errno,
-+ uint32_t seq,
-+ uint32_t pid);
-+
-+int
-+pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext,
-+ uint16_t exttype,
-+ uint32_t spi, /* in network order */
-+ uint8_t replay_window,
-+ uint8_t sa_state,
-+ uint8_t auth,
-+ uint8_t encrypt,
-+ uint32_t flags,
-+ uint32_t/*IPsecSAref_t*/ ref);
-+
-+int
-+pfkey_sa_build(struct sadb_ext ** pfkey_ext,
-+ uint16_t exttype,
-+ uint32_t spi, /* in network order */
-+ uint8_t replay_window,
-+ uint8_t sa_state,
-+ uint8_t auth,
-+ uint8_t encrypt,
-+ uint32_t flags);
-+
-+int
-+pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
-+ uint16_t exttype,
-+ uint32_t allocations,
-+ uint64_t bytes,
-+ uint64_t addtime,
-+ uint64_t usetime,
-+ uint32_t packets);
-+
-+int
-+pfkey_address_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint8_t proto,
-+ uint8_t prefixlen,
-+ struct sockaddr* address);
-+
-+int
-+pfkey_key_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint16_t key_bits,
-+ char* key);
-+
-+int
-+pfkey_ident_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint16_t ident_type,
-+ uint64_t ident_id,
-+ uint8_t ident_len,
-+ char* ident_string);
-+
-+#ifdef NAT_TRAVERSAL
-+#ifdef __KERNEL__
-+extern int pfkey_nat_t_new_mapping(struct ipsec_sa *, struct sockaddr *, __u16);
-+extern int pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
-+extern int pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr);
-+#endif /* __KERNEL__ */
-+int
-+pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
-+ uint8_t type);
-+int
-+pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint16_t port);
-+#endif
-+
-+int
-+pfkey_sens_build(struct sadb_ext** pfkey_ext,
-+ uint32_t dpd,
-+ uint8_t sens_level,
-+ uint8_t sens_len,
-+ uint64_t* sens_bitmap,
-+ uint8_t integ_level,
-+ uint8_t integ_len,
-+ uint64_t* integ_bitmap);
-+
-+int pfkey_x_protocol_build(struct sadb_ext **, uint8_t);
-+
-+
-+int
-+pfkey_prop_build(struct sadb_ext** pfkey_ext,
-+ uint8_t replay,
-+ unsigned int comb_num,
-+ struct sadb_comb* comb);
-+
-+int
-+pfkey_supported_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ unsigned int alg_num,
-+ struct sadb_alg* alg);
-+
-+int
-+pfkey_spirange_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint32_t min,
-+ uint32_t max);
-+
-+int
-+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext);
-+
-+int
-+pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
-+ uint8_t satype);
-+
-+int
-+pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
-+ uint32_t tunnel,
-+ uint32_t netlink,
-+ uint32_t xform,
-+ uint32_t eroute,
-+ uint32_t spi,
-+ uint32_t radij,
-+ uint32_t esp,
-+ uint32_t ah,
-+ uint32_t rcv,
-+ uint32_t pfkey,
-+ uint32_t ipcomp,
-+ uint32_t verbose);
-+
-+int
-+pfkey_msg_build(struct sadb_msg** pfkey_msg,
-+ struct sadb_ext* extensions[],
-+ int dir);
-+
-+/* in pfkey_v2_debug.c - routines to decode numbers -> strings */
-+const char *
-+pfkey_v2_sadb_ext_string(int extnum);
-+
-+const char *
-+pfkey_v2_sadb_type_string(int sadb_type);
-+
-+
-+#endif /* __NET_IPSEC_PF_KEY_H */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.45 2004/04/06 02:49:00 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.44 2003/12/10 01:20:01 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.43 2003/10/31 02:26:44 mcr
-+ * pulled up port-selector patches.
-+ *
-+ * Revision 1.42.2.2 2003/10/29 01:09:32 mcr
-+ * added debugging for pfkey library.
-+ *
-+ * Revision 1.42.2.1 2003/09/21 13:59:34 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.42 2003/08/25 22:08:19 mcr
-+ * removed pfkey_proto_init() from pfkey.h for 2.6 support.
-+ *
-+ * Revision 1.41 2003/05/07 17:28:57 mcr
-+ * new function pfkey_debug_func added for us in debugging from
-+
-+ * pfkey library.
-+ *
-+ * Revision 1.40 2003/01/30 02:31:34 rgb
-+ *
-+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
-+ *
-+ * Revision 1.39 2002/09/20 15:40:21 rgb
-+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
-+ * Added ref parameter to pfkey_sa_build().
-+ * Cleaned out unused cruft.
-+ *
-+ * Revision 1.38 2002/05/14 02:37:24 rgb
-+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
-+ * ipsec_sa or ipsec_sa.
-+ * Added function prototypes for the functions moved to
-+ * pfkey_v2_ext_process.c.
-+ *
-+ * Revision 1.37 2002/04/24 07:36:49 mcr
-+ * Moved from ./lib/pfkey.h,v
-+ *
-+ * Revision 1.36 2002/01/20 20:34:49 mcr
-+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
-+ *
-+ * Revision 1.35 2001/11/27 05:27:47 mcr
-+ * pfkey parses are now maintained by a structure
-+ * that includes their name for debug purposes.
-+ *
-+ * Revision 1.34 2001/11/26 09:23:53 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.33 2001/11/06 19:47:47 rgb
-+ * Added packet parameter to lifetime and comb structures.
-+ *
-+ * Revision 1.32 2001/09/08 21:13:34 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.31 2001/06/14 19:35:16 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.30 2001/02/27 07:04:52 rgb
-+ * Added satype2name prototype.
-+ *
-+ * Revision 1.29 2001/02/26 19:59:33 rgb
-+ * Ditch unused sadb_satype2proto[], replaced by satype2proto().
-+ *
-+ * Revision 1.28 2000/10/10 20:10:19 rgb
-+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
-+ *
-+ * Revision 1.27 2000/09/21 04:20:45 rgb
-+ * Fixed array size off-by-one error. (Thanks Svenning!)
-+ *
-+ * Revision 1.26 2000/09/12 03:26:05 rgb
-+ * Added pfkey_acquire prototype.
-+ *
-+ * Revision 1.25 2000/09/08 19:21:28 rgb
-+ * Fix pfkey_prop_build() parameter to be only single indirection.
-+ *
-+ * Revision 1.24 2000/09/01 18:46:42 rgb
-+ * Added a supported algorithms array lists, one per satype and registered
-+ * existing algorithms.
-+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
-+ * list.
-+ *
-+ * Revision 1.23 2000/08/27 01:55:26 rgb
-+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
-+ *
-+ * Revision 1.22 2000/08/20 21:39:23 rgb
-+ * Added kernel prototypes for kernel funcitions pfkey_upmsg() and
-+ * pfkey_expire().
-+ *
-+ * Revision 1.21 2000/08/15 17:29:23 rgb
-+ * Fixes from SZI to untested pfkey_prop_build().
-+ *
-+ * Revision 1.20 2000/05/10 20:14:19 rgb
-+ * Fleshed out sensitivity, proposal and supported extensions.
-+ *
-+ * Revision 1.19 2000/03/16 14:07:23 rgb
-+ * Renamed ALIGN macro to avoid fighting with others in kernel.
-+ *
-+ * Revision 1.18 2000/01/22 23:24:06 rgb
-+ * Added prototypes for proto2satype(), satype2proto() and proto2name().
-+ *
-+ * Revision 1.17 2000/01/21 06:26:59 rgb
-+ * Converted from double tdb arguments to one structure (extr)
-+ * containing pointers to all temporary information structures.
-+ * Added klipsdebug switching capability.
-+ * Dropped unused argument to pfkey_x_satype_build().
-+ *
-+ * Revision 1.16 1999/12/29 21:17:41 rgb
-+ * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
-+ * parameter for cleaner manipulation of extensions[] and to guard
-+ * against potential memory leaks.
-+ * Changed the I/F to pfkey_msg_free() for the same reason.
-+ *
-+ * Revision 1.15 1999/12/09 23:12:54 rgb
-+ * Added macro for BITS_PER_OCTET.
-+ * Added argument to pfkey_sa_build() to do eroutes.
-+ *
-+ * Revision 1.14 1999/12/08 20:33:25 rgb
-+ * Changed sa_family_t to uint16_t for 2.0.xx compatibility.
-+ *
-+ * Revision 1.13 1999/12/07 19:53:40 rgb
-+ * Removed unused first argument from extension parsers.
-+ * Changed __u* types to uint* to avoid use of asm/types.h and
-+ * sys/types.h in userspace code.
-+ * Added function prototypes for pfkey message and extensions
-+ * initialisation and cleanup.
-+ *
-+ * Revision 1.12 1999/12/01 22:19:38 rgb
-+ * Change pfkey_sa_build to accept an SPI in network byte order.
-+ *
-+ * Revision 1.11 1999/11/27 11:55:26 rgb
-+ * Added extern sadb_satype2proto to enable moving protocol lookup table
-+ * to lib/pfkey_v2_parse.c.
-+ * Delete unused, moved typedefs.
-+ * Add argument to pfkey_msg_parse() for direction.
-+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
-+ *
-+ * Revision 1.10 1999/11/23 22:29:21 rgb
-+ * This file has been moved in the distribution from klips/net/ipsec to
-+ * lib.
-+ * Add macros for dealing with alignment and rounding up more opaquely.
-+ * The uint<n>_t type defines have been moved to freeswan.h to avoid
-+ * chicken-and-egg problems.
-+ * Add macros for dealing with alignment and rounding up more opaque.
-+ * Added prototypes for using extention header bitmaps.
-+ * Added prototypes of all the build functions.
-+ *
-+ * Revision 1.9 1999/11/20 21:59:48 rgb
-+ * Moved socketlist type declarations and prototypes for shared use.
-+ * Slightly modified scope of sockaddr_key declaration.
-+ *
-+ * Revision 1.8 1999/11/17 14:34:25 rgb
-+ * Protect sa_family_t from being used in userspace with GLIBC<2.
-+ *
-+ * Revision 1.7 1999/10/27 19:40:35 rgb
-+ * Add a maximum PFKEY packet size macro.
-+ *
-+ * Revision 1.6 1999/10/26 16:58:58 rgb
-+ * Created a sockaddr_key and key_opt socket extension structures.
-+ *
-+ * Revision 1.5 1999/06/10 05:24:41 rgb
-+ * Renamed variables to reduce confusion.
-+ *
-+ * Revision 1.4 1999/04/29 15:21:11 rgb
-+ * Add pfkey support to debugging.
-+ * Add return values to init and cleanup functions.
-+ *
-+ * Revision 1.3 1999/04/15 17:58:07 rgb
-+ * Add RCSID labels.
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/pfkeyv2.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,467 @@
-+/*
-+ * RCSID $Id$
-+ */
-+
-+/*
-+RFC 2367 PF_KEY Key Management API July 1998
-+
-+
-+Appendix D: Sample Header File
-+
-+This file defines structures and symbols for the PF_KEY Version 2
-+key management interface. It was written at the U.S. Naval Research
-+Laboratory. This file is in the public domain. The authors ask that
-+you leave this credit intact on any copies of this file.
-+*/
-+#ifndef __PFKEY_V2_H
-+#define __PFKEY_V2_H 1
-+
-+#define PF_KEY_V2 2
-+#define PFKEYV2_REVISION 199806L
-+
-+#define SADB_RESERVED 0
-+#define SADB_GETSPI 1
-+#define SADB_UPDATE 2
-+#define SADB_ADD 3
-+#define SADB_DELETE 4
-+#define SADB_GET 5
-+#define SADB_ACQUIRE 6
-+#define SADB_REGISTER 7
-+#define SADB_EXPIRE 8
-+#define SADB_FLUSH 9
-+#define SADB_DUMP 10
-+#define SADB_X_PROMISC 11
-+#define SADB_X_PCHANGE 12
-+#define SADB_X_GRPSA 13
-+#define SADB_X_ADDFLOW 14
-+#define SADB_X_DELFLOW 15
-+#define SADB_X_DEBUG 16
-+#define SADB_X_NAT_T_NEW_MAPPING 17
-+#define SADB_MAX 17
-+
-+struct sadb_msg {
-+ uint8_t sadb_msg_version;
-+ uint8_t sadb_msg_type;
-+ uint8_t sadb_msg_errno;
-+ uint8_t sadb_msg_satype;
-+ uint16_t sadb_msg_len;
-+ uint16_t sadb_msg_reserved;
-+ uint32_t sadb_msg_seq;
-+ uint32_t sadb_msg_pid;
-+};
-+
-+struct sadb_ext {
-+ uint16_t sadb_ext_len;
-+ uint16_t sadb_ext_type;
-+};
-+
-+struct sadb_sa {
-+ uint16_t sadb_sa_len;
-+ uint16_t sadb_sa_exttype;
-+ uint32_t sadb_sa_spi;
-+ uint8_t sadb_sa_replay;
-+ uint8_t sadb_sa_state;
-+ uint8_t sadb_sa_auth;
-+ uint8_t sadb_sa_encrypt;
-+ uint32_t sadb_sa_flags;
-+ uint32_t /*IPsecSAref_t*/ sadb_x_sa_ref; /* 32 bits */
-+ uint8_t sadb_x_reserved[4];
-+};
-+
-+struct sadb_sa_v1 {
-+ uint16_t sadb_sa_len;
-+ uint16_t sadb_sa_exttype;
-+ uint32_t sadb_sa_spi;
-+ uint8_t sadb_sa_replay;
-+ uint8_t sadb_sa_state;
-+ uint8_t sadb_sa_auth;
-+ uint8_t sadb_sa_encrypt;
-+ uint32_t sadb_sa_flags;
-+};
-+
-+struct sadb_lifetime {
-+ uint16_t sadb_lifetime_len;
-+ uint16_t sadb_lifetime_exttype;
-+ uint32_t sadb_lifetime_allocations;
-+ uint64_t sadb_lifetime_bytes;
-+ uint64_t sadb_lifetime_addtime;
-+ uint64_t sadb_lifetime_usetime;
-+ uint32_t sadb_x_lifetime_packets;
-+ uint32_t sadb_x_lifetime_reserved;
-+};
-+
-+struct sadb_address {
-+ uint16_t sadb_address_len;
-+ uint16_t sadb_address_exttype;
-+ uint8_t sadb_address_proto;
-+ uint8_t sadb_address_prefixlen;
-+ uint16_t sadb_address_reserved;
-+};
-+
-+struct sadb_key {
-+ uint16_t sadb_key_len;
-+ uint16_t sadb_key_exttype;
-+ uint16_t sadb_key_bits;
-+ uint16_t sadb_key_reserved;
-+};
-+
-+struct sadb_ident {
-+ uint16_t sadb_ident_len;
-+ uint16_t sadb_ident_exttype;
-+ uint16_t sadb_ident_type;
-+ uint16_t sadb_ident_reserved;
-+ uint64_t sadb_ident_id;
-+};
-+
-+struct sadb_sens {
-+ uint16_t sadb_sens_len;
-+ uint16_t sadb_sens_exttype;
-+ uint32_t sadb_sens_dpd;
-+ uint8_t sadb_sens_sens_level;
-+ uint8_t sadb_sens_sens_len;
-+ uint8_t sadb_sens_integ_level;
-+ uint8_t sadb_sens_integ_len;
-+ uint32_t sadb_sens_reserved;
-+};
-+
-+struct sadb_prop {
-+ uint16_t sadb_prop_len;
-+ uint16_t sadb_prop_exttype;
-+ uint8_t sadb_prop_replay;
-+ uint8_t sadb_prop_reserved[3];
-+};
-+
-+struct sadb_comb {
-+ uint8_t sadb_comb_auth;
-+ uint8_t sadb_comb_encrypt;
-+ uint16_t sadb_comb_flags;
-+ uint16_t sadb_comb_auth_minbits;
-+ uint16_t sadb_comb_auth_maxbits;
-+ uint16_t sadb_comb_encrypt_minbits;
-+ uint16_t sadb_comb_encrypt_maxbits;
-+ uint32_t sadb_comb_reserved;
-+ uint32_t sadb_comb_soft_allocations;
-+ uint32_t sadb_comb_hard_allocations;
-+ uint64_t sadb_comb_soft_bytes;
-+ uint64_t sadb_comb_hard_bytes;
-+ uint64_t sadb_comb_soft_addtime;
-+ uint64_t sadb_comb_hard_addtime;
-+ uint64_t sadb_comb_soft_usetime;
-+ uint64_t sadb_comb_hard_usetime;
-+ uint32_t sadb_x_comb_soft_packets;
-+ uint32_t sadb_x_comb_hard_packets;
-+};
-+
-+struct sadb_supported {
-+ uint16_t sadb_supported_len;
-+ uint16_t sadb_supported_exttype;
-+ uint32_t sadb_supported_reserved;
-+};
-+
-+struct sadb_alg {
-+ uint8_t sadb_alg_id;
-+ uint8_t sadb_alg_ivlen;
-+ uint16_t sadb_alg_minbits;
-+ uint16_t sadb_alg_maxbits;
-+ uint16_t sadb_alg_reserved;
-+};
-+
-+struct sadb_spirange {
-+ uint16_t sadb_spirange_len;
-+ uint16_t sadb_spirange_exttype;
-+ uint32_t sadb_spirange_min;
-+ uint32_t sadb_spirange_max;
-+ uint32_t sadb_spirange_reserved;
-+};
-+
-+struct sadb_x_kmprivate {
-+ uint16_t sadb_x_kmprivate_len;
-+ uint16_t sadb_x_kmprivate_exttype;
-+ uint32_t sadb_x_kmprivate_reserved;
-+};
-+
-+struct sadb_x_satype {
-+ uint16_t sadb_x_satype_len;
-+ uint16_t sadb_x_satype_exttype;
-+ uint8_t sadb_x_satype_satype;
-+ uint8_t sadb_x_satype_reserved[3];
-+};
-+
-+struct sadb_x_policy {
-+ uint16_t sadb_x_policy_len;
-+ uint16_t sadb_x_policy_exttype;
-+ uint16_t sadb_x_policy_type;
-+ uint8_t sadb_x_policy_dir;
-+ uint8_t sadb_x_policy_reserved;
-+ uint32_t sadb_x_policy_id;
-+ uint32_t sadb_x_policy_reserved2;
-+};
-+
-+struct sadb_x_debug {
-+ uint16_t sadb_x_debug_len;
-+ uint16_t sadb_x_debug_exttype;
-+ uint32_t sadb_x_debug_tunnel;
-+ uint32_t sadb_x_debug_netlink;
-+ uint32_t sadb_x_debug_xform;
-+ uint32_t sadb_x_debug_eroute;
-+ uint32_t sadb_x_debug_spi;
-+ uint32_t sadb_x_debug_radij;
-+ uint32_t sadb_x_debug_esp;
-+ uint32_t sadb_x_debug_ah;
-+ uint32_t sadb_x_debug_rcv;
-+ uint32_t sadb_x_debug_pfkey;
-+ uint32_t sadb_x_debug_ipcomp;
-+ uint32_t sadb_x_debug_verbose;
-+ uint8_t sadb_x_debug_reserved[4];
-+};
-+
-+struct sadb_x_nat_t_type {
-+ uint16_t sadb_x_nat_t_type_len;
-+ uint16_t sadb_x_nat_t_type_exttype;
-+ uint8_t sadb_x_nat_t_type_type;
-+ uint8_t sadb_x_nat_t_type_reserved[3];
-+};
-+struct sadb_x_nat_t_port {
-+ uint16_t sadb_x_nat_t_port_len;
-+ uint16_t sadb_x_nat_t_port_exttype;
-+ uint16_t sadb_x_nat_t_port_port;
-+ uint16_t sadb_x_nat_t_port_reserved;
-+};
-+
-+/*
-+ * A protocol structure for passing through the transport level
-+ * protocol. It contains more fields than are actually used/needed
-+ * but it is this way to be compatible with the structure used in
-+ * OpenBSD (http://www.openbsd.org/cgi-bin/cvsweb/src/sys/net/pfkeyv2.h)
-+ */
-+struct sadb_protocol {
-+ uint16_t sadb_protocol_len;
-+ uint16_t sadb_protocol_exttype;
-+ uint8_t sadb_protocol_proto;
-+ uint8_t sadb_protocol_direction;
-+ uint8_t sadb_protocol_flags;
-+ uint8_t sadb_protocol_reserved2;
-+};
-+
-+#define SADB_EXT_RESERVED 0
-+#define SADB_EXT_SA 1
-+#define SADB_EXT_LIFETIME_CURRENT 2
-+#define SADB_EXT_LIFETIME_HARD 3
-+#define SADB_EXT_LIFETIME_SOFT 4
-+#define SADB_EXT_ADDRESS_SRC 5
-+#define SADB_EXT_ADDRESS_DST 6
-+#define SADB_EXT_ADDRESS_PROXY 7
-+#define SADB_EXT_KEY_AUTH 8
-+#define SADB_EXT_KEY_ENCRYPT 9
-+#define SADB_EXT_IDENTITY_SRC 10
-+#define SADB_EXT_IDENTITY_DST 11
-+#define SADB_EXT_SENSITIVITY 12
-+#define SADB_EXT_PROPOSAL 13
-+#define SADB_EXT_SUPPORTED_AUTH 14
-+#define SADB_EXT_SUPPORTED_ENCRYPT 15
-+#define SADB_EXT_SPIRANGE 16
-+#define SADB_X_EXT_KMPRIVATE 17
-+#define SADB_X_EXT_SATYPE2 18
-+#ifdef KERNEL26_HAS_KAME_DUPLICATES
-+#define SADB_X_EXT_POLICY 18
-+#endif
-+#define SADB_X_EXT_SA2 19
-+#define SADB_X_EXT_ADDRESS_DST2 20
-+#define SADB_X_EXT_ADDRESS_SRC_FLOW 21
-+#define SADB_X_EXT_ADDRESS_DST_FLOW 22
-+#define SADB_X_EXT_ADDRESS_SRC_MASK 23
-+#define SADB_X_EXT_ADDRESS_DST_MASK 24
-+#define SADB_X_EXT_DEBUG 25
-+#define SADB_X_EXT_PROTOCOL 26
-+#define SADB_X_EXT_NAT_T_TYPE 27
-+#define SADB_X_EXT_NAT_T_SPORT 28
-+#define SADB_X_EXT_NAT_T_DPORT 29
-+#define SADB_X_EXT_NAT_T_OA 30
-+#define SADB_EXT_MAX 30
-+
-+/* SADB_X_DELFLOW required over and above SADB_X_SAFLAGS_CLEARFLOW */
-+#define SADB_X_EXT_ADDRESS_DELFLOW \
-+ ( (1<<SADB_X_EXT_ADDRESS_SRC_FLOW) \
-+ | (1<<SADB_X_EXT_ADDRESS_DST_FLOW) \
-+ | (1<<SADB_X_EXT_ADDRESS_SRC_MASK) \
-+ | (1<<SADB_X_EXT_ADDRESS_DST_MASK))
-+
-+#define SADB_SATYPE_UNSPEC 0
-+#define SADB_SATYPE_AH 2
-+#define SADB_SATYPE_ESP 3
-+#define SADB_SATYPE_RSVP 5
-+#define SADB_SATYPE_OSPFV2 6
-+#define SADB_SATYPE_RIPV2 7
-+#define SADB_SATYPE_MIP 8
-+#define SADB_X_SATYPE_IPIP 9
-+#ifdef KERNEL26_HAS_KAME_DUPLICATES
-+#define SADB_X_SATYPE_IPCOMP 9 /* ICK! */
-+#endif
-+#define SADB_X_SATYPE_COMP 10
-+#define SADB_X_SATYPE_INT 11
-+#define SADB_SATYPE_MAX 11
-+
-+#define SADB_SASTATE_LARVAL 0
-+#define SADB_SASTATE_MATURE 1
-+#define SADB_SASTATE_DYING 2
-+#define SADB_SASTATE_DEAD 3
-+#define SADB_SASTATE_MAX 3
-+
-+#define SADB_SAFLAGS_PFS 1
-+#define SADB_X_SAFLAGS_REPLACEFLOW 2
-+#define SADB_X_SAFLAGS_CLEARFLOW 4
-+#define SADB_X_SAFLAGS_INFLOW 8
-+
-+/* not obvious, but these are the same values as used in isakmp,
-+ * and in freeswan/ipsec_policy.h. If you need to add any, they
-+ * should be added as according to
-+ * http://www.iana.org/assignments/isakmp-registry
-+ *
-+ * and if not, then please try to use a private-use value, and
-+ * consider asking IANA to assign a value.
-+ */
-+#define SADB_AALG_NONE 0
-+#define SADB_AALG_MD5HMAC 2
-+#define SADB_AALG_SHA1HMAC 3
-+#define SADB_X_AALG_SHA2_256HMAC 5
-+#define SADB_X_AALG_SHA2_384HMAC 6
-+#define SADB_X_AALG_SHA2_512HMAC 7
-+#define SADB_X_AALG_RIPEMD160HMAC 8
-+#define SADB_X_AALG_NULL 251 /* kame */
-+#define SADB_AALG_MAX 251
-+
-+#define SADB_EALG_NONE 0
-+#define SADB_EALG_DESCBC 2
-+#define SADB_EALG_3DESCBC 3
-+#define SADB_X_EALG_CASTCBC 6
-+#define SADB_X_EALG_BLOWFISHCBC 7
-+#define SADB_EALG_NULL 11
-+#define SADB_X_EALG_AESCBC 12
-+#define SADB_EALG_MAX 255
-+
-+#define SADB_X_CALG_NONE 0
-+#define SADB_X_CALG_OUI 1
-+#define SADB_X_CALG_DEFLATE 2
-+#define SADB_X_CALG_LZS 3
-+#define SADB_X_CALG_V42BIS 4
-+#ifdef KERNEL26_HAS_KAME_DUPLICATES
-+#define SADB_X_CALG_LZJH 4
-+#endif
-+#define SADB_X_CALG_MAX 4
-+
-+#define SADB_X_TALG_NONE 0
-+#define SADB_X_TALG_IPv4_in_IPv4 1
-+#define SADB_X_TALG_IPv6_in_IPv4 2
-+#define SADB_X_TALG_IPv4_in_IPv6 3
-+#define SADB_X_TALG_IPv6_in_IPv6 4
-+#define SADB_X_TALG_MAX 4
-+
-+
-+#define SADB_IDENTTYPE_RESERVED 0
-+#define SADB_IDENTTYPE_PREFIX 1
-+#define SADB_IDENTTYPE_FQDN 2
-+#define SADB_IDENTTYPE_USERFQDN 3
-+#define SADB_X_IDENTTYPE_CONNECTION 4
-+#define SADB_IDENTTYPE_MAX 4
-+
-+#define SADB_KEY_FLAGS_MAX 0
-+#endif /* __PFKEY_V2_H */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.30 2004/04/06 02:49:00 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.29 2003/12/22 21:35:58 mcr
-+ * new patches from Dr{Who}.
-+ *
-+ * Revision 1.28 2003/12/22 19:33:15 mcr
-+ * added 0.6c NAT-T patch.
-+ *
-+ * Revision 1.27 2003/12/10 01:20:01 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.26 2003/10/31 02:26:44 mcr
-+ * pulled up port-selector patches.
-+ *
-+ * Revision 1.25.4.1 2003/09/21 13:59:34 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.25 2003/07/31 23:59:17 mcr
-+ * re-introduce kernel 2.6 duplicate values for now.
-+ * hope to get them changed!
-+ *
-+ * Revision 1.24 2003/07/31 22:55:27 mcr
-+ * added some definitions to keep pfkeyv2.h files in sync.
-+ *
-+ * Revision 1.23 2003/05/11 00:43:48 mcr
-+ * added comment about origin of values used
-+ *
-+ * Revision 1.22 2003/01/30 02:31:34 rgb
-+ *
-+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
-+ *
-+ * Revision 1.21 2002/12/16 19:26:49 mcr
-+ * added definition of FS 1.xx sadb structure
-+ *
-+ * Revision 1.20 2002/09/20 15:40:25 rgb
-+ * Added sadb_x_sa_ref to struct sadb_sa.
-+ *
-+ * Revision 1.19 2002/04/24 07:36:49 mcr
-+ * Moved from ./lib/pfkeyv2.h,v
-+ *
-+ * Revision 1.18 2001/11/06 19:47:47 rgb
-+ * Added packet parameter to lifetime and comb structures.
-+ *
-+ * Revision 1.17 2001/09/08 21:13:35 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.16 2001/07/06 19:49:46 rgb
-+ * Added SADB_X_SAFLAGS_INFLOW for supporting incoming policy checks.
-+ *
-+ * Revision 1.15 2001/02/26 20:00:43 rgb
-+ * Added internal IP protocol 61 for magic SAs.
-+ *
-+ * Revision 1.14 2001/02/08 18:51:05 rgb
-+ * Include RFC document title and appendix subsection title.
-+ *
-+ * Revision 1.13 2000/10/10 20:10:20 rgb
-+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
-+ *
-+ * Revision 1.12 2000/09/15 06:41:50 rgb
-+ * Added V42BIS constant.
-+ *
-+ * Revision 1.11 2000/09/12 22:35:37 rgb
-+ * Restructured to remove unused extensions from CLEARFLOW messages.
-+ *
-+ * Revision 1.10 2000/09/12 18:50:09 rgb
-+ * Added IPIP tunnel types as algo support.
-+ *
-+ * Revision 1.9 2000/08/21 16:47:19 rgb
-+ * Added SADB_X_CALG_* macros for IPCOMP.
-+ *
-+ * Revision 1.8 2000/08/09 20:43:34 rgb
-+ * Fixed bitmask value for SADB_X_SAFLAGS_CLEAREROUTE.
-+ *
-+ * Revision 1.7 2000/01/21 06:28:37 rgb
-+ * Added flow add/delete message type macros.
-+ * Added flow address extension type macros.
-+ * Tidied up spacing.
-+ * Added klipsdebug switching capability.
-+ *
-+ * Revision 1.6 1999/11/27 11:56:08 rgb
-+ * Add SADB_X_SATYPE_COMP for compression, eventually.
-+ *
-+ * Revision 1.5 1999/11/23 22:23:16 rgb
-+ * This file has been moved in the distribution from klips/net/ipsec to
-+ * lib.
-+ *
-+ * Revision 1.4 1999/04/29 15:23:29 rgb
-+ * Add GRPSA support.
-+ * Add support for a second SATYPE, SA and DST_ADDRESS.
-+ * Add IPPROTO_IPIP support.
-+ *
-+ * Revision 1.3 1999/04/15 17:58:08 rgb
-+ * Add RCSID labels.
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/zlib/zlib.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,893 @@
-+/* zlib.h -- interface of the 'zlib' general purpose compression library
-+ version 1.1.4, March 11th, 2002
-+
-+ Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
-+
-+ This software is provided 'as-is', without any express or implied
-+ warranty. In no event will the authors be held liable for any damages
-+ arising from the use of this software.
-+
-+ Permission is granted to anyone to use this software for any purpose,
-+ including commercial applications, and to alter it and redistribute it
-+ freely, subject to the following restrictions:
-+
-+ 1. The origin of this software must not be misrepresented; you must not
-+ claim that you wrote the original software. If you use this software
-+ in a product, an acknowledgment in the product documentation would be
-+ appreciated but is not required.
-+ 2. Altered source versions must be plainly marked as such, and must not be
-+ misrepresented as being the original software.
-+ 3. This notice may not be removed or altered from any source distribution.
-+
-+ Jean-loup Gailly Mark Adler
-+ jloup@gzip.org madler@alumni.caltech.edu
-+
-+
-+ The data format used by the zlib library is described by RFCs (Request for
-+ Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
-+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
-+*/
-+
-+#ifndef _ZLIB_H
-+#define _ZLIB_H
-+
-+#include "zconf.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#define ZLIB_VERSION "1.1.4"
-+
-+/*
-+ The 'zlib' compression library provides in-memory compression and
-+ decompression functions, including integrity checks of the uncompressed
-+ data. This version of the library supports only one compression method
-+ (deflation) but other algorithms will be added later and will have the same
-+ stream interface.
-+
-+ Compression can be done in a single step if the buffers are large
-+ enough (for example if an input file is mmap'ed), or can be done by
-+ repeated calls of the compression function. In the latter case, the
-+ application must provide more input and/or consume the output
-+ (providing more output space) before each call.
-+
-+ The library also supports reading and writing files in gzip (.gz) format
-+ with an interface similar to that of stdio.
-+
-+ The library does not install any signal handler. The decoder checks
-+ the consistency of the compressed data, so the library should never
-+ crash even in case of corrupted input.
-+*/
-+
-+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
-+typedef void (*free_func) OF((voidpf opaque, voidpf address));
-+
-+struct internal_state;
-+
-+typedef struct z_stream_s {
-+ Bytef *next_in; /* next input byte */
-+ uInt avail_in; /* number of bytes available at next_in */
-+ uLong total_in; /* total nb of input bytes read so far */
-+
-+ Bytef *next_out; /* next output byte should be put there */
-+ uInt avail_out; /* remaining free space at next_out */
-+ uLong total_out; /* total nb of bytes output so far */
-+
-+ const char *msg; /* last error message, NULL if no error */
-+ struct internal_state FAR *state; /* not visible by applications */
-+
-+ alloc_func zalloc; /* used to allocate the internal state */
-+ free_func zfree; /* used to free the internal state */
-+ voidpf opaque; /* private data object passed to zalloc and zfree */
-+
-+ int data_type; /* best guess about the data type: ascii or binary */
-+ uLong adler; /* adler32 value of the uncompressed data */
-+ uLong reserved; /* reserved for future use */
-+} z_stream;
-+
-+typedef z_stream FAR *z_streamp;
-+
-+/*
-+ The application must update next_in and avail_in when avail_in has
-+ dropped to zero. It must update next_out and avail_out when avail_out
-+ has dropped to zero. The application must initialize zalloc, zfree and
-+ opaque before calling the init function. All other fields are set by the
-+ compression library and must not be updated by the application.
-+
-+ The opaque value provided by the application will be passed as the first
-+ parameter for calls of zalloc and zfree. This can be useful for custom
-+ memory management. The compression library attaches no meaning to the
-+ opaque value.
-+
-+ zalloc must return Z_NULL if there is not enough memory for the object.
-+ If zlib is used in a multi-threaded application, zalloc and zfree must be
-+ thread safe.
-+
-+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
-+ exactly 65536 bytes, but will not be required to allocate more than this
-+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
-+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
-+ have their offset normalized to zero. The default allocation function
-+ provided by this library ensures this (see zutil.c). To reduce memory
-+ requirements and avoid any allocation of 64K objects, at the expense of
-+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
-+
-+ The fields total_in and total_out can be used for statistics or
-+ progress reports. After compression, total_in holds the total size of
-+ the uncompressed data and may be saved for use in the decompressor
-+ (particularly if the decompressor wants to decompress everything in
-+ a single step).
-+*/
-+
-+ /* constants */
-+
-+#define Z_NO_FLUSH 0
-+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
-+#define Z_SYNC_FLUSH 2
-+#define Z_FULL_FLUSH 3
-+#define Z_FINISH 4
-+/* Allowed flush values; see deflate() below for details */
-+
-+#define Z_OK 0
-+#define Z_STREAM_END 1
-+#define Z_NEED_DICT 2
-+#define Z_ERRNO (-1)
-+#define Z_STREAM_ERROR (-2)
-+#define Z_DATA_ERROR (-3)
-+#define Z_MEM_ERROR (-4)
-+#define Z_BUF_ERROR (-5)
-+#define Z_VERSION_ERROR (-6)
-+/* Return codes for the compression/decompression functions. Negative
-+ * values are errors, positive values are used for special but normal events.
-+ */
-+
-+#define Z_NO_COMPRESSION 0
-+#define Z_BEST_SPEED 1
-+#define Z_BEST_COMPRESSION 9
-+#define Z_DEFAULT_COMPRESSION (-1)
-+/* compression levels */
-+
-+#define Z_FILTERED 1
-+#define Z_HUFFMAN_ONLY 2
-+#define Z_DEFAULT_STRATEGY 0
-+/* compression strategy; see deflateInit2() below for details */
-+
-+#define Z_BINARY 0
-+#define Z_ASCII 1
-+#define Z_UNKNOWN 2
-+/* Possible values of the data_type field */
-+
-+#define Z_DEFLATED 8
-+/* The deflate compression method (the only one supported in this version) */
-+
-+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
-+
-+#define zlib_version zlibVersion()
-+/* for compatibility with versions < 1.0.2 */
-+
-+ /* basic functions */
-+
-+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
-+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
-+ If the first character differs, the library code actually used is
-+ not compatible with the zlib.h header file used by the application.
-+ This check is automatically made by deflateInit and inflateInit.
-+ */
-+
-+/*
-+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
-+
-+ Initializes the internal stream state for compression. The fields
-+ zalloc, zfree and opaque must be initialized before by the caller.
-+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to
-+ use default allocation functions.
-+
-+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
-+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
-+ all (the input data is simply copied a block at a time).
-+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
-+ compression (currently equivalent to level 6).
-+
-+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
-+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
-+ with the version assumed by the caller (ZLIB_VERSION).
-+ msg is set to null if there is no error message. deflateInit does not
-+ perform any compression: this will be done by deflate().
-+*/
-+
-+
-+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
-+/*
-+ deflate compresses as much data as possible, and stops when the input
-+ buffer becomes empty or the output buffer becomes full. It may introduce some
-+ output latency (reading input without producing any output) except when
-+ forced to flush.
-+
-+ The detailed semantics are as follows. deflate performs one or both of the
-+ following actions:
-+
-+ - Compress more input starting at next_in and update next_in and avail_in
-+ accordingly. If not all input can be processed (because there is not
-+ enough room in the output buffer), next_in and avail_in are updated and
-+ processing will resume at this point for the next call of deflate().
-+
-+ - Provide more output starting at next_out and update next_out and avail_out
-+ accordingly. This action is forced if the parameter flush is non zero.
-+ Forcing flush frequently degrades the compression ratio, so this parameter
-+ should be set only when necessary (in interactive applications).
-+ Some output may be provided even if flush is not set.
-+
-+ Before the call of deflate(), the application should ensure that at least
-+ one of the actions is possible, by providing more input and/or consuming
-+ more output, and updating avail_in or avail_out accordingly; avail_out
-+ should never be zero before the call. The application can consume the
-+ compressed output when it wants, for example when the output buffer is full
-+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
-+ and with zero avail_out, it must be called again after making room in the
-+ output buffer because there might be more output pending.
-+
-+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
-+ flushed to the output buffer and the output is aligned on a byte boundary, so
-+ that the decompressor can get all input data available so far. (In particular
-+ avail_in is zero after the call if enough output space has been provided
-+ before the call.) Flushing may degrade compression for some compression
-+ algorithms and so it should be used only when necessary.
-+
-+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
-+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
-+ restart from this point if previous compressed data has been damaged or if
-+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
-+ the compression.
-+
-+ If deflate returns with avail_out == 0, this function must be called again
-+ with the same value of the flush parameter and more output space (updated
-+ avail_out), until the flush is complete (deflate returns with non-zero
-+ avail_out).
-+
-+ If the parameter flush is set to Z_FINISH, pending input is processed,
-+ pending output is flushed and deflate returns with Z_STREAM_END if there
-+ was enough output space; if deflate returns with Z_OK, this function must be
-+ called again with Z_FINISH and more output space (updated avail_out) but no
-+ more input data, until it returns with Z_STREAM_END or an error. After
-+ deflate has returned Z_STREAM_END, the only possible operations on the
-+ stream are deflateReset or deflateEnd.
-+
-+ Z_FINISH can be used immediately after deflateInit if all the compression
-+ is to be done in a single step. In this case, avail_out must be at least
-+ 0.1% larger than avail_in plus 12 bytes. If deflate does not return
-+ Z_STREAM_END, then it must be called again as described above.
-+
-+ deflate() sets strm->adler to the adler32 checksum of all input read
-+ so far (that is, total_in bytes).
-+
-+ deflate() may update data_type if it can make a good guess about
-+ the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
-+ binary. This field is only for information purposes and does not affect
-+ the compression algorithm in any manner.
-+
-+ deflate() returns Z_OK if some progress has been made (more input
-+ processed or more output produced), Z_STREAM_END if all input has been
-+ consumed and all output has been produced (only when flush is set to
-+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
-+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
-+ (for example avail_in or avail_out was zero).
-+*/
-+
-+
-+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
-+/*
-+ All dynamically allocated data structures for this stream are freed.
-+ This function discards any unprocessed input and does not flush any
-+ pending output.
-+
-+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
-+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
-+ prematurely (some input or output was discarded). In the error case,
-+ msg may be set but then points to a static string (which must not be
-+ deallocated).
-+*/
-+
-+
-+/*
-+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
-+
-+ Initializes the internal stream state for decompression. The fields
-+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
-+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
-+ value depends on the compression method), inflateInit determines the
-+ compression method from the zlib header and allocates all data structures
-+ accordingly; otherwise the allocation will be deferred to the first call of
-+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
-+ use default allocation functions.
-+
-+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
-+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
-+ version assumed by the caller. msg is set to null if there is no error
-+ message. inflateInit does not perform any decompression apart from reading
-+ the zlib header if present: this will be done by inflate(). (So next_in and
-+ avail_in may be modified, but next_out and avail_out are unchanged.)
-+*/
-+
-+
-+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
-+/*
-+ inflate decompresses as much data as possible, and stops when the input
-+ buffer becomes empty or the output buffer becomes full. It may some
-+ introduce some output latency (reading input without producing any output)
-+ except when forced to flush.
-+
-+ The detailed semantics are as follows. inflate performs one or both of the
-+ following actions:
-+
-+ - Decompress more input starting at next_in and update next_in and avail_in
-+ accordingly. If not all input can be processed (because there is not
-+ enough room in the output buffer), next_in is updated and processing
-+ will resume at this point for the next call of inflate().
-+
-+ - Provide more output starting at next_out and update next_out and avail_out
-+ accordingly. inflate() provides as much output as possible, until there
-+ is no more input data or no more space in the output buffer (see below
-+ about the flush parameter).
-+
-+ Before the call of inflate(), the application should ensure that at least
-+ one of the actions is possible, by providing more input and/or consuming
-+ more output, and updating the next_* and avail_* values accordingly.
-+ The application can consume the uncompressed output when it wants, for
-+ example when the output buffer is full (avail_out == 0), or after each
-+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
-+ must be called again after making room in the output buffer because there
-+ might be more output pending.
-+
-+ If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
-+ output as possible to the output buffer. The flushing behavior of inflate is
-+ not specified for values of the flush parameter other than Z_SYNC_FLUSH
-+ and Z_FINISH, but the current implementation actually flushes as much output
-+ as possible anyway.
-+
-+ inflate() should normally be called until it returns Z_STREAM_END or an
-+ error. However if all decompression is to be performed in a single step
-+ (a single call of inflate), the parameter flush should be set to
-+ Z_FINISH. In this case all pending input is processed and all pending
-+ output is flushed; avail_out must be large enough to hold all the
-+ uncompressed data. (The size of the uncompressed data may have been saved
-+ by the compressor for this purpose.) The next operation on this stream must
-+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
-+ is never required, but can be used to inform inflate that a faster routine
-+ may be used for the single inflate() call.
-+
-+ If a preset dictionary is needed at this point (see inflateSetDictionary
-+ below), inflate sets strm-adler to the adler32 checksum of the
-+ dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
-+ it sets strm->adler to the adler32 checksum of all output produced
-+ so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
-+ an error code as described below. At the end of the stream, inflate()
-+ checks that its computed adler32 checksum is equal to that saved by the
-+ compressor and returns Z_STREAM_END only if the checksum is correct.
-+
-+ inflate() returns Z_OK if some progress has been made (more input processed
-+ or more output produced), Z_STREAM_END if the end of the compressed data has
-+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
-+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
-+ corrupted (input stream not conforming to the zlib format or incorrect
-+ adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
-+ (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
-+ enough memory, Z_BUF_ERROR if no progress is possible or if there was not
-+ enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
-+ case, the application may then call inflateSync to look for a good
-+ compression block.
-+*/
-+
-+
-+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
-+/*
-+ All dynamically allocated data structures for this stream are freed.
-+ This function discards any unprocessed input and does not flush any
-+ pending output.
-+
-+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
-+ was inconsistent. In the error case, msg may be set but then points to a
-+ static string (which must not be deallocated).
-+*/
-+
-+ /* Advanced functions */
-+
-+/*
-+ The following functions are needed only in some special applications.
-+*/
-+
-+/*
-+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
-+ int level,
-+ int method,
-+ int windowBits,
-+ int memLevel,
-+ int strategy));
-+
-+ This is another version of deflateInit with more compression options. The
-+ fields next_in, zalloc, zfree and opaque must be initialized before by
-+ the caller.
-+
-+ The method parameter is the compression method. It must be Z_DEFLATED in
-+ this version of the library.
-+
-+ The windowBits parameter is the base two logarithm of the window size
-+ (the size of the history buffer). It should be in the range 8..15 for this
-+ version of the library. Larger values of this parameter result in better
-+ compression at the expense of memory usage. The default value is 15 if
-+ deflateInit is used instead.
-+
-+ The memLevel parameter specifies how much memory should be allocated
-+ for the internal compression state. memLevel=1 uses minimum memory but
-+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
-+ for optimal speed. The default value is 8. See zconf.h for total memory
-+ usage as a function of windowBits and memLevel.
-+
-+ The strategy parameter is used to tune the compression algorithm. Use the
-+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
-+ filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
-+ string match). Filtered data consists mostly of small values with a
-+ somewhat random distribution. In this case, the compression algorithm is
-+ tuned to compress them better. The effect of Z_FILTERED is to force more
-+ Huffman coding and less string matching; it is somewhat intermediate
-+ between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
-+ the compression ratio but not the correctness of the compressed output even
-+ if it is not set appropriately.
-+
-+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
-+ method). msg is set to null if there is no error message. deflateInit2 does
-+ not perform any compression: this will be done by deflate().
-+*/
-+
-+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
-+ const Bytef *dictionary,
-+ uInt dictLength));
-+/*
-+ Initializes the compression dictionary from the given byte sequence
-+ without producing any compressed output. This function must be called
-+ immediately after deflateInit, deflateInit2 or deflateReset, before any
-+ call of deflate. The compressor and decompressor must use exactly the same
-+ dictionary (see inflateSetDictionary).
-+
-+ The dictionary should consist of strings (byte sequences) that are likely
-+ to be encountered later in the data to be compressed, with the most commonly
-+ used strings preferably put towards the end of the dictionary. Using a
-+ dictionary is most useful when the data to be compressed is short and can be
-+ predicted with good accuracy; the data can then be compressed better than
-+ with the default empty dictionary.
-+
-+ Depending on the size of the compression data structures selected by
-+ deflateInit or deflateInit2, a part of the dictionary may in effect be
-+ discarded, for example if the dictionary is larger than the window size in
-+ deflate or deflate2. Thus the strings most likely to be useful should be
-+ put at the end of the dictionary, not at the front.
-+
-+ Upon return of this function, strm->adler is set to the Adler32 value
-+ of the dictionary; the decompressor may later use this value to determine
-+ which dictionary has been used by the compressor. (The Adler32 value
-+ applies to the whole dictionary even if only a subset of the dictionary is
-+ actually used by the compressor.)
-+
-+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
-+ parameter is invalid (such as NULL dictionary) or the stream state is
-+ inconsistent (for example if deflate has already been called for this stream
-+ or if the compression method is bsort). deflateSetDictionary does not
-+ perform any compression: this will be done by deflate().
-+*/
-+
-+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
-+ z_streamp source));
-+/*
-+ Sets the destination stream as a complete copy of the source stream.
-+
-+ This function can be useful when several compression strategies will be
-+ tried, for example when there are several ways of pre-processing the input
-+ data with a filter. The streams that will be discarded should then be freed
-+ by calling deflateEnd. Note that deflateCopy duplicates the internal
-+ compression state which can be quite large, so this strategy is slow and
-+ can consume lots of memory.
-+
-+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
-+ (such as zalloc being NULL). msg is left unchanged in both source and
-+ destination.
-+*/
-+
-+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
-+/*
-+ This function is equivalent to deflateEnd followed by deflateInit,
-+ but does not free and reallocate all the internal compression state.
-+ The stream will keep the same compression level and any other attributes
-+ that may have been set by deflateInit2.
-+
-+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-+ stream state was inconsistent (such as zalloc or state being NULL).
-+*/
-+
-+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
-+ int level,
-+ int strategy));
-+/*
-+ Dynamically update the compression level and compression strategy. The
-+ interpretation of level and strategy is as in deflateInit2. This can be
-+ used to switch between compression and straight copy of the input data, or
-+ to switch to a different kind of input data requiring a different
-+ strategy. If the compression level is changed, the input available so far
-+ is compressed with the old level (and may be flushed); the new level will
-+ take effect only at the next call of deflate().
-+
-+ Before the call of deflateParams, the stream state must be set as for
-+ a call of deflate(), since the currently available input may have to
-+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
-+
-+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
-+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
-+ if strm->avail_out was zero.
-+*/
-+
-+/*
-+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
-+ int windowBits));
-+
-+ This is another version of inflateInit with an extra parameter. The
-+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
-+ before by the caller.
-+
-+ The windowBits parameter is the base two logarithm of the maximum window
-+ size (the size of the history buffer). It should be in the range 8..15 for
-+ this version of the library. The default value is 15 if inflateInit is used
-+ instead. If a compressed stream with a larger window size is given as
-+ input, inflate() will return with the error code Z_DATA_ERROR instead of
-+ trying to allocate a larger window.
-+
-+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
-+ memLevel). msg is set to null if there is no error message. inflateInit2
-+ does not perform any decompression apart from reading the zlib header if
-+ present: this will be done by inflate(). (So next_in and avail_in may be
-+ modified, but next_out and avail_out are unchanged.)
-+*/
-+
-+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
-+ const Bytef *dictionary,
-+ uInt dictLength));
-+/*
-+ Initializes the decompression dictionary from the given uncompressed byte
-+ sequence. This function must be called immediately after a call of inflate
-+ if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
-+ can be determined from the Adler32 value returned by this call of
-+ inflate. The compressor and decompressor must use exactly the same
-+ dictionary (see deflateSetDictionary).
-+
-+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
-+ parameter is invalid (such as NULL dictionary) or the stream state is
-+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
-+ expected one (incorrect Adler32 value). inflateSetDictionary does not
-+ perform any decompression: this will be done by subsequent calls of
-+ inflate().
-+*/
-+
-+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
-+/*
-+ Skips invalid compressed data until a full flush point (see above the
-+ description of deflate with Z_FULL_FLUSH) can be found, or until all
-+ available input is skipped. No output is provided.
-+
-+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
-+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
-+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
-+ case, the application may save the current current value of total_in which
-+ indicates where valid compressed data was found. In the error case, the
-+ application may repeatedly call inflateSync, providing more input each time,
-+ until success or end of the input data.
-+*/
-+
-+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
-+/*
-+ This function is equivalent to inflateEnd followed by inflateInit,
-+ but does not free and reallocate all the internal decompression state.
-+ The stream will keep attributes that may have been set by inflateInit2.
-+
-+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
-+ stream state was inconsistent (such as zalloc or state being NULL).
-+*/
-+
-+
-+ /* utility functions */
-+
-+/*
-+ The following utility functions are implemented on top of the
-+ basic stream-oriented functions. To simplify the interface, some
-+ default options are assumed (compression level and memory usage,
-+ standard memory allocation functions). The source code of these
-+ utility functions can easily be modified if you need special options.
-+*/
-+
-+ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
-+ const Bytef *source, uLong sourceLen));
-+/*
-+ Compresses the source buffer into the destination buffer. sourceLen is
-+ the byte length of the source buffer. Upon entry, destLen is the total
-+ size of the destination buffer, which must be at least 0.1% larger than
-+ sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
-+ compressed buffer.
-+ This function can be used to compress a whole file at once if the
-+ input file is mmap'ed.
-+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory, Z_BUF_ERROR if there was not enough room in the output
-+ buffer.
-+*/
-+
-+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
-+ const Bytef *source, uLong sourceLen,
-+ int level));
-+/*
-+ Compresses the source buffer into the destination buffer. The level
-+ parameter has the same meaning as in deflateInit. sourceLen is the byte
-+ length of the source buffer. Upon entry, destLen is the total size of the
-+ destination buffer, which must be at least 0.1% larger than sourceLen plus
-+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
-+
-+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
-+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
-+ Z_STREAM_ERROR if the level parameter is invalid.
-+*/
-+
-+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
-+ const Bytef *source, uLong sourceLen));
-+/*
-+ Decompresses the source buffer into the destination buffer. sourceLen is
-+ the byte length of the source buffer. Upon entry, destLen is the total
-+ size of the destination buffer, which must be large enough to hold the
-+ entire uncompressed data. (The size of the uncompressed data must have
-+ been saved previously by the compressor and transmitted to the decompressor
-+ by some mechanism outside the scope of this compression library.)
-+ Upon exit, destLen is the actual size of the compressed buffer.
-+ This function can be used to decompress a whole file at once if the
-+ input file is mmap'ed.
-+
-+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
-+ enough memory, Z_BUF_ERROR if there was not enough room in the output
-+ buffer, or Z_DATA_ERROR if the input data was corrupted.
-+*/
-+
-+
-+typedef voidp gzFile;
-+
-+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
-+/*
-+ Opens a gzip (.gz) file for reading or writing. The mode parameter
-+ is as in fopen ("rb" or "wb") but can also include a compression level
-+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
-+ Huffman only compression as in "wb1h". (See the description
-+ of deflateInit2 for more information about the strategy parameter.)
-+
-+ gzopen can be used to read a file which is not in gzip format; in this
-+ case gzread will directly read from the file without decompression.
-+
-+ gzopen returns NULL if the file could not be opened or if there was
-+ insufficient memory to allocate the (de)compression state; errno
-+ can be checked to distinguish the two cases (if errno is zero, the
-+ zlib error is Z_MEM_ERROR). */
-+
-+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
-+/*
-+ gzdopen() associates a gzFile with the file descriptor fd. File
-+ descriptors are obtained from calls like open, dup, creat, pipe or
-+ fileno (in the file has been previously opened with fopen).
-+ The mode parameter is as in gzopen.
-+ The next call of gzclose on the returned gzFile will also close the
-+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
-+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
-+ gzdopen returns NULL if there was insufficient memory to allocate
-+ the (de)compression state.
-+*/
-+
-+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
-+/*
-+ Dynamically update the compression level or strategy. See the description
-+ of deflateInit2 for the meaning of these parameters.
-+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
-+ opened for writing.
-+*/
-+
-+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
-+/*
-+ Reads the given number of uncompressed bytes from the compressed file.
-+ If the input file was not in gzip format, gzread copies the given number
-+ of bytes into the buffer.
-+ gzread returns the number of uncompressed bytes actually read (0 for
-+ end of file, -1 for error). */
-+
-+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
-+ const voidp buf, unsigned len));
-+/*
-+ Writes the given number of uncompressed bytes into the compressed file.
-+ gzwrite returns the number of uncompressed bytes actually written
-+ (0 in case of error).
-+*/
-+
-+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
-+/*
-+ Converts, formats, and writes the args to the compressed file under
-+ control of the format string, as in fprintf. gzprintf returns the number of
-+ uncompressed bytes actually written (0 in case of error).
-+*/
-+
-+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
-+/*
-+ Writes the given null-terminated string to the compressed file, excluding
-+ the terminating null character.
-+ gzputs returns the number of characters written, or -1 in case of error.
-+*/
-+
-+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
-+/*
-+ Reads bytes from the compressed file until len-1 characters are read, or
-+ a newline character is read and transferred to buf, or an end-of-file
-+ condition is encountered. The string is then terminated with a null
-+ character.
-+ gzgets returns buf, or Z_NULL in case of error.
-+*/
-+
-+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
-+/*
-+ Writes c, converted to an unsigned char, into the compressed file.
-+ gzputc returns the value that was written, or -1 in case of error.
-+*/
-+
-+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
-+/*
-+ Reads one byte from the compressed file. gzgetc returns this byte
-+ or -1 in case of end of file or error.
-+*/
-+
-+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
-+/*
-+ Flushes all pending output into the compressed file. The parameter
-+ flush is as in the deflate() function. The return value is the zlib
-+ error number (see function gzerror below). gzflush returns Z_OK if
-+ the flush parameter is Z_FINISH and all output could be flushed.
-+ gzflush should be called only when strictly necessary because it can
-+ degrade compression.
-+*/
-+
-+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
-+ z_off_t offset, int whence));
-+/*
-+ Sets the starting position for the next gzread or gzwrite on the
-+ given compressed file. The offset represents a number of bytes in the
-+ uncompressed data stream. The whence parameter is defined as in lseek(2);
-+ the value SEEK_END is not supported.
-+ If the file is opened for reading, this function is emulated but can be
-+ extremely slow. If the file is opened for writing, only forward seeks are
-+ supported; gzseek then compresses a sequence of zeroes up to the new
-+ starting position.
-+
-+ gzseek returns the resulting offset location as measured in bytes from
-+ the beginning of the uncompressed stream, or -1 in case of error, in
-+ particular if the file is opened for writing and the new starting position
-+ would be before the current position.
-+*/
-+
-+ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
-+/*
-+ Rewinds the given file. This function is supported only for reading.
-+
-+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
-+*/
-+
-+ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
-+/*
-+ Returns the starting position for the next gzread or gzwrite on the
-+ given compressed file. This position represents a number of bytes in the
-+ uncompressed data stream.
-+
-+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
-+*/
-+
-+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
-+/*
-+ Returns 1 when EOF has previously been detected reading the given
-+ input stream, otherwise zero.
-+*/
-+
-+ZEXTERN int ZEXPORT gzclose OF((gzFile file));
-+/*
-+ Flushes all pending output if necessary, closes the compressed file
-+ and deallocates all the (de)compression state. The return value is the zlib
-+ error number (see function gzerror below).
-+*/
-+
-+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
-+/*
-+ Returns the error message for the last error which occurred on the
-+ given compressed file. errnum is set to zlib error number. If an
-+ error occurred in the file system and not in the compression library,
-+ errnum is set to Z_ERRNO and the application may consult errno
-+ to get the exact error code.
-+*/
-+
-+ /* checksum functions */
-+
-+/*
-+ These functions are not related to compression but are exported
-+ anyway because they might be useful in applications using the
-+ compression library.
-+*/
-+
-+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
-+
-+/*
-+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
-+ return the updated checksum. If buf is NULL, this function returns
-+ the required initial value for the checksum.
-+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
-+ much faster. Usage example:
-+
-+ uLong adler = adler32(0L, Z_NULL, 0);
-+
-+ while (read_buffer(buffer, length) != EOF) {
-+ adler = adler32(adler, buffer, length);
-+ }
-+ if (adler != original_adler) error();
-+*/
-+
-+ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
-+/*
-+ Update a running crc with the bytes buf[0..len-1] and return the updated
-+ crc. If buf is NULL, this function returns the required initial value
-+ for the crc. Pre- and post-conditioning (one's complement) is performed
-+ within this function so it shouldn't be done by the application.
-+ Usage example:
-+
-+ uLong crc = crc32(0L, Z_NULL, 0);
-+
-+ while (read_buffer(buffer, length) != EOF) {
-+ crc = crc32(crc, buffer, length);
-+ }
-+ if (crc != original_crc) error();
-+*/
-+
-+
-+ /* various hacks, don't look :) */
-+
-+/* deflateInit and inflateInit are macros to allow checking the zlib version
-+ * and the compiler's view of z_stream:
-+ */
-+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
-+ const char *version, int stream_size));
-+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
-+ const char *version, int stream_size));
-+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
-+ int windowBits, int memLevel,
-+ int strategy, const char *version,
-+ int stream_size));
-+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
-+ const char *version, int stream_size));
-+#define deflateInit(strm, level) \
-+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
-+#define inflateInit(strm) \
-+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
-+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
-+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
-+ (strategy), ZLIB_VERSION, sizeof(z_stream))
-+#define inflateInit2(strm, windowBits) \
-+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
-+
-+
-+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
-+ struct internal_state {int dummy;}; /* hack for buggy compilers */
-+#endif
-+
-+ZEXTERN const char * ZEXPORT zError OF((int err));
-+ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
-+ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _ZLIB_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/include/zlib/zutil.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,225 @@
-+/* zutil.h -- internal interface and configuration of the compression library
-+ * Copyright (C) 1995-2002 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+/* @(#) $Id$ */
-+
-+#ifndef _Z_UTIL_H
-+#define _Z_UTIL_H
-+
-+#include "zlib.h"
-+
-+#include <linux/string.h>
-+#define HAVE_MEMCPY
-+
-+#if 0 // #ifdef STDC
-+# include <stddef.h>
-+# include <string.h>
-+# include <stdlib.h>
-+#endif
-+#ifndef __KERNEL__
-+#ifdef NO_ERRNO_H
-+ extern int errno;
-+#else
-+# include <errno.h>
-+#endif
-+#endif
-+
-+#ifndef local
-+# define local static
-+#endif
-+/* compile with -Dlocal if your debugger can't find static symbols */
-+
-+typedef unsigned char uch;
-+typedef uch FAR uchf;
-+typedef unsigned short ush;
-+typedef ush FAR ushf;
-+typedef unsigned long ulg;
-+
-+extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
-+/* (size given to avoid silly warnings with Visual C++) */
-+
-+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
-+
-+#define ERR_RETURN(strm,err) \
-+ return (strm->msg = ERR_MSG(err), (err))
-+/* To be used only when the state is known to be valid */
-+
-+ /* common constants */
-+
-+#ifndef DEF_WBITS
-+# define DEF_WBITS MAX_WBITS
-+#endif
-+/* default windowBits for decompression. MAX_WBITS is for compression only */
-+
-+#if MAX_MEM_LEVEL >= 8
-+# define DEF_MEM_LEVEL 8
-+#else
-+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
-+#endif
-+/* default memLevel */
-+
-+#define STORED_BLOCK 0
-+#define STATIC_TREES 1
-+#define DYN_TREES 2
-+/* The three kinds of block type */
-+
-+#define MIN_MATCH 3
-+#define MAX_MATCH 258
-+/* The minimum and maximum match lengths */
-+
-+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
-+
-+ /* target dependencies */
-+
-+#ifdef MSDOS
-+# define OS_CODE 0x00
-+# if defined(__TURBOC__) || defined(__BORLANDC__)
-+# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
-+ /* Allow compilation with ANSI keywords only enabled */
-+ void _Cdecl farfree( void *block );
-+ void *_Cdecl farmalloc( unsigned long nbytes );
-+# else
-+# include <alloc.h>
-+# endif
-+# else /* MSC or DJGPP */
-+# include <malloc.h>
-+# endif
-+#endif
-+
-+#ifdef OS2
-+# define OS_CODE 0x06
-+#endif
-+
-+#ifdef WIN32 /* Window 95 & Windows NT */
-+# define OS_CODE 0x0b
-+#endif
-+
-+#if defined(VAXC) || defined(VMS)
-+# define OS_CODE 0x02
-+# define F_OPEN(name, mode) \
-+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
-+#endif
-+
-+#ifdef AMIGA
-+# define OS_CODE 0x01
-+#endif
-+
-+#if defined(ATARI) || defined(atarist)
-+# define OS_CODE 0x05
-+#endif
-+
-+#if defined(MACOS) || defined(TARGET_OS_MAC)
-+# define OS_CODE 0x07
-+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
-+# include <unix.h> /* for fdopen */
-+# else
-+# ifndef fdopen
-+# define fdopen(fd,mode) NULL /* No fdopen() */
-+# endif
-+# endif
-+#endif
-+
-+#ifdef __50SERIES /* Prime/PRIMOS */
-+# define OS_CODE 0x0F
-+#endif
-+
-+#ifdef TOPS20
-+# define OS_CODE 0x0a
-+#endif
-+
-+#if defined(_BEOS_) || defined(RISCOS)
-+# define fdopen(fd,mode) NULL /* No fdopen() */
-+#endif
-+
-+#if (defined(_MSC_VER) && (_MSC_VER > 600))
-+# define fdopen(fd,type) _fdopen(fd,type)
-+#endif
-+
-+
-+ /* Common defaults */
-+
-+#ifndef OS_CODE
-+# define OS_CODE 0x03 /* assume Unix */
-+#endif
-+
-+#ifndef F_OPEN
-+# define F_OPEN(name, mode) fopen((name), (mode))
-+#endif
-+
-+ /* functions */
-+
-+#ifdef HAVE_STRERROR
-+ extern char *strerror OF((int));
-+# define zstrerror(errnum) strerror(errnum)
-+#else
-+# define zstrerror(errnum) ""
-+#endif
-+
-+#if defined(pyr)
-+# define NO_MEMCPY
-+#endif
-+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
-+ /* Use our own functions for small and medium model with MSC <= 5.0.
-+ * You may have to use the same strategy for Borland C (untested).
-+ * The __SC__ check is for Symantec.
-+ */
-+# define NO_MEMCPY
-+#endif
-+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
-+# define HAVE_MEMCPY
-+#endif
-+#ifdef HAVE_MEMCPY
-+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
-+# define zmemcpy _fmemcpy
-+# define zmemcmp _fmemcmp
-+# define zmemzero(dest, len) _fmemset(dest, 0, len)
-+# else
-+# define zmemcpy memcpy
-+# define zmemcmp memcmp
-+# define zmemzero(dest, len) memset(dest, 0, len)
-+# endif
-+#else
-+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
-+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
-+ extern void zmemzero OF((Bytef* dest, uInt len));
-+#endif
-+
-+/* Diagnostic functions */
-+#ifdef DEBUG
-+# include <stdio.h>
-+ extern int z_verbose;
-+ extern void z_error OF((char *m));
-+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
-+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
-+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
-+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
-+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
-+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
-+#else
-+# define Assert(cond,msg)
-+# define Trace(x)
-+# define Tracev(x)
-+# define Tracevv(x)
-+# define Tracec(c,x)
-+# define Tracecv(c,x)
-+#endif
-+
-+
-+typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
-+ uInt len));
-+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
-+void zcfree OF((voidpf opaque, voidpf ptr));
-+
-+#define ZALLOC(strm, items, size) \
-+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
-+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
-+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
-+
-+#endif /* _Z_UTIL_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/Makefile.objs Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,21 @@
-+obj-y += satot.o
-+obj-y += addrtot.o
-+obj-y += ultot.o
-+obj-y += addrtypeof.o
-+obj-y += anyaddr.o
-+obj-y += initaddr.o
-+obj-y += ultoa.o
-+obj-y += addrtoa.o
-+obj-y += subnettoa.o
-+obj-y += subnetof.o
-+obj-y += goodmask.o
-+obj-y += datatot.o
-+obj-y += rangetoa.o
-+obj-y += prng.o
-+obj-y += pfkey_v2_parse.o
-+obj-y += pfkey_v2_build.o
-+obj-y += pfkey_v2_debug.o
-+obj-y += pfkey_v2_ext_bits.o
-+
-+#version.c: ${LIBFREESWANDIR}/version.in.c ${OPENSWANSRCDIR}/Makefile.ver
-+# sed '/"/s/xxx/$(IPSECVERSION)/' ${LIBFREESWANDIR}/version.in.c >$@
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/addrtoa.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,67 @@
-+/*
-+ * addresses to ASCII
-+ * Copyright (C) 1998, 1999 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+#define NBYTES 4 /* bytes in an address */
-+#define PERBYTE 4 /* three digits plus a dot or NUL */
-+#define BUFLEN (NBYTES*PERBYTE)
-+
-+#if BUFLEN != ADDRTOA_BUF
-+#error "ADDRTOA_BUF in openswan.h inconsistent with addrtoa() code"
-+#endif
-+
-+/*
-+ - addrtoa - convert binary address to ASCII dotted decimal
-+ */
-+size_t /* space needed for full conversion */
-+addrtoa(addr, format, dst, dstlen)
-+struct in_addr addr;
-+int format; /* character */
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ unsigned long a = ntohl(addr.s_addr);
-+ int i;
-+ size_t n;
-+ unsigned long byte;
-+ char buf[BUFLEN];
-+ char *p;
-+
-+ switch (format) {
-+ case 0:
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+
-+ p = buf;
-+ for (i = NBYTES-1; i >= 0; i--) {
-+ byte = (a >> (i*8)) & 0xff;
-+ p += ultoa(byte, 10, p, PERBYTE);
-+ if (i != 0)
-+ *(p-1) = '.';
-+ }
-+ n = p - buf;
-+
-+ if (dstlen > 0) {
-+ if (n > dstlen)
-+ buf[dstlen - 1] = '\0';
-+ strcpy(dst, buf);
-+ }
-+ return n;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/addrtot.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,334 @@
-+/*
-+ * addresses to text
-+ * Copyright (C) 2000 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+#define IP4BYTES 4 /* bytes in an IPv4 address */
-+#define PERBYTE 4 /* three digits plus a dot or NUL */
-+#define IP6BYTES 16 /* bytes in an IPv6 address */
-+
-+/* forwards */
-+static size_t normal4(const unsigned char *s, size_t len, char *b, char **dp);
-+static size_t normal6(const unsigned char *s, size_t len, char *b, char **dp, int squish);
-+static size_t reverse4(const unsigned char *s, size_t len, char *b, char **dp);
-+static size_t reverse6(const unsigned char *s, size_t len, char *b, char **dp);
-+
-+/*
-+ - addrtot - convert binary address to text (dotted decimal or IPv6 string)
-+ */
-+size_t /* space needed for full conversion */
-+addrtot(src, format, dst, dstlen)
-+const ip_address *src;
-+int format; /* character */
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ const unsigned char *b;
-+ size_t n;
-+ char buf[1+ADDRTOT_BUF+1]; /* :address: */
-+ char *p;
-+ int t = addrtypeof(src);
-+# define TF(t, f) (((t)<<8) | (f))
-+
-+ n = addrbytesptr(src, &b);
-+ if (n == 0) {
-+ bad:
-+ dst[0]='\0';
-+ strncat(dst, "<invalid>", dstlen);
-+ return sizeof("<invalid>");
-+ }
-+
-+ switch (TF(t, format)) {
-+ case TF(AF_INET, 0):
-+ n = normal4(b, n, buf, &p);
-+ break;
-+ case TF(AF_INET6, 0):
-+ n = normal6(b, n, buf, &p, 1);
-+ break;
-+ case TF(AF_INET, 'Q'):
-+ n = normal4(b, n, buf, &p);
-+ break;
-+ case TF(AF_INET6, 'Q'):
-+ n = normal6(b, n, buf, &p, 0);
-+ break;
-+ case TF(AF_INET, 'r'):
-+ n = reverse4(b, n, buf, &p);
-+ break;
-+ case TF(AF_INET6, 'r'):
-+ n = reverse6(b, n, buf, &p);
-+ break;
-+ default: /* including (AF_INET, 'R') */
-+ goto bad;
-+ break;
-+ }
-+
-+ if (dstlen > 0) {
-+ if (dstlen < n)
-+ p[dstlen - 1] = '\0';
-+ strcpy(dst, p);
-+ }
-+ return n;
-+}
-+
-+/*
-+ - normal4 - normal IPv4 address-text conversion
-+ */
-+static size_t /* size of text, including NUL */
-+normal4(srcp, srclen, buf, dstp)
-+const unsigned char *srcp;
-+size_t srclen;
-+char *buf; /* guaranteed large enough */
-+char **dstp; /* where to put result pointer */
-+{
-+ int i;
-+ char *p;
-+
-+ if (srclen != IP4BYTES) /* "can't happen" */
-+ return 0;
-+ p = buf;
-+ for (i = 0; i < IP4BYTES; i++) {
-+ p += ultot(srcp[i], 10, p, PERBYTE);
-+ if (i != IP4BYTES - 1)
-+ *(p-1) = '.'; /* overwrites the NUL */
-+ }
-+ *dstp = buf;
-+ return p - buf;
-+}
-+
-+/*
-+ - normal6 - normal IPv6 address-text conversion
-+ */
-+static size_t /* size of text, including NUL */
-+normal6(srcp, srclen, buf, dstp, squish)
-+const unsigned char *srcp;
-+size_t srclen;
-+char *buf; /* guaranteed large enough, plus 2 */
-+char **dstp; /* where to put result pointer */
-+int squish; /* whether to squish out 0:0 */
-+{
-+ int i;
-+ unsigned long piece;
-+ char *p;
-+ char *q;
-+
-+ if (srclen != IP6BYTES) /* "can't happen" */
-+ return 0;
-+ p = buf;
-+ *p++ = ':';
-+ for (i = 0; i < IP6BYTES/2; i++) {
-+ piece = (srcp[2*i] << 8) + srcp[2*i + 1];
-+ p += ultot(piece, 16, p, 5); /* 5 = abcd + NUL */
-+ *(p-1) = ':'; /* overwrites the NUL */
-+ }
-+ *p = '\0';
-+ q = strstr(buf, ":0:0:");
-+ if (squish && q != NULL) { /* zero squishing is possible */
-+ p = q + 1;
-+ while (*p == '0' && *(p+1) == ':')
-+ p += 2;
-+ q++;
-+ *q++ = ':'; /* overwrite first 0 */
-+ while (*p != '\0')
-+ *q++ = *p++;
-+ *q = '\0';
-+ if (!(*(q-1) == ':' && *(q-2) == ':'))
-+ *--q = '\0'; /* strip final : unless :: */
-+ p = buf;
-+ if (!(*p == ':' && *(p+1) == ':'))
-+ p++; /* skip initial : unless :: */
-+ } else {
-+ q = p;
-+ *--q = '\0'; /* strip final : */
-+ p = buf + 1; /* skip initial : */
-+ }
-+ *dstp = p;
-+ return q - p + 1;
-+}
-+
-+/*
-+ - reverse4 - IPv4 reverse-lookup conversion
-+ */
-+static size_t /* size of text, including NUL */
-+reverse4(srcp, srclen, buf, dstp)
-+const unsigned char *srcp;
-+size_t srclen;
-+char *buf; /* guaranteed large enough */
-+char **dstp; /* where to put result pointer */
-+{
-+ int i;
-+ char *p;
-+
-+ if (srclen != IP4BYTES) /* "can't happen" */
-+ return 0;
-+ p = buf;
-+ for (i = IP4BYTES-1; i >= 0; i--) {
-+ p += ultot(srcp[i], 10, p, PERBYTE);
-+ *(p-1) = '.'; /* overwrites the NUL */
-+ }
-+ strcpy(p, "IN-ADDR.ARPA.");
-+ *dstp = buf;
-+ return strlen(buf) + 1;
-+}
-+
-+/*
-+ - reverse6 - IPv6 reverse-lookup conversion (RFC 1886)
-+ * A trifle inefficient, really shouldn't use ultot...
-+ */
-+static size_t /* size of text, including NUL */
-+reverse6(srcp, srclen, buf, dstp)
-+const unsigned char *srcp;
-+size_t srclen;
-+char *buf; /* guaranteed large enough */
-+char **dstp; /* where to put result pointer */
-+{
-+ int i;
-+ unsigned long piece;
-+ char *p;
-+
-+ if (srclen != IP6BYTES) /* "can't happen" */
-+ return 0;
-+ p = buf;
-+ for (i = IP6BYTES-1; i >= 0; i--) {
-+ piece = srcp[i];
-+ p += ultot(piece&0xf, 16, p, 2);
-+ *(p-1) = '.';
-+ p += ultot(piece>>4, 16, p, 2);
-+ *(p-1) = '.';
-+ }
-+ strcpy(p, "IP6.ARPA.");
-+ *dstp = buf;
-+ return strlen(buf) + 1;
-+}
-+
-+/*
-+ - reverse6 - modern IPv6 reverse-lookup conversion (RFC 2874)
-+ * this version removed as it was obsoleted in the end.
-+ */
-+
-+#ifdef ADDRTOT_MAIN
-+
-+#include <stdio.h>
-+#include <sys/socket.h>
-+#include <netinet/in.h>
-+#include <arpa/inet.h>
-+
-+void regress(void);
-+
-+int
-+main(int argc, char *argv[])
-+{
-+ if (argc < 2) {
-+ fprintf(stderr, "Usage: %s {addr|net/mask|begin...end|-r}\n",
-+ argv[0]);
-+ exit(2);
-+ }
-+
-+ if (strcmp(argv[1], "-r") == 0) {
-+ regress();
-+ fprintf(stderr, "regress() returned?!?\n");
-+ exit(1);
-+ }
-+ exit(0);
-+}
-+
-+struct rtab {
-+ char *input;
-+ char format;
-+ char *output; /* NULL means error expected */
-+} rtab[] = {
-+ {"1.2.3.0", 0, "1.2.3.0"},
-+ {"1:2::3:4", 0, "1:2::3:4"},
-+ {"1:2::3:4", 'Q', "1:2:0:0:0:0:3:4"},
-+ {"1:2:0:0:3:4:0:0", 0, "1:2::3:4:0:0"},
-+ {"1.2.3.4", 'r' , "4.3.2.1.IN-ADDR.ARPA."},
-+ /* 0 1 2 3 4 5 6 7 8 9 a b c d e f 0 1 2 3 4 5 6 7 8 9 a b c d e f */
-+ {"1:2::3:4", 'r', "4.0.0.0.3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.2.0.0.0.1.0.0.0.IP6.ARPA."},
-+ {NULL, 0, NULL}
-+};
-+
-+void
-+regress()
-+{
-+ struct rtab *r;
-+ int status = 0;
-+ ip_address a;
-+ char in[100];
-+ char buf[100];
-+ const char *oops;
-+ size_t n;
-+
-+ for (r = rtab; r->input != NULL; r++) {
-+ strcpy(in, r->input);
-+
-+ /* convert it *to* internal format */
-+ oops = ttoaddr(in, strlen(in), 0, &a);
-+
-+ /* now convert it back */
-+
-+ n = addrtot(&a, r->format, buf, sizeof(buf));
-+
-+ if (n == 0 && r->output == NULL)
-+ {} /* okay, error expected */
-+
-+ else if (n == 0) {
-+ printf("`%s' atoasr failed\n", r->input);
-+ status = 1;
-+
-+ } else if (r->output == NULL) {
-+ printf("`%s' atoasr succeeded unexpectedly '%c'\n",
-+ r->input, r->format);
-+ status = 1;
-+ } else {
-+ if (strcasecmp(r->output, buf) != 0) {
-+ printf("`%s' '%c' gave `%s', expected `%s'\n",
-+ r->input, r->format, buf, r->output);
-+ status = 1;
-+ }
-+ }
-+ }
-+ exit(status);
-+}
-+
-+#endif /* ADDRTOT_MAIN */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.15 2004/04/11 17:39:25 mcr
-+ * removed internal.h requirements.
-+ *
-+ * Revision 1.14 2004/03/08 01:59:08 ken
-+ * freeswan.h -> openswan.h
-+ *
-+ * Revision 1.13 2004/01/05 23:21:05 mcr
-+ * if the address type is invalid, then return length of <invalid>
-+ * string!
-+ *
-+ * Revision 1.12 2003/12/30 06:42:48 mcr
-+ * added $Log$
-+ * added Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * added Turn off EOLN_NATIVE flag
-+ * added
-+ * added (Logical change 1.5010)
-+ * added
-+ * added Revision 1.15 2004/04/11 17:39:25 mcr
-+ * added removed internal.h requirements.
-+ * added
-+ * added Revision 1.14 2004/03/08 01:59:08 ken
-+ * added freeswan.h -> openswan.h
-+ * added
-+ * added Revision 1.13 2004/01/05 23:21:05 mcr
-+ * added if the address type is invalid, then return length of <invalid>
-+ * added string!
-+ * added
-+ *
-+ *
-+ */
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/addrtypeof.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,93 @@
-+/*
-+ * extract parts of an ip_address
-+ * Copyright (C) 2000 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/*
-+ - addrtypeof - get the type of an ip_address
-+ */
-+int
-+addrtypeof(src)
-+const ip_address *src;
-+{
-+ return src->u.v4.sin_family;
-+}
-+
-+/*
-+ - addrbytesptr - get pointer to the address bytes of an ip_address
-+ */
-+size_t /* 0 for error */
-+addrbytesptr(src, dstp)
-+const ip_address *src;
-+const unsigned char **dstp; /* NULL means just a size query */
-+{
-+ const unsigned char *p;
-+ size_t n;
-+
-+ switch (src->u.v4.sin_family) {
-+ case AF_INET:
-+ p = (const unsigned char *)&src->u.v4.sin_addr.s_addr;
-+ n = 4;
-+ break;
-+ case AF_INET6:
-+ p = (const unsigned char *)&src->u.v6.sin6_addr;
-+ n = 16;
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+
-+ if (dstp != NULL)
-+ *dstp = p;
-+ return n;
-+}
-+
-+/*
-+ - addrlenof - get length of the address bytes of an ip_address
-+ */
-+size_t /* 0 for error */
-+addrlenof(src)
-+const ip_address *src;
-+{
-+ return addrbytesptr(src, NULL);
-+}
-+
-+/*
-+ - addrbytesof - get the address bytes of an ip_address
-+ */
-+size_t /* 0 for error */
-+addrbytesof(src, dst, dstlen)
-+const ip_address *src;
-+unsigned char *dst;
-+size_t dstlen;
-+{
-+ const unsigned char *p;
-+ size_t n;
-+ size_t ncopy;
-+
-+ n = addrbytesptr(src, &p);
-+ if (n == 0)
-+ return 0;
-+
-+ if (dstlen > 0) {
-+ ncopy = n;
-+ if (ncopy > dstlen)
-+ ncopy = dstlen;
-+ memcpy(dst, p, ncopy);
-+ }
-+ return n;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/anyaddr.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,145 @@
-+/*
-+ * special addresses
-+ * Copyright (C) 2000 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/* these are mostly fallbacks for the no-IPv6-support-in-library case */
-+#ifndef IN6ADDR_ANY_INIT
-+#define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
-+#endif
-+#ifndef IN6ADDR_LOOPBACK_INIT
-+#define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}
-+#endif
-+
-+static struct in6_addr v6any = IN6ADDR_ANY_INIT;
-+static struct in6_addr v6loop = IN6ADDR_LOOPBACK_INIT;
-+
-+/*
-+ - anyaddr - initialize to the any-address value
-+ */
-+err_t /* NULL for success, else string literal */
-+anyaddr(af, dst)
-+int af; /* address family */
-+ip_address *dst;
-+{
-+ uint32_t v4any = htonl(INADDR_ANY);
-+
-+ switch (af) {
-+ case AF_INET:
-+ return initaddr((unsigned char *)&v4any, sizeof(v4any), af, dst);
-+ break;
-+ case AF_INET6:
-+ return initaddr((unsigned char *)&v6any, sizeof(v6any), af, dst);
-+ break;
-+ default:
-+ return "unknown address family in anyaddr/unspecaddr";
-+ break;
-+ }
-+}
-+
-+/*
-+ - unspecaddr - initialize to the unspecified-address value
-+ */
-+err_t /* NULL for success, else string literal */
-+unspecaddr(af, dst)
-+int af; /* address family */
-+ip_address *dst;
-+{
-+ return anyaddr(af, dst);
-+}
-+
-+/*
-+ - loopbackaddr - initialize to the loopback-address value
-+ */
-+err_t /* NULL for success, else string literal */
-+loopbackaddr(af, dst)
-+int af; /* address family */
-+ip_address *dst;
-+{
-+ uint32_t v4loop = htonl(INADDR_LOOPBACK);
-+
-+ switch (af) {
-+ case AF_INET:
-+ return initaddr((unsigned char *)&v4loop, sizeof(v4loop), af, dst);
-+ break;
-+ case AF_INET6:
-+ return initaddr((unsigned char *)&v6loop, sizeof(v6loop), af, dst);
-+ break;
-+ default:
-+ return "unknown address family in loopbackaddr";
-+ break;
-+ }
-+}
-+
-+/*
-+ - isanyaddr - test for the any-address value
-+ */
-+int
-+isanyaddr(src)
-+const ip_address *src;
-+{
-+ uint32_t v4any = htonl(INADDR_ANY);
-+ int cmp;
-+
-+ switch (src->u.v4.sin_family) {
-+ case AF_INET:
-+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4any, sizeof(v4any));
-+ break;
-+ case AF_INET6:
-+ cmp = memcmp(&src->u.v6.sin6_addr, &v6any, sizeof(v6any));
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+
-+ return (cmp == 0) ? 1 : 0;
-+}
-+
-+/*
-+ - isunspecaddr - test for the unspecified-address value
-+ */
-+int
-+isunspecaddr(src)
-+const ip_address *src;
-+{
-+ return isanyaddr(src);
-+}
-+
-+/*
-+ - isloopbackaddr - test for the loopback-address value
-+ */
-+int
-+isloopbackaddr(src)
-+const ip_address *src;
-+{
-+ uint32_t v4loop = htonl(INADDR_LOOPBACK);
-+ int cmp;
-+
-+ switch (src->u.v4.sin_family) {
-+ case AF_INET:
-+ cmp = memcmp(&src->u.v4.sin_addr.s_addr, &v4loop, sizeof(v4loop));
-+ break;
-+ case AF_INET6:
-+ cmp = memcmp(&src->u.v6.sin6_addr, &v6loop, sizeof(v6loop));
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+
-+ return (cmp == 0) ? 1 : 0;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/datatot.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,232 @@
-+/*
-+ * convert from binary data (e.g. key) to text form
-+ * Copyright (C) 2000 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+static void convert(const char *src, size_t nreal, int format, char *out);
-+
-+/*
-+ - datatot - convert data bytes to text
-+ */
-+size_t /* true length (with NUL) for success */
-+datatot(src, srclen, format, dst, dstlen)
-+const char *src;
-+size_t srclen;
-+int format; /* character indicating what format */
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ size_t inblocksize; /* process this many bytes at a time */
-+ size_t outblocksize; /* producing this many */
-+ size_t breakevery; /* add a _ every this many (0 means don't) */
-+ size_t sincebreak; /* output bytes since last _ */
-+ char breakchar; /* character used to break between groups */
-+ char inblock[10]; /* enough for any format */
-+ char outblock[10]; /* enough for any format */
-+ char fake[1]; /* fake output area for dstlen == 0 */
-+ size_t needed; /* return value */
-+ char *stop; /* where the terminating NUL will go */
-+ size_t ntodo; /* remaining input */
-+ size_t nreal;
-+ char *out;
-+ char *prefix;
-+
-+ breakevery = 0;
-+ breakchar = '_';
-+
-+ switch (format) {
-+ case 0:
-+ case 'h':
-+ format = 'x';
-+ breakevery = 8;
-+ /* FALLTHROUGH */
-+ case 'x':
-+ inblocksize = 1;
-+ outblocksize = 2;
-+ prefix = "0x";
-+ break;
-+ case ':':
-+ format = 'x';
-+ breakevery = 2;
-+ breakchar = ':';
-+ /* FALLTHROUGH */
-+ case 16:
-+ inblocksize = 1;
-+ outblocksize = 2;
-+ prefix = "";
-+ format = 'x';
-+ break;
-+ case 's':
-+ inblocksize = 3;
-+ outblocksize = 4;
-+ prefix = "0s";
-+ break;
-+ case 64: /* beware, equals ' ' */
-+ inblocksize = 3;
-+ outblocksize = 4;
-+ prefix = "";
-+ format = 's';
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+ assert(inblocksize < sizeof(inblock));
-+ assert(outblocksize < sizeof(outblock));
-+ assert(breakevery % outblocksize == 0);
-+
-+ if (srclen == 0)
-+ return 0;
-+ ntodo = srclen;
-+
-+ if (dstlen == 0) { /* dispose of awkward special case */
-+ dst = fake;
-+ dstlen = 1;
-+ }
-+ stop = dst + dstlen - 1;
-+
-+ nreal = strlen(prefix);
-+ needed = nreal; /* for starters */
-+ if (dstlen <= nreal) { /* prefix won't fit */
-+ strncpy(dst, prefix, dstlen - 1);
-+ dst += dstlen - 1;
-+ } else {
-+ strcpy(dst, prefix);
-+ dst += nreal;
-+ }
-+ assert(dst <= stop);
-+ sincebreak = 0;
-+
-+ while (ntodo > 0) {
-+ if (ntodo < inblocksize) { /* incomplete input */
-+ memset(inblock, 0, sizeof(inblock));
-+ memcpy(inblock, src, ntodo);
-+ src = inblock;
-+ nreal = ntodo;
-+ ntodo = inblocksize;
-+ } else
-+ nreal = inblocksize;
-+ out = (outblocksize > stop - dst) ? outblock : dst;
-+
-+ convert(src, nreal, format, out);
-+ needed += outblocksize;
-+ sincebreak += outblocksize;
-+ if (dst < stop) {
-+ if (out != dst) {
-+ assert(outblocksize > stop - dst);
-+ memcpy(dst, out, stop - dst);
-+ dst = stop;
-+ } else
-+ dst += outblocksize;
-+ }
-+
-+ src += inblocksize;
-+ ntodo -= inblocksize;
-+ if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) {
-+ if (dst < stop)
-+ *dst++ = breakchar;
-+ needed++;
-+ sincebreak = 0;
-+ }
-+ }
-+
-+ assert(dst <= stop);
-+ *dst++ = '\0';
-+ needed++;
-+
-+ return needed;
-+}
-+
-+/*
-+ - convert - convert one input block to one output block
-+ */
-+static void
-+convert(src, nreal, format, out)
-+const char *src;
-+size_t nreal; /* how much of the input block is real */
-+int format;
-+char *out;
-+{
-+ static char hex[] = "0123456789abcdef";
-+ static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-+ "abcdefghijklmnopqrstuvwxyz"
-+ "0123456789+/";
-+ unsigned char c;
-+ unsigned char c1, c2, c3;
-+
-+ assert(nreal > 0);
-+ switch (format) {
-+ case 'x':
-+ assert(nreal == 1);
-+ c = (unsigned char)*src;
-+ *out++ = hex[c >> 4];
-+ *out++ = hex[c & 0xf];
-+ break;
-+ case 's':
-+ c1 = (unsigned char)*src++;
-+ c2 = (unsigned char)*src++;
-+ c3 = (unsigned char)*src++;
-+ *out++ = base64[c1 >> 2]; /* top 6 bits of c1 */
-+ c = (c1 & 0x3) << 4; /* bottom 2 of c1... */
-+ c |= c2 >> 4; /* ...top 4 of c2 */
-+ *out++ = base64[c];
-+ if (nreal == 1)
-+ *out++ = '=';
-+ else {
-+ c = (c2 & 0xf) << 2; /* bottom 4 of c2... */
-+ c |= c3 >> 6; /* ...top 2 of c3 */
-+ *out++ = base64[c];
-+ }
-+ if (nreal <= 2)
-+ *out++ = '=';
-+ else
-+ *out++ = base64[c3 & 0x3f]; /* bottom 6 of c3 */
-+ break;
-+ default:
-+ assert(nreal == 0); /* unknown format */
-+ break;
-+ }
-+}
-+
-+/*
-+ - datatoa - convert data to ASCII
-+ * backward-compatibility synonym for datatot
-+ */
-+size_t /* true length (with NUL) for success */
-+datatoa(src, srclen, format, dst, dstlen)
-+const char *src;
-+size_t srclen;
-+int format; /* character indicating what format */
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ return datatot(src, srclen, format, dst, dstlen);
-+}
-+
-+/*
-+ - bytestoa - convert data bytes to ASCII
-+ * backward-compatibility synonym for datatot
-+ */
-+size_t /* true length (with NUL) for success */
-+bytestoa(src, srclen, format, dst, dstlen)
-+const char *src;
-+size_t srclen;
-+int format; /* character indicating what format */
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ return datatot(src, srclen, format, dst, dstlen);
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/goodmask.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,100 @@
-+/*
-+ * minor utilities for subnet-mask manipulation
-+ * Copyright (C) 1998, 1999 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+#ifndef ABITS
-+#define ABITS 32 /* bits in an IPv4 address */
-+#endif
-+
-+/*
-+ - goodmask - is this a good (^1*0*$) subnet mask?
-+ * You are not expected to understand this. See Henry S. Warren Jr,
-+ * "Functions realizable with word-parallel logical and two's-complement
-+ * addition instructions", CACM 20.6 (June 1977), p.439.
-+ */
-+int /* predicate */
-+goodmask(mask)
-+struct in_addr mask;
-+{
-+ unsigned long x = ntohl(mask.s_addr);
-+ /* clear rightmost contiguous string of 1-bits */
-+# define CRCS1B(x) (((x|(x-1))+1)&x)
-+# define TOPBIT (1UL << 31)
-+
-+ /* either zero, or has one string of 1-bits which is left-justified */
-+ if (x == 0 || (CRCS1B(x) == 0 && (x&TOPBIT)))
-+ return 1;
-+ return 0;
-+}
-+
-+/*
-+ - masktobits - how many bits in this mask?
-+ * The algorithm is essentially a binary search, but highly optimized
-+ * for this particular task.
-+ */
-+int /* -1 means !goodmask() */
-+masktobits(mask)
-+struct in_addr mask;
-+{
-+ unsigned long m = ntohl(mask.s_addr);
-+ int masklen;
-+
-+ if (!goodmask(mask))
-+ return -1;
-+
-+ if (m&0x00000001UL)
-+ return 32;
-+ masklen = 0;
-+ if (m&(0x0000ffffUL<<1)) { /* <<1 for 1-origin numbering */
-+ masklen |= 0x10;
-+ m <<= 16;
-+ }
-+ if (m&(0x00ff0000UL<<1)) {
-+ masklen |= 0x08;
-+ m <<= 8;
-+ }
-+ if (m&(0x0f000000UL<<1)) {
-+ masklen |= 0x04;
-+ m <<= 4;
-+ }
-+ if (m&(0x30000000UL<<1)) {
-+ masklen |= 0x02;
-+ m <<= 2;
-+ }
-+ if (m&(0x40000000UL<<1))
-+ masklen |= 0x01;
-+
-+ return masklen;
-+}
-+
-+/*
-+ - bitstomask - return a mask with this many high bits on
-+ */
-+struct in_addr
-+bitstomask(n)
-+int n;
-+{
-+ struct in_addr result;
-+
-+ if (n > 0 && n <= ABITS)
-+ result.s_addr = htonl(~((1UL << (ABITS - n)) - 1));
-+ else if (n == 0)
-+ result.s_addr = 0;
-+ else
-+ result.s_addr = 0; /* best error report we can do */
-+ return result;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/initaddr.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,50 @@
-+/*
-+ * initialize address structure
-+ * Copyright (C) 2000 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/*
-+ - initaddr - initialize ip_address from bytes
-+ */
-+err_t /* NULL for success, else string literal */
-+initaddr(src, srclen, af, dst)
-+const unsigned char *src;
-+size_t srclen;
-+int af; /* address family */
-+ip_address *dst;
-+{
-+ switch (af) {
-+ case AF_INET:
-+ if (srclen != 4)
-+ return "IPv4 address must be exactly 4 bytes";
-+ dst->u.v4.sin_family = af;
-+ dst->u.v4.sin_port = 0; /* unused */
-+ memcpy((char *)&dst->u.v4.sin_addr.s_addr, src, srclen);
-+ break;
-+ case AF_INET6:
-+ if (srclen != 16)
-+ return "IPv6 address must be exactly 16 bytes";
-+ dst->u.v6.sin6_family = af;
-+ dst->u.v6.sin6_flowinfo = 0; /* unused */
-+ dst->u.v6.sin6_port = 0; /* unused */
-+ memcpy((char *)&dst->u.v6.sin6_addr, src, srclen);
-+ break;
-+ default:
-+ return "unknown address family in initaddr";
-+ break;
-+ }
-+ return NULL;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/pfkey_v2_build.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1559 @@
-+/*
-+ * RFC2367 PF_KEYv2 Key management API message parser
-+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
-+ */
-+
-+char pfkey_v2_build_c_version[] = "$Id$";
-+
-+/*
-+ * Some ugly stuff to allow consistent debugging code for use in the
-+ * kernel and in user space
-+*/
-+
-+#ifdef __KERNEL__
-+
-+# include <linux/kernel.h> /* for printk */
-+
-+# include "openswan/ipsec_kversion.h" /* for malloc switch */
-+# ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+# else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+# endif /* MALLOC_SLAB */
-+# include <linux/errno.h> /* error codes */
-+# include <linux/types.h> /* size_t */
-+# include <linux/interrupt.h> /* mark_bh */
-+
-+# include <linux/netdevice.h> /* struct device, and other headers */
-+# include <linux/etherdevice.h> /* eth_type_trans */
-+# include <linux/ip.h> /* struct iphdr */
-+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+# include <linux/ipv6.h> /* struct ipv6hdr */
-+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
-+
-+# define MALLOC(size) kmalloc(size, GFP_ATOMIC)
-+# define FREE(obj) kfree(obj)
-+# include <openswan.h>
-+#else /* __KERNEL__ */
-+
-+# include <sys/types.h>
-+# include <linux/types.h>
-+# include <linux/errno.h>
-+# include <malloc.h>
-+# include <string.h> /* memset */
-+
-+# include <openswan.h>
-+
-+#endif /* __KERNEL__ */
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#ifdef __KERNEL__
-+#include "openswan/radij.h" /* rd_nodes */
-+#include "openswan/ipsec_encap.h" /* sockaddr_encap */
-+#endif /* __KERNEL__ */
-+
-+
-+#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
-+#include "openswan/pfkey_debug.h"
-+
-+
-+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
-+
-+void
-+pfkey_extensions_init(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
-+{
-+ int i;
-+
-+ for (i = 0; i != SADB_EXT_MAX + 1; i++) {
-+ extensions[i] = NULL;
-+ }
-+}
-+
-+void
-+pfkey_extensions_free(struct sadb_ext *extensions[SADB_EXT_MAX + 1])
-+{
-+ int i;
-+
-+ if(!extensions) {
-+ return;
-+ }
-+
-+ if(extensions[0]) {
-+ memset(extensions[0], 0, sizeof(struct sadb_msg));
-+ FREE(extensions[0]);
-+ extensions[0] = NULL;
-+ }
-+
-+ for (i = 1; i != SADB_EXT_MAX + 1; i++) {
-+ if(extensions[i]) {
-+ memset(extensions[i], 0, extensions[i]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
-+ FREE(extensions[i]);
-+ extensions[i] = NULL;
-+ }
-+ }
-+}
-+
-+void
-+pfkey_msg_free(struct sadb_msg **pfkey_msg)
-+{
-+ if(*pfkey_msg) {
-+ memset(*pfkey_msg, 0, (*pfkey_msg)->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
-+ FREE(*pfkey_msg);
-+ *pfkey_msg = NULL;
-+ }
-+}
-+
-+/* Default extension builders taken from the KLIPS code */
-+
-+int
-+pfkey_msg_hdr_build(struct sadb_ext** pfkey_ext,
-+ uint8_t msg_type,
-+ uint8_t satype,
-+ uint8_t msg_errno,
-+ uint32_t seq,
-+ uint32_t pid)
-+{
-+ int error = 0;
-+ struct sadb_msg *pfkey_msg = (struct sadb_msg *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_hdr_build:\n");
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_hdr_build: "
-+ "on_entry &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
-+ &pfkey_ext,
-+ pfkey_ext,
-+ *pfkey_ext);
-+ /* sanity checks... */
-+ if(pfkey_msg) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_hdr_build: "
-+ "why is pfkey_msg already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!msg_type) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_hdr_build: "
-+ "msg type not set, must be non-zero..\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(msg_type > SADB_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_hdr_build: "
-+ "msg type too large:%d.\n",
-+ msg_type);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(satype > SADB_SATYPE_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_hdr_build: "
-+ "satype %d > max %d\n",
-+ satype, SADB_SATYPE_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_msg = (struct sadb_msg*)
-+ MALLOC(sizeof(struct sadb_msg)))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_hdr_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_msg, 0, sizeof(struct sadb_msg));
-+
-+ pfkey_msg->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
-+
-+ pfkey_msg->sadb_msg_type = msg_type;
-+ pfkey_msg->sadb_msg_satype = satype;
-+
-+ pfkey_msg->sadb_msg_version = PF_KEY_V2;
-+ pfkey_msg->sadb_msg_errno = msg_errno;
-+ pfkey_msg->sadb_msg_reserved = 0;
-+ pfkey_msg->sadb_msg_seq = seq;
-+ pfkey_msg->sadb_msg_pid = pid;
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_hdr_build: "
-+ "on_exit &pfkey_ext=0p%p pfkey_ext=0p%p *pfkey_ext=0p%p.\n",
-+ &pfkey_ext,
-+ pfkey_ext,
-+ *pfkey_ext);
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_sa_ref_build(struct sadb_ext ** pfkey_ext,
-+ uint16_t exttype,
-+ uint32_t spi,
-+ uint8_t replay_window,
-+ uint8_t sa_state,
-+ uint8_t auth,
-+ uint8_t encrypt,
-+ uint32_t flags,
-+ uint32_t/*IPsecSAref_t*/ ref)
-+{
-+ int error = 0;
-+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "spi=%08x replay=%d sa_state=%d auth=%d encrypt=%d flags=%d\n",
-+ ntohl(spi), /* in network order */
-+ replay_window,
-+ sa_state,
-+ auth,
-+ encrypt,
-+ flags);
-+ /* sanity checks... */
-+ if(pfkey_sa) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "why is pfkey_sa already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(exttype != SADB_EXT_SA &&
-+ exttype != SADB_X_EXT_SA2) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "invalid exttype=%d.\n",
-+ exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(replay_window > 64) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "replay window size: %d -- must be 0 <= size <= 64\n",
-+ replay_window);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(auth > SADB_AALG_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "auth=%d > SADB_AALG_MAX=%d.\n",
-+ auth,
-+ SADB_AALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(encrypt > SADB_EALG_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "encrypt=%d > SADB_EALG_MAX=%d.\n",
-+ encrypt,
-+ SADB_EALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(sa_state > SADB_SASTATE_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "sa_state=%d exceeds MAX=%d.\n",
-+ sa_state,
-+ SADB_SASTATE_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(sa_state == SADB_SASTATE_DEAD) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "sa_state=%d is DEAD=%d is not allowed.\n",
-+ sa_state,
-+ SADB_SASTATE_DEAD);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if((IPSEC_SAREF_NULL != ref) && (ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
-+ ref,
-+ IPSEC_SAREF_NULL,
-+ IPSEC_SA_REF_TABLE_NUM_ENTRIES);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_sa = (struct sadb_sa*)
-+ MALLOC(sizeof(struct sadb_sa)))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sa_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_sa, 0, sizeof(struct sadb_sa));
-+
-+ pfkey_sa->sadb_sa_len = sizeof(*pfkey_sa) / IPSEC_PFKEYv2_ALIGN;
-+ pfkey_sa->sadb_sa_exttype = exttype;
-+ pfkey_sa->sadb_sa_spi = spi;
-+ pfkey_sa->sadb_sa_replay = replay_window;
-+ pfkey_sa->sadb_sa_state = sa_state;
-+ pfkey_sa->sadb_sa_auth = auth;
-+ pfkey_sa->sadb_sa_encrypt = encrypt;
-+ pfkey_sa->sadb_sa_flags = flags;
-+ pfkey_sa->sadb_x_sa_ref = ref;
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_sa_build(struct sadb_ext ** pfkey_ext,
-+ uint16_t exttype,
-+ uint32_t spi,
-+ uint8_t replay_window,
-+ uint8_t sa_state,
-+ uint8_t auth,
-+ uint8_t encrypt,
-+ uint32_t flags)
-+{
-+ return pfkey_sa_ref_build(pfkey_ext,
-+ exttype,
-+ spi,
-+ replay_window,
-+ sa_state,
-+ auth,
-+ encrypt,
-+ flags,
-+ IPSEC_SAREF_NULL);
-+}
-+
-+int
-+pfkey_lifetime_build(struct sadb_ext ** pfkey_ext,
-+ uint16_t exttype,
-+ uint32_t allocations,
-+ uint64_t bytes,
-+ uint64_t addtime,
-+ uint64_t usetime,
-+ uint32_t packets)
-+{
-+ int error = 0;
-+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_lifetime_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_lifetime) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_lifetime_build: "
-+ "why is pfkey_lifetime already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(exttype != SADB_EXT_LIFETIME_CURRENT &&
-+ exttype != SADB_EXT_LIFETIME_HARD &&
-+ exttype != SADB_EXT_LIFETIME_SOFT) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_lifetime_build: "
-+ "invalid exttype=%d.\n",
-+ exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_lifetime = (struct sadb_lifetime*)
-+ MALLOC(sizeof(struct sadb_lifetime)))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_lifetime_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_lifetime, 0, sizeof(struct sadb_lifetime));
-+
-+ pfkey_lifetime->sadb_lifetime_len = sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN;
-+ pfkey_lifetime->sadb_lifetime_exttype = exttype;
-+ pfkey_lifetime->sadb_lifetime_allocations = allocations;
-+ pfkey_lifetime->sadb_lifetime_bytes = bytes;
-+ pfkey_lifetime->sadb_lifetime_addtime = addtime;
-+ pfkey_lifetime->sadb_lifetime_usetime = usetime;
-+ pfkey_lifetime->sadb_x_lifetime_packets = packets;
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_address_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint8_t proto,
-+ uint8_t prefixlen,
-+ struct sockaddr* address)
-+{
-+ int error = 0;
-+ int saddr_len = 0;
-+ char ipaddr_txt[ADDRTOT_BUF + 6/*extra for port number*/];
-+ struct sadb_address *pfkey_address = (struct sadb_address *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_address_build: "
-+ "exttype=%d proto=%d prefixlen=%d\n",
-+ exttype,
-+ proto,
-+ prefixlen);
-+ /* sanity checks... */
-+ if(pfkey_address) {
-+ ERROR("pfkey_address_build: "
-+ "why is pfkey_address already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if (!address) {
-+ ERROR("pfkey_address_build: " "address is NULL\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(exttype) {
-+ case SADB_EXT_ADDRESS_SRC:
-+ case SADB_EXT_ADDRESS_DST:
-+ case SADB_EXT_ADDRESS_PROXY:
-+ case SADB_X_EXT_ADDRESS_DST2:
-+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
-+ case SADB_X_EXT_ADDRESS_DST_FLOW:
-+ case SADB_X_EXT_ADDRESS_SRC_MASK:
-+ case SADB_X_EXT_ADDRESS_DST_MASK:
-+#ifdef NAT_TRAVERSAL
-+ case SADB_X_EXT_NAT_T_OA:
-+#endif
-+ break;
-+ default:
-+ ERROR("pfkey_address_build: "
-+ "unrecognised ext_type=%d.\n",
-+ exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(address->sa_family) {
-+ case AF_INET:
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_address_build: "
-+ "found address family AF_INET.\n");
-+ saddr_len = sizeof(struct sockaddr_in);
-+ sprintf(ipaddr_txt, "%d.%d.%d.%d:%d"
-+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 0) & 0xFF
-+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 8) & 0xFF
-+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 16) & 0xFF
-+ , (((struct sockaddr_in*)address)->sin_addr.s_addr >> 24) & 0xFF
-+ , ntohs(((struct sockaddr_in*)address)->sin_port));
-+ break;
-+ case AF_INET6:
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_address_build: "
-+ "found address family AF_INET6.\n");
-+ saddr_len = sizeof(struct sockaddr_in6);
-+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x-%x"
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[0])
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[1])
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[2])
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[3])
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[4])
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[5])
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[6])
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_addr.s6_addr16[7])
-+ , ntohs(((struct sockaddr_in6*)address)->sin6_port));
-+ break;
-+ default:
-+ ERROR("pfkey_address_build: "
-+ "address->sa_family=%d not supported.\n",
-+ address->sa_family);
-+ SENDERR(EPFNOSUPPORT);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_address_build: "
-+ "found address=%s.\n",
-+ ipaddr_txt);
-+ if(prefixlen != 0) {
-+ ERROR("pfkey_address_build: "
-+ "address prefixes not supported yet.\n");
-+ SENDERR(EAFNOSUPPORT); /* not supported yet */
-+ }
-+
-+ /* allocate some memory for the extension */
-+ pfkey_address = (struct sadb_address*)
-+ MALLOC(ALIGN_N(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN));
-+ *pfkey_ext = (struct sadb_ext*)pfkey_address;
-+
-+ if(pfkey_address == NULL ) {
-+ ERROR("pfkey_lifetime_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_address,
-+ 0,
-+ ALIGN_N(sizeof(struct sadb_address) + saddr_len,
-+ IPSEC_PFKEYv2_ALIGN));
-+
-+ pfkey_address->sadb_address_len = DIVUP(sizeof(struct sadb_address) + saddr_len,
-+ IPSEC_PFKEYv2_ALIGN);
-+
-+ pfkey_address->sadb_address_exttype = exttype;
-+ pfkey_address->sadb_address_proto = proto;
-+ pfkey_address->sadb_address_prefixlen = prefixlen;
-+ pfkey_address->sadb_address_reserved = 0;
-+
-+ memcpy((char*)pfkey_address + sizeof(struct sadb_address),
-+ address,
-+ saddr_len);
-+
-+#if 0
-+ for(i = 0; i < sizeof(struct sockaddr_in) - offsetof(struct sockaddr_in, sin_zero); i++) {
-+ pfkey_address_s_ska.sin_zero[i] = 0;
-+ }
-+#endif
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_address_build: "
-+ "successful created len: %d.\n", pfkey_address->sadb_address_len);
-+
-+ errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_key_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint16_t key_bits,
-+ char* key)
-+{
-+ int error = 0;
-+ struct sadb_key *pfkey_key = (struct sadb_key *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_key_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_key) {
-+ ERROR("pfkey_key_build: "
-+ "why is pfkey_key already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!key_bits) {
-+ ERROR("pfkey_key_build: "
-+ "key_bits is zero, it must be non-zero.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if( !((exttype == SADB_EXT_KEY_AUTH) || (exttype == SADB_EXT_KEY_ENCRYPT))) {
-+ ERROR("pfkey_key_build: "
-+ "unsupported extension type=%d.\n",
-+ exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_key = (struct sadb_key*)
-+ MALLOC(sizeof(struct sadb_key) +
-+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN))) {
-+ ERROR("pfkey_key_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_key,
-+ 0,
-+ sizeof(struct sadb_key) +
-+ DIVUP(key_bits, 64) * IPSEC_PFKEYv2_ALIGN);
-+
-+ pfkey_key->sadb_key_len = DIVUP(sizeof(struct sadb_key) * IPSEC_PFKEYv2_ALIGN + key_bits,
-+ 64);
-+ pfkey_key->sadb_key_exttype = exttype;
-+ pfkey_key->sadb_key_bits = key_bits;
-+ pfkey_key->sadb_key_reserved = 0;
-+ memcpy((char*)pfkey_key + sizeof(struct sadb_key),
-+ key,
-+ DIVUP(key_bits, 8));
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_ident_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint16_t ident_type,
-+ uint64_t ident_id,
-+ uint8_t ident_len,
-+ char* ident_string)
-+{
-+ int error = 0;
-+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)*pfkey_ext;
-+ int data_len = ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_ident_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_ident) {
-+ ERROR("pfkey_ident_build: "
-+ "why is pfkey_ident already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if( ! ((exttype == SADB_EXT_IDENTITY_SRC) ||
-+ (exttype == SADB_EXT_IDENTITY_DST))) {
-+ ERROR("pfkey_ident_build: "
-+ "unsupported extension type=%d.\n",
-+ exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if((ident_type == SADB_IDENTTYPE_RESERVED)) {
-+ ERROR("pfkey_ident_build: "
-+ "ident_type must be non-zero.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(ident_type > SADB_IDENTTYPE_MAX) {
-+ ERROR("pfkey_ident_build: "
-+ "identtype=%d out of range.\n",
-+ ident_type);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(((ident_type == SADB_IDENTTYPE_PREFIX) ||
-+ (ident_type == SADB_IDENTTYPE_FQDN)) &&
-+ !ident_string) {
-+ ERROR("pfkey_ident_build: "
-+ "string required to allocate size of extension.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+#if 0
-+ if((ident_type == SADB_IDENTTYPE_USERFQDN) ) {
-+ }
-+#endif
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_ident = (struct sadb_ident*)
-+ MALLOC(ident_len * IPSEC_PFKEYv2_ALIGN))) {
-+ ERROR("pfkey_ident_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_ident, 0, ident_len * IPSEC_PFKEYv2_ALIGN);
-+
-+ pfkey_ident->sadb_ident_len = ident_len;
-+ pfkey_ident->sadb_ident_exttype = exttype;
-+ pfkey_ident->sadb_ident_type = ident_type;
-+ pfkey_ident->sadb_ident_reserved = 0;
-+ pfkey_ident->sadb_ident_id = ident_id;
-+ memcpy((char*)pfkey_ident + sizeof(struct sadb_ident),
-+ ident_string,
-+ data_len);
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_sens_build(struct sadb_ext** pfkey_ext,
-+ uint32_t dpd,
-+ uint8_t sens_level,
-+ uint8_t sens_len,
-+ uint64_t* sens_bitmap,
-+ uint8_t integ_level,
-+ uint8_t integ_len,
-+ uint64_t* integ_bitmap)
-+{
-+ int error = 0;
-+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)*pfkey_ext;
-+ int i;
-+ uint64_t* bitmap;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sens_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_sens) {
-+ ERROR("pfkey_sens_build: "
-+ "why is pfkey_sens already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_sens_build: "
-+ "Sorry, I can't build exttype=%d yet.\n",
-+ (*pfkey_ext)->sadb_ext_type);
-+ SENDERR(EINVAL); /* don't process these yet */
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_sens = (struct sadb_sens*)
-+ MALLOC(sizeof(struct sadb_sens) +
-+ (sens_len + integ_len) * sizeof(uint64_t)))) {
-+ ERROR("pfkey_sens_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_sens,
-+ 0,
-+ sizeof(struct sadb_sens) +
-+ (sens_len + integ_len) * sizeof(uint64_t));
-+
-+ pfkey_sens->sadb_sens_len = (sizeof(struct sadb_sens) +
-+ (sens_len + integ_len) * sizeof(uint64_t)) / IPSEC_PFKEYv2_ALIGN;
-+ pfkey_sens->sadb_sens_exttype = SADB_EXT_SENSITIVITY;
-+ pfkey_sens->sadb_sens_dpd = dpd;
-+ pfkey_sens->sadb_sens_sens_level = sens_level;
-+ pfkey_sens->sadb_sens_sens_len = sens_len;
-+ pfkey_sens->sadb_sens_integ_level = integ_level;
-+ pfkey_sens->sadb_sens_integ_len = integ_len;
-+ pfkey_sens->sadb_sens_reserved = 0;
-+
-+ bitmap = (uint64_t*)((char*)pfkey_ext + sizeof(struct sadb_sens));
-+ for(i = 0; i < sens_len; i++) {
-+ *bitmap = sens_bitmap[i];
-+ bitmap++;
-+ }
-+ for(i = 0; i < integ_len; i++) {
-+ *bitmap = integ_bitmap[i];
-+ bitmap++;
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_prop_build(struct sadb_ext** pfkey_ext,
-+ uint8_t replay,
-+ unsigned int comb_num,
-+ struct sadb_comb* comb)
-+{
-+ int error = 0;
-+ int i;
-+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)*pfkey_ext;
-+ struct sadb_comb *combp;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_prop_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_prop) {
-+ ERROR("pfkey_prop_build: "
-+ "why is pfkey_prop already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_prop = (struct sadb_prop*)
-+ MALLOC(sizeof(struct sadb_prop) +
-+ comb_num * sizeof(struct sadb_comb)))) {
-+ ERROR("pfkey_prop_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_prop,
-+ 0,
-+ sizeof(struct sadb_prop) +
-+ comb_num * sizeof(struct sadb_comb));
-+
-+ pfkey_prop->sadb_prop_len = (sizeof(struct sadb_prop) +
-+ comb_num * sizeof(struct sadb_comb)) / IPSEC_PFKEYv2_ALIGN;
-+
-+ pfkey_prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
-+ pfkey_prop->sadb_prop_replay = replay;
-+
-+ for(i=0; i<3; i++) {
-+ pfkey_prop->sadb_prop_reserved[i] = 0;
-+ }
-+
-+ combp = (struct sadb_comb*)((char*)*pfkey_ext + sizeof(struct sadb_prop));
-+ for(i = 0; i < comb_num; i++) {
-+ memcpy (combp, &(comb[i]), sizeof(struct sadb_comb));
-+ combp++;
-+ }
-+
-+#if 0
-+ uint8_t sadb_comb_auth;
-+ uint8_t sadb_comb_encrypt;
-+ uint16_t sadb_comb_flags;
-+ uint16_t sadb_comb_auth_minbits;
-+ uint16_t sadb_comb_auth_maxbits;
-+ uint16_t sadb_comb_encrypt_minbits;
-+ uint16_t sadb_comb_encrypt_maxbits;
-+ uint32_t sadb_comb_reserved;
-+ uint32_t sadb_comb_soft_allocations;
-+ uint32_t sadb_comb_hard_allocations;
-+ uint64_t sadb_comb_soft_bytes;
-+ uint64_t sadb_comb_hard_bytes;
-+ uint64_t sadb_comb_soft_addtime;
-+ uint64_t sadb_comb_hard_addtime;
-+ uint64_t sadb_comb_soft_usetime;
-+ uint64_t sadb_comb_hard_usetime;
-+ uint32_t sadb_comb_soft_packets;
-+ uint32_t sadb_comb_hard_packets;
-+#endif
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_supported_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ unsigned int alg_num,
-+ struct sadb_alg* alg)
-+{
-+ int error = 0;
-+ unsigned int i;
-+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)*pfkey_ext;
-+ struct sadb_alg *pfkey_alg;
-+
-+ /* sanity checks... */
-+ if(pfkey_supported) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_supported_build: "
-+ "why is pfkey_supported already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if( !((exttype == SADB_EXT_SUPPORTED_AUTH) || (exttype == SADB_EXT_SUPPORTED_ENCRYPT))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_supported_build: "
-+ "unsupported extension type=%d.\n",
-+ exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_supported = (struct sadb_supported*)
-+ MALLOC(sizeof(struct sadb_supported) +
-+ alg_num *
-+ sizeof(struct sadb_alg)))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_supported_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_supported,
-+ 0,
-+ sizeof(struct sadb_supported) +
-+ alg_num *
-+ sizeof(struct sadb_alg));
-+
-+ pfkey_supported->sadb_supported_len = (sizeof(struct sadb_supported) +
-+ alg_num *
-+ sizeof(struct sadb_alg)) /
-+ IPSEC_PFKEYv2_ALIGN;
-+ pfkey_supported->sadb_supported_exttype = exttype;
-+ pfkey_supported->sadb_supported_reserved = 0;
-+
-+ pfkey_alg = (struct sadb_alg*)((char*)pfkey_supported + sizeof(struct sadb_supported));
-+ for(i = 0; i < alg_num; i++) {
-+ memcpy (pfkey_alg, &(alg[i]), sizeof(struct sadb_alg));
-+ pfkey_alg->sadb_alg_reserved = 0;
-+ pfkey_alg++;
-+ }
-+
-+#if 0
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_supported_build: "
-+ "Sorry, I can't build exttype=%d yet.\n",
-+ (*pfkey_ext)->sadb_ext_type);
-+ SENDERR(EINVAL); /* don't process these yet */
-+
-+ uint8_t sadb_alg_id;
-+ uint8_t sadb_alg_ivlen;
-+ uint16_t sadb_alg_minbits;
-+ uint16_t sadb_alg_maxbits;
-+ uint16_t sadb_alg_reserved;
-+#endif
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_spirange_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint32_t min, /* in network order */
-+ uint32_t max) /* in network order */
-+{
-+ int error = 0;
-+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)*pfkey_ext;
-+
-+ /* sanity checks... */
-+ if(pfkey_spirange) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_spirange_build: "
-+ "why is pfkey_spirange already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(ntohl(max) < ntohl(min)) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_spirange_build: "
-+ "minspi=%08x must be < maxspi=%08x.\n",
-+ ntohl(min),
-+ ntohl(max));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(ntohl(min) <= 255) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_spirange_build: "
-+ "minspi=%08x must be > 255.\n",
-+ ntohl(min));
-+ SENDERR(EEXIST);
-+ }
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_spirange = (struct sadb_spirange*)
-+ MALLOC(sizeof(struct sadb_spirange)))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_spirange_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_spirange,
-+ 0,
-+ sizeof(struct sadb_spirange));
-+
-+ pfkey_spirange->sadb_spirange_len = sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN;
-+
-+ pfkey_spirange->sadb_spirange_exttype = SADB_EXT_SPIRANGE;
-+ pfkey_spirange->sadb_spirange_min = min;
-+ pfkey_spirange->sadb_spirange_max = max;
-+ pfkey_spirange->sadb_spirange_reserved = 0;
-+ errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_x_kmprivate_build(struct sadb_ext** pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)*pfkey_ext;
-+
-+ /* sanity checks... */
-+ if(pfkey_x_kmprivate) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_kmprivate_build: "
-+ "why is pfkey_x_kmprivate already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_kmprivate_build: "
-+ "Sorry, I can't build exttype=%d yet.\n",
-+ (*pfkey_ext)->sadb_ext_type);
-+ SENDERR(EINVAL); /* don't process these yet */
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)
-+ pfkey_x_kmprivate = (struct sadb_x_kmprivate*)
-+ MALLOC(sizeof(struct sadb_x_kmprivate)))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_kmprivate_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_x_kmprivate,
-+ 0,
-+ sizeof(struct sadb_x_kmprivate));
-+
-+ pfkey_x_kmprivate->sadb_x_kmprivate_len =
-+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN;
-+
-+ pfkey_x_kmprivate->sadb_x_kmprivate_exttype = SADB_X_EXT_KMPRIVATE;
-+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved = 0;
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_x_satype_build(struct sadb_ext** pfkey_ext,
-+ uint8_t satype)
-+{
-+ int error = 0;
-+ int i;
-+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_satype_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_x_satype) {
-+ ERROR("pfkey_x_satype_build: "
-+ "why is pfkey_x_satype already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!satype) {
-+ ERROR("pfkey_x_satype_build: "
-+ "SA type not set, must be non-zero.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(satype > SADB_SATYPE_MAX) {
-+ ERROR("pfkey_x_satype_build: "
-+ "satype %d > max %d\n",
-+ satype, SADB_SATYPE_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_satype = (struct sadb_x_satype*)
-+ MALLOC(sizeof(struct sadb_x_satype)))) {
-+ ERROR("pfkey_x_satype_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ memset(pfkey_x_satype,
-+ 0,
-+ sizeof(struct sadb_x_satype));
-+
-+ pfkey_x_satype->sadb_x_satype_len = sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN;
-+
-+ pfkey_x_satype->sadb_x_satype_exttype = SADB_X_EXT_SATYPE2;
-+ pfkey_x_satype->sadb_x_satype_satype = satype;
-+ for(i=0; i<3; i++) {
-+ pfkey_x_satype->sadb_x_satype_reserved[i] = 0;
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_x_debug_build(struct sadb_ext** pfkey_ext,
-+ uint32_t tunnel,
-+ uint32_t netlink,
-+ uint32_t xform,
-+ uint32_t eroute,
-+ uint32_t spi,
-+ uint32_t radij,
-+ uint32_t esp,
-+ uint32_t ah,
-+ uint32_t rcv,
-+ uint32_t pfkey,
-+ uint32_t ipcomp,
-+ uint32_t verbose)
-+{
-+ int error = 0;
-+ int i;
-+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_debug_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_x_debug) {
-+ ERROR("pfkey_x_debug_build: "
-+ "why is pfkey_x_debug already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_debug_build: "
-+ "tunnel=%x netlink=%x xform=%x eroute=%x spi=%x radij=%x esp=%x ah=%x rcv=%x pfkey=%x ipcomp=%x verbose=%x?\n",
-+ tunnel, netlink, xform, eroute, spi, radij, esp, ah, rcv, pfkey, ipcomp, verbose);
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_debug = (struct sadb_x_debug*)
-+ MALLOC(sizeof(struct sadb_x_debug)))) {
-+ ERROR("pfkey_x_debug_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+#if 0
-+ memset(pfkey_x_debug,
-+ 0,
-+ sizeof(struct sadb_x_debug));
-+#endif
-+
-+ pfkey_x_debug->sadb_x_debug_len = sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN;
-+ pfkey_x_debug->sadb_x_debug_exttype = SADB_X_EXT_DEBUG;
-+
-+ pfkey_x_debug->sadb_x_debug_tunnel = tunnel;
-+ pfkey_x_debug->sadb_x_debug_netlink = netlink;
-+ pfkey_x_debug->sadb_x_debug_xform = xform;
-+ pfkey_x_debug->sadb_x_debug_eroute = eroute;
-+ pfkey_x_debug->sadb_x_debug_spi = spi;
-+ pfkey_x_debug->sadb_x_debug_radij = radij;
-+ pfkey_x_debug->sadb_x_debug_esp = esp;
-+ pfkey_x_debug->sadb_x_debug_ah = ah;
-+ pfkey_x_debug->sadb_x_debug_rcv = rcv;
-+ pfkey_x_debug->sadb_x_debug_pfkey = pfkey;
-+ pfkey_x_debug->sadb_x_debug_ipcomp = ipcomp;
-+ pfkey_x_debug->sadb_x_debug_verbose = verbose;
-+
-+ for(i=0; i<4; i++) {
-+ pfkey_x_debug->sadb_x_debug_reserved[i] = 0;
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_x_nat_t_type_build(struct sadb_ext** pfkey_ext,
-+ uint8_t type)
-+{
-+ int error = 0;
-+ int i;
-+ struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_nat_t_type_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_x_nat_t_type) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_nat_t_type_build: "
-+ "why is pfkey_x_nat_t_type already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_nat_t_type_build: "
-+ "type=%d\n", type);
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_type = (struct sadb_x_nat_t_type*)
-+ MALLOC(sizeof(struct sadb_x_nat_t_type)))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_nat_t_type_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+
-+ pfkey_x_nat_t_type->sadb_x_nat_t_type_len = sizeof(struct sadb_x_nat_t_type) / IPSEC_PFKEYv2_ALIGN;
-+ pfkey_x_nat_t_type->sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
-+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type = type;
-+ for(i=0; i<3; i++) {
-+ pfkey_x_nat_t_type->sadb_x_nat_t_type_reserved[i] = 0;
-+ }
-+
-+errlab:
-+ return error;
-+}
-+int
-+pfkey_x_nat_t_port_build(struct sadb_ext** pfkey_ext,
-+ uint16_t exttype,
-+ uint16_t port)
-+{
-+ int error = 0;
-+ struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)*pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_nat_t_port_build:\n");
-+ /* sanity checks... */
-+ if(pfkey_x_nat_t_port) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_nat_t_port_build: "
-+ "why is pfkey_x_nat_t_port already pointing to something?\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(exttype) {
-+ case SADB_X_EXT_NAT_T_SPORT:
-+ case SADB_X_EXT_NAT_T_DPORT:
-+ break;
-+ default:
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_nat_t_port_build: "
-+ "unrecognised ext_type=%d.\n",
-+ exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_nat_t_port_build: "
-+ "ext=%d, port=%d\n", exttype, port);
-+
-+ if(!(*pfkey_ext = (struct sadb_ext*)pfkey_x_nat_t_port = (struct sadb_x_nat_t_port*)
-+ MALLOC(sizeof(struct sadb_x_nat_t_port)))) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_x_nat_t_port_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+
-+ pfkey_x_nat_t_port->sadb_x_nat_t_port_len = sizeof(struct sadb_x_nat_t_port) / IPSEC_PFKEYv2_ALIGN;
-+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype = exttype;
-+ pfkey_x_nat_t_port->sadb_x_nat_t_port_port = port;
-+ pfkey_x_nat_t_port->sadb_x_nat_t_port_reserved = 0;
-+
-+errlab:
-+ return error;
-+}
-+
-+int pfkey_x_protocol_build(struct sadb_ext **pfkey_ext,
-+ uint8_t protocol)
-+{
-+ int error = 0;
-+ struct sadb_protocol * p = (struct sadb_protocol *)*pfkey_ext;
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,"pfkey_x_protocol_build: protocol=%u\n", protocol);
-+ /* sanity checks... */
-+ if (p != 0) {
-+ ERROR("pfkey_x_protocol_build: bogus protocol pointer\n");
-+ SENDERR(EINVAL);
-+ }
-+ if ((p = (struct sadb_protocol*)MALLOC(sizeof(*p))) == 0) {
-+ ERROR("pfkey_build: memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+ *pfkey_ext = (struct sadb_ext *)p;
-+ p->sadb_protocol_len = sizeof(*p) / sizeof(uint64_t);
-+ p->sadb_protocol_exttype = SADB_X_EXT_PROTOCOL;
-+ p->sadb_protocol_proto = protocol;
-+ p->sadb_protocol_flags = 0;
-+ p->sadb_protocol_reserved2 = 0;
-+ errlab:
-+ return error;
-+}
-+
-+
-+#if I_DONT_THINK_THIS_WILL_BE_USEFUL
-+int (*ext_default_builders[SADB_EXT_MAX +1])(struct sadb_msg*, struct sadb_ext*)
-+ =
-+{
-+ NULL, /* pfkey_msg_build, */
-+ pfkey_sa_build,
-+ pfkey_lifetime_build,
-+ pfkey_lifetime_build,
-+ pfkey_lifetime_build,
-+ pfkey_address_build,
-+ pfkey_address_build,
-+ pfkey_address_build,
-+ pfkey_key_build,
-+ pfkey_key_build,
-+ pfkey_ident_build,
-+ pfkey_ident_build,
-+ pfkey_sens_build,
-+ pfkey_prop_build,
-+ pfkey_supported_build,
-+ pfkey_supported_build,
-+ pfkey_spirange_build,
-+ pfkey_x_kmprivate_build,
-+ pfkey_x_satype_build,
-+ pfkey_sa_build,
-+ pfkey_address_build,
-+ pfkey_address_build,
-+ pfkey_address_build,
-+ pfkey_address_build,
-+ pfkey_address_build,
-+ pfkey_x_ext_debug_build
-+};
-+#endif
-+
-+int
-+pfkey_msg_build(struct sadb_msg **pfkey_msg, struct sadb_ext *extensions[], int dir)
-+{
-+ int error = 0;
-+ unsigned ext;
-+ unsigned total_size;
-+ struct sadb_ext *pfkey_ext;
-+ int extensions_seen = 0;
-+#ifndef __KERNEL__
-+ struct sadb_ext *extensions_check[SADB_EXT_MAX + 1];
-+#endif
-+
-+ if(!extensions[0]) {
-+ ERROR("pfkey_msg_build: "
-+ "extensions[0] must be specified (struct sadb_msg).\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* figure out the total size for all the requested extensions */
-+ total_size = IPSEC_PFKEYv2_WORDS(sizeof(struct sadb_msg));
-+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
-+ if(extensions[ext]) {
-+ total_size += (extensions[ext])->sadb_ext_len;
-+ }
-+ }
-+
-+ /* allocate that much space */
-+ *pfkey_msg = (struct sadb_msg*)MALLOC(total_size * IPSEC_PFKEYv2_ALIGN);
-+ if(*pfkey_msg == NULL) {
-+ ERROR("pfkey_msg_build: "
-+ "memory allocation failed\n");
-+ SENDERR(ENOMEM);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_build: "
-+ "pfkey_msg=0p%p allocated %lu bytes, &(extensions[0])=0p%p\n",
-+ *pfkey_msg,
-+ (unsigned long)(total_size * IPSEC_PFKEYv2_ALIGN),
-+ &(extensions[0]));
-+
-+ memcpy(*pfkey_msg,
-+ extensions[0],
-+ sizeof(struct sadb_msg));
-+ (*pfkey_msg)->sadb_msg_len = total_size;
-+ (*pfkey_msg)->sadb_msg_reserved = 0;
-+ extensions_seen = 1 ;
-+
-+ /*
-+ * point pfkey_ext to immediately after the space for the header,
-+ * i.e. at the first extension location.
-+ */
-+ pfkey_ext = (struct sadb_ext*)(((char*)(*pfkey_msg)) + sizeof(struct sadb_msg));
-+
-+ for(ext = 1; ext <= SADB_EXT_MAX; ext++) {
-+ /* copy from extension[ext] to buffer */
-+ if(extensions[ext]) {
-+ /* Is this type of extension permitted for this type of message? */
-+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type] &
-+ 1<<ext)) {
-+ ERROR("pfkey_msg_build: "
-+ "ext type %d not permitted, exts_perm=%08x, 1<<type=%08x\n",
-+ ext,
-+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
-+ 1<<ext);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_build: "
-+ "copying %lu bytes from extensions[%u] (type=%d)\n",
-+ (unsigned long)(extensions[ext]->sadb_ext_len * IPSEC_PFKEYv2_ALIGN),
-+ ext,
-+ extensions[ext]->sadb_ext_type);
-+
-+ memcpy(pfkey_ext,
-+ extensions[ext],
-+ (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
-+ ((char*)pfkey_ext) += (extensions[ext])->sadb_ext_len * IPSEC_PFKEYv2_ALIGN;
-+ /* Mark that we have seen this extension and remember the header location */
-+ extensions_seen |= ( 1 << ext );
-+ }
-+ }
-+
-+ /* check required extensions */
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_build: "
-+ "extensions permitted=%08x, seen=%08x, required=%08x.\n",
-+ extensions_bitmaps[dir][EXT_BITS_PERM][(*pfkey_msg)->sadb_msg_type],
-+ extensions_seen,
-+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]);
-+
-+ if((extensions_seen &
-+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) !=
-+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) {
-+ DEBUGGING(PF_KEY_DEBUG_BUILD,
-+ "pfkey_msg_build: "
-+ "required extensions missing:%08x.\n",
-+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type] -
-+ (extensions_seen &
-+ extensions_bitmaps[dir][EXT_BITS_REQ][(*pfkey_msg)->sadb_msg_type]) );
-+ SENDERR(EINVAL);
-+ }
-+
-+#ifndef __KERNEL__
-+/*
-+ * this is silly, there is no need to reparse the message that we just built.
-+ *
-+ */
-+ if((error = pfkey_msg_parse(*pfkey_msg, NULL, extensions_check, dir))) {
-+ ERROR(
-+ "pfkey_msg_build: "
-+ "Trouble parsing newly built pfkey message, error=%d.\n",
-+ error);
-+ SENDERR(-error);
-+ }
-+#endif
-+
-+errlab:
-+
-+ return error;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.49 2004/04/12 02:59:06 mcr
-+ * erroneously moved pfkey_v2_build.c
-+ *
-+ * Revision 1.48 2004/04/09 18:00:40 mcr
-+ * Moved from linux/lib/libfreeswan/pfkey_v2_build.c,v
-+ *
-+ * Revision 1.47 2004/03/08 01:59:08 ken
-+ * freeswan.h -> openswan.h
-+ *
-+ * Revision 1.46 2003/12/10 01:20:19 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.45 2003/12/04 23:01:12 mcr
-+ * removed ipsec_netlink.h
-+ *
-+ * Revision 1.44 2003/10/31 02:27:12 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.43.4.2 2003/10/29 01:11:32 mcr
-+ * added debugging for pfkey library.
-+ *
-+ * Revision 1.43.4.1 2003/09/21 13:59:44 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.43 2003/05/07 17:29:17 mcr
-+ * new function pfkey_debug_func added for us in debugging from
-+ * pfkey library.
-+ *
-+ * Revision 1.42 2003/01/30 02:32:09 rgb
-+ *
-+ * Rename SAref table macro names for clarity.
-+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
-+ *
-+ * Revision 1.41 2002/12/13 18:16:02 mcr
-+ * restored sa_ref code
-+ *
-+ * Revision 1.40 2002/12/13 18:06:52 mcr
-+ * temporarily removed sadb_x_sa_ref reference for 2.xx
-+ *
-+ * Revision 1.39 2002/12/13 17:43:28 mcr
-+ * commented out access to sadb_x_sa_ref for 2.xx branch
-+ *
-+ * Revision 1.38 2002/10/09 03:12:05 dhr
-+ *
-+ * [kenb+dhr] 64-bit fixes
-+ *
-+ * Revision 1.37 2002/09/20 15:40:39 rgb
-+ * Added new function pfkey_sa_ref_build() to accomodate saref parameter.
-+ *
-+ * Revision 1.36 2002/09/20 05:01:22 rgb
-+ * Generalise for platform independance: fix (ia64) using unsigned for sizes.
-+ *
-+ * Revision 1.35 2002/07/24 18:44:54 rgb
-+ * Type fiddling to tame ia64 compiler.
-+ *
-+ * Revision 1.34 2002/05/23 07:14:11 rgb
-+ * Cleaned up %p variants to 0p%p for test suite cleanup.
-+ *
-+ * Revision 1.33 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.32 2002/04/24 07:36:40 mcr
-+ * Moved from ./lib/pfkey_v2_build.c,v
-+ *
-+ * Revision 1.31 2002/01/29 22:25:35 rgb
-+ * Re-add ipsec_kversion.h to keep MALLOC happy.
-+ *
-+ * Revision 1.30 2002/01/29 01:59:09 mcr
-+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
-+ * updating of IPv6 structures to match latest in6.h version.
-+ * removed dead code from openswan.h that also duplicated kversions.h
-+ * code.
-+ *
-+ * Revision 1.29 2001/12/19 21:06:09 rgb
-+ * Added port numbers to pfkey_address_build() debugging.
-+ *
-+ * Revision 1.28 2001/11/06 19:47:47 rgb
-+ * Added packet parameter to lifetime and comb structures.
-+ *
-+ * Revision 1.27 2001/10/18 04:45:24 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/openswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.26 2001/09/08 21:13:34 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.25 2001/06/14 19:35:16 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.24 2001/03/20 03:49:45 rgb
-+ * Ditch superfluous debug_pfkey declaration.
-+ * Move misplaced openswan.h inclusion for kernel case.
-+ *
-+ * Revision 1.23 2001/03/16 07:41:50 rgb
-+ * Put openswan.h include before pluto includes.
-+ *
-+ * Revision 1.22 2001/02/27 22:24:56 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.21 2000/11/17 18:10:30 rgb
-+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
-+ * network byte order since this is the way PF_KEYv2 stored spis.
-+ *
-+ * Revision 1.20 2000/10/12 00:02:39 rgb
-+ * Removed 'format, ##' nonsense from debug macros for RH7.0.
-+ *
-+ * Revision 1.19 2000/10/10 20:10:20 rgb
-+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
-+ *
-+ * Revision 1.18 2000/09/12 18:59:54 rgb
-+ * Added Gerhard's IPv6 support to pfkey parts of libopenswan.
-+ *
-+ * Revision 1.17 2000/09/12 03:27:00 rgb
-+ * Moved DEBUGGING definition to compile kernel with debug off.
-+ *
-+ * Revision 1.16 2000/09/08 19:22:12 rgb
-+ * Fixed pfkey_prop_build() parameter to be only single indirection.
-+ * Fixed struct alg copy.
-+ *
-+ * Revision 1.15 2000/08/20 21:40:01 rgb
-+ * Added an address parameter sanity check to pfkey_address_build().
-+ *
-+ * Revision 1.14 2000/08/15 17:29:23 rgb
-+ * Fixes from SZI to untested pfkey_prop_build().
-+ *
-+ * Revision 1.13 2000/06/02 22:54:14 rgb
-+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
-+ *
-+ * Revision 1.12 2000/05/10 19:24:01 rgb
-+ * Fleshed out sensitivity, proposal and supported extensions.
-+ *
-+ * Revision 1.11 2000/03/16 14:07:23 rgb
-+ * Renamed ALIGN macro to avoid fighting with others in kernel.
-+ *
-+ * Revision 1.10 2000/01/24 21:14:35 rgb
-+ * Added disabled pluto pfkey lib debug flag.
-+ *
-+ * Revision 1.9 2000/01/21 06:27:32 rgb
-+ * Added address cases for eroute flows.
-+ * Removed unused code.
-+ * Dropped unused argument to pfkey_x_satype_build().
-+ * Indented compiler directives for readability.
-+ * Added klipsdebug switching capability.
-+ * Fixed SADB_EXT_MAX bug not permitting last extension access.
-+ *
-+ * Revision 1.8 1999/12/29 21:17:41 rgb
-+ * Changed pfkey_msg_build() I/F to include a struct sadb_msg**
-+ * parameter for cleaner manipulation of extensions[] and to guard
-+ * against potential memory leaks.
-+ * Changed the I/F to pfkey_msg_free() for the same reason.
-+ *
-+ * Revision 1.7 1999/12/09 23:12:20 rgb
-+ * Removed unused cruft.
-+ * Added argument to pfkey_sa_build() to do eroutes.
-+ * Fixed exttype check in as yet unused pfkey_lifetime_build().
-+ *
-+ * Revision 1.6 1999/12/07 19:54:29 rgb
-+ * Removed static pluto debug flag.
-+ * Added functions for pfkey message and extensions initialisation
-+ * and cleanup.
-+ *
-+ * Revision 1.5 1999/12/01 22:20:06 rgb
-+ * Changed pfkey_sa_build to accept an SPI in network byte order.
-+ * Added <string.h> to quiet userspace compiler.
-+ * Moved pfkey_lib_debug variable into the library.
-+ * Removed SATYPE check from pfkey_msg_hdr_build so FLUSH will work.
-+ * Added extension assembly debugging.
-+ * Isolated assignment with brackets to be sure of scope.
-+ *
-+ * Revision 1.4 1999/11/27 11:57:35 rgb
-+ * Added ipv6 headers.
-+ * Remove over-zealous algorithm sanity checkers from pfkey_sa_build.
-+ * Debugging error messages added.
-+ * Fixed missing auth and encrypt assignment bug.
-+ * Add argument to pfkey_msg_parse() for direction.
-+ * Move parse-after-build check inside pfkey_msg_build().
-+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
-+ * Add CVS log entry to bottom of file.
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/pfkey_v2_debug.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,176 @@
-+/*
-+ * @(#) pfkey version 2 debugging messages
-+ *
-+ * Copyright (C) 2001 Richard Guy Briggs <rgb@openswan.org>
-+ * and Michael Richardson <mcr@openswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ */
-+
-+#ifdef __KERNEL__
-+
-+# include <linux/kernel.h> /* for printk */
-+
-+# include "openswan/ipsec_kversion.h" /* for malloc switch */
-+# ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+# else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+# endif /* MALLOC_SLAB */
-+# include <linux/errno.h> /* error codes */
-+# include <linux/types.h> /* size_t */
-+# include <linux/interrupt.h> /* mark_bh */
-+
-+# include <linux/netdevice.h> /* struct device, and other headers */
-+# include <linux/etherdevice.h> /* eth_type_trans */
-+extern int debug_pfkey;
-+
-+#else /* __KERNEL__ */
-+
-+# include <sys/types.h>
-+# include <linux/types.h>
-+# include <linux/errno.h>
-+
-+#endif /* __KERNEL__ */
-+
-+#include "openswan.h"
-+#include "pfkeyv2.h"
-+#include "pfkey.h"
-+
-+/*
-+ * This file provides ASCII translations of PF_KEY magic numbers.
-+ *
-+ */
-+
-+static char *pfkey_sadb_ext_strings[]={
-+ "reserved", /* SADB_EXT_RESERVED 0 */
-+ "security-association", /* SADB_EXT_SA 1 */
-+ "lifetime-current", /* SADB_EXT_LIFETIME_CURRENT 2 */
-+ "lifetime-hard", /* SADB_EXT_LIFETIME_HARD 3 */
-+ "lifetime-soft", /* SADB_EXT_LIFETIME_SOFT 4 */
-+ "source-address", /* SADB_EXT_ADDRESS_SRC 5 */
-+ "destination-address", /* SADB_EXT_ADDRESS_DST 6 */
-+ "proxy-address", /* SADB_EXT_ADDRESS_PROXY 7 */
-+ "authentication-key", /* SADB_EXT_KEY_AUTH 8 */
-+ "cipher-key", /* SADB_EXT_KEY_ENCRYPT 9 */
-+ "source-identity", /* SADB_EXT_IDENTITY_SRC 10 */
-+ "destination-identity", /* SADB_EXT_IDENTITY_DST 11 */
-+ "sensitivity-label", /* SADB_EXT_SENSITIVITY 12 */
-+ "proposal", /* SADB_EXT_PROPOSAL 13 */
-+ "supported-auth", /* SADB_EXT_SUPPORTED_AUTH 14 */
-+ "supported-cipher", /* SADB_EXT_SUPPORTED_ENCRYPT 15 */
-+ "spi-range", /* SADB_EXT_SPIRANGE 16 */
-+ "X-kmpprivate", /* SADB_X_EXT_KMPRIVATE 17 */
-+ "X-satype2", /* SADB_X_EXT_SATYPE2 18 */
-+ "X-security-association", /* SADB_X_EXT_SA2 19 */
-+ "X-destination-address2", /* SADB_X_EXT_ADDRESS_DST2 20 */
-+ "X-source-flow-address", /* SADB_X_EXT_ADDRESS_SRC_FLOW 21 */
-+ "X-dest-flow-address", /* SADB_X_EXT_ADDRESS_DST_FLOW 22 */
-+ "X-source-mask", /* SADB_X_EXT_ADDRESS_SRC_MASK 23 */
-+ "X-dest-mask", /* SADB_X_EXT_ADDRESS_DST_MASK 24 */
-+ "X-set-debug", /* SADB_X_EXT_DEBUG 25 */
-+#ifdef NAT_TRAVERSAL
-+ "X-NAT-T-type", /* SADB_X_EXT_NAT_T_TYPE 26 */
-+ "X-NAT-T-sport", /* SADB_X_EXT_NAT_T_SPORT 27 */
-+ "X-NAT-T-dport", /* SADB_X_EXT_NAT_T_DPORT 28 */
-+ "X-NAT-T-OA", /* SADB_X_EXT_NAT_T_OA 29 */
-+#endif
-+};
-+
-+const char *
-+pfkey_v2_sadb_ext_string(int ext)
-+{
-+ if(ext <= SADB_EXT_MAX) {
-+ return pfkey_sadb_ext_strings[ext];
-+ } else {
-+ return "unknown-ext";
-+ }
-+}
-+
-+
-+static char *pfkey_sadb_type_strings[]={
-+ "reserved", /* SADB_RESERVED */
-+ "getspi", /* SADB_GETSPI */
-+ "update", /* SADB_UPDATE */
-+ "add", /* SADB_ADD */
-+ "delete", /* SADB_DELETE */
-+ "get", /* SADB_GET */
-+ "acquire", /* SADB_ACQUIRE */
-+ "register", /* SADB_REGISTER */
-+ "expire", /* SADB_EXPIRE */
-+ "flush", /* SADB_FLUSH */
-+ "dump", /* SADB_DUMP */
-+ "x-promisc", /* SADB_X_PROMISC */
-+ "x-pchange", /* SADB_X_PCHANGE */
-+ "x-groupsa", /* SADB_X_GRPSA */
-+ "x-addflow(eroute)", /* SADB_X_ADDFLOW */
-+ "x-delflow(eroute)", /* SADB_X_DELFLOW */
-+ "x-debug", /* SADB_X_DEBUG */
-+};
-+
-+const char *
-+pfkey_v2_sadb_type_string(int sadb_type)
-+{
-+ if(sadb_type <= SADB_MAX) {
-+ return pfkey_sadb_type_strings[sadb_type];
-+ } else {
-+ return "unknown-sadb-type";
-+ }
-+}
-+
-+
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.9 2004/03/08 01:59:08 ken
-+ * freeswan.h -> openswan.h
-+ *
-+ * Revision 1.8 2003/12/10 01:20:19 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.7 2002/09/20 05:01:26 rgb
-+ * Fixed limit inclusion error in both type and ext string conversion.
-+ *
-+ * Revision 1.6 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.5 2002/04/24 07:36:40 mcr
-+ * Moved from ./lib/pfkey_v2_debug.c,v
-+ *
-+ * Revision 1.4 2002/01/29 22:25:36 rgb
-+ * Re-add ipsec_kversion.h to keep MALLOC happy.
-+ *
-+ * Revision 1.3 2002/01/29 01:59:09 mcr
-+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
-+ * updating of IPv6 structures to match latest in6.h version.
-+ * removed dead code from openswan.h that also duplicated kversions.h
-+ * code.
-+ *
-+ * Revision 1.2 2002/01/20 20:34:50 mcr
-+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
-+ *
-+ * Revision 1.1 2001/11/27 05:30:06 mcr
-+ * initial set of debug strings for pfkey debugging.
-+ * this will eventually only be included for debug builds.
-+ *
-+ * Revision 1.1 2001/09/21 04:12:03 mcr
-+ * first compilable version.
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/pfkey_v2_ext_bits.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,808 @@
-+/*
-+ * RFC2367 PF_KEYv2 Key management API message parser
-+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * Template from klips/net/ipsec/ipsec/ipsec_parse.c.
-+ */
-+
-+char pfkey_v2_ext_bits_c_version[] = "$Id$";
-+
-+/*
-+ * Some ugly stuff to allow consistent debugging code for use in the
-+ * kernel and in user space
-+*/
-+
-+#ifdef __KERNEL__
-+
-+# include <linux/kernel.h> /* for printk */
-+
-+# include "openswan/ipsec_kversion.h" /* for malloc switch */
-+# ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+# else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+# endif /* MALLOC_SLAB */
-+# include <linux/errno.h> /* error codes */
-+# include <linux/types.h> /* size_t */
-+# include <linux/interrupt.h> /* mark_bh */
-+
-+# include <linux/netdevice.h> /* struct device, and other headers */
-+# include <linux/etherdevice.h> /* eth_type_trans */
-+# include <linux/ip.h> /* struct iphdr */
-+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+# include <linux/ipv6.h>
-+# endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
-+
-+#else /* __KERNEL__ */
-+
-+# include <sys/types.h>
-+# include <linux/types.h>
-+# include <linux/errno.h>
-+#endif
-+
-+#include <openswan.h>
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+unsigned int extensions_bitmaps[2/*in/out*/][2/*perm/req*/][SADB_MAX + 1/*ext*/] = {
-+
-+/* INBOUND EXTENSIONS */
-+{
-+
-+/* PERMITTED IN */
-+{
-+/* SADB_RESERVED */
-+0
-+,
-+/* SADB_GETSPI */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_SPIRANGE
-+,
-+/* SADB_UPDATE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+,
-+/* SADB_ADD */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_X_EXT_NAT_T_TYPE
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+| 1<<SADB_X_EXT_NAT_T_OA
-+,
-+/* SADB_DELETE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_GET */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_ACQUIRE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+,
-+/* SADB_REGISTER */
-+1<<SADB_EXT_RESERVED
-+,
-+/* SADB_EXPIRE */
-+0
-+,
-+/* SADB_FLUSH */
-+1<<SADB_EXT_RESERVED
-+,
-+/* SADB_DUMP */
-+1<<SADB_EXT_RESERVED
-+,
-+/* SADB_X_PROMISC */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+| 1<<SADB_EXT_SPIRANGE
-+| 1<<SADB_X_EXT_KMPRIVATE
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_PCHANGE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+| 1<<SADB_EXT_SPIRANGE
-+| 1<<SADB_X_EXT_KMPRIVATE
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_GRPSA */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_ADDFLOW */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_X_EXT_PROTOCOL
-+,
-+/* SADB_X_DELFLOW */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_X_EXT_PROTOCOL
-+,
-+/* SADB_X_DEBUG */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_X_EXT_DEBUG
-+,
-+/* SADB_X_NAT_T_NEW_MAPPING */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+},
-+
-+/* REQUIRED IN */
-+{
-+/* SADB_RESERVED */
-+0
-+,
-+/* SADB_GETSPI */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_SPIRANGE
-+,
-+/* SADB_UPDATE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+/*| 1<<SADB_EXT_KEY_AUTH*/
-+/*| 1<<SADB_EXT_KEY_ENCRYPT*/
-+,
-+/* SADB_ADD */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+/*| 1<<SADB_EXT_KEY_AUTH*/
-+/*| 1<<SADB_EXT_KEY_ENCRYPT*/
-+,
-+/* SADB_DELETE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_GET */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_ACQUIRE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_PROPOSAL
-+,
-+/* SADB_REGISTER */
-+1<<SADB_EXT_RESERVED
-+,
-+/* SADB_EXPIRE */
-+0
-+,
-+/* SADB_FLUSH */
-+1<<SADB_EXT_RESERVED
-+,
-+/* SADB_DUMP */
-+1<<SADB_EXT_RESERVED
-+,
-+/* SADB_X_PROMISC */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+| 1<<SADB_EXT_SPIRANGE
-+| 1<<SADB_X_EXT_KMPRIVATE
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_PCHANGE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+| 1<<SADB_EXT_SPIRANGE
-+| 1<<SADB_X_EXT_KMPRIVATE
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_GRPSA */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_DST
-+/*| 1<<SADB_X_EXT_SATYPE2*/
-+/*| 1<<SADB_X_EXT_SA2*/
-+/*| 1<<SADB_X_EXT_ADDRESS_DST2*/
-+,
-+/* SADB_X_ADDFLOW */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-+,
-+/* SADB_X_DELFLOW */
-+1<<SADB_EXT_RESERVED
-+/*| 1<<SADB_EXT_SA*/
-+#if 0 /* SADB_X_CLREROUTE doesn't need all these... */
-+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-+#endif
-+,
-+/* SADB_X_DEBUG */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_X_EXT_DEBUG
-+,
-+/* SADB_X_NAT_T_NEW_MAPPING */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+}
-+
-+},
-+
-+/* OUTBOUND EXTENSIONS */
-+{
-+
-+/* PERMITTED OUT */
-+{
-+/* SADB_RESERVED */
-+0
-+,
-+/* SADB_GETSPI */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_UPDATE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+,
-+/* SADB_ADD */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_X_EXT_NAT_T_TYPE
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+| 1<<SADB_X_EXT_NAT_T_OA
-+,
-+/* SADB_DELETE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_GET */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_X_EXT_NAT_T_TYPE
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+| 1<<SADB_X_EXT_NAT_T_OA
-+,
-+/* SADB_ACQUIRE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+,
-+/* SADB_REGISTER */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+,
-+/* SADB_EXPIRE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_FLUSH */
-+1<<SADB_EXT_RESERVED
-+,
-+/* SADB_DUMP */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_X_EXT_NAT_T_TYPE
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+| 1<<SADB_X_EXT_NAT_T_OA
-+,
-+/* SADB_X_PROMISC */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+| 1<<SADB_EXT_SPIRANGE
-+| 1<<SADB_X_EXT_KMPRIVATE
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_PCHANGE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+| 1<<SADB_EXT_SPIRANGE
-+| 1<<SADB_X_EXT_KMPRIVATE
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_GRPSA */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_ADDFLOW */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-+| 1<<SADB_X_EXT_PROTOCOL
-+,
-+/* SADB_X_DELFLOW */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-+| 1<<SADB_X_EXT_PROTOCOL
-+,
-+/* SADB_X_DEBUG */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_X_EXT_DEBUG
-+,
-+/* SADB_X_NAT_T_NEW_MAPPING */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+},
-+
-+/* REQUIRED OUT */
-+{
-+/* SADB_RESERVED */
-+0
-+,
-+/* SADB_GETSPI */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_UPDATE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_ADD */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_DELETE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_GET */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+/* | 1<<SADB_EXT_KEY_AUTH */
-+/* | 1<<SADB_EXT_KEY_ENCRYPT */
-+,
-+/* SADB_ACQUIRE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_PROPOSAL
-+,
-+/* SADB_REGISTER */
-+1<<SADB_EXT_RESERVED
-+/* | 1<<SADB_EXT_SUPPORTED_AUTH
-+ | 1<<SADB_EXT_SUPPORTED_ENCRYPT */
-+,
-+/* SADB_EXPIRE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+/* | 1<<SADB_EXT_LIFETIME_HARD
-+ | 1<<SADB_EXT_LIFETIME_SOFT */
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_FLUSH */
-+1<<SADB_EXT_RESERVED
-+,
-+/* SADB_DUMP */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+,
-+/* SADB_X_PROMISC */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+| 1<<SADB_EXT_SPIRANGE
-+| 1<<SADB_X_EXT_KMPRIVATE
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_PCHANGE */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_LIFETIME_CURRENT
-+| 1<<SADB_EXT_LIFETIME_HARD
-+| 1<<SADB_EXT_LIFETIME_SOFT
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_EXT_ADDRESS_PROXY
-+| 1<<SADB_EXT_KEY_AUTH
-+| 1<<SADB_EXT_KEY_ENCRYPT
-+| 1<<SADB_EXT_IDENTITY_SRC
-+| 1<<SADB_EXT_IDENTITY_DST
-+| 1<<SADB_EXT_SENSITIVITY
-+| 1<<SADB_EXT_PROPOSAL
-+| 1<<SADB_EXT_SUPPORTED_AUTH
-+| 1<<SADB_EXT_SUPPORTED_ENCRYPT
-+| 1<<SADB_EXT_SPIRANGE
-+| 1<<SADB_X_EXT_KMPRIVATE
-+| 1<<SADB_X_EXT_SATYPE2
-+| 1<<SADB_X_EXT_SA2
-+| 1<<SADB_X_EXT_ADDRESS_DST2
-+,
-+/* SADB_X_GRPSA */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_DST
-+,
-+/* SADB_X_ADDFLOW */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-+,
-+/* SADB_X_DELFLOW */
-+1<<SADB_EXT_RESERVED
-+/*| 1<<SADB_EXT_SA*/
-+| 1<<SADB_X_EXT_ADDRESS_SRC_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_DST_FLOW
-+| 1<<SADB_X_EXT_ADDRESS_SRC_MASK
-+| 1<<SADB_X_EXT_ADDRESS_DST_MASK
-+,
-+/* SADB_X_DEBUG */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_X_EXT_DEBUG
-+,
-+/* SADB_X_NAT_T_NEW_MAPPING */
-+1<<SADB_EXT_RESERVED
-+| 1<<SADB_EXT_SA
-+| 1<<SADB_EXT_ADDRESS_SRC
-+| 1<<SADB_EXT_ADDRESS_DST
-+| 1<<SADB_X_EXT_NAT_T_SPORT
-+| 1<<SADB_X_EXT_NAT_T_DPORT
-+}
-+}
-+};
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.20 2004/03/08 01:59:08 ken
-+ * freeswan.h -> openswan.h
-+ *
-+ * Revision 1.19 2003/12/22 21:38:13 mcr
-+ * removed extraenous #endif.
-+ *
-+ * Revision 1.18 2003/12/22 19:34:41 mcr
-+ * added 0.6c NAT-T patch.
-+ *
-+ * Revision 1.17 2003/12/10 01:20:19 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.16 2003/10/31 02:27:12 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.15.30.1 2003/09/21 13:59:44 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.15 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.14 2002/04/24 07:36:40 mcr
-+ * Moved from ./lib/pfkey_v2_ext_bits.c,v
-+ *
-+ * Revision 1.13 2002/01/29 22:25:36 rgb
-+ * Re-add ipsec_kversion.h to keep MALLOC happy.
-+ *
-+ * Revision 1.12 2002/01/29 01:59:10 mcr
-+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
-+ * updating of IPv6 structures to match latest in6.h version.
-+ * removed dead code from openswan.h that also duplicated kversions.h
-+ * code.
-+ *
-+ * Revision 1.11 2001/10/18 04:45:24 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/openswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.10 2001/09/08 21:13:35 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.9 2001/06/14 19:35:16 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.8 2001/03/26 23:07:36 rgb
-+ * Remove requirement for auth and enc key from UPDATE.
-+ *
-+ * Revision 1.7 2000/09/12 22:35:37 rgb
-+ * Restructured to remove unused extensions from CLEARFLOW messages.
-+ *
-+ * Revision 1.6 2000/09/09 06:39:01 rgb
-+ * Added comments for clarity.
-+ *
-+ * Revision 1.5 2000/06/02 22:54:14 rgb
-+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
-+ *
-+ * Revision 1.4 2000/01/21 06:27:56 rgb
-+ * Added address cases for eroute flows.
-+ * Added comments for each message type.
-+ * Added klipsdebug switching capability.
-+ * Fixed GRPSA bitfields.
-+ *
-+ * Revision 1.3 1999/12/01 22:20:27 rgb
-+ * Remove requirement for a proxy address in an incoming getspi message.
-+ *
-+ * Revision 1.2 1999/11/27 11:57:06 rgb
-+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
-+ * Add CVS log entry to bottom of file.
-+ * Cleaned out unused bits.
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/pfkey_v2_parse.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1820 @@
-+/*
-+ * RFC2367 PF_KEYv2 Key management API message parser
-+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * Template from klips/net/ipsec/ipsec/ipsec_parser.c.
-+ */
-+
-+char pfkey_v2_parse_c_version[] = "$Id$";
-+
-+/*
-+ * Some ugly stuff to allow consistent debugging code for use in the
-+ * kernel and in user space
-+*/
-+
-+#ifdef __KERNEL__
-+
-+# include <linux/kernel.h> /* for printk */
-+
-+#include "openswan/ipsec_kversion.h" /* for malloc switch */
-+
-+# ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+# else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+# endif /* MALLOC_SLAB */
-+# include <linux/errno.h> /* error codes */
-+# include <linux/types.h> /* size_t */
-+# include <linux/interrupt.h> /* mark_bh */
-+
-+# include <linux/netdevice.h> /* struct device, and other headers */
-+# include <linux/etherdevice.h> /* eth_type_trans */
-+# include <linux/ip.h> /* struct iphdr */
-+# if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+# include <linux/ipv6.h> /* struct ipv6hdr */
-+# endif /* if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
-+extern int debug_pfkey;
-+
-+# include <openswan.h>
-+
-+#include "openswan/ipsec_encap.h"
-+
-+#else /* __KERNEL__ */
-+
-+# include <sys/types.h>
-+# include <linux/types.h>
-+# include <linux/errno.h>
-+
-+# include <openswan.h>
-+# include "constants.h"
-+# include "programs/pluto/defs.h" /* for PRINTF_LIKE */
-+
-+#endif /* __KERNEL__ */
-+
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_sa.h" /* IPSEC_SAREF_NULL, IPSEC_SA_REF_TABLE_IDX_WIDTH */
-+
-+/*
-+ * how to handle debugging for pfkey.
-+ */
-+#include <openswan/pfkey_debug.h>
-+
-+unsigned int pfkey_lib_debug = PF_KEY_DEBUG_PARSE_NONE;
-+void (*pfkey_debug_func)(const char *message, ...) PRINTF_LIKE(1);
-+void (*pfkey_error_func)(const char *message, ...) PRINTF_LIKE(1);
-+
-+
-+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
-+
-+struct satype_tbl {
-+ uint8_t proto;
-+ uint8_t satype;
-+ char* name;
-+} static satype_tbl[] = {
-+#ifdef __KERNEL__
-+ { IPPROTO_ESP, SADB_SATYPE_ESP, "ESP" },
-+ { IPPROTO_AH, SADB_SATYPE_AH, "AH" },
-+ { IPPROTO_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ { IPPROTO_COMP, SADB_X_SATYPE_COMP, "COMP" },
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ { IPPROTO_INT, SADB_X_SATYPE_INT, "INT" },
-+#else /* __KERNEL__ */
-+ { SA_ESP, SADB_SATYPE_ESP, "ESP" },
-+ { SA_AH, SADB_SATYPE_AH, "AH" },
-+ { SA_IPIP, SADB_X_SATYPE_IPIP, "IPIP" },
-+ { SA_COMP, SADB_X_SATYPE_COMP, "COMP" },
-+ { SA_INT, SADB_X_SATYPE_INT, "INT" },
-+#endif /* __KERNEL__ */
-+ { 0, 0, "UNKNOWN" }
-+};
-+
-+uint8_t
-+satype2proto(uint8_t satype)
-+{
-+ int i =0;
-+
-+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
-+ i++;
-+ }
-+ return satype_tbl[i].proto;
-+}
-+
-+uint8_t
-+proto2satype(uint8_t proto)
-+{
-+ int i = 0;
-+
-+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
-+ i++;
-+ }
-+ return satype_tbl[i].satype;
-+}
-+
-+char*
-+satype2name(uint8_t satype)
-+{
-+ int i = 0;
-+
-+ while(satype_tbl[i].satype != satype && satype_tbl[i].satype != 0) {
-+ i++;
-+ }
-+ return satype_tbl[i].name;
-+}
-+
-+char*
-+proto2name(uint8_t proto)
-+{
-+ int i = 0;
-+
-+ while(satype_tbl[i].proto != proto && satype_tbl[i].proto != 0) {
-+ i++;
-+ }
-+ return satype_tbl[i].name;
-+}
-+
-+/* Default extension parsers taken from the KLIPS code */
-+
-+DEBUG_NO_STATIC int
-+pfkey_sa_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
-+#if 0
-+ struct sadb_sa sav2;
-+#endif
-+
-+ /* sanity checks... */
-+ if(!pfkey_sa) {
-+ ERROR("pfkey_sa_parse: "
-+ "NULL pointer passed in.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+#if 0
-+ /* check if this structure is short, and if so, fix it up.
-+ * XXX this is NOT the way to do things.
-+ */
-+ if(pfkey_sa->sadb_sa_len == sizeof(struct sadb_sa_v1)/IPSEC_PFKEYv2_ALIGN) {
-+
-+ /* yes, so clear out a temporary structure, and copy first */
-+ memset(&sav2, 0, sizeof(sav2));
-+ memcpy(&sav2, pfkey_sa, sizeof(struct sadb_sa_v1));
-+ sav2.sadb_x_sa_ref=-1;
-+ sav2.sadb_sa_len = sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN;
-+
-+ pfkey_sa = &sav2;
-+ }
-+#endif
-+
-+
-+ if(pfkey_sa->sadb_sa_len != sizeof(struct sadb_sa) / IPSEC_PFKEYv2_ALIGN) {
-+ ERROR(
-+ "pfkey_sa_parse: "
-+ "length wrong pfkey_sa->sadb_sa_len=%d sizeof(struct sadb_sa)=%d.\n",
-+ pfkey_sa->sadb_sa_len,
-+ (int)sizeof(struct sadb_sa));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_sa->sadb_sa_encrypt > SADB_EALG_MAX) {
-+ ERROR(
-+ "pfkey_sa_parse: "
-+ "pfkey_sa->sadb_sa_encrypt=%d > SADB_EALG_MAX=%d.\n",
-+ pfkey_sa->sadb_sa_encrypt,
-+ SADB_EALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_sa->sadb_sa_auth > SADB_AALG_MAX) {
-+ ERROR(
-+ "pfkey_sa_parse: "
-+ "pfkey_sa->sadb_sa_auth=%d > SADB_AALG_MAX=%d.\n",
-+ pfkey_sa->sadb_sa_auth,
-+ SADB_AALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_sa->sadb_sa_state > SADB_SASTATE_MAX) {
-+ ERROR(
-+ "pfkey_sa_parse: "
-+ "state=%d exceeds MAX=%d.\n",
-+ pfkey_sa->sadb_sa_state,
-+ SADB_SASTATE_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_sa->sadb_sa_state == SADB_SASTATE_DEAD) {
-+ ERROR(
-+ "pfkey_sa_parse: "
-+ "state=%d is DEAD=%d.\n",
-+ pfkey_sa->sadb_sa_state,
-+ SADB_SASTATE_DEAD);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_sa->sadb_sa_replay > 64) {
-+ ERROR(
-+ "pfkey_sa_parse: "
-+ "replay window size: %d -- must be 0 <= size <= 64\n",
-+ pfkey_sa->sadb_sa_replay);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(! ((pfkey_sa->sadb_sa_exttype == SADB_EXT_SA) ||
-+ (pfkey_sa->sadb_sa_exttype == SADB_X_EXT_SA2)))
-+ {
-+ ERROR(
-+ "pfkey_sa_parse: "
-+ "unknown exttype=%d, expecting SADB_EXT_SA=%d or SADB_X_EXT_SA2=%d.\n",
-+ pfkey_sa->sadb_sa_exttype,
-+ SADB_EXT_SA,
-+ SADB_X_EXT_SA2);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if((IPSEC_SAREF_NULL != pfkey_sa->sadb_x_sa_ref) && (pfkey_sa->sadb_x_sa_ref >= (1 << IPSEC_SA_REF_TABLE_IDX_WIDTH))) {
-+ ERROR(
-+ "pfkey_sa_parse: "
-+ "SAref=%d must be (SAref == IPSEC_SAREF_NULL(%d) || SAref < IPSEC_SA_REF_TABLE_NUM_ENTRIES(%d)).\n",
-+ pfkey_sa->sadb_x_sa_ref,
-+ IPSEC_SAREF_NULL,
-+ IPSEC_SA_REF_TABLE_NUM_ENTRIES);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_sa_parse: "
-+ "successfully found len=%d exttype=%d(%s) spi=%08lx replay=%d state=%d auth=%d encrypt=%d flags=%d ref=%d.\n",
-+ pfkey_sa->sadb_sa_len,
-+ pfkey_sa->sadb_sa_exttype,
-+ pfkey_v2_sadb_ext_string(pfkey_sa->sadb_sa_exttype),
-+ (long unsigned int)ntohl(pfkey_sa->sadb_sa_spi),
-+ pfkey_sa->sadb_sa_replay,
-+ pfkey_sa->sadb_sa_state,
-+ pfkey_sa->sadb_sa_auth,
-+ pfkey_sa->sadb_sa_encrypt,
-+ pfkey_sa->sadb_sa_flags,
-+ pfkey_sa->sadb_x_sa_ref);
-+
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_lifetime_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-+ "pfkey_lifetime_parse:enter\n");
-+ /* sanity checks... */
-+ if(!pfkey_lifetime) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_lifetime_parse: "
-+ "NULL pointer passed in.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_lifetime->sadb_lifetime_len !=
-+ sizeof(struct sadb_lifetime) / IPSEC_PFKEYv2_ALIGN) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_lifetime_parse: "
-+ "length wrong pfkey_lifetime->sadb_lifetime_len=%d sizeof(struct sadb_lifetime)=%d.\n",
-+ pfkey_lifetime->sadb_lifetime_len,
-+ (int)sizeof(struct sadb_lifetime));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if((pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_HARD) &&
-+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_SOFT) &&
-+ (pfkey_lifetime->sadb_lifetime_exttype != SADB_EXT_LIFETIME_CURRENT)) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_lifetime_parse: "
-+ "unexpected ext_type=%d.\n",
-+ pfkey_lifetime->sadb_lifetime_exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_lifetime_parse: "
-+ "life_type=%d(%s) alloc=%u bytes=%u add=%u use=%u pkts=%u.\n",
-+ pfkey_lifetime->sadb_lifetime_exttype,
-+ pfkey_v2_sadb_ext_string(pfkey_lifetime->sadb_lifetime_exttype),
-+ pfkey_lifetime->sadb_lifetime_allocations,
-+ (unsigned)pfkey_lifetime->sadb_lifetime_bytes,
-+ (unsigned)pfkey_lifetime->sadb_lifetime_addtime,
-+ (unsigned)pfkey_lifetime->sadb_lifetime_usetime,
-+ pfkey_lifetime->sadb_x_lifetime_packets);
-+errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_address_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ int saddr_len = 0;
-+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
-+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
-+ char ipaddr_txt[ADDRTOT_BUF];
-+
-+ /* sanity checks... */
-+ if(!pfkey_address) {
-+ ERROR(
-+ "pfkey_address_parse: "
-+ "NULL pointer passed in.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_address->sadb_address_len <
-+ (sizeof(struct sadb_address) + sizeof(struct sockaddr))/
-+ IPSEC_PFKEYv2_ALIGN) {
-+ ERROR("pfkey_address_parse: "
-+ "size wrong 1 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
-+ pfkey_address->sadb_address_len,
-+ (int)sizeof(struct sadb_address),
-+ (int)sizeof(struct sockaddr));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_address->sadb_address_reserved) {
-+ ERROR("pfkey_address_parse: "
-+ "res=%d, must be zero.\n",
-+ pfkey_address->sadb_address_reserved);
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_address->sadb_address_exttype) {
-+ case SADB_EXT_ADDRESS_SRC:
-+ case SADB_EXT_ADDRESS_DST:
-+ case SADB_EXT_ADDRESS_PROXY:
-+ case SADB_X_EXT_ADDRESS_DST2:
-+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
-+ case SADB_X_EXT_ADDRESS_DST_FLOW:
-+ case SADB_X_EXT_ADDRESS_SRC_MASK:
-+ case SADB_X_EXT_ADDRESS_DST_MASK:
-+#ifdef NAT_TRAVERSAL
-+ case SADB_X_EXT_NAT_T_OA:
-+#endif
-+ break;
-+ default:
-+ ERROR(
-+ "pfkey_address_parse: "
-+ "unexpected ext_type=%d.\n",
-+ pfkey_address->sadb_address_exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(s->sa_family) {
-+ case AF_INET:
-+ saddr_len = sizeof(struct sockaddr_in);
-+ sprintf(ipaddr_txt, "%d.%d.%d.%d"
-+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 0) & 0xFF
-+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 8) & 0xFF
-+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 16) & 0xFF
-+ , (((struct sockaddr_in*)s)->sin_addr.s_addr >> 24) & 0xFF);
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_address_parse: "
-+ "found exttype=%u(%s) family=%d(AF_INET) address=%s proto=%u port=%u.\n",
-+ pfkey_address->sadb_address_exttype,
-+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
-+ s->sa_family,
-+ ipaddr_txt,
-+ pfkey_address->sadb_address_proto,
-+ ntohs(((struct sockaddr_in*)s)->sin_port));
-+ break;
-+ case AF_INET6:
-+ saddr_len = sizeof(struct sockaddr_in6);
-+ sprintf(ipaddr_txt, "%x:%x:%x:%x:%x:%x:%x:%x"
-+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[0])
-+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[1])
-+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[2])
-+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[3])
-+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[4])
-+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[5])
-+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[6])
-+ , ntohs(((struct sockaddr_in6*)s)->sin6_addr.s6_addr16[7]));
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_address_parse: "
-+ "found exttype=%u(%s) family=%d(AF_INET6) address=%s proto=%u port=%u.\n",
-+ pfkey_address->sadb_address_exttype,
-+ pfkey_v2_sadb_ext_string(pfkey_address->sadb_address_exttype),
-+ s->sa_family,
-+ ipaddr_txt,
-+ pfkey_address->sadb_address_proto,
-+ ((struct sockaddr_in6*)s)->sin6_port);
-+ break;
-+ default:
-+ ERROR(
-+ "pfkey_address_parse: "
-+ "s->sa_family=%d not supported.\n",
-+ s->sa_family);
-+ SENDERR(EPFNOSUPPORT);
-+ }
-+
-+ if(pfkey_address->sadb_address_len !=
-+ DIVUP(sizeof(struct sadb_address) + saddr_len, IPSEC_PFKEYv2_ALIGN)) {
-+ ERROR(
-+ "pfkey_address_parse: "
-+ "size wrong 2 ext_len=%d, adr_ext_len=%d, saddr_len=%d.\n",
-+ pfkey_address->sadb_address_len,
-+ (int)sizeof(struct sadb_address),
-+ saddr_len);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_address->sadb_address_prefixlen != 0) {
-+ ERROR(
-+ "pfkey_address_parse: "
-+ "address prefixes not supported yet.\n");
-+ SENDERR(EAFNOSUPPORT); /* not supported yet */
-+ }
-+
-+ /* XXX check if port!=0 */
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-+ "pfkey_address_parse: successful.\n");
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_key_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
-+
-+ /* sanity checks... */
-+
-+ if(!pfkey_key) {
-+ ERROR(
-+ "pfkey_key_parse: "
-+ "NULL pointer passed in.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_key->sadb_key_len < sizeof(struct sadb_key) / IPSEC_PFKEYv2_ALIGN) {
-+ ERROR(
-+ "pfkey_key_parse: "
-+ "size wrong ext_len=%d, key_ext_len=%d.\n",
-+ pfkey_key->sadb_key_len,
-+ (int)sizeof(struct sadb_key));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!pfkey_key->sadb_key_bits) {
-+ ERROR(
-+ "pfkey_key_parse: "
-+ "key length set to zero, must be non-zero.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_key->sadb_key_len !=
-+ DIVUP(sizeof(struct sadb_key) * OCTETBITS + pfkey_key->sadb_key_bits,
-+ PFKEYBITS)) {
-+ ERROR(
-+ "pfkey_key_parse: "
-+ "key length=%d does not agree with extension length=%d.\n",
-+ pfkey_key->sadb_key_bits,
-+ pfkey_key->sadb_key_len);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_key->sadb_key_reserved) {
-+ ERROR(
-+ "pfkey_key_parse: "
-+ "res=%d, must be zero.\n",
-+ pfkey_key->sadb_key_reserved);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(! ( (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_AUTH) ||
-+ (pfkey_key->sadb_key_exttype == SADB_EXT_KEY_ENCRYPT))) {
-+ ERROR(
-+ "pfkey_key_parse: "
-+ "expecting extension type AUTH or ENCRYPT, got %d.\n",
-+ pfkey_key->sadb_key_exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_key_parse: "
-+ "success, found len=%d exttype=%d(%s) bits=%d reserved=%d.\n",
-+ pfkey_key->sadb_key_len,
-+ pfkey_key->sadb_key_exttype,
-+ pfkey_v2_sadb_ext_string(pfkey_key->sadb_key_exttype),
-+ pfkey_key->sadb_key_bits,
-+ pfkey_key->sadb_key_reserved);
-+
-+errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_ident_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
-+
-+ /* sanity checks... */
-+ if(pfkey_ident->sadb_ident_len < sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
-+ ERROR(
-+ "pfkey_ident_parse: "
-+ "size wrong ext_len=%d, key_ext_len=%d.\n",
-+ pfkey_ident->sadb_ident_len,
-+ (int)sizeof(struct sadb_ident));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_ident->sadb_ident_type > SADB_IDENTTYPE_MAX) {
-+ ERROR(
-+ "pfkey_ident_parse: "
-+ "ident_type=%d out of range, must be less than %d.\n",
-+ pfkey_ident->sadb_ident_type,
-+ SADB_IDENTTYPE_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_ident->sadb_ident_reserved) {
-+ ERROR(
-+ "pfkey_ident_parse: "
-+ "res=%d, must be zero.\n",
-+ pfkey_ident->sadb_ident_reserved);
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* string terminator/padding must be zero */
-+ if(pfkey_ident->sadb_ident_len > sizeof(struct sadb_ident) / IPSEC_PFKEYv2_ALIGN) {
-+ if(*((char*)pfkey_ident + pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1)) {
-+ ERROR(
-+ "pfkey_ident_parse: "
-+ "string padding must be zero, last is 0x%02x.\n",
-+ *((char*)pfkey_ident +
-+ pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - 1));
-+ SENDERR(EINVAL);
-+ }
-+ }
-+
-+ if( ! ((pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC) ||
-+ (pfkey_ident->sadb_ident_exttype == SADB_EXT_IDENTITY_DST))) {
-+ ERROR(
-+ "pfkey_key_parse: "
-+ "expecting extension type IDENTITY_SRC or IDENTITY_DST, got %d.\n",
-+ pfkey_ident->sadb_ident_exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_sens_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_sens *pfkey_sens = (struct sadb_sens *)pfkey_ext;
-+
-+ /* sanity checks... */
-+ if(pfkey_sens->sadb_sens_len < sizeof(struct sadb_sens) / IPSEC_PFKEYv2_ALIGN) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_sens_parse: "
-+ "size wrong ext_len=%d, key_ext_len=%d.\n",
-+ pfkey_sens->sadb_sens_len,
-+ (int)sizeof(struct sadb_sens));
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_sens_parse: "
-+ "Sorry, I can't parse exttype=%d yet.\n",
-+ pfkey_ext->sadb_ext_type);
-+#if 0
-+ SENDERR(EINVAL); /* don't process these yet */
-+#endif
-+
-+errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_prop_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ int i, num_comb;
-+ struct sadb_prop *pfkey_prop = (struct sadb_prop *)pfkey_ext;
-+ struct sadb_comb *pfkey_comb = (struct sadb_comb *)((char*)pfkey_ext + sizeof(struct sadb_prop));
-+
-+ /* sanity checks... */
-+ if((pfkey_prop->sadb_prop_len < sizeof(struct sadb_prop) / IPSEC_PFKEYv2_ALIGN) ||
-+ (((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) % sizeof(struct sadb_comb))) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "size wrong ext_len=%d, prop_ext_len=%d comb_ext_len=%d.\n",
-+ pfkey_prop->sadb_prop_len,
-+ (int)sizeof(struct sadb_prop),
-+ (int)sizeof(struct sadb_comb));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_prop->sadb_prop_replay > 64) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "replay window size: %d -- must be 0 <= size <= 64\n",
-+ pfkey_prop->sadb_prop_replay);
-+ SENDERR(EINVAL);
-+ }
-+
-+ for(i=0; i<3; i++) {
-+ if(pfkey_prop->sadb_prop_reserved[i]) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "res[%d]=%d, must be zero.\n",
-+ i, pfkey_prop->sadb_prop_reserved[i]);
-+ SENDERR(EINVAL);
-+ }
-+ }
-+
-+ num_comb = ((pfkey_prop->sadb_prop_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_prop)) / sizeof(struct sadb_comb);
-+
-+ for(i = 0; i < num_comb; i++) {
-+ if(pfkey_comb->sadb_comb_auth > SADB_AALG_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_auth=%d > SADB_AALG_MAX=%d.\n",
-+ i,
-+ pfkey_comb->sadb_comb_auth,
-+ SADB_AALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_comb->sadb_comb_auth) {
-+ if(!pfkey_comb->sadb_comb_auth_minbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_auth_minbits=0, fatal.\n",
-+ i);
-+ SENDERR(EINVAL);
-+ }
-+ if(!pfkey_comb->sadb_comb_auth_maxbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=0, fatal.\n",
-+ i);
-+ SENDERR(EINVAL);
-+ }
-+ if(pfkey_comb->sadb_comb_auth_minbits > pfkey_comb->sadb_comb_auth_maxbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d > maxbits=%d, fatal.\n",
-+ i,
-+ pfkey_comb->sadb_comb_auth_minbits,
-+ pfkey_comb->sadb_comb_auth_maxbits);
-+ SENDERR(EINVAL);
-+ }
-+ } else {
-+ if(pfkey_comb->sadb_comb_auth_minbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_auth_minbits=%d != 0, fatal.\n",
-+ i,
-+ pfkey_comb->sadb_comb_auth_minbits);
-+ SENDERR(EINVAL);
-+ }
-+ if(pfkey_comb->sadb_comb_auth_maxbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_auth_maxbits=%d != 0, fatal.\n",
-+ i,
-+ pfkey_comb->sadb_comb_auth_maxbits);
-+ SENDERR(EINVAL);
-+ }
-+ }
-+
-+ if(pfkey_comb->sadb_comb_encrypt > SADB_EALG_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_comb_parse: "
-+ "pfkey_comb[%d]->sadb_comb_encrypt=%d > SADB_EALG_MAX=%d.\n",
-+ i,
-+ pfkey_comb->sadb_comb_encrypt,
-+ SADB_EALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_comb->sadb_comb_encrypt) {
-+ if(!pfkey_comb->sadb_comb_encrypt_minbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=0, fatal.\n",
-+ i);
-+ SENDERR(EINVAL);
-+ }
-+ if(!pfkey_comb->sadb_comb_encrypt_maxbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=0, fatal.\n",
-+ i);
-+ SENDERR(EINVAL);
-+ }
-+ if(pfkey_comb->sadb_comb_encrypt_minbits > pfkey_comb->sadb_comb_encrypt_maxbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d > maxbits=%d, fatal.\n",
-+ i,
-+ pfkey_comb->sadb_comb_encrypt_minbits,
-+ pfkey_comb->sadb_comb_encrypt_maxbits);
-+ SENDERR(EINVAL);
-+ }
-+ } else {
-+ if(pfkey_comb->sadb_comb_encrypt_minbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_encrypt_minbits=%d != 0, fatal.\n",
-+ i,
-+ pfkey_comb->sadb_comb_encrypt_minbits);
-+ SENDERR(EINVAL);
-+ }
-+ if(pfkey_comb->sadb_comb_encrypt_maxbits) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_encrypt_maxbits=%d != 0, fatal.\n",
-+ i,
-+ pfkey_comb->sadb_comb_encrypt_maxbits);
-+ SENDERR(EINVAL);
-+ }
-+ }
-+
-+ /* XXX do sanity check on flags */
-+
-+ if(pfkey_comb->sadb_comb_hard_allocations && pfkey_comb->sadb_comb_soft_allocations > pfkey_comb->sadb_comb_hard_allocations) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_soft_allocations=%d > hard_allocations=%d, fatal.\n",
-+ i,
-+ pfkey_comb->sadb_comb_soft_allocations,
-+ pfkey_comb->sadb_comb_hard_allocations);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_comb->sadb_comb_hard_bytes && pfkey_comb->sadb_comb_soft_bytes > pfkey_comb->sadb_comb_hard_bytes) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_soft_bytes=%Ld > hard_bytes=%Ld, fatal.\n",
-+ i,
-+ (unsigned long long int)pfkey_comb->sadb_comb_soft_bytes,
-+ (unsigned long long int)pfkey_comb->sadb_comb_hard_bytes);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_comb->sadb_comb_hard_addtime && pfkey_comb->sadb_comb_soft_addtime > pfkey_comb->sadb_comb_hard_addtime) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_soft_addtime=%Ld > hard_addtime=%Ld, fatal.\n",
-+ i,
-+ (unsigned long long int)pfkey_comb->sadb_comb_soft_addtime,
-+ (unsigned long long int)pfkey_comb->sadb_comb_hard_addtime);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_comb->sadb_comb_hard_usetime && pfkey_comb->sadb_comb_soft_usetime > pfkey_comb->sadb_comb_hard_usetime) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_comb_soft_usetime=%Ld > hard_usetime=%Ld, fatal.\n",
-+ i,
-+ (unsigned long long int)pfkey_comb->sadb_comb_soft_usetime,
-+ (unsigned long long int)pfkey_comb->sadb_comb_hard_usetime);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_comb->sadb_x_comb_hard_packets && pfkey_comb->sadb_x_comb_soft_packets > pfkey_comb->sadb_x_comb_hard_packets) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "pfkey_comb[%d]->sadb_x_comb_soft_packets=%d > hard_packets=%d, fatal.\n",
-+ i,
-+ pfkey_comb->sadb_x_comb_soft_packets,
-+ pfkey_comb->sadb_x_comb_hard_packets);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_comb->sadb_comb_reserved) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_prop_parse: "
-+ "comb[%d].res=%d, must be zero.\n",
-+ i,
-+ pfkey_comb->sadb_comb_reserved);
-+ SENDERR(EINVAL);
-+ }
-+ pfkey_comb++;
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_supported_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ unsigned int i, num_alg;
-+ struct sadb_supported *pfkey_supported = (struct sadb_supported *)pfkey_ext;
-+ struct sadb_alg *pfkey_alg = (struct sadb_alg*)((char*)pfkey_ext + sizeof(struct sadb_supported));
-+
-+ /* sanity checks... */
-+ if((pfkey_supported->sadb_supported_len <
-+ sizeof(struct sadb_supported) / IPSEC_PFKEYv2_ALIGN) ||
-+ (((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) -
-+ sizeof(struct sadb_supported)) % sizeof(struct sadb_alg))) {
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_supported_parse: "
-+ "size wrong ext_len=%d, supported_ext_len=%d alg_ext_len=%d.\n",
-+ pfkey_supported->sadb_supported_len,
-+ (int)sizeof(struct sadb_supported),
-+ (int)sizeof(struct sadb_alg));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_supported->sadb_supported_reserved) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_supported_parse: "
-+ "res=%d, must be zero.\n",
-+ pfkey_supported->sadb_supported_reserved);
-+ SENDERR(EINVAL);
-+ }
-+
-+ num_alg = ((pfkey_supported->sadb_supported_len * IPSEC_PFKEYv2_ALIGN) - sizeof(struct sadb_supported)) / sizeof(struct sadb_alg);
-+
-+ for(i = 0; i < num_alg; i++) {
-+ /* process algo description */
-+ if(pfkey_alg->sadb_alg_reserved) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_supported_parse: "
-+ "alg[%d], id=%d, ivlen=%d, minbits=%d, maxbits=%d, res=%d, must be zero.\n",
-+ i,
-+ pfkey_alg->sadb_alg_id,
-+ pfkey_alg->sadb_alg_ivlen,
-+ pfkey_alg->sadb_alg_minbits,
-+ pfkey_alg->sadb_alg_maxbits,
-+ pfkey_alg->sadb_alg_reserved);
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* XXX can alg_id auth/enc be determined from info given?
-+ Yes, but OpenBSD's method does not iteroperate with rfc2367.
-+ rgb, 2000-04-06 */
-+
-+ switch(pfkey_supported->sadb_supported_exttype) {
-+ case SADB_EXT_SUPPORTED_AUTH:
-+ if(pfkey_alg->sadb_alg_id > SADB_AALG_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_supported_parse: "
-+ "alg[%d], alg_id=%d > SADB_AALG_MAX=%d, fatal.\n",
-+ i,
-+ pfkey_alg->sadb_alg_id,
-+ SADB_AALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+ break;
-+ case SADB_EXT_SUPPORTED_ENCRYPT:
-+ if(pfkey_alg->sadb_alg_id > SADB_EALG_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_supported_parse: "
-+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
-+ i,
-+ pfkey_alg->sadb_alg_id,
-+ SADB_EALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+ break;
-+ default:
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_supported_parse: "
-+ "alg[%d], alg_id=%d > SADB_EALG_MAX=%d, fatal.\n",
-+ i,
-+ pfkey_alg->sadb_alg_id,
-+ SADB_EALG_MAX);
-+ SENDERR(EINVAL);
-+ }
-+ pfkey_alg++;
-+ }
-+
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_spirange_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_spirange *pfkey_spirange = (struct sadb_spirange *)pfkey_ext;
-+
-+ /* sanity checks... */
-+ if(pfkey_spirange->sadb_spirange_len !=
-+ sizeof(struct sadb_spirange) / IPSEC_PFKEYv2_ALIGN) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_spirange_parse: "
-+ "size wrong ext_len=%d, key_ext_len=%d.\n",
-+ pfkey_spirange->sadb_spirange_len,
-+ (int)sizeof(struct sadb_spirange));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_spirange->sadb_spirange_reserved) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_spirange_parse: "
-+ "reserved=%d must be set to zero.\n",
-+ pfkey_spirange->sadb_spirange_reserved);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(ntohl(pfkey_spirange->sadb_spirange_max) < ntohl(pfkey_spirange->sadb_spirange_min)) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_spirange_parse: "
-+ "minspi=%08x must be < maxspi=%08x.\n",
-+ ntohl(pfkey_spirange->sadb_spirange_min),
-+ ntohl(pfkey_spirange->sadb_spirange_max));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(ntohl(pfkey_spirange->sadb_spirange_min) <= 255) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_spirange_parse: "
-+ "minspi=%08x must be > 255.\n",
-+ ntohl(pfkey_spirange->sadb_spirange_min));
-+ SENDERR(EEXIST);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_spirange_parse: "
-+ "ext_len=%u ext_type=%u(%s) min=%u max=%u res=%u.\n",
-+ pfkey_spirange->sadb_spirange_len,
-+ pfkey_spirange->sadb_spirange_exttype,
-+ pfkey_v2_sadb_ext_string(pfkey_spirange->sadb_spirange_exttype),
-+ pfkey_spirange->sadb_spirange_min,
-+ pfkey_spirange->sadb_spirange_max,
-+ pfkey_spirange->sadb_spirange_reserved);
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_kmprivate_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_x_kmprivate *pfkey_x_kmprivate = (struct sadb_x_kmprivate *)pfkey_ext;
-+
-+ /* sanity checks... */
-+ if(pfkey_x_kmprivate->sadb_x_kmprivate_len <
-+ sizeof(struct sadb_x_kmprivate) / IPSEC_PFKEYv2_ALIGN) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_kmprivate_parse: "
-+ "size wrong ext_len=%d, key_ext_len=%d.\n",
-+ pfkey_x_kmprivate->sadb_x_kmprivate_len,
-+ (int)sizeof(struct sadb_x_kmprivate));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_x_kmprivate->sadb_x_kmprivate_reserved) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_kmprivate_parse: "
-+ "reserved=%d must be set to zero.\n",
-+ pfkey_x_kmprivate->sadb_x_kmprivate_reserved);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_kmprivate_parse: "
-+ "Sorry, I can't parse exttype=%d yet.\n",
-+ pfkey_ext->sadb_ext_type);
-+ SENDERR(EINVAL); /* don't process these yet */
-+
-+errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_satype_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ int i;
-+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-+ "pfkey_x_satype_parse: enter\n");
-+ /* sanity checks... */
-+ if(pfkey_x_satype->sadb_x_satype_len !=
-+ sizeof(struct sadb_x_satype) / IPSEC_PFKEYv2_ALIGN) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_satype_parse: "
-+ "size wrong ext_len=%d, key_ext_len=%d.\n",
-+ pfkey_x_satype->sadb_x_satype_len,
-+ (int)sizeof(struct sadb_x_satype));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!pfkey_x_satype->sadb_x_satype_satype) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_satype_parse: "
-+ "satype is zero, must be non-zero.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_x_satype->sadb_x_satype_satype > SADB_SATYPE_MAX) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_satype_parse: "
-+ "satype %d > max %d, invalid.\n",
-+ pfkey_x_satype->sadb_x_satype_satype, SADB_SATYPE_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_satype_parse: "
-+ "proto lookup from satype=%d failed.\n",
-+ pfkey_x_satype->sadb_x_satype_satype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ for(i = 0; i < 3; i++) {
-+ if(pfkey_x_satype->sadb_x_satype_reserved[i]) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_satype_parse: "
-+ "reserved[%d]=%d must be set to zero.\n",
-+ i, pfkey_x_satype->sadb_x_satype_reserved[i]);
-+ SENDERR(EINVAL);
-+ }
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_x_satype_parse: "
-+ "len=%u ext=%u(%s) satype=%u(%s) res=%u,%u,%u.\n",
-+ pfkey_x_satype->sadb_x_satype_len,
-+ pfkey_x_satype->sadb_x_satype_exttype,
-+ pfkey_v2_sadb_ext_string(pfkey_x_satype->sadb_x_satype_exttype),
-+ pfkey_x_satype->sadb_x_satype_satype,
-+ satype2name(pfkey_x_satype->sadb_x_satype_satype),
-+ pfkey_x_satype->sadb_x_satype_reserved[0],
-+ pfkey_x_satype->sadb_x_satype_reserved[1],
-+ pfkey_x_satype->sadb_x_satype_reserved[2]);
-+errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_ext_debug_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ int i;
-+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-+ "pfkey_x_debug_parse: enter\n");
-+ /* sanity checks... */
-+ if(pfkey_x_debug->sadb_x_debug_len !=
-+ sizeof(struct sadb_x_debug) / IPSEC_PFKEYv2_ALIGN) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_debug_parse: "
-+ "size wrong ext_len=%d, key_ext_len=%d.\n",
-+ pfkey_x_debug->sadb_x_debug_len,
-+ (int)sizeof(struct sadb_x_debug));
-+ SENDERR(EINVAL);
-+ }
-+
-+ for(i = 0; i < 4; i++) {
-+ if(pfkey_x_debug->sadb_x_debug_reserved[i]) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_debug_parse: "
-+ "reserved[%d]=%d must be set to zero.\n",
-+ i, pfkey_x_debug->sadb_x_debug_reserved[i]);
-+ SENDERR(EINVAL);
-+ }
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_ext_protocol_parse(struct sadb_ext *pfkey_ext)
-+{
-+ int error = 0;
-+ struct sadb_protocol *p = (struct sadb_protocol *)pfkey_ext;
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM, "pfkey_x_protocol_parse:\n");
-+ /* sanity checks... */
-+
-+ if (p->sadb_protocol_len != sizeof(*p)/IPSEC_PFKEYv2_ALIGN) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_x_protocol_parse: size wrong ext_len=%d, key_ext_len=%d.\n",
-+ p->sadb_protocol_len, (int)sizeof(*p));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if (p->sadb_protocol_reserved2 != 0) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_protocol_parse: res=%d, must be zero.\n",
-+ p->sadb_protocol_reserved2);
-+ SENDERR(EINVAL);
-+ }
-+
-+ errlab:
-+ return error;
-+}
-+
-+#ifdef NAT_TRAVERSAL
-+DEBUG_NO_STATIC int
-+pfkey_x_ext_nat_t_type_parse(struct sadb_ext *pfkey_ext)
-+{
-+ return 0;
-+}
-+DEBUG_NO_STATIC int
-+pfkey_x_ext_nat_t_port_parse(struct sadb_ext *pfkey_ext)
-+{
-+ return 0;
-+}
-+#endif
-+
-+#define DEFINEPARSER(NAME) static struct pf_key_ext_parsers_def NAME##_def={NAME, #NAME};
-+
-+DEFINEPARSER(pfkey_sa_parse);
-+DEFINEPARSER(pfkey_lifetime_parse);
-+DEFINEPARSER(pfkey_address_parse);
-+DEFINEPARSER(pfkey_key_parse);
-+DEFINEPARSER(pfkey_ident_parse);
-+DEFINEPARSER(pfkey_sens_parse);
-+DEFINEPARSER(pfkey_prop_parse);
-+DEFINEPARSER(pfkey_supported_parse);
-+DEFINEPARSER(pfkey_spirange_parse);
-+DEFINEPARSER(pfkey_x_kmprivate_parse);
-+DEFINEPARSER(pfkey_x_satype_parse);
-+DEFINEPARSER(pfkey_x_ext_debug_parse);
-+DEFINEPARSER(pfkey_x_ext_protocol_parse);
-+#ifdef NAT_TRAVERSAL
-+DEFINEPARSER(pfkey_x_ext_nat_t_type_parse);
-+DEFINEPARSER(pfkey_x_ext_nat_t_port_parse);
-+#endif
-+
-+struct pf_key_ext_parsers_def *ext_default_parsers[]=
-+{
-+ NULL, /* pfkey_msg_parse, */
-+ &pfkey_sa_parse_def,
-+ &pfkey_lifetime_parse_def,
-+ &pfkey_lifetime_parse_def,
-+ &pfkey_lifetime_parse_def,
-+ &pfkey_address_parse_def,
-+ &pfkey_address_parse_def,
-+ &pfkey_address_parse_def,
-+ &pfkey_key_parse_def,
-+ &pfkey_key_parse_def,
-+ &pfkey_ident_parse_def,
-+ &pfkey_ident_parse_def,
-+ &pfkey_sens_parse_def,
-+ &pfkey_prop_parse_def,
-+ &pfkey_supported_parse_def,
-+ &pfkey_supported_parse_def,
-+ &pfkey_spirange_parse_def,
-+ &pfkey_x_kmprivate_parse_def,
-+ &pfkey_x_satype_parse_def,
-+ &pfkey_sa_parse_def,
-+ &pfkey_address_parse_def,
-+ &pfkey_address_parse_def,
-+ &pfkey_address_parse_def,
-+ &pfkey_address_parse_def,
-+ &pfkey_address_parse_def,
-+ &pfkey_x_ext_debug_parse_def,
-+ &pfkey_x_ext_protocol_parse_def
-+#ifdef NAT_TRAVERSAL
-+ ,
-+ &pfkey_x_ext_nat_t_type_parse_def,
-+ &pfkey_x_ext_nat_t_port_parse_def,
-+ &pfkey_x_ext_nat_t_port_parse_def,
-+ &pfkey_address_parse_def
-+#endif
-+};
-+
-+int
-+pfkey_msg_parse(struct sadb_msg *pfkey_msg,
-+ struct pf_key_ext_parsers_def *ext_parsers[],
-+ struct sadb_ext *extensions[],
-+ int dir)
-+{
-+ int error = 0;
-+ int remain;
-+ struct sadb_ext *pfkey_ext;
-+ int extensions_seen = 0;
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_msg_parse: "
-+ "parsing message ver=%d, type=%d(%s), errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
-+ pfkey_msg->sadb_msg_version,
-+ pfkey_msg->sadb_msg_type,
-+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
-+ pfkey_msg->sadb_msg_errno,
-+ pfkey_msg->sadb_msg_satype,
-+ satype2name(pfkey_msg->sadb_msg_satype),
-+ pfkey_msg->sadb_msg_len,
-+ pfkey_msg->sadb_msg_reserved,
-+ pfkey_msg->sadb_msg_seq,
-+ pfkey_msg->sadb_msg_pid);
-+
-+ if(ext_parsers == NULL) ext_parsers = ext_default_parsers;
-+
-+ pfkey_extensions_init(extensions);
-+
-+ remain = pfkey_msg->sadb_msg_len;
-+ remain -= sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
-+
-+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_msg +
-+ sizeof(struct sadb_msg));
-+
-+ extensions[0] = (struct sadb_ext *) pfkey_msg;
-+
-+
-+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
-+ ERROR("pfkey_msg_parse: "
-+ "not PF_KEY_V2 msg, found %d, should be %d.\n",
-+ pfkey_msg->sadb_msg_version,
-+ PF_KEY_V2);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!pfkey_msg->sadb_msg_type) {
-+ ERROR("pfkey_msg_parse: "
-+ "msg type not set, must be non-zero..\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(pfkey_msg->sadb_msg_type > SADB_MAX) {
-+ ERROR("pfkey_msg_parse: "
-+ "msg type=%d > max=%d.\n",
-+ pfkey_msg->sadb_msg_type,
-+ SADB_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_msg->sadb_msg_type) {
-+ case SADB_GETSPI:
-+ case SADB_UPDATE:
-+ case SADB_ADD:
-+ case SADB_DELETE:
-+ case SADB_GET:
-+ case SADB_X_GRPSA:
-+ case SADB_X_ADDFLOW:
-+ if(!satype2proto(pfkey_msg->sadb_msg_satype)) {
-+ ERROR("pfkey_msg_parse: "
-+ "satype %d conversion to proto failed for msg_type %d (%s).\n",
-+ pfkey_msg->sadb_msg_satype,
-+ pfkey_msg->sadb_msg_type,
-+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
-+ SENDERR(EINVAL);
-+ } else {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "satype %d(%s) conversion to proto gives %d for msg_type %d(%s).\n",
-+ pfkey_msg->sadb_msg_satype,
-+ satype2name(pfkey_msg->sadb_msg_satype),
-+ satype2proto(pfkey_msg->sadb_msg_satype),
-+ pfkey_msg->sadb_msg_type,
-+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
-+ }
-+ case SADB_ACQUIRE:
-+ case SADB_REGISTER:
-+ case SADB_EXPIRE:
-+ if(!pfkey_msg->sadb_msg_satype) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "satype is zero, must be non-zero for msg_type %d(%s).\n",
-+ pfkey_msg->sadb_msg_type,
-+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type));
-+ SENDERR(EINVAL);
-+ }
-+ default:
-+ break;
-+ }
-+
-+ /* errno must not be set in downward messages */
-+ /* this is not entirely true... a response to an ACQUIRE could return an error */
-+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type != SADB_ACQUIRE) && pfkey_msg->sadb_msg_errno) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "errno set to %d.\n",
-+ pfkey_msg->sadb_msg_errno);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-+ "pfkey_msg_parse: "
-+ "remain=%d, ext_type=%d(%s), ext_len=%d.\n",
-+ remain,
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-+ pfkey_ext->sadb_ext_len);
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-+ "pfkey_msg_parse: "
-+ "extensions permitted=%08x, required=%08x.\n",
-+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
-+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
-+
-+ extensions_seen = 1;
-+
-+ while( (remain * IPSEC_PFKEYv2_ALIGN) >= sizeof(struct sadb_ext) ) {
-+ /* Is there enough message left to support another extension header? */
-+ if(remain < pfkey_ext->sadb_ext_len) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "remain %d less than ext len %d.\n",
-+ remain, pfkey_ext->sadb_ext_len);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-+ "pfkey_msg_parse: "
-+ "parsing ext type=%d(%s) remain=%d.\n",
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-+ remain);
-+
-+ /* Is the extension header type valid? */
-+ if((pfkey_ext->sadb_ext_type > SADB_EXT_MAX) || (!pfkey_ext->sadb_ext_type)) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "ext type %d(%s) invalid, SADB_EXT_MAX=%d.\n",
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-+ SADB_EXT_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* Have we already seen this type of extension? */
-+ if((extensions_seen & ( 1 << pfkey_ext->sadb_ext_type )) != 0)
-+ {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "ext type %d(%s) already seen.\n",
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* Do I even know about this type of extension? */
-+ if(ext_parsers[pfkey_ext->sadb_ext_type]==NULL) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "ext type %d(%s) unknown, ignoring.\n",
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
-+ goto next_ext;
-+ }
-+
-+ /* Is this type of extension permitted for this type of message? */
-+ if(!(extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type] &
-+ 1<<pfkey_ext->sadb_ext_type)) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "ext type %d(%s) not permitted, exts_perm_in=%08x, 1<<type=%08x\n",
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
-+ 1<<pfkey_ext->sadb_ext_type);
-+ SENDERR(EINVAL);
-+ }
-+
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_msg_parse: "
-+ "remain=%d ext_type=%d(%s) ext_len=%d parsing ext 0p%p with parser %s.\n",
-+ remain,
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-+ pfkey_ext->sadb_ext_len,
-+ pfkey_ext,
-+ ext_parsers[pfkey_ext->sadb_ext_type]->parser_name);
-+
-+ /* Parse the extension */
-+ if((error =
-+ (*ext_parsers[pfkey_ext->sadb_ext_type]->parser)(pfkey_ext))) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "extension parsing for type %d(%s) failed with error %d.\n",
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type),
-+ error);
-+ SENDERR(-error);
-+ }
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_FLOW,
-+ "pfkey_msg_parse: "
-+ "Extension %d(%s) parsed.\n",
-+ pfkey_ext->sadb_ext_type,
-+ pfkey_v2_sadb_ext_string(pfkey_ext->sadb_ext_type));
-+
-+ /* Mark that we have seen this extension and remember the header location */
-+ extensions_seen |= ( 1 << pfkey_ext->sadb_ext_type );
-+ extensions[pfkey_ext->sadb_ext_type] = pfkey_ext;
-+
-+ next_ext:
-+ /* Calculate how much message remains */
-+ remain -= pfkey_ext->sadb_ext_len;
-+
-+ if(!remain) {
-+ break;
-+ }
-+ /* Find the next extension header */
-+ pfkey_ext = (struct sadb_ext*)((char*)pfkey_ext +
-+ pfkey_ext->sadb_ext_len * IPSEC_PFKEYv2_ALIGN);
-+ }
-+
-+ if(remain) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "unexpected remainder of %d.\n",
-+ remain);
-+ /* why is there still something remaining? */
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* check required extensions */
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_STRUCT,
-+ "pfkey_msg_parse: "
-+ "extensions permitted=%08x, seen=%08x, required=%08x.\n",
-+ extensions_bitmaps[dir][EXT_BITS_PERM][pfkey_msg->sadb_msg_type],
-+ extensions_seen,
-+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]);
-+
-+ /* don't check further if it is an error return message since it
-+ may not have a body */
-+ if(pfkey_msg->sadb_msg_errno) {
-+ SENDERR(-error);
-+ }
-+
-+ if((extensions_seen &
-+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) !=
-+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "required extensions missing:%08x.\n",
-+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type] -
-+ (extensions_seen &
-+ extensions_bitmaps[dir][EXT_BITS_REQ][pfkey_msg->sadb_msg_type]));
-+ SENDERR(EINVAL);
-+ }
-+
-+ if((dir == EXT_BITS_IN) && (pfkey_msg->sadb_msg_type == SADB_X_DELFLOW)
-+ && ((extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW)
-+ != SADB_X_EXT_ADDRESS_DELFLOW)
-+ && (((extensions_seen & (1<<SADB_EXT_SA)) != (1<<SADB_EXT_SA))
-+ || ((((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_flags
-+ & SADB_X_SAFLAGS_CLEARFLOW)
-+ != SADB_X_SAFLAGS_CLEARFLOW))) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "required SADB_X_DELFLOW extensions missing: either %08x must be present or %08x must be present with SADB_X_SAFLAGS_CLEARFLOW set.\n",
-+ SADB_X_EXT_ADDRESS_DELFLOW
-+ - (extensions_seen & SADB_X_EXT_ADDRESS_DELFLOW),
-+ (1<<SADB_EXT_SA) - (extensions_seen & (1<<SADB_EXT_SA)));
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_msg->sadb_msg_type) {
-+ case SADB_ADD:
-+ case SADB_UPDATE:
-+ /* check maturity */
-+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state !=
-+ SADB_SASTATE_MATURE) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "state=%d for add or update should be MATURE=%d.\n",
-+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
-+ SADB_SASTATE_MATURE);
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* check AH and ESP */
-+ switch(((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype) {
-+ case SADB_SATYPE_AH:
-+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
-+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_auth !=
-+ SADB_AALG_NONE)) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "auth alg is zero, must be non-zero for AH SAs.\n");
-+ SENDERR(EINVAL);
-+ }
-+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt !=
-+ SADB_EALG_NONE) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "AH handed encalg=%d, must be zero.\n",
-+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt);
-+ SENDERR(EINVAL);
-+ }
-+ break;
-+ case SADB_SATYPE_ESP:
-+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
-+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
-+ SADB_EALG_NONE)) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "encrypt alg=%d is zero, must be non-zero for ESP=%d SAs.\n",
-+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
-+ SENDERR(EINVAL);
-+ }
-+ if((((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_encrypt ==
-+ SADB_EALG_NULL) &&
-+ (((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth ==
-+ SADB_AALG_NONE) ) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "ESP handed encNULL+authNONE, illegal combination.\n");
-+ SENDERR(EINVAL);
-+ }
-+ break;
-+ case SADB_X_SATYPE_COMP:
-+ if(!(((struct sadb_sa*)extensions[SADB_EXT_SA]) &&
-+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt !=
-+ SADB_EALG_NONE)) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "encrypt alg=%d is zero, must be non-zero for COMP=%d SAs.\n",
-+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_encrypt,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
-+ SENDERR(EINVAL);
-+ }
-+ if(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth !=
-+ SADB_AALG_NONE) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "COMP handed auth=%d, must be zero.\n",
-+ ((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_auth);
-+ SENDERR(EINVAL);
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+ if(ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi) <= 255) {
-+ DEBUGGING(PF_KEY_DEBUG_PARSE_PROBLEM,
-+ "pfkey_msg_parse: "
-+ "spi=%08x must be > 255.\n",
-+ ntohl(((struct sadb_sa*)(extensions[SADB_EXT_SA]))->sadb_sa_spi));
-+ SENDERR(EINVAL);
-+ }
-+ default:
-+ break;
-+ }
-+errlab:
-+
-+ return error;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.59 2004/04/18 03:03:49 mcr
-+ * renamed common include files from pluto directory.
-+ *
-+ * Revision 1.58 2004/03/08 01:59:08 ken
-+ * freeswan.h -> openswan.h
-+ *
-+ * Revision 1.57 2003/12/10 01:20:19 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.56 2003/12/04 23:01:12 mcr
-+ * removed ipsec_netlink.h
-+ *
-+ * Revision 1.55 2003/11/07 01:30:37 ken
-+ * Cast sizeof() to int to keep things 64bit clean
-+ *
-+ * Revision 1.54 2003/10/31 02:27:12 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.53.20.2 2003/10/29 01:11:32 mcr
-+ * added debugging for pfkey library.
-+ *
-+ * Revision 1.53.20.1 2003/09/21 13:59:44 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.53 2003/01/30 02:32:09 rgb
-+ *
-+ * Rename SAref table macro names for clarity.
-+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
-+ *
-+ * Revision 1.52 2002/12/30 06:53:07 mcr
-+ * deal with short SA structures... #if 0 out for now. Probably
-+ * not quite the right way.
-+ *
-+ * Revision 1.51 2002/12/13 18:16:02 mcr
-+ * restored sa_ref code
-+ *
-+ * Revision 1.50 2002/12/13 18:06:52 mcr
-+ * temporarily removed sadb_x_sa_ref reference for 2.xx
-+ *
-+ * Revision 1.49 2002/10/05 05:02:58 dhr
-+ *
-+ * C labels go on statements
-+ *
-+ * Revision 1.48 2002/09/20 15:40:45 rgb
-+ * Added sadb_x_sa_ref to struct sadb_sa.
-+ *
-+ * Revision 1.47 2002/09/20 05:01:31 rgb
-+ * Fixed usage of pfkey_lib_debug.
-+ * Format for function declaration style consistency.
-+ * Added text labels to elucidate numeric values presented.
-+ * Re-organised debug output to reduce noise in output.
-+ *
-+ * Revision 1.46 2002/07/24 18:44:54 rgb
-+ * Type fiddling to tame ia64 compiler.
-+ *
-+ * Revision 1.45 2002/05/23 07:14:11 rgb
-+ * Cleaned up %p variants to 0p%p for test suite cleanup.
-+ *
-+ * Revision 1.44 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.43 2002/04/24 07:36:40 mcr
-+ * Moved from ./lib/pfkey_v2_parse.c,v
-+ *
-+ * Revision 1.42 2002/01/29 22:25:36 rgb
-+ * Re-add ipsec_kversion.h to keep MALLOC happy.
-+ *
-+ * Revision 1.41 2002/01/29 01:59:10 mcr
-+ * removal of kversions.h - sources that needed it now use ipsec_param.h.
-+ * updating of IPv6 structures to match latest in6.h version.
-+ * removed dead code from openswan.h that also duplicated kversions.h
-+ * code.
-+ *
-+ * Revision 1.40 2002/01/20 20:34:50 mcr
-+ * added pfkey_v2_sadb_type_string to decode sadb_type to string.
-+ *
-+ * Revision 1.39 2001/11/27 05:29:22 mcr
-+ * pfkey parses are now maintained by a structure
-+ * that includes their name for debug purposes.
-+ * DEBUGGING() macro changed so that it takes a debug
-+ * level so that pf_key() can use this to decode the
-+ * structures without innundanting humans.
-+ * Also uses pfkey_v2_sadb_ext_string() in messages.
-+ *
-+ * Revision 1.38 2001/11/06 19:47:47 rgb
-+ * Added packet parameter to lifetime and comb structures.
-+ *
-+ * Revision 1.37 2001/10/18 04:45:24 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/openswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.36 2001/06/14 19:35:16 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.35 2001/05/03 19:44:51 rgb
-+ * Standardise on SENDERR() macro.
-+ *
-+ * Revision 1.34 2001/03/16 07:41:51 rgb
-+ * Put openswan.h include before pluto includes.
-+ *
-+ * Revision 1.33 2001/02/27 07:13:51 rgb
-+ * Added satype2name() function.
-+ * Added text to default satype_tbl entry.
-+ * Added satype2name() conversions for most satype debug output.
-+ *
-+ * Revision 1.32 2001/02/26 20:01:09 rgb
-+ * Added internal IP protocol 61 for magic SAs.
-+ * Ditch unused sadb_satype2proto[], replaced by satype2proto().
-+ * Re-formatted debug output (split lines, consistent spacing).
-+ * Removed acquire, register and expire requirements for a known satype.
-+ * Changed message type checking to a switch structure.
-+ * Verify expected NULL auth for IPCOMP.
-+ * Enforced spi > 0x100 requirement, now that pass uses a magic SA for
-+ * appropriate message types.
-+ *
-+ * Revision 1.31 2000/12/01 07:09:00 rgb
-+ * Added ipcomp sanity check to require encalgo is set.
-+ *
-+ * Revision 1.30 2000/11/17 18:10:30 rgb
-+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
-+ * network byte order since this is the way PF_KEYv2 stored spis.
-+ *
-+ * Revision 1.29 2000/10/12 00:02:39 rgb
-+ * Removed 'format, ##' nonsense from debug macros for RH7.0.
-+ *
-+ * Revision 1.28 2000/09/20 16:23:04 rgb
-+ * Remove over-paranoid extension check in the presence of sadb_msg_errno.
-+ *
-+ * Revision 1.27 2000/09/20 04:04:21 rgb
-+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
-+ * oopsen.
-+ *
-+ * Revision 1.26 2000/09/15 11:37:02 rgb
-+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
-+ * IPCOMP zlib deflate code.
-+ *
-+ * Revision 1.25 2000/09/12 22:35:37 rgb
-+ * Restructured to remove unused extensions from CLEARFLOW messages.
-+ *
-+ * Revision 1.24 2000/09/12 18:59:54 rgb
-+ * Added Gerhard's IPv6 support to pfkey parts of libopenswan.
-+ *
-+ * Revision 1.23 2000/09/12 03:27:00 rgb
-+ * Moved DEBUGGING definition to compile kernel with debug off.
-+ *
-+ * Revision 1.22 2000/09/09 06:39:27 rgb
-+ * Restrict pfkey errno check to downward messages only.
-+ *
-+ * Revision 1.21 2000/09/08 19:22:34 rgb
-+ * Enabled pfkey_sens_parse().
-+ * Added check for errno on downward acquire messages only.
-+ *
-+ * Revision 1.20 2000/09/01 18:48:23 rgb
-+ * Fixed reserved check bug and added debug output in
-+ * pfkey_supported_parse().
-+ * Fixed debug output label bug in pfkey_ident_parse().
-+ *
-+ * Revision 1.19 2000/08/27 01:55:26 rgb
-+ * Define OCTETBITS and PFKEYBITS to avoid using 'magic' numbers in code.
-+ *
-+ * Revision 1.18 2000/08/24 17:00:36 rgb
-+ * Ignore unknown extensions instead of failing.
-+ *
-+ * Revision 1.17 2000/06/02 22:54:14 rgb
-+ * Added Gerhard Gessler's struct sockaddr_storage mods for IPv6 support.
-+ *
-+ * Revision 1.16 2000/05/10 19:25:11 rgb
-+ * Fleshed out proposal and supported extensions.
-+ *
-+ * Revision 1.15 2000/01/24 21:15:31 rgb
-+ * Added disabled pluto pfkey lib debug flag.
-+ * Added algo debugging reporting.
-+ *
-+ * Revision 1.14 2000/01/22 23:24:29 rgb
-+ * Added new functions proto2satype() and satype2proto() and lookup
-+ * table satype_tbl. Also added proto2name() since it was easy.
-+ *
-+ * Revision 1.13 2000/01/21 09:43:59 rgb
-+ * Cast ntohl(spi) as (unsigned long int) to shut up compiler.
-+ *
-+ * Revision 1.12 2000/01/21 06:28:19 rgb
-+ * Added address cases for eroute flows.
-+ * Indented compiler directives for readability.
-+ * Added klipsdebug switching capability.
-+ *
-+ * Revision 1.11 1999/12/29 21:14:59 rgb
-+ * Fixed debug text cut and paste typo.
-+ *
-+ * Revision 1.10 1999/12/10 17:45:24 rgb
-+ * Added address debugging.
-+ *
-+ * Revision 1.9 1999/12/09 23:11:42 rgb
-+ * Ditched <string.h> include since we no longer use memset().
-+ * Use new pfkey_extensions_init() instead of memset().
-+ * Added check for SATYPE in pfkey_msg_build().
-+ * Tidy up comments and debugging comments.
-+ *
-+ * Revision 1.8 1999/12/07 19:55:26 rgb
-+ * Removed unused first argument from extension parsers.
-+ * Removed static pluto debug flag.
-+ * Moved message type and state checking to pfkey_msg_parse().
-+ * Changed print[fk] type from lx to x to quiet compiler.
-+ * Removed redundant remain check.
-+ * Changed __u* types to uint* to avoid use of asm/types.h and
-+ * sys/types.h in userspace code.
-+ *
-+ * Revision 1.7 1999/12/01 22:20:51 rgb
-+ * Moved pfkey_lib_debug variable into the library.
-+ * Added pfkey version check into header parsing.
-+ * Added check for SATYPE only for those extensions that require a
-+ * non-zero value.
-+ *
-+ * Revision 1.6 1999/11/27 11:58:05 rgb
-+ * Added ipv6 headers.
-+ * Moved sadb_satype2proto protocol lookup table from
-+ * klips/net/ipsec/pfkey_v2_parser.c.
-+ * Enable lifetime_current checking.
-+ * Debugging error messages added.
-+ * Add argument to pfkey_msg_parse() for direction.
-+ * Consolidated the 4 1-d extension bitmap arrays into one 4-d array.
-+ * Add CVS log entry to bottom of file.
-+ * Moved auth and enc alg check to pfkey_msg_parse().
-+ * Enable accidentally disabled spirange parsing.
-+ * Moved protocol/algorithm checks from klips/net/ipsec/pfkey_v2_parser.c
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/prng.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,201 @@
-+/*
-+ * crypto-class pseudorandom number generator
-+ * currently uses same algorithm as RC4(TM), from Schneier 2nd ed p397
-+ * Copyright (C) 2002 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/*
-+ - prng_init - initialize PRNG from a key
-+ */
-+void
-+prng_init(prng, key, keylen)
-+struct prng *prng;
-+const unsigned char *key;
-+size_t keylen;
-+{
-+ unsigned char k[256];
-+ int i, j;
-+ unsigned const char *p;
-+ unsigned const char *keyend = key + keylen;
-+ unsigned char t;
-+
-+ for (i = 0; i <= 255; i++)
-+ prng->sbox[i] = i;
-+ p = key;
-+ for (i = 0; i <= 255; i++) {
-+ k[i] = *p++;
-+ if (p >= keyend)
-+ p = key;
-+ }
-+ j = 0;
-+ for (i = 0; i <= 255; i++) {
-+ j = (j + prng->sbox[i] + k[i]) & 0xff;
-+ t = prng->sbox[i];
-+ prng->sbox[i] = prng->sbox[j];
-+ prng->sbox[j] = t;
-+ k[i] = 0; /* clear out key memory */
-+ }
-+ prng->i = 0;
-+ prng->j = 0;
-+ prng->count = 0;
-+}
-+
-+/*
-+ - prng_bytes - get some pseudorandom bytes from PRNG
-+ */
-+void
-+prng_bytes(prng, dst, dstlen)
-+struct prng *prng;
-+unsigned char *dst;
-+size_t dstlen;
-+{
-+ int i, j, t;
-+ unsigned char *p = dst;
-+ size_t remain = dstlen;
-+# define MAX 4000000000ul
-+
-+ while (remain > 0) {
-+ i = (prng->i + 1) & 0xff;
-+ prng->i = i;
-+ j = (prng->j + prng->sbox[i]) & 0xff;
-+ prng->j = j;
-+ t = prng->sbox[i];
-+ prng->sbox[i] = prng->sbox[j];
-+ prng->sbox[j] = t;
-+ t = (t + prng->sbox[i]) & 0xff;
-+ *p++ = prng->sbox[t];
-+ remain--;
-+ }
-+ if (prng->count < MAX - dstlen)
-+ prng->count += dstlen;
-+ else
-+ prng->count = MAX;
-+}
-+
-+/*
-+ - prnt_count - how many bytes have been extracted from PRNG so far?
-+ */
-+unsigned long
-+prng_count(prng)
-+struct prng *prng;
-+{
-+ return prng->count;
-+}
-+
-+/*
-+ - prng_final - clear out PRNG to ensure nothing left in memory
-+ */
-+void
-+prng_final(prng)
-+struct prng *prng;
-+{
-+ int i;
-+
-+ for (i = 0; i <= 255; i++)
-+ prng->sbox[i] = 0;
-+ prng->i = 0;
-+ prng->j = 0;
-+ prng->count = 0; /* just for good measure */
-+}
-+
-+
-+
-+#ifdef PRNG_MAIN
-+
-+#include <stdio.h>
-+
-+void regress();
-+
-+int
-+main(argc, argv)
-+int argc;
-+char *argv[];
-+{
-+ struct prng pr;
-+ unsigned char buf[100];
-+ unsigned char *p;
-+ size_t n;
-+
-+ if (argc < 2) {
-+ fprintf(stderr, "Usage: %s {key|-r}\n", argv[0]);
-+ exit(2);
-+ }
-+
-+ if (strcmp(argv[1], "-r") == 0) {
-+ regress();
-+ fprintf(stderr, "regress() returned?!?\n");
-+ exit(1);
-+ }
-+
-+ prng_init(&pr, argv[1], strlen(argv[1]));
-+ prng_bytes(&pr, buf, 32);
-+ printf("0x");
-+ for (p = buf, n = 32; n > 0; p++, n--)
-+ printf("%02x", *p);
-+ printf("\n%lu bytes\n", prng_count(&pr));
-+ prng_final(&pr);
-+ exit(0);
-+}
-+
-+void
-+regress()
-+{
-+ struct prng pr;
-+ unsigned char buf[100];
-+ unsigned char *p;
-+ size_t n;
-+ /* somewhat non-random sample key */
-+ unsigned char key[] = "here we go gathering nuts in May";
-+ /* first thirty bytes of output from that key */
-+ unsigned char good[] = "\x3f\x02\x8e\x4a\x2a\xea\x23\x18\x92\x7c"
-+ "\x09\x52\x83\x61\xaa\x26\xce\xbb\x9d\x71"
-+ "\x71\xe5\x10\x22\xaf\x60\x54\x8d\x5b\x28";
-+ int nzero, none;
-+ int show = 0;
-+
-+ prng_init(&pr, key, strlen(key));
-+ prng_bytes(&pr, buf, sizeof(buf));
-+ for (p = buf, n = sizeof(buf); n > 0; p++, n--) {
-+ if (*p == 0)
-+ nzero++;
-+ if (*p == 255)
-+ none++;
-+ }
-+ if (nzero > 3 || none > 3) {
-+ fprintf(stderr, "suspiciously non-random output!\n");
-+ show = 1;
-+ }
-+ if (memcmp(buf, good, strlen(good)) != 0) {
-+ fprintf(stderr, "incorrect output!\n");
-+ show = 1;
-+ }
-+ if (show) {
-+ fprintf(stderr, "0x");
-+ for (p = buf, n = sizeof(buf); n > 0; p++, n--)
-+ fprintf(stderr, "%02x", *p);
-+ fprintf(stderr, "\n");
-+ exit(1);
-+ }
-+ if (prng_count(&pr) != sizeof(buf)) {
-+ fprintf(stderr, "got %u bytes, but count is %lu\n",
-+ sizeof(buf), prng_count(&pr));
-+ exit(1);
-+ }
-+ prng_final(&pr);
-+ exit(0);
-+}
-+
-+#endif /* PRNG_MAIN */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/rangetoa.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,60 @@
-+/*
-+ * convert binary form of address range to ASCII
-+ * Copyright (C) 1998, 1999 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/*
-+ - rangetoa - convert address range to ASCII
-+ */
-+size_t /* space needed for full conversion */
-+rangetoa(addrs, format, dst, dstlen)
-+struct in_addr addrs[2];
-+int format; /* character */
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ size_t len;
-+ size_t rest;
-+ int n;
-+ char *p;
-+
-+ switch (format) {
-+ case 0:
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+
-+ len = addrtoa(addrs[0], 0, dst, dstlen);
-+ if (len < dstlen)
-+ for (p = dst + len - 1, n = 3; len < dstlen && n > 0;
-+ p++, len++, n--)
-+ *p = '.';
-+ else
-+ p = NULL;
-+ if (len < dstlen)
-+ rest = dstlen - len;
-+ else {
-+ if (dstlen > 0)
-+ *(dst + dstlen - 1) = '\0';
-+ rest = 0;
-+ }
-+
-+ len += addrtoa(addrs[1], 0, p, rest);
-+
-+ return len;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/satot.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,133 @@
-+/*
-+ * convert from binary form of SA ID to text
-+ * Copyright (C) 2000, 2001 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+static struct typename {
-+ char type;
-+ char *name;
-+} typenames[] = {
-+ { SA_AH, "ah" },
-+ { SA_ESP, "esp" },
-+ { SA_IPIP, "tun" },
-+ { SA_COMP, "comp" },
-+ { SA_INT, "int" },
-+ { 0, NULL }
-+};
-+
-+/*
-+ - satot - convert SA to text "ah507@1.2.3.4"
-+ */
-+size_t /* space needed for full conversion */
-+satot(sa, format, dst, dstlen)
-+const ip_said *sa;
-+int format; /* character */
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ size_t len = 0; /* 0 means "not recognized yet" */
-+ int base;
-+ int showversion; /* use delimiter to show IP version? */
-+ struct typename *tn;
-+ char *p;
-+ char *pre;
-+ char buf[10+1+ULTOT_BUF+ADDRTOT_BUF];
-+ char unk[10];
-+
-+ switch (format) {
-+ case 0:
-+ base = 16;
-+ showversion = 1;
-+ break;
-+ case 'f':
-+ base = 17;
-+ showversion = 1;
-+ break;
-+ case 'x':
-+ base = 'x';
-+ showversion = 0;
-+ break;
-+ case 'd':
-+ base = 10;
-+ showversion = 0;
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+
-+ memset(buf, 0, sizeof(buf));
-+
-+ pre = NULL;
-+ for (tn = typenames; tn->name != NULL; tn++)
-+ if (sa->proto == tn->type) {
-+ pre = tn->name;
-+ break; /* NOTE BREAK OUT */
-+ }
-+ if (pre == NULL) { /* unknown protocol */
-+ strcpy(unk, "unk");
-+ (void) ultot((unsigned char)sa->proto, 10, unk+strlen(unk),
-+ sizeof(unk)-strlen(unk));
-+ pre = unk;
-+ }
-+
-+ if (strcmp(pre, PASSTHROUGHTYPE) == 0 &&
-+ sa->spi == PASSTHROUGHSPI &&
-+ isunspecaddr(&sa->dst)) {
-+ strcpy(buf, (addrtypeof(&sa->dst) == AF_INET) ?
-+ PASSTHROUGH4NAME :
-+ PASSTHROUGH6NAME);
-+ len = strlen(buf);
-+ }
-+
-+ if (sa->proto == SA_INT) {
-+ switch (ntohl(sa->spi)) {
-+ case SPI_PASS: p = "%pass"; break;
-+ case SPI_DROP: p = "%drop"; break;
-+ case SPI_REJECT: p = "%reject"; break;
-+ case SPI_HOLD: p = "%hold"; break;
-+ case SPI_TRAP: p = "%trap"; break;
-+ case SPI_TRAPSUBNET: p = "%trapsubnet"; break;
-+ default: p = NULL; break;
-+ }
-+ if (p != NULL) {
-+ strcpy(buf, p);
-+ len = strlen(buf);
-+ }
-+ }
-+
-+ if (len == 0) { /* general case needed */
-+ strcpy(buf, pre);
-+ len = strlen(buf);
-+ if (showversion) {
-+ *(buf+len) = (addrtypeof(&sa->dst) == AF_INET) ? '.' :
-+ ':';
-+ len++;
-+ *(buf+len) = '\0';
-+ }
-+ len += ultot(ntohl(sa->spi), base, buf+len, sizeof(buf)-len);
-+ *(buf+len-1) = '@';
-+ len += addrtot(&sa->dst, 0, buf+len, sizeof(buf)-len);
-+ *(buf+len) = '\0';
-+ }
-+
-+ if (dst != NULL) {
-+ if (len > dstlen)
-+ *(buf+dstlen-1) = '\0';
-+ strcpy(dst, buf);
-+ }
-+ return len;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/subnetof.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,59 @@
-+/*
-+ * minor network-address manipulation utilities
-+ * Copyright (C) 1998, 1999 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/*
-+ - subnetof - given address and mask, return subnet part
-+ */
-+struct in_addr
-+subnetof(addr, mask)
-+struct in_addr addr;
-+struct in_addr mask;
-+{
-+ struct in_addr result;
-+
-+ result.s_addr = addr.s_addr & mask.s_addr;
-+ return result;
-+}
-+
-+/*
-+ - hostof - given address and mask, return host part
-+ */
-+struct in_addr
-+hostof(addr, mask)
-+struct in_addr addr;
-+struct in_addr mask;
-+{
-+ struct in_addr result;
-+
-+ result.s_addr = addr.s_addr & ~mask.s_addr;
-+ return result;
-+}
-+
-+/*
-+ - broadcastof - given (network) address and mask, return broadcast address
-+ */
-+struct in_addr
-+broadcastof(addr, mask)
-+struct in_addr addr;
-+struct in_addr mask;
-+{
-+ struct in_addr result;
-+
-+ result.s_addr = addr.s_addr | ~mask.s_addr;
-+ return result;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/subnettoa.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,61 @@
-+/*
-+ * convert binary form of subnet description to ASCII
-+ * Copyright (C) 1998, 1999 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/*
-+ - subnettoa - convert address and mask to ASCII "addr/mask"
-+ * Output expresses the mask as a bit count if possible, else dotted decimal.
-+ */
-+size_t /* space needed for full conversion */
-+subnettoa(addr, mask, format, dst, dstlen)
-+struct in_addr addr;
-+struct in_addr mask;
-+int format; /* character */
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ size_t len;
-+ size_t rest;
-+ int n;
-+ char *p;
-+
-+ switch (format) {
-+ case 0:
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+
-+ len = addrtoa(addr, 0, dst, dstlen);
-+ if (len < dstlen) {
-+ dst[len - 1] = '/';
-+ p = dst + len;
-+ rest = dstlen - len;
-+ } else {
-+ p = NULL;
-+ rest = 0;
-+ }
-+
-+ n = masktobits(mask);
-+ if (n >= 0)
-+ len += ultoa((unsigned long)n, 10, p, rest);
-+ else
-+ len += addrtoa(mask, 0, p, rest);
-+
-+ return len;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/ultoa.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,66 @@
-+/*
-+ * convert unsigned long to ASCII
-+ * Copyright (C) 1998, 1999 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/*
-+ - ultoa - convert unsigned long to decimal ASCII
-+ */
-+size_t /* length required for full conversion */
-+ultoa(n, base, dst, dstlen)
-+unsigned long n;
-+int base;
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ char buf[3*sizeof(unsigned long) + 1];
-+ char *bufend = buf + sizeof(buf);
-+ size_t len;
-+ char *p;
-+ static char hex[] = "0123456789abcdef";
-+
-+ p = bufend;
-+ *--p = '\0';
-+ if (base == 10) {
-+ do {
-+ *--p = n%10 + '0';
-+ n /= 10;
-+ } while (n != 0);
-+ } else if (base == 16) {
-+ do {
-+ *--p = hex[n&0xf];
-+ n >>= 4;
-+ } while (n != 0);
-+ *--p = 'x';
-+ *--p = '0';
-+ } else if (base == 8) {
-+ do {
-+ *--p = (n&07) + '0';
-+ n >>= 3;
-+ } while (n != 0);
-+ *--p = '0';
-+ } else
-+ *--p = '?';
-+
-+ len = bufend - p;
-+
-+ if (dstlen > 0) {
-+ if (len > dstlen)
-+ *(p + dstlen - 1) = '\0';
-+ strcpy(dst, p);
-+ }
-+ return len;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/libfreeswan/ultot.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,82 @@
-+/*
-+ * convert unsigned long to text
-+ * Copyright (C) 2000 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+#include "openswan.h"
-+
-+/*
-+ - ultot - convert unsigned long to text
-+ */
-+size_t /* length required for full conversion */
-+ultot(n, base, dst, dstlen)
-+unsigned long n;
-+int base;
-+char *dst; /* need not be valid if dstlen is 0 */
-+size_t dstlen;
-+{
-+ char buf[3*sizeof(unsigned long) + 1];
-+ char *bufend = buf + sizeof(buf);
-+ size_t len;
-+ char *p;
-+ static char hex[] = "0123456789abcdef";
-+# define HEX32 (32/4)
-+
-+ p = bufend;
-+ *--p = '\0';
-+ switch (base) {
-+ case 10:
-+ case 'd':
-+ do {
-+ *--p = n%10 + '0';
-+ n /= 10;
-+ } while (n != 0);
-+ break;
-+ case 16:
-+ case 17:
-+ case 'x':
-+ do {
-+ *--p = hex[n&0xf];
-+ n >>= 4;
-+ } while (n != 0);
-+ if (base == 17)
-+ while (bufend - p < HEX32 + 1)
-+ *--p = '0';
-+ if (base == 'x') {
-+ *--p = 'x';
-+ *--p = '0';
-+ }
-+ break;
-+ case 8:
-+ case 'o':
-+ do {
-+ *--p = (n&07) + '0';
-+ n >>= 3;
-+ } while (n != 0);
-+ if (base == 'o')
-+ *--p = '0';
-+ break;
-+ default:
-+ return 0;
-+ break;
-+ }
-+
-+ len = bufend - p;
-+ if (dstlen > 0) {
-+ if (len > dstlen)
-+ *(p + dstlen - 1) = '\0';
-+ strcpy(dst, p);
-+ }
-+ return len;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/Makefile Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,118 @@
-+# (kernel) Makefile for IPCOMP zlib deflate code
-+# Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+# Copyright (C) 2000 Svenning Soerensen
-+#
-+# 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+#
-+# 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.
-+#
-+# RCSID $Id$
-+#
-+
-+
-+
-+include ../Makefile.inc
-+
-+
-+
-+ifndef TOPDIR
-+TOPDIR := /usr/src/linux
-+endif
-+
-+
-+L_TARGET := zlib.a
-+
-+obj-y :=
-+
-+include Makefile.objs
-+
-+EXTRA_CFLAGS += $(KLIPSCOMPILE)
-+
-+EXTRA_CFLAGS += -Wall
-+#EXTRA_CFLAGS += -Wconversion
-+#EXTRA_CFLAGS += -Wmissing-prototypes
-+EXTRA_CFLAGS += -Wpointer-arith
-+#EXTRA_CFLAGS += -Wcast-qual
-+#EXTRA_CFLAGS += -Wmissing-declarations
-+EXTRA_CFLAGS += -Wstrict-prototypes
-+#EXTRA_CFLAGS += -pedantic
-+#EXTRA_CFLAGS += -W
-+#EXTRA_CFLAGS += -Wwrite-strings
-+EXTRA_CFLAGS += -Wbad-function-cast
-+EXTRA_CFLAGS += -DIPCOMP_PREFIX
-+
-+.S.o:
-+ $(CC) -D__ASSEMBLY__ -DNO_UNDERLINE -traditional -c $< -o $*.o
-+
-+asm-obj-$(CONFIG_M586) += match586.o
-+asm-obj-$(CONFIG_M586TSC) += match586.o
-+asm-obj-$(CONFIG_M586MMX) += match586.o
-+asm-obj-$(CONFIG_M686) += match686.o
-+asm-obj-$(CONFIG_MPENTIUMIII) += match686.o
-+asm-obj-$(CONFIG_MPENTIUM4) += match686.o
-+asm-obj-$(CONFIG_MK6) += match586.o
-+asm-obj-$(CONFIG_MK7) += match686.o
-+asm-obj-$(CONFIG_MCRUSOE) += match586.o
-+asm-obj-$(CONFIG_MWINCHIPC6) += match586.o
-+asm-obj-$(CONFIG_MWINCHIP2) += match686.o
-+asm-obj-$(CONFIG_MWINCHIP3D) += match686.o
-+
-+obj-y += $(asm-obj-y)
-+ifneq ($(strip $(asm-obj-y)),)
-+ EXTRA_CFLAGS += -DASMV
-+endif
-+
-+active-objs := $(sort $(obj-y) $(obj-m))
-+L_OBJS := $(obj-y)
-+M_OBJS := $(obj-m)
-+MIX_OBJS := $(filter $(export-objs), $(active-objs))
-+
-+include $(TOPDIR)/Rules.make
-+
-+$(obj-y) : $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
-+
-+
-+clean:
-+ -rm -f *.o *.a
-+
-+checkprograms:
-+programs: $(L_TARGET)
-+
-+#
-+# $Log$
-+# Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+# Turn off EOLN_NATIVE flag
-+#
-+# (Logical change 1.5010)
-+#
-+# Revision 1.9 2002/04/24 07:55:32 mcr
-+# #include patches and Makefiles for post-reorg compilation.
-+#
-+# Revision 1.8 2002/04/24 07:36:44 mcr
-+# Moved from ./zlib/Makefile,v
-+#
-+# Revision 1.7 2002/03/27 23:34:35 mcr
-+# added programs: target
-+#
-+# Revision 1.6 2001/12/05 20:19:08 henry
-+# use new compile-control variable
-+#
-+# Revision 1.5 2001/11/27 16:38:08 mcr
-+# added new "checkprograms" target to deal with programs that
-+# are required for "make check", but that may not be ready to
-+# build for every user due to external dependancies.
-+#
-+# Revision 1.4 2001/10/24 14:46:24 henry
-+# Makefile.inc
-+#
-+# Revision 1.3 2001/04/21 23:05:24 rgb
-+# Update asm directives for 2.4 style makefiles.
-+#
-+# Revision 1.2 2001/01/29 22:22:00 rgb
-+# Convert to 2.4 new style with back compat.
-+#
-+# Revision 1.1.1.1 2000/09/29 18:51:33 rgb
-+# zlib_beginnings
-+#
-+#
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/Makefile.objs Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,27 @@
-+obj-$(CONFIG_IPSEC_IPCOMP) += adler32.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += deflate.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += infblock.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += infcodes.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += inffast.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += inflate.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += inftrees.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += infutil.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += trees.o
-+obj-$(CONFIG_IPSEC_IPCOMP) += zutil.o
-+
-+asm-obj-$(CONFIG_M586) += ${LIBZLIBSRCDIR}/match586.o
-+asm-obj-$(CONFIG_M586TSC) += ${LIBZLIBSRCDIR}/match586.o
-+asm-obj-$(CONFIG_M586MMX) += ${LIBZLIBSRCDIR}/match586.o
-+asm-obj-$(CONFIG_M686) += ${LIBZLIBSRCDIR}/match686.o
-+asm-obj-$(CONFIG_MPENTIUMIII) += ${LIBZLIBSRCDIR}/match686.o
-+asm-obj-$(CONFIG_MPENTIUM4) += ${LIBZLIBSRCDIR}/match686.o
-+asm-obj-$(CONFIG_MK6) += ${LIBZLIBSRCDIR}/match586.o
-+asm-obj-$(CONFIG_MK7) += ${LIBZLIBSRCDIR}/match686.o
-+asm-obj-$(CONFIG_MCRUSOE) += ${LIBZLIBSRCDIR}/match586.o
-+asm-obj-$(CONFIG_MWINCHIPC6) += ${LIBZLIBSRCDIR}/match586.o
-+asm-obj-$(CONFIG_MWINCHIP2) += ${LIBZLIBSRCDIR}/match686.o
-+asm-obj-$(CONFIG_MWINCHIP3D) += ${LIBZLIBSRCDIR}/match686.o
-+
-+EXTRA_CFLAGS += -DIPCOMP_PREFIX
-+
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/README Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,147 @@
-+zlib 1.1.4 is a general purpose data compression library. All the code
-+is thread safe. The data format used by the zlib library
-+is described by RFCs (Request for Comments) 1950 to 1952 in the files
-+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
-+format) and rfc1952.txt (gzip format). These documents are also available in
-+other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
-+
-+All functions of the compression library are documented in the file zlib.h
-+(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
-+example of the library is given in the file example.c which also tests that
-+the library is working correctly. Another example is given in the file
-+minigzip.c. The compression library itself is composed of all source files
-+except example.c and minigzip.c.
-+
-+To compile all files and run the test program, follow the instructions
-+given at the top of Makefile. In short "make test; make install"
-+should work for most machines. For Unix: "./configure; make test; make install"
-+For MSDOS, use one of the special makefiles such as Makefile.msc.
-+For VMS, use Make_vms.com or descrip.mms.
-+
-+Questions about zlib should be sent to <zlib@gzip.org>, or to
-+Gilles Vollant <info@winimage.com> for the Windows DLL version.
-+The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/
-+Before reporting a problem, please check this site to verify that
-+you have the latest version of zlib; otherwise get the latest version and
-+check whether the problem still exists or not.
-+
-+PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html
-+before asking for help.
-+
-+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
-+issue of Dr. Dobb's Journal; a copy of the article is available in
-+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
-+
-+The changes made in version 1.1.4 are documented in the file ChangeLog.
-+The only changes made since 1.1.3 are bug corrections:
-+
-+- ZFREE was repeated on same allocation on some error conditions.
-+ This creates a security problem described in
-+ http://www.zlib.org/advisory-2002-03-11.txt
-+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
-+- Avoid accesses before window for invalid distances with inflate window
-+ less than 32K.
-+- force windowBits > 8 to avoid a bug in the encoder for a window size
-+ of 256 bytes. (A complete fix will be available in 1.1.5).
-+
-+The beta version 1.1.5beta includes many more changes. A new official
-+version 1.1.5 will be released as soon as extensive testing has been
-+completed on it.
-+
-+
-+Unsupported third party contributions are provided in directory "contrib".
-+
-+A Java implementation of zlib is available in the Java Development Kit
-+http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
-+See the zlib home page http://www.zlib.org for details.
-+
-+A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
-+is in the CPAN (Comprehensive Perl Archive Network) sites
-+http://www.cpan.org/modules/by-module/Compress/
-+
-+A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
-+is available in Python 1.5 and later versions, see
-+http://www.python.org/doc/lib/module-zlib.html
-+
-+A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
-+is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
-+
-+An experimental package to read and write files in .zip format,
-+written on top of zlib by Gilles Vollant <info@winimage.com>, is
-+available at http://www.winimage.com/zLibDll/unzip.html
-+and also in the contrib/minizip directory of zlib.
-+
-+
-+Notes for some targets:
-+
-+- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
-+ and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
-+ The zlib DLL support was initially done by Alessandro Iacopetti and is
-+ now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
-+ home page at http://www.winimage.com/zLibDll
-+
-+ From Visual Basic, you can call the DLL functions which do not take
-+ a structure as argument: compress, uncompress and all gz* functions.
-+ See contrib/visual-basic.txt for more information, or get
-+ http://www.tcfb.com/dowseware/cmp-z-it.zip
-+
-+- For 64-bit Irix, deflate.c must be compiled without any optimization.
-+ With -O, one libpng test fails. The test works in 32 bit mode (with
-+ the -n32 compiler flag). The compiler bug has been reported to SGI.
-+
-+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1
-+ it works when compiled with cc.
-+
-+- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
-+ is necessary to get gzprintf working correctly. This is done by configure.
-+
-+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
-+ with other compilers. Use "make test" to check your compiler.
-+
-+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
-+
-+- For Turbo C the small model is supported only with reduced performance to
-+ avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
-+
-+- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
-+ Per Harald Myrvang <perm@stud.cs.uit.no>
-+
-+
-+Acknowledgments:
-+
-+ The deflate format used by zlib was defined by Phil Katz. The deflate
-+ and zlib specifications were written by L. Peter Deutsch. Thanks to all the
-+ people who reported problems and suggested various improvements in zlib;
-+ they are too numerous to cite here.
-+
-+Copyright notice:
-+
-+ (C) 1995-2002 Jean-loup Gailly and Mark Adler
-+
-+ This software is provided 'as-is', without any express or implied
-+ warranty. In no event will the authors be held liable for any damages
-+ arising from the use of this software.
-+
-+ Permission is granted to anyone to use this software for any purpose,
-+ including commercial applications, and to alter it and redistribute it
-+ freely, subject to the following restrictions:
-+
-+ 1. The origin of this software must not be misrepresented; you must not
-+ claim that you wrote the original software. If you use this software
-+ in a product, an acknowledgment in the product documentation would be
-+ appreciated but is not required.
-+ 2. Altered source versions must be plainly marked as such, and must not be
-+ misrepresented as being the original software.
-+ 3. This notice may not be removed or altered from any source distribution.
-+
-+ Jean-loup Gailly Mark Adler
-+ jloup@gzip.org madler@alumni.caltech.edu
-+
-+If you use the zlib library in a product, we would appreciate *not*
-+receiving lengthy legal documents to sign. The sources are provided
-+for free but without warranty of any kind. The library has been
-+entirely written by Jean-loup Gailly and Mark Adler; it does not
-+include third-party code.
-+
-+If you redistribute modified sources, we would appreciate that you include
-+in the file ChangeLog history information documenting your changes.
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/README.freeswan Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,13 @@
-+The only changes made to these files for use in FreeS/WAN are:
-+
-+ - In zconf.h, macros are defined to prefix global symbols with "ipcomp_"
-+ (or "_ipcomp"), when compiled with -DIPCOMP_PREFIX.
-+ - The copyright strings are defined local (static)
-+
-+ The above changes are made to avoid name collisions with ppp_deflate
-+ and ext2compr.
-+
-+ - Files not needed for FreeS/WAN have been removed
-+
-+ See the "README" file for information about where to obtain the complete
-+ zlib package.
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/adler32.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,49 @@
-+/* adler32.c -- compute the Adler-32 checksum of a data stream
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* @(#) $Id$ */
-+
-+#include <zlib/zlib.h>
-+#include "zconf.h"
-+
-+#define BASE 65521L /* largest prime smaller than 65536 */
-+#define NMAX 5552
-+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
-+
-+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
-+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
-+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
-+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
-+#define DO16(buf) DO8(buf,0); DO8(buf,8);
-+
-+/* ========================================================================= */
-+uLong ZEXPORT adler32(adler, buf, len)
-+ uLong adler;
-+ const Bytef *buf;
-+ uInt len;
-+{
-+ unsigned long s1 = adler & 0xffff;
-+ unsigned long s2 = (adler >> 16) & 0xffff;
-+ int k;
-+
-+ if (buf == Z_NULL) return 1L;
-+
-+ while (len > 0) {
-+ k = len < NMAX ? len : NMAX;
-+ len -= k;
-+ while (k >= 16) {
-+ DO16(buf);
-+ buf += 16;
-+ k -= 16;
-+ }
-+ if (k != 0) do {
-+ s1 += *buf++;
-+ s2 += s1;
-+ } while (--k);
-+ s1 %= BASE;
-+ s2 %= BASE;
-+ }
-+ return (s2 << 16) | s1;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/deflate.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1351 @@
-+/* deflate.c -- compress data using the deflation algorithm
-+ * Copyright (C) 1995-2002 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/*
-+ * ALGORITHM
-+ *
-+ * The "deflation" process depends on being able to identify portions
-+ * of the input text which are identical to earlier input (within a
-+ * sliding window trailing behind the input currently being processed).
-+ *
-+ * The most straightforward technique turns out to be the fastest for
-+ * most input files: try all possible matches and select the longest.
-+ * The key feature of this algorithm is that insertions into the string
-+ * dictionary are very simple and thus fast, and deletions are avoided
-+ * completely. Insertions are performed at each input character, whereas
-+ * string matches are performed only when the previous match ends. So it
-+ * is preferable to spend more time in matches to allow very fast string
-+ * insertions and avoid deletions. The matching algorithm for small
-+ * strings is inspired from that of Rabin & Karp. A brute force approach
-+ * is used to find longer strings when a small match has been found.
-+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
-+ * (by Leonid Broukhis).
-+ * A previous version of this file used a more sophisticated algorithm
-+ * (by Fiala and Greene) which is guaranteed to run in linear amortized
-+ * time, but has a larger average cost, uses more memory and is patented.
-+ * However the F&G algorithm may be faster for some highly redundant
-+ * files if the parameter max_chain_length (described below) is too large.
-+ *
-+ * ACKNOWLEDGEMENTS
-+ *
-+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
-+ * I found it in 'freeze' written by Leonid Broukhis.
-+ * Thanks to many people for bug reports and testing.
-+ *
-+ * REFERENCES
-+ *
-+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
-+ * Available in ftp://ds.internic.net/rfc/rfc1951.txt
-+ *
-+ * A description of the Rabin and Karp algorithm is given in the book
-+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
-+ *
-+ * Fiala,E.R., and Greene,D.H.
-+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
-+ *
-+ */
-+
-+/* @(#) $Id$ */
-+
-+#include "deflate.h"
-+
-+local const char deflate_copyright[] =
-+ " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly ";
-+/*
-+ If you use the zlib library in a product, an acknowledgment is welcome
-+ in the documentation of your product. If for some reason you cannot
-+ include such an acknowledgment, I would appreciate that you keep this
-+ copyright string in the executable of your product.
-+ */
-+
-+/* ===========================================================================
-+ * Function prototypes.
-+ */
-+typedef enum {
-+ need_more, /* block not completed, need more input or more output */
-+ block_done, /* block flush performed */
-+ finish_started, /* finish started, need only more output at next deflate */
-+ finish_done /* finish done, accept no more input or output */
-+} block_state;
-+
-+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
-+/* Compression function. Returns the block state after the call. */
-+
-+local void fill_window OF((deflate_state *s));
-+local block_state deflate_stored OF((deflate_state *s, int flush));
-+local block_state deflate_fast OF((deflate_state *s, int flush));
-+local block_state deflate_slow OF((deflate_state *s, int flush));
-+local void lm_init OF((deflate_state *s));
-+local void putShortMSB OF((deflate_state *s, uInt b));
-+local void flush_pending OF((z_streamp strm));
-+local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
-+#ifdef ASMV
-+ void match_init OF((void)); /* asm code initialization */
-+ uInt longest_match OF((deflate_state *s, IPos cur_match));
-+#else
-+local uInt longest_match OF((deflate_state *s, IPos cur_match));
-+#endif
-+
-+#ifdef DEBUG
-+local void check_match OF((deflate_state *s, IPos start, IPos match,
-+ int length));
-+#endif
-+
-+/* ===========================================================================
-+ * Local data
-+ */
-+
-+#define NIL 0
-+/* Tail of hash chains */
-+
-+#ifndef TOO_FAR
-+# define TOO_FAR 4096
-+#endif
-+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
-+
-+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-+/* Minimum amount of lookahead, except at the end of the input file.
-+ * See deflate.c for comments about the MIN_MATCH+1.
-+ */
-+
-+/* Values for max_lazy_match, good_match and max_chain_length, depending on
-+ * the desired pack level (0..9). The values given below have been tuned to
-+ * exclude worst case performance for pathological files. Better values may be
-+ * found for specific files.
-+ */
-+typedef struct config_s {
-+ ush good_length; /* reduce lazy search above this match length */
-+ ush max_lazy; /* do not perform lazy search above this match length */
-+ ush nice_length; /* quit search above this match length */
-+ ush max_chain;
-+ compress_func func;
-+} config;
-+
-+local const config configuration_table[10] = {
-+/* good lazy nice chain */
-+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
-+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* maximum speed, no lazy matches */
-+/* 2 */ {4, 5, 16, 8, deflate_fast},
-+/* 3 */ {4, 6, 32, 32, deflate_fast},
-+
-+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
-+/* 5 */ {8, 16, 32, 32, deflate_slow},
-+/* 6 */ {8, 16, 128, 128, deflate_slow},
-+/* 7 */ {8, 32, 128, 256, deflate_slow},
-+/* 8 */ {32, 128, 258, 1024, deflate_slow},
-+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
-+
-+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
-+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
-+ * meaning.
-+ */
-+
-+#define EQUAL 0
-+/* result of memcmp for equal strings */
-+
-+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
-+
-+/* ===========================================================================
-+ * Update a hash value with the given input byte
-+ * IN assertion: all calls to to UPDATE_HASH are made with consecutive
-+ * input characters, so that a running hash key can be computed from the
-+ * previous key instead of complete recalculation each time.
-+ */
-+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
-+
-+
-+/* ===========================================================================
-+ * Insert string str in the dictionary and set match_head to the previous head
-+ * of the hash chain (the most recent string with same hash key). Return
-+ * the previous length of the hash chain.
-+ * If this file is compiled with -DFASTEST, the compression level is forced
-+ * to 1, and no hash chains are maintained.
-+ * IN assertion: all calls to to INSERT_STRING are made with consecutive
-+ * input characters and the first MIN_MATCH bytes of str are valid
-+ * (except for the last MIN_MATCH-1 bytes of the input file).
-+ */
-+#ifdef FASTEST
-+#define INSERT_STRING(s, str, match_head) \
-+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
-+ match_head = s->head[s->ins_h], \
-+ s->head[s->ins_h] = (Pos)(str))
-+#else
-+#define INSERT_STRING(s, str, match_head) \
-+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
-+ s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
-+ s->head[s->ins_h] = (Pos)(str))
-+#endif
-+
-+/* ===========================================================================
-+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
-+ * prev[] will be initialized on the fly.
-+ */
-+#define CLEAR_HASH(s) \
-+ s->head[s->hash_size-1] = NIL; \
-+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
-+
-+/* ========================================================================= */
-+int ZEXPORT deflateInit_(strm, level, version, stream_size)
-+ z_streamp strm;
-+ int level;
-+ const char *version;
-+ int stream_size;
-+{
-+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
-+ Z_DEFAULT_STRATEGY, version, stream_size);
-+ /* To do: ignore strm->next_in if we use it as window */
-+}
-+
-+/* ========================================================================= */
-+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
-+ version, stream_size)
-+ z_streamp strm;
-+ int level;
-+ int method;
-+ int windowBits;
-+ int memLevel;
-+ int strategy;
-+ const char *version;
-+ int stream_size;
-+{
-+ deflate_state *s;
-+ int noheader = 0;
-+ static const char* my_version = ZLIB_VERSION;
-+
-+ ushf *overlay;
-+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
-+ * output size for (length,distance) codes is <= 24 bits.
-+ */
-+
-+ if (version == Z_NULL || version[0] != my_version[0] ||
-+ stream_size != sizeof(z_stream)) {
-+ return Z_VERSION_ERROR;
-+ }
-+ if (strm == Z_NULL) return Z_STREAM_ERROR;
-+
-+ strm->msg = Z_NULL;
-+ if (strm->zalloc == Z_NULL) {
-+ return Z_STREAM_ERROR;
-+/* strm->zalloc = zcalloc;
-+ strm->opaque = (voidpf)0;*/
-+ }
-+ if (strm->zfree == Z_NULL) return Z_STREAM_ERROR; /* strm->zfree = zcfree; */
-+
-+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
-+#ifdef FASTEST
-+ level = 1;
-+#endif
-+
-+ if (windowBits < 0) { /* undocumented feature: suppress zlib header */
-+ noheader = 1;
-+ windowBits = -windowBits;
-+ }
-+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
-+ windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
-+ strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
-+ return Z_STREAM_ERROR;
-+ }
-+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
-+ if (s == Z_NULL) return Z_MEM_ERROR;
-+ strm->state = (struct internal_state FAR *)s;
-+ s->strm = strm;
-+
-+ s->noheader = noheader;
-+ s->w_bits = windowBits;
-+ s->w_size = 1 << s->w_bits;
-+ s->w_mask = s->w_size - 1;
-+
-+ s->hash_bits = memLevel + 7;
-+ s->hash_size = 1 << s->hash_bits;
-+ s->hash_mask = s->hash_size - 1;
-+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
-+
-+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
-+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
-+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
-+
-+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
-+
-+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
-+ s->pending_buf = (uchf *) overlay;
-+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
-+
-+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
-+ s->pending_buf == Z_NULL) {
-+ strm->msg = ERR_MSG(Z_MEM_ERROR);
-+ deflateEnd (strm);
-+ return Z_MEM_ERROR;
-+ }
-+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
-+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
-+
-+ s->level = level;
-+ s->strategy = strategy;
-+ s->method = (Byte)method;
-+
-+ return deflateReset(strm);
-+}
-+
-+/* ========================================================================= */
-+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
-+ z_streamp strm;
-+ const Bytef *dictionary;
-+ uInt dictLength;
-+{
-+ deflate_state *s;
-+ uInt length = dictLength;
-+ uInt n;
-+ IPos hash_head = 0;
-+
-+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
-+ strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
-+
-+ s = strm->state;
-+ strm->adler = adler32(strm->adler, dictionary, dictLength);
-+
-+ if (length < MIN_MATCH) return Z_OK;
-+ if (length > MAX_DIST(s)) {
-+ length = MAX_DIST(s);
-+#ifndef USE_DICT_HEAD
-+ dictionary += dictLength - length; /* use the tail of the dictionary */
-+#endif
-+ }
-+ zmemcpy(s->window, dictionary, length);
-+ s->strstart = length;
-+ s->block_start = (long)length;
-+
-+ /* Insert all strings in the hash table (except for the last two bytes).
-+ * s->lookahead stays null, so s->ins_h will be recomputed at the next
-+ * call of fill_window.
-+ */
-+ s->ins_h = s->window[0];
-+ UPDATE_HASH(s, s->ins_h, s->window[1]);
-+ for (n = 0; n <= length - MIN_MATCH; n++) {
-+ INSERT_STRING(s, n, hash_head);
-+ }
-+ if (hash_head) hash_head = 0; /* to make compiler happy */
-+ return Z_OK;
-+}
-+
-+/* ========================================================================= */
-+int ZEXPORT deflateReset (strm)
-+ z_streamp strm;
-+{
-+ deflate_state *s;
-+
-+ if (strm == Z_NULL || strm->state == Z_NULL ||
-+ strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
-+
-+ strm->total_in = strm->total_out = 0;
-+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
-+ strm->data_type = Z_UNKNOWN;
-+
-+ s = (deflate_state *)strm->state;
-+ s->pending = 0;
-+ s->pending_out = s->pending_buf;
-+
-+ if (s->noheader < 0) {
-+ s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
-+ }
-+ s->status = s->noheader ? BUSY_STATE : INIT_STATE;
-+ strm->adler = 1;
-+ s->last_flush = Z_NO_FLUSH;
-+
-+ _tr_init(s);
-+ lm_init(s);
-+
-+ return Z_OK;
-+}
-+
-+/* ========================================================================= */
-+int ZEXPORT deflateParams(strm, level, strategy)
-+ z_streamp strm;
-+ int level;
-+ int strategy;
-+{
-+ deflate_state *s;
-+ compress_func func;
-+ int err = Z_OK;
-+
-+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-+ s = strm->state;
-+
-+ if (level == Z_DEFAULT_COMPRESSION) {
-+ level = 6;
-+ }
-+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
-+ return Z_STREAM_ERROR;
-+ }
-+ func = configuration_table[s->level].func;
-+
-+ if (func != configuration_table[level].func && strm->total_in != 0) {
-+ /* Flush the last buffer: */
-+ err = deflate(strm, Z_PARTIAL_FLUSH);
-+ }
-+ if (s->level != level) {
-+ s->level = level;
-+ s->max_lazy_match = configuration_table[level].max_lazy;
-+ s->good_match = configuration_table[level].good_length;
-+ s->nice_match = configuration_table[level].nice_length;
-+ s->max_chain_length = configuration_table[level].max_chain;
-+ }
-+ s->strategy = strategy;
-+ return err;
-+}
-+
-+/* =========================================================================
-+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
-+ * IN assertion: the stream state is correct and there is enough room in
-+ * pending_buf.
-+ */
-+local void putShortMSB (s, b)
-+ deflate_state *s;
-+ uInt b;
-+{
-+ put_byte(s, (Byte)(b >> 8));
-+ put_byte(s, (Byte)(b & 0xff));
-+}
-+
-+/* =========================================================================
-+ * Flush as much pending output as possible. All deflate() output goes
-+ * through this function so some applications may wish to modify it
-+ * to avoid allocating a large strm->next_out buffer and copying into it.
-+ * (See also read_buf()).
-+ */
-+local void flush_pending(strm)
-+ z_streamp strm;
-+{
-+ unsigned len = strm->state->pending;
-+
-+ if (len > strm->avail_out) len = strm->avail_out;
-+ if (len == 0) return;
-+
-+ zmemcpy(strm->next_out, strm->state->pending_out, len);
-+ strm->next_out += len;
-+ strm->state->pending_out += len;
-+ strm->total_out += len;
-+ strm->avail_out -= len;
-+ strm->state->pending -= len;
-+ if (strm->state->pending == 0) {
-+ strm->state->pending_out = strm->state->pending_buf;
-+ }
-+}
-+
-+/* ========================================================================= */
-+int ZEXPORT deflate (strm, flush)
-+ z_streamp strm;
-+ int flush;
-+{
-+ int old_flush; /* value of flush param for previous deflate call */
-+ deflate_state *s;
-+
-+ if (strm == Z_NULL || strm->state == Z_NULL ||
-+ flush > Z_FINISH || flush < 0) {
-+ return Z_STREAM_ERROR;
-+ }
-+ s = strm->state;
-+
-+ if (strm->next_out == Z_NULL ||
-+ (strm->next_in == Z_NULL && strm->avail_in != 0) ||
-+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
-+ ERR_RETURN(strm, Z_STREAM_ERROR);
-+ }
-+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
-+
-+ s->strm = strm; /* just in case */
-+ old_flush = s->last_flush;
-+ s->last_flush = flush;
-+
-+ /* Write the zlib header */
-+ if (s->status == INIT_STATE) {
-+
-+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
-+ uInt level_flags = (s->level-1) >> 1;
-+
-+ if (level_flags > 3) level_flags = 3;
-+ header |= (level_flags << 6);
-+ if (s->strstart != 0) header |= PRESET_DICT;
-+ header += 31 - (header % 31);
-+
-+ s->status = BUSY_STATE;
-+ putShortMSB(s, header);
-+
-+ /* Save the adler32 of the preset dictionary: */
-+ if (s->strstart != 0) {
-+ putShortMSB(s, (uInt)(strm->adler >> 16));
-+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
-+ }
-+ strm->adler = 1L;
-+ }
-+
-+ /* Flush as much pending output as possible */
-+ if (s->pending != 0) {
-+ flush_pending(strm);
-+ if (strm->avail_out == 0) {
-+ /* Since avail_out is 0, deflate will be called again with
-+ * more output space, but possibly with both pending and
-+ * avail_in equal to zero. There won't be anything to do,
-+ * but this is not an error situation so make sure we
-+ * return OK instead of BUF_ERROR at next call of deflate:
-+ */
-+ s->last_flush = -1;
-+ return Z_OK;
-+ }
-+
-+ /* Make sure there is something to do and avoid duplicate consecutive
-+ * flushes. For repeated and useless calls with Z_FINISH, we keep
-+ * returning Z_STREAM_END instead of Z_BUFF_ERROR.
-+ */
-+ } else if (strm->avail_in == 0 && flush <= old_flush &&
-+ flush != Z_FINISH) {
-+ ERR_RETURN(strm, Z_BUF_ERROR);
-+ }
-+
-+ /* User must not provide more input after the first FINISH: */
-+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
-+ ERR_RETURN(strm, Z_BUF_ERROR);
-+ }
-+
-+ /* Start a new block or continue the current one.
-+ */
-+ if (strm->avail_in != 0 || s->lookahead != 0 ||
-+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
-+ block_state bstate;
-+
-+ bstate = (*(configuration_table[s->level].func))(s, flush);
-+
-+ if (bstate == finish_started || bstate == finish_done) {
-+ s->status = FINISH_STATE;
-+ }
-+ if (bstate == need_more || bstate == finish_started) {
-+ if (strm->avail_out == 0) {
-+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
-+ }
-+ return Z_OK;
-+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
-+ * of deflate should use the same flush parameter to make sure
-+ * that the flush is complete. So we don't have to output an
-+ * empty block here, this will be done at next call. This also
-+ * ensures that for a very small output buffer, we emit at most
-+ * one empty block.
-+ */
-+ }
-+ if (bstate == block_done) {
-+ if (flush == Z_PARTIAL_FLUSH) {
-+ _tr_align(s);
-+ } else { /* FULL_FLUSH or SYNC_FLUSH */
-+ _tr_stored_block(s, (char*)0, 0L, 0);
-+ /* For a full flush, this empty block will be recognized
-+ * as a special marker by inflate_sync().
-+ */
-+ if (flush == Z_FULL_FLUSH) {
-+ CLEAR_HASH(s); /* forget history */
-+ }
-+ }
-+ flush_pending(strm);
-+ if (strm->avail_out == 0) {
-+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
-+ return Z_OK;
-+ }
-+ }
-+ }
-+ Assert(strm->avail_out > 0, "bug2");
-+
-+ if (flush != Z_FINISH) return Z_OK;
-+ if (s->noheader) return Z_STREAM_END;
-+
-+ /* Write the zlib trailer (adler32) */
-+ putShortMSB(s, (uInt)(strm->adler >> 16));
-+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
-+ flush_pending(strm);
-+ /* If avail_out is zero, the application will call deflate again
-+ * to flush the rest.
-+ */
-+ s->noheader = -1; /* write the trailer only once! */
-+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
-+}
-+
-+/* ========================================================================= */
-+int ZEXPORT deflateEnd (strm)
-+ z_streamp strm;
-+{
-+ int status;
-+
-+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
-+
-+ status = strm->state->status;
-+ if (status != INIT_STATE && status != BUSY_STATE &&
-+ status != FINISH_STATE) {
-+ return Z_STREAM_ERROR;
-+ }
-+
-+ /* Deallocate in reverse order of allocations: */
-+ TRY_FREE(strm, strm->state->pending_buf);
-+ TRY_FREE(strm, strm->state->head);
-+ TRY_FREE(strm, strm->state->prev);
-+ TRY_FREE(strm, strm->state->window);
-+
-+ ZFREE(strm, strm->state);
-+ strm->state = Z_NULL;
-+
-+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
-+}
-+
-+/* =========================================================================
-+ * Copy the source state to the destination state.
-+ * To simplify the source, this is not supported for 16-bit MSDOS (which
-+ * doesn't have enough memory anyway to duplicate compression states).
-+ */
-+int ZEXPORT deflateCopy (dest, source)
-+ z_streamp dest;
-+ z_streamp source;
-+{
-+#ifdef MAXSEG_64K
-+ return Z_STREAM_ERROR;
-+#else
-+ deflate_state *ds;
-+ deflate_state *ss;
-+ ushf *overlay;
-+
-+
-+ if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
-+ return Z_STREAM_ERROR;
-+ }
-+
-+ ss = source->state;
-+
-+ *dest = *source;
-+
-+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
-+ if (ds == Z_NULL) return Z_MEM_ERROR;
-+ dest->state = (struct internal_state FAR *) ds;
-+ *ds = *ss;
-+ ds->strm = dest;
-+
-+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
-+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
-+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
-+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
-+ ds->pending_buf = (uchf *) overlay;
-+
-+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
-+ ds->pending_buf == Z_NULL) {
-+ deflateEnd (dest);
-+ return Z_MEM_ERROR;
-+ }
-+ /* following zmemcpy do not work for 16-bit MSDOS */
-+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
-+ zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
-+ zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
-+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
-+
-+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
-+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
-+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
-+
-+ ds->l_desc.dyn_tree = ds->dyn_ltree;
-+ ds->d_desc.dyn_tree = ds->dyn_dtree;
-+ ds->bl_desc.dyn_tree = ds->bl_tree;
-+
-+ return Z_OK;
-+#endif
-+}
-+
-+/* ===========================================================================
-+ * Read a new buffer from the current input stream, update the adler32
-+ * and total number of bytes read. All deflate() input goes through
-+ * this function so some applications may wish to modify it to avoid
-+ * allocating a large strm->next_in buffer and copying from it.
-+ * (See also flush_pending()).
-+ */
-+local int read_buf(strm, buf, size)
-+ z_streamp strm;
-+ Bytef *buf;
-+ unsigned size;
-+{
-+ unsigned len = strm->avail_in;
-+
-+ if (len > size) len = size;
-+ if (len == 0) return 0;
-+
-+ strm->avail_in -= len;
-+
-+ if (!strm->state->noheader) {
-+ strm->adler = adler32(strm->adler, strm->next_in, len);
-+ }
-+ zmemcpy(buf, strm->next_in, len);
-+ strm->next_in += len;
-+ strm->total_in += len;
-+
-+ return (int)len;
-+}
-+
-+/* ===========================================================================
-+ * Initialize the "longest match" routines for a new zlib stream
-+ */
-+local void lm_init (s)
-+ deflate_state *s;
-+{
-+ s->window_size = (ulg)2L*s->w_size;
-+
-+ CLEAR_HASH(s);
-+
-+ /* Set the default configuration parameters:
-+ */
-+ s->max_lazy_match = configuration_table[s->level].max_lazy;
-+ s->good_match = configuration_table[s->level].good_length;
-+ s->nice_match = configuration_table[s->level].nice_length;
-+ s->max_chain_length = configuration_table[s->level].max_chain;
-+
-+ s->strstart = 0;
-+ s->block_start = 0L;
-+ s->lookahead = 0;
-+ s->match_length = s->prev_length = MIN_MATCH-1;
-+ s->match_available = 0;
-+ s->ins_h = 0;
-+#ifdef ASMV
-+ match_init(); /* initialize the asm code */
-+#endif
-+}
-+
-+/* ===========================================================================
-+ * Set match_start to the longest match starting at the given string and
-+ * return its length. Matches shorter or equal to prev_length are discarded,
-+ * in which case the result is equal to prev_length and match_start is
-+ * garbage.
-+ * IN assertions: cur_match is the head of the hash chain for the current
-+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
-+ * OUT assertion: the match length is not greater than s->lookahead.
-+ */
-+#ifndef ASMV
-+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
-+ * match.S. The code will be functionally equivalent.
-+ */
-+#ifndef FASTEST
-+local uInt longest_match(s, cur_match)
-+ deflate_state *s;
-+ IPos cur_match; /* current match */
-+{
-+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
-+ register Bytef *scan = s->window + s->strstart; /* current string */
-+ register Bytef *match; /* matched string */
-+ register int len; /* length of current match */
-+ int best_len = s->prev_length; /* best match length so far */
-+ int nice_match = s->nice_match; /* stop if match long enough */
-+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
-+ s->strstart - (IPos)MAX_DIST(s) : NIL;
-+ /* Stop when cur_match becomes <= limit. To simplify the code,
-+ * we prevent matches with the string of window index 0.
-+ */
-+ Posf *prev = s->prev;
-+ uInt wmask = s->w_mask;
-+
-+#ifdef UNALIGNED_OK
-+ /* Compare two bytes at a time. Note: this is not always beneficial.
-+ * Try with and without -DUNALIGNED_OK to check.
-+ */
-+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
-+ register ush scan_start = *(ushf*)scan;
-+ register ush scan_end = *(ushf*)(scan+best_len-1);
-+#else
-+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-+ register Byte scan_end1 = scan[best_len-1];
-+ register Byte scan_end = scan[best_len];
-+#endif
-+
-+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
-+ * It is easy to get rid of this optimization if necessary.
-+ */
-+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-+
-+ /* Do not waste too much time if we already have a good match: */
-+ if (s->prev_length >= s->good_match) {
-+ chain_length >>= 2;
-+ }
-+ /* Do not look for matches beyond the end of the input. This is necessary
-+ * to make deflate deterministic.
-+ */
-+ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
-+
-+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-+
-+ do {
-+ Assert(cur_match < s->strstart, "no future");
-+ match = s->window + cur_match;
-+
-+ /* Skip to next match if the match length cannot increase
-+ * or if the match length is less than 2:
-+ */
-+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
-+ /* This code assumes sizeof(unsigned short) == 2. Do not use
-+ * UNALIGNED_OK if your compiler uses a different size.
-+ */
-+ if (*(ushf*)(match+best_len-1) != scan_end ||
-+ *(ushf*)match != scan_start) continue;
-+
-+ /* It is not necessary to compare scan[2] and match[2] since they are
-+ * always equal when the other bytes match, given that the hash keys
-+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
-+ * strstart+3, +5, ... up to strstart+257. We check for insufficient
-+ * lookahead only every 4th comparison; the 128th check will be made
-+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
-+ * necessary to put more guard bytes at the end of the window, or
-+ * to check more often for insufficient lookahead.
-+ */
-+ Assert(scan[2] == match[2], "scan[2]?");
-+ scan++, match++;
-+ do {
-+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
-+ scan < strend);
-+ /* The funny "do {}" generates better code on most compilers */
-+
-+ /* Here, scan <= window+strstart+257 */
-+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-+ if (*scan == *match) scan++;
-+
-+ len = (MAX_MATCH - 1) - (int)(strend-scan);
-+ scan = strend - (MAX_MATCH-1);
-+
-+#else /* UNALIGNED_OK */
-+
-+ if (match[best_len] != scan_end ||
-+ match[best_len-1] != scan_end1 ||
-+ *match != *scan ||
-+ *++match != scan[1]) continue;
-+
-+ /* The check at best_len-1 can be removed because it will be made
-+ * again later. (This heuristic is not always a win.)
-+ * It is not necessary to compare scan[2] and match[2] since they
-+ * are always equal when the other bytes match, given that
-+ * the hash keys are equal and that HASH_BITS >= 8.
-+ */
-+ scan += 2, match++;
-+ Assert(*scan == *match, "match[2]?");
-+
-+ /* We check for insufficient lookahead only every 8th comparison;
-+ * the 256th check will be made at strstart+258.
-+ */
-+ do {
-+ } while (*++scan == *++match && *++scan == *++match &&
-+ *++scan == *++match && *++scan == *++match &&
-+ *++scan == *++match && *++scan == *++match &&
-+ *++scan == *++match && *++scan == *++match &&
-+ scan < strend);
-+
-+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-+
-+ len = MAX_MATCH - (int)(strend - scan);
-+ scan = strend - MAX_MATCH;
-+
-+#endif /* UNALIGNED_OK */
-+
-+ if (len > best_len) {
-+ s->match_start = cur_match;
-+ best_len = len;
-+ if (len >= nice_match) break;
-+#ifdef UNALIGNED_OK
-+ scan_end = *(ushf*)(scan+best_len-1);
-+#else
-+ scan_end1 = scan[best_len-1];
-+ scan_end = scan[best_len];
-+#endif
-+ }
-+ } while ((cur_match = prev[cur_match & wmask]) > limit
-+ && --chain_length != 0);
-+
-+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
-+ return s->lookahead;
-+}
-+
-+#else /* FASTEST */
-+/* ---------------------------------------------------------------------------
-+ * Optimized version for level == 1 only
-+ */
-+local uInt longest_match(s, cur_match)
-+ deflate_state *s;
-+ IPos cur_match; /* current match */
-+{
-+ register Bytef *scan = s->window + s->strstart; /* current string */
-+ register Bytef *match; /* matched string */
-+ register int len; /* length of current match */
-+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
-+
-+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
-+ * It is easy to get rid of this optimization if necessary.
-+ */
-+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
-+
-+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
-+
-+ Assert(cur_match < s->strstart, "no future");
-+
-+ match = s->window + cur_match;
-+
-+ /* Return failure if the match length is less than 2:
-+ */
-+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
-+
-+ /* The check at best_len-1 can be removed because it will be made
-+ * again later. (This heuristic is not always a win.)
-+ * It is not necessary to compare scan[2] and match[2] since they
-+ * are always equal when the other bytes match, given that
-+ * the hash keys are equal and that HASH_BITS >= 8.
-+ */
-+ scan += 2, match += 2;
-+ Assert(*scan == *match, "match[2]?");
-+
-+ /* We check for insufficient lookahead only every 8th comparison;
-+ * the 256th check will be made at strstart+258.
-+ */
-+ do {
-+ } while (*++scan == *++match && *++scan == *++match &&
-+ *++scan == *++match && *++scan == *++match &&
-+ *++scan == *++match && *++scan == *++match &&
-+ *++scan == *++match && *++scan == *++match &&
-+ scan < strend);
-+
-+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
-+
-+ len = MAX_MATCH - (int)(strend - scan);
-+
-+ if (len < MIN_MATCH) return MIN_MATCH - 1;
-+
-+ s->match_start = cur_match;
-+ return len <= s->lookahead ? len : s->lookahead;
-+}
-+#endif /* FASTEST */
-+#endif /* ASMV */
-+
-+#ifdef DEBUG
-+/* ===========================================================================
-+ * Check that the match at match_start is indeed a match.
-+ */
-+local void check_match(s, start, match, length)
-+ deflate_state *s;
-+ IPos start, match;
-+ int length;
-+{
-+ /* check that the match is indeed a match */
-+ if (zmemcmp(s->window + match,
-+ s->window + start, length) != EQUAL) {
-+ fprintf(stderr, " start %u, match %u, length %d\n",
-+ start, match, length);
-+ do {
-+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
-+ } while (--length != 0);
-+ z_error("invalid match");
-+ }
-+ if (z_verbose > 1) {
-+ fprintf(stderr,"\\[%d,%d]", start-match, length);
-+ do { putc(s->window[start++], stderr); } while (--length != 0);
-+ }
-+}
-+#else
-+# define check_match(s, start, match, length)
-+#endif
-+
-+/* ===========================================================================
-+ * Fill the window when the lookahead becomes insufficient.
-+ * Updates strstart and lookahead.
-+ *
-+ * IN assertion: lookahead < MIN_LOOKAHEAD
-+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
-+ * At least one byte has been read, or avail_in == 0; reads are
-+ * performed for at least two bytes (required for the zip translate_eol
-+ * option -- not supported here).
-+ */
-+local void fill_window(s)
-+ deflate_state *s;
-+{
-+ register unsigned n, m;
-+ register Posf *p;
-+ unsigned more; /* Amount of free space at the end of the window. */
-+ uInt wsize = s->w_size;
-+
-+ do {
-+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
-+
-+ /* Deal with !@#$% 64K limit: */
-+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
-+ more = wsize;
-+
-+ } else if (more == (unsigned)(-1)) {
-+ /* Very unlikely, but possible on 16 bit machine if strstart == 0
-+ * and lookahead == 1 (input done one byte at time)
-+ */
-+ more--;
-+
-+ /* If the window is almost full and there is insufficient lookahead,
-+ * move the upper half to the lower one to make room in the upper half.
-+ */
-+ } else if (s->strstart >= wsize+MAX_DIST(s)) {
-+
-+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
-+ s->match_start -= wsize;
-+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
-+ s->block_start -= (long) wsize;
-+
-+ /* Slide the hash table (could be avoided with 32 bit values
-+ at the expense of memory usage). We slide even when level == 0
-+ to keep the hash table consistent if we switch back to level > 0
-+ later. (Using level 0 permanently is not an optimal usage of
-+ zlib, so we don't care about this pathological case.)
-+ */
-+ n = s->hash_size;
-+ p = &s->head[n];
-+ do {
-+ m = *--p;
-+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
-+ } while (--n);
-+
-+ n = wsize;
-+#ifndef FASTEST
-+ p = &s->prev[n];
-+ do {
-+ m = *--p;
-+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
-+ /* If n is not on any hash chain, prev[n] is garbage but
-+ * its value will never be used.
-+ */
-+ } while (--n);
-+#endif
-+ more += wsize;
-+ }
-+ if (s->strm->avail_in == 0) return;
-+
-+ /* If there was no sliding:
-+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
-+ * more == window_size - lookahead - strstart
-+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
-+ * => more >= window_size - 2*WSIZE + 2
-+ * In the BIG_MEM or MMAP case (not yet supported),
-+ * window_size == input_size + MIN_LOOKAHEAD &&
-+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
-+ * Otherwise, window_size == 2*WSIZE so more >= 2.
-+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
-+ */
-+ Assert(more >= 2, "more < 2");
-+
-+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
-+ s->lookahead += n;
-+
-+ /* Initialize the hash value now that we have some input: */
-+ if (s->lookahead >= MIN_MATCH) {
-+ s->ins_h = s->window[s->strstart];
-+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-+#if MIN_MATCH != 3
-+ Call UPDATE_HASH() MIN_MATCH-3 more times
-+#endif
-+ }
-+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
-+ * but this is not important since only literal bytes will be emitted.
-+ */
-+
-+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
-+}
-+
-+/* ===========================================================================
-+ * Flush the current block, with given end-of-file flag.
-+ * IN assertion: strstart is set to the end of the current match.
-+ */
-+#define FLUSH_BLOCK_ONLY(s, eof) { \
-+ _tr_flush_block(s, (s->block_start >= 0L ? \
-+ (charf *)&s->window[(unsigned)s->block_start] : \
-+ (charf *)Z_NULL), \
-+ (ulg)((long)s->strstart - s->block_start), \
-+ (eof)); \
-+ s->block_start = s->strstart; \
-+ flush_pending(s->strm); \
-+ Tracev((stderr,"[FLUSH]")); \
-+}
-+
-+/* Same but force premature exit if necessary. */
-+#define FLUSH_BLOCK(s, eof) { \
-+ FLUSH_BLOCK_ONLY(s, eof); \
-+ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
-+}
-+
-+/* ===========================================================================
-+ * Copy without compression as much as possible from the input stream, return
-+ * the current block state.
-+ * This function does not insert new strings in the dictionary since
-+ * uncompressible data is probably not useful. This function is used
-+ * only for the level=0 compression option.
-+ * NOTE: this function should be optimized to avoid extra copying from
-+ * window to pending_buf.
-+ */
-+local block_state deflate_stored(s, flush)
-+ deflate_state *s;
-+ int flush;
-+{
-+ /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
-+ * to pending_buf_size, and each stored block has a 5 byte header:
-+ */
-+ ulg max_block_size = 0xffff;
-+ ulg max_start;
-+
-+ if (max_block_size > s->pending_buf_size - 5) {
-+ max_block_size = s->pending_buf_size - 5;
-+ }
-+
-+ /* Copy as much as possible from input to output: */
-+ for (;;) {
-+ /* Fill the window as much as possible: */
-+ if (s->lookahead <= 1) {
-+
-+ Assert(s->strstart < s->w_size+MAX_DIST(s) ||
-+ s->block_start >= (long)s->w_size, "slide too late");
-+
-+ fill_window(s);
-+ if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
-+
-+ if (s->lookahead == 0) break; /* flush the current block */
-+ }
-+ Assert(s->block_start >= 0L, "block gone");
-+
-+ s->strstart += s->lookahead;
-+ s->lookahead = 0;
-+
-+ /* Emit a stored block if pending_buf will be full: */
-+ max_start = s->block_start + max_block_size;
-+ if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
-+ /* strstart == 0 is possible when wraparound on 16-bit machine */
-+ s->lookahead = (uInt)(s->strstart - max_start);
-+ s->strstart = (uInt)max_start;
-+ FLUSH_BLOCK(s, 0);
-+ }
-+ /* Flush if we may have to slide, otherwise block_start may become
-+ * negative and the data will be gone:
-+ */
-+ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
-+ FLUSH_BLOCK(s, 0);
-+ }
-+ }
-+ FLUSH_BLOCK(s, flush == Z_FINISH);
-+ return flush == Z_FINISH ? finish_done : block_done;
-+}
-+
-+/* ===========================================================================
-+ * Compress as much as possible from the input stream, return the current
-+ * block state.
-+ * This function does not perform lazy evaluation of matches and inserts
-+ * new strings in the dictionary only for unmatched strings or for short
-+ * matches. It is used only for the fast compression options.
-+ */
-+local block_state deflate_fast(s, flush)
-+ deflate_state *s;
-+ int flush;
-+{
-+ IPos hash_head = NIL; /* head of the hash chain */
-+ int bflush; /* set if current block must be flushed */
-+
-+ for (;;) {
-+ /* Make sure that we always have enough lookahead, except
-+ * at the end of the input file. We need MAX_MATCH bytes
-+ * for the next match, plus MIN_MATCH bytes to insert the
-+ * string following the next match.
-+ */
-+ if (s->lookahead < MIN_LOOKAHEAD) {
-+ fill_window(s);
-+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
-+ return need_more;
-+ }
-+ if (s->lookahead == 0) break; /* flush the current block */
-+ }
-+
-+ /* Insert the string window[strstart .. strstart+2] in the
-+ * dictionary, and set hash_head to the head of the hash chain:
-+ */
-+ if (s->lookahead >= MIN_MATCH) {
-+ INSERT_STRING(s, s->strstart, hash_head);
-+ }
-+
-+ /* Find the longest match, discarding those <= prev_length.
-+ * At this point we have always match_length < MIN_MATCH
-+ */
-+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
-+ /* To simplify the code, we prevent matches with the string
-+ * of window index 0 (in particular we have to avoid a match
-+ * of the string with itself at the start of the input file).
-+ */
-+ if (s->strategy != Z_HUFFMAN_ONLY) {
-+ s->match_length = longest_match (s, hash_head);
-+ }
-+ /* longest_match() sets match_start */
-+ }
-+ if (s->match_length >= MIN_MATCH) {
-+ check_match(s, s->strstart, s->match_start, s->match_length);
-+
-+ _tr_tally_dist(s, s->strstart - s->match_start,
-+ s->match_length - MIN_MATCH, bflush);
-+
-+ s->lookahead -= s->match_length;
-+
-+ /* Insert new strings in the hash table only if the match length
-+ * is not too large. This saves time but degrades compression.
-+ */
-+#ifndef FASTEST
-+ if (s->match_length <= s->max_insert_length &&
-+ s->lookahead >= MIN_MATCH) {
-+ s->match_length--; /* string at strstart already in hash table */
-+ do {
-+ s->strstart++;
-+ INSERT_STRING(s, s->strstart, hash_head);
-+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
-+ * always MIN_MATCH bytes ahead.
-+ */
-+ } while (--s->match_length != 0);
-+ s->strstart++;
-+ } else
-+#endif
-+ {
-+ s->strstart += s->match_length;
-+ s->match_length = 0;
-+ s->ins_h = s->window[s->strstart];
-+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
-+#if MIN_MATCH != 3
-+ Call UPDATE_HASH() MIN_MATCH-3 more times
-+#endif
-+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
-+ * matter since it will be recomputed at next deflate call.
-+ */
-+ }
-+ } else {
-+ /* No match, output a literal byte */
-+ Tracevv((stderr,"%c", s->window[s->strstart]));
-+ _tr_tally_lit (s, s->window[s->strstart], bflush);
-+ s->lookahead--;
-+ s->strstart++;
-+ }
-+ if (bflush) FLUSH_BLOCK(s, 0);
-+ }
-+ FLUSH_BLOCK(s, flush == Z_FINISH);
-+ return flush == Z_FINISH ? finish_done : block_done;
-+}
-+
-+/* ===========================================================================
-+ * Same as above, but achieves better compression. We use a lazy
-+ * evaluation for matches: a match is finally adopted only if there is
-+ * no better match at the next window position.
-+ */
-+local block_state deflate_slow(s, flush)
-+ deflate_state *s;
-+ int flush;
-+{
-+ IPos hash_head = NIL; /* head of hash chain */
-+ int bflush; /* set if current block must be flushed */
-+
-+ /* Process the input block. */
-+ for (;;) {
-+ /* Make sure that we always have enough lookahead, except
-+ * at the end of the input file. We need MAX_MATCH bytes
-+ * for the next match, plus MIN_MATCH bytes to insert the
-+ * string following the next match.
-+ */
-+ if (s->lookahead < MIN_LOOKAHEAD) {
-+ fill_window(s);
-+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
-+ return need_more;
-+ }
-+ if (s->lookahead == 0) break; /* flush the current block */
-+ }
-+
-+ /* Insert the string window[strstart .. strstart+2] in the
-+ * dictionary, and set hash_head to the head of the hash chain:
-+ */
-+ if (s->lookahead >= MIN_MATCH) {
-+ INSERT_STRING(s, s->strstart, hash_head);
-+ }
-+
-+ /* Find the longest match, discarding those <= prev_length.
-+ */
-+ s->prev_length = s->match_length, s->prev_match = s->match_start;
-+ s->match_length = MIN_MATCH-1;
-+
-+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
-+ s->strstart - hash_head <= MAX_DIST(s)) {
-+ /* To simplify the code, we prevent matches with the string
-+ * of window index 0 (in particular we have to avoid a match
-+ * of the string with itself at the start of the input file).
-+ */
-+ if (s->strategy != Z_HUFFMAN_ONLY) {
-+ s->match_length = longest_match (s, hash_head);
-+ }
-+ /* longest_match() sets match_start */
-+
-+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
-+ (s->match_length == MIN_MATCH &&
-+ s->strstart - s->match_start > TOO_FAR))) {
-+
-+ /* If prev_match is also MIN_MATCH, match_start is garbage
-+ * but we will ignore the current match anyway.
-+ */
-+ s->match_length = MIN_MATCH-1;
-+ }
-+ }
-+ /* If there was a match at the previous step and the current
-+ * match is not better, output the previous match:
-+ */
-+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
-+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
-+ /* Do not insert strings in hash table beyond this. */
-+
-+ check_match(s, s->strstart-1, s->prev_match, s->prev_length);
-+
-+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
-+ s->prev_length - MIN_MATCH, bflush);
-+
-+ /* Insert in hash table all strings up to the end of the match.
-+ * strstart-1 and strstart are already inserted. If there is not
-+ * enough lookahead, the last two strings are not inserted in
-+ * the hash table.
-+ */
-+ s->lookahead -= s->prev_length-1;
-+ s->prev_length -= 2;
-+ do {
-+ if (++s->strstart <= max_insert) {
-+ INSERT_STRING(s, s->strstart, hash_head);
-+ }
-+ } while (--s->prev_length != 0);
-+ s->match_available = 0;
-+ s->match_length = MIN_MATCH-1;
-+ s->strstart++;
-+
-+ if (bflush) FLUSH_BLOCK(s, 0);
-+
-+ } else if (s->match_available) {
-+ /* If there was no match at the previous position, output a
-+ * single literal. If there was a match but the current match
-+ * is longer, truncate the previous match to a single literal.
-+ */
-+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
-+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
-+ if (bflush) {
-+ FLUSH_BLOCK_ONLY(s, 0);
-+ }
-+ s->strstart++;
-+ s->lookahead--;
-+ if (s->strm->avail_out == 0) return need_more;
-+ } else {
-+ /* There is no previous match to compare with, wait for
-+ * the next step to decide.
-+ */
-+ s->match_available = 1;
-+ s->strstart++;
-+ s->lookahead--;
-+ }
-+ }
-+ Assert (flush != Z_NO_FLUSH, "no flush?");
-+ if (s->match_available) {
-+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
-+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
-+ s->match_available = 0;
-+ }
-+ FLUSH_BLOCK(s, flush == Z_FINISH);
-+ return flush == Z_FINISH ? finish_done : block_done;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/deflate.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,318 @@
-+/* deflate.h -- internal compression state
-+ * Copyright (C) 1995-2002 Jean-loup Gailly
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+/* @(#) $Id$ */
-+
-+#ifndef _DEFLATE_H
-+#define _DEFLATE_H
-+
-+#include "zlib/zutil.h"
-+
-+/* ===========================================================================
-+ * Internal compression state.
-+ */
-+
-+#define LENGTH_CODES 29
-+/* number of length codes, not counting the special END_BLOCK code */
-+
-+#define LITERALS 256
-+/* number of literal bytes 0..255 */
-+
-+#define L_CODES (LITERALS+1+LENGTH_CODES)
-+/* number of Literal or Length codes, including the END_BLOCK code */
-+
-+#define D_CODES 30
-+/* number of distance codes */
-+
-+#define BL_CODES 19
-+/* number of codes used to transfer the bit lengths */
-+
-+#define HEAP_SIZE (2*L_CODES+1)
-+/* maximum heap size */
-+
-+#define MAX_BITS 15
-+/* All codes must not exceed MAX_BITS bits */
-+
-+#define INIT_STATE 42
-+#define BUSY_STATE 113
-+#define FINISH_STATE 666
-+/* Stream status */
-+
-+
-+/* Data structure describing a single value and its code string. */
-+typedef struct ct_data_s {
-+ union {
-+ ush freq; /* frequency count */
-+ ush code; /* bit string */
-+ } fc;
-+ union {
-+ ush dad; /* father node in Huffman tree */
-+ ush len; /* length of bit string */
-+ } dl;
-+} FAR ct_data;
-+
-+#define Freq fc.freq
-+#define Code fc.code
-+#define Dad dl.dad
-+#define Len dl.len
-+
-+typedef struct static_tree_desc_s static_tree_desc;
-+
-+typedef struct tree_desc_s {
-+ ct_data *dyn_tree; /* the dynamic tree */
-+ int max_code; /* largest code with non zero frequency */
-+ static_tree_desc *stat_desc; /* the corresponding static tree */
-+} FAR tree_desc;
-+
-+typedef ush Pos;
-+typedef Pos FAR Posf;
-+typedef unsigned IPos;
-+
-+/* A Pos is an index in the character window. We use short instead of int to
-+ * save space in the various tables. IPos is used only for parameter passing.
-+ */
-+
-+typedef struct internal_state {
-+ z_streamp strm; /* pointer back to this zlib stream */
-+ int status; /* as the name implies */
-+ Bytef *pending_buf; /* output still pending */
-+ ulg pending_buf_size; /* size of pending_buf */
-+ Bytef *pending_out; /* next pending byte to output to the stream */
-+ int pending; /* nb of bytes in the pending buffer */
-+ int noheader; /* suppress zlib header and adler32 */
-+ Byte data_type; /* UNKNOWN, BINARY or ASCII */
-+ Byte method; /* STORED (for zip only) or DEFLATED */
-+ int last_flush; /* value of flush param for previous deflate call */
-+
-+ /* used by deflate.c: */
-+
-+ uInt w_size; /* LZ77 window size (32K by default) */
-+ uInt w_bits; /* log2(w_size) (8..16) */
-+ uInt w_mask; /* w_size - 1 */
-+
-+ Bytef *window;
-+ /* Sliding window. Input bytes are read into the second half of the window,
-+ * and move to the first half later to keep a dictionary of at least wSize
-+ * bytes. With this organization, matches are limited to a distance of
-+ * wSize-MAX_MATCH bytes, but this ensures that IO is always
-+ * performed with a length multiple of the block size. Also, it limits
-+ * the window size to 64K, which is quite useful on MSDOS.
-+ * To do: use the user input buffer as sliding window.
-+ */
-+
-+ ulg window_size;
-+ /* Actual size of window: 2*wSize, except when the user input buffer
-+ * is directly used as sliding window.
-+ */
-+
-+ Posf *prev;
-+ /* Link to older string with same hash index. To limit the size of this
-+ * array to 64K, this link is maintained only for the last 32K strings.
-+ * An index in this array is thus a window index modulo 32K.
-+ */
-+
-+ Posf *head; /* Heads of the hash chains or NIL. */
-+
-+ uInt ins_h; /* hash index of string to be inserted */
-+ uInt hash_size; /* number of elements in hash table */
-+ uInt hash_bits; /* log2(hash_size) */
-+ uInt hash_mask; /* hash_size-1 */
-+
-+ uInt hash_shift;
-+ /* Number of bits by which ins_h must be shifted at each input
-+ * step. It must be such that after MIN_MATCH steps, the oldest
-+ * byte no longer takes part in the hash key, that is:
-+ * hash_shift * MIN_MATCH >= hash_bits
-+ */
-+
-+ long block_start;
-+ /* Window position at the beginning of the current output block. Gets
-+ * negative when the window is moved backwards.
-+ */
-+
-+ uInt match_length; /* length of best match */
-+ IPos prev_match; /* previous match */
-+ int match_available; /* set if previous match exists */
-+ uInt strstart; /* start of string to insert */
-+ uInt match_start; /* start of matching string */
-+ uInt lookahead; /* number of valid bytes ahead in window */
-+
-+ uInt prev_length;
-+ /* Length of the best match at previous step. Matches not greater than this
-+ * are discarded. This is used in the lazy match evaluation.
-+ */
-+
-+ uInt max_chain_length;
-+ /* To speed up deflation, hash chains are never searched beyond this
-+ * length. A higher limit improves compression ratio but degrades the
-+ * speed.
-+ */
-+
-+ uInt max_lazy_match;
-+ /* Attempt to find a better match only when the current match is strictly
-+ * smaller than this value. This mechanism is used only for compression
-+ * levels >= 4.
-+ */
-+# define max_insert_length max_lazy_match
-+ /* Insert new strings in the hash table only if the match length is not
-+ * greater than this length. This saves time but degrades compression.
-+ * max_insert_length is used only for compression levels <= 3.
-+ */
-+
-+ int level; /* compression level (1..9) */
-+ int strategy; /* favor or force Huffman coding*/
-+
-+ uInt good_match;
-+ /* Use a faster search when the previous match is longer than this */
-+
-+ int nice_match; /* Stop searching when current match exceeds this */
-+
-+ /* used by trees.c: */
-+ /* Didn't use ct_data typedef below to supress compiler warning */
-+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
-+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
-+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
-+
-+ struct tree_desc_s l_desc; /* desc. for literal tree */
-+ struct tree_desc_s d_desc; /* desc. for distance tree */
-+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
-+
-+ ush bl_count[MAX_BITS+1];
-+ /* number of codes at each bit length for an optimal tree */
-+
-+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
-+ int heap_len; /* number of elements in the heap */
-+ int heap_max; /* element of largest frequency */
-+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
-+ * The same heap array is used to build all trees.
-+ */
-+
-+ uch depth[2*L_CODES+1];
-+ /* Depth of each subtree used as tie breaker for trees of equal frequency
-+ */
-+
-+ uchf *l_buf; /* buffer for literals or lengths */
-+
-+ uInt lit_bufsize;
-+ /* Size of match buffer for literals/lengths. There are 4 reasons for
-+ * limiting lit_bufsize to 64K:
-+ * - frequencies can be kept in 16 bit counters
-+ * - if compression is not successful for the first block, all input
-+ * data is still in the window so we can still emit a stored block even
-+ * when input comes from standard input. (This can also be done for
-+ * all blocks if lit_bufsize is not greater than 32K.)
-+ * - if compression is not successful for a file smaller than 64K, we can
-+ * even emit a stored file instead of a stored block (saving 5 bytes).
-+ * This is applicable only for zip (not gzip or zlib).
-+ * - creating new Huffman trees less frequently may not provide fast
-+ * adaptation to changes in the input data statistics. (Take for
-+ * example a binary file with poorly compressible code followed by
-+ * a highly compressible string table.) Smaller buffer sizes give
-+ * fast adaptation but have of course the overhead of transmitting
-+ * trees more frequently.
-+ * - I can't count above 4
-+ */
-+
-+ uInt last_lit; /* running index in l_buf */
-+
-+ ushf *d_buf;
-+ /* Buffer for distances. To simplify the code, d_buf and l_buf have
-+ * the same number of elements. To use different lengths, an extra flag
-+ * array would be necessary.
-+ */
-+
-+ ulg opt_len; /* bit length of current block with optimal trees */
-+ ulg static_len; /* bit length of current block with static trees */
-+ uInt matches; /* number of string matches in current block */
-+ int last_eob_len; /* bit length of EOB code for last block */
-+
-+#ifdef DEBUG
-+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
-+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
-+#endif
-+
-+ ush bi_buf;
-+ /* Output buffer. bits are inserted starting at the bottom (least
-+ * significant bits).
-+ */
-+ int bi_valid;
-+ /* Number of valid bits in bi_buf. All bits above the last valid bit
-+ * are always zero.
-+ */
-+
-+} FAR deflate_state;
-+
-+/* Output a byte on the stream.
-+ * IN assertion: there is enough room in pending_buf.
-+ */
-+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
-+
-+
-+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
-+/* Minimum amount of lookahead, except at the end of the input file.
-+ * See deflate.c for comments about the MIN_MATCH+1.
-+ */
-+
-+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
-+/* In order to simplify the code, particularly on 16 bit machines, match
-+ * distances are limited to MAX_DIST instead of WSIZE.
-+ */
-+
-+ /* in trees.c */
-+void _tr_init OF((deflate_state *s));
-+int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
-+void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
-+ int eof));
-+void _tr_align OF((deflate_state *s));
-+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
-+ int eof));
-+
-+#define d_code(dist) \
-+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
-+/* Mapping from a distance to a distance code. dist is the distance - 1 and
-+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
-+ * used.
-+ */
-+
-+#ifndef DEBUG
-+/* Inline versions of _tr_tally for speed: */
-+
-+#if defined(GEN_TREES_H) || !defined(STDC)
-+ extern uch _length_code[];
-+ extern uch _dist_code[];
-+#else
-+ extern const uch _length_code[];
-+ extern const uch _dist_code[];
-+#endif
-+
-+# define _tr_tally_lit(s, c, flush) \
-+ { uch cc = (c); \
-+ s->d_buf[s->last_lit] = 0; \
-+ s->l_buf[s->last_lit++] = cc; \
-+ s->dyn_ltree[cc].Freq++; \
-+ flush = (s->last_lit == s->lit_bufsize-1); \
-+ }
-+# define _tr_tally_dist(s, distance, length, flush) \
-+ { uch len = (length); \
-+ ush dist = (distance); \
-+ s->d_buf[s->last_lit] = dist; \
-+ s->l_buf[s->last_lit++] = len; \
-+ dist--; \
-+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
-+ s->dyn_dtree[d_code(dist)].Freq++; \
-+ flush = (s->last_lit == s->lit_bufsize-1); \
-+ }
-+#else
-+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
-+# define _tr_tally_dist(s, distance, length, flush) \
-+ flush = _tr_tally(s, distance, length)
-+#endif
-+
-+#endif /* _DEFLATE_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/infblock.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,403 @@
-+/* infblock.c -- interpret and process block types to last block
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+#include <zlib/zutil.h>
-+#include "infblock.h"
-+#include "inftrees.h"
-+#include "infcodes.h"
-+#include "infutil.h"
-+
-+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-+
-+/* simplify the use of the inflate_huft type with some defines */
-+#define exop word.what.Exop
-+#define bits word.what.Bits
-+
-+/* Table for deflate from PKZIP's appnote.txt. */
-+local const uInt border[] = { /* Order of the bit length code lengths */
-+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
-+
-+/*
-+ Notes beyond the 1.93a appnote.txt:
-+
-+ 1. Distance pointers never point before the beginning of the output
-+ stream.
-+ 2. Distance pointers can point back across blocks, up to 32k away.
-+ 3. There is an implied maximum of 7 bits for the bit length table and
-+ 15 bits for the actual data.
-+ 4. If only one code exists, then it is encoded using one bit. (Zero
-+ would be more efficient, but perhaps a little confusing.) If two
-+ codes exist, they are coded using one bit each (0 and 1).
-+ 5. There is no way of sending zero distance codes--a dummy must be
-+ sent if there are none. (History: a pre 2.0 version of PKZIP would
-+ store blocks with no distance codes, but this was discovered to be
-+ too harsh a criterion.) Valid only for 1.93a. 2.04c does allow
-+ zero distance codes, which is sent as one code of zero bits in
-+ length.
-+ 6. There are up to 286 literal/length codes. Code 256 represents the
-+ end-of-block. Note however that the static length tree defines
-+ 288 codes just to fill out the Huffman codes. Codes 286 and 287
-+ cannot be used though, since there is no length base or extra bits
-+ defined for them. Similarily, there are up to 30 distance codes.
-+ However, static trees define 32 codes (all 5 bits) to fill out the
-+ Huffman codes, but the last two had better not show up in the data.
-+ 7. Unzip can check dynamic Huffman blocks for complete code sets.
-+ The exception is that a single code would not be complete (see #4).
-+ 8. The five bits following the block type is really the number of
-+ literal codes sent minus 257.
-+ 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
-+ (1+6+6). Therefore, to output three times the length, you output
-+ three codes (1+1+1), whereas to output four times the same length,
-+ you only need two codes (1+3). Hmm.
-+ 10. In the tree reconstruction algorithm, Code = Code + Increment
-+ only if BitLength(i) is not zero. (Pretty obvious.)
-+ 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19)
-+ 12. Note: length code 284 can represent 227-258, but length code 285
-+ really is 258. The last length deserves its own, short code
-+ since it gets used a lot in very redundant files. The length
-+ 258 is special since 258 - 3 (the min match length) is 255.
-+ 13. The literal/length and distance code bit lengths are read as a
-+ single stream of lengths. It is possible (and advantageous) for
-+ a repeat code (16, 17, or 18) to go across the boundary between
-+ the two sets of lengths.
-+ */
-+
-+
-+void inflate_blocks_reset(s, z, c)
-+inflate_blocks_statef *s;
-+z_streamp z;
-+uLongf *c;
-+{
-+ if (c != Z_NULL)
-+ *c = s->check;
-+ if (s->mode == BTREE || s->mode == DTREE)
-+ ZFREE(z, s->sub.trees.blens);
-+ if (s->mode == CODES)
-+ inflate_codes_free(s->sub.decode.codes, z);
-+ s->mode = TYPE;
-+ s->bitk = 0;
-+ s->bitb = 0;
-+ s->read = s->write = s->window;
-+ if (s->checkfn != Z_NULL)
-+ z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
-+ Tracev((stderr, "inflate: blocks reset\n"));
-+}
-+
-+
-+inflate_blocks_statef *inflate_blocks_new(z, c, w)
-+z_streamp z;
-+check_func c;
-+uInt w;
-+{
-+ inflate_blocks_statef *s;
-+
-+ if ((s = (inflate_blocks_statef *)ZALLOC
-+ (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
-+ return s;
-+ if ((s->hufts =
-+ (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
-+ {
-+ ZFREE(z, s);
-+ return Z_NULL;
-+ }
-+ if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
-+ {
-+ ZFREE(z, s->hufts);
-+ ZFREE(z, s);
-+ return Z_NULL;
-+ }
-+ s->end = s->window + w;
-+ s->checkfn = c;
-+ s->mode = TYPE;
-+ Tracev((stderr, "inflate: blocks allocated\n"));
-+ inflate_blocks_reset(s, z, Z_NULL);
-+ return s;
-+}
-+
-+
-+int inflate_blocks(s, z, r)
-+inflate_blocks_statef *s;
-+z_streamp z;
-+int r;
-+{
-+ uInt t; /* temporary storage */
-+ uLong b; /* bit buffer */
-+ uInt k; /* bits in bit buffer */
-+ Bytef *p; /* input data pointer */
-+ uInt n; /* bytes available there */
-+ Bytef *q; /* output window write pointer */
-+ uInt m; /* bytes to end of window or read pointer */
-+
-+ /* copy input/output information to locals (UPDATE macro restores) */
-+ LOAD
-+
-+ /* process input based on current state */
-+ while (1) switch (s->mode)
-+ {
-+ case TYPE:
-+ NEEDBITS(3)
-+ t = (uInt)b & 7;
-+ s->last = t & 1;
-+ switch (t >> 1)
-+ {
-+ case 0: /* stored */
-+ Tracev((stderr, "inflate: stored block%s\n",
-+ s->last ? " (last)" : ""));
-+ DUMPBITS(3)
-+ t = k & 7; /* go to byte boundary */
-+ DUMPBITS(t)
-+ s->mode = LENS; /* get length of stored block */
-+ break;
-+ case 1: /* fixed */
-+ Tracev((stderr, "inflate: fixed codes block%s\n",
-+ s->last ? " (last)" : ""));
-+ {
-+ uInt bl, bd;
-+ inflate_huft *tl, *td;
-+
-+ inflate_trees_fixed(&bl, &bd, &tl, &td, z);
-+ s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
-+ if (s->sub.decode.codes == Z_NULL)
-+ {
-+ r = Z_MEM_ERROR;
-+ LEAVE
-+ }
-+ }
-+ DUMPBITS(3)
-+ s->mode = CODES;
-+ break;
-+ case 2: /* dynamic */
-+ Tracev((stderr, "inflate: dynamic codes block%s\n",
-+ s->last ? " (last)" : ""));
-+ DUMPBITS(3)
-+ s->mode = TABLE;
-+ break;
-+ case 3: /* illegal */
-+ DUMPBITS(3)
-+ s->mode = BAD;
-+ z->msg = (char*)"invalid block type";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ }
-+ break;
-+ case LENS:
-+ NEEDBITS(32)
-+ if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
-+ {
-+ s->mode = BAD;
-+ z->msg = (char*)"invalid stored block lengths";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ }
-+ s->sub.left = (uInt)b & 0xffff;
-+ b = k = 0; /* dump bits */
-+ Tracev((stderr, "inflate: stored length %u\n", s->sub.left));
-+ s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
-+ break;
-+ case STORED:
-+ if (n == 0)
-+ LEAVE
-+ NEEDOUT
-+ t = s->sub.left;
-+ if (t > n) t = n;
-+ if (t > m) t = m;
-+ zmemcpy(q, p, t);
-+ p += t; n -= t;
-+ q += t; m -= t;
-+ if ((s->sub.left -= t) != 0)
-+ break;
-+ Tracev((stderr, "inflate: stored end, %lu total out\n",
-+ z->total_out + (q >= s->read ? q - s->read :
-+ (s->end - s->read) + (q - s->window))));
-+ s->mode = s->last ? DRY : TYPE;
-+ break;
-+ case TABLE:
-+ NEEDBITS(14)
-+ s->sub.trees.table = t = (uInt)b & 0x3fff;
-+#ifndef PKZIP_BUG_WORKAROUND
-+ if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
-+ {
-+ s->mode = BAD;
-+ z->msg = (char*)"too many length or distance symbols";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ }
-+#endif
-+ t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
-+ if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
-+ {
-+ r = Z_MEM_ERROR;
-+ LEAVE
-+ }
-+ DUMPBITS(14)
-+ s->sub.trees.index = 0;
-+ Tracev((stderr, "inflate: table sizes ok\n"));
-+ s->mode = BTREE;
-+ case BTREE:
-+ while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
-+ {
-+ NEEDBITS(3)
-+ s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
-+ DUMPBITS(3)
-+ }
-+ while (s->sub.trees.index < 19)
-+ s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
-+ s->sub.trees.bb = 7;
-+ t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
-+ &s->sub.trees.tb, s->hufts, z);
-+ if (t != Z_OK)
-+ {
-+ r = t;
-+ if (r == Z_DATA_ERROR)
-+ {
-+ ZFREE(z, s->sub.trees.blens);
-+ s->mode = BAD;
-+ }
-+ LEAVE
-+ }
-+ s->sub.trees.index = 0;
-+ Tracev((stderr, "inflate: bits tree ok\n"));
-+ s->mode = DTREE;
-+ case DTREE:
-+ while (t = s->sub.trees.table,
-+ s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
-+ {
-+ inflate_huft *h;
-+ uInt i, j, c;
-+
-+ t = s->sub.trees.bb;
-+ NEEDBITS(t)
-+ h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
-+ t = h->bits;
-+ c = h->base;
-+ if (c < 16)
-+ {
-+ DUMPBITS(t)
-+ s->sub.trees.blens[s->sub.trees.index++] = c;
-+ }
-+ else /* c == 16..18 */
-+ {
-+ i = c == 18 ? 7 : c - 14;
-+ j = c == 18 ? 11 : 3;
-+ NEEDBITS(t + i)
-+ DUMPBITS(t)
-+ j += (uInt)b & inflate_mask[i];
-+ DUMPBITS(i)
-+ i = s->sub.trees.index;
-+ t = s->sub.trees.table;
-+ if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
-+ (c == 16 && i < 1))
-+ {
-+ ZFREE(z, s->sub.trees.blens);
-+ s->mode = BAD;
-+ z->msg = (char*)"invalid bit length repeat";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ }
-+ c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
-+ do {
-+ s->sub.trees.blens[i++] = c;
-+ } while (--j);
-+ s->sub.trees.index = i;
-+ }
-+ }
-+ s->sub.trees.tb = Z_NULL;
-+ {
-+ uInt bl, bd;
-+ inflate_huft *tl, *td;
-+ inflate_codes_statef *c;
-+
-+ bl = 9; /* must be <= 9 for lookahead assumptions */
-+ bd = 6; /* must be <= 9 for lookahead assumptions */
-+ t = s->sub.trees.table;
-+ t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
-+ s->sub.trees.blens, &bl, &bd, &tl, &td,
-+ s->hufts, z);
-+ if (t != Z_OK)
-+ {
-+ if (t == (uInt)Z_DATA_ERROR)
-+ {
-+ ZFREE(z, s->sub.trees.blens);
-+ s->mode = BAD;
-+ }
-+ r = t;
-+ LEAVE
-+ }
-+ Tracev((stderr, "inflate: trees ok\n"));
-+ if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
-+ {
-+ r = Z_MEM_ERROR;
-+ LEAVE
-+ }
-+ s->sub.decode.codes = c;
-+ }
-+ ZFREE(z, s->sub.trees.blens);
-+ s->mode = CODES;
-+ case CODES:
-+ UPDATE
-+ if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
-+ return inflate_flush(s, z, r);
-+ r = Z_OK;
-+ inflate_codes_free(s->sub.decode.codes, z);
-+ LOAD
-+ Tracev((stderr, "inflate: codes end, %lu total out\n",
-+ z->total_out + (q >= s->read ? q - s->read :
-+ (s->end - s->read) + (q - s->window))));
-+ if (!s->last)
-+ {
-+ s->mode = TYPE;
-+ break;
-+ }
-+ s->mode = DRY;
-+ case DRY:
-+ FLUSH
-+ if (s->read != s->write)
-+ LEAVE
-+ s->mode = DONE;
-+ case DONE:
-+ r = Z_STREAM_END;
-+ LEAVE
-+ case BAD:
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ default:
-+ r = Z_STREAM_ERROR;
-+ LEAVE
-+ }
-+}
-+
-+
-+int inflate_blocks_free(s, z)
-+inflate_blocks_statef *s;
-+z_streamp z;
-+{
-+ inflate_blocks_reset(s, z, Z_NULL);
-+ ZFREE(z, s->window);
-+ ZFREE(z, s->hufts);
-+ ZFREE(z, s);
-+ Tracev((stderr, "inflate: blocks freed\n"));
-+ return Z_OK;
-+}
-+
-+
-+void inflate_set_dictionary(s, d, n)
-+inflate_blocks_statef *s;
-+const Bytef *d;
-+uInt n;
-+{
-+ zmemcpy(s->window, d, n);
-+ s->read = s->write = s->window + n;
-+}
-+
-+
-+/* Returns true if inflate is currently at the end of a block generated
-+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH.
-+ * IN assertion: s != Z_NULL
-+ */
-+int inflate_blocks_sync_point(s)
-+inflate_blocks_statef *s;
-+{
-+ return s->mode == LENS;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/infblock.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,39 @@
-+/* infblock.h -- header to use infblock.c
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+struct inflate_blocks_state;
-+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
-+
-+extern inflate_blocks_statef * inflate_blocks_new OF((
-+ z_streamp z,
-+ check_func c, /* check function */
-+ uInt w)); /* window size */
-+
-+extern int inflate_blocks OF((
-+ inflate_blocks_statef *,
-+ z_streamp ,
-+ int)); /* initial return code */
-+
-+extern void inflate_blocks_reset OF((
-+ inflate_blocks_statef *,
-+ z_streamp ,
-+ uLongf *)); /* check value on output */
-+
-+extern int inflate_blocks_free OF((
-+ inflate_blocks_statef *,
-+ z_streamp));
-+
-+extern void inflate_set_dictionary OF((
-+ inflate_blocks_statef *s,
-+ const Bytef *d, /* dictionary */
-+ uInt n)); /* dictionary length */
-+
-+extern int inflate_blocks_sync_point OF((
-+ inflate_blocks_statef *s));
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/infcodes.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,251 @@
-+/* infcodes.c -- process literals and length/distance pairs
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+#include <zlib/zutil.h>
-+#include "inftrees.h"
-+#include "infblock.h"
-+#include "infcodes.h"
-+#include "infutil.h"
-+#include "inffast.h"
-+
-+/* simplify the use of the inflate_huft type with some defines */
-+#define exop word.what.Exop
-+#define bits word.what.Bits
-+
-+typedef enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
-+ START, /* x: set up for LEN */
-+ LEN, /* i: get length/literal/eob next */
-+ LENEXT, /* i: getting length extra (have base) */
-+ DIST, /* i: get distance next */
-+ DISTEXT, /* i: getting distance extra */
-+ COPY, /* o: copying bytes in window, waiting for space */
-+ LIT, /* o: got literal, waiting for output space */
-+ WASH, /* o: got eob, possibly still output waiting */
-+ END, /* x: got eob and all data flushed */
-+ BADCODE} /* x: got error */
-+inflate_codes_mode;
-+
-+/* inflate codes private state */
-+struct inflate_codes_state {
-+
-+ /* mode */
-+ inflate_codes_mode mode; /* current inflate_codes mode */
-+
-+ /* mode dependent information */
-+ uInt len;
-+ union {
-+ struct {
-+ inflate_huft *tree; /* pointer into tree */
-+ uInt need; /* bits needed */
-+ } code; /* if LEN or DIST, where in tree */
-+ uInt lit; /* if LIT, literal */
-+ struct {
-+ uInt get; /* bits to get for extra */
-+ uInt dist; /* distance back to copy from */
-+ } copy; /* if EXT or COPY, where and how much */
-+ } sub; /* submode */
-+
-+ /* mode independent information */
-+ Byte lbits; /* ltree bits decoded per branch */
-+ Byte dbits; /* dtree bits decoder per branch */
-+ inflate_huft *ltree; /* literal/length/eob tree */
-+ inflate_huft *dtree; /* distance tree */
-+
-+};
-+
-+
-+inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
-+uInt bl, bd;
-+inflate_huft *tl;
-+inflate_huft *td; /* need separate declaration for Borland C++ */
-+z_streamp z;
-+{
-+ inflate_codes_statef *c;
-+
-+ if ((c = (inflate_codes_statef *)
-+ ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
-+ {
-+ c->mode = START;
-+ c->lbits = (Byte)bl;
-+ c->dbits = (Byte)bd;
-+ c->ltree = tl;
-+ c->dtree = td;
-+ Tracev((stderr, "inflate: codes new\n"));
-+ }
-+ return c;
-+}
-+
-+
-+int inflate_codes(s, z, r)
-+inflate_blocks_statef *s;
-+z_streamp z;
-+int r;
-+{
-+ uInt j; /* temporary storage */
-+ inflate_huft *t; /* temporary pointer */
-+ uInt e; /* extra bits or operation */
-+ uLong b; /* bit buffer */
-+ uInt k; /* bits in bit buffer */
-+ Bytef *p; /* input data pointer */
-+ uInt n; /* bytes available there */
-+ Bytef *q; /* output window write pointer */
-+ uInt m; /* bytes to end of window or read pointer */
-+ Bytef *f; /* pointer to copy strings from */
-+ inflate_codes_statef *c = s->sub.decode.codes; /* codes state */
-+
-+ /* copy input/output information to locals (UPDATE macro restores) */
-+ LOAD
-+
-+ /* process input and output based on current state */
-+ while (1) switch (c->mode)
-+ { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
-+ case START: /* x: set up for LEN */
-+#ifndef SLOW
-+ if (m >= 258 && n >= 10)
-+ {
-+ UPDATE
-+ r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
-+ LOAD
-+ if (r != Z_OK)
-+ {
-+ c->mode = r == Z_STREAM_END ? WASH : BADCODE;
-+ break;
-+ }
-+ }
-+#endif /* !SLOW */
-+ c->sub.code.need = c->lbits;
-+ c->sub.code.tree = c->ltree;
-+ c->mode = LEN;
-+ case LEN: /* i: get length/literal/eob next */
-+ j = c->sub.code.need;
-+ NEEDBITS(j)
-+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
-+ DUMPBITS(t->bits)
-+ e = (uInt)(t->exop);
-+ if (e == 0) /* literal */
-+ {
-+ c->sub.lit = t->base;
-+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-+ "inflate: literal '%c'\n" :
-+ "inflate: literal 0x%02x\n", t->base));
-+ c->mode = LIT;
-+ break;
-+ }
-+ if (e & 16) /* length */
-+ {
-+ c->sub.copy.get = e & 15;
-+ c->len = t->base;
-+ c->mode = LENEXT;
-+ break;
-+ }
-+ if ((e & 64) == 0) /* next table */
-+ {
-+ c->sub.code.need = e;
-+ c->sub.code.tree = t + t->base;
-+ break;
-+ }
-+ if (e & 32) /* end of block */
-+ {
-+ Tracevv((stderr, "inflate: end of block\n"));
-+ c->mode = WASH;
-+ break;
-+ }
-+ c->mode = BADCODE; /* invalid code */
-+ z->msg = (char*)"invalid literal/length code";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ case LENEXT: /* i: getting length extra (have base) */
-+ j = c->sub.copy.get;
-+ NEEDBITS(j)
-+ c->len += (uInt)b & inflate_mask[j];
-+ DUMPBITS(j)
-+ c->sub.code.need = c->dbits;
-+ c->sub.code.tree = c->dtree;
-+ Tracevv((stderr, "inflate: length %u\n", c->len));
-+ c->mode = DIST;
-+ case DIST: /* i: get distance next */
-+ j = c->sub.code.need;
-+ NEEDBITS(j)
-+ t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
-+ DUMPBITS(t->bits)
-+ e = (uInt)(t->exop);
-+ if (e & 16) /* distance */
-+ {
-+ c->sub.copy.get = e & 15;
-+ c->sub.copy.dist = t->base;
-+ c->mode = DISTEXT;
-+ break;
-+ }
-+ if ((e & 64) == 0) /* next table */
-+ {
-+ c->sub.code.need = e;
-+ c->sub.code.tree = t + t->base;
-+ break;
-+ }
-+ c->mode = BADCODE; /* invalid code */
-+ z->msg = (char*)"invalid distance code";
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ case DISTEXT: /* i: getting distance extra */
-+ j = c->sub.copy.get;
-+ NEEDBITS(j)
-+ c->sub.copy.dist += (uInt)b & inflate_mask[j];
-+ DUMPBITS(j)
-+ Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist));
-+ c->mode = COPY;
-+ case COPY: /* o: copying bytes in window, waiting for space */
-+ f = q - c->sub.copy.dist;
-+ while (f < s->window) /* modulo window size-"while" instead */
-+ f += s->end - s->window; /* of "if" handles invalid distances */
-+ while (c->len)
-+ {
-+ NEEDOUT
-+ OUTBYTE(*f++)
-+ if (f == s->end)
-+ f = s->window;
-+ c->len--;
-+ }
-+ c->mode = START;
-+ break;
-+ case LIT: /* o: got literal, waiting for output space */
-+ NEEDOUT
-+ OUTBYTE(c->sub.lit)
-+ c->mode = START;
-+ break;
-+ case WASH: /* o: got eob, possibly more output */
-+ if (k > 7) /* return unused byte, if any */
-+ {
-+ Assert(k < 16, "inflate_codes grabbed too many bytes")
-+ k -= 8;
-+ n++;
-+ p--; /* can always return one */
-+ }
-+ FLUSH
-+ if (s->read != s->write)
-+ LEAVE
-+ c->mode = END;
-+ case END:
-+ r = Z_STREAM_END;
-+ LEAVE
-+ case BADCODE: /* x: got error */
-+ r = Z_DATA_ERROR;
-+ LEAVE
-+ default:
-+ r = Z_STREAM_ERROR;
-+ LEAVE
-+ }
-+#ifdef NEED_DUMMY_RETURN
-+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
-+#endif
-+}
-+
-+
-+void inflate_codes_free(c, z)
-+inflate_codes_statef *c;
-+z_streamp z;
-+{
-+ ZFREE(z, c);
-+ Tracev((stderr, "inflate: codes free\n"));
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/infcodes.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,31 @@
-+/* infcodes.h -- header to use infcodes.c
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+#ifndef _INFCODES_H
-+#define _INFCODES_H
-+
-+struct inflate_codes_state;
-+typedef struct inflate_codes_state FAR inflate_codes_statef;
-+
-+extern inflate_codes_statef *inflate_codes_new OF((
-+ uInt, uInt,
-+ inflate_huft *, inflate_huft *,
-+ z_streamp ));
-+
-+extern int inflate_codes OF((
-+ inflate_blocks_statef *,
-+ z_streamp ,
-+ int));
-+
-+extern void inflate_codes_free OF((
-+ inflate_codes_statef *,
-+ z_streamp ));
-+
-+#endif /* _INFCODES_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/inffast.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,183 @@
-+/* inffast.c -- process literals and length/distance pairs fast
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+#include <zlib/zutil.h>
-+#include "inftrees.h"
-+#include "infblock.h"
-+#include "infcodes.h"
-+#include "infutil.h"
-+#include "inffast.h"
-+
-+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-+
-+/* simplify the use of the inflate_huft type with some defines */
-+#define exop word.what.Exop
-+#define bits word.what.Bits
-+
-+/* macros for bit input with no checking and for returning unused bytes */
-+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-+#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
-+
-+/* Called with number of bytes left to write in window at least 258
-+ (the maximum string length) and number of input bytes available
-+ at least ten. The ten bytes are six bytes for the longest length/
-+ distance pair plus four bytes for overloading the bit buffer. */
-+
-+int inflate_fast(bl, bd, tl, td, s, z)
-+uInt bl, bd;
-+inflate_huft *tl;
-+inflate_huft *td; /* need separate declaration for Borland C++ */
-+inflate_blocks_statef *s;
-+z_streamp z;
-+{
-+ inflate_huft *t; /* temporary pointer */
-+ uInt e; /* extra bits or operation */
-+ uLong b; /* bit buffer */
-+ uInt k; /* bits in bit buffer */
-+ Bytef *p; /* input data pointer */
-+ uInt n; /* bytes available there */
-+ Bytef *q; /* output window write pointer */
-+ uInt m; /* bytes to end of window or read pointer */
-+ uInt ml; /* mask for literal/length tree */
-+ uInt md; /* mask for distance tree */
-+ uInt c; /* bytes to copy */
-+ uInt d; /* distance back to copy from */
-+ Bytef *r; /* copy source pointer */
-+
-+ /* load input, output, bit values */
-+ LOAD
-+
-+ /* initialize masks */
-+ ml = inflate_mask[bl];
-+ md = inflate_mask[bd];
-+
-+ /* do until not enough input or output space for fast loop */
-+ do { /* assume called with m >= 258 && n >= 10 */
-+ /* get literal/length code */
-+ GRABBITS(20) /* max bits for literal/length code */
-+ if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
-+ {
-+ DUMPBITS(t->bits)
-+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-+ "inflate: * literal '%c'\n" :
-+ "inflate: * literal 0x%02x\n", t->base));
-+ *q++ = (Byte)t->base;
-+ m--;
-+ continue;
-+ }
-+ do {
-+ DUMPBITS(t->bits)
-+ if (e & 16)
-+ {
-+ /* get extra bits for length */
-+ e &= 15;
-+ c = t->base + ((uInt)b & inflate_mask[e]);
-+ DUMPBITS(e)
-+ Tracevv((stderr, "inflate: * length %u\n", c));
-+
-+ /* decode distance base of block to copy */
-+ GRABBITS(15); /* max bits for distance code */
-+ e = (t = td + ((uInt)b & md))->exop;
-+ do {
-+ DUMPBITS(t->bits)
-+ if (e & 16)
-+ {
-+ /* get extra bits to add to distance base */
-+ e &= 15;
-+ GRABBITS(e) /* get extra bits (up to 13) */
-+ d = t->base + ((uInt)b & inflate_mask[e]);
-+ DUMPBITS(e)
-+ Tracevv((stderr, "inflate: * distance %u\n", d));
-+
-+ /* do the copy */
-+ m -= c;
-+ r = q - d;
-+ if (r < s->window) /* wrap if needed */
-+ {
-+ do {
-+ r += s->end - s->window; /* force pointer in window */
-+ } while (r < s->window); /* covers invalid distances */
-+ e = s->end - r;
-+ if (c > e)
-+ {
-+ c -= e; /* wrapped copy */
-+ do {
-+ *q++ = *r++;
-+ } while (--e);
-+ r = s->window;
-+ do {
-+ *q++ = *r++;
-+ } while (--c);
-+ }
-+ else /* normal copy */
-+ {
-+ *q++ = *r++; c--;
-+ *q++ = *r++; c--;
-+ do {
-+ *q++ = *r++;
-+ } while (--c);
-+ }
-+ }
-+ else /* normal copy */
-+ {
-+ *q++ = *r++; c--;
-+ *q++ = *r++; c--;
-+ do {
-+ *q++ = *r++;
-+ } while (--c);
-+ }
-+ break;
-+ }
-+ else if ((e & 64) == 0)
-+ {
-+ t += t->base;
-+ e = (t += ((uInt)b & inflate_mask[e]))->exop;
-+ }
-+ else
-+ {
-+ z->msg = (char*)"invalid distance code";
-+ UNGRAB
-+ UPDATE
-+ return Z_DATA_ERROR;
-+ }
-+ } while (1);
-+ break;
-+ }
-+ if ((e & 64) == 0)
-+ {
-+ t += t->base;
-+ if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
-+ {
-+ DUMPBITS(t->bits)
-+ Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
-+ "inflate: * literal '%c'\n" :
-+ "inflate: * literal 0x%02x\n", t->base));
-+ *q++ = (Byte)t->base;
-+ m--;
-+ break;
-+ }
-+ }
-+ else if (e & 32)
-+ {
-+ Tracevv((stderr, "inflate: * end of block\n"));
-+ UNGRAB
-+ UPDATE
-+ return Z_STREAM_END;
-+ }
-+ else
-+ {
-+ z->msg = (char*)"invalid literal/length code";
-+ UNGRAB
-+ UPDATE
-+ return Z_DATA_ERROR;
-+ }
-+ } while (1);
-+ } while (m >= 258 && n >= 10);
-+
-+ /* not enough input or output--restore pointers and return */
-+ UNGRAB
-+ UPDATE
-+ return Z_OK;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/inffast.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,22 @@
-+/* inffast.h -- header to use inffast.c
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+#ifndef _INFFAST_H
-+#define _INFFAST_H
-+
-+extern int inflate_fast OF((
-+ uInt,
-+ uInt,
-+ inflate_huft *,
-+ inflate_huft *,
-+ inflate_blocks_statef *,
-+ z_streamp ));
-+
-+#endif /* _INFFAST_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/inffixed.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,151 @@
-+/* inffixed.h -- table for decoding fixed codes
-+ * Generated automatically by the maketree.c program
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+local uInt fixed_bl = 9;
-+local uInt fixed_bd = 5;
-+local inflate_huft fixed_tl[] = {
-+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
-+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
-+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
-+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
-+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
-+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
-+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
-+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
-+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
-+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
-+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
-+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
-+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
-+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
-+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
-+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
-+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
-+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
-+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
-+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
-+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
-+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
-+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
-+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
-+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
-+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
-+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
-+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
-+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
-+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
-+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
-+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
-+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
-+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
-+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
-+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
-+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
-+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
-+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
-+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
-+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
-+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
-+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
-+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
-+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
-+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
-+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
-+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
-+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
-+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
-+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
-+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
-+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
-+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
-+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
-+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
-+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
-+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
-+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
-+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
-+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
-+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
-+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
-+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
-+ {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
-+ {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
-+ {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
-+ {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
-+ {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
-+ {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
-+ {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
-+ {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
-+ {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
-+ {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
-+ {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
-+ {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
-+ {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
-+ {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
-+ {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
-+ {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
-+ {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
-+ {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
-+ {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
-+ {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
-+ {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
-+ {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
-+ {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
-+ {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
-+ {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
-+ {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
-+ {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
-+ {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
-+ {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
-+ {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
-+ {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
-+ {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
-+ {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
-+ {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
-+ {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
-+ {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
-+ {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
-+ {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
-+ {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
-+ {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
-+ {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
-+ {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
-+ {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
-+ {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
-+ {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
-+ {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
-+ {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
-+ {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
-+ {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
-+ {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
-+ {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
-+ {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
-+ {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
-+ {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
-+ {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
-+ {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
-+ {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
-+ {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
-+ {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
-+ {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
-+ {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
-+ {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
-+ {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
-+ {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
-+ };
-+local inflate_huft fixed_td[] = {
-+ {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
-+ {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
-+ {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
-+ {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
-+ {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
-+ {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
-+ {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
-+ {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
-+ };
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/inflate.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,368 @@
-+/* inflate.c -- zlib interface to inflate modules
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+#include <zlib/zutil.h>
-+#include "infblock.h"
-+
-+struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
-+
-+typedef enum {
-+ METHOD, /* waiting for method byte */
-+ FLAG, /* waiting for flag byte */
-+ DICT4, /* four dictionary check bytes to go */
-+ DICT3, /* three dictionary check bytes to go */
-+ DICT2, /* two dictionary check bytes to go */
-+ DICT1, /* one dictionary check byte to go */
-+ DICT0, /* waiting for inflateSetDictionary */
-+ BLOCKS, /* decompressing blocks */
-+ CHECK4, /* four check bytes to go */
-+ CHECK3, /* three check bytes to go */
-+ CHECK2, /* two check bytes to go */
-+ CHECK1, /* one check byte to go */
-+ DONE, /* finished check, done */
-+ BAD} /* got an error--stay here */
-+inflate_mode;
-+
-+/* inflate private state */
-+struct internal_state {
-+
-+ /* mode */
-+ inflate_mode mode; /* current inflate mode */
-+
-+ /* mode dependent information */
-+ union {
-+ uInt method; /* if FLAGS, method byte */
-+ struct {
-+ uLong was; /* computed check value */
-+ uLong need; /* stream check value */
-+ } check; /* if CHECK, check values to compare */
-+ uInt marker; /* if BAD, inflateSync's marker bytes count */
-+ } sub; /* submode */
-+
-+ /* mode independent information */
-+ int nowrap; /* flag for no wrapper */
-+ uInt wbits; /* log2(window size) (8..15, defaults to 15) */
-+ inflate_blocks_statef
-+ *blocks; /* current inflate_blocks state */
-+
-+};
-+
-+
-+int ZEXPORT inflateReset(z)
-+z_streamp z;
-+{
-+ if (z == Z_NULL || z->state == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ z->total_in = z->total_out = 0;
-+ z->msg = Z_NULL;
-+ z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
-+ inflate_blocks_reset(z->state->blocks, z, Z_NULL);
-+ Tracev((stderr, "inflate: reset\n"));
-+ return Z_OK;
-+}
-+
-+
-+int ZEXPORT inflateEnd(z)
-+z_streamp z;
-+{
-+ if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ if (z->state->blocks != Z_NULL)
-+ inflate_blocks_free(z->state->blocks, z);
-+ ZFREE(z, z->state);
-+ z->state = Z_NULL;
-+ Tracev((stderr, "inflate: end\n"));
-+ return Z_OK;
-+}
-+
-+
-+int ZEXPORT inflateInit2_(z, w, version, stream_size)
-+z_streamp z;
-+int w;
-+const char *version;
-+int stream_size;
-+{
-+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
-+ stream_size != sizeof(z_stream))
-+ return Z_VERSION_ERROR;
-+
-+ /* initialize state */
-+ if (z == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ z->msg = Z_NULL;
-+ if (z->zalloc == Z_NULL)
-+ {
-+ return Z_STREAM_ERROR;
-+/* z->zalloc = zcalloc;
-+ z->opaque = (voidpf)0;
-+*/
-+ }
-+ if (z->zfree == Z_NULL) return Z_STREAM_ERROR; /* z->zfree = zcfree; */
-+ if ((z->state = (struct internal_state FAR *)
-+ ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
-+ return Z_MEM_ERROR;
-+ z->state->blocks = Z_NULL;
-+
-+ /* handle undocumented nowrap option (no zlib header or check) */
-+ z->state->nowrap = 0;
-+ if (w < 0)
-+ {
-+ w = - w;
-+ z->state->nowrap = 1;
-+ }
-+
-+ /* set window size */
-+ if (w < 8 || w > 15)
-+ {
-+ inflateEnd(z);
-+ return Z_STREAM_ERROR;
-+ }
-+ z->state->wbits = (uInt)w;
-+
-+ /* create inflate_blocks state */
-+ if ((z->state->blocks =
-+ inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
-+ == Z_NULL)
-+ {
-+ inflateEnd(z);
-+ return Z_MEM_ERROR;
-+ }
-+ Tracev((stderr, "inflate: allocated\n"));
-+
-+ /* reset state */
-+ inflateReset(z);
-+ return Z_OK;
-+}
-+
-+
-+int ZEXPORT inflateInit_(z, version, stream_size)
-+z_streamp z;
-+const char *version;
-+int stream_size;
-+{
-+ return inflateInit2_(z, DEF_WBITS, version, stream_size);
-+}
-+
-+
-+#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
-+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
-+
-+int ZEXPORT inflate(z, f)
-+z_streamp z;
-+int f;
-+{
-+ int r;
-+ uInt b;
-+
-+ if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
-+ r = Z_BUF_ERROR;
-+ while (1) switch (z->state->mode)
-+ {
-+ case METHOD:
-+ NEEDBYTE
-+ if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = (char*)"unknown compression method";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = (char*)"invalid window size";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ z->state->mode = FLAG;
-+ case FLAG:
-+ NEEDBYTE
-+ b = NEXTBYTE;
-+ if (((z->state->sub.method << 8) + b) % 31)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = (char*)"incorrect header check";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ Tracev((stderr, "inflate: zlib header ok\n"));
-+ if (!(b & PRESET_DICT))
-+ {
-+ z->state->mode = BLOCKS;
-+ break;
-+ }
-+ z->state->mode = DICT4;
-+ case DICT4:
-+ NEEDBYTE
-+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
-+ z->state->mode = DICT3;
-+ case DICT3:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
-+ z->state->mode = DICT2;
-+ case DICT2:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
-+ z->state->mode = DICT1;
-+ case DICT1:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE;
-+ z->adler = z->state->sub.check.need;
-+ z->state->mode = DICT0;
-+ return Z_NEED_DICT;
-+ case DICT0:
-+ z->state->mode = BAD;
-+ z->msg = (char*)"need dictionary";
-+ z->state->sub.marker = 0; /* can try inflateSync */
-+ return Z_STREAM_ERROR;
-+ case BLOCKS:
-+ r = inflate_blocks(z->state->blocks, z, r);
-+ if (r == Z_DATA_ERROR)
-+ {
-+ z->state->mode = BAD;
-+ z->state->sub.marker = 0; /* can try inflateSync */
-+ break;
-+ }
-+ if (r == Z_OK)
-+ r = f;
-+ if (r != Z_STREAM_END)
-+ return r;
-+ r = f;
-+ inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
-+ if (z->state->nowrap)
-+ {
-+ z->state->mode = DONE;
-+ break;
-+ }
-+ z->state->mode = CHECK4;
-+ case CHECK4:
-+ NEEDBYTE
-+ z->state->sub.check.need = (uLong)NEXTBYTE << 24;
-+ z->state->mode = CHECK3;
-+ case CHECK3:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE << 16;
-+ z->state->mode = CHECK2;
-+ case CHECK2:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE << 8;
-+ z->state->mode = CHECK1;
-+ case CHECK1:
-+ NEEDBYTE
-+ z->state->sub.check.need += (uLong)NEXTBYTE;
-+
-+ if (z->state->sub.check.was != z->state->sub.check.need)
-+ {
-+ z->state->mode = BAD;
-+ z->msg = (char*)"incorrect data check";
-+ z->state->sub.marker = 5; /* can't try inflateSync */
-+ break;
-+ }
-+ Tracev((stderr, "inflate: zlib check ok\n"));
-+ z->state->mode = DONE;
-+ case DONE:
-+ return Z_STREAM_END;
-+ case BAD:
-+ return Z_DATA_ERROR;
-+ default:
-+ return Z_STREAM_ERROR;
-+ }
-+#ifdef NEED_DUMMY_RETURN
-+ return Z_STREAM_ERROR; /* Some dumb compilers complain without this */
-+#endif
-+}
-+
-+
-+int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
-+z_streamp z;
-+const Bytef *dictionary;
-+uInt dictLength;
-+{
-+ uInt length = dictLength;
-+
-+ if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
-+ return Z_STREAM_ERROR;
-+
-+ if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
-+ z->adler = 1L;
-+
-+ if (length >= ((uInt)1<<z->state->wbits))
-+ {
-+ length = (1<<z->state->wbits)-1;
-+ dictionary += dictLength - length;
-+ }
-+ inflate_set_dictionary(z->state->blocks, dictionary, length);
-+ z->state->mode = BLOCKS;
-+ return Z_OK;
-+}
-+
-+
-+int ZEXPORT inflateSync(z)
-+z_streamp z;
-+{
-+ uInt n; /* number of bytes to look at */
-+ Bytef *p; /* pointer to bytes */
-+ uInt m; /* number of marker bytes found in a row */
-+ uLong r, w; /* temporaries to save total_in and total_out */
-+
-+ /* set up */
-+ if (z == Z_NULL || z->state == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ if (z->state->mode != BAD)
-+ {
-+ z->state->mode = BAD;
-+ z->state->sub.marker = 0;
-+ }
-+ if ((n = z->avail_in) == 0)
-+ return Z_BUF_ERROR;
-+ p = z->next_in;
-+ m = z->state->sub.marker;
-+
-+ /* search */
-+ while (n && m < 4)
-+ {
-+ static const Byte mark[4] = {0, 0, 0xff, 0xff};
-+ if (*p == mark[m])
-+ m++;
-+ else if (*p)
-+ m = 0;
-+ else
-+ m = 4 - m;
-+ p++, n--;
-+ }
-+
-+ /* restore */
-+ z->total_in += p - z->next_in;
-+ z->next_in = p;
-+ z->avail_in = n;
-+ z->state->sub.marker = m;
-+
-+ /* return no joy or set up to restart on a new block */
-+ if (m != 4)
-+ return Z_DATA_ERROR;
-+ r = z->total_in; w = z->total_out;
-+ inflateReset(z);
-+ z->total_in = r; z->total_out = w;
-+ z->state->mode = BLOCKS;
-+ return Z_OK;
-+}
-+
-+
-+/* Returns true if inflate is currently at the end of a block generated
-+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
-+ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
-+ * but removes the length bytes of the resulting empty stored block. When
-+ * decompressing, PPP checks that at the end of input packet, inflate is
-+ * waiting for these length bytes.
-+ */
-+int ZEXPORT inflateSyncPoint(z)
-+z_streamp z;
-+{
-+ if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
-+ return Z_STREAM_ERROR;
-+ return inflate_blocks_sync_point(z->state->blocks);
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/inftrees.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,454 @@
-+/* inftrees.c -- generate Huffman trees for efficient decoding
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+#include <zlib/zutil.h>
-+#include "inftrees.h"
-+
-+#if !defined(BUILDFIXED) && !defined(STDC)
-+# define BUILDFIXED /* non ANSI compilers may not accept inffixed.h */
-+#endif
-+
-+local const char inflate_copyright[] =
-+ " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
-+/*
-+ If you use the zlib library in a product, an acknowledgment is welcome
-+ in the documentation of your product. If for some reason you cannot
-+ include such an acknowledgment, I would appreciate that you keep this
-+ copyright string in the executable of your product.
-+ */
-+struct internal_state {int dummy;}; /* for buggy compilers */
-+
-+/* simplify the use of the inflate_huft type with some defines */
-+#define exop word.what.Exop
-+#define bits word.what.Bits
-+
-+
-+local int huft_build OF((
-+ uIntf *, /* code lengths in bits */
-+ uInt, /* number of codes */
-+ uInt, /* number of "simple" codes */
-+ const uIntf *, /* list of base values for non-simple codes */
-+ const uIntf *, /* list of extra bits for non-simple codes */
-+ inflate_huft * FAR*,/* result: starting table */
-+ uIntf *, /* maximum lookup bits (returns actual) */
-+ inflate_huft *, /* space for trees */
-+ uInt *, /* hufts used in space */
-+ uIntf * )); /* space for values */
-+
-+/* Tables for deflate from PKZIP's appnote.txt. */
-+local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
-+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
-+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
-+ /* see note #13 above about 258 */
-+local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
-+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
-+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
-+local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
-+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
-+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
-+ 8193, 12289, 16385, 24577};
-+local const uInt cpdext[30] = { /* Extra bits for distance codes */
-+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
-+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
-+ 12, 12, 13, 13};
-+
-+/*
-+ Huffman code decoding is performed using a multi-level table lookup.
-+ The fastest way to decode is to simply build a lookup table whose
-+ size is determined by the longest code. However, the time it takes
-+ to build this table can also be a factor if the data being decoded
-+ is not very long. The most common codes are necessarily the
-+ shortest codes, so those codes dominate the decoding time, and hence
-+ the speed. The idea is you can have a shorter table that decodes the
-+ shorter, more probable codes, and then point to subsidiary tables for
-+ the longer codes. The time it costs to decode the longer codes is
-+ then traded against the time it takes to make longer tables.
-+
-+ This results of this trade are in the variables lbits and dbits
-+ below. lbits is the number of bits the first level table for literal/
-+ length codes can decode in one step, and dbits is the same thing for
-+ the distance codes. Subsequent tables are also less than or equal to
-+ those sizes. These values may be adjusted either when all of the
-+ codes are shorter than that, in which case the longest code length in
-+ bits is used, or when the shortest code is *longer* than the requested
-+ table size, in which case the length of the shortest code in bits is
-+ used.
-+
-+ There are two different values for the two tables, since they code a
-+ different number of possibilities each. The literal/length table
-+ codes 286 possible values, or in a flat code, a little over eight
-+ bits. The distance table codes 30 possible values, or a little less
-+ than five bits, flat. The optimum values for speed end up being
-+ about one bit more than those, so lbits is 8+1 and dbits is 5+1.
-+ The optimum values may differ though from machine to machine, and
-+ possibly even between compilers. Your mileage may vary.
-+ */
-+
-+
-+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
-+#define BMAX 15 /* maximum bit length of any code */
-+
-+local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
-+uIntf *b; /* code lengths in bits (all assumed <= BMAX) */
-+uInt n; /* number of codes (assumed <= 288) */
-+uInt s; /* number of simple-valued codes (0..s-1) */
-+const uIntf *d; /* list of base values for non-simple codes */
-+const uIntf *e; /* list of extra bits for non-simple codes */
-+inflate_huft * FAR *t; /* result: starting table */
-+uIntf *m; /* maximum lookup bits, returns actual */
-+inflate_huft *hp; /* space for trees */
-+uInt *hn; /* hufts used in space */
-+uIntf *v; /* working area: values in order of bit length */
-+/* Given a list of code lengths and a maximum table size, make a set of
-+ tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR
-+ if the given code set is incomplete (the tables are still built in this
-+ case), or Z_DATA_ERROR if the input is invalid. */
-+{
-+
-+ uInt a; /* counter for codes of length k */
-+ uInt c[BMAX+1]; /* bit length count table */
-+ uInt f; /* i repeats in table every f entries */
-+ int g; /* maximum code length */
-+ int h; /* table level */
-+ register uInt i; /* counter, current code */
-+ register uInt j; /* counter */
-+ register int k; /* number of bits in current code */
-+ int l; /* bits per table (returned in m) */
-+ uInt mask; /* (1 << w) - 1, to avoid cc -O bug on HP */
-+ register uIntf *p; /* pointer into c[], b[], or v[] */
-+ inflate_huft *q; /* points to current table */
-+ struct inflate_huft_s r; /* table entry for structure assignment */
-+ inflate_huft *u[BMAX]; /* table stack */
-+ register int w; /* bits before this table == (l * h) */
-+ uInt x[BMAX+1]; /* bit offsets, then code stack */
-+ uIntf *xp; /* pointer into x */
-+ int y; /* number of dummy codes added */
-+ uInt z; /* number of entries in current table */
-+
-+
-+ /* Generate counts for each bit length */
-+ p = c;
-+#define C0 *p++ = 0;
-+#define C2 C0 C0 C0 C0
-+#define C4 C2 C2 C2 C2
-+ C4 /* clear c[]--assume BMAX+1 is 16 */
-+ p = b; i = n;
-+ do {
-+ c[*p++]++; /* assume all entries <= BMAX */
-+ } while (--i);
-+ if (c[0] == n) /* null input--all zero length codes */
-+ {
-+ *t = (inflate_huft *)Z_NULL;
-+ *m = 0;
-+ return Z_OK;
-+ }
-+
-+
-+ /* Find minimum and maximum length, bound *m by those */
-+ l = *m;
-+ for (j = 1; j <= BMAX; j++)
-+ if (c[j])
-+ break;
-+ k = j; /* minimum code length */
-+ if ((uInt)l < j)
-+ l = j;
-+ for (i = BMAX; i; i--)
-+ if (c[i])
-+ break;
-+ g = i; /* maximum code length */
-+ if ((uInt)l > i)
-+ l = i;
-+ *m = l;
-+
-+
-+ /* Adjust last length count to fill out codes, if needed */
-+ for (y = 1 << j; j < i; j++, y <<= 1)
-+ if ((y -= c[j]) < 0)
-+ return Z_DATA_ERROR;
-+ if ((y -= c[i]) < 0)
-+ return Z_DATA_ERROR;
-+ c[i] += y;
-+
-+
-+ /* Generate starting offsets into the value table for each length */
-+ x[1] = j = 0;
-+ p = c + 1; xp = x + 2;
-+ while (--i) { /* note that i == g from above */
-+ *xp++ = (j += *p++);
-+ }
-+
-+
-+ /* Make a table of values in order of bit lengths */
-+ p = b; i = 0;
-+ do {
-+ if ((j = *p++) != 0)
-+ v[x[j]++] = i;
-+ } while (++i < n);
-+ n = x[g]; /* set n to length of v */
-+
-+
-+ /* Generate the Huffman codes and for each, make the table entries */
-+ x[0] = i = 0; /* first Huffman code is zero */
-+ p = v; /* grab values in bit order */
-+ h = -1; /* no tables yet--level -1 */
-+ w = -l; /* bits decoded == (l * h) */
-+ u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */
-+ q = (inflate_huft *)Z_NULL; /* ditto */
-+ z = 0; /* ditto */
-+
-+ /* go through the bit lengths (k already is bits in shortest code) */
-+ for (; k <= g; k++)
-+ {
-+ a = c[k];
-+ while (a--)
-+ {
-+ /* here i is the Huffman code of length k bits for value *p */
-+ /* make tables up to required level */
-+ while (k > w + l)
-+ {
-+ h++;
-+ w += l; /* previous table always l bits */
-+
-+ /* compute minimum size table less than or equal to l bits */
-+ z = g - w;
-+ z = z > (uInt)l ? l : z; /* table size upper limit */
-+ if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */
-+ { /* too few codes for k-w bit table */
-+ f -= a + 1; /* deduct codes from patterns left */
-+ xp = c + k;
-+ if (j < z)
-+ while (++j < z) /* try smaller tables up to z bits */
-+ {
-+ if ((f <<= 1) <= *++xp)
-+ break; /* enough codes to use up j bits */
-+ f -= *xp; /* else deduct codes from patterns */
-+ }
-+ }
-+ z = 1 << j; /* table entries for j-bit table */
-+
-+ /* allocate new table */
-+ if (*hn + z > MANY) /* (note: doesn't matter for fixed) */
-+ return Z_DATA_ERROR; /* overflow of MANY */
-+ u[h] = q = hp + *hn;
-+ *hn += z;
-+
-+ /* connect to last table, if there is one */
-+ if (h)
-+ {
-+ x[h] = i; /* save pattern for backing up */
-+ r.bits = (Byte)l; /* bits to dump before this table */
-+ r.exop = (Byte)j; /* bits in this table */
-+ j = i >> (w - l);
-+ r.base = (uInt)(q - u[h-1] - j); /* offset to this table */
-+ u[h-1][j] = r; /* connect to last table */
-+ }
-+ else
-+ *t = q; /* first table is returned result */
-+ }
-+
-+ /* set up table entry in r */
-+ r.bits = (Byte)(k - w);
-+ if (p >= v + n)
-+ r.exop = 128 + 64; /* out of values--invalid code */
-+ else if (*p < s)
-+ {
-+ r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */
-+ r.base = *p++; /* simple code is just the value */
-+ }
-+ else
-+ {
-+ r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
-+ r.base = d[*p++ - s];
-+ }
-+
-+ /* fill code-like entries with r */
-+ f = 1 << (k - w);
-+ for (j = i >> w; j < z; j += f)
-+ q[j] = r;
-+
-+ /* backwards increment the k-bit code i */
-+ for (j = 1 << (k - 1); i & j; j >>= 1)
-+ i ^= j;
-+ i ^= j;
-+
-+ /* backup over finished tables */
-+ mask = (1 << w) - 1; /* needed on HP, cc -O bug */
-+ while ((i & mask) != x[h])
-+ {
-+ h--; /* don't need to update q */
-+ w -= l;
-+ mask = (1 << w) - 1;
-+ }
-+ }
-+ }
-+
-+
-+ /* Return Z_BUF_ERROR if we were given an incomplete table */
-+ return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
-+}
-+
-+
-+int inflate_trees_bits(c, bb, tb, hp, z)
-+uIntf *c; /* 19 code lengths */
-+uIntf *bb; /* bits tree desired/actual depth */
-+inflate_huft * FAR *tb; /* bits tree result */
-+inflate_huft *hp; /* space for trees */
-+z_streamp z; /* for messages */
-+{
-+ int r;
-+ uInt hn = 0; /* hufts used in space */
-+ uIntf *v; /* work area for huft_build */
-+
-+ if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
-+ return Z_MEM_ERROR;
-+ r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
-+ tb, bb, hp, &hn, v);
-+ if (r == Z_DATA_ERROR)
-+ z->msg = (char*)"oversubscribed dynamic bit lengths tree";
-+ else if (r == Z_BUF_ERROR || *bb == 0)
-+ {
-+ z->msg = (char*)"incomplete dynamic bit lengths tree";
-+ r = Z_DATA_ERROR;
-+ }
-+ ZFREE(z, v);
-+ return r;
-+}
-+
-+
-+int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
-+uInt nl; /* number of literal/length codes */
-+uInt nd; /* number of distance codes */
-+uIntf *c; /* that many (total) code lengths */
-+uIntf *bl; /* literal desired/actual bit depth */
-+uIntf *bd; /* distance desired/actual bit depth */
-+inflate_huft * FAR *tl; /* literal/length tree result */
-+inflate_huft * FAR *td; /* distance tree result */
-+inflate_huft *hp; /* space for trees */
-+z_streamp z; /* for messages */
-+{
-+ int r;
-+ uInt hn = 0; /* hufts used in space */
-+ uIntf *v; /* work area for huft_build */
-+
-+ /* allocate work area */
-+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
-+ return Z_MEM_ERROR;
-+
-+ /* build literal/length tree */
-+ r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
-+ if (r != Z_OK || *bl == 0)
-+ {
-+ if (r == Z_DATA_ERROR)
-+ z->msg = (char*)"oversubscribed literal/length tree";
-+ else if (r != Z_MEM_ERROR)
-+ {
-+ z->msg = (char*)"incomplete literal/length tree";
-+ r = Z_DATA_ERROR;
-+ }
-+ ZFREE(z, v);
-+ return r;
-+ }
-+
-+ /* build distance tree */
-+ r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
-+ if (r != Z_OK || (*bd == 0 && nl > 257))
-+ {
-+ if (r == Z_DATA_ERROR)
-+ z->msg = (char*)"oversubscribed distance tree";
-+ else if (r == Z_BUF_ERROR) {
-+#ifdef PKZIP_BUG_WORKAROUND
-+ r = Z_OK;
-+ }
-+#else
-+ z->msg = (char*)"incomplete distance tree";
-+ r = Z_DATA_ERROR;
-+ }
-+ else if (r != Z_MEM_ERROR)
-+ {
-+ z->msg = (char*)"empty distance tree with lengths";
-+ r = Z_DATA_ERROR;
-+ }
-+ ZFREE(z, v);
-+ return r;
-+#endif
-+ }
-+
-+ /* done */
-+ ZFREE(z, v);
-+ return Z_OK;
-+}
-+
-+
-+/* build fixed tables only once--keep them here */
-+#ifdef BUILDFIXED
-+local int fixed_built = 0;
-+#define FIXEDH 544 /* number of hufts used by fixed tables */
-+local inflate_huft fixed_mem[FIXEDH];
-+local uInt fixed_bl;
-+local uInt fixed_bd;
-+local inflate_huft *fixed_tl;
-+local inflate_huft *fixed_td;
-+#else
-+#include "inffixed.h"
-+#endif
-+
-+
-+int inflate_trees_fixed(bl, bd, tl, td, z)
-+uIntf *bl; /* literal desired/actual bit depth */
-+uIntf *bd; /* distance desired/actual bit depth */
-+inflate_huft * FAR *tl; /* literal/length tree result */
-+inflate_huft * FAR *td; /* distance tree result */
-+z_streamp z; /* for memory allocation */
-+{
-+#ifdef BUILDFIXED
-+ /* build fixed tables if not already */
-+ if (!fixed_built)
-+ {
-+ int k; /* temporary variable */
-+ uInt f = 0; /* number of hufts used in fixed_mem */
-+ uIntf *c; /* length list for huft_build */
-+ uIntf *v; /* work area for huft_build */
-+
-+ /* allocate memory */
-+ if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
-+ return Z_MEM_ERROR;
-+ if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
-+ {
-+ ZFREE(z, c);
-+ return Z_MEM_ERROR;
-+ }
-+
-+ /* literal table */
-+ for (k = 0; k < 144; k++)
-+ c[k] = 8;
-+ for (; k < 256; k++)
-+ c[k] = 9;
-+ for (; k < 280; k++)
-+ c[k] = 7;
-+ for (; k < 288; k++)
-+ c[k] = 8;
-+ fixed_bl = 9;
-+ huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
-+ fixed_mem, &f, v);
-+
-+ /* distance table */
-+ for (k = 0; k < 30; k++)
-+ c[k] = 5;
-+ fixed_bd = 5;
-+ huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
-+ fixed_mem, &f, v);
-+
-+ /* done */
-+ ZFREE(z, v);
-+ ZFREE(z, c);
-+ fixed_built = 1;
-+ }
-+#endif
-+ *bl = fixed_bl;
-+ *bd = fixed_bd;
-+ *tl = fixed_tl;
-+ *td = fixed_td;
-+ return Z_OK;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/inftrees.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,63 @@
-+/* inftrees.h -- header to use inftrees.c
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+/* Huffman code lookup table entry--this entry is four bytes for machines
-+ that have 16-bit pointers (e.g. PC's in the small or medium model). */
-+
-+#ifndef _INFTREES_H
-+#define _INFTREES_H
-+
-+typedef struct inflate_huft_s FAR inflate_huft;
-+
-+struct inflate_huft_s {
-+ union {
-+ struct {
-+ Byte Exop; /* number of extra bits or operation */
-+ Byte Bits; /* number of bits in this code or subcode */
-+ } what;
-+ uInt pad; /* pad structure to a power of 2 (4 bytes for */
-+ } word; /* 16-bit, 8 bytes for 32-bit int's) */
-+ uInt base; /* literal, length base, distance base,
-+ or table offset */
-+};
-+
-+/* Maximum size of dynamic tree. The maximum found in a long but non-
-+ exhaustive search was 1004 huft structures (850 for length/literals
-+ and 154 for distances, the latter actually the result of an
-+ exhaustive search). The actual maximum is not known, but the
-+ value below is more than safe. */
-+#define MANY 1440
-+
-+extern int inflate_trees_bits OF((
-+ uIntf *, /* 19 code lengths */
-+ uIntf *, /* bits tree desired/actual depth */
-+ inflate_huft * FAR *, /* bits tree result */
-+ inflate_huft *, /* space for trees */
-+ z_streamp)); /* for messages */
-+
-+extern int inflate_trees_dynamic OF((
-+ uInt, /* number of literal/length codes */
-+ uInt, /* number of distance codes */
-+ uIntf *, /* that many (total) code lengths */
-+ uIntf *, /* literal desired/actual bit depth */
-+ uIntf *, /* distance desired/actual bit depth */
-+ inflate_huft * FAR *, /* literal/length tree result */
-+ inflate_huft * FAR *, /* distance tree result */
-+ inflate_huft *, /* space for trees */
-+ z_streamp)); /* for messages */
-+
-+extern int inflate_trees_fixed OF((
-+ uIntf *, /* literal desired/actual bit depth */
-+ uIntf *, /* distance desired/actual bit depth */
-+ inflate_huft * FAR *, /* literal/length tree result */
-+ inflate_huft * FAR *, /* distance tree result */
-+ z_streamp)); /* for memory allocation */
-+
-+#endif /* _INFTREES_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/infutil.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,87 @@
-+/* inflate_util.c -- data and routines common to blocks and codes
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+#include <zlib/zutil.h>
-+#include "infblock.h"
-+#include "inftrees.h"
-+#include "infcodes.h"
-+#include "infutil.h"
-+
-+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
-+
-+/* And'ing with mask[n] masks the lower n bits */
-+uInt inflate_mask[17] = {
-+ 0x0000,
-+ 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
-+ 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
-+};
-+
-+
-+/* copy as much as possible from the sliding window to the output area */
-+int inflate_flush(s, z, r)
-+inflate_blocks_statef *s;
-+z_streamp z;
-+int r;
-+{
-+ uInt n;
-+ Bytef *p;
-+ Bytef *q;
-+
-+ /* local copies of source and destination pointers */
-+ p = z->next_out;
-+ q = s->read;
-+
-+ /* compute number of bytes to copy as far as end of window */
-+ n = (uInt)((q <= s->write ? s->write : s->end) - q);
-+ if (n > z->avail_out) n = z->avail_out;
-+ if (n && r == Z_BUF_ERROR) r = Z_OK;
-+
-+ /* update counters */
-+ z->avail_out -= n;
-+ z->total_out += n;
-+
-+ /* update check information */
-+ if (s->checkfn != Z_NULL)
-+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
-+
-+ /* copy as far as end of window */
-+ zmemcpy(p, q, n);
-+ p += n;
-+ q += n;
-+
-+ /* see if more to copy at beginning of window */
-+ if (q == s->end)
-+ {
-+ /* wrap pointers */
-+ q = s->window;
-+ if (s->write == s->end)
-+ s->write = s->window;
-+
-+ /* compute bytes to copy */
-+ n = (uInt)(s->write - q);
-+ if (n > z->avail_out) n = z->avail_out;
-+ if (n && r == Z_BUF_ERROR) r = Z_OK;
-+
-+ /* update counters */
-+ z->avail_out -= n;
-+ z->total_out += n;
-+
-+ /* update check information */
-+ if (s->checkfn != Z_NULL)
-+ z->adler = s->check = (*s->checkfn)(s->check, q, n);
-+
-+ /* copy */
-+ zmemcpy(p, q, n);
-+ p += n;
-+ q += n;
-+ }
-+
-+ /* update pointers */
-+ z->next_out = p;
-+ s->read = q;
-+
-+ /* done */
-+ return r;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/infutil.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,98 @@
-+/* infutil.h -- types and macros common to blocks and codes
-+ * Copyright (C) 1995-2002 Mark Adler
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* WARNING: this file should *not* be used by applications. It is
-+ part of the implementation of the compression library and is
-+ subject to change. Applications should only use zlib.h.
-+ */
-+
-+#ifndef _INFUTIL_H
-+#define _INFUTIL_H
-+
-+typedef enum {
-+ TYPE, /* get type bits (3, including end bit) */
-+ LENS, /* get lengths for stored */
-+ STORED, /* processing stored block */
-+ TABLE, /* get table lengths */
-+ BTREE, /* get bit lengths tree for a dynamic block */
-+ DTREE, /* get length, distance trees for a dynamic block */
-+ CODES, /* processing fixed or dynamic block */
-+ DRY, /* output remaining window bytes */
-+ DONE, /* finished last block, done */
-+ BAD} /* got a data error--stuck here */
-+inflate_block_mode;
-+
-+/* inflate blocks semi-private state */
-+struct inflate_blocks_state {
-+
-+ /* mode */
-+ inflate_block_mode mode; /* current inflate_block mode */
-+
-+ /* mode dependent information */
-+ union {
-+ uInt left; /* if STORED, bytes left to copy */
-+ struct {
-+ uInt table; /* table lengths (14 bits) */
-+ uInt index; /* index into blens (or border) */
-+ uIntf *blens; /* bit lengths of codes */
-+ uInt bb; /* bit length tree depth */
-+ inflate_huft *tb; /* bit length decoding tree */
-+ } trees; /* if DTREE, decoding info for trees */
-+ struct {
-+ inflate_codes_statef
-+ *codes;
-+ } decode; /* if CODES, current state */
-+ } sub; /* submode */
-+ uInt last; /* true if this block is the last block */
-+
-+ /* mode independent information */
-+ uInt bitk; /* bits in bit buffer */
-+ uLong bitb; /* bit buffer */
-+ inflate_huft *hufts; /* single malloc for tree space */
-+ Bytef *window; /* sliding window */
-+ Bytef *end; /* one byte after sliding window */
-+ Bytef *read; /* window read pointer */
-+ Bytef *write; /* window write pointer */
-+ check_func checkfn; /* check function */
-+ uLong check; /* check on output */
-+
-+};
-+
-+
-+/* defines for inflate input/output */
-+/* update pointers and return */
-+#define UPDBITS {s->bitb=b;s->bitk=k;}
-+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
-+#define UPDOUT {s->write=q;}
-+#define UPDATE {UPDBITS UPDIN UPDOUT}
-+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
-+/* get bytes and bits */
-+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
-+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
-+#define NEXTBYTE (n--,*p++)
-+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
-+#define DUMPBITS(j) {b>>=(j);k-=(j);}
-+/* output bytes */
-+#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
-+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
-+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
-+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
-+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
-+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
-+/* load local pointers */
-+#define LOAD {LOADIN LOADOUT}
-+
-+/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
-+extern uInt inflate_mask[17];
-+
-+/* copy as much as possible from the sliding window to the output area */
-+extern int inflate_flush OF((
-+ inflate_blocks_statef *,
-+ z_streamp ,
-+ int));
-+
-+struct internal_state {int dummy;}; /* for buggy compilers */
-+
-+#endif /* _INFUTIL_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/match586.S Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,357 @@
-+/* match.s -- Pentium-optimized version of longest_match()
-+ * Written for zlib 1.1.2
-+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
-+ *
-+ * This is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License.
-+ */
-+
-+#ifndef NO_UNDERLINE
-+#define match_init _ipcomp_match_init
-+#define longest_match _ipcomp_longest_match
-+#else
-+#define match_init ipcomp_match_init
-+#define longest_match ipcomp_longest_match
-+#endif
-+
-+#define MAX_MATCH (258)
-+#define MIN_MATCH (3)
-+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
-+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
-+
-+/* stack frame offsets */
-+
-+#define wmask 0 /* local copy of s->wmask */
-+#define window 4 /* local copy of s->window */
-+#define windowbestlen 8 /* s->window + bestlen */
-+#define chainlenscanend 12 /* high word: current chain len */
-+ /* low word: last bytes sought */
-+#define scanstart 16 /* first two bytes of string */
-+#define scanalign 20 /* dword-misalignment of string */
-+#define nicematch 24 /* a good enough match size */
-+#define bestlen 28 /* size of best match so far */
-+#define scan 32 /* ptr to string wanting match */
-+
-+#define LocalVarsSize (36)
-+/* saved ebx 36 */
-+/* saved edi 40 */
-+/* saved esi 44 */
-+/* saved ebp 48 */
-+/* return address 52 */
-+#define deflatestate 56 /* the function arguments */
-+#define curmatch 60
-+
-+/* Offsets for fields in the deflate_state structure. These numbers
-+ * are calculated from the definition of deflate_state, with the
-+ * assumption that the compiler will dword-align the fields. (Thus,
-+ * changing the definition of deflate_state could easily cause this
-+ * program to crash horribly, without so much as a warning at
-+ * compile time. Sigh.)
-+ */
-+#define dsWSize 36
-+#define dsWMask 44
-+#define dsWindow 48
-+#define dsPrev 56
-+#define dsMatchLen 88
-+#define dsPrevMatch 92
-+#define dsStrStart 100
-+#define dsMatchStart 104
-+#define dsLookahead 108
-+#define dsPrevLen 112
-+#define dsMaxChainLen 116
-+#define dsGoodMatch 132
-+#define dsNiceMatch 136
-+
-+
-+.file "match.S"
-+
-+.globl match_init, longest_match
-+
-+.text
-+
-+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
-+
-+longest_match:
-+
-+/* Save registers that the compiler may be using, and adjust %esp to */
-+/* make room for our stack frame. */
-+
-+ pushl %ebp
-+ pushl %edi
-+ pushl %esi
-+ pushl %ebx
-+ subl $LocalVarsSize, %esp
-+
-+/* Retrieve the function arguments. %ecx will hold cur_match */
-+/* throughout the entire function. %edx will hold the pointer to the */
-+/* deflate_state structure during the function's setup (before */
-+/* entering the main loop). */
-+
-+ movl deflatestate(%esp), %edx
-+ movl curmatch(%esp), %ecx
-+
-+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
-+
-+ movl dsNiceMatch(%edx), %eax
-+ movl dsLookahead(%edx), %ebx
-+ cmpl %eax, %ebx
-+ jl LookaheadLess
-+ movl %eax, %ebx
-+LookaheadLess: movl %ebx, nicematch(%esp)
-+
-+/* register Bytef *scan = s->window + s->strstart; */
-+
-+ movl dsWindow(%edx), %esi
-+ movl %esi, window(%esp)
-+ movl dsStrStart(%edx), %ebp
-+ lea (%esi,%ebp), %edi
-+ movl %edi, scan(%esp)
-+
-+/* Determine how many bytes the scan ptr is off from being */
-+/* dword-aligned. */
-+
-+ movl %edi, %eax
-+ negl %eax
-+ andl $3, %eax
-+ movl %eax, scanalign(%esp)
-+
-+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
-+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
-+
-+ movl dsWSize(%edx), %eax
-+ subl $MIN_LOOKAHEAD, %eax
-+ subl %eax, %ebp
-+ jg LimitPositive
-+ xorl %ebp, %ebp
-+LimitPositive:
-+
-+/* unsigned chain_length = s->max_chain_length; */
-+/* if (s->prev_length >= s->good_match) { */
-+/* chain_length >>= 2; */
-+/* } */
-+
-+ movl dsPrevLen(%edx), %eax
-+ movl dsGoodMatch(%edx), %ebx
-+ cmpl %ebx, %eax
-+ movl dsMaxChainLen(%edx), %ebx
-+ jl LastMatchGood
-+ shrl $2, %ebx
-+LastMatchGood:
-+
-+/* chainlen is decremented once beforehand so that the function can */
-+/* use the sign flag instead of the zero flag for the exit test. */
-+/* It is then shifted into the high word, to make room for the scanend */
-+/* scanend value, which it will always accompany. */
-+
-+ decl %ebx
-+ shll $16, %ebx
-+
-+/* int best_len = s->prev_length; */
-+
-+ movl dsPrevLen(%edx), %eax
-+ movl %eax, bestlen(%esp)
-+
-+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
-+
-+ addl %eax, %esi
-+ movl %esi, windowbestlen(%esp)
-+
-+/* register ush scan_start = *(ushf*)scan; */
-+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
-+
-+ movw (%edi), %bx
-+ movw %bx, scanstart(%esp)
-+ movw -1(%edi,%eax), %bx
-+ movl %ebx, chainlenscanend(%esp)
-+
-+/* Posf *prev = s->prev; */
-+/* uInt wmask = s->w_mask; */
-+
-+ movl dsPrev(%edx), %edi
-+ movl dsWMask(%edx), %edx
-+ mov %edx, wmask(%esp)
-+
-+/* Jump into the main loop. */
-+
-+ jmp LoopEntry
-+
-+.balign 16
-+
-+/* do {
-+ * match = s->window + cur_match;
-+ * if (*(ushf*)(match+best_len-1) != scan_end ||
-+ * *(ushf*)match != scan_start) continue;
-+ * [...]
-+ * } while ((cur_match = prev[cur_match & wmask]) > limit
-+ * && --chain_length != 0);
-+ *
-+ * Here is the inner loop of the function. The function will spend the
-+ * majority of its time in this loop, and majority of that time will
-+ * be spent in the first ten instructions.
-+ *
-+ * Within this loop:
-+ * %ebx = chainlenscanend - i.e., ((chainlen << 16) | scanend)
-+ * %ecx = curmatch
-+ * %edx = curmatch & wmask
-+ * %esi = windowbestlen - i.e., (window + bestlen)
-+ * %edi = prev
-+ * %ebp = limit
-+ *
-+ * Two optimization notes on the choice of instructions:
-+ *
-+ * The first instruction uses a 16-bit address, which costs an extra,
-+ * unpairable cycle. This is cheaper than doing a 32-bit access and
-+ * zeroing the high word, due to the 3-cycle misalignment penalty which
-+ * would occur half the time. This also turns out to be cheaper than
-+ * doing two separate 8-bit accesses, as the memory is so rarely in the
-+ * L1 cache.
-+ *
-+ * The window buffer, however, apparently spends a lot of time in the
-+ * cache, and so it is faster to retrieve the word at the end of the
-+ * match string with two 8-bit loads. The instructions that test the
-+ * word at the beginning of the match string, however, are executed
-+ * much less frequently, and there it was cheaper to use 16-bit
-+ * instructions, which avoided the necessity of saving off and
-+ * subsequently reloading one of the other registers.
-+ */
-+LookupLoop:
-+ /* 1 U & V */
-+ movw (%edi,%edx,2), %cx /* 2 U pipe */
-+ movl wmask(%esp), %edx /* 2 V pipe */
-+ cmpl %ebp, %ecx /* 3 U pipe */
-+ jbe LeaveNow /* 3 V pipe */
-+ subl $0x00010000, %ebx /* 4 U pipe */
-+ js LeaveNow /* 4 V pipe */
-+LoopEntry: movb -1(%esi,%ecx), %al /* 5 U pipe */
-+ andl %ecx, %edx /* 5 V pipe */
-+ cmpb %bl, %al /* 6 U pipe */
-+ jnz LookupLoop /* 6 V pipe */
-+ movb (%esi,%ecx), %ah
-+ cmpb %bh, %ah
-+ jnz LookupLoop
-+ movl window(%esp), %eax
-+ movw (%eax,%ecx), %ax
-+ cmpw scanstart(%esp), %ax
-+ jnz LookupLoop
-+
-+/* Store the current value of chainlen. */
-+
-+ movl %ebx, chainlenscanend(%esp)
-+
-+/* Point %edi to the string under scrutiny, and %esi to the string we */
-+/* are hoping to match it up with. In actuality, %esi and %edi are */
-+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
-+/* initialized to -(MAX_MATCH_8 - scanalign). */
-+
-+ movl window(%esp), %esi
-+ movl scan(%esp), %edi
-+ addl %ecx, %esi
-+ movl scanalign(%esp), %eax
-+ movl $(-MAX_MATCH_8), %edx
-+ lea MAX_MATCH_8(%edi,%eax), %edi
-+ lea MAX_MATCH_8(%esi,%eax), %esi
-+
-+/* Test the strings for equality, 8 bytes at a time. At the end,
-+ * adjust %edx so that it is offset to the exact byte that mismatched.
-+ *
-+ * We already know at this point that the first three bytes of the
-+ * strings match each other, and they can be safely passed over before
-+ * starting the compare loop. So what this code does is skip over 0-3
-+ * bytes, as much as necessary in order to dword-align the %edi
-+ * pointer. (%esi will still be misaligned three times out of four.)
-+ *
-+ * It should be confessed that this loop usually does not represent
-+ * much of the total running time. Replacing it with a more
-+ * straightforward "rep cmpsb" would not drastically degrade
-+ * performance.
-+ */
-+LoopCmps:
-+ movl (%esi,%edx), %eax
-+ movl (%edi,%edx), %ebx
-+ xorl %ebx, %eax
-+ jnz LeaveLoopCmps
-+ movl 4(%esi,%edx), %eax
-+ movl 4(%edi,%edx), %ebx
-+ xorl %ebx, %eax
-+ jnz LeaveLoopCmps4
-+ addl $8, %edx
-+ jnz LoopCmps
-+ jmp LenMaximum
-+LeaveLoopCmps4: addl $4, %edx
-+LeaveLoopCmps: testl $0x0000FFFF, %eax
-+ jnz LenLower
-+ addl $2, %edx
-+ shrl $16, %eax
-+LenLower: subb $1, %al
-+ adcl $0, %edx
-+
-+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
-+/* then automatically accept it as the best possible match and leave. */
-+
-+ lea (%edi,%edx), %eax
-+ movl scan(%esp), %edi
-+ subl %edi, %eax
-+ cmpl $MAX_MATCH, %eax
-+ jge LenMaximum
-+
-+/* If the length of the match is not longer than the best match we */
-+/* have so far, then forget it and return to the lookup loop. */
-+
-+ movl deflatestate(%esp), %edx
-+ movl bestlen(%esp), %ebx
-+ cmpl %ebx, %eax
-+ jg LongerMatch
-+ movl chainlenscanend(%esp), %ebx
-+ movl windowbestlen(%esp), %esi
-+ movl dsPrev(%edx), %edi
-+ movl wmask(%esp), %edx
-+ andl %ecx, %edx
-+ jmp LookupLoop
-+
-+/* s->match_start = cur_match; */
-+/* best_len = len; */
-+/* if (len >= nice_match) break; */
-+/* scan_end = *(ushf*)(scan+best_len-1); */
-+
-+LongerMatch: movl nicematch(%esp), %ebx
-+ movl %eax, bestlen(%esp)
-+ movl %ecx, dsMatchStart(%edx)
-+ cmpl %ebx, %eax
-+ jge LeaveNow
-+ movl window(%esp), %esi
-+ addl %eax, %esi
-+ movl %esi, windowbestlen(%esp)
-+ movl chainlenscanend(%esp), %ebx
-+ movw -1(%edi,%eax), %bx
-+ movl dsPrev(%edx), %edi
-+ movl %ebx, chainlenscanend(%esp)
-+ movl wmask(%esp), %edx
-+ andl %ecx, %edx
-+ jmp LookupLoop
-+
-+/* Accept the current string, with the maximum possible length. */
-+
-+LenMaximum: movl deflatestate(%esp), %edx
-+ movl $MAX_MATCH, bestlen(%esp)
-+ movl %ecx, dsMatchStart(%edx)
-+
-+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
-+/* return s->lookahead; */
-+
-+LeaveNow:
-+ movl deflatestate(%esp), %edx
-+ movl bestlen(%esp), %ebx
-+ movl dsLookahead(%edx), %eax
-+ cmpl %eax, %ebx
-+ jg LookaheadRet
-+ movl %ebx, %eax
-+LookaheadRet:
-+
-+/* Restore the stack and return from whence we came. */
-+
-+ addl $LocalVarsSize, %esp
-+ popl %ebx
-+ popl %esi
-+ popl %edi
-+ popl %ebp
-+match_init: ret
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/match686.S Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,330 @@
-+/* match.s -- Pentium-Pro-optimized version of longest_match()
-+ * Written for zlib 1.1.2
-+ * Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
-+ *
-+ * This is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License.
-+ */
-+
-+#ifndef NO_UNDERLINE
-+#define match_init _ipcomp_match_init
-+#define longest_match _ipcomp_longest_match
-+#else
-+#define match_init ipcomp_match_init
-+#define longest_match ipcomp_longest_match
-+#endif
-+
-+#define MAX_MATCH (258)
-+#define MIN_MATCH (3)
-+#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1)
-+#define MAX_MATCH_8 ((MAX_MATCH + 7) & ~7)
-+
-+/* stack frame offsets */
-+
-+#define chainlenwmask 0 /* high word: current chain len */
-+ /* low word: s->wmask */
-+#define window 4 /* local copy of s->window */
-+#define windowbestlen 8 /* s->window + bestlen */
-+#define scanstart 16 /* first two bytes of string */
-+#define scanend 12 /* last two bytes of string */
-+#define scanalign 20 /* dword-misalignment of string */
-+#define nicematch 24 /* a good enough match size */
-+#define bestlen 28 /* size of best match so far */
-+#define scan 32 /* ptr to string wanting match */
-+
-+#define LocalVarsSize (36)
-+/* saved ebx 36 */
-+/* saved edi 40 */
-+/* saved esi 44 */
-+/* saved ebp 48 */
-+/* return address 52 */
-+#define deflatestate 56 /* the function arguments */
-+#define curmatch 60
-+
-+/* Offsets for fields in the deflate_state structure. These numbers
-+ * are calculated from the definition of deflate_state, with the
-+ * assumption that the compiler will dword-align the fields. (Thus,
-+ * changing the definition of deflate_state could easily cause this
-+ * program to crash horribly, without so much as a warning at
-+ * compile time. Sigh.)
-+ */
-+#define dsWSize 36
-+#define dsWMask 44
-+#define dsWindow 48
-+#define dsPrev 56
-+#define dsMatchLen 88
-+#define dsPrevMatch 92
-+#define dsStrStart 100
-+#define dsMatchStart 104
-+#define dsLookahead 108
-+#define dsPrevLen 112
-+#define dsMaxChainLen 116
-+#define dsGoodMatch 132
-+#define dsNiceMatch 136
-+
-+
-+.file "match.S"
-+
-+.globl match_init, longest_match
-+
-+.text
-+
-+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
-+
-+longest_match:
-+
-+/* Save registers that the compiler may be using, and adjust %esp to */
-+/* make room for our stack frame. */
-+
-+ pushl %ebp
-+ pushl %edi
-+ pushl %esi
-+ pushl %ebx
-+ subl $LocalVarsSize, %esp
-+
-+/* Retrieve the function arguments. %ecx will hold cur_match */
-+/* throughout the entire function. %edx will hold the pointer to the */
-+/* deflate_state structure during the function's setup (before */
-+/* entering the main loop). */
-+
-+ movl deflatestate(%esp), %edx
-+ movl curmatch(%esp), %ecx
-+
-+/* uInt wmask = s->w_mask; */
-+/* unsigned chain_length = s->max_chain_length; */
-+/* if (s->prev_length >= s->good_match) { */
-+/* chain_length >>= 2; */
-+/* } */
-+
-+ movl dsPrevLen(%edx), %eax
-+ movl dsGoodMatch(%edx), %ebx
-+ cmpl %ebx, %eax
-+ movl dsWMask(%edx), %eax
-+ movl dsMaxChainLen(%edx), %ebx
-+ jl LastMatchGood
-+ shrl $2, %ebx
-+LastMatchGood:
-+
-+/* chainlen is decremented once beforehand so that the function can */
-+/* use the sign flag instead of the zero flag for the exit test. */
-+/* It is then shifted into the high word, to make room for the wmask */
-+/* value, which it will always accompany. */
-+
-+ decl %ebx
-+ shll $16, %ebx
-+ orl %eax, %ebx
-+ movl %ebx, chainlenwmask(%esp)
-+
-+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; */
-+
-+ movl dsNiceMatch(%edx), %eax
-+ movl dsLookahead(%edx), %ebx
-+ cmpl %eax, %ebx
-+ jl LookaheadLess
-+ movl %eax, %ebx
-+LookaheadLess: movl %ebx, nicematch(%esp)
-+
-+/* register Bytef *scan = s->window + s->strstart; */
-+
-+ movl dsWindow(%edx), %esi
-+ movl %esi, window(%esp)
-+ movl dsStrStart(%edx), %ebp
-+ lea (%esi,%ebp), %edi
-+ movl %edi, scan(%esp)
-+
-+/* Determine how many bytes the scan ptr is off from being */
-+/* dword-aligned. */
-+
-+ movl %edi, %eax
-+ negl %eax
-+ andl $3, %eax
-+ movl %eax, scanalign(%esp)
-+
-+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ? */
-+/* s->strstart - (IPos)MAX_DIST(s) : NIL; */
-+
-+ movl dsWSize(%edx), %eax
-+ subl $MIN_LOOKAHEAD, %eax
-+ subl %eax, %ebp
-+ jg LimitPositive
-+ xorl %ebp, %ebp
-+LimitPositive:
-+
-+/* int best_len = s->prev_length; */
-+
-+ movl dsPrevLen(%edx), %eax
-+ movl %eax, bestlen(%esp)
-+
-+/* Store the sum of s->window + best_len in %esi locally, and in %esi. */
-+
-+ addl %eax, %esi
-+ movl %esi, windowbestlen(%esp)
-+
-+/* register ush scan_start = *(ushf*)scan; */
-+/* register ush scan_end = *(ushf*)(scan+best_len-1); */
-+/* Posf *prev = s->prev; */
-+
-+ movzwl (%edi), %ebx
-+ movl %ebx, scanstart(%esp)
-+ movzwl -1(%edi,%eax), %ebx
-+ movl %ebx, scanend(%esp)
-+ movl dsPrev(%edx), %edi
-+
-+/* Jump into the main loop. */
-+
-+ movl chainlenwmask(%esp), %edx
-+ jmp LoopEntry
-+
-+.balign 16
-+
-+/* do {
-+ * match = s->window + cur_match;
-+ * if (*(ushf*)(match+best_len-1) != scan_end ||
-+ * *(ushf*)match != scan_start) continue;
-+ * [...]
-+ * } while ((cur_match = prev[cur_match & wmask]) > limit
-+ * && --chain_length != 0);
-+ *
-+ * Here is the inner loop of the function. The function will spend the
-+ * majority of its time in this loop, and majority of that time will
-+ * be spent in the first ten instructions.
-+ *
-+ * Within this loop:
-+ * %ebx = scanend
-+ * %ecx = curmatch
-+ * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
-+ * %esi = windowbestlen - i.e., (window + bestlen)
-+ * %edi = prev
-+ * %ebp = limit
-+ */
-+LookupLoop:
-+ andl %edx, %ecx
-+ movzwl (%edi,%ecx,2), %ecx
-+ cmpl %ebp, %ecx
-+ jbe LeaveNow
-+ subl $0x00010000, %edx
-+ js LeaveNow
-+LoopEntry: movzwl -1(%esi,%ecx), %eax
-+ cmpl %ebx, %eax
-+ jnz LookupLoop
-+ movl window(%esp), %eax
-+ movzwl (%eax,%ecx), %eax
-+ cmpl scanstart(%esp), %eax
-+ jnz LookupLoop
-+
-+/* Store the current value of chainlen. */
-+
-+ movl %edx, chainlenwmask(%esp)
-+
-+/* Point %edi to the string under scrutiny, and %esi to the string we */
-+/* are hoping to match it up with. In actuality, %esi and %edi are */
-+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is */
-+/* initialized to -(MAX_MATCH_8 - scanalign). */
-+
-+ movl window(%esp), %esi
-+ movl scan(%esp), %edi
-+ addl %ecx, %esi
-+ movl scanalign(%esp), %eax
-+ movl $(-MAX_MATCH_8), %edx
-+ lea MAX_MATCH_8(%edi,%eax), %edi
-+ lea MAX_MATCH_8(%esi,%eax), %esi
-+
-+/* Test the strings for equality, 8 bytes at a time. At the end,
-+ * adjust %edx so that it is offset to the exact byte that mismatched.
-+ *
-+ * We already know at this point that the first three bytes of the
-+ * strings match each other, and they can be safely passed over before
-+ * starting the compare loop. So what this code does is skip over 0-3
-+ * bytes, as much as necessary in order to dword-align the %edi
-+ * pointer. (%esi will still be misaligned three times out of four.)
-+ *
-+ * It should be confessed that this loop usually does not represent
-+ * much of the total running time. Replacing it with a more
-+ * straightforward "rep cmpsb" would not drastically degrade
-+ * performance.
-+ */
-+LoopCmps:
-+ movl (%esi,%edx), %eax
-+ xorl (%edi,%edx), %eax
-+ jnz LeaveLoopCmps
-+ movl 4(%esi,%edx), %eax
-+ xorl 4(%edi,%edx), %eax
-+ jnz LeaveLoopCmps4
-+ addl $8, %edx
-+ jnz LoopCmps
-+ jmp LenMaximum
-+LeaveLoopCmps4: addl $4, %edx
-+LeaveLoopCmps: testl $0x0000FFFF, %eax
-+ jnz LenLower
-+ addl $2, %edx
-+ shrl $16, %eax
-+LenLower: subb $1, %al
-+ adcl $0, %edx
-+
-+/* Calculate the length of the match. If it is longer than MAX_MATCH, */
-+/* then automatically accept it as the best possible match and leave. */
-+
-+ lea (%edi,%edx), %eax
-+ movl scan(%esp), %edi
-+ subl %edi, %eax
-+ cmpl $MAX_MATCH, %eax
-+ jge LenMaximum
-+
-+/* If the length of the match is not longer than the best match we */
-+/* have so far, then forget it and return to the lookup loop. */
-+
-+ movl deflatestate(%esp), %edx
-+ movl bestlen(%esp), %ebx
-+ cmpl %ebx, %eax
-+ jg LongerMatch
-+ movl windowbestlen(%esp), %esi
-+ movl dsPrev(%edx), %edi
-+ movl scanend(%esp), %ebx
-+ movl chainlenwmask(%esp), %edx
-+ jmp LookupLoop
-+
-+/* s->match_start = cur_match; */
-+/* best_len = len; */
-+/* if (len >= nice_match) break; */
-+/* scan_end = *(ushf*)(scan+best_len-1); */
-+
-+LongerMatch: movl nicematch(%esp), %ebx
-+ movl %eax, bestlen(%esp)
-+ movl %ecx, dsMatchStart(%edx)
-+ cmpl %ebx, %eax
-+ jge LeaveNow
-+ movl window(%esp), %esi
-+ addl %eax, %esi
-+ movl %esi, windowbestlen(%esp)
-+ movzwl -1(%edi,%eax), %ebx
-+ movl dsPrev(%edx), %edi
-+ movl %ebx, scanend(%esp)
-+ movl chainlenwmask(%esp), %edx
-+ jmp LookupLoop
-+
-+/* Accept the current string, with the maximum possible length. */
-+
-+LenMaximum: movl deflatestate(%esp), %edx
-+ movl $MAX_MATCH, bestlen(%esp)
-+ movl %ecx, dsMatchStart(%edx)
-+
-+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len; */
-+/* return s->lookahead; */
-+
-+LeaveNow:
-+ movl deflatestate(%esp), %edx
-+ movl bestlen(%esp), %ebx
-+ movl dsLookahead(%edx), %eax
-+ cmpl %eax, %ebx
-+ jg LookaheadRet
-+ movl %ebx, %eax
-+LookaheadRet:
-+
-+/* Restore the stack and return from whence we came. */
-+
-+ addl $LocalVarsSize, %esp
-+ popl %ebx
-+ popl %esi
-+ popl %edi
-+ popl %ebp
-+match_init: ret
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/trees.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1214 @@
-+/* trees.c -- output deflated data using Huffman coding
-+ * Copyright (C) 1995-2002 Jean-loup Gailly
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/*
-+ * ALGORITHM
-+ *
-+ * The "deflation" process uses several Huffman trees. The more
-+ * common source values are represented by shorter bit sequences.
-+ *
-+ * Each code tree is stored in a compressed form which is itself
-+ * a Huffman encoding of the lengths of all the code strings (in
-+ * ascending order by source values). The actual code strings are
-+ * reconstructed from the lengths in the inflate process, as described
-+ * in the deflate specification.
-+ *
-+ * REFERENCES
-+ *
-+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
-+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
-+ *
-+ * Storer, James A.
-+ * Data Compression: Methods and Theory, pp. 49-50.
-+ * Computer Science Press, 1988. ISBN 0-7167-8156-5.
-+ *
-+ * Sedgewick, R.
-+ * Algorithms, p290.
-+ * Addison-Wesley, 1983. ISBN 0-201-06672-6.
-+ */
-+
-+/* @(#) $Id$ */
-+
-+/* #define GEN_TREES_H */
-+
-+#include "deflate.h"
-+
-+#ifdef DEBUG
-+# include <ctype.h>
-+#endif
-+
-+/* ===========================================================================
-+ * Constants
-+ */
-+
-+#define MAX_BL_BITS 7
-+/* Bit length codes must not exceed MAX_BL_BITS bits */
-+
-+#define END_BLOCK 256
-+/* end of block literal code */
-+
-+#define REP_3_6 16
-+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
-+
-+#define REPZ_3_10 17
-+/* repeat a zero length 3-10 times (3 bits of repeat count) */
-+
-+#define REPZ_11_138 18
-+/* repeat a zero length 11-138 times (7 bits of repeat count) */
-+
-+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
-+ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
-+
-+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
-+ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
-+
-+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
-+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
-+
-+local const uch bl_order[BL_CODES]
-+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
-+/* The lengths of the bit length codes are sent in order of decreasing
-+ * probability, to avoid transmitting the lengths for unused bit length codes.
-+ */
-+
-+#define Buf_size (8 * 2*sizeof(char))
-+/* Number of bits used within bi_buf. (bi_buf might be implemented on
-+ * more than 16 bits on some systems.)
-+ */
-+
-+/* ===========================================================================
-+ * Local data. These are initialized only once.
-+ */
-+
-+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
-+
-+#if defined(GEN_TREES_H) || !defined(STDC)
-+/* non ANSI compilers may not accept trees.h */
-+
-+local ct_data static_ltree[L_CODES+2];
-+/* The static literal tree. Since the bit lengths are imposed, there is no
-+ * need for the L_CODES extra codes used during heap construction. However
-+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
-+ * below).
-+ */
-+
-+local ct_data static_dtree[D_CODES];
-+/* The static distance tree. (Actually a trivial tree since all codes use
-+ * 5 bits.)
-+ */
-+
-+uch _dist_code[DIST_CODE_LEN];
-+/* Distance codes. The first 256 values correspond to the distances
-+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
-+ * the 15 bit distances.
-+ */
-+
-+uch _length_code[MAX_MATCH-MIN_MATCH+1];
-+/* length code for each normalized match length (0 == MIN_MATCH) */
-+
-+local int base_length[LENGTH_CODES];
-+/* First normalized length for each code (0 = MIN_MATCH) */
-+
-+local int base_dist[D_CODES];
-+/* First normalized distance for each code (0 = distance of 1) */
-+
-+#else
-+# include "trees.h"
-+#endif /* GEN_TREES_H */
-+
-+struct static_tree_desc_s {
-+ const ct_data *static_tree; /* static tree or NULL */
-+ const intf *extra_bits; /* extra bits for each code or NULL */
-+ int extra_base; /* base index for extra_bits */
-+ int elems; /* max number of elements in the tree */
-+ int max_length; /* max bit length for the codes */
-+};
-+
-+local static_tree_desc static_l_desc =
-+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
-+
-+local static_tree_desc static_d_desc =
-+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
-+
-+local static_tree_desc static_bl_desc =
-+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
-+
-+/* ===========================================================================
-+ * Local (static) routines in this file.
-+ */
-+
-+local void tr_static_init OF((void));
-+local void init_block OF((deflate_state *s));
-+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
-+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
-+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
-+local void build_tree OF((deflate_state *s, tree_desc *desc));
-+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
-+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
-+local int build_bl_tree OF((deflate_state *s));
-+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
-+ int blcodes));
-+local void compress_block OF((deflate_state *s, const ct_data *ltree,
-+ const ct_data *dtree));
-+local void set_data_type OF((deflate_state *s));
-+local unsigned bi_reverse OF((unsigned value, int length));
-+local void bi_windup OF((deflate_state *s));
-+local void bi_flush OF((deflate_state *s));
-+local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
-+ int header));
-+
-+#ifdef GEN_TREES_H
-+local void gen_trees_header OF((void));
-+#endif
-+
-+#ifndef DEBUG
-+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
-+ /* Send a code of the given tree. c and tree must not have side effects */
-+
-+#else /* DEBUG */
-+# define send_code(s, c, tree) \
-+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
-+ send_bits(s, tree[c].Code, tree[c].Len); }
-+#endif
-+
-+/* ===========================================================================
-+ * Output a short LSB first on the stream.
-+ * IN assertion: there is enough room in pendingBuf.
-+ */
-+#define put_short(s, w) { \
-+ put_byte(s, (uch)((w) & 0xff)); \
-+ put_byte(s, (uch)((ush)(w) >> 8)); \
-+}
-+
-+/* ===========================================================================
-+ * Send a value on a given number of bits.
-+ * IN assertion: length <= 16 and value fits in length bits.
-+ */
-+#ifdef DEBUG
-+local void send_bits OF((deflate_state *s, int value, int length));
-+
-+local void send_bits(s, value, length)
-+ deflate_state *s;
-+ int value; /* value to send */
-+ int length; /* number of bits */
-+{
-+ Tracevv((stderr," l %2d v %4x ", length, value));
-+ Assert(length > 0 && length <= 15, "invalid length");
-+ s->bits_sent += (ulg)length;
-+
-+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and
-+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
-+ * unused bits in value.
-+ */
-+ if (s->bi_valid > (int)Buf_size - length) {
-+ s->bi_buf |= (value << s->bi_valid);
-+ put_short(s, s->bi_buf);
-+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
-+ s->bi_valid += length - Buf_size;
-+ } else {
-+ s->bi_buf |= value << s->bi_valid;
-+ s->bi_valid += length;
-+ }
-+}
-+#else /* !DEBUG */
-+
-+#define send_bits(s, value, length) \
-+{ int len = length;\
-+ if (s->bi_valid > (int)Buf_size - len) {\
-+ int val = value;\
-+ s->bi_buf |= (val << s->bi_valid);\
-+ put_short(s, s->bi_buf);\
-+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
-+ s->bi_valid += len - Buf_size;\
-+ } else {\
-+ s->bi_buf |= (value) << s->bi_valid;\
-+ s->bi_valid += len;\
-+ }\
-+}
-+#endif /* DEBUG */
-+
-+
-+#define MAX(a,b) (a >= b ? a : b)
-+/* the arguments must not have side effects */
-+
-+/* ===========================================================================
-+ * Initialize the various 'constant' tables.
-+ */
-+local void tr_static_init()
-+{
-+#if defined(GEN_TREES_H) || !defined(STDC)
-+ static int static_init_done = 0;
-+ int n; /* iterates over tree elements */
-+ int bits; /* bit counter */
-+ int length; /* length value */
-+ int code; /* code value */
-+ int dist; /* distance index */
-+ ush bl_count[MAX_BITS+1];
-+ /* number of codes at each bit length for an optimal tree */
-+
-+ if (static_init_done) return;
-+
-+ /* For some embedded targets, global variables are not initialized: */
-+ static_l_desc.static_tree = static_ltree;
-+ static_l_desc.extra_bits = extra_lbits;
-+ static_d_desc.static_tree = static_dtree;
-+ static_d_desc.extra_bits = extra_dbits;
-+ static_bl_desc.extra_bits = extra_blbits;
-+
-+ /* Initialize the mapping length (0..255) -> length code (0..28) */
-+ length = 0;
-+ for (code = 0; code < LENGTH_CODES-1; code++) {
-+ base_length[code] = length;
-+ for (n = 0; n < (1<<extra_lbits[code]); n++) {
-+ _length_code[length++] = (uch)code;
-+ }
-+ }
-+ Assert (length == 256, "tr_static_init: length != 256");
-+ /* Note that the length 255 (match length 258) can be represented
-+ * in two different ways: code 284 + 5 bits or code 285, so we
-+ * overwrite length_code[255] to use the best encoding:
-+ */
-+ _length_code[length-1] = (uch)code;
-+
-+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
-+ dist = 0;
-+ for (code = 0 ; code < 16; code++) {
-+ base_dist[code] = dist;
-+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
-+ _dist_code[dist++] = (uch)code;
-+ }
-+ }
-+ Assert (dist == 256, "tr_static_init: dist != 256");
-+ dist >>= 7; /* from now on, all distances are divided by 128 */
-+ for ( ; code < D_CODES; code++) {
-+ base_dist[code] = dist << 7;
-+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
-+ _dist_code[256 + dist++] = (uch)code;
-+ }
-+ }
-+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
-+
-+ /* Construct the codes of the static literal tree */
-+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
-+ n = 0;
-+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
-+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
-+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
-+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
-+ /* Codes 286 and 287 do not exist, but we must include them in the
-+ * tree construction to get a canonical Huffman tree (longest code
-+ * all ones)
-+ */
-+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
-+
-+ /* The static distance tree is trivial: */
-+ for (n = 0; n < D_CODES; n++) {
-+ static_dtree[n].Len = 5;
-+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
-+ }
-+ static_init_done = 1;
-+
-+# ifdef GEN_TREES_H
-+ gen_trees_header();
-+# endif
-+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
-+}
-+
-+/* ===========================================================================
-+ * Genererate the file trees.h describing the static trees.
-+ */
-+#ifdef GEN_TREES_H
-+# ifndef DEBUG
-+# include <stdio.h>
-+# endif
-+
-+# define SEPARATOR(i, last, width) \
-+ ((i) == (last)? "\n};\n\n" : \
-+ ((i) % (width) == (width)-1 ? ",\n" : ", "))
-+
-+void gen_trees_header()
-+{
-+ FILE *header = fopen("trees.h", "w");
-+ int i;
-+
-+ Assert (header != NULL, "Can't open trees.h");
-+ fprintf(header,
-+ "/* header created automatically with -DGEN_TREES_H */\n\n");
-+
-+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
-+ for (i = 0; i < L_CODES+2; i++) {
-+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
-+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
-+ }
-+
-+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
-+ for (i = 0; i < D_CODES; i++) {
-+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
-+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
-+ }
-+
-+ fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
-+ for (i = 0; i < DIST_CODE_LEN; i++) {
-+ fprintf(header, "%2u%s", _dist_code[i],
-+ SEPARATOR(i, DIST_CODE_LEN-1, 20));
-+ }
-+
-+ fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
-+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
-+ fprintf(header, "%2u%s", _length_code[i],
-+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
-+ }
-+
-+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
-+ for (i = 0; i < LENGTH_CODES; i++) {
-+ fprintf(header, "%1u%s", base_length[i],
-+ SEPARATOR(i, LENGTH_CODES-1, 20));
-+ }
-+
-+ fprintf(header, "local const int base_dist[D_CODES] = {\n");
-+ for (i = 0; i < D_CODES; i++) {
-+ fprintf(header, "%5u%s", base_dist[i],
-+ SEPARATOR(i, D_CODES-1, 10));
-+ }
-+
-+ fclose(header);
-+}
-+#endif /* GEN_TREES_H */
-+
-+/* ===========================================================================
-+ * Initialize the tree data structures for a new zlib stream.
-+ */
-+void _tr_init(s)
-+ deflate_state *s;
-+{
-+ tr_static_init();
-+
-+ s->l_desc.dyn_tree = s->dyn_ltree;
-+ s->l_desc.stat_desc = &static_l_desc;
-+
-+ s->d_desc.dyn_tree = s->dyn_dtree;
-+ s->d_desc.stat_desc = &static_d_desc;
-+
-+ s->bl_desc.dyn_tree = s->bl_tree;
-+ s->bl_desc.stat_desc = &static_bl_desc;
-+
-+ s->bi_buf = 0;
-+ s->bi_valid = 0;
-+ s->last_eob_len = 8; /* enough lookahead for inflate */
-+#ifdef DEBUG
-+ s->compressed_len = 0L;
-+ s->bits_sent = 0L;
-+#endif
-+
-+ /* Initialize the first block of the first file: */
-+ init_block(s);
-+}
-+
-+/* ===========================================================================
-+ * Initialize a new block.
-+ */
-+local void init_block(s)
-+ deflate_state *s;
-+{
-+ int n; /* iterates over tree elements */
-+
-+ /* Initialize the trees. */
-+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
-+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
-+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
-+
-+ s->dyn_ltree[END_BLOCK].Freq = 1;
-+ s->opt_len = s->static_len = 0L;
-+ s->last_lit = s->matches = 0;
-+}
-+
-+#define SMALLEST 1
-+/* Index within the heap array of least frequent node in the Huffman tree */
-+
-+
-+/* ===========================================================================
-+ * Remove the smallest element from the heap and recreate the heap with
-+ * one less element. Updates heap and heap_len.
-+ */
-+#define pqremove(s, tree, top) \
-+{\
-+ top = s->heap[SMALLEST]; \
-+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
-+ pqdownheap(s, tree, SMALLEST); \
-+}
-+
-+/* ===========================================================================
-+ * Compares to subtrees, using the tree depth as tie breaker when
-+ * the subtrees have equal frequency. This minimizes the worst case length.
-+ */
-+#define smaller(tree, n, m, depth) \
-+ (tree[n].Freq < tree[m].Freq || \
-+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
-+
-+/* ===========================================================================
-+ * Restore the heap property by moving down the tree starting at node k,
-+ * exchanging a node with the smallest of its two sons if necessary, stopping
-+ * when the heap property is re-established (each father smaller than its
-+ * two sons).
-+ */
-+local void pqdownheap(s, tree, k)
-+ deflate_state *s;
-+ ct_data *tree; /* the tree to restore */
-+ int k; /* node to move down */
-+{
-+ int v = s->heap[k];
-+ int j = k << 1; /* left son of k */
-+ while (j <= s->heap_len) {
-+ /* Set j to the smallest of the two sons: */
-+ if (j < s->heap_len &&
-+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
-+ j++;
-+ }
-+ /* Exit if v is smaller than both sons */
-+ if (smaller(tree, v, s->heap[j], s->depth)) break;
-+
-+ /* Exchange v with the smallest son */
-+ s->heap[k] = s->heap[j]; k = j;
-+
-+ /* And continue down the tree, setting j to the left son of k */
-+ j <<= 1;
-+ }
-+ s->heap[k] = v;
-+}
-+
-+/* ===========================================================================
-+ * Compute the optimal bit lengths for a tree and update the total bit length
-+ * for the current block.
-+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
-+ * above are the tree nodes sorted by increasing frequency.
-+ * OUT assertions: the field len is set to the optimal bit length, the
-+ * array bl_count contains the frequencies for each bit length.
-+ * The length opt_len is updated; static_len is also updated if stree is
-+ * not null.
-+ */
-+local void gen_bitlen(s, desc)
-+ deflate_state *s;
-+ tree_desc *desc; /* the tree descriptor */
-+{
-+ ct_data *tree = desc->dyn_tree;
-+ int max_code = desc->max_code;
-+ const ct_data *stree = desc->stat_desc->static_tree;
-+ const intf *extra = desc->stat_desc->extra_bits;
-+ int base = desc->stat_desc->extra_base;
-+ int max_length = desc->stat_desc->max_length;
-+ int h; /* heap index */
-+ int n, m; /* iterate over the tree elements */
-+ int bits; /* bit length */
-+ int xbits; /* extra bits */
-+ ush f; /* frequency */
-+ int overflow = 0; /* number of elements with bit length too large */
-+
-+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
-+
-+ /* In a first pass, compute the optimal bit lengths (which may
-+ * overflow in the case of the bit length tree).
-+ */
-+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
-+
-+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
-+ n = s->heap[h];
-+ bits = tree[tree[n].Dad].Len + 1;
-+ if (bits > max_length) bits = max_length, overflow++;
-+ tree[n].Len = (ush)bits;
-+ /* We overwrite tree[n].Dad which is no longer needed */
-+
-+ if (n > max_code) continue; /* not a leaf node */
-+
-+ s->bl_count[bits]++;
-+ xbits = 0;
-+ if (n >= base) xbits = extra[n-base];
-+ f = tree[n].Freq;
-+ s->opt_len += (ulg)f * (bits + xbits);
-+ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
-+ }
-+ if (overflow == 0) return;
-+
-+ Trace((stderr,"\nbit length overflow\n"));
-+ /* This happens for example on obj2 and pic of the Calgary corpus */
-+
-+ /* Find the first bit length which could increase: */
-+ do {
-+ bits = max_length-1;
-+ while (s->bl_count[bits] == 0) bits--;
-+ s->bl_count[bits]--; /* move one leaf down the tree */
-+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
-+ s->bl_count[max_length]--;
-+ /* The brother of the overflow item also moves one step up,
-+ * but this does not affect bl_count[max_length]
-+ */
-+ overflow -= 2;
-+ } while (overflow > 0);
-+
-+ /* Now recompute all bit lengths, scanning in increasing frequency.
-+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
-+ * lengths instead of fixing only the wrong ones. This idea is taken
-+ * from 'ar' written by Haruhiko Okumura.)
-+ */
-+ for (bits = max_length; bits != 0; bits--) {
-+ n = s->bl_count[bits];
-+ while (n != 0) {
-+ m = s->heap[--h];
-+ if (m > max_code) continue;
-+ if (tree[m].Len != (unsigned) bits) {
-+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
-+ s->opt_len += ((long)bits - (long)tree[m].Len)
-+ *(long)tree[m].Freq;
-+ tree[m].Len = (ush)bits;
-+ }
-+ n--;
-+ }
-+ }
-+}
-+
-+/* ===========================================================================
-+ * Generate the codes for a given tree and bit counts (which need not be
-+ * optimal).
-+ * IN assertion: the array bl_count contains the bit length statistics for
-+ * the given tree and the field len is set for all tree elements.
-+ * OUT assertion: the field code is set for all tree elements of non
-+ * zero code length.
-+ */
-+local void gen_codes (tree, max_code, bl_count)
-+ ct_data *tree; /* the tree to decorate */
-+ int max_code; /* largest code with non zero frequency */
-+ ushf *bl_count; /* number of codes at each bit length */
-+{
-+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
-+ ush code = 0; /* running code value */
-+ int bits; /* bit index */
-+ int n; /* code index */
-+
-+ /* The distribution counts are first used to generate the code values
-+ * without bit reversal.
-+ */
-+ for (bits = 1; bits <= MAX_BITS; bits++) {
-+ next_code[bits] = code = (code + bl_count[bits-1]) << 1;
-+ }
-+ /* Check that the bit counts in bl_count are consistent. The last code
-+ * must be all ones.
-+ */
-+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
-+ "inconsistent bit counts");
-+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
-+
-+ for (n = 0; n <= max_code; n++) {
-+ int len = tree[n].Len;
-+ if (len == 0) continue;
-+ /* Now reverse the bits */
-+ tree[n].Code = bi_reverse(next_code[len]++, len);
-+
-+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
-+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
-+ }
-+}
-+
-+/* ===========================================================================
-+ * Construct one Huffman tree and assigns the code bit strings and lengths.
-+ * Update the total bit length for the current block.
-+ * IN assertion: the field freq is set for all tree elements.
-+ * OUT assertions: the fields len and code are set to the optimal bit length
-+ * and corresponding code. The length opt_len is updated; static_len is
-+ * also updated if stree is not null. The field max_code is set.
-+ */
-+local void build_tree(s, desc)
-+ deflate_state *s;
-+ tree_desc *desc; /* the tree descriptor */
-+{
-+ ct_data *tree = desc->dyn_tree;
-+ const ct_data *stree = desc->stat_desc->static_tree;
-+ int elems = desc->stat_desc->elems;
-+ int n, m; /* iterate over heap elements */
-+ int max_code = -1; /* largest code with non zero frequency */
-+ int node; /* new node being created */
-+
-+ /* Construct the initial heap, with least frequent element in
-+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
-+ * heap[0] is not used.
-+ */
-+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
-+
-+ for (n = 0; n < elems; n++) {
-+ if (tree[n].Freq != 0) {
-+ s->heap[++(s->heap_len)] = max_code = n;
-+ s->depth[n] = 0;
-+ } else {
-+ tree[n].Len = 0;
-+ }
-+ }
-+
-+ /* The pkzip format requires that at least one distance code exists,
-+ * and that at least one bit should be sent even if there is only one
-+ * possible code. So to avoid special checks later on we force at least
-+ * two codes of non zero frequency.
-+ */
-+ while (s->heap_len < 2) {
-+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
-+ tree[node].Freq = 1;
-+ s->depth[node] = 0;
-+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
-+ /* node is 0 or 1 so it does not have extra bits */
-+ }
-+ desc->max_code = max_code;
-+
-+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
-+ * establish sub-heaps of increasing lengths:
-+ */
-+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
-+
-+ /* Construct the Huffman tree by repeatedly combining the least two
-+ * frequent nodes.
-+ */
-+ node = elems; /* next internal node of the tree */
-+ do {
-+ pqremove(s, tree, n); /* n = node of least frequency */
-+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
-+
-+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
-+ s->heap[--(s->heap_max)] = m;
-+
-+ /* Create a new node father of n and m */
-+ tree[node].Freq = tree[n].Freq + tree[m].Freq;
-+ s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
-+ tree[n].Dad = tree[m].Dad = (ush)node;
-+#ifdef DUMP_BL_TREE
-+ if (tree == s->bl_tree) {
-+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
-+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
-+ }
-+#endif
-+ /* and insert the new node in the heap */
-+ s->heap[SMALLEST] = node++;
-+ pqdownheap(s, tree, SMALLEST);
-+
-+ } while (s->heap_len >= 2);
-+
-+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
-+
-+ /* At this point, the fields freq and dad are set. We can now
-+ * generate the bit lengths.
-+ */
-+ gen_bitlen(s, (tree_desc *)desc);
-+
-+ /* The field len is now set, we can generate the bit codes */
-+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
-+}
-+
-+/* ===========================================================================
-+ * Scan a literal or distance tree to determine the frequencies of the codes
-+ * in the bit length tree.
-+ */
-+local void scan_tree (s, tree, max_code)
-+ deflate_state *s;
-+ ct_data *tree; /* the tree to be scanned */
-+ int max_code; /* and its largest code of non zero frequency */
-+{
-+ int n; /* iterates over all tree elements */
-+ int prevlen = -1; /* last emitted length */
-+ int curlen; /* length of current code */
-+ int nextlen = tree[0].Len; /* length of next code */
-+ int count = 0; /* repeat count of the current code */
-+ int max_count = 7; /* max repeat count */
-+ int min_count = 4; /* min repeat count */
-+
-+ if (nextlen == 0) max_count = 138, min_count = 3;
-+ tree[max_code+1].Len = (ush)0xffff; /* guard */
-+
-+ for (n = 0; n <= max_code; n++) {
-+ curlen = nextlen; nextlen = tree[n+1].Len;
-+ if (++count < max_count && curlen == nextlen) {
-+ continue;
-+ } else if (count < min_count) {
-+ s->bl_tree[curlen].Freq += count;
-+ } else if (curlen != 0) {
-+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
-+ s->bl_tree[REP_3_6].Freq++;
-+ } else if (count <= 10) {
-+ s->bl_tree[REPZ_3_10].Freq++;
-+ } else {
-+ s->bl_tree[REPZ_11_138].Freq++;
-+ }
-+ count = 0; prevlen = curlen;
-+ if (nextlen == 0) {
-+ max_count = 138, min_count = 3;
-+ } else if (curlen == nextlen) {
-+ max_count = 6, min_count = 3;
-+ } else {
-+ max_count = 7, min_count = 4;
-+ }
-+ }
-+}
-+
-+/* ===========================================================================
-+ * Send a literal or distance tree in compressed form, using the codes in
-+ * bl_tree.
-+ */
-+local void send_tree (s, tree, max_code)
-+ deflate_state *s;
-+ ct_data *tree; /* the tree to be scanned */
-+ int max_code; /* and its largest code of non zero frequency */
-+{
-+ int n; /* iterates over all tree elements */
-+ int prevlen = -1; /* last emitted length */
-+ int curlen; /* length of current code */
-+ int nextlen = tree[0].Len; /* length of next code */
-+ int count = 0; /* repeat count of the current code */
-+ int max_count = 7; /* max repeat count */
-+ int min_count = 4; /* min repeat count */
-+
-+ /* tree[max_code+1].Len = -1; */ /* guard already set */
-+ if (nextlen == 0) max_count = 138, min_count = 3;
-+
-+ for (n = 0; n <= max_code; n++) {
-+ curlen = nextlen; nextlen = tree[n+1].Len;
-+ if (++count < max_count && curlen == nextlen) {
-+ continue;
-+ } else if (count < min_count) {
-+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
-+
-+ } else if (curlen != 0) {
-+ if (curlen != prevlen) {
-+ send_code(s, curlen, s->bl_tree); count--;
-+ }
-+ Assert(count >= 3 && count <= 6, " 3_6?");
-+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
-+
-+ } else if (count <= 10) {
-+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
-+
-+ } else {
-+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
-+ }
-+ count = 0; prevlen = curlen;
-+ if (nextlen == 0) {
-+ max_count = 138, min_count = 3;
-+ } else if (curlen == nextlen) {
-+ max_count = 6, min_count = 3;
-+ } else {
-+ max_count = 7, min_count = 4;
-+ }
-+ }
-+}
-+
-+/* ===========================================================================
-+ * Construct the Huffman tree for the bit lengths and return the index in
-+ * bl_order of the last bit length code to send.
-+ */
-+local int build_bl_tree(s)
-+ deflate_state *s;
-+{
-+ int max_blindex; /* index of last bit length code of non zero freq */
-+
-+ /* Determine the bit length frequencies for literal and distance trees */
-+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
-+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
-+
-+ /* Build the bit length tree: */
-+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
-+ /* opt_len now includes the length of the tree representations, except
-+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
-+ */
-+
-+ /* Determine the number of bit length codes to send. The pkzip format
-+ * requires that at least 4 bit length codes be sent. (appnote.txt says
-+ * 3 but the actual value used is 4.)
-+ */
-+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
-+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
-+ }
-+ /* Update opt_len to include the bit length tree and counts */
-+ s->opt_len += 3*(max_blindex+1) + 5+5+4;
-+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
-+ s->opt_len, s->static_len));
-+
-+ return max_blindex;
-+}
-+
-+/* ===========================================================================
-+ * Send the header for a block using dynamic Huffman trees: the counts, the
-+ * lengths of the bit length codes, the literal tree and the distance tree.
-+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
-+ */
-+local void send_all_trees(s, lcodes, dcodes, blcodes)
-+ deflate_state *s;
-+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
-+{
-+ int rank; /* index in bl_order */
-+
-+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
-+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
-+ "too many codes");
-+ Tracev((stderr, "\nbl counts: "));
-+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
-+ send_bits(s, dcodes-1, 5);
-+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
-+ for (rank = 0; rank < blcodes; rank++) {
-+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
-+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
-+ }
-+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
-+
-+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
-+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
-+
-+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
-+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
-+}
-+
-+/* ===========================================================================
-+ * Send a stored block
-+ */
-+void _tr_stored_block(s, buf, stored_len, eof)
-+ deflate_state *s;
-+ charf *buf; /* input block */
-+ ulg stored_len; /* length of input block */
-+ int eof; /* true if this is the last block for a file */
-+{
-+ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
-+#ifdef DEBUG
-+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
-+ s->compressed_len += (stored_len + 4) << 3;
-+#endif
-+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
-+}
-+
-+/* ===========================================================================
-+ * Send one empty static block to give enough lookahead for inflate.
-+ * This takes 10 bits, of which 7 may remain in the bit buffer.
-+ * The current inflate code requires 9 bits of lookahead. If the
-+ * last two codes for the previous block (real code plus EOB) were coded
-+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
-+ * the last real code. In this case we send two empty static blocks instead
-+ * of one. (There are no problems if the previous block is stored or fixed.)
-+ * To simplify the code, we assume the worst case of last real code encoded
-+ * on one bit only.
-+ */
-+void _tr_align(s)
-+ deflate_state *s;
-+{
-+ send_bits(s, STATIC_TREES<<1, 3);
-+ send_code(s, END_BLOCK, static_ltree);
-+#ifdef DEBUG
-+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
-+#endif
-+ bi_flush(s);
-+ /* Of the 10 bits for the empty block, we have already sent
-+ * (10 - bi_valid) bits. The lookahead for the last real code (before
-+ * the EOB of the previous block) was thus at least one plus the length
-+ * of the EOB plus what we have just sent of the empty static block.
-+ */
-+ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
-+ send_bits(s, STATIC_TREES<<1, 3);
-+ send_code(s, END_BLOCK, static_ltree);
-+#ifdef DEBUG
-+ s->compressed_len += 10L;
-+#endif
-+ bi_flush(s);
-+ }
-+ s->last_eob_len = 7;
-+}
-+
-+/* ===========================================================================
-+ * Determine the best encoding for the current block: dynamic trees, static
-+ * trees or store, and output the encoded block to the zip file.
-+ */
-+void _tr_flush_block(s, buf, stored_len, eof)
-+ deflate_state *s;
-+ charf *buf; /* input block, or NULL if too old */
-+ ulg stored_len; /* length of input block */
-+ int eof; /* true if this is the last block for a file */
-+{
-+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
-+ int max_blindex = 0; /* index of last bit length code of non zero freq */
-+
-+ /* Build the Huffman trees unless a stored block is forced */
-+ if (s->level > 0) {
-+
-+ /* Check if the file is ascii or binary */
-+ if (s->data_type == Z_UNKNOWN) set_data_type(s);
-+
-+ /* Construct the literal and distance trees */
-+ build_tree(s, (tree_desc *)(&(s->l_desc)));
-+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
-+ s->static_len));
-+
-+ build_tree(s, (tree_desc *)(&(s->d_desc)));
-+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
-+ s->static_len));
-+ /* At this point, opt_len and static_len are the total bit lengths of
-+ * the compressed block data, excluding the tree representations.
-+ */
-+
-+ /* Build the bit length tree for the above two trees, and get the index
-+ * in bl_order of the last bit length code to send.
-+ */
-+ max_blindex = build_bl_tree(s);
-+
-+ /* Determine the best encoding. Compute first the block length in bytes*/
-+ opt_lenb = (s->opt_len+3+7)>>3;
-+ static_lenb = (s->static_len+3+7)>>3;
-+
-+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
-+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
-+ s->last_lit));
-+
-+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
-+
-+ } else {
-+ Assert(buf != (char*)0, "lost buf");
-+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
-+ }
-+
-+#ifdef FORCE_STORED
-+ if (buf != (char*)0) { /* force stored block */
-+#else
-+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
-+ /* 4: two words for the lengths */
-+#endif
-+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
-+ * Otherwise we can't have processed more than WSIZE input bytes since
-+ * the last block flush, because compression would have been
-+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
-+ * transform a block into a stored block.
-+ */
-+ _tr_stored_block(s, buf, stored_len, eof);
-+
-+#ifdef FORCE_STATIC
-+ } else if (static_lenb >= 0) { /* force static trees */
-+#else
-+ } else if (static_lenb == opt_lenb) {
-+#endif
-+ send_bits(s, (STATIC_TREES<<1)+eof, 3);
-+ compress_block(s, static_ltree, static_dtree);
-+#ifdef DEBUG
-+ s->compressed_len += 3 + s->static_len;
-+#endif
-+ } else {
-+ send_bits(s, (DYN_TREES<<1)+eof, 3);
-+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
-+ max_blindex+1);
-+ compress_block(s, s->dyn_ltree, s->dyn_dtree);
-+#ifdef DEBUG
-+ s->compressed_len += 3 + s->opt_len;
-+#endif
-+ }
-+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
-+ /* The above check is made mod 2^32, for files larger than 512 MB
-+ * and uLong implemented on 32 bits.
-+ */
-+ init_block(s);
-+
-+ if (eof) {
-+ bi_windup(s);
-+#ifdef DEBUG
-+ s->compressed_len += 7; /* align on byte boundary */
-+#endif
-+ }
-+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
-+ s->compressed_len-7*eof));
-+}
-+
-+/* ===========================================================================
-+ * Save the match info and tally the frequency counts. Return true if
-+ * the current block must be flushed.
-+ */
-+int _tr_tally (s, dist, lc)
-+ deflate_state *s;
-+ unsigned dist; /* distance of matched string */
-+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
-+{
-+ s->d_buf[s->last_lit] = (ush)dist;
-+ s->l_buf[s->last_lit++] = (uch)lc;
-+ if (dist == 0) {
-+ /* lc is the unmatched char */
-+ s->dyn_ltree[lc].Freq++;
-+ } else {
-+ s->matches++;
-+ /* Here, lc is the match length - MIN_MATCH */
-+ dist--; /* dist = match distance - 1 */
-+ Assert((ush)dist < (ush)MAX_DIST(s) &&
-+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
-+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
-+
-+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
-+ s->dyn_dtree[d_code(dist)].Freq++;
-+ }
-+
-+#ifdef TRUNCATE_BLOCK
-+ /* Try to guess if it is profitable to stop the current block here */
-+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
-+ /* Compute an upper bound for the compressed length */
-+ ulg out_length = (ulg)s->last_lit*8L;
-+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
-+ int dcode;
-+ for (dcode = 0; dcode < D_CODES; dcode++) {
-+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
-+ (5L+extra_dbits[dcode]);
-+ }
-+ out_length >>= 3;
-+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
-+ s->last_lit, in_length, out_length,
-+ 100L - out_length*100L/in_length));
-+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
-+ }
-+#endif
-+ return (s->last_lit == s->lit_bufsize-1);
-+ /* We avoid equality with lit_bufsize because of wraparound at 64K
-+ * on 16 bit machines and because stored blocks are restricted to
-+ * 64K-1 bytes.
-+ */
-+}
-+
-+/* ===========================================================================
-+ * Send the block data compressed using the given Huffman trees
-+ */
-+local void compress_block(s, ltree, dtree)
-+ deflate_state *s;
-+ const ct_data *ltree; /* literal tree */
-+ const ct_data *dtree; /* distance tree */
-+{
-+ unsigned dist; /* distance of matched string */
-+ int lc; /* match length or unmatched char (if dist == 0) */
-+ unsigned lx = 0; /* running index in l_buf */
-+ unsigned code; /* the code to send */
-+ int extra; /* number of extra bits to send */
-+
-+ if (s->last_lit != 0) do {
-+ dist = s->d_buf[lx];
-+ lc = s->l_buf[lx++];
-+ if (dist == 0) {
-+ send_code(s, lc, ltree); /* send a literal byte */
-+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
-+ } else {
-+ /* Here, lc is the match length - MIN_MATCH */
-+ code = _length_code[lc];
-+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
-+ extra = extra_lbits[code];
-+ if (extra != 0) {
-+ lc -= base_length[code];
-+ send_bits(s, lc, extra); /* send the extra length bits */
-+ }
-+ dist--; /* dist is now the match distance - 1 */
-+ code = d_code(dist);
-+ Assert (code < D_CODES, "bad d_code");
-+
-+ send_code(s, code, dtree); /* send the distance code */
-+ extra = extra_dbits[code];
-+ if (extra != 0) {
-+ dist -= base_dist[code];
-+ send_bits(s, dist, extra); /* send the extra distance bits */
-+ }
-+ } /* literal or match pair ? */
-+
-+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
-+ Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
-+
-+ } while (lx < s->last_lit);
-+
-+ send_code(s, END_BLOCK, ltree);
-+ s->last_eob_len = ltree[END_BLOCK].Len;
-+}
-+
-+/* ===========================================================================
-+ * Set the data type to ASCII or BINARY, using a crude approximation:
-+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
-+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
-+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
-+ */
-+local void set_data_type(s)
-+ deflate_state *s;
-+{
-+ int n = 0;
-+ unsigned ascii_freq = 0;
-+ unsigned bin_freq = 0;
-+ while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
-+ while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
-+ while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
-+ s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
-+}
-+
-+/* ===========================================================================
-+ * Reverse the first len bits of a code, using straightforward code (a faster
-+ * method would use a table)
-+ * IN assertion: 1 <= len <= 15
-+ */
-+local unsigned bi_reverse(code, len)
-+ unsigned code; /* the value to invert */
-+ int len; /* its bit length */
-+{
-+ register unsigned res = 0;
-+ do {
-+ res |= code & 1;
-+ code >>= 1, res <<= 1;
-+ } while (--len > 0);
-+ return res >> 1;
-+}
-+
-+/* ===========================================================================
-+ * Flush the bit buffer, keeping at most 7 bits in it.
-+ */
-+local void bi_flush(s)
-+ deflate_state *s;
-+{
-+ if (s->bi_valid == 16) {
-+ put_short(s, s->bi_buf);
-+ s->bi_buf = 0;
-+ s->bi_valid = 0;
-+ } else if (s->bi_valid >= 8) {
-+ put_byte(s, (Byte)s->bi_buf);
-+ s->bi_buf >>= 8;
-+ s->bi_valid -= 8;
-+ }
-+}
-+
-+/* ===========================================================================
-+ * Flush the bit buffer and align the output on a byte boundary
-+ */
-+local void bi_windup(s)
-+ deflate_state *s;
-+{
-+ if (s->bi_valid > 8) {
-+ put_short(s, s->bi_buf);
-+ } else if (s->bi_valid > 0) {
-+ put_byte(s, (Byte)s->bi_buf);
-+ }
-+ s->bi_buf = 0;
-+ s->bi_valid = 0;
-+#ifdef DEBUG
-+ s->bits_sent = (s->bits_sent+7) & ~7;
-+#endif
-+}
-+
-+/* ===========================================================================
-+ * Copy a stored block, storing first the length and its
-+ * one's complement if requested.
-+ */
-+local void copy_block(s, buf, len, header)
-+ deflate_state *s;
-+ charf *buf; /* the input data */
-+ unsigned len; /* its length */
-+ int header; /* true if block header must be written */
-+{
-+ bi_windup(s); /* align on byte boundary */
-+ s->last_eob_len = 8; /* enough lookahead for inflate */
-+
-+ if (header) {
-+ put_short(s, (ush)len);
-+ put_short(s, (ush)~len);
-+#ifdef DEBUG
-+ s->bits_sent += 2*16;
-+#endif
-+ }
-+#ifdef DEBUG
-+ s->bits_sent += (ulg)len<<3;
-+#endif
-+ while (len--) {
-+ put_byte(s, *buf++);
-+ }
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/trees.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,128 @@
-+/* header created automatically with -DGEN_TREES_H */
-+
-+local const ct_data static_ltree[L_CODES+2] = {
-+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
-+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
-+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
-+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
-+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
-+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
-+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
-+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
-+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
-+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
-+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
-+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
-+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
-+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
-+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
-+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
-+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
-+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
-+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
-+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
-+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
-+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
-+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
-+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
-+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
-+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
-+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
-+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
-+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
-+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
-+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
-+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
-+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
-+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
-+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
-+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
-+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
-+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
-+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
-+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
-+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
-+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
-+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
-+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
-+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
-+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
-+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
-+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
-+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
-+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
-+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
-+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
-+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
-+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
-+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
-+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
-+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
-+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
-+};
-+
-+local const ct_data static_dtree[D_CODES] = {
-+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
-+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
-+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
-+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
-+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
-+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
-+};
-+
-+const uch _dist_code[DIST_CODE_LEN] = {
-+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
-+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
-+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
-+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
-+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
-+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
-+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
-+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
-+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
-+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
-+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
-+};
-+
-+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
-+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
-+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
-+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
-+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
-+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
-+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
-+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
-+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
-+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
-+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
-+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
-+};
-+
-+local const int base_length[LENGTH_CODES] = {
-+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
-+64, 80, 96, 112, 128, 160, 192, 224, 0
-+};
-+
-+local const int base_dist[D_CODES] = {
-+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
-+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
-+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
-+};
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/zconf.h Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,309 @@
-+/* zconf.h -- configuration of the zlib compression library
-+ * Copyright (C) 1995-2002 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* @(#) $Id$ */
-+
-+#ifndef _ZCONF_H
-+#define _ZCONF_H
-+
-+/*
-+ * If you *really* need a unique prefix for all types and library functions,
-+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
-+ */
-+#ifdef IPCOMP_PREFIX
-+# define deflateInit_ ipcomp_deflateInit_
-+# define deflate ipcomp_deflate
-+# define deflateEnd ipcomp_deflateEnd
-+# define inflateInit_ ipcomp_inflateInit_
-+# define inflate ipcomp_inflate
-+# define inflateEnd ipcomp_inflateEnd
-+# define deflateInit2_ ipcomp_deflateInit2_
-+# define deflateSetDictionary ipcomp_deflateSetDictionary
-+# define deflateCopy ipcomp_deflateCopy
-+# define deflateReset ipcomp_deflateReset
-+# define deflateParams ipcomp_deflateParams
-+# define inflateInit2_ ipcomp_inflateInit2_
-+# define inflateSetDictionary ipcomp_inflateSetDictionary
-+# define inflateSync ipcomp_inflateSync
-+# define inflateSyncPoint ipcomp_inflateSyncPoint
-+# define inflateReset ipcomp_inflateReset
-+# define compress ipcomp_compress
-+# define compress2 ipcomp_compress2
-+# define uncompress ipcomp_uncompress
-+# define adler32 ipcomp_adler32
-+# define crc32 ipcomp_crc32
-+# define get_crc_table ipcomp_get_crc_table
-+/* SSS: these also need to be prefixed to avoid clash with ppp_deflate and ext2compression */
-+# define inflate_blocks ipcomp_deflate_blocks
-+# define inflate_blocks_free ipcomp_deflate_blocks_free
-+# define inflate_blocks_new ipcomp_inflate_blocks_new
-+# define inflate_blocks_reset ipcomp_inflate_blocks_reset
-+# define inflate_blocks_sync_point ipcomp_inflate_blocks_sync_point
-+# define inflate_set_dictionary ipcomp_inflate_set_dictionary
-+# define inflate_codes ipcomp_inflate_codes
-+# define inflate_codes_free ipcomp_inflate_codes_free
-+# define inflate_codes_new ipcomp_inflate_codes_new
-+# define inflate_fast ipcomp_inflate_fast
-+# define inflate_trees_bits ipcomp_inflate_trees_bits
-+# define inflate_trees_dynamic ipcomp_inflate_trees_dynamic
-+# define inflate_trees_fixed ipcomp_inflate_trees_fixed
-+# define inflate_flush ipcomp_inflate_flush
-+# define inflate_mask ipcomp_inflate_mask
-+# define _dist_code _ipcomp_dist_code
-+# define _length_code _ipcomp_length_code
-+# define _tr_align _ipcomp_tr_align
-+# define _tr_flush_block _ipcomp_tr_flush_block
-+# define _tr_init _ipcomp_tr_init
-+# define _tr_stored_block _ipcomp_tr_stored_block
-+# define _tr_tally _ipcomp_tr_tally
-+# define zError ipcomp_zError
-+# define z_errmsg ipcomp_z_errmsg
-+# define zlibVersion ipcomp_zlibVersion
-+# define match_init ipcomp_match_init
-+# define longest_match ipcomp_longest_match
-+#endif
-+
-+#ifdef Z_PREFIX
-+# define Byte z_Byte
-+# define uInt z_uInt
-+# define uLong z_uLong
-+# define Bytef z_Bytef
-+# define charf z_charf
-+# define intf z_intf
-+# define uIntf z_uIntf
-+# define uLongf z_uLongf
-+# define voidpf z_voidpf
-+# define voidp z_voidp
-+#endif
-+
-+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
-+# define WIN32
-+#endif
-+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
-+# ifndef __32BIT__
-+# define __32BIT__
-+# endif
-+#endif
-+#if defined(__MSDOS__) && !defined(MSDOS)
-+# define MSDOS
-+#endif
-+
-+/*
-+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
-+ * than 64k bytes at a time (needed on systems with 16-bit int).
-+ */
-+#if defined(MSDOS) && !defined(__32BIT__)
-+# define MAXSEG_64K
-+#endif
-+#ifdef MSDOS
-+# define UNALIGNED_OK
-+#endif
-+
-+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
-+# define STDC
-+#endif
-+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
-+# ifndef STDC
-+# define STDC
-+# endif
-+#endif
-+
-+#ifndef STDC
-+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
-+# define const
-+# endif
-+#endif
-+
-+/* Some Mac compilers merge all .h files incorrectly: */
-+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
-+# define NO_DUMMY_DECL
-+#endif
-+
-+/* Old Borland C incorrectly complains about missing returns: */
-+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
-+# define NEED_DUMMY_RETURN
-+#endif
-+
-+
-+/* Maximum value for memLevel in deflateInit2 */
-+#ifndef MAX_MEM_LEVEL
-+# ifdef MAXSEG_64K
-+# define MAX_MEM_LEVEL 8
-+# else
-+# define MAX_MEM_LEVEL 9
-+# endif
-+#endif
-+
-+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
-+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
-+ * created by gzip. (Files created by minigzip can still be extracted by
-+ * gzip.)
-+ */
-+#ifndef MAX_WBITS
-+# define MAX_WBITS 15 /* 32K LZ77 window */
-+#endif
-+
-+/* The memory requirements for deflate are (in bytes):
-+ (1 << (windowBits+2)) + (1 << (memLevel+9))
-+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
-+ plus a few kilobytes for small objects. For example, if you want to reduce
-+ the default memory requirements from 256K to 128K, compile with
-+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
-+ Of course this will generally degrade compression (there's no free lunch).
-+
-+ The memory requirements for inflate are (in bytes) 1 << windowBits
-+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
-+ for small objects.
-+*/
-+
-+ /* Type declarations */
-+
-+#ifndef OF /* function prototypes */
-+# ifdef STDC
-+# define OF(args) args
-+# else
-+# define OF(args) ()
-+# endif
-+#endif
-+
-+/* The following definitions for FAR are needed only for MSDOS mixed
-+ * model programming (small or medium model with some far allocations).
-+ * This was tested only with MSC; for other MSDOS compilers you may have
-+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
-+ * just define FAR to be empty.
-+ */
-+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
-+ /* MSC small or medium model */
-+# define SMALL_MEDIUM
-+# ifdef _MSC_VER
-+# define FAR _far
-+# else
-+# define FAR far
-+# endif
-+#endif
-+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
-+# ifndef __32BIT__
-+# define SMALL_MEDIUM
-+# define FAR _far
-+# endif
-+#endif
-+
-+/* Compile with -DZLIB_DLL for Windows DLL support */
-+#if defined(ZLIB_DLL)
-+# if defined(_WINDOWS) || defined(WINDOWS)
-+# ifdef FAR
-+# undef FAR
-+# endif
-+# include <windows.h>
-+# define ZEXPORT WINAPI
-+# ifdef WIN32
-+# define ZEXPORTVA WINAPIV
-+# else
-+# define ZEXPORTVA FAR _cdecl _export
-+# endif
-+# endif
-+# if defined (__BORLANDC__)
-+# if (__BORLANDC__ >= 0x0500) && defined (WIN32)
-+# include <windows.h>
-+# define ZEXPORT __declspec(dllexport) WINAPI
-+# define ZEXPORTRVA __declspec(dllexport) WINAPIV
-+# else
-+# if defined (_Windows) && defined (__DLL__)
-+# define ZEXPORT _export
-+# define ZEXPORTVA _export
-+# endif
-+# endif
-+# endif
-+#endif
-+
-+#if defined (__BEOS__)
-+# if defined (ZLIB_DLL)
-+# define ZEXTERN extern __declspec(dllexport)
-+# else
-+# define ZEXTERN extern __declspec(dllimport)
-+# endif
-+#endif
-+
-+#ifndef ZEXPORT
-+# define ZEXPORT
-+#endif
-+#ifndef ZEXPORTVA
-+# define ZEXPORTVA
-+#endif
-+#ifndef ZEXTERN
-+# define ZEXTERN extern
-+#endif
-+
-+#ifndef FAR
-+# define FAR
-+#endif
-+
-+#if !defined(MACOS) && !defined(TARGET_OS_MAC)
-+typedef unsigned char Byte; /* 8 bits */
-+#endif
-+typedef unsigned int uInt; /* 16 bits or more */
-+typedef unsigned long uLong; /* 32 bits or more */
-+
-+#ifdef SMALL_MEDIUM
-+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
-+# define Bytef Byte FAR
-+#else
-+ typedef Byte FAR Bytef;
-+#endif
-+typedef char FAR charf;
-+typedef int FAR intf;
-+typedef uInt FAR uIntf;
-+typedef uLong FAR uLongf;
-+
-+#ifdef STDC
-+ typedef void FAR *voidpf;
-+ typedef void *voidp;
-+#else
-+ typedef Byte FAR *voidpf;
-+ typedef Byte *voidp;
-+#endif
-+
-+#ifdef HAVE_UNISTD_H
-+# include <sys/types.h> /* for off_t */
-+# include <unistd.h> /* for SEEK_* and off_t */
-+# define z_off_t off_t
-+#endif
-+#ifndef SEEK_SET
-+# define SEEK_SET 0 /* Seek from beginning of file. */
-+# define SEEK_CUR 1 /* Seek from current position. */
-+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
-+#endif
-+#ifndef z_off_t
-+# define z_off_t long
-+#endif
-+
-+/* MVS linker does not support external names larger than 8 bytes */
-+#if defined(__MVS__)
-+# pragma map(deflateInit_,"DEIN")
-+# pragma map(deflateInit2_,"DEIN2")
-+# pragma map(deflateEnd,"DEEND")
-+# pragma map(inflateInit_,"ININ")
-+# pragma map(inflateInit2_,"ININ2")
-+# pragma map(inflateEnd,"INEND")
-+# pragma map(inflateSync,"INSY")
-+# pragma map(inflateSetDictionary,"INSEDI")
-+# pragma map(inflate_blocks,"INBL")
-+# pragma map(inflate_blocks_new,"INBLNE")
-+# pragma map(inflate_blocks_free,"INBLFR")
-+# pragma map(inflate_blocks_reset,"INBLRE")
-+# pragma map(inflate_codes_free,"INCOFR")
-+# pragma map(inflate_codes,"INCO")
-+# pragma map(inflate_fast,"INFA")
-+# pragma map(inflate_flush,"INFLU")
-+# pragma map(inflate_mask,"INMA")
-+# pragma map(inflate_set_dictionary,"INSEDI2")
-+# pragma map(ipcomp_inflate_copyright,"INCOPY")
-+# pragma map(inflate_trees_bits,"INTRBI")
-+# pragma map(inflate_trees_dynamic,"INTRDY")
-+# pragma map(inflate_trees_fixed,"INTRFI")
-+# pragma map(inflate_trees_free,"INTRFR")
-+#endif
-+
-+#endif /* _ZCONF_H */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/lib/zlib/zutil.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,227 @@
-+/* zutil.c -- target dependent utility functions for the compression library
-+ * Copyright (C) 1995-2002 Jean-loup Gailly.
-+ * For conditions of distribution and use, see copyright notice in zlib.h
-+ */
-+
-+/* @(#) $Id$ */
-+
-+#include <zlib/zutil.h>
-+
-+#define MY_ZCALLOC
-+
-+struct internal_state {int dummy;}; /* for buggy compilers */
-+
-+#ifndef STDC
-+extern void exit OF((int));
-+#endif
-+
-+const char *z_errmsg[10] = {
-+"need dictionary", /* Z_NEED_DICT 2 */
-+"stream end", /* Z_STREAM_END 1 */
-+"", /* Z_OK 0 */
-+"file error", /* Z_ERRNO (-1) */
-+"stream error", /* Z_STREAM_ERROR (-2) */
-+"data error", /* Z_DATA_ERROR (-3) */
-+"insufficient memory", /* Z_MEM_ERROR (-4) */
-+"buffer error", /* Z_BUF_ERROR (-5) */
-+"incompatible version",/* Z_VERSION_ERROR (-6) */
-+""};
-+
-+
-+const char * ZEXPORT zlibVersion()
-+{
-+ return ZLIB_VERSION;
-+}
-+
-+#ifdef DEBUG
-+
-+# ifndef verbose
-+# define verbose 0
-+# endif
-+int z_verbose = verbose;
-+
-+void z_error (m)
-+ char *m;
-+{
-+ fprintf(stderr, "%s\n", m);
-+ exit(1);
-+}
-+#endif
-+
-+/* exported to allow conversion of error code to string for compress() and
-+ * uncompress()
-+ */
-+const char * ZEXPORT zError(err)
-+ int err;
-+{
-+ return ERR_MSG(err);
-+}
-+
-+
-+#ifndef HAVE_MEMCPY
-+
-+void zmemcpy(dest, source, len)
-+ Bytef* dest;
-+ const Bytef* source;
-+ uInt len;
-+{
-+ if (len == 0) return;
-+ do {
-+ *dest++ = *source++; /* ??? to be unrolled */
-+ } while (--len != 0);
-+}
-+
-+int zmemcmp(s1, s2, len)
-+ const Bytef* s1;
-+ const Bytef* s2;
-+ uInt len;
-+{
-+ uInt j;
-+
-+ for (j = 0; j < len; j++) {
-+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
-+ }
-+ return 0;
-+}
-+
-+void zmemzero(dest, len)
-+ Bytef* dest;
-+ uInt len;
-+{
-+ if (len == 0) return;
-+ do {
-+ *dest++ = 0; /* ??? to be unrolled */
-+ } while (--len != 0);
-+}
-+#endif
-+
-+#ifdef __TURBOC__
-+#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
-+/* Small and medium model in Turbo C are for now limited to near allocation
-+ * with reduced MAX_WBITS and MAX_MEM_LEVEL
-+ */
-+# define MY_ZCALLOC
-+
-+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
-+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
-+ * must fix the pointer. Warning: the pointer must be put back to its
-+ * original form in order to free it, use zcfree().
-+ */
-+
-+#define MAX_PTR 10
-+/* 10*64K = 640K */
-+
-+local int next_ptr = 0;
-+
-+typedef struct ptr_table_s {
-+ voidpf org_ptr;
-+ voidpf new_ptr;
-+} ptr_table;
-+
-+local ptr_table table[MAX_PTR];
-+/* This table is used to remember the original form of pointers
-+ * to large buffers (64K). Such pointers are normalized with a zero offset.
-+ * Since MSDOS is not a preemptive multitasking OS, this table is not
-+ * protected from concurrent access. This hack doesn't work anyway on
-+ * a protected system like OS/2. Use Microsoft C instead.
-+ */
-+
-+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-+{
-+ voidpf buf = opaque; /* just to make some compilers happy */
-+ ulg bsize = (ulg)items*size;
-+
-+ /* If we allocate less than 65520 bytes, we assume that farmalloc
-+ * will return a usable pointer which doesn't have to be normalized.
-+ */
-+ if (bsize < 65520L) {
-+ buf = farmalloc(bsize);
-+ if (*(ush*)&buf != 0) return buf;
-+ } else {
-+ buf = farmalloc(bsize + 16L);
-+ }
-+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
-+ table[next_ptr].org_ptr = buf;
-+
-+ /* Normalize the pointer to seg:0 */
-+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
-+ *(ush*)&buf = 0;
-+ table[next_ptr++].new_ptr = buf;
-+ return buf;
-+}
-+
-+void zcfree (voidpf opaque, voidpf ptr)
-+{
-+ int n;
-+ if (*(ush*)&ptr != 0) { /* object < 64K */
-+ farfree(ptr);
-+ return;
-+ }
-+ /* Find the original pointer */
-+ for (n = 0; n < next_ptr; n++) {
-+ if (ptr != table[n].new_ptr) continue;
-+
-+ farfree(table[n].org_ptr);
-+ while (++n < next_ptr) {
-+ table[n-1] = table[n];
-+ }
-+ next_ptr--;
-+ return;
-+ }
-+ ptr = opaque; /* just to make some compilers happy */
-+ Assert(0, "zcfree: ptr not found");
-+}
-+#endif
-+#endif /* __TURBOC__ */
-+
-+
-+#if defined(M_I86) && !defined(__32BIT__)
-+/* Microsoft C in 16-bit mode */
-+
-+# define MY_ZCALLOC
-+
-+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
-+# define _halloc halloc
-+# define _hfree hfree
-+#endif
-+
-+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
-+{
-+ if (opaque) opaque = 0; /* to make compiler happy */
-+ return _halloc((long)items, size);
-+}
-+
-+void zcfree (voidpf opaque, voidpf ptr)
-+{
-+ if (opaque) opaque = 0; /* to make compiler happy */
-+ _hfree(ptr);
-+}
-+
-+#endif /* MSC */
-+
-+
-+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
-+
-+#ifndef STDC
-+extern voidp calloc OF((uInt items, uInt size));
-+extern void free OF((voidpf ptr));
-+#endif
-+
-+voidpf zcalloc (opaque, items, size)
-+ voidpf opaque;
-+ unsigned items;
-+ unsigned size;
-+{
-+ if (opaque) items += size - size; /* make compiler happy */
-+ return (voidpf)calloc(items, size);
-+}
-+
-+void zcfree (opaque, ptr)
-+ voidpf opaque;
-+ voidpf ptr;
-+{
-+ free(ptr);
-+ if (opaque) return; /* make compiler happy */
-+}
-+
-+#endif /* MY_ZCALLOC */
---- linux/net/Config.in.orig Fri Feb 9 14:34:13 2001
-+++ linux/net/Config.in Thu Feb 22 19:40:08 2001
-@@ -88,4 +88,9 @@
- #bool 'Network code profiler' CONFIG_NET_PROFILE
- endmenu
-
-+tristate 'IP Security Protocol (FreeS/WAN IPSEC)' CONFIG_IPSEC
-+if [ "$CONFIG_IPSEC" != "n" ]; then
-+ source net/ipsec/Config.in
-+fi
-+
- endmenu
-RCSID $Id$
---- linux/net/Makefile.preipsec Mon Jun 11 22:15:27 2001
-+++ linux/net/Makefile Tue Nov 6 21:07:43 2001
-@@ -17,6 +17,7 @@
- subdir-$(CONFIG_NET) += 802 sched
- subdir-$(CONFIG_INET) += ipv4
- subdir-$(CONFIG_NETFILTER) += ipv4/netfilter
-+subdir-$(CONFIG_IPSEC) += ipsec
- subdir-$(CONFIG_UNIX) += unix
- subdir-$(CONFIG_IPV6) += ipv6
-
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/Config.in Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,76 @@
-+#
-+# IPSEC configuration
-+# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
-+#
-+# 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+#
-+# 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.
-+#
-+# RCSID $Id$
-+
-+comment 'IPSec options (Openswan)'
-+
-+bool ' IPSEC: IP-in-IP encapsulation (tunnel mode)' CONFIG_IPSEC_IPIP
-+
-+bool ' IPSEC: Authentication Header' CONFIG_IPSEC_AH
-+if [ "$CONFIG_IPSEC_AH" = "y" -o "$CONFIG_IPSEC_ESP" = "y" ]; then
-+ bool ' HMAC-MD5 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_MD5
-+ bool ' HMAC-SHA1 authentication algorithm' CONFIG_IPSEC_AUTH_HMAC_SHA1
-+fi
-+
-+bool ' IPSEC: Encapsulating Security Payload' CONFIG_IPSEC_ESP
-+if [ "$CONFIG_IPSEC_ESP" = "y" ]; then
-+ bool ' 3DES encryption algorithm' CONFIG_IPSEC_ENC_3DES
-+ bool ' AES encryption algorithm' CONFIG_IPSEC_ENC_AES
-+fi
-+
-+bool ' IPSEC Modular Extensions' CONFIG_IPSEC_ALG
-+if [ "$CONFIG_IPSEC_ALG" != "n" ]; then
-+ source net/ipsec/alg/Config.in
-+fi
-+
-+bool ' IPSEC: IP Compression' CONFIG_IPSEC_IPCOMP
-+
-+bool ' IPSEC Debugging Option' CONFIG_IPSEC_DEBUG
-+
-+#
-+#
-+# $Log$
-+# Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+# Turn off EOLN_NATIVE flag
-+#
-+# (Logical change 1.5010)
-+#
-+# Revision 1.30 2004/06/23 09:49:37 ken
-+# Free -> Open
-+#
-+# Revision 1.29 2004/04/06 02:49:25 mcr
-+# pullup of algo code from alg-branch.
-+#
-+# Revision 1.28 2004/02/03 03:12:26 mcr
-+# remove NAT-traversal option from IPsec config,
-+# as it should be in the kernel configuration if
-+# the NAT-T patch is installed.
-+#
-+# Revision 1.27.2.2 2004/04/05 04:30:46 mcr
-+# patches for alg-branch to compile/work with 2.x openswan
-+#
-+# Revision 1.27.2.1 2003/12/23 12:48:25 jjo
-+# Added missing alg part to linux/net/ipsec/Config.in
-+#
-+# Revision 1.27 2003/12/10 01:14:27 mcr
-+# NAT-traversal patches to KLIPS.
-+#
-+# Revision 1.26 2002/04/24 07:36:26 mcr
-+# Moved from ./klips/net/ipsec/Config.in,v
-+#
-+# Revision 1.25 2002/02/21 19:55:12 mcr
-+# removed all traces of IPSEC_CONFIG_REGRESS because it
-+# screwed up 2.2's "make menuconfig" scripts.
-+#
-+# Revision 1.24 2002/01/28 20:24:31 mcr
-+# commented out IPSEC_REGRESS option from user visible config.
-+#
-+#
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/Makefile Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,337 @@
-+# Makefile for KLIPS kernel code as a module
-+# Copyright (C) 1998, 1999, 2000,2001 Richard Guy Briggs.
-+# Copyright (C) 2002 Michael Richardson <mcr@freeswan.org>
-+#
-+# This program is free software; you can redistribute it and/or modify it
-+# under the terms of the GNU General Public License as published by the
-+# Free Software Foundation; either version 2 of the License, or (at your
-+# option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+#
-+# 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.
-+#
-+# RCSID $Id$
-+#
-+# Note! Dependencies are done automagically by 'make dep', which also
-+# removes any old dependencies. DON'T put your own dependencies here
-+# unless it's something special (ie not a .c file).
-+#
-+
-+ifeq ($(strip $(KLIPSMODULE)),)
-+OPENSWANSRCDIR=.
-+else
-+OPENSWANSRCDIR=../../..
-+endif
-+-include ${OPENSWANSRCDIR}/Makefile.ver
-+
-+ifeq ($(strip $(KLIPS_TOP)),)
-+KLIPS_TOP=../..
-+endif
-+
-+ifneq ($(strip $(KLIPSMODULE)),)
-+
-+ifndef TOPDIR
-+TOPDIR:=/usr/src/linux
-+endif
-+export TOPDIR
-+
-+endif
-+
-+#
-+# This magic from User-Mode-Linux list. It gets list of -I options, as
-+# UML needs some extra, that varry by revision.
-+#
-+KERNEL_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(CFLAGS)' )
-+
-+MODULE_CFLAGS= $(shell $(MAKE) -C $(TOPDIR) --no-print-directory -s -f Makefile ARCH=$(ARCH) MAKEFLAGS= script SCRIPT='@echo $$(MODFLAGS)' )
-+
-+subdir- :=
-+subdir-n :=
-+subdir-y :=
-+subdir-m :=
-+
-+
-+MOD_DESTDIR:=net/ipsec
-+
-+export TOPDIR
-+
-+all: ipsec.o
-+
-+foo:
-+ echo KERNEL: ${KERNEL_CFLAGS}
-+ echo MODULE: ${MODULE_CFLAGS}
-+
-+ipsec.o: foo
-+
-+O_TARGET := ipsec.o
-+obj-y := ipsec_init.o ipsec_sa.o ipsec_radij.o radij.o
-+obj-y += ipsec_life.o ipsec_proc.o
-+obj-y += ipsec_tunnel.o ipsec_xmit.o ipsec_rcv.o ipsec_ipip.o
-+obj-y += sysctl_net_ipsec.o
-+obj-y += pfkey_v2.o pfkey_v2_parser.o pfkey_v2_ext_process.o
-+obj-y += version.o
-+obj-$(CONFIG_IPSEC_AH) += ipsec_ah.o
-+obj-$(CONFIG_IPSEC_ESP) += ipsec_esp.o
-+obj-$(CONFIG_IPSEC_IPCOMP)+= ipsec_ipcomp.o
-+
-+CFLAGS_ipsec_alg.o += -DEXPORT_SYMTAB
-+obj-$(CONFIG_IPSEC_ALG) += ipsec_alg.o
-+obj-$(CONFIG_IPSEC_ENC_AES) += ipsec_alg_aes.o
-+obj-$(CONFIG_IPSEC_ENC_CRYPTOAPI) += ipsec_alg_cryptoapi.o
-+
-+export-objs += ipsec_alg.o
-+
-+
-+LIBDESDIR=${KLIPS_TOP}/crypto/ciphers/des
-+VPATH+= ${LIBDESDIR}
-+
-+include ${LIBDESDIR}/Makefile.objs
-+
-+LIBFREESWANDIR=${KLIPS_TOP}/lib/libfreeswan
-+VPATH+=${LIBFREESWANDIR}
-+
-+include ${LIBFREESWANDIR}/Makefile.objs
-+
-+# IPcomp stuff
-+obj-$(CONFIG_IPSEC_IPCOMP) += ipcomp.o
-+
-+LIBZLIBSRCDIR=${KLIPS_TOP}/lib/zlib
-+VPATH+=${LIBZLIBSRCDIR}
-+
-+LIBAESDIR=$(KLIPS_TOP)/crypto/ciphers/aes
-+VPATH+=${LIBAESDIR}
-+include ${LIBAESDIR}/Makefile.objs
-+
-+# CFLAGS='$(CFLAGS)' \
-+# MODULE_CFLAGS='$(MODULE_CFLAGS)' KERNEL_CFLAGS='$(KERNEL_CFLAGS)' \
-+#
-+include ${LIBZLIBSRCDIR}/Makefile.objs
-+
-+export-objs := radij.o
-+
-+EXTRA_CFLAGS += $(ALGO_FLAGS)
-+
-+
-+# include file with .h-style macros that would otherwise be created by
-+# config. Must occur before other includes.
-+ifneq ($(strip $(MODULE_DEF_INCLUDE)),)
-+EXTRA_CFLAGS += -include ${MODULE_DEF_INCLUDE}
-+endif
-+
-+# 'override CFLAGS' should really be 'EXTRA_CFLAGS'
-+#EXTRA_CFLAGS += -nostdinc
-+EXTRA_CFLAGS += -I${KLIPS_TOP}/include
-+
-+EXTRA_CFLAGS += -I${TOPDIR}/include
-+EXTRA_CFLAGS += -I${LIBZLIBSRCDIR}
-+
-+ifeq ($(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION),2.4.2-2)
-+EXTRA_CFLAGS += -DREDHAT_BOGOSITY
-+endif
-+
-+ifeq ($(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION),2.4.3-12)
-+EXTRA_CFLAGS += -DREDHAT_BOGOSITY
-+endif
-+
-+
-+#ifeq ($(CONFIG_IPSEC_DEBUG),y)
-+#EXTRA_CFLAGS += -g
-+#endif
-+
-+#ifeq ($(CONFIG_IPSEC_ALG), y)
-+EXTRA_CFLAGS += -DCONFIG_IPSEC_ALG
-+#endif
-+# MOST of these flags are in KERNEL_CFLAGS already!
-+
-+EXTRA_CFLAGS += $(KLIPSCOMPILE)
-+EXTRA_CFLAGS += -Wall
-+#EXTRA_CFLAGS += -Werror
-+#EXTRA_CFLAGS += -Wconversion
-+#EXTRA_CFLAGS += -Wmissing-prototypes
-+# cannot use both -Wpointer-arith and -Werror with CONFIG_HIGHMEM
-+# include/linux/highmem.h has an inline function definition that uses void* arithmentic.
-+ifeq ($(CONFIG_NOHIGHMEM),y)
-+EXTRA_CFLAGS += -Wpointer-arith
-+endif
-+#EXTRA_CFLAGS += -Wcast-qual
-+#EXTRA_CFLAGS += -Wmissing-declarations
-+#EXTRA_CFLAGS += -Wstrict-prototypes
-+#EXTRA_CFLAGS += -pedantic
-+#EXTRA_CFLAGS += -O3
-+#EXTRA_CFLAGS += -W
-+#EXTRA_CFLAGS += -Wwrite-strings
-+#EXTRA_CFLAGS += -Wbad-function-cast
-+
-+ifneq ($(strip $(KLIPSMODULE)),)
-+# for when we aren't building in the kernel tree
-+EXTRA_CFLAGS += -DARCH=${ARCH}
-+EXTRA_CFLAGS += -DMODVERSIONS
-+EXTRA_CFLAGS += -include ${TOPDIR}/include/linux/modversions.h
-+EXTRA_CFLAGS += ${MODULE_CFLAGS}
-+endif
-+
-+EXTRA_CFLAGS += ${KERNEL_CFLAGS}
-+
-+#EXTRA_CFLAGS += -DRJ_DEBUG -DRJ_DEBUG2
-+
-+
-+# GCC 3.2 (and we presume any other 3.x) wants -falign-functions
-+# in place of the traditional -malign-functions. Getting this
-+# wrong leads to a warning, which is fatal due to our use of -Werror.
-+ifeq ($(patsubst 3.%,3,$(shell $(CC) -dumpversion)),3)
-+override CFLAGS:=$(subst -malign-functions=,-falign-functions=,$(CFLAGS))
-+endif
-+
-+
-+obj-$(CONFIG_IPSEC_AUTH_HMAC_MD5) += ipsec_md5c.o
-+obj-$(CONFIG_IPSEC_AUTH_HMAC_SHA1) += ipsec_sha1.o
-+
-+###
-+### Pre Rules.make
-+###
-+# undo O_TARGET, obj-y if no static
-+ifneq ($(CONFIG_IPSEC),y)
-+O_TARGET :=
-+ipsec_obj-y := $(obj-y)
-+obj-y :=
-+subdir-y :=
-+endif
-+
-+# Define obj-m if modular ipsec
-+ifeq ($(CONFIG_IPSEC),m)
-+obj-m += ipsec.o
-+endif
-+
-+
-+# These rules translate from new to old makefile rules
-+# Translate to Rules.make lists.
-+multi-used := $(filter $(list-multi), $(obj-y) $(obj-m))
-+multi-objs := $(foreach m, $(multi-used), $($(basename $(m))-objs))
-+active-objs := $(sort $(multi-objs) $(obj-y) $(obj-m))
-+O_OBJS := $(obj-y)
-+M_OBJS := $(obj-m)
-+MIX_OBJS := $(filter $(export-objs), $(active-objs))
-+OX_OBJS := $(export-objs)
-+SUB_DIRS := $(subdir-y)
-+ALL_SUB_DIRS := $(subdir-y) $(subdir-m)
-+MOD_SUB_DIRS := $(subdir-m)
-+
-+# dunno why, but some 2.2 setups may need explicit -DEXPORT_SYMTAB
-+# uncomment next line if ipsec_alg.c compilation fails with
-+# "parse error before `EXPORT_SYMTAB_not_defined'" --Juanjo
-+
-+include $(TOPDIR)/Rules.make
-+
-+###
-+### Post Rules.make
-+###
-+# for modular ipsec, no O_TARGET defined => define ipsec.o creation rules
-+ifeq ($(CONFIG_IPSEC),m)
-+ipsec.o : $(ipsec_obj-y)
-+ rm -f $@
-+ $(LD) $(LD_EXTRAFLAGS) -r $(ipsec_obj-y) -o $@
-+endif
-+
-+$(ipsec_obj-y) $(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
-+
-+#$(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h
-+
-+USE_STANDARD_AS_RULE=true
-+
-+clean:
-+ $(MAKE) -C alg clean
-+ -rm -f *.o
-+ -rm -f .*.o.flags
-+ -rm -f version.c
-+
-+tags TAGS: *.c *.h libfreeswan/*.c libfreeswan/*.h
-+ etags *.c ../../include/*.h ../../include/freeswan/*.h
-+ ctags *.c ../../include/*.h ../../include/freeswan/*.h
-+
-+tar:
-+ tar -cvf /dev/f1 .
-+
-+#
-+# $Log$
-+# Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+# Turn off EOLN_NATIVE flag
-+#
-+# (Logical change 1.5010)
-+#
-+# Revision 1.72 2004/06/22 14:44:07 ken
-+# Merge nice version of Nate's CryptoAPI patch
-+#
-+# Revision 1.71 2004/04/18 03:04:21 mcr
-+# removed duplicate version.o reference.
-+#
-+# Revision 1.70 2004/04/14 05:09:39 ken
-+# We need to link version.o
-+#
-+# Revision 1.69 2004/04/12 04:02:39 ken
-+# version.o no longer exists
-+#
-+# Revision 1.68 2004/04/11 17:08:41 mcr
-+# moved PASSTHROUGH definitions to openswan.h
-+# requirement for internal.h removed.
-+# version.c is now generated by patch at patch-time.
-+#
-+# Revision 1.67 2004/04/06 02:49:25 mcr
-+# pullup of algo code from alg-branch.
-+#
-+# Revision 1.66 2004/04/03 19:44:41 ken
-+# FREESWANSRCDIR -> OPENSWANSRCDIR (patch by folken)
-+#
-+# Revision 1.65 2004/02/09 16:22:07 paul
-+# Added -f to rm version.c in clean target to prevent bogus error
-+#
-+# Revision 1.64 2003/12/22 19:40:57 mcr
-+# NAT-T patches 0.6c.
-+#
-+# Revision 1.63 2003/12/13 19:10:21 mcr
-+# refactored rcv and xmit code - same as FS 2.05.
-+#
-+# Revision 1.62.4.2 2004/04/05 04:30:46 mcr
-+# patches for alg-branch to compile/work with 2.x openswan
-+#
-+# Revision 1.62.4.1 2003/12/22 15:25:52 jjo
-+# Merged algo-0.8.1-rc11-test1 into alg-branch
-+#
-+# Revision 1.62 2003/10/31 02:27:55 mcr
-+# pulled up port-selector patches and sa_id elimination.
-+#
-+# Revision 1.61.4.1 2003/10/29 01:30:41 mcr
-+# elimited "struct sa_id".
-+#
-+# Revision 1.61 2003/06/22 21:07:46 mcr
-+# adjusted TAGS target in makefile to be useful in 2.00 source layout.
-+#
-+# Revision 1.60 2003/05/03 23:45:23 mcr
-+# rm .o.flags and generated version.c file.
-+#
-+# Revision 1.59 2003/02/12 19:32:47 rgb
-+# Added ipsec_xmit to the list of object files.
-+#
-+# Revision 1.58 2003/01/03 00:36:44 rgb
-+#
-+# Added emacs compile-command.
-+#
-+# Revision 1.57 2002/11/08 23:49:53 mcr
-+# use KERNEL_CFLAGS and MODULE_CFLAGS to get proper list
-+# of include directories.
-+# This also eliminates some of the guesswork in the kernel
-+# configuration file.
-+#
-+# Revision 1.56 2002/11/08 23:23:18 mcr
-+# attempt to guess kernel compilation flags (i.e. list of -I)
-+# by using some magic targets in the kernel makefile.
-+#
-+# Revision 1.55 2002/11/08 10:13:33 mcr
-+# added additional include directories for module builds for 2.4.19.
-+#
-+# Revision 1.54 2002/10/20 06:10:30 build
-+# CONFIG_NOHIGHMEM for -Wpointer-arith RPM building issues.
-+#
-+# (elided rest of log)
-+#
-+# Local Variables:
-+# compile-command: "(cd ../../.. && source umlsetup.sh && make -C ${POOLSPACE} module/ipsec.o)"
-+# End Variables:
-+#
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/Config.alg_aes.in Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,3 @@
-+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
-+ tristate ' AES encryption algorithm' CONFIG_IPSEC_ALG_AES
-+fi
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/Config.alg_cryptoapi.in Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,6 @@
-+if [ "$CONFIG_IPSEC_ALG" = "y" ]; then
-+ dep_tristate ' CRYPTOAPI ciphers support (needs cryptoapi patch)' CONFIG_IPSEC_ALG_CRYPTOAPI $CONFIG_CRYPTO
-+ if [ "$CONFIG_IPSEC_ALG_CRYPTOAPI" != "n" ]; then
-+ bool ' CRYPTOAPI proprietary ciphers ' CONFIG_IPSEC_ALG_NON_LIBRE
-+ fi
-+fi
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/Config.in Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,3 @@
-+#Placeholder
-+source net/ipsec/alg/Config.alg_aes.in
-+source net/ipsec/alg/Config.alg_cryptoapi.in
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/Makefile Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,112 @@
-+# Makefile,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
-+ifeq ($(strip $(KLIPSMODULE)),)
-+FREESWANSRCDIR=.
-+else
-+FREESWANSRCDIR=../../../..
-+endif
-+ifeq ($(strip $(KLIPS_TOP)),)
-+KLIPS_TOP=../../..
-+override EXTRA_CFLAGS += -I$(KLIPS_TOP)/include
-+endif
-+
-+ifeq ($(CONFIG_IPSEC_DEBUG),y)
-+override EXTRA_CFLAGS += -g
-+endif
-+
-+# LIBCRYPTO normally comes as an argument from "parent" Makefile
-+# (this applies both to FS' "make module" and eg. Linux' "make modules"
-+# But make dep doest follow same evaluations, so we need this default:
-+LIBCRYPTO=$(TOPDIR)/lib/libcrypto
-+
-+override EXTRA_CFLAGS += -I$(LIBCRYPTO)/include
-+override EXTRA_CFLAGS += -Wall -Wpointer-arith -Wstrict-prototypes
-+
-+MOD_LIST_NAME := NET_MISC_MODULES
-+
-+#O_TARGET := static_init.o
-+
-+subdir- :=
-+subdir-n :=
-+subdir-y :=
-+subdir-m :=
-+
-+obj-y := static_init.o
-+
-+ARCH_ASM-y :=
-+ARCH_ASM-$(CONFIG_M586) := i586
-+ARCH_ASM-$(CONFIG_M586TSC) := i586
-+ARCH_ASM-$(CONFIG_M586MMX) := i586
-+ARCH_ASM-$(CONFIG_MK6) := i586
-+ARCH_ASM-$(CONFIG_M686) := i686
-+ARCH_ASM-$(CONFIG_MPENTIUMIII) := i686
-+ARCH_ASM-$(CONFIG_MPENTIUM4) := i686
-+ARCH_ASM-$(CONFIG_MK7) := i686
-+ARCH_ASM-$(CONFIG_MCRUSOE) := i586
-+ARCH_ASM-$(CONFIG_MWINCHIPC6) := i586
-+ARCH_ASM-$(CONFIG_MWINCHIP2) := i586
-+ARCH_ASM-$(CONFIG_MWINCHIP3D) := i586
-+ARCH_ASM-$(CONFIG_USERMODE) := i586
-+
-+ARCH_ASM :=$(ARCH_ASM-y)
-+ifdef NO_ASM
-+ARCH_ASM :=
-+endif
-+
-+# The algorithm makefiles may put dependences, short-circuit them
-+null:
-+
-+makefiles=$(filter-out %.preipsec, $(wildcard Makefile.alg_*))
-+ifneq ($(makefiles),)
-+#include Makefile.alg_aes
-+#include Makefile.alg_aes-opt
-+include $(makefiles)
-+endif
-+
-+# These rules translate from new to old makefile rules
-+# Translate to Rules.make lists.
-+multi-used := $(filter $(list-multi), $(obj-y) $(obj-m))
-+multi-objs := $(foreach m, $(multi-used), $($(basename $(m))-objs))
-+active-objs := $(sort $(multi-objs) $(obj-y) $(obj-m))
-+O_OBJS := $(obj-y)
-+M_OBJS := $(obj-m)
-+MIX_OBJS := $(filter $(export-objs), $(active-objs))
-+#OX_OBJS := $(export-objs)
-+SUB_DIRS := $(subdir-y)
-+ALL_SUB_DIRS := $(subdir-y) $(subdir-m)
-+MOD_SUB_DIRS := $(subdir-m)
-+
-+
-+static_init_mod.o: $(obj-y)
-+ rm -f $@
-+ $(LD) $(LD_EXTRAFLAGS) $(obj-y) -r -o $@
-+
-+perlasm: $(LIBCRYPTO)/perlasm
-+ ln -sf $? $@
-+
-+$(obj-y) $(obj-m): $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h
-+$(alg_obj-y) $(alg_obj-m): perlasm $(TOPDIR)/include/linux/config.h $(TOPDIR)/include/linux/autoconf.h $(KLIPS_TOP)/include/freeswan/ipsec_alg.h
-+
-+
-+all_alg_modules: perlasm $(ALG_MODULES)
-+ @echo "ALG_MODULES=$(ALG_MODULES)"
-+
-+
-+#
-+# Construct alg. init. function: call ipsec_ALGO_init() for every static algo
-+# Needed when there are static algos (with static or modular ipsec.o)
-+#
-+static_init.c: $(TOPDIR)/include/linux/autoconf.h Makefile $(makefiles) scripts/mk-static_init.c.sh
-+ @echo "Re-creating $@"
-+ $(SHELL) scripts/mk-static_init.c.sh $(static_init-func-y) > $@
-+
-+clean:
-+ @for i in $(ALG_SUBDIRS);do test -d $$i && make -C $$i clean;done;exit 0
-+ @find . -type l -exec rm -f {} \;
-+ -rm -f perlasm
-+ -rm -rf $(ALG_SUBDIRS)
-+ -rm -f *.o static_init.c
-+
-+ifdef TOPDIR
-+include $(TOPDIR)/Rules.make
-+endif
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/Makefile.alg_aes Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,23 @@
-+MOD_AES := ipsec_aes.o
-+
-+ALG_MODULES += $(MOD_AES)
-+ALG_SUBDIRS += libaes
-+
-+obj-$(CONFIG_IPSEC_ALG_AES) += $(MOD_AES)
-+static_init-func-$(CONFIG_IPSEC_ALG_AES)+= ipsec_aes_init
-+alg_obj-$(CONFIG_IPSEC_ALG_AES) += ipsec_alg_aes.o
-+
-+AES_OBJS := ipsec_alg_aes.o libaes/libaes.a
-+
-+$(MOD_AES): libaes $(AES_OBJS)
-+ $(LD) $(EXTRA_LDFLAGS) -r $(AES_OBJS) -o $@
-+
-+libaes: $(LIBCRYPTO)/libaes
-+ test -d $@ || mkdir $@ ;exit 0
-+ test -d $@/asm || mkdir $@/asm;exit 0
-+ cd $@ && ln -sf $?/Makefile $?/*.[chS] .
-+ cd $@/asm && ln -sf $?/asm/*.S .
-+
-+libaes/libaes.a: libaes
-+ ( cd libaes && \
-+ $(MAKE) CC='$(CC)' 'ARCH_ASM=$(ARCH_ASM)' CFLAGS='$(CFLAGS) $(EXTRA_CFLAGS)' libaes.a ;)
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/Makefile.alg_cryptoapi Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,14 @@
-+MOD_CRYPTOAPI := ipsec_cryptoapi.o
-+
-+ifneq ($(wildcard $(TOPDIR)/include/linux/crypto.h),)
-+ALG_MODULES += $(MOD_CRYPTOAPI)
-+obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += $(MOD_CRYPTOAPI)
-+static_init-func-$(CONFIG_IPSEC_ALG_CRYPTOAPI)+= ipsec_cryptoapi_init
-+alg_obj-$(CONFIG_IPSEC_ALG_CRYPTOAPI) += ipsec_alg_cryptoapi.o
-+else
-+$(warning "Linux CryptoAPI (2.4.22+ or 2.6.x) not found, not building ipsec_cryptoapi.o")
-+endif
-+
-+CRYPTOAPI_OBJS := ipsec_alg_cryptoapi.o
-+$(MOD_CRYPTOAPI): $(CRYPTOAPI_OBJS)
-+ $(LD) -r $(CRYPTOAPI_OBJS) -o $@
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/ipsec_alg_aes.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,253 @@
-+/*
-+ * ipsec_alg AES cipher stubs
-+ *
-+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
-+ *
-+ * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * Fixes by:
-+ * PK: Pawel Krawczyk <kravietz@aba.krakow.pl>
-+ * Fixes list:
-+ * PK: make XCBC comply with latest draft (keylength)
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+/*
-+ * special case: ipsec core modular with this static algo inside:
-+ * must avoid MODULE magic for this file
-+ */
-+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_AES
-+#undef MODULE
-+#endif
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+
-+#include <linux/kernel.h> /* printk() */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/string.h>
-+
-+/* Check if __exit is defined, if not null it */
-+#ifndef __exit
-+#define __exit
-+#endif
-+
-+/* Low freeswan header coupling */
-+#include "freeswan/ipsec_alg.h"
-+#include "libaes/aes_cbc.h"
-+
-+#define CONFIG_IPSEC_ALG_AES_MAC 1
-+
-+#define AES_CONTEXT_T aes_context
-+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
-+static int debug=0;
-+MODULE_PARM(debug, "i");
-+static int test=0;
-+MODULE_PARM(test, "i");
-+static int excl=0;
-+MODULE_PARM(excl, "i");
-+static int keyminbits=0;
-+MODULE_PARM(keyminbits, "i");
-+static int keymaxbits=0;
-+MODULE_PARM(keymaxbits, "i");
-+
-+#if CONFIG_IPSEC_ALG_AES_MAC
-+#include "libaes/aes_xcbc_mac.h"
-+
-+/*
-+ * Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt).
-+ * We use 9 for non-modular algorithm and none for modular, thus
-+ * forcing user to specify one on module load. -kravietz
-+ */
-+#ifdef MODULE
-+static int auth_id=0;
-+#else
-+static int auth_id=9;
-+#endif
-+MODULE_PARM(auth_id, "i");
-+#endif
-+
-+#define ESP_AES 12 /* truely _constant_ :) */
-+
-+/* 128, 192 or 256 */
-+#define ESP_AES_KEY_SZ_MIN 16 /* 128 bit secret key */
-+#define ESP_AES_KEY_SZ_MAX 32 /* 256 bit secret key */
-+#define ESP_AES_CBC_BLK_LEN 16 /* AES-CBC block size */
-+
-+/* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt
-+ * -kravietz
-+ */
-+#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
-+#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
-+
-+static int _aes_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) {
-+ int ret;
-+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
-+ ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL;
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:_aes_set_key:"
-+ "ret=%d key_e=%p key=%p keysize=%d\n",
-+ ret, key_e, key, keysize);
-+ return ret;
-+}
-+static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
-+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
-+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
-+ key_e, in, ilen, iv, encrypt);
-+ return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt);
-+}
-+#if CONFIG_IPSEC_ALG_AES_MAC
-+static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) {
-+ aes_context_mac *ctxm=(aes_context_mac *)key_a;
-+ return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL;
-+}
-+static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) {
-+ int ret;
-+ char hash_buf[16];
-+ aes_context_mac *ctxm=(aes_context_mac *)key_a;
-+ ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf);
-+ memcpy(hash, hash_buf, hashlen);
-+ return ret;
-+}
-+static struct ipsec_alg_auth ipsec_alg_AES_MAC = {
-+ ixt_version: IPSEC_ALG_VERSION,
-+ ixt_module: THIS_MODULE,
-+ ixt_refcnt: ATOMIC_INIT(0),
-+ ixt_alg_type: IPSEC_ALG_TYPE_AUTH,
-+ ixt_alg_id: 0,
-+ ixt_name: "aes_mac",
-+ ixt_blocksize: ESP_AES_MAC_BLK_LEN,
-+ ixt_keyminbits: ESP_AES_MAC_KEY_SZ*8,
-+ ixt_keymaxbits: ESP_AES_MAC_KEY_SZ*8,
-+ ixt_a_keylen: ESP_AES_MAC_KEY_SZ,
-+ ixt_a_ctx_size: sizeof(aes_context_mac),
-+ ixt_a_hmac_set_key: _aes_mac_set_key,
-+ ixt_a_hmac_hash:_aes_mac_hash,
-+};
-+#endif /* CONFIG_IPSEC_ALG_AES_MAC */
-+static struct ipsec_alg_enc ipsec_alg_AES = {
-+ ixt_version: IPSEC_ALG_VERSION,
-+ ixt_module: THIS_MODULE,
-+ ixt_refcnt: ATOMIC_INIT(0),
-+ ixt_alg_type: IPSEC_ALG_TYPE_ENCRYPT,
-+ ixt_alg_id: ESP_AES,
-+ ixt_name: "aes",
-+ ixt_blocksize: ESP_AES_CBC_BLK_LEN,
-+ ixt_keyminbits: ESP_AES_KEY_SZ_MIN*8,
-+ ixt_keymaxbits: ESP_AES_KEY_SZ_MAX*8,
-+ ixt_e_keylen: ESP_AES_KEY_SZ_MAX,
-+ ixt_e_ctx_size: sizeof(AES_CONTEXT_T),
-+ ixt_e_set_key: _aes_set_key,
-+ ixt_e_cbc_encrypt:_aes_cbc_encrypt,
-+};
-+
-+IPSEC_ALG_MODULE_INIT( ipsec_aes_init )
-+{
-+ int ret, test_ret;
-+ if (keyminbits)
-+ ipsec_alg_AES.ixt_keyminbits=keyminbits;
-+ if (keymaxbits) {
-+ ipsec_alg_AES.ixt_keymaxbits=keymaxbits;
-+ if (keymaxbits*8>ipsec_alg_AES.ixt_keymaxbits)
-+ ipsec_alg_AES.ixt_e_keylen=keymaxbits*8;
-+ }
-+ if (excl) ipsec_alg_AES.ixt_state |= IPSEC_ALG_ST_EXCL;
-+ ret=register_ipsec_alg_enc(&ipsec_alg_AES);
-+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
-+ ipsec_alg_AES.ixt_alg_type,
-+ ipsec_alg_AES.ixt_alg_id,
-+ ipsec_alg_AES.ixt_name,
-+ ret);
-+ if (ret==0 && test) {
-+ test_ret=ipsec_alg_test(
-+ ipsec_alg_AES.ixt_alg_type,
-+ ipsec_alg_AES.ixt_alg_id,
-+ test);
-+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
-+ ipsec_alg_AES.ixt_alg_type,
-+ ipsec_alg_AES.ixt_alg_id,
-+ test_ret);
-+ }
-+#if CONFIG_IPSEC_ALG_AES_MAC
-+ if (auth_id!=0){
-+ int ret;
-+ ipsec_alg_AES_MAC.ixt_alg_id=auth_id;
-+ ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC);
-+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
-+ ipsec_alg_AES_MAC.ixt_alg_type,
-+ ipsec_alg_AES_MAC.ixt_alg_id,
-+ ipsec_alg_AES_MAC.ixt_name,
-+ ret);
-+ if (ret==0 && test) {
-+ test_ret=ipsec_alg_test(
-+ ipsec_alg_AES_MAC.ixt_alg_type,
-+ ipsec_alg_AES_MAC.ixt_alg_id,
-+ test);
-+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
-+ ipsec_alg_AES_MAC.ixt_alg_type,
-+ ipsec_alg_AES_MAC.ixt_alg_id,
-+ test_ret);
-+ }
-+ } else {
-+ printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id);
-+ }
-+#endif /* CONFIG_IPSEC_ALG_AES_MAC */
-+ return ret;
-+}
-+IPSEC_ALG_MODULE_EXIT( ipsec_aes_fini )
-+{
-+#if CONFIG_IPSEC_ALG_AES_MAC
-+ if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC);
-+#endif /* CONFIG_IPSEC_ALG_AES_MAC */
-+ unregister_ipsec_alg_enc(&ipsec_alg_AES);
-+ return;
-+}
-+#ifdef MODULE_LICENSE
-+MODULE_LICENSE("GPL");
-+#endif
-+
-+#if 0+NOT_YET
-+#ifndef MODULE
-+/*
-+ * This is intended for static module setups, currently
-+ * doesn't work for modular ipsec.o with static algos inside
-+ */
-+static int setup_keybits(const char *str)
-+{
-+ unsigned aux;
-+ char *end;
-+
-+ aux = simple_strtoul(str,&end,0);
-+ if (aux != 128 && aux != 192 && aux != 256)
-+ return 0;
-+ keyminbits = aux;
-+
-+ if (*end == 0 || *end != ',')
-+ return 1;
-+ str=end+1;
-+ aux = simple_strtoul(str, NULL, 0);
-+ if (aux != 128 && aux != 192 && aux != 256)
-+ return 0;
-+ if (aux >= keyminbits)
-+ keymaxbits = aux;
-+ return 1;
-+}
-+__setup("ipsec_aes_keybits=", setup_keybits);
-+#endif
-+#endif
-+EXPORT_NO_SYMBOLS;
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,421 @@
-+/*
-+ * ipsec_alg to linux cryptoapi GLUE
-+ *
-+ * Authors: CODE.ar TEAM
-+ * Harpo MAxx <harpo@linuxmendoza.org.ar>
-+ * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
-+ * Luciano Ruete <docemeses@softhome.net>
-+ *
-+ * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * Example usage:
-+ * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
-+ * modprobe ipsec_cryptoapi
-+ * modprobe ipsec_cryptoapi test=1
-+ * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
-+ * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
-+ * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
-+ * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
-+ */
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+/*
-+ * special case: ipsec core modular with this static algo inside:
-+ * must avoid MODULE magic for this file
-+ */
-+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI
-+#undef MODULE
-+#endif
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+
-+#include <linux/kernel.h> /* printk() */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/string.h>
-+
-+/* Check if __exit is defined, if not null it */
-+#ifndef __exit
-+#define __exit
-+#endif
-+
-+/* warn the innocent */
-+#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
-+#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"
-+#define NO_CRYPTOAPI_SUPPORT
-+#endif
-+/* Low freeswan header coupling */
-+#include "freeswan/ipsec_alg.h"
-+
-+#include <linux/crypto.h>
-+#ifdef CRYPTO_API_VERSION_CODE
-+#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
-+#define NO_CRYPTOAPI_SUPPORT
-+#endif
-+
-+#ifdef NO_CRYPTOAPI_SUPPORT
-+#warning "Building an unusable module :P"
-+/* Catch old CryptoAPI by not allowing module to load */
-+IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
-+{
-+ printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
-+ return -EINVAL;
-+}
-+#else
-+#include <asm/scatterlist.h>
-+#include <asm/pgtable.h>
-+#include <linux/mm.h>
-+
-+#define CIPHERNAME_AES "aes"
-+#define CIPHERNAME_3DES "des3_ede"
-+#define CIPHERNAME_BLOWFISH "blowfish"
-+#define CIPHERNAME_CAST "cast5"
-+#define CIPHERNAME_SERPENT "serpent"
-+#define CIPHERNAME_TWOFISH "twofish"
-+
-+#define ESP_3DES 3
-+#define ESP_AES 12
-+#define ESP_BLOWFISH 7 /* truely _constant_ :) */
-+#define ESP_CAST 6 /* quite constant :) */
-+#define ESP_SERPENT 252 /* from ipsec drafts */
-+#define ESP_TWOFISH 253 /* from ipsec drafts */
-+
-+#define AH_MD5 2
-+#define AH_SHA 3
-+#define DIGESTNAME_MD5 "md5"
-+#define DIGESTNAME_SHA1 "sha1"
-+
-+MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
-+static int debug=0;
-+MODULE_PARM(debug, "i");
-+static int test=0;
-+MODULE_PARM(test, "i");
-+static int excl=0;
-+MODULE_PARM(excl, "i");
-+
-+static int noauto = 0;
-+MODULE_PARM(noauto,"i");
-+MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
-+
-+static int des_ede3[] = {-1, -1};
-+static int aes[] = {-1, -1};
-+static int blowfish[] = {-1, -1};
-+static int cast[] = {-1, -1};
-+static int serpent[] = {-1, -1};
-+static int twofish[] = {-1, -1};
-+
-+MODULE_PARM(des_ede3,"1-2i");
-+MODULE_PARM(aes,"1-2i");
-+MODULE_PARM(blowfish,"1-2i");
-+MODULE_PARM(cast,"1-2i");
-+MODULE_PARM(serpent,"1-2i");
-+MODULE_PARM(twofish,"1-2i");
-+MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
-+MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
-+MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
-+MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
-+MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
-+MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
-+
-+struct ipsec_alg_capi_cipher {
-+ const char *ciphername; /* cryptoapi's ciphername */
-+ unsigned blocksize;
-+ unsigned short minbits;
-+ unsigned short maxbits;
-+ int *parm; /* lkm param for this cipher */
-+ struct ipsec_alg_enc alg; /* note it's not a pointer */
-+};
-+static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
-+ { CIPHERNAME_AES , 16, 128, 256, aes , { ixt_alg_id: ESP_AES, }},
-+ { CIPHERNAME_TWOFISH , 16, 128, 256, twofish, { ixt_alg_id: ESP_TWOFISH, }},
-+ { CIPHERNAME_SERPENT , 16, 128, 256, serpent, { ixt_alg_id: ESP_SERPENT, }},
-+ { CIPHERNAME_CAST , 8, 128, 128, cast , { ixt_alg_id: ESP_CAST, }},
-+ { CIPHERNAME_BLOWFISH , 8, 96, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }},
-+ { CIPHERNAME_3DES , 8, 192, 192, des_ede3,{ ixt_alg_id: ESP_3DES, }},
-+ { NULL, 0, 0, 0, NULL, {} }
-+};
-+#ifdef NOT_YET
-+struct ipsec_alg_capi_digest {
-+ const char *digestname; /* cryptoapi's digestname */
-+ struct digest_implementation *di;
-+ struct ipsec_alg_auth alg; /* note it's not a pointer */
-+};
-+static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
-+ { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
-+ { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
-+ { NULL, NULL, {} }
-+};
-+#endif
-+/*
-+ * "generic" linux cryptoapi setup_cipher() function
-+ */
-+int setup_cipher(const char *ciphername)
-+{
-+ return crypto_alg_available(ciphername, 0);
-+}
-+
-+/*
-+ * setups ipsec_alg_capi_cipher "hyper" struct components, calling
-+ * register_ipsec_alg for cointaned ipsec_alg object
-+ */
-+static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
-+static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
-+static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
-+
-+static int
-+setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
-+{
-+ int ret;
-+ cptr->alg.ixt_version = IPSEC_ALG_VERSION;
-+ cptr->alg.ixt_module = THIS_MODULE;
-+ atomic_set (& cptr->alg.ixt_refcnt, 0);
-+ strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name));
-+
-+ cptr->alg.ixt_blocksize=cptr->blocksize;
-+ cptr->alg.ixt_keyminbits=cptr->minbits;
-+ cptr->alg.ixt_keymaxbits=cptr->maxbits;
-+ cptr->alg.ixt_state = 0;
-+ if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL;
-+ cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8;
-+ cptr->alg.ixt_e_ctx_size = 0;
-+ cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT;
-+ cptr->alg.ixt_e_new_key = _capi_new_key;
-+ cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
-+ cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
-+ cptr->alg.ixt_data = cptr;
-+
-+ ret=register_ipsec_alg_enc(&cptr->alg);
-+ printk("setup_ipsec_alg_capi_cipher(): "
-+ "alg_type=%d alg_id=%d name=%s "
-+ "keyminbits=%d keymaxbits=%d, ret=%d\n",
-+ cptr->alg.ixt_alg_type,
-+ cptr->alg.ixt_alg_id,
-+ cptr->alg.ixt_name,
-+ cptr->alg.ixt_keyminbits,
-+ cptr->alg.ixt_keymaxbits,
-+ ret);
-+ return ret;
-+}
-+/*
-+ * called in ipsec_sa_wipe() time, will destroy key contexts
-+ * and do 1 unbind()
-+ */
-+static void
-+_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
-+{
-+ struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
-+
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
-+ "name=%s key_e=%p \n",
-+ alg->ixt_name, key_e);
-+ if (!key_e) {
-+ printk(KERN_ERR "klips_debug: _capi_destroy_key:"
-+ "name=%s NULL key_e!\n",
-+ alg->ixt_name);
-+ return;
-+ }
-+ crypto_free_tfm(tfm);
-+}
-+
-+/*
-+ * create new key context, need alg->ixt_data to know which
-+ * (of many) cipher inside this module is the target
-+ */
-+static __u8 *
-+_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
-+{
-+ struct ipsec_alg_capi_cipher *cptr;
-+ struct crypto_tfm *tfm=NULL;
-+
-+ cptr = alg->ixt_data;
-+ if (!cptr) {
-+ printk(KERN_ERR "_capi_new_key(): "
-+ "NULL ixt_data (?!) for \"%s\" algo\n"
-+ , alg->ixt_name);
-+ goto err;
-+ }
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
-+ "name=%s cptr=%p key=%p keysize=%d\n",
-+ alg->ixt_name, cptr, key, keylen);
-+
-+ /*
-+ * alloc tfm
-+ */
-+ tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);
-+ if (!tfm) {
-+ printk(KERN_ERR "_capi_new_key(): "
-+ "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
-+ , alg->ixt_name, cptr->ciphername);
-+ goto err;
-+ }
-+ if (crypto_cipher_setkey(tfm, key, keylen) < 0) {
-+ printk(KERN_ERR "_capi_new_key(): "
-+ "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
-+ , alg->ixt_name, keylen);
-+ crypto_free_tfm(tfm);
-+ tfm=NULL;
-+ }
-+err:
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
-+ "name=%s key=%p keylen=%d tfm=%p\n",
-+ alg->ixt_name, key, keylen, tfm);
-+ return (__u8 *) tfm;
-+}
-+/*
-+ * core encryption function: will use cx->ci to call actual cipher's
-+ * cbc function
-+ */
-+static int
-+_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
-+ int error =0;
-+ struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
-+ struct scatterlist sg = {
-+ .page = virt_to_page(in),
-+ .offset = (unsigned long)(in) % PAGE_SIZE,
-+ .length=ilen,
-+ };
-+ if (debug > 1)
-+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
-+ "key_e=%p "
-+ "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
-+ , key_e
-+ , in, in, ilen, iv, encrypt);
-+ crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));
-+ if (encrypt)
-+ error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);
-+ else
-+ error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);
-+ if (debug > 1)
-+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
-+ "error=%d\n"
-+ , error);
-+ return (error<0)? error : ilen;
-+}
-+/*
-+ * main initialization loop: for each cipher in list, do
-+ * 1) setup cryptoapi cipher else continue
-+ * 2) register ipsec_alg object
-+ */
-+static int
-+setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
-+{
-+ struct ipsec_alg_capi_cipher *cptr;
-+ /* foreach cipher in list ... */
-+ for (cptr=clist;cptr->ciphername;cptr++) {
-+ /*
-+ * see if cipher has been disabled (0) or
-+ * if noauto set and not enabled (1)
-+ */
-+ if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
-+ if (debug>0)
-+ printk(KERN_INFO "setup_cipher_list(): "
-+ "ciphername=%s skipped at user request: "
-+ "noauto=%d parm[0]=%d parm[1]=%d\n"
-+ , cptr->ciphername
-+ , noauto
-+ , cptr->parm[0]
-+ , cptr->parm[1]);
-+ continue;
-+ }
-+ /*
-+ * use a local ci to avoid touching cptr->ci,
-+ * if register ipsec_alg success then bind cipher
-+ */
-+ if( setup_cipher(cptr->ciphername) ) {
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:"
-+ "setup_cipher_list():"
-+ "ciphername=%s found\n"
-+ , cptr->ciphername);
-+ if (setup_ipsec_alg_capi_cipher(cptr) == 0) {
-+
-+
-+ } else {
-+ printk(KERN_ERR "klips_debug:"
-+ "setup_cipher_list():"
-+ "ciphername=%s failed ipsec_alg_register\n"
-+ , cptr->ciphername);
-+ }
-+ } else {
-+ if (debug>0)
-+ printk(KERN_INFO "setup_cipher_list(): lookup for ciphername=%s: not found \n",
-+ cptr->ciphername);
-+ }
-+ }
-+ return 0;
-+}
-+/*
-+ * deregister ipsec_alg objects and unbind ciphers
-+ */
-+static int
-+unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
-+{
-+ struct ipsec_alg_capi_cipher *cptr;
-+ /* foreach cipher in list ... */
-+ for (cptr=clist;cptr->ciphername;cptr++) {
-+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
-+ unregister_ipsec_alg_enc(&cptr->alg);
-+ }
-+ }
-+ return 0;
-+}
-+/*
-+ * test loop for registered algos
-+ */
-+static int
-+test_cipher_list (struct ipsec_alg_capi_cipher* clist)
-+{
-+ int test_ret;
-+ struct ipsec_alg_capi_cipher *cptr;
-+ /* foreach cipher in list ... */
-+ for (cptr=clist;cptr->ciphername;cptr++) {
-+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
-+ test_ret=ipsec_alg_test(
-+ cptr->alg.ixt_alg_type,
-+ cptr->alg.ixt_alg_id,
-+ test);
-+ printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
-+ cptr->alg.ixt_alg_type,
-+ cptr->alg.ixt_alg_id,
-+ test_ret);
-+ }
-+ }
-+ return 0;
-+}
-+
-+IPSEC_ALG_MODULE_INIT( ipsec_cryptoapi_init )
-+{
-+ int ret, test_ret;
-+ if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
-+ return -EPROTONOSUPPORT;
-+ if (ret==0 && test) {
-+ test_ret=test_cipher_list(alg_capi_carray);
-+ }
-+ return ret;
-+}
-+IPSEC_ALG_MODULE_EXIT( ipsec_cryptoapi_fini )
-+{
-+ unsetup_cipher_list(alg_capi_carray);
-+ return;
-+}
-+#ifdef MODULE_LICENSE
-+MODULE_LICENSE("GPL");
-+#endif
-+
-+EXPORT_NO_SYMBOLS;
-+#endif /* NO_CRYPTOAPI_SUPPORT */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/alg/scripts/mk-static_init.c.sh Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,18 @@
-+#!/bin/sh
-+cat << EOF
-+#include <linux/kernel.h>
-+#include <linux/list.h>
-+#include "freeswan/ipsec_alg.h"
-+$(for i in $*; do
-+ test -z "$i" && continue
-+ echo "extern int $i(void);"
-+done)
-+void ipsec_alg_static_init(void){
-+ int __attribute__ ((unused)) err=0;
-+$(for i in $*; do
-+ test -z "$i" && continue
-+ echo " if ((err=$i()) < 0)"
-+ echo " printk(KERN_WARNING \"$i() returned %d\", err);"
-+done)
-+}
-+EOF
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/defconfig Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,146 @@
-+
-+#
-+# RCSID $Id$
-+#
-+
-+#
-+# FreeS/WAN IPSec implementation, KLIPS kernel config defaults
-+#
-+
-+#
-+# First, lets override stuff already set or not in the kernel config.
-+#
-+# We can't even think about leaving this off...
-+CONFIG_INET=y
-+
-+#
-+# This must be on for subnet protection.
-+CONFIG_IP_FORWARD=y
-+
-+# Shut off IPSEC masquerading if it has been enabled, since it will
-+# break the compile. IPPROTO_ESP and IPPROTO_AH were included in
-+# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h.
-+CONFIG_IP_MASQUERADE_IPSEC=n
-+
-+#
-+# Next, lets set the recommended FreeS/WAN configuration.
-+#
-+
-+# To config as static (preferred), 'y'. To config as module, 'm'.
-+CONFIG_IPSEC=y
-+
-+# To do tunnel mode IPSec, this must be enabled.
-+CONFIG_IPSEC_IPIP=y
-+
-+# To enable authentication, say 'y'. (Highly recommended)
-+CONFIG_IPSEC_AH=y
-+
-+# Authentication algorithm(s):
-+CONFIG_IPSEC_AUTH_HMAC_MD5=y
-+CONFIG_IPSEC_AUTH_HMAC_SHA1=y
-+
-+# To enable encryption, say 'y'. (Highly recommended)
-+CONFIG_IPSEC_ESP=y
-+
-+# Encryption algorithm(s):
-+CONFIG_IPSEC_ENC_3DES=y
-+CONFIG_IPSEC_ENC_AES=y
-+
-+# modular algo extensions (and new ALGOs)
-+CONFIG_IPSEC_ALG=y
-+CONFIG_IPSEC_ENC_3DES=y
-+CONFIG_IPSEC_ENC_AES=y
-+
-+CONFIG_IPSEC_ALG_TWOFISH=m
-+CONFIG_IPSEC_ALG_BLOWFISH=m
-+CONFIG_IPSEC_ALG_SERPENT=m
-+CONFIG_IPSEC_ALG_MD5=m
-+CONFIG_IPSEC_ALG_SHA1=m
-+CONFIG_IPSEC_ALG_SHA2=m
-+#CONFIG_IPSEC_ALG_CAST=n
-+#CONFIG_IPSEC_ALG_NULL=n
-+
-+# Use CryptoAPI for ALG? - by default, no.
-+CONFIG_IPSEC_ENC_CRYPTOAPI=n
-+
-+
-+# IP Compression: new, probably still has minor bugs.
-+CONFIG_IPSEC_IPCOMP=y
-+
-+# To enable userspace-switchable KLIPS debugging, say 'y'.
-+CONFIG_IPSEC_DEBUG=y
-+
-+# NAT Traversal
-+CONFIG_IPSEC_NAT_TRAVERSAL=y
-+
-+#
-+#
-+# $Log$
-+# Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+# Turn off EOLN_NATIVE flag
-+#
-+# (Logical change 1.5010)
-+#
-+# Revision 1.25 2004/07/05 01:03:53 mcr
-+# fix for adding cryptoapi code.
-+# keep it off for now, since UMLs do not have it yet.
-+#
-+# Revision 1.24 2004/04/06 02:49:25 mcr
-+# pullup of algo code from alg-branch.
-+#
-+# Revision 1.23.2.2 2004/04/05 04:30:46 mcr
-+# patches for alg-branch to compile/work with 2.x openswan
-+#
-+# Revision 1.23.2.1 2003/12/22 15:25:52 jjo
-+# . Merged algo-0.8.1-rc11-test1 into alg-branch
-+#
-+# Revision 1.23 2003/12/10 01:14:27 mcr
-+# NAT-traversal patches to KLIPS.
-+#
-+# Revision 1.22 2003/02/24 19:37:27 mcr
-+# changed default compilation mode to static.
-+#
-+# Revision 1.21 2002/04/24 07:36:27 mcr
-+# Moved from ./klips/net/ipsec/defconfig,v
-+#
-+# Revision 1.20 2002/04/02 04:07:40 mcr
-+# default build is now 'm'odule for KLIPS
-+#
-+# Revision 1.19 2002/03/08 18:57:17 rgb
-+# Added a blank line at the beginning of the file to make it easier for
-+# other projects to patch ./arch/i386/defconfig, for example
-+# LIDS+grSecurity requested by Jason Pattie.
-+#
-+# Revision 1.18 2000/11/30 17:26:56 rgb
-+# Cleaned out unused options and enabled ipcomp by default.
-+#
-+# Revision 1.17 2000/09/15 11:37:01 rgb
-+# Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
-+# IPCOMP zlib deflate code.
-+#
-+# Revision 1.16 2000/09/08 19:12:55 rgb
-+# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+#
-+# Revision 1.15 2000/05/24 19:37:13 rgb
-+# *** empty log message ***
-+#
-+# Revision 1.14 2000/05/11 21:14:57 henry
-+# just commenting the FOOBAR=y lines out is not enough
-+#
-+# Revision 1.13 2000/05/10 20:17:58 rgb
-+# Comment out netlink defaults, which are no longer needed.
-+#
-+# Revision 1.12 2000/05/10 19:13:38 rgb
-+# Added configure option to shut off no eroute passthrough.
-+#
-+# Revision 1.11 2000/03/16 07:09:46 rgb
-+# Hardcode PF_KEYv2 support.
-+# Disable IPSEC_ICMP by default.
-+# Remove DES config option from defaults file.
-+#
-+# Revision 1.10 2000/01/11 03:09:42 rgb
-+# Added a default of 'y' to PF_KEYv2 keying I/F.
-+#
-+# Revision 1.9 1999/05/08 21:23:12 rgb
-+# Added support for 2.2.x kernels.
-+#
-+# Revision 1.8 1999/04/06 04:54:25 rgb
-+# Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+# patch shell fixes.
-+#
-+#
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipcomp.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,725 @@
-+/*
-+ * IPCOMP zlib interface code.
-+ * Copyright (C) 2000 Svenning Soerensen <svenning@post5.tele.dk>
-+ * Copyright (C) 2000, 2001 Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipcomp_c_version[] = "RCSID $Id$";
-+
-+/* SSS */
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h>
-+#include <linux/netdevice.h>
-+#include <linux/ip.h>
-+#include <linux/skbuff.h>
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+
-+#include <openswan.h>
-+
-+#ifdef NET_21
-+# include <net/dst.h>
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define proto_priv cb
-+#endif /* NET21 */
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h" /* sysctl_ipsec_inbound_policy_check */
-+#include "openswan/ipcomp.h"
-+#include "zlib/zlib.h"
-+#include "zlib/zutil.h"
-+
-+#include <pfkeyv2.h> /* SADB_X_CALG_DEFLATE */
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int sysctl_ipsec_debug_ipcomp = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+static
-+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask);
-+
-+static
-+voidpf my_zcalloc(voidpf opaque, uInt items, uInt size)
-+{
-+ return (voidpf) kmalloc(items*size, GFP_ATOMIC);
-+}
-+
-+static
-+void my_zfree(voidpf opaque, voidpf address)
-+{
-+ kfree(address);
-+}
-+
-+struct sk_buff *skb_compress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
-+{
-+ struct iphdr *iph;
-+ unsigned int iphlen, pyldsz, cpyldsz;
-+ unsigned char *buffer;
-+ z_stream zs;
-+ int zresult;
-+
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: .\n");
-+
-+ if(skb == NULL) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "passed in NULL skb, returning ERROR.\n");
-+ if(flags != NULL) {
-+ *flags |= IPCOMP_PARMERROR;
-+ }
-+ return skb;
-+ }
-+
-+ if(ips == NULL) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "passed in NULL ipsec_sa needed for cpi, returning ERROR.\n");
-+ if(flags) {
-+ *flags |= IPCOMP_PARMERROR;
-+ }
-+ return skb;
-+ }
-+
-+ if (flags == NULL) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "passed in NULL flags, returning ERROR.\n");
-+ ipsec_kfree_skb(skb);
-+ return NULL;
-+ }
-+
-+#ifdef NET_21
-+ iph = skb->nh.iph;
-+#else /* NET_21 */
-+ iph = skb->ip_hdr;
-+#endif /* NET_21 */
-+
-+ switch (iph->protocol) {
-+ case IPPROTO_COMP:
-+ case IPPROTO_AH:
-+ case IPPROTO_ESP:
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "skipping compression of packet with ip protocol %d.\n",
-+ iph->protocol);
-+ *flags |= IPCOMP_UNCOMPRESSABLE;
-+ return skb;
-+ }
-+
-+ /* Don't compress packets already fragmented */
-+ if (iph->frag_off & __constant_htons(IP_MF | IP_OFFSET)) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "skipping compression of fragmented packet.\n");
-+ *flags |= IPCOMP_UNCOMPRESSABLE;
-+ return skb;
-+ }
-+
-+ iphlen = iph->ihl << 2;
-+ pyldsz = ntohs(iph->tot_len) - iphlen;
-+
-+ /* Don't compress less than 90 bytes (rfc 2394) */
-+ if (pyldsz < 90) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "skipping compression of tiny packet, len=%d.\n",
-+ pyldsz);
-+ *flags |= IPCOMP_UNCOMPRESSABLE;
-+ return skb;
-+ }
-+
-+ /* Adaptive decision */
-+ if (ips->ips_comp_adapt_skip) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "skipping compression: ips_comp_adapt_skip=%d.\n",
-+ ips->ips_comp_adapt_skip);
-+ ips->ips_comp_adapt_skip--;
-+ *flags |= IPCOMP_UNCOMPRESSABLE;
-+ return skb;
-+ }
-+
-+ zs.zalloc = my_zcalloc;
-+ zs.zfree = my_zfree;
-+ zs.opaque = 0;
-+
-+ /* We want to use deflateInit2 because we don't want the adler
-+ header. */
-+ zresult = deflateInit2(&zs, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -11,
-+ DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY);
-+ if (zresult != Z_OK) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_compress: "
-+ "deflateInit2() returned error %d (%s), "
-+ "skipping compression.\n",
-+ zresult,
-+ zs.msg ? zs.msg : zError(zresult));
-+ *flags |= IPCOMP_COMPRESSIONERROR;
-+ return skb;
-+ }
-+
-+
-+ /* Max output size. Result should be max this size.
-+ * Implementation specific tweak:
-+ * If it's not at least 32 bytes and 6.25% smaller than
-+ * the original packet, it's probably not worth wasting
-+ * the receiver's CPU cycles decompressing it.
-+ * Your mileage may vary.
-+ */
-+ cpyldsz = pyldsz - sizeof(struct ipcomphdr) - (pyldsz <= 512 ? 32 : pyldsz >> 4);
-+
-+ buffer = kmalloc(cpyldsz, GFP_ATOMIC);
-+ if (!buffer) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_compress: "
-+ "unable to kmalloc(%d, GFP_ATOMIC), "
-+ "skipping compression.\n",
-+ cpyldsz);
-+ *flags |= IPCOMP_COMPRESSIONERROR;
-+ deflateEnd(&zs);
-+ return skb;
-+ }
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
-+ __u8 *c;
-+ int i;
-+
-+ c = (__u8*)iph + iphlen;
-+ for(i = 0; i < pyldsz; i++, c++) {
-+ if(!(i % 16)) {
-+ printk(KERN_INFO "skb_compress: before:");
-+ }
-+ printk("%02x ", *c);
-+ if(!((i + 1) % 16)) {
-+ printk("\n");
-+ }
-+ }
-+ if(i % 16) {
-+ printk("\n");
-+ }
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ zs.next_in = (char *) iph + iphlen; /* start of payload */
-+ zs.avail_in = pyldsz;
-+ zs.next_out = buffer; /* start of compressed payload */
-+ zs.avail_out = cpyldsz;
-+
-+ /* Finish compression in one step */
-+ zresult = deflate(&zs, Z_FINISH);
-+
-+ /* Free all dynamically allocated buffers */
-+ deflateEnd(&zs);
-+ if (zresult != Z_STREAM_END) {
-+ *flags |= IPCOMP_UNCOMPRESSABLE;
-+ kfree(buffer);
-+
-+ /* Adjust adaptive counters */
-+ if (++(ips->ips_comp_adapt_tries) == IPCOMP_ADAPT_INITIAL_TRIES) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "first %d packets didn't compress, "
-+ "skipping next %d\n",
-+ IPCOMP_ADAPT_INITIAL_TRIES,
-+ IPCOMP_ADAPT_INITIAL_SKIP);
-+ ips->ips_comp_adapt_skip = IPCOMP_ADAPT_INITIAL_SKIP;
-+ }
-+ else if (ips->ips_comp_adapt_tries == IPCOMP_ADAPT_INITIAL_TRIES + IPCOMP_ADAPT_SUBSEQ_TRIES) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "next %d packets didn't compress, "
-+ "skipping next %d\n",
-+ IPCOMP_ADAPT_SUBSEQ_TRIES,
-+ IPCOMP_ADAPT_SUBSEQ_SKIP);
-+ ips->ips_comp_adapt_skip = IPCOMP_ADAPT_SUBSEQ_SKIP;
-+ ips->ips_comp_adapt_tries = IPCOMP_ADAPT_INITIAL_TRIES;
-+ }
-+
-+ return skb;
-+ }
-+
-+ /* resulting compressed size */
-+ cpyldsz -= zs.avail_out;
-+
-+ /* Insert IPCOMP header */
-+ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_nh = iph->protocol;
-+ ((struct ipcomphdr*) ((char*) iph + iphlen))->ipcomp_flags = 0;
-+ /* use the bottom 16 bits of the spi for the cpi. The top 16 bits are
-+ for internal reference only. */
-+ ((struct ipcomphdr*) (((char*)iph) + iphlen))->ipcomp_cpi = htons((__u16)(ntohl(ips->ips_said.spi) & 0x0000ffff));
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_compress: "
-+ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: raw=%d, comp=%d.\n",
-+ ntohl(ips->ips_said.spi),
-+ ntohl(ips->ips_said.spi) & 0x0000ffff,
-+ ntohs(((struct ipcomphdr*)(((char*)iph)+iphlen))->ipcomp_cpi),
-+ pyldsz,
-+ cpyldsz);
-+
-+ /* Update IP header */
-+ iph->protocol = IPPROTO_COMP;
-+ iph->tot_len = htons(iphlen + sizeof(struct ipcomphdr) + cpyldsz);
-+#if 1 /* XXX checksum is done by ipsec_tunnel ? */
-+ iph->check = 0;
-+ iph->check = ip_fast_csum((char *) iph, iph->ihl);
-+#endif
-+
-+ /* Copy compressed payload */
-+ memcpy((char *) iph + iphlen + sizeof(struct ipcomphdr),
-+ buffer,
-+ cpyldsz);
-+ kfree(buffer);
-+
-+ /* Update skb length/tail by "unputting" the shrinkage */
-+ skb_put(skb,
-+ cpyldsz + sizeof(struct ipcomphdr) - pyldsz);
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
-+ __u8 *c;
-+ int i;
-+
-+ c = (__u8*)iph + iphlen + sizeof(struct ipcomphdr);
-+ for(i = 0; i < cpyldsz; i++, c++) {
-+ if(!(i % 16)) {
-+ printk(KERN_INFO "skb_compress: result:");
-+ }
-+ printk("%02x ", *c);
-+ if(!((i + 1) % 16)) {
-+ printk("\n");
-+ }
-+ }
-+ if(i % 16) {
-+ printk("\n");
-+ }
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ ips->ips_comp_adapt_skip = 0;
-+ ips->ips_comp_adapt_tries = 0;
-+
-+ return skb;
-+}
-+
-+struct sk_buff *skb_decompress(struct sk_buff *skb, struct ipsec_sa *ips, unsigned int *flags)
-+{
-+ struct sk_buff *nskb = NULL;
-+
-+ /* original ip header */
-+ struct iphdr *oiph, *iph;
-+ unsigned int iphlen, pyldsz, cpyldsz;
-+ z_stream zs;
-+ int zresult;
-+
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_decompress: .\n");
-+
-+ if(!skb) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "passed in NULL skb, returning ERROR.\n");
-+ if (flags) *flags |= IPCOMP_PARMERROR;
-+ return skb;
-+ }
-+
-+ if(!ips && sysctl_ipsec_inbound_policy_check) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "passed in NULL ipsec_sa needed for comp alg, returning ERROR.\n");
-+ if (flags) *flags |= IPCOMP_PARMERROR;
-+ return skb;
-+ }
-+
-+ if (!flags) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "passed in NULL flags, returning ERROR.\n");
-+ ipsec_kfree_skb(skb);
-+ return NULL;
-+ }
-+
-+#ifdef NET_21
-+ oiph = skb->nh.iph;
-+#else /* NET_21 */
-+ oiph = skb->ip_hdr;
-+#endif /* NET_21 */
-+
-+ iphlen = oiph->ihl << 2;
-+
-+ if (oiph->protocol != IPPROTO_COMP) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "called with non-IPCOMP packet (protocol=%d),"
-+ "skipping decompression.\n",
-+ oiph->protocol);
-+ *flags |= IPCOMP_PARMERROR;
-+ return skb;
-+ }
-+
-+ if ( (((struct ipcomphdr*)((char*) oiph + iphlen))->ipcomp_flags != 0)
-+ || ((((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi
-+ != htons(SADB_X_CALG_DEFLATE))
-+ && sysctl_ipsec_inbound_policy_check
-+ && (!ips || (ips && (ips->ips_encalg != SADB_X_CALG_DEFLATE)))) ) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "called with incompatible IPCOMP packet (flags=%d, "
-+ "cpi=%d), ips-compalg=%d, skipping decompression.\n",
-+ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_flags),
-+ ntohs(((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_cpi),
-+ ips ? ips->ips_encalg : 0);
-+ *flags |= IPCOMP_PARMERROR;
-+
-+ return skb;
-+ }
-+
-+ if (ntohs(oiph->frag_off) & ~0x4000) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "called with fragmented IPCOMP packet, "
-+ "skipping decompression.\n");
-+ *flags |= IPCOMP_PARMERROR;
-+ return skb;
-+ }
-+
-+ /* original compressed payload size */
-+ cpyldsz = ntohs(oiph->tot_len) - iphlen - sizeof(struct ipcomphdr);
-+
-+ zs.zalloc = my_zcalloc;
-+ zs.zfree = my_zfree;
-+ zs.opaque = 0;
-+
-+ zs.next_in = (char *) oiph + iphlen + sizeof(struct ipcomphdr);
-+ zs.avail_in = cpyldsz;
-+
-+ /* Maybe we should be a bit conservative about memory
-+ requirements and use inflateInit2 */
-+ /* Beware, that this might make us unable to decompress packets
-+ from other implementations - HINT: check PGPnet source code */
-+ /* We want to use inflateInit2 because we don't want the adler
-+ header. */
-+ zresult = inflateInit2(&zs, -15);
-+ if (zresult != Z_OK) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "inflateInit2() returned error %d (%s), "
-+ "skipping decompression.\n",
-+ zresult,
-+ zs.msg ? zs.msg : zError(zresult));
-+ *flags |= IPCOMP_DECOMPRESSIONERROR;
-+
-+ return skb;
-+ }
-+
-+ /* We have no way of knowing the exact length of the resulting
-+ decompressed output before we have actually done the decompression.
-+ For now, we guess that the packet will not be bigger than the
-+ attached ipsec device's mtu or 16260, whichever is biggest.
-+ This may be wrong, since the sender's mtu may be bigger yet.
-+ XXX This must be dealt with later XXX
-+ */
-+
-+ /* max payload size */
-+ pyldsz = skb->dev ? (skb->dev->mtu < 16260 ? 16260 : skb->dev->mtu)
-+ : (65520 - iphlen);
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_decompress: "
-+ "max payload size: %d\n", pyldsz);
-+
-+ while (pyldsz > (cpyldsz + sizeof(struct ipcomphdr)) &&
-+ (nskb = skb_copy_ipcomp(skb,
-+ pyldsz - cpyldsz - sizeof(struct ipcomphdr),
-+ GFP_ATOMIC)) == NULL) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "unable to skb_copy_ipcomp(skb, %d, GFP_ATOMIC), "
-+ "trying with less payload size.\n",
-+ (int)(pyldsz - cpyldsz - sizeof(struct ipcomphdr)));
-+ pyldsz >>=1;
-+ }
-+
-+ if (!nskb) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "unable to allocate memory, dropping packet.\n");
-+ *flags |= IPCOMP_DECOMPRESSIONERROR;
-+ inflateEnd(&zs);
-+
-+ return skb;
-+ }
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
-+ __u8 *c;
-+ int i;
-+
-+ c = (__u8*)oiph + iphlen + sizeof(struct ipcomphdr);
-+ for(i = 0; i < cpyldsz; i++, c++) {
-+ if(!(i % 16)) {
-+ printk(KERN_INFO "skb_decompress: before:");
-+ }
-+ printk("%02x ", *c);
-+ if(!((i + 1) % 16)) {
-+ printk("\n");
-+ }
-+ }
-+ if(i % 16) {
-+ printk("\n");
-+ }
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#ifdef NET_21
-+ iph = nskb->nh.iph;
-+#else /* NET_21 */
-+ iph = nskb->ip_hdr;
-+#endif /* NET_21 */
-+ zs.next_out = (char *)iph + iphlen;
-+ zs.avail_out = pyldsz;
-+
-+ zresult = inflate(&zs, Z_SYNC_FLUSH);
-+
-+ /* work around a bug in zlib, which sometimes wants to taste an extra
-+ * byte when being used in the (undocumented) raw deflate mode.
-+ */
-+ if (zresult == Z_OK && !zs.avail_in && zs.avail_out) {
-+ __u8 zerostuff = 0;
-+
-+ zs.next_in = &zerostuff;
-+ zs.avail_in = 1;
-+ zresult = inflate(&zs, Z_FINISH);
-+ }
-+
-+ inflateEnd(&zs);
-+ if (zresult != Z_STREAM_END) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_error:skb_decompress: "
-+ "inflate() returned error %d (%s), "
-+ "skipping decompression.\n",
-+ zresult,
-+ zs.msg ? zs.msg : zError(zresult));
-+ *flags |= IPCOMP_DECOMPRESSIONERROR;
-+ ipsec_kfree_skb(nskb);
-+
-+ return skb;
-+ }
-+
-+ /* Update IP header */
-+ /* resulting decompressed size */
-+ pyldsz -= zs.avail_out;
-+ iph->tot_len = htons(iphlen + pyldsz);
-+ iph->protocol = ((struct ipcomphdr*) ((char*) oiph + iphlen))->ipcomp_nh;
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_decompress: "
-+ "spi=%08x, spi&0xffff=%04x, cpi=%04x, payload size: comp=%d, raw=%d, nh=%d.\n",
-+ ips ? ntohl(ips->ips_said.spi) : 0,
-+ ips ? ntohl(ips->ips_said.spi) & 0x0000ffff : 0,
-+ ntohs(((struct ipcomphdr*)(((char*)oiph)+iphlen))->ipcomp_cpi),
-+ cpyldsz,
-+ pyldsz,
-+ iph->protocol);
-+
-+#if 1 /* XXX checksum is done by ipsec_rcv ? */
-+ iph->check = 0;
-+ iph->check = ip_fast_csum((char*) iph, iph->ihl);
-+#endif
-+
-+ /* Update skb length/tail by "unputting" the unused data area */
-+ skb_put(nskb, -zs.avail_out);
-+
-+ ipsec_kfree_skb(skb);
-+
-+ if (iph->protocol == IPPROTO_COMP)
-+ {
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(sysctl_ipsec_debug_ipcomp)
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_decompress: "
-+ "Eh? inner packet is also compressed, dropping.\n");
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ ipsec_kfree_skb(nskb);
-+ return NULL;
-+ }
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(sysctl_ipsec_debug_ipcomp && sysctl_ipsec_debug_verbose) {
-+ __u8 *c;
-+ int i;
-+
-+ c = (__u8*)iph + iphlen;
-+ for(i = 0; i < pyldsz; i++, c++) {
-+ if(!(i % 16)) {
-+ printk(KERN_INFO "skb_decompress: result:");
-+ }
-+ printk("%02x ", *c);
-+ if(!((i + 1) % 16)) {
-+ printk("\n");
-+ }
-+ }
-+ if(i % 16) {
-+ printk("\n");
-+ }
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ return nskb;
-+}
-+
-+
-+/* this is derived from skb_copy() in linux 2.2.14 */
-+/* May be incompatible with other kernel versions!! */
-+static
-+struct sk_buff *skb_copy_ipcomp(struct sk_buff *skb, int data_growth, int gfp_mask)
-+{
-+ struct sk_buff *n;
-+ struct iphdr *iph;
-+ unsigned long offset;
-+ unsigned int iphlen;
-+
-+ if(!skb) {
-+ KLIPS_PRINT(sysctl_ipsec_debug_ipcomp,
-+ "klips_debug:skb_copy_ipcomp: "
-+ "passed in NULL skb, returning NULL.\n");
-+ return NULL;
-+ }
-+
-+ /*
-+ * Allocate the copy buffer
-+ */
-+
-+#ifdef NET_21
-+ iph = skb->nh.iph;
-+#else /* NET_21 */
-+ iph = skb->ip_hdr;
-+#endif /* NET_21 */
-+ if (!iph) return NULL;
-+ iphlen = iph->ihl << 2;
-+
-+ n=alloc_skb(skb->end - skb->head + data_growth, gfp_mask);
-+ if(n==NULL)
-+ return NULL;
-+
-+ /*
-+ * Shift between the two data areas in bytes
-+ */
-+
-+ offset=n->head-skb->head;
-+
-+ /* Set the data pointer */
-+ skb_reserve(n,skb->data-skb->head);
-+ /* Set the tail pointer and length */
-+ skb_put(n,skb->len+data_growth);
-+ /* Copy the bytes up to and including the ip header */
-+ memcpy(n->head,
-+ skb->head,
-+ ((char *)iph - (char *)skb->head) + iphlen);
-+ n->list=NULL;
-+ n->next=NULL;
-+ n->prev=NULL;
-+ n->sk=NULL;
-+ n->dev=skb->dev;
-+ if (skb->h.raw)
-+ n->h.raw=skb->h.raw+offset;
-+ else
-+ n->h.raw=NULL;
-+ n->protocol=skb->protocol;
-+#ifdef NET_21
-+ n->csum = 0;
-+ n->priority=skb->priority;
-+ n->dst=dst_clone(skb->dst);
-+ n->nh.raw=skb->nh.raw+offset;
-+#ifndef NETDEV_23
-+ n->is_clone=0;
-+#endif /* NETDEV_23 */
-+ atomic_set(&n->users, 1);
-+ n->destructor = NULL;
-+ n->security=skb->security;
-+ memcpy(n->cb, skb->cb, sizeof(skb->cb));
-+#ifdef CONFIG_IP_FIREWALL
-+ n->fwmark = skb->fwmark;
-+#endif
-+#else /* NET_21 */
-+ n->link3=NULL;
-+ n->when=skb->when;
-+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
-+ n->saddr=skb->saddr;
-+ n->daddr=skb->daddr;
-+ n->raddr=skb->raddr;
-+ n->seq=skb->seq;
-+ n->end_seq=skb->end_seq;
-+ n->ack_seq=skb->ack_seq;
-+ n->acked=skb->acked;
-+ n->free=1;
-+ n->arp=skb->arp;
-+ n->tries=0;
-+ n->lock=0;
-+ n->users=0;
-+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
-+#endif /* NET_21 */
-+ if (skb->mac.raw)
-+ n->mac.raw=skb->mac.raw+offset;
-+ else
-+ n->mac.raw=NULL;
-+#ifndef NETDEV_23
-+ n->used=skb->used;
-+#endif /* !NETDEV_23 */
-+ n->pkt_type=skb->pkt_type;
-+#ifndef NETDEV_23
-+ n->pkt_bridged=skb->pkt_bridged;
-+#endif /* NETDEV_23 */
-+ n->ip_summed=0;
-+ n->stamp=skb->stamp;
-+#ifndef NETDEV_23 /* this seems to have been removed in 2.4 */
-+#if defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE)
-+ n->shapelatency=skb->shapelatency; /* Latency on frame */
-+ n->shapeclock=skb->shapeclock; /* Time it should go out */
-+ n->shapelen=skb->shapelen; /* Frame length in clocks */
-+ n->shapestamp=skb->shapestamp; /* Stamp for shaper */
-+ n->shapepend=skb->shapepend; /* Pending */
-+#endif /* defined(CONFIG_SHAPER) || defined(CONFIG_SHAPER_MODULE) */
-+#endif /* NETDEV_23 */
-+#ifdef CONFIG_HIPPI
-+ n->private.ifield=skb->private.ifield;
-+#endif /* CONFIG_HIPPI */
-+
-+ return n;
-+}
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_ah.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,363 @@
-+/*
-+ * processing code for AH
-+ * Copyright (C) 2003-2004 Michael Richardson <mcr@xelerance.com>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipsec_ah_c_version[] = "RCSID $Id$";
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define proto_priv cb
-+#endif /* NET21 */
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h"
-+#include "openswan/ipsec_xmit.h"
-+
-+#include "openswan/ipsec_auth.h"
-+
-+#ifdef CONFIG_IPSEC_AH
-+#include "openswan/ipsec_ah.h"
-+#endif /* CONFIG_IPSEC_AH */
-+
-+#include "openswan/ipsec_proto.h"
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_ah = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+__u32 zeroes[AH_AMAX];
-+
-+#ifdef CONFIG_IPSEC_AH
-+enum ipsec_rcv_value
-+ipsec_rcv_ah_checks(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb)
-+{
-+ int ahminlen;
-+
-+ ahminlen = irs->hard_header_len + sizeof(struct iphdr);
-+
-+ /* take care not to deref this pointer until we check the minlen though */
-+ irs->protostuff.ahstuff.ahp = (struct ahhdr *) (skb->data + irs->iphlen);
-+
-+ if((skb->len < ahminlen+sizeof(struct ahhdr)) ||
-+ (skb->len < ahminlen+(irs->protostuff.ahstuff.ahp->ah_hl << 2))) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
-+ "klips_debug:ipsec_rcv: "
-+ "runt ah packet of skb->len=%d received from %s, dropped.\n",
-+ skb->len,
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_BADLEN;
-+ }
-+
-+ irs->said.spi = irs->protostuff.ahstuff.ahp->ah_spi;
-+
-+ /* XXX we only support the one 12-byte authenticator for now */
-+ if(irs->protostuff.ahstuff.ahp->ah_hl != ((AHHMAC_HASHLEN+AHHMAC_RPLLEN) >> 2)) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
-+ "klips_debug:ipsec_rcv: "
-+ "bad authenticator length %ld, expected %lu from %s.\n",
-+ (long)(irs->protostuff.ahstuff.ahp->ah_hl << 2),
-+ (unsigned long) sizeof(struct ahhdr),
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_BADLEN;
-+ }
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+
-+enum ipsec_rcv_value
-+ipsec_rcv_ah_setup_auth(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb,
-+ __u32 *replay,
-+ unsigned char **authenticator)
-+{
-+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
-+
-+ *replay = ntohl(ahp->ah_rpl);
-+ *authenticator = ahp->ah_data;
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+enum ipsec_rcv_value
-+ipsec_rcv_ah_authcalc(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb)
-+{
-+ struct auth_alg *aa;
-+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
-+ union {
-+ MD5_CTX md5;
-+ SHA1_CTX sha1;
-+ } tctx;
-+ struct iphdr ipo;
-+ int ahhlen;
-+
-+ aa = irs->authfuncs;
-+
-+ /* copy the initialized keying material */
-+ memcpy(&tctx, irs->ictx, irs->ictx_len);
-+
-+ ipo = *irs->ipp;
-+ ipo.tos = 0; /* mutable RFC 2402 3.3.3.1.1.1 */
-+ ipo.frag_off = 0;
-+ ipo.ttl = 0;
-+ ipo.check = 0;
-+
-+
-+ /* do the sanitized header */
-+ (*aa->update)((void*)&tctx, (caddr_t)&ipo, sizeof(struct iphdr));
-+
-+ /* XXX we didn't do the options here! */
-+
-+ /* now do the AH header itself */
-+ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
-+ (*aa->update)((void*)&tctx, (caddr_t)ahp, ahhlen - AHHMAC_HASHLEN);
-+
-+ /* now, do some zeroes */
-+ (*aa->update)((void*)&tctx, (caddr_t)zeroes, AHHMAC_HASHLEN);
-+
-+ /* finally, do the packet contents themselves */
-+ (*aa->update)((void*)&tctx,
-+ (caddr_t)skb->data + irs->iphlen + ahhlen,
-+ skb->len - irs->iphlen - ahhlen);
-+
-+ (*aa->final)(irs->hash, (void *)&tctx);
-+
-+ memcpy(&tctx, irs->octx, irs->octx_len);
-+
-+ (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
-+ (*aa->final)(irs->hash, (void *)&tctx);
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+enum ipsec_rcv_value
-+ipsec_rcv_ah_decap(struct ipsec_rcv_state *irs)
-+{
-+ struct ahhdr *ahp = irs->protostuff.ahstuff.ahp;
-+ struct sk_buff *skb;
-+ int ahhlen;
-+
-+ skb=irs->skb;
-+
-+ ahhlen = AH_BASIC_LEN + (ahp->ah_hl << 2);
-+
-+ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - ahhlen);
-+ irs->next_header = ahp->ah_nh;
-+
-+ /*
-+ * move the IP header forward by the size of the AH header, which
-+ * will remove the the AH header from the packet.
-+ */
-+ memmove((void *)(skb->data + ahhlen),
-+ (void *)(skb->data), irs->iphlen);
-+
-+ ipsec_rcv_dmp("ah postmove", skb->data, skb->len);
-+
-+ /* skb_pull below, will move up by ahhlen */
-+
-+ /* XXX not clear how this can happen, as the message indicates */
-+ if(skb->len < ahhlen) {
-+ printk(KERN_WARNING
-+ "klips_error:ipsec_rcv: "
-+ "tried to skb_pull ahhlen=%d, %d available. This should never happen, please report.\n",
-+ ahhlen,
-+ (int)(skb->len));
-+ return IPSEC_RCV_DECAPFAIL;
-+ }
-+ skb_pull(skb, ahhlen);
-+
-+ irs->ipp = (struct iphdr *)skb->data;
-+
-+ ipsec_rcv_dmp("ah postpull", skb->data, skb->len);
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_ah_setup(struct ipsec_xmit_state *ixs)
-+{
-+ struct iphdr ipo;
-+ struct ahhdr *ahp;
-+ __u8 hash[AH_AMAX];
-+ union {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ MD5_CTX md5;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ SHA1_CTX sha1;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ } tctx;
-+ unsigned char *dat = (unsigned char *)ixs->iph;
-+
-+ ahp = (struct ahhdr *)(dat + ixs->iphlen);
-+ ahp->ah_spi = ixs->ipsp->ips_said.spi;
-+ ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
-+ ahp->ah_rv = 0;
-+ ahp->ah_nh = ixs->iph->protocol;
-+ ahp->ah_hl = (sizeof(struct ahhdr) >> 2) - sizeof(__u64)/sizeof(__u32);
-+ ixs->iph->protocol = IPPROTO_AH;
-+ ipsec_xmit_dmp("ahp", (char*)ahp, sizeof(*ahp));
-+
-+ ipo = *ixs->iph;
-+ ipo.tos = 0;
-+ ipo.frag_off = 0;
-+ ipo.ttl = 0;
-+ ipo.check = 0;
-+ ipsec_xmit_dmp("ipo", (char*)&ipo, sizeof(ipo));
-+
-+ switch(ixs->ipsp->ips_authalg) {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5:
-+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
-+ ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
-+ ipsec_xmit_dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, (unsigned char *)ahp,
-+ sizeof(struct ahhdr) - sizeof(ahp->ah_data));
-+ ipsec_xmit_dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
-+ ipsec_xmit_dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, dat + ixs->iphlen + sizeof(struct ahhdr),
-+ ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
-+ ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Final(hash, &tctx.md5);
-+ ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
-+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
-+ ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, hash, AHMD596_ALEN);
-+ ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Final(hash, &tctx.md5);
-+ ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
-+
-+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
-+
-+ /* paranoid */
-+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
-+ memset((caddr_t)hash, 0, sizeof(*hash));
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA:
-+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
-+ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
-+ SHA1Update(&tctx.sha1, (unsigned char *)ahp, sizeof(struct ahhdr) - sizeof(ahp->ah_data));
-+ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
-+ SHA1Update(&tctx.sha1, dat + ixs->iphlen + sizeof(struct ahhdr),
-+ ixs->skb->len - ixs->iphlen - sizeof(struct ahhdr));
-+ SHA1Final(hash, &tctx.sha1);
-+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
-+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
-+ SHA1Final(hash, &tctx.sha1);
-+
-+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
-+
-+ /* paranoid */
-+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
-+ memset((caddr_t)hash, 0, sizeof(*hash));
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_AH_BADALG;
-+ }
-+#ifdef NET_21
-+ ixs->skb->h.raw = (unsigned char*)ahp;
-+#endif /* NET_21 */
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+struct xform_functions ah_xform_funcs[]={
-+ { rcv_checks: ipsec_rcv_ah_checks,
-+ rcv_setup_auth: ipsec_rcv_ah_setup_auth,
-+ rcv_calc_auth: ipsec_rcv_ah_authcalc,
-+ rcv_decrypt: ipsec_rcv_ah_decap,
-+
-+ xmit_setup: ipsec_xmit_ah_setup,
-+ xmit_headroom: sizeof(struct ahhdr),
-+ xmit_needtailroom: 0,
-+ },
-+};
-+
-+struct inet_protocol ah_protocol =
-+{
-+ ipsec_rcv, /* AH handler */
-+ NULL, /* TUNNEL error control */
-+#ifdef NETDEV_25
-+ 1, /* no policy */
-+#else
-+ 0, /* next */
-+ IPPROTO_AH, /* protocol ID */
-+ 0, /* copy */
-+ NULL, /* data */
-+ "AH" /* name */
-+#endif
-+};
-+
-+#endif /* CONFIG_IPSEC_AH */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.2 2004/04/06 02:49:25 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_alg.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,953 @@
-+/*
-+ * Modular extensions service and registration functions
-+ *
-+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
-+ *
-+ * Version: 0.8.1
-+ *
-+ * ipsec_alg.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ */
-+#ifdef CONFIG_IPSEC_ALG
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/in.h>
-+#include <linux/types.h>
-+#include <linux/string.h> /* memcmp() */
-+#include <linux/random.h> /* get_random_bytes() */
-+#include <linux/errno.h> /* error codes */
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define proto_priv cb
-+#endif /* NET21 */
-+#include "openswan/ipsec_param.h"
-+#include <openswan.h>
-+#include "openswan/ipsec_sa.h"
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h"
-+#if defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH)
-+# include "openswan/ipsec_ah.h"
-+#endif /* defined(CONFIG_IPSEC_ESP) || defined(CONFIG_IPSEC_AH) */
-+#ifdef CONFIG_IPSEC_ESP
-+# include "openswan/ipsec_esp.h"
-+#endif /* !CONFIG_IPSEC_ESP */
-+#ifdef CONFIG_IPSEC_IPCOMP
-+# include "openswan/ipcomp.h"
-+#endif /* CONFIG_IPSEC_COMP */
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_alg.h"
-+
-+#ifndef CONFIG_IPSEC_ALG
-+#error This file _MUST_ be compiled with CONFIG_IPSEC_ALG enabled !
-+#endif
-+#if SADB_EALG_MAX < 255
-+#warning Compiling with limited ESP support ( SADB_EALG_MAX < 256 )
-+#endif
-+
-+static rwlock_t ipsec_alg_lock = RW_LOCK_UNLOCKED;
-+#define IPSEC_ALG_HASHSZ 16 /* must be power of 2, even 2^0=1 */
-+static struct list_head ipsec_alg_hash_table[IPSEC_ALG_HASHSZ];
-+
-+/* Old gcc's will fail here */
-+#define barf_out(fmt, args...) do { printk(KERN_ERR "%s: (%s) " fmt, __FUNCTION__, ixt->ixt_name , ## args)\
-+ ; goto out; } while(0)
-+
-+/*
-+ * Must be already protected by lock
-+ */
-+static void __ipsec_alg_usage_inc(struct ipsec_alg *ixt) {
-+ if (ixt->ixt_module)
-+ __MOD_INC_USE_COUNT(ixt->ixt_module);
-+ atomic_inc(&ixt->ixt_refcnt);
-+}
-+static void __ipsec_alg_usage_dec(struct ipsec_alg *ixt) {
-+ atomic_dec(&ixt->ixt_refcnt);
-+ if (ixt->ixt_module)
-+ __MOD_DEC_USE_COUNT(ixt->ixt_module);
-+}
-+/*
-+ * simple hash function, optimized for 0-hash (1 list) special
-+ * case
-+ */
-+#if IPSEC_ALG_HASHSZ > 1
-+static inline unsigned ipsec_alg_hashfn(int alg_type, int alg_id) {
-+ return ((alg_type^alg_id)&(IPSEC_ALG_HASHSZ-1));
-+}
-+#else
-+#define ipsec_alg_hashfn(x,y) (0)
-+#endif
-+
-+/*****************************************************************
-+ *
-+ * INTERNAL table handling: insert, delete, find
-+ *
-+ *****************************************************************/
-+
-+/*
-+ * hash table initialization, called from ipsec_alg_init()
-+ */
-+static void ipsec_alg_hash_init(void) {
-+ struct list_head *head = ipsec_alg_hash_table;
-+ int i = IPSEC_ALG_HASHSZ;
-+ do {
-+ INIT_LIST_HEAD(head);
-+ head++;
-+ i--;
-+ } while (i);
-+}
-+/*
-+ * hash list lookup by {alg_type, alg_id} and table head,
-+ * must be already protected by lock
-+ */
-+static struct ipsec_alg *__ipsec_alg_find(unsigned alg_type, unsigned alg_id, struct list_head * head) {
-+ struct list_head *p;
-+ struct ipsec_alg *ixt=NULL;
-+ for (p=head->next; p!=head; p=p->next) {
-+ ixt = list_entry(p, struct ipsec_alg, ixt_list);
-+ if (ixt->ixt_alg_type == alg_type && ixt->ixt_alg_id==alg_id) {
-+ goto out;
-+ }
-+ }
-+ ixt=NULL;
-+out:
-+ return ixt;
-+}
-+/*
-+ * inserts (in front) a new entry in hash table,
-+ * called from ipsec_alg_register() when new algorithm is registered.
-+ */
-+static int ipsec_alg_insert(struct ipsec_alg *ixt) {
-+ int ret=-EINVAL;
-+ unsigned hashval=ipsec_alg_hashfn(ixt->ixt_alg_type, ixt->ixt_alg_id);
-+ struct list_head *head= ipsec_alg_hash_table + hashval;
-+ struct ipsec_alg *ixt_cur;
-+ /* new element must be virgin ... */
-+ if (ixt->ixt_list.next != &ixt->ixt_list ||
-+ ixt->ixt_list.prev != &ixt->ixt_list) {
-+ printk(KERN_ERR "ipsec_alg_insert: ixt object \"%s\" "
-+ "list head not initialized\n",
-+ ixt->ixt_name);
-+ return ret;
-+ }
-+ write_lock_bh(&ipsec_alg_lock);
-+ ixt_cur = __ipsec_alg_find(ixt->ixt_alg_type, ixt->ixt_alg_id, head);
-+ /* if previous (current) ipsec_alg found check excl flag of _anyone_ */
-+ if (ixt_cur && ((ixt->ixt_state|ixt_cur->ixt_state) & IPSEC_ALG_ST_EXCL))
-+ barf_out("ipsec_alg for alg_type=%d, alg_id=%d already exist. "
-+ "Not loaded (ret=%d).\n",
-+ ixt->ixt_alg_type,
-+ ixt->ixt_alg_id, ret=-EEXIST);
-+ list_add(&ixt->ixt_list, head);
-+ ixt->ixt_state |= IPSEC_ALG_ST_REGISTERED;
-+ ret=0;
-+out:
-+ write_unlock_bh(&ipsec_alg_lock);
-+ return ret;
-+}
-+/*
-+ * deletes an existing entry in hash table,
-+ * called from ipsec_alg_unregister() when algorithm is unregistered.
-+ */
-+static int ipsec_alg_delete(struct ipsec_alg *ixt) {
-+ write_lock_bh(&ipsec_alg_lock);
-+ list_del(&ixt->ixt_list);
-+ write_unlock_bh(&ipsec_alg_lock);
-+ return 0;
-+}
-+/*
-+ * here @user context (read-only when @kernel bh context)
-+ * -> no bh disabling
-+ *
-+ * called from ipsec_sa_init() -> ipsec_alg_sa_init()
-+ */
-+static struct ipsec_alg *ipsec_alg_get(int alg_type, int alg_id) {
-+ unsigned hashval=ipsec_alg_hashfn(alg_type, alg_id);
-+ struct list_head *head= ipsec_alg_hash_table + hashval;
-+ struct ipsec_alg *ixt;
-+ read_lock(&ipsec_alg_lock);
-+ ixt=__ipsec_alg_find(alg_type, alg_id, head);
-+ if (ixt) __ipsec_alg_usage_inc(ixt);
-+ read_unlock(&ipsec_alg_lock);
-+ return ixt;
-+}
-+
-+static void ipsec_alg_put(struct ipsec_alg *ixt) {
-+ __ipsec_alg_usage_dec((struct ipsec_alg *)ixt);
-+}
-+
-+/*****************************************************************
-+ *
-+ * INTERFACE for ENC services: key creation, encrypt function
-+ *
-+ *****************************************************************/
-+
-+/*
-+ * main encrypt service entry point
-+ * called from ipsec_rcv() with encrypt=IPSEC_ALG_DECRYPT and
-+ * ipsec_tunnel_start_xmit with encrypt=IPSEC_ALG_ENCRYPT
-+ */
-+int ipsec_alg_esp_encrypt(struct ipsec_sa *sa_p, __u8 * idat, int ilen, const __u8 * iv, int encrypt) {
-+ int ret;
-+ struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
-+ KLIPS_PRINT(debug_rcv||debug_tunnel,
-+ "klips_debug:ipsec_alg_esp_encrypt: "
-+ "entering with encalg=%d, ixt_e=%p\n",
-+ sa_p->ips_encalg, ixt_e);
-+ if (!ixt_e) {
-+ KLIPS_PRINT(debug_rcv||debug_tunnel,
-+ "klips_debug:ipsec_alg_esp_encrypt: "
-+ "NULL ipsec_alg_enc object\n");
-+ return -1;
-+ }
-+ KLIPS_PRINT(debug_rcv||debug_tunnel,
-+ "klips_debug:ipsec_alg_esp_encrypt: "
-+ "calling cbc_encrypt encalg=%d "
-+ "ips_key_e=%p idat=%p ilen=%d iv=%p, encrypt=%d\n",
-+ sa_p->ips_encalg,
-+ sa_p->ips_key_e, idat, ilen, iv, encrypt);
-+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, sa_p->ips_key_e, idat, ilen, iv, encrypt);
-+ KLIPS_PRINT(debug_rcv||debug_tunnel,
-+ "klips_debug:ipsec_alg_esp_encrypt: "
-+ "returned ret=%d\n",
-+ ret);
-+ return ret;
-+}
-+/*
-+ * encryption key context creation function
-+ * called from pfkey_v2_parser.c:pfkey_ips_init()
-+ */
-+int ipsec_alg_enc_key_create(struct ipsec_sa *sa_p) {
-+ int ret=-EINVAL;
-+ int keyminbits, keymaxbits;
-+ caddr_t ekp;
-+ struct ipsec_alg_enc *ixt_e=sa_p->ips_alg_enc;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_alg_enc_key_create: "
-+ "entering with encalg=%d ixt_e=%p\n",
-+ sa_p->ips_encalg, ixt_e);
-+ if (!ixt_e) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_alg_enc_key_create: "
-+ "NULL ipsec_alg_enc object\n");
-+ return -EPROTO;
-+ }
-+
-+ /*
-+ * grRRR... DES 7bits jurassic stuff ... f*ckk --jjo
-+ */
-+ switch(ixt_e->ixt_alg_id) {
-+ case ESP_3DES:
-+ keyminbits=keymaxbits=192;break;
-+ case ESP_DES:
-+ keyminbits=keymaxbits=64;break;
-+ default:
-+ keyminbits=ixt_e->ixt_keyminbits;
-+ keymaxbits=ixt_e->ixt_keymaxbits;
-+ }
-+ if(sa_p->ips_key_bits_e<keyminbits ||
-+ sa_p->ips_key_bits_e>keymaxbits) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_alg_enc_key_create: "
-+ "incorrect encryption key size for id=%d: %d bits -- "
-+ "must be between %d,%d bits\n" /*octets (bytes)\n"*/,
-+ ixt_e->ixt_alg_id,
-+ sa_p->ips_key_bits_e, keyminbits, keymaxbits);
-+ ret=-EINVAL;
-+ goto ixt_out;
-+ }
-+ /* save encryption key pointer */
-+ ekp = sa_p->ips_key_e;
-+
-+
-+ if (ixt_e->ixt_e_new_key) {
-+ sa_p->ips_key_e = ixt_e->ixt_e_new_key(ixt_e,
-+ ekp, sa_p->ips_key_bits_e/8);
-+ ret = (sa_p->ips_key_e)? 0 : -EINVAL;
-+ } else {
-+ if((sa_p->ips_key_e = (caddr_t)
-+ kmalloc((sa_p->ips_key_e_size = ixt_e->ixt_e_ctx_size),
-+ GFP_ATOMIC)) == NULL) {
-+ ret=-ENOMEM;
-+ goto ixt_out;
-+ }
-+ /* zero-out key_e */
-+ memset(sa_p->ips_key_e, 0, sa_p->ips_key_e_size);
-+
-+ /* I cast here to allow more decoupling in alg module */
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_alg_enc_key_create: about to call:"
-+ "set_key(key_e=%p, ekp=%p, key_size=%d)\n",
-+ (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
-+ ret = ixt_e->ixt_e_set_key(ixt_e, (caddr_t)sa_p->ips_key_e, ekp, sa_p->ips_key_bits_e/8);
-+ }
-+ /* paranoid */
-+ memset(ekp, 0, sa_p->ips_key_bits_e/8);
-+ kfree(ekp);
-+ixt_out:
-+ return ret;
-+}
-+
-+/***************************************************************
-+ *
-+ * INTERFACE for AUTH services: key creation, hash functions
-+ *
-+ ***************************************************************/
-+
-+/*
-+ * auth key context creation function
-+ * called from pfkey_v2_parser.c:pfkey_ips_init()
-+ */
-+int ipsec_alg_auth_key_create(struct ipsec_sa *sa_p) {
-+ int ret=-EINVAL;
-+ struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
-+ int keyminbits, keymaxbits;
-+ unsigned char *akp;
-+ unsigned int aks;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_alg_auth_key_create: "
-+ "entering with authalg=%d ixt_a=%p\n",
-+ sa_p->ips_authalg, ixt_a);
-+ if (!ixt_a) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_alg_auth_key_create: "
-+ "NULL ipsec_alg_auth object\n");
-+ return -EPROTO;
-+ }
-+ keyminbits=ixt_a->ixt_keyminbits;
-+ keymaxbits=ixt_a->ixt_keymaxbits;
-+ if(sa_p->ips_key_bits_a<keyminbits || sa_p->ips_key_bits_a>keymaxbits) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_alg_auth_key_create: incorrect auth"
-+ "key size: %d bits -- must be between %d,%d bits\n"/*octets (bytes)\n"*/,
-+ sa_p->ips_key_bits_a, keyminbits, keymaxbits);
-+ ret=-EINVAL;
-+ goto ixt_out;
-+ }
-+ /* save auth key pointer */
-+ sa_p->ips_auth_bits = ixt_a->ixt_a_keylen * 8; /* XXX XXX */
-+ akp = sa_p->ips_key_a;
-+ aks = sa_p->ips_key_a_size;
-+
-+ /* will hold: 2 ctx and a blocksize buffer: kb */
-+ sa_p->ips_key_a_size = ixt_a->ixt_a_ctx_size;
-+ if((sa_p->ips_key_a =
-+ (caddr_t) kmalloc(sa_p->ips_key_a_size, GFP_ATOMIC)) == NULL) {
-+ ret=-ENOMEM;
-+ goto ixt_out;
-+ }
-+ ixt_a->ixt_a_hmac_set_key(ixt_a, sa_p->ips_key_a, akp, sa_p->ips_key_bits_a/8); /* XXX XXX */
-+ ret=0;
-+ memset(akp, 0, aks);
-+ kfree(akp);
-+
-+ixt_out:
-+ return ret;
-+}
-+
-+
-+int ipsec_alg_sa_esp_hash(const struct ipsec_sa *sa_p, const __u8 *espp, int len, __u8 *hash, int hashlen) {
-+ struct ipsec_alg_auth *ixt_a=sa_p->ips_alg_auth;
-+ if (!ixt_a) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_sa_esp_hash: "
-+ "NULL ipsec_alg_auth object\n");
-+ return -EPROTO;
-+ }
-+ KLIPS_PRINT(debug_tunnel|debug_rcv,
-+ "klips_debug:ipsec_sa_esp_hash: "
-+ "hashing %p (%d bytes) to %p (%d bytes)\n",
-+ espp, len,
-+ hash, hashlen);
-+ ixt_a->ixt_a_hmac_hash(ixt_a,
-+ sa_p->ips_key_a,
-+ espp, len,
-+ hash, hashlen);
-+ return 0;
-+}
-+
-+/***************************************************************
-+ *
-+ * INTERFACE for module loading,testing, and unloading
-+ *
-+ ***************************************************************/
-+
-+/* validation for registering (enc) module */
-+static int check_enc(struct ipsec_alg_enc *ixt) {
-+ int ret=-EINVAL;
-+ if (ixt->ixt_alg_id==0 || ixt->ixt_alg_id > SADB_EALG_MAX)
-+ barf_out("invalid alg_id=%d >= %d\n", ixt->ixt_alg_id, SADB_EALG_MAX);
-+ if (ixt->ixt_blocksize==0) /* || ixt->ixt_blocksize%2) need for ESP_NULL */
-+ barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_blocksize);
-+ if (ixt->ixt_keyminbits==0 && ixt->ixt_keymaxbits==0 && ixt->ixt_e_keylen==0)
-+ goto zero_key_ok;
-+ if (ixt->ixt_keyminbits==0)
-+ barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_keyminbits);
-+ if (ixt->ixt_keymaxbits==0)
-+ barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_keymaxbits);
-+ if (ixt->ixt_e_keylen==0)
-+ barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_e_keylen);
-+zero_key_ok:
-+ if (ixt->ixt_e_ctx_size==0 && ixt->ixt_e_new_key == NULL)
-+ barf_out(KERN_ERR "invalid key_e_size=%d and ixt_e_new_key=NULL\n", ixt->ixt_e_ctx_size);
-+ if (ixt->ixt_e_cbc_encrypt==NULL)
-+ barf_out(KERN_ERR "e_cbc_encrypt() must be not NULL\n");
-+ ret=0;
-+out:
-+ return ret;
-+}
-+
-+/* validation for registering (auth) module */
-+static int check_auth(struct ipsec_alg_auth *ixt)
-+{
-+ int ret=-EINVAL;
-+ if (ixt->ixt_alg_id==0 || ixt->ixt_alg_id > SADB_AALG_MAX)
-+ barf_out("invalid alg_id=%d > %d (SADB_AALG_MAX)\n", ixt->ixt_alg_id, SADB_AALG_MAX);
-+ if (ixt->ixt_blocksize==0 || ixt->ixt_blocksize%2)
-+ barf_out(KERN_ERR "invalid blocksize=%d\n", ixt->ixt_blocksize);
-+ if (ixt->ixt_blocksize>AH_BLKLEN_MAX)
-+ barf_out(KERN_ERR "sorry blocksize=%d > %d. "
-+ "Please increase AH_BLKLEN_MAX and recompile\n",
-+ ixt->ixt_blocksize,
-+ AH_BLKLEN_MAX);
-+ if (ixt->ixt_keyminbits==0 && ixt->ixt_keymaxbits==0 && ixt->ixt_a_keylen==0)
-+ goto zero_key_ok;
-+ if (ixt->ixt_keyminbits==0)
-+ barf_out(KERN_ERR "invalid keyminbits=%d\n", ixt->ixt_keyminbits);
-+ if (ixt->ixt_keymaxbits==0)
-+ barf_out(KERN_ERR "invalid keymaxbits=%d\n", ixt->ixt_keymaxbits);
-+ if (ixt->ixt_keymaxbits!=ixt->ixt_keyminbits)
-+ barf_out(KERN_ERR "keymaxbits must equal keyminbits (not sure).\n");
-+ if (ixt->ixt_a_keylen==0)
-+ barf_out(KERN_ERR "invalid keysize=%d\n", ixt->ixt_a_keylen);
-+zero_key_ok:
-+ if (ixt->ixt_a_ctx_size==0)
-+ barf_out(KERN_ERR "invalid a_ctx_size=%d\n", ixt->ixt_a_ctx_size);
-+ if (ixt->ixt_a_hmac_set_key==NULL)
-+ barf_out(KERN_ERR "a_hmac_set_key() must be not NULL\n");
-+ if (ixt->ixt_a_hmac_hash==NULL)
-+ barf_out(KERN_ERR "a_hmac_hash() must be not NULL\n");
-+ ret=0;
-+out:
-+ return ret;
-+}
-+
-+/*
-+ * Generic (enc, auth) registration entry point
-+ */
-+int register_ipsec_alg(struct ipsec_alg *ixt) {
-+ int ret=-EINVAL;
-+ /* Validation */
-+ if (ixt==NULL)
-+ barf_out("NULL ipsec_alg object passed\n");
-+ if ((ixt->ixt_version&0xffffff00) != (IPSEC_ALG_VERSION&0xffffff00))
-+ barf_out("incorrect version: %d.%d.%d-%d, "
-+ "must be %d.%d.%d[-%d]\n",
-+ IPSEC_ALG_VERSION_QUAD(ixt->ixt_version),
-+ IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION));
-+ switch(ixt->ixt_alg_type) {
-+ case IPSEC_ALG_TYPE_AUTH:
-+ if ((ret=check_auth((struct ipsec_alg_auth *)ixt)<0))
-+ goto out;
-+ break;
-+ case IPSEC_ALG_TYPE_ENCRYPT:
-+ if ((ret=check_enc((struct ipsec_alg_enc *)ixt)<0))
-+ goto out;
-+ /*
-+ * Adapted two lines below:
-+ * ivlen == 0 is possible (NULL enc has blocksize==1)
-+ *
-+ * fixed NULL support by David De Reu <DeReu@tComLabs.com>
-+ */
-+ if (ixt->ixt_ivlen == 0 && ixt->ixt_blocksize > 1)
-+ ixt->ixt_ivlen = ixt->ixt_blocksize*8;
-+ break;
-+ default:
-+ barf_out("alg_type=%d not supported\n", ixt->ixt_alg_type);
-+ }
-+ INIT_LIST_HEAD(&ixt->ixt_list);
-+ ret = ipsec_alg_insert(ixt);
-+ if (ret<0)
-+ barf_out(KERN_WARNING "ipsec_alg for alg_id=%d failed."
-+ "Not loaded (ret=%d).\n",
-+ ixt->ixt_alg_id, ret);
-+
-+ ret = pfkey_list_insert_supported((struct supported *)&ixt->ixt_support, &(pfkey_supported_list[SADB_SATYPE_ESP]));
-+ if (ret==0) {
-+ ixt->ixt_state |= IPSEC_ALG_ST_SUPP;
-+ /* send register event to userspace */
-+ pfkey_register_reply(SADB_SATYPE_ESP, NULL);
-+ } else
-+ printk(KERN_ERR "pfkey_list_insert_supported returned %d. "
-+ "Loading anyway.\n", ret);
-+ ret=0;
-+out:
-+ return ret;
-+}
-+
-+/*
-+ * unregister ipsec_alg object from own tables, if
-+ * success => calls pfkey_list_remove_supported()
-+ */
-+int unregister_ipsec_alg(struct ipsec_alg *ixt) {
-+ int ret= -EINVAL;
-+ switch(ixt->ixt_alg_type) {
-+ case IPSEC_ALG_TYPE_AUTH:
-+ case IPSEC_ALG_TYPE_ENCRYPT:
-+ break;
-+ default:
-+ /* this is not a typo :) */
-+ barf_out("frog found in list (\"%s\"): ixt_p=NULL\n",
-+ ixt->ixt_name);
-+ }
-+
-+ ret=ipsec_alg_delete(ixt);
-+ if (ixt->ixt_state&IPSEC_ALG_ST_SUPP) {
-+ ixt->ixt_state &= ~IPSEC_ALG_ST_SUPP;
-+ pfkey_list_remove_supported((struct supported *)&ixt->ixt_support, &(pfkey_supported_list[SADB_SATYPE_ESP]));
-+ /* send register event to userspace */
-+ pfkey_register_reply(SADB_SATYPE_ESP, NULL);
-+ }
-+
-+out:
-+ return ret;
-+}
-+
-+/*
-+ * Must be called from user context
-+ * used at module load type for testing algo implementation
-+ */
-+static int ipsec_alg_test_encrypt(int enc_alg, int test) {
-+ int ret;
-+ caddr_t buf = NULL;
-+ int iv_size, keysize, key_e_size;
-+ struct ipsec_alg_enc *ixt_e;
-+ void *tmp_key_e = NULL;
-+ #define BUFSZ 1024
-+ #define MARGIN 0
-+ #define test_enc (buf+MARGIN)
-+ #define test_dec (test_enc+BUFSZ+MARGIN)
-+ #define test_tmp (test_dec+BUFSZ+MARGIN)
-+ #define test_key_e (test_tmp+BUFSZ+MARGIN)
-+ #define test_iv (test_key_e+key_e_size+MARGIN)
-+ #define test_key (test_iv+iv_size+MARGIN)
-+ #define test_size (BUFSZ*3+key_e_size+iv_size+keysize+MARGIN*7)
-+ ixt_e=(struct ipsec_alg_enc *)ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, enc_alg);
-+ if (ixt_e==NULL) {
-+ KLIPS_PRINT(1,
-+ "klips_debug: ipsec_alg_test_encrypt: "
-+ "encalg=%d object not found\n",
-+ enc_alg);
-+ ret=-EINVAL;
-+ goto out;
-+ }
-+ iv_size=ixt_e->ixt_ivlen / 8;
-+ key_e_size=ixt_e->ixt_e_ctx_size;
-+ keysize=ixt_e->ixt_e_keylen;
-+ KLIPS_PRINT(1,
-+ "klips_debug: ipsec_alg_test_encrypt: "
-+ "enc_alg=%d blocksize=%d key_e_size=%d keysize=%d\n",
-+ enc_alg, iv_size, key_e_size, keysize);
-+ if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
-+ ret= -ENOMEM;
-+ goto out;
-+ }
-+ get_random_bytes(test_key, keysize);
-+ get_random_bytes(test_iv, iv_size);
-+ if (ixt_e->ixt_e_new_key) {
-+ tmp_key_e = ixt_e->ixt_e_new_key(ixt_e, test_key, keysize);
-+ ret = tmp_key_e ? 0 : -EINVAL;
-+ } else {
-+ tmp_key_e = test_key_e;
-+ ret = ixt_e->ixt_e_set_key(ixt_e, test_key_e, test_key, keysize);
-+ }
-+ if (ret < 0)
-+ goto out;
-+ get_random_bytes(test_enc, BUFSZ);
-+ memcpy(test_tmp, test_enc, BUFSZ);
-+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_enc, BUFSZ, test_iv, 1);
-+ printk(KERN_INFO
-+ "klips_info: ipsec_alg_test_encrypt: "
-+ "cbc_encrypt=1 ret=%d\n",
-+ ret);
-+ ret=memcmp(test_enc, test_tmp, BUFSZ);
-+ printk(KERN_INFO
-+ "klips_info: ipsec_alg_test_encrypt: "
-+ "memcmp(enc, tmp) ret=%d: %s\n", ret,
-+ ret!=0? "OK. (encr->DIFFers)" : "FAIL! (encr->SAME)" );
-+ memcpy(test_dec, test_enc, BUFSZ);
-+ ret=ixt_e->ixt_e_cbc_encrypt(ixt_e, tmp_key_e, test_dec, BUFSZ, test_iv, 0);
-+ printk(KERN_INFO
-+ "klips_info: ipsec_alg_test_encrypt: "
-+ "cbc_encrypt=0 ret=%d\n", ret);
-+ ret=memcmp(test_dec, test_tmp, BUFSZ);
-+ printk(KERN_INFO
-+ "klips_info: ipsec_alg_test_encrypt: "
-+ "memcmp(dec,tmp) ret=%d: %s\n", ret,
-+ ret==0? "OK. (encr->decr->SAME)" : "FAIL! (encr->decr->DIFFers)" );
-+ {
-+ /* Shamelessly taken from drivers/md sources O:) */
-+ unsigned long now;
-+ int i, count, max=0;
-+ int encrypt, speed;
-+ for (encrypt=0; encrypt <2;encrypt ++) {
-+ for (i = 0; i < 5; i++) {
-+ now = jiffies;
-+ count = 0;
-+ while (jiffies == now) {
-+ mb();
-+ ixt_e->ixt_e_cbc_encrypt(ixt_e,
-+ tmp_key_e, test_tmp,
-+ BUFSZ, test_iv, encrypt);
-+ mb();
-+ count++;
-+ mb();
-+ }
-+ if (count > max)
-+ max = count;
-+ }
-+ speed = max * (HZ * BUFSZ / 1024);
-+ printk(KERN_INFO
-+ "klips_info: ipsec_alg_test_encrypt: "
-+ "%s %s speed=%d KB/s\n",
-+ ixt_e->ixt_name,
-+ encrypt? "encrypt": "decrypt", speed);
-+ }
-+ }
-+out:
-+ if (tmp_key_e && ixt_e->ixt_e_destroy_key) ixt_e->ixt_e_destroy_key(ixt_e, tmp_key_e);
-+ if (buf) kfree(buf);
-+ if (ixt_e) ipsec_alg_put((struct ipsec_alg *)ixt_e);
-+ return ret;
-+ #undef test_enc
-+ #undef test_dec
-+ #undef test_tmp
-+ #undef test_key_e
-+ #undef test_iv
-+ #undef test_key
-+ #undef test_size
-+}
-+
-+/*
-+ * Must be called from user context
-+ * used at module load type for testing algo implementation
-+ */
-+static int ipsec_alg_test_auth(int auth_alg, int test) {
-+ int ret;
-+ caddr_t buf = NULL;
-+ int blocksize, keysize, key_a_size;
-+ struct ipsec_alg_auth *ixt_a;
-+ #define BUFSZ 1024
-+ #define MARGIN 0
-+ #define test_auth (buf+MARGIN)
-+ #define test_key_a (test_auth+BUFSZ+MARGIN)
-+ #define test_key (test_key_a+key_a_size+MARGIN)
-+ #define test_hash (test_key+keysize+MARGIN)
-+ #define test_size (BUFSZ+key_a_size+keysize+AHHMAC_HASHLEN+MARGIN*4)
-+ ixt_a=(struct ipsec_alg_auth *)ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, auth_alg);
-+ if (ixt_a==NULL) {
-+ KLIPS_PRINT(1,
-+ "klips_debug: ipsec_alg_test_auth: "
-+ "encalg=%d object not found\n",
-+ auth_alg);
-+ ret=-EINVAL;
-+ goto out;
-+ }
-+ blocksize=ixt_a->ixt_blocksize;
-+ key_a_size=ixt_a->ixt_a_ctx_size;
-+ keysize=ixt_a->ixt_a_keylen;
-+ KLIPS_PRINT(1,
-+ "klips_debug: ipsec_alg_test_auth: "
-+ "auth_alg=%d blocksize=%d key_a_size=%d keysize=%d\n",
-+ auth_alg, blocksize, key_a_size, keysize);
-+ if ((buf=kmalloc (test_size, GFP_KERNEL)) == NULL) {
-+ ret= -ENOMEM;
-+ goto out;
-+ }
-+ get_random_bytes(test_key, keysize);
-+ ret = ixt_a->ixt_a_hmac_set_key(ixt_a, test_key_a, test_key, keysize);
-+ if (ret < 0 )
-+ goto out;
-+ get_random_bytes(test_auth, BUFSZ);
-+ ret=ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
-+ printk(KERN_INFO
-+ "klips_info: ipsec_alg_test_auth: "
-+ "ret=%d\n", ret);
-+ {
-+ /* Shamelessly taken from drivers/md sources O:) */
-+ unsigned long now;
-+ int i, count, max=0;
-+ int speed;
-+ for (i = 0; i < 5; i++) {
-+ now = jiffies;
-+ count = 0;
-+ while (jiffies == now) {
-+ mb();
-+ ixt_a->ixt_a_hmac_hash(ixt_a, test_key_a, test_auth, BUFSZ, test_hash, AHHMAC_HASHLEN);
-+ mb();
-+ count++;
-+ mb();
-+ }
-+ if (count > max)
-+ max = count;
-+ }
-+ speed = max * (HZ * BUFSZ / 1024);
-+ printk(KERN_INFO
-+ "klips_info: ipsec_alg_test_auth: "
-+ "%s hash speed=%d KB/s\n",
-+ ixt_a->ixt_name,
-+ speed);
-+ }
-+out:
-+ if (buf) kfree(buf);
-+ if (ixt_a) ipsec_alg_put((struct ipsec_alg *)ixt_a);
-+ return ret;
-+ #undef test_auth
-+ #undef test_key_a
-+ #undef test_key
-+ #undef test_hash
-+ #undef test_size
-+}
-+
-+int ipsec_alg_test(unsigned alg_type, unsigned alg_id, int test) {
-+ switch(alg_type) {
-+ case IPSEC_ALG_TYPE_ENCRYPT:
-+ return ipsec_alg_test_encrypt(alg_id, test);
-+ break;
-+ case IPSEC_ALG_TYPE_AUTH:
-+ return ipsec_alg_test_auth(alg_id, test);
-+ break;
-+ }
-+ printk(KERN_ERR "klips_info: ipsec_alg_test() called incorrectly: "
-+ "alg_type=%d alg_id=%d\n",
-+ alg_type, alg_id);
-+ return -EINVAL;
-+}
-+
-+int ipsec_alg_init(void) {
-+ KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
-+ "KLIPS alg v=%d.%d.%d-%d (EALG_MAX=%d, AALG_MAX=%d)\n",
-+ IPSEC_ALG_VERSION_QUAD(IPSEC_ALG_VERSION),
-+ SADB_EALG_MAX, SADB_AALG_MAX);
-+ /* Initialize tables */
-+ write_lock_bh(&ipsec_alg_lock);
-+ ipsec_alg_hash_init();
-+ write_unlock_bh(&ipsec_alg_lock);
-+
-+ /* Initialize static algos */
-+ KLIPS_PRINT(1, "klips_info:ipsec_alg_init: "
-+ "calling ipsec_alg_static_init()\n");
-+
-+ /* If we are suppose to use our AES, and don't have CryptoAPI enabled... */
-+#if defined(CONFIG_IPSEC_ENC_AES) && CONFIG_IPSEC_ENC_AES && !defined(CONFIG_IPSEC_ENC_AES_MODULE) && !CONFIG_IPSEC_ENC_CRYPTOAPI && !defined(CONFIG_IPSEC_ENC_CRYPTOAPI_MODULE)
-+ {
-+ extern int ipsec_aes_init(void);
-+ ipsec_aes_init();
-+ }
-+#endif
-+
-+ /* If we are doing CryptoAPI, then init */
-+#if defined(CONFIG_IPSEC_ENC_CRYPTOAPI) && CONFIG_IPSEC_ENC_CRYPTOAPI && !defined(CONFIG_IPSEC_ENC_CRYPTOAPI_MODULE)
-+ {
-+ extern int ipsec_cryptoapi_init(void);
-+ ipsec_cryptoapi_init();
-+ }
-+#endif
-+
-+
-+ return 0;
-+}
-+
-+/**********************************************
-+ *
-+ * INTERFACE for ipsec_sa init and wipe
-+ *
-+ **********************************************/
-+
-+/*
-+ * Called from pluto -> pfkey_v2_parser.c:pfkey_ipsec_sa_init()
-+ */
-+int ipsec_alg_sa_init(struct ipsec_sa *sa_p) {
-+ struct ipsec_alg_enc *ixt_e;
-+ struct ipsec_alg_auth *ixt_a;
-+
-+ /* Only ESP for now ... */
-+ if (sa_p->ips_said.proto != IPPROTO_ESP)
-+ return -EPROTONOSUPPORT;
-+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_init() :"
-+ "entering for encalg=%d, authalg=%d\n",
-+ sa_p->ips_encalg, sa_p->ips_authalg);
-+ if ((ixt_e=(struct ipsec_alg_enc *)
-+ ipsec_alg_get(IPSEC_ALG_TYPE_ENCRYPT, sa_p->ips_encalg))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug: ipsec_alg_sa_init() :"
-+ "found ipsec_alg (ixt_e=%p) for encalg=%d\n",
-+ ixt_e, sa_p->ips_encalg);
-+ sa_p->ips_alg_enc=ixt_e;
-+ }
-+ if ((ixt_a=(struct ipsec_alg_auth *)
-+ ipsec_alg_get(IPSEC_ALG_TYPE_AUTH, sa_p->ips_authalg))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug: ipsec_alg_sa_init() :"
-+ "found ipsec_alg (ixt_a=%p) for auth=%d\n",
-+ ixt_a, sa_p->ips_authalg);
-+ sa_p->ips_alg_auth=ixt_a;
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * Called from pluto -> ipsec_sa.c:ipsec_sa_delchain()
-+ */
-+int ipsec_alg_sa_wipe(struct ipsec_sa *sa_p) {
-+ struct ipsec_alg *ixt;
-+ if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_enc)) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
-+ "unlinking for encalg=%d\n",
-+ ixt->ixt_alg_id);
-+ ipsec_alg_put(ixt);
-+ }
-+ if ((ixt=(struct ipsec_alg *)sa_p->ips_alg_auth)) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug: ipsec_alg_sa_wipe() :"
-+ "unlinking for authalg=%d\n",
-+ ixt->ixt_alg_id);
-+ ipsec_alg_put(ixt);
-+ }
-+ return 0;
-+}
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_xform_get_info(char *buffer,
-+ char **start,
-+ off_t offset,
-+ int length IPSEC_PROC_LAST_ARG)
-+{
-+ int len = 0;
-+ off_t begin = 0;
-+ int i;
-+ struct list_head *head;
-+ struct ipsec_alg *ixt;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_tncfg_get_info: "
-+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
-+ buffer,
-+ *start,
-+ (int)offset,
-+ length);
-+
-+ for(i = 0, head = ipsec_alg_hash_table; i< IPSEC_ALG_HASHSZ; i++, head++)
-+ {
-+ struct list_head *p;
-+ for (p=head->next; p!=head; p=p->next)
-+ {
-+ ixt = list_entry(p, struct ipsec_alg, ixt_list);
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ "VERSION=%d TYPE=%d ID=%d NAME=%s REFCNT=%d ",
-+ ixt->ixt_version, ixt->ixt_alg_type, ixt->ixt_alg_id,
-+ ixt->ixt_name, ixt->ixt_refcnt);
-+
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ "STATE=%08x BLOCKSIZE=%d IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
-+ ixt->ixt_state, ixt->ixt_blocksize,
-+ ixt->ixt_ivlen, ixt->ixt_keyminbits, ixt->ixt_keymaxbits);
-+
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ "IVLEN=%d KEYMINBITS=%d KEYMAXBITS=%d ",
-+ ixt->ixt_ivlen, ixt->ixt_keyminbits, ixt->ixt_keymaxbits);
-+
-+ switch(ixt->ixt_alg_type)
-+ {
-+ case IPSEC_ALG_TYPE_AUTH:
-+ {
-+ struct ipsec_alg_auth *auth = (struct ipsec_alg_auth *)ixt;
-+
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ "KEYLEN=%d CTXSIZE=%d AUTHLEN=%d ",
-+ auth->ixt_a_keylen, auth->ixt_a_ctx_size,
-+ auth->ixt_a_authlen);
-+ break;
-+ }
-+ case IPSEC_ALG_TYPE_ENCRYPT:
-+ {
-+ struct ipsec_alg_enc *enc = (struct ipsec_alg_enc *)ixt;
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ "KEYLEN=%d CTXSIZE=%d ",
-+ enc->ixt_e_keylen, enc->ixt_e_ctx_size);
-+
-+ break;
-+ }
-+ }
-+
-+ len += ipsec_snprintf(buffer+len, length-len, "\n");
-+ }
-+ }
-+
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ len -= (offset - begin); /* Start slop */
-+ if (len > length)
-+ len = length;
-+ return len;
-+}
-+
-+
-+/*
-+ * As the author of this module, I ONLY ALLOW using it from
-+ * GPL (or same LICENSE TERMS as kernel source) modules.
-+ *
-+ * In respect to hardware crypto engines this means:
-+ * * Closed-source device drivers ARE NOT ALLOWED to use
-+ * this interface.
-+ * * Closed-source VHDL/Verilog firmware running on
-+ * the crypto hardware device IS ALLOWED to use this interface
-+ * via a GPL (or same LICENSE TERMS as kernel source) device driver.
-+ * --Juan Jose Ciarlante 20/03/2002 (thanks RGB for the correct wording)
-+ */
-+
-+/*
-+ * These symbols can only be used from GPL modules
-+ * for now, I'm disabling this because it creates false
-+ * symbol problems for old modutils.
-+ */
-+
-+/* #ifndef EXPORT_SYMBOL_GPL */
-+#undef EXPORT_SYMBOL_GPL
-+#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
-+/* #endif */
-+EXPORT_SYMBOL_GPL(register_ipsec_alg);
-+EXPORT_SYMBOL_GPL(unregister_ipsec_alg);
-+EXPORT_SYMBOL_GPL(ipsec_alg_test);
-+#endif /* CONFIG_IPSEC_ALG */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_alg_aes.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,263 @@
-+/*
-+ * ipsec_alg AES cipher stubs
-+ *
-+ * Author: JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
-+ *
-+ * ipsec_alg_aes.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * Fixes by:
-+ * PK: Pawel Krawczyk <kravietz@aba.krakow.pl>
-+ * Fixes list:
-+ * PK: make XCBC comply with latest draft (keylength)
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+/*
-+ * special case: ipsec core modular with this static algo inside:
-+ * must avoid MODULE magic for this file
-+ */
-+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_AES
-+#undef MODULE
-+#endif
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+
-+#include <linux/kernel.h> /* printk() */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/string.h>
-+
-+/* Check if __exit is defined, if not null it */
-+#ifndef __exit
-+#define __exit
-+#endif
-+
-+/* Low freeswan header coupling */
-+#include "openswan/ipsec_alg.h"
-+#include "crypto/aes_cbc.h"
-+
-+#define CONFIG_IPSEC_ALG_AES_MAC 1
-+
-+#define AES_CONTEXT_T aes_context
-+MODULE_AUTHOR("JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>");
-+static int debug=0;
-+MODULE_PARM(debug, "i");
-+static int test=0;
-+MODULE_PARM(test, "i");
-+static int excl=0;
-+MODULE_PARM(excl, "i");
-+static int keyminbits=0;
-+MODULE_PARM(keyminbits, "i");
-+static int keymaxbits=0;
-+MODULE_PARM(keymaxbits, "i");
-+
-+#if CONFIG_IPSEC_ALG_AES_MAC
-+#include "crypto/aes_xcbc_mac.h"
-+
-+/*
-+ * Not IANA number yet (draft-ietf-ipsec-ciph-aes-xcbc-mac-00.txt).
-+ * We use 9 for non-modular algorithm and none for modular, thus
-+ * forcing user to specify one on module load. -kravietz
-+ */
-+#ifdef MODULE
-+static int auth_id=0;
-+#else
-+static int auth_id=9;
-+#endif
-+MODULE_PARM(auth_id, "i");
-+#endif
-+
-+#define ESP_AES 12 /* truely _constant_ :) */
-+
-+/* 128, 192 or 256 */
-+#define ESP_AES_KEY_SZ_MIN 16 /* 128 bit secret key */
-+#define ESP_AES_KEY_SZ_MAX 32 /* 256 bit secret key */
-+#define ESP_AES_CBC_BLK_LEN 16 /* AES-CBC block size */
-+
-+/* Values according to draft-ietf-ipsec-ciph-aes-xcbc-mac-02.txt
-+ * -kravietz
-+ */
-+#define ESP_AES_MAC_KEY_SZ 16 /* 128 bit MAC key */
-+#define ESP_AES_MAC_BLK_LEN 16 /* 128 bit block */
-+
-+static int _aes_set_key(struct ipsec_alg_enc *alg, __u8 * key_e, const __u8 * key, size_t keysize) {
-+ int ret;
-+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
-+ ret=AES_set_key(ctx, key, keysize)!=0? 0: -EINVAL;
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:_aes_set_key:"
-+ "ret=%d key_e=%p key=%p keysize=%d\n",
-+ ret, key_e, key, keysize);
-+ return ret;
-+}
-+static int _aes_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
-+ AES_CONTEXT_T *ctx=(AES_CONTEXT_T*)key_e;
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:_aes_cbc_encrypt:"
-+ "key_e=%p in=%p ilen=%d iv=%p encrypt=%d\n",
-+ key_e, in, ilen, iv, encrypt);
-+ return AES_cbc_encrypt(ctx, in, in, ilen, iv, encrypt);
-+}
-+#if CONFIG_IPSEC_ALG_AES_MAC
-+static int _aes_mac_set_key(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * key, int keylen) {
-+ aes_context_mac *ctxm=(aes_context_mac *)key_a;
-+ return AES_xcbc_mac_set_key(ctxm, key, keylen)? 0 : -EINVAL;
-+}
-+static int _aes_mac_hash(struct ipsec_alg_auth *alg, __u8 * key_a, const __u8 * dat, int len, __u8 * hash, int hashlen) {
-+ int ret;
-+ char hash_buf[16];
-+ aes_context_mac *ctxm=(aes_context_mac *)key_a;
-+ ret=AES_xcbc_mac_hash(ctxm, dat, len, hash_buf);
-+ memcpy(hash, hash_buf, hashlen);
-+ return ret;
-+}
-+static struct ipsec_alg_auth ipsec_alg_AES_MAC = {
-+ ixt_version: IPSEC_ALG_VERSION,
-+ ixt_module: THIS_MODULE,
-+ ixt_refcnt: ATOMIC_INIT(0),
-+ ixt_alg_type: IPSEC_ALG_TYPE_AUTH,
-+ ixt_alg_id: 0,
-+ ixt_name: "aes_mac",
-+ ixt_blocksize: ESP_AES_MAC_BLK_LEN,
-+ ixt_keyminbits: ESP_AES_MAC_KEY_SZ*8,
-+ ixt_keymaxbits: ESP_AES_MAC_KEY_SZ*8,
-+ ixt_a_keylen: ESP_AES_MAC_KEY_SZ,
-+ ixt_a_ctx_size: sizeof(aes_context_mac),
-+ ixt_a_hmac_set_key: _aes_mac_set_key,
-+ ixt_a_hmac_hash:_aes_mac_hash,
-+};
-+#endif /* CONFIG_IPSEC_ALG_AES_MAC */
-+static struct ipsec_alg_enc ipsec_alg_AES = {
-+ ixt_version: IPSEC_ALG_VERSION,
-+ ixt_module: THIS_MODULE,
-+ ixt_refcnt: ATOMIC_INIT(0),
-+ ixt_alg_type: IPSEC_ALG_TYPE_ENCRYPT,
-+ ixt_alg_id: ESP_AES,
-+ ixt_name: "aes",
-+ ixt_blocksize: ESP_AES_CBC_BLK_LEN,
-+ ixt_keyminbits: ESP_AES_KEY_SZ_MIN*8,
-+ ixt_keymaxbits: ESP_AES_KEY_SZ_MAX*8,
-+ ixt_e_keylen: ESP_AES_KEY_SZ_MAX,
-+ ixt_e_ctx_size: sizeof(AES_CONTEXT_T),
-+ ixt_e_set_key: _aes_set_key,
-+ ixt_e_cbc_encrypt:_aes_cbc_encrypt,
-+};
-+
-+#if defined(CONFIG_IPSEC_ENC_AES_MODULE)
-+IPSEC_ALG_MODULE_INIT_MOD( ipsec_aes_init )
-+#else
-+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_aes_init )
-+#endif
-+{
-+ int ret, test_ret;
-+
-+ if (keyminbits)
-+ ipsec_alg_AES.ixt_keyminbits=keyminbits;
-+ if (keymaxbits) {
-+ ipsec_alg_AES.ixt_keymaxbits=keymaxbits;
-+ if (keymaxbits*8>ipsec_alg_AES.ixt_keymaxbits)
-+ ipsec_alg_AES.ixt_e_keylen=keymaxbits*8;
-+ }
-+ if (excl) ipsec_alg_AES.ixt_state |= IPSEC_ALG_ST_EXCL;
-+ ret=register_ipsec_alg_enc(&ipsec_alg_AES);
-+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
-+ ipsec_alg_AES.ixt_alg_type,
-+ ipsec_alg_AES.ixt_alg_id,
-+ ipsec_alg_AES.ixt_name,
-+ ret);
-+ if (ret==0 && test) {
-+ test_ret=ipsec_alg_test(
-+ ipsec_alg_AES.ixt_alg_type,
-+ ipsec_alg_AES.ixt_alg_id,
-+ test);
-+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
-+ ipsec_alg_AES.ixt_alg_type,
-+ ipsec_alg_AES.ixt_alg_id,
-+ test_ret);
-+ }
-+#if CONFIG_IPSEC_ALG_AES_MAC
-+ if (auth_id!=0){
-+ int ret;
-+ ipsec_alg_AES_MAC.ixt_alg_id=auth_id;
-+ ret=register_ipsec_alg_auth(&ipsec_alg_AES_MAC);
-+ printk("ipsec_aes_init(alg_type=%d alg_id=%d name=%s): ret=%d\n",
-+ ipsec_alg_AES_MAC.ixt_alg_type,
-+ ipsec_alg_AES_MAC.ixt_alg_id,
-+ ipsec_alg_AES_MAC.ixt_name,
-+ ret);
-+ if (ret==0 && test) {
-+ test_ret=ipsec_alg_test(
-+ ipsec_alg_AES_MAC.ixt_alg_type,
-+ ipsec_alg_AES_MAC.ixt_alg_id,
-+ test);
-+ printk("ipsec_aes_init(alg_type=%d alg_id=%d): test_ret=%d\n",
-+ ipsec_alg_AES_MAC.ixt_alg_type,
-+ ipsec_alg_AES_MAC.ixt_alg_id,
-+ test_ret);
-+ }
-+ } else {
-+ printk(KERN_DEBUG "klips_debug: experimental ipsec_alg_AES_MAC not registered [Ok] (auth_id=%d)\n", auth_id);
-+ }
-+#endif /* CONFIG_IPSEC_ALG_AES_MAC */
-+ return ret;
-+}
-+
-+#if defined(CONFIG_IPSEC_ENC_AES_MODULE)
-+IPSEC_ALG_MODULE_EXIT_MOD( ipsec_aes_fini )
-+#else
-+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_aes_fini )
-+#endif
-+{
-+#if CONFIG_IPSEC_ALG_AES_MAC
-+ if (auth_id) unregister_ipsec_alg_auth(&ipsec_alg_AES_MAC);
-+#endif /* CONFIG_IPSEC_ALG_AES_MAC */
-+ unregister_ipsec_alg_enc(&ipsec_alg_AES);
-+ return;
-+}
-+#ifdef MODULE_LICENSE
-+MODULE_LICENSE("GPL");
-+#endif
-+
-+#if 0+NOT_YET
-+#ifndef MODULE
-+/*
-+ * This is intended for static module setups, currently
-+ * doesn't work for modular ipsec.o with static algos inside
-+ */
-+static int setup_keybits(const char *str)
-+{
-+ unsigned aux;
-+ char *end;
-+
-+ aux = simple_strtoul(str,&end,0);
-+ if (aux != 128 && aux != 192 && aux != 256)
-+ return 0;
-+ keyminbits = aux;
-+
-+ if (*end == 0 || *end != ',')
-+ return 1;
-+ str=end+1;
-+ aux = simple_strtoul(str, NULL, 0);
-+ if (aux != 128 && aux != 192 && aux != 256)
-+ return 0;
-+ if (aux >= keyminbits)
-+ keymaxbits = aux;
-+ return 1;
-+}
-+__setup("ipsec_aes_keybits=", setup_keybits);
-+#endif
-+#endif
-+EXPORT_NO_SYMBOLS;
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_alg_cryptoapi.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,421 @@
-+/*
-+ * ipsec_alg to linux cryptoapi GLUE
-+ *
-+ * Authors: CODE.ar TEAM
-+ * Harpo MAxx <harpo@linuxmendoza.org.ar>
-+ * JuanJo Ciarlante <jjo-ipsec@mendoza.gov.ar>
-+ * Luciano Ruete <docemeses@softhome.net>
-+ *
-+ * ipsec_alg_cryptoapi.c,v 1.1.2.1 2003/11/21 18:12:23 jjo Exp
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * Example usage:
-+ * modinfo -p ipsec_cryptoapi (quite useful info, including supported algos)
-+ * modprobe ipsec_cryptoapi
-+ * modprobe ipsec_cryptoapi test=1
-+ * modprobe ipsec_cryptoapi excl=1 (exclusive cipher/algo)
-+ * modprobe ipsec_cryptoapi noauto=1 aes=1 twofish=1 (only these ciphers)
-+ * modprobe ipsec_cryptoapi aes=128,128 (force these keylens)
-+ * modprobe ipsec_cryptoapi des_ede3=0 (everything but 3DES)
-+ */
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+/*
-+ * special case: ipsec core modular with this static algo inside:
-+ * must avoid MODULE magic for this file
-+ */
-+#if CONFIG_IPSEC_MODULE && CONFIG_IPSEC_ALG_CRYPTOAPI
-+#undef MODULE
-+#endif
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+
-+#include <linux/kernel.h> /* printk() */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/string.h>
-+
-+/* Check if __exit is defined, if not null it */
-+#ifndef __exit
-+#define __exit
-+#endif
-+
-+/* warn the innocent */
-+#if !defined (CONFIG_CRYPTO) && !defined (CONFIG_CRYPTO_MODULE)
-+#warning "No linux CryptoAPI found, install 2.4.22+ or 2.6.x"
-+#define NO_CRYPTOAPI_SUPPORT
-+#endif
-+/* Low Openswan header coupling */
-+#include "openswan/ipsec_alg.h"
-+
-+#include <linux/crypto.h>
-+#ifdef CRYPTO_API_VERSION_CODE
-+#warning "Old CryptoAPI is not supported. Only linux-2.4.22+ or linux-2.6.x are supported"
-+#define NO_CRYPTOAPI_SUPPORT
-+#endif
-+
-+#ifdef NO_CRYPTOAPI_SUPPORT
-+#warning "Building an unusable module :P"
-+/* Catch old CryptoAPI by not allowing module to load */
-+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
-+{
-+ printk(KERN_WARNING "ipsec_cryptoapi.o was not built on stock Linux CryptoAPI (2.4.22+ or 2.6.x), not loading.\n");
-+ return -EINVAL;
-+}
-+#else
-+#include <asm/scatterlist.h>
-+#include <asm/pgtable.h>
-+#include <linux/mm.h>
-+
-+#define CIPHERNAME_AES "aes"
-+#define CIPHERNAME_3DES "des3_ede"
-+#define CIPHERNAME_BLOWFISH "blowfish"
-+#define CIPHERNAME_CAST "cast5"
-+#define CIPHERNAME_SERPENT "serpent"
-+#define CIPHERNAME_TWOFISH "twofish"
-+
-+#define ESP_3DES 3
-+#define ESP_AES 12
-+#define ESP_BLOWFISH 7 /* truely _constant_ :) */
-+#define ESP_CAST 6 /* quite constant :) */
-+#define ESP_SERPENT 252 /* from ipsec drafts */
-+#define ESP_TWOFISH 253 /* from ipsec drafts */
-+
-+#define AH_MD5 2
-+#define AH_SHA 3
-+#define DIGESTNAME_MD5 "md5"
-+#define DIGESTNAME_SHA1 "sha1"
-+
-+MODULE_AUTHOR("Juanjo Ciarlante, Harpo MAxx, Luciano Ruete");
-+static int debug=0;
-+MODULE_PARM(debug, "i");
-+static int test=0;
-+MODULE_PARM(test, "i");
-+static int excl=0;
-+MODULE_PARM(excl, "i");
-+
-+static int noauto = 0;
-+MODULE_PARM(noauto,"i");
-+MODULE_PARM_DESC(noauto, "Dont try all known algos, just setup enabled ones");
-+
-+static int des_ede3[] = {-1, -1};
-+static int aes[] = {-1, -1};
-+static int blowfish[] = {-1, -1};
-+static int cast[] = {-1, -1};
-+static int serpent[] = {-1, -1};
-+static int twofish[] = {-1, -1};
-+
-+MODULE_PARM(des_ede3,"1-2i");
-+MODULE_PARM(aes,"1-2i");
-+MODULE_PARM(blowfish,"1-2i");
-+MODULE_PARM(cast,"1-2i");
-+MODULE_PARM(serpent,"1-2i");
-+MODULE_PARM(twofish,"1-2i");
-+MODULE_PARM_DESC(des_ede3, "0: disable | 1: force_enable | min,max: dontuse");
-+MODULE_PARM_DESC(aes, "0: disable | 1: force_enable | min,max: keybitlens");
-+MODULE_PARM_DESC(blowfish, "0: disable | 1: force_enable | min,max: keybitlens");
-+MODULE_PARM_DESC(cast, "0: disable | 1: force_enable | min,max: keybitlens");
-+MODULE_PARM_DESC(serpent, "0: disable | 1: force_enable | min,max: keybitlens");
-+MODULE_PARM_DESC(twofish, "0: disable | 1: force_enable | min,max: keybitlens");
-+
-+struct ipsec_alg_capi_cipher {
-+ const char *ciphername; /* cryptoapi's ciphername */
-+ unsigned blocksize;
-+ unsigned short minbits;
-+ unsigned short maxbits;
-+ int *parm; /* lkm param for this cipher */
-+ struct ipsec_alg_enc alg; /* note it's not a pointer */
-+};
-+static struct ipsec_alg_capi_cipher alg_capi_carray[] = {
-+ { CIPHERNAME_AES , 16, 128, 256, aes , { ixt_alg_id: ESP_AES, }},
-+ { CIPHERNAME_TWOFISH , 16, 128, 256, twofish, { ixt_alg_id: ESP_TWOFISH, }},
-+ { CIPHERNAME_SERPENT , 16, 128, 256, serpent, { ixt_alg_id: ESP_SERPENT, }},
-+ { CIPHERNAME_CAST , 8, 128, 128, cast , { ixt_alg_id: ESP_CAST, }},
-+ { CIPHERNAME_BLOWFISH , 8, 96, 448, blowfish,{ ixt_alg_id: ESP_BLOWFISH, }},
-+ { CIPHERNAME_3DES , 8, 192, 192, des_ede3,{ ixt_alg_id: ESP_3DES, }},
-+ { NULL, 0, 0, 0, NULL, {} }
-+};
-+#ifdef NOT_YET
-+struct ipsec_alg_capi_digest {
-+ const char *digestname; /* cryptoapi's digestname */
-+ struct digest_implementation *di;
-+ struct ipsec_alg_auth alg; /* note it's not a pointer */
-+};
-+static struct ipsec_alg_capi_cipher alg_capi_darray[] = {
-+ { DIGESTNAME_MD5, NULL, { ixt_alg_id: AH_MD5, }},
-+ { DIGESTNAME_SHA1, NULL, { ixt_alg_id: AH_SHA, }},
-+ { NULL, NULL, {} }
-+};
-+#endif
-+/*
-+ * "generic" linux cryptoapi setup_cipher() function
-+ */
-+int setup_cipher(const char *ciphername)
-+{
-+ return crypto_alg_available(ciphername, 0);
-+}
-+
-+/*
-+ * setups ipsec_alg_capi_cipher "hyper" struct components, calling
-+ * register_ipsec_alg for cointaned ipsec_alg object
-+ */
-+static void _capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e);
-+static __u8 * _capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen);
-+static int _capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt);
-+
-+static int
-+setup_ipsec_alg_capi_cipher(struct ipsec_alg_capi_cipher *cptr)
-+{
-+ int ret;
-+ cptr->alg.ixt_version = IPSEC_ALG_VERSION;
-+ cptr->alg.ixt_module = THIS_MODULE;
-+ atomic_set (& cptr->alg.ixt_refcnt, 0);
-+ strncpy (cptr->alg.ixt_name , cptr->ciphername, sizeof (cptr->alg.ixt_name));
-+
-+ cptr->alg.ixt_blocksize=cptr->blocksize;
-+ cptr->alg.ixt_keyminbits=cptr->minbits;
-+ cptr->alg.ixt_keymaxbits=cptr->maxbits;
-+ cptr->alg.ixt_state = 0;
-+ if (excl) cptr->alg.ixt_state |= IPSEC_ALG_ST_EXCL;
-+ cptr->alg.ixt_e_keylen=cptr->alg.ixt_keymaxbits/8;
-+ cptr->alg.ixt_e_ctx_size = 0;
-+ cptr->alg.ixt_alg_type = IPSEC_ALG_TYPE_ENCRYPT;
-+ cptr->alg.ixt_e_new_key = _capi_new_key;
-+ cptr->alg.ixt_e_destroy_key = _capi_destroy_key;
-+ cptr->alg.ixt_e_cbc_encrypt = _capi_cbc_encrypt;
-+ cptr->alg.ixt_data = cptr;
-+
-+ ret=register_ipsec_alg_enc(&cptr->alg);
-+ printk("setup_ipsec_alg_capi_cipher(): "
-+ "alg_type=%d alg_id=%d name=%s "
-+ "keyminbits=%d keymaxbits=%d, ret=%d\n",
-+ cptr->alg.ixt_alg_type,
-+ cptr->alg.ixt_alg_id,
-+ cptr->alg.ixt_name,
-+ cptr->alg.ixt_keyminbits,
-+ cptr->alg.ixt_keymaxbits,
-+ ret);
-+ return ret;
-+}
-+/*
-+ * called in ipsec_sa_wipe() time, will destroy key contexts
-+ * and do 1 unbind()
-+ */
-+static void
-+_capi_destroy_key (struct ipsec_alg_enc *alg, __u8 *key_e)
-+{
-+ struct crypto_tfm *tfm=(struct crypto_tfm*)key_e;
-+
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug: _capi_destroy_key:"
-+ "name=%s key_e=%p \n",
-+ alg->ixt_name, key_e);
-+ if (!key_e) {
-+ printk(KERN_ERR "klips_debug: _capi_destroy_key:"
-+ "name=%s NULL key_e!\n",
-+ alg->ixt_name);
-+ return;
-+ }
-+ crypto_free_tfm(tfm);
-+}
-+
-+/*
-+ * create new key context, need alg->ixt_data to know which
-+ * (of many) cipher inside this module is the target
-+ */
-+static __u8 *
-+_capi_new_key (struct ipsec_alg_enc *alg, const __u8 *key, size_t keylen)
-+{
-+ struct ipsec_alg_capi_cipher *cptr;
-+ struct crypto_tfm *tfm=NULL;
-+
-+ cptr = alg->ixt_data;
-+ if (!cptr) {
-+ printk(KERN_ERR "_capi_new_key(): "
-+ "NULL ixt_data (?!) for \"%s\" algo\n"
-+ , alg->ixt_name);
-+ goto err;
-+ }
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
-+ "name=%s cptr=%p key=%p keysize=%d\n",
-+ alg->ixt_name, cptr, key, keylen);
-+
-+ /*
-+ * alloc tfm
-+ */
-+ tfm = crypto_alloc_tfm(cptr->ciphername, CRYPTO_TFM_MODE_CBC);
-+ if (!tfm) {
-+ printk(KERN_ERR "_capi_new_key(): "
-+ "NULL tfm for \"%s\" cryptoapi (\"%s\") algo\n"
-+ , alg->ixt_name, cptr->ciphername);
-+ goto err;
-+ }
-+ if (crypto_cipher_setkey(tfm, key, keylen) < 0) {
-+ printk(KERN_ERR "_capi_new_key(): "
-+ "failed new_key() for \"%s\" cryptoapi algo (keylen=%d)\n"
-+ , alg->ixt_name, keylen);
-+ crypto_free_tfm(tfm);
-+ tfm=NULL;
-+ }
-+err:
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:_capi_new_key:"
-+ "name=%s key=%p keylen=%d tfm=%p\n",
-+ alg->ixt_name, key, keylen, tfm);
-+ return (__u8 *) tfm;
-+}
-+/*
-+ * core encryption function: will use cx->ci to call actual cipher's
-+ * cbc function
-+ */
-+static int
-+_capi_cbc_encrypt(struct ipsec_alg_enc *alg, __u8 * key_e, __u8 * in, int ilen, const __u8 * iv, int encrypt) {
-+ int error =0;
-+ struct crypto_tfm *tfm=(struct crypto_tfm *)key_e;
-+ struct scatterlist sg = {
-+ .page = virt_to_page(in),
-+ .offset = (unsigned long)(in) % PAGE_SIZE,
-+ .length=ilen,
-+ };
-+ if (debug > 1)
-+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
-+ "key_e=%p "
-+ "in=%p out=%p ilen=%d iv=%p encrypt=%d\n"
-+ , key_e
-+ , in, in, ilen, iv, encrypt);
-+ crypto_cipher_set_iv(tfm, iv, crypto_tfm_alg_ivsize(tfm));
-+ if (encrypt)
-+ error = crypto_cipher_encrypt (tfm, &sg, &sg, ilen);
-+ else
-+ error = crypto_cipher_decrypt (tfm, &sg, &sg, ilen);
-+ if (debug > 1)
-+ printk(KERN_DEBUG "klips_debug:_capi_cbc_encrypt:"
-+ "error=%d\n"
-+ , error);
-+ return (error<0)? error : ilen;
-+}
-+/*
-+ * main initialization loop: for each cipher in list, do
-+ * 1) setup cryptoapi cipher else continue
-+ * 2) register ipsec_alg object
-+ */
-+static int
-+setup_cipher_list (struct ipsec_alg_capi_cipher* clist)
-+{
-+ struct ipsec_alg_capi_cipher *cptr;
-+ /* foreach cipher in list ... */
-+ for (cptr=clist;cptr->ciphername;cptr++) {
-+ /*
-+ * see if cipher has been disabled (0) or
-+ * if noauto set and not enabled (1)
-+ */
-+ if (cptr->parm[0] == 0 || (noauto && cptr->parm[0] < 0)) {
-+ if (debug>0)
-+ printk(KERN_INFO "setup_cipher_list(): "
-+ "ciphername=%s skipped at user request: "
-+ "noauto=%d parm[0]=%d parm[1]=%d\n"
-+ , cptr->ciphername
-+ , noauto
-+ , cptr->parm[0]
-+ , cptr->parm[1]);
-+ continue;
-+ }
-+ /*
-+ * use a local ci to avoid touching cptr->ci,
-+ * if register ipsec_alg success then bind cipher
-+ */
-+ if( setup_cipher(cptr->ciphername) ) {
-+ if (debug > 0)
-+ printk(KERN_DEBUG "klips_debug:"
-+ "setup_cipher_list():"
-+ "ciphername=%s found\n"
-+ , cptr->ciphername);
-+ if (setup_ipsec_alg_capi_cipher(cptr) == 0) {
-+
-+
-+ } else {
-+ printk(KERN_ERR "klips_debug:"
-+ "setup_cipher_list():"
-+ "ciphername=%s failed ipsec_alg_register\n"
-+ , cptr->ciphername);
-+ }
-+ } else {
-+ if (debug>0)
-+ printk(KERN_INFO "setup_cipher_list(): lookup for ciphername=%s: not found \n",
-+ cptr->ciphername);
-+ }
-+ }
-+ return 0;
-+}
-+/*
-+ * deregister ipsec_alg objects and unbind ciphers
-+ */
-+static int
-+unsetup_cipher_list (struct ipsec_alg_capi_cipher* clist)
-+{
-+ struct ipsec_alg_capi_cipher *cptr;
-+ /* foreach cipher in list ... */
-+ for (cptr=clist;cptr->ciphername;cptr++) {
-+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
-+ unregister_ipsec_alg_enc(&cptr->alg);
-+ }
-+ }
-+ return 0;
-+}
-+/*
-+ * test loop for registered algos
-+ */
-+static int
-+test_cipher_list (struct ipsec_alg_capi_cipher* clist)
-+{
-+ int test_ret;
-+ struct ipsec_alg_capi_cipher *cptr;
-+ /* foreach cipher in list ... */
-+ for (cptr=clist;cptr->ciphername;cptr++) {
-+ if (cptr->alg.ixt_state & IPSEC_ALG_ST_REGISTERED) {
-+ test_ret=ipsec_alg_test(
-+ cptr->alg.ixt_alg_type,
-+ cptr->alg.ixt_alg_id,
-+ test);
-+ printk("test_cipher_list(alg_type=%d alg_id=%d): test_ret=%d\n",
-+ cptr->alg.ixt_alg_type,
-+ cptr->alg.ixt_alg_id,
-+ test_ret);
-+ }
-+ }
-+ return 0;
-+}
-+
-+IPSEC_ALG_MODULE_INIT_STATIC( ipsec_cryptoapi_init )
-+{
-+ int ret, test_ret;
-+ if ((ret=setup_cipher_list(alg_capi_carray)) < 0)
-+ return -EPROTONOSUPPORT;
-+ if (ret==0 && test) {
-+ test_ret=test_cipher_list(alg_capi_carray);
-+ }
-+ return ret;
-+}
-+IPSEC_ALG_MODULE_EXIT_STATIC( ipsec_cryptoapi_fini )
-+{
-+ unsetup_cipher_list(alg_capi_carray);
-+ return;
-+}
-+#ifdef MODULE_LICENSE
-+MODULE_LICENSE("GPL");
-+#endif
-+
-+EXPORT_NO_SYMBOLS;
-+#endif /* NO_CRYPTOAPI_SUPPORT */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_esp.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,558 @@
-+/*
-+ * processing code for ESP
-+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipsec_esp_c_version[] = "RCSID $Id$";
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define proto_priv cb
-+#endif /* NET21 */
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h"
-+#include "openswan/ipsec_xmit.h"
-+
-+#include "openswan/ipsec_auth.h"
-+
-+#ifdef CONFIG_IPSEC_ESP
-+#include "openswan/ipsec_esp.h"
-+#endif /* CONFIG_IPSEC_ESP */
-+
-+#include "openswan/ipsec_proto.h"
-+#include "openswan/ipsec_alg.h"
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_esp = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+
-+#ifdef CONFIG_IPSEC_ESP
-+enum ipsec_rcv_value
-+ipsec_rcv_esp_checks(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb)
-+{
-+ __u8 proto;
-+ int len; /* packet length */
-+
-+ len = skb->len;
-+ proto = irs->ipp->protocol;
-+
-+ /* XXX this will need to be 8 for IPv6 */
-+ if ((proto == IPPROTO_ESP) && ((len - irs->iphlen) % 4)) {
-+ printk("klips_error:ipsec_rcv: "
-+ "got packet with content length = %d from %s -- should be on 4 octet boundary, packet dropped\n",
-+ len - irs->iphlen,
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_BADLEN;
-+ }
-+
-+ if(skb->len < (irs->hard_header_len + sizeof(struct iphdr) + sizeof(struct esphdr))) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
-+ "klips_debug:ipsec_rcv: "
-+ "runt esp packet of skb->len=%d received from %s, dropped.\n",
-+ skb->len,
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_BADLEN;
-+ }
-+
-+ irs->protostuff.espstuff.espp = (struct esphdr *)(skb->data + irs->iphlen);
-+ irs->said.spi = irs->protostuff.espstuff.espp->esp_spi;
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+enum ipsec_rcv_value
-+ipsec_rcv_esp_decrypt_setup(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb,
-+ __u32 *replay,
-+ unsigned char **authenticator)
-+{
-+ struct esphdr *espp = irs->protostuff.espstuff.espp;
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "packet from %s received with seq=%d (iv)=0x%08x%08x iplen=%d esplen=%d sa=%s\n",
-+ irs->ipsaddr_txt,
-+ (__u32)ntohl(espp->esp_rpl),
-+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) )),
-+ (__u32)ntohl(*((__u32 *)(espp->esp_iv) + 1)),
-+ irs->len,
-+ irs->ilen,
-+ irs->sa_len ? irs->sa : " (error)");
-+
-+ *replay = ntohl(espp->esp_rpl);
-+ *authenticator = &(skb->data[irs->len - irs->authlen]);
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+enum ipsec_rcv_value
-+ipsec_rcv_esp_authcalc(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb)
-+{
-+ struct auth_alg *aa;
-+ struct esphdr *espp = irs->protostuff.espstuff.espp;
-+ union {
-+ MD5_CTX md5;
-+ SHA1_CTX sha1;
-+ } tctx;
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if (irs->ipsp->ips_alg_auth) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "ipsec_alg hashing proto=%d... ",
-+ irs->said.proto);
-+ if(irs->said.proto == IPPROTO_ESP) {
-+ ipsec_alg_sa_esp_hash(irs->ipsp,
-+ (caddr_t)espp, irs->ilen,
-+ irs->hash, AHHMAC_HASHLEN);
-+ return IPSEC_RCV_OK;
-+ }
-+ return IPSEC_RCV_BADPROTO;
-+ }
-+#endif
-+ aa = irs->authfuncs;
-+
-+ /* copy the initialized keying material */
-+ memcpy(&tctx, irs->ictx, irs->ictx_len);
-+
-+ (*aa->update)((void *)&tctx, (caddr_t)espp, irs->ilen);
-+
-+ (*aa->final)(irs->hash, (void *)&tctx);
-+
-+ memcpy(&tctx, irs->octx, irs->octx_len);
-+
-+ (*aa->update)((void *)&tctx, irs->hash, aa->hashlen);
-+ (*aa->final)(irs->hash, (void *)&tctx);
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+
-+enum ipsec_rcv_value
-+ipsec_rcv_esp_decrypt(struct ipsec_rcv_state *irs)
-+{
-+ struct ipsec_sa *ipsp = irs->ipsp;
-+ struct esphdr *espp = irs->protostuff.espstuff.espp;
-+ int esphlen = 0;
-+ __u8 *idat; /* pointer to content to be decrypted/authenticated */
-+ __u32 iv[2];
-+ int pad = 0, padlen;
-+ int badpad = 0;
-+ int i;
-+ struct sk_buff *skb;
-+#ifdef CONFIG_IPSEC_ALG
-+ struct ipsec_alg_enc *ixt_e=NULL;
-+#endif /* CONFIG_IPSEC_ALG */
-+
-+ skb=irs->skb;
-+
-+ idat = skb->data + irs->iphlen;
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if ((ixt_e=ipsp->ips_alg_enc)) {
-+ esphlen = ESP_HEADER_LEN + ixt_e->ixt_ivlen/8;
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "encalg=%d esphlen=%d\n",
-+ ipsp->ips_encalg, esphlen);
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ipsp->ips_encalg) {
-+ case ESP_3DES:
-+ iv[0] = *((__u32 *)(espp->esp_iv) );
-+ iv[1] = *((__u32 *)(espp->esp_iv) + 1);
-+ esphlen = sizeof(struct esphdr);
-+ break;
-+ default:
-+ ipsp->ips_errs.ips_alg_errs += 1;
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_ESP_BADALG;
-+ }
-+
-+ idat += esphlen;
-+ irs->ilen -= esphlen;
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if (ixt_e)
-+ {
-+ if (ipsec_alg_esp_encrypt(ipsp,
-+ idat, irs->ilen, espp->esp_iv,
-+ IPSEC_ALG_DECRYPT) <= 0)
-+ {
-+ printk("klips_error:ipsec_rcv: "
-+ "got packet with esplen = %d "
-+ "from %s -- should be on "
-+ "ENC(%d) octet boundary, "
-+ "packet dropped\n",
-+ irs->ilen,
-+ irs->ipsaddr_txt,
-+ ipsp->ips_encalg);
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_BAD_DECRYPT;
-+ }
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ipsp->ips_encalg) {
-+ case ESP_3DES:
-+ if ((irs->ilen) % 8) {
-+ ipsp->ips_errs.ips_encsize_errs += 1;
-+ printk("klips_error:ipsec_rcv: "
-+ "got packet with esplen = %d from %s -- should be on 8 octet boundary, packet dropped\n",
-+ irs->ilen,
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_3DES_BADBLOCKING;
-+ }
-+ des_ede3_cbc_encrypt((des_cblock *)idat,
-+ (des_cblock *)idat,
-+ irs->ilen,
-+ ((struct des_eks *)(ipsp->ips_key_e))[0].ks,
-+ ((struct des_eks *)(ipsp->ips_key_e))[1].ks,
-+ ((struct des_eks *)(ipsp->ips_key_e))[2].ks,
-+ (des_cblock *)iv, 0);
-+ break;
-+ }
-+
-+ ipsec_rcv_dmp("postdecrypt", skb->data, skb->len);
-+
-+ irs->next_header = idat[irs->ilen - 1];
-+ padlen = idat[irs->ilen - 2];
-+ pad = padlen + 2 + irs->authlen;
-+
-+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
-+ "klips_debug:ipsec_rcv: "
-+ "padlen=%d, contents: 0x<offset>: 0x<value> 0x<value> ...\n",
-+ padlen);
-+
-+ for (i = 1; i <= padlen; i++) {
-+ if((i % 16) == 1) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
-+ "klips_debug: %02x:",
-+ i - 1);
-+ }
-+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
-+ " %02x",
-+ idat[irs->ilen - 2 - padlen + i - 1]);
-+ if(i != idat[irs->ilen - 2 - padlen + i - 1]) {
-+ badpad = 1;
-+ }
-+ if((i % 16) == 0) {
-+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
-+ "\n");
-+ }
-+ }
-+ if((i % 16) != 1) {
-+ KLIPS_PRINTMORE(debug_rcv & DB_RX_IPAD,
-+ "\n");
-+ }
-+ if(badpad) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
-+ "klips_debug:ipsec_rcv: "
-+ "warning, decrypted packet from %s has bad padding\n",
-+ irs->ipsaddr_txt);
-+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
-+ "klips_debug:ipsec_rcv: "
-+ "...may be bad decryption -- not dropped\n");
-+ ipsp->ips_errs.ips_encpad_errs += 1;
-+ }
-+
-+ KLIPS_PRINT(debug_rcv & DB_RX_IPAD,
-+ "klips_debug:ipsec_rcv: "
-+ "packet decrypted from %s: next_header = %d, padding = %d\n",
-+ irs->ipsaddr_txt,
-+ irs->next_header,
-+ pad - 2 - irs->authlen);
-+
-+ irs->ipp->tot_len = htons(ntohs(irs->ipp->tot_len) - (esphlen + pad));
-+
-+ /*
-+ * move the IP header forward by the size of the ESP header, which
-+ * will remove the the ESP header from the packet.
-+ */
-+ memmove((void *)(skb->data + esphlen),
-+ (void *)(skb->data), irs->iphlen);
-+
-+ ipsec_rcv_dmp("esp postmove", skb->data, skb->len);
-+
-+ /* skb_pull below, will move up by esphlen */
-+
-+ /* XXX not clear how this can happen, as the message indicates */
-+ if(skb->len < esphlen) {
-+ printk(KERN_WARNING
-+ "klips_error:ipsec_rcv: "
-+ "tried to skb_pull esphlen=%d, %d available. This should never happen, please report.\n",
-+ esphlen, (int)(skb->len));
-+ return IPSEC_RCV_ESP_DECAPFAIL;
-+ }
-+ skb_pull(skb, esphlen);
-+
-+ irs->ipp = (struct iphdr *)skb->data;
-+
-+ ipsec_rcv_dmp("esp postpull", skb->data, skb->len);
-+
-+ /* now, trip off the padding from the end */
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "trimming to %d.\n",
-+ irs->len - esphlen - pad);
-+ if(pad + esphlen <= irs->len) {
-+ skb_trim(skb, irs->len - esphlen - pad);
-+ } else {
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "bogus packet, size is zero or negative, dropping.\n");
-+ return IPSEC_RCV_DECAPFAIL;
-+ }
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_esp_setup(struct ipsec_xmit_state *ixs)
-+{
-+ __u32 iv[2];
-+ struct esphdr *espp;
-+ int ilen = 0;
-+ int padlen = 0, i;
-+ unsigned char *dat;
-+ unsigned char *idat, *pad;
-+ __u8 hash[AH_AMAX];
-+ union {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ MD5_CTX md5;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ SHA1_CTX sha1;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ } tctx;
-+
-+ dat = (unsigned char *)ixs->iph;
-+
-+ espp = (struct esphdr *)(dat + ixs->iphlen);
-+ espp->esp_spi = ixs->ipsp->ips_said.spi;
-+ espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
-+
-+ switch(ixs->ipsp->ips_encalg) {
-+#if defined(CONFIG_IPSEC_ENC_3DES)
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ iv[0] = *((__u32*)&(espp->esp_iv) ) =
-+ ((__u32*)(ixs->ipsp->ips_iv))[0];
-+ iv[1] = *((__u32*)&(espp->esp_iv) + 1) =
-+ ((__u32*)(ixs->ipsp->ips_iv))[1];
-+ break;
-+#endif /* defined(CONFIG_IPSEC_ENC_3DES) */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_BADALG;
-+ }
-+
-+ idat = dat + ixs->iphlen + sizeof(struct esphdr);
-+ ilen = ixs->skb->len - (ixs->iphlen + sizeof(struct esphdr) + ixs->authlen);
-+
-+ /* Self-describing padding */
-+ pad = &dat[ixs->skb->len - ixs->tailroom];
-+ padlen = ixs->tailroom - 2 - ixs->authlen;
-+ for (i = 0; i < padlen; i++) {
-+ pad[i] = i + 1;
-+ }
-+ dat[ixs->skb->len - ixs->authlen - 2] = padlen;
-+
-+ dat[ixs->skb->len - ixs->authlen - 1] = ixs->iph->protocol;
-+ ixs->iph->protocol = IPPROTO_ESP;
-+
-+ switch(ixs->ipsp->ips_encalg) {
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+ des_ede3_cbc_encrypt((des_cblock *)idat,
-+ (des_cblock *)idat,
-+ ilen,
-+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[0].ks,
-+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[1].ks,
-+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[2].ks,
-+ (des_cblock *)iv, 1);
-+ break;
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_BADALG;
-+ }
-+
-+ switch(ixs->ipsp->ips_encalg) {
-+#if defined(CONFIG_IPSEC_ENC_3DES)
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ /* XXX update IV with the last 8 octets of the encryption */
-+#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK
-+ ((__u32*)(ixs->ipsp->ips_iv))[0] =
-+ ((__u32 *)(idat))[(ilen >> 2) - 2];
-+ ((__u32*)(ixs->ipsp->ips_iv))[1] =
-+ ((__u32 *)(idat))[(ilen >> 2) - 1];
-+#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
-+ prng_bytes(&ipsec_prng, (char *)ixs->ipsp->ips_iv, EMT_ESPDES_IV_SZ);
-+#endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
-+ break;
-+#endif /* defined(CONFIG_IPSEC_ENC_3DES) */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_BADALG;
-+ }
-+
-+ switch(ixs->ipsp->ips_authalg) {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5:
-+ ipsec_xmit_dmp("espp", (char*)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
-+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
-+ ipsec_xmit_dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
-+ ipsec_xmit_dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Final(hash, &tctx.md5);
-+ ipsec_xmit_dmp("ictx hash", (char*)&hash, sizeof(hash));
-+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
-+ ipsec_xmit_dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, hash, AHMD596_ALEN);
-+ ipsec_xmit_dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Final(hash, &tctx.md5);
-+ ipsec_xmit_dmp("octx hash", (char*)&hash, sizeof(hash));
-+ memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
-+
-+ /* paranoid */
-+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
-+ memset((caddr_t)hash, 0, sizeof(*hash));
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA:
-+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
-+ SHA1Update(&tctx.sha1, (caddr_t)espp, ixs->skb->len - ixs->iphlen - ixs->authlen);
-+ SHA1Final(hash, &tctx.sha1);
-+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
-+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
-+ SHA1Final(hash, &tctx.sha1);
-+ memcpy(&(dat[ixs->skb->len - ixs->authlen]), hash, ixs->authlen);
-+
-+ /* paranoid */
-+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
-+ memset((caddr_t)hash, 0, sizeof(*hash));
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ case AH_NONE:
-+ break;
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_AH_BADALG;
-+ }
-+#ifdef NET_21
-+ ixs->skb->h.raw = (unsigned char*)espp;
-+#endif /* NET_21 */
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+
-+struct xform_functions esp_xform_funcs[]={
-+ { rcv_checks: ipsec_rcv_esp_checks,
-+ rcv_setup_auth: ipsec_rcv_esp_decrypt_setup,
-+ rcv_calc_auth: ipsec_rcv_esp_authcalc,
-+ rcv_decrypt: ipsec_rcv_esp_decrypt,
-+
-+ xmit_setup: ipsec_xmit_esp_setup,
-+ xmit_headroom: sizeof(struct esphdr),
-+ xmit_needtailroom: 1,
-+ },
-+};
-+
-+struct inet_protocol esp_protocol =
-+{
-+ ipsec_rcv, /* ESP handler */
-+ NULL, /* TUNNEL error control */
-+#ifdef NETDEV_25
-+ 1, /* no policy */
-+#else
-+ 0, /* next */
-+ IPPROTO_ESP, /* protocol ID */
-+ 0, /* copy */
-+ NULL, /* data */
-+ "ESP" /* name */
-+#endif
-+};
-+
-+
-+
-+#endif /* !CONFIG_IPSEC_ESP */
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.2 2004/04/06 02:49:25 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_init.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,531 @@
-+/*
-+ * @(#) Initialization code.
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998 - 2002 Richard Guy Briggs <rgb@freeswan.org>
-+ * 2001 - 2004 Michael Richardson <mcr@xelerance.com>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * /proc system code was split out into ipsec_proc.c after rev. 1.70.
-+ *
-+ */
-+
-+char ipsec_init_c_version[] = "RCSID $Id$";
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/in.h> /* struct sockaddr_in */
-+#include <linux/skbuff.h>
-+#include <linux/random.h> /* get_random_bytes() */
-+#include <openswan.h>
-+
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* 23_SPINLOCK */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* 23_SPINLOCK */
-+#endif /* SPINLOCK */
-+
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+#endif /* NET_21 */
-+
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#ifdef CONFIG_PROC_FS
-+# include <linux/proc_fs.h>
-+#endif /* CONFIG_PROC_FS */
-+
-+#ifdef NETLINK_SOCK
-+# include <linux/netlink.h>
-+#else
-+# include <net/netlink.h>
-+#endif
-+
-+#include "openswan/radij.h"
-+
-+#include "openswan/ipsec_life.h"
-+#include "openswan/ipsec_stats.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+
-+#include "openswan/ipsec_rcv.h"
-+#include "openswan/ipsec_ah.h"
-+#include "openswan/ipsec_esp.h"
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+# include "openswan/ipcomp.h"
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#include "openswan/ipsec_proto.h"
-+#include "openswan/ipsec_alg.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#if !defined(CONFIG_IPSEC_ESP) && !defined(CONFIG_IPSEC_AH)
-+#error "kernel configuration must include ESP or AH"
-+#endif
-+
-+/*
-+ * seems to be present in 2.4.10 (Linus), but also in some RH and other
-+ * distro kernels of a lower number.
-+ */
-+#ifdef MODULE_LICENSE
-+MODULE_LICENSE("GPL");
-+#endif
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_eroute = 0;
-+int debug_spi = 0;
-+int debug_netlink = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+struct prng ipsec_prng;
-+
-+extern int ipsec_device_event(struct notifier_block *dnot, unsigned long event, void *ptr);
-+/*
-+ * the following structure is required so that we receive
-+ * event notifications when network devices are enabled and
-+ * disabled (ifconfig up and down).
-+ */
-+static struct notifier_block ipsec_dev_notifier={
-+ ipsec_device_event,
-+ NULL,
-+ 0
-+};
-+
-+#ifdef CONFIG_SYSCTL
-+extern int ipsec_sysctl_register(void);
-+extern void ipsec_sysctl_unregister(void);
-+#endif
-+
-+static inline int
-+openswan_inet_add_protocol(struct inet_protocol *prot, unsigned protocol)
-+{
-+#ifdef NETDEV_25
-+ return inet_add_protocol(prot, protocol);
-+#else
-+ inet_add_protocol(prot);
-+ return 0;
-+#endif
-+}
-+
-+static inline int
-+openswan_inet_del_protocol(struct inet_protocol *prot, unsigned protocol)
-+{
-+#ifdef NETDEV_25
-+ return inet_del_protocol(prot, protocol);
-+#else
-+ inet_del_protocol(prot);
-+ return 0;
-+#endif
-+}
-+
-+/* void */
-+int
-+ipsec_init(void)
-+{
-+ int error = 0;
-+ unsigned char seed[256];
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ extern int des_check_key;
-+
-+ /* turn off checking of keys */
-+ des_check_key=0;
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+
-+ KLIPS_PRINT(1, "klips_info:ipsec_init: "
-+ "KLIPS startup, Openswan KLIPS IPsec stack version: %s\n",
-+ ipsec_version_code());
-+
-+ error |= ipsec_proc_init();
-+
-+#ifdef SPINLOCK
-+ ipsec_sadb.sadb_lock = SPIN_LOCK_UNLOCKED;
-+#else /* SPINLOCK */
-+ ipsec_sadb.sadb_lock = 0;
-+#endif /* SPINLOCK */
-+
-+#ifndef SPINLOCK
-+ tdb_lock.lock = 0;
-+ eroute_lock.lock = 0;
-+#endif /* !SPINLOCK */
-+
-+ error |= ipsec_sadb_init();
-+ error |= ipsec_radijinit();
-+
-+ error |= pfkey_init();
-+
-+ error |= register_netdevice_notifier(&ipsec_dev_notifier);
-+
-+#ifdef CONFIG_IPSEC_ESP
-+ openswan_inet_add_protocol(&esp_protocol, IPPROTO_ESP);
-+#endif /* CONFIG_IPSEC_ESP */
-+
-+#ifdef CONFIG_IPSEC_AH
-+ openswan_inet_add_protocol(&ah_protocol, IPPROTO_AH);
-+#endif /* CONFIG_IPSEC_AH */
-+
-+/* we never actually link IPCOMP to the stack */
-+#ifdef IPCOMP_USED_ALONE
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ openswan_inet_add_protocol(&comp_protocol, IPPROTO_COMP);
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+#endif
-+
-+ error |= ipsec_tunnel_init_devices();
-+
-+
-+#ifdef CONFIG_SYSCTL
-+ error |= ipsec_sysctl_register();
-+#endif
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ ipsec_alg_init();
-+#endif
-+
-+ get_random_bytes((void *)seed, sizeof(seed));
-+ prng_init(&ipsec_prng, seed, sizeof(seed));
-+
-+ return error;
-+}
-+
-+
-+/* void */
-+int
-+ipsec_cleanup(void)
-+{
-+ int error = 0;
-+
-+#ifdef CONFIG_SYSCTL
-+ ipsec_sysctl_unregister();
-+#endif
-+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
-+ "klips_debug:ipsec_cleanup: "
-+ "calling ipsec_tunnel_cleanup_devices.\n");
-+ error |= ipsec_tunnel_cleanup_devices();
-+
-+ KLIPS_PRINT(debug_netlink, "called ipsec_tunnel_cleanup_devices");
-+
-+/* we never actually link IPCOMP to the stack */
-+#ifdef IPCOMP_USED_ALONE
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ if (openswan_inet_del_protocol(&comp_protocol, IPPROTO_COMP) < 0)
-+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
-+ "comp close: can't remove protocol\n");
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+#endif /* IPCOMP_USED_ALONE */
-+
-+#ifdef CONFIG_IPSEC_AH
-+ if (openswan_inet_del_protocol(&ah_protocol, IPPROTO_AH) < 0)
-+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
-+ "ah close: can't remove protocol\n");
-+#endif /* CONFIG_IPSEC_AH */
-+
-+#ifdef CONFIG_IPSEC_ESP
-+ if (openswan_inet_del_protocol(&esp_protocol, IPPROTO_ESP) < 0)
-+ printk(KERN_INFO "klips_debug:ipsec_cleanup: "
-+ "esp close: can't remove protocol\n");
-+#endif /* CONFIG_IPSEC_ESP */
-+
-+ error |= unregister_netdevice_notifier(&ipsec_dev_notifier);
-+
-+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
-+ "klips_debug:ipsec_cleanup: "
-+ "calling ipsec_sadb_cleanup.\n");
-+ error |= ipsec_sadb_cleanup(0);
-+ error |= ipsec_sadb_free();
-+
-+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
-+ "klips_debug:ipsec_cleanup: "
-+ "calling ipsec_radijcleanup.\n");
-+ error |= ipsec_radijcleanup();
-+
-+ KLIPS_PRINT(debug_pfkey, /* debug_tunnel & DB_TN_INIT, */
-+ "klips_debug:ipsec_cleanup: "
-+ "calling pfkey_cleanup.\n");
-+ error |= pfkey_cleanup();
-+
-+ ipsec_proc_cleanup();
-+
-+ prng_final(&ipsec_prng);
-+
-+ return error;
-+}
-+
-+#ifdef MODULE
-+int
-+init_module(void)
-+{
-+ int error = 0;
-+
-+ error |= ipsec_init();
-+
-+ return error;
-+}
-+
-+int
-+cleanup_module(void)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_netlink, /* debug_tunnel & DB_TN_INIT, */
-+ "klips_debug:cleanup_module: "
-+ "calling ipsec_cleanup.\n");
-+
-+ error |= ipsec_cleanup();
-+
-+ KLIPS_PRINT(1, "klips_info:cleanup_module: "
-+ "ipsec module unloaded.\n");
-+
-+ return error;
-+}
-+#endif /* MODULE */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.93 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.92 2004/03/30 15:30:39 ken
-+ * Proper Capitalization
-+ *
-+ * Revision 1.91 2004/03/22 01:51:51 ken
-+ * We are open
-+ *
-+ * Revision 1.90.4.2 2004/04/05 04:30:46 mcr
-+ * patches for alg-branch to compile/work with 2.x openswan
-+ *
-+ * Revision 1.90.4.1 2003/12/22 15:25:52 jjo
-+ * Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.90 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.89.4.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.89 2003/07/31 22:47:16 mcr
-+ * preliminary (untested by FS-team) 2.5 patches.
-+ *
-+ * Revision 1.88 2003/06/22 20:05:36 mcr
-+ * clarified why IPCOMP was not being registered, and put a new
-+ * #ifdef in rather than #if 0.
-+ *
-+ * Revision 1.87 2002/09/20 15:40:51 rgb
-+ * Added a lock to the global ipsec_sadb struct for future use.
-+ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
-+ * of freeing newly created structures when clearing the reftable upon startup
-+ * to start from a known state.
-+ *
-+ * Revision 1.86 2002/08/15 18:39:15 rgb
-+ * Move ipsec_prng outside debug code.
-+ *
-+ * Revision 1.85 2002/05/14 02:35:29 rgb
-+ * Change reference to tdb to ipsa.
-+ *
-+ * Revision 1.84 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.83 2002/04/24 07:36:28 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_init.c,v
-+ *
-+ * Revision 1.82 2002/04/20 00:12:25 rgb
-+ * Added esp IV CBC attack fix, disabled.
-+ *
-+ * Revision 1.81 2002/04/09 16:13:32 mcr
-+ * switch license to straight GPL.
-+ *
-+ * Revision 1.80 2002/03/24 07:34:08 rgb
-+ * Sanity check for at least one of AH or ESP configured.
-+ *
-+ * Revision 1.79 2002/02/05 22:55:15 mcr
-+ * added MODULE_LICENSE declaration.
-+ * This macro does not appear in all kernel versions (see comment).
-+ *
-+ * Revision 1.78 2002/01/29 17:17:55 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.77 2002/01/29 04:00:51 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.76 2002/01/29 02:13:17 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.75 2001/11/26 09:23:48 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.74 2001/11/22 05:44:11 henry
-+ * new version stuff
-+ *
-+ * Revision 1.71.2.2 2001/10/22 20:51:00 mcr
-+ * explicitely set des_check_key.
-+ *
-+ * Revision 1.71.2.1 2001/09/25 02:19:39 mcr
-+ * /proc manipulation code moved to new ipsec_proc.c
-+ *
-+ * Revision 1.73 2001/11/06 19:47:17 rgb
-+ * Changed lifetime_packets to uint32 from uint64.
-+ *
-+ * Revision 1.72 2001/10/18 04:45:19 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/freeswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.71 2001/09/20 15:32:45 rgb
-+ * Minor pfkey lifetime fixes.
-+ *
-+ * Revision 1.70 2001/07/06 19:51:21 rgb
-+ * Added inbound policy checking code for IPIP SAs.
-+ *
-+ * Revision 1.69 2001/06/14 19:33:26 rgb
-+ * Silence startup message for console, but allow it to be logged.
-+ * Update copyright date.
-+ *
-+ * Revision 1.68 2001/05/29 05:14:36 rgb
-+ * Added PMTU to /proc/net/ipsec_tncfg output. See 'man 5 ipsec_tncfg'.
-+ *
-+ * Revision 1.67 2001/05/04 16:34:52 rgb
-+ * Rremove erroneous checking of return codes for proc_net_* in 2.4.
-+ *
-+ * Revision 1.66 2001/05/03 19:40:34 rgb
-+ * Check error return codes in startup and shutdown.
-+ *
-+ * Revision 1.65 2001/02/28 05:03:27 rgb
-+ * Clean up and rationalise startup messages.
-+ *
-+ * Revision 1.64 2001/02/27 22:24:53 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.63 2000/11/29 20:14:06 rgb
-+ * Add src= to the output of /proc/net/ipsec_spi and delete dst from IPIP.
-+ *
-+ * Revision 1.62 2000/11/06 04:31:24 rgb
-+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
-+ * Fixed longlong for pre-2.4 kernels (Svenning).
-+ * Add Svenning's adaptive content compression.
-+ * Disabled registration of ipcomp handler.
-+ *
-+ * Revision 1.61 2000/10/11 13:37:54 rgb
-+ * #ifdef out debug print that causes proc/net/ipsec_version to oops.
-+ *
-+ * Revision 1.60 2000/09/20 03:59:01 rgb
-+ * Change static info functions to DEBUG_NO_STATIC to reveal function names
-+ * in oopsen.
-+ *
-+ * Revision 1.59 2000/09/16 01:06:26 rgb
-+ * Added cast of var to silence compiler warning about long fed to int
-+ * format.
-+ *
-+ * Revision 1.58 2000/09/15 11:37:01 rgb
-+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
-+ * IPCOMP zlib deflate code.
-+ *
-+ * Revision 1.57 2000/09/12 03:21:50 rgb
-+ * Moved radij_c_version printing to ipsec_version_get_info().
-+ * Reformatted ipsec_version_get_info().
-+ * Added sysctl_{,un}register() calls.
-+ *
-+ * Revision 1.56 2000/09/08 19:16:50 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
-+ *
-+ * Revision 1.55 2000/08/30 05:19:03 rgb
-+ * Cleaned up no longer used spi_next, netlink register/unregister, other
-+ * minor cleanup.
-+ * Removed cruft replaced by TDB_XFORM_NAME.
-+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
-+ * Moved debug version strings to printk when /proc/net/ipsec_version is
-+ * called.
-+ *
-+ * Revision 1.54 2000/08/20 18:31:05 rgb
-+ * Changed cosmetic alignment in spi_info.
-+ * Changed addtime and usetime to use actual value which is relative
-+ * anyways, as intended. (Momchil)
-+ *
-+ * Revision 1.53 2000/08/18 17:37:03 rgb
-+ * Added an (int) cast to shut up the compiler...
-+ *
-+ * Revision 1.52 2000/08/01 14:51:50 rgb
-+ * Removed _all_ remaining traces of DES.
-+ *
-+ * Revision 1.51 2000/07/25 20:41:22 rgb
-+ * Removed duplicate parameter in spi_getinfo.
-+ *
-+ * Revision 1.50 2000/07/17 03:21:45 rgb
-+ * Removed /proc/net/ipsec_spinew.
-+ *
-+ * Revision 1.49 2000/06/28 05:46:51 rgb
-+ * Renamed ivlen to iv_bits for consistency.
-+ * Changed output of add and use times to be relative to now.
-+ *
-+ * Revision 1.48 2000/05/11 18:26:10 rgb
-+ * Commented out calls to netlink_attach/detach to avoid activating netlink
-+ * in the kenrel config.
-+ *
-+ * Revision 1.47 2000/05/10 22:35:26 rgb
-+ * Comment out most of the startup version information.
-+ *
-+ * Revision 1.46 2000/03/22 16:15:36 rgb
-+ * Fixed renaming of dev_get (MB).
-+ *
-+ * Revision 1.45 2000/03/16 06:40:48 rgb
-+ * Hardcode PF_KEYv2 support.
-+ *
-+ * Revision 1.44 2000/01/22 23:19:20 rgb
-+ * Simplified code to use existing macro TDB_XFORM_NAME().
-+ *
-+ * Revision 1.43 2000/01/21 06:14:04 rgb
-+ * Print individual stats only if non-zero.
-+ * Removed 'bits' from each keylength for brevity.
-+ * Shortened lifetimes legend for brevity.
-+ * Changed wording from 'last_used' to the clearer 'idle'.
-+ *
-+ * Revision 1.42 1999/12/31 14:57:19 rgb
-+ * MB fix for new dummy-less proc_get_info in 2.3.35.
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_ipcomp.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,276 @@
-+/*
-+ * processing code for IPCOMP
-+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipsec_ipcomp_c_version[] = "RCSID $Id$";
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define proto_priv cb
-+#endif /* NET21 */
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h"
-+#include "openswan/ipsec_xmit.h"
-+
-+#include "openswan/ipsec_auth.h"
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+#include "openswan/ipsec_ipcomp.h"
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#include "openswan/ipsec_proto.h"
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_ipcomp = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+enum ipsec_rcv_value
-+ipsec_rcv_ipcomp_checks(struct ipsec_rcv_state *irs,
-+ struct sk_buff *skb)
-+{
-+ int ipcompminlen;
-+
-+ ipcompminlen = irs->hard_header_len + sizeof(struct iphdr);
-+
-+ if(skb->len < (ipcompminlen + sizeof(struct ipcomphdr))) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
-+ "klips_debug:ipsec_rcv: "
-+ "runt comp packet of skb->len=%d received from %s, dropped.\n",
-+ skb->len,
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_BADLEN;
-+ }
-+
-+ irs->protostuff.ipcompstuff.compp = (struct ipcomphdr *)(skb->data + irs->iphlen);
-+ irs->said.spi = htonl((__u32)ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi));
-+ return IPSEC_RCV_OK;
-+}
-+
-+enum ipsec_rcv_value
-+ipsec_rcv_ipcomp_decomp(struct ipsec_rcv_state *irs)
-+{
-+ unsigned int flags = 0;
-+ struct ipsec_sa *ipsp = irs->ipsp;
-+ struct sk_buff *skb;
-+
-+ skb=irs->skb;
-+
-+ ipsec_xmit_dmp("ipcomp", skb->data, skb->len);
-+
-+ if(ipsp == NULL) {
-+ return IPSEC_RCV_SAIDNOTFOUND;
-+ }
-+
-+#if 0
-+ /* we want to check that this wasn't the first SA on the list, because
-+ * we don't support bare IPCOMP, for unexplained reasons. MCR
-+ */
-+ if (ipsp->ips_onext != NULL) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "Incoming packet with outer IPCOMP header SA:%s: not yet supported by KLIPS, dropped\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+
-+ return IPSEC_RCV_IPCOMPALONE;
-+ }
-+#endif
-+
-+ if(sysctl_ipsec_inbound_policy_check &&
-+ ((((ntohl(ipsp->ips_said.spi) & 0x0000ffff) != ntohl(irs->said.spi)) &&
-+ (ipsp->ips_encalg != ntohl(irs->said.spi)) /* this is a workaround for peer non-compliance with rfc2393 */
-+ ))) {
-+ char sa2[SATOT_BUF];
-+ size_t sa_len2 = 0;
-+
-+ sa_len2 = satot(&ipsp->ips_said, 0, sa2, sizeof(sa2));
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "Incoming packet with SA(IPCA):%s does not match policy SA(IPCA):%s cpi=%04x cpi->spi=%08x spi=%08x, spi->cpi=%04x for SA grouping, dropped.\n",
-+ irs->sa_len ? irs->sa : " (error)",
-+ ipsp != NULL ? (sa_len2 ? sa2 : " (error)") : "NULL",
-+ ntohs(irs->protostuff.ipcompstuff.compp->ipcomp_cpi),
-+ (__u32)ntohl(irs->said.spi),
-+ ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
-+ ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0);
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_SAIDNOTFOUND;
-+ }
-+
-+ ipsp->ips_comp_ratio_cbytes += ntohs(irs->ipp->tot_len);
-+ irs->next_header = irs->protostuff.ipcompstuff.compp->ipcomp_nh;
-+
-+ skb = skb_decompress(skb, ipsp, &flags);
-+ if (!skb || flags) {
-+ spin_unlock(&tdb_lock);
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "skb_decompress() returned error flags=%x, dropped.\n",
-+ flags);
-+ if (irs->stats) {
-+ if (flags)
-+ irs->stats->rx_errors++;
-+ else
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_IPCOMPFAILED;
-+ }
-+
-+ /* make sure we update the pointer */
-+ irs->skb = skb;
-+
-+#ifdef NET_21
-+ irs->ipp = skb->nh.iph;
-+#else /* NET_21 */
-+ irs->ipp = skb->ip_hdr;
-+#endif /* NET_21 */
-+
-+ ipsp->ips_comp_ratio_dbytes += ntohs(irs->ipp->tot_len);
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "packet decompressed SA(IPCA):%s cpi->spi=%08x spi=%08x, spi->cpi=%04x, nh=%d.\n",
-+ irs->sa_len ? irs->sa : " (error)",
-+ (__u32)ntohl(irs->said.spi),
-+ ipsp != NULL ? (__u32)ntohl((ipsp->ips_said.spi)) : 0,
-+ ipsp != NULL ? (__u16)(ntohl(ipsp->ips_said.spi) & 0x0000ffff) : 0,
-+ irs->next_header);
-+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, irs->ipp);
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_ipcomp_setup(struct ipsec_xmit_state *ixs)
-+{
-+ unsigned int flags = 0;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
-+
-+ ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
-+
-+#ifdef NET_21
-+ ixs->iph = ixs->skb->nh.iph;
-+#else /* NET_21 */
-+ ixs->iph = ixs->skb->ip_hdr;
-+#endif /* NET_21 */
-+
-+ ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (debug_tunnel & DB_TN_CROUT)
-+ {
-+ if (old_tot_len > ntohs(ixs->iph->tot_len))
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_once: "
-+ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
-+ old_tot_len, ntohs(ixs->iph->tot_len),
-+ ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
-+ ntohl(ixs->ipsp->ips_said.spi),
-+ (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
-+ else
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_once: "
-+ "packet did not compress (flags = %d).\n",
-+ flags);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+struct xform_functions ipcomp_xform_funcs[]={
-+ {rcv_checks: ipsec_rcv_ipcomp_checks,
-+ rcv_decrypt: ipsec_rcv_ipcomp_decomp,
-+ xmit_setup: ipsec_xmit_ipcomp_setup,
-+ xmit_headroom: 0,
-+ xmit_needtailroom: 0,
-+ },
-+};
-+
-+#if 0
-+/* We probably don't want to install a pure IPCOMP protocol handler, but
-+ only want to handle IPCOMP if it is encapsulated inside an ESP payload
-+ (which is already handled) */
-+#ifdef CONFIG_IPSEC_IPCOMP
-+struct inet_protocol comp_protocol =
-+{
-+ ipsec_rcv, /* COMP handler */
-+ NULL, /* COMP error control */
-+#ifdef NETDEV_25
-+ 1, /* no policy */
-+#else
-+ 0, /* next */
-+ IPPROTO_COMP, /* protocol ID */
-+ 0, /* copy */
-+ NULL, /* data */
-+ "COMP" /* name */
-+#endif
-+};
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+#endif
-+
-+#endif /* CONFIG_IPSEC_IPCOMP */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_ipip.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,133 @@
-+/*
-+ * processing code for IPIP
-+ * Copyright (C) 2003 Michael Richardson <mcr@sandelman.ottawa.on.ca>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipsec_ipip_c_version[] = "RCSID $Id$";
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define proto_priv cb
-+#endif /* NET21 */
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h"
-+#include "openswan/ipsec_xmit.h"
-+
-+#include "openswan/ipsec_auth.h"
-+#include "openswan/ipsec_ipip.h"
-+#include "openswan/ipsec_param.h"
-+
-+#include "openswan/ipsec_proto.h"
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_ipip_setup(struct ipsec_xmit_state *ixs)
-+{
-+ ixs->iph->version = 4;
-+
-+ switch(sysctl_ipsec_tos) {
-+ case 0:
-+#ifdef NET_21
-+ ixs->iph->tos = ixs->skb->nh.iph->tos;
-+#else /* NET_21 */
-+ ixs->iph->tos = ixs->skb->ip_hdr->tos;
-+#endif /* NET_21 */
-+ break;
-+ case 1:
-+ ixs->iph->tos = 0;
-+ break;
-+ default:
-+ break;
-+ }
-+#ifdef NET_21
-+#ifdef NETDEV_23
-+ ixs->iph->ttl = sysctl_ip_default_ttl;
-+#else /* NETDEV_23 */
-+ ixs->iph->ttl = ip_statistics.IpDefaultTTL;
-+#endif /* NETDEV_23 */
-+#else /* NET_21 */
-+ ixs->iph->ttl = 64; /* ip_statistics.IpDefaultTTL; */
-+#endif /* NET_21 */
-+ ixs->iph->frag_off = 0;
-+ ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
-+ ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
-+ ixs->iph->protocol = IPPROTO_IPIP;
-+ ixs->iph->ihl = sizeof(struct iphdr) >> 2;
-+
-+ KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
-+
-+ ixs->newdst = (__u32)ixs->iph->daddr;
-+ ixs->newsrc = (__u32)ixs->iph->saddr;
-+
-+#ifdef NET_21
-+ ixs->skb->h.ipiph = ixs->skb->nh.iph;
-+#endif /* NET_21 */
-+ return IPSEC_XMIT_OK;
-+}
-+
-+struct xform_functions ipip_xform_funcs[]={
-+ { rcv_checks: NULL,
-+ rcv_setup_auth: NULL,
-+ rcv_calc_auth: NULL,
-+ rcv_decrypt: NULL,
-+
-+ xmit_setup: ipsec_xmit_ipip_setup,
-+ xmit_headroom: sizeof(struct iphdr),
-+ xmit_needtailroom: 0,
-+ },
-+};
-+
-+
-+
-+
-+
-+
-+
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_life.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,263 @@
-+/*
-+ * @(#) lifetime structure utilities
-+ *
-+ * Copyright (C) 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ * and Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ */
-+
-+/*
-+ * This provides series of utility functions for dealing with lifetime
-+ * structures.
-+ *
-+ * ipsec_check_lifetime - returns -1 hard lifetime exceeded
-+ * 0 soft lifetime exceeded
-+ * 1 everything is okay
-+ * based upon whether or not the count exceeds hard/soft
-+ *
-+ */
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/config.h> /* for CONFIG_IP_FORWARD */
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_life.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_eroute.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+
-+#include "openswan/ipsec_sa.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_ipe4.h"
-+#include "openswan/ipsec_ah.h"
-+#include "openswan/ipsec_esp.h"
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+#include "openswan/ipcomp.h"
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+
-+
-+enum ipsec_life_alive
-+ipsec_lifetime_check(struct ipsec_lifetime64 *il64,
-+ const char *lifename,
-+ const char *saname,
-+ enum ipsec_life_type ilt,
-+ enum ipsec_direction idir,
-+ struct ipsec_sa *ips)
-+{
-+ __u64 count;
-+ const char *dir;
-+
-+ if(saname == NULL) {
-+ saname = "unknown-SA";
-+ }
-+
-+ if(idir == ipsec_incoming) {
-+ dir = "incoming";
-+ } else {
-+ dir = "outgoing";
-+ }
-+
-+
-+ if(ilt == ipsec_life_timebased) {
-+ count = jiffies/HZ - il64->ipl_count;
-+ } else {
-+ count = il64->ipl_count;
-+ }
-+
-+ if(il64->ipl_hard &&
-+ (count > il64->ipl_hard)) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_lifetime_check: "
-+ "hard %s lifetime of SA:<%s%s%s> %s has been reached, SA expired, "
-+ "%s packet dropped.\n",
-+ lifename,
-+ IPS_XFORM_NAME(ips),
-+ saname,
-+ dir);
-+
-+ pfkey_expire(ips, 1);
-+ return ipsec_life_harddied;
-+ }
-+
-+ if(il64->ipl_soft &&
-+ (count > il64->ipl_soft)) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_lifetime_check: "
-+ "soft %s lifetime of SA:<%s%s%s> %s has been reached, SA expiring, "
-+ "soft expire message sent up, %s packet still processed.\n",
-+ lifename,
-+ IPS_XFORM_NAME(ips),
-+ saname,
-+ dir);
-+
-+ if(ips->ips_state != SADB_SASTATE_DYING) {
-+ pfkey_expire(ips, 0);
-+ }
-+ ips->ips_state = SADB_SASTATE_DYING;
-+
-+ return ipsec_life_softdied;
-+ }
-+ return ipsec_life_okay;
-+}
-+
-+
-+/*
-+ * This function takes a buffer (with length), a lifetime name and type,
-+ * and formats a string to represent the current values of the lifetime.
-+ *
-+ * It returns the number of bytes that the format took (or would take,
-+ * if the buffer were large enough: snprintf semantics).
-+ * This is used in /proc routines and in debug output.
-+ */
-+int
-+ipsec_lifetime_format(char *buffer,
-+ int buflen,
-+ char *lifename,
-+ enum ipsec_life_type timebaselife,
-+ struct ipsec_lifetime64 *lifetime)
-+{
-+ int len = 0;
-+ __u64 count;
-+
-+ if(timebaselife == ipsec_life_timebased) {
-+ count = jiffies/HZ - lifetime->ipl_count;
-+ } else {
-+ count = lifetime->ipl_count;
-+ }
-+
-+ if(lifetime->ipl_count > 1 ||
-+ lifetime->ipl_soft ||
-+ lifetime->ipl_hard) {
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0))
-+ len = ipsec_snprintf(buffer, buflen,
-+ "%s(%Lu,%Lu,%Lu)",
-+ lifename,
-+ count,
-+ lifetime->ipl_soft,
-+ lifetime->ipl_hard);
-+#else /* XXX high 32 bits are not displayed */
-+ len = ipsec_snprintf(buffer, buflen,
-+ "%s(%lu,%lu,%lu)",
-+ lifename,
-+ (unsigned long)count,
-+ (unsigned long)lifetime->ipl_soft,
-+ (unsigned long)lifetime->ipl_hard);
-+#endif
-+ }
-+
-+ return len;
-+}
-+
-+void
-+ipsec_lifetime_update_hard(struct ipsec_lifetime64 *lifetime,
-+ __u64 newvalue)
-+{
-+ if(newvalue &&
-+ (!lifetime->ipl_hard ||
-+ (newvalue < lifetime->ipl_hard))) {
-+ lifetime->ipl_hard = newvalue;
-+
-+ if(!lifetime->ipl_soft &&
-+ (lifetime->ipl_hard < lifetime->ipl_soft)) {
-+ lifetime->ipl_soft = lifetime->ipl_hard;
-+ }
-+ }
-+}
-+
-+void
-+ipsec_lifetime_update_soft(struct ipsec_lifetime64 *lifetime,
-+ __u64 newvalue)
-+{
-+ if(newvalue &&
-+ (!lifetime->ipl_soft ||
-+ (newvalue < lifetime->ipl_soft))) {
-+ lifetime->ipl_soft = newvalue;
-+
-+ if(lifetime->ipl_hard &&
-+ (lifetime->ipl_hard < lifetime->ipl_soft)) {
-+ lifetime->ipl_soft = lifetime->ipl_hard;
-+ }
-+ }
-+}
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.12 2004/04/23 20:44:35 ken
-+ * Update comments
-+ *
-+ * Revision 1.11 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.10 2004/03/30 11:03:10 paul
-+ * two more occurances of snprintf, found by Sam from a users oops msg.
-+ *
-+ * Revision 1.9 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.8.4.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.8 2003/02/06 02:00:10 rgb
-+ * Fixed incorrect debugging text label
-+ *
-+ * Revision 1.7 2002/05/23 07:16:26 rgb
-+ * Fixed absolute/relative reference to lifetime count printout.
-+ *
-+ * Revision 1.6 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.5 2002/04/24 07:36:28 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_life.c,v
-+ *
-+ * Revision 1.4 2002/01/29 17:17:55 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.3 2002/01/29 02:13:17 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.2 2001/11/26 09:16:14 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:25:57 mcr
-+ * lifetime structure created and common functions created.
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_mast.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1080 @@
-+/*
-+ * IPSEC MAST code.
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipsec_mast_c_version[] = "RCSID $Id$";
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/config.h> /* for CONFIG_IP_FORWARD */
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "freeswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/tcp.h> /* struct tcphdr */
-+#include <linux/udp.h> /* struct udphdr */
-+#include <linux/skbuff.h>
-+#include <freeswan.h>
-+#include <asm/uaccess.h>
-+#include <linux/in6.h>
-+#include <net/dst.h>
-+#undef dev_kfree_skb
-+#define dev_kfree_skb(a,b) kfree_skb(a)
-+#define PHYSDEV_TYPE
-+#include <asm/checksum.h>
-+#include <net/icmp.h> /* icmp_send() */
-+#include <net/ip.h>
-+#include <linux/netfilter_ipv4.h>
-+
-+#include <linux/if_arp.h>
-+
-+#include "freeswan/radij.h"
-+#include "freeswan/ipsec_life.h"
-+#include "freeswan/ipsec_xform.h"
-+#include "freeswan/ipsec_eroute.h"
-+#include "freeswan/ipsec_encap.h"
-+#include "freeswan/ipsec_radij.h"
-+#include "freeswan/ipsec_sa.h"
-+#include "freeswan/ipsec_tunnel.h"
-+#include "freeswan/ipsec_mast.h"
-+#include "freeswan/ipsec_ipe4.h"
-+#include "freeswan/ipsec_ah.h"
-+#include "freeswan/ipsec_esp.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "freeswan/ipsec_proto.h"
-+
-+int ipsec_maxdevice_count = -1;
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_open(struct device *dev)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ /*
-+ * Can't open until attached.
-+ */
-+
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_open: "
-+ "dev = %s, prv->dev = %s\n",
-+ dev->name, prv->dev?prv->dev->name:"NONE");
-+
-+ if (prv->dev == NULL)
-+ return -ENODEV;
-+
-+ MOD_INC_USE_COUNT;
-+ return 0;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_close(struct device *dev)
-+{
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static inline int ipsec_mast_xmit2(struct sk_buff *skb)
-+{
-+ return ip_send(skb);
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_mast_send(struct ipsec_xmit_state*ixs)
-+{
-+ /* new route/dst cache code from James Morris */
-+ ixs->skb->dev = ixs->physdev;
-+ /*skb_orphan(ixs->skb);*/
-+ if((ixs->error = ip_route_output(&ixs->route,
-+ ixs->skb->nh.iph->daddr,
-+ ixs->pass ? 0 : ixs->skb->nh.iph->saddr,
-+ RT_TOS(ixs->skb->nh.iph->tos),
-+ ixs->physdev->iflink /* rgb: should this be 0? */))) {
-+ ixs->stats->tx_errors++;
-+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
-+ "klips_debug:ipsec_xmit_send: "
-+ "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
-+ ixs->error,
-+ ixs->route->u.dst.dev->name);
-+ return IPSEC_XMIT_ROUTEERR;
-+ }
-+ if(ixs->dev == ixs->route->u.dst.dev) {
-+ ip_rt_put(ixs->route);
-+ /* This is recursion, drop it. */
-+ ixs->stats->tx_errors++;
-+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
-+ "klips_debug:ipsec_xmit_send: "
-+ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
-+ ixs->dev->name);
-+ return IPSEC_XMIT_RECURSDETECT;
-+ }
-+ dst_release(ixs->skb->dst);
-+ ixs->skb->dst = &ixs->route->u.dst;
-+ ixs->stats->tx_bytes += ixs->skb->len;
-+ if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {
-+ ixs->stats->tx_errors++;
-+ printk(KERN_WARNING
-+ "klips_error:ipsec_xmit_send: "
-+ "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
-+ (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),
-+ ixs->skb->len);
-+ return IPSEC_XMIT_PUSHPULLERR;
-+ }
-+ __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);
-+#ifdef SKB_RESET_NFCT
-+ nf_conntrack_put(ixs->skb->nfct);
-+ ixs->skb->nfct = NULL;
-+#ifdef CONFIG_NETFILTER_DEBUG
-+ ixs->skb->nf_debug = 0;
-+#endif /* CONFIG_NETFILTER_DEBUG */
-+#endif /* SKB_RESET_NFCT */
-+ KLIPS_PRINT(debug_mast & DB_MAST_XMIT,
-+ "klips_debug:ipsec_xmit_send: "
-+ "...done, calling ip_send() on device:%s\n",
-+ ixs->skb->dev ? ixs->skb->dev->name : "NULL");
-+ KLIPS_IP_PRINT(debug_mast & DB_MAST_XMIT, ixs->skb->nh.iph);
-+ {
-+ int err;
-+
-+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,
-+ ipsec_mast_xmit2);
-+ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
-+ if(net_ratelimit())
-+ printk(KERN_ERR
-+ "klips_error:ipsec_xmit_send: "
-+ "ip_send() failed, err=%d\n",
-+ -err);
-+ ixs->stats->tx_errors++;
-+ ixs->stats->tx_aborted_errors++;
-+ ixs->skb = NULL;
-+ return IPSEC_XMIT_IPSENDFAILURE;
-+ }
-+ }
-+ ixs->stats->tx_packets++;
-+
-+ ixs->skb = NULL;
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+void
-+ipsec_mast_cleanup(struct ipsec_xmit_state*ixs)
-+{
-+#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
-+ netif_wake_queue(ixs->dev);
-+#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
-+ ixs->dev->tbusy = 0;
-+#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
-+ if(ixs->saved_header) {
-+ kfree(ixs->saved_header);
-+ }
-+ if(ixs->skb) {
-+ dev_kfree_skb(ixs->skb, FREE_WRITE);
-+ }
-+ if(ixs->oskb) {
-+ dev_kfree_skb(ixs->oskb, FREE_WRITE);
-+ }
-+ if (ixs->ips.ips_ident_s.data) {
-+ kfree(ixs->ips.ips_ident_s.data);
-+ }
-+ if (ixs->ips.ips_ident_d.data) {
-+ kfree(ixs->ips.ips_ident_d.data);
-+ }
-+}
-+
-+#if 0
-+/*
-+ * This function assumes it is being called from dev_queue_xmit()
-+ * and that skb is filled properly by that function.
-+ */
-+int
-+ipsec_mast_start_xmit(struct sk_buff *skb, struct device *dev, IPsecSAref_t SAref)
-+{
-+ struct ipsec_xmit_state ixs_mem;
-+ struct ipsec_xmit_state *ixs = &ixs_mem;
-+ enum ipsec_xmit_value stat = IPSEC_XMIT_OK;
-+
-+ /* dev could be a mast device, but should be optional, I think... */
-+ /* SAref is also optional, but one of the two must be present. */
-+ /* I wonder if it could accept no device or saref and guess? */
-+
-+/* ipsec_xmit_sanity_check_dev(ixs); */
-+
-+ ipsec_xmit_sanity_check_skb(ixs);
-+
-+ ipsec_xmit_adjust_hard_header(ixs);
-+
-+ stat = ipsec_xmit_encap_bundle(ixs);
-+ if(stat != IPSEC_XMIT_OK) {
-+ /* SA processing failed */
-+ }
-+
-+ ipsec_xmit_hard_header_restore();
-+}
-+#endif
-+
-+DEBUG_NO_STATIC struct net_device_stats *
-+ipsec_mast_get_stats(struct device *dev)
-+{
-+ return &(((struct ipsecpriv *)(dev->priv))->mystats);
-+}
-+
-+/*
-+ * Revectored calls.
-+ * For each of these calls, a field exists in our private structure.
-+ */
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_hard_header(struct sk_buff *skb, struct device *dev,
-+ unsigned short type, void *daddr, void *saddr, unsigned len)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+ struct device *tmp;
-+ int ret;
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(skb == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_hard_header: "
-+ "no skb...\n");
-+ return -ENODATA;
-+ }
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_hard_header: "
-+ "no device...\n");
-+ return -ENODEV;
-+ }
-+
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_hard_header: "
-+ "skb->dev=%s dev=%s.\n",
-+ skb->dev ? skb->dev->name : "NULL",
-+ dev->name);
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_hard_header: "
-+ "no private space associated with dev=%s\n",
-+ dev->name ? dev->name : "NULL");
-+ return -ENODEV;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_hard_header: "
-+ "no physical device associated with dev=%s\n",
-+ dev->name ? dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+ /* check if we have to send a IPv6 packet. It might be a Router
-+ Solicitation, where the building of the packet happens in
-+ reverse order:
-+ 1. ll hdr,
-+ 2. IPv6 hdr,
-+ 3. ICMPv6 hdr
-+ -> skb->nh.raw is still uninitialized when this function is
-+ called!! If this is no IPv6 packet, we can print debugging
-+ messages, otherwise we skip all debugging messages and just
-+ build the ll header */
-+ if(type != ETH_P_IPV6) {
-+ /* execute this only, if we don't have to build the
-+ header for a IPv6 packet */
-+ if(!prv->hard_header) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_hard_header: "
-+ "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
-+ saddr,
-+ daddr,
-+ len,
-+ type,
-+ dev->name);
-+ KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->nh.iph->saddr),
-+ (__u32)ntohl(skb->nh.iph->daddr) );
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+#define da ((struct device *)(prv->dev))->dev_addr
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_hard_header: "
-+ "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
-+ saddr,
-+ daddr,
-+ len,
-+ type,
-+ dev->name,
-+ prv->dev->name,
-+ da[0], da[1], da[2], da[3], da[4], da[5]);
-+ KLIPS_PRINTMORE(debug_mast & DB_MAST_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->nh.iph->saddr),
-+ (__u32)ntohl(skb->nh.iph->daddr) );
-+ } else {
-+ KLIPS_PRINT(debug_mast,
-+ "klips_debug:ipsec_mast_hard_header: "
-+ "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
-+ }
-+ tmp = skb->dev;
-+ skb->dev = prv->dev;
-+ ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
-+ skb->dev = tmp;
-+ return ret;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_rebuild_header(struct sk_buff *skb)
-+{
-+ struct ipsecpriv *prv = skb->dev->priv;
-+ struct device *tmp;
-+ int ret;
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(skb->dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_rebuild_header: "
-+ "no device...");
-+ return -ENODEV;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_rebuild_header: "
-+ "no private space associated with dev=%s",
-+ skb->dev->name ? skb->dev->name : "NULL");
-+ return -ENODEV;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_rebuild_header: "
-+ "no physical device associated with dev=%s",
-+ skb->dev->name ? skb->dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+ if(!prv->rebuild_header) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_rebuild_header: "
-+ "physical device has been detached, packet dropped skb->dev=%s->NULL ",
-+ skb->dev->name);
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->nh.iph->saddr),
-+ (__u32)ntohl(skb->nh.iph->daddr) );
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast: "
-+ "Revectored rebuild_header dev=%s->%s ",
-+ skb->dev->name, prv->dev->name);
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->nh.iph->saddr),
-+ (__u32)ntohl(skb->nh.iph->daddr) );
-+ tmp = skb->dev;
-+ skb->dev = prv->dev;
-+
-+ ret = prv->rebuild_header(skb);
-+ skb->dev = tmp;
-+ return ret;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_set_mac_address(struct device *dev, void *addr)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_set_mac_address: "
-+ "no device...");
-+ return -ENODEV;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_set_mac_address: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return -ENODEV;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_set_mac_address: "
-+ "no physical device associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+ if(!prv->set_mac_address) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_set_mac_address: "
-+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
-+ dev->name);
-+ return -ENODEV;
-+ }
-+
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_set_mac_address: "
-+ "Revectored dev=%s->%s addr=0p%p\n",
-+ dev->name, prv->dev->name, addr);
-+ return prv->set_mac_address(prv->dev, addr);
-+
-+}
-+
-+DEBUG_NO_STATIC void
-+ipsec_mast_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_cache_update: "
-+ "no device...");
-+ return;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_cache_update: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_cache_update: "
-+ "no physical device associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return;
-+ }
-+
-+ if(!prv->header_cache_update) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_cache_update: "
-+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
-+ dev->name);
-+ return;
-+ }
-+
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast: "
-+ "Revectored cache_update\n");
-+ prv->header_cache_update(hh, prv->dev, haddr);
-+ return;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_neigh_setup(struct neighbour *n)
-+{
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_neigh_setup:\n");
-+
-+ if (n->nud_state == NUD_NONE) {
-+ n->ops = &arp_broken_ops;
-+ n->output = n->ops->output;
-+ }
-+ return 0;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_neigh_setup_dev(struct device *dev, struct neigh_parms *p)
-+{
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_neigh_setup_dev: "
-+ "setting up %s\n",
-+ dev ? dev->name : "NULL");
-+
-+ if (p->tbl->family == AF_INET) {
-+ p->neigh_setup = ipsec_mast_neigh_setup;
-+ p->ucast_probes = 0;
-+ p->mcast_probes = 0;
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * We call the attach routine to attach another device.
-+ */
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_attach(struct device *dev, struct device *physdev)
-+{
-+ int i;
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_attach: "
-+ "no device...");
-+ return -ENODEV;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_attach: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return -ENODATA;
-+ }
-+
-+ prv->dev = physdev;
-+ prv->hard_start_xmit = physdev->hard_start_xmit;
-+ prv->get_stats = physdev->get_stats;
-+
-+ if (physdev->hard_header) {
-+ prv->hard_header = physdev->hard_header;
-+ dev->hard_header = ipsec_mast_hard_header;
-+ } else
-+ dev->hard_header = NULL;
-+
-+ if (physdev->rebuild_header) {
-+ prv->rebuild_header = physdev->rebuild_header;
-+ dev->rebuild_header = ipsec_mast_rebuild_header;
-+ } else
-+ dev->rebuild_header = NULL;
-+
-+ if (physdev->set_mac_address) {
-+ prv->set_mac_address = physdev->set_mac_address;
-+ dev->set_mac_address = ipsec_mast_set_mac_address;
-+ } else
-+ dev->set_mac_address = NULL;
-+
-+ if (physdev->header_cache_update) {
-+ prv->header_cache_update = physdev->header_cache_update;
-+ dev->header_cache_update = ipsec_mast_cache_update;
-+ } else
-+ dev->header_cache_update = NULL;
-+
-+ dev->hard_header_len = physdev->hard_header_len;
-+
-+/* prv->neigh_setup = physdev->neigh_setup; */
-+ dev->neigh_setup = ipsec_mast_neigh_setup_dev;
-+ dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
-+ prv->mtu = physdev->mtu;
-+
-+#ifdef PHYSDEV_TYPE
-+ dev->type = physdev->type; /* ARPHRD_MAST; */
-+#endif /* PHYSDEV_TYPE */
-+
-+ dev->addr_len = physdev->addr_len;
-+ for (i=0; i<dev->addr_len; i++) {
-+ dev->dev_addr[i] = physdev->dev_addr[i];
-+ }
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(debug_mast & DB_MAST_INIT) {
-+ printk(KERN_INFO "klips_debug:ipsec_mast_attach: "
-+ "physical device %s being attached has HW address: %2x",
-+ physdev->name, physdev->dev_addr[0]);
-+ for (i=1; i < physdev->addr_len; i++) {
-+ printk(":%02x", physdev->dev_addr[i]);
-+ }
-+ printk("\n");
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ return 0;
-+}
-+
-+/*
-+ * We call the detach routine to detach the ipsec mast from another device.
-+ */
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_detach(struct device *dev)
-+{
-+ int i;
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_detach: "
-+ "no device...");
-+ return -ENODEV;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_REVEC,
-+ "klips_debug:ipsec_mast_detach: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return -ENODATA;
-+ }
-+
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_detach: "
-+ "physical device %s being detached from virtual device %s\n",
-+ prv->dev ? prv->dev->name : "NULL",
-+ dev->name);
-+
-+ prv->dev = NULL;
-+ prv->hard_start_xmit = NULL;
-+ prv->get_stats = NULL;
-+
-+ prv->hard_header = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->hard_header = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+ prv->rebuild_header = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->rebuild_header = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+ prv->set_mac_address = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->set_mac_address = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+ prv->header_cache_update = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->header_cache_update = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+#ifdef DETACH_AND_DOWN
-+ dev->neigh_setup = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+ dev->hard_header_len = 0;
-+#ifdef DETACH_AND_DOWN
-+ dev->mtu = 0;
-+#endif /* DETACH_AND_DOWN */
-+ prv->mtu = 0;
-+ for (i=0; i<MAX_ADDR_LEN; i++) {
-+ dev->dev_addr[i] = 0;
-+ }
-+ dev->addr_len = 0;
-+#ifdef PHYSDEV_TYPE
-+ dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */
-+#endif /* PHYSDEV_TYPE */
-+
-+ return 0;
-+}
-+
-+/*
-+ * We call the clear routine to detach all ipsec masts from other devices.
-+ */
-+DEBUG_NO_STATIC int
-+ipsec_mast_clear(void)
-+{
-+ int i;
-+ struct device *ipsecdev = NULL, *prvdev;
-+ struct ipsecpriv *prv;
-+ char name[9];
-+ int ret;
-+
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_clear: .\n");
-+
-+ for(i = 0; i < IPSEC_NUM_IF; i++) {
-+ sprintf(name, IPSEC_DEV_FORMAT, i);
-+ if((ipsecdev = ipsec_dev_get(name)) != NULL) {
-+ if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
-+ prvdev = (struct device *)(prv->dev);
-+ if(prvdev) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_clear: "
-+ "physical device for device %s is %s\n",
-+ name, prvdev->name);
-+ if((ret = ipsec_mast_detach(ipsecdev))) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_clear: "
-+ "error %d detatching device %s from device %s.\n",
-+ ret, name, prvdev->name);
-+ return ret;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ return 0;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_mast_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
-+{
-+ struct ipsecmastconf *cf = (struct ipsecmastconf *)&ifr->ifr_data;
-+ struct ipsecpriv *prv = dev->priv;
-+ struct device *them; /* physical device */
-+#ifdef CONFIG_IP_ALIAS
-+ char *colon;
-+ char realphysname[IFNAMSIZ];
-+#endif /* CONFIG_IP_ALIAS */
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "device not supplied.\n");
-+ return -ENODEV;
-+ }
-+
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "tncfg service call #%d for dev=%s\n",
-+ cmd,
-+ dev->name ? dev->name : "NULL");
-+ switch (cmd) {
-+ /* attach a virtual ipsec? device to a physical device */
-+ case IPSEC_SET_DEV:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "calling ipsec_mast_attatch...\n");
-+#ifdef CONFIG_IP_ALIAS
-+ /* If this is an IP alias interface, get its real physical name */
-+ strncpy(realphysname, cf->cf_name, IFNAMSIZ);
-+ realphysname[IFNAMSIZ-1] = 0;
-+ colon = strchr(realphysname, ':');
-+ if (colon) *colon = 0;
-+ them = ipsec_dev_get(realphysname);
-+#else /* CONFIG_IP_ALIAS */
-+ them = ipsec_dev_get(cf->cf_name);
-+#endif /* CONFIG_IP_ALIAS */
-+
-+ if (them == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "physical device %s requested is null\n",
-+ cf->cf_name);
-+ return -ENXIO;
-+ }
-+
-+#if 0
-+ if (them->flags & IFF_UP) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "physical device %s requested is not up.\n",
-+ cf->cf_name);
-+ return -ENXIO;
-+ }
-+#endif
-+
-+ if (prv && prv->dev) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "virtual device is already connected to %s.\n",
-+ prv->dev->name ? prv->dev->name : "NULL");
-+ return -EBUSY;
-+ }
-+ return ipsec_mast_attach(dev, them);
-+
-+ case IPSEC_DEL_DEV:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "calling ipsec_mast_detatch.\n");
-+ if (! prv->dev) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "physical device not connected.\n");
-+ return -ENODEV;
-+ }
-+ return ipsec_mast_detach(dev);
-+
-+ case IPSEC_CLR_DEV:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "calling ipsec_mast_clear.\n");
-+ return ipsec_mast_clear();
-+
-+ default:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_ioctl: "
-+ "unknown command %d.\n",
-+ cmd);
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+int
-+ipsec_mast_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
-+{
-+ struct device *dev = ptr;
-+ struct device *ipsec_dev;
-+ struct ipsecpriv *priv;
-+ char name[9];
-+ int i;
-+
-+ if (dev == NULL) {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "dev=NULL for event type %ld.\n",
-+ event);
-+ return(NOTIFY_DONE);
-+ }
-+
-+ /* check for loopback devices */
-+ if (dev && (dev->flags & IFF_LOOPBACK)) {
-+ return(NOTIFY_DONE);
-+ }
-+
-+ switch (event) {
-+ case NETDEV_DOWN:
-+ /* look very carefully at the scope of these compiler
-+ directives before changing anything... -- RGB */
-+
-+ case NETDEV_UNREGISTER:
-+ switch (event) {
-+ case NETDEV_DOWN:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_DOWN dev=%s flags=%x\n",
-+ dev->name,
-+ dev->flags);
-+ if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
-+ printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
-+ dev->name);
-+ }
-+ break;
-+ case NETDEV_UNREGISTER:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_UNREGISTER dev=%s flags=%x\n",
-+ dev->name,
-+ dev->flags);
-+ break;
-+ }
-+
-+ /* find the attached physical device and detach it. */
-+ for(i = 0; i < IPSEC_NUM_IF; i++) {
-+ sprintf(name, IPSEC_DEV_FORMAT, i);
-+ ipsec_dev = ipsec_dev_get(name);
-+ if(ipsec_dev) {
-+ priv = (struct ipsecpriv *)(ipsec_dev->priv);
-+ if(priv) {
-+ ;
-+ if(((struct device *)(priv->dev)) == dev) {
-+ /* dev_close(ipsec_dev); */
-+ /* return */ ipsec_mast_detach(ipsec_dev);
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "device '%s' has been detached.\n",
-+ ipsec_dev->name);
-+ break;
-+ }
-+ } else {
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "device '%s' has no private data space!\n",
-+ ipsec_dev->name);
-+ }
-+ }
-+ }
-+ break;
-+ case NETDEV_UP:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_UP dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_REBOOT:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_REBOOT dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_CHANGE:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_CHANGE dev=%s flags=%x\n",
-+ dev->name,
-+ dev->flags);
-+ break;
-+ case NETDEV_REGISTER:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_REGISTER dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_CHANGEMTU:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
-+ dev->name,
-+ dev->mtu);
-+ break;
-+ case NETDEV_CHANGEADDR:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_CHANGEADDR dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_GOING_DOWN:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_GOING_DOWN dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_CHANGENAME:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "NETDEV_CHANGENAME dev=%s\n",
-+ dev->name);
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_mast & DB_MAST_INIT,
-+ "klips_debug:ipsec_mast_device_event: "
-+ "event type %ld unrecognised for dev=%s\n",
-+ event,
-+ dev->name);
-+ break;
-+ }
-+ return NOTIFY_DONE;
-+}
-+
-+/*
-+ * Called when an ipsec mast device is initialized.
-+ * The ipsec mast device structure is passed to us.
-+ */
-+
-+int
-+ipsec_mast_init(struct device *dev)
-+{
-+ int i;
-+
-+ KLIPS_PRINT(debug_mast,
-+ "klips_debug:ipsec_mast_init: "
-+ "allocating %lu bytes initialising device: %s\n",
-+ (unsigned long) sizeof(struct ipsecpriv),
-+ dev->name ? dev->name : "NULL");
-+
-+ /* Add our mast functions to the device */
-+ dev->open = ipsec_mast_open;
-+ dev->stop = ipsec_mast_close;
-+ dev->hard_start_xmit = ipsec_mast_start_xmit;
-+ dev->get_stats = ipsec_mast_get_stats;
-+
-+ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
-+ if (dev->priv == NULL)
-+ return -ENOMEM;
-+ memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
-+
-+ for(i = 0; i < sizeof(zeroes); i++) {
-+ ((__u8*)(zeroes))[i] = 0;
-+ }
-+
-+ dev->set_multicast_list = NULL;
-+ dev->do_ioctl = ipsec_mast_ioctl;
-+ dev->hard_header = NULL;
-+ dev->rebuild_header = NULL;
-+ dev->set_mac_address = NULL;
-+ dev->header_cache_update= NULL;
-+ dev->neigh_setup = ipsec_mast_neigh_setup_dev;
-+ dev->hard_header_len = 0;
-+ dev->mtu = 0;
-+ dev->addr_len = 0;
-+ dev->type = ARPHRD_VOID; /* ARPHRD_MAST; */ /* ARPHRD_ETHER; */
-+ dev->tx_queue_len = 10; /* Small queue */
-+ memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
-+
-+ /* New-style flags. */
-+ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
-+ dev_init_buffers(dev);
-+
-+ /* We're done. Have I forgotten anything? */
-+ return 0;
-+}
-+
-+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-+/* Module specific interface (but it links with the rest of IPSEC) */
-+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-+
-+int
-+ipsec_mast_probe(struct device *dev)
-+{
-+ ipsec_mast_init(dev);
-+ return 0;
-+}
-+
-+int
-+ipsec_mast_init_devices(void)
-+{
-+ return 0;
-+}
-+
-+/* void */
-+int
-+ipsec_mast_cleanup_devices(void)
-+{
-+ int error = 0;
-+ int i;
-+ char name[10];
-+ struct device *dev_mast;
-+
-+ for(i = 0; i < ipsec_mastdevice_count; i++) {
-+ sprintf(name, MAST_DEV_FORMAT, i);
-+ if((dev_mast = ipsec_dev_get(name)) == NULL) {
-+ break;
-+ }
-+ unregister_netdev(dev_mast);
-+ kfree(dev_mast->priv);
-+ dev_mast->priv=NULL;
-+ }
-+ return error;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.3 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.2.4.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.2 2003/06/22 20:06:17 mcr
-+ * refactored mast code still had lots of ipsecX junk in it.
-+ *
-+ * Revision 1.1 2003/02/12 19:31:12 rgb
-+ * Refactored from ipsec_tunnel.c
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_md5c.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,448 @@
-+/*
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * The rest of the code is derived from MD5C.C by RSADSI. Minor cosmetic
-+ * changes to accomodate it in the kernel by ji.
-+ */
-+
-+#include <asm/byteorder.h>
-+#include <linux/string.h>
-+
-+#include "openswan/ipsec_md5h.h"
-+
-+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
-+ */
-+
-+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
-+rights reserved.
-+
-+License to copy and use this software is granted provided that it
-+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
-+Algorithm" in all material mentioning or referencing this software
-+or this function.
-+
-+License is also granted to make and use derivative works provided
-+that such works are identified as "derived from the RSA Data
-+Security, Inc. MD5 Message-Digest Algorithm" in all material
-+mentioning or referencing the derived work.
-+
-+RSA Data Security, Inc. makes no representations concerning either
-+the merchantability of this software or the suitability of this
-+software for any particular purpose. It is provided "as is"
-+without express or implied warranty of any kind.
-+
-+These notices must be retained in any copies of any part of this
-+documentation and/or software.
-+ */
-+
-+/*
-+ * Additions by JI
-+ *
-+ * HAVEMEMCOPY is defined if mem* routines are available
-+ *
-+ * HAVEHTON is defined if htons() and htonl() can be used
-+ * for big/little endian conversions
-+ *
-+ */
-+
-+#define HAVEMEMCOPY
-+#ifdef __LITTLE_ENDIAN
-+#define LITTLENDIAN
-+#endif
-+#ifdef __BIG_ENDIAN
-+#define BIGENDIAN
-+#endif
-+
-+/* Constants for MD5Transform routine.
-+ */
-+
-+#define S11 7
-+#define S12 12
-+#define S13 17
-+#define S14 22
-+#define S21 5
-+#define S22 9
-+#define S23 14
-+#define S24 20
-+#define S31 4
-+#define S32 11
-+#define S33 16
-+#define S34 23
-+#define S41 6
-+#define S42 10
-+#define S43 15
-+#define S44 21
-+
-+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
-+
-+#ifdef LITTLEENDIAN
-+#define Encode MD5_memcpy
-+#define Decode MD5_memcpy
-+#else
-+static void Encode PROTO_LIST
-+ ((unsigned char *, UINT4 *, unsigned int));
-+static void Decode PROTO_LIST
-+ ((UINT4 *, unsigned char *, unsigned int));
-+#endif
-+
-+#ifdef HAVEMEMCOPY
-+/* no need to include <memory.h> here; <linux/string.h> defines these */
-+#define MD5_memcpy memcpy
-+#define MD5_memset memset
-+#else
-+#ifdef HAVEBCOPY
-+#define MD5_memcpy(_a,_b,_c) bcopy((_b),(_a),(_c))
-+#define MD5_memset(_a,_b,_c) bzero((_a),(_c))
-+#else
-+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
-+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
-+#endif
-+#endif
-+static unsigned char PADDING[64] = {
-+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-+};
-+
-+/* F, G, H and I are basic MD5 functions.
-+ */
-+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-+#define H(x, y, z) ((x) ^ (y) ^ (z))
-+#define I(x, y, z) ((y) ^ ((x) | (~z)))
-+
-+/* ROTATE_LEFT rotates x left n bits.
-+ */
-+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-+
-+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
-+Rotation is separate from addition to prevent recomputation.
-+ */
-+#define FF(a, b, c, d, x, s, ac) { \
-+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
-+ (a) = ROTATE_LEFT ((a), (s)); \
-+ (a) += (b); \
-+ }
-+#define GG(a, b, c, d, x, s, ac) { \
-+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
-+ (a) = ROTATE_LEFT ((a), (s)); \
-+ (a) += (b); \
-+ }
-+#define HH(a, b, c, d, x, s, ac) { \
-+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
-+ (a) = ROTATE_LEFT ((a), (s)); \
-+ (a) += (b); \
-+ }
-+#define II(a, b, c, d, x, s, ac) { \
-+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
-+ (a) = ROTATE_LEFT ((a), (s)); \
-+ (a) += (b); \
-+ }
-+
-+/*
-+ * MD5 initialization. Begins an MD5 operation, writing a new context.
-+ */
-+void MD5Init(void *vcontext)
-+{
-+ MD5_CTX *context = vcontext;
-+
-+ context->count[0] = context->count[1] = 0;
-+ /* Load magic initialization constants.
-+*/
-+ context->state[0] = 0x67452301;
-+ context->state[1] = 0xefcdab89;
-+ context->state[2] = 0x98badcfe;
-+ context->state[3] = 0x10325476;
-+}
-+
-+/* MD5 block update operation. Continues an MD5 message-digest
-+ operation, processing another message block, and updating the
-+ context.
-+ */
-+void MD5Update (vcontext, input, inputLen)
-+ void *vcontext;
-+ unsigned char *input; /* input block */
-+ __u32 inputLen; /* length of input block */
-+{
-+ MD5_CTX *context = vcontext;
-+ __u32 i;
-+ unsigned int index, partLen;
-+
-+ /* Compute number of bytes mod 64 */
-+ index = (unsigned int)((context->count[0] >> 3) & 0x3F);
-+
-+ /* Update number of bits */
-+ if ((context->count[0] += ((UINT4)inputLen << 3))
-+ < ((UINT4)inputLen << 3))
-+ context->count[1]++;
-+ context->count[1] += ((UINT4)inputLen >> 29);
-+
-+ partLen = 64 - index;
-+
-+ /* Transform as many times as possible.
-+*/
-+ if (inputLen >= partLen) {
-+ MD5_memcpy
-+ ((POINTER)&context->buffer[index], (POINTER)input, partLen);
-+ MD5Transform (context->state, context->buffer);
-+
-+ for (i = partLen; i + 63 < inputLen; i += 64)
-+ MD5Transform (context->state, &input[i]);
-+
-+ index = 0;
-+ }
-+ else
-+ i = 0;
-+
-+ /* Buffer remaining input */
-+ MD5_memcpy
-+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
-+ inputLen-i);
-+}
-+
-+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
-+ the message digest and zeroizing the context.
-+ */
-+void MD5Final (digest, vcontext)
-+unsigned char digest[16]; /* message digest */
-+void *vcontext; /* context */
-+{
-+ MD5_CTX *context = vcontext;
-+ unsigned char bits[8];
-+ unsigned int index, padLen;
-+
-+ /* Save number of bits */
-+ Encode (bits, context->count, 8);
-+
-+ /* Pad out to 56 mod 64.
-+*/
-+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
-+ padLen = (index < 56) ? (56 - index) : (120 - index);
-+ MD5Update (context, PADDING, padLen);
-+
-+ /* Append length (before padding) */
-+ MD5Update (context, bits, 8);
-+
-+ if (digest != NULL) /* Bill Simpson's padding */
-+ {
-+ /* store state in digest */
-+ Encode (digest, context->state, 16);
-+
-+ /* Zeroize sensitive information.
-+ */
-+ MD5_memset ((POINTER)context, 0, sizeof (*context));
-+ }
-+}
-+
-+/* MD5 basic transformation. Transforms state based on block.
-+ */
-+static void MD5Transform (state, block)
-+UINT4 state[4];
-+unsigned char block[64];
-+{
-+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
-+
-+ Decode (x, block, 64);
-+
-+ /* Round 1 */
-+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
-+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
-+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
-+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
-+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
-+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
-+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
-+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
-+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
-+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
-+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
-+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
-+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
-+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
-+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
-+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
-+
-+ /* Round 2 */
-+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
-+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
-+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
-+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
-+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
-+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
-+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
-+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
-+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
-+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
-+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
-+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
-+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
-+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
-+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
-+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
-+
-+ /* Round 3 */
-+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
-+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
-+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
-+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
-+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
-+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
-+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
-+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
-+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
-+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
-+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
-+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
-+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
-+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
-+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
-+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
-+
-+ /* Round 4 */
-+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
-+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
-+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
-+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
-+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
-+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
-+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
-+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
-+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
-+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
-+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
-+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
-+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
-+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
-+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
-+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
-+
-+ state[0] += a;
-+ state[1] += b;
-+ state[2] += c;
-+ state[3] += d;
-+
-+ /* Zeroize sensitive information.
-+*/
-+ MD5_memset ((POINTER)x, 0, sizeof (x));
-+}
-+
-+#ifndef LITTLEENDIAN
-+
-+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
-+ a multiple of 4.
-+ */
-+static void Encode (output, input, len)
-+unsigned char *output;
-+UINT4 *input;
-+unsigned int len;
-+{
-+ unsigned int i, j;
-+
-+ for (i = 0, j = 0; j < len; i++, j += 4) {
-+ output[j] = (unsigned char)(input[i] & 0xff);
-+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
-+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
-+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
-+ }
-+}
-+
-+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
-+ a multiple of 4.
-+ */
-+static void Decode (output, input, len)
-+UINT4 *output;
-+unsigned char *input;
-+unsigned int len;
-+{
-+ unsigned int i, j;
-+
-+ for (i = 0, j = 0; j < len; i++, j += 4)
-+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
-+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
-+}
-+
-+#endif
-+
-+#ifndef HAVEMEMCOPY
-+#ifndef HAVEBCOPY
-+/* Note: Replace "for loop" with standard memcpy if possible.
-+ */
-+
-+static void MD5_memcpy (output, input, len)
-+POINTER output;
-+POINTER input;
-+unsigned int len;
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < len; i++)
-+
-+ output[i] = input[i];
-+}
-+
-+/* Note: Replace "for loop" with standard memset if possible.
-+ */
-+
-+static void MD5_memset (output, value, len)
-+POINTER output;
-+int value;
-+unsigned int len;
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < len; i++)
-+ ((char *)output)[i] = (char)value;
-+}
-+#endif
-+#endif
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.8 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.7 2002/09/10 01:45:14 mcr
-+ * changed type of MD5_CTX and SHA1_CTX to void * so that
-+ * the function prototypes would match, and could be placed
-+ * into a pointer to a function.
-+ *
-+ * Revision 1.6 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.5 2002/04/24 07:36:28 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_md5c.c,v
-+ *
-+ * Revision 1.4 1999/12/13 13:59:12 rgb
-+ * Quick fix to argument size to Update bugs.
-+ *
-+ * Revision 1.3 1999/05/21 18:09:28 henry
-+ * unnecessary <memory.h> include causes trouble in 2.2
-+ *
-+ * Revision 1.2 1999/04/06 04:54:26 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:48 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.2 1998/04/23 20:54:02 rgb
-+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
-+ * verified.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:08 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.3 1996/11/20 14:48:53 ji
-+ * Release update only.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_proc.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1127 @@
-+/*
-+ * @(#) /proc file system interface code.
-+ *
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ * 2001 Michael Richardson <mcr@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * Split out from ipsec_init.c version 1.70.
-+ */
-+
-+char ipsec_proc_c_version[] = "RCSID $Id$";
-+
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/in.h> /* struct sockaddr_in */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef SPINLOCK
-+#ifdef SPINLOCK_23
-+#include <linux/spinlock.h> /* *lock* */
-+#else /* SPINLOCK_23 */
-+#include <asm/spinlock.h> /* *lock* */
-+#endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+#include <asm/uaccess.h>
-+#include <linux/in6.h>
-+#endif /* NET_21 */
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+#ifdef CONFIG_PROC_FS
-+#include <linux/proc_fs.h>
-+#endif /* CONFIG_PROC_FS */
-+#ifdef NETLINK_SOCK
-+#include <linux/netlink.h>
-+#else
-+#include <net/netlink.h>
-+#endif
-+
-+#include "openswan/radij.h"
-+
-+#include "openswan/ipsec_life.h"
-+#include "openswan/ipsec_stats.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_xmit.h"
-+
-+#include "openswan/ipsec_rcv.h"
-+#include "openswan/ipsec_ah.h"
-+#include "openswan/ipsec_esp.h"
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+#include "openswan/ipcomp.h"
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#include "openswan/ipsec_proto.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#ifdef CONFIG_PROC_FS
-+
-+#ifdef IPSEC_PROC_SUBDIRS
-+static struct proc_dir_entry *proc_net_ipsec_dir = NULL;
-+static struct proc_dir_entry *proc_eroute_dir = NULL;
-+static struct proc_dir_entry *proc_spi_dir = NULL;
-+static struct proc_dir_entry *proc_spigrp_dir = NULL;
-+static struct proc_dir_entry *proc_birth_dir = NULL;
-+static struct proc_dir_entry *proc_stats_dir = NULL;
-+#endif
-+
-+struct ipsec_birth_reply ipsec_ipv4_birth_packet;
-+struct ipsec_birth_reply ipsec_ipv6_birth_packet;
-+
-+#define DECREMENT_UNSIGNED(X, amount) ((amount < (X)) ? (X)-amount : 0)
-+
-+extern int ipsec_xform_get_info(char *buffer, char **start,
-+ off_t offset, int length IPSEC_PROC_LAST_ARG);
-+
-+
-+/* ipsec_snprintf: like snprintf except
-+ * - size is signed and a negative value is treated as if it were 0
-+ * - the returned result is never negative --
-+ * an error generates a "?" or null output (depending on space).
-+ * (Our callers are too lazy to check for an error return.)
-+ *
-+ * @param buf String buffer
-+ * @param size Size of the string
-+ * @param fmt printf string
-+ * @param ... Variables to be displayed in fmt
-+ * @return int Return code
-+ */
-+int ipsec_snprintf(char *buf, ssize_t size, const char *fmt, ...)
-+{
-+ va_list args;
-+ int i;
-+ size_t possize = size < 0? 0 : size;
-+ va_start(args, fmt);
-+ i = vsnprintf(buf,possize,fmt,args);
-+ va_end(args);
-+ if (i < 0) {
-+ /* create empty output in place of error */
-+ i = 0;
-+ if (size > 0) {
-+ *buf = '\0';
-+ }
-+ }
-+ return i;
-+}
-+
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_eroute_get_info(char *buffer,
-+ char **start,
-+ off_t offset,
-+ int length IPSEC_PROC_LAST_ARG)
-+{
-+ struct wsbuf w = {buffer, length, offset, 0, 0};
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (debug_radij & DB_RJ_DUMPTREES)
-+ rj_dumptrees(); /* XXXXXXXXX */
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_eroute_get_info: "
-+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
-+ buffer,
-+ *start,
-+ (int)offset,
-+ length);
-+
-+ spin_lock_bh(&eroute_lock);
-+
-+ rj_walktree(rnh, ipsec_rj_walker_procprint, &w);
-+/* rj_walktree(mask_rjhead, ipsec_rj_walker_procprint, &w); */
-+
-+ spin_unlock_bh(&eroute_lock);
-+
-+ *start = buffer + (offset - w.begin); /* Start of wanted data */
-+ return w.len - (offset - w.begin);
-+}
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_spi_get_info(char *buffer,
-+ char **start,
-+ off_t offset,
-+ int length IPSEC_PROC_LAST_ARG)
-+{
-+ const int max_content = length > 0? length-1 : 0;
-+ int len = 0;
-+ off_t begin = 0;
-+ int i;
-+ struct ipsec_sa *sa_p;
-+ char sa[SATOT_BUF];
-+ char buf_s[SUBNETTOA_BUF];
-+ char buf_d[SUBNETTOA_BUF];
-+ size_t sa_len;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_spi_get_info: "
-+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
-+ buffer,
-+ *start,
-+ (int)offset,
-+ length);
-+
-+ spin_lock_bh(&tdb_lock);
-+
-+ for (i = 0; i < SADB_HASHMOD; i++) {
-+ for (sa_p = ipsec_sadb_hash[i];
-+ sa_p;
-+ sa_p = sa_p->ips_hnext) {
-+ atomic_inc(&sa_p->ips_refcount);
-+ sa_len = satot(&sa_p->ips_said, 'x', sa, sizeof(sa));
-+ len += ipsec_snprintf(buffer+len, length-len, "%s ",
-+ sa_len ? sa : " (error)");
-+
-+ len += ipsec_snprintf(buffer+len, length-len, "%s%s%s",
-+ IPS_XFORM_NAME(sa_p));
-+
-+ len += ipsec_snprintf(buffer+len, length-len, ": dir=%s",
-+ (sa_p->ips_flags & EMT_INBOUND) ?
-+ "in " : "out");
-+
-+ if(sa_p->ips_addr_s) {
-+ addrtoa(((struct sockaddr_in*)(sa_p->ips_addr_s))->sin_addr,
-+ 0, buf_s, sizeof(buf_s));
-+ len += ipsec_snprintf(buffer+len, length-len, " src=%s",
-+ buf_s);
-+ }
-+
-+ if((sa_p->ips_said.proto == IPPROTO_IPIP)
-+ && (sa_p->ips_flags & SADB_X_SAFLAGS_INFLOW)) {
-+ subnettoa(sa_p->ips_flow_s.u.v4.sin_addr,
-+ sa_p->ips_mask_s.u.v4.sin_addr,
-+ 0,
-+ buf_s,
-+ sizeof(buf_s));
-+
-+ subnettoa(sa_p->ips_flow_d.u.v4.sin_addr,
-+ sa_p->ips_mask_d.u.v4.sin_addr,
-+ 0,
-+ buf_d,
-+ sizeof(buf_d));
-+
-+ len += ipsec_snprintf(buffer+len, length-len, " policy=%s->%s",
-+ buf_s, buf_d);
-+ }
-+
-+ if(sa_p->ips_iv_bits) {
-+ int j;
-+ len += ipsec_snprintf(buffer+len, length-len, " iv_bits=%dbits iv=0x",
-+ sa_p->ips_iv_bits);
-+
-+ for(j = 0; j < sa_p->ips_iv_bits / 8; j++) {
-+ len += ipsec_snprintf(buffer+len, length-len, "%02x",
-+ (__u32)((__u8*)(sa_p->ips_iv))[j]);
-+ }
-+ }
-+
-+ if(sa_p->ips_encalg || sa_p->ips_authalg) {
-+ if(sa_p->ips_replaywin) {
-+ len += ipsec_snprintf(buffer+len, length-len, " ooowin=%d",
-+ sa_p->ips_replaywin);
-+ }
-+ if(sa_p->ips_errs.ips_replaywin_errs) {
-+ len += ipsec_snprintf(buffer+len, length-len, " ooo_errs=%d",
-+ sa_p->ips_errs.ips_replaywin_errs);
-+ }
-+ if(sa_p->ips_replaywin_lastseq) {
-+ len += ipsec_snprintf(buffer+len, length-len, " seq=%d",
-+ sa_p->ips_replaywin_lastseq);
-+ }
-+ if(sa_p->ips_replaywin_bitmap) {
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-+ len += ipsec_snprintf(buffer+len, length-len, " bit=0x%Lx",
-+ sa_p->ips_replaywin_bitmap);
-+#else
-+ len += ipsec_snprintf(buffer+len, length-len, " bit=0x%x%08x",
-+ (__u32)(sa_p->ips_replaywin_bitmap >> 32),
-+ (__u32)sa_p->ips_replaywin_bitmap);
-+#endif
-+ }
-+ if(sa_p->ips_replaywin_maxdiff) {
-+ len += ipsec_snprintf(buffer+len, length-len, " max_seq_diff=%d",
-+ sa_p->ips_replaywin_maxdiff);
-+ }
-+ }
-+ if(sa_p->ips_flags & ~EMT_INBOUND) {
-+ len += ipsec_snprintf(buffer+len, length-len, " flags=0x%x",
-+ sa_p->ips_flags & ~EMT_INBOUND);
-+ len += ipsec_snprintf(buffer+len, length-len, "<");
-+ /* flag printing goes here */
-+ len += ipsec_snprintf(buffer+len, length-len, ">");
-+ }
-+ if(sa_p->ips_auth_bits) {
-+ len += ipsec_snprintf(buffer+len, length-len, " alen=%d",
-+ sa_p->ips_auth_bits);
-+ }
-+ if(sa_p->ips_key_bits_a) {
-+ len += ipsec_snprintf(buffer+len, length-len, " aklen=%d",
-+ sa_p->ips_key_bits_a);
-+ }
-+ if(sa_p->ips_errs.ips_auth_errs) {
-+ len += ipsec_snprintf(buffer+len, length-len, " auth_errs=%d",
-+ sa_p->ips_errs.ips_auth_errs);
-+ }
-+ if(sa_p->ips_key_bits_e) {
-+ len += ipsec_snprintf(buffer+len, length-len, " eklen=%d",
-+ sa_p->ips_key_bits_e);
-+ }
-+ if(sa_p->ips_errs.ips_encsize_errs) {
-+ len += ipsec_snprintf(buffer+len, length-len, " encr_size_errs=%d",
-+ sa_p->ips_errs.ips_encsize_errs);
-+ }
-+ if(sa_p->ips_errs.ips_encpad_errs) {
-+ len += ipsec_snprintf(buffer+len, length-len, " encr_pad_errs=%d",
-+ sa_p->ips_errs.ips_encpad_errs);
-+ }
-+
-+ len += ipsec_snprintf(buffer+len, length-len, " life(c,s,h)=");
-+
-+ len += ipsec_lifetime_format(buffer + len,
-+ length - len,
-+ "alloc",
-+ ipsec_life_countbased,
-+ &sa_p->ips_life.ipl_allocations);
-+
-+ len += ipsec_lifetime_format(buffer + len,
-+ length - len,
-+ "bytes",
-+ ipsec_life_countbased,
-+ &sa_p->ips_life.ipl_bytes);
-+
-+ len += ipsec_lifetime_format(buffer + len,
-+ length - len,
-+ "addtime",
-+ ipsec_life_timebased,
-+ &sa_p->ips_life.ipl_addtime);
-+
-+ len += ipsec_lifetime_format(buffer + len,
-+ length - len,
-+ "usetime",
-+ ipsec_life_timebased,
-+ &sa_p->ips_life.ipl_usetime);
-+
-+ len += ipsec_lifetime_format(buffer + len,
-+ length - len,
-+ "packets",
-+ ipsec_life_countbased,
-+ &sa_p->ips_life.ipl_packets);
-+
-+ if(sa_p->ips_life.ipl_usetime.ipl_last) { /* XXX-MCR should be last? */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-+ len += ipsec_snprintf(buffer+len, length-len, " idle=%Ld",
-+ jiffies / HZ - sa_p->ips_life.ipl_usetime.ipl_last);
-+#else
-+ len += ipsec_snprintf(buffer+len, length-len, " idle=%lu",
-+ jiffies / HZ - (unsigned long)sa_p->ips_life.ipl_usetime.ipl_last);
-+#endif
-+ }
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ if(sa_p->ips_said.proto == IPPROTO_COMP &&
-+ (sa_p->ips_comp_ratio_dbytes ||
-+ sa_p->ips_comp_ratio_cbytes)) {
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
-+ len += ipsec_snprintf(buffer+len, length-len, " ratio=%Ld:%Ld",
-+ sa_p->ips_comp_ratio_dbytes,
-+ sa_p->ips_comp_ratio_cbytes);
-+#else
-+ len += ipsec_snprintf(buffer+len, length-len, " ratio=%lu:%lu",
-+ (unsigned long)sa_p->ips_comp_ratio_dbytes,
-+ (unsigned long)sa_p->ips_comp_ratio_cbytes);
-+#endif
-+ }
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if(sa_p->ips_natt_type != 0) {
-+ char *natttype_name;
-+
-+ switch(sa_p->ips_natt_type)
-+ {
-+ case ESPINUDP_WITH_NON_IKE:
-+ natttype_name="nonike";
-+ break;
-+ case ESPINUDP_WITH_NON_ESP:
-+ natttype_name="nonesp";
-+ break;
-+ default:
-+ natttype_name = "unknown";
-+ break;
-+ }
-+
-+ len += ipsec_snprintf(buffer + len, length-len, " natencap=%s",
-+ natttype_name);
-+
-+ len += ipsec_snprintf(buffer + len, length-len, " natsport=%d",
-+ sa_p->ips_natt_sport);
-+
-+ len += ipsec_snprintf(buffer + len,length-len, " natdport=%d",
-+ sa_p->ips_natt_dport);
-+ }
-+#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
-+
-+ len += ipsec_snprintf(buffer + len,length-len, " refcount=%d",
-+ atomic_read(&sa_p->ips_refcount));
-+
-+ len += ipsec_snprintf(buffer+len, length-len, " ref=%d",
-+ sa_p->ips_ref);
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(debug_xform) {
-+ len += ipsec_snprintf(buffer+len, length-len, " reftable=%lu refentry=%lu",
-+ (unsigned long)IPsecSAref2table(sa_p->ips_ref),
-+ (unsigned long)IPsecSAref2entry(sa_p->ips_ref));
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ len += ipsec_snprintf(buffer+len, length-len, "\n");
-+
-+ atomic_dec(&sa_p->ips_refcount);
-+
-+ if (len >= max_content) {
-+ /* we've done all that can fit -- stop loops */
-+ len = max_content; /* truncate crap */
-+ goto done_spi_i;
-+ } else {
-+ const off_t pos = begin + len; /* file position of end of what we've generated */
-+
-+ if (pos <= offset) {
-+ /* all is before first interesting character:
-+ * discard, but note where we are.
-+ */
-+ len = 0;
-+ begin = pos;
-+ }
-+ }
-+ }
-+ }
-+
-+done_spi_i:
-+ spin_unlock_bh(&tdb_lock);
-+
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ return len - (offset - begin);
-+}
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_spigrp_get_info(char *buffer,
-+ char **start,
-+ off_t offset,
-+ int length IPSEC_PROC_LAST_ARG)
-+{
-+ /* Limit of useful snprintf output */
-+ const int max_content = length > 0? length-1 : 0;
-+
-+ int len = 0;
-+ off_t begin = 0;
-+ int i;
-+ struct ipsec_sa *sa_p, *sa_p2;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_spigrp_get_info: "
-+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
-+ buffer,
-+ *start,
-+ (int)offset,
-+ length);
-+
-+ spin_lock_bh(&tdb_lock);
-+
-+ for (i = 0; i < SADB_HASHMOD; i++) {
-+ for (sa_p = ipsec_sadb_hash[i];
-+ sa_p != NULL;
-+ sa_p = sa_p->ips_hnext)
-+ {
-+ atomic_inc(&sa_p->ips_refcount);
-+ if(sa_p->ips_inext == NULL) {
-+ sa_p2 = sa_p;
-+ while(sa_p2 != NULL) {
-+ atomic_inc(&sa_p2->ips_refcount);
-+ sa_len = satot(&sa_p2->ips_said,
-+ 'x', sa, sizeof(sa));
-+
-+ len += ipsec_snprintf(buffer+len, length-len, "%s ",
-+ sa_len ? sa : " (error)");
-+ atomic_dec(&sa_p2->ips_refcount);
-+ sa_p2 = sa_p2->ips_onext;
-+ }
-+ len += ipsec_snprintf(buffer+len, length-len, "\n");
-+ }
-+
-+ atomic_dec(&sa_p->ips_refcount);
-+
-+ if (len >= max_content) {
-+ /* we've done all that can fit -- stop loops */
-+ len = max_content; /* truncate crap */
-+ goto done_spigrp_i;
-+ } else {
-+ const off_t pos = begin + len;
-+
-+ if (pos <= offset) {
-+ /* all is before first interesting character:
-+ * discard, but note where we are.
-+ */
-+ len = 0;
-+ begin = pos;
-+ }
-+ }
-+ }
-+ }
-+
-+done_spigrp_i:
-+ spin_unlock_bh(&tdb_lock);
-+
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ return len - (offset - begin);
-+}
-+
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_tncfg_get_info(char *buffer,
-+ char **start,
-+ off_t offset,
-+ int length IPSEC_PROC_LAST_ARG)
-+{
-+ /* limit of useful snprintf output */
-+ const int max_content = length > 0? length-1 : 0;
-+ int len = 0;
-+ off_t begin = 0;
-+ int i;
-+ char name[9];
-+ struct device *dev, *privdev;
-+ struct ipsecpriv *priv;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_tncfg_get_info: "
-+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
-+ buffer,
-+ *start,
-+ (int)offset,
-+ length);
-+
-+ for(i = 0; i < IPSEC_NUM_IF; i++) {
-+ ipsec_snprintf(name, (ssize_t) sizeof(name), IPSEC_DEV_FORMAT, i);
-+ dev = __ipsec_dev_get(name);
-+ if(dev) {
-+ priv = (struct ipsecpriv *)(dev->priv);
-+ len += ipsec_snprintf(buffer+len, length-len, "%s",
-+ dev->name);
-+ if(priv) {
-+ privdev = (struct device *)(priv->dev);
-+ len += ipsec_snprintf(buffer+len, length-len, " -> %s",
-+ privdev ? privdev->name : "NULL");
-+ len += ipsec_snprintf(buffer+len, length-len, " mtu=%d(%d) -> %d",
-+ dev->mtu,
-+ priv->mtu,
-+ privdev ? privdev->mtu : 0);
-+ } else {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_tncfg_get_info: device '%s' has no private data space!\n",
-+ dev->name);
-+ }
-+ len += ipsec_snprintf(buffer+len, length-len, "\n");
-+
-+ if (len >= max_content) {
-+ /* we've done all that can fit -- stop loop */
-+ len = max_content; /* truncate crap */
-+ break;
-+ } else {
-+ const off_t pos = begin + len;
-+ if (pos <= offset) {
-+ len = 0;
-+ begin = pos;
-+ }
-+ }
-+ }
-+ }
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ len -= (offset - begin); /* Start slop */
-+ if (len > length)
-+ len = length;
-+ return len;
-+}
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_version_get_info(char *buffer,
-+ char **start,
-+ off_t offset,
-+ int length IPSEC_PROC_LAST_ARG)
-+{
-+ int len = 0;
-+ off_t begin = 0;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_version_get_info: "
-+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
-+ buffer,
-+ *start,
-+ (int)offset,
-+ length);
-+
-+ len += ipsec_snprintf(buffer + len,length-len, "Openswan version: %s\n",
-+ ipsec_version_code());
-+#if 0
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_version_get_info: "
-+ "ipsec_init version: %s\n",
-+ ipsec_init_c_version);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_version_get_info: "
-+ "ipsec_tunnel version: %s\n",
-+ ipsec_tunnel_c_version);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_version_get_info: "
-+ "ipsec_netlink version: %s\n",
-+ ipsec_netlink_c_version);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_version_get_info: "
-+ "radij_c_version: %s\n",
-+ radij_c_version);
-+#endif
-+
-+
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ len -= (offset - begin); /* Start slop */
-+ if (len > length)
-+ len = length;
-+ return len;
-+}
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_birth_info(char *page,
-+ char **start,
-+ off_t offset,
-+ int count,
-+ int *eof,
-+ void *data)
-+{
-+ struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
-+ int len;
-+
-+ if(offset >= ibr->packet_template_len) {
-+ if(eof) {
-+ *eof=1;
-+ }
-+ return 0;
-+ }
-+
-+ len = ibr->packet_template_len;
-+ len -= offset;
-+ if (len > count)
-+ len = count;
-+
-+ memcpy(page + offset, ibr->packet_template+offset, len);
-+
-+ return len;
-+}
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_birth_set(struct file *file, const char *buffer,
-+ unsigned long count, void *data)
-+{
-+ struct ipsec_birth_reply *ibr = (struct ipsec_birth_reply *)data;
-+ int len;
-+
-+ MOD_INC_USE_COUNT;
-+ if(count > IPSEC_BIRTH_TEMPLATE_MAXLEN) {
-+ len = IPSEC_BIRTH_TEMPLATE_MAXLEN;
-+ } else {
-+ len = count;
-+ }
-+
-+ if(copy_from_user(ibr->packet_template, buffer, len)) {
-+ MOD_DEC_USE_COUNT;
-+ return -EFAULT;
-+ }
-+ ibr->packet_template_len = len;
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ return len;
-+}
-+
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_klipsdebug_get_info(char *buffer,
-+ char **start,
-+ off_t offset,
-+ int length IPSEC_PROC_LAST_ARG)
-+{
-+ int len = 0;
-+ off_t begin = 0;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS,
-+ "klips_debug:ipsec_klipsdebug_get_info: "
-+ "buffer=0p%p, *start=0p%p, offset=%d, length=%d\n",
-+ buffer,
-+ *start,
-+ (int)offset,
-+ length);
-+
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_tunnel=%08x.\n", debug_tunnel);
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_xform=%08x.\n", debug_xform);
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_eroute=%08x.\n", debug_eroute);
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_spi=%08x.\n", debug_spi);
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_radij=%08x.\n", debug_radij);
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_esp=%08x.\n", debug_esp);
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_ah=%08x.\n", debug_ah);
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_rcv=%08x.\n", debug_rcv);
-+ len += ipsec_snprintf(buffer+len, length-len, "debug_pfkey=%08x.\n", debug_pfkey);
-+
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ len -= (offset - begin); /* Start slop */
-+ if (len > length)
-+ len = length;
-+ return len;
-+}
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+IPSEC_PROCFS_DEBUG_NO_STATIC
-+int
-+ipsec_stats_get_int_info(char *buffer,
-+ char **start,
-+ off_t offset,
-+ int length,
-+ int *eof,
-+ void *data)
-+{
-+
-+ const int max_content = length > 0? length-1 : 0;
-+ int len = 0;
-+ int *thing;
-+
-+ thing = (int *)data;
-+
-+ len = ipsec_snprintf(buffer+len, length-len, "%08x\n", *thing);
-+
-+ if (len >= max_content)
-+ len = max_content; /* truncate crap */
-+
-+ *start = buffer + offset; /* Start of wanted data */
-+ return len > offset? len - offset : 0;
-+
-+}
-+
-+#ifndef PROC_FS_2325
-+struct proc_dir_entry ipsec_eroute =
-+{
-+ 0,
-+ 12, "ipsec_eroute",
-+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
-+ &proc_net_inode_operations,
-+ ipsec_eroute_get_info,
-+ NULL, NULL, NULL, NULL, NULL
-+};
-+
-+struct proc_dir_entry ipsec_spi =
-+{
-+ 0,
-+ 9, "ipsec_spi",
-+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
-+ &proc_net_inode_operations,
-+ ipsec_spi_get_info,
-+ NULL, NULL, NULL, NULL, NULL
-+};
-+
-+struct proc_dir_entry ipsec_spigrp =
-+{
-+ 0,
-+ 12, "ipsec_spigrp",
-+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
-+ &proc_net_inode_operations,
-+ ipsec_spigrp_get_info,
-+ NULL, NULL, NULL, NULL, NULL
-+};
-+
-+struct proc_dir_entry ipsec_tncfg =
-+{
-+ 0,
-+ 11, "ipsec_tncfg",
-+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
-+ &proc_net_inode_operations,
-+ ipsec_tncfg_get_info,
-+ NULL, NULL, NULL, NULL, NULL
-+};
-+
-+struct proc_dir_entry ipsec_version =
-+{
-+ 0,
-+ 13, "ipsec_version",
-+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
-+ &proc_net_inode_operations,
-+ ipsec_version_get_info,
-+ NULL, NULL, NULL, NULL, NULL
-+};
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+struct proc_dir_entry ipsec_klipsdebug =
-+{
-+ 0,
-+ 16, "ipsec_klipsdebug",
-+ S_IFREG | S_IRUGO, 1, 0, 0, 0,
-+ &proc_net_inode_operations,
-+ ipsec_klipsdebug_get_info,
-+ NULL, NULL, NULL, NULL, NULL
-+};
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#endif /* !PROC_FS_2325 */
-+#endif /* CONFIG_PROC_FS */
-+
-+#if defined(PROC_FS_2325)
-+struct ipsec_proc_list {
-+ char *name;
-+ struct proc_dir_entry **parent;
-+ struct proc_dir_entry **dir;
-+ read_proc_t *readthing;
-+ write_proc_t *writething;
-+ void *data;
-+};
-+static struct ipsec_proc_list proc_items[]={
-+#ifdef CONFIG_IPSEC_DEBUG
-+ {"klipsdebug", &proc_net_ipsec_dir, NULL, ipsec_klipsdebug_get_info, NULL, NULL},
-+#endif
-+ {"eroute", &proc_net_ipsec_dir, &proc_eroute_dir, NULL, NULL, NULL},
-+ {"all", &proc_eroute_dir, NULL, ipsec_eroute_get_info, NULL, NULL},
-+ {"spi", &proc_net_ipsec_dir, &proc_spi_dir, NULL, NULL, NULL},
-+ {"all", &proc_spi_dir, NULL, ipsec_spi_get_info, NULL, NULL},
-+ {"spigrp", &proc_net_ipsec_dir, &proc_spigrp_dir, NULL, NULL, NULL},
-+ {"all", &proc_spigrp_dir, NULL, ipsec_spigrp_get_info, NULL, NULL},
-+ {"birth", &proc_net_ipsec_dir, &proc_birth_dir, NULL, NULL, NULL},
-+ {"ipv4", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv4_birth_packet},
-+ {"ipv6", &proc_birth_dir, NULL, ipsec_birth_info, ipsec_birth_set, (void *)&ipsec_ipv6_birth_packet},
-+ {"tncfg", &proc_net_ipsec_dir, NULL, ipsec_tncfg_get_info, NULL, NULL},
-+ {"xforms", &proc_net_ipsec_dir, NULL, ipsec_xform_get_info, NULL, NULL},
-+ {"stats", &proc_net_ipsec_dir, &proc_stats_dir, NULL, NULL, NULL},
-+ {"trap_count", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_count},
-+ {"trap_sendcount", &proc_stats_dir, NULL, ipsec_stats_get_int_info, NULL, &ipsec_xmit_trap_sendcount},
-+ {"version", &proc_net_ipsec_dir, NULL, ipsec_version_get_info, NULL, NULL},
-+ {NULL, NULL, NULL, NULL, NULL, NULL}
-+};
-+#endif
-+
-+int
-+ipsec_proc_init()
-+{
-+ int error = 0;
-+#ifdef IPSEC_PROC_SUBDIRS
-+ struct proc_dir_entry *item;
-+#endif
-+
-+ /*
-+ * just complain because pluto won't run without /proc!
-+ */
-+#ifndef CONFIG_PROC_FS
-+#error You must have PROC_FS built in to use KLIPS
-+#endif
-+
-+ /* for 2.0 kernels */
-+#if !defined(PROC_FS_2325) && !defined(PROC_FS_21)
-+ error |= proc_register_dynamic(&proc_net, &ipsec_eroute);
-+ error |= proc_register_dynamic(&proc_net, &ipsec_spi);
-+ error |= proc_register_dynamic(&proc_net, &ipsec_spigrp);
-+ error |= proc_register_dynamic(&proc_net, &ipsec_tncfg);
-+ error |= proc_register_dynamic(&proc_net, &ipsec_version);
-+#ifdef CONFIG_IPSEC_DEBUG
-+ error |= proc_register_dynamic(&proc_net, &ipsec_klipsdebug);
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#endif
-+
-+ /* for 2.2 kernels */
-+#if !defined(PROC_FS_2325) && defined(PROC_FS_21)
-+ error |= proc_register(proc_net, &ipsec_eroute);
-+ error |= proc_register(proc_net, &ipsec_spi);
-+ error |= proc_register(proc_net, &ipsec_spigrp);
-+ error |= proc_register(proc_net, &ipsec_tncfg);
-+ error |= proc_register(proc_net, &ipsec_version);
-+#ifdef CONFIG_IPSEC_DEBUG
-+ error |= proc_register(proc_net, &ipsec_klipsdebug);
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#endif
-+
-+ /* for 2.4 kernels */
-+#if defined(PROC_FS_2325)
-+ /* create /proc/net/ipsec */
-+
-+ /* zero these out before we initialize /proc/net/ipsec/birth/stuff */
-+ memset(&ipsec_ipv4_birth_packet, 0, sizeof(struct ipsec_birth_reply));
-+ memset(&ipsec_ipv6_birth_packet, 0, sizeof(struct ipsec_birth_reply));
-+
-+ proc_net_ipsec_dir = proc_mkdir("ipsec", proc_net);
-+ if(proc_net_ipsec_dir == NULL) {
-+ /* no point in continuing */
-+ return 1;
-+ }
-+
-+ {
-+ struct ipsec_proc_list *it;
-+
-+ it=proc_items;
-+ while(it->name!=NULL) {
-+ if(it->dir) {
-+ /* make a dir instead */
-+ item = proc_mkdir(it->name, *it->parent);
-+ *it->dir = item;
-+ } else {
-+ item = create_proc_entry(it->name, 0400, *it->parent);
-+ }
-+ if(item) {
-+ item->read_proc = it->readthing;
-+ item->write_proc = it->writething;
-+ item->data = it->data;
-+#ifdef MODULE
-+ item->owner = THIS_MODULE;
-+#endif
-+ } else {
-+ error |= 1;
-+ }
-+ it++;
-+ }
-+ }
-+
-+ /* now create some symlinks to provide compatibility */
-+ proc_symlink("ipsec_eroute", proc_net, "ipsec/eroute/all");
-+ proc_symlink("ipsec_spi", proc_net, "ipsec/spi/all");
-+ proc_symlink("ipsec_spigrp", proc_net, "ipsec/spigrp/all");
-+ proc_symlink("ipsec_tncfg", proc_net, "ipsec/tncfg");
-+ proc_symlink("ipsec_version",proc_net, "ipsec/version");
-+ proc_symlink("ipsec_klipsdebug",proc_net,"ipsec/klipsdebug");
-+
-+#endif /* !PROC_FS_2325 */
-+
-+ return error;
-+}
-+
-+void
-+ipsec_proc_cleanup()
-+{
-+
-+ /* for 2.0 and 2.2 kernels */
-+#if !defined(PROC_FS_2325)
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (proc_net_unregister(ipsec_klipsdebug.low_ino) != 0)
-+ printk("klips_debug:ipsec_cleanup: "
-+ "cannot unregister /proc/net/ipsec_klipsdebug\n");
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ if (proc_net_unregister(ipsec_version.low_ino) != 0)
-+ printk("klips_debug:ipsec_cleanup: "
-+ "cannot unregister /proc/net/ipsec_version\n");
-+ if (proc_net_unregister(ipsec_eroute.low_ino) != 0)
-+ printk("klips_debug:ipsec_cleanup: "
-+ "cannot unregister /proc/net/ipsec_eroute\n");
-+ if (proc_net_unregister(ipsec_spi.low_ino) != 0)
-+ printk("klips_debug:ipsec_cleanup: "
-+ "cannot unregister /proc/net/ipsec_spi\n");
-+ if (proc_net_unregister(ipsec_spigrp.low_ino) != 0)
-+ printk("klips_debug:ipsec_cleanup: "
-+ "cannot unregister /proc/net/ipsec_spigrp\n");
-+ if (proc_net_unregister(ipsec_tncfg.low_ino) != 0)
-+ printk("klips_debug:ipsec_cleanup: "
-+ "cannot unregister /proc/net/ipsec_tncfg\n");
-+#endif
-+
-+ /* for 2.4 kernels */
-+#if defined(PROC_FS_2325)
-+ {
-+ struct ipsec_proc_list *it;
-+
-+ /* find end of list */
-+ it=proc_items;
-+ while(it->name!=NULL) {
-+ it++;
-+ }
-+ it--;
-+
-+ do {
-+ remove_proc_entry(it->name, *it->parent);
-+ it--;
-+ } while(it > proc_items);
-+ }
-+
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ remove_proc_entry("ipsec_klipsdebug", proc_net);
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ remove_proc_entry("ipsec_eroute", proc_net);
-+ remove_proc_entry("ipsec_spi", proc_net);
-+ remove_proc_entry("ipsec_spigrp", proc_net);
-+ remove_proc_entry("ipsec_tncfg", proc_net);
-+ remove_proc_entry("ipsec_version", proc_net);
-+ remove_proc_entry("ipsec", proc_net);
-+#endif /* 2.4 kernel */
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.30 2004/04/25 21:23:11 ken
-+ * Pull in dhr's changes from FreeS/WAN 2.06
-+ *
-+ * Revision 1.29 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.28 2004/03/28 20:29:58 paul
-+ * <hugh_> ssize_t, not ssized_t
-+ *
-+ * Revision 1.27 2004/03/28 20:27:20 paul
-+ * Included tested and confirmed fixes mcr made and dhr verified for
-+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
-+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
-+ * dhr. (thanks dhr!)
-+ *
-+ * Revision 1.26 2004/02/09 22:07:06 mcr
-+ * added information about nat-traversal setting to spi-output.
-+ *
-+ * Revision 1.25.4.1 2004/04/05 04:30:46 mcr
-+ * patches for alg-branch to compile/work with 2.x openswan
-+ *
-+ * Revision 1.25 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.24.4.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.24 2003/06/20 01:42:21 mcr
-+ * added counters to measure how many ACQUIREs we send to pluto,
-+ * and how many are successfully sent.
-+ *
-+ * Revision 1.23 2003/04/03 17:38:09 rgb
-+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
-+ *
-+ * Revision 1.22 2002/09/20 15:40:57 rgb
-+ * Renamed saref macros for consistency and brevity.
-+ *
-+ * Revision 1.21 2002/09/20 05:01:35 rgb
-+ * Print ref and reftable, refentry seperately.
-+ *
-+ * Revision 1.20 2002/09/19 02:35:39 mcr
-+ * do not define structures needed by /proc/net/ipsec/ if we
-+ * aren't going create that directory.
-+ *
-+ * Revision 1.19 2002/09/10 01:43:25 mcr
-+ * fixed problem in /-* comment.
-+ *
-+ * Revision 1.18 2002/09/03 16:22:11 mcr
-+ * fixed initialization of birth/stuff values - some simple
-+ * screw ups in the code.
-+ * removed debugging that was left in by mistake.
-+ *
-+ * Revision 1.17 2002/09/02 17:54:53 mcr
-+ * changed how the table driven /proc entries are created so that
-+ * making subdirs is now explicit rather than implicit.
-+ *
-+ * Revision 1.16 2002/08/30 01:23:37 mcr
-+ * reorganized /proc creating code to clear up ifdefs,
-+ * make the 2.4 code table driven, and put things into
-+ * /proc/net/ipsec subdir. Symlinks are left for compatibility.
-+ *
-+ * Revision 1.15 2002/08/13 19:01:25 mcr
-+ * patches from kenb to permit compilation of FreeSWAN on ia64.
-+ * des library patched to use proper DES_LONG type for ia64.
-+ *
-+ * Revision 1.14 2002/07/26 08:48:31 rgb
-+ * Added SA ref table code.
-+ *
-+ * Revision 1.13 2002/07/24 18:44:54 rgb
-+ * Type fiddling to tame ia64 compiler.
-+ *
-+ * Revision 1.12 2002/05/27 18:56:07 rgb
-+ * Convert to dynamic ipsec device allocation.
-+ *
-+ * Revision 1.11 2002/05/23 07:14:50 rgb
-+ * Added refcount code.
-+ * Cleaned up %p variants to 0p%p for test suite cleanup.
-+ * Convert "usecount" to "refcount" to remove ambiguity.
-+ *
-+ * Revision 1.10 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.9 2002/04/24 07:36:28 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_proc.c,v
-+ *
-+ * Revision 1.8 2002/01/29 17:17:55 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.7 2002/01/29 04:00:52 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.6 2002/01/29 02:13:17 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.5 2002/01/12 02:54:30 mcr
-+ * beginnings of /proc/net/ipsec dir.
-+ *
-+ * Revision 1.4 2001/12/11 02:21:05 rgb
-+ * Don't include module version here, fixing 2.2 compile bug.
-+ *
-+ * Revision 1.3 2001/12/05 07:19:44 rgb
-+ * Fixed extraneous #include "version.c" bug causing modular KLIPS failure.
-+ *
-+ * Revision 1.2 2001/11/26 09:16:14 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.74 2001/11/22 05:44:11 henry
-+ * new version stuff
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:19:40 mcr
-+ * /proc manipulation code moved to new ipsec_proc.c
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_radij.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,869 @@
-+/*
-+ * Interface between the IPSEC code and the radix (radij) tree code
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, struct net_device_stats and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* 23_SPINLOCK */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* 23_SPINLOCK */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+#endif
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "openswan/ipsec_eroute.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_tunnel.h" /* struct ipsecpriv */
-+#include "openswan/ipsec_xform.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_radij = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+struct radij_node_head *rnh = NULL;
-+#ifdef SPINLOCK
-+spinlock_t eroute_lock = SPIN_LOCK_UNLOCKED;
-+#else /* SPINLOCK */
-+spinlock_t eroute_lock;
-+#endif /* SPINLOCK */
-+
-+int
-+ipsec_radijinit(void)
-+{
-+ maj_keylen = sizeof (struct sockaddr_encap);
-+
-+ rj_init();
-+
-+ if (rj_inithead((void **)&rnh, /*16*/offsetof(struct sockaddr_encap, sen_type) * sizeof(__u8)) == 0) /* 16 is bit offset of sen_type */
-+ return -1;
-+ return 0;
-+}
-+
-+int
-+ipsec_radijcleanup(void)
-+{
-+ int error;
-+
-+ spin_lock_bh(&eroute_lock);
-+
-+ error = radijcleanup();
-+
-+ spin_unlock_bh(&eroute_lock);
-+
-+ return error;
-+}
-+
-+int
-+ipsec_cleareroutes(void)
-+{
-+ int error;
-+
-+ spin_lock_bh(&eroute_lock);
-+
-+ error = radijcleartree();
-+
-+ spin_unlock_bh(&eroute_lock);
-+
-+ return error;
-+}
-+
-+int
-+ipsec_breakroute(struct sockaddr_encap *eaddr,
-+ struct sockaddr_encap *emask,
-+ struct sk_buff **first,
-+ struct sk_buff **last)
-+{
-+ struct eroute *ro;
-+ struct radij_node *rn;
-+ int error;
-+#ifdef CONFIG_IPSEC_DEBUG
-+
-+ if (debug_eroute) {
-+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
-+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_breakroute: "
-+ "attempting to delete eroute for %s:%d->%s:%d %d\n",
-+ buf1, ntohs(eaddr->sen_sport),
-+ buf2, ntohs(eaddr->sen_dport), eaddr->sen_proto);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ spin_lock_bh(&eroute_lock);
-+
-+ if ((error = rj_delete(eaddr, emask, rnh, &rn)) != 0) {
-+ spin_unlock_bh(&eroute_lock);
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_breakroute: "
-+ "node not found, eroute delete failed.\n");
-+ return error;
-+ }
-+
-+ spin_unlock_bh(&eroute_lock);
-+
-+ ro = (struct eroute *)rn;
-+
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_breakroute: "
-+ "deleted eroute=0p%p, ident=0p%p->0p%p, first=0p%p, last=0p%p\n",
-+ ro,
-+ ro->er_ident_s.data,
-+ ro->er_ident_d.data,
-+ ro->er_first,
-+ ro->er_last);
-+
-+ if (ro->er_ident_s.data != NULL) {
-+ kfree(ro->er_ident_s.data);
-+ }
-+ if (ro->er_ident_d.data != NULL) {
-+ kfree(ro->er_ident_d.data);
-+ }
-+ if (ro->er_first != NULL) {
-+#if 0
-+ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_first->dev->priv))->mystats);
-+ stats->tx_dropped--;
-+#endif
-+ *first = ro->er_first;
-+ }
-+ if (ro->er_last != NULL) {
-+#if 0
-+ struct net_device_stats *stats = (struct net_device_stats *) &(((struct ipsecpriv *)(ro->er_last->dev->priv))->mystats);
-+ stats->tx_dropped--;
-+#endif
-+ *last = ro->er_last;
-+ }
-+
-+ if (rn->rj_flags & (RJF_ACTIVE | RJF_ROOT))
-+ panic ("ipsec_breakroute RMT_DELEROUTE root or active node\n");
-+ memset((caddr_t)rn, 0, sizeof (struct eroute));
-+ kfree(rn);
-+
-+ return 0;
-+}
-+
-+int
-+ipsec_makeroute(struct sockaddr_encap *eaddr,
-+ struct sockaddr_encap *emask,
-+ ip_said said,
-+ uint32_t pid,
-+ struct sk_buff *skb,
-+ struct ident *ident_s,
-+ struct ident *ident_d)
-+{
-+ struct eroute *retrt;
-+ int error;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+
-+ if (debug_eroute) {
-+
-+ {
-+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
-+
-+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
-+ sa_len = satot(&said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_makeroute: "
-+ "attempting to allocate %lu bytes to insert eroute for %s->%s, SA: %s, PID:%d, skb=0p%p, ident:%s->%s\n",
-+ (unsigned long) sizeof(struct eroute),
-+ buf1,
-+ buf2,
-+ sa_len ? sa : " (error)",
-+ pid,
-+ skb,
-+ (ident_s ? (ident_s->data ? ident_s->data : "NULL") : "NULL"),
-+ (ident_d ? (ident_d->data ? ident_d->data : "NULL") : "NULL"));
-+ }
-+ {
-+ char buf1[sizeof(struct sockaddr_encap)*2 + 1],
-+ buf2[sizeof(struct sockaddr_encap)*2 + 1];
-+ int i;
-+ unsigned char *b1 = buf1,
-+ *b2 = buf2,
-+ *ea = (unsigned char *)eaddr,
-+ *em = (unsigned char *)emask;
-+
-+
-+ for (i=0; i<sizeof(struct sockaddr_encap); i++) {
-+ sprintf(b1, "%02x", ea[i]);
-+ sprintf(b2, "%02x", em[i]);
-+ b1+=2;
-+ b2+=2;
-+ }
-+ KLIPS_PRINT(debug_eroute, "klips_debug:ipsec_makeroute: %s / %s \n", buf1, buf2);
-+ }
-+
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ retrt = (struct eroute *)kmalloc(sizeof (struct eroute), GFP_ATOMIC);
-+ if (retrt == NULL) {
-+ printk("klips_error:ipsec_makeroute: "
-+ "not able to allocate kernel memory");
-+ return -ENOMEM;
-+ }
-+ memset((caddr_t)retrt, 0, sizeof (struct eroute));
-+
-+ retrt->er_eaddr = *eaddr;
-+ retrt->er_emask = *emask;
-+ retrt->er_said = said;
-+ retrt->er_pid = pid;
-+ retrt->er_count = 0;
-+ retrt->er_lasttime = jiffies/HZ;
-+ rd_key((&(retrt->er_rjt))) = &(retrt->er_eaddr);
-+
-+ if (ident_s && ident_s->type != SADB_IDENTTYPE_RESERVED) {
-+ int data_len = ident_s->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
-+
-+ retrt->er_ident_s.type = ident_s->type;
-+ retrt->er_ident_s.id = ident_s->id;
-+ retrt->er_ident_s.len = ident_s->len;
-+ if(data_len) {
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_makeroute: "
-+ "attempting to allocate %u bytes for ident_s.\n",
-+ data_len);
-+ if(!(retrt->er_ident_s.data = kmalloc(data_len, GFP_KERNEL))) {
-+ kfree(retrt);
-+ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
-+ return ENOMEM;
-+ }
-+ memcpy(retrt->er_ident_s.data, ident_s->data, data_len);
-+ } else {
-+ retrt->er_ident_s.data = NULL;
-+ }
-+ }
-+
-+ if (ident_d && ident_d->type != SADB_IDENTTYPE_RESERVED) {
-+ int data_len = ident_d->len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
-+
-+ retrt->er_ident_d.type = ident_d->type;
-+ retrt->er_ident_d.id = ident_d->id;
-+ retrt->er_ident_d.len = ident_d->len;
-+ if(data_len) {
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_makeroute: "
-+ "attempting to allocate %u bytes for ident_d.\n",
-+ data_len);
-+ if(!(retrt->er_ident_d.data = kmalloc(data_len, GFP_KERNEL))) {
-+ if (retrt->er_ident_s.data)
-+ kfree(retrt->er_ident_s.data);
-+ kfree(retrt);
-+ printk("klips_error:ipsec_makeroute: not able to allocate kernel memory (%d)\n", data_len);
-+ return ENOMEM;
-+ }
-+ memcpy(retrt->er_ident_d.data, ident_d->data, data_len);
-+ } else {
-+ retrt->er_ident_d.data = NULL;
-+ }
-+ }
-+ retrt->er_first = skb;
-+ retrt->er_last = NULL;
-+
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_makeroute: "
-+ "calling rj_addroute now\n");
-+
-+ spin_lock_bh(&eroute_lock);
-+
-+ error = rj_addroute(&(retrt->er_eaddr), &(retrt->er_emask),
-+ rnh, retrt->er_rjt.rd_nodes);
-+
-+ spin_unlock_bh(&eroute_lock);
-+
-+ if(error) {
-+ sa_len = satot(&said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_makeroute: "
-+ "rj_addroute not able to insert eroute for SA:%s (error:%d)\n",
-+ sa_len ? sa : " (error)", error);
-+ if (retrt->er_ident_s.data)
-+ kfree(retrt->er_ident_s.data);
-+ if (retrt->er_ident_d.data)
-+ kfree(retrt->er_ident_d.data);
-+
-+ kfree(retrt);
-+
-+ return error;
-+ }
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (debug_eroute) {
-+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
-+/*
-+ subnettoa(eaddr->sen_ip_src, emask->sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(eaddr->sen_ip_dst, emask->sen_ip_dst, 0, buf2, sizeof(buf2));
-+*/
-+ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_src, rd_mask((&(retrt->er_rjt)))->sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(rd_key((&(retrt->er_rjt)))->sen_ip_dst, rd_mask((&(retrt->er_rjt)))->sen_ip_dst, 0, buf2, sizeof(buf2));
-+ sa_len = satot(&retrt->er_said, 0, sa, sizeof(sa));
-+
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_makeroute: "
-+ "pid=%05d "
-+ "count=%10d "
-+ "lasttime=%6d "
-+ "%-18s -> %-18s => %s\n",
-+ retrt->er_pid,
-+ retrt->er_count,
-+ (int)(jiffies/HZ - retrt->er_lasttime),
-+ buf1,
-+ buf2,
-+ sa_len ? sa : " (error)");
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_makeroute: "
-+ "succeeded.\n");
-+ return 0;
-+}
-+
-+struct eroute *
-+ipsec_findroute(struct sockaddr_encap *eaddr)
-+{
-+ struct radij_node *rn;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ char buf1[ADDRTOA_BUF], buf2[ADDRTOA_BUF];
-+
-+ if (debug_radij & DB_RJ_FINDROUTE) {
-+ addrtoa(eaddr->sen_ip_src, 0, buf1, sizeof(buf1));
-+ addrtoa(eaddr->sen_ip_dst, 0, buf2, sizeof(buf2));
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:ipsec_findroute: "
-+ "%s:%d->%s:%d %d\n",
-+ buf1, ntohs(eaddr->sen_sport),
-+ buf2, ntohs(eaddr->sen_dport),
-+ eaddr->sen_proto);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ rn = rj_match((caddr_t)eaddr, rnh);
-+ if(rn) {
-+ KLIPS_PRINT(debug_eroute && sysctl_ipsec_debug_verbose,
-+ "klips_debug:ipsec_findroute: "
-+ "found, points to proto=%d, spi=%x, dst=%x.\n",
-+ ((struct eroute*)rn)->er_said.proto,
-+ ntohl(((struct eroute*)rn)->er_said.spi),
-+ ntohl(((struct eroute*)rn)->er_said.dst.u.v4.sin_addr.s_addr));
-+ }
-+ return (struct eroute *)rn;
-+}
-+
-+#ifdef CONFIG_PROC_FS
-+/** ipsec_rj_walker_procprint: print one line of eroute table output.
-+ *
-+ * Theoretical BUG: if w->length is less than the length
-+ * of some line we should produce, that line will never
-+ * be finished. In effect, the "file" will stop part way
-+ * through that line.
-+ */
-+int
-+ipsec_rj_walker_procprint(struct radij_node *rn, void *w0)
-+{
-+ struct eroute *ro = (struct eroute *)rn;
-+ struct rjtentry *rd = (struct rjtentry *)rn;
-+ struct wsbuf *w = (struct wsbuf *)w0;
-+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
-+ char buf3[16];
-+ char sa[SATOT_BUF];
-+ size_t sa_len, buf_len;
-+ struct sockaddr_encap *key, *mask;
-+
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:ipsec_rj_walker_procprint: "
-+ "rn=0p%p, w0=0p%p\n",
-+ rn,
-+ w0);
-+ if (rn->rj_b >= 0) {
-+ return 0;
-+ }
-+
-+ key = rd_key(rd);
-+ mask = rd_mask(rd);
-+
-+ if (key == NULL || mask == NULL) {
-+ return 0;
-+ }
-+
-+ buf_len = subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
-+ if(key->sen_sport != 0) {
-+ sprintf(buf1+buf_len-1, ":%d", ntohs(key->sen_sport));
-+ }
-+
-+ buf_len = subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
-+ if(key->sen_dport != 0) {
-+ sprintf(buf2+buf_len-1, ":%d", ntohs(key->sen_dport));
-+ }
-+
-+ buf3[0]='\0';
-+ if(key->sen_proto != 0) {
-+ sprintf(buf3, ":%d", key->sen_proto);
-+ }
-+
-+ sa_len = satot(&ro->er_said, 'x', sa, sizeof(sa));
-+ w->len += ipsec_snprintf(w->buffer + w->len,
-+ w->length - w->len,
-+ "%-10d "
-+ "%-18s -> %-18s => %s%s\n",
-+ ro->er_count,
-+ buf1,
-+ buf2,
-+ sa_len ? sa : " (error)",
-+ buf3);
-+
-+ {
-+ /* snprintf can only fill the last character with NUL
-+ * so the maximum useful character is w->length-1.
-+ * However, if w->length == 0, we cannot go back.
-+ * (w->length surely cannot be negative.)
-+ */
-+ int max_content = w->length > 0? w->length-1 : 0;
-+
-+ if (w->len >= max_content) {
-+ /* we've done all that can fit -- stop treewalking */
-+ w->len = max_content; /* truncate crap */
-+ return -ENOBUFS;
-+ } else {
-+ const off_t pos = w->begin + w->len; /* file position of end of what we've generated */
-+
-+ if (pos <= w->offset) {
-+ /* all is before first interesting character:
-+ * discard, but note where we are.
-+ */
-+ w->len = 0;
-+ w->begin = pos;
-+ }
-+ return 0;
-+ }
-+ }
-+}
-+#endif /* CONFIG_PROC_FS */
-+
-+int
-+ipsec_rj_walker_delete(struct radij_node *rn, void *w0)
-+{
-+ struct eroute *ro;
-+ struct rjtentry *rd = (struct rjtentry *)rn;
-+ struct radij_node *rn2;
-+ int error;
-+ struct sockaddr_encap *key, *mask;
-+
-+ key = rd_key(rd);
-+ mask = rd_mask(rd);
-+
-+ if(!key || !mask) {
-+ return -ENODATA;
-+ }
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(debug_radij) {
-+ char buf1[SUBNETTOA_BUF], buf2[SUBNETTOA_BUF];
-+ subnettoa(key->sen_ip_src, mask->sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(key->sen_ip_dst, mask->sen_ip_dst, 0, buf2, sizeof(buf2));
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:ipsec_rj_walker_delete: "
-+ "deleting: %s -> %s\n",
-+ buf1,
-+ buf2);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ if((error = rj_delete(key, mask, rnh, &rn2))) {
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:ipsec_rj_walker_delete: "
-+ "rj_delete failed with error=%d.\n", error);
-+ return error;
-+ }
-+
-+ if(rn2 != rn) {
-+ printk("klips_debug:ipsec_rj_walker_delete: "
-+ "tried to delete a different node?!? This should never happen!\n");
-+ }
-+
-+ ro = (struct eroute *)rn;
-+
-+ if (ro->er_ident_s.data)
-+ kfree(ro->er_ident_s.data);
-+ if (ro->er_ident_d.data)
-+ kfree(ro->er_ident_d.data);
-+
-+ memset((caddr_t)rn, 0, sizeof (struct eroute));
-+ kfree(rn);
-+
-+ return 0;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.70 2004/04/25 21:10:52 ken
-+ * Pull in dhr's changes from FreeS/WAN 2.06
-+ *
-+ * Revision 1.69 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.68 2004/03/28 20:27:20 paul
-+ * Included tested and confirmed fixes mcr made and dhr verified for
-+ * snprint statements. Changed one other snprintf to use ipsec_snprintf
-+ * so it wouldnt break compatibility with 2.0/2.2 kernels. Verified with
-+ * dhr. (thanks dhr!)
-+ *
-+ * Revision 1.67.4.1 2004/04/05 04:30:46 mcr
-+ * patches for alg-branch to compile/work with 2.x openswan
-+ *
-+ * Revision 1.67 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.66.24.2 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.66.24.1 2003/09/21 13:59:56 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.66 2002/10/12 23:11:53 dhr
-+ *
-+ * [KenB + DHR] more 64-bit cleanup
-+ *
-+ * Revision 1.65 2002/09/20 05:01:40 rgb
-+ * Added memory allocation debugging.
-+ *
-+ * Revision 1.64 2002/05/31 01:46:05 mcr
-+ * added && sysctl_ipsec_debug_verbose verbose to ipsec_findroute
-+ * as requested in PR#14.
-+ *
-+ * Revision 1.63 2002/05/23 07:14:11 rgb
-+ * Cleaned up %p variants to 0p%p for test suite cleanup.
-+ *
-+ * Revision 1.62 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.61 2002/04/24 07:36:29 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_radij.c,v
-+ *
-+ * Revision 1.60 2002/02/19 23:59:45 rgb
-+ * Removed redundant compiler directives.
-+ *
-+ * Revision 1.59 2002/02/06 04:13:47 mcr
-+ * missing #ifdef CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.58 2002/01/29 17:17:56 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.57 2002/01/29 04:00:52 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.56 2002/01/29 02:13:17 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.55 2001/11/26 09:23:48 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.53.2.1 2001/09/25 02:26:32 mcr
-+ * headers adjusted for new usage.
-+ *
-+ * Revision 1.54 2001/10/18 04:45:20 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/freeswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.53 2001/09/19 17:19:40 rgb
-+ * Debug output bugfix for NetCelo's PF_KEY ident patch.
-+ *
-+ * Revision 1.52 2001/09/19 16:33:37 rgb
-+ * Temporarily disable ident fields to /proc/net/ipsec_eroute.
-+ *
-+ * Revision 1.51 2001/09/15 16:24:04 rgb
-+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
-+ *
-+ * Revision 1.50 2001/09/14 16:58:36 rgb
-+ * Added support for storing the first and last packets through a HOLD.
-+ *
-+ * Revision 1.49 2001/09/08 21:13:32 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.48 2001/06/15 04:12:56 rgb
-+ * Fixed kernel memory allocation error return code polarity bug.
-+ *
-+ * Revision 1.47 2001/06/14 19:35:09 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.46 2001/06/08 08:47:18 rgb
-+ * Fixed for debug disabled.
-+ *
-+ * Revision 1.45 2001/05/27 06:12:11 rgb
-+ * Added structures for pid, packet count and last access time to eroute.
-+ * Added packet count to beginning of /proc/net/ipsec_eroute.
-+ *
-+ * Revision 1.44 2001/05/03 19:41:01 rgb
-+ * Initialise error return variable.
-+ * Use more appropriate return value for ipsec_rj_walker_delete().
-+ *
-+ * Revision 1.43 2001/02/27 22:24:54 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.42 2001/02/27 06:21:57 rgb
-+ * Added findroute success instrumentation.
-+ *
-+ * Revision 1.41 2000/11/06 04:32:08 rgb
-+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
-+ *
-+ * Revision 1.40 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.39 2000/08/30 05:25:20 rgb
-+ * Correct debug text in ipsec_breakroute() from incorrect
-+ * "ipsec_callback".
-+ *
-+ * Revision 1.38 2000/07/28 14:58:31 rgb
-+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
-+ *
-+ * Revision 1.37 2000/03/16 14:02:50 rgb
-+ * Fixed debug scope to enable compilation with debug off.
-+ *
-+ * Revision 1.36 2000/01/21 06:14:46 rgb
-+ * Added debugging text to ipsec_rj_walker_delete().
-+ * Set return code to negative for consistency.
-+ *
-+ * Revision 1.35 1999/11/23 23:05:24 rgb
-+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
-+ *
-+ * Revision 1.34 1999/11/18 04:13:56 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
-+ *
-+ * Revision 1.33 1999/11/17 15:53:39 rgb
-+ * Changed all occurrences of #include "../../../lib/freeswan.h"
-+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
-+ * klips/net/ipsec/Makefile.
-+ *
-+ * Revision 1.32 1999/10/26 13:58:33 rgb
-+ * Put spinlock flags variable declaration outside the debug compiler
-+ * directive to enable compilation with debug shut off.
-+ *
-+ * Revision 1.31 1999/10/15 22:13:29 rgb
-+ * Clean out cruft.
-+ * Align /proc/net/ipsec_eroute output for easier readability.
-+ * Fix double linefeed in radij debug output.
-+ * Fix double locking bug that locks up 2.0.36 but not 2.0.38.
-+ *
-+ * Revision 1.30 1999/10/08 18:37:33 rgb
-+ * Fix end-of-line spacing to sate whining PHMs.
-+ *
-+ * Revision 1.29 1999/10/03 18:52:45 rgb
-+ * Spinlock support for 2.0.xx.
-+ * Dumb return code spin_unlock fix.
-+ *
-+ * Revision 1.28 1999/10/01 16:22:24 rgb
-+ * Switch from assignment init. to functional init. of spinlocks.
-+ *
-+ * Revision 1.27 1999/10/01 15:44:53 rgb
-+ * Move spinlock header include to 2.1> scope.
-+ *
-+ * Revision 1.26 1999/10/01 00:01:23 rgb
-+ * Added eroute structure locking.
-+ *
-+ * Revision 1.25 1999/06/10 16:07:30 rgb
-+ * Silence delete eroute on no debug.
-+ *
-+ * Revision 1.24 1999/05/09 03:25:36 rgb
-+ * Fix bug introduced by 2.2 quick-and-dirty patch.
-+ *
-+ * Revision 1.23 1999/05/05 22:02:31 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.22 1999/04/29 15:17:23 rgb
-+ * Add return values to init and cleanup functions.
-+ * Add sanity checking for null pointer arguments.
-+ *
-+ * Revision 1.21 1999/04/11 00:28:58 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.20 1999/04/06 04:54:26 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.19 1999/02/17 16:50:35 rgb
-+ * Clean out unused cruft.
-+ * Consolidate for space and speed efficiency.
-+ * Convert DEBUG_IPSEC to KLIPS_PRINT
-+ *
-+ * Revision 1.18 1999/01/22 06:22:06 rgb
-+ * Cruft clean-out.
-+ * 64-bit clean-up.
-+ *
-+ * Revision 1.17 1998/12/02 03:09:39 rgb
-+ * Clean up debug printing conditionals to compile with debugging off.
-+ *
-+ * Revision 1.16 1998/12/01 13:49:39 rgb
-+ * Wrap version info printing in debug switches.
-+ *
-+ * Revision 1.15 1998/11/30 13:22:54 rgb
-+ * Rationalised all the klips kernel file headers. They are much shorter
-+ * now and won't conflict under RH5.2.
-+ *
-+ * Revision 1.14 1998/10/31 06:48:17 rgb
-+ * Fixed up comments in #endif directives.
-+ *
-+ * Revision 1.13 1998/10/27 13:48:09 rgb
-+ * Cleaned up /proc/net/ipsec_* filesystem for easy parsing by scripts.
-+ * Fixed less(1) truncated output bug.
-+ * Code clean-up.
-+ *
-+ * Revision 1.12 1998/10/25 02:41:36 rgb
-+ * Change return type on ipsec_breakroute and ipsec_makeroute and add an
-+ * argument to be able to transmit more infomation about errors.
-+ * Fix cut-and-paste debug statement identifier.
-+ *
-+ * Revision 1.11 1998/10/22 06:45:39 rgb
-+ * Cleaned up cruft.
-+ * Convert to use satoa for printk.
-+ *
-+ * Revision 1.10 1998/10/19 14:44:28 rgb
-+ * Added inclusion of freeswan.h.
-+ * sa_id structure implemented and used: now includes protocol.
-+ *
-+ * Revision 1.9 1998/10/09 04:30:52 rgb
-+ * Added 'klips_debug' prefix to all klips printk debug statements.
-+ * Deleted old commented out cruft.
-+ *
-+ * Revision 1.8 1998/08/06 17:24:23 rgb
-+ * Fix addrtoa return code bug from stale manpage advice preventing packets
-+ * from being erouted.
-+ *
-+ * Revision 1.7 1998/08/06 07:44:59 rgb
-+ * Fixed /proc/net/ipsec_eroute subnettoa and addrtoa return value bug that
-+ * ended up in nothing being printed.
-+ *
-+ * Revision 1.6 1998/08/05 22:16:41 rgb
-+ * Cleanup to prevent cosmetic errors (ie. debug output) from being fatal.
-+ *
-+ * Revision 1.5 1998/07/29 20:38:44 rgb
-+ * Debug and fix subnettoa and addrtoa output.
-+ *
-+ * Revision 1.4 1998/07/28 00:02:39 rgb
-+ * Converting to exclusive use of addrtoa.
-+ * Fix eroute delete.
-+ *
-+ * Revision 1.3 1998/07/14 18:21:26 rgb
-+ * Add function to clear the eroute table.
-+ *
-+ * Revision 1.2 1998/06/23 02:59:14 rgb
-+ * Added debugging output to eroute add/delete routines.
-+ *
-+ * Revision 1.9 1998/06/18 21:29:06 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid kernel
-+ * build scripts happier in presence of symbolic links
-+ *
-+ * Revision 1.8 1998/06/05 02:32:26 rgb
-+ * Fix spi ntoh kernel debug output.
-+ *
-+ * Revision 1.7 1998/05/25 20:30:37 rgb
-+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
-+ *
-+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
-+ * add ipsec_rj_walker_delete.
-+ *
-+ * Revision 1.6 1998/05/21 13:08:57 rgb
-+ * Rewrote procinfo subroutines to avoid *bad things* when more that 3k of
-+ * information is available for printout.
-+ *
-+ * Revision 1.5 1998/05/18 21:35:55 rgb
-+ * Clean up output for numerical consistency and readability. Zero freed
-+ * eroute memory.
-+ *
-+ * Revision 1.4 1998/04/21 21:28:58 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.3 1998/04/14 17:30:39 rgb
-+ * Fix up compiling errors for radij tree memory reclamation.
-+ *
-+ * Revision 1.2 1998/04/12 22:03:23 rgb
-+ * Updated ESP-3DES-HMAC-MD5-96,
-+ * ESP-DES-HMAC-MD5-96,
-+ * AH-HMAC-MD5-96,
-+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
-+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
-+ *
-+ * Fixed eroute references in /proc/net/ipsec*.
-+ *
-+ * Started to patch module unloading memory leaks in ipsec_netlink and
-+ * radij tree unloading.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:10 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * No changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:39:04 ji
-+ * Minor cleanups.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_rcv.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1922 @@
-+/*
-+ * receive code
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998-2003 Richard Guy Briggs.
-+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipsec_rcv_c_version[] = "RCSID $Id$";
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <net/udp.h>
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define proto_priv cb
-+#endif /* NET21 */
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h"
-+
-+#include "openswan/ipsec_auth.h"
-+
-+#include "openswan/ipsec_esp.h"
-+
-+#ifdef CONFIG_IPSEC_AH
-+#include "openswan/ipsec_ah.h"
-+#endif /* CONFIG_IPSEC_AH */
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+#include "openswan/ipsec_ipcomp.h"
-+#endif /* CONFIG_IPSEC_COMP */
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+#include "openswan/ipsec_alg.h"
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_rcv = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+int sysctl_ipsec_inbound_policy_check = 1;
-+
-+/* This is a private use protocol, and AT&T should be ashamed. They should have
-+ * used protocol # 59, which is "no next header" instead of 0xFE.
-+ */
-+#ifndef IPPROTO_ATT_HEARTBEAT
-+#define IPPROTO_ATT_HEARTBEAT 0xFE
-+#endif
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+void
-+ipsec_dmp(char *s, caddr_t bb, int len)
-+{
-+ int i;
-+ unsigned char *b = bb;
-+
-+
-+ printk(KERN_INFO "klips_debug:ipsec_tunnel_:dmp: "
-+ "at %s, len=%d:",
-+ s,
-+ len);
-+ for (i=0; i < len; i++) {
-+ if(!(i%16)){
-+ printk("\nklips_debug: ");
-+ }
-+ printk(" %02x", *b++);
-+ }
-+ printk("\n");
-+}
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+/*
-+ * Check-replay-window routine, adapted from the original
-+ * by J. Hughes, from draft-ietf-ipsec-esp-des-md5-03.txt
-+ *
-+ * This is a routine that implements a 64 packet window. This is intend-
-+ * ed on being an implementation sample.
-+ */
-+
-+DEBUG_NO_STATIC int
-+ipsec_checkreplaywindow(struct ipsec_sa*ipsp, __u32 seq)
-+{
-+ __u32 diff;
-+
-+ if (ipsp->ips_replaywin == 0) /* replay shut off */
-+ return 1;
-+ if (seq == 0)
-+ return 0; /* first == 0 or wrapped */
-+
-+ /* new larger sequence number */
-+ if (seq > ipsp->ips_replaywin_lastseq) {
-+ return 1; /* larger is good */
-+ }
-+ diff = ipsp->ips_replaywin_lastseq - seq;
-+
-+ /* too old or wrapped */ /* if wrapped, kill off SA? */
-+ if (diff >= ipsp->ips_replaywin) {
-+ return 0;
-+ }
-+ /* this packet already seen */
-+ if (ipsp->ips_replaywin_bitmap & (1 << diff))
-+ return 0;
-+ return 1; /* out of order but good */
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_updatereplaywindow(struct ipsec_sa*ipsp, __u32 seq)
-+{
-+ __u32 diff;
-+
-+ if (ipsp->ips_replaywin == 0) /* replay shut off */
-+ return 1;
-+ if (seq == 0)
-+ return 0; /* first == 0 or wrapped */
-+
-+ /* new larger sequence number */
-+ if (seq > ipsp->ips_replaywin_lastseq) {
-+ diff = seq - ipsp->ips_replaywin_lastseq;
-+
-+ /* In win, set bit for this pkt */
-+ if (diff < ipsp->ips_replaywin)
-+ ipsp->ips_replaywin_bitmap =
-+ (ipsp->ips_replaywin_bitmap << diff) | 1;
-+ else
-+ /* This packet has way larger seq num */
-+ ipsp->ips_replaywin_bitmap = 1;
-+
-+ if(seq - ipsp->ips_replaywin_lastseq - 1 > ipsp->ips_replaywin_maxdiff) {
-+ ipsp->ips_replaywin_maxdiff = seq - ipsp->ips_replaywin_lastseq - 1;
-+ }
-+ ipsp->ips_replaywin_lastseq = seq;
-+ return 1; /* larger is good */
-+ }
-+ diff = ipsp->ips_replaywin_lastseq - seq;
-+
-+ /* too old or wrapped */ /* if wrapped, kill off SA? */
-+ if (diff >= ipsp->ips_replaywin) {
-+/*
-+ if(seq < 0.25*max && ipsp->ips_replaywin_lastseq > 0.75*max) {
-+ ipsec_sa_delchain(ipsp);
-+ }
-+*/
-+ return 0;
-+ }
-+ /* this packet already seen */
-+ if (ipsp->ips_replaywin_bitmap & (1 << diff))
-+ return 0;
-+ ipsp->ips_replaywin_bitmap |= (1 << diff); /* mark as seen */
-+ return 1; /* out of order but good */
-+}
-+
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+struct auth_alg ipsec_rcv_md5[]={
-+ {MD5Init, MD5Update, MD5Final, AHMD596_ALEN}
-+};
-+
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+struct auth_alg ipsec_rcv_sha1[]={
-+ {SHA1Init, SHA1Update, SHA1Final, AHSHA196_ALEN}
-+};
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+
-+enum ipsec_rcv_value
-+ipsec_rcv_decap_once(struct ipsec_rcv_state *irs, struct xform_functions *proto_funcs)
-+{
-+ int iphlen;
-+ unsigned char *dat;
-+ __u8 proto;
-+ struct in_addr ipsaddr;
-+ struct in_addr ipdaddr;
-+ int replay = 0; /* replay value in AH or ESP packet */
-+ struct ipsec_sa* ipsnext = NULL; /* next SA towards inside of packet */
-+ struct ipsec_sa *newipsp;
-+ struct iphdr *ipp;
-+ struct sk_buff *skb;
-+#ifdef CONFIG_IPSEC_ALG
-+ struct ipsec_alg_auth *ixt_a=NULL;
-+#endif /* CONFIG_IPSEC_ALG */
-+
-+ skb = irs->skb;
-+ irs->len = skb->len;
-+ dat = skb->data;
-+ ipp = irs->ipp;
-+ proto = ipp->protocol;
-+ ipsaddr.s_addr = ipp->saddr;
-+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
-+ ipdaddr.s_addr = ipp->daddr;
-+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
-+
-+ iphlen = ipp->ihl << 2;
-+ irs->iphlen=iphlen;
-+ ipp->check = 0; /* we know the sum is good */
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv_decap_once: "
-+ "decap (%d) from %s -> %s\n",
-+ proto, irs->ipsaddr_txt, irs->ipdaddr_txt);
-+
-+ /*
-+ * Find tunnel control block and (indirectly) call the
-+ * appropriate tranform routine. The resulting sk_buf
-+ * is a valid IP packet ready to go through input processing.
-+ */
-+
-+ irs->said.dst.u.v4.sin_addr.s_addr = ipp->daddr;
-+ irs->said.dst.u.v4.sin_family = AF_INET;
-+
-+ if(proto_funcs->rcv_checks) {
-+ enum ipsec_rcv_value retval =
-+ (*proto_funcs->rcv_checks)(irs, skb);
-+
-+ if(retval < 0) {
-+ return retval;
-+ }
-+ }
-+
-+ irs->said.proto = proto;
-+ irs->sa_len = satot(&irs->said, 0, irs->sa, sizeof(irs->sa));
-+ if(irs->sa_len == 0) {
-+ strcpy(irs->sa, "(error)");
-+ }
-+
-+ newipsp = ipsec_sa_getbyid(&irs->said);
-+ if (newipsp == NULL) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "no ipsec_sa for SA:%s: incoming packet with no SA dropped\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_SAIDNOTFOUND;
-+ }
-+
-+ /* MCR - XXX this is bizarre. ipsec_sa_getbyid returned it, having incremented the refcount,
-+ * why in the world would we decrement it here?
-+
-+ ipsec_sa_put(irs->ipsp);*/ /* incomplete */
-+
-+ /* If it is in larval state, drop the packet, we cannot process yet. */
-+ if(newipsp->ips_state == SADB_SASTATE_LARVAL) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "ipsec_sa in larval state, cannot be used yet, dropping packet.\n");
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ ipsec_sa_put(newipsp);
-+ return IPSEC_RCV_SAIDNOTLIVE;
-+ }
-+
-+ if(newipsp->ips_state == SADB_SASTATE_DEAD) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "ipsec_sa in dead state, cannot be used any more, dropping packet.\n");
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ ipsec_sa_put(newipsp);
-+ return IPSEC_RCV_SAIDNOTLIVE;
-+ }
-+
-+ if(sysctl_ipsec_inbound_policy_check) {
-+ if(irs->ipp->saddr != ((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n",
-+ irs->sa_len ? irs->sa : " (error)",
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ ipsec_sa_put(newipsp);
-+ return IPSEC_RCV_FAILEDINBOUND;
-+ }
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s, src=%s of pkt agrees with expected SA source address policy.\n",
-+ irs->sa_len ? irs->sa : " (error)",
-+ irs->ipsaddr_txt);
-+
-+ /*
-+ * at this point, we have looked up a new SA, and we want to make sure that if this
-+ * isn't the first SA in the list, that the previous SA actually points at this one.
-+ */
-+ if(irs->ipsp) {
-+ if(irs->ipsp->ips_inext != newipsp) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "unexpected SA:%s: does not agree with ips->inext policy, dropped\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ ipsec_sa_put(newipsp);
-+ return IPSEC_RCV_FAILEDINBOUND;
-+ }
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s grouping from previous SA is OK.\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ } else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s First SA in group.\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ }
-+
-+ /*
-+ * previously, at this point, we checked if the back pointer from the new SA that
-+ * we just found matched the back pointer. But, we won't do this check anymore,
-+ * because we want to be able to nest SAs
-+ */
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "natt_type=%u tdbp->ips_natt_type=%u : %s\n",
-+ irs->natt_type, newipsp->ips_natt_type,
-+ (irs->natt_type==newipsp->ips_natt_type)?"ok":"bad");
-+ if (irs->natt_type != newipsp->ips_natt_type) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s does not agree with expected NAT-T policy.\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ ipsec_sa_put(newipsp);
-+ return IPSEC_RCV_FAILEDINBOUND;
-+ }
-+#endif
-+ }
-+
-+ /* okay, SA checks out, so free any previous SA, and record a new one */
-+
-+ if(irs->ipsp) {
-+ ipsec_sa_put(irs->ipsp);
-+ }
-+ irs->ipsp=newipsp;
-+
-+ /* note that the outer code will free the irs->ipsp if there is an error */
-+
-+
-+ /* now check the lifetimes */
-+ if(ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_bytes, "bytes",
-+ irs->sa, ipsec_life_countbased, ipsec_incoming,
-+ irs->ipsp) == ipsec_life_harddied ||
-+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "addtime",
-+ irs->sa, ipsec_life_timebased, ipsec_incoming,
-+ irs->ipsp) == ipsec_life_harddied ||
-+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_addtime, "usetime",
-+ irs->sa, ipsec_life_timebased, ipsec_incoming,
-+ irs->ipsp) == ipsec_life_harddied ||
-+ ipsec_lifetime_check(&irs->ipsp->ips_life.ipl_packets, "packets",
-+ irs->sa, ipsec_life_countbased, ipsec_incoming,
-+ irs->ipsp) == ipsec_life_harddied) {
-+ ipsec_sa_delchain(irs->ipsp);
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv_decap_once: "
-+ "decap (%d) failed lifetime check\n",
-+ proto);
-+
-+ return IPSEC_RCV_LIFETIMEFAILED;
-+ }
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if ((irs->natt_type) &&
-+ ( (irs->ipp->saddr != (((struct sockaddr_in*)(newipsp->ips_addr_s))->sin_addr.s_addr)) ||
-+ (irs->natt_sport != newipsp->ips_natt_sport)
-+ )) {
-+ struct sockaddr sipaddr;
-+ /** Advertise NAT-T addr change to pluto **/
-+ sipaddr.sa_family = AF_INET;
-+ ((struct sockaddr_in*)&sipaddr)->sin_addr.s_addr = irs->ipp->saddr;
-+ ((struct sockaddr_in*)&sipaddr)->sin_port = htons(irs->natt_sport);
-+ pfkey_nat_t_new_mapping(newipsp, &sipaddr, irs->natt_sport);
-+ /**
-+ * Then allow or block packet depending on
-+ * sysctl_ipsec_inbound_policy_check.
-+ *
-+ * In all cases, pluto will update SA if new mapping is
-+ * accepted.
-+ */
-+ if (sysctl_ipsec_inbound_policy_check) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s, src=%s:%u of pkt does not agree with expected "
-+ "SA source address policy (pluto has been informed).\n",
-+ irs->sa_len ? irs->sa : " (error)",
-+ irs->ipsaddr_txt, irs->natt_sport);
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ ipsec_sa_put(newipsp);
-+ return IPSEC_RCV_FAILEDINBOUND;
-+ }
-+ }
-+#endif
-+
-+ irs->authfuncs=NULL;
-+ /* authenticate, if required */
-+#ifdef CONFIG_IPSEC_ALG
-+ if ((ixt_a=irs->ipsp->ips_alg_auth)) {
-+ irs->authlen = AHHMAC_HASHLEN;
-+ irs->authfuncs = NULL;
-+ irs->ictx = NULL;
-+ irs->octx = NULL;
-+ irs->ictx_len = 0;
-+ irs->octx_len = 0;
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "authalg=%d authlen=%d\n",
-+ irs->ipsp->ips_authalg,
-+ irs->authlen);
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(irs->ipsp->ips_authalg) {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5:
-+ irs->authlen = AHHMAC_HASHLEN;
-+ irs->authfuncs = ipsec_rcv_md5;
-+ irs->ictx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx;
-+ irs->octx = (void *)&((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx;
-+ irs->ictx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->ictx);
-+ irs->octx_len = sizeof(((struct md5_ctx*)(irs->ipsp->ips_key_a))->octx);
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA:
-+ irs->authlen = AHHMAC_HASHLEN;
-+ irs->authfuncs = ipsec_rcv_sha1;
-+ irs->ictx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx;
-+ irs->octx = (void *)&((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx;
-+ irs->ictx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->ictx);
-+ irs->octx_len = sizeof(((struct sha1_ctx*)(irs->ipsp->ips_key_a))->octx);
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ case AH_NONE:
-+ irs->authlen = 0;
-+ irs->authfuncs = NULL;
-+ irs->ictx = NULL;
-+ irs->octx = NULL;
-+ irs->ictx_len = 0;
-+ irs->octx_len = 0;
-+ break;
-+ default:
-+ irs->ipsp->ips_errs.ips_alg_errs += 1;
-+ if(irs->stats) {
-+ irs->stats->rx_errors++;
-+ }
-+ return IPSEC_RCV_BADAUTH;
-+ }
-+
-+ irs->ilen = irs->len - iphlen - irs->authlen;
-+ if(irs->ilen <= 0) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "runt %s packet with no data, dropping.\n",
-+ (proto == IPPROTO_ESP ? "esp" : "ah"));
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_BADLEN;
-+ }
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if(irs->authfuncs || ixt_a) {
-+#else
-+ if(irs->authfuncs) {
-+#endif
-+ unsigned char *authenticator = NULL;
-+
-+ if(proto_funcs->rcv_setup_auth) {
-+ enum ipsec_rcv_value retval
-+ = (*proto_funcs->rcv_setup_auth)(irs, skb,
-+ &replay,
-+ &authenticator);
-+ if(retval < 0) {
-+ return retval;
-+ }
-+ }
-+
-+ if(!authenticator) {
-+ irs->ipsp->ips_errs.ips_auth_errs += 1;
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_BADAUTH;
-+ }
-+
-+ if(!ipsec_checkreplaywindow(irs->ipsp, replay)) {
-+ irs->ipsp->ips_errs.ips_replaywin_errs += 1;
-+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
-+ "klips_debug:ipsec_rcv: "
-+ "duplicate frame from %s, packet dropped\n",
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_REPLAYFAILED;
-+ }
-+
-+ /*
-+ * verify authenticator
-+ */
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "encalg = %d, authalg = %d.\n",
-+ irs->ipsp->ips_encalg,
-+ irs->ipsp->ips_authalg);
-+
-+ /* calculate authenticator */
-+ if(proto_funcs->rcv_calc_auth == NULL) {
-+ return IPSEC_RCV_BADAUTH;
-+ }
-+ (*proto_funcs->rcv_calc_auth)(irs, skb);
-+
-+ if (memcmp(irs->hash, authenticator, irs->authlen)) {
-+ irs->ipsp->ips_errs.ips_auth_errs += 1;
-+ KLIPS_PRINT(debug_rcv & DB_RX_INAU,
-+ "klips_debug:ipsec_rcv: "
-+ "auth failed on incoming packet from %s: hash=%08x%08x%08x auth=%08x%08x%08x, dropped\n",
-+ irs->ipsaddr_txt,
-+ ntohl(*(__u32*)&irs->hash[0]),
-+ ntohl(*(__u32*)&irs->hash[4]),
-+ ntohl(*(__u32*)&irs->hash[8]),
-+ ntohl(*(__u32*)authenticator),
-+ ntohl(*((__u32*)authenticator + 1)),
-+ ntohl(*((__u32*)authenticator + 2)));
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_AUTHFAILED;
-+ } else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "authentication successful.\n");
-+ }
-+
-+ /* Crypto hygiene: clear memory used to calculate autheticator.
-+ * The length varies with the algorithm.
-+ */
-+ memset(irs->hash, 0, irs->authlen);
-+
-+ /* If the sequence number == 0, expire SA, it had rolled */
-+ if(irs->ipsp->ips_replaywin && !replay /* !irs->ipsp->ips_replaywin_lastseq */) {
-+ ipsec_sa_delchain(irs->ipsp);
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "replay window counter rolled, expiring SA.\n");
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_REPLAYROLLED;
-+ }
-+
-+ /* now update the replay counter */
-+ if (!ipsec_updatereplaywindow(irs->ipsp, replay)) {
-+ irs->ipsp->ips_errs.ips_replaywin_errs += 1;
-+ KLIPS_PRINT(debug_rcv & DB_RX_REPLAY,
-+ "klips_debug:ipsec_rcv: "
-+ "duplicate frame from %s, packet dropped\n",
-+ irs->ipsaddr_txt);
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_REPLAYROLLED;
-+ }
-+ }
-+
-+ if(proto_funcs->rcv_decrypt) {
-+ enum ipsec_rcv_value retval =
-+ (*proto_funcs->rcv_decrypt)(irs);
-+
-+ if(retval != IPSEC_RCV_OK) {
-+ return retval;
-+ }
-+ }
-+
-+ /*
-+ * Adjust pointers
-+ */
-+ skb = irs->skb;
-+ irs->len = skb->len;
-+ dat = skb->data;
-+
-+#ifdef NET_21
-+/* skb->h.ipiph=(struct iphdr *)skb->data; */
-+ skb->nh.raw = skb->data;
-+ skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2);
-+
-+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
-+#else /* NET_21 */
-+ skb->h.iph=(struct iphdr *)skb->data;
-+ skb->ip_hdr=(struct iphdr *)skb->data;
-+ memset(skb->proto_priv, 0, sizeof(struct options));
-+#endif /* NET_21 */
-+
-+ ipp = (struct iphdr *)dat;
-+ ipsaddr.s_addr = ipp->saddr;
-+ addrtoa(ipsaddr, 0, irs->ipsaddr_txt, sizeof(irs->ipsaddr_txt));
-+ ipdaddr.s_addr = ipp->daddr;
-+ addrtoa(ipdaddr, 0, irs->ipdaddr_txt, sizeof(irs->ipdaddr_txt));
-+ /*
-+ * Discard the original ESP/AH header
-+ */
-+ ipp->protocol = irs->next_header;
-+
-+ ipp->check = 0; /* NOTE: this will be included in checksum */
-+ ipp->check = ip_fast_csum((unsigned char *)dat, iphlen >> 2);
-+
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "after <%s%s%s>, SA:%s:\n",
-+ IPS_XFORM_NAME(irs->ipsp),
-+ irs->sa_len ? irs->sa : " (error)");
-+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
-+
-+ skb->protocol = htons(ETH_P_IP);
-+ skb->ip_summed = 0;
-+
-+ ipsnext = irs->ipsp->ips_inext;
-+ if(sysctl_ipsec_inbound_policy_check) {
-+ if(ipsnext) {
-+ if(
-+ ipp->protocol != IPPROTO_AH
-+ && ipp->protocol != IPPROTO_ESP
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ && ipp->protocol != IPPROTO_COMP
-+ && (ipsnext->ips_said.proto != IPPROTO_COMP
-+ || ipsnext->ips_inext)
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ && ipp->protocol != IPPROTO_IPIP
-+ && ipp->protocol != 0xFE /* added to support heartbeats to AT&T SIG/GIG */
-+ ) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "packet with incomplete policy dropped, last successful SA:%s.\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ if(irs->stats) {
-+ irs->stats->rx_dropped++;
-+ }
-+ return IPSEC_RCV_FAILEDINBOUND;
-+ }
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s, Another IPSEC header to process.\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ } else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "No ips_inext from this SA:%s.\n",
-+ irs->sa_len ? irs->sa : " (error)");
-+ }
-+ }
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ /* update ipcomp ratio counters, even if no ipcomp packet is present */
-+ if (ipsnext
-+ && ipsnext->ips_said.proto == IPPROTO_COMP
-+ && ipp->protocol != IPPROTO_COMP) {
-+ ipsnext->ips_comp_ratio_cbytes += ntohs(ipp->tot_len);
-+ ipsnext->ips_comp_ratio_dbytes += ntohs(ipp->tot_len);
-+ }
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+ irs->ipsp->ips_life.ipl_bytes.ipl_count += irs->len;
-+ irs->ipsp->ips_life.ipl_bytes.ipl_last = irs->len;
-+
-+ if(!irs->ipsp->ips_life.ipl_usetime.ipl_count) {
-+ irs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
-+ }
-+ irs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
-+ irs->ipsp->ips_life.ipl_packets.ipl_count += 1;
-+
-+#ifdef CONFIG_NETFILTER
-+ if(proto == IPPROTO_ESP || proto == IPPROTO_AH) {
-+ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_MASK))))
-+ | IPsecSAref2NFmark(IPsecSA2SAref(irs->ipsp));
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "%s SA sets skb->nfmark=0x%x.\n",
-+ proto == IPPROTO_ESP ? "ESP" : "AH",
-+ (unsigned)skb->nfmark);
-+ }
-+#endif /* CONFIG_NETFILTER */
-+
-+ return IPSEC_RCV_OK;
-+}
-+
-+
-+int
-+#ifdef PROTO_HANDLER_SINGLE_PARM
-+ipsec_rcv(struct sk_buff *skb)
-+#else /* PROTO_HANDLER_SINGLE_PARM */
-+#ifdef NET_21
-+ipsec_rcv(struct sk_buff *skb, unsigned short xlen)
-+#else /* NET_21 */
-+ipsec_rcv(struct sk_buff *skb, struct device *dev, struct options *opt,
-+ __u32 daddr_unused, unsigned short xlen, __u32 saddr,
-+ int redo, struct inet_protocol *protocol)
-+#endif /* NET_21 */
-+#endif /* PROTO_HANDLER_SINGLE_PARM */
-+{
-+#ifdef NET_21
-+#ifdef CONFIG_IPSEC_DEBUG
-+ struct device *dev = skb->dev;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#endif /* NET_21 */
-+ unsigned char protoc;
-+ struct iphdr *ipp;
-+ struct ipsec_sa *ipsp = NULL;
-+ struct net_device_stats *stats = NULL; /* This device's statistics */
-+ struct device *ipsecdev = NULL, *prvdev;
-+ struct ipsecpriv *prv;
-+ char name[9];
-+ int i;
-+ struct in_addr ipsaddr;
-+ struct in_addr ipdaddr;
-+
-+ struct ipsec_sa* ipsnext = NULL; /* next SA towards inside of packet */
-+ struct ipsec_rcv_state irs;
-+
-+ /* Don't unlink in the middle of a turnaround */
-+ MOD_INC_USE_COUNT;
-+
-+ memset(&irs, 0, sizeof(struct ipsec_rcv_state));
-+
-+ if (skb == NULL) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NULL skb passed in.\n");
-+ goto rcvleave;
-+ }
-+
-+ if (skb->data == NULL) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NULL skb->data passed in, packet is bogus, dropping.\n");
-+ goto rcvleave;
-+ }
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if (skb->sk && skb->nh.iph && skb->nh.iph->protocol==IPPROTO_UDP) {
-+ /**
-+ * Packet comes from udp_queue_rcv_skb so it is already defrag,
-+ * checksum verified, ... (ie safe to use)
-+ *
-+ * If the packet is not for us, return -1 and udp_queue_rcv_skb
-+ * will continue to handle it (do not kfree skb !!).
-+ */
-+#ifndef UDP_OPT_IN_SOCK
-+ struct udp_opt {
-+ __u32 esp_in_udp;
-+ };
-+ struct udp_opt *tp = (struct udp_opt *)&(skb->sk->tp_pinfo.af_tcp);
-+#else
-+ struct udp_opt *tp = &(skb->sk->tp_pinfo.af_udp);
-+#endif
-+ struct iphdr *ip = (struct iphdr *)skb->nh.iph;
-+ struct udphdr *udp = (struct udphdr *)((__u32 *)ip+ip->ihl);
-+ __u8 *udpdata = (__u8 *)udp + sizeof(struct udphdr);
-+ __u32 *udpdata32 = (__u32 *)udpdata;
-+
-+ irs.natt_sport = ntohs(udp->source);
-+ irs.natt_dport = ntohs(udp->dest);
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "suspected ESPinUDP packet (NAT-Traversal) [%d].\n",
-+ tp->esp_in_udp);
-+ KLIPS_IP_PRINT(debug_rcv, ip);
-+
-+ if (udpdata < skb->tail) {
-+ unsigned int len = skb->tail - udpdata;
-+ if ((len==1) && (udpdata[0]==0xff)) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ /* not IPv6 compliant message */
-+ "NAT-keepalive from %d.%d.%d.%d.\n", NIPQUAD(ip->saddr));
-+ goto rcvleave;
-+ }
-+ else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_IKE) &&
-+ (len > (2*sizeof(__u32) + sizeof(struct esphdr))) &&
-+ (udpdata32[0]==0) && (udpdata32[1]==0) ) {
-+ /* ESP Packet with Non-IKE header */
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "ESPinUDP pkt with Non-IKE - spi=0x%x\n",
-+ ntohl(udpdata32[2]));
-+ irs.natt_type = ESPINUDP_WITH_NON_IKE;
-+ irs.natt_len = sizeof(struct udphdr)+(2*sizeof(__u32));
-+ }
-+ else if ( (tp->esp_in_udp == ESPINUDP_WITH_NON_ESP) &&
-+ (len > sizeof(struct esphdr)) &&
-+ (udpdata32[0]!=0) ) {
-+ /* ESP Packet without Non-ESP header */
-+ irs.natt_type = ESPINUDP_WITH_NON_ESP;
-+ irs.natt_len = sizeof(struct udphdr);
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "ESPinUDP pkt without Non-ESP - spi=0x%x\n",
-+ ntohl(udpdata32[0]));
-+ }
-+ else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "IKE packet - not handled here\n");
-+ MOD_DEC_USE_COUNT;
-+ return -1;
-+ }
-+ }
-+ else {
-+ MOD_DEC_USE_COUNT;
-+ return -1;
-+ }
-+ }
-+#endif
-+
-+#ifdef IPH_is_SKB_PULLED
-+ /* In Linux 2.4.4, the IP header has been skb_pull()ed before the
-+ packet is passed to us. So we'll skb_push() to get back to it. */
-+ if (skb->data == skb->h.raw) {
-+ skb_push(skb, skb->h.raw - skb->nh.raw);
-+ }
-+#endif /* IPH_is_SKB_PULLED */
-+
-+ /* dev->hard_header_len is unreliable and should not be used */
-+ irs.hard_header_len = skb->mac.raw ? (skb->data - skb->mac.raw) : 0;
-+ if((irs.hard_header_len < 0) || (irs.hard_header_len > skb_headroom(skb)))
-+ irs.hard_header_len = 0;
-+
-+#ifdef NET_21
-+ /* if skb was cloned (most likely due to a packet sniffer such as
-+ tcpdump being momentarily attached to the interface), make
-+ a copy of our own to modify */
-+ if(skb_cloned(skb)) {
-+ /* include any mac header while copying.. */
-+ if(skb_headroom(skb) < irs.hard_header_len) {
-+ printk(KERN_WARNING "klips_error:ipsec_rcv: "
-+ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
-+ irs.hard_header_len,
-+ skb_headroom(skb));
-+ goto rcvleave;
-+ }
-+ skb_push(skb, irs.hard_header_len);
-+ if
-+#ifdef SKB_COW_NEW
-+ (skb_cow(skb, skb_headroom(skb)) != 0)
-+#else /* SKB_COW_NEW */
-+ ((skb = skb_cow(skb, skb_headroom(skb))) == NULL)
-+#endif /* SKB_COW_NEW */
-+ {
-+ goto rcvleave;
-+ }
-+ if(skb->len < irs.hard_header_len) {
-+ printk(KERN_WARNING "klips_error:ipsec_rcv: "
-+ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
-+ irs.hard_header_len,
-+ skb->len);
-+ goto rcvleave;
-+ }
-+ skb_pull(skb, irs.hard_header_len);
-+ }
-+
-+#endif /* NET_21 */
-+
-+#if IP_FRAGMENT_LINEARIZE
-+ /* In Linux 2.4.4, we may have to reassemble fragments. They are
-+ not assembled automatically to save TCP from having to copy
-+ twice.
-+ */
-+ if (skb_is_nonlinear(skb)) {
-+ if (skb_linearize(skb, GFP_ATOMIC) != 0) {
-+ goto rcvleave;
-+ }
-+ }
-+#endif /* IP_FRAGMENT_LINEARIZE */
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if (irs.natt_len) {
-+ /**
-+ * Now, we are sure packet is ESPinUDP. Remove natt_len bytes from
-+ * packet and modify protocol to ESP.
-+ */
-+ if (((unsigned char *)skb->data > (unsigned char *)skb->nh.iph) &&
-+ ((unsigned char *)skb->nh.iph > (unsigned char *)skb->head)) {
-+ unsigned int _len = (unsigned char *)skb->data -
-+ (unsigned char *)skb->nh.iph;
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: adjusting skb: skb_push(%u)\n",
-+ _len);
-+ skb_push(skb, _len);
-+ }
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "removing %d bytes from ESPinUDP packet\n", irs.natt_len);
-+ ipp = (struct iphdr *)skb->data;
-+ irs.iphlen = ipp->ihl << 2;
-+ ipp->tot_len = htons(ntohs(ipp->tot_len) - irs.natt_len);
-+ if (skb->len < irs.iphlen + irs.natt_len) {
-+ printk(KERN_WARNING
-+ "klips_error:ipsec_rcv: "
-+ "ESPinUDP packet is too small (%d < %d+%d). "
-+ "This should never happen, please report.\n",
-+ (int)(skb->len), irs.iphlen, irs.natt_len);
-+ goto rcvleave;
-+ }
-+ memmove(skb->data + irs.natt_len, skb->data, irs.iphlen);
-+ skb_pull(skb, irs.natt_len);
-+
-+ /* update nh.iph */
-+ ipp = skb->nh.iph = (struct iphdr *)skb->data;
-+
-+ /* modify protocol */
-+ ipp->protocol = IPPROTO_ESP;
-+
-+ skb->sk = NULL;
-+
-+ KLIPS_IP_PRINT(debug_rcv, skb->nh.iph);
-+ }
-+#endif
-+
-+ ipp = skb->nh.iph;
-+ ipsaddr.s_addr = ipp->saddr;
-+ addrtoa(ipsaddr, 0, irs.ipsaddr_txt, sizeof(irs.ipsaddr_txt));
-+ ipdaddr.s_addr = ipp->daddr;
-+ addrtoa(ipdaddr, 0, irs.ipdaddr_txt, sizeof(irs.ipdaddr_txt));
-+ irs.iphlen = ipp->ihl << 2;
-+
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "<<< Info -- ");
-+ KLIPS_PRINTMORE(debug_rcv && skb->dev, "skb->dev=%s ",
-+ skb->dev->name ? skb->dev->name : "NULL");
-+ KLIPS_PRINTMORE(debug_rcv && dev, "dev=%s ",
-+ dev->name ? dev->name : "NULL");
-+ KLIPS_PRINTMORE(debug_rcv, "\n");
-+
-+ KLIPS_PRINT(debug_rcv && !(skb->dev && dev && (skb->dev == dev)),
-+ "klips_debug:ipsec_rcv: "
-+ "Informational -- **if this happens, find out why** skb->dev:%s is not equal to dev:%s\n",
-+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL",
-+ dev ? (dev->name ? dev->name : "NULL") : "NULL");
-+
-+ protoc = ipp->protocol;
-+#ifndef NET_21
-+ if((!protocol) || (protocol->protocol != protoc)) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
-+ "klips_debug:ipsec_rcv: "
-+ "protocol arg is NULL or unequal to the packet contents, this is odd, using value in packet.\n");
-+ }
-+#endif /* !NET_21 */
-+
-+ if( (protoc != IPPROTO_AH) &&
-+#ifdef CONFIG_IPSEC_IPCOMP_disabled_until_we_register_IPCOMP_HANDLER
-+ (protoc != IPPROTO_COMP) &&
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ (protoc != IPPROTO_ESP) ) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_IPSA,
-+ "klips_debug:ipsec_rcv: Why the hell is someone "
-+ "passing me a non-ipsec protocol = %d packet? -- dropped.\n",
-+ protoc);
-+ goto rcvleave;
-+ }
-+
-+ if(skb->dev) {
-+ for(i = 0; i < IPSEC_NUM_IF; i++) {
-+ sprintf(name, IPSEC_DEV_FORMAT, i);
-+ if(!strcmp(name, skb->dev->name)) {
-+ prv = (struct ipsecpriv *)(skb->dev->priv);
-+ if(prv) {
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+ }
-+ ipsecdev = skb->dev;
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "Info -- pkt already proc'ed a group of ipsec headers, processing next group of ipsec headers.\n");
-+ break;
-+ }
-+ if((ipsecdev = __ipsec_dev_get(name)) == NULL) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_error:ipsec_rcv: "
-+ "device %s does not exist\n",
-+ name);
-+ }
-+ prv = ipsecdev ? (struct ipsecpriv *)(ipsecdev->priv) : NULL;
-+ prvdev = prv ? (struct device *)(prv->dev) : NULL;
-+
-+#if 0
-+ KLIPS_PRINT(debug_rcv && prvdev,
-+ "klips_debug:ipsec_rcv: "
-+ "physical device for device %s is %s\n",
-+ name,
-+ prvdev->name);
-+#endif
-+ if(prvdev && skb->dev &&
-+ !strcmp(prvdev->name, skb->dev->name)) {
-+ stats = prv ? ((struct net_device_stats *) &(prv->mystats)) : NULL;
-+ skb->dev = ipsecdev;
-+ KLIPS_PRINT(debug_rcv && prvdev,
-+ "klips_debug:ipsec_rcv: "
-+ "assigning packet ownership to virtual device %s from physical device %s.\n",
-+ name, prvdev->name);
-+ if(stats) {
-+ stats->rx_packets++;
-+ }
-+ break;
-+ }
-+ }
-+ } else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "device supplied with skb is NULL\n");
-+ }
-+
-+ if(stats == NULL) {
-+ KLIPS_PRINT((debug_rcv),
-+ "klips_error:ipsec_rcv: "
-+ "packet received from physical I/F (%s) not connected to ipsec I/F. Cannot record stats. May not have SA for decoding. Is IPSEC traffic expected on this I/F? Check routing.\n",
-+ skb->dev ? (skb->dev->name ? skb->dev->name : "NULL") : "NULL");
-+ }
-+
-+ KLIPS_IP_PRINT(debug_rcv, ipp);
-+
-+ /* begin decapsulating loop here */
-+
-+ /*
-+ The spinlock is to prevent any other process from
-+ accessing or deleting the ipsec_sa hash table or any of the
-+ ipsec_sa s while we are using and updating them.
-+
-+ This is not optimal, but was relatively straightforward
-+ at the time. A better way to do it has been planned for
-+ more than a year, to lock the hash table and put reference
-+ counts on each ipsec_sa instead. This is not likely to happen
-+ in KLIPS1 unless a volunteer contributes it, but will be
-+ designed into KLIPS2.
-+ */
-+ spin_lock(&tdb_lock);
-+
-+ /* set up for decap loop */
-+ irs.stats= stats;
-+ irs.ipp = ipp;
-+ irs.ipsp = NULL;
-+ irs.ilen = 0;
-+ irs.authlen=0;
-+ irs.authfuncs=NULL;
-+ irs.skb = skb;
-+
-+ do {
-+ int decap_stat;
-+ struct xform_functions *proto_funcs;
-+
-+ switch(irs.ipp->protocol) {
-+ case IPPROTO_ESP:
-+ proto_funcs = esp_xform_funcs;
-+ break;
-+
-+#ifdef CONFIG_IPSEC_AH
-+ case IPPROTO_AH:
-+ proto_funcs = ah_xform_funcs;
-+ break;
-+#endif /* !CONFIG_IPSEC_AH */
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ case IPPROTO_COMP:
-+ proto_funcs = ipcomp_xform_funcs;
-+ break;
-+#endif /* !CONFIG_IPSEC_IPCOMP */
-+ default:
-+ if(irs.stats) {
-+ irs.stats->rx_errors++;
-+ }
-+ decap_stat = IPSEC_RCV_BADPROTO;
-+ goto rcvleave;
-+ }
-+
-+ decap_stat = ipsec_rcv_decap_once(&irs, proto_funcs);
-+
-+ if(decap_stat != IPSEC_RCV_OK) {
-+ spin_unlock(&tdb_lock);
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: decap_once failed: %d\n",
-+ decap_stat);
-+
-+ goto rcvleave;
-+ }
-+ /* end decapsulation loop here */
-+ } while( (irs.ipp->protocol == IPPROTO_ESP )
-+ || (irs.ipp->protocol == IPPROTO_AH )
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ || (irs.ipp->protocol == IPPROTO_COMP)
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ );
-+
-+ /* set up for decap loop */
-+ ipp =irs.ipp;
-+ ipsp =irs.ipsp;
-+ ipsnext = ipsp->ips_inext;
-+ skb = irs.skb;
-+
-+ /* if there is an IPCOMP, but we don't have an IPPROTO_COMP,
-+ * then we can just skip it
-+ */
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ if(ipsnext && ipsnext->ips_said.proto == IPPROTO_COMP) {
-+ ipsp = ipsnext;
-+ ipsnext = ipsp->ips_inext;
-+ }
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if ((irs.natt_type) && (ipp->protocol != IPPROTO_IPIP)) {
-+ /**
-+ * NAT-Traversal and Transport Mode:
-+ * we need to correct TCP/UDP checksum
-+ *
-+ * If we've got NAT-OA, we can fix checksum without recalculation.
-+ */
-+ __u32 natt_oa = ipsp->ips_natt_oa ?
-+ ((struct sockaddr_in*)(ipsp->ips_natt_oa))->sin_addr.s_addr : 0;
-+ __u16 pkt_len = skb->tail - (unsigned char *)ipp;
-+ __u16 data_len = pkt_len - (ipp->ihl << 2);
-+
-+ switch (ipp->protocol) {
-+ case IPPROTO_TCP:
-+ if (data_len >= sizeof(struct tcphdr)) {
-+ struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ipp+ipp->ihl);
-+ if (natt_oa) {
-+ __u32 buff[2] = { ~natt_oa, ipp->saddr };
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NAT-T & TRANSPORT: "
-+ "fix TCP checksum using NAT-OA\n");
-+ tcp->check = csum_fold(
-+ csum_partial((unsigned char *)buff, sizeof(buff),
-+ tcp->check^0xffff));
-+ }
-+ else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NAT-T & TRANSPORT: recalc TCP checksum\n");
-+ if (pkt_len > (ntohs(ipp->tot_len)))
-+ data_len -= (pkt_len - ntohs(ipp->tot_len));
-+ tcp->check = 0;
-+ tcp->check = csum_tcpudp_magic(ipp->saddr, ipp->daddr,
-+ data_len, IPPROTO_TCP,
-+ csum_partial((unsigned char *)tcp, data_len, 0));
-+ }
-+ }
-+ else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NAT-T & TRANSPORT: can't fix TCP checksum\n");
-+ }
-+ break;
-+ case IPPROTO_UDP:
-+ if (data_len >= sizeof(struct udphdr)) {
-+ struct udphdr *udp = (struct udphdr *)((__u32 *)ipp+ipp->ihl);
-+ if (udp->check == 0) {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NAT-T & TRANSPORT: UDP checksum already 0\n");
-+ }
-+ else if (natt_oa) {
-+ __u32 buff[2] = { ~natt_oa, ipp->saddr };
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NAT-T & TRANSPORT: "
-+ "fix UDP checksum using NAT-OA\n");
-+ udp->check = csum_fold(
-+ csum_partial((unsigned char *)buff, sizeof(buff),
-+ udp->check^0xffff));
-+ }
-+ else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NAT-T & TRANSPORT: zero UDP checksum\n");
-+ udp->check = 0;
-+ }
-+ }
-+ else {
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NAT-T & TRANSPORT: can't fix UDP checksum\n");
-+ }
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");
-+ break;
-+ }
-+ }
-+#endif
-+
-+ /*
-+ * XXX this needs to be locked from when it was first looked
-+ * up in the decapsulation loop. Perhaps it is better to put
-+ * the IPIP decap inside the loop.
-+ */
-+ if(ipsnext) {
-+ ipsp = ipsnext;
-+ irs.sa_len = satot(&irs.said, 0, irs.sa, sizeof(irs.sa));
-+ if((ipp->protocol != IPPROTO_IPIP) &&
-+ ( 0xFE != ipp->protocol)) { /* added to support AT&T heartbeats to SIG/GIG */
-+ spin_unlock(&tdb_lock);
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s, Hey! How did this get through? Dropped.\n",
-+ irs.sa_len ? irs.sa : " (error)");
-+ if(stats) {
-+ stats->rx_dropped++;
-+ }
-+ goto rcvleave;
-+ }
-+ if(sysctl_ipsec_inbound_policy_check) {
-+ if((ipsnext = ipsp->ips_inext)) {
-+ char sa2[SATOT_BUF];
-+ size_t sa_len2;
-+ sa_len2 = satot(&ipsnext->ips_said, 0, sa2, sizeof(sa2));
-+ spin_unlock(&tdb_lock);
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "unexpected SA:%s after IPIP SA:%s\n",
-+ sa_len2 ? sa2 : " (error)",
-+ irs.sa_len ? irs.sa : " (error)");
-+ if(stats) {
-+ stats->rx_dropped++;
-+ }
-+ goto rcvleave;
-+ }
-+ if(ipp->saddr != ((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr.s_addr) {
-+ spin_unlock(&tdb_lock);
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s, src=%s of pkt does not agree with expected SA source address policy.\n",
-+ irs.sa_len ? irs.sa : " (error)",
-+ irs.ipsaddr_txt);
-+ if(stats) {
-+ stats->rx_dropped++;
-+ }
-+ goto rcvleave;
-+ }
-+ }
-+
-+ if(ipp->protocol == IPPROTO_IPIP) /* added to support AT&T heartbeats to SIG/GIG */
-+ {
-+ /*
-+ * XXX this needs to be locked from when it was first looked
-+ * up in the decapsulation loop. Perhaps it is better to put
-+ * the IPIP decap inside the loop.
-+ */
-+ ipsp->ips_life.ipl_bytes.ipl_count += skb->len;
-+ ipsp->ips_life.ipl_bytes.ipl_last = skb->len;
-+
-+ if(!ipsp->ips_life.ipl_usetime.ipl_count) {
-+ ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
-+ }
-+ ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
-+ ipsp->ips_life.ipl_packets.ipl_count += 1;
-+
-+ if(skb->len < irs.iphlen) {
-+ spin_unlock(&tdb_lock);
-+ printk(KERN_WARNING "klips_debug:ipsec_rcv: "
-+ "tried to skb_pull iphlen=%d, %d available. This should never happen, please report.\n",
-+ irs.iphlen,
-+ (int)(skb->len));
-+
-+ goto rcvleave;
-+ }
-+ skb_pull(skb, irs.iphlen);
-+
-+#ifdef NET_21
-+ ipp = (struct iphdr *)skb->nh.raw = skb->data;
-+ skb->h.raw = skb->nh.raw + (skb->nh.iph->ihl << 2);
-+
-+ memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
-+#else /* NET_21 */
-+ ipp = skb->ip_hdr = skb->h.iph = (struct iphdr *)skb->data;
-+
-+ memset(skb->proto_priv, 0, sizeof(struct options));
-+#endif /* NET_21 */
-+ ipsaddr.s_addr = ipp->saddr;
-+ addrtoa(ipsaddr, 0, irs.ipsaddr_txt, sizeof(irs.ipsaddr_txt));
-+ ipdaddr.s_addr = ipp->daddr;
-+ addrtoa(ipdaddr, 0, irs.ipdaddr_txt, sizeof(irs.ipdaddr_txt));
-+
-+ skb->protocol = htons(ETH_P_IP);
-+ skb->ip_summed = 0;
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "IPIP tunnel stripped.\n");
-+ KLIPS_IP_PRINT(debug_rcv & DB_RX_PKTRX, ipp);
-+ }
-+
-+ if(sysctl_ipsec_inbound_policy_check
-+ /*
-+ Note: "xor" (^) logically replaces "not equal"
-+ (!=) and "bitwise or" (|) logically replaces
-+ "boolean or" (||). This is done to speed up
-+ execution by doing only bitwise operations and
-+ no branch operations
-+ */
-+ && (((ipp->saddr & ipsp->ips_mask_s.u.v4.sin_addr.s_addr)
-+ ^ ipsp->ips_flow_s.u.v4.sin_addr.s_addr)
-+ | ((ipp->daddr & ipsp->ips_mask_d.u.v4.sin_addr.s_addr)
-+ ^ ipsp->ips_flow_d.u.v4.sin_addr.s_addr)) )
-+ {
-+ char sflow_txt[SUBNETTOA_BUF], dflow_txt[SUBNETTOA_BUF];
-+
-+ subnettoa(ipsp->ips_flow_s.u.v4.sin_addr,
-+ ipsp->ips_mask_s.u.v4.sin_addr,
-+ 0, sflow_txt, sizeof(sflow_txt));
-+ subnettoa(ipsp->ips_flow_d.u.v4.sin_addr,
-+ ipsp->ips_mask_d.u.v4.sin_addr,
-+ 0, dflow_txt, sizeof(dflow_txt));
-+ spin_unlock(&tdb_lock);
-+ KLIPS_PRINT(debug_rcv,
-+ "klips_debug:ipsec_rcv: "
-+ "SA:%s, inner tunnel policy [%s -> %s] does not agree with pkt contents [%s -> %s].\n",
-+ irs.sa_len ? irs.sa : " (error)",
-+ sflow_txt,
-+ dflow_txt,
-+ irs.ipsaddr_txt,
-+ irs.ipdaddr_txt);
-+ if(stats) {
-+ stats->rx_dropped++;
-+ }
-+ goto rcvleave;
-+ }
-+#ifdef CONFIG_NETFILTER
-+ skb->nfmark = (skb->nfmark & (~(IPsecSAref2NFmark(IPSEC_SA_REF_TABLE_MASK))))
-+ | IPsecSAref2NFmark(IPsecSA2SAref(ipsp));
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "IPIP SA sets skb->nfmark=0x%x.\n",
-+ (unsigned)skb->nfmark);
-+#endif /* CONFIG_NETFILTER */
-+ }
-+
-+ spin_unlock(&tdb_lock);
-+
-+#ifdef NET_21
-+ if(stats) {
-+ stats->rx_bytes += skb->len;
-+ }
-+ if(skb->dst) {
-+ dst_release(skb->dst);
-+ skb->dst = NULL;
-+ }
-+ skb->pkt_type = PACKET_HOST;
-+ if(irs.hard_header_len &&
-+ (skb->mac.raw != (skb->data - irs.hard_header_len)) &&
-+ (irs.hard_header_len <= skb_headroom(skb))) {
-+ /* copy back original MAC header */
-+ memmove(skb->data - irs.hard_header_len, skb->mac.raw, irs.hard_header_len);
-+ skb->mac.raw = skb->data - irs.hard_header_len;
-+ }
-+#endif /* NET_21 */
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ if(ipp->protocol == IPPROTO_COMP) {
-+ unsigned int flags = 0;
-+
-+ if(sysctl_ipsec_inbound_policy_check) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "inbound policy checking enabled, IPCOMP follows IPIP, dropped.\n");
-+ if (stats) {
-+ stats->rx_errors++;
-+ }
-+ goto rcvleave;
-+ }
-+ /*
-+ XXX need a ipsec_sa for updating ratio counters but it is not
-+ following policy anyways so it is not a priority
-+ */
-+ skb = skb_decompress(skb, NULL, &flags);
-+ if (!skb || flags) {
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "skb_decompress() returned error flags: %d, dropped.\n",
-+ flags);
-+ if (stats) {
-+ stats->rx_errors++;
-+ }
-+ goto rcvleave;
-+ }
-+ }
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#ifdef SKB_RESET_NFCT
-+ nf_conntrack_put(skb->nfct);
-+ skb->nfct = NULL;
-+#ifdef CONFIG_NETFILTER_DEBUG
-+ skb->nf_debug = 0;
-+#endif /* CONFIG_NETFILTER_DEBUG */
-+#endif /* SKB_RESET_NFCT */
-+ KLIPS_PRINT(debug_rcv & DB_RX_PKTRX,
-+ "klips_debug:ipsec_rcv: "
-+ "netif_rx() called.\n");
-+ netif_rx(skb);
-+
-+ MOD_DEC_USE_COUNT;
-+ return(0);
-+
-+ rcvleave:
-+ if(skb) {
-+ ipsec_kfree_skb(skb);
-+ }
-+
-+ MOD_DEC_USE_COUNT;
-+ return(0);
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.143.4.2 2004/08/22 03:29:06 mcr
-+ * include udp.h regardless of nat-t support.
-+ *
-+ * Revision 1.143.4.1 2004/08/21 02:14:58 ken
-+ * Patch from Jochen Eisinger for AT&T MTS Heartbeat packet support
-+ *
-+ * Revision 1.143 2004/05/10 22:27:00 mcr
-+ * fix for ESP-3DES-noauth test case.
-+ *
-+ * Revision 1.142 2004/05/10 22:25:57 mcr
-+ * reformat of calls to ipsec_lifetime_check().
-+ *
-+ * Revision 1.141 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.140 2004/02/03 03:12:53 mcr
-+ * removed erroneously, double patched code.
-+ *
-+ * Revision 1.139 2004/01/05 23:21:29 mcr
-+ * initialize sin_family in ipsec_rcv.c
-+ *
-+ * Revision 1.138 2003/12/24 19:46:52 mcr
-+ * if sock.h patch has not been applied, then define appropriate
-+ * structure so we can use it. This is serious inferior, and
-+ * depends upon the concept that the structure in question is
-+ * smaller than the other members of that union.
-+ * getting rid of differing methods is a better solution.
-+ *
-+ * Revision 1.137 2003/12/22 19:40:57 mcr
-+ * NAT-T patches 0.6c.
-+ *
-+ * Revision 1.136 2003/12/15 18:13:12 mcr
-+ * when compiling with NAT traversal, don't assume that the
-+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
-+ * is set.
-+ *
-+ * Revision 1.135 2003/12/13 19:10:21 mcr
-+ * refactored rcv and xmit code - same as FS 2.05.
-+ *
-+ * Revision 1.134.2.1 2003/12/22 15:25:52 jjo
-+ * Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.134 2003/12/10 01:14:27 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.133 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.132.2.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.132 2003/09/02 19:51:48 mcr
-+ * fixes for PR#252.
-+ *
-+ * Revision 1.131 2003/07/31 22:47:16 mcr
-+ * preliminary (untested by FS-team) 2.5 patches.
-+ *
-+ * Revision 1.130 2003/04/03 17:38:25 rgb
-+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
-+ * Clarified logic for non-connected devices.
-+ *
-+ * Revision 1.129 2003/02/06 02:21:34 rgb
-+ *
-+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
-+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
-+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
-+ *
-+ * Revision 1.128 2002/12/13 20:58:03 rgb
-+ * Relegated MCR's recent "_dmp" routine to debug_verbose.
-+ * Cleaned up printing of source and destination addresses in debug output.
-+ *
-+ * Revision 1.127 2002/12/04 16:00:16 rgb
-+ *
-+ * Fixed AH decapsulation pointer update bug and added some comments and
-+ * debugging.
-+ * This bug was caught by west-ah-0[12].
-+ *
-+ * Revision 1.126 2002/11/04 05:03:43 mcr
-+ * fixes for IPCOMP. There were two problems:
-+ * 1) the irs->ipp pointer was not being updated properly after
-+ * the ESP descryption. The meant nothing for IPIP, as the
-+ * later IP header overwrote the earlier one.
-+ * 2) the more serious problem was that skb_decompress will
-+ * usually allocate a new SKB, so we have to make sure that
-+ * it doesn't get lost.
-+ * #2 meant removing the skb argument from the ->decrypt routine
-+ * and moving it to the irs->skb, so it could be value/result.
-+ *
-+ * Revision 1.125 2002/11/01 01:53:35 dhr
-+ *
-+ * fix typo
-+ *
-+ * Revision 1.124 2002/10/31 22:49:01 dhr
-+ *
-+ * - eliminate unused variable "hash"
-+ * - reduce scope of variable "authenticator"
-+ * - add comment on a couple of tricky bits
-+ *
-+ * Revision 1.123 2002/10/31 22:39:56 dhr
-+ *
-+ * use correct type for result of function calls
-+ *
-+ * Revision 1.122 2002/10/31 22:36:25 dhr
-+ *
-+ * simplify complex test
-+ *
-+ * Revision 1.121 2002/10/31 22:34:04 dhr
-+ *
-+ * ipsprev is never used: ditch it
-+ *
-+ * Revision 1.120 2002/10/31 22:30:21 dhr
-+ *
-+ * eliminate redundant assignments
-+ *
-+ * Revision 1.119 2002/10/31 22:27:43 dhr
-+ *
-+ * make whitespace canonical
-+ *
-+ * Revision 1.118 2002/10/30 05:47:17 rgb
-+ * Fixed cut-and-paste error mis-identifying comp runt as ah.
-+ *
-+ * Revision 1.117 2002/10/17 16:37:45 rgb
-+ * Remove compp intermediate variable and in-line its contents
-+ * where used
-+ *
-+ * Revision 1.116 2002/10/12 23:11:53 dhr
-+ *
-+ * [KenB + DHR] more 64-bit cleanup
-+ *
-+ * Revision 1.115 2002/10/07 19:06:58 rgb
-+ * Minor fixups and activation to west-rcv-nfmark-set-01 test to check for SA reference properly set on incoming.
-+ *
-+ * Revision 1.114 2002/10/07 18:31:31 rgb
-+ * Set saref on incoming packets.
-+ *
-+ * Revision 1.113 2002/09/16 21:28:12 mcr
-+ * adjust hash length for HMAC calculation - must look at whether
-+ * it is MD5 or SHA1.
-+ *
-+ * Revision 1.112 2002/09/16 21:19:15 mcr
-+ * fixes for west-ah-icmp-01 - length of AH header must be
-+ * calculated properly, and next_header field properly copied.
-+ *
-+ * Revision 1.111 2002/09/10 02:45:56 mcr
-+ * re-factored the ipsec_rcv function into several functions,
-+ * ipsec_rcv_decap_once, and a set of functions for AH, ESP and IPCOMP.
-+ * In addition, the MD5 and SHA1 functions are replaced with pointers.
-+ *
-+ * Revision 1.110 2002/08/30 06:34:33 rgb
-+ * Fix scope of shift in AH header length check.
-+ *
-+ * Revision 1.109 2002/08/27 16:49:20 rgb
-+ * Fixed ESP short packet DOS (and AH and IPCOMP).
-+ *
-+ * Revision 1.108 2002/07/24 18:44:54 rgb
-+ * Type fiddling to tame ia64 compiler.
-+ *
-+ * Revision 1.107 2002/05/27 18:58:18 rgb
-+ * Convert to dynamic ipsec device allocation.
-+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
-+ *
-+ * Revision 1.106 2002/05/23 07:15:21 rgb
-+ * Pointer clean-up.
-+ * Added refcount code.
-+ *
-+ * Revision 1.105 2002/05/14 02:35:06 rgb
-+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
-+ * ipsec_sa or ipsec_sa.
-+ * Change references to _TDB to _IPSA.
-+ *
-+ * Revision 1.104 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.103 2002/04/24 07:36:30 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_rcv.c,v
-+ *
-+ * Revision 1.102 2002/01/29 17:17:56 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.101 2002/01/29 04:00:52 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.100 2002/01/29 02:13:17 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.99 2002/01/28 21:40:59 mcr
-+ * should use #if to test boolean option rather than #ifdef.
-+ *
-+ * Revision 1.98 2002/01/20 20:19:36 mcr
-+ * renamed option to IP_FRAGMENT_LINEARIZE.
-+ *
-+ * Revision 1.97 2002/01/12 02:55:36 mcr
-+ * fix for post-2.4.4 to linearize skb's when ESP packet
-+ * was assembled from fragments.
-+ *
-+ * Revision 1.96 2001/11/26 09:23:49 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.93.2.2 2001/10/22 20:54:07 mcr
-+ * include des.h, removed phony prototypes and fixed calling
-+ * conventions to match real prototypes.
-+ *
-+ * Revision 1.93.2.1 2001/09/25 02:22:22 mcr
-+ * struct tdb -> struct ipsec_sa.
-+ * lifetime checks moved to ipsec_life.c
-+ * some sa(tdb) manipulation functions renamed.
-+ *
-+ * Revision 1.95 2001/11/06 19:49:07 rgb
-+ * Added variable descriptions.
-+ * Removed unauthenticated sequence==0 check to prevent DoS.
-+ *
-+ * Revision 1.94 2001/10/18 04:45:20 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/freeswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.93 2001/09/07 22:17:24 rgb
-+ * Fix for removal of transport layer protocol handler arg in 2.4.4.
-+ * Fix to accomodate peer non-conformance to IPCOMP rfc2393.
-+ *
-+ * Revision 1.92 2001/08/27 19:44:41 rgb
-+ * Fix error in comment.
-+ *
-+ * Revision 1.91 2001/07/20 19:31:48 dhr
-+ * [DHR] fix source and destination subnets of policy in diagnostic
-+ *
-+ * Revision 1.90 2001/07/06 19:51:09 rgb
-+ * Added inbound policy checking code for IPIP SAs.
-+ * Renamed unused function argument for ease and intuitive naming.
-+ *
-+ * Revision 1.89 2001/06/22 19:35:23 rgb
-+ * Disable ipcomp processing if we are handed a ipcomp packet with no esp
-+ * or ah header.
-+ * Print protocol if we are handed a non-ipsec packet.
-+ *
-+ * Revision 1.88 2001/06/20 06:30:47 rgb
-+ * Fixed transport mode IPCOMP policy check bug.
-+ *
-+ * Revision 1.87 2001/06/13 20:58:40 rgb
-+ * Added parentheses around assignment used as truth value to silence
-+ * compiler.
-+ *
-+ * Revision 1.86 2001/06/07 22:25:23 rgb
-+ * Added a source address policy check for tunnel mode. It still does
-+ * not check client addresses and masks.
-+ * Only decapsulate IPIP if it is expected.
-+ *
-+ * Revision 1.85 2001/05/30 08:14:02 rgb
-+ * Removed vestiges of esp-null transforms.
-+ *
-+ * Revision 1.84 2001/05/27 06:12:11 rgb
-+ * Added structures for pid, packet count and last access time to eroute.
-+ * Added packet count to beginning of /proc/net/ipsec_eroute.
-+ *
-+ * Revision 1.83 2001/05/04 16:45:47 rgb
-+ * Remove unneeded code. ipp is not used after this point.
-+ *
-+ * Revision 1.82 2001/05/04 16:36:00 rgb
-+ * Fix skb_cow() call for 2.4.4. (SS)
-+ *
-+ * Revision 1.81 2001/05/02 14:46:53 rgb
-+ * Fix typo for compiler directive to pull IPH back.
-+ *
-+ * Revision 1.80 2001/04/30 19:46:34 rgb
-+ * Update for 2.4.4. We now receive the skb with skb->data pointing to
-+ * h.raw.
-+ *
-+ * Revision 1.79 2001/04/23 15:01:15 rgb
-+ * Added spin_lock() check to prevent double-locking for multiple
-+ * transforms and hence kernel lock-ups with SMP kernels.
-+ * Minor spin_unlock() adjustments to unlock before non-dependant prints
-+ * and IPSEC device stats updates.
-+ *
-+ * Revision 1.78 2001/04/21 23:04:24 rgb
-+ * Check if soft expire has already been sent before sending another to
-+ * prevent ACQUIRE flooding.
-+ *
-+ * Revision 1.77 2001/03/16 07:35:20 rgb
-+ * Ditch extra #if 1 around now permanent policy checking code.
-+ *
-+ * Revision 1.76 2001/02/27 22:24:54 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.75 2001/02/19 22:28:30 rgb
-+ * Minor change to virtual device discovery code to assert which I/F has
-+ * been found.
-+ *
-+ * Revision 1.74 2000/11/25 03:50:36 rgb
-+ * Oops fix by minor re-arrangement of code to avoid accessing a freed tdb.
-+ *
-+ * Revision 1.73 2000/11/09 20:52:15 rgb
-+ * More spinlock shuffling, locking earlier and unlocking later in rcv to
-+ * include ipcomp and prevent races, renaming some tdb variables that got
-+ * forgotten, moving some unlocks to include tdbs and adding a missing
-+ * unlock. Thanks to Svenning for some of these.
-+ *
-+ * Revision 1.72 2000/11/09 20:11:22 rgb
-+ * Minor shuffles to fix non-standard kernel config option selection.
-+ *
-+ * Revision 1.71 2000/11/06 04:36:18 rgb
-+ * Ditched spin_lock_irqsave in favour of spin_lock.
-+ * Minor initial protocol check rewrite.
-+ * Clean up debug printing.
-+ * Clean up tdb handling on ipcomp.
-+ * Fixed transport mode null pointer de-reference without ipcomp.
-+ * Add Svenning's adaptive content compression.
-+ * Disabled registration of ipcomp handler.
-+ *
-+ * Revision 1.70 2000/10/30 23:41:43 henry
-+ * Hans-Joerg Hoexer's null-pointer fix
-+ *
-+ * Revision 1.69 2000/10/10 18:54:16 rgb
-+ * Added a fix for incoming policy check with ipcomp enabled but
-+ * uncompressible.
-+ *
-+ * Revision 1.68 2000/09/22 17:53:12 rgb
-+ * Fixed ipcomp tdb pointers update for policy checking.
-+ *
-+ * Revision 1.67 2000/09/21 03:40:58 rgb
-+ * Added more debugging to try and track down the cpi outward copy problem.
-+ *
-+ * Revision 1.66 2000/09/20 04:00:10 rgb
-+ * Changed static functions to DEBUG_NO_STATIC to reveal function names for
-+ * debugging oopsen.
-+ *
-+ * Revision 1.65 2000/09/19 07:07:16 rgb
-+ * Added debugging to inbound policy check for ipcomp.
-+ * Added missing spin_unlocks (thanks Svenning!).
-+ * Fixed misplaced tdbnext pointers causing mismatched ipip policy check.
-+ * Protect ipcomp policy check following ipip decap with sysctl switch.
-+ *
-+ * Revision 1.64 2000/09/18 21:27:29 rgb
-+ * 2.0 fixes.
-+ *
-+ * Revision 1.63 2000/09/18 02:35:50 rgb
-+ * Added policy checking to ipcomp and re-enabled policy checking by
-+ * default.
-+ * Optimised satoa calls.
-+ *
-+ * Revision 1.62 2000/09/17 21:02:32 rgb
-+ * Clean up debugging, removing slow timestamp debug code.
-+ *
-+ * Revision 1.61 2000/09/16 01:07:55 rgb
-+ * Fixed erroneous ref from struct ipcomp to struct ipcomphdr.
-+ *
-+ * Revision 1.60 2000/09/15 11:37:01 rgb
-+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
-+ * IPCOMP zlib deflate code.
-+ *
-+ * Revision 1.59 2000/09/15 04:56:20 rgb
-+ * Remove redundant satoa() call, reformat comment.
-+ *
-+ * Revision 1.58 2000/09/13 08:00:52 rgb
-+ * Flick on inbound policy checking.
-+ *
-+ * Revision 1.57 2000/09/12 03:22:19 rgb
-+ * Converted inbound_policy_check to sysctl.
-+ * Re-enabled policy backcheck.
-+ * Moved policy checks to top and within tdb lock.
-+ *
-+ * Revision 1.56 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.55 2000/08/28 18:15:46 rgb
-+ * Added MB's nf-debug reset patch.
-+ *
-+ * Revision 1.54 2000/08/27 01:41:26 rgb
-+ * More minor tweaks to the bad padding debug code.
-+ *
-+ * Revision 1.53 2000/08/24 16:54:16 rgb
-+ * Added KLIPS_PRINTMORE macro to continue lines without KERN_INFO level
-+ * info.
-+ * Tidied up device reporting at the start of ipsec_rcv.
-+ * Tidied up bad padding debugging and processing.
-+ *
-+ * Revision 1.52 2000/08/20 21:36:03 rgb
-+ * Activated pfkey_expire() calls.
-+ * Added a hard/soft expiry parameter to pfkey_expire().
-+ * Added sanity checking to avoid propagating zero or smaller-length skbs
-+ * from a bogus decryption.
-+ * Re-arranged the order of soft and hard expiry to conform to RFC2367.
-+ * Clean up references to CONFIG_IPSEC_PFKEYv2.
-+ *
-+ * Revision 1.51 2000/08/18 21:23:30 rgb
-+ * Improve bad padding warning so that the printk buffer doesn't get
-+ * trampled.
-+ *
-+ * Revision 1.50 2000/08/01 14:51:51 rgb
-+ * Removed _all_ remaining traces of DES.
-+ *
-+ * Revision 1.49 2000/07/28 13:50:53 rgb
-+ * Changed enet_statistics to net_device_stats and added back compatibility
-+ * for pre-2.1.19.
-+ *
-+ * Revision 1.48 2000/05/10 19:14:40 rgb
-+ * Only check usetime against soft and hard limits if the tdb has been
-+ * used.
-+ * Cast output of ntohl so that the broken prototype doesn't make our
-+ * compile noisy.
-+ *
-+ * Revision 1.47 2000/05/09 17:45:43 rgb
-+ * Fix replay bitmap corruption bug upon receipt of bogus packet
-+ * with correct SPI. This was a DoS.
-+ *
-+ * Revision 1.46 2000/03/27 02:31:58 rgb
-+ * Fixed authentication failure printout bug.
-+ *
-+ * Revision 1.45 2000/03/22 16:15:37 rgb
-+ * Fixed renaming of dev_get (MB).
-+ *
-+ * Revision 1.44 2000/03/16 08:17:24 rgb
-+ * Hardcode PF_KEYv2 support.
-+ * Fixed minor bug checking AH header length.
-+ *
-+ * Revision 1.43 2000/03/14 12:26:59 rgb
-+ * Added skb->nfct support for clearing netfilter conntrack bits (MB).
-+ *
-+ * Revision 1.42 2000/01/26 10:04:04 rgb
-+ * Fixed inbound policy checking on transport mode bug.
-+ * Fixed noisy 2.0 printk arguments.
-+ *
-+ * Revision 1.41 2000/01/24 20:58:02 rgb
-+ * Improve debugging/reporting support for (disabled) inbound
-+ * policy checking.
-+ *
-+ * Revision 1.40 2000/01/22 23:20:10 rgb
-+ * Fixed up inboud policy checking code.
-+ * Cleaned out unused crud.
-+ *
-+ * Revision 1.39 2000/01/21 06:15:29 rgb
-+ * Added sanity checks on skb_push(), skb_pull() to prevent panics.
-+ * Fixed cut-and-paste debug_tunnel to debug_rcv.
-+ * Added inbound policy checking code, disabled.
-+ * Simplified output code by updating ipp to post-IPIP decapsulation.
-+ *
-+ * elided pre-2000 comments. Use "cvs log"
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_sa.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1383 @@
-+/*
-+ * Common routines for IPsec SA maintenance routines.
-+ *
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001, 2002 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ *
-+ * This is the file formerly known as "ipsec_xform.h"
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/vmalloc.h> /* vmalloc() */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef SPINLOCK
-+#ifdef SPINLOCK_23
-+#include <linux/spinlock.h> /* *lock* */
-+#else /* SPINLOCK_23 */
-+#include <asm/spinlock.h> /* *lock* */
-+#endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+#include <asm/uaccess.h>
-+#include <linux/in6.h>
-+#endif
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "openswan/radij.h"
-+
-+#include "openswan/ipsec_stats.h"
-+#include "openswan/ipsec_life.h"
-+#include "openswan/ipsec_sa.h"
-+#include "openswan/ipsec_xform.h"
-+
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_ipe4.h"
-+#include "openswan/ipsec_ah.h"
-+#include "openswan/ipsec_esp.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+#include "openswan/ipsec_alg.h"
-+
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_xform = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
-+
-+struct ipsec_sa *ipsec_sadb_hash[SADB_HASHMOD];
-+#ifdef SPINLOCK
-+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
-+#else /* SPINLOCK */
-+spinlock_t tdb_lock;
-+#endif /* SPINLOCK */
-+
-+struct ipsec_sadb ipsec_sadb;
-+
-+#if IPSEC_SA_REF_CODE
-+
-+/* the sub table must be narrower (or equal) in bits than the variable type
-+ in the main table to count the number of unused entries in it. */
-+typedef struct {
-+ int testSizeOf_refSubTable :
-+ ((sizeof(IPsecRefTableUnusedCount) * 8) < IPSEC_SA_REF_SUBTABLE_IDX_WIDTH ? -1 : 1);
-+} dummy;
-+
-+
-+/* The field where the saref will be hosted in the skb must be wide enough to
-+ accomodate the information it needs to store. */
-+typedef struct {
-+ int testSizeOf_refField :
-+ (IPSEC_SA_REF_HOST_FIELD_WIDTH < IPSEC_SA_REF_TABLE_IDX_WIDTH ? -1 : 1 );
-+} dummy2;
-+
-+
-+#define IPS_HASH(said) (((said)->spi + (said)->dst.u.v4.sin_addr.s_addr + (said)->proto) % SADB_HASHMOD)
-+
-+
-+void
-+ipsec_SAtest(void)
-+{
-+ IPsecSAref_t SAref = 258;
-+ struct ipsec_sa ips;
-+ ips.ips_ref = 772;
-+
-+ printk("klips_debug:ipsec_SAtest: "
-+ "IPSEC_SA_REF_SUBTABLE_IDX_WIDTH=%u\n"
-+ "IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES=%u\n"
-+ "IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES=%u\n"
-+ "IPSEC_SA_REF_HOST_FIELD_WIDTH=%lu\n"
-+ "IPSEC_SA_REF_TABLE_MASK=%x\n"
-+ "IPSEC_SA_REF_ENTRY_MASK=%x\n"
-+ "IPsecSAref2table(%d)=%u\n"
-+ "IPsecSAref2entry(%d)=%u\n"
-+ "IPsecSAref2NFmark(%d)=%u\n"
-+ "IPsecSAref2SA(%d)=%p\n"
-+ "IPsecSA2SAref(%p)=%d\n"
-+ ,
-+ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
-+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
-+ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
-+ (unsigned long) IPSEC_SA_REF_HOST_FIELD_WIDTH,
-+ IPSEC_SA_REF_TABLE_MASK,
-+ IPSEC_SA_REF_ENTRY_MASK,
-+ SAref, IPsecSAref2table(SAref),
-+ SAref, IPsecSAref2entry(SAref),
-+ SAref, IPsecSAref2NFmark(SAref),
-+ SAref, IPsecSAref2SA(SAref),
-+ (&ips), IPsecSA2SAref((&ips))
-+ );
-+ return;
-+}
-+
-+int
-+ipsec_SAref_recycle(void)
-+{
-+ int table;
-+ int entry;
-+ int error = 0;
-+
-+ ipsec_sadb.refFreeListHead = -1;
-+ ipsec_sadb.refFreeListTail = -1;
-+
-+ if(ipsec_sadb.refFreeListCont == IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_recycle: "
-+ "end of table reached, continuing at start..\n");
-+ ipsec_sadb.refFreeListCont = 0;
-+ }
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_recycle: "
-+ "recycling, continuing from SAref=%d (0p%p), table=%d, entry=%d.\n",
-+ ipsec_sadb.refFreeListCont,
-+ (ipsec_sadb.refTable[IPsecSAref2table(ipsec_sadb.refFreeListCont)] != NULL) ? IPsecSAref2SA(ipsec_sadb.refFreeListCont) : NULL,
-+ IPsecSAref2table(ipsec_sadb.refFreeListCont),
-+ IPsecSAref2entry(ipsec_sadb.refFreeListCont));
-+
-+ for(table = IPsecSAref2table(ipsec_sadb.refFreeListCont);
-+ table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES;
-+ table++) {
-+ if(ipsec_sadb.refTable[table] == NULL) {
-+ error = ipsec_SArefSubTable_alloc(table);
-+ if(error) {
-+ return error;
-+ }
-+ }
-+ for(entry = IPsecSAref2entry(ipsec_sadb.refFreeListCont);
-+ entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES;
-+ entry++) {
-+ if(ipsec_sadb.refTable[table]->entry[entry] == NULL) {
-+ ipsec_sadb.refFreeList[++ipsec_sadb.refFreeListTail] = IPsecSArefBuild(table, entry);
-+ if(ipsec_sadb.refFreeListTail == (IPSEC_SA_REF_FREELIST_NUM_ENTRIES - 1)) {
-+ ipsec_sadb.refFreeListHead = 0;
-+ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_recycle: "
-+ "SArefFreeList refilled.\n");
-+ return 0;
-+ }
-+ }
-+ }
-+ }
-+
-+ if(ipsec_sadb.refFreeListTail == -1) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_recycle: "
-+ "out of room in the SArefTable.\n");
-+
-+ return(-ENOSPC);
-+ }
-+
-+ ipsec_sadb.refFreeListHead = 0;
-+ ipsec_sadb.refFreeListCont = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListTail] + 1;
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_recycle: "
-+ "SArefFreeList partly refilled to %d of %d.\n",
-+ ipsec_sadb.refFreeListTail,
-+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
-+ return 0;
-+}
-+
-+int
-+ipsec_SArefSubTable_alloc(unsigned table)
-+{
-+ unsigned entry;
-+ struct IPsecSArefSubTable* SArefsub;
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SArefSubTable_alloc: "
-+ "allocating %lu bytes for table %u of %u.\n",
-+ (unsigned long) (IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *)),
-+ table,
-+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
-+
-+ /* allocate another sub-table */
-+ SArefsub = vmalloc(IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES * sizeof(struct ipsec_sa *));
-+ if(SArefsub == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SArefSubTable_alloc: "
-+ "error allocating memory for table %u of %u!\n",
-+ table,
-+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES);
-+ return -ENOMEM;
-+ }
-+
-+ /* add this sub-table to the main table */
-+ ipsec_sadb.refTable[table] = SArefsub;
-+
-+ /* initialise each element to NULL */
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SArefSubTable_alloc: "
-+ "initialising %u elements (2 ^ %u) of table %u.\n",
-+ IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES,
-+ IPSEC_SA_REF_SUBTABLE_IDX_WIDTH,
-+ table);
-+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
-+ SArefsub->entry[entry] = NULL;
-+ }
-+
-+ return 0;
-+}
-+#endif /* IPSEC_SA_REF_CODE */
-+
-+int
-+ipsec_saref_freelist_init(void)
-+{
-+ int i;
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_saref_freelist_init: "
-+ "initialising %u elements of FreeList.\n",
-+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
-+
-+ for(i = 0; i < IPSEC_SA_REF_FREELIST_NUM_ENTRIES; i++) {
-+ ipsec_sadb.refFreeList[i] = IPSEC_SAREF_NULL;
-+ }
-+ ipsec_sadb.refFreeListHead = -1;
-+ ipsec_sadb.refFreeListCont = 0;
-+ ipsec_sadb.refFreeListTail = -1;
-+
-+ return 0;
-+}
-+
-+int
-+ipsec_sadb_init(void)
-+{
-+ int error = 0;
-+ unsigned i;
-+
-+ for(i = 0; i < SADB_HASHMOD; i++) {
-+ ipsec_sadb_hash[i] = NULL;
-+ }
-+ /* parts above are for the old style SADB hash table */
-+
-+
-+#if IPSEC_SA_REF_CODE
-+ /* initialise SA reference table */
-+
-+ /* initialise the main table */
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_init: "
-+ "initialising main table of size %u (2 ^ %u).\n",
-+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES,
-+ IPSEC_SA_REF_MAINTABLE_IDX_WIDTH);
-+ {
-+ unsigned table;
-+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
-+ ipsec_sadb.refTable[table] = NULL;
-+ }
-+ }
-+
-+ /* allocate the first sub-table */
-+ error = ipsec_SArefSubTable_alloc(0);
-+ if(error) {
-+ return error;
-+ }
-+
-+ error = ipsec_saref_freelist_init();
-+#endif /* IPSEC_SA_REF_CODE */
-+ return error;
-+}
-+
-+#if IPSEC_SA_REF_CODE
-+IPsecSAref_t
-+ipsec_SAref_alloc(int*error) /* pass in error var by pointer */
-+{
-+ IPsecSAref_t SAref;
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_alloc: "
-+ "SAref requested... head=%d, cont=%d, tail=%d, listsize=%d.\n",
-+ ipsec_sadb.refFreeListHead,
-+ ipsec_sadb.refFreeListCont,
-+ ipsec_sadb.refFreeListTail,
-+ IPSEC_SA_REF_FREELIST_NUM_ENTRIES);
-+
-+ if(ipsec_sadb.refFreeListHead == -1) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_alloc: "
-+ "FreeList empty, recycling...\n");
-+ *error = ipsec_SAref_recycle();
-+ if(*error) {
-+ return IPSEC_SAREF_NULL;
-+ }
-+ }
-+
-+ SAref = ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead];
-+ if(SAref == IPSEC_SAREF_NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_alloc: "
-+ "unexpected error, refFreeListHead = %d points to invalid entry.\n",
-+ ipsec_sadb.refFreeListHead);
-+ *error = -ESPIPE;
-+ return IPSEC_SAREF_NULL;
-+ }
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_alloc: "
-+ "allocating SAref=%d, table=%u, entry=%u of %u.\n",
-+ SAref,
-+ IPsecSAref2table(SAref),
-+ IPsecSAref2entry(SAref),
-+ IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES * IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES);
-+
-+ ipsec_sadb.refFreeList[ipsec_sadb.refFreeListHead] = IPSEC_SAREF_NULL;
-+ ipsec_sadb.refFreeListHead++;
-+ if(ipsec_sadb.refFreeListHead > ipsec_sadb.refFreeListTail) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_SAref_alloc: "
-+ "last FreeList entry allocated, resetting list head to empty.\n");
-+ ipsec_sadb.refFreeListHead = -1;
-+ }
-+
-+ return SAref;
-+}
-+#endif /* IPSEC_SA_REF_CODE */
-+
-+int
-+ipsec_sa_print(struct ipsec_sa *ips)
-+{
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+ printk(KERN_INFO "klips_debug: SA:");
-+ if(ips == NULL) {
-+ printk("NULL\n");
-+ return -ENOENT;
-+ }
-+ printk(" ref=%d", ips->ips_ref);
-+ printk(" refcount=%d", atomic_read(&ips->ips_refcount));
-+ if(ips->ips_hnext != NULL) {
-+ printk(" hnext=0p%p", ips->ips_hnext);
-+ }
-+ if(ips->ips_inext != NULL) {
-+ printk(" inext=0p%p", ips->ips_inext);
-+ }
-+ if(ips->ips_onext != NULL) {
-+ printk(" onext=0p%p", ips->ips_onext);
-+ }
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ printk(" said=%s", sa_len ? sa : " (error)");
-+ if(ips->ips_seq) {
-+ printk(" seq=%u", ips->ips_seq);
-+ }
-+ if(ips->ips_pid) {
-+ printk(" pid=%u", ips->ips_pid);
-+ }
-+ if(ips->ips_authalg) {
-+ printk(" authalg=%u", ips->ips_authalg);
-+ }
-+ if(ips->ips_encalg) {
-+ printk(" encalg=%u", ips->ips_encalg);
-+ }
-+ printk(" XFORM=%s%s%s", IPS_XFORM_NAME(ips));
-+ if(ips->ips_replaywin) {
-+ printk(" ooowin=%u", ips->ips_replaywin);
-+ }
-+ if(ips->ips_flags) {
-+ printk(" flags=%u", ips->ips_flags);
-+ }
-+ if(ips->ips_addr_s) {
-+ char buf[SUBNETTOA_BUF];
-+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
-+ 0, buf, sizeof(buf));
-+ printk(" src=%s", buf);
-+ }
-+ if(ips->ips_addr_d) {
-+ char buf[SUBNETTOA_BUF];
-+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_s))->sin_addr,
-+ 0, buf, sizeof(buf));
-+ printk(" dst=%s", buf);
-+ }
-+ if(ips->ips_addr_p) {
-+ char buf[SUBNETTOA_BUF];
-+ addrtoa(((struct sockaddr_in*)(ips->ips_addr_p))->sin_addr,
-+ 0, buf, sizeof(buf));
-+ printk(" proxy=%s", buf);
-+ }
-+ if(ips->ips_key_bits_a) {
-+ printk(" key_bits_a=%u", ips->ips_key_bits_a);
-+ }
-+ if(ips->ips_key_bits_e) {
-+ printk(" key_bits_e=%u", ips->ips_key_bits_e);
-+ }
-+
-+ printk("\n");
-+ return 0;
-+}
-+
-+struct ipsec_sa*
-+ipsec_sa_alloc(int*error) /* pass in error var by pointer */
-+{
-+ struct ipsec_sa* ips;
-+
-+ if((ips = kmalloc(sizeof(*ips), GFP_ATOMIC) ) == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_alloc: "
-+ "memory allocation error\n");
-+ *error = -ENOMEM;
-+ return NULL;
-+ }
-+ memset((caddr_t)ips, 0, sizeof(*ips));
-+#if IPSEC_SA_REF_CODE
-+ ips->ips_ref = ipsec_SAref_alloc(error); /* pass in error return by pointer */
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_alloc: "
-+ "allocated %lu bytes for ipsec_sa struct=0p%p ref=%d.\n",
-+ (unsigned long) sizeof(*ips),
-+ ips,
-+ ips->ips_ref);
-+ if(ips->ips_ref == IPSEC_SAREF_NULL) {
-+ kfree(ips);
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_alloc: "
-+ "SAref allocation error\n");
-+ return NULL;
-+ }
-+
-+ atomic_inc(&ips->ips_refcount);
-+ IPsecSAref2SA(ips->ips_ref) = ips;
-+#endif /* IPSEC_SA_REF_CODE */
-+
-+ *error = 0;
-+ return(ips);
-+}
-+
-+int
-+ipsec_sa_free(struct ipsec_sa* ips)
-+{
-+ return ipsec_sa_wipe(ips);
-+}
-+
-+struct ipsec_sa *
-+ipsec_sa_getbyid(ip_said *said)
-+{
-+ int hashval;
-+ struct ipsec_sa *ips;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+ if(said == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_error:ipsec_sa_getbyid: "
-+ "null pointer passed in!\n");
-+ return NULL;
-+ }
-+
-+ sa_len = satot(said, 0, sa, sizeof(sa));
-+
-+ hashval = IPS_HASH(said);
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_getbyid: "
-+ "linked entry in ipsec_sa table for hash=%d of SA:%s requested.\n",
-+ hashval,
-+ sa_len ? sa : " (error)");
-+
-+ if((ips = ipsec_sadb_hash[hashval]) == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_getbyid: "
-+ "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
-+ hashval,
-+ sa_len ? sa : " (error)");
-+ return NULL;
-+ }
-+
-+ for (; ips; ips = ips->ips_hnext) {
-+ if ((ips->ips_said.spi == said->spi) &&
-+ (ips->ips_said.dst.u.v4.sin_addr.s_addr == said->dst.u.v4.sin_addr.s_addr) &&
-+ (ips->ips_said.proto == said->proto)) {
-+ atomic_inc(&ips->ips_refcount);
-+ return ips;
-+ }
-+ }
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_getbyid: "
-+ "no entry in linked list for hash=%d of SA:%s.\n",
-+ hashval,
-+ sa_len ? sa : " (error)");
-+ return NULL;
-+}
-+
-+int
-+ipsec_sa_put(struct ipsec_sa *ips)
-+{
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+ if(ips == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_error:ipsec_sa_put: "
-+ "null pointer passed in!\n");
-+ return -1;
-+ }
-+
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_put: "
-+ "ipsec_sa SA:%s, ref:%d reference count decremented.\n",
-+ sa_len ? sa : " (error)",
-+ ips->ips_ref);
-+
-+ atomic_dec(&ips->ips_refcount);
-+
-+ return 0;
-+}
-+
-+/*
-+ The ipsec_sa table better *NOT* be locked before it is handed in, or SMP locks will happen
-+*/
-+int
-+ipsec_sa_add(struct ipsec_sa *ips)
-+{
-+ int error = 0;
-+ unsigned int hashval;
-+
-+ if(ips == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_error:ipsec_sa_add: "
-+ "null pointer passed in!\n");
-+ return -ENODATA;
-+ }
-+ hashval = IPS_HASH(&ips->ips_said);
-+
-+ atomic_inc(&ips->ips_refcount);
-+ spin_lock_bh(&tdb_lock);
-+
-+ ips->ips_hnext = ipsec_sadb_hash[hashval];
-+ ipsec_sadb_hash[hashval] = ips;
-+
-+ spin_unlock_bh(&tdb_lock);
-+
-+ return error;
-+}
-+
-+/*
-+ The ipsec_sa table better be locked before it is handed in, or races might happen
-+*/
-+int
-+ipsec_sa_del(struct ipsec_sa *ips)
-+{
-+ unsigned int hashval;
-+ struct ipsec_sa *ipstp;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+ if(ips == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_error:ipsec_sa_del: "
-+ "null pointer passed in!\n");
-+ return -ENODATA;
-+ }
-+
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ if(ips->ips_inext || ips->ips_onext) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_error:ipsec_sa_del: "
-+ "SA:%s still linked!\n",
-+ sa_len ? sa : " (error)");
-+ return -EMLINK;
-+ }
-+
-+ hashval = IPS_HASH(&ips->ips_said);
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_del: "
-+ "deleting SA:%s, hashval=%d.\n",
-+ sa_len ? sa : " (error)",
-+ hashval);
-+ if(ipsec_sadb_hash[hashval] == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_del: "
-+ "no entries in ipsec_sa table for hash=%d of SA:%s.\n",
-+ hashval,
-+ sa_len ? sa : " (error)");
-+ return -ENOENT;
-+ }
-+
-+ if (ips == ipsec_sadb_hash[hashval]) {
-+ ipsec_sadb_hash[hashval] = ipsec_sadb_hash[hashval]->ips_hnext;
-+ ips->ips_hnext = NULL;
-+ atomic_dec(&ips->ips_refcount);
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_del: "
-+ "successfully deleted first ipsec_sa in chain.\n");
-+ return 0;
-+ } else {
-+ for (ipstp = ipsec_sadb_hash[hashval];
-+ ipstp;
-+ ipstp = ipstp->ips_hnext) {
-+ if (ipstp->ips_hnext == ips) {
-+ ipstp->ips_hnext = ips->ips_hnext;
-+ ips->ips_hnext = NULL;
-+ atomic_dec(&ips->ips_refcount);
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_del: "
-+ "successfully deleted link in ipsec_sa chain.\n");
-+ return 0;
-+ }
-+ }
-+ }
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_del: "
-+ "no entries in linked list for hash=%d of SA:%s.\n",
-+ hashval,
-+ sa_len ? sa : " (error)");
-+ return -ENOENT;
-+}
-+
-+/*
-+ The ipsec_sa table better be locked before it is handed in, or races
-+ might happen
-+*/
-+int
-+ipsec_sa_delchain(struct ipsec_sa *ips)
-+{
-+ struct ipsec_sa *ipsdel;
-+ int error = 0;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+ if(ips == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_error:ipsec_sa_delchain: "
-+ "null pointer passed in!\n");
-+ return -ENODATA;
-+ }
-+
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_delchain: "
-+ "passed SA:%s\n",
-+ sa_len ? sa : " (error)");
-+ while(ips->ips_onext != NULL) {
-+ ips = ips->ips_onext;
-+ }
-+
-+ while(ips) {
-+ /* XXX send a pfkey message up to advise of deleted ipsec_sa */
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_delchain: "
-+ "unlinking and delting SA:%s",
-+ sa_len ? sa : " (error)");
-+ ipsdel = ips;
-+ ips = ips->ips_inext;
-+ if(ips != NULL) {
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ ", inext=%s",
-+ sa_len ? sa : " (error)");
-+ atomic_dec(&ipsdel->ips_refcount);
-+ ipsdel->ips_inext = NULL;
-+ atomic_dec(&ips->ips_refcount);
-+ ips->ips_onext = NULL;
-+ }
-+ KLIPS_PRINT(debug_xform,
-+ ".\n");
-+ if((error = ipsec_sa_del(ipsdel))) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_delchain: "
-+ "ipsec_sa_del returned error %d.\n", -error);
-+ return error;
-+ }
-+ if((error = ipsec_sa_wipe(ipsdel))) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_delchain: "
-+ "ipsec_sa_wipe returned error %d.\n", -error);
-+ return error;
-+ }
-+ }
-+ return error;
-+}
-+
-+int
-+ipsec_sadb_cleanup(__u8 proto)
-+{
-+ unsigned i;
-+ int error = 0;
-+ struct ipsec_sa *ips, **ipsprev, *ipsdel;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_cleanup: "
-+ "cleaning up proto=%d.\n",
-+ proto);
-+
-+ spin_lock_bh(&tdb_lock);
-+
-+ for (i = 0; i < SADB_HASHMOD; i++) {
-+ ipsprev = &(ipsec_sadb_hash[i]);
-+ ips = ipsec_sadb_hash[i];
-+ if(ips != NULL) {
-+ atomic_inc(&ips->ips_refcount);
-+ }
-+ for(; ips != NULL;) {
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_cleanup: "
-+ "checking SA:%s, hash=%d, ref=%d",
-+ sa_len ? sa : " (error)",
-+ i,
-+ ips->ips_ref);
-+ ipsdel = ips;
-+ ips = ipsdel->ips_hnext;
-+ if(ips != NULL) {
-+ atomic_inc(&ips->ips_refcount);
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ ", hnext=%s",
-+ sa_len ? sa : " (error)");
-+ }
-+ if(*ipsprev != NULL) {
-+ sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ ", *ipsprev=%s",
-+ sa_len ? sa : " (error)");
-+ if((*ipsprev)->ips_hnext) {
-+ sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ ", *ipsprev->ips_hnext=%s",
-+ sa_len ? sa : " (error)");
-+ }
-+ }
-+ KLIPS_PRINT(debug_xform,
-+ ".\n");
-+ if(proto == 0 || (proto == ipsdel->ips_said.proto)) {
-+ sa_len = satot(&ipsdel->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_cleanup: "
-+ "deleting SA chain:%s.\n",
-+ sa_len ? sa : " (error)");
-+ if((error = ipsec_sa_delchain(ipsdel))) {
-+ SENDERR(-error);
-+ }
-+ ipsprev = &(ipsec_sadb_hash[i]);
-+ ips = ipsec_sadb_hash[i];
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_cleanup: "
-+ "deleted SA chain:%s",
-+ sa_len ? sa : " (error)");
-+ if(ips != NULL) {
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ ", ipsec_sadb_hash[%d]=%s",
-+ i,
-+ sa_len ? sa : " (error)");
-+ }
-+ if(*ipsprev != NULL) {
-+ sa_len = satot(&(*ipsprev)->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ ", *ipsprev=%s",
-+ sa_len ? sa : " (error)");
-+ if((*ipsprev)->ips_hnext != NULL) {
-+ sa_len = satot(&(*ipsprev)->ips_hnext->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ ", *ipsprev->ips_hnext=%s",
-+ sa_len ? sa : " (error)");
-+ }
-+ }
-+ KLIPS_PRINT(debug_xform,
-+ ".\n");
-+ } else {
-+ ipsprev = &ipsdel;
-+ }
-+ if(ipsdel != NULL) {
-+ ipsec_sa_put(ipsdel);
-+ }
-+ }
-+ }
-+ errlab:
-+
-+ spin_unlock_bh(&tdb_lock);
-+
-+
-+#if IPSEC_SA_REF_CODE
-+ /* clean up SA reference table */
-+
-+ /* go through the ref table and clean out all the SAs */
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_cleanup: "
-+ "removing SAref entries and tables.");
-+ {
-+ unsigned table, entry;
-+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_cleanup: "
-+ "cleaning SAref table=%u.\n",
-+ table);
-+ if(ipsec_sadb.refTable[table] == NULL) {
-+ printk("\n");
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_cleanup: "
-+ "cleaned %u used refTables.\n",
-+ table);
-+ break;
-+ }
-+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
-+ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
-+ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
-+ ipsec_sadb.refTable[table]->entry[entry] = NULL;
-+ }
-+ }
-+ }
-+ }
-+#endif /* IPSEC_SA_REF_CODE */
-+
-+ return(error);
-+}
-+
-+int
-+ipsec_sadb_free(void)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_free: "
-+ "freeing SArefTable memory.\n");
-+
-+ /* clean up SA reference table */
-+
-+ /* go through the ref table and clean out all the SAs if any are
-+ left and free table memory */
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_free: "
-+ "removing SAref entries and tables.\n");
-+ {
-+ unsigned table, entry;
-+ for(table = 0; table < IPSEC_SA_REF_MAINTABLE_NUM_ENTRIES; table++) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_free: "
-+ "removing SAref table=%u.\n",
-+ table);
-+ if(ipsec_sadb.refTable[table] == NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sadb_free: "
-+ "removed %u used refTables.\n",
-+ table);
-+ break;
-+ }
-+ for(entry = 0; entry < IPSEC_SA_REF_SUBTABLE_NUM_ENTRIES; entry++) {
-+ if(ipsec_sadb.refTable[table]->entry[entry] != NULL) {
-+ ipsec_sa_delchain(ipsec_sadb.refTable[table]->entry[entry]);
-+ ipsec_sadb.refTable[table]->entry[entry] = NULL;
-+ }
-+ }
-+ vfree(ipsec_sadb.refTable[table]);
-+ ipsec_sadb.refTable[table] = NULL;
-+ }
-+ }
-+
-+ return(error);
-+}
-+
-+int
-+ipsec_sa_wipe(struct ipsec_sa *ips)
-+{
-+ if(ips == NULL) {
-+ return -ENODATA;
-+ }
-+
-+ /* if(atomic_dec_and_test(ips)) {
-+ }; */
-+
-+#if IPSEC_SA_REF_CODE
-+ /* remove me from the SArefTable */
-+ {
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+ sa_len = satot(&ips->ips_said, 0, sa, sizeof(sa));
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_wipe: "
-+ "removing SA=%s(0p%p), SAref=%d, table=%d(0p%p), entry=%d from the refTable.\n",
-+ sa_len ? sa : " (error)",
-+ ips,
-+ ips->ips_ref,
-+ IPsecSAref2table(IPsecSA2SAref(ips)),
-+ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))],
-+ IPsecSAref2entry(IPsecSA2SAref(ips)));
-+ }
-+ if(ips->ips_ref == IPSEC_SAREF_NULL) {
-+ KLIPS_PRINT(debug_xform,
-+ "klips_debug:ipsec_sa_wipe: "
-+ "why does this SA not have a valid SAref?.\n");
-+ }
-+ ipsec_sadb.refTable[IPsecSAref2table(IPsecSA2SAref(ips))]->entry[IPsecSAref2entry(IPsecSA2SAref(ips))] = NULL;
-+ ips->ips_ref = IPSEC_SAREF_NULL;
-+ ipsec_sa_put(ips);
-+#endif /* IPSEC_SA_REF_CODE */
-+
-+ /* paranoid clean up */
-+ if(ips->ips_addr_s != NULL) {
-+ memset((caddr_t)(ips->ips_addr_s), 0, ips->ips_addr_s_size);
-+ kfree(ips->ips_addr_s);
-+ }
-+ ips->ips_addr_s = NULL;
-+
-+ if(ips->ips_addr_d != NULL) {
-+ memset((caddr_t)(ips->ips_addr_d), 0, ips->ips_addr_d_size);
-+ kfree(ips->ips_addr_d);
-+ }
-+ ips->ips_addr_d = NULL;
-+
-+ if(ips->ips_addr_p != NULL) {
-+ memset((caddr_t)(ips->ips_addr_p), 0, ips->ips_addr_p_size);
-+ kfree(ips->ips_addr_p);
-+ }
-+ ips->ips_addr_p = NULL;
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if(ips->ips_natt_oa) {
-+ memset((caddr_t)(ips->ips_natt_oa), 0, ips->ips_natt_oa_size);
-+ kfree(ips->ips_natt_oa);
-+ }
-+ ips->ips_natt_oa = NULL;
-+#endif
-+
-+ if(ips->ips_key_a != NULL) {
-+ memset((caddr_t)(ips->ips_key_a), 0, ips->ips_key_a_size);
-+ kfree(ips->ips_key_a);
-+ }
-+ ips->ips_key_a = NULL;
-+
-+ if(ips->ips_key_e != NULL) {
-+#ifdef CONFIG_IPSEC_ALG
-+ if (ips->ips_alg_enc&&ips->ips_alg_enc->ixt_e_destroy_key) {
-+ ips->ips_alg_enc->ixt_e_destroy_key(ips->ips_alg_enc,
-+ ips->ips_key_e);
-+ } else {
-+#endif /* CONFIG_IPSEC_ALG */
-+ memset((caddr_t)(ips->ips_key_e), 0, ips->ips_key_e_size);
-+ kfree(ips->ips_key_e);
-+#ifdef CONFIG_IPSEC_ALG
-+ }
-+#endif /* CONFIG_IPSEC_ALG */
-+ }
-+ ips->ips_key_e = NULL;
-+
-+ if(ips->ips_iv != NULL) {
-+ memset((caddr_t)(ips->ips_iv), 0, ips->ips_iv_size);
-+ kfree(ips->ips_iv);
-+ }
-+ ips->ips_iv = NULL;
-+
-+ if(ips->ips_ident_s.data != NULL) {
-+ memset((caddr_t)(ips->ips_ident_s.data),
-+ 0,
-+ ips->ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
-+ kfree(ips->ips_ident_s.data);
-+ }
-+ ips->ips_ident_s.data = NULL;
-+
-+ if(ips->ips_ident_d.data != NULL) {
-+ memset((caddr_t)(ips->ips_ident_d.data),
-+ 0,
-+ ips->ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident));
-+ kfree(ips->ips_ident_d.data);
-+ }
-+ ips->ips_ident_d.data = NULL;
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if (ips->ips_alg_enc||ips->ips_alg_auth) {
-+ ipsec_alg_sa_wipe(ips);
-+ }
-+#endif /* CONFIG_IPSEC_ALG */
-+
-+ memset((caddr_t)ips, 0, sizeof(*ips));
-+ kfree(ips);
-+ ips = NULL;
-+
-+ return 0;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.23 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.22.2.1 2003/12/22 15:25:52 jjo
-+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.22 2003/12/10 01:14:27 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.21 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.20.4.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.20 2003/02/06 01:50:34 rgb
-+ * Fixed initialisation bug for first sadb hash bucket that would only manifest itself on platforms where NULL != 0.
-+ *
-+ * Revision 1.19 2003/01/30 02:32:22 rgb
-+ *
-+ * Rename SAref table macro names for clarity.
-+ * Transmit error code through to caller from callee for better diagnosis of problems.
-+ * Convert IPsecSAref_t from signed to unsigned to fix apparent SAref exhaustion bug.
-+ *
-+ * Revision 1.18 2002/10/12 23:11:53 dhr
-+ *
-+ * [KenB + DHR] more 64-bit cleanup
-+ *
-+ * Revision 1.17 2002/10/07 18:31:43 rgb
-+ * Move field width sanity checks to ipsec_sa.c
-+ *
-+ * Revision 1.16 2002/09/20 15:41:02 rgb
-+ * Re-wrote most of the SAref code to eliminate Entry pointers.
-+ * Added SAref code compiler directive switch.
-+ * Added a saref test function for testing macros.
-+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
-+ * Split ipsec_sadb_cleanup from new funciton ipsec_sadb_free to avoid problem
-+ * of freeing newly created structures when clearing the reftable upon startup
-+ * to start from a known state.
-+ * Place all ipsec sadb globals into one struct.
-+ * Rework saref freelist.
-+ * Added memory allocation debugging.
-+ *
-+ * Revision 1.15 2002/09/20 05:01:44 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.14 2002/08/13 19:01:25 mcr
-+ * patches from kenb to permit compilation of FreeSWAN on ia64.
-+ * des library patched to use proper DES_LONG type for ia64.
-+ *
-+ * Revision 1.13 2002/07/29 03:06:20 mcr
-+ * get rid of variable not used warnings.
-+ *
-+ * Revision 1.12 2002/07/26 08:48:31 rgb
-+ * Added SA ref table code.
-+ *
-+ * Revision 1.11 2002/06/04 16:48:49 rgb
-+ * Tidied up pointer code for processor independance.
-+ *
-+ * Revision 1.10 2002/05/23 07:16:17 rgb
-+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
-+ * Pointer clean-up.
-+ * Added refcount code.
-+ * Convert "usecount" to "refcount" to remove ambiguity.
-+ *
-+ * Revision 1.9 2002/05/14 02:34:49 rgb
-+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
-+ * with "put" usage in the kernel.
-+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
-+ * ipsec_sa or ipsec_sa.
-+ * Added some preliminary refcount code.
-+ *
-+ * Revision 1.8 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.7 2002/04/24 07:36:30 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_sa.c,v
-+ *
-+ * Revision 1.6 2002/04/20 00:12:25 rgb
-+ * Added esp IV CBC attack fix, disabled.
-+ *
-+ * Revision 1.5 2002/01/29 17:17:56 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.4 2002/01/29 04:00:52 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.3 2002/01/29 02:13:18 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.2 2001/11/26 09:16:15 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.1.2.2 2001/10/22 21:05:41 mcr
-+ * removed phony prototype for des_set_key.
-+ *
-+ * Revision 1.1.2.1 2001/09/25 02:24:57 mcr
-+ * struct tdb -> struct ipsec_sa.
-+ * sa(tdb) manipulation functions renamed and moved to ipsec_sa.c
-+ * ipsec_xform.c removed. header file still contains useful things.
-+ *
-+ *
-+ *
-+ * CLONED from ipsec_xform.c:
-+ * Revision 1.53 2001/09/08 21:13:34 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.52 2001/06/14 19:35:11 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.51 2001/05/30 08:14:03 rgb
-+ * Removed vestiges of esp-null transforms.
-+ *
-+ * Revision 1.50 2001/05/03 19:43:18 rgb
-+ * Initialise error return variable.
-+ * Update SENDERR macro.
-+ * Fix sign of error return code for ipsec_tdbcleanup().
-+ * Use more appropriate return code for ipsec_tdbwipe().
-+ *
-+ * Revision 1.49 2001/04/19 18:56:17 rgb
-+ * Fixed tdb table locking comments.
-+ *
-+ * Revision 1.48 2001/02/27 22:24:55 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.47 2000/11/06 04:32:08 rgb
-+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
-+ *
-+ * Revision 1.46 2000/09/20 16:21:57 rgb
-+ * Cleaned up ident string alloc/free.
-+ *
-+ * Revision 1.45 2000/09/08 19:16:51 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
-+ *
-+ * Revision 1.44 2000/08/30 05:29:04 rgb
-+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
-+ *
-+ * Revision 1.43 2000/08/18 21:30:41 rgb
-+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
-+ *
-+ * Revision 1.42 2000/08/01 14:51:51 rgb
-+ * Removed _all_ remaining traces of DES.
-+ *
-+ * Revision 1.41 2000/07/28 14:58:31 rgb
-+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
-+ *
-+ * Revision 1.40 2000/06/28 05:50:11 rgb
-+ * Actually set iv_bits.
-+ *
-+ * Revision 1.39 2000/05/10 23:11:09 rgb
-+ * Added netlink debugging output.
-+ * Added a cast to quiet down the ntohl bug.
-+ *
-+ * Revision 1.38 2000/05/10 19:18:42 rgb
-+ * Cast output of ntohl so that the broken prototype doesn't make our
-+ * compile noisy.
-+ *
-+ * Revision 1.37 2000/03/16 14:04:59 rgb
-+ * Hardwired CONFIG_IPSEC_PFKEYv2 on.
-+ *
-+ * Revision 1.36 2000/01/26 10:11:28 rgb
-+ * Fixed spacing in error text causing run-in words.
-+ *
-+ * Revision 1.35 2000/01/21 06:17:16 rgb
-+ * Tidied up compiler directive indentation for readability.
-+ * Added ictx,octx vars for simplification.(kravietz)
-+ * Added macros for HMAC padding magic numbers.(kravietz)
-+ * Fixed missing key length reporting bug.
-+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
-+ *
-+ * Revision 1.34 1999/12/08 00:04:19 rgb
-+ * Fixed SA direction overwriting bug for netlink users.
-+ *
-+ * Revision 1.33 1999/12/01 22:16:44 rgb
-+ * Minor formatting changes in ESP MD5 initialisation.
-+ *
-+ * Revision 1.32 1999/11/25 09:06:36 rgb
-+ * Fixed error return messages, should be returning negative numbers.
-+ * Implemented SENDERR macro for propagating error codes.
-+ * Added debug message and separate error code for algorithms not compiled
-+ * in.
-+ *
-+ * Revision 1.31 1999/11/23 23:06:26 rgb
-+ * Sort out pfkey and freeswan headers, putting them in a library path.
-+ *
-+ * Revision 1.30 1999/11/18 04:09:20 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ *
-+ * Revision 1.29 1999/11/17 15:53:40 rgb
-+ * Changed all occurrences of #include "../../../lib/freeswan.h"
-+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
-+ * klips/net/ipsec/Makefile.
-+ *
-+ * Revision 1.28 1999/10/18 20:04:01 rgb
-+ * Clean-out unused cruft.
-+ *
-+ * Revision 1.27 1999/10/03 19:01:03 rgb
-+ * Spinlock support for 2.3.xx and 2.0.xx kernels.
-+ *
-+ * Revision 1.26 1999/10/01 16:22:24 rgb
-+ * Switch from assignment init. to functional init. of spinlocks.
-+ *
-+ * Revision 1.25 1999/10/01 15:44:54 rgb
-+ * Move spinlock header include to 2.1> scope.
-+ *
-+ * Revision 1.24 1999/10/01 00:03:46 rgb
-+ * Added tdb structure locking.
-+ * Minor formatting changes.
-+ * Add function to initialize tdb hash table.
-+ *
-+ * Revision 1.23 1999/05/25 22:42:12 rgb
-+ * Add deltdbchain() debugging.
-+ *
-+ * Revision 1.22 1999/05/25 21:24:31 rgb
-+ * Add debugging statements to deltdbchain().
-+ *
-+ * Revision 1.21 1999/05/25 03:51:48 rgb
-+ * Refix error return code.
-+ *
-+ * Revision 1.20 1999/05/25 03:34:07 rgb
-+ * Fix error return for flush.
-+ *
-+ * Revision 1.19 1999/05/09 03:25:37 rgb
-+ * Fix bug introduced by 2.2 quick-and-dirty patch.
-+ *
-+ * Revision 1.18 1999/05/05 22:02:32 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.17 1999/04/29 15:20:16 rgb
-+ * Change gettdb parameter to a pointer to reduce stack loading and
-+ * facilitate parameter sanity checking.
-+ * Add sanity checking for null pointer arguments.
-+ * Add debugging instrumentation.
-+ * Add function deltdbchain() which will take care of unlinking,
-+ * zeroing and deleting a chain of tdbs.
-+ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
-+ * tdbwipe now actually zeroes the tdb as well as any of its pointed
-+ * structures.
-+ *
-+ * Revision 1.16 1999/04/16 15:36:29 rgb
-+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
-+ *
-+ * Revision 1.15 1999/04/11 00:29:01 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.14 1999/04/06 04:54:28 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.13 1999/02/19 18:23:01 rgb
-+ * Nix debug off compile warning.
-+ *
-+ * Revision 1.12 1999/02/17 16:52:16 rgb
-+ * Consolidate satoa()s for space and speed efficiency.
-+ * Convert DEBUG_IPSEC to KLIPS_PRINT
-+ * Clean out unused cruft.
-+ * Ditch NET_IPIP dependancy.
-+ * Loop for 3des key setting.
-+ *
-+ * Revision 1.11 1999/01/26 02:09:05 rgb
-+ * Remove ah/esp/IPIP switching on include files.
-+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
-+ * Removed dead code.
-+ * Clean up debug code when switched off.
-+ * Remove references to INET_GET_PROTOCOL.
-+ * Added code exclusion macros to reduce code from unused algorithms.
-+ *
-+ * Revision 1.10 1999/01/22 06:28:55 rgb
-+ * Cruft clean-out.
-+ * Put random IV generation in kernel.
-+ * Added algorithm switch code.
-+ * Enhanced debugging.
-+ * 64-bit clean-up.
-+ *
-+ * Revision 1.9 1998/11/30 13:22:55 rgb
-+ * Rationalised all the klips kernel file headers. They are much shorter
-+ * now and won't conflict under RH5.2.
-+ *
-+ * Revision 1.8 1998/11/25 04:59:06 rgb
-+ * Add conditionals for no IPIP tunnel code.
-+ * Delete commented out code.
-+ *
-+ * Revision 1.7 1998/10/31 06:50:41 rgb
-+ * Convert xform ASCII names to no spaces.
-+ * Fixed up comments in #endif directives.
-+ *
-+ * Revision 1.6 1998/10/19 14:44:28 rgb
-+ * Added inclusion of freeswan.h.
-+ * sa_id structure implemented and used: now includes protocol.
-+ *
-+ * Revision 1.5 1998/10/09 04:32:19 rgb
-+ * Added 'klips_debug' prefix to all klips printk debug statements.
-+ *
-+ * Revision 1.4 1998/08/12 00:11:31 rgb
-+ * Added new xform functions to the xform table.
-+ * Fixed minor debug output spelling error.
-+ *
-+ * Revision 1.3 1998/07/09 17:45:31 rgb
-+ * Clarify algorithm not available message.
-+ *
-+ * Revision 1.2 1998/06/23 03:00:51 rgb
-+ * Check for presence of IPIP protocol if it is setup one way (we don't
-+ * know what has been set up the other way and can only assume it will be
-+ * symmetrical with the exception of keys).
-+ *
-+ * Revision 1.1 1998/06/18 21:27:51 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.3 1998/06/11 05:54:59 rgb
-+ * Added transform version string pointer to xformsw initialisations.
-+ *
-+ * Revision 1.2 1998/04/21 21:28:57 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:13 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.5 1997/06/03 04:24:48 ji
-+ * Added ESP-3DES-MD5-96
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * Added new transforms.
-+ *
-+ * Revision 0.3 1996/11/20 14:39:04 ji
-+ * Minor cleanups.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_sha1.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,219 @@
-+/*
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * The rest of the code is derived from sha1.c by Steve Reid, which is
-+ * public domain.
-+ * Minor cosmetic changes to accomodate it in the Linux kernel by ji.
-+ */
-+
-+#include <asm/byteorder.h>
-+#include <linux/string.h>
-+
-+#include "openswan/ipsec_sha1.h"
-+
-+#if defined(rol)
-+#undef rol
-+#endif
-+
-+#define SHA1HANDSOFF
-+
-+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-+
-+/* blk0() and blk() perform the initial expand. */
-+/* I got the idea of expanding during the round function from SSLeay */
-+#ifdef __LITTLE_ENDIAN
-+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
-+ |(rol(block->l[i],8)&0x00FF00FF))
-+#else
-+#define blk0(i) block->l[i]
-+#endif
-+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
-+ ^block->l[(i+2)&15]^block->l[i&15],1))
-+
-+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
-+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
-+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
-+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
-+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
-+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
-+
-+
-+/* Hash a single 512-bit block. This is the core of the algorithm. */
-+
-+void SHA1Transform(__u32 state[5], __u8 buffer[64])
-+{
-+__u32 a, b, c, d, e;
-+typedef union {
-+ unsigned char c[64];
-+ __u32 l[16];
-+} CHAR64LONG16;
-+CHAR64LONG16* block;
-+#ifdef SHA1HANDSOFF
-+static unsigned char workspace[64];
-+ block = (CHAR64LONG16*)workspace;
-+ memcpy(block, buffer, 64);
-+#else
-+ block = (CHAR64LONG16*)buffer;
-+#endif
-+ /* Copy context->state[] to working vars */
-+ a = state[0];
-+ b = state[1];
-+ c = state[2];
-+ d = state[3];
-+ e = state[4];
-+ /* 4 rounds of 20 operations each. Loop unrolled. */
-+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
-+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
-+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
-+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
-+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
-+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
-+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
-+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
-+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
-+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
-+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
-+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
-+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
-+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
-+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
-+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
-+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
-+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
-+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
-+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
-+ /* Add the working vars back into context.state[] */
-+ state[0] += a;
-+ state[1] += b;
-+ state[2] += c;
-+ state[3] += d;
-+ state[4] += e;
-+ /* Wipe variables */
-+ a = b = c = d = e = 0;
-+}
-+
-+
-+/* SHA1Init - Initialize new context */
-+
-+void SHA1Init(void *vcontext)
-+{
-+ SHA1_CTX* context = vcontext;
-+
-+ /* SHA1 initialization constants */
-+ context->state[0] = 0x67452301;
-+ context->state[1] = 0xEFCDAB89;
-+ context->state[2] = 0x98BADCFE;
-+ context->state[3] = 0x10325476;
-+ context->state[4] = 0xC3D2E1F0;
-+ context->count[0] = context->count[1] = 0;
-+}
-+
-+
-+/* Run your data through this. */
-+
-+void SHA1Update(void *vcontext, unsigned char* data, __u32 len)
-+{
-+ SHA1_CTX* context = vcontext;
-+ __u32 i, j;
-+
-+ j = context->count[0];
-+ if ((context->count[0] += len << 3) < j)
-+ context->count[1]++;
-+ context->count[1] += (len>>29);
-+ j = (j >> 3) & 63;
-+ if ((j + len) > 63) {
-+ memcpy(&context->buffer[j], data, (i = 64-j));
-+ SHA1Transform(context->state, context->buffer);
-+ for ( ; i + 63 < len; i += 64) {
-+ SHA1Transform(context->state, &data[i]);
-+ }
-+ j = 0;
-+ }
-+ else i = 0;
-+ memcpy(&context->buffer[j], &data[i], len - i);
-+}
-+
-+
-+/* Add padding and return the message digest. */
-+
-+void SHA1Final(unsigned char digest[20], void *vcontext)
-+{
-+ __u32 i, j;
-+ unsigned char finalcount[8];
-+ SHA1_CTX* context = vcontext;
-+
-+ for (i = 0; i < 8; i++) {
-+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
-+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
-+ }
-+ SHA1Update(context, (unsigned char *)"\200", 1);
-+ while ((context->count[0] & 504) != 448) {
-+ SHA1Update(context, (unsigned char *)"\0", 1);
-+ }
-+ SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
-+ for (i = 0; i < 20; i++) {
-+ digest[i] = (unsigned char)
-+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
-+ }
-+ /* Wipe variables */
-+ i = j = 0;
-+ memset(context->buffer, 0, 64);
-+ memset(context->state, 0, 20);
-+ memset(context->count, 0, 8);
-+ memset(&finalcount, 0, 8);
-+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
-+ SHA1Transform(context->state, context->buffer);
-+#endif
-+}
-+
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.9 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.8 2002/09/10 01:45:14 mcr
-+ * changed type of MD5_CTX and SHA1_CTX to void * so that
-+ * the function prototypes would match, and could be placed
-+ * into a pointer to a function.
-+ *
-+ * Revision 1.7 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.6 2002/04/24 07:36:30 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_sha1.c,v
-+ *
-+ * Revision 1.5 1999/12/13 13:59:13 rgb
-+ * Quick fix to argument size to Update bugs.
-+ *
-+ * Revision 1.4 1999/04/11 00:29:00 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.3 1999/04/06 04:54:27 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.2 1999/01/22 06:55:50 rgb
-+ * 64-bit clean-up.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:50 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.2 1998/04/23 20:54:04 rgb
-+ * Fixed md5 and sha1 include file nesting issues, to be cleaned up when
-+ * verified.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:11 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:05 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * New transform
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_tunnel.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,2645 @@
-+/*
-+ * IPSEC Tunneling code. Heavily based on drivers/net/new_tunnel.c
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipsec_tunnel_c_version[] = "RCSID $Id$";
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/config.h> /* for CONFIG_IP_FORWARD */
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/tcp.h> /* struct tcphdr */
-+#include <linux/udp.h> /* struct udphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define ip_chk_addr inet_addr_type
-+# define IS_MYADDR RTN_LOCAL
-+# include <net/dst.h>
-+# undef dev_kfree_skb
-+# define dev_kfree_skb(a,b) kfree_skb(a)
-+# define PHYSDEV_TYPE
-+#endif /* NET_21 */
-+#include <asm/checksum.h>
-+#include <net/icmp.h> /* icmp_send() */
-+#include <net/ip.h>
-+#ifdef NETDEV_23
-+# include <linux/netfilter_ipv4.h>
-+#endif /* NETDEV_23 */
-+
-+#include <linux/if_arp.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_life.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_eroute.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_sa.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_xmit.h"
-+#include "openswan/ipsec_ipe4.h"
-+#include "openswan/ipsec_ah.h"
-+#include "openswan/ipsec_esp.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+#include <linux/udp.h>
-+#endif
-+
-+static __u32 zeroes[64];
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_tunnel = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_open(struct device *dev)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ /*
-+ * Can't open until attached.
-+ */
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_open: "
-+ "dev = %s, prv->dev = %s\n",
-+ dev->name, prv->dev?prv->dev->name:"NONE");
-+
-+ if (prv->dev == NULL)
-+ return -ENODEV;
-+
-+ MOD_INC_USE_COUNT;
-+ return 0;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_close(struct device *dev)
-+{
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+#ifdef NETDEV_23
-+static inline int ipsec_tunnel_xmit2(struct sk_buff *skb)
-+{
-+#ifdef NETDEV_25 /* 2.6 kernels */
-+ return dst_output(skb);
-+#else
-+ return ip_send(skb);
-+#endif
-+}
-+#endif /* NETDEV_23 */
-+
-+enum ipsec_xmit_value
-+ipsec_tunnel_strip_hard_header(struct ipsec_xmit_state *ixs)
-+{
-+ /* ixs->physdev->hard_header_len is unreliable and should not be used */
-+ ixs->hard_header_len = (unsigned char *)(ixs->iph) - ixs->skb->data;
-+
-+ if(ixs->hard_header_len < 0) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_error:ipsec_xmit_strip_hard_header: "
-+ "Negative hard_header_len (%d)?!\n", ixs->hard_header_len);
-+ ixs->stats->tx_dropped++;
-+ return IPSEC_XMIT_BADHHLEN;
-+ }
-+
-+ /* while ixs->physdev->hard_header_len is unreliable and
-+ * should not be trusted, it accurate and required for ATM, GRE and
-+ * some other interfaces to work. Thanks to Willy Tarreau
-+ * <willy@w.ods.org>.
-+ */
-+ if(ixs->hard_header_len == 0) { /* no hard header present */
-+ ixs->hard_header_stripped = 1;
-+ ixs->hard_header_len = ixs->physdev->hard_header_len;
-+ }
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (debug_tunnel & DB_TN_XMIT) {
-+ int i;
-+ char c;
-+
-+ printk(KERN_INFO "klips_debug:ipsec_xmit_strip_hard_header: "
-+ ">>> skb->len=%ld hard_header_len:%d",
-+ (unsigned long int)ixs->skb->len, ixs->hard_header_len);
-+ c = ' ';
-+ for (i=0; i < ixs->hard_header_len; i++) {
-+ printk("%c%02x", c, ixs->skb->data[i]);
-+ c = ':';
-+ }
-+ printk(" \n");
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_strip_hard_header: "
-+ "Original head,tailroom: %d,%d\n",
-+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_tunnel_SAlookup(struct ipsec_xmit_state *ixs)
-+{
-+ /*
-+ * First things first -- look us up in the erouting tables.
-+ */
-+ ixs->matcher.sen_len = sizeof (struct sockaddr_encap);
-+ ixs->matcher.sen_family = AF_ENCAP;
-+ ixs->matcher.sen_type = SENT_IP4;
-+ ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
-+ ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
-+ ixs->matcher.sen_proto = ixs->iph->protocol;
-+ ipsec_extract_ports(ixs->iph, &ixs->matcher);
-+
-+ /*
-+ * The spinlock is to prevent any other process from accessing or deleting
-+ * the eroute while we are using and updating it.
-+ */
-+ spin_lock(&eroute_lock);
-+
-+ ixs->eroute = ipsec_findroute(&ixs->matcher);
-+
-+ if(ixs->iph->protocol == IPPROTO_UDP) {
-+ if(ixs->skb->sk) {
-+ ixs->sport=ntohs(ixs->skb->sk->sport);
-+ ixs->dport=ntohs(ixs->skb->sk->dport);
-+ } else if((ntohs(ixs->iph->frag_off) & IP_OFFSET) == 0 &&
-+ ((ixs->skb->len - ixs->hard_header_len) >=
-+ ((ixs->iph->ihl << 2) + sizeof(struct udphdr)))) {
-+ ixs->sport=ntohs(((struct udphdr*)((caddr_t)ixs->iph+(ixs->iph->ihl<<2)))->source);
-+ ixs->dport=ntohs(((struct udphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl<<2)))->dest);
-+ } else {
-+ ixs->sport=0; ixs->dport=0;
-+ }
-+ }
-+
-+ /* default to a %drop eroute */
-+ ixs->outgoing_said.proto = IPPROTO_INT;
-+ ixs->outgoing_said.spi = htonl(SPI_DROP);
-+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_SAlookup: "
-+ "checking for local udp/500 IKE packet "
-+ "saddr=%x, er=0p%p, daddr=%x, er_dst=%x, proto=%d sport=%d dport=%d\n",
-+ ntohl((unsigned int)ixs->iph->saddr),
-+ ixs->eroute,
-+ ntohl((unsigned int)ixs->iph->daddr),
-+ ixs->eroute ? ntohl((unsigned int)ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr) : 0,
-+ ixs->iph->protocol,
-+ ixs->sport,
-+ ixs->dport);
-+
-+ /*
-+ * Quick cheat for now...are we udp/500? If so, let it through
-+ * without interference since it is most likely an IKE packet.
-+ */
-+
-+ if (ip_chk_addr((unsigned long)ixs->iph->saddr) == IS_MYADDR
-+ && (!ixs->eroute
-+ || ixs->iph->daddr == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr
-+ || INADDR_ANY == ixs->eroute->er_said.dst.u.v4.sin_addr.s_addr)
-+
-+ && ((ixs->sport == 500) || (ixs->sport == 4500))) {
-+ /* Whatever the eroute, this is an IKE message
-+ * from us (i.e. not being forwarded).
-+ * Furthermore, if there is a tunnel eroute,
-+ * the destination is the peer for this eroute.
-+ * So %pass the packet: modify the default %drop.
-+ */
-+ ixs->outgoing_said.spi = htonl(SPI_PASS);
-+ if(!(ixs->skb->sk) && ((ntohs(ixs->iph->frag_off) & IP_MF) != 0)) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_SAlookup: "
-+ "local UDP/500 (probably IKE) passthrough: base fragment, rest of fragments will probably get filtered.\n");
-+ }
-+ } else if (ixs->eroute) {
-+ ixs->eroute->er_count++;
-+ ixs->eroute->er_lasttime = jiffies/HZ;
-+ if(ixs->eroute->er_said.proto==IPPROTO_INT
-+ && ixs->eroute->er_said.spi==htonl(SPI_HOLD)) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_SAlookup: "
-+ "shunt SA of HOLD: skb stored in HOLD.\n");
-+ if(ixs->eroute->er_last != NULL) {
-+ kfree_skb(ixs->eroute->er_last);
-+ }
-+ ixs->eroute->er_last = ixs->skb;
-+ ixs->skb = NULL;
-+ ixs->stats->tx_dropped++;
-+ spin_unlock(&eroute_lock);
-+ return IPSEC_XMIT_STOLEN;
-+ }
-+ ixs->outgoing_said = ixs->eroute->er_said;
-+ ixs->eroute_pid = ixs->eroute->er_pid;
-+ /* Copy of the ident for the TRAP/TRAPSUBNET eroutes */
-+ if(ixs->outgoing_said.proto==IPPROTO_INT
-+ && (ixs->outgoing_said.spi==htonl(SPI_TRAP)
-+ || (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)))) {
-+ int len;
-+
-+ ixs->ips.ips_ident_s.type = ixs->eroute->er_ident_s.type;
-+ ixs->ips.ips_ident_s.id = ixs->eroute->er_ident_s.id;
-+ ixs->ips.ips_ident_s.len = ixs->eroute->er_ident_s.len;
-+ if (ixs->ips.ips_ident_s.len) {
-+ len = ixs->ips.ips_ident_s.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_SAlookup: "
-+ "allocating %d bytes for ident_s shunt SA of HOLD: skb stored in HOLD.\n",
-+ len);
-+ if ((ixs->ips.ips_ident_s.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
-+ printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
-+ "Failed, tried to allocate %d bytes for source ident.\n",
-+ len);
-+ ixs->stats->tx_dropped++;
-+ spin_unlock(&eroute_lock);
-+ return IPSEC_XMIT_ERRMEMALLOC;
-+ }
-+ memcpy(ixs->ips.ips_ident_s.data, ixs->eroute->er_ident_s.data, len);
-+ }
-+ ixs->ips.ips_ident_d.type = ixs->eroute->er_ident_d.type;
-+ ixs->ips.ips_ident_d.id = ixs->eroute->er_ident_d.id;
-+ ixs->ips.ips_ident_d.len = ixs->eroute->er_ident_d.len;
-+ if (ixs->ips.ips_ident_d.len) {
-+ len = ixs->ips.ips_ident_d.len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_SAlookup: "
-+ "allocating %d bytes for ident_d shunt SA of HOLD: skb stored in HOLD.\n",
-+ len);
-+ if ((ixs->ips.ips_ident_d.data = kmalloc(len, GFP_ATOMIC)) == NULL) {
-+ printk(KERN_WARNING "klips_debug:ipsec_xmit_SAlookup: "
-+ "Failed, tried to allocate %d bytes for dest ident.\n",
-+ len);
-+ ixs->stats->tx_dropped++;
-+ spin_unlock(&eroute_lock);
-+ return IPSEC_XMIT_ERRMEMALLOC;
-+ }
-+ memcpy(ixs->ips.ips_ident_d.data, ixs->eroute->er_ident_d.data, len);
-+ }
-+ }
-+ }
-+
-+ spin_unlock(&eroute_lock);
-+ return IPSEC_XMIT_OK;
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_tunnel_restore_hard_header(struct ipsec_xmit_state*ixs)
-+{
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_restore_hard_header: "
-+ "After recursive xforms -- head,tailroom: %d,%d\n",
-+ skb_headroom(ixs->skb),
-+ skb_tailroom(ixs->skb));
-+
-+ if(ixs->saved_header) {
-+ if(skb_headroom(ixs->skb) < ixs->hard_header_len) {
-+ printk(KERN_WARNING
-+ "klips_error:ipsec_xmit_restore_hard_header: "
-+ "tried to skb_push hhlen=%d, %d available. This should never happen, please report.\n",
-+ ixs->hard_header_len,
-+ skb_headroom(ixs->skb));
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_PUSHPULLERR;
-+
-+ }
-+ skb_push(ixs->skb, ixs->hard_header_len);
-+ {
-+ int i;
-+ for (i = 0; i < ixs->hard_header_len; i++) {
-+ ixs->skb->data[i] = ixs->saved_header[i];
-+ }
-+ }
-+ }
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if (ixs->natt_type && ixs->natt_head) {
-+ struct iphdr *ipp = ixs->skb->nh.iph;
-+ struct udphdr *udp;
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "encapsuling packet into UDP (NAT-Traversal) (%d %d)\n",
-+ ixs->natt_type, ixs->natt_head);
-+
-+ ixs->iphlen = ipp->ihl << 2;
-+ ipp->tot_len =
-+ htons(ntohs(ipp->tot_len) + ixs->natt_head);
-+ if(skb_tailroom(ixs->skb) < ixs->natt_head) {
-+ printk(KERN_WARNING "klips_error:ipsec_tunnel_start_xmit: "
-+ "tried to skb_put %d, %d available. "
-+ "This should never happen, please report.\n",
-+ ixs->natt_head,
-+ skb_tailroom(ixs->skb));
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESPUDP;
-+ }
-+ skb_put(ixs->skb, ixs->natt_head);
-+
-+ udp = (struct udphdr *)((char *)ipp + ixs->iphlen);
-+
-+ /* move ESP hdr after UDP hdr */
-+ memmove((void *)((char *)udp + ixs->natt_head),
-+ (void *)(udp),
-+ ntohs(ipp->tot_len) - ixs->iphlen - ixs->natt_head);
-+
-+ /* clear UDP & Non-IKE Markers (if any) */
-+ memset(udp, 0, ixs->natt_head);
-+
-+ /* fill UDP with usefull informations ;-) */
-+ udp->source = htons(ixs->natt_sport);
-+ udp->dest = htons(ixs->natt_dport);
-+ udp->len = htons(ntohs(ipp->tot_len) - ixs->iphlen);
-+
-+ /* set protocol */
-+ ipp->protocol = IPPROTO_UDP;
-+
-+ /* fix IP checksum */
-+ ipp->check = 0;
-+ ipp->check = ip_fast_csum((unsigned char *)ipp, ipp->ihl);
-+ }
-+#endif
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_restore_hard_header: "
-+ "With hard_header, final head,tailroom: %d,%d\n",
-+ skb_headroom(ixs->skb),
-+ skb_tailroom(ixs->skb));
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_tunnel_send(struct ipsec_xmit_state*ixs)
-+{
-+#ifdef NETDEV_25
-+ struct flowi fl;
-+#endif
-+
-+#ifdef NET_21 /* 2.2 and 2.4 kernels */
-+ /* new route/dst cache code from James Morris */
-+ ixs->skb->dev = ixs->physdev;
-+#ifdef NETDEV_25
-+ fl.oif = ixs->physdev->iflink;
-+ fl.nl_u.ip4_u.daddr = ixs->skb->nh.iph->daddr;
-+ fl.nl_u.ip4_u.saddr = ixs->pass ? 0 : ixs->skb->nh.iph->saddr;
-+ fl.nl_u.ip4_u.tos = RT_TOS(ixs->skb->nh.iph->tos);
-+ fl.proto = ixs->skb->nh.iph->protocol;
-+ if ((ixs->error = ip_route_output_key(&ixs->route, &fl))) {
-+#else
-+ /*skb_orphan(ixs->skb);*/
-+ if((ixs->error = ip_route_output(&ixs->route,
-+ ixs->skb->nh.iph->daddr,
-+ ixs->pass ? 0 : ixs->skb->nh.iph->saddr,
-+ RT_TOS(ixs->skb->nh.iph->tos),
-+ /* mcr->rgb: should this be 0 instead? */
-+ ixs->physdev->iflink))) {
-+#endif
-+ ixs->stats->tx_errors++;
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_send: "
-+ "ip_route_output failed with error code %d, rt->u.dst.dev=%s, dropped\n",
-+ ixs->error,
-+ ixs->route->u.dst.dev->name);
-+ return IPSEC_XMIT_ROUTEERR;
-+ }
-+ if(ixs->dev == ixs->route->u.dst.dev) {
-+ ip_rt_put(ixs->route);
-+ /* This is recursion, drop it. */
-+ ixs->stats->tx_errors++;
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_send: "
-+ "suspect recursion, dev=rt->u.dst.dev=%s, dropped\n",
-+ ixs->dev->name);
-+ return IPSEC_XMIT_RECURSDETECT;
-+ }
-+ dst_release(ixs->skb->dst);
-+ ixs->skb->dst = &ixs->route->u.dst;
-+ ixs->stats->tx_bytes += ixs->skb->len;
-+ if(ixs->skb->len < ixs->skb->nh.raw - ixs->skb->data) {
-+ ixs->stats->tx_errors++;
-+ printk(KERN_WARNING
-+ "klips_error:ipsec_xmit_send: "
-+ "tried to __skb_pull nh-data=%ld, %d available. This should never happen, please report.\n",
-+ (unsigned long)(ixs->skb->nh.raw - ixs->skb->data),
-+ ixs->skb->len);
-+ return IPSEC_XMIT_PUSHPULLERR;
-+ }
-+ __skb_pull(ixs->skb, ixs->skb->nh.raw - ixs->skb->data);
-+#ifdef SKB_RESET_NFCT
-+ if(!ixs->pass) {
-+ nf_conntrack_put(ixs->skb->nfct);
-+ ixs->skb->nfct = NULL;
-+ }
-+#ifdef CONFIG_NETFILTER_DEBUG
-+ ixs->skb->nf_debug = 0;
-+#endif /* CONFIG_NETFILTER_DEBUG */
-+#endif /* SKB_RESET_NFCT */
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_send: "
-+ "...done, calling ip_send() on device:%s\n",
-+ ixs->skb->dev ? ixs->skb->dev->name : "NULL");
-+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->skb->nh.iph);
-+#ifdef NETDEV_23 /* 2.4 kernels */
-+ {
-+ int err;
-+
-+ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, ixs->skb, NULL, ixs->route->u.dst.dev,
-+ ipsec_tunnel_xmit2);
-+ if(err != NET_XMIT_SUCCESS && err != NET_XMIT_CN) {
-+ if(net_ratelimit())
-+ printk(KERN_ERR
-+ "klips_error:ipsec_xmit_send: "
-+ "ip_send() failed, err=%d\n",
-+ -err);
-+ ixs->stats->tx_errors++;
-+ ixs->stats->tx_aborted_errors++;
-+ ixs->skb = NULL;
-+ return IPSEC_XMIT_IPSENDFAILURE;
-+ }
-+ }
-+#else /* NETDEV_23 */ /* 2.2 kernels */
-+ ip_send(ixs->skb);
-+#endif /* NETDEV_23 */
-+#else /* NET_21 */ /* 2.0 kernels */
-+ ixs->skb->arp = 1;
-+ /* ISDN/ASYNC PPP from Matjaz Godec. */
-+ /* skb->protocol = htons(ETH_P_IP); */
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_send: "
-+ "...done, calling dev_queue_xmit() or ip_fragment().\n");
-+ IP_SEND(ixs->skb, ixs->physdev);
-+#endif /* NET_21 */
-+ ixs->stats->tx_packets++;
-+
-+ ixs->skb = NULL;
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+void
-+ipsec_tunnel_cleanup(struct ipsec_xmit_state*ixs)
-+{
-+#if defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE)
-+ netif_wake_queue(ixs->dev);
-+#else /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
-+ ixs->dev->tbusy = 0;
-+#endif /* defined(HAS_NETIF_QUEUE) || defined (HAVE_NETIF_QUEUE) */
-+ if(ixs->saved_header) {
-+ kfree(ixs->saved_header);
-+ }
-+ if(ixs->skb) {
-+ dev_kfree_skb(ixs->skb, FREE_WRITE);
-+ }
-+ if(ixs->oskb) {
-+ dev_kfree_skb(ixs->oskb, FREE_WRITE);
-+ }
-+ if (ixs->ips.ips_ident_s.data) {
-+ kfree(ixs->ips.ips_ident_s.data);
-+ }
-+ if (ixs->ips.ips_ident_d.data) {
-+ kfree(ixs->ips.ips_ident_d.data);
-+ }
-+}
-+
-+/*
-+ * This function assumes it is being called from dev_queue_xmit()
-+ * and that skb is filled properly by that function.
-+ */
-+int
-+ipsec_tunnel_start_xmit(struct sk_buff *skb, struct device *dev)
-+{
-+ struct ipsec_xmit_state ixs_mem;
-+ struct ipsec_xmit_state *ixs = &ixs_mem;
-+ enum ipsec_xmit_value stat;
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ ixs->natt_type = 0, ixs->natt_head = 0;
-+ ixs->natt_sport = 0, ixs->natt_dport = 0;
-+#endif
-+
-+ memset((caddr_t)ixs, 0, sizeof(*ixs));
-+ ixs->oskb = NULL;
-+ ixs->saved_header = NULL; /* saved copy of the hard header */
-+ ixs->route = NULL;
-+ memset((caddr_t)&(ixs->ips), 0, sizeof(ixs->ips));
-+ ixs->dev = dev;
-+ ixs->skb = skb;
-+
-+ stat = ipsec_xmit_sanity_check_dev(ixs);
-+ if(stat != IPSEC_XMIT_OK) {
-+ goto cleanup;
-+ }
-+
-+ stat = ipsec_xmit_sanity_check_skb(ixs);
-+ if(stat != IPSEC_XMIT_OK) {
-+ goto cleanup;
-+ }
-+
-+ stat = ipsec_tunnel_strip_hard_header(ixs);
-+ if(stat != IPSEC_XMIT_OK) {
-+ goto cleanup;
-+ }
-+
-+ stat = ipsec_tunnel_SAlookup(ixs);
-+ if(stat != IPSEC_XMIT_OK) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_tunnel_start_xmit: SAlookup failed: %d\n",
-+ stat);
-+ goto cleanup;
-+ }
-+
-+ ixs->innersrc = ixs->iph->saddr;
-+ /* start encapsulation loop here XXX */
-+ do {
-+ stat = ipsec_xmit_encap_bundle(ixs);
-+ if(stat != IPSEC_XMIT_OK) {
-+ if(stat == IPSEC_XMIT_PASS) {
-+ goto bypass;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_tunnel_start_xmit: encap_bundle failed: %d\n",
-+ stat);
-+ goto cleanup;
-+ }
-+
-+ ixs->matcher.sen_ip_src.s_addr = ixs->iph->saddr;
-+ ixs->matcher.sen_ip_dst.s_addr = ixs->iph->daddr;
-+ ixs->matcher.sen_proto = ixs->iph->protocol;
-+ ipsec_extract_ports(ixs->iph, &ixs->matcher);
-+
-+ spin_lock(&eroute_lock);
-+ ixs->eroute = ipsec_findroute(&ixs->matcher);
-+ if(ixs->eroute) {
-+ ixs->outgoing_said = ixs->eroute->er_said;
-+ ixs->eroute_pid = ixs->eroute->er_pid;
-+ ixs->eroute->er_count++;
-+ ixs->eroute->er_lasttime = jiffies/HZ;
-+ }
-+ spin_unlock(&eroute_lock);
-+
-+ KLIPS_PRINT((debug_tunnel & DB_TN_XMIT) &&
-+ /* ((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc)) */
-+ (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
-+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
-+ ixs->eroute,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "We are recursing here.\n");
-+
-+ } while(/*((ixs->orgdst != ixs->newdst) || (ixs->orgsrc != ixs->newsrc))*/
-+ (ixs->orgedst != ixs->outgoing_said.dst.u.v4.sin_addr.s_addr) &&
-+ ixs->outgoing_said.dst.u.v4.sin_addr.s_addr &&
-+ ixs->eroute);
-+
-+ stat = ipsec_tunnel_restore_hard_header(ixs);
-+ if(stat != IPSEC_XMIT_OK) {
-+ goto cleanup;
-+ }
-+
-+ bypass:
-+ stat = ipsec_tunnel_send(ixs);
-+
-+ cleanup:
-+ ipsec_tunnel_cleanup(ixs);
-+
-+ return 0;
-+}
-+
-+DEBUG_NO_STATIC struct net_device_stats *
-+ipsec_tunnel_get_stats(struct device *dev)
-+{
-+ return &(((struct ipsecpriv *)(dev->priv))->mystats);
-+}
-+
-+/*
-+ * Revectored calls.
-+ * For each of these calls, a field exists in our private structure.
-+ */
-+
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_hard_header(struct sk_buff *skb, struct device *dev,
-+ unsigned short type, void *daddr, void *saddr, unsigned len)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+ struct device *tmp;
-+ int ret;
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(skb == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_hard_header: "
-+ "no skb...\n");
-+ return -ENODATA;
-+ }
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_hard_header: "
-+ "no device...\n");
-+ return -ENODEV;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_hard_header: "
-+ "skb->dev=%s dev=%s.\n",
-+ skb->dev ? skb->dev->name : "NULL",
-+ dev->name);
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_hard_header: "
-+ "no private space associated with dev=%s\n",
-+ dev->name ? dev->name : "NULL");
-+ return -ENODEV;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_hard_header: "
-+ "no physical device associated with dev=%s\n",
-+ dev->name ? dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+ /* check if we have to send a IPv6 packet. It might be a Router
-+ Solicitation, where the building of the packet happens in
-+ reverse order:
-+ 1. ll hdr,
-+ 2. IPv6 hdr,
-+ 3. ICMPv6 hdr
-+ -> skb->nh.raw is still uninitialized when this function is
-+ called!! If this is no IPv6 packet, we can print debugging
-+ messages, otherwise we skip all debugging messages and just
-+ build the ll header */
-+ if(type != ETH_P_IPV6) {
-+ /* execute this only, if we don't have to build the
-+ header for a IPv6 packet */
-+ if(!prv->hard_header) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_hard_header: "
-+ "physical device has been detached, packet dropped 0p%p->0p%p len=%d type=%d dev=%s->NULL ",
-+ saddr,
-+ daddr,
-+ len,
-+ type,
-+ dev->name);
-+#ifdef NET_21
-+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->nh.iph->saddr),
-+ (__u32)ntohl(skb->nh.iph->daddr) );
-+#else /* NET_21 */
-+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->ip_hdr->saddr),
-+ (__u32)ntohl(skb->ip_hdr->daddr) );
-+#endif /* NET_21 */
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+#define da ((struct device *)(prv->dev))->dev_addr
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_hard_header: "
-+ "Revectored 0p%p->0p%p len=%d type=%d dev=%s->%s dev_addr=%02x:%02x:%02x:%02x:%02x:%02x ",
-+ saddr,
-+ daddr,
-+ len,
-+ type,
-+ dev->name,
-+ prv->dev->name,
-+ da[0], da[1], da[2], da[3], da[4], da[5]);
-+#ifdef NET_21
-+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->nh.iph->saddr),
-+ (__u32)ntohl(skb->nh.iph->daddr) );
-+#else /* NET_21 */
-+ KLIPS_PRINTMORE(debug_tunnel & DB_TN_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->ip_hdr->saddr),
-+ (__u32)ntohl(skb->ip_hdr->daddr) );
-+#endif /* NET_21 */
-+ } else {
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_hard_header: "
-+ "is IPv6 packet, skip debugging messages, only revector and build linklocal header.\n");
-+ }
-+ tmp = skb->dev;
-+ skb->dev = prv->dev;
-+ ret = prv->hard_header(skb, prv->dev, type, (void *)daddr, (void *)saddr, len);
-+ skb->dev = tmp;
-+ return ret;
-+}
-+
-+DEBUG_NO_STATIC int
-+#ifdef NET_21
-+ipsec_tunnel_rebuild_header(struct sk_buff *skb)
-+#else /* NET_21 */
-+ipsec_tunnel_rebuild_header(void *buff, struct device *dev,
-+ unsigned long raddr, struct sk_buff *skb)
-+#endif /* NET_21 */
-+{
-+ struct ipsecpriv *prv = skb->dev->priv;
-+ struct device *tmp;
-+ int ret;
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(skb->dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_rebuild_header: "
-+ "no device...");
-+ return -ENODEV;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_rebuild_header: "
-+ "no private space associated with dev=%s",
-+ skb->dev->name ? skb->dev->name : "NULL");
-+ return -ENODEV;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_rebuild_header: "
-+ "no physical device associated with dev=%s",
-+ skb->dev->name ? skb->dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+ if(!prv->rebuild_header) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_rebuild_header: "
-+ "physical device has been detached, packet dropped skb->dev=%s->NULL ",
-+ skb->dev->name);
-+#ifdef NET_21
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->nh.iph->saddr),
-+ (__u32)ntohl(skb->nh.iph->daddr) );
-+#else /* NET_21 */
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->ip_hdr->saddr),
-+ (__u32)ntohl(skb->ip_hdr->daddr) );
-+#endif /* NET_21 */
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel: "
-+ "Revectored rebuild_header dev=%s->%s ",
-+ skb->dev->name, prv->dev->name);
-+#ifdef NET_21
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->nh.iph->saddr),
-+ (__u32)ntohl(skb->nh.iph->daddr) );
-+#else /* NET_21 */
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "ip=%08x->%08x\n",
-+ (__u32)ntohl(skb->ip_hdr->saddr),
-+ (__u32)ntohl(skb->ip_hdr->daddr) );
-+#endif /* NET_21 */
-+ tmp = skb->dev;
-+ skb->dev = prv->dev;
-+
-+#ifdef NET_21
-+ ret = prv->rebuild_header(skb);
-+#else /* NET_21 */
-+ ret = prv->rebuild_header(buff, prv->dev, raddr, skb);
-+#endif /* NET_21 */
-+ skb->dev = tmp;
-+ return ret;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_set_mac_address(struct device *dev, void *addr)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_set_mac_address: "
-+ "no device...");
-+ return -ENODEV;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_set_mac_address: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return -ENODEV;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_set_mac_address: "
-+ "no physical device associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return -ENODEV;
-+ }
-+
-+ if(!prv->set_mac_address) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_set_mac_address: "
-+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
-+ dev->name);
-+ return -ENODEV;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_set_mac_address: "
-+ "Revectored dev=%s->%s addr=0p%p\n",
-+ dev->name, prv->dev->name, addr);
-+ return prv->set_mac_address(prv->dev, addr);
-+
-+}
-+
-+#ifndef NET_21
-+DEBUG_NO_STATIC void
-+ipsec_tunnel_cache_bind(struct hh_cache **hhp, struct device *dev,
-+ unsigned short htype, __u32 daddr)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_bind: "
-+ "no device...");
-+ return;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_bind: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_bind: "
-+ "no physical device associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return;
-+ }
-+
-+ if(!prv->header_cache_bind) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_bind: "
-+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
-+ dev->name);
-+ stats->tx_dropped++;
-+ return;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_bind: "
-+ "Revectored \n");
-+ prv->header_cache_bind(hhp, prv->dev, htype, daddr);
-+ return;
-+}
-+#endif /* !NET_21 */
-+
-+
-+DEBUG_NO_STATIC void
-+ipsec_tunnel_cache_update(struct hh_cache *hh, struct device *dev, unsigned char * haddr)
-+{
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ struct net_device_stats *stats; /* This device's statistics */
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_update: "
-+ "no device...");
-+ return;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_update: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return;
-+ }
-+
-+ stats = (struct net_device_stats *) &(prv->mystats);
-+
-+ if(prv->dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_update: "
-+ "no physical device associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ stats->tx_dropped++;
-+ return;
-+ }
-+
-+ if(!prv->header_cache_update) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_cache_update: "
-+ "physical device has been detached, cannot set - skb->dev=%s->NULL\n",
-+ dev->name);
-+ return;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel: "
-+ "Revectored cache_update\n");
-+ prv->header_cache_update(hh, prv->dev, haddr);
-+ return;
-+}
-+
-+#ifdef NET_21
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_neigh_setup(struct neighbour *n)
-+{
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_neigh_setup:\n");
-+
-+ if (n->nud_state == NUD_NONE) {
-+ n->ops = &arp_broken_ops;
-+ n->output = n->ops->output;
-+ }
-+ return 0;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_neigh_setup_dev(struct device *dev, struct neigh_parms *p)
-+{
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_neigh_setup_dev: "
-+ "setting up %s\n",
-+ dev ? dev->name : "NULL");
-+
-+ if (p->tbl->family == AF_INET) {
-+ p->neigh_setup = ipsec_tunnel_neigh_setup;
-+ p->ucast_probes = 0;
-+ p->mcast_probes = 0;
-+ }
-+ return 0;
-+}
-+#endif /* NET_21 */
-+
-+/*
-+ * We call the attach routine to attach another device.
-+ */
-+
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_attach(struct device *dev, struct device *physdev)
-+{
-+ int i;
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_attach: "
-+ "no device...");
-+ return -ENODEV;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_attach: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return -ENODATA;
-+ }
-+
-+ prv->dev = physdev;
-+ prv->hard_start_xmit = physdev->hard_start_xmit;
-+ prv->get_stats = physdev->get_stats;
-+
-+ if (physdev->hard_header) {
-+ prv->hard_header = physdev->hard_header;
-+ dev->hard_header = ipsec_tunnel_hard_header;
-+ } else
-+ dev->hard_header = NULL;
-+
-+ if (physdev->rebuild_header) {
-+ prv->rebuild_header = physdev->rebuild_header;
-+ dev->rebuild_header = ipsec_tunnel_rebuild_header;
-+ } else
-+ dev->rebuild_header = NULL;
-+
-+ if (physdev->set_mac_address) {
-+ prv->set_mac_address = physdev->set_mac_address;
-+ dev->set_mac_address = ipsec_tunnel_set_mac_address;
-+ } else
-+ dev->set_mac_address = NULL;
-+
-+#ifndef NET_21
-+ if (physdev->header_cache_bind) {
-+ prv->header_cache_bind = physdev->header_cache_bind;
-+ dev->header_cache_bind = ipsec_tunnel_cache_bind;
-+ } else
-+ dev->header_cache_bind = NULL;
-+#endif /* !NET_21 */
-+
-+ if (physdev->header_cache_update) {
-+ prv->header_cache_update = physdev->header_cache_update;
-+ dev->header_cache_update = ipsec_tunnel_cache_update;
-+ } else
-+ dev->header_cache_update = NULL;
-+
-+ dev->hard_header_len = physdev->hard_header_len;
-+
-+#ifdef NET_21
-+/* prv->neigh_setup = physdev->neigh_setup; */
-+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
-+#endif /* NET_21 */
-+ dev->mtu = 16260; /* 0xfff0; */ /* dev->mtu; */
-+ prv->mtu = physdev->mtu;
-+
-+#ifdef PHYSDEV_TYPE
-+ dev->type = physdev->type; /* ARPHRD_TUNNEL; */
-+#endif /* PHYSDEV_TYPE */
-+
-+ dev->addr_len = physdev->addr_len;
-+ for (i=0; i<dev->addr_len; i++) {
-+ dev->dev_addr[i] = physdev->dev_addr[i];
-+ }
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(debug_tunnel & DB_TN_INIT) {
-+ printk(KERN_INFO "klips_debug:ipsec_tunnel_attach: "
-+ "physical device %s being attached has HW address: %2x",
-+ physdev->name, physdev->dev_addr[0]);
-+ for (i=1; i < physdev->addr_len; i++) {
-+ printk(":%02x", physdev->dev_addr[i]);
-+ }
-+ printk("\n");
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ return 0;
-+}
-+
-+/*
-+ * We call the detach routine to detach the ipsec tunnel from another device.
-+ */
-+
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_detach(struct device *dev)
-+{
-+ int i;
-+ struct ipsecpriv *prv = dev->priv;
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_detach: "
-+ "no device...");
-+ return -ENODEV;
-+ }
-+
-+ if(prv == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_REVEC,
-+ "klips_debug:ipsec_tunnel_detach: "
-+ "no private space associated with dev=%s",
-+ dev->name ? dev->name : "NULL");
-+ return -ENODATA;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_detach: "
-+ "physical device %s being detached from virtual device %s\n",
-+ prv->dev ? prv->dev->name : "NULL",
-+ dev->name);
-+
-+ ipsec_dev_put(prv->dev);
-+ prv->dev = NULL;
-+ prv->hard_start_xmit = NULL;
-+ prv->get_stats = NULL;
-+
-+ prv->hard_header = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->hard_header = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+ prv->rebuild_header = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->rebuild_header = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+ prv->set_mac_address = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->set_mac_address = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+#ifndef NET_21
-+ prv->header_cache_bind = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->header_cache_bind = NULL;
-+#endif /* DETACH_AND_DOWN */
-+#endif /* !NET_21 */
-+
-+ prv->header_cache_update = NULL;
-+#ifdef DETACH_AND_DOWN
-+ dev->header_cache_update = NULL;
-+#endif /* DETACH_AND_DOWN */
-+
-+#ifdef NET_21
-+/* prv->neigh_setup = NULL; */
-+#ifdef DETACH_AND_DOWN
-+ dev->neigh_setup = NULL;
-+#endif /* DETACH_AND_DOWN */
-+#endif /* NET_21 */
-+ dev->hard_header_len = 0;
-+#ifdef DETACH_AND_DOWN
-+ dev->mtu = 0;
-+#endif /* DETACH_AND_DOWN */
-+ prv->mtu = 0;
-+ for (i=0; i<MAX_ADDR_LEN; i++) {
-+ dev->dev_addr[i] = 0;
-+ }
-+ dev->addr_len = 0;
-+#ifdef PHYSDEV_TYPE
-+ dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */
-+#endif /* PHYSDEV_TYPE */
-+
-+ return 0;
-+}
-+
-+/*
-+ * We call the clear routine to detach all ipsec tunnels from other devices.
-+ */
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_clear(void)
-+{
-+ int i;
-+ struct device *ipsecdev = NULL, *prvdev;
-+ struct ipsecpriv *prv;
-+ char name[9];
-+ int ret;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_clear: .\n");
-+
-+ for(i = 0; i < IPSEC_NUM_IF; i++) {
-+ ipsecdev = ipsecdevices[i];
-+ if(ipsecdev != NULL) {
-+ if((prv = (struct ipsecpriv *)(ipsecdev->priv))) {
-+ prvdev = (struct device *)(prv->dev);
-+ if(prvdev) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_clear: "
-+ "physical device for device %s is %s\n",
-+ name, prvdev->name);
-+ if((ret = ipsec_tunnel_detach(ipsecdev))) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_clear: "
-+ "error %d detatching device %s from device %s.\n",
-+ ret, name, prvdev->name);
-+ return ret;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ return 0;
-+}
-+
-+DEBUG_NO_STATIC int
-+ipsec_tunnel_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
-+{
-+ struct ipsectunnelconf *cf = (struct ipsectunnelconf *)&ifr->ifr_data;
-+ struct ipsecpriv *prv = dev->priv;
-+ struct device *them; /* physical device */
-+#ifdef CONFIG_IP_ALIAS
-+ char *colon;
-+ char realphysname[IFNAMSIZ];
-+#endif /* CONFIG_IP_ALIAS */
-+
-+ if(dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "device not supplied.\n");
-+ return -ENODEV;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "tncfg service call #%d for dev=%s\n",
-+ cmd,
-+ dev->name ? dev->name : "NULL");
-+ switch (cmd) {
-+ /* attach a virtual ipsec? device to a physical device */
-+ case IPSEC_SET_DEV:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "calling ipsec_tunnel_attatch...\n");
-+#ifdef CONFIG_IP_ALIAS
-+ /* If this is an IP alias interface, get its real physical name */
-+ strncpy(realphysname, cf->cf_name, IFNAMSIZ);
-+ realphysname[IFNAMSIZ-1] = 0;
-+ colon = strchr(realphysname, ':');
-+ if (colon) *colon = 0;
-+ them = ipsec_dev_get(realphysname);
-+#else /* CONFIG_IP_ALIAS */
-+ them = ipsec_dev_get(cf->cf_name);
-+#endif /* CONFIG_IP_ALIAS */
-+
-+ if (them == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "physical device %s requested is null\n",
-+ cf->cf_name);
-+ ipsec_dev_put(them);
-+ return -ENXIO;
-+ }
-+
-+#if 0
-+ if (them->flags & IFF_UP) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "physical device %s requested is not up.\n",
-+ cf->cf_name);
-+ ipsec_dev_put(them);
-+ return -ENXIO;
-+ }
-+#endif
-+
-+ if (prv && prv->dev) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "virtual device is already connected to %s.\n",
-+ prv->dev->name ? prv->dev->name : "NULL");
-+ ipsec_dev_put(them);
-+ return -EBUSY;
-+ }
-+ return ipsec_tunnel_attach(dev, them);
-+
-+ case IPSEC_DEL_DEV:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "calling ipsec_tunnel_detatch.\n");
-+ if (! prv->dev) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "physical device not connected.\n");
-+ return -ENODEV;
-+ }
-+ return ipsec_tunnel_detach(dev);
-+
-+ case IPSEC_CLR_DEV:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "calling ipsec_tunnel_clear.\n");
-+ return ipsec_tunnel_clear();
-+
-+ default:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_ioctl: "
-+ "unknown command %d.\n",
-+ cmd);
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+int
-+ipsec_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
-+{
-+ struct device *dev = ptr;
-+ struct device *ipsec_dev;
-+ struct ipsecpriv *priv;
-+ int i;
-+
-+ if (dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "dev=NULL for event type %ld.\n",
-+ event);
-+ return(NOTIFY_DONE);
-+ }
-+
-+ /* check for loopback devices */
-+ if (dev && (dev->flags & IFF_LOOPBACK)) {
-+ return(NOTIFY_DONE);
-+ }
-+
-+ switch (event) {
-+ case NETDEV_DOWN:
-+ /* look very carefully at the scope of these compiler
-+ directives before changing anything... -- RGB */
-+#ifdef NET_21
-+ case NETDEV_UNREGISTER:
-+ switch (event) {
-+ case NETDEV_DOWN:
-+#endif /* NET_21 */
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_DOWN dev=%s flags=%x\n",
-+ dev->name,
-+ dev->flags);
-+ if(strncmp(dev->name, "ipsec", strlen("ipsec")) == 0) {
-+ printk(KERN_CRIT "IPSEC EVENT: KLIPS device %s shut down.\n",
-+ dev->name);
-+ }
-+#ifdef NET_21
-+ break;
-+ case NETDEV_UNREGISTER:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_UNREGISTER dev=%s flags=%x\n",
-+ dev->name,
-+ dev->flags);
-+ break;
-+ }
-+#endif /* NET_21 */
-+
-+ /* find the attached physical device and detach it. */
-+ for(i = 0; i < IPSEC_NUM_IF; i++) {
-+ ipsec_dev = ipsecdevices[i];
-+
-+ if(ipsec_dev) {
-+ priv = (struct ipsecpriv *)(ipsec_dev->priv);
-+ if(priv) {
-+ ;
-+ if(((struct device *)(priv->dev)) == dev) {
-+ /* dev_close(ipsec_dev); */
-+ /* return */ ipsec_tunnel_detach(ipsec_dev);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "device '%s' has been detached.\n",
-+ ipsec_dev->name);
-+ break;
-+ }
-+ } else {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "device '%s' has no private data space!\n",
-+ ipsec_dev->name);
-+ }
-+ }
-+ }
-+ break;
-+ case NETDEV_UP:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_UP dev=%s\n",
-+ dev->name);
-+ break;
-+#ifdef NET_21
-+ case NETDEV_REBOOT:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_REBOOT dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_CHANGE:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_CHANGE dev=%s flags=%x\n",
-+ dev->name,
-+ dev->flags);
-+ break;
-+ case NETDEV_REGISTER:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_REGISTER dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_CHANGEMTU:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_CHANGEMTU dev=%s to mtu=%d\n",
-+ dev->name,
-+ dev->mtu);
-+ break;
-+ case NETDEV_CHANGEADDR:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_CHANGEADDR dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_GOING_DOWN:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_GOING_DOWN dev=%s\n",
-+ dev->name);
-+ break;
-+ case NETDEV_CHANGENAME:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "NETDEV_CHANGENAME dev=%s\n",
-+ dev->name);
-+ break;
-+#endif /* NET_21 */
-+ default:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_device_event: "
-+ "event type %ld unrecognised for dev=%s\n",
-+ event,
-+ dev->name);
-+ break;
-+ }
-+ return NOTIFY_DONE;
-+}
-+
-+/*
-+ * Called when an ipsec tunnel device is initialized.
-+ * The ipsec tunnel device structure is passed to us.
-+ */
-+
-+int
-+ipsec_tunnel_init(struct device *dev)
-+{
-+ int i;
-+
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_init: "
-+ "allocating %lu bytes initialising device: %s\n",
-+ (unsigned long) sizeof(struct ipsecpriv),
-+ dev->name ? dev->name : "NULL");
-+
-+ /* Add our tunnel functions to the device */
-+ dev->open = ipsec_tunnel_open;
-+ dev->stop = ipsec_tunnel_close;
-+ dev->hard_start_xmit = ipsec_tunnel_start_xmit;
-+ dev->get_stats = ipsec_tunnel_get_stats;
-+
-+ dev->priv = kmalloc(sizeof(struct ipsecpriv), GFP_KERNEL);
-+ if (dev->priv == NULL)
-+ return -ENOMEM;
-+ memset((caddr_t)(dev->priv), 0, sizeof(struct ipsecpriv));
-+
-+ for(i = 0; i < sizeof(zeroes); i++) {
-+ ((__u8*)(zeroes))[i] = 0;
-+ }
-+
-+#ifndef NET_21
-+ /* Initialize the tunnel device structure */
-+ for (i = 0; i < DEV_NUMBUFFS; i++)
-+ skb_queue_head_init(&dev->buffs[i]);
-+#endif /* !NET_21 */
-+
-+ dev->set_multicast_list = NULL;
-+ dev->do_ioctl = ipsec_tunnel_ioctl;
-+ dev->hard_header = NULL;
-+ dev->rebuild_header = NULL;
-+ dev->set_mac_address = NULL;
-+#ifndef NET_21
-+ dev->header_cache_bind = NULL;
-+#endif /* !NET_21 */
-+ dev->header_cache_update= NULL;
-+
-+#ifdef NET_21
-+/* prv->neigh_setup = NULL; */
-+ dev->neigh_setup = ipsec_tunnel_neigh_setup_dev;
-+#endif /* NET_21 */
-+ dev->hard_header_len = 0;
-+ dev->mtu = 0;
-+ dev->addr_len = 0;
-+ dev->type = ARPHRD_VOID; /* ARPHRD_TUNNEL; */ /* ARPHRD_ETHER; */
-+ dev->tx_queue_len = 10; /* Small queue */
-+ memset((caddr_t)(dev->broadcast),0xFF, ETH_ALEN); /* what if this is not attached to ethernet? */
-+
-+ /* New-style flags. */
-+ dev->flags = IFF_NOARP /* 0 */ /* Petr Novak */;
-+#ifdef NET_21
-+ dev_init_buffers(dev);
-+#else /* NET_21 */
-+ dev->family = AF_INET;
-+ dev->pa_addr = 0;
-+ dev->pa_brdaddr = 0;
-+ dev->pa_mask = 0;
-+ dev->pa_alen = 4;
-+#endif /* NET_21 */
-+
-+ /* We're done. Have I forgotten anything? */
-+ return 0;
-+}
-+
-+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-+/* Module specific interface (but it links with the rest of IPSEC) */
-+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-+
-+int
-+ipsec_tunnel_probe(struct device *dev)
-+{
-+ ipsec_tunnel_init(dev);
-+ return 0;
-+}
-+
-+struct device *ipsecdevices[IPSEC_NUM_IF];
-+
-+int
-+ipsec_tunnel_init_devices(void)
-+{
-+ int i;
-+ char name[IFNAMSIZ];
-+ struct device *dev_ipsec;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_init_devices: "
-+ "creating and registering IPSEC_NUM_IF=%u devices, allocating %lu per device, IFNAMSIZ=%u.\n",
-+ IPSEC_NUM_IF,
-+ (unsigned long) (sizeof(struct device) + IFNAMSIZ),
-+ IFNAMSIZ);
-+
-+ for(i = 0; i < IPSEC_NUM_IF; i++) {
-+ sprintf(name, IPSEC_DEV_FORMAT, i);
-+ dev_ipsec = (struct device*)kmalloc(sizeof(struct device), GFP_KERNEL);
-+ if (dev_ipsec == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_init_devices: "
-+ "failed to allocate memory for device %s, quitting device init.\n",
-+ name);
-+ return -ENOMEM;
-+ }
-+ memset((caddr_t)dev_ipsec, 0, sizeof(struct device));
-+#ifdef NETDEV_23
-+ strncpy(dev_ipsec->name, name, sizeof(dev_ipsec->name));
-+#else /* NETDEV_23 */
-+ dev_ipsec->name = (char*)kmalloc(IFNAMSIZ, GFP_KERNEL);
-+ if (dev_ipsec->name == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_init_devices: "
-+ "failed to allocate memory for device %s name, quitting device init.\n",
-+ name);
-+ return -ENOMEM;
-+ }
-+ memset((caddr_t)dev_ipsec->name, 0, IFNAMSIZ);
-+ strncpy(dev_ipsec->name, name, IFNAMSIZ);
-+#endif /* NETDEV_23 */
-+ dev_ipsec->next = NULL;
-+ dev_ipsec->init = &ipsec_tunnel_probe;
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_init_devices: "
-+ "registering device %s\n",
-+ dev_ipsec->name);
-+
-+ /* reference and hold the device reference */
-+ dev_hold(dev_ipsec);
-+ ipsecdevices[i]=dev_ipsec;
-+
-+ if (register_netdev(dev_ipsec) != 0) {
-+ KLIPS_PRINT(1 || debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_init_devices: "
-+ "registering device %s failed, quitting device init.\n",
-+ dev_ipsec->name);
-+ return -EIO;
-+ } else {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_INIT,
-+ "klips_debug:ipsec_tunnel_init_devices: "
-+ "registering device %s succeeded, continuing...\n",
-+ dev_ipsec->name);
-+ }
-+ }
-+ return 0;
-+}
-+
-+/* void */
-+int
-+ipsec_tunnel_cleanup_devices(void)
-+{
-+ int error = 0;
-+ int i;
-+ char name[32];
-+ struct device *dev_ipsec;
-+
-+ for(i = 0; i < IPSEC_NUM_IF; i++) {
-+ dev_ipsec = ipsecdevices[i];
-+ if(dev_ipsec == NULL) {
-+ continue;
-+ }
-+
-+ /* release reference */
-+ ipsecdevices[i]=NULL;
-+ ipsec_dev_put(dev_ipsec);
-+
-+ KLIPS_PRINT(debug_tunnel, "Unregistering %s (refcnt=%d)\n",
-+ name,
-+ atomic_read(&dev_ipsec->refcnt));
-+ unregister_netdev(dev_ipsec);
-+ KLIPS_PRINT(debug_tunnel, "Unregisted %s\n", name);
-+#ifndef NETDEV_23
-+ kfree(dev_ipsec->name);
-+ dev_ipsec->name=NULL;
-+#endif /* !NETDEV_23 */
-+ kfree(dev_ipsec->priv);
-+ dev_ipsec->priv=NULL;
-+ }
-+ return error;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.220 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.219 2004/02/03 03:13:17 mcr
-+ * minor edits for readability, and error reporting.
-+ *
-+ * Revision 1.218 2004/01/27 20:29:20 mcr
-+ * fix for unregister_netdev() problem for underlying eth0.
-+ *
-+ * Revision 1.217 2003/12/10 01:14:27 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.216 2003/12/04 23:01:17 mcr
-+ * removed ipsec_netlink.h
-+ *
-+ * Revision 1.215 2003/12/04 16:35:16 ken
-+ * Fix for ATM devices where physdev->hard_header_len *is* correct
-+ *
-+ * Revision 1.214 2003/11/25 23:52:37 mcr
-+ * fix typo in patch - ixs-> needed.
-+ *
-+ * Revision 1.213 2003/11/24 18:25:49 mcr
-+ * patch from willy@w.ods.org to fix problems with ATM interfaces.
-+ *
-+ * Revision 1.212 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.211.2.2 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.211.2.1 2003/09/21 13:59:56 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.211 2003/09/10 16:46:30 mcr
-+ * patches for 2.4 backport/2.6 existence.
-+ *
-+ * Revision 1.210 2003/07/31 22:47:16 mcr
-+ * preliminary (untested by FS-team) 2.5 patches.
-+ *
-+ * Revision 1.209 2003/06/22 21:28:43 mcr
-+ * inability to unload module was caused by calls to dev_get
-+ * (ipsec_dev_get), to gather a device from a name. There is
-+ * simply no reason to look the devices up - they should be kept
-+ * in a nice array, ready for use.
-+ *
-+ * Revision 1.208 2003/06/22 21:25:07 mcr
-+ * all staticly counted ipsecXXX device support removed.
-+ *
-+ * Revision 1.207 2003/04/02 20:15:37 mcr
-+ * fix for PR#204 - do not clear connection tracking info if we
-+ * the packet is being sent in the clear.
-+ *
-+ * Revision 1.206 2003/02/12 19:32:51 rgb
-+ * Refactored file to:
-+ * ipsec_xmit.c
-+ * ipsec_xmit.h
-+ * ipsec_mast.c
-+ *
-+ * Revision 1.205 2003/02/06 17:47:00 rgb
-+ *
-+ * Remove unused ipsec_tunnel_lock() and ipsec_tunnel_unlock() code.
-+ * Refactor ipsec_tunnel_start_xmit() further into:
-+ * ipsec_xmit_sanity_check_dev()
-+ * ipsec_xmit_sanity_check_skb()
-+ * ipsec_xmit_strip_hard_header()
-+ * ipsec_xmit_restore_hard_header()
-+ * ipsec_xmit_send()
-+ * ipsec_xmit_cleanup()
-+ * and start a skeletal ipsec_mast_start_xmit() .
-+ *
-+ * Revision 1.204 2003/02/06 06:43:46 rgb
-+ *
-+ * Refactor ipsec_tunnel_start_xmit, bringing out:
-+ * ipsec_xmit_SAlookup
-+ * ipsec_xmit_encap_once
-+ * ipsec_xmit_encap_bundle
-+ *
-+ * Revision 1.203 2003/02/06 02:21:34 rgb
-+ *
-+ * Moved "struct auth_alg" from ipsec_rcv.c to ipsec_ah.h .
-+ * Changed "struct ah" to "struct ahhdr" and "struct esp" to "struct esphdr".
-+ * Removed "#ifdef INBOUND_POLICY_CHECK_eroute" dead code.
-+ *
-+ * Revision 1.202 2003/01/03 07:38:01 rgb
-+ *
-+ * Start to refactor ipsec_tunnel_start_xmit() by putting local variables
-+ * into struct ipsec_xmit_state and renaming a few variables to give more
-+ * unique or searchable names.
-+ *
-+ * Revision 1.201 2003/01/03 00:31:28 rgb
-+ *
-+ * Clean up memset usage, including fixing 2 places where keys were not
-+ * properly wiped.
-+ *
-+ * Revision 1.200 2002/12/06 02:24:02 mcr
-+ * patches for compiling against SUSE 8.1 kernels. Requires
-+ * an additional -DSUSE_LINUX_2_4_19_IS_STUPID.
-+ *
-+ * Revision 1.199 2002/10/12 23:11:53 dhr
-+ *
-+ * [KenB + DHR] more 64-bit cleanup
-+ *
-+ * Revision 1.198 2002/10/05 05:02:58 dhr
-+ *
-+ * C labels go on statements
-+ *
-+ * Revision 1.197 2002/09/20 05:01:50 rgb
-+ * Added compiler directive to switch on IP options and fix IP options bug.
-+ * Make ip->ihl treatment consistent using shifts rather than multiplications.
-+ * Check for large enough packet before accessing udp header for IKE bypass.
-+ * Added memory allocation debugging.
-+ * Fixed potential memory allocation failure-induced oops.
-+ *
-+ * Revision 1.196 2002/07/24 18:44:54 rgb
-+ * Type fiddling to tame ia64 compiler.
-+ *
-+ * Revision 1.195 2002/07/23 03:36:07 rgb
-+ * Fixed 2.2 device initialisation hang.
-+ *
-+ * Revision 1.194 2002/05/27 21:40:34 rgb
-+ * Set unused ipsec devices to ARPHRD_VOID to avoid confusing iproute2.
-+ * Cleaned up intermediate step to dynamic device allocation.
-+ *
-+ * Revision 1.193 2002/05/27 19:31:36 rgb
-+ * Convert to dynamic ipsec device allocation.
-+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
-+ *
-+ * Revision 1.192 2002/05/23 07:14:28 rgb
-+ * Added refcount code.
-+ * Cleaned up %p variants to 0p%p for test suite cleanup.
-+ *
-+ * Revision 1.191 2002/05/14 02:34:37 rgb
-+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
-+ * ipsec_sa or ipsec_sa.
-+ *
-+ * Revision 1.190 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.189 2002/04/24 07:36:32 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_tunnel.c,v
-+ *
-+ * Revision 1.188 2002/04/20 00:12:25 rgb
-+ * Added esp IV CBC attack fix, disabled.
-+ *
-+ * Revision 1.187 2002/03/23 19:55:17 rgb
-+ * Fix for 2.2 local IKE fragmentation blackhole. Still won't work if
-+ * iptraf or another pcap app is running.
-+ *
-+ * Revision 1.186 2002/03/19 03:26:22 rgb
-+ * Applied DHR's tunnel patch to streamline IKE/specialSA processing.
-+ *
-+ * Revision 1.185 2002/02/20 04:13:05 rgb
-+ * Send back ICMP_PKT_FILTERED upon %reject.
-+ *
-+ * Revision 1.184 2002/01/29 17:17:56 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.183 2002/01/29 04:00:53 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.182 2002/01/29 02:13:18 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.181 2002/01/07 20:00:33 rgb
-+ * Added IKE destination port debugging.
-+ *
-+ * Revision 1.180 2001/12/21 21:49:54 rgb
-+ * Fixed bug as a result of moving IKE bypass above %trap/%hold code.
-+ *
-+ * Revision 1.179 2001/12/19 21:08:14 rgb
-+ * Added transport protocol ports to ipsec_print_ip().
-+ * Update eroute info for non-SA targets.
-+ * Added obey DF code disabled.
-+ * Fixed formatting bugs in ipsec_tunnel_hard_header().
-+ *
-+ * Revision 1.178 2001/12/05 09:36:10 rgb
-+ * Moved the UDP/500 IKE check just above the %hold/%trap checks to avoid
-+ * IKE packets being stolen by the %hold (and returned to the sending KMd
-+ * in an ACQUIRE, ironically ;-).
-+ *
-+ * Revision 1.177 2001/11/26 09:23:50 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.170.2.1 2001/09/25 02:28:27 mcr
-+ * struct tdb -> struct ipsec_sa.
-+ * lifetime checks moved to common routines.
-+ * cleaned up includes.
-+ *
-+ * Revision 1.170.2.2 2001/10/22 21:08:01 mcr
-+ * include des.h, removed phony prototypes and fixed calling
-+ * conventions to match real prototypes.
-+ *
-+ * Revision 1.176 2001/11/09 18:32:31 rgb
-+ * Added Hans Schultz' fragmented UDP/500 IKE socket port selector.
-+ *
-+ * Revision 1.175 2001/11/06 20:47:00 rgb
-+ * Added Eric Espie's TRAPSUBNET fix, minus spin-lock-bh dabbling.
-+ *
-+ * Revision 1.174 2001/11/06 19:50:43 rgb
-+ * Moved IP_SEND, ICMP_SEND, DEV_QUEUE_XMIT macros to ipsec_tunnel.h for
-+ * use also by pfkey_v2_parser.c
-+ *
-+ * Revision 1.173 2001/10/29 21:53:44 henry
-+ * tone down the device-down message slightly, until we can make it smarter
-+ *
-+ * Revision 1.172 2001/10/26 04:59:37 rgb
-+ * Added a critical level syslog message if an ipsec device goes down.
-+ *
-+ * Revision 1.171 2001/10/18 04:45:21 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/freeswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.170 2001/09/25 00:09:50 rgb
-+ * Added NetCelo's TRAPSUBNET code to convert a new type TRAPSUBNET into a
-+ * HOLD.
-+ *
-+ * Revision 1.169 2001/09/15 16:24:05 rgb
-+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
-+ *
-+ * Revision 1.168 2001/09/14 16:58:37 rgb
-+ * Added support for storing the first and last packets through a HOLD.
-+ *
-+ * Revision 1.167 2001/09/08 21:13:33 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.166 2001/08/27 19:47:59 rgb
-+ * Clear tdb before usage.
-+ * Added comment: clear IF before calling routing?
-+ *
-+ * Revision 1.165 2001/07/03 01:23:53 rgb
-+ * Send back ICMP iff DF set, !ICMP, offset==0, sysctl_icmp, iph->tot_len >
-+ * emtu, and don't drop.
-+ *
-+ * Revision 1.164 2001/06/14 19:35:10 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.163 2001/06/06 20:28:51 rgb
-+ * Added sanity checks for NULL skbs and devices.
-+ * Added more debugging output to various functions.
-+ * Removed redundant dev->priv argument to ipsec_tunnel_{at,de}tach().
-+ * Renamed ipsec_tunnel_attach() virtual and physical device arguments.
-+ * Corrected neigh_setup() device function assignment.
-+ * Keep valid pointers to ipsec_tunnel_*() on detach.
-+ * Set dev->type to the originally-initiallised value.
-+ *
-+ * Revision 1.162 2001/06/01 07:28:04 rgb
-+ * Added sanity checks for detached devices. Don't down virtual devices
-+ * to prevent packets going out in the clear if the detached device comes
-+ * back up.
-+ *
-+ * Revision 1.161 2001/05/30 08:14:52 rgb
-+ * Removed vestiges of esp-null transforms.
-+ * NetDev Notifier instrumentation to track down disappearing devices.
-+ *
-+ * Revision 1.160 2001/05/29 05:15:12 rgb
-+ * Added SS' PMTU patch which notifies sender if packet doesn't fit
-+ * physical MTU (if it wasn't ICMP) and then drops it.
-+ *
-+ * Revision 1.159 2001/05/27 06:12:12 rgb
-+ * Added structures for pid, packet count and last access time to eroute.
-+ * Added packet count to beginning of /proc/net/ipsec_eroute.
-+ *
-+ * Revision 1.158 2001/05/24 05:39:33 rgb
-+ * Applied source zeroing to 2.2 ip_route_output() call as well to enable
-+ * PASS eroutes for opportunism.
-+ *
-+ * Revision 1.157 2001/05/23 22:35:28 rgb
-+ * 2.4 source override simplification.
-+ *
-+ * Revision 1.156 2001/05/23 21:41:31 rgb
-+ * Added error return code printing on ip_route_output().
-+ *
-+ * Revision 1.155 2001/05/23 05:09:13 rgb
-+ * Fixed incorrect ip_route_output() failure message.
-+ *
-+ * Revision 1.154 2001/05/21 14:53:31 rgb
-+ * Added debug statement for case when ip_route_output() fails, causing
-+ * packet to be dropped, but log looked ok.
-+ *
-+ * Revision 1.153 2001/05/19 02:37:54 rgb
-+ * Fixed missing comment termination.
-+ *
-+ * Revision 1.152 2001/05/19 02:35:50 rgb
-+ * Debug code optimisation for non-debug speed.
-+ * Kernel version compiler define comments.
-+ * 2.2 and 2.4 kernel ip_send device and ip debug output added.
-+ *
-+ * Revision 1.151 2001/05/18 16:17:35 rgb
-+ * Changed reference from "magic" to "shunt" SAs.
-+ *
-+ * Revision 1.150 2001/05/18 16:12:19 rgb
-+ * Changed UDP/500 bypass test from 3 nested ifs to one anded if.
-+ *
-+ * Revision 1.149 2001/05/16 04:39:33 rgb
-+ * Add default == eroute.dest to IKE bypass conditions for magic eroutes.
-+ *
-+ * Revision 1.148 2001/05/05 03:31:41 rgb
-+ * IP frag debugging updates and enhancements.
-+ *
-+ * Revision 1.147 2001/05/03 19:41:40 rgb
-+ * Added SS' skb_cow fix for 2.4.4.
-+ *
-+ * Revision 1.146 2001/04/30 19:28:16 rgb
-+ * Update for 2.4.4. ip_select_ident() now has 3 args.
-+ *
-+ * Revision 1.145 2001/04/23 14:56:10 rgb
-+ * Added spin_lock() check to prevent double-locking for multiple
-+ * transforms and hence kernel lock-ups with SMP kernels.
-+ *
-+ * Revision 1.144 2001/04/21 23:04:45 rgb
-+ * Define out skb->used for 2.4 kernels.
-+ * Check if soft expire has already been sent before sending another to
-+ * prevent ACQUIRE flooding.
-+ *
-+ * Revision 1.143 2001/03/16 07:37:21 rgb
-+ * Added comments to all #endifs.
-+ *
-+ * Revision 1.142 2001/02/28 05:03:27 rgb
-+ * Clean up and rationalise startup messages.
-+ *
-+ * Revision 1.141 2001/02/27 22:24:54 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.140 2001/02/27 06:40:12 rgb
-+ * Fixed TRAP->HOLD eroute byte order.
-+ *
-+ * Revision 1.139 2001/02/26 20:38:59 rgb
-+ * Added compiler defines for 2.4.x-specific code.
-+ *
-+ * Revision 1.138 2001/02/26 19:57:27 rgb
-+ * Implement magic SAs %drop, %reject, %trap, %hold, %pass as part
-+ * of the new SPD and to support opportunistic.
-+ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
-+ *
-+ * Revision 1.137 2001/02/19 22:29:49 rgb
-+ * Fixes for presence of active ipv6 segments which share ipsec physical
-+ * device (gg).
-+ *
-+ * Revision 1.136 2001/01/29 22:30:38 rgb
-+ * Fixed minor acquire debug printing bug.
-+ *
-+ * Revision 1.135 2001/01/29 22:19:45 rgb
-+ * Zero source address for 2.4 bypass route lookup.
-+ *
-+ * Revision 1.134 2001/01/23 20:19:49 rgb
-+ * 2.4 fix to remove removed is_clone member.
-+ *
-+ * Revision 1.133 2000/12/09 22:08:35 rgb
-+ * Fix NET_23 bug, should be NETDEV_23.
-+ *
-+ * Revision 1.132 2000/12/01 06:54:50 rgb
-+ * Fix for new 2.4 IP TTL default variable name.
-+ *
-+ * Revision 1.131 2000/11/09 20:52:15 rgb
-+ * More spinlock shuffling, locking earlier and unlocking later in rcv to
-+ * include ipcomp and prevent races, renaming some tdb variables that got
-+ * forgotten, moving some unlocks to include tdbs and adding a missing
-+ * unlock. Thanks to Svenning for some of these.
-+ *
-+ * Revision 1.130 2000/11/09 20:11:22 rgb
-+ * Minor shuffles to fix non-standard kernel config option selection.
-+ *
-+ * Revision 1.129 2000/11/06 04:32:49 rgb
-+ * Clean up debug printing.
-+ * Copy skb->protocol for all kernel versions.
-+ * Ditched spin_lock_irqsave in favour of spin_lock.
-+ * Disabled TTL decrement, done in ip_forward.
-+ * Added debug printing before pfkey_acquire().
-+ * Fixed printk-deltdbchain-spin_lock races (Svenning).
-+ * Use defaultTTL for 2.1+ kernels.
-+ * Add Svenning's adaptive content compression.
-+ * Fix up debug display arguments.
-+ *
-+ * Revision 1.128 2000/09/28 00:58:57 rgb
-+ * Moved the IKE passthrough check after the eroute lookup so we can pass
-+ * IKE through intermediate tunnels.
-+ *
-+ * Revision 1.127 2000/09/22 17:52:11 rgb
-+ * Fixed misleading ipcomp debug output.
-+ *
-+ * Revision 1.126 2000/09/22 04:22:56 rgb
-+ * Fixed dumb spi->cpi conversion error.
-+ *
-+ * Revision 1.125 2000/09/21 04:34:48 rgb
-+ * A few debug-specific things should be hidden under
-+ * CONFIG_IPSEC_DEBUG.(MB)
-+ * Improved ip_send() error handling.(MB)
-+ *
-+ * Revision 1.124 2000/09/21 03:40:58 rgb
-+ * Added more debugging to try and track down the cpi outward copy problem.
-+ *
-+ * Revision 1.123 2000/09/19 07:08:49 rgb
-+ * Added debugging to outgoing compression report.
-+ *
-+ * Revision 1.122 2000/09/18 19:21:26 henry
-+ * RGB-supplied fix for RH5.2 problem
-+ *
-+ * Revision 1.121 2000/09/17 21:05:09 rgb
-+ * Added tdb to skb_compress call to write in cpi.
-+ *
-+ * Revision 1.120 2000/09/17 16:57:16 rgb
-+ * Added Svenning's patch to remove restriction of ipcomp to innermost
-+ * transform.
-+ *
-+ * Revision 1.119 2000/09/15 11:37:01 rgb
-+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
-+ * IPCOMP zlib deflate code.
-+ *
-+ * Revision 1.118 2000/09/15 04:57:16 rgb
-+ * Moved debug output after sanity check.
-+ * Added tos copy sysctl.
-+ *
-+ * Revision 1.117 2000/09/12 03:22:51 rgb
-+ * Converted ipsec_icmp, no_eroute_pass, opportunistic and #if0 debugs to
-+ * sysctl.
-+ *
-+ * Revision 1.116 2000/09/08 19:18:19 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ * Added outgoing opportunistic hook, ifdef'ed out.
-+ *
-+ * Revision 1.115 2000/08/30 05:27:29 rgb
-+ * Removed all the rest of the references to tdb_spi, tdb_proto, tdb_dst.
-+ * Kill remainder of tdb_xform, tdb_xdata, xformsw.
-+ *
-+ * Revision 1.114 2000/08/28 18:15:46 rgb
-+ * Added MB's nf-debug reset patch.
-+ *
-+ * Revision 1.113 2000/08/27 02:26:40 rgb
-+ * Send all no-eroute-bypass, pluto-bypass and passthrough packets through
-+ * fragmentation machinery for 2.0, 2.2 and 2.4 kernels.
-+ *
-+ * Revision 1.112 2000/08/20 21:37:33 rgb
-+ * Activated pfkey_expire() calls.
-+ * Added a hard/soft expiry parameter to pfkey_expire(). (Momchil)
-+ * Re-arranged the order of soft and hard expiry to conform to RFC2367.
-+ * Clean up references to CONFIG_IPSEC_PFKEYv2.
-+ *
-+ * Revision 1.111 2000/08/01 14:51:51 rgb
-+ * Removed _all_ remaining traces of DES.
-+ *
-+ * Revision 1.110 2000/07/28 14:58:31 rgb
-+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
-+ *
-+ * Revision 1.109 2000/07/28 13:50:54 rgb
-+ * Changed enet_statistics to net_device_stats and added back compatibility
-+ * for pre-2.1.19.
-+ *
-+ * Revision 1.108 2000/05/16 03:03:11 rgb
-+ * Updates for 2.3.99pre8 from MB.
-+ *
-+ * Revision 1.107 2000/05/10 23:08:21 rgb
-+ * Print a debug warning about bogus packets received by the outgoing
-+ * processing machinery only when klipsdebug is not set to none.
-+ * Comment out the device initialisation informational messages.
-+ *
-+ * Revision 1.106 2000/05/10 19:17:14 rgb
-+ * Define an IP_SEND macro, intending to have all packet passthroughs
-+ * use fragmentation. This didn't quite work, but is a step in the
-+ * right direction.
-+ * Added buffer allocation debugging statements.
-+ * Added configure option to shut off no eroute passthrough.
-+ * Only check usetime against soft and hard limits if the tdb has been
-+ * used.
-+ * Cast output of ntohl so that the broken prototype doesn't make our
-+ * compile noisy.
-+ *
-+ * Revision 1.105 2000/03/22 16:15:37 rgb
-+ * Fixed renaming of dev_get (MB).
-+ *
-+ * Revision 1.104 2000/03/16 14:04:15 rgb
-+ * Indented headers for readability.
-+ * Fixed debug scope to enable compilation with debug off.
-+ * Added macros for ip_chk_addr and IS_MYADDR for identifying self.
-+ *
-+ * Revision 1.103 2000/03/16 07:11:07 rgb
-+ * Hardcode PF_KEYv2 support.
-+ * Fixed bug which allowed UDP/500 packet from another machine
-+ * through in the clear.
-+ * Added disabled skb->protocol fix for ISDN/ASYNC PPP from Matjaz Godec.
-+ *
-+ * Revision 1.102 2000/03/14 12:26:59 rgb
-+ * Added skb->nfct support for clearing netfilter conntrack bits (MB).
-+ *
-+ * Revision 1.101 2000/02/14 21:05:22 rgb
-+ * Added MB's netif_queue fix for kernels 2.3.43+.
-+ *
-+ * Revision 1.100 2000/01/26 10:04:57 rgb
-+ * Fixed noisy 2.0 printk arguments.
-+ *
-+ * Revision 1.99 2000/01/21 06:16:25 rgb
-+ * Added sanity checks on skb_push(), skb_pull() to prevent panics.
-+ * Switched to AF_ENCAP macro.
-+ * Shortened debug output per packet and re-arranging debug_tunnel
-+ * bitmap flags, while retaining necessary information to avoid
-+ * trampling the kernel print ring buffer.
-+ * Reformatted recursion switch code.
-+ * Changed all references to tdb_proto to tdb_said.proto for clarity.
-+ *
-+ * Revision 1.98 2000/01/13 08:09:31 rgb
-+ * Shuffled debug_tunnel switches to focus output.
-+ * Fixed outgoing recursion bug, limiting to recursing only if the remote
-+ * SG changes and if it is valid, ie. not passthrough.
-+ * Clarified a number of debug messages.
-+ *
-+ * Revision 1.97 2000/01/10 16:37:16 rgb
-+ * MB support for new ip_select_ident() upon disappearance of
-+ * ip_id_count in 2.3.36+.
-+ *
-+ * Revision 1.96 1999/12/31 14:59:08 rgb
-+ * MB fix to use new skb_copy_expand in kernel 2.3.35.
-+ *
-+ * Revision 1.95 1999/12/29 21:15:44 rgb
-+ * Fix tncfg to aliased device bug.
-+ *
-+ * Revision 1.94 1999/12/22 04:26:06 rgb
-+ * Converted all 'static' functions to 'DEBUG_NO_STATIC' to enable
-+ * debugging by providing external labels to all functions with debugging
-+ * turned on.
-+ *
-+ * Revision 1.93 1999/12/13 13:30:14 rgb
-+ * Changed MTU reports and HW address reporting back to debug only.
-+ *
-+ * Revision 1.92 1999/12/07 18:57:56 rgb
-+ * Fix PFKEY symbol compile error (SADB_*) without pfkey enabled.
-+ *
-+ * Revision 1.91 1999/12/01 22:15:36 rgb
-+ * Add checks for LARVAL and DEAD SAs.
-+ * Change state of SA from MATURE to DYING when a soft lifetime is
-+ * reached and print debug warning.
-+ *
-+ * Revision 1.90 1999/11/23 23:04:04 rgb
-+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
-+ * Sort out pfkey and freeswan headers, putting them in a library path.
-+ *
-+ * Revision 1.89 1999/11/18 18:50:59 rgb
-+ * Changed all device registrations for static linking to
-+ * dynamic to reduce the number and size of patches.
-+ *
-+ * Revision 1.88 1999/11/18 04:09:19 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ *
-+ * Revision 1.87 1999/11/17 15:53:40 rgb
-+ * Changed all occurrences of #include "../../../lib/freeswan.h"
-+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
-+ * klips/net/ipsec/Makefile.
-+ *
-+ * Revision 1.86 1999/10/16 18:25:37 rgb
-+ * Moved SA lifetime expiry checks before packet processing.
-+ * Expire SA on replay counter rollover.
-+ *
-+ * Revision 1.85 1999/10/16 04:24:31 rgb
-+ * Add stats for time since last packet.
-+ *
-+ * Revision 1.84 1999/10/16 00:30:47 rgb
-+ * Added SA lifetime counting.
-+ *
-+ * Revision 1.83 1999/10/15 22:15:57 rgb
-+ * Clean out cruft.
-+ * Add debugging.
-+ *
-+ * Revision 1.82 1999/10/08 18:26:19 rgb
-+ * Fix 2.0.3x outgoing fragmented packet memory leak.
-+ *
-+ * Revision 1.81 1999/10/05 02:38:54 rgb
-+ * Lower the default mtu of virtual devices to 16260.
-+ *
-+ * Revision 1.80 1999/10/03 18:56:41 rgb
-+ * Spinlock support for 2.3.xx.
-+ * Don't forget to undo spinlocks on error!
-+ * Check for valid eroute before copying the structure.
-+ *
-+ * Revision 1.79 1999/10/01 15:44:53 rgb
-+ * Move spinlock header include to 2.1> scope.
-+ *
-+ * Revision 1.78 1999/10/01 00:02:43 rgb
-+ * Added tdb structure locking.
-+ * Added eroute structure locking.
-+ *
-+ * Revision 1.77 1999/09/30 02:52:29 rgb
-+ * Add Marc Boucher's Copy-On-Write code (same as ipsec_rcv.c).
-+ *
-+ * Revision 1.76 1999/09/25 19:31:27 rgb
-+ * Refine MSS hack to affect SYN, but not SYN+ACK packets.
-+ *
-+ * Revision 1.75 1999/09/24 22:52:38 rgb
-+ * Fix two things broken in 2.0.38 by trying to fix network notifiers.
-+ *
-+ * Revision 1.74 1999/09/24 00:30:37 rgb
-+ * Add test for changed source as well as destination to check for
-+ * recursion.
-+ *
-+ * Revision 1.73 1999/09/23 20:52:24 rgb
-+ * Add James Morris' MSS hack patch, disabled.
-+ *
-+ * Revision 1.72 1999/09/23 20:22:40 rgb
-+ * Enable, tidy and fix network notifier code.
-+ *
-+ * Revision 1.71 1999/09/23 18:09:05 rgb
-+ * Clean up 2.2.x fragmenting traces.
-+ * Disable dev->type switching, forcing ARPHRD_TUNNEL.
-+ *
-+ * Revision 1.70 1999/09/22 14:14:24 rgb
-+ * Add sanity checks for revectored calls to prevent calling a downed I/F.
-+ *
-+ * Revision 1.69 1999/09/21 15:00:57 rgb
-+ * Add Marc Boucher's packet size check.
-+ * Flesh out network device notifier code.
-+ *
-+ * Revision 1.68 1999/09/18 11:39:57 rgb
-+ * Start to add (disabled) netdevice notifier code.
-+ *
-+ * Revision 1.67 1999/09/17 23:44:40 rgb
-+ * Add a comment warning potential code hackers to stay away from mac.raw.
-+ *
-+ * Revision 1.66 1999/09/17 18:04:02 rgb
-+ * Add fix for unpredictable hard_header_len for ISDN folks (thanks MB).
-+ * Ditch TTL decrement in 2.2 (MB).
-+ *
-+ * Revision 1.65 1999/09/15 23:15:35 henry
-+ * Marc Boucher's PPP fixes
-+ *
-+ * Revision 1.64 1999/09/07 13:40:53 rgb
-+ * Ditch unreliable references to skb->mac.raw.
-+ *
-+ * Revision 1.63 1999/08/28 11:33:09 rgb
-+ * Check for null skb->mac pointer.
-+ *
-+ * Revision 1.62 1999/08/28 02:02:30 rgb
-+ * Add Marc Boucher's fix for properly dealing with skb->sk.
-+ *
-+ * Revision 1.61 1999/08/27 05:23:05 rgb
-+ * Clean up skb->data/raw/nh/h manipulation.
-+ * Add Marc Boucher's mods to aid tcpdump.
-+ * Add sanity checks to skb->raw/nh/h pointer copies in skb_copy_expand.
-+ * Re-order hard_header stripping -- might be able to remove it...
-+ *
-+ * Revision 1.60 1999/08/26 20:01:02 rgb
-+ * Tidy up compiler directives and macros.
-+ * Re-enable ICMP for tunnels where inner_dst != outer_dst.
-+ * Remove unnecessary skb->dev = physdev assignment affecting 2.2.x.
-+ *
-+ * Revision 1.59 1999/08/25 15:44:41 rgb
-+ * Clean up from 2.2.x instrumenting for compilation under 2.0.36.
-+ *
-+ * Revision 1.58 1999/08/25 15:00:54 rgb
-+ * Add dst cache code for 2.2.xx.
-+ * Add sanity check for skb packet header pointers.
-+ * Add/modify debugging instrumentation to *_start_xmit, *_hard_header and
-+ * *_rebuild_header.
-+ * Add neigh_* cache code.
-+ * Change dev->type back to ARPHRD_TUNNEL.
-+ *
-+ * Revision 1.57 1999/08/17 21:50:23 rgb
-+ * Fixed minor debug output bugs.
-+ * Regrouped error recovery exit code.
-+ * Added compiler directives to remove unwanted code and symbols.
-+ * Shut off ICMP messages: to be refined to only send ICMP to remote systems.
-+ * Add debugging code for output function addresses.
-+ * Fix minor bug in (possibly unused) header_cache_bind function.
-+ * Add device neighbour caching code.
-+ * Change dev->type from ARPHRD_TUNNEL to physdev->type.
-+ *
-+ * Revision 1.56 1999/08/03 17:22:56 rgb
-+ * Debug output clarification using KERN_* macros. Other inactive changes
-+ * added.
-+ *
-+ * Revision 1.55 1999/08/03 16:58:46 rgb
-+ * Fix skb_copy_expand size bug. Was getting incorrect size.
-+ *
-+ * Revision 1.54 1999/07/14 19:32:38 rgb
-+ * Fix oversize packet crash and ssh stalling in 2.2.x kernels.
-+ *
-+ * Revision 1.53 1999/06/10 15:44:02 rgb
-+ * Minor reformatting and clean-up.
-+ *
-+ * Revision 1.52 1999/05/09 03:25:36 rgb
-+ * Fix bug introduced by 2.2 quick-and-dirty patch.
-+ *
-+ * Revision 1.51 1999/05/08 21:24:59 rgb
-+ * Add casting to silence the 2.2.x compile.
-+ *
-+ * Revision 1.50 1999/05/05 22:02:32 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.49 1999/04/29 15:18:52 rgb
-+ * Change gettdb parameter to a pointer to reduce stack loading and
-+ * facilitate parameter sanity checking.
-+ * Fix undetected bug that might have tried to access a null pointer.
-+ * Eliminate unnessessary usage of tdb_xform member to further switch
-+ * away from the transform switch to the algorithm switch.
-+ * Add return values to init and cleanup functions.
-+ *
-+ * Revision 1.48 1999/04/16 15:38:00 rgb
-+ * Minor rearrangement of freeing code to avoid memory leaks with impossible or
-+ * rare situations.
-+ *
-+ * Revision 1.47 1999/04/15 15:37:25 rgb
-+ * Forward check changes from POST1_00 branch.
-+ *
-+ * Revision 1.32.2.4 1999/04/13 21:00:18 rgb
-+ * Ditch 'things I wish I had known before...'.
-+ *
-+ * Revision 1.32.2.3 1999/04/13 20:34:38 rgb
-+ * Free skb after fragmentation.
-+ * Use stats more effectively.
-+ * Add I/F to mtu notch-down reporting.
-+ *
-+ * Revision 1.32.2.2 1999/04/02 04:26:14 rgb
-+ * Backcheck from HEAD, pre1.0.
-+ *
-+ * Revision 1.46 1999/04/11 00:29:00 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.45 1999/04/07 15:42:01 rgb
-+ * Fix mtu/ping bug AGAIN!
-+ *
-+ * Revision 1.44 1999/04/06 04:54:27 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.43 1999/04/04 03:57:07 rgb
-+ * ip_fragment() doesn't free the supplied skb. Freed.
-+ *
-+ * Revision 1.42 1999/04/01 23:27:15 rgb
-+ * Preload size of virtual mtu.
-+ *
-+ * Revision 1.41 1999/04/01 09:31:23 rgb
-+ * Invert meaning of ICMP PMTUD config option and clarify.
-+ * Code clean-up.
-+ *
-+ * Revision 1.40 1999/04/01 04:37:17 rgb
-+ * SSH stalling bug fix.
-+ *
-+ * Revision 1.39 1999/03/31 23:44:28 rgb
-+ * Don't send ICMP on DF and frag_off.
-+ *
-+ * Revision 1.38 1999/03/31 15:20:10 rgb
-+ * Quiet down debugging.
-+ *
-+ * Revision 1.37 1999/03/31 08:30:31 rgb
-+ * Add switch to shut off ICMP PMTUD packets.
-+ *
-+ * Revision 1.36 1999/03/31 05:44:47 rgb
-+ * Keep PMTU reduction private.
-+ *
-+ * Revision 1.35 1999/03/27 15:13:02 rgb
-+ * PMTU/fragmentation bug fix.
-+ *
-+ * Revision 1.34 1999/03/17 21:19:26 rgb
-+ * Fix kmalloc nonatomic bug.
-+ *
-+ * Revision 1.33 1999/03/17 15:38:42 rgb
-+ * Code clean-up.
-+ * ESP_NULL IV bug fix.
-+ *
-+ * Revision 1.32 1999/03/01 20:44:25 rgb
-+ * Code clean-up.
-+ * Memory leak bug fix.
-+ *
-+ * Revision 1.31 1999/02/27 00:02:09 rgb
-+ * Tune to report the MTU reduction once, rather than after every recursion
-+ * through the encapsulating code, preventing tcp stream stalling.
-+ *
-+ * Revision 1.30 1999/02/24 20:21:01 rgb
-+ * Reformat debug printk's.
-+ * Fix recursive encapsulation, dynamic MTU bugs and add debugging code.
-+ * Clean-up.
-+ *
-+ * Revision 1.29 1999/02/22 17:08:14 rgb
-+ * Fix recursive encapsulation code.
-+ *
-+ * Revision 1.28 1999/02/19 18:27:02 rgb
-+ * Improve DF, fragmentation and PMTU behaviour and add dynamic MTU discovery.
-+ *
-+ * Revision 1.27 1999/02/17 16:51:37 rgb
-+ * Clean out unused cruft.
-+ * Temporarily tone down volume of debug output.
-+ * Temporarily shut off fragment rejection.
-+ * Disabled temporary failed recursive encapsulation loop.
-+ *
-+ * Revision 1.26 1999/02/12 21:21:26 rgb
-+ * Move KLIPS_PRINT to ipsec_netlink.h for accessibility.
-+ *
-+ * Revision 1.25 1999/02/11 19:38:27 rgb
-+ * More clean-up.
-+ * Add sanity checking for skb_copy_expand() to prevent kernel panics on
-+ * skb_put() values out of range.
-+ * Fix head/tailroom calculation causing skb_put() out-of-range values.
-+ * Fix return values to prevent 'nonatomic alloc_skb' warnings.
-+ * Allocate new skb iff needed.
-+ * Added more debug statements.
-+ * Make headroom depend on structure, not hard-coded values.
-+ *
-+ * Revision 1.24 1999/02/10 23:20:33 rgb
-+ * Shut up annoying 'statement has no effect' compiler warnings with
-+ * debugging compiled out.
-+ *
-+ * Revision 1.23 1999/02/10 22:36:30 rgb
-+ * Clean-up obsolete, unused and messy code.
-+ * Converted most IPSEC_DEBUG statements to KLIPS_PRINT macros.
-+ * Rename ipsec_tunnel_do_xmit to ipsec_tunnel_start_xmit and eliminated
-+ * original ipsec_tunnel_start_xmit.
-+ * Send all packet with different inner and outer destinations directly to
-+ * the attached physical device, rather than back through ip_forward,
-+ * preventing disappearing routes problems.
-+ * Do sanity checking before investing too much CPU in allocating new
-+ * structures.
-+ * Fail on IP header options: We cannot process them yet.
-+ * Add some helpful comments.
-+ * Use virtual device for parameters instead of physical device.
-+ *
-+ * Revision 1.22 1999/02/10 03:03:02 rgb
-+ * Duh. Fixed the TTL bug: forgot to update the checksum.
-+ *
-+ * Revision 1.21 1999/02/09 23:17:53 rgb
-+ * Add structure members to ipsec_print_ip debug function.
-+ * Temporarily fix TTL bug preventing tunnel mode from functioning.
-+ *
-+ * Revision 1.20 1999/02/09 00:14:25 rgb
-+ * Add KLIPSPRINT macro. (Not used yet, though.)
-+ * Delete old ip_tunnel code (BADCODE).
-+ * Decrement TTL in outgoing packet.
-+ * Set TTL on new IPIP_TUNNEL to default, not existing packet TTL.
-+ * Delete ethernet only feature and fix hard-coded hard_header_len.
-+ *
-+ * Revision 1.19 1999/01/29 17:56:22 rgb
-+ * 64-bit re-fix submitted by Peter Onion.
-+ *
-+ * Revision 1.18 1999/01/28 22:43:24 rgb
-+ * Fixed bug in ipsec_print_ip that caused an OOPS, found by P.Onion.
-+ *
-+ * Revision 1.17 1999/01/26 02:08:16 rgb
-+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
-+ * Removed dead code.
-+ *
-+ * Revision 1.16 1999/01/22 06:25:26 rgb
-+ * Cruft clean-out.
-+ * Added algorithm switch code.
-+ * 64-bit clean-up.
-+ * Passthrough on IPIP protocol, spi 0x0 fix.
-+ * Enhanced debugging.
-+ *
-+ * Revision 1.15 1998/12/01 13:22:04 rgb
-+ * Added support for debug printing of version info.
-+ *
-+ * Revision 1.14 1998/11/30 13:22:55 rgb
-+ * Rationalised all the klips kernel file headers. They are much shorter
-+ * now and won't conflict under RH5.2.
-+ *
-+ * Revision 1.13 1998/11/17 21:13:52 rgb
-+ * Put IKE port bypass debug output in user-switched debug statements.
-+ *
-+ * Revision 1.12 1998/11/13 13:20:25 rgb
-+ * Fixed ntohs bug in udp/500 hole for IKE.
-+ *
-+ * Revision 1.11 1998/11/10 08:01:19 rgb
-+ * Kill tcp/500 hole, keep udp/500 hole.
-+ *
-+ * Revision 1.10 1998/11/09 21:29:26 rgb
-+ * If no eroute is found, discard packet and incr. tx_error.
-+ *
-+ * Revision 1.9 1998/10/31 06:50:00 rgb
-+ * Add tcp/udp/500 bypass.
-+ * Fixed up comments in #endif directives.
-+ *
-+ * Revision 1.8 1998/10/27 00:34:31 rgb
-+ * Reformat debug output of IP headers.
-+ * Newlines added before calls to ipsec_print_ip.
-+ *
-+ * Revision 1.7 1998/10/19 14:44:28 rgb
-+ * Added inclusion of freeswan.h.
-+ * sa_id structure implemented and used: now includes protocol.
-+ *
-+ * Revision 1.6 1998/10/09 04:31:35 rgb
-+ * Added 'klips_debug' prefix to all klips printk debug statements.
-+ *
-+ * Revision 1.5 1998/08/28 03:09:51 rgb
-+ * Prevent kernel log spam with default route through ipsec.
-+ *
-+ * Revision 1.4 1998/08/05 22:23:09 rgb
-+ * Change setdev return code to ENXIO for a non-existant physical device.
-+ *
-+ * Revision 1.3 1998/07/29 20:41:11 rgb
-+ * Add ipsec_tunnel_clear to clear all tunnel attachments.
-+ *
-+ * Revision 1.2 1998/06/25 20:00:33 rgb
-+ * Clean up #endif comments.
-+ * Rename dev_ipsec to dev_ipsec0 for consistency.
-+ * Document ipsec device fields.
-+ * Make ipsec_tunnel_probe visible from rest of kernel for static linking.
-+ * Get debugging report for *every* ipsec device initialisation.
-+ * Comment out redundant code.
-+ *
-+ * Revision 1.1 1998/06/18 21:27:50 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.8 1998/06/14 23:49:40 rgb
-+ * Clarify version reporting on module loading.
-+ *
-+ * Revision 1.7 1998/05/27 23:19:20 rgb
-+ * Added version reporting.
-+ *
-+ * Revision 1.6 1998/05/18 21:56:23 rgb
-+ * Clean up for numerical consistency of output and cleaning up debug code.
-+ *
-+ * Revision 1.5 1998/05/12 02:44:23 rgb
-+ * Clarifying 'no e-route to host' message.
-+ *
-+ * Revision 1.4 1998/04/30 15:34:35 rgb
-+ * Enclosed most remaining debugging statements in #ifdef's to make it quieter.
-+ *
-+ * Revision 1.3 1998/04/21 21:28:54 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.2 1998/04/12 22:03:24 rgb
-+ * Updated ESP-3DES-HMAC-MD5-96,
-+ * ESP-DES-HMAC-MD5-96,
-+ * AH-HMAC-MD5-96,
-+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
-+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
-+ *
-+ * Fixed eroute references in /proc/net/ipsec*.
-+ *
-+ * Started to patch module unloading memory leaks in ipsec_netlink and
-+ * radij tree unloading.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:12 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:04 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.5 1997/06/03 04:24:48 ji
-+ * Added transport mode.
-+ * Changed the way routing is done.
-+ * Lots of bug fixes.
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * No changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:39:04 ji
-+ * Minor cleanups.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ * Local Variables:
-+ * c-style: linux
-+ * End:
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_xform.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,351 @@
-+/*
-+ * Common routines for IPSEC transformations.
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "freeswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#include <linux/random.h> /* get_random_bytes() */
-+#include <freeswan.h>
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+#endif
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include "freeswan/radij.h"
-+#include "freeswan/ipsec_encap.h"
-+#include "freeswan/ipsec_radij.h"
-+#include "freeswan/ipsec_xform.h"
-+#include "freeswan/ipsec_ipe4.h"
-+#include "freeswan/ipsec_ah.h"
-+#include "freeswan/ipsec_esp.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_xform = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#ifdef SPINLOCK
-+spinlock_t tdb_lock = SPIN_LOCK_UNLOCKED;
-+#else /* SPINLOCK */
-+spinlock_t tdb_lock;
-+#endif /* SPINLOCK */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.63 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.62.30.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.62 2002/05/14 02:34:21 rgb
-+ * Delete stale code.
-+ *
-+ * Revision 1.61 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.60 2002/04/24 07:36:33 mcr
-+ * Moved from ./klips/net/ipsec/ipsec_xform.c,v
-+ *
-+ * Revision 1.59 2002/03/29 15:01:36 rgb
-+ * Delete decommissioned code.
-+ *
-+ * Revision 1.58 2002/01/29 17:17:57 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.57 2002/01/29 04:00:53 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.56 2001/11/27 05:17:22 mcr
-+ * turn off the worst of the per-packet debugging.
-+ *
-+ * Revision 1.55 2001/11/26 09:23:50 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.54 2001/10/18 04:45:21 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/freeswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.53 2001/09/08 21:13:34 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ *
-+ * Revision 1.52 2001/06/14 19:35:11 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.51 2001/05/30 08:14:03 rgb
-+ * Removed vestiges of esp-null transforms.
-+ *
-+ * Revision 1.50 2001/05/03 19:43:18 rgb
-+ * Initialise error return variable.
-+ * Update SENDERR macro.
-+ * Fix sign of error return code for ipsec_tdbcleanup().
-+ * Use more appropriate return code for ipsec_tdbwipe().
-+ *
-+ * Revision 1.49 2001/04/19 18:56:17 rgb
-+ * Fixed tdb table locking comments.
-+ *
-+ * Revision 1.48 2001/02/27 22:24:55 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.47 2000/11/06 04:32:08 rgb
-+ * Ditched spin_lock_irqsave in favour of spin_lock_bh.
-+ *
-+ * Revision 1.46 2000/09/20 16:21:57 rgb
-+ * Cleaned up ident string alloc/free.
-+ *
-+ * Revision 1.45 2000/09/08 19:16:51 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
-+ *
-+ * Revision 1.44 2000/08/30 05:29:04 rgb
-+ * Compiler-define out no longer used tdb_init() in ipsec_xform.c.
-+ *
-+ * Revision 1.43 2000/08/18 21:30:41 rgb
-+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
-+ *
-+ * Revision 1.42 2000/08/01 14:51:51 rgb
-+ * Removed _all_ remaining traces of DES.
-+ *
-+ * Revision 1.41 2000/07/28 14:58:31 rgb
-+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
-+ *
-+ * Revision 1.40 2000/06/28 05:50:11 rgb
-+ * Actually set iv_bits.
-+ *
-+ * Revision 1.39 2000/05/10 23:11:09 rgb
-+ * Added netlink debugging output.
-+ * Added a cast to quiet down the ntohl bug.
-+ *
-+ * Revision 1.38 2000/05/10 19:18:42 rgb
-+ * Cast output of ntohl so that the broken prototype doesn't make our
-+ * compile noisy.
-+ *
-+ * Revision 1.37 2000/03/16 14:04:59 rgb
-+ * Hardwired CONFIG_IPSEC_PFKEYv2 on.
-+ *
-+ * Revision 1.36 2000/01/26 10:11:28 rgb
-+ * Fixed spacing in error text causing run-in words.
-+ *
-+ * Revision 1.35 2000/01/21 06:17:16 rgb
-+ * Tidied up compiler directive indentation for readability.
-+ * Added ictx,octx vars for simplification.(kravietz)
-+ * Added macros for HMAC padding magic numbers.(kravietz)
-+ * Fixed missing key length reporting bug.
-+ * Fixed bug in tdbwipe to return immediately on NULL tdbp passed in.
-+ *
-+ * Revision 1.34 1999/12/08 00:04:19 rgb
-+ * Fixed SA direction overwriting bug for netlink users.
-+ *
-+ * Revision 1.33 1999/12/01 22:16:44 rgb
-+ * Minor formatting changes in ESP MD5 initialisation.
-+ *
-+ * Revision 1.32 1999/11/25 09:06:36 rgb
-+ * Fixed error return messages, should be returning negative numbers.
-+ * Implemented SENDERR macro for propagating error codes.
-+ * Added debug message and separate error code for algorithms not compiled
-+ * in.
-+ *
-+ * Revision 1.31 1999/11/23 23:06:26 rgb
-+ * Sort out pfkey and freeswan headers, putting them in a library path.
-+ *
-+ * Revision 1.30 1999/11/18 04:09:20 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ *
-+ * Revision 1.29 1999/11/17 15:53:40 rgb
-+ * Changed all occurrences of #include "../../../lib/freeswan.h"
-+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
-+ * klips/net/ipsec/Makefile.
-+ *
-+ * Revision 1.28 1999/10/18 20:04:01 rgb
-+ * Clean-out unused cruft.
-+ *
-+ * Revision 1.27 1999/10/03 19:01:03 rgb
-+ * Spinlock support for 2.3.xx and 2.0.xx kernels.
-+ *
-+ * Revision 1.26 1999/10/01 16:22:24 rgb
-+ * Switch from assignment init. to functional init. of spinlocks.
-+ *
-+ * Revision 1.25 1999/10/01 15:44:54 rgb
-+ * Move spinlock header include to 2.1> scope.
-+ *
-+ * Revision 1.24 1999/10/01 00:03:46 rgb
-+ * Added tdb structure locking.
-+ * Minor formatting changes.
-+ * Add function to initialize tdb hash table.
-+ *
-+ * Revision 1.23 1999/05/25 22:42:12 rgb
-+ * Add deltdbchain() debugging.
-+ *
-+ * Revision 1.22 1999/05/25 21:24:31 rgb
-+ * Add debugging statements to deltdbchain().
-+ *
-+ * Revision 1.21 1999/05/25 03:51:48 rgb
-+ * Refix error return code.
-+ *
-+ * Revision 1.20 1999/05/25 03:34:07 rgb
-+ * Fix error return for flush.
-+ *
-+ * Revision 1.19 1999/05/09 03:25:37 rgb
-+ * Fix bug introduced by 2.2 quick-and-dirty patch.
-+ *
-+ * Revision 1.18 1999/05/05 22:02:32 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.17 1999/04/29 15:20:16 rgb
-+ * Change gettdb parameter to a pointer to reduce stack loading and
-+ * facilitate parameter sanity checking.
-+ * Add sanity checking for null pointer arguments.
-+ * Add debugging instrumentation.
-+ * Add function deltdbchain() which will take care of unlinking,
-+ * zeroing and deleting a chain of tdbs.
-+ * Add a parameter to tdbcleanup to be able to delete a class of SAs.
-+ * tdbwipe now actually zeroes the tdb as well as any of its pointed
-+ * structures.
-+ *
-+ * Revision 1.16 1999/04/16 15:36:29 rgb
-+ * Fix cut-and-paste error causing a memory leak in IPIP TDB freeing.
-+ *
-+ * Revision 1.15 1999/04/11 00:29:01 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.14 1999/04/06 04:54:28 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.13 1999/02/19 18:23:01 rgb
-+ * Nix debug off compile warning.
-+ *
-+ * Revision 1.12 1999/02/17 16:52:16 rgb
-+ * Consolidate satoa()s for space and speed efficiency.
-+ * Convert DEBUG_IPSEC to KLIPS_PRINT
-+ * Clean out unused cruft.
-+ * Ditch NET_IPIP dependancy.
-+ * Loop for 3des key setting.
-+ *
-+ * Revision 1.11 1999/01/26 02:09:05 rgb
-+ * Remove ah/esp/IPIP switching on include files.
-+ * Removed CONFIG_IPSEC_ALGO_SWITCH macro.
-+ * Removed dead code.
-+ * Clean up debug code when switched off.
-+ * Remove references to INET_GET_PROTOCOL.
-+ * Added code exclusion macros to reduce code from unused algorithms.
-+ *
-+ * Revision 1.10 1999/01/22 06:28:55 rgb
-+ * Cruft clean-out.
-+ * Put random IV generation in kernel.
-+ * Added algorithm switch code.
-+ * Enhanced debugging.
-+ * 64-bit clean-up.
-+ *
-+ * Revision 1.9 1998/11/30 13:22:55 rgb
-+ * Rationalised all the klips kernel file headers. They are much shorter
-+ * now and won't conflict under RH5.2.
-+ *
-+ * Revision 1.8 1998/11/25 04:59:06 rgb
-+ * Add conditionals for no IPIP tunnel code.
-+ * Delete commented out code.
-+ *
-+ * Revision 1.7 1998/10/31 06:50:41 rgb
-+ * Convert xform ASCII names to no spaces.
-+ * Fixed up comments in #endif directives.
-+ *
-+ * Revision 1.6 1998/10/19 14:44:28 rgb
-+ * Added inclusion of freeswan.h.
-+ * sa_id structure implemented and used: now includes protocol.
-+ *
-+ * Revision 1.5 1998/10/09 04:32:19 rgb
-+ * Added 'klips_debug' prefix to all klips printk debug statements.
-+ *
-+ * Revision 1.4 1998/08/12 00:11:31 rgb
-+ * Added new xform functions to the xform table.
-+ * Fixed minor debug output spelling error.
-+ *
-+ * Revision 1.3 1998/07/09 17:45:31 rgb
-+ * Clarify algorithm not available message.
-+ *
-+ * Revision 1.2 1998/06/23 03:00:51 rgb
-+ * Check for presence of IPIP protocol if it is setup one way (we don't
-+ * know what has been set up the other way and can only assume it will be
-+ * symmetrical with the exception of keys).
-+ *
-+ * Revision 1.1 1998/06/18 21:27:51 henry
-+ * move sources from klips/src to klips/net/ipsec, to keep stupid
-+ * kernel-build scripts happier in the presence of symlinks
-+ *
-+ * Revision 1.3 1998/06/11 05:54:59 rgb
-+ * Added transform version string pointer to xformsw initialisations.
-+ *
-+ * Revision 1.2 1998/04/21 21:28:57 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:13 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:02 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.5 1997/06/03 04:24:48 ji
-+ * Added ESP-3DES-MD5-96
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * Added new transforms.
-+ *
-+ * Revision 0.3 1996/11/20 14:39:04 ji
-+ * Minor cleanups.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/ipsec_xmit.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1869 @@
-+/*
-+ * IPSEC Transmit code.
-+ * Copyright (C) 1996, 1997 John Ioannidis.
-+ * Copyright (C) 1998-2003 Richard Guy Briggs.
-+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ */
-+
-+char ipsec_xmit_c_version[] = "RCSID $Id$";
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/config.h> /* for CONFIG_IP_FORWARD */
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, struct net_device_stats, dev_queue_xmit() and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/tcp.h> /* struct tcphdr */
-+#include <linux/udp.h> /* struct udphdr */
-+#include <linux/skbuff.h>
-+#include <openswan.h>
-+#ifdef NET_21
-+# define MSS_HACK_ /* experimental */
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# include <net/dst.h>
-+# define proto_priv cb
-+#endif /* NET_21 */
-+#include <asm/checksum.h>
-+#include <net/icmp.h> /* icmp_send() */
-+#include <net/ip.h>
-+#ifdef NETDEV_23
-+# include <linux/netfilter_ipv4.h>
-+#endif /* NETDEV_23 */
-+
-+#include <linux/if_arp.h>
-+#ifdef MSS_HACK
-+# include <net/tcp.h> /* TCP options */
-+#endif /* MSS_HACK */
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_life.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_eroute.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xmit.h"
-+#include "openswan/ipsec_sa.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_ipe4.h"
-+#include "openswan/ipsec_ah.h"
-+#include "openswan/ipsec_esp.h"
-+
-+#ifdef CONFIG_IPSEC_IPCOMP
-+#include "openswan/ipcomp.h"
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+#include "openswan/ipsec_alg.h"
-+
-+
-+/*
-+ * Stupid kernel API differences in APIs. Not only do some
-+ * kernels not have ip_select_ident, but some have differing APIs,
-+ * and SuSE has one with one parameter, but no way of checking to
-+ * see what is really what.
-+ */
-+
-+#ifdef SUSE_LINUX_2_4_19_IS_STUPID
-+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph)
-+#else
-+
-+/* simplest case, nothing */
-+#if !defined(IP_SELECT_IDENT)
-+#define KLIPS_IP_SELECT_IDENT(iph, skb) do { iph->id = htons(ip_id_count++); } while(0)
-+#endif
-+
-+/* kernels > 2.3.37-ish */
-+#if defined(IP_SELECT_IDENT) && !defined(IP_SELECT_IDENT_NEW)
-+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst)
-+#endif
-+
-+/* kernels > 2.4.2 */
-+#if defined(IP_SELECT_IDENT) && defined(IP_SELECT_IDENT_NEW)
-+#define KLIPS_IP_SELECT_IDENT(iph, skb) ip_select_ident(iph, skb->dst, NULL)
-+#endif
-+
-+#endif /* SUSE_LINUX_2_4_19_IS_STUPID */
-+
-+
-+static __u32 zeroes[64];
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int sysctl_ipsec_debug_verbose = 0;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+int ipsec_xmit_trap_count = 0;
-+int ipsec_xmit_trap_sendcount = 0;
-+
-+int sysctl_ipsec_icmp = 0;
-+int sysctl_ipsec_tos = 0;
-+
-+#ifdef CONFIG_IPSEC_DEBUG_
-+DEBUG_NO_STATIC void
-+dmp(char *s, caddr_t bb, int len)
-+{
-+ int i;
-+ unsigned char *b = bb;
-+
-+ if (debug_tunnel) {
-+ printk(KERN_INFO "klips_debug:ipsec_tunnel_:dmp: "
-+ "at %s, len=%d:",
-+ s,
-+ len);
-+ for (i=0; i < len; i++) {
-+ if(!(i%16)){
-+ printk("\nklips_debug: ");
-+ }
-+ printk(" %02x", *b++);
-+ }
-+ printk("\n");
-+ }
-+}
-+#else /* CONFIG_IPSEC_DEBUG */
-+#define dmp(_x, _y, _z)
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#ifndef SKB_COPY_EXPAND
-+/*
-+ * This is mostly skbuff.c:skb_copy().
-+ */
-+struct sk_buff *
-+skb_copy_expand(struct sk_buff *skb, int headroom, int tailroom, int priority)
-+{
-+ struct sk_buff *n;
-+ unsigned long offset;
-+
-+ /*
-+ * Do sanity checking
-+ */
-+ if((headroom < 0) || (tailroom < 0) || ((headroom+tailroom) < 0)) {
-+ printk(KERN_WARNING
-+ "klips_error:skb_copy_expand: "
-+ "Illegal negative head,tailroom %d,%d\n",
-+ headroom,
-+ tailroom);
-+ return NULL;
-+ }
-+ /*
-+ * Allocate the copy buffer
-+ */
-+
-+#ifndef NET_21
-+ IS_SKB(skb);
-+#endif /* !NET_21 */
-+
-+
-+ n=alloc_skb(skb->end - skb->head + headroom + tailroom, priority);
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:skb_copy_expand: "
-+ "allocating %d bytes, head=0p%p data=0p%p tail=0p%p end=0p%p end-head=%d tail-data=%d\n",
-+ skb->end - skb->head + headroom + tailroom,
-+ skb->head,
-+ skb->data,
-+ skb->tail,
-+ skb->end,
-+ skb->end - skb->head,
-+ skb->tail - skb->data);
-+
-+ if(n==NULL)
-+ return NULL;
-+
-+ /*
-+ * Shift between the two data areas in bytes
-+ */
-+
-+ /* Set the data pointer */
-+ skb_reserve(n,skb->data-skb->head+headroom);
-+ /* Set the tail pointer and length */
-+ if(skb_tailroom(n) < skb->len) {
-+ printk(KERN_WARNING "klips_error:skb_copy_expand: "
-+ "tried to skb_put %ld, %d available. This should never happen, please report.\n",
-+ (unsigned long int)skb->len,
-+ skb_tailroom(n));
-+ ipsec_kfree_skb(n);
-+ return NULL;
-+ }
-+ skb_put(n,skb->len);
-+
-+ offset=n->head + headroom - skb->head;
-+
-+ /* Copy the bytes */
-+ memcpy(n->head + headroom, skb->head,skb->end-skb->head);
-+#ifdef NET_21
-+ n->csum=skb->csum;
-+ n->priority=skb->priority;
-+ n->dst=dst_clone(skb->dst);
-+ if(skb->nh.raw)
-+ n->nh.raw=skb->nh.raw+offset;
-+#ifndef NETDEV_23
-+ n->is_clone=0;
-+#endif /* NETDEV_23 */
-+ atomic_set(&n->users, 1);
-+ n->destructor = NULL;
-+ n->security=skb->security;
-+#else /* NET_21 */
-+ n->link3=NULL;
-+ n->when=skb->when;
-+ if(skb->ip_hdr)
-+ n->ip_hdr=(struct iphdr *)(((char *)skb->ip_hdr)+offset);
-+ n->saddr=skb->saddr;
-+ n->daddr=skb->daddr;
-+ n->raddr=skb->raddr;
-+ n->seq=skb->seq;
-+ n->end_seq=skb->end_seq;
-+ n->ack_seq=skb->ack_seq;
-+ n->acked=skb->acked;
-+ n->free=1;
-+ n->arp=skb->arp;
-+ n->tries=0;
-+ n->lock=0;
-+ n->users=0;
-+#endif /* NET_21 */
-+ n->protocol=skb->protocol;
-+ n->list=NULL;
-+ n->sk=NULL;
-+ n->dev=skb->dev;
-+ if(skb->h.raw)
-+ n->h.raw=skb->h.raw+offset;
-+ if(skb->mac.raw)
-+ n->mac.raw=skb->mac.raw+offset;
-+ memcpy(n->proto_priv, skb->proto_priv, sizeof(skb->proto_priv));
-+#ifndef NETDEV_23
-+ n->used=skb->used;
-+#endif /* !NETDEV_23 */
-+ n->pkt_type=skb->pkt_type;
-+ n->stamp=skb->stamp;
-+
-+#ifndef NET_21
-+ IS_SKB(n);
-+#endif /* !NET_21 */
-+ return n;
-+}
-+#endif /* !SKB_COPY_EXPAND */
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+void
-+ipsec_print_ip(struct iphdr *ip)
-+{
-+ char buf[ADDRTOA_BUF];
-+
-+ printk(KERN_INFO "klips_debug: IP:");
-+ printk(" ihl:%d", ip->ihl << 2);
-+ printk(" ver:%d", ip->version);
-+ printk(" tos:%d", ip->tos);
-+ printk(" tlen:%d", ntohs(ip->tot_len));
-+ printk(" id:%d", ntohs(ip->id));
-+ printk(" %s%s%sfrag_off:%d",
-+ ip->frag_off & __constant_htons(IP_CE) ? "CE " : "",
-+ ip->frag_off & __constant_htons(IP_DF) ? "DF " : "",
-+ ip->frag_off & __constant_htons(IP_MF) ? "MF " : "",
-+ (ntohs(ip->frag_off) & IP_OFFSET) << 3);
-+ printk(" ttl:%d", ip->ttl);
-+ printk(" proto:%d", ip->protocol);
-+ if(ip->protocol == IPPROTO_UDP)
-+ printk(" (UDP)");
-+ if(ip->protocol == IPPROTO_TCP)
-+ printk(" (TCP)");
-+ if(ip->protocol == IPPROTO_ICMP)
-+ printk(" (ICMP)");
-+ printk(" chk:%d", ntohs(ip->check));
-+ addrtoa(*((struct in_addr*)(&ip->saddr)), 0, buf, sizeof(buf));
-+ printk(" saddr:%s", buf);
-+ if(ip->protocol == IPPROTO_UDP)
-+ printk(":%d",
-+ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
-+ if(ip->protocol == IPPROTO_TCP)
-+ printk(":%d",
-+ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->source));
-+ addrtoa(*((struct in_addr*)(&ip->daddr)), 0, buf, sizeof(buf));
-+ printk(" daddr:%s", buf);
-+ if(ip->protocol == IPPROTO_UDP)
-+ printk(":%d",
-+ ntohs(((struct udphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
-+ if(ip->protocol == IPPROTO_TCP)
-+ printk(":%d",
-+ ntohs(((struct tcphdr*)((caddr_t)ip + (ip->ihl << 2)))->dest));
-+ if(ip->protocol == IPPROTO_ICMP)
-+ printk(" type:code=%d:%d",
-+ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->type,
-+ ((struct icmphdr*)((caddr_t)ip + (ip->ihl << 2)))->code);
-+ printk("\n");
-+
-+ if(sysctl_ipsec_debug_verbose) {
-+ __u8 *c;
-+ int i;
-+
-+ c = ((__u8*)ip) + ip->ihl*4;
-+ for(i = 0; i < ntohs(ip->tot_len) - ip->ihl*4; i++ /*, c++*/) {
-+ if(!(i % 16)) {
-+ printk(KERN_INFO
-+ "klips_debug: @%03x:",
-+ i);
-+ }
-+ printk(" %02x", /***/c[i]);
-+ if(!((i + 1) % 16)) {
-+ printk("\n");
-+ }
-+ }
-+ if(i % 16) {
-+ printk("\n");
-+ }
-+ }
-+}
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#ifdef MSS_HACK
-+/*
-+ * Issues:
-+ * 1) Fragments arriving in the tunnel should probably be rejected.
-+ * 2) How does this affect syncookies, mss_cache, dst cache ?
-+ * 3) Path MTU discovery handling needs to be reviewed. For example,
-+ * if we receive an ICMP 'packet too big' message from an intermediate
-+ * router specifying it's next hop MTU, our stack may process this and
-+ * adjust the MSS without taking our AH/ESP overheads into account.
-+ */
-+
-+
-+/*
-+ * Recaclulate checksum using differences between changed datum,
-+ * borrowed from netfilter.
-+ */
-+DEBUG_NO_STATIC u_int16_t
-+ipsec_fast_csum(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck)
-+{
-+ u_int32_t diffs[] = { oldvalinv, newval };
-+ return csum_fold(csum_partial((char *)diffs, sizeof(diffs),
-+ oldcheck^0xFFFF));
-+}
-+
-+/*
-+ * Determine effective MSS.
-+ *
-+ * Note that we assume that there is always an MSS option for our own
-+ * SYN segments, which is mentioned in tcp_syn_build_options(), kernel 2.2.x.
-+ * This could change, and we should probably parse TCP options instead.
-+ *
-+ */
-+DEBUG_NO_STATIC u_int8_t
-+ipsec_adjust_mss(struct sk_buff *skb, struct tcphdr *tcph, u_int16_t mtu)
-+{
-+ u_int16_t oldmss, newmss;
-+ u_int32_t *mssp;
-+ struct sock *sk = skb->sk;
-+
-+ newmss = tcp_sync_mss(sk, mtu);
-+ printk(KERN_INFO "klips: setting mss to %u\n", newmss);
-+ mssp = (u_int32_t *)tcph + sizeof(struct tcphdr) / sizeof(u_int32_t);
-+ oldmss = ntohl(*mssp) & 0x0000FFFF;
-+ *mssp = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | newmss);
-+ tcph->check = ipsec_fast_csum(htons(~oldmss),
-+ htons(newmss), tcph->check);
-+ return 1;
-+}
-+#endif /* MSS_HACK */
-+
-+/*
-+ * Sanity checks
-+ */
-+enum ipsec_xmit_value
-+ipsec_xmit_sanity_check_dev(struct ipsec_xmit_state *ixs)
-+{
-+
-+ if (ixs->dev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_error:ipsec_xmit_sanity_check_dev: "
-+ "No device associated with skb!\n" );
-+ return IPSEC_XMIT_NODEV;
-+ }
-+
-+ ixs->prv = ixs->dev->priv;
-+ if (ixs->prv == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_error:ipsec_xmit_sanity_check_dev: "
-+ "Device has no private structure!\n" );
-+ return IPSEC_XMIT_NOPRIVDEV;
-+ }
-+
-+ ixs->physdev = ixs->prv->dev;
-+ if (ixs->physdev == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_error:ipsec_xmit_sanity_check_dev: "
-+ "Device is not attached to physical device!\n" );
-+ return IPSEC_XMIT_NOPHYSDEV;
-+ }
-+
-+ ixs->physmtu = ixs->physdev->mtu;
-+
-+ ixs->stats = (struct net_device_stats *) &(ixs->prv->mystats);
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_sanity_check_skb(struct ipsec_xmit_state *ixs)
-+{
-+ /*
-+ * Return if there is nothing to do. (Does this ever happen?) XXX
-+ */
-+ if (ixs->skb == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_error:ipsec_xmit_sanity_check_skb: "
-+ "Nothing to do!\n" );
-+ return IPSEC_XMIT_NOSKB;
-+ }
-+#ifdef NET_21
-+ /* if skb was cloned (most likely due to a packet sniffer such as
-+ tcpdump being momentarily attached to the interface), make
-+ a copy of our own to modify */
-+ if(skb_cloned(ixs->skb)) {
-+ if
-+#ifdef SKB_COW_NEW
-+ (skb_cow(ixs->skb, skb_headroom(ixs->skb)) != 0)
-+#else /* SKB_COW_NEW */
-+ ((ixs->skb = skb_cow(ixs->skb, skb_headroom(ixs->skb))) == NULL)
-+#endif /* SKB_COW_NEW */
-+ {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_error:ipsec_xmit_sanity_check_skb: "
-+ "skb_cow failed to allocate buffer, dropping.\n" );
-+ ixs->stats->tx_dropped++;
-+ return IPSEC_XMIT_ERRSKBALLOC;
-+ }
-+ }
-+#endif /* NET_21 */
-+
-+#ifdef NET_21
-+ ixs->iph = ixs->skb->nh.iph;
-+#else /* NET_21 */
-+ ixs->iph = ixs->skb->ip_hdr;
-+#endif /* NET_21 */
-+
-+ /* sanity check for IP version as we can't handle IPv6 right now */
-+ if (ixs->iph->version != 4) {
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_xmit_sanity_check_skb: "
-+ "found IP Version %d but cannot process other IP versions than v4.\n",
-+ ixs->iph->version); /* XXX */
-+ ixs->stats->tx_dropped++;
-+ return IPSEC_XMIT_NOIPV6;
-+ }
-+
-+#if IPSEC_DISALLOW_IPOPTIONS
-+ if ((ixs->iph->ihl << 2) != sizeof (struct iphdr)) {
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_xmit_sanity_check_skb: "
-+ "cannot process IP header options yet. May be mal-formed packet.\n"); /* XXX */
-+ ixs->stats->tx_dropped++;
-+ return IPSEC_XMIT_NOIPOPTIONS;
-+ }
-+#endif /* IPSEC_DISALLOW_IPOPTIONS */
-+
-+#ifndef NET_21
-+ if (ixs->iph->ttl <= 0) {
-+ /* Tell the sender its packet died... */
-+ ICMP_SEND(ixs->skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0, ixs->physdev);
-+
-+ KLIPS_PRINT(debug_tunnel, "klips_debug:ipsec_xmit_sanity_check_skb: "
-+ "TTL=0, too many hops!\n");
-+ ixs->stats->tx_dropped++;
-+ return IPSEC_XMIT_TTLEXPIRED;
-+ }
-+#endif /* !NET_21 */
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_encap_once(struct ipsec_xmit_state *ixs)
-+{
-+#ifdef CONFIG_IPSEC_ESP
-+ struct esphdr *espp;
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ __u32 iv[ESP_IV_MAXSZ_INT];
-+#endif /* !CONFIG_IPSEC_ENC_3DES */
-+ unsigned char *idat, *pad;
-+ int authlen = 0, padlen = 0, i;
-+#endif /* !CONFIG_IPSEC_ESP */
-+#ifdef CONFIG_IPSEC_AH
-+ struct iphdr ipo;
-+ struct ahhdr *ahp;
-+#endif /* CONFIG_IPSEC_AH */
-+#if defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1)
-+ union {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ MD5_CTX md5;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ SHA1_CTX sha1;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ } tctx;
-+ __u8 hash[AH_AMAX];
-+#endif /* defined(CONFIG_IPSEC_AUTH_HMAC_MD5) || defined(CONFIG_IPSEC_AUTH_HMAC_SHA1) */
-+ int headroom = 0, tailroom = 0, ilen = 0, len = 0;
-+ unsigned char *dat;
-+ int blocksize = 8; /* XXX: should be inside ixs --jjo */
-+#ifdef CONFIG_IPSEC_ALG
-+ struct ipsec_alg_enc *ixt_e = NULL;
-+ struct ipsec_alg_auth *ixt_a = NULL;
-+#endif /* CONFIG_IPSEC_ALG */
-+
-+ ixs->iphlen = ixs->iph->ihl << 2;
-+ ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
-+ ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, SATOT_BUF);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_OXFS,
-+ "klips_debug:ipsec_xmit_encap_once: "
-+ "calling output for <%s%s%s>, SA:%s\n",
-+ IPS_XFORM_NAME(ixs->ipsp),
-+ ixs->sa_len ? ixs->sa_txt : " (error)");
-+
-+ switch(ixs->ipsp->ips_said.proto) {
-+#ifdef CONFIG_IPSEC_AH
-+ case IPPROTO_AH:
-+ headroom += sizeof(struct ahhdr);
-+ break;
-+#endif /* CONFIG_IPSEC_AH */
-+#ifdef CONFIG_IPSEC_ESP
-+ case IPPROTO_ESP:
-+#ifdef CONFIG_IPSEC_ALG
-+ if ((ixt_e=ixs->ipsp->ips_alg_enc)) {
-+ blocksize = ixt_e->ixt_blocksize;
-+ headroom += ESP_HEADER_LEN + ixt_e->ixt_ivlen/8;
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ixs->ipsp->ips_encalg) {
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+ headroom += sizeof(struct esphdr);
-+ break;
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_BADALG;
-+ }
-+#ifdef CONFIG_IPSEC_ALG
-+ if ((ixt_a=ixs->ipsp->ips_alg_auth)) {
-+ tailroom += AHHMAC_HASHLEN;
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ixs->ipsp->ips_authalg) {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5:
-+ authlen = AHHMAC_HASHLEN;
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA:
-+ authlen = AHHMAC_HASHLEN;
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ case AH_NONE:
-+ break;
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_BADALG;
-+ }
-+#ifdef CONFIG_IPSEC_ALG
-+ tailroom += blocksize != 1 ?
-+ ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 :
-+ ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
-+#else
-+ tailroom += ((8 - ((ixs->pyldsz + 2 * sizeof(unsigned char)) % 8)) % 8) + 2;
-+#endif /* CONFIG_IPSEC_ALG */
-+ tailroom += authlen;
-+ break;
-+#endif /* !CONFIG_IPSEC_ESP */
-+#ifdef CONFIG_IPSEC_IPIP
-+ case IPPROTO_IPIP:
-+ headroom += sizeof(struct iphdr);
-+ ixs->iphlen = sizeof(struct iphdr);
-+ break;
-+#endif /* !CONFIG_IPSEC_IPIP */
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ case IPPROTO_COMP:
-+ break;
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_BADPROTO;
-+ }
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_once: "
-+ "pushing %d bytes, putting %d, proto %d.\n",
-+ headroom, tailroom, ixs->ipsp->ips_said.proto);
-+ if(skb_headroom(ixs->skb) < headroom) {
-+ printk(KERN_WARNING
-+ "klips_error:ipsec_xmit_encap_once: "
-+ "tried to skb_push headroom=%d, %d available. This should never happen, please report.\n",
-+ headroom, skb_headroom(ixs->skb));
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_PUSHPULLERR;
-+ }
-+ dat = skb_push(ixs->skb, headroom);
-+ ilen = ixs->skb->len - tailroom;
-+ if(skb_tailroom(ixs->skb) < tailroom) {
-+ printk(KERN_WARNING
-+ "klips_error:ipsec_xmit_encap_once: "
-+ "tried to skb_put %d, %d available. This should never happen, please report.\n",
-+ tailroom, skb_tailroom(ixs->skb));
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_PUSHPULLERR;
-+ }
-+ skb_put(ixs->skb, tailroom);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_once: "
-+ "head,tailroom: %d,%d before xform.\n",
-+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
-+ len = ixs->skb->len;
-+ if(len > 0xfff0) {
-+ printk(KERN_WARNING "klips_error:ipsec_xmit_encap_once: "
-+ "tot_len (%d) > 65520. This should never happen, please report.\n",
-+ len);
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_BADLEN;
-+ }
-+ memmove((void *)dat, (void *)(dat + headroom), ixs->iphlen);
-+ ixs->iph = (struct iphdr *)dat;
-+ ixs->iph->tot_len = htons(ixs->skb->len);
-+
-+ switch(ixs->ipsp->ips_said.proto) {
-+#ifdef CONFIG_IPSEC_ESP
-+ case IPPROTO_ESP:
-+ espp = (struct esphdr *)(dat + ixs->iphlen);
-+ espp->esp_spi = ixs->ipsp->ips_said.spi;
-+ espp->esp_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if (!ixt_e)
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ixs->ipsp->ips_encalg) {
-+#if defined(CONFIG_IPSEC_ENC_3DES)
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ iv[0] = *((__u32*)&(espp->esp_iv) ) =
-+ ((__u32*)(ixs->ipsp->ips_iv))[0];
-+ iv[1] = *((__u32*)&(espp->esp_iv) + 1) =
-+ ((__u32*)(ixs->ipsp->ips_iv))[1];
-+ break;
-+#endif /* defined(CONFIG_IPSEC_ENC_3DES) */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_BADALG;
-+ }
-+
-+ idat = dat + ixs->iphlen + headroom;
-+ ilen = len - (ixs->iphlen + headroom + authlen);
-+
-+ /* Self-describing padding */
-+ pad = &dat[len - tailroom];
-+ padlen = tailroom - 2 - authlen;
-+ for (i = 0; i < padlen; i++) {
-+ pad[i] = i + 1;
-+ }
-+ dat[len - authlen - 2] = padlen;
-+
-+ dat[len - authlen - 1] = ixs->iph->protocol;
-+ ixs->iph->protocol = IPPROTO_ESP;
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ /* Do all operations here:
-+ * copy IV->ESP, encrypt, update ips IV
-+ */
-+ if (ixt_e) {
-+ int ret;
-+ memcpy(espp->esp_iv,
-+ ixs->ipsp->ips_iv,
-+ ixt_e->ixt_ivlen/8);
-+ ret=ipsec_alg_esp_encrypt(ixs->ipsp,
-+ idat, ilen, espp->esp_iv,
-+ IPSEC_ALG_ENCRYPT);
-+ memcpy(ixs->ipsp->ips_iv,
-+ idat + ilen - ixt_e->ixt_ivlen/8,
-+ ixt_e->ixt_ivlen/8);
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ixs->ipsp->ips_encalg) {
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+ des_ede3_cbc_encrypt((des_cblock *)idat,
-+ (des_cblock *)idat,
-+ ilen,
-+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[0].ks,
-+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[1].ks,
-+ ((struct des_eks *)(ixs->ipsp->ips_key_e))[2].ks,
-+ (des_cblock *)iv, 1);
-+ break;
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_BADALG;
-+ }
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if (!ixt_e)
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ixs->ipsp->ips_encalg) {
-+#if defined(CONFIG_IPSEC_ENC_3DES)
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ /* XXX update IV with the last 8 octets of the encryption */
-+#if KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK
-+ ((__u32*)(ixs->ipsp->ips_iv))[0] =
-+ ((__u32 *)(idat))[(ilen >> 2) - 2];
-+ ((__u32*)(ixs->ipsp->ips_iv))[1] =
-+ ((__u32 *)(idat))[(ilen >> 2) - 1];
-+#else /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
-+ prng_bytes(&ipsec_prng, (char *)ixs->ipsp->ips_iv, EMT_ESPDES_IV_SZ);
-+#endif /* KLIPS_IMPAIRMENT_ESPIV_CBC_ATTACK */
-+ break;
-+#endif /* defined(CONFIG_IPSEC_ENC_3DES) */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_ESP_BADALG;
-+ }
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if (ixt_a) {
-+ ipsec_alg_sa_esp_hash(ixs->ipsp,
-+ (caddr_t)espp, len - ixs->iphlen - authlen,
-+ &(dat[len - authlen]), authlen);
-+
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ixs->ipsp->ips_authalg) {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5:
-+ dmp("espp", (char*)espp, len - ixs->iphlen - authlen);
-+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
-+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, (caddr_t)espp, len - ixs->iphlen - authlen);
-+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Final(hash, &tctx.md5);
-+ dmp("ictx hash", (char*)&hash, sizeof(hash));
-+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
-+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, hash, AHMD596_ALEN);
-+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Final(hash, &tctx.md5);
-+ dmp("octx hash", (char*)&hash, sizeof(hash));
-+ memcpy(&(dat[len - authlen]), hash, authlen);
-+
-+ /* paranoid */
-+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
-+ memset((caddr_t)hash, 0, sizeof(*hash));
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA:
-+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
-+ SHA1Update(&tctx.sha1, (caddr_t)espp, len - ixs->iphlen - authlen);
-+ SHA1Final(hash, &tctx.sha1);
-+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
-+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
-+ SHA1Final(hash, &tctx.sha1);
-+ memcpy(&(dat[len - authlen]), hash, authlen);
-+
-+ /* paranoid */
-+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
-+ memset((caddr_t)hash, 0, sizeof(*hash));
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ case AH_NONE:
-+ break;
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_AH_BADALG;
-+ }
-+#ifdef NET_21
-+ ixs->skb->h.raw = (unsigned char*)espp;
-+#endif /* NET_21 */
-+ break;
-+#endif /* !CONFIG_IPSEC_ESP */
-+#ifdef CONFIG_IPSEC_AH
-+ case IPPROTO_AH:
-+ ahp = (struct ahhdr *)(dat + ixs->iphlen);
-+ ahp->ah_spi = ixs->ipsp->ips_said.spi;
-+ ahp->ah_rpl = htonl(++(ixs->ipsp->ips_replaywin_lastseq));
-+ ahp->ah_rv = 0;
-+ ahp->ah_nh = ixs->iph->protocol;
-+ ahp->ah_hl = (headroom >> 2) - sizeof(__u64)/sizeof(__u32);
-+ ixs->iph->protocol = IPPROTO_AH;
-+ dmp("ahp", (char*)ahp, sizeof(*ahp));
-+
-+ ipo = *ixs->iph;
-+ ipo.tos = 0;
-+ ipo.frag_off = 0;
-+ ipo.ttl = 0;
-+ ipo.check = 0;
-+ dmp("ipo", (char*)&ipo, sizeof(ipo));
-+
-+ switch(ixs->ipsp->ips_authalg) {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5:
-+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->ictx;
-+ dmp("ictx", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, (unsigned char *)&ipo, sizeof (struct iphdr));
-+ dmp("ictx+ipo", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
-+ dmp("ictx+ahp", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, (unsigned char *)zeroes, AHHMAC_HASHLEN);
-+ dmp("ictx+zeroes", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom);
-+ dmp("ictx+dat", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Final(hash, &tctx.md5);
-+ dmp("ictx hash", (char*)&hash, sizeof(hash));
-+ tctx.md5 = ((struct md5_ctx*)(ixs->ipsp->ips_key_a))->octx;
-+ dmp("octx", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Update(&tctx.md5, hash, AHMD596_ALEN);
-+ dmp("octx+hash", (char*)&tctx.md5, sizeof(tctx.md5));
-+ MD5Final(hash, &tctx.md5);
-+ dmp("octx hash", (char*)&hash, sizeof(hash));
-+
-+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
-+
-+ /* paranoid */
-+ memset((caddr_t)&tctx.md5, 0, sizeof(tctx.md5));
-+ memset((caddr_t)hash, 0, sizeof(*hash));
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA:
-+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->ictx;
-+ SHA1Update(&tctx.sha1, (unsigned char *)&ipo, sizeof (struct iphdr));
-+ SHA1Update(&tctx.sha1, (unsigned char *)ahp, headroom - sizeof(ahp->ah_data));
-+ SHA1Update(&tctx.sha1, (unsigned char *)zeroes, AHHMAC_HASHLEN);
-+ SHA1Update(&tctx.sha1, dat + ixs->iphlen + headroom, len - ixs->iphlen - headroom);
-+ SHA1Final(hash, &tctx.sha1);
-+ tctx.sha1 = ((struct sha1_ctx*)(ixs->ipsp->ips_key_a))->octx;
-+ SHA1Update(&tctx.sha1, hash, AHSHA196_ALEN);
-+ SHA1Final(hash, &tctx.sha1);
-+
-+ memcpy(ahp->ah_data, hash, AHHMAC_HASHLEN);
-+
-+ /* paranoid */
-+ memset((caddr_t)&tctx.sha1, 0, sizeof(tctx.sha1));
-+ memset((caddr_t)hash, 0, sizeof(*hash));
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_AH_BADALG;
-+ }
-+#ifdef NET_21
-+ ixs->skb->h.raw = (unsigned char*)ahp;
-+#endif /* NET_21 */
-+ break;
-+#endif /* CONFIG_IPSEC_AH */
-+#ifdef CONFIG_IPSEC_IPIP
-+ case IPPROTO_IPIP:
-+ ixs->iph->version = 4;
-+ switch(sysctl_ipsec_tos) {
-+ case 0:
-+#ifdef NET_21
-+ ixs->iph->tos = ixs->skb->nh.iph->tos;
-+#else /* NET_21 */
-+ ixs->iph->tos = ixs->skb->ip_hdr->tos;
-+#endif /* NET_21 */
-+ break;
-+ case 1:
-+ ixs->iph->tos = 0;
-+ break;
-+ default:
-+ break;
-+ }
-+#ifdef NET_21
-+#ifdef NETDEV_23
-+ ixs->iph->ttl = sysctl_ip_default_ttl;
-+#else /* NETDEV_23 */
-+ ixs->iph->ttl = ip_statistics.IpDefaultTTL;
-+#endif /* NETDEV_23 */
-+#else /* NET_21 */
-+ ixs->iph->ttl = 64; /* ip_statistics.IpDefaultTTL; */
-+#endif /* NET_21 */
-+ ixs->iph->frag_off = 0;
-+ ixs->iph->saddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_s))->sin_addr.s_addr;
-+ ixs->iph->daddr = ((struct sockaddr_in*)(ixs->ipsp->ips_addr_d))->sin_addr.s_addr;
-+ ixs->iph->protocol = IPPROTO_IPIP;
-+ ixs->iph->ihl = sizeof(struct iphdr) >> 2;
-+
-+ KLIPS_IP_SELECT_IDENT(ixs->iph, ixs->skb);
-+
-+ ixs->newdst = (__u32)ixs->iph->daddr;
-+ ixs->newsrc = (__u32)ixs->iph->saddr;
-+
-+#ifdef NET_21
-+ ixs->skb->h.ipiph = ixs->skb->nh.iph;
-+#endif /* NET_21 */
-+ break;
-+#endif /* !CONFIG_IPSEC_IPIP */
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ case IPPROTO_COMP:
-+ {
-+ unsigned int flags = 0;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ unsigned int old_tot_len = ntohs(ixs->iph->tot_len);
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ ixs->ipsp->ips_comp_ratio_dbytes += ntohs(ixs->iph->tot_len);
-+
-+ ixs->skb = skb_compress(ixs->skb, ixs->ipsp, &flags);
-+
-+#ifdef NET_21
-+ ixs->iph = ixs->skb->nh.iph;
-+#else /* NET_21 */
-+ ixs->iph = ixs->skb->ip_hdr;
-+#endif /* NET_21 */
-+
-+ ixs->ipsp->ips_comp_ratio_cbytes += ntohs(ixs->iph->tot_len);
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (debug_tunnel & DB_TN_CROUT)
-+ {
-+ if (old_tot_len > ntohs(ixs->iph->tot_len))
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_once: "
-+ "packet shrunk from %d to %d bytes after compression, cpi=%04x (should be from spi=%08x, spi&0xffff=%04x.\n",
-+ old_tot_len, ntohs(ixs->iph->tot_len),
-+ ntohs(((struct ipcomphdr*)(((char*)ixs->iph) + ((ixs->iph->ihl) << 2)))->ipcomp_cpi),
-+ ntohl(ixs->ipsp->ips_said.spi),
-+ (__u16)(ntohl(ixs->ipsp->ips_said.spi) & 0x0000ffff));
-+ else
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_once: "
-+ "packet did not compress (flags = %d).\n",
-+ flags);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ }
-+ break;
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ default:
-+ ixs->stats->tx_errors++;
-+ return IPSEC_XMIT_BADPROTO;
-+ }
-+
-+#ifdef NET_21
-+ ixs->skb->nh.raw = ixs->skb->data;
-+#else /* NET_21 */
-+ ixs->skb->ip_hdr = ixs->skb->h.iph = (struct iphdr *) ixs->skb->data;
-+#endif /* NET_21 */
-+ ixs->iph->check = 0;
-+ ixs->iph->check = ip_fast_csum((unsigned char *)ixs->iph, ixs->iph->ihl);
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_once: "
-+ "after <%s%s%s>, SA:%s:\n",
-+ IPS_XFORM_NAME(ixs->ipsp),
-+ ixs->sa_len ? ixs->sa_txt : " (error)");
-+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_XMIT, ixs->iph);
-+
-+ ixs->ipsp->ips_life.ipl_bytes.ipl_count += len;
-+ ixs->ipsp->ips_life.ipl_bytes.ipl_last = len;
-+
-+ if(!ixs->ipsp->ips_life.ipl_usetime.ipl_count) {
-+ ixs->ipsp->ips_life.ipl_usetime.ipl_count = jiffies / HZ;
-+ }
-+ ixs->ipsp->ips_life.ipl_usetime.ipl_last = jiffies / HZ;
-+ ixs->ipsp->ips_life.ipl_packets.ipl_count++;
-+
-+ ixs->ipsp = ixs->ipsp->ips_onext;
-+
-+ return IPSEC_XMIT_OK;
-+}
-+
-+/*
-+ * If the IP packet (iph) is a carrying TCP/UDP, then set the encaps
-+ * source and destination ports to those from the TCP/UDP header.
-+ */
-+void ipsec_extract_ports(struct iphdr * iph, struct sockaddr_encap * er)
-+{
-+ struct udphdr *udp;
-+
-+ switch (iph->protocol) {
-+ case IPPROTO_UDP:
-+ case IPPROTO_TCP:
-+ /*
-+ * The ports are at the same offsets in a TCP and UDP
-+ * header so hack it ...
-+ */
-+ udp = (struct udphdr*)(((char*)iph)+(iph->ihl<<2));
-+ er->sen_sport = udp->source;
-+ er->sen_dport = udp->dest;
-+ break;
-+ default:
-+ er->sen_sport = 0;
-+ er->sen_dport = 0;
-+ break;
-+ }
-+}
-+
-+/*
-+ * A TRAP eroute is installed and we want to replace it with a HOLD
-+ * eroute.
-+ */
-+static int create_hold_eroute(struct eroute *origtrap,
-+ struct sk_buff * skb, struct iphdr * iph,
-+ uint32_t eroute_pid)
-+{
-+ struct eroute hold_eroute;
-+ ip_said hold_said;
-+ struct sk_buff *first, *last;
-+ int error;
-+
-+ first = last = NULL;
-+ memset((caddr_t)&hold_eroute, 0, sizeof(hold_eroute));
-+ memset((caddr_t)&hold_said, 0, sizeof(hold_said));
-+
-+ hold_said.proto = IPPROTO_INT;
-+ hold_said.spi = htonl(SPI_HOLD);
-+ hold_said.dst.u.v4.sin_addr.s_addr = INADDR_ANY;
-+
-+ hold_eroute.er_eaddr.sen_len = sizeof(struct sockaddr_encap);
-+ hold_eroute.er_emask.sen_len = sizeof(struct sockaddr_encap);
-+ hold_eroute.er_eaddr.sen_family = AF_ENCAP;
-+ hold_eroute.er_emask.sen_family = AF_ENCAP;
-+ hold_eroute.er_eaddr.sen_type = SENT_IP4;
-+ hold_eroute.er_emask.sen_type = 255;
-+
-+ hold_eroute.er_eaddr.sen_ip_src.s_addr = iph->saddr;
-+ hold_eroute.er_eaddr.sen_ip_dst.s_addr = iph->daddr;
-+ hold_eroute.er_emask.sen_ip_src.s_addr = INADDR_BROADCAST;
-+ hold_eroute.er_emask.sen_ip_dst.s_addr = INADDR_BROADCAST;
-+ hold_eroute.er_emask.sen_sport = 0;
-+ hold_eroute.er_emask.sen_dport = 0;
-+ hold_eroute.er_pid = eroute_pid;
-+ hold_eroute.er_count = 0;
-+ hold_eroute.er_lasttime = jiffies/HZ;
-+
-+ /*
-+ * if it wasn't captured by a wildcard, then don't record it as
-+ * a wildcard.
-+ */
-+ if(origtrap->er_eaddr.sen_proto != 0) {
-+ hold_eroute.er_eaddr.sen_proto = iph->protocol;
-+
-+ if((iph->protocol == IPPROTO_TCP ||
-+ iph->protocol == IPPROTO_UDP) &&
-+ (origtrap->er_eaddr.sen_sport != 0 ||
-+ origtrap->er_eaddr.sen_dport != 0)) {
-+
-+ if(origtrap->er_eaddr.sen_sport != 0)
-+ hold_eroute.er_emask.sen_sport = ~0;
-+
-+ if(origtrap->er_eaddr.sen_dport != 0)
-+ hold_eroute.er_emask.sen_dport = ~0;
-+
-+ ipsec_extract_ports(iph, &hold_eroute.er_eaddr);
-+ }
-+ }
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (debug_pfkey) {
-+ char buf1[64], buf2[64];
-+ subnettoa(hold_eroute.er_eaddr.sen_ip_src,
-+ hold_eroute.er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(hold_eroute.er_eaddr.sen_ip_dst,
-+ hold_eroute.er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "calling breakeroute and makeroute for %s:%d->%s:%d %d HOLD eroute.\n",
-+ buf1, ntohs(hold_eroute.er_eaddr.sen_sport),
-+ buf2, ntohs(hold_eroute.er_eaddr.sen_dport),
-+ hold_eroute.er_eaddr.sen_proto);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ if (ipsec_breakroute(&(hold_eroute.er_eaddr), &(hold_eroute.er_emask),
-+ &first, &last)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "HOLD breakeroute found nothing.\n");
-+ } else {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "HOLD breakroute deleted %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u %u\n",
-+ NIPQUAD(hold_eroute.er_eaddr.sen_ip_src),
-+ ntohs(hold_eroute.er_eaddr.sen_sport),
-+ NIPQUAD(hold_eroute.er_eaddr.sen_ip_dst),
-+ ntohs(hold_eroute.er_eaddr.sen_dport),
-+ hold_eroute.er_eaddr.sen_proto);
-+ }
-+ if (first != NULL)
-+ kfree_skb(first);
-+ if (last != NULL)
-+ kfree_skb(last);
-+
-+ error = ipsec_makeroute(&(hold_eroute.er_eaddr),
-+ &(hold_eroute.er_emask),
-+ hold_said, eroute_pid, skb, NULL, NULL);
-+ if (error) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "HOLD makeroute returned %d, failed.\n", error);
-+ } else {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "HOLD makeroute call successful.\n");
-+ }
-+ return (error == 0);
-+}
-+
-+enum ipsec_xmit_value
-+ipsec_xmit_encap_bundle(struct ipsec_xmit_state *ixs)
-+{
-+#ifdef CONFIG_IPSEC_ALG
-+ struct ipsec_alg_enc *ixt_e = NULL;
-+ struct ipsec_alg_auth *ixt_a = NULL;
-+ int blocksize = 8;
-+#endif /* CONFIG_IPSEC_ALG */
-+ enum ipsec_xmit_value bundle_stat = IPSEC_XMIT_OK;
-+
-+ ixs->newdst = ixs->orgdst = ixs->iph->daddr;
-+ ixs->newsrc = ixs->orgsrc = ixs->iph->saddr;
-+ ixs->orgedst = ixs->outgoing_said.dst.u.v4.sin_addr.s_addr;
-+ ixs->iphlen = ixs->iph->ihl << 2;
-+ ixs->pyldsz = ntohs(ixs->iph->tot_len) - ixs->iphlen;
-+ ixs->max_headroom = ixs->max_tailroom = 0;
-+
-+ if (ixs->outgoing_said.proto == IPPROTO_INT) {
-+ switch (ntohl(ixs->outgoing_said.spi)) {
-+ case SPI_DROP:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "shunt SA of DROP or no eroute: dropping.\n");
-+ ixs->stats->tx_dropped++;
-+ break;
-+
-+ case SPI_REJECT:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "shunt SA of REJECT: notifying and dropping.\n");
-+ ICMP_SEND(ixs->skb,
-+ ICMP_DEST_UNREACH,
-+ ICMP_PKT_FILTERED,
-+ 0,
-+ ixs->physdev);
-+ ixs->stats->tx_dropped++;
-+ break;
-+
-+ case SPI_PASS:
-+#ifdef NET_21
-+ ixs->pass = 1;
-+#endif /* NET_21 */
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "PASS: calling dev_queue_xmit\n");
-+ return IPSEC_XMIT_PASS;
-+ goto cleanup;
-+
-+ case SPI_HOLD:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "shunt SA of HOLD: this does not make sense here, dropping.\n");
-+ ixs->stats->tx_dropped++;
-+ break;
-+
-+ case SPI_TRAP:
-+ case SPI_TRAPSUBNET:
-+ {
-+ struct sockaddr_in src, dst;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ char bufsrc[ADDRTOA_BUF], bufdst[ADDRTOA_BUF];
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ /* Signal all listening KMds with a PF_KEY ACQUIRE */
-+
-+ src.sin_family = AF_INET;
-+ dst.sin_family = AF_INET;
-+ src.sin_addr.s_addr = ixs->iph->saddr;
-+ dst.sin_addr.s_addr = ixs->iph->daddr;
-+
-+ ixs->ips.ips_transport_protocol = 0;
-+ src.sin_port = 0;
-+ dst.sin_port = 0;
-+ {
-+ int i;
-+ for(i = 0;
-+ i < sizeof(struct sockaddr_in)
-+ - offsetof(struct sockaddr_in, sin_zero);
-+ i++) {
-+ src.sin_zero[i] = 0;
-+ dst.sin_zero[i] = 0;
-+ }
-+ }
-+
-+ if(ixs->eroute->er_eaddr.sen_proto != 0) {
-+ ixs->ips.ips_transport_protocol = ixs->iph->protocol;
-+
-+ if(ixs->eroute->er_eaddr.sen_sport != 0) {
-+ src.sin_port =
-+ (ixs->iph->protocol == IPPROTO_UDP
-+ ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->source
-+ : (ixs->iph->protocol == IPPROTO_TCP
-+ ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->source
-+ : 0));
-+ }
-+ if(ixs->eroute->er_eaddr.sen_dport != 0) {
-+ dst.sin_port =
-+ (ixs->iph->protocol == IPPROTO_UDP
-+ ? ((struct udphdr*) (((caddr_t)ixs->iph) + (ixs->iph->ihl << 2)))->dest
-+ : (ixs->iph->protocol == IPPROTO_TCP
-+ ? ((struct tcphdr*)((caddr_t)ixs->iph + (ixs->iph->ihl << 2)))->dest
-+ : 0));
-+ }
-+ }
-+
-+ ixs->ips.ips_addr_s = (struct sockaddr*)(&src);
-+ ixs->ips.ips_addr_d = (struct sockaddr*)(&dst);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "SADB_ACQUIRE sent with src=%s:%d, dst=%s:%d, proto=%d.\n",
-+ addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_addr, 0, bufsrc, sizeof(bufsrc)) <= ADDRTOA_BUF ? bufsrc : "BAD_ADDR",
-+ ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_s))->sin_port),
-+ addrtoa(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_addr, 0, bufdst, sizeof(bufdst)) <= ADDRTOA_BUF ? bufdst : "BAD_ADDR",
-+ ntohs(((struct sockaddr_in*)(ixs->ips.ips_addr_d))->sin_port),
-+ ixs->ips.ips_said.proto);
-+
-+ /* increment count of total traps needed */
-+ ipsec_xmit_trap_count++;
-+
-+ if (pfkey_acquire(&ixs->ips) == 0) {
-+
-+ /* note that we succeeded */
-+ ipsec_xmit_trap_sendcount++;
-+
-+ if (ixs->outgoing_said.spi==htonl(SPI_TRAPSUBNET)) {
-+ /*
-+ * The spinlock is to prevent any other
-+ * process from accessing or deleting
-+ * the eroute while we are using and
-+ * updating it.
-+ */
-+ spin_lock(&eroute_lock);
-+ ixs->eroute = ipsec_findroute(&ixs->matcher);
-+ if(ixs->eroute) {
-+ ixs->eroute->er_said.spi = htonl(SPI_HOLD);
-+ ixs->eroute->er_first = ixs->skb;
-+ ixs->skb = NULL;
-+ }
-+ spin_unlock(&eroute_lock);
-+ } else if (create_hold_eroute(ixs->eroute,
-+ ixs->skb,
-+ ixs->iph,
-+ ixs->eroute_pid)) {
-+ ixs->skb = NULL;
-+ }
-+ /* whether or not the above succeeded, we continue */
-+
-+ }
-+ ixs->stats->tx_dropped++;
-+ }
-+ default:
-+ /* XXX what do we do with an unknown shunt spi? */
-+ break;
-+ } /* switch (ntohl(ixs->outgoing_said.spi)) */
-+ return IPSEC_XMIT_STOLEN;
-+ } /* if (ixs->outgoing_said.proto == IPPROTO_INT) */
-+
-+ /*
-+ The spinlock is to prevent any other process from
-+ accessing or deleting the ipsec_sa hash table or any of the
-+ ipsec_sa s while we are using and updating them.
-+
-+ This is not optimal, but was relatively straightforward
-+ at the time. A better way to do it has been planned for
-+ more than a year, to lock the hash table and put reference
-+ counts on each ipsec_sa instead. This is not likely to happen
-+ in KLIPS1 unless a volunteer contributes it, but will be
-+ designed into KLIPS2.
-+ */
-+ spin_lock(&tdb_lock);
-+
-+ ixs->ipsp = ipsec_sa_getbyid(&ixs->outgoing_said);
-+ ixs->sa_len = satot(&ixs->outgoing_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
-+
-+ if (ixs->ipsp == NULL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "no ipsec_sa for SA%s: outgoing packet with no SA, dropped.\n",
-+ ixs->sa_len ? ixs->sa_txt : " (error)");
-+ ixs->stats->tx_dropped++;
-+ bundle_stat = IPSEC_XMIT_SAIDNOTFOUND;
-+ goto cleanup;
-+ }
-+
-+ ipsec_sa_put(ixs->ipsp); /* incomplete */
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "found ipsec_sa -- SA:<%s%s%s> %s\n",
-+ IPS_XFORM_NAME(ixs->ipsp),
-+ ixs->sa_len ? ixs->sa_txt : " (error)");
-+
-+ /*
-+ * How much headroom do we need to be able to apply
-+ * all the grouped transforms?
-+ */
-+ ixs->ipsq = ixs->ipsp; /* save the head of the ipsec_sa chain */
-+ while (ixs->ipsp) {
-+ ixs->sa_len = satot(&ixs->ipsp->ips_said, 0, ixs->sa_txt, sizeof(ixs->sa_txt));
-+ if(ixs->sa_len == 0) {
-+ strcpy(ixs->sa_txt, "(error)");
-+ }
-+
-+ /* If it is in larval state, drop the packet, we cannot process yet. */
-+ if(ixs->ipsp->ips_state == SADB_SASTATE_LARVAL) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "ipsec_sa in larval state for SA:<%s%s%s> %s, cannot be used yet, dropping packet.\n",
-+ IPS_XFORM_NAME(ixs->ipsp),
-+ ixs->sa_len ? ixs->sa_txt : " (error)");
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
-+ goto cleanup;
-+ }
-+
-+ if(ixs->ipsp->ips_state == SADB_SASTATE_DEAD) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "ipsec_sa in dead state for SA:<%s%s%s> %s, can no longer be used, dropping packet.\n",
-+ IPS_XFORM_NAME(ixs->ipsp),
-+ ixs->sa_len ? ixs->sa_txt : " (error)");
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_SAIDNOTLIVE;
-+ goto cleanup;
-+ }
-+
-+ /* If the replay window counter == -1, expire SA, it will roll */
-+ if(ixs->ipsp->ips_replaywin && ixs->ipsp->ips_replaywin_lastseq == -1) {
-+ pfkey_expire(ixs->ipsp, 1);
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "replay window counter rolled for SA:<%s%s%s> %s, packet dropped, expiring SA.\n",
-+ IPS_XFORM_NAME(ixs->ipsp),
-+ ixs->sa_len ? ixs->sa_txt : " (error)");
-+ ipsec_sa_delchain(ixs->ipsp);
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_REPLAYROLLED;
-+ goto cleanup;
-+ }
-+
-+ /*
-+ * if this is the first time we are using this SA, mark start time,
-+ * and offset hard/soft counters by "now" for later checking.
-+ */
-+#if 0
-+ if(ixs->ipsp->ips_life.ipl_usetime.count == 0) {
-+ ixs->ipsp->ips_life.ipl_usetime.count = jiffies;
-+ ixs->ipsp->ips_life.ipl_usetime.hard += jiffies;
-+ ixs->ipsp->ips_life.ipl_usetime.soft += jiffies;
-+ }
-+#endif
-+
-+
-+ if(ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_bytes, "bytes", ixs->sa_txt,
-+ ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
-+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_addtime, "addtime",ixs->sa_txt,
-+ ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
-+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_usetime, "usetime",ixs->sa_txt,
-+ ipsec_life_timebased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied ||
-+ ipsec_lifetime_check(&ixs->ipsp->ips_life.ipl_packets, "packets",ixs->sa_txt,
-+ ipsec_life_countbased, ipsec_outgoing, ixs->ipsp) == ipsec_life_harddied) {
-+
-+ ipsec_sa_delchain(ixs->ipsp);
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_LIFETIMEFAILED;
-+ goto cleanup;
-+ }
-+
-+
-+ ixs->headroom = ixs->tailroom = 0;
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "calling room for <%s%s%s>, SA:%s\n",
-+ IPS_XFORM_NAME(ixs->ipsp),
-+ ixs->sa_len ? ixs->sa_txt : " (error)");
-+ switch(ixs->ipsp->ips_said.proto) {
-+#ifdef CONFIG_IPSEC_AH
-+ case IPPROTO_AH:
-+ ixs->headroom += sizeof(struct ahhdr);
-+ break;
-+#endif /* CONFIG_IPSEC_AH */
-+#ifdef CONFIG_IPSEC_ESP
-+ case IPPROTO_ESP:
-+#ifdef CONFIG_IPSEC_ALG
-+ if ((ixt_e=ixs->ipsp->ips_alg_enc)) {
-+ blocksize = ixt_e->ixt_blocksize;
-+ ixs->headroom += ESP_HEADER_LEN + ixt_e->ixt_ivlen/8;
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ixs->ipsp->ips_encalg) {
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+ ixs->headroom += sizeof(struct esphdr);
-+ break;
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ default:
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_ESP_BADALG;
-+ goto cleanup;
-+ }
-+#ifdef CONFIG_IPSEC_ALG
-+ if ((ixt_a=ixs->ipsp->ips_alg_auth)) {
-+ ixs->tailroom += AHHMAC_HASHLEN;
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ixs->ipsp->ips_authalg) {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5:
-+ ixs->tailroom += AHHMAC_HASHLEN;
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA:
-+ ixs->tailroom += AHHMAC_HASHLEN;
-+ break;
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ case AH_NONE:
-+ break;
-+ default:
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_AH_BADALG;
-+ goto cleanup;
-+ }
-+#ifdef CONFIG_IPSEC_ALG
-+ ixs->tailroom += blocksize != 1 ?
-+ ((blocksize - ((ixs->pyldsz + 2) % blocksize)) % blocksize) + 2 :
-+ ((4 - ((ixs->pyldsz + 2) % 4)) % 4) + 2;
-+#else
-+ ixs->tailroom += ((8 - ((ixs->pyldsz + 2 * sizeof(unsigned char)) % 8)) % 8) + 2;
-+#endif /* CONFIG_IPSEC_ALG */
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if ((ixs->ipsp->ips_natt_type) && (!ixs->natt_type)) {
-+ ixs->natt_type = ixs->ipsp->ips_natt_type;
-+ ixs->natt_sport = ixs->ipsp->ips_natt_sport;
-+ ixs->natt_dport = ixs->ipsp->ips_natt_dport;
-+ switch (ixs->natt_type) {
-+ case ESPINUDP_WITH_NON_IKE:
-+ ixs->natt_head = sizeof(struct udphdr)+(2*sizeof(__u32));
-+ break;
-+
-+ case ESPINUDP_WITH_NON_ESP:
-+ ixs->natt_head = sizeof(struct udphdr);
-+ break;
-+
-+ default:
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT
-+ , "klips_xmit: invalid nat-t type %d"
-+ , ixs->natt_type);
-+ bundle_stat = IPSEC_XMIT_ESPUDP_BADTYPE;
-+ goto cleanup;
-+
-+ break;
-+ }
-+ ixs->tailroom += ixs->natt_head;
-+ }
-+#endif
-+ break;
-+#endif /* !CONFIG_IPSEC_ESP */
-+#ifdef CONFIG_IPSEC_IPIP
-+ case IPPROTO_IPIP:
-+ ixs->headroom += sizeof(struct iphdr);
-+ break;
-+#endif /* !CONFIG_IPSEC_IPIP */
-+ case IPPROTO_COMP:
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ /*
-+ We can't predict how much the packet will
-+ shrink without doing the actual compression.
-+ We could do it here, if we were the first
-+ encapsulation in the chain. That might save
-+ us a skb_copy_expand, since we might fit
-+ into the existing skb then. However, this
-+ would be a bit unclean (and this hack has
-+ bit us once), so we better not do it. After
-+ all, the skb_copy_expand is cheap in
-+ comparison to the actual compression.
-+ At least we know the packet will not grow.
-+ */
-+ break;
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ default:
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_BADPROTO;
-+ goto cleanup;
-+ }
-+ ixs->ipsp = ixs->ipsp->ips_onext;
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "Required head,tailroom: %d,%d\n",
-+ ixs->headroom, ixs->tailroom);
-+ ixs->max_headroom += ixs->headroom;
-+ ixs->max_tailroom += ixs->tailroom;
-+ ixs->pyldsz += (ixs->headroom + ixs->tailroom);
-+ }
-+ ixs->ipsp = ixs->ipsq; /* restore the head of the ipsec_sa chain */
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "existing head,tailroom: %d,%d before applying xforms with head,tailroom: %d,%d .\n",
-+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb),
-+ ixs->max_headroom, ixs->max_tailroom);
-+
-+ ixs->tot_headroom += ixs->max_headroom;
-+ ixs->tot_tailroom += ixs->max_tailroom;
-+
-+ ixs->mtudiff = ixs->prv->mtu + ixs->tot_headroom + ixs->tot_tailroom - ixs->physmtu;
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "mtu:%d physmtu:%d tothr:%d tottr:%d mtudiff:%d ippkttotlen:%d\n",
-+ ixs->prv->mtu, ixs->physmtu,
-+ ixs->tot_headroom, ixs->tot_tailroom, ixs->mtudiff, ntohs(ixs->iph->tot_len));
-+ if(ixs->mtudiff > 0) {
-+ int newmtu = ixs->physmtu - (ixs->tot_headroom + ((ixs->tot_tailroom + 2) & ~7) + 5);
-+
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_info:ipsec_xmit_encap_bundle: "
-+ "dev %s mtu of %d decreased by %d to %d\n",
-+ ixs->dev->name,
-+ ixs->prv->mtu,
-+ ixs->prv->mtu - newmtu,
-+ newmtu);
-+ ixs->prv->mtu = newmtu;
-+#ifdef NET_21
-+#if 0
-+ ixs->skb->dst->pmtu = ixs->prv->mtu; /* RGB */
-+#endif /* 0 */
-+#else /* NET_21 */
-+#if 0
-+ ixs->dev->mtu = ixs->prv->mtu; /* RGB */
-+#endif /* 0 */
-+#endif /* NET_21 */
-+ }
-+
-+ /*
-+ If the sender is doing PMTU discovery, and the
-+ packet doesn't fit within ixs->prv->mtu, notify him
-+ (unless it was an ICMP packet, or it was not the
-+ zero-offset packet) and send it anyways.
-+
-+ Note: buggy firewall configuration may prevent the
-+ ICMP packet from getting back.
-+ */
-+ if(sysctl_ipsec_icmp
-+ && ixs->prv->mtu < ntohs(ixs->iph->tot_len)
-+ && (ixs->iph->frag_off & __constant_htons(IP_DF)) ) {
-+ int notify = ixs->iph->protocol != IPPROTO_ICMP
-+ && (ixs->iph->frag_off & __constant_htons(IP_OFFSET)) == 0;
-+
-+#ifdef IPSEC_obey_DF
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "fragmentation needed and DF set; %sdropping packet\n",
-+ notify ? "sending ICMP and " : "");
-+ if (notify)
-+ ICMP_SEND(ixs->skb,
-+ ICMP_DEST_UNREACH,
-+ ICMP_FRAG_NEEDED,
-+ ixs->prv->mtu,
-+ ixs->physdev);
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_CANNOTFRAG;
-+ goto cleanup;
-+#else /* IPSEC_obey_DF */
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "fragmentation needed and DF set; %spassing packet\n",
-+ notify ? "sending ICMP and " : "");
-+ if (notify)
-+ ICMP_SEND(ixs->skb,
-+ ICMP_DEST_UNREACH,
-+ ICMP_FRAG_NEEDED,
-+ ixs->prv->mtu,
-+ ixs->physdev);
-+#endif /* IPSEC_obey_DF */
-+ }
-+
-+#ifdef MSS_HACK
-+ /*
-+ * If this is a transport mode TCP packet with
-+ * SYN set, determine an effective MSS based on
-+ * AH/ESP overheads determined above.
-+ */
-+ if (ixs->iph->protocol == IPPROTO_TCP
-+ && ixs->outgoing_said.proto != IPPROTO_IPIP) {
-+ struct tcphdr *tcph = ixs->skb->h.th;
-+ if (tcph->syn && !tcph->ack) {
-+ if(!ipsec_adjust_mss(ixs->skb, tcph, ixs->prv->mtu)) {
-+ printk(KERN_WARNING
-+ "klips_warning:ipsec_xmit_encap_bundle: "
-+ "ipsec_adjust_mss() failed\n");
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_MSSERR;
-+ goto cleanup;
-+ }
-+ }
-+ }
-+#endif /* MSS_HACK */
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if ((ixs->natt_type) && (ixs->outgoing_said.proto != IPPROTO_IPIP)) {
-+ /**
-+ * NAT-Traversal and Transport Mode:
-+ * we need to correct TCP/UDP checksum
-+ *
-+ * If we've got NAT-OA, we can fix checksum without recalculation.
-+ * If we don't we can zero udp checksum.
-+ */
-+ __u32 natt_oa = ixs->ipsp->ips_natt_oa ?
-+ ((struct sockaddr_in*)(ixs->ipsp->ips_natt_oa))->sin_addr.s_addr : 0;
-+ __u16 pkt_len = ixs->skb->tail - (unsigned char *)ixs->iph;
-+ __u16 data_len = pkt_len - (ixs->iph->ihl << 2);
-+ switch (ixs->iph->protocol) {
-+ case IPPROTO_TCP:
-+ if (data_len >= sizeof(struct tcphdr)) {
-+ struct tcphdr *tcp = (struct tcphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);
-+ if (natt_oa) {
-+ __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "NAT-T & TRANSPORT: "
-+ "fix TCP checksum using NAT-OA\n");
-+ tcp->check = csum_fold(
-+ csum_partial((unsigned char *)buff, sizeof(buff),
-+ tcp->check^0xffff));
-+ }
-+ else {
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "NAT-T & TRANSPORT: do not recalc TCP checksum\n");
-+ }
-+ }
-+ else {
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "NAT-T & TRANSPORT: can't fix TCP checksum\n");
-+ }
-+ break;
-+ case IPPROTO_UDP:
-+ if (data_len >= sizeof(struct udphdr)) {
-+ struct udphdr *udp = (struct udphdr *)((__u32 *)ixs->iph+ixs->iph->ihl);
-+ if (udp->check == 0) {
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "NAT-T & TRANSPORT: UDP checksum already 0\n");
-+ }
-+ else if (natt_oa) {
-+ __u32 buff[2] = { ~ixs->iph->daddr, natt_oa };
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "NAT-T & TRANSPORT: "
-+ "fix UDP checksum using NAT-OA\n");
-+ udp->check = csum_fold(
-+ csum_partial((unsigned char *)buff, sizeof(buff),
-+ udp->check^0xffff));
-+ }
-+ else {
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "NAT-T & TRANSPORT: zero UDP checksum\n");
-+ udp->check = 0;
-+ }
-+ }
-+ else {
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "NAT-T & TRANSPORT: can't fix UDP checksum\n");
-+ }
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_tunnel,
-+ "klips_debug:ipsec_tunnel_start_xmit: "
-+ "NAT-T & TRANSPORT: non TCP/UDP packet -- do nothing\n");
-+ break;
-+ }
-+ }
-+#endif /* CONFIG_IPSEC_NAT_TRAVERSAL */
-+
-+ if(!ixs->hard_header_stripped) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "allocating %d bytes for hardheader.\n",
-+ ixs->hard_header_len);
-+ if((ixs->saved_header = kmalloc(ixs->hard_header_len, GFP_ATOMIC)) == NULL) {
-+ printk(KERN_WARNING "klips_debug:ipsec_xmit_encap_bundle: "
-+ "Failed, tried to allocate %d bytes for temp hard_header.\n",
-+ ixs->hard_header_len);
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_ERRMEMALLOC;
-+ goto cleanup;
-+ }
-+ {
-+ int i;
-+ for (i = 0; i < ixs->hard_header_len; i++) {
-+ ixs->saved_header[i] = ixs->skb->data[i];
-+ }
-+ }
-+ if(ixs->skb->len < ixs->hard_header_len) {
-+ printk(KERN_WARNING "klips_error:ipsec_xmit_encap_bundle: "
-+ "tried to skb_pull hhlen=%d, %d available. This should never happen, please report.\n",
-+ ixs->hard_header_len, (int)(ixs->skb->len));
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_ESP_PUSHPULLERR;
-+ goto cleanup;
-+ }
-+ skb_pull(ixs->skb, ixs->hard_header_len);
-+ ixs->hard_header_stripped = 1;
-+
-+/* ixs->iph = (struct iphdr *) (ixs->skb->data); */
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "head,tailroom: %d,%d after hard_header stripped.\n",
-+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
-+ KLIPS_IP_PRINT(debug_tunnel & DB_TN_CROUT, ixs->iph);
-+ } else {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "hard header already stripped.\n");
-+ }
-+
-+ ixs->ll_headroom = (ixs->hard_header_len + 15) & ~15;
-+
-+ if ((skb_headroom(ixs->skb) >= ixs->max_headroom + 2 * ixs->ll_headroom) &&
-+ (skb_tailroom(ixs->skb) >= ixs->max_tailroom)
-+#ifndef NET_21
-+ && ixs->skb->free
-+#endif /* !NET_21 */
-+ ) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "data fits in existing skb\n");
-+ } else {
-+ struct sk_buff* tskb;
-+
-+ if(!ixs->oskb) {
-+ ixs->oskb = ixs->skb;
-+ }
-+
-+ tskb = skb_copy_expand(ixs->skb,
-+ /* The need for 2 * link layer length here remains unexplained...RGB */
-+ ixs->max_headroom + 2 * ixs->ll_headroom,
-+ ixs->max_tailroom,
-+ GFP_ATOMIC);
-+#ifdef NET_21
-+ if(tskb && ixs->skb->sk) {
-+ skb_set_owner_w(tskb, ixs->skb->sk);
-+ }
-+#endif /* NET_21 */
-+ if(ixs->skb != ixs->oskb) {
-+ ipsec_kfree_skb(ixs->skb);
-+ }
-+ ixs->skb = tskb;
-+ if (!ixs->skb) {
-+ printk(KERN_WARNING
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "Failed, tried to allocate %d head and %d tailroom\n",
-+ ixs->max_headroom, ixs->max_tailroom);
-+ ixs->stats->tx_errors++;
-+ bundle_stat = IPSEC_XMIT_ERRSKBALLOC;
-+ goto cleanup;
-+ }
-+ KLIPS_PRINT(debug_tunnel & DB_TN_CROUT,
-+ "klips_debug:ipsec_xmit_encap_bundle: "
-+ "head,tailroom: %d,%d after allocation\n",
-+ skb_headroom(ixs->skb), skb_tailroom(ixs->skb));
-+ }
-+
-+ /*
-+ * Apply grouped transforms to packet
-+ */
-+ while (ixs->ipsp) {
-+ enum ipsec_xmit_value encap_stat = IPSEC_XMIT_OK;
-+
-+ encap_stat = ipsec_xmit_encap_once(ixs);
-+ if(encap_stat != IPSEC_XMIT_OK) {
-+ KLIPS_PRINT(debug_tunnel & DB_TN_XMIT,
-+ "klips_debug:ipsec_xmit_encap_bundle: encap_once failed: %d\n",
-+ encap_stat);
-+
-+ bundle_stat = IPSEC_XMIT_ENCAPFAIL;
-+ goto cleanup;
-+ }
-+ }
-+ /* end encapsulation loop here XXX */
-+ cleanup:
-+ spin_unlock(&tdb_lock);
-+ return bundle_stat;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.8 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.7 2004/02/03 03:13:41 mcr
-+ * mark invalid encapsulation states.
-+ *
-+ * Revision 1.6.2.1 2003/12/22 15:25:52 jjo
-+ * Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.6 2003/12/10 01:14:27 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.5 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.4.4.2 2003/10/29 01:37:39 mcr
-+ * when creating %hold from %trap, only make the %hold as
-+ * specific as the %trap was - so if the protocol and ports
-+ * were wildcards, then the %hold will be too.
-+ *
-+ * Revision 1.4.4.1 2003/09/21 13:59:56 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.4 2003/06/20 02:28:10 mcr
-+ * misstype of variable name, not detected by module build.
-+ *
-+ * Revision 1.3 2003/06/20 01:42:21 mcr
-+ * added counters to measure how many ACQUIREs we send to pluto,
-+ * and how many are successfully sent.
-+ *
-+ * Revision 1.2 2003/04/03 17:38:35 rgb
-+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
-+ * Normalised coding style.
-+ * Simplified logic and reduced duplication of code.
-+ *
-+ * Revision 1.1 2003/02/12 19:31:23 rgb
-+ * Refactored from ipsec_tunnel.c
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/pfkey_v2.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,2126 @@
-+/*
-+ * @(#) RFC2367 PF_KEYv2 Key management API domain socket I/F
-+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * Template from /usr/src/linux-2.0.36/net/unix/af_unix.c.
-+ * Hints from /usr/src/linux-2.0.36/net/ipv4/udp.c.
-+ */
-+
-+#define __NO_VERSION__
-+#include <linux/module.h>
-+#include <linux/version.h>
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+
-+#include "openswan/ipsec_param.h"
-+
-+#include <linux/major.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/stat.h>
-+#include <linux/socket.h>
-+#include <linux/un.h>
-+#include <linux/fcntl.h>
-+#include <linux/termios.h>
-+#include <linux/socket.h>
-+#include <linux/sockios.h>
-+#include <linux/net.h> /* struct socket */
-+#include <linux/in.h>
-+#include <linux/fs.h>
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <asm/segment.h>
-+#include <linux/skbuff.h>
-+#include <linux/netdevice.h>
-+#include <net/sock.h> /* struct sock */
-+/* #include <net/tcp.h> */
-+#include <net/af_unix.h>
-+#ifdef CONFIG_PROC_FS
-+# include <linux/proc_fs.h>
-+#endif /* CONFIG_PROC_FS */
-+
-+#include <linux/types.h>
-+
-+#include <openswan.h>
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+#endif /* NET_21 */
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+int debug_pfkey = 0;
-+extern int sysctl_ipsec_debug_verbose;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
-+
-+#ifndef SOCKOPS_WRAPPED
-+#define SOCKOPS_WRAPPED(name) name
-+#endif /* SOCKOPS_WRAPPED */
-+
-+extern struct proto_ops pfkey_ops;
-+struct sock *pfkey_sock_list = NULL;
-+struct supported_list *pfkey_supported_list[SADB_SATYPE_MAX+1];
-+
-+struct socket_list *pfkey_open_sockets = NULL;
-+struct socket_list *pfkey_registered_sockets[SADB_SATYPE_MAX+1];
-+
-+int pfkey_msg_interp(struct sock *, struct sadb_msg *, struct sadb_msg **);
-+
-+int
-+pfkey_list_remove_socket(struct socket *socketp, struct socket_list **sockets)
-+{
-+ struct socket_list *socket_listp,*prev;
-+
-+ if(!socketp) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_remove_socket: "
-+ "NULL socketp handed in, failed.\n");
-+ return -EINVAL;
-+ }
-+
-+ if(!sockets) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_remove_socket: "
-+ "NULL sockets list handed in, failed.\n");
-+ return -EINVAL;
-+ }
-+
-+ socket_listp = *sockets;
-+ prev = NULL;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_remove_socket: "
-+ "removing sock=0p%p\n",
-+ socketp);
-+
-+ while(socket_listp != NULL) {
-+ if(socket_listp->socketp == socketp) {
-+ if(prev != NULL) {
-+ prev->next = socket_listp->next;
-+ } else {
-+ *sockets = socket_listp->next;
-+ }
-+
-+ kfree((void*)socket_listp);
-+
-+ break;
-+ }
-+ prev = socket_listp;
-+ socket_listp = socket_listp->next;
-+ }
-+
-+ return 0;
-+}
-+
-+int
-+pfkey_list_insert_socket(struct socket *socketp, struct socket_list **sockets)
-+{
-+ struct socket_list *socket_listp;
-+
-+ if(!socketp) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_socket: "
-+ "NULL socketp handed in, failed.\n");
-+ return -EINVAL;
-+ }
-+
-+ if(!sockets) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_socket: "
-+ "NULL sockets list handed in, failed.\n");
-+ return -EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_socket: "
-+ "allocating %lu bytes for socketp=0p%p\n",
-+ (unsigned long) sizeof(struct socket_list),
-+ socketp);
-+
-+ if((socket_listp = (struct socket_list *)kmalloc(sizeof(struct socket_list), GFP_KERNEL)) == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_socket: "
-+ "memory allocation error.\n");
-+ return -ENOMEM;
-+ }
-+
-+ socket_listp->socketp = socketp;
-+ socket_listp->next = *sockets;
-+ *sockets = socket_listp;
-+
-+ return 0;
-+}
-+
-+int
-+pfkey_list_remove_supported(struct supported *supported, struct supported_list **supported_list)
-+{
-+ struct supported_list *supported_listp = *supported_list, *prev = NULL;
-+
-+ if(!supported) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_remove_supported: "
-+ "NULL supported handed in, failed.\n");
-+ return -EINVAL;
-+ }
-+
-+ if(!supported_list) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_remove_supported: "
-+ "NULL supported_list handed in, failed.\n");
-+ return -EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_remove_supported: "
-+ "removing supported=0p%p\n",
-+ supported);
-+
-+ while(supported_listp != NULL) {
-+ if(supported_listp->supportedp == supported) {
-+ if(prev != NULL) {
-+ prev->next = supported_listp->next;
-+ } else {
-+ *supported_list = supported_listp->next;
-+ }
-+
-+ kfree((void*)supported_listp);
-+
-+ break;
-+ }
-+ prev = supported_listp;
-+ supported_listp = supported_listp->next;
-+ }
-+
-+ return 0;
-+}
-+
-+int
-+pfkey_list_insert_supported(struct supported *supported, struct supported_list **supported_list)
-+{
-+ struct supported_list *supported_listp;
-+
-+ if(!supported) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_supported: "
-+ "NULL supported handed in, failed.\n");
-+ return -EINVAL;
-+ }
-+
-+ if(!supported_list) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_supported: "
-+ "NULL supported_list handed in, failed.\n");
-+ return -EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_supported: "
-+ "allocating %lu bytes for incoming, supported=0p%p, supported_list=0p%p\n",
-+ (unsigned long) sizeof(struct supported_list),
-+ supported,
-+ supported_list);
-+
-+ supported_listp = (struct supported_list *)kmalloc(sizeof(struct supported_list), GFP_KERNEL);
-+ if(supported_listp == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_supported: "
-+ "memory allocation error.\n");
-+ return -ENOMEM;
-+ }
-+
-+ supported_listp->supportedp = supported;
-+ supported_listp->next = *supported_list;
-+ *supported_list = supported_listp;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_list_insert_supported: "
-+ "outgoing, supported=0p%p, supported_list=0p%p\n",
-+ supported,
-+ supported_list);
-+
-+ return 0;
-+}
-+
-+#ifndef NET_21
-+DEBUG_NO_STATIC void
-+pfkey_state_change(struct sock *sk)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_state_change: .\n");
-+ if(!sk->dead) {
-+ wake_up_interruptible(sk->sleep);
-+ }
-+}
-+#endif /* !NET_21 */
-+
-+#ifndef NET_21
-+DEBUG_NO_STATIC void
-+pfkey_data_ready(struct sock *sk, int len)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_data_ready: "
-+ "sk=0p%p len=%d\n",
-+ sk,
-+ len);
-+ if(!sk->dead) {
-+ wake_up_interruptible(sk->sleep);
-+ sock_wake_async(sk->socket, 1);
-+ }
-+}
-+
-+DEBUG_NO_STATIC void
-+pfkey_write_space(struct sock *sk)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_write_space: .\n");
-+ if(!sk->dead) {
-+ wake_up_interruptible(sk->sleep);
-+ sock_wake_async(sk->socket, 2);
-+ }
-+}
-+#endif /* !NET_21 */
-+
-+DEBUG_NO_STATIC void
-+pfkey_insert_socket(struct sock *sk)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_insert_socket: "
-+ "sk=0p%p\n",
-+ sk);
-+ cli();
-+ sk->next=pfkey_sock_list;
-+ pfkey_sock_list=sk;
-+ sti();
-+}
-+
-+DEBUG_NO_STATIC void
-+pfkey_remove_socket(struct sock *sk)
-+{
-+ struct sock **s;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_remove_socket: .\n");
-+ cli();
-+ s=&pfkey_sock_list;
-+
-+ while(*s!=NULL) {
-+ if(*s==sk) {
-+ *s=sk->next;
-+ sk->next=NULL;
-+ sti();
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_remove_socket: "
-+ "succeeded.\n");
-+ return;
-+ }
-+ s=&((*s)->next);
-+ }
-+ sti();
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_remove_socket: "
-+ "not found.\n");
-+ return;
-+}
-+
-+DEBUG_NO_STATIC void
-+pfkey_destroy_socket(struct sock *sk)
-+{
-+ struct sk_buff *skb;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_destroy_socket: .\n");
-+ pfkey_remove_socket(sk);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_destroy_socket: "
-+ "pfkey_remove_socket called.\n");
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_destroy_socket: "
-+ "sk(0p%p)->(&0p%p)receive_queue.{next=0p%p,prev=0p%p}.\n",
-+ sk,
-+ &(sk->receive_queue),
-+ sk->receive_queue.next,
-+ sk->receive_queue.prev);
-+ while(sk && ((skb=skb_dequeue(&(sk->receive_queue)))!=NULL)) {
-+#ifdef NET_21
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(debug_pfkey && sysctl_ipsec_debug_verbose) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_destroy_socket: "
-+ "skb=0p%p dequeued.\n", skb);
-+ printk(KERN_INFO "klips_debug:pfkey_destroy_socket: "
-+ "pfkey_skb contents:");
-+ printk(" next:0p%p", skb->next);
-+ printk(" prev:0p%p", skb->prev);
-+ printk(" list:0p%p", skb->list);
-+ printk(" sk:0p%p", skb->sk);
-+ printk(" stamp:%ld.%ld", skb->stamp.tv_sec, skb->stamp.tv_usec);
-+ printk(" dev:0p%p", skb->dev);
-+ if(skb->dev) {
-+ if(skb->dev->name) {
-+ printk(" dev->name:%s", skb->dev->name);
-+ } else {
-+ printk(" dev->name:NULL?");
-+ }
-+ } else {
-+ printk(" dev:NULL");
-+ }
-+ printk(" h:0p%p", skb->h.raw);
-+ printk(" nh:0p%p", skb->nh.raw);
-+ printk(" mac:0p%p", skb->mac.raw);
-+ printk(" dst:0p%p", skb->dst);
-+ if(sysctl_ipsec_debug_verbose) {
-+ int i;
-+
-+ printk(" cb");
-+ for(i=0; i<48; i++) {
-+ printk(":%2x", skb->cb[i]);
-+ }
-+ }
-+ printk(" len:%d", skb->len);
-+ printk(" csum:%d", skb->csum);
-+#ifndef NETDEV_23
-+ printk(" used:%d", skb->used);
-+ printk(" is_clone:%d", skb->is_clone);
-+#endif /* NETDEV_23 */
-+ printk(" cloned:%d", skb->cloned);
-+ printk(" pkt_type:%d", skb->pkt_type);
-+ printk(" ip_summed:%d", skb->ip_summed);
-+ printk(" priority:%d", skb->priority);
-+ printk(" protocol:%d", skb->protocol);
-+ printk(" security:%d", skb->security);
-+ printk(" truesize:%d", skb->truesize);
-+ printk(" head:0p%p", skb->head);
-+ printk(" data:0p%p", skb->data);
-+ printk(" tail:0p%p", skb->tail);
-+ printk(" end:0p%p", skb->end);
-+ if(sysctl_ipsec_debug_verbose) {
-+ unsigned char* i;
-+ printk(" data");
-+ for(i = skb->head; i < skb->end; i++) {
-+ printk(":%2x", (unsigned char)(*(i)));
-+ }
-+ }
-+ printk(" destructor:0p%p", skb->destructor);
-+ printk("\n");
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+#endif /* NET_21 */
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_destroy_socket: "
-+ "skb=0p%p freed.\n",
-+ skb);
-+ ipsec_kfree_skb(skb);
-+ }
-+
-+ sk->dead = 1;
-+ sk_free(sk);
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_destroy_socket: destroyed.\n");
-+}
-+
-+int
-+pfkey_upmsg(struct socket *sock, struct sadb_msg *pfkey_msg)
-+{
-+ int error = 0;
-+ struct sk_buff * skb = NULL;
-+ struct sock *sk;
-+
-+ if(sock == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_upmsg: "
-+ "NULL socket passed in.\n");
-+ return -EINVAL;
-+ }
-+
-+ if(pfkey_msg == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_upmsg: "
-+ "NULL pfkey_msg passed in.\n");
-+ return -EINVAL;
-+ }
-+
-+#ifdef NET_21
-+ sk = sock->sk;
-+#else /* NET_21 */
-+ sk = sock->data;
-+#endif /* NET_21 */
-+
-+ if(sk == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_upmsg: "
-+ "NULL sock passed in.\n");
-+ return -EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_upmsg: "
-+ "allocating %d bytes...\n",
-+ (int)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN));
-+ if(!(skb = alloc_skb(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN, GFP_ATOMIC) )) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_upmsg: "
-+ "no buffers left to send up a message.\n");
-+ return -ENOBUFS;
-+ }
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_upmsg: "
-+ "...allocated at 0p%p.\n",
-+ skb);
-+
-+ skb->dev = NULL;
-+
-+ if(skb_tailroom(skb) < pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
-+ printk(KERN_WARNING "klips_error:pfkey_upmsg: "
-+ "tried to skb_put %ld, %d available. This should never happen, please report.\n",
-+ (unsigned long int)pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN,
-+ skb_tailroom(skb));
-+ ipsec_kfree_skb(skb);
-+ return -ENOBUFS;
-+ }
-+ skb->h.raw = skb_put(skb, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
-+ memcpy(skb->h.raw, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN);
-+
-+#ifndef NET_21
-+ skb->free = 1;
-+#endif /* !NET_21 */
-+
-+ if((error = sock_queue_rcv_skb(sk, skb)) < 0) {
-+ skb->sk=NULL;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_upmsg: "
-+ "error=%d calling sock_queue_rcv_skb with skb=0p%p.\n",
-+ error,
-+ skb);
-+ ipsec_kfree_skb(skb);
-+ return error;
-+ }
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ if(sock == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_create: "
-+ "socket NULL.\n");
-+ return -EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_create: "
-+ "sock=0p%p type:%d state:%d flags:%ld protocol:%d\n",
-+ sock,
-+ sock->type,
-+ (unsigned int)(sock->state),
-+ sock->flags, protocol);
-+
-+ if(sock->type != SOCK_RAW) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_create: "
-+ "only SOCK_RAW supported.\n");
-+ return -ESOCKTNOSUPPORT;
-+ }
-+
-+ if(protocol != PF_KEY_V2) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_create: "
-+ "protocol not PF_KEY_V2.\n");
-+ return -EPROTONOSUPPORT;
-+ }
-+
-+ if((current->uid != 0)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_create: "
-+ "must be root to open pfkey sockets.\n");
-+ return -EACCES;
-+ }
-+
-+#ifdef NET_21
-+ sock->state = SS_UNCONNECTED;
-+#endif /* NET_21 */
-+ MOD_INC_USE_COUNT;
-+#ifdef NET_21
-+ if((sk=(struct sock *)sk_alloc(PF_KEY, GFP_KERNEL, 1)) == NULL)
-+#else /* NET_21 */
-+ if((sk=(struct sock *)sk_alloc(GFP_KERNEL)) == NULL)
-+#endif /* NET_21 */
-+ {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_create: "
-+ "Out of memory trying to allocate.\n");
-+ MOD_DEC_USE_COUNT;
-+ return -ENOMEM;
-+ }
-+
-+#ifndef NET_21
-+ memset(sk, 0, sizeof(*sk));
-+#endif /* !NET_21 */
-+
-+#ifdef NET_21
-+ sock_init_data(sock, sk);
-+
-+ sk->destruct = NULL;
-+ sk->reuse = 1;
-+ sock->ops = &pfkey_ops;
-+
-+ sk->zapped=0;
-+ sk->family = PF_KEY;
-+/* sk->num = protocol; */
-+ sk->protocol = protocol;
-+ key_pid(sk) = current->pid;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_create: "
-+ "sock->fasync_list=0p%p sk->sleep=0p%p.\n",
-+ sock->fasync_list,
-+ sk->sleep);
-+#else /* NET_21 */
-+ sk->type=sock->type;
-+ init_timer(&sk->timer);
-+ skb_queue_head_init(&sk->write_queue);
-+ skb_queue_head_init(&sk->receive_queue);
-+ skb_queue_head_init(&sk->back_log);
-+ sk->rcvbuf=SK_RMEM_MAX;
-+ sk->sndbuf=SK_WMEM_MAX;
-+ sk->allocation=GFP_KERNEL;
-+ sk->state=TCP_CLOSE;
-+ sk->priority=SOPRI_NORMAL;
-+ sk->state_change=pfkey_state_change;
-+ sk->data_ready=pfkey_data_ready;
-+ sk->write_space=pfkey_write_space;
-+ sk->error_report=pfkey_state_change;
-+ sk->mtu=4096;
-+ sk->socket=sock;
-+ sock->data=(void *)sk;
-+ sk->sleep=sock->wait;
-+#endif /* NET_21 */
-+
-+ pfkey_insert_socket(sk);
-+ pfkey_list_insert_socket(sock, &pfkey_open_sockets);
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_create: "
-+ "Socket sock=0p%p sk=0p%p initialised.\n", sock, sk);
-+ return 0;
-+}
-+
-+#ifndef NET_21
-+DEBUG_NO_STATIC int
-+pfkey_dup(struct socket *newsock, struct socket *oldsock)
-+{
-+ struct sock *sk;
-+
-+ if(newsock==NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_dup: "
-+ "No new socket attached.\n");
-+ return -EINVAL;
-+ }
-+
-+ if(oldsock==NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_dup: "
-+ "No old socket attached.\n");
-+ return -EINVAL;
-+ }
-+
-+#ifdef NET_21
-+ sk=oldsock->sk;
-+#else /* NET_21 */
-+ sk=oldsock->data;
-+#endif /* NET_21 */
-+
-+ /* May not have data attached */
-+ if(sk==NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_dup: "
-+ "No sock attached to old socket.\n");
-+ return -EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_dup: .\n");
-+
-+ return pfkey_create(newsock, sk->protocol);
-+}
-+#endif /* !NET_21 */
-+
-+DEBUG_NO_STATIC int
-+#ifdef NETDEV_23
-+pfkey_release(struct socket *sock)
-+#else /* NETDEV_23 */
-+pfkey_release(struct socket *sock, struct socket *peersock)
-+#endif /* NETDEV_23 */
-+{
-+ struct sock *sk;
-+ int i;
-+
-+ if(sock==NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_release: "
-+ "No socket attached.\n");
-+ return 0; /* -EINVAL; */
-+ }
-+
-+#ifdef NET_21
-+ sk=sock->sk;
-+#else /* NET_21 */
-+ sk=sock->data;
-+#endif /* NET_21 */
-+
-+ /* May not have data attached */
-+ if(sk==NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_release: "
-+ "No sk attached to sock=0p%p.\n", sock);
-+ return 0; /* -EINVAL; */
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_release: "
-+ "sock=0p%p sk=0p%p\n", sock, sk);
-+
-+#ifdef NET_21
-+ if(!sk->dead)
-+#endif /* NET_21 */
-+ if(sk->state_change) {
-+ sk->state_change(sk);
-+ }
-+
-+#ifdef NET_21
-+ sock->sk = NULL;
-+#else /* NET_21 */
-+ sock->data = NULL;
-+#endif /* NET_21 */
-+
-+ /* Try to flush out this socket. Throw out buffers at least */
-+ pfkey_destroy_socket(sk);
-+ pfkey_list_remove_socket(sock, &pfkey_open_sockets);
-+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
-+ pfkey_list_remove_socket(sock, &(pfkey_registered_sockets[i]));
-+ }
-+
-+ MOD_DEC_USE_COUNT;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_release: "
-+ "succeeded.\n");
-+
-+ return 0;
-+}
-+
-+#ifndef NET_21
-+DEBUG_NO_STATIC int
-+pfkey_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_bind: "
-+ "operation not supported.\n");
-+ return -EINVAL;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_connect: "
-+ "operation not supported.\n");
-+ return -EINVAL;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_socketpair(struct socket *a, struct socket *b)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_socketpair: "
-+ "operation not supported.\n");
-+ return -EINVAL;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_accept(struct socket *sock, struct socket *newsock, int flags)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_aaccept: "
-+ "operation not supported.\n");
-+ return -EINVAL;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len,
-+ int peer)
-+{
-+ struct sockaddr *ska = (struct sockaddr*)uaddr;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_getname: .\n");
-+ ska->sa_family = PF_KEY;
-+ *uaddr_len = sizeof(*ska);
-+ return 0;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_select(struct socket *sock, int sel_type, select_table *wait)
-+{
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_select: "
-+ ".sock=0p%p sk=0p%p sel_type=%d\n",
-+ sock,
-+ sock->data,
-+ sel_type);
-+ if(sock == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_select: "
-+ "Null socket passed in.\n");
-+ return -EINVAL;
-+ }
-+ return datagram_select(sock->data, sel_type, wait);
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ioctl: "
-+ "not supported.\n");
-+ return -EINVAL;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_listen(struct socket *sock, int backlog)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_listen: "
-+ "not supported.\n");
-+ return -EINVAL;
-+}
-+#endif /* !NET_21 */
-+
-+DEBUG_NO_STATIC int
-+pfkey_shutdown(struct socket *sock, int mode)
-+{
-+ struct sock *sk;
-+
-+ if(sock == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_shutdown: "
-+ "NULL socket passed in.\n");
-+ return -EINVAL;
-+ }
-+
-+#ifdef NET_21
-+ sk=sock->sk;
-+#else /* NET_21 */
-+ sk=sock->data;
-+#endif /* NET_21 */
-+
-+ if(sk == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_shutdown: "
-+ "No sock attached to socket.\n");
-+ return -EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_shutdown: "
-+ "mode=%x.\n", mode);
-+ mode++;
-+
-+ if(mode&SEND_SHUTDOWN) {
-+ sk->shutdown|=SEND_SHUTDOWN;
-+ sk->state_change(sk);
-+ }
-+
-+ if(mode&RCV_SHUTDOWN) {
-+ sk->shutdown|=RCV_SHUTDOWN;
-+ sk->state_change(sk);
-+ }
-+ return 0;
-+}
-+
-+#ifndef NET_21
-+DEBUG_NO_STATIC int
-+pfkey_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
-+{
-+#ifndef NET_21
-+ struct sock *sk;
-+
-+ if(sock == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_setsockopt: "
-+ "Null socket passed in.\n");
-+ return -EINVAL;
-+ }
-+
-+ sk=sock->data;
-+
-+ if(sk == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_setsockopt: "
-+ "Null sock passed in.\n");
-+ return -EINVAL;
-+ }
-+#endif /* !NET_21 */
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_setsockopt: .\n");
-+ if(level!=SOL_SOCKET) {
-+ return -EOPNOTSUPP;
-+ }
-+#ifdef NET_21
-+ return sock_setsockopt(sock, level, optname, optval, optlen);
-+#else /* NET_21 */
-+ return sock_setsockopt(sk, level, optname, optval, optlen);
-+#endif /* NET_21 */
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
-+{
-+#ifndef NET_21
-+ struct sock *sk;
-+
-+ if(sock == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_setsockopt: "
-+ "Null socket passed in.\n");
-+ return -EINVAL;
-+ }
-+
-+ sk=sock->data;
-+
-+ if(sk == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_setsockopt: "
-+ "Null sock passed in.\n");
-+ return -EINVAL;
-+ }
-+#endif /* !NET_21 */
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_getsockopt: .\n");
-+ if(level!=SOL_SOCKET) {
-+ return -EOPNOTSUPP;
-+ }
-+#ifdef NET_21
-+ return sock_getsockopt(sock, level, optname, optval, optlen);
-+#else /* NET_21 */
-+ return sock_getsockopt(sk, level, optname, optval, optlen);
-+#endif /* NET_21 */
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_fcntl: "
-+ "not supported.\n");
-+ return -EINVAL;
-+}
-+#endif /* !NET_21 */
-+
-+/*
-+ * Send PF_KEY data down.
-+ */
-+
-+DEBUG_NO_STATIC int
-+#ifdef NET_21
-+pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
-+#else /* NET_21 */
-+pfkey_sendmsg(struct socket *sock, struct msghdr *msg, int len, int nonblock, int flags)
-+#endif /* NET_21 */
-+{
-+ struct sock *sk;
-+ int error = 0;
-+ struct sadb_msg *pfkey_msg = NULL, *pfkey_reply = NULL;
-+
-+ if(sock == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "Null socket passed in.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+#ifdef NET_21
-+ sk = sock->sk;
-+#else /* NET_21 */
-+ sk = sock->data;
-+#endif /* NET_21 */
-+
-+ if(sk == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "Null sock passed in.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(msg == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "Null msghdr passed in.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: .\n");
-+ if(sk->err) {
-+ error = sock_error(sk);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "sk->err is non-zero, returns %d.\n",
-+ error);
-+ SENDERR(-error);
-+ }
-+
-+ if((current->uid != 0)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "must be root to send messages to pfkey sockets.\n");
-+ SENDERR(EACCES);
-+ }
-+
-+#ifdef NET_21
-+ if(msg->msg_control)
-+#else /* NET_21 */
-+ if(flags || msg->msg_control)
-+#endif /* NET_21 */
-+ {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "can't set flags or set msg_control.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(sk->shutdown & SEND_SHUTDOWN) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "shutdown.\n");
-+ send_sig(SIGPIPE, current, 0);
-+ SENDERR(EPIPE);
-+ }
-+
-+ if(len < sizeof(struct sadb_msg)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "bogus msg len of %d, too small.\n", len);
-+ SENDERR(EMSGSIZE);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "allocating %d bytes for downward message.\n",
-+ len);
-+ if((pfkey_msg = (struct sadb_msg*)kmalloc(len, GFP_KERNEL)) == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "memory allocation error.\n");
-+ SENDERR(ENOBUFS);
-+ }
-+
-+ memcpy_fromiovec((void *)pfkey_msg, msg->msg_iov, len);
-+
-+ if(pfkey_msg->sadb_msg_version != PF_KEY_V2) {
-+ KLIPS_PRINT(1 || debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "not PF_KEY_V2 msg, found %d, should be %d.\n",
-+ pfkey_msg->sadb_msg_version,
-+ PF_KEY_V2);
-+ kfree((void*)pfkey_msg);
-+ return -EINVAL;
-+ }
-+
-+ if(len != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "bogus msg len of %d, not %d byte aligned.\n",
-+ len, (int)IPSEC_PFKEYv2_ALIGN);
-+ SENDERR(EMSGSIZE);
-+ }
-+
-+#if 0
-+ /* This check is questionable, since a downward message could be
-+ the result of an ACQUIRE either from kernel (PID==0) or
-+ userspace (some other PID). */
-+ /* check PID */
-+ if(pfkey_msg->sadb_msg_pid != current->pid) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "pid (%d) does not equal sending process pid (%d).\n",
-+ pfkey_msg->sadb_msg_pid, current->pid);
-+ SENDERR(EINVAL);
-+ }
-+#endif
-+
-+ if(pfkey_msg->sadb_msg_reserved) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "reserved field must be zero, set to %d.\n",
-+ pfkey_msg->sadb_msg_reserved);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if((pfkey_msg->sadb_msg_type > SADB_MAX) || (!pfkey_msg->sadb_msg_type)){
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "msg type too large or small:%d.\n",
-+ pfkey_msg->sadb_msg_type);
-+ SENDERR(EINVAL);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "msg sent for parsing.\n");
-+
-+ if((error = pfkey_msg_interp(sk, pfkey_msg, &pfkey_reply))) {
-+ struct socket_list *pfkey_socketsp;
-+
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
-+ "pfkey_msg_parse returns %d.\n",
-+ error);
-+
-+ if((pfkey_reply = (struct sadb_msg*)kmalloc(sizeof(struct sadb_msg), GFP_KERNEL)) == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "memory allocation error.\n");
-+ SENDERR(ENOBUFS);
-+ }
-+ memcpy((void*)pfkey_reply, (void*)pfkey_msg, sizeof(struct sadb_msg));
-+ pfkey_reply->sadb_msg_errno = -error;
-+ pfkey_reply->sadb_msg_len = sizeof(struct sadb_msg) / IPSEC_PFKEYv2_ALIGN;
-+
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ int error_upmsg = 0;
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
-+ "sending up error=%d message=0p%p to socket=0p%p.\n",
-+ error,
-+ pfkey_reply,
-+ pfkey_socketsp->socketp);
-+ if((error_upmsg = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
-+ "sending up error message to socket=0p%p failed with error=%d.\n",
-+ pfkey_socketsp->socketp,
-+ error_upmsg);
-+ /* pfkey_msg_free(&pfkey_reply); */
-+ /* SENDERR(-error); */
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_sendmsg: "
-+ "sending up error message to socket=0p%p succeeded.\n",
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ pfkey_msg_free(&pfkey_reply);
-+
-+ SENDERR(-error);
-+ }
-+
-+ errlab:
-+ if (pfkey_msg) {
-+ kfree((void*)pfkey_msg);
-+ }
-+
-+ if(error) {
-+ return error;
-+ } else {
-+ return len;
-+ }
-+}
-+
-+/*
-+ * Receive PF_KEY data up.
-+ */
-+
-+DEBUG_NO_STATIC int
-+#ifdef NET_21
-+pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm)
-+#else /* NET_21 */
-+pfkey_recvmsg(struct socket *sock, struct msghdr *msg, int size, int noblock, int flags, int *addr_len)
-+#endif /* NET_21 */
-+{
-+ struct sock *sk;
-+#ifdef NET_21
-+ int noblock = flags & MSG_DONTWAIT;
-+#endif /* NET_21 */
-+ struct sk_buff *skb;
-+ int error;
-+
-+ if(sock == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_recvmsg: "
-+ "Null socket passed in.\n");
-+ return -EINVAL;
-+ }
-+
-+#ifdef NET_21
-+ sk = sock->sk;
-+#else /* NET_21 */
-+ sk = sock->data;
-+#endif /* NET_21 */
-+
-+ if(sk == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_recvmsg: "
-+ "Null sock passed in for sock=0p%p.\n", sock);
-+ return -EINVAL;
-+ }
-+
-+ if(msg == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_recvmsg: "
-+ "Null msghdr passed in for sock=0p%p, sk=0p%p.\n",
-+ sock, sk);
-+ return -EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_recvmsg: sock=0p%p sk=0p%p msg=0p%p size=%d.\n",
-+ sock, sk, msg, size);
-+ if(flags & ~MSG_PEEK) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "flags (%d) other than MSG_PEEK not supported.\n",
-+ flags);
-+ return -EOPNOTSUPP;
-+ }
-+
-+#ifdef NET_21
-+ msg->msg_namelen = 0; /* sizeof(*ska); */
-+#else /* NET_21 */
-+ if(addr_len) {
-+ *addr_len = 0; /* sizeof(*ska); */
-+ }
-+#endif /* NET_21 */
-+
-+ if(sk->err) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sendmsg: "
-+ "sk->err=%d.\n", sk->err);
-+ return sock_error(sk);
-+ }
-+
-+ if((skb = skb_recv_datagram(sk, flags, noblock, &error) ) == NULL) {
-+ return error;
-+ }
-+
-+ if(size > skb->len) {
-+ size = skb->len;
-+ }
-+#ifdef NET_21
-+ else if(size <skb->len) {
-+ msg->msg_flags |= MSG_TRUNC;
-+ }
-+#endif /* NET_21 */
-+
-+ skb_copy_datagram_iovec(skb, 0, msg->msg_iov, size);
-+ sk->stamp=skb->stamp;
-+
-+ skb_free_datagram(sk, skb);
-+ return size;
-+}
-+
-+#ifdef NET_21
-+struct net_proto_family pfkey_family_ops = {
-+ PF_KEY,
-+ pfkey_create
-+};
-+
-+struct proto_ops SOCKOPS_WRAPPED(pfkey_ops) = {
-+#ifdef NETDEV_23
-+ family: PF_KEY,
-+ release: pfkey_release,
-+ bind: sock_no_bind,
-+ connect: sock_no_connect,
-+ socketpair: sock_no_socketpair,
-+ accept: sock_no_accept,
-+ getname: sock_no_getname,
-+ poll: datagram_poll,
-+ ioctl: sock_no_ioctl,
-+ listen: sock_no_listen,
-+ shutdown: pfkey_shutdown,
-+ setsockopt: sock_no_setsockopt,
-+ getsockopt: sock_no_getsockopt,
-+ sendmsg: pfkey_sendmsg,
-+ recvmsg: pfkey_recvmsg,
-+ mmap: sock_no_mmap,
-+#else /* NETDEV_23 */
-+ PF_KEY,
-+ sock_no_dup,
-+ pfkey_release,
-+ sock_no_bind,
-+ sock_no_connect,
-+ sock_no_socketpair,
-+ sock_no_accept,
-+ sock_no_getname,
-+ datagram_poll,
-+ sock_no_ioctl,
-+ sock_no_listen,
-+ pfkey_shutdown,
-+ sock_no_setsockopt,
-+ sock_no_getsockopt,
-+ sock_no_fcntl,
-+ pfkey_sendmsg,
-+ pfkey_recvmsg
-+#endif /* NETDEV_23 */
-+};
-+
-+#ifdef NETDEV_23
-+#include <linux/smp_lock.h>
-+SOCKOPS_WRAP(pfkey, PF_KEY);
-+#endif /* NETDEV_23 */
-+
-+#else /* NET_21 */
-+struct proto_ops pfkey_proto_ops = {
-+ PF_KEY,
-+ pfkey_create,
-+ pfkey_dup,
-+ pfkey_release,
-+ pfkey_bind,
-+ pfkey_connect,
-+ pfkey_socketpair,
-+ pfkey_accept,
-+ pfkey_getname,
-+ pfkey_select,
-+ pfkey_ioctl,
-+ pfkey_listen,
-+ pfkey_shutdown,
-+ pfkey_setsockopt,
-+ pfkey_getsockopt,
-+ pfkey_fcntl,
-+ pfkey_sendmsg,
-+ pfkey_recvmsg
-+};
-+#endif /* NET_21 */
-+
-+#ifdef CONFIG_PROC_FS
-+#ifndef PROC_FS_2325
-+DEBUG_NO_STATIC
-+#endif /* PROC_FS_2325 */
-+int
-+pfkey_get_info(char *buffer, char **start, off_t offset, int length
-+#ifndef PROC_NO_DUMMY
-+, int dummy
-+#endif /* !PROC_NO_DUMMY */
-+)
-+{
-+ const int max_content = length > 0? length-1 : 0;
-+ off_t begin=0;
-+ int len=0;
-+ struct sock *sk=pfkey_sock_list;
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(!sysctl_ipsec_debug_verbose) {
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ len+= snprintf(buffer,length,
-+ " sock pid socket next prev e n p sndbf Flags Type St\n");
-+#ifdef CONFIG_IPSEC_DEBUG
-+ } else {
-+ len+= snprintf(buffer,length,
-+ " sock pid d sleep socket next prev e r z n p sndbf stamp Flags Type St\n");
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ while(sk!=NULL) {
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(!sysctl_ipsec_debug_verbose) {
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ "%8p %5d %8p %8p %8p %d %d %d %5d %08lX %8X %2X\n",
-+ sk,
-+ key_pid(sk),
-+ sk->socket,
-+ sk->next,
-+ sk->prev,
-+ sk->err,
-+ sk->num,
-+ sk->protocol,
-+ sk->sndbuf,
-+ sk->socket->flags,
-+ sk->socket->type,
-+ sk->socket->state);
-+#ifdef CONFIG_IPSEC_DEBUG
-+ } else {
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ "%8p %5d %d %8p %8p %8p %8p %d %d %d %d %d %5d %d.%06d %08lX %8X %2X\n",
-+ sk,
-+ key_pid(sk),
-+ sk->dead,
-+ sk->sleep,
-+ sk->socket,
-+ sk->next,
-+ sk->prev,
-+ sk->err,
-+ sk->reuse,
-+ sk->zapped,
-+ sk->num,
-+ sk->protocol,
-+ sk->sndbuf,
-+ (unsigned int)sk->stamp.tv_sec,
-+ (unsigned int)sk->stamp.tv_usec,
-+ sk->socket->flags,
-+ sk->socket->type,
-+ sk->socket->state);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ if (len >= max_content) {
-+ /* we've done all that can fit -- stop loop */
-+ len = max_content; /* truncate crap */
-+ break;
-+ } else {
-+
-+ const off_t pos = begin + len; /* file position of end of what we've generated */
-+
-+ if (pos <= offset) {
-+ /* all is before first interesting character:
-+ * discard, but note where we are.
-+ */
-+ len = 0;
-+ begin = pos;
-+ }
-+ }
-+ sk=sk->next;
-+
-+ }
-+
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ return len - (offset - begin);
-+
-+}
-+
-+#ifndef PROC_FS_2325
-+DEBUG_NO_STATIC
-+#endif /* PROC_FS_2325 */
-+int
-+pfkey_supported_get_info(char *buffer, char **start, off_t offset, int length
-+#ifndef PROC_NO_DUMMY
-+, int dummy
-+#endif /* !PROC_NO_DUMMY */
-+)
-+{
-+ const int max_content = length > 0? length-1 : 0;
-+ off_t begin=0;
-+ int len=0;
-+ int satype;
-+ struct supported_list *pfkey_supported_p;
-+
-+ len += ipsec_snprintf(buffer, length,
-+ "satype exttype alg_id ivlen minbits maxbits\n");
-+
-+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
-+ pfkey_supported_p = pfkey_supported_list[satype];
-+ while(pfkey_supported_p) {
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ " %2d %2d %2d %3d %3d %3d\n",
-+ satype,
-+ pfkey_supported_p->supportedp->supported_alg_exttype,
-+ pfkey_supported_p->supportedp->supported_alg_id,
-+ pfkey_supported_p->supportedp->supported_alg_ivlen,
-+ pfkey_supported_p->supportedp->supported_alg_minbits,
-+ pfkey_supported_p->supportedp->supported_alg_maxbits);
-+
-+ if (len >= max_content) {
-+ /* we've done all that can fit -- stop loop */
-+ len = max_content; /* truncate crap */
-+ break;
-+ } else {
-+ const off_t pos = begin + len; /* file position of end of what we've generated */
-+
-+ if (pos <= offset) {
-+ /* all is before first interesting character:
-+ * discard, but note where we are.
-+ */
-+ len = 0;
-+ begin = pos;
-+ }
-+ }
-+
-+ pfkey_supported_p = pfkey_supported_p->next;
-+ }
-+ }
-+
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ return len - (offset - begin);
-+
-+}
-+
-+#ifndef PROC_FS_2325
-+DEBUG_NO_STATIC
-+#endif /* PROC_FS_2325 */
-+int
-+pfkey_registered_get_info(char *buffer, char **start, off_t offset, int length
-+#ifndef PROC_NO_DUMMY
-+, int dummy
-+#endif /* !PROC_NO_DUMMY */
-+)
-+{
-+ const int max_content = length > 0? length-1 : 0;
-+ off_t begin=0;
-+ int len=0;
-+ int satype;
-+ struct socket_list *pfkey_sockets;
-+
-+ len += ipsec_snprintf(buffer, length,
-+ "satype socket pid sk\n");
-+
-+ for(satype = SADB_SATYPE_UNSPEC; satype <= SADB_SATYPE_MAX; satype++) {
-+ pfkey_sockets = pfkey_registered_sockets[satype];
-+ while(pfkey_sockets) {
-+#ifdef NET_21
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ " %2d %8p %5d %8p\n",
-+ satype,
-+ pfkey_sockets->socketp,
-+ key_pid(pfkey_sockets->socketp->sk),
-+ pfkey_sockets->socketp->sk);
-+#else /* NET_21 */
-+ len += ipsec_snprintf(buffer+len, length-len,
-+ " %2d %8p N/A %8p\n",
-+ satype,
-+ pfkey_sockets->socketp,
-+#if 0
-+ key_pid((pfkey_sockets->socketp)->data),
-+#endif
-+ (pfkey_sockets->socketp)->data);
-+#endif /* NET_21 */
-+
-+ if (len >= max_content) {
-+ /* we've done all that can fit -- stop loop (could stop two) */
-+ len = max_content; /* truncate crap */
-+ break;
-+ } else {
-+ const off_t pos = begin + len; /* file position of end of what we've generated */
-+
-+ if (pos <= offset) {
-+ /* all is before first interesting character:
-+ * discard, but note where we are.
-+ */
-+ len = 0;
-+ begin = pos;
-+ }
-+ }
-+
-+
-+ pfkey_sockets = pfkey_sockets->next;
-+ }
-+ }
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ return len - (offset - begin);
-+}
-+
-+#ifndef PROC_FS_2325
-+struct proc_dir_entry proc_net_pfkey =
-+{
-+ 0,
-+ 6, "pf_key",
-+ S_IFREG | S_IRUGO, 1, 0, 0,
-+ 0, &proc_net_inode_operations,
-+ pfkey_get_info
-+};
-+struct proc_dir_entry proc_net_pfkey_supported =
-+{
-+ 0,
-+ 16, "pf_key_supported",
-+ S_IFREG | S_IRUGO, 1, 0, 0,
-+ 0, &proc_net_inode_operations,
-+ pfkey_supported_get_info
-+};
-+struct proc_dir_entry proc_net_pfkey_registered =
-+{
-+ 0,
-+ 17, "pf_key_registered",
-+ S_IFREG | S_IRUGO, 1, 0, 0,
-+ 0, &proc_net_inode_operations,
-+ pfkey_registered_get_info
-+};
-+#endif /* !PROC_FS_2325 */
-+#endif /* CONFIG_PROC_FS */
-+
-+DEBUG_NO_STATIC int
-+supported_add_all(int satype, struct supported supported[], int size)
-+{
-+ int i;
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:init_pfkey: "
-+ "sizeof(supported_init_<satype=%d>)[%d]/sizeof(struct supported)[%d]=%d.\n",
-+ satype,
-+ size,
-+ (int)sizeof(struct supported),
-+ (int)(size/sizeof(struct supported)));
-+
-+ for(i = 0; i < size / sizeof(struct supported); i++) {
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:init_pfkey: "
-+ "i=%d inserting satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
-+ i,
-+ satype,
-+ supported[i].supported_alg_exttype,
-+ supported[i].supported_alg_id,
-+ supported[i].supported_alg_ivlen,
-+ supported[i].supported_alg_minbits,
-+ supported[i].supported_alg_maxbits);
-+
-+ error |= pfkey_list_insert_supported(&(supported[i]),
-+ &(pfkey_supported_list[satype]));
-+ }
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+supported_remove_all(int satype)
-+{
-+ int error = 0;
-+ struct supported*supportedp;
-+
-+ while(pfkey_supported_list[satype]) {
-+ supportedp = pfkey_supported_list[satype]->supportedp;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:init_pfkey: "
-+ "removing satype=%d exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
-+ satype,
-+ supportedp->supported_alg_exttype,
-+ supportedp->supported_alg_id,
-+ supportedp->supported_alg_ivlen,
-+ supportedp->supported_alg_minbits,
-+ supportedp->supported_alg_maxbits);
-+
-+ error |= pfkey_list_remove_supported(supportedp,
-+ &(pfkey_supported_list[satype]));
-+ }
-+ return error;
-+}
-+
-+int
-+pfkey_init(void)
-+{
-+ int error = 0;
-+ int i;
-+
-+ static struct supported supported_init_ah[] = {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160}
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ };
-+ static struct supported supported_init_esp[] = {
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_MD5HMAC, 0, 128, 128},
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+#ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ {SADB_EXT_SUPPORTED_AUTH, SADB_AALG_SHA1HMAC, 0, 160, 160},
-+#endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+#ifdef CONFIG_IPSEC_ENC_3DES
-+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_EALG_3DESCBC, 64, 168, 168},
-+#endif /* CONFIG_IPSEC_ENC_3DES */
-+ };
-+ static struct supported supported_init_ipip[] = {
-+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv4, 0, 32, 32}
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv4, 0, 128, 32}
-+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv4_in_IPv6, 0, 32, 128}
-+ , {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_TALG_IPv6_in_IPv6, 0, 128, 128}
-+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
-+ };
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ static struct supported supported_init_ipcomp[] = {
-+ {SADB_EXT_SUPPORTED_ENCRYPT, SADB_X_CALG_DEFLATE, 0, 1, 1}
-+ };
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#if 0
-+ printk(KERN_INFO
-+ "klips_info:pfkey_init: "
-+ "FreeS/WAN: initialising PF_KEYv2 domain sockets.\n");
-+#endif
-+
-+ for(i = SADB_SATYPE_UNSPEC; i <= SADB_SATYPE_MAX; i++) {
-+ pfkey_registered_sockets[i] = NULL;
-+ pfkey_supported_list[i] = NULL;
-+ }
-+
-+ error |= supported_add_all(SADB_SATYPE_AH, supported_init_ah, sizeof(supported_init_ah));
-+ error |= supported_add_all(SADB_SATYPE_ESP, supported_init_esp, sizeof(supported_init_esp));
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ error |= supported_add_all(SADB_X_SATYPE_COMP, supported_init_ipcomp, sizeof(supported_init_ipcomp));
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ error |= supported_add_all(SADB_X_SATYPE_IPIP, supported_init_ipip, sizeof(supported_init_ipip));
-+
-+#ifdef NET_21
-+ error |= sock_register(&pfkey_family_ops);
-+#else /* NET_21 */
-+ error |= sock_register(pfkey_proto_ops.family, &pfkey_proto_ops);
-+#endif /* NET_21 */
-+
-+#ifdef CONFIG_PROC_FS
-+# ifndef PROC_FS_2325
-+# ifdef PROC_FS_21
-+ error |= proc_register(proc_net, &proc_net_pfkey);
-+ error |= proc_register(proc_net, &proc_net_pfkey_supported);
-+ error |= proc_register(proc_net, &proc_net_pfkey_registered);
-+# else /* PROC_FS_21 */
-+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey);
-+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_supported);
-+ error |= proc_register_dynamic(&proc_net, &proc_net_pfkey_registered);
-+# endif /* PROC_FS_21 */
-+# else /* !PROC_FS_2325 */
-+ proc_net_create ("pf_key", 0, pfkey_get_info);
-+ proc_net_create ("pf_key_supported", 0, pfkey_supported_get_info);
-+ proc_net_create ("pf_key_registered", 0, pfkey_registered_get_info);
-+# endif /* !PROC_FS_2325 */
-+#endif /* CONFIG_PROC_FS */
-+
-+ return error;
-+}
-+
-+int
-+pfkey_cleanup(void)
-+{
-+ int error = 0;
-+
-+ printk(KERN_INFO "klips_info:pfkey_cleanup: "
-+ "shutting down PF_KEY domain sockets.\n");
-+#ifdef NET_21
-+ error |= sock_unregister(PF_KEY);
-+#else /* NET_21 */
-+ error |= sock_unregister(pfkey_proto_ops.family);
-+#endif /* NET_21 */
-+
-+ error |= supported_remove_all(SADB_SATYPE_AH);
-+ error |= supported_remove_all(SADB_SATYPE_ESP);
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ error |= supported_remove_all(SADB_X_SATYPE_COMP);
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ error |= supported_remove_all(SADB_X_SATYPE_IPIP);
-+
-+#ifdef CONFIG_PROC_FS
-+# ifndef PROC_FS_2325
-+ if (proc_net_unregister(proc_net_pfkey.low_ino) != 0)
-+ printk("klips_debug:pfkey_cleanup: "
-+ "cannot unregister /proc/net/pf_key\n");
-+ if (proc_net_unregister(proc_net_pfkey_supported.low_ino) != 0)
-+ printk("klips_debug:pfkey_cleanup: "
-+ "cannot unregister /proc/net/pf_key_supported\n");
-+ if (proc_net_unregister(proc_net_pfkey_registered.low_ino) != 0)
-+ printk("klips_debug:pfkey_cleanup: "
-+ "cannot unregister /proc/net/pf_key_registered\n");
-+# else /* !PROC_FS_2325 */
-+ proc_net_remove ("pf_key");
-+ proc_net_remove ("pf_key_supported");
-+ proc_net_remove ("pf_key_registered");
-+# endif /* !PROC_FS_2325 */
-+#endif /* CONFIG_PROC_FS */
-+
-+ /* other module unloading cleanup happens here */
-+ return error;
-+}
-+
-+#ifdef MODULE
-+#if 0
-+int
-+init_module(void)
-+{
-+ pfkey_init();
-+ return 0;
-+}
-+
-+void
-+cleanup_module(void)
-+{
-+ pfkey_cleanup();
-+}
-+#endif /* 0 */
-+#else /* MODULE */
-+void
-+pfkey_proto_init(struct net_proto *pro)
-+{
-+ pfkey_init();
-+}
-+#endif /* MODULE */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.81 2004/04/25 21:23:11 ken
-+ * Pull in dhr's changes from FreeS/WAN 2.06
-+ *
-+ * Revision 1.80 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.79.4.1 2003/12/22 15:25:52 jjo
-+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.79 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.78.4.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.78 2003/04/03 17:38:09 rgb
-+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
-+ *
-+ * Revision 1.77 2002/10/17 16:49:36 mcr
-+ * sock->ops should reference the unwrapped options so that
-+ * we get hacked in locking on SMP systems.
-+ *
-+ * Revision 1.76 2002/10/12 23:11:53 dhr
-+ *
-+ * [KenB + DHR] more 64-bit cleanup
-+ *
-+ * Revision 1.75 2002/09/20 05:01:57 rgb
-+ * Added memory allocation debugging.
-+ *
-+ * Revision 1.74 2002/09/19 02:42:50 mcr
-+ * do not define the pfkey_ops function for now.
-+ *
-+ * Revision 1.73 2002/09/17 17:29:23 mcr
-+ * #if 0 out some dead code - pfkey_ops is never used as written.
-+ *
-+ * Revision 1.72 2002/07/24 18:44:54 rgb
-+ * Type fiddling to tame ia64 compiler.
-+ *
-+ * Revision 1.71 2002/05/23 07:14:11 rgb
-+ * Cleaned up %p variants to 0p%p for test suite cleanup.
-+ *
-+ * Revision 1.70 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.69 2002/04/24 07:36:33 mcr
-+ * Moved from ./klips/net/ipsec/pfkey_v2.c,v
-+ *
-+ * Revision 1.68 2002/03/08 01:15:17 mcr
-+ * put some internal structure only debug messages behind
-+ * && sysctl_ipsec_debug_verbose.
-+ *
-+ * Revision 1.67 2002/01/29 17:17:57 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.66 2002/01/29 04:00:54 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.65 2002/01/29 02:13:18 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.64 2001/11/26 09:23:51 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.61.2.1 2001/09/25 02:28:44 mcr
-+ * cleaned up includes.
-+ *
-+ * Revision 1.63 2001/11/12 19:38:00 rgb
-+ * Continue trying other sockets even if one fails and return only original
-+ * error.
-+ *
-+ * Revision 1.62 2001/10/18 04:45:22 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/freeswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.61 2001/09/20 15:32:59 rgb
-+ * Min/max cleanup.
-+ *
-+ * Revision 1.60 2001/06/14 19:35:12 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.59 2001/06/13 15:35:48 rgb
-+ * Fixed #endif comments.
-+ *
-+ * Revision 1.58 2001/05/04 16:37:24 rgb
-+ * Remove erroneous checking of return codes for proc_net_* in 2.4.
-+ *
-+ * Revision 1.57 2001/05/03 19:43:36 rgb
-+ * Initialise error return variable.
-+ * Check error return codes in startup and shutdown.
-+ * Standardise on SENDERR() macro.
-+ *
-+ * Revision 1.56 2001/04/21 23:05:07 rgb
-+ * Define out skb->used for 2.4 kernels.
-+ *
-+ * Revision 1.55 2001/02/28 05:03:28 rgb
-+ * Clean up and rationalise startup messages.
-+ *
-+ * Revision 1.54 2001/02/27 22:24:55 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.53 2001/02/27 06:48:18 rgb
-+ * Fixed pfkey socket unregister log message to reflect type and function.
-+ *
-+ * Revision 1.52 2001/02/26 22:34:38 rgb
-+ * Fix error return code that was getting overwritten by the error return
-+ * code of an upmsg.
-+ *
-+ * Revision 1.51 2001/01/30 23:42:47 rgb
-+ * Allow pfkey msgs from pid other than user context required for ACQUIRE
-+ * and subsequent ADD or UDATE.
-+ *
-+ * Revision 1.50 2001/01/23 20:22:59 rgb
-+ * 2.4 fix to remove removed is_clone member.
-+ *
-+ * Revision 1.49 2000/11/06 04:33:47 rgb
-+ * Changed non-exported functions to DEBUG_NO_STATIC.
-+ *
-+ * Revision 1.48 2000/09/29 19:47:41 rgb
-+ * Update copyright.
-+ *
-+ * Revision 1.47 2000/09/22 04:23:04 rgb
-+ * Added more debugging to pfkey_upmsg() call from pfkey_sendmsg() error.
-+ *
-+ * Revision 1.46 2000/09/21 04:20:44 rgb
-+ * Fixed array size off-by-one error. (Thanks Svenning!)
-+ *
-+ * Revision 1.45 2000/09/20 04:01:26 rgb
-+ * Changed static functions to DEBUG_NO_STATIC for revealing function names
-+ * in oopsen.
-+ *
-+ * Revision 1.44 2000/09/19 00:33:17 rgb
-+ * 2.0 fixes.
-+ *
-+ * Revision 1.43 2000/09/16 01:28:13 rgb
-+ * Fixed use of 0 in p format warning.
-+ *
-+ * Revision 1.42 2000/09/16 01:09:41 rgb
-+ * Fixed debug format warning for pointers that was expecting ints.
-+ *
-+ * Revision 1.41 2000/09/13 15:54:00 rgb
-+ * Rewrote pfkey_get_info(), added pfkey_{supported,registered}_get_info().
-+ * Moved supported algos add and remove to functions.
-+ *
-+ * Revision 1.40 2000/09/12 18:49:28 rgb
-+ * Added IPIP tunnel and IPCOMP register support.
-+ *
-+ * Revision 1.39 2000/09/12 03:23:49 rgb
-+ * Converted #if0 debugs to sysctl.
-+ * Removed debug_pfkey initialisations that prevented no_debug loading or
-+ * linking.
-+ *
-+ * Revision 1.38 2000/09/09 06:38:02 rgb
-+ * Return positive errno in pfkey_reply error message.
-+ *
-+ * Revision 1.37 2000/09/08 19:19:09 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ * Clean-up of long-unused crud...
-+ * Create pfkey error message on on failure.
-+ * Give pfkey_list_{insert,remove}_{socket,supported}() some error
-+ * checking.
-+ *
-+ * Revision 1.36 2000/09/01 18:49:38 rgb
-+ * Reap experimental NET_21_ bits.
-+ * Turned registered sockets list into an array of one list per satype.
-+ * Remove references to deprecated sklist_{insert,remove}_socket.
-+ * Removed leaking socket debugging code.
-+ * Removed duplicate pfkey_insert_socket in pfkey_create.
-+ * Removed all references to pfkey msg->msg_name, since it is not used for
-+ * pfkey.
-+ * Added a supported algorithms array lists, one per satype and registered
-+ * existing algorithms.
-+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
-+ * list.
-+ * Only send pfkey_expire() messages to sockets registered for that satype.
-+ *
-+ * Revision 1.35 2000/08/24 17:03:00 rgb
-+ * Corrected message size error return code for PF_KEYv2.
-+ * Removed downward error prohibition.
-+ *
-+ * Revision 1.34 2000/08/21 16:32:26 rgb
-+ * Re-formatted for cosmetic consistency and readability.
-+ *
-+ * Revision 1.33 2000/08/20 21:38:24 rgb
-+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
-+ * Extended the upward message initiation of pfkey_sendmsg(). (Momchil)
-+ *
-+ * Revision 1.32 2000/07/28 14:58:31 rgb
-+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
-+ *
-+ * Revision 1.31 2000/05/16 03:04:00 rgb
-+ * Updates for 2.3.99pre8 from MB.
-+ *
-+ * Revision 1.30 2000/05/10 19:22:21 rgb
-+ * Use sklist private functions for 2.3.xx compatibility.
-+ *
-+ * Revision 1.29 2000/03/22 16:17:03 rgb
-+ * Fixed SOCKOPS_WRAPPED macro for SMP (MB).
-+ *
-+ * Revision 1.28 2000/02/21 19:30:45 rgb
-+ * Removed references to pkt_bridged for 2.3.47 compatibility.
-+ *
-+ * Revision 1.27 2000/02/14 21:07:00 rgb
-+ * Fixed /proc/net/pf-key legend spacing.
-+ *
-+ * Revision 1.26 2000/01/22 03:46:59 rgb
-+ * Fixed pfkey error return mechanism so that we are able to free the
-+ * local copy of the pfkey_msg, plugging a memory leak and silencing
-+ * the bad object free complaints.
-+ *
-+ * Revision 1.25 2000/01/21 06:19:44 rgb
-+ * Moved pfkey_list_remove_socket() calls to before MOD_USE_DEC_COUNT.
-+ * Added debugging to pfkey_upmsg.
-+ *
-+ * Revision 1.24 2000/01/10 16:38:23 rgb
-+ * MB fixups for 2.3.x.
-+ *
-+ * Revision 1.23 1999/12/09 23:22:16 rgb
-+ * Added more instrumentation for debugging 2.0 socket
-+ * selection/reading.
-+ * Removed erroneous 2.0 wait==NULL check bug in select.
-+ *
-+ * Revision 1.22 1999/12/08 20:32:16 rgb
-+ * Tidied up 2.0.xx support, after major pfkey work, eliminating
-+ * msg->msg_name twiddling in the process, since it is not defined
-+ * for PF_KEYv2.
-+ *
-+ * Revision 1.21 1999/12/01 22:17:19 rgb
-+ * Set skb->dev to zero on new skb in case it is a reused skb.
-+ * Added check for skb_put overflow and freeing to avoid upmsg on error.
-+ * Added check for wrong pfkey version and freeing to avoid upmsg on
-+ * error.
-+ * Shut off content dumping in pfkey_destroy.
-+ * Added debugging message for size of buffer allocated for upmsg.
-+ *
-+ * Revision 1.20 1999/11/27 12:11:00 rgb
-+ * Minor clean-up, enabling quiet operation of pfkey if desired.
-+ *
-+ * Revision 1.19 1999/11/25 19:04:21 rgb
-+ * Update proc_fs code for pfkey to use dynamic registration.
-+ *
-+ * Revision 1.18 1999/11/25 09:07:17 rgb
-+ * Implemented SENDERR macro for propagating error codes.
-+ * Fixed error return code bug.
-+ *
-+ * Revision 1.17 1999/11/23 23:07:20 rgb
-+ * Change name of pfkey_msg_parser to pfkey_msg_interp since it no longer
-+ * parses. (PJO)
-+ * Sort out pfkey and freeswan headers, putting them in a library path.
-+ *
-+ * Revision 1.16 1999/11/20 22:00:22 rgb
-+ * Moved socketlist type declarations and prototypes for shared use.
-+ * Renamed reformatted and generically extended for use by other socket
-+ * lists pfkey_{del,add}_open_socket to pfkey_list_{remove,insert}_socket.
-+ *
-+ * Revision 1.15 1999/11/18 04:15:09 rgb
-+ * Make pfkey_data_ready temporarily available for 2.2.x testing.
-+ * Clean up pfkey_destroy_socket() debugging statements.
-+ * Add Peter Onion's code to send messages up to all listening sockets.
-+ * Changed all occurrences of #include "../../../lib/freeswan.h"
-+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
-+ * klips/net/ipsec/Makefile.
-+ * Replaced all kernel version macros to shorter, readable form.
-+ * Added CONFIG_PROC_FS compiler directives in case it is shut off.
-+ *
-+ * Revision 1.14 1999/11/17 16:01:00 rgb
-+ * Make pfkey_data_ready temporarily available for 2.2.x testing.
-+ * Clean up pfkey_destroy_socket() debugging statements.
-+ * Add Peter Onion's code to send messages up to all listening sockets.
-+ * Changed #include "../../../lib/freeswan.h" to #include <freeswan.h>
-+ * which works due to -Ilibfreeswan in the klips/net/ipsec/Makefile.
-+ *
-+ * Revision 1.13 1999/10/27 19:59:51 rgb
-+ * Removed af_unix comments that are no longer relevant.
-+ * Added debug prink statements.
-+ * Added to the /proc output in pfkey_get_info.
-+ * Made most functions non-static to enable oops tracing.
-+ * Re-enable skb dequeueing and freeing.
-+ * Fix skb_alloc() and skb_put() size bug in pfkey_upmsg().
-+ *
-+ * Revision 1.12 1999/10/26 17:05:42 rgb
-+ * Complete re-ordering based on proto_ops structure order.
-+ * Separated out proto_ops structures for 2.0.x and 2.2.x for clarity.
-+ * Simplification to use built-in socket ops where possible for 2.2.x.
-+ * Add shorter macros for compiler directives to visually clean-up.
-+ * Add lots of sk skb dequeueing debugging statements.
-+ * Added to the /proc output in pfkey_get_info.
-+ *
-+ * Revision 1.11 1999/09/30 02:55:10 rgb
-+ * Bogus skb detection.
-+ * Fix incorrect /proc/net/ipsec-eroute printk message.
-+ *
-+ * Revision 1.10 1999/09/21 15:22:13 rgb
-+ * Temporary fix while I figure out the right way to destroy sockets.
-+ *
-+ * Revision 1.9 1999/07/08 19:19:44 rgb
-+ * Fix pointer format warning.
-+ * Fix missing member error under 2.0.xx kernels.
-+ *
-+ * Revision 1.8 1999/06/13 07:24:04 rgb
-+ * Add more debugging.
-+ *
-+ * Revision 1.7 1999/06/10 05:24:17 rgb
-+ * Clarified compiler directives.
-+ * Renamed variables to reduce confusion.
-+ * Used sklist_*_socket() kernel functions to simplify 2.2.x socket support.
-+ * Added lots of sanity checking.
-+ *
-+ * Revision 1.6 1999/06/03 18:59:50 rgb
-+ * More updates to 2.2.x socket support. Almost works, oops at end of call.
-+ *
-+ * Revision 1.5 1999/05/25 22:44:05 rgb
-+ * Start fixing 2.2 sockets.
-+ *
-+ * Revision 1.4 1999/04/29 15:21:34 rgb
-+ * Move log to the end of the file.
-+ * Eliminate min/max redefinition in #include <net/tcp.h>.
-+ * Correct path for pfkey #includes
-+ * Standardise an error return method.
-+ * Add debugging instrumentation.
-+ * Move message type checking to pfkey_msg_parse().
-+ * Add check for errno incorrectly set.
-+ * Add check for valid PID.
-+ * Add check for reserved illegally set.
-+ * Add check for message out of bounds.
-+ *
-+ * Revision 1.3 1999/04/15 17:58:07 rgb
-+ * Add RCSID labels.
-+ *
-+ * Revision 1.2 1999/04/15 15:37:26 rgb
-+ * Forward check changes from POST1_00 branch.
-+ *
-+ * Revision 1.1.2.2 1999/04/13 20:37:12 rgb
-+ * Header Title correction.
-+ *
-+ * Revision 1.1.2.1 1999/03/26 20:58:55 rgb
-+ * Add pfkeyv2 support to KLIPS.
-+ *
-+ *
-+ * RFC 2367
-+ * PF_KEY_v2 Key Management API
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/pfkey_v2_ext_process.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,922 @@
-+/*
-+ * @(#) RFC2367 PF_KEYv2 Key management API message parser
-+ * Copyright (C) 1998-2003 Richard Guy Briggs.
-+ * Copyright (C) 2004 Michael Richardson <mcr@xelerance.com>
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
-+ */
-+
-+char pfkey_v2_ext_process_c_version[] = "$Id$";
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+
-+#include <openswan.h>
-+
-+#include <crypto/des.h>
-+
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define ip_chk_addr inet_addr_type
-+# define IS_MYADDR RTN_LOCAL
-+#endif
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+#ifdef NETLINK_SOCK
-+# include <linux/netlink.h>
-+#else
-+# include <net/netlink.h>
-+#endif
-+
-+#include <linux/random.h> /* get_random_bytes() */
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_ah.h"
-+#include "openswan/ipsec_esp.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h"
-+#include "openswan/ipcomp.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+#include "openswan/ipsec_alg.h"
-+
-+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
-+
-+int
-+pfkey_sa_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ struct sadb_sa *pfkey_sa = (struct sadb_sa *)pfkey_ext;
-+ int error = 0;
-+ struct ipsec_sa* ipsp;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sa_process: .\n");
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sa_process: "
-+ "extr or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_ext->sadb_ext_type) {
-+ case SADB_EXT_SA:
-+ ipsp = extr->ips;
-+ break;
-+ case SADB_X_EXT_SA2:
-+ if(extr->ips2 == NULL) {
-+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
-+ }
-+ if(extr->ips2 == NULL) {
-+ SENDERR(-error);
-+ }
-+ ipsp = extr->ips2;
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sa_process: "
-+ "invalid exttype=%d.\n",
-+ pfkey_ext->sadb_ext_type);
-+ SENDERR(EINVAL);
-+ }
-+
-+ ipsp->ips_said.spi = pfkey_sa->sadb_sa_spi;
-+ ipsp->ips_replaywin = pfkey_sa->sadb_sa_replay;
-+ ipsp->ips_state = pfkey_sa->sadb_sa_state;
-+ ipsp->ips_flags = pfkey_sa->sadb_sa_flags;
-+ ipsp->ips_replaywin_lastseq = ipsp->ips_replaywin_bitmap = 0;
-+ ipsp->ips_ref_rel = pfkey_sa->sadb_x_sa_ref;
-+
-+ switch(ipsp->ips_said.proto) {
-+ case IPPROTO_AH:
-+ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
-+ ipsp->ips_encalg = SADB_EALG_NONE;
-+ break;
-+ case IPPROTO_ESP:
-+ ipsp->ips_authalg = pfkey_sa->sadb_sa_auth;
-+ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
-+#ifdef CONFIG_IPSEC_ALG
-+ ipsec_alg_sa_init(ipsp);
-+#endif /* CONFIG_IPSEC_ALG */
-+ break;
-+ case IPPROTO_IPIP:
-+ ipsp->ips_authalg = AH_NONE;
-+ ipsp->ips_encalg = ESP_NONE;
-+ break;
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ case IPPROTO_COMP:
-+ ipsp->ips_authalg = AH_NONE;
-+ ipsp->ips_encalg = pfkey_sa->sadb_sa_encrypt;
-+ break;
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ case IPPROTO_INT:
-+ ipsp->ips_authalg = AH_NONE;
-+ ipsp->ips_encalg = ESP_NONE;
-+ break;
-+ case 0:
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sa_process: "
-+ "unknown proto=%d.\n",
-+ ipsp->ips_said.proto);
-+ SENDERR(EINVAL);
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_lifetime_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct sadb_lifetime *pfkey_lifetime = (struct sadb_lifetime *)pfkey_ext;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_lifetime_process: .\n");
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_lifetime_process: "
-+ "extr or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_lifetime->sadb_lifetime_exttype) {
-+ case SADB_EXT_LIFETIME_CURRENT:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_lifetime_process: "
-+ "lifetime_current not supported yet.\n");
-+ SENDERR(EINVAL);
-+ break;
-+ case SADB_EXT_LIFETIME_HARD:
-+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_allocations,
-+ pfkey_lifetime->sadb_lifetime_allocations);
-+
-+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_bytes,
-+ pfkey_lifetime->sadb_lifetime_bytes);
-+
-+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_addtime,
-+ pfkey_lifetime->sadb_lifetime_addtime);
-+
-+ ipsec_lifetime_update_hard(&extr->ips->ips_life.ipl_usetime,
-+ pfkey_lifetime->sadb_lifetime_usetime);
-+
-+ break;
-+
-+ case SADB_EXT_LIFETIME_SOFT:
-+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_allocations,
-+ pfkey_lifetime->sadb_lifetime_allocations);
-+
-+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_bytes,
-+ pfkey_lifetime->sadb_lifetime_bytes);
-+
-+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_addtime,
-+ pfkey_lifetime->sadb_lifetime_addtime);
-+
-+ ipsec_lifetime_update_soft(&extr->ips->ips_life.ipl_usetime,
-+ pfkey_lifetime->sadb_lifetime_usetime);
-+
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_lifetime_process: "
-+ "invalid exttype=%d.\n",
-+ pfkey_ext->sadb_ext_type);
-+ SENDERR(EINVAL);
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_address_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ int saddr_len = 0;
-+ char ipaddr_txt[ADDRTOA_BUF];
-+ unsigned char **sap;
-+ unsigned short * portp = 0;
-+ struct sadb_address *pfkey_address = (struct sadb_address *)pfkey_ext;
-+ struct sockaddr* s = (struct sockaddr*)((char*)pfkey_address + sizeof(*pfkey_address));
-+ struct ipsec_sa* ipsp;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process:\n");
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "extr or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(s->sa_family) {
-+ case AF_INET:
-+ saddr_len = sizeof(struct sockaddr_in);
-+ addrtoa(((struct sockaddr_in*)s)->sin_addr, 0, ipaddr_txt, sizeof(ipaddr_txt));
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found address family=%d, AF_INET, %s.\n",
-+ s->sa_family,
-+ ipaddr_txt);
-+ break;
-+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-+ case AF_INET6:
-+ saddr_len = sizeof(struct sockaddr_in6);
-+ break;
-+#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "s->sa_family=%d not supported.\n",
-+ s->sa_family);
-+ SENDERR(EPFNOSUPPORT);
-+ }
-+
-+ switch(pfkey_address->sadb_address_exttype) {
-+ case SADB_EXT_ADDRESS_SRC:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found src address.\n");
-+ sap = (unsigned char **)&(extr->ips->ips_addr_s);
-+ extr->ips->ips_addr_s_size = saddr_len;
-+ break;
-+ case SADB_EXT_ADDRESS_DST:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found dst address.\n");
-+ sap = (unsigned char **)&(extr->ips->ips_addr_d);
-+ extr->ips->ips_addr_d_size = saddr_len;
-+ break;
-+ case SADB_EXT_ADDRESS_PROXY:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found proxy address.\n");
-+ sap = (unsigned char **)&(extr->ips->ips_addr_p);
-+ extr->ips->ips_addr_p_size = saddr_len;
-+ break;
-+ case SADB_X_EXT_ADDRESS_DST2:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found 2nd dst address.\n");
-+ if(extr->ips2 == NULL) {
-+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
-+ }
-+ if(extr->ips2 == NULL) {
-+ SENDERR(-error);
-+ }
-+ sap = (unsigned char **)&(extr->ips2->ips_addr_d);
-+ extr->ips2->ips_addr_d_size = saddr_len;
-+ break;
-+ case SADB_X_EXT_ADDRESS_SRC_FLOW:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found src flow address.\n");
-+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
-+ SENDERR(ENOMEM);
-+ }
-+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_src);
-+ portp = &(extr->eroute->er_eaddr.sen_sport);
-+ break;
-+ case SADB_X_EXT_ADDRESS_DST_FLOW:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found dst flow address.\n");
-+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
-+ SENDERR(ENOMEM);
-+ }
-+ sap = (unsigned char **)&(extr->eroute->er_eaddr.sen_ip_dst);
-+ portp = &(extr->eroute->er_eaddr.sen_dport);
-+ break;
-+ case SADB_X_EXT_ADDRESS_SRC_MASK:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found src mask address.\n");
-+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
-+ SENDERR(ENOMEM);
-+ }
-+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_src);
-+ portp = &(extr->eroute->er_emask.sen_sport);
-+ break;
-+ case SADB_X_EXT_ADDRESS_DST_MASK:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found dst mask address.\n");
-+ if(pfkey_alloc_eroute(&(extr->eroute)) == ENOMEM) {
-+ SENDERR(ENOMEM);
-+ }
-+ sap = (unsigned char **)&(extr->eroute->er_emask.sen_ip_dst);
-+ portp = &(extr->eroute->er_emask.sen_dport);
-+ break;
-+#ifdef NAT_TRAVERSAL
-+ case SADB_X_EXT_NAT_T_OA:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "found NAT-OA address.\n");
-+ sap = (unsigned char **)&(extr->ips->ips_natt_oa);
-+ extr->ips->ips_natt_oa_size = saddr_len;
-+ break;
-+#endif
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "unrecognised ext_type=%d.\n",
-+ pfkey_address->sadb_address_exttype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_address->sadb_address_exttype) {
-+ case SADB_EXT_ADDRESS_SRC:
-+ case SADB_EXT_ADDRESS_DST:
-+ case SADB_EXT_ADDRESS_PROXY:
-+ case SADB_X_EXT_ADDRESS_DST2:
-+#ifdef NAT_TRAVERSAL
-+ case SADB_X_EXT_NAT_T_OA:
-+#endif
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "allocating %d bytes for saddr.\n",
-+ saddr_len);
-+ if(!(*sap = kmalloc(saddr_len, GFP_KERNEL))) {
-+ SENDERR(ENOMEM);
-+ }
-+ memcpy(*sap, s, saddr_len);
-+ break;
-+ default:
-+ if(s->sa_family != AF_INET) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "s->sa_family=%d not supported.\n",
-+ s->sa_family);
-+ SENDERR(EPFNOSUPPORT);
-+ }
-+ (unsigned long)(*sap) = ((struct sockaddr_in*)s)->sin_addr.s_addr;
-+ if (portp != 0)
-+ *portp = ((struct sockaddr_in*)s)->sin_port;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(extr->eroute) {
-+ char buf1[64], buf2[64];
-+ if (debug_pfkey) {
-+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
-+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
-+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_parse: "
-+ "extr->eroute set to %s:%d->%s:%d\n",
-+ buf1,
-+ ntohs(extr->eroute->er_eaddr.sen_sport),
-+ buf2,
-+ ntohs(extr->eroute->er_eaddr.sen_dport));
-+ }
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ }
-+
-+ ipsp = extr->ips;
-+ switch(pfkey_address->sadb_address_exttype) {
-+ case SADB_X_EXT_ADDRESS_DST2:
-+ ipsp = extr->ips2;
-+ case SADB_EXT_ADDRESS_DST:
-+ if(s->sa_family == AF_INET) {
-+ ipsp->ips_said.dst.u.v4.sin_addr.s_addr = ((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr.s_addr;
-+ ipsp->ips_said.dst.u.v4.sin_family = AF_INET;
-+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
-+ 0,
-+ ipaddr_txt,
-+ sizeof(ipaddr_txt));
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "ips_said.dst set to %s.\n",
-+ ipaddr_txt);
-+ } else {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: "
-+ "uh, ips_said.dst doesn't do address family=%d yet, said will be invalid.\n",
-+ s->sa_family);
-+ }
-+ default:
-+ break;
-+ }
-+
-+ /* XXX check if port!=0 */
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_address_process: successful.\n");
-+ errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_key_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct sadb_key *pfkey_key = (struct sadb_key *)pfkey_ext;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_key_process: .\n");
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_key_process: "
-+ "extr or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_key->sadb_key_exttype) {
-+ case SADB_EXT_KEY_AUTH:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_key_process: "
-+ "allocating %d bytes for authkey.\n",
-+ DIVUP(pfkey_key->sadb_key_bits, 8));
-+ if(!(extr->ips->ips_key_a = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_key_process: "
-+ "memory allocation error.\n");
-+ SENDERR(ENOMEM);
-+ }
-+ extr->ips->ips_key_bits_a = pfkey_key->sadb_key_bits;
-+ extr->ips->ips_key_a_size = DIVUP(pfkey_key->sadb_key_bits, 8);
-+ memcpy(extr->ips->ips_key_a,
-+ (char*)pfkey_key + sizeof(struct sadb_key),
-+ extr->ips->ips_key_a_size);
-+ break;
-+ case SADB_EXT_KEY_ENCRYPT: /* Key(s) */
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_key_process: "
-+ "allocating %d bytes for enckey.\n",
-+ DIVUP(pfkey_key->sadb_key_bits, 8));
-+ if(!(extr->ips->ips_key_e = kmalloc(DIVUP(pfkey_key->sadb_key_bits, 8), GFP_KERNEL))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_key_process: "
-+ "memory allocation error.\n");
-+ SENDERR(ENOMEM);
-+ }
-+ extr->ips->ips_key_bits_e = pfkey_key->sadb_key_bits;
-+ extr->ips->ips_key_e_size = DIVUP(pfkey_key->sadb_key_bits, 8);
-+ memcpy(extr->ips->ips_key_e,
-+ (char*)pfkey_key + sizeof(struct sadb_key),
-+ extr->ips->ips_key_e_size);
-+ break;
-+ default:
-+ SENDERR(EINVAL);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_key_process: "
-+ "success.\n");
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_ident_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct sadb_ident *pfkey_ident = (struct sadb_ident *)pfkey_ext;
-+ int data_len;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ident_process: .\n");
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ident_process: "
-+ "extr or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_ident->sadb_ident_exttype) {
-+ case SADB_EXT_IDENTITY_SRC:
-+ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
-+
-+ extr->ips->ips_ident_s.type = pfkey_ident->sadb_ident_type;
-+ extr->ips->ips_ident_s.id = pfkey_ident->sadb_ident_id;
-+ extr->ips->ips_ident_s.len = pfkey_ident->sadb_ident_len;
-+ if(data_len) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ident_process: "
-+ "allocating %d bytes for ident_s.\n",
-+ data_len);
-+ if(!(extr->ips->ips_ident_s.data
-+ = kmalloc(data_len, GFP_KERNEL))) {
-+ SENDERR(ENOMEM);
-+ }
-+ memcpy(extr->ips->ips_ident_s.data,
-+ (char*)pfkey_ident + sizeof(struct sadb_ident),
-+ data_len);
-+ } else {
-+ extr->ips->ips_ident_s.data = NULL;
-+ }
-+ break;
-+ case SADB_EXT_IDENTITY_DST: /* Identity(ies) */
-+ data_len = pfkey_ident->sadb_ident_len * IPSEC_PFKEYv2_ALIGN - sizeof(struct sadb_ident);
-+
-+ extr->ips->ips_ident_d.type = pfkey_ident->sadb_ident_type;
-+ extr->ips->ips_ident_d.id = pfkey_ident->sadb_ident_id;
-+ extr->ips->ips_ident_d.len = pfkey_ident->sadb_ident_len;
-+ if(data_len) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ident_process: "
-+ "allocating %d bytes for ident_d.\n",
-+ data_len);
-+ if(!(extr->ips->ips_ident_d.data
-+ = kmalloc(data_len, GFP_KERNEL))) {
-+ SENDERR(ENOMEM);
-+ }
-+ memcpy(extr->ips->ips_ident_d.data,
-+ (char*)pfkey_ident + sizeof(struct sadb_ident),
-+ data_len);
-+ } else {
-+ extr->ips->ips_ident_d.data = NULL;
-+ }
-+ break;
-+ default:
-+ SENDERR(EINVAL);
-+ }
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_sens_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_sens_process: "
-+ "Sorry, I can't process exttype=%d yet.\n",
-+ pfkey_ext->sadb_ext_type);
-+ SENDERR(EINVAL); /* don't process these yet */
-+ errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_prop_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_prop_process: "
-+ "Sorry, I can't process exttype=%d yet.\n",
-+ pfkey_ext->sadb_ext_type);
-+ SENDERR(EINVAL); /* don't process these yet */
-+
-+ errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_supported_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_supported_process: "
-+ "Sorry, I can't process exttype=%d yet.\n",
-+ pfkey_ext->sadb_ext_type);
-+ SENDERR(EINVAL); /* don't process these yet */
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_spirange_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_spirange_process: .\n");
-+/* errlab: */
-+ return error;
-+}
-+
-+int
-+pfkey_x_kmprivate_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_kmprivate_process: "
-+ "Sorry, I can't process exttype=%d yet.\n",
-+ pfkey_ext->sadb_ext_type);
-+ SENDERR(EINVAL); /* don't process these yet */
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_x_satype_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct sadb_x_satype *pfkey_x_satype = (struct sadb_x_satype *)pfkey_ext;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_satype_process: .\n");
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_satype_process: "
-+ "extr or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(extr->ips2 == NULL) {
-+ extr->ips2 = ipsec_sa_alloc(&error); /* pass error var by pointer */
-+ }
-+ if(extr->ips2 == NULL) {
-+ SENDERR(-error);
-+ }
-+ if(!(extr->ips2->ips_said.proto = satype2proto(pfkey_x_satype->sadb_x_satype_satype))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_satype_process: "
-+ "proto lookup from satype=%d failed.\n",
-+ pfkey_x_satype->sadb_x_satype_satype);
-+ SENDERR(EINVAL);
-+ }
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_satype_process: "
-+ "protocol==%d decoded from satype==%d(%s).\n",
-+ extr->ips2->ips_said.proto,
-+ pfkey_x_satype->sadb_x_satype_satype,
-+ satype2name(pfkey_x_satype->sadb_x_satype_satype));
-+
-+errlab:
-+ return error;
-+}
-+
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+int
-+pfkey_x_nat_t_type_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct sadb_x_nat_t_type *pfkey_x_nat_t_type = (struct sadb_x_nat_t_type *)pfkey_ext;
-+
-+ if(!pfkey_x_nat_t_type) {
-+ printk("klips_debug:pfkey_x_nat_t_type_process: "
-+ "null pointer passed in\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_nat_t_type_process: %d.\n",
-+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_nat_t_type_process: "
-+ "extr or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_x_nat_t_type->sadb_x_nat_t_type_type) {
-+ case ESPINUDP_WITH_NON_IKE: /* with Non-IKE (older version) */
-+ case ESPINUDP_WITH_NON_ESP: /* with Non-ESP */
-+
-+ extr->ips->ips_natt_type = pfkey_x_nat_t_type->sadb_x_nat_t_type_type;
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_nat_t_type_process: "
-+ "unknown type %d.\n",
-+ pfkey_x_nat_t_type->sadb_x_nat_t_type_type);
-+ SENDERR(EINVAL);
-+ break;
-+ }
-+
-+errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_x_nat_t_port_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct sadb_x_nat_t_port *pfkey_x_nat_t_port = (struct sadb_x_nat_t_port *)pfkey_ext;
-+
-+ if(!pfkey_x_nat_t_port) {
-+ printk("klips_debug:pfkey_x_nat_t_port_process: "
-+ "null pointer passed in\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_nat_t_port_process: %d/%d.\n",
-+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype,
-+ pfkey_x_nat_t_port->sadb_x_nat_t_port_port);
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_nat_t_type_process: "
-+ "extr or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype) {
-+ case SADB_X_EXT_NAT_T_SPORT:
-+ extr->ips->ips_natt_sport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
-+ break;
-+ case SADB_X_EXT_NAT_T_DPORT:
-+ extr->ips->ips_natt_dport = pfkey_x_nat_t_port->sadb_x_nat_t_port_port;
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_nat_t_port_process: "
-+ "unknown exttype %d.\n",
-+ pfkey_x_nat_t_port->sadb_x_nat_t_port_exttype);
-+ SENDERR(EINVAL);
-+ break;
-+ }
-+
-+errlab:
-+ return error;
-+}
-+#endif
-+
-+int
-+pfkey_x_debug_process(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct sadb_x_debug *pfkey_x_debug = (struct sadb_x_debug *)pfkey_ext;
-+
-+ if(!pfkey_x_debug) {
-+ printk("klips_debug:pfkey_x_debug_process: "
-+ "null pointer passed in\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_debug_process: .\n");
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(pfkey_x_debug->sadb_x_debug_netlink >>
-+ (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 - 1)) {
-+ pfkey_x_debug->sadb_x_debug_netlink &=
-+ ~(1 << (sizeof(pfkey_x_debug->sadb_x_debug_netlink) * 8 -1));
-+ debug_tunnel |= pfkey_x_debug->sadb_x_debug_tunnel;
-+ debug_netlink |= pfkey_x_debug->sadb_x_debug_netlink;
-+ debug_xform |= pfkey_x_debug->sadb_x_debug_xform;
-+ debug_eroute |= pfkey_x_debug->sadb_x_debug_eroute;
-+ debug_spi |= pfkey_x_debug->sadb_x_debug_spi;
-+ debug_radij |= pfkey_x_debug->sadb_x_debug_radij;
-+ debug_esp |= pfkey_x_debug->sadb_x_debug_esp;
-+ debug_ah |= pfkey_x_debug->sadb_x_debug_ah;
-+ debug_rcv |= pfkey_x_debug->sadb_x_debug_rcv;
-+ debug_pfkey |= pfkey_x_debug->sadb_x_debug_pfkey;
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ sysctl_ipsec_debug_ipcomp |= pfkey_x_debug->sadb_x_debug_ipcomp;
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ sysctl_ipsec_debug_verbose |= pfkey_x_debug->sadb_x_debug_verbose;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_debug_process: "
-+ "set\n");
-+ } else {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_debug_process: "
-+ "unset\n");
-+ debug_tunnel &= pfkey_x_debug->sadb_x_debug_tunnel;
-+ debug_netlink &= pfkey_x_debug->sadb_x_debug_netlink;
-+ debug_xform &= pfkey_x_debug->sadb_x_debug_xform;
-+ debug_eroute &= pfkey_x_debug->sadb_x_debug_eroute;
-+ debug_spi &= pfkey_x_debug->sadb_x_debug_spi;
-+ debug_radij &= pfkey_x_debug->sadb_x_debug_radij;
-+ debug_esp &= pfkey_x_debug->sadb_x_debug_esp;
-+ debug_ah &= pfkey_x_debug->sadb_x_debug_ah;
-+ debug_rcv &= pfkey_x_debug->sadb_x_debug_rcv;
-+ debug_pfkey &= pfkey_x_debug->sadb_x_debug_pfkey;
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ sysctl_ipsec_debug_ipcomp &= pfkey_x_debug->sadb_x_debug_ipcomp;
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ sysctl_ipsec_debug_verbose &= pfkey_x_debug->sadb_x_debug_verbose;
-+ }
-+#else /* CONFIG_IPSEC_DEBUG */
-+ printk("klips_debug:pfkey_x_debug_process: "
-+ "debugging not enabled\n");
-+ SENDERR(EINVAL);
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+errlab:
-+ return error;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.15 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.14 2004/02/03 03:13:59 mcr
-+ * no longer #ifdef out NON_ESP mode. That was a mistake.
-+ *
-+ * Revision 1.13 2003/12/15 18:13:12 mcr
-+ * when compiling with NAT traversal, don't assume that the
-+ * kernel has been patched, unless CONFIG_IPSEC_NAT_NON_ESP
-+ * is set.
-+ *
-+ * Revision 1.12.2.1 2003/12/22 15:25:52 jjo
-+ * Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.12 2003/12/10 01:14:27 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.11 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.10.4.2 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.10.4.1 2003/09/21 13:59:56 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.10 2003/02/06 01:51:41 rgb
-+ * Removed no longer relevant comment
-+ *
-+ * Revision 1.9 2003/01/30 02:32:44 rgb
-+ *
-+ * Transmit error code through to caller from callee for better diagnosis of problems.
-+ *
-+ * Revision 1.8 2002/12/13 22:42:22 mcr
-+ * restored sa_ref code
-+ *
-+ * Revision 1.7 2002/12/13 22:40:48 mcr
-+ * temporarily removed sadb_x_sa_ref reference for 2.xx
-+ *
-+ * Revision 1.6 2002/10/05 05:02:58 dhr
-+ *
-+ * C labels go on statements
-+ *
-+ * Revision 1.5 2002/09/20 15:41:08 rgb
-+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
-+ * Added sadb_x_sa_ref to struct sadb_sa.
-+ *
-+ * Revision 1.4 2002/09/20 05:02:02 rgb
-+ * Added memory allocation debugging.
-+ *
-+ * Revision 1.3 2002/07/24 18:44:54 rgb
-+ * Type fiddling to tame ia64 compiler.
-+ *
-+ * Revision 1.2 2002/05/27 18:55:03 rgb
-+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
-+ *
-+ * Revision 1.1 2002/05/14 02:33:51 rgb
-+ * Moved all the extension processing functions to pfkey_v2_ext_process.c.
-+ *
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/pfkey_v2_parser.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,4018 @@
-+/*
-+ * @(#) RFC2367 PF_KEYv2 Key management API message parser
-+ * Copyright (C) 1999, 2000, 2001 Richard Guy Briggs <rgb@freeswan.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License as published by the
-+ * Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+/*
-+ * Template from klips/net/ipsec/ipsec/ipsec_netlink.c.
-+ */
-+
-+char pfkey_v2_parser_c_version[] = "$Id$";
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+
-+#include <openswan.h>
-+
-+#include <crypto/des.h>
-+
-+#ifdef SPINLOCK
-+# ifdef SPINLOCK_23
-+# include <linux/spinlock.h> /* *lock* */
-+# else /* SPINLOCK_23 */
-+# include <asm/spinlock.h> /* *lock* */
-+# endif /* SPINLOCK_23 */
-+#endif /* SPINLOCK */
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+# define ip_chk_addr inet_addr_type
-+# define IS_MYADDR RTN_LOCAL
-+#endif
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+#ifdef NETLINK_SOCK
-+# include <linux/netlink.h>
-+#else
-+# include <net/netlink.h>
-+#endif
-+
-+#include <linux/random.h> /* get_random_bytes() */
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_sa.h"
-+
-+#include "openswan/ipsec_radij.h"
-+#include "openswan/ipsec_xform.h"
-+#include "openswan/ipsec_ah.h"
-+#include "openswan/ipsec_esp.h"
-+#include "openswan/ipsec_tunnel.h"
-+#include "openswan/ipsec_rcv.h"
-+#include "openswan/ipcomp.h"
-+
-+#include <pfkeyv2.h>
-+#include <pfkey.h>
-+
-+#include "openswan/ipsec_proto.h"
-+#include "openswan/ipsec_alg.h"
-+
-+
-+#define SENDERR(_x) do { error = -(_x); goto errlab; } while (0)
-+
-+struct sklist_t {
-+ struct socket *sk;
-+ struct sklist_t* next;
-+} pfkey_sklist_head, *pfkey_sklist, *pfkey_sklist_prev;
-+
-+__u32 pfkey_msg_seq = 0;
-+
-+
-+#if 0
-+#define DUMP_SAID dump_said(&extr->ips->ips_said, __LINE__)
-+#define DUMP_SAID2 dump_said(&extr.ips->ips_said, __LINE__)
-+static void dump_said(ip_said *s, int line)
-+{
-+ char msa[SATOT_BUF];
-+ size_t msa_len;
-+
-+ msa_len = satot(s, 0, msa, sizeof(msa));
-+
-+ printk("line: %d msa: %s\n", line, msa);
-+}
-+#endif
-+
-+
-+int
-+pfkey_alloc_eroute(struct eroute** eroute)
-+{
-+ int error = 0;
-+ if(*eroute) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_alloc_eroute: "
-+ "eroute struct already allocated\n");
-+ SENDERR(EEXIST);
-+ }
-+
-+ if((*eroute = kmalloc(sizeof(**eroute), GFP_ATOMIC) ) == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_alloc_eroute: "
-+ "memory allocation error\n");
-+ SENDERR(ENOMEM);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_alloc_eroute: "
-+ "allocating %lu bytes for an eroute at 0p%p\n",
-+ (unsigned long) sizeof(**eroute), *eroute);
-+
-+ memset((caddr_t)*eroute, 0, sizeof(**eroute));
-+ (*eroute)->er_eaddr.sen_len =
-+ (*eroute)->er_emask.sen_len = sizeof(struct sockaddr_encap);
-+ (*eroute)->er_eaddr.sen_family =
-+ (*eroute)->er_emask.sen_family = AF_ENCAP;
-+ (*eroute)->er_eaddr.sen_type = SENT_IP4;
-+ (*eroute)->er_emask.sen_type = 255;
-+ (*eroute)->er_pid = 0;
-+ (*eroute)->er_count = 0;
-+ (*eroute)->er_lasttime = jiffies/HZ;
-+
-+ errlab:
-+ return(error);
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_protocol_process(struct sadb_ext *pfkey_ext,
-+ struct pfkey_extracted_data *extr)
-+{
-+ int error = 0;
-+ struct sadb_protocol * p = (struct sadb_protocol *)pfkey_ext;
-+
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_protocol_process: %p\n", extr);
-+
-+ if (extr == 0) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_protocol_process:"
-+ "extr is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+ if (extr->eroute == 0) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_protocol_process:"
-+ "extr->eroute is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ extr->eroute->er_eaddr.sen_proto = p->sadb_protocol_proto;
-+ extr->eroute->er_emask.sen_proto = p->sadb_protocol_proto ? ~0:0;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_protocol_process: protocol = %d.\n",
-+ p->sadb_protocol_proto);
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_ipsec_sa_init(struct ipsec_sa *ipsp, struct sadb_ext **extensions)
-+{
-+ int i;
-+ int error = 0;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+ char ipaddr_txt[ADDRTOA_BUF];
-+ char ipaddr2_txt[ADDRTOA_BUF];
-+#if defined (CONFIG_IPSEC_AUTH_HMAC_MD5) || defined (CONFIG_IPSEC_AUTH_HMAC_SHA1)
-+ unsigned char kb[AHMD596_BLKLEN];
-+#endif
-+#ifdef CONFIG_IPSEC_ALG
-+ struct ipsec_alg_enc *ixt_e = NULL;
-+ struct ipsec_alg_auth *ixt_a = NULL;
-+#endif /* CONFIG_IPSEC_ALG */
-+
-+ if(ipsp == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "ipsp is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ sa_len = satot(&ipsp->ips_said, 0, sa, sizeof(sa));
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "(pfkey defined) called for SA:%s\n",
-+ sa_len ? sa : " (error)");
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "calling init routine of %s%s%s\n",
-+ IPS_XFORM_NAME(ipsp));
-+
-+ switch(ipsp->ips_said.proto) {
-+
-+#ifdef CONFIG_IPSEC_IPIP
-+ case IPPROTO_IPIP: {
-+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_s))->sin_addr,
-+ 0,
-+ ipaddr_txt, sizeof(ipaddr_txt));
-+ addrtoa(((struct sockaddr_in*)(ipsp->ips_addr_d))->sin_addr,
-+ 0,
-+ ipaddr2_txt, sizeof(ipaddr_txt));
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "(pfkey defined) IPIP ipsec_sa set for %s->%s.\n",
-+ ipaddr_txt,
-+ ipaddr2_txt);
-+ }
-+ break;
-+#endif /* !CONFIG_IPSEC_IPIP */
-+#ifdef CONFIG_IPSEC_AH
-+ case IPPROTO_AH:
-+ switch(ipsp->ips_authalg) {
-+# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5: {
-+ unsigned char *akp;
-+ unsigned int aks;
-+ MD5_CTX *ictx;
-+ MD5_CTX *octx;
-+
-+ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
-+ ipsp->ips_key_bits_a, AHMD596_KLEN * 8);
-+ SENDERR(EINVAL);
-+ }
-+
-+# if KLIPS_DIVULGE_HMAC_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
-+# endif /* KLIPS_DIVULGE_HMAC_KEY */
-+
-+ ipsp->ips_auth_bits = AHMD596_ALEN * 8;
-+
-+ /* save the pointer to the key material */
-+ akp = ipsp->ips_key_a;
-+ aks = ipsp->ips_key_a_size;
-+
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "allocating %lu bytes for md5_ctx.\n",
-+ (unsigned long) sizeof(struct md5_ctx));
-+ if((ipsp->ips_key_a = (caddr_t)
-+ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
-+ ipsp->ips_key_a = akp;
-+ SENDERR(ENOMEM);
-+ }
-+ ipsp->ips_key_a_size = sizeof(struct md5_ctx);
-+
-+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
-+ kb[i] = akp[i] ^ HMAC_IPAD;
-+ }
-+ for (; i < AHMD596_BLKLEN; i++) {
-+ kb[i] = HMAC_IPAD;
-+ }
-+
-+ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
-+ MD5Init(ictx);
-+ MD5Update(ictx, kb, AHMD596_BLKLEN);
-+
-+ for (i = 0; i < AHMD596_BLKLEN; i++) {
-+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
-+ }
-+
-+ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
-+ MD5Init(octx);
-+ MD5Update(octx, kb, AHMD596_BLKLEN);
-+
-+# if KLIPS_DIVULGE_HMAC_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
-+ ((__u32*)ictx)[0],
-+ ((__u32*)ictx)[1],
-+ ((__u32*)ictx)[2],
-+ ((__u32*)ictx)[3],
-+ ((__u32*)octx)[0],
-+ ((__u32*)octx)[1],
-+ ((__u32*)octx)[2],
-+ ((__u32*)octx)[3] );
-+# endif /* KLIPS_DIVULGE_HMAC_KEY */
-+
-+ /* zero key buffer -- paranoid */
-+ memset(akp, 0, aks);
-+ kfree(akp);
-+ }
-+ break;
-+# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA: {
-+ unsigned char *akp;
-+ unsigned int aks;
-+ SHA1_CTX *ictx;
-+ SHA1_CTX *octx;
-+
-+ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "incorrect key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
-+ ipsp->ips_key_bits_a, AHSHA196_KLEN * 8);
-+ SENDERR(EINVAL);
-+ }
-+
-+# if KLIPS_DIVULGE_HMAC_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
-+# endif /* KLIPS_DIVULGE_HMAC_KEY */
-+
-+ ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
-+
-+ /* save the pointer to the key material */
-+ akp = ipsp->ips_key_a;
-+ aks = ipsp->ips_key_a_size;
-+
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "allocating %lu bytes for sha1_ctx.\n",
-+ (unsigned long) sizeof(struct sha1_ctx));
-+ if((ipsp->ips_key_a = (caddr_t)
-+ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
-+ ipsp->ips_key_a = akp;
-+ SENDERR(ENOMEM);
-+ }
-+ ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
-+
-+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
-+ kb[i] = akp[i] ^ HMAC_IPAD;
-+ }
-+ for (; i < AHMD596_BLKLEN; i++) {
-+ kb[i] = HMAC_IPAD;
-+ }
-+
-+ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
-+ SHA1Init(ictx);
-+ SHA1Update(ictx, kb, AHSHA196_BLKLEN);
-+
-+ for (i = 0; i < AHSHA196_BLKLEN; i++) {
-+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
-+ }
-+
-+ octx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->octx);
-+ SHA1Init(octx);
-+ SHA1Update(octx, kb, AHSHA196_BLKLEN);
-+
-+# if KLIPS_DIVULGE_HMAC_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
-+ ((__u32*)ictx)[0],
-+ ((__u32*)ictx)[1],
-+ ((__u32*)ictx)[2],
-+ ((__u32*)ictx)[3],
-+ ((__u32*)octx)[0],
-+ ((__u32*)octx)[1],
-+ ((__u32*)octx)[2],
-+ ((__u32*)octx)[3] );
-+# endif /* KLIPS_DIVULGE_HMAC_KEY */
-+ /* zero key buffer -- paranoid */
-+ memset(akp, 0, aks);
-+ kfree(akp);
-+ }
-+ break;
-+# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "authalg=%d support not available in the kernel",
-+ ipsp->ips_authalg);
-+ SENDERR(EINVAL);
-+ }
-+ break;
-+#endif /* CONFIG_IPSEC_AH */
-+#ifdef CONFIG_IPSEC_ESP
-+ case IPPROTO_ESP: {
-+#if defined (CONFIG_IPSEC_AUTH_HMAC_MD5) || defined (CONFIG_IPSEC_AUTH_HMAC_SHA1)
-+ unsigned char *akp;
-+ unsigned int aks;
-+#endif
-+#if defined (CONFIG_IPSEC_ENC_3DES)
-+ unsigned char *ekp;
-+ unsigned int eks;
-+#endif
-+
-+ ipsp->ips_iv_size = 0;
-+#ifdef CONFIG_IPSEC_ALG
-+ if ((ixt_e=ipsp->ips_alg_enc)) {
-+ ipsp->ips_iv_size = ixt_e->ixt_ivlen/8;
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ipsp->ips_encalg) {
-+# ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+# endif /* CONFIG_IPSEC_ENC_3DES */
-+# if defined(CONFIG_IPSEC_ENC_3DES)
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "allocating %u bytes for iv.\n",
-+ EMT_ESPDES_IV_SZ);
-+ if((ipsp->ips_iv = (caddr_t)
-+ kmalloc((ipsp->ips_iv_size = EMT_ESPDES_IV_SZ), GFP_ATOMIC)) == NULL) {
-+ SENDERR(ENOMEM);
-+ }
-+ prng_bytes(&ipsec_prng, (char *)ipsp->ips_iv, EMT_ESPDES_IV_SZ);
-+ ipsp->ips_iv_bits = ipsp->ips_iv_size * 8;
-+ ipsp->ips_iv_size = EMT_ESPDES_IV_SZ;
-+ break;
-+# endif /* defined(CONFIG_IPSEC_ENC_3DES) */
-+ case ESP_NONE:
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "encalg=%d support not available in the kernel",
-+ ipsp->ips_encalg);
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* Create IV */
-+ if (ipsp->ips_iv_size) {
-+ if((ipsp->ips_iv = (caddr_t)
-+ kmalloc(ipsp->ips_iv_size, GFP_ATOMIC)) == NULL) {
-+ SENDERR(ENOMEM);
-+ }
-+ prng_bytes(&ipsec_prng, (char *)ipsp->ips_iv, ipsp->ips_iv_size);
-+ ipsp->ips_iv_bits = ipsp->ips_iv_size * 8;
-+ }
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if (ixt_e) {
-+ if ((error=ipsec_alg_enc_key_create(ipsp)) < 0)
-+ SENDERR(-error);
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+ switch(ipsp->ips_encalg) {
-+# ifdef CONFIG_IPSEC_ENC_3DES
-+ case ESP_3DES:
-+ if(ipsp->ips_key_bits_e != (EMT_ESP3DES_KEY_SZ * 8)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "incorrect encryption key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
-+ ipsp->ips_key_bits_e, EMT_ESP3DES_KEY_SZ * 8);
-+ SENDERR(EINVAL);
-+ }
-+
-+ /* save encryption key pointer */
-+ ekp = ipsp->ips_key_e;
-+ eks = ipsp->ips_key_e_size;
-+
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "allocating %lu bytes for 3des.\n",
-+ (unsigned long) (3 * sizeof(struct des_eks)));
-+ if((ipsp->ips_key_e = (caddr_t)
-+ kmalloc(3 * sizeof(struct des_eks), GFP_ATOMIC)) == NULL) {
-+ ipsp->ips_key_e = ekp;
-+ SENDERR(ENOMEM);
-+ }
-+ ipsp->ips_key_e_size = 3 * sizeof(struct des_eks);
-+
-+ for(i = 0; i < 3; i++) {
-+#if KLIPS_DIVULGE_CYPHER_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "3des key %d/3 is 0x%08x%08x\n",
-+ i + 1,
-+ ntohl(*((__u32 *)ekp + i * 2)),
-+ ntohl(*((__u32 *)ekp + i * 2 + 1)));
-+# endif
-+#if KLIPS_FIXES_DES_PARITY
-+ /* force parity */
-+ des_set_odd_parity((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i));
-+#endif
-+ error = des_set_key((des_cblock *)(ekp + EMT_ESPDES_KEY_SZ * i),
-+ ((struct des_eks *)(ipsp->ips_key_e))[i].ks);
-+ if (error == -1)
-+ printk("klips_debug:pfkey_ipsec_sa_init: "
-+ "parity error in des key %d/3\n",
-+ i + 1);
-+ else if (error == -2)
-+ printk("klips_debug:pfkey_ipsec_sa_init: "
-+ "illegal weak des key %d/3\n", i + 1);
-+ if (error) {
-+ memset(ekp, 0, eks);
-+ kfree(ekp);
-+ SENDERR(EINVAL);
-+ }
-+ }
-+
-+ /* paranoid */
-+ memset(ekp, 0, eks);
-+ kfree(ekp);
-+ break;
-+# endif /* CONFIG_IPSEC_ENC_3DES */
-+ case ESP_NONE:
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "encalg=%d support not available in the kernel",
-+ ipsp->ips_encalg);
-+ SENDERR(EINVAL);
-+ }
-+
-+#ifdef CONFIG_IPSEC_ALG
-+ if ((ixt_a=ipsp->ips_alg_auth)) {
-+ if ((error=ipsec_alg_auth_key_create(ipsp)) < 0)
-+ SENDERR(-error);
-+ } else
-+#endif /* CONFIG_IPSEC_ALG */
-+
-+ switch(ipsp->ips_authalg) {
-+# ifdef CONFIG_IPSEC_AUTH_HMAC_MD5
-+ case AH_MD5: {
-+ MD5_CTX *ictx;
-+ MD5_CTX *octx;
-+
-+ if(ipsp->ips_key_bits_a != (AHMD596_KLEN * 8)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
-+ ipsp->ips_key_bits_a,
-+ AHMD596_KLEN * 8);
-+ SENDERR(EINVAL);
-+ }
-+
-+# if KLIPS_DIVULGE_HMAC_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "hmac md5-96 key is 0x%08x %08x %08x %08x\n",
-+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+0)),
-+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+1)),
-+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+2)),
-+ ntohl(*(((__u32 *)(ipsp->ips_key_a))+3)));
-+# endif /* KLIPS_DIVULGE_HMAC_KEY */
-+ ipsp->ips_auth_bits = AHMD596_ALEN * 8;
-+
-+ /* save the pointer to the key material */
-+ akp = ipsp->ips_key_a;
-+ aks = ipsp->ips_key_a_size;
-+
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "allocating %lu bytes for md5_ctx.\n",
-+ (unsigned long) sizeof(struct md5_ctx));
-+ if((ipsp->ips_key_a = (caddr_t)
-+ kmalloc(sizeof(struct md5_ctx), GFP_ATOMIC)) == NULL) {
-+ ipsp->ips_key_a = akp;
-+ SENDERR(ENOMEM);
-+ }
-+ ipsp->ips_key_a_size = sizeof(struct md5_ctx);
-+
-+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
-+ kb[i] = akp[i] ^ HMAC_IPAD;
-+ }
-+ for (; i < AHMD596_BLKLEN; i++) {
-+ kb[i] = HMAC_IPAD;
-+ }
-+
-+ ictx = &(((struct md5_ctx*)(ipsp->ips_key_a))->ictx);
-+ MD5Init(ictx);
-+ MD5Update(ictx, kb, AHMD596_BLKLEN);
-+
-+ for (i = 0; i < AHMD596_BLKLEN; i++) {
-+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
-+ }
-+
-+ octx = &(((struct md5_ctx*)(ipsp->ips_key_a))->octx);
-+ MD5Init(octx);
-+ MD5Update(octx, kb, AHMD596_BLKLEN);
-+
-+# if KLIPS_DIVULGE_HMAC_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "MD5 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
-+ ((__u32*)ictx)[0],
-+ ((__u32*)ictx)[1],
-+ ((__u32*)ictx)[2],
-+ ((__u32*)ictx)[3],
-+ ((__u32*)octx)[0],
-+ ((__u32*)octx)[1],
-+ ((__u32*)octx)[2],
-+ ((__u32*)octx)[3] );
-+# endif /* KLIPS_DIVULGE_HMAC_KEY */
-+ /* paranoid */
-+ memset(akp, 0, aks);
-+ kfree(akp);
-+ break;
-+ }
-+# endif /* CONFIG_IPSEC_AUTH_HMAC_MD5 */
-+# ifdef CONFIG_IPSEC_AUTH_HMAC_SHA1
-+ case AH_SHA: {
-+ SHA1_CTX *ictx;
-+ SHA1_CTX *octx;
-+
-+ if(ipsp->ips_key_bits_a != (AHSHA196_KLEN * 8)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "incorrect authorisation key size: %d bits -- must be %d bits\n"/*octets (bytes)\n"*/,
-+ ipsp->ips_key_bits_a,
-+ AHSHA196_KLEN * 8);
-+ SENDERR(EINVAL);
-+ }
-+
-+# if KLIPS_DIVULGE_HMAC_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "hmac sha1-96 key is 0x%08x %08x %08x %08x\n",
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+0)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+1)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+2)),
-+ ntohl(*(((__u32 *)ipsp->ips_key_a)+3)));
-+# endif /* KLIPS_DIVULGE_HMAC_KEY */
-+ ipsp->ips_auth_bits = AHSHA196_ALEN * 8;
-+
-+ /* save the pointer to the key material */
-+ akp = ipsp->ips_key_a;
-+ aks = ipsp->ips_key_a_size;
-+
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "allocating %lu bytes for sha1_ctx.\n",
-+ (unsigned long) sizeof(struct sha1_ctx));
-+ if((ipsp->ips_key_a = (caddr_t)
-+ kmalloc(sizeof(struct sha1_ctx), GFP_ATOMIC)) == NULL) {
-+ ipsp->ips_key_a = akp;
-+ SENDERR(ENOMEM);
-+ }
-+ ipsp->ips_key_a_size = sizeof(struct sha1_ctx);
-+
-+ for (i = 0; i < DIVUP(ipsp->ips_key_bits_a, 8); i++) {
-+ kb[i] = akp[i] ^ HMAC_IPAD;
-+ }
-+ for (; i < AHMD596_BLKLEN; i++) {
-+ kb[i] = HMAC_IPAD;
-+ }
-+
-+ ictx = &(((struct sha1_ctx*)(ipsp->ips_key_a))->ictx);
-+ SHA1Init(ictx);
-+ SHA1Update(ictx, kb, AHSHA196_BLKLEN);
-+
-+ for (i = 0; i < AHSHA196_BLKLEN; i++) {
-+ kb[i] ^= (HMAC_IPAD ^ HMAC_OPAD);
-+ }
-+
-+ octx = &((struct sha1_ctx*)(ipsp->ips_key_a))->octx;
-+ SHA1Init(octx);
-+ SHA1Update(octx, kb, AHSHA196_BLKLEN);
-+
-+# if KLIPS_DIVULGE_HMAC_KEY
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "SHA1 ictx=0x%08x %08x %08x %08x octx=0x%08x %08x %08x %08x\n",
-+ ((__u32*)ictx)[0],
-+ ((__u32*)ictx)[1],
-+ ((__u32*)ictx)[2],
-+ ((__u32*)ictx)[3],
-+ ((__u32*)octx)[0],
-+ ((__u32*)octx)[1],
-+ ((__u32*)octx)[2],
-+ ((__u32*)octx)[3] );
-+# endif /* KLIPS_DIVULGE_HMAC_KEY */
-+ memset(akp, 0, aks);
-+ kfree(akp);
-+ break;
-+ }
-+# endif /* CONFIG_IPSEC_AUTH_HMAC_SHA1 */
-+ case AH_NONE:
-+ break;
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "authalg=%d support not available in the kernel.\n",
-+ ipsp->ips_authalg);
-+ SENDERR(EINVAL);
-+ }
-+ }
-+ break;
-+#endif /* !CONFIG_IPSEC_ESP */
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ case IPPROTO_COMP:
-+ ipsp->ips_comp_adapt_tries = 0;
-+ ipsp->ips_comp_adapt_skip = 0;
-+ ipsp->ips_comp_ratio_cbytes = 0;
-+ ipsp->ips_comp_ratio_dbytes = 0;
-+ break;
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+ default:
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_ipsec_sa_init: "
-+ "proto=%d unknown.\n",
-+ ipsp->ips_said.proto);
-+ SENDERR(EINVAL);
-+ }
-+
-+ errlab:
-+ return(error);
-+}
-+
-+
-+int
-+pfkey_safe_build(int error, struct sadb_ext *extensions[SADB_MAX+1])
-+{
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build: "
-+ "error=%d\n",
-+ error);
-+ if (!error) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
-+ "success.\n");
-+ return 1;
-+ } else {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_safe_build:"
-+ "caught error %d\n",
-+ error);
-+ pfkey_extensions_free(extensions);
-+ return 0;
-+ }
-+}
-+
-+
-+DEBUG_NO_STATIC int
-+pfkey_getspi_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ ipsec_spi_t minspi = htonl(256), maxspi = htonl(-1L);
-+ int found_avail = 0;
-+ struct ipsec_sa *ipsq;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_getspi_parse: .\n");
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ if(extr == NULL || extr->ips == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_getspi_parse: "
-+ "error, extr or extr->ipsec_sa pointer NULL\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(extensions[SADB_EXT_SPIRANGE]) {
-+ minspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_min;
-+ maxspi = ((struct sadb_spirange *)extensions[SADB_EXT_SPIRANGE])->sadb_spirange_max;
-+ }
-+
-+ if(maxspi == minspi) {
-+ extr->ips->ips_said.spi = maxspi;
-+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
-+ if(ipsq != NULL) {
-+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
-+ ipsec_sa_put(ipsq);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_getspi_parse: "
-+ "EMT_GETSPI found an old ipsec_sa for SA: %s, delete it first.\n",
-+ sa_len ? sa : " (error)");
-+ SENDERR(EEXIST);
-+ } else {
-+ found_avail = 1;
-+ }
-+ } else {
-+ int i = 0;
-+ __u32 rand_val;
-+ __u32 spi_diff;
-+ while( ( i < (spi_diff = (ntohl(maxspi) - ntohl(minspi)))) && !found_avail ) {
-+ prng_bytes(&ipsec_prng, (char *) &(rand_val),
-+ ( (spi_diff < (2^8)) ? 1 :
-+ ( (spi_diff < (2^16)) ? 2 :
-+ ( (spi_diff < (2^24)) ? 3 :
-+ 4 ) ) ) );
-+ extr->ips->ips_said.spi = htonl(ntohl(minspi) +
-+ (rand_val %
-+ (spi_diff + 1)));
-+ i++;
-+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
-+ if(ipsq == NULL) {
-+ found_avail = 1;
-+ } else {
-+ ipsec_sa_put(ipsq);
-+ }
-+ }
-+ }
-+
-+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
-+
-+ if (!found_avail) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_getspi_parse: "
-+ "found an old ipsec_sa for SA: %s, delete it first.\n",
-+ sa_len ? sa : " (error)");
-+ SENDERR(EEXIST);
-+ }
-+
-+ if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) {
-+ extr->ips->ips_flags |= EMT_INBOUND;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_getspi_parse: "
-+ "existing ipsec_sa not found (this is good) for SA: %s, %s-bound, allocating.\n",
-+ sa_len ? sa : " (error)",
-+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
-+
-+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
-+ extr->ips->ips_rcvif = NULL;
-+ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies/HZ;
-+
-+ extr->ips->ips_state = SADB_SASTATE_LARVAL;
-+
-+ if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
-+ extr->ips->ips_life.ipl_allocations.ipl_count += 1;
-+ }
-+
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_GETSPI,
-+ satype,
-+ 0,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ 0,
-+ SADB_SASTATE_LARVAL,
-+ 0,
-+ 0,
-+ 0,
-+ extr->ips->ips_ref),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_s),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_d),
-+ extensions_reply) )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
-+ "failed to build the getspi reply message extensions\n");
-+ goto errlab;
-+ }
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
-+ "failed to build the getspi reply message\n");
-+ SENDERR(-error);
-+ }
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
-+ "sending up getspi reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
-+ "sending up getspi reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ if((error = ipsec_sa_add(extr->ips))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_getspi_parse: "
-+ "failed to add the larval SA=%s with error=%d.\n",
-+ sa_len ? sa : " (error)",
-+ error);
-+ SENDERR(-error);
-+ }
-+ extr->ips = NULL;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_getspi_parse: "
-+ "successful for SA: %s\n",
-+ sa_len ? sa : " (error)");
-+
-+ errlab:
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_update_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct ipsec_sa* ipsq;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ struct ipsec_sa *nat_t_ips_saved = NULL;
-+#endif
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: .\n");
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: "
-+ "error, sa_state=%d must be MATURE=%d\n",
-+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
-+ SADB_SASTATE_MATURE);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(extr == NULL || extr->ips == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: "
-+ "error, extr or extr->ips pointer NULL\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
-+
-+ spin_lock_bh(&tdb_lock);
-+
-+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
-+ if (ipsq == NULL) {
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: "
-+ "reserved ipsec_sa for SA: %s not found. Call SADB_GETSPI first or call SADB_ADD instead.\n",
-+ sa_len ? sa : " (error)");
-+ SENDERR(ENOENT);
-+ }
-+
-+ if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) {
-+ extr->ips->ips_flags |= EMT_INBOUND;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: "
-+ "existing ipsec_sa found (this is good) for SA: %s, %s-bound, updating.\n",
-+ sa_len ? sa : " (error)",
-+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if (extr->ips->ips_natt_sport || extr->ips->ips_natt_dport) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: only updating NAT-T ports "
-+ "(%u:%u -> %u:%u)\n",
-+ ipsq->ips_natt_sport, ipsq->ips_natt_dport,
-+ extr->ips->ips_natt_sport, extr->ips->ips_natt_dport);
-+
-+ if (extr->ips->ips_natt_sport) {
-+ ipsq->ips_natt_sport = extr->ips->ips_natt_sport;
-+ if (ipsq->ips_addr_s->sa_family == AF_INET) {
-+ ((struct sockaddr_in *)(ipsq->ips_addr_s))->sin_port = htons(extr->ips->ips_natt_sport);
-+ }
-+ }
-+
-+ if (extr->ips->ips_natt_dport) {
-+ ipsq->ips_natt_dport = extr->ips->ips_natt_dport;
-+ if (ipsq->ips_addr_d->sa_family == AF_INET) {
-+ ((struct sockaddr_in *)(ipsq->ips_addr_d))->sin_port = htons(extr->ips->ips_natt_dport);
-+ }
-+ }
-+
-+ nat_t_ips_saved = extr->ips;
-+ extr->ips = ipsq;
-+ }
-+ else {
-+#endif
-+
-+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
-+ extr->ips->ips_rcvif = NULL;
-+ if ((error = pfkey_ipsec_sa_init(extr->ips, extensions))) {
-+ ipsec_sa_put(ipsq);
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: "
-+ "not successful for SA: %s, deleting.\n",
-+ sa_len ? sa : " (error)");
-+ SENDERR(-error);
-+ }
-+
-+ extr->ips->ips_life.ipl_addtime.ipl_count = ipsq->ips_life.ipl_addtime.ipl_count;
-+ ipsec_sa_put(ipsq);
-+ if((error = ipsec_sa_delchain(ipsq))) {
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: "
-+ "error=%d, trouble deleting intermediate ipsec_sa for SA=%s.\n",
-+ error,
-+ sa_len ? sa : " (error)");
-+ SENDERR(-error);
-+ }
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ }
-+#endif
-+
-+ spin_unlock_bh(&tdb_lock);
-+
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_UPDATE,
-+ satype,
-+ 0,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ extr->ips->ips_replaywin,
-+ extr->ips->ips_state,
-+ extr->ips->ips_authalg,
-+ extr->ips->ips_encalg,
-+ extr->ips->ips_flags,
-+ extr->ips->ips_ref),
-+ extensions_reply)
-+ /* The 3 lifetime extentions should only be sent if non-zero. */
-+ && (extensions[SADB_EXT_LIFETIME_HARD]
-+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
-+ SADB_EXT_LIFETIME_HARD,
-+ extr->ips->ips_life.ipl_allocations.ipl_hard,
-+ extr->ips->ips_life.ipl_bytes.ipl_hard,
-+ extr->ips->ips_life.ipl_addtime.ipl_hard,
-+ extr->ips->ips_life.ipl_usetime.ipl_hard,
-+ extr->ips->ips_life.ipl_packets.ipl_hard),
-+ extensions_reply) : 1)
-+ && (extensions[SADB_EXT_LIFETIME_SOFT]
-+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
-+ SADB_EXT_LIFETIME_SOFT,
-+ extr->ips->ips_life.ipl_allocations.ipl_count,
-+ extr->ips->ips_life.ipl_bytes.ipl_count,
-+ extr->ips->ips_life.ipl_addtime.ipl_count,
-+ extr->ips->ips_life.ipl_usetime.ipl_count,
-+ extr->ips->ips_life.ipl_packets.ipl_count),
-+ extensions_reply) : 1)
-+ && (extr->ips->ips_life.ipl_allocations.ipl_count
-+ || extr->ips->ips_life.ipl_bytes.ipl_count
-+ || extr->ips->ips_life.ipl_addtime.ipl_count
-+ || extr->ips->ips_life.ipl_usetime.ipl_count
-+ || extr->ips->ips_life.ipl_packets.ipl_count
-+
-+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
-+ SADB_EXT_LIFETIME_CURRENT,
-+ extr->ips->ips_life.ipl_allocations.ipl_count,
-+ extr->ips->ips_life.ipl_bytes.ipl_count,
-+ extr->ips->ips_life.ipl_addtime.ipl_count,
-+ extr->ips->ips_life.ipl_usetime.ipl_count,
-+ extr->ips->ips_life.ipl_packets.ipl_count),
-+ extensions_reply) : 1)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_s),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_d),
-+ extensions_reply)
-+ && (extr->ips->ips_ident_s.data
-+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
-+ SADB_EXT_IDENTITY_SRC,
-+ extr->ips->ips_ident_s.type,
-+ extr->ips->ips_ident_s.id,
-+ extr->ips->ips_ident_s.len,
-+ extr->ips->ips_ident_s.data),
-+ extensions_reply) : 1)
-+ && (extr->ips->ips_ident_d.data
-+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
-+ SADB_EXT_IDENTITY_DST,
-+ extr->ips->ips_ident_d.type,
-+ extr->ips->ips_ident_d.id,
-+ extr->ips->ips_ident_d.len,
-+ extr->ips->ips_ident_d.data),
-+ extensions_reply) : 1)
-+#if 0
-+ /* FIXME: This won't work yet because I have not finished
-+ it. */
-+ && (extr->ips->ips_sens_
-+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
-+ extr->ips->ips_sens_dpd,
-+ extr->ips->ips_sens_sens_level,
-+ extr->ips->ips_sens_sens_len,
-+ extr->ips->ips_sens_sens_bitmap,
-+ extr->ips->ips_sens_integ_level,
-+ extr->ips->ips_sens_integ_len,
-+ extr->ips->ips_sens_integ_bitmap),
-+ extensions_reply) : 1)
-+#endif
-+ )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
-+ "failed to build the update reply message extensions\n");
-+ SENDERR(-error);
-+ }
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
-+ "failed to build the update reply message\n");
-+ SENDERR(-error);
-+ }
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
-+ "sending up update reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
-+ "sending up update reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ if (nat_t_ips_saved) {
-+ /**
-+ * As we _really_ update existing SA, we keep tdbq and need to delete
-+ * parsed ips (nat_t_ips_saved, was extr->ips).
-+ *
-+ * goto errlab with extr->ips = nat_t_ips_saved will free it.
-+ */
-+
-+ extr->ips = nat_t_ips_saved;
-+
-+ error = 0;
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse (NAT-T ports): "
-+ "successful for SA: %s\n",
-+ sa_len ? sa : " (error)");
-+
-+ goto errlab;
-+ }
-+#endif
-+
-+ if((error = ipsec_sa_add(extr->ips))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_update_parse: "
-+ "failed to update the mature SA=%s with error=%d.\n",
-+ sa_len ? sa : " (error)",
-+ error);
-+ SENDERR(-error);
-+ }
-+ extr->ips = NULL;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_update_parse: "
-+ "successful for SA: %s\n",
-+ sa_len ? sa : " (error)");
-+
-+ errlab:
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_add_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct ipsec_sa* ipsq;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_add_parse: .\n");
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ if(((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state != SADB_SASTATE_MATURE) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_add_parse: "
-+ "error, sa_state=%d must be MATURE=%d\n",
-+ ((struct sadb_sa*)extensions[SADB_EXT_SA])->sadb_sa_state,
-+ SADB_SASTATE_MATURE);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_add_parse: "
-+ "extr or extr->ips pointer NULL\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
-+
-+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
-+ if(ipsq != NULL) {
-+ ipsec_sa_put(ipsq);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_add_parse: "
-+ "found an old ipsec_sa for SA%s, delete it first.\n",
-+ sa_len ? sa : " (error)");
-+ SENDERR(EEXIST);
-+ }
-+
-+ if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) {
-+ extr->ips->ips_flags |= EMT_INBOUND;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_add_parse: "
-+ "existing ipsec_sa not found (this is good) for SA%s, %s-bound, allocating.\n",
-+ sa_len ? sa : " (error)",
-+ extr->ips->ips_flags & EMT_INBOUND ? "in" : "out");
-+
-+ /* XXX extr->ips->ips_rcvif = &(enc_softc[em->em_if].enc_if);*/
-+ extr->ips->ips_rcvif = NULL;
-+
-+ if ((error = pfkey_ipsec_sa_init(extr->ips, extensions))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_add_parse: "
-+ "not successful for SA: %s, deleting.\n",
-+ sa_len ? sa : " (error)");
-+ SENDERR(-error);
-+ }
-+
-+ extr->ips->ips_life.ipl_addtime.ipl_count = jiffies / HZ;
-+ if(!extr->ips->ips_life.ipl_allocations.ipl_count) {
-+ extr->ips->ips_life.ipl_allocations.ipl_count += 1;
-+ }
-+
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_ADD,
-+ satype,
-+ 0,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ extr->ips->ips_replaywin,
-+ extr->ips->ips_state,
-+ extr->ips->ips_authalg,
-+ extr->ips->ips_encalg,
-+ extr->ips->ips_flags,
-+ extr->ips->ips_ref),
-+ extensions_reply)
-+ /* The 3 lifetime extentions should only be sent if non-zero. */
-+ && (extensions[SADB_EXT_LIFETIME_HARD]
-+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
-+ SADB_EXT_LIFETIME_HARD,
-+ extr->ips->ips_life.ipl_allocations.ipl_hard,
-+ extr->ips->ips_life.ipl_bytes.ipl_hard,
-+ extr->ips->ips_life.ipl_addtime.ipl_hard,
-+ extr->ips->ips_life.ipl_usetime.ipl_hard,
-+ extr->ips->ips_life.ipl_packets.ipl_hard),
-+ extensions_reply) : 1)
-+ && (extensions[SADB_EXT_LIFETIME_SOFT]
-+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
-+ SADB_EXT_LIFETIME_SOFT,
-+ extr->ips->ips_life.ipl_allocations.ipl_soft,
-+ extr->ips->ips_life.ipl_bytes.ipl_soft,
-+ extr->ips->ips_life.ipl_addtime.ipl_soft,
-+ extr->ips->ips_life.ipl_usetime.ipl_soft,
-+ extr->ips->ips_life.ipl_packets.ipl_soft),
-+ extensions_reply) : 1)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_s),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_d),
-+ extensions_reply)
-+ && (extr->ips->ips_ident_s.data
-+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
-+ SADB_EXT_IDENTITY_SRC,
-+ extr->ips->ips_ident_s.type,
-+ extr->ips->ips_ident_s.id,
-+ extr->ips->ips_ident_s.len,
-+ extr->ips->ips_ident_s.data),
-+ extensions_reply) : 1)
-+ && (extr->ips->ips_ident_d.data
-+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
-+ SADB_EXT_IDENTITY_DST,
-+ extr->ips->ips_ident_d.type,
-+ extr->ips->ips_ident_d.id,
-+ extr->ips->ips_ident_d.len,
-+ extr->ips->ips_ident_d.data),
-+ extensions_reply) : 1)
-+#if 0
-+ /* FIXME: This won't work yet because I have not finished
-+ it. */
-+ && (extr->ips->ips_sens_
-+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
-+ extr->ips->ips_sens_dpd,
-+ extr->ips->ips_sens_sens_level,
-+ extr->ips->ips_sens_sens_len,
-+ extr->ips->ips_sens_sens_bitmap,
-+ extr->ips->ips_sens_integ_level,
-+ extr->ips->ips_sens_integ_len,
-+ extr->ips->ips_sens_integ_bitmap),
-+ extensions_reply) : 1)
-+#endif
-+ )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
-+ "failed to build the add reply message extensions\n");
-+ SENDERR(-error);
-+ }
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
-+ "failed to build the add reply message\n");
-+ SENDERR(-error);
-+ }
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
-+ "sending up add reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
-+ "sending up add reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ if((error = ipsec_sa_add(extr->ips))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_add_parse: "
-+ "failed to add the mature SA=%s with error=%d.\n",
-+ sa_len ? sa : " (error)",
-+ error);
-+ SENDERR(-error);
-+ }
-+ extr->ips = NULL;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_add_parse: "
-+ "successful for SA: %s\n",
-+ sa_len ? sa : " (error)");
-+
-+ errlab:
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_delete_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ struct ipsec_sa *ipsp;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+ int error = 0;
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_delete_parse: .\n");
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_delete_parse: "
-+ "extr or extr->ips pointer NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
-+
-+ spin_lock_bh(&tdb_lock);
-+
-+ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
-+ if (ipsp == NULL) {
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_delete_parse: "
-+ "ipsec_sa not found for SA:%s, could not delete.\n",
-+ sa_len ? sa : " (error)");
-+ SENDERR(ESRCH);
-+ }
-+
-+ ipsec_sa_put(ipsp);
-+ if((error = ipsec_sa_delchain(ipsp))) {
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_delete_parse: "
-+ "error=%d returned trying to delete ipsec_sa for SA:%s.\n",
-+ error,
-+ sa_len ? sa : " (error)");
-+ SENDERR(-error);
-+ }
-+ spin_unlock_bh(&tdb_lock);
-+
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_DELETE,
-+ satype,
-+ 0,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ 0,
-+ 0,
-+ 0,
-+ 0,
-+ 0,
-+ extr->ips->ips_ref),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_s),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_d),
-+ extensions_reply)
-+ )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
-+ "failed to build the delete reply message extensions\n");
-+ SENDERR(-error);
-+ }
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
-+ "failed to build the delete reply message\n");
-+ SENDERR(-error);
-+ }
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
-+ "sending up delete reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_delete_parse: "
-+ "sending up delete reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ errlab:
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_get_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct ipsec_sa *ipsp;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_get_parse: .\n");
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ if(!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_get_parse: "
-+ "extr or extr->ips pointer NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
-+
-+ spin_lock_bh(&tdb_lock);
-+
-+ ipsp = ipsec_sa_getbyid(&(extr->ips->ips_said));
-+ if (ipsp == NULL) {
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
-+ "ipsec_sa not found for SA=%s, could not get.\n",
-+ sa_len ? sa : " (error)");
-+ SENDERR(ESRCH);
-+ }
-+
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_GET,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype,
-+ 0,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ extr->ips->ips_replaywin,
-+ extr->ips->ips_state,
-+ extr->ips->ips_authalg,
-+ extr->ips->ips_encalg,
-+ extr->ips->ips_flags,
-+ extr->ips->ips_ref),
-+ extensions_reply)
-+ /* The 3 lifetime extentions should only be sent if non-zero. */
-+ && (ipsp->ips_life.ipl_allocations.ipl_count
-+ || ipsp->ips_life.ipl_bytes.ipl_count
-+ || ipsp->ips_life.ipl_addtime.ipl_count
-+ || ipsp->ips_life.ipl_usetime.ipl_count
-+ || ipsp->ips_life.ipl_packets.ipl_count
-+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_CURRENT],
-+ SADB_EXT_LIFETIME_CURRENT,
-+ ipsp->ips_life.ipl_allocations.ipl_count,
-+ ipsp->ips_life.ipl_bytes.ipl_count,
-+ ipsp->ips_life.ipl_addtime.ipl_count,
-+ ipsp->ips_life.ipl_usetime.ipl_count,
-+ ipsp->ips_life.ipl_packets.ipl_count),
-+ extensions_reply) : 1)
-+ && (ipsp->ips_life.ipl_allocations.ipl_hard
-+ || ipsp->ips_life.ipl_bytes.ipl_hard
-+ || ipsp->ips_life.ipl_addtime.ipl_hard
-+ || ipsp->ips_life.ipl_usetime.ipl_hard
-+ || ipsp->ips_life.ipl_packets.ipl_hard
-+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_HARD],
-+ SADB_EXT_LIFETIME_HARD,
-+ ipsp->ips_life.ipl_allocations.ipl_hard,
-+ ipsp->ips_life.ipl_bytes.ipl_hard,
-+ ipsp->ips_life.ipl_addtime.ipl_hard,
-+ ipsp->ips_life.ipl_usetime.ipl_hard,
-+ ipsp->ips_life.ipl_packets.ipl_hard),
-+ extensions_reply) : 1)
-+ && (ipsp->ips_life.ipl_allocations.ipl_soft
-+ || ipsp->ips_life.ipl_bytes.ipl_soft
-+ || ipsp->ips_life.ipl_addtime.ipl_soft
-+ || ipsp->ips_life.ipl_usetime.ipl_soft
-+ || ipsp->ips_life.ipl_packets.ipl_soft
-+ ? pfkey_safe_build(error = pfkey_lifetime_build(&extensions_reply[SADB_EXT_LIFETIME_SOFT],
-+ SADB_EXT_LIFETIME_SOFT,
-+ ipsp->ips_life.ipl_allocations.ipl_soft,
-+ ipsp->ips_life.ipl_bytes.ipl_soft,
-+ ipsp->ips_life.ipl_addtime.ipl_soft,
-+ ipsp->ips_life.ipl_usetime.ipl_soft,
-+ ipsp->ips_life.ipl_packets.ipl_soft),
-+ extensions_reply) : 1)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_s),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_d),
-+ extensions_reply)
-+ && (extr->ips->ips_addr_p
-+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_PROXY],
-+ SADB_EXT_ADDRESS_PROXY,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_p),
-+ extensions_reply) : 1)
-+#if 0
-+ /* FIXME: This won't work yet because the keys are not
-+ stored directly in the ipsec_sa. They are stored as
-+ contexts. */
-+ && (extr->ips->ips_key_a_size
-+ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_AUTH],
-+ SADB_EXT_KEY_AUTH,
-+ extr->ips->ips_key_a_size * 8,
-+ extr->ips->ips_key_a),
-+ extensions_reply) : 1)
-+ /* FIXME: This won't work yet because the keys are not
-+ stored directly in the ipsec_sa. They are stored as
-+ key schedules. */
-+ && (extr->ips->ips_key_e_size
-+ ? pfkey_safe_build(error = pfkey_key_build(&extensions_reply[SADB_EXT_KEY_ENCRYPT],
-+ SADB_EXT_KEY_ENCRYPT,
-+ extr->ips->ips_key_e_size * 8,
-+ extr->ips->ips_key_e),
-+ extensions_reply) : 1)
-+#endif
-+ && (extr->ips->ips_ident_s.data
-+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_SRC],
-+ SADB_EXT_IDENTITY_SRC,
-+ extr->ips->ips_ident_s.type,
-+ extr->ips->ips_ident_s.id,
-+ extr->ips->ips_ident_s.len,
-+ extr->ips->ips_ident_s.data),
-+ extensions_reply) : 1)
-+ && (extr->ips->ips_ident_d.data
-+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions_reply[SADB_EXT_IDENTITY_DST],
-+ SADB_EXT_IDENTITY_DST,
-+ extr->ips->ips_ident_d.type,
-+ extr->ips->ips_ident_d.id,
-+ extr->ips->ips_ident_d.len,
-+ extr->ips->ips_ident_d.data),
-+ extensions_reply) : 1)
-+#if 0
-+ /* FIXME: This won't work yet because I have not finished
-+ it. */
-+ && (extr->ips->ips_sens_
-+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions_reply[SADB_EXT_SENSITIVITY],
-+ extr->ips->ips_sens_dpd,
-+ extr->ips->ips_sens_sens_level,
-+ extr->ips->ips_sens_sens_len,
-+ extr->ips->ips_sens_sens_bitmap,
-+ extr->ips->ips_sens_integ_level,
-+ extr->ips->ips_sens_integ_len,
-+ extr->ips->ips_sens_integ_bitmap),
-+ extensions_reply) : 1)
-+#endif
-+ )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
-+ "failed to build the get reply message extensions\n");
-+ ipsec_sa_put(ipsp);
-+ spin_unlock_bh(&tdb_lock);
-+ SENDERR(-error);
-+ }
-+
-+ ipsec_sa_put(ipsp);
-+ spin_unlock_bh(&tdb_lock);
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
-+ "failed to build the get reply message\n");
-+ SENDERR(-error);
-+ }
-+
-+ if((error = pfkey_upmsg(sk->socket, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
-+ "failed to send the get reply message\n");
-+ SENDERR(-error);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_get_parse: "
-+ "succeeded in sending get reply message.\n");
-+
-+ errlab:
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_acquire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_acquire_parse: .\n");
-+
-+ /* XXX I don't know if we want an upper bound, since userspace may
-+ want to register itself for an satype > SADB_SATYPE_MAX. */
-+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_acquire_parse: "
-+ "SATYPE=%d invalid.\n",
-+ satype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(pfkey_registered_sockets[satype])) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
-+ "no sockets registered for SAtype=%d(%s).\n",
-+ satype,
-+ satype2name(satype));
-+ SENDERR(EPROTONOSUPPORT);
-+ }
-+
-+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
-+ "sending up acquire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire_parse: "
-+ "sending up acquire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_register_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_parse: .\n");
-+
-+ /* XXX I don't know if we want an upper bound, since userspace may
-+ want to register itself for an satype > SADB_SATYPE_MAX. */
-+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_parse: "
-+ "SATYPE=%d invalid.\n",
-+ satype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!pfkey_list_insert_socket(sk->socket,
-+ &(pfkey_registered_sockets[satype]))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_parse: "
-+ "SATYPE=%02d(%s) successfully registered by KMd (pid=%d).\n",
-+ satype,
-+ satype2name(satype),
-+ key_pid(sk));
-+ };
-+
-+ /* send up register msg with supported SATYPE algos */
-+
-+ error=pfkey_register_reply(satype, (struct sadb_msg*)extensions[SADB_EXT_RESERVED]);
-+ errlab:
-+ return error;
-+}
-+
-+int
-+pfkey_register_reply(int satype, struct sadb_msg *sadb_msg)
-+{
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ struct supported_list *pfkey_supported_listp;
-+ unsigned int alg_num_a = 0, alg_num_e = 0;
-+ struct sadb_alg *alg_a = NULL, *alg_e = NULL, *alg_ap = NULL, *alg_ep = NULL;
-+ int error = 0;
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
-+ "SAtype=%d unspecified or unknown.\n",
-+ satype);
-+ SENDERR(EINVAL);
-+ }
-+ if(!(pfkey_registered_sockets[satype])) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
-+ "no sockets registered for SAtype=%d(%s).\n",
-+ satype,
-+ satype2name(satype));
-+ SENDERR(EPROTONOSUPPORT);
-+ }
-+ /* send up register msg with supported SATYPE algos */
-+ pfkey_supported_listp = pfkey_supported_list[satype];
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "pfkey_supported_list[%d]=0p%p\n",
-+ satype,
-+ pfkey_supported_list[satype]);
-+ while(pfkey_supported_listp) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "checking supported=0p%p\n",
-+ pfkey_supported_listp);
-+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "adding auth alg.\n");
-+ alg_num_a++;
-+ }
-+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "adding encrypt alg.\n");
-+ alg_num_e++;
-+ }
-+ pfkey_supported_listp = pfkey_supported_listp->next;
-+ }
-+
-+ if(alg_num_a) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "allocating %lu bytes for auth algs.\n",
-+ (unsigned long) (alg_num_a * sizeof(struct sadb_alg)));
-+ if((alg_a = kmalloc(alg_num_a * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "auth alg memory allocation error\n");
-+ SENDERR(ENOMEM);
-+ }
-+ alg_ap = alg_a;
-+ }
-+
-+ if(alg_num_e) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "allocating %lu bytes for enc algs.\n",
-+ (unsigned long) (alg_num_e * sizeof(struct sadb_alg)));
-+ if((alg_e = kmalloc(alg_num_e * sizeof(struct sadb_alg), GFP_ATOMIC) ) == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "enc alg memory allocation error\n");
-+ SENDERR(ENOMEM);
-+ }
-+ alg_ep = alg_e;
-+ }
-+
-+ pfkey_supported_listp = pfkey_supported_list[satype];
-+ while(pfkey_supported_listp) {
-+ if(alg_num_a) {
-+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_AUTH) {
-+ alg_ap->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id;
-+ alg_ap->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen;
-+ alg_ap->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits;
-+ alg_ap->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits;
-+ alg_ap->sadb_alg_reserved = 0;
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_register_reply: "
-+ "adding auth=0p%p\n",
-+ alg_ap);
-+ alg_ap++;
-+ }
-+ }
-+ if(alg_num_e) {
-+ if(pfkey_supported_listp->supportedp->supported_alg_exttype == SADB_EXT_SUPPORTED_ENCRYPT) {
-+ alg_ep->sadb_alg_id = pfkey_supported_listp->supportedp->supported_alg_id;
-+ alg_ep->sadb_alg_ivlen = pfkey_supported_listp->supportedp->supported_alg_ivlen;
-+ alg_ep->sadb_alg_minbits = pfkey_supported_listp->supportedp->supported_alg_minbits;
-+ alg_ep->sadb_alg_maxbits = pfkey_supported_listp->supportedp->supported_alg_maxbits;
-+ alg_ep->sadb_alg_reserved = 0;
-+ KLIPS_PRINT(debug_pfkey && sysctl_ipsec_debug_verbose,
-+ "klips_debug:pfkey_register_reply: "
-+ "adding encrypt=0p%p\n",
-+ alg_ep);
-+ alg_ep++;
-+ }
-+ }
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_register_reply: "
-+ "found satype=%d(%s) exttype=%d id=%d ivlen=%d minbits=%d maxbits=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_supported_listp->supportedp->supported_alg_exttype,
-+ pfkey_supported_listp->supportedp->supported_alg_id,
-+ pfkey_supported_listp->supportedp->supported_alg_ivlen,
-+ pfkey_supported_listp->supportedp->supported_alg_minbits,
-+ pfkey_supported_listp->supportedp->supported_alg_maxbits);
-+ pfkey_supported_listp = pfkey_supported_listp->next;
-+ }
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_REGISTER,
-+ satype,
-+ 0,
-+ sadb_msg? sadb_msg->sadb_msg_seq : ++pfkey_msg_seq,
-+ sadb_msg? sadb_msg->sadb_msg_pid: current->pid),
-+ extensions_reply) &&
-+ (alg_num_a ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_AUTH],
-+ SADB_EXT_SUPPORTED_AUTH,
-+ alg_num_a,
-+ alg_a),
-+ extensions_reply) : 1) &&
-+ (alg_num_e ? pfkey_safe_build(error = pfkey_supported_build(&extensions_reply[SADB_EXT_SUPPORTED_ENCRYPT],
-+ SADB_EXT_SUPPORTED_ENCRYPT,
-+ alg_num_e,
-+ alg_e),
-+ extensions_reply) : 1))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
-+ "failed to build the register message extensions_reply\n");
-+ SENDERR(-error);
-+ }
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
-+ "failed to build the register message\n");
-+ SENDERR(-error);
-+ }
-+ /* this should go to all registered sockets for that satype only */
-+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
-+ "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_register_reply: "
-+ "sending up register message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ errlab:
-+ if(alg_a) {
-+ kfree(alg_a);
-+ }
-+ if(alg_e) {
-+ kfree(alg_e);
-+ }
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_expire_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct socket_list *pfkey_socketsp;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_expire_parse: .\n");
-+
-+ if(pfkey_open_sockets) {
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
-+ "sending up expire reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire_parse: "
-+ "sending up expire reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+ }
-+
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_flush_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+ uint8_t proto = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_flush_parse: "
-+ "flushing type %d SAs\n",
-+ satype);
-+
-+ if(satype && !(proto = satype2proto(satype))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_flush_parse: "
-+ "satype %d lookup failed.\n",
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if ((error = ipsec_sadb_cleanup(proto))) {
-+ SENDERR(-error);
-+ }
-+
-+ if(pfkey_open_sockets) {
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
-+ "sending up flush reply message for satype=%d(%s) (proto=%d) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ proto,
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_flush_parse: "
-+ "sending up flush reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+ }
-+
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_dump_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_dump_parse: .\n");
-+
-+ SENDERR(ENOSYS);
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_promisc_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_promisc_parse: .\n");
-+
-+ SENDERR(ENOSYS);
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_pchange_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_pchange_parse: .\n");
-+
-+ SENDERR(ENOSYS);
-+ errlab:
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_grpsa_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ struct ipsec_sa *ips1p, *ips2p, *ipsp;
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+ char sa1[SATOT_BUF], sa2[SATOT_BUF];
-+ size_t sa_len1, sa_len2 = 0;
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: .\n");
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ if(extr == NULL || extr->ips == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: "
-+ "extr or extr->ips is NULL, fatal.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ sa_len1 = satot(&extr->ips->ips_said, 0, sa1, sizeof(sa1));
-+ if(extr->ips2 != NULL) {
-+ sa_len2 = satot(&extr->ips2->ips_said, 0, sa2, sizeof(sa2));
-+ }
-+
-+ spin_lock_bh(&tdb_lock);
-+
-+ ips1p = ipsec_sa_getbyid(&(extr->ips->ips_said));
-+ if(ips1p == NULL) {
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: "
-+ "reserved ipsec_sa for SA1: %s not found. Call SADB_ADD/UPDATE first.\n",
-+ sa_len1 ? sa1 : " (error)");
-+ SENDERR(ENOENT);
-+ }
-+ if(extr->ips2) { /* GRPSA */
-+ ips2p = ipsec_sa_getbyid(&(extr->ips2->ips_said));
-+ if(ips2p == NULL) {
-+ ipsec_sa_put(ips1p);
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: "
-+ "reserved ipsec_sa for SA2: %s not found. Call SADB_ADD/UPDATE first.\n",
-+ sa_len2 ? sa2 : " (error)");
-+ SENDERR(ENOENT);
-+ }
-+
-+ /* Is either one already linked? */
-+ if(ips1p->ips_onext) {
-+ ipsec_sa_put(ips1p);
-+ ipsec_sa_put(ips2p);
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: "
-+ "ipsec_sa for SA: %s is already linked.\n",
-+ sa_len1 ? sa1 : " (error)");
-+ SENDERR(EEXIST);
-+ }
-+ if(ips2p->ips_inext) {
-+ ipsec_sa_put(ips1p);
-+ ipsec_sa_put(ips2p);
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: "
-+ "ipsec_sa for SA: %s is already linked.\n",
-+ sa_len2 ? sa2 : " (error)");
-+ SENDERR(EEXIST);
-+ }
-+
-+ /* Is extr->ips already linked to extr->ips2? */
-+ ipsp = ips2p;
-+ while(ipsp) {
-+ if(ipsp == ips1p) {
-+ ipsec_sa_put(ips1p);
-+ ipsec_sa_put(ips2p);
-+ spin_unlock_bh(&tdb_lock);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: "
-+ "ipsec_sa for SA: %s is already linked to %s.\n",
-+ sa_len1 ? sa1 : " (error)",
-+ sa_len2 ? sa2 : " (error)");
-+ SENDERR(EEXIST);
-+ }
-+ ipsp = ipsp->ips_onext;
-+ }
-+
-+ /* link 'em */
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: "
-+ "linking ipsec_sa SA: %s with %s.\n",
-+ sa_len1 ? sa1 : " (error)",
-+ sa_len2 ? sa2 : " (error)");
-+ ips1p->ips_onext = ips2p;
-+ ips2p->ips_inext = ips1p;
-+ } else { /* UNGRPSA */
-+ ipsec_sa_put(ips1p);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_grpsa_parse: "
-+ "unlinking ipsec_sa SA: %s.\n",
-+ sa_len1 ? sa1 : " (error)");
-+ while(ips1p->ips_onext) {
-+ ips1p = ips1p->ips_onext;
-+ }
-+ while(ips1p->ips_inext) {
-+ ipsp = ips1p;
-+ ips1p = ips1p->ips_inext;
-+ ipsec_sa_put(ips1p);
-+ ipsp->ips_inext = NULL;
-+ ipsec_sa_put(ipsp);
-+ ips1p->ips_onext = NULL;
-+ }
-+ }
-+
-+ spin_unlock_bh(&tdb_lock);
-+
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_X_GRPSA,
-+ satype,
-+ 0,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ extr->ips->ips_replaywin,
-+ extr->ips->ips_state,
-+ extr->ips->ips_authalg,
-+ extr->ips->ips_encalg,
-+ extr->ips->ips_flags,
-+ extr->ips->ips_ref),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_d),
-+ extensions_reply)
-+ && (extr->ips2
-+ ? (pfkey_safe_build(error = pfkey_x_satype_build(&extensions_reply[SADB_X_EXT_SATYPE2],
-+ ((struct sadb_x_satype*)extensions[SADB_X_EXT_SATYPE2])->sadb_x_satype_satype
-+ /* proto2satype(extr->ips2->ips_said.proto) */),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_X_EXT_SA2],
-+ SADB_X_EXT_SA2,
-+ extr->ips2->ips_said.spi,
-+ extr->ips2->ips_replaywin,
-+ extr->ips2->ips_state,
-+ extr->ips2->ips_authalg,
-+ extr->ips2->ips_encalg,
-+ extr->ips2->ips_flags,
-+ extr->ips2->ips_ref),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST2],
-+ SADB_X_EXT_ADDRESS_DST2,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips2->ips_addr_d),
-+ extensions_reply) ) : 1 )
-+ )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
-+ "failed to build the x_grpsa reply message extensions\n");
-+ SENDERR(-error);
-+ }
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
-+ "failed to build the x_grpsa reply message\n");
-+ SENDERR(-error);
-+ }
-+
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
-+ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
-+ "sending up x_grpsa reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_grpsa_parse: "
-+ "succeeded in sending x_grpsa reply message.\n");
-+
-+ errlab:
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_addflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ char buf1[64], buf2[64];
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+ ip_address srcflow, dstflow, srcmask, dstmask;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: .\n");
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ memset((caddr_t)&srcflow, 0, sizeof(srcflow));
-+ memset((caddr_t)&dstflow, 0, sizeof(dstflow));
-+ memset((caddr_t)&srcmask, 0, sizeof(srcmask));
-+ memset((caddr_t)&dstmask, 0, sizeof(dstmask));
-+
-+ if(!extr || !(extr->ips) || !(extr->eroute)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "missing extr, ipsec_sa or eroute data.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ srcflow.u.v4.sin_family = AF_INET;
-+ dstflow.u.v4.sin_family = AF_INET;
-+ srcmask.u.v4.sin_family = AF_INET;
-+ dstmask.u.v4.sin_family = AF_INET;
-+ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
-+ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
-+ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
-+ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (debug_pfkey) {
-+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
-+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
-+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "calling breakeroute and/or makeroute for %s->%s\n",
-+ buf1, buf2);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_INFLOW) {
-+/* if(ip_chk_addr((unsigned long)extr->ips->ips_said.dst.u.v4.sin_addr.s_addr) == IS_MYADDR) */
-+ struct ipsec_sa *ipsp, *ipsq;
-+ char sa[SATOT_BUF];
-+ size_t sa_len;
-+
-+ ipsq = ipsec_sa_getbyid(&(extr->ips->ips_said));
-+ if(ipsq == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "ipsec_sa not found, cannot set incoming policy.\n");
-+ SENDERR(ENOENT);
-+ }
-+
-+ ipsp = ipsq;
-+ while(ipsp && ipsp->ips_said.proto != IPPROTO_IPIP) {
-+ ipsp = ipsp->ips_inext;
-+ }
-+
-+ if(ipsp == NULL) {
-+ ipsec_sa_put(ipsq);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "SA chain does not have an IPIP SA, cannot set incoming policy.\n");
-+ SENDERR(ENOENT);
-+ }
-+
-+ sa_len = satot(&extr->ips->ips_said, 0, sa, sizeof(sa));
-+
-+ ipsp->ips_flags |= SADB_X_SAFLAGS_INFLOW;
-+ ipsp->ips_flow_s = srcflow;
-+ ipsp->ips_flow_d = dstflow;
-+ ipsp->ips_mask_s = srcmask;
-+ ipsp->ips_mask_d = dstmask;
-+
-+ ipsec_sa_put(ipsq);
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "inbound eroute, setting incoming policy information in IPIP ipsec_sa for SA: %s.\n",
-+ sa_len ? sa : " (error)");
-+ } else {
-+ struct sk_buff *first = NULL, *last = NULL;
-+
-+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_REPLACEFLOW) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "REPLACEFLOW flag set, calling breakeroute.\n");
-+ if ((error = ipsec_breakroute(&(extr->eroute->er_eaddr),
-+ &(extr->eroute->er_emask),
-+ &first, &last))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "breakeroute returned %d. first=0p%p, last=0p%p\n",
-+ error,
-+ first,
-+ last);
-+ if(first != NULL) {
-+ ipsec_kfree_skb(first);
-+ }
-+ if(last != NULL) {
-+ ipsec_kfree_skb(last);
-+ }
-+ SENDERR(-error);
-+ }
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "calling makeroute.\n");
-+
-+ if ((error = ipsec_makeroute(&(extr->eroute->er_eaddr),
-+ &(extr->eroute->er_emask),
-+ extr->ips->ips_said,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid,
-+ NULL,
-+ &(extr->ips->ips_ident_s),
-+ &(extr->ips->ips_ident_d)))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "makeroute returned %d.\n", error);
-+ SENDERR(-error);
-+ }
-+ if(first != NULL) {
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "first=0p%p HOLD packet re-injected.\n",
-+ first);
-+ DEV_QUEUE_XMIT(first, first->dev, SOPRI_NORMAL);
-+ }
-+ if(last != NULL) {
-+ KLIPS_PRINT(debug_eroute,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "last=0p%p HOLD packet re-injected.\n",
-+ last);
-+ DEV_QUEUE_XMIT(last, last->dev, SOPRI_NORMAL);
-+ }
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "makeroute call successful.\n");
-+
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_X_ADDFLOW,
-+ satype,
-+ 0,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ extr->ips->ips_replaywin,
-+ extr->ips->ips_state,
-+ extr->ips->ips_authalg,
-+ extr->ips->ips_encalg,
-+ extr->ips->ips_flags,
-+ extr->ips->ips_ref),
-+ extensions_reply)
-+ && (extensions[SADB_EXT_ADDRESS_SRC]
-+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_s),
-+ extensions_reply) : 1)
-+ && (extensions[SADB_EXT_ADDRESS_DST]
-+ ? pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ extr->ips->ips_addr_d),
-+ extensions_reply) : 1)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
-+ SADB_X_EXT_ADDRESS_SRC_FLOW,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ (struct sockaddr*)&srcflow),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
-+ SADB_X_EXT_ADDRESS_DST_FLOW,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ (struct sockaddr*)&dstflow),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
-+ SADB_X_EXT_ADDRESS_SRC_MASK,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ (struct sockaddr*)&srcmask),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
-+ SADB_X_EXT_ADDRESS_DST_MASK,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ (struct sockaddr*)&dstmask),
-+ extensions_reply)
-+ )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
-+ "failed to build the x_addflow reply message extensions\n");
-+ SENDERR(-error);
-+ }
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
-+ "failed to build the x_addflow reply message\n");
-+ SENDERR(-error);
-+ }
-+
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
-+ "sending up x_addflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_addflow_parse: "
-+ "sending up x_addflow reply message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ extr->ips->ips_said.proto,
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_addflow_parse: "
-+ "extr->ips cleaned up and freed.\n");
-+
-+ errlab:
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_delflow_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ char buf1[64], buf2[64];
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ struct sadb_ext *extensions_reply[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_reply = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ uint8_t satype = ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_satype;
-+ ip_address srcflow, dstflow, srcmask, dstmask;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_delflow_parse: .\n");
-+
-+ pfkey_extensions_init(extensions_reply);
-+
-+ memset((caddr_t)&srcflow, 0, sizeof(srcflow));
-+ memset((caddr_t)&dstflow, 0, sizeof(dstflow));
-+ memset((caddr_t)&srcmask, 0, sizeof(srcmask));
-+ memset((caddr_t)&dstmask, 0, sizeof(dstmask));
-+
-+ if(!extr || !(extr->ips)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_delflow_parse: "
-+ "extr, or extr->ips is NULL, fatal\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(extr->ips->ips_flags & SADB_X_SAFLAGS_CLEARFLOW) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_delflow_parse: "
-+ "CLEARFLOW flag set, calling cleareroutes.\n");
-+ if ((error = ipsec_cleareroutes()))
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_delflow_parse: "
-+ "cleareroutes returned %d.\n", error);
-+ SENDERR(-error);
-+ } else {
-+ struct sk_buff *first = NULL, *last = NULL;
-+
-+ if(!(extr->eroute)) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_delflow_parse: "
-+ "extr->eroute is NULL, fatal.\n");
-+ SENDERR(EINVAL);
-+ }
-+
-+ srcflow.u.v4.sin_family = AF_INET;
-+ dstflow.u.v4.sin_family = AF_INET;
-+ srcmask.u.v4.sin_family = AF_INET;
-+ dstmask.u.v4.sin_family = AF_INET;
-+ srcflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_src;
-+ dstflow.u.v4.sin_addr = extr->eroute->er_eaddr.sen_ip_dst;
-+ srcmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_src;
-+ dstmask.u.v4.sin_addr = extr->eroute->er_emask.sen_ip_dst;
-+
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if (debug_pfkey) {
-+ subnettoa(extr->eroute->er_eaddr.sen_ip_src,
-+ extr->eroute->er_emask.sen_ip_src, 0, buf1, sizeof(buf1));
-+ subnettoa(extr->eroute->er_eaddr.sen_ip_dst,
-+ extr->eroute->er_emask.sen_ip_dst, 0, buf2, sizeof(buf2));
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_delflow_parse: "
-+ "calling breakeroute for %s->%s\n",
-+ buf1, buf2);
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ error = ipsec_breakroute(&(extr->eroute->er_eaddr),
-+ &(extr->eroute->er_emask),
-+ &first, &last);
-+ if(error) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_delflow_parse: "
-+ "breakeroute returned %d. first=0p%p, last=0p%p\n",
-+ error,
-+ first,
-+ last);
-+ }
-+ if(first != NULL) {
-+ ipsec_kfree_skb(first);
-+ }
-+ if(last != NULL) {
-+ ipsec_kfree_skb(last);
-+ }
-+ if(error) {
-+ SENDERR(-error);
-+ }
-+ }
-+
-+ if(!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions_reply[0],
-+ SADB_X_DELFLOW,
-+ satype,
-+ 0,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_seq,
-+ ((struct sadb_msg*)extensions[SADB_EXT_RESERVED])->sadb_msg_pid),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions_reply[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ extr->ips->ips_replaywin,
-+ extr->ips->ips_state,
-+ extr->ips->ips_authalg,
-+ extr->ips->ips_encalg,
-+ extr->ips->ips_flags,
-+ extr->ips->ips_ref),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_FLOW],
-+ SADB_X_EXT_ADDRESS_SRC_FLOW,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ (struct sockaddr*)&srcflow),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_FLOW],
-+ SADB_X_EXT_ADDRESS_DST_FLOW,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ (struct sockaddr*)&dstflow),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_SRC_MASK],
-+ SADB_X_EXT_ADDRESS_SRC_MASK,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ (struct sockaddr*)&srcmask),
-+ extensions_reply)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions_reply[SADB_X_EXT_ADDRESS_DST_MASK],
-+ SADB_X_EXT_ADDRESS_DST_MASK,
-+ 0, /*extr->ips->ips_said.proto,*/
-+ 0,
-+ (struct sockaddr*)&dstmask),
-+ extensions_reply)
-+ )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
-+ "failed to build the x_delflow reply message extensions\n");
-+ SENDERR(-error);
-+ }
-+
-+ if((error = pfkey_msg_build(&pfkey_reply, extensions_reply, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
-+ "failed to build the x_delflow reply message\n");
-+ SENDERR(-error);
-+ }
-+
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_reply))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
-+ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_x_delflow_parse: "
-+ "sending up x_delflow reply message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_delflow_parse: "
-+ "extr->ips cleaned up and freed.\n");
-+
-+ errlab:
-+ if (pfkey_reply) {
-+ pfkey_msg_free(&pfkey_reply);
-+ }
-+ pfkey_extensions_free(extensions_reply);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_msg_debug_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ int error = 0;
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_x_msg_debug_parse: .\n");
-+
-+/* errlab:*/
-+ return error;
-+}
-+
-+/* pfkey_expire expects the ipsec_sa table to be locked before being called. */
-+int
-+pfkey_expire(struct ipsec_sa *ipsp, int hard)
-+{
-+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_msg = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ int error = 0;
-+ uint8_t satype;
-+
-+ pfkey_extensions_init(extensions);
-+
-+ if(!(satype = proto2satype(ipsp->ips_said.proto))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_expire: "
-+ "satype lookup for protocol %d lookup failed.\n",
-+ ipsp->ips_said.proto);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!pfkey_open_sockets) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
-+ "no sockets listening.\n");
-+ SENDERR(EPROTONOSUPPORT);
-+ }
-+
-+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
-+ SADB_EXPIRE,
-+ satype,
-+ 0,
-+ ++pfkey_msg_seq,
-+ 0),
-+ extensions)
-+ && pfkey_safe_build(error = pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ ipsp->ips_said.spi,
-+ ipsp->ips_replaywin,
-+ ipsp->ips_state,
-+ ipsp->ips_authalg,
-+ ipsp->ips_encalg,
-+ ipsp->ips_flags,
-+ ipsp->ips_ref),
-+ extensions)
-+ && pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_CURRENT],
-+ SADB_EXT_LIFETIME_CURRENT,
-+ ipsp->ips_life.ipl_allocations.ipl_count,
-+ ipsp->ips_life.ipl_bytes.ipl_count,
-+ ipsp->ips_life.ipl_addtime.ipl_count,
-+ ipsp->ips_life.ipl_usetime.ipl_count,
-+ ipsp->ips_life.ipl_packets.ipl_count),
-+ extensions)
-+ && (hard ?
-+ pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_HARD],
-+ SADB_EXT_LIFETIME_HARD,
-+ ipsp->ips_life.ipl_allocations.ipl_hard,
-+ ipsp->ips_life.ipl_bytes.ipl_hard,
-+ ipsp->ips_life.ipl_addtime.ipl_hard,
-+ ipsp->ips_life.ipl_usetime.ipl_hard,
-+ ipsp->ips_life.ipl_packets.ipl_hard),
-+ extensions)
-+ : pfkey_safe_build(error = pfkey_lifetime_build(&extensions[SADB_EXT_LIFETIME_SOFT],
-+ SADB_EXT_LIFETIME_SOFT,
-+ ipsp->ips_life.ipl_allocations.ipl_soft,
-+ ipsp->ips_life.ipl_bytes.ipl_soft,
-+ ipsp->ips_life.ipl_addtime.ipl_soft,
-+ ipsp->ips_life.ipl_usetime.ipl_soft,
-+ ipsp->ips_life.ipl_packets.ipl_soft),
-+ extensions))
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ 0, /* ipsp->ips_said.proto, */
-+ 0,
-+ ipsp->ips_addr_s),
-+ extensions)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ 0, /* ipsp->ips_said.proto, */
-+ 0,
-+ ipsp->ips_addr_d),
-+ extensions))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
-+ "failed to build the expire message extensions\n");
-+ spin_unlock(&tdb_lock);
-+ goto errlab;
-+ }
-+
-+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
-+ "failed to build the expire message\n");
-+ SENDERR(-error);
-+ }
-+
-+ for(pfkey_socketsp = pfkey_open_sockets;
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
-+ "sending up expire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_expire: "
-+ "sending up expire message for satype=%d(%s) (proto=%d) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ ipsp->ips_said.proto,
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ errlab:
-+ if (pfkey_msg) {
-+ pfkey_msg_free(&pfkey_msg);
-+ }
-+ pfkey_extensions_free(extensions);
-+ return error;
-+}
-+
-+int
-+pfkey_acquire(struct ipsec_sa *ipsp)
-+{
-+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_msg = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ int error = 0;
-+ struct sadb_comb comb[] = {
-+ /* auth; encrypt; flags; */
-+ /* auth_minbits; auth_maxbits; encrypt_minbits; encrypt_maxbits; */
-+ /* reserved; soft_allocations; hard_allocations; soft_bytes; hard_bytes; */
-+ /* soft_addtime; hard_addtime; soft_usetime; hard_usetime; */
-+ /* soft_packets; hard_packets; */
-+ { SADB_AALG_MD5HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
-+ 128, 128, 168, 168,
-+ 0, 0, 0, 0, 0,
-+ 57600, 86400, 57600, 86400,
-+ 0, 0 },
-+ { SADB_AALG_SHA1HMAC, SADB_EALG_3DESCBC, SADB_SAFLAGS_PFS,
-+ 160, 160, 168, 168,
-+ 0, 0, 0, 0, 0,
-+ 57600, 86400, 57600, 86400,
-+ 0, 0 }
-+ };
-+
-+ /* XXX This should not be hard-coded. It should be taken from the spdb */
-+ uint8_t satype = SADB_SATYPE_ESP;
-+
-+ pfkey_extensions_init(extensions);
-+
-+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
-+ "SAtype=%d unspecified or unknown.\n",
-+ satype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(pfkey_registered_sockets[satype])) {
-+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
-+ "no sockets registered for SAtype=%d(%s).\n",
-+ satype,
-+ satype2name(satype));
-+ SENDERR(EPROTONOSUPPORT);
-+ }
-+
-+ if (!(pfkey_safe_build(error = pfkey_msg_hdr_build(&extensions[0],
-+ SADB_ACQUIRE,
-+ satype,
-+ 0,
-+ ++pfkey_msg_seq,
-+ 0),
-+ extensions)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ ipsp->ips_transport_protocol,
-+ 0,
-+ ipsp->ips_addr_s),
-+ extensions)
-+ && pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ ipsp->ips_transport_protocol,
-+ 0,
-+ ipsp->ips_addr_d),
-+ extensions)
-+#if 0
-+ && (ipsp->ips_addr_p
-+ ? pfkey_safe_build(error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_PROXY],
-+ SADB_EXT_ADDRESS_PROXY,
-+ ipsp->ips_transport_protocol,
-+ 0,
-+ ipsp->ips_addr_p),
-+ extensions) : 1)
-+#endif
-+ && (ipsp->ips_ident_s.type != SADB_IDENTTYPE_RESERVED
-+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_SRC],
-+ SADB_EXT_IDENTITY_SRC,
-+ ipsp->ips_ident_s.type,
-+ ipsp->ips_ident_s.id,
-+ ipsp->ips_ident_s.len,
-+ ipsp->ips_ident_s.data),
-+ extensions) : 1)
-+
-+ && (ipsp->ips_ident_d.type != SADB_IDENTTYPE_RESERVED
-+ ? pfkey_safe_build(error = pfkey_ident_build(&extensions[SADB_EXT_IDENTITY_DST],
-+ SADB_EXT_IDENTITY_DST,
-+ ipsp->ips_ident_d.type,
-+ ipsp->ips_ident_d.id,
-+ ipsp->ips_ident_d.len,
-+ ipsp->ips_ident_d.data),
-+ extensions) : 1)
-+#if 0
-+ /* FIXME: This won't work yet because I have not finished
-+ it. */
-+ && (ipsp->ips_sens_
-+ ? pfkey_safe_build(error = pfkey_sens_build(&extensions[SADB_EXT_SENSITIVITY],
-+ ipsp->ips_sens_dpd,
-+ ipsp->ips_sens_sens_level,
-+ ipsp->ips_sens_sens_len,
-+ ipsp->ips_sens_sens_bitmap,
-+ ipsp->ips_sens_integ_level,
-+ ipsp->ips_sens_integ_len,
-+ ipsp->ips_sens_integ_bitmap),
-+ extensions) : 1)
-+#endif
-+ && pfkey_safe_build(error = pfkey_prop_build(&extensions[SADB_EXT_PROPOSAL],
-+ 64, /* replay */
-+ sizeof(comb)/sizeof(struct sadb_comb),
-+ &(comb[0])),
-+ extensions)
-+ )) {
-+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
-+ "failed to build the acquire message extensions\n");
-+ SENDERR(-error);
-+ }
-+
-+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
-+ "failed to build the acquire message\n");
-+ SENDERR(-error);
-+ }
-+
-+#if KLIPS_PFKEY_ACQUIRE_LOSSAGE > 0
-+ if(sysctl_ipsec_regress_pfkey_lossage) {
-+ return(0);
-+ }
-+#endif
-+
-+ /* this should go to all registered sockets for that satype only */
-+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
-+ KLIPS_PRINT(1|debug_pfkey, "klips_debug:pfkey_acquire: "
-+ "sending up acquire message for satype=%d(%s) to socket=0p%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_acquire: "
-+ "sending up acquire message for satype=%d(%s) to socket=0p%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ errlab:
-+ if (pfkey_msg) {
-+ pfkey_msg_free(&pfkey_msg);
-+ }
-+ pfkey_extensions_free(extensions);
-+ return error;
-+}
-+
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+int
-+pfkey_nat_t_new_mapping(struct ipsec_sa *ipsp, struct sockaddr *ipaddr,
-+ __u16 sport)
-+{
-+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
-+ struct sadb_msg *pfkey_msg = NULL;
-+ struct socket_list *pfkey_socketsp;
-+ int error = 0;
-+ uint8_t satype = (ipsp->ips_said.proto==IPPROTO_ESP) ? SADB_SATYPE_ESP : 0;
-+
-+ /* Construct SADB_X_NAT_T_NEW_MAPPING message */
-+
-+ pfkey_extensions_init(extensions);
-+
-+ if((satype == 0) || (satype > SADB_SATYPE_MAX)) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
-+ "SAtype=%d unspecified or unknown.\n",
-+ satype);
-+ SENDERR(EINVAL);
-+ }
-+
-+ if(!(pfkey_registered_sockets[satype])) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
-+ "no sockets registered for SAtype=%d(%s).\n",
-+ satype,
-+ satype2name(satype));
-+ SENDERR(EPROTONOSUPPORT);
-+ }
-+
-+ if (!(pfkey_safe_build
-+ (error = pfkey_msg_hdr_build(&extensions[0], SADB_X_NAT_T_NEW_MAPPING,
-+ satype, 0, ++pfkey_msg_seq, 0), extensions)
-+ /* SA */
-+ && pfkey_safe_build
-+ (error = pfkey_sa_build(&extensions[SADB_EXT_SA],
-+ SADB_EXT_SA, ipsp->ips_said.spi, 0, 0, 0, 0, 0), extensions)
-+ /* ADDRESS_SRC = old addr */
-+ && pfkey_safe_build
-+ (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC, ipsp->ips_said.proto, 0, ipsp->ips_addr_s),
-+ extensions)
-+ /* NAT_T_SPORT = old port */
-+ && pfkey_safe_build
-+ (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_SPORT],
-+ SADB_X_EXT_NAT_T_SPORT, ipsp->ips_natt_sport), extensions)
-+ /* ADDRESS_DST = new addr */
-+ && pfkey_safe_build
-+ (error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST, ipsp->ips_said.proto, 0, ipaddr), extensions)
-+ /* NAT_T_DPORT = new port */
-+ && pfkey_safe_build
-+ (error = pfkey_x_nat_t_port_build(&extensions[SADB_X_EXT_NAT_T_DPORT],
-+ SADB_X_EXT_NAT_T_DPORT, sport), extensions)
-+ )) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
-+ "failed to build the nat_t_new_mapping message extensions\n");
-+ SENDERR(-error);
-+ }
-+
-+ if ((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_OUT))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
-+ "failed to build the nat_t_new_mapping message\n");
-+ SENDERR(-error);
-+ }
-+
-+ /* this should go to all registered sockets for that satype only */
-+ for(pfkey_socketsp = pfkey_registered_sockets[satype];
-+ pfkey_socketsp;
-+ pfkey_socketsp = pfkey_socketsp->next) {
-+ if((error = pfkey_upmsg(pfkey_socketsp->socketp, pfkey_msg))) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
-+ "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p failed with error=%d.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp,
-+ error);
-+ SENDERR(-error);
-+ }
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_nat_t_new_mapping: "
-+ "sending up nat_t_new_mapping message for satype=%d(%s) to socket=%p succeeded.\n",
-+ satype,
-+ satype2name(satype),
-+ pfkey_socketsp->socketp);
-+ }
-+
-+ errlab:
-+ if (pfkey_msg) {
-+ pfkey_msg_free(&pfkey_msg);
-+ }
-+ pfkey_extensions_free(extensions);
-+ return error;
-+}
-+
-+DEBUG_NO_STATIC int
-+pfkey_x_nat_t_new_mapping_parse(struct sock *sk, struct sadb_ext **extensions, struct pfkey_extracted_data* extr)
-+{
-+ /* SADB_X_NAT_T_NEW_MAPPING not used in kernel */
-+ return -EINVAL;
-+}
-+#endif
-+
-+DEBUG_NO_STATIC int (*ext_processors[SADB_EXT_MAX+1])(struct sadb_ext *pfkey_ext, struct pfkey_extracted_data* extr) =
-+{
-+ NULL, /* pfkey_msg_process, */
-+ pfkey_sa_process,
-+ pfkey_lifetime_process,
-+ pfkey_lifetime_process,
-+ pfkey_lifetime_process,
-+ pfkey_address_process,
-+ pfkey_address_process,
-+ pfkey_address_process,
-+ pfkey_key_process,
-+ pfkey_key_process,
-+ pfkey_ident_process,
-+ pfkey_ident_process,
-+ pfkey_sens_process,
-+ pfkey_prop_process,
-+ pfkey_supported_process,
-+ pfkey_supported_process,
-+ pfkey_spirange_process,
-+ pfkey_x_kmprivate_process,
-+ pfkey_x_satype_process,
-+ pfkey_sa_process,
-+ pfkey_address_process,
-+ pfkey_address_process,
-+ pfkey_address_process,
-+ pfkey_address_process,
-+ pfkey_address_process,
-+ pfkey_x_debug_process,
-+ pfkey_x_protocol_process
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ ,
-+ pfkey_x_nat_t_type_process,
-+ pfkey_x_nat_t_port_process,
-+ pfkey_x_nat_t_port_process,
-+ pfkey_address_process
-+#endif
-+};
-+
-+
-+DEBUG_NO_STATIC int (*msg_parsers[SADB_MAX +1])(struct sock *sk, struct sadb_ext *extensions[], struct pfkey_extracted_data* extr)
-+ =
-+{
-+ NULL, /* RESERVED */
-+ pfkey_getspi_parse,
-+ pfkey_update_parse,
-+ pfkey_add_parse,
-+ pfkey_delete_parse,
-+ pfkey_get_parse,
-+ pfkey_acquire_parse,
-+ pfkey_register_parse,
-+ pfkey_expire_parse,
-+ pfkey_flush_parse,
-+ pfkey_dump_parse,
-+ pfkey_x_promisc_parse,
-+ pfkey_x_pchange_parse,
-+ pfkey_x_grpsa_parse,
-+ pfkey_x_addflow_parse,
-+ pfkey_x_delflow_parse,
-+ pfkey_x_msg_debug_parse
-+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
-+ , pfkey_x_nat_t_new_mapping_parse
-+#endif
-+};
-+
-+int
-+pfkey_build_reply(struct sadb_msg *pfkey_msg, struct pfkey_extracted_data *extr,
-+ struct sadb_msg **pfkey_reply)
-+{
-+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
-+ int error = 0;
-+ int msg_type = pfkey_msg->sadb_msg_type;
-+ int seq = pfkey_msg->sadb_msg_seq;
-+
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
-+ "building reply with type: %d\n",
-+ msg_type);
-+ pfkey_extensions_init(extensions);
-+ if (!extr || !extr->ips) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
-+ "bad ipsec_sa passed\n");
-+ return EINVAL;
-+ }
-+ error = pfkey_safe_build(pfkey_msg_hdr_build(&extensions[0],
-+ msg_type,
-+ proto2satype(extr->ips->ips_said.proto),
-+ 0,
-+ seq,
-+ pfkey_msg->sadb_msg_pid),
-+ extensions) &&
-+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
-+ 1 << SADB_EXT_SA)
-+ || pfkey_safe_build(pfkey_sa_ref_build(&extensions[SADB_EXT_SA],
-+ SADB_EXT_SA,
-+ extr->ips->ips_said.spi,
-+ extr->ips->ips_replaywin,
-+ extr->ips->ips_state,
-+ extr->ips->ips_authalg,
-+ extr->ips->ips_encalg,
-+ extr->ips->ips_flags,
-+ extr->ips->ips_ref),
-+ extensions)) &&
-+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
-+ 1 << SADB_EXT_LIFETIME_CURRENT)
-+ || pfkey_safe_build(pfkey_lifetime_build(&extensions
-+ [SADB_EXT_LIFETIME_CURRENT],
-+ SADB_EXT_LIFETIME_CURRENT,
-+ extr->ips->ips_life.ipl_allocations.ipl_count,
-+ extr->ips->ips_life.ipl_bytes.ipl_count,
-+ extr->ips->ips_life.ipl_addtime.ipl_count,
-+ extr->ips->ips_life.ipl_usetime.ipl_count,
-+ extr->ips->ips_life.ipl_packets.ipl_count),
-+ extensions)) &&
-+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
-+ 1 << SADB_EXT_ADDRESS_SRC)
-+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC],
-+ SADB_EXT_ADDRESS_SRC,
-+ extr->ips->ips_said.proto,
-+ 0,
-+ extr->ips->ips_addr_s),
-+ extensions)) &&
-+ (!(extensions_bitmaps[EXT_BITS_OUT][EXT_BITS_REQ][msg_type] &
-+ 1 << SADB_EXT_ADDRESS_DST)
-+ || pfkey_safe_build(pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST],
-+ SADB_EXT_ADDRESS_DST,
-+ extr->ips->ips_said.proto,
-+ 0,
-+ extr->ips->ips_addr_d),
-+ extensions));
-+
-+ if (error == 0) {
-+ KLIPS_PRINT(debug_pfkey, "klips_debug:pfkey_build_reply: "
-+ "building extensions failed\n");
-+ return EINVAL;
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_build_reply: "
-+ "built extensions, proceed to build the message\n");
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_build_reply: "
-+ "extensions[1]=0p%p\n",
-+ extensions[1]);
-+ error = pfkey_msg_build(pfkey_reply, extensions, EXT_BITS_OUT);
-+ pfkey_extensions_free(extensions);
-+
-+ return error;
-+}
-+
-+int
-+pfkey_msg_interp(struct sock *sk, struct sadb_msg *pfkey_msg,
-+ struct sadb_msg **pfkey_reply)
-+{
-+ int error = 0;
-+ int i;
-+ struct sadb_ext *extensions[SADB_EXT_MAX+1];
-+ struct pfkey_extracted_data extr = {NULL, NULL, NULL};
-+
-+ pfkey_extensions_init(extensions);
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "parsing message ver=%d, type=%d, errno=%d, satype=%d(%s), len=%d, res=%d, seq=%d, pid=%d.\n",
-+ pfkey_msg->sadb_msg_version,
-+ pfkey_msg->sadb_msg_type,
-+ pfkey_msg->sadb_msg_errno,
-+ pfkey_msg->sadb_msg_satype,
-+ satype2name(pfkey_msg->sadb_msg_satype),
-+ pfkey_msg->sadb_msg_len,
-+ pfkey_msg->sadb_msg_reserved,
-+ pfkey_msg->sadb_msg_seq,
-+ pfkey_msg->sadb_msg_pid);
-+
-+ extr.ips = ipsec_sa_alloc(&error); /* pass in error var by pointer */
-+ if(extr.ips == NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "memory allocation error.\n");
-+ SENDERR(-error);
-+ }
-+
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "allocated extr->ips=0p%p.\n",
-+ extr.ips);
-+
-+ if(pfkey_msg->sadb_msg_satype > SADB_SATYPE_MAX) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "satype %d > max %d\n",
-+ pfkey_msg->sadb_msg_satype,
-+ SADB_SATYPE_MAX);
-+ SENDERR(EINVAL);
-+ }
-+
-+ switch(pfkey_msg->sadb_msg_type) {
-+ case SADB_GETSPI:
-+ case SADB_UPDATE:
-+ case SADB_ADD:
-+ case SADB_DELETE:
-+ case SADB_X_GRPSA:
-+ case SADB_X_ADDFLOW:
-+
-+ if(!(extr.ips->ips_said.proto = satype2proto(pfkey_msg->sadb_msg_satype))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "satype %d lookup failed.\n",
-+ pfkey_msg->sadb_msg_satype);
-+ SENDERR(EINVAL);
-+ } else {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "satype %d lookups to proto=%d.\n",
-+ pfkey_msg->sadb_msg_satype,
-+ extr.ips->ips_said.proto);
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+
-+ /* The NULL below causes the default extension parsers to be used */
-+ /* Parse the extensions */
-+ if((error = pfkey_msg_parse(pfkey_msg, NULL, extensions, EXT_BITS_IN)))
-+ {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "message parsing failed with error %d.\n",
-+ error);
-+ SENDERR(-error);
-+ }
-+
-+ /* Process the extensions */
-+ for(i=1; i <= SADB_EXT_MAX;i++) {
-+ if(extensions[i] != NULL) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "processing ext %d 0p%p with processor 0p%p.\n",
-+ i, extensions[i], ext_processors[i]);
-+ if((error = ext_processors[i](extensions[i], &extr))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "extension processing for type %d failed with error %d.\n",
-+ i,
-+ error);
-+ SENDERR(-error);
-+ }
-+
-+ }
-+
-+ }
-+
-+ /* Parse the message types */
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "parsing message type %d(%s) with msg_parser 0p%p.\n",
-+ pfkey_msg->sadb_msg_type,
-+ pfkey_v2_sadb_type_string(pfkey_msg->sadb_msg_type),
-+ msg_parsers[pfkey_msg->sadb_msg_type]);
-+ if((error = msg_parsers[pfkey_msg->sadb_msg_type](sk, extensions, &extr))) {
-+ KLIPS_PRINT(debug_pfkey,
-+ "klips_debug:pfkey_msg_interp: "
-+ "message parsing failed with error %d.\n",
-+ error);
-+ SENDERR(-error);
-+ }
-+
-+#if 0
-+ error = pfkey_build_reply(pfkey_msg, &extr, pfkey_reply);
-+ if (error) {
-+ *pfkey_reply = NULL;
-+ }
-+#endif
-+ errlab:
-+ if(extr.ips != NULL) {
-+ ipsec_sa_wipe(extr.ips);
-+ }
-+ if(extr.ips2 != NULL) {
-+ ipsec_sa_wipe(extr.ips2);
-+ }
-+ if (extr.eroute != NULL) {
-+ kfree(extr.eroute);
-+ }
-+ return(error);
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.123 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.122.2.2 2004/04/05 04:30:46 mcr
-+ * patches for alg-branch to compile/work with 2.x openswan
-+ *
-+ * Revision 1.122.2.1 2003/12/22 15:25:52 jjo
-+ * . Merged algo-0.8.1-rc11-test1 into alg-branch
-+ *
-+ * Revision 1.122 2003/12/10 01:14:27 mcr
-+ * NAT-traversal patches to KLIPS.
-+ *
-+ * Revision 1.121 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.120.4.2 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.120.4.1 2003/09/21 13:59:56 mcr
-+ * pre-liminary X.509 patch - does not yet pass tests.
-+ *
-+ * Revision 1.120 2003/04/03 17:38:09 rgb
-+ * Centralised ipsec_kfree_skb and ipsec_dev_{get,put}.
-+ *
-+ * Revision 1.119 2003/02/06 01:52:37 rgb
-+ * Removed no longer relevant comment
-+ *
-+ * Revision 1.118 2003/01/30 02:32:44 rgb
-+ *
-+ * Transmit error code through to caller from callee for better diagnosis of problems.
-+ *
-+ * Revision 1.117 2003/01/16 18:48:13 rgb
-+ *
-+ * Fixed sign bug in error return from an sa allocation call in
-+ * pfkey_msg_interp.
-+ *
-+ * Revision 1.116 2002/10/17 16:38:01 rgb
-+ * Change pfkey_alloc_eroute() to never static since its consumers
-+ * have been moved outside the file.
-+ *
-+ * Revision 1.115 2002/10/12 23:11:53 dhr
-+ *
-+ * [KenB + DHR] more 64-bit cleanup
-+ *
-+ * Revision 1.114 2002/10/05 05:02:58 dhr
-+ *
-+ * C labels go on statements
-+ *
-+ * Revision 1.113 2002/09/30 19:11:22 rgb
-+ * Turn on debugging for upgoing acquire messages to test for reliability.
-+ *
-+ * Revision 1.112 2002/09/20 15:41:16 rgb
-+ * Switch from pfkey_alloc_ipsec_sa() to ipsec_sa_alloc().
-+ * Added sadb_x_sa_ref to struct sadb_sa.
-+ * Added ref parameter to pfkey_sa_build().
-+ *
-+ * Revision 1.111 2002/09/20 05:02:08 rgb
-+ * Added memory allocation debugging.
-+ * Convert to switch to divulge hmac keys for debugging.
-+ * Added text labels to elucidate numeric values presented.
-+ *
-+ * Revision 1.110 2002/08/03 18:03:05 mcr
-+ * loop that checks for SPI's to have been already linked
-+ * fails to actually step to next pointer, but continuously
-+ * resets to head of list. Wrong pointer used.
-+ * test east-icmp-02 revealed this.
-+ *
-+ * Revision 1.109 2002/07/26 08:48:31 rgb
-+ * Added SA ref table code.
-+ *
-+ * Revision 1.108 2002/05/27 18:55:03 rgb
-+ * Remove final vistiges of tdb references via IPSEC_KLIPS1_COMPAT.
-+ *
-+ * Revision 1.107 2002/05/23 07:16:08 rgb
-+ * Added ipsec_sa_put() for releasing an ipsec_sa refcount.
-+ * Pointer clean-up.
-+ * Added refcount code.
-+ *
-+ * Revision 1.106 2002/05/14 02:34:13 rgb
-+ * Converted reference from ipsec_sa_put to ipsec_sa_add to avoid confusion
-+ * with "put" usage in the kernel.
-+ * Change all references to tdb, TDB or Tunnel Descriptor Block to ips,
-+ * ipsec_sa or ipsec_sa.
-+ * Moved all the extension parsing functions to pfkey_v2_ext_process.c.
-+ *
-+ * Revision 1.105 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.104 2002/04/24 07:36:34 mcr
-+ * Moved from ./klips/net/ipsec/pfkey_v2_parser.c,v
-+ *
-+ * Revision 1.103 2002/04/20 00:12:25 rgb
-+ * Added esp IV CBC attack fix, disabled.
-+ *
-+ * Revision 1.102 2002/03/08 01:15:17 mcr
-+ * put some internal structure only debug messages behind
-+ * && sysctl_ipsec_debug_verbose.
-+ *
-+ * Revision 1.101 2002/01/29 17:17:57 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.100 2002/01/29 04:00:54 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.99 2002/01/29 02:13:19 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.98 2002/01/12 02:57:57 mcr
-+ * first regression test causes acquire messages to be lost
-+ * 100% of the time. This is to help testing of pluto.
-+ *
-+ * Revision 1.97 2001/11/26 09:23:52 rgb
-+ * Merge MCR's ipsec_sa, eroute, proc and struct lifetime changes.
-+ *
-+ * Revision 1.93.2.4 2001/10/23 04:20:27 mcr
-+ * parity was forced on wrong structure! prototypes help here.
-+ *
-+ * Revision 1.93.2.3 2001/10/22 21:14:59 mcr
-+ * include des.h, removed phony prototypes and fixed calling
-+ * conventions to match real prototypes.
-+ *
-+ * Revision 1.93.2.2 2001/10/15 05:39:03 mcr
-+ * %08lx is not the right format for u32. Use %08x. 64-bit safe? ha.
-+ *
-+ * Revision 1.93.2.1 2001/09/25 02:30:14 mcr
-+ * struct tdb -> struct ipsec_sa.
-+ * use new lifetime structure. common format routines for debug.
-+ *
-+ * Revision 1.96 2001/11/06 20:47:54 rgb
-+ * Fixed user context call to ipsec_dev_start_xmit() bug. Call
-+ * dev_queue_xmit() instead.
-+ *
-+ * Revision 1.95 2001/11/06 19:47:46 rgb
-+ * Added packet parameter to lifetime and comb structures.
-+ *
-+ * Revision 1.94 2001/10/18 04:45:23 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/freeswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.93 2001/09/20 15:32:59 rgb
-+ * Min/max cleanup.
-+ *
-+ * Revision 1.92 2001/09/19 16:35:48 rgb
-+ * PF_KEY ident fix for getspi from NetCelo (puttdb duplication).
-+ *
-+ * Revision 1.91 2001/09/15 16:24:06 rgb
-+ * Re-inject first and last HOLD packet when an eroute REPLACE is done.
-+ *
-+ * Revision 1.90 2001/09/14 16:58:38 rgb
-+ * Added support for storing the first and last packets through a HOLD.
-+ *
-+ * Revision 1.89 2001/09/08 21:14:07 rgb
-+ * Added pfkey ident extension support for ISAKMPd. (NetCelo)
-+ * Better state coherency (error management) between pf_key and IKE daemon.
-+ * (NetCelo)
-+ *
-+ * Revision 1.88 2001/08/27 19:42:44 rgb
-+ * Fix memory leak of encrypt and auth structs in pfkey register.
-+ *
-+ * Revision 1.87 2001/07/06 19:50:46 rgb
-+ * Removed unused debugging code.
-+ * Added inbound policy checking code for IPIP SAs.
-+ *
-+ * Revision 1.86 2001/06/20 06:26:04 rgb
-+ * Changed missing SA errors from EEXIST to ENOENT and added debug output
-+ * for already linked SAs.
-+ *
-+ * Revision 1.85 2001/06/15 04:57:02 rgb
-+ * Remove single error return condition check and check for all errors in
-+ * the case of a replace eroute delete operation. This means that
-+ * applications must expect to be deleting something before replacing it
-+ * and if nothing is found, complain.
-+ *
-+ * Revision 1.84 2001/06/14 19:35:12 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.83 2001/06/12 00:03:19 rgb
-+ * Silence debug set/unset under normal conditions.
-+ *
-+ * Revision 1.82 2001/05/30 08:14:04 rgb
-+ * Removed vestiges of esp-null transforms.
-+ *
-+ * Revision 1.81 2001/05/27 06:12:12 rgb
-+ * Added structures for pid, packet count and last access time to eroute.
-+ * Added packet count to beginning of /proc/net/ipsec_eroute.
-+ *
-+ * Revision 1.80 2001/05/03 19:43:59 rgb
-+ * Check error return codes for all build function calls.
-+ * Standardise on SENDERR() macro.
-+ *
-+ * Revision 1.79 2001/04/20 21:09:16 rgb
-+ * Cleaned up fixed tdbwipes.
-+ * Free pfkey_reply and clean up extensions_reply for grpsa, addflow and
-+ * delflow (Per Cederqvist) plugging memleaks.
-+ *
-+ * Revision 1.78 2001/04/19 19:02:39 rgb
-+ * Fixed extr.tdb freeing, stealing it for getspi, update and add.
-+ * Refined a couple of spinlocks, fixed the one in update.
-+ *
-+ * Revision 1.77 2001/04/18 20:26:16 rgb
-+ * Wipe/free eroute and both tdbs from extr at end of pfkey_msg_interp()
-+ * instead of inside each message type parser. This fixes two memleaks.
-+ *
-+ * Revision 1.76 2001/04/17 23:51:18 rgb
-+ * Quiet down pfkey_x_debug_process().
-+ *
-+ * Revision 1.75 2001/03/29 01:55:05 rgb
-+ * Fixed pfkey key init memleak.
-+ * Fixed pfkey encryption key debug output.
-+ *
-+ * Revision 1.74 2001/03/27 05:29:14 rgb
-+ * Debug output cleanup/silencing.
-+ *
-+ * Revision 1.73 2001/02/28 05:03:28 rgb
-+ * Clean up and rationalise startup messages.
-+ *
-+ * Revision 1.72 2001/02/27 22:24:56 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.71 2001/02/27 06:59:30 rgb
-+ * Added satype2name() conversions most places satype is debug printed.
-+ *
-+ * Revision 1.70 2001/02/26 22:37:08 rgb
-+ * Fixed 'unknown proto' INT bug in new code.
-+ * Added satype to protocol debugging instrumentation.
-+ *
-+ * Revision 1.69 2001/02/26 19:57:51 rgb
-+ * Re-formatted debug output (split lines, consistent spacing).
-+ * Fixed as yet undetected FLUSH bug which called ipsec_tdbcleanup()
-+ * with an satype instead of proto.
-+ * Checked for satype consistency and fixed minor bugs.
-+ * Fixed undetected ungrpspi bug that tried to upmsg a second tdb.
-+ * Check for satype sanity in pfkey_expire().
-+ * Added satype sanity check to addflow.
-+ *
-+ * Revision 1.68 2001/02/12 23:14:40 rgb
-+ * Remove double spin lock in pfkey_expire().
-+ *
-+ * Revision 1.67 2001/01/31 19:23:40 rgb
-+ * Fixed double-unlock bug introduced by grpsa upmsg (found by Lars Heete).
-+ *
-+ * Revision 1.66 2001/01/29 22:20:04 rgb
-+ * Fix minor add upmsg lifetime bug.
-+ *
-+ * Revision 1.65 2001/01/24 06:12:33 rgb
-+ * Fixed address extension compile bugs just introduced.
-+ *
-+ * Revision 1.64 2001/01/24 00:31:15 rgb
-+ * Added upmsg for addflow/delflow.
-+ *
-+ * Revision 1.63 2001/01/23 22:02:55 rgb
-+ * Added upmsg to x_grpsa.
-+ * Fixed lifetimes extentions to add/update/get upmsg.
-+ *
-+ * Revision 1.62 2000/11/30 21:47:51 rgb
-+ * Fix error return bug after returning from pfkey_tdb_init().
-+ *
-+ * Revision 1.61 2000/11/17 18:10:29 rgb
-+ * Fixed bugs mostly relating to spirange, to treat all spi variables as
-+ * network byte order since this is the way PF_KEYv2 stored spis.
-+ *
-+ * Revision 1.60 2000/11/06 04:34:53 rgb
-+ * Changed non-exported functions to DEBUG_NO_STATIC.
-+ * Add Svenning's adaptive content compression.
-+ * Ditched spin_lock_irqsave in favour of spin_lock/_bh.
-+ * Fixed double unlock bug (Svenning).
-+ * Fixed pfkey_msg uninitialized bug in pfkey_{expire,acquire}().
-+ * Fixed incorrect extension type (prop) in pfkey)acquire().
-+ *
-+ * Revision 1.59 2000/10/11 15:25:12 rgb
-+ * Fixed IPCOMP disabled compile bug.
-+ *
-+ * Revision 1.58 2000/10/11 14:54:03 rgb
-+ * Fixed pfkey_acquire() satype to SADB_SATYPE_ESP and removed pfkey
-+ * protocol violations of setting pfkey_address_build() protocol parameter
-+ * to non-zero except in the case of pfkey_acquire().
-+ *
-+ * Revision 1.57 2000/10/10 20:10:18 rgb
-+ * Added support for debug_ipcomp and debug_verbose to klipsdebug.
-+ *
-+ * Revision 1.56 2000/10/06 20:24:36 rgb
-+ * Fixes to pfkey_acquire to initialize extensions[] and use correct
-+ * ipproto.
-+ *
-+ * Revision 1.55 2000/10/03 03:20:57 rgb
-+ * Added brackets to get a?b:c scope right for pfkey_register reply.
-+ *
-+ * Revision 1.54 2000/09/29 19:49:30 rgb
-+ * As-yet-unused-bits cleanup.
-+ *
-+ * Revision 1.53 2000/09/28 00:35:45 rgb
-+ * Padded SATYPE printout in pfkey_register for vertical alignment.
-+ *
-+ * Revision 1.52 2000/09/20 16:21:58 rgb
-+ * Cleaned up ident string alloc/free.
-+ *
-+ * Revision 1.51 2000/09/20 04:04:20 rgb
-+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
-+ * oopsen.
-+ *
-+ * Revision 1.50 2000/09/16 01:10:53 rgb
-+ * Fixed unused var warning with debug off.
-+ *
-+ * Revision 1.49 2000/09/15 11:37:02 rgb
-+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
-+ * IPCOMP zlib deflate code.
-+ *
-+ * Revision 1.48 2000/09/15 04:57:57 rgb
-+ * Cleaned up existing IPCOMP code before svenning addition.
-+ * Initialize pfkey_reply and extensions_reply in case of early error in
-+ * message parsing functions (thanks Kai!).
-+ *
-+ * Revision 1.47 2000/09/13 08:02:56 rgb
-+ * Added KMd registration notification.
-+ *
-+ * Revision 1.46 2000/09/12 22:35:36 rgb
-+ * Restructured to remove unused extensions from CLEARFLOW messages.
-+ *
-+ * Revision 1.45 2000/09/12 03:24:23 rgb
-+ * Converted #if0 debugs to sysctl.
-+ *
-+ * Revision 1.44 2000/09/09 06:38:39 rgb
-+ * Correct SADB message type for update, add and delete.
-+ *
-+ * Revision 1.43 2000/09/08 19:19:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ * Removed all references to CONFIG_IPSEC_PFKEYv2.
-+ * Put in sanity checks in most msg type parsers to catch invalid satypes
-+ * and empty socket lists.
-+ * Moved spin-locks in pfkey_get_parse() to simplify.
-+ * Added pfkey_acquire().
-+ * Added upwards messages to update, add, delete, acquire_parse,
-+ * expire_parse and flush.
-+ * Fix pfkey_prop_build() parameter to be only single indirection.
-+ * Changed all replies to use pfkey_reply.
-+ * Check return code on puttdb() and deltdbchain() in getspi, update,
-+ * add, delete.
-+ * Fixed up all pfkey replies to open and registered sockets.
-+ *
-+ * Revision 1.42 2000/09/01 18:50:26 rgb
-+ * Added a supported algorithms array lists, one per satype and registered
-+ * existing algorithms.
-+ * Fixed pfkey_list_{insert,remove}_{socket,support}() to allow change to
-+ * list.
-+ * Only send pfkey_expire() messages to sockets registered for that satype.
-+ * Added reply to pfkey_getspi_parse().
-+ * Added reply to pfkey_get_parse().
-+ * Fixed debug output label bug in pfkey_lifetime_process().
-+ * Cleaned up pfkey_sa_process a little.
-+ * Moved pfkey_safe_build() above message type parsers to make it available
-+ * for creating replies.
-+ * Added comments for future work in pfkey_acquire_parse().
-+ * Fleshed out guts of pfkey_register_parse().
-+ *
-+ * Revision 1.41 2000/08/24 16:58:11 rgb
-+ * Fixed key debugging variables.
-+ * Fixed error return code for a failed search.
-+ * Changed order of pfkey_get operations.
-+ *
-+ * Revision 1.40 2000/08/21 16:32:27 rgb
-+ * Re-formatted for cosmetic consistency and readability.
-+ *
-+ * Revision 1.39 2000/08/20 21:38:57 rgb
-+ * Bugfixes to as-yet-unused pfkey_update_parse() and
-+ * pfkey_register_parse(). (Momchil)
-+ * Added functions pfkey_safe_build(), pfkey_expire() and
-+ * pfkey_build_reply(). (Momchil)
-+ * Added a pfkey_reply parameter to pfkey_msg_interp(). (Momchil)
-+ *
-+ * Revision 1.38 2000/08/18 21:30:41 rgb
-+ * Purged all tdb_spi, tdb_proto and tdb_dst macros. They are unclear.
-+ *
-+ * Revision 1.37 2000/08/18 18:18:02 rgb
-+ * Cosmetic and descriptive changes made to debug test.
-+ * getspi and update fixes from Momchil.
-+ *
-+ * Revision 1.36 2000/08/15 15:41:55 rgb
-+ * Fixed the (as yet unused and untested) pfkey_getspi() routine.
-+ *
-+ * Revision 1.35 2000/08/01 14:51:52 rgb
-+ * Removed _all_ remaining traces of DES.
-+ *
-+ * Revision 1.34 2000/07/28 14:58:32 rgb
-+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
-+ *
-+ * Revision 1.33 2000/06/28 05:50:11 rgb
-+ * Actually set iv_bits.
-+ *
-+ * Revision 1.32 2000/05/30 18:36:56 rgb
-+ * Fix AH auth hash setup bug. This breaks interop with previous PF_KEY
-+ * FreeS/WAN, but fixes interop with other implementations.
-+ *
-+ * Revision 1.31 2000/03/16 14:05:48 rgb
-+ * Fixed brace scope preventing non-debug compile.
-+ * Added null parameter check for pfkey_x_debug().
-+ *
-+ * Revision 1.30 2000/01/22 23:21:13 rgb
-+ * Use new function satype2proto().
-+ *
-+ * Revision 1.29 2000/01/22 08:40:21 rgb
-+ * Invert condition to known value to avoid AF_INET6 in 2.0.36.
-+ *
-+ * Revision 1.28 2000/01/22 07:58:57 rgb
-+ * Fixed REPLACEFLOW bug, missing braces around KLIPS_PRINT *and* SENDERR.
-+ *
-+ * Revision 1.27 2000/01/22 03:48:01 rgb
-+ * Added extr pointer component debugging.
-+ *
-+ * Revision 1.26 2000/01/21 09:41:25 rgb
-+ * Changed a (void*) to (char*) cast to do proper pointer math.
-+ * Don't call tdbwipe if tdb2 is NULL.
-+ *
-+ * Revision 1.25 2000/01/21 06:21:01 rgb
-+ * Added address cases for eroute flows.
-+ * Tidied up compiler directive indentation for readability.
-+ * Added ictx,octx vars for simplification.
-+ * Added macros for HMAC padding magic numbers.
-+ * Converted from double tdb arguments to one structure (extr)
-+ * containing pointers to all temporary information structures
-+ * and checking for valid arguments to all ext processors and
-+ * msg type parsers.
-+ * Added spiungrp'ing.
-+ * Added klipsdebug switching capability.
-+ * Removed sa_process() check for zero protocol.
-+ * Added address case for DST2 for grouping.
-+ * Added/changed minor debugging instrumentation.
-+ * Fixed spigrp for single said, ungrouping case.
-+ * Added code to parse addflow and delflow messages.
-+ * Removed redundant statements duplicating tdbwipe() functionality
-+ * and causing double kfrees.
-+ * Permit addflow to have a protocol of 0.
-+ *
-+ * Revision 1.24 1999/12/09 23:23:00 rgb
-+ * Added check to pfkey_sa_process() to do eroutes.
-+ * Converted to DIVUP() macro.
-+ * Converted if() to switch() in pfkey_register_parse().
-+ * Use new pfkey_extensions_init() instead of memset().
-+ *
-+ * Revision 1.23 1999/12/01 22:18:13 rgb
-+ * Preset minspi and maxspi values in case and spirange extension is not
-+ * included and check for the presence of an spirange extension before
-+ * using it. Initialise tdb_sastate to LARVAL.
-+ * Fixed debugging output typo.
-+ * Fixed authentication context initialisation bugs (4 places).
-+ *
-+ * Revision 1.22 1999/11/27 11:53:08 rgb
-+ * Moved pfkey_msg_parse prototype to pfkey.h
-+ * Moved exts_permitted/required prototype to pfkey.h.
-+ * Moved sadb_satype2proto protocol lookup table to lib/pfkey_v2_parse.c.
-+ * Deleted SADB_X_EXT_SA2 code from pfkey_sa_process() since it will never
-+ * be called.
-+ * Moved protocol/algorithm checks to lib/pfkey_v2_parse.c
-+ * Debugging error messages added.
-+ * Enable lifetime_current checking.
-+ * Remove illegal requirement for SA extension to be present in an
-+ * originating GETSPI call.
-+ * Re-instate requirement for UPDATE or ADD message to be MATURE.
-+ * Add argument to pfkey_msg_parse() for direction.
-+ * Fixed IPIP dst address bug and purged redundant, leaky code.
-+ *
-+ * Revision 1.21 1999/11/24 05:24:20 rgb
-+ * hanged 'void*extensions' to 'struct sadb_ext*extensions'.
-+ * Fixed indention.
-+ * Ditched redundant replay check.
-+ * Fixed debug message text from 'parse' to 'process'.
-+ * Added more debug output.
-+ * Forgot to zero extensions array causing bug, fixed.
-+ *
-+ * Revision 1.20 1999/11/23 23:08:13 rgb
-+ * Move all common parsing code to lib/pfkey_v2_parse.c and rename
-+ * remaining bits to *_process. (PJO)
-+ * Add macros for dealing with alignment and rounding up more opaquely.
-+ * Use provided macro ADDRTOA_BUF instead of hardcoded value.
-+ * Sort out pfkey and freeswan headers, putting them in a library path.
-+ * Corrected a couple of bugs in as-yet-inactive code.
-+ *
-+ * Revision 1.19 1999/11/20 22:01:10 rgb
-+ * Add more descriptive error messages for non-zero reserved fields.
-+ * Add more descriptive error message for spirange parsing.
-+ * Start on supported extension parsing.
-+ * Start on register and get message parsing.
-+ *
-+ * Revision 1.18 1999/11/18 04:09:20 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ *
-+ * Revision 1.17 1999/11/17 15:53:41 rgb
-+ * Changed all occurrences of #include "../../../lib/freeswan.h"
-+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
-+ * klips/net/ipsec/Makefile.
-+ *
-+ * Revision 1.16 1999/10/26 16:57:43 rgb
-+ * Add shorter macros for compiler directives to visually clean-up.
-+ * Give ipv6 code meaningful compiler directive.
-+ * Add comments to other #if 0 debug code.
-+ * Remove unused *_bh_atomic() calls.
-+ * Fix mis-placed spinlock.
-+ *
-+ * Revision 1.15 1999/10/16 18:27:10 rgb
-+ * Clean-up unused cruft.
-+ * Fix-up lifetime_allocations_c and lifetime_addtime_c initialisations.
-+ *
-+ * Revision 1.14 1999/10/08 18:37:34 rgb
-+ * Fix end-of-line spacing to sate whining PHMs.
-+ *
-+ * Revision 1.13 1999/10/03 18:49:12 rgb
-+ * Spinlock fixes for 2.0.xx and 2.3.xx.
-+ *
-+ * Revision 1.12 1999/10/01 15:44:54 rgb
-+ * Move spinlock header include to 2.1> scope.
-+ *
-+ * Revision 1.11 1999/10/01 00:05:45 rgb
-+ * Added tdb structure locking.
-+ * Use 'jiffies' instead of do_get_timeofday().
-+ * Fix lifetime assignments.
-+ *
-+ * Revision 1.10 1999/09/21 15:24:45 rgb
-+ * Rework spirange code to save entropy and prevent endless loops.
-+ *
-+ * Revision 1.9 1999/09/16 12:10:21 rgb
-+ * Minor fixes to random spi selection for correctness and entropy conservation.
-+ *
-+ * Revision 1.8 1999/05/25 22:54:46 rgb
-+ * Fix comparison that should be an assignment in an if.
-+ *
-+ * Revision 1.7 1999/05/09 03:25:37 rgb
-+ * Fix bug introduced by 2.2 quick-and-dirty patch.
-+ *
-+ * Revision 1.6 1999/05/08 21:32:30 rgb
-+ * Fix error return reporting.
-+ *
-+ * Revision 1.5 1999/05/05 22:02:33 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.4 1999/04/29 15:22:40 rgb
-+ * Standardise an error return method.
-+ * Add debugging instrumentation.
-+ * Add check for existence of macros min/max.
-+ * Add extensions permitted/required in/out filters.
-+ * Add satype-to-protocol table.
-+ * Add a second tdb pointer to each parser to accomodate GRPSA.
-+ * Move AH & no_algo_set to GETSPI, UPDATE and ADD.
-+ * Add OOO window check.
-+ * Add support for IPPROTO_IPIP and hooks for IPPROTO_COMP.
-+ * Add timestamp to lifetime parse.
-+ * Fix address structure length checking bug.
-+ * Fix address structure allocation bug (forgot to kmalloc!).
-+ * Add checks for extension lengths.
-+ * Add checks for extension reserved illegal values.
-+ * Add check for spirange legal values.
-+ * Add an extension type for parsing a second satype, SA and
-+ * DST_ADDRESS.
-+ * Make changes to tdb_init() template to get pfkey_tdb_init(),
-+ * eliminating any mention of xformsw.
-+ * Implement getspi, update and grpsa (not tested).
-+ * Add stubs for as yet unimplemented message types.
-+ * Add table of message parsers to substitute for msg_parse switch.
-+ *
-+ * Revision 1.3 1999/04/15 17:58:07 rgb
-+ * Add RCSID labels.
-+ *
-+ * Revision 1.2 1999/04/15 15:37:26 rgb
-+ * Forward check changes from POST1_00 branch.
-+ *
-+ * Revision 1.1.2.1 1999/03/26 20:58:56 rgb
-+ * Add pfkeyv2 support to KLIPS.
-+ *
-+ * Local variables:
-+ * c-file-style: "linux"
-+ * End:
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/radij.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,1225 @@
-+char radij_c_version[] = "RCSID $Id$";
-+
-+/*
-+ * This file is defived from ${SRC}/sys/net/radix.c of BSD 4.4lite
-+ *
-+ * Variable and procedure names have been modified so that they don't
-+ * conflict with the original BSD code, as a small number of modifications
-+ * have been introduced and we may want to reuse this code in BSD.
-+ *
-+ * The `j' in `radij' is pronounced as a voiceless guttural (like a Greek
-+ * chi or a German ch sound (as `doch', not as in `milch'), or even a
-+ * spanish j as in Juan. It is not as far back in the throat like
-+ * the corresponding Hebrew sound, nor is it a soft breath like the English h.
-+ * It has nothing to do with the Dutch ij sound.
-+ *
-+ * Here is the appropriate copyright notice:
-+ */
-+
-+/*
-+ * Copyright (c) 1988, 1989, 1993
-+ * The Regents of the University of California. All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * This product includes software developed by the University of
-+ * California, Berkeley and its contributors.
-+ * 4. Neither the name of the University nor the names of its contributors
-+ * may be used to endorse or promote products derived from this software
-+ * without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * @(#)radix.c 8.2 (Berkeley) 1/4/94
-+ */
-+
-+/*
-+ * Routines to build and maintain radix trees for routing lookups.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h> /* printk() */
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef MALLOC_SLAB
-+# include <linux/slab.h> /* kmalloc() */
-+#else /* MALLOC_SLAB */
-+# include <linux/malloc.h> /* kmalloc() */
-+#endif /* MALLOC_SLAB */
-+#include <linux/errno.h> /* error codes */
-+#include <linux/types.h> /* size_t */
-+#include <linux/interrupt.h> /* mark_bh */
-+
-+#include <linux/netdevice.h> /* struct device, and other headers */
-+#include <linux/etherdevice.h> /* eth_type_trans */
-+#include <linux/ip.h> /* struct iphdr */
-+#include <linux/skbuff.h>
-+#ifdef NET_21
-+# include <asm/uaccess.h>
-+# include <linux/in6.h>
-+#endif /* NET_21 */
-+#include <asm/checksum.h>
-+#include <net/ip.h>
-+
-+#include <openswan.h>
-+
-+#include "openswan/radij.h"
-+#include "openswan/ipsec_encap.h"
-+#include "openswan/ipsec_radij.h"
-+
-+int maj_keylen;
-+struct radij_mask *rj_mkfreelist;
-+struct radij_node_head *mask_rjhead;
-+static int gotOddMasks;
-+static char *maskedKey;
-+static char *rj_zeroes, *rj_ones;
-+
-+#define rj_masktop (mask_rjhead->rnh_treetop)
-+#ifdef Bcmp
-+# undef Bcmp
-+#endif /* Bcmp */
-+#define Bcmp(a, b, l) (l == 0 ? 0 : memcmp((caddr_t)(b), (caddr_t)(a), (size_t)l))
-+/*
-+ * The data structure for the keys is a radix tree with one way
-+ * branching removed. The index rj_b at an internal node n represents a bit
-+ * position to be tested. The tree is arranged so that all descendants
-+ * of a node n have keys whose bits all agree up to position rj_b - 1.
-+ * (We say the index of n is rj_b.)
-+ *
-+ * There is at least one descendant which has a one bit at position rj_b,
-+ * and at least one with a zero there.
-+ *
-+ * A route is determined by a pair of key and mask. We require that the
-+ * bit-wise logical and of the key and mask to be the key.
-+ * We define the index of a route to associated with the mask to be
-+ * the first bit number in the mask where 0 occurs (with bit number 0
-+ * representing the highest order bit).
-+ *
-+ * We say a mask is normal if every bit is 0, past the index of the mask.
-+ * If a node n has a descendant (k, m) with index(m) == index(n) == rj_b,
-+ * and m is a normal mask, then the route applies to every descendant of n.
-+ * If the index(m) < rj_b, this implies the trailing last few bits of k
-+ * before bit b are all 0, (and hence consequently true of every descendant
-+ * of n), so the route applies to all descendants of the node as well.
-+ *
-+ * The present version of the code makes no use of normal routes,
-+ * but similar logic shows that a non-normal mask m such that
-+ * index(m) <= index(n) could potentially apply to many children of n.
-+ * Thus, for each non-host route, we attach its mask to a list at an internal
-+ * node as high in the tree as we can go.
-+ */
-+
-+struct radij_node *
-+rj_search(v_arg, head)
-+ void *v_arg;
-+ struct radij_node *head;
-+{
-+ register struct radij_node *x;
-+ register caddr_t v;
-+
-+ for (x = head, v = v_arg; x->rj_b >= 0;) {
-+ if (x->rj_bmask & v[x->rj_off])
-+ x = x->rj_r;
-+ else
-+ x = x->rj_l;
-+ }
-+ return (x);
-+};
-+
-+struct radij_node *
-+rj_search_m(v_arg, head, m_arg)
-+ struct radij_node *head;
-+ void *v_arg, *m_arg;
-+{
-+ register struct radij_node *x;
-+ register caddr_t v = v_arg, m = m_arg;
-+
-+ for (x = head; x->rj_b >= 0;) {
-+ if ((x->rj_bmask & m[x->rj_off]) &&
-+ (x->rj_bmask & v[x->rj_off]))
-+ x = x->rj_r;
-+ else
-+ x = x->rj_l;
-+ }
-+ return x;
-+};
-+
-+int
-+rj_refines(m_arg, n_arg)
-+ void *m_arg, *n_arg;
-+{
-+ register caddr_t m = m_arg, n = n_arg;
-+ register caddr_t lim, lim2 = lim = n + *(u_char *)n;
-+ int longer = (*(u_char *)n++) - (int)(*(u_char *)m++);
-+ int masks_are_equal = 1;
-+
-+ if (longer > 0)
-+ lim -= longer;
-+ while (n < lim) {
-+ if (*n & ~(*m))
-+ return 0;
-+ if (*n++ != *m++)
-+ masks_are_equal = 0;
-+
-+ }
-+ while (n < lim2)
-+ if (*n++)
-+ return 0;
-+ if (masks_are_equal && (longer < 0))
-+ for (lim2 = m - longer; m < lim2; )
-+ if (*m++)
-+ return 1;
-+ return (!masks_are_equal);
-+}
-+
-+
-+struct radij_node *
-+rj_match(v_arg, head)
-+ void *v_arg;
-+ struct radij_node_head *head;
-+{
-+ caddr_t v = v_arg;
-+ register struct radij_node *t = head->rnh_treetop, *x;
-+ register caddr_t cp = v, cp2, cp3;
-+ caddr_t cplim, mstart;
-+ struct radij_node *saved_t, *top = t;
-+ int off = t->rj_off, vlen = *(u_char *)cp, matched_off;
-+
-+ /*
-+ * Open code rj_search(v, top) to avoid overhead of extra
-+ * subroutine call.
-+ */
-+ for (; t->rj_b >= 0; ) {
-+ if (t->rj_bmask & cp[t->rj_off])
-+ t = t->rj_r;
-+ else
-+ t = t->rj_l;
-+ }
-+ /*
-+ * See if we match exactly as a host destination
-+ */
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:rj_match: "
-+ "* See if we match exactly as a host destination\n");
-+
-+ cp += off; cp2 = t->rj_key + off; cplim = v + vlen;
-+ for (; cp < cplim; cp++, cp2++)
-+ if (*cp != *cp2)
-+ goto on1;
-+ /*
-+ * This extra grot is in case we are explicitly asked
-+ * to look up the default. Ugh!
-+ */
-+ if ((t->rj_flags & RJF_ROOT) && t->rj_dupedkey)
-+ t = t->rj_dupedkey;
-+ return t;
-+on1:
-+ matched_off = cp - v;
-+ saved_t = t;
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:rj_match: "
-+ "** try to match a leaf, t=0p%p\n", t);
-+ do {
-+ if (t->rj_mask) {
-+ /*
-+ * Even if we don't match exactly as a hosts;
-+ * we may match if the leaf we wound up at is
-+ * a route to a net.
-+ */
-+ cp3 = matched_off + t->rj_mask;
-+ cp2 = matched_off + t->rj_key;
-+ for (; cp < cplim; cp++)
-+ if ((*cp2++ ^ *cp) & *cp3++)
-+ break;
-+ if (cp == cplim)
-+ return t;
-+ cp = matched_off + v;
-+ }
-+ } while ((t = t->rj_dupedkey));
-+ t = saved_t;
-+ /* start searching up the tree */
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:rj_match: "
-+ "*** start searching up the tree, t=0p%p\n",
-+ t);
-+ do {
-+ register struct radij_mask *m;
-+
-+ t = t->rj_p;
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:rj_match: "
-+ "**** t=0p%p\n",
-+ t);
-+ if ((m = t->rj_mklist)) {
-+ /*
-+ * After doing measurements here, it may
-+ * turn out to be faster to open code
-+ * rj_search_m here instead of always
-+ * copying and masking.
-+ */
-+ /* off = min(t->rj_off, matched_off); */
-+ off = t->rj_off;
-+ if (matched_off < off)
-+ off = matched_off;
-+ mstart = maskedKey + off;
-+ do {
-+ cp2 = mstart;
-+ cp3 = m->rm_mask + off;
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:rj_match: "
-+ "***** cp2=0p%p cp3=0p%p\n",
-+ cp2, cp3);
-+ for (cp = v + off; cp < cplim;)
-+ *cp2++ = *cp++ & *cp3++;
-+ x = rj_search(maskedKey, t);
-+ while (x && x->rj_mask != m->rm_mask)
-+ x = x->rj_dupedkey;
-+ if (x &&
-+ (Bcmp(mstart, x->rj_key + off,
-+ vlen - off) == 0))
-+ return x;
-+ } while ((m = m->rm_mklist));
-+ }
-+ } while (t != top);
-+ KLIPS_PRINT(debug_radij,
-+ "klips_debug:rj_match: "
-+ "***** not found.\n");
-+ return 0;
-+};
-+
-+#ifdef RJ_DEBUG
-+int rj_nodenum;
-+struct radij_node *rj_clist;
-+int rj_saveinfo;
-+DEBUG_NO_STATIC void traverse(struct radij_node *);
-+#ifdef RJ_DEBUG2
-+int rj_debug = 1;
-+#else
-+int rj_debug = 0;
-+#endif /* RJ_DEBUG2 */
-+#endif /* RJ_DEBUG */
-+
-+struct radij_node *
-+rj_newpair(v, b, nodes)
-+ void *v;
-+ int b;
-+ struct radij_node nodes[2];
-+{
-+ register struct radij_node *tt = nodes, *t = tt + 1;
-+ t->rj_b = b; t->rj_bmask = 0x80 >> (b & 7);
-+ t->rj_l = tt; t->rj_off = b >> 3;
-+ tt->rj_b = -1; tt->rj_key = (caddr_t)v; tt->rj_p = t;
-+ tt->rj_flags = t->rj_flags = RJF_ACTIVE;
-+#ifdef RJ_DEBUG
-+ tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
-+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
-+#endif /* RJ_DEBUG */
-+ return t;
-+}
-+
-+struct radij_node *
-+rj_insert(v_arg, head, dupentry, nodes)
-+ void *v_arg;
-+ struct radij_node_head *head;
-+ int *dupentry;
-+ struct radij_node nodes[2];
-+{
-+ caddr_t v = v_arg;
-+ struct radij_node *top = head->rnh_treetop;
-+ int head_off = top->rj_off, vlen = (int)*((u_char *)v);
-+ register struct radij_node *t = rj_search(v_arg, top);
-+ register caddr_t cp = v + head_off;
-+ register int b;
-+ struct radij_node *tt;
-+ /*
-+ *find first bit at which v and t->rj_key differ
-+ */
-+ {
-+ register caddr_t cp2 = t->rj_key + head_off;
-+ register int cmp_res;
-+ caddr_t cplim = v + vlen;
-+
-+ while (cp < cplim)
-+ if (*cp2++ != *cp++)
-+ goto on1;
-+ *dupentry = 1;
-+ return t;
-+on1:
-+ *dupentry = 0;
-+ cmp_res = (cp[-1] ^ cp2[-1]) & 0xff;
-+ for (b = (cp - v) << 3; cmp_res; b--)
-+ cmp_res >>= 1;
-+ }
-+ {
-+ register struct radij_node *p, *x = top;
-+ cp = v;
-+ do {
-+ p = x;
-+ if (cp[x->rj_off] & x->rj_bmask)
-+ x = x->rj_r;
-+ else x = x->rj_l;
-+ } while (b > (unsigned) x->rj_b); /* x->rj_b < b && x->rj_b >= 0 */
-+#ifdef RJ_DEBUG
-+ if (rj_debug)
-+ printk("klips_debug:rj_insert: Going In:\n"), traverse(p);
-+#endif /* RJ_DEBUG */
-+ t = rj_newpair(v_arg, b, nodes); tt = t->rj_l;
-+ if ((cp[p->rj_off] & p->rj_bmask) == 0)
-+ p->rj_l = t;
-+ else
-+ p->rj_r = t;
-+ x->rj_p = t; t->rj_p = p; /* frees x, p as temp vars below */
-+ if ((cp[t->rj_off] & t->rj_bmask) == 0) {
-+ t->rj_r = x;
-+ } else {
-+ t->rj_r = tt; t->rj_l = x;
-+ }
-+#ifdef RJ_DEBUG
-+ if (rj_debug)
-+ printk("klips_debug:rj_insert: Coming out:\n"), traverse(p);
-+#endif /* RJ_DEBUG */
-+ }
-+ return (tt);
-+}
-+
-+struct radij_node *
-+rj_addmask(n_arg, search, skip)
-+ int search, skip;
-+ void *n_arg;
-+{
-+ caddr_t netmask = (caddr_t)n_arg;
-+ register struct radij_node *x;
-+ register caddr_t cp, cplim;
-+ register int b, mlen, j;
-+ int maskduplicated;
-+
-+ mlen = *(u_char *)netmask;
-+ if (search) {
-+ x = rj_search(netmask, rj_masktop);
-+ mlen = *(u_char *)netmask;
-+ if (Bcmp(netmask, x->rj_key, mlen) == 0)
-+ return (x);
-+ }
-+ R_Malloc(x, struct radij_node *, maj_keylen + 2 * sizeof (*x));
-+ if (x == 0)
-+ return (0);
-+ Bzero(x, maj_keylen + 2 * sizeof (*x));
-+ cp = (caddr_t)(x + 2);
-+ Bcopy(netmask, cp, mlen);
-+ netmask = cp;
-+ x = rj_insert(netmask, mask_rjhead, &maskduplicated, x);
-+ /*
-+ * Calculate index of mask.
-+ */
-+ cplim = netmask + mlen;
-+ for (cp = netmask + skip; cp < cplim; cp++)
-+ if (*(u_char *)cp != 0xff)
-+ break;
-+ b = (cp - netmask) << 3;
-+ if (cp != cplim) {
-+ if (*cp != 0) {
-+ gotOddMasks = 1;
-+ for (j = 0x80; j; b++, j >>= 1)
-+ if ((j & *cp) == 0)
-+ break;
-+ }
-+ }
-+ x->rj_b = -1 - b;
-+ return (x);
-+}
-+
-+#if 0
-+struct radij_node *
-+#endif
-+int
-+rj_addroute(v_arg, n_arg, head, treenodes)
-+ void *v_arg, *n_arg;
-+ struct radij_node_head *head;
-+ struct radij_node treenodes[2];
-+{
-+ caddr_t v = (caddr_t)v_arg, netmask = (caddr_t)n_arg;
-+ register struct radij_node *t, *x=NULL, *tt;
-+ struct radij_node *saved_tt, *top = head->rnh_treetop;
-+ short b = 0, b_leaf;
-+ int mlen, keyduplicated;
-+ caddr_t cplim;
-+ struct radij_mask *m, **mp;
-+
-+ /*
-+ * In dealing with non-contiguous masks, there may be
-+ * many different routes which have the same mask.
-+ * We will find it useful to have a unique pointer to
-+ * the mask to speed avoiding duplicate references at
-+ * nodes and possibly save time in calculating indices.
-+ */
-+ if (netmask) {
-+ x = rj_search(netmask, rj_masktop);
-+ mlen = *(u_char *)netmask;
-+ if (Bcmp(netmask, x->rj_key, mlen) != 0) {
-+ x = rj_addmask(netmask, 0, top->rj_off);
-+ if (x == 0)
-+ return -ENOMEM; /* (0) rgb */
-+ }
-+ netmask = x->rj_key;
-+ b = -1 - x->rj_b;
-+ }
-+ /*
-+ * Deal with duplicated keys: attach node to previous instance
-+ */
-+ saved_tt = tt = rj_insert(v, head, &keyduplicated, treenodes);
-+#ifdef RJ_DEBUG
-+ printk("addkey: duplicated: %d\n", keyduplicated);
-+#endif
-+ if (keyduplicated) {
-+ do {
-+ if (tt->rj_mask == netmask)
-+ return -EEXIST; /* -ENXIO; (0) rgb */
-+ t = tt;
-+ if (netmask == 0 ||
-+ (tt->rj_mask && rj_refines(netmask, tt->rj_mask)))
-+ break;
-+ } while ((tt = tt->rj_dupedkey));
-+ /*
-+ * If the mask is not duplicated, we wouldn't
-+ * find it among possible duplicate key entries
-+ * anyway, so the above test doesn't hurt.
-+ *
-+ * We sort the masks for a duplicated key the same way as
-+ * in a masklist -- most specific to least specific.
-+ * This may require the unfortunate nuisance of relocating
-+ * the head of the list.
-+ */
-+ if (tt && t == saved_tt) {
-+ struct radij_node *xx = x;
-+ /* link in at head of list */
-+ (tt = treenodes)->rj_dupedkey = t;
-+ tt->rj_flags = t->rj_flags;
-+ tt->rj_p = x = t->rj_p;
-+ if (x->rj_l == t) x->rj_l = tt; else x->rj_r = tt;
-+ saved_tt = tt; x = xx;
-+ } else {
-+ (tt = treenodes)->rj_dupedkey = t->rj_dupedkey;
-+ t->rj_dupedkey = tt;
-+ }
-+#ifdef RJ_DEBUG
-+ t=tt+1; tt->rj_info = rj_nodenum++; t->rj_info = rj_nodenum++;
-+ tt->rj_twin = t; tt->rj_ybro = rj_clist; rj_clist = tt;
-+#endif /* RJ_DEBUG */
-+ t = saved_tt;
-+ tt->rj_key = (caddr_t) v;
-+ tt->rj_b = -1;
-+ tt->rj_flags = t->rj_flags & ~RJF_ROOT;
-+ }
-+ /*
-+ * Put mask in tree.
-+ */
-+ if (netmask) {
-+ tt->rj_mask = netmask;
-+ tt->rj_b = x->rj_b;
-+ }
-+ t = saved_tt->rj_p;
-+ b_leaf = -1 - t->rj_b;
-+ if (t->rj_r == saved_tt) x = t->rj_l; else x = t->rj_r;
-+ /* Promote general routes from below */
-+ if (x->rj_b < 0) {
-+ if (x->rj_mask && (x->rj_b >= b_leaf) && x->rj_mklist == 0) {
-+ MKGet(m);
-+ if (m) {
-+ Bzero(m, sizeof *m);
-+ m->rm_b = x->rj_b;
-+ m->rm_mask = x->rj_mask;
-+ x->rj_mklist = t->rj_mklist = m;
-+ }
-+ }
-+ } else if (x->rj_mklist) {
-+ /*
-+ * Skip over masks whose index is > that of new node
-+ */
-+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
-+ if (m->rm_b >= b_leaf)
-+ break;
-+ t->rj_mklist = m; *mp = 0;
-+ }
-+ /* Add new route to highest possible ancestor's list */
-+ if ((netmask == 0) || (b > t->rj_b )) {
-+#ifdef RJ_DEBUG
-+ printk("klips:radij.c: netmask = %p or b(%d)>t->rjb(%d)\n", netmask, b, t->rj_b);
-+#endif
-+ return 0; /* tt rgb */ /* can't lift at all */
-+ }
-+ b_leaf = tt->rj_b;
-+ do {
-+ x = t;
-+ t = t->rj_p;
-+ } while (b <= t->rj_b && x != top);
-+ /*
-+ * Search through routes associated with node to
-+ * insert new route according to index.
-+ * For nodes of equal index, place more specific
-+ * masks first.
-+ */
-+ cplim = netmask + mlen;
-+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist) {
-+ if (m->rm_b < b_leaf)
-+ continue;
-+ if (m->rm_b > b_leaf)
-+ break;
-+ if (m->rm_mask == netmask) {
-+ m->rm_refs++;
-+ tt->rj_mklist = m;
-+#ifdef RJ_DEBUG
-+ printk("klips:radij.c: m->rm_mask %p == netmask\n", netmask);
-+#endif
-+ return 0; /* tt rgb */
-+ }
-+ if (rj_refines(netmask, m->rm_mask))
-+ break;
-+ }
-+ MKGet(m);
-+ if (m == 0) {
-+ printk("klips_debug:rj_addroute: "
-+ "Mask for route not entered\n");
-+ return 0; /* (tt) rgb */
-+ }
-+ Bzero(m, sizeof *m);
-+ m->rm_b = b_leaf;
-+ m->rm_mask = netmask;
-+ m->rm_mklist = *mp;
-+ *mp = m;
-+ tt->rj_mklist = m;
-+#ifdef RJ_DEBUG
-+ printk("klips:radij.c: addroute done\n");
-+#endif
-+ return 0; /* tt rgb */
-+}
-+
-+int
-+rj_delete(v_arg, netmask_arg, head, node)
-+ void *v_arg, *netmask_arg;
-+ struct radij_node_head *head;
-+ struct radij_node **node;
-+{
-+ register struct radij_node *t, *p, *x, *tt;
-+ struct radij_mask *m, *saved_m, **mp;
-+ struct radij_node *dupedkey, *saved_tt, *top;
-+ caddr_t v, netmask;
-+ int b, head_off, vlen;
-+
-+ v = v_arg;
-+ netmask = netmask_arg;
-+ x = head->rnh_treetop;
-+ tt = rj_search(v, x);
-+ head_off = x->rj_off;
-+ vlen = *(u_char *)v;
-+ saved_tt = tt;
-+ top = x;
-+ if (tt == 0 ||
-+ Bcmp(v + head_off, tt->rj_key + head_off, vlen - head_off))
-+ return -EFAULT; /* (0) rgb */
-+ /*
-+ * Delete our route from mask lists.
-+ */
-+ if ((dupedkey = tt->rj_dupedkey)) {
-+ if (netmask)
-+ netmask = rj_search(netmask, rj_masktop)->rj_key;
-+ while (tt->rj_mask != netmask)
-+ if ((tt = tt->rj_dupedkey) == 0)
-+ return -ENOENT; /* -ENXIO; (0) rgb */
-+ }
-+ if (tt->rj_mask == 0 || (saved_m = m = tt->rj_mklist) == 0)
-+ goto on1;
-+ if (m->rm_mask != tt->rj_mask) {
-+ printk("klips_debug:rj_delete: "
-+ "inconsistent annotation\n");
-+ goto on1;
-+ }
-+ if (--m->rm_refs >= 0)
-+ goto on1;
-+ b = -1 - tt->rj_b;
-+ t = saved_tt->rj_p;
-+ if (b > t->rj_b)
-+ goto on1; /* Wasn't lifted at all */
-+ do {
-+ x = t;
-+ t = t->rj_p;
-+ } while (b <= t->rj_b && x != top);
-+ for (mp = &x->rj_mklist; (m = *mp); mp = &m->rm_mklist)
-+ if (m == saved_m) {
-+ *mp = m->rm_mklist;
-+ MKFree(m);
-+ break;
-+ }
-+ if (m == 0)
-+ printk("klips_debug:rj_delete: "
-+ "couldn't find our annotation\n");
-+on1:
-+ /*
-+ * Eliminate us from tree
-+ */
-+ if (tt->rj_flags & RJF_ROOT)
-+ return -EFAULT; /* (0) rgb */
-+#ifdef RJ_DEBUG
-+ /* Get us out of the creation list */
-+ for (t = rj_clist; t && t->rj_ybro != tt; t = t->rj_ybro) {}
-+ if (t) t->rj_ybro = tt->rj_ybro;
-+#endif /* RJ_DEBUG */
-+ t = tt->rj_p;
-+ if (dupedkey) {
-+ if (tt == saved_tt) {
-+ x = dupedkey; x->rj_p = t;
-+ if (t->rj_l == tt) t->rj_l = x; else t->rj_r = x;
-+ } else {
-+ for (x = p = saved_tt; p && p->rj_dupedkey != tt;)
-+ p = p->rj_dupedkey;
-+ if (p) p->rj_dupedkey = tt->rj_dupedkey;
-+ else printk("klips_debug:rj_delete: "
-+ "couldn't find node that we started with\n");
-+ }
-+ t = tt + 1;
-+ if (t->rj_flags & RJF_ACTIVE) {
-+#ifndef RJ_DEBUG
-+ *++x = *t; p = t->rj_p;
-+#else
-+ b = t->rj_info; *++x = *t; t->rj_info = b; p = t->rj_p;
-+#endif /* RJ_DEBUG */
-+ if (p->rj_l == t) p->rj_l = x; else p->rj_r = x;
-+ x->rj_l->rj_p = x; x->rj_r->rj_p = x;
-+ }
-+ goto out;
-+ }
-+ if (t->rj_l == tt) x = t->rj_r; else x = t->rj_l;
-+ p = t->rj_p;
-+ if (p->rj_r == t) p->rj_r = x; else p->rj_l = x;
-+ x->rj_p = p;
-+ /*
-+ * Demote routes attached to us.
-+ */
-+ if (t->rj_mklist) {
-+ if (x->rj_b >= 0) {
-+ for (mp = &x->rj_mklist; (m = *mp);)
-+ mp = &m->rm_mklist;
-+ *mp = t->rj_mklist;
-+ } else {
-+ for (m = t->rj_mklist; m;) {
-+ struct radij_mask *mm = m->rm_mklist;
-+ if (m == x->rj_mklist && (--(m->rm_refs) < 0)) {
-+ x->rj_mklist = 0;
-+ MKFree(m);
-+ } else
-+ printk("klips_debug:rj_delete: "
-+ "Orphaned Mask 0p%p at 0p%p\n", m, x);
-+ m = mm;
-+ }
-+ }
-+ }
-+ /*
-+ * We may be holding an active internal node in the tree.
-+ */
-+ x = tt + 1;
-+ if (t != x) {
-+#ifndef RJ_DEBUG
-+ *t = *x;
-+#else
-+ b = t->rj_info; *t = *x; t->rj_info = b;
-+#endif /* RJ_DEBUG */
-+ t->rj_l->rj_p = t; t->rj_r->rj_p = t;
-+ p = x->rj_p;
-+ if (p->rj_l == x) p->rj_l = t; else p->rj_r = t;
-+ }
-+out:
-+ tt->rj_flags &= ~RJF_ACTIVE;
-+ tt[1].rj_flags &= ~RJF_ACTIVE;
-+ *node = tt;
-+ return 0; /* (tt) rgb */
-+}
-+
-+int
-+rj_walktree(h, f, w)
-+ struct radij_node_head *h;
-+ register int (*f)(struct radij_node *,void *);
-+ void *w;
-+{
-+ int error;
-+ struct radij_node *base, *next;
-+ register struct radij_node *rn;
-+
-+ if(!h || !f /* || !w */) {
-+ return -ENODATA;
-+ }
-+
-+ rn = h->rnh_treetop;
-+ /*
-+ * This gets complicated because we may delete the node
-+ * while applying the function f to it, so we need to calculate
-+ * the successor node in advance.
-+ */
-+ /* First time through node, go left */
-+ while (rn->rj_b >= 0)
-+ rn = rn->rj_l;
-+ for (;;) {
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(debug_radij) {
-+ printk("klips_debug:rj_walktree: "
-+ "for: rn=0p%p rj_b=%d rj_flags=%x",
-+ rn,
-+ rn->rj_b,
-+ rn->rj_flags);
-+ rn->rj_b >= 0 ?
-+ printk(" node off=%x\n",
-+ rn->rj_off) :
-+ printk(" leaf key = %08x->%08x\n",
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
-+ ;
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ base = rn;
-+ /* If at right child go back up, otherwise, go right */
-+ while (rn->rj_p->rj_r == rn && (rn->rj_flags & RJF_ROOT) == 0)
-+ rn = rn->rj_p;
-+ /* Find the next *leaf* since next node might vanish, too */
-+ for (rn = rn->rj_p->rj_r; rn->rj_b >= 0;)
-+ rn = rn->rj_l;
-+ next = rn;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(debug_radij) {
-+ printk("klips_debug:rj_walktree: "
-+ "processing leaves, rn=0p%p rj_b=%d rj_flags=%x",
-+ rn,
-+ rn->rj_b,
-+ rn->rj_flags);
-+ rn->rj_b >= 0 ?
-+ printk(" node off=%x\n",
-+ rn->rj_off) :
-+ printk(" leaf key = %08x->%08x\n",
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
-+ ;
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ /* Process leaves */
-+ while ((rn = base)) {
-+ base = rn->rj_dupedkey;
-+#ifdef CONFIG_IPSEC_DEBUG
-+ if(debug_radij) {
-+ printk("klips_debug:rj_walktree: "
-+ "while: base=0p%p rn=0p%p rj_b=%d rj_flags=%x",
-+ base,
-+ rn,
-+ rn->rj_b,
-+ rn->rj_flags);
-+ rn->rj_b >= 0 ?
-+ printk(" node off=%x\n",
-+ rn->rj_off) :
-+ printk(" leaf key = %08x->%08x\n",
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr))
-+ ;
-+ }
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ if (!(rn->rj_flags & RJF_ROOT) && (error = (*f)(rn, w)))
-+ return (-error);
-+ }
-+ rn = next;
-+ if (rn->rj_flags & RJF_ROOT)
-+ return (0);
-+ }
-+ /* NOTREACHED */
-+}
-+
-+int
-+rj_inithead(head, off)
-+ void **head;
-+ int off;
-+{
-+ register struct radij_node_head *rnh;
-+ register struct radij_node *t, *tt, *ttt;
-+ if (*head)
-+ return (1);
-+ R_Malloc(rnh, struct radij_node_head *, sizeof (*rnh));
-+ if (rnh == NULL)
-+ return (0);
-+ Bzero(rnh, sizeof (*rnh));
-+ *head = rnh;
-+ t = rj_newpair(rj_zeroes, off, rnh->rnh_nodes);
-+ ttt = rnh->rnh_nodes + 2;
-+ t->rj_r = ttt;
-+ t->rj_p = t;
-+ tt = t->rj_l;
-+ tt->rj_flags = t->rj_flags = RJF_ROOT | RJF_ACTIVE;
-+ tt->rj_b = -1 - off;
-+ *ttt = *tt;
-+ ttt->rj_key = rj_ones;
-+ rnh->rnh_addaddr = rj_addroute;
-+ rnh->rnh_deladdr = rj_delete;
-+ rnh->rnh_matchaddr = rj_match;
-+ rnh->rnh_walktree = rj_walktree;
-+ rnh->rnh_treetop = t;
-+ return (1);
-+}
-+
-+void
-+rj_init()
-+{
-+ char *cp, *cplim;
-+
-+ if (maj_keylen == 0) {
-+ printk("klips_debug:rj_init: "
-+ "radij functions require maj_keylen be set\n");
-+ return;
-+ }
-+ R_Malloc(rj_zeroes, char *, 3 * maj_keylen);
-+ if (rj_zeroes == NULL)
-+ panic("rj_init");
-+ Bzero(rj_zeroes, 3 * maj_keylen);
-+ rj_ones = cp = rj_zeroes + maj_keylen;
-+ maskedKey = cplim = rj_ones + maj_keylen;
-+ while (cp < cplim)
-+ *cp++ = -1;
-+ if (rj_inithead((void **)&mask_rjhead, 0) == 0)
-+ panic("rj_init 2");
-+}
-+
-+void
-+rj_preorder(struct radij_node *rn, int l)
-+{
-+ int i;
-+
-+ if (rn == NULL){
-+ printk("klips_debug:rj_preorder: "
-+ "NULL pointer\n");
-+ return;
-+ }
-+
-+ if (rn->rj_b >= 0){
-+ rj_preorder(rn->rj_l, l+1);
-+ rj_preorder(rn->rj_r, l+1);
-+ printk("klips_debug:");
-+ for (i=0; i<l; i++)
-+ printk("*");
-+ printk(" off = %d\n",
-+ rn->rj_off);
-+ } else {
-+ printk("klips_debug:");
-+ for (i=0; i<l; i++)
-+ printk("@");
-+ printk(" flags = %x",
-+ (u_int)rn->rj_flags);
-+ if (rn->rj_flags & RJF_ACTIVE) {
-+ printk(" @key=0p%p",
-+ rn->rj_key);
-+ printk(" key = %08x->%08x",
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_src.s_addr),
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_key)->sen_ip_dst.s_addr));
-+ printk(" @mask=0p%p",
-+ rn->rj_mask);
-+ if (rn->rj_mask)
-+ printk(" mask = %08x->%08x",
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_src.s_addr),
-+ (u_int)ntohl(((struct sockaddr_encap *)rn->rj_mask)->sen_ip_dst.s_addr));
-+ if (rn->rj_dupedkey)
-+ printk(" dupedkey = 0p%p",
-+ rn->rj_dupedkey);
-+ }
-+ printk("\n");
-+ }
-+}
-+
-+#ifdef RJ_DEBUG
-+DEBUG_NO_STATIC void traverse(struct radij_node *p)
-+{
-+ rj_preorder(p, 0);
-+}
-+#endif /* RJ_DEBUG */
-+
-+void
-+rj_dumptrees(void)
-+{
-+ rj_preorder(rnh->rnh_treetop, 0);
-+}
-+
-+void
-+rj_free_mkfreelist(void)
-+{
-+ struct radij_mask *mknp, *mknp2;
-+
-+ mknp = rj_mkfreelist;
-+ while(mknp)
-+ {
-+ mknp2 = mknp;
-+ mknp = mknp->rm_mklist;
-+ kfree(mknp2);
-+ }
-+}
-+
-+int
-+radijcleartree(void)
-+{
-+ return rj_walktree(rnh, ipsec_rj_walker_delete, NULL);
-+}
-+
-+int
-+radijcleanup(void)
-+{
-+ int error = 0;
-+
-+ error = radijcleartree();
-+
-+ rj_free_mkfreelist();
-+
-+/* rj_walktree(mask_rjhead, ipsec_rj_walker_delete, NULL); */
-+ if(mask_rjhead) {
-+ kfree(mask_rjhead);
-+ }
-+
-+ if(rj_zeroes) {
-+ kfree(rj_zeroes);
-+ }
-+
-+ if(rnh) {
-+ kfree(rnh);
-+ }
-+
-+ return error;
-+}
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.46 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.45 2003/10/31 02:27:55 mcr
-+ * pulled up port-selector patches and sa_id elimination.
-+ *
-+ * Revision 1.44.30.1 2003/10/29 01:30:41 mcr
-+ * elimited "struct sa_id".
-+ *
-+ * Revision 1.44 2002/07/24 18:44:54 rgb
-+ * Type fiddling to tame ia64 compiler.
-+ *
-+ * Revision 1.43 2002/05/23 07:14:11 rgb
-+ * Cleaned up %p variants to 0p%p for test suite cleanup.
-+ *
-+ * Revision 1.42 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.41 2002/04/24 07:36:35 mcr
-+ * Moved from ./klips/net/ipsec/radij.c,v
-+ *
-+ * Revision 1.40 2002/01/29 17:17:58 mcr
-+ * moved include of ipsec_param.h to after include of linux/kernel.h
-+ * otherwise, it seems that some option that is set in ipsec_param.h
-+ * screws up something subtle in the include path to kernel.h, and
-+ * it complains on the snprintf() prototype.
-+ *
-+ * Revision 1.39 2002/01/29 04:00:55 mcr
-+ * more excise of kversions.h header.
-+ *
-+ * Revision 1.38 2002/01/29 02:13:19 mcr
-+ * introduction of ipsec_kversion.h means that include of
-+ * ipsec_param.h must preceed any decisions about what files to
-+ * include to deal with differences in kernel source.
-+ *
-+ * Revision 1.37 2001/10/18 04:45:23 rgb
-+ * 2.4.9 kernel deprecates linux/malloc.h in favour of linux/slab.h,
-+ * lib/freeswan.h version macros moved to lib/kversions.h.
-+ * Other compiler directive cleanups.
-+ *
-+ * Revision 1.36 2001/08/22 13:43:51 henry
-+ * eliminate the single use of min() to avoid problems with Linus changing it
-+ *
-+ * Revision 1.35 2001/06/15 04:57:29 rgb
-+ * Clarified error return codes.
-+ * Changed mask add already exists to EEXIST.
-+ * Changed mask delete did not exist to ENOENT.
-+ *
-+ * Revision 1.34 2001/05/03 19:44:26 rgb
-+ * Fix sign of error return codes for rj_addroute().
-+ *
-+ * Revision 1.33 2001/02/27 22:24:56 rgb
-+ * Re-formatting debug output (line-splitting, joining, 1arg/line).
-+ * Check for satoa() return codes.
-+ *
-+ * Revision 1.32 2001/02/27 06:23:15 rgb
-+ * Debug line splitting.
-+ *
-+ * Revision 1.31 2000/11/06 04:35:21 rgb
-+ * Clear table *before* releasing other items in radijcleanup.
-+ *
-+ * Revision 1.30 2000/09/20 04:07:40 rgb
-+ * Changed static functions to DEBUG_NO_STATIC to reveal function names in
-+ * oopsen.
-+ *
-+ * Revision 1.29 2000/09/12 03:25:02 rgb
-+ * Moved radij_c_version printing to ipsec_version_get_info().
-+ *
-+ * Revision 1.28 2000/09/08 19:12:56 rgb
-+ * Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
-+ *
-+ * Revision 1.27 2000/07/28 14:58:32 rgb
-+ * Changed kfree_s to kfree, eliminating extra arg to fix 2.4.0-test5.
-+ *
-+ * Revision 1.26 2000/05/10 23:11:37 rgb
-+ * Comment out most of the startup version information.
-+ *
-+ * Revision 1.25 2000/01/21 06:21:47 rgb
-+ * Change return codes to negative on error.
-+ *
-+ * Revision 1.24 1999/11/18 04:09:20 rgb
-+ * Replaced all kernel version macros to shorter, readable form.
-+ *
-+ * Revision 1.23 1999/11/17 15:53:41 rgb
-+ * Changed all occurrences of #include "../../../lib/freeswan.h"
-+ * to #include <freeswan.h> which works due to -Ilibfreeswan in the
-+ * klips/net/ipsec/Makefile.
-+ *
-+ * Revision 1.22 1999/10/15 22:17:28 rgb
-+ * Modify radijcleanup() to call radijcleartree().
-+ *
-+ * Revision 1.21 1999/10/08 18:37:34 rgb
-+ * Fix end-of-line spacing to sate whining PHMs.
-+ *
-+ * Revision 1.20 1999/10/01 15:44:54 rgb
-+ * Move spinlock header include to 2.1> scope.
-+ *
-+ * Revision 1.19 1999/10/01 08:35:52 rgb
-+ * Add spinlock include to shut up compiler for 2.0.38.
-+ *
-+ * Revision 1.18 1999/09/23 18:02:52 rgb
-+ * De-alarm the search failure message so it doesn't sound so grave.
-+ *
-+ * Revision 1.17 1999/05/25 21:26:01 rgb
-+ * Fix rj_walktree() sanity checking bug.
-+ *
-+ * Revision 1.16 1999/05/09 03:25:38 rgb
-+ * Fix bug introduced by 2.2 quick-and-dirty patch.
-+ *
-+ * Revision 1.15 1999/05/05 22:02:33 rgb
-+ * Add a quick and dirty port to 2.2 kernels by Marc Boucher <marc@mbsi.ca>.
-+ *
-+ * Revision 1.14 1999/04/29 15:24:15 rgb
-+ * Add sanity checking for null pointer arguments.
-+ * Standardise an error return method.
-+ *
-+ * Revision 1.13 1999/04/11 00:29:02 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.12 1999/04/06 04:54:28 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ * Revision 1.11 1999/02/17 16:52:53 rgb
-+ * Convert DEBUG_IPSEC to KLIPS_PRINT
-+ * Clean out unused cruft.
-+ *
-+ * Revision 1.10 1999/01/22 06:30:05 rgb
-+ * Cruft clean-out.
-+ * 64-bit clean-up.
-+ *
-+ * Revision 1.9 1998/12/01 13:22:04 rgb
-+ * Added support for debug printing of version info.
-+ *
-+ * Revision 1.8 1998/11/30 13:22:55 rgb
-+ * Rationalised all the klips kernel file headers. They are much shorter
-+ * now and won't conflict under RH5.2.
-+ *
-+ * Revision 1.7 1998/10/25 02:43:26 rgb
-+ * Change return type on rj_addroute and rj_delete and add and argument
-+ * to the latter to be able to transmit more infomation about errors.
-+ *
-+ * Revision 1.6 1998/10/19 14:30:06 rgb
-+ * Added inclusion of freeswan.h.
-+ *
-+ * Revision 1.5 1998/10/09 04:33:27 rgb
-+ * Added 'klips_debug' prefix to all klips printk debug statements.
-+ * Fixed output formatting slightly.
-+ *
-+ * Revision 1.4 1998/07/28 00:06:59 rgb
-+ * Add debug detail to tree traversing.
-+ *
-+ * Revision 1.3 1998/07/14 18:07:58 rgb
-+ * Add a routine to clear the eroute tree.
-+ *
-+ * Revision 1.2 1998/06/25 20:03:22 rgb
-+ * Cleanup #endif comments. Debug output for rj_init.
-+ *
-+ * Revision 1.1 1998/06/18 21:30:22 henry
-+ * move sources from klips/src to klips/net/ipsec to keep stupid kernel
-+ * build scripts happier about symlinks
-+ *
-+ * Revision 1.8 1998/05/25 20:34:15 rgb
-+ * Remove temporary ipsec_walk, rj_deltree and rj_delnodes functions.
-+ *
-+ * Rename ipsec_rj_walker (ipsec_walk) to ipsec_rj_walker_procprint and
-+ * add ipsec_rj_walker_delete.
-+ *
-+ * Recover memory for eroute table on unload of module.
-+ *
-+ * Revision 1.7 1998/05/21 12:58:58 rgb
-+ * Moved 'extern' definitions to ipsec_radij.h to support /proc 3k limit fix.
-+ *
-+ * Revision 1.6 1998/04/23 20:57:29 rgb
-+ * Cleaned up compiler warnings for unused debugging functions.
-+ *
-+ * Revision 1.5 1998/04/22 16:51:38 rgb
-+ * Tidy up radij debug code from recent rash of modifications to debug code.
-+ *
-+ * Revision 1.4 1998/04/21 21:28:56 rgb
-+ * Rearrange debug switches to change on the fly debug output from user
-+ * space. Only kernel changes checked in at this time. radij.c was also
-+ * changed to temporarily remove buggy debugging code in rj_delete causing
-+ * an OOPS and hence, netlink device open errors.
-+ *
-+ * Revision 1.3 1998/04/14 17:30:37 rgb
-+ * Fix up compiling errors for radij tree memory reclamation.
-+ *
-+ * Revision 1.2 1998/04/12 22:03:25 rgb
-+ * Updated ESP-3DES-HMAC-MD5-96,
-+ * ESP-DES-HMAC-MD5-96,
-+ * AH-HMAC-MD5-96,
-+ * AH-HMAC-SHA1-96 since Henry started freeswan cvs repository
-+ * from old standards (RFC182[5-9] to new (as of March 1998) drafts.
-+ *
-+ * Fixed eroute references in /proc/net/ipsec*.
-+ *
-+ * Started to patch module unloading memory leaks in ipsec_netlink and
-+ * radij tree unloading.
-+ *
-+ * Revision 1.1 1998/04/09 03:06:15 henry
-+ * sources moved up from linux/net/ipsec
-+ *
-+ * Revision 1.1.1.1 1998/04/08 05:35:03 henry
-+ * RGB's ipsec-0.8pre2.tar.gz ipsec-0.8
-+ *
-+ * Revision 0.4 1997/01/15 01:28:15 ji
-+ * No changes.
-+ *
-+ * Revision 0.3 1996/11/20 14:39:04 ji
-+ * Minor cleanups.
-+ * Rationalized debugging code.
-+ *
-+ * Revision 0.2 1996/11/02 00:18:33 ji
-+ * First limited release.
-+ *
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/sysctl_net_ipsec.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,196 @@
-+/*
-+ * sysctl interface to net IPSEC subsystem.
-+ * Copyright (C) 1998, 1999, 2000, 2001 Richard Guy Briggs.
-+ *
-+ * 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. See <http://www.fsf.org/copyleft/gpl.txt>.
-+ *
-+ * 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.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+/* -*- linux-c -*-
-+ *
-+ * Initiated April 3, 1998, Richard Guy Briggs <rgb@conscoop.ottawa.on.ca>
-+ */
-+
-+#include <linux/mm.h>
-+#include <linux/sysctl.h>
-+
-+#include "openswan/ipsec_param.h"
-+
-+#ifdef CONFIG_SYSCTL
-+
-+#define NET_IPSEC 2112 /* Random number */
-+#ifdef CONFIG_IPSEC_DEBUG
-+extern int debug_ah;
-+extern int debug_esp;
-+extern int debug_tunnel;
-+extern int debug_eroute;
-+extern int debug_spi;
-+extern int debug_radij;
-+extern int debug_netlink;
-+extern int debug_xform;
-+extern int debug_rcv;
-+extern int debug_pfkey;
-+extern int sysctl_ipsec_debug_verbose;
-+#ifdef CONFIG_IPSEC_IPCOMP
-+extern int sysctl_ipsec_debug_ipcomp;
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+#endif /* CONFIG_IPSEC_DEBUG */
-+
-+extern int sysctl_ipsec_icmp;
-+extern int sysctl_ipsec_inbound_policy_check;
-+extern int sysctl_ipsec_tos;
-+int sysctl_ipsec_regress_pfkey_lossage;
-+
-+enum {
-+#ifdef CONFIG_IPSEC_DEBUG
-+ NET_IPSEC_DEBUG_AH=1,
-+ NET_IPSEC_DEBUG_ESP=2,
-+ NET_IPSEC_DEBUG_TUNNEL=3,
-+ NET_IPSEC_DEBUG_EROUTE=4,
-+ NET_IPSEC_DEBUG_SPI=5,
-+ NET_IPSEC_DEBUG_RADIJ=6,
-+ NET_IPSEC_DEBUG_NETLINK=7,
-+ NET_IPSEC_DEBUG_XFORM=8,
-+ NET_IPSEC_DEBUG_RCV=9,
-+ NET_IPSEC_DEBUG_PFKEY=10,
-+ NET_IPSEC_DEBUG_VERBOSE=11,
-+ NET_IPSEC_DEBUG_IPCOMP=12,
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ NET_IPSEC_ICMP=13,
-+ NET_IPSEC_INBOUND_POLICY_CHECK=14,
-+ NET_IPSEC_TOS=15,
-+ NET_IPSEC_REGRESS_PFKEY_LOSSAGE=16,
-+};
-+
-+static ctl_table ipsec_table[] = {
-+#ifdef CONFIG_IPSEC_DEBUG
-+ { NET_IPSEC_DEBUG_AH, "debug_ah", &debug_ah,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_ESP, "debug_esp", &debug_esp,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_TUNNEL, "debug_tunnel", &debug_tunnel,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_EROUTE, "debug_eroute", &debug_eroute,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_SPI, "debug_spi", &debug_spi,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_RADIJ, "debug_radij", &debug_radij,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_NETLINK, "debug_netlink", &debug_netlink,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_XFORM, "debug_xform", &debug_xform,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_RCV, "debug_rcv", &debug_rcv,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_PFKEY, "debug_pfkey", &debug_pfkey,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_DEBUG_VERBOSE, "debug_verbose",&sysctl_ipsec_debug_verbose,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+#ifdef CONFIG_IPSEC_IPCOMP
-+ { NET_IPSEC_DEBUG_IPCOMP, "debug_ipcomp", &sysctl_ipsec_debug_ipcomp,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+#endif /* CONFIG_IPSEC_IPCOMP */
-+
-+#ifdef CONFIG_IPSEC_REGRESS
-+ { NET_IPSEC_REGRESS_PFKEY_LOSSAGE, "pfkey_lossage",
-+ &sysctl_ipsec_regress_pfkey_lossage,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+#endif /* CONFIG_IPSEC_REGRESS */
-+
-+#endif /* CONFIG_IPSEC_DEBUG */
-+ { NET_IPSEC_ICMP, "icmp", &sysctl_ipsec_icmp,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_INBOUND_POLICY_CHECK, "inbound_policy_check", &sysctl_ipsec_inbound_policy_check,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ { NET_IPSEC_TOS, "tos", &sysctl_ipsec_tos,
-+ sizeof(int), 0644, NULL, &proc_dointvec},
-+ {0}
-+};
-+
-+static ctl_table ipsec_net_table[] = {
-+ { NET_IPSEC, "ipsec", NULL, 0, 0555, ipsec_table },
-+ { 0 }
-+};
-+
-+static ctl_table ipsec_root_table[] = {
-+ { CTL_NET, "net", NULL, 0, 0555, ipsec_net_table },
-+ { 0 }
-+};
-+
-+static struct ctl_table_header *ipsec_table_header;
-+
-+int ipsec_sysctl_register(void)
-+{
-+ ipsec_table_header = register_sysctl_table(ipsec_root_table, 0);
-+ if (!ipsec_table_header) {
-+ return -ENOMEM;
-+ }
-+ return 0;
-+}
-+
-+void ipsec_sysctl_unregister(void)
-+{
-+ unregister_sysctl_table(ipsec_table_header);
-+}
-+
-+#endif /* CONFIG_SYSCTL */
-+
-+/*
-+ * $Log$
-+ * Revision 1.3 2004-11-25 10:19:50 kergoth.com!kergoth
-+ * Turn off EOLN_NATIVE flag
-+ *
-+ * (Logical change 1.5010)
-+ *
-+ * Revision 1.16 2004/04/06 02:49:26 mcr
-+ * pullup of algo code from alg-branch.
-+ *
-+ * Revision 1.15 2002/04/24 07:55:32 mcr
-+ * #include patches and Makefiles for post-reorg compilation.
-+ *
-+ * Revision 1.14 2002/04/24 07:36:35 mcr
-+ * Moved from ./klips/net/ipsec/sysctl_net_ipsec.c,v
-+ *
-+ * Revision 1.13 2002/01/12 02:58:32 mcr
-+ * first regression test causes acquire messages to be lost
-+ * 100% of the time. This is to help testing of pluto.
-+ *
-+ * Revision 1.12 2001/06/14 19:35:13 rgb
-+ * Update copyright date.
-+ *
-+ * Revision 1.11 2001/02/26 19:58:13 rgb
-+ * Drop sysctl_ipsec_{no_eroute_pass,opportunistic}, replaced by magic SAs.
-+ *
-+ * Revision 1.10 2000/09/16 01:50:15 rgb
-+ * Protect sysctl_ipsec_debug_ipcomp with compiler defines too so that the
-+ * linker won't blame rj_delete() for missing symbols. ;-> Damn statics...
-+ *
-+ * Revision 1.9 2000/09/15 23:17:51 rgb
-+ * Moved stuff around to compile with debug off.
-+ *
-+ * Revision 1.8 2000/09/15 11:37:02 rgb
-+ * Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
-+ * IPCOMP zlib deflate code.
-+ *
-+ * Revision 1.7 2000/09/15 07:37:15 rgb
-+ * Munged silly log comment that was causing a warning.
-+ *
-+ * Revision 1.6 2000/09/15 04:58:23 rgb
-+ * Added tos runtime switch.
-+ * Removed 'sysctl_ipsec_' prefix from /proc/sys/net/ipsec/ filenames.
-+ *
-+ * Revision 1.5 2000/09/12 03:25:28 rgb
-+ * Filled in and implemented sysctl.
-+ *
-+ * Revision 1.4 1999/04/11 00:29:03 henry
-+ * GPL boilerplate
-+ *
-+ * Revision 1.3 1999/04/06 04:54:29 rgb
-+ * Fix/Add RCSID Id: and Log: bits to make PHMDs happy. This includes
-+ * patch shell fixes.
-+ *
-+ */
---- /dev/null Tue Mar 11 13:02:56 2003
-+++ linux/net/ipsec/version.c Mon Feb 9 13:51:03 2004
-@@ -0,0 +1,44 @@
-+/*
-+ * return IPsec version information
-+ * Copyright (C) 2001 Henry Spencer.
-+ *
-+ * This library is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU Library General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or (at your
-+ * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
-+ *
-+ * This library 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 Library General Public
-+ * License for more details.
-+ *
-+ * RCSID $Id$
-+ */
-+
-+#ifdef __KERNEL__
-+#include <linux/netdevice.h>
-+#endif
-+
-+#include "openswan.h"
-+
-+#define V "cvs2002Mar12_01:19:03" /* substituted in by Makefile */
-+static const char openswan_number[] = V;
-+static const char openswan_string[] = "Openswan " V;
-+
-+/*
-+ - ipsec_version_code - return IPsec version number/code, as string
-+ */
-+const char *
-+ipsec_version_code()
-+{
-+ return openswan_number;
-+}
-+
-+/*
-+ - ipsec_version_string - return full version string
-+ */
-+const char *
-+ipsec_version_string()
-+{
-+ return openswan_string;
-+}
-RCSID $Id$
---- ./net/ipv4/af_inet.c.preipsec Wed Apr 26 15:13:17 2000
-+++ ./net/ipv4/af_inet.c Fri Jun 30 15:01:27 2000
-@@ -1019,6 +1019,17 @@
- ip_mr_init();
- #endif
-
-+#if defined(CONFIG_IPSEC)
-+ {
-+ extern /* void */ int ipsec_init(void);
-+ /*
-+ * Initialise AF_INET ESP and AH protocol support including
-+ * e-routing and SA tables
-+ */
-+ ipsec_init();
-+ }
-+#endif /* CONFIG_IPSEC */
-+
- /*
- * Create all the /proc entries.
- */
---- /dev/null Fri May 10 13:59:54 2002
-+++ linux/net/ipsec/Makefile.ver Sun Jul 28 22:10:40 2002
-@@ -0,0 +1 @@
-+IPSECVERSION=cvs2002Mar12_01:19:03
-make[1]: Leaving directory `/data/mtx/oe/tmp/work/openswan-2.2.0-r0/openswan-2.2.0'
diff --git a/linux/linux-mtx-1-2.4.27/14-au1000-eth-link-beat.diff b/linux/linux-mtx-1-2.4.27/14-au1000-eth-link-beat.diff
deleted file mode 100644
index f848d2a224..0000000000
--- a/linux/linux-mtx-1-2.4.27/14-au1000-eth-link-beat.diff
+++ /dev/null
@@ -1,64 +0,0 @@
---- linux/drivers/net/au1000_eth.c.orig 2004-11-23 12:01:00.551663672 +0100
-+++ linux/drivers/net/au1000_eth.c 2004-11-23 12:08:36.795304096 +0100
-@@ -6,7 +6,9 @@
- * Copyright 2002 TimeSys Corp.
- * Author: MontaVista Software, Inc.
- * ppopov@mvista.com or source@mvista.com
-- *
-+ * Bjoern Riemer 2004
-+ * riemer@fokus.fraunhofer.de or riemer@riemer-nt.de
-+ * // fixed the link beat detection with ioctls (SIOCGMIIPHY)
- * ########################################################################
- *
- * This program is free software; you can distribute it and/or modify it
-@@ -1383,6 +1385,10 @@
- aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed);
- control = MAC_DISABLE_RX_OWN | MAC_RX_ENABLE | MAC_TX_ENABLE;
- #ifndef CONFIG_CPU_LITTLE_ENDIAN
-+ /*riemer: fix for startup without cable */
-+ if (!link)
-+ dev->flags &= ~IFF_RUNNING;
-+
- control |= MAC_BIG_ENDIAN;
- #endif
- if (link && (dev->if_port == IF_PORT_100BASEFX)) {
-@@ -1841,17 +1847,35 @@
-
- static int au1000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
- {
-- //u16 *data = (u16 *)&rq->ifr_data;
-+/*
-+// This structure is used in all SIOCxMIIxxx ioctl calls
-+struct mii_ioctl_data {
-+ 0 u16 phy_id;
-+ 1 u16 reg_num;
-+ 2 u16 val_in;
-+ 3 u16 val_out;
-+};*/
-+ u16 *data = (u16 *)&rq->ifr_data;
-+ struct au1000_private *aup = (struct au1000_private *) dev->priv;
-+ //struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
-
- /* fixme */
- switch(cmd) {
- case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */
-- //data[0] = PHY_ADDRESS;
-+ case SIOCGMIIPHY:
-+ if (!netif_running(dev))
-+ return -EINVAL;
-+ data[0] = aup->phy_addr;
- case SIOCDEVPRIVATE+1: /* Read the specified MII register. */
-- //data[3] = mdio_read(ioaddr, data[0], data[1]);
-+ case SIOCGMIIREG:
-+ data[3] = mdio_read(dev, data[0], data[1]);
-+ //data->val_out = mdio_read(dev,data->phy_id,data->reg_num);
- return 0;
- case SIOCDEVPRIVATE+2: /* Write the specified MII register */
-- //mdio_write(ioaddr, data[0], data[1], data[2]);
-+ case SIOCSMIIREG:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EPERM;
-+ mdio_write(dev, data[0], data[1],data[2]);
- return 0;
- default:
- return -EOPNOTSUPP;
diff --git a/linux/linux-mtx-1-2.4.27/15-au1000-pci-fixup-non-coherent-pre-ac.diff b/linux/linux-mtx-1-2.4.27/15-au1000-pci-fixup-non-coherent-pre-ac.diff
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-mtx-1-2.4.27/15-au1000-pci-fixup-non-coherent-pre-ac.diff
+++ /dev/null
diff --git a/linux/linux-mtx-1-2.4.27/defconfig-mtx-1 b/linux/linux-mtx-1-2.4.27/defconfig-mtx-1
deleted file mode 100644
index 0afef23a7b..0000000000
--- a/linux/linux-mtx-1-2.4.27/defconfig-mtx-1
+++ /dev/null
@@ -1,1200 +0,0 @@
-#
-# Automatically generated by make menuconfig: don't edit
-#
-CONFIG_MIPS=y
-CONFIG_MIPS32=y
-# CONFIG_MIPS64 is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# Machine selection
-#
-# CONFIG_ACER_PICA_61 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_DB1550 is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-# CONFIG_MIPS_HYDROGEN3 is not set
-# CONFIG_MIPS_PB1550 is not set
-# CONFIG_MIPS_XXS1500 is not set
-CONFIG_MIPS_MTX1=y
-# CONFIG_COGENT_CSB250 is not set
-# CONFIG_BAGET_MIPS is not set
-# CONFIG_CASIO_E55 is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_EV96100 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_HP_LASERJET is not set
-# CONFIG_IBM_WORKPAD is not set
-# CONFIG_LASAT is not set
-# CONFIG_MIPS_ITE8172 is not set
-# CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MAGNUM_4000 is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_SEAD is not set
-# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
-# CONFIG_MOMENCO_JAGUAR_ATX is not set
-# CONFIG_PMC_BIG_SUR is not set
-# CONFIG_PMC_STRETCH is not set
-# CONFIG_PMC_YOSEMITE is not set
-# CONFIG_DDB5074 is not set
-# CONFIG_DDB5476 is not set
-# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
-# CONFIG_NEC_EAGLE is not set
-# CONFIG_OLIVETTI_M700 is not set
-# CONFIG_NINO is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
-# CONFIG_SNI_RM200_PCI is not set
-# CONFIG_TANBAC_TB0226 is not set
-# CONFIG_TANBAC_TB0229 is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_VICTOR_MPC30X is not set
-# CONFIG_ZAO_CAPCELLA is not set
-# CONFIG_HIGHMEM is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_SOC_AU1X00=y
-CONFIG_SOC_AU1500=y
-CONFIG_NONCOHERENT_IO=y
-# CONFIG_MIPS_AU1000 is not set
-
-#
-# CPU selection
-#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 is not set
-# CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_VR41XX is not set
-# CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_TX49XX is not set
-# CONFIG_CPU_R5000 is not set
-# CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_R6000 is not set
-# CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_R10000 is not set
-# CONFIG_CPU_RM7000 is not set
-# CONFIG_CPU_RM9000 is not set
-# CONFIG_CPU_SB1 is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_64KB is not set
-CONFIG_CPU_HAS_PREFETCH=y
-# CONFIG_VTAG_ICACHE is not set
-CONFIG_64BIT_PHYS_ADDR=y
-# CONFIG_CPU_ADVANCED is not set
-CONFIG_CPU_HAS_LLSC=y
-# CONFIG_CPU_HAS_LLDSCD is not set
-# CONFIG_CPU_HAS_WB is not set
-CONFIG_CPU_HAS_SYNC=y
-
-#
-# General setup
-#
-CONFIG_CPU_LITTLE_ENDIAN=y
-# CONFIG_BUILD_ELF64 is not set
-CONFIG_NET=y
-CONFIG_PCI=y
-CONFIG_PCI_NEW=y
-CONFIG_PCI_AUTO=y
-CONFIG_PCI_NAMES=y
-# CONFIG_ISA is not set
-# CONFIG_TC is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-# CONFIG_PCMCIA is not set
-
-#
-# PCI Hotplug Support
-#
-# CONFIG_HOTPLUG_PCI is not set
-# CONFIG_HOTPLUG_PCI_COMPAQ is not set
-# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
-# CONFIG_HOTPLUG_PCI_SHPC is not set
-# CONFIG_HOTPLUG_PCI_SHPC_POLL_EVENT_MODE is not set
-# CONFIG_HOTPLUG_PCI_PCIE is not set
-# CONFIG_HOTPLUG_PCI_PCIE_POLL_EVENT_MODE is not set
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_MIPS32_COMPAT is not set
-# CONFIG_MIPS32_O32 is not set
-# CONFIG_MIPS32_N32 is not set
-# CONFIG_BINFMT_ELF32 is not set
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_OOM_KILLER is not set
-# CONFIG_CMDLINE_BOOL is not set
-# CONFIG_PM is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_AMDSTD_RETRY=y
-CONFIG_MTD_CFI_AMDSTD_RETRY_MAX=5
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_DB1X00 is not set
-CONFIG_MTD_MTX1=y
-# CONFIG_MTD_CSTM_MIPS_IXX is not set
-# CONFIG_MTD_OCELOT is not set
-# CONFIG_MTD_LASAT is not set
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PCMCIA is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
-# CONFIG_CISS_MONITOR_THREAD is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_SX8 is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=m
-CONFIG_BLK_DEV_RAM_SIZE=4096
-# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_BLK_STATS is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=m
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_FWMARK=y
-CONFIG_IP_ROUTE_NAT=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_TOS=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-CONFIG_SYN_COOKIES=y
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_UNCLEAN=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_MIRROR=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_NAT_AMANDA=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-
-#
-# IP: Virtual Server Configuration
-#
-# CONFIG_IP_VS is not set
-CONFIG_IPV6=m
-
-#
-# IPv6: Netfilter Configuration
-#
-CONFIG_IP6_NF_QUEUE=m
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_MATCH_OPTS=m
-CONFIG_IP6_NF_MATCH_FRAG=m
-CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
-CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_AHESP=m
-CONFIG_IP6_NF_MATCH_LENGTH=m
-CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
-# CONFIG_KHTTPD is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-CONFIG_VLAN_8021Q=m
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_DEV_APPLETALK is not set
-# CONFIG_DECNET is not set
-CONFIG_BRIDGE=m
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_CSZ=m
-# CONFIG_NET_SCH_HFSC is not set
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-# CONFIG_NET_SCH_NETEM is not set
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_QOS=y
-CONFIG_NET_ESTIMATOR=y
-CONFIG_NET_CLS=y
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_ROUTE=y
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-CONFIG_NET_CLS_POLICE=y
-
-#
-# Network testing
-#
-CONFIG_NET_PKTGEN=m
-CONFIG_IPSEC_NAT_TRAVERSAL=y
-CONFIG_IPSEC=m
-CONFIG_IPSEC_IPIP=y
-CONFIG_IPSEC_AH=y
-CONFIG_IPSEC_AUTH_HMAC_MD5=y
-CONFIG_IPSEC_AUTH_HMAC_SHA1=y
-CONFIG_IPSEC_ESP=y
-CONFIG_IPSEC_ENC_3DES=y
-CONFIG_IPSEC_ENC_AES=y
-CONFIG_IPSEC_ALG=y
-CONFIG_IPSEC_ALG_AES=m
-CONFIG_IPSEC_ALG_CRYPTOAPI=m
-CONFIG_IPSEC_ALG_NON_LIBRE=y
-CONFIG_IPSEC_IPCOMP=y
-CONFIG_IPSEC_DEBUG=y
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-# CONFIG_PHONE_IXJ is not set
-# CONFIG_PHONE_IXJ_PCMCIA is not set
-
-#
-# ATA/IDE/MFM/RLL support
-#
-# CONFIG_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
-CONFIG_SD_EXTRA_DEVS=40
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_SR_EXTRA_DEVS=2
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_SCSI_DEBUG_QUEUES is not set
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_MEGARAID2 is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_SATA_SVW is not set
-# CONFIG_SCSI_SATA_PROMISE is not set
-# CONFIG_SCSI_SATA_SX4 is not set
-# CONFIG_SCSI_SATA_SIL is not set
-# CONFIG_SCSI_SATA_SIS is not set
-# CONFIG_SCSI_SATA_VIA is not set
-# CONFIG_SCSI_SATA_VITESSE is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_NCR53C8XX is not set
-# CONFIG_SCSI_SYM53C8XX is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_SIM710 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-# CONFIG_FUSION_BOOT is not set
-# CONFIG_FUSION_ISENSE is not set
-# CONFIG_FUSION_CTL is not set
-# CONFIG_FUSION_LAN is not set
-
-#
-# IEEE 1394 (FireWire) support (EXPERIMENTAL)
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_PCI is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-CONFIG_DUMMY=m
-CONFIG_BONDING=m
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MIPS_AU1X00_ENET=y
-# CONFIG_BCM5222_DUAL_PHY is not set
-# CONFIG_SUNLANCE is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNBMAC is not set
-# CONFIG_SUNQE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPPOE=m
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_STRIP is not set
-# CONFIG_WAVELAN is not set
-# CONFIG_ARLAN is not set
-CONFIG_AIRONET4500=m
-CONFIG_AIRONET4500_NONCS=m
-# CONFIG_AIRONET4500_PNP is not set
-CONFIG_AIRONET4500_PCI=y
-# CONFIG_AIRONET4500_ISA is not set
-# CONFIG_AIRONET4500_I365 is not set
-CONFIG_AIRONET4500_PROC=m
-CONFIG_AIRO=m
-# CONFIG_HERMES is not set
-# CONFIG_PLX_HERMES is not set
-# CONFIG_TMD_HERMES is not set
-# CONFIG_PCI_HERMES is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-CONFIG_SHAPER=m
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_UINPUT is not set
-
-#
-# Character devices
-#
-# CONFIG_VT is not set
-# CONFIG_SERIAL is not set
-# CONFIG_SERIAL_EXTENDED is not set
-CONFIG_SERIAL_NONSTANDARD=y
-# CONFIG_COMPUTONE is not set
-# CONFIG_ROCKETPORT is not set
-# CONFIG_CYCLADES is not set
-# CONFIG_DIGIEPCA is not set
-# CONFIG_DIGI is not set
-# CONFIG_ESPSERIAL is not set
-# CONFIG_MOXA_INTELLIO is not set
-# CONFIG_MOXA_SMARTIO is not set
-# CONFIG_ISI is not set
-# CONFIG_SYNCLINK is not set
-# CONFIG_SYNCLINKMP is not set
-# CONFIG_N_HDLC is not set
-# CONFIG_RISCOM8 is not set
-# CONFIG_SPECIALIX is not set
-# CONFIG_SX is not set
-# CONFIG_RIO is not set
-# CONFIG_STALDRV is not set
-# CONFIG_SERIAL_TX3912 is not set
-# CONFIG_SERIAL_TX3912_CONSOLE is not set
-# CONFIG_SERIAL_TXX9 is not set
-# CONFIG_SERIAL_TXX9_CONSOLE is not set
-CONFIG_AU1X00_UART=y
-CONFIG_AU1X00_SERIAL_CONSOLE=y
-# CONFIG_AU1X00_USB_TTY is not set
-# CONFIG_AU1X00_USB_RAW is not set
-# CONFIG_TXX927_SERIAL is not set
-# CONFIG_MIPS_HYDROGEN3_BUTTONS is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_IPMI_PANIC_EVENT is not set
-# CONFIG_IPMI_DEVICE_INTERFACE is not set
-# CONFIG_IPMI_KCS is not set
-# CONFIG_IPMI_WATCHDOG is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_SCx200 is not set
-# CONFIG_SCx200_GPIO is not set
-# CONFIG_AMD_PM768 is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-
-#
-# Direct Rendering Manager (XFree86 DRI support)
-#
-# CONFIG_DRM is not set
-CONFIG_AU1X00_GPIO=m
-# CONFIG_TS_AU1X00_ADS7846 is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_QFMT_V2 is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BEFS_DEBUG is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=m
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=m
-CONFIG_MSDOS_FS=m
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=m
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_CRAMFS is not set
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-# CONFIG_JFS_FS is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-CONFIG_NTFS_FS=m
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=m
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_TRACE is not set
-# CONFIG_XFS_DEBUG is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_TCP is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_SMB_UNIX is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-CONFIG_ZISOFS_FS=m
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-15"
-CONFIG_NLS_CODEPAGE_437=m
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-CONFIG_NLS_CODEPAGE_850=m
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ISO8859_1=m
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-CONFIG_NLS_ISO8859_15=m
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-CONFIG_NLS_UTF8=m
-
-#
-# Multimedia devices
-#
-CONFIG_VIDEO_DEV=m
-
-#
-# Video For Linux
-#
-CONFIG_VIDEO_PROC_FS=y
-# CONFIG_I2C_PARPORT is not set
-# CONFIG_VIDEO_BT848 is not set
-# CONFIG_VIDEO_PMS is not set
-CONFIG_VIDEO_CPIA=m
-# CONFIG_VIDEO_CPIA_PP is not set
-CONFIG_VIDEO_CPIA_USB=m
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIDEO_ZORAN_BUZ is not set
-# CONFIG_VIDEO_ZORAN_DC10 is not set
-# CONFIG_VIDEO_ZORAN_LML33 is not set
-# CONFIG_VIDEO_ZR36120 is not set
-# CONFIG_VIDEO_MEYE is not set
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_GEMTEK_PCI is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_MAESTRO is not set
-# CONFIG_RADIO_MIROPCM20 is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=m
-# CONFIG_SOUND_ALI5455 is not set
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_FORTE is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_AU1X00 is not set
-# CONFIG_SOUND_AU1550_PSC is not set
-# CONFIG_SOUND_AU1550_I2S is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-CONFIG_SOUND_OSS=m
-# CONFIG_SOUND_TRACEINIT is not set
-# CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_AD1889 is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_ADLIB is not set
-# CONFIG_SOUND_ACI_MIXER is not set
-# CONFIG_SOUND_CS4232 is not set
-# CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_VMIDI is not set
-# CONFIG_SOUND_TRIX is not set
-# CONFIG_SOUND_MSS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_NM256 is not set
-# CONFIG_SOUND_MAD16 is not set
-# CONFIG_SOUND_PAS is not set
-# CONFIG_PAS_JOYSTICK is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_SB is not set
-# CONFIG_SOUND_AWE32_SYNTH is not set
-# CONFIG_SOUND_KAHLUA is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_OPL3SA2 is not set
-# CONFIG_SOUND_YMFPCI is not set
-# CONFIG_SOUND_YMFPCI_LEGACY is not set
-# CONFIG_SOUND_UART6850 is not set
-# CONFIG_SOUND_AEDSP16 is not set
-# CONFIG_SOUND_TVMIXER is not set
-# CONFIG_SOUND_AD1980 is not set
-# CONFIG_SOUND_WM97XX is not set
-
-#
-# USB support
-#
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-CONFIG_USB_OHCI=y
-CONFIG_USB_NON_PCI_OHCI=y
-CONFIG_USB_AUDIO=m
-CONFIG_USB_EMI26=m
-CONFIG_USB_MIDI=m
-CONFIG_USB_STORAGE=m
-CONFIG_USB_STORAGE_DEBUG=y
-CONFIG_USB_STORAGE_DATAFAB=y
-CONFIG_USB_STORAGE_FREECOM=y
-# CONFIG_USB_STORAGE_ISD200 is not set
-CONFIG_USB_STORAGE_DPCM=y
-CONFIG_USB_STORAGE_HP8200e=y
-CONFIG_USB_STORAGE_SDDR09=y
-CONFIG_USB_STORAGE_SDDR55=y
-CONFIG_USB_STORAGE_JUMPSHOT=y
-CONFIG_USB_ACM=m
-CONFIG_USB_PRINTER=m
-# CONFIG_USB_HID is not set
-# CONFIG_USB_HIDINPUT is not set
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-CONFIG_USB_DC2XX=m
-CONFIG_USB_MDC800=m
-CONFIG_USB_SCANNER=m
-CONFIG_USB_MICROTEK=m
-CONFIG_USB_HPUSBSCSI=m
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_KONICAWC=m
-CONFIG_USB_OV511=m
-CONFIG_USB_PWC=m
-CONFIG_USB_SE401=m
-CONFIG_USB_STV680=m
-# CONFIG_USB_W9968CF is not set
-CONFIG_USB_VICAM=m
-CONFIG_USB_DSBR=m
-CONFIG_USB_DABUSB=m
-CONFIG_USB_PEGASUS=m
-CONFIG_USB_RTL8150=m
-CONFIG_USB_KAWETH=m
-CONFIG_USB_CATC=m
-CONFIG_USB_CDCETHER=m
-CONFIG_USB_USBNET=m
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-CONFIG_USB_SERIAL=m
-# CONFIG_USB_SERIAL_DEBUG is not set
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_BELKIN=m
-CONFIG_USB_SERIAL_WHITEHEAT=m
-CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
-CONFIG_USB_SERIAL_EMPEG=m
-CONFIG_USB_SERIAL_FTDI_SIO=m
-CONFIG_USB_SERIAL_VISOR=m
-CONFIG_USB_SERIAL_IPAQ=m
-CONFIG_USB_SERIAL_IR=m
-CONFIG_USB_SERIAL_EDGEPORT=m
-CONFIG_USB_SERIAL_EDGEPORT_TI=m
-CONFIG_USB_SERIAL_KEYSPAN_PDA=m
-CONFIG_USB_SERIAL_KEYSPAN=m
-CONFIG_USB_SERIAL_KEYSPAN_USA28=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19=y
-CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
-CONFIG_USB_SERIAL_KEYSPAN_MPR=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
-CONFIG_USB_SERIAL_MCT_U232=m
-CONFIG_USB_SERIAL_KLSI=m
-CONFIG_USB_SERIAL_KOBIL_SCT=m
-CONFIG_USB_SERIAL_PL2303=m
-CONFIG_USB_SERIAL_CYBERJACK=m
-CONFIG_USB_SERIAL_XIRCOM=m
-CONFIG_USB_SERIAL_OMNINET=m
-CONFIG_USB_RIO500=m
-CONFIG_USB_AUERSWALD=m
-CONFIG_USB_TIGL=m
-CONFIG_USB_BRLVGER=m
-CONFIG_USB_LCD=m
-
-#
-# Support for USB gadgets
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# Bluetooth support
-#
-CONFIG_BLUEZ=m
-CONFIG_BLUEZ_L2CAP=m
-CONFIG_BLUEZ_SCO=m
-CONFIG_BLUEZ_RFCOMM=m
-CONFIG_BLUEZ_RFCOMM_TTY=y
-CONFIG_BLUEZ_BNEP=m
-CONFIG_BLUEZ_BNEP_MC_FILTER=y
-CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
-
-#
-# Bluetooth device drivers
-#
-CONFIG_BLUEZ_HCIUSB=m
-CONFIG_BLUEZ_HCIUSB_SCO=y
-CONFIG_BLUEZ_HCIUART=m
-CONFIG_BLUEZ_HCIUART_H4=y
-CONFIG_BLUEZ_HCIUART_BCSP=y
-CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y
-CONFIG_BLUEZ_HCIBFUSB=m
-# CONFIG_BLUEZ_HCIDTL1 is not set
-# CONFIG_BLUEZ_HCIBT3C is not set
-# CONFIG_BLUEZ_HCIBLUECARD is not set
-# CONFIG_BLUEZ_HCIBTUART is not set
-CONFIG_BLUEZ_HCIVHCI=m
-
-#
-# Kernel hacking
-#
-CONFIG_CROSSCOMPILE=y
-# CONFIG_RUNTIME_DEBUG is not set
-# CONFIG_KGDB is not set
-# CONFIG_GDB_CONSOLE is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_MIPS_UNCACHED is not set
-CONFIG_LOG_BUF_SHIFT=0
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=m
-CONFIG_CRYPTO_MD5=m
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_DES=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_DEFLATE=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_TEST=m
-
-#
-# Library routines
-#
-CONFIG_CRC32=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_FW_LOADER=m
diff --git a/linux/linux-mtx-1-2.4.27/mtx-1-board-reset.diff b/linux/linux-mtx-1-2.4.27/mtx-1-board-reset.diff
deleted file mode 100644
index 9a13c2a403..0000000000
--- a/linux/linux-mtx-1-2.4.27/mtx-1-board-reset.diff
+++ /dev/null
@@ -1,15 +0,0 @@
---- linux/arch/mips/au1000/mtx-1/board_setup.c.orig 2004-10-13 19:05:15.340583632 +0200
-+++ linux/arch/mips/au1000/mtx-1/board_setup.c 2004-10-13 19:01:03.402883984 +0200
-@@ -48,6 +48,12 @@
-
- extern struct rtc_ops no_rtc_ops;
-
-+void board_reset (void)
-+{
-+ /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
-+ au_writel(0x00000000, 0xAE00001C);
-+}
-+
- void __init board_setup(void)
- {
- rtc_ops = &no_rtc_ops;
diff --git a/linux/linux-mtx-1-2.4.27/zimage-flash-bin.patch b/linux/linux-mtx-1-2.4.27/zimage-flash-bin.patch
deleted file mode 100644
index dca79a3000..0000000000
--- a/linux/linux-mtx-1-2.4.27/zimage-flash-bin.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-diff -Nurb oe/tmp/work/linux-mtx-1-2.4.27-r0/linux/arch/mips/zboot/pb1xxx/Makefile linux.m/arch/mips/zboot/pb1xxx/Makefile
---- oe/tmp/work/linux-mtx-1-2.4.27-r0/linux/arch/mips/zboot/pb1xxx/Makefile 2004-10-13 21:08:49.840408328 +0200
-+++ linux.m/arch/mips/zboot/pb1xxx/Makefile 2004-10-13 21:08:29.736464592 +0200
-@@ -131,5 +131,7 @@
- zImage.flash: zImage
- $(OBJCOPY) -O srec --adjust-vma 0x3ed00000 \
- ../images/zImage.$(BNAME) ../images/$(BNAME).flash.srec
-+ $(OBJCOPY) -O binary --adjust-vma 0x3ed00000 \
-+ ../images/zImage.$(BNAME) ../images/$(BNAME).flash.bin
-
- include $(TOPDIR)/Rules.make
diff --git a/linux/linux-mtx-1_2.4.24.bb b/linux/linux-mtx-1_2.4.24.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-mtx-1_2.4.24.bb
+++ /dev/null
diff --git a/linux/linux-mtx-1_2.4.27.bb b/linux/linux-mtx-1_2.4.27.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-mtx-1_2.4.27.bb
+++ /dev/null
diff --git a/linux/linux-netvista-2.4.27/netvista_defconfig b/linux/linux-netvista-2.4.27/netvista_defconfig
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-netvista-2.4.27/netvista_defconfig
+++ /dev/null
diff --git a/linux/linux-netvista_2.4.27.bb b/linux/linux-netvista_2.4.27.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-netvista_2.4.27.bb
+++ /dev/null
diff --git a/linux/linux-omap-2.6-2.6.9-omap1/omap1610h2/defconfig b/linux/linux-omap-2.6-2.6.9-omap1/omap1610h2/defconfig
deleted file mode 100644
index 8b4d7f27ce..0000000000
--- a/linux/linux-omap-2.6-2.6.9-omap1/omap1610h2/defconfig
+++ /dev/null
@@ -1,840 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.9-rc4-omap1
-# Thu Oct 14 16:30:44 2004
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_IOMAP=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-CONFIG_SHMEM=y
-# CONFIG_TINY_SHMEM is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_KMOD is not set
-
-#
-# System Type
-#
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-CONFIG_ARCH_OMAP=y
-# CONFIG_ARCH_VERSATILE_PB is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
-
-#
-# TI OMAP Implementations
-#
-
-#
-# OMAP Core Type
-#
-# CONFIG_ARCH_OMAP730 is not set
-# CONFIG_ARCH_OMAP1510 is not set
-CONFIG_ARCH_OMAP16XX=y
-CONFIG_ARCH_OMAP_OTG=y
-
-#
-# OMAP Board Type
-#
-# CONFIG_MACH_OMAP_INNOVATOR is not set
-CONFIG_MACH_OMAP_H2=y
-# CONFIG_MACH_OMAP_H3 is not set
-# CONFIG_MACH_OMAP_H4 is not set
-# CONFIG_MACH_OMAP_OSK is not set
-# CONFIG_MACH_OMAP_GENERIC is not set
-
-#
-# OMAP Feature Selections
-#
-# CONFIG_OMAP_BOOT_TAG is not set
-CONFIG_OMAP_MUX=y
-# CONFIG_OMAP_MUX_DEBUG is not set
-CONFIG_OMAP_MUX_WARNINGS=y
-CONFIG_OMAP_LL_DEBUG_UART1=y
-# CONFIG_OMAP_LL_DEBUG_UART2 is not set
-# CONFIG_OMAP_LL_DEBUG_UART3 is not set
-CONFIG_OMAP_ARM_192MHZ=y
-# CONFIG_OMAP_ARM_168MHZ is not set
-# CONFIG_OMAP_ARM_120MHZ is not set
-# CONFIG_OMAP_ARM_60MHZ is not set
-# CONFIG_OMAP_ARM_30MHZ is not set
-# CONFIG_OMAP_DSP is not set
-
-#
-# h720x Implementations
-#
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_ARM926T=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5TJ=y
-CONFIG_CPU_COPY_V4WB=y
-CONFIG_CPU_TLB_V4WBI=y
-
-#
-# Processor Features
-#
-CONFIG_ARM_THUMB=y
-# CONFIG_CPU_ICACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
-
-#
-# General setup
-#
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0x10C08000
-CONFIG_ZBOOT_ROM_BSS=0x10200000
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-# CONFIG_VFP is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=y
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_DEBUG_DRIVER is not set
-# CONFIG_PM is not set
-CONFIG_PREEMPT=y
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="mem=32M console=ttyS0,115200n8 initrd=0x10A00000,8M root=/dev/ram0 rw ip=dhcp devfs=mount"
-# CONFIG_LEDS is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_UB is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_NET_VENDOR_SMC=y
-CONFIG_SMC91X=y
-# CONFIG_SMC9194 is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-CONFIG_PPP=y
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-# CONFIG_PPP_ASYNC is not set
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-# CONFIG_PPP_BSDCOMP is not set
-# CONFIG_PPPOE is not set
-CONFIG_SLIP=y
-CONFIG_SLIP_COMPRESSED=y
-# CONFIG_SLIP_SMART is not set
-# CONFIG_SLIP_MODE_SLIP6 is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-CONFIG_SERIO_SERPORT=y
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-# CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_KEYBOARD_OMAP=y
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=4
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_8250_OMAP=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS is not set
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-
-#
-# USB-based Watchdog Cards
-#
-# CONFIG_USBPCWATCHDOG is not set
-# CONFIG_OMAP16XX_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_OMAP_RTC=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# I2C support
-#
-CONFIG_I2C=y
-# CONFIG_I2C_CHARDEV is not set
-
-#
-# I2C Algorithms
-#
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_ISA is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_SCx200_ACB is not set
-# CONFIG_I2C_PCA_ISA is not set
-CONFIG_I2C_OMAP=y
-
-#
-# Hardware Sensors Chip support
-#
-# CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-
-#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-CONFIG_ISP1301_OMAP=m
-CONFIG_TPS65010=y
-# CONFIG_SENSORS_TLV320AIC23 is not set
-CONFIG_GPIOEXPANDER_OMAP=y
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# Multimedia devices
-#
-CONFIG_VIDEO_DEV=y
-
-#
-# Video For Linux
-#
-
-#
-# Video Adapters
-#
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_VIDEO_SAA5246A is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_OVCAMCHIP is not set
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_MAESTRO is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-# CONFIG_EXT2_FS_POSIX_ACL is not set
-# CONFIG_EXT2_FS_SECURITY is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=y
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_SYSFS=y
-CONFIG_DEVFS_FS=y
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
-CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Profiling support
-#
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
-
-#
-# Graphics support
-#
-CONFIG_FB=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_OMAP=y
-CONFIG_FB_OMAP_INTERNAL_LCDC=y
-# CONFIG_FB_OMAP_EXTERNAL_LCDC is not set
-# CONFIG_FB_OMAP_DMA_TUNE is not set
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-# CONFIG_FONTS is not set
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-
-#
-# Logo configuration
-#
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_LOGO_LINUX_CLUT224=y
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-
-#
-# Advanced Linux Sound Architecture
-#
-# CONFIG_SND is not set
-
-#
-# Open Sound System
-#
-CONFIG_SOUND_PRIME=y
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_TVMIXER is not set
-# CONFIG_SOUND_AD1980 is not set
-
-#
-# Misc devices
-#
-
-#
-# USB support
-#
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_OTG is not set
-
-#
-# USB Host Controller Drivers
-#
-# CONFIG_USB_EHCI_HCD is not set
-CONFIG_USB_OHCI_HCD=m
-# CONFIG_USB_UHCI_HCD is not set
-# CONFIG_USB_SL811HS is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_BLUETOOTH_TTY is not set
-# CONFIG_USB_MIDI is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_STORAGE is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-# CONFIG_USB_HID is not set
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_EGALAX is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_VICAM is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_KONICAWC is not set
-# CONFIG_USB_OV511 is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_SN9C102 is not set
-# CONFIG_USB_STV680 is not set
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_TIGL is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETSERVO is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# Synchronous Serial Interfaces (SSI)
-#
-CONFIG_OMAP_UWIRE=y
-
-#
-# MMC/SD Card support
-#
-# CONFIG_MMC is not set
-
-#
-# Kernel hacking
-#
-CONFIG_DEBUG_KERNEL=y
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_INFO=y
-CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_USER=y
-# CONFIG_DEBUG_WAITQ is not set
-CONFIG_DEBUG_ERRORS=y
-CONFIG_SCHEDSTATS=y
-CONFIG_DEBUG_LL=y
-# CONFIG_DEBUG_ICEDCC is not set
-
-#
-# Security options
-#
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Library routines
-#
-CONFIG_CRC_CCITT=y
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
diff --git a/linux/linux-omap-2.6-2.6.9-omap1/schedstats-arm.patch b/linux/linux-omap-2.6-2.6.9-omap1/schedstats-arm.patch
deleted file mode 100644
index f5823a9943..0000000000
--- a/linux/linux-omap-2.6-2.6.9-omap1/schedstats-arm.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- linux-2.6.9-rc4/arch/arm/Kconfig.debug~schedstats-arm
-+++ linux-2.6.9-rc4/arch/arm/Kconfig.debug
-@@ -57,6 +57,18 @@
- time and disk space needed for compilation of the kernel. If in
- doubt say N.
-
-+config SCHEDSTATS
-+ bool "Collect scheduler statistics"
-+ depends on DEBUG_KERNEL && PROC_FS
-+ help
-+ If you say Y here, additional code will be inserted into the
-+ scheduler and related routines to collect statistics about
-+ scheduler behavior and provide them in /proc/schedstat. These
-+ stats may be useful for both tuning and debugging the scheduler
-+ If you aren't debugging the scheduler or trying to tune a specific
-+ application, you can say N to avoid the very slight overhead
-+ this adds.
-+
- # These options are only for real kernel hackers who want to get their hands dirty.
- config DEBUG_LL
- bool "Kernel low-level debugging functions"
diff --git a/linux/linux-omap-2.6_2.6.9-omap1.bb b/linux/linux-omap-2.6_2.6.9-omap1.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-omap-2.6_2.6.9-omap1.bb
+++ /dev/null
diff --git a/linux/linux-sun4cdm-2.4.26/defconfig b/linux/linux-sun4cdm-2.4.26/defconfig
deleted file mode 100644
index 8704f6307e..0000000000
--- a/linux/linux-sun4cdm-2.4.26/defconfig
+++ /dev/null
@@ -1,473 +0,0 @@
-#
-# Automatically generated by make menuconfig: don't edit
-#
-CONFIG_UID16=y
-CONFIG_HIGHMEM=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# General setup
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-# CONFIG_SMP is not set
-CONFIG_SPARC32=y
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-# CONFIG_MCA is not set
-# CONFIG_PCMCIA is not set
-CONFIG_SBUS=y
-CONFIG_SBUSCHAR=y
-CONFIG_BUSMOUSE=y
-CONFIG_SUN_MOUSE=y
-CONFIG_SERIAL=y
-CONFIG_SUN_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
-CONFIG_SUN_KEYBOARD=y
-CONFIG_SUN_CONSOLE=y
-CONFIG_SUN_AUXIO=y
-CONFIG_SUN_IO=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_SUN_PM=y
-# CONFIG_SUN4 is not set
-CONFIG_PCI=y
-# CONFIG_PCI_NAMES is not set
-CONFIG_SUN_OPENPROMFS=m
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-CONFIG_KCORE_ELF=y
-CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_MISC=m
-CONFIG_SUNOS_EMUL=y
-# CONFIG_OOM_KILLER is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-# CONFIG_PRINTER is not set
-
-#
-# Console drivers
-#
-# CONFIG_PROM_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_CLGEN is not set
-# CONFIG_FB_PM2 is not set
-# CONFIG_FB_PM3 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_MATROX is not set
-# CONFIG_FB_ATY is not set
-# CONFIG_FB_RADEON is not set
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_INTEL is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_NEOMAGIC is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_TRIDENT is not set
-CONFIG_FB_SBUS=y
-# CONFIG_FB_CGSIX is not set
-CONFIG_FB_BWTWO=y
-CONFIG_FB_CGTHREE=y
-# CONFIG_FB_TCX is not set
-# CONFIG_FB_CGFOURTEEN is not set
-# CONFIG_FB_P9100 is not set
-# CONFIG_FB_LEO is not set
-# CONFIG_FB_PCI is not set
-# CONFIG_FB_IT8181 is not set
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FBCON_ADVANCED is not set
-CONFIG_FBCON_MFB=y
-CONFIG_FBCON_CFB8=y
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FONT_SUN8x16=y
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FBCON_FONTS is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Misc Linux/SPARC drivers
-#
-CONFIG_SUN_OPENPROMIO=m
-CONFIG_SUN_MOSTEK_RTC=m
-# CONFIG_SUN_BPP is not set
-# CONFIG_SUN_VIDEOPIX is not set
-# CONFIG_SUN_AURORA is not set
-# CONFIG_TADPOLE_TS102_UCTRL is not set
-# CONFIG_SUN_JSFLASH is not set
-CONFIG_APM_RTC_IS_GMT=y
-CONFIG_RTC=y
-
-#
-# Linux/SPARC audio subsystem (EXPERIMENTAL)
-#
-# CONFIG_SPARCAUDIO is not set
-# CONFIG_SPARCAUDIO_AMD7930 is not set
-# CONFIG_SPARCAUDIO_DBRI is not set
-# CONFIG_SPARCAUDIO_CS4231 is not set
-# CONFIG_SPARCAUDIO_DUMMY is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-CONFIG_BLK_DEV_LOOP=m
-# CONFIG_BLK_DEV_NBD is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-# CONFIG_NETFILTER is not set
-# CONFIG_FILTER is not set
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-CONFIG_IPV6=y
-# CONFIG_KHTTPD is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-CONFIG_IP_SCTP=m
-# CONFIG_SCTP_DBG_MSG is not set
-CONFIG_SCTP_DBG_OBJCNT=y
-# CONFIG_SCTP_HMAC_NONE is not set
-# CONFIG_SCTP_HMAC_SHA1 is not set
-CONFIG_SCTP_HMAC_MD5=y
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_DEV_APPLETALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-CONFIG_NET_PKTGEN=m
-
-#
-# ATA/IDE/MFM/RLL support
-#
-# CONFIG_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SD_EXTRA_DEVS=40
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_SR_EXTRA_DEVS=2
-CONFIG_CHR_DEV_SG=m
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-CONFIG_SCSI_SUNESP=y
-CONFIG_SCSI_QLOGICPTI=m
-
-#
-# Fibre Channel support
-#
-# CONFIG_FC4 is not set
-# CONFIG_FC4_SOC is not set
-# CONFIG_FC4_SOCAL is not set
-# CONFIG_SCSI_PLUTO is not set
-# CONFIG_SCSI_FCAL is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
-# CONFIG_BONDING is not set
-CONFIG_TUN=m
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-CONFIG_SUNLANCE=y
-CONFIG_HAPPYMEAL=m
-CONFIG_SUNBMAC=m
-CONFIG_SUNQE=m
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_VORTEX is not set
-
-#
-# Unix98 PTY support
-#
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_QFMT_V2 is not set
-CONFIG_AUTOFS_FS=m
-CONFIG_AUTOFS4_FS=m
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-CONFIG_BEFS_FS=m
-# CONFIG_BEFS_DEBUG is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_JBD_DEBUG is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-# CONFIG_JFFS2_FS is not set
-CONFIG_CRAMFS=y
-# CONFIG_TMPFS is not set
-CONFIG_RAMFS=y
-CONFIG_ISO9660_FS=m
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-CONFIG_ROMFS_FS=m
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-CONFIG_XFS_FS=m
-CONFIG_XFS_QUOTA=y
-CONFIG_XFS_RT=y
-# CONFIG_XFS_TRACE is not set
-# CONFIG_XFS_DEBUG is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_ROOT_NFS=y
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-# CONFIG_SMB_FS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_SUN_PARTITION=y
-# CONFIG_SMB_NLS is not set
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BLUEZ is not set
-
-#
-# Watchdog
-#
-# CONFIG_SOFT_WATCHDOG is not set
-
-#
-# Kernel hacking
-#
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_HIGHMEM is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_IOVIRT is not set
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
-CONFIG_LOG_BUF_SHIFT=14
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_ARC4=m
-CONFIG_CRYPTO_DEFLATE=y
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Library routines
-#
-CONFIG_CRC32=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/linux-sun4cdm-2.6.8.1/sun4c_defconfig b/linux/linux-sun4cdm-2.6.8.1/sun4c_defconfig
deleted file mode 100644
index 49b84791ae..0000000000
--- a/linux/linux-sun4cdm-2.6.8.1/sun4c_defconfig
+++ /dev/null
@@ -1,689 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_HIGHMEM=y
-CONFIG_GENERIC_ISA_DMA=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_HOTPLUG is not set
-# CONFIG_IKCONFIG is not set
-# CONFIG_EMBEDDED is not set
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# General setup
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-CONFIG_SPARC32=y
-CONFIG_SBUS=y
-CONFIG_SBUSCHAR=y
-CONFIG_SERIAL_CONSOLE=y
-CONFIG_SUN_AUXIO=y
-CONFIG_SUN_IO=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_SUN_PM=y
-# CONFIG_SUN4 is not set
-CONFIG_PCI=y
-# CONFIG_PCI_LEGACY_PROC is not set
-# CONFIG_PCI_NAMES is not set
-CONFIG_SUN_OPENPROMFS=m
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_MISC=m
-CONFIG_SUNOS_EMUL=y
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_DEBUG_DRIVER is not set
-
-#
-# Graphics support
-#
-CONFIG_FB=y
-# CONFIG_FB_CIRRUS is not set
-# CONFIG_FB_PM2 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_ASILIANT is not set
-# CONFIG_FB_IMSTT is not set
-CONFIG_FB_BW2=y
-CONFIG_FB_CG3=y
-CONFIG_FB_CG6=y
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
-# CONFIG_FB_RADEON is not set
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_ATY is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_NEOMAGIC is not set
-# CONFIG_FB_KYRO is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_TRIDENT is not set
-CONFIG_FB_SBUS=y
-# CONFIG_FB_TCX is not set
-# CONFIG_FB_CG14 is not set
-# CONFIG_FB_P9100 is not set
-# CONFIG_FB_LEO is not set
-# CONFIG_FB_PCI is not set
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-# CONFIG_MDA_CONSOLE is not set
-# CONFIG_PROM_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-# CONFIG_FONTS is not set
-CONFIG_FONT_SUN8x16=y
-# CONFIG_FONT_SUN12x22 is not set
-
-#
-# Logo configuration
-#
-# CONFIG_LOGO is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-# CONFIG_MTD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_SUNCORE=y
-CONFIG_SERIAL_SUNZILOG=y
-CONFIG_SERIAL_SUNZILOG_CONSOLE=y
-CONFIG_SERIAL_SUNSU=y
-CONFIG_SERIAL_SUNSU_CONSOLE=y
-# CONFIG_SERIAL_SUNSAB is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-
-#
-# Misc Linux/SPARC drivers
-#
-CONFIG_SUN_OPENPROMIO=m
-CONFIG_SUN_MOSTEK_RTC=m
-# CONFIG_SUN_BPP is not set
-# CONFIG_SUN_VIDEOPIX is not set
-# CONFIG_TADPOLE_TS102_UCTRL is not set
-# CONFIG_SUN_JSFLASH is not set
-CONFIG_APM_RTC_IS_GMT=y
-CONFIG_RTC=m
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_SX8 is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=y
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_CHR_DEV_SG=m
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI Transport Attributes
-#
-CONFIG_SCSI_SPI_ATTRS=m
-# CONFIG_SCSI_FC_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLOGICPTI=m
-CONFIG_SCSI_QLA2XXX=y
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-CONFIG_SCSI_SUNESP=y
-
-#
-# Fibre Channel support
-#
-# CONFIG_FC4 is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-CONFIG_NETLINK_DEV=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_SYN_COOKIES is not set
-CONFIG_INET_AH=y
-CONFIG_INET_ESP=y
-CONFIG_INET_IPCOMP=y
-CONFIG_IPV6=y
-CONFIG_IPV6_PRIVACY=y
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_TUNNEL=m
-# CONFIG_NETFILTER is not set
-CONFIG_XFRM=y
-CONFIG_XFRM_USER=m
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-CONFIG_IP_SCTP=m
-# CONFIG_SCTP_DBG_MSG is not set
-CONFIG_SCTP_DBG_OBJCNT=y
-# CONFIG_SCTP_HMAC_NONE is not set
-# CONFIG_SCTP_HMAC_SHA1 is not set
-CONFIG_SCTP_HMAC_MD5=y
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-CONFIG_NET_PKTGEN=m
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=m
-CONFIG_SUNLANCE=y
-CONFIG_HAPPYMEAL=m
-CONFIG_SUNBMAC=m
-CONFIG_SUNQE=m
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-
-#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_PCI is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# Unix98 PTY support
-#
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-CONFIG_INPUT_JOYDEV=m
-# CONFIG_INPUT_TSDEV is not set
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_EVBUG=m
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=m
-# CONFIG_SERIO_I8042 is not set
-CONFIG_SERIO_SERPORT=m
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_PCIPS2 is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-CONFIG_KEYBOARD_ATKBD=m
-CONFIG_KEYBOARD_SUNKBD=m
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-CONFIG_INPUT_MOUSE=y
-CONFIG_MOUSE_PS2=m
-CONFIG_MOUSE_SERIAL=m
-# CONFIG_MOUSE_VSXXXAA is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-CONFIG_XFS_FS=m
-CONFIG_XFS_RT=y
-CONFIG_XFS_QUOTA=y
-CONFIG_XFS_SECURITY=y
-CONFIG_XFS_POSIX_ACL=y
-# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=m
-# CONFIG_QUOTA is not set
-CONFIG_QUOTACTL=y
-CONFIG_AUTOFS_FS=m
-CONFIG_AUTOFS4_FS=m
-
-#
-# CD-ROM/DVD Filesystems
-#
-CONFIG_ISO9660_FS=m
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-CONFIG_DEVPTS_FS_XATTR=y
-# CONFIG_DEVPTS_FS_SECURITY is not set
-# CONFIG_TMPFS is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-CONFIG_BEFS_FS=m
-# CONFIG_BEFS_DEBUG is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-CONFIG_CRAMFS=y
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_ROOT_NFS=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
-CONFIG_SUNRPC=y
-CONFIG_SUNRPC_GSS=m
-CONFIG_RPCSEC_GSS_KRB5=m
-# CONFIG_SMB_FS is not set
-CONFIG_CIFS=m
-# CONFIG_CIFS_STATS is not set
-# CONFIG_CIFS_XATTR is not set
-# CONFIG_CIFS_POSIX is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-CONFIG_AFS_FS=m
-CONFIG_RXRPC=m
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_SUN_PARTITION=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# USB support
-#
-# CONFIG_USB is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-
-#
-# Kernel hacking
-#
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_HIGHMEM is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-
-#
-# Security options
-#
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_NULL=m
-CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA256=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_CAST5=m
-CONFIG_CRYPTO_CAST6=m
-# CONFIG_CRYPTO_TEA is not set
-CONFIG_CRYPTO_ARC4=m
-# CONFIG_CRYPTO_KHAZAD is not set
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_CRC32C=m
-# CONFIG_CRYPTO_TEST is not set
-
-#
-# Library routines
-#
-# CONFIG_CRC_CCITT is not set
-CONFIG_CRC32=y
-CONFIG_LIBCRC32C=m
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/linux-sun4cdm_2.4.26.bb b/linux/linux-sun4cdm_2.4.26.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-sun4cdm_2.4.26.bb
+++ /dev/null
diff --git a/linux/linux-sun4cdm_2.6.8.1.bb b/linux/linux-sun4cdm_2.6.8.1.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-sun4cdm_2.6.8.1.bb
+++ /dev/null
diff --git a/linux/linux-xxs1500-2.4.21/Makefile b/linux/linux-xxs1500-2.4.21/Makefile
deleted file mode 100644
index 7ef3faa145..0000000000
--- a/linux/linux-xxs1500-2.4.21/Makefile
+++ /dev/null
@@ -1,756 +0,0 @@
-#
-# This file is subject to the terms and conditions of the GNU General Public
-# License. See the file "COPYING" in the main directory of this archive
-# for more details.
-#
-# Copyright (C) 1994, 1995, 1996 by Ralf Baechle
-# DECStation modifications by Paul M. Antoine, 1996
-# Copyright (C) 2002, 2003 Maciej W. Rozycki
-#
-# This file is included by the global makefile so that you can add your own
-# architecture-specific flags and dependencies. Remember to do have actions
-# for "archclean" and "archdep" for cleaning up and making dependencies for
-# this architecture
-#
-
-#
-# Select the object file format to substitute into the linker script.
-#
-ifdef CONFIG_CPU_LITTLE_ENDIAN
-tool-prefix = mipsel-linux-
-ld-emul = elf32ltsmip
-else
-tool-prefix = mips-linux-
-ld-emul = elf32btsmip
-endif
-
-ifdef CONFIG_CROSSCOMPILE
-CROSS_COMPILE = $(tool-prefix)
-endif
-
-check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
-
-#
-#
-# GCC uses -G 0 -mabicalls -fpic as default. We don't want PIC in the kernel
-# code since it only slows down the whole thing. At some point we might make
-# use of global pointer optimizations but their use of $28 conflicts with
-# the current pointer optimization.
-#
-# The DECStation requires an ECOFF kernel for remote booting, other MIPS
-# machines may also. Since BFD is incredibly buggy with respect to
-# crossformat linking we rely on the elf2ecoff tool for format conversion.
-#
-GCCFLAGS := -I $(TOPDIR)/include/asm/gcc
-GCCFLAGS += -G 0 -mno-abicalls -fno-pic -pipe
-GCCFLAGS += $(call check_gcc, -finline-limit=100000,)
-LINKFLAGS += -G 0 -static # -N
-MODFLAGS += -mlong-calls
-
-ifdef CONFIG_DEBUG_INFO
-GCCFLAGS += -g
-ifdef CONFIG_SB1XXX_CORELIS
-GCCFLAGS += -mno-sched-prolog -fno-omit-frame-pointer
-endif
-endif
-
-#
-# Use: $(call set_gccflags,<cpu0>,<isa0>,<cpu1>,<isa1>,<isa2>)
-#
-# <cpu0>,<isa0> -- preferred CPU and ISA designations (may require
-# recent tools)
-# <cpu1>,<isa1> -- fallback CPU and ISA designations (have to work
-# with up to the oldest supported tools)
-# <isa2> -- an ISA designation used as an ABI selector for
-# gcc versions that do not support "-mabi=32"
-# (depending on the CPU type, either "mips1" or
-# "mips2")
-#
-set_gccflags = $(shell \
-while :; do \
- cpu=$(1); isa=-$(2); \
- for gcc_opt in -march= -mcpu=; do \
- $(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \
- -xc /dev/null > /dev/null 2>&1 && \
- break 2; \
- done; \
- cpu=$(3); isa=-$(4); \
- for gcc_opt in -march= -mcpu=; do \
- $(CC) $$gcc_opt$$cpu $$isa -S -o /dev/null \
- -xc /dev/null > /dev/null 2>&1 && \
- break 2; \
- done; \
- break; \
-done; \
-gcc_abi=-mabi=32; gcc_cpu=$$cpu; \
-if $(CC) $$gcc_abi -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then \
- gcc_isa=$$isa; \
-else \
- gcc_abi=; gcc_isa=-$(5); \
-fi; \
-gas_abi=-Wa,-32; gas_cpu=$$cpu; gas_isa=-Wa,$$isa; \
-while :; do \
- for gas_opt in -Wa,-march= -Wa,-mcpu=; do \
- $(CC) $$gas_abi $$gas_opt$$cpu $$gas_isa -Wa,-Z -c \
- -o /dev/null -xassembler /dev/null > /dev/null 2>&1 && \
- break 2; \
- done; \
- gas_abi=; gas_opt=; gas_cpu=; gas_isa=; \
- break; \
-done; \
-echo $$gcc_abi $$gcc_opt$$gcc_cpu $$gcc_isa $$gas_abi $$gas_opt$$gas_cpu $$gas_isa)
-
-#
-# CPU-dependent compiler/assembler options for optimization.
-#
-ifdef CONFIG_CPU_R3000
-GCCFLAGS += $(call set_gccflags,r3000,mips1,r3000,mips1,mips1)
-endif
-ifdef CONFIG_CPU_TX39XX
-GCCFLAGS += $(call set_gccflags,r3900,mips1,r3000,mips1,mips1)
-endif
-ifdef CONFIG_CPU_R6000
-GCCFLAGS += $(call set_gccflags,r6000,mips2,r6000,mips2,mips2) \
- -Wa,--trap
-endif
-ifdef CONFIG_CPU_R4300
-GCCFLAGS += $(call set_gccflags,r4300,mips3,r4300,mips3,mips2) \
- -Wa,--trap
-endif
-ifdef CONFIG_CPU_VR41XX
-GCCFLAGS += $(call set_gccflags,r4100,mips3,r4600,mips3,mips2) \
- -Wa,--trap
-endif
-ifdef CONFIG_CPU_R4X00
-GCCFLAGS += $(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \
- -Wa,--trap
-endif
-ifdef CONFIG_CPU_TX49XX
-GCCFLAGS += $(call set_gccflags,r4600,mips3,r4600,mips3,mips2) \
- -Wa,--trap
-endif
-ifdef CONFIG_CPU_MIPS32
-GCCFLAGS += $(call set_gccflags,mips32,mips32,r4600,mips3,mips2) \
- -Wa,--trap
-endif
-ifdef CONFIG_CPU_MIPS64
-GCCFLAGS += $(call set_gccflags,mips64,mips64,r4600,mips3,mips2) \
- -Wa,--trap
-endif
-ifdef CONFIG_CPU_R5000
-GCCFLAGS += $(call set_gccflags,r5000,mips4,r5000,mips4,mips2) \
- -Wa,--trap
-endif
-ifdef CONFIG_CPU_R5432
-GCCFLAGS += $(call set_gccflags,r5400,mips4,r5000,mips4,mips2) \
- -Wa,--trap
-endif
-ifdef CONFIG_CPU_NEVADA
-GCCFLAGS += $(call set_gccflags,rm5200,mips4,r5000,mips4,mips2) \
- -Wa,--trap
-#GCCFLAGS += $(call check_gcc,-mmad,)
-endif
-ifdef CONFIG_CPU_RM7000
-GCCFLAGS += $(call set_gccflags,rm7000,mips4,r5000,mips4,mips2) \
- -Wa,--trap
-endif
-ifdef CONFIG_CPU_RM9000
-GCCFLAGS += $(call set_gccflags,rm9000,mips4,r5000,mips4,mips2) \
- -Wa,--trap
-endif
-ifdef CONFIG_CPU_SB1
-GCCFLAGS += $(call set_gccflags,sb1,mips64,r5000,mips4,mips2) \
- -Wa,--trap
-ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
-MODFLAGS += -msb1-pass1-workarounds
-endif
-endif
-
-AFLAGS += $(GCCFLAGS)
-CFLAGS += $(GCCFLAGS)
-LDFLAGS += -m $(ld-emul)
-
-
-#
-# We unconditionally build the math emulator
-#
-CORE_FILES += arch/mips/math-emu/fpu_emulator.o
-SUBDIRS += arch/mips/math-emu
-
-#
-# ramdisk/initrd support
-# You need a compressed ramdisk image, named ramdisk.gz in
-# arch/mips/ramdisk
-#
-ifdef CONFIG_EMBEDDED_RAMDISK
-CORE_FILES += arch/mips/ramdisk/ramdisk.o
-SUBDIRS += arch/mips/ramdisk
-endif
-
-
-#
-# Board-dependent options and extra files
-#
-
-#
-# Acer PICA 61, Mips Magnum 4000 and Olivetti M700.
-#
-ifdef CONFIG_MIPS_JAZZ
-CORE_FILES += arch/mips/jazz/jazz.o
-SUBDIRS += arch/mips/jazz arch/mips/arc
-LIBS += arch/mips/arc/arclib.a
-LOADADDR := 0x80080000
-endif
-
-#
-# Au1000 (Alchemy Semi PB1000) eval board
-#
-ifdef CONFIG_MIPS_PB1000
-LIBS += arch/mips/au1000/pb1000/pb1000.o \
- arch/mips/au1000/common/au1000.o
-SUBDIRS += arch/mips/au1000/pb1000 arch/mips/au1000/common
-LOADADDR := 0x80100000
-endif
-
-#
-# Au1100 (Alchemy Semi PB1100) eval board
-#
-ifdef CONFIG_MIPS_PB1100
-LIBS += arch/mips/au1000/pb1100/pb1100.o \
- arch/mips/au1000/common/au1000.o
-SUBDIRS += arch/mips/au1000/pb1100 arch/mips/au1000/common
-LOADADDR += 0x80100000
-endif
-
-#
-# Au1500 (Alchemy Semi PB1500) eval board
-#
-ifdef CONFIG_MIPS_PB1500
-LIBS += arch/mips/au1000/pb1500/pb1500.o \
- arch/mips/au1000/common/au1000.o
-SUBDIRS += arch/mips/au1000/pb1500 arch/mips/au1000/common
-LOADADDR := 0x80100000
-endif
-
-#
-# Au1x00 (AMD/Alchemy) eval boards
-#
-ifdef CONFIG_MIPS_DB1000
-LIBS += arch/mips/au1000/db1x00/db1x00.o \
- arch/mips/au1000/common/au1000.o
-SUBDIRS += arch/mips/au1000/db1x00 arch/mips/au1000/common
-LOADADDR += 0x80100000
-endif
-
-ifdef CONFIG_MIPS_DB1500
-LIBS += arch/mips/au1000/db1x00/db1x00.o \
- arch/mips/au1000/common/au1000.o
-SUBDIRS += arch/mips/au1000/db1x00 arch/mips/au1000/common
-LOADADDR += 0x80100000
-endif
-
-ifdef CONFIG_MIPS_DB1100
-LIBS += arch/mips/au1000/db1x00/db1x00.o \
- arch/mips/au1000/common/au1000.o
-SUBDIRS += arch/mips/au1000/db1x00 arch/mips/au1000/common
-LOADADDR += 0x80100000
-endif
-
-ifdef CONFIG_MIPS_HYDROGEN3
-LIBS += arch/mips/au1000/hydrogen3/hydrogen3.o \
- arch/mips/au1000/common/au1000.o
-SUBDIRS += arch/mips/au1000/hydrogen3 arch/mips/au1000/common
-LOADADDR += 0x80100000
-endif
-
-ifdef CONFIG_MIPS_BOSPORUS
-LIBS += arch/mips/au1000/db1x00/db1x00.o \
- arch/mips/au1000/common/au1000.o
-SUBDIRS += arch/mips/au1000/db1x00 arch/mips/au1000/common
-LOADADDR += 0x80100000
-endif
-
-ifdef CONFIG_MIPS_MIRAGE
-LIBS += arch/mips/au1000/db1x00/db1x00.o \
- arch/mips/au1000/common/au1000.o
-SUBDIRS += arch/mips/au1000/db1x00 arch/mips/au1000/common
-LOADADDR += 0x80100000
-endif
-
-ifdef CONFIG_MIPS_XXS1500
-LIBS += arch/mips/au1000/xxs1500/xxs1500.o \
- arch/mips/au1000/common/au1000.o
-SUBDIRS += arch/mips/au1000/xxs1500 arch/mips/au1000/common
-LOADADDR += 0x80100000
-endif
-
-ifdef CONFIG_MIPS_MTX1
-LIBS += arch/mips/au1000/mtx-1/mtx-1.o \
- arch/mips/au1000/common/au1000.o
-SUBDIRS += arch/mips/au1000/mtx-1 arch/mips/au1000/common
-LOADADDR += 0x80100000
-endif
-
-ifdef CONFIG_MIPS_PB1550
-LIBS += arch/mips/au1000/pb1550/pb1550.o \
- arch/mips/au1000/common/au1000.o
-SUBDIRS += arch/mips/au1000/pb1550 arch/mips/au1000/common
-LOADADDR += 0x80100000
-endif
-
-
-#
-# Cogent CSB250
-#
-ifdef CONFIG_COGENT_CSB250
-LIBS += arch/mips/au1000/csb250/csb250.o \
- arch/mips/au1000/common/au1000.o
-SUBDIRS += arch/mips/au1000/csb250 arch/mips/au1000/common
-LOADADDR := 0x80100000
-endif
-
-ifdef CONFIG_PCI
-CORE_FILES += arch/mips/pci/pci-core.o
-SUBDIRS += arch/mips/pci
-endif
-
-#
-# Algorithmics P4032
-#
-ifdef CONFIG_ALGOR_P4032
-CORE_FILES += arch/mips/algor/algor.o
-SUBDIRS += arch/mips/algor
-LOADADDR := 0x80000000
-endif
-
-#
-# Baget/MIPS
-#
-ifdef CONFIG_BAGET_MIPS
-SUBDIRS += arch/mips/baget arch/mips/baget/prom
-LIBS += arch/mips/baget/baget.a arch/mips/baget/prom/bagetlib.a
-LOADADDR := 0x80001000
-endif
-
-#
-# Cobalt Server
-#
-ifdef CONFIG_MIPS_COBALT
-SUBDIRS += arch/mips/cobalt
-CORE_FILES += arch/mips/cobalt/cobalt.o
-LOADADDR := 0x80080000
-endif
-
-#
-# DECstation family
-#
-ifdef CONFIG_DECSTATION
-CORE_FILES += arch/mips/dec/dec.o
-SUBDIRS += arch/mips/dec arch/mips/dec/prom
-LIBS += arch/mips/dec/prom/rexlib.a
-LOADADDR := 0x80040000
-endif
-
-#
-# Galileo EV64120 Board
-#
-ifdef CONFIG_MIPS_EV64120
-LIBS += arch/mips/gt64120/common/gt64120.o \
- arch/mips/gt64120/ev64120/ev64120.o
-SUBDIRS += arch/mips/gt64120/common arch/mips/gt64120/ev64120
-LOADADDR := 0x80100000
-endif
-
-#
-# Galileo EV96100 Board
-#
-ifdef CONFIG_MIPS_EV96100
-LIBS += arch/mips/galileo-boards/ev96100/ev96100.o
-SUBDIRS += arch/mips/galileo-boards/ev96100
-LOADADDR := 0x80100000
-endif
-
-#
-# Globespan IVR eval board with QED 5231 CPU
-#
-ifdef CONFIG_MIPS_IVR
-LIBS += arch/mips/ite-boards/ivr/ivr.o \
- arch/mips/ite-boards/generic/it8172.o
-SUBDIRS += arch/mips/ite-boards/generic arch/mips/ite-boards/ivr
-LOADADDR := 0x80100000
-endif
-
-#
-# HP LaserJet
-#
-ifdef CONFIG_HP_LASERJET
-SUBDIRS += arch/mips/hp-lj
-LIBS += arch/mips/hp-lj/hp-lj.o
-LOADADDR := 0x80030000
-endif
-
-#
-# ITE 8172 eval board with QED 5231 CPU
-#
-ifdef CONFIG_MIPS_ITE8172
-LIBS += arch/mips/ite-boards/qed-4n-s01b/ite.o \
- arch/mips/ite-boards/generic/it8172.o
-SUBDIRS += arch/mips/ite-boards/generic arch/mips/ite-boards/qed-4n-s01b
-LOADADDR := 0x80100000
-endif
-
-#
-# MIPS Atlas board
-#
-ifdef CONFIG_MIPS_ATLAS
-LIBS += arch/mips/mips-boards/atlas/atlas.o \
- arch/mips/mips-boards/generic/mipsboards.o
-SUBDIRS += arch/mips/mips-boards/generic arch/mips/mips-boards/atlas
-LOADADDR := 0x80100000
-endif
-
-#
-# MIPS Malta board
-#
-ifdef CONFIG_MIPS_MALTA
-LIBS += arch/mips/mips-boards/malta/malta.o \
- arch/mips/mips-boards/generic/mipsboards.o
-SUBDIRS += arch/mips/mips-boards/malta arch/mips/mips-boards/generic
-LOADADDR := 0x80100000
-endif
-
-#
-# MIPS SEAD board
-#
-ifdef CONFIG_MIPS_SEAD
-LIBS += arch/mips/mips-boards/sead/sead.o \
- arch/mips/mips-boards/generic/mipsboards.o
-SUBDIRS += arch/mips/mips-boards/generic arch/mips/mips-boards/sead
-LOADADDR := 0x80100000
-endif
-
-#
-# Momentum Ocelot board
-#
-ifdef CONFIG_MOMENCO_OCELOT
-# The Ocelot setup.o must be linked early - it does the ioremap() for the
-# mips_io_port_base.
-CORE_FILES += arch/mips/gt64120/common/gt64120.o \
- arch/mips/gt64120/momenco_ocelot/momenco_ocelot.o
-SUBDIRS += arch/mips/gt64120/common arch/mips/gt64120/momenco_ocelot
-LOADADDR := 0x80100000
-endif
-
-#
-# Momentum Ocelot-G board
-#
-ifdef CONFIG_MOMENCO_OCELOT_G
-# The Ocelot-G setup.o must be linked early - it does the ioremap() for the
-# mips_io_port_base.
-CORE_FILES += arch/mips/momentum/ocelot_g/ocelot_g.o
-SUBDIRS += arch/mips/momentum/ocelot_g
-LOADADDR := 0x80100000
-endif
-
-#
-# Momentum Ocelot-C and -CS boards
-#
-ifdef CONFIG_MOMENCO_OCELOT_C
-# The Ocelot-C[S] setup.o must be linked early - it does the ioremap() for the
-# mips_io_port_base.
-CORE_FILES += arch/mips/momentum/ocelot_c/ocelot_c.o
-SUBDIRS += arch/mips/momentum/ocelot_c
-LOADADDR := 0x80100000
-endif
-
-ifdef CONFIG_MOMENCO_JAGUAR_ATX
-LIBS += arch/mips/momentum/jaguar_atx/jaguar_atx.o
-SUBDIRS += arch/mips/momentum/jaguar_atx
-ifdef CONFIG_JAGUAR_DMALOW
-LOADADDR := 0x88000000
-else
-LOADADDR := 0x80100000
-endif
-endif
-
-#
-# NEC DDB Vrc-5074
-#
-ifdef CONFIG_DDB5074
-SUBDIRS += arch/mips/ddb5xxx/common arch/mips/ddb5xxx/ddb5074
-LIBS += arch/mips/ddb5xxx/common/ddb5xxx.o arch/mips/ddb5xxx/ddb5074/ddb5074.o
-LOADADDR := 0x80080000
-endif
-
-#
-# NEC DDB Vrc-5476
-#
-ifdef CONFIG_DDB5476
-SUBDIRS += arch/mips/ddb5xxx/common arch/mips/ddb5xxx/ddb5476
-LIBS += arch/mips/ddb5xxx/common/ddb5xxx.o \
- arch/mips/ddb5xxx/ddb5476/ddb5476.o
-LOADADDR := 0x80080000
-endif
-
-#
-# NEC DDB Vrc-5477
-#
-ifdef CONFIG_DDB5477
-SUBDIRS += arch/mips/ddb5xxx/common arch/mips/ddb5xxx/ddb5477
-LIBS += arch/mips/ddb5xxx/common/ddb5xxx.o \
- arch/mips/ddb5xxx/ddb5477/ddb5477.o
-LOADADDR := 0x80100000
-endif
-
-ifdef CONFIG_LASAT
-LIBS += arch/mips/lasat/lasatkern.o
-SUBDIRS += arch/mips/lasat
-LOADADDR += 0x80000000
-endif
-#
-# NEC Osprey (vr4181) board
-#
-ifdef CONFIG_NEC_OSPREY
-SUBDIRS += arch/mips/vr4181/common arch/mips/vr4181/osprey
-LIBS += arch/mips/vr4181/common/vr4181.o \
- arch/mips/vr4181/osprey/osprey.o
-LOADADDR := 0x80002000
-endif
-
-#
-# NEC Eagle/Hawk (VR4122/VR4131) board
-#
-ifdef CONFIG_NEC_EAGLE
-SUBDIRS += arch/mips/vr41xx/common \
- arch/mips/vr41xx/nec-eagle
-CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \
- arch/mips/vr41xx/nec-eagle/eagle.o
-LOADADDR := 0x80000000
-endif
-
-#
-# ZAO Networks Capcella (VR4131)
-#
-ifdef CONFIG_ZAO_CAPCELLA
-SUBDIRS += arch/mips/vr41xx/common \
- arch/mips/vr41xx/zao-capcella
-CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \
- arch/mips/vr41xx/zao-capcella/capcella.o
-LOADADDR := 0x80000000
-endif
-
-#
-# Victor MP-C303/304 (VR4122)
-#
-ifdef CONFIG_VICTOR_MPC30X
-SUBDIRS += arch/mips/vr41xx/common \
- arch/mips/vr41xx/victor-mpc30x
-CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \
- arch/mips/vr41xx/victor-mpc30x/mpc30x.o
-LOADADDR := 0x80001000
-endif
-
-#
-# IBM WorkPad z50 (VR4121)
-#
-ifdef CONFIG_IBM_WORKPAD
-SUBDIRS += arch/mips/vr41xx/common \
- arch/mips/vr41xx/ibm-workpad
-CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \
- arch/mips/vr41xx/ibm-workpad/workpad.o
-LOADADDR += 0x80004000
-endif
-
-#
-# CASIO CASSIPEIA E-55/65 (VR4111)
-#
-ifdef CONFIG_CASIO_E55
-SUBDIRS += arch/mips/vr41xx/common \
- arch/mips/vr41xx/casio-e55
-CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \
- arch/mips/vr41xx/casio-e55/e55.o
-LOADADDR += 0x80004000
-endif
-
-#
-# TANBAC TB0226 Mbase (VR4131)
-#
-ifdef CONFIG_TANBAC_TB0226
-SUBDIRS += arch/mips/vr41xx/common \
- arch/mips/vr41xx/tanbac-tb0226
-CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \
- arch/mips/vr41xx/tanbac-tb0226/tb0226.o
-LOADADDR := 0x80000000
-endif
-
-#
-# TANBAC TB0229 (VR4131DIMM)
-#
-ifdef CONFIG_TANBAC_TB0229
-SUBDIRS += arch/mips/vr41xx/common \
- arch/mips/vr41xx/tanbac-tb0229
-CORE_FILES += arch/mips/vr41xx/common/vr41xx.o \
- arch/mips/vr41xx/tanbac-tb0229/tb0229.o
-LOADADDR := 0x80000000
-endif
-
-#
-# Philips Nino
-#
-ifdef CONFIG_NINO
-CORE_FILES += arch/mips/philips/nino/nino.o
-SUBDIRS += arch/mips/philips/nino
-LOADADDR := 0x80000000
-endif
-
-#
-# SGI IP22 (Indy/Indigo2)
-#
-ifdef CONFIG_SGI_IP22
-CORE_FILES += arch/mips/sgi-ip22/ip22-kern.o
-LIBS += arch/mips/arc/arclib.a
-SUBDIRS += arch/mips/sgi-ip22 arch/mips/arc
-#
-# Set LOADADDR to >= 0x88069000 if you want to leave space for symmon,
-# 0x88002000 for production kernels. Note that the value must be
-# 8kb aligned or the handling of the current variable will break.
-#
-LOADADDR := 0x88002000
-endif
-
-#
-# Sibyte SB1250 SOC and Broadcom (SiByte) BCM112x SOCs
-#
-ifneq ($(CONFIG_SIBYTE_SB1250)$(CONFIG_SIBYTE_BCM112X),)
-# This is a LIB so that it links at the end, and initcalls are later
-# the sequence; but it is built as an object so that modules don't get
-# removed (as happens, even if they have __initcall/module_init)
-LIBS += arch/mips/sibyte/sb1250/sb1250.o
-SUBDIRS += arch/mips/sibyte/sb1250
-LOADADDR := 0x80100000
-endif
-
-#
-# Sibyte boards:
-#
-# BCM91250A (SWARM),
-# BCM91250E (Sentosa),
-# BCM91120C (CRhine),
-# BCM91120x (Carmel),
-# BCM91125C (CRhone),
-# BCM91125E (Rhone).
-#
-ifdef CONFIG_SIBYTE_BOARD
-LIBS += arch/mips/sibyte/swarm/sbswarm.a
-SUBDIRS += arch/mips/sibyte/swarm
-endif
-
-#
-# Sibyte CFE firmware
-#
-ifdef CONFIG_SIBYTE_CFE
-LIBS += arch/mips/sibyte/cfe/cfe.a
-SUBDIRS += arch/mips/sibyte/cfe
-endif
-
-#
-# SNI RM200 PCI
-#
-ifdef CONFIG_SNI_RM200_PCI
-CORE_FILES += arch/mips/sni/sni.o
-SUBDIRS += arch/mips/sni arch/mips/arc
-LIBS += arch/mips/arc/arclib.a
-LOADADDR := 0x80080000
-endif
-
-#
-# Toshiba JMR-TX3927 board
-#
-ifdef CONFIG_TOSHIBA_JMR3927
-CORE_FILES += arch/mips/jmr3927/rbhma3100/jmr3927.o \
- arch/mips/jmr3927/common/tx3927.o
-SUBDIRS += arch/mips/jmr3927/rbhma3100 arch/mips/jmr3927/common
-LOADADDR := 0x80050000
-endif
-
-#
-# Toshiba RBTX4927 board or
-# Toshiba RBTX4937 board
-#
-ifdef CONFIG_TOSHIBA_RBTX4927
-MIPS = arch/mips
-CEC = tx4927
-COMMON = $(MIPS)/$(CEC)/common
-BOARD = $(MIPS)/$(CEC)/toshiba_rbtx4927
-LIBS += $(BOARD)/toshiba_rbtx4927.o $(COMMON)/tx4927.o
-SUBDIRS += $(BOARD) $(COMMON)
-LOADADDR += 0x80020000
-endif
-
-#
-# Choosing incompatible machines durings configuration will result in
-# error messages during linking. Select a default linkscript if
-# none has been choosen above.
-#
-vmlinux: arch/$(ARCH)/ld.script
-
-arch/$(ARCH)/ld.script: arch/$(ARCH)/ld.script.in arch/$(ARCH)/Makefile
- sed -e 's/@@LOADADDR@@/$(LOADADDR)/' <$< >$@
-LINKFLAGS += -T arch/$(ARCH)/ld.script
-
-HEAD := arch/mips/kernel/head.o arch/mips/kernel/init_task.o
-
-SUBDIRS := $(addprefix arch/mips/, tools) $(SUBDIRS) $(addprefix arch/mips/, kernel mm lib)
-CORE_FILES := arch/mips/kernel/kernel.o arch/mips/mm/mm.o $(CORE_FILES)
-LIBS := arch/mips/lib/lib.a $(LIBS)
-
-ifdef CONFIG_BAGET_MIPS
-
-BAGETBOOT = $(MAKE) -C arch/$(ARCH)/baget
-
-balo: vmlinux
- $(BAGETBOOT) balo
-
-endif
-
-ifdef CONFIG_MIPS_EV64120
-gboot: vmlinux
- $(MAKE) -C arch/$(ARCH)/galileo-boards/ev64120/compressed
-endif
-
-ifdef CONFIG_LASAT
-rom.bin rom.sw: vmlinux
- $(MAKE) -C arch/$(ARCH)/lasat/image $@
-endif
-
-MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
-MAKEZBOOT = $(MAKE) -C arch/$(ARCH)/zboot
-BOOT_TARGETS = zImage zImage.initrd zImage.flash zImage.flash.bin
-
-vmlinux.ecoff: vmlinux
- @$(MAKEBOOT) $@
-
- $(BOOT_TARGETS): vmlinux
- @$(MAKEZBOOT) $@
-
-vmlinux.srec: vmlinux
- @$(MAKEBOOT) $@
-
-archclean:
- @$(MAKEBOOT) clean
- @$(MAKEZBOOT) clean
- rm -f arch/$(ARCH)/ld.script
- $(MAKE) -C arch/$(ARCH)/tools clean
- $(MAKE) -C arch/mips/baget clean
- $(MAKE) -C arch/mips/lasat clean
-
-archmrproper:
- @$(MAKEBOOT) mrproper
- $(RM) $(TOPDIR)/include/asm-$(ARCH)/offset.h
- $(MAKE) -C arch/$(ARCH)/tools mrproper
-
-archdep:
- if [ ! -f $(TOPDIR)/include/asm-$(ARCH)/offset.h ]; then \
- touch $(TOPDIR)/include/asm-$(ARCH)/offset.h; \
- fi;
- @$(MAKEBOOT) dep
diff --git a/linux/linux-xxs1500-2.4.21/defconfig-xxs1500 b/linux/linux-xxs1500-2.4.21/defconfig-xxs1500
deleted file mode 100644
index 0fc84863ca..0000000000
--- a/linux/linux-xxs1500-2.4.21/defconfig-xxs1500
+++ /dev/null
@@ -1,1199 +0,0 @@
-#
-# Automatically generated by make menuconfig: don't edit
-#
-CONFIG_MIPS=y
-CONFIG_MIPS32=y
-# CONFIG_MIPS64 is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# Machine selection
-#
-# CONFIG_ACER_PICA_61 is not set
-# CONFIG_MIPS_BOSPORUS is not set
-# CONFIG_MIPS_MIRAGE is not set
-# CONFIG_MIPS_DB1000 is not set
-# CONFIG_MIPS_DB1100 is not set
-# CONFIG_MIPS_DB1500 is not set
-# CONFIG_MIPS_PB1000 is not set
-# CONFIG_MIPS_PB1100 is not set
-# CONFIG_MIPS_PB1500 is not set
-CONFIG_MIPS_XXS1500=y
-# CONFIG_MIPS_MTX1 is not set
-# CONFIG_BAGET_MIPS is not set
-# CONFIG_CASIO_E55 is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_DECSTATION is not set
-# CONFIG_MIPS_EV64120 is not set
-# CONFIG_MIPS_EV96100 is not set
-# CONFIG_MIPS_IVR is not set
-# CONFIG_HP_LASERJET is not set
-# CONFIG_IBM_WORKPAD is not set
-# CONFIG_LASAT is not set
-# CONFIG_MIPS_ITE8172 is not set
-# CONFIG_MIPS_ATLAS is not set
-# CONFIG_MIPS_MAGNUM_4000 is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_SEAD is not set
-# CONFIG_MOMENCO_OCELOT is not set
-# CONFIG_MOMENCO_OCELOT_G is not set
-# CONFIG_MOMENCO_OCELOT_C is not set
-# CONFIG_DDB5074 is not set
-# CONFIG_DDB5476 is not set
-# CONFIG_DDB5477 is not set
-# CONFIG_NEC_OSPREY is not set
-# CONFIG_NEC_EAGLE is not set
-# CONFIG_OLIVETTI_M700 is not set
-# CONFIG_NINO is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SIBYTE_SB1xxx_SOC is not set
-# CONFIG_SNI_RM200_PCI is not set
-# CONFIG_TANBAC_TB0226 is not set
-# CONFIG_TANBAC_TB0229 is not set
-# CONFIG_TOSHIBA_JMR3927 is not set
-# CONFIG_TOSHIBA_RBTX4927 is not set
-# CONFIG_VICTOR_MPC30X is not set
-# CONFIG_ZAO_CAPCELLA is not set
-# CONFIG_HIGHMEM is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-CONFIG_SOC_AU1X00=y
-CONFIG_SOC_AU1500=y
-CONFIG_PCI=y
-CONFIG_NEW_PCI=y
-CONFIG_PCI_AUTO=y
-CONFIG_NONCOHERENT_IO=y
-CONFIG_PC_KEYB=y
-# CONFIG_MIPS_AU1000 is not set
-
-#
-# CPU selection
-#
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS64 is not set
-# CONFIG_CPU_R3000 is not set
-# CONFIG_CPU_TX39XX is not set
-# CONFIG_CPU_VR41XX is not set
-# CONFIG_CPU_R4300 is not set
-# CONFIG_CPU_R4X00 is not set
-# CONFIG_CPU_TX49XX is not set
-# CONFIG_CPU_R5000 is not set
-# CONFIG_CPU_R5432 is not set
-# CONFIG_CPU_R6000 is not set
-# CONFIG_CPU_NEVADA is not set
-# CONFIG_CPU_R8000 is not set
-# CONFIG_CPU_R10000 is not set
-# CONFIG_CPU_RM7000 is not set
-# CONFIG_CPU_SB1 is not set
-CONFIG_CPU_HAS_PREFETCH=y
-# CONFIG_VTAG_ICACHE is not set
-CONFIG_64BIT_PHYS_ADDR=y
-# CONFIG_CPU_ADVANCED is not set
-CONFIG_CPU_HAS_LLSC=y
-# CONFIG_CPU_HAS_LLDSCD is not set
-# CONFIG_CPU_HAS_WB is not set
-CONFIG_CPU_HAS_SYNC=y
-
-#
-# General setup
-#
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_NET=y
-CONFIG_PCI_NAMES=y
-# CONFIG_ISA is not set
-# CONFIG_EISA is not set
-# CONFIG_TC is not set
-# CONFIG_MCA is not set
-# CONFIG_SBUS is not set
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=m
-# CONFIG_CARDBUS is not set
-# CONFIG_TCIC is not set
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-CONFIG_PCMCIA_AU1X00=m
-# CONFIG_PCMCIA_PB1X00 is not set
-# CONFIG_PCMCIA_DB1X00 is not set
-CONFIG_PCMCIA_XXS1500=y
-# CONFIG_PCMCIA_VRC4173 is not set
-
-#
-# PCI Hotplug Support
-#
-# CONFIG_HOTPLUG_PCI is not set
-# CONFIG_HOTPLUG_PCI_COMPAQ is not set
-# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set
-# CONFIG_HOTPLUG_PCI_ACPI is not set
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_MIPS32_COMPAT is not set
-# CONFIG_MIPS32_O32 is not set
-# CONFIG_MIPS32_N32 is not set
-# CONFIG_BINFMT_ELF32 is not set
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_PM is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-CONFIG_MTD_CFI_AMDSTD=y
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_PB1000 is not set
-# CONFIG_MTD_PB1500 is not set
-# CONFIG_MTD_PB1100 is not set
-# CONFIG_MTD_BOSPORUS is not set
-CONFIG_MTD_XXS1500=y
-# CONFIG_MTD_MTX1 is not set
-# CONFIG_MTD_DB1X00 is not set
-# CONFIG_MTD_CSTM_MIPS_IXX is not set
-# CONFIG_MTD_OCELOT is not set
-# CONFIG_MTD_LASAT is not set
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PCMCIA is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-# CONFIG_MTD_DOC1000 is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Parallel port support
-#
-CONFIG_PARPORT=m
-CONFIG_PARPORT_PC=m
-# CONFIG_PARPORT_PC_FIFO is not set
-# CONFIG_PARPORT_PC_SUPERIO is not set
-# CONFIG_PARPORT_PC_PCMCIA is not set
-# CONFIG_PARPORT_AMIGA is not set
-# CONFIG_PARPORT_MFC3 is not set
-# CONFIG_PARPORT_ATARI is not set
-# CONFIG_PARPORT_GSC is not set
-# CONFIG_PARPORT_SUNBPP is not set
-# CONFIG_PARPORT_IP22 is not set
-# CONFIG_PARPORT_OTHER is not set
-CONFIG_PARPORT_1284=y
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_BLK_STATS is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_FWMARK=y
-CONFIG_IP_ROUTE_NAT=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_TOS=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_ROUTE_LARGE_TABLES=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-# CONFIG_IP_PNP_BOOTP is not set
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-CONFIG_INET_ECN=y
-CONFIG_SYN_COOKIES=y
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_UNCLEAN=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_MIRROR=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_NAT_AMANDA=m
-# CONFIG_IP_NF_NAT_LOCAL is not set
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-CONFIG_IPV6=m
-
-#
-# IPv6: Netfilter Configuration
-#
-CONFIG_IP6_NF_QUEUE=m
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_MATCH_OPTS=m
-CONFIG_IP6_NF_MATCH_FRAG=m
-CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
-CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_AHESP=m
-CONFIG_IP6_NF_MATCH_LENGTH=m
-CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-CONFIG_VLAN_8021Q=m
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_DEV_APPLETALK is not set
-# CONFIG_DECNET is not set
-CONFIG_BRIDGE=m
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-CONFIG_NET_SCH_CSZ=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_QOS=y
-CONFIG_NET_ESTIMATOR=y
-CONFIG_NET_CLS=y
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_ROUTE=y
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-CONFIG_NET_CLS_POLICE=y
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-
-#
-# Telephony Support
-#
-# CONFIG_PHONE is not set
-# CONFIG_PHONE_IXJ is not set
-# CONFIG_PHONE_IXJ_PCMCIA is not set
-
-#
-# ATA/IDE/MFM/RLL support
-#
-CONFIG_IDE=m
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=m
-# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=m
-CONFIG_IDEDISK_MULTI_MODE=y
-# CONFIG_IDEDISK_STROKE is not set
-CONFIG_BLK_DEV_IDECS=m
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
-CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_BLK_DEV_GENERIC is not set
-# CONFIG_IDEPCI_SHARE_IRQ is not set
-CONFIG_BLK_DEV_IDEDMA_PCI=y
-CONFIG_BLK_DEV_OFFBOARD=y
-# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_PCI_AUTO=y
-# CONFIG_IDEDMA_ONLYDISK is not set
-CONFIG_BLK_DEV_IDEDMA=y
-# CONFIG_IDEDMA_PCI_WIP is not set
-# CONFIG_BLK_DEV_ADMA100 is not set
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_WDC_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_AMD74XX_OVERRIDE is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_HPT34X is not set
-# CONFIG_HPT34X_AUTODMA is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_PDC202XX_BURST is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SIS5513 is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_IDE_CHIPSETS is not set
-CONFIG_IDEDMA_AUTO=y
-# CONFIG_IDEDMA_IVB is not set
-# CONFIG_DMA_NONPCI is not set
-CONFIG_BLK_DEV_IDE_MODES=y
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-# CONFIG_BLK_DEV_ATARAID_SII is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=m
-CONFIG_BLK_DEV_SD=m
-CONFIG_SD_EXTRA_DEVS=40
-CONFIG_CHR_DEV_ST=m
-# CONFIG_CHR_DEV_OSST is not set
-CONFIG_BLK_DEV_SR=m
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-CONFIG_SR_EXTRA_DEVS=2
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_SCSI_DEBUG_QUEUES is not set
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_CONSTANTS=y
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_PPA is not set
-# CONFIG_SCSI_IMM is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_NCR53C8XX is not set
-# CONFIG_SCSI_SYM53C8XX is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_SIM710 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# PCMCIA SCSI adapter support
-#
-CONFIG_SCSI_PCMCIA=y
-CONFIG_PCMCIA_AHA152X=m
-CONFIG_PCMCIA_FDOMAIN=m
-CONFIG_PCMCIA_NINJA_SCSI=m
-# CONFIG_PCMCIA_QLOGIC is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_PCI is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-CONFIG_DUMMY=m
-CONFIG_BONDING=m
-CONFIG_EQUALIZER=m
-CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MIPS_AU1X00_ENET=y
-CONFIG_BCM5222_DUAL_PHY=y
-# CONFIG_SUNLANCE is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNBMAC is not set
-# CONFIG_SUNQE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPPOE=m
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_STRIP is not set
-# CONFIG_WAVELAN is not set
-# CONFIG_ARLAN is not set
-# CONFIG_AIRONET4500 is not set
-# CONFIG_AIRONET4500_NONCS is not set
-# CONFIG_AIRONET4500_PROC is not set
-# CONFIG_AIRO is not set
-# CONFIG_HERMES is not set
-# CONFIG_PLX_HERMES is not set
-# CONFIG_PCI_HERMES is not set
-# CONFIG_PCMCIA_HERMES is not set
-CONFIG_AIRO_CS=m
-CONFIG_NET_WIRELESS=y
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-CONFIG_SHAPER=m
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_AXNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-# CONFIG_ARCNET_COM20020_CS is not set
-# CONFIG_PCMCIA_IBMTR is not set
-CONFIG_NET_PCMCIA_RADIO=y
-# CONFIG_PCMCIA_RAYCS is not set
-# CONFIG_PCMCIA_NETWAVE is not set
-# CONFIG_PCMCIA_WAVELAN is not set
-# CONFIG_AIRONET4500_CS is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-# CONFIG_SERIAL is not set
-# CONFIG_SERIAL_EXTENDED is not set
-CONFIG_SERIAL_NONSTANDARD=y
-# CONFIG_COMPUTONE is not set
-# CONFIG_ROCKETPORT is not set
-# CONFIG_CYCLADES is not set
-# CONFIG_DIGIEPCA is not set
-# CONFIG_DIGI is not set
-# CONFIG_ESPSERIAL is not set
-# CONFIG_MOXA_INTELLIO is not set
-# CONFIG_MOXA_SMARTIO is not set
-# CONFIG_ISI is not set
-# CONFIG_SYNCLINK is not set
-# CONFIG_SYNCLINKMP is not set
-# CONFIG_N_HDLC is not set
-# CONFIG_RISCOM8 is not set
-# CONFIG_SPECIALIX is not set
-# CONFIG_SX is not set
-# CONFIG_RIO is not set
-# CONFIG_STALDRV is not set
-# CONFIG_SERIAL_TX3912 is not set
-# CONFIG_SERIAL_TX3912_CONSOLE is not set
-# CONFIG_SERIAL_TXX9 is not set
-# CONFIG_SERIAL_TXX9_CONSOLE is not set
-CONFIG_AU1X00_UART=y
-CONFIG_AU1X00_SERIAL_CONSOLE=y
-# CONFIG_AU1X00_USB_TTY is not set
-# CONFIG_AU1X00_USB_RAW is not set
-# CONFIG_TXX927_SERIAL is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-# CONFIG_PRINTER is not set
-# CONFIG_PPDEV is not set
-# CONFIG_TIPAR is not set
-
-#
-# I2C support
-#
-CONFIG_I2C=m
-CONFIG_I2C_ALGOBIT=m
-# CONFIG_I2C_PHILIPSPAR is not set
-# CONFIG_I2C_ELV is not set
-# CONFIG_I2C_VELLEMAN is not set
-# CONFIG_SCx200_I2C is not set
-# CONFIG_SCx200_ACB is not set
-# CONFIG_I2C_ALGOPCF is not set
-CONFIG_I2C_CHARDEV=m
-# CONFIG_I2C_PROC is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_IPMI_PANIC_EVENT is not set
-# CONFIG_IPMI_DEVICE_INTERFACE is not set
-# CONFIG_IPMI_KCS is not set
-# CONFIG_IPMI_WATCHDOG is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_SCx200_GPIO is not set
-# CONFIG_AMD_PM768 is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-# CONFIG_PCMCIA_SERIAL_CS is not set
-# CONFIG_SYNCLINK_CS is not set
-# CONFIG_AU1X00_GPIO is not set
-# CONFIG_TS_AU1X00_ADS7846 is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-CONFIG_AUTOFS_FS=m
-CONFIG_AUTOFS4_FS=m
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BEFS_DEBUG is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=m
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=m
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=m
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=2
-# CONFIG_CRAMFS is not set
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-# CONFIG_JFS_FS is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=m
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_TCP is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-CONFIG_ZISOFS_FS=m
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Multimedia devices
-#
-CONFIG_VIDEO_DEV=m
-
-#
-# Video For Linux
-#
-CONFIG_VIDEO_PROC_FS=y
-# CONFIG_I2C_PARPORT is not set
-CONFIG_VIDEO_BT848=m
-# CONFIG_VIDEO_PMS is not set
-CONFIG_VIDEO_BWQCAM=m
-CONFIG_VIDEO_CQCAM=m
-CONFIG_VIDEO_W9966=m
-CONFIG_VIDEO_CPIA=m
-# CONFIG_VIDEO_CPIA_PP is not set
-CONFIG_VIDEO_CPIA_USB=m
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIDEO_ZORAN_BUZ is not set
-# CONFIG_VIDEO_ZORAN_DC10 is not set
-# CONFIG_VIDEO_ZORAN_LML33 is not set
-# CONFIG_VIDEO_ZR36120 is not set
-# CONFIG_VIDEO_MEYE is not set
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_GEMTEK_PCI is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_MAESTRO is not set
-# CONFIG_RADIO_MIROPCM20 is not set
-
-#
-# Console drivers
-#
-CONFIG_VGA_CONSOLE=y
-# CONFIG_MDA_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_CLGEN is not set
-# CONFIG_FB_PM2 is not set
-# CONFIG_FB_PM3 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_MATROX is not set
-# CONFIG_FB_ATY is not set
-# CONFIG_FB_RADEON is not set
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_INTEL is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_NEOMAGIC is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_E1356 is not set
-CONFIG_FB_MB86290=y
-CONFIG_FB_LYNX3DM=y
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-# CONFIG_FBCON_CFB4 is not set
-# CONFIG_FBCON_CFB8 is not set
-CONFIG_FBCON_CFB16=y
-# CONFIG_FBCON_CFB24 is not set
-# CONFIG_FBCON_CFB32 is not set
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA_PLANES is not set
-# CONFIG_FBCON_VGA is not set
-# CONFIG_FBCON_HGA is not set
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_ALI5455 is not set
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_FORTE is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-CONFIG_SOUND_AU1X00=y
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_TVMIXER is not set
-
-#
-# USB support
-#
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_EHCI_HCD is not set
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-CONFIG_USB_OHCI=y
-CONFIG_USB_NON_PCI_OHCI=y
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_BLUETOOTH is not set
-# CONFIG_USB_MIDI is not set
-CONFIG_USB_STORAGE=m
-CONFIG_USB_STORAGE_DEBUG=y
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-CONFIG_USB_STORAGE_SDDR09=y
-# CONFIG_USB_STORAGE_SDDR55 is not set
-CONFIG_USB_STORAGE_JUMPSHOT=y
-# CONFIG_USB_ACM is not set
-CONFIG_USB_PRINTER=m
-CONFIG_USB_HID=m
-# CONFIG_USB_HIDINPUT is not set
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-CONFIG_USB_IBMCAM=m
-CONFIG_USB_KONICAWC=m
-CONFIG_USB_OV511=m
-CONFIG_USB_PWC=m
-CONFIG_USB_SE401=m
-CONFIG_USB_STV680=m
-CONFIG_USB_VICAM=m
-# CONFIG_USB_DSBR is not set
-CONFIG_USB_DABUSB=m
-CONFIG_USB_PEGASUS=m
-CONFIG_USB_RTL8150=m
-CONFIG_USB_KAWETH=m
-CONFIG_USB_CATC=m
-CONFIG_USB_CDCETHER=m
-CONFIG_USB_USBNET=m
-CONFIG_USB_USS720=m
-
-#
-# USB Serial Converter support
-#
-CONFIG_USB_SERIAL=m
-# CONFIG_USB_SERIAL_DEBUG is not set
-CONFIG_USB_SERIAL_GENERIC=y
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_KOBIL_SCT is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_TIGL is not set
-# CONFIG_USB_BRLVGER is not set
-CONFIG_USB_LCD=m
-
-#
-# Bluetooth support
-#
-# CONFIG_BLUEZ is not set
-
-#
-# Kernel hacking
-#
-CONFIG_CROSSCOMPILE=y
-# CONFIG_RUNTIME_DEBUG is not set
-# CONFIG_KGDB is not set
-# CONFIG_GDB_CONSOLE is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_MIPS_UNCACHED is not set
-
-#
-# Library routines
-#
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/linux-xxs1500-2.4.21/zboot-Makefile-flags.diff b/linux/linux-xxs1500-2.4.21/zboot-Makefile-flags.diff
deleted file mode 100644
index da17a12f38..0000000000
--- a/linux/linux-xxs1500-2.4.21/zboot-Makefile-flags.diff
+++ /dev/null
@@ -1,11 +0,0 @@
---- arch/mips/zboot/Makefile.o 2004-10-09 19:44:27.380145288 +0200
-+++ arch/mips/zboot/Makefile 2004-10-09 19:46:17.643382728 +0200
-@@ -27,7 +27,7 @@
-
- CFLAGS := $(CPPFLAGS) -O2 -D__BOOTER__ \
- -fomit-frame-pointer -fno-strict-aliasing -fno-common \
-- -G 0 -mno-abicalls -fno-pic -mcpu=r4600 -mips2 \
-+ -G 0 -mno-abicalls -fno-pic -mabi=32 -march=mips32 -mips32 \
- -I$(TOPDIR)/arch/$(ARCH)/zboot/include \
- -I$(TOPDIR)/include/asm
- AFLAGS += -D__BOOTER__
diff --git a/linux/linux-xxs1500_2.4.21.bb b/linux/linux-xxs1500_2.4.21.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/linux-xxs1500_2.4.21.bb
+++ /dev/null
diff --git a/linux/mnci-ramses-2.4.21-rmk2-pxa1.bb b/linux/mnci-ramses-2.4.21-rmk2-pxa1.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/mnci-ramses-2.4.21-rmk2-pxa1.bb
+++ /dev/null
diff --git a/linux/mnci-ramses-2.4.21-rmk2-pxa1/diff-2.4.21-rmk2-pxa1.gz b/linux/mnci-ramses-2.4.21-rmk2-pxa1/diff-2.4.21-rmk2-pxa1.gz
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/mnci-ramses-2.4.21-rmk2-pxa1/diff-2.4.21-rmk2-pxa1.gz
+++ /dev/null
diff --git a/linux/mnci-ramses-2.4.21-rmk2-pxa1/mnci-combined.patch b/linux/mnci-ramses-2.4.21-rmk2-pxa1/mnci-combined.patch
deleted file mode 100644
index 55d91b9a36..0000000000
--- a/linux/mnci-ramses-2.4.21-rmk2-pxa1/mnci-combined.patch
+++ /dev/null
@@ -1,19914 +0,0 @@
-
-# This is a cumulative patch consisting of:
-#
-# linux-vtcomparison.patch
-# linux-mkdep.patch
-# linux-iw241_we16-6.patch
-# arm-noshortloads.patch
-# pxa-pcmcia.patch
-# pxa-smc91x.patch
-# pxa-usb.patch
-# pxa-usbeth.patch
-# pxa-irda.patch
-# pxa-ac97.patch
-# pxa-timerint.patch
-# fb-buffered.patch
-# fb-turn180.patch
-# i2c-ds1337.patch
-# keyb-input.patch
-# keyb-module.patch
-# logo-noscrollregion.patch
-# net-dhcp-timeout.patch
-# pm.patch
-# swap-performance.patch
-# small-nocramdisk.patch
-# smc91x-ethtool.patch
-# ucb1x00.patch
-# vmalloc.patch
-# usb-sl811.patch
-# orinoco013e.patch
-# ramses.patch
-# ramses-ac97.patch
-# ramses-keyb.patch
-# ramses-mtd.patch
-# ramses-orinoco-ignorecis.patch
-# ramses-pcmcia.patch
-# ramses-serial.patch
-# ramses-smc91x.patch
-# ramses-sysctl.patch
-# ramses-ucb1x00-dejitter.patch
-# ramses-lcd.patch
-# ramses-usb.patch
-# ramses-corevolt.patch
-# wedge.patch
-# usb-sonycamera.patch
-# ramses-ucb1x00-rotate.patch
-# vt-noblank.patch
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- linux-2.4.21/Makefile~linux-mkdep
-+++ linux-2.4.21/Makefile
-@@ -14,10 +14,11 @@
- else echo sh; fi ; fi)
- TOPDIR := $(shell /bin/pwd)
-
-+PATH := /usr/local/arm/3.3/bin:$(PATH)
- HPATH = $(TOPDIR)/include
- FINDHPATH = $(HPATH)/asm $(HPATH)/linux $(HPATH)/scsi $(HPATH)/net $(HPATH)/math-emu
-
--HOSTCC = gcc
-+HOSTCC = ccache gcc
- HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
-
- CROSS_COMPILE = arm-linux-
-@@ -28,7 +29,7 @@
-
- AS = $(CROSS_COMPILE)as
- LD = $(CROSS_COMPILE)ld
--CC = $(CROSS_COMPILE)gcc
-+CC = ccache $(CROSS_COMPILE)gcc
- CPP = $(CC) -E
- AR = $(CROSS_COMPILE)ar
- NM = $(CROSS_COMPILE)nm
-@@ -80,6 +81,7 @@
- # makefile but the arguement can be passed to make if needed.
- #
-
-+export INSTALL_MOD_PATH = /tftpboot/ramses2
- MODLIB := $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
- export MODLIB
-
-@@ -140,7 +142,6 @@
- DRIVERS-y += drivers/serial/serial.o \
- drivers/char/char.o \
- drivers/block/block.o \
-- drivers/misc/misc.o \
- drivers/net/net.o
- DRIVERS-$(CONFIG_AGP) += drivers/char/agp/agp.o
- DRIVERS-$(CONFIG_DRM_NEW) += drivers/char/drm/drm.o
-@@ -197,6 +198,7 @@
- DRIVERS-$(CONFIG_ISDN_BOOL) += drivers/isdn/vmlinux-obj.o
- DRIVERS-$(CONFIG_PLD) += drivers/pld/pld.o
- DRIVERS-$(CONFIG_ARCH_AT91RM9200) += drivers/at91/at91drv.o
-+DRIVERS-y += drivers/misc/misc.o
-
- DRIVERS := $(DRIVERS-y)
-
-@@ -416,7 +418,7 @@
- endif
- .PHONY: _modinst_post
- _modinst_post: _modinst_post_pcmcia
-- if [ -r System.map ]; then $(DEPMOD) -ae -F System.map $(depmod_opts) $(KERNELRELEASE); fi
-+# if [ -r System.map ]; then $(DEPMOD) -ae -F System.map $(depmod_opts) $(KERNELRELEASE); fi
-
- # Backwards compatibilty symlinks for people still using old versions
- # of pcmcia-cs with hard coded pathnames on insmod. Remove
-@@ -495,7 +497,7 @@
- ifdef CONFIG_MODVERSIONS
- $(MAKE) update-modverfile
- endif
-- scripts/mkdep -- `find $(FINDHPATH) \( -name SCCS -o -name .svn \) -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend
-+ $(foreach, dir, $(FINDHPATH), scripts/mkdep -- `find $(dir) -name SCCS -prune -o -follow -name \*.h ! -name modversions.h -print` >> .hdepend)
- scripts/mkdep -- init/*.c > .depend
-
- ifdef CONFIG_MODVERSIONS
-@@ -574,3 +576,14 @@
- . scripts/mkversion > .version ; \
- rpm -ta $(TOPDIR)/../$(KERNELPATH).tar.gz ; \
- rm $(TOPDIR)/../$(KERNELPATH).tar.gz
-+
-+
-+
-+#
-+# Burn Linux Image for ArmBoot using the bdi2000
-+#
-+burn burn_zImage:
-+ python ../hwtester/burner.py arch/arm/boot/zImage 0x40000
-+
-+publish: arch/arm/boot/zImage
-+ cp arch/arm/boot/zImage /tftpboot/bdi/zImage.testing
---- linux-2.4.21/arch/arm/Makefile~arm-noshortloads
-+++ linux-2.4.21/arch/arm/Makefile
-@@ -55,8 +55,8 @@
- #tune-$(CONFIG_CPU_XSCALE) :=-mtune=xscale
- tune-$(CONFIG_CPU_XSCALE) :=-mtune=strongarm
-
--CFLAGS_BOOT :=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Uarm
--CFLAGS +=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Uarm
-+CFLAGS_BOOT :=$(apcs-y) $(arch-y) $(tune-y) -msoft-float -Uarm
-+CFLAGS +=$(apcs-y) $(arch-y) $(tune-y) -msoft-float -Uarm
- AFLAGS +=$(apcs-y) $(arch-y) -msoft-float
-
- ifeq ($(CONFIG_CPU_26),y)
-@@ -289,7 +289,7 @@
- arch/arm/kernel arch/arm/mm arch/arm/lib: dummy
- $(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@)
-
--bzImage zImage zinstall Image xipImage bootpImage install: vmlinux
-+bzImage zImage zinstall Image xipImage bootpImage: vmlinux
- @$(MAKEBOOT) $@
-
- CLEAN_FILES += \
---- linux-2.4.21/arch/arm/config.in~pm
-+++ linux-2.4.21/arch/arm/config.in
-@@ -152,6 +152,7 @@
- dep_bool ' Intel DBPXA250 Development Platform' CONFIG_ARCH_LUBBOCK $CONFIG_ARCH_PXA
- dep_bool ' Accelent Xscale IDP' CONFIG_ARCH_PXA_IDP $CONFIG_ARCH_PXA
- dep_bool ' Intrinsyc CerfBoard' CONFIG_ARCH_PXA_CERF $CONFIG_ARCH_PXA
-+dep_bool ' M und N Ramses' CONFIG_ARCH_RAMSES $CONFIG_ARCH_PXA
- dep_bool ' Trizeps-II MT6N' CONFIG_ARCH_TRIZEPS2 $CONFIG_ARCH_PXA
-
- if [ "$CONFIG_ARCH_PXA_CERF" = "y" ]; then
-@@ -586,6 +587,7 @@
- tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
- tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
- dep_bool 'Power Management support (experimental)' CONFIG_PM $CONFIG_EXPERIMENTAL
-+dep_bool 'Advanced power management emulation support' CONFIG_APM $CONFIG_PM
- dep_tristate 'RISC OS personality' CONFIG_ARTHUR $CONFIG_CPU_32
- string 'Default kernel command string' CONFIG_CMDLINE ""
-
---- /dev/null
-+++ linux-2.4.21/arch/arm/def-configs/ramses
-@@ -0,0 +1,1128 @@
-+#
-+# Automatically generated by make menuconfig: don't edit
-+#
-+CONFIG_ARM=y
-+# CONFIG_EISA is not set
-+# CONFIG_SBUS is not set
-+# CONFIG_MCA is not set
-+CONFIG_UID16=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-+# CONFIG_GENERIC_BUST_SPINLOCK is not set
-+# CONFIG_GENERIC_ISA_DMA is not set
-+
-+#
-+# Code maturity level options
-+#
-+CONFIG_EXPERIMENTAL=y
-+# CONFIG_OBSOLETE is not set
-+
-+#
-+# Loadable module support
-+#
-+CONFIG_MODULES=y
-+# CONFIG_MODVERSIONS is not set
-+CONFIG_KMOD=y
-+
-+#
-+# System Type
-+#
-+# CONFIG_ARCH_ANAKIN is not set
-+# CONFIG_ARCH_ARCA5K is not set
-+# CONFIG_ARCH_CLPS7500 is not set
-+# CONFIG_ARCH_CLPS711X is not set
-+# CONFIG_ARCH_CO285 is not set
-+CONFIG_ARCH_PXA=y
-+# CONFIG_ARCH_EBSA110 is not set
-+# CONFIG_ARCH_CAMELOT is not set
-+# CONFIG_ARCH_FOOTBRIDGE is not set
-+# CONFIG_ARCH_INTEGRATOR is not set
-+# CONFIG_ARCH_OMAHA is not set
-+# CONFIG_ARCH_L7200 is not set
-+# CONFIG_ARCH_MX1ADS is not set
-+# CONFIG_ARCH_RPC is not set
-+# CONFIG_ARCH_RISCSTATION is not set
-+# CONFIG_ARCH_SA1100 is not set
-+# CONFIG_ARCH_SHARK is not set
-+# CONFIG_ARCH_AT91RM9200 is not set
-+
-+#
-+# Archimedes/A5000 Implementations
-+#
-+# CONFIG_ARCH_ARC is not set
-+# CONFIG_ARCH_A5K is not set
-+
-+#
-+# Footbridge Implementations
-+#
-+# CONFIG_ARCH_CATS is not set
-+# CONFIG_ARCH_PERSONAL_SERVER is not set
-+# CONFIG_ARCH_EBSA285_ADDIN is not set
-+# CONFIG_ARCH_EBSA285_HOST is not set
-+# CONFIG_ARCH_NETWINDER is not set
-+
-+#
-+# SA11x0 Implementations
-+#
-+# CONFIG_SA1100_ACCELENT is not set
-+# CONFIG_SA1100_ASSABET is not set
-+# CONFIG_ASSABET_NEPONSET is not set
-+# CONFIG_SA1100_ADSAGC is not set
-+# CONFIG_SA1100_ADSBITSY is not set
-+# CONFIG_SA1100_ADSBITSYPLUS is not set
-+# CONFIG_SA1100_BRUTUS is not set
-+# CONFIG_SA1100_CEP is not set
-+# CONFIG_SA1100_CERF is not set
-+# CONFIG_SA1100_H3100 is not set
-+# CONFIG_SA1100_H3600 is not set
-+# CONFIG_SA1100_H3800 is not set
-+# CONFIG_SA1100_H3XXX is not set
-+# CONFIG_H3600_SLEEVE is not set
-+# CONFIG_SA1100_EXTENEX1 is not set
-+# CONFIG_SA1100_FLEXANET is not set
-+# CONFIG_SA1100_FREEBIRD is not set
-+# CONFIG_SA1100_FRODO is not set
-+# CONFIG_SA1100_GRAPHICSCLIENT is not set
-+# CONFIG_SA1100_GRAPHICSMASTER is not set
-+# CONFIG_SA1100_HACKKIT is not set
-+# CONFIG_SA1100_BADGE4 is not set
-+# CONFIG_SA1100_JORNADA720 is not set
-+# CONFIG_SA1100_HUW_WEBPANEL is not set
-+# CONFIG_SA1100_ITSY is not set
-+# CONFIG_SA1100_LART is not set
-+# CONFIG_SA1100_NANOENGINE is not set
-+# CONFIG_SA1100_OMNIMETER is not set
-+# CONFIG_SA1100_PANGOLIN is not set
-+# CONFIG_SA1100_PLEB is not set
-+# CONFIG_SA1100_PT_SYSTEM3 is not set
-+# CONFIG_SA1100_SHANNON is not set
-+# CONFIG_SA1100_SHERMAN is not set
-+# CONFIG_SA1100_SIMPAD is not set
-+# CONFIG_SA1100_SIMPUTER is not set
-+# CONFIG_SA1100_PFS168 is not set
-+# CONFIG_SA1100_VICTOR is not set
-+# CONFIG_SA1100_XP860 is not set
-+# CONFIG_SA1100_YOPY is not set
-+# CONFIG_SA1100_USB is not set
-+# CONFIG_SA1100_USB_NETLINK is not set
-+# CONFIG_SA1100_USB_CHAR is not set
-+# CONFIG_SA1100_SSP is not set
-+
-+#
-+# AT91RM9200 Implementations
-+#
-+# CONFIG_ARCH_AT91RM9200DK is not set
-+
-+#
-+# Intel PXA250/210 Implementations
-+#
-+# CONFIG_ARCH_LUBBOCK is not set
-+# CONFIG_ARCH_PXA_IDP is not set
-+# CONFIG_ARCH_PXA_CERF is not set
-+CONFIG_ARCH_RAMSES=y
-+# CONFIG_ARCH_TRIZEPS2 is not set
-+CONFIG_PXA_USB=m
-+CONFIG_PXA_USB_NETLINK=m
-+CONFIG_PXA_USB_CHAR=m
-+
-+#
-+# CLPS711X/EP721X Implementations
-+#
-+# CONFIG_ARCH_AUTCPU12 is not set
-+# CONFIG_ARCH_CDB89712 is not set
-+# CONFIG_ARCH_CLEP7312 is not set
-+# CONFIG_ARCH_EDB7211 is not set
-+# CONFIG_ARCH_FORTUNET is not set
-+# CONFIG_ARCH_GUIDEA07 is not set
-+# CONFIG_ARCH_P720T is not set
-+# CONFIG_ARCH_EP7211 is not set
-+# CONFIG_ARCH_EP7212 is not set
-+# CONFIG_ARCH_ACORN is not set
-+# CONFIG_PLD is not set
-+# CONFIG_FOOTBRIDGE is not set
-+# CONFIG_FOOTBRIDGE_HOST is not set
-+# CONFIG_FOOTBRIDGE_ADDIN is not set
-+CONFIG_CPU_32=y
-+# CONFIG_CPU_26 is not set
-+# CONFIG_CPU_ARM610 is not set
-+# CONFIG_CPU_ARM710 is not set
-+# CONFIG_CPU_ARM720T is not set
-+# CONFIG_CPU_ARM920T is not set
-+# CONFIG_CPU_ARM922T is not set
-+# CONFIG_CPU_ARM926T is not set
-+# CONFIG_CPU_ARM1020 is not set
-+# CONFIG_CPU_ARM1020E is not set
-+# CONFIG_CPU_ARM1022 is not set
-+# CONFIG_CPU_ARM1026 is not set
-+# CONFIG_CPU_SA110 is not set
-+# CONFIG_CPU_SA1100 is not set
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_XSCALE=y
-+# CONFIG_XSCALE_CACHE_ERRATA is not set
-+# CONFIG_CPU_32v3 is not set
-+# CONFIG_CPU_32v4 is not set
-+# CONFIG_DISCONTIGMEM is not set
-+
-+#
-+# General setup
-+#
-+# CONFIG_PCI is not set
-+# CONFIG_ISA is not set
-+# CONFIG_ISA_DMA is not set
-+CONFIG_ZBOOT_ROM=y
-+CONFIG_ZBOOT_ROM_TEXT=00040000
-+CONFIG_ZBOOT_ROM_BSS=a00c0000
-+CONFIG_CPU_FREQ=y
-+CONFIG_HOTPLUG=y
-+
-+#
-+# PCMCIA/CardBus support
-+#
-+CONFIG_PCMCIA=y
-+# CONFIG_I82092 is not set
-+# CONFIG_I82365 is not set
-+# CONFIG_TCIC is not set
-+# CONFIG_PCMCIA_CLPS6700 is not set
-+# CONFIG_PCMCIA_SA1100 is not set
-+CONFIG_PCMCIA_PXA=y
-+
-+#
-+# MMC device drivers
-+#
-+CONFIG_MMC=m
-+CONFIG_MMC_PXA=m
-+CONFIG_MMC_BLOCK=m
-+CONFIG_MMC_PARTITIONS=y
-+CONFIG_NET=y
-+CONFIG_SYSVIPC=y
-+# CONFIG_BSD_PROCESS_ACCT is not set
-+CONFIG_SYSCTL=y
-+# CONFIG_XIP_KERNEL is not set
-+CONFIG_FPE_NWFPE=y
-+# CONFIG_FPE_NWFPE_XP is not set
-+# CONFIG_FPE_FASTFPE is not set
-+CONFIG_KCORE_ELF=y
-+# CONFIG_KCORE_AOUT is not set
-+# CONFIG_BINFMT_AOUT is not set
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_MISC is not set
-+CONFIG_PM=y
-+CONFIG_APM=y
-+# CONFIG_ARTHUR is not set
-+CONFIG_CMDLINE="debug"
-+CONFIG_ALIGNMENT_TRAP=y
-+
-+#
-+# Parallel port support
-+#
-+# CONFIG_PARPORT is not set
-+
-+#
-+# Memory Technology Devices (MTD)
-+#
-+CONFIG_MTD=y
-+# CONFIG_MTD_DEBUG is not set
-+CONFIG_MTD_PARTITIONS=y
-+# CONFIG_MTD_CONCAT is not set
-+# CONFIG_MTD_REDBOOT_PARTS is not set
-+# CONFIG_MTD_CMDLINE_PARTS is not set
-+# CONFIG_MTD_AFS_PARTS is not set
-+CONFIG_MTD_CHAR=y
-+CONFIG_MTD_BLOCK=y
-+# CONFIG_FTL is not set
-+# CONFIG_NFTL is not set
-+
-+#
-+# RAM/ROM/Flash chip drivers
-+#
-+CONFIG_MTD_CFI=y
-+# CONFIG_MTD_JEDECPROBE is not set
-+CONFIG_MTD_GEN_PROBE=y
-+CONFIG_MTD_CFI_ADV_OPTIONS=y
-+CONFIG_MTD_CFI_NOSWAP=y
-+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-+CONFIG_MTD_CFI_GEOMETRY=y
-+# CONFIG_MTD_CFI_B1 is not set
-+# CONFIG_MTD_CFI_B2 is not set
-+CONFIG_MTD_CFI_B4=y
-+# CONFIG_MTD_CFI_B8 is not set
-+# CONFIG_MTD_CFI_I1 is not set
-+CONFIG_MTD_CFI_I2=y
-+# CONFIG_MTD_CFI_I4 is not set
-+# CONFIG_MTD_CFI_I8 is not set
-+CONFIG_MTD_CFI_INTELEXT=y
-+# CONFIG_MTD_CFI_AMDSTD is not set
-+# CONFIG_MTD_CFI_STAA is not set
-+# CONFIG_MTD_RAM is not set
-+# CONFIG_MTD_ROM is not set
-+# CONFIG_MTD_ABSENT is not set
-+# CONFIG_MTD_OBSOLETE_CHIPS is not set
-+# CONFIG_MTD_AMDSTD is not set
-+# CONFIG_MTD_SHARP is not set
-+# CONFIG_MTD_JEDEC is not set
-+
-+#
-+# Mapping drivers for chip access
-+#
-+# CONFIG_MTD_PHYSMAP is not set
-+# CONFIG_MTD_LUBBOCK is not set
-+CONFIG_MTD_RAMSES=y
-+# CONFIG_MTD_NORA is not set
-+# CONFIG_MTD_ARM_INTEGRATOR is not set
-+# CONFIG_MTD_CDB89712 is not set
-+# CONFIG_MTD_SA1100 is not set
-+# CONFIG_MTD_DC21285 is not set
-+# CONFIG_MTD_IQ80310 is not set
-+# CONFIG_MTD_FORTUNET is not set
-+# CONFIG_MTD_EPXA is not set
-+# CONFIG_MTD_AUTCPU12 is not set
-+# CONFIG_MTD_EDB7312 is not set
-+# CONFIG_MTD_IMPA7 is not set
-+# CONFIG_MTD_CEIVA is not set
-+# CONFIG_MTD_PCI is not set
-+# CONFIG_MTD_PCMCIA is not set
-+
-+#
-+# Self-contained MTD device drivers
-+#
-+# CONFIG_MTD_PMC551 is not set
-+# CONFIG_MTD_SLRAM is not set
-+# CONFIG_MTD_MTDRAM is not set
-+# CONFIG_MTD_BLKMTD is not set
-+# CONFIG_MTD_DOC1000 is not set
-+# CONFIG_MTD_DOC2000 is not set
-+# CONFIG_MTD_DOC2001 is not set
-+# CONFIG_MTD_DOCPROBE is not set
-+
-+#
-+# NAND Flash Device Drivers
-+#
-+# CONFIG_MTD_NAND is not set
-+
-+#
-+# Plug and Play configuration
-+#
-+# CONFIG_PNP is not set
-+# CONFIG_ISAPNP is not set
-+
-+#
-+# Block devices
-+#
-+# CONFIG_BLK_DEV_FD is not set
-+# CONFIG_BLK_DEV_XD is not set
-+# CONFIG_PARIDE is not set
-+# CONFIG_BLK_CPQ_DA is not set
-+# CONFIG_BLK_CPQ_CISS_DA is not set
-+# CONFIG_CISS_SCSI_TAPE is not set
-+# CONFIG_BLK_DEV_DAC960 is not set
-+# CONFIG_BLK_DEV_UMEM is not set
-+CONFIG_BLK_DEV_LOOP=m
-+CONFIG_BLK_DEV_NBD=m
-+# CONFIG_BLK_DEV_RAM is not set
-+# CONFIG_BLK_DEV_INITRD is not set
-+CONFIG_BLK_STATS=y
-+
-+#
-+# Multi-device support (RAID and LVM)
-+#
-+# CONFIG_MD is not set
-+# CONFIG_BLK_DEV_MD is not set
-+# CONFIG_MD_LINEAR is not set
-+# CONFIG_MD_RAID0 is not set
-+# CONFIG_MD_RAID1 is not set
-+# CONFIG_MD_RAID5 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_BLK_DEV_LVM is not set
-+
-+#
-+# Networking options
-+#
-+CONFIG_PACKET=y
-+# CONFIG_PACKET_MMAP is not set
-+CONFIG_NETLINK_DEV=m
-+# CONFIG_NETFILTER is not set
-+# CONFIG_FILTER is not set
-+CONFIG_UNIX=y
-+CONFIG_INET=y
-+# CONFIG_IP_MULTICAST is not set
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+CONFIG_IP_PNP=y
-+CONFIG_IP_PNP_DHCP=y
-+# CONFIG_IP_PNP_BOOTP is not set
-+# CONFIG_IP_PNP_RARP is not set
-+CONFIG_NET_IPIP=m
-+CONFIG_NET_IPGRE=m
-+# CONFIG_ARPD is not set
-+# CONFIG_INET_ECN is not set
-+# CONFIG_SYN_COOKIES is not set
-+# CONFIG_IPV6 is not set
-+# CONFIG_KHTTPD is not set
-+# CONFIG_ATM is not set
-+CONFIG_VLAN_8021Q=m
-+# CONFIG_IPX is not set
-+# CONFIG_ATALK is not set
-+
-+#
-+# Appletalk devices
-+#
-+# CONFIG_DEV_APPLETALK is not set
-+# CONFIG_DECNET is not set
-+CONFIG_BRIDGE=m
-+# CONFIG_X25 is not set
-+# CONFIG_LAPB is not set
-+# CONFIG_LLC is not set
-+# CONFIG_NET_DIVERT is not set
-+# CONFIG_ECONET is not set
-+# CONFIG_WAN_ROUTER is not set
-+# CONFIG_NET_FASTROUTE is not set
-+# CONFIG_NET_HW_FLOWCONTROL is not set
-+
-+#
-+# QoS and/or fair queueing
-+#
-+# CONFIG_NET_SCHED is not set
-+
-+#
-+# Network testing
-+#
-+# CONFIG_NET_PKTGEN is not set
-+
-+#
-+# Network device support
-+#
-+CONFIG_NETDEVICES=y
-+
-+#
-+# ARCnet devices
-+#
-+# CONFIG_ARCNET is not set
-+# CONFIG_DUMMY is not set
-+# CONFIG_BONDING is not set
-+# CONFIG_EQUALIZER is not set
-+# CONFIG_TUN is not set
-+# CONFIG_ETHERTAP is not set
-+
-+#
-+# Ethernet (10 or 100Mbit)
-+#
-+CONFIG_NET_ETHERNET=y
-+# CONFIG_ARM_AM79C961A is not set
-+# CONFIG_ARM_CIRRUS is not set
-+# CONFIG_SUNLANCE is not set
-+# CONFIG_SUNBMAC is not set
-+# CONFIG_SUNQE is not set
-+# CONFIG_SUNGEM is not set
-+# CONFIG_NET_VENDOR_3COM is not set
-+# CONFIG_LANCE is not set
-+CONFIG_NET_VENDOR_SMC=y
-+# CONFIG_WD80x3 is not set
-+# CONFIG_ULTRAMCA is not set
-+# CONFIG_ULTRA is not set
-+# CONFIG_ULTRA32 is not set
-+# CONFIG_SMC9194 is not set
-+CONFIG_SMC91X=y
-+# CONFIG_NET_VENDOR_RACAL is not set
-+# CONFIG_NET_ISA is not set
-+# CONFIG_NET_PCI is not set
-+# CONFIG_NET_POCKET is not set
-+
-+#
-+# Ethernet (1000 Mbit)
-+#
-+# CONFIG_ACENIC is not set
-+# CONFIG_DL2K is not set
-+# CONFIG_E1000 is not set
-+# CONFIG_MYRI_SBUS is not set
-+# CONFIG_NS83820 is not set
-+# CONFIG_HAMACHI is not set
-+# CONFIG_YELLOWFIN is not set
-+# CONFIG_R8169 is not set
-+# CONFIG_SK98LIN is not set
-+# CONFIG_TIGON3 is not set
-+# CONFIG_FDDI is not set
-+# CONFIG_HIPPI is not set
-+# CONFIG_PLIP is not set
-+CONFIG_PPP=m
-+# CONFIG_PPP_MULTILINK is not set
-+# CONFIG_PPP_FILTER is not set
-+CONFIG_PPP_ASYNC=m
-+CONFIG_PPP_SYNC_TTY=m
-+CONFIG_PPP_DEFLATE=m
-+CONFIG_PPP_BSDCOMP=m
-+CONFIG_PPPOE=m
-+# CONFIG_SLIP is not set
-+
-+#
-+# Wireless LAN (non-hamradio)
-+#
-+CONFIG_NET_RADIO=y
-+# CONFIG_STRIP is not set
-+# CONFIG_WAVELAN is not set
-+# CONFIG_ARLAN is not set
-+# CONFIG_AIRONET4500 is not set
-+# CONFIG_AIRONET4500_NONCS is not set
-+# CONFIG_AIRONET4500_PROC is not set
-+CONFIG_HERMES=m
-+CONFIG_PCMCIA_HERMES=m
-+# CONFIG_AIRO_CS is not set
-+CONFIG_NET_WIRELESS=y
-+
-+#
-+# Token Ring devices
-+#
-+# CONFIG_TR is not set
-+# CONFIG_NET_FC is not set
-+# CONFIG_RCPCI is not set
-+# CONFIG_SHAPER is not set
-+
-+#
-+# Wan interfaces
-+#
-+# CONFIG_WAN is not set
-+
-+#
-+# PCMCIA network device support
-+#
-+CONFIG_NET_PCMCIA=y
-+# CONFIG_PCMCIA_3C589 is not set
-+# CONFIG_PCMCIA_3C574 is not set
-+# CONFIG_PCMCIA_FMVJ18X is not set
-+# CONFIG_PCMCIA_PCNET is not set
-+# CONFIG_PCMCIA_AXNET is not set
-+# CONFIG_PCMCIA_NMCLAN is not set
-+# CONFIG_PCMCIA_SMC91C92 is not set
-+# CONFIG_PCMCIA_XIRC2PS is not set
-+# CONFIG_ARCNET_COM20020_CS is not set
-+# CONFIG_PCMCIA_IBMTR is not set
-+# CONFIG_NET_PCMCIA_RADIO is not set
-+
-+#
-+# Amateur Radio support
-+#
-+# CONFIG_HAMRADIO is not set
-+
-+#
-+# IrDA (infrared) support
-+#
-+CONFIG_IRDA=m
-+CONFIG_IRLAN=m
-+CONFIG_IRNET=m
-+CONFIG_IRCOMM=m
-+CONFIG_IRDA_ULTRA=y
-+CONFIG_IRDA_CACHE_LAST_LSAP=y
-+CONFIG_IRDA_FAST_RR=y
-+CONFIG_IRDA_DEBUG=y
-+
-+#
-+# Infrared-port device drivers
-+#
-+CONFIG_IRTTY_SIR=m
-+CONFIG_IRPORT_SIR=m
-+# CONFIG_DONGLE is not set
-+# CONFIG_USB_IRDA is not set
-+# CONFIG_NSC_FIR is not set
-+# CONFIG_WINBOND_FIR is not set
-+# CONFIG_TOSHIBA_OLD is not set
-+# CONFIG_TOSHIBA_FIR is not set
-+# CONFIG_SMC_IRCC_FIR is not set
-+# CONFIG_ALI_FIR is not set
-+# CONFIG_VLSI_FIR is not set
-+CONFIG_PXA_FIR=m
-+
-+#
-+# ATA/ATAPI/MFM/RLL support
-+#
-+# CONFIG_IDE is not set
-+# CONFIG_BLK_DEV_IDE_MODES is not set
-+# CONFIG_BLK_DEV_HD is not set
-+
-+#
-+# SCSI support
-+#
-+CONFIG_SCSI=m
-+CONFIG_BLK_DEV_SD=m
-+CONFIG_SD_EXTRA_DEVS=4
-+# CONFIG_CHR_DEV_ST is not set
-+# CONFIG_CHR_DEV_OSST is not set
-+# CONFIG_BLK_DEV_SR is not set
-+# CONFIG_CHR_DEV_SG is not set
-+# CONFIG_SCSI_DEBUG_QUEUES is not set
-+# CONFIG_SCSI_MULTI_LUN is not set
-+# CONFIG_SCSI_CONSTANTS is not set
-+# CONFIG_SCSI_LOGGING is not set
-+
-+#
-+# SCSI low-level drivers
-+#
-+# CONFIG_SCSI_7000FASST is not set
-+# CONFIG_SCSI_ACARD is not set
-+# CONFIG_SCSI_AHA152X is not set
-+# CONFIG_SCSI_AHA1542 is not set
-+# CONFIG_SCSI_AHA1740 is not set
-+# CONFIG_SCSI_AACRAID is not set
-+# CONFIG_SCSI_AIC7XXX is not set
-+# CONFIG_SCSI_AIC79XX is not set
-+# CONFIG_SCSI_AIC7XXX_OLD is not set
-+# CONFIG_SCSI_DPT_I2O is not set
-+# CONFIG_SCSI_ADVANSYS is not set
-+# CONFIG_SCSI_IN2000 is not set
-+# CONFIG_SCSI_AM53C974 is not set
-+# CONFIG_SCSI_MEGARAID is not set
-+# CONFIG_SCSI_BUSLOGIC is not set
-+# CONFIG_SCSI_DMX3191D is not set
-+# CONFIG_SCSI_DTC3280 is not set
-+# CONFIG_SCSI_EATA is not set
-+# CONFIG_SCSI_EATA_DMA is not set
-+# CONFIG_SCSI_EATA_PIO is not set
-+# CONFIG_SCSI_FUTURE_DOMAIN is not set
-+# CONFIG_SCSI_GDTH is not set
-+# CONFIG_SCSI_GENERIC_NCR5380 is not set
-+# CONFIG_SCSI_INITIO is not set
-+# CONFIG_SCSI_INIA100 is not set
-+# CONFIG_SCSI_NCR53C406A is not set
-+# CONFIG_SCSI_NCR53C7xx is not set
-+# CONFIG_SCSI_PAS16 is not set
-+# CONFIG_SCSI_PCI2000 is not set
-+# CONFIG_SCSI_PCI2220I is not set
-+# CONFIG_SCSI_PSI240I is not set
-+# CONFIG_SCSI_QLOGIC_FAS is not set
-+# CONFIG_SCSI_SIM710 is not set
-+# CONFIG_SCSI_SYM53C416 is not set
-+# CONFIG_SCSI_T128 is not set
-+# CONFIG_SCSI_U14_34F is not set
-+# CONFIG_SCSI_NSP32 is not set
-+# CONFIG_SCSI_DEBUG is not set
-+
-+#
-+# PCMCIA SCSI adapter support
-+#
-+# CONFIG_SCSI_PCMCIA is not set
-+
-+#
-+# I2O device support
-+#
-+# CONFIG_I2O is not set
-+# CONFIG_I2O_BLOCK is not set
-+# CONFIG_I2O_LAN is not set
-+# CONFIG_I2O_SCSI is not set
-+# CONFIG_I2O_PROC is not set
-+
-+#
-+# ISDN subsystem
-+#
-+# CONFIG_ISDN is not set
-+
-+#
-+# Input core support
-+#
-+CONFIG_INPUT=y
-+CONFIG_INPUT_KEYBDEV=y
-+CONFIG_INPUT_RAMSES_KEYB=y
-+CONFIG_INPUT_RAMSES_WEDGE=y
-+# CONFIG_INPUT_MOUSEDEV is not set
-+# CONFIG_INPUT_JOYDEV is not set
-+CONFIG_INPUT_EVDEV=y
-+# CONFIG_INPUT_MX1TS is not set
-+
-+#
-+# Character devices
-+#
-+CONFIG_VT=y
-+CONFIG_VT_CONSOLE=y
-+CONFIG_SERIAL=y
-+CONFIG_SERIAL_CONSOLE=y
-+# CONFIG_SERIAL_EXTENDED is not set
-+# CONFIG_SERIAL_NONSTANDARD is not set
-+
-+#
-+# Serial drivers
-+#
-+# CONFIG_SERIAL_ANAKIN is not set
-+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-+# CONFIG_SERIAL_AMBA is not set
-+# CONFIG_SERIAL_AMBA_CONSOLE is not set
-+# CONFIG_SERIAL_CLPS711X is not set
-+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-+# CONFIG_SERIAL_21285 is not set
-+# CONFIG_SERIAL_21285_OLD is not set
-+# CONFIG_SERIAL_21285_CONSOLE is not set
-+# CONFIG_SERIAL_UART00 is not set
-+# CONFIG_SERIAL_UART00_CONSOLE is not set
-+# CONFIG_SERIAL_SA1100 is not set
-+# CONFIG_SERIAL_SA1100_CONSOLE is not set
-+# CONFIG_SERIAL_OMAHA is not set
-+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
-+# CONFIG_SERIAL_AT91 is not set
-+# CONFIG_SERIAL_AT91_CONSOLE is not set
-+# CONFIG_SERIAL_8250 is not set
-+# CONFIG_SERIAL_8250_CONSOLE is not set
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+# CONFIG_SERIAL_8250_MANY_PORTS is not set
-+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-+# CONFIG_SERIAL_8250_MULTIPORT is not set
-+# CONFIG_SERIAL_8250_HUB6 is not set
-+CONFIG_UNIX98_PTYS=y
-+CONFIG_UNIX98_PTY_COUNT=32
-+
-+#
-+# I2C support
-+#
-+CONFIG_I2C=y
-+# CONFIG_I2C_ALGOBIT is not set
-+# CONFIG_I2C_ALGOPCF is not set
-+CONFIG_I2C_PXA_ALGO=y
-+CONFIG_I2C_PXA_ADAP=y
-+CONFIG_I2C_CHARDEV=m
-+CONFIG_I2C_PROC=m
-+# CONFIG_I2C_DS1307 is not set
-+CONFIG_I2C_DS1337=y
-+
-+#
-+# L3 serial bus support
-+#
-+# CONFIG_L3 is not set
-+# CONFIG_L3_ALGOBIT is not set
-+# CONFIG_L3_BIT_SA1100_GPIO is not set
-+# CONFIG_L3_SA1111 is not set
-+# CONFIG_BIT_SA1100_GPIO is not set
-+
-+#
-+# Mice
-+#
-+# CONFIG_BUSMOUSE is not set
-+# CONFIG_MOUSE is not set
-+
-+#
-+# Joysticks
-+#
-+# CONFIG_INPUT_GAMEPORT is not set
-+# CONFIG_INPUT_NS558 is not set
-+# CONFIG_INPUT_LIGHTNING is not set
-+# CONFIG_INPUT_PCIGAME is not set
-+# CONFIG_INPUT_CS461X is not set
-+# CONFIG_INPUT_EMU10K1 is not set
-+# CONFIG_INPUT_SERIO is not set
-+# CONFIG_INPUT_SERPORT is not set
-+# CONFIG_INPUT_ANALOG is not set
-+# CONFIG_INPUT_A3D is not set
-+# CONFIG_INPUT_ADI is not set
-+# CONFIG_INPUT_COBRA is not set
-+# CONFIG_INPUT_GF2K is not set
-+# CONFIG_INPUT_GRIP is not set
-+# CONFIG_INPUT_INTERACT is not set
-+# CONFIG_INPUT_TMDC is not set
-+# CONFIG_INPUT_SIDEWINDER is not set
-+# CONFIG_INPUT_IFORCE_USB is not set
-+# CONFIG_INPUT_IFORCE_232 is not set
-+# CONFIG_INPUT_WARRIOR is not set
-+# CONFIG_INPUT_MAGELLAN is not set
-+# CONFIG_INPUT_SPACEORB is not set
-+# CONFIG_INPUT_SPACEBALL is not set
-+# CONFIG_INPUT_STINGER is not set
-+# CONFIG_INPUT_DB9 is not set
-+# CONFIG_INPUT_GAMECON is not set
-+# CONFIG_INPUT_TURBOGRAFX is not set
-+# CONFIG_QIC02_TAPE is not set
-+# CONFIG_IPMI_HANDLER is not set
-+# CONFIG_IPMI_PANIC_EVENT is not set
-+# CONFIG_IPMI_DEVICE_INTERFACE is not set
-+# CONFIG_IPMI_KCS is not set
-+# CONFIG_IPMI_WATCHDOG is not set
-+
-+#
-+# Watchdog Cards
-+#
-+# CONFIG_WATCHDOG is not set
-+# CONFIG_SCx200_GPIO is not set
-+# CONFIG_AMD_PM768 is not set
-+# CONFIG_NVRAM is not set
-+CONFIG_RTC=m
-+CONFIG_PXA_RTC=m
-+# CONFIG_DTLK is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_APPLICOM is not set
-+
-+#
-+# Ftape, the floppy tape device driver
-+#
-+# CONFIG_FTAPE is not set
-+# CONFIG_AGP is not set
-+# CONFIG_DRM is not set
-+
-+#
-+# PCMCIA character devices
-+#
-+# CONFIG_PCMCIA_SERIAL_CS is not set
-+# CONFIG_SYNCLINK_CS is not set
-+
-+#
-+# Multimedia devices
-+#
-+CONFIG_VIDEO_DEV=m
-+
-+#
-+# Video For Linux
-+#
-+CONFIG_VIDEO_PROC_FS=y
-+# CONFIG_I2C_PARPORT is not set
-+# CONFIG_VIDEO_BT848 is not set
-+# CONFIG_VIDEO_PMS is not set
-+# CONFIG_VIDEO_CPIA is not set
-+# CONFIG_VIDEO_SAA5249 is not set
-+# CONFIG_TUNER_3036 is not set
-+# CONFIG_VIDEO_STRADIS is not set
-+# CONFIG_VIDEO_ZORAN is not set
-+# CONFIG_VIDEO_ZORAN_BUZ is not set
-+# CONFIG_VIDEO_ZORAN_DC10 is not set
-+# CONFIG_VIDEO_ZORAN_LML33 is not set
-+# CONFIG_VIDEO_ZR36120 is not set
-+# CONFIG_VIDEO_MEYE is not set
-+# CONFIG_VIDEO_CYBERPRO is not set
-+
-+#
-+# Radio Adapters
-+#
-+# CONFIG_RADIO_GEMTEK_PCI is not set
-+# CONFIG_RADIO_MAXIRADIO is not set
-+# CONFIG_RADIO_MAESTRO is not set
-+# CONFIG_RADIO_MIROPCM20 is not set
-+
-+#
-+# File systems
-+#
-+# CONFIG_QUOTA is not set
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+# CONFIG_REISERFS_FS is not set
-+# CONFIG_REISERFS_CHECK is not set
-+# CONFIG_REISERFS_PROC_INFO is not set
-+# CONFIG_ADFS_FS is not set
-+# CONFIG_ADFS_FS_RW is not set
-+# CONFIG_AFFS_FS is not set
-+# CONFIG_HFS_FS is not set
-+# CONFIG_BEFS_FS is not set
-+# CONFIG_BEFS_DEBUG is not set
-+# CONFIG_BFS_FS is not set
-+# CONFIG_EXT3_FS is not set
-+# CONFIG_JBD is not set
-+# CONFIG_JBD_DEBUG is not set
-+CONFIG_FAT_FS=m
-+CONFIG_MSDOS_FS=m
-+# CONFIG_UMSDOS_FS is not set
-+CONFIG_VFAT_FS=m
-+# CONFIG_EFS_FS is not set
-+# CONFIG_JFFS_FS is not set
-+CONFIG_JFFS2_FS=y
-+CONFIG_JFFS2_FS_DEBUG=0
-+CONFIG_CRAMFS=m
-+# CONFIG_CRAMFS_LINEAR is not set
-+# CONFIG_CRAMFS_LINEAR_XIP is not set
-+# CONFIG_ROOT_CRAMFS_LINEAR is not set
-+CONFIG_TMPFS=y
-+CONFIG_RAMFS=y
-+# CONFIG_ISO9660_FS is not set
-+# CONFIG_JOLIET is not set
-+# CONFIG_ZISOFS is not set
-+# CONFIG_JFS_FS is not set
-+# CONFIG_JFS_DEBUG is not set
-+# CONFIG_JFS_STATISTICS is not set
-+# CONFIG_MINIX_FS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_NTFS_FS is not set
-+# CONFIG_NTFS_RW is not set
-+# CONFIG_HPFS_FS is not set
-+CONFIG_PROC_FS=y
-+CONFIG_DEVFS_FS=y
-+CONFIG_DEVFS_MOUNT=y
-+# CONFIG_DEVFS_DEBUG is not set
-+# CONFIG_DEVPTS_FS is not set
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_QNX4FS_RW is not set
-+# CONFIG_ROMFS_FS is not set
-+CONFIG_EXT2_FS=m
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UDF_FS is not set
-+# CONFIG_UDF_RW is not set
-+# CONFIG_UFS_FS is not set
-+# CONFIG_UFS_FS_WRITE is not set
-+
-+#
-+# Network File Systems
-+#
-+# CONFIG_CODA_FS is not set
-+# CONFIG_INTERMEZZO_FS is not set
-+CONFIG_NFS_FS=y
-+# CONFIG_NFS_V3 is not set
-+CONFIG_ROOT_NFS=y
-+# CONFIG_NFSD is not set
-+# CONFIG_NFSD_V3 is not set
-+# CONFIG_NFSD_TCP is not set
-+CONFIG_SUNRPC=y
-+CONFIG_LOCKD=y
-+# CONFIG_SMB_FS is not set
-+# CONFIG_NCP_FS is not set
-+# CONFIG_NCPFS_PACKET_SIGNING is not set
-+# CONFIG_NCPFS_IOCTL_LOCKING is not set
-+# CONFIG_NCPFS_STRONG is not set
-+# CONFIG_NCPFS_NFS_NS is not set
-+# CONFIG_NCPFS_OS2_NS is not set
-+# CONFIG_NCPFS_SMALLDOS is not set
-+# CONFIG_NCPFS_NLS is not set
-+# CONFIG_NCPFS_EXTRAS is not set
-+# CONFIG_ZISOFS_FS is not set
-+
-+#
-+# Partition Types
-+#
-+# CONFIG_PARTITION_ADVANCED is not set
-+CONFIG_MSDOS_PARTITION=y
-+# CONFIG_SMB_NLS is not set
-+CONFIG_NLS=y
-+
-+#
-+# Native Language Support
-+#
-+CONFIG_NLS_DEFAULT="iso8859-1"
-+CONFIG_NLS_CODEPAGE_437=m
-+CONFIG_NLS_CODEPAGE_737=m
-+CONFIG_NLS_CODEPAGE_775=m
-+CONFIG_NLS_CODEPAGE_850=m
-+CONFIG_NLS_CODEPAGE_852=m
-+CONFIG_NLS_CODEPAGE_855=m
-+CONFIG_NLS_CODEPAGE_857=m
-+CONFIG_NLS_CODEPAGE_860=m
-+CONFIG_NLS_CODEPAGE_861=m
-+CONFIG_NLS_CODEPAGE_862=m
-+CONFIG_NLS_CODEPAGE_863=m
-+CONFIG_NLS_CODEPAGE_864=m
-+CONFIG_NLS_CODEPAGE_865=m
-+CONFIG_NLS_CODEPAGE_866=m
-+CONFIG_NLS_CODEPAGE_869=m
-+CONFIG_NLS_CODEPAGE_936=m
-+CONFIG_NLS_CODEPAGE_950=m
-+CONFIG_NLS_CODEPAGE_932=m
-+CONFIG_NLS_CODEPAGE_949=m
-+CONFIG_NLS_CODEPAGE_874=m
-+CONFIG_NLS_ISO8859_8=m
-+CONFIG_NLS_CODEPAGE_1250=m
-+CONFIG_NLS_CODEPAGE_1251=m
-+CONFIG_NLS_ISO8859_1=m
-+CONFIG_NLS_ISO8859_2=m
-+CONFIG_NLS_ISO8859_3=m
-+CONFIG_NLS_ISO8859_4=m
-+CONFIG_NLS_ISO8859_5=m
-+CONFIG_NLS_ISO8859_6=m
-+CONFIG_NLS_ISO8859_7=m
-+CONFIG_NLS_ISO8859_9=m
-+CONFIG_NLS_ISO8859_13=m
-+CONFIG_NLS_ISO8859_14=m
-+CONFIG_NLS_ISO8859_15=m
-+CONFIG_NLS_KOI8_R=m
-+CONFIG_NLS_KOI8_U=m
-+CONFIG_NLS_UTF8=m
-+
-+#
-+# Console drivers
-+#
-+CONFIG_PC_KEYMAP=y
-+# CONFIG_VGA_CONSOLE is not set
-+
-+#
-+# Frame-buffer support
-+#
-+CONFIG_FB=y
-+CONFIG_DUMMY_CONSOLE=y
-+# CONFIG_FB_ACORN is not set
-+# CONFIG_FB_ANAKIN is not set
-+# CONFIG_FB_CLPS711X is not set
-+# CONFIG_FB_SA1100 is not set
-+# CONFIG_FB_DBMX1 is not set
-+CONFIG_FB_PXA=y
-+# CONFIG_FB_PXA_8BPP is not set
-+CONFIG_FB_PXA_16BPP=y
-+# CONFIG_FB_CYBER2000 is not set
-+# CONFIG_FB_VIRTUAL is not set
-+CONFIG_FBCON_ADVANCED=y
-+# CONFIG_FBCON_MFB is not set
-+# CONFIG_FBCON_CFB2 is not set
-+# CONFIG_FBCON_CFB4 is not set
-+# CONFIG_FBCON_CFB8 is not set
-+CONFIG_FBCON_CFB16=y
-+# CONFIG_FBCON_CFB24 is not set
-+# CONFIG_FBCON_CFB32 is not set
-+# CONFIG_FBCON_AFB is not set
-+# CONFIG_FBCON_ILBM is not set
-+# CONFIG_FBCON_IPLAN2P2 is not set
-+# CONFIG_FBCON_IPLAN2P4 is not set
-+# CONFIG_FBCON_IPLAN2P8 is not set
-+# CONFIG_FBCON_MAC is not set
-+# CONFIG_FBCON_VGA_PLANES is not set
-+# CONFIG_FBCON_VGA is not set
-+# CONFIG_FBCON_HGA is not set
-+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-+# CONFIG_FBCON_FONTS is not set
-+CONFIG_FONT_8x8=y
-+CONFIG_FONT_8x16=y
-+
-+#
-+# Sound
-+#
-+CONFIG_SOUND=y
-+# CONFIG_SOUND_ALI5455 is not set
-+# CONFIG_SOUND_BT878 is not set
-+# CONFIG_SOUND_CMPCI is not set
-+# CONFIG_SOUND_EMU10K1 is not set
-+# CONFIG_MIDI_EMU10K1 is not set
-+# CONFIG_SOUND_FUSION is not set
-+# CONFIG_SOUND_CS4281 is not set
-+# CONFIG_SOUND_ES1370 is not set
-+# CONFIG_SOUND_ES1371 is not set
-+# CONFIG_SOUND_ESSSOLO1 is not set
-+# CONFIG_SOUND_MAESTRO is not set
-+# CONFIG_SOUND_MAESTRO3 is not set
-+# CONFIG_SOUND_FORTE is not set
-+# CONFIG_SOUND_ICH is not set
-+# CONFIG_SOUND_RME96XX is not set
-+# CONFIG_SOUND_SONICVIBES is not set
-+# CONFIG_SOUND_TRIDENT is not set
-+# CONFIG_SOUND_MSNDCLAS is not set
-+# CONFIG_SOUND_MSNDPIN is not set
-+# CONFIG_SOUND_VIA82CXXX is not set
-+# CONFIG_MIDI_VIA82CXXX is not set
-+# CONFIG_SOUND_OSS is not set
-+# CONFIG_SOUND_VIDC is not set
-+# CONFIG_SOUND_WAVEARTIST is not set
-+CONFIG_SOUND_PXA_AC97=y
-+# CONFIG_SOUND_TVMIXER is not set
-+
-+#
-+# Multimedia Capabilities Port drivers
-+#
-+CONFIG_MCP=y
-+# CONFIG_MCP_SA1100 is not set
-+# CONFIG_MCP_UCB1200 is not set
-+# CONFIG_MCP_UCB1200_AUDIO is not set
-+# CONFIG_MCP_UCB1200_TS is not set
-+CONFIG_MCP_UCB1400_TS=y
-+
-+#
-+# USB support
-+#
-+CONFIG_USB=m
-+# CONFIG_USB_DEBUG is not set
-+CONFIG_USB_DEVICEFS=y
-+# CONFIG_USB_BANDWIDTH is not set
-+# CONFIG_USB_EHCI_HCD is not set
-+# CONFIG_USB_UHCI is not set
-+# CONFIG_USB_UHCI_ALT is not set
-+# CONFIG_USB_OHCI is not set
-+# CONFIG_USB_OHCI_SA1111 is not set
-+CONFIG_USB_SL811HS_ALT=m
-+CONFIG_USB_AUDIO=m
-+CONFIG_USB_EMI26=m
-+# CONFIG_USB_BLUETOOTH is not set
-+CONFIG_USB_MIDI=m
-+CONFIG_USB_STORAGE=m
-+CONFIG_USB_STORAGE_DEBUG=y
-+CONFIG_USB_STORAGE_DATAFAB=y
-+CONFIG_USB_STORAGE_FREECOM=y
-+# CONFIG_USB_STORAGE_ISD200 is not set
-+CONFIG_USB_STORAGE_DPCM=y
-+CONFIG_USB_STORAGE_HP8200e=y
-+CONFIG_USB_STORAGE_SDDR09=y
-+CONFIG_USB_STORAGE_SDDR55=y
-+CONFIG_USB_STORAGE_JUMPSHOT=y
-+# CONFIG_USB_ACM is not set
-+CONFIG_USB_PRINTER=m
-+CONFIG_USB_HID=m
-+CONFIG_USB_HIDINPUT=y
-+CONFIG_USB_HIDDEV=y
-+CONFIG_USB_KBD=m
-+# CONFIG_USB_MOUSE is not set
-+# CONFIG_USB_AIPTEK is not set
-+# CONFIG_USB_WACOM is not set
-+# CONFIG_USB_KBTAB is not set
-+# CONFIG_USB_POWERMATE is not set
-+CONFIG_USB_DC2XX=m
-+CONFIG_USB_MDC800=m
-+CONFIG_USB_SCANNER=m
-+CONFIG_USB_MICROTEK=m
-+CONFIG_USB_HPUSBSCSI=m
-+CONFIG_USB_IBMCAM=m
-+CONFIG_USB_KONICAWC=m
-+CONFIG_USB_OV511=m
-+CONFIG_USB_PWC=m
-+CONFIG_USB_SE401=m
-+CONFIG_USB_STV680=m
-+CONFIG_USB_VICAM=m
-+# CONFIG_USB_DSBR is not set
-+# CONFIG_USB_DABUSB is not set
-+# CONFIG_USB_PEGASUS is not set
-+# CONFIG_USB_RTL8150 is not set
-+# CONFIG_USB_KAWETH is not set
-+# CONFIG_USB_CATC is not set
-+# CONFIG_USB_CDCETHER is not set
-+# CONFIG_USB_USBNET is not set
-+# CONFIG_USB_USS720 is not set
-+
-+#
-+# USB Serial Converter support
-+#
-+CONFIG_USB_SERIAL=m
-+# CONFIG_USB_SERIAL_DEBUG is not set
-+CONFIG_USB_SERIAL_GENERIC=y
-+CONFIG_USB_SERIAL_BELKIN=m
-+CONFIG_USB_SERIAL_WHITEHEAT=m
-+CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
-+CONFIG_USB_SERIAL_EMPEG=m
-+# CONFIG_USB_SERIAL_FTDI_SIO is not set
-+# CONFIG_USB_SERIAL_VISOR is not set
-+# CONFIG_USB_SERIAL_IPAQ is not set
-+# CONFIG_USB_SERIAL_IR is not set
-+# CONFIG_USB_SERIAL_EDGEPORT is not set
-+# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-+# CONFIG_USB_SERIAL_KEYSPAN is not set
-+# CONFIG_USB_SERIAL_MCT_U232 is not set
-+# CONFIG_USB_SERIAL_KLSI is not set
-+# CONFIG_USB_SERIAL_KOBIL_SCT is not set
-+# CONFIG_USB_SERIAL_PL2303 is not set
-+# CONFIG_USB_SERIAL_CYBERJACK is not set
-+# CONFIG_USB_SERIAL_XIRCOM is not set
-+# CONFIG_USB_SERIAL_OMNINET is not set
-+# CONFIG_USB_RIO500 is not set
-+# CONFIG_USB_AUERSWALD is not set
-+# CONFIG_USB_TIGL is not set
-+# CONFIG_USB_BRLVGER is not set
-+# CONFIG_USB_LCD is not set
-+
-+#
-+# Bluetooth support
-+#
-+# CONFIG_BLUEZ is not set
-+
-+#
-+# Kernel hacking
-+#
-+CONFIG_FRAME_POINTER=y
-+# CONFIG_DEBUG_USER is not set
-+# CONFIG_DEBUG_INFO is not set
-+# CONFIG_NO_PGT_CACHE is not set
-+# CONFIG_DEBUG_KERNEL is not set
-+# CONFIG_DEBUG_SLAB is not set
-+# CONFIG_MAGIC_SYSRQ is not set
-+# CONFIG_DEBUG_SPINLOCK is not set
-+# CONFIG_DEBUG_WAITQ is not set
-+# CONFIG_DEBUG_BUGVERBOSE is not set
-+# CONFIG_DEBUG_ERRORS is not set
-+# CONFIG_DEBUG_LL is not set
-+# CONFIG_DEBUG_DC21285_PORT is not set
-+# CONFIG_DEBUG_CLPS711X_UART2 is not set
-+
-+#
-+# Library routines
-+#
-+CONFIG_ZLIB_INFLATE=y
-+CONFIG_ZLIB_DEFLATE=y
---- linux-2.4.21/arch/arm/mach-pxa/Makefile~pm
-+++ linux-2.4.21/arch/arm/mach-pxa/Makefile
-@@ -14,8 +14,11 @@
- obj-n :=
- obj- :=
-
--export-objs := generic.o irq.o dma.o sa1111.o \
-- usb_ctl.o usb_recv.o usb_send.o
-+export-objs := apm.o generic.o irq.o dma.o sa1111.o \
-+ usb_ctl.o usb_recv.o usb_send.o pm.o
-+
-+
-+export-objs += ramses.o
-
- # Common support (must be linked before board specific support)
- obj-y += generic.o irq.o dma.o
-@@ -27,6 +30,7 @@
- obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
- obj-$(CONFIG_ARCH_PXA_CERF) += cerf.o
- obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
-+obj-$(CONFIG_ARCH_RAMSES) += ramses.o
- obj-$(CONFIG_ARCH_TRIZEPS2) += trizeps2.o
-
- # Support for blinky lights
-@@ -48,6 +52,7 @@
-
- # Misc features
- obj-$(CONFIG_PM) += pm.o sleep.o
-+obj-$(CONFIG_APM) += apm.o
- obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o
-
- include $(TOPDIR)/Rules.make
---- /dev/null
-+++ linux-2.4.21/arch/arm/mach-pxa/apm.c
-@@ -0,0 +1,491 @@
-+/*
-+ * bios-less APM driver for ARM Linux
-+ * Jamey Hicks <jamey@crl.dec.com>
-+ * adapted from the APM BIOS driver for Linux by Stephen Rothwell (sfr@linuxcare.com)
-+ *
-+ * APM 1.2 Reference:
-+ * Intel Corporation, Microsoft Corporation. Advanced Power Management
-+ * (APM) BIOS Interface Specification, Revision 1.2, February 1996.
-+ *
-+ * [This document is available from Microsoft at:
-+ * http://www.microsoft.com/hwdev/busbios/amp_12.htm]
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/poll.h>
-+#include <linux/types.h>
-+#include <linux/stddef.h>
-+#include <linux/timer.h>
-+#include <linux/fcntl.h>
-+#include <linux/slab.h>
-+#include <linux/stat.h>
-+#include <linux/proc_fs.h>
-+#include <linux/miscdevice.h>
-+#include <linux/apm_bios.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/pm.h>
-+#include <linux/kernel.h>
-+#include <linux/smp_lock.h>
-+
-+#include <asm/system.h>
-+#include <asm/hardware.h>
-+
-+#ifdef CONFIG_SA1100_H3XXX
-+#include <asm/arch/h3600_hal.h>
-+#endif
-+
-+#include "pm-common.c"
-+
-+struct apm_bios_info apm_bios_info = {
-+ /* this driver simulates APM version 1.2 */
-+ version: 0x102,
-+ flags: APM_32_BIT_SUPPORT
-+};
-+
-+/*
-+ * The apm_bios device is one of the misc char devices.
-+ * This is its minor number.
-+ */
-+#define APM_MINOR_DEV 134
-+
-+/*
-+ * See Documentation/Config.help for the configuration options.
-+ *
-+ * Various options can be changed at boot time as follows:
-+ * (We allow underscores for compatibility with the modules code)
-+ * apm=on/off enable/disable APM
-+ * [no-]power[-_]off power off on shutdown
-+ */
-+
-+/*
-+ * Maximum number of events stored
-+ */
-+#define APM_MAX_EVENTS 10
-+
-+/*
-+ * The per-file APM data
-+ */
-+struct apm_user {
-+ int magic;
-+ struct apm_user * next;
-+ int suser: 1;
-+ int suspend_wait: 1;
-+ int suspend_result;
-+ int suspends_pending;
-+ int standbys_pending;
-+ int suspends_read;
-+ int standbys_read;
-+ int event_head;
-+ int event_tail;
-+ apm_event_t events[APM_MAX_EVENTS];
-+};
-+
-+/*
-+ * The magic number in apm_user
-+ */
-+#define APM_BIOS_MAGIC 0x4101
-+
-+/*
-+ * Local variables
-+ */
-+
-+#ifdef CONFIG_APM_RTC_IS_GMT
-+#define clock_cmos_diff 0
-+#define got_clock_diff 1
-+#endif
-+static int apm_disabled;
-+#ifdef CONFIG_SMP
-+static int power_off;
-+#else
-+static int power_off = 1;
-+#endif
-+static int exit_kapmd;
-+static int kapmd_running;
-+
-+static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
-+static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
-+static struct apm_user * user_list = NULL;
-+
-+static char driver_version[] = "1.13"; /* no spaces */
-+
-+typedef struct lookup_t {
-+ int key;
-+ char * msg;
-+} lookup_t;
-+
-+static const lookup_t error_table[] = {
-+/* N/A { APM_SUCCESS, "Operation succeeded" }, */
-+ { APM_DISABLED, "Power management disabled" },
-+ { APM_CONNECTED, "Real mode interface already connected" },
-+ { APM_NOT_CONNECTED, "Interface not connected" },
-+ { APM_16_CONNECTED, "16 bit interface already connected" },
-+/* N/A { APM_16_UNSUPPORTED, "16 bit interface not supported" }, */
-+ { APM_32_CONNECTED, "32 bit interface already connected" },
-+ { APM_32_UNSUPPORTED, "32 bit interface not supported" },
-+ { APM_BAD_DEVICE, "Unrecognized device ID" },
-+ { APM_BAD_PARAM, "Parameter out of range" },
-+ { APM_NOT_ENGAGED, "Interface not engaged" },
-+ { APM_BAD_FUNCTION, "Function not supported" },
-+ { APM_RESUME_DISABLED, "Resume timer disabled" },
-+ { APM_BAD_STATE, "Unable to enter requested state" },
-+/* N/A { APM_NO_EVENTS, "No events pending" }, */
-+ { APM_NO_ERROR, "BIOS did not set a return code" },
-+ { APM_NOT_PRESENT, "No APM present" }
-+};
-+#define ERROR_COUNT (sizeof(error_table)/sizeof(lookup_t))
-+
-+static int (*apm_get_power_status)(u_char *ac_line_status,
-+ u_char *battery_status,
-+ u_char *battery_flag,
-+ u_char *battery_percentage,
-+ u_short *battery_life) = 0;
-+
-+void apm_register_get_power_status( int (*fn)(u_char *ac_line_status,
-+ u_char *battery_status,
-+ u_char *battery_flag,
-+ u_char *battery_percentage,
-+ u_short *battery_life))
-+{
-+ apm_get_power_status = fn;
-+}
-+
-+static int queue_empty(struct apm_user *as)
-+{
-+ return as->event_head == as->event_tail;
-+}
-+
-+static apm_event_t get_queued_event(struct apm_user *as)
-+{
-+ as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
-+ return as->events[as->event_tail];
-+}
-+
-+static int check_apm_user(struct apm_user *as, const char *func)
-+{
-+ if ((as == NULL) || (as->magic != APM_BIOS_MAGIC)) {
-+ printk(KERN_ERR "apm: %s passed bad filp\n", func);
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+static ssize_t do_read(struct file *fp, char *buf, size_t count, loff_t *ppos)
-+{
-+ struct apm_user * as;
-+ int i;
-+ apm_event_t event;
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+ as = fp->private_data;
-+ if (check_apm_user(as, "read"))
-+ return -EIO;
-+ if (count < sizeof(apm_event_t))
-+ return -EINVAL;
-+ if (queue_empty(as)) {
-+ if (fp->f_flags & O_NONBLOCK)
-+ return -EAGAIN;
-+ add_wait_queue(&apm_waitqueue, &wait);
-+ printk("do_read: waiting\n");
-+repeat:
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (queue_empty(as) && !signal_pending(current)) {
-+ schedule();
-+ goto repeat;
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&apm_waitqueue, &wait);
-+ }
-+ i = count;
-+ while ((i >= sizeof(event)) && !queue_empty(as)) {
-+ event = get_queued_event(as);
-+ printk(" do_read: event=%d\n", event);
-+ if (copy_to_user(buf, &event, sizeof(event))) {
-+ if (i < count)
-+ break;
-+ return -EFAULT;
-+ }
-+ switch (event) {
-+ case APM_SYS_SUSPEND:
-+ case APM_USER_SUSPEND:
-+ as->suspends_read++;
-+ break;
-+
-+ case APM_SYS_STANDBY:
-+ case APM_USER_STANDBY:
-+ as->standbys_read++;
-+ break;
-+ }
-+ buf += sizeof(event);
-+ i -= sizeof(event);
-+ }
-+ if (i < count)
-+ return count - i;
-+ if (signal_pending(current))
-+ return -ERESTARTSYS;
-+ return 0;
-+}
-+
-+static unsigned int do_poll(struct file *fp, poll_table * wait)
-+{
-+ struct apm_user * as;
-+
-+ as = fp->private_data;
-+ if (check_apm_user(as, "poll"))
-+ return 0;
-+ poll_wait(fp, &apm_waitqueue, wait);
-+ if (!queue_empty(as))
-+ return POLLIN | POLLRDNORM;
-+ return 0;
-+}
-+
-+static int do_ioctl(struct inode * inode, struct file *filp,
-+ u_int cmd, u_long arg)
-+{
-+ struct apm_user * as;
-+
-+ as = filp->private_data;
-+ if (check_apm_user(as, "ioctl"))
-+ return -EIO;
-+ if (!as->suser)
-+ return -EPERM;
-+ switch (cmd) {
-+ case APM_IOC_SUSPEND:
-+ pm_suggest_suspend();
-+ break;
-+ default:
-+ printk("//hs %x\n", cmd);
-+ return -EINVAL;
-+ }
-+ return 0;
-+}
-+
-+static int do_release(struct inode * inode, struct file * filp)
-+{
-+ struct apm_user * as;
-+
-+ as = filp->private_data;
-+ if (check_apm_user(as, "release"))
-+ return 0;
-+ filp->private_data = NULL;
-+ lock_kernel();
-+ unlock_kernel();
-+ kfree(as);
-+ return 0;
-+}
-+
-+static int do_open(struct inode * inode, struct file * filp)
-+{
-+ struct apm_user * as;
-+
-+ as = (struct apm_user *)kmalloc(sizeof(*as), GFP_KERNEL);
-+ if (as == NULL) {
-+ printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n",
-+ sizeof(*as));
-+ return -ENOMEM;
-+ }
-+ as->magic = APM_BIOS_MAGIC;
-+ as->event_tail = as->event_head = 0;
-+ as->suspends_pending = as->standbys_pending = 0;
-+ as->suspends_read = as->standbys_read = 0;
-+ /*
-+ * XXX - this is a tiny bit broken, when we consider BSD
-+ * process accounting. If the device is opened by root, we
-+ * instantly flag that we used superuser privs. Who knows,
-+ * we might close the device immediately without doing a
-+ * privileged operation -- cevans
-+ */
-+ as->suser = capable(CAP_SYS_ADMIN);
-+ as->next = user_list;
-+ user_list = as;
-+ filp->private_data = as;
-+ return 0;
-+}
-+
-+static int apm_get_info(char *buf, char **start, off_t fpos, int length)
-+{
-+ char * p;
-+ unsigned short dx;
-+ unsigned short error;
-+ unsigned char ac_line_status = 0xff;
-+ unsigned char battery_status = 0xff;
-+ unsigned char battery_flag = 0xff;
-+ unsigned char percentage = 0xff;
-+ int time_units = -1;
-+ char *units = "?";
-+
-+ p = buf;
-+
-+ if ( (smp_num_cpus == 1) &&
-+ apm_get_power_status &&
-+ !(error = apm_get_power_status(&ac_line_status,
-+ &battery_status, &battery_flag, &percentage, &dx))) {
-+ if (apm_bios_info.version > 0x100) {
-+ if (dx != 0xffff) {
-+ units = (dx & 0x8000) ? "min" : "sec";
-+ time_units = dx & 0x7fff;
-+ }
-+ }
-+ }
-+ /* Arguments, with symbols from linux/apm_bios.h. Information is
-+ from the Get Power Status (0x0a) call unless otherwise noted.
-+
-+ 0) Linux driver version (this will change if format changes)
-+ 1) APM BIOS Version. Usually 1.0, 1.1 or 1.2.
-+ 2) APM flags from APM Installation Check (0x00):
-+ bit 0: APM_16_BIT_SUPPORT
-+ bit 1: APM_32_BIT_SUPPORT
-+ bit 2: APM_IDLE_SLOWS_CLOCK
-+ bit 3: APM_BIOS_DISABLED
-+ bit 4: APM_BIOS_DISENGAGED
-+ 3) AC line status
-+ 0x00: Off-line
-+ 0x01: On-line
-+ 0x02: On backup power (BIOS >= 1.1 only)
-+ 0xff: Unknown
-+ 4) Battery status
-+ 0x00: High
-+ 0x01: Low
-+ 0x02: Critical
-+ 0x03: Charging
-+ 0x04: Selected battery not present (BIOS >= 1.2 only)
-+ 0xff: Unknown
-+ 5) Battery flag
-+ bit 0: High
-+ bit 1: Low
-+ bit 2: Critical
-+ bit 3: Charging
-+ bit 7: No system battery
-+ 0xff: Unknown
-+ 6) Remaining battery life (percentage of charge):
-+ 0-100: valid
-+ -1: Unknown
-+ 7) Remaining battery life (time units):
-+ Number of remaining minutes or seconds
-+ -1: Unknown
-+ 8) min = minutes; sec = seconds */
-+
-+ p += sprintf(p, "%s %d.%d 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
-+ driver_version,
-+ (apm_bios_info.version >> 8) & 0xff,
-+ apm_bios_info.version & 0xff,
-+ apm_bios_info.flags,
-+ ac_line_status,
-+ battery_status,
-+ battery_flag,
-+ percentage,
-+ time_units,
-+ units);
-+
-+ return p - buf;
-+}
-+
-+#ifndef MODULE
-+static int __init apm_setup(char *str)
-+{
-+ int invert;
-+
-+printk("//hs apm_setup\n");
-+ while ((str != NULL) && (*str != '\0')) {
-+ if (strncmp(str, "off", 3) == 0)
-+ apm_disabled = 1;
-+ if (strncmp(str, "on", 2) == 0)
-+ apm_disabled = 0;
-+ invert = (strncmp(str, "no-", 3) == 0);
-+ if (invert)
-+ str += 3;
-+ if ((strncmp(str, "power-off", 9) == 0) ||
-+ (strncmp(str, "power_off", 9) == 0))
-+ power_off = !invert;
-+ str = strchr(str, ',');
-+ if (str != NULL)
-+ str += strspn(str, ", \t");
-+ }
-+ return 1;
-+}
-+
-+__setup("apm=", apm_setup);
-+#endif
-+
-+static struct file_operations apm_bios_fops = {
-+ owner: THIS_MODULE,
-+ read: do_read,
-+ poll: do_poll,
-+ ioctl: do_ioctl,
-+ open: do_open,
-+ release: do_release,
-+};
-+
-+static struct miscdevice apm_device = {
-+ APM_MINOR_DEV,
-+ "apm_bios",
-+ &apm_bios_fops
-+};
-+
-+#define APM_INIT_ERROR_RETURN return -1
-+
-+/*
-+ * Just start the APM thread. We do NOT want to do APM BIOS
-+ * calls from anything but the APM thread, if for no other reason
-+ * than the fact that we don't trust the APM BIOS. This way,
-+ * most common APM BIOS problems that lead to protection errors
-+ * etc will have at least some level of being contained...
-+ *
-+ * In short, if something bad happens, at least we have a choice
-+ * of just killing the apm thread..
-+ */
-+static int __init apm_init(void)
-+{
-+ if (apm_bios_info.version == 0) {
-+ printk(KERN_INFO "apm: BIOS not found.\n");
-+ APM_INIT_ERROR_RETURN;
-+ }
-+ printk(KERN_INFO
-+ "apm: BIOS version %d.%d Flags 0x%02x (Driver version %s)\n",
-+ ((apm_bios_info.version >> 8) & 0xff),
-+ (apm_bios_info.version & 0xff),
-+ apm_bios_info.flags,
-+ driver_version);
-+
-+ if (apm_disabled) {
-+ printk(KERN_NOTICE "apm: disabled on user request.\n");
-+ APM_INIT_ERROR_RETURN;
-+ }
-+
-+ if (PM_IS_ACTIVE()) {
-+ printk(KERN_NOTICE "apm: overridden by ACPI.\n");
-+ APM_INIT_ERROR_RETURN;
-+ }
-+ pm_active = 1;
-+
-+ create_proc_info_entry("apm", 0, NULL, apm_get_info);
-+
-+ misc_register(&apm_device);
-+
-+ return 0;
-+}
-+
-+module_init(apm_init);
-+
-+#ifdef MODULE
-+static void __exit apm_exit(void)
-+{
-+ misc_deregister(&apm_device);
-+ remove_proc_entry("apm", NULL);
-+ if (power_off)
-+ pm_power_off = NULL;
-+ exit_kapmd = 1;
-+ while (kapmd_running)
-+ schedule();
-+ pm_active = 0;
-+}
-+
-+module_exit(apm_exit);
-+
-+MODULE_AUTHOR("Jamey Hicks, pulling bits from original by Stephen Rothwell");
-+MODULE_DESCRIPTION("A minimal emulation of APM");
-+MODULE_PARM(power_off, "i");
-+MODULE_PARM_DESC(power_off, "Enable power off");
-+#endif
---- linux-2.4.21/arch/arm/mach-pxa/cpu-pxa.c~ramses-corevolt
-+++ linux-2.4.21/arch/arm/mach-pxa/cpu-pxa.c
-@@ -39,7 +39,7 @@
-
- #include <asm/hardware.h>
-
--#define DEBUGGING 1
-+#define DEBUGGING 0
-
- #if DEBUGGING
- static unsigned int freq_debug = DEBUGGING;
-@@ -52,6 +52,7 @@
- unsigned int khz;
- unsigned int cccr;
- unsigned int pxbus;
-+ unsigned int corevolt;
- } pxa_freqs_t;
-
- #define CCLKCFG_TURBO 0x1
-@@ -79,23 +80,23 @@
-
- static pxa_freqs_t pxa250_valid_freqs[] =
- {
-- {199100, 0x141, 99}, /* mem= 99, run=199, turbo=199, PXbus= 99 */
-- {298600, 0x1c1, 99}, /* mem= 99, run=199, turbo=298, PXbus= 99 */
-- {398100, 0x241, 99}, /* mem= 99, run=199, turbo=398, PXbus= 99 */
-+ {199100, 0x141, 99, 115}, /* mem= 99, run=199, turbo=199, PXbus= 99 */
-+ {298600, 0x1c1, 99, 125}, /* mem= 99, run=199, turbo=298, PXbus= 99 */
-+ {398100, 0x241, 99, 135}, /* mem= 99, run=199, turbo=398, PXbus= 99 */
- {0,0}
- };
-
- static pxa_freqs_t pxa255_valid_freqs[] =
- {
-- { 99000, 0x121, 50}, /* mem= 99, run= 99, turbo= 99, PXbus= 50 */
--OC( {118000, 0x122, 59},)/* mem=118, run=118, turbo=118, PXbus= 59 OC'd mem */
-- {199100, 0x141, 99}, /* mem= 99, run=199, turbo=199, PXbus= 99 */
--OC( {236000, 0x142,118},)/* mem=118, run=236, turbo=236, PXbus=118 OC'd mem */
-- {298600, 0x1c1, 99}, /* mem= 99, run=199, turbo=298, PXbus= 99 */
--OC( {354000, 0x1c2,118},)/* mem=118, run=236, turbo=354, PXbus=118 OC'd mem */
-- {398099, 0x241, 99}, /* mem= 99, run=199, turbo=398, PXbus= 99 */
-- {398100, 0x161,196}, /* mem= 99, run=398, turbo=398, PXbus=196 */
--OC( {471000, 0x162,236},)/* mem=118, run=471, turbo=471, PXbus=236 OC'd mem/core/bus */
-+ { 99000, 0x121, 50, 105}, /* mem= 99, run= 99, turbo= 99, PXbus= 50 */
-+OC( {118000, 0x122, 59, 115},)/* mem=118, run=118, turbo=118, PXbus= 59 OC'd mem */
-+ {199100, 0x141, 99, 115}, /* mem= 99, run=199, turbo=199, PXbus= 99 */
-+OC( {236000, 0x142,118, 125},)/* mem=118, run=236, turbo=236, PXbus=118 OC'd mem */
-+ {298600, 0x1c1, 99, 125}, /* mem= 99, run=199, turbo=298, PXbus= 99 */
-+OC( {354000, 0x1c2,118, 135},)/* mem=118, run=236, turbo=354, PXbus=118 OC'd mem */
-+ {398099, 0x241, 99, 135}, /* mem= 99, run=199, turbo=398, PXbus= 99 */
-+ {398100, 0x161,196, 135}, /* mem= 99, run=398, turbo=398, PXbus=196 */
-+OC( {471000, 0x162,236, 150},)/* mem=118, run=471, turbo=471, PXbus=236 OC'd mem/core/bus */
- {0,0}
- };
-
-@@ -109,7 +110,7 @@
- int i=0;
- while( pxa_valid_freqs[i].khz)
- {
-- if( pxa_valid_freqs[i].khz == khz)
-+ if (pxa_valid_freqs[i].khz == khz)
- return &pxa_valid_freqs[i];
- i++;
- }
-@@ -141,14 +142,17 @@
- void *ramstart = phys_to_virt(0xa0000000);
- pxa_freqs_t *freq_info;
-
-- if( ! supported) return;
-+ if (! supported) return;
-
- freq_info = pxa_get_freq_info( khz);
-
-- if( ! freq_info) return;
-+ if (! freq_info) return;
-+
-+ if (freq_info->corevolt > ramses_corevolt_shadow)
-+ ramses_set_corevolt(freq_info->corevolt);
-
- CCCR = freq_info->cccr;
-- if( freq_debug)
-+ if (freq_debug)
- printk(KERN_INFO "Changing CPU frequency to %d Mhz (PXbus=%dMhz).\n",
- khz/1000, freq_info->pxbus);
-
-@@ -184,6 +188,9 @@
- : "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart)
- : "r4", "r5");
- local_irq_restore(flags);
-+
-+ if (freq_info->corevolt < ramses_corevolt_shadow)
-+ ramses_set_corevolt(freq_info->corevolt);
- }
-
- static int pxa_init_freqs( void)
-@@ -191,19 +198,19 @@
- int cpu_ver;
- asm("mrc%? p15, 0, %0, c0, c0" : "=r" (cpu_ver));
-
-- if( (cpu_ver & 0xf) <= PXA250_REV_A1)
-+ if ((cpu_ver & 0xf) <= PXA250_REV_A1)
- {
- return 0;
- }
-
-- if( (cpu_ver & 0xf) <= PXA250_REV_B2)
-+ if ((cpu_ver & 0xf) <= PXA250_REV_B2)
- {
-- if( freq_debug) printk(KERN_INFO "Using PXA250 frequency points.\n");
-+ if (freq_debug) printk(KERN_INFO "Using PXA250 frequency points.\n");
- pxa_valid_freqs = pxa250_valid_freqs;
- }
- else /* C0 and above */
- {
-- if( freq_debug) printk(KERN_INFO "Using PXA255 frequency points.\n");
-+ if (freq_debug) printk(KERN_INFO "Using PXA255 frequency points.\n");
- pxa_valid_freqs = pxa255_valid_freqs;
- }
-
-@@ -212,24 +219,23 @@
-
- static int __init pxa_clk_init(void)
- {
-- if( pxa_init_freqs())
-+ if (pxa_init_freqs())
- {
-- if( freq_debug) printk(KERN_INFO "Registering CPU frequency change support.\n");
-+ if (freq_debug) printk(KERN_INFO "Registering CPU frequency change support.\n");
- supported = 1;
-
- cpufreq_init( get_clk_frequency_khz(0), PXA25x_MIN_FREQ, PXA25x_MAX_FREQ);
-- cpufreq_setfunctions(pxa_validate_speed, pxa_setspeed);
- }
- else
- {
-- if( freq_debug) printk(KERN_INFO "Disabling CPU frequency change support.\n");
-+ if (freq_debug) printk(KERN_INFO "Disabling CPU frequency change support.\n");
- /* Note that we have to initialize the generic code in order to
- * release a lock (cpufreq_sem). Any registration for freq changes
- * (e.g. lcd driver) will get blocked otherwise.
- */
- cpufreq_init( 0, 0, 0);
-- cpufreq_setfunctions(pxa_validate_speed, pxa_setspeed);
- }
-+ cpufreq_setfunctions(pxa_validate_speed, pxa_setspeed);
-
- return 0;
- }
---- linux-2.4.21/arch/arm/mach-pxa/generic.c~pm
-+++ linux-2.4.21/arch/arm/mach-pxa/generic.c
-@@ -28,6 +28,11 @@
- #include <asm/pgtable.h>
- #include <asm/mach/map.h>
-
-+#ifdef CONFIG_PXA_RTC_HACK
-+#include <asm/setup.h>
-+#include <linux/bootmem.h>
-+#endif
-+
- #include "generic.h"
-
- /*
-@@ -139,4 +144,41 @@
- {
- iotable_init(standard_io_desc);
- get_clk_frequency_khz( 1);
-+#ifdef CONFIG_PXA_RTC_HACK
-+ pxa_rtc_hack_init();
-+#endif
-+}
-+
-+
-+
-+#ifdef CONFIG_PXA_RTC_HACK
-+unsigned long *save_RCNR = 0;
-+
-+void pxa_rtc_hack_init(void)
-+{
-+ /*
-+ This has to be here since I guess the bootmem API is the
-+ right choice to allocate the memory during boot
-+ place. And we are sure that timer iqr is not already
-+ running.
-+ - Christian Pellegin <chri@infis.univ.trieste.it>
-+ */
-+ unsigned long pxa_rtc_hack = 0;
-+
-+ pxa_rtc_hack = meminfo.bank[meminfo.nr_banks-1].start +
-+ meminfo.bank[meminfo.nr_banks-1].size -
-+ PAGE_SIZE;
-+ reserve_bootmem(pxa_rtc_hack, PAGE_SIZE);
-+ printk("Reserved %ld bytes at %lx for RTC hack\n",
-+ PAGE_SIZE, pxa_rtc_hack);
-+ save_RCNR = (unsigned long *) phys_to_virt(pxa_rtc_hack);
-+ if ( (save_RCNR[0] ^ save_RCNR[1]) == 0xffffffff ) {
-+ printk("Restoring saved RCNR value to %ld (from %lx)\n",
-+ save_RCNR[0], (unsigned long) save_RCNR);
-+ RCNR = save_RCNR[0];
-+ }
-+ else {
-+ printk("No valid saved RCNR value found at %lx\n", (unsigned long) save_RCNR);
-+ }
- }
-+#endif /* CONFIG_PXA_RTC_HACK */
---- linux-2.4.21/arch/arm/mach-pxa/generic.h~pm
-+++ linux-2.4.21/arch/arm/mach-pxa/generic.h
-@@ -17,3 +17,7 @@
- mi->bank[__nr].size = (__size), \
- mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27)
-
-+#ifdef CONFIG_PXA_RTC_HACK
-+void pxa_rtc_hack_init(void);
-+extern unsigned long *save_RCNR;
-+#endif
---- /dev/null
-+++ linux-2.4.21/arch/arm/mach-pxa/pm-common.c
-@@ -0,0 +1,285 @@
-+/*
-+ * SA1100 Power Management Routines
-+ *
-+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License.
-+ *
-+ * History:
-+ *
-+ * 2001-02-06: Cliff Brake Initial code
-+ *
-+ * 2001-02-25: Sukjae Cho <sjcho@east.isi.edu> &
-+ * Chester Kuo <chester@linux.org.tw>
-+ * Save more value for the resume function! Support
-+ * Bitsy/Assabet/Freebird board
-+ *
-+ * 2001-08-29: Nicolas Pitre <nico@cam.org>
-+ * Cleaned up, pushed platform dependent stuff
-+ * in the platform specific files.
-+ *
-+ * 2002-05-27: Nicolas Pitre Killed sleep.h and the kmalloced save array.
-+ * Storage is local on the stack now.
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/pm.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/sysctl.h>
-+#include <linux/errno.h>
-+#include <linux/cpufreq.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/memory.h>
-+#include <asm/system.h>
-+#include <asm/leds.h>
-+#include <asm/uaccess.h>
-+
-+
-+#ifdef CONFIG_IPAQ_HANDHELD
-+#include <asm/arch-sa1100/h3600_asic.h>
-+#endif
-+
-+#define __KERNEL_SYSCALLS__
-+#include <linux/unistd.h>
-+
-+
-+
-+static char pm_helper_path[128] = "/etc/apm/apmd_proxy";
-+extern int exec_usermodehelper(char *path, char **argv, char **envp);
-+int debug_pm = 0;
-+static int pm_helper_veto = 0;
-+
-+static int
-+run_sbin_pm_helper( pm_request_t action )
-+{
-+ int i;
-+ char *argv[3], *envp[8];
-+
-+ if (!pm_helper_path[0])
-+ return 2;
-+
-+ if ( action != PM_SUSPEND && action != PM_RESUME )
-+ return 1;
-+
-+ /* Be root */
-+ current->uid = current->gid = 0;
-+
-+ i = 0;
-+ argv[i++] = pm_helper_path;
-+ argv[i++] = (action == PM_RESUME ? "resume" : "suspend");
-+
-+ if (action == PM_RESUME)
-+ argv[i++]="suspend";
-+
-+ argv[i] = 0;
-+
-+ i = 0;
-+ /* minimal command environment */
-+ envp[i++] = "HOME=/";
-+ envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-+ envp[i] = 0;
-+
-+ /* other stuff we want to pass to /sbin/pm_helper */
-+ return exec_usermodehelper (argv [0], argv, envp);
-+}
-+
-+/*
-+ * If pm_suggest_suspend_hook is non-NULL, it is called by pm_suggest_suspend.
-+ */
-+int (*pm_suggest_suspend_hook)(int state);
-+EXPORT_SYMBOL(pm_suggest_suspend_hook);
-+
-+/*
-+ * If pm_use_sbin_pm_helper is nonzero, then run_sbin_pm_helper is called before suspend and after resume
-+ */
-+int pm_use_sbin_pm_helper = 1;
-+EXPORT_SYMBOL(pm_use_sbin_pm_helper);
-+
-+/*
-+ * If sysctl_pm_do_suspend_hook is non-NULL, it is called by sysctl_pm_do_suspend.
-+ * If it returns a true value, then pm_suspend is not called.
-+ * Use this to hook in apmd, for now.
-+ */
-+int (*pm_sysctl_suspend_hook)(int state);
-+EXPORT_SYMBOL(pm_sysctl_suspend_hook);
-+
-+int pm_suspend(void);
-+
-+int pm_suggest_suspend(void)
-+{
-+ int retval;
-+
-+ if (pm_suggest_suspend_hook) {
-+ if (pm_suggest_suspend_hook(PM_SUSPEND))
-+ return 0;
-+ }
-+
-+ if (pm_use_sbin_pm_helper) {
-+ pid_t pid;
-+ int res;
-+ int status = 0;
-+ unsigned int old_fs;
-+
-+ pid = kernel_thread ((int (*) (void *)) run_sbin_pm_helper, (void *) PM_SUSPEND, 0 );
-+ if ( pid < 0 )
-+ return pid;
-+
-+ if (debug_pm)
-+ printk(KERN_CRIT "%s:%d got pid=%d\n", __FUNCTION__, __LINE__, pid);
-+
-+ old_fs = get_fs ();
-+ set_fs (get_ds ());
-+ res = waitpid(pid, &status, __WCLONE);
-+ set_fs (old_fs);
-+
-+ if ( pid != res ) {
-+ if (debug_pm)
-+ printk(KERN_CRIT ": waitpid returned %d (exit_code=%d); not suspending\n", res, status );
-+
-+ return -1;
-+ }
-+
-+ /*if ( WIFEXITED(status) && ( WIFEXITSTATUS(status) != 0 )) {*/
-+ if (( status & 0xff7f ) != 0 ) {
-+ if (pm_helper_veto) {
-+ if (debug_pm)
-+ printk(KERN_CRIT "%s: SUSPEND WAS CANCELLED BY pm_helper (exit status %d)\n", __FUNCTION__, status >> 8);
-+ return -1;
-+ } else {
-+ if (debug_pm)
-+ printk(KERN_CRIT "%s: pm_helper returned %d, but going ahead anyway\n", __FUNCTION__, status >> 8);
-+ }
-+ }
-+ }
-+
-+ if (debug_pm)
-+ printk(KERN_CRIT "%s: REALLY SUSPENDING NOW\n", __FUNCTION__ );
-+
-+ if (pm_sysctl_suspend_hook) {
-+ if (pm_sysctl_suspend_hook(PM_SUSPEND))
-+ return 0;
-+ }
-+
-+ retval = pm_suspend();
-+ if (retval) {
-+ if (debug_pm)
-+ printk(KERN_CRIT "pm_suspend returned %d\n", retval);
-+ return retval;
-+ }
-+
-+ if (pm_use_sbin_pm_helper) {
-+ pid_t pid;
-+
-+ if (debug_pm)
-+ printk(KERN_CRIT "%s: running pm_helper for wakeup\n", __FUNCTION__);
-+
-+ pid = kernel_thread ((int (*) (void *)) run_sbin_pm_helper, (void *) PM_RESUME, 0 );
-+ if ( pid < 0 )
-+ return pid;
-+
-+ if ( pid != waitpid ( pid, NULL, __WCLONE ))
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+EXPORT_SYMBOL(pm_suggest_suspend);
-+
-+
-+/*
-+ * Send us to sleep.
-+ */
-+int pm_suspend(void)
-+{
-+ int retval;
-+
-+ retval = pm_send_all(PM_SUSPEND, (void *)3);
-+ if ( retval )
-+ return retval;
-+
-+#ifdef CONFIG_IPAQ_HANDHELD
-+ retval = h3600_power_management(PM_SUSPEND);
-+ if (retval) {
-+ pm_send_all(PM_RESUME, (void *)0);
-+ return retval;
-+ }
-+#endif
-+
-+ retval = pm_do_suspend();
-+
-+#ifdef CONFIG_IPAQ_HANDHELD
-+ /* Allow the power management routines to override resuming */
-+ while ( h3600_power_management(PM_RESUME) )
-+ retval = pm_do_suspend();
-+#endif
-+
-+ pm_send_all(PM_RESUME, (void *)0);
-+
-+ return retval;
-+}
-+EXPORT_SYMBOL(pm_suspend);
-+
-+#ifdef CONFIG_SYSCTL
-+/*
-+ * ARGH! ACPI people defined CTL_ACPI in linux/acpi.h rather than
-+ * linux/sysctl.h.
-+ *
-+ * This means our interface here won't survive long - it needs a new
-+ * interface. Quick hack to get this working - use sysctl id 9999.
-+ */
-+#warning ACPI broke the kernel, this interface needs to be fixed up.
-+#define CTL_ACPI 9999
-+#define ACPI_S1_SLP_TYP 19
-+
-+/*
-+ * Send us to sleep.
-+ */
-+static int sysctl_pm_do_suspend(void)
-+{
-+ int retval;
-+
-+ retval = pm_send_all(PM_SUSPEND, (void *)3);
-+
-+ if (retval == 0) {
-+ retval = pm_do_suspend();
-+
-+ pm_send_all(PM_RESUME, (void *)0);
-+ }
-+
-+ return retval;
-+}
-+
-+static struct ctl_table pm_table[] =
-+{
-+ {ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, (proc_handler *)&sysctl_pm_do_suspend},
-+ {2, "helper", pm_helper_path, sizeof(pm_helper_path), 0644, NULL, (proc_handler *)&proc_dostring},
-+ {3, "debug", &debug_pm, sizeof(debug_pm), 0644, NULL, (proc_handler *)&proc_dointvec},
-+ {4, "helper_veto", &pm_helper_veto, sizeof(pm_helper_veto), 0644, NULL, (proc_handler *)&proc_dointvec},
-+ {0}
-+};
-+
-+static struct ctl_table pm_dir_table[] =
-+{
-+ {CTL_ACPI, "pm", NULL, 0, 0555, pm_table},
-+ {0}
-+};
-+
-+/*
-+ * Initialize power interface
-+ */
-+static int __init pm_init(void)
-+{
-+ register_sysctl_table(pm_dir_table, 1);
-+ return 0;
-+}
-+
-+__initcall(pm_init);
-+
-+#endif
-+
---- linux-2.4.21/arch/arm/mach-pxa/pm.c~pm
-+++ linux-2.4.21/arch/arm/mach-pxa/pm.c
-@@ -19,6 +19,7 @@
- #include <linux/interrupt.h>
- #include <linux/sysctl.h>
- #include <linux/errno.h>
-+#include <linux/module.h>
-
- #include <asm/hardware.h>
- #include <asm/memory.h>
-@@ -82,7 +83,7 @@
-
- /*
- * Temporary solution. This won't be necessary once
-- * we move pxa support into the serial/* driver
-+ * we move pxa support into the serial driver
- * Save the FF UART
- */
- SAVE(FFIER);
-@@ -176,7 +177,7 @@
-
- /*
- * Temporary solution. This won't be necessary once
-- * we move pxa support into the serial/* driver.
-+ * we move pxa support into the serial driver.
- * Restore the FF UART.
- */
- RESTORE(FFMCR);
-@@ -209,6 +210,12 @@
- return virt_to_phys(sp);
- }
-
-+#ifndef CONFIG_APM
-+/*
-+ * This code is only needed if we don't compile in APM support.
-+ * If we compile APM support in, then this code is in pm-common.c
-+ */
-+
- #ifdef CONFIG_SYSCTL
- /*
- * ARGH! ACPI people defined CTL_ACPI in linux/acpi.h rather than
-@@ -263,3 +270,6 @@
- __initcall(pm_init);
-
- #endif
-+#endif
-+
-+EXPORT_SYMBOL(pm_do_suspend);
---- linux-2.4.21/arch/arm/mach-pxa/pxa_usb.h~pxa-usb
-+++ linux-2.4.21/arch/arm/mach-pxa/pxa_usb.h
-@@ -39,6 +39,7 @@
- int pxa_usb_xmitter_avail( void );
- int pxa_usb_send(char *buf, int len, usb_callback_t callback);
- void sa110a_usb_send_reset(void);
-+void pxa_usb_send_reset(void);
-
- /* in usb_recev.c */
- int pxa_usb_recv(char *buf, int len, usb_callback_t callback);
---- /dev/null
-+++ linux-2.4.21/arch/arm/mach-pxa/ramses.c
-@@ -0,0 +1,844 @@
-+/*
-+ * linux/arch/arm/mach-pxa/ramses.c
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Copyright (c) 2002,2003,2004 by M&N Logistik-Lösungen Online GmbH
-+ * written by Holger Schurig
-+ *
-+ * 2001-09-13: Cliff Brake <cbrake@accelent.com>
-+ * Initial code
-+ *
-+ * 2002-10-09: adaptions to ramses
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+#include <linux/ioport.h>
-+#include <linux/pm.h>
-+#include <linux/delay.h>
-+#ifdef CONFIG_APM
-+#include <linux/apm_bios.h>
-+#endif
-+#define USE_UCB
-+//#define PFI_LED
-+#define PFI_TURNOFF
-+
-+#include <asm/types.h>
-+#include <asm/setup.h>
-+#include <asm/memory.h>
-+#include <asm/mach-types.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+
-+#include <asm/mach/arch.h>
-+#include <asm/mach/map.h>
-+#include <asm/mach/irq.h>
-+#include <asm/arch/irq.h>
-+#include <asm/arch-pxa/pxa-regs.h>
-+
-+#ifdef USE_UCB
-+#include "../drivers/misc/ucb1x00.h"
-+#endif
-+
-+#include "generic.h"
-+
-+
-+/* shadow registers for write only registers */
-+u16 ramses_control_shadow =
-+ RAMSES_CONTROL_LED_BLUE_ +
-+ RAMSES_CONTROL_LED_ORANGE_ +
-+ RAMSES_CONTROL_SCANNER_WAKE_ +
-+ RAMSES_CONTROL_SCANNER_TRIG_;
-+
-+/* various flags the change the behavior of the kernel */
-+unsigned int ramses_flags =
-+ RAMSES_FLAGS_KEY_SCAN +
-+ RAMSES_FLAGS_KEY_SUSPEND +
-+ RAMSES_FLAGS_KEY_OFF;
-+
-+
-+/******************************************************************/
-+/* Corevoltage settings */
-+/******************************************************************/
-+
-+int ramses_corevolt_shadow = 150;
-+
-+void ramses_set_corevolt(int volt)
-+{
-+ int val = 0;
-+ switch (volt) {
-+ case 150:
-+ val = 5;
-+ break;
-+ case 135:
-+ val = 8;
-+ break;
-+ case 125:
-+ val = 10;
-+ break;
-+ case 115:
-+ val = 12;
-+ break;
-+ case 105:
-+ val = 14;
-+ break;
-+ }
-+ if (val) {
-+ ramses_corevolt_shadow = volt;
-+ RAMSES_COREVOLT = val;
-+ RAMSES_CPLD_PERIPH_PWR |= CORE_VAR_EN;
-+ }
-+}
-+
-+
-+/******************************************************************/
-+/* LCD stuff */
-+/******************************************************************/
-+
-+u16 ramses_lcd_type;
-+
-+void ramses_lcd_power_on(void)
-+{
-+ //printk("--> ramses_lcd_power_on\n");
-+
-+ /* 1. VCC */
-+ RAMSES_CPLD_LCD |= RAMSES_LCD_VCC;
-+
-+ /* 2. Signal */
-+
-+ /* 3. the PWM */
-+ CKEN |= (CKEN0_PWM0 | CKEN1_PWM1);
-+
-+ /* 4. nDISPOFF (done at backlight_on time) */
-+ RAMSES_CPLD_LCD |= RAMSES_LCD_DISPOFF;
-+}
-+
-+
-+void ramses_lcd_power_off(void)
-+{
-+ //printk("--> ramses_lcd_power_off\n");
-+ if (RAMSES_CPLD_LCD & RAMSES_LCD_DISPOFF) {
-+ //printk("--> turn bl off first\n");
-+ ramses_lcd_backlight_off();
-+ }
-+
-+ /* 1. nDISPOFF (just to be sure) */
-+ RAMSES_CPLD_LCD &= ~RAMSES_LCD_DISPOFF;
-+
-+ // for Torisan: wait until all has been sent out
-+ if (ramses_lcd_type == 2) {
-+ int i;
-+ for (i=0; i<33; i++)
-+ udelay(1500);
-+ }
-+
-+ /* 2. disable the PWM */
-+ set_GPIO_mode(GPIO16_PWM0 | GPIO_OUT);
-+ set_GPIO_mode(GPIO17_PWM1 | GPIO_OUT);
-+ CKEN &= ~(CKEN0_PWM0 | CKEN1_PWM1);
-+
-+ /* 3. SIGNAL */
-+
-+ /* 4. VCC */
-+ RAMSES_CPLD_LCD &= ~RAMSES_LCD_VCC;
-+}
-+
-+
-+void ramses_lcd_backlight_on(void)
-+{
-+ int i;
-+
-+ //printk("--> ramses_lcd_backlight_on\n");
-+ if ((ramses_control_shadow & RAMSES_CONTROL_LCD_BLIGHT) != 0)
-+ return;
-+ //printk(" state: %d\n", ramses_control_shadow & RAMSES_CONTROL_LCD_BLIGHT);
-+
-+ set_GPIO_mode(GPIO17_PWM1 | GPIO_OUT);
-+
-+ /* 4. nDISPOFF */
-+ RAMSES_CPLD_LCD |= RAMSES_LCD_DISPOFF;
-+
-+ /* Backlight can be turned on at any time */
-+ RAMSES_LCD_BLIGHT_ON();
-+
-+ for (i=0; i<33; i++)
-+ udelay(1500);
-+ set_GPIO_mode(GPIO16_PWM0_MD);
-+ set_GPIO_mode(GPIO17_PWM1_MD);
-+}
-+
-+
-+void ramses_lcd_backlight_off(void)
-+{
-+ int i;
-+
-+ //printk("--> ramses_lcd_backlight_off\n");
-+ if ((ramses_control_shadow & RAMSES_CONTROL_LCD_BLIGHT) == 0)
-+ return;
-+ //printk(" state: %d\n", ramses_control_shadow & RAMSES_CONTROL_LCD_BLIGHT);
-+
-+ set_GPIO_mode(GPIO17_PWM1 | GPIO_OUT);
-+ for (i=0; i<100; i++)
-+ udelay(1500);
-+
-+ /* Backlight can be turned off at any time */
-+ RAMSES_LCD_BLIGHT_OFF();
-+ udelay(1500);
-+
-+ /* 1. nDISPOFF */
-+ if (ramses_lcd_type != 2)
-+ RAMSES_CPLD_LCD &= ~RAMSES_LCD_DISPOFF;
-+
-+ //set_GPIO_mode(GPIO16_PWM0 | GPIO_IN);
-+ //set_GPIO_mode(GPIO17_PWM1 | GPIO_IN);
-+}
-+
-+
-+void ramses_lcd_set_brightness(int b)
-+{
-+ if (b > 255) b = 255;
-+ if (b < 0) b = 0;
-+ PWM_PWDUTY1 = 510-(b<<1);
-+}
-+
-+
-+int ramses_lcd_get_brightness(void)
-+{
-+ return 255-(PWM_PWDUTY1 >> 1);
-+}
-+
-+
-+void ramses_lcd_set_contrast(int c)
-+{
-+ if (c > 255) c = 255;
-+ if (c < 0) c = 0;
-+ PWM_PWDUTY0 = 542-c;
-+}
-+
-+
-+int ramses_lcd_get_contrast(void)
-+{
-+ return 542-PWM_PWDUTY0;
-+}
-+
-+
-+void ramses_lcd_set_intensity(int i)
-+{
-+ //printk("--> ramses_lcd_set_intensity(%d)\n", i);
-+ if (i) {
-+ ramses_lcd_backlight_on();
-+ } else {
-+ ramses_lcd_backlight_off();
-+ }
-+}
-+
-+
-+int ramses_lcd_get_intensity(void)
-+{
-+ return ramses_control_shadow & RAMSES_CONTROL_LCD_BLIGHT;
-+}
-+
-+
-+
-+
-+
-+/******************************************************************/
-+/* HDQ communication */
-+/******************************************************************/
-+
-+#define GPIO_HDQ 2
-+
-+#define HDQ_LO GPCR(GPIO_HDQ) = GPIO_bit(GPIO_HDQ)
-+#define HDQ_HI GPSR(GPIO_HDQ) = GPIO_bit(GPIO_HDQ)
-+#define HDQ_GET (GPLR(GPIO_HDQ) & (1 << GPIO_HDQ))
-+
-+#define MAXLOOPS 800
-+#define MAXTRIES 3
-+
-+
-+static void hdq_break(void)
-+{
-+ HDQ_LO;
-+ set_GPIO_mode(GPIO_HDQ | GPIO_OUT);
-+ udelay(220);
-+ HDQ_HI;
-+ udelay(50);
-+}
-+
-+
-+/**
-+ * Send data on the 1-bit wire.
-+ *
-+ * LSB first. Depending on the bit, do the low phase short or
-+ * small. The used timings in usec's are made so that our send
-+ * stuff has exactly the timing that the BQ2050 battery sends
-+ * us back.
-+*/
-+static void hdq_put_data(unsigned char cmd)
-+{
-+ unsigned char mask = 1;
-+
-+ HDQ_HI;
-+ set_GPIO_mode(GPIO_HDQ | GPIO_OUT);
-+
-+ while (1) {
-+ HDQ_LO;
-+ udelay(cmd & mask ? 37 : 115);
-+ HDQ_HI;
-+ udelay(cmd & mask ? 163 : 85);
-+ if (mask == 0x80) break;
-+ mask = mask << 1;
-+ }
-+ set_GPIO_mode(GPIO_HDQ | GPIO_IN);
-+}
-+
-+
-+/**
-+ * Receive data on the 1-bit wire.
-+ *
-+ * Little state-machine with two states (yuck) that measures the time
-+ * in the low-state. If it exceeds some value, then the bit was a 0,
-+ * otherwise it's a 1.
-+*/
-+static int hdq_get_data(void)
-+{
-+ enum { ST_WAITLOW, ST_LOW };
-+
-+ int i;
-+ int lastlow = 0;
-+ int state = ST_WAITLOW;
-+ unsigned char mask = 1;
-+ unsigned char d = 0;
-+
-+ for (i=0; i<MAXLOOPS; i++) {
-+ if (state==ST_WAITLOW) {
-+ if (HDQ_GET == 0) {
-+ lastlow = i;
-+ state = ST_LOW;
-+ }
-+ } else
-+ if (state == ST_LOW) {
-+ if (HDQ_GET) {
-+ // 34 must be changed if the udelay(2) changes!
-+ if (i-lastlow < 34) {
-+ d = d | mask;
-+ }
-+ if (mask == 0x80) break;
-+ mask = mask << 1;
-+ state = ST_WAITLOW;
-+ }
-+ }
-+ udelay(2);
-+ }
-+ if (i==MAXLOOPS) {
-+ //printk("no respone after %d\n", i);
-+ return -1;
-+ } else {
-+ //printk("done after %d: %d %x\n", i, d, d);
-+ return d;
-+ }
-+}
-+
-+
-+static int hdq_get_reg_once(unsigned char reg)
-+{
-+ int d = -1;
-+ int i;
-+
-+ reg &= 0x7f;
-+
-+ for (i=0; i<MAXTRIES; i++) {
-+ hdq_break();
-+ hdq_put_data(reg);
-+ d = hdq_get_data();
-+ if (d != -1)
-+ break;
-+ //printk("hdq_get_reg_once try again: %d\n", i);
-+ }
-+
-+ return d;
-+}
-+
-+/**
-+ * The HDQ protocol communication is so bad that we can't really
-+ * be sure that we got something usable. So we call hdq_get_reg_once()
-+ * twice and compare if we got the same value twice. If not, we try
-+ * again. And again, and again ... up to MAXTRIES times.
-+ */
-+int ramses_hdq_get_reg(unsigned char reg)
-+{
-+ int i,d1,d2;
-+
-+ d1 = hdq_get_reg_once(reg);
-+ for (i=0; i<MAXTRIES; i++) {
-+ d2 = hdq_get_reg_once(reg);
-+ if (d1 == d2)
-+ return d2;
-+ d1 = d2;
-+ }
-+ printk("no response from battery\n");
-+ return -1;
-+}
-+
-+
-+
-+/******************************************************************/
-+/* Power Management */
-+/******************************************************************/
-+
-+#ifdef CONFIG_PM
-+static int
-+ramses_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data)
-+{
-+ static int old_shadow;
-+ static int old_ctrl0;
-+ static int old_ctrl1;
-+ static int old_perval0;
-+ static int old_perval1;
-+ static int old_duty0;
-+ static int old_duty1;
-+
-+ switch (req) {
-+ case PM_SUSPEND:
-+ old_shadow = ramses_control_shadow;
-+ old_ctrl0 = PWM_CTRL0;
-+ old_ctrl1 = PWM_CTRL1;
-+ old_perval0 = PWM_PERVAL0;
-+ old_perval1 = PWM_PERVAL1;
-+ old_duty0 = PWM_PWDUTY0;
-+ old_duty1 = PWM_PWDUTY1;
-+
-+ // RAMSES_LED_BLUE_OFF();
-+ // RAMSES_LED_ORANGE_OFF();
-+ RAMSES_UART_OFF();
-+ // RAMSES_SCANNER_OFF();
-+ // RAMSES_USB_BUS_OFF();
-+ // printk("shadow: %08x -> %08x\n", old_shadow, ramses_control_shadow);
-+
-+ RAMSES_CPLD_PERIPH_PWR &= ~PER_PWR_EN;
-+ break;
-+
-+ case PM_RESUME:
-+ RAMSES_CPLD_PERIPH_PWR |= PER_PWR_EN;
-+ ramses_control_shadow = old_shadow;
-+ PWM_CTRL0 = old_ctrl0;
-+ PWM_CTRL1 = old_ctrl1;
-+ PWM_PERVAL0 = old_perval0;
-+ PWM_PERVAL1 = old_perval1;
-+ PWM_PWDUTY0 = old_duty0;
-+ PWM_PWDUTY1 = old_duty1;
-+
-+ break;
-+ }
-+ return 0;
-+}
-+
-+#endif
-+
-+
-+
-+static void pf_interrupt(int irq, void *dummy, struct pt_regs *fp)
-+{
-+#ifdef PFI_LED
-+ RAMSES_LED_BLUE_ON();
-+ RAMSES_LED_ORANGE_ON();
-+#endif
-+#ifdef PFI_TURNOFF
-+ // Make sure we can't be turned on by setting low onto the CPLD's columns
-+ RAMSES_CPLD_KB_COL_LOW = 0;
-+ RAMSES_CPLD_KB_COL_HIGH = 0;
-+
-+ // turn power off
-+ RAMSES_POWER_OFF();
-+
-+ // wait until VCC fades
-+ while (1) { }
-+#endif
-+}
-+
-+
-+void ramses_shut_off(void)
-+{
-+ // Make sure we can't be turned on by setting low onto the CPLD's columns
-+ RAMSES_CPLD_KB_COL_LOW = 0;
-+ RAMSES_CPLD_KB_COL_HIGH = 0;
-+ //printk("--> ramses_shut_off calling ramses_lcd_backlight_off\n");
-+ ramses_lcd_backlight_off();
-+ //printk("--> ramses_shut_off calling ramses_lcd_power_off\n");
-+ ramses_lcd_power_off();
-+
-+ // turn power off
-+ RAMSES_POWER_OFF();
-+
-+ // wait until voltage fades
-+ while (1) {}
-+}
-+
-+
-+
-+
-+#ifdef CONFIG_APM
-+static int ramses_get_power_status(u_char *ac_line_status,
-+ u_char *battery_status,
-+ u_char *battery_flag,
-+ u_char *battery_percentage,
-+ u_short *battery_life)
-+{
-+#ifdef USE_UCB
-+ int adc3;
-+ struct ucb1x00 *ucb = ucb1x00_get();
-+
-+ ucb1x00_adc_enable(ucb);
-+ adc3 = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD3, 0);
-+ ucb1x00_adc_disable(ucb);
-+
-+ /*
-+ * when charged: 0..430
-+ * when discharging: 0..340
-+ */
-+
-+#define CHG_LO 165
-+#define CHG_HI 420
-+#define OFF_LO 60
-+#define OFF_HI 350
-+ if ((RAMSES_CPLD_MISC_STATUS & RAMSES_CHG_STS) == 0) {
-+ // in Docking-Station
-+ if (adc3 > CHG_HI) adc3 = CHG_HI;
-+ if (adc3 < CHG_LO) adc3 = CHG_LO;
-+ adc3 -= CHG_LO;
-+ *battery_percentage = adc3 * 100 / (CHG_HI-CHG_LO);
-+ *ac_line_status = 0x01;
-+ } else {
-+ // offline
-+ if (adc3 > OFF_HI) adc3 = OFF_HI;
-+ if (adc3 < OFF_LO) adc3 = OFF_LO;
-+ adc3 -= OFF_LO;
-+ *battery_percentage = adc3 * 100 / (OFF_HI-OFF_LO);
-+ *ac_line_status = 0x00;
-+ }
-+
-+ if (*battery_percentage > 100)
-+ *battery_percentage = 100;
-+
-+ if (*ac_line_status) {
-+ *battery_status = 3; // charging
-+ *battery_flag = 1<<3;
-+ } else
-+ if (*battery_percentage >= 30) {
-+ *battery_status = 0; // high
-+ *battery_flag = 1<<0;
-+ } else
-+ if (*battery_percentage >= 15) {
-+ *battery_status = 1; // low
-+ *battery_flag = 1<<1;
-+ } else {
-+ *battery_status = 2; // critical
-+ *battery_flag = 1<<2;
-+ }
-+
-+ // assume 5.5 hours operation, 330 minutes
-+ *battery_life = (*battery_percentage * 330 / 100) | 0x8000;
-+#endif
-+
-+
-+#ifdef USE_HDQ
-+#error HDQ
-+ // SAE is something like mAh * 10
-+ int sae, sael;
-+
-+ sael = ramses_hdq_get_reg(HDQ_SAEL);
-+ sae = ramses_hdq_get_reg(HDQ_SAEH);
-+
-+ if (sae == -1 || sael == -1) {
-+ //printk("ramses: could not read HDQ_SAE\n");
-+ *ac_line_status = 0xff;
-+ *battery_status = 0xff;
-+ *battery_flag = 0xff;
-+ *battery_percentage = 0xff;
-+ *battery_life = -1;
-+ return 0;
-+ }
-+
-+ sae = (sae << 16) + sael;
-+ if (sae > 27000) {
-+ printk("ramses: capped HDQ_SAE from %d to 27000\n", sae);
-+ sae = 27000;
-+ }
-+
-+ if (sae < 4000) {
-+ *battery_status = 2; // critical
-+ *battery_flag = 1<<2;
-+ } else
-+ if (sae < 10000) {
-+ *battery_status = 1; // low
-+ *battery_flag = 1<<1;
-+ } else {
-+ *battery_status = 0; // high
-+ *battery_flag = 1<<0;
-+ }
-+
-+ if ((RAMSES_CPLD_MISC_STATUS & RAMSES_CHG_STS) == 0) {
-+ *battery_status = 3; // charging
-+ *battery_flag = 1<<3;
-+ *ac_line_status = 0x01; // online
-+ } else {
-+ *ac_line_status = 0x00; // offline
-+ }
-+
-+ *battery_percentage = sae / 270;
-+ *battery_life = (sae / 56) | 0x8000;
-+#endif
-+
-+
-+#if !defined(USE_UCB) && !defined(USE_HDQ)
-+#error NONE
-+ *ac_line_status = 0xff;
-+ *battery_status = 0xff;
-+ *battery_flag = 0xff;
-+ *battery_percentage = 0xff;
-+ *battery_life = -1;
-+#endif
-+
-+ return 0;
-+}
-+#endif
-+
-+
-+
-+
-+/******************************************************************/
-+/* Initialisation */
-+/******************************************************************/
-+
-+static struct map_desc ramses_io_desc[] __initdata = {
-+ /* virtual physical length domain r w c b */
-+ { RAMSES_IDE_BASE, RAMSES_IDE_PHYS, RAMSES_IDE_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
-+ { RAMSES_ETH_BASE, RAMSES_ETH_PHYS, RAMSES_ETH_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
-+ { RAMSES_COREVOLT_BASE, RAMSES_COREVOLT_PHYS, RAMSES_COREVOLT_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
-+ { RAMSES_CPLD_BASE, RAMSES_CPLD_PHYS, RAMSES_CPLD_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
-+ { RAMSES_CONTROL_BASE, RAMSES_CONTROL_PHYS, RAMSES_CONTROL_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
-+ LAST_DESC
-+};
-+
-+
-+
-+
-+
-+/*
-+ * Uncompressing Linux...... done, booting the kernel.
-+ * Linux version 2.4.19-rmk4-pxa1-mn ...
-+ * CPU: Intel XScale-PXA250 revision 4
-+ * Machine: Ramses
-+ * fixup_ramses()
-+ */
-+
-+static void __init
-+fixup_ramses(struct machine_desc *desc, struct param_struct *params,
-+ char **cmdline, struct meminfo *mi)
-+{
-+ SET_BANK (0, 0xa0000000,128*1024*1024);
-+ mi->nr_banks = 1;
-+}
-+
-+
-+
-+
-+/*
-+ * fixup_ramses()
-+ * ramses_map_io()
-+ */
-+
-+static void __init ramses_map_io(void)
-+{
-+ u16 smc_eeprom_read(long ioaddr, u16 location);
-+
-+ pxa_map_io();
-+ iotable_init(ramses_io_desc);
-+
-+#ifdef IPAQ
-+ // set power managament stuff
-+ PGSR0 = GPSRx_SleepValue;
-+ PGSR1 = GPSRy_SleepValue;
-+ PGSR2 = GPSRz_SleepValue;
-+ PWER = PWER_GPIO0 | PWER_RTC;
-+ PFER = PWER_GPIO0 | PWER_RTC;
-+ PRER = 0;
-+#endif
-+
-+ ramses_lcd_type = smc_eeprom_read(RAMSES_ETH_BASE+0x300, RAMSES_LCD_TYPE_OFFSET);
-+ // here we could make a special case about ramses_lcd_type == 0xffff
-+ ramses_flags |= (ramses_lcd_type & RAMSES_FLAGS_LCD_FBTURN);
-+}
-+
-+
-+
-+
-+/*
-+ * ramses_map_io()
-+ * Memory clock: 99.53MHz (*27)
-+ * Run Mode clock: 199.07MHz (*2)
-+ * Turbo Mode clock: 398.13MHz (*2.0, active) * On node 0 totalpages: 16384
-+ * zone(0): 32768 pages.
-+ * zone(1): 0 pages.
-+ * zone(2): 0 pages.
-+ * Kernel command line: root=/dev/nfsroot ...
-+ * ramses_init_irq()
-+ */
-+
-+static void __init ramses_init_irq(void)
-+{
-+ set_GPIO_IRQ_edge(21, GPIO_FALLING_EDGE); // UCB 1400
-+
-+ RAMSES_SCANNER_OFF();
-+ RAMSES_GSM_OFF();
-+ RAMSES_GSM_RESET_OFF();
-+ RAMSES_GSM_BOOT_OFF();
-+ pxa_init_irq();
-+}
-+
-+
-+
-+
-+/*
-+ * ramses_init_irq()
-+ * Console: colour dummy device 80x30
-+ * serial_console_init
-+ * serial_console_setup
-+ * Calibrating delay loop... 397.31 BogoMIPS
-+ * Memory: 128MB = 128MB total
-+ * Memory: 127872KB available (1355K code, 272K data, 112K init)
-+ * Dentry cache hash table entries: 16384 (order: 5, 131072 bytes)
-+ * Inode cache hash table entries: 8192 (order: 4, 65536 bytes)
-+ * Mount-cache hash table entries: 2048 (order: 2, 16384 bytes)
-+ * Buffer-cache hash table entries: 8192 (order: 3, 32768 bytes)
-+ * Page-cache hash table entries: 32768 (order: 5, 131072 bytes)
-+ * POSIX conformance testing by UNIFIX
-+ * Linux NET4.0 for Linux 2.4
-+ * Based upon Swansea University Computer Society NET3.039
-+ * Initializing RT netlink socket
-+ * ramses_init()
-+ */
-+
-+static int __init ramses_init(void)
-+{
-+ unsigned int irq_gpio_pin;
-+
-+ // Set IRQ for Touchpanel (via UCB 1400)
-+ irq_gpio_pin = IRQ_TO_GPIO_2_80(TOUCH_PANEL_IRQ);
-+ set_GPIO_IRQ_edge(irq_gpio_pin, TOUCH_PANEL_IRQ_EDGE);
-+
-+ // Set IRQ for Power Fail Interrupt
-+ set_GPIO_IRQ_edge(1, GPIO_FALLING_EDGE);
-+ request_irq(IRQ_GPIO(1), pf_interrupt, 0, "PWR FAIL", NULL);
-+
-+ // Setup IRQ edge for Ethernet
-+ //set_GPIO_IRQ_edge(IRQ_TO_GPIO_2_80(27), GPIO_RISING_EDGE);
-+ set_GPIO_IRQ_edge(IRQ_TO_GPIO_2_80(ETHERNET_IRQ), ETHERNET_IRQ_EDGE);
-+
-+ // Configure PWMs for LCD
-+ PWM_CTRL0 = 0;
-+ PWM_PERVAL0 = 512;
-+ PWM_PWDUTY0 = 440;
-+ PWM_CTRL1 = 0;
-+ PWM_PERVAL1 = 512;
-+ PWM_PWDUTY1 = 450;
-+
-+ // Request Memory Regions of core components
-+ request_mem_region(RAMSES_CONTROL_BASE, RAMSES_CONTROL_SIZE, "Ramses Control");
-+ request_mem_region(RAMSES_CPLD_BASE, RAMSES_CPLD_SIZE, "Ramses CPLD");
-+ request_mem_region(RAMSES_COREVOLT_BASE, RAMSES_COREVOLT_SIZE, "Ramses Corevolt");
-+
-+#ifdef CONFIG_PM
-+#ifdef PM_DEBUG
-+ pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, ramses_pm_callback, "ramses");
-+#else
-+ pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, ramses_pm_callback);
-+#endif
-+ //TODO PWER (PXA255: 3-25)
-+ //TODO PRER (PXA255: 3-26)
-+ //TODO PFER (PXA255: 3-27)
-+ //TODO PSSR (PXA255: 3-29)
-+ //TODO PGSR0..PGSR2 (PXA255: 3-32)
-+#endif
-+
-+#ifdef CONFIG_APM
-+ apm_register_get_power_status(ramses_get_power_status);
-+#endif
-+
-+ PCFR = PCFR_OPDE | PCFR_FS | PCFR_FP; // PXA255: 3-24
-+
-+ pm_power_off = ramses_shut_off;
-+
-+ return 0;
-+}
-+
-+__initcall(ramses_init);
-+
-+
-+
-+/*
-+ * ramses_init()
-+ * Using PXA255 frequency points.
-+ * Registering CPU frequency change support.
-+ * CPU clock: 398.131 MHz (99.000-400.000 MHz)
-+ * Starting kswapd
-+ * devfs: v1.12a (20020514) Richard Gooch (rgooch@atnf.csiro.au)
-+ * devfs: boot_options: 0x1
-+ * pty: 256 Unix98 ptys configured
-+ * pxa & ti16c754b serial driver
-+ * tts/0 at irq 14 is a PXA UART
-+ * tts/1 at irq 13 is a PXA UART
-+ * tts/2 at irq 12 is a PXA UART
-+ * tts/3 at irq 45 is a TI16750
-+ * tts/4 at irq 46 is a TI16750
-+ * tts/5 at irq 47 is a TI16750
-+ * tts/6 at irq 48 is a TI16750
-+ * LAN91C111: You shouldn't use auto-probing with insmod!
-+ * SMSC LAN91C111 Driver (v2.2), (Linux Kernel 2.4 + Support for Odd Byte) ...
-+ * eth0: SMC91C11xFD(rev:1) at 0xf0100300 IRQ:26 MEMSIZE ...
-+ * ac97_codec: AC97 Audio codec, id: 0x5053:0x4304 (Philips UCB1400)
-+ * NET4: Linux TCP/IP 1.0 for NET4.0
-+ * IP Protocols: ICMP, UDP, TCP
-+ * IP: routing cache hash table of 512 buckets, 4Kbytes
-+ * TCP: Hash tables configured (established 4096 bind 4096)
-+ * IP-Config: ...
-+ * NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
-+ * NetWinder Floating Point Emulator V0.95 (c) 1998-1999 Rebel.com
-+ * Looking up port of RPC 100003/2 on 192.168.233.66
-+ * Looking up port of RPC 100005/1 on 192.168.233.66
-+ * VFS: Mounted root (nfs filesystem).
-+ * Mounted devfs on /dev
-+ * Freeing init memory: 68K
-+ * INIT: version 2.84 booting
-+ */
-+
-+
-+
-+MACHINE_START(RAMSES, "Ramses")
-+ MAINTAINER("M&N Logistik-Lösungen Online GmbH")
-+ BOOT_MEM(0xa0000000, 0x40000000, 0xfc000000)
-+ BOOT_PARAMS(0xa0000100)
-+ FIXUP(fixup_ramses)
-+ MAPIO(ramses_map_io)
-+ INITIRQ(ramses_init_irq)
-+MACHINE_END
-+
-+EXPORT_SYMBOL(ramses_lcd_type);
-+EXPORT_SYMBOL(ramses_lcd_power_on);
-+EXPORT_SYMBOL(ramses_lcd_power_off);
-+EXPORT_SYMBOL(ramses_lcd_backlight_on);
-+EXPORT_SYMBOL(ramses_lcd_backlight_off);
-+EXPORT_SYMBOL(ramses_lcd_set_intensity);
-+EXPORT_SYMBOL(ramses_lcd_set_brightness);
-+EXPORT_SYMBOL(ramses_lcd_set_contrast);
-+EXPORT_SYMBOL(ramses_lcd_get_intensity);
-+EXPORT_SYMBOL(ramses_lcd_get_brightness);
-+EXPORT_SYMBOL(ramses_lcd_get_contrast);
-+EXPORT_SYMBOL(ramses_hdq_get_reg);
-+EXPORT_SYMBOL(ramses_set_corevolt);
-+EXPORT_SYMBOL(ramses_corevolt_shadow);
---- linux-2.4.21/arch/arm/mach-pxa/usb-char.c~pxa-usb
-+++ linux-2.4.21/arch/arm/mach-pxa/usb-char.c
-@@ -211,7 +211,6 @@
- static void twiddle_descriptors( void )
- {
- desc_t * pDesc = pxa_usb_get_descriptor_ptr();
-- string_desc_t * pString;
-
- pDesc->b.ep1.wMaxPacketSize = make_word_c( RX_PACKET_SIZE );
- pDesc->b.ep1.bmAttributes = USB_EP_BULK;
-@@ -220,6 +219,7 @@
-
- if ( machine_is_extenex1() ) {
- #ifdef CONFIG_SA1100_EXTENEX1
-+ string_desc_t * pString;
- pDesc->dev.idVendor = make_word_c( 0xC9F );
- pDesc->dev.idProduct = 1;
- pDesc->dev.bcdDevice = make_word_c( 0x0001 );
---- linux-2.4.21/arch/arm/mach-pxa/usb-eth.c~pxa-usbeth
-+++ linux-2.4.21/arch/arm/mach-pxa/usb-eth.c
-@@ -52,6 +52,7 @@
-
- #define ETHERNET_VENDOR_ID 0x49f
- #define ETHERNET_PRODUCT_ID 0x505A
-+#define ETHERNET_DEVICE_ID 0x0200
- #define MAX_PACKET 32768
- #define MIN(a, b) (((a) < (b)) ? (a) : (b))
-
-@@ -329,6 +330,7 @@
- pd->b.ep2.wMaxPacketSize = make_word( usb_wsize );
- pd->dev.idVendor = ETHERNET_VENDOR_ID;
- pd->dev.idProduct = ETHERNET_PRODUCT_ID;
-+ pd->dev.bcdDevice = ETHERNET_DEVICE_ID;
- pstr = pxa_usb_kmalloc_string_descriptor( "PXA USB NIC" );
- if ( pstr ) {
- pxa_usb_set_string_descriptor( 1, pstr );
---- linux-2.4.21/drivers/char/Config.in~i2c-ds1337
-+++ linux-2.4.21/drivers/char/Config.in
-@@ -164,6 +164,7 @@
-
- if [ "$CONFIG_I2C" != "n" ]; then
- dep_tristate ' DS1307 RTC' CONFIG_I2C_DS1307 $CONFIG_I2C
-+ dep_tristate ' DS1337 RTC' CONFIG_I2C_DS1337 $CONFIG_I2C
- fi
-
- source drivers/l3/Config.in
---- linux-2.4.21/drivers/char/Makefile~i2c-ds1337
-+++ linux-2.4.21/drivers/char/Makefile
-@@ -21,10 +21,11 @@
- # All of the (potential) objects that export symbols.
- # This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
-
--export-objs := busmouse.o console.o keyboard.o sysrq.o \
-+export-objs := vt.o busmouse.o console.o keyboard.o sysrq.o \
- misc.o pty.o random.o selection.o serial.o \
- sonypi.o tty_io.o tty_ioctl.o generic_serial.o \
-- au1000_gpio.o hp_psaux.o nvram.o scx200.o
-+ au1000_gpio.o hp_psaux.o nvram.o scx200.o \
-+ input_keyb.o
-
- mod-subdirs := joystick ftape drm drm-4.0 pcmcia
-
-@@ -129,6 +130,11 @@
- ifeq ($(CONFIG_SA1100_CERF_CPLD),y)
- KEYBD += cerf_keyb.o
- endif
-+ ifeq ($(CONFIG_ARCH_RAMSES),y)
-+ KEYMAP = german.o
-+ KEYBD += input_keyb.o
-+ obj-m += sysctl.o
-+ endif
- ifeq ($(CONFIG_ARCH_FORTUNET),y)
- KEYMAP := defkeymap.o
- endif
-@@ -337,6 +343,7 @@
-
- # I2C char devices
- obj-$(CONFIG_I2C_DS1307) += ds1307.o
-+obj-$(CONFIG_I2C_DS1337) += ds1337.o
-
- subdir-$(CONFIG_MWAVE) += mwave
- ifeq ($(CONFIG_MWAVE),y)
-@@ -372,4 +379,7 @@
- set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@
-
- qtronixmap.c: qtronixmap.map
-+ set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@
-+
-+german.c: german.map
- set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@
---- linux-2.4.21/drivers/char/console.c~keyb-module
-+++ linux-2.4.21/drivers/char/console.c
-@@ -150,7 +150,7 @@
- static int con_open(struct tty_struct *, struct file *);
- static void vc_init(unsigned int console, unsigned int rows,
- unsigned int cols, int do_clear);
--static void blank_screen(unsigned long dummy);
-+//static void blank_screen(unsigned long dummy);
- static void gotoxy(int currcons, int new_x, int new_y);
- static void save_cur(int currcons);
- static void reset_terminal(int currcons, int do_clear);
-@@ -158,7 +158,7 @@
- static void set_vesa_blanking(unsigned long arg);
- static void set_cursor(int currcons);
- static void hide_cursor(int currcons);
--static void unblank_screen_t(unsigned long dummy);
-+//static void unblank_screen_t(unsigned long dummy);
- static void console_callback(void *ignored);
-
- static int printable; /* Is console ready for printing? */
-@@ -167,7 +167,7 @@
- int console_blanked;
-
- static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
--static int blankinterval = 10*60*HZ;
-+//static int blankinterval = 10*60*HZ;
- static int vesa_off_interval;
-
- static struct tq_struct console_callback_tq = {
-@@ -209,9 +209,9 @@
- * Hook so that the power management routines can (un)blank
- * the console on our behalf.
- */
--int (*console_blank_hook)(int);
-+//int (*console_blank_hook)(int);
-
--static struct timer_list console_timer;
-+//static struct timer_list console_timer;
-
- /*
- * Low-Level Functions
-@@ -543,7 +543,7 @@
-
- static void set_cursor(int currcons)
- {
-- if (!IS_FG || console_blanked || vcmode == KD_GRAPHICS)
-+ if (!IS_FG || vcmode == KD_GRAPHICS)
- return;
- if (deccm) {
- if (currcons == sel_cons)
-@@ -1287,7 +1287,7 @@
- update_attr(currcons);
- break;
- case 9: /* set blanking interval */
-- blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
-+ //blankinterval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
- poke_blanked_console();
- break;
- case 10: /* set bell frequency in Hz */
-@@ -2575,11 +2575,11 @@
- if (tty_register_driver(&console_driver))
- panic("Couldn't register console driver\n");
-
-- init_timer(&console_timer);
-- console_timer.function = blank_screen;
-- if (blankinterval) {
-- mod_timer(&console_timer, jiffies + blankinterval);
-- }
-+ //init_timer(&console_timer);
-+ //console_timer.function = blank_screen;
-+ //if (blankinterval) {
-+ // mod_timer(&console_timer, jiffies + blankinterval);
-+ //}
-
- /*
- * kmalloc is not running yet - we use the bootmem allocator.
-@@ -2744,11 +2744,12 @@
- */
- static void vesa_powerdown_screen(unsigned long dummy)
- {
-- console_timer.function = unblank_screen_t;
-+ //console_timer.function = unblank_screen_t;
-
- vesa_powerdown();
- }
-
-+#if 0
- static void timer_do_blank_screen(int entering_gfx, int from_timer_handler)
- {
- int currcons = fg_console;
-@@ -2797,12 +2798,14 @@
- if (vesa_blank_mode)
- sw->con_blank(vc_cons[currcons].d, vesa_blank_mode + 1);
- }
-+#endif
-
- void do_blank_screen(int entering_gfx)
- {
-- timer_do_blank_screen(entering_gfx, 0);
-+ //timer_do_blank_screen(entering_gfx, 0);
- }
-
-+#if 0
- /*
- * This is a timer handler
- */
-@@ -2810,12 +2813,14 @@
- {
- unblank_screen();
- }
-+#endif
-
- /*
- * Called by timer as well as from vt_console_driver
- */
- void unblank_screen(void)
- {
-+#if 0
- int currcons;
-
- if (!console_blanked)
-@@ -2842,6 +2847,7 @@
- /* Low-level driver cannot restore -> do it ourselves */
- update_screen(fg_console);
- set_cursor(fg_console);
-+#endif
- }
-
- /*
-@@ -2849,11 +2855,12 @@
- */
- static void blank_screen(unsigned long dummy)
- {
-- timer_do_blank_screen(0, 1);
-+ //timer_do_blank_screen(0, 1);
- }
-
- void poke_blanked_console(void)
- {
-+#if 0
- del_timer(&console_timer);
- if (!vt_cons[fg_console] || vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
- return;
-@@ -2863,6 +2870,7 @@
- } else if (blankinterval) {
- mod_timer(&console_timer, jiffies + blankinterval);
- }
-+#endif
- }
-
- /*
-@@ -3088,7 +3096,7 @@
- unblank_screen();
- break;
- case PM_SUSPEND:
-- do_blank_screen(0);
-+ //do_blank_screen(0);
- break;
- }
- return 0;
-@@ -3106,7 +3114,8 @@
- EXPORT_SYMBOL(video_scan_lines);
- EXPORT_SYMBOL(vc_resize);
- EXPORT_SYMBOL(fg_console);
--EXPORT_SYMBOL(console_blank_hook);
-+//EXPORT_SYMBOL(console_blank_hook);
-+EXPORT_SYMBOL(console_driver);
- #ifdef CONFIG_VT
- EXPORT_SYMBOL(vt_cons);
- #endif
---- /dev/null
-+++ linux-2.4.21/drivers/char/ds1337.c
-@@ -0,0 +1,545 @@
-+/*
-+ * ds1337.c
-+ *
-+ * Device driver for Dallas Semiconductor's Real Time Controller DS1337.
-+ *
-+ * Copyright (C) 2003 M&N Logistik-Lösungen Online GmbH
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Documentation for this Chip: http://pdfserv.maxim-ic.com/arpdf/DS1337.pdf
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/version.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/poll.h>
-+#include <linux/i2c.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/rtc.h>
-+#include <linux/string.h>
-+#include <linux/miscdevice.h>
-+#include <linux/proc_fs.h>
-+
-+#include "ds1337.h"
-+
-+//#define DEBUG 1
-+
-+#if DEBUG
-+static unsigned int rtc_debug = DEBUG;
-+#else
-+#define rtc_debug 0 /* gcc will remove all the debug code for us */
-+#endif
-+
-+static unsigned short slave_address = DS1337_I2C_SLAVE_ADDR;
-+struct i2c_driver ds1337_driver;
-+struct i2c_client *ds1337_i2c_client = 0;
-+static spinlock_t ds1337_rtc_lock = SPIN_LOCK_UNLOCKED;
-+
-+static unsigned short ignore[] = { I2C_CLIENT_END };
-+static unsigned short normal_addr[] = { DS1337_I2C_SLAVE_ADDR, I2C_CLIENT_END };
-+
-+static int ds1337_rtc_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
-+static int ds1337_rtc_noop(struct inode *inode, struct file *file);
-+
-+static int ds1337_probe(struct i2c_adapter *adap);
-+static int ds1337_detach(struct i2c_client *client);
-+static int ds1337_command(struct i2c_client *client, unsigned int cmd, void *arg);
-+
-+
-+static struct i2c_client_address_data addr_data = {
-+ .normal_i2c = normal_addr,
-+ .normal_i2c_range = ignore,
-+ .probe = ignore,
-+ .probe_range = ignore,
-+ .ignore = ignore,
-+ .ignore_range = ignore,
-+ .force = ignore,
-+};
-+
-+static struct file_operations rtc_fops = {
-+ .owner = THIS_MODULE,
-+ .ioctl = ds1337_rtc_ioctl,
-+ .open = ds1337_rtc_noop,
-+ .release = ds1337_rtc_noop,
-+};
-+
-+static struct miscdevice ds1337_rtc_miscdev = {
-+ RTC_MINOR,
-+ "rtc",
-+ &rtc_fops
-+};
-+
-+
-+struct i2c_driver ds1337_driver = {
-+ .name = "DS1337",
-+ .id = I2C_DRIVERID_DS1337,
-+ .flags = I2C_DF_NOTIFY,
-+ .attach_adapter = ds1337_probe,
-+ .detach_client = ds1337_detach,
-+ .command = ds1337_command
-+};
-+
-+#define DAT(x) ((unsigned int)((x)->data)) /* keep the control register info */
-+
-+
-+static int ds1337_readram(char *buf, int len)
-+{
-+ unsigned long flags;
-+ unsigned char ad[1] = { 0 };
-+ int ret;
-+ struct i2c_msg msgs[2] = {
-+ {ds1337_i2c_client->addr, 0, 1, ad},
-+ {ds1337_i2c_client->addr, I2C_M_RD, len, buf}
-+ };
-+
-+ spin_lock_irqsave(&ds1337_rtc_lock, flags);
-+ ret = i2c_transfer(ds1337_i2c_client->adapter, msgs, 2);
-+ spin_unlock_irqrestore(&ds1337_rtc_lock, flags);
-+
-+ return ret;
-+}
-+
-+
-+static void ds1337_setreg(struct i2c_client *c, unsigned char reg, unsigned char val)
-+{
-+ unsigned char buf[2];
-+ buf[0] = reg;
-+ buf[1] = val;
-+ i2c_master_send(c, (char *) buf, 2);
-+}
-+
-+static int ds1337_attach(struct i2c_adapter *adap, int addr,
-+ unsigned short flags, int kind)
-+{
-+ struct i2c_client *c;
-+ unsigned char buf[DS1337_MEM_SIZE], ad[1] = { 7 };
-+ struct i2c_msg msgs[2] = {
-+ {addr, 0, 1, ad},
-+ {addr, I2C_M_RD, 1, buf}
-+ };
-+ int ret;
-+
-+ if (rtc_debug>1)
-+ printk("%s(adap,%d,%d,%d)\n", __FUNCTION__, addr, flags, kind);
-+
-+ c = (struct i2c_client *) kmalloc(sizeof(*c), GFP_KERNEL);
-+ if (!c)
-+ return -ENOMEM;
-+
-+ strcpy(c->name, "DS1337");
-+ c->id = ds1337_driver.id;
-+ c->flags = 0;
-+ c->addr = addr;
-+ c->adapter = adap;
-+ c->driver = &ds1337_driver;
-+ c->data = NULL;
-+
-+ ret = i2c_transfer(c->adapter, msgs, 2);
-+
-+ if (ret == 2) {
-+ DAT(c) = buf[0];
-+ } else
-+ printk("ds1337_attach(): i2c_transfer() returned %d.\n", ret);
-+
-+ ds1337_i2c_client = c;
-+
-+ ds1337_readram(buf, DS1337_MEM_SIZE);
-+
-+ // set 24 hour mode
-+ ds1337_setreg(c, 0x2, buf[2] | DS1337_HOUR24);
-+ // INTCN sets INTB to alarm2 (disables SQW)
-+ ds1337_setreg(c, 0x5, buf[5] & 0x7f); // clear century
-+ ds1337_setreg(c, 0x7, 0x00); // clear Alarm 1 seconds
-+ ds1337_setreg(c, 0x8, 0x00); // clear Alarm 1 minutes
-+ ds1337_setreg(c, 0x9, 0x40); // clear Alarm 1 hours, 24 hour on
-+ ds1337_setreg(c, 0xA, 0x00); // clear Alarm 1 date
-+ ds1337_setreg(c, 0xB, 0x00); // clear Alarm 2 minutes
-+ ds1337_setreg(c, 0xC, 0x40); // clear Alarm 2 hours, 24 hour on
-+ ds1337_setreg(c, 0xD, 0x00); // clear Alarm 2 date
-+ ds1337_setreg(c, 0xe, 4); // nEOSC enabled
-+ ds1337_setreg(c, 0xf, 0); // clear OSF, A2F, A1F
-+
-+ return i2c_attach_client(c);
-+}
-+
-+
-+static int ds1337_probe(struct i2c_adapter *adap)
-+{
-+ if (rtc_debug>1)
-+ printk("%s()\n", __FUNCTION__);
-+
-+ return i2c_probe(adap, &addr_data, ds1337_attach);
-+}
-+
-+
-+static int ds1337_detach(struct i2c_client *client)
-+{
-+ if (rtc_debug>1)
-+ printk("%s()\n", __FUNCTION__);
-+
-+ i2c_detach_client(client);
-+
-+ return 0;
-+}
-+
-+
-+static void ds1337_convert_to_time(struct rtc_time *dt, char *buf)
-+{
-+ if (rtc_debug>1)
-+ printk("%s()\n", __FUNCTION__);
-+
-+ dt->tm_sec = BCD_TO_BIN(buf[0]);
-+ dt->tm_min = BCD_TO_BIN(buf[1]);
-+ dt->tm_hour = DS1337_HOURS_24(buf[2]);
-+
-+ dt->tm_mday = BCD_TO_BIN(buf[4]);
-+ /* dt->tm_mon is zero-based */
-+ dt->tm_mon = BCD_TO_BIN(buf[5]) - 1;
-+ /* year is 1900 + dt->tm_year */
-+ dt->tm_year = BCD_TO_BIN(buf[6]) + 100;
-+
-+ if (rtc_debug > 2) {
-+ printk("ds1337_get_datetime: year = %d\n", dt->tm_year);
-+ printk("ds1337_get_datetime: mon = %d\n", dt->tm_mon);
-+ printk("ds1337_get_datetime: mday = %d\n", dt->tm_mday);
-+ printk("ds1337_get_datetime: hour = %d\n", dt->tm_hour);
-+ printk("ds1337_get_datetime: min = %d\n", dt->tm_min);
-+ printk("ds1337_get_datetime: sec = %d\n", dt->tm_sec);
-+ }
-+}
-+
-+
-+static int ds1337_get_datetime(struct i2c_client *client,
-+ struct rtc_time *dt)
-+{
-+ unsigned char buf[7], addr[1] = { 0 };
-+ struct i2c_msg msgs[2] = {
-+ {client->addr, 0, 1, addr},
-+ {client->addr, I2C_M_RD, 7, buf}
-+ };
-+ int ret = -EIO;
-+
-+ if (rtc_debug)
-+ printk("%s()\n", __FUNCTION__);
-+
-+ memset(buf, 0, sizeof(buf));
-+
-+ ret = i2c_transfer(client->adapter, msgs, 2);
-+
-+ if (ret == 2) {
-+ ds1337_convert_to_time(dt, buf);
-+ ret = 0;
-+ } else
-+ printk("ds1337_get_datetime(), i2c_transfer() returned %d\n", ret);
-+
-+ return ret;
-+}
-+
-+
-+static int ds1337_set_datetime(struct i2c_client *client,
-+ struct rtc_time *dt, int datetoo)
-+{
-+ unsigned char buf[8];
-+ int ret, len = 4;
-+
-+ if (rtc_debug)
-+ printk("%s()\n", __FUNCTION__);
-+
-+ if (rtc_debug > 2) {
-+ printk("ds1337_set_datetime: tm_year = %d\n", dt->tm_year);
-+ printk("ds1337_set_datetime: tm_mon = %d\n", dt->tm_mon);
-+ printk("ds1337_set_datetime: tm_mday = %d\n", dt->tm_mday);
-+ printk("ds1337_set_datetime: tm_hour = %d\n", dt->tm_hour);
-+ printk("ds1337_set_datetime: tm_min = %d\n", dt->tm_min);
-+ printk("ds1337_set_datetime: tm_sec = %d\n", dt->tm_sec);
-+ }
-+
-+ buf[0] = 0; /* register address on DS1337 */
-+ buf[1] = (BIN_TO_BCD(dt->tm_sec));
-+ buf[2] = (BIN_TO_BCD(dt->tm_min));
-+ buf[3] = (BIN_TO_BCD(dt->tm_hour)) | DS1337_HOUR24;
-+
-+ if (datetoo) {
-+ len = 8;
-+ /* we skip buf[4] as we don't use day-of-week. */
-+ buf[5] = (BIN_TO_BCD(dt->tm_mday));
-+ buf[6] = (BIN_TO_BCD(dt->tm_mon + 1));
-+ /* The year only ranges from 0-99, we are being passed an offset from 1900,
-+ * and the chip calulates leap years based on 2000, thus we adjust by 100.
-+ */
-+ buf[7] = (BIN_TO_BCD(dt->tm_year - 100));
-+ }
-+ ret = i2c_master_send(client, (char *) buf, len);
-+ if (ret == len)
-+ ret = 0;
-+ else
-+ printk("ds1337_set_datetime(), i2c_master_send() returned %d\n",
-+ ret);
-+
-+
-+ return ret;
-+}
-+
-+
-+#if 0
-+static int ds1337_get_ctrl(struct i2c_client *client, unsigned char *ctrl)
-+{
-+ *ctrl = DAT(client);
-+
-+ if (rtc_debug)
-+ printk("%s():%d\n", __FUNCTION__, *ctrl);
-+
-+ return 0;
-+}
-+
-+
-+static int ds1337_set_ctrl(struct i2c_client *client, unsigned char *cinfo)
-+{
-+ unsigned char buf[2];
-+ int ret;
-+
-+ if (rtc_debug)
-+ printk("%s(%d)\n", __FUNCTION__, *cinfo);
-+
-+ buf[0] = 7; /* control register address on DS1337 */
-+ buf[1] = *cinfo;
-+ /* save the control reg info in the client data field so that get_ctrl
-+ * function doesn't have to do an I2C transfer to get it.
-+ */
-+ DAT(client) = buf[1];
-+
-+ ret = i2c_master_send(client, (char *) buf, 2);
-+
-+ return ret;
-+}
-+#endif
-+
-+
-+static int ds1337_command(struct i2c_client *client, unsigned int cmd,
-+ void *arg)
-+{
-+ if (rtc_debug)
-+ printk("%s(client,,%u,arg)\n", __FUNCTION__, cmd);
-+
-+ switch (cmd) {
-+ case DS1337_GETDATETIME:
-+ return ds1337_get_datetime(client, arg);
-+
-+ case DS1337_SETTIME:
-+ return ds1337_set_datetime(client, arg, 0);
-+
-+ case DS1337_SETDATETIME:
-+ return ds1337_set_datetime(client, arg, 1);
-+
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
-+
-+static int ds1337_rtc_noop(struct inode *inode, struct file *file)
-+{
-+ return 0;
-+}
-+
-+
-+static int ds1337_rtc_ioctl(struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ unsigned long flags;
-+ struct rtc_time wtime;
-+ int status = 0;
-+
-+ if (rtc_debug)
-+ printk("%s()\n", __FUNCTION__);
-+
-+ switch (cmd) {
-+ default:
-+ case RTC_UIE_ON: // mask ints from RTC updates
-+ case RTC_UIE_OFF:
-+ case RTC_PIE_ON: // allow periodic interrupts
-+ case RTC_PIE_OFF:
-+ case RTC_AIE_ON: // mask alarm int enable bit
-+ case RTC_AIE_OFF:
-+ case RTC_ALM_SET:
-+ /*
-+ * This expects a struct rtc_time. Writing 0xff means
-+ * "don't care" or "match all". Only the tm_hour,
-+ * tm_min and tm_sec are used.
-+ */
-+ case RTC_ALM_READ:
-+ // get_rtc_alm_time(&wtime);
-+ case RTC_IRQP_READ: // Read the periodic IRQ rate
-+ case RTC_IRQP_SET: // Set periodic IRQ rate
-+ case RTC_EPOCH_READ:
-+ // return put_user (epoch, (unsigned long *)arg);
-+ case RTC_EPOCH_SET:
-+ case RTC_WKALM_SET:
-+ case RTC_WKALM_RD:
-+ status = -EINVAL;
-+ break;
-+
-+ case RTC_RD_TIME:
-+ spin_lock_irqsave(&ds1337_rtc_lock, flags);
-+ ds1337_command(ds1337_i2c_client, DS1337_GETDATETIME, &wtime);
-+ spin_unlock_irqrestore(&ds1337_rtc_lock, flags);
-+
-+ if (copy_to_user((void *) arg, &wtime, sizeof(struct rtc_time)))
-+ status = -EFAULT;
-+ break;
-+
-+ case RTC_SET_TIME:
-+ if (!capable(CAP_SYS_TIME)) {
-+ status = -EACCES;
-+ break;
-+ }
-+
-+ if (copy_from_user
-+ (&wtime, (struct rtc_time *) arg, sizeof(struct rtc_time))) {
-+ status = -EFAULT;
-+ break;
-+ }
-+
-+ spin_lock_irqsave(&ds1337_rtc_lock, flags);
-+ ds1337_command(ds1337_i2c_client, DS1337_SETDATETIME, &wtime);
-+ spin_unlock_irqrestore(&ds1337_rtc_lock, flags);
-+ break;
-+ }
-+
-+ return status;
-+}
-+
-+
-+static char *ds1337_mon2str(unsigned int mon)
-+{
-+ char *mon2str[12] = {
-+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-+ };
-+ if (mon > 11)
-+ return "error";
-+ else
-+ return mon2str[mon];
-+}
-+
-+
-+static int ds1337_rtc_proc_output(char *buf)
-+{
-+#define CHECK(ctrl,bit) ((ctrl & bit) ? "yes" : "no")
-+
-+ unsigned char ram[DS1337_MEM_SIZE];
-+ int ret;
-+
-+ char *p = buf;
-+
-+ ret = ds1337_readram(ram, DS1337_MEM_SIZE);
-+ if (ret > 0) {
-+#ifdef DEBUG
-+ int i;
-+ char text[9];
-+#endif
-+ struct rtc_time dt;
-+
-+ p += sprintf(p, "DS1337 (i2c Serial Real Time Clock)\n");
-+
-+ ds1337_convert_to_time(&dt, ram);
-+ p += sprintf(p, "Date/Time: %02d-%s-%04d %02d:%02d:%02d\n",
-+ dt.tm_mday, ds1337_mon2str(dt.tm_mon),
-+ dt.tm_year + 1900, dt.tm_hour, dt.tm_min, dt.tm_sec);
-+
-+#ifdef DEBUG
-+ p += sprintf(p, "RAM dump:\n");
-+ text[8] = '\0';
-+ for (i = 0; i < DS1337_MEM_SIZE; i++) {
-+ if ((i % 8) == 0)
-+ p += sprintf(p, "%02X: ", i);
-+ p += sprintf(p, "%02X ", ram[i]);
-+
-+ if ((ram[i] < 32) || (ram[i] > 126))
-+ ram[i] = '.';
-+ text[i % 8] = ram[i];
-+ if ((i % 8) == 7)
-+ p += sprintf(p, "%s\n", text);
-+ }
-+ p += sprintf(p, "\n");
-+#endif
-+ } else {
-+ p += sprintf(p, "Failed to read RTC memory!\n");
-+ }
-+
-+ return p - buf;
-+}
-+
-+
-+static int ds1337_rtc_read_proc(char *page, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ int len = ds1337_rtc_proc_output(page);
-+
-+ if (len <= off + count)
-+ *eof = 1;
-+ *start = page + off;
-+ len -= off;
-+ if (len > count)
-+ len = count;
-+ if (len < 0)
-+ len = 0;
-+ return len;
-+}
-+
-+
-+static __init int ds1337_init(void)
-+{
-+ int retval = 0;
-+
-+ if (rtc_debug>1)
-+ printk("%s()\n", __FUNCTION__);
-+
-+ if (slave_address != 0xffff) {
-+ normal_addr[0] = slave_address;
-+ }
-+
-+ if (normal_addr[0] == 0xffff) {
-+ printk(KERN_ERR
-+ "I2C: Invalid slave address for DS1337 RTC (%#x)\n",
-+ normal_addr[0]);
-+ return -EINVAL;
-+ }
-+
-+ retval = i2c_add_driver(&ds1337_driver);
-+
-+ if (retval == 0) {
-+ misc_register(&ds1337_rtc_miscdev);
-+ create_proc_read_entry(DS1337_PROC_NAME, 0, 0,
-+ ds1337_rtc_read_proc, NULL);
-+ printk("I2C: DS1337 RTC driver loaded\n");
-+ }
-+ return retval;
-+}
-+
-+
-+static __exit void ds1337_exit(void)
-+{
-+ if (rtc_debug>1)
-+ printk("%s()\n", __FUNCTION__);
-+
-+ remove_proc_entry(DS1337_PROC_NAME, NULL);
-+ misc_deregister(&ds1337_rtc_miscdev);
-+ i2c_del_driver(&ds1337_driver);
-+}
-+
-+
-+module_init(ds1337_init);
-+module_exit(ds1337_exit);
-+
-+MODULE_PARM(slave_address, "i");
-+MODULE_PARM_DESC(slave_address, "I2C slave address for DS1337 RTC");
-+
-+MODULE_AUTHOR("M&N Logistik-Lösungen Online GmbH");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ linux-2.4.21/drivers/char/ds1337.h
-@@ -0,0 +1,43 @@
-+/*
-+ * ds1337.h
-+ *
-+ * Copyright (C) 2003 M&N Logistik-Lösungen Online GmbH
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ */
-+#ifndef DS1337_H
-+#define DS1337_H
-+
-+#define DS1337_I2C_SLAVE_ADDR 0x68
-+//#define DS1337_RAM_ADDR_START 0x10
-+//#define DS1337_RAM_ADDR_END 0x10
-+#define DS1337_MEM_SIZE 0x10
-+
-+#define DS1337_PROC_NAME "driver/ds1337"
-+
-+struct rtc_mem {
-+ unsigned int loc;
-+ unsigned int nr;
-+ unsigned char *data;
-+};
-+
-+#define DS1337_GETDATETIME 0
-+#define DS1337_SETTIME 1
-+#define DS1337_SETDATETIME 2
-+
-+#define DS1337_RATE_1HZ 0x00 /* Rate Select 1 Hz */
-+#define DS1337_RATE_4096HZ 0x01 /* Rate Select 4096 kHz */
-+#define DS1337_RATE_8192HZ 0x02 /* Rate Select 8192 kHz */
-+#define DS1337_RATE_32768HZ 0x03 /* Rate Select 32768 kHz */
-+
-+#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
-+#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
-+
-+#define DS1337_HOUR12 0x40
-+#define DS1337_HOUR24 0x00
-+#define DS1337_HOURS_24(val) BCD_TO_BIN((val & 0x3f))
-+
-+#endif
---- /dev/null
-+++ linux-2.4.21/drivers/char/german.map
-@@ -0,0 +1,528 @@
-+keymaps 0-2,4-6,8-10,12
-+keycode 1 = Escape Escape
-+ alt keycode 1 = Meta_Escape
-+ shift alt keycode 1 = Meta_Escape
-+keycode 2 = one exclam
-+ alt keycode 2 = Meta_one
-+ shift alt keycode 2 = Meta_exclam
-+keycode 3 = two quotedbl twosuperior nul
-+ alt keycode 3 = Meta_two
-+ shift alt keycode 3 = Meta_quotedbl
-+ control alt keycode 3 = Meta_nul
-+keycode 4 = three section threesuperior Escape
-+ alt keycode 4 = Meta_three
-+ control alt keycode 4 = Meta_Escape
-+keycode 5 = four dollar
-+ alt keycode 5 = Meta_four
-+ shift alt keycode 5 = Meta_dollar
-+keycode 6 = five percent
-+ alt keycode 6 = Meta_five
-+ shift alt keycode 6 = Meta_percent
-+keycode 7 = six ampersand
-+ control keycode 7 = Control_asciicircum
-+ alt keycode 7 = Meta_six
-+ shift alt keycode 7 = Meta_ampersand
-+keycode 8 = seven slash braceleft
-+ alt keycode 8 = Meta_seven
-+ shift alt keycode 8 = Meta_slash
-+ altgr alt keycode 8 = Meta_braceleft
-+keycode 9 = eight parenleft bracketleft
-+ alt keycode 9 = Meta_eight
-+ shift alt keycode 9 = Meta_parenleft
-+ altgr alt keycode 9 = Meta_bracketleft
-+keycode 10 = nine parenright bracketright
-+ altgr control keycode 10 = Control_bracketright
-+ alt keycode 10 = Meta_nine
-+ shift alt keycode 10 = Meta_parenright
-+ altgr alt keycode 10 = Meta_bracketright
-+keycode 11 = zero equal braceright
-+ alt keycode 11 = Meta_zero
-+ shift alt keycode 11 = Meta_equal
-+ altgr alt keycode 11 = Meta_braceright
-+keycode 12 = ssharp question backslash
-+ altgr control keycode 12 = Control_backslash
-+ shift alt keycode 12 = Meta_question
-+ altgr alt keycode 12 = Meta_backslash
-+keycode 13 = apostrophe grave
-+ alt keycode 13 = 0x08b4
-+ shift alt keycode 13 = Meta_grave
-+keycode 14 = BackSpace Delete
-+ alt keycode 14 = Meta_BackSpace
-+ shift alt keycode 14 = Meta_Delete
-+keycode 15 = Tab Tab
-+ alt keycode 15 = Meta_Tab
-+ shift alt keycode 15 = Meta_Tab
-+keycode 16 = +q +Q at Control_q Control_q Control_q Meta_q Meta_Q Meta_at Meta_Control_q
-+keycode 17 = w
-+keycode 18 = +e +E currency Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_Control_e
-+keycode 19 = r
-+keycode 20 = t
-+keycode 21 = z
-+keycode 22 = u
-+keycode 23 = i
-+keycode 24 = o
-+keycode 25 = p
-+keycode 26 = +udiaeresis +Udiaeresis
-+keycode 27 = plus asterisk asciitilde
-+ alt keycode 27 = Meta_plus
-+ shift alt keycode 27 = Meta_asterisk
-+keycode 28 = Return
-+ alt keycode 28 = Meta_Control_m
-+keycode 29 = Control
-+keycode 30 = a
-+keycode 31 = s
-+keycode 32 = d
-+keycode 33 = f
-+keycode 34 = g
-+keycode 35 = h
-+keycode 36 = j
-+keycode 37 = k
-+keycode 38 = l
-+keycode 39 = +odiaeresis +Odiaeresis
-+keycode 40 = +adiaeresis +Adiaeresis
-+keycode 41 = asciicircum degree Meta_asciicircum Control_asciicircum
-+ control alt keycode 41 = Meta_Control_asciicircum
-+keycode 42 = Shift
-+keycode 43 = numbersign apostrophe
-+ alt keycode 43 = Meta_numbersign
-+ shift alt keycode 43 = Meta_apostrophe
-+keycode 44 = y
-+keycode 45 = x
-+keycode 46 = c
-+keycode 47 = v
-+keycode 48 = b
-+keycode 49 = n
-+keycode 50 = +m +M mu Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_Control_m
-+keycode 51 = comma semicolon
-+ alt keycode 51 = Meta_comma
-+ shift alt keycode 51 = Meta_semicolon
-+keycode 52 = period colon
-+ alt keycode 52 = Meta_period
-+ shift alt keycode 52 = Meta_colon
-+keycode 53 = minus underscore Meta_minus
-+ shift control keycode 53 = Control_underscore
-+ alt keycode 53 = Meta_minus
-+ shift alt keycode 53 = Meta_underscore
-+keycode 54 = Shift
-+keycode 55 = KP_Multiply
-+ altgr keycode 55 = Hex_C
-+keycode 56 = Alt
-+keycode 57 = space space Meta_space nul
-+ alt keycode 57 = Meta_space
-+ shift alt keycode 57 = Meta_space
-+ control alt keycode 57 = Meta_nul
-+keycode 58 = Caps_Lock
-+keycode 59 = F1 F13 Console_13 F25
-+ altgr control keycode 59 = F1
-+ alt keycode 59 = Console_1
-+ control alt keycode 59 = Console_1
-+keycode 60 = F2 F14 Console_14 F26
-+ altgr control keycode 60 = F2
-+ alt keycode 60 = Console_2
-+ control alt keycode 60 = Console_2
-+keycode 61 = F3 F15 Console_15 F27
-+ altgr control keycode 61 = F3
-+ alt keycode 61 = Console_3
-+ control alt keycode 61 = Console_3
-+keycode 62 = F4 F16 Console_16 F28
-+ altgr control keycode 62 = F4
-+ alt keycode 62 = Console_4
-+ control alt keycode 62 = Console_4
-+keycode 63 = F5 F17 Console_17 F29
-+ altgr control keycode 63 = F5
-+ alt keycode 63 = Console_5
-+ control alt keycode 63 = Console_5
-+keycode 64 = F6 F18 Console_18 F30
-+ altgr control keycode 64 = F6
-+ alt keycode 64 = Console_6
-+ control alt keycode 64 = Console_6
-+keycode 65 = F7 F19 Console_19 F31
-+ altgr control keycode 65 = F7
-+ alt keycode 65 = Console_7
-+ control alt keycode 65 = Console_7
-+keycode 66 = F8 F20 Console_20 F32
-+ altgr control keycode 66 = F8
-+ alt keycode 66 = Console_8
-+ control alt keycode 66 = Console_8
-+keycode 67 = F9 F21 Console_21 F33
-+ altgr control keycode 67 = F9
-+ alt keycode 67 = Console_9
-+ control alt keycode 67 = Console_9
-+keycode 68 = F10 F22 Console_22 F34
-+ altgr control keycode 68 = F10
-+ alt keycode 68 = Console_10
-+ control alt keycode 68 = Console_10
-+keycode 69 = Num_Lock
-+ altgr keycode 69 = Hex_A
-+keycode 70 = Scroll_Lock Show_Memory Show_Registers Show_State
-+ alt keycode 70 = Scroll_Lock
-+keycode 71 = KP_7
-+ altgr keycode 71 = Hex_7
-+ alt keycode 71 = Ascii_7
-+keycode 72 = KP_8
-+ altgr keycode 72 = Hex_8
-+ alt keycode 72 = Ascii_8
-+keycode 73 = KP_9
-+ altgr keycode 73 = Hex_9
-+ alt keycode 73 = Ascii_9
-+keycode 74 = KP_Subtract
-+ altgr keycode 74 = Hex_D
-+keycode 75 = KP_4
-+ altgr keycode 75 = Hex_4
-+ alt keycode 75 = Ascii_4
-+keycode 76 = KP_5
-+ altgr keycode 76 = Hex_5
-+ alt keycode 76 = Ascii_5
-+keycode 77 = KP_6
-+ altgr keycode 77 = Hex_6
-+ alt keycode 77 = Ascii_6
-+keycode 78 = KP_Add
-+ altgr keycode 78 = Hex_E
-+keycode 79 = KP_1
-+ altgr keycode 79 = Hex_1
-+ alt keycode 79 = Ascii_1
-+keycode 80 = KP_2
-+ altgr keycode 80 = Hex_2
-+ alt keycode 80 = Ascii_2
-+keycode 81 = KP_3
-+ altgr keycode 81 = Hex_3
-+ alt keycode 81 = Ascii_3
-+keycode 82 = KP_0
-+ altgr keycode 82 = Hex_0
-+ alt keycode 82 = Ascii_0
-+keycode 83 = KP_Comma
-+ altgr control keycode 83 = Boot
-+ control alt keycode 83 = Boot
-+#keycode 84 = Last_Console
-+keycode 85 =
-+keycode 86 = less greater bar
-+ alt keycode 86 = Meta_less
-+ shift alt keycode 86 = Meta_greater
-+ altgr alt keycode 86 = Meta_bar
-+keycode 87 = F11 F23 Console_23 F35
-+ altgr control keycode 87 = F11
-+ alt keycode 87 = Console_11
-+ control alt keycode 87 = Console_11
-+keycode 88 = F12 F24 Console_24 F36
-+ altgr control keycode 88 = F12
-+ alt keycode 88 = Console_12
-+ control alt keycode 88 = Console_12
-+keycode 89 = slash question degree
-+ alt keycode 89 = Meta_slash
-+ shift alt keycode 89 = Meta_question
-+keycode 90 =
-+keycode 91 =
-+keycode 92 =
-+keycode 93 =
-+keycode 94 =
-+keycode 95 =
-+keycode 96 = KP_Enter
-+ altgr keycode 96 = Hex_F
-+keycode 97 = Control
-+keycode 98 = KP_Divide
-+ altgr keycode 98 = Hex_B
-+keycode 99 = Compose
-+keycode 100 = AltGr
-+ alt keycode 100 = Compose
-+keycode 101 = Break
-+keycode 102 = Find
-+keycode 103 = Up
-+ alt keycode 103 = KeyboardSignal
-+keycode 104 = Prior
-+ shift keycode 104 = Scroll_Backward
-+keycode 105 = Left
-+# alt keycode 105 = Decr_Console
-+keycode 106 = Right
-+# alt keycode 106 = Incr_Console
-+keycode 107 = Select
-+keycode 108 = Down
-+keycode 109 = Next
-+ shift keycode 109 = Scroll_Forward
-+keycode 110 = Insert
-+keycode 111 = Remove
-+ altgr control keycode 111 = Boot
-+ control alt keycode 111 = Boot
-+keycode 112 = Macro
-+ shift alt keycode 112 = VoidSymbol
-+ altgr alt keycode 112 = VoidSymbol
-+keycode 113 = F13
-+ shift alt keycode 113 = VoidSymbol
-+ altgr alt keycode 113 = VoidSymbol
-+keycode 114 = F14
-+ shift alt keycode 114 = VoidSymbol
-+ altgr alt keycode 114 = VoidSymbol
-+keycode 115 = Help
-+ shift alt keycode 115 = VoidSymbol
-+ altgr alt keycode 115 = VoidSymbol
-+keycode 116 = Do
-+ shift alt keycode 116 = VoidSymbol
-+ altgr alt keycode 116 = VoidSymbol
-+keycode 117 = F17
-+ shift alt keycode 117 = VoidSymbol
-+ altgr alt keycode 117 = VoidSymbol
-+keycode 118 = KP_MinPlus
-+ shift alt keycode 118 = VoidSymbol
-+ altgr alt keycode 118 = VoidSymbol
-+keycode 119 = Pause
-+keycode 120 =
-+keycode 121 =
-+keycode 122 =
-+keycode 123 =
-+keycode 124 =
-+#keycode 125 = Decr_Console
-+#keycode 126 = Incr_Console
-+keycode 127 = Compose
-+string F1 = "\033[[A"
-+string F2 = "\033[[B"
-+string F3 = "\033[[C"
-+string F4 = "\033[[D"
-+string F5 = "\033[[E"
-+string F6 = "\033[17~"
-+string F7 = "\033[18~"
-+string F8 = "\033[19~"
-+string F9 = "\033[20~"
-+string F10 = "\033[21~"
-+string F11 = "\033[23~"
-+string F12 = "\033[24~"
-+string F13 = "\033[25~"
-+string F14 = "\033[26~"
-+string F15 = "\033[28~"
-+string F16 = "\033[29~"
-+string F17 = "\033[31~"
-+string F18 = "\033[32~"
-+string F19 = "\033[33~"
-+string F20 = "\033[34~"
-+string Find = "\033[1~"
-+string Insert = "\033[2~"
-+string Remove = "\033[3~"
-+string Select = "\033[4~"
-+string Prior = "\033[5~"
-+string Next = "\033[6~"
-+string Macro = "\033[M"
-+string Pause = "\033[P"
-+compose '!' '!' to '¡'
-+compose '"' 'A' to 'Ä'
-+compose '"' 'E' to 'Ë'
-+compose '"' 'I' to 'Ï'
-+compose '"' 'O' to 'Ö'
-+compose '"' 'U' to 'Ü'
-+compose '"' 'Y' to '¾'
-+compose '"' 'a' to 'ä'
-+compose '"' 'c' to '©'
-+compose '"' 'e' to 'ë'
-+compose '"' 'i' to 'ï'
-+compose '"' 'o' to 'ö'
-+compose '"' 'r' to '®'
-+compose '"' 'u' to 'ü'
-+compose '"' 'y' to 'ÿ'
-+compose '(' 'c' to '©'
-+compose '(' 'r' to '®'
-+compose '+' '-' to '±'
-+compose ',' 'A' to '¡'
-+compose ',' 'C' to 'Ç'
-+compose ',' 'E' to 'Ê'
-+compose ',' 'G' to '«'
-+compose ',' 'I' to 'Ç'
-+compose ',' 'K' to 'Ó'
-+compose ',' 'L' to '¦'
-+compose ',' 'N' to 'Ñ'
-+compose ',' 'R' to '£'
-+compose ',' 'S' to 'ª'
-+compose ',' 'T' to 'Þ'
-+compose ',' 'U' to 'Ù'
-+compose ',' 'a' to '±'
-+compose ',' 'c' to 'ç'
-+compose ',' 'e' to 'ê'
-+compose ',' 'g' to '»'
-+compose ',' 'i' to 'ç'
-+compose ',' 'k' to 'ó'
-+compose ',' 'l' to '¶'
-+compose ',' 'n' to 'ñ'
-+compose ',' 'r' to '³'
-+compose ',' 's' to 'º'
-+compose ',' 't' to 'þ'
-+compose ',' 'u' to 'ù'
-+compose '-' ':' to '÷'
-+compose '-' 'A' to 'ª'
-+compose '-' 'C' to '¢'
-+compose '-' 'D' to 'Ð'
-+compose '-' 'E' to '¤'
-+compose '-' 'H' to '¡'
-+compose '-' 'L' to '£'
-+compose '-' 'O' to 'º'
-+compose '-' 'T' to '¬'
-+compose '-' 'Y' to '¥'
-+compose '-' 'a' to 'ª'
-+compose '-' 'c' to '¢'
-+compose '-' 'd' to 'ð'
-+compose '-' 'e' to '¤'
-+compose '-' 'h' to '±'
-+compose '-' 'l' to '£'
-+compose '-' 'l' to '¥'
-+compose '-' 'l' to '³'
-+compose '-' 'o' to 'º'
-+compose '-' 't' to '¼'
-+compose '.' '.' to '·'
-+compose '.' 'C' to 'Å'
-+compose '.' 'C' to 'Õ'
-+compose '.' 'E' to 'Ì'
-+compose '.' 'I' to '©'
-+compose '.' 'Z' to '¯'
-+compose '.' 'c' to 'å'
-+compose '.' 'c' to 'õ'
-+compose '.' 'e' to 'ì'
-+compose '.' 'i' to '¹'
-+compose '.' 'z' to '¿'
-+compose '/' 'D' to 'Ð'
-+compose '/' 'L' to '£'
-+compose '/' 'O' to 'Ø'
-+compose '/' 'T' to '¬'
-+compose '/' 'c' to '¢'
-+compose '/' 'd' to 'ð'
-+compose '/' 'l' to '³'
-+compose '/' 'o' to 'ø'
-+compose '/' 't' to '¼'
-+compose '0' 'A' to 'Å'
-+compose '0' 'U' to 'Ù'
-+compose '0' 'a' to 'å'
-+compose '0' 'u' to 'ù'
-+compose '1' '2' to '½'
-+compose '1' '4' to '¼'
-+compose '3' '4' to '¾'
-+compose ':' '-' to '÷'
-+compose ':' 'A' to 'Ä'
-+compose ':' 'E' to 'Ë'
-+compose ':' 'O' to 'Ö'
-+compose ':' 'U' to 'Ü'
-+compose ':' 'a' to 'ä'
-+compose ':' 'e' to 'ë'
-+compose ':' 'o' to 'ö'
-+compose ':' 'u' to 'ü'
-+compose '<' '<' to '«'
-+compose '>' '>' to '»'
-+compose '?' '?' to '¿'
-+compose 'A' 'A' to 'Å'
-+compose 'A' 'E' to 'Æ'
-+compose 'I' 'J' to '¾'
-+compose 'L' '=' to '£'
-+compose 'N' 'G' to '½'
-+compose 'N' 'H' to 'Ñ'
-+compose 'N' 'N' to 'Ñ'
-+compose 'N' 'Y' to 'Ñ'
-+compose 'N' 'h' to 'Ñ'
-+compose 'N' 'n' to 'Ñ'
-+compose 'N' 'y' to 'Ñ'
-+compose 'O' 'A' to 'Å'
-+compose 'O' 'E' to '¼'
-+compose 'O' 'e' to '¼'
-+compose 'T' 'H' to 'Þ'
-+compose 'U' 'U' to 'Ù'
-+compose 'Y' '=' to '¥'
-+compose '\'' 'A' to 'Á'
-+compose '\'' 'C' to 'Æ'
-+compose '\'' 'E' to 'É'
-+compose '\'' 'I' to 'Í'
-+compose '\'' 'L' to 'Å'
-+compose '\'' 'N' to 'Ñ'
-+compose '\'' 'O' to 'Ó'
-+compose '\'' 'R' to 'À'
-+compose '\'' 'S' to '¦'
-+compose '\'' 'U' to 'Ú'
-+compose '\'' 'Y' to 'Ý'
-+compose '\'' 'Z' to '¬'
-+compose '\'' 'a' to 'á'
-+compose '\'' 'c' to 'æ'
-+compose '\'' 'e' to 'é'
-+compose '\'' 'i' to 'í'
-+compose '\'' 'l' to 'å'
-+compose '\'' 'n' to 'ñ'
-+compose '\'' 'o' to 'ó'
-+compose '\'' 'r' to 'à'
-+compose '\'' 's' to '¶'
-+compose '\'' 'u' to 'ú'
-+compose '\'' 'y' to 'ý'
-+compose '\'' 'z' to '¼'
-+compose '^' '!' to '¡'
-+compose '^' '*' to '×'
-+compose '^' '.' to '·'
-+compose '^' '/' to '÷'
-+compose '^' '1' to '¹'
-+compose '^' '2' to '²'
-+compose '^' '3' to '³'
-+compose '^' ':' to '÷'
-+compose '^' '?' to '¿'
-+compose '^' 'A' to 'Â'
-+compose '^' 'C' to 'Ç'
-+compose '^' 'D' to 'Ð'
-+compose '^' 'E' to 'Ê'
-+compose '^' 'G' to 'Ô'
-+compose '^' 'H' to '¦'
-+compose '^' 'I' to 'Î'
-+compose '^' 'J' to '¬'
-+compose '^' 'L' to '¥'
-+compose '^' 'N' to 'Ñ'
-+compose '^' 'R' to 'Ø'
-+compose '^' 'S' to '¦'
-+compose '^' 'T' to '«'
-+compose '^' 'U' to 'Û'
-+compose '^' 'Z' to '´'
-+compose '^' 'a' to 'â'
-+compose '^' 'c' to 'ç'
-+compose '^' 'd' to 'ð'
-+compose '^' 'e' to 'ê'
-+compose '^' 'g' to 'ø'
-+compose '^' 'h' to '¶'
-+compose '^' 'i' to 'î'
-+compose '^' 'j' to '¼'
-+compose '^' 'l' to 'µ'
-+compose '^' 'n' to 'ñ'
-+compose '^' 'o' to 'ô'
-+compose '^' 'r' to 'ø'
-+compose '^' 's' to '¨'
-+compose '^' 't' to '»'
-+compose '^' 'u' to 'û'
-+compose '^' 'x' to '×'
-+compose '^' 'z' to '¸'
-+compose '`' 'A' to 'À'
-+compose '`' 'E' to 'È'
-+compose '`' 'I' to 'Ì'
-+compose '`' 'O' to 'Ò'
-+compose '`' 'U' to 'Ù'
-+compose '`' 'a' to 'à'
-+compose '`' 'e' to 'è'
-+compose '`' 'i' to 'ì'
-+compose '`' 'o' to 'ò'
-+compose '`' 'u' to 'ù'
-+compose 'a' 'a' to 'å'
-+compose 'a' 'e' to 'æ'
-+compose 'c' '/' to '¢'
-+compose 'c' '=' to '¢'
-+compose 'e' '=' to '¤'
-+compose 'i' 'j' to 'ÿ'
-+compose 'm' 'u' to 'µ'
-+compose 'n' 'g' to '¿'
-+compose 'n' 'h' to 'ñ'
-+compose 'n' 'n' to 'ñ'
-+compose 'o' 'a' to 'å'
-+compose 'o' 'e' to '½'
-+compose 's' 's' to 'ß'
-+compose 's' 'z' to 'ß'
-+compose 't' 'h' to 'þ'
-+compose 'u' 'u' to 'ù'
-+compose 'v' 'S' to '¦'
-+compose 'v' 'Z' to '´'
-+compose 'v' 's' to '¨'
-+compose 'v' 'z' to '¸'
-+compose 'x' 'x' to '×'
-+compose '~' 'A' to 'Ã'
-+compose '~' 'G' to '«'
-+compose '~' 'I' to '¥'
-+compose '~' 'N' to 'Ñ'
-+compose '~' 'O' to 'Õ'
-+compose '~' 'U' to 'Ý'
-+compose '~' 'a' to 'ã'
-+compose '~' 'g' to '»'
-+compose '~' 'i' to 'µ'
-+compose '~' 'n' to 'ñ'
-+compose '~' 'o' to 'õ'
-+compose '~' 'u' to 'ý'
---- /dev/null
-+++ linux-2.4.21/drivers/char/input_keyb.c
-@@ -0,0 +1,167 @@
-+/*
-+ * linux/drivers/char/input_keyb.c by Russ Dill <Russ.Dill@asu.edu>
-+ * taken from pc_keyb.c
-+ *
-+ * This code grabs keypresses from the input layer and makes them
-+ * available to the console.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <asm/uaccess.h>
-+#include <asm/keyboard.h>
-+
-+/* Simple translation table for the SysRq keys */
-+
-+unsigned char input_sysrq_xlate[128] =
-+ "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
-+ "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
-+ "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
-+ "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
-+ "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
-+ "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
-+ "\r\000/"; /* 0x60 - 0x6f */
-+
-+/*
-+ * Translation of escaped scancodes to keycodes.
-+ * This is now user-settable.
-+ * The keycodes 1-88,96-111,119 are fairly standard, and
-+ * should probably not be changed - changing might confuse X.
-+ * X also interprets scancode 0x5d (KEY_Begin).
-+ *
-+ * For 1-88 keycode equals scancode.
-+ */
-+
-+#define E0_KPENTER 96
-+#define E0_RCTRL 97
-+#define E0_KPSLASH 98
-+#define E0_PRSCR 99
-+#define E0_RALT 100
-+#define E0_BREAK 101 /* (control-pause) */
-+#define E0_HOME 102
-+#define E0_UP 103
-+#define E0_PGUP 104
-+#define E0_LEFT 105
-+#define E0_RIGHT 106
-+#define E0_END 107
-+#define E0_DOWN 108
-+#define E0_PGDN 109
-+#define E0_INS 110
-+#define E0_DEL 111
-+
-+#define E1_PAUSE 119
-+
-+/*
-+ * New microsoft keyboard is rumoured to have
-+ * e0 5b (left window button), e0 5c (right window button),
-+ * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
-+ * [or: Windows_L, Windows_R, TaskMan]
-+ */
-+#define E0_MSLW 125
-+
-+static unsigned char e0_keys[128] = {
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */
-+ 0, 0, 0, 0, 0, E0_RCTRL, 0, 0, /* 0x18-0x1f */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */
-+ 0, 0, 0, 0, 0, 0, 0, E0_PRSCR, /* 0x30-0x37 */
-+ E0_RALT, 0, 0, 0, 0, 0, 0, 0, /* 0x38-0x3f */
-+ 0, 0, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */
-+ E0_UP, E0_PGUP, 0, E0_LEFT, 0, E0_RIGHT, 0, E0_END, /* 0x48-0x4f */
-+ E0_DOWN, E0_PGDN, 0, 0, 0, 0, 0, 0, /* 0x50-0x57 */
-+ 0, 0, 0, E0_MSLW, 0, 0, 0, 0, /* 0x58-0x5f */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x68-0x6f */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */
-+ 0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */
-+};
-+
-+int input_setkeycode(unsigned int scancode, unsigned int keycode)
-+{
-+ if (scancode > 255 || keycode > 127) return -EINVAL;
-+ e0_keys[scancode - 128] = keycode;
-+ return 0;
-+}
-+
-+int input_getkeycode(unsigned int scancode)
-+{
-+ return scancode > 255 ? -EINVAL : e0_keys[scancode - 128];
-+}
-+
-+#define KBD_REPORT_UNKN
-+int input_translate(unsigned char scancode, unsigned char *keycode,
-+ char raw_mode)
-+{
-+ static int prev_scancode;
-+
-+ /* special prefix scancodes.. */
-+ if (scancode == 0xe0 || scancode == 0xe1) {
-+ prev_scancode = scancode;
-+ return 0;
-+ }
-+ if (prev_scancode) {
-+ /*
-+ * usually it will be 0xe0, but a Pause key generates
-+ * e1 1d 45 e1 9d c5 when pressed, and nothing when released
-+ */
-+ if (prev_scancode != 0xe0) {
-+ if (prev_scancode == 0xe1 && scancode == 0x1d) {
-+ prev_scancode = 0x100;
-+ return 0;
-+ } else if (prev_scancode == 0x100 && scancode == 0x45) {
-+ *keycode = E1_PAUSE;
-+ prev_scancode = 0;
-+ } else {
-+#ifdef KBD_REPORT_UNKN
-+ if (!raw_mode)
-+ printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
-+#endif
-+ prev_scancode = 0;
-+ return 0;
-+ }
-+ } else {
-+ prev_scancode = 0;
-+
-+ if (e0_keys[scancode])
-+ *keycode = e0_keys[scancode];
-+ else {
-+#ifdef KBD_REPORT_UNKN
-+ if (!raw_mode)
-+ printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
-+ scancode);
-+#endif
-+ return 0;
-+ }
-+ }
-+ } else
-+ *keycode = scancode;
-+ return 1;
-+}
-+
-+char input_unexpected_up(unsigned char keycode)
-+{
-+ return 0200;
-+}
-+
-+/* Allow for loadable keyboard drivers */
-+EXPORT_SYMBOL(input_setkeycode);
-+EXPORT_SYMBOL(input_unexpected_up);
-+EXPORT_SYMBOL(input_translate);
-+EXPORT_SYMBOL(input_sysrq_xlate);
-+EXPORT_SYMBOL(input_getkeycode);
-+EXPORT_SYMBOL(k_setkeycode);
-+EXPORT_SYMBOL(k_unexpected_up);
-+EXPORT_SYMBOL(k_translate);
-+EXPORT_SYMBOL(k_getkeycode);
-+#ifdef CONFIG_MAGIC_SYSRQ
-+EXPORT_SYMBOL(k_sysrq_key);
-+EXPORT_SYMBOL(k_sysrq_xlate);
-+#endif
---- linux-2.4.21/drivers/char/keyboard.c~wedge
-+++ linux-2.4.21/drivers/char/keyboard.c
-@@ -77,6 +77,7 @@
- void (*kbd_ledfunc)(unsigned int led);
- EXPORT_SYMBOL(handle_scancode);
- EXPORT_SYMBOL(kbd_ledfunc);
-+EXPORT_SYMBOL(key_maps);
- EXPORT_SYMBOL(kbd_refresh_leds);
-
- extern void ctrl_alt_del(void);
---- linux-2.4.21/drivers/char/serial.c~ramses-serial
-+++ linux-2.4.21/drivers/char/serial.c
-@@ -1,138 +1,8 @@
--/*
-- * linux/drivers/char/serial.c
-- *
-- * Copyright (C) 1991, 1992 Linus Torvalds
-- * Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997,
-- * 1998, 1999 Theodore Ts'o
-- *
-- * Extensively rewritten by Theodore Ts'o, 8/16/92 -- 9/14/92. Now
-- * much more extensible to support other serial cards based on the
-- * 16450/16550A UART's. Added support for the AST FourPort and the
-- * Accent Async board.
-- *
-- * set_serial_info fixed to set the flags, custom divisor, and uart
-- * type fields. Fix suggested by Michael K. Johnson 12/12/92.
-- *
-- * 11/95: TIOCMIWAIT, TIOCGICOUNT by Angelo Haritsis <ah@doc.ic.ac.uk>
-- *
-- * 03/96: Modularised by Angelo Haritsis <ah@doc.ic.ac.uk>
-- *
-- * rs_set_termios fixed to look also for changes of the input
-- * flags INPCK, BRKINT, PARMRK, IGNPAR and IGNBRK.
-- * Bernd Anhäupl 05/17/96.
-- *
-- * 1/97: Extended dumb serial ports are a config option now.
-- * Saves 4k. Michael A. Griffith <grif@acm.org>
-- *
-- * 8/97: Fix bug in rs_set_termios with RTS
-- * Stanislav V. Voronyi <stas@uanet.kharkov.ua>
-- *
-- * 3/98: Change the IRQ detection, use of probe_irq_o*(),
-- * suppress TIOCSERGWILD and TIOCSERSWILD
-- * Etienne Lorrain <etienne.lorrain@ibm.net>
-- *
-- * 4/98: Added changes to support the ARM architecture proposed by
-- * Russell King
-- *
-- * 5/99: Updated to include support for the XR16C850 and ST16C654
-- * uarts. Stuart MacDonald <stuartm@connecttech.com>
-- *
-- * 8/99: Generalized PCI support added. Theodore Ts'o
-- *
-- * 3/00: Rid circular buffer of redundant xmit_cnt. Fix a
-- * few races on freeing buffers too.
-- * Alan Modra <alan@linuxcare.com>
-- *
-- * 5/00: Support for the RSA-DV II/S card added.
-- * Kiyokazu SUTO <suto@ks-and-ks.ne.jp>
-- *
-- * 6/00: Remove old-style timer, use timer_list
-- * Andrew Morton <andrewm@uow.edu.au>
-- *
-- * 7/00: Support Timedia/Sunix/Exsys PCI cards
-- *
-- * 7/00: fix some returns on failure not using MOD_DEC_USE_COUNT.
-- * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
-- *
-- * 10/00: add in optional software flow control for serial console.
-- * Kanoj Sarcar <kanoj@sgi.com> (Modified by Theodore Ts'o)
-- *
-- * 02/02: Fix for AMD Elan bug in transmit irq routine, by
-- * Christer Weinigel <wingel@hog.ctrl-c.liu.se>,
-- * Robert Schwebel <robert@schwebel.de>,
-- * Juergen Beisert <jbeisert@eurodsn.de>,
-- * Theodore Ts'o <tytso@mit.edu>
-- */
--
--static char *serial_version = "5.05c";
--static char *serial_revdate = "2001-07-08";
--
--/*
-- * Serial driver configuration section. Here are the various options:
-- *
-- * CONFIG_HUB6
-- * Enables support for the venerable Bell Technologies
-- * HUB6 card.
-- *
-- * CONFIG_SERIAL_MANY_PORTS
-- * Enables support for ports beyond the standard, stupid
-- * COM 1/2/3/4.
-- *
-- * CONFIG_SERIAL_MULTIPORT
-- * Enables support for special multiport board support.
-- *
-- * CONFIG_SERIAL_SHARE_IRQ
-- * Enables support for multiple serial ports on one IRQ
-- *
-- * CONFIG_SERIAL_DETECT_IRQ
-- * Enable the autodetection of IRQ on standart ports
-- *
-- * SERIAL_PARANOIA_CHECK
-- * Check the magic number for the async_structure where
-- * ever possible.
-- *
-- * CONFIG_SERIAL_ACPI
-- * Enable support for serial console port and serial
-- * debug port as defined by the SPCR and DBGP tables in
-- * ACPI 2.0.
-- */
-+#undef DEBUG
-
- #include <linux/config.h>
- #include <linux/version.h>
-
--#undef SERIAL_PARANOIA_CHECK
--#define CONFIG_SERIAL_NOPAUSE_IO
--#define SERIAL_DO_RESTART
--
--#if 0
--/* These defines are normally controlled by the autoconf.h */
--#define CONFIG_SERIAL_MANY_PORTS
--#define CONFIG_SERIAL_SHARE_IRQ
--#define CONFIG_SERIAL_DETECT_IRQ
--#define CONFIG_SERIAL_MULTIPORT
--#define CONFIG_HUB6
--#endif
--
--#ifdef CONFIG_PCI
--#define ENABLE_SERIAL_PCI
--#ifndef CONFIG_SERIAL_SHARE_IRQ
--#define CONFIG_SERIAL_SHARE_IRQ
--#endif
--#ifndef CONFIG_SERIAL_MANY_PORTS
--#define CONFIG_SERIAL_MANY_PORTS
--#endif
--#endif
--
--#ifdef CONFIG_SERIAL_ACPI
--#define ENABLE_SERIAL_ACPI
--#endif
--
--#if defined(CONFIG_ISAPNP)|| (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE))
--#ifndef ENABLE_SERIAL_PNP
--#define ENABLE_SERIAL_PNP
--#endif
--#endif
--
- #ifdef CONFIG_ARCH_PXA
- #define pxa_port(x) ((x) == PORT_PXA)
- #define pxa_buggy_port(x) ({ \
-@@ -149,39 +19,16 @@
- #undef SERIAL_DEBUG_OPEN
- #undef SERIAL_DEBUG_FLOW
- #undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
--#undef SERIAL_DEBUG_PCI
--#undef SERIAL_DEBUG_AUTOCONF
-
- /* Sanity checks */
-
--#ifdef CONFIG_SERIAL_MULTIPORT
--#ifndef CONFIG_SERIAL_SHARE_IRQ
--#define CONFIG_SERIAL_SHARE_IRQ
--#endif
--#endif
--
--#ifdef CONFIG_HUB6
--#ifndef CONFIG_SERIAL_MANY_PORTS
--#define CONFIG_SERIAL_MANY_PORTS
--#endif
--#ifndef CONFIG_SERIAL_SHARE_IRQ
--#define CONFIG_SERIAL_SHARE_IRQ
--#endif
--#endif
--
- #ifdef MODULE
- #undef CONFIG_SERIAL_CONSOLE
- #endif
-
--#define CONFIG_SERIAL_RSA
--
- #define RS_STROBE_TIME (10*HZ)
- #define RS_ISR_PASS_LIMIT 256
-
--#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
--#define SERIAL_INLINE
--#endif
--
- /*
- * End of serial driver configuration section.
- */
-@@ -213,53 +60,51 @@
- #include <linux/ioport.h>
- #include <linux/mm.h>
- #include <linux/slab.h>
--#if (LINUX_VERSION_CODE >= 131343)
- #include <linux/init.h>
--#endif
--#if (LINUX_VERSION_CODE >= 131336)
- #include <asm/uaccess.h>
--#endif
- #include <linux/delay.h>
- #ifdef CONFIG_SERIAL_CONSOLE
- #include <linux/console.h>
- #endif
--#ifdef ENABLE_SERIAL_PCI
--#include <linux/pci.h>
--#endif
--#ifdef ENABLE_SERIAL_PNP
--#include <linux/isapnp.h>
--#endif
- #ifdef CONFIG_MAGIC_SYSRQ
- #include <linux/sysrq.h>
- #endif
-
--/*
-- * All of the compatibilty code so we can compile serial.c against
-- * older kernels is hidden in serial_compat.h
-- */
--#if defined(LOCAL_HEADERS) || (LINUX_VERSION_CODE < 0x020317) /* 2.3.23 */
--#include "serial_compat.h"
--#endif
--
- #include <asm/system.h>
- #include <asm/io.h>
- #include <asm/irq.h>
- #include <asm/bitops.h>
-
--#if defined(CONFIG_MAC_SERIAL)
--#define SERIAL_DEV_OFFSET ((_machine == _MACH_prep || _machine == _MACH_chrp) ? 0 : 2)
--#else
--#define SERIAL_DEV_OFFSET 0
--#endif
-+#define _INLINE_
-
--#ifdef SERIAL_INLINE
--#define _INLINE_ inline
-+/*
-+ * The TI16754 has 4 UARTS. They are selected with nCS3 and some
-+ * address bits:
-+ *
-+ * 12 8 4
-+ * nA8, nCS[3] for MN_UART_1, address mask 1110 1110 0000 0000 = 0xEE00
-+ * nA9, nCS[3] for MN_UART_1, address mask 1110 1101 0000 0000 = 0xED00
-+ * nA10, nCS[3] for MN_UART_1, address mask 1110 1011 0000 0000 = 0xEB00
-+ * nA11, nCS[3] for MN_UART_1, address mask 1110 0111 0000 0000 = 0xE700
-+ */
-+#define RAMSES_UARTA_PHYS (PXA_CS3_PHYS+0xEE00)
-+#define RAMSES_UARTB_PHYS (PXA_CS3_PHYS+0xED00)
-+#define RAMSES_UARTC_PHYS (PXA_CS3_PHYS+0xEB00)
-+#define RAMSES_UARTD_PHYS (PXA_CS3_PHYS+0xE700)
-+static void *ramses_uarta; // address cookie for UART A
-+static void *ramses_uartb; // address cookie for UART B
-+static void *ramses_uartc; // address cookie for UART C/Scanner
-+static void *ramses_uartd; // address cookie for UART D
-+static int ramses_stay_on = 0;
-+
-+#ifdef DEBUG
-+#define DPRINTK(fmt,args...) printk("//HS " fmt, ## args)
-+static int show_io = 1;
- #else
--#define _INLINE_
-+#define DPRINTK(fmt,args...)
-+static int show_io = 0;
- #endif
-
--static char *serial_name = "Serial driver";
--
- static DECLARE_TASK_QUEUE(tq_serial);
-
- static struct tty_driver serial_driver, callout_driver;
-@@ -282,9 +127,6 @@
- */
-
- static struct async_struct *IRQ_ports[NR_IRQS];
--#ifdef CONFIG_SERIAL_MULTIPORT
--static struct rs_multiport_struct rs_multiport[NR_IRQS];
--#endif
- static int IRQ_timeout[NR_IRQS];
- #ifdef CONFIG_SERIAL_CONSOLE
- static struct console sercons;
-@@ -294,8 +136,6 @@
- static unsigned long break_pressed; /* break, really ... */
- #endif
-
--static unsigned detect_uart_irq (struct serial_state * state);
--static void autoconfig(struct serial_state * state);
- static void change_speed(struct async_struct *info, struct termios *old);
- static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
-
-@@ -325,46 +165,74 @@
- { 0, 0}
- };
-
--#if defined(CONFIG_SERIAL_RSA) && defined(MODULE)
--
--#define PORT_RSA_MAX 4
--static int probe_rsa[PORT_RSA_MAX];
--static int force_rsa[PORT_RSA_MAX];
--
--MODULE_PARM(probe_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i");
--MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
--MODULE_PARM(force_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i");
--MODULE_PARM_DESC(force_rsa, "Force I/O ports for RSA");
--#endif /* CONFIG_SERIAL_RSA */
--
--struct serial_state rs_table[RS_TABLE_SIZE] = {
-- SERIAL_PORT_DFNS /* Defined in serial.h */
-+static struct serial_state rs_table[] = {
-+ {
-+ type: PORT_PXA,
-+ xmit_fifo_size: 32,
-+ baud_base: 921600,
-+ iomem_base: (void *)&FFUART,
-+ iomem_reg_shift: 2,
-+ io_type: SERIAL_IO_MEM32,
-+ irq: IRQ_FFUART,
-+ flags: ASYNC_SKIP_TEST,
-+ }, {
-+ type: PORT_PXA,
-+ xmit_fifo_size: 32,
-+ baud_base: 921600,
-+ iomem_base: (void *)&BTUART,
-+ iomem_reg_shift: 2,
-+ io_type: SERIAL_IO_MEM32,
-+ irq: IRQ_BTUART,
-+ flags: ASYNC_SKIP_TEST,
-+ }, {
-+ type: PORT_PXA,
-+ xmit_fifo_size: 32,
-+ baud_base: 921600,
-+ iomem_base: (void *)&STUART,
-+ iomem_reg_shift: 2,
-+ io_type: SERIAL_IO_MEM32,
-+ irq: IRQ_STUART,
-+ flags: ASYNC_SKIP_TEST,
-+ }, {
-+ type: PORT_16750,
-+ xmit_fifo_size: 64,
-+ baud_base: 115200*2,
-+ iomem_base: (void *)0,
-+ iomem_reg_shift: 2,
-+ io_type: SERIAL_IO_MEM,
-+ irq: IRQ_GPIO(7),
-+ flags: ASYNC_SKIP_TEST,
-+ }, {
-+ type: PORT_16750,
-+ xmit_fifo_size: 64,
-+ baud_base: 115200*2,
-+ iomem_base: (void *)0,
-+ iomem_reg_shift: 2,
-+ io_type: SERIAL_IO_MEM,
-+ irq: IRQ_GPIO(24),
-+ flags: ASYNC_SKIP_TEST,
-+ }, {
-+ type: PORT_16750,
-+ xmit_fifo_size: 64,
-+ baud_base: 115200*2,
-+ iomem_base: (void *)0,
-+ iomem_reg_shift: 2,
-+ io_type: SERIAL_IO_MEM,
-+ irq: IRQ_GPIO(25),
-+ flags: ASYNC_SKIP_TEST,
-+ }, {
-+ type: PORT_16750,
-+ xmit_fifo_size: 64,
-+ baud_base: 115200*2,
-+ iomem_base: (void *)0,
-+ iomem_reg_shift: 2,
-+ io_type: SERIAL_IO_MEM,
-+ irq: IRQ_GPIO(26),
-+ flags: ASYNC_SKIP_TEST,
-+ }
- };
-
- #define NR_PORTS (sizeof(rs_table)/sizeof(struct serial_state))
--int serial_nr_ports = NR_PORTS;
--
--#if (defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP))
--#define NR_PCI_BOARDS 8
--
--static struct pci_board_inst serial_pci_board[NR_PCI_BOARDS];
--
--#ifndef IS_PCI_REGION_IOPORT
--#define IS_PCI_REGION_IOPORT(dev, r) (pci_resource_flags((dev), (r)) & \
-- IORESOURCE_IO)
--#endif
--#ifndef IS_PCI_REGION_IOMEM
--#define IS_PCI_REGION_IOMEM(dev, r) (pci_resource_flags((dev), (r)) & \
-- IORESOURCE_MEM)
--#endif
--#ifndef PCI_IRQ_RESOURCE
--#define PCI_IRQ_RESOURCE(dev, r) ((dev)->irq_resource[r].start)
--#endif
--#ifndef pci_get_subvendor
--#define pci_get_subvendor(dev) ((dev)->subsystem_vendor)
--#define pci_get_subdevice(dev) ((dev)->subsystem_device)
--#endif
--#endif /* ENABLE_SERIAL_PCI || ENABLE_SERIAL_PNP */
-
- #ifndef PREPARE_FUNC
- #define PREPARE_FUNC(dev) (dev->prepare)
-@@ -403,39 +271,21 @@
- #endif
-
-
--static inline int serial_paranoia_check(struct async_struct *info,
-- kdev_t device, const char *routine)
--{
--#ifdef SERIAL_PARANOIA_CHECK
-- static const char *badmagic =
-- "Warning: bad magic number for serial struct (%s) in %s\n";
-- static const char *badinfo =
-- "Warning: null async_struct for (%s) in %s\n";
--
-- if (!info) {
-- printk(badinfo, kdevname(device), routine);
-- return 1;
-- }
-- if (info->magic != SERIAL_MAGIC) {
-- printk(badmagic, kdevname(device), routine);
-- return 1;
-- }
--#endif
-- return 0;
--}
--
- static _INLINE_ unsigned int serial_in(struct async_struct *info, int offset)
- {
-+ unsigned int value;
- switch (info->io_type) {
--#ifdef CONFIG_HUB6
-- case SERIAL_IO_HUB6:
-- outb(info->hub6 - 1 + offset, info->port);
-- return inb(info->port+1);
--#endif
- case SERIAL_IO_MEM:
-- return readb((unsigned long) info->iomem_base +
-+ value = readb((unsigned long) info->iomem_base +
- (offset<<info->iomem_reg_shift));
-+ udelay(10);
-+ if (show_io) printk("in %02x = %02x\n", offset, value);
-+ return value;
- case SERIAL_IO_MEM32:
-+ value = readl((unsigned long) info->iomem_base +
-+ (offset<<info->iomem_reg_shift));
-+ if (show_io) printk("in %02x = %02x\n", offset, value);
-+ return value;
- return readl((unsigned long) info->iomem_base +
- (offset<<info->iomem_reg_shift));
- default:
-@@ -447,17 +297,14 @@
- int value)
- {
- switch (info->io_type) {
--#ifdef CONFIG_HUB6
-- case SERIAL_IO_HUB6:
-- outb(info->hub6 - 1 + offset, info->port);
-- outb(value, info->port+1);
-- break;
--#endif
- case SERIAL_IO_MEM:
-+ if (show_io) printk("out %02x, %02x\n", offset, value);
- writeb(value, (unsigned long) info->iomem_base +
- (offset<<info->iomem_reg_shift));
-+ udelay(10);
- break;
- case SERIAL_IO_MEM32:
-+ if (show_io) printk("out %02x, %02x\n", offset, value);
- writel(value, (unsigned long) info->iomem_base +
- (offset<<info->iomem_reg_shift));
- break;
-@@ -509,9 +356,6 @@
- struct async_struct *info = (struct async_struct *)tty->driver_data;
- unsigned long flags;
-
-- if (serial_paranoia_check(info, tty->device, "rs_stop"))
-- return;
--
- save_flags(flags); cli();
- if (info->IER & UART_IER_THRI) {
- info->IER &= ~UART_IER_THRI;
-@@ -529,9 +373,6 @@
- struct async_struct *info = (struct async_struct *)tty->driver_data;
- unsigned long flags;
-
-- if (serial_paranoia_check(info, tty->device, "rs_start"))
-- return;
--
- save_flags(flags); cli();
- if (info->xmit.head != info->xmit.tail
- && info->xmit.buf
-@@ -689,11 +530,7 @@
- #endif
- *status = serial_inp(info, UART_LSR);
- } while ((*status & UART_LSR_DR) && (max_count-- > 0));
--#if (LINUX_VERSION_CODE > 131394) /* 2.1.66 */
- tty_flip_buffer_push(tty);
--#else
-- queue_task_irq_off(&tty->flip.tqueue, &tq_timer);
--#endif
- }
-
- static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
-@@ -758,11 +595,6 @@
- icount->dsr++;
- if (status & UART_MSR_DDCD) {
- icount->dcd++;
--#ifdef CONFIG_HARD_PPS
-- if ((info->flags & ASYNC_HARDPPS_CD) &&
-- (status & UART_MSR_DCD))
-- hardpps();
--#endif
- }
- if (status & UART_MSR_DCTS)
- icount->cts++;
-@@ -810,120 +642,23 @@
- }
- }
-
--#ifdef CONFIG_SERIAL_SHARE_IRQ
--/*
-- * This is the serial driver's generic interrupt routine
-- */
--static void rs_interrupt(int irq, void *dev_id, struct pt_regs * regs)
--{
-- int status, iir;
-- struct async_struct * info;
-- int pass_counter = 0;
-- struct async_struct *end_mark = 0;
--#ifdef CONFIG_SERIAL_MULTIPORT
-- int first_multi = 0;
-- struct rs_multiport_struct *multi;
--#endif
--
--#ifdef SERIAL_DEBUG_INTR
-- printk("rs_interrupt(%d)...", irq);
--#endif
--
-- info = IRQ_ports[irq];
-- if (!info)
-- return;
--
--#ifdef CONFIG_SERIAL_MULTIPORT
-- multi = &rs_multiport[irq];
-- if (multi->port_monitor)
-- first_multi = inb(multi->port_monitor);
--#endif
--
-- do {
-- if (!info->tty ||
-- ((iir=serial_in(info, UART_IIR)) & UART_IIR_NO_INT)) {
-- if (!end_mark)
-- end_mark = info;
-- goto next;
-- }
--#ifdef SERIAL_DEBUG_INTR
-- printk("IIR = %x...", serial_in(info, UART_IIR));
--#endif
-- end_mark = 0;
--
-- info->last_active = jiffies;
--
-- status = serial_inp(info, UART_LSR);
--#ifdef SERIAL_DEBUG_INTR
-- printk("status = %x...", status);
--#endif
-- if (status & UART_LSR_DR)
-- receive_chars(info, &status, regs);
-- check_modem_status(info);
--#ifdef CONFIG_MELAN
-- if ((status & UART_LSR_THRE) ||
-- /* for buggy ELAN processors */
-- ((iir & UART_IIR_ID) == UART_IIR_THRI))
-- transmit_chars(info, 0);
--#else
-- if (status & UART_LSR_THRE)
-- transmit_chars(info, 0);
--#endif
--
-- next:
-- info = info->next_port;
-- if (!info) {
-- info = IRQ_ports[irq];
-- if (pass_counter++ > RS_ISR_PASS_LIMIT) {
--#if 0
-- printk("rs loop break\n");
--#endif
-- break; /* Prevent infinite loops */
-- }
-- continue;
-- }
-- } while (end_mark != info);
--#ifdef CONFIG_SERIAL_MULTIPORT
-- if (multi->port_monitor)
-- printk("rs port monitor (normal) irq %d: 0x%x, 0x%x\n",
-- info->state->irq, first_multi,
-- inb(multi->port_monitor));
--#endif
--#ifdef SERIAL_DEBUG_INTR
-- printk("end.\n");
--#endif
--}
--#endif /* #ifdef CONFIG_SERIAL_SHARE_IRQ */
--
-
- /*
- * This is the serial driver's interrupt routine for a single port
- */
- static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
- {
-- int status, iir;
-+ int status;
- int pass_counter = 0;
- struct async_struct * info;
--#ifdef CONFIG_SERIAL_MULTIPORT
-- int first_multi = 0;
-- struct rs_multiport_struct *multi;
--#endif
-
- #ifdef SERIAL_DEBUG_INTR
- printk("rs_interrupt_single(%d)...", irq);
- #endif
--
- info = IRQ_ports[irq];
- if (!info || !info->tty)
- return;
-
--#ifdef CONFIG_SERIAL_MULTIPORT
-- multi = &rs_multiport[irq];
-- if (multi->port_monitor)
-- first_multi = inb(multi->port_monitor);
--#endif
--
-- iir = serial_in(info, UART_IIR);
- do {
- status = serial_inp(info, UART_LSR);
- #ifdef SERIAL_DEBUG_INTR
-@@ -932,120 +667,23 @@
- if (status & UART_LSR_DR)
- receive_chars(info, &status, regs);
- check_modem_status(info);
-- if ((status & UART_LSR_THRE) ||
-- /* For buggy ELAN processors */
-- ((iir & UART_IIR_ID) == UART_IIR_THRI))
-+ if (status & UART_LSR_THRE)
- transmit_chars(info, 0);
- if (pass_counter++ > RS_ISR_PASS_LIMIT) {
--#if SERIAL_DEBUG_INTR
-+#if 0
- printk("rs_single loop break.\n");
- #endif
- break;
- }
-- iir = serial_in(info, UART_IIR);
--#ifdef SERIAL_DEBUG_INTR
-- printk("IIR = %x...", iir);
--#endif
-- } while ((iir & UART_IIR_NO_INT) == 0);
-- info->last_active = jiffies;
--#ifdef CONFIG_SERIAL_MULTIPORT
-- if (multi->port_monitor)
-- printk("rs port monitor (single) irq %d: 0x%x, 0x%x\n",
-- info->state->irq, first_multi,
-- inb(multi->port_monitor));
--#endif
--#ifdef SERIAL_DEBUG_INTR
-- printk("end.\n");
--#endif
--}
--
--#ifdef CONFIG_SERIAL_MULTIPORT
--/*
-- * This is the serial driver's for multiport boards
-- */
--static void rs_interrupt_multi(int irq, void *dev_id, struct pt_regs * regs)
--{
-- int status;
-- struct async_struct * info;
-- int pass_counter = 0;
-- int first_multi= 0;
-- struct rs_multiport_struct *multi;
--
- #ifdef SERIAL_DEBUG_INTR
-- printk("rs_interrupt_multi(%d)...", irq);
-+ printk("IIR = %x...", serial_in(info, UART_IIR));
- #endif
--
-- info = IRQ_ports[irq];
-- if (!info)
-- return;
-- multi = &rs_multiport[irq];
-- if (!multi->port1) {
-- /* Should never happen */
-- printk("rs_interrupt_multi: NULL port1!\n");
-- return;
-- }
-- if (multi->port_monitor)
-- first_multi = inb(multi->port_monitor);
--
-- while (1) {
-- if (!info->tty ||
-- (serial_in(info, UART_IIR) & UART_IIR_NO_INT))
-- goto next;
--
-+ } while (!(serial_in(info, UART_IIR) & UART_IIR_NO_INT));
- info->last_active = jiffies;
--
-- status = serial_inp(info, UART_LSR);
--#ifdef SERIAL_DEBUG_INTR
-- printk("status = %x...", status);
--#endif
-- if (status & UART_LSR_DR)
-- receive_chars(info, &status, regs);
-- check_modem_status(info);
-- if (status & UART_LSR_THRE)
-- transmit_chars(info, 0);
--
-- next:
-- info = info->next_port;
-- if (info)
-- continue;
--
-- info = IRQ_ports[irq];
-- /*
-- * The user was a bonehead, and misconfigured their
-- * multiport info. Rather than lock up the kernel
-- * in an infinite loop, if we loop too many times,
-- * print a message and break out of the loop.
-- */
-- if (pass_counter++ > RS_ISR_PASS_LIMIT) {
-- printk("Misconfigured multiport serial info "
-- "for irq %d. Breaking out irq loop\n", irq);
-- break;
-- }
-- if (multi->port_monitor)
-- printk("rs port monitor irq %d: 0x%x, 0x%x\n",
-- info->state->irq, first_multi,
-- inb(multi->port_monitor));
-- if ((inb(multi->port1) & multi->mask1) != multi->match1)
-- continue;
-- if (!multi->port2)
-- break;
-- if ((inb(multi->port2) & multi->mask2) != multi->match2)
-- continue;
-- if (!multi->port3)
-- break;
-- if ((inb(multi->port3) & multi->mask3) != multi->match3)
-- continue;
-- if (!multi->port4)
-- break;
-- if ((inb(multi->port4) & multi->mask4) != multi->match4)
-- continue;
-- break;
-- }
- #ifdef SERIAL_DEBUG_INTR
- printk("end.\n");
- #endif
- }
--#endif
-
- /*
- * -------------------------------------------------------------------
-@@ -1107,22 +745,6 @@
- if (!info)
- continue;
- save_flags(flags); cli();
--#ifdef CONFIG_SERIAL_SHARE_IRQ
-- if (info->next_port) {
-- do {
-- serial_out(info, UART_IER, 0);
-- info->IER |= UART_IER_THRI;
-- serial_out(info, UART_IER, info->IER);
-- info = info->next_port;
-- } while (info);
--#ifdef CONFIG_SERIAL_MULTIPORT
-- if (rs_multiport[i].port1)
-- rs_interrupt_multi(i, NULL, NULL);
-- else
--#endif
-- rs_interrupt(i, NULL, NULL);
-- } else
--#endif /* CONFIG_SERIAL_SHARE_IRQ */
- rs_interrupt_single(i, NULL, NULL);
- restore_flags(flags);
- }
-@@ -1132,11 +754,7 @@
-
- if (IRQ_ports[0]) {
- save_flags(flags); cli();
--#ifdef CONFIG_SERIAL_SHARE_IRQ
-- rs_interrupt(0, NULL, NULL);
--#else
- rs_interrupt_single(0, NULL, NULL);
--#endif
- restore_flags(flags);
-
- mod_timer(&serial_timer, jiffies + IRQ_timeout[0]);
-@@ -1177,50 +795,6 @@
- IRQ_timeout[irq] = (timeout > 3) ? timeout-2 : 1;
- }
-
--#ifdef CONFIG_SERIAL_RSA
--/* Attempts to turn on the RSA FIFO. Returns zero on failure */
--static int enable_rsa(struct async_struct *info)
--{
-- unsigned char mode;
-- int result;
-- unsigned long flags;
--
-- save_flags(flags); cli();
-- mode = serial_inp(info, UART_RSA_MSR);
-- result = mode & UART_RSA_MSR_FIFO;
--
-- if (!result) {
-- serial_outp(info, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
-- mode = serial_inp(info, UART_RSA_MSR);
-- result = mode & UART_RSA_MSR_FIFO;
-- }
--
-- restore_flags(flags);
-- return result;
--}
--
--/* Attempts to turn off the RSA FIFO. Returns zero on failure */
--static int disable_rsa(struct async_struct *info)
--{
-- unsigned char mode;
-- int result;
-- unsigned long flags;
--
-- save_flags(flags); cli();
-- mode = serial_inp(info, UART_RSA_MSR);
-- result = !(mode & UART_RSA_MSR_FIFO);
--
-- if (!result) {
-- serial_outp(info, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
-- mode = serial_inp(info, UART_RSA_MSR);
-- result = !(mode & UART_RSA_MSR_FIFO);
-- }
--
-- restore_flags(flags);
-- return result;
--}
--#endif /* CONFIG_SERIAL_RSA */
--
- static int startup(struct async_struct * info)
- {
- unsigned long flags;
-@@ -1228,9 +802,6 @@
- void (*handler)(int, void *, struct pt_regs *);
- struct serial_state *state= info->state;
- unsigned long page;
--#ifdef CONFIG_SERIAL_MANY_PORTS
-- unsigned short ICP;
--#endif
-
- page = get_zeroed_page(GFP_KERNEL);
- if (!page)
-@@ -1258,6 +829,22 @@
- printk("starting up ttys%d (irq %d)...", info->line, state->irq);
- #endif
-
-+ // Special handling to give power to devices
-+ switch (info->line) {
-+ case 3:
-+ //printk("gsm on\n");
-+ RAMSES_GSM_ON();
-+ break;
-+ case 4:
-+ //printk("uart on\n");
-+ RAMSES_UART_ON();
-+ break;
-+ case 5:
-+ //printk("scanner on\n");
-+ RAMSES_SCANNER_ON();
-+ break;
-+ }
-+
- if (uart_config[state->type].flags & UART_STARTECH) {
- /* Wake up UART */
- serial_outp(info, UART_LCR, 0xBF);
-@@ -1305,25 +892,12 @@
- serial_outp(info, UART_LCR, 0);
- }
-
--#ifdef CONFIG_SERIAL_RSA
-- /*
-- * If this is an RSA port, see if we can kick it up to the
-- * higher speed clock.
-- */
-- if (state->type == PORT_RSA) {
-- if (state->baud_base != SERIAL_RSA_BAUD_BASE &&
-- enable_rsa(info))
-- state->baud_base = SERIAL_RSA_BAUD_BASE;
-- if (state->baud_base == SERIAL_RSA_BAUD_BASE)
-- serial_outp(info, UART_RSA_FRR, 0);
-- }
--#endif
--
- #ifdef CONFIG_ARCH_PXA
- if (state->type == PORT_PXA) {
- switch ((long)state->iomem_base) {
- case (long)&FFUART: CKEN |= CKEN6_FFUART; break;
- case (long)&BTUART: CKEN |= CKEN7_BTUART; break;
-+ //HS TODO: cerf keeps the clock on
- case (long)&STUART: CKEN |= CKEN5_STUART; break;
- }
- }
-@@ -1344,6 +918,7 @@
- /*
- * Clear the interrupt registers.
- */
-+ (void) serial_inp(info, UART_IIR);
- (void) serial_inp(info, UART_LSR);
- (void) serial_inp(info, UART_RX);
- (void) serial_inp(info, UART_IIR);
-@@ -1371,18 +946,8 @@
- if (state->irq && (!IRQ_ports[state->irq] ||
- !IRQ_ports[state->irq]->next_port)) {
- if (IRQ_ports[state->irq]) {
--#ifdef CONFIG_SERIAL_SHARE_IRQ
-- free_irq(state->irq, &IRQ_ports[state->irq]);
--#ifdef CONFIG_SERIAL_MULTIPORT
-- if (rs_multiport[state->irq].port1)
-- handler = rs_interrupt_multi;
-- else
--#endif
-- handler = rs_interrupt;
--#else
- retval = -EBUSY;
- goto errout;
--#endif /* CONFIG_SERIAL_SHARE_IRQ */
- } else
- handler = rs_interrupt_single;
-
-@@ -1417,12 +982,6 @@
- info->MCR = 0;
- if (info->tty->termios->c_cflag & CBAUD)
- info->MCR = UART_MCR_DTR | UART_MCR_RTS;
--#ifdef CONFIG_SERIAL_MANY_PORTS
-- if (info->flags & ASYNC_FOURPORT) {
-- if (state->irq == 0)
-- info->MCR |= UART_MCR_OUT1;
-- } else
--#endif
- {
- if (state->irq != 0)
- info->MCR |= UART_MCR_OUT2;
-@@ -1437,18 +996,9 @@
- */
- info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
- if (pxa_port(state->type))
-- info->IER |= UART_IER_UUE | UART_IER_RTOIE;
-+ info->IER |= UART_IER_UUE | UART_IER_RTOIE; //HS TODO: UART_IER_THRI for PXA uarts?
- serial_outp(info, UART_IER, info->IER); /* enable interrupts */
-
--#ifdef CONFIG_SERIAL_MANY_PORTS
-- if (info->flags & ASYNC_FOURPORT) {
-- /* Enable interrupts on the AST Fourport board */
-- ICP = (info->port & 0xFE0) | 0x01F;
-- outb_p(0x80, ICP);
-- (void) inb_p(ICP);
-- }
--#endif
--
- /*
- * And clear the interrupt registers again for luck.
- */
-@@ -1469,7 +1019,6 @@
- /*
- * Set up the tty->alt_speed kludge
- */
--#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
- if (info->tty) {
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
- info->tty->alt_speed = 57600;
-@@ -1480,7 +1029,6 @@
- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
- info->tty->alt_speed = 460800;
- }
--#endif
-
- /*
- * and set the speed of the serial port
-@@ -1516,6 +1064,30 @@
- state->irq);
- #endif
-
-+ switch (info->line) {
-+ case 3:
-+ if (ramses_stay_on & RAMSES_CONTROL_GSM_PWR) {
-+ //printk("gsm on\n");
-+ RAMSES_GSM_OFF();
-+ }
-+ //else printk("gsm stays on\n");
-+ break;
-+ case 4:
-+ if (ramses_stay_on & RAMSES_CONTROL_UART_PWR) {
-+ //printk("uart off\n");
-+ RAMSES_UART_OFF();
-+ }
-+ //else printk("uart stays on\n");
-+ break;
-+ case 5:
-+ if (ramses_stay_on & RAMSES_CONTROL_SCANNER_PWR) {
-+ //printk("scanner off\n");
-+ RAMSES_SCANNER_OFF();
-+ }
-+ //else printk("scanner on\n");
-+ break;
-+ }
-+
- save_flags(flags); cli(); /* Disable interrupts */
-
- /*
-@@ -1561,13 +1133,6 @@
-
- info->IER = 0;
- serial_outp(info, UART_IER, 0x00); /* disable all intrs */
--#ifdef CONFIG_SERIAL_MANY_PORTS
-- if (info->flags & ASYNC_FOURPORT) {
-- /* reset interrupts on the AST Fourport board */
-- (void) inb((info->port & 0xFE0) | 0x01F);
-- info->MCR |= UART_MCR_OUT1;
-- } else
--#endif
- info->MCR &= ~UART_MCR_OUT2;
- if (pxa_buggy_port(state->type))
- info->MCR ^= UART_MCR_OUT2;
-@@ -1586,16 +1151,6 @@
- UART_FCR_CLEAR_XMIT));
- serial_outp(info, UART_FCR, 0);
-
--#ifdef CONFIG_SERIAL_RSA
-- /*
-- * Reset the RSA board back to 115kbps compat mode.
-- */
-- if ((state->type == PORT_RSA) &&
-- (state->baud_base == SERIAL_RSA_BAUD_BASE &&
-- disable_rsa(info)))
-- state->baud_base = SERIAL_RSA_BAUD_BASE_LO;
--#endif
--
- #ifdef CONFIG_ARCH_PXA
- if (state->type == PORT_PXA
- #ifdef CONFIG_SERIAL_CONSOLE
-@@ -1634,37 +1189,6 @@
- restore_flags(flags);
- }
-
--#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
--static int baud_table[] = {
-- 0, 50, 75, 110, 134, 150, 200, 300,
-- 600, 1200, 1800, 2400, 4800, 9600, 19200,
-- 38400, 57600, 115200, 230400, 460800, 0 };
--
--static int tty_get_baud_rate(struct tty_struct *tty)
--{
-- struct async_struct * info = (struct async_struct *)tty->driver_data;
-- unsigned int cflag, i;
--
-- cflag = tty->termios->c_cflag;
--
-- i = cflag & CBAUD;
-- if (i & CBAUDEX) {
-- i &= ~CBAUDEX;
-- if (i < 1 || i > 2)
-- tty->termios->c_cflag &= ~CBAUDEX;
-- else
-- i += 15;
-- }
-- if (i == 15) {
-- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-- i += 1;
-- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-- i += 2;
-- }
-- return baud_table[i];
--}
--#endif
--
- /*
- * This routine is called to set the UART divisor registers to match
- * the specified baud rate for a serial port.
-@@ -1711,12 +1235,6 @@
- baud = tty_get_baud_rate(info->tty);
- if (!baud)
- baud = 9600; /* B0 transition handled in rs_set_termios */
--#ifdef CONFIG_SERIAL_RSA
-- if ((info->state->type == PORT_RSA) &&
-- (info->state->baud_base != SERIAL_RSA_BAUD_BASE) &&
-- enable_rsa(info))
-- info->state->baud_base = SERIAL_RSA_BAUD_BASE;
--#endif
- baud_base = info->state->baud_base;
- if (info->state->type == PORT_16C950) {
- if (baud <= baud_base)
-@@ -1778,10 +1296,6 @@
- if (uart_config[info->state->type].flags & UART_USE_FIFO) {
- if ((info->state->baud_base / quot) < 2400)
- fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
--#ifdef CONFIG_SERIAL_RSA
-- else if (info->state->type == PORT_RSA)
-- fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_14;
--#endif
- else
- fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
- }
-@@ -1864,9 +1378,6 @@
- struct async_struct *info = (struct async_struct *)tty->driver_data;
- unsigned long flags;
-
-- if (serial_paranoia_check(info, tty->device, "rs_put_char"))
-- return;
--
- if (!tty || !info->xmit.buf)
- return;
-
-@@ -1888,9 +1399,6 @@
- struct async_struct *info = (struct async_struct *)tty->driver_data;
- unsigned long flags;
-
-- if (serial_paranoia_check(info, tty->device, "rs_flush_chars"))
-- return;
--
- if (info->xmit.head == info->xmit.tail
- || tty->stopped
- || tty->hw_stopped
-@@ -1900,8 +1408,6 @@
- save_flags(flags); cli();
- info->IER |= UART_IER_THRI;
- serial_out(info, UART_IER, info->IER);
-- if (pxa_buggy_port(info->state->type))
-- rs_interrupt_single(info->state->irq, NULL, NULL);
- restore_flags(flags);
- }
-
-@@ -1912,9 +1418,6 @@
- struct async_struct *info = (struct async_struct *)tty->driver_data;
- unsigned long flags;
-
-- if (serial_paranoia_check(info, tty->device, "rs_write"))
-- return 0;
--
- if (!tty || !info->xmit.buf || !tmp_buf)
- return 0;
-
-@@ -1978,11 +1481,6 @@
- && !(info->IER & UART_IER_THRI)) {
- info->IER |= UART_IER_THRI;
- serial_out(info, UART_IER, info->IER);
-- if (pxa_buggy_port(info->state->type)) {
-- save_flags(flags); cli();
-- rs_interrupt_single(info->state->irq, NULL, NULL);
-- restore_flags(flags);
-- }
- }
- return ret;
- }
-@@ -1991,8 +1489,6 @@
- {
- struct async_struct *info = (struct async_struct *)tty->driver_data;
-
-- if (serial_paranoia_check(info, tty->device, "rs_write_room"))
-- return 0;
- return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
- }
-
-@@ -2000,8 +1496,6 @@
- {
- struct async_struct *info = (struct async_struct *)tty->driver_data;
-
-- if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
-- return 0;
- return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
- }
-
-@@ -2010,8 +1504,6 @@
- struct async_struct *info = (struct async_struct *)tty->driver_data;
- unsigned long flags;
-
-- if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
-- return;
- save_flags(flags); cli();
- info->xmit.head = info->xmit.tail = 0;
- restore_flags(flags);
-@@ -2032,16 +1524,11 @@
- {
- struct async_struct *info = (struct async_struct *)tty->driver_data;
-
-- if (serial_paranoia_check(info, tty->device, "rs_send_char"))
-- return;
--
- info->x_char = ch;
- if (ch) {
- /* Make sure transmit interrupts are on */
- info->IER |= UART_IER_THRI;
- serial_out(info, UART_IER, info->IER);
-- if (pxa_buggy_port(info->state->type))
-- rs_interrupt_single(info->state->irq, NULL, NULL);
- }
- }
-
-@@ -2064,9 +1551,6 @@
- tty->ldisc.chars_in_buffer(tty));
- #endif
-
-- if (serial_paranoia_check(info, tty->device, "rs_throttle"))
-- return;
--
- if (I_IXOFF(tty))
- rs_send_xchar(tty, STOP_CHAR(tty));
-
-@@ -2089,9 +1573,6 @@
- tty->ldisc.chars_in_buffer(tty));
- #endif
-
-- if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
-- return;
--
- if (I_IXOFF(tty)) {
- if (info->x_char)
- info->x_char = 0;
-@@ -2134,7 +1615,6 @@
- tmp.close_delay = state->close_delay;
- tmp.closing_wait = state->closing_wait;
- tmp.custom_divisor = state->custom_divisor;
-- tmp.hub6 = state->hub6;
- tmp.io_type = state->io_type;
- if (copy_to_user(retinfo,&tmp,sizeof(*retinfo)))
- return -EFAULT;
-@@ -2160,8 +1640,7 @@
- new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET;
-
- change_irq = new_serial.irq != state->irq;
-- change_port = (new_port != ((int) state->port)) ||
-- (new_serial.hub6 != state->hub6);
-+ change_port = (new_port != ((int) state->port));
-
- if (!capable(CAP_SYS_ADMIN)) {
- if (change_irq || change_port ||
-@@ -2198,7 +1677,6 @@
- if (new_serial.type) {
- for (i = 0 ; i < NR_PORTS; i++)
- if ((state != &rs_table[i]) &&
-- (rs_table[i].io_type == SERIAL_IO_PORT) &&
- (rs_table[i].port == new_port) &&
- rs_table[i].type)
- return -EADDRINUSE;
-@@ -2220,18 +1698,11 @@
- state->custom_divisor = new_serial.custom_divisor;
- state->close_delay = new_serial.close_delay * HZ/100;
- state->closing_wait = new_serial.closing_wait * HZ/100;
--#if (LINUX_VERSION_CODE > 0x20100)
- info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
--#endif
- info->xmit_fifo_size = state->xmit_fifo_size =
- new_serial.xmit_fifo_size;
-
- if ((state->type != PORT_UNKNOWN) && state->port) {
--#ifdef CONFIG_SERIAL_RSA
-- if (old_state.type == PORT_RSA)
-- release_region(state->port + UART_RSA_BASE, 16);
-- else
--#endif
- release_region(state->port,8);
- }
- state->type = new_serial.type;
-@@ -2243,31 +1714,19 @@
- shutdown(info);
- state->irq = new_serial.irq;
- info->port = state->port = new_port;
-- info->hub6 = state->hub6 = new_serial.hub6;
-- if (info->hub6)
-- info->io_type = state->io_type = SERIAL_IO_HUB6;
-- else if (info->io_type == SERIAL_IO_HUB6)
-- info->io_type = state->io_type = SERIAL_IO_PORT;
- }
- if ((state->type != PORT_UNKNOWN) && state->port) {
--#ifdef CONFIG_SERIAL_RSA
-- if (state->type == PORT_RSA)
-- request_region(state->port + UART_RSA_BASE,
-- 16, "serial_rsa(set)");
-- else
--#endif
- request_region(state->port,8,"serial(set)");
- }
-
-
- check_and_exit:
-- if ((!state->port && !state->iomem_base) || !state->type)
-+ if (!state->port || !state->type)
- return 0;
- if (info->flags & ASYNC_INITIALIZED) {
- if (((old_state.flags & ASYNC_SPD_MASK) !=
- (state->flags & ASYNC_SPD_MASK)) ||
- (old_state.custom_divisor != state->custom_divisor)) {
--#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
- if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
- info->tty->alt_speed = 57600;
- if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-@@ -2276,7 +1735,6 @@
- info->tty->alt_speed = 230400;
- if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
- info->tty->alt_speed = 460800;
--#endif
- change_speed(info, 0);
- }
- } else
-@@ -2414,60 +1872,14 @@
- return 0;
- }
-
--static int do_autoconfig(struct async_struct * info)
--{
-- int irq, retval;
--
-- if (!capable(CAP_SYS_ADMIN))
-- return -EPERM;
--
-- if (info->state->count > 1)
-- return -EBUSY;
--
-- shutdown(info);
--
-- autoconfig(info->state);
-- if ((info->state->flags & ASYNC_AUTO_IRQ) &&
-- (info->state->port != 0 || info->state->iomem_base != 0) &&
-- (info->state->type != PORT_UNKNOWN)) {
-- irq = detect_uart_irq(info->state);
-- if (irq > 0)
-- info->state->irq = irq;
-- }
--
-- retval = startup(info);
-- if (retval)
-- return retval;
-- return 0;
--}
--
- /*
- * rs_break() --- routine which turns the break handling on or off
- */
--#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
--static void send_break( struct async_struct * info, int duration)
--{
-- if (!CONFIGURED_SERIAL_PORT(info))
-- return;
-- current->state = TASK_INTERRUPTIBLE;
-- current->timeout = jiffies + duration;
-- cli();
-- info->LCR |= UART_LCR_SBC;
-- serial_out(info, UART_LCR, info->LCR);
-- schedule();
-- info->LCR &= ~UART_LCR_SBC;
-- serial_out(info, UART_LCR, info->LCR);
-- sti();
--}
--#else
- static void rs_break(struct tty_struct *tty, int break_state)
- {
- struct async_struct * info = (struct async_struct *)tty->driver_data;
- unsigned long flags;
-
-- if (serial_paranoia_check(info, tty->device, "rs_break"))
-- return;
--
- if (!CONFIGURED_SERIAL_PORT(info))
- return;
- save_flags(flags); cli();
-@@ -2478,121 +1890,6 @@
- serial_out(info, UART_LCR, info->LCR);
- restore_flags(flags);
- }
--#endif
--
--#ifdef CONFIG_SERIAL_MULTIPORT
--static int get_multiport_struct(struct async_struct * info,
-- struct serial_multiport_struct *retinfo)
--{
-- struct serial_multiport_struct ret;
-- struct rs_multiport_struct *multi;
--
-- multi = &rs_multiport[info->state->irq];
--
-- ret.port_monitor = multi->port_monitor;
--
-- ret.port1 = multi->port1;
-- ret.mask1 = multi->mask1;
-- ret.match1 = multi->match1;
--
-- ret.port2 = multi->port2;
-- ret.mask2 = multi->mask2;
-- ret.match2 = multi->match2;
--
-- ret.port3 = multi->port3;
-- ret.mask3 = multi->mask3;
-- ret.match3 = multi->match3;
--
-- ret.port4 = multi->port4;
-- ret.mask4 = multi->mask4;
-- ret.match4 = multi->match4;
--
-- ret.irq = info->state->irq;
--
-- if (copy_to_user(retinfo,&ret,sizeof(*retinfo)))
-- return -EFAULT;
-- return 0;
--}
--
--static int set_multiport_struct(struct async_struct * info,
-- struct serial_multiport_struct *in_multi)
--{
-- struct serial_multiport_struct new_multi;
-- struct rs_multiport_struct *multi;
-- struct serial_state *state;
-- int was_multi, now_multi;
-- int retval;
-- void (*handler)(int, void *, struct pt_regs *);
--
-- if (!capable(CAP_SYS_ADMIN))
-- return -EPERM;
-- state = info->state;
--
-- if (copy_from_user(&new_multi, in_multi,
-- sizeof(struct serial_multiport_struct)))
-- return -EFAULT;
--
-- if (new_multi.irq != state->irq || state->irq == 0 ||
-- !IRQ_ports[state->irq])
-- return -EINVAL;
--
-- multi = &rs_multiport[state->irq];
-- was_multi = (multi->port1 != 0);
--
-- multi->port_monitor = new_multi.port_monitor;
--
-- if (multi->port1)
-- release_region(multi->port1,1);
-- multi->port1 = new_multi.port1;
-- multi->mask1 = new_multi.mask1;
-- multi->match1 = new_multi.match1;
-- if (multi->port1)
-- request_region(multi->port1,1,"serial(multiport1)");
--
-- if (multi->port2)
-- release_region(multi->port2,1);
-- multi->port2 = new_multi.port2;
-- multi->mask2 = new_multi.mask2;
-- multi->match2 = new_multi.match2;
-- if (multi->port2)
-- request_region(multi->port2,1,"serial(multiport2)");
--
-- if (multi->port3)
-- release_region(multi->port3,1);
-- multi->port3 = new_multi.port3;
-- multi->mask3 = new_multi.mask3;
-- multi->match3 = new_multi.match3;
-- if (multi->port3)
-- request_region(multi->port3,1,"serial(multiport3)");
--
-- if (multi->port4)
-- release_region(multi->port4,1);
-- multi->port4 = new_multi.port4;
-- multi->mask4 = new_multi.mask4;
-- multi->match4 = new_multi.match4;
-- if (multi->port4)
-- request_region(multi->port4,1,"serial(multiport4)");
--
-- now_multi = (multi->port1 != 0);
--
-- if (IRQ_ports[state->irq]->next_port &&
-- (was_multi != now_multi)) {
-- free_irq(state->irq, &IRQ_ports[state->irq]);
-- if (now_multi)
-- handler = rs_interrupt_multi;
-- else
-- handler = rs_interrupt;
--
-- retval = request_irq(state->irq, handler, SA_SHIRQ,
-- "serial", &IRQ_ports[state->irq]);
-- if (retval) {
-- printk("Couldn't reallocate serial interrupt "
-- "driver!!\n");
-- }
-- }
-- return 0;
--}
--#endif
-
- static int rs_ioctl(struct tty_struct *tty, struct file * file,
- unsigned int cmd, unsigned long arg)
-@@ -2601,12 +1898,6 @@
- struct async_icount cprev, cnow; /* kernel counter temps */
- struct serial_icounter_struct icount;
- unsigned long flags;
--#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
-- int retval, tmp;
--#endif
--
-- if (serial_paranoia_check(info, tty->device, "rs_ioctl"))
-- return -ENODEV;
-
- if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
- (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
-@@ -2616,45 +1907,6 @@
- }
-
- switch (cmd) {
--#if (LINUX_VERSION_CODE < 131394) /* Linux 2.1.66 */
-- case TCSBRK: /* SVID version: non-zero arg --> no break */
-- retval = tty_check_change(tty);
-- if (retval)
-- return retval;
-- tty_wait_until_sent(tty, 0);
-- if (signal_pending(current))
-- return -EINTR;
-- if (!arg) {
-- send_break(info, HZ/4); /* 1/4 second */
-- if (signal_pending(current))
-- return -EINTR;
-- }
-- return 0;
-- case TCSBRKP: /* support for POSIX tcsendbreak() */
-- retval = tty_check_change(tty);
-- if (retval)
-- return retval;
-- tty_wait_until_sent(tty, 0);
-- if (signal_pending(current))
-- return -EINTR;
-- send_break(info, arg ? arg*(HZ/10) : HZ/4);
-- if (signal_pending(current))
-- return -EINTR;
-- return 0;
-- case TIOCGSOFTCAR:
-- tmp = C_CLOCAL(tty) ? 1 : 0;
-- if (copy_to_user((void *)arg, &tmp, sizeof(int)))
-- return -EFAULT;
-- return 0;
-- case TIOCSSOFTCAR:
-- if (copy_from_user(&tmp, (void *)arg, sizeof(int)))
-- return -EFAULT;
--
-- tty->termios->c_cflag =
-- ((tty->termios->c_cflag & ~CLOCAL) |
-- (tmp ? CLOCAL : 0));
-- return 0;
--#endif
- case TIOCMGET:
- return get_modem_info(info, (unsigned int *) arg);
- case TIOCMBIS:
-@@ -2667,9 +1919,6 @@
- case TIOCSSERIAL:
- return set_serial_info(info,
- (struct serial_struct *) arg);
-- case TIOCSERCONFIG:
-- return do_autoconfig(info);
--
- case TIOCSERGETLSR: /* Get line status register */
- return get_lsr_info(info, (unsigned int *) arg);
-
-@@ -2679,15 +1928,6 @@
- return -EFAULT;
- return 0;
-
--#ifdef CONFIG_SERIAL_MULTIPORT
-- case TIOCSERGETMULTI:
-- return get_multiport_struct(info,
-- (struct serial_multiport_struct *) arg);
-- case TIOCSERSETMULTI:
-- return set_multiport_struct(info,
-- (struct serial_multiport_struct *) arg);
--#endif
--
- /*
- * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
- * - mask passed in arg for lines of interest
-@@ -2754,6 +1994,39 @@
- printk ("TIOCSER?WILD ioctl obsolete, ignored.\n");
- return 0;
-
-+ case TIOCSERSETMULTI:
-+ switch (arg) {
-+
-+ // switch devices on
-+ case 2: RAMSES_LCD_BLIGHT_ON(); break;
-+ case 3: RAMSES_GSM_ON(); break;
-+ case 4: RAMSES_UART_ON(); break;
-+ case 5: RAMSES_SCANNER_ON(); break;
-+ case 7: RAMSES_SCANNER_WAKE_ON(); break;
-+ case 8: RAMSES_SCANNER_TRIG_ON(); break;
-+ case 9: RAMSES_GSM_RESET_ON(); break;
-+
-+ // switch devices off
-+ case 12: RAMSES_LCD_BLIGHT_OFF(); break;
-+ case 13: RAMSES_GSM_OFF(); break;
-+ case 14: RAMSES_UART_OFF(); break;
-+ case 15: RAMSES_SCANNER_OFF(); break;
-+ case 17: RAMSES_SCANNER_WAKE_OFF(); break;
-+ case 18: RAMSES_SCANNER_TRIG_OFF(); break;
-+ case 19: RAMSES_GSM_RESET_OFF(); break;
-+
-+ // disable automatic poweroff on file-handle close
-+ case 23: ramses_stay_on |= RAMSES_CONTROL_GSM_PWR; break;
-+ case 24: ramses_stay_on |= RAMSES_CONTROL_UART_PWR; break;
-+ case 25: ramses_stay_on |= RAMSES_CONTROL_SCANNER_PWR; break;
-+
-+ // enable automatic poweroff on file-handle close
-+ case 33: ramses_stay_on &= ~RAMSES_CONTROL_GSM_PWR; break;
-+ case 34: ramses_stay_on &= ~RAMSES_CONTROL_UART_PWR; break;
-+ case 35: ramses_stay_on &= ~RAMSES_CONTROL_SCANNER_PWR; break;
-+ }
-+ return 0;
-+
- default:
- return -ENOIOCTLCMD;
- }
-@@ -2801,18 +2074,6 @@
- tty->hw_stopped = 0;
- rs_start(tty);
- }
--
--#if 0
-- /*
-- * No need to wake up processes in open wait, since they
-- * sample the CLOCAL flag once, and don't recheck it.
-- * XXX It's not clear whether the current behavior is correct
-- * or not. Hence, this may change.....
-- */
-- if (!(old_termios->c_cflag & CLOCAL) &&
-- (tty->termios->c_cflag & CLOCAL))
-- wake_up_interruptible(&info->open_wait);
--#endif
- }
-
- /*
-@@ -2831,9 +2092,6 @@
- struct serial_state *state;
- unsigned long flags;
-
-- if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
-- return;
--
- state = info->state;
-
- save_flags(flags); cli();
-@@ -2933,10 +2191,7 @@
- {
- struct async_struct * info = (struct async_struct *)tty->driver_data;
- unsigned long orig_jiffies, char_time;
-- int lsr;
--
-- if (serial_paranoia_check(info, tty->device, "rs_wait_until_sent"))
-- return;
-+ int lsr, old_show_io;
-
- if (info->state->type == PORT_UNKNOWN)
- return;
-@@ -2974,9 +2229,11 @@
- printk("In rs_wait_until_sent(%d) check=%lu...", timeout, char_time);
- printk("jiff=%lu...", jiffies);
- #endif
-+ old_show_io = show_io;
-+ show_io = 0;
- while (!((lsr = serial_inp(info, UART_LSR)) & UART_LSR_TEMT)) {
- #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
-- printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
-+ printk("lsr = %02x (jiff=%lu)...", lsr, jiffies);
- #endif
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(char_time);
-@@ -2986,8 +2243,9 @@
- break;
- }
- #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
-- printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
-+ printk("lsr = %02x (jiff=%lu)...done\n", lsr, jiffies);
- #endif
-+ show_io = old_show_io;
- }
-
- /*
-@@ -2998,9 +2256,6 @@
- struct async_struct * info = (struct async_struct *)tty->driver_data;
- struct serial_state *state = info->state;
-
-- if (serial_paranoia_check(info, tty->device, "rs_hangup"))
-- return;
--
- state = info->state;
-
- rs_flush_buffer(tty);
-@@ -3036,12 +2291,8 @@
- (info->flags & ASYNC_CLOSING)) {
- if (info->flags & ASYNC_CLOSING)
- interruptible_sleep_on(&info->close_wait);
--#ifdef SERIAL_DO_RESTART
- return ((info->flags & ASYNC_HUP_NOTIFY) ?
- -EAGAIN : -ERESTARTSYS);
--#else
-- return -EAGAIN;
--#endif
- }
-
- /*
-@@ -3114,14 +2365,10 @@
- set_current_state(TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp) ||
- !(info->flags & ASYNC_INITIALIZED)) {
--#ifdef SERIAL_DO_RESTART
- if (info->flags & ASYNC_HUP_NOTIFY)
- retval = -EAGAIN;
- else
- retval = -ERESTARTSYS;
--#else
-- retval = -EAGAIN;
--#endif
- break;
- }
- if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-@@ -3223,16 +2470,12 @@
- }
- tty->driver_data = info;
- info->tty = tty;
-- if (serial_paranoia_check(info, tty->device, "rs_open"))
-- return -ENODEV;
-
- #ifdef SERIAL_DEBUG_OPEN
- printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
- info->state->count);
- #endif
--#if (LINUX_VERSION_CODE > 0x20100)
- info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
--#endif
-
- /*
- * This relies on lock_kernel() stuff so wants tidying for 2.5
-@@ -3254,12 +2497,8 @@
- (info->flags & ASYNC_CLOSING)) {
- if (info->flags & ASYNC_CLOSING)
- interruptible_sleep_on(&info->close_wait);
--#ifdef SERIAL_DO_RESTART
- return ((info->flags & ASYNC_HUP_NOTIFY) ?
- -EAGAIN : -ERESTARTSYS);
--#else
-- return -EAGAIN;
--#endif
- }
-
- /*
-@@ -3313,17 +2552,14 @@
- int ret;
- unsigned long flags;
-
-- /*
-- * Return zero characters for ports not claimed by driver.
-- */
-- if (state->type == PORT_UNKNOWN) {
-- return 0; /* ignore unused ports */
-- }
--
- ret = sprintf(buf, "%d: uart:%s port:%lX irq:%d",
- state->line, uart_config[state->type].name,
-- (state->port ? state->port : (long)state->iomem_base),
-- state->irq);
-+ state->port, state->irq);
-+
-+ if (!state->port || (state->type == PORT_UNKNOWN)) {
-+ ret += sprintf(buf+ret, "\n");
-+ return ret;
-+ }
-
- /*
- * Figure out the current RS-232 lines
-@@ -3334,7 +2570,6 @@
- info->magic = SERIAL_MAGIC;
- info->port = state->port;
- info->flags = state->flags;
-- info->hub6 = state->hub6;
- info->io_type = state->io_type;
- info->iomem_base = state->iomem_base;
- info->iomem_reg_shift = state->iomem_reg_shift;
-@@ -3389,13 +2624,13 @@
- }
-
- static int rs_read_proc(char *page, char **start, off_t off, int count,
-- int *eof, void *data)
-+ int *eof, void *data)
- {
- int i, len = 0, l;
- off_t begin = 0;
-
-- len += sprintf(page, "serinfo:1.0 driver:%s%s revision:%s\n",
-- serial_version, LOCAL_VERSTRING, serial_revdate);
-+ len += sprintf(page, "serial: %s\n",
-+ LOCAL_VERSTRING);
- for (i = 0; i < NR_PORTS && len < 4000; i++) {
- l = line_info(page + len, &rs_table[i]);
- len += l;
-@@ -3423,2038 +2658,63 @@
- */
-
- /*
-- * This routine prints out the appropriate serial driver version
-- * number, and identifies which options were configured into this
-- * driver.
-- */
--static char serial_options[] __initdata =
--#ifdef CONFIG_HUB6
-- " HUB-6"
--#define SERIAL_OPT
--#endif
--#ifdef CONFIG_SERIAL_MANY_PORTS
-- " MANY_PORTS"
--#define SERIAL_OPT
--#endif
--#ifdef CONFIG_SERIAL_MULTIPORT
-- " MULTIPORT"
--#define SERIAL_OPT
--#endif
--#ifdef CONFIG_SERIAL_SHARE_IRQ
-- " SHARE_IRQ"
--#define SERIAL_OPT
--#endif
--#ifdef CONFIG_SERIAL_DETECT_IRQ
-- " DETECT_IRQ"
--#define SERIAL_OPT
--#endif
--#ifdef ENABLE_SERIAL_PCI
-- " SERIAL_PCI"
--#define SERIAL_OPT
--#endif
--#ifdef ENABLE_SERIAL_PNP
-- " ISAPNP"
--#define SERIAL_OPT
--#endif
--#ifdef ENABLE_SERIAL_ACPI
-- " SERIAL_ACPI"
--#define SERIAL_OPT
--#endif
--#ifdef SERIAL_OPT
-- " enabled\n";
--#else
-- " no serial options enabled\n";
--#endif
--#undef SERIAL_OPT
--
--static _INLINE_ void show_serial_version(void)
--{
-- printk(KERN_INFO "%s version %s%s (%s) with%s", serial_name,
-- serial_version, LOCAL_VERSTRING, serial_revdate,
-- serial_options);
--}
--
--/*
-- * This routine detect the IRQ of a serial port by clearing OUT2 when
-- * no UART interrupt are requested (IER = 0) (*GPL*). This seems to work at
-- * each time, as long as no other device permanently request the IRQ.
-- * If no IRQ is detected, or multiple IRQ appear, this function returns 0.
-- * The variable "state" and the field "state->port" should not be null.
-- */
--static unsigned detect_uart_irq (struct serial_state * state)
--{
-- int irq;
-- unsigned long irqs;
-- unsigned char save_mcr, save_ier;
-- struct async_struct scr_info; /* serial_{in,out} because HUB6 */
--
--#ifdef CONFIG_SERIAL_MANY_PORTS
-- unsigned char save_ICP=0; /* no warning */
-- unsigned short ICP=0;
--
-- if (state->flags & ASYNC_FOURPORT) {
-- ICP = (state->port & 0xFE0) | 0x01F;
-- save_ICP = inb_p(ICP);
-- outb_p(0x80, ICP);
-- (void) inb_p(ICP);
-- }
--#endif
-- scr_info.magic = SERIAL_MAGIC;
-- scr_info.state = state;
-- scr_info.port = state->port;
-- scr_info.flags = state->flags;
--#ifdef CONFIG_HUB6
-- scr_info.hub6 = state->hub6;
--#endif
-- scr_info.io_type = state->io_type;
-- scr_info.iomem_base = state->iomem_base;
-- scr_info.iomem_reg_shift = state->iomem_reg_shift;
--
-- /* forget possible initially masked and pending IRQ */
-- probe_irq_off(probe_irq_on());
-- save_mcr = serial_inp(&scr_info, UART_MCR);
-- save_ier = serial_inp(&scr_info, UART_IER);
-- serial_outp(&scr_info, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
--
-- irqs = probe_irq_on();
-- serial_outp(&scr_info, UART_MCR, 0);
-- udelay (10);
-- if (state->flags & ASYNC_FOURPORT) {
-- serial_outp(&scr_info, UART_MCR,
-- UART_MCR_DTR | UART_MCR_RTS);
-- } else {
-- serial_outp(&scr_info, UART_MCR,
-- UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
-- }
-- serial_outp(&scr_info, UART_IER, 0x0f); /* enable all intrs */
-- (void)serial_inp(&scr_info, UART_LSR);
-- (void)serial_inp(&scr_info, UART_RX);
-- (void)serial_inp(&scr_info, UART_IIR);
-- (void)serial_inp(&scr_info, UART_MSR);
-- serial_outp(&scr_info, UART_TX, 0xFF);
-- udelay (20);
-- irq = probe_irq_off(irqs);
--
-- serial_outp(&scr_info, UART_MCR, save_mcr);
-- serial_outp(&scr_info, UART_IER, save_ier);
--#ifdef CONFIG_SERIAL_MANY_PORTS
-- if (state->flags & ASYNC_FOURPORT)
-- outb_p(save_ICP, ICP);
--#endif
-- return (irq > 0)? irq : 0;
--}
--
--/*
-- * This is a quickie test to see how big the FIFO is.
-- * It doesn't work at all the time, more's the pity.
-- */
--static int size_fifo(struct async_struct *info)
--{
-- unsigned char old_fcr, old_mcr, old_dll, old_dlm;
-- int count;
--
-- old_fcr = serial_inp(info, UART_FCR);
-- old_mcr = serial_inp(info, UART_MCR);
-- serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO |
-- UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
-- serial_outp(info, UART_MCR, UART_MCR_LOOP);
-- serial_outp(info, UART_LCR, UART_LCR_DLAB);
-- old_dll = serial_inp(info, UART_DLL);
-- old_dlm = serial_inp(info, UART_DLM);
-- serial_outp(info, UART_DLL, 0x01);
-- serial_outp(info, UART_DLM, 0x00);
-- serial_outp(info, UART_LCR, 0x03);
-- for (count = 0; count < 256; count++)
-- serial_outp(info, UART_TX, count);
-- mdelay(20);
-- for (count = 0; (serial_inp(info, UART_LSR) & UART_LSR_DR) &&
-- (count < 256); count++)
-- serial_inp(info, UART_RX);
-- serial_outp(info, UART_FCR, old_fcr);
-- serial_outp(info, UART_MCR, old_mcr);
-- serial_outp(info, UART_LCR, UART_LCR_DLAB);
-- serial_outp(info, UART_DLL, old_dll);
-- serial_outp(info, UART_DLM, old_dlm);
--
-- return count;
--}
--
--/*
-- * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
-- * When this function is called we know it is at least a StarTech
-- * 16650 V2, but it might be one of several StarTech UARTs, or one of
-- * its clones. (We treat the broken original StarTech 16650 V1 as a
-- * 16550, and why not? Startech doesn't seem to even acknowledge its
-- * existence.)
-- *
-- * What evil have men's minds wrought...
-- */
--static void autoconfig_startech_uarts(struct async_struct *info,
-- struct serial_state *state,
-- unsigned long flags)
--{
-- unsigned char scratch, scratch2, scratch3, scratch4;
--
-- /*
-- * First we check to see if it's an Oxford Semiconductor UART.
-- *
-- * If we have to do this here because some non-National
-- * Semiconductor clone chips lock up if you try writing to the
-- * LSR register (which serial_icr_read does)
-- */
-- if (state->type == PORT_16550A) {
-- /*
-- * EFR [4] must be set else this test fails
-- *
-- * This shouldn't be necessary, but Mike Hudson
-- * (Exoray@isys.ca) claims that it's needed for 952
-- * dual UART's (which are not recommended for new designs).
-- */
-- info->ACR = 0;
-- serial_out(info, UART_LCR, 0xBF);
-- serial_out(info, UART_EFR, 0x10);
-- serial_out(info, UART_LCR, 0x00);
-- /* Check for Oxford Semiconductor 16C950 */
-- scratch = serial_icr_read(info, UART_ID1);
-- scratch2 = serial_icr_read(info, UART_ID2);
-- scratch3 = serial_icr_read(info, UART_ID3);
--
-- if (scratch == 0x16 && scratch2 == 0xC9 &&
-- (scratch3 == 0x50 || scratch3 == 0x52 ||
-- scratch3 == 0x54)) {
-- state->type = PORT_16C950;
-- state->revision = serial_icr_read(info, UART_REV) |
-- (scratch3 << 8);
-- return;
-- }
-- }
--
-- /*
-- * We check for a XR16C850 by setting DLL and DLM to 0, and
-- * then reading back DLL and DLM. If DLM reads back 0x10,
-- * then the UART is a XR16C850 and the DLL contains the chip
-- * revision. If DLM reads back 0x14, then the UART is a
-- * XR16C854.
-- *
-- */
--
-- /* Save the DLL and DLM */
--
-- serial_outp(info, UART_LCR, UART_LCR_DLAB);
-- scratch3 = serial_inp(info, UART_DLL);
-- scratch4 = serial_inp(info, UART_DLM);
--
-- serial_outp(info, UART_DLL, 0);
-- serial_outp(info, UART_DLM, 0);
-- scratch2 = serial_inp(info, UART_DLL);
-- scratch = serial_inp(info, UART_DLM);
-- serial_outp(info, UART_LCR, 0);
--
-- if (scratch == 0x10 || scratch == 0x14) {
-- if (scratch == 0x10)
-- state->revision = scratch2;
-- state->type = PORT_16850;
-- return;
-- }
--
-- /* Restore the DLL and DLM */
--
-- serial_outp(info, UART_LCR, UART_LCR_DLAB);
-- serial_outp(info, UART_DLL, scratch3);
-- serial_outp(info, UART_DLM, scratch4);
-- serial_outp(info, UART_LCR, 0);
-- /*
-- * We distinguish between the '654 and the '650 by counting
-- * how many bytes are in the FIFO. I'm using this for now,
-- * since that's the technique that was sent to me in the
-- * serial driver update, but I'm not convinced this works.
-- * I've had problems doing this in the past. -TYT
-- */
-- if (size_fifo(info) == 64)
-- state->type = PORT_16654;
-- else
-- state->type = PORT_16650V2;
--}
--
--/*
-- * This routine is called by rs_init() to initialize a specific serial
-- * port. It determines what type of UART chip this serial port is
-- * using: 8250, 16450, 16550, 16550A. The important question is
-- * whether or not this UART is a 16550A or not, since this will
-- * determine whether or not we can use its FIFO features or not.
-- */
--static void autoconfig(struct serial_state * state)
--{
-- unsigned char status1, status2, scratch, scratch2, scratch3;
-- unsigned char save_lcr, save_mcr;
-- struct async_struct *info, scr_info;
-- unsigned long flags;
--
-- state->type = PORT_UNKNOWN;
--
--#ifdef SERIAL_DEBUG_AUTOCONF
-- printk("Testing ttyS%d (0x%04lx, 0x%04x)...\n", state->line,
-- state->port, (unsigned) state->iomem_base);
--#endif
--
-- if (!CONFIGURED_SERIAL_PORT(state))
-- return;
--
-- info = &scr_info; /* This is just for serial_{in,out} */
--
-- info->magic = SERIAL_MAGIC;
-- info->state = state;
-- info->port = state->port;
-- info->flags = state->flags;
--#ifdef CONFIG_HUB6
-- info->hub6 = state->hub6;
--#endif
-- info->io_type = state->io_type;
-- info->iomem_base = state->iomem_base;
-- info->iomem_reg_shift = state->iomem_reg_shift;
--
-- save_flags(flags); cli();
--
-- if (!(state->flags & ASYNC_BUGGY_UART) &&
-- !state->iomem_base) {
-- /*
-- * Do a simple existence test first; if we fail this,
-- * there's no point trying anything else.
-- *
-- * 0x80 is used as a nonsense port to prevent against
-- * false positives due to ISA bus float. The
-- * assumption is that 0x80 is a non-existent port;
-- * which should be safe since include/asm/io.h also
-- * makes this assumption.
-- */
-- scratch = serial_inp(info, UART_IER);
-- serial_outp(info, UART_IER, 0);
--#ifdef __i386__
-- outb(0xff, 0x080);
--#endif
-- scratch2 = serial_inp(info, UART_IER);
-- serial_outp(info, UART_IER, 0x0F);
--#ifdef __i386__
-- outb(0, 0x080);
--#endif
-- scratch3 = serial_inp(info, UART_IER);
-- serial_outp(info, UART_IER, scratch);
-- if (scratch2 || scratch3 != 0x0F) {
--#ifdef SERIAL_DEBUG_AUTOCONF
-- printk("serial: ttyS%d: simple autoconfig failed "
-- "(%02x, %02x)\n", state->line,
-- scratch2, scratch3);
--#endif
-- restore_flags(flags);
-- return; /* We failed; there's nothing here */
-- }
-- }
--
-- save_mcr = serial_in(info, UART_MCR);
-- save_lcr = serial_in(info, UART_LCR);
--
-- /*
-- * Check to see if a UART is really there. Certain broken
-- * internal modems based on the Rockwell chipset fail this
-- * test, because they apparently don't implement the loopback
-- * test mode. So this test is skipped on the COM 1 through
-- * COM 4 ports. This *should* be safe, since no board
-- * manufacturer would be stupid enough to design a board
-- * that conflicts with COM 1-4 --- we hope!
-- */
-- if (!(state->flags & ASYNC_SKIP_TEST)) {
-- serial_outp(info, UART_MCR, UART_MCR_LOOP | 0x0A);
-- status1 = serial_inp(info, UART_MSR) & 0xF0;
-- serial_outp(info, UART_MCR, save_mcr);
-- if (status1 != 0x90) {
--#ifdef SERIAL_DEBUG_AUTOCONF
-- printk("serial: ttyS%d: no UART loopback failed\n",
-- state->line);
--#endif
-- restore_flags(flags);
-- return;
-- }
-- }
-- serial_outp(info, UART_LCR, 0xBF); /* set up for StarTech test */
-- serial_outp(info, UART_EFR, 0); /* EFR is the same as FCR */
-- serial_outp(info, UART_LCR, 0);
-- serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
-- scratch = serial_in(info, UART_IIR) >> 6;
-- switch (scratch) {
-- case 0:
-- state->type = PORT_16450;
-- break;
-- case 1:
-- state->type = PORT_UNKNOWN;
-- break;
-- case 2:
-- state->type = PORT_16550;
-- break;
-- case 3:
-- state->type = PORT_16550A;
-- break;
-- }
-- if (state->type == PORT_16550A) {
-- /* Check for Startech UART's */
-- serial_outp(info, UART_LCR, UART_LCR_DLAB);
-- if (serial_in(info, UART_EFR) == 0) {
-- state->type = PORT_16650;
-- } else {
-- serial_outp(info, UART_LCR, 0xBF);
-- if (serial_in(info, UART_EFR) == 0)
-- autoconfig_startech_uarts(info, state, flags);
-- }
-- }
-- if (state->type == PORT_16550A) {
-- /* Check for TI 16750 */
-- serial_outp(info, UART_LCR, save_lcr | UART_LCR_DLAB);
-- serial_outp(info, UART_FCR,
-- UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
-- scratch = serial_in(info, UART_IIR) >> 5;
-- if (scratch == 7) {
-- /*
-- * If this is a 16750, and not a cheap UART
-- * clone, then it should only go into 64 byte
-- * mode if the UART_FCR7_64BYTE bit was set
-- * while UART_LCR_DLAB was latched.
-- */
-- serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
-- serial_outp(info, UART_LCR, 0);
-- serial_outp(info, UART_FCR,
-- UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
-- scratch = serial_in(info, UART_IIR) >> 5;
-- if (scratch == 6)
-- state->type = PORT_16750;
-- }
-- serial_outp(info, UART_FCR, UART_FCR_ENABLE_FIFO);
-- }
--#if defined(CONFIG_SERIAL_RSA) && defined(MODULE)
-- if (state->type == PORT_16550A) {
-- int i;
--
-- for (i = 0 ; i < PORT_RSA_MAX ; ++i) {
-- if (!probe_rsa[i] && !force_rsa[i])
-- break;
-- if (((probe_rsa[i] != state->port) ||
-- check_region(state->port + UART_RSA_BASE, 16)) &&
-- (force_rsa[i] != state->port))
-- continue;
-- if (!enable_rsa(info))
-- continue;
-- state->type = PORT_RSA;
-- state->baud_base = SERIAL_RSA_BAUD_BASE;
-- break;
-- }
-- }
--#endif
-- serial_outp(info, UART_LCR, save_lcr);
-- if (state->type == PORT_16450) {
-- scratch = serial_in(info, UART_SCR);
-- serial_outp(info, UART_SCR, 0xa5);
-- status1 = serial_in(info, UART_SCR);
-- serial_outp(info, UART_SCR, 0x5a);
-- status2 = serial_in(info, UART_SCR);
-- serial_outp(info, UART_SCR, scratch);
--
-- if ((status1 != 0xa5) || (status2 != 0x5a))
-- state->type = PORT_8250;
-- }
-- state->xmit_fifo_size = uart_config[state->type].dfl_xmit_fifo_size;
--
-- if (state->type == PORT_UNKNOWN) {
-- restore_flags(flags);
-- return;
-- }
--
-- if (info->port) {
--#ifdef CONFIG_SERIAL_RSA
-- if (state->type == PORT_RSA)
-- request_region(info->port + UART_RSA_BASE, 16,
-- "serial_rsa(auto)");
-- else
--#endif
-- request_region(info->port,8,"serial(auto)");
-- }
--
-- /*
-- * Reset the UART.
-- */
--#ifdef CONFIG_SERIAL_RSA
-- if (state->type == PORT_RSA)
-- serial_outp(info, UART_RSA_FRR, 0);
--#endif
-- serial_outp(info, UART_MCR, save_mcr);
-- serial_outp(info, UART_FCR, (UART_FCR_ENABLE_FIFO |
-- UART_FCR_CLEAR_RCVR |
-- UART_FCR_CLEAR_XMIT));
-- serial_outp(info, UART_FCR, 0);
-- (void)serial_in(info, UART_RX);
-- serial_outp(info, UART_IER, 0);
--
-- restore_flags(flags);
--}
--
--int register_serial(struct serial_struct *req);
--void unregister_serial(int line);
--
--#if (LINUX_VERSION_CODE > 0x20100)
--EXPORT_SYMBOL(register_serial);
--EXPORT_SYMBOL(unregister_serial);
--#else
--static struct symbol_table serial_syms = {
--#include <linux/symtab_begin.h>
-- X(register_serial),
-- X(unregister_serial),
--#include <linux/symtab_end.h>
--};
--#endif
--
--
--#if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP)
--
--static void __devinit printk_pnp_dev_id(unsigned short vendor,
-- unsigned short device)
--{
-- printk("%c%c%c%x%x%x%x",
-- 'A' + ((vendor >> 2) & 0x3f) - 1,
-- 'A' + (((vendor & 3) << 3) | ((vendor >> 13) & 7)) - 1,
-- 'A' + ((vendor >> 8) & 0x1f) - 1,
-- (device >> 4) & 0x0f,
-- device & 0x0f,
-- (device >> 12) & 0x0f,
-- (device >> 8) & 0x0f);
--}
--
--static _INLINE_ int get_pci_port(struct pci_dev *dev,
-- struct pci_board *board,
-- struct serial_struct *req,
-- int idx)
--{
-- unsigned long port;
-- int base_idx;
-- int max_port;
-- int offset;
--
-- base_idx = SPCI_FL_GET_BASE(board->flags);
-- if (board->flags & SPCI_FL_BASE_TABLE)
-- base_idx += idx;
--
-- if (board->flags & SPCI_FL_REGION_SZ_CAP) {
-- max_port = pci_resource_len(dev, base_idx) / 8;
-- if (idx >= max_port)
-- return 1;
-- }
--
-- offset = board->first_uart_offset;
--
-- /* Timedia/SUNIX uses a mixture of BARs and offsets */
-- /* Ugh, this is ugly as all hell --- TYT */
-- if(dev->vendor == PCI_VENDOR_ID_TIMEDIA ) /* 0x1409 */
-- switch(idx) {
-- case 0: base_idx=0;
-- break;
-- case 1: base_idx=0; offset=8;
-- break;
-- case 2: base_idx=1;
-- break;
-- case 3: base_idx=1; offset=8;
-- break;
-- case 4: /* BAR 2*/
-- case 5: /* BAR 3 */
-- case 6: /* BAR 4*/
-- case 7: base_idx=idx-2; /* BAR 5*/
-- }
--
-- /* Some Titan cards are also a little weird */
-- if (dev->vendor == PCI_VENDOR_ID_TITAN &&
-- (dev->device == PCI_DEVICE_ID_TITAN_400L ||
-- dev->device == PCI_DEVICE_ID_TITAN_800L)) {
-- switch (idx) {
-- case 0: base_idx = 1;
-- break;
-- case 1: base_idx = 2;
-- break;
-- default:
-- base_idx = 4;
-- offset = 8 * (idx - 2);
-- }
--
-- }
--
-- /* HP's Diva chip puts the 4th/5th serial port further out, and
-- * some serial ports are supposed to be hidden on certain models.
-- */
-- if (dev->vendor == PCI_VENDOR_ID_HP &&
-- dev->device == PCI_DEVICE_ID_HP_SAS) {
-- switch (dev->subsystem_device) {
-- case 0x104B: /* Maestro */
-- if (idx == 3) idx++;
-- break;
-- case 0x1282: /* Everest / Longs Peak */
-- if (idx > 0) idx++;
-- if (idx > 2) idx++;
-- break;
-- }
-- if (idx > 2) {
-- offset = 0x18;
-- }
-- }
--
-- port = pci_resource_start(dev, base_idx) + offset;
--
-- if ((board->flags & SPCI_FL_BASE_TABLE) == 0)
-- port += idx * (board->uart_offset ? board->uart_offset : 8);
--
-- if (IS_PCI_REGION_IOPORT(dev, base_idx)) {
-- req->port = port;
-- if (HIGH_BITS_OFFSET)
-- req->port_high = port >> HIGH_BITS_OFFSET;
-- else
-- req->port_high = 0;
-- return 0;
-- }
-- req->io_type = SERIAL_IO_MEM;
-- req->iomem_base = ioremap(port, board->uart_offset);
-- req->iomem_reg_shift = board->reg_shift;
-- req->port = 0;
-- return 0;
--}
--
--static _INLINE_ int get_pci_irq(struct pci_dev *dev,
-- struct pci_board *board,
-- int idx)
--{
-- int base_idx;
--
-- if ((board->flags & SPCI_FL_IRQRESOURCE) == 0)
-- return dev->irq;
--
-- base_idx = SPCI_FL_GET_IRQBASE(board->flags);
-- if (board->flags & SPCI_FL_IRQ_TABLE)
-- base_idx += idx;
--
-- return PCI_IRQ_RESOURCE(dev, base_idx);
--}
--
--/*
-- * Common enabler code shared by both PCI and ISAPNP probes
-- */
--static void __devinit start_pci_pnp_board(struct pci_dev *dev,
-- struct pci_board *board)
--{
-- int k, line;
-- struct serial_struct serial_req;
-- int base_baud;
--
-- if (PREPARE_FUNC(dev) && (PREPARE_FUNC(dev))(dev) < 0) {
-- printk("serial: PNP device '");
-- printk_pnp_dev_id(dev->vendor, dev->device);
-- printk("' prepare failed\n");
-- return;
-- }
--
-- if (ACTIVATE_FUNC(dev) && (ACTIVATE_FUNC(dev))(dev) < 0) {
-- printk("serial: PNP device '");
-- printk_pnp_dev_id(dev->vendor, dev->device);
-- printk("' activate failed\n");
-- return;
-- }
--
-- /*
-- * Run the initialization function, if any
-- */
-- if (board->init_fn && ((board->init_fn)(dev, board, 1) != 0))
-- return;
--
-- /*
-- * Register the serial board in the array if we need to
-- * shutdown the board on a module unload or card removal
-- */
-- if (DEACTIVATE_FUNC(dev) || board->init_fn) {
-- for (k=0; k < NR_PCI_BOARDS; k++)
-- if (serial_pci_board[k].dev == 0)
-- break;
-- if (k >= NR_PCI_BOARDS)
-- return;
-- serial_pci_board[k].board = *board;
-- serial_pci_board[k].dev = dev;
-- }
--
-- base_baud = board->base_baud;
-- if (!base_baud)
-- base_baud = BASE_BAUD;
-- memset(&serial_req, 0, sizeof(serial_req));
--
-- for (k=0; k < board->num_ports; k++) {
-- serial_req.irq = get_pci_irq(dev, board, k);
-- if (get_pci_port(dev, board, &serial_req, k))
-- break;
-- serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE;
--#ifdef SERIAL_DEBUG_PCI
-- printk("Setup PCI/PNP port: port %x, irq %d, type %d\n",
-- serial_req.port, serial_req.irq, serial_req.io_type);
--#endif
-- line = register_serial(&serial_req);
-- if (line < 0)
-- break;
-- rs_table[line].baud_base = base_baud;
-- rs_table[line].dev = dev;
-- }
--}
--#endif /* ENABLE_SERIAL_PCI || ENABLE_SERIAL_PNP */
--
--#ifdef ENABLE_SERIAL_PCI
--/*
-- * Some PCI serial cards using the PLX 9050 PCI interface chip require
-- * that the card interrupt be explicitly enabled or disabled. This
-- * seems to be mainly needed on card using the PLX which also use I/O
-- * mapped memory.
-- */
--static int __devinit
--pci_plx9050_fn(struct pci_dev *dev, struct pci_board *board, int enable)
--{
-- u8 data, *p, irq_config;
-- int pci_config;
--
-- irq_config = 0x41;
-- pci_config = PCI_COMMAND_MEMORY;
-- if (dev->vendor == PCI_VENDOR_ID_PANACOM)
-- irq_config = 0x43;
-- if ((dev->vendor == PCI_VENDOR_ID_PLX) &&
-- (dev->device == PCI_DEVICE_ID_PLX_ROMULUS)) {
-- /*
-- * As the megawolf cards have the int pins active
-- * high, and have 2 UART chips, both ints must be
-- * enabled on the 9050. Also, the UARTS are set in
-- * 16450 mode by default, so we have to enable the
-- * 16C950 'enhanced' mode so that we can use the deep
-- * FIFOs
-- */
-- irq_config = 0x5b;
-- pci_config = PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
-- }
--
-- pci_read_config_byte(dev, PCI_COMMAND, &data);
--
-- if (enable)
-- pci_write_config_byte(dev, PCI_COMMAND,
-- data | pci_config);
--
-- /* enable/disable interrupts */
-- p = ioremap(pci_resource_start(dev, 0), 0x80);
-- writel(enable ? irq_config : 0x00, (unsigned long)p + 0x4c);
-- iounmap(p);
--
-- if (!enable)
-- pci_write_config_byte(dev, PCI_COMMAND,
-- data & ~pci_config);
-- return 0;
--}
--
--
--/*
-- * SIIG serial cards have an PCI interface chip which also controls
-- * the UART clocking frequency. Each UART can be clocked independently
-- * (except cards equiped with 4 UARTs) and initial clocking settings
-- * are stored in the EEPROM chip. It can cause problems because this
-- * version of serial driver doesn't support differently clocked UART's
-- * on single PCI card. To prevent this, initialization functions set
-- * high frequency clocking for all UART's on given card. It is safe (I
-- * hope) because it doesn't touch EEPROM settings to prevent conflicts
-- * with other OSes (like M$ DOS).
-- *
-- * SIIG support added by Andrey Panin <pazke@mail.tp.ru>, 10/1999
-- *
-- * There is two family of SIIG serial cards with different PCI
-- * interface chip and different configuration methods:
-- * - 10x cards have control registers in IO and/or memory space;
-- * - 20x cards have control registers in standard PCI configuration space.
-- *
-- * SIIG initialization functions exported for use by parport_serial.c module.
-- */
--
--#define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc)
--#define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8)
--
--int __devinit
--pci_siig10x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
--{
-- u16 data, *p;
--
-- if (!enable) return 0;
--
-- p = ioremap(pci_resource_start(dev, 0), 0x80);
--
-- switch (dev->device & 0xfff8) {
-- case PCI_DEVICE_ID_SIIG_1S_10x: /* 1S */
-- data = 0xffdf;
-- break;
-- case PCI_DEVICE_ID_SIIG_2S_10x: /* 2S, 2S1P */
-- data = 0xf7ff;
-- break;
-- default: /* 1S1P, 4S */
-- data = 0xfffb;
-- break;
-- }
--
-- writew(readw((unsigned long) p + 0x28) & data, (unsigned long) p + 0x28);
-- iounmap(p);
-- return 0;
--}
--EXPORT_SYMBOL(pci_siig10x_fn);
--
--#define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc)
--#define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc)
--
--int __devinit
--pci_siig20x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
--{
-- u8 data;
--
-- if (!enable) return 0;
--
-- /* Change clock frequency for the first UART. */
-- pci_read_config_byte(dev, 0x6f, &data);
-- pci_write_config_byte(dev, 0x6f, data & 0xef);
--
-- /* If this card has 2 UART, we have to do the same with second UART. */
-- if (((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S_20x) ||
-- ((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S1P_20x)) {
-- pci_read_config_byte(dev, 0x73, &data);
-- pci_write_config_byte(dev, 0x73, data & 0xef);
-- }
-- return 0;
--}
--EXPORT_SYMBOL(pci_siig20x_fn);
--
--/* Added for EKF Intel i960 serial boards */
--static int __devinit
--pci_inteli960ni_fn(struct pci_dev *dev,
-- struct pci_board *board,
-- int enable)
--{
-- unsigned long oldval;
--
-- if (!(pci_get_subdevice(dev) & 0x1000))
-- return(-1);
--
-- if (!enable) /* is there something to deinit? */
-- return(0);
--
--#ifdef SERIAL_DEBUG_PCI
-- printk(KERN_DEBUG " Subsystem ID %lx (intel 960)\n",
-- (unsigned long) board->subdevice);
--#endif
-- /* is firmware started? */
-- pci_read_config_dword(dev, 0x44, (void*) &oldval);
-- if (oldval == 0x00001000L) { /* RESET value */
-- printk(KERN_DEBUG "Local i960 firmware missing");
-- return(-1);
-- }
-- return(0);
--}
--
--/*
-- * Timedia has an explosion of boards, and to avoid the PCI table from
-- * growing *huge*, we use this function to collapse some 70 entries
-- * in the PCI table into one, for sanity's and compactness's sake.
-- */
--static unsigned short timedia_single_port[] = {
-- 0x4025, 0x4027, 0x4028, 0x5025, 0x5027, 0 };
--static unsigned short timedia_dual_port[] = {
-- 0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085,
-- 0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079,
-- 0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079,
-- 0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079,
-- 0xD079, 0 };
--static unsigned short timedia_quad_port[] = {
-- 0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157,
-- 0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159,
-- 0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056,
-- 0xB157, 0 };
--static unsigned short timedia_eight_port[] = {
-- 0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166,
-- 0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0 };
--static struct timedia_struct {
-- int num;
-- unsigned short *ids;
--} timedia_data[] = {
-- { 1, timedia_single_port },
-- { 2, timedia_dual_port },
-- { 4, timedia_quad_port },
-- { 8, timedia_eight_port },
-- { 0, 0 }
--};
--
--static int __devinit
--pci_timedia_fn(struct pci_dev *dev, struct pci_board *board, int enable)
--{
-- int i, j;
-- unsigned short *ids;
--
-- if (!enable)
-- return 0;
--
-- for (i=0; timedia_data[i].num; i++) {
-- ids = timedia_data[i].ids;
-- for (j=0; ids[j]; j++) {
-- if (pci_get_subdevice(dev) == ids[j]) {
-- board->num_ports = timedia_data[i].num;
-- return 0;
-- }
-- }
-- }
-- return 0;
--}
--
--/*
-- * HP's Remote Management Console. The Diva chip came in several
-- * different versions. N-class, L2000 and A500 have two Diva chips, each
-- * with 3 UARTs (the third UART on the second chip is unused). Superdome
-- * and Keystone have one Diva chip with 3 UARTs. Some later machines have
-- * one Diva chip, but it has been expanded to 5 UARTs.
-- */
--static int __devinit
--pci_hp_diva(struct pci_dev *dev, struct pci_board *board, int enable)
--{
-- if (!enable)
-- return 0;
--
-- switch (dev->subsystem_device) {
-- case 0x1049: /* Prelude Diva 1 */
-- case 0x1223: /* Superdome */
-- case 0x1226: /* Keystone */
-- case 0x1282: /* Everest / Longs Peak */
-- board->num_ports = 3;
-- break;
-- case 0x104A: /* Prelude Diva 2 */
-- board->num_ports = 2;
-- break;
-- case 0x104B: /* Maestro */
-- board->num_ports = 4;
-- break;
-- case 0x1227: /* Powerbar */
-- board->num_ports = 1;
-- break;
-- }
--
-- return 0;
--}
--
--static int __devinit
--pci_xircom_fn(struct pci_dev *dev, struct pci_board *board, int enable)
--{
-- __set_current_state(TASK_UNINTERRUPTIBLE);
-- schedule_timeout(HZ/10);
-- return 0;
--}
--
--/*
-- * This is the configuration table for all of the PCI serial boards
-- * which we support. It is directly indexed by the pci_board_num_t enum
-- * value, which is encoded in the pci_device_id PCI probe table's
-- * driver_data member.
-- */
--enum pci_board_num_t {
-- pbn_b0_1_115200,
-- pbn_default = 0,
--
-- pbn_b0_2_115200,
-- pbn_b0_4_115200,
--
-- pbn_b0_1_921600,
-- pbn_b0_2_921600,
-- pbn_b0_4_921600,
--
-- pbn_b0_bt_1_115200,
-- pbn_b0_bt_2_115200,
-- pbn_b0_bt_1_460800,
-- pbn_b0_bt_2_460800,
-- pbn_b0_bt_2_921600,
--
-- pbn_b1_1_115200,
-- pbn_b1_2_115200,
-- pbn_b1_4_115200,
-- pbn_b1_8_115200,
--
-- pbn_b1_2_921600,
-- pbn_b1_4_921600,
-- pbn_b1_8_921600,
--
-- pbn_b1_2_1382400,
-- pbn_b1_4_1382400,
-- pbn_b1_8_1382400,
--
-- pbn_b2_1_115200,
-- pbn_b2_8_115200,
-- pbn_b2_4_460800,
-- pbn_b2_8_460800,
-- pbn_b2_16_460800,
-- pbn_b2_4_921600,
-- pbn_b2_8_921600,
--
-- pbn_b2_bt_1_115200,
-- pbn_b2_bt_2_115200,
-- pbn_b2_bt_4_115200,
-- pbn_b2_bt_2_921600,
--
-- pbn_panacom,
-- pbn_panacom2,
-- pbn_panacom4,
-- pbn_plx_romulus,
-- pbn_oxsemi,
-- pbn_timedia,
-- pbn_intel_i960,
-- pbn_sgi_ioc3,
-- pbn_hp_diva,
--#ifdef CONFIG_DDB5074
-- pbn_nec_nile4,
--#endif
--#if 0
-- pbn_dci_pccom8,
--#endif
-- pbn_xircom_combo,
--
-- pbn_siig10x_0,
-- pbn_siig10x_1,
-- pbn_siig10x_2,
-- pbn_siig10x_4,
-- pbn_siig20x_0,
-- pbn_siig20x_2,
-- pbn_siig20x_4,
--
-- pbn_computone_4,
-- pbn_computone_6,
-- pbn_computone_8,
--};
--
--static struct pci_board pci_boards[] __devinitdata = {
-- /*
-- * PCI Flags, Number of Ports, Base (Maximum) Baud Rate,
-- * Offset to get to next UART's registers,
-- * Register shift to use for memory-mapped I/O,
-- * Initialization function, first UART offset
-- */
--
-- /* Generic serial board, pbn_b0_1_115200, pbn_default */
-- { SPCI_FL_BASE0, 1, 115200 }, /* pbn_b0_1_115200,
-- pbn_default */
--
-- { SPCI_FL_BASE0, 2, 115200 }, /* pbn_b0_2_115200 */
-- { SPCI_FL_BASE0, 4, 115200 }, /* pbn_b0_4_115200 */
--
-- { SPCI_FL_BASE0, 1, 921600 }, /* pbn_b0_1_921600 */
-- { SPCI_FL_BASE0, 2, 921600 }, /* pbn_b0_2_921600 */
-- { SPCI_FL_BASE0, 4, 921600 }, /* pbn_b0_4_921600 */
--
-- { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* pbn_b0_bt_1_115200 */
-- { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* pbn_b0_bt_2_115200 */
-- { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 460800 }, /* pbn_b0_bt_1_460800 */
-- { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 }, /* pbn_b0_bt_2_460800 */
-- { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 921600 }, /* pbn_b0_bt_2_921600 */
--
-- { SPCI_FL_BASE1, 1, 115200 }, /* pbn_b1_1_115200 */
-- { SPCI_FL_BASE1, 2, 115200 }, /* pbn_b1_2_115200 */
-- { SPCI_FL_BASE1, 4, 115200 }, /* pbn_b1_4_115200 */
-- { SPCI_FL_BASE1, 8, 115200 }, /* pbn_b1_8_115200 */
--
-- { SPCI_FL_BASE1, 2, 921600 }, /* pbn_b1_2_921600 */
-- { SPCI_FL_BASE1, 4, 921600 }, /* pbn_b1_4_921600 */
-- { SPCI_FL_BASE1, 8, 921600 }, /* pbn_b1_8_921600 */
--
-- { SPCI_FL_BASE1, 2, 1382400 }, /* pbn_b1_2_1382400 */
-- { SPCI_FL_BASE1, 4, 1382400 }, /* pbn_b1_4_1382400 */
-- { SPCI_FL_BASE1, 8, 1382400 }, /* pbn_b1_8_1382400 */
--
-- { SPCI_FL_BASE2, 1, 115200 }, /* pbn_b2_1_115200 */
-- { SPCI_FL_BASE2, 8, 115200 }, /* pbn_b2_8_115200 */
-- { SPCI_FL_BASE2, 4, 460800 }, /* pbn_b2_4_460800 */
-- { SPCI_FL_BASE2, 8, 460800 }, /* pbn_b2_8_460800 */
-- { SPCI_FL_BASE2, 16, 460800 }, /* pbn_b2_16_460800 */
-- { SPCI_FL_BASE2, 4, 921600 }, /* pbn_b2_4_921600 */
-- { SPCI_FL_BASE2, 8, 921600 }, /* pbn_b2_8_921600 */
--
-- { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* pbn_b2_bt_1_115200 */
-- { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* pbn_b2_bt_2_115200 */
-- { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 115200 }, /* pbn_b2_bt_4_115200 */
-- { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600 }, /* pbn_b2_bt_2_921600 */
--
-- { SPCI_FL_BASE2, 2, 921600, /* IOMEM */ /* pbn_panacom */
-- 0x400, 7, pci_plx9050_fn },
-- { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600, /* pbn_panacom2 */
-- 0x400, 7, pci_plx9050_fn },
-- { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 921600, /* pbn_panacom4 */
-- 0x400, 7, pci_plx9050_fn },
-- { SPCI_FL_BASE2, 4, 921600, /* pbn_plx_romulus */
-- 0x20, 2, pci_plx9050_fn, 0x03 },
-- /* This board uses the size of PCI Base region 0 to
-- * signal now many ports are available */
-- { SPCI_FL_BASE0 | SPCI_FL_REGION_SZ_CAP, 32, 115200 }, /* pbn_oxsemi */
-- { SPCI_FL_BASE_TABLE, 1, 921600, /* pbn_timedia */
-- 0, 0, pci_timedia_fn },
-- /* EKF addition for i960 Boards form EKF with serial port */
-- { SPCI_FL_BASE0, 32, 921600, /* max 256 ports */ /* pbn_intel_i960 */
-- 8<<2, 2, pci_inteli960ni_fn, 0x10000},
-- { SPCI_FL_BASE0 | SPCI_FL_IRQRESOURCE, /* pbn_sgi_ioc3 */
-- 1, 458333, 0, 0, 0, 0x20178 },
-- { SPCI_FL_BASE0, 5, 115200, 8, 0, pci_hp_diva, 0}, /* pbn_hp_diva */
--#ifdef CONFIG_DDB5074
-- /*
-- * NEC Vrc-5074 (Nile 4) builtin UART.
-- * Conditionally compiled in since this is a motherboard device.
-- */
-- { SPCI_FL_BASE0, 1, 520833, /* pbn_nec_nile4 */
-- 64, 3, NULL, 0x300 },
--#endif
--#if 0 /* PCI_DEVICE_ID_DCI_PCCOM8 ? */ /* pbn_dci_pccom8 */
-- { SPCI_FL_BASE3, 8, 115200, 8 },
--#endif
-- { SPCI_FL_BASE0, 1, 115200, /* pbn_xircom_combo */
-- 0, 0, pci_xircom_fn },
--
-- { SPCI_FL_BASE2, 1, 460800, /* pbn_siig10x_0 */
-- 0, 0, pci_siig10x_fn },
-- { SPCI_FL_BASE2, 1, 921600, /* pbn_siig10x_1 */
-- 0, 0, pci_siig10x_fn },
-- { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600, /* pbn_siig10x_2 */
-- 0, 0, pci_siig10x_fn },
-- { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 921600, /* pbn_siig10x_4 */
-- 0, 0, pci_siig10x_fn },
-- { SPCI_FL_BASE0, 1, 921600, /* pbn_siix20x_0 */
-- 0, 0, pci_siig20x_fn },
-- { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 921600, /* pbn_siix20x_2 */
-- 0, 0, pci_siig20x_fn },
-- { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 4, 921600, /* pbn_siix20x_4 */
-- 0, 0, pci_siig20x_fn },
--
-- { SPCI_FL_BASE0, 4, 921600, /* IOMEM */ /* pbn_computone_4 */
-- 0x40, 2, NULL, 0x200 },
-- { SPCI_FL_BASE0, 6, 921600, /* IOMEM */ /* pbn_computone_6 */
-- 0x40, 2, NULL, 0x200 },
-- { SPCI_FL_BASE0, 8, 921600, /* IOMEM */ /* pbn_computone_8 */
-- 0x40, 2, NULL, 0x200 },
--};
--
--/*
-- * Given a complete unknown PCI device, try to use some heuristics to
-- * guess what the configuration might be, based on the pitiful PCI
-- * serial specs. Returns 0 on success, 1 on failure.
-+ * The serial driver boot-time initialization code!
- */
--static int __devinit serial_pci_guess_board(struct pci_dev *dev,
-- struct pci_board *board)
-+static int __init rs_init(void)
- {
-- int num_iomem = 0, num_port = 0, first_port = -1;
- int i;
-+ struct serial_state * state;
-
-- /*
-- * If it is not a communications device or the programming
-- * interface is greater than 6, give up.
-- *
-- * (Should we try to make guesses for multiport serial devices
-- * later?)
-- */
-- if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) &&
-- ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) ||
-- (dev->class & 0xff) > 6)
-- return 1;
--
-- for (i=0; i < 6; i++) {
-- if (IS_PCI_REGION_IOPORT(dev, i)) {
-- num_port++;
-- if (first_port == -1)
-- first_port = i;
-- }
-- if (IS_PCI_REGION_IOMEM(dev, i))
-- num_iomem++;
-- }
-+ printk("pxa & ti16c754b serial driver\n");
-+ set_GPIO_IRQ_edge(7, GPIO_RISING_EDGE);
-+ set_GPIO_IRQ_edge(24, GPIO_RISING_EDGE);
-+ set_GPIO_IRQ_edge(25, GPIO_RISING_EDGE);
-+ set_GPIO_IRQ_edge(26, GPIO_RISING_EDGE);
-
-- /*
-- * If there is exactly one port of 8 bytes, use it.
-- */
-- if (num_port == 1 && pci_resource_len(dev, first_port) == 8) {
-- board->flags = first_port;
-- return 0;
-+ if (!request_mem_region(RAMSES_UARTA_PHYS, 16*4, "Ramses UART A"))
-+ printk(KERN_ERR "unable to reserve region\n");
-+ else {
-+ ramses_uarta = ioremap_nocache(RAMSES_UARTA_PHYS, 16*4);
-+ if (!ramses_uarta)
-+ printk(KERN_ERR "unable to map region\n");
-+ else {
-+ //printk("ramses_uarta cookie is: %08x\n", (unsigned int) ramses_uarta);
-+ rs_table[3].iomem_base = ramses_uarta;
- }
--
-- /*
-- * If there is 1 or 0 iomem regions, and exactly one port, use
-- * it.
-- */
-- if (num_iomem <= 1 && num_port == 1) {
-- board->flags = first_port;
-- return 0;
- }
-- return 1;
--}
--
--static int __devinit serial_init_one(struct pci_dev *dev,
-- const struct pci_device_id *ent)
--{
-- struct pci_board *board, tmp;
-- int rc;
--
-- board = &pci_boards[ent->driver_data];
--
-- rc = pci_enable_device(dev);
-- if (rc) return rc;
--
-- if (ent->driver_data == pbn_default &&
-- serial_pci_guess_board(dev, board))
-- return -ENODEV;
-- else if (serial_pci_guess_board(dev, &tmp) == 0) {
-- printk(KERN_INFO "Redundant entry in serial pci_table. "
-- "Please send the output of\n"
-- "lspci -vv, this message (%04x,%04x,%04x,%04x)\n"
-- "and the manufacturer and name of "
-- "serial board or modem board\n"
-- "to serial-pci-info@lists.sourceforge.net.\n",
-- dev->vendor, dev->device,
-- pci_get_subvendor(dev), pci_get_subdevice(dev));
-- }
--
-- start_pci_pnp_board(dev, board);
--
-- return 0;
--}
--
--static void __devexit serial_remove_one(struct pci_dev *dev)
--{
-- int i;
--
-- /*
-- * Iterate through all of the ports finding those that belong
-- * to this PCI device.
-- */
-- for(i = 0; i < NR_PORTS; i++) {
-- if (rs_table[i].dev != dev)
-- continue;
-- unregister_serial(i);
-- rs_table[i].dev = 0;
-+ if (!request_mem_region(RAMSES_UARTB_PHYS, 16*4, "Ramses UART B"))
-+ printk(KERN_ERR "unable to reserve region\n");
-+ else {
-+ ramses_uartb = ioremap_nocache(RAMSES_UARTB_PHYS, 16*4);
-+ if (!ramses_uartb)
-+ printk(KERN_ERR "unable to map region\n");
-+ else {
-+ //printk("ramses_uartb cookie is: %08x\n", (unsigned int) ramses_uartb);
-+ rs_table[4].iomem_base = ramses_uartb;
- }
-- /*
-- * Now execute any board-specific shutdown procedure
-- */
-- for (i=0; i < NR_PCI_BOARDS; i++) {
-- struct pci_board_inst *brd = &serial_pci_board[i];
--
-- if (serial_pci_board[i].dev != dev)
-- continue;
-- if (brd->board.init_fn)
-- (brd->board.init_fn)(brd->dev, &brd->board, 0);
-- if (DEACTIVATE_FUNC(brd->dev))
-- (DEACTIVATE_FUNC(brd->dev))(brd->dev);
-- serial_pci_board[i].dev = 0;
- }
--}
--
--
--static struct pci_device_id serial_pci_tbl[] __devinitdata = {
-- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
-- PCI_SUBVENDOR_ID_CONNECT_TECH,
-- PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
-- pbn_b1_8_1382400 },
-- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
-- PCI_SUBVENDOR_ID_CONNECT_TECH,
-- PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
-- pbn_b1_4_1382400 },
-- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
-- PCI_SUBVENDOR_ID_CONNECT_TECH,
-- PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0,
-- pbn_b1_2_1382400 },
-- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-- PCI_SUBVENDOR_ID_CONNECT_TECH,
-- PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
-- pbn_b1_8_1382400 },
-- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-- PCI_SUBVENDOR_ID_CONNECT_TECH,
-- PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
-- pbn_b1_4_1382400 },
-- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-- PCI_SUBVENDOR_ID_CONNECT_TECH,
-- PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0,
-- pbn_b1_2_1382400 },
-- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-- PCI_SUBVENDOR_ID_CONNECT_TECH,
-- PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485, 0, 0,
-- pbn_b1_8_921600 },
-- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-- PCI_SUBVENDOR_ID_CONNECT_TECH,
-- PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4, 0, 0,
-- pbn_b1_8_921600 },
-- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-- PCI_SUBVENDOR_ID_CONNECT_TECH,
-- PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485, 0, 0,
-- pbn_b1_4_921600 },
-- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-- PCI_SUBVENDOR_ID_CONNECT_TECH,
-- PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2, 0, 0,
-- pbn_b1_4_921600 },
-- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-- PCI_SUBVENDOR_ID_CONNECT_TECH,
-- PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485, 0, 0,
-- pbn_b1_2_921600 },
-- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-- PCI_SUBVENDOR_ID_CONNECT_TECH,
-- PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6, 0, 0,
-- pbn_b1_8_921600 },
-- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-- PCI_SUBVENDOR_ID_CONNECT_TECH,
-- PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1, 0, 0,
-- pbn_b1_8_921600 },
-- { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-- PCI_SUBVENDOR_ID_CONNECT_TECH,
-- PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1, 0, 0,
-- pbn_b1_4_921600 },
--
-- { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b2_bt_1_115200 },
-- { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM2,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b2_bt_2_115200 },
-- { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM422,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b2_bt_4_115200 },
-- { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM232,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b2_bt_2_115200 },
-- { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM4,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b2_bt_4_115200 },
-- { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM8,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b2_8_115200 },
--
-- { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_GTEK_SERIAL2,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b2_bt_2_115200 },
-- { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM200,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b2_bt_2_921600 },
-- /* VScom SPCOM800, from sl@s.pl */
-- { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM800,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b2_8_921600 },
-- { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_1077,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b2_4_921600 },
-- { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-- PCI_SUBVENDOR_ID_KEYSPAN,
-- PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0,
-- pbn_panacom },
-- { PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_QUADMODEM,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_panacom4 },
-- { PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_DUALMODEM,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_panacom2 },
-- { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-- PCI_SUBVENDOR_ID_CHASE_PCIFAST,
-- PCI_SUBDEVICE_ID_CHASE_PCIFAST4, 0, 0,
-- pbn_b2_4_460800 },
-- { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-- PCI_SUBVENDOR_ID_CHASE_PCIFAST,
-- PCI_SUBDEVICE_ID_CHASE_PCIFAST8, 0, 0,
-- pbn_b2_8_460800 },
-- { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-- PCI_SUBVENDOR_ID_CHASE_PCIFAST,
-- PCI_SUBDEVICE_ID_CHASE_PCIFAST16, 0, 0,
-- pbn_b2_16_460800 },
-- { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-- PCI_SUBVENDOR_ID_CHASE_PCIFAST,
-- PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC, 0, 0,
-- pbn_b2_16_460800 },
-- { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-- PCI_SUBVENDOR_ID_CHASE_PCIRAS,
-- PCI_SUBDEVICE_ID_CHASE_PCIRAS4, 0, 0,
-- pbn_b2_4_460800 },
-- { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-- PCI_SUBVENDOR_ID_CHASE_PCIRAS,
-- PCI_SUBDEVICE_ID_CHASE_PCIRAS8, 0, 0,
-- pbn_b2_8_460800 },
-- /* Megawolf Romulus PCI Serial Card, from Mike Hudson */
-- /* (Exoray@isys.ca) */
-- { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS,
-- 0x10b5, 0x106a, 0, 0,
-- pbn_plx_romulus },
-- { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b1_4_115200 },
-- { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b1_2_115200 },
-- { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b1_8_115200 },
-- { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b1_8_115200 },
-- { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954,
-- PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4, 0, 0,
-- pbn_b0_4_921600 },
-- { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b0_4_115200 },
-- { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b0_bt_2_921600 },
--
-- /* Digitan DS560-558, from jimd@esoft.com */
-- { PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_ATT_VENUS_MODEM,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b1_1_115200 },
--
-- /* 3Com US Robotics 56k Voice Internal PCI model 5610 */
-- { PCI_VENDOR_ID_USR, 0x1008,
-- PCI_ANY_ID, PCI_ANY_ID, },
--
-- /* Titan Electronic cards */
-- { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b0_1_921600 },
-- { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b0_2_921600 },
-- { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b0_4_921600 },
-- { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800B,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b0_4_921600 },
-- { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100L,
-- PCI_ANY_ID, PCI_ANY_ID,
-- SPCI_FL_BASE1, 1, 921600 },
-- { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200L,
-- PCI_ANY_ID, PCI_ANY_ID,
-- SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 },
-- /* The 400L and 800L have a custom hack in get_pci_port */
-- { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400L,
-- PCI_ANY_ID, PCI_ANY_ID,
-- SPCI_FL_BASE_TABLE, 4, 921600 },
-- { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800L,
-- PCI_ANY_ID, PCI_ANY_ID,
-- SPCI_FL_BASE_TABLE, 8, 921600 },
--
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig10x_0 },
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_650,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig10x_0 },
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_850,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig10x_0 },
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_550,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig10x_2 },
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_650,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig10x_2 },
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_850,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig10x_2 },
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_550,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig10x_4 },
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_650,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig10x_4 },
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_850,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig10x_4 },
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_550,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig20x_0 },
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_650,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig20x_0 },
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_850,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig20x_0 },
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_550,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig20x_2 },
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_650,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig20x_2 },
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_850,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig20x_2 },
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_550,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig20x_4 },
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_650,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig20x_4 },
-- { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_850,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_siig20x_4 },
--
-- /* Computone devices submitted by Doug McNash dmcnash@computone.com */
-- { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
-- PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG4,
-- 0, 0, pbn_computone_4 },
-- { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
-- PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG8,
-- 0, 0, pbn_computone_8 },
-- { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
-- PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG6,
-- 0, 0, pbn_computone_6 },
--
-- { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI95N,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_oxsemi },
-- { PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889,
-- PCI_VENDOR_ID_TIMEDIA, PCI_ANY_ID, 0, 0, pbn_timedia },
--
-- { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DSERIAL,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b0_bt_2_115200 },
-- { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_A,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b0_bt_2_115200 },
-- { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b0_bt_2_115200 },
-- { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_PLUS,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b0_bt_2_460800 },
-- { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_A,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b0_bt_2_460800 },
-- { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_B,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b0_bt_2_460800 },
-- { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_SSERIAL,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b0_bt_1_115200 },
-- { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_650,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b0_bt_1_460800 },
--
-- /* RAStel 2 port modem, gerg@moreton.com.au */
-- { PCI_VENDOR_ID_MORETON, PCI_DEVICE_ID_RASTEL_2PORT,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b2_bt_2_115200 },
--
-- /* EKF addition for i960 Boards form EKF with serial port */
-- { PCI_VENDOR_ID_INTEL, 0x1960,
-- 0xE4BF, PCI_ANY_ID, 0, 0,
-- pbn_intel_i960 },
--
-- /* Xircom Cardbus/Ethernet combos */
-- { PCI_VENDOR_ID_XIRCOM, PCI_DEVICE_ID_XIRCOM_X3201_MDM,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_xircom_combo },
--
-- /*
-- * Untested PCI modems, sent in from various folks...
-- */
--
-- /* Elsa Model 56K PCI Modem, from Andreas Rath <arh@01019freenet.de> */
-- { PCI_VENDOR_ID_ROCKWELL, 0x1004,
-- 0x1048, 0x1500, 0, 0,
-- pbn_b1_1_115200 },
--
-- { PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
-- 0xFF00, 0, 0, 0,
-- pbn_sgi_ioc3 },
--
-- /* HP Diva card */
-- { PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_SAS,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_hp_diva },
-- { PCI_VENDOR_ID_HP, 0x1290,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_b2_1_115200 },
--
--#ifdef CONFIG_DDB5074
-- /*
-- * NEC Vrc-5074 (Nile 4) builtin UART.
-- * Conditionally compiled in since this is a motherboard device.
-- */
-- { PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_NILE4,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_nec_nile4 },
--#endif
--
--#if 0 /* PCI_DEVICE_ID_DCI_PCCOM8 ? */
-- { PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM8,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-- pbn_dci_pccom8 },
--#endif
--
-- { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
-- PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xffff00, },
-- { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
-- PCI_CLASS_COMMUNICATION_MODEM << 8, 0xffff00, },
-- { 0, }
--};
--
--MODULE_DEVICE_TABLE(pci, serial_pci_tbl);
--
--static struct pci_driver serial_pci_driver = {
-- name: "serial",
-- probe: serial_init_one,
-- remove: __devexit_p(serial_remove_one),
-- id_table: serial_pci_tbl,
--};
--
--
--/*
-- * Query PCI space for known serial boards
-- * If found, add them to the PCI device space in rs_table[]
-- *
-- * Accept a maximum of eight boards
-- *
-- */
--static void __devinit probe_serial_pci(void)
--{
--#ifdef SERIAL_DEBUG_PCI
-- printk(KERN_DEBUG "Entered probe_serial_pci()\n");
--#endif
--
-- /* Register call PCI serial devices. Null out
-- * the driver name upon failure, as a signal
-- * not to attempt to unregister the driver later
-- */
-- if (pci_module_init (&serial_pci_driver) != 0)
-- serial_pci_driver.name = "";
--
--#ifdef SERIAL_DEBUG_PCI
-- printk(KERN_DEBUG "Leaving probe_serial_pci() (probe finished)\n");
--#endif
-- return;
--}
--
--#endif /* ENABLE_SERIAL_PCI */
--
--#ifdef ENABLE_SERIAL_PNP
--
--struct pnp_board {
-- unsigned short vendor;
-- unsigned short device;
--};
--
--static struct pnp_board pnp_devices[] __devinitdata = {
-- /* Archtek America Corp. */
-- /* Archtek SmartLink Modem 3334BT Plug & Play */
-- { ISAPNP_VENDOR('A', 'A', 'C'), ISAPNP_DEVICE(0x000F) },
-- /* Anchor Datacomm BV */
-- /* SXPro 144 External Data Fax Modem Plug & Play */
-- { ISAPNP_VENDOR('A', 'D', 'C'), ISAPNP_DEVICE(0x0001) },
-- /* SXPro 288 External Data Fax Modem Plug & Play */
-- { ISAPNP_VENDOR('A', 'D', 'C'), ISAPNP_DEVICE(0x0002) },
-- /* Rockwell 56K ACF II Fax+Data+Voice Modem */
-- { ISAPNP_VENDOR('A', 'K', 'Y'), ISAPNP_DEVICE(0x1021) },
-- /* AZT3005 PnP SOUND DEVICE */
-- { ISAPNP_VENDOR('A', 'Z', 'T'), ISAPNP_DEVICE(0x4001) },
-- /* Best Data Products Inc. Smart One 336F PnP Modem */
-- { ISAPNP_VENDOR('B', 'D', 'P'), ISAPNP_DEVICE(0x3336) },
-- /* Boca Research */
-- /* Boca Complete Ofc Communicator 14.4 Data-FAX */
-- { ISAPNP_VENDOR('B', 'R', 'I'), ISAPNP_DEVICE(0x0A49) },
-- /* Boca Research 33,600 ACF Modem */
-- { ISAPNP_VENDOR('B', 'R', 'I'), ISAPNP_DEVICE(0x1400) },
-- /* Boca 33.6 Kbps Internal FD34FSVD */
-- { ISAPNP_VENDOR('B', 'R', 'I'), ISAPNP_DEVICE(0x3400) },
-- /* Boca 33.6 Kbps Internal FD34FSVD */
-- { ISAPNP_VENDOR('B', 'R', 'I'), ISAPNP_DEVICE(0x0A49) },
-- /* Best Data Products Inc. Smart One 336F PnP Modem */
-- { ISAPNP_VENDOR('B', 'D', 'P'), ISAPNP_DEVICE(0x3336) },
-- /* Computer Peripherals Inc */
-- /* EuroViVa CommCenter-33.6 SP PnP */
-- { ISAPNP_VENDOR('C', 'P', 'I'), ISAPNP_DEVICE(0x4050) },
-- /* Creative Labs */
-- /* Creative Labs Phone Blaster 28.8 DSVD PnP Voice */
-- { ISAPNP_VENDOR('C', 'T', 'L'), ISAPNP_DEVICE(0x3001) },
-- /* Creative Labs Modem Blaster 28.8 DSVD PnP Voice */
-- { ISAPNP_VENDOR('C', 'T', 'L'), ISAPNP_DEVICE(0x3011) },
-- /* Creative */
-- /* Creative Modem Blaster Flash56 DI5601-1 */
-- { ISAPNP_VENDOR('D', 'M', 'B'), ISAPNP_DEVICE(0x1032) },
-- /* Creative Modem Blaster V.90 DI5660 */
-- { ISAPNP_VENDOR('D', 'M', 'B'), ISAPNP_DEVICE(0x2001) },
-- /* FUJITSU */
-- /* Fujitsu 33600 PnP-I2 R Plug & Play */
-- { ISAPNP_VENDOR('F', 'U', 'J'), ISAPNP_DEVICE(0x0202) },
-- /* Fujitsu FMV-FX431 Plug & Play */
-- { ISAPNP_VENDOR('F', 'U', 'J'), ISAPNP_DEVICE(0x0205) },
-- /* Fujitsu 33600 PnP-I4 R Plug & Play */
-- { ISAPNP_VENDOR('F', 'U', 'J'), ISAPNP_DEVICE(0x0206) },
-- /* Fujitsu Fax Voice 33600 PNP-I5 R Plug & Play */
-- { ISAPNP_VENDOR('F', 'U', 'J'), ISAPNP_DEVICE(0x0209) },
-- /* Archtek America Corp. */
-- /* Archtek SmartLink Modem 3334BT Plug & Play */
-- { ISAPNP_VENDOR('G', 'V', 'C'), ISAPNP_DEVICE(0x000F) },
-- /* Hayes */
-- /* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */
-- { ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x0001) },
-- /* Hayes Optima 336 V.34 + FAX + Voice PnP */
-- { ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x000C) },
-- /* Hayes Optima 336B V.34 + FAX + Voice PnP */
-- { ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x000D) },
-- /* Hayes Accura 56K Ext Fax Modem PnP */
-- { ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x5670) },
-- /* Hayes Accura 56K Ext Fax Modem PnP */
-- { ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x5674) },
-- /* Hayes Accura 56K Fax Modem PnP */
-- { ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0x5675) },
-- /* Hayes 288, V.34 + FAX */
-- { ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0xF000) },
-- /* Hayes Optima 288 V.34 + FAX + Voice, Plug & Play */
-- { ISAPNP_VENDOR('H', 'A', 'Y'), ISAPNP_DEVICE(0xF001) },
-- /* IBM */
-- /* IBM Thinkpad 701 Internal Modem Voice */
-- { ISAPNP_VENDOR('I', 'B', 'M'), ISAPNP_DEVICE(0x0033) },
-- /* Intertex */
-- /* Intertex 28k8 33k6 Voice EXT PnP */
-- { ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xC801) },
-- /* Intertex 33k6 56k Voice EXT PnP */
-- { ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xC901) },
-- /* Intertex 28k8 33k6 Voice SP EXT PnP */
-- { ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xD801) },
-- /* Intertex 33k6 56k Voice SP EXT PnP */
-- { ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xD901) },
-- /* Intertex 28k8 33k6 Voice SP INT PnP */
-- { ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xF401) },
-- /* Intertex 28k8 33k6 Voice SP EXT PnP */
-- { ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xF801) },
-- /* Intertex 33k6 56k Voice SP EXT PnP */
-- { ISAPNP_VENDOR('I', 'X', 'D'), ISAPNP_DEVICE(0xF901) },
-- /* Kortex International */
-- /* KORTEX 28800 Externe PnP */
-- { ISAPNP_VENDOR('K', 'O', 'R'), ISAPNP_DEVICE(0x4522) },
-- /* KXPro 33.6 Vocal ASVD PnP */
-- { ISAPNP_VENDOR('K', 'O', 'R'), ISAPNP_DEVICE(0xF661) },
-- /* Lasat */
-- /* LASAT Internet 33600 PnP */
-- { ISAPNP_VENDOR('L', 'A', 'S'), ISAPNP_DEVICE(0x4040) },
-- /* Lasat Safire 560 PnP */
-- { ISAPNP_VENDOR('L', 'A', 'S'), ISAPNP_DEVICE(0x4540) },
-- /* Lasat Safire 336 PnP */
-- { ISAPNP_VENDOR('L', 'A', 'S'), ISAPNP_DEVICE(0x5440) },
-- /* Microcom, Inc. */
-- /* Microcom TravelPorte FAST V.34 Plug & Play */
-- { ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x281) },
-- /* Microcom DeskPorte V.34 FAST or FAST+ Plug & Play */
-- { ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0336) },
-- /* Microcom DeskPorte FAST EP 28.8 Plug & Play */
-- { ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0339) },
-- /* Microcom DeskPorte 28.8P Plug & Play */
-- { ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0342) },
-- /* Microcom DeskPorte FAST ES 28.8 Plug & Play */
-- { ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0500) },
-- /* Microcom DeskPorte FAST ES 28.8 Plug & Play */
-- { ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0501) },
-- /* Microcom DeskPorte 28.8S Internal Plug & Play */
-- { ISAPNP_VENDOR('M', 'N', 'P'), ISAPNP_DEVICE(0x0502) },
-- /* Motorola */
-- /* Motorola BitSURFR Plug & Play */
-- { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1105) },
-- /* Motorola TA210 Plug & Play */
-- { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1111) },
-- /* Motorola HMTA 200 (ISDN) Plug & Play */
-- { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1114) },
-- /* Motorola BitSURFR Plug & Play */
-- { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1115) },
-- /* Motorola Lifestyle 28.8 Internal */
-- { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1190) },
-- /* Motorola V.3400 Plug & Play */
-- { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1501) },
-- /* Motorola Lifestyle 28.8 V.34 Plug & Play */
-- { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1502) },
-- /* Motorola Power 28.8 V.34 Plug & Play */
-- { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1505) },
-- /* Motorola ModemSURFR External 28.8 Plug & Play */
-- { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1509) },
-- /* Motorola Premier 33.6 Desktop Plug & Play */
-- { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x150A) },
-- /* Motorola VoiceSURFR 56K External PnP */
-- { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x150F) },
-- /* Motorola ModemSURFR 56K External PnP */
-- { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1510) },
-- /* Motorola ModemSURFR 56K Internal PnP */
-- { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1550) },
-- /* Motorola ModemSURFR Internal 28.8 Plug & Play */
-- { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1560) },
-- /* Motorola Premier 33.6 Internal Plug & Play */
-- { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x1580) },
-- /* Motorola OnlineSURFR 28.8 Internal Plug & Play */
-- { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x15B0) },
-- /* Motorola VoiceSURFR 56K Internal PnP */
-- { ISAPNP_VENDOR('M', 'O', 'T'), ISAPNP_DEVICE(0x15F0) },
-- /* Com 1 */
-- /* Deskline K56 Phone System PnP */
-- { ISAPNP_VENDOR('M', 'V', 'X'), ISAPNP_DEVICE(0x00A1) },
-- /* PC Rider K56 Phone System PnP */
-- { ISAPNP_VENDOR('M', 'V', 'X'), ISAPNP_DEVICE(0x00F2) },
-- /* Pace 56 Voice Internal Plug & Play Modem */
-- { ISAPNP_VENDOR('P', 'M', 'C'), ISAPNP_DEVICE(0x2430) },
-- /* Generic */
-- /* Generic standard PC COM port */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0500) },
-- /* Generic 16550A-compatible COM port */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x0501) },
-- /* Compaq 14400 Modem */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC000) },
-- /* Compaq 2400/9600 Modem */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC001) },
-- /* Dial-Up Networking Serial Cable between 2 PCs */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC031) },
-- /* Dial-Up Networking Parallel Cable between 2 PCs */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC032) },
-- /* Standard 9600 bps Modem */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC100) },
-- /* Standard 14400 bps Modem */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC101) },
-- /* Standard 28800 bps Modem*/
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC102) },
-- /* Standard Modem*/
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC103) },
-- /* Standard 9600 bps Modem*/
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC104) },
-- /* Standard 14400 bps Modem*/
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC105) },
-- /* Standard 28800 bps Modem*/
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC106) },
-- /* Standard Modem */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC107) },
-- /* Standard 9600 bps Modem */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC108) },
-- /* Standard 14400 bps Modem */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC109) },
-- /* Standard 28800 bps Modem */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10A) },
-- /* Standard Modem */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10B) },
-- /* Standard 9600 bps Modem */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10C) },
-- /* Standard 14400 bps Modem */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10D) },
-- /* Standard 28800 bps Modem */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10E) },
-- /* Standard Modem */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0xC10F) },
-- /* Standard PCMCIA Card Modem */
-- { ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_DEVICE(0x2000) },
-- /* Rockwell */
-- /* Modular Technology */
-- /* Rockwell 33.6 DPF Internal PnP */
-- /* Modular Technology 33.6 Internal PnP */
-- { ISAPNP_VENDOR('R', 'O', 'K'), ISAPNP_DEVICE(0x0030) },
-- /* Kortex International */
-- /* KORTEX 14400 Externe PnP */
-- { ISAPNP_VENDOR('R', 'O', 'K'), ISAPNP_DEVICE(0x0100) },
-- /* Viking Components, Inc */
-- /* Viking 28.8 INTERNAL Fax+Data+Voice PnP */
-- { ISAPNP_VENDOR('R', 'O', 'K'), ISAPNP_DEVICE(0x4920) },
-- /* Rockwell */
-- /* British Telecom */
-- /* Modular Technology */
-- /* Rockwell 33.6 DPF External PnP */
-- /* BT Prologue 33.6 External PnP */
-- /* Modular Technology 33.6 External PnP */
-- { ISAPNP_VENDOR('R', 'S', 'S'), ISAPNP_DEVICE(0x00A0) },
-- /* Viking 56K FAX INT */
-- { ISAPNP_VENDOR('R', 'S', 'S'), ISAPNP_DEVICE(0x0262) },
-- /* SupraExpress 28.8 Data/Fax PnP modem */
-- { ISAPNP_VENDOR('S', 'U', 'P'), ISAPNP_DEVICE(0x1310) },
-- /* SupraExpress 33.6 Data/Fax PnP modem */
-- { ISAPNP_VENDOR('S', 'U', 'P'), ISAPNP_DEVICE(0x1421) },
-- /* SupraExpress 33.6 Data/Fax PnP modem */
-- { ISAPNP_VENDOR('S', 'U', 'P'), ISAPNP_DEVICE(0x1590) },
-- /* SupraExpress 33.6 Data/Fax PnP modem */
-- { ISAPNP_VENDOR('S', 'U', 'P'), ISAPNP_DEVICE(0x1760) },
-- /* Phoebe Micro */
-- /* Phoebe Micro 33.6 Data Fax 1433VQH Plug & Play */
-- { ISAPNP_VENDOR('T', 'E', 'X'), ISAPNP_DEVICE(0x0011) },
-- /* Archtek America Corp. */
-- /* Archtek SmartLink Modem 3334BT Plug & Play */
-- { ISAPNP_VENDOR('U', 'A', 'C'), ISAPNP_DEVICE(0x000F) },
-- /* 3Com Corp. */
-- /* Gateway Telepath IIvi 33.6 */
-- { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x0000) },
-- /* Sportster Vi 14.4 PnP FAX Voicemail */
-- { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x0004) },
-- /* U.S. Robotics 33.6K Voice INT PnP */
-- { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x0006) },
-- /* U.S. Robotics 33.6K Voice EXT PnP */
-- { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x0007) },
-- /* U.S. Robotics 33.6K Voice INT PnP */
-- { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x2002) },
-- /* U.S. Robotics 56K Voice INT PnP */
-- { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x2070) },
-- /* U.S. Robotics 56K Voice EXT PnP */
-- { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x2080) },
-- /* U.S. Robotics 56K FAX INT */
-- { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x3031) },
-- /* U.S. Robotics 56K Voice INT PnP */
-- { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x3070) },
-- /* U.S. Robotics 56K Voice EXT PnP */
-- { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x3080) },
-- /* U.S. Robotics 56K Voice INT PnP */
-- { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x3090) },
-- /* U.S. Robotics 56K Message */
-- { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x9100) },
-- /* U.S. Robotics 56K FAX EXT PnP*/
-- { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x9160) },
-- /* U.S. Robotics 56K FAX INT PnP*/
-- { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x9170) },
-- /* U.S. Robotics 56K Voice EXT PnP*/
-- { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x9180) },
-- /* U.S. Robotics 56K Voice INT PnP*/
-- { ISAPNP_VENDOR('U', 'S', 'R'), ISAPNP_DEVICE(0x9190) },
-- { 0, }
--};
--
--static inline void avoid_irq_share(struct pci_dev *dev)
--{
-- int i, map = 0x1FF8;
-- struct serial_state *state = rs_table;
-- struct isapnp_irq *irq;
-- struct isapnp_resources *res = dev->sysdata;
--
-- for (i = 0; i < NR_PORTS; i++) {
-- if (state->type != PORT_UNKNOWN)
-- clear_bit(state->irq, &map);
-- state++;
-- }
--
-- for ( ; res; res = res->alt)
-- for(irq = res->irq; irq; irq = irq->next)
-- irq->map = map;
--}
--
--static char *modem_names[] __devinitdata = {
-- "MODEM", "Modem", "modem", "FAX", "Fax", "fax",
-- "56K", "56k", "K56", "33.6", "28.8", "14.4",
-- "33,600", "28,800", "14,400", "33.600", "28.800", "14.400",
-- "33600", "28800", "14400", "V.90", "V.34", "V.32", 0
--};
--
--static int __devinit check_name(char *name)
--{
-- char **tmp = modem_names;
--
-- while (*tmp) {
-- if (strstr(name, *tmp))
-- return 1;
-- tmp++;
-+ if (!request_mem_region(RAMSES_UARTC_PHYS, 16*4, "Ramses UART C"))
-+ printk(KERN_ERR "unable to reserve region\n");
-+ else {
-+ ramses_uartc = ioremap_nocache(RAMSES_UARTC_PHYS, 16*4);
-+ if (!ramses_uartc)
-+ printk(KERN_ERR "unable to map region\n");
-+ else {
-+ //printk("ramses_uartc cookie is: %08x\n", (unsigned int) ramses_uartc);
-+ rs_table[5].iomem_base = ramses_uartc;
- }
-- return 0;
--}
--
--static inline int check_compatible_id(struct pci_dev *dev)
--{
-- int i;
-- for (i = 0; i < DEVICE_COUNT_COMPATIBLE; i++)
-- if ((dev->vendor_compatible[i] ==
-- ISAPNP_VENDOR('P', 'N', 'P')) &&
-- (swab16(dev->device_compatible[i]) >= 0xc000) &&
-- (swab16(dev->device_compatible[i]) <= 0xdfff))
-- return 0;
-- return 1;
--}
--
--/*
-- * Given a complete unknown ISA PnP device, try to use some heuristics to
-- * detect modems. Currently use such heuristic set:
-- * - dev->name or dev->bus->name must contain "modem" substring;
-- * - device must have only one IO region (8 byte long) with base adress
-- * 0x2e8, 0x3e8, 0x2f8 or 0x3f8.
-- *
-- * Such detection looks very ugly, but can detect at least some of numerous
-- * ISA PnP modems, alternatively we must hardcode all modems in pnp_devices[]
-- * table.
-- */
--static int _INLINE_ serial_pnp_guess_board(struct pci_dev *dev,
-- struct pci_board *board)
--{
-- struct isapnp_resources *res = (struct isapnp_resources *)dev->sysdata;
-- struct isapnp_resources *resa;
--
-- if (!(check_name(dev->name) || check_name(dev->bus->name)) &&
-- !(check_compatible_id(dev)))
-- return 1;
--
-- if (!res || res->next)
-- return 1;
--
-- for (resa = res->alt; resa; resa = resa->alt) {
-- struct isapnp_port *port;
-- for (port = res->port; port; port = port->next)
-- if ((port->size == 8) &&
-- ((port->min == 0x2f8) ||
-- (port->min == 0x3f8) ||
-- (port->min == 0x2e8) ||
-- (port->min == 0x3e8)))
-- return 0;
- }
--
-- return 1;
--}
--
--static void __devinit probe_serial_pnp(void)
--{
-- struct pci_dev *dev = NULL;
-- struct pnp_board *pnp_board;
-- struct pci_board board;
--
--#ifdef SERIAL_DEBUG_PNP
-- printk("Entered probe_serial_pnp()\n");
--#endif
-- if (!isapnp_present()) {
--#ifdef SERIAL_DEBUG_PNP
-- printk("Leaving probe_serial_pnp() (no isapnp)\n");
--#endif
-- return;
-+ if (!request_mem_region(RAMSES_UARTD_PHYS, 16*4, "Ramses UART D"))
-+ printk(KERN_ERR "unable to reserve region\n");
-+ else {
-+ ramses_uartd = ioremap_nocache(RAMSES_UARTD_PHYS, 16*4);
-+ if (!ramses_uartd)
-+ printk(KERN_ERR "unable to map region\n");
-+ else {
-+ //printk("ramses_uartd cookie is: %08x\n", (unsigned int) ramses_uartd);
-+ rs_table[6].iomem_base = ramses_uartd;
- }
--
-- isapnp_for_each_dev(dev) {
-- if (dev->active)
-- continue;
--
-- memset(&board, 0, sizeof(board));
-- board.flags = SPCI_FL_BASE0 | SPCI_FL_PNPDEFAULT;
-- board.num_ports = 1;
-- board.base_baud = 115200;
--
-- for (pnp_board = pnp_devices; pnp_board->vendor; pnp_board++)
-- if ((dev->vendor == pnp_board->vendor) &&
-- (dev->device == pnp_board->device))
-- break;
--
-- if (pnp_board->vendor) {
-- /* Special case that's more efficient to hardcode */
-- if ((pnp_board->vendor == ISAPNP_VENDOR('A', 'K', 'Y') &&
-- pnp_board->device == ISAPNP_DEVICE(0x1021)))
-- board.flags |= SPCI_FL_NO_SHIRQ;
-- } else {
-- if (serial_pnp_guess_board(dev, &board))
-- continue;
- }
--
-- if (board.flags & SPCI_FL_NO_SHIRQ)
-- avoid_irq_share(dev);
-- start_pci_pnp_board(dev, &board);
-- }
--
--#ifdef SERIAL_DEBUG_PNP
-- printk("Leaving probe_serial_pnp() (probe finished)\n");
--#endif
-- return;
--}
--
--#endif /* ENABLE_SERIAL_PNP */
--
--/*
-- * The serial driver boot-time initialization code!
-- */
--static int __init rs_init(void)
--{
-- int i;
-- struct serial_state * state;
--
- init_bh(SERIAL_BH, do_serial_bh);
- init_timer(&serial_timer);
- serial_timer.function = rs_timer;
-@@ -5463,10 +2723,6 @@
- for (i = 0; i < NR_IRQS; i++) {
- IRQ_ports[i] = 0;
- IRQ_timeout[i] = 0;
--#ifdef CONFIG_SERIAL_MULTIPORT
-- memset(&rs_multiport[i], 0,
-- sizeof(struct rs_multiport_struct));
--#endif
- }
- #ifdef CONFIG_SERIAL_CONSOLE
- /*
-@@ -5480,29 +2736,25 @@
- rs_table[i].irq = 0;
- }
- #endif
-- show_serial_version();
--
- /* Initialize the tty_driver structure */
-
- memset(&serial_driver, 0, sizeof(struct tty_driver));
- serial_driver.magic = TTY_DRIVER_MAGIC;
--#if (LINUX_VERSION_CODE > 0x20100)
- serial_driver.driver_name = "serial";
--#endif
--#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
-+#if defined(CONFIG_DEVFS_FS)
- serial_driver.name = "tts/%d";
- #else
- serial_driver.name = "ttyS";
- #endif
- serial_driver.major = TTY_MAJOR;
-- serial_driver.minor_start = 64 + SERIAL_DEV_OFFSET;
-- serial_driver.name_base = SERIAL_DEV_OFFSET;
-+ serial_driver.minor_start = 64;
-+ serial_driver.name_base = 0;
- serial_driver.num = NR_PORTS;
- serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
- serial_driver.subtype = SERIAL_TYPE_NORMAL;
- serial_driver.init_termios = tty_std_termios;
- serial_driver.init_termios.c_cflag =
-- B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-+ B115200 | CS8 | CREAD | HUPCL | CLOCAL;
- serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
- serial_driver.refcount = &serial_refcount;
- serial_driver.table = serial_table;
-@@ -5524,31 +2776,25 @@
- serial_driver.stop = rs_stop;
- serial_driver.start = rs_start;
- serial_driver.hangup = rs_hangup;
--#if (LINUX_VERSION_CODE >= 131394) /* Linux 2.1.66 */
- serial_driver.break_ctl = rs_break;
--#endif
--#if (LINUX_VERSION_CODE >= 131343)
- serial_driver.send_xchar = rs_send_xchar;
- serial_driver.wait_until_sent = rs_wait_until_sent;
- serial_driver.read_proc = rs_read_proc;
--#endif
-
- /*
- * The callout device is just like normal device except for
- * major number and the subtype code.
- */
- callout_driver = serial_driver;
--#if (LINUX_VERSION_CODE > 0x2032D && defined(CONFIG_DEVFS_FS))
-+#if defined(CONFIG_DEVFS_FS)
- callout_driver.name = "cua/%d";
- #else
- callout_driver.name = "cua";
- #endif
- callout_driver.major = TTYAUX_MAJOR;
- callout_driver.subtype = SERIAL_TYPE_CALLOUT;
--#if (LINUX_VERSION_CODE >= 131343)
- callout_driver.read_proc = 0;
- callout_driver.proc_entry = 0;
--#endif
-
- if (tty_register_driver(&serial_driver))
- panic("Couldn't register serial driver\n");
-@@ -5569,53 +2815,23 @@
- state->icount.frame = state->icount.parity = 0;
- state->icount.overrun = state->icount.brk = 0;
- state->irq = irq_cannonicalize(state->irq);
-- if (state->hub6)
-- state->io_type = SERIAL_IO_HUB6;
- if (state->port && check_region(state->port,8)) {
- state->type = PORT_UNKNOWN;
- continue;
- }
--#ifdef CONFIG_MCA
-- if ((state->flags & ASYNC_BOOT_ONLYMCA) && !MCA_bus)
-- continue;
--#endif
-- if (state->flags & ASYNC_BOOT_AUTOCONF) {
-- state->type = PORT_UNKNOWN;
-- autoconfig(state);
-- }
- }
- for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
- if (state->type == PORT_UNKNOWN)
- continue;
-- if ( (state->flags & ASYNC_BOOT_AUTOCONF)
-- && (state->flags & ASYNC_AUTO_IRQ)
-- && (state->port != 0 || state->iomem_base != 0))
-- state->irq = detect_uart_irq(state);
-- if (state->io_type == SERIAL_IO_MEM) {
-- printk(KERN_INFO"ttyS%02d%s at 0x%p (irq = %d) is a %s\n",
-- state->line + SERIAL_DEV_OFFSET,
-- (state->flags & ASYNC_FOURPORT) ? " FourPort" : "",
-- state->iomem_base, state->irq,
-- uart_config[state->type].name);
-- }
-- else {
-- printk(KERN_INFO "ttyS%02d%s at 0x%04lx (irq = %d) is a %s\n",
-- state->line + SERIAL_DEV_OFFSET,
-- (state->flags & ASYNC_FOURPORT) ? " FourPort" : "",
-- state->port, state->irq,
-+ printk(KERN_INFO"tts/%d at irq %d is a %s\n",
-+ state->line,
-+ state->irq,
- uart_config[state->type].name);
-- }
- tty_register_devfs(&serial_driver, 0,
- serial_driver.minor_start + state->line);
- tty_register_devfs(&callout_driver, 0,
- callout_driver.minor_start + state->line);
- }
--#ifdef ENABLE_SERIAL_PCI
-- probe_serial_pci();
--#endif
--#ifdef ENABLE_SERIAL_PNP
-- probe_serial_pnp();
--#endif
- return 0;
- }
-
-@@ -5627,6 +2843,8 @@
- {
- int i = req->line;
-
-+ printk("%s\n", __FUNCTION__);
-+
- if (i >= NR_IRQS)
- return(-ENOENT);
- rs_table[i].magic = 0;
-@@ -5639,7 +2857,6 @@
- rs_table[i].flags = req->flags;
- rs_table[i].close_delay = req->close_delay;
- rs_table[i].io_type = req->io_type;
-- rs_table[i].hub6 = req->hub6;
- rs_table[i].iomem_base = req->iomem_base;
- rs_table[i].iomem_reg_shift = req->iomem_reg_shift;
- rs_table[i].type = req->type;
-@@ -5726,7 +2943,6 @@
- info->iomem_base = req->iomem_base;
- info->iomem_reg_shift = req->iomem_reg_shift;
- }
-- autoconfig(state);
- if (state->type == PORT_UNKNOWN) {
- restore_flags(flags);
- printk("register_serial(): autoconfig failed\n");
-@@ -5734,11 +2950,8 @@
- }
- restore_flags(flags);
-
-- if ((state->flags & ASYNC_AUTO_IRQ) && CONFIGURED_SERIAL_PORT(state))
-- state->irq = detect_uart_irq(state);
--
- printk(KERN_INFO "ttyS%02d at %s 0x%04lx (irq = %d) is a %s\n",
-- state->line + SERIAL_DEV_OFFSET,
-+ state->line,
- state->iomem_base ? "iomem" : "port",
- state->iomem_base ? (unsigned long)state->iomem_base :
- state->port, state->irq, uart_config[state->type].name);
-@@ -5746,7 +2959,7 @@
- serial_driver.minor_start + state->line);
- tty_register_devfs(&callout_driver, 0,
- callout_driver.minor_start + state->line);
-- return state->line + SERIAL_DEV_OFFSET;
-+ return state->line;
- }
-
- /**
-@@ -5785,7 +2998,6 @@
- int i;
- struct async_struct *info;
-
-- /* printk("Unloading %s: version %s\n", serial_name, serial_version); */
- del_timer_sync(&serial_timer);
- save_flags(flags); cli();
- remove_bh(SERIAL_BH);
-@@ -5803,41 +3015,31 @@
- kfree(info);
- }
- if ((rs_table[i].type != PORT_UNKNOWN) && rs_table[i].port) {
--#ifdef CONFIG_SERIAL_RSA
-- if (rs_table[i].type == PORT_RSA)
-- release_region(rs_table[i].port +
-- UART_RSA_BASE, 16);
-- else
--#endif
- release_region(rs_table[i].port, 8);
- }
--#if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP)
-- if (rs_table[i].iomem_base)
-- iounmap(rs_table[i].iomem_base);
--#endif
-- }
--#if defined(ENABLE_SERIAL_PCI) || defined(ENABLE_SERIAL_PNP)
-- for (i=0; i < NR_PCI_BOARDS; i++) {
-- struct pci_board_inst *brd = &serial_pci_board[i];
--
-- if (serial_pci_board[i].dev == 0)
-- continue;
-- if (brd->board.init_fn)
-- (brd->board.init_fn)(brd->dev, &brd->board, 0);
-- if (DEACTIVATE_FUNC(brd->dev))
-- (DEACTIVATE_FUNC(brd->dev))(brd->dev);
- }
--#endif
- if (tmp_buf) {
- unsigned long pg = (unsigned long) tmp_buf;
- tmp_buf = NULL;
- free_page(pg);
- }
-
--#ifdef ENABLE_SERIAL_PCI
-- if (serial_pci_driver.name[0])
-- pci_unregister_driver (&serial_pci_driver);
--#endif
-+ if (ramses_uarta) {
-+ iounmap(ramses_uarta);
-+ release_mem_region(RAMSES_UARTA_PHYS, 16*4);
-+ }
-+ if (ramses_uartb) {
-+ iounmap(ramses_uartb);
-+ release_mem_region(RAMSES_UARTB_PHYS, 16*4);
-+ }
-+ if (ramses_uartc) {
-+ iounmap(ramses_uartc);
-+ release_mem_region(RAMSES_UARTC_PHYS, 16*4);
-+ }
-+ if (ramses_uartd) {
-+ iounmap(ramses_uartd);
-+ release_mem_region(RAMSES_UARTD_PHYS, 16*4);
-+ }
- }
-
- module_init(rs_init);
-@@ -5946,7 +3148,7 @@
- static struct async_struct *info;
- struct serial_state *state;
- unsigned cval;
-- int baud = 9600;
-+ int baud = 115200;
- int bits = 8;
- int parity = 'n';
- int doflow = 0;
-@@ -5954,6 +3156,8 @@
- int quot = 0;
- char *s;
-
-+ printk("%s\n", __FUNCTION__);
-+
- if (options) {
- baud = simple_strtoul(options, NULL, 10);
- s = options;
-@@ -6028,19 +3232,12 @@
- info->state = state;
- info->port = state->port;
- info->flags = state->flags;
--#ifdef CONFIG_HUB6
-- info->hub6 = state->hub6;
--#endif
- info->io_type = state->io_type;
- info->iomem_base = state->iomem_base;
- info->iomem_reg_shift = state->iomem_reg_shift;
- quot = state->baud_base / baud;
- cval = cflag & (CSIZE | CSTOPB);
--#if defined(__powerpc__) || defined(__alpha__)
-- cval >>= 8;
--#else /* !__powerpc__ && !__alpha__ */
- cval >>= 4;
--#endif /* !__powerpc__ && !__alpha__ */
- if (cflag & PARENB)
- cval |= UART_LCR_PARITY;
- if (!(cflag & PARODD))
-@@ -6082,9 +3279,14 @@
- */
- void __init serial_console_init(void)
- {
-+ printk("%s\n", __FUNCTION__);
-+
- register_console(&sercons);
- }
- #endif
-+
-+EXPORT_SYMBOL(register_serial);
-+EXPORT_SYMBOL(unregister_serial);
-
- /*
- Local variables:
---- /dev/null
-+++ linux-2.4.21/drivers/char/sysctl.c
-@@ -0,0 +1,948 @@
-+/*
-+ * /proc/sys-board - Interface to the 16 bit latch and other
-+ * ramses-related hardware settings
-+ *
-+ * (C) 2002,2003 by M&N Logistik-Lösungen Online GmbH
-+ * written by H.Schurig
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/sysctl.h>
-+#include <linux/crc32.h>
-+#include <linux/delay.h>
-+#include <linux/pm.h>
-+
-+#include <asm/io.h>
-+#include <asm/arch/ramses.h>
-+#include <asm/uaccess.h>
-+
-+#include "../drivers/misc/ucb1x00.h"
-+
-+//#define DEBUG
-+//define CPLD_LED 1
-+//define POTI 1
-+
-+/*
-+ * This is the number for the "board" entry in /proc/sys:
-+ */
-+#define RAMSES_SYSCTL 1312
-+
-+/*
-+ * These are the numbers for the entries in /etc/sys/board
-+ */
-+enum {
-+ CTL_NAME=991,
-+ CTL_CPLD_VERSION,
-+ CTL_BOOTLOADER_CRC,
-+ CTL_LINUX_CRC,
-+ CTL_LED_BLUE,
-+ CTL_LED_ORANGE,
-+ CTL_UART,
-+ CTL_MMC,
-+ CTL_POWEROFF,
-+ CTL_GSM_POWER,
-+ CTL_GSM_RESET,
-+ CTL_SCANNER_POWER,
-+ CTL_SCANNER_WAKE,
-+ CTL_SCANNER_TRIG,
-+ CTL_SCANNER_BEAM,
-+ CTL_KEY_SCAN,
-+ CTL_KEY_SUSPEND,
-+ CTL_KEY_OFF,
-+ CTL_USBBUS_POWER,
-+ CTL_USBCHIP_POWER,
-+#ifdef CPLD_LED
-+ CTL_LED_CPLD,
-+ CTL_LED_CPLD_RED,
-+#endif
-+ CTL_LCD_VCC,
-+ CTL_LCD_DISPOFF,
-+ CTL_LCD_BLIGHT,
-+#ifdef DEBUG
-+ CTL_LCD_PWM0,
-+ CTL_LCD_PWM1,
-+#endif
-+ CTL_LCD_BRIGHTNESS,
-+ CTL_LCD_CONTRAST,
-+ CTL_LCD_FBTURN,
-+ CTL_LCD_TYPE,
-+ CTL_CONTROL_SHADOW,
-+ CTL_COREVOLT,
-+#ifdef POTI
-+ CTL_LCD_POTI_NINC,
-+ CTL_LCD_POTI_NCS,
-+ CTL_LCD_POTI_UP,
-+#endif
-+#ifdef CONFIG_MCP_UCB1400_TS
-+ CTL_ADC0,
-+ CTL_ADC1,
-+ CTL_ADC2,
-+ CTL_ADC3,
-+#else
-+#error NO UCB
-+#endif
-+ CTL_CHG_STS,
-+ CTL_WALL_IN,
-+ CTL_BATT_TMP,
-+ CTL_BATT_LMD,
-+ CTL_BATT_VSB,
-+ CTL_BATT_RCAC,
-+ CTL_BATT_CACT,
-+ CTL_BATT_SAE,
-+ CTL_BATT_DCR,
-+};
-+
-+static const char ramses_board_name[] = "ramses";
-+static int dummy_int = 0;
-+static char dummy_str[80];
-+
-+
-+
-+/******************************************************************/
-+/* ADC communication */
-+/******************************************************************/
-+
-+
-+#ifdef CONFIG_MCP_UCB1400_TS
-+static int adc_get(int channel)
-+{
-+ int val;
-+ struct ucb1x00 *ucb = ucb1x00_get();
-+
-+ ucb1x00_adc_enable(ucb);
-+ val = ucb1x00_adc_read(ucb, channel, 0);
-+ ucb1x00_adc_disable(ucb);
-+
-+ return val;
-+}
-+#endif
-+
-+
-+
-+static int
-+ramses_sysctl_handler(ctl_table * ctl, int write, struct file *filp,
-+ void *buffer, size_t * lenp)
-+{
-+ int *valp = ctl->data;
-+ int val;
-+ int ret;
-+ unsigned crc;
-+ void *flash;
-+
-+#ifdef DEBUG
-+ printk("ramses_control_shadow: %04x\n", ramses_control_shadow);
-+#endif
-+
-+ // Update parameters from the real registers
-+ switch (ctl->ctl_name) {
-+ case CTL_CPLD_VERSION:
-+ sprintf(dummy_str,"20%02ld-%02ld-%02ld.%ld\n",
-+ RAMSES_CPLD_YEAR & 0xff,
-+ RAMSES_CPLD_MONTH & 0xff,
-+ RAMSES_CPLD_DAY & 0xff,
-+ RAMSES_CPLD_REV & 0xff);
-+ return proc_dostring(ctl,write,filp,buffer,lenp);
-+
-+ case CTL_BOOTLOADER_CRC:
-+ flash = ioremap_nocache(RAMSES_FLASH_PHYS, 0x40000);
-+ crc = ether_crc_le(0x40000, flash);
-+ iounmap(flash);
-+ sprintf(dummy_str,"%08x", crc);
-+ return proc_dostring(ctl,write,filp,buffer,lenp);
-+
-+ case CTL_LINUX_CRC:
-+ flash = ioremap_nocache(RAMSES_FLASH_PHYS+0x40000, 3*0x40000);
-+ crc = ether_crc_le(3*0x40000, flash);
-+ iounmap(flash);
-+ sprintf(dummy_str,"%08x", crc);
-+ return proc_dostring(ctl,write,filp,buffer,lenp);
-+
-+ case CTL_LED_BLUE:
-+ *valp = (ramses_control_shadow & RAMSES_CONTROL_LED_BLUE_) == 0;
-+ break;
-+ case CTL_LED_ORANGE:
-+ *valp = (ramses_control_shadow & RAMSES_CONTROL_LED_ORANGE_) == 0;
-+ break;
-+ case CTL_UART:
-+ *valp = (ramses_control_shadow & RAMSES_CONTROL_UART_PWR) != 0;
-+ break;
-+ case CTL_MMC:
-+ *valp = (ramses_control_shadow & RAMSES_CONTROL_MMC_PWR) != 0;
-+ break;
-+ case CTL_POWEROFF:
-+ *valp = 0;
-+ break;
-+ case CTL_GSM_POWER:
-+ *valp = (ramses_control_shadow & RAMSES_CONTROL_GSM_PWR) != 0;
-+ break;
-+ case CTL_GSM_RESET:
-+ *valp = (ramses_control_shadow & RAMSES_CONTROL_GSM_RESET) != 0;
-+ break;
-+
-+ case CTL_SCANNER_POWER:
-+ *valp = (ramses_control_shadow & RAMSES_CONTROL_SCANNER_PWR) != 0;
-+ break;
-+ case CTL_SCANNER_WAKE:
-+ *valp = (ramses_control_shadow & RAMSES_CONTROL_SCANNER_WAKE_) == 0;
-+ break;
-+ case CTL_SCANNER_TRIG:
-+ *valp = (ramses_control_shadow & RAMSES_CONTROL_SCANNER_TRIG_) == 0;
-+ break;
-+ case CTL_SCANNER_BEAM:
-+ *valp = ramses_flags & RAMSES_FLAGS_SCANNER_BEAM;
-+ break;
-+
-+ case CTL_KEY_SCAN:
-+ *valp = (ramses_flags & RAMSES_FLAGS_KEY_SCAN) != 0;
-+ break;
-+ case CTL_KEY_SUSPEND:
-+ *valp = (ramses_flags & RAMSES_FLAGS_KEY_SUSPEND) != 0;
-+ break;
-+ case CTL_KEY_OFF:
-+ *valp = (ramses_flags & RAMSES_FLAGS_KEY_OFF) != 0;
-+ break;
-+
-+ case CTL_USBBUS_POWER:
-+ *valp = (ramses_control_shadow & RAMSES_CONTROL_USB) != 0;
-+ break;
-+ case CTL_USBCHIP_POWER:
-+ *valp = (RAMSES_CPLD_PERIPH_PWR & USB_HOST_PWR_EN) != 0;
-+ break;
-+#ifdef CPLD_LED
-+ case CTL_LED_CPLD:
-+ *valp = (RAMSES_CPLD_LED_CONTROL & CPLD_LED1) == 0;
-+ break;
-+ case CTL_LED_CPLD_RED:
-+ *valp = (RAMSES_CPLD_LED_CONTROL & CPLD_LED2) == 0;
-+ break;
-+#endif
-+ case CTL_LCD_BLIGHT:
-+ *valp = (ramses_control_shadow & RAMSES_CONTROL_LCD_BLIGHT) != 0;
-+ break;
-+ case CTL_LCD_VCC:
-+ *valp = (RAMSES_CPLD_LCD & RAMSES_LCD_VCC) != 0;
-+ break;
-+ case CTL_LCD_DISPOFF:
-+ *valp = (RAMSES_CPLD_LCD & RAMSES_LCD_DISPOFF) != 0;
-+ break;
-+#ifdef DEBUG
-+ case CTL_LCD_PWM0:
-+ *valp = PWM_PWDUTY0;
-+ break;
-+ case CTL_LCD_PWM1:
-+#ifdef OLDCODE
-+ *valp = ramses_lcd_pwm1_shadow;
-+#else
-+ *valp = PWM_PWDUTY1;
-+#endif
-+ break;
-+#endif
-+ case CTL_LCD_BRIGHTNESS:
-+ *valp = ramses_lcd_get_brightness();
-+ break;
-+ case CTL_LCD_CONTRAST:
-+ *valp = ramses_lcd_get_contrast();
-+ break;
-+ case CTL_LCD_FBTURN:
-+ *valp = (ramses_flags & RAMSES_FLAGS_LCD_FBTURN) != 0;
-+ break;
-+ case CTL_LCD_TYPE:
-+ *valp = ramses_lcd_type;
-+ break;
-+
-+ case CTL_CONTROL_SHADOW:
-+ sprintf(dummy_str,"%04x", ramses_control_shadow);
-+ return proc_dostring(ctl,write,filp,buffer,lenp);
-+
-+ case CTL_COREVOLT:
-+ *valp = ramses_corevolt_shadow;
-+ break;
-+
-+#ifdef POTI
-+ case CTL_LCD_POTI_NINC:
-+ *valp = (RAMSES_CPLD_LCD & RAMSES_LCD_PINC) != 0;
-+ break;
-+ case CTL_LCD_POTI_NCS:
-+ *valp = (RAMSES_CPLD_LCD & RAMSES_LCD_PCS) != 0;
-+ break;
-+ case CTL_LCD_POTI_UP:
-+ *valp = (RAMSES_CPLD_LCD & RAMSES_LCD_PUP) != 0;
-+ break;
-+#endif
-+
-+#ifdef CONFIG_MCP_UCB1400_TS
-+ case CTL_ADC0:
-+ *valp = adc_get(UCB_ADC_INP_AD0);
-+ break;
-+ case CTL_ADC1:
-+ *valp = adc_get(UCB_ADC_INP_AD1);
-+ break;
-+ case CTL_ADC2:
-+ *valp = adc_get(UCB_ADC_INP_AD2);
-+ break;
-+ case CTL_ADC3:
-+ *valp = adc_get(UCB_ADC_INP_AD3);
-+ break;
-+#endif
-+
-+ case CTL_CHG_STS:
-+ *valp = (RAMSES_CPLD_MISC_STATUS & RAMSES_CHG_STS) == 0;
-+ break;
-+ case CTL_WALL_IN:
-+ *valp = (RAMSES_CPLD_MISC_STATUS & RAMSES_WALL_IN) != 0;
-+ break;
-+
-+ case CTL_BATT_TMP:
-+ *valp = ramses_hdq_get_reg(HDQ_TMP) >> 4;
-+ break;
-+ case CTL_BATT_LMD:
-+ *valp = ramses_hdq_get_reg(HDQ_LMD);
-+ break;
-+ case CTL_BATT_VSB:
-+ *valp = ramses_hdq_get_reg(HDQ_VSB);
-+ break;
-+ case CTL_BATT_RCAC:
-+ *valp = ramses_hdq_get_reg(HDQ_RCAC) & 0x7f;
-+ break;
-+ case CTL_BATT_CACT:
-+ *valp = ramses_hdq_get_reg(HDQ_CACT);
-+ break;
-+ case CTL_BATT_SAE:
-+ *valp = ramses_hdq_get_reg(HDQ_SAEH) << 8 | ramses_hdq_get_reg(HDQ_SAEL);
-+ break;
-+ case CTL_BATT_DCR:
-+ *valp = ramses_hdq_get_reg(HDQ_DCR);
-+ break;
-+
-+ default:
-+ // Just ignore unsupported parameters
-+ break;
-+ }
-+
-+ // Save old state
-+ val = *valp;
-+
-+ // Perform the generic integer operation
-+ if ((ret = proc_dointvec(ctl, write, filp, buffer, lenp)) != 0)
-+ return (ret);
-+
-+ // Write changes out to the registers
-+ if (write && *valp != val) {
-+
-+ val = *valp;
-+ switch (ctl->ctl_name) {
-+
-+ case CTL_LED_BLUE:
-+ if (val)
-+ RAMSES_LED_BLUE_ON()
-+ else
-+ RAMSES_LED_BLUE_OFF();
-+ break;
-+
-+ case CTL_LED_ORANGE:
-+ if (val)
-+ RAMSES_LED_ORANGE_ON()
-+ else
-+ RAMSES_LED_ORANGE_OFF();
-+ break;
-+
-+ case CTL_UART:
-+ if (val)
-+ RAMSES_UART_ON()
-+ else
-+ RAMSES_UART_OFF();
-+ break;
-+
-+ case CTL_MMC:
-+ if (val)
-+ RAMSES_MMC_ON()
-+ else
-+ RAMSES_MMC_OFF();
-+ break;
-+
-+ case CTL_POWEROFF:
-+ if (val)
-+ pm_power_off();
-+ break;
-+
-+ case CTL_GSM_POWER:
-+ if (val)
-+ RAMSES_GSM_ON()
-+ else
-+ RAMSES_GSM_OFF();
-+ break;
-+
-+ case CTL_GSM_RESET:
-+ if (val)
-+ RAMSES_GSM_RESET_ON()
-+ else
-+ RAMSES_GSM_RESET_OFF();
-+ break;
-+
-+ case CTL_SCANNER_POWER:
-+ if (val)
-+ RAMSES_SCANNER_ON()
-+ else
-+ RAMSES_SCANNER_OFF();
-+ break;
-+
-+ case CTL_SCANNER_WAKE:
-+ if (val)
-+ RAMSES_SCANNER_WAKE_ON()
-+ else
-+ RAMSES_SCANNER_WAKE_OFF();
-+ break;
-+
-+ case CTL_SCANNER_TRIG:
-+ if (val)
-+ RAMSES_SCANNER_TRIG_ON()
-+ else
-+ RAMSES_SCANNER_TRIG_OFF();
-+ break;
-+
-+ case CTL_SCANNER_BEAM:
-+ if (val)
-+ ramses_flags |= RAMSES_FLAGS_SCANNER_BEAM;
-+ else
-+ ramses_flags &= ~RAMSES_FLAGS_SCANNER_BEAM;
-+ break;
-+
-+ case CTL_KEY_SCAN:
-+ if (val)
-+ ramses_flags |= RAMSES_FLAGS_KEY_SCAN;
-+ else
-+ ramses_flags &= ~RAMSES_FLAGS_KEY_SCAN;
-+ break;
-+
-+ case CTL_KEY_SUSPEND:
-+ if (val)
-+ ramses_flags |= RAMSES_FLAGS_KEY_SUSPEND;
-+ else
-+ ramses_flags &= ~RAMSES_FLAGS_KEY_SUSPEND;
-+ break;
-+
-+ case CTL_KEY_OFF:
-+ if (val)
-+ ramses_flags |= RAMSES_FLAGS_KEY_OFF;
-+ else
-+ ramses_flags &= ~RAMSES_FLAGS_KEY_OFF;
-+ break;
-+
-+ case CTL_USBBUS_POWER:
-+ if (val)
-+ RAMSES_USB_BUS_ON()
-+ else
-+ RAMSES_USB_BUS_OFF();
-+ break;
-+
-+ case CTL_USBCHIP_POWER:
-+ if (val)
-+ RAMSES_CPLD_PERIPH_PWR |= USB_HOST_PWR_EN;
-+ else
-+ RAMSES_CPLD_PERIPH_PWR &= ~USB_HOST_PWR_EN;
-+ break;
-+
-+#ifdef CPLD_LED
-+ case CTL_LED_CPLD:
-+ if (val)
-+ RAMSES_CPLD_LED_CONTROL &= ~CPLD_LED1;
-+ else
-+ RAMSES_CPLD_LED_CONTROL |= CPLD_LED1;
-+ break;
-+
-+ case CTL_LED_CPLD_RED:
-+ if (val)
-+ RAMSES_CPLD_LED_CONTROL &= ~CPLD_LED2;
-+ else
-+ RAMSES_CPLD_LED_CONTROL |= CPLD_LED2;
-+ break;
-+#endif
-+
-+ case CTL_LCD_BLIGHT:
-+ if (val)
-+ ramses_lcd_backlight_on();
-+ else
-+ ramses_lcd_backlight_off();
-+ break;
-+
-+ case CTL_LCD_VCC:
-+ if (val)
-+ RAMSES_CPLD_LCD |= RAMSES_LCD_VCC;
-+ else
-+ RAMSES_CPLD_LCD &= ~RAMSES_LCD_VCC;
-+ break;
-+
-+ case CTL_LCD_DISPOFF:
-+ if (val)
-+ RAMSES_CPLD_LCD |= RAMSES_LCD_DISPOFF;
-+ else
-+ RAMSES_CPLD_LCD &= ~RAMSES_LCD_DISPOFF;
-+ break;
-+
-+#ifdef DEBUG
-+ case CTL_LCD_PWM0:
-+ PWM_PWDUTY0 = val;
-+ break;
-+
-+ case CTL_LCD_PWM1:
-+#ifdef OLDCODE
-+ ramses_lcd_set_pwm1(val);
-+#else
-+ PWM_PWDUTY1 = val;
-+#endif
-+ break;
-+#endif
-+
-+ case CTL_LCD_BRIGHTNESS:
-+ ramses_lcd_set_brightness(val);
-+ break;
-+
-+ case CTL_LCD_CONTRAST:
-+ ramses_lcd_set_contrast(val);
-+ break;
-+
-+ case CTL_LCD_FBTURN:
-+ if (val)
-+ ramses_flags |= RAMSES_FLAGS_LCD_FBTURN;
-+ else
-+ ramses_flags &= ~RAMSES_FLAGS_LCD_FBTURN;
-+ break;
-+
-+ case CTL_COREVOLT:
-+ ramses_set_corevolt(val);
-+ break;
-+
-+#ifdef POTI
-+ case CTL_LCD_POTI_NCS:
-+ if (val)
-+ RAMSES_CPLD_LCD |= RAMSES_LCD_PCS;
-+ else
-+ RAMSES_CPLD_LCD &= ~RAMSES_LCD_PCS;
-+ break;
-+ case CTL_LCD_POTI_NINC:
-+ if (val)
-+ RAMSES_CPLD_LCD |= RAMSES_LCD_PINC;
-+ else
-+ RAMSES_CPLD_LCD &= ~RAMSES_LCD_PINC;
-+ break;
-+ case CTL_LCD_POTI_UP:
-+ if (val)
-+ RAMSES_CPLD_LCD |= RAMSES_LCD_PUP;
-+ else
-+ RAMSES_CPLD_LCD &= ~RAMSES_LCD_PUP;
-+ break;
-+#endif
-+
-+ default:
-+ // Just ignore unsupported parameters
-+ break;
-+ }
-+ }
-+
-+#ifdef DEBUG
-+ printk("ramses_control_shadow new: %04x\n", ramses_control_shadow);
-+#endif
-+ return ret;
-+}
-+
-+
-+
-+static ctl_table ramses_table[] = {
-+ {
-+ procname: "sys_name",
-+ ctl_name: CTL_NAME,
-+ data: &ramses_board_name,
-+ maxlen: sizeof(ramses_board_name),
-+ proc_handler: &proc_dostring,
-+ mode: 0444, // read-only
-+ }, {
-+ procname: "sys_cpldver",
-+ ctl_name: CTL_CPLD_VERSION,
-+ data: &dummy_str,
-+ maxlen: sizeof(dummy_str),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444, // read-only
-+ }, {
-+ procname: "sys_bootcrc",
-+ ctl_name: CTL_BOOTLOADER_CRC,
-+ data: &dummy_str,
-+ maxlen: sizeof(dummy_str),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444, // read-only
-+ }, {
-+ procname: "sys_linuxcrc",
-+ ctl_name: CTL_LINUX_CRC,
-+ data: &dummy_str,
-+ maxlen: sizeof(dummy_str),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444, // read-only
-+ }, {
-+ procname: "led_blue",
-+ ctl_name: CTL_LED_BLUE,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "led_orange",
-+ ctl_name: CTL_LED_ORANGE,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "pwr_uart",
-+ ctl_name: CTL_UART,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "pwr_mmc",
-+ ctl_name: CTL_MMC,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "pwr_off",
-+ ctl_name: CTL_POWEROFF,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "gsm_power",
-+ ctl_name: CTL_GSM_POWER,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "gsm_reset",
-+ ctl_name: CTL_GSM_RESET,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "scanner_power",
-+ ctl_name: CTL_SCANNER_POWER,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "scanner_wake",
-+ ctl_name: CTL_SCANNER_WAKE,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "scanner_trig",
-+ ctl_name: CTL_SCANNER_TRIG,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "scanner_beam",
-+ ctl_name: CTL_SCANNER_BEAM,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "key_scan",
-+ ctl_name: CTL_KEY_SCAN,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "key_suspend",
-+ ctl_name: CTL_KEY_SUSPEND,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "key_off",
-+ ctl_name: CTL_KEY_OFF,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "usb_bus_power",
-+ ctl_name: CTL_USBBUS_POWER,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "usb_chip_power",
-+ ctl_name: CTL_USBCHIP_POWER,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ },
-+#if LED_CPLD
-+ {
-+ procname: "led_cpld",
-+ ctl_name: CTL_LED_CPLD,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "led_cpld_red",
-+ ctl_name: CTL_LED_CPLD_RED,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ },
-+#endif
-+ {
-+ procname: "lcd_backlight",
-+ ctl_name: CTL_LCD_BLIGHT,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "lcd_vcc",
-+ ctl_name: CTL_LCD_VCC,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "lcd_dispoff",
-+ ctl_name: CTL_LCD_DISPOFF,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "lcd_brightness",
-+ ctl_name: CTL_LCD_BRIGHTNESS,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "lcd_contrast",
-+ ctl_name: CTL_LCD_CONTRAST,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "lcd_fbturn",
-+ ctl_name: CTL_LCD_FBTURN,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "lcd_type",
-+ ctl_name: CTL_LCD_TYPE,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444,
-+ },
-+#ifdef POTI
-+ {
-+ procname: "lcd_poti_ncs",
-+ ctl_name: CTL_LCD_POTI_NCS,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "lcd_poti_ninc",
-+ ctl_name: CTL_LCD_POTI_NINC,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "lcd_poti_up",
-+ ctl_name: CTL_LCD_POTI_UP,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ },
-+#endif
-+#ifdef DEBUG
-+ {
-+ procname: "lcd_pwm0",
-+ ctl_name: CTL_LCD_PWM0,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ }, {
-+ procname: "lcd_pwm1",
-+ ctl_name: CTL_LCD_PWM1,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ },
-+#endif
-+ {
-+ procname: "sys_shadowreg",
-+ ctl_name: CTL_CONTROL_SHADOW,
-+ data: &dummy_str,
-+ maxlen: sizeof(dummy_str),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444,
-+ },
-+ {
-+ procname: "pwr_corevolt",
-+ ctl_name: CTL_COREVOLT,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0664,
-+ },
-+#ifdef CONFIG_MCP_UCB1400_TS
-+ {
-+ procname: "adc0_vcc",
-+ ctl_name: CTL_ADC0,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444,
-+ }, {
-+ procname: "adc1_ntc",
-+ ctl_name: CTL_ADC1,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444,
-+ }, {
-+ procname: "adc2_goldcap",
-+ ctl_name: CTL_ADC2,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444,
-+ }, {
-+ procname: "adc3_batt",
-+ ctl_name: CTL_ADC3,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444,
-+ },
-+#else
-+#error No UCB
-+#endif
-+ {
-+ procname: "pwr_wall_in",
-+ ctl_name: CTL_WALL_IN,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444,
-+ }, {
-+ procname: "batt_charge",
-+ ctl_name: CTL_CHG_STS,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444,
-+ }, {
-+ procname: "batt_temp",
-+ ctl_name: CTL_BATT_TMP,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444,
-+ }, {
-+ procname: "batt_lmd",
-+ ctl_name: CTL_BATT_LMD,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444,
-+ }, {
-+ procname: "batt_vsb",
-+ ctl_name: CTL_BATT_VSB,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444,
-+ }, {
-+ procname: "batt_rcac",
-+ ctl_name: CTL_BATT_RCAC,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444,
-+ }, {
-+ procname: "batt_cact",
-+ ctl_name: CTL_BATT_CACT,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444,
-+ }, {
-+ procname: "batt_sae",
-+ ctl_name: CTL_BATT_SAE,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444,
-+ }, {
-+ procname: "batt_dcr",
-+ ctl_name: CTL_BATT_DCR,
-+ data: &dummy_int,
-+ maxlen: sizeof(int),
-+ proc_handler: &ramses_sysctl_handler,
-+ mode: 0444,
-+ },
-+
-+ {0}
-+ };
-+
-+static ctl_table ramses_root_table[] = {
-+ {RAMSES_SYSCTL, "board", NULL, 0, 0555, ramses_table},
-+ {0}
-+ };
-+
-+
-+static struct ctl_table_header *ramses_table_header;
-+
-+
-+static int __init ramses_sysctl_init(void)
-+{
-+ ramses_table_header = register_sysctl_table(ramses_root_table, 0);
-+ if (!ramses_table_header)
-+ return -ENOMEM;
-+ return 0;
-+}
-+
-+static void __exit ramses_sysctl_exit(void)
-+{
-+ unregister_sysctl_table(ramses_table_header);
-+}
-+
-+
-+module_init(ramses_sysctl_init);
-+module_exit(ramses_sysctl_exit);
-+
-+MODULE_AUTHOR("Holger Schurig <h.schurig@mn-logistik.de>");
-+MODULE_DESCRIPTION("Implements /proc/sys/board");
-+MODULE_LICENSE("GPL");
---- linux-2.4.21/drivers/char/vt.c~linux-vtcomparison
-+++ linux-2.4.21/drivers/char/vt.c
-@@ -163,7 +163,9 @@
-
- if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
- return -EFAULT;
-- if (i >= NR_KEYS || s >= MAX_NR_KEYMAPS)
-+ if (i >= NR_KEYS)
-+ return -EINVAL;
-+ if (s >= MAX_NR_KEYMAPS)
- return -EINVAL;
-
- switch (cmd) {
---- linux-2.4.21/drivers/input/Config.in~keyb-input
-+++ linux-2.4.21/drivers/input/Config.in
-@@ -7,6 +7,8 @@
-
- tristate 'Input core support' CONFIG_INPUT
- dep_tristate ' Keyboard support' CONFIG_INPUT_KEYBDEV $CONFIG_INPUT
-+dep_tristate ' Ramses keyboard' CONFIG_INPUT_RAMSES_KEYB $CONFIG_INPUT_KEYBDEV $CONFIG_ARCH_RAMSES
-+dep_tristate ' Ramses wedge' CONFIG_INPUT_RAMSES_WEDGE $CONFIG_INPUT_RAMSES_KEYB
- dep_tristate ' Mouse support' CONFIG_INPUT_MOUSEDEV $CONFIG_INPUT
- if [ "$CONFIG_INPUT_MOUSEDEV" != "n" ]; then
- int ' Horizontal screen resolution' CONFIG_INPUT_MOUSEDEV_SCREEN_X 1024
---- linux-2.4.21/drivers/input/Makefile~ramses-keyb
-+++ linux-2.4.21/drivers/input/Makefile
-@@ -8,7 +8,7 @@
-
- # Objects that export symbols.
-
--export-objs := input.o
-+export-objs := input.o ramses_keyb.o
-
- # Object file lists.
-
-@@ -21,10 +21,12 @@
-
- obj-$(CONFIG_INPUT) += input.o
- obj-$(CONFIG_INPUT_KEYBDEV) += keybdev.o
-+obj-$(CONFIG_INPUT_RAMSES_KEYB) += ramses_keyb.o
- obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
- obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
- obj-$(CONFIG_INPUT_EVDEV) += evdev.o
- obj-$(CONFIG_INPUT_MX1TS) += mx1ts.o
-+obj-$(CONFIG_INPUT_RAMSES_WEDGE) += wedge.o
-
- # The global Rules.make.
-
---- /dev/null
-+++ linux-2.4.21/drivers/input/ramses_cellmap.h
-@@ -0,0 +1,34 @@
-+static int ramses_cellmap[][8] = {
-+ { KEY_A, KEY_B, KEY_C, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 0
-+ { KEY_D, KEY_E, KEY_F, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 1
-+ { KEY_G, KEY_H, KEY_I, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 2
-+ { KEY_J, KEY_K, KEY_L, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 3
-+ { KEY_M, KEY_N, KEY_O, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 4
-+ { KEY_P, KEY_Q, KEY_R, KEY_S, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 5
-+ { KEY_T, KEY_U, KEY_V, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 6
-+ { KEY_W, KEY_X, KEY_Y, KEY_Z, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 7
-+ { KEY_AE, KEY_OE, KEY_UE, KEY_SZ, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 8
-+ { KEY_sA, KEY_sB, KEY_sC, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 9
-+ { KEY_sD, KEY_sE, KEY_sF, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 10
-+ { KEY_sG, KEY_sH, KEY_sI, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 11
-+ { KEY_sJ, KEY_sK, KEY_sL, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 12
-+ { KEY_sM, KEY_sN, KEY_sO, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 13
-+ { KEY_sP, KEY_sQ, KEY_sR, KEY_sS, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 14
-+ { KEY_sT, KEY_sU, KEY_sV, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 15
-+ { KEY_sW, KEY_sX, KEY_sY, KEY_sZ, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 16
-+ { KEY_sAE, KEY_sOE, KEY_sUE, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 17
-+ { KEY_COLON, KEY_FSLASH,KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 18
-+ { KEY_SEMI, KEY_BSLASH,KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 19
-+ { KEY_COMMA, KEY_STAR, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 20
-+ { KEY_UNDERL,KEY_EQUAL, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 21
-+ { KEY_PLUS, KEY_MINUS, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 22
-+ { KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 24
-+ { KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 24
-+ { KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 25
-+ { KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 26
-+ { KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 27
-+ { KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 28
-+ { KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 29
-+ { KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 30
-+ { KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop }, // 31
-+};
---- /dev/null
-+++ linux-2.4.21/drivers/input/ramses_keyb.c
-@@ -0,0 +1,596 @@
-+/*
-+ * Keyboard driver using input layer
-+ *
-+ * (C) 2002,2003 by M&N Logistik-Lösungen Online GmbH
-+ * written by H.Schurig
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/input.h>
-+#include <linux/delay.h>
-+
-+#include <asm/keyboard.h>
-+#include <asm/irq.h>
-+#include <linux/keyboard.h>
-+
-+// Debug
-+//#define DEBUG
-+//#define DEBUG_DUMP_KEYSTATE
-+#ifdef DEBUG
-+# define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
-+# define PRINTK(fmt, args...) printk(fmt, ## args)
-+#else
-+# define DPRINTK(fmt, args...)
-+# define PRINTK(fmt, args...)
-+#endif
-+
-+
-+/*
-+ * Timeouts
-+ */
-+#define SCANINTERVAL HZ/10
-+#define TRIGOFFINTERVAL HZ*2
-+#define CELLINTERVAL HZ+HZ/2
-+#define MAPINTERVAL 15*HZ
-+#define SUSPEND_COUNTER 40
-+#define SUSPEND_LED_COUNTER 8
-+#define SUSPEND_NOW 0xffff
-+#define KEYBD_MATRIX_SETTLING_TIME_US 100
-+
-+
-+/*
-+ * macros for matrix keyboard driver
-+ */
-+#define KEYBD_MATRIX_NUMBER_INPUTS 7
-+#define KEYBD_MATRIX_NUMBER_OUTPUTS 14
-+
-+#define KEYBD_MATRIX_SET_OUTPUTS(outputs) \
-+{\
-+ RAMSES_CPLD_KB_COL_LOW = outputs;\
-+ RAMSES_CPLD_KB_COL_HIGH = outputs >> 7;\
-+}
-+
-+#define KEYBD_MATRIX_GET_INPUTS(inputs) \
-+{\
-+ inputs = (RAMSES_CPLD_KB_ROW & 0x7f);\
-+}
-+
-+
-+// External functions (are they in some #include file?)
-+extern int input_setkeycode(unsigned int scancode, unsigned int keycode);
-+extern int input_getkeycode(unsigned int scancode);
-+extern int input_translate(unsigned char scancode, unsigned char *keycode,
-+ char raw_mode);
-+extern char input_unexpected_up(unsigned char keycode);
-+extern unsigned char input_sysrq_xlate[];
-+extern int pm_suggest_suspend(void);
-+
-+// Keyboard-Related definitions
-+#define KEYBD_MATRIX_INPUT_MASK ((1 << KEYBD_MATRIX_NUMBER_INPUTS)-1)
-+#define KEYBD_MATRIX_OUTPUT_MASK ((1 << KEYBD_MATRIX_NUMBER_OUTPUTS)-1)
-+
-+#include "ramses_scancodes.h"
-+#include "ramses_keymap.h"
-+#include "ramses_cellmap.h"
-+
-+
-+static char *kbd_name = "Keyboard";
-+struct input_dev ramses_kbd_dev;
-+static struct timer_list reenable_timer;
-+static struct timer_list trigoff_timer;
-+static struct tq_struct tq_suspend;
-+static __u16 keystate_cur[KEYBD_MATRIX_NUMBER_OUTPUTS];
-+static __u16 keystate_prev[KEYBD_MATRIX_NUMBER_OUTPUTS];
-+static __u16 keystate_keep[KEYBD_MATRIX_NUMBER_OUTPUTS]; // used for auto-repeat
-+static struct timer_list cell_timer;
-+static int curr_map = MAP_NORMAL;
-+static int cell_key = -1;
-+static int cell_sel = -1;
-+static struct pm_dev *pm_keyb;
-+static int suspend_counter = 0;
-+
-+
-+void ramses_key(int keycode)
-+{
-+ DPRINTK("keycode: %d 0x%x\n", keycode, keycode);
-+ if (KVAL(keycode)) {
-+ switch (KMOD(keycode)) {
-+ case KM_SHIFT:
-+ DPRINTK("shift\n");
-+ input_report_key(&ramses_kbd_dev, KEY_LEFTSHIFT, 1);
-+ break;
-+ case KM_CTRL:
-+ DPRINTK("ctrl\n");
-+ input_report_key(&ramses_kbd_dev, KEY_LEFTCTRL, 1);
-+ break;
-+ case KM_ALT:
-+ DPRINTK("alt\n");
-+ input_report_key(&ramses_kbd_dev, KEY_LEFTALT, 1);
-+ break;
-+ case KM_ALTGR:
-+ DPRINTK("altgr\n");
-+ input_report_key(&ramses_kbd_dev, KEY_RIGHTALT, 1);
-+ break;
-+ case KM_ALTCTRL:
-+ DPRINTK("alt+ctrl\n");
-+ input_report_key(&ramses_kbd_dev, KEY_LEFTALT, 1);
-+ input_report_key(&ramses_kbd_dev, KEY_LEFTCTRL, 1);
-+ break;
-+ }
-+
-+ DPRINTK("report: %d 0x%x\n", KVAL(keycode), KVAL(keycode));
-+ input_report_key(&ramses_kbd_dev, KVAL(keycode), 1);
-+ input_report_key(&ramses_kbd_dev, KVAL(keycode), 0);
-+
-+ switch (KMOD(keycode)) {
-+ case KM_SHIFT:
-+ input_report_key(&ramses_kbd_dev, KEY_LEFTSHIFT, 0);
-+ break;
-+ case KM_CTRL:
-+ input_report_key(&ramses_kbd_dev, KEY_LEFTCTRL, 0);
-+ break;
-+ case KM_ALT:
-+ input_report_key(&ramses_kbd_dev, KEY_LEFTALT, 0);
-+ break;
-+ case KM_ALTGR:
-+ input_report_key(&ramses_kbd_dev, KEY_RIGHTALT, 0);
-+ break;
-+ case KM_ALTCTRL:
-+ input_report_key(&ramses_kbd_dev, KEY_LEFTALT, 0);
-+ input_report_key(&ramses_kbd_dev, KEY_LEFTCTRL, 0);
-+ break;
-+ }
-+ }
-+}
-+
-+static void kbd_cell_timer(unsigned long keepmap)
-+{
-+ int keycode;
-+
-+ if (cell_sel != -1) {
-+ keycode = ramses_cellmap[cell_key][cell_sel];
-+ //DPRINTK("key: %d sel: %d keycode: %d 0x%x\n", cell_key, cell_sel, keycode, keycode);
-+ ramses_key(keycode);
-+ cell_sel = -1;
-+ }
-+
-+ if (!keepmap && curr_map!=MAP_NORMAL) {
-+ DPRINTK("normal map because of %ld\n", keepmap);
-+ curr_map = MAP_NORMAL;
-+ RAMSES_LED_BLUE_OFF();
-+ RAMSES_LED_ORANGE_OFF();
-+ }
-+}
-+
-+static void kbd_setleds(void)
-+{
-+ if (suspend_counter >= SUSPEND_LED_COUNTER) {
-+ if (suspend_counter & 4) {
-+ RAMSES_LED_ORANGE_OFF();
-+ RAMSES_LED_BLUE_ON();
-+ } else {
-+ RAMSES_LED_ORANGE_ON();
-+ RAMSES_LED_BLUE_OFF();
-+ }
-+ return;
-+ }
-+
-+ switch (curr_map) {
-+ case MAP_NORMAL:
-+ RAMSES_LED_BLUE_OFF();
-+ RAMSES_LED_ORANGE_OFF();
-+ return;
-+
-+ case MAP_BLUE:
-+ RAMSES_LED_BLUE_ON();
-+ RAMSES_LED_ORANGE_OFF();
-+ return;
-+
-+ case MAP_ORANGE:
-+ RAMSES_LED_BLUE_OFF();
-+ RAMSES_LED_ORANGE_ON();
-+ return;
-+
-+ case MAP_CAPS:
-+ RAMSES_LED_BLUE_ON();
-+ RAMSES_LED_ORANGE_ON();
-+ return;
-+ }
-+ DPRINTK("unknown map\n");
-+}
-+
-+
-+static void kbd_start_scanner(void)
-+{
-+ RAMSES_SCANNER_TRIG_OFF();
-+ RAMSES_SCANNER_WAKE_OFF();
-+ RAMSES_SCANNER_TRIG_ON();
-+ mod_timer(&trigoff_timer, jiffies + TRIGOFFINTERVAL);
-+}
-+
-+static void kbd_stop_scanner(unsigned long dummy)
-+{
-+ RAMSES_SCANNER_TRIG_OFF();
-+}
-+
-+static int kbd_dokeycode(unsigned char scancode, int down)
-+{
-+ int i,keycode;
-+
-+ //DPRINTK("calling with (%d,%x,%d)\n", scancode, scancode, down);
-+ if (scancode >= MAX_SCANCODES) {
-+ printk("%s: scancode too big for table\n", __FUNCTION__);
-+ return 0;
-+ }
-+
-+ keycode = ramses_keymap[scancode][curr_map];
-+
-+
-+ if (keycode==KEY_SCAN) {
-+ if ((ramses_flags & RAMSES_FLAGS_KEY_SCAN) == 0)
-+ return 0;
-+
-+ DPRINTK("scan btn\n");
-+ if (down) {
-+ if (ramses_flags & RAMSES_FLAGS_SCANNER_BEAM) {
-+ // just turn on laser beam
-+ RAMSES_SCANNER_WAKE_ON();
-+ } else {
-+ kbd_start_scanner();
-+ }
-+ } else {
-+ if (ramses_flags & RAMSES_FLAGS_SCANNER_BEAM) {
-+ kbd_start_scanner();
-+ } else {
-+ kbd_stop_scanner(0);
-+ }
-+ }
-+ return 0;
-+ }
-+
-+
-+ if (keycode==KEY_SUSP) {
-+ if ((ramses_flags & RAMSES_FLAGS_KEY_SUSPEND) == 0)
-+ return 0;
-+
-+ if (down) {
-+ suspend_counter++;
-+ if (suspend_counter >= SUSPEND_COUNTER) {
-+ suspend_counter = SUSPEND_NOW;
-+ }
-+ } else {
-+ if (suspend_counter == SUSPEND_NOW) {
-+ curr_map = MAP_NORMAL;
-+ schedule_task(&tq_suspend);
-+ }
-+ suspend_counter = 0;
-+ }
-+ return down;
-+ }
-+
-+
-+ if (keycode==KEY_OFF) {
-+ if (down || ((ramses_flags & RAMSES_FLAGS_KEY_OFF) == 0))
-+ return 0;
-+ curr_map = MAP_NORMAL;
-+ ramses_shut_off();
-+ return 0;
-+ }
-+
-+
-+ if (!down)
-+ return 0;
-+
-+
-+ DPRINTK("curr_map %d scancode %d keycode %d 0x%x typ %d\n", curr_map, scancode, keycode, keycode, KMOD(keycode));
-+
-+
-+ // Cell-Phone keyboard handling
-+ if (KMOD(keycode)==KM_CELL) {
-+ //DPRINTK("cell phone key %d\n", KVAL(keycode));
-+
-+ // did we press a different cell-phone key as last time?
-+ if (KVAL(keycode)!=cell_key)
-+ kbd_cell_timer(1);
-+
-+ cell_key = KVAL(keycode); // store current cell-phone key
-+ cell_sel++; // increase current sub-key
-+ if (ramses_cellmap[cell_key][cell_sel]==0) // if at end of sub-key list, back off
-+ cell_sel = 0;
-+ //DPRINTK("cell_key: %d cell_sel: %d\n", cell_key, cell_sel);
-+ // auto-emit via kbd_cell_timer
-+ mod_timer(&cell_timer, jiffies + CELLINTERVAL);
-+ return 0; // do not revert to keys_normal
-+ }
-+
-+
-+ // if we pressed any other key then a cell-phone key, we look if the
-+ // current half-pressed cell-phone key should be emitted
-+ kbd_cell_timer(1);
-+
-+
-+ switch(keycode) {
-+
-+ // Keymap handling
-+
-+ case KEY_NORM:
-+ DPRINTK("norm key map\n");
-+ curr_map = MAP_NORMAL;
-+ return 0;
-+
-+ case KEY_BLUE:
-+ //DPRINTK("blue key map\n");
-+ curr_map = MAP_BLUE;
-+ mod_timer(&cell_timer, jiffies + MAPINTERVAL); // automatically disable keymap
-+ return 0;
-+
-+ case KEY_ORNG:
-+ //DPRINTK("orange key map\n");
-+ curr_map = MAP_ORANGE;
-+ mod_timer(&cell_timer, jiffies + MAPINTERVAL); // automatically disable keymap
-+ return 0;
-+
-+ case KEY_CAPS:
-+ DPRINTK("caps key map\n");
-+ curr_map = MAP_CAPS;
-+ mod_timer(&cell_timer, jiffies + MAPINTERVAL); // automatically disable keymap
-+ return 0;
-+
-+ case KEY_BRIP:
-+ i = ramses_lcd_get_brightness()-6;
-+ ramses_lcd_set_brightness(i);
-+ mod_timer(&cell_timer, jiffies + MAPINTERVAL); // automatically disable keymap
-+ return 0;
-+
-+ case KEY_BRIM:
-+ i = ramses_lcd_get_brightness()+6;
-+ ramses_lcd_set_brightness(i);
-+ mod_timer(&cell_timer, jiffies + MAPINTERVAL); // automatically disable keymap
-+ return 0;
-+
-+ case KEY_CTRM:
-+ i = ramses_lcd_get_contrast()+3;
-+ ramses_lcd_set_contrast(i);
-+ mod_timer(&cell_timer, jiffies + MAPINTERVAL); // automatically disable keymap
-+ return 0;
-+
-+ case KEY_CTRP:
-+ i = ramses_lcd_get_contrast()-3;
-+ ramses_lcd_set_contrast(i);
-+ mod_timer(&cell_timer, jiffies + MAPINTERVAL); // automatically disable keymap
-+ return 0;
-+ }
-+
-+ // normal keys
-+
-+ ramses_key(keycode);
-+
-+ if (curr_map!=MAP_NORMAL)
-+ DPRINTK("back to normal map\n");
-+ curr_map = MAP_NORMAL;
-+ RAMSES_LED_BLUE_OFF();
-+ RAMSES_LED_ORANGE_OFF();
-+ return 0;
-+}
-+
-+
-+/**
-+ * @param rescan 0 if we look for pressed keys, 1 if we look for released keys
-+ *
-+ * This routine get's called from the ISR (then rescan is always 0) or from
-+ * the reenable_timer function (then rescan is 1).
-+ */
-+static void kbd_scan_keyboard(unsigned long rescan)
-+{
-+ int i,n;
-+ int cols;
-+ unsigned char code;
-+ __u16 keystate_xor[KEYBD_MATRIX_NUMBER_OUTPUTS];
-+
-+
-+ // Find out if a key (or more) was pressed down. It's possible that
-+ // because of spikes we got an interrupt, but when the IRQ service
-+ // routine fired there is currently no detectable key. If this is
-+ // true, then delay some times and re-try, but not too often.
-+
-+ cols = 0;
-+ for(n=0; n<10; n++) {
-+ for (i = 0; i < KEYBD_MATRIX_NUMBER_OUTPUTS; i++) {
-+ KEYBD_MATRIX_SET_OUTPUTS( 1 << i );
-+ udelay(KEYBD_MATRIX_SETTLING_TIME_US);
-+ KEYBD_MATRIX_GET_INPUTS(keystate_cur[i]);
-+ if (keystate_cur[i])
-+ cols++;
-+ }
-+ if (cols || rescan)
-+ break;
-+ udelay(KEYBD_MATRIX_SETTLING_TIME_US*50);
-+ }
-+
-+ // if rescan is true, we are in the process of turning on the IRQ.
-+ // Ignore any spurious IRQ. However, if we got an IRQ but could not
-+ // detect any key, we note this on the console, clear the keystate
-+ // completely and make sure the IRQ gets re-enabled via the timer
-+ // shortly.
-+
-+ if (!cols && !rescan) {
-+ printk("%s: spurious kbd int\n", __FUNCTION__);
-+ for (i = 0; i < KEYBD_MATRIX_NUMBER_OUTPUTS; i++) {
-+ keystate_cur[i] = 0;
-+ keystate_prev[i] = 0;
-+ }
-+ mod_timer(&reenable_timer, jiffies + SCANINTERVAL);
-+ return;
-+ }
-+
-+ pm_access(pm_keyb);
-+
-+ // Okay, all went well. We now keystate_cur[] may contain the rows
-+ // where we had keypresses, e.g.
-+ // 0 0 0 2 0 0 0 0 0 0 0 0 0 0
-+ // We would see this if DEBUG_DUMP_KEYSTATE is on:
-+
-+#ifdef DEBUG_DUMP_KEYSTATE
-+ cols = 0;
-+ for (i = 0; i < KEYBD_MATRIX_NUMBER_OUTPUTS; i++) {
-+ printk("%d-%d ",keystate_cur[i], keystate_keep[i]);
-+ }
-+ printk("\n");
-+#endif
-+
-+ cols = 0;
-+ for (i = 0; i < KEYBD_MATRIX_NUMBER_OUTPUTS; i++) {
-+
-+ // detect which key has changes doing an XOR of old state with new state
-+ keystate_xor[i] = keystate_prev[i] ^ keystate_cur[i];
-+ //printk("%d: prev %d cur %d xor %d keep %d\n", i, keystate_prev[i], keystate_cur[i], keystate_xor[i], keystate_keep[i]);
-+
-+ // some key changed, find out which one and do the scancode handling
-+ if (keystate_xor[i] || keystate_keep[i]) {
-+ for (n = 0; n < KEYBD_MATRIX_NUMBER_INPUTS; n++)
-+ {
-+ if ( (keystate_keep[i] & keystate_cur[i]) ||
-+ (keystate_xor[i] & (1 << n)) )
-+ {
-+ int res;
-+ code = n * KEYBD_MATRIX_NUMBER_OUTPUTS + i + 1;
-+ res = kbd_dokeycode(code, keystate_cur[i] & (1 << n) ? 1 : 0);
-+ kbd_setleds();
-+ if (res) {
-+ keystate_keep[i] = 1 << n;
-+ goto out;
-+ }
-+ }
-+ }
-+ }
-+out:
-+ keystate_prev[i] = keystate_cur[i];
-+ }
-+
-+
-+ // fire reenable time if we are in the ISR
-+ if (!rescan)
-+ mod_timer(&reenable_timer, jiffies + SCANINTERVAL);
-+}
-+
-+
-+
-+static void kbd_reenable_timer(unsigned long dummy)
-+{
-+ // re-scan the keyboard (to detect released keys)
-+ kbd_scan_keyboard(1);
-+
-+ // re-enable interrupts from the CPLD
-+ KEYBD_MATRIX_SET_OUTPUTS( KEYBD_MATRIX_OUTPUT_MASK );
-+}
-+
-+
-+
-+
-+
-+/**
-+ * Referenced by request_irq()
-+ */
-+static void kbd_interrupt(int irq, void *dummy, struct pt_regs *fp)
-+{
-+ kbd_scan_keyboard(0);
-+}
-+
-+static void ramseskbd_suspend(void *data)
-+{
-+ pm_suggest_suspend();
-+}
-+
-+
-+static int __init ramseskbd_init(void)
-+{
-+ int irq_gpio_pin;
-+
-+ // Activate the normal pc-keycodes for the input-layer-keyboard
-+ k_setkeycode = input_setkeycode;
-+ k_getkeycode = input_getkeycode;
-+ k_translate = input_translate;
-+ k_unexpected_up = input_unexpected_up;
-+#ifdef CONFIG_MAGIC_SYSRQ
-+ k_sysrq_key = 0x54;
-+ k_sysrq_xlate = input_sysrq_xlate;
-+#endif
-+
-+ // In linux-2.5.x we can do
-+ // init_input_dev(&ramses_kbd_dev);
-+ // but here we don't have this on linux-2.4, so we fill it with zeros:
-+ memset(&ramses_kbd_dev, 0, sizeof(ramses_kbd_dev));
-+ ramses_kbd_dev.name = kbd_name;
-+
-+ // which events we can produce (only keypresses):
-+ ramses_kbd_dev.evbit[0] = BIT(EV_KEY);
-+
-+ // which keypresses we can produce (all):
-+ memset(&ramses_kbd_dev.keybit, 0xff, sizeof(ramses_kbd_dev.keybit));
-+
-+ // We set the 14 output columns to 0. This stops the CPLD to
-+ // generate an IRQ before we finished our setup
-+ KEYBD_MATRIX_SET_OUTPUTS(0);
-+
-+ // Turn all LEDs off, meaning that we have the normal keymap active
-+ RAMSES_LED_BLUE_OFF();
-+ RAMSES_LED_ORANGE_OFF();
-+ // TODO: used leds.c?
-+
-+ // Now we make sure that the GPIO for our IRQ is programmed correctly
-+ irq_gpio_pin = IRQ_TO_GPIO_2_80(RAMSES_KEYBOARD_IRQ);
-+ GPDR(irq_gpio_pin) &= ~GPIO_bit(irq_gpio_pin);
-+ set_GPIO_IRQ_edge(irq_gpio_pin, RAMSES_KEYBOARD_IRQ_EDGE);
-+ request_irq(RAMSES_KEYBOARD_IRQ, kbd_interrupt, 0, kbd_name, NULL);
-+
-+ // Initialize timer to re-enable IRQs. That's our method of keyboard de-prelling
-+ init_timer(&reenable_timer);
-+ reenable_timer.function = kbd_reenable_timer;
-+
-+ init_timer(&trigoff_timer);
-+ trigoff_timer.function = kbd_stop_scanner;
-+
-+ // Initialize to escape the blue mode, so we emit the current cell-phone key
-+ init_timer(&cell_timer);
-+ cell_timer.function = kbd_cell_timer;
-+
-+ tq_suspend.routine = ramseskbd_suspend;
-+
-+ // Register with Power-Management
-+#ifdef PM_DEBUG
-+ pm_keyb = pm_register(PM_SYS_DEV, PM_SYS_KBC+1, NULL, "ramses_keyb");
-+#else
-+ pm_keyb = pm_register(PM_SYS_DEV, PM_SYS_KBC+1, NULL);
-+#endif
-+
-+ // Register our keyboard
-+ input_register_device(&ramses_kbd_dev);
-+
-+ // We set the 14 output columns to 1. This allows the CPLD to
-+ // generate an IRQ when one of the rows goes high
-+ KEYBD_MATRIX_SET_OUTPUTS(KEYBD_MATRIX_OUTPUT_MASK);
-+
-+ return 0;
-+}
-+
-+
-+static void __exit ramseskbd_exit(void)
-+{
-+ // make IRQs impossible, return the IRQ and unregister us
-+ KEYBD_MATRIX_SET_OUTPUTS(0);
-+ free_irq(RAMSES_KEYBOARD_IRQ, NULL);
-+ pm_unregister(pm_keyb);
-+ input_unregister_device(&ramses_kbd_dev);
-+}
-+
-+
-+module_init(ramseskbd_init);
-+module_exit(ramseskbd_exit);
-+
-+MODULE_AUTHOR("Holger Schurig <h.schurig@mn-logistik.de>");
-+MODULE_DESCRIPTION("Ramses keyboard driver");
-+MODULE_LICENSE("GPL");
-+EXPORT_SYMBOL(ramses_key);
-+EXPORT_SYMBOL(ramses_kbd_dev);
---- /dev/null
-+++ linux-2.4.21/drivers/input/ramses_keymap.h
-@@ -0,0 +1,68 @@
-+// Normal Map
-+static int ramses_keymap[][6] = {
-+/* Normal Blue Orange Caps Spare Spare */
-+/* 0 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 1 */ {KEY_SUSP, KEY_SUSP, KEY_SUSP, KEY_OFF, KEY_SUSP, KEY_SUSP },
-+/* 2 */ {KEY_UP, KEY_UP, KEY_PGUP, KEY_UP, KEY_noop, KEY_noop },
-+/* 3 */ {KEY_1, KEY_SPACE, KEY_BRIM, KEY_SPACE, KEY_noop, KEY_noop },
-+/* 4 */ {KEY_4, KEY_ghi , KEY_CTRM, KEY_GHI , KEY_noop, KEY_noop },
-+/* 5 */ {KEY_7, KEY_pqrs, KEY_cel7, KEY_PQRS, KEY_noop, KEY_noop },
-+/* 6 */ {KEY_DOT, KEY_uml, KEY_celP, KEY_UML, KEY_noop, KEY_noop },
-+/* 7 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 8 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 9 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 10 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 11 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 12 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 13 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 14 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 15 */ {KEY_ENTER, KEY_ENTER, KEY_ENTER, KEY_ENTER, KEY_ENTER, KEY_ENTER},
-+/* 16 */ {KEY_DOWN, KEY_DOWN, KEY_PGDN, KEY_DOWN, KEY_noop, KEY_noop },
-+/* 17 */ {KEY_2, KEY_abc , KEY_BRIP, KEY_ABC , KEY_noop, KEY_noop },
-+/* 18 */ {KEY_5, KEY_jkl , KEY_CTRP, KEY_JKL, KEY_noop, KEY_noop },
-+/* 19 */ {KEY_8, KEY_tuv , KEY_cel8, KEY_TUV, KEY_noop, KEY_noop },
-+
-+/* Normal Blue Orange Caps Spare Spare */
-+/* 20 */ {KEY_0, KEY_TAB, KEY_cel0, KEY_BTAB, KEY_noop, KEY_noop },
-+/* 21 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 22 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 23 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 24 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 25 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 26 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 27 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 28 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 29 */ {KEY_ESC, KEY_ESC, KEY_ESC, KEY_ESC, KEY_ESC, KEY_ESC },
-+/* 30 */ {KEY_RIGHT, KEY_RIGHT, KEY_END, KEY_C2, KEY_noop, KEY_noop },
-+/* 31 */ {KEY_3, KEY_def, KEY_FXIT, KEY_DEF, KEY_noop, KEY_noop },
-+/* 32 */ {KEY_6, KEY_mno , KEY_FRST, KEY_MNO, KEY_noop, KEY_noop },
-+/* 33 */ {KEY_9, KEY_wxyz, KEY_cel9, KEY_WXYZ, KEY_noop, KEY_noop },
-+/* 34 */ {KEY_BACKSPACE,KEY_ATSIGN,KEY_BAR, KEY_noop, KEY_noop, KEY_noop },
-+/* 35 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 36 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 37 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 38 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 39 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+
-+/* Normal Blue Orange Caps Spare Spare */
-+/* 40 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 41 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 42 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 43 */ {KEY_SCAN, KEY_SCAN, KEY_SCAN, KEY_SCAN, KEY_SCAN, KEY_SCAN },
-+/* 44 */ {KEY_LEFT, KEY_LEFT, KEY_HOME, KEY_C1, KEY_noop, KEY_noop },
-+/* 45 */ {KEY_OFF, KEY_OFF, KEY_OFF, KEY_OFF, KEY_OFF, KEY_OFF },
-+/* 46 */ {KEY_F1, KEY_F4, KEY_F7, KEY_F10, KEY_noop, KEY_noop },
-+/* 47 */ {KEY_F2, KEY_F5, KEY_F8, KEY_F11, KEY_noop, KEY_noop },
-+/* 48 */ {KEY_F3, KEY_F6, KEY_F9, KEY_F12, KEY_noop, KEY_noop },
-+/* 49 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 50 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 51 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 52 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 53 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 54 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 55 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 56 */ {KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop, KEY_noop },
-+/* 57 */ {KEY_SCAN, KEY_SCAN, KEY_SCAN, KEY_SCAN, KEY_SCAN, KEY_SCAN },
-+/* 58 */ {KEY_BLUE, KEY_NORM, KEY_CAPS, KEY_NORM, KEY_NORM, KEY_NORM },
-+/* 59 */ {KEY_ORNG, KEY_CAPS, KEY_NORM, KEY_NORM, KEY_NORM, KEY_NORM },
-+};
---- /dev/null
-+++ linux-2.4.21/drivers/input/ramses_scancodes.h
-@@ -0,0 +1,134 @@
-+#ifndef _RAMSES_SCANCODES_H
-+#define _RAMSES_SCANCODES_H
-+
-+#define KMOD(a) (a & 0xff00)
-+#undef KVAL
-+#define KVAL(a) (a & 0x00ff)
-+
-+// which modifiers to send before/after
-+#define KM_SPECIAL 0x300
-+#define KM_CELL 0x400
-+#define KM_SHIFT 0x500
-+#define KM_ALT 0x600
-+#define KM_CTRL 0x700
-+#define KM_ALTGR 0x800
-+#define KM_ALTCTRL 0x900
-+
-+// or special keys
-+#define KEY_noop KM_SPECIAL + 0
-+#define KEY_OFF KM_SPECIAL + 1
-+#define KEY_SUSP KM_SPECIAL + 2
-+#define KEY_SCAN KM_SPECIAL + 3
-+#define KEY_CTRM KM_SPECIAL + 4
-+#define KEY_CTRP KM_SPECIAL + 5
-+#define KEY_BRIM KM_SPECIAL + 6
-+#define KEY_BRIP KM_SPECIAL + 7
-+
-+#define KEY_NORM KM_SPECIAL + 10
-+#define KEY_BLUE KM_SPECIAL + 11
-+#define KEY_ORNG KM_SPECIAL + 12
-+#define KEY_CAPS KM_SPECIAL + 13
-+
-+
-+// our cell-phone like keys
-+#define KEY_abc KM_CELL + 0
-+#define KEY_def KM_CELL + 1
-+#define KEY_ghi KM_CELL + 2
-+#define KEY_jkl KM_CELL + 3
-+#define KEY_mno KM_CELL + 4
-+#define KEY_pqrs KM_CELL + 5
-+#define KEY_tuv KM_CELL + 6
-+#define KEY_wxyz KM_CELL + 7
-+#define KEY_uml KM_CELL + 8
-+#define KEY_ABC KM_CELL + 9
-+#define KEY_DEF KM_CELL + 10
-+#define KEY_GHI KM_CELL + 11
-+#define KEY_JKL KM_CELL + 12
-+#define KEY_MNO KM_CELL + 13
-+#define KEY_PQRS KM_CELL + 14
-+#define KEY_TUV KM_CELL + 15
-+#define KEY_WXYZ KM_CELL + 16
-+#define KEY_UML KM_CELL + 17
-+#define KEY_cel7 KM_CELL + 18
-+#define KEY_cel8 KM_CELL + 19
-+#define KEY_cel9 KM_CELL + 20
-+#define KEY_celP KM_CELL + 21
-+#define KEY_cel0 KM_CELL + 22
-+
-+// Shift-Keys
-+#define KEY_sA KM_SHIFT + KEY_A
-+#define KEY_sB KM_SHIFT + KEY_B
-+#define KEY_sC KM_SHIFT + KEY_C
-+#define KEY_sD KM_SHIFT + KEY_D
-+#define KEY_sE KM_SHIFT + KEY_E
-+#define KEY_sF KM_SHIFT + KEY_F
-+#define KEY_sG KM_SHIFT + KEY_G
-+#define KEY_sH KM_SHIFT + KEY_H
-+#define KEY_sI KM_SHIFT + KEY_I
-+#define KEY_sJ KM_SHIFT + KEY_J
-+#define KEY_sK KM_SHIFT + KEY_K
-+#define KEY_sL KM_SHIFT + KEY_L
-+#define KEY_sM KM_SHIFT + KEY_M
-+#define KEY_sN KM_SHIFT + KEY_N
-+#define KEY_sO KM_SHIFT + KEY_O
-+#define KEY_sP KM_SHIFT + KEY_P
-+#define KEY_sQ KM_SHIFT + KEY_Q
-+#define KEY_sR KM_SHIFT + KEY_R
-+#define KEY_sS KM_SHIFT + KEY_S
-+#define KEY_sT KM_SHIFT + KEY_T
-+#define KEY_sU KM_SHIFT + KEY_U
-+#define KEY_sV KM_SHIFT + KEY_V
-+#define KEY_sW KM_SHIFT + KEY_W
-+#define KEY_sX KM_SHIFT + KEY_X
-+#define KEY_sY KM_SHIFT + KEY_Y
-+#define KEY_sZ KM_SHIFT + KEY_Z
-+
-+// Umlaute
-+#define KEY_sAE KM_SHIFT + 40
-+#define KEY_sOE KM_SHIFT + 39
-+#define KEY_sUE KM_SHIFT + 26
-+#define KEY_AE 40
-+#define KEY_OE 39
-+#define KEY_UE 26
-+#define KEY_SZ 12
-+
-+// AS400-Keys
-+#define KEY_FRST KM_ALT + KEY_R
-+#define KEY_FXIT KM_ALT + KEY_X
-+
-+// Console-Switch
-+#define KEY_C1 KM_ALTCTRL + KEY_F1
-+#define KEY_C2 KM_ALTCTRL + KEY_F2
-+
-+// additional keys from the german keyboard
-+#undef KEY_MINUS
-+#undef KEY_EQUAL
-+#undef KEY_Y
-+#undef KEY_Z
-+#define KEY_Y 44
-+#define KEY_Z 21
-+#define KEY_STAR 55
-+#define KEY_COLON KM_SHIFT + 52
-+#define KEY_UNDERL KM_SHIFT + 53
-+#define KEY_ATSIGN KM_ALTGR + 16
-+#define KEY_BAR KM_ALTGR + 86
-+#define KEY_EQUAL KM_SHIFT + 11
-+#define KEY_SEMI KM_SHIFT + 51
-+#define KEY_BSLASH KM_ALTGR + 12
-+#define KEY_FSLASH KM_SHIFT + KEY_7
-+#define KEY_MINUS 53
-+#define KEY_PLUS 27
-+#define KEY_GAENSE KM_SHIFT + 3
-+#define KEY_PARA KM_SHIFT + 4
-+#define KEY_HASH 43
-+#define KEY_PGUP KEY_PAGEUP
-+#define KEY_PGDN KEY_PAGEDOWN
-+#define KEY_BTAB KM_SHIFT + KEY_TAB
-+
-+#define MAP_NORMAL 0
-+#define MAP_BLUE 1
-+#define MAP_ORANGE 2
-+#define MAP_CAPS 3
-+#define MAX_SCANCODES 100
-+
-+#endif
---- /dev/null
-+++ linux-2.4.21/drivers/input/wedge.c
-@@ -0,0 +1,241 @@
-+/*
-+ * Virtual keyboard wedge using input layer
-+ *
-+ * (C) 2002,2003 by M&N Logistik-Lösungen Online GmbH
-+ * written by H.Schurig
-+ *
-+ * Creates a misc char device /dev/misc/wedge. Any output to this
-+ * device will be translated (via a german keyboard map) into scancodes
-+ * and re-submitted into the keyboard channel. Any console, X-Windows
-+ * or Qt/Embedded application will be able to receive this info.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/miscdevice.h>
-+#include <linux/input.h>
-+
-+#include <linux/types.h>
-+#include <linux/keyboard.h>
-+#include <linux/kd.h>
-+
-+#include <asm/uaccess.h>
-+
-+
-+// Debug
-+//#define DEBUG 1
-+#ifdef DEBUG
-+# define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
-+# define PRINTK(fmt, args...) printk(fmt, ## args)
-+#else
-+# define DPRINTK(fmt, args...)
-+# define PRINTK(fmt, args...)
-+#endif
-+
-+
-+// Defines
-+#define KBD_STUFF_MAX_BYTES 512
-+
-+// Für den IOCTL
-+#define WEDGE_RAWKEY_DOWN _IOW('w', 0x72, unsigned long)
-+#define WEDGE_RAWKEY_UP _IOW('w', 0x73, unsigned long)
-+#define WEDGE_TS_ABS_X _IOW('w', 0x74, unsigned long)
-+#define WEDGE_TS_ABS_Y _IOW('w', 0x75, unsigned long)
-+#define WEDGE_TS_ABS_PRESSURE _IOW('w', 0x76, unsigned long)
-+
-+// Externs
-+#define MAX_NR_KEYMAPS 256
-+extern void ramses_key(int keycode);
-+extern unsigned short *key_maps[MAX_NR_KEYMAPS];
-+extern struct input_dev ramses_kbd_dev;
-+extern void ucb1x00_ts_evt_add(void *, u16 pressure, u16 x, u16 y);
-+
-+// for special keys
-+struct wedge_lookup_t {
-+ u_short c;
-+ u_short keysym;
-+};
-+
-+struct wedge_lookup_t wedge_lookup[] = {
-+ { 0x0a, 0x001c, },
-+ { 0x2f, 0x0508, },
-+};
-+
-+
-+
-+
-+static void *outbuf;
-+
-+static int wedge_open(struct inode *inode, struct file *filp)
-+{
-+ int ret;
-+
-+ ret = -ENXIO;
-+ outbuf = kmalloc(KBD_STUFF_MAX_BYTES, GFP_KERNEL);
-+ if (!outbuf)
-+ goto out;
-+
-+ ret = 0;
-+
-+out:
-+ if (ret) {
-+ kfree(outbuf);
-+ }
-+ return ret;
-+}
-+
-+
-+static int wedge_close(struct inode *inode, struct file *filp)
-+{
-+ kfree(outbuf);
-+ return 0;
-+}
-+
-+
-+static int wedge_search_map(u_short map[], int c)
-+{
-+ int i;
-+
-+ for (i=0; i<NR_KEYS; i++) {
-+ if (map[i] == (c | 0xf000))
-+ return i;
-+ if (map[i] == (c | 0xfb00))
-+ return i;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static void wedge_handle_char(int c)
-+{
-+ int i;
-+ unsigned int maps;
-+ u_short *map;
-+
-+ DPRINTK("wedge_handle_char(0x%0x)\n", c);
-+
-+ for (i=0; i < sizeof(wedge_lookup)/sizeof(wedge_lookup[0]); i++) {
-+ if (wedge_lookup[i].c == c) {
-+ ramses_key(wedge_lookup[i].keysym);
-+ return;
-+ }
-+ }
-+
-+
-+ i = 0;
-+ for (maps=0; maps<MAX_NR_KEYMAPS; maps++) {
-+ map = key_maps[maps];
-+ if (!map)
-+ continue;
-+ if ((i = wedge_search_map(map, c))) {
-+ switch(maps) {
-+ case 0:
-+ break;
-+ case 1:
-+ i |= 0x500; // KT_SHIFT from ramses_scancodes.h
-+ break;
-+ case 2:
-+ i |= 0x800; // KT_ALTGR from ramses_scancodes.h
-+ break;
-+ case 4:
-+ i |= 0x700; // KT_CTRL from ramses_scancodes.h
-+ break;
-+ default:
-+ DPRINTK("unknown map for char %d %d\n", c, maps);
-+ }
-+ DPRINTK("ramses_key(0x%x)\n", i);
-+ ramses_key(i);
-+ return;
-+ }
-+ }
-+
-+ DPRINTK("entry for char %02x missing\n", c);
-+}
-+
-+
-+
-+static ssize_t wedge_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
-+{
-+ const char *p = buf;
-+ char c;
-+
-+ //DPRINTK("count=%d\n", count);
-+ while (count) {
-+ if (copy_from_user(&c, p, sizeof(c)))
-+ return -EFAULT;
-+
-+ p++;
-+ count--;
-+
-+ wedge_handle_char( (int)c & 0xff);
-+
-+ }
-+ return p - buf;
-+}
-+
-+
-+int wedge_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-+{
-+ static u16 x;
-+ static u16 y;
-+ static u16 p;
-+
-+ switch (cmd) {
-+ case WEDGE_RAWKEY_DOWN:
-+ DPRINTK("send down raw key\n");
-+ input_report_key(&ramses_kbd_dev, arg, 1);
-+ return 0;
-+ case WEDGE_RAWKEY_UP:
-+ DPRINTK("send up raw key\n");
-+ input_report_key(&ramses_kbd_dev, arg, 0);
-+ return 0;
-+ case WEDGE_TS_ABS_X:
-+ x = arg;
-+ return 0;
-+ case WEDGE_TS_ABS_Y:
-+ y = arg;
-+ return 0;
-+ case WEDGE_TS_ABS_PRESSURE:
-+ p = arg;
-+ ucb1x00_ts_evt_add(NULL, arg, y, x);
-+ return 0;
-+ }
-+ return -EINVAL;
-+}
-+
-+
-+static struct file_operations wedge_fops = {
-+ owner: THIS_MODULE,
-+ write: wedge_write,
-+ open: wedge_open,
-+ release: wedge_close,
-+ ioctl: wedge_ioctl,
-+};
-+
-+
-+static struct miscdevice wedge_miscdev = {
-+ minor: MISC_DYNAMIC_MINOR,
-+ name: "wedge",
-+ fops: &wedge_fops,
-+};
-+
-+static int __init wedge_init(void)
-+{
-+ int ret;
-+ ret = misc_register(&wedge_miscdev);
-+ DPRINTK("major,minor is 10,%d\n", wedge_miscdev.minor);
-+ return ret;
-+}
-+
-+static void __exit wedge_exit(void)
-+{
-+ misc_deregister(&wedge_miscdev);
-+}
-+
-+module_init(wedge_init);
-+module_exit(wedge_exit);
-+
-+MODULE_DESCRIPTION("virtual keyboard wedge");
-+MODULE_LICENSE("GPL");
---- linux-2.4.21/drivers/misc/Makefile~wedge
-+++ linux-2.4.21/drivers/misc/Makefile
-@@ -12,7 +12,7 @@
- O_TARGET := misc.o
-
- export-objs := mcp-core.o mcp-sa1100.o mcp-pxa.o \
-- ucb1x00-core.o
-+ ucb1x00-core.o ucb1x00-ts.o
-
- obj-$(CONFIG_MCP_SA1100) += mcp-core.o mcp-sa1100.o
- obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
---- linux-2.4.21/drivers/misc/mcp-pxa.c~ucb1x00
-+++ linux-2.4.21/drivers/misc/mcp-pxa.c
-@@ -31,6 +31,11 @@
- return (struct mcp *)codec;
- }
-
-+void mcp_put(void)
-+{
-+ pxa_ac97_put();
-+}
-+
- void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val)
- {
- struct ac97_codec *codec = (struct ac97_codec *)mcp;
-@@ -55,3 +60,7 @@
- void mcp_disable(struct mcp *mcp)
- {
- }
-+
-+MODULE_AUTHOR("Jeff Sutherland <jeffs@accelent.com>");
-+MODULE_DESCRIPTION("PXA mcp low level support");
-+MODULE_LICENSE("GPL");
---- linux-2.4.21/drivers/misc/mcp.h~ucb1x00
-+++ linux-2.4.21/drivers/misc/mcp.h
-@@ -43,6 +43,7 @@
-
- /* noddy implementation alert! */
- struct mcp *mcp_get(void);
-+void mcp_put(void);
- int mcp_register(struct mcp *);
-
- #define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate)
---- linux-2.4.21/drivers/misc/ucb1x00-core.c~pm
-+++ linux-2.4.21/drivers/misc/ucb1x00-core.c
-@@ -25,6 +25,7 @@
- #include <linux/pm.h>
- #include <linux/tqueue.h>
- #include <linux/config.h>
-+#include <linux/delay.h>
-
- #include <asm/irq.h>
- #include <asm/mach-types.h>
-@@ -181,8 +182,9 @@
- if (val & UCB_ADC_DAT_VAL)
- break;
- /* yield to other processes */
-- set_current_state(TASK_INTERRUPTIBLE);
-- schedule_timeout(1);
-+ //HS set_current_state(TASK_INTERRUPTIBLE);
-+ //HS schedule_timeout(1);
-+ udelay(200);
- }
-
- return UCB_ADC_DAT(val);
-@@ -209,7 +211,8 @@
- struct ucb1x00 *ucb = (struct ucb1x00 *)dev->data;
- unsigned int isr;
-
-- if (rqst == PM_RESUME) {
-+ switch (rqst) {
-+ case PM_RESUME:
- ucb1x00_enable(ucb);
- isr = ucb1x00_reg_read(ucb, UCB_IE_STATUS);
- ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr);
-@@ -521,7 +524,9 @@
- */
- static int __init ucb1x00_configure(struct ucb1x00 *ucb)
- {
-+#ifndef CONFIG_ARCH_RAMSES
- unsigned int irq_gpio_pin = 0;
-+#endif
- int irq, default_irq = NO_IRQ;
-
- #ifdef CONFIG_ARCH_SA1100
-@@ -611,11 +616,13 @@
- /*
- * Eventually, this will disappear.
- */
-+#ifndef CONFIG_ARCH_RAMSES
- if (irq_gpio_pin)
- #ifdef CONFIG_ARCH_PXA_IDP
- set_GPIO_IRQ_edge(irq_gpio_pin, GPIO_FALLING_EDGE);
- #else
- set_GPIO_IRQ_edge(irq_gpio_pin, GPIO_RISING_EDGE);
-+#endif
- #endif
- irq = ucb1x00_detect_irq(ucb);
- if (irq != NO_IRQ) {
---- linux-2.4.21/drivers/misc/ucb1x00-ts.c~ramses-ucb1x00-dejitter
-+++ linux-2.4.21/drivers/misc/ucb1x00-ts.c
-@@ -29,6 +29,7 @@
-
- #include <asm/dma.h>
- #include <asm/semaphore.h>
-+#include <asm/hardware.h>
-
- #include "ucb1x00.h"
-
-@@ -97,7 +98,7 @@
- };
-
- static struct ucb1x00_ts ucbts;
--static int adcsync = UCB_NOSYNC;
-+static int adcsync = UCB_SYNC;
-
- static int ucb1x00_ts_startup(struct ucb1x00_ts *ts);
- static void ucb1x00_ts_shutdown(struct ucb1x00_ts *ts);
-@@ -116,8 +117,14 @@
- next_head = (ts->evt_head + 1) & (NR_EVENTS - 1);
- if (next_head != ts->evt_tail) {
- ts->events[ts->evt_head].pressure = pressure;
-+#if 0
- ts->events[ts->evt_head].x = x;
- ts->events[ts->evt_head].y = y;
-+#else
-+ // rotate by -90
-+ ts->events[ts->evt_head].x = y;
-+ ts->events[ts->evt_head].y = x;
-+#endif
- do_gettimeofday(&ts->events[ts->evt_head].stamp);
- ts->evt_head = next_head;
-
-@@ -256,11 +263,11 @@
-
- #define ucb1x00_ts_evt_clear(ts) do { } while (0)
-
--static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
-+void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
- {
-- input_report_abs(&ts->idev, ABS_X, x);
-- input_report_abs(&ts->idev, ABS_Y, y);
-- input_report_abs(&ts->idev, ABS_PRESSURE, pressure);
-+ input_report_abs(&ucbts.idev, ABS_X, y);
-+ input_report_abs(&ucbts.idev, ABS_Y, x);
-+ input_report_abs(&ucbts.idev, ABS_PRESSURE, pressure);
- }
-
- static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
-@@ -335,7 +342,7 @@
- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-
-- return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
-+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSMY, ts->adcsync);
- }
-
- /*
-@@ -346,19 +353,15 @@
- */
- static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
- {
-- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-- UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
-- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-- UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
-- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-+ unsigned int res;
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
- UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
- UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
-
-- udelay(55);
-+ udelay(600);
-
-- return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
-+ res = ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSMY, ts->adcsync);
-+ return res;
- }
-
- /*
-@@ -369,19 +372,15 @@
- */
- static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts)
- {
-+ unsigned int res;
- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
-- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
-- UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
-+ UCB_TS_CR_TSPY_GND | UCB_TS_CR_TSMY_POW |
- UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
-
-- udelay(55);
-+ udelay(300);
-
-- return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);
-+ res = ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);
-+ return res;
- }
-
- /*
-@@ -430,8 +429,9 @@
- * We could run as a real-time thread. However, thus far
- * this doesn't seem to be necessary.
- */
--// tsk->policy = SCHED_FIFO;
--// tsk->rt_priority = 1;
-+//HS
-+ tsk->policy = SCHED_FIFO;
-+ tsk->rt_priority = 1;
-
- /* only want to receive SIGKILL */
- spin_lock_irq(&tsk->sigmask_lock);
-@@ -451,8 +451,8 @@
- ucb1x00_adc_enable(ts->ucb);
-
- x = ucb1x00_ts_read_xpos(ts);
-- y = ucb1x00_ts_read_ypos(ts);
- p = ucb1x00_ts_read_pressure(ts);
-+ y = ucb1x00_ts_read_ypos(ts);
-
- /*
- * Switch back to interrupt mode.
-@@ -461,7 +461,7 @@
- ucb1x00_adc_disable(ts->ucb);
-
- set_task_state(tsk, TASK_UNINTERRUPTIBLE);
-- schedule_timeout(HZ / 100);
-+ schedule_timeout(HZ / 200);
- if (signal_pending(tsk))
- break;
-
-@@ -504,7 +504,7 @@
- }
-
- set_task_state(tsk, TASK_INTERRUPTIBLE);
-- schedule_timeout(HZ / 100);
-+ schedule_timeout(HZ / 200);
- }
-
- if (signal_pending(tsk))
-@@ -655,8 +655,8 @@
- char *p;
-
- while ((p = strsep(&str, ",")) != NULL) {
-- if (strcmp(p, "sync") == 0)
-- adcsync = UCB_SYNC;
-+ if (strcmp(p, "nosync") == 0)
-+ adcsync = UCB_NOSYNC;
- }
-
- return 1;
-@@ -674,6 +674,7 @@
- module_init(ucb1x00_ts_init);
- module_exit(ucb1x00_ts_exit);
-
-+EXPORT_SYMBOL(ucb1x00_ts_evt_add);
- MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
- MODULE_DESCRIPTION("UCB1x00 touchscreen driver");
- MODULE_LICENSE("GPL");
---- linux-2.4.21/drivers/mtd/maps/Config.in~ramses-mtd
-+++ linux-2.4.21/drivers/mtd/maps/Config.in
-@@ -76,6 +76,7 @@
-
- if [ "$CONFIG_ARM" = "y" ]; then
- dep_tristate ' CFI Flash device mapped on Lubbock board' CONFIG_MTD_LUBBOCK $CONFIG_MTD_CFI $CONFIG_ARCH_LUBBOCK $CONFIG_MTD_PARTITIONS
-+ dep_tristate ' CFI Flash device mapped on Ramses board' CONFIG_MTD_RAMSES $CONFIG_MTD_CFI $CONFIG_ARCH_RAMSES $CONFIG_MTD_PARTITIONS
- dep_tristate ' CFI Flash device mapped on Nora' CONFIG_MTD_NORA $CONFIG_MTD_CFI
- dep_tristate ' CFI Flash device mapped on ARM Integrator/P720T' CONFIG_MTD_ARM_INTEGRATOR $CONFIG_MTD_CFI
- dep_tristate ' Cirrus CDB89712 evaluation board mappings' CONFIG_MTD_CDB89712 $CONFIG_MTD_CFI $CONFIG_ARCH_CDB89712
---- linux-2.4.21/drivers/mtd/maps/Makefile~ramses-mtd
-+++ linux-2.4.21/drivers/mtd/maps/Makefile
-@@ -16,6 +16,7 @@
- obj-$(CONFIG_MTD_EPXA) += epxa-flash.o
- obj-$(CONFIG_MTD_IQ80310) += iq80310.o
- obj-$(CONFIG_MTD_LUBBOCK) += lubbock.o
-+obj-$(CONFIG_MTD_RAMSES) += ramses.o
- obj-$(CONFIG_MTD_PXA_CERF) += pxa_cerf.o
- obj-$(CONFIG_MTD_TRIZEPS2) += trizeps2.o
- obj-$(CONFIG_MTD_L440GX) += l440gx.o
---- /dev/null
-+++ linux-2.4.21/drivers/mtd/maps/ramses.c
-@@ -0,0 +1,167 @@
-+/*
-+ * Map driver for the Ramses developer platform.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <asm/io.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+
-+
-+#define WINDOW_ADDR 0
-+#define WINDOW_SIZE 32*1024*1024
-+
-+static __u8 ramses_read8(struct map_info *map, unsigned long ofs)
-+{
-+ return *(__u8 *)(map->map_priv_1 + ofs);
-+}
-+
-+static __u16 ramses_read16(struct map_info *map, unsigned long ofs)
-+{
-+ return *(__u16 *)(map->map_priv_1 + ofs);
-+}
-+
-+static __u32 ramses_read32(struct map_info *map, unsigned long ofs)
-+{
-+ return *(__u32 *)(map->map_priv_1 + ofs);
-+}
-+
-+static void ramses_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-+{
-+ memcpy(to, (void *)(map->map_priv_1 + from), len);
-+}
-+
-+static void ramses_write8(struct map_info *map, __u8 d, unsigned long adr)
-+{
-+ *(__u8 *)(map->map_priv_1 + adr) = d;
-+}
-+
-+static void ramses_write16(struct map_info *map, __u16 d, unsigned long adr)
-+{
-+ *(__u16 *)(map->map_priv_1 + adr) = d;
-+}
-+
-+static void ramses_write32(struct map_info *map, __u32 d, unsigned long adr)
-+{
-+ *(__u32 *)(map->map_priv_1 + adr) = d;
-+}
-+
-+static void ramses_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-+{
-+ memcpy((void *)(map->map_priv_1 + to), from, len);
-+}
-+
-+static struct map_info ramses_map = {
-+ name: "Flash",
-+ size: WINDOW_SIZE,
-+ read8: ramses_read8,
-+ read16: ramses_read16,
-+ read32: ramses_read32,
-+ copy_from: ramses_copy_from,
-+ write8: ramses_write8,
-+ write16: ramses_write16,
-+ write32: ramses_write32,
-+ copy_to: ramses_copy_to
-+};
-+
-+static struct mtd_partition ramses_partitions[] = {
-+ {
-+ name: "Bootloader",
-+ size: 0x00040000,
-+ offset: 0,
-+ },{
-+ name: "Kernel",
-+ size: 0x00100000,
-+ offset: 0x00040000,
-+ },{
-+ name: "Filesystem",
-+ size: MTDPART_SIZ_FULL,
-+ offset: 0x00140000
-+ }
-+};
-+
-+#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
-+
-+static struct mtd_info *mymtd;
-+static struct mtd_partition *parsed_parts;
-+
-+extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
-+
-+static int __init init_ramses(void)
-+{
-+ struct mtd_partition *parts;
-+ int nb_parts = 0;
-+ int parsed_nr_parts = 0;
-+ char *part_type = "static";
-+
-+ ramses_map.buswidth = (BOOT_DEF & 1) ? 2 : 4;
-+ printk( "Probing flash at physical address 0x%08x (%d-bit buswidth)\n",
-+ WINDOW_ADDR, ramses_map.buswidth * 8 );
-+#ifdef CONFIG_ARCH_RAMSES
-+ FLASH_WRITE_PROTECT_DISABLE();
-+#endif
-+ ramses_map.map_priv_1 = (unsigned long)__ioremap(WINDOW_ADDR, WINDOW_SIZE, 0);
-+ if (!ramses_map.map_priv_1) {
-+ printk("Failed to ioremap\n");
-+ return -EIO;
-+ }
-+ mymtd = do_map_probe("cfi_probe", &ramses_map);
-+ if (!mymtd) {
-+ iounmap((void *)ramses_map.map_priv_1);
-+ return -ENXIO;
-+ }
-+ mymtd->module = THIS_MODULE;
-+
-+#ifdef CONFIG_MTD_REDBOOT_PARTS
-+ if (parsed_nr_parts == 0) {
-+ int ret = parse_redboot_partitions(mymtd, &parsed_parts);
-+
-+ if (ret > 0) {
-+ part_type = "RedBoot";
-+ parsed_nr_parts = ret;
-+ }
-+ }
-+#endif
-+
-+ if (parsed_nr_parts > 0) {
-+ parts = parsed_parts;
-+ nb_parts = parsed_nr_parts;
-+ } else {
-+ parts = ramses_partitions;
-+ nb_parts = NB_OF(ramses_partitions);
-+ }
-+ if (nb_parts) {
-+ printk(KERN_NOTICE "Using %s partition definition\n", part_type);
-+ add_mtd_partitions(mymtd, parts, nb_parts);
-+ } else {
-+ add_mtd_device(mymtd);
-+ }
-+ return 0;
-+}
-+
-+static void __exit cleanup_ramses(void)
-+{
-+ if (mymtd) {
-+ del_mtd_partitions(mymtd);
-+ map_destroy(mymtd);
-+ if (parsed_parts)
-+ kfree(parsed_parts);
-+ }
-+ if (ramses_map.map_priv_1)
-+ iounmap((void *)ramses_map.map_priv_1);
-+#ifdef CONFIG_ARCH_RAMSES
-+ FLASH_WRITE_PROTECT_ENABLE();
-+#endif
-+ return;
-+}
-+
-+module_init(init_ramses);
-+module_exit(cleanup_ramses);
-+
---- linux-2.4.21/drivers/net/irda/pxa_ir.c~pxa-irda
-+++ linux-2.4.21/drivers/net/irda/pxa_ir.c
-@@ -38,6 +38,7 @@
- #include <net/irda/wrapper.h>
- #include <net/irda/irda_device.h>
-
-+#include <asm/io.h>
- #include <asm/irq.h>
- #include <asm/dma.h>
- #include <asm/hardware.h>
-@@ -786,6 +787,7 @@
- * Suspend the IrDA interface.
- */
-
-+/*
- static int pxa250_irda_shutdown(struct pxa250_irda *si)
- {
-
-@@ -793,6 +795,7 @@
- return 0;
-
- }
-+*/
-
-
- static int pxa250_irda_suspend(struct net_device *dev, int state)
-@@ -1141,11 +1144,11 @@
- /* allocate consistent buffers for dma access
- * buffers have to be aligned and situated in dma capable memory region;
- */
-- si->rxbuf_dma_virt = consistent_alloc(GFP_KERNEL | GFP_DMA ,HPSIR_MAX_RXLEN , &si->rxbuf_dma);
-+ si->rxbuf_dma_virt = consistent_alloc(GFP_KERNEL | GFP_DMA ,HPSIR_MAX_RXLEN , &si->rxbuf_dma, 0);
- if (! si->rxbuf_dma_virt )
- goto err_rxbuf_dma;
-
-- si->txbuf_dma_virt = consistent_alloc(GFP_KERNEL | GFP_DMA, HPSIR_MAX_TXLEN, &si->txbuf_dma);
-+ si->txbuf_dma_virt = consistent_alloc(GFP_KERNEL | GFP_DMA, HPSIR_MAX_TXLEN, &si->txbuf_dma, 0);
- if (! si->txbuf_dma_virt )
- goto err_txbuf_dma;
-
---- linux-2.4.21/drivers/net/smc91x.c~pxa-smc91x
-+++ linux-2.4.21/drivers/net/smc91x.c
-@@ -46,10 +46,13 @@
- . 12/20/01 Jeff Sutherland initial port to Xscale PXA with DMA support
- . 04/07/03 Nicolas Pitre unified SMC91x driver, killed irq races,
- . more bus abstraction, big cleanup, etc.
-+ . 20/08/03 Holger Schurig add ethtool support
- ----------------------------------------------------------------------------*/
-
-+#define DRV_NAME "smc91x"
-+
- static const char version[] =
-- "smc91x.c: v1.0, mar 07 2003 by Nicolas Pitre <nico@cam.org>\n";
-+ DRV_NAME ": v1.1 Aug 20 2003 by Nicolas Pitre <nico@cam.org>\n";
-
- /* Debugging level */
- #ifndef SMC_DEBUG
-@@ -67,6 +70,7 @@
- #include <linux/timer.h>
- #include <linux/errno.h>
- #include <linux/ioport.h>
-+#include <linux/ethtool.h>
-
- #include <linux/netdevice.h>
- #include <linux/etherdevice.h>
-@@ -78,6 +82,7 @@
- #include <asm/io.h>
- #include <asm/hardware.h>
- #include <asm/irq.h>
-+#include <asm/uaccess.h>
-
- #include "smc91x.h"
-
-@@ -105,7 +110,7 @@
- static int irq = SMC_IRQ;
-
- #ifndef SMC_NOWAIT
--# define SMC_NOWAIT 0
-+# define SMC_NOWAIT 1
- #endif
- static int nowait = SMC_NOWAIT;
-
-@@ -116,6 +121,11 @@
- MODULE_PARM_DESC(irq, "IRQ number");
- MODULE_PARM_DESC(nowait, "set to 1 for no wait state");
-
-+static int
-+smc_read_phy_register(unsigned long ioaddr, int phyaddr, int phyreg);
-+static void
-+smc_write_phy_register( unsigned long ioaddr, int phyaddr,
-+ int phyreg, int phydata );
-
- /*------------------------------------------------------------------------
- .
-@@ -143,7 +153,12 @@
- . but to the expense of reduced TX throughput and increased IRQ overhead.
- . Note this is not a cure for a too slow data bus or too high IRQ latency.
- */
--#define THROTTLE_TX_PKTS 0
-+#define THROTTLE_TX_PKTS 1
-+
-+/*
-+ . This defines if we want to compile ethtool support into the driver
-+*/
-+#define WITH_ETHTOOL 1
-
-
- /* store this information for the driver.. */
-@@ -310,14 +325,14 @@
- if (nowait)
- SMC_SET_CONFIG( SMC_GET_CONFIG() | CONFIG_NO_WAIT );
-
--#ifdef POWER_DOWN
-+#if POWER_DOWN
- /* Release from possible power-down state */
- /* Configuration register is not affected by Soft Reset */
- SMC_SELECT_BANK( 1 );
- SMC_SET_CONFIG( SMC_GET_CONFIG() | CONFIG_EPH_POWER_EN );
- status = smc_read_phy_register(ioaddr, phyaddr, PHY_CNTL_REG);
- status &= ~PHY_CNTL_PDN;
-- smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG);
-+ smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG, status);
- #endif
-
- /* this should pause enough for the chip to be happy */
-@@ -390,10 +405,10 @@
- SMC_SET_RCR( RCR_CLEAR );
- SMC_SET_TCR( TCR_CLEAR );
-
--#ifdef POWER_DOWN
-+#if POWER_DOWN
- status = smc_read_phy_register(ioaddr, phyaddr, PHY_CNTL_REG);
- status |= PHY_CNTL_PDN;
-- smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG);
-+ smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG, status);
-
- /* finally, shut the chip down */
- SMC_SELECT_BANK( 1 );
-@@ -1628,14 +1643,18 @@
- // Setup the default Register Modes
- lp->tcr_cur_mode = TCR_DEFAULT;
- lp->rcr_cur_mode = RCR_DEFAULT;
-- lp->rpc_cur_mode = RPC_DEFAULT;
-
- /* Set default parameters */
- #ifdef CONFIG_ARCH_RAMSES
-- lp->ctl_autoneg = 0;
-- lp->ctl_rfduplx = 0;
-+ lp->rpc_cur_mode = (RPC_ANEG | (RPC_LED_10 << RPC_LSXA_SHFT) | (RPC_LED_TX_RX << RPC_LSXB_SHFT) | RPC_DPLX);
-+
-+ // 10 MBit/S, auto-negotiation only for 10 MB/s
-+ lp->ctl_autoneg = 1;
-+ lp->ctl_rfduplx = 1;
- lp->ctl_rspeed = 10;
- #else
-+ lp->rpc_cur_mode = RPC_DEFAULT;
-+
- lp->ctl_autoneg = 1;
- lp->ctl_rfduplx = 1;
- lp->ctl_rspeed = 100;
-@@ -1680,6 +1699,127 @@
- return 0;
- }
-
-+/*----------------------------------------------------
-+ . smc_ioctl
-+ .
-+ . This ioctl is currently only used by ethtool(8) to
-+ . access the serial EEPROM
-+ -----------------------------------------------------*/
-+
-+#if WITH_ETHTOOL
-+
-+#define SMC91x_EEPROM_SIZE (0x40*2)
-+
-+u16 smc_eeprom_read(long ioaddr, u16 location)
-+{
-+ u16 val;
-+ u16 oldBank;
-+ u16 oldPtr;
-+
-+ cli();
-+ // Save chip settings
-+ oldBank = SMC_CURRENT_BANK();
-+ SMC_SELECT_BANK( 2 );
-+ oldPtr = SMC_GET_PTR();
-+
-+ // Set location in EEPROM to be read
-+ SMC_SET_PTR(location);
-+
-+ // Set EEPROM_SELECT and RELOAD bits in control register
-+ SMC_SELECT_BANK( 1 );
-+ val = SMC_GET_CTL();
-+ SMC_SET_CTL(val | CTL_EEPROM_SELECT | CTL_RELOAD);
-+
-+ // Wait until RELEAD is finished
-+ while (SMC_GET_CTL() & CTL_RELOAD) ;
-+
-+ // Get EEPROM data
-+ val = SMC_inw(ioaddr, GP_REG);
-+
-+ // Restore chip settings
-+ SMC_SELECT_BANK( 2 );
-+ SMC_SET_PTR(oldPtr);
-+ SMC_SELECT_BANK( oldBank );
-+ sti();
-+
-+ return val;
-+}
-+
-+static int smc_get_eeprom(struct net_device *dev, u8 *buf)
-+{
-+ int i;
-+ u16 *ebuf = (u16 *)buf;
-+
-+ for (i = 0; i < SMC91x_EEPROM_SIZE/2; i++) {
-+ ebuf[i] = smc_eeprom_read(dev->base_addr, i);
-+ }
-+ return 0;
-+}
-+
-+static int smc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-+{
-+ u32 etcmd;
-+ int ret = -EINVAL;
-+
-+ if (cmd != SIOCETHTOOL)
-+ return -EOPNOTSUPP;
-+
-+ if (get_user(etcmd, (u32 *)rq->ifr_data))
-+ return -EFAULT;
-+
-+ switch (etcmd) {
-+
-+ /* Get driver info */
-+ case ETHTOOL_GDRVINFO: {
-+ struct ethtool_drvinfo edrv;
-+
-+ memset(&edrv, 0, sizeof(edrv));
-+ edrv.cmd = etcmd;
-+ strcpy(edrv.driver, DRV_NAME);
-+ sprintf(edrv.bus_info, "ISA:%8.8lx:%d", dev->base_addr, dev->irq);
-+ edrv.eedump_len = SMC91x_EEPROM_SIZE;
-+ ret = copy_to_user(rq->ifr_data, &edrv, sizeof(edrv)) ? -EFAULT : 0;
-+ break;
-+ }
-+
-+ /* Get EEPROM data */
-+ case ETHTOOL_GEEPROM: {
-+ struct ethtool_eeprom eeprom;
-+ u8 eebuf[SMC91x_EEPROM_SIZE];
-+ int r;
-+
-+ if (copy_from_user(&eeprom, rq->ifr_data, sizeof(eeprom)))
-+ return -EFAULT;
-+
-+ if (eeprom.offset > eeprom.offset+eeprom.len)
-+ return -EINVAL;
-+
-+ if ((eeprom.offset+eeprom.len) > SMC91x_EEPROM_SIZE) {
-+ eeprom.len = SMC91x_EEPROM_SIZE-eeprom.offset;
-+ }
-+ eeprom.magic = 0;
-+ if (copy_to_user(rq->ifr_data, &eeprom, sizeof(eeprom)))
-+ return -EFAULT;
-+
-+ rq->ifr_data += offsetof(struct ethtool_eeprom, data);
-+
-+ r = smc_get_eeprom(dev, eebuf);
-+
-+ if (r)
-+ return r;
-+ if (copy_to_user(rq->ifr_data, eebuf+eeprom.offset, eeprom.len))
-+ return -EFAULT;
-+ return 0;
-+
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+#endif
-+
-+
- /*------------------------------------------------------------
- . Get the current statistics.
- . This may be called with the card open or closed.
-@@ -1925,6 +2065,9 @@
- dev->watchdog_timeo = HZ/10;
- dev->get_stats = smc_query_statistics;
- dev->set_multicast_list = smc_set_multicast_list;
-+#if WITH_ETHTOOL
-+ dev->do_ioctl = smc_ioctl;
-+#endif
-
- return 0;
-
-@@ -1961,12 +2104,17 @@
- smc_shutdown(global_dev);
- break;
- case PM_RESUME:
-+ udelay(5000);
- smc_reset(global_dev);
- smc_enable(global_dev);
- SMC_SELECT_BANK( 1 );
- SMC_SET_MAC_ADDR(global_dev->dev_addr);
-- if (lp->version >= 0x70)
-- smc_phy_configure(global_dev);
-+ if (global_dev->flags & IFF_UP) {
-+ if (lp->version >= 0x70)
-+ smc_phy_configure(global_dev);
-+ } else {
-+ smc_shutdown(global_dev);
-+ }
- break;
- }
- return 0;
-@@ -2054,6 +2202,15 @@
- int ioaddr = RAMSES_ETH_BASE + 0x300;
- global_dev->irq = SMC_IRQ;
- ret = smc_probe(global_dev, ioaddr);
-+#ifdef POWER_DOWN
-+ smc_shutdown(global_dev);
-+#endif
-+ }
-+#elif defined(CONFIG_ARCH_RAMSES)
-+ {
-+ int ioaddr = RAMSES_ETH_BASE + 0x300;
-+ global_dev->irq = SMC_IRQ;
-+ ret = smc_probe(global_dev, ioaddr);
- }
- #else
- if (global_dev->base_addr == -1) {
-@@ -2083,7 +2240,11 @@
- #ifdef CONFIG_PM
- if (ret == 0) {
- struct smc_local *lp = (struct smc_local *)global_dev->priv;
-+#ifdef PM_DEBUG
-+ lp->pm = pm_register(PM_SYS_UNKNOWN, 0x73393178, smc_pm_callback, "smc91x");
-+#else
- lp->pm = pm_register(PM_SYS_UNKNOWN, 0x73393178, smc_pm_callback);
-+#endif
- }
- #endif
-
---- linux-2.4.21/drivers/net/smc91x.h~ramses-smc91x
-+++ linux-2.4.21/drivers/net/smc91x.h
-@@ -79,6 +79,11 @@
- #include <asm/arch/ramses.h>
- #define SMC_IOADDR (RAMSES_ETH_PHYS + 0x300)
- #define SMC_IRQ ETHERNET_IRQ
-+
-+#elif CONFIG_ARCH_RAMSES
-+#include <asm/arch/ramses.h>
-+#define SMC_IOADDR (RAMSES_ETH_PHYS + 0x300)
-+#define SMC_IRQ ETHERNET_IRQ
- #endif
-
- #define SMC_CAN_USE_8BIT 1
---- linux-2.4.21/drivers/net/wireless/hermes.c~orinoco013e
-+++ linux-2.4.21/drivers/net/wireless/hermes.c
-@@ -52,7 +52,6 @@
-
- #include "hermes.h"
-
--static char version[] __initdata = "hermes.c: 4 Dec 2002 David Gibson <hermes@gibson.dropbear.id.au>";
- MODULE_DESCRIPTION("Low-level driver helper for Lucent Hermes chipset and Prism II HFA384x wireless MAC controller");
- MODULE_AUTHOR("David Gibson <hermes@gibson.dropbear.id.au>");
- #ifdef MODULE_LICENSE
-@@ -226,7 +225,8 @@
- * Returns: < 0 on internal error, 0 on success, > 0 on error returned by the firmware
- *
- * Callable from any context, but locking is your problem. */
--int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, hermes_response_t *resp)
-+int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
-+ hermes_response_t *resp)
- {
- int err;
- int k;
-@@ -469,13 +469,17 @@
-
- err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS, rid, NULL);
- if (err)
-- goto out;
-+ return err;
-
- err = hermes_bap_seek(hw, bap, rid, 0);
- if (err)
-- goto out;
-+ return err;
-
- rlength = hermes_read_reg(hw, dreg);
-+
-+ if (! rlength)
-+ return -ENOENT;
-+
- rtype = hermes_read_reg(hw, dreg);
-
- if (length)
-@@ -495,8 +499,7 @@
- nwords = min((unsigned)rlength - 1, bufsize / 2);
- hermes_read_words(hw, dreg, buf, nwords);
-
-- out:
-- return err;
-+ return 0;
- }
-
- int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
-@@ -511,7 +514,7 @@
-
- err = hermes_bap_seek(hw, bap, rid, 0);
- if (err)
-- goto out;
-+ return err;
-
- hermes_write_reg(hw, dreg, length);
- hermes_write_reg(hw, dreg, rid);
-@@ -523,7 +526,6 @@
- err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE,
- rid, NULL);
-
-- out:
- return err;
- }
-
-@@ -539,9 +541,12 @@
-
- static int __init init_hermes(void)
- {
-- printk(KERN_DEBUG "%s\n", version);
--
- return 0;
- }
-
-+static void __exit exit_hermes(void)
-+{
-+}
-+
- module_init(init_hermes);
-+module_exit(exit_hermes);
---- linux-2.4.21/drivers/net/wireless/hermes.h~orinoco013e
-+++ linux-2.4.21/drivers/net/wireless/hermes.h
-@@ -250,7 +250,6 @@
- u16 scanreason; /* ??? */
- struct hermes_scan_apinfo aps[35]; /* Scan result */
- } __attribute__ ((packed));
--
- #define HERMES_LINKSTATUS_NOT_CONNECTED (0x0000)
- #define HERMES_LINKSTATUS_CONNECTED (0x0001)
- #define HERMES_LINKSTATUS_DISCONNECTED (0x0002)
-@@ -278,7 +277,7 @@
-
- /* Basic control structure */
- typedef struct hermes {
-- ulong iobase;
-+ unsigned long iobase;
- int io_space; /* 1 if we IO-mapped IO, 0 for memory-mapped IO? */
- #define HERMES_IO 1
- #define HERMES_MEM 0
-@@ -368,7 +367,7 @@
- if (hw->io_space) {
- insw(hw->iobase + off, buf, count);
- } else {
-- int i;
-+ unsigned i;
- u16 *p;
-
- /* This needs to *not* byteswap (like insw()) but
-@@ -388,7 +387,7 @@
- if (hw->io_space) {
- outsw(hw->iobase + off, buf, count);
- } else {
-- int i;
-+ unsigned i;
- const u16 *p;
-
- /* This needs to *not* byteswap (like outsw()) but
-@@ -398,6 +397,21 @@
- for (i = 0, p = buf; i < count; i++) {
- writew(le16_to_cpu(*p++), hw->iobase + off);
- }
-+ }
-+}
-+
-+static inline void hermes_clear_words(struct hermes *hw, int off, unsigned count)
-+{
-+ unsigned i;
-+
-+ off = off << hw->reg_spacing;;
-+
-+ if (hw->io_space) {
-+ for (i = 0; i < count; i++)
-+ outw(0, hw->iobase + off);
-+ } else {
-+ for (i = 0; i < count; i++)
-+ writew(0, hw->iobase + off);
- }
- }
-
---- linux-2.4.21/drivers/net/wireless/ieee802_11.h~orinoco013e
-+++ linux-2.4.21/drivers/net/wireless/ieee802_11.h
-@@ -9,6 +9,8 @@
- bytes is allowed, which is a bit confusing, I suspect this
- represents the 2304 bytes of real data, plus a possible 8 bytes of
- WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
-+
-+
- #define IEEE802_11_HLEN 30
- #define IEEE802_11_FRAME_LEN (IEEE802_11_DATA_LEN + IEEE802_11_HLEN)
-
---- linux-2.4.21/drivers/net/wireless/orinoco.c~orinoco013e
-+++ linux-2.4.21/drivers/net/wireless/orinoco.c
-@@ -1,4 +1,4 @@
--/* orinoco.c 0.13b - (formerly known as dldwd_cs.c and orinoco_cs.c)
-+/* orinoco.c 0.13e - (formerly known as dldwd_cs.c and orinoco_cs.c)
- *
- * A driver for Hermes or Prism 2 chipset based PCMCIA wireless
- * adaptors, with Lucent/Agere, Intersil or Symbol firmware.
-@@ -117,7 +117,7 @@
- * o Init of priv->tx_rate_ctrl in firmware specific section.
- * o Prism2/Symbol rate, upto should be 0xF and not 0x15. Doh !
- * o Spectrum card always need cor_reset (for every reset)
-- * o Fix cor_reset to not loose bit 7 in the register
-+ * o Fix cor_reset to not lose bit 7 in the register
- * o flush_stale_links to remove zombie Pcmcia instances
- * o Ack previous hermes event before reset
- * Me (with my little hands)
-@@ -289,7 +289,7 @@
- * which are used as the dev->open, dev->stop, priv->reset
- * callbacks if none are specified when alloc_orinocodev() is
- * called.
-- * o Removed orinoco_plx_interupt() and orinoco_pci_interrupt().
-+ * o Removed orinoco_plx_interrupt() and orinoco_pci_interrupt().
- * They didn't do anything.
- *
- * v0.12 -> v0.12a - 4 Jul 2002 - David Gibson
-@@ -345,13 +345,54 @@
- * we are connected (avoids cofusing the firmware), and only
- * give LINKSTATUS printk()s if the status has changed.
- *
-+ * v0.13b -> v0.13c - 11 Mar 2003 - David Gibson
-+ * o Cleanup: use dev instead of priv in various places.
-+ * o Bug fix: Don't ReleaseConfiguration on RESET_PHYSICAL event
-+ * if we're in the middle of a (driver initiated) hard reset.
-+ * o Bug fix: ETH_ZLEN is supposed to include the header
-+ * (Dionysus Blazakis & Manish Karir)
-+ * o Convert to using workqueues instead of taskqueues (and
-+ * backwards compatibility macros for pre 2.5.41 kernels).
-+ * o Drop redundant (I think...) MOD_{INC,DEC}_USE_COUNT in
-+ * airport.c
-+ * o New orinoco_tmd.c init module from Joerg Dorchain for
-+ * TMD7160 based PCI to PCMCIA bridges (similar to
-+ * orinoco_plx.c).
-+ *
-+ * v0.13c -> v0.13d - 22 Apr 2003 - David Gibson
-+ * o Make hw_unavailable a counter, rather than just a flag, this
-+ * is necessary to avoid some races (such as a card being
-+ * removed in the middle of orinoco_reset().
-+ * o Restore Release/RequestConfiguration in the PCMCIA event handler
-+ * when dealing with a driver initiated hard reset. This is
-+ * necessary to prevent hangs due to a spurious interrupt while
-+ * the reset is in progress.
-+ * o Clear the 802.11 header when transmitting, even though we
-+ * don't use it. This fixes a long standing bug on some
-+ * firmwares, which seem to get confused if that isn't done.
-+ * o Be less eager to de-encapsulate SNAP frames, only do so if
-+ * the OUI is 00:00:00 or 00:00:f8, leave others alone. The old
-+ * behaviour broke CDP (Cisco Discovery Protocol).
-+ * o Use dev instead of priv for free_irq() as well as
-+ * request_irq() (oops).
-+ * o Attempt to reset rather than giving up if we get too many
-+ * IRQs.
-+ * o Changed semantics of __orinoco_down() so it can be called
-+ * safely with hw_unavailable set. It also now clears the
-+ * linkstatus (since we're going to have to reassociate).
-+ *
-+ * v0.13d -> v0.13e - 12 May 2003 - David Gibson
-+ * o Support for post-2.5.68 return values from irq handler.
-+ * o Fixed bug where underlength packets would be double counted
-+ * in the rx_dropped statistics.
-+ * o Provided a module parameter to suppress linkstatus messages.
-+ *
- * TODO
--
- * o New wireless extensions API (patch from Moustafa
-- * Youssef, updated by Jim Carter).
-- * o Fix PCMCIA hard resets with pcmcia-cs.
-+ * Youssef, updated by Jim Carter and Pavel Roskin).
- * o Handle de-encapsulation within network layer, provide 802.11
- * headers (patch from Thomas 'Dent' Mirlacher)
-+ * o RF monitor mode support
- * o Fix possible races in SPY handling.
- * o Disconnect wireless extensions from fundamental configuration.
- * o (maybe) Software WEP support (patch from Stano Meduna).
-@@ -373,27 +414,27 @@
- * flag after taking the lock, and if it is set, give up on whatever
- * they are doing and drop the lock again. The orinoco_lock()
- * function handles this (it unlocks and returns -EBUSY if
-- * hw_unavailable is true). */
-+ * hw_unavailable is non-zero). */
-
- #include <linux/config.h>
-
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
--#include <linux/sched.h>
- #include <linux/ptrace.h>
- #include <linux/slab.h>
- #include <linux/string.h>
- #include <linux/timer.h>
- #include <linux/ioport.h>
--#include <asm/uaccess.h>
--#include <asm/io.h>
--#include <asm/system.h>
- #include <linux/netdevice.h>
- #include <linux/if_arp.h>
- #include <linux/etherdevice.h>
- #include <linux/wireless.h>
-
-+#include <asm/uaccess.h>
-+#include <asm/io.h>
-+#include <asm/system.h>
-+
- #include "hermes.h"
- #include "hermes_rid.h"
- #include "orinoco.h"
-@@ -416,6 +457,9 @@
- EXPORT_SYMBOL(orinoco_debug);
- #endif
-
-+static int suppress_linkstatus; /* = 0 */
-+MODULE_PARM(suppress_linkstatus, "i");
-+
- /********************************************************************/
- /* Compile time configuration and compatibility stuff */
- /********************************************************************/
-@@ -443,8 +487,10 @@
- #define USER_BAP 0
- #define IRQ_BAP 1
- #define MAX_IRQLOOPS_PER_IRQ 10
--#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of how many events the
-- device could legitimately generate */
-+#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of
-+ * how many events the
-+ * device could
-+ * legitimately generate */
- #define SMALL_KEY_SIZE 5
- #define LARGE_KEY_SIZE 13
- #define TX_NICBUF_SIZE_BUG 1585 /* Bug in Symbol firmware */
-@@ -480,8 +526,8 @@
- {10, 1, 1, 1},
- {20, 0, 2, 2},
- {20, 1, 6, 3},
-- {55, 0, 4, 4},
-- {55, 1, 7, 7},
-+ {55, 0, 4, 4},
-+ {55, 1, 7, 7},
- {110, 0, 5, 8},
- };
- #define BITRATE_TABLE_SIZE (sizeof(bitrate_table) / sizeof(bitrate_table[0]))
-@@ -522,7 +568,7 @@
-
- /* Hardware control routines */
-
--static int __orinoco_program_rids(struct orinoco_private *priv);
-+static int __orinoco_program_rids(struct net_device *dev);
-
- static int __orinoco_hw_set_bitrate(struct orinoco_private *priv);
- static int __orinoco_hw_setup_wep(struct orinoco_private *priv);
-@@ -535,37 +581,17 @@
- static void __orinoco_set_multicast_list(struct net_device *dev);
-
- /* Interrupt handling routines */
--static void __orinoco_ev_tick(struct orinoco_private *priv, hermes_t *hw);
--static void __orinoco_ev_wterr(struct orinoco_private *priv, hermes_t *hw);
--static void __orinoco_ev_infdrop(struct orinoco_private *priv, hermes_t *hw);
--static void __orinoco_ev_info(struct orinoco_private *priv, hermes_t *hw);
--static void __orinoco_ev_rx(struct orinoco_private *priv, hermes_t *hw);
--static void __orinoco_ev_txexc(struct orinoco_private *priv, hermes_t *hw);
--static void __orinoco_ev_tx(struct orinoco_private *priv, hermes_t *hw);
--static void __orinoco_ev_alloc(struct orinoco_private *priv, hermes_t *hw);
-+static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw);
-+static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw);
-+static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw);
-+static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw);
-+static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw);
-+static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw);
-+static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw);
-+static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw);
-
- /* ioctl() routines */
--static int orinoco_ioctl_getiwrange(struct net_device *dev, struct iw_point *rrq);
--static int orinoco_ioctl_setiwencode(struct net_device *dev, struct iw_point *erq);
--static int orinoco_ioctl_getiwencode(struct net_device *dev, struct iw_point *erq);
--static int orinoco_ioctl_setessid(struct net_device *dev, struct iw_point *erq);
--static int orinoco_ioctl_getessid(struct net_device *dev, struct iw_point *erq);
--static int orinoco_ioctl_setnick(struct net_device *dev, struct iw_point *nrq);
--static int orinoco_ioctl_getnick(struct net_device *dev, struct iw_point *nrq);
--static int orinoco_ioctl_setfreq(struct net_device *dev, struct iw_freq *frq);
--static int orinoco_ioctl_getsens(struct net_device *dev, struct iw_param *srq);
--static int orinoco_ioctl_setsens(struct net_device *dev, struct iw_param *srq);
--static int orinoco_ioctl_setrts(struct net_device *dev, struct iw_param *rrq);
--static int orinoco_ioctl_setfrag(struct net_device *dev, struct iw_param *frq);
--static int orinoco_ioctl_getfrag(struct net_device *dev, struct iw_param *frq);
--static int orinoco_ioctl_setrate(struct net_device *dev, struct iw_param *frq);
--static int orinoco_ioctl_getrate(struct net_device *dev, struct iw_param *frq);
--static int orinoco_ioctl_setpower(struct net_device *dev, struct iw_param *prq);
--static int orinoco_ioctl_getpower(struct net_device *dev, struct iw_param *prq);
--static int orinoco_ioctl_setport3(struct net_device *dev, struct iwreq *wrq);
--static int orinoco_ioctl_getport3(struct net_device *dev, struct iwreq *wrq);
--
--static int orinoco_debug_dump_recs(struct orinoco_private *priv);
-+static int orinoco_debug_dump_recs(struct net_device *dev);
-
- /********************************************************************/
- /* Function prototypes */
-@@ -577,7 +603,7 @@
- struct hermes *hw = &priv->hw;
- int err;
-
-- err = __orinoco_program_rids(priv);
-+ err = __orinoco_program_rids(dev);
- if (err) {
- printk(KERN_ERR "%s: Error %d configuring card\n",
- dev->name, err);
-@@ -606,14 +632,25 @@
-
- netif_stop_queue(dev);
-
-- err = hermes_disable_port(hw, 0);
-- if (err) {
-- printk(KERN_ERR "%s: Error %d disabling MAC port\n",
-- dev->name, err);
-- return err;
-+ if (! priv->hw_unavailable) {
-+ if (! priv->broken_disableport) {
-+ err = hermes_disable_port(hw, 0);
-+ if (err) {
-+ /* Some firmwares (e.g. Intersil 1.3.x) seem
-+ * to have problems disabling the port, oh
-+ * well, too bad. */
-+ printk(KERN_WARNING "%s: Error %d disabling MAC port\n",
-+ dev->name, err);
-+ priv->broken_disableport = 1;
-+ }
-+ }
-+ hermes_set_irqmask(hw, 0);
-+ hermes_write_regn(hw, EVACK, 0xffff);
- }
-- hermes_set_irqmask(hw, 0);
-- hermes_write_regn(hw, EVACK, 0xffff);
-+
-+ /* firmware will have to reassociate */
-+ priv->last_linkstatus = 0xffff;
-+ priv->connected = 0;
-
- return 0;
- }
-@@ -656,38 +693,38 @@
- if (err)
- return err;
-
-- priv->open = 1;
--
- err = __orinoco_up(dev);
-
-+ if (! err)
-+ priv->open = 1;
-+
- orinoco_unlock(priv, &flags);
-
- return err;
- }
-
--static int orinoco_stop(struct net_device *dev)
-+int orinoco_stop(struct net_device *dev)
- {
- struct orinoco_private *priv = dev->priv;
- int err = 0;
-
- /* We mustn't use orinoco_lock() here, because we need to be
-- able to close the interface, even if hw_unavailable is set
-+ able to close the interface even if hw_unavailable is set
- (e.g. as we're released after a PC Card removal) */
- spin_lock_irq(&priv->lock);
-
- priv->open = 0;
-
-- if (! priv->hw_unavailable)
-- err = __orinoco_down(dev);
-+ err = __orinoco_down(dev);
-
- spin_unlock_irq(&priv->lock);
-
- return err;
- }
-
--static int __orinoco_program_rids(struct orinoco_private *priv)
-+static int __orinoco_program_rids(struct net_device *dev)
- {
-- struct net_device *dev = priv->ndev;
-+ struct orinoco_private *priv = dev->priv;
- hermes_t *hw = &priv->hw;
- int err;
- struct hermes_idstring idbuf;
-@@ -873,51 +910,84 @@
- }
-
- /* xyzzy */
--static int orinoco_reconfigure(struct orinoco_private *priv)
-+static int orinoco_reconfigure(struct net_device *dev)
- {
-+ struct orinoco_private *priv = dev->priv;
- struct hermes *hw = &priv->hw;
- unsigned long flags;
- int err = 0;
-
-- orinoco_lock(priv, &flags);
-+ if (priv->broken_disableport) {
-+ schedule_work(&priv->reset_work);
-+ return 0;
-+ }
-+
-+ err = orinoco_lock(priv, &flags);
-+ if (err)
-+ return err;
-
-+
- err = hermes_disable_port(hw, 0);
- if (err) {
-- printk(KERN_ERR "%s: Unable to disable port in orinco_reconfigure()\n",
-- priv->ndev->name);
-+ printk(KERN_WARNING "%s: Unable to disable port while reconfiguring card\n",
-+ dev->name);
-+ priv->broken_disableport = 1;
- goto out;
- }
-
-- err = __orinoco_program_rids(priv);
-- if (err)
-+ err = __orinoco_program_rids(dev);
-+ if (err) {
-+ printk(KERN_WARNING "%s: Unable to reconfigure card\n",
-+ dev->name);
- goto out;
-+ }
-
- err = hermes_enable_port(hw, 0);
- if (err) {
-- printk(KERN_ERR "%s: Unable to enable port in orinco_reconfigure()\n",
-- priv->ndev->name);
-+ printk(KERN_WARNING "%s: Unable to enable port while reconfiguring card\n",
-+ dev->name);
- goto out;
- }
-
- out:
-+ if (err) {
-+ printk(KERN_WARNING "%s: Resetting instead...\n", dev->name);
-+ schedule_work(&priv->reset_work);
-+ err = 0;
-+ }
-+
- orinoco_unlock(priv, &flags);
- return err;
-
- }
-
- /* This must be called from user context, without locks held - use
-- * schedule_task() */
-+ * schedule_work() */
- static void orinoco_reset(struct net_device *dev)
- {
- struct orinoco_private *priv = dev->priv;
-+ struct hermes *hw = &priv->hw;
- int err;
- unsigned long flags;
-
- err = orinoco_lock(priv, &flags);
- if (err)
-+ /* When the hardware becomes available again, whatever
-+ * detects that is responsible for re-initializing
-+ * it. So no need for anything further*/
- return;
-
-- priv->hw_unavailable = 1;
-+ netif_stop_queue(dev);
-+
-+ /* Shut off interrupts. Depending on what state the hardware
-+ * is in, this might not work, but we'll try anyway */
-+ hermes_set_irqmask(hw, 0);
-+ hermes_write_regn(hw, EVACK, 0xffff);
-+
-+ priv->hw_unavailable++;
-+ priv->last_linkstatus = 0xffff; /* firmware will have to reassociate */
-+ priv->connected = 0;
-+
- orinoco_unlock(priv, &flags);
-
- if (priv->hard_reset)
-@@ -936,18 +1006,22 @@
- return;
- }
-
-- spin_lock_irqsave(&priv->lock, flags);
-+ spin_lock_irq(&priv->lock); /* This has to be called from user context */
-
-- priv->hw_unavailable = 0;
-+ priv->hw_unavailable--;
-
-- err = __orinoco_up(dev);
-- if (err) {
-- printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
-- dev->name, err);
-- } else
-- dev->trans_start = jiffies;
-+ /* priv->open or priv->hw_unavailable might have changed while
-+ * we dropped the lock */
-+ if (priv->open && (! priv->hw_unavailable)) {
-+ err = __orinoco_up(dev);
-+ if (err) {
-+ printk(KERN_ERR "%s: orinoco_reset: Error %d reenabling card\n",
-+ dev->name, err);
-+ } else
-+ dev->trans_start = jiffies;
-+ }
-
-- orinoco_unlock(priv, &flags);
-+ spin_unlock_irq(&priv->lock);
-
- return;
- }
-@@ -979,10 +1053,18 @@
- }
- }
-
-+/* Does the frame have a SNAP header indicating it should be
-+ * de-encapsulated to Ethernet-II? */
- static inline int
--is_snap(struct header_struct *hdr)
-+is_ethersnap(struct header_struct *hdr)
- {
-- return (hdr->dsap == 0xAA) && (hdr->ssap == 0xAA) && (hdr->ctrl == 0x3);
-+ /* We de-encapsulate all packets which, a) have SNAP headers
-+ * (i.e. SSAP=DSAP=0xaa and CTRL=0x3 in the 802.2 LLC header
-+ * and where b) the OUI of the SNAP header is 00:00:00 or
-+ * 00:00:f8 - we need both because different APs appear to use
-+ * different OUIs for some reason */
-+ return (memcmp(&hdr->dsap, &encaps_hdr, 5) == 0)
-+ && ( (hdr->oui[2] == 0x00) || (hdr->oui[2] == 0xf8) );
- }
-
- static void
-@@ -1140,7 +1222,8 @@
- return 0;
- }
-
--static int orinoco_hw_get_bssid(struct orinoco_private *priv, char buf[ETH_ALEN])
-+static int orinoco_hw_get_bssid(struct orinoco_private *priv,
-+ char buf[ETH_ALEN])
- {
- hermes_t *hw = &priv->hw;
- int err = 0;
-@@ -1159,7 +1242,7 @@
- }
-
- static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
-- char buf[IW_ESSID_MAX_SIZE+1])
-+ char buf[IW_ESSID_MAX_SIZE+1])
- {
- hermes_t *hw = &priv->hw;
- int err = 0;
-@@ -1236,9 +1319,8 @@
- }
-
- if ( (channel < 1) || (channel > NUM_CHANNELS) ) {
-- struct net_device *dev = priv->ndev;
--
-- printk(KERN_WARNING "%s: Channel out of range (%d)!\n", dev->name, channel);
-+ printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
-+ priv->ndev->name, channel);
- err = -EBUSY;
- goto out;
-
-@@ -1253,8 +1335,8 @@
- return err ? err : freq;
- }
-
--static int orinoco_hw_get_bitratelist(struct orinoco_private *priv, int *numrates,
-- s32 *rates, int max)
-+static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
-+ int *numrates, s32 *rates, int max)
- {
- hermes_t *hw = &priv->hw;
- struct hermes_idstring list;
-@@ -1287,9 +1369,6 @@
- }
-
- #if 0
--#ifndef ORINOCO_DEBUG
--static inline void show_rx_frame(struct orinoco_rxframe_hdr *frame) {}
--#else
- static void show_rx_frame(struct orinoco_rxframe_hdr *frame)
- {
- printk(KERN_DEBUG "RX descriptor:\n");
-@@ -1346,17 +1425,16 @@
- frame->p8022.oui[0], frame->p8022.oui[1], frame->p8022.oui[2]);
- printk(KERN_DEBUG " ethertype = 0x%04x\n", frame->ethertype);
- }
--#endif
--#endif
-+#endif /* 0 */
-
- /*
- * Interrupt handler
- */
--void orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+irqreturn_t orinoco_interrupt(int irq, void *dev_id, struct pt_regs *regs)
- {
-- struct orinoco_private *priv = (struct orinoco_private *) dev_id;
-+ struct net_device *dev = (struct net_device *)dev_id;
-+ struct orinoco_private *priv = dev->priv;
- hermes_t *hw = &priv->hw;
-- struct net_device *dev = priv->ndev;
- int count = MAX_IRQLOOPS_PER_IRQ;
- u16 evstat, events;
- /* These are used to detect a runaway interrupt situation */
-@@ -1367,12 +1445,17 @@
- unsigned long flags;
-
- if (orinoco_lock(priv, &flags) != 0) {
-- /* If hw is unavailable */
-- return;
-+ /* If hw is unavailable - we don't know if the irq was
-+ * for us or not */
-+ return IRQ_HANDLED;
- }
-
- evstat = hermes_read_regn(hw, EVSTAT);
- events = evstat & hw->inten;
-+ if (! events) {
-+ orinoco_unlock(priv, &flags);
-+ return IRQ_NONE;
-+ }
-
- if (jiffies != last_irq_jiffy)
- loops_this_jiffy = 0;
-@@ -1380,11 +1463,11 @@
-
- while (events && count--) {
- if (++loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY) {
-- printk(KERN_CRIT "%s: IRQ handler is looping too \
--much! Shutting down.\n",
-- dev->name);
-- /* Perform an emergency shutdown */
-+ printk(KERN_WARNING "%s: IRQ handler is looping too "
-+ "much! Resetting.\n", dev->name);
-+ /* Disable interrupts for now */
- hermes_set_irqmask(hw, 0);
-+ schedule_work(&priv->reset_work);
- break;
- }
-
-@@ -1395,21 +1478,21 @@
- }
-
- if (events & HERMES_EV_TICK)
-- __orinoco_ev_tick(priv, hw);
-+ __orinoco_ev_tick(dev, hw);
- if (events & HERMES_EV_WTERR)
-- __orinoco_ev_wterr(priv, hw);
-+ __orinoco_ev_wterr(dev, hw);
- if (events & HERMES_EV_INFDROP)
-- __orinoco_ev_infdrop(priv, hw);
-+ __orinoco_ev_infdrop(dev, hw);
- if (events & HERMES_EV_INFO)
-- __orinoco_ev_info(priv, hw);
-+ __orinoco_ev_info(dev, hw);
- if (events & HERMES_EV_RX)
-- __orinoco_ev_rx(priv, hw);
-+ __orinoco_ev_rx(dev, hw);
- if (events & HERMES_EV_TXEXC)
-- __orinoco_ev_txexc(priv, hw);
-+ __orinoco_ev_txexc(dev, hw);
- if (events & HERMES_EV_TX)
-- __orinoco_ev_tx(priv, hw);
-+ __orinoco_ev_tx(dev, hw);
- if (events & HERMES_EV_ALLOC)
-- __orinoco_ev_alloc(priv, hw);
-+ __orinoco_ev_alloc(dev, hw);
-
- hermes_write_regn(hw, EVACK, events);
-
-@@ -1418,30 +1501,34 @@
- };
-
- orinoco_unlock(priv, &flags);
-+ return IRQ_HANDLED;
- }
-
--static void __orinoco_ev_tick(struct orinoco_private *priv, hermes_t *hw)
-+static void __orinoco_ev_tick(struct net_device *dev, hermes_t *hw)
- {
-- printk(KERN_DEBUG "%s: TICK\n", priv->ndev->name);
-+ printk(KERN_DEBUG "%s: TICK\n", dev->name);
- }
-
--static void __orinoco_ev_wterr(struct orinoco_private *priv, hermes_t *hw)
-+static void __orinoco_ev_wterr(struct net_device *dev, hermes_t *hw)
- {
- /* This seems to happen a fair bit under load, but ignoring it
- seems to work fine...*/
- printk(KERN_DEBUG "%s: MAC controller error (WTERR). Ignoring.\n",
-- priv->ndev->name);
-+ dev->name);
- }
-
--static void __orinoco_ev_infdrop(struct orinoco_private *priv, hermes_t *hw)
-+static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
- {
-- printk(KERN_WARNING "%s: Information frame lost.\n", priv->ndev->name);
-+ printk(KERN_WARNING "%s: Information frame lost.\n", dev->name);
- }
-
- static void print_linkstatus(struct net_device *dev, u16 status)
- {
- char * s;
-
-+ if (suppress_linkstatus)
-+ return;
-+
- switch (status) {
- case HERMES_LINKSTATUS_NOT_CONNECTED:
- s = "Not Connected";
-@@ -1472,9 +1559,9 @@
- dev->name, s, status);
- }
-
--static void __orinoco_ev_info(struct orinoco_private *priv, hermes_t *hw)
-+static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
- {
-- struct net_device *dev = priv->ndev;
-+ struct orinoco_private *priv = dev->priv;
- u16 infofid;
- struct {
- u16 len;
-@@ -1573,9 +1660,9 @@
- }
- }
-
--static void __orinoco_ev_rx(struct orinoco_private *priv, hermes_t *hw)
-+static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
- {
-- struct net_device *dev = priv->ndev;
-+ struct orinoco_private *priv = dev->priv;
- struct net_device_stats *stats = &priv->stats;
- struct iw_statistics *wstats = &priv->wstats;
- struct sk_buff *skb = NULL;
-@@ -1664,14 +1751,13 @@
- * So, check ourselves */
- if(((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
- ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
-- is_snap(&hdr)) {
-+ is_ethersnap(&hdr)) {
- /* These indicate a SNAP within 802.2 LLC within
- 802.11 frame which we'll need to de-encapsulate to
- the original EthernetII frame. */
-
- if (length < ENCAPS_OVERHEAD) { /* No room for full LLC+SNAP */
- stats->rx_length_errors++;
-- stats->rx_dropped++;
- goto drop;
- }
-
-@@ -1726,9 +1812,9 @@
- return;
- }
-
--static void __orinoco_ev_txexc(struct orinoco_private *priv, hermes_t *hw)
-+static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
- {
-- struct net_device *dev = priv->ndev;
-+ struct orinoco_private *priv = dev->priv;
- struct net_device_stats *stats = &priv->stats;
- u16 fid = hermes_read_regn(hw, TXCOMPLFID);
- struct hermes_tx_descriptor desc;
-@@ -1752,8 +1838,9 @@
- hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
- }
-
--static void __orinoco_ev_tx(struct orinoco_private *priv, hermes_t *hw)
-+static void __orinoco_ev_tx(struct net_device *dev, hermes_t *hw)
- {
-+ struct orinoco_private *priv = dev->priv;
- struct net_device_stats *stats = &priv->stats;
-
- stats->tx_packets++;
-@@ -1761,9 +1848,10 @@
- hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
- }
-
--static void __orinoco_ev_alloc(struct orinoco_private *priv, hermes_t *hw)
-+static void __orinoco_ev_alloc(struct net_device *dev, hermes_t *hw)
- {
-- struct net_device *dev = priv->ndev;
-+ struct orinoco_private *priv = dev->priv;
-+
- u16 fid = hermes_read_regn(hw, ALLOCFID);
-
- if (fid != priv->txfid) {
-@@ -1945,7 +2033,7 @@
-
- TRACE_ENTER(dev->name);
-
-- /* No need to lock, the resetting flag is already set in
-+ /* No need to lock, the hw_unavailable flag is already set in
- * alloc_orinocodev() */
- priv->nicbuf_size = IEEE802_11_FRAME_LEN + ETH_HLEN;
-
-@@ -2081,8 +2169,6 @@
- priv->wep_on = 0;
- priv->tx_key = 0;
-
-- priv->hw_unavailable = 0;
--
- err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid);
- if (err == -EIO) {
- /* Try workaround for old Symbol firmware bug */
-@@ -2102,6 +2188,12 @@
- goto out;
- }
-
-+ /* Make the hardware available, as long as it hasn't been
-+ * removed elsewhere (e.g. by PCMCIA hot unplug) */
-+ spin_lock_irq(&priv->lock);
-+ priv->hw_unavailable--;
-+ spin_unlock_irq(&priv->lock);
-+
- printk(KERN_DEBUG "%s: ready\n", dev->name);
-
- out:
-@@ -2267,7 +2359,7 @@
-
- /* Length of the packet body */
- /* FIXME: what if the skb is smaller than this? */
-- len = max_t(int,skb->len - ETH_HLEN, ETH_ZLEN);
-+ len = max_t(int,skb->len - ETH_HLEN, ETH_ZLEN - ETH_HLEN);
-
- eh = (struct ethhdr *)skb->data;
-
-@@ -2281,6 +2373,12 @@
- goto fail;
- }
-
-+ /* Clear the 802.11 header and data length fields - some
-+ * firmwares (e.g. Lucent/Agere 8.xx) appear to get confused
-+ * if this isn't done. */
-+ hermes_clear_words(hw, HERMES_DATA0,
-+ HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
-+
- /* Encapsulate Ethernet-II frames */
- if (ntohs(eh->h_proto) > 1500) { /* Ethernet-II frame */
- struct header_struct hdr;
-@@ -2362,7 +2460,7 @@
-
- stats->tx_errors++;
-
-- schedule_task(&priv->timeout_task);
-+ schedule_work(&priv->reset_work);
- }
-
- static int
-@@ -2532,7 +2630,7 @@
- }
-
- err = orinoco_hw_get_bitratelist(priv, &numrates,
-- range.bitrate, IW_MAX_BITRATES);
-+ range.bitrate, IW_MAX_BITRATES);
- if (err)
- return err;
- range.num_bitrates = numrates;
-@@ -2799,7 +2897,7 @@
- erq->flags = 1;
- erq->length = strlen(essidbuf) + 1;
- if (erq->pointer)
-- if ( copy_to_user(erq->pointer, essidbuf, erq->length) )
-+ if (copy_to_user(erq->pointer, essidbuf, erq->length))
- return -EFAULT;
-
- TRACE_EXIT(dev->name);
-@@ -3128,7 +3226,7 @@
- rrq->value = 5500000;
- else
- rrq->value = val * 1000000;
-- break;
-+ break;
- case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
- case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
- for (i = 0; i < BITRATE_TABLE_SIZE; i++)
-@@ -3754,7 +3852,7 @@
-
- printk(KERN_DEBUG "%s: Force scheduling reset!\n", dev->name);
-
-- schedule_task(&priv->timeout_task);
-+ schedule_work(&priv->reset_work);
- break;
-
- case SIOCIWFIRSTPRIV + 0x2: /* set_port3 */
-@@ -3827,7 +3925,7 @@
- break;
-
- case SIOCIWLASTPRIV:
-- err = orinoco_debug_dump_recs(priv);
-+ err = orinoco_debug_dump_recs(dev);
- if (err)
- printk(KERN_ERR "%s: Unable to dump records (%d)\n",
- dev->name, err);
-@@ -3839,7 +3937,7 @@
- }
-
- if (! err && changed && netif_running(dev)) {
-- err = orinoco_reconfigure(priv);
-+ err = orinoco_reconfigure(dev);
- }
-
- TRACE_EXIT(dev->name);
-@@ -3924,7 +4022,7 @@
- DEBUG_REC(PRIID,WORDS),
- DEBUG_REC(PRISUPRANGE,WORDS),
- DEBUG_REC(CFIACTRANGES,WORDS),
-- DEBUG_REC(NICSERNUM,WORDS),
-+ DEBUG_REC(NICSERNUM,XSTRING),
- DEBUG_REC(NICID,WORDS),
- DEBUG_REC(MFISUPRANGE,WORDS),
- DEBUG_REC(CFISUPRANGE,WORDS),
-@@ -3961,8 +4059,9 @@
-
- #define DEBUG_LTV_SIZE 128
-
--static int orinoco_debug_dump_recs(struct orinoco_private *priv)
-+static int orinoco_debug_dump_recs(struct net_device *dev)
- {
-+ struct orinoco_private *priv = dev->priv;
- hermes_t *hw = &priv->hw;
- u8 *val8;
- u16 *val16;
-@@ -4051,6 +4150,7 @@
- dev->do_ioctl = orinoco_ioctl;
- dev->change_mtu = orinoco_change_mtu;
- dev->set_multicast_list = orinoco_set_multicast_list;
-+ /* we use the default eth_mac_addr for setting the MAC addr */
-
- /* Set up default callbacks */
- dev->open = orinoco_open;
-@@ -4062,7 +4162,7 @@
- priv->hw_unavailable = 1; /* orinoco_init() must clear this
- * before anything else touches the
- * hardware */
-- INIT_TQUEUE(&priv->timeout_task, (void (*)(void *))orinoco_reset, dev);
-+ INIT_WORK(&priv->reset_work, (void (*)(void *))orinoco_reset, dev);
-
- priv->last_linkstatus = 0xffff;
- priv->connected = 0;
-@@ -4079,13 +4179,14 @@
-
- EXPORT_SYMBOL(__orinoco_up);
- EXPORT_SYMBOL(__orinoco_down);
-+EXPORT_SYMBOL(orinoco_stop);
- EXPORT_SYMBOL(orinoco_reinit_firmware);
-
- EXPORT_SYMBOL(orinoco_interrupt);
-
- /* Can't be declared "const" or the whole __initdata section will
- * become const */
--static char version[] __initdata = "orinoco.c 0.13b (David Gibson <hermes@gibson.dropbear.id.au> and others)";
-+static char version[] __initdata = "orinoco.c 0.13e (David Gibson <hermes@gibson.dropbear.id.au> and others)";
-
- static int __init init_orinoco(void)
- {
---- linux-2.4.21/drivers/net/wireless/orinoco.h~orinoco013e
-+++ linux-2.4.21/drivers/net/wireless/orinoco.h
-@@ -11,9 +11,29 @@
- #include <linux/spinlock.h>
- #include <linux/netdevice.h>
- #include <linux/wireless.h>
--#include <linux/tqueue.h>
-+#include <linux/version.h>
- #include "hermes.h"
-
-+/* Workqueue / task queue backwards compatibility stuff */
-+
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)
-+#include <linux/workqueue.h>
-+#else
-+#include <linux/tqueue.h>
-+#define work_struct tq_struct
-+#define INIT_WORK INIT_TQUEUE
-+#define schedule_work schedule_task
-+#endif
-+
-+/* Interrupt handler backwards compatibility stuff */
-+#ifndef IRQ_NONE
-+
-+#define IRQ_NONE
-+#define IRQ_HANDLED
-+typedef void irqreturn_t;
-+
-+#endif
-+
- /* To enable debug messages */
- //#define ORINOCO_DEBUG 3
-
-@@ -36,13 +56,13 @@
-
-
- struct orinoco_private {
-- void *card; /* Pointer to card dependant structure */
-+ void *card; /* Pointer to card dependent structure */
- int (*hard_reset)(struct orinoco_private *);
-
- /* Synchronisation stuff */
- spinlock_t lock;
- int hw_unavailable;
-- struct tq_struct timeout_task;
-+ struct work_struct reset_work;
-
- /* driver state */
- int open;
-@@ -72,6 +92,7 @@
- int has_sensitivity;
- int nicbuf_size;
- u16 channel_mask;
-+ int broken_disableport;
-
- /* Configuration paramaters */
- u32 iw_mode;
-@@ -111,9 +132,9 @@
- int (*hard_reset)(struct orinoco_private *));
- extern int __orinoco_up(struct net_device *dev);
- extern int __orinoco_down(struct net_device *dev);
--int orinoco_reinit_firmware(struct net_device *dev);
--
--extern void orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs);
-+extern int orinoco_stop(struct net_device *dev);
-+extern int orinoco_reinit_firmware(struct net_device *dev);
-+extern irqreturn_t orinoco_interrupt(int irq, void * dev_id, struct pt_regs *regs);
-
- /********************************************************************/
- /* Locking and synchronization functions */
---- linux-2.4.21/drivers/net/wireless/orinoco_cs.c~orinoco013e
-+++ linux-2.4.21/drivers/net/wireless/orinoco_cs.c
-@@ -1,4 +1,4 @@
--/* orinoco_cs.c 0.13b - (formerly known as dldwd_cs.c)
-+/* orinoco_cs.c 0.13e - (formerly known as dldwd_cs.c)
- *
- * A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
- * as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
-@@ -22,11 +22,7 @@
- #include <linux/ptrace.h>
- #include <linux/slab.h>
- #include <linux/string.h>
--#include <linux/timer.h>
- #include <linux/ioport.h>
--#include <asm/uaccess.h>
--#include <asm/io.h>
--#include <asm/system.h>
- #include <linux/netdevice.h>
- #include <linux/if_arp.h>
- #include <linux/etherdevice.h>
-@@ -38,7 +34,10 @@
- #include <pcmcia/cistpl.h>
- #include <pcmcia/cisreg.h>
- #include <pcmcia/ds.h>
--#include <pcmcia/bus_ops.h>
-+
-+#include <asm/uaccess.h>
-+#include <asm/io.h>
-+#include <asm/system.h>
-
- #include "orinoco.h"
-
-@@ -62,7 +61,7 @@
-
- /* Some D-Link cards have buggy CIS. They do work at 5v properly, but
- * don't have any CIS entry for it. This workaround it... */
--static int ignore_cis_vcc; /* = 0 */
-+static int ignore_cis_vcc = 1;
-
- MODULE_PARM(irq_mask, "i");
- MODULE_PARM(irq_list, "1-4i");
-@@ -145,8 +144,10 @@
- /* PCMCIA stuff */
- /********************************************************************/
-
-+/* In 2.5 (as of 2.5.69 at least) there is a cs_error exported which
-+ * does this, but it's not in 2.4 so we do our own for now. */
- static void
--cs_error(client_handle_t handle, int func, int ret)
-+orinoco_cs_error(client_handle_t handle, int func, int ret)
- {
- error_info_t err = { func, ret };
- CardServices(ReportError, handle, &err);
-@@ -202,6 +203,7 @@
- link->priv = dev;
-
- /* Initialize the dev_link_t structure */
-+ init_timer(&link->release);
- link->release.function = &orinoco_cs_release;
- link->release.data = (u_long) link;
-
-@@ -240,7 +242,7 @@
-
- ret = CardServices(RegisterClient, &link->handle, &client_reg);
- if (ret != CS_SUCCESS) {
-- cs_error(link->handle, RegisterClient, ret);
-+ orinoco_cs_error(link->handle, RegisterClient, ret);
- orinoco_cs_detach(link);
- return NULL;
- }
-@@ -269,19 +271,12 @@
- return;
- }
-
-- /*
-- If the device is currently configured and active, we won't
-- actually delete it yet. Instead, it is marked so that when
-- the release() function is called, that will trigger a proper
-- detach().
-- */
- if (link->state & DEV_CONFIG) {
--#ifdef PCMCIA_DEBUG
-- printk(KERN_DEBUG "orinoco_cs: detach postponed, '%s' "
-- "still locked\n", link->dev->dev_name);
--#endif
-- link->state |= DEV_STALE_LINK;
-- return;
-+ orinoco_cs_release((u_long)link);
-+ if (link->state & DEV_CONFIG) {
-+ link->state |= DEV_STALE_LINK;
-+ return;
-+ }
- }
-
- /* Break the link with Card Services */
-@@ -368,7 +363,7 @@
- CS_CHECK(GetFirstTuple, handle, &tuple);
- while (1) {
- cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
-- cistpl_cftable_entry_t dflt = { index: 0 };
-+ cistpl_cftable_entry_t dflt = { .index = 0 };
-
- CFG_CHECK(GetTupleData, handle, &tuple);
- CFG_CHECK(ParseTuple, handle, &tuple, &parse);
-@@ -472,7 +467,7 @@
- link->irq.IRQInfo2 |= 1 << irq_list[i];
-
- link->irq.Handler = orinoco_interrupt;
-- link->irq.Instance = priv;
-+ link->irq.Instance = dev;
-
- CS_CHECK(RequestIRQ, link->handle, &link->irq);
- }
-@@ -532,7 +527,7 @@
- return;
-
- cs_failed:
-- cs_error(link->handle, last_fn, last_ret);
-+ orinoco_cs_error(link->handle, last_fn, last_ret);
-
- failed:
- orinoco_cs_release((u_long) link);
-@@ -549,18 +544,13 @@
- dev_link_t *link = (dev_link_t *) arg;
- struct net_device *dev = link->priv;
- struct orinoco_private *priv = dev->priv;
-+ unsigned long flags;
-
-- /*
-- If the device is currently in use, we won't release until it
-- is actually closed, because until then, we can't be sure that
-- no one will try to access the device or its data structures.
-- */
-- if (priv->open) {
-- DEBUG(0, "orinoco_cs: release postponed, '%s' still open\n",
-- link->dev->dev_name);
-- link->state |= DEV_STALE_CONFIG;
-- return;
-- }
-+ /* We're committed to taking the device away now, so mark the
-+ * hardware as unavailable */
-+ spin_lock_irqsave(&priv->lock, flags);
-+ priv->hw_unavailable++;
-+ spin_unlock_irqrestore(&priv->lock, flags);
-
- /* Don't bother checking to see if these succeed or not */
- CardServices(ReleaseConfiguration, link->handle);
-@@ -593,14 +583,9 @@
- orinoco_lock(priv, &flags);
-
- netif_device_detach(dev);
-- priv->hw_unavailable = 1;
-+ priv->hw_unavailable++;
-
- orinoco_unlock(priv, &flags);
--
--/* if (link->open) */
--/* orinoco_cs_stop(dev); */
--
-- mod_timer(&link->release, jiffies + HZ / 20);
- }
- break;
-
-@@ -619,13 +604,8 @@
- a better way, short of rewriting the PCMCIA
- layer to not suck :-( */
- if (! test_bit(0, &card->hard_reset_in_progress)) {
-- err = orinoco_lock(priv, &flags);
-- if (err) {
-- printk(KERN_ERR "%s: hw_unavailable on SUSPEND/RESET_PHYSICAL\n",
-- dev->name);
-- break;
-- }
--
-+ spin_lock_irqsave(&priv->lock, flags);
-+
- err = __orinoco_down(dev);
- if (err)
- printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
-@@ -634,9 +614,9 @@
- err);
-
- netif_device_detach(dev);
-- priv->hw_unavailable = 1;
--
-- orinoco_unlock(priv, &flags);
-+ priv->hw_unavailable++;
-+
-+ spin_unlock_irqrestore(&priv->lock, flags);
- }
-
- CardServices(ReleaseConfiguration, link->handle);
-@@ -653,10 +633,6 @@
- CardServices(RequestConfiguration, link->handle,
- &link->conf);
-
-- /* If we're only getting these events because
-- of the ResetCard in the hard reset, we
-- don't need to do anything - orinoco_reset()
-- will handle reinitialization. */
- if (! test_bit(0, &card->hard_reset_in_progress)) {
- err = orinoco_reinit_firmware(dev);
- if (err) {
-@@ -668,9 +644,9 @@
- spin_lock_irqsave(&priv->lock, flags);
-
- netif_device_attach(dev);
-- priv->hw_unavailable = 0;
-+ priv->hw_unavailable--;
-
-- if (priv->open) {
-+ if (priv->open && ! priv->hw_unavailable) {
- err = __orinoco_up(dev);
- if (err)
- printk(KERN_ERR "%s: Error %d restarting card\n",
-@@ -678,7 +654,7 @@
-
- }
-
-- orinoco_unlock(priv, &flags);
-+ spin_unlock_irqrestore(&priv->lock, flags);
- }
- }
- break;
-@@ -693,7 +669,7 @@
-
- /* Can't be declared "const" or the whole __initdata section will
- * become const */
--static char version[] __initdata = "orinoco_cs.c 0.13b (David Gibson <hermes@gibson.dropbear.id.au> and others)";
-+static char version[] __initdata = "orinoco_cs.c 0.13e (David Gibson <hermes@gibson.dropbear.id.au> and others)";
-
- static int __init
- init_orinoco_cs(void)
-@@ -722,7 +698,6 @@
- if (dev_list)
- DEBUG(0, "orinoco_cs: Removing leftover devices.\n");
- while (dev_list != NULL) {
-- del_timer(&dev_list->release);
- if (dev_list->state & DEV_CONFIG)
- orinoco_cs_release((u_long) dev_list);
- orinoco_cs_detach(dev_list);
---- linux-2.4.21/drivers/pcmcia/pxa/Makefile~ramses-pcmcia
-+++ linux-2.4.21/drivers/pcmcia/pxa/Makefile
-@@ -12,6 +12,7 @@
- obj-$(CONFIG_ARCH_PXA_IDP) += pxa_idp.o
- obj-$(CONFIG_ARCH_TRIZEPS2) += trizeps2.o
- obj-$(CONFIG_ARCH_PXA_CERF) += ../sa1100_cerf.o
-+obj-$(CONFIG_ARCH_RAMSES) += ramses.o
-
- obj-m := $(O_TARGET)
-
---- linux-2.4.21/drivers/pcmcia/pxa/pxa.c~pxa-pcmcia
-+++ linux-2.4.21/drivers/pcmcia/pxa/pxa.c
-@@ -187,7 +187,6 @@
- struct pcmcia_state state[PXA_PCMCIA_MAX_SOCK];
- struct pcmcia_state_array state_array;
- unsigned int i, clock;
-- unsigned long mecr;
-
- printk(KERN_INFO "Intel PXA250/210 PCMCIA (CS release %s)\n", CS_RELEASE);
-
-@@ -240,6 +239,8 @@
- pcmcia_low_level=&pxa_idp_pcmcia_ops;
- } else if( machine_is_pxa_cerf()){
- pcmcia_low_level=&cerf_pcmcia_ops;
-+ } else if( machine_is_ramses()){
-+ pcmcia_low_level=&ramses_pcmcia_ops;
- } else if (machine_is_trizeps2()){
- #ifdef CONFIG_ARCH_TRIZEPS2
- pcmcia_low_level=&trizeps2_pcmcia_ops;
-@@ -835,7 +836,7 @@
- static int pxa_pcmcia_set_io_map(unsigned int sock,
- struct pccard_io_map *map){
- unsigned int clock, speed;
-- unsigned long mecr, start;
-+ unsigned long start;
-
- DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
-
-@@ -941,7 +942,7 @@
- static int pxa_pcmcia_set_mem_map(unsigned int sock,
- struct pccard_mem_map *map){
- unsigned int clock, speed;
-- unsigned long mecr, start;
-+ unsigned long start;
-
- DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
-
-@@ -1076,7 +1077,6 @@
- char *p=buf;
- unsigned int sock=(unsigned int)data;
- unsigned int clock = get_lclk_frequency_10khz();
-- unsigned long mecr = MECR;
-
- p+=sprintf(p, "k_flags : %s%s%s%s%s%s%s\n",
- pxa_pcmcia_socket[sock].k_state.detect?"detect ":"",
---- linux-2.4.21/drivers/pcmcia/pxa/pxa.h~ramses-pcmcia
-+++ linux-2.4.21/drivers/pcmcia/pxa/pxa.h
-@@ -228,6 +228,7 @@
- extern struct pcmcia_low_level lubbock_pcmcia_ops;
- extern struct pcmcia_low_level pxa_idp_pcmcia_ops;
- extern struct pcmcia_low_level cerf_pcmcia_ops;
-+extern struct pcmcia_low_level ramses_pcmcia_ops;
- extern struct pcmcia_low_level trizeps2_pcmcia_ops;
-
- #endif /* !defined(_PCMCIA_PXA_H) */
---- /dev/null
-+++ linux-2.4.21/drivers/pcmcia/pxa/ramses.c
-@@ -0,0 +1,223 @@
-+/*
-+ * linux/drivers/pcmcia/pxa/ramses.c
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Copyright (c) 2003 M&N Logistik-Lösungen Online GmbH
-+ *
-+ * Platform specific routines for the Ramses, based on those
-+ * first done for the Lubbock and PXA IDP.
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+
-+#include <pcmcia/ss.h>
-+
-+#include <asm/delay.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/arch/pcmcia.h>
-+
-+static int
-+ramses_pcmcia_init(struct pcmcia_init *init)
-+{
-+ int return_val = 0;
-+
-+ /* Set PCMCIA Socket 0 power to standby mode.
-+ * RAMSES has dedicated CPLD pins for all this stuff :-)
-+ */
-+
-+ /* both slots disabled, reset NOT active */
-+ RAMSES_CPLD_PCCARD_EN = PCC0_ENABLE | PCC1_ENABLE;
-+
-+ RAMSES_CPLD_PCCARD_PWR = 0; //all power to both slots off
-+ //GPDR(IRQ_TO_GPIO_2_80(CFCARD_CD_VALID)) &= ~GPIO_bit(IRQ_TO_GPIO_2_80(CFCARD_CD_VALID));
-+ set_GPIO_IRQ_edge(IRQ_TO_GPIO_2_80(CFCARD_CD_VALID), GPIO_BOTH_EDGES);
-+ //GPDR(IRQ_TO_GPIO_2_80(CFCARD_RDYINT)) &= ~GPIO_bit(IRQ_TO_GPIO_2_80(CFCARD_RDYINT));
-+ set_GPIO_IRQ_edge(IRQ_TO_GPIO_2_80(CFCARD_RDYINT), GPIO_FALLING_EDGE);
-+
-+ return_val +=
-+ request_irq(CFCARD_CD_VALID, init->handler, SA_INTERRUPT,
-+ "CF-Card CD", NULL);
-+
-+ if (return_val < 0) {
-+ return -1;
-+ }
-+
-+ return 2;
-+}
-+
-+static int
-+ramses_pcmcia_shutdown(void)
-+{
-+
-+ free_irq(CFCARD_CD_VALID, NULL);
-+
-+ RAMSES_CPLD_PCCARD_EN = 0x03; //disable slots
-+ udelay(200);
-+ RAMSES_CPLD_PCCARD_PWR = 0; //shut off all power
-+
-+ return 0;
-+}
-+
-+static int
-+ramses_pcmcia_socket_state(struct pcmcia_state_array *state_array)
-+{
-+ unsigned long status;
-+ int return_val = 1;
-+ int i;
-+ volatile unsigned long *stat_regs[2] = {
-+ &RAMSES_CPLD_PCCARD0_STATUS,
-+ &RAMSES_CPLD_PCCARD1_STATUS
-+ };
-+
-+ if (state_array->size < 2)
-+ return -1;
-+
-+ memset(state_array->state, 0,
-+ (state_array->size) * sizeof (struct pcmcia_state));
-+
-+ for (i = 1; i < 2; i++) {
-+
-+ status = *stat_regs[i];
-+
-+ /* this one is a gpio */
-+ state_array->state[i].detect = (PCC_DETECT(i)) ? 0 : 1;
-+
-+ state_array->state[i].ready = ((status & _PCC_IRQ) == 0) ? 0 : 1;
-+ state_array->state[i].bvd1 = (status & PCC_BVD1) ? 0 : 1;
-+ state_array->state[i].bvd2 = (status & PCC_BVD2) ? 0 : 1;
-+ state_array->state[i].wrprot = (status & _PCC_WRPROT) ? 1 : 0;
-+ state_array->state[i].vs_3v = (status & PCC_VS1) ? 0 : 1;
-+ state_array->state[i].vs_Xv = (status & PCC_VS2) ? 0 : 1;
-+ }
-+
-+ state_array->state[0].detect = 0;
-+ state_array->state[0].ready = 0;
-+ state_array->state[0].bvd1 = 0;
-+ state_array->state[0].bvd2 = 0;
-+ state_array->state[0].wrprot = 0;
-+ state_array->state[0].vs_3v = 0;
-+ state_array->state[0].vs_Xv = 0;
-+
-+ return return_val;
-+}
-+
-+static int
-+ramses_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-+{
-+ switch (info->sock) {
-+ case 0:
-+ //info->irq = PCMCIA_S0_RDYINT;
-+ //printk("//hs ramses_pcmcia_get_irq_info called for slot 0\n");
-+ break;
-+
-+ case 1:
-+ info->irq = CFCARD_RDYINT;
-+ break;
-+
-+ default:
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+ramses_pcmcia_configure_socket(unsigned int sock, socket_state_t *state)
-+{
-+ /* The Ramses uses the Maxim MAX1602, with the following connections:
-+ *
-+ * Socket 0 (PCMCIA):
-+ * MAX1602 PXA_IDP Register
-+ * Pin Signal RAMSES_CPLD_PCCARD_PWR:
-+ * ----- ------- ----------------------
-+ * A0VPP PCC0_PWR0 bit0
-+ * A1VPP PCC0_PWR1 bit1
-+ * A0VCC PCC0_PWR2 bit2
-+ * A1VCC PCC0_PWR3 bit3
-+ * VX VCC
-+ * VY +3.3V
-+ * 12IN +12V
-+ * CODE +3.3V Cirrus Code, CODE = High (VY)
-+ *
-+ * Socket 1 (PCMCIA):
-+ * MAX1602 PXA_IDP Register
-+ * Pin Signal RAMSES_CPLD_PCCARD_PWR:
-+ * ----- ------- ----------------------
-+ * A0VPP PCC1_PWR0 bit4
-+ * A1VPP PCC1_PWR1 bit5
-+ * A0VCC PCC1_PWR2 bit6
-+ * A1VCC PCC1_PWR3 bit7
-+ * VX VCC
-+ * VY +3.3V
-+ * 12IN +12V
-+ * CODE +3.3V Cirrus Code, CODE = High (VY)
-+ *
-+ */
-+
-+ if (sock == 1) {
-+
-+ switch (state->Vcc) {
-+ case 0:
-+ RAMSES_CPLD_PCCARD_EN |= PCC1_ENABLE; // disable socket
-+ udelay(200);
-+ RAMSES_CPLD_PCCARD_PWR &= ~(PCC1_PWR2 | PCC1_PWR3);
-+ break;
-+
-+ case 33:
-+ RAMSES_CPLD_PCCARD_PWR &= ~(PCC1_PWR2 | PCC1_PWR3);
-+ RAMSES_CPLD_PCCARD_PWR |= PCC1_PWR3;
-+ RAMSES_CPLD_PCCARD_EN &= ~PCC1_ENABLE; //turn it on
-+ break;
-+
-+ case 50:
-+ RAMSES_CPLD_PCCARD_PWR &= ~(PCC1_PWR2 | PCC1_PWR3);
-+ RAMSES_CPLD_PCCARD_PWR |= PCC1_PWR2;
-+ RAMSES_CPLD_PCCARD_EN &= ~PCC1_ENABLE;
-+ break;
-+
-+ default:
-+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-+ __FUNCTION__, state->Vcc);
-+ return -1;
-+ }
-+
-+ switch (state->Vpp) {
-+ case 0:
-+ RAMSES_CPLD_PCCARD_PWR &= ~(PCC1_PWR0 | PCC1_PWR1);
-+ break;
-+
-+ case 120:
-+ RAMSES_CPLD_PCCARD_PWR &= ~(PCC1_PWR0 | PCC1_PWR1);
-+ RAMSES_CPLD_PCCARD_PWR |= PCC1_PWR1;
-+ break;
-+
-+ default:
-+ if (state->Vpp == state->Vcc)
-+ RAMSES_CPLD_PCCARD_PWR =
-+ (RAMSES_CPLD_PCCARD_PWR &
-+ ~(PCC1_PWR0 | PCC1_PWR1)) | PCC1_PWR0;
-+ else {
-+ printk(KERN_ERR "%s(): unrecognized Vpp %u\n",
-+ __FUNCTION__, state->Vpp);
-+ return -1;
-+ }
-+ }
-+ RAMSES_CPLD_PCCARD_EN = (state->flags & SS_RESET) ? (RAMSES_CPLD_PCCARD_EN | PCC1_RESET)
-+ : (RAMSES_CPLD_PCCARD_EN & ~PCC1_RESET);
-+ }
-+ return 0;
-+}
-+
-+struct pcmcia_low_level ramses_pcmcia_ops = {
-+ ramses_pcmcia_init,
-+ ramses_pcmcia_shutdown,
-+ ramses_pcmcia_socket_state,
-+ ramses_pcmcia_get_irq_info,
-+ ramses_pcmcia_configure_socket
-+};
---- linux-2.4.21/drivers/scsi/scsi.h~usb-sonycamera
-+++ linux-2.4.21/drivers/scsi/scsi.h
-@@ -610,6 +610,7 @@
- unsigned remap:1; /* support remapping */
- unsigned starved:1; /* unable to process commands because
- host busy */
-+ unsigned no_start_on_add:1; /* do not issue start on add */
-
- // Flag to allow revalidate to succeed in sd_open
- int allow_revalidate;
---- linux-2.4.21/drivers/scsi/scsi_scan.c~usb-sonycamera
-+++ linux-2.4.21/drivers/scsi/scsi_scan.c
-@@ -37,6 +37,8 @@
- #define BLIST_ISDISK 0x100 /* Treat as (removable) disk */
- #define BLIST_ISROM 0x200 /* Treat as (removable) CD-ROM */
- #define BLIST_LARGELUN 0x400 /* LUNs larger than 7 despite reporting as SCSI 2 */
-+#define BLIST_NOSTARTONADD 0x1000 /* do not do automatic start on add */
-+
-
- static void print_inquiry(unsigned char *data);
- static int scan_scsis_single(unsigned int channel, unsigned int dev,
-@@ -110,9 +112,10 @@
- {"HP", "C1750A", "3226", BLIST_NOLUN}, /* scanjet iic */
- {"HP", "C1790A", "", BLIST_NOLUN}, /* scanjet iip */
- {"HP", "C2500A", "", BLIST_NOLUN}, /* scanjet iicx */
-- {"HP", "A6188A", "*", BLIST_SPARSELUN}, /* HP Va7100 Array */
-- {"HP", "A6189A", "*", BLIST_SPARSELUN}, /* HP Va7400 Array */
-- {"HP", "A6189B", "*", BLIST_SPARSELUN}, /* HP Va7410 Array */
-+ {"HP", "A6188A", "*", BLIST_SPARSELUN | BLIST_LARGELUN},/* HP Va7100 Array */
-+ {"HP", "A6189A", "*", BLIST_SPARSELUN | BLIST_LARGELUN},/* HP Va7400 Array */
-+ {"HP", "A6189B", "*", BLIST_SPARSELUN | BLIST_LARGELUN},/* HP Va7110 Array */
-+ {"HP", "A6218A", "*", BLIST_SPARSELUN | BLIST_LARGELUN},/* HP Va7410 Array */
- {"YAMAHA", "CDR100", "1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0 */
- {"YAMAHA", "CDR102", "1.00", BLIST_NOLUN}, /* Locks up if polled for lun != 0
- * extra reset */
-@@ -145,7 +148,7 @@
- {"EMULEX", "MD21/S2 ESDI", "*", BLIST_SINGLELUN},
- {"CANON", "IPUBJD", "*", BLIST_SPARSELUN},
- {"nCipher", "Fastness Crypto", "*", BLIST_FORCELUN},
-- {"DEC","HSG80","*", BLIST_FORCELUN},
-+ {"DEC","HSG80","*", BLIST_FORCELUN | BLIST_NOSTARTONADD},
- {"COMPAQ","LOGICAL VOLUME","*", BLIST_FORCELUN},
- {"COMPAQ","CR3500","*", BLIST_FORCELUN},
- {"NEC", "PD-1 ODX654P", "*", BLIST_FORCELUN | BLIST_SINGLELUN},
-@@ -173,7 +176,11 @@
- {"HP", "NetRAID-4M", "*", BLIST_FORCELUN},
- {"ADAPTEC", "AACRAID", "*", BLIST_FORCELUN},
- {"ADAPTEC", "Adaptec 5400S", "*", BLIST_FORCELUN},
-- {"COMPAQ", "MSA1000", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-+ {"APPLE", "Xserve", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-+ {"COMPAQ", "MSA1000", "*", BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_NOSTARTONADD},
-+ {"COMPAQ", "MSA1000 VOLUME", "*", BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_NOSTARTONADD},
-+ {"COMPAQ", "HSV110", "*", BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_NOSTARTONADD},
-+ {"HP", "HSV100", "*", BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_NOSTARTONADD},
- {"HP", "C1557A", "*", BLIST_FORCELUN},
- {"IBM", "AuSaV1S2", "*", BLIST_FORCELUN},
- {"FSC", "CentricStor", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-@@ -182,7 +189,8 @@
- {"HITACHI", "DF500", "*", BLIST_SPARSELUN},
- {"HITACHI", "DF600", "*", BLIST_SPARSELUN},
- {"IBM", "ProFibre 4000R", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-- {"HITACHI", "OPEN-", "*", BLIST_SPARSELUN}, /* HITACHI XP Arrays */
-+ {"HITACHI", "OPEN-", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, /* HITACHI XP Arrays */
-+ {"HITACHI", "DISK-SUBSYSTEM", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, /* HITACHI 9960 */
- {"WINSYS","FLASHDISK G6", "*", BLIST_SPARSELUN},
- {"DotHill","SANnet RAID X300", "*", BLIST_SPARSELUN},
- {"SUN", "T300", "*", BLIST_SPARSELUN},
-@@ -194,6 +202,12 @@
- {"SGI", "TP9400", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
- {"SGI", "TP9500", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
- {"MYLEX", "DACARMRB", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-+ {"PLATYPUS", "CX5", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-+ {"Raidtec", "FCR", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-+ {"HP", "C7200", "*", BLIST_SPARSELUN}, /* Medium Changer */
-+ {"SMSC", "USB 2 HS", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-+ {"XYRATEX", "RS", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
-+ {"NEC", "iStorage", "*", BLIST_SPARSELUN | BLIST_LARGELUN | BLIST_FORCELUN},
-
- /*
- * Must be at end of list...
-@@ -209,10 +223,14 @@
- static unsigned int max_scsi_luns = 1;
- #endif
-
-+static unsigned int scsi_allow_ghost_devices = 0;
-+
- #ifdef MODULE
-
- MODULE_PARM(max_scsi_luns, "i");
- MODULE_PARM_DESC(max_scsi_luns, "last scsi LUN (should be between 1 and 2^32-1)");
-+MODULE_PARM(scsi_allow_ghost_devices, "i");
-+MODULE_PARM_DESC(scsi_allow_ghost_devices, "allow devices marked as being offline to be accessed anyway (0 = off, else allow ghosts on lun 0 through scsi_allow_ghost_devices - 1");
-
- #else
-
-@@ -232,6 +250,21 @@
-
- __setup("max_scsi_luns=", scsi_luns_setup);
-
-+static int __init scsi_allow_ghost_devices_setup(char *str)
-+{
-+ unsigned int tmp;
-+
-+ if (get_option(&str, &tmp) == 1) {
-+ scsi_allow_ghost_devices = tmp;
-+ return 1;
-+ } else {
-+ printk("scsi_allow_ghost_devices_setup: usage scsi_allow_ghost_devices=n (0: off else\nallow ghost devices (ghost devices are devices that report themselves as\nbeing offline but which we allow access to anyway) on lun 0 through n - 1.\n");
-+ return 0;
-+ }
-+}
-+
-+__setup("scsi_allow_ghost_devices=", scsi_allow_ghost_devices_setup);
-+
- #endif
-
- static void print_inquiry(unsigned char *data)
-@@ -608,6 +641,7 @@
- } else {
- /* assume no peripheral if any other sort of error */
- scsi_release_request(SRpnt);
-+ scsi_release_commandblocks(SDpnt);
- return 0;
- }
- }
-@@ -618,6 +652,24 @@
- */
-
- /*
-+ * If we are offline and we are on a LUN != 0, then skip this entry.
-+ * If we are on a BLIST_FORCELUN device this will stop the scan at
-+ * the first offline LUN (typically the correct thing to do). If
-+ * we are on a BLIST_SPARSELUN device then this won't stop the scan,
-+ * but it will keep us from having false entries in our device
-+ * array. DL
-+ *
-+ * NOTE: Need to test this to make sure it doesn't cause problems
-+ * with tape autoloaders, multidisc CD changers, and external
-+ * RAID chassis that might use sparse luns or multiluns... DL
-+ */
-+ if (lun != 0 && (scsi_result[0] >> 5) == 1) {
-+ scsi_release_request(SRpnt);
-+ scsi_release_commandblocks(SDpnt);
-+ return 0;
-+ }
-+
-+ /*
- * Get any flags for this device.
- */
- bflags = get_device_flags (scsi_result);
-@@ -655,8 +707,11 @@
-
- SDpnt->removable = (0x80 & scsi_result[1]) >> 7;
- /* Use the peripheral qualifier field to determine online/offline */
-- if (((scsi_result[0] >> 5) & 7) == 1) SDpnt->online = FALSE;
-- else SDpnt->online = TRUE;
-+ if ((((scsi_result[0] >> 5) & 7) == 1) &&
-+ (lun >= scsi_allow_ghost_devices))
-+ SDpnt->online = FALSE;
-+ else
-+ SDpnt->online = TRUE;
- SDpnt->lockable = SDpnt->removable;
- SDpnt->changed = 0;
- SDpnt->access_count = 0;
-@@ -742,6 +797,13 @@
- if ((bflags & BLIST_BORKEN) == 0)
- SDpnt->borken = 0;
-
-+ /*
-+ * Some devices may not want to have a start command automatically
-+ * issued when a device is added.
-+ */
-+ if (bflags & BLIST_NOSTARTONADD)
-+ SDpnt->no_start_on_add = 1;
-+
- /*
- * If we want to only allow I/O to one of the luns attached to this device
- * at a time, then we set this flag.
-@@ -857,11 +919,26 @@
- * I think we need REPORT LUNS in future to avoid scanning
- * of unused LUNs. But, that is another item.
- */
-+ /*
- if (*max_dev_lun < shpnt->max_lun)
- *max_dev_lun = shpnt->max_lun;
- else if ((max_scsi_luns >> 1) >= *max_dev_lun)
- *max_dev_lun += shpnt->max_lun;
- else *max_dev_lun = max_scsi_luns;
-+ */
-+ /*
-+ * Blech...the above code is broken. When you have a device
-+ * that is present, and it is a FORCELUN device, then we
-+ * need to scan *all* the luns on that device. Besides,
-+ * skipping the scanning of LUNs is a false optimization.
-+ * Scanning for a LUN on a present device is a very fast
-+ * operation, it's scanning for devices that don't exist that
-+ * is expensive and slow (although if you are truly scanning
-+ * through MAX_SCSI_LUNS devices that would be bad, I hope
-+ * all of the controllers out there set a reasonable value
-+ * in shpnt->max_lun). DL
-+ */
-+ *max_dev_lun = shpnt->max_lun;
- return 1;
- }
- /*
---- linux-2.4.21/drivers/scsi/sd.c~usb-sonycamera
-+++ linux-2.4.21/drivers/scsi/sd.c
-@@ -775,7 +775,8 @@
- char nbuff[6];
- unsigned char *buffer;
- unsigned long spintime_value = 0;
-- int the_result, retries, spintime;
-+ int retries, spintime;
-+ unsigned int the_result;
- int sector_size;
- Scsi_Request *SRpnt;
-
-@@ -817,7 +818,7 @@
- do {
- retries = 0;
-
-- while (retries < 3) {
-+ do {
- cmd[0] = TEST_UNIT_READY;
- cmd[1] = (rscsi_disks[i].device->scsi_level <= SCSI_2) ?
- ((rscsi_disks[i].device->lun << 5) & 0xe0) : 0;
-@@ -832,10 +833,10 @@
-
- the_result = SRpnt->sr_result;
- retries++;
-- if (the_result == 0
-- || SRpnt->sr_sense_buffer[2] != UNIT_ATTENTION)
-- break;
-- }
-+ } while (retries < 3
-+ && (the_result !=0
-+ || ((driver_byte(the_result) & DRIVER_SENSE)
-+ && SRpnt->sr_sense_buffer[2] == UNIT_ATTENTION)));
-
- /*
- * If the drive has indicated to us that it doesn't have
-@@ -853,24 +854,47 @@
- break;
- }
-
-+ if ((driver_byte(the_result) & DRIVER_SENSE) == 0) {
-+ /* no sense, TUR either succeeded or failed
-+ * with a status error */
-+ if(!spintime && the_result != 0)
-+ printk(KERN_NOTICE "%s: Unit Not Ready, error = 0x%x\n", nbuff, the_result);
-+ break;
-+ }
-+
-+ /*
-+ * The device does not want the automatic start to be issued.
-+ */
-+ if (rscsi_disks[i].device->no_start_on_add) {
-+ break;
-+ }
-+
-+ /*
-+ * If manual intervention is required, or this is an
-+ * absent USB storage device, a spinup is meaningless.
-+ */
-+ if (SRpnt->sr_sense_buffer[2] == NOT_READY &&
-+ SRpnt->sr_sense_buffer[12] == 4 /* not ready */ &&
-+ SRpnt->sr_sense_buffer[13] == 3) {
-+ break; /* manual intervention required */
- /* Look for non-removable devices that return NOT_READY.
- * Issue command to spin up drive for these cases. */
-- if (the_result && !rscsi_disks[i].device->removable &&
-- SRpnt->sr_sense_buffer[2] == NOT_READY) {
-+ } else if (the_result && !rscsi_disks[i].device->removable &&
-+ SRpnt->sr_sense_buffer[2] == NOT_READY) {
- unsigned long time1;
- if (!spintime) {
- printk("%s: Spinning up disk...", nbuff);
- cmd[0] = START_STOP;
- cmd[1] = (rscsi_disks[i].device->scsi_level <= SCSI_2) ?
-- ((rscsi_disks[i].device->lun << 5) & 0xe0) : 0;
-- cmd[1] |= 1; /* Return immediately */
-+ ((rscsi_disks[i].device->lun << 5) & 0xe0) : 0;
-+ cmd[1] |= 1; /* Return immediately */
- memset((void *) &cmd[2], 0, 8);
-- cmd[4] = 1; /* Start spin cycle */
-+ cmd[4] = 1; /* Start spin cycle */
- SRpnt->sr_cmd_len = 0;
- SRpnt->sr_sense_buffer[0] = 0;
- SRpnt->sr_sense_buffer[2] = 0;
-
-- SRpnt->sr_data_direction = SCSI_DATA_READ;
-+ SRpnt->sr_data_direction = SCSI_DATA_NONE;
- scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer,
- 0/*512*/, SD_TIMEOUT, MAX_RETRIES);
- spintime_value = jiffies;
-@@ -883,6 +907,14 @@
- time1 = schedule_timeout(time1);
- } while(time1);
- printk(".");
-+ } else {
-+ /* we don't understand the sense code, so it's
-+ * probably pointless to loop */
-+ if(!spintime) {
-+ printk(KERN_NOTICE "%s: Unit Not Ready, sense:\n", nbuff);
-+ print_req_sense("", SRpnt);
-+ }
-+ break;
- }
- } while (the_result && spintime &&
- time_after(spintime_value + 100 * HZ, jiffies));
---- linux-2.4.21/drivers/sound/ac97_codec.c~ucb1x00
-+++ linux-2.4.21/drivers/sound/ac97_codec.c
-@@ -547,6 +547,12 @@
- val = SOUND_CAP_EXCL_INPUT;
- break;
-
-+ case SOUND_MIXER_AC97:
-+ if (get_user(val, (int *)arg))
-+ return -EFAULT;
-+ val = codec->codec_read(codec, val);
-+ return put_user(val, (int *)arg);
-+
- default: /* read a specific mixer */
- i = _IOC_NR(cmd);
-
-@@ -575,6 +581,11 @@
- codec->recmask_io(codec, 0, val);
-
- return 0;
-+
-+ case SOUND_MIXER_AC97:
-+ codec->codec_write(codec, val >> 16 & 0xffff, val & 0xffff);
-+ return 0;
-+
- default: /* write a specific mixer */
- i = _IOC_NR(cmd);
-
---- linux-2.4.21/drivers/sound/pxa-ac97.c~pxa-ac97
-+++ linux-2.4.21/drivers/sound/pxa-ac97.c
-@@ -27,6 +27,7 @@
- #include <linux/sound.h>
- #include <linux/soundcard.h>
- #include <linux/ac97_codec.h>
-+#include <linux/pm.h>
-
- #include <asm/hardware.h>
- #include <asm/irq.h>
-@@ -164,6 +165,11 @@
- //pxa_ac97_write(&pxa_ac97_codec, 0x6a, 0x1ff7);
- pxa_ac97_write(&pxa_ac97_codec, 0x6a, 0x0050);
- pxa_ac97_write(&pxa_ac97_codec, 0x6c, 0x0030);
-+#if CONFIG_ARCH_RAMSES
-+ pxa_ac97_codec.supported_mixers = SOUND_MASK_VOLUME | SOUND_MASK_IGAIN;
-+ pxa_ac97_codec.stereo_mixers = SOUND_MASK_VOLUME | SOUND_MASK_IGAIN;
-+ pxa_ac97_codec.record_sources = SOUND_MASK_MIC | SOUND_MASK_LINE;
-+#endif
- }
-
- pxa_ac97_refcount++;
-@@ -198,7 +204,7 @@
- static int mixer_ioctl( struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
- {
-- int ret, val;
-+ int ret;
-
- ret = pxa_ac97_codec.mixer_ioctl(&pxa_ac97_codec, cmd, arg);
- if (ret)
-@@ -282,6 +288,7 @@
- /* fall through */
-
- case SOUND_PCM_READ_RATE:
-+ val = 0;
- if (file->f_mode & FMODE_READ)
- val = codec_adc_rate;
- if (file->f_mode & FMODE_WRITE)
-@@ -342,6 +349,44 @@
- };
-
-
-+#ifdef CONFIG_PM
-+
-+static int pxa_ac97_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
-+{
-+ down(&pxa_ac97_mutex);
-+
-+ switch (rqst) {
-+ case PM_SUSPEND:
-+ // TODO: set to low-power state?
-+ GCR = GCR_ACLINK_OFF;
-+ CKEN &= ~CKEN2_AC97;
-+ break;
-+
-+ case PM_RESUME:
-+ CKEN |= CKEN2_AC97;
-+
-+ GCR = 0;
-+ udelay(10);
-+ GCR = GCR_COLD_RST|GCR_CDONE_IE|GCR_SDONE_IE;
-+ while (!(GSR & GSR_PCR)) {
-+ schedule();
-+ }
-+
-+ // need little hack for UCB1400 (should be moved elsewhere)
-+ pxa_ac97_write(&pxa_ac97_codec,AC97_EXTENDED_STATUS,1);
-+ pxa_ac97_write(&pxa_ac97_codec, 0x6a, 0x0050);
-+ pxa_ac97_write(&pxa_ac97_codec, 0x6c, 0x0030);
-+ break;
-+ }
-+
-+ up(&pxa_ac97_mutex);
-+
-+ return 0;
-+}
-+
-+#endif
-+
-+
- static int __init pxa_ac97_init(void)
- {
- int ret;
-@@ -354,11 +399,18 @@
- ac97_audio_state.dev_dsp = register_sound_dsp(&ac97_audio_fops, -1);
- pxa_ac97_codec.dev_mixer = register_sound_mixer(&mixer_fops, -1);
-
-+#ifdef PM_DEBUG
-+ ac97_audio_state.pmdev = pm_register(PM_SYS_UNKNOWN, 0x71783937, pxa_ac97_pm_callback, "pxa-ac97");
-+#else
-+ ac97_audio_state.pmdev = pm_register(PM_SYS_UNKNOWN, 0x71783937, pxa_ac97_pm_callback);
-+#endif
-+
- return 0;
- }
-
- static void __exit pxa_ac97_exit(void)
- {
-+ pm_unregister(ac97_audio_state.pmdev);
- unregister_sound_dsp(ac97_audio_state.dev_dsp);
- unregister_sound_mixer(pxa_ac97_codec.dev_mixer);
- pxa_ac97_put();
---- linux-2.4.21/drivers/sound/pxa-audio.h~pm
-+++ linux-2.4.21/drivers/sound/pxa-audio.h
-@@ -47,6 +47,9 @@
- int wr_ref:1; /* open reference for playback */
- int (*client_ioctl)(struct inode *, struct file *, uint, ulong);
- struct semaphore sem; /* prevent races in attach/release */
-+#ifdef CONFIG_PM
-+ struct pm_dev *pmdev; /* Power management */
-+#endif
- } audio_state_t;
-
- extern int pxa_audio_attach(struct inode *inode, struct file *file,
---- linux-2.4.21/drivers/usb/Config.in~pxa-usb
-+++ linux-2.4.21/drivers/usb/Config.in
-@@ -5,7 +5,7 @@
- comment 'USB support'
-
- # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
--if [ "$CONFIG_PCI" = "y" -o "$CONFIG_SA1111" = "y" -o "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
-+if [ "$CONFIG_PCI" = "y" -o "$CONFIG_SA1111" = "y" -o "$CONFIG_ARCH_AT91RM9200" = "y" -o "$CONFIG_ARCH_PXA" = "y" ]; then
- tristate 'Support for USB' CONFIG_USB
- else
- define_bool CONFIG_USB n
---- linux-2.4.21/drivers/usb/Makefile~usb-sl811
-+++ linux-2.4.21/drivers/usb/Makefile
-@@ -80,6 +80,9 @@
- ifeq ($(CONFIG_USB_OHCI),y)
- obj-y += host/usb-ohci.o host/usb-ohci-sa1111.o
- endif
-+
-+subdir-$(CONFIG_USB_SL811HS_ALT)+= host
-+
- subdir-$(CONFIG_USB_OHCI_AT91) += host
- ifeq ($(CONFIG_USB_OHCI_AT91),y)
- obj-y += host/usb-ohci.o
---- linux-2.4.21/drivers/usb/hcd.c~ramses-usb
-+++ linux-2.4.21/drivers/usb/hcd.c
-@@ -662,7 +662,9 @@
- pci_set_drvdata(dev, hcd);
- hcd->driver = driver;
- hcd->description = driver->description;
-+#ifdef TODO
- hcd->pdev = dev;
-+#endif
- printk (KERN_INFO "%s %s: %s\n",
- hcd->description, dev->slot_name, dev->name);
-
-@@ -1201,6 +1203,7 @@
- return status;
-
- // NOTE: 2.5 does this if !URB_NO_DMA_MAP transfer flag
-+#ifdef TODO
- if (usb_pipecontrol (urb->pipe))
- urb->setup_dma = pci_map_single (
- #ifdef CONFIG_PCI
-@@ -1223,7 +1226,7 @@
- usb_pipein (urb->pipe)
- ? PCI_DMA_FROMDEVICE
- : PCI_DMA_TODEVICE);
--
-+#endif
- if (urb->dev == hcd->bus->root_hub)
- status = rh_urb_enqueue (hcd, urb);
- else
-@@ -1488,6 +1491,7 @@
- // hcd_monitor_hook(MONITOR_URB_UPDATE, urb, dev)
-
- // NOTE: 2.5 does this if !URB_NO_DMA_MAP transfer flag
-+#ifdef TODO
- if (usb_pipecontrol (urb->pipe))
- pci_unmap_single (
- #ifdef CONFIG_PCI
-@@ -1510,6 +1514,7 @@
- usb_pipein (urb->pipe)
- ? PCI_DMA_FROMDEVICE
- : PCI_DMA_TODEVICE);
-+#endif
-
- /* pass ownership to the completion handler */
- urb->complete (urb);
---- linux-2.4.21/drivers/usb/host/Config.in~usb-sl811
-+++ linux-2.4.21/drivers/usb/host/Config.in
-@@ -13,6 +13,9 @@
- fi
- dep_tristate ' OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI $CONFIG_USB
- dep_tristate ' SA1111 OHCI-compatible host interface support' CONFIG_USB_OHCI_SA1111 $CONFIG_USB
-+if [ "$CONFIG_ARM" = "y" -o "$CONFIG_X86" = "y" ]; then
-+ dep_tristate ' SL811HS Alternate (x86, StrongARM, isosynchronous mode)' CONFIG_USB_SL811HS_ALT $CONFIG_USB $CONFIG_EXPERIMENTAL
-+fi
- if [ "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
- dep_tristate ' AT91RM9200 OHCI-compatible host interface support' CONFIG_USB_OHCI_AT91 $CONFIG_USB
- fi
---- linux-2.4.21/drivers/usb/host/Makefile~usb-sl811
-+++ linux-2.4.21/drivers/usb/host/Makefile
-@@ -10,6 +10,7 @@
- obj-$(CONFIG_USB_UHCI) += usb-uhci.o
- obj-$(CONFIG_USB_OHCI) += usb-ohci.o usb-ohci-pci.o
- obj-$(CONFIG_USB_OHCI_SA1111) += usb-ohci.o usb-ohci-sa1111.o
-+obj-$(CONFIG_USB_SL811HS_ALT) += sl811.o
- obj-$(CONFIG_USB_OHCI_AT91) += usb-ohci.o
-
- # Extract lists of the multi-part drivers.
---- /dev/null
-+++ linux-2.4.21/drivers/usb/host/sl811.c
-@@ -0,0 +1,2782 @@
-+/*
-+ * SL811 Host Controller Interface driver for USB.
-+ *
-+ * Copyright (c) 2003/06, Courage Co., Ltd.
-+ *
-+ * Based on:
-+ * 1.uhci.c by Linus Torvalds, Johannes Erdfelt, Randy Dunlap,
-+ * Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber,
-+ * Adam Richter, Gregory P. Smith;
-+ * 2.Original SL811 driver (hc_sl811.o) by Pei Liu <pbl@cypress.com>
-+ * 3.Rewrited as sl811.o by Yin Aihua <yinah:couragetech.com.cn>
-+ *
-+ * It's now support isochornous mode and more effective than hc_sl811.o
-+ * Support x86 architecture now.
-+ *
-+ * 19.09.2003 (05.06.2003) HNE
-+ * sl811_alloc_hc: Set "bus->bus_name" at init.
-+ * sl811_reg_test (hc_reset,regTest):
-+ * Stop output at first failed pattern.
-+ * Down-Grade for Kernel 2.4.20 and from 2.4.22
-+ * Split hardware dependency into files sl811-x86.h and sl811-arm.h.
-+ *
-+ * 22.09.2003 HNE
-+ * sl811_found_hc: First patterntest, than interrupt enable.
-+ * Do nothing, if patterntest failed. Release IO if failed.
-+ * Stop Interrupts first, than remove handle. (Old blocked Shared IRQ)
-+ * Alternate IO-Base for second Controller (CF/USB1).
-+ *
-+ * 24.09.2003 HNE
-+ * Remove all arm specific source (moved into include/asm/sl811-hw.h).
-+ *
-+ * 03.10.2003 HNE
-+ * Low level only for port IO into hardware-include.
-+ *
-+ * To do:
-+ * 1.Modify the timeout part, it's some messy
-+ * 2.Use usb-a and usb-b set in Ping-Pong mode
-+ * o Floppy do not work.
-+ * o driver crash, if io region can't register
-+ * o Only tested as module. Compiled-in version not tested!
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+#include <linux/smp_lock.h>
-+#include <linux/list.h>
-+#include <linux/ioport.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/hardware.h>
-+#include <linux/usb.h>
-+
-+#include "../hcd.h"
-+#include "../hub.h"
-+#include "sl811.h"
-+
-+#define DRIVER_VERSION "v0.30"
-+#define MODNAME "SL811"
-+#define DRIVER_AUTHOR "Yin Aihua <yinah@couragetech.com.cn>, Henry Nestler <hne@ist1.de>"
-+#define DRIVER_DESC "Sl811 USB Host Controller Alternate Driver"
-+
-+static LIST_HEAD(sl811_hcd_list);
-+
-+/*
-+ * 0: normal prompt and information
-+ * 1: error should not occur in normal
-+ * 2: error maybe occur in normal
-+ * 3: useful and detail debug information
-+ * 4: function level enter and level inforamtion
-+ * 5: endless information will output because of timer function or interrupt
-+ */
-+static int debug = 0;
-+MODULE_PARM(debug,"i");
-+MODULE_PARM_DESC(debug,"debug level");
-+
-+#include <asm/sl811-hw.h> /* Include hardware and board depens */
-+
-+static void sl811_rh_int_timer_do(unsigned long ptr);
-+static void sl811_transfer_done(struct sl811_hc *hc, int sof);
-+
-+/*
-+ * Read a byte of data from the SL811H/SL11H
-+ */
-+static __u8 inline sl811_read(struct sl811_hc *hc, __u8 offset)
-+{
-+ sl811_write_index (hc, offset);
-+ return (sl811_read_data (hc));
-+}
-+
-+/*
-+ * Write a byte of data to the SL811H/SL11H
-+ */
-+static void inline sl811_write(struct sl811_hc *hc, __u8 offset, __u8 data)
-+{
-+ sl811_write_index_data (hc, offset, data);
-+}
-+
-+/*
-+ * Read consecutive bytes of data from the SL811H/SL11H buffer
-+ */
-+static void inline sl811_read_buf(struct sl811_hc *hc, __u8 offset, __u8 *buf, __u8 size)
-+{
-+ sl811_write_index (hc, offset);
-+ while (size--) {
-+ *buf++ = sl811_read_data(hc);
-+ }
-+}
-+
-+/*
-+ * Write consecutive bytes of data to the SL811H/SL11H buffer
-+ */
-+static void inline sl811_write_buf(struct sl811_hc *hc, __u8 offset, __u8 *buf, __u8 size)
-+{
-+ sl811_write_index (hc, offset);
-+ while (size--) {
-+ sl811_write_data (hc, *buf);
-+ buf++;
-+ }
-+}
-+
-+/*
-+ * This routine test the Read/Write functionality of SL811HS registers
-+ */
-+static int sl811_reg_test(struct sl811_hc *hc)
-+{
-+ int i, data, result = 0;
-+ __u8 buf[256];
-+
-+ for (i = 0x10; i < 256; i++) {
-+ /* save the original buffer */
-+ buf[i] = sl811_read(hc, i);
-+
-+ /* Write the new data to the buffer */
-+ sl811_write(hc, i, ~i);
-+ }
-+
-+ /* compare the written data */
-+ for (i = 0x10; i < 256; i++) {
-+ data = sl811_read(hc, i);
-+ if (data != (__u8) ~i) {
-+ PDEBUG(1, "reg %02x expected %02x got %02x", i, (__u8) ~i, data);
-+ result = -1;
-+
-+ /* If no Debug, show only first failed Address */
-+ if (!debug)
-+ break;
-+ }
-+ }
-+
-+ /* restore the data */
-+ for (i = 0x10; i < 256; i++)
-+ sl811_write(hc, i, buf[i]);
-+
-+ return result;
-+}
-+
-+/*
-+ * Display all SL811HS register values
-+ */
-+#if 0 /* unused (hne) */
-+static void sl811_reg_show(struct sl811_hc *hc)
-+{
-+ int i;
-+
-+ for (i = 0; i < 256; i++)
-+ PDEBUG(4, "offset %d: 0x%x", i, sl811_read(hc, i));
-+}
-+#endif
-+
-+/*
-+ * This function enables SL811HS interrupts
-+ */
-+static void sl811_enable_interrupt(struct sl811_hc *hc)
-+{
-+ PDEBUG(4, "enter");
-+ sl811_write(hc, SL811_INTR, SL811_INTR_DONE_A | SL811_INTR_SOF | SL811_INTR_INSRMV);
-+}
-+
-+/*
-+ * This function disables SL811HS interrupts
-+ */
-+static void sl811_disable_interrupt(struct sl811_hc *hc)
-+{
-+ PDEBUG(4, "enter");
-+ // Disable all other interrupt except for insert/remove.
-+ sl811_write(hc, SL811_INTR, SL811_INTR_INSRMV);
-+}
-+
-+/*
-+ * SL811 Virtual Root Hub
-+ */
-+
-+/* Device descriptor */
-+static __u8 sl811_rh_dev_des[] =
-+{
-+ 0x12, /* __u8 bLength; */
-+ 0x01, /* __u8 bDescriptorType; Device */
-+ 0x10, /* __u16 bcdUSB; v1.1 */
-+ 0x01,
-+ 0x09, /* __u8 bDeviceClass; HUB_CLASSCODE */
-+ 0x00, /* __u8 bDeviceSubClass; */
-+ 0x00, /* __u8 bDeviceProtocol; */
-+ 0x08, /* __u8 bMaxPacketSize0; 8 Bytes */
-+ 0x00, /* __u16 idVendor; */
-+ 0x00,
-+ 0x00, /* __u16 idProduct; */
-+ 0x00,
-+ 0x00, /* __u16 bcdDevice; */
-+ 0x00,
-+ 0x00, /* __u8 iManufacturer; */
-+ 0x02, /* __u8 iProduct; */
-+ 0x01, /* __u8 iSerialNumber; */
-+ 0x01 /* __u8 bNumConfigurations; */
-+};
-+
-+/* Configuration descriptor */
-+static __u8 sl811_rh_config_des[] =
-+{
-+ 0x09, /* __u8 bLength; */
-+ 0x02, /* __u8 bDescriptorType; Configuration */
-+ 0x19, /* __u16 wTotalLength; */
-+ 0x00,
-+ 0x01, /* __u8 bNumInterfaces; */
-+ 0x01, /* __u8 bConfigurationValue; */
-+ 0x00, /* __u8 iConfiguration; */
-+ 0x40, /* __u8 bmAttributes;
-+ Bit 7: Bus-powered, 6: Self-powered, 5 Remote-wakwup,
-+ 4..0: resvd */
-+ 0x00, /* __u8 MaxPower; */
-+
-+ /* interface */
-+ 0x09, /* __u8 if_bLength; */
-+ 0x04, /* __u8 if_bDescriptorType; Interface */
-+ 0x00, /* __u8 if_bInterfaceNumber; */
-+ 0x00, /* __u8 if_bAlternateSetting; */
-+ 0x01, /* __u8 if_bNumEndpoints; */
-+ 0x09, /* __u8 if_bInterfaceClass; HUB_CLASSCODE */
-+ 0x00, /* __u8 if_bInterfaceSubClass; */
-+ 0x00, /* __u8 if_bInterfaceProtocol; */
-+ 0x00, /* __u8 if_iInterface; */
-+
-+ /* endpoint */
-+ 0x07, /* __u8 ep_bLength; */
-+ 0x05, /* __u8 ep_bDescriptorType; Endpoint */
-+ 0x81, /* __u8 ep_bEndpointAddress; IN Endpoint 1 */
-+ 0x03, /* __u8 ep_bmAttributes; Interrupt */
-+ 0x08, /* __u16 ep_wMaxPacketSize; */
-+ 0x00,
-+ 0xff /* __u8 ep_bInterval; 255 ms */
-+};
-+
-+/* root hub class descriptor*/
-+static __u8 sl811_rh_hub_des[] =
-+{
-+ 0x09, /* __u8 bLength; */
-+ 0x29, /* __u8 bDescriptorType; Hub-descriptor */
-+ 0x01, /* __u8 bNbrPorts; */
-+ 0x00, /* __u16 wHubCharacteristics; */
-+ 0x00,
-+ 0x50, /* __u8 bPwrOn2pwrGood; 2ms */
-+ 0x00, /* __u8 bHubContrCurrent; 0 mA */
-+ 0xfc, /* __u8 DeviceRemovable; *** 7 Ports max *** */
-+ 0xff /* __u8 PortPwrCtrlMask; *** 7 ports max *** */
-+};
-+
-+/*
-+ * This function examine the port change in the virtual root hub. HUB INTERRUPT ENDPOINT.
-+ */
-+static int sl811_rh_send_irq(struct sl811_hc *hc, __u8 *rh_change, int rh_len)
-+{
-+ __u8 data = 0;
-+
-+ PDEBUG(5, "enter");
-+
-+ /*
-+ * Right now, It is assume the power is good and no changes and only one port.
-+ */
-+ if (hc->rh_status.wPortChange & (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE)) {
-+ data = 1<<1;
-+ *(__u8 *)rh_change = data;
-+ return 1;
-+ } else
-+ return 0;
-+}
-+
-+/*
-+ * This function creates a timer that act as interrupt pipe in the virtual hub.
-+ *
-+ * Note: The virtual root hub's interrupt pipe are polled by the timer
-+ * every "interval" ms
-+ */
-+static void sl811_rh_init_int_timer(struct urb * urb)
-+{
-+ struct sl811_hc *hc = urb->dev->bus->hcpriv;
-+ hc->rh.interval = urb->interval;
-+
-+ init_timer(&hc->rh.rh_int_timer);
-+ hc->rh.rh_int_timer.function = sl811_rh_int_timer_do;
-+ hc->rh.rh_int_timer.data = (unsigned long)urb;
-+ hc->rh.rh_int_timer.expires = jiffies +
-+ (HZ * (urb->interval < 30? 30: urb->interval)) / 1000;
-+ add_timer (&hc->rh.rh_int_timer);
-+}
-+
-+/*
-+ * This function is called when the timer expires. It gets the the port
-+ * change data and pass along to the upper protocol.
-+ */
-+static void sl811_rh_int_timer_do(unsigned long ptr)
-+{
-+ int len;
-+ struct urb *urb = (struct urb *)ptr;
-+ struct sl811_hc *hc = urb->dev->bus->hcpriv;
-+ PDEBUG (5, "enter");
-+
-+ if(hc->rh.send) {
-+ len = sl811_rh_send_irq(hc, urb->transfer_buffer,
-+ urb->transfer_buffer_length);
-+ if (len > 0) {
-+ urb->actual_length = len;
-+ if (urb->complete)
-+ urb->complete(urb);
-+ }
-+ }
-+
-+#ifdef SL811_TIMEOUT
-+
-+{
-+ struct list_head *head, *tmp;
-+ struct sl811_urb_priv *urbp;
-+ struct urb *u;
-+ int i;
-+ static int timeout_count = 0;
-+
-+// check time out every second
-+ if (++timeout_count > 4) {
-+ int max_scan = hc->active_urbs;
-+ timeout_count = 0;
-+ for (i = 0; i < 6; ++i) {
-+ head = &hc->urb_list[i];
-+ tmp = head->next;
-+ while (tmp != head && max_scan--) {
-+ u = list_entry(tmp, struct urb, urb_list);
-+ urbp = (struct sl811_urb_priv *)u->hcpriv;
-+ tmp = tmp->next;
-+ // Check if the URB timed out
-+ if (u->timeout && time_after_eq(jiffies, urbp->inserttime + u->timeout)) {
-+ PDEBUG(3, "urb = %p time out, we kill it", urb);
-+ u->transfer_flags |= USB_TIMEOUT_KILLED;
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+#endif
-+ // re-activate the timer
-+ sl811_rh_init_int_timer(urb);
-+}
-+
-+/* helper macro */
-+#define OK(x) len = (x); break
-+
-+/*
-+ * This function handles all USB request to the the virtual root hub
-+ */
-+static int sl811_rh_submit_urb(struct urb *urb)
-+{
-+ struct usb_device *usb_dev = urb->dev;
-+ struct sl811_hc *hc = usb_dev->bus->hcpriv;
-+ struct usb_ctrlrequest *cmd = (struct usb_ctrlrequest *)urb->setup_packet;
-+ void *data = urb->transfer_buffer;
-+ int buf_len = urb->transfer_buffer_length;
-+ unsigned int pipe = urb->pipe;
-+ __u8 data_buf[16];
-+ __u8 *bufp = data_buf;
-+ int len = 0;
-+ int status = 0;
-+
-+ __u16 bmRType_bReq;
-+ __u16 wValue;
-+ __u16 wIndex;
-+ __u16 wLength;
-+
-+ if (usb_pipeint(pipe)) {
-+ hc->rh.urb = urb;
-+ hc->rh.send = 1;
-+ hc->rh.interval = urb->interval;
-+ sl811_rh_init_int_timer(urb);
-+ urb->status = 0;
-+
-+ return 0;
-+ }
-+
-+ bmRType_bReq = cmd->bRequestType | (cmd->bRequest << 8);
-+ wValue = le16_to_cpu (cmd->wValue);
-+ wIndex = le16_to_cpu (cmd->wIndex);
-+ wLength = le16_to_cpu (cmd->wLength);
-+
-+ PDEBUG(5, "submit rh urb, req = %d(%x) len=%d", bmRType_bReq, bmRType_bReq, wLength);
-+
-+ /* Request Destination:
-+ without flags: Device,
-+ USB_RECIP_INTERFACE: interface,
-+ USB_RECIP_ENDPOINT: endpoint,
-+ USB_TYPE_CLASS means HUB here,
-+ USB_RECIP_OTHER | USB_TYPE_CLASS almost ever means HUB_PORT here
-+ */
-+ switch (bmRType_bReq) {
-+ case RH_GET_STATUS:
-+ *(__u16 *)bufp = cpu_to_le16(1);
-+ OK(2);
-+
-+ case RH_GET_STATUS | USB_RECIP_INTERFACE:
-+ *(__u16 *)bufp = cpu_to_le16(0);
-+ OK(2);
-+
-+ case RH_GET_STATUS | USB_RECIP_ENDPOINT:
-+ *(__u16 *)bufp = cpu_to_le16(0);
-+ OK(2);
-+
-+ case RH_GET_STATUS | USB_TYPE_CLASS:
-+ *(__u32 *)bufp = cpu_to_le32(0);
-+ OK(4);
-+
-+ case RH_GET_STATUS | USB_RECIP_OTHER | USB_TYPE_CLASS:
-+ *(__u32 *)bufp = cpu_to_le32(hc->rh_status.wPortChange<<16 | hc->rh_status.wPortStatus);
-+ OK(4);
-+
-+ case RH_CLEAR_FEATURE | USB_RECIP_ENDPOINT:
-+ switch (wValue) {
-+ case 1:
-+ OK(0);
-+ }
-+ break;
-+
-+ case RH_CLEAR_FEATURE | USB_TYPE_CLASS:
-+ switch (wValue) {
-+ case C_HUB_LOCAL_POWER:
-+ OK(0);
-+
-+ case C_HUB_OVER_CURRENT:
-+ OK(0);
-+ }
-+ break;
-+
-+ case RH_CLEAR_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS:
-+ switch (wValue) {
-+ case USB_PORT_FEAT_ENABLE:
-+ hc->rh_status.wPortStatus &= ~USB_PORT_STAT_ENABLE;
-+ OK(0);
-+
-+ case USB_PORT_FEAT_SUSPEND:
-+ hc->rh_status.wPortStatus &= ~USB_PORT_STAT_SUSPEND;
-+ OK(0);
-+
-+ case USB_PORT_FEAT_POWER:
-+ hc->rh_status.wPortStatus &= ~USB_PORT_STAT_POWER;
-+ OK(0);
-+
-+ case USB_PORT_FEAT_C_CONNECTION:
-+ hc->rh_status.wPortChange &= ~USB_PORT_STAT_C_CONNECTION;
-+ OK(0);
-+
-+ case USB_PORT_FEAT_C_ENABLE:
-+ hc->rh_status.wPortChange &= ~USB_PORT_STAT_C_ENABLE;
-+ OK(0);
-+
-+ case USB_PORT_FEAT_C_SUSPEND:
-+ hc->rh_status.wPortChange &= ~USB_PORT_STAT_C_SUSPEND;
-+ OK(0);
-+
-+ case USB_PORT_FEAT_C_OVER_CURRENT:
-+ hc->rh_status.wPortChange &= ~USB_PORT_STAT_C_OVERCURRENT;
-+ OK(0);
-+
-+ case USB_PORT_FEAT_C_RESET:
-+ hc->rh_status.wPortChange &= ~USB_PORT_STAT_C_RESET;
-+ OK(0);
-+ }
-+ break;
-+
-+ case RH_SET_FEATURE | USB_RECIP_OTHER | USB_TYPE_CLASS:
-+ switch (wValue) {
-+ case USB_PORT_FEAT_SUSPEND:
-+ hc->rh_status.wPortStatus |= USB_PORT_STAT_SUSPEND;
-+ OK(0);
-+
-+ case USB_PORT_FEAT_RESET:
-+ hc->rh_status.wPortStatus |= USB_PORT_STAT_RESET;
-+ hc->rh_status.wPortChange = 0;
-+ hc->rh_status.wPortChange |= USB_PORT_STAT_C_RESET;
-+ hc->rh_status.wPortStatus &= ~USB_PORT_STAT_RESET;
-+ hc->rh_status.wPortStatus |= USB_PORT_STAT_ENABLE;
-+ OK(0);
-+
-+ case USB_PORT_FEAT_POWER:
-+ hc->rh_status.wPortStatus |= USB_PORT_STAT_POWER;
-+ OK(0);
-+
-+ case USB_PORT_FEAT_ENABLE:
-+ hc->rh_status.wPortStatus |= USB_PORT_STAT_ENABLE;
-+ OK(0);
-+ }
-+ break;
-+
-+ case RH_SET_ADDRESS:
-+ hc->rh.devnum = wValue;
-+ OK(0);
-+
-+ case RH_GET_DESCRIPTOR:
-+ switch ((wValue & 0xff00) >> 8) {
-+ case USB_DT_DEVICE:
-+ len = sizeof(sl811_rh_dev_des);
-+ bufp = sl811_rh_dev_des;
-+ OK(len);
-+
-+ case USB_DT_CONFIG:
-+ len = sizeof(sl811_rh_config_des);
-+ bufp = sl811_rh_config_des;
-+ OK(len);
-+
-+ case USB_DT_STRING:
-+ len = usb_root_hub_string(wValue & 0xff, (int)(long)0, "SL811HS", data, wLength);
-+ if (len > 0) {
-+ bufp = data;
-+ OK(len);
-+ }
-+
-+ default:
-+ status = -EPIPE;
-+ }
-+ break;
-+
-+ case RH_GET_DESCRIPTOR | USB_TYPE_CLASS:
-+ len = sizeof(sl811_rh_hub_des);
-+ bufp = sl811_rh_hub_des;
-+ OK(len);
-+
-+ case RH_GET_CONFIGURATION:
-+ bufp[0] = 0x01;
-+ OK(1);
-+
-+ case RH_SET_CONFIGURATION:
-+ OK(0);
-+
-+ default:
-+ PDEBUG(1, "unsupported root hub command");
-+ status = -EPIPE;
-+ }
-+
-+ len = min(len, buf_len);
-+ if (data != bufp)
-+ memcpy(data, bufp, len);
-+ urb->actual_length = len;
-+ urb->status = status;
-+
-+ PDEBUG(5, "len = %d, status = %d", len, status);
-+
-+ urb->hcpriv = NULL;
-+ urb->dev = NULL;
-+ if (urb->complete)
-+ urb->complete(urb);
-+
-+ return 0;
-+}
-+
-+/*
-+ * This function unlinks the URB
-+ */
-+static int sl811_rh_unlink_urb(struct urb *urb)
-+{
-+ struct sl811_hc *hc = urb->dev->bus->hcpriv;
-+
-+ PDEBUG(5, "enter");
-+
-+ if (hc->rh.urb == urb) {
-+ hc->rh.send = 0;
-+ del_timer(&hc->rh.rh_int_timer);
-+ hc->rh.urb = NULL;
-+ urb->hcpriv = NULL;
-+ usb_dec_dev_use(urb->dev);
-+ urb->dev = NULL;
-+ if (urb->transfer_flags & USB_ASYNC_UNLINK) {
-+ urb->status = -ECONNRESET;
-+ if (urb->complete)
-+ urb->complete(urb);
-+ } else
-+ urb->status = -ENOENT;
-+ }
-+
-+ return 0;
-+}
-+
-+/*
-+ * This function connect the virtual root hub to the USB stack
-+ */
-+static int sl811_connect_rh(struct sl811_hc * hc)
-+{
-+ struct usb_device *usb_dev;
-+
-+ hc->rh.devnum = 0;
-+ usb_dev = usb_alloc_dev(NULL, hc->bus);
-+ if (!usb_dev)
-+ return -ENOMEM;
-+
-+ hc->bus->root_hub = usb_dev;
-+ usb_connect(usb_dev);
-+
-+ if (usb_new_device(usb_dev)) {
-+ usb_free_dev(usb_dev);
-+ return -ENODEV;
-+ }
-+
-+ PDEBUG(5, "leave success");
-+
-+ return 0;
-+}
-+
-+/*
-+ * This function allocates private data space for the usb device
-+ */
-+static int sl811_alloc_dev_priv(struct usb_device *usb_dev)
-+{
-+ return 0;
-+}
-+
-+/*
-+ * This function de-allocates private data space for the usb devic
-+ */
-+static int sl811_free_dev_priv (struct usb_device *usb_dev)
-+{
-+ return 0;
-+}
-+
-+/*
-+ * This function allocates private data space for the urb
-+ */
-+static struct sl811_urb_priv* sl811_alloc_urb_priv(struct urb *urb)
-+{
-+ struct sl811_urb_priv *urbp;
-+
-+ urbp = kmalloc(sizeof(*urbp), GFP_KERNEL);
-+ if (!urbp)
-+ return NULL;
-+
-+ memset(urbp, 0, sizeof(*urbp));
-+
-+ INIT_LIST_HEAD(&urbp->td_list);
-+
-+ urbp->urb = urb;
-+ urb->hcpriv = urbp;
-+
-+ return urbp;
-+}
-+
-+/*
-+ * This function free private data space for the urb
-+ */
-+static void sl811_free_urb_priv(struct urb *urb)
-+{
-+ struct sl811_urb_priv *urbp = urb->hcpriv;
-+ struct sl811_td *td;
-+ struct list_head *head, *tmp;
-+
-+ if (!urbp)
-+ return ;
-+
-+ head = &urbp->td_list;
-+ tmp = head->next;
-+
-+ while (tmp != head) {
-+ td = list_entry(tmp, struct sl811_td, td_list);
-+ tmp = tmp->next;
-+ kfree(td);
-+ }
-+
-+ kfree(urbp);
-+ urb->hcpriv = NULL;
-+
-+ return ;
-+}
-+
-+/*
-+ * This function calculate the bus time need by this td.
-+ * Fix me! Can this use usb_calc_bus_time()?
-+ */
-+static void sl811_calc_td_time(struct sl811_td *td)
-+{
-+#if 1
-+ int time;
-+ int len = td->len;
-+ struct sl811_hc *hc = td->urb->dev->bus->hcpriv;
-+
-+ if (hc->rh_status.wPortStatus & USB_PORT_STAT_LOW_SPEED)
-+ time = 8*8*len + 1024;
-+ else {
-+ if (td->ctrl & SL811_USB_CTRL_PREAMBLE)
-+ time = 8*8*len + 2048;
-+ else
-+ time = 8*len + 256;
-+ }
-+
-+ time += 2*10 * len;
-+
-+ td->bustime = time;
-+
-+#else
-+
-+ unsigned long tmp;
-+ int time;
-+ int low_speed = usb_pipeslow(td->urb->pipe);
-+ int input_dir = usb_pipein(td->urb->pipe);
-+ int bytecount = td->len;
-+ int isoc = usb_pipeisoc(td->urb->pipe);
-+
-+ if (low_speed) { /* no isoc. here */
-+ if (input_dir) {
-+ tmp = (67667L * (31L + 10L * BitTime (bytecount))) / 1000L;
-+ time = (64060L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp);
-+ } else {
-+ tmp = (66700L * (31L + 10L * BitTime (bytecount))) / 1000L;
-+ time = (64107L + (2 * BW_HUB_LS_SETUP) + BW_HOST_DELAY + tmp);
-+ }
-+ } else if (!isoc){ /* for full-speed: */
-+ tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L;
-+ time = (9107L + BW_HOST_DELAY + tmp);
-+ } else { /* for isoc: */
-+ tmp = (8354L * (31L + 10L * BitTime (bytecount))) / 1000L;
-+ time = (((input_dir) ? 7268L : 6265L) + BW_HOST_DELAY + tmp);
-+ }
-+
-+ td->bustime = time / 84;
-+
-+#endif
-+}
-+
-+/*
-+ * This function calculate the remainder bus time in current frame.
-+ */
-+static inline int sl811_calc_bus_remainder(struct sl811_hc *hc)
-+{
-+ return (sl811_read(hc, SL811_SOFCNTDIV) * 64);
-+}
-+
-+/*
-+ * This function allocates td for the urb
-+ */
-+static struct sl811_td* sl811_alloc_td(struct urb *urb)
-+{
-+ struct sl811_urb_priv *urbp = urb->hcpriv;
-+ struct sl811_td *td;
-+
-+ td = kmalloc(sizeof (*td), GFP_KERNEL);
-+ if (!td)
-+ return NULL;
-+
-+ memset(td, 0, sizeof(*td));
-+
-+ INIT_LIST_HEAD(&td->td_list);
-+
-+ td->urb = urb;
-+ list_add_tail(&td->td_list, &urbp->td_list);
-+
-+ return td;
-+}
-+
-+/*
-+ * Fill the td.
-+ */
-+static inline void sl811_fill_td(struct sl811_td *td, __u8 ctrl, __u8 addr, __u8 len, __u8 pidep, __u8 dev, __u8 *buf)
-+{
-+ td->ctrl = ctrl;
-+ td->addr = addr;
-+ td->len = len;
-+ td->pidep = pidep;
-+ td->dev = dev;
-+ td->buf = buf;
-+ td->left = len;
-+ td->errcnt = 3;
-+}
-+
-+/*
-+ * Fill the td.
-+ */
-+static inline void sl811_reset_td(struct sl811_td *td)
-+{
-+ td->status = 0;
-+ td->left = td->len;
-+ td->done = 0;
-+ td->errcnt = 3;
-+ td->nakcnt = 0;
-+ td->td_status = 0;
-+}
-+
-+static void sl811_print_td(int level, struct sl811_td *td)
-+{
-+ PDEBUG(level, "td = %p, ctrl = %x, addr = %x, len = %x, pidep = %x\n "
-+ "dev = %x, status = %x, left = %x, errcnt = %x, done = %x\n "
-+ "buf = %p, bustime = %d, td_status = %d\n",
-+ td, td->ctrl, td->addr, td->len, td->pidep,
-+ td->dev, td->status, td->left, td->errcnt, td->done,
-+ td->buf, td->bustime, td->td_status);
-+}
-+
-+/*
-+ * Isochronous transfers
-+ */
-+static int sl811_submit_isochronous(struct urb *urb)
-+{
-+ __u8 dev = usb_pipedevice(urb->pipe);
-+ __u8 pidep = PIDEP(usb_packetid(urb->pipe), usb_pipeendpoint(urb->pipe));
-+ __u8 ctrl = 0;
-+ struct sl811_urb_priv *urbp = urb->hcpriv;
-+ struct sl811_td *td = NULL;
-+ int i;
-+
-+ PDEBUG(4, "enter, urb = %p, urbp = %p", urb, urbp);
-+
-+ /* Can't have low speed bulk transfers */
-+ if (usb_pipeslow(urb->pipe)) {
-+ PDEBUG(1, "error, urb = %p, low speed device", urb);
-+ return -EINVAL;
-+ }
-+
-+ if (usb_pipeout(urb->pipe))
-+ ctrl |= SL811_USB_CTRL_DIR_OUT;
-+
-+ ctrl |= SL811_USB_CTRL_ARM | SL811_USB_CTRL_ENABLE | SL811_USB_CTRL_ISO;
-+
-+ for (i = 0; i < urb->number_of_packets; i++) {
-+ urb->iso_frame_desc[i].actual_length = 0;
-+ urb->iso_frame_desc[i].status = -EXDEV;
-+
-+ td = sl811_alloc_td(urb);
-+ if (!td)
-+ return -ENOMEM;
-+
-+ sl811_fill_td(td, ctrl, SL811_DATA_START,
-+ urb->iso_frame_desc[i].length,
-+ pidep, dev,
-+ urb->transfer_buffer + urb->iso_frame_desc[i].offset);
-+ sl811_calc_td_time(td);
-+ if (urbp->cur_td == NULL)
-+ urbp->cur_td = urbp->first_td = td;
-+ }
-+
-+ urbp->last_td = td;
-+
-+ PDEBUG(4, "leave success");
-+
-+/*
-+// for debug
-+ {
-+ struct list_head *head, *tmp;
-+ struct sl811_td *td;
-+ int i = 0;
-+ head = &urbp->td_list;
-+ tmp = head->next;
-+
-+ if (list_empty(&urbp->td_list)) {
-+ PDEBUG(1, "bug!!! td list is empty!");
-+ return -ENODEV;
-+ }
-+
-+ while (tmp != head) {
-+ ++i;
-+ td = list_entry(tmp, struct sl811_td, td_list);
-+ PDEBUG(2, "td = %p, i = %d", td, i);
-+ tmp = tmp->next;
-+ }
-+ }
-+*/
-+ return 0;
-+}
-+
-+/*
-+ * Reset isochronous transfers
-+ */
-+static void sl811_reset_isochronous(struct urb *urb)
-+{
-+ struct sl811_urb_priv *urbp = urb->hcpriv;
-+ struct sl811_td *td = NULL;
-+ struct list_head *head, *tmp;
-+ int i;
-+
-+ PDEBUG(4, "enter, urb = %p", urb);
-+
-+ for (i = 0; i < urb->number_of_packets; i++) {
-+ urb->iso_frame_desc[i].actual_length = 0;
-+ urb->iso_frame_desc[i].status = -EXDEV;
-+ }
-+
-+ head = &urbp->td_list;
-+ tmp = head->next;
-+ while (tmp != head) {
-+ td = list_entry(tmp, struct sl811_td, td_list);
-+ tmp = tmp->next;
-+ sl811_reset_td(td);
-+ }
-+
-+ urbp->cur_td = urbp->first_td;
-+
-+ urb->status = -EINPROGRESS;
-+ urb->actual_length = 0;
-+ urb->error_count = 0;
-+}
-+
-+/*
-+ * Result the iso urb.
-+ */
-+static void sl811_result_isochronous(struct urb *urb)
-+{
-+ struct list_head *tmp, *head;
-+ struct sl811_urb_priv *urbp = urb->hcpriv;
-+ int status = 0;
-+ struct sl811_td *td;
-+ int i;
-+
-+ PDEBUG(4, "enter, urb = %p", urb);
-+
-+ urb->actual_length = 0;
-+
-+ i = 0;
-+ head = &urbp->td_list;
-+ tmp = head->next;
-+ while (tmp != head) {
-+ td = list_entry(tmp, struct sl811_td, td_list);
-+ tmp = tmp->next;
-+
-+ if (!td->done) {
-+ if (urbp->unlink)
-+ urb->status = -ENOENT;
-+ else {
-+ PDEBUG(1, "we should not get here!");
-+ urb->status = -EXDEV;
-+ }
-+ return ;
-+ }
-+ if (td->td_status) {
-+ status = td->td_status;
-+ urb->error_count++;
-+ PDEBUG(1, "error: td = %p, td status = %d", td, td->td_status);
-+ }
-+
-+ urb->iso_frame_desc[i].actual_length = td->len - td->left;
-+ urb->actual_length += td->len - td->left;
-+ urb->iso_frame_desc[i].status = td->td_status;
-+ ++i;
-+ if (td->left)
-+ PDEBUG(3, "short packet, td = %p, len = %d, left = %d", td, td->len, td->left);
-+ }
-+
-+ urb->status = status;
-+/*
-+// for debug
-+ PDEBUG(2, "iso urb complete, len = %d, status =%d ", urb->actual_length, urb->status);
-+*/
-+ PDEBUG(4, "leave success");
-+}
-+
-+/*
-+ * Interrupt transfers
-+ */
-+static int sl811_submit_interrupt(struct urb *urb)
-+{
-+ int maxsze = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
-+ int len = urb->transfer_buffer_length;
-+ __u8 *data = urb->transfer_buffer;
-+ __u8 dev = usb_pipedevice(urb->pipe);
-+ __u8 pidep = PIDEP(usb_packetid(urb->pipe), usb_pipeendpoint(urb->pipe));
-+ __u8 ctrl = 0;
-+ struct sl811_hc *hc = urb->dev->bus->hcpriv;
-+ struct sl811_urb_priv *urbp = urb->hcpriv;
-+ struct sl811_td *td = NULL;
-+
-+ PDEBUG(4, "enter, urb = %p", urb);
-+
-+ if (len > maxsze) {
-+ PDEBUG(1, "length is big than max packet size, len = %d, max packet = %d", len, maxsze);
-+ return -EINVAL;
-+ }
-+ if (usb_pipeslow(urb->pipe) && !(hc->rh_status.wPortStatus & USB_PORT_STAT_LOW_SPEED))
-+ ctrl |= SL811_USB_CTRL_PREAMBLE;
-+
-+ ctrl |= SL811_USB_CTRL_ARM | SL811_USB_CTRL_ENABLE;
-+ if (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)))
-+ ctrl |= SL811_USB_CTRL_TOGGLE_1;
-+ usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
-+ td = sl811_alloc_td(urb);
-+ if (!td)
-+ return -ENOMEM;
-+
-+ sl811_fill_td(td, ctrl, SL811_DATA_START, len, pidep, dev, data);
-+ sl811_calc_td_time(td);
-+ urbp->cur_td = urbp->first_td = urbp->last_td = td;
-+ urbp->interval = 0;
-+
-+ PDEBUG(4, "leave success");
-+
-+ return 0;
-+}
-+
-+/*
-+ * Reset interrupt transfers
-+ */
-+static void sl811_reset_interrupt(struct urb *urb)
-+{
-+ struct sl811_urb_priv *urbp = urb->hcpriv;
-+ struct sl811_td *td = urbp->cur_td;
-+
-+ PDEBUG(4, "enter, interval = %d", urb->interval);
-+
-+ td->ctrl &= ~SL811_USB_CTRL_TOGGLE_1;
-+ if (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)))
-+ td->ctrl |= SL811_USB_CTRL_TOGGLE_1;
-+ usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
-+
-+ sl811_reset_td(td);
-+
-+ urbp->interval = urb->interval;
-+
-+ urb->status = -EINPROGRESS;
-+ urb->actual_length = 0;
-+}
-+
-+/*
-+ * Result the interrupt urb.
-+ */
-+static void sl811_result_interrupt(struct urb *urb)
-+{
-+ struct list_head *tmp;
-+ struct sl811_urb_priv *urbp = urb->hcpriv;
-+ struct sl811_td *td;
-+ int toggle;
-+
-+ PDEBUG(4, "enter, urb = %p", urb);
-+
-+ urb->actual_length = 0;
-+
-+ tmp = &urbp->td_list;
-+ tmp = tmp->next;
-+ td = list_entry(tmp, struct sl811_td, td_list);
-+
-+ // success.
-+ if (td->done && td->td_status == 0) {
-+ urb->actual_length += td->len - td->left;
-+ urb->status = 0;
-+ return ;
-+ }
-+ // tranfer is done but fail, reset the toggle.
-+ else if (td->done && td->td_status) {
-+ urb->status = td->td_status;
-+reset_toggle:
-+ toggle = (td->ctrl & SL811_USB_CTRL_TOGGLE_1) ? 1 : 0;
-+ usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), toggle);
-+ PDEBUG(3, "error: td = %p, td status = %d", td, td->td_status);
-+ return ;
-+ }
-+ // unlink, and not do transfer yet
-+ else if (td->done == 0 && urbp->unlink && td->td_status == 0) {
-+ urb->status = -ENOENT;
-+ PDEBUG(3, "unlink and not transfer!");
-+ return ;
-+ }
-+ // unlink, and transfer not complete yet.
-+ else if (td->done == 0 && urbp->unlink && td->td_status) {
-+ urb->status = -ENOENT;
-+ PDEBUG(3, "unlink and not complete!");
-+ goto reset_toggle;
-+ }
-+ // must be bug!!!
-+ else {// (td->done == 0 && urbp->unlink == 0)
-+ PDEBUG(1, "we should not get here!");
-+ urb->status = -EPIPE;
-+ return ;
-+ }
-+}
-+
-+/*
-+ * Control transfers
-+ */
-+static int sl811_submit_control(struct urb *urb)
-+{
-+ int maxsze = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
-+ int len = urb->transfer_buffer_length;
-+ __u8 *data = urb->transfer_buffer;
-+ __u8 dev = usb_pipedevice(urb->pipe);
-+ __u8 pidep = 0;
-+ __u8 ctrl = 0;
-+ struct sl811_hc *hc = urb->dev->bus->hcpriv;
-+ struct sl811_urb_priv *urbp = urb->hcpriv;
-+ struct sl811_td *td = NULL;
-+
-+ PDEBUG(4, "enter, urb = %p", urb);
-+
-+ if (usb_pipeslow(urb->pipe) && !(hc->rh_status.wPortStatus & USB_PORT_STAT_LOW_SPEED))
-+ ctrl |= SL811_USB_CTRL_PREAMBLE;
-+
-+ /* Build SETUP TD */
-+ pidep = PIDEP(USB_PID_SETUP, usb_pipeendpoint(urb->pipe));
-+ ctrl |= SL811_USB_CTRL_ARM | SL811_USB_CTRL_ENABLE | SL811_USB_CTRL_DIR_OUT;
-+ td = sl811_alloc_td(urb);
-+ if (!td)
-+ return -ENOMEM;
-+
-+ sl811_fill_td(td, ctrl, SL811_DATA_START, 8, pidep, dev, urb->setup_packet);
-+ sl811_calc_td_time(td);
-+
-+ urbp->cur_td = urbp->first_td = td;
-+
-+ /*
-+ * If direction is "send", change the frame from SETUP (0x2D)
-+ * to OUT (0xE1). Else change it from SETUP to IN (0x69).
-+ */
-+ pidep = PIDEP(usb_packetid(urb->pipe), usb_pipeendpoint(urb->pipe));
-+ if (usb_pipeout(urb->pipe))
-+ ctrl |= SL811_USB_CTRL_DIR_OUT;
-+ else
-+ ctrl &= ~SL811_USB_CTRL_DIR_OUT;
-+
-+ /* Build the DATA TD's */
-+ while (len > 0) {
-+ int pktsze = len;
-+
-+ if (pktsze > maxsze)
-+ pktsze = maxsze;
-+
-+ /* Alternate Data0/1 (start with Data1) */
-+ ctrl ^= SL811_USB_CTRL_TOGGLE_1;
-+
-+ td = sl811_alloc_td(urb);
-+ if (!td)
-+ return -ENOMEM;
-+
-+ sl811_fill_td(td, ctrl, SL811_DATA_START, pktsze, pidep, dev, data);
-+ sl811_calc_td_time(td);
-+
-+ data += pktsze;
-+ len -= pktsze;
-+ }
-+
-+ /* Build the final TD for control status */
-+ td = sl811_alloc_td(urb);
-+ if (!td)
-+ return -ENOMEM;
-+
-+ /* It's IN if the pipe is an output pipe or we're not expecting data back */
-+ if (usb_pipeout(urb->pipe) || !urb->transfer_buffer_length) {
-+ pidep = PIDEP(USB_PID_IN, usb_pipeendpoint(urb->pipe));
-+ ctrl &= ~SL811_USB_CTRL_DIR_OUT;
-+ } else {
-+ pidep = PIDEP(USB_PID_OUT, usb_pipeendpoint(urb->pipe));
-+ ctrl |= SL811_USB_CTRL_DIR_OUT;
-+ }
-+
-+ /* End in Data1 */
-+ ctrl |= SL811_USB_CTRL_TOGGLE_1;
-+
-+ sl811_fill_td(td, ctrl, SL811_DATA_START, 0, pidep, dev, 0);
-+ sl811_calc_td_time(td);
-+ urbp->last_td = td;
-+/*
-+// for debug
-+ {
-+ struct list_head *head, *tmp;
-+ struct sl811_td *td;
-+ int i = 0;
-+ head = &urbp->td_list;
-+ tmp = head->next;
-+
-+ if (list_empty(&urbp->td_list)) {
-+ PDEBUG(1, "bug!!! td list is empty!");
-+ return -ENODEV;
-+ }
-+
-+ while (tmp != head) {
-+ ++i;
-+ td = list_entry(tmp, struct sl811_td, td_list);
-+ PDEBUG(3, "td = %p, i = %d", td, i);
-+ tmp = tmp->next;
-+ }
-+ }
-+*/
-+ PDEBUG(4, "leave success");
-+
-+ return 0;
-+}
-+
-+/*
-+ * Result the control urb.
-+ */
-+static void sl811_result_control(struct urb *urb)
-+{
-+ struct list_head *tmp, *head;
-+ struct sl811_urb_priv *urbp = urb->hcpriv;
-+ struct sl811_td *td;
-+
-+ PDEBUG(4, "enter, urb = %p", urb);
-+
-+ if (list_empty(&urbp->td_list)) {
-+ PDEBUG(1, "td list is empty");
-+ return ;
-+ }
-+
-+ head = &urbp->td_list;
-+
-+ tmp = head->next;
-+ td = list_entry(tmp, struct sl811_td, td_list);
-+
-+ /* The first TD is the SETUP phase, check the status, but skip the count */
-+ if (!td->done) {
-+ PDEBUG(3, "setup phase error, td = %p, done = %d", td, td->done);
-+ goto err_done;
-+ }
-+ if (td->td_status) {
-+ PDEBUG(3, "setup phase error, td = %p, td status = %d", td, td->td_status);
-+ goto err_status;
-+ }
-+
-+ urb->actual_length = 0;
-+
-+ /* The rest of the TD's (but the last) are data */
-+ tmp = tmp->next;
-+ while (tmp != head && tmp->next != head) {
-+ td = list_entry(tmp, struct sl811_td, td_list);
-+ tmp = tmp->next;
-+ if (!td->done) {
-+ PDEBUG(3, "data phase error, td = %p, done = %d", td, td->done);
-+ goto err_done;
-+ }
-+ if (td->td_status) {
-+ PDEBUG(3, "data phase error, td = %p, td status = %d", td, td->td_status);
-+ goto err_status;
-+ }
-+
-+ urb->actual_length += td->len - td->left;
-+ // short packet.
-+ if (td->left) {
-+ PDEBUG(3, "data phase short packet, td = %p, count = %d", td, td->len - td->left);
-+ break;
-+ }
-+ }
-+
-+ /* The last td is status phase */
-+ td = urbp->last_td;
-+ if (!td->done) {
-+ PDEBUG(3, "status phase error, td = %p, done = %d", td, td->done);
-+ goto err_done;
-+ }
-+ if (td->td_status) {
-+ PDEBUG(3, "status phase error, td = %p, td status = %d", td, td->td_status);
-+ goto err_status;
-+ }
-+
-+ PDEBUG(4, "leave success");
-+
-+ urb->status = 0;
-+ return ;
-+
-+err_done:
-+ if (urbp->unlink)
-+ urb->status = -ENOENT;
-+ else {
-+ PDEBUG(1, "we should not get here! td = %p", td);
-+ urb->status = -EPIPE;
-+ }
-+ return ;
-+
-+err_status:
-+ urb->status = td->td_status;
-+ return ;
-+}
-+
-+/*
-+ * Bulk transfers
-+ */
-+static int sl811_submit_bulk(struct urb *urb)
-+{
-+ int maxsze = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
-+ int len = urb->transfer_buffer_length;
-+ __u8 *data = urb->transfer_buffer;
-+ __u8 dev = usb_pipedevice(urb->pipe);
-+ __u8 pidep = PIDEP(usb_packetid(urb->pipe), usb_pipeendpoint(urb->pipe));
-+ __u8 ctrl = 0;
-+ struct sl811_urb_priv *urbp = urb->hcpriv;
-+ struct sl811_td *td = NULL;
-+
-+ PDEBUG(4, "enter, urb = %p", urb);
-+
-+ if (len < 0) {
-+ PDEBUG(1, "error, urb = %p, len = %d", urb, len);
-+ return -EINVAL;
-+ }
-+
-+ /* Can't have low speed bulk transfers */
-+ if (usb_pipeslow(urb->pipe)) {
-+ PDEBUG(1, "error, urb = %p, low speed device", urb);
-+ return -EINVAL;
-+ }
-+
-+ if (usb_pipeout(urb->pipe))
-+ ctrl |= SL811_USB_CTRL_DIR_OUT;
-+
-+ ctrl |= SL811_USB_CTRL_ARM | SL811_USB_CTRL_ENABLE;
-+
-+ /* Build the DATA TD's */
-+ do { /* Allow zero length packets */
-+ int pktsze = len;
-+
-+ if (pktsze > maxsze)
-+ pktsze = maxsze;
-+
-+ td = sl811_alloc_td(urb);
-+ if (!td)
-+ return -ENOMEM;
-+
-+ /* Alternate Data0/1 (start with Data1) */
-+ ctrl &= ~SL811_USB_CTRL_TOGGLE_1;
-+ if (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)))
-+ ctrl |= SL811_USB_CTRL_TOGGLE_1;
-+ usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
-+
-+ sl811_fill_td(td, ctrl, SL811_DATA_START, pktsze, pidep, dev, data);
-+ sl811_calc_td_time(td);
-+
-+ if (urbp->cur_td == NULL)
-+ urbp->cur_td = urbp->first_td = td;
-+
-+ data += pktsze;
-+ len -= maxsze;
-+ } while (len > 0);
-+
-+ /*
-+ * USB_ZERO_PACKET means adding a 0-length packet, if
-+ * direction is OUT and the transfer_length was an
-+ * exact multiple of maxsze, hence
-+ * (len = transfer_length - N * maxsze) == 0
-+ * however, if transfer_length == 0, the zero packet
-+ * was already prepared above.
-+ */
-+ if (usb_pipeout(urb->pipe) && (urb->transfer_flags & USB_ZERO_PACKET) &&
-+ !len && urb->transfer_buffer_length) {
-+
-+ td = sl811_alloc_td(urb);
-+ if (!td)
-+ return -ENOMEM;
-+
-+ /* Alternate Data0/1 (start with Data1) */
-+ ctrl &= ~SL811_USB_CTRL_TOGGLE_1;
-+ if (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)))
-+ ctrl |= SL811_USB_CTRL_TOGGLE_1;
-+ usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
-+
-+ sl811_fill_td(td, ctrl, SL811_DATA_START, 0, pidep, dev, 0);
-+ sl811_calc_td_time(td);
-+ }
-+
-+ urbp->last_td = td;
-+
-+ PDEBUG(4, "leave success");
-+
-+ return 0;
-+}
-+
-+/*
-+ * Reset bulk transfers
-+ */
-+static int sl811_reset_bulk(struct urb *urb)
-+{
-+ struct sl811_urb_priv *urbp = urb->hcpriv;
-+ struct sl811_td *td;
-+ struct list_head *head, *tmp;
-+
-+ PDEBUG(4, "enter, urb = %p", urb);
-+
-+
-+ head = &urbp->td_list;
-+ tmp = head->next;
-+
-+ while (tmp != head) {
-+ td = list_entry(tmp, struct sl811_td, td_list);
-+
-+ /* Alternate Data0/1 (start with Data1) */
-+ td->ctrl &= ~SL811_USB_CTRL_TOGGLE_1;
-+ if (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe)))
-+ td->ctrl |= SL811_USB_CTRL_TOGGLE_1;
-+ usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
-+
-+ sl811_reset_td(td);
-+ }
-+
-+ urb->status = -EINPROGRESS;
-+ urb->actual_length = 0;
-+ urbp->cur_td = urbp->first_td;
-+
-+ PDEBUG(4, "leave success");
-+
-+ return 0;
-+}
-+
-+/*
-+ * Result the bulk urb.
-+ */
-+static void sl811_result_bulk(struct urb *urb)
-+{
-+ struct list_head *tmp, *head;
-+ struct sl811_urb_priv *urbp = urb->hcpriv;
-+ struct sl811_td *td = NULL;
-+ int toggle;
-+
-+ PDEBUG(4, "enter, urb = %p", urb);
-+
-+ urb->actual_length = 0;
-+
-+ head = &urbp->td_list;
-+ tmp = head->next;
-+ while (tmp != head) {
-+ td = list_entry(tmp, struct sl811_td, td_list);
-+ tmp = tmp->next;
-+
-+ // success.
-+ if (td->done && td->td_status == 0) {
-+ urb->actual_length += td->len - td->left;
-+
-+ // short packet
-+ if (td->left) {
-+ urb->status = 0;
-+ PDEBUG(3, "short packet, td = %p, count = %d", td, td->len - td->left);
-+ goto reset_toggle;
-+ }
-+ }
-+ // tranfer is done but fail, reset the toggle.
-+ else if (td->done && td->td_status) {
-+ urb->status = td->td_status;
-+ PDEBUG(3, "error: td = %p, td status = %d", td, td->td_status);
-+ goto reset_toggle;
-+ }
-+ // unlink, and not do transfer yet
-+ else if (td->done == 0 && urbp->unlink && td->td_status == 0) {
-+ urb->status = -ENOENT;
-+ PDEBUG(3, "unlink and not transfer!");
-+ return ;
-+ }
-+ // unlink, and transfer not complete yet.
-+ else if (td->done == 0 && urbp->unlink && td->td_status) {
-+ PDEBUG(3, "unlink and not complete!");
-+ urb->status = -ENOENT;
-+ goto reset_toggle;
-+ }
-+ // must be bug!!!
-+ else {// (td->done == 0 && urbp->unlink == 0)
-+ urb->status = -EPIPE;
-+ PDEBUG(1, "we should not get here!");
-+ return ;
-+ }
-+ }
-+
-+ PDEBUG(4, "leave success");
-+ urb->status = 0;
-+ return ;
-+
-+reset_toggle:
-+ toggle = (td->ctrl & SL811_USB_CTRL_TOGGLE_1) ? 1 : 0;
-+ usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), toggle);
-+}
-+
-+/*
-+ * Find the first urb have the same dev and endpoint.
-+ */
-+static inline int sl811_find_same_urb(struct list_head *head, struct urb *urb)
-+{
-+ struct list_head *tmp;
-+ struct urb *u;
-+
-+ if (!head || !urb)
-+ return 0;
-+
-+ tmp = head->next;
-+
-+ while (tmp != head) {
-+ u = list_entry(tmp, struct urb, urb_list);
-+ if (u == urb)
-+ return 1;
-+ tmp = tmp->next;
-+ }
-+
-+ return 0;
-+}
-+
-+/*
-+ * Find the first urb have the same dev and endpoint.
-+ */
-+static inline struct urb* sl811_find_same_devep(struct list_head *head, struct urb *urb)
-+{
-+ struct list_head *tmp;
-+ struct urb *u;
-+
-+ if (!head || !urb)
-+ return NULL;
-+
-+ tmp = head->next;
-+
-+ while (tmp != head) {
-+ u = list_entry(tmp, struct urb, urb_list);
-+ if ((usb_pipe_endpdev(u->pipe)) == (usb_pipe_endpdev(urb->pipe)))
-+ return u;
-+ tmp = tmp->next;
-+ }
-+
-+ return NULL;
-+}
-+
-+/*
-+ * This function is called by the USB core API when an URB is available to
-+ * process.
-+ */
-+static int sl811_submit_urb(struct urb *urb)
-+{
-+ struct sl811_hc *hc = urb->dev->bus->hcpriv;
-+ unsigned int pipe = urb->pipe;
-+ struct list_head *head = NULL;
-+ unsigned long flags;
-+ int bustime;
-+ int ret = 0;
-+
-+ if (!urb) {
-+ PDEBUG(1, "urb is null");
-+ return -EINVAL;
-+ }
-+
-+ if (urb->hcpriv) {
-+ PDEBUG(1, "urbp is not null, urb = %p, urbp = %p", urb, urb->hcpriv);
-+ return -EINVAL;
-+ }
-+
-+ if (!urb->dev || !urb->dev->bus || !hc) {
-+ PDEBUG(1, "dev or bus or hc is null");
-+ return -ENODEV;
-+ }
-+
-+ if (usb_endpoint_halted(urb->dev, usb_pipeendpoint(pipe), usb_pipeout(pipe))) {
-+ PDEBUG(2, "sl811_submit_urb: endpoint_halted");
-+ return -EPIPE;
-+ }
-+
-+ if (usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)) > SL811_DATA_LIMIT) {
-+ printk(KERN_ERR "Packet size is big for SL811, should < %d!\n", SL811_DATA_LIMIT);
-+ return -EINVAL;
-+ }
-+
-+ /* a request to the virtual root hub */
-+ if (usb_pipedevice(pipe) == hc->rh.devnum)
-+ return sl811_rh_submit_urb(urb);
-+
-+ spin_lock_irqsave(&hc->hc_lock, flags);
-+ spin_lock(&urb->lock);
-+
-+ switch (usb_pipetype(urb->pipe)) {
-+ case PIPE_ISOCHRONOUS:
-+ head = &hc->iso_list;
-+ break;
-+ case PIPE_INTERRUPT:
-+ head = &hc->intr_list;
-+ break;
-+ case PIPE_CONTROL:
-+ head = &hc->ctrl_list;
-+ break;
-+ case PIPE_BULK:
-+ head = &hc->bulk_list;
-+ break;
-+ }
-+
-+ if (sl811_find_same_devep(head, urb)) {
-+ list_add(&urb->urb_list, &hc->wait_list);
-+ PDEBUG(4, "add to wait list");
-+ goto out_unlock;
-+ }
-+
-+ if (!sl811_alloc_urb_priv(urb)) {
-+ ret = -ENOMEM;
-+ goto out_unlock;
-+ }
-+
-+ switch (usb_pipetype(urb->pipe)) {
-+ case PIPE_ISOCHRONOUS:
-+ if (urb->number_of_packets <= 0) {
-+ ret = -EINVAL;
-+ break;
-+ }
-+ bustime = usb_check_bandwidth(urb->dev, urb);
-+ if (bustime < 0) {
-+ ret = bustime;
-+ break;
-+ }
-+ if (!(ret = sl811_submit_isochronous(urb)))
-+ usb_claim_bandwidth(urb->dev, urb, bustime, 1);
-+ break;
-+ case PIPE_INTERRUPT:
-+ bustime = usb_check_bandwidth(urb->dev, urb);
-+ if (bustime < 0)
-+ ret = bustime;
-+ else if (!(ret = sl811_submit_interrupt(urb)))
-+ usb_claim_bandwidth(urb->dev, urb, bustime, 0);
-+ break;
-+ case PIPE_CONTROL:
-+ ret = sl811_submit_control(urb);
-+ break;
-+ case PIPE_BULK:
-+ ret = sl811_submit_bulk(urb);
-+ break;
-+ }
-+
-+ if (!ret) {
-+ ((struct sl811_urb_priv *)urb->hcpriv)->inserttime = jiffies;
-+ list_add(&urb->urb_list, head);
-+ PDEBUG(4, "add to type list");
-+ urb->status = -EINPROGRESS;
-+ if (++hc->active_urbs == 1)
-+ sl811_enable_interrupt(hc);
-+ goto out_unlock;
-+ } else {
-+ PDEBUG(2, "submit urb fail! error = %d", ret);
-+ sl811_free_urb_priv(urb);
-+ }
-+
-+out_unlock:
-+ spin_unlock(&urb->lock);
-+ spin_unlock_irqrestore(&hc->hc_lock, flags);
-+
-+ return ret;
-+}
-+
-+/*
-+ * Submit the urb the wait list.
-+ */
-+static int sl811_submit_urb_with_lock(struct urb *urb)
-+{
-+ struct sl811_hc *hc = urb->dev->bus->hcpriv;
-+ struct list_head *head = NULL;
-+ int bustime;
-+ int ret = 0;
-+
-+ spin_lock(&urb->lock);
-+
-+ switch (usb_pipetype(urb->pipe)) {
-+ case PIPE_ISOCHRONOUS:
-+ head = &hc->iso_list;
-+ break;
-+ case PIPE_INTERRUPT:
-+ head = &hc->intr_list;
-+ break;
-+ case PIPE_CONTROL:
-+ head = &hc->ctrl_list;
-+ break;
-+ case PIPE_BULK:
-+ head = &hc->bulk_list;
-+ break;
-+ }
-+
-+ if (!sl811_alloc_urb_priv(urb)) {
-+ ret = -ENOMEM;
-+ goto out_unlock;
-+ }
-+
-+ switch (usb_pipetype(urb->pipe)) {
-+ case PIPE_ISOCHRONOUS:
-+ if (urb->number_of_packets <= 0) {
-+ ret = -EINVAL;
-+ break;
-+ }
-+ bustime = usb_check_bandwidth(urb->dev, urb);
-+ if (bustime < 0) {
-+ ret = bustime;
-+ break;
-+ }
-+ if (!(ret = sl811_submit_isochronous(urb)))
-+ usb_claim_bandwidth(urb->dev, urb, bustime, 1);
-+ break;
-+ case PIPE_INTERRUPT:
-+ bustime = usb_check_bandwidth(urb->dev, urb);
-+ if (bustime < 0)
-+ ret = bustime;
-+ else if (!(ret = sl811_submit_interrupt(urb)))
-+ usb_claim_bandwidth(urb->dev, urb, bustime, 0);
-+ break;
-+ case PIPE_CONTROL:
-+ ret = sl811_submit_control(urb);
-+ break;
-+ case PIPE_BULK:
-+ ret = sl811_submit_bulk(urb);
-+ break;
-+ }
-+
-+ if (ret == 0) {
-+ ((struct sl811_urb_priv *)urb->hcpriv)->inserttime = jiffies;
-+ list_add(&urb->urb_list, head);
-+ PDEBUG(4, "add to type list");
-+ urb->status = -EINPROGRESS;
-+ if (++hc->active_urbs == 1)
-+ sl811_enable_interrupt(hc);
-+ goto out_unlock;
-+ } else {
-+ PDEBUG(2, "submit urb fail! error = %d", ret);
-+ sl811_free_urb_priv(urb);
-+ }
-+
-+out_unlock:
-+ spin_unlock(&urb->lock);
-+
-+ return ret;
-+}
-+
-+/*
-+ * Reset the urb
-+ */
-+static void sl811_reset_urb(struct urb *urb)
-+{
-+ struct sl811_urb_priv *urbp = urb->hcpriv;
-+
-+ switch (usb_pipetype(urb->pipe)) {
-+ case PIPE_ISOCHRONOUS:
-+ sl811_reset_isochronous(urb);
-+ break;
-+ case PIPE_INTERRUPT:
-+ sl811_reset_interrupt(urb);
-+ break;
-+ case PIPE_CONTROL:
-+ return;
-+ case PIPE_BULK:
-+ sl811_reset_bulk(urb);
-+ break;
-+ }
-+ urbp->inserttime = jiffies;
-+}
-+
-+/*
-+ * Return the result of a transfer
-+ */
-+static void sl811_result_urb(struct urb *urb)
-+{
-+ struct sl811_urb_priv *urbp = urb->hcpriv;
-+ struct sl811_hc *hc = urb->dev->bus->hcpriv;
-+ struct list_head *head = NULL;
-+ struct urb *u = NULL;
-+ int reset = 0;
-+ int ring = 0;
-+
-+ if (urb->status != -EINPROGRESS) {
-+ PDEBUG(1, "urb status is not EINPROGRESS!");
-+ return ;
-+ }
-+
-+ spin_lock(&urb->lock);
-+
-+ switch (usb_pipetype(urb->pipe)) {
-+ case PIPE_ISOCHRONOUS:
-+ head = &hc->iso_list;
-+ sl811_result_isochronous(urb);
-+
-+ // if the urb is not unlink and is in a urb "ring", we reset it
-+ if (!urbp->unlink && urb->next)
-+ ring = 1;
-+ break;
-+ case PIPE_INTERRUPT:
-+ head = &hc->intr_list;
-+ sl811_result_interrupt(urb);
-+
-+ // if the urb is not unlink and not "once" query, we reset.
-+ if (!urbp->unlink && urb->interval)
-+ reset = 1;
-+ break;
-+ case PIPE_CONTROL:
-+ head = &hc->ctrl_list;
-+ sl811_result_control(urb);
-+ break;
-+ case PIPE_BULK:
-+ head = &hc->bulk_list;
-+ sl811_result_bulk(urb);
-+
-+ // if the urb is not unlink and is in a urb "ring", we reset it
-+ if (!urbp->unlink && urb->next)
-+ ring = 1;
-+ break;
-+ }
-+
-+ PDEBUG(4, "result urb status = %d", urb->status);
-+
-+ if (ring && urb->next == urb)
-+ reset = 1;
-+
-+ if (!reset) {
-+ switch (usb_pipetype(urb->pipe)) {
-+ case PIPE_ISOCHRONOUS:
-+ usb_release_bandwidth(urb->dev, urb, 1);
-+ break;
-+ case PIPE_INTERRUPT:
-+ usb_release_bandwidth(urb->dev, urb, 0);
-+ break;
-+ }
-+ sl811_free_urb_priv(urb);
-+ }
-+
-+ spin_unlock(&urb->lock);
-+
-+ if (urb->complete)
-+ urb->complete(urb);
-+
-+ if (reset) {
-+ spin_lock(&urb->lock);
-+ sl811_reset_urb(urb);
-+ if (usb_pipeint(urb->pipe))
-+ list_add(&urb->urb_list, &hc->idle_intr_list);
-+ else
-+ list_add(&urb->urb_list, head);
-+ spin_unlock(&urb->lock);
-+ } else {
-+ if (--hc->active_urbs <= 0) {
-+ hc->active_urbs = 0;
-+ sl811_disable_interrupt(hc);
-+ }
-+
-+ if (ring)
-+ u = urb->next;
-+ else
-+ u = sl811_find_same_devep(&hc->wait_list, urb);
-+
-+ if (u) {
-+ if (!list_empty(&u->urb_list))
-+ list_del(&u->urb_list);
-+ if (sl811_submit_urb_with_lock(u))
-+ list_add(&u->urb_list, &hc->wait_list);
-+ }
-+ }
-+}
-+
-+
-+#ifdef SL811_TIMEOUT
-+
-+/*
-+ * Unlink the urb from the urb list
-+ */
-+static int sl811_unlink_urb(struct urb *urb)
-+{
-+ unsigned long flags;
-+ struct sl811_hc *hc;
-+ struct sl811_urb_priv *urbp;
-+ int call = 0;
-+ int schedule = 0;
-+ int count = 0;
-+
-+ if (!urb) {
-+ PDEBUG(1, "urb is null");
-+ return -EINVAL;
-+ }
-+
-+ if (!urb->dev || !urb->dev->bus) {
-+ PDEBUG(1, "dev or bus is null");
-+ return -ENODEV;
-+ }
-+
-+ hc = urb->dev->bus->hcpriv;
-+ urbp = urb->hcpriv;
-+
-+ /* a request to the virtual root hub */
-+ if (usb_pipedevice(urb->pipe) == hc->rh.devnum)
-+ return sl811_rh_unlink_urb(urb);
-+
-+ spin_lock_irqsave(&hc->hc_lock, flags);
-+ spin_lock(&urb->lock);
-+
-+ // in wait list
-+ if (sl811_find_same_urb(&hc->wait_list, urb)) {
-+ PDEBUG(4, "unlink urb in wait list");
-+ list_del_init(&urb->urb_list);
-+ urb->status = -ENOENT;
-+ call = 1;
-+ goto out;
-+ }
-+
-+ // in intr idle list.
-+ if (sl811_find_same_urb(&hc->idle_intr_list, urb)) {
-+ PDEBUG(4, "unlink urb in idle intr list");
-+ list_del_init(&urb->urb_list);
-+ urb->status = -ENOENT;
-+ sl811_free_urb_priv(urb);
-+ usb_release_bandwidth(urb->dev, urb, 0);
-+ if (--hc->active_urbs <= 0) {
-+ hc->active_urbs = 0;
-+ sl811_disable_interrupt(hc);
-+ }
-+ call = 1;
-+ goto out;
-+ }
-+
-+ if (urb->status == -EINPROGRESS) {
-+ PDEBUG(3, "urb is still in progress");
-+ urbp->unlink = 1;
-+
-+re_unlink:
-+ // Is it in progress?
-+ urbp = urb->hcpriv;
-+ if (urbp && hc->cur_td == urbp->cur_td) {
-+ ++count;
-+ if (sl811_read(hc, 0) & SL811_USB_CTRL_ARM) {
-+ PDEBUG(3, "unlink: cur td is still in progress! count = %d", count);
-+re_schedule:
-+ schedule = 1;
-+ spin_unlock(&urb->lock);
-+ spin_unlock_irqrestore(&hc->hc_lock, flags);
-+ schedule_timeout(HZ/50);
-+ spin_lock_irqsave(&hc->hc_lock, flags);
-+ spin_lock(&urb->lock);
-+ } else {
-+ PDEBUG(3, "unlink: lost of interrupt? do parse! count = %d", count);
-+ spin_unlock(&urb->lock);
-+ sl811_transfer_done(hc, 0);
-+ spin_lock(&urb->lock);
-+ }
-+ goto re_unlink;
-+ }
-+
-+ if (list_empty(&urb->urb_list)) {
-+ PDEBUG(3, "unlink: list empty!");
-+ goto out;
-+ }
-+
-+ if (urb->transfer_flags & USB_TIMEOUT_KILLED) {
-+ PDEBUG(3, "unlink: time out killed");
-+ // it is timeout killed by us
-+ goto result;
-+ } else if (urb->transfer_flags & USB_ASYNC_UNLINK) {
-+ // we do nothing, just let it be processing later
-+ PDEBUG(3, "unlink async, do nothing");
-+ goto out;
-+ } else {
-+ // synchron without callback
-+ PDEBUG(3, "unlink synchron, we wait the urb complete or timeout");
-+ if (schedule == 0) {
-+ PDEBUG(3, "goto re_schedule");
-+ goto re_schedule;
-+ } else {
-+ PDEBUG(3, "already scheduled");
-+ goto result;
-+ }
-+ }
-+ } else if (!list_empty(&urb->urb_list)) {
-+ PDEBUG(1, "urb = %p, status = %d is in a list, why?", urb, urb->status);
-+ //list_del_init(&urb->urb_list);
-+ //call = 1;
-+ }
-+
-+out:
-+ spin_unlock(&urb->lock);
-+ spin_unlock_irqrestore(&hc->hc_lock, flags);
-+
-+ if (call && urb->complete)
-+ urb->complete(urb);
-+
-+ return 0;
-+
-+result:
-+ spin_unlock(&urb->lock);
-+
-+ list_del_init(&urb->urb_list);
-+ sl811_result_urb(urb);
-+
-+ spin_unlock_irqrestore(&hc->hc_lock, flags);
-+
-+ return 0;
-+}
-+
-+#else
-+
-+/*
-+ * Unlink the urb from the urb list
-+ */
-+static int sl811_unlink_urb(struct urb *urb)
-+{
-+ unsigned long flags;
-+ struct sl811_hc *hc;
-+ struct sl811_urb_priv *urbp;
-+ int call = 0;
-+
-+ if (!urb) {
-+ PDEBUG(1, "urb is null");
-+ return -EINVAL;
-+ }
-+
-+ if (!urb->dev || !urb->dev->bus) {
-+ PDEBUG(1, "dev or bus is null");
-+ return -ENODEV;
-+ }
-+
-+ hc = urb->dev->bus->hcpriv;
-+ urbp = urb->hcpriv;
-+
-+ /* a request to the virtual root hub */
-+ if (usb_pipedevice(urb->pipe) == hc->rh.devnum)
-+ return sl811_rh_unlink_urb(urb);
-+
-+ spin_lock_irqsave(&hc->hc_lock, flags);
-+ spin_lock(&urb->lock);
-+
-+ // in wait list
-+ if (sl811_find_same_urb(&hc->wait_list, urb)) {
-+ PDEBUG(2, "unlink urb in wait list");
-+ list_del_init(&urb->urb_list);
-+ urb->status = -ENOENT;
-+ call = 1;
-+ goto out;
-+ }
-+
-+ if (urb->status == -EINPROGRESS) {
-+ PDEBUG(2, "urb is still in progress");
-+ urbp->unlink = 1;
-+
-+ // Is it in progress?
-+ urbp = urb->hcpriv;
-+ if (urbp && hc->cur_td == urbp->cur_td) {
-+ // simple, let it out
-+ PDEBUG(2, "unlink: cur td is still in progress!");
-+ hc->cur_td = NULL;
-+ }
-+
-+ goto result;
-+ } else if (!list_empty(&urb->urb_list)) {
-+ PDEBUG(1, "urb = %p, status = %d is in a list, why?", urb, urb->status);
-+ list_del_init(&urb->urb_list);
-+ if (urbp)
-+ goto result;
-+ else
-+ call = 1;
-+ }
-+
-+out:
-+ spin_unlock(&urb->lock);
-+ spin_unlock_irqrestore(&hc->hc_lock, flags);
-+
-+ if (call && urb->complete)
-+ urb->complete(urb);
-+
-+ return 0;
-+
-+result:
-+ spin_unlock(&urb->lock);
-+
-+ list_del_init(&urb->urb_list);
-+ sl811_result_urb(urb);
-+
-+ spin_unlock_irqrestore(&hc->hc_lock, flags);
-+
-+ return 0;
-+}
-+
-+#endif
-+
-+static int sl811_get_current_frame_number(struct usb_device *usb_dev)
-+{
-+ return ((struct sl811_hc *)(usb_dev->bus->hcpriv))->frame_number;
-+}
-+
-+static struct usb_operations sl811_device_operations =
-+{
-+ sl811_alloc_dev_priv,
-+ sl811_free_dev_priv,
-+ sl811_get_current_frame_number,
-+ sl811_submit_urb,
-+ sl811_unlink_urb
-+};
-+
-+/*
-+ * This functions transmit a td.
-+ */
-+static inline void sl811_trans_cur_td(struct sl811_hc *hc, struct sl811_td *td)
-+{
-+ sl811_print_td(4, td);
-+ sl811_write_buf(hc, SL811_ADDR_A, &td->addr, 4);
-+ if (td->len && (td->ctrl & SL811_USB_CTRL_DIR_OUT))
-+ sl811_write_buf(hc, td->addr, td->buf, td->len);
-+
-+ sl811_write(hc, SL811_CTRL_A, td->ctrl);
-+}
-+
-+
-+/*
-+ * This function checks the status of the transmitted or received packet
-+ * and copy the data from the SL811HS register into a buffer.
-+ */
-+static void sl811_parse_cur_td(struct sl811_hc *hc, struct sl811_td *td)
-+{
-+ struct urb *urb = td->urb;
-+#ifdef SL811_DEBUG
-+ int dev = usb_pipedevice(td->urb->pipe);
-+ int ep = usb_pipeendpoint(td->urb->pipe);
-+#endif
-+
-+ sl811_read_buf(hc, SL811_STS_A, &td->status, 2);
-+
-+ if (td->status & SL811_USB_STS_ACK) {
-+ td->done = 1;
-+
-+/* if ((td->ctrl & SL811_USB_CTRL_TOGGLE_1) != (td->status & SL811_USB_STS_TOGGLE_1)) {
-+ PDEBUG(2, "dev %d endpoint %d unexpect data toggle!", dev, ep);
-+ td->td_status = -EILSEQ;
-+ }
-+*/
-+ if (!(td->ctrl & SL811_USB_CTRL_DIR_OUT) && td->len > 0)
-+ sl811_read_buf(hc, td->addr, td->buf, td->len - td->left);
-+
-+ if (td->left && (urb->transfer_flags & USB_DISABLE_SPD)) {
-+ PDEBUG(2, "dev %d endpoint %d unexpect short packet! td = %p", dev, ep, td);
-+ td->td_status = -EREMOTEIO;
-+ } else
-+ td->td_status = 0;
-+ } else if (td->status & SL811_USB_STS_STALL) {
-+ PDEBUG(2, "dev %d endpoint %d halt, td = %p", dev, ep, td);
-+ td->td_status = -EPIPE;
-+ if (urb->dev)
-+ usb_endpoint_halt(td->urb->dev, usb_pipeendpoint(td->urb->pipe), usb_pipeout(td->urb->pipe));
-+ td->done = 1;
-+ } else if (td->status & SL811_USB_STS_OVERFLOW) {
-+ PDEBUG(1, "dev %d endpoint %d overflow, sl811 only support packet less than %d", dev, ep, SL811_DATA_LIMIT);
-+ td->td_status = -EOVERFLOW;
-+ td->done = 1;
-+ } else if (td->status & SL811_USB_STS_TIMEOUT ) {
-+ PDEBUG(2, "dev %d endpoint %d timeout, td = %p", dev, ep, td);
-+ td->td_status = -ETIMEDOUT;
-+ if (--td->errcnt == 0)
-+ td->done = 1;
-+ } else if (td->status & SL811_USB_STS_ERROR) {
-+ PDEBUG(2, "dev %d endpoint %d error, td = %p", dev, ep, td);
-+ td->td_status = -EILSEQ;
-+ if (--td->errcnt == 0)
-+ td->done = 1;
-+ } else if (td->status & SL811_USB_STS_NAK) {
-+ ++td->nakcnt;
-+ PDEBUG(3, "dev %d endpoint %d nak, td = %p, count = %d", dev, ep, td, td->nakcnt);
-+ td->td_status = -EINPROGRESS;
-+ if (!usb_pipeslow(td->urb->pipe) && td->nakcnt > 1024) {
-+ PDEBUG(2, "too many naks, td = %p, count = %d", td, td->nakcnt);
-+ td->td_status = -ETIMEDOUT;
-+ td->done = 1;
-+ }
-+ }
-+
-+ sl811_print_td(4, td);
-+}
-+
-+/*
-+ * This function checks the status of current urb.
-+ */
-+static int sl811_parse_cur_urb(struct urb *urb)
-+{
-+ struct sl811_urb_priv *urbp = urb->hcpriv;
-+ struct sl811_td *td = urbp->cur_td;
-+ struct list_head *tmp;
-+
-+ sl811_print_td(5, td);
-+
-+ // this td not done yet.
-+ if (!td->done)
-+ return 0;
-+
-+ // the last ld, so the urb is done.
-+ if (td == urbp->last_td) {
-+ PDEBUG(4, "urb = %p is done success", td->urb);
-+ if (usb_pipeisoc(td->urb->pipe))
-+ PDEBUG(4, "ISO URB DONE, td = %p", td);
-+ return 1;
-+ }
-+
-+ // iso transfer, we always advance to next td
-+ if (usb_pipeisoc(td->urb->pipe)) {
-+ tmp = &td->td_list;
-+ tmp = tmp->next;
-+ urbp->cur_td = list_entry(tmp, struct sl811_td, td_list);
-+ PDEBUG(4, "ISO NEXT, td = %p", urbp->cur_td);
-+ return 0;
-+ }
-+
-+ // some error occur, so the urb is done.
-+ if (td->td_status) {
-+ PDEBUG(3, "urb = %p is done error, td status is = %d", td->urb, td->td_status);
-+ return 1;
-+ }
-+
-+ // short packet.
-+ if (td->left) {
-+ if (usb_pipecontrol(td->urb->pipe)) {
-+ // control packet, we advance to the last td
-+ PDEBUG(3, "ctrl short packet, advance to last td");
-+ urbp->cur_td = urbp->last_td;
-+ return 0;
-+ } else {
-+ // interrut and bulk packet, urb is over.
-+ PDEBUG(3, "bulk or intr short packet, urb is over");
-+ return 1;
-+ }
-+ }
-+
-+ // we advance to next td.
-+ tmp = &td->td_list;
-+ tmp = tmp->next;
-+ urbp->cur_td = list_entry(tmp, struct sl811_td, td_list);
-+#ifdef SL811_DEBUG
-+ PDEBUG(4, "advance to the next td, urb = %p, td = %p", urb, urbp->cur_td);
-+ sl811_print_td(5, urbp->cur_td);
-+ if (td == urbp->cur_td)
-+ PDEBUG(1, "bug!!!");
-+#endif
-+ return 0;
-+}
-+
-+/*
-+ * Find the next td to transfer.
-+ */
-+static inline struct sl811_td* sl811_schedule_next_td(struct urb *urb, struct sl811_td *cur_td)
-+{
-+ struct sl811_urb_priv *urbp = urb->hcpriv;
-+
-+ PDEBUG(4, "urb at %p, cur td at %p", urb, cur_td);
-+
-+ // iso don't schedule the td in the same frame.
-+ if (usb_pipeisoc(cur_td->urb->pipe))
-+ return NULL;
-+
-+ // cur td is not complete
-+ if (!cur_td->done)
-+ return NULL;
-+
-+ // here, urbp->cur_td is already the next td;
-+ return urbp->cur_td;
-+}
-+
-+/*
-+ * Scan the list to find a active urb
-+ */
-+static inline struct urb* sl811_get_list_next_urb(struct sl811_hc *hc, struct list_head *next)
-+{
-+ struct urb *urb;
-+ int i;
-+
-+ if (list_empty(next))
-+ return NULL;
-+
-+ if (next == hc->cur_list)
-+ return NULL;
-+
-+ for (i = 0; i < 4; ++i)
-+ if (next == &hc->urb_list[i])
-+ return NULL;
-+
-+ urb = list_entry(next, struct urb, urb_list);
-+ PDEBUG(4, "next urb in list is at %p", urb);
-+
-+ return urb;
-+}
-+
-+/*
-+ * Find the next td to transfer.
-+ */
-+static struct sl811_td* sl811_schedule_next_urb(struct sl811_hc *hc, struct list_head *next)
-+{
-+ struct urb *urb = NULL;
-+ int back_loop = 1;
-+ struct list_head *old_list = hc->cur_list;
-+
-+ // try to get next urb in the same list.
-+ if (next) {
-+ urb = sl811_get_list_next_urb(hc, next);
-+ if (!urb)
-+ ++hc->cur_list;
-+ }
-+
-+ // try other list.
-+ if (!urb) {
-+re_loop:
-+ // try all the list.
-+ while (hc->cur_list < &hc->urb_list[4]) {
-+ if ((urb = sl811_get_list_next_urb(hc, hc->cur_list->next)))
-+ return ((struct sl811_urb_priv *)urb->hcpriv)->cur_td;
-+ ++hc->cur_list;
-+ }
-+ // the last list is try
-+ if (back_loop && (old_list >= &hc->ctrl_list)) {
-+ hc->cur_list = &hc->ctrl_list;
-+ back_loop = 0;
-+ goto re_loop;
-+ }
-+ }
-+
-+ if (hc->cur_list > &hc->urb_list[3])
-+ hc->cur_list = &hc->ctrl_list;
-+
-+ return NULL;
-+}
-+
-+/*
-+ * This function process the transfer rusult.
-+ */
-+static void sl811_transfer_done(struct sl811_hc *hc, int sof)
-+{
-+ struct sl811_td *cur_td = hc->cur_td, *next_td = NULL;
-+ struct urb *cur_urb = NULL;
-+ struct list_head *next = NULL;
-+ int done;
-+
-+ PDEBUG(5, "enter");
-+
-+ if (cur_td == NULL) {
-+ PDEBUG(1, "in done interrupt, but td is null, be already parsed?");
-+ return ;
-+ }
-+
-+ cur_urb = cur_td->urb;
-+ hc->cur_td = NULL;
-+ next = &cur_urb->urb_list;
-+ next = next->next;
-+
-+ spin_lock(&cur_urb->lock);
-+ sl811_parse_cur_td(hc, cur_td);
-+ done = sl811_parse_cur_urb(cur_urb);
-+ spin_unlock(&cur_urb->lock);
-+
-+ if (done) {
-+ list_del_init(&cur_urb->urb_list);
-+ cur_td = NULL;
-+ sl811_result_urb(cur_urb);
-+ }
-+
-+ if (sof)
-+ return ;
-+
-+ if (!done) {
-+ next_td = sl811_schedule_next_td(cur_urb, cur_td);
-+ if (next_td && next_td != cur_td && (sl811_calc_bus_remainder(hc) > next_td->bustime)) {
-+ hc->cur_td = next_td;
-+ PDEBUG(5, "ADD TD");
-+ sl811_trans_cur_td(hc, next_td);
-+ return ;
-+ }
-+ }
-+
-+ while (1) {
-+ next_td = sl811_schedule_next_urb(hc, next);
-+ if (!next_td)
-+ return;
-+ if (next_td == cur_td)
-+ return;
-+ next = &next_td->urb->urb_list;
-+ next = next->next;
-+ if (sl811_calc_bus_remainder(hc) > next_td->bustime) {
-+ hc->cur_td = next_td;
-+ PDEBUG(5, "ADD TD");
-+ sl811_trans_cur_td(hc, next_td);
-+ return ;
-+ }
-+ }
-+}
-+
-+/*
-+ *
-+ */
-+static void inline sl811_dec_intr_interval(struct sl811_hc *hc)
-+{
-+ struct list_head *head, *tmp;
-+ struct urb *urb;
-+ struct sl811_urb_priv *urbp;
-+
-+ if (list_empty(&hc->idle_intr_list))
-+ return ;
-+
-+ head = &hc->idle_intr_list;
-+ tmp = head->next;
-+
-+ while (tmp != head) {
-+ urb = list_entry(tmp, struct urb, urb_list);
-+ tmp = tmp->next;
-+ spin_lock(&urb->lock);
-+ urbp = urb->hcpriv;
-+ if (--urbp->interval == 0) {
-+ list_del(&urb->urb_list);
-+ list_add(&urb->urb_list, &hc->intr_list);
-+ PDEBUG(4, "intr urb active");
-+ }
-+ spin_unlock(&urb->lock);
-+ }
-+}
-+
-+/*
-+ * The sof interrupt is happen.
-+ */
-+static void sl811_start_sof(struct sl811_hc *hc)
-+{
-+ struct sl811_td *next_td;
-+#ifdef SL811_DEBUG
-+ static struct sl811_td *repeat_td = NULL;
-+ static int repeat_cnt = 1;
-+#endif
-+ if (++hc->frame_number > 1024)
-+ hc->frame_number = 0;
-+
-+ if (hc->active_urbs == 0)
-+ return ;
-+
-+ sl811_dec_intr_interval(hc);
-+
-+ if (hc->cur_td) {
-+ if (sl811_read(hc, 0) & SL811_USB_CTRL_ARM) {
-+#ifdef SL811_DEBUG
-+ if (repeat_td == hc->cur_td)
-+ ++repeat_cnt;
-+ else {
-+ if (repeat_cnt >= 2)
-+ PDEBUG(2, "cur td = %p repeat %d", hc->cur_td, repeat_cnt);
-+ repeat_cnt = 1;
-+ repeat_td = hc->cur_td;
-+ }
-+#endif
-+ return ;
-+ } else {
-+ PDEBUG(2, "lost of interrupt in sof? do parse!");
-+ sl811_transfer_done(hc, 1);
-+
-+ // let this frame idle
-+ return;
-+ }
-+ }
-+
-+ hc->cur_list = &hc->iso_list;
-+
-+ if (hc->active_urbs == 0)
-+ return ;
-+
-+ next_td = sl811_schedule_next_urb(hc, NULL);
-+ if (!next_td) {
-+#ifdef SL811_DEBUG
-+ if (list_empty(&hc->idle_intr_list))
-+ PDEBUG(2, "not schedule a td, why? urbs = %d", hc->active_urbs);
-+#endif
-+ return;
-+ }
-+ if (sl811_calc_bus_remainder(hc) > next_td->bustime) {
-+ hc->cur_td = next_td;
-+ sl811_trans_cur_td(hc, next_td);
-+ } else
-+ PDEBUG(2, "bus time if not enough, why?");
-+}
-+
-+/*
-+ * This function resets SL811HS controller and detects the speed of
-+ * the connecting device
-+ *
-+ * Return: 0 = no device attached; 1 = USB device attached
-+ */
-+static int sl811_hc_reset(struct sl811_hc *hc)
-+{
-+ int status ;
-+
-+ sl811_write(hc, SL811_CTRL2, SL811_CTL2_HOST | SL811_12M_HI);
-+ sl811_write(hc, SL811_CTRL1, SL811_CTRL1_RESET);
-+
-+ mdelay(20);
-+
-+ // Disable hardware SOF generation, clear all irq status.
-+ sl811_write(hc, SL811_CTRL1, 0);
-+ mdelay(2);
-+ sl811_write(hc, SL811_INTRSTS, 0xff);
-+ status = sl811_read(hc, SL811_INTRSTS);
-+
-+ if (status & SL811_INTR_NOTPRESENT) {
-+ // Device is not present
-+ PDEBUG(0, "Device not present");
-+ hc->rh_status.wPortStatus &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE);
-+ hc->rh_status.wPortChange |= USB_PORT_STAT_C_CONNECTION;
-+ sl811_write(hc, SL811_INTR, SL811_INTR_INSRMV);
-+ return 0;
-+ }
-+
-+ // Send SOF to address 0, endpoint 0.
-+ sl811_write(hc, SL811_LEN_B, 0);
-+ sl811_write(hc, SL811_PIDEP_B, PIDEP(USB_PID_SOF, 0));
-+ sl811_write(hc, SL811_DEV_B, 0x00);
-+ sl811_write (hc, SL811_SOFLOW, SL811_12M_HI);
-+
-+ if (status & SL811_INTR_SPEED_FULL) {
-+ /* full speed device connect directly to root hub */
-+ PDEBUG (0, "Full speed Device attached");
-+
-+ sl811_write(hc, SL811_CTRL1, SL811_CTRL1_RESET);
-+ mdelay(20);
-+ sl811_write(hc, SL811_CTRL2, SL811_CTL2_HOST | SL811_12M_HI);
-+ sl811_write(hc, SL811_CTRL1, SL811_CTRL1_SOF);
-+
-+ /* start the SOF or EOP */
-+ sl811_write(hc, SL811_CTRL_B, SL811_USB_CTRL_ARM);
-+ hc->rh_status.wPortStatus |= USB_PORT_STAT_CONNECTION;
-+ hc->rh_status.wPortStatus &= ~USB_PORT_STAT_LOW_SPEED;
-+ mdelay(2);
-+ sl811_write (hc, SL811_INTRSTS, 0xff);
-+ } else {
-+ /* slow speed device connect directly to root-hub */
-+ PDEBUG(0, "Low speed Device attached");
-+
-+ sl811_write(hc, SL811_CTRL1, SL811_CTRL1_RESET);
-+ mdelay(20);
-+ sl811_write(hc, SL811_CTRL2, SL811_CTL2_HOST | SL811_CTL2_DSWAP | SL811_12M_HI);
-+ sl811_write(hc, SL811_CTRL1, SL811_CTRL1_SPEED_LOW | SL811_CTRL1_SOF);
-+
-+ /* start the SOF or EOP */
-+ sl811_write(hc, SL811_CTRL_B, SL811_USB_CTRL_ARM);
-+ hc->rh_status.wPortStatus |= USB_PORT_STAT_CONNECTION | USB_PORT_STAT_LOW_SPEED;
-+ mdelay(2);
-+ sl811_write(hc, SL811_INTRSTS, 0xff);
-+ }
-+
-+ hc->rh_status.wPortChange |= USB_PORT_STAT_C_CONNECTION;
-+ sl811_write(hc, SL811_INTR, SL811_INTR_INSRMV);
-+
-+ return 1;
-+}
-+
-+/*
-+ * Interrupt service routine.
-+ */
-+static void sl811_interrupt(int irq, void *__hc, struct pt_regs * r)
-+{
-+ __u8 status;
-+ struct sl811_hc *hc = __hc;
-+
-+ status = sl811_read(hc, SL811_INTRSTS);
-+ if (status == 0)
-+ return ; /* Not me */
-+
-+ sl811_write(hc, SL811_INTRSTS, 0xff);
-+
-+ if (status & SL811_INTR_INSRMV) {
-+ sl811_write(hc, SL811_INTR, 0);
-+ sl811_write(hc, SL811_CTRL1, 0);
-+ // wait for device stable
-+ mdelay(100);
-+ sl811_hc_reset(hc);
-+ return ;
-+ }
-+
-+ spin_lock(&hc->hc_lock);
-+
-+ if (status & SL811_INTR_DONE_A) {
-+ if (status & SL811_INTR_SOF) {
-+ sl811_transfer_done(hc, 1);
-+ PDEBUG(4, "sof in done!");
-+ sl811_start_sof(hc);
-+ } else
-+ sl811_transfer_done(hc, 0);
-+ } else if (status & SL811_INTR_SOF)
-+ sl811_start_sof(hc);
-+
-+ spin_unlock(&hc->hc_lock);
-+
-+ return ;
-+}
-+
-+/*
-+ * This function allocates all data structure and store in the
-+ * private data structure.
-+ *
-+ * Return value : data structure for the host controller
-+ */
-+static struct sl811_hc* __devinit sl811_alloc_hc(void)
-+{
-+ struct sl811_hc *hc;
-+ struct usb_bus *bus;
-+ int i;
-+
-+ PDEBUG(4, "enter");
-+
-+ hc = (struct sl811_hc *)kmalloc(sizeof(struct sl811_hc), GFP_KERNEL);
-+ if (!hc)
-+ return NULL;
-+
-+ memset(hc, 0, sizeof(struct sl811_hc));
-+
-+ hc->rh_status.wPortStatus = USB_PORT_STAT_POWER;
-+ hc->rh_status.wPortChange = 0;
-+
-+ hc->active_urbs = 0;
-+ INIT_LIST_HEAD(&hc->hc_hcd_list);
-+ list_add(&hc->hc_hcd_list, &sl811_hcd_list);
-+
-+ init_waitqueue_head(&hc->waitq);
-+
-+ for (i = 0; i < 6; ++i)
-+ INIT_LIST_HEAD(&hc->urb_list[i]);
-+
-+ hc->cur_list = &hc->iso_list;
-+
-+ bus = usb_alloc_bus(&sl811_device_operations);
-+ if (!bus) {
-+ kfree (hc);
-+ return NULL;
-+ }
-+
-+ hc->bus = bus;
-+ bus->bus_name = MODNAME;
-+ bus->hcpriv = hc;
-+
-+ return hc;
-+}
-+
-+/*
-+ * This function De-allocate all resources
-+ */
-+static void sl811_release_hc(struct sl811_hc *hc)
-+{
-+ PDEBUG(4, "enter");
-+
-+ /* disconnect all devices */
-+ if (hc->bus->root_hub)
-+ usb_disconnect(&hc->bus->root_hub);
-+
-+ // Stop interrupt handle
-+ if (hc->irq)
-+ free_irq(hc->irq, hc);
-+ hc->irq = 0;
-+
-+ /* Stop interrupt for sharing */
-+ if (hc->addr_io) {
-+ /* Disable Interrupts */
-+ sl811_write(hc, SL811_INTR, 0);
-+
-+ /* Remove all Interrupt events */
-+ mdelay(2);
-+ sl811_write(hc, SL811_INTRSTS, 0xff);
-+ }
-+
-+ /* free io regions */
-+ sl811_release_regions(hc);
-+
-+ usb_deregister_bus(hc->bus);
-+ usb_free_bus(hc->bus);
-+
-+ list_del(&hc->hc_hcd_list);
-+ INIT_LIST_HEAD(&hc->hc_hcd_list);
-+
-+ kfree (hc);
-+}
-+
-+/*
-+ * This function request IO memory regions, request IRQ, and
-+ * allocate all other resources.
-+ *
-+ * Input: addr_io = first IO address
-+ * data_io = second IO address
-+ * irq = interrupt number
-+ *
-+ * Return: 0 = success or error condition
-+ */
-+static int __devinit sl811_found_hc(int addr_io, int data_io, int irq)
-+{
-+ struct sl811_hc *hc;
-+
-+ PDEBUG(4, "enter");
-+
-+ hc = sl811_alloc_hc();
-+ if (!hc)
-+ return -ENOMEM;
-+
-+ if (sl811_request_regions (hc, addr_io, data_io, MODNAME)) {
-+ PDEBUG(1, "ioport %X,%X is in use!", addr_io, data_io);
-+ sl811_release_hc(hc);
-+ return -EBUSY;
-+ }
-+
-+ if (sl811_reg_test(hc)) {
-+ PDEBUG(1, "SL811 register test failed!");
-+ sl811_release_hc(hc);
-+ return -ENODEV;
-+ }
-+
-+//#ifdef SL811_DEBUG_VERBOSE
-+ {
-+ __u8 u = sl811_read(hc, SL811_HWREV);
-+
-+ // Show the hardware revision of chip
-+ PDEBUG(1, "SL811 HW: %02Xh", u);
-+ switch (u & 0xF0) {
-+ case 0x00: PDEBUG(1, "SL11H"); break;
-+ case 0x10: PDEBUG(1, "SL811HS rev1.2"); break;
-+ case 0x20: PDEBUG(1, "SL811HS rev1.5"); break;
-+ default: PDEBUG(1, "Revision unknown!");
-+ }
-+ }
-+//#endif // SL811_DEBUG_VERBOSE
-+
-+ sl811_init_irq();
-+
-+ usb_register_bus(hc->bus);
-+
-+ if (request_irq(irq, sl811_interrupt, SA_SHIRQ, MODNAME, hc)) {
-+ PDEBUG(1, "request interrupt %d failed", irq);
-+ sl811_release_hc(hc);
-+ return -EBUSY;
-+ }
-+ hc->irq = irq;
-+
-+ printk(KERN_INFO __FILE__ ": USB SL811 at %08x,%08x, IRQ %d\n",
-+ hc->addr_io, hc->data_io, irq);
-+
-+ sl811_hc_reset(hc);
-+ sl811_connect_rh(hc);
-+
-+ return 0;
-+}
-+
-+/*
-+ * This is an init function, and it is the first function being called
-+ *
-+ * Return: 0 = success or error condition
-+ */
-+static int __init sl811_hcd_init(void)
-+{
-+ int ret = -ENODEV;
-+
-+ PDEBUG(4, "enter");
-+
-+ info(DRIVER_VERSION " : " DRIVER_DESC);
-+
-+#ifdef CONFIG_X86
-+ {
-+ int count;
-+ // registering some instance
-+ for (count = 0; count < MAX_CONTROLERS; count++) {
-+ if (io[count]) {
-+ ret = sl811_found_hc(io[count], io[count]+OFFSET_DATA_REG, irq[count]);
-+ if (ret)
-+ return (ret);
-+ }
-+ }
-+ }
-+#endif
-+#ifdef CONFIG_ARCH_RAMSES
-+ ret = sl811_found_hc(0,0,SL811HS_IRQ);
-+#endif
-+
-+ return ret;
-+}
-+
-+/*
-+ * This is a cleanup function, and it is called when module is unloaded.
-+ */
-+static void __exit sl811_hcd_cleanup(void)
-+{
-+ struct list_head *list = sl811_hcd_list.next;
-+ struct sl811_hc *hc;
-+
-+ PDEBUG(4, "enter");
-+
-+ for (; list != &sl811_hcd_list; ) {
-+ hc = list_entry(list, struct sl811_hc, hc_hcd_list);
-+ list = list->next;
-+ sl811_release_hc(hc);
-+ }
-+}
-+
-+module_init(sl811_hcd_init);
-+module_exit(sl811_hcd_cleanup);
-+
-+MODULE_AUTHOR(DRIVER_AUTHOR);
-+MODULE_DESCRIPTION(DRIVER_DESC);
---- /dev/null
-+++ linux-2.4.21/drivers/usb/host/sl811.h
-@@ -0,0 +1,177 @@
-+#ifndef __LINUX_SL811_H
-+#define __LINUX_SL811_H
-+
-+#define SL811_DEBUG
-+
-+#ifdef SL811_DEBUG
-+ #define PDEBUG(level, fmt, args...) \
-+ if (debug >= (level)) info("[%s:%d] " fmt, \
-+ __PRETTY_FUNCTION__, __LINE__ , ## args)
-+#else
-+ #define PDEBUG(level, fmt, args...) do {} while(0)
-+#endif
-+
-+//#define SL811_TIMEOUT
-+
-+/* Sl811 host control register */
-+#define SL811_CTRL_A 0x00
-+#define SL811_ADDR_A 0x01
-+#define SL811_LEN_A 0x02
-+#define SL811_STS_A 0x03 /* read */
-+#define SL811_PIDEP_A 0x03 /* write */
-+#define SL811_CNT_A 0x04 /* read */
-+#define SL811_DEV_A 0x04 /* write */
-+#define SL811_CTRL1 0x05
-+#define SL811_INTR 0x06
-+#define SL811_CTRL_B 0x08
-+#define SL811_ADDR_B 0x09
-+#define SL811_LEN_B 0x0A
-+#define SL811_STS_B 0x0B /* read */
-+#define SL811_PIDEP_B 0x0B /* write */
-+#define SL811_CNT_B 0x0C /* read */
-+#define SL811_DEV_B 0x0C /* write */
-+#define SL811_INTRSTS 0x0D /* write clears bitwise */
-+#define SL811_HWREV 0x0E /* read */
-+#define SL811_SOFLOW 0x0E /* write */
-+#define SL811_SOFCNTDIV 0x0F /* read */
-+#define SL811_CTRL2 0x0F /* write */
-+
-+/* USB control register bits (addr 0x00 and addr 0x08) */
-+#define SL811_USB_CTRL_ARM 0x01
-+#define SL811_USB_CTRL_ENABLE 0x02
-+#define SL811_USB_CTRL_DIR_OUT 0x04
-+#define SL811_USB_CTRL_ISO 0x10
-+#define SL811_USB_CTRL_SOF 0x20
-+#define SL811_USB_CTRL_TOGGLE_1 0x40
-+#define SL811_USB_CTRL_PREAMBLE 0x80
-+
-+/* USB status register bits (addr 0x03 and addr 0x0B) */
-+#define SL811_USB_STS_ACK 0x01
-+#define SL811_USB_STS_ERROR 0x02
-+#define SL811_USB_STS_TIMEOUT 0x04
-+#define SL811_USB_STS_TOGGLE_1 0x08
-+#define SL811_USB_STS_SETUP 0x10
-+#define SL811_USB_STS_OVERFLOW 0x20
-+#define SL811_USB_STS_NAK 0x40
-+#define SL811_USB_STS_STALL 0x80
-+
-+/* Control register 1 bits (addr 0x05) */
-+#define SL811_CTRL1_SOF 0x01
-+#define SL811_CTRL1_RESET 0x08
-+#define SL811_CTRL1_JKSTATE 0x10
-+#define SL811_CTRL1_SPEED_LOW 0x20
-+#define SL811_CTRL1_SUSPEND 0x40
-+
-+/* Interrut enable (addr 0x06) and interrupt status register bits (addr 0x0D) */
-+#define SL811_INTR_DONE_A 0x01
-+#define SL811_INTR_DONE_B 0x02
-+#define SL811_INTR_SOF 0x10
-+#define SL811_INTR_INSRMV 0x20
-+#define SL811_INTR_DETECT 0x40
-+#define SL811_INTR_NOTPRESENT 0x40
-+#define SL811_INTR_SPEED_FULL 0x80 /* only in status reg */
-+
-+/* HW rev and SOF lo register bits (addr 0x0E) */
-+#define SL811_HWR_HWREV 0xF0
-+
-+/* SOF counter and control reg 2 (addr 0x0F) */
-+#define SL811_CTL2_SOFHI 0x3F
-+#define SL811_CTL2_DSWAP 0x40
-+#define SL811_CTL2_HOST 0x80
-+
-+/* Set up for 1-ms SOF time. */
-+#define SL811_12M_LOW 0xE0
-+#define SL811_12M_HI 0x2E
-+
-+#define SL811_DATA_START 0x10
-+#define SL811_DATA_LIMIT 240
-+
-+
-+/* Requests: bRequest << 8 | bmRequestType */
-+#define RH_GET_STATUS 0x0080
-+#define RH_CLEAR_FEATURE 0x0100
-+#define RH_SET_FEATURE 0x0300
-+#define RH_SET_ADDRESS 0x0500
-+#define RH_GET_DESCRIPTOR 0x0680
-+#define RH_SET_DESCRIPTOR 0x0700
-+#define RH_GET_CONFIGURATION 0x0880
-+#define RH_SET_CONFIGURATION 0x0900
-+#define RH_GET_STATE 0x0280
-+#define RH_GET_INTERFACE 0x0A80
-+#define RH_SET_INTERFACE 0x0B00
-+#define RH_SYNC_FRAME 0x0C80
-+
-+
-+#define PIDEP(pid, ep) (((pid) & 0x0f) << 4 | (ep))
-+
-+/* Virtual Root HUB */
-+struct virt_root_hub {
-+ int devnum; /* Address of Root Hub endpoint */
-+ void *urb; /* interrupt URB of root hub */
-+ int send; /* active flag */
-+ int interval; /* intervall of roothub interrupt transfers */
-+ struct timer_list rh_int_timer; /* intervall timer for rh interrupt EP */
-+};
-+
-+struct sl811_td {
-+ /* hardware */
-+ __u8 ctrl; /* control register */
-+
-+ /* write */
-+ __u8 addr; /* base adrress register */
-+ __u8 len; /* base length register */
-+ __u8 pidep; /* PId and endpoint register */
-+ __u8 dev; /* device address register */
-+
-+ /* read */
-+ __u8 status; /* status register */
-+ __u8 left; /* transfer count register */
-+
-+ /* software */
-+ __u8 errcnt; /* error count, begin with 3 */
-+ __u8 done; /* is this td tranfer done */
-+ __u8 *buf; /* point to data buffer for tranfer */
-+ int bustime; /* the bus time need by this td */
-+ int td_status; /* the status of this td */
-+ int nakcnt; /* number of naks */
-+ struct urb *urb; /* the urb this td belongs to */
-+ struct list_head td_list; /* link to a list of the urb */
-+};
-+
-+struct sl811_urb_priv {
-+ struct urb *urb; /* the urb this priv beloings to */
-+ struct list_head td_list; /* list of all the td of this urb */
-+ struct sl811_td *cur_td; /* current td is in processing or it will be */
-+ struct sl811_td *first_td; /* the first td of this urb */
-+ struct sl811_td *last_td; /* the last td of this urb */
-+ int interval; /* the query time value for intr urb */
-+ int unlink; /* is the this urb unlinked */
-+ unsigned long inserttime; /* the time when insert to list */
-+};
-+
-+struct sl811_hc {
-+ spinlock_t hc_lock; /* Lock for this structure */
-+
-+ int irq; /* IRQ number this hc use */
-+ int addr_io; /* I/O address line address */
-+ int data_io; /* I/O data line address */
-+ struct virt_root_hub rh; /* root hub */
-+ struct usb_port_status rh_status;/* root hub port status */
-+ struct list_head urb_list[6]; /* set of urbs, the order is iso,intr,ctrl,bulk,inactive intr, wait */
-+ struct list_head *cur_list; /* the current list is in process */
-+ wait_queue_head_t waitq; /* deletion of URBs and devices needs a waitqueue */
-+ struct sl811_td *cur_td; /* point to the td is in process */
-+ struct list_head hc_hcd_list; /* list of all hci_hcd */
-+ struct usb_bus *bus; /* our bus */
-+ int active_urbs; /* total number of active usbs */
-+ int frame_number; /* the current frame number, we do't use it, any one need it? */
-+};
-+
-+#define iso_list urb_list[0] /* set of isoc urbs */
-+#define intr_list urb_list[1] /* ordered (tree) set of int urbs */
-+#define ctrl_list urb_list[2] /* set of ctrl urbs */
-+#define bulk_list urb_list[3] /* set of bulk urbs */
-+#define idle_intr_list urb_list[4] /* set of intr urbs in its idle time*/
-+#define wait_list urb_list[5] /* set of wait urbs */
-+
-+#endif
---- linux-2.4.21/drivers/usb/storage/transport.h~usb-sonycamera
-+++ linux-2.4.21/drivers/usb/storage/transport.h
-@@ -75,6 +75,8 @@
- #define US_PR_JUMPSHOT 0xf3 /* Lexar Jumpshot */
- #endif
-
-+#define US_PR_DEVICE 0xff /* Use device's value */
-+
- /*
- * Bulk only data structures
- */
---- linux-2.4.21/drivers/usb/storage/unusual_devs.h~usb-sonycamera
-+++ linux-2.4.21/drivers/usb/storage/unusual_devs.h
-@@ -223,10 +223,10 @@
- US_FL_FIX_INQUIRY | US_FL_START_STOP ),
-
- /* This entry is needed because the device reports Sub=ff */
--UNUSUAL_DEV( 0x054c, 0x0010, 0x0106, 0x0440,
-+UNUSUAL_DEV( 0x054c, 0x0010, 0x0106, 0x0450,
- "Sony",
-- "DSC-S30/S70/S75/505V/F505/F707/F717",
-- US_SC_SCSI, US_PR_CB, NULL,
-+ "DSC-S30/S70/S75/505V/F505/F707/F717/P8",
-+ US_SC_SCSI, US_PR_DEVICE, NULL,
- US_FL_SINGLE_LUN | US_FL_START_STOP | US_FL_MODE_XLATE ),
-
- /* Reported by wim@geeks.nl */
---- linux-2.4.21/drivers/usb/storage/usb.c~usb-sonycamera
-+++ linux-2.4.21/drivers/usb/storage/usb.c
-@@ -622,7 +622,9 @@
-
- /* Determine subclass and protocol, or copy from the interface */
- subclass = unusual_dev->useProtocol;
-- protocol = unusual_dev->useTransport;
-+ protocol = (unusual_dev->useTransport == US_PR_DEVICE) ?
-+ altsetting->bInterfaceProtocol :
-+ unusual_dev->useTransport;
- flags = unusual_dev->flags;
-
- /*
---- linux-2.4.21/drivers/video/fbcon-cfb16.c~fb-turn180
-+++ linux-2.4.21/drivers/video/fbcon-cfb16.c
-@@ -34,6 +34,41 @@
- #endif
- };
-
-+static u8 mirrortab_cfb16[] = {
-+ 0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,
-+ 0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0,
-+ 0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,
-+ 0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,
-+ 0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,
-+ 0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4,
-+ 0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,
-+ 0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,
-+ 0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,
-+ 0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2,
-+ 0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,
-+ 0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,
-+ 0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,
-+ 0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6,
-+ 0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,
-+ 0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,
-+ 0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,
-+ 0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1,
-+ 0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,
-+ 0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9,
-+ 0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,
-+ 0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
-+ 0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,
-+ 0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD,
-+ 0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,
-+ 0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,
-+ 0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,
-+ 0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB,
-+ 0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,
-+ 0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
-+ 0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,
-+ 0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF
-+};
-+
- void fbcon_cfb16_setup(struct display *p)
- {
- p->next_line = p->line_length ? p->line_length : p->var.xres_virtual<<1;
-@@ -46,6 +81,53 @@
- int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
- u8 *src, *dst;
-
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ char *scrn_end = p->screen_base + p->var.xres*p->var.yres * 2;
-+/*
-+ printk("---@paul@-------------------------\n"\
-+ "fbcon_cfb16_bmove() %d %d %d %d %d %d\n",
-+ sx,sy,dx,dy,height,width
-+ );
-+*/
-+ if (sx == 0 && dx == 0 && width * fontwidth(p) * 2 == bytes)
-+ {
-+ fb_memmove(
-+ scrn_end - dy * linesize,
-+ scrn_end - sy * linesize,
-+ height * linesize
-+ );
-+ return;
-+ }
-+ if (fontwidthlog(p)) {
-+ sx <<= fontwidthlog(p)+1;
-+ dx <<= fontwidthlog(p)+1;
-+ width <<= fontwidthlog(p)+1;
-+ } else {
-+ sx *= fontwidth(p)*2;
-+ dx *= fontwidth(p)*2;
-+ width *= fontwidth(p)*2;
-+ }
-+ if (dy < sy || (dy == sy && dx < sx)) {
-+ src = scrn_end + sy * linesize + sx;
-+ dst = scrn_end + dy * linesize + dx;
-+ for (rows = height * fontheight(p); rows--;)
-+ {
-+ fb_memmove(dst, src, width);
-+ src += bytes;
-+ dst += bytes;
-+ }
-+ } else {
-+ src = scrn_end + (sy+height) * linesize + sx - bytes;
-+ dst = scrn_end + (dy+height) * linesize + dx - bytes;
-+ for (rows = height * fontheight(p); rows--;)
-+ {
-+ fb_memmove(dst, src, width);
-+ src -= bytes;
-+ dst -= bytes;
-+ }
-+ }
-+/* if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) */
-+ } else {
- if (sx == 0 && dx == 0 && width * fontwidth(p) * 2 == bytes) {
- fb_memmove(p->screen_base + dy * linesize,
- p->screen_base + sy * linesize,
-@@ -78,6 +160,8 @@
- dst -= bytes;
- }
- }
-+ }
-+/* elseif ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) */
- }
-
- static inline void rectfill(u8 *dest, int width, int height, u32 data,
-@@ -108,10 +192,16 @@
- int bytes = p->next_line, lines = height * fontheight(p);
- u32 bgx;
-
-- dest = p->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p) * 2;
--
-- bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
--
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ dest = p->screen_base
-+ + p->var.xres*p->var.yres * 2
-+ - (sy+height) * fontheight(p) * bytes
-+ + sx * fontwidth(p) * 2;
-+ bgx = 1;
-+ } else {
-+ dest = p->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p) * 2;
-+ bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-+ }
- width *= fontwidth(p)/4;
- if (width * 8 == bytes)
- rectfill(dest, lines * width * 4, 1, bgx, bytes);
-@@ -126,14 +216,69 @@
- int bytes = p->next_line, rows;
- u32 eorx, fgx, bgx;
-
-- dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
--
- fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
- bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
- fgx |= (fgx << 16);
- bgx |= (bgx << 16);
- eorx = fgx ^ bgx;
-
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ dest = p->screen_base
-+ + p->var.xres*p->var.yres * 2
-+ - yy * fontheight(p) * bytes
-+ - xx * fontwidth(p) * 2;
-+
-+ switch (fontwidth(p)) {
-+ case 4:
-+ cdat = p->fontdata + (c & p->charmask) * fontheight(p);
-+ for (rows = fontheight(p); rows--; dest += bytes)
-+ {
-+ bits = mirrortab_cfb16[*cdat++];
-+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest-8);
-+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest-4);
-+ }
-+ case 8:
-+ cdat = p->fontdata + (c & p->charmask) * fontheight(p);
-+ for (rows = fontheight(p); rows--; dest += bytes)
-+ {
-+ bits = mirrortab_cfb16[*cdat++];
-+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest-16);
-+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest-12);
-+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest-8);
-+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest-4);
-+ }
-+ break;
-+ case 12:
-+ cdat = p->fontdata + ((c & p->charmask) * fontheight(p) << 1);
-+ for (rows = fontheight(p); rows--; dest += bytes) {
-+ bits = mirrortab_cfb16[*cdat++];
-+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest-24);
-+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest-20);
-+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest-16);
-+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest-12);
-+ bits = mirrortab_cfb16[*cdat++];
-+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest-8);
-+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest-4);
-+ }
-+ case 16:
-+ cdat = p->fontdata + ((c & p->charmask) * fontheight(p) << 1);
-+ for (rows = fontheight(p); rows--; dest += bytes) {
-+ bits = mirrortab_cfb16[*cdat++];
-+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest-32);
-+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest-28);
-+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest-24);
-+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest-20);
-+ bits = mirrortab_cfb16[*cdat++];
-+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest-16);
-+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest-12);
-+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest-8);
-+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest-4);
-+ }
-+ break;
-+ }
-+/* if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) */
-+ } else {
-+ dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
- switch (fontwidth(p)) {
- case 4:
- case 8:
-@@ -167,6 +312,8 @@
- }
- break;
- }
-+ }
-+/* elseif ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) */
- }
-
- void fbcon_cfb16_putcs(struct vc_data *conp, struct display *p,
-@@ -177,7 +324,6 @@
- int rows, bytes = p->next_line;
- u32 eorx, fgx, bgx;
-
-- dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
- c = scr_readw(s);
- fgx = ((u16 *)p->dispsw_data)[attr_fgcol(p, c)];
- bgx = ((u16 *)p->dispsw_data)[attr_bgcol(p, c)];
-@@ -185,6 +331,81 @@
- bgx |= (bgx << 16);
- eorx = fgx ^ bgx;
-
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ dest0 = p->screen_base
-+ + p->var.xres * p->var.yres * 2
-+ - yy * fontheight(p) * bytes
-+ - xx * fontwidth(p) * 2;
-+
-+ switch (fontwidth(p)) {
-+ case 4:
-+ while (count--) {
-+ c = scr_readw(s++) & p->charmask;
-+ cdat = p->fontdata + c * fontheight(p);
-+ for (rows = fontheight(p), dest = dest0; rows--; dest -= bytes)
-+ {
-+ u8 bits = mirrortab_cfb16[*cdat++];
-+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest-8);
-+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest-4);
-+ }
-+ dest0 -= fontwidth(p)*2;
-+ }
-+ case 8:
-+ while (count--) {
-+ c = scr_readw(s++) & p->charmask;
-+ cdat = p->fontdata + c * fontheight(p);
-+ for (rows = fontheight(p), dest = dest0; rows--; dest -= bytes)
-+ {
-+ u8 bits = mirrortab_cfb16[*cdat++];
-+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest-16);
-+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest-12);
-+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest-8);
-+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest-4);
-+ }
-+ dest0 -= fontwidth(p)*2;
-+ }
-+ break;
-+ case 12:
-+ while (count--) {
-+ c = scr_readw(s++) & p->charmask;
-+ cdat = p->fontdata + (c * fontheight(p) << 1);
-+ for (rows = fontheight(p), dest = dest0; rows--; dest -= bytes)
-+ {
-+ u8 bits = mirrortab_cfb16[*cdat++];
-+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest-24);
-+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest-20);
-+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest-16);
-+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest-12);
-+ bits = mirrortab_cfb16[*cdat++];
-+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest-8);
-+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest-4);
-+ }
-+ dest0 -= fontwidth(p)*2;
-+ }
-+ case 16:
-+ while (count--) {
-+ c = scr_readw(s++) & p->charmask;
-+ cdat = p->fontdata + (c * fontheight(p) << 1);
-+ for (rows = fontheight(p), dest = dest0; rows--; dest -= bytes)
-+ {
-+ u8 bits = mirrortab_cfb16[*cdat++];
-+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest-32);
-+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest-28);
-+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest-24);
-+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest-20);
-+ bits = mirrortab_cfb16[*cdat++];
-+ fb_writel((tab_cfb16[bits >> 6] & eorx) ^ bgx, dest-16);
-+ fb_writel((tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx, dest-12);
-+ fb_writel((tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx, dest-8);
-+ fb_writel((tab_cfb16[bits & 3] & eorx) ^ bgx, dest-4);
-+ }
-+ dest0 -= fontwidth(p)*2;
-+ }
-+ break;
-+ }
-+/* if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) */
-+ } else {
-+ dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p) * 2;
- switch (fontwidth(p)) {
- case 4:
- case 8:
-@@ -226,6 +447,8 @@
- }
- break;
- }
-+ }
-+/* elseif ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) */
- }
-
- void fbcon_cfb16_revc(struct display *p, int xx, int yy)
-@@ -233,6 +456,32 @@
- u8 *dest;
- int bytes = p->next_line, rows;
-
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ dest = p->screen_base
-+ + p->var.xres*p->var.yres * 2
-+ - yy * fontheight(p) * bytes
-+ - xx * fontwidth(p) * 2;
-+ for (rows = fontheight(p); rows--; dest -= bytes) {
-+ switch (fontwidth(p)) {
-+ case 16:
-+ fb_writel(fb_readl(dest-32) ^ 0xffffffff, dest-32);
-+ fb_writel(fb_readl(dest-28) ^ 0xffffffff, dest-28);
-+ /* FALL THROUGH */
-+ case 12:
-+ fb_writel(fb_readl(dest-24) ^ 0xffffffff, dest-24);
-+ fb_writel(fb_readl(dest-20) ^ 0xffffffff, dest-20);
-+ /* FALL THROUGH */
-+ case 8:
-+ fb_writel(fb_readl(dest-16) ^ 0xffffffff, dest-16);
-+ fb_writel(fb_readl(dest-12) ^ 0xffffffff, dest-12);
-+ /* FALL THROUGH */
-+ case 4:
-+ fb_writel(fb_readl(dest-8) ^ 0xffffffff, dest-8);
-+ fb_writel(fb_readl(dest-4) ^ 0xffffffff, dest-4);
-+ }
-+ }
-+/* if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) */
-+ } else {
- dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p)*2;
- for (rows = fontheight(p); rows--; dest += bytes) {
- switch (fontwidth(p)) {
-@@ -253,6 +502,8 @@
- fb_writel(fb_readl(dest+4) ^ 0xffffffff, dest+4);
- }
- }
-+ }
-+/* elseif ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) */
- }
-
- void fbcon_cfb16_clear_margins(struct vc_data *conp, struct display *p,
-@@ -268,6 +519,9 @@
- bgx = ((u16 *)p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
- if (!bottom_only && (right_width = p->var.xres-right_start))
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ printk("---@paul@------------------------- fbcon-cfb16 clear margins\n");
-+ }
- rectfill(p->screen_base+right_start*2, right_width,
- p->var.yres_virtual, bgx, bytes);
- if ((bottom_width = p->var.yres-bottom_start))
---- linux-2.4.21/drivers/video/fbcon-cfb8.c~fb-turn180
-+++ linux-2.4.21/drivers/video/fbcon-cfb8.c
-@@ -39,6 +39,41 @@
- #endif
- };
-
-+static u8 mirrortab_cfb8[] = {
-+ 0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,
-+ 0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0,
-+ 0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,
-+ 0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,
-+ 0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,
-+ 0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4,
-+ 0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,
-+ 0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,
-+ 0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,
-+ 0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2,
-+ 0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,
-+ 0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,
-+ 0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,
-+ 0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6,
-+ 0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,
-+ 0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,
-+ 0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,
-+ 0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1,
-+ 0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,
-+ 0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9,
-+ 0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,
-+ 0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
-+ 0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,
-+ 0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD,
-+ 0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,
-+ 0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,
-+ 0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,
-+ 0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB,
-+ 0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,
-+ 0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
-+ 0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,
-+ 0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF
-+};
-+
- void fbcon_cfb8_setup(struct display *p)
- {
- p->next_line = p->line_length ? p->line_length : p->var.xres_virtual;
-@@ -51,10 +86,57 @@
- int bytes = p->next_line, linesize = bytes * fontheight(p), rows;
- u8 *src,*dst;
-
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+/*
-+ printk("---@paul@-------------------------\n"\
-+ "fbcon_cfb8_bmove() %d %d %d %d %d %d\n",
-+ sx,sy,dx,dy,height,width
-+ );
-+*/
-+ if (sx == 0 && dx == 0 && width * fontwidth(p) == bytes)
-+ {
-+ fb_memmove(
-+ p->screen_base + p->var.xres*p->var.yres - dy * linesize,
-+ p->screen_base + p->var.xres*p->var.yres - sy * linesize,
-+ height * linesize);
-+ return;
-+ }
-+ if (fontwidthlog(p)) {
-+ sx <<= fontwidthlog(p); dx <<= fontwidthlog(p); width <<= fontwidthlog(p);
-+ } else {
-+ sx *= fontwidth(p); dx *= fontwidth(p); width *= fontwidth(p);
-+ }
-+ if (dy < sy || (dy == sy && dx < sx))
-+ {
-+ src = p->screen_base + p->var.xres*p->var.yres
-+ - sy * linesize - sx;
-+ dst = p->screen_base + p->var.xres*p->var.yres
-+ - dy * linesize - dx;
-+ for (rows = height * fontheight(p) ; rows-- ;)
-+ {
-+ fb_memmove(dst, src, width);
-+ src += bytes;
-+ dst += bytes;
-+ }
-+ } else
-+ {
-+ src = p->screen_base + p->var.xres*p->var.yres
-+ - (sy+height) * linesize - sx + bytes;
-+ dst = p->screen_base + p->var.xres*p->var.yres
-+ - (dy+height) * linesize - dx + bytes;
-+ for (rows = height * fontheight(p) ; rows-- ;)
-+ {
-+ fb_memmove(dst, src, width);
-+ src -= bytes;
-+ dst -= bytes;
-+ }
-+ }
-+/* if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) */
-+ } else {
- if (sx == 0 && dx == 0 && width * fontwidth(p) == bytes) {
-- fb_memmove(p->screen_base + dy * linesize,
-- p->screen_base + sy * linesize,
-- height * linesize);
-+ fb_memmove(p->screen_base + dy * linesize,
-+ p->screen_base + sy * linesize,
-+ height * linesize);
- return;
- }
- if (fontwidthlog(p)) {
-@@ -79,6 +161,7 @@
- dst -= bytes;
- }
- }
-+/* elseif ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) */
- }
-
- static inline void rectfill(u8 *dest, int width, int height, u8 data,
-@@ -97,11 +180,17 @@
- int bytes=p->next_line,lines=height * fontheight(p);
- u8 bgx;
-
-- dest = p->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p);
--
-- bgx=attr_bgcol_ec(p,conp);
--
-- width *= fontwidth(p);
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ bgx=attr_bgcol_ec(p,conp);
-+ width *= fontwidth(p);
-+ dest = p->screen_base + p->var.xres*p->var.yres
-+ - (sy+height) * fontheight(p) * bytes
-+ + sx * fontwidth(p);
-+ } else {
-+ dest = p->screen_base + sy * fontheight(p) * bytes + sx * fontwidth(p);
-+ bgx=attr_bgcol_ec(p,conp);
-+ width *= fontwidth(p);
-+ }
- if (width == bytes)
- rectfill(dest, lines * width, 1, bgx, bytes);
- else
-@@ -114,8 +203,8 @@
- u8 *dest,*cdat;
- int bytes=p->next_line,rows;
- u32 eorx,fgx,bgx;
-+ u8 chrrow;
-
-- dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p);
- if (fontwidth(p) <= 8)
- cdat = p->fontdata + (c & p->charmask) * fontheight(p);
- else
-@@ -129,6 +218,53 @@
- bgx |= (bgx << 16);
- eorx = fgx ^ bgx;
-
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ dest = p->screen_base
-+ + p->var.xres*p->var.yres
-+ - yy * fontheight(p) * bytes
-+ - xx * fontwidth(p);
-+
-+ switch (fontwidth(p)) {
-+ case 4:
-+ for (rows = fontheight(p) ; rows-- ; dest += bytes)
-+ {
-+ chrrow = mirrortab_cfb8[*cdat++];
-+ fb_writel((nibbletab_cfb8[chrrow >> 4] & eorx) ^ bgx, dest-4);
-+ }
-+ break;
-+ case 8:
-+ for (rows = fontheight(p) ; rows-- ; dest += bytes)
-+ {
-+ chrrow = mirrortab_cfb8[*cdat++];
-+ fb_writel((nibbletab_cfb8[chrrow >> 4] & eorx) ^ bgx, dest-8);
-+ fb_writel((nibbletab_cfb8[chrrow & 0xf] & eorx) ^ bgx, dest-4);
-+ }
-+ break;
-+ case 12:
-+ for (rows = fontheight(p) ; rows-- ; dest += bytes)
-+ {
-+ chrrow = mirrortab_cfb8[*cdat++];
-+ fb_writel((nibbletab_cfb8[chrrow >> 4] & eorx) ^ bgx, dest-12);
-+ fb_writel((nibbletab_cfb8[chrrow & 0xf] & eorx) ^ bgx, dest-8);
-+ chrrow = mirrortab_cfb8[*cdat++];
-+ fb_writel((nibbletab_cfb8[chrrow >> 4] & eorx) ^ bgx, dest-4);
-+ }
-+ break;
-+ case 16:
-+ for (rows = fontheight(p) ; rows-- ; dest += bytes)
-+ {
-+ chrrow = mirrortab_cfb8[*cdat++];
-+ fb_writel((nibbletab_cfb8[chrrow >> 4] & eorx) ^ bgx, dest-16);
-+ fb_writel((nibbletab_cfb8[chrrow & 0xf] & eorx) ^ bgx, dest-12);
-+ chrrow = mirrortab_cfb8[*cdat++];
-+ fb_writel((nibbletab_cfb8[chrrow >> 4] & eorx) ^ bgx, dest-8);
-+ fb_writel((nibbletab_cfb8[chrrow & 0xf] & eorx) ^ bgx, dest-4);
-+ }
-+ break;
-+ }
-+/* if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) */
-+ } else {
-+ dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p);
- switch (fontwidth(p)) {
- case 4:
- for (rows = fontheight(p) ; rows-- ; dest += bytes)
-@@ -152,6 +288,8 @@
- }
- break;
- }
-+ }
-+/* elseif ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) */
- }
-
- void fbcon_cfb8_putcs(struct vc_data *conp, struct display *p,
-@@ -161,8 +299,8 @@
- u16 c;
- int rows,bytes=p->next_line;
- u32 eorx, fgx, bgx;
-+ u8 chrrow;
-
-- dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p);
- c = scr_readw(s);
- fgx = attr_fgcol(p, c);
- bgx = attr_bgcol(p, c);
-@@ -171,6 +309,76 @@
- bgx |= (bgx << 8);
- bgx |= (bgx << 16);
- eorx = fgx ^ bgx;
-+
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ dest0 = p->screen_base
-+ + p->var.xres*p->var.yres
-+ - yy * fontheight(p) * bytes
-+ - xx * fontwidth(p);
-+ switch (fontwidth(p)) {
-+ case 4:
-+ while (count--) {
-+ c = scr_readw(s++) & p->charmask;
-+ cdat = p->fontdata + c * fontheight(p);
-+
-+ for (rows = fontheight(p), dest = dest0; rows-- ; dest -= bytes)
-+ {
-+ chrrow = mirrortab_cfb8[*cdat++];
-+ fb_writel((nibbletab_cfb8[chrrow >> 4] & eorx) ^ bgx, dest-4);
-+ }
-+ dest0 -= 4;
-+ }
-+ break;
-+ case 8:
-+ while (count--) {
-+ c = scr_readw(s++) & p->charmask;
-+ cdat = p->fontdata + c * fontheight(p);
-+ for (rows = fontheight(p), dest = dest0; rows-- ; dest -= bytes)
-+ {
-+ chrrow = mirrortab_cfb8[*cdat++];
-+ fb_writel((nibbletab_cfb8[chrrow >> 4] & eorx) ^ bgx, dest-8);
-+ fb_writel((nibbletab_cfb8[chrrow & 0xf] & eorx) ^ bgx, dest-4);
-+ }
-+ dest0 -= 8;
-+ }
-+ break;
-+ case 12:
-+ while (count--) {
-+ c = scr_readw(s++) & p->charmask;
-+ cdat = p->fontdata + (c * fontheight(p) << 1);
-+
-+ for (rows = fontheight(p), dest = dest0; rows-- ; dest -= bytes)
-+ {
-+ chrrow = mirrortab_cfb8[*cdat++];
-+ fb_writel((nibbletab_cfb8[chrrow >> 4] & eorx) ^ bgx, dest-12);
-+ fb_writel((nibbletab_cfb8[chrrow & 0xf] & eorx) ^ bgx, dest-8);
-+ chrrow = mirrortab_cfb8[*cdat++];
-+ fb_writel((nibbletab_cfb8[chrrow >> 4] & eorx) ^ bgx, dest-4);
-+ }
-+ dest0 -= fontwidth(p);
-+ }
-+ break;
-+ case 16:
-+ while (count--) {
-+ c = scr_readw(s++) & p->charmask;
-+ cdat = p->fontdata + (c * fontheight(p) << 1);
-+
-+ for (rows = fontheight(p), dest = dest0; rows-- ; dest -= bytes)
-+ {
-+ chrrow = mirrortab_cfb8[*cdat++];
-+ fb_writel((nibbletab_cfb8[chrrow >> 4] & eorx) ^ bgx, dest-16);
-+ fb_writel((nibbletab_cfb8[chrrow & 0xf] & eorx) ^ bgx, dest-12);
-+ chrrow = mirrortab_cfb8[*cdat++];
-+ fb_writel((nibbletab_cfb8[chrrow >> 4] & eorx) ^ bgx, dest-8);
-+ fb_writel((nibbletab_cfb8[chrrow & 0xf] & eorx) ^ bgx, dest-4);
-+ }
-+ dest0 -= fontwidth(p);
-+ }
-+ break;
-+ } /* switch (fontwidth(p)) */
-+/* if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) */
-+ } else {
-+ dest0 = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p);
- switch (fontwidth(p)) {
- case 4:
- while (count--) {
-@@ -212,6 +420,8 @@
- }
- break;
- }
-+ }
-+/* elseif ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) */
- }
-
- void fbcon_cfb8_revc(struct display *p, int xx, int yy)
-@@ -219,6 +429,21 @@
- u8 *dest;
- int bytes=p->next_line, rows;
-
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ dest = p->screen_base + p->var.xres*p->var.yres
-+ - yy * fontheight(p) * bytes
-+ - xx * fontwidth(p);
-+ for (rows = fontheight(p) ; rows-- ; dest -= bytes) {
-+ switch (fontwidth(p)) {
-+ case 16: fb_writel(fb_readl(dest-16) ^ 0x0f0f0f0f, dest-16); /* fall thru */
-+ case 12: fb_writel(fb_readl(dest-12) ^ 0x0f0f0f0f, dest-12); /* fall thru */
-+ case 8: fb_writel(fb_readl(dest-8) ^ 0x0f0f0f0f, dest-8); /* fall thru */
-+ case 4: fb_writel(fb_readl(dest-4) ^ 0x0f0f0f0f, dest-4); /* fall thru */
-+ default: break;
-+ }
-+ }
-+/* if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) */
-+ } else {
- dest = p->screen_base + yy * fontheight(p) * bytes + xx * fontwidth(p);
- for (rows = fontheight(p) ; rows-- ; dest += bytes) {
- switch (fontwidth(p)) {
-@@ -229,6 +454,8 @@
- default: break;
- }
- }
-+ }
-+/* elseif ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) */
- }
-
- void fbcon_cfb8_clear_margins(struct vc_data *conp, struct display *p,
-@@ -244,6 +471,9 @@
- bgx=attr_bgcol_ec(p,conp);
-
- if (!bottom_only && (right_width = p->var.xres-right_start))
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ printk("---@paul@------------------------- fbcon-cfb8 clear margins\n");
-+ }
- rectfill(p->screen_base+right_start, right_width, p->var.yres_virtual,
- bgx, bytes);
- if ((bottom_width = p->var.yres-bottom_start))
---- linux-2.4.21/drivers/video/fbcon.c~fb-turn180
-+++ linux-2.4.21/drivers/video/fbcon.c
-@@ -1558,6 +1558,7 @@
- update_region(fg_console,
- conp->vc_origin + conp->vc_size_row * conp->vc_top,
- conp->vc_size_row * (conp->vc_bottom - conp->vc_top) / 2);
-+ conp->vc_top = 0;
- return 0;
- }
- return 1;
-@@ -2209,7 +2210,16 @@
- src = logo;
- bdepth = depth/8;
- for( y1 = 0; y1 < LOGO_H; y1++ ) {
-- dst = fb + y1*line + x*bdepth;
-+
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+/*
-+ Das ist NICHT die richtige Stelle für den Ramses 16 BPP Modus
-+ aber dafür die weiter unten.
-+*/
-+ dst = fb + p->var.xres*p->var.yres*bdepth -1 - y1*line - x*bdepth;
-+ } else {
-+ dst = fb + y1*line + x*bdepth;
-+ }
- for( x1 = 0; x1 < LOGO_W; x1++, src++ ) {
- val = (*src << redshift) |
- (*src << greenshift) |
-@@ -2217,18 +2227,32 @@
- if (bdepth == 4 && !((long)dst & 3)) {
- /* Some cards require 32bit access */
- fb_writel (val, dst);
-- dst += 4;
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ dst -= 4;
-+ } else {
-+ dst += 4;
-+ }
- } else if (bdepth == 2 && !((long)dst & 1)) {
- /* others require 16bit access */
- fb_writew (val,dst);
-- dst +=2;
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ dst -= 2;
-+ } else {
-+ dst +=2;
-+ }
- } else {
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ for( i = bdepth-1; i >= 0; --i )
-+ fb_writeb (val >> (i*8), dst--);
-+
-+ } else {
- #ifdef __LITTLE_ENDIAN
-- for( i = 0; i < bdepth; ++i )
-+ for( i = 0; i < bdepth; ++i )
- #else
-- for( i = bdepth-1; i >= 0; --i )
-+ for( i = bdepth-1; i >= 0; --i )
- #endif
-- fb_writeb (val >> (i*8), dst++);
-+ fb_writeb (val >> (i*8), dst++);
-+ }
- }
- }
- }
-@@ -2239,28 +2263,42 @@
- src = linux_logo16;
- bdepth = (depth+7)/8;
- for( y1 = 0; y1 < LOGO_H; y1++ ) {
-- dst = fb + y1*line + x*bdepth;
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ dst = fb + p->var.xres*p->var.yres*bdepth -1 - y1*line - x*bdepth;
-+ } else {
-+ dst = fb + y1*line + x*bdepth;
-+ }
- for( x1 = 0; x1 < LOGO_W/2; x1++, src++ ) {
- pix = *src >> 4; /* upper nibble */
- val = (pix << redshift) |
- (pix << greenshift) |
- (pix << blueshift);
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ for( i = bdepth-1; i >= 0; --i )
-+ fb_writeb (val >> (i*8), dst--);
-+ } else {
- #ifdef __LITTLE_ENDIAN
-- for( i = 0; i < bdepth; ++i )
-+ for( i = 0; i < bdepth; ++i )
- #else
-- for( i = bdepth-1; i >= 0; --i )
-+ for( i = bdepth-1; i >= 0; --i )
- #endif
-- fb_writeb (val >> (i*8), dst++);
-+ fb_writeb (val >> (i*8), dst++);
-+ }
- pix = *src & 0x0f; /* lower nibble */
- val = (pix << redshift) |
- (pix << greenshift) |
- (pix << blueshift);
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ for( i = bdepth-1; i >= 0; --i )
-+ fb_writeb (val >> (i*8), dst--);
-+ } else {
- #ifdef __LITTLE_ENDIAN
-- for( i = 0; i < bdepth; ++i )
-+ for( i = 0; i < bdepth; ++i )
- #else
-- for( i = bdepth-1; i >= 0; --i )
-+ for( i = bdepth-1; i >= 0; --i )
- #endif
-- fb_writeb (val >> (i*8), dst++);
-+ fb_writeb (val >> (i*8), dst++);
-+ }
- }
- }
- }
-@@ -2287,7 +2325,11 @@
-
- src = logo;
- for( y1 = 0; y1 < LOGO_H; y1++ ) {
-- dst = fb + y1*line + x*bdepth;
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ dst = fb + p->var.xres*p->var.yres*bdepth -1 - y1*line - x*bdepth;
-+ } else {
-+ dst = fb + y1*line + x*bdepth;
-+ }
- for( x1 = 0; x1 < LOGO_W; x1++, src++ ) {
- val = safe_shift((linux_logo_red[*src-32] & redmask), redshift) |
- safe_shift((linux_logo_green[*src-32] & greenmask), greenshift) |
-@@ -2295,18 +2337,31 @@
- if (bdepth == 4 && !((long)dst & 3)) {
- /* Some cards require 32bit access */
- fb_writel (val, dst);
-- dst += 4;
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ dst -= 4;
-+ } else {
-+ dst += 4;
-+ }
- } else if (bdepth == 2 && !((long)dst & 1)) {
- /* others require 16bit access */
- fb_writew (val,dst);
-- dst +=2;
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ dst -= 2;
-+ } else {
-+ dst +=2;
-+ }
- } else {
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ for( i = bdepth-1; i >= 0; --i )
-+ fb_writeb (val >> (i*8), dst--);
-+ } else {
- #ifdef __LITTLE_ENDIAN
-- for( i = 0; i < bdepth; ++i )
-+ for( i = 0; i < bdepth; ++i )
- #else
-- for( i = bdepth-1; i >= 0; --i )
-+ for( i = bdepth-1; i >= 0; --i )
- #endif
-- fb_writeb (val >> (i*8), dst++);
-+ fb_writeb (val >> (i*8), dst++);
-+ }
- }
- }
- }
-@@ -2331,13 +2386,24 @@
- if (depth == 8 && p->type == FB_TYPE_PACKED_PIXELS) {
- /* depth 8 or more, packed, with color registers */
-
-- src = logo;
-- for( y1 = 0; y1 < LOGO_H; y1++ ) {
-- dst = fb + y1*line + x;
-- for( x1 = 0; x1 < LOGO_W; x1++ )
-- fb_writeb (*src++, dst++);
-- }
-- done = 1;
-+ if ( ramses_flags & RAMSES_FLAGS_LCD_FBTURN) {
-+ src = logo;
-+ for( y1 = 0; y1 < LOGO_H; y1++ )
-+ {
-+ dst = fb + p->var.xres*p->var.yres -1 - y1*line - x;
-+ for( x1 = 0; x1 < LOGO_W; x1++ )
-+ fb_writeb (*src++, dst--);
-+ }
-+ done = 1;
-+ } else {
-+ src = logo;
-+ for( y1 = 0; y1 < LOGO_H; y1++ ) {
-+ dst = fb + y1*line + x;
-+ for( x1 = 0; x1 < LOGO_W; x1++ )
-+ fb_writeb (*src++, dst++);
-+ }
-+ done = 1;
-+ }
- }
- #endif
- #if defined(CONFIG_FBCON_AFB) || defined(CONFIG_FBCON_ILBM) || \
---- linux-2.4.21/drivers/video/fbmem.c~fb-buffered
-+++ linux-2.4.21/drivers/video/fbmem.c
-@@ -302,7 +302,7 @@
- { "sa1100", sa1100fb_init, NULL },
- #endif
- #ifdef CONFIG_FB_PXA
-- { "pxa", pxafb_init, NULL },
-+ { "pxa", pxafb_init, NULL },
- #endif
- #ifdef CONFIG_FB_SUN3
- { "sun3", sun3fb_init, sun3fb_setup },
-@@ -672,7 +672,11 @@
- #elif defined(__hppa__)
- pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
- #elif defined(__ia64__) || defined(__arm__)
-+#ifdef CONFIG_PXA
-+ vma->vm_page_prot = pgprot_noncached_buffered(vma->vm_page_prot);
-+#else
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
-+#endif
- #elif defined(__hppa__)
- pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
- #else
---- linux-2.4.21/drivers/video/pxafb.c~ramses-lcd
-+++ linux-2.4.21/drivers/video/pxafb.c
-@@ -45,8 +45,6 @@
-
- #include <video/fbcon.h>
- #include <video/fbcon-mfb.h>
--#include <video/fbcon-cfb4.h>
--#include <video/fbcon-cfb8.h>
- #include <video/fbcon-cfb16.h>
- #include <video/lcdctrl.h> /* brightness, contrast, etc. control */
-
-@@ -57,7 +55,7 @@
- /*
- * Complain if VAR is out of range.
- */
--#define DEBUG_VAR 1
-+#define DEBUG_VAR 0
-
- #undef ASSABET_PAL_VIDEO
-
-@@ -66,16 +64,6 @@
- void (*pxafb_blank_helper)(int blank);
- EXPORT_SYMBOL(pxafb_blank_helper);
-
--/*
-- * IMHO this looks wrong. In 8BPP, length should be 8.
-- */
--static struct pxafb_rgb rgb_8 = {
-- red: { offset: 0, length: 4, },
-- green: { offset: 0, length: 4, },
-- blue: { offset: 0, length: 4, },
-- transp: { offset: 0, length: 0, },
--};
--
- static struct pxafb_rgb def_rgb_16 = {
- red: { offset: 11, length: 5, },
- green: { offset: 5, length: 6, },
-@@ -99,9 +87,30 @@
- lccr3: LCD_LCCR3
- };
-
-+static struct pxafb_mach_info torisan_fb_info __initdata = {
-+ pixclock: 70000,
-+ bpp: LCD_BPP,
-+ xres: 320,
-+ yres: 240,
-+ hsync_len: 2,
-+ vsync_len: 2,
-+ left_margin: 1,
-+ upper_margin: 4,
-+ right_margin: 139,
-+ lower_margin: 4,
-+ sync: FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-+ lccr0: LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM | LCCR0_QDM | LCCR0_BM | LCCR0_OUM | LCCR0_PAS,
-+ lccr3: 0x04700007
-+};
-+
- static struct pxafb_mach_info * __init
- pxafb_get_machine_info(struct pxafb_info *fbi)
- {
-+#ifdef CONFIG_ARCH_RAMSES
-+ if (ramses_lcd_type == 2)
-+ return &torisan_fb_info;
-+ else
-+#endif
- return &pxa_fb_info;
- }
-
-@@ -276,7 +285,7 @@
- * 16 bits works apparemtly fine in passive mode for those,
- * so don't complain
- */
-- if (machine_is_lubbock() ||
-+ if (machine_is_lubbock() || machine_is_ramses() ||
- machine_is_pxa_cerf()) {
- ret = 0;
- } else
-@@ -671,7 +680,7 @@
- static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *fbi)
- {
- struct pxafb_lcd_reg new_regs;
--// u_int pcd = get_pcd(var->pixclock);
-+ u_int pcd = get_pcd(var->pixclock);
- u_long flags;
-
- DPRINTK("Configuring PXA LCD\n");
-@@ -710,7 +719,7 @@
- fbi->fb.fix.id, var->lower_margin);
- #endif
-
--#if defined (CONFIG_PXA_CERF_PDA)
-+#if defined (CONFIG_PXA_CERF_PDA) || defined(CONFIG_ARCH_RAMSES)
- new_regs.lccr0 = fbi->lccr0;
- new_regs.lccr1 =
- LCCR1_DisWdth(var->xres) +
-@@ -767,8 +776,8 @@
- // LCCR3_ACBsCntOff;
- #endif
-
--// if (pcd)
--// new_regs.lccr3 |= LCCR3_PixClkDiv(pcd);
-+ if (pcd)
-+ new_regs.lccr3 = (new_regs.lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd);
-
- DPRINTK("nlccr0 = 0x%08x\n", new_regs.lccr0);
- DPRINTK("nlccr1 = 0x%08x\n", new_regs.lccr1);
-@@ -820,6 +829,7 @@
- fbi->fdadr0 = fbi->dmadesc_fbhigh_dma; /* no pal just fbhigh */
- }
-
-+#if 0
- DPRINTK("fbi->dmadesc_fblow_cpu = 0x%x\n", fbi->dmadesc_fblow_cpu);
- DPRINTK("fbi->dmadesc_fbhigh_cpu = 0x%x\n", fbi->dmadesc_fbhigh_cpu);
- DPRINTK("fbi->dmadesc_palette_cpu = 0x%x\n", fbi->dmadesc_palette_cpu);
-@@ -838,6 +848,7 @@
- DPRINTK("fbi->dmadesc_fblow_cpu->ldcmd = 0x%x\n", fbi->dmadesc_fblow_cpu->ldcmd);
- DPRINTK("fbi->dmadesc_fbhigh_cpu->ldcmd = 0x%x\n", fbi->dmadesc_fbhigh_cpu->ldcmd);
- DPRINTK("fbi->dmadesc_palette_cpu->ldcmd = 0x%x\n", fbi->dmadesc_palette_cpu->ldcmd);
-+#endif
-
- fbi->reg_lccr0 = new_regs.lccr0;
- fbi->reg_lccr1 = new_regs.lccr1;
-@@ -874,14 +885,20 @@
- DPRINTK("backlight on\n");
-
- #ifdef CONFIG_ARCH_PXA_IDP
-- if(machine_is_pxa_idp()) {
-+ if (machine_is_pxa_idp()) {
- FB_BACKLIGHT_ON();
- }
- #endif
-+#ifdef CONFIG_ARCH_RAMSES
-+ if (machine_is_ramses()) {
-+//printk("--> pxafb_backlight_on\n");
-+ ramses_lcd_backlight_on();
-+ }
-+#endif
- }
-
- /*
-- * FIXME: move LCD power stuf into pxafb_power_down_lcd()
-+ * FIXME: move LCD power stuff into pxafb_power_down_lcd()
- * Also, I'm expecting that the backlight stuff should
- * be handled differently.
- */
-@@ -894,7 +911,13 @@
- FB_BACKLIGHT_OFF();
- }
- #endif
--
-+
-+#ifdef CONFIG_ARCH_RAMSES
-+ if (machine_is_ramses()) {
-+//printk("--> pxafb_backlight_off calling ramses_lcd_backlight_off\n");
-+ ramses_lcd_backlight_off();
-+ }
-+#endif
- }
-
- static void pxafb_power_up_lcd(struct pxafb_info *fbi)
-@@ -902,11 +925,10 @@
- DPRINTK("LCD power on\n");
- CKEN |= CKEN16_LCD;
-
-- if(machine_is_pxa_cerf()) {
-+ if (machine_is_pxa_cerf()) {
- lcdctrl_enable();
- }
--
--#if CONFIG_ARCH_PXA_IDP
-+#ifdef CONFIG_ARCH_PXA_IDP
- /* set GPIOs, etc */
- if(machine_is_pxa_idp()) {
- // FIXME need to add proper delays
-@@ -914,26 +936,36 @@
- FB_VLCD_ON(); // FIXME this should be after scanning starts
- }
- #endif
-+
-+#ifdef CONFIG_ARCH_RAMSES
-+ if (machine_is_ramses()) {
-+//printk("--> pxafb_power_up_lcd\n");
-+ ramses_lcd_power_on();
-+ }
-+#endif
- }
-
- static void pxafb_power_down_lcd(struct pxafb_info *fbi)
- {
- DPRINTK("LCD power off\n");
-+#ifdef CONFIG_ARCH_RAMSES
-+ if (machine_is_ramses()) {
-+//printk("--> pxafb_power_down_lcd calling ramses_lcd_power_off\n");
-+ ramses_lcd_power_off();
-+ }
-+#endif
- CKEN &= ~CKEN16_LCD;
-
-- if(machine_is_pxa_cerf()) {
-+ if (machine_is_pxa_cerf()) {
- lcdctrl_disable();
- }
--
-- /* set GPIOs, etc */
--#if CONFIG_ARCH_PXA_IDP
-+#ifdef CONFIG_ARCH_PXA_IDP
- if(machine_is_pxa_idp()) {
- // FIXME need to add proper delays
- FB_PWR_OFF();
- FB_VLCD_OFF(); // FIXME this should be before scanning stops
- }
- #endif
--
- }
-
- static void pxafb_setup_gpio(struct pxafb_info *fbi)
-@@ -1082,6 +1114,10 @@
- if (old_state != C_DISABLE) {
- fbi->state = state;
-
-+#ifdef CONFIG_ARCH_PXA
-+ //printk("--> set_ctrlr_state(%d) calling ramses_lcd_power_off\n", state);
-+ ramses_lcd_power_off();
-+#endif
- pxafb_backlight_off(fbi);
- if (old_state != C_DISABLE_CLKCHANGE)
- pxafb_disable_controller(fbi);
-@@ -1191,6 +1227,7 @@
-
- if (state == 0) {
- /* Enter D0. */
-+//printk("--> pxafb_pm_callback(%d)\n", req);
- set_ctrlr_state(fbi, C_ENABLE);
- } else {
- /* Enter D1-D3. Disable the LCD controller. */
-@@ -1300,7 +1337,6 @@
- fbi->fb.disp = (struct display *)(fbi + 1);
- fbi->fb.pseudo_palette = (void *)(fbi->fb.disp + 1);
-
-- fbi->rgb[RGB_8] = &rgb_8;
- fbi->rgb[RGB_16] = &def_rgb_16;
-
- inf = pxafb_get_machine_info(fbi);
-@@ -1348,11 +1384,18 @@
- if (!fbi)
- goto failed;
-
-- if(machine_is_pxa_cerf()) {
-- // brightness&contrast is handled via lcdctrl.
-+ if (machine_is_pxa_cerf()) {
-+ // brightness & contrast is handled via lcdctrl
- lcdctrl_init();
- }
--
-+#if 0
-+ ifdef CONFIG_ARCH_RAMSES
-+ if (machine_is_ramses()) {
-+ ramses_lcd_set_intensity(100);
-+ ramses_lcd_set_brightness(20);
-+ ramses_lcd_set_contrast(84,1);
-+ }
-+#endif
- /* Initialize video memory */
- ret = pxafb_map_video_memory(fbi);
- if (ret)
---- linux-2.4.21/drivers/video/pxafb.h~ramses-lcd
-+++ linux-2.4.21/drivers/video/pxafb.h
-@@ -235,4 +235,22 @@
- #define LCD_LCCR0 (LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM | LCCR0_QDM | LCCR0_BM | LCCR0_OUM)
- #define LCD_LCCR3 (LCCR3_PCP | LCCR3_PixClkDiv(0x12) | LCCR3_Bpp(PXAFB_BPP_BITS) | LCCR3_Acb(0x18))
-
-+#elif defined CONFIG_ARCH_RAMSES
-+#define LCD_PIXCLOCK 100000
-+#define LCD_BPP PXAFB_BPP
-+#define LCD_XRES 240
-+#define LCD_YRES 320
-+#define LCD_HORIZONTAL_SYNC_PULSE_WIDTH 6
-+#define LCD_VERTICAL_SYNC_PULSE_WIDTH 1
-+#define LCD_BEGIN_OF_LINE_WAIT_COUNT 21
-+#define LCD_BEGIN_FRAME_WAIT_COUNT 7
-+#define LCD_END_OF_LINE_WAIT_COUNT 21
-+#define LCD_END_OF_FRAME_WAIT_COUNT 1
-+#define LCD_SYNC (FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT)
-+#define LCD_LCCR0 (LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM | LCCR0_QDM | LCCR0_BM | LCCR0_OUM)
-+#define LCD_LCCR3 (LCCR3_PCP | LCCR3_Bpp(PXAFB_BPP_BITS) | LCCR3_Acb(0xe))
-+
-+// PCD 21 ist noch ok
-+// PIXCLOCK 150000 ergibt LCCR3_PCD von 15
-+
- #endif
---- linux-2.4.21/include/asm-arm/arch-pxa/hardware.h~ramses
-+++ linux-2.4.21/include/asm-arm/arch-pxa/hardware.h
-@@ -127,16 +127,20 @@
- * Implementation specifics
- */
-
--//#ifdef CONFIG_ARCH_LUBBOCK
-+#ifdef CONFIG_ARCH_LUBBOCK
- #include "lubbock.h"
--//#endif
-+#endif
-
--//#ifdef CONFIG_ARCH_PXA_IDP
-+#ifdef CONFIG_ARCH_PXA_IDP
- #include "idp.h"
--//#endif
-+#endif
-
--//#ifdef CONFIG_ARCH_PXA_CERF
-+#ifdef CONFIG_ARCH_PXA_CERF
- #include "cerf.h"
--//#endif
-+#endif
-+
-+#ifdef CONFIG_ARCH_RAMSES
-+#include "ramses.h"
-+#endif
-
- #endif /* _ASM_ARCH_HARDWARE_H */
---- linux-2.4.21/include/asm-arm/arch-pxa/irqs.h~ramses
-+++ linux-2.4.21/include/asm-arm/arch-pxa/irqs.h
-@@ -105,14 +105,13 @@
- #define S0_BVD1_STSCHG SA1111_IRQ(53)
- #define S1_BVD1_STSCHG SA1111_IRQ(54)
-
--#define SA1111_IRQ_MAX SA1111_IRQ(54)
-
- #undef NR_IRQS
- #define NR_IRQS (SA1111_IRQ_MAX + 1)
-
- #endif // defined(CONFIG_SA1111)
-
--#if defined(CONFIG_ARCH_LUBBOCK) || defined(CONFIG_ARCH_PXA_IDP)
-+#if defined(CONFIG_ARCH_LUBBOCK) || defined(CONFIG_ARCH_PXA_IDP)
- #if CONFIG_SA1111
- #define LUBBOCK_IRQ(x) (SA1111_IRQ_MAX + 1 + (x))
- #else
-@@ -132,6 +131,3 @@
- #define NR_IRQS (LUBBOCK_LAST_IRQ + 1)
-
- #endif // CONFIG_ARCH_LUBBOCK
--
--
--
---- linux-2.4.21/include/asm-arm/arch-pxa/pxa-regs.h~ramses
-+++ linux-2.4.21/include/asm-arm/arch-pxa/pxa-regs.h
-@@ -1051,6 +1051,7 @@
- #define PGSR1 __REG(0x40F00024) /* Power Manager GPIO Sleep State Register for GP[63-32] */
- #define PGSR2 __REG(0x40F00028) /* Power Manager GPIO Sleep State Register for GP[84-64] */
- #define RCSR __REG(0x40F00030) /* Reset Controller Status Register */
-+#define PMFW __REG(0x40F00034) /* Power Manager Fast-Sleep Wakeup Configuration Register */
-
- #define PSSR_RDH (1 << 5) /* Read Disable Hold */
- #define PSSR_PH (1 << 4) /* Peripheral Control Hold */
---- /dev/null
-+++ linux-2.4.21/include/asm-arm/arch-pxa/ramses.h
-@@ -0,0 +1,364 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/ramses.h
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Copyright (c) 2002,2003 M&N Logistik-Lösungen Online GmbH
-+ *
-+ * 2001-09-13: Cliff Brake <cbrake@accelent.com>
-+ * Initial code
-+ *
-+ * 2002-10-08: adaption from PXA IDP to Ramses
-+ *
-+ */
-+
-+
-+/*
-+ * Note: this file must be safe to include in assembly files
-+ */
-+
-+#define RAMSES_FLASH_PHYS (PXA_CS0_PHYS)
-+#define RAMSES_ALT_FLASH_PHYS (PXA_CS1_PHYS)
-+#define RAMSES_MEDIAQ_PHYS (PXA_CS3_PHYS)
-+#define RAMSES_CONTROL_PHYS (PXA_CS4_PHYS)
-+#define RAMSES_IDE_PHYS (PXA_CS5_PHYS + 0x03000000)
-+#define RAMSES_ETH_PHYS (PXA_CS5_PHYS + 0x03400000)
-+#define RAMSES_COREVOLT_PHYS (PXA_CS5_PHYS + 0x03800000)
-+#define RAMSES_CPLD_PHYS (PXA_CS5_PHYS + 0x03C00000)
-+
-+/*
-+ * virtual memory map
-+ */
-+
-+#define RAMSES_IDE_BASE (0xf0000000)
-+#define RAMSES_IDE_SIZE (1*1024*1024)
-+#define RAMSES_ETH_BASE (RAMSES_IDE_BASE + RAMSES_IDE_SIZE)
-+#define RAMSES_ETH_SIZE (1*1024*1024)
-+#define RAMSES_COREVOLT_BASE (RAMSES_ETH_BASE + RAMSES_ETH_SIZE)
-+#define RAMSES_COREVOLT_SIZE (1*1024*1024)
-+#define RAMSES_CPLD_BASE (RAMSES_COREVOLT_BASE + RAMSES_COREVOLT_SIZE)
-+#define RAMSES_CPLD_SIZE (1*1024*1024)
-+#define RAMSES_CONTROL_BASE (RAMSES_CPLD_BASE + RAMSES_CPLD_SIZE)
-+#define RAMSES_CONTROL_SIZE (1*1024*1024)
-+
-+#if (RAMSES_CONTROL_BASE + RAMSES_CONTROL_SIZE) > 0xfc000000
-+#error Your custom IO space is getting a bit large !!
-+#endif
-+
-+#define CPLD_P2V(x) ((x) - RAMSES_CPLD_PHYS + RAMSES_CPLD_BASE)
-+#define CPLD_V2P(x) ((x) - RAMSES_CPLD_BASE + RAMSES_CPLD_PHYS)
-+#define CTRL_P2V(x) ((x) - RAMSES_CONTROL_PHYS + RAMSES_CONTROL_BASE)
-+#define CTRL_V2P(x) ((x) - RAMSES_CONTROL_BASE + RAMSES_CONTROL_PHYS)
-+#define CORE_P2V(x) ((x) - RAMSES_COREVOLT_PHYS + RAMSES_COREVOLT_BASE)
-+#define CORE_V2P(x) ((x) - RAMSES_COREVOLT_BASE + RAMSES_COREVOLT_PHYS)
-+
-+//smc91111 driver compatibility issue
-+#define ETH_BASE RAMSES_ETH_BASE
-+
-+#ifndef __ASSEMBLY__
-+# define __CPLD_REG(x) (*((volatile unsigned long *)CPLD_P2V(x)))
-+# define __CTRL_REG(x) (*((volatile unsigned long *)CTRL_P2V(x)))
-+# define __CORE_REG(x) (*((volatile unsigned long *)CORE_P2V(x)))
-+#else
-+# define __CPLD_REG(x) CPLD_P2V(x)
-+# define __CTRL_REG(x) CTRL_P2V(x)
-+# define __CORE_REG(x) CORE_P2V(x)
-+#endif
-+
-+/* CPLD addresses */
-+
-+#define RAMSES_CPLD_PERIPH_PWR_ (RAMSES_CPLD_PHYS + 0x04)
-+#define RAMSES_CPLD_PERIPH_PWR __CPLD_REG(RAMSES_CPLD_PERIPH_PWR_)
-+#define PER_RESET (1 << 4)
-+#define PER_PWR_EN (1 << 3)
-+#define USB_HOST_PWR_EN (1 << 2)
-+#define CORE_VAR_EN (1 << 0)
-+
-+#define RAMSES_CPLD_LED_CONTROL_ (RAMSES_CPLD_PHYS + 0x08)
-+#define RAMSES_CPLD_LED_CONTROL __CPLD_REG(RAMSES_CPLD_LED_CONTROL_)
-+#define CPLD_LED2 (1 << 6)
-+#define CPLD_LED1 (1 << 5)
-+#define GSM_ACTIVE (1 << 4)
-+
-+#define RAMSES_CPLD_KB_COL_HIGH_ (RAMSES_CPLD_PHYS + 0x0C)
-+#define RAMSES_CPLD_KB_COL_HIGH __CPLD_REG(RAMSES_CPLD_KB_COL_HIGH_)
-+// kbch(7)..kbch(13) on bit 0..6
-+
-+#define RAMSES_CPLD_KB_COL_LOW_ (RAMSES_CPLD_PHYS + 0x10)
-+#define RAMSES_CPLD_KB_COL_LOW __CPLD_REG(RAMSES_CPLD_KB_COL_LOW_)
-+// kbcl(0)..kbch(6) on bit 0..6
-+
-+#define RAMSES_CPLD_PCCARD_EN_ (RAMSES_CPLD_PHYS + 0x14)
-+#define RAMSES_CPLD_PCCARD_EN __CPLD_REG(RAMSES_CPLD_PCCARD_EN_)
-+#define PCC1_RESET (1 << 7)
-+#define PCC0_RESET (1 << 6)
-+#define PCC1_ENABLE (1 << 1)
-+#define PCC0_ENABLE (1 << 0)
-+
-+#define RAMSES_CPLD_PCCARD_PWR_ (RAMSES_CPLD_PHYS + 0x28)
-+#define RAMSES_CPLD_PCCARD_PWR __CPLD_REG(RAMSES_CPLD_PCCARD_PWR_)
-+#define PCC1_PWR3 (1 << 7)
-+#define PCC1_PWR2 (1 << 6)
-+#define PCC1_PWR1 (1 << 5)
-+#define PCC1_PWR0 (1 << 4)
-+#define PCC0_PWR3 (1 << 3)
-+#define PCC0_PWR2 (1 << 2)
-+#define PCC0_PWR1 (1 << 1)
-+#define PCC0_PWR0 (1 << 0)
-+
-+#define RAMSES_CPLD_MISC_CTRL_ (RAMSES_CPLD_PHYS + 0x2C)
-+#define RAMSES_CPLD_MISC_CTRL __CPLD_REG(RAMSES_CPLD_MISC_CTRL_)
-+#define RAMSES_IRDA_MD1 (1 << 5)
-+#define RAMSES_IRDA_MD0 (1 << 4)
-+#define RAMSES_FIR (1 << 3)
-+
-+#define RAMSES_CPLD_LCD_ (RAMSES_CPLD_PHYS + 0x30)
-+#define RAMSES_CPLD_LCD __CPLD_REG(RAMSES_CPLD_LCD_)
-+#define RAMSES_LCD_PINC (1 << 7)
-+#define RAMSES_LCD_PUP (1 << 6)
-+#define RAMSES_LCD_PCS (1 << 5)
-+#define RAMSES_LCD_DISPOFF (1 << 2)
-+#define RAMSES_LCD_VCC (1 << 0)
-+
-+#define RAMSES_CPLD_FLASH_WE_ (RAMSES_CPLD_PHYS + 0x34)
-+#define RAMSES_CPLD_FLASH_WE __CPLD_REG(RAMSES_CPLD_FLASH_WE_)
-+#define RAMSES_FLASH_WE (1 << 0)
-+
-+/* Read-Only registers */
-+
-+#define RAMSES_CPLD_KB_ROW_ (RAMSES_CPLD_PHYS + 0x50)
-+#define RAMSES_CPLD_KB_ROW __CPLD_REG(RAMSES_CPLD_KB_ROW_)
-+// kbr(0)..kbr(6) on bits 0..6
-+
-+#define RAMSES_CPLD_PCCARD0_STATUS_ (RAMSES_CPLD_PHYS + 0x54)
-+#define RAMSES_CPLD_PCCARD0_STATUS __CPLD_REG(RAMSES_CPLD_PCCARD0_STATUS_)
-+#define RAMSES_CPLD_PCCARD1_STATUS_ (RAMSES_CPLD_PHYS + 0x58)
-+#define RAMSES_CPLD_PCCARD1_STATUS __CPLD_REG(RAMSES_CPLD_PCCARD1_STATUS_)
-+#define _PCC_WRPROT (1 << 7)
-+#define _PCC_S16 (1 << 7)
-+#define _PCC_RESET (1 << 6)
-+#define _PCC_IRQ (1 << 5)
-+#define _PCC_INPACK (1 << 4)
-+#define PCC_BVD2 (1 << 3)
-+#define PCC_BVD1 (1 << 2)
-+#define PCC_VS2 (1 << 1)
-+#define PCC_VS1 (1 << 0)
-+
-+#define RAMSES_CPLD_MISC_STATUS_ (RAMSES_CPLD_PHYS + 0x5C)
-+#define RAMSES_CPLD_MISC_STATUS __CPLD_REG(RAMSES_CPLD_MISC_STATUS_)
-+#define RAMSES_MMC_WRPROT (1 << 7)
-+#define RAMSES_USB_OVERCURR (1 << 4)
-+#define RAMSES_CHG_STS (1 << 2)
-+#define RAMSES_WALL_IN (1 << 1)
-+#define RAMSES_USB_D_CON (1 << 0)
-+
-+#define RAMSES_CPLD_YEAR_ (RAMSES_CPLD_PHYS + 0x60)
-+#define RAMSES_CPLD_YEAR __CPLD_REG(RAMSES_CPLD_YEAR_)
-+
-+#define RAMSES_CPLD_MONTH_ (RAMSES_CPLD_PHYS + 0x64)
-+#define RAMSES_CPLD_MONTH __CPLD_REG(RAMSES_CPLD_MONTH_)
-+
-+#define RAMSES_CPLD_DAY_ (RAMSES_CPLD_PHYS + 0x68)
-+#define RAMSES_CPLD_DAY __CPLD_REG(RAMSES_CPLD_DAY_)
-+
-+#define RAMSES_CPLD_REV_ (RAMSES_CPLD_PHYS + 0x6C)
-+#define RAMSES_CPLD_REV __CPLD_REG(RAMSES_CPLD_REV_)
-+
-+#define RAMSES_CPLD_VSTAT_ (RAMSES_CPLD_PHYS + 0x7C)
-+#define RAMSES_CPLD_VSTAT __CPLD_REG(RAMSES_CPLD_VSTAT_)
-+#define RAMSES_BWE (1 << 1)
-+
-+
-+/* Flags for ramses_flags */
-+
-+#define RAMSES_FLAGS_LCD_FBTURN (1<<0)
-+/* MUST stay bit 0 */
-+#define RAMSES_FLAGS_SCANNER_BEAM (1<<1)
-+#define RAMSES_FLAGS_KEY_SCAN (1<<2)
-+#define RAMSES_FLAGS_KEY_SUSPEND (1<<3)
-+#define RAMSES_FLAGS_KEY_OFF (1<<4)
-+
-+
-+/* Offset in SMC EEPROM for LCD type */
-+#define RAMSES_LCD_TYPE_OFFSET 0x23
-+
-+
-+/* The control register on the I/O board */
-+
-+#define RAMSES_CONTROL_ (RAMSES_CONTROL_PHYS + 0)
-+#define RAMSES_CONTROL __CTRL_REG(RAMSES_CONTROL_)
-+// 5c00 = 0101 1100 0000 0000
-+#define RAMSES_CONTROL_SCANNER_TRIG_ (1 << 15)
-+#define RAMSES_CONTROL_SCANNER_WAKE_ (1 << 14)
-+#define RAMSES_CONTROL_SCANNER_PWR (1 << 13)
-+#define RAMSES_CONTROL_LED_BLUE_ (1 << 12)
-+
-+#define RAMSES_CONTROL_LED_ORANGE_ (1 << 11)
-+#define RAMSES_CONTROL_GSM_RESET (1 << 10)
-+#define RAMSES_CONTROL_GSM_BOOT (1 << 9)
-+#define RAMSES_CONTROL_GSM_PWR (1 << 8)
-+
-+#define RAMSES_CONTROL_POWEROFF (1 << 7)
-+#define RAMSES_CONTROL_USB_INTERN (1 << 6)
-+#define RAMSES_CONTROL_MMC_PWR (1 << 5)
-+#define RAMSES_CONTROL_UART_PWR (1 << 4)
-+
-+#define RAMSES_CONTROL_LCD_BLIGHT (1 << 3)
-+#define RAMSES_CONTROL_USB (1 << 2)
-+
-+#define RAMSES_POWER_OFF() { ramses_control_shadow |= RAMSES_CONTROL_POWEROFF; RAMSES_CONTROL = ramses_control_shadow; }
-+
-+// Active low
-+#define RAMSES_SCANNER_TRIG_ON() { ramses_control_shadow &= ~RAMSES_CONTROL_SCANNER_TRIG_; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_SCANNER_TRIG_OFF() { ramses_control_shadow |= RAMSES_CONTROL_SCANNER_TRIG_; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_SCANNER_WAKE_ON() { ramses_control_shadow &= ~RAMSES_CONTROL_SCANNER_WAKE_; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_SCANNER_WAKE_OFF() { ramses_control_shadow |= RAMSES_CONTROL_SCANNER_WAKE_; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_LED_BLUE_ON() { ramses_control_shadow &= ~RAMSES_CONTROL_LED_BLUE_; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_LED_BLUE_OFF() { ramses_control_shadow |= RAMSES_CONTROL_LED_BLUE_; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_LED_ORANGE_ON() { ramses_control_shadow &= ~RAMSES_CONTROL_LED_ORANGE_; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_LED_ORANGE_OFF() { ramses_control_shadow |= RAMSES_CONTROL_LED_ORANGE_; RAMSES_CONTROL = ramses_control_shadow; }
-+
-+// Active high
-+#define RAMSES_SCANNER_ON() { ramses_control_shadow |= RAMSES_CONTROL_SCANNER_PWR; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_SCANNER_OFF() { ramses_control_shadow &= ~RAMSES_CONTROL_SCANNER_PWR; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_GSM_RESET_ON() { ramses_control_shadow |= RAMSES_CONTROL_GSM_RESET; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_GSM_RESET_OFF() { ramses_control_shadow &= ~RAMSES_CONTROL_GSM_RESET; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_GSM_BOOT_ON() { ramses_control_shadow |= RAMSES_CONTROL_GSM_BOOT; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_GSM_BOOT_OFF() { ramses_control_shadow &= ~RAMSES_CONTROL_GSM_BOOT; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_GSM_ON() { ramses_control_shadow |= RAMSES_CONTROL_GSM_PWR; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_GSM_OFF() { ramses_control_shadow &= ~RAMSES_CONTROL_GSM_PWR; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_USB_INTERN() { ramses_control_shadow |= RAMSES_CONTROL_USB_INTERN; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_USB_EXTERN() { ramses_control_shadow &= ~RAMSES_CONTROL_USB_INTERN; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_UART_ON() { ramses_control_shadow |= RAMSES_CONTROL_UART_PWR; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_UART_OFF() { ramses_control_shadow &= ~RAMSES_CONTROL_UART_PWR; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_MMC_ON() { ramses_control_shadow |= RAMSES_CONTROL_MMC_PWR; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_MMC_OFF() { ramses_control_shadow &= ~RAMSES_CONTROL_MMC_PWR; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_LCD_BLIGHT_ON() { ramses_control_shadow |= RAMSES_CONTROL_LCD_BLIGHT; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_LCD_BLIGHT_OFF() { ramses_control_shadow &= ~RAMSES_CONTROL_LCD_BLIGHT; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_USB_BUS_ON() { ramses_control_shadow |= RAMSES_CONTROL_USB; RAMSES_CONTROL = ramses_control_shadow; }
-+#define RAMSES_USB_BUS_OFF() { ramses_control_shadow &= ~RAMSES_CONTROL_USB; RAMSES_CONTROL = ramses_control_shadow; }
-+
-+// Corevolt settings
-+#define RAMSES_COREVOLT_ (RAMSES_COREVOLT_PHYS)
-+#define RAMSES_COREVOLT __CORE_REG(RAMSES_COREVOLT_)
-+
-+// Battery protocol
-+#define HDQ_TMP 0x02
-+#define HDQ_LMD 0x05
-+#define HDQ_VSB 0x0b
-+#define HDQ_CACT 0x0d
-+#define HDQ_SAEH 0x0f
-+#define HDQ_SAEL 0x10
-+#define HDQ_RCAC 0x11
-+#define HDQ_DCR 0x18
-+
-+
-+#ifndef __ASSEMBLY__
-+
-+/* Ramses specific functions */
-+void ramses_lcd_power_on(void);
-+void ramses_lcd_power_off(void);
-+void ramses_lcd_backlight_on(void);
-+void ramses_lcd_backlight_off(void);
-+void ramses_lcd_set_intensity(int i);
-+#ifdef OLDCODE
-+void ramses_lcd_set_pwm1(int p);
-+#endif
-+void ramses_lcd_set_brightness(int b);
-+void ramses_lcd_set_contrast(int c);
-+int ramses_lcd_get_intensity(void);
-+int ramses_lcd_get_brightness(void);
-+int ramses_lcd_get_contrast(void);
-+int ramses_hdq_get_reg(unsigned char reg);
-+void ramses_shut_off(void);
-+void ramses_set_corevolt(int volt);
-+
-+
-+/* shadow registers for write only registers */
-+extern u16 ramses_control_shadow;
-+extern int ramses_corevolt_shadow;
-+extern u16 ramses_lcd_type;
-+extern int ramses_lcd_pwm1_shadow;
-+
-+
-+/* flag register for various settings */
-+extern unsigned int ramses_flags;
-+
-+/*
-+ * macros to write to write only register
-+ *
-+ * none of these macros are protected from
-+ * multiple drivers using them in interrupt context.
-+ */
-+
-+#define WRITE_RAMSES_CONTROL(value, mask) \
-+{\
-+ ramses_control_shadow = ((value & mask) | (ramses_control_shadow & ~mask));\
-+ RAMSES_CONTROL = ramses_control_shadow;\
-+}
-+#endif
-+
-+/*
-+ * USB Host
-+ *
-+ * The SL811HS is selected with nCS3 and some address bits:
-+ *
-+ * 12 8 4
-+ * nA14, nCS[3], address mask 1011 1111 1111 0000 = xBf00
-+ */
-+#define SL811HS_PHYS (PXA_CS3_PHYS+0xBFF0)
-+#define SL811HS_DATA (PXA_CS3_PHYS+0xBFF4)
-+
-+
-+
-+
-+
-+
-+
-+#define PCC_DETECT(x) (GPLR(7 + (x)) & GPIO_bit(7 + (x)))
-+
-+
-+
-+
-+
-+/* A listing of interrupts used by external hardware devices */
-+
-+#define TOUCH_PANEL_IRQ IRQ_GPIO(21)
-+#define TOUCH_PANEL_IRQ_EDGE GPIO_FALLING_EDGE
-+
-+#define ETHERNET_IRQ IRQ_GPIO(4)
-+#define ETHERNET_IRQ_EDGE GPIO_RISING_EDGE
-+
-+#define CFCARD_CD_VALID IRQ_GPIO(8)
-+#define CFCARD_CD_VALID_EDGE GPIO_BOTH_EDGES
-+
-+#define CFCARD_RDYINT IRQ_GPIO(22)
-+
-+#define RAMSES_KEYBOARD_IRQ IRQ_GPIO(3)
-+#define RAMSES_KEYBOARD_IRQ_EDGE GPIO_FALLING_EDGE
-+
-+#define SL811HS_IRQ IRQ_GPIO(32)
-+#define SL811HS_IRQ_EDGE GPIO_RISING_EDGE
-+
-+/*
-+ * Macros for LED Driver
-+ */
-+
-+/* leds 0 = ON */
-+#define RAMSES_HB_LED (1<<5)
-+#define RAMSES_BUSY_LED (1<<6)
-+
-+#define RAMSES_LEDS_MASK (RAMSES_HB_LED | RAMSES_BUSY_LED)
-+
-+#define RAMSES_WRITE_LEDS(value) (RAMSES_CPLD_LED_CONTROL = ((RAMSES_CPLD_LED_CONTROL & ~(RAMSES_LEDS_MASK)) | value))
-+
-+/*
-+ * macros for MTD driver
-+ */
-+
-+#define FLASH_WRITE_PROTECT_DISABLE() ((RAMSES_CPLD_FLASH_WE) &= ~(0x1))
-+#define FLASH_WRITE_PROTECT_ENABLE() ((RAMSES_CPLD_FLASH_WE) |= (0x1))
-+
-+
---- linux-2.4.21/include/asm-arm/arch-pxa/time.h~pxa-timerint
-+++ linux-2.4.21/include/asm-arm/arch-pxa/time.h
-@@ -33,7 +33,7 @@
- /* IRQs are disabled before entering here from do_gettimeofday() */
- static unsigned long pxa_gettimeoffset (void)
- {
-- unsigned long ticks_to_match, elapsed, usec;
-+ long ticks_to_match, elapsed, usec;
-
- /* Get ticks before next timer match */
- ticks_to_match = OSMR0 - OSCR;
-@@ -41,6 +41,10 @@
- /* We need elapsed ticks since last match */
- elapsed = LATCH - ticks_to_match;
-
-+ /* don't get fooled by the workaround in pxa_timer_interrupt() */
-+ if (elapsed <= 0)
-+ return 0;
-+
- /* Now convert them to usec */
- usec = (unsigned long)(elapsed*tick)/LATCH;
-
-@@ -59,6 +63,15 @@
- * IRQs are disabled inside the loop to ensure coherence between
- * lost_ticks (updated in do_timer()) and the match reg value, so we
- * can use do_gettimeofday() from interrupt handlers.
-+ *
-+ * HACK ALERT: it seems that the PXA timer regs aren't updated right
-+ * away in all cases when a write occurs. We therefore compare with
-+ * 8 instead of 0 in the while() condition below to avoid missing a
-+ * match if OSCR has already reached the next OSMR value.
-+ * Experience has shown that up to 6 ticks are needed to work around
-+ * this problem, but let's use 8 to be conservative. Note that this
-+ * affect things only when the timer IRQ has been delayed by nearly
-+ * exactly one tick period which should be a pretty rare event.
- */
- do {
- do_leds();
-@@ -68,7 +81,7 @@
- OSSR = OSSR_M0; /* Clear match on timer 0 */
- next_match = (OSMR0 += LATCH);
- restore_flags( flags );
-- } while( (signed long)(next_match - OSCR) <= 0 );
-+ } while( (signed long)(next_match - OSCR) <= 8 );
- }
-
- extern inline void setup_timer (void)
---- /dev/null
-+++ linux-2.4.21/include/asm-arm/sl811-hw.h
-@@ -0,0 +1,202 @@
-+/*
-+File: include/asm-arm/sl811-hw.h
-+
-+19.09.2003 hne@ist1.de
-+Use Kernel 2.4.20 and this source from 2.4.22
-+Splitt hardware depens into file sl811-x86.h and sl811-arm.h.
-+Functions as inline.
-+
-+23.09.2003 hne
-+Move Hardware depend header sl811-arm.h into include/asm-arm/sl811-hw.h.
-+GPRD as parameter.
-+
-+24.09.2003 hne
-+Use Offset from ADDR to DATA instand of direct io.
-+
-+03.10.2003 hne
-+Low level only for port io into hardware-include.
-+*/
-+
-+#ifndef __LINUX_SL811_HW_H
-+#define __LINUX_SL811_HW_H
-+
-+#ifdef CONFIG_X86
-+#define MAX_CONTROLERS 1 /* Max number of sl811 controllers */
-+ /* Always 1 for this architecture! */
-+
-+#define SIZEOF_IO_REGION 1 /* Size for request/release region */
-+
-+#define OFFSET_DATA_REG data_off /* Offset from ADDR_IO to DATA_IO (future) */
-+ /* Can change by arg */
-+
-+static int io = 0xf100000e; /* Base addr_io */
-+static int data_off = 1; /* Offset from addr_io to addr_io */
-+static int irq = 44; /* also change gprd !!! */
-+static int gprd = 23; /* also change irq !!! */
-+
-+MODULE_PARM(io,"i");
-+MODULE_PARM_DESC(io,"sl811 address io port 0xf100000e");
-+MODULE_PARM(data_off,"i");
-+MODULE_PARM_DESC(data_off,"sl811 data io port offset from address port (default 1)");
-+MODULE_PARM(irq,"i");
-+MODULE_PARM_DESC(irq,"sl811 irq 44(default)");
-+MODULE_PARM(gprd,"i");
-+MODULE_PARM_DESC(gprd,"sl811 GPRD port 23(default)");
-+#endif
-+
-+#ifdef CONFIG_ARCH_RAMSES
-+#define SIZEOF_IO_REGION 8 /* Size for request/release region */
-+static void *ramses_sl811hs; /* dynamically assign virtual address */
-+#endif
-+
-+
-+/*
-+ * Low level: Read from Data port [arm]
-+ */
-+static __u8 inline sl811_read_data (struct sl811_hc *hc)
-+{
-+ __u8 data;
-+ data = readb(hc->data_io);
-+ rmb();
-+//printk("%s: in %08p %02x\n", __FUNCTION__, hc->data_io, data);
-+ return data;
-+}
-+
-+/*
-+ * Low level: Write to index register [arm]
-+ */
-+static void inline sl811_write_index (struct sl811_hc *hc, __u8 index)
-+{
-+//printk("%s: out %08p %02x\n", __FUNCTION__, hc->addr_io, index);
-+ writeb(index, hc->addr_io);
-+ wmb();
-+}
-+
-+/*
-+ * Low level: Write to Data port [arm]
-+ */
-+static void inline sl811_write_data (struct sl811_hc *hc, __u8 data)
-+{
-+//printk("%s: out %08p %02x\n", __FUNCTION__, hc->data_io, data);
-+ writeb(data, hc->data_io);
-+ wmb();
-+}
-+
-+/*
-+ * Low level: Write to index register and data port [arm]
-+ */
-+static void inline sl811_write_index_data (struct sl811_hc *hc, __u8 index, __u8 data)
-+{
-+ writeb(index, hc->addr_io);
-+//printk("%s: out %08p %02x\n", __FUNCTION__, hc->addr_io, index);
-+ writeb(data, hc->data_io);
-+//printk("%s: out %08p %02x\n", __FUNCTION__, hc->data_io, data);
-+ wmb();
-+}
-+
-+
-+/*
-+ * This function is board specific. It sets up the interrupt to
-+ * be an edge trigger and trigger on the rising edge
-+ */
-+static void inline sl811_init_irq(void)
-+{
-+#ifdef CONFIG_X86
-+ GPDR &= ~(1<<gprd);
-+ set_GPIO_IRQ_edge(1<<gprd, GPIO_RISING_EDGE);
-+#endif
-+#ifdef CONFIG_ARCH_PXA
-+ int irq_gpio_pin = IRQ_TO_GPIO_2_80(SL811HS_IRQ);
-+ GPDR(irq_gpio_pin) &= ~GPIO_bit(irq_gpio_pin);
-+ set_GPIO_IRQ_edge(irq_gpio_pin, SL811HS_IRQ_EDGE);
-+#endif
-+}
-+
-+/*****************************************************************
-+ *
-+ * Function Name: release_regions [arm]
-+ *
-+ * This function is board specific. It release all io address
-+ * from memory (if can).
-+ *
-+ * Input: struct sl811_hc * *
-+ *
-+ * Return value : 0 = OK
-+ *
-+ *****************************************************************/
-+static void inline sl811_release_regions(struct sl811_hc *hc)
-+{
-+#ifdef CONFIG_X86
-+ if (hc->addr_io)
-+ release_region(hc->addr_io, SIZEOF_IO_REGION);
-+ hc->addr_io = 0;
-+
-+ if (hc->data_io)
-+ release_region(hc->data_io, SIZEOF_IO_REGION);
-+ hc->data_io = 0;
-+#endif
-+#ifdef CONFIG_ARCH_RAMSES
-+ if (ramses_sl811hs) {
-+ iounmap(ramses_sl811hs);
-+ release_mem_region(SL811HS_PHYS, SIZEOF_IO_REGION);
-+ }
-+ hc->addr_io = 0;
-+ hc->data_io = 0;
-+ RAMSES_CPLD_PERIPH_PWR &= ~USB_HOST_PWR_EN;
-+ RAMSES_USB_BUS_OFF();
-+#endif
-+}
-+
-+/*****************************************************************
-+ *
-+ * Function Name: request_regions [arm]
-+ *
-+ * This function is board specific. It request all io address and
-+ * maps into memory (if can).
-+ *
-+ * Input: struct sl811_hc *
-+ *
-+ * Return value : 0 = OK
-+ *
-+ *****************************************************************/
-+static int inline sl811_request_regions (struct sl811_hc *hc, int addr_io, int data_io, const char *name)
-+{
-+#ifdef CONFIG_X86
-+ if (!request_region(addr_io, SIZEOF_IO_REGION, name)) {
-+ PDEBUG(3, "request address %d failed", addr_io);
-+ return -EBUSY;
-+ }
-+ hc->addr_io = addr_io;
-+
-+ if (!request_region(data_io, SIZEOF_IO_REGION, MODNAME)) {
-+ PDEBUG(3, "request address %d failed", data_io);
-+ /* release_region(hc->addr_io, SIZEOF_IO_REGION); */
-+ return -EBUSY;
-+ }
-+ hc->data_io = data_io;
-+#endif
-+#ifdef CONFIG_ARCH_RAMSES
-+ RAMSES_USB_BUS_ON();
-+ RAMSES_CPLD_PERIPH_PWR |= USB_HOST_PWR_EN;
-+ mdelay(300);
-+
-+ if (!request_mem_region(SL811HS_PHYS, SIZEOF_IO_REGION, name)) {
-+ printk(KERN_ERR "unable to reserve region\n");
-+ return -EBUSY;
-+ } else {
-+ ramses_sl811hs = ioremap_nocache(SL811HS_PHYS, SIZEOF_IO_REGION);
-+ dbg("phys %p -> virt %p\n", SL811HS_PHYS, ramses_sl811hs);
-+ if (!ramses_sl811hs) {
-+ printk(KERN_ERR "unable to map region\n");
-+ release_mem_region(SL811HS_PHYS, SIZEOF_IO_REGION);
-+ return -EBUSY;
-+ }
-+ }
-+ hc->addr_io = (unsigned long) ramses_sl811hs;
-+ hc->data_io = (unsigned long) ramses_sl811hs+4;
-+#endif
-+
-+ return 0;
-+}
-+
-+#endif // __LINUX_SL811_HW_H
---- linux-2.4.21/include/linux/apm_bios.h~pm
-+++ linux-2.4.21/include/linux/apm_bios.h
-@@ -16,6 +16,8 @@
- * General Public License for more details.
- */
-
-+#include <linux/pm-devices.h>
-+
- typedef unsigned short apm_event_t;
- typedef unsigned short apm_eventinfo_t;
-
-@@ -59,6 +61,16 @@
- };
-
- /*
-+ * Allow device specific code to register function which
-+ * gets the battery power status (see arch/arm/mach-pxa/apm.c).
-+ */
-+extern void apm_register_get_power_status( int (*fn)(u_char *ac_line_status,
-+ u_char *battery_status,
-+ u_char *battery_flag,
-+ u_char *battery_percentage,
-+ u_short *battery_life));
-+
-+/*
- * The APM function codes
- */
- #define APM_FUNC_INST_CHECK 0x5300
-@@ -168,6 +180,7 @@
- /*
- * APM Device IDs
- */
-+#ifdef _i386_
- #define APM_DEVICE_BIOS 0x0000
- #define APM_DEVICE_ALL 0x0001
- #define APM_DEVICE_DISPLAY 0x0100
-@@ -181,6 +194,21 @@
- #define APM_DEVICE_OLD_ALL 0xffff
- #define APM_DEVICE_CLASS 0x00ff
- #define APM_DEVICE_MASK 0xff00
-+#endif
-+
-+/*
-+ * APM devices IDs for non-x86
-+ */
-+#define APM_DEVICE_ALL PM_SYS_DEV
-+#define APM_DEVICE_DISPLAY PM_DISPLAY_DEV
-+#define APM_DEVICE_STORAGE PM_STORAGE_DEV
-+#define APM_DEVICE_PARALLEL PM_PARALLEL_DEV
-+#define APM_DEVICE_SERIAL PM_SERIAL_DEV
-+#define APM_DEVICE_NETWORK PM_NETWORK_DEV
-+#define APM_DEVICE_PCMCIA PM_PCMCIA_DEV
-+#define APM_DEVICE_BATTERY PM_BATTERY_DEV
-+#define APM_DEVICE_TPANEL PM_TPANEL_DEV
-+
-
- #ifdef __KERNEL__
- /*
-@@ -214,5 +242,6 @@
-
- #define APM_IOC_STANDBY _IO('A', 1)
- #define APM_IOC_SUSPEND _IO('A', 2)
-+#define APM_IOC_SET_WAKEUP _IO('A', 3)
-
- #endif /* LINUX_APM_H */
---- linux-2.4.21/include/linux/i2c-id.h~i2c-ds1337
-+++ linux-2.4.21/include/linux/i2c-id.h
-@@ -95,13 +95,14 @@
- #define I2C_DRIVERID_ADV717x 48 /* ADV 7175/7176 video encoder */
- #define I2C_DRIVERID_ZR36067 49 /* Zoran 36067 video encoder */
- #define I2C_DRIVERID_ZR36120 50 /* Zoran 36120 video encoder */
--#define I2C_DRIVERID_24LC32A 51 /* Microchip 24LC32A 32k EEPROM */
-+#define I2C_DRIVERID_24LC32A 51 /* Microchip 24LC32A 32k EEPROM */
-+#define I2C_DRIVERID_DS1337 52 /* DS1337 real time clock */
-
-
-
--#define I2C_DRIVERID_DS1307 46 /* real time clock: DS1307 */
--#define I2C_DRIVERID_24LC64 47 /* EEprom 24LC64 */
--#define I2C_DRIVERID_FM24CLB4 48 /* EEprom FM24CLB4 */
-+//#define I2C_DRIVERID_DS1307 46 /* real time clock: DS1307 */
-+//#define I2C_DRIVERID_24LC64 47 /* EEprom 24LC64 */
-+//#define I2C_DRIVERID_FM24CLB4 48 /* EEprom FM24CLB4 */
-
- #define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */
- #define I2C_DRIVERID_EXP1 0xF1
---- /dev/null
-+++ linux-2.4.21/include/linux/pm-devices.h
-@@ -0,0 +1,41 @@
-+#ifndef _LINUX_PM_DEV_H
-+#define _LINUX_PM_DEV_H
-+
-+/*
-+ * Copyright 2002 Montavista Software (mlocke@mvista.com)
-+ *
-+ * 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, 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.
-+ */
-+
-+
-+
-+/*
-+ * Device types
-+ */
-+enum
-+{
-+ PM_UNKNOWN_DEV = 0, /* generic */
-+ PM_SYS_DEV, /* system device (fan, KB controller, ...) */
-+ PM_PCI_DEV, /* PCI device */
-+ PM_USB_DEV, /* USB device */
-+ PM_SCSI_DEV, /* SCSI device */
-+ PM_ISA_DEV, /* ISA device */
-+ PM_MTD_DEV, /* Memory Technology Device */
-+ PM_TPANEL_DEV, /* Memory Technology Device */
-+ PM_STORAGE_DEV, /* Memory Technology Device */
-+ PM_NETWORK_DEV, /* Memory Technology Device */
-+ PM_PCMCIA_DEV, /* Memory Technology Device */
-+ PM_DISPLAY_DEV, /* Memory Technology Device */
-+ PM_SERIAL_DEV, /* Memory Technology Device */
-+ PM_BATTERY_DEV, /* Memory Technology Device */
-+};
-+
-+#endif
---- linux-2.4.21/include/linux/pm.h~pm
-+++ linux-2.4.21/include/linux/pm.h
-@@ -24,6 +24,7 @@
- #ifdef __KERNEL__
-
- #include <linux/config.h>
-+#include <linux/pm-devices.h>
- #include <linux/list.h>
-
- /*
-@@ -49,20 +50,6 @@
- };
-
- typedef int pm_request_t;
--
--/*
-- * Device types
-- */
--enum
--{
-- PM_UNKNOWN_DEV = 0, /* generic */
-- PM_SYS_DEV, /* system device (fan, KB controller, ...) */
-- PM_PCI_DEV, /* PCI device */
-- PM_USB_DEV, /* USB device */
-- PM_SCSI_DEV, /* SCSI device */
-- PM_ISA_DEV, /* ISA device */
-- PM_MTD_DEV, /* Memory Technology Device */
--};
-
- typedef int pm_dev_t;
-
---- linux-2.4.21/include/linux/soundcard.h~ucb1x00
-+++ linux-2.4.21/include/linux/soundcard.h
-@@ -811,6 +811,7 @@
- #define SOUND_MIXER_STEREODEVS 0xfb /* Mixer channels supporting stereo */
- #define SOUND_MIXER_OUTSRC 0xfa /* Arg contains a bit for each input source to output */
- #define SOUND_MIXER_OUTMASK 0xf9 /* Arg contains a bit for each supported input source to output */
-+#define SOUND_MIXER_AC97 0xf8 /* directly access ac97 registers */
-
- /* Device mask bits */
-
-@@ -874,6 +875,7 @@
- #define SOUND_MIXER_READ_RECMASK MIXER_READ(SOUND_MIXER_RECMASK)
- #define SOUND_MIXER_READ_STEREODEVS MIXER_READ(SOUND_MIXER_STEREODEVS)
- #define SOUND_MIXER_READ_CAPS MIXER_READ(SOUND_MIXER_CAPS)
-+#define SOUND_MIXER_READ_AC97 MIXER_READ(SOUND_MIXER_AC97)
-
- #define MIXER_WRITE(dev) _SIOWR('M', dev, int)
- #define SOUND_MIXER_WRITE_VOLUME MIXER_WRITE(SOUND_MIXER_VOLUME)
-@@ -900,6 +902,7 @@
- #define SOUND_MIXER_WRITE_LOUD MIXER_WRITE(SOUND_MIXER_LOUD)
-
- #define SOUND_MIXER_WRITE_RECSRC MIXER_WRITE(SOUND_MIXER_RECSRC)
-+#define SOUND_MIXER_WRITE_AC97 MIXER_WRITE(SOUND_MIXER_AC97)
-
- typedef struct mixer_info
- {
---- linux-2.4.21/include/linux/tty.h~ramses-lcd
-+++ linux-2.4.21/include/linux/tty.h
-@@ -10,8 +10,8 @@
- * resizing).
- */
- #define MIN_NR_CONSOLES 1 /* must be at least 1 */
--#define MAX_NR_CONSOLES 63 /* serial lines start at 64 */
--#define MAX_NR_USER_CONSOLES 63 /* must be root to allocate above this */
-+#define MAX_NR_CONSOLES 3 /* serial lines start at 64 */
-+#define MAX_NR_USER_CONSOLES 3 /* must be root to allocate above this */
- /* Note: the ioctl VT_GETSTATE does not work for
- consoles 16 and higher (since it returns a short) */
-
---- linux-2.4.21/include/linux/usb.h~ramses-usb
-+++ linux-2.4.21/include/linux/usb.h
-@@ -1079,7 +1079,7 @@
- void usb_show_string(struct usb_device *dev, char *id, int index);
-
- #ifdef DEBUG
--#define dbg(format, arg...) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg)
-+#define dbg(format, arg...) printk(__FILE__ ": " format "\n" , ## arg)
- #else
- #define dbg(format, arg...) do {} while (0)
- #endif
---- linux-2.4.21/include/linux/wireless.h~linux-iw241_we16-6
-+++ linux-2.4.21/include/linux/wireless.h
-@@ -1,7 +1,7 @@
- /*
- * This file define a set of standard wireless extensions
- *
-- * Version : 15 12.7.02
-+ * Version : 16 2.4.03
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
- * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
-@@ -69,6 +69,8 @@
-
- /***************************** INCLUDES *****************************/
-
-+/* To minimise problems in user space, I might remove those headers
-+ * at some point. Jean II */
- #include <linux/types.h> /* for "caddr_t" et al */
- #include <linux/socket.h> /* for "struct sockaddr" et al */
- #include <linux/if.h> /* for IFNAMSIZ and co... */
-@@ -80,7 +82,7 @@
- * (there is some stuff that will be added in the future...)
- * I just plan to increment with each new version.
- */
--#define WIRELESS_EXT 15
-+#define WIRELESS_EXT 16
-
- /*
- * Changes :
-@@ -163,6 +165,16 @@
- * - Add IW_TXPOW_RANGE for range of Tx Powers
- * - Add IWEVREGISTERED & IWEVEXPIRED events for Access Points
- * - Add IW_MODE_MONITOR for passive monitor
-+ *
-+ * V15 to V16
-+ * ----------
-+ * - Increase the number of bitrates in iw_range to 32 (for 802.11g)
-+ * - Increase the number of frequencies in iw_range to 32 (for 802.11b+a)
-+ * - Reshuffle struct iw_range for increases, add filler
-+ * - Increase IW_MAX_AP to 64 for driver returning a lot of addresses
-+ * - Remove IW_MAX_GET_SPY because conflict with enhanced spy support
-+ * - Add SIOCSIWTHRSPY/SIOCGIWTHRSPY and "struct iw_thrspy"
-+ * - Add IW_ENCODE_TEMP and iw_range->encoding_login_index
- */
-
- /**************************** CONSTANTS ****************************/
-@@ -196,9 +208,11 @@
- /* SIOCGIWSTATS is strictly used between user space and the kernel, and
- * is never passed to the driver (i.e. the driver will never see it). */
-
--/* Mobile IP support (statistics per MAC address) */
-+/* Spy support (statistics per MAC address - used for Mobile IP support) */
- #define SIOCSIWSPY 0x8B10 /* set spy addresses */
- #define SIOCGIWSPY 0x8B11 /* get spy info (quality of link) */
-+#define SIOCSIWTHRSPY 0x8B12 /* set spy threshold (spy event) */
-+#define SIOCGIWTHRSPY 0x8B13 /* get spy threshold */
-
- /* Access Point manipulation */
- #define SIOCSIWAP 0x8B14 /* set access point MAC addresses */
-@@ -294,7 +308,7 @@
- #define IW_PRIV_TYPE_FLOAT 0x5000 /* struct iw_freq */
- #define IW_PRIV_TYPE_ADDR 0x6000 /* struct sockaddr */
-
--#define IW_PRIV_SIZE_FIXED 0x0800 /* Variable or fixed nuber of args */
-+#define IW_PRIV_SIZE_FIXED 0x0800 /* Variable or fixed number of args */
-
- #define IW_PRIV_SIZE_MASK 0x07FF /* Max number of those args */
-
-@@ -306,13 +320,13 @@
- /* ----------------------- OTHER CONSTANTS ----------------------- */
-
- /* Maximum frequencies in the range struct */
--#define IW_MAX_FREQUENCIES 16
-+#define IW_MAX_FREQUENCIES 32
- /* Note : if you have something like 80 frequencies,
- * don't increase this constant and don't fill the frequency list.
- * The user will be able to set by channel anyway... */
-
- /* Maximum bit rates in the range struct */
--#define IW_MAX_BITRATES 8
-+#define IW_MAX_BITRATES 32
-
- /* Maximum tx powers in the range struct */
- #define IW_MAX_TXPOWER 8
-@@ -320,8 +334,7 @@
- * a few of them in the struct iw_range. */
-
- /* Maximum of address that you may set with SPY */
--#define IW_MAX_SPY 8 /* set */
--#define IW_MAX_GET_SPY 64 /* get */
-+#define IW_MAX_SPY 8
-
- /* Maximum of address that you may get in the
- list of access points in range */
-@@ -354,7 +367,8 @@
- #define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */
- #define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */
- #define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */
--#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
-+#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
-+#define IW_ENCODE_TEMP 0x0400 /* Temporary key */
-
- /* Power management flags available (along with the value, if any) */
- #define IW_POWER_ON 0x0000 /* No details... */
-@@ -482,6 +496,17 @@
- __u32 beacon; /* Missed beacons/superframe */
- };
-
-+/*
-+ * Quality range (for spy threshold)
-+ */
-+struct iw_thrspy
-+{
-+ struct sockaddr addr; /* Source address (hw/mac) */
-+ struct iw_quality qual; /* Quality of the link */
-+ struct iw_quality low; /* Low threshold */
-+ struct iw_quality high; /* High threshold */
-+};
-+
- /* ------------------------ WIRELESS STATS ------------------------ */
- /*
- * Wireless statistics (used for /proc/net/wireless)
-@@ -534,7 +559,7 @@
- struct iw_quality qual; /* Quality part of statistics */
-
- struct sockaddr ap_addr; /* Access point address */
-- struct sockaddr addr; /* Destination address (hw) */
-+ struct sockaddr addr; /* Destination address (hw/mac) */
-
- struct iw_param param; /* Other small parameters */
- struct iw_point data; /* Other large parameters */
-@@ -582,17 +607,31 @@
- __u32 min_nwid; /* Minimal NWID we are able to set */
- __u32 max_nwid; /* Maximal NWID we are able to set */
-
-- /* Frequency */
-- __u16 num_channels; /* Number of channels [0; num - 1] */
-- __u8 num_frequency; /* Number of entry in the list */
-- struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */
-- /* Note : this frequency list doesn't need to fit channel numbers */
-+ /* Old Frequency (backward compat - moved lower ) */
-+ __u16 old_num_channels;
-+ __u8 old_num_frequency;
-+ /* Filler to keep "version" at the same offset */
-+ __s32 old_freq[6];
-
- /* signal level threshold range */
- __s32 sensitivity;
-
- /* Quality of link & SNR stuff */
-+ /* Quality range (link, level, noise)
-+ * If the quality is absolute, it will be in the range [0 ; max_qual],
-+ * if the quality is dBm, it will be in the range [max_qual ; 0].
-+ * Don't forget that we use 8 bit arithmetics... */
- struct iw_quality max_qual; /* Quality of the link */
-+ /* This should contain the average/typical values of the quality
-+ * indicator. This should be the threshold between a "good" and
-+ * a "bad" link (example : monitor going from green to orange).
-+ * Currently, user space apps like quality monitors don't have any
-+ * way to calibrate the measurement. With this, they can split
-+ * the range between 0 and max_qual in different quality level
-+ * (using a geometric subdivision centered on the average).
-+ * I expect that people doing the user space apps will feedback
-+ * us on which value we need to put in each driver... */
-+ struct iw_quality avg_qual; /* Quality of the link */
-
- /* Rates */
- __u8 num_bitrates; /* Number of entries in the list */
-@@ -619,6 +658,8 @@
- __u16 encoding_size[IW_MAX_ENCODING_SIZES]; /* Different token sizes */
- __u8 num_encoding_sizes; /* Number of entry in the list */
- __u8 max_encoding_tokens; /* Max number of tokens */
-+ /* For drivers that need a "login/passwd" form */
-+ __u8 encoding_login_index; /* token index for login token */
-
- /* Transmit power */
- __u16 txpower_capa; /* What options are supported */
-@@ -638,18 +679,12 @@
- __s32 min_r_time; /* Minimal retry lifetime */
- __s32 max_r_time; /* Maximal retry lifetime */
-
-- /* Average quality of link & SNR */
-- struct iw_quality avg_qual; /* Quality of the link */
-- /* This should contain the average/typical values of the quality
-- * indicator. This should be the threshold between a "good" and
-- * a "bad" link (example : monitor going from green to orange).
-- * Currently, user space apps like quality monitors don't have any
-- * way to calibrate the measurement. With this, they can split
-- * the range between 0 and max_qual in different quality level
-- * (using a geometric subdivision centered on the average).
-- * I expect that people doing the user space apps will feedback
-- * us on which value we need to put in each driver...
-- */
-+ /* Frequency */
-+ __u16 num_channels; /* Number of channels [0; num - 1] */
-+ __u8 num_frequency; /* Number of entry in the list */
-+ struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */
-+ /* Note : this frequency list doesn't need to fit channel numbers,
-+ * because each entry contain its channel index */
- };
-
- /*
---- linux-2.4.21/include/net/iw_handler.h~linux-iw241_we16-6
-+++ linux-2.4.21/include/net/iw_handler.h
-@@ -1,7 +1,7 @@
- /*
- * This file define the new driver API for Wireless Extensions
- *
-- * Version : 4 21.6.02
-+ * Version : 5 4.12.02
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
- * Copyright (c) 2001-2002 Jean Tourrilhes, All Rights Reserved.
-@@ -206,7 +206,7 @@
- * will be needed...
- * I just plan to increment with each new version.
- */
--#define IW_HANDLER_VERSION 4
-+#define IW_HANDLER_VERSION 5
-
- /*
- * Changes :
-@@ -220,10 +220,18 @@
- * V3 to V4
- * --------
- * - Reshuffle IW_HEADER_TYPE_XXX to map IW_PRIV_TYPE_XXX changes
-+ *
-+ * V4 to V5
-+ * --------
-+ * - Add new spy support : struct iw_spy_data & prototypes
- */
-
- /**************************** CONSTANTS ****************************/
-
-+/* Enable enhanced spy support. Disable to reduce footprint */
-+#define IW_WIRELESS_SPY
-+#define IW_WIRELESS_THRSPY
-+
- /* Special error message for the driver to indicate that we
- * should do a commit after return from the iw_handler */
- #define EIWCOMMIT EINPROGRESS
-@@ -315,6 +323,9 @@
- * We will automatically export that to user space... */
- struct iw_priv_args * private_args;
-
-+ /* Driver enhanced spy support */
-+ long spy_offset; /* Spy data offset */
-+
- /* In the long term, get_wireless_stats will move from
- * 'struct net_device' to here, to minimise bloat. */
- };
-@@ -350,6 +361,33 @@
-
- /* Need to think of short header translation table. Later. */
-
-+/* --------------------- ENHANCED SPY SUPPORT --------------------- */
-+/*
-+ * In the old days, the driver was handling spy support all by itself.
-+ * Now, the driver can delegate this task to Wireless Extensions.
-+ * It needs to include this struct in its private part and use the
-+ * standard spy iw_handler.
-+ */
-+
-+/*
-+ * Instance specific spy data, i.e. addresses spied and quality for them.
-+ */
-+struct iw_spy_data
-+{
-+#ifdef IW_WIRELESS_SPY
-+ /* --- Standard spy support --- */
-+ int spy_number;
-+ u_char spy_address[IW_MAX_SPY][ETH_ALEN];
-+ struct iw_quality spy_stat[IW_MAX_SPY];
-+#ifdef IW_WIRELESS_THRSPY
-+ /* --- Enhanced spy support (event) */
-+ struct iw_quality spy_thr_low; /* Low threshold */
-+ struct iw_quality spy_thr_high; /* High threshold */
-+ u_char spy_thr_under[IW_MAX_SPY];
-+#endif /* IW_WIRELESS_THRSPY */
-+#endif /* IW_WIRELESS_SPY */
-+};
-+
- /**************************** PROTOTYPES ****************************/
- /*
- * Functions part of the Wireless Extensions (defined in net/core/wireless.c).
-@@ -375,6 +413,31 @@
-
- /* We may need a function to send a stream of events to user space.
- * More on that later... */
-+
-+/* Standard handler for SIOCSIWSPY */
-+extern int iw_handler_set_spy(struct net_device * dev,
-+ struct iw_request_info * info,
-+ union iwreq_data * wrqu,
-+ char * extra);
-+/* Standard handler for SIOCGIWSPY */
-+extern int iw_handler_get_spy(struct net_device * dev,
-+ struct iw_request_info * info,
-+ union iwreq_data * wrqu,
-+ char * extra);
-+/* Standard handler for SIOCSIWTHRSPY */
-+extern int iw_handler_set_thrspy(struct net_device * dev,
-+ struct iw_request_info *info,
-+ union iwreq_data * wrqu,
-+ char * extra);
-+/* Standard handler for SIOCGIWTHRSPY */
-+extern int iw_handler_get_thrspy(struct net_device * dev,
-+ struct iw_request_info *info,
-+ union iwreq_data * wrqu,
-+ char * extra);
-+/* Driver call to update spy records */
-+extern void wireless_spy_update(struct net_device * dev,
-+ unsigned char * address,
-+ struct iw_quality * wstats);
-
- /************************* INLINE FUNTIONS *************************/
- /*
---- linux-2.4.21/init/do_mounts.c~small-nocramdisk
-+++ linux-2.4.21/init/do_mounts.c
-@@ -16,8 +16,6 @@
- #include <linux/ext2_fs.h>
- #include <linux/romfs_fs.h>
-
--#define BUILD_CRAMDISK
--
- extern int get_filesystem_list(char * buf);
-
- extern asmlinkage long sys_mount(char *dev_name, char *dir_name, char *type,
---- linux-2.4.21/kernel/ksyms.c~ramses
-+++ linux-2.4.21/kernel/ksyms.c
-@@ -585,6 +585,11 @@
-
- EXPORT_SYMBOL(tasklist_lock);
- EXPORT_SYMBOL(pidhash);
-+#ifdef CONFIG_ARCH_RAMSES
-+#include <asm/arch/ramses.h>
-+EXPORT_SYMBOL(ramses_control_shadow);
-+EXPORT_SYMBOL(ramses_flags);
-+#endif
-
- /* debug */
- EXPORT_SYMBOL(dump_stack);
---- linux-2.4.21/kernel/pm.c~pm
-+++ linux-2.4.21/kernel/pm.c
-@@ -234,7 +234,7 @@
- struct list_head *entry;
-
- down(&pm_devs_lock);
-- entry = pm_devs.next;
-+ entry = (rqst==PM_RESUME) ? pm_devs.prev : pm_devs.next;
- while (entry != &pm_devs) {
- struct pm_dev *dev = list_entry(entry, struct pm_dev, entry);
- if (dev->callback) {
-@@ -249,7 +249,7 @@
- return status;
- }
- }
-- entry = entry->next;
-+ entry = (rqst==PM_RESUME) ? entry->prev : entry->next;
- }
- up(&pm_devs_lock);
- return 0;
---- linux-2.4.21/mm/swap.c~swap-performance
-+++ linux-2.4.21/mm/swap.c
-@@ -28,7 +28,7 @@
- int page_cluster;
-
- pager_daemon_t pager_daemon = {
-- 512, /* base number for calculating the number of tries */
-+ 128, /* base number for calculating the number of tries */
- SWAP_CLUSTER_MAX, /* minimum number of tries */
- 8, /* do swap I/O in clusters of this size */
- };
---- linux-2.4.21/mm/vmalloc.c~vmalloc
-+++ linux-2.4.21/mm/vmalloc.c
-@@ -183,6 +183,9 @@
- return NULL;
-
- size += PAGE_SIZE;
-+#ifdef VMALLOC_ALIGN
-+ size = (size + VMALLOC_ALIGN - 1) & ~(VMALLOC_ALIGN - 1);
-+#endif
- if (!size) {
- kfree (area);
- return NULL;
---- linux-2.4.21/net/core/wireless.c~linux-iw241_we16-6
-+++ linux-2.4.21/net/core/wireless.c
-@@ -2,7 +2,7 @@
- * This file implement the Wireless Extensions APIs.
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-- * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
-+ * Copyright (c) 1997-2003 Jean Tourrilhes, All Rights Reserved.
- *
- * (As all part of the Linux kernel, this file is GPL)
- */
-@@ -43,6 +43,11 @@
- * o Turn on WE_STRICT_WRITE by default + kernel warning
- * o Fix WE_STRICT_WRITE in ioctl_export_private() (32 => iw_num)
- * o Fix off-by-one in test (extra_size <= IFNAMSIZ)
-+ *
-+ * v6 - 9.01.03 - Jean II
-+ * o Add common spy support : iw_handler_set_spy(), wireless_spy_update()
-+ * o Add enhanced spy support : iw_handler_set_thrspy() and event.
-+ * o Add WIRELESS_EXT version display in /proc/net/wireless
- */
-
- /***************************** INCLUDES *****************************/
-@@ -52,6 +57,7 @@
- #include <linux/types.h> /* off_t */
- #include <linux/netdevice.h> /* struct ifreq, dev_get_by_name() */
- #include <linux/rtnetlink.h> /* rtnetlink stuff */
-+#include <linux/if_arp.h> /* ARPHRD_ETHER */
-
- #include <linux/wireless.h> /* Pretty obvious */
- #include <net/iw_handler.h> /* New driver API */
-@@ -65,6 +71,7 @@
- /* Debuging stuff */
- #undef WE_IOCTL_DEBUG /* Debug IOCTL API */
- #undef WE_EVENT_DEBUG /* Debug Event dispatcher */
-+#undef WE_SPY_DEBUG /* Debug enhanced spy support */
-
- /* Options */
- #define WE_EVENT_NETLINK /* Propagate events using rtnetlink */
-@@ -72,7 +79,7 @@
-
- /************************* GLOBAL VARIABLES *************************/
- /*
-- * You should not use global variables, because or re-entrancy.
-+ * You should not use global variables, because of re-entrancy.
- * On our case, it's only const, so it's OK...
- */
- /*
-@@ -115,11 +122,11 @@
- /* SIOCSIWSPY */
- { IW_HEADER_TYPE_POINT, 0, sizeof(struct sockaddr), 0, IW_MAX_SPY, 0},
- /* SIOCGIWSPY */
-- { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_GET_SPY, 0},
-- /* -- hole -- */
-- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-- /* -- hole -- */
-- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_SPY, 0},
-+ /* SIOCSIWTHRSPY */
-+ { IW_HEADER_TYPE_POINT, 0, sizeof(struct iw_thrspy), 1, 1, 0},
-+ /* SIOCGIWTHRSPY */
-+ { IW_HEADER_TYPE_POINT, 0, sizeof(struct iw_thrspy), 1, 1, 0},
- /* SIOCSIWAP */
- { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
- /* SIOCGIWAP */
-@@ -377,9 +384,9 @@
- struct net_device * dev;
-
- size = sprintf(buffer,
-- "Inter-| sta-| Quality | Discarded packets | Missed\n"
-- " face | tus | link level noise | nwid crypt frag retry misc | beacon\n"
-- );
-+ "Inter-| sta-| Quality | Discarded packets | Missed | WE\n"
-+ " face | tus | link level noise | nwid crypt frag retry misc | beacon | %d\n",
-+ WIRELESS_EXT);
-
- pos += size;
- len += size;
-@@ -1023,4 +1030,253 @@
- kfree(event);
-
- return; /* Always success, I guess ;-) */
-+}
-+
-+/********************** ENHANCED IWSPY SUPPORT **********************/
-+/*
-+ * In the old days, the driver was handling spy support all by itself.
-+ * Now, the driver can delegate this task to Wireless Extensions.
-+ * It needs to use those standard spy iw_handler in struct iw_handler_def,
-+ * push data to us via XXX and include struct iw_spy_data in its
-+ * private part.
-+ * One of the main advantage of centralising spy support here is that
-+ * it becomes much easier to improve and extend it without having to touch
-+ * the drivers. One example is the addition of the Spy-Threshold events.
-+ * Note : IW_WIRELESS_SPY is defined in iw_handler.h
-+ */
-+
-+/*------------------------------------------------------------------*/
-+/*
-+ * Standard Wireless Handler : set Spy List
-+ */
-+int iw_handler_set_spy(struct net_device * dev,
-+ struct iw_request_info * info,
-+ union iwreq_data * wrqu,
-+ char * extra)
-+{
-+#ifdef IW_WIRELESS_SPY
-+ struct iw_spy_data * spydata = (dev->priv +
-+ dev->wireless_handlers->spy_offset);
-+ struct sockaddr * address = (struct sockaddr *) extra;
-+
-+ /* Disable spy collection while we copy the addresses.
-+ * As we don't disable interrupts, we need to do this to avoid races.
-+ * As we are the only writer, this is good enough. */
-+ spydata->spy_number = 0;
-+
-+ /* Are there are addresses to copy? */
-+ if(wrqu->data.length > 0) {
-+ int i;
-+
-+ /* Copy addresses */
-+ for(i = 0; i < wrqu->data.length; i++)
-+ memcpy(spydata->spy_address[i], address[i].sa_data,
-+ ETH_ALEN);
-+ /* Reset stats */
-+ memset(spydata->spy_stat, 0,
-+ sizeof(struct iw_quality) * IW_MAX_SPY);
-+
-+#ifdef WE_SPY_DEBUG
-+ printk(KERN_DEBUG "iw_handler_set_spy() : offset %ld, spydata %p, num %d\n", dev->wireless_handlers->spy_offset, spydata, wrqu->data.length);
-+ for (i = 0; i < wrqu->data.length; i++)
-+ printk(KERN_DEBUG
-+ "%02X:%02X:%02X:%02X:%02X:%02X \n",
-+ spydata->spy_address[i][0],
-+ spydata->spy_address[i][1],
-+ spydata->spy_address[i][2],
-+ spydata->spy_address[i][3],
-+ spydata->spy_address[i][4],
-+ spydata->spy_address[i][5]);
-+#endif /* WE_SPY_DEBUG */
-+ }
-+ /* Enable addresses */
-+ spydata->spy_number = wrqu->data.length;
-+
-+ return 0;
-+#else /* IW_WIRELESS_SPY */
-+ return -EOPNOTSUPP;
-+#endif /* IW_WIRELESS_SPY */
-+}
-+
-+/*------------------------------------------------------------------*/
-+/*
-+ * Standard Wireless Handler : get Spy List
-+ */
-+int iw_handler_get_spy(struct net_device * dev,
-+ struct iw_request_info * info,
-+ union iwreq_data * wrqu,
-+ char * extra)
-+{
-+#ifdef IW_WIRELESS_SPY
-+ struct iw_spy_data * spydata = (dev->priv +
-+ dev->wireless_handlers->spy_offset);
-+ struct sockaddr * address = (struct sockaddr *) extra;
-+ int i;
-+
-+ wrqu->data.length = spydata->spy_number;
-+
-+ /* Copy addresses. */
-+ for(i = 0; i < spydata->spy_number; i++) {
-+ memcpy(address[i].sa_data, spydata->spy_address[i], ETH_ALEN);
-+ address[i].sa_family = AF_UNIX;
-+ }
-+ /* Copy stats to the user buffer (just after). */
-+ if(spydata->spy_number > 0)
-+ memcpy(extra + (sizeof(struct sockaddr) *spydata->spy_number),
-+ spydata->spy_stat,
-+ sizeof(struct iw_quality) * spydata->spy_number);
-+ /* Reset updated flags. */
-+ for(i = 0; i < spydata->spy_number; i++)
-+ spydata->spy_stat[i].updated = 0;
-+ return 0;
-+#else /* IW_WIRELESS_SPY */
-+ return -EOPNOTSUPP;
-+#endif /* IW_WIRELESS_SPY */
-+}
-+
-+/*------------------------------------------------------------------*/
-+/*
-+ * Standard Wireless Handler : set spy threshold
-+ */
-+int iw_handler_set_thrspy(struct net_device * dev,
-+ struct iw_request_info *info,
-+ union iwreq_data * wrqu,
-+ char * extra)
-+{
-+#ifdef IW_WIRELESS_THRSPY
-+ struct iw_spy_data * spydata = (dev->priv +
-+ dev->wireless_handlers->spy_offset);
-+ struct iw_thrspy * threshold = (struct iw_thrspy *) extra;
-+
-+ /* Just do it */
-+ memcpy(&(spydata->spy_thr_low), &(threshold->low),
-+ 2 * sizeof(struct iw_quality));
-+
-+ /* Clear flag */
-+ memset(spydata->spy_thr_under, '\0', sizeof(spydata->spy_thr_under));
-+
-+#ifdef WE_SPY_DEBUG
-+ printk(KERN_DEBUG "iw_handler_set_thrspy() : low %d ; high %d\n", spydata->spy_thr_low.level, spydata->spy_thr_high.level);
-+#endif /* WE_SPY_DEBUG */
-+
-+ return 0;
-+#else /* IW_WIRELESS_THRSPY */
-+ return -EOPNOTSUPP;
-+#endif /* IW_WIRELESS_THRSPY */
-+}
-+
-+/*------------------------------------------------------------------*/
-+/*
-+ * Standard Wireless Handler : get spy threshold
-+ */
-+int iw_handler_get_thrspy(struct net_device * dev,
-+ struct iw_request_info *info,
-+ union iwreq_data * wrqu,
-+ char * extra)
-+{
-+#ifdef IW_WIRELESS_THRSPY
-+ struct iw_spy_data * spydata = (dev->priv +
-+ dev->wireless_handlers->spy_offset);
-+ struct iw_thrspy * threshold = (struct iw_thrspy *) extra;
-+
-+ /* Just do it */
-+ memcpy(&(threshold->low), &(spydata->spy_thr_low),
-+ 2 * sizeof(struct iw_quality));
-+
-+ return 0;
-+#else /* IW_WIRELESS_THRSPY */
-+ return -EOPNOTSUPP;
-+#endif /* IW_WIRELESS_THRSPY */
-+}
-+
-+#ifdef IW_WIRELESS_THRSPY
-+/*------------------------------------------------------------------*/
-+/*
-+ * Prepare and send a Spy Threshold event
-+ */
-+static void iw_send_thrspy_event(struct net_device * dev,
-+ struct iw_spy_data * spydata,
-+ unsigned char * address,
-+ struct iw_quality * wstats)
-+{
-+ union iwreq_data wrqu;
-+ struct iw_thrspy threshold;
-+
-+ /* Init */
-+ wrqu.data.length = 1;
-+ wrqu.data.flags = 0;
-+ /* Copy address */
-+ memcpy(threshold.addr.sa_data, address, ETH_ALEN);
-+ threshold.addr.sa_family = ARPHRD_ETHER;
-+ /* Copy stats */
-+ memcpy(&(threshold.qual), wstats, sizeof(struct iw_quality));
-+ /* Copy also thresholds */
-+ memcpy(&(threshold.low), &(spydata->spy_thr_low),
-+ 2 * sizeof(struct iw_quality));
-+
-+#ifdef WE_SPY_DEBUG
-+ printk(KERN_DEBUG "iw_send_thrspy_event() : address %02X:%02X:%02X:%02X:%02X:%02X, level %d, up = %d\n",
-+ threshold.addr.sa_data[0],
-+ threshold.addr.sa_data[1],
-+ threshold.addr.sa_data[2],
-+ threshold.addr.sa_data[3],
-+ threshold.addr.sa_data[4],
-+ threshold.addr.sa_data[5], threshold.qual.level);
-+#endif /* WE_SPY_DEBUG */
-+
-+ /* Send event to user space */
-+ wireless_send_event(dev, SIOCGIWTHRSPY, &wrqu, (char *) &threshold);
-+}
-+#endif /* IW_WIRELESS_THRSPY */
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Call for the driver to update the spy data.
-+ * For now, the spy data is a simple array. As the size of the array is
-+ * small, this is good enough. If we wanted to support larger number of
-+ * spy addresses, we should use something more efficient...
-+ */
-+void wireless_spy_update(struct net_device * dev,
-+ unsigned char * address,
-+ struct iw_quality * wstats)
-+{
-+#ifdef IW_WIRELESS_SPY
-+ struct iw_spy_data * spydata = (dev->priv +
-+ dev->wireless_handlers->spy_offset);
-+ int i;
-+ int match = -1;
-+
-+#ifdef WE_SPY_DEBUG
-+ printk(KERN_DEBUG "wireless_spy_update() : offset %ld, spydata %p, address %02X:%02X:%02X:%02X:%02X:%02X\n", dev->wireless_handlers->spy_offset, spydata, address[0], address[1], address[2], address[3], address[4], address[5]);
-+#endif /* WE_SPY_DEBUG */
-+
-+ /* Update all records that match */
-+ for(i = 0; i < spydata->spy_number; i++)
-+ if(!memcmp(address, spydata->spy_address[i], ETH_ALEN)) {
-+ memcpy(&(spydata->spy_stat[i]), wstats,
-+ sizeof(struct iw_quality));
-+ match = i;
-+ }
-+#ifdef IW_WIRELESS_THRSPY
-+ /* Generate an event if we cross the spy threshold.
-+ * To avoid event storms, we have a simple hysteresis : we generate
-+ * event only when we go under the low threshold or above the
-+ * high threshold. */
-+ if(match >= 0) {
-+ if(spydata->spy_thr_under[match]) {
-+ if(wstats->level > spydata->spy_thr_high.level) {
-+ spydata->spy_thr_under[match] = 0;
-+ iw_send_thrspy_event(dev, spydata,
-+ address, wstats);
-+ }
-+ } else {
-+ if(wstats->level < spydata->spy_thr_low.level) {
-+ spydata->spy_thr_under[match] = 1;
-+ iw_send_thrspy_event(dev, spydata,
-+ address, wstats);
-+ }
-+ }
-+ }
-+#endif /* IW_WIRELESS_THRSPY */
-+#endif /* IW_WIRELESS_SPY */
- }
---- linux-2.4.21/net/ipv4/ipconfig.c~net-dhcp-timeout
-+++ linux-2.4.21/net/ipv4/ipconfig.c
-@@ -87,7 +87,7 @@
-
- /* Define the timeout for waiting for a DHCP/BOOTP/RARP reply */
- #define CONF_OPEN_RETRIES 2 /* (Re)open devices twice */
--#define CONF_SEND_RETRIES 6 /* Send six requests per open */
-+#define CONF_SEND_RETRIES 4 /* Send six requests per open */
- #define CONF_INTER_TIMEOUT (HZ/2) /* Inter-device timeout: 1/2 second */
- #define CONF_BASE_TIMEOUT (HZ*2) /* Initial timeout: 2 seconds */
- #define CONF_TIMEOUT_RANDOM (HZ) /* Maximum amount of randomization */
-@@ -1238,9 +1238,11 @@
- #endif
-
- if (--retries) {
-+#ifndef CONFIG_ARCH_RAMSES
- printk(KERN_ERR
- "IP-Config: Reopening network devices...\n");
- goto try_try_again;
-+#endif
- }
-
- /* Oh, well. At least we tried. */
---- linux-2.4.21/net/netsyms.c~linux-iw241_we16-6
-+++ linux-2.4.21/net/netsyms.c
-@@ -601,6 +601,11 @@
- #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
- #include <net/iw_handler.h>
- EXPORT_SYMBOL(wireless_send_event);
-+EXPORT_SYMBOL(iw_handler_set_spy);
-+EXPORT_SYMBOL(iw_handler_get_spy);
-+EXPORT_SYMBOL(iw_handler_set_thrspy);
-+EXPORT_SYMBOL(iw_handler_get_thrspy);
-+EXPORT_SYMBOL(wireless_spy_update);
- #endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
-
- #endif /* CONFIG_NET */
diff --git a/linux/mnci-ramses_2.4.21-rmk2-pxa1.bb b/linux/mnci-ramses_2.4.21-rmk2-pxa1.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/mnci-ramses_2.4.21-rmk2-pxa1.bb
+++ /dev/null
diff --git a/linux/montavista-sa-2.4.17-mvl21/apm-hh-merge.patch b/linux/montavista-sa-2.4.17-mvl21/apm-hh-merge.patch
deleted file mode 100644
index f8343f89e1..0000000000
--- a/linux/montavista-sa-2.4.17-mvl21/apm-hh-merge.patch
+++ /dev/null
@@ -1,561 +0,0 @@
-
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- linux-2.4.17_mvl21/arch/arm/mach-sa1100/apm.c~apm-hh-merge
-+++ linux-2.4.17_mvl21/arch/arm/mach-sa1100/apm.c
-@@ -86,6 +86,8 @@
- int magic;
- struct apm_user * next;
- int suser: 1;
-+ int writer : 1;
-+ int reader : 1;
- int suspend_wait: 1;
- int suspend_result;
- int suspends_pending;
-@@ -105,7 +107,7 @@
- /*
- * Local variables
- */
--//static int suspends_pending;
-+static int suspends_pending;
- //static int standbys_pending;
- //static int ignore_normal_resume;
-
-@@ -123,8 +125,6 @@
- #else
- static int power_off = 1;
- #endif
--static int exit_kapmd;
--static int kapmd_running;
-
- static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
- static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
-@@ -192,6 +192,41 @@
- return as->events[as->event_tail];
- }
-
-+static void queue_event(apm_event_t event, struct apm_user *sender)
-+{
-+ struct apm_user * as;
-+ if (user_list == NULL)
-+ return;
-+ for (as = user_list; as != NULL; as = as->next) {
-+ if ((as == sender) || (!as->reader))
-+ continue;
-+ as->event_head = (as->event_head + 1) % APM_MAX_EVENTS;
-+ if (as->event_head == as->event_tail) {
-+ static int notified;
-+
-+ if (notified++ == 0)
-+ printk(KERN_ERR "apm: an event queue overflowed\n");
-+ as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
-+ }
-+ as->events[as->event_head] = event;
-+ if ((!as->suser) || (!as->writer))
-+ continue;
-+ switch (event) {
-+ case APM_SYS_SUSPEND:
-+ case APM_USER_SUSPEND:
-+ as->suspends_pending++;
-+ suspends_pending++;
-+ break;
-+
-+ case APM_SYS_STANDBY:
-+ case APM_USER_STANDBY:
-+ as->standbys_pending++;
-+ break;
-+ }
-+ }
-+ wake_up_interruptible(&apm_waitqueue);
-+}
-+
- static int check_apm_user(struct apm_user *as, const char *func)
- {
- if ((as == NULL) || (as->magic != APM_BIOS_MAGIC)) {
-@@ -270,7 +305,6 @@
- return 0;
- }
-
--extern int pm_do_suspend(void);
-
- static int do_ioctl(struct inode * inode, struct file *filp,
- u_int cmd, u_long arg)
-@@ -284,7 +318,17 @@
- return -EPERM;
- switch (cmd) {
- case APM_IOC_SUSPEND:
-- pm_do_suspend();
-+ if (as->suspends_read > 0) {
-+ as->suspends_read--;
-+ as->suspends_pending--;
-+ suspends_pending--;
-+ } else {
-+ queue_event(APM_USER_SUSPEND, as);
-+ }
-+
-+ if (suspends_pending <= 0)
-+ wake_up(&apm_suspend_waitqueue);
-+
- break;
- default:
- return -EINVAL;
-@@ -301,6 +345,20 @@
- return 0;
- filp->private_data = NULL;
- lock_kernel();
-+ if (user_list == as)
-+ user_list = as->next;
-+ else {
-+ struct apm_user * as1;
-+
-+ for (as1 = user_list;
-+ (as1 != NULL) && (as1->next != as);
-+ as1 = as1->next)
-+ ;
-+ if (as1 == NULL)
-+ printk(KERN_ERR "apm: filp not in user list\n");
-+ else
-+ as1->next = as->next;
-+ }
- unlock_kernel();
- kfree(as);
- return 0;
-@@ -328,6 +386,8 @@
- * privileged operation -- cevans
- */
- as->suser = capable(CAP_SYS_ADMIN);
-+ as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE;
-+ as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ;
- as->next = user_list;
- user_list = as;
- filp->private_data = as;
-@@ -411,33 +471,7 @@
- return p - buf;
- }
-
--#ifndef MODULE
--static int __init apm_setup(char *str)
--{
-- int invert;
--
-- while ((str != NULL) && (*str != '\0')) {
-- if (strncmp(str, "off", 3) == 0)
-- apm_disabled = 1;
-- if (strncmp(str, "on", 2) == 0)
-- apm_disabled = 0;
-- invert = (strncmp(str, "no-", 3) == 0);
-- if (invert)
-- str += 3;
-- if (strncmp(str, "debug", 5) == 0)
-- debug = !invert;
-- if ((strncmp(str, "power-off", 9) == 0) ||
-- (strncmp(str, "power_off", 9) == 0))
-- power_off = !invert;
-- str = strchr(str, ',');
-- if (str != NULL)
-- str += strspn(str, ", \t");
-- }
-- return 1;
--}
-
--__setup("apm=", apm_setup);
--#endif
-
- static struct file_operations apm_bios_fops = {
- owner: THIS_MODULE,
-@@ -449,13 +483,55 @@
- };
-
- static struct miscdevice apm_device = {
-- APM_MINOR_DEV,
-- "apm_bios",
-- &apm_bios_fops
-+ minor : APM_MINOR_DEV,
-+ name : "apm_bios",
-+ fops : &apm_bios_fops
- };
-
- #define APM_INIT_ERROR_RETURN return -1
-
-+static pid_t apmd_pid;
-+static DECLARE_COMPLETION(apmd_exited);
-+
-+static int apm(void *unused)
-+{
-+ unsigned short bx;
-+ unsigned short cx;
-+ unsigned short dx;
-+ int error;
-+ char * power_stat;
-+ char * bat_stat;
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct apm_user au, *as;
-+
-+ lock_kernel();
-+
-+ daemonize();
-+
-+ strcpy(current->comm, "kapmd");
-+
-+ as = &au;
-+ as->magic = APM_BIOS_MAGIC;
-+ as->event_tail = as->event_head = 0;
-+ as->suspends_pending = as->standbys_pending = 0;
-+ as->suspends_read = as->standbys_read = 0;
-+ as->suser = 1;
-+ as->writer = 1;
-+ as->reader = 0;
-+
-+ while (!signal_pending (current)) {
-+ interruptible_sleep_on(&apm_suspend_waitqueue);
-+
-+ pm_suggest_suspend();
-+
-+ queue_event(APM_NORMAL_RESUME, as);
-+ }
-+
-+ unlock_kernel();
-+
-+ complete_and_exit(&apmd_exited, 0);
-+}
-+
- /*
- * Just start the APM thread. We do NOT want to do APM BIOS
- * calls from anything but the APM thread, if for no other reason
-@@ -494,18 +570,19 @@
-
- misc_register(&apm_device);
-
-+ apmd_pid = kernel_thread(apm, NULL, 0);
-+
- return 0;
- }
-
- static void __exit apm_exit(void)
- {
- misc_deregister(&apm_device);
-- remove_proc_entry("apm", NULL);
-+ remove_proc_entry("apm", NULL);
-+ kill_proc (apmd_pid, SIGTERM, 1);
-+ wait_for_completion(&apmd_exited);
- if (power_off)
- pm_power_off = NULL;
-- exit_kapmd = 1;
-- while (kapmd_running)
-- schedule();
- pm_active = 0;
- }
-
-@@ -514,6 +591,7 @@
-
- MODULE_AUTHOR("Jamey Hicks, pulling bits from original by Stephen Rothwell");
- MODULE_DESCRIPTION("A minimal emulation of APM");
-+MODULE_LICENSE("GPL");
- MODULE_PARM(debug, "i");
- MODULE_PARM_DESC(debug, "Enable debug mode");
- MODULE_PARM(power_off, "i");
---- linux-2.4.17_mvl21/arch/arm/mach-sa1100/pm.c~apm-hh-merge
-+++ linux-2.4.17_mvl21/arch/arm/mach-sa1100/pm.c
-@@ -53,6 +53,10 @@
- #include <asm/arch/assabet.h>
- #endif
-
-+#define __KERNEL_SYSCALLS__
-+#include <linux/unistd.h>
-+
-+
- /*
- * ARGH! Stupid ACPI people. They should define this in linux/sysctl.h,
- * NOT linux/acpi.h.
-@@ -64,123 +68,6 @@
- #define CTL_ACPI 9999
- #define ACPI_S1_SLP_TYP 19
-
--#ifndef CONFIG_SA1100_BEAGLE
--
--extern void sa1100_cpu_suspend(void);
--extern void sa1100_cpu_resume(void);
--
--extern unsigned long *sleep_save; /* virtual address */
--extern unsigned long sleep_save_p; /* physical address */
--
--#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
--#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
--
--int sa1110_suspend(void)
--{
-- int retval;
--
-- /* set up pointer to sleep parameters */
-- sleep_save = kmalloc (SLEEP_SAVE_SIZE*sizeof(long), GFP_ATOMIC);
-- if (!sleep_save)
-- return -ENOMEM;
-- sleep_save_p = virt_to_phys(sleep_save);
--
-- retval = pm_send_all(PM_SUSPEND, (void *)2);
-- if (retval) {
-- kfree(sleep_save);
-- return retval;
-- }
--
-- cli();
--
-- /* preserve current time */
-- RCNR = xtime.tv_sec;
--
-- /* save vital registers */
-- SAVE(OSCR);
-- SAVE(OSMR0);
-- SAVE(OSMR1);
-- SAVE(OSMR2);
-- SAVE(OSMR3);
-- SAVE(OIER);
--
-- SAVE(GPDR);
-- SAVE(GRER);
-- SAVE(GFER);
-- SAVE(GAFR);
--
-- SAVE(PPDR);
-- SAVE(PPSR);
-- SAVE(PPAR);
-- SAVE(PSDR);
--
-- SAVE(Ser1SDCR0);
--
-- SAVE(ICMR);
--
-- /* ... maybe a global variable initialized by arch code to set this? */
-- GRER = PWER;
-- GFER = 0;
-- GEDR = GEDR;
--
-- /* Clear previous reset status */
-- RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR;
--
-- /* set resume return address */
-- PSPR = virt_to_phys(sa1100_cpu_resume);
--
-- /* go zzz */
-- sa1100_cpu_suspend();
--
-- /* ensure not to come back here if it wasn't intended */
-- PSPR = 0;
--
-- DPRINTK("*** made it back from resume\n");
--
-- /* restore registers */
-- RESTORE(GPDR);
-- RESTORE(GRER);
-- RESTORE(GFER);
-- RESTORE(GAFR);
--
-- /* clear any edge detect bit */
-- GEDR = GEDR;
--
-- RESTORE(PPDR);
-- RESTORE(PPSR);
-- RESTORE(PPAR);
-- RESTORE(PSDR);
--
-- RESTORE(Ser1SDCR0);
--
-- PSSR = PSSR_PH;
--
-- RESTORE(OSMR0);
-- RESTORE(OSMR1);
-- RESTORE(OSMR2);
-- RESTORE(OSMR3);
-- RESTORE(OSCR);
-- RESTORE(OIER);
--
-- ICLR = 0;
-- ICCR = 1;
-- RESTORE(ICMR);
--
-- /* restore current time */
-- xtime.tv_sec = RCNR;
--
-- sti();
--
-- kfree (sleep_save);
--
--#ifdef CONFIG_CPU_FREQ
-- cpufreq_restore();
--#endif
--
-- return pm_send_all(PM_RESUME, (void *)0);
--}
--
--#else //CONFIG_SA1100_BEAGLE
-
- typedef struct _tag_SLEEP_SAVED_DATA {
- uint wakeup_addr;
-@@ -363,9 +250,6 @@
- " );
- }
-
--extern void h3600_control_egpio( enum ipaq_egpio_type x, int setp );
--extern unsigned long h3600_read_egpio( void );
--
- static int GPDR_saved;
- static int GPLR_saved;
- static int GRER_saved;
-@@ -742,21 +626,37 @@
- Ser3UTSR1 = 0xff;
- }
-
--#endif //CONFIG_SA1100_BEAGLE
--
-+/*
-+ * If pm_suggest_suspend_hook is non-NULL, it is called by pm_suggest_suspend.
-+ *
-+ * If sysctl_pm_do_suspend_hook is non-NULL, it is called by sysctl_pm_do_suspend.
-+ * If it returns a true value, then pm_suspend is not called.
-+ * Use this to hook in apmd, for now.
-+ *
-+ * -not exported just so that the code compiles
-+ */
-+int (*pm_suggest_suspend_hook)(int state);
-+int (*pm_sysctl_suspend_hook)(int state);
-+int pm_use_sbin_pm_helper = 1;
- static char pm_helper_path[128] = "/sbin/pm_helper";
-+extern int exec_usermodehelper(char *path, char **argv, char **envp);
-+int debug_pm = 0;
-+static int pm_helper_veto = 0;
-
--static void
-+static int
- run_sbin_pm_helper( pm_request_t action )
- {
- int i;
- char *argv[3], *envp[8];
-
- if (!pm_helper_path[0])
-- return;
-+ return 2;
-
- if ( action != PM_SUSPEND && action != PM_RESUME )
-- return;
-+ return 1;
-+
-+ /* Be root */
-+ current->uid = current->gid = 0;
-
- i = 0;
- argv[i++] = pm_helper_path;
-@@ -771,14 +671,15 @@
- envp[i] = 0;
-
- /* other stuff we want to pass to /sbin/hotplug */
-- call_usermodehelper (argv [0], argv, envp);
-+ return exec_usermodehelper (argv [0], argv, envp);
- }
-
-+int pm_force_suspend(void);
-+
- int pm_do_suspend(void)
- {
-- DPRINTK("suggest\n");
-- run_sbin_pm_helper(PM_SUSPEND);
-- return 0;
-+ DPRINTK("suspend now\n");
-+ return pm_force_suspend();
- }
-
- #ifdef CONFIG_SA1100_BEAGLE
-@@ -863,9 +764,91 @@
- }
- #endif
-
-+int pm_suggest_suspend(void)
-+{
-+ int retval;
-+
-+ if (pm_suggest_suspend_hook) {
-+ if (pm_suggest_suspend_hook(PM_SUSPEND))
-+ return 0;
-+ }
-+
-+ if (pm_use_sbin_pm_helper) {
-+ pid_t pid;
-+ int res;
-+ int status = 0;
-+ unsigned int old_fs;
-+
-+ pid = kernel_thread ((int (*) (void *)) run_sbin_pm_helper, (void *) PM_SUSPEND, 0 );
-+ if ( pid < 0 )
-+ return pid;
-+
-+ if (debug_pm)
-+ printk(KERN_CRIT "%s:%d got pid=%d\n", __FUNCTION__, __LINE__, pid);
-+
-+ old_fs = get_fs ();
-+ set_fs (get_ds ());
-+ res = waitpid(pid, &status, __WCLONE);
-+ set_fs (old_fs);
-+
-+ if ( pid != res ) {
-+ if (debug_pm)
-+ printk(KERN_CRIT ": waitpid returned %d (exit_code=%d); not suspending\n", res, status );
-+
-+ return -1;
-+ }
-+
-+ /*if ( WIFEXITED(status) && ( WIFEXITSTATUS(status) != 0 )) {*/
-+ if (( status & 0xff7f ) != 0 ) {
-+ if (pm_helper_veto) {
-+ if (debug_pm)
-+ printk(KERN_CRIT "%s: SUSPEND WAS CANCELLED BY pm_helper (exit status %d)\n", __FUNCTION__, status >> 8);
-+ return -1;
-+ } else {
-+ if (debug_pm)
-+ printk(KERN_CRIT "%s: pm_helper returned %d, but going ahead anyway\n", __FUNCTION__, status >> 8);
-+ }
-+ }
-+ }
-+
-+ if (debug_pm)
-+ printk(KERN_CRIT "%s: REALLY SUSPENDING NOW\n", __FUNCTION__ );
-+
-+ if (pm_sysctl_suspend_hook) {
-+ if (pm_sysctl_suspend_hook(PM_SUSPEND))
-+ return 0;
-+ }
-+
-+ retval = pm_do_suspend();
-+ if (retval) {
-+ if (debug_pm)
-+ printk(KERN_CRIT "pm_suspend returned %d\n", retval);
-+ return retval;
-+ }
-+
-+ if (pm_use_sbin_pm_helper) {
-+ pid_t pid;
-+
-+ if (debug_pm)
-+ printk(KERN_CRIT "%s: running pm_helper for wakeup\n", __FUNCTION__);
-+
-+ pid = kernel_thread ((int (*) (void *)) run_sbin_pm_helper, (void *) PM_RESUME, 0 );
-+ if ( pid < 0 )
-+ return pid;
-+
-+ if ( pid != waitpid ( pid, NULL, __WCLONE ))
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+EXPORT_SYMBOL(pm_suggest_suspend);
-+
-+
- static struct ctl_table pm_table[] =
- {
-- {ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0644, NULL, (proc_handler *)&pm_force_suspend},
-+/* {ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0644, NULL, (proc_handler *)&pm_force_suspend}, */
- {2, "helper", pm_helper_path, sizeof(pm_helper_path), 0644, NULL, (proc_handler *)&proc_dostring},
- #ifdef CONFIG_SA1100_BEAGLE
- {3, "wakeup_delayed_time", &wakeup_delayed_time, sizeof(wakeup_delayed_time), 0644, NULL, &proc_dointvec },
diff --git a/linux/montavista-sa-2.4.17-mvl21/beagle-sound.patch b/linux/montavista-sa-2.4.17-mvl21/beagle-sound.patch
deleted file mode 100644
index f4749ca944..0000000000
--- a/linux/montavista-sa-2.4.17-mvl21/beagle-sound.patch
+++ /dev/null
@@ -1,57 +0,0 @@
-
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- linux-2.4.17_mvl21/drivers/sound/assabet-uda1341.c~beagle-sound.patch
-+++ linux-2.4.17_mvl21/drivers/sound/assabet-uda1341.c
-@@ -49,7 +49,9 @@
- #ifdef CONFIG_SA1100_BEAGLE
- #include <linux/timer.h>
- #include <linux/sysctl.h>
--#include <asm/io.h>
-+
-+#define CCR_ADDR 0xf2000000
-+
- #endif
-
- #include "sa1100-audio.h"
-@@ -142,15 +144,12 @@
- /* MasterIA support full sampling rate in BEAGLE and
- provide click from other device */
-
-- unsigned int ccr_addr;
- unsigned int frg_set;
- unsigned int frg_get = -1;
- int count;
-
- audio_samplerate = val;
-
-- ccr_addr = (unsigned int)__ioremap((unsigned long)0x18000000, 0x00100000, 0);
--
- switch(val) {
- case 8000: frg_set = 0x01; break;
- case 11025: frg_set = 0x02; break;
-@@ -165,18 +164,16 @@
- count = 0;
- while(frg_set != frg_get) {
- /* Ensure CPLD read we gave */
-- *((volatile unsigned int*)(ccr_addr+0x04)) = frg_set;
-+ *((volatile unsigned int*)(CCR_ADDR+0x04)) = frg_set;
-
-- frg_get = *((volatile unsigned int*)(ccr_addr+0x0024)) & 0xFF;
-+ frg_get = *((volatile unsigned int*)(CCR_ADDR+0x0024)) & 0xFF;
- if ( ++count >= 10 ) {
- schedule_timeout( 1 );
- count = 0;
- }
--// printk("*** Sound: write %02x[%08x], read %02x[%08x]\n", frg_set, ccr_addr+0x04,
--// frg_get, ccr_addr+0x24);
-+// printk("*** Sound: write %02x[%08x], read %02x[%08x]\n", frg_set, CCR_ADDR+0x04,
-+// frg_get, CCR_ADDR+0x24);
- }
--
-- __iounmap((void*)ccr_addr);
- #else
- struct uda1341_cfg cfg;
- u_int clk_ref, clk_div;
diff --git a/linux/montavista-sa-2.4.17-mvl21/defconfig-beagle b/linux/montavista-sa-2.4.17-mvl21/defconfig-beagle
deleted file mode 100644
index 063f48bce2..0000000000
--- a/linux/montavista-sa-2.4.17-mvl21/defconfig-beagle
+++ /dev/null
@@ -1,1152 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_ADIFCC is not set
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP310 is not set
-# CONFIG_ARCH_IXP1200 is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_RPC is not set
-CONFIG_ARCH_SA1100=y
-# CONFIG_ARCH_SHARK is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-
-#
-# Archimedes/A5000 Implementations (select only ONE)
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-CONFIG_SA1100_ASSABET=y
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_H3XXX is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-CONFIG_SA1100_BEAGLE=y
-CONFIG_SA1100_USB=m
-CONFIG_SA1100_USB_NETLINK=m
-# CONFIG_SA1100_USB_CHAR is not set
-
-#
-# Intel PXA250/210 Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-
-#
-# Processor Type
-#
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM922T is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_SA110 is not set
-CONFIG_CPU_SA1100=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_DISCONTIGMEM=y
-# CONFIG_EMBEDDED_OOM_KILLER is not set
-# CONFIG_RTSCHED is not set
-# CONFIG_CPU_BIG_ENDIAN is not set
-
-#
-# General setup
-#
-# CONFIG_PCI is not set
-# CONFIG_ISA is not set
-# CONFIG_ISA_DMA is not set
-# CONFIG_CPU_FREQ is not set
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=y
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_CLPS6700 is not set
-CONFIG_PCMCIA_SA1100=y
-CONFIG_CMCS_HACK=y
-# CONFIG_MERCURY_BACKPAQ is not set
-# CONFIG_PCMCIA_PXA is not set
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_MULTITHREADED_CORES is not set
-# CONFIG_BINFMT_MISC is not set
-CONFIG_PM=y
-CONFIG_APM=y
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="root=/dev/mtdblock/1 mem=32M console=ttySA0 noinitrd"
-CONFIG_LEDS=y
-# CONFIG_LEDS_TIMER is not set
-# CONFIG_LEDS_CPU is not set
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_PREEMPT=y
-# CONFIG_PREEMPT_TIMES is not set
-# CONFIG_LOCK_BREAK is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_BOOTLDR_PARTS is not set
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_GEOMETRY=y
-# CONFIG_MTD_CFI_B1 is not set
-# CONFIG_MTD_CFI_B2 is not set
-CONFIG_MTD_CFI_B4=y
-# CONFIG_MTD_CFI_B8 is not set
-# CONFIG_MTD_CFI_I1 is not set
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_CSTM_MIPS_IXX is not set
-# CONFIG_MTD_NORA is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-CONFIG_MTD_SA1100=y
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_EPXA10DB is not set
-# CONFIG_MTD_LUBBOCK is not set
-# CONFIG_MTD_PCI is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC1000 is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_BLK_DEV_PRD is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=m
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=m
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_UNCLEAN=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_MIRROR=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-# CONFIG_IPV6 is not set
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-
-#
-#
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-# CONFIG_NET_ETHERNET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=m
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=m
-# CONFIG_PPP_SYNC_TTY is not set
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPPOE=m
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_STRIP is not set
-CONFIG_WAVELAN=m
-# CONFIG_ARLAN is not set
-# CONFIG_AIRONET4500 is not set
-# CONFIG_AIRONET4500_NONCS is not set
-# CONFIG_AIRONET4500_PROC is not set
-CONFIG_HERMES=m
-
-#
-# Wireless Pcmcia cards support
-#
-CONFIG_PCMCIA_HERMES=m
-CONFIG_AIRO_CS=m
-CONFIG_NET_WIRELESS=y
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-# CONFIG_PCMCIA_3C589 is not set
-# CONFIG_PCMCIA_3C574 is not set
-# CONFIG_PCMCIA_FMVJ18X is not set
-CONFIG_PCMCIA_PCNET=m
-# CONFIG_PCMCIA_AXNET is not set
-# CONFIG_PCMCIA_NMCLAN is not set
-# CONFIG_PCMCIA_SMC91C92 is not set
-# CONFIG_PCMCIA_XIRC2PS is not set
-# CONFIG_ARCNET_COM20020_CS is not set
-# CONFIG_PCMCIA_IBMTR is not set
-# CONFIG_NET_PCMCIA_RADIO is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-CONFIG_IRDA_ULTRA=y
-CONFIG_IRDA_OPTIONS=y
-
-#
-# IrDA options
-#
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-# CONFIG_IRDA_DEBUG is not set
-CONFIG_IRDA_DEVICENAME="Linux-Beagle"
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-# CONFIG_IRTTY_SIR is not set
-# CONFIG_IRPORT_SIR is not set
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-CONFIG_SA1100_FIR=m
-
-#
-# ATA/IDE/MFM/RLL support
-#
-CONFIG_IDE=y
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-# CONFIG_BLK_DEV_IDEDISK_WD is not set
-# CONFIG_BLK_DEV_COMMERIAL is not set
-# CONFIG_BLK_DEV_TIVO is not set
-CONFIG_BLK_DEV_IDECS=y
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_DMA_NONPCI is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-
-#
-# SCSI support
-#
-# CONFIG_SCSI is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=m
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_ANAKIN is not set
-# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_UART00 is not set
-# CONFIG_SERIAL_UART00_CONSOLE is not set
-CONFIG_SERIAL_SA1100=y
-CONFIG_SERIAL_SA1100_CONSOLE=y
-CONFIG_SA1100_DEFAULT_BAUDRATE=38400
-# CONFIG_SERIAL_IXP1200 is not set
-# CONFIG_SERIAL_IXP1200_CONSOLE is not set
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# L3 serial bus support
-#
-CONFIG_L3=y
-CONFIG_L3_ALGOBIT=y
-CONFIG_L3_BIT_SA1100_GPIO=y
-
-#
-# Other L3 adapters
-#
-# CONFIG_L3_SA1111 is not set
-CONFIG_BIT_SA1100_GPIO=y
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-
-#
-# Input core support is needed for gameports
-#
-
-#
-# Input core support is needed for joysticks
-#
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_SA1100_RTC=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-CONFIG_PCMCIA_SERIAL_CS=m
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-CONFIG_FS_SYNC=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=m
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=m
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_CRAMFS is not set
-CONFIG_TMPFS=y
-# CONFIG_RAMFS is not set
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-# CONFIG_ZISOFS is not set
-CONFIG_MINIX_FS=y
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-# CONFIG_DEVPTS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=m
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-# CONFIG_NFS_FS is not set
-# CONFIG_NFS_V3 is not set
-# CONFIG_ROOT_NFS is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-# CONFIG_SUNRPC is not set
-# CONFIG_LOCKD is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-# CONFIG_ZLIB_FS_INFLATE is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_SMB_NLS is not set
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="cp950"
-CONFIG_NLS_CODEPAGE_437=m
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-CONFIG_NLS_CODEPAGE_850=m
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ISO8859_1=m
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Console drivers
-#
-CONFIG_PC_KEYMAP=y
-# CONFIG_VGA_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_ACORN is not set
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_CLPS711X is not set
-CONFIG_FB_SA1100=y
-# CONFIG_FB_PXA is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_MQ200 is not set
-# CONFIG_FB_IT8181 is not set
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-# CONFIG_FBCON_CFB4 is not set
-# CONFIG_FBCON_CFB8 is not set
-CONFIG_FBCON_CFB16=y
-# CONFIG_FBCON_CFB24 is not set
-# CONFIG_FBCON_CFB32 is not set
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA_PLANES is not set
-# CONFIG_FBCON_VGA is not set
-# CONFIG_FBCON_HGA is not set
-CONFIG_FBCON_FONTWIDTH8_ONLY=y
-CONFIG_FBCON_FONTS=y
-CONFIG_FONT_8x8=y
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-CONFIG_SOUND_SA1100=y
-CONFIG_SOUND_UDA1341=y
-CONFIG_SOUND_ASSABET_UDA1341=y
-# CONFIG_SOUND_H3600_UDA1341 is not set
-# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
-# CONFIG_SOUND_SA1111_UDA1341 is not set
-# CONFIG_SOUND_SA1100SSP is not set
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_WAVEARTIST is not set
-# CONFIG_SOUND_PXA_AC97 is not set
-# CONFIG_SOUND_TVMIXER is not set
-
-#
-# Multimedia Capabilities Port drivers
-#
-CONFIG_MCP=y
-CONFIG_MCP_SA1100=y
-CONFIG_MCP_UCB1200=y
-# CONFIG_MCP_UCB1200_AUDIO is not set
-CONFIG_MCP_UCB1200_TS=y
-# CONFIG_MCP_UCB1400_TS is not set
-
-#
-# USB support
-#
-# CONFIG_USB is not set
-
-#
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-# CONFIG_USB_NON_PCI_OHCI is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_BLUETOOTH is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-
-#
-# Input core support is needed for USB HID
-#
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDCETHER is not set
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_RIO500 is not set
-
-#
-# USB Device Support
-#
-CONFIG_USBD=m
-CONFIG_USBD_VENDORID=ffff
-CONFIG_USBD_PRODUCTID=ffff
-CONFIG_USBD_PRODUCT_NAME="Beagle Series"
-CONFIG_USBD_MANUFACTURER="Master IA"
-CONFIG_USBD_USE_SERIAL_NUMBER=y
-CONFIG_USBD_SERIAL_NUMBER_STR="0123456789"
-CONFIG_USBD_SELFPOWERED=y
-CONFIG_USBD_MONITOR=m
-
-#
-#
-#
-CONFIG_USBD_PROCFS=y
-
-#
-# USB Device functions --
-#
-
-#
-# Network Function
-#
-CONFIG_USBD_NET=m
-CONFIG_USBD_NET_VENDORID=ffff
-CONFIG_USBD_NET_PRODUCTID=8004
-CONFIG_USBD_NET_IFNAME="usbd"
-CONFIG_USBD_NET_OUT_ENDPOINT=1
-CONFIG_USBD_NET_OUT_PKTSIZE=64
-CONFIG_USBD_NET_IN_ENDPOINT=2
-CONFIG_USBD_NET_IN_PKTSIZE=64
-# CONFIG_USBD_NET_ALWAYSUP is not set
-# CONFIG_USBD_NET_SAFE is not set
-CONFIG_USBD_NET_CDC=y
-CONFIG_USBD_NET_REMOTE_MACADDR=""
-CONFIG_USBD_NET_REMOTE_OUI=400002
-CONFIG_USBD_NET_LOCAL_MACADDR="400001000001"
-CONFIG_USBD_NET_LOCAL_OUI=400001
-# CONFIG_USBD_NET_MACADDR_FROM_USBADDR is not set
-
-#
-# Serial Function
-#
-CONFIG_USBD_SERIAL=m
-CONFIG_USBD_SERIAL_VENDORID=ffff
-CONFIG_USBD_SERIAL_PRODUCTID=8002
-# CONFIG_USBD_SERIAL_CDC is not set
-CONFIG_USBD_SERIAL_OUT_ENDPOINT=1
-CONFIG_USBD_SERIAL_IN_PKTSIZE=64
-CONFIG_USBD_SERIAL_IN_ENDPOINT=2
-CONFIG_USBD_SERIAL_OUT_PKTSIZE=64
-# CONFIG_USBD_SERIAL_SAFE is not set
-
-#
-# USB Device bus interfaces --
-#
-
-#
-# Intel StrongArm SA-1110 Bus Interface Driver
-#
-CONFIG_USBD_SA1100_BUS=m
-# CONFIG_SA1100_NEW_DMA_COOPERATION is not set
-CONFIG_USBD_STALL_TIMEOUT=0
-CONFIG_USBD_STALL_DISCONNECT_DURATION=2
-# CONFIG_USBD_TRAFFIC_KEEPAWAKE is not set
-
-#
-# Generic Bus Interface
-#
-# CONFIG_USBD_GENERIC_BUS is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BLUEZ is not set
-
-#
-# Kernel hacking
-#
-# CONFIG_NO_FRAME_POINTER is not set
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_NO_PGT_CACHE is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
-CONFIG_ZLIB=y
diff --git a/linux/montavista-sa-2.4.17-mvl21/disable-pcmcia-probe.patch b/linux/montavista-sa-2.4.17-mvl21/disable-pcmcia-probe.patch
deleted file mode 100644
index 79ba036323..0000000000
--- a/linux/montavista-sa-2.4.17-mvl21/disable-pcmcia-probe.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-
-#
-# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux/drivers/pcmcia/Config.in~disable-pcmcia-probe 2003-05-13 11:18:23.000000000 +0200
-+++ linux/drivers/pcmcia/Config.in 2004-05-27 13:59:50.000000000 +0200
-@@ -15,9 +15,6 @@
- tristate 'PCMCIA/CardBus support' CONFIG_PCMCIA
- if [ "$CONFIG_PCMCIA" != "n" ]; then
- # yes, I really mean the following...
-- if [ "$CONFIG_ISA" = "y" -o "$CONFIG_ARCH_SA1100" = "y" ]; then
-- define_bool CONFIG_PCMCIA_PROBE y
-- fi
- if [ "$CONFIG_PCI" != "n" ]; then
- bool ' CardBus support' CONFIG_CARDBUS
- fi
diff --git a/linux/montavista-sa-2.4.17-mvl21/flash-for-beagle-iii.patch b/linux/montavista-sa-2.4.17-mvl21/flash-for-beagle-iii.patch
deleted file mode 100644
index 5da237ff1a..0000000000
--- a/linux/montavista-sa-2.4.17-mvl21/flash-for-beagle-iii.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- linux-2.4.17_mvl21/drivers/mtd/maps/sa1100-flash.c~flash-for-beagle-iii.patch
-+++ linux-2.4.17_mvl21/drivers/mtd/maps/sa1100-flash.c
-@@ -184,12 +184,7 @@
- },
- {
- name: "root",
-- //size: 0x01E80000,
-- // for III
-- //size: 0x01AC0000,
-- // for III TimKang modified 20040112
-- //size: 0x017C0000,
-- size: 0x015C0000,
-+ size: 0x00EC0000,
- offset: MTDPART_OFS_APPEND,
- },
- {
diff --git a/linux/montavista-sa-2.4.17-mvl21/iw240_we15-6.diff b/linux/montavista-sa-2.4.17-mvl21/iw240_we15-6.diff
deleted file mode 100644
index 2ebfd8ec12..0000000000
--- a/linux/montavista-sa-2.4.17-mvl21/iw240_we15-6.diff
+++ /dev/null
@@ -1,399 +0,0 @@
-diff -u -p linux/include/linux/wireless.14.h linux/include/linux/wireless.h
---- linux/include/linux/wireless.14.h Mon Dec 2 18:51:00 2002
-+++ linux/include/linux/wireless.h Mon Dec 2 18:53:35 2002
-@@ -1,7 +1,7 @@
- /*
- * This file define a set of standard wireless extensions
- *
-- * Version : 14 25.1.02
-+ * Version : 15 12.7.02
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
- * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
-@@ -80,7 +80,7 @@
- * (there is some stuff that will be added in the future...)
- * I just plan to increment with each new version.
- */
--#define WIRELESS_EXT 14
-+#define WIRELESS_EXT 15
-
- /*
- * Changes :
-@@ -153,17 +153,32 @@
- * - Define additional specific event numbers
- * - Add "addr" and "param" fields in union iwreq_data
- * - AP scanning stuff (SIOCSIWSCAN and friends)
-+ *
-+ * V14 to V15
-+ * ----------
-+ * - Add IW_PRIV_TYPE_ADDR for struct sockaddr private arg
-+ * - Make struct iw_freq signed (both m & e), add explicit padding
-+ * - Add IWEVCUSTOM for driver specific event/scanning token
-+ * - Add IW_MAX_GET_SPY for driver returning a lot of addresses
-+ * - Add IW_TXPOW_RANGE for range of Tx Powers
-+ * - Add IWEVREGISTERED & IWEVEXPIRED events for Access Points
-+ * - Add IW_MODE_MONITOR for passive monitor
- */
-
- /**************************** CONSTANTS ****************************/
-
- /* -------------------------- IOCTL LIST -------------------------- */
-
--/* Basic operations */
-+/* Wireless Identification */
- #define SIOCSIWCOMMIT 0x8B00 /* Commit pending changes to driver */
- #define SIOCGIWNAME 0x8B01 /* get name == wireless protocol */
--#define SIOCSIWNWID 0x8B02 /* set network id (the cell) */
--#define SIOCGIWNWID 0x8B03 /* get network id */
-+/* SIOCGIWNAME is used to verify the presence of Wireless Extensions.
-+ * Common values : "IEEE 802.11-DS", "IEEE 802.11-FH", "IEEE 802.11b"...
-+ * Don't put the name of your driver there, it's useless. */
-+
-+/* Basic operations */
-+#define SIOCSIWNWID 0x8B02 /* set network id (pre-802.11) */
-+#define SIOCGIWNWID 0x8B03 /* get network id (the cell) */
- #define SIOCSIWFREQ 0x8B04 /* set channel/frequency (Hz) */
- #define SIOCGIWFREQ 0x8B05 /* get channel/frequency (Hz) */
- #define SIOCSIWMODE 0x8B06 /* set operation mode */
-@@ -178,16 +193,18 @@
- #define SIOCGIWPRIV 0x8B0D /* get private ioctl interface info */
- #define SIOCSIWSTATS 0x8B0E /* Unused */
- #define SIOCGIWSTATS 0x8B0F /* Get /proc/net/wireless stats */
-+/* SIOCGIWSTATS is strictly used between user space and the kernel, and
-+ * is never passed to the driver (i.e. the driver will never see it). */
-
--/* Mobile IP support */
-+/* Mobile IP support (statistics per MAC address) */
- #define SIOCSIWSPY 0x8B10 /* set spy addresses */
- #define SIOCGIWSPY 0x8B11 /* get spy info (quality of link) */
-
- /* Access Point manipulation */
- #define SIOCSIWAP 0x8B14 /* set access point MAC addresses */
- #define SIOCGIWAP 0x8B15 /* get access point MAC addresses */
--#define SIOCGIWAPLIST 0x8B17 /* get list of access point in range */
--#define SIOCSIWSCAN 0x8B18 /* trigger scanning */
-+#define SIOCGIWAPLIST 0x8B17 /* Deprecated in favor of scanning */
-+#define SIOCSIWSCAN 0x8B18 /* trigger scanning (list cells) */
- #define SIOCGIWSCAN 0x8B19 /* get scanning results */
-
- /* 802.11 specific support */
-@@ -197,9 +214,7 @@
- #define SIOCGIWNICKN 0x8B1D /* get node name/nickname */
- /* As the ESSID and NICKN are strings up to 32 bytes long, it doesn't fit
- * within the 'iwreq' structure, so we need to use the 'data' member to
-- * point to a string in user space, like it is done for RANGE...
-- * The "flags" member indicate if the ESSID is active or not (promiscuous).
-- */
-+ * point to a string in user space, like it is done for RANGE... */
-
- /* Other parameters useful in 802.11 and some other devices */
- #define SIOCSIWRATE 0x8B20 /* set default bit rate (bps) */
-@@ -257,7 +272,10 @@
- /* Most events use the same identifier as ioctl requests */
-
- #define IWEVTXDROP 0x8C00 /* Packet dropped to excessive retry */
--#define IWEVQUAL 0x8C01 /* Quality part of statistics */
-+#define IWEVQUAL 0x8C01 /* Quality part of statistics (scan) */
-+#define IWEVCUSTOM 0x8C02 /* Driver specific ascii string */
-+#define IWEVREGISTERED 0x8C03 /* Discovered a new node (AP mode) */
-+#define IWEVEXPIRED 0x8C04 /* Expired a node (AP mode) */
-
- #define IWEVFIRST 0x8C00
-
-@@ -273,7 +291,8 @@
- #define IW_PRIV_TYPE_BYTE 0x1000 /* Char as number */
- #define IW_PRIV_TYPE_CHAR 0x2000 /* Char as character */
- #define IW_PRIV_TYPE_INT 0x4000 /* 32 bits int */
--#define IW_PRIV_TYPE_FLOAT 0x5000
-+#define IW_PRIV_TYPE_FLOAT 0x5000 /* struct iw_freq */
-+#define IW_PRIV_TYPE_ADDR 0x6000 /* struct sockaddr */
-
- #define IW_PRIV_SIZE_FIXED 0x0800 /* Variable or fixed nuber of args */
-
-@@ -297,13 +316,16 @@
-
- /* Maximum tx powers in the range struct */
- #define IW_MAX_TXPOWER 8
-+/* Note : if you more than 8 TXPowers, just set the max and min or
-+ * a few of them in the struct iw_range. */
-
- /* Maximum of address that you may set with SPY */
--#define IW_MAX_SPY 8
-+#define IW_MAX_SPY 8 /* set */
-+#define IW_MAX_GET_SPY 64 /* get */
-
- /* Maximum of address that you may get in the
- list of access points in range */
--#define IW_MAX_AP 8
-+#define IW_MAX_AP 64
-
- /* Maximum size of the ESSID and NICKN strings */
- #define IW_ESSID_MAX_SIZE 32
-@@ -315,6 +337,7 @@
- #define IW_MODE_MASTER 3 /* Synchronisation master or Access Point */
- #define IW_MODE_REPEAT 4 /* Wireless Repeater (forwarder) */
- #define IW_MODE_SECOND 5 /* Secondary master/repeater (backup) */
-+#define IW_MODE_MONITOR 6 /* Passive monitor (listen only) */
-
- /* Maximum number of size of encoding token available
- * they are listed in the range structure */
-@@ -350,8 +373,10 @@
- #define IW_POWER_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
-
- /* Transmit Power flags available */
-+#define IW_TXPOW_TYPE 0x00FF /* Type of value */
- #define IW_TXPOW_DBM 0x0000 /* Value is in dBm */
- #define IW_TXPOW_MWATT 0x0001 /* Value is in mW */
-+#define IW_TXPOW_RANGE 0x1000 /* Range of value between min/max */
-
- /* Retry limits and lifetime flags available */
- #define IW_RETRY_ON 0x0000 /* No details... */
-@@ -376,6 +401,9 @@
- /* Maximum size of returned data */
- #define IW_SCAN_MAX_DATA 4096 /* In bytes */
-
-+/* Max number of char in custom event - use multiple of them if needed */
-+#define IW_CUSTOM_MAX 256 /* In bytes */
-+
- /****************************** TYPES ******************************/
-
- /* --------------------------- SUBTYPES --------------------------- */
-@@ -411,9 +439,10 @@ struct iw_point
- */
- struct iw_freq
- {
-- __u32 m; /* Mantissa */
-- __u16 e; /* Exponent */
-+ __s32 m; /* Mantissa */
-+ __s16 e; /* Exponent */
- __u8 i; /* List index (when in range struct) */
-+ __u8 pad; /* Unused - just for alignement */
- };
-
- /*
-diff -u -p linux/include/net/iw_handler.14.h linux/include/net/iw_handler.h
---- linux/include/net/iw_handler.14.h Mon Dec 2 18:51:17 2002
-+++ linux/include/net/iw_handler.h Mon Dec 2 18:54:51 2002
-@@ -1,7 +1,7 @@
- /*
- * This file define the new driver API for Wireless Extensions
- *
-- * Version : 3 17.1.02
-+ * Version : 4 21.6.02
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
- * Copyright (c) 2001-2002 Jean Tourrilhes, All Rights Reserved.
-@@ -206,7 +206,7 @@
- * will be needed...
- * I just plan to increment with each new version.
- */
--#define IW_HANDLER_VERSION 3
-+#define IW_HANDLER_VERSION 4
-
- /*
- * Changes :
-@@ -217,6 +217,9 @@
- * - Add Wireless Event support :
- * o wireless_send_event() prototype
- * o iwe_stream_add_event/point() inline functions
-+ * V3 to V4
-+ * --------
-+ * - Reshuffle IW_HEADER_TYPE_XXX to map IW_PRIV_TYPE_XXX changes
- */
-
- /**************************** CONSTANTS ****************************/
-@@ -233,10 +236,10 @@
- #define IW_HEADER_TYPE_CHAR 2 /* char [IFNAMSIZ] */
- #define IW_HEADER_TYPE_UINT 4 /* __u32 */
- #define IW_HEADER_TYPE_FREQ 5 /* struct iw_freq */
--#define IW_HEADER_TYPE_POINT 6 /* struct iw_point */
--#define IW_HEADER_TYPE_PARAM 7 /* struct iw_param */
--#define IW_HEADER_TYPE_ADDR 8 /* struct sockaddr */
--#define IW_HEADER_TYPE_QUAL 9 /* struct iw_quality */
-+#define IW_HEADER_TYPE_ADDR 6 /* struct sockaddr */
-+#define IW_HEADER_TYPE_POINT 8 /* struct iw_point */
-+#define IW_HEADER_TYPE_PARAM 9 /* struct iw_param */
-+#define IW_HEADER_TYPE_QUAL 10 /* struct iw_quality */
-
- /* Handling flags */
- /* Most are not implemented. I just use them as a reminder of some
-diff -u -p linux/net/core/wireless.14.c linux/net/core/wireless.c
---- linux/net/core/wireless.14.c Mon Dec 2 18:51:35 2002
-+++ linux/net/core/wireless.c Mon Dec 2 18:53:10 2002
-@@ -33,8 +33,16 @@
- * o Propagate events as rtnetlink IFLA_WIRELESS option
- * o Generate event on selected SET requests
- *
-- * v4 - 18.04.01 - Jean II
-+ * v4 - 18.04.02 - Jean II
- * o Fix stupid off by one in iw_ioctl_description : IW_ESSID_MAX_SIZE + 1
-+ *
-+ * v5 - 21.06.02 - Jean II
-+ * o Add IW_PRIV_TYPE_ADDR in priv_type_size (+cleanup)
-+ * o Reshuffle IW_HEADER_TYPE_XXX to map IW_PRIV_TYPE_XXX changes
-+ * o Add IWEVCUSTOM for driver specific event/scanning token
-+ * o Turn on WE_STRICT_WRITE by default + kernel warning
-+ * o Fix WE_STRICT_WRITE in ioctl_export_private() (32 => iw_num)
-+ * o Fix off-by-one in test (extra_size <= IFNAMSIZ)
- */
-
- /***************************** INCLUDES *****************************/
-@@ -50,8 +58,9 @@
-
- /**************************** CONSTANTS ****************************/
-
--/* This will be turned on later on... */
--#undef WE_STRICT_WRITE /* Check write buffer size */
-+/* Enough lenience, let's make sure things are proper... */
-+#define WE_STRICT_WRITE /* Check write buffer size */
-+/* I'll probably drop both the define and kernel message in the next version */
-
- /* Debuging stuff */
- #undef WE_IOCTL_DEBUG /* Debug IOCTL API */
-@@ -106,7 +115,7 @@ static const struct iw_ioctl_description
- /* SIOCSIWSPY */
- { IW_HEADER_TYPE_POINT, 0, sizeof(struct sockaddr), 0, IW_MAX_SPY, 0},
- /* SIOCGIWSPY */
-- { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_SPY, 0},
-+ { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_GET_SPY, 0},
- /* -- hole -- */
- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
- /* -- hole -- */
-@@ -176,25 +185,41 @@ static const struct iw_ioctl_description
- { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
- /* IWEVQUAL */
- { IW_HEADER_TYPE_QUAL, 0, 0, 0, 0, 0},
-+ /* IWEVCUSTOM */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_CUSTOM_MAX, 0},
-+ /* IWEVREGISTERED */
-+ { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
-+ /* IWEVEXPIRED */
-+ { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
- };
- static const int standard_event_num = (sizeof(standard_event) /
- sizeof(struct iw_ioctl_description));
-
- /* Size (in bytes) of the various private data types */
--static const char priv_type_size[] = { 0, 1, 1, 0, 4, 4, 0, 0 };
-+static const char priv_type_size[] = {
-+ 0, /* IW_PRIV_TYPE_NONE */
-+ 1, /* IW_PRIV_TYPE_BYTE */
-+ 1, /* IW_PRIV_TYPE_CHAR */
-+ 0, /* Not defined */
-+ sizeof(__u32), /* IW_PRIV_TYPE_INT */
-+ sizeof(struct iw_freq), /* IW_PRIV_TYPE_FLOAT */
-+ sizeof(struct sockaddr), /* IW_PRIV_TYPE_ADDR */
-+ 0, /* Not defined */
-+};
-
- /* Size (in bytes) of various events */
- static const int event_type_size[] = {
-- IW_EV_LCP_LEN,
-+ IW_EV_LCP_LEN, /* IW_HEADER_TYPE_NULL */
-+ 0,
-+ IW_EV_CHAR_LEN, /* IW_HEADER_TYPE_CHAR */
- 0,
-- IW_EV_CHAR_LEN,
-+ IW_EV_UINT_LEN, /* IW_HEADER_TYPE_UINT */
-+ IW_EV_FREQ_LEN, /* IW_HEADER_TYPE_FREQ */
-+ IW_EV_ADDR_LEN, /* IW_HEADER_TYPE_ADDR */
- 0,
-- IW_EV_UINT_LEN,
-- IW_EV_FREQ_LEN,
- IW_EV_POINT_LEN, /* Without variable payload */
-- IW_EV_PARAM_LEN,
-- IW_EV_ADDR_LEN,
-- IW_EV_QUAL_LEN,
-+ IW_EV_PARAM_LEN, /* IW_HEADER_TYPE_PARAM */
-+ IW_EV_QUAL_LEN, /* IW_HEADER_TYPE_QUAL */
- };
-
- /************************ COMMON SUBROUTINES ************************/
-@@ -440,8 +465,10 @@ static inline int ioctl_export_private(s
- return -EFAULT;
- #ifdef WE_STRICT_WRITE
- /* Check if there is enough buffer up there */
-- if(iwr->u.data.length < (SIOCIWLASTPRIV - SIOCIWFIRSTPRIV + 1))
-+ if(iwr->u.data.length < dev->wireless_handlers->num_private_args) {
-+ printk(KERN_ERR "%s (WE) : Buffer for request SIOCGIWPRIV too small (%d<%d)\n", dev->name, iwr->u.data.length, dev->wireless_handlers->num_private_args);
- return -E2BIG;
-+ }
- #endif /* WE_STRICT_WRITE */
-
- /* Set the number of available ioctls. */
-@@ -471,6 +498,7 @@ static inline int ioctl_standard_call(st
- const struct iw_ioctl_description * descr;
- struct iw_request_info info;
- int ret = -EINVAL;
-+ int user_size = 0;
-
- /* Get the description of the IOCTL */
- if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
-@@ -518,11 +546,8 @@ static inline int ioctl_standard_call(st
- /* Check NULL pointer */
- if(iwr->u.data.pointer == NULL)
- return -EFAULT;
--#ifdef WE_STRICT_WRITE
-- /* Check if there is enough buffer up there */
-- if(iwr->u.data.length < descr->max_tokens)
-- return -E2BIG;
--#endif /* WE_STRICT_WRITE */
-+ /* Save user space buffer size for checking */
-+ user_size = iwr->u.data.length;
- }
-
- #ifdef WE_IOCTL_DEBUG
-@@ -559,6 +584,15 @@ static inline int ioctl_standard_call(st
-
- /* If we have something to return to the user */
- if (!ret && IW_IS_GET(cmd)) {
-+#ifdef WE_STRICT_WRITE
-+ /* Check if there is enough buffer up there */
-+ if(user_size < iwr->u.data.length) {
-+ printk(KERN_ERR "%s (WE) : Buffer for request %04X too small (%d<%d)\n", dev->name, cmd, user_size, iwr->u.data.length);
-+ kfree(extra);
-+ return -E2BIG;
-+ }
-+#endif /* WE_STRICT_WRITE */
-+
- err = copy_to_user(iwr->u.data.pointer, extra,
- iwr->u.data.length *
- descr->token_size);
-@@ -646,12 +680,18 @@ static inline int ioctl_private_call(str
- /* Compute the size of the set/get arguments */
- if(descr != NULL) {
- if(IW_IS_SET(cmd)) {
-+ int offset = 0; /* For sub-ioctls */
-+ /* Check for sub-ioctl handler */
-+ if(descr->name[0] == '\0')
-+ /* Reserve one int for sub-ioctl index */
-+ offset = sizeof(__u32);
-+
- /* Size of set arguments */
- extra_size = get_priv_size(descr->set_args);
-
- /* Does it fits in iwr ? */
- if((descr->set_args & IW_PRIV_SIZE_FIXED) &&
-- (extra_size < IFNAMSIZ))
-+ ((extra_size + offset) <= IFNAMSIZ))
- extra_size = 0;
- } else {
- /* Size of set arguments */
-@@ -659,7 +699,7 @@ static inline int ioctl_private_call(str
-
- /* Does it fits in iwr ? */
- if((descr->get_args & IW_PRIV_SIZE_FIXED) &&
-- (extra_size < IFNAMSIZ))
-+ (extra_size <= IFNAMSIZ))
- extra_size = 0;
- }
- }
-@@ -925,7 +965,7 @@ void wireless_send_event(struct net_devi
- * The best the driver could do is to log an error message.
- * We will do it ourselves instead...
- */
-- printk(KERN_ERR "%s (WE) : Invalid Wireless Event (0x%04X)\n",
-+ printk(KERN_ERR "%s (WE) : Invalid/Unknown Wireless Event (0x%04X)\n",
- dev->name, cmd);
- return;
- }
diff --git a/linux/montavista-sa-2.4.17-mvl21/iw_handlers.w13-5.diff b/linux/montavista-sa-2.4.17-mvl21/iw_handlers.w13-5.diff
deleted file mode 100644
index a27a7654a9..0000000000
--- a/linux/montavista-sa-2.4.17-mvl21/iw_handlers.w13-5.diff
+++ /dev/null
@@ -1,1513 +0,0 @@
-diff -u -p -r --new-file linux/include/linux-w12/netdevice.h linux/include/linux/netdevice.h
---- linux/include/linux-w12/netdevice.h Thu Nov 22 11:47:09 2001
-+++ linux/include/linux/netdevice.h Thu Jan 17 12:00:39 2002
-@@ -278,6 +278,10 @@ struct net_device
- struct net_device_stats* (*get_stats)(struct net_device *dev);
- struct iw_statistics* (*get_wireless_stats)(struct net_device *dev);
-
-+ /* List of functions to handle Wireless Extensions (instead of ioctl).
-+ * See <net/iw_handler.h> for details. Jean II */
-+ struct iw_handler_def * wireless_handlers;
-+
- /*
- * This marks the end of the "visible" part of the structure. All
- * fields hereafter are internal to the system, and may change at
-diff -u -p -r --new-file linux/include/linux-w12/wireless.h linux/include/linux/wireless.h
---- linux/include/linux-w12/wireless.h Thu Nov 22 11:47:12 2001
-+++ linux/include/linux/wireless.h Thu Jan 17 12:04:08 2002
-@@ -1,9 +1,10 @@
- /*
- * This file define a set of standard wireless extensions
- *
-- * Version : 12 5.10.01
-+ * Version : 13 6.12.01
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-+ * Copyright (c) 1997-2001 Jean Tourrilhes, All Rights Reserved.
- */
-
- #ifndef _LINUX_WIRELESS_H
-@@ -11,6 +12,8 @@
-
- /************************** DOCUMENTATION **************************/
- /*
-+ * Initial APIs (1996 -> onward) :
-+ * -----------------------------
- * Basically, the wireless extensions are for now a set of standard ioctl
- * call + /proc/net/wireless
- *
-@@ -27,16 +30,27 @@
- * We have the list of command plus a structure descibing the
- * data exchanged...
- * Note that to add these ioctl, I was obliged to modify :
-- * net/core/dev.c (two place + add include)
-- * net/ipv4/af_inet.c (one place + add include)
-+ * # net/core/dev.c (two place + add include)
-+ * # net/ipv4/af_inet.c (one place + add include)
- *
- * /proc/net/wireless is a copy of /proc/net/dev.
- * We have a structure for data passed from the driver to /proc/net/wireless
- * Too add this, I've modified :
-- * net/core/dev.c (two other places)
-- * include/linux/netdevice.h (one place)
-- * include/linux/proc_fs.h (one place)
-+ * # net/core/dev.c (two other places)
-+ * # include/linux/netdevice.h (one place)
-+ * # include/linux/proc_fs.h (one place)
-+ *
-+ * New driver API (2001 -> onward) :
-+ * -------------------------------
-+ * This file is only concerned with the user space API and common definitions.
-+ * The new driver API is defined and documented in :
-+ * # include/net/iw_handler.h
- *
-+ * Note as well that /proc/net/wireless implementation has now moved in :
-+ * # include/linux/wireless.c
-+ *
-+ * Other comments :
-+ * --------------
- * Do not add here things that are redundant with other mechanisms
- * (drivers init, ifconfig, /proc/net/dev, ...) and with are not
- * wireless specific.
-@@ -54,16 +68,14 @@
- #include <linux/socket.h> /* for "struct sockaddr" et al */
- #include <linux/if.h> /* for IFNAMSIZ and co... */
-
--/**************************** CONSTANTS ****************************/
--
--/* --------------------------- VERSION --------------------------- */
-+/***************************** VERSION *****************************/
- /*
- * This constant is used to know the availability of the wireless
- * extensions and to know which version of wireless extensions it is
- * (there is some stuff that will be added in the future...)
- * I just plan to increment with each new version.
- */
--#define WIRELESS_EXT 12
-+#define WIRELESS_EXT 13
-
- /*
- * Changes :
-@@ -123,12 +135,20 @@
- * - Add DEV PRIVATE IOCTL to avoid collisions in SIOCDEVPRIVATE space
- * - Add new statistics (frag, retry, beacon)
- * - Add average quality (for user space calibration)
-+ *
-+ * V12 to V13
-+ * ----------
-+ * - Document creation of new driver API.
-+ * - Extract union iwreq_data from struct iwreq (for new driver API).
-+ * - Rename SIOCSIWNAME as SIOCSIWCOMMIT
- */
-
-+/**************************** CONSTANTS ****************************/
-+
- /* -------------------------- IOCTL LIST -------------------------- */
-
- /* Basic operations */
--#define SIOCSIWNAME 0x8B00 /* Unused */
-+#define SIOCSIWCOMMIT 0x8B00 /* Commit pending changes to driver */
- #define SIOCGIWNAME 0x8B01 /* get name == wireless protocol */
- #define SIOCSIWNWID 0x8B02 /* set network id (the cell) */
- #define SIOCGIWNWID 0x8B03 /* get network id */
-@@ -414,13 +434,49 @@ struct iw_statistics
-
- /* ------------------------ IOCTL REQUEST ------------------------ */
- /*
-+ * This structure defines the payload of an ioctl, and is used
-+ * below.
-+ *
-+ * Note that this structure should fit on the memory footprint
-+ * of iwreq (which is the same as ifreq), which mean a max size of
-+ * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
-+ * You should check this when increasing the structures defined
-+ * above in this file...
-+ */
-+union iwreq_data
-+{
-+ /* Config - generic */
-+ char name[IFNAMSIZ];
-+ /* Name : used to verify the presence of wireless extensions.
-+ * Name of the protocol/provider... */
-+
-+ struct iw_point essid; /* Extended network name */
-+ struct iw_param nwid; /* network id (or domain - the cell) */
-+ struct iw_freq freq; /* frequency or channel :
-+ * 0-1000 = channel
-+ * > 1000 = frequency in Hz */
-+
-+ struct iw_param sens; /* signal level threshold */
-+ struct iw_param bitrate; /* default bit rate */
-+ struct iw_param txpower; /* default transmit power */
-+ struct iw_param rts; /* RTS threshold threshold */
-+ struct iw_param frag; /* Fragmentation threshold */
-+ __u32 mode; /* Operation mode */
-+ struct iw_param retry; /* Retry limits & lifetime */
-+
-+ struct iw_point encoding; /* Encoding stuff : tokens */
-+ struct iw_param power; /* PM duration/timeout */
-+
-+ struct sockaddr ap_addr; /* Access point address */
-+
-+ struct iw_point data; /* Other large parameters */
-+};
-+
-+/*
- * The structure to exchange data for ioctl.
- * This structure is the same as 'struct ifreq', but (re)defined for
- * convenience...
-- *
-- * Note that it should fit on the same memory footprint !
-- * You should check this when increasing the above structures (16 octets)
-- * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
-+ * Do I need to remind you about structure size (32 octets) ?
- */
- struct iwreq
- {
-@@ -429,35 +485,8 @@ struct iwreq
- char ifrn_name[IFNAMSIZ]; /* if name, e.g. "eth0" */
- } ifr_ifrn;
-
-- /* Data part */
-- union
-- {
-- /* Config - generic */
-- char name[IFNAMSIZ];
-- /* Name : used to verify the presence of wireless extensions.
-- * Name of the protocol/provider... */
--
-- struct iw_point essid; /* Extended network name */
-- struct iw_param nwid; /* network id (or domain - the cell) */
-- struct iw_freq freq; /* frequency or channel :
-- * 0-1000 = channel
-- * > 1000 = frequency in Hz */
--
-- struct iw_param sens; /* signal level threshold */
-- struct iw_param bitrate; /* default bit rate */
-- struct iw_param txpower; /* default transmit power */
-- struct iw_param rts; /* RTS threshold threshold */
-- struct iw_param frag; /* Fragmentation threshold */
-- __u32 mode; /* Operation mode */
-- struct iw_param retry; /* Retry limits & lifetime */
--
-- struct iw_point encoding; /* Encoding stuff : tokens */
-- struct iw_param power; /* PM duration/timeout */
--
-- struct sockaddr ap_addr; /* Access point address */
--
-- struct iw_point data; /* Other large parameters */
-- } u;
-+ /* Data part (defined just above) */
-+ union iwreq_data u;
- };
-
- /* -------------------------- IOCTL DATA -------------------------- */
-diff -u -p -r --new-file linux/include/net-w12/iw_handler.h linux/include/net/iw_handler.h
---- linux/include/net-w12/iw_handler.h Wed Dec 31 16:00:00 1969
-+++ linux/include/net/iw_handler.h Thu Jan 17 12:16:46 2002
-@@ -0,0 +1,374 @@
-+/*
-+ * This file define the new driver API for Wireless Extensions
-+ *
-+ * Version : 2 6.12.01
-+ *
-+ * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-+ * Copyright (c) 2001 Jean Tourrilhes, All Rights Reserved.
-+ */
-+
-+#ifndef _IW_HANDLER_H
-+#define _IW_HANDLER_H
-+
-+/************************** DOCUMENTATION **************************/
-+/*
-+ * Initial driver API (1996 -> onward) :
-+ * -----------------------------------
-+ * The initial API just sends the IOCTL request received from user space
-+ * to the driver (via the driver ioctl handler). The driver has to
-+ * handle all the rest...
-+ *
-+ * The initial API also defines a specific handler in struct net_device
-+ * to handle wireless statistics.
-+ *
-+ * The initial APIs served us well and has proven a reasonably good design.
-+ * However, there is a few shortcommings :
-+ * o No events, everything is a request to the driver.
-+ * o Large ioctl function in driver with gigantic switch statement
-+ * (i.e. spaghetti code).
-+ * o Driver has to mess up with copy_to/from_user, and in many cases
-+ * does it unproperly. Common mistakes are :
-+ * * buffer overflows (no checks or off by one checks)
-+ * * call copy_to/from_user with irq disabled
-+ * o The user space interface is tied to ioctl because of the use
-+ * copy_to/from_user.
-+ *
-+ * New driver API (2001 -> onward) :
-+ * -------------------------------
-+ * The new driver API is just a bunch of standard functions (handlers),
-+ * each handling a specific Wireless Extension. The driver just export
-+ * the list of handler it supports, and those will be called apropriately.
-+ *
-+ * I tried to keep the main advantage of the previous API (simplicity,
-+ * efficiency and light weight), and also I provide a good dose of backward
-+ * compatibility (most structures are the same, driver can use both API
-+ * simultaneously, ...).
-+ * Hopefully, I've also addressed the shortcomming of the initial API.
-+ *
-+ * The advantage of the new API are :
-+ * o Handling of Extensions in driver broken in small contained functions
-+ * o Tighter checks of ioctl before calling the driver
-+ * o Flexible commit strategy (at least, the start of it)
-+ * o Backward compatibility (can be mixed with old API)
-+ * o Driver doesn't have to worry about memory and user-space issues
-+ * The last point is important for the following reasons :
-+ * o You are now able to call the new driver API from any API you
-+ * want (including from within other parts of the kernel).
-+ * o Common mistakes are avoided (buffer overflow, user space copy
-+ * with irq disabled and so on).
-+ *
-+ * The Drawback of the new API are :
-+ * o bloat (especially kernel)
-+ * o need to migrate existing drivers to new API
-+ * My initial testing shows that the new API adds around 3kB to the kernel
-+ * and save between 0 and 5kB from a typical driver.
-+ * Also, as all structures and data types are unchanged, the migration is
-+ * quite straightforward (but tedious).
-+ *
-+ * ---
-+ *
-+ * The new driver API is defined below in this file. User space should
-+ * not be aware of what's happening down there...
-+ *
-+ * A new kernel wrapper is in charge of validating the IOCTLs and calling
-+ * the appropriate driver handler. This is implemented in :
-+ * # net/core/wireless.c
-+ *
-+ * The driver export the list of handlers in :
-+ * # include/linux/netdevice.h (one place)
-+ *
-+ * The new driver API is available for WIRELESS_EXT >= 13.
-+ * Good luck with migration to the new API ;-)
-+ */
-+
-+/* ---------------------- THE IMPLEMENTATION ---------------------- */
-+/*
-+ * Some of the choice I've made are pretty controversials. Defining an
-+ * API is very much weighting compromises. This goes into some of the
-+ * details and the thinking behind the implementation.
-+ *
-+ * Implementation goals :
-+ * --------------------
-+ * The implementation goals were as follow :
-+ * o Obvious : you should not need a PhD to understand what's happening,
-+ * the benefit is easier maintainance.
-+ * o Flexible : it should accomodate a wide variety of driver
-+ * implementations and be as flexible as the old API.
-+ * o Lean : it should be efficient memory wise to minimise the impact
-+ * on kernel footprint.
-+ * o Transparent to user space : the large number of user space
-+ * applications that use Wireless Extensions should not need
-+ * any modifications.
-+ *
-+ * Array of functions versus Struct of functions
-+ * ---------------------------------------------
-+ * 1) Having an array of functions allow the kernel code to access the
-+ * handler in a single lookup, which is much more efficient (think hash
-+ * table here).
-+ * 2) The only drawback is that driver writer may put their handler in
-+ * the wrong slot. This is trivial to test (I set the frequency, the
-+ * bitrate changes). Once the handler is in the proper slot, it will be
-+ * there forever, because the array is only extended at the end.
-+ * 3) Backward/forward compatibility : adding new handler just require
-+ * extending the array, so you can put newer driver in older kernel
-+ * without having to patch the kernel code (and vice versa).
-+ *
-+ * All handler are of the same generic type
-+ * ----------------------------------------
-+ * That's a feature !!!
-+ * 1) Having a generic handler allow to have generic code, which is more
-+ * efficient. If each of the handler was individually typed I would need
-+ * to add a big switch in the kernel (== more bloat). This solution is
-+ * more scalable, adding new Wireless Extensions doesn't add new code.
-+ * 2) You can use the same handler in different slots of the array. For
-+ * hardware, it may be more efficient or logical to handle multiple
-+ * Wireless Extensions with a single function, and the API allow you to
-+ * do that. (An example would be a single record on the card to control
-+ * both bitrate and frequency, the handler would read the old record,
-+ * modify it according to info->cmd and rewrite it).
-+ *
-+ * Functions prototype uses union iwreq_data
-+ * -----------------------------------------
-+ * Some would have prefered functions defined this way :
-+ * static int mydriver_ioctl_setrate(struct net_device *dev,
-+ * long rate, int auto)
-+ * 1) The kernel code doesn't "validate" the content of iwreq_data, and
-+ * can't do it (different hardware may have different notion of what a
-+ * valid frequency is), so we don't pretend that we do it.
-+ * 2) The above form is not extendable. If I want to add a flag (for
-+ * example to distinguish setting max rate and basic rate), I would
-+ * break the prototype. Using iwreq_data is more flexible.
-+ * 3) Also, the above form is not generic (see above).
-+ * 4) I don't expect driver developper using the wrong field of the
-+ * union (Doh !), so static typechecking doesn't add much value.
-+ * 5) Lastly, you can skip the union by doing :
-+ * static int mydriver_ioctl_setrate(struct net_device *dev,
-+ * struct iw_request_info *info,
-+ * struct iw_param *rrq,
-+ * char *extra)
-+ * And then adding the handler in the array like this :
-+ * (iw_handler) mydriver_ioctl_setrate, // SIOCSIWRATE
-+ *
-+ * Using functions and not a registry
-+ * ----------------------------------
-+ * Another implementation option would have been for every instance to
-+ * define a registry (a struct containing all the Wireless Extensions)
-+ * and only have a function to commit the registry to the hardware.
-+ * 1) This approach can be emulated by the current code, but not
-+ * vice versa.
-+ * 2) Some drivers don't keep any configuration in the driver, for them
-+ * adding such a registry would be a significant bloat.
-+ * 3) The code to translate from Wireless Extension to native format is
-+ * needed anyway, so it would not reduce significantely the amount of code.
-+ * 4) The current approach only selectively translate Wireless Extensions
-+ * to native format and only selectively set, whereas the registry approach
-+ * would require to translate all WE and set all parameters for any single
-+ * change.
-+ * 5) For many Wireless Extensions, the GET operation return the current
-+ * dynamic value, not the value that was set.
-+ *
-+ * This header is <net/iw_handler.h>
-+ * ---------------------------------
-+ * 1) This header is kernel space only and should not be exported to
-+ * user space. Headers in "include/linux/" are exported, headers in
-+ * "include/net/" are not.
-+ *
-+ * Mixed 32/64 bit issues
-+ * ----------------------
-+ * The Wireless Extensions are designed to be 64 bit clean, by using only
-+ * datatypes with explicit storage size.
-+ * There are some issues related to kernel and user space using different
-+ * memory model, and in particular 64bit kernel with 32bit user space.
-+ * The problem is related to struct iw_point, that contains a pointer
-+ * that *may* need to be translated.
-+ * This is quite messy. The new API doesn't solve this problem (it can't),
-+ * but is a step in the right direction :
-+ * 1) Meta data about each ioctl is easily available, so we know what type
-+ * of translation is needed.
-+ * 2) The move of data between kernel and user space is only done in a single
-+ * place in the kernel, so adding specific hooks in there is possible.
-+ * 3) In the long term, it allows to move away from using ioctl as the
-+ * user space API.
-+ *
-+ * So many comments and so few code
-+ * --------------------------------
-+ * That's a feature. Comments won't bloat the resulting kernel binary.
-+ */
-+
-+/***************************** INCLUDES *****************************/
-+
-+#include <linux/wireless.h> /* IOCTL user space API */
-+
-+/***************************** VERSION *****************************/
-+/*
-+ * This constant is used to know which version of the driver API is
-+ * available. Hopefully, this will be pretty stable and no changes
-+ * will be needed...
-+ * I just plan to increment with each new version.
-+ */
-+#define IW_HANDLER_VERSION 2
-+
-+/**************************** CONSTANTS ****************************/
-+
-+/* Special error message for the driver to indicate that we
-+ * should do a commit after return from the iw_handler */
-+#define EIWCOMMIT EINPROGRESS
-+
-+/* Flags available in struct iw_request_info */
-+#define IW_REQUEST_FLAG_NONE 0x0000 /* No flag so far */
-+
-+/* Type of headers we know about (basically union iwreq_data) */
-+#define IW_HEADER_TYPE_NULL 0 /* Not available */
-+#define IW_HEADER_TYPE_CHAR 2 /* char [IFNAMSIZ] */
-+#define IW_HEADER_TYPE_UINT 4 /* __u32 */
-+#define IW_HEADER_TYPE_FREQ 5 /* struct iw_freq */
-+#define IW_HEADER_TYPE_POINT 6 /* struct iw_point */
-+#define IW_HEADER_TYPE_PARAM 7 /* struct iw_param */
-+#define IW_HEADER_TYPE_ADDR 8 /* struct sockaddr */
-+
-+/* Handling flags */
-+/* Most are not implemented. I just use them as a reminder of some
-+ * cool features we might need one day ;-) */
-+#define IW_DESCR_FLAG_NONE 0x0000 /* Obvious */
-+/* Wrapper level flags */
-+#define IW_DESCR_FLAG_DUMP 0x0001 /* Not part of the dump command */
-+#define IW_DESCR_FLAG_EVENT 0x0002 /* Generate an event on SET */
-+#define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET request is ROOT only */
-+/* Driver level flags */
-+#define IW_DESCR_FLAG_WAIT 0x0100 /* Wait for driver event */
-+
-+/****************************** TYPES ******************************/
-+
-+/* ----------------------- WIRELESS HANDLER ----------------------- */
-+/*
-+ * A wireless handler is just a standard function, that looks like the
-+ * ioctl handler.
-+ * We also define there how a handler list look like... As the Wireless
-+ * Extension space is quite dense, we use a simple array, which is faster
-+ * (that's the perfect hash table ;-).
-+ */
-+
-+/*
-+ * Meta data about the request passed to the iw_handler.
-+ * Most handlers can safely ignore what's in there.
-+ * The 'cmd' field might come handy if you want to use the same handler
-+ * for multiple command...
-+ * This struct is also my long term insurance. I can add new fields here
-+ * without breaking the prototype of iw_handler...
-+ */
-+struct iw_request_info
-+{
-+ __u16 cmd; /* Wireless Extension command */
-+ __u16 flags; /* More to come ;-) */
-+};
-+
-+/*
-+ * This is how a function handling a Wireless Extension should look
-+ * like (both get and set, standard and private).
-+ */
-+typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,
-+ union iwreq_data *wrqu, char *extra);
-+
-+/*
-+ * This define all the handler that the driver export.
-+ * As you need only one per driver type, please use a static const
-+ * shared by all driver instances... Same for the members...
-+ * This will be linked from net_device in <linux/netdevice.h>
-+ */
-+struct iw_handler_def
-+{
-+ /* Number of handlers defined (more precisely, index of the
-+ * last defined handler + 1) */
-+ __u16 num_standard;
-+ __u16 num_private;
-+ /* Number of private arg description */
-+ __u16 num_private_args;
-+
-+ /* Array of handlers for standard ioctls
-+ * We will call dev->wireless_handlers->standard[ioctl - SIOCSIWNAME]
-+ */
-+ iw_handler * standard;
-+
-+ /* Array of handlers for private ioctls
-+ * Will call dev->wireless_handlers->private[ioctl - SIOCIWFIRSTPRIV]
-+ */
-+ iw_handler * private;
-+
-+ /* Arguments of private handler. This one is just a list, so you
-+ * can put it in any order you want and should not leave holes...
-+ * We will automatically export that to user space... */
-+ struct iw_priv_args * private_args;
-+
-+ /* In the long term, get_wireless_stats will move from
-+ * 'struct net_device' to here, to minimise bloat. */
-+};
-+
-+/* ----------------------- WIRELESS EVENTS ----------------------- */
-+/*
-+ * Currently we don't support events, so let's just plan for the
-+ * future...
-+ */
-+
-+/*
-+ * A Wireless Event.
-+ */
-+// How do we define short header ? We don't want a flag on length.
-+// Probably a flag on event ? Highest bit to zero...
-+struct iw_event
-+{
-+ __u16 length; /* Lenght of this stuff */
-+ __u16 event; /* Wireless IOCTL */
-+ union iwreq_data header; /* IOCTL fixed payload */
-+ char extra[0]; /* Optional IOCTL data */
-+};
-+
-+/* ---------------------- IOCTL DESCRIPTION ---------------------- */
-+/*
-+ * One of the main goal of the new interface is to deal entirely with
-+ * user space/kernel space memory move.
-+ * For that, we need to know :
-+ * o if iwreq is a pointer or contain the full data
-+ * o what is the size of the data to copy
-+ *
-+ * For private IOCTLs, we use the same rules as used by iwpriv and
-+ * defined in struct iw_priv_args.
-+ *
-+ * For standard IOCTLs, things are quite different and we need to
-+ * use the stuctures below. Actually, this struct is also more
-+ * efficient, but that's another story...
-+ */
-+
-+/*
-+ * Describe how a standard IOCTL looks like.
-+ */
-+struct iw_ioctl_description
-+{
-+ __u8 header_type; /* NULL, iw_point or other */
-+ __u8 token_type; /* Future */
-+ __u16 token_size; /* Granularity of payload */
-+ __u16 min_tokens; /* Min acceptable token number */
-+ __u16 max_tokens; /* Max acceptable token number */
-+ __u32 flags; /* Special handling of the request */
-+};
-+
-+/* Need to think of short header translation table. Later. */
-+
-+/**************************** PROTOTYPES ****************************/
-+/*
-+ * Functions part of the Wireless Extensions (defined in net/core/wireless.c).
-+ * Those may be called only within the kernel.
-+ */
-+
-+/* First : function strictly used inside the kernel */
-+
-+/* Handle /proc/net/wireless, called in net/code/dev.c */
-+extern int dev_get_wireless_info(char * buffer, char **start, off_t offset,
-+ int length);
-+
-+/* Handle IOCTLs, called in net/code/dev.c */
-+extern int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd);
-+
-+/* Second : functions that may be called by driver modules */
-+/* None yet */
-+
-+#endif /* _LINUX_WIRELESS_H */
-diff -u -p -r --new-file linux/net/core-w12/Makefile linux/net/core/Makefile
---- linux/net/core-w12/Makefile Tue Oct 30 15:08:12 2001
-+++ linux/net/core/Makefile Thu Jan 17 11:06:07 2002
-@@ -26,5 +26,8 @@ obj-$(CONFIG_NET) += dev.o dev_mcast.o d
- obj-$(CONFIG_NETFILTER) += netfilter.o
- obj-$(CONFIG_NET_DIVERT) += dv.o
- obj-$(CONFIG_NET_PROFILE) += profile.o
-+obj-$(CONFIG_NET_RADIO) += wireless.o
-+# Ugly. I wish all wireless drivers were moved in drivers/net/wireless
-+obj-$(CONFIG_NET_PCMCIA_RADIO) += wireless.o
-
- include $(TOPDIR)/Rules.make
-diff -u -p -r --new-file linux/net/core-w12/dev.c linux/net/core/dev.c
---- linux/net/core-w12/dev.c Wed Nov 7 14:39:36 2001
-+++ linux/net/core/dev.c Thu Jan 17 11:06:07 2002
-@@ -102,6 +102,7 @@
- #include <linux/module.h>
- #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
- #include <linux/wireless.h> /* Note : will define WIRELESS_EXT */
-+#include <net/iw_handler.h>
- #endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
- #ifdef CONFIG_PLIP
- extern int plip_init(void);
-@@ -1796,122 +1797,6 @@ static int dev_proc_stats(char *buffer,
- #endif /* CONFIG_PROC_FS */
-
-
--#ifdef WIRELESS_EXT
--#ifdef CONFIG_PROC_FS
--
--/*
-- * Print one entry of /proc/net/wireless
-- * This is a clone of /proc/net/dev (just above)
-- */
--static int sprintf_wireless_stats(char *buffer, struct net_device *dev)
--{
-- /* Get stats from the driver */
-- struct iw_statistics *stats = (dev->get_wireless_stats ?
-- dev->get_wireless_stats(dev) :
-- (struct iw_statistics *) NULL);
-- int size;
--
-- if (stats != (struct iw_statistics *) NULL) {
-- size = sprintf(buffer,
-- "%6s: %04x %3d%c %3d%c %3d%c %6d %6d %6d %6d %6d %6d\n",
-- dev->name,
-- stats->status,
-- stats->qual.qual,
-- stats->qual.updated & 1 ? '.' : ' ',
-- stats->qual.level,
-- stats->qual.updated & 2 ? '.' : ' ',
-- stats->qual.noise,
-- stats->qual.updated & 4 ? '.' : ' ',
-- stats->discard.nwid,
-- stats->discard.code,
-- stats->discard.fragment,
-- stats->discard.retries,
-- stats->discard.misc,
-- stats->miss.beacon);
-- stats->qual.updated = 0;
-- }
-- else
-- size = 0;
--
-- return size;
--}
--
--/*
-- * Print info for /proc/net/wireless (print all entries)
-- * This is a clone of /proc/net/dev (just above)
-- */
--static int dev_get_wireless_info(char * buffer, char **start, off_t offset,
-- int length)
--{
-- int len = 0;
-- off_t begin = 0;
-- off_t pos = 0;
-- int size;
--
-- struct net_device * dev;
--
-- size = sprintf(buffer,
-- "Inter-| sta-| Quality | Discarded packets | Missed\n"
-- " face | tus | link level noise | nwid crypt frag retry misc | beacon\n"
-- );
--
-- pos += size;
-- len += size;
--
-- read_lock(&dev_base_lock);
-- for (dev = dev_base; dev != NULL; dev = dev->next) {
-- size = sprintf_wireless_stats(buffer + len, dev);
-- len += size;
-- pos = begin + len;
--
-- if (pos < offset) {
-- len = 0;
-- begin = pos;
-- }
-- if (pos > offset + length)
-- break;
-- }
-- read_unlock(&dev_base_lock);
--
-- *start = buffer + (offset - begin); /* Start of wanted data */
-- len -= (offset - begin); /* Start slop */
-- if (len > length)
-- len = length; /* Ending slop */
-- if (len < 0)
-- len = 0;
--
-- return len;
--}
--#endif /* CONFIG_PROC_FS */
--
--/*
-- * Allow programatic access to /proc/net/wireless even if /proc
-- * doesn't exist... Also more efficient...
-- */
--static inline int dev_iwstats(struct net_device *dev, struct ifreq *ifr)
--{
-- /* Get stats from the driver */
-- struct iw_statistics *stats = (dev->get_wireless_stats ?
-- dev->get_wireless_stats(dev) :
-- (struct iw_statistics *) NULL);
--
-- if (stats != (struct iw_statistics *) NULL) {
-- struct iwreq * wrq = (struct iwreq *)ifr;
--
-- /* Copy statistics to the user buffer */
-- if(copy_to_user(wrq->u.data.pointer, stats,
-- sizeof(struct iw_statistics)))
-- return -EFAULT;
--
-- /* Check if we need to clear the update flag */
-- if(wrq->u.data.flags != 0)
-- stats->qual.updated = 0;
-- return(0);
-- } else
-- return -EOPNOTSUPP;
--}
--#endif /* WIRELESS_EXT */
--
- /**
- * netdev_set_master - set up master/slave pair
- * @slave: slave device
-@@ -2209,11 +2094,6 @@ static int dev_ifsioc(struct ifreq *ifr,
- notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev);
- return 0;
-
--#ifdef WIRELESS_EXT
-- case SIOCGIWSTATS:
-- return dev_iwstats(dev, ifr);
--#endif /* WIRELESS_EXT */
--
- /*
- * Unknown or private ioctl
- */
-@@ -2239,17 +2119,6 @@ static int dev_ifsioc(struct ifreq *ifr,
- return -EOPNOTSUPP;
- }
-
--#ifdef WIRELESS_EXT
-- if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
-- if (dev->do_ioctl) {
-- if (!netif_device_present(dev))
-- return -ENODEV;
-- return dev->do_ioctl(dev, ifr, cmd);
-- }
-- return -EOPNOTSUPP;
-- }
--#endif /* WIRELESS_EXT */
--
- }
- return -EINVAL;
- }
-@@ -2431,7 +2300,8 @@ int dev_ioctl(unsigned int cmd, void *ar
- }
- dev_load(ifr.ifr_name);
- rtnl_lock();
-- ret = dev_ifsioc(&ifr, cmd);
-+ /* Follow me in net/core/wireless.c */
-+ ret = wireless_process_ioctl(&ifr, cmd);
- rtnl_unlock();
- if (!ret && IW_IS_GET(cmd) &&
- copy_to_user(arg, &ifr, sizeof(struct ifreq)))
-@@ -2856,6 +2726,7 @@ int __init net_dev_init(void)
- proc_net_create("dev", 0, dev_get_info);
- create_proc_read_entry("net/softnet_stat", 0, 0, dev_proc_stats, NULL);
- #ifdef WIRELESS_EXT
-+ /* Available in net/core/wireless.c */
- proc_net_create("wireless", 0, dev_get_wireless_info);
- #endif /* WIRELESS_EXT */
- #endif /* CONFIG_PROC_FS */
-diff -u -p -r --new-file linux/net/core-w12/wireless.c linux/net/core/wireless.c
---- linux/net/core-w12/wireless.c Wed Dec 31 16:00:00 1969
-+++ linux/net/core/wireless.c Mon Jan 21 11:13:23 2002
-@@ -0,0 +1,733 @@
-+/*
-+ * This file implement the Wireless Extensions APIs.
-+ *
-+ * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-+ * Copyright (c) 1997-2001 Jean Tourrilhes, All Rights Reserved.
-+ *
-+ * (As all part of the Linux kernel, this file is GPL)
-+ */
-+
-+/************************** DOCUMENTATION **************************/
-+/*
-+ * API definition :
-+ * --------------
-+ * See <linux/wireless.h> for details of the APIs and the rest.
-+ *
-+ * History :
-+ * -------
-+ *
-+ * v1 - 5.12.01 - Jean II
-+ * o Created this file.
-+ *
-+ * v2 - 13.12.01 - Jean II
-+ * o Move /proc/net/wireless stuff from net/core/dev.c to here
-+ * o Make Wireless Extension IOCTLs go through here
-+ * o Added iw_handler handling ;-)
-+ * o Added standard ioctl description
-+ * o Initial dumb commit strategy based on orinoco.c
-+ */
-+
-+/***************************** INCLUDES *****************************/
-+
-+#include <asm/uaccess.h> /* copy_to_user() */
-+#include <linux/config.h> /* Not needed ??? */
-+#include <linux/types.h> /* off_t */
-+#include <linux/netdevice.h> /* struct ifreq, dev_get_by_name() */
-+
-+#include <linux/wireless.h> /* Pretty obvious */
-+#include <net/iw_handler.h> /* New driver API */
-+
-+/**************************** CONSTANTS ****************************/
-+
-+/* This will be turned on later on... */
-+#undef WE_STRICT_WRITE /* Check write buffer size */
-+
-+/* Debuging stuff */
-+#undef WE_IOCTL_DEBUG /* Debug IOCTL API */
-+
-+/************************* GLOBAL VARIABLES *************************/
-+/*
-+ * You should not use global variables, because or re-entrancy.
-+ * On our case, it's only const, so it's OK...
-+ */
-+static const struct iw_ioctl_description standard_ioctl[] = {
-+ /* SIOCSIWCOMMIT (internal) */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCGIWNAME */
-+ { IW_HEADER_TYPE_CHAR, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWNWID */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, IW_DESCR_FLAG_EVENT},
-+ /* SIOCGIWNWID */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWFREQ */
-+ { IW_HEADER_TYPE_FREQ, 0, 0, 0, 0, IW_DESCR_FLAG_EVENT},
-+ /* SIOCGIWFREQ */
-+ { IW_HEADER_TYPE_FREQ, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWMODE */
-+ { IW_HEADER_TYPE_UINT, 0, 0, 0, 0, IW_DESCR_FLAG_EVENT},
-+ /* SIOCGIWMODE */
-+ { IW_HEADER_TYPE_UINT, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWSENS */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWSENS */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWRANGE */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCGIWRANGE */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, sizeof(struct iw_range), IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWPRIV */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCGIWPRIV (handled directly by us) */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCSIWSTATS */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCGIWSTATS (handled directly by us) */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWSPY */
-+ { IW_HEADER_TYPE_POINT, 0, sizeof(struct sockaddr), 0, IW_MAX_SPY, 0},
-+ /* SIOCGIWSPY */
-+ { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_SPY, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCSIWAP */
-+ { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
-+ /* SIOCGIWAP */
-+ { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCGIWAPLIST */
-+ { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_AP, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCSIWESSID */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, IW_DESCR_FLAG_EVENT},
-+ /* SIOCGIWESSID */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWNICKN */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, 0},
-+ /* SIOCGIWNICKN */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCSIWRATE */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWRATE */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWRTS */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWRTS */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWFRAG */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWFRAG */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWTXPOW */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWTXPOW */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWRETRY */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWRETRY */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWENCODE */
-+ { IW_HEADER_TYPE_POINT, 4, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT},
-+ /* SIOCGIWENCODE */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_DUMP | IW_DESCR_FLAG_RESTRICT},
-+ /* SIOCSIWPOWER */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWPOWER */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+};
-+
-+/* Size (in bytes) of the various private data types */
-+char priv_type_size[] = { 0, 1, 1, 0, 4, 4, 0, 0 };
-+
-+/************************ COMMON SUBROUTINES ************************/
-+/*
-+ * Stuff that may be used in various place or doesn't fit in one
-+ * of the section below.
-+ */
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Return the driver handler associated with a specific Wireless Extension.
-+ * Called from various place, so make sure it remains efficient.
-+ */
-+static inline iw_handler get_handler(struct net_device *dev,
-+ unsigned int cmd)
-+{
-+ unsigned int index; /* MUST be unsigned */
-+
-+ /* Check if we have some wireless handlers defined */
-+ if(dev->wireless_handlers == NULL)
-+ return NULL;
-+
-+ /* Try as a standard command */
-+ index = cmd - SIOCIWFIRST;
-+ if(index < dev->wireless_handlers->num_standard)
-+ return dev->wireless_handlers->standard[index];
-+
-+ /* Try as a private command */
-+ index = cmd - SIOCIWFIRSTPRIV;
-+ if(index < dev->wireless_handlers->num_private)
-+ return dev->wireless_handlers->private[index];
-+
-+ /* Not found */
-+ return NULL;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Get statistics out of the driver
-+ */
-+static inline struct iw_statistics *get_wireless_stats(struct net_device *dev)
-+{
-+ return (dev->get_wireless_stats ?
-+ dev->get_wireless_stats(dev) :
-+ (struct iw_statistics *) NULL);
-+ /* In the future, get_wireless_stats may move from 'struct net_device'
-+ * to 'struct iw_handler_def', to de-bloat struct net_device.
-+ * Definitely worse a thought... */
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Call the commit handler in the driver
-+ * (if exist and if conditions are right)
-+ *
-+ * Note : our current commit strategy is currently pretty dumb,
-+ * but we will be able to improve on that...
-+ * The goal is to try to agreagate as many changes as possible
-+ * before doing the commit. Drivers that will define a commit handler
-+ * are usually those that need a reset after changing parameters, so
-+ * we want to minimise the number of reset.
-+ * A cool idea is to use a timer : at each "set" command, we re-set the
-+ * timer, when the timer eventually fires, we call the driver.
-+ * Hopefully, more on that later.
-+ *
-+ * Also, I'm waiting to see how many people will complain about the
-+ * netif_running(dev) test. I'm open on that one...
-+ * Hopefully, the driver will remember to do a commit in "open()" ;-)
-+ */
-+static inline int call_commit_handler(struct net_device * dev)
-+{
-+ if((netif_running(dev)) &&
-+ (dev->wireless_handlers->standard[0] != NULL)) {
-+ /* Call the commit handler on the driver */
-+ return dev->wireless_handlers->standard[0](dev, NULL,
-+ NULL, NULL);
-+ } else
-+ return 0; /* Command completed successfully */
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Number of private arguments
-+ */
-+static inline int get_priv_size(__u16 args)
-+{
-+ int num = args & IW_PRIV_SIZE_MASK;
-+ int type = (args & IW_PRIV_TYPE_MASK) >> 12;
-+
-+ return num * priv_type_size[type];
-+}
-+
-+
-+/******************** /proc/net/wireless SUPPORT ********************/
-+/*
-+ * The /proc/net/wireless file is a human readable user-space interface
-+ * exporting various wireless specific statistics from the wireless devices.
-+ * This is the most popular part of the Wireless Extensions ;-)
-+ *
-+ * This interface is a pure clone of /proc/net/dev (in net/core/dev.c).
-+ * The content of the file is basically the content of "struct iw_statistics".
-+ */
-+
-+#ifdef CONFIG_PROC_FS
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Print one entry (line) of /proc/net/wireless
-+ */
-+static inline int sprintf_wireless_stats(char *buffer, struct net_device *dev)
-+{
-+ /* Get stats from the driver */
-+ struct iw_statistics *stats;
-+ int size;
-+
-+ stats = get_wireless_stats(dev);
-+ if (stats != (struct iw_statistics *) NULL) {
-+ size = sprintf(buffer,
-+ "%6s: %04x %3d%c %3d%c %3d%c %6d %6d %6d %6d %6d %6d\n",
-+ dev->name,
-+ stats->status,
-+ stats->qual.qual,
-+ stats->qual.updated & 1 ? '.' : ' ',
-+ stats->qual.level,
-+ stats->qual.updated & 2 ? '.' : ' ',
-+ stats->qual.noise,
-+ stats->qual.updated & 4 ? '.' : ' ',
-+ stats->discard.nwid,
-+ stats->discard.code,
-+ stats->discard.fragment,
-+ stats->discard.retries,
-+ stats->discard.misc,
-+ stats->miss.beacon);
-+ stats->qual.updated = 0;
-+ }
-+ else
-+ size = 0;
-+
-+ return size;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Print info for /proc/net/wireless (print all entries)
-+ */
-+int dev_get_wireless_info(char * buffer, char **start, off_t offset,
-+ int length)
-+{
-+ int len = 0;
-+ off_t begin = 0;
-+ off_t pos = 0;
-+ int size;
-+
-+ struct net_device * dev;
-+
-+ size = sprintf(buffer,
-+ "Inter-| sta-| Quality | Discarded packets | Missed\n"
-+ " face | tus | link level noise | nwid crypt frag retry misc | beacon\n"
-+ );
-+
-+ pos += size;
-+ len += size;
-+
-+ read_lock(&dev_base_lock);
-+ for (dev = dev_base; dev != NULL; dev = dev->next) {
-+ size = sprintf_wireless_stats(buffer + len, dev);
-+ len += size;
-+ pos = begin + len;
-+
-+ if (pos < offset) {
-+ len = 0;
-+ begin = pos;
-+ }
-+ if (pos > offset + length)
-+ break;
-+ }
-+ read_unlock(&dev_base_lock);
-+
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ len -= (offset - begin); /* Start slop */
-+ if (len > length)
-+ len = length; /* Ending slop */
-+ if (len < 0)
-+ len = 0;
-+
-+ return len;
-+}
-+#endif /* CONFIG_PROC_FS */
-+
-+/************************** IOCTL SUPPORT **************************/
-+/*
-+ * The original user space API to configure all those Wireless Extensions
-+ * is through IOCTLs.
-+ * In there, we check if we need to call the new driver API (iw_handler)
-+ * or just call the driver ioctl handler.
-+ */
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Allow programatic access to /proc/net/wireless even if /proc
-+ * doesn't exist... Also more efficient...
-+ */
-+static inline int dev_iwstats(struct net_device *dev, struct ifreq *ifr)
-+{
-+ /* Get stats from the driver */
-+ struct iw_statistics *stats;
-+
-+ stats = get_wireless_stats(dev);
-+ if (stats != (struct iw_statistics *) NULL) {
-+ struct iwreq * wrq = (struct iwreq *)ifr;
-+
-+ /* Copy statistics to the user buffer */
-+ if(copy_to_user(wrq->u.data.pointer, stats,
-+ sizeof(struct iw_statistics)))
-+ return -EFAULT;
-+
-+ /* Check if we need to clear the update flag */
-+ if(wrq->u.data.flags != 0)
-+ stats->qual.updated = 0;
-+ return 0;
-+ } else
-+ return -EOPNOTSUPP;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Export the driver private handler definition
-+ * They will be picked up by tools like iwpriv...
-+ */
-+static inline int ioctl_export_private(struct net_device * dev,
-+ struct ifreq * ifr)
-+{
-+ struct iwreq * iwr = (struct iwreq *) ifr;
-+
-+ /* Check if the driver has something to export */
-+ if((dev->wireless_handlers->num_private_args == 0) ||
-+ (dev->wireless_handlers->private_args == NULL))
-+ return -EOPNOTSUPP;
-+
-+ /* Check NULL pointer */
-+ if(iwr->u.data.pointer == NULL)
-+ return -EFAULT;
-+#ifdef WE_STRICT_WRITE
-+ /* Check if there is enough buffer up there */
-+ if(iwr->u.data.length < (SIOCIWLASTPRIV - SIOCIWFIRSTPRIV + 1))
-+ return -E2BIG;
-+#endif /* WE_STRICT_WRITE */
-+
-+ /* Set the number of available ioctls. */
-+ iwr->u.data.length = dev->wireless_handlers->num_private_args;
-+
-+ /* Copy structure to the user buffer. */
-+ if (copy_to_user(iwr->u.data.pointer,
-+ dev->wireless_handlers->private_args,
-+ sizeof(struct iw_priv_args) * iwr->u.data.length))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Wrapper to call a standard Wireless Extension handler.
-+ * We do various checks and also take care of moving data between
-+ * user space and kernel space.
-+ */
-+static inline int ioctl_standard_call(struct net_device * dev,
-+ struct ifreq * ifr,
-+ unsigned int cmd,
-+ iw_handler handler)
-+{
-+ struct iwreq * iwr = (struct iwreq *) ifr;
-+ const struct iw_ioctl_description * descr;
-+ struct iw_request_info info;
-+ int ret = -EINVAL;
-+
-+ /* Get the description of the IOCTL */
-+ descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
-+
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "%s : Found standard handler for 0x%04X\n",
-+ ifr->ifr_name, cmd);
-+ printk(KERN_DEBUG "Header type : %d, token type : %d, token_size : %d, max_token : %d\n", descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
-+#endif /* WE_IOCTL_DEBUG */
-+
-+ /* Prepare the call */
-+ info.cmd = cmd;
-+ info.flags = 0;
-+
-+ /* Check if we have a pointer to user space data or not */
-+ if(descr->header_type != IW_HEADER_TYPE_POINT) {
-+ /* No extra arguments. Trivial to handle */
-+ ret = handler(dev, &info, &(iwr->u), NULL);
-+ } else {
-+ char * extra;
-+ int err;
-+
-+ /* Check what user space is giving us */
-+ if(IW_IS_SET(cmd)) {
-+ /* Check NULL pointer */
-+ if((iwr->u.data.pointer == NULL) &&
-+ (iwr->u.data.length != 0))
-+ return -EFAULT;
-+ /* Check if number of token fits within bounds */
-+ if(iwr->u.data.length > descr->max_tokens)
-+ return -E2BIG;
-+ if(iwr->u.data.length < descr->min_tokens)
-+ return -EINVAL;
-+ } else {
-+ /* Check NULL pointer */
-+ if(iwr->u.data.pointer == NULL)
-+ return -EFAULT;
-+#ifdef WE_STRICT_WRITE
-+ /* Check if there is enough buffer up there */
-+ if(iwr->u.data.length < descr->max_tokens)
-+ return -E2BIG;
-+#endif /* WE_STRICT_WRITE */
-+ }
-+
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Malloc %d bytes\n",
-+ descr->max_tokens * descr->token_size);
-+#endif /* WE_IOCTL_DEBUG */
-+
-+ /* Always allocate for max space. Easier, and won't last
-+ * long... */
-+ extra = kmalloc(descr->max_tokens * descr->token_size,
-+ GFP_KERNEL);
-+ if (extra == NULL) {
-+ return -ENOMEM;
-+ }
-+
-+ /* If it is a SET, get all the extra data in here */
-+ if(IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
-+ err = copy_from_user(extra, iwr->u.data.pointer,
-+ iwr->u.data.length *
-+ descr->token_size);
-+ if (err) {
-+ kfree(extra);
-+ return -EFAULT;
-+ }
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Got %d bytes\n",
-+ iwr->u.data.length * descr->token_size);
-+#endif /* WE_IOCTL_DEBUG */
-+ }
-+
-+ /* Call the handler */
-+ ret = handler(dev, &info, &(iwr->u), extra);
-+
-+ /* If we have something to return to the user */
-+ if (!ret && IW_IS_GET(cmd)) {
-+ err = copy_to_user(iwr->u.data.pointer, extra,
-+ iwr->u.data.length *
-+ descr->token_size);
-+ if (err)
-+ ret = -EFAULT;
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Wrote %d bytes\n",
-+ iwr->u.data.length * descr->token_size);
-+#endif /* WE_IOCTL_DEBUG */
-+ }
-+
-+ /* Cleanup - I told you it wasn't that long ;-) */
-+ kfree(extra);
-+ }
-+
-+ /* Call commit handler if needed and defined */
-+ if(ret == -EIWCOMMIT)
-+ ret = call_commit_handler(dev);
-+
-+ /* Here, we will generate the appropriate event if needed */
-+
-+ return ret;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Wrapper to call a private Wireless Extension handler.
-+ * We do various checks and also take care of moving data between
-+ * user space and kernel space.
-+ * It's not as nice and slimline as the standard wrapper. The cause
-+ * is struct iw_priv_args, which was not really designed for the
-+ * job we are going here.
-+ *
-+ * IMPORTANT : This function prevent to set and get data on the same
-+ * IOCTL and enforce the SET/GET convention. Not doing it would be
-+ * far too hairy...
-+ * If you need to set and get data at the same time, please don't use
-+ * a iw_handler but process it in your ioctl handler (i.e. use the
-+ * old driver API).
-+ */
-+static inline int ioctl_private_call(struct net_device * dev,
-+ struct ifreq * ifr,
-+ unsigned int cmd,
-+ iw_handler handler)
-+{
-+ struct iwreq * iwr = (struct iwreq *) ifr;
-+ struct iw_priv_args * descr = NULL;
-+ struct iw_request_info info;
-+ int extra_size = 0;
-+ int i;
-+ int ret = -EINVAL;
-+
-+ /* Get the description of the IOCTL */
-+ for(i = 0; i < dev->wireless_handlers->num_private_args; i++)
-+ if(cmd == dev->wireless_handlers->private_args[i].cmd) {
-+ descr = &(dev->wireless_handlers->private_args[i]);
-+ break;
-+ }
-+
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "%s : Found private handler for 0x%04X\n",
-+ ifr->ifr_name, cmd);
-+ if(descr) {
-+ printk(KERN_DEBUG "Name %s, set %X, get %X\n",
-+ descr->name, descr->set_args, descr->get_args);
-+ }
-+#endif /* WE_IOCTL_DEBUG */
-+
-+ /* Compute the size of the set/get arguments */
-+ if(descr != NULL) {
-+ if(IW_IS_SET(cmd)) {
-+ /* Size of set arguments */
-+ extra_size = get_priv_size(descr->set_args);
-+
-+ /* Does it fits in iwr ? */
-+ if((descr->set_args & IW_PRIV_SIZE_FIXED) &&
-+ (extra_size < IFNAMSIZ))
-+ extra_size = 0;
-+ } else {
-+ /* Size of set arguments */
-+ extra_size = get_priv_size(descr->get_args);
-+
-+ /* Does it fits in iwr ? */
-+ if((descr->get_args & IW_PRIV_SIZE_FIXED) &&
-+ (extra_size < IFNAMSIZ))
-+ extra_size = 0;
-+ }
-+ }
-+
-+ /* Prepare the call */
-+ info.cmd = cmd;
-+ info.flags = 0;
-+
-+ /* Check if we have a pointer to user space data or not. */
-+ if(extra_size == 0) {
-+ /* No extra arguments. Trivial to handle */
-+ ret = handler(dev, &info, &(iwr->u), (char *) &(iwr->u));
-+ } else {
-+ char * extra;
-+ int err;
-+
-+ /* Check what user space is giving us */
-+ if(IW_IS_SET(cmd)) {
-+ /* Check NULL pointer */
-+ if((iwr->u.data.pointer == NULL) &&
-+ (iwr->u.data.length != 0))
-+ return -EFAULT;
-+
-+ /* Does it fits within bounds ? */
-+ if(iwr->u.data.length > (descr->set_args &
-+ IW_PRIV_SIZE_MASK))
-+ return -E2BIG;
-+ } else {
-+ /* Check NULL pointer */
-+ if(iwr->u.data.pointer == NULL)
-+ return -EFAULT;
-+ }
-+
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Malloc %d bytes\n", extra_size);
-+#endif /* WE_IOCTL_DEBUG */
-+
-+ /* Always allocate for max space. Easier, and won't last
-+ * long... */
-+ extra = kmalloc(extra_size, GFP_KERNEL);
-+ if (extra == NULL) {
-+ return -ENOMEM;
-+ }
-+
-+ /* If it is a SET, get all the extra data in here */
-+ if(IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
-+ err = copy_from_user(extra, iwr->u.data.pointer,
-+ extra_size);
-+ if (err) {
-+ kfree(extra);
-+ return -EFAULT;
-+ }
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Got %d elem\n", iwr->u.data.length);
-+#endif /* WE_IOCTL_DEBUG */
-+ }
-+
-+ /* Call the handler */
-+ ret = handler(dev, &info, &(iwr->u), extra);
-+
-+ /* If we have something to return to the user */
-+ if (!ret && IW_IS_GET(cmd)) {
-+ err = copy_to_user(iwr->u.data.pointer, extra,
-+ extra_size);
-+ if (err)
-+ ret = -EFAULT;
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Wrote %d elem\n",
-+ iwr->u.data.length);
-+#endif /* WE_IOCTL_DEBUG */
-+ }
-+
-+ /* Cleanup - I told you it wasn't that long ;-) */
-+ kfree(extra);
-+ }
-+
-+
-+ /* Call commit handler if needed and defined */
-+ if(ret == -EIWCOMMIT)
-+ ret = call_commit_handler(dev);
-+
-+ return ret;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Main IOCTl dispatcher. Called from the main networking code
-+ * (dev_ioctl() in net/core/dev.c).
-+ * Check the type of IOCTL and call the appropriate wrapper...
-+ */
-+int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd)
-+{
-+ struct net_device *dev;
-+ iw_handler handler;
-+
-+ /* Permissions are already checked in dev_ioctl() before calling us.
-+ * The copy_to/from_user() of ifr is also dealt with in there */
-+
-+ /* Make sure the device exist */
-+ if ((dev = __dev_get_by_name(ifr->ifr_name)) == NULL)
-+ return -ENODEV;
-+
-+ /* A bunch of special cases, then the generic case...
-+ * Note that 'cmd' is already filtered in dev_ioctl() with
-+ * (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) */
-+ switch(cmd)
-+ {
-+ case SIOCGIWSTATS:
-+ /* Get Wireless Stats */
-+ return dev_iwstats(dev, ifr);
-+
-+ case SIOCGIWPRIV:
-+ /* Check if we have some wireless handlers defined */
-+ if(dev->wireless_handlers != NULL) {
-+ /* We export to user space the definition of
-+ * the private handler ourselves */
-+ return ioctl_export_private(dev, ifr);
-+ }
-+ // ## Fall-through for old API ##
-+ default:
-+ /* Generic IOCTL */
-+ /* Basic check */
-+ if (!netif_device_present(dev))
-+ return -ENODEV;
-+ /* New driver API : try to find the handler */
-+ handler = get_handler(dev, cmd);
-+ if(handler != NULL) {
-+ /* Standard and private are not the same */
-+ if(cmd < SIOCIWFIRSTPRIV)
-+ return ioctl_standard_call(dev,
-+ ifr,
-+ cmd,
-+ handler);
-+ else
-+ return ioctl_private_call(dev,
-+ ifr,
-+ cmd,
-+ handler);
-+ }
-+ /* Old driver API : call driver ioctl handler */
-+ if (dev->do_ioctl) {
-+ return dev->do_ioctl(dev, ifr, cmd);
-+ }
-+ return -EOPNOTSUPP;
-+ }
-+ /* Not reached */
-+ return -EINVAL;
-+}
diff --git a/linux/montavista-sa-2.4.17-mvl21/iw_handlers.w14-5.diff b/linux/montavista-sa-2.4.17-mvl21/iw_handlers.w14-5.diff
deleted file mode 100644
index 539b160068..0000000000
--- a/linux/montavista-sa-2.4.17-mvl21/iw_handlers.w14-5.diff
+++ /dev/null
@@ -1,838 +0,0 @@
-diff -u -p -r --new-file linux/include/linux-w13/rtnetlink.h linux/include/linux/rtnetlink.h
---- linux/include/linux-w13/rtnetlink.h Thu Jun 6 14:44:08 2002
-+++ linux/include/linux/rtnetlink.h Thu Jun 6 15:47:44 2002
-@@ -440,12 +440,14 @@ enum
- #define IFLA_COST IFLA_COST
- IFLA_PRIORITY,
- #define IFLA_PRIORITY IFLA_PRIORITY
-- IFLA_MASTER
-+ IFLA_MASTER,
- #define IFLA_MASTER IFLA_MASTER
-+ IFLA_WIRELESS, /* Wireless Extension event - see wireless.h */
-+#define IFLA_WIRELESS IFLA_WIRELESS
- };
-
-
--#define IFLA_MAX IFLA_MASTER
-+#define IFLA_MAX IFLA_WIRELESS
-
- #define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
- #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
-diff -u -p -r --new-file linux/include/linux-w13/wireless.h linux/include/linux/wireless.h
---- linux/include/linux-w13/wireless.h Thu Jun 6 15:00:28 2002
-+++ linux/include/linux/wireless.h Thu Jun 6 15:47:44 2002
-@@ -1,10 +1,10 @@
- /*
- * This file define a set of standard wireless extensions
- *
-- * Version : 13 6.12.01
-+ * Version : 14 25.1.02
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-- * Copyright (c) 1997-2001 Jean Tourrilhes, All Rights Reserved.
-+ * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
- */
-
- #ifndef _LINUX_WIRELESS_H
-@@ -40,7 +40,7 @@
- * # include/linux/netdevice.h (one place)
- * # include/linux/proc_fs.h (one place)
- *
-- * New driver API (2001 -> onward) :
-+ * New driver API (2002 -> onward) :
- * -------------------------------
- * This file is only concerned with the user space API and common definitions.
- * The new driver API is defined and documented in :
-@@ -49,6 +49,11 @@
- * Note as well that /proc/net/wireless implementation has now moved in :
- * # include/linux/wireless.c
- *
-+ * Wireless Events (2002 -> onward) :
-+ * --------------------------------
-+ * Events are defined at the end of this file, and implemented in :
-+ * # include/linux/wireless.c
-+ *
- * Other comments :
- * --------------
- * Do not add here things that are redundant with other mechanisms
-@@ -75,7 +80,7 @@
- * (there is some stuff that will be added in the future...)
- * I just plan to increment with each new version.
- */
--#define WIRELESS_EXT 13
-+#define WIRELESS_EXT 14
-
- /*
- * Changes :
-@@ -141,6 +146,13 @@
- * - Document creation of new driver API.
- * - Extract union iwreq_data from struct iwreq (for new driver API).
- * - Rename SIOCSIWNAME as SIOCSIWCOMMIT
-+ *
-+ * V13 to V14
-+ * ----------
-+ * - Wireless Events support : define struct iw_event
-+ * - Define additional specific event numbers
-+ * - Add "addr" and "param" fields in union iwreq_data
-+ * - AP scanning stuff (SIOCSIWSCAN and friends)
- */
-
- /**************************** CONSTANTS ****************************/
-@@ -175,6 +187,8 @@
- #define SIOCSIWAP 0x8B14 /* set access point MAC addresses */
- #define SIOCGIWAP 0x8B15 /* get access point MAC addresses */
- #define SIOCGIWAPLIST 0x8B17 /* get list of access point in range */
-+#define SIOCSIWSCAN 0x8B18 /* trigger scanning */
-+#define SIOCGIWSCAN 0x8B19 /* get scanning results */
-
- /* 802.11 specific support */
- #define SIOCSIWESSID 0x8B1A /* set ESSID (network name) */
-@@ -238,6 +252,15 @@
- #define IW_IS_SET(cmd) (!((cmd) & 0x1))
- #define IW_IS_GET(cmd) ((cmd) & 0x1)
-
-+/* ----------------------- WIRELESS EVENTS ----------------------- */
-+/* Those are *NOT* ioctls, do not issue request on them !!! */
-+/* Most events use the same identifier as ioctl requests */
-+
-+#define IWEVTXDROP 0x8C00 /* Packet dropped to excessive retry */
-+#define IWEVQUAL 0x8C01 /* Quality part of statistics */
-+
-+#define IWEVFIRST 0x8C00
-+
- /* ------------------------- PRIVATE INFO ------------------------- */
- /*
- * The following is used with SIOCGIWPRIV. It allow a driver to define
-@@ -340,6 +363,19 @@
- #define IW_RETRY_MAX 0x0002 /* Value is a maximum */
- #define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
-
-+/* Scanning request flags */
-+#define IW_SCAN_DEFAULT 0x0000 /* Default scan of the driver */
-+#define IW_SCAN_ALL_ESSID 0x0001 /* Scan all ESSIDs */
-+#define IW_SCAN_THIS_ESSID 0x0002 /* Scan only this ESSID */
-+#define IW_SCAN_ALL_FREQ 0x0004 /* Scan all Frequencies */
-+#define IW_SCAN_THIS_FREQ 0x0008 /* Scan only this Frequency */
-+#define IW_SCAN_ALL_MODE 0x0010 /* Scan all Modes */
-+#define IW_SCAN_THIS_MODE 0x0020 /* Scan only this Mode */
-+#define IW_SCAN_ALL_RATE 0x0040 /* Scan all Bit-Rates */
-+#define IW_SCAN_THIS_RATE 0x0080 /* Scan only this Bit-Rate */
-+/* Maximum size of returned data */
-+#define IW_SCAN_MAX_DATA 4096 /* In bytes */
-+
- /****************************** TYPES ******************************/
-
- /* --------------------------- SUBTYPES --------------------------- */
-@@ -466,9 +502,12 @@ union iwreq_data
-
- struct iw_point encoding; /* Encoding stuff : tokens */
- struct iw_param power; /* PM duration/timeout */
-+ struct iw_quality qual; /* Quality part of statistics */
-
- struct sockaddr ap_addr; /* Access point address */
-+ struct sockaddr addr; /* Destination address (hw) */
-
-+ struct iw_param param; /* Other small parameters */
- struct iw_point data; /* Other large parameters */
- };
-
-@@ -595,5 +634,36 @@ struct iw_priv_args
- __u16 get_args; /* Type and number of args */
- char name[IFNAMSIZ]; /* Name of the extension */
- };
-+
-+/* ----------------------- WIRELESS EVENTS ----------------------- */
-+/*
-+ * Wireless events are carried through the rtnetlink socket to user
-+ * space. They are encapsulated in the IFLA_WIRELESS field of
-+ * a RTM_NEWLINK message.
-+ */
-+
-+/*
-+ * A Wireless Event. Contains basically the same data as the ioctl...
-+ */
-+struct iw_event
-+{
-+ __u16 len; /* Real lenght of this stuff */
-+ __u16 cmd; /* Wireless IOCTL */
-+ union iwreq_data u; /* IOCTL fixed payload */
-+};
-+
-+/* Size of the Event prefix (including padding and alignement junk) */
-+#define IW_EV_LCP_LEN (sizeof(struct iw_event) - sizeof(union iwreq_data))
-+/* Size of the various events */
-+#define IW_EV_CHAR_LEN (IW_EV_LCP_LEN + IFNAMSIZ)
-+#define IW_EV_UINT_LEN (IW_EV_LCP_LEN + sizeof(__u32))
-+#define IW_EV_FREQ_LEN (IW_EV_LCP_LEN + sizeof(struct iw_freq))
-+#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point))
-+#define IW_EV_PARAM_LEN (IW_EV_LCP_LEN + sizeof(struct iw_param))
-+#define IW_EV_ADDR_LEN (IW_EV_LCP_LEN + sizeof(struct sockaddr))
-+#define IW_EV_QUAL_LEN (IW_EV_LCP_LEN + sizeof(struct iw_quality))
-+
-+/* Note : in the case of iw_point, the extra data will come at the
-+ * end of the event */
-
- #endif /* _LINUX_WIRELESS_H */
-diff -u -p -r --new-file linux/include/net-w13/iw_handler.h linux/include/net/iw_handler.h
---- linux/include/net-w13/iw_handler.h Thu Jun 6 15:06:16 2002
-+++ linux/include/net/iw_handler.h Thu Jun 6 15:48:06 2002
-@@ -1,10 +1,10 @@
- /*
- * This file define the new driver API for Wireless Extensions
- *
-- * Version : 2 6.12.01
-+ * Version : 3 17.1.02
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-- * Copyright (c) 2001 Jean Tourrilhes, All Rights Reserved.
-+ * Copyright (c) 2001-2002 Jean Tourrilhes, All Rights Reserved.
- */
-
- #ifndef _IW_HANDLER_H
-@@ -33,7 +33,7 @@
- * o The user space interface is tied to ioctl because of the use
- * copy_to/from_user.
- *
-- * New driver API (2001 -> onward) :
-+ * New driver API (2002 -> onward) :
- * -------------------------------
- * The new driver API is just a bunch of standard functions (handlers),
- * each handling a specific Wireless Extension. The driver just export
-@@ -206,7 +206,18 @@
- * will be needed...
- * I just plan to increment with each new version.
- */
--#define IW_HANDLER_VERSION 2
-+#define IW_HANDLER_VERSION 3
-+
-+/*
-+ * Changes :
-+ *
-+ * V2 to V3
-+ * --------
-+ * - Move event definition in <linux/wireless.h>
-+ * - Add Wireless Event support :
-+ * o wireless_send_event() prototype
-+ * o iwe_stream_add_event/point() inline functions
-+ */
-
- /**************************** CONSTANTS ****************************/
-
-@@ -225,6 +236,7 @@
- #define IW_HEADER_TYPE_POINT 6 /* struct iw_point */
- #define IW_HEADER_TYPE_PARAM 7 /* struct iw_param */
- #define IW_HEADER_TYPE_ADDR 8 /* struct sockaddr */
-+#define IW_HEADER_TYPE_QUAL 9 /* struct iw_quality */
-
- /* Handling flags */
- /* Most are not implemented. I just use them as a reminder of some
-@@ -233,7 +245,8 @@
- /* Wrapper level flags */
- #define IW_DESCR_FLAG_DUMP 0x0001 /* Not part of the dump command */
- #define IW_DESCR_FLAG_EVENT 0x0002 /* Generate an event on SET */
--#define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET request is ROOT only */
-+#define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET : request is ROOT only */
-+ /* SET : Omit payload from generated iwevent */
- /* Driver level flags */
- #define IW_DESCR_FLAG_WAIT 0x0100 /* Wait for driver event */
-
-@@ -303,25 +316,6 @@ struct iw_handler_def
- * 'struct net_device' to here, to minimise bloat. */
- };
-
--/* ----------------------- WIRELESS EVENTS ----------------------- */
--/*
-- * Currently we don't support events, so let's just plan for the
-- * future...
-- */
--
--/*
-- * A Wireless Event.
-- */
--// How do we define short header ? We don't want a flag on length.
--// Probably a flag on event ? Highest bit to zero...
--struct iw_event
--{
-- __u16 length; /* Lenght of this stuff */
-- __u16 event; /* Wireless IOCTL */
-- union iwreq_data header; /* IOCTL fixed payload */
-- char extra[0]; /* Optional IOCTL data */
--};
--
- /* ---------------------- IOCTL DESCRIPTION ---------------------- */
- /*
- * One of the main goal of the new interface is to deal entirely with
-@@ -369,6 +363,88 @@ extern int dev_get_wireless_info(char *
- extern int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd);
-
- /* Second : functions that may be called by driver modules */
--/* None yet */
-
--#endif /* _LINUX_WIRELESS_H */
-+/* Send a single event to user space */
-+extern void wireless_send_event(struct net_device * dev,
-+ unsigned int cmd,
-+ union iwreq_data * wrqu,
-+ char * extra);
-+
-+/* We may need a function to send a stream of events to user space.
-+ * More on that later... */
-+
-+/************************* INLINE FUNTIONS *************************/
-+/*
-+ * Function that are so simple that it's more efficient inlining them
-+ */
-+
-+/*------------------------------------------------------------------*/
-+/*
-+ * Wrapper to add an Wireless Event to a stream of events.
-+ */
-+static inline char *
-+iwe_stream_add_event(char * stream, /* Stream of events */
-+ char * ends, /* End of stream */
-+ struct iw_event *iwe, /* Payload */
-+ int event_len) /* Real size of payload */
-+{
-+ /* Check if it's possible */
-+ if((stream + event_len) < ends) {
-+ iwe->len = event_len;
-+ memcpy(stream, (char *) iwe, event_len);
-+ stream += event_len;
-+ }
-+ return stream;
-+}
-+
-+/*------------------------------------------------------------------*/
-+/*
-+ * Wrapper to add an short Wireless Event containing a pointer to a
-+ * stream of events.
-+ */
-+static inline char *
-+iwe_stream_add_point(char * stream, /* Stream of events */
-+ char * ends, /* End of stream */
-+ struct iw_event *iwe, /* Payload */
-+ char * extra)
-+{
-+ int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
-+ /* Check if it's possible */
-+ if((stream + event_len) < ends) {
-+ iwe->len = event_len;
-+ memcpy(stream, (char *) iwe, IW_EV_POINT_LEN);
-+ memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
-+ stream += event_len;
-+ }
-+ return stream;
-+}
-+
-+/*------------------------------------------------------------------*/
-+/*
-+ * Wrapper to add a value to a Wireless Event in a stream of events.
-+ * Be careful, this one is tricky to use properly :
-+ * At the first run, you need to have (value = event + IW_EV_LCP_LEN).
-+ */
-+static inline char *
-+iwe_stream_add_value(char * event, /* Event in the stream */
-+ char * value, /* Value in event */
-+ char * ends, /* End of stream */
-+ struct iw_event *iwe, /* Payload */
-+ int event_len) /* Real size of payload */
-+{
-+ /* Don't duplicate LCP */
-+ event_len -= IW_EV_LCP_LEN;
-+
-+ /* Check if it's possible */
-+ if((value + event_len) < ends) {
-+ /* Add new value */
-+ memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
-+ value += event_len;
-+ /* Patch LCP */
-+ iwe->len = value - event;
-+ memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
-+ }
-+ return value;
-+}
-+
-+#endif /* _IW_HANDLER_H */
-diff -u -p -r --new-file linux/net/netsyms-w13.c linux/net/netsyms.c
---- linux/net/netsyms-w13.c Thu Jun 6 15:46:34 2002
-+++ linux/net/netsyms.c Thu Jun 6 15:47:44 2002
-@@ -588,4 +588,10 @@ EXPORT_SYMBOL(register_gifconf);
- EXPORT_SYMBOL(net_call_rx_atomic);
- EXPORT_SYMBOL(softnet_data);
-
-+#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
-+/* Don't include the whole header mess for a single function */
-+extern void wireless_send_event(struct net_device *dev, unsigned int cmd, union iwreq_data *wrqu, char *extra);
-+EXPORT_SYMBOL(wireless_send_event);
-+#endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
-+
- #endif /* CONFIG_NET */
-diff -u -p -r --new-file linux/net/core/wireless-w13.c linux/net/core/wireless.c
---- linux/net/core/wireless-w13.c Thu Jun 6 15:46:45 2002
-+++ linux/net/core/wireless.c Thu Jun 6 15:48:06 2002
-@@ -2,7 +2,7 @@
- * This file implement the Wireless Extensions APIs.
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-- * Copyright (c) 1997-2001 Jean Tourrilhes, All Rights Reserved.
-+ * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
- *
- * (As all part of the Linux kernel, this file is GPL)
- */
-@@ -25,6 +25,16 @@
- * o Added iw_handler handling ;-)
- * o Added standard ioctl description
- * o Initial dumb commit strategy based on orinoco.c
-+ *
-+ * v3 - 19.12.01 - Jean II
-+ * o Make sure we don't go out of standard_ioctl[] in ioctl_standard_call
-+ * o Add event dispatcher function
-+ * o Add event description
-+ * o Propagate events as rtnetlink IFLA_WIRELESS option
-+ * o Generate event on selected SET requests
-+ *
-+ * v4 - 18.04.01 - Jean II
-+ * o Fix stupid off by one in iw_ioctl_description : IW_ESSID_MAX_SIZE + 1
- */
-
- /***************************** INCLUDES *****************************/
-@@ -33,6 +43,7 @@
- #include <linux/config.h> /* Not needed ??? */
- #include <linux/types.h> /* off_t */
- #include <linux/netdevice.h> /* struct ifreq, dev_get_by_name() */
-+#include <linux/rtnetlink.h> /* rtnetlink stuff */
-
- #include <linux/wireless.h> /* Pretty obvious */
- #include <net/iw_handler.h> /* New driver API */
-@@ -44,14 +55,23 @@
-
- /* Debuging stuff */
- #undef WE_IOCTL_DEBUG /* Debug IOCTL API */
-+#undef WE_EVENT_DEBUG /* Debug Event dispatcher */
-+
-+/* Options */
-+#define WE_EVENT_NETLINK /* Propagate events using rtnetlink */
-+#define WE_SET_EVENT /* Generate an event on some set commands */
-
- /************************* GLOBAL VARIABLES *************************/
- /*
- * You should not use global variables, because or re-entrancy.
- * On our case, it's only const, so it's OK...
- */
-+/*
-+ * Meta-data about all the standard Wireless Extension request we
-+ * know about.
-+ */
- static const struct iw_ioctl_description standard_ioctl[] = {
-- /* SIOCSIWCOMMIT (internal) */
-+ /* SIOCSIWCOMMIT */
- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
- /* SIOCGIWNAME */
- { IW_HEADER_TYPE_CHAR, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-@@ -99,18 +119,18 @@ static const struct iw_ioctl_description
- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
- /* SIOCGIWAPLIST */
- { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_AP, 0},
-- /* -- hole -- */
-- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-- /* -- hole -- */
-- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCSIWSCAN */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWSCAN */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_SCAN_MAX_DATA, 0},
- /* SIOCSIWESSID */
-- { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, IW_DESCR_FLAG_EVENT},
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, IW_DESCR_FLAG_EVENT},
- /* SIOCGIWESSID */
-- { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, IW_DESCR_FLAG_DUMP},
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, IW_DESCR_FLAG_DUMP},
- /* SIOCSIWNICKN */
-- { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, 0},
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, 0},
- /* SIOCGIWNICKN */
-- { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, 0},
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, 0},
- /* -- hole -- */
- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
- /* -- hole -- */
-@@ -136,7 +156,7 @@ static const struct iw_ioctl_description
- /* SIOCGIWRETRY */
- { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
- /* SIOCSIWENCODE */
-- { IW_HEADER_TYPE_POINT, 4, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT},
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT},
- /* SIOCGIWENCODE */
- { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_DUMP | IW_DESCR_FLAG_RESTRICT},
- /* SIOCSIWPOWER */
-@@ -144,9 +164,38 @@ static const struct iw_ioctl_description
- /* SIOCGIWPOWER */
- { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
- };
-+static const int standard_ioctl_num = (sizeof(standard_ioctl) /
-+ sizeof(struct iw_ioctl_description));
-+
-+/*
-+ * Meta-data about all the additional standard Wireless Extension events
-+ * we know about.
-+ */
-+static const struct iw_ioctl_description standard_event[] = {
-+ /* IWEVTXDROP */
-+ { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
-+ /* IWEVQUAL */
-+ { IW_HEADER_TYPE_QUAL, 0, 0, 0, 0, 0},
-+};
-+static const int standard_event_num = (sizeof(standard_event) /
-+ sizeof(struct iw_ioctl_description));
-
- /* Size (in bytes) of the various private data types */
--char priv_type_size[] = { 0, 1, 1, 0, 4, 4, 0, 0 };
-+static const char priv_type_size[] = { 0, 1, 1, 0, 4, 4, 0, 0 };
-+
-+/* Size (in bytes) of various events */
-+static const int event_type_size[] = {
-+ IW_EV_LCP_LEN,
-+ 0,
-+ IW_EV_CHAR_LEN,
-+ 0,
-+ IW_EV_UINT_LEN,
-+ IW_EV_FREQ_LEN,
-+ IW_EV_POINT_LEN, /* Without variable payload */
-+ IW_EV_PARAM_LEN,
-+ IW_EV_ADDR_LEN,
-+ IW_EV_QUAL_LEN,
-+};
-
- /************************ COMMON SUBROUTINES ************************/
- /*
-@@ -162,7 +211,8 @@ char priv_type_size[] = { 0, 1, 1, 0, 4,
- static inline iw_handler get_handler(struct net_device *dev,
- unsigned int cmd)
- {
-- unsigned int index; /* MUST be unsigned */
-+ /* Don't "optimise" the following variable, it will crash */
-+ unsigned int index; /* *MUST* be unsigned */
-
- /* Check if we have some wireless handlers defined */
- if(dev->wireless_handlers == NULL)
-@@ -269,9 +319,9 @@ static inline int sprintf_wireless_stats
- stats->status,
- stats->qual.qual,
- stats->qual.updated & 1 ? '.' : ' ',
-- stats->qual.level,
-+ ((__u8) stats->qual.level),
- stats->qual.updated & 2 ? '.' : ' ',
-- stats->qual.noise,
-+ ((__u8) stats->qual.noise),
- stats->qual.updated & 4 ? '.' : ' ',
- stats->discard.nwid,
- stats->discard.code,
-@@ -423,12 +473,14 @@ static inline int ioctl_standard_call(st
- int ret = -EINVAL;
-
- /* Get the description of the IOCTL */
-+ if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
-+ return -EOPNOTSUPP;
- descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
-
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "%s : Found standard handler for 0x%04X\n",
-+ printk(KERN_DEBUG "%s (WE) : Found standard handler for 0x%04X\n",
- ifr->ifr_name, cmd);
-- printk(KERN_DEBUG "Header type : %d, token type : %d, token_size : %d, max_token : %d\n", descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
-+ printk(KERN_DEBUG "%s (WE) : Header type : %d, Token type : %d, size : %d, token : %d\n", dev->name, descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
- #endif /* WE_IOCTL_DEBUG */
-
- /* Prepare the call */
-@@ -437,8 +489,16 @@ static inline int ioctl_standard_call(st
-
- /* Check if we have a pointer to user space data or not */
- if(descr->header_type != IW_HEADER_TYPE_POINT) {
-+
- /* No extra arguments. Trivial to handle */
- ret = handler(dev, &info, &(iwr->u), NULL);
-+
-+#ifdef WE_SET_EVENT
-+ /* Generate an event to notify listeners of the change */
-+ if((descr->flags & IW_DESCR_FLAG_EVENT) &&
-+ ((ret == 0) || (ret == -EIWCOMMIT)))
-+ wireless_send_event(dev, cmd, &(iwr->u), NULL);
-+#endif /* WE_SET_EVENT */
- } else {
- char * extra;
- int err;
-@@ -466,8 +526,8 @@ static inline int ioctl_standard_call(st
- }
-
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Malloc %d bytes\n",
-- descr->max_tokens * descr->token_size);
-+ printk(KERN_DEBUG "%s (WE) : Malloc %d bytes\n",
-+ dev->name, descr->max_tokens * descr->token_size);
- #endif /* WE_IOCTL_DEBUG */
-
- /* Always allocate for max space. Easier, and won't last
-@@ -488,7 +548,8 @@ static inline int ioctl_standard_call(st
- return -EFAULT;
- }
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Got %d bytes\n",
-+ printk(KERN_DEBUG "%s (WE) : Got %d bytes\n",
-+ dev->name,
- iwr->u.data.length * descr->token_size);
- #endif /* WE_IOCTL_DEBUG */
- }
-@@ -504,11 +565,26 @@ static inline int ioctl_standard_call(st
- if (err)
- ret = -EFAULT;
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Wrote %d bytes\n",
-+ printk(KERN_DEBUG "%s (WE) : Wrote %d bytes\n",
-+ dev->name,
- iwr->u.data.length * descr->token_size);
- #endif /* WE_IOCTL_DEBUG */
- }
-
-+#ifdef WE_SET_EVENT
-+ /* Generate an event to notify listeners of the change */
-+ if((descr->flags & IW_DESCR_FLAG_EVENT) &&
-+ ((ret == 0) || (ret == -EIWCOMMIT))) {
-+ if(descr->flags & IW_DESCR_FLAG_RESTRICT)
-+ /* If the event is restricted, don't
-+ * export the payload */
-+ wireless_send_event(dev, cmd, &(iwr->u), NULL);
-+ else
-+ wireless_send_event(dev, cmd, &(iwr->u),
-+ extra);
-+ }
-+#endif /* WE_SET_EVENT */
-+
- /* Cleanup - I told you it wasn't that long ;-) */
- kfree(extra);
- }
-@@ -558,11 +634,12 @@ static inline int ioctl_private_call(str
- }
-
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "%s : Found private handler for 0x%04X\n",
-+ printk(KERN_DEBUG "%s (WE) : Found private handler for 0x%04X\n",
- ifr->ifr_name, cmd);
- if(descr) {
-- printk(KERN_DEBUG "Name %s, set %X, get %X\n",
-- descr->name, descr->set_args, descr->get_args);
-+ printk(KERN_DEBUG "%s (WE) : Name %s, set %X, get %X\n",
-+ dev->name, descr->name,
-+ descr->set_args, descr->get_args);
- }
- #endif /* WE_IOCTL_DEBUG */
-
-@@ -617,7 +694,8 @@ static inline int ioctl_private_call(str
- }
-
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Malloc %d bytes\n", extra_size);
-+ printk(KERN_DEBUG "%s (WE) : Malloc %d bytes\n",
-+ dev->name, extra_size);
- #endif /* WE_IOCTL_DEBUG */
-
- /* Always allocate for max space. Easier, and won't last
-@@ -636,7 +714,8 @@ static inline int ioctl_private_call(str
- return -EFAULT;
- }
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Got %d elem\n", iwr->u.data.length);
-+ printk(KERN_DEBUG "%s (WE) : Got %d elem\n",
-+ dev->name, iwr->u.data.length);
- #endif /* WE_IOCTL_DEBUG */
- }
-
-@@ -650,8 +729,8 @@ static inline int ioctl_private_call(str
- if (err)
- ret = -EFAULT;
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Wrote %d elem\n",
-- iwr->u.data.length);
-+ printk(KERN_DEBUG "%s (WE) : Wrote %d elem\n",
-+ dev->name, iwr->u.data.length);
- #endif /* WE_IOCTL_DEBUG */
- }
-
-@@ -730,4 +809,178 @@ int wireless_process_ioctl(struct ifreq
- }
- /* Not reached */
- return -EINVAL;
-+}
-+
-+/************************* EVENT PROCESSING *************************/
-+/*
-+ * Process events generated by the wireless layer or the driver.
-+ * Most often, the event will be propagated through rtnetlink
-+ */
-+
-+#ifdef WE_EVENT_NETLINK
-+/* "rtnl" is defined in net/core/rtnetlink.c, but we need it here.
-+ * It is declared in <linux/rtnetlink.h> */
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Fill a rtnetlink message with our event data.
-+ * Note that we propage only the specified event and don't dump the
-+ * current wireless config. Dumping the wireless config is far too
-+ * expensive (for each parameter, the driver need to query the hardware).
-+ */
-+static inline int rtnetlink_fill_iwinfo(struct sk_buff * skb,
-+ struct net_device * dev,
-+ int type,
-+ char * event,
-+ int event_len)
-+{
-+ struct ifinfomsg *r;
-+ struct nlmsghdr *nlh;
-+ unsigned char *b = skb->tail;
-+
-+ nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(*r));
-+ r = NLMSG_DATA(nlh);
-+ r->ifi_family = AF_UNSPEC;
-+ r->ifi_type = dev->type;
-+ r->ifi_index = dev->ifindex;
-+ r->ifi_flags = dev->flags;
-+ r->ifi_change = 0; /* Wireless changes don't affect those flags */
-+
-+ /* Add the wireless events in the netlink packet */
-+ RTA_PUT(skb, IFLA_WIRELESS,
-+ event_len, event);
-+
-+ nlh->nlmsg_len = skb->tail - b;
-+ return skb->len;
-+
-+nlmsg_failure:
-+rtattr_failure:
-+ skb_trim(skb, b - skb->data);
-+ return -1;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Create and broadcast and send it on the standard rtnetlink socket
-+ * This is a pure clone rtmsg_ifinfo() in net/core/rtnetlink.c
-+ * Andrzej Krzysztofowicz mandated that I used a IFLA_XXX field
-+ * within a RTM_NEWLINK event.
-+ */
-+static inline void rtmsg_iwinfo(struct net_device * dev,
-+ char * event,
-+ int event_len)
-+{
-+ struct sk_buff *skb;
-+ int size = NLMSG_GOODSIZE;
-+
-+ skb = alloc_skb(size, GFP_ATOMIC);
-+ if (!skb)
-+ return;
-+
-+ if (rtnetlink_fill_iwinfo(skb, dev, RTM_NEWLINK,
-+ event, event_len) < 0) {
-+ kfree_skb(skb);
-+ return;
-+ }
-+ NETLINK_CB(skb).dst_groups = RTMGRP_LINK;
-+ netlink_broadcast(rtnl, skb, 0, RTMGRP_LINK, GFP_ATOMIC);
-+}
-+#endif /* WE_EVENT_NETLINK */
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Main event dispatcher. Called from other parts and drivers.
-+ * Send the event on the apropriate channels.
-+ * May be called from interrupt context.
-+ */
-+void wireless_send_event(struct net_device * dev,
-+ unsigned int cmd,
-+ union iwreq_data * wrqu,
-+ char * extra)
-+{
-+ const struct iw_ioctl_description * descr = NULL;
-+ int extra_len = 0;
-+ struct iw_event *event; /* Mallocated whole event */
-+ int event_len; /* Its size */
-+ int hdr_len; /* Size of the event header */
-+ /* Don't "optimise" the following variable, it will crash */
-+ unsigned cmd_index; /* *MUST* be unsigned */
-+
-+ /* Get the description of the IOCTL */
-+ if(cmd <= SIOCIWLAST) {
-+ cmd_index = cmd - SIOCIWFIRST;
-+ if(cmd_index < standard_ioctl_num)
-+ descr = &(standard_ioctl[cmd_index]);
-+ } else {
-+ cmd_index = cmd - IWEVFIRST;
-+ if(cmd_index < standard_event_num)
-+ descr = &(standard_event[cmd_index]);
-+ }
-+ /* Don't accept unknown events */
-+ if(descr == NULL) {
-+ /* Note : we don't return an error to the driver, because
-+ * the driver would not know what to do about it. It can't
-+ * return an error to the user, because the event is not
-+ * initiated by a user request.
-+ * The best the driver could do is to log an error message.
-+ * We will do it ourselves instead...
-+ */
-+ printk(KERN_ERR "%s (WE) : Invalid Wireless Event (0x%04X)\n",
-+ dev->name, cmd);
-+ return;
-+ }
-+#ifdef WE_EVENT_DEBUG
-+ printk(KERN_DEBUG "%s (WE) : Got event 0x%04X\n",
-+ dev->name, cmd);
-+ printk(KERN_DEBUG "%s (WE) : Header type : %d, Token type : %d, size : %d, token : %d\n", dev->name, descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
-+#endif /* WE_EVENT_DEBUG */
-+
-+ /* Check extra parameters and set extra_len */
-+ if(descr->header_type == IW_HEADER_TYPE_POINT) {
-+ /* Check if number of token fits within bounds */
-+ if(wrqu->data.length > descr->max_tokens) {
-+ printk(KERN_ERR "%s (WE) : Wireless Event too big (%d)\n", dev->name, wrqu->data.length);
-+ return;
-+ }
-+ if(wrqu->data.length < descr->min_tokens) {
-+ printk(KERN_ERR "%s (WE) : Wireless Event too small (%d)\n", dev->name, wrqu->data.length);
-+ return;
-+ }
-+ /* Calculate extra_len - extra is NULL for restricted events */
-+ if(extra != NULL)
-+ extra_len = wrqu->data.length * descr->token_size;
-+#ifdef WE_EVENT_DEBUG
-+ printk(KERN_DEBUG "%s (WE) : Event 0x%04X, tokens %d, extra_len %d\n", dev->name, cmd, wrqu->data.length, extra_len);
-+#endif /* WE_EVENT_DEBUG */
-+ }
-+
-+ /* Total length of the event */
-+ hdr_len = event_type_size[descr->header_type];
-+ event_len = hdr_len + extra_len;
-+
-+#ifdef WE_EVENT_DEBUG
-+ printk(KERN_DEBUG "%s (WE) : Event 0x%04X, hdr_len %d, event_len %d\n", dev->name, cmd, hdr_len, event_len);
-+#endif /* WE_EVENT_DEBUG */
-+
-+ /* Create temporary buffer to hold the event */
-+ event = kmalloc(event_len, GFP_ATOMIC);
-+ if(event == NULL)
-+ return;
-+
-+ /* Fill event */
-+ event->len = event_len;
-+ event->cmd = cmd;
-+ memcpy(&event->u, wrqu, hdr_len - IW_EV_LCP_LEN);
-+ if(extra != NULL)
-+ memcpy(((char *) event) + hdr_len, extra, extra_len);
-+
-+#ifdef WE_EVENT_NETLINK
-+ /* rtnetlink event channel */
-+ rtmsg_iwinfo(dev, (char *) event, event_len);
-+#endif /* WE_EVENT_NETLINK */
-+
-+ /* Cleanup */
-+ kfree(event);
-+
-+ return; /* Always success, I guess ;-) */
- }
diff --git a/linux/montavista-sa-2.4.17-mvl21/machine_name.patch b/linux/montavista-sa-2.4.17-mvl21/machine_name.patch
deleted file mode 100644
index 8b7ad2b143..0000000000
--- a/linux/montavista-sa-2.4.17-mvl21/machine_name.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-Change the Name showed by /proc/cpuinfo
-
-
-
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- linux-2.4.17_mvl21/arch/arm/mach-sa1100/assabet.c~machine_name
-+++ linux-2.4.17_mvl21/arch/arm/mach-sa1100/assabet.c
-@@ -374,7 +374,7 @@
- }
-
-
--MACHINE_START(ASSABET, "Intel-Assabet")
-+MACHINE_START(ASSABET, "Tradesquare.NL Tuxpad 1")
- BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
- BOOT_PARAMS(0xc0000100)
- FIXUP(fixup_assabet)
diff --git a/linux/montavista-sa-2.4.17-mvl21/mkdep.patch b/linux/montavista-sa-2.4.17-mvl21/mkdep.patch
deleted file mode 100644
index 4daeaa11be..0000000000
--- a/linux/montavista-sa-2.4.17-mvl21/mkdep.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-
-#
-# Made by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux/Makefile~mkdep 2003-12-19 09:36:51.000000000 -0800
-+++ linux/Makefile 2003-12-19 09:57:44.000000000 -0800
-@@ -458,7 +458,7 @@
-
- dep-files: scripts/mkdep archdep include/linux/version.h
- scripts/mkdep -- init/*.c > .depend
-- scripts/mkdep -- `find $(FINDHPATH) -name SCCS -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend
-+ $(foreach, dir, $(FINDHPATH), scripts/mkdep -- `find $(dir) -name SCCS -prune -o -follow -name \*.h ! -name modversions.h -print` >> .hdepend)
- $(MAKE) $(patsubst %,_sfdep_%,$(SUBDIRS)) _FASTDEP_ALL_SUB_DIRS="$(SUBDIRS)"
- ifdef CONFIG_MODVERSIONS
- $(MAKE) update-modverfile
diff --git a/linux/montavista-sa-2.4.17-mvl21/opie-logo.patch b/linux/montavista-sa-2.4.17-mvl21/opie-logo.patch
deleted file mode 100644
index f19cd8c0af..0000000000
--- a/linux/montavista-sa-2.4.17-mvl21/opie-logo.patch
+++ /dev/null
@@ -1,10936 +0,0 @@
-
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- linux-2.4.17_mvl21/include/linux/linux_logo.h~opie-logo.patch
-+++ linux-2.4.17_mvl21/include/linux/linux_logo.h
-@@ -1,25 +1,12 @@
--/* $Id$
-+/*
- * include/linux/linux_logo.h: This is a linux logo
- * to be displayed on boot.
- *
-- * Copyright (C) 1996 Larry Ewing (lewing@isc.tamu.edu)
-- * Copyright (C) 1996,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
-- *
-- * You can put anything here, but:
-- * LINUX_LOGO_COLORS has to be less than 224
-- * image size has to be 80x80
-- * values have to start from 0x20
-- * (i.e. RGB(linux_logo_red[0],
-- * linux_logo_green[0],
-- * linux_logo_blue[0]) is color 0x20)
-- * BW image has to be 80x80 as well, with MS bit
-- * on the left
-- * Serial_console ascii image can be any size,
-- * but should contain %s to display the version
-+ * This file has been generated. Do not edit.
- */
-
- #ifndef __HAVE_ARCH_LINUX_LOGO
--#define LINUX_LOGO_COLORS 214
-+#define LINUX_LOGO_COLORS 224
- #endif
-
- #ifdef INCLUDE_LINUX_LOGO_DATA
-@@ -27,646 +14,10208 @@
- #ifndef __HAVE_ARCH_LINUX_LOGO
-
- unsigned char linux_logo_red[] __initdata = {
-- 0xa5, 0x09, 0x3d, 0x4d, 0xfd, 0xf3, 0x1e, 0xeb, 0x8b, 0xc1, 0x5c, 0x85, 0xca, 0x25, 0x66, 0x00,
-- 0x01, 0x00, 0x00, 0x00, 0x01, 0x0b, 0x05, 0x04, 0x04, 0x0c, 0x0f, 0x0f, 0x01, 0x01, 0x01, 0x11,
-- 0x01, 0x01, 0x01, 0x00, 0x40, 0x08, 0x00, 0x0e, 0x0e, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x11,
-- 0x05, 0x05, 0x00, 0x04, 0xe0, 0x08, 0x00, 0x00, 0x20, 0x40, 0x44, 0x35, 0x20, 0x40, 0xff, 0x10,
-- 0x0f, 0x08, 0x00, 0xb8, 0x94, 0x40, 0x08, 0x42, 0x88, 0xbf, 0x16, 0xa7, 0x15, 0x00, 0x15, 0x73,
-- 0x94, 0x40, 0x00, 0xc7, 0xa0, 0x40, 0x08, 0x00, 0xb0, 0xbf, 0x00, 0x42, 0x82, 0x00, 0x15, 0xc7,
-- 0x03, 0x00, 0x10, 0xb8, 0x94, 0x40, 0x00, 0x0f, 0x18, 0xbf, 0x09, 0x42, 0xf0, 0xbf, 0xff, 0x00,
-- 0x68, 0x08, 0xff, 0x0f, 0x00, 0x00, 0x03, 0x00, 0x1b, 0x00, 0x03, 0x00, 0x7f, 0x08, 0xff, 0xe7,
-- 0x6c, 0x08, 0x08, 0xc8, 0x46, 0x40, 0x0a, 0xcb, 0x00, 0x00, 0x11, 0xe7, 0xac, 0x40, 0xff, 0x46,
-- 0x68, 0x08, 0x0a, 0x00, 0x68, 0x08, 0x19, 0xad, 0xac, 0x40, 0x09, 0x9b, 0x28, 0x08, 0x00, 0x10,
-- 0x0c, 0x00, 0x00, 0xaf, 0x60, 0x00, 0x10, 0x00, 0x01, 0x00, 0x06, 0x00, 0xe4, 0xbf, 0x06, 0xe7,
-- 0xd0, 0xbf, 0x0a, 0xcb, 0xd0, 0x40, 0xff, 0x0f, 0x68, 0xbf, 0x13, 0x0f, 0x0c, 0x00, 0xff, 0x00,
-- 0x0f, 0x00, 0x00, 0xcb, 0x94, 0x40, 0x09, 0x00, 0x00, 0x00, 0x00, 0x42, 0x94, 0x40, 0x15, 0xe7,
-- 0xfc, 0x08, 0x08, 0xc9, 0x32, 0x40, 0x00, 0x9a, 0x8b, 0x40, 0x19, 0x42, 0x15, 0x00, 0x15, 0xac
-+ 0x02, 0x03, 0x0d, 0x40, 0x30, 0xb8, 0x4e, 0x35,
-+ 0x04, 0xcc, 0xd1, 0x40, 0x0b, 0xdb, 0x0d, 0x13,
-+ 0xfa, 0x44, 0x74, 0xaa, 0xb7, 0xe6, 0x9d, 0x13,
-+ 0x02, 0x9d, 0xaa, 0xf1, 0x6c, 0x0e, 0xcc, 0xfe,
-+ 0xf6, 0x9d, 0xad, 0xa9, 0x26, 0x12, 0x71, 0x10,
-+ 0xfb, 0xf7, 0x38, 0x5b, 0x19, 0xa3, 0x15, 0x4c,
-+ 0x2f, 0x57, 0xdb, 0x47, 0xfa, 0x9e, 0x61, 0x95,
-+ 0xf7, 0x15, 0xb8, 0xc8, 0x1b, 0xb0, 0xc0, 0x5f,
-+ 0x26, 0x17, 0xee, 0xfd, 0xd3, 0xfc, 0xd6, 0x1f,
-+ 0x8a, 0xde, 0x62, 0x46, 0x22, 0x5e, 0x6e, 0xfd,
-+ 0x0a, 0x10, 0xb8, 0x19, 0xed, 0x9d, 0xfd, 0x0a,
-+ 0xde, 0xea, 0x46, 0x7b, 0x38, 0x68, 0xe6, 0xdc,
-+ 0x0b, 0xb5, 0x36, 0x72, 0xf6, 0x87, 0x9a, 0x2f,
-+ 0xfe, 0x0b, 0xa1, 0x1c, 0x7d, 0x1b, 0x7a, 0xfe,
-+ 0x60, 0x46, 0xfc, 0x2d, 0xd3, 0x7e, 0xc7, 0x66,
-+ 0xfd, 0xe8, 0xbe, 0xfb, 0xcf, 0x30, 0x66, 0xd8,
-+ 0xec, 0x11, 0x14, 0x6c, 0x96, 0x52, 0x9a, 0x07,
-+ 0x2f, 0xf6, 0xb7, 0xf2, 0xfa, 0xb2, 0x1e, 0xdc,
-+ 0x7c, 0xfe, 0x85, 0x42, 0xc8, 0xd3, 0x14, 0x4b,
-+ 0x83, 0xd2, 0xeb, 0x45, 0x33, 0x40, 0xe0, 0x2e,
-+ 0xf3, 0x16, 0x49, 0xed, 0x7e, 0xc0, 0xab, 0xe1,
-+ 0x6e, 0xdc, 0x32, 0x24, 0x35, 0x15, 0x20, 0x9c,
-+ 0xb1, 0xfe, 0xd2, 0xf6, 0xf6, 0xfd, 0x08, 0x21,
-+ 0x2e, 0x67, 0x8d, 0x8c, 0x73, 0xf1, 0x77, 0xef,
-+ 0x1a, 0x06, 0x4e, 0x5c, 0xf6, 0x52, 0x88, 0x1d,
-+ 0xfe, 0x76, 0x93, 0x7a, 0x62, 0x1b, 0x3e, 0xfe,
-+ 0xa6, 0x79, 0x59, 0xba, 0x4a, 0xf8, 0x4e, 0x6e,
-+ 0x7f, 0xef, 0xd5, 0x49, 0x82, 0xa4, 0x46, 0x19,
-+ 0x42, 0xff, 0xff, 0xff, 0x42, 0xff, 0xff, 0xff,
-+ 0x42, 0xff, 0xff, 0xff, 0x42, 0xff, 0xff, 0xff,
-+ 0x42, 0xff, 0xff, 0xff, 0x42, 0xff, 0xff, 0xff,
-+ 0x42, 0xff, 0xff, 0xff, 0x42, 0xff, 0xff, 0xff
- };
-
- unsigned char linux_logo_green[] __initdata = {
-- 0xb7, 0x66, 0x91, 0x57, 0xd0, 0xb7, 0x21, 0xe1, 0x91, 0x97, 0x51, 0x73, 0xb6, 0x3e, 0x66, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x06, 0x05, 0x05, 0x04, 0x04, 0x0a, 0x0f, 0x01, 0x01, 0x01, 0x01, 0x39,
-- 0x02, 0x01, 0x0e, 0x08, 0xb0, 0x01, 0x00, 0x03, 0x01, 0x01, 0x02, 0x01, 0x01, 0x01, 0x01, 0x39,
-- 0x09, 0x08, 0x00, 0x0c, 0xaf, 0x01, 0x00, 0x00, 0x35, 0x50, 0x40, 0x44, 0x35, 0x68, 0xbf, 0x39,
-- 0x0e, 0x02, 0x00, 0x15, 0xe7, 0xfc, 0x08, 0x08, 0xc7, 0x8e, 0x40, 0x00, 0x9a, 0x8b, 0x40, 0x16,
-- 0xe7, 0x01, 0x00, 0xff, 0x89, 0xfc, 0x08, 0x00, 0xc7, 0x01, 0x00, 0x08, 0x00, 0x8b, 0x40, 0xff,
-- 0x00, 0x1b, 0x00, 0x15, 0xe7, 0x00, 0x00, 0x0a, 0xc8, 0xc1, 0x40, 0x08, 0xc7, 0x08, 0xbf, 0x00,
-- 0x0f, 0x24, 0xbf, 0x0a, 0x00, 0x03, 0x00, 0x10, 0x00, 0x26, 0x00, 0x00, 0x03, 0x38, 0xbf, 0x19,
-- 0x79, 0x68, 0x08, 0xff, 0x4f, 0x68, 0x08, 0xff, 0x00, 0x42, 0x40, 0x19, 0xad, 0xb8, 0xbf, 0x13,
-- 0x0f, 0x68, 0x08, 0x00, 0x10, 0x94, 0x40, 0x19, 0xad, 0x64, 0x40, 0x09, 0x9b, 0x0b, 0x00, 0x08,
-- 0x00, 0x15, 0x00, 0x06, 0x00, 0x78, 0x40, 0x00, 0x00, 0x10, 0x08, 0x00, 0xc8, 0xb8, 0x08, 0x19,
-- 0xc8, 0x68, 0x08, 0xff, 0x91, 0xd0, 0xbf, 0x0a, 0xcb, 0x94, 0x40, 0x0a, 0x00, 0xd0, 0xbf, 0x00,
-- 0x00, 0x00, 0x00, 0xff, 0x25, 0x28, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe7, 0x8b, 0x40, 0x19,
-- 0x42, 0xb8, 0x08, 0xff, 0xb1, 0x15, 0x00, 0x00, 0xb8, 0x94, 0x40, 0x08, 0x9a, 0x8b, 0x40, 0x1c
-+ 0x02, 0x2e, 0x6d, 0x78, 0x94, 0xb7, 0xba, 0xf5,
-+ 0xfe, 0xcd, 0xdf, 0x9f, 0xf9, 0xea, 0x3e, 0xa7,
-+ 0xac, 0x45, 0x6d, 0xb7, 0xb7, 0xf2, 0x98, 0x5f,
-+ 0x7c, 0xa0, 0x0d, 0x7d, 0x3c, 0xf2, 0xc4, 0xfd,
-+ 0xcf, 0x87, 0xb9, 0xa0, 0x63, 0xee, 0x10, 0x6f,
-+ 0xdd, 0xea, 0x64, 0x74, 0x1a, 0xce, 0xe9, 0xa6,
-+ 0x6e, 0x86, 0xfb, 0x31, 0xfa, 0xb7, 0xc8, 0x94,
-+ 0xd3, 0x14, 0xdd, 0xea, 0x88, 0xa8, 0xbd, 0x58,
-+ 0x54, 0x70, 0xa8, 0xfe, 0xcb, 0xdc, 0xb6, 0xd5,
-+ 0x8a, 0xf4, 0xce, 0x86, 0x22, 0x9d, 0x6e, 0xeb,
-+ 0x60, 0x35, 0xa6, 0x62, 0xd0, 0x59, 0xec, 0x6b,
-+ 0xb7, 0xad, 0x53, 0x7e, 0x6f, 0x55, 0xeb, 0xdc,
-+ 0x0b, 0xb4, 0x3e, 0xa5, 0xfe, 0x9d, 0x83, 0x55,
-+ 0xf3, 0xc9, 0xa5, 0x91, 0xe2, 0x62, 0x88, 0xf4,
-+ 0x62, 0x44, 0xe0, 0x62, 0xbe, 0x7a, 0xc9, 0xd2,
-+ 0xfe, 0xe8, 0xbe, 0xb3, 0xce, 0xa8, 0x89, 0xb8,
-+ 0xb7, 0xc0, 0x4e, 0xbb, 0x1e, 0x53, 0x6e, 0x65,
-+ 0x75, 0xec, 0xaa, 0xf2, 0xfe, 0xd4, 0x6b, 0xa8,
-+ 0x97, 0xf5, 0x9b, 0x04, 0xac, 0xb7, 0x9a, 0x4e,
-+ 0x88, 0x9e, 0xde, 0x70, 0x64, 0x40, 0xd2, 0x2e,
-+ 0xc9, 0x76, 0x48, 0xee, 0x76, 0xc3, 0xac, 0xe2,
-+ 0xd6, 0xdc, 0x89, 0xf7, 0x36, 0x64, 0xa4, 0x9c,
-+ 0xd3, 0xfe, 0x8e, 0xf6, 0xb4, 0xdb, 0x4e, 0x9c,
-+ 0x9e, 0x58, 0x8b, 0xbc, 0x9b, 0xbf, 0x7a, 0xfd,
-+ 0x7d, 0x06, 0x51, 0xfc, 0xaa, 0x82, 0x4c, 0xfe,
-+ 0xfa, 0x76, 0xc9, 0xb4, 0x62, 0x4e, 0x81, 0xf3,
-+ 0xa9, 0x83, 0x57, 0x78, 0x1a, 0xb7, 0x0e, 0x32,
-+ 0xf8, 0xbd, 0xd4, 0x88, 0x85, 0xa4, 0x63, 0x6b,
-+ 0x7b, 0xff, 0xff, 0xff, 0x7c, 0xff, 0xff, 0xff,
-+ 0x7d, 0xff, 0xff, 0xff, 0x7e, 0xff, 0xff, 0xff,
-+ 0x7f, 0xff, 0xff, 0xff, 0x80, 0xff, 0xff, 0xff,
-+ 0x81, 0xff, 0xff, 0xff, 0x82, 0xff, 0xff, 0xff
- };
-
- unsigned char linux_logo_blue[] __initdata = {
-- 0xc9, 0xd4, 0xe9, 0x5e, 0x19, 0x11, 0x23, 0xc4, 0x8b, 0x16, 0x22, 0x22, 0x4e, 0x5c, 0x66, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x0c, 0x04, 0x04, 0x0f, 0x0f, 0x01, 0x01, 0x01, 0xe6, 0x40,
-- 0x01, 0x01, 0x0e, 0x08, 0x0a, 0x00, 0x0e, 0x03, 0x01, 0x01, 0x02, 0x02, 0x01, 0x01, 0xe6, 0x40,
-- 0x05, 0x00, 0x04, 0x0c, 0x0a, 0x00, 0x60, 0x00, 0x44, 0x50, 0x20, 0x40, 0x44, 0xc7, 0x2c, 0x40,
-- 0x0e, 0x00, 0x8b, 0x40, 0x19, 0x42, 0xfc, 0x08, 0xff, 0x73, 0x15, 0x00, 0x00, 0xb8, 0x2e, 0x40,
-- 0x19, 0x00, 0xc8, 0xbf, 0x16, 0x42, 0x0c, 0x00, 0xff, 0x00, 0xfc, 0x08, 0x00, 0xb8, 0xb0, 0xbf,
-- 0x03, 0x00, 0x8b, 0x40, 0x19, 0x00, 0x68, 0x08, 0xff, 0xbb, 0xfc, 0x08, 0xff, 0xc8, 0x00, 0x00,
-- 0x0a, 0xc8, 0x84, 0x08, 0x00, 0x00, 0x1b, 0x00, 0x10, 0x4e, 0x1b, 0x00, 0x09, 0xc8, 0x94, 0x40,
-- 0x06, 0x10, 0x38, 0xbf, 0x13, 0x0f, 0x90, 0xbf, 0x00, 0x93, 0x94, 0x40, 0x19, 0xc8, 0xa2, 0x40,
-- 0x0a, 0x0f, 0x0c, 0x00, 0x08, 0xe7, 0xb4, 0x40, 0x19, 0xb9, 0x28, 0x08, 0x09, 0x00, 0x68, 0x08,
-- 0x00, 0x9a, 0xf8, 0x08, 0x00, 0x59, 0x01, 0x00, 0x01, 0xb0, 0x00, 0x00, 0xff, 0xaf, 0x94, 0x40,
-- 0xff, 0x0f, 0x68, 0xbf, 0x1c, 0xc8, 0x68, 0x08, 0xff, 0x25, 0x68, 0x08, 0x00, 0xc8, 0x00, 0x00,
-- 0x00, 0x00, 0x90, 0xbf, 0x13, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x60, 0x08, 0x19, 0xb8, 0x94, 0x40,
-- 0x08, 0x3a, 0x28, 0xbf, 0x16, 0xa7, 0x15, 0x00, 0x15, 0xe7, 0xfc, 0x08, 0x00, 0xb8, 0x72, 0x40
-+ 0x02, 0x0b, 0x27, 0x23, 0x5e, 0x0e, 0x82, 0x91,
-+ 0x82, 0x3c, 0x3c, 0x6c, 0x83, 0x2e, 0x1f, 0x5f,
-+ 0x12, 0x03, 0x1d, 0x34, 0x52, 0x2e, 0x1b, 0x3e,
-+ 0x34, 0x42, 0x0c, 0x2e, 0x04, 0x82, 0x0e, 0xce,
-+ 0x72, 0x13, 0x62, 0x5e, 0x8f, 0x84, 0x03, 0x40,
-+ 0x82, 0x7e, 0x0b, 0x67, 0x18, 0xf6, 0x7c, 0x86,
-+ 0xb1, 0xa8, 0xfc, 0x1a, 0xfa, 0xad, 0x9c, 0x94,
-+ 0x83, 0x13, 0xf3, 0xf9, 0x50, 0x6d, 0x35, 0x1b,
-+ 0x30, 0x49, 0x1d, 0xea, 0x0b, 0x98, 0x6c, 0x6f,
-+ 0x2a, 0xf8, 0x96, 0x10, 0x22, 0xae, 0x6c, 0xa7,
-+ 0x24, 0x1c, 0x4f, 0x42, 0x93, 0x36, 0xb9, 0xbd,
-+ 0x3e, 0x22, 0x02, 0x7a, 0x95, 0x2f, 0x1b, 0xdc,
-+ 0x0b, 0xb2, 0x39, 0xd8, 0xfc, 0x2b, 0x4b, 0x3f,
-+ 0xbf, 0x70, 0x76, 0x54, 0xa6, 0x82, 0x4a, 0xcc,
-+ 0x35, 0x1b, 0xad, 0x41, 0xaa, 0x39, 0xc8, 0x96,
-+ 0xf5, 0xe8, 0xbc, 0x0d, 0xcc, 0x6c, 0x83, 0x54,
-+ 0x35, 0x63, 0x02, 0x99, 0x08, 0x13, 0x54, 0xb9,
-+ 0x56, 0xe8, 0xa3, 0xf2, 0xfd, 0xfe, 0x9b, 0x3f,
-+ 0x6a, 0xf3, 0x8d, 0x02, 0x5f, 0x61, 0x58, 0x1f,
-+ 0x5c, 0x1a, 0xdb, 0x65, 0x6e, 0x40, 0x9e, 0x2d,
-+ 0x5a, 0xca, 0x48, 0xed, 0x38, 0x09, 0xab, 0xe2,
-+ 0xa0, 0x1a, 0x59, 0x8d, 0x34, 0xac, 0x61, 0x99,
-+ 0xf3, 0xfe, 0x5a, 0xf6, 0x20, 0x6c, 0x25, 0x60,
-+ 0x66, 0x05, 0x89, 0xe8, 0xc4, 0x53, 0x75, 0xfb,
-+ 0x4c, 0x06, 0x4f, 0xac, 0x2d, 0x14, 0x1d, 0x8f,
-+ 0xfb, 0x71, 0xf3, 0xe4, 0x60, 0x2e, 0xba, 0xad,
-+ 0x16, 0x16, 0x57, 0x3d, 0x02, 0x35, 0x02, 0x15,
-+ 0xbb, 0x61, 0xd4, 0x70, 0x81, 0xa3, 0x5d, 0xb1,
-+ 0xbd, 0xff, 0xff, 0xff, 0xbe, 0xff, 0xff, 0xff,
-+ 0xbf, 0xff, 0xff, 0xff, 0xc0, 0xff, 0xff, 0xff,
-+ 0xc1, 0xff, 0xff, 0xff, 0xc2, 0xff, 0xff, 0xff,
-+ 0xc3, 0xff, 0xff, 0xff, 0xc4, 0xff, 0xff, 0xff
- };
-
- unsigned char linux_logo[] __initdata = {
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x26,
-- 0x2d, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x23, 0x23,
-- 0x26, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x2d, 0x23, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x28, 0x28, 0x2e, 0x2e, 0x28, 0x28, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x23, 0x2d, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2d, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x28, 0x28, 0x28, 0x23, 0x28, 0x20, 0x28, 0x23, 0x20, 0x28, 0x2e, 0x28, 0x20, 0x20, 0x2e, 0x2e,
-- 0x28, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2d, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x28, 0x20, 0x2e, 0x2e,
-- 0x27, 0x20, 0x20, 0x23, 0x28, 0x27, 0x28, 0x23, 0x20, 0x28, 0x2e, 0x28, 0x28, 0x20, 0x2e, 0x28,
-- 0x20, 0x28, 0x2e, 0x2e, 0x28, 0x2e, 0x2e, 0x2e, 0x23, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x20, 0x28, 0x2e,
-- 0x20, 0x27, 0x20, 0x2e, 0x28, 0x20, 0x28, 0x2e, 0x28, 0x28, 0x23, 0x28, 0x28, 0x20, 0x2e, 0x28,
-- 0x28, 0x20, 0x23, 0x28, 0x20, 0x28, 0x2e, 0x2e, 0x2e, 0x2e, 0x23, 0x26, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x26, 0x2e, 0x2e, 0x2e, 0x28, 0x28, 0x2e, 0x2e, 0x2e, 0x23, 0x20, 0x28, 0x2e,
-- 0x28, 0x20, 0x20, 0x2e, 0x2e, 0x20, 0x28, 0x23, 0x28, 0x28, 0x2e, 0x28, 0x27, 0x28, 0x23, 0x28,
-- 0x20, 0x28, 0x2e, 0x20, 0x28, 0x23, 0x2e, 0x27, 0x28, 0x2e, 0x2e, 0x2e, 0x2d, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x26, 0x23, 0x2e, 0x2e, 0x2e, 0x23, 0x20, 0x28, 0x2e, 0x2e, 0x2e, 0x23, 0x28, 0x20, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x23, 0x2e, 0x28, 0x2b, 0x2e, 0x2e, 0x2e, 0x23, 0x2e, 0x2e, 0x2e, 0x28,
-- 0x20, 0x2e, 0x28, 0x20, 0x2e, 0x2e, 0x28, 0x28, 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x26, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x26, 0x2e, 0x2e, 0x2e, 0x28, 0x28, 0x23, 0x28, 0x27, 0x2e, 0x2e, 0x2e, 0x2e, 0x23, 0x28, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x28, 0x27, 0x24, 0x25, 0x25, 0x2b, 0x2e, 0x23, 0x23, 0x2e, 0x2e, 0x2a,
-- 0x2e, 0x2e, 0x2e, 0x20, 0x2e, 0x2e, 0x20, 0x20, 0x28, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2d,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2d,
-- 0x2e, 0x2e, 0x2e, 0x28, 0x28, 0x27, 0x2e, 0x23, 0x20, 0x28, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x23, 0x21, 0x28, 0x29, 0x2c, 0x24, 0x25, 0x27, 0x27, 0x27, 0x27, 0x28, 0x21, 0x21, 0x21, 0x21,
-- 0x2e, 0x2e, 0x23, 0x23, 0x2e, 0x28, 0x20, 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x20, 0x2e, 0x2e,
-- 0x2a, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2a, 0x2e,
-- 0x2e, 0x28, 0x2e, 0x23, 0x20, 0x28, 0x20, 0x23, 0x2e, 0x28, 0x2e, 0x2e, 0x2e, 0x23, 0x21, 0x21,
-- 0x21, 0x28, 0x25, 0x25, 0x25, 0x25, 0x25, 0x24, 0x27, 0x27, 0x27, 0x27, 0x2c, 0x28, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x2e, 0x2e, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x28, 0x27, 0x20, 0x2e,
-- 0x2e, 0x23, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x23, 0x2e, 0x2e,
-- 0x28, 0x27, 0x28, 0x23, 0x2e, 0x28, 0x28, 0x2e, 0x2e, 0x2e, 0x2e, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x2c, 0x24, 0x25, 0x24, 0x25, 0x25, 0x25, 0x25, 0x25, 0x24, 0x27, 0x27, 0x27, 0x24, 0x28, 0x21,
-- 0x21, 0x21, 0x21, 0x22, 0x22, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x28, 0x27, 0x20, 0x28, 0x2e,
-- 0x28, 0x2e, 0x23, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x23, 0x2e, 0x2e, 0x2e,
-- 0x23, 0x2e, 0x20, 0x2e, 0x23, 0x28, 0x2e, 0x2e, 0x2e, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x28,
-- 0x24, 0x25, 0x25, 0x24, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x2e,
-- 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x23, 0x2e, 0x2e, 0x2e, 0x28, 0x27, 0x2e, 0x23, 0x28,
-- 0x20, 0x28, 0x2e, 0x23, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x23, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x23, 0x2e, 0x20, 0x2e, 0x23, 0x2e, 0x28, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x22, 0x24,
-- 0x24, 0x25, 0x25, 0x24, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-- 0x2d, 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x21, 0x2e, 0x2e, 0x23, 0x28, 0x2e, 0x2e, 0x27,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x23, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x23, 0x2e, 0x2e, 0x2e, 0x22, 0x20, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x2c, 0x24,
-- 0x25, 0x24, 0x25, 0x24, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-- 0x2e, 0x2d, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x2d, 0x21, 0x2e, 0x2e, 0x23, 0x2e, 0x20, 0x28,
-- 0x2e, 0x2e, 0x20, 0x28, 0x2e, 0x23, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x2e, 0x2e, 0x28, 0x20, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x23, 0x21, 0x21, 0x21, 0x21, 0x2d, 0x21, 0x21, 0x21, 0x28, 0x24, 0x24,
-- 0x24, 0x25, 0x29, 0x2e, 0x23, 0x2b, 0x2e, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
-- 0x2c, 0x21, 0x2d, 0x21, 0x28, 0x21, 0x21, 0x2d, 0x21, 0x21, 0x21, 0x23, 0x2e, 0x23, 0x28, 0x28,
-- 0x23, 0x28, 0x20, 0x20, 0x2e, 0x2e, 0x23, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x2e, 0x2e, 0x2e, 0x28, 0x28, 0x20, 0x28,
-- 0x2e, 0x2e, 0x2e, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2c, 0x24, 0x2c,
-- 0x24, 0x2b, 0x2e, 0x23, 0x2d, 0x20, 0x2a, 0x25, 0x25, 0x25, 0x25, 0x24, 0x25, 0x25, 0x25, 0x24,
-- 0x25, 0x21, 0x2d, 0x2d, 0x22, 0x21, 0x2d, 0x21, 0x2d, 0x2d, 0x21, 0x21, 0x2d, 0x2e, 0x23, 0x23,
-- 0x28, 0x27, 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x23, 0x2e, 0x2e, 0x23, 0x23, 0x20, 0x28, 0x20,
-- 0x2e, 0x2e, 0x21, 0x22, 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x21, 0x22, 0x24, 0x27, 0x24,
-- 0x24, 0x29, 0x26, 0x2e, 0x28, 0x2e, 0x26, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x2c, 0x27,
-- 0x25, 0x23, 0x21, 0x21, 0x28, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x20, 0x20, 0x20, 0x2e, 0x2e,
-- 0x28, 0x28, 0x23, 0x2e, 0x28, 0x28, 0x28, 0x2e, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x23, 0x2e, 0x2e, 0x28, 0x28, 0x23, 0x2a, 0x28, 0x28,
-- 0x2e, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x20, 0x27, 0x24, 0x2c,
-- 0x24, 0x29, 0x2f, 0x23, 0x20, 0x2f, 0x2a, 0x25, 0x25, 0x25, 0x25, 0x24, 0x25, 0x25, 0x27, 0x27,
-- 0x24, 0x28, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x22, 0x22, 0x2e,
-- 0x23, 0x2e, 0x2e, 0x28, 0x20, 0x20, 0x28, 0x2e, 0x23, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x2e, 0x2e, 0x2e, 0x20, 0x27, 0x20, 0x2e, 0x23, 0x2e,
-- 0x22, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x22, 0x21, 0x22, 0x21, 0x22, 0x20, 0x24, 0x24, 0x24,
-- 0x24, 0x28, 0x26, 0x26, 0x26, 0x2f, 0x2a, 0x25, 0x25, 0x25, 0x25, 0x24, 0x25, 0x25, 0x24, 0x27,
-- 0x24, 0x28, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x2e, 0x2e, 0x28, 0x27, 0x28, 0x20, 0x2e, 0x2e, 0x2e, 0x2d, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2e, 0x2e, 0x2e, 0x23, 0x28, 0x20, 0x20, 0x20, 0x2e, 0x28,
-- 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x2c, 0x27, 0x2c, 0x24,
-- 0x27, 0x27, 0x2c, 0x29, 0x29, 0x29, 0x29, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x27, 0x27,
-- 0x27, 0x2c, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x2e, 0x23, 0x28, 0x28, 0x2e, 0x2e, 0x28, 0x28, 0x2e, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2d, 0x2e, 0x2e, 0x28, 0x2e, 0x23, 0x23, 0x28, 0x2e, 0x2e, 0x22,
-- 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x21, 0x27, 0x24, 0x24, 0x24,
-- 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x27,
-- 0x25, 0x25, 0x28, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x22, 0x21,
-- 0x21, 0x2e, 0x2e, 0x23, 0x23, 0x2e, 0x20, 0x20, 0x2e, 0x2e, 0x23, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2e, 0x2e, 0x23, 0x28, 0x20, 0x28, 0x2e, 0x23, 0x2e, 0x21, 0x22,
-- 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x22, 0x22, 0x22, 0x21, 0x21, 0x28, 0x24, 0x24, 0x24, 0x25,
-- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x24, 0x24, 0x24, 0x27, 0x24,
-- 0x24, 0x2c, 0x28, 0x21, 0x21, 0x20, 0x22, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x22, 0x20, 0x21,
-- 0x22, 0x22, 0x2e, 0x2e, 0x28, 0x27, 0x2e, 0x23, 0x2e, 0x2e, 0x2e, 0x26, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2d, 0x2e, 0x2e, 0x2e, 0x23, 0x23, 0x28, 0x20, 0x2e, 0x23, 0x21, 0x22,
-- 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x22, 0x20, 0x20, 0x22, 0x2c, 0x2c, 0x2c, 0x2c, 0x25, 0x25,
-- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x24, 0x24, 0x24, 0x24, 0x27, 0x27, 0x2c, 0x28, 0x2b,
-- 0x23, 0x21, 0x21, 0x22, 0x21, 0x22, 0x22, 0x22, 0x21, 0x22, 0x21, 0x21, 0x22, 0x21, 0x20, 0x22,
-- 0x21, 0x22, 0x21, 0x2e, 0x23, 0x28, 0x2e, 0x2e, 0x2e, 0x28, 0x2e, 0x23, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2e, 0x2e, 0x2e, 0x20, 0x28, 0x23, 0x23, 0x2e, 0x2e, 0x21, 0x21, 0x22,
-- 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x20, 0x22, 0x21, 0x21, 0x22, 0x21, 0x26, 0x26, 0x26,
-- 0x26, 0x26, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, 0x2a, 0x26, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x21, 0x21, 0x22, 0x22, 0x22, 0x21, 0x21, 0x22, 0x22,
-- 0x21, 0x22, 0x21, 0x23, 0x2e, 0x2e, 0x2e, 0x28, 0x20, 0x28, 0x28, 0x2e, 0x26, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x26, 0x2e, 0x2e, 0x28, 0x27, 0x27, 0x28, 0x28, 0x2e, 0x21, 0x22, 0x22, 0x22,
-- 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x21, 0x22, 0x20, 0x21, 0x22, 0x22, 0x22, 0x2f, 0x2f, 0x2f,
-- 0x26, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2d, 0x21, 0x22, 0x21, 0x20, 0x20, 0x20, 0x22, 0x20, 0x20, 0x20, 0x22, 0x22, 0x20, 0x20,
-- 0x20, 0x20, 0x22, 0x20, 0x2e, 0x2e, 0x20, 0x20, 0x28, 0x20, 0x28, 0x2e, 0x23, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x23, 0x2e, 0x2e, 0x23, 0x2e, 0x20, 0x20, 0x28, 0x2e, 0x21, 0x22, 0x21, 0x22,
-- 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x21, 0x20, 0x22, 0x21, 0x21, 0x22, 0x21, 0x2f, 0x2f, 0x2f,
-- 0x26, 0x26, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x2a, 0x2d, 0x26, 0x26, 0x2d, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2d, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x2e, 0x23, 0x28, 0x28, 0x28, 0x23, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x26, 0x2e, 0x2e, 0x28, 0x2e, 0x23, 0x2a, 0x2e, 0x2e, 0x21, 0x21, 0x21, 0x21, 0x22,
-- 0x22, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x2f, 0x2f, 0x2d,
-- 0x2e, 0x23, 0x26, 0x2f, 0x2f, 0x2f, 0x26, 0x2e, 0x2e, 0x28, 0x2e, 0x26, 0x26, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x26, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21, 0x22,
-- 0x22, 0x22, 0x21, 0x21, 0x21, 0x2e, 0x23, 0x23, 0x23, 0x2e, 0x28, 0x28, 0x2e, 0x26, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x26, 0x2e, 0x2e, 0x20, 0x28, 0x28, 0x2e, 0x2e, 0x2e, 0x21, 0x21, 0x21, 0x22, 0x22,
-- 0x22, 0x21, 0x21, 0x22, 0x21, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2f, 0x26, 0x28,
-- 0x28, 0x20, 0x2e, 0x2f, 0x2f, 0x2f, 0x2e, 0x20, 0x28, 0x2e, 0x28, 0x28, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x26, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x20, 0x22, 0x22, 0x21, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x22, 0x2e, 0x2e, 0x2e, 0x28, 0x20, 0x20, 0x20, 0x2e, 0x23, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x23, 0x2e, 0x23, 0x2e, 0x28, 0x20, 0x20, 0x28, 0x23, 0x21, 0x22, 0x21, 0x21, 0x22,
-- 0x22, 0x21, 0x21, 0x22, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x22, 0x21, 0x21, 0x2f, 0x23, 0x2e,
-- 0x26, 0x28, 0x27, 0x26, 0x2f, 0x26, 0x20, 0x20, 0x26, 0x23, 0x2e, 0x20, 0x23, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x26, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21, 0x22,
-- 0x22, 0x22, 0x22, 0x21, 0x21, 0x21, 0x2e, 0x2e, 0x28, 0x2e, 0x23, 0x23, 0x2e, 0x2e, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2e, 0x2e, 0x2e, 0x23, 0x23, 0x23, 0x28, 0x2e, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22,
-- 0x21, 0x22, 0x21, 0x22, 0x22, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x2f, 0x2e, 0x23,
-- 0x2e, 0x2e, 0x27, 0x2d, 0x26, 0x26, 0x27, 0x28, 0x2f, 0x23, 0x2e, 0x20, 0x28, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x22, 0x22, 0x21, 0x21, 0x22, 0x22, 0x22, 0x20, 0x20, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x2e, 0x2e, 0x23, 0x2e, 0x2e, 0x28, 0x2e, 0x2e, 0x26, 0x2f,
-- 0x2f, 0x26, 0x2e, 0x2e, 0x28, 0x20, 0x28, 0x2e, 0x23, 0x2e, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22,
-- 0x21, 0x22, 0x21, 0x22, 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x22, 0x21, 0x2f, 0x28, 0x23,
-- 0x26, 0x2d, 0x20, 0x2a, 0x26, 0x26, 0x20, 0x28, 0x2f, 0x2f, 0x2f, 0x20, 0x20, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x26, 0x22, 0x22, 0x21, 0x21, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x2e, 0x2e, 0x28, 0x20, 0x20, 0x28, 0x28, 0x2e, 0x2d, 0x2f,
-- 0x2f, 0x2d, 0x2e, 0x23, 0x28, 0x20, 0x27, 0x20, 0x28, 0x2e, 0x21, 0x22, 0x21, 0x21, 0x21, 0x22,
-- 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2f, 0x2e, 0x28,
-- 0x2f, 0x2a, 0x29, 0x25, 0x25, 0x29, 0x2c, 0x2c, 0x26, 0x2f, 0x26, 0x27, 0x28, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x22, 0x22, 0x21,
-- 0x21, 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x2e, 0x2e, 0x2e, 0x23, 0x23, 0x2e, 0x2e, 0x23, 0x2f,
-- 0x2f, 0x2a, 0x2e, 0x2e, 0x28, 0x27, 0x20, 0x28, 0x2e, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22,
-- 0x22, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x21, 0x2f, 0x26, 0x20,
-- 0x2b, 0x29, 0x29, 0x25, 0x25, 0x2c, 0x24, 0x27, 0x2c, 0x2b, 0x27, 0x27, 0x23, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x21, 0x21,
-- 0x21, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2e, 0x23, 0x2e, 0x28, 0x28, 0x28, 0x2e, 0x23, 0x2f,
-- 0x2f, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x28, 0x28, 0x2e, 0x21, 0x22, 0x21, 0x21, 0x21, 0x21, 0x22,
-- 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x22, 0x21, 0x22, 0x21, 0x22, 0x21, 0x26, 0x2f, 0x2b,
-- 0x25, 0x25, 0x25, 0x25, 0x2c, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x2c, 0x2a, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2e, 0x2e, 0x20, 0x28, 0x28, 0x20, 0x28, 0x2e, 0x26,
-- 0x2f, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x23, 0x23, 0x2e, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22,
-- 0x22, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x26, 0x26, 0x25,
-- 0x25, 0x29, 0x25, 0x25, 0x25, 0x2c, 0x27, 0x24, 0x24, 0x24, 0x2c, 0x2c, 0x29, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2d, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2d, 0x21, 0x21, 0x22,
-- 0x22, 0x22, 0x21, 0x22, 0x21, 0x21, 0x21, 0x23, 0x2e, 0x20, 0x28, 0x28, 0x20, 0x2e, 0x2e, 0x26,
-- 0x2f, 0x2e, 0x2e, 0x28, 0x20, 0x20, 0x20, 0x2e, 0x2e, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x22,
-- 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x26, 0x2b, 0x25,
-- 0x29, 0x25, 0x25, 0x25, 0x2c, 0x24, 0x24, 0x2c, 0x2c, 0x29, 0x29, 0x29, 0x2b, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x21, 0x22, 0x21, 0x21, 0x22, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22,
-- 0x21, 0x22, 0x20, 0x20, 0x20, 0x20, 0x22, 0x2e, 0x23, 0x23, 0x2e, 0x2e, 0x23, 0x2e, 0x2e, 0x26,
-- 0x26, 0x2e, 0x23, 0x28, 0x28, 0x2e, 0x20, 0x20, 0x23, 0x21, 0x22, 0x21, 0x21, 0x21, 0x22, 0x22,
-- 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2d, 0x26, 0x29,
-- 0x25, 0x25, 0x25, 0x25, 0x24, 0x2c, 0x27, 0x29, 0x29, 0x29, 0x29, 0x29, 0x2a, 0x2f, 0x2f, 0x26,
-- 0x2f, 0x2f, 0x26, 0x21, 0x22, 0x21, 0x22, 0x20, 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x22, 0x20,
-- 0x21, 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x26,
-- 0x26, 0x2e, 0x2e, 0x23, 0x28, 0x28, 0x28, 0x28, 0x23, 0x21, 0x21, 0x22, 0x21, 0x21, 0x22, 0x22,
-- 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x20, 0x22, 0x21, 0x21, 0x22, 0x22, 0x2d, 0x2f, 0x2b,
-- 0x29, 0x29, 0x29, 0x29, 0x2c, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x2c, 0x2e, 0x2f, 0x2f, 0x2d,
-- 0x2d, 0x2f, 0x2f, 0x2d, 0x22, 0x21, 0x22, 0x20, 0x22, 0x22, 0x22, 0x21, 0x22, 0x21, 0x21, 0x22,
-- 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x2e, 0x28, 0x20, 0x27, 0x27, 0x28, 0x2e, 0x2d,
-- 0x26, 0x2e, 0x2e, 0x2e, 0x2e, 0x23, 0x23, 0x2e, 0x23, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x26, 0x2f, 0x28,
-- 0x29, 0x29, 0x2c, 0x2c, 0x2c, 0x29, 0x25, 0x29, 0x29, 0x2c, 0x20, 0x20, 0x28, 0x2f, 0x2f, 0x2f,
-- 0x2a, 0x26, 0x2f, 0x26, 0x21, 0x21, 0x21, 0x20, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x22,
-- 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2d, 0x2e, 0x2e, 0x20, 0x28, 0x28, 0x28, 0x2e, 0x26,
-- 0x26, 0x2e, 0x2e, 0x20, 0x20, 0x28, 0x2e, 0x2e, 0x23, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22,
-- 0x21, 0x26, 0x26, 0x26, 0x26, 0x26, 0x2d, 0x2d, 0x2d, 0x2d, 0x21, 0x21, 0x21, 0x2f, 0x2f, 0x28,
-- 0x20, 0x29, 0x2c, 0x2c, 0x25, 0x25, 0x29, 0x29, 0x2c, 0x20, 0x27, 0x27, 0x27, 0x23, 0x2f, 0x2f,
-- 0x26, 0x2f, 0x2f, 0x2f, 0x26, 0x26, 0x26, 0x26, 0x26, 0x2d, 0x21, 0x22, 0x22, 0x21, 0x22, 0x20,
-- 0x20, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x2e, 0x23, 0x23, 0x23, 0x23, 0x2e, 0x2e, 0x2d,
-- 0x26, 0x2e, 0x23, 0x28, 0x28, 0x20, 0x20, 0x2e, 0x28, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x26, 0x2f, 0x23, 0x20, 0x20, 0x20, 0x28, 0x2d, 0x2f, 0x2f, 0x26, 0x2d, 0x2d, 0x2f, 0x26, 0x20,
-- 0x20, 0x20, 0x2c, 0x2c, 0x29, 0x2c, 0x28, 0x20, 0x20, 0x27, 0x27, 0x27, 0x27, 0x27, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2d, 0x28, 0x28, 0x2e, 0x26, 0x23, 0x20, 0x22, 0x20, 0x20,
-- 0x20, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x26,
-- 0x26, 0x2e, 0x2e, 0x23, 0x23, 0x23, 0x23, 0x2e, 0x2e, 0x20, 0x20, 0x20, 0x20, 0x27, 0x20, 0x23,
-- 0x2f, 0x26, 0x28, 0x20, 0x20, 0x20, 0x28, 0x2d, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x28, 0x27,
-- 0x27, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x2e, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2d, 0x28, 0x20, 0x20, 0x20, 0x23, 0x2f, 0x21, 0x21, 0x22,
-- 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x26,
-- 0x26, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x20, 0x22, 0x20, 0x22, 0x20, 0x22, 0x26,
-- 0x2f, 0x26, 0x2e, 0x28, 0x28, 0x28, 0x2e, 0x26, 0x2f, 0x2f, 0x26, 0x26, 0x26, 0x2d, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x28, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x27, 0x20, 0x28, 0x26,
-- 0x26, 0x26, 0x26, 0x2f, 0x2f, 0x2f, 0x26, 0x29, 0x2c, 0x28, 0x20, 0x28, 0x26, 0x26, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x26,
-- 0x2f, 0x2e, 0x2e, 0x2e, 0x2e, 0x2b, 0x24, 0x24, 0x2c, 0x20, 0x22, 0x22, 0x28, 0x25, 0x24, 0x2a,
-- 0x2f, 0x26, 0x23, 0x2e, 0x2e, 0x2e, 0x2d, 0x2f, 0x2f, 0x2d, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x23, 0x25, 0x24, 0x2c,
-- 0x22, 0x22, 0x22, 0x23, 0x29, 0x24, 0x24, 0x24, 0x24, 0x29, 0x2e, 0x28, 0x26, 0x26, 0x22, 0x20,
-- 0x20, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x2e, 0x2e, 0x2e, 0x2e, 0x28, 0x28, 0x28, 0x28, 0x26,
-- 0x2f, 0x23, 0x2e, 0x2e, 0x23, 0x2b, 0x24, 0x24, 0x24, 0x20, 0x22, 0x22, 0x25, 0x24, 0x24, 0x2b,
-- 0x2f, 0x2f, 0x26, 0x2d, 0x2a, 0x26, 0x26, 0x2f, 0x26, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x28, 0x2c, 0x2c, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x21, 0x29, 0x24, 0x24,
-- 0x22, 0x22, 0x22, 0x28, 0x24, 0x24, 0x29, 0x29, 0x25, 0x26, 0x2d, 0x2d, 0x26, 0x26, 0x20, 0x20,
-- 0x20, 0x2c, 0x2c, 0x22, 0x22, 0x20, 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x28, 0x20, 0x20, 0x20, 0x26,
-- 0x2f, 0x23, 0x2e, 0x2e, 0x23, 0x29, 0x24, 0x24, 0x24, 0x20, 0x22, 0x28, 0x24, 0x24, 0x24, 0x29,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x26, 0x2f, 0x2f, 0x2d, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x29, 0x24, 0x24, 0x21, 0x21, 0x21, 0x21, 0x20, 0x22, 0x22, 0x22, 0x21, 0x2a, 0x24, 0x24,
-- 0x20, 0x22, 0x22, 0x2c, 0x24, 0x24, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x23, 0x20, 0x20,
-- 0x29, 0x24, 0x24, 0x22, 0x22, 0x22, 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x28, 0x2e, 0x2f,
-- 0x2f, 0x2d, 0x2e, 0x2e, 0x2e, 0x29, 0x24, 0x24, 0x24, 0x2c, 0x21, 0x2c, 0x24, 0x24, 0x24, 0x29,
-- 0x2f, 0x2f, 0x2b, 0x29, 0x24, 0x25, 0x2b, 0x23, 0x21, 0x28, 0x2c, 0x28, 0x28, 0x24, 0x24, 0x28,
-- 0x21, 0x25, 0x24, 0x24, 0x2c, 0x20, 0x28, 0x2c, 0x24, 0x2c, 0x2c, 0x2c, 0x2c, 0x2d, 0x29, 0x24,
-- 0x2c, 0x22, 0x22, 0x24, 0x24, 0x29, 0x26, 0x29, 0x29, 0x26, 0x2f, 0x2b, 0x25, 0x24, 0x2c, 0x28,
-- 0x25, 0x24, 0x24, 0x2c, 0x20, 0x20, 0x24, 0x24, 0x2c, 0x29, 0x2c, 0x29, 0x2e, 0x2e, 0x23, 0x2f,
-- 0x2f, 0x26, 0x2e, 0x2e, 0x23, 0x25, 0x24, 0x25, 0x24, 0x24, 0x28, 0x25, 0x24, 0x25, 0x24, 0x24,
-- 0x21, 0x29, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x23, 0x29, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-- 0x2b, 0x24, 0x24, 0x24, 0x24, 0x2c, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x2d, 0x2a, 0x24,
-- 0x24, 0x21, 0x2b, 0x24, 0x24, 0x22, 0x23, 0x24, 0x24, 0x2a, 0x2b, 0x24, 0x24, 0x29, 0x25, 0x28,
-- 0x24, 0x24, 0x24, 0x24, 0x2c, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x2e, 0x2e, 0x2d, 0x2f,
-- 0x2f, 0x26, 0x2e, 0x2e, 0x2e, 0x25, 0x24, 0x2b, 0x29, 0x24, 0x25, 0x24, 0x25, 0x2b, 0x24, 0x25,
-- 0x28, 0x24, 0x24, 0x29, 0x23, 0x2b, 0x24, 0x24, 0x2c, 0x29, 0x24, 0x25, 0x23, 0x2a, 0x25, 0x24,
-- 0x2b, 0x2b, 0x24, 0x25, 0x2a, 0x25, 0x24, 0x25, 0x2e, 0x2a, 0x29, 0x24, 0x24, 0x2d, 0x26, 0x25,
-- 0x24, 0x29, 0x2c, 0x24, 0x2c, 0x21, 0x23, 0x24, 0x24, 0x28, 0x29, 0x24, 0x25, 0x2a, 0x21, 0x2d,
-- 0x29, 0x24, 0x25, 0x2b, 0x25, 0x24, 0x25, 0x2b, 0x2a, 0x25, 0x24, 0x24, 0x2e, 0x2e, 0x26, 0x2f,
-- 0x2f, 0x2f, 0x23, 0x2e, 0x2b, 0x24, 0x24, 0x2b, 0x2b, 0x24, 0x24, 0x24, 0x28, 0x2e, 0x24, 0x25,
-- 0x29, 0x24, 0x24, 0x22, 0x21, 0x2d, 0x29, 0x24, 0x29, 0x29, 0x24, 0x29, 0x21, 0x2d, 0x25, 0x24,
-- 0x23, 0x2b, 0x24, 0x24, 0x2d, 0x25, 0x24, 0x28, 0x21, 0x21, 0x2b, 0x24, 0x24, 0x2d, 0x2d, 0x2b,
-- 0x24, 0x24, 0x24, 0x24, 0x2e, 0x21, 0x23, 0x24, 0x24, 0x20, 0x2a, 0x24, 0x24, 0x24, 0x24, 0x2e,
-- 0x2b, 0x24, 0x2c, 0x23, 0x25, 0x24, 0x29, 0x23, 0x2d, 0x2b, 0x24, 0x24, 0x2e, 0x2e, 0x26, 0x2f,
-- 0x2f, 0x2f, 0x2d, 0x2e, 0x2b, 0x24, 0x24, 0x2e, 0x2a, 0x25, 0x24, 0x24, 0x22, 0x23, 0x25, 0x25,
-- 0x29, 0x24, 0x24, 0x20, 0x21, 0x21, 0x25, 0x24, 0x25, 0x29, 0x24, 0x2c, 0x21, 0x21, 0x29, 0x24,
-- 0x28, 0x2b, 0x24, 0x24, 0x2d, 0x25, 0x24, 0x2c, 0x21, 0x21, 0x28, 0x24, 0x24, 0x21, 0x21, 0x2a,
-- 0x24, 0x24, 0x24, 0x25, 0x21, 0x21, 0x23, 0x24, 0x24, 0x27, 0x2d, 0x2a, 0x2b, 0x25, 0x24, 0x2c,
-- 0x2b, 0x24, 0x24, 0x23, 0x25, 0x24, 0x2c, 0x2e, 0x2e, 0x29, 0x24, 0x24, 0x2e, 0x23, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x26, 0x2e, 0x29, 0x24, 0x24, 0x2e, 0x2d, 0x29, 0x24, 0x2c, 0x21, 0x21, 0x25, 0x24,
-- 0x2b, 0x25, 0x24, 0x24, 0x2c, 0x25, 0x24, 0x24, 0x2c, 0x29, 0x24, 0x24, 0x20, 0x28, 0x25, 0x24,
-- 0x20, 0x29, 0x24, 0x24, 0x20, 0x29, 0x24, 0x24, 0x2c, 0x2c, 0x24, 0x24, 0x24, 0x21, 0x22, 0x23,
-- 0x25, 0x24, 0x24, 0x2c, 0x20, 0x20, 0x28, 0x25, 0x24, 0x27, 0x2c, 0x2c, 0x2c, 0x25, 0x24, 0x2c,
-- 0x29, 0x24, 0x24, 0x28, 0x29, 0x24, 0x24, 0x25, 0x25, 0x24, 0x24, 0x24, 0x2e, 0x2d, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x23, 0x29, 0x24, 0x25, 0x2e, 0x2e, 0x2a, 0x24, 0x28, 0x21, 0x21, 0x25, 0x24,
-- 0x2b, 0x2a, 0x25, 0x24, 0x24, 0x24, 0x25, 0x2b, 0x21, 0x29, 0x24, 0x2c, 0x21, 0x21, 0x29, 0x24,
-- 0x2e, 0x2e, 0x24, 0x25, 0x22, 0x2d, 0x29, 0x24, 0x24, 0x24, 0x25, 0x24, 0x25, 0x22, 0x22, 0x21,
-- 0x2b, 0x24, 0x24, 0x22, 0x22, 0x21, 0x2e, 0x24, 0x24, 0x2b, 0x25, 0x24, 0x24, 0x24, 0x25, 0x2e,
-- 0x2b, 0x24, 0x25, 0x22, 0x2d, 0x29, 0x24, 0x24, 0x24, 0x25, 0x24, 0x25, 0x2e, 0x26, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x26, 0x2a, 0x2a, 0x2e, 0x2e, 0x2e, 0x2a, 0x2a, 0x2e, 0x22, 0x21, 0x2d, 0x2e,
-- 0x23, 0x21, 0x2d, 0x2a, 0x2b, 0x2a, 0x28, 0x22, 0x21, 0x2d, 0x2a, 0x28, 0x21, 0x21, 0x2b, 0x2b,
-- 0x21, 0x2d, 0x2a, 0x23, 0x21, 0x22, 0x2d, 0x2a, 0x2b, 0x23, 0x23, 0x23, 0x2e, 0x21, 0x22, 0x22,
-- 0x2d, 0x2a, 0x23, 0x21, 0x21, 0x21, 0x2d, 0x2a, 0x23, 0x21, 0x2d, 0x2a, 0x2b, 0x2a, 0x21, 0x21,
-- 0x2d, 0x23, 0x23, 0x21, 0x23, 0x2a, 0x2a, 0x2b, 0x2a, 0x2a, 0x2a, 0x2b, 0x23, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x26, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x23, 0x21, 0x21, 0x22,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x20, 0x28, 0x28, 0x21, 0x21, 0x21, 0x28, 0x25, 0x2c,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x21, 0x20, 0x22, 0x21, 0x21, 0x22, 0x22,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x2e, 0x2e, 0x23, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x26, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x22, 0x21, 0x20,
-- 0x22, 0x21, 0x21, 0x22, 0x22, 0x22, 0x20, 0x25, 0x24, 0x25, 0x21, 0x21, 0x21, 0x2b, 0x24, 0x24,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x21, 0x20, 0x22, 0x22, 0x22, 0x22, 0x22,
-- 0x21, 0x22, 0x21, 0x22, 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x21,
-- 0x21, 0x22, 0x21, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x21, 0x20,
-- 0x20, 0x21, 0x21, 0x22, 0x21, 0x20, 0x20, 0x29, 0x24, 0x24, 0x2d, 0x21, 0x21, 0x2d, 0x2a, 0x2e,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x21, 0x22, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x20, 0x20, 0x22, 0x21, 0x21,
-- 0x21, 0x21, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2d, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x22, 0x20,
-- 0x21, 0x21, 0x21, 0x22, 0x21, 0x21, 0x22, 0x29, 0x24, 0x25, 0x21, 0x21, 0x21, 0x21, 0x23, 0x23,
-- 0x21, 0x23, 0x23, 0x23, 0x23, 0x28, 0x28, 0x21, 0x21, 0x22, 0x20, 0x22, 0x21, 0x21, 0x22, 0x22,
-- 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21, 0x2e, 0x2e, 0x23, 0x22, 0x20, 0x20, 0x22, 0x2d, 0x21,
-- 0x21, 0x21, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x28,
-- 0x21, 0x21, 0x2d, 0x21, 0x21, 0x21, 0x28, 0x29, 0x24, 0x24, 0x21, 0x21, 0x21, 0x2e, 0x24, 0x2c,
-- 0x2d, 0x29, 0x24, 0x2c, 0x24, 0x24, 0x24, 0x25, 0x21, 0x29, 0x24, 0x24, 0x21, 0x2d, 0x29, 0x24,
-- 0x28, 0x2a, 0x25, 0x24, 0x2c, 0x2e, 0x25, 0x24, 0x25, 0x23, 0x21, 0x28, 0x22, 0x23, 0x2d, 0x21,
-- 0x21, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x25, 0x24, 0x25, 0x22, 0x20, 0x21, 0x2a, 0x24, 0x25,
-- 0x21, 0x29, 0x24, 0x24, 0x2b, 0x2b, 0x24, 0x24, 0x2b, 0x2b, 0x24, 0x25, 0x21, 0x21, 0x29, 0x24,
-- 0x28, 0x21, 0x2a, 0x25, 0x24, 0x24, 0x24, 0x25, 0x2d, 0x2d, 0x2d, 0x21, 0x2d, 0x21, 0x21, 0x2d,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x23, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x21, 0x21, 0x22, 0x21, 0x21, 0x20, 0x29, 0x24, 0x24, 0x27, 0x20, 0x21, 0x2e, 0x24, 0x2c,
-- 0x2d, 0x29, 0x24, 0x2c, 0x21, 0x2d, 0x25, 0x24, 0x28, 0x2b, 0x24, 0x25, 0x21, 0x21, 0x2b, 0x24,
-- 0x28, 0x21, 0x21, 0x2b, 0x24, 0x24, 0x24, 0x2e, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2d, 0x23,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x21, 0x22, 0x22, 0x21, 0x20, 0x29, 0x24, 0x24, 0x22, 0x21, 0x21, 0x2e, 0x24, 0x25,
-- 0x21, 0x29, 0x24, 0x2c, 0x21, 0x21, 0x24, 0x24, 0x28, 0x2b, 0x24, 0x24, 0x21, 0x21, 0x29, 0x24,
-- 0x28, 0x21, 0x21, 0x2c, 0x24, 0x24, 0x24, 0x2c, 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, 0x23, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x20, 0x22, 0x21, 0x20, 0x29, 0x24, 0x24, 0x2c, 0x2c, 0x2c, 0x2b, 0x24, 0x24,
-- 0x22, 0x29, 0x24, 0x2c, 0x22, 0x2e, 0x25, 0x24, 0x2b, 0x2b, 0x24, 0x24, 0x28, 0x28, 0x25, 0x24,
-- 0x28, 0x21, 0x2c, 0x24, 0x25, 0x29, 0x24, 0x24, 0x2c, 0x21, 0x21, 0x22, 0x22, 0x28, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x23, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x22, 0x21, 0x20, 0x25, 0x24, 0x24, 0x24, 0x24, 0x24, 0x29, 0x24, 0x24,
-- 0x22, 0x25, 0x24, 0x2c, 0x22, 0x2e, 0x24, 0x24, 0x28, 0x2d, 0x25, 0x24, 0x24, 0x24, 0x24, 0x24,
-- 0x20, 0x2c, 0x24, 0x24, 0x2c, 0x23, 0x29, 0x24, 0x24, 0x2c, 0x21, 0x22, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x23, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x21, 0x20, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x23, 0x2b, 0x2e,
-- 0x21, 0x2a, 0x2b, 0x2e, 0x21, 0x21, 0x2b, 0x2b, 0x2e, 0x21, 0x2d, 0x2b, 0x29, 0x29, 0x2b, 0x2e,
-- 0x2e, 0x2b, 0x2b, 0x2b, 0x22, 0x22, 0x2d, 0x2a, 0x2b, 0x2b, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x23, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x28, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x20, 0x21, 0x22, 0x21, 0x21, 0x2d, 0x21, 0x21, 0x21, 0x21, 0x2d, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x22, 0x20, 0x21, 0x21, 0x21, 0x21, 0x2d, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x21, 0x22, 0x21, 0x21, 0x21, 0x21,
-- 0x22, 0x21, 0x20, 0x21, 0x21, 0x21, 0x21, 0x2d, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2d, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x23, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x21, 0x21, 0x21, 0x21,
-- 0x21, 0x22, 0x20, 0x21, 0x22, 0x21, 0x21, 0x2d, 0x21, 0x21, 0x2d, 0x21, 0x2d, 0x21, 0x21, 0x21,
-- 0x21, 0x21, 0x21, 0x23, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x23,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x21,
-- 0x21, 0x22, 0x20, 0x21, 0x21, 0x21, 0x21, 0x2d, 0x2d, 0x2d, 0x21, 0x2d, 0x21, 0x2d, 0x21, 0x21,
-- 0x21, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x23, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x23, 0x23, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x23, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x23,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x26, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x23, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x26, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x23, 0x26, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2d, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2d, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x23, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x23, 0x2d, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x2d, 0x23, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2d, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x26, 0x26, 0x23,
-- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
-- 0x23, 0x2d, 0x26, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x26, 0x26, 0x26, 0x2d, 0x2d, 0x2a, 0x2d, 0x2a, 0x2d, 0x2d, 0x2d, 0x26, 0x26, 0x26, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
-- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd3, 0xd1, 0x54, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xcf, 0xc6, 0xc6,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xfd, 0xc6, 0xfd, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd3, 0x20, 0xe1, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x4c, 0x20,
-+ 0x20, 0x20, 0xe1, 0x20, 0xe1, 0x20, 0xe1, 0x20,
-+ 0x20, 0x20, 0xe1, 0x20, 0xe1, 0x20, 0x20, 0x20,
-+ 0x4c, 0xd1, 0x54, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xab, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0xe1, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0x54, 0xd1, 0x20, 0x20, 0xe1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x7f, 0xcf, 0xec, 0x4c, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd3, 0x6c, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0xe1, 0x20, 0x80,
-+ 0x20, 0xe1, 0x20, 0x20, 0xe1, 0x20, 0x20, 0x20,
-+ 0x6c, 0xd3, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd3,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0xab, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xab, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0x54, 0x54, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0x80, 0x20, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0xab, 0xd1,
-+ 0xd1, 0x54, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xab, 0xe1, 0x20, 0x20, 0xd1, 0x54, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x96, 0x57,
-+ 0xe2, 0x59, 0xe1, 0xe1, 0x20, 0x20, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x57, 0xda,
-+ 0xda, 0xda, 0xfc, 0xfc, 0xda, 0xfc, 0x20, 0x20,
-+ 0xe1, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xda,
-+ 0xda, 0xd1, 0xd1, 0x54, 0xab, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0xe1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd3, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x20, 0xe1, 0xe1, 0xab, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xf2, 0x20,
-+ 0x80, 0x20, 0x80, 0x20, 0x20, 0x80, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0x20, 0x20,
-+ 0x20, 0xd3, 0xd1, 0xd1, 0xb1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xc3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xc3, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd3, 0x54, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x80, 0xe1, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0x54, 0xe2, 0x6c,
-+ 0xf2, 0xfd, 0x9c, 0x20, 0x20, 0x20, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0x54, 0xd1, 0x54,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xab, 0xd1, 0x54, 0x20, 0x20, 0xe1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0x20, 0x80, 0x20, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xac, 0x54, 0xd1, 0x20, 0xe1,
-+ 0x20, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd3, 0xd3, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xe8,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd3, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0x99, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xab, 0xd1, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd3, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd3, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd3,
-+ 0xd3, 0xd1, 0xab, 0xd1, 0xab, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0x20, 0x20, 0x20, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xc3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xac, 0xe8, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x80, 0x20, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0x4c, 0x20,
-+ 0x20, 0xd1, 0x54, 0xd1, 0xc7, 0x59, 0x80, 0xe1,
-+ 0xe9, 0xab, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xab,
-+ 0x6c, 0x20, 0x6c, 0xd3, 0xd3, 0xd3, 0xd1, 0x20,
-+ 0x20, 0xe1, 0xd1, 0xd1, 0xc6, 0xbd, 0x80, 0x80,
-+ 0x82, 0x57, 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xc7, 0xcf, 0xf2, 0xbf, 0x59, 0xe1,
-+ 0xe1, 0x80, 0xe2, 0xfd, 0x99, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd3, 0xc6, 0xe2,
-+ 0x59, 0x59, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0x4c, 0x20,
-+ 0x20, 0xab, 0xd1, 0x81, 0xbd, 0x20, 0x80, 0xcc,
-+ 0xcf, 0xd3, 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0x54,
-+ 0xd3, 0xd1, 0x99, 0xfd, 0xec, 0x59, 0xe1, 0x20,
-+ 0x20, 0x59, 0x20, 0xe1, 0x20, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xc7, 0x57, 0xf2, 0xbf, 0x80,
-+ 0xe1, 0x80, 0x4c, 0xe2, 0xfd, 0xc3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xab, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0x54, 0x80, 0x20, 0xe1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xe1, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xe1, 0x20, 0x20, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xfd, 0x20, 0x20,
-+ 0x20, 0x96, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xde,
-+ 0x20, 0x20, 0xc6, 0xab, 0xd1, 0xd1, 0xd3, 0xe1,
-+ 0x20, 0x20, 0xd1, 0xe9, 0x20, 0x20, 0xe1, 0x20,
-+ 0x20, 0x20, 0xc2, 0xd3, 0x54, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xe9, 0xe1, 0x20, 0x80, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0xe1, 0x20, 0xc2, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xc3, 0xd1, 0xd1, 0x96, 0xcc, 0x20, 0x20,
-+ 0x80, 0x20, 0x80, 0x20, 0x20, 0xe1, 0x20, 0xe1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0x7b, 0x20, 0x20, 0xe1, 0x20, 0x20,
-+ 0x20, 0xc2, 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xfa, 0xcc, 0x20, 0xe1, 0x20, 0x59, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0x7b, 0x20, 0x20, 0x80, 0x20, 0xe1,
-+ 0x20, 0xe1, 0x20, 0x80, 0x20, 0xc2, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xe8, 0x54, 0xd1, 0xe2, 0x20,
-+ 0x20, 0x6c, 0xab, 0xd1, 0x54, 0xd1, 0x7f, 0x20,
-+ 0x20, 0xc2, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x20,
-+ 0x20, 0x20, 0xc6, 0x20, 0x20, 0x4c, 0xc2, 0x6c,
-+ 0x20, 0x20, 0x20, 0x6e, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xec, 0x20, 0x80, 0xf2, 0xfc, 0xfd, 0xc6,
-+ 0x57, 0xe2, 0x20, 0x20, 0x20, 0xda, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xfa, 0x4c, 0x20, 0x20, 0x6e,
-+ 0x7f, 0xd1, 0xab, 0x99, 0x96, 0x20, 0x20, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0xe1, 0x57, 0xe1, 0x20, 0x80, 0xc2, 0x6c, 0x20,
-+ 0x20, 0x20, 0xe9, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x7f, 0x80, 0x20, 0xe1, 0xec, 0x7f, 0xd1, 0xd3,
-+ 0x99, 0x96, 0x20, 0x20, 0x20, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xf2, 0xe1, 0x59, 0xe2, 0xfc, 0xfd,
-+ 0xfd, 0x57, 0xe2, 0x20, 0x20, 0x20, 0xfc, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x7f, 0x4c,
-+ 0xe1, 0x20, 0x6e, 0xd1, 0xd1, 0x54, 0xbd, 0x80,
-+ 0xe1, 0x96, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x20,
-+ 0x20, 0x20, 0x59, 0x20, 0xfc, 0xab, 0xd1, 0x54,
-+ 0xfc, 0x20, 0x20, 0x80, 0xfa, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xcf, 0x9a, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xfc, 0x20, 0x80, 0x6c, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xe8, 0x82, 0x20, 0x20, 0x7b, 0x54,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd3, 0x20, 0x20, 0xe1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0x4c, 0x20, 0xfc, 0x54, 0xac, 0xd1, 0xfc,
-+ 0x20, 0xe1, 0x20, 0x7f, 0xd1, 0x54, 0x54, 0xd1,
-+ 0xcc, 0x80, 0x20, 0x6e, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0x99, 0xe1, 0x20, 0x20, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xcf, 0xc6, 0xd1, 0x54, 0xe8, 0xd1,
-+ 0xd1, 0xd1, 0xe8, 0xfc, 0x20, 0x20, 0xcc, 0xab,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xcf,
-+ 0x20, 0x80, 0x20, 0x9a, 0xd1, 0xc6, 0x20, 0x20,
-+ 0x7b, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20,
-+ 0x80, 0x20, 0x20, 0xfd, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0x82, 0x20, 0x20, 0xfc, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd3, 0xe8,
-+ 0x54, 0xd1, 0xc3, 0x20, 0x20, 0x80, 0xd1, 0xd3,
-+ 0x54, 0xd1, 0x81, 0xe1, 0x20, 0x80, 0xab, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0x80, 0xfd, 0x54, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0x82, 0x20, 0x20, 0xfc, 0xd1, 0x54, 0xd1, 0x9a,
-+ 0x20, 0x20, 0x80, 0xab, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xe1, 0x20, 0x20, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd3, 0x54, 0xd1, 0xab, 0xd1,
-+ 0xd1, 0xd3, 0x54, 0xab, 0x20, 0x20, 0x80, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xe2, 0x20, 0xe1, 0x6c, 0x7f, 0x4c, 0xe1, 0x6c,
-+ 0x54, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0x20,
-+ 0x20, 0x20, 0xde, 0xd1, 0xd1, 0xc3, 0xd1, 0xd1,
-+ 0xd1, 0x57, 0x20, 0x80, 0xbd, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd3, 0xd3, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xec, 0x20, 0x20, 0xec, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd3, 0xd1, 0x20, 0x20, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xde, 0xd3, 0xe8, 0xd1, 0xd1, 0xd1, 0xe8,
-+ 0xcf, 0x20, 0x59, 0xcc, 0xd1, 0xd1, 0xd1, 0xf2,
-+ 0x20, 0x20, 0xf2, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xab, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0x54, 0xe8, 0x80, 0x20, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xc3, 0x59, 0x20, 0x20, 0x59, 0x20, 0x20, 0x81,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd3, 0xd1, 0x20,
-+ 0x20, 0x80, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0x7f, 0x20, 0xe1, 0x59, 0xd3, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x80, 0x54, 0xd3,
-+ 0xd1, 0xd1, 0x6c, 0x20, 0x20, 0x57, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xe1, 0xe1, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0x54,
-+ 0x7f, 0x20, 0x20, 0x4c, 0xd1, 0xd1, 0xd1, 0x6c,
-+ 0x20, 0x20, 0xda, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0x54, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0xd1, 0xd1,
-+ 0xab, 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd3, 0xd1, 0x54, 0x20, 0x20, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd3,
-+ 0xd3, 0xc6, 0x20, 0x20, 0x20, 0x80, 0xe2, 0xd1,
-+ 0xab, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x20,
-+ 0x20, 0x20, 0x54, 0xd3, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0x54, 0x54, 0x20, 0x20, 0xe1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xc3, 0xc6, 0xec, 0xe2, 0x6c,
-+ 0x80, 0x4c, 0x20, 0x20, 0xe1, 0x20, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xe1, 0xe1, 0xe1, 0xfd, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xab, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xab, 0x20, 0x20, 0xe1, 0xd1, 0x54, 0x54, 0xe1,
-+ 0x80, 0x20, 0xfd, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xc6, 0xe9, 0xc2,
-+ 0xbf, 0x80, 0x4c, 0x80, 0x80, 0x20, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0xe1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0x81, 0x20, 0xe1, 0x20, 0x20, 0x9c, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x20,
-+ 0x20, 0x80, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd3,
-+ 0x54, 0xd1, 0x20, 0x20, 0xe1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xc7, 0xfc, 0x80, 0x20, 0xe1, 0x59, 0xcc,
-+ 0xc2, 0xc2, 0xbd, 0x80, 0x20, 0xe1, 0xd1, 0xd3,
-+ 0xd1, 0x99, 0x20, 0x20, 0x20, 0x9a, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0x20, 0xe1, 0x20, 0xd1, 0xd1, 0xab, 0x20,
-+ 0x20, 0x20, 0xc6, 0xd3, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0x20, 0x20, 0x20, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0x54, 0xe9, 0x20, 0x20, 0x20, 0x59,
-+ 0xbf, 0xc2, 0xc2, 0xbd, 0x20, 0x20, 0xe1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54,
-+ 0xab, 0xbf, 0x20, 0x20, 0x80, 0x20, 0xe2, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x20,
-+ 0x20, 0x20, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xab, 0x20, 0x20, 0x59, 0xd1, 0xd1, 0xd1,
-+ 0xc3, 0xbd, 0x20, 0x20, 0xec, 0x96, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0x20, 0x20, 0x20, 0xfd, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x20, 0x20, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0x20, 0x20, 0x59, 0xd1, 0x54, 0x54, 0x20,
-+ 0x20, 0x20, 0x81, 0xd1, 0xd3, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0x54, 0x20, 0x20, 0x20, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xc3, 0xcc, 0x20, 0x20, 0xec, 0x96, 0x54,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x20, 0xe1, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0x54, 0xd1, 0x54, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0x54,
-+ 0x6e, 0x20, 0x20, 0x6e, 0x20, 0x20, 0x20, 0xc6,
-+ 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd3, 0x20,
-+ 0x20, 0x20, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x96, 0x80, 0x20, 0xcc, 0x54, 0xd1, 0xd3,
-+ 0xde, 0x20, 0xe1, 0x7b, 0xd1, 0xd1, 0xd1, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0x54, 0xd1,
-+ 0x54, 0xd1, 0xe1, 0x20, 0x20, 0xda, 0xac, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0xe1, 0xab, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x96, 0xe1, 0x20, 0x82, 0xd1, 0xd1, 0xd1, 0xe1,
-+ 0x20, 0x20, 0x57, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0x20, 0x20, 0x20, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xe9, 0x20, 0x20, 0x7b, 0xd1, 0xd3, 0xd1,
-+ 0xac, 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0x20, 0xe1, 0x20, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xab, 0xd3, 0xd1, 0xd1, 0x20, 0xe1,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0x54, 0xd1, 0xab, 0x54, 0x20, 0x20, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0xc3, 0xd1, 0x54, 0xe9, 0x20, 0xe1,
-+ 0x20, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0x54, 0xfa,
-+ 0x4c, 0x20, 0xe2, 0xd1, 0xe2, 0x80, 0x20, 0x80,
-+ 0x99, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20,
-+ 0x20, 0x20, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xda, 0x20, 0x20, 0xe9, 0xd1, 0x54, 0xd1,
-+ 0x4c, 0x20, 0x20, 0xc3, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xe1, 0x20, 0x20, 0xd1, 0xd1,
-+ 0xd1, 0xe8, 0xcc, 0x20, 0x20, 0x6e, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xcf, 0x20, 0x80, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xac, 0xd1,
-+ 0xcf, 0x20, 0x20, 0x6e, 0x54, 0xd1, 0xab, 0xcc,
-+ 0x20, 0x20, 0xec, 0x54, 0xd3, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xcf, 0x20, 0x20, 0xe1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0x6c, 0x80, 0x20, 0x99, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0x20, 0xe1, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x80, 0xd1, 0x54, 0xd3, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0x80, 0x20, 0x20, 0xc7,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xda, 0x20, 0x20, 0x20,
-+ 0x20, 0xab, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xbd,
-+ 0x20, 0x59, 0x99, 0xd3, 0xc3, 0x59, 0x20, 0x20,
-+ 0xf2, 0x54, 0xd1, 0xd1, 0x54, 0x54, 0x54, 0x20,
-+ 0x20, 0xe1, 0xd3, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xac, 0xcc, 0x20, 0x20, 0x9a, 0xd1, 0xd1, 0xab,
-+ 0xe1, 0xe1, 0x20, 0xab, 0xd1, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd3, 0xe1, 0x20, 0x80, 0xd1, 0x54,
-+ 0xd1, 0xd3, 0xe9, 0x20, 0x20, 0x59, 0x54, 0xd3,
-+ 0xd1, 0xd1, 0x54, 0x9c, 0x59, 0x20, 0x20, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0x6c, 0x20, 0xe1, 0x9a, 0xd1, 0x54, 0xd1, 0xe9,
-+ 0x20, 0x20, 0x6c, 0xd3, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0x9c, 0x80, 0x20, 0x20, 0xe1, 0x54, 0xd1, 0xd3,
-+ 0xd1, 0x20, 0x20, 0xe1, 0xab, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0x54, 0x20, 0x20, 0x80, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x20, 0x20, 0xe1, 0x54, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xab, 0xd1, 0xd1, 0x54, 0xd1, 0x80, 0x20,
-+ 0x20, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xab, 0xd1,
-+ 0xd1, 0xab, 0xd1, 0xd1, 0x59, 0x20, 0x20, 0xcf,
-+ 0xd1, 0xab, 0xd3, 0xfc, 0x20, 0x6c, 0xe1, 0x20,
-+ 0x80, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x57, 0x20,
-+ 0x20, 0xda, 0x54, 0xd1, 0xd1, 0x9a, 0x20, 0x20,
-+ 0x20, 0xc6, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0x20,
-+ 0x20, 0x20, 0xd1, 0x54, 0xd1, 0xd1, 0xd3, 0xe8,
-+ 0x6e, 0x20, 0xe1, 0xbd, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0x59, 0x20, 0x20, 0xe9, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xfd, 0xcc, 0x20, 0xe1, 0x20, 0x9a, 0xd1,
-+ 0xac, 0xd1, 0x7f, 0x20, 0x20, 0xe1, 0xde, 0xd1,
-+ 0xd3, 0xd1, 0xfa, 0x4c, 0xe1, 0x20, 0x20, 0xe1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0x7b,
-+ 0xe1, 0x20, 0xcc, 0xd1, 0xd1, 0xd1, 0xd1, 0x96,
-+ 0x20, 0x20, 0x20, 0xda, 0x54, 0x54, 0xd1, 0x7f,
-+ 0x6c, 0x80, 0x20, 0x20, 0x20, 0xd1, 0xd3, 0xd1,
-+ 0xc3, 0x6c, 0x20, 0xe1, 0xde, 0x54, 0xd1, 0xd1,
-+ 0x54, 0xac, 0x81, 0xbd, 0x20, 0x20, 0x20, 0x96,
-+ 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xab, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0x20, 0x20, 0x20, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xab, 0xe1, 0x20,
-+ 0x59, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xab, 0xec, 0x20, 0xe1, 0x20,
-+ 0xbd, 0xe2, 0x59, 0x20, 0x59, 0x9a, 0x20, 0x20,
-+ 0xe1, 0x54, 0x54, 0xd3, 0xd1, 0xc7, 0x6c, 0x20,
-+ 0xbf, 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xec, 0x20,
-+ 0x20, 0x6c, 0xc7, 0xab, 0xd1, 0xd3, 0xd1, 0x20,
-+ 0x20, 0x20, 0xec, 0xda, 0xfd, 0xc6, 0xcf, 0xcc,
-+ 0x20, 0xe1, 0x59, 0xfa, 0x54, 0xd1, 0xd1, 0xd3,
-+ 0xde, 0xe1, 0x20, 0x20, 0x6c, 0x6e, 0xfc, 0xe2,
-+ 0x6c, 0x20, 0x20, 0xbf, 0x20, 0x20, 0x6c, 0x6e,
-+ 0x7f, 0xd1, 0x54, 0x6e, 0x20, 0x20, 0x20, 0x6e,
-+ 0xc6, 0xe9, 0x80, 0x80, 0x6e, 0xe1, 0x20, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xec, 0xfc, 0xcf, 0x81, 0xfc, 0x82, 0x20,
-+ 0x20, 0x59, 0x99, 0xd1, 0x54, 0xe8, 0xd1, 0xd1,
-+ 0xec, 0x20, 0x20, 0xe1, 0x6e, 0xc6, 0xde, 0xe1,
-+ 0x20, 0x6e, 0x20, 0xe1, 0x20, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0x6e, 0x20, 0x20, 0x20, 0xbf, 0x6e, 0x6e,
-+ 0xf2, 0x6c, 0x20, 0x20, 0xbf, 0xe1, 0x80, 0x59,
-+ 0xde, 0x7f, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x96, 0x81,
-+ 0x81, 0xc6, 0xfd, 0x20, 0x20, 0x20, 0xfd, 0x9a,
-+ 0xc6, 0x81, 0x9c, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xc3, 0xd1, 0xd1, 0xfa, 0x59, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x59, 0x9a, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0x54, 0xd1, 0xec, 0x20, 0x20,
-+ 0x96, 0xc3, 0xd1, 0xd1, 0x54, 0xd1, 0xab, 0x6c,
-+ 0x20, 0x20, 0xe2, 0xd1, 0xd1, 0xd1, 0xd3, 0xe1,
-+ 0x80, 0x20, 0x20, 0xe1, 0x20, 0xe1, 0x20, 0x20,
-+ 0x20, 0x6c, 0xfa, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xbd, 0x20, 0xe1, 0x20, 0x20, 0xe1, 0x20,
-+ 0x20, 0xcc, 0x96, 0x96, 0x20, 0x20, 0x20, 0x20,
-+ 0xfd, 0xd1, 0xd1, 0x99, 0xc2, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0xe1, 0xe2, 0xd1, 0x20, 0xe1, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x80, 0x20, 0x20, 0xe1, 0x20, 0x20, 0x20, 0x20,
-+ 0xbf, 0x7f, 0xd3, 0xd1, 0xd1, 0xac, 0xd1, 0xd1,
-+ 0xab, 0xbd, 0x80, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0xec, 0xd1, 0x20, 0x20, 0x20, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xbd, 0x20, 0x80, 0x20, 0xe1, 0x20,
-+ 0x20, 0xe1, 0x6c, 0x96, 0x7f, 0x20, 0x20, 0xe1,
-+ 0x20, 0xfd, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xe2, 0x20,
-+ 0x20, 0x20, 0x80, 0x20, 0x80, 0x20, 0x80, 0x20,
-+ 0xe1, 0x20, 0xf2, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0x80, 0x20,
-+ 0xe1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0x54, 0xd1, 0x54, 0xd1, 0x54, 0x96, 0xc2, 0x80,
-+ 0x20, 0x6c, 0x6e, 0x7f, 0xd1, 0x54, 0xe1, 0x20,
-+ 0xe1, 0xd1, 0xd3, 0xd1, 0x9a, 0x20, 0x20, 0xec,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x81,
-+ 0x20, 0x20, 0xe1, 0xfd, 0xd1, 0xd3, 0xd1, 0x20,
-+ 0x20, 0x20, 0xe1, 0x20, 0x80, 0x20, 0x4c, 0xf2,
-+ 0xfd, 0xd1, 0xd1, 0x54, 0xe8, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xfd, 0xcc, 0x4c, 0x20, 0x80, 0xe2,
-+ 0xfd, 0xd3, 0xd1, 0xd1, 0x57, 0x80, 0xe1, 0xcc,
-+ 0x9a, 0xd1, 0xd1, 0xd1, 0xab, 0x57, 0xcc, 0xe1,
-+ 0x80, 0x82, 0xcf, 0xab, 0x54, 0x20, 0x20, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0x20, 0xe1, 0xe1, 0x20, 0x6c, 0xf2, 0xcf,
-+ 0xd1, 0x54, 0x54, 0xd1, 0xe8, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xab, 0xfc, 0xcc, 0x80, 0xe1, 0xcc, 0xcf,
-+ 0xab, 0xd1, 0x20, 0x80, 0x80, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xcf, 0xcc, 0x80, 0x20, 0x59,
-+ 0xe2, 0xcf, 0xd1, 0xd1, 0xd3, 0x57, 0x59, 0x20,
-+ 0xbd, 0x81, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd3, 0xe2, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xe1,
-+ 0x20, 0x20, 0xf2, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xe8, 0x54, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xe8, 0xd1, 0x54, 0xd1, 0xd1, 0x20,
-+ 0x20, 0x80, 0x54, 0xd3, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xe8, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20,
-+ 0x20, 0x20, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe1,
-+ 0x20, 0x20, 0x54, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd3, 0x20, 0x20,
-+ 0xe1, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x20,
-+ 0x20, 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x20,
-+ 0x20, 0x20, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0x20, 0x20,
-+ 0x20, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0xab, 0xbf,
-+ 0xbf, 0x82, 0xc3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xab, 0xcc, 0xbf,
-+ 0xbf, 0xab, 0xd1, 0xd1, 0xd1, 0xd3, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xe8, 0xd3, 0xd1, 0xd1, 0xd3, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xab, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xab, 0x54,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xab, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xc3, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x99, 0xe9, 0x54, 0xd1, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0x99, 0xe9, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0x20, 0x6c, 0x4c, 0x59, 0x6c, 0x57, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xfa, 0x20, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0x99, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0x7f,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xfa, 0x20, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x20, 0xfa, 0xd1, 0xd1, 0x81, 0x20, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xc3, 0xd1, 0xd1, 0x54,
-+ 0x54, 0xfa, 0xe1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xfa, 0x20, 0xd1, 0x54, 0xd1, 0xd1, 0xfa, 0x20,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0x7f, 0x20, 0x54, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x20, 0xfa, 0xd1, 0xc7, 0x6e, 0xf2, 0xd1,
-+ 0x7f, 0x20, 0xfc, 0xbf, 0xd3, 0xfa, 0xcc, 0xbf,
-+ 0xbd, 0xc7, 0xd1, 0x96, 0x20, 0xd1, 0xd3, 0x7f,
-+ 0x20, 0xd1, 0xd1, 0x57, 0xe2, 0xf2, 0x6c, 0xf2,
-+ 0xd1, 0xc7, 0x20, 0x81, 0xcc, 0x80, 0xe9, 0xd1,
-+ 0xbd, 0xe1, 0xbf, 0xfa, 0xd1, 0xab, 0xc2, 0x20,
-+ 0xbf, 0xc7, 0x96, 0xbf, 0xbf, 0xbd, 0x99, 0x54,
-+ 0xd1, 0xd1, 0x54, 0xc2, 0xfc, 0xd3, 0xd1, 0x57,
-+ 0x6e, 0xac, 0xfa, 0xbf, 0xbf, 0xbd, 0xc7, 0xd1,
-+ 0x9c, 0x20, 0xd1, 0xd1, 0xfa, 0x20, 0xd1, 0xd1,
-+ 0xc3, 0xd1, 0x9c, 0x20, 0x57, 0x4c, 0x6c, 0x9c,
-+ 0xd1, 0xc2, 0x57, 0xd1, 0xd3, 0xcf, 0x6e, 0x54,
-+ 0x20, 0xfa, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xab, 0x80, 0x20, 0x20, 0x20, 0xe2, 0xd3, 0xd1,
-+ 0xfa, 0x20, 0x7b, 0xd1, 0xd1, 0x6c, 0xc6, 0xd1,
-+ 0xda, 0x82, 0xd1, 0x99, 0x20, 0xd1, 0xd1, 0x7f,
-+ 0xe1, 0xd1, 0x9c, 0x59, 0xc3, 0xac, 0xfc, 0xe2,
-+ 0xd3, 0xfa, 0x80, 0xec, 0x99, 0x9a, 0x80, 0xd1,
-+ 0xfa, 0x20, 0xd1, 0x54, 0xd3, 0xd1, 0xfa, 0x20,
-+ 0xd3, 0x54, 0x6c, 0x81, 0x54, 0xfc, 0xc2, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xfd, 0xcc, 0xd1, 0xd3, 0xcc,
-+ 0x9a, 0xd1, 0x6c, 0xfd, 0xd1, 0xfc, 0xe2, 0x54,
-+ 0x7f, 0x20, 0xd1, 0xc3, 0x7f, 0xe1, 0xd3, 0xd1,
-+ 0xd1, 0xd3, 0xfa, 0x20, 0x6e, 0xd1, 0x6e, 0x82,
-+ 0xd1, 0xfd, 0xbf, 0xd1, 0xd1, 0xbf, 0x96, 0xd1,
-+ 0x99, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x20, 0xfa, 0xd1, 0x96, 0xcc, 0xec, 0xac,
-+ 0xfa, 0xe1, 0xd1, 0x54, 0x7f, 0x20, 0x99, 0xd1,
-+ 0x9c, 0x59, 0x54, 0x7f, 0x20, 0x54, 0xd1, 0x96,
-+ 0x20, 0x54, 0xfc, 0xcc, 0xd1, 0xe8, 0x57, 0xc2,
-+ 0xd1, 0xfa, 0xe1, 0xd3, 0x54, 0x9c, 0xe1, 0xd1,
-+ 0x7f, 0x20, 0xd1, 0xd1, 0xd1, 0x54, 0x7f, 0x20,
-+ 0xd1, 0x99, 0x20, 0x54, 0xd1, 0x9c, 0x59, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xab, 0x80, 0x9c, 0xfa, 0xbf,
-+ 0xd1, 0x7f, 0x20, 0xd1, 0x54, 0x9c, 0x80, 0xd1,
-+ 0xfa, 0x20, 0xd3, 0xd1, 0xfa, 0x20, 0xd3, 0xd1,
-+ 0xd3, 0xac, 0x7f, 0xe1, 0xab, 0xd1, 0x9a, 0x20,
-+ 0x54, 0xd3, 0x4c, 0x96, 0x96, 0x82, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xac, 0x80, 0x96, 0xd1, 0xd1, 0x9a, 0x80, 0xd1,
-+ 0x7f, 0x20, 0xd1, 0xd1, 0x7f, 0x20, 0xd1, 0x54,
-+ 0x9a, 0x59, 0xd1, 0x7f, 0x20, 0xd1, 0xd1, 0x7f,
-+ 0x20, 0xd1, 0xfd, 0x6c, 0x54, 0xe8, 0x6e, 0xe2,
-+ 0xab, 0x7f, 0x20, 0xd1, 0xd1, 0xc7, 0x20, 0xd1,
-+ 0xfa, 0xe1, 0xd3, 0x54, 0xd1, 0x54, 0xfa, 0x20,
-+ 0x54, 0x99, 0x20, 0x54, 0x54, 0x96, 0x80, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xec, 0x6e, 0x6e, 0x57,
-+ 0xd3, 0x7f, 0xe1, 0x54, 0xd1, 0xfa, 0x20, 0xd1,
-+ 0xfa, 0x80, 0xd1, 0x54, 0xfa, 0x20, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xfa, 0x80, 0x54, 0xd1, 0x9a, 0x80,
-+ 0xd1, 0xd1, 0xf2, 0xe9, 0xec, 0xcf, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x20, 0x7f, 0xd1, 0x54, 0xfd, 0x4c, 0xd1,
-+ 0xfa, 0x20, 0x54, 0xd1, 0x54, 0x6c, 0xc6, 0xd1,
-+ 0xda, 0xbd, 0x54, 0x7f, 0x20, 0x99, 0x99, 0xbd,
-+ 0x20, 0x54, 0x99, 0x59, 0xe9, 0xec, 0x6c, 0xf2,
-+ 0xe8, 0xc7, 0x20, 0xd1, 0xd1, 0xfa, 0x20, 0x54,
-+ 0x7f, 0x20, 0xd1, 0xd1, 0xd1, 0x54, 0x99, 0x20,
-+ 0xd3, 0xd1, 0x6c, 0xc6, 0xd1, 0xfc, 0xc2, 0xd1,
-+ 0xd1, 0xe8, 0x54, 0xd1, 0x9a, 0x4c, 0x59, 0xd3,
-+ 0xd1, 0xd1, 0x6c, 0xfd, 0xd1, 0xfc, 0xc2, 0xd1,
-+ 0x7f, 0x20, 0x7f, 0xc7, 0xc2, 0x20, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xfa, 0x20, 0xd1, 0xd1, 0x7b, 0xc2,
-+ 0xd1, 0x54, 0x96, 0x6c, 0x59, 0xc3, 0xd1, 0xd1,
-+ 0x99, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0x20, 0x6c, 0x6c, 0x80, 0x4c, 0x81, 0xd1,
-+ 0xfa, 0xe1, 0xd3, 0xd1, 0xd1, 0x96, 0xcc, 0xbf,
-+ 0x82, 0x7f, 0xd1, 0xd1, 0xc2, 0x80, 0xcc, 0xfd,
-+ 0xe1, 0xd1, 0xd1, 0xfa, 0xda, 0x81, 0xfc, 0xf2,
-+ 0xd1, 0xfa, 0x20, 0x54, 0x54, 0x7f, 0x20, 0xd1,
-+ 0x54, 0xc2, 0xbf, 0xab, 0xd3, 0xd1, 0xab, 0xc2,
-+ 0xbf, 0xc3, 0xfa, 0xbf, 0xbf, 0xbd, 0x99, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x6c, 0xec, 0xd3,
-+ 0xd1, 0xd1, 0x96, 0xcc, 0x6c, 0xbd, 0xc7, 0xd1,
-+ 0xd1, 0xf2, 0x80, 0x82, 0xcf, 0x20, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xfa, 0x20, 0xc2, 0xe2, 0xe2, 0xc3,
-+ 0xd1, 0xd1, 0x54, 0x6c, 0xec, 0xd1, 0xd1, 0xd1,
-+ 0x20, 0xfa, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xac, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0x54, 0xd1, 0xfa, 0x7f, 0xac, 0x9c, 0xbf, 0xcf,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd3, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0x54, 0xd1,
-+ 0xac, 0xd1, 0xab, 0xd1, 0x54, 0x59, 0x96, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xac, 0xac, 0xd1, 0xd3, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xe8, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0x59, 0xfa, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xfd, 0xbf, 0x20, 0x80, 0xe9, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0x54, 0xfd, 0xcc, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xfd, 0xcc, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xc7, 0x7f, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0x99, 0x7f, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0x54, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xe8, 0xab, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xac, 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xac, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x98, 0x98, 0x98, 0x98, 0x98, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x84, 0xdf,
-+ 0x84, 0x84, 0xd1, 0xe8, 0xb1, 0xd1, 0x84, 0xac,
-+ 0xac, 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x98, 0x98, 0xd1, 0xd1, 0xac, 0x84, 0xac, 0x84,
-+ 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0x98, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xac, 0xd1, 0xd1, 0xd1, 0xac,
-+ 0xdf, 0x84, 0xb1, 0xb1, 0x98, 0x7f, 0xfe, 0xed,
-+ 0xc7, 0xac, 0xd1, 0x98, 0xd1, 0xd1, 0xe8, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0x98, 0x98, 0x98,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x98, 0xd1, 0xd1, 0xd1, 0xac, 0xd1, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xd1, 0xd1, 0xd1,
-+ 0x98, 0xac, 0xac, 0xd1, 0xd1, 0xac, 0xd3, 0xd1,
-+ 0xac, 0xdf, 0x54, 0xac, 0xc7, 0x2e, 0xca, 0x70,
-+ 0x55, 0xac, 0xe8, 0xe8, 0xe8, 0xe8, 0x54, 0xe8,
-+ 0xe8, 0xb1, 0xe8, 0xb1, 0xe8, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xac, 0xac,
-+ 0xac, 0xac, 0xac, 0xd1, 0x98, 0x98, 0x98, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xac, 0x84,
-+ 0x84, 0x84, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x98, 0xd1, 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x98, 0x98, 0x98, 0x63, 0x98, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xac, 0xd1, 0xe8, 0xd1, 0xd1,
-+ 0x54, 0x84, 0xdf, 0x69, 0xed, 0xa8, 0x8b, 0x47,
-+ 0xb2, 0xe8, 0xd3, 0xe8, 0xd3, 0x54, 0xd3, 0x54,
-+ 0x54, 0xe8, 0xe8, 0xd1, 0xe8, 0xd1, 0xac, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xac, 0xac, 0xac, 0xd1, 0xac, 0xac, 0xac,
-+ 0x98, 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xac, 0xac, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0x84, 0xac, 0xac, 0xac, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x98, 0xd1, 0x98, 0xd1, 0xd1, 0xd1,
-+ 0xac, 0xd1, 0xd1, 0xd1, 0x98, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0x98, 0x98, 0xd1,
-+ 0x84, 0x84, 0xd1, 0xe8, 0xe8, 0xe8, 0xe8, 0xac,
-+ 0xd1, 0xd3, 0xdf, 0xbb, 0xe0, 0xce, 0x38, 0x47,
-+ 0x6d, 0x98, 0xab, 0xd3, 0xd3, 0xd3, 0xab, 0xab,
-+ 0xdf, 0xd3, 0xdf, 0xdf, 0xdf, 0x84, 0xac, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xe8, 0xb1, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xac,
-+ 0xac, 0x98, 0x98, 0x63, 0x84, 0x63, 0x84, 0x63,
-+ 0x84, 0x84, 0x63, 0x63, 0x98, 0x98, 0x98, 0xac,
-+ 0xac, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xac, 0x98, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xac, 0xac, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac,
-+ 0xac, 0xac, 0xac, 0x98, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0xd1, 0xac,
-+ 0xac, 0x84, 0xe8, 0xe8, 0xe8, 0xb1, 0xac, 0x84,
-+ 0x84, 0xdf, 0x8a, 0x37, 0x5c, 0x5c, 0x38, 0xd6,
-+ 0x55, 0xd3, 0xab, 0xc3, 0xc3, 0xab, 0xc3, 0xab,
-+ 0xab, 0x69, 0xdf, 0xdf, 0xdf, 0x84, 0xac, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0x98, 0x98,
-+ 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x84, 0xac, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xac, 0xac, 0x98, 0x98, 0xac, 0xd1, 0xd1, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0xd1, 0xd1, 0xac,
-+ 0x84, 0x54, 0xe8, 0xb1, 0xe8, 0xac, 0x84, 0x5b,
-+ 0xb0, 0x93, 0x71, 0x2e, 0x70, 0x47, 0x5c, 0x2e,
-+ 0xd0, 0x99, 0x99, 0x99, 0x99, 0x99, 0xa9, 0xc3,
-+ 0xc3, 0x69, 0xc3, 0xdf, 0xdf, 0xdf, 0xb1, 0xb1,
-+ 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xe8, 0xe8,
-+ 0xe8, 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x98, 0x98, 0x98, 0x98, 0x98, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xac, 0xac, 0xac,
-+ 0xd1, 0xd1, 0xac, 0x98, 0x98, 0xac, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x98, 0x98, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xe8, 0xb1, 0xd1, 0xe8, 0xdf, 0x55, 0xed,
-+ 0x6d, 0x26, 0x4f, 0x24, 0x47, 0x21, 0x73, 0x21,
-+ 0xc7, 0x99, 0x99, 0x99, 0xba, 0xba, 0xba, 0xba,
-+ 0x99, 0x99, 0x69, 0x69, 0xab, 0xb1, 0xb1, 0xb1,
-+ 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0xd1,
-+ 0xac, 0xac, 0xac, 0xac, 0xac, 0xd1, 0xd1, 0xe8,
-+ 0xe8, 0xe8, 0xe8, 0xb1, 0xe8, 0xe8, 0xe8, 0xe8,
-+ 0xe8, 0xe8, 0xb1, 0xe8, 0xe8, 0xe8, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xac, 0xac,
-+ 0xac, 0x98, 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0xd1,
-+ 0x98, 0x98, 0xd1, 0x98, 0xd1, 0x98, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xac, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xac, 0xac, 0xd1, 0xac, 0xd1, 0xe8,
-+ 0xe8, 0xe8, 0xe8, 0xd1, 0x98, 0xac, 0x54, 0xd1,
-+ 0x54, 0x98, 0x98, 0x63, 0x98, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xe8, 0xd1, 0x84, 0xb2, 0x61, 0xa3,
-+ 0x26, 0x9d, 0x4f, 0xd8, 0xd7, 0xca, 0x21, 0x71,
-+ 0x99, 0xba, 0x7f, 0x7f, 0x7f, 0x7f, 0xfa, 0xba,
-+ 0xba, 0xba, 0xba, 0x99, 0xc3, 0xa9, 0xb1, 0xb1,
-+ 0xb1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac,
-+ 0x98, 0xac, 0xac, 0x98, 0x98, 0x98, 0x98, 0x98,
-+ 0x98, 0xd1, 0xe8, 0x98, 0xe8, 0xe8, 0xe8, 0xe8,
-+ 0xe8, 0xe8, 0x98, 0xe8, 0xe8, 0x98, 0xe8, 0x98,
-+ 0xe8, 0x98, 0x98, 0xac, 0xac, 0x84, 0x98, 0xac,
-+ 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98,
-+ 0xac, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xac, 0xd1, 0xd1, 0x98, 0x98, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xac, 0x84, 0xd1, 0xd1, 0xd1, 0xa9, 0xe8,
-+ 0xb1, 0xb1, 0xb1, 0xe8, 0x98, 0x54, 0xd1, 0x98,
-+ 0x98, 0x98, 0x63, 0x98, 0x98, 0xd3, 0x54, 0xd1,
-+ 0xe8, 0xd3, 0xac, 0xdf, 0xb2, 0xa8, 0x26, 0x9d,
-+ 0x9d, 0xd7, 0xd7, 0x9d, 0x8b, 0x24, 0xa8, 0x71,
-+ 0xfa, 0x7f, 0xc7, 0xd0, 0x5a, 0x9c, 0xfa, 0x9c,
-+ 0xfa, 0xba, 0xba, 0x99, 0xa9, 0xb1, 0xa9, 0xb1,
-+ 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xac, 0xac, 0xac, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0x63, 0x63, 0x63,
-+ 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-+ 0xef, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
-+ 0x63, 0x63, 0x63, 0x98, 0x98, 0x98, 0xd1, 0xe8,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xac, 0xac, 0xac, 0xac, 0x98,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xac, 0xab, 0xd1, 0xd1, 0xb1, 0xe8, 0x74, 0x86,
-+ 0xa6, 0xa6, 0x94, 0x63, 0xe8, 0x63, 0xab, 0xd1,
-+ 0xd1, 0xd3, 0xb1, 0xe8, 0xe8, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0x84, 0x55, 0x70, 0x26, 0x9d, 0x9d,
-+ 0xd7, 0xce, 0xd7, 0xce, 0xce, 0x24, 0x24, 0x93,
-+ 0xfe, 0x5a, 0x55, 0x2b, 0xa8, 0x60, 0xbb, 0x96,
-+ 0x9c, 0x74, 0xfa, 0xba, 0xba, 0xab, 0xab, 0xd3,
-+ 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xac, 0xac, 0xac, 0xd1, 0xd1, 0xd1, 0xe8, 0xe8,
-+ 0xe8, 0xe8, 0xe8, 0x63, 0x63, 0x63, 0x63, 0x3f,
-+ 0x3f, 0x3f, 0x8f, 0x76, 0x6f, 0x92, 0x65, 0x65,
-+ 0x58, 0x58, 0x40, 0xc0, 0x64, 0xdd, 0x78, 0x78,
-+ 0xdd, 0xa0, 0x78, 0xdd, 0xc0, 0x40, 0xc0, 0x74,
-+ 0x58, 0x58, 0x65, 0x92, 0x76, 0x8f, 0x3f, 0x63,
-+ 0x3f, 0x63, 0x3f, 0x63, 0x63, 0xe8, 0xd1, 0xe8,
-+ 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x98, 0xd1, 0x98, 0xd1, 0xd1, 0xac,
-+ 0xd1, 0xd1, 0xab, 0xe8, 0xa9, 0xa6, 0x3c, 0x75,
-+ 0xf3, 0x86, 0x75, 0x53, 0x94, 0xab, 0xac, 0x54,
-+ 0xd3, 0xe8, 0xd1, 0xe8, 0xd3, 0xd3, 0x54, 0x54,
-+ 0x63, 0xdf, 0x5a, 0xd6, 0x56, 0x26, 0xce, 0x2f,
-+ 0xd7, 0xce, 0x2f, 0xb6, 0x2f, 0xce, 0x8b, 0xca,
-+ 0xa2, 0xa2, 0x37, 0x61, 0xca, 0xca, 0x87, 0xfc,
-+ 0x94, 0x94, 0xfa, 0xfa, 0xc7, 0x99, 0x69, 0x69,
-+ 0xd3, 0xd3, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xb1, 0xb1, 0xb1,
-+ 0xb1, 0xe8, 0x8f, 0x76, 0x6f, 0x49, 0x48, 0x48,
-+ 0xdd, 0xdd, 0xdd, 0xf5, 0xa0, 0xd4, 0x79, 0x79,
-+ 0x79, 0x79, 0x79, 0x79, 0xd4, 0xd4, 0xd4, 0xd4,
-+ 0xd4, 0xd4, 0xd4, 0x79, 0x79, 0xd4, 0xd4, 0x79,
-+ 0xa0, 0xa0, 0xd4, 0xa0, 0xa0, 0xa0, 0xa0, 0xdd,
-+ 0xd5, 0x48, 0x49, 0x6f, 0x6f, 0x88, 0xb1, 0xb1,
-+ 0xe8, 0xb1, 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xd1, 0xd1, 0xac,
-+ 0x54, 0xd1, 0xe8, 0xa9, 0xa6, 0xe6, 0xf3, 0xd2,
-+ 0xd2, 0x79, 0xb4, 0x72, 0x7d, 0xda, 0x63, 0xab,
-+ 0xab, 0xab, 0x99, 0xa9, 0xe8, 0xc3, 0xc3, 0x98,
-+ 0xc3, 0x52, 0xa2, 0x26, 0x9d, 0xce, 0xce, 0xd7,
-+ 0xce, 0xb6, 0x2f, 0xce, 0x2f, 0xce, 0x2f, 0xd7,
-+ 0xa8, 0x21, 0xca, 0x8b, 0x8b, 0xe0, 0xd6, 0x55,
-+ 0x9a, 0x9a, 0x9c, 0xfa, 0x5b, 0x5b, 0x69, 0xc3,
-+ 0xab, 0xd3, 0xd3, 0x54, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x98, 0x63, 0x63, 0x63, 0xe8, 0x63, 0x8f, 0x88,
-+ 0x92, 0x65, 0x58, 0xc0, 0xdd, 0xa0, 0xa0, 0xd4,
-+ 0x30, 0x9b, 0x30, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0x9b, 0x9b, 0x9b, 0x9b, 0x30, 0x9b, 0x9b, 0x9b,
-+ 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0x9b, 0x9b, 0x9b, 0x30, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0x79, 0x79, 0xa0, 0xa0, 0xc0, 0x40, 0x58, 0x65,
-+ 0x76, 0x8f, 0x8f, 0x63, 0xe8, 0xe8, 0xe8, 0x98,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xac,
-+ 0xd1, 0xd1, 0xb1, 0xf3, 0xe6, 0x75, 0x3b, 0x3b,
-+ 0xb9, 0xb9, 0xaf, 0x75, 0x7d, 0xc2, 0x8a, 0x99,
-+ 0xc3, 0xab, 0xb1, 0x99, 0xa9, 0xe8, 0xdf, 0x63,
-+ 0xdf, 0x4b, 0x24, 0x26, 0xd8, 0xd7, 0x24, 0xce,
-+ 0x2f, 0x9d, 0xd7, 0xce, 0xce, 0x2f, 0xce, 0xb6,
-+ 0x8b, 0xd6, 0x47, 0x38, 0x5c, 0x37, 0xed, 0x55,
-+ 0x81, 0x9a, 0x9a, 0x9c, 0xfa, 0x7f, 0xc7, 0x69,
-+ 0xab, 0xab, 0xd3, 0x54, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x63, 0x63, 0x3f, 0x3f, 0x6f, 0x48, 0x40, 0xdd,
-+ 0xa0, 0xd4, 0xd4, 0xd4, 0x30, 0x30, 0x30, 0xd4,
-+ 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0x30, 0x30, 0x30, 0x9b, 0x30, 0x9b, 0x9b, 0x9b,
-+ 0x9b, 0x9b, 0x9b, 0x30, 0x9b, 0x30, 0x9b, 0x9b,
-+ 0x30, 0x9b, 0x9b, 0x30, 0x30, 0x9b, 0x9b, 0x9b,
-+ 0x9b, 0x9b, 0x30, 0x30, 0x30, 0xd4, 0xd4, 0xa0,
-+ 0xa0, 0xc0, 0xd5, 0x6f, 0xef, 0x3f, 0x3f, 0x63,
-+ 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xac,
-+ 0xd3, 0xe8, 0xb1, 0xf7, 0x75, 0x3b, 0x3b, 0x3b,
-+ 0x3b, 0x62, 0xaf, 0xe6, 0x6f, 0x9c, 0xb8, 0xb0,
-+ 0x9a, 0xfa, 0xc3, 0xb1, 0xba, 0x99, 0xb1, 0x99,
-+ 0x55, 0x37, 0xa3, 0xd7, 0xd8, 0xd7, 0x9d, 0xd7,
-+ 0xd7, 0x2f, 0x2f, 0xce, 0xd8, 0xb6, 0xd7, 0xd8,
-+ 0xd8, 0x47, 0x70, 0x47, 0x70, 0xd6, 0xdc, 0x57,
-+ 0xfd, 0x81, 0x9a, 0x96, 0xd0, 0xfa, 0x7f, 0xba,
-+ 0x99, 0xc3, 0xab, 0xd3, 0x54, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0x63, 0x63, 0x3f,
-+ 0x88, 0x92, 0xc0, 0xdd, 0x78, 0xa0, 0xa0, 0xa0,
-+ 0xd4, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0x30, 0xd4, 0x30, 0xd4, 0xd4,
-+ 0xd4, 0xd4, 0xa0, 0x79, 0xa0, 0xa0, 0x78, 0xa0,
-+ 0xa0, 0xa0, 0x79, 0xa0, 0xd4, 0xa0, 0xd4, 0xd4,
-+ 0xd4, 0x9b, 0x30, 0x9b, 0x9b, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0x30, 0x9b, 0x9b, 0x9b, 0xd4,
-+ 0xd4, 0xa0, 0x79, 0x78, 0x78, 0xdd, 0x65, 0x6f,
-+ 0x3f, 0x3f, 0x63, 0x63, 0x98, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xd1, 0xd1,
-+ 0xd1, 0xb1, 0xba, 0xa4, 0xf3, 0x3b, 0x3b, 0x3b,
-+ 0xe4, 0xb9, 0xe4, 0x91, 0x65, 0x5f, 0x42, 0x33,
-+ 0xf1, 0x5f, 0x95, 0x96, 0xba, 0x99, 0x99, 0x5a,
-+ 0x2e, 0x37, 0x2b, 0x24, 0xce, 0x24, 0x24, 0x24,
-+ 0xd7, 0xd6, 0x8b, 0xce, 0xd7, 0xd7, 0xd8, 0xd8,
-+ 0x8b, 0xd7, 0x2e, 0x61, 0xd6, 0x4b, 0x57, 0xcf,
-+ 0x57, 0xfd, 0x55, 0x9a, 0x9a, 0x9c, 0x74, 0xba,
-+ 0xba, 0x99, 0xab, 0xd3, 0x54, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0x84, 0xac,
-+ 0xac, 0xd1, 0xd1, 0x98, 0x98, 0xd1, 0xac, 0x84,
-+ 0xac, 0xac, 0x98, 0x63, 0x3f, 0x88, 0x65, 0xdd,
-+ 0xf5, 0xf5, 0xe4, 0xd4, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0x9b, 0x9b, 0x9b, 0x9b, 0x30, 0x9b, 0x30, 0xf5,
-+ 0xa0, 0x78, 0x9f, 0x78, 0xb5, 0xb5, 0xb4, 0x34,
-+ 0x5d, 0x5d, 0x5d, 0x8a, 0xcf, 0x39, 0xcf, 0x39,
-+ 0xb2, 0x39, 0x8a, 0x8a, 0x5d, 0x5d, 0xb4, 0xb4,
-+ 0xb5, 0x66, 0xaf, 0xa0, 0xa0, 0xd4, 0xe4, 0x30,
-+ 0x9b, 0x9b, 0x9b, 0x30, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0xd4, 0xd4, 0x79, 0xd4, 0xa0, 0xa0, 0xf5, 0xa0,
-+ 0xc0, 0xd5, 0xef, 0x3f, 0x63, 0x63, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xac, 0xd1, 0xac,
-+ 0xac, 0x84, 0xdf, 0x84, 0xac, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xdf, 0xdf, 0xac, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xb1, 0x94, 0xe6, 0x3b, 0x3b, 0x3b, 0x62,
-+ 0x62, 0xe4, 0x3c, 0xb8, 0x9c, 0x32, 0x42, 0x35,
-+ 0x35, 0x35, 0xc5, 0xa5, 0x95, 0xbe, 0x7f, 0x4a,
-+ 0x2b, 0x47, 0x22, 0x8b, 0xd7, 0x9d, 0xca, 0x47,
-+ 0xd6, 0x38, 0x2f, 0x2f, 0xd7, 0xce, 0xd8, 0xd8,
-+ 0xd8, 0x5c, 0x70, 0x71, 0xbc, 0x7b, 0xfc, 0x86,
-+ 0xda, 0xaa, 0xfd, 0x81, 0x9a, 0x96, 0x9c, 0xba,
-+ 0xba, 0x99, 0xc3, 0xab, 0xd3, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0xd1, 0xd1, 0x98,
-+ 0x98, 0x3f, 0x3f, 0x6f, 0x58, 0xf9, 0xf5, 0xf5,
-+ 0x30, 0x30, 0x9b, 0x30, 0x9b, 0x9b, 0x9b, 0xf5,
-+ 0xd4, 0xa0, 0xa0, 0xa0, 0x9f, 0xaf, 0xb4, 0x43,
-+ 0x43, 0x39, 0x8e, 0x95, 0x4b, 0x4b, 0x4b, 0x4b,
-+ 0xbb, 0xfe, 0xbb, 0xbc, 0xbc, 0x44, 0x44, 0xbc,
-+ 0xbc, 0xbc, 0xbc, 0xfe, 0xbb, 0xbb, 0xbb, 0x4b,
-+ 0xec, 0xc4, 0x7b, 0xb8, 0x86, 0x43, 0x72, 0xb4,
-+ 0xb4, 0xaf, 0x78, 0xa0, 0xa0, 0xa0, 0xd4, 0x79,
-+ 0x9b, 0x9b, 0xf5, 0x9b, 0x9b, 0x30, 0x9b, 0x9b,
-+ 0x9b, 0xd4, 0xa0, 0xc0, 0x65, 0x88, 0x63, 0x63,
-+ 0x98, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xac, 0x84, 0xac, 0xac, 0xac, 0xac,
-+ 0x84, 0x84, 0xac, 0x84, 0xac, 0xd1, 0xe8, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0xdf, 0xdf, 0x84, 0xd1, 0xe8, 0xb1,
-+ 0xd1, 0xe8, 0xd2, 0xe6, 0x3b, 0x3b, 0x3b, 0x62,
-+ 0xe4, 0xf9, 0xc4, 0x85, 0x5a, 0xbe, 0xa5, 0x2a,
-+ 0x7e, 0x7e, 0x7e, 0x7e, 0x25, 0x7a, 0x31, 0x23,
-+ 0x4f, 0xd8, 0x47, 0xe0, 0x9d, 0x70, 0xd6, 0x22,
-+ 0x8b, 0xd7, 0xce, 0x2f, 0xd7, 0xd7, 0xd8, 0xd7,
-+ 0xd7, 0xd8, 0xe0, 0x2e, 0xde, 0xde, 0xa6, 0xfc,
-+ 0xfc, 0x57, 0xcf, 0xc6, 0x81, 0x9a, 0x9c, 0xfa,
-+ 0x7f, 0x99, 0xc3, 0xc3, 0xd3, 0xd3, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xac,
-+ 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0x3f,
-+ 0xef, 0xd5, 0xdd, 0xf5, 0x30, 0x30, 0x30, 0x9b,
-+ 0x9b, 0x9b, 0x9b, 0xd4, 0xd4, 0x79, 0x78, 0xb5,
-+ 0xb5, 0x5d, 0xb2, 0x8e, 0x51, 0x4b, 0x7c, 0xbc,
-+ 0xae, 0x44, 0x44, 0x44, 0x44, 0x8d, 0x8d, 0x44,
-+ 0xff, 0xff, 0xcd, 0xff, 0xff, 0xff, 0xff, 0x77,
-+ 0xae, 0xff, 0x77, 0xcd, 0xcd, 0xcd, 0xcd, 0xae,
-+ 0xae, 0xae, 0x44, 0x44, 0x44, 0x44, 0xbc, 0xbc,
-+ 0xfb, 0x4b, 0x9e, 0xb0, 0x8a, 0x34, 0xb5, 0xdd,
-+ 0xa0, 0x9b, 0x9b, 0x30, 0x9b, 0x9b, 0x9b, 0x9b,
-+ 0x30, 0x30, 0xd4, 0xe4, 0xe4, 0xf9, 0xd5, 0x6f,
-+ 0x3f, 0x3f, 0x63, 0x98, 0xd1, 0xd1, 0xe8, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0x98, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x84, 0xdf, 0xac, 0xd1, 0xd1, 0xe8,
-+ 0xd1, 0xb1, 0x94, 0xe6, 0x3b, 0xe4, 0x62, 0x62,
-+ 0xaf, 0xa5, 0xc4, 0xb7, 0xb0, 0x81, 0x36, 0xc4,
-+ 0x3e, 0x3e, 0x29, 0xc9, 0x2d, 0x2a, 0x25, 0x7a,
-+ 0x4a, 0xfb, 0xca, 0x4f, 0xca, 0x47, 0xd8, 0xd7,
-+ 0x2b, 0xd8, 0xd7, 0xd8, 0xd7, 0xd7, 0xce, 0xce,
-+ 0xb6, 0xd8, 0xca, 0x2e, 0x4b, 0xec, 0xec, 0xe9,
-+ 0xfc, 0xda, 0xb2, 0xfd, 0xaa, 0x81, 0x96, 0x9c,
-+ 0x7f, 0xc7, 0x99, 0xc3, 0xab, 0x54, 0x54, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0x98, 0x98, 0x63, 0x98, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xb1,
-+ 0xd1, 0xe8, 0xb1, 0xe8, 0xe8, 0x3f, 0x6f, 0x58,
-+ 0xf5, 0xd4, 0x9b, 0x9b, 0x9b, 0xd4, 0xd4, 0xa0,
-+ 0x79, 0x78, 0x78, 0xb5, 0xb4, 0x43, 0xb8, 0x4b,
-+ 0xfe, 0xbc, 0x44, 0xae, 0x8d, 0x77, 0x77, 0xa7,
-+ 0xa7, 0xa7, 0x77, 0xa7, 0x77, 0xcd, 0xff, 0xa7,
-+ 0xa7, 0xcd, 0x77, 0xff, 0x77, 0xcd, 0xa7, 0x77,
-+ 0x77, 0x77, 0x77, 0x77, 0x77, 0xa7, 0x77, 0x77,
-+ 0xa7, 0xa7, 0x77, 0x77, 0x77, 0x77, 0x77, 0xa7,
-+ 0xcd, 0xff, 0x8d, 0x44, 0xbc, 0xbb, 0x4b, 0x95,
-+ 0x36, 0x72, 0x78, 0xa0, 0xa0, 0x79, 0x9b, 0xd4,
-+ 0x30, 0x30, 0x9b, 0x9b, 0x30, 0x30, 0xd4, 0xdd,
-+ 0x40, 0x49, 0x3f, 0x3f, 0x3f, 0xe8, 0xe8, 0xe8,
-+ 0xd1, 0xd1, 0x98, 0x98, 0xe8, 0xe8, 0xe8, 0xd1,
-+ 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0xd1, 0xac, 0x84,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0xac, 0xdf, 0xac, 0xd1, 0xe8, 0xe8,
-+ 0xd1, 0xd1, 0xba, 0x53, 0xd2, 0xd2, 0xaf, 0xf9,
-+ 0x43, 0xc4, 0xaa, 0xa5, 0x4c, 0xec, 0xaa, 0xa6,
-+ 0x91, 0x36, 0x5e, 0xc5, 0x3e, 0xc9, 0x2d, 0x2a,
-+ 0x85, 0xa2, 0x4a, 0xfb, 0x2b, 0x9d, 0xd8, 0x8b,
-+ 0xd7, 0xd7, 0x24, 0xd8, 0xd8, 0xb6, 0x2f, 0x2f,
-+ 0xce, 0xce, 0xca, 0x60, 0x4b, 0x4b, 0x4b, 0xe9,
-+ 0xe9, 0xde, 0xda, 0xcf, 0xfd, 0xaa, 0x9a, 0x96,
-+ 0xfa, 0x7f, 0x99, 0x99, 0xab, 0xd3, 0x54, 0x54,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x98, 0x98, 0x98, 0x98, 0xd1, 0xd1,
-+ 0x54, 0xac, 0xac, 0xac, 0x98, 0xd1, 0xe8, 0xe8,
-+ 0xd1, 0xd1, 0x63, 0x3f, 0x6f, 0x58, 0xdd, 0x30,
-+ 0xe4, 0xe4, 0x30, 0x30, 0xd4, 0xa0, 0x3e, 0x9f,
-+ 0x42, 0xb2, 0x9e, 0xbb, 0xbc, 0xbc, 0x44, 0xcd,
-+ 0xcd, 0xcd, 0xa7, 0x77, 0xff, 0xa7, 0x77, 0xff,
-+ 0xff, 0xcd, 0xff, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
-+ 0xcd, 0x8d, 0xcd, 0x44, 0x8d, 0x44, 0x44, 0x8d,
-+ 0x8d, 0x8d, 0xcd, 0xcd, 0xff, 0xcd, 0xcd, 0xa7,
-+ 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
-+ 0x77, 0x77, 0xcd, 0xff, 0xcd, 0xcd, 0x8d, 0x44,
-+ 0x44, 0xbc, 0x4b, 0xde, 0x39, 0x5d, 0x66, 0x9f,
-+ 0xf5, 0xd4, 0x30, 0x9b, 0x9b, 0x30, 0x30, 0x62,
-+ 0x30, 0xf5, 0xc0, 0x48, 0x88, 0x3f, 0xe8, 0xe8,
-+ 0x84, 0x84, 0xe8, 0xe8, 0xe8, 0xe8, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0xac, 0xdf, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x84, 0xac, 0x98, 0xa6, 0xa6, 0xaf, 0xe6, 0x7d,
-+ 0x31, 0x4c, 0x9a, 0x94, 0xfd, 0xc2, 0x6c, 0x57,
-+ 0xfd, 0x7d, 0x31, 0x36, 0x25, 0x29, 0xc5, 0x2a,
-+ 0x2d, 0x2d, 0xf1, 0xa2, 0x23, 0x24, 0xd7, 0xce,
-+ 0xd7, 0xd7, 0xd8, 0xd7, 0xd7, 0xd7, 0x2f, 0x2f,
-+ 0x2f, 0xb6, 0xca, 0xa8, 0x93, 0xbb, 0x4b, 0xfb,
-+ 0x9e, 0xde, 0xda, 0xda, 0xfd, 0xaa, 0x9a, 0xd0,
-+ 0xfa, 0x7f, 0x99, 0x99, 0xc3, 0xd3, 0x54, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x98, 0x98, 0x98, 0xd1, 0xe8, 0xe8,
-+ 0x54, 0x84, 0xdf, 0x84, 0x84, 0x98, 0xd1, 0xe8,
-+ 0x63, 0x3f, 0x76, 0x58, 0xdd, 0x79, 0x30, 0x9b,
-+ 0x30, 0xd4, 0xd4, 0xa0, 0x5e, 0x72, 0x57, 0x4b,
-+ 0xbb, 0xbc, 0xbc, 0x44, 0xae, 0xff, 0x77, 0xa7,
-+ 0xa7, 0x77, 0xa7, 0xcd, 0xcd, 0xae, 0x50, 0xee,
-+ 0xee, 0xee, 0x6d, 0x83, 0xeb, 0xdb, 0xea, 0x4d,
-+ 0xad, 0xad, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a,
-+ 0xad, 0x4d, 0x4d, 0xdb, 0xdb, 0x83, 0x6d, 0x6d,
-+ 0xee, 0xee, 0xc1, 0xc1, 0xff, 0x77, 0xa7, 0xcd,
-+ 0x77, 0xcd, 0x77, 0x77, 0x77, 0xa7, 0x77, 0x77,
-+ 0xa7, 0xcd, 0xcd, 0x44, 0x87, 0xfe, 0x6e, 0xb8,
-+ 0x43, 0xb4, 0x78, 0xa0, 0xd4, 0x9b, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0xdd, 0xc0, 0x92, 0x76, 0x63,
-+ 0x98, 0xac, 0xd1, 0xe8, 0xe8, 0xd1, 0xe8, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xe8, 0xe8, 0xd1, 0xac, 0x98,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xe8, 0xd1, 0xac, 0xac, 0xd1, 0xe8, 0xd1,
-+ 0x84, 0x84, 0x98, 0x99, 0x3c, 0x72, 0x91, 0x49,
-+ 0x7f, 0x81, 0x5d, 0x81, 0x9a, 0x81, 0x57, 0xbd,
-+ 0xec, 0xaa, 0xc4, 0xf4, 0x32, 0x36, 0x25, 0xc5,
-+ 0xc9, 0x2a, 0x2d, 0x2a, 0x73, 0x70, 0xd7, 0xce,
-+ 0xce, 0xce, 0xd7, 0xd7, 0xce, 0x2f, 0x2f, 0x2f,
-+ 0x2f, 0xd7, 0x24, 0xe0, 0x21, 0xd6, 0xd6, 0xd6,
-+ 0x2e, 0x82, 0xe9, 0xda, 0xcf, 0xc6, 0x81, 0x9a,
-+ 0x9c, 0x7f, 0xc7, 0x99, 0xab, 0xab, 0x54, 0x54,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xac, 0x63, 0x63, 0x98, 0x98, 0x8f,
-+ 0xef, 0xd5, 0xa0, 0x79, 0xd4, 0x9b, 0x9b, 0xd4,
-+ 0xa0, 0x9f, 0x5d, 0xb0, 0x4b, 0x7c, 0xae, 0xae,
-+ 0xae, 0xff, 0xcd, 0xcd, 0xcd, 0xcd, 0x44, 0x50,
-+ 0x50, 0xee, 0x6d, 0xeb, 0xea, 0x5a, 0x5b, 0x5b,
-+ 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf,
-+ 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0x84, 0x84,
-+ 0x84, 0xac, 0x84, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf,
-+ 0x52, 0x52, 0x69, 0x5a, 0xd0, 0xdb, 0x83, 0xdc,
-+ 0x7c, 0x50, 0x8d, 0xff, 0x77, 0xa7, 0x77, 0x77,
-+ 0x77, 0xa7, 0xa7, 0xcd, 0x50, 0xff, 0x44, 0x44,
-+ 0xfe, 0x51, 0xb0, 0x8a, 0xb5, 0x78, 0xd4, 0x30,
-+ 0x30, 0x9b, 0x9b, 0xd4, 0x79, 0xdd, 0x40, 0x48,
-+ 0x8f, 0x63, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0x63,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0x98,
-+ 0x84, 0x84, 0x63, 0x54, 0xba, 0x7d, 0x6c, 0x57,
-+ 0xc7, 0x9a, 0x9c, 0x9a, 0xc6, 0xc6, 0xcf, 0xfd,
-+ 0xfc, 0xc2, 0x7d, 0xf4, 0xf6, 0xf4, 0x41, 0x36,
-+ 0x25, 0x3e, 0xc5, 0x2a, 0x6b, 0x22, 0x9d, 0xd7,
-+ 0x2f, 0xd7, 0xd7, 0xd7, 0x9d, 0x9d, 0x2f, 0x2f,
-+ 0xd7, 0xd7, 0xd8, 0x24, 0xd6, 0xe0, 0xfb, 0x24,
-+ 0x7c, 0x60, 0x51, 0x7b, 0x57, 0xcf, 0x81, 0x9a,
-+ 0x96, 0xfa, 0x7f, 0x99, 0xc3, 0xab, 0x54, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x98, 0x98, 0xac, 0x84, 0xac, 0xd1, 0xd1, 0xe8,
-+ 0xe8, 0xd1, 0x98, 0x98, 0x63, 0x63, 0x8f, 0x6f,
-+ 0xdd, 0xa0, 0xa0, 0xd4, 0xe4, 0x79, 0x78, 0xb5,
-+ 0x39, 0xe5, 0xbb, 0x44, 0xff, 0xcd, 0xcd, 0xcd,
-+ 0xcd, 0xcd, 0x44, 0x50, 0xee, 0x83, 0xea, 0xad,
-+ 0x69, 0x52, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0x84,
-+ 0xac, 0xac, 0xac, 0x84, 0x84, 0x84, 0x84, 0x84,
-+ 0x84, 0x84, 0x84, 0xac, 0xac, 0xac, 0xac, 0xd1,
-+ 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0xac, 0x84, 0x84,
-+ 0xac, 0x84, 0xdf, 0x84, 0x84, 0x63, 0xdf, 0xdf,
-+ 0x52, 0x5b, 0xad, 0xeb, 0x6d, 0xee, 0xff, 0xa7,
-+ 0xa7, 0x77, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
-+ 0xcd, 0x8d, 0x8d, 0xbc, 0x4b, 0xb0, 0xb4, 0x78,
-+ 0xa0, 0x30, 0x9b, 0x9b, 0x9b, 0x30, 0xd4, 0xf5,
-+ 0x58, 0x76, 0x3f, 0x63, 0x84, 0x84, 0x84, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0x98,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xe8, 0xac, 0xac, 0x98, 0xd1, 0x98, 0xd1,
-+ 0x98, 0xdf, 0xd3, 0xe8, 0xe8, 0x92, 0x81, 0x90,
-+ 0x9c, 0xfa, 0x81, 0x9a, 0xc6, 0xfd, 0xfd, 0xb2,
-+ 0xcf, 0xda, 0xc2, 0xf6, 0xa4, 0xa4, 0x46, 0x3c,
-+ 0xb9, 0x25, 0xc5, 0xf0, 0xa2, 0xca, 0x24, 0xd7,
-+ 0xce, 0x2f, 0xce, 0xce, 0x2f, 0xb6, 0xce, 0xce,
-+ 0xce, 0xce, 0xd7, 0xd7, 0xd6, 0x5c, 0xe0, 0x61,
-+ 0x73, 0xed, 0xde, 0xfc, 0x57, 0xcf, 0xc6, 0x9a,
-+ 0x96, 0x9c, 0x7f, 0x99, 0x99, 0xab, 0xd3, 0xd3,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0x98, 0xd1, 0x84, 0x84, 0xac, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0x98, 0x63, 0x3f, 0x6f, 0xc0, 0x79,
-+ 0xe4, 0x9b, 0xf5, 0x78, 0x9f, 0x43, 0xfc, 0xbc,
-+ 0x50, 0xae, 0x77, 0x77, 0xcd, 0xcd, 0x44, 0x7c,
-+ 0x51, 0xeb, 0xd0, 0x69, 0xdf, 0xdf, 0xdf, 0xdf,
-+ 0xac, 0xac, 0xd1, 0xd1, 0xac, 0xac, 0xac, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xac, 0xac, 0xd1, 0xac, 0xac, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x84, 0xdf, 0xdf, 0xdf, 0xdf, 0x52, 0x5b, 0xad,
-+ 0x83, 0x51, 0x50, 0xa7, 0x77, 0xa7, 0x77, 0xa7,
-+ 0x77, 0xa7, 0x77, 0xff, 0xae, 0x8d, 0xa8, 0x9e,
-+ 0x39, 0xb4, 0xa0, 0x30, 0x30, 0x30, 0x30, 0x30,
-+ 0xe4, 0xe4, 0x58, 0x3f, 0x63, 0x84, 0x84, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xac, 0xac, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xd1,
-+ 0xac, 0x84, 0xdf, 0xd3, 0xd3, 0xc3, 0x99, 0x5b,
-+ 0xfa, 0x96, 0x81, 0x81, 0xaa, 0xcf, 0xfd, 0xb2,
-+ 0xb2, 0xda, 0xe1, 0x46, 0x3a, 0x3a, 0x3a, 0x46,
-+ 0xf6, 0x41, 0x33, 0x6b, 0xa2, 0x24, 0xd8, 0xd7,
-+ 0xd7, 0xce, 0x2f, 0xce, 0xce, 0xce, 0xd7, 0xd7,
-+ 0xd8, 0xd7, 0xd7, 0xb6, 0x38, 0xd6, 0xa8, 0xed,
-+ 0xed, 0x4b, 0x4b, 0xde, 0xda, 0xcf, 0xfd, 0x81,
-+ 0x9a, 0xfa, 0xfa, 0x99, 0x99, 0xc3, 0xd3, 0x54,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x98, 0xd1, 0xac, 0xac, 0xac, 0xd1, 0xd1,
-+ 0xd1, 0x63, 0x3f, 0x88, 0xd5, 0xf9, 0x79, 0xd4,
-+ 0xf5, 0x78, 0xaf, 0x43, 0x7b, 0xbb, 0x8d, 0xae,
-+ 0x77, 0xa7, 0x77, 0xff, 0xee, 0x83, 0x4d, 0x5b,
-+ 0xdf, 0xdf, 0x84, 0xdf, 0xdf, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98,
-+ 0xd1, 0x98, 0xd1, 0xd1, 0xd1, 0xe8, 0xe8, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xab,
-+ 0x52, 0x52, 0x5b, 0xdb, 0x6d, 0xee, 0xff, 0xc1,
-+ 0xa7, 0x77, 0xc1, 0x77, 0xa7, 0x77, 0x77, 0x8d,
-+ 0x7c, 0x8e, 0x57, 0xb4, 0xa0, 0xd4, 0x30, 0x30,
-+ 0x30, 0xf5, 0xa0, 0xc0, 0xef, 0x3f, 0x63, 0x98,
-+ 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0xac, 0xac, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xac, 0xd1, 0xd1, 0x98, 0xd1, 0x98,
-+ 0xac, 0x54, 0xe8, 0xd3, 0xa9, 0xa9, 0xc7, 0xc7,
-+ 0x5a, 0x9c, 0x94, 0xaa, 0xaa, 0xcf, 0x57, 0x57,
-+ 0xb2, 0x82, 0x53, 0xb3, 0x3a, 0x3a, 0x3a, 0xa4,
-+ 0xf6, 0x68, 0x85, 0x2e, 0xca, 0x24, 0x24, 0xce,
-+ 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xd7, 0xd7,
-+ 0xd8, 0xd7, 0xd7, 0xb6, 0xe0, 0xd6, 0xd6, 0x87,
-+ 0xe2, 0x4b, 0x4b, 0xde, 0xfc, 0xb2, 0xfd, 0xc6,
-+ 0x9a, 0x96, 0x7f, 0x7f, 0x99, 0xab, 0xd3, 0xd3,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0x63, 0x3f, 0x6f, 0xc0, 0xf5, 0x30, 0xd4, 0xa0,
-+ 0xb4, 0xcf, 0x4b, 0xbc, 0x44, 0xae, 0xae, 0xcd,
-+ 0x44, 0x51, 0xeb, 0xfa, 0x69, 0xdf, 0x84, 0xdf,
-+ 0xdf, 0xdf, 0x84, 0xac, 0x84, 0x84, 0xd1, 0xd1,
-+ 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xe8, 0x54, 0xd1, 0xac, 0xd1,
-+ 0xac, 0x84, 0xdf, 0xdf, 0xdf, 0x52, 0xea, 0xdc,
-+ 0xee, 0x44, 0xcd, 0xa7, 0x77, 0xff, 0xa7, 0xcd,
-+ 0xcd, 0x8d, 0x44, 0xbb, 0xcf, 0x34, 0x78, 0xf5,
-+ 0x9b, 0x30, 0x9b, 0xf5, 0xa0, 0xd5, 0x3f, 0xe8,
-+ 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xe8, 0xd3, 0xa9, 0xa9, 0xc7, 0xba,
-+ 0x9c, 0x9c, 0x9c, 0x81, 0x9a, 0xfd, 0xfd, 0xfd,
-+ 0xfb, 0x4b, 0xb7, 0xb3, 0x3a, 0x3a, 0x3a, 0x46,
-+ 0x75, 0x33, 0x60, 0x4a, 0xd8, 0xd8, 0xd7, 0xd7,
-+ 0xd7, 0xd7, 0xd7, 0xce, 0xce, 0xd7, 0xd8, 0xd7,
-+ 0xce, 0xd7, 0xce, 0xd7, 0x8b, 0x4c, 0xbb, 0xe2,
-+ 0xf2, 0xf2, 0x6e, 0xe9, 0x7b, 0xda, 0xfd, 0xaa,
-+ 0x9a, 0x96, 0xfa, 0x7f, 0x99, 0x99, 0xd3, 0xd3,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xac, 0xd1, 0xe8, 0xe8, 0xb1, 0xe8, 0xd1, 0x98,
-+ 0x88, 0x48, 0xdd, 0x79, 0xe4, 0xa0, 0xb4, 0x36,
-+ 0x4b, 0xbc, 0x44, 0x44, 0xcd, 0x8d, 0xee, 0xeb,
-+ 0x5b, 0xc3, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xdf, 0xdf, 0x84, 0xac, 0xac, 0xd1, 0xe8, 0xb1,
-+ 0xe8, 0xd1, 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xac, 0x84, 0xac, 0xd1, 0x98,
-+ 0xe8, 0x98, 0xd1, 0x84, 0x54, 0x54, 0x63, 0xdf,
-+ 0x69, 0x4d, 0xdc, 0x50, 0xcd, 0xcd, 0xcd, 0xa7,
-+ 0xcd, 0xa7, 0x77, 0xcd, 0xbc, 0xbb, 0x85, 0x5e,
-+ 0x78, 0xf5, 0x9b, 0x30, 0x9b, 0xd4, 0xc0, 0x76,
-+ 0x63, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0xe8, 0xb1, 0xd3, 0xa9, 0x99, 0x7f,
-+ 0x7f, 0xfa, 0x94, 0x81, 0xc6, 0xfe, 0x2e, 0xed,
-+ 0x2e, 0xa3, 0x87, 0x53, 0x46, 0x3a, 0x46, 0x3c,
-+ 0x72, 0x4a, 0x22, 0x24, 0x24, 0xd7, 0xb6, 0xce,
-+ 0xce, 0xce, 0xce, 0xce, 0xd7, 0xce, 0xd7, 0xd8,
-+ 0xd7, 0xd8, 0xd7, 0x8b, 0x5c, 0xd6, 0x87, 0xc2,
-+ 0x7d, 0xc2, 0xec, 0x6e, 0x7b, 0xda, 0xfd, 0xfd,
-+ 0x81, 0x9a, 0xfa, 0x7f, 0xc7, 0xc3, 0xab, 0xd3,
-+ 0xd3, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac,
-+ 0x84, 0xac, 0xd1, 0xe8, 0xb1, 0xe8, 0x63, 0xef,
-+ 0x40, 0xdd, 0x30, 0xd4, 0xaf, 0x43, 0xde, 0x50,
-+ 0x44, 0xae, 0xae, 0x7c, 0x83, 0x5a, 0x52, 0xdf,
-+ 0xdf, 0xdf, 0xdf, 0xac, 0xd1, 0xd1, 0xe8, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xe8, 0xe8, 0xe8,
-+ 0xb1, 0xe8, 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0xac,
-+ 0x84, 0x84, 0xac, 0xac, 0x98, 0x98, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0xd1,
-+ 0xac, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xac, 0xac, 0x84, 0xac, 0xac,
-+ 0xac, 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0xd1, 0x98,
-+ 0x98, 0x98, 0xac, 0x84, 0x84, 0xdf, 0x84, 0xdf,
-+ 0x84, 0xdf, 0x54, 0x69, 0x9a, 0x51, 0x50, 0xff,
-+ 0x77, 0xa7, 0xcd, 0xff, 0xae, 0x44, 0x50, 0xbb,
-+ 0xb2, 0x5e, 0x78, 0xd4, 0x30, 0x30, 0xe4, 0xf9,
-+ 0x92, 0x8f, 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xe8, 0x54, 0xd3, 0xd3, 0xa9, 0xa9, 0xba,
-+ 0x7f, 0x9c, 0xfa, 0x9a, 0xfe, 0x6d, 0xa3, 0x73,
-+ 0x24, 0xa3, 0x23, 0x85, 0x53, 0xf4, 0xd9, 0x34,
-+ 0x23, 0xa2, 0xfb, 0x24, 0xce, 0xce, 0x2f, 0xce,
-+ 0xce, 0xd8, 0xd7, 0xd8, 0xd7, 0xd7, 0xd7, 0xd7,
-+ 0x9d, 0xd7, 0xd8, 0x24, 0xca, 0xed, 0xfe, 0xc2,
-+ 0xc2, 0x7d, 0xec, 0x6e, 0x7b, 0xfc, 0x57, 0xfd,
-+ 0x81, 0x9a, 0x9c, 0x7f, 0xc7, 0x99, 0xab, 0xd3,
-+ 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xac, 0xac, 0xe8, 0xb1, 0xe8, 0x8f, 0x6f, 0x40,
-+ 0xa0, 0xa0, 0xaf, 0x72, 0xfc, 0xf2, 0x44, 0x8d,
-+ 0xff, 0x51, 0xdb, 0x5b, 0xdf, 0xac, 0xd1, 0xac,
-+ 0xac, 0xac, 0xac, 0x84, 0x54, 0xb1, 0xb1, 0xb1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0xe8,
-+ 0xd1, 0xe8, 0xd1, 0xd1, 0x98, 0xd1, 0x98, 0xd1,
-+ 0xd1, 0x98, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-+ 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xac, 0x84, 0xac, 0xac, 0xac, 0xac, 0xd1,
-+ 0xd1, 0xd1, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
-+ 0x84, 0x84, 0xac, 0x98, 0x98, 0x98, 0x98, 0x98,
-+ 0x98, 0x54, 0x84, 0xac, 0x84, 0x84, 0x98, 0x98,
-+ 0x84, 0xd1, 0xd1, 0x54, 0x84, 0xdf, 0x5a, 0xeb,
-+ 0x50, 0xcd, 0xcd, 0xcd, 0xcd, 0xa7, 0xa7, 0xa7,
-+ 0xbb, 0x4b, 0x43, 0x9f, 0xa0, 0x30, 0xd4, 0xe4,
-+ 0xf9, 0x65, 0x8f, 0x63, 0x98, 0x98, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd3, 0xa9, 0x99,
-+ 0xba, 0xba, 0x9c, 0x96, 0xbc, 0x4f, 0xca, 0x70,
-+ 0x97, 0x6a, 0xce, 0xd6, 0x42, 0xf0, 0x39, 0x4a,
-+ 0xa2, 0xca, 0xca, 0xd8, 0xd7, 0xce, 0xce, 0xce,
-+ 0xce, 0xce, 0xd7, 0xce, 0xd8, 0xd7, 0xd8, 0xd7,
-+ 0xd7, 0x9d, 0xd6, 0x70, 0x61, 0xd6, 0x2e, 0xe2,
-+ 0xf2, 0xec, 0xfe, 0x4b, 0xde, 0xda, 0xda, 0xfd,
-+ 0x81, 0x9a, 0x96, 0xfa, 0x7f, 0x99, 0xc3, 0xab,
-+ 0xd3, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xac, 0x54, 0xe8, 0xe8, 0x3f, 0x65, 0xdd, 0x78,
-+ 0x78, 0x34, 0xb2, 0x4b, 0x44, 0xcd, 0x7c, 0x51,
-+ 0xd0, 0x5b, 0xdf, 0xdf, 0x84, 0xac, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0xac, 0xac,
-+ 0xac, 0xac, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xd1, 0xd1,
-+ 0x98, 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac,
-+ 0xac, 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xac, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0x84, 0xdf, 0xdf, 0xdf, 0xdf,
-+ 0x5b, 0xdb, 0x51, 0x44, 0xcd, 0xa7, 0x77, 0x77,
-+ 0xcd, 0xae, 0xbb, 0xb8, 0xb4, 0xdd, 0xd4, 0x9b,
-+ 0x30, 0xdd, 0x58, 0x76, 0x63, 0x98, 0xac, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xac, 0xac,
-+ 0xac, 0xd1, 0xd1, 0x54, 0xdf, 0xd3, 0xc3, 0x99,
-+ 0x99, 0xc7, 0x7f, 0x9c, 0xed, 0x4f, 0x61, 0x5c,
-+ 0x56, 0x26, 0x26, 0x22, 0xd6, 0x4a, 0x2e, 0x22,
-+ 0xd8, 0xce, 0x9d, 0xd8, 0x24, 0x9d, 0xb6, 0xb6,
-+ 0x2f, 0x2f, 0xce, 0xce, 0xd7, 0xd7, 0xce, 0xce,
-+ 0xce, 0x9d, 0x26, 0x9d, 0xca, 0xd6, 0x21, 0x21,
-+ 0x87, 0x87, 0x82, 0x4b, 0x4b, 0xfc, 0xda, 0xcf,
-+ 0xaa, 0x81, 0x96, 0xfa, 0x7f, 0x99, 0x99, 0xc3,
-+ 0xd3, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xe8, 0xe8, 0x63, 0x92, 0xdd, 0x78, 0x78,
-+ 0xf0, 0x9e, 0x44, 0x8d, 0x50, 0x6d, 0x4d, 0xdf,
-+ 0xdf, 0xd1, 0xac, 0x84, 0xac, 0xac, 0xd1, 0xd1,
-+ 0xd1, 0xe8, 0xd1, 0xd1, 0xd1, 0xac, 0x84, 0xd1,
-+ 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0x84, 0x84, 0xdf,
-+ 0x84, 0xdf, 0x84, 0xac, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x98, 0xd1, 0xac, 0xac, 0xac, 0xd1,
-+ 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0x98, 0x98,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xe8, 0x54, 0xe8, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0x84, 0x84, 0xac, 0x84, 0xac, 0x84,
-+ 0xac, 0xdf, 0x69, 0xea, 0x51, 0xcd, 0xcd, 0xcd,
-+ 0x77, 0xcd, 0xcd, 0xbc, 0x4b, 0x39, 0x78, 0xd4,
-+ 0x9b, 0x62, 0x79, 0x58, 0x8f, 0x63, 0xd1, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0x54, 0xac, 0x54, 0xd3, 0xdf, 0xab, 0x69,
-+ 0x69, 0x5b, 0xc7, 0xc7, 0x60, 0x4f, 0xd6, 0x26,
-+ 0x6a, 0x6a, 0xce, 0x24, 0xca, 0x23, 0xfb, 0x24,
-+ 0xd8, 0xd7, 0x24, 0x24, 0xd8, 0x24, 0xd8, 0xce,
-+ 0xce, 0x2f, 0x2f, 0xce, 0xce, 0xd7, 0xd7, 0xd8,
-+ 0xce, 0xd7, 0xce, 0x9d, 0x9d, 0x26, 0xa3, 0xca,
-+ 0xd6, 0x21, 0x71, 0xee, 0x4b, 0x7b, 0xda, 0xcf,
-+ 0xfd, 0x81, 0x9a, 0x9c, 0xfa, 0xc7, 0xc3, 0xc3,
-+ 0xd3, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xac, 0xac,
-+ 0xe8, 0x98, 0x3f, 0x65, 0xa0, 0x79, 0xb5, 0xb0,
-+ 0xbb, 0x8d, 0xbc, 0xdc, 0x5a, 0xdf, 0xdf, 0xdf,
-+ 0x84, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac,
-+ 0xd1, 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xac, 0x84, 0xdf, 0xdf, 0x69, 0xad, 0x9e, 0x44,
-+ 0xcd, 0xcd, 0xa7, 0xff, 0x8d, 0x7c, 0x9e, 0x34,
-+ 0xa0, 0x9b, 0x9b, 0xd4, 0xc0, 0x8f, 0x63, 0x98,
-+ 0x98, 0x98, 0xac, 0xd1, 0xb1, 0xe8, 0x84, 0xdf,
-+ 0xdf, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xd1,
-+ 0xd1, 0xe8, 0x54, 0xd1, 0xe8, 0xe8, 0xb1, 0xab,
-+ 0x99, 0xdf, 0x7f, 0xc7, 0x60, 0xa8, 0xa8, 0x97,
-+ 0x56, 0x9d, 0x38, 0xd6, 0xd6, 0xd6, 0x70, 0x70,
-+ 0xd6, 0x70, 0x22, 0xca, 0xca, 0xd8, 0xd7, 0xd7,
-+ 0xd7, 0xb6, 0xd7, 0xce, 0xce, 0xce, 0xce, 0xce,
-+ 0xd7, 0xd8, 0xce, 0xd7, 0xce, 0x9d, 0x9d, 0x26,
-+ 0x56, 0x26, 0x61, 0xd6, 0xbb, 0x9e, 0xfc, 0x57,
-+ 0xfd, 0x81, 0x9a, 0x96, 0xfa, 0x99, 0xc7, 0xc3,
-+ 0xb1, 0xb1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xd1,
-+ 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x98, 0x98, 0x98, 0xac, 0xac, 0xd1,
-+ 0x98, 0x8f, 0x65, 0xf9, 0x9f, 0x34, 0xe9, 0xfe,
-+ 0x44, 0xdc, 0x5a, 0xdf, 0x84, 0xd1, 0xac, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xac, 0xac, 0x84, 0xac, 0x84, 0xc7, 0xd0,
-+ 0x51, 0x50, 0xcd, 0xa7, 0xa7, 0xff, 0xbc, 0x4b,
-+ 0x39, 0xdd, 0xf5, 0x79, 0xa0, 0x58, 0x6f, 0x63,
-+ 0x63, 0xe8, 0xac, 0xac, 0xd1, 0xe8, 0xac, 0xdf,
-+ 0x84, 0x84, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x98, 0xac, 0xd1, 0xd1, 0xd1, 0x98, 0x63, 0x98,
-+ 0xd1, 0xd1, 0xe8, 0xe8, 0x54, 0x54, 0xd3, 0x69,
-+ 0x3f, 0xc3, 0xa9, 0xba, 0x2e, 0x73, 0xca, 0xa8,
-+ 0xd6, 0xe0, 0x26, 0x8c, 0x8c, 0x8c, 0xf8, 0xf8,
-+ 0xf8, 0xc8, 0x4f, 0x47, 0x70, 0x47, 0xd8, 0x9d,
-+ 0xd7, 0x9d, 0xce, 0xce, 0xb6, 0x9d, 0xb6, 0xce,
-+ 0xd7, 0xce, 0xd7, 0x2f, 0xd7, 0xce, 0x9d, 0x9d,
-+ 0x9d, 0x26, 0x56, 0xa3, 0xbb, 0xfe, 0xfc, 0xda,
-+ 0x57, 0x9a, 0x81, 0x96, 0x9c, 0x7f, 0x7f, 0xc3,
-+ 0xa9, 0xab, 0xe8, 0xd1, 0xe8, 0xd1, 0xac, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xe8, 0xd1, 0x98, 0x63, 0x98, 0xac, 0x98,
-+ 0x8f, 0x76, 0x9f, 0xb4, 0x8a, 0xbb, 0xfe, 0x51,
-+ 0x96, 0x69, 0xdf, 0xdf, 0xdf, 0x84, 0xd1, 0xb1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xac, 0x84, 0x84, 0x84, 0x84, 0xdf,
-+ 0x5b, 0xeb, 0x50, 0x44, 0xff, 0xa7, 0xff, 0xae,
-+ 0xbb, 0x68, 0x9f, 0xf5, 0x62, 0xe4, 0x40, 0x8f,
-+ 0x63, 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xac, 0xac, 0xd1, 0xe8, 0xe8, 0xe8, 0xd1, 0x98,
-+ 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x63, 0x98,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0x54, 0x54, 0xd3,
-+ 0x52, 0xc3, 0xc7, 0xc7, 0xb7, 0x21, 0x61, 0x6a,
-+ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xe3,
-+ 0xe3, 0xf8, 0xf8, 0xf8, 0x8c, 0xca, 0xd6, 0xe0,
-+ 0xd8, 0xd8, 0xb6, 0x2f, 0x2f, 0xb6, 0x9d, 0xce,
-+ 0xd7, 0xce, 0xd8, 0xce, 0xb6, 0xb6, 0xd7, 0xce,
-+ 0xce, 0x9d, 0x4f, 0x26, 0x93, 0xde, 0x7b, 0xda,
-+ 0xda, 0xfd, 0x81, 0x96, 0x9c, 0xc7, 0x99, 0x99,
-+ 0xc3, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0x63, 0x63, 0x63,
-+ 0x92, 0x9f, 0xb4, 0x43, 0xbb, 0x7c, 0xdb, 0x69,
-+ 0xac, 0xe8, 0xac, 0xdf, 0xdf, 0xdf, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0x98, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0xd1, 0xac, 0x84, 0x84, 0xdf, 0xdf,
-+ 0xdf, 0xdf, 0x5b, 0xdc, 0x50, 0xff, 0xa7, 0xff,
-+ 0xae, 0xbc, 0x8e, 0x9f, 0xa0, 0xe4, 0xf5, 0x40,
-+ 0x3f, 0x98, 0xd1, 0xb1, 0xd1, 0xd1, 0xb1, 0xe8,
-+ 0xd1, 0xac, 0xd1, 0xe8, 0xb1, 0xb1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0xd1,
-+ 0xd1, 0xe8, 0xe8, 0xd1, 0x63, 0x63, 0x63, 0x63,
-+ 0xdf, 0xab, 0xac, 0x69, 0x59, 0xbb, 0xf8, 0xf8,
-+ 0xf8, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3,
-+ 0xe3, 0x27, 0xe3, 0xe3, 0xe3, 0xf8, 0xc8, 0x47,
-+ 0x22, 0xd8, 0xce, 0xb6, 0x9d, 0xce, 0xd7, 0x24,
-+ 0xd8, 0xce, 0xce, 0xce, 0xce, 0xce, 0x2f, 0xce,
-+ 0xce, 0xce, 0x5c, 0x24, 0xed, 0xde, 0x6e, 0x86,
-+ 0x57, 0xfd, 0xaa, 0x81, 0x96, 0xfa, 0xc7, 0xc7,
-+ 0xab, 0xab, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x98, 0xd1, 0xe8, 0xd1, 0x98, 0x3f, 0x76,
-+ 0xf9, 0xb5, 0xfc, 0xfe, 0xdc, 0x5b, 0xac, 0xac,
-+ 0x54, 0x54, 0xd1, 0x98, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xd1, 0xac, 0x84,
-+ 0x84, 0xdf, 0xdf, 0x52, 0xd0, 0xee, 0x44, 0xa7,
-+ 0x77, 0xff, 0x44, 0xde, 0x34, 0x78, 0x79, 0x79,
-+ 0x48, 0x3f, 0x98, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1,
-+ 0x63, 0xd1, 0xe8, 0xb1, 0xe8, 0xe8, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0x98, 0xd1,
-+ 0xd1, 0xd1, 0xe8, 0xd1, 0x98, 0x63, 0x63, 0x98,
-+ 0xdf, 0xd3, 0x99, 0x69, 0x21, 0xa3, 0xf8, 0xe3,
-+ 0xe3, 0xe3, 0x27, 0xe7, 0xcb, 0xe7, 0xcb, 0xcb,
-+ 0xcb, 0xe7, 0x27, 0x27, 0xe3, 0xe3, 0xe3, 0x8c,
-+ 0x5c, 0x47, 0x24, 0xd8, 0xd7, 0x9d, 0xb6, 0xd7,
-+ 0xd7, 0xce, 0xce, 0xd7, 0xce, 0xd7, 0x2f, 0x2f,
-+ 0xce, 0xd7, 0x24, 0xca, 0x87, 0xec, 0x6e, 0xa6,
-+ 0xda, 0xaa, 0xfd, 0x9a, 0x96, 0x96, 0x7f, 0xc7,
-+ 0xc3, 0xab, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x63, 0x98, 0xd1, 0xb1, 0xb1, 0xe8, 0x88, 0xbe,
-+ 0xb4, 0xc4, 0x51, 0xad, 0xdf, 0xdf, 0xd1, 0xb1,
-+ 0xd1, 0xd1, 0x63, 0xe8, 0xd1, 0xd1, 0x98, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xac, 0x84, 0xac,
-+ 0xe8, 0x54, 0x84, 0x84, 0xdf, 0x69, 0xeb, 0x50,
-+ 0xa7, 0x77, 0xcd, 0x8d, 0xde, 0x72, 0xa0, 0xd4,
-+ 0xa0, 0x48, 0x3f, 0xe8, 0xd1, 0xac, 0x98, 0x98,
-+ 0x98, 0xe8, 0xe8, 0xd1, 0xe8, 0xd1, 0xac, 0x84,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0x98, 0xd1,
-+ 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0x98, 0xac, 0x84,
-+ 0xd3, 0xac, 0xe8, 0x84, 0x2e, 0xf8, 0xf8, 0xe3,
-+ 0x27, 0xcb, 0xcb, 0x3d, 0x28, 0x28, 0x2c, 0x3d,
-+ 0xcb, 0xe7, 0x2c, 0x2c, 0xe7, 0xe7, 0xe3, 0xe3,
-+ 0xf8, 0x8b, 0x70, 0xd8, 0x24, 0x24, 0xd7, 0x9d,
-+ 0xce, 0xd7, 0xd8, 0xce, 0xd7, 0xce, 0x2f, 0xce,
-+ 0xce, 0xb6, 0xca, 0xd6, 0xbb, 0xec, 0xde, 0xa6,
-+ 0xfc, 0xda, 0xaa, 0x81, 0xcf, 0xfa, 0xfa, 0xc7,
-+ 0xc7, 0xab, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x63, 0x63, 0xd1, 0xd1, 0xe8, 0xa9, 0xbe, 0x5d,
-+ 0x7b, 0x57, 0xc3, 0xdf, 0xdf, 0xdf, 0x54, 0x98,
-+ 0xb1, 0xe8, 0x98, 0xd1, 0xac, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xd1,
-+ 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0x54, 0x84, 0x84, 0x84, 0xdf, 0xad,
-+ 0x51, 0x50, 0x77, 0xcd, 0x8d, 0x4b, 0x5d, 0x78,
-+ 0x62, 0xdd, 0x92, 0x63, 0x63, 0x63, 0xdf, 0x63,
-+ 0xe8, 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0xac, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xd1, 0x54,
-+ 0xd1, 0xab, 0xa9, 0x96, 0xca, 0xf8, 0xf8, 0xe3,
-+ 0xcb, 0xe7, 0x28, 0x28, 0x28, 0x28, 0x2c, 0x2c,
-+ 0xe7, 0x2c, 0x3d, 0x2c, 0x28, 0x2c, 0xe7, 0x27,
-+ 0xe3, 0xf8, 0x8b, 0x70, 0xd8, 0x24, 0xce, 0xce,
-+ 0xce, 0xd7, 0xd8, 0xd7, 0xce, 0xce, 0x2f, 0x2f,
-+ 0xd7, 0xd7, 0xa8, 0x2e, 0xbb, 0xfe, 0x6e, 0xfe,
-+ 0xda, 0xda, 0xb2, 0x6e, 0xec, 0x96, 0x96, 0x7f,
-+ 0xc7, 0xc3, 0x84, 0xd1, 0xd1, 0xd1, 0x98, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xac, 0xd1,
-+ 0x63, 0x98, 0x98, 0xe8, 0xb1, 0xba, 0x66, 0x86,
-+ 0x9a, 0xdf, 0x84, 0xdf, 0xdf, 0x84, 0x98, 0x63,
-+ 0xe8, 0xe8, 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0xac, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1,
-+ 0x69, 0x83, 0xae, 0xa7, 0xc1, 0x8d, 0x4b, 0xb4,
-+ 0xa0, 0xe4, 0xdd, 0x88, 0x3f, 0xdf, 0x63, 0x63,
-+ 0xe8, 0xb1, 0xd1, 0xdf, 0x84, 0x84, 0x84, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x98, 0xd1, 0xd1, 0x54, 0x54,
-+ 0x54, 0xac, 0xdf, 0xb0, 0x26, 0xe3, 0xe3, 0x27,
-+ 0x2c, 0x2c, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2c,
-+ 0x3d, 0x3d, 0x28, 0x28, 0x28, 0x28, 0x28, 0xe7,
-+ 0xcb, 0xe3, 0xe3, 0x38, 0xe0, 0x24, 0x9d, 0xb6,
-+ 0xce, 0xd7, 0xd7, 0xce, 0xd7, 0xce, 0xce, 0xd7,
-+ 0x8b, 0xca, 0xa8, 0xbc, 0x87, 0xfe, 0xde, 0x2e,
-+ 0x71, 0xb2, 0xe2, 0x71, 0xb2, 0x55, 0xfa, 0x9c,
-+ 0x7f, 0x99, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xd1,
-+ 0xd1, 0xd1, 0x63, 0x3f, 0x88, 0xb4, 0xaa, 0xba,
-+ 0xd1, 0xd1, 0x98, 0x98, 0x98, 0xdf, 0x98, 0xac,
-+ 0x98, 0xe8, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xe8, 0xd1,
-+ 0x98, 0xd1, 0xd1, 0x98, 0xd1, 0xe8, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0x98, 0xd1,
-+ 0xd1, 0xdf, 0x4d, 0xee, 0x8d, 0xcd, 0xae, 0xbb,
-+ 0xb4, 0xaf, 0xf5, 0x40, 0x3f, 0xdf, 0x3f, 0xac,
-+ 0xd1, 0xd1, 0xac, 0x84, 0x84, 0xac, 0xac, 0x98,
-+ 0xd1, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x63, 0xd1, 0xd1, 0xd1, 0xe8, 0xd3, 0xe8,
-+ 0xd3, 0xd1, 0x54, 0x93, 0xf8, 0xe3, 0xe3, 0xcb,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x2c, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2c,
-+ 0x3d, 0xe7, 0x27, 0xe3, 0xd6, 0x8b, 0xce, 0xd7,
-+ 0xce, 0xd8, 0xd7, 0xd7, 0xd7, 0xb6, 0xce, 0xd7,
-+ 0x24, 0xa8, 0x2e, 0x87, 0xfe, 0xfe, 0x7c, 0x93,
-+ 0x2e, 0x2e, 0x9e, 0xed, 0xc6, 0x9a, 0x96, 0x9c,
-+ 0xfa, 0xba, 0xd1, 0xd1, 0xd1, 0xac, 0xd1, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xd1, 0xd1,
-+ 0xd1, 0xab, 0x63, 0x3f, 0x9c, 0xbe, 0xb1, 0xb1,
-+ 0xe8, 0xd1, 0xd1, 0x98, 0xac, 0xac, 0xdf, 0x84,
-+ 0xd1, 0xd1, 0xe8, 0xe8, 0xe8, 0xd1, 0xd1, 0x98,
-+ 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd3, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd3,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0x98, 0xd1, 0xe8,
-+ 0xd1, 0x98, 0xe8, 0xb1, 0xd1, 0x98, 0xd1, 0xd1,
-+ 0x98, 0x98, 0xd3, 0xd1, 0xd1, 0x98, 0x98, 0x98,
-+ 0xd1, 0x54, 0xdf, 0x5b, 0x6d, 0x44, 0xcd, 0x44,
-+ 0x6e, 0x9f, 0xaf, 0xa0, 0x6f, 0x63, 0x54, 0x63,
-+ 0x98, 0xd1, 0xac, 0x84, 0x84, 0x84, 0x98, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98,
-+ 0x98, 0x98, 0x98, 0xd1, 0xe8, 0xb1, 0xe8, 0xe8,
-+ 0xe8, 0xe8, 0x69, 0xb7, 0x8c, 0xe3, 0x27, 0x2c,
-+ 0x2c, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x2c, 0x3d, 0x27, 0x38, 0x8b, 0xd7, 0xd8,
-+ 0xce, 0xd7, 0xd7, 0xce, 0xce, 0xce, 0xb6, 0x8b,
-+ 0xca, 0xa8, 0x59, 0x87, 0x71, 0xbc, 0x61, 0x2e,
-+ 0x70, 0x83, 0xfb, 0x87, 0x55, 0x81, 0x81, 0x94,
-+ 0xfa, 0x7f, 0xd1, 0xd1, 0xd1, 0x54, 0x84, 0x84,
-+ 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0x63, 0x76, 0x7f, 0xef, 0xe8, 0xb1,
-+ 0xe8, 0xd1, 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xac,
-+ 0xd1, 0xd1, 0xe8, 0xe8, 0xd1, 0xac, 0xd1, 0x98,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xab, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xab, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd3,
-+ 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd3, 0x54, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x98, 0xd1, 0xe8, 0x98, 0xb1,
-+ 0xe8, 0x98, 0xac, 0xac, 0x54, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xac, 0x84, 0xdf, 0x69, 0x83, 0x50, 0x8d,
-+ 0x7c, 0x4b, 0x29, 0xaf, 0xc0, 0x8f, 0xe8, 0x63,
-+ 0x63, 0x98, 0xac, 0xac, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98,
-+ 0x63, 0x63, 0x63, 0xd1, 0xd1, 0xe8, 0xe8, 0xe8,
-+ 0xe8, 0xd1, 0x96, 0x93, 0xa2, 0x6b, 0x27, 0x2c,
-+ 0x2c, 0x28, 0x28, 0x2c, 0x2c, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2c, 0x2c,
-+ 0x28, 0x28, 0x28, 0x45, 0x5c, 0x8b, 0xd7, 0xd8,
-+ 0xce, 0xd7, 0xce, 0x9d, 0x2f, 0xd7, 0xd7, 0x24,
-+ 0x61, 0x2e, 0x21, 0xfe, 0x60, 0x37, 0xd6, 0x24,
-+ 0xa3, 0xca, 0x2e, 0xdc, 0xb2, 0xcf, 0x9a, 0x9a,
-+ 0x94, 0xfa, 0xe8, 0xd1, 0xac, 0xac, 0xac, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0x3f, 0xc3, 0x3f, 0x63, 0xb1, 0xd1,
-+ 0x98, 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xe8, 0xe8, 0xac, 0xac, 0xac, 0xd1,
-+ 0xd1, 0xd3, 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0x54, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xab, 0xd3, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xab, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xab, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xab, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0x54, 0xe8, 0xd1, 0xd3, 0xe8, 0xd1, 0x63,
-+ 0xe8, 0xd1, 0x84, 0xdf, 0x84, 0xac, 0xe8, 0xd1,
-+ 0x84, 0xdf, 0x54, 0x84, 0x84, 0x52, 0xdb, 0x50,
-+ 0x8d, 0xbb, 0xb8, 0x34, 0xb5, 0x58, 0xb1, 0xe8,
-+ 0x63, 0x98, 0xd1, 0xd1, 0xd1, 0x98, 0xd1, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98,
-+ 0x63, 0x63, 0xd1, 0xd1, 0xa9, 0xe8, 0x98, 0x3f,
-+ 0xe8, 0xd3, 0xfd, 0x82, 0xe5, 0x4a, 0xa1, 0xe7,
-+ 0x2c, 0x3d, 0x2c, 0x28, 0x3d, 0x2c, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2c, 0x2c,
-+ 0x28, 0x28, 0x28, 0x2c, 0x38, 0xb6, 0xd7, 0xd8,
-+ 0xd8, 0xd7, 0xce, 0xce, 0xb6, 0xd7, 0xd7, 0x5c,
-+ 0x70, 0x4c, 0x2e, 0x2e, 0xd6, 0xfb, 0x26, 0x4f,
-+ 0xca, 0xa8, 0x93, 0x9e, 0xb2, 0xfd, 0xaa, 0x81,
-+ 0x96, 0x9c, 0xd1, 0xd1, 0xac, 0x84, 0xac, 0xac,
-+ 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x98, 0x63, 0xe8, 0x63, 0x98, 0xe8, 0xd1, 0x98,
-+ 0xac, 0x84, 0xac, 0xe8, 0xe8, 0xe8, 0xe8, 0xe8,
-+ 0xe8, 0xd1, 0xac, 0xac, 0xd1, 0xd1, 0xac, 0x84,
-+ 0xac, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xab, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd3, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xac, 0xd3,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xac,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0x98, 0x54, 0xac,
-+ 0x63, 0x98, 0xac, 0x84, 0x84, 0x54, 0xe8, 0xac,
-+ 0xac, 0x84, 0xac, 0xac, 0x54, 0xac, 0xdf, 0xea,
-+ 0x7c, 0x44, 0xfe, 0x5d, 0x66, 0xf9, 0x76, 0xe8,
-+ 0x63, 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac,
-+ 0x63, 0x98, 0xd1, 0xe8, 0xd1, 0x6e, 0xc4, 0x34,
-+ 0x3f, 0x3f, 0xcf, 0x4c, 0x5d, 0x33, 0x70, 0x67,
-+ 0x45, 0x3d, 0x3d, 0x2c, 0x2c, 0x2c, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2c, 0x2c,
-+ 0x28, 0x28, 0x28, 0xe7, 0x70, 0xd7, 0xd7, 0xd7,
-+ 0xce, 0xd7, 0xce, 0xce, 0xd7, 0xce, 0x8b, 0x70,
-+ 0x71, 0x47, 0xca, 0x26, 0x26, 0x4f, 0xd8, 0xca,
-+ 0xfb, 0xed, 0x4b, 0xb2, 0x57, 0xda, 0xfd, 0xaa,
-+ 0x94, 0x96, 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x63, 0x54, 0xd1, 0xd1, 0xd3, 0xe8, 0x98, 0xac,
-+ 0x84, 0x84, 0xd1, 0xd1, 0xd1, 0x63, 0xe8, 0xe8,
-+ 0xd1, 0xd1, 0xac, 0x84, 0xd1, 0xd1, 0xac, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xab, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd3, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd3, 0x54,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd3, 0xab, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xe8, 0xd1,
-+ 0x54, 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0x54, 0xd1,
-+ 0xd1, 0xab, 0xd1, 0x54, 0x54, 0xd1, 0x98, 0xd1,
-+ 0xd1, 0x98, 0xab, 0xd1, 0xd1, 0xac, 0xac, 0x54,
-+ 0xdf, 0xdf, 0x63, 0x98, 0xd1, 0xe8, 0xab, 0xdf,
-+ 0x5a, 0x7c, 0x44, 0x4b, 0x72, 0x66, 0x58, 0x3f,
-+ 0x63, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8,
-+ 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98,
-+ 0x98, 0x54, 0xd3, 0xe8, 0xe8, 0x90, 0x34, 0x68,
-+ 0xa5, 0x68, 0x4b, 0x4c, 0x5e, 0x33, 0x6b, 0x38,
-+ 0x27, 0x2c, 0x3d, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x3d, 0x2c,
-+ 0x28, 0x28, 0x28, 0x45, 0x70, 0xd8, 0xce, 0xce,
-+ 0xd7, 0xd7, 0xce, 0xb6, 0xce, 0x9d, 0x8b, 0x22,
-+ 0x24, 0xd8, 0x9d, 0x4f, 0x9d, 0x8b, 0xd8, 0xe0,
-+ 0x93, 0x93, 0x4b, 0xe9, 0x7b, 0xcf, 0xfd, 0xc6,
-+ 0x81, 0x9a, 0x84, 0xac, 0xac, 0xd1, 0xe8, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0xd1,
-+ 0x98, 0x98, 0xd1, 0xe8, 0xd1, 0xd1, 0xac, 0xdf,
-+ 0x84, 0x84, 0xd1, 0xe8, 0xe8, 0xd1, 0x98, 0x63,
-+ 0x98, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x96, 0xc2, 0x6e,
-+ 0xec, 0xbf, 0xec, 0xec, 0xec, 0xec, 0x82, 0xf2,
-+ 0xe9, 0xf2, 0xcf, 0xd1, 0x54, 0xd3, 0xd1, 0x6e,
-+ 0xe2, 0xe8, 0xd1, 0xd3, 0xfc, 0xcc, 0xbd, 0xe9,
-+ 0x6e, 0x6e, 0xfa, 0xd1, 0xd1, 0x57, 0xcc, 0xe2,
-+ 0xde, 0x6e, 0xc2, 0x7b, 0xd3, 0x96, 0xe9, 0xe9,
-+ 0xec, 0xda, 0xd1, 0xd1, 0x9a, 0x7b, 0x6e, 0x6e,
-+ 0x57, 0xc3, 0xd1, 0xfd, 0x82, 0x82, 0xc6, 0x99,
-+ 0xec, 0x82, 0xec, 0x99, 0xd1, 0x54, 0x96, 0x82,
-+ 0xfd, 0xd1, 0xd1, 0x96, 0xf2, 0xbf, 0xec, 0xec,
-+ 0xf2, 0x9a, 0xd1, 0x9c, 0xf2, 0xcc, 0x6e, 0xe9,
-+ 0xec, 0x82, 0x7f, 0xac, 0xd1, 0xab, 0x81, 0xc2,
-+ 0xcc, 0xc6, 0xe8, 0x9c, 0xec, 0xe2, 0x81, 0xe9,
-+ 0x82, 0x6e, 0x9a, 0xb1, 0x98, 0xd1, 0xac, 0xdf,
-+ 0xdf, 0x5b, 0xee, 0xfe, 0xb8, 0xb4, 0x66, 0xef,
-+ 0x63, 0x98, 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xac, 0x98,
-+ 0x54, 0xe8, 0xb1, 0xe8, 0xb1, 0x90, 0x29, 0x2a,
-+ 0xc9, 0xc5, 0x53, 0x4c, 0x64, 0x25, 0x85, 0xa2,
-+ 0xa1, 0xe7, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2c,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x2c, 0x2c,
-+ 0x28, 0x28, 0x28, 0x89, 0x22, 0x24, 0xd8, 0xce,
-+ 0xce, 0xce, 0xce, 0xd7, 0xb6, 0xd7, 0xd7, 0xd7,
-+ 0xd8, 0xb6, 0x9d, 0xb6, 0x9d, 0xd7, 0xe0, 0xa8,
-+ 0xed, 0xec, 0xde, 0x6e, 0x7b, 0xda, 0x57, 0xfd,
-+ 0x81, 0x9a, 0xdf, 0x84, 0xac, 0xd1, 0xb1, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0x98, 0x98, 0x98,
-+ 0xe8, 0xd1, 0xd1, 0xe8, 0x54, 0xac, 0xac, 0xac,
-+ 0xac, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1, 0xac, 0x84,
-+ 0x84, 0x98, 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x96, 0xe2, 0xab,
-+ 0xda, 0x20, 0x81, 0x96, 0xe9, 0xc6, 0x20, 0x57,
-+ 0xd3, 0xec, 0x4c, 0x9a, 0xd1, 0x54, 0xfa, 0x59,
-+ 0x20, 0x7f, 0xd1, 0xd1, 0x54, 0x20, 0xf2, 0x54,
-+ 0x99, 0xf2, 0xbf, 0x7f, 0xd3, 0xd1, 0x80, 0x82,
-+ 0xe8, 0x54, 0x81, 0xe2, 0x99, 0xbd, 0xe2, 0xd3,
-+ 0xfa, 0xbd, 0x54, 0x9a, 0x6c, 0xda, 0xd1, 0x7f,
-+ 0xcc, 0xec, 0xab, 0xd1, 0x6c, 0xbf, 0xd1, 0xd1,
-+ 0xfd, 0x80, 0xcf, 0xd1, 0x54, 0xd1, 0xde, 0xe1,
-+ 0xe2, 0xab, 0x54, 0xd1, 0xda, 0x20, 0x81, 0x54,
-+ 0xc2, 0x59, 0x7f, 0xac, 0x7b, 0x20, 0x9c, 0xac,
-+ 0x99, 0x82, 0x7f, 0x84, 0x54, 0xac, 0xac, 0xbd,
-+ 0xe1, 0xcc, 0xba, 0xe8, 0x96, 0xde, 0xdf, 0x9a,
-+ 0x20, 0xda, 0xb1, 0xd1, 0x98, 0xac, 0x84, 0xdf,
-+ 0xdf, 0x52, 0x5b, 0x4b, 0xfe, 0x8a, 0x9f, 0x58,
-+ 0x3f, 0xd1, 0x98, 0x98, 0x84, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xd1,
-+ 0xac, 0xd1, 0xd3, 0x98, 0x63, 0x68, 0xf0, 0x29,
-+ 0x64, 0x29, 0x29, 0xa5, 0x25, 0x3e, 0xf0, 0xf1,
-+ 0x38, 0x4e, 0x2c, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x3d, 0x2f, 0x38, 0x24, 0xd7, 0xd7,
-+ 0xce, 0xd7, 0x2f, 0xce, 0x9d, 0xd7, 0xd7, 0xd7,
-+ 0xce, 0xce, 0x2f, 0xb6, 0x5c, 0x24, 0xca, 0x2e,
-+ 0xbb, 0xe2, 0xec, 0x6e, 0xe9, 0x7b, 0xcf, 0x57,
-+ 0xc6, 0x81, 0xdf, 0xac, 0xd1, 0xd1, 0xe8, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac,
-+ 0xac, 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x99, 0x7f, 0xd1,
-+ 0x57, 0x20, 0x81, 0xd1, 0x9c, 0xc6, 0x20, 0xfd,
-+ 0xd1, 0xfd, 0x20, 0xc6, 0xd1, 0xd1, 0xcf, 0xec,
-+ 0x20, 0xfc, 0xd1, 0xd1, 0xab, 0x20, 0xf2, 0x54,
-+ 0xd1, 0x96, 0xe1, 0xde, 0xd1, 0xd1, 0x20, 0xc2,
-+ 0xd1, 0x54, 0x96, 0x96, 0xfa, 0x80, 0xbd, 0x99,
-+ 0x54, 0x96, 0xd1, 0xf2, 0x6c, 0x99, 0xd1, 0xd1,
-+ 0xda, 0x80, 0x96, 0xd1, 0x4c, 0xbf, 0xe8, 0xd1,
-+ 0xfd, 0x20, 0xfd, 0xd1, 0xab, 0xc7, 0xec, 0xc2,
-+ 0x4c, 0x7f, 0xd1, 0xd1, 0xda, 0x20, 0x9a, 0xd1,
-+ 0xfc, 0x20, 0x96, 0xd1, 0xde, 0x20, 0x9c, 0xd1,
-+ 0x96, 0xfa, 0xc3, 0xd1, 0xd1, 0xd1, 0xd1, 0xec,
-+ 0x6e, 0x20, 0x6e, 0xb1, 0xfa, 0xfc, 0xac, 0x9a,
-+ 0x20, 0x57, 0x98, 0xab, 0x98, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x84, 0x5b, 0x51, 0x4b, 0xb4, 0xf9,
-+ 0x3f, 0xb1, 0x63, 0x98, 0x84, 0xac, 0xd1, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0x98, 0x98, 0x98,
-+ 0xd1, 0xf2, 0x90, 0x95, 0xba, 0xbe, 0x32, 0x29,
-+ 0xc5, 0xc5, 0xc5, 0x25, 0x25, 0x78, 0x25, 0x85,
-+ 0x22, 0x2f, 0xcb, 0x28, 0x28, 0x28, 0x2c, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x2c, 0x67, 0x70, 0xd7, 0xd8, 0xd7, 0xce,
-+ 0xd7, 0xce, 0xd7, 0xb6, 0xce, 0xce, 0xce, 0xce,
-+ 0xb6, 0xce, 0x8b, 0x8b, 0xca, 0xa8, 0x2e, 0xbb,
-+ 0xe2, 0xe2, 0xec, 0x6e, 0x6e, 0x7b, 0xda, 0x57,
-+ 0xc6, 0x55, 0xac, 0xac, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xcf, 0x20, 0x9a, 0xd1, 0x54, 0xc6, 0x20, 0xcf,
-+ 0x99, 0xec, 0xcc, 0x7f, 0xd1, 0xc3, 0xec, 0xfa,
-+ 0x4c, 0xc2, 0x99, 0x54, 0xd1, 0x20, 0xe2, 0xd1,
-+ 0xd1, 0xd1, 0x80, 0xbd, 0xd1, 0xd3, 0x4c, 0x6c,
-+ 0xfd, 0x7b, 0xe9, 0xd1, 0x99, 0xbd, 0x20, 0x6c,
-+ 0xda, 0xfa, 0xd1, 0x6c, 0xcc, 0xd1, 0xd1, 0x54,
-+ 0x81, 0x20, 0xcf, 0xd1, 0x6c, 0x6c, 0xd1, 0xe8,
-+ 0xc6, 0x20, 0xfd, 0xd1, 0xd1, 0x9a, 0xcf, 0x57,
-+ 0x20, 0xfd, 0x54, 0xd1, 0xfc, 0xe1, 0x9a, 0x99,
-+ 0x82, 0xf2, 0xc7, 0xd1, 0xe9, 0x80, 0xfc, 0xcf,
-+ 0xcc, 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0x54, 0xec,
-+ 0xc7, 0xbf, 0xe1, 0xc6, 0x9c, 0xda, 0x54, 0x96,
-+ 0x20, 0xda, 0xc3, 0xd1, 0xd1, 0xd3, 0xd1, 0xd3,
-+ 0x98, 0xd1, 0xe8, 0xab, 0x5a, 0xbb, 0x36, 0x9f,
-+ 0x92, 0x63, 0xb1, 0x63, 0x84, 0xac, 0xd1, 0xe8,
-+ 0xe8, 0xe8, 0xd1, 0x98, 0x63, 0x98, 0xd1, 0x98,
-+ 0x63, 0xb8, 0x34, 0x33, 0x32, 0x68, 0x31, 0x5e,
-+ 0xc5, 0xc5, 0xc5, 0x3e, 0x78, 0x25, 0x25, 0x25,
-+ 0x6b, 0x22, 0x4e, 0x2c, 0x28, 0x28, 0x2c, 0x28,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
-+ 0x2c, 0x4e, 0xa1, 0x70, 0xd8, 0x24, 0x2f, 0xce,
-+ 0xce, 0xb6, 0xce, 0xd8, 0xb6, 0xd7, 0xce, 0x2f,
-+ 0xce, 0x8b, 0x24, 0xe0, 0xfb, 0x2e, 0xfe, 0xc2,
-+ 0xe2, 0xf2, 0xf2, 0x6e, 0x6e, 0xde, 0xfc, 0x57,
-+ 0xfd, 0xc6, 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0x54,
-+ 0xda, 0xe1, 0x9a, 0xab, 0xd1, 0xc6, 0x20, 0xbd,
-+ 0xc2, 0x59, 0xfd, 0xd1, 0xd1, 0x96, 0x6e, 0x9a,
-+ 0xcc, 0x59, 0xfa, 0xd1, 0xd1, 0x20, 0xe2, 0xd1,
-+ 0xd1, 0xd1, 0x59, 0xc2, 0xd3, 0xd1, 0xe1, 0xbd,
-+ 0x96, 0xfd, 0xe9, 0xd1, 0xd3, 0xc3, 0xfc, 0x6c,
-+ 0x20, 0xbf, 0xc7, 0x59, 0xbd, 0xd1, 0x54, 0xd1,
-+ 0xc6, 0x80, 0xda, 0xd1, 0x6c, 0xbf, 0xd1, 0xd1,
-+ 0xfd, 0x20, 0xfd, 0x54, 0xd1, 0x6e, 0xfc, 0xcf,
-+ 0x80, 0xe2, 0xd3, 0xd1, 0xda, 0x20, 0xe2, 0xbd,
-+ 0x59, 0x9a, 0xd1, 0xe8, 0x7b, 0x20, 0xcf, 0x9a,
-+ 0xc2, 0xd3, 0xd1, 0xd3, 0xd1, 0xd3, 0xd1, 0x6e,
-+ 0xc3, 0x9c, 0x59, 0xcc, 0x81, 0xfc, 0xe8, 0xc6,
-+ 0xe1, 0xda, 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xe8, 0xac, 0x84, 0xdf, 0x5a, 0x6e, 0xb4,
-+ 0x94, 0x3f, 0xb1, 0x98, 0x98, 0xd1, 0xd1, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0x98, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x9c, 0x90, 0x29, 0x29, 0x36, 0x6c, 0x68,
-+ 0xc5, 0xc5, 0xc5, 0xc5, 0x3e, 0x3e, 0xc5, 0x33,
-+ 0x33, 0x70, 0x67, 0x4e, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x28, 0x28, 0x2c, 0x28, 0x28, 0x28, 0x2c,
-+ 0x45, 0x4e, 0x70, 0xd7, 0xd7, 0xd8, 0xce, 0xce,
-+ 0xd7, 0xd8, 0xce, 0x8b, 0xd7, 0xce, 0xd7, 0x8b,
-+ 0xb6, 0x8b, 0xe0, 0xa8, 0x71, 0xfe, 0xe2, 0x82,
-+ 0xc2, 0xe2, 0xf2, 0xec, 0x6e, 0xe9, 0xfc, 0x57,
-+ 0xcf, 0xc6, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x57, 0x20, 0xc6, 0xd1, 0xd1, 0xc6, 0x80, 0xcf,
-+ 0x96, 0x59, 0x82, 0xc3, 0xe8, 0xfc, 0xfc, 0xfd,
-+ 0x6e, 0x20, 0xfd, 0x54, 0xd3, 0x20, 0xf2, 0xd1,
-+ 0x54, 0x7f, 0x80, 0x6e, 0xd1, 0xd1, 0x59, 0xbd,
-+ 0xd1, 0xd1, 0x7f, 0x99, 0x99, 0xfa, 0x54, 0x7f,
-+ 0xec, 0x20, 0xde, 0xcc, 0xcc, 0x54, 0xd3, 0xd1,
-+ 0xfd, 0x80, 0xc6, 0x54, 0x6c, 0xcc, 0x54, 0xd1,
-+ 0xc6, 0x20, 0xc6, 0xd1, 0x99, 0xec, 0x81, 0xfd,
-+ 0x6c, 0xbf, 0xc7, 0xd1, 0xda, 0x20, 0x9a, 0x81,
-+ 0x20, 0xe2, 0x54, 0xd1, 0xde, 0x20, 0xfa, 0xd1,
-+ 0xfa, 0xab, 0x54, 0xac, 0x99, 0xd1, 0xd3, 0xec,
-+ 0xab, 0x54, 0x6e, 0xe1, 0xcc, 0xfc, 0xd1, 0x9a,
-+ 0x20, 0xda, 0x54, 0xd1, 0xc3, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0xdf, 0xdf, 0xac, 0x98, 0x96, 0x86,
-+ 0x66, 0xef, 0x63, 0xac, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0x98, 0x98, 0xd1, 0xd1, 0xd1, 0x98,
-+ 0xe8, 0x63, 0xa5, 0x5e, 0x29, 0x64, 0x25, 0x90,
-+ 0xc5, 0xc5, 0xc5, 0xc5, 0x3e, 0xc5, 0xc5, 0x33,
-+ 0xf0, 0x6b, 0x5c, 0x4e, 0x28, 0x28, 0x28, 0x28,
-+ 0x28, 0x2c, 0x28, 0x28, 0x28, 0x28, 0x2c, 0x3d,
-+ 0x27, 0x2f, 0x47, 0xd8, 0xd8, 0x24, 0x9d, 0xd7,
-+ 0xd7, 0xd8, 0xd7, 0xd7, 0xd7, 0x8b, 0x38, 0xd7,
-+ 0x5c, 0x5c, 0x61, 0xed, 0x87, 0x82, 0xcc, 0xc2,
-+ 0xc2, 0xe2, 0xf2, 0xec, 0x6e, 0xe9, 0xfc, 0xda,
-+ 0xcf, 0xc6, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0x57, 0x20, 0x9a, 0xd1, 0xd3, 0x81, 0x20, 0xcf,
-+ 0xab, 0xbf, 0x59, 0x96, 0xd1, 0xe2, 0x99, 0xd1,
-+ 0x7f, 0x20, 0xc2, 0xd3, 0xd1, 0xe1, 0xc2, 0xd1,
-+ 0xd1, 0xcf, 0x59, 0x81, 0xd1, 0xd1, 0x80, 0xbd,
-+ 0xd1, 0xd1, 0x54, 0xda, 0x9a, 0xf2, 0xd1, 0xd1,
-+ 0x9a, 0x80, 0x57, 0x7b, 0x59, 0x7f, 0xd1, 0xd1,
-+ 0x6e, 0x80, 0xc7, 0xd1, 0xc2, 0x4c, 0xc3, 0x54,
-+ 0xda, 0x80, 0x9a, 0xd1, 0xc6, 0xfc, 0xd1, 0xd1,
-+ 0xe9, 0x20, 0xfd, 0xd1, 0xfc, 0xe1, 0x81, 0xab,
-+ 0x80, 0x6c, 0x7f, 0xd1, 0x7b, 0x20, 0x9c, 0x54,
-+ 0xd1, 0xc6, 0x9c, 0xda, 0x4c, 0xc6, 0xd1, 0xec,
-+ 0x99, 0xd1, 0xc3, 0x82, 0xe1, 0xde, 0xd1, 0x9a,
-+ 0x20, 0x57, 0xd1, 0xd1, 0x6e, 0xc3, 0xd1, 0xd1,
-+ 0xe8, 0xb1, 0x84, 0xdf, 0x84, 0xac, 0xd1, 0x94,
-+ 0x66, 0x58, 0xd1, 0x84, 0xd1, 0xe8, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x98, 0x98, 0xd1, 0xd1, 0xe8, 0xd1,
-+ 0xd1, 0x63, 0x8a, 0xf1, 0x29, 0xc5, 0x64, 0x25,
-+ 0xc5, 0xc5, 0xc5, 0xc5, 0x25, 0xc5, 0xc5, 0xc5,
-+ 0xf0, 0x85, 0x70, 0x27, 0x3d, 0x28, 0x28, 0x28,
-+ 0x28, 0x2c, 0x28, 0x28, 0x28, 0x2c, 0x2c, 0x45,
-+ 0x89, 0x22, 0x2f, 0xb6, 0xce, 0xd7, 0xd7, 0xb6,
-+ 0xd7, 0x5c, 0x8b, 0x8b, 0x5c, 0x5c, 0xca, 0xa8,
-+ 0xee, 0x2e, 0x93, 0x87, 0xcc, 0xbd, 0xbd, 0xbd,
-+ 0xc2, 0xe2, 0xf2, 0xec, 0x6e, 0xe9, 0xfc, 0xda,
-+ 0xcf, 0xc6, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xab, 0xfa,
-+ 0xec, 0x20, 0xe9, 0x7f, 0x99, 0xde, 0x20, 0xec,
-+ 0x99, 0xe9, 0x80, 0xec, 0x6e, 0xbd, 0x81, 0xd1,
-+ 0x9a, 0x80, 0x80, 0xcf, 0xfd, 0x20, 0xbf, 0xcf,
-+ 0xe9, 0x82, 0xc6, 0xd3, 0xd1, 0xc6, 0x20, 0x6c,
-+ 0x57, 0xda, 0xec, 0xe2, 0xc7, 0xe2, 0xec, 0xda,
-+ 0xf2, 0xf2, 0xd3, 0xab, 0xf2, 0xe2, 0xc6, 0xda,
-+ 0xbf, 0x81, 0xd1, 0x54, 0x9a, 0xc2, 0xf2, 0x57,
-+ 0x82, 0xde, 0xd1, 0x96, 0xbd, 0xe9, 0x99, 0xab,
-+ 0xec, 0x80, 0xc2, 0x9a, 0xec, 0x20, 0xde, 0x99,
-+ 0xe9, 0x20, 0xfc, 0xfa, 0xc2, 0x20, 0xf2, 0xfd,
-+ 0xda, 0x4c, 0xfa, 0x6e, 0x80, 0x57, 0x81, 0x82,
-+ 0xcf, 0xc3, 0xd3, 0x9a, 0x4c, 0xfc, 0x99, 0xde,
-+ 0x20, 0xbd, 0xda, 0xe9, 0xcc, 0x54, 0xd1, 0xe8,
-+ 0xe8, 0x98, 0xdf, 0xdf, 0xd3, 0xd1, 0xac, 0xe8,
-+ 0x74, 0x74, 0x98, 0xdf, 0x98, 0xe8, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8,
-+ 0xb1, 0x63, 0xa9, 0x7a, 0x33, 0xc5, 0xc5, 0xc5,
-+ 0xc5, 0xc5, 0x3e, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
-+ 0x25, 0x85, 0xd6, 0x6a, 0xcb, 0x28, 0x28, 0x28,
-+ 0x2c, 0x2c, 0x28, 0x28, 0x28, 0xe7, 0xcb, 0x67,
-+ 0x38, 0x38, 0xce, 0xd7, 0x8b, 0x24, 0x8b, 0xb6,
-+ 0x8b, 0xd7, 0x5c, 0x5c, 0xca, 0xfb, 0xa8, 0x87,
-+ 0x71, 0xbc, 0x82, 0x71, 0xbd, 0x82, 0xc2, 0xc2,
-+ 0xc2, 0xe2, 0xf2, 0xec, 0x6e, 0xe9, 0xda, 0x57,
-+ 0xfd, 0xc6, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xc7,
-+ 0xfa, 0xfa, 0x7f, 0x54, 0xe8, 0x9c, 0xfa, 0x7f,
-+ 0xab, 0xd1, 0xc7, 0x9c, 0xfa, 0xfa, 0xc3, 0x54,
-+ 0x99, 0x7f, 0xfa, 0x7f, 0x99, 0xfa, 0x7f, 0xfa,
-+ 0x7f, 0xc3, 0xd1, 0xd1, 0xd3, 0xc3, 0xfa, 0x9c,
-+ 0xfa, 0x7f, 0x9c, 0x99, 0xd1, 0x99, 0xc7, 0x7f,
-+ 0xfa, 0xd3, 0xd1, 0xd1, 0xc3, 0x9a, 0xe2, 0x20,
-+ 0xe9, 0x54, 0xd1, 0xd1, 0xd3, 0x99, 0x7f, 0x7f,
-+ 0x7f, 0xb1, 0xd1, 0xc3, 0xfa, 0xc7, 0x99, 0x54,
-+ 0x7f, 0xfa, 0xfa, 0xc7, 0x7f, 0x7f, 0xfa, 0xd3,
-+ 0xd3, 0xfa, 0xfa, 0xd3, 0xfa, 0xc7, 0x7f, 0x9c,
-+ 0xfa, 0x7f, 0xc3, 0xab, 0xc7, 0xd3, 0xa9, 0xfa,
-+ 0x7f, 0xd3, 0xd1, 0xd3, 0x7f, 0xe8, 0xab, 0x7f,
-+ 0xfa, 0x7f, 0xfa, 0x7f, 0x7f, 0x54, 0xe8, 0xd1,
-+ 0xb1, 0xd1, 0xdf, 0xdf, 0x84, 0xd3, 0xd1, 0xe8,
-+ 0x76, 0xba, 0x63, 0xd1, 0x98, 0x63, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0x98, 0x63, 0xb8, 0x68, 0xc5, 0xc5, 0xc5,
-+ 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
-+ 0xc5, 0x85, 0x70, 0x26, 0x67, 0x4e, 0x45, 0x45,
-+ 0x4e, 0x4e, 0x45, 0x45, 0x4e, 0x4e, 0x89, 0xb6,
-+ 0x22, 0xb6, 0x5c, 0x8b, 0x24, 0xe0, 0x24, 0x5c,
-+ 0x5c, 0x8b, 0xca, 0xca, 0xbb, 0xed, 0x82, 0xec,
-+ 0x82, 0xbd, 0xcc, 0xbd, 0xc2, 0x82, 0x82, 0xf2,
-+ 0xe2, 0xf2, 0xec, 0x6e, 0xe9, 0x7b, 0x57, 0x57,
-+ 0xc6, 0x81, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8,
-+ 0xe8, 0xd1, 0xe8, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0xe8, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0x9a, 0x6c,
-+ 0x4c, 0xcf, 0xab, 0x54, 0xd1, 0xd1, 0xe8, 0xe8,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xe8, 0xd1, 0xe8,
-+ 0xd1, 0xab, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xe8,
-+ 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xd1,
-+ 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0x54, 0x63, 0x84, 0xac, 0xac, 0x54, 0xe8,
-+ 0x3f, 0xa9, 0xab, 0xd1, 0x98, 0x98, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1,
-+ 0x63, 0xe8, 0xb1, 0x8f, 0x31, 0x33, 0xc5, 0xc5,
-+ 0xc5, 0x3e, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
-+ 0x25, 0xf0, 0x60, 0x24, 0x9d, 0xa1, 0xa1, 0xa1,
-+ 0x89, 0xa1, 0x89, 0x89, 0x89, 0xa1, 0xb6, 0xd6,
-+ 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0x23,
-+ 0xe0, 0x61, 0x37, 0xa2, 0x71, 0x71, 0x82, 0xbd,
-+ 0xcc, 0xcc, 0x91, 0x82, 0xbd, 0xc2, 0xc2, 0xc2,
-+ 0xf2, 0xec, 0xec, 0x6e, 0xe9, 0xda, 0x57, 0xfd,
-+ 0xc6, 0x81, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0x99,
-+ 0xcf, 0xfd, 0xfa, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x98, 0xac, 0x98, 0x84, 0xd1, 0xe8, 0xe8,
-+ 0xd1, 0xe8, 0x98, 0xd1, 0x98, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x98, 0xab, 0xe8, 0xb1, 0xaa, 0x90, 0xc5, 0xc5,
-+ 0xc5, 0xc5, 0x3e, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
-+ 0x25, 0x85, 0x60, 0x4a, 0x8b, 0x8b, 0x9d, 0xce,
-+ 0xd7, 0xce, 0x2f, 0xb6, 0xb6, 0xe0, 0x21, 0xa2,
-+ 0xa2, 0x60, 0x2e, 0x2e, 0xa2, 0x21, 0xa2, 0x60,
-+ 0x4a, 0x4a, 0xe5, 0xf1, 0x8e, 0xcc, 0x82, 0xcc,
-+ 0x53, 0xcc, 0xbd, 0x91, 0xbd, 0xc2, 0xe2, 0xe2,
-+ 0xf2, 0xec, 0x6e, 0x7b, 0xfc, 0xda, 0xcf, 0xc6,
-+ 0x81, 0x96, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0xd1, 0xd1, 0x98, 0xd1, 0xd1, 0xd1,
-+ 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x63,
-+ 0xe8, 0xd1, 0xa9, 0xa9, 0xb1, 0x32, 0x68, 0xc5,
-+ 0xc5, 0xc5, 0x25, 0xc5, 0x64, 0x25, 0x25, 0x25,
-+ 0xf0, 0x68, 0x82, 0x4b, 0x93, 0x61, 0x70, 0x70,
-+ 0x73, 0x70, 0x61, 0x70, 0x73, 0xa8, 0xfe, 0x71,
-+ 0x39, 0x68, 0x39, 0x33, 0xf0, 0x33, 0x33, 0x33,
-+ 0x25, 0xf0, 0x33, 0x85, 0x32, 0x90, 0x82, 0xcc,
-+ 0x82, 0xbd, 0xbd, 0xc2, 0xc2, 0xc2, 0xf2, 0xf2,
-+ 0xec, 0x6e, 0xe9, 0xfc, 0xda, 0xcf, 0xfd, 0x81,
-+ 0x9a, 0x96, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0xac, 0xac, 0xd1, 0xd1, 0xe8, 0xd1,
-+ 0xe8, 0xd1, 0xd1, 0xd1, 0xac, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x98, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1, 0x98,
-+ 0xe8, 0xe8, 0xe8, 0xd1, 0xa9, 0xfa, 0xa5, 0x85,
-+ 0x5e, 0x5e, 0xc5, 0xc5, 0xc5, 0x3e, 0x3e, 0x25,
-+ 0x36, 0xf1, 0x7a, 0x87, 0xc2, 0x87, 0x87, 0xed,
-+ 0x82, 0xed, 0xed, 0x82, 0xed, 0x31, 0x90, 0x95,
-+ 0x7e, 0x3e, 0xf0, 0x25, 0x33, 0x25, 0xc5, 0x25,
-+ 0x25, 0x3e, 0x25, 0xf0, 0x31, 0xb7, 0xbf, 0xbd,
-+ 0x82, 0xcc, 0xbd, 0xc2, 0xc2, 0xe2, 0xf2, 0xec,
-+ 0x6e, 0xe9, 0xfc, 0xda, 0x57, 0xfd, 0x81, 0x9a,
-+ 0x9a, 0x9c, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xd1, 0xd1,
-+ 0x98, 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0x63,
-+ 0xd1, 0xe8, 0xd3, 0xa9, 0x99, 0xb1, 0x99, 0x91,
-+ 0xf1, 0xf0, 0x25, 0xf0, 0x25, 0x25, 0x36, 0x36,
-+ 0x85, 0xcc, 0x6e, 0xe2, 0xbd, 0x82, 0xc2, 0xc2,
-+ 0xc2, 0xbd, 0x82, 0x82, 0xc2, 0x31, 0xa5, 0x58,
-+ 0x5e, 0x5e, 0x7a, 0x64, 0x25, 0x3e, 0x3e, 0x3e,
-+ 0x3e, 0x3e, 0xf0, 0x68, 0xa5, 0x91, 0xbd, 0x82,
-+ 0xbd, 0xbd, 0xc2, 0xc2, 0xf2, 0xf2, 0xec, 0x6e,
-+ 0x6e, 0xfc, 0xda, 0xcf, 0xfd, 0xc6, 0x81, 0x96,
-+ 0xfa, 0x7f, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x98, 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98,
-+ 0x54, 0x54, 0xd3, 0xd1, 0xc3, 0x99, 0x7f, 0xbe,
-+ 0x90, 0xd9, 0x95, 0x36, 0x36, 0x36, 0x36, 0xf1,
-+ 0x31, 0x6e, 0xe2, 0xbd, 0xec, 0xbd, 0xc2, 0xcc,
-+ 0xc2, 0xbd, 0xc2, 0xe2, 0xbd, 0xc2, 0x5f, 0x43,
-+ 0x86, 0x53, 0x31, 0x33, 0xc5, 0xc5, 0xf1, 0x25,
-+ 0x78, 0x25, 0x72, 0xa5, 0x5f, 0x82, 0x82, 0xcc,
-+ 0xbd, 0xc2, 0xc2, 0xf2, 0xf2, 0xec, 0x6e, 0xe9,
-+ 0xfc, 0xda, 0xcf, 0xc6, 0x81, 0x9a, 0x96, 0x9c,
-+ 0xfa, 0xc7, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xe8, 0xd1, 0xac,
-+ 0x84, 0xd1, 0xd1, 0xd1, 0xac, 0xac, 0xd1, 0xd1,
-+ 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xd1,
-+ 0xd1, 0xac, 0x98, 0xc3, 0xab, 0xab, 0x99, 0xc7,
-+ 0xfa, 0x5d, 0x32, 0x31, 0x31, 0x82, 0x31, 0xa5,
-+ 0x6e, 0xec, 0xf2, 0xe2, 0xc2, 0xc2, 0xc2, 0xe2,
-+ 0xc2, 0xe2, 0xe2, 0xe2, 0xe2, 0xc2, 0xec, 0xf2,
-+ 0x90, 0x32, 0x5f, 0x85, 0x42, 0x36, 0xbf, 0xc4,
-+ 0x25, 0x25, 0xf1, 0xb7, 0xb7, 0xc2, 0xbd, 0xe2,
-+ 0xc2, 0xc2, 0xc2, 0xf2, 0xec, 0x6e, 0xe9, 0xfc,
-+ 0xda, 0xcf, 0xfd, 0xc6, 0x9a, 0x96, 0x9c, 0xfa,
-+ 0xc7, 0xc7, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0x63, 0x63,
-+ 0xdf, 0xac, 0xe8, 0xd1, 0xac, 0xac, 0xd1, 0xd1,
-+ 0x98, 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0xac, 0xac,
-+ 0x54, 0xd1, 0xac, 0xc3, 0x98, 0x99, 0xc7, 0x7f,
-+ 0x7f, 0x96, 0x81, 0x5d, 0x57, 0xb2, 0xb0, 0xc4,
-+ 0xec, 0xec, 0xec, 0xe2, 0xf2, 0xe2, 0xe2, 0xc2,
-+ 0xc2, 0xf2, 0xe2, 0xf2, 0xec, 0xf2, 0x6e, 0xec,
-+ 0x90, 0x90, 0x4b, 0x31, 0x82, 0x5f, 0x90, 0x31,
-+ 0x68, 0x85, 0x53, 0xa5, 0xc2, 0xc2, 0xbd, 0xc2,
-+ 0xe2, 0xf2, 0xf2, 0xec, 0x6e, 0xe9, 0xfc, 0xda,
-+ 0x57, 0xfd, 0x81, 0x9a, 0x96, 0x9c, 0x7f, 0x7f,
-+ 0x99, 0xc3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x98, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1, 0x63, 0x63,
-+ 0x84, 0x84, 0xd1, 0xe8, 0xac, 0xac, 0x98, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x98, 0x63, 0x98, 0xd1,
-+ 0xac, 0xdf, 0xd3, 0xac, 0xab, 0xab, 0xc3, 0x5b,
-+ 0x9c, 0x9c, 0x94, 0xaa, 0xc6, 0x57, 0xfc, 0xfc,
-+ 0xe9, 0xec, 0x7d, 0xf2, 0xec, 0xf2, 0xf2, 0x7d,
-+ 0xf2, 0xec, 0xec, 0x6e, 0xec, 0x6e, 0xec, 0x6e,
-+ 0x4b, 0xde, 0x6e, 0x4b, 0xde, 0xec, 0xf2, 0x6e,
-+ 0x91, 0xb7, 0x4b, 0xc2, 0xe2, 0xe2, 0xe2, 0xe2,
-+ 0xf2, 0xf2, 0xec, 0x6e, 0xe9, 0x7b, 0x57, 0x57,
-+ 0xc6, 0xc6, 0x9a, 0x96, 0x9c, 0xfa, 0x7f, 0x99,
-+ 0xc3, 0xc3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xac, 0x98, 0x54, 0xd3, 0xc3, 0x99, 0x99,
-+ 0x7f, 0x9c, 0x96, 0x81, 0xc6, 0xcf, 0xda, 0xfc,
-+ 0xde, 0xe9, 0x6e, 0xec, 0xec, 0xec, 0xec, 0xec,
-+ 0xec, 0x6e, 0x6e, 0x6e, 0xde, 0xde, 0xde, 0xde,
-+ 0xde, 0xde, 0x7b, 0xe9, 0xe9, 0x6e, 0x6e, 0xec,
-+ 0xec, 0xec, 0xf2, 0xf2, 0xe2, 0xe2, 0xf2, 0xf2,
-+ 0xec, 0xec, 0x6e, 0xa6, 0x7b, 0xda, 0xcf, 0xfd,
-+ 0x81, 0x9a, 0x96, 0xfa, 0x7f, 0xc7, 0x99, 0xc3,
-+ 0xc3, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x98, 0x54, 0x54, 0xd3, 0xab, 0xc3, 0x99,
-+ 0x7f, 0xfa, 0x9c, 0x9a, 0x81, 0xc6, 0xcf, 0x57,
-+ 0xfc, 0x7b, 0xe9, 0xe9, 0x6e, 0x6e, 0x6e, 0xe9,
-+ 0x6e, 0xe9, 0xde, 0x7b, 0xfc, 0xfc, 0xda, 0xda,
-+ 0xda, 0xda, 0xfc, 0xfc, 0xfc, 0x7b, 0xe9, 0xe9,
-+ 0x6e, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec,
-+ 0xec, 0x6e, 0xe9, 0xfc, 0xda, 0x57, 0xfd, 0xc6,
-+ 0x81, 0x96, 0x9c, 0xfa, 0x7f, 0x99, 0xc3, 0xc3,
-+ 0xab, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0x54, 0x54, 0xab, 0xab, 0xc3,
-+ 0xc7, 0x7f, 0x9c, 0x9a, 0x9a, 0x81, 0xfd, 0xcf,
-+ 0x57, 0xda, 0xfc, 0xfc, 0x7b, 0x7b, 0xde, 0x7b,
-+ 0xfc, 0xfc, 0xda, 0xda, 0x57, 0x57, 0xcf, 0xcf,
-+ 0xcf, 0xcf, 0x57, 0x57, 0xda, 0xda, 0xfc, 0xfc,
-+ 0xde, 0xde, 0x6e, 0x6e, 0xec, 0x6e, 0x6e, 0x6e,
-+ 0xe9, 0xe9, 0xfc, 0xda, 0x57, 0xfd, 0x81, 0x9a,
-+ 0x96, 0x9c, 0x7f, 0x99, 0x99, 0xc3, 0xab, 0xd3,
-+ 0xd3, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x98, 0x54, 0x54, 0xab, 0xc3,
-+ 0x99, 0x7f, 0xfa, 0xfa, 0x9a, 0x9a, 0xc6, 0xfd,
-+ 0xcf, 0x57, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda,
-+ 0x57, 0x57, 0xcf, 0xfd, 0xfd, 0xc6, 0xc6, 0xc6,
-+ 0xc6, 0xfd, 0xc6, 0xfd, 0xfd, 0xcf, 0x57, 0xda,
-+ 0xda, 0xfc, 0x7b, 0xde, 0x7b, 0x6e, 0xe9, 0x7b,
-+ 0x7b, 0xfc, 0xda, 0xcf, 0xfd, 0xc6, 0x81, 0x96,
-+ 0x9c, 0xfa, 0xc7, 0xc7, 0xc3, 0xab, 0xd3, 0xd3,
-+ 0xe8, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xac, 0x54, 0xd3, 0xd3, 0xab,
-+ 0xc3, 0x99, 0x7f, 0x7f, 0x9c, 0x96, 0x9a, 0x81,
-+ 0xc6, 0xfd, 0xcf, 0xcf, 0xcf, 0xcf, 0x57, 0xcf,
-+ 0xfd, 0xfd, 0xfd, 0xc6, 0x81, 0x81, 0x81, 0x9a,
-+ 0x9a, 0x81, 0x81, 0x81, 0xc6, 0xc6, 0xfd, 0xcf,
-+ 0x57, 0x57, 0x57, 0xda, 0xda, 0xfc, 0xda, 0xda,
-+ 0xda, 0x57, 0xcf, 0xfd, 0xc6, 0x9a, 0x9a, 0x9c,
-+ 0xfa, 0x7f, 0x99, 0x99, 0xc3, 0xb1, 0x54, 0x54,
-+ 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3,
-+ 0xab, 0xc3, 0x99, 0x7f, 0xfa, 0x9c, 0x96, 0x96,
-+ 0x9a, 0x81, 0xc6, 0xc6, 0xc6, 0xc6, 0xaa, 0xc6,
-+ 0xc6, 0x81, 0x9a, 0x9a, 0x9a, 0x9a, 0x96, 0x96,
-+ 0x96, 0x96, 0x96, 0x9a, 0x9a, 0x81, 0x81, 0xc6,
-+ 0xfd, 0xcf, 0xcf, 0x57, 0x57, 0xda, 0x57, 0x57,
-+ 0xcf, 0xfd, 0xfd, 0x81, 0x81, 0x96, 0x9c, 0xfa,
-+ 0xc7, 0xc7, 0xc3, 0xc3, 0xab, 0xd3, 0xac, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1, 0xd3, 0xd3,
-+ 0xab, 0xc3, 0x99, 0x99, 0x7f, 0xfa, 0x9c, 0x96,
-+ 0x96, 0x96, 0x9a, 0x81, 0x81, 0x81, 0x81, 0x9a,
-+ 0x9a, 0x9a, 0x96, 0x9c, 0xfa, 0x9c, 0x9c, 0xfa,
-+ 0xfa, 0xfa, 0xfa, 0xfa, 0x9c, 0x96, 0x9a, 0x9a,
-+ 0x81, 0x81, 0xc6, 0xc6, 0xc6, 0xfd, 0xfd, 0xc6,
-+ 0xfd, 0x81, 0x81, 0x9a, 0x9a, 0x9c, 0xfa, 0x7f,
-+ 0xc7, 0xc3, 0xc3, 0xb1, 0x54, 0x54, 0xd1, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xe8, 0x54,
-+ 0xd3, 0xab, 0xab, 0x99, 0x99, 0xc7, 0x7f, 0xfa,
-+ 0xfa, 0x9c, 0x96, 0x9c, 0x96, 0x96, 0x96, 0x96,
-+ 0x9c, 0xfa, 0xfa, 0xfa, 0x7f, 0x7f, 0x7f, 0x7f,
-+ 0x7f, 0x7f, 0x7f, 0x7f, 0xfa, 0xfa, 0x9c, 0x96,
-+ 0x96, 0x9a, 0x9a, 0x81, 0x81, 0x81, 0x81, 0x9a,
-+ 0x81, 0x9a, 0x9a, 0x96, 0x9c, 0xfa, 0xc7, 0xc7,
-+ 0x99, 0xc3, 0xab, 0xab, 0xd3, 0xe8, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd3, 0xd3, 0xab, 0xc3, 0x99, 0xc7, 0xba,
-+ 0x7f, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
-+ 0xfa, 0x7f, 0x7f, 0xc7, 0x99, 0x99, 0x99, 0x99,
-+ 0x99, 0x99, 0xc7, 0xc7, 0x7f, 0x7f, 0x7f, 0xfa,
-+ 0x9c, 0x9c, 0x96, 0x96, 0x9a, 0x96, 0x9a, 0x9a,
-+ 0x96, 0x96, 0x9c, 0xfa, 0xfa, 0xc7, 0xc7, 0x99,
-+ 0xc3, 0xab, 0xd3, 0x54, 0xac, 0xac, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1,
-+ 0x54, 0x54, 0x54, 0xab, 0xab, 0xc3, 0x99, 0x99,
-+ 0x99, 0x99, 0xc7, 0x7f, 0x7f, 0x7f, 0xc7, 0x7f,
-+ 0x99, 0xc7, 0x99, 0x99, 0x99, 0xc3, 0xc3, 0xab,
-+ 0xc3, 0xc3, 0xc3, 0xc3, 0x99, 0xc7, 0x7f, 0xc7,
-+ 0x7f, 0xfa, 0xfa, 0xfa, 0x9c, 0x9c, 0x9c, 0x9c,
-+ 0xfa, 0xfa, 0x7f, 0x7f, 0xc7, 0x99, 0xc3, 0xc3,
-+ 0xd3, 0xd3, 0x54, 0x54, 0xe8, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8,
-+ 0xac, 0x54, 0x54, 0xd3, 0xd3, 0xd3, 0xab, 0xc3,
-+ 0xc3, 0x99, 0x99, 0x99, 0xc7, 0x99, 0x99, 0x99,
-+ 0x99, 0xc3, 0xc3, 0xab, 0xab, 0xab, 0xab, 0xd3,
-+ 0xd3, 0xd3, 0xab, 0xab, 0xc3, 0xc3, 0x99, 0x99,
-+ 0xc7, 0xc7, 0xba, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-+ 0x7f, 0x7f, 0x7f, 0x99, 0x99, 0xc3, 0xab, 0xab,
-+ 0xd3, 0xd3, 0x54, 0xac, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0xe8, 0xe8, 0xe8, 0xd3, 0xd3, 0xd3, 0xab,
-+ 0xab, 0xab, 0xc3, 0xa9, 0xc3, 0xc3, 0xc3, 0xc3,
-+ 0xd3, 0xab, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3,
-+ 0xd3, 0x54, 0xd3, 0xd3, 0xd3, 0xab, 0xc3, 0xc3,
-+ 0x99, 0x99, 0x99, 0x99, 0xc7, 0xc7, 0xc7, 0xc7,
-+ 0x99, 0xc3, 0xa9, 0xc3, 0xa9, 0xab, 0xd3, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xe8, 0x54, 0xe8, 0xac, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x99,
-+ 0x6e, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0x99, 0xec, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x6e, 0xe2, 0xd1, 0x54, 0xd1, 0x54, 0x57,
-+ 0x6e, 0x7f, 0xe1, 0x54, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xc7, 0x20, 0xd1, 0x54, 0xfa, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0x54, 0xd1, 0x54, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0x7f, 0xd1, 0x96,
-+ 0x20, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xc3, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xfa, 0x80, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xfa, 0x80, 0x99, 0xd1, 0xd1, 0xd1, 0xbf,
-+ 0x96, 0x54, 0x7f, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd3, 0x7f, 0xd1, 0xc7, 0x20, 0x54,
-+ 0xd1, 0x54, 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xab, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xab, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x7f, 0x20, 0xd3, 0x7f,
-+ 0x20, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xfa, 0x20, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xab, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xbd, 0xfc, 0xd3, 0xd1, 0x9a, 0xbf,
-+ 0xd1, 0x7f, 0xe1, 0x54, 0x54, 0x6e, 0x6c, 0xbf,
-+ 0xe9, 0xd1, 0xfa, 0x80, 0x54, 0xcc, 0xe1, 0xbf,
-+ 0x96, 0xd1, 0xd1, 0x7f, 0x20, 0xd1, 0xd1, 0x7f,
-+ 0x20, 0xd1, 0xd3, 0xec, 0xbf, 0xbf, 0xde, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xab, 0xfa, 0xcc, 0xcc, 0x82,
-+ 0x7f, 0xd1, 0x7f, 0x20, 0x9a, 0xbf, 0x59, 0x7b,
-+ 0xd1, 0xd3, 0xd1, 0xd3, 0xe2, 0x20, 0xcc, 0xc6,
-+ 0x20, 0x9a, 0xbf, 0x80, 0x7b, 0x54, 0xd1, 0x57,
-+ 0x82, 0xbf, 0xbd, 0xc3, 0x54, 0xd1, 0xd1, 0xd3,
-+ 0xcc, 0x81, 0x54, 0x57, 0xe1, 0xc3, 0xd1, 0xe2,
-+ 0x9a, 0x54, 0x57, 0x82, 0xbf, 0x82, 0x99, 0x54,
-+ 0x99, 0x20, 0xcf, 0x59, 0xbf, 0xfa, 0x54, 0x54,
-+ 0x20, 0xfa, 0xd1, 0xd3, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xfd, 0xbf, 0xd3, 0xd1, 0xec, 0xcf,
-+ 0x54, 0x7f, 0x20, 0xd1, 0x99, 0x20, 0xd3, 0xd3,
-+ 0xd1, 0x54, 0xfa, 0x20, 0xd1, 0xfa, 0xe1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x9a, 0x80, 0xd1, 0xd3, 0x7f,
-+ 0x20, 0xd1, 0x99, 0x20, 0x7f, 0xd1, 0x54, 0xd3,
-+ 0xd3, 0xd1, 0x54, 0xd1, 0xbf, 0xcf, 0xd1, 0xfc,
-+ 0xbd, 0xd1, 0xfa, 0x20, 0xec, 0xc3, 0x81, 0xe1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0x9c, 0xe1, 0xd1, 0xfa,
-+ 0x80, 0xf2, 0xc3, 0x9a, 0x20, 0xd1, 0x96, 0x4c,
-+ 0xc3, 0xd1, 0xe9, 0xf2, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0x6e, 0xe9, 0xac, 0xbd, 0x6c, 0x9a, 0xc3, 0x59,
-+ 0xab, 0x9a, 0x6c, 0x7f, 0xd1, 0x7b, 0xe2, 0xd1,
-+ 0xfa, 0x20, 0x6e, 0xc3, 0x6e, 0xbf, 0xd1, 0xd1,
-+ 0x99, 0x54, 0x54, 0xd1, 0x54, 0xd3, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0x80, 0x81, 0xab, 0x80, 0xab,
-+ 0xd1, 0xfa, 0xe1, 0xd1, 0xab, 0xbf, 0xbf, 0xda,
-+ 0xc3, 0xd1, 0x7f, 0xe1, 0xd1, 0x7f, 0x20, 0x54,
-+ 0xd1, 0xd3, 0xd1, 0x7f, 0x20, 0xd1, 0xd3, 0x7f,
-+ 0x80, 0x54, 0xab, 0xcc, 0xbf, 0xfc, 0xab, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x7f, 0x20, 0x99, 0xd1, 0x96,
-+ 0x59, 0xd3, 0x9c, 0x20, 0xab, 0xd1, 0x7f, 0x20,
-+ 0xd1, 0xd1, 0xab, 0x54, 0x7f, 0x20, 0xd3, 0x7f,
-+ 0x20, 0xab, 0xd1, 0x7f, 0x20, 0xd1, 0xda, 0x59,
-+ 0xc2, 0xec, 0xbd, 0x6c, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xc6, 0xbf, 0x99, 0xcc, 0xfc, 0xe9, 0xc6, 0xec,
-+ 0xd1, 0x57, 0x59, 0xf2, 0xec, 0xbd, 0x6c, 0xd1,
-+ 0xfa, 0x20, 0xd1, 0xd1, 0x9a, 0x80, 0x54, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xab, 0x7b, 0xe2, 0xda, 0xec, 0xd1,
-+ 0xd1, 0xfa, 0x20, 0xd1, 0x54, 0xd1, 0xc6, 0xe2,
-+ 0x6c, 0xab, 0x7f, 0x20, 0x54, 0xfa, 0xe1, 0xd1,
-+ 0xd3, 0xd1, 0xd3, 0x7f, 0x20, 0xd1, 0xd1, 0x9c,
-+ 0x20, 0xd3, 0xd1, 0x54, 0xc6, 0xe2, 0x6c, 0xab,
-+ 0x54, 0x54, 0xd1, 0x99, 0x20, 0xd1, 0xd3, 0x96,
-+ 0x20, 0xd1, 0x7f, 0xe1, 0xd1, 0xd3, 0x9c, 0x80,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xc7, 0x20, 0xd1, 0xfa,
-+ 0x20, 0xd1, 0xd3, 0xfa, 0xe1, 0xd1, 0xfc, 0xbd,
-+ 0x99, 0x7f, 0xfa, 0x99, 0x54, 0xd1, 0x54, 0xd1,
-+ 0xc3, 0xe1, 0x57, 0xe9, 0x9c, 0x6c, 0xe9, 0xda,
-+ 0x54, 0xda, 0xbf, 0xc7, 0xfa, 0x7f, 0x99, 0x54,
-+ 0x7f, 0x20, 0xd1, 0xd1, 0x9a, 0xe1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xfa, 0xe1, 0x6c, 0x96, 0xd1,
-+ 0xd1, 0x7f, 0x20, 0xd1, 0xab, 0x99, 0xd1, 0x99,
-+ 0x20, 0x7f, 0x7f, 0x20, 0xd1, 0x7f, 0x20, 0xd3,
-+ 0xd1, 0xd1, 0x54, 0xc7, 0x20, 0xc7, 0x99, 0xbd,
-+ 0x20, 0xd1, 0xd3, 0xc3, 0xd1, 0xc3, 0x20, 0x99,
-+ 0xd1, 0xd1, 0xd1, 0xab, 0xbf, 0xfd, 0xd1, 0xfc,
-+ 0xe2, 0x54, 0xfa, 0x20, 0xd1, 0xd1, 0xfa, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xe8, 0x7f, 0x20, 0xc3, 0xfa,
-+ 0x20, 0xd1, 0xd1, 0xfa, 0x20, 0xd1, 0x7f, 0xe1,
-+ 0x9a, 0xd1, 0xd1, 0x99, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xbf, 0x80, 0xfa, 0x54, 0x59, 0x59, 0x99,
-+ 0xd1, 0xc7, 0xe1, 0x9a, 0xd1, 0x54, 0xd3, 0xd1,
-+ 0xfa, 0x20, 0xd1, 0x54, 0xfc, 0xe2, 0xd1, 0x54,
-+ 0xc7, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xbd, 0xbf, 0xd1, 0xd3,
-+ 0xd1, 0xfa, 0x20, 0xd1, 0x7f, 0xbf, 0xcc, 0x4c,
-+ 0x7b, 0xd1, 0xfa, 0x20, 0xd1, 0xd1, 0xbd, 0xbf,
-+ 0xab, 0xd1, 0xd1, 0xd3, 0xf2, 0x80, 0xbf, 0xfd,
-+ 0x20, 0xd1, 0xc7, 0xbf, 0x6c, 0x6c, 0x7b, 0xe8,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x96, 0xcc, 0xbf, 0xbd,
-+ 0xc7, 0xd1, 0xfa, 0x20, 0xd1, 0xd1, 0xfa, 0x20,
-+ 0xd1, 0xd1, 0xac, 0xd1, 0x54, 0xc2, 0xbf, 0x96,
-+ 0x20, 0xd1, 0xd1, 0x9c, 0x20, 0xd1, 0xd3, 0x9a,
-+ 0xcc, 0x4c, 0xcc, 0xf2, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xec, 0xbf, 0xd1, 0xd1, 0xec, 0xbf, 0xd1,
-+ 0x54, 0xd1, 0x81, 0xbf, 0x6c, 0xcc, 0xf2, 0xd1,
-+ 0xfa, 0x20, 0xc2, 0xe2, 0xc2, 0x99, 0xd1, 0xe8,
-+ 0xe1, 0xfa, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1,
-+ 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd3, 0xd1, 0xac, 0xd1,
-+ 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0xe8, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x99, 0xd1, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1, 0x54,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd3, 0xd1, 0xd1, 0x54, 0x54,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0x54, 0xd3, 0xd1,
-+ 0xc3, 0xd1, 0x54, 0x54, 0xd1, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0xac, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0x54, 0xd1, 0xe8,
-+ 0x54, 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xac, 0xd3, 0xac, 0xd1,
-+ 0xd1, 0xd1, 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd3, 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd3, 0x54, 0xac, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xe8, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xe8, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xac, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd3, 0xd1,
-+ 0xd3, 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0x54, 0xac, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0x54, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xe8, 0xd1, 0xd3, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xc3,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd3, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xe8, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd3, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0x54, 0x54, 0xd1, 0xd3,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0x54, 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xac, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xe8, 0xd1, 0x54, 0x54, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xc7, 0xec, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0x54, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0x54, 0xc3, 0xec,
-+ 0x54, 0xd3, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0x54, 0xd1, 0x7f, 0xc2, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xfa, 0xe1, 0xd1, 0xd3, 0xd1, 0xd1, 0x54,
-+ 0xd3, 0x7f, 0x54, 0xd1, 0xfa, 0x54, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd3, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xda, 0x57, 0xd3, 0xfc, 0xda, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xab, 0xd1, 0x54, 0x54, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd3, 0xd1, 0xab, 0xc7, 0xd1, 0xd1,
-+ 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x7f, 0x20,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd3, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd3,
-+ 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xab, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xc3, 0x54, 0xd1, 0x54, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0x54, 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xc7, 0x20, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0x7f, 0x20, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x7f, 0x20, 0xd1, 0xfa, 0x80, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54,
-+ 0x54, 0xd1, 0x82, 0x7f, 0xd1, 0xc2, 0x7f, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x7f, 0x20, 0xd1, 0xe8,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x96, 0x80,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xfa, 0x20, 0xd1, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x7f, 0xe1, 0xc6, 0x6c, 0x59, 0xde, 0xd1,
-+ 0xc2, 0xe1, 0xbf, 0x4c, 0x20, 0xcc, 0xc6, 0x20,
-+ 0x57, 0x4c, 0x6c, 0x96, 0x54, 0x54, 0x20, 0x7f,
-+ 0xd1, 0x99, 0xcc, 0xd3, 0xc3, 0xbf, 0xbf, 0xc6,
-+ 0xd1, 0x57, 0x80, 0xd3, 0xd1, 0xc2, 0x9a, 0xbf,
-+ 0x81, 0x54, 0x57, 0x80, 0xd1, 0xd1, 0xe2, 0x9a,
-+ 0xcc, 0x81, 0x54, 0x57, 0x20, 0x54, 0xd1, 0xe2,
-+ 0x9a, 0x54, 0xd1, 0xd3, 0xbd, 0x80, 0xbf, 0xc6,
-+ 0x20, 0x7b, 0x82, 0xe8, 0xfd, 0xbf, 0x59, 0xec,
-+ 0xd1, 0xd1, 0xd1, 0xfa, 0xbd, 0xf2, 0xcc, 0xe1,
-+ 0xd3, 0x54, 0xfd, 0xbf, 0xbf, 0xbd, 0x99, 0xd1,
-+ 0xd1, 0xfa, 0xbd, 0xbf, 0x59, 0x20, 0xd1, 0xfa,
-+ 0x20, 0xd1, 0x54, 0x96, 0x20, 0xd1, 0xd1, 0x57,
-+ 0xcc, 0x6c, 0xf2, 0xd1, 0x54, 0xfa, 0x20, 0xfc,
-+ 0xbf, 0xd1, 0x57, 0xcc, 0x82, 0xbd, 0xc7, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xfa, 0x20, 0x9a, 0x6c, 0x59,
-+ 0xde, 0xd1, 0xfa, 0x20, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x9c, 0x80, 0xec, 0xd3, 0x9a, 0x20, 0xd1,
-+ 0xfa, 0x20, 0x54, 0x7f, 0x20, 0xd3, 0x7f, 0xe1,
-+ 0x6e, 0xc3, 0xde, 0xbd, 0xd1, 0x54, 0x7f, 0x54,
-+ 0xd1, 0xfd, 0xe9, 0xd1, 0xcf, 0xe9, 0xe9, 0xe9,
-+ 0xd1, 0xcc, 0x6c, 0x81, 0xab, 0x6c, 0x54, 0x6e,
-+ 0xe9, 0xac, 0xc2, 0x4c, 0x81, 0xd1, 0x80, 0xab,
-+ 0x6e, 0xe9, 0xd1, 0x82, 0xbf, 0x81, 0x99, 0x59,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xfa, 0x20, 0xd3, 0x7f,
-+ 0x80, 0xda, 0xd1, 0x54, 0x7f, 0xd1, 0x99, 0x20,
-+ 0x99, 0xab, 0xd1, 0x82, 0xfd, 0x54, 0xfa, 0x20,
-+ 0xd1, 0x96, 0x4c, 0x99, 0xd1, 0xe9, 0xf2, 0xd1,
-+ 0xc3, 0xcc, 0xcf, 0x54, 0x7f, 0x20, 0xd1, 0xfa,
-+ 0x20, 0xd1, 0xd1, 0x7f, 0xe1, 0x54, 0x54, 0x7f,
-+ 0xd1, 0x99, 0x20, 0x7f, 0x54, 0x7f, 0x20, 0xfc,
-+ 0x54, 0xfa, 0x80, 0x99, 0xb1, 0xe9, 0xf2, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xc7, 0x20, 0xec, 0xc3, 0x81,
-+ 0x20, 0xd1, 0xc7, 0x20, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0x99, 0x20, 0x99, 0xd1, 0x7f, 0x20, 0xd3,
-+ 0xfa, 0x20, 0xd1, 0x7f, 0x20, 0xd1, 0x9c, 0x20,
-+ 0xd1, 0xd1, 0x9c, 0x20, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xc2, 0x9c, 0x54, 0xf2, 0x96, 0xfd, 0xcc,
-+ 0x99, 0xbf, 0xda, 0x6e, 0x9a, 0xc2, 0x54, 0x81,
-+ 0xcc, 0x99, 0x6c, 0xfc, 0xde, 0x81, 0xf2, 0xd1,
-+ 0xc6, 0x82, 0xba, 0x6c, 0xfc, 0x6e, 0x9a, 0xe2,
-+ 0xd3, 0xd1, 0xd3, 0xd1, 0xfa, 0x20, 0xd1, 0xfa,
-+ 0x20, 0xab, 0xd1, 0xd3, 0xc3, 0xcf, 0xda, 0x20,
-+ 0xfa, 0xd1, 0xc7, 0x20, 0xc7, 0xd1, 0x7f, 0xe1,
-+ 0xc3, 0x57, 0x80, 0xf2, 0xec, 0xcc, 0x6c, 0xd1,
-+ 0x99, 0xe1, 0x99, 0xd1, 0xfa, 0x20, 0xd1, 0x9c,
-+ 0x20, 0xd1, 0x54, 0xfa, 0x20, 0xd1, 0xd1, 0xab,
-+ 0xfd, 0x6e, 0x80, 0x7f, 0xd1, 0xfa, 0xe1, 0xd3,
-+ 0xd1, 0xfc, 0x6c, 0xf2, 0xec, 0xbd, 0x6c, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xc7, 0x20, 0xab, 0xd1, 0x9c,
-+ 0xe1, 0xd1, 0x7f, 0x20, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xfa, 0x20, 0xd1, 0x54, 0xfa, 0x20, 0xd1,
-+ 0x7f, 0x20, 0xd1, 0xfa, 0x20, 0xd1, 0xfa, 0x20,
-+ 0xd1, 0xd1, 0xfa, 0x80, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xac, 0x6c, 0xd1, 0x54, 0x6c, 0xd1, 0x99, 0xe1,
-+ 0xda, 0x7b, 0x96, 0xcc, 0xec, 0xfd, 0xd1, 0x99,
-+ 0x20, 0x57, 0x7b, 0xfa, 0x6c, 0x6e, 0x57, 0x54,
-+ 0xc3, 0x20, 0x57, 0x7b, 0x96, 0xbf, 0x6e, 0xcf,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xfa, 0x20, 0x54, 0x7f,
-+ 0x20, 0xd1, 0xd3, 0xd1, 0x6c, 0xcf, 0xc7, 0x20,
-+ 0x7f, 0xd1, 0xfa, 0xe1, 0xab, 0x54, 0xfa, 0x20,
-+ 0xd1, 0xda, 0xcc, 0x7f, 0x7f, 0x7f, 0x99, 0xd1,
-+ 0x99, 0x20, 0xd1, 0x54, 0x9c, 0x80, 0xd1, 0xfa,
-+ 0x20, 0xd1, 0xd1, 0xfa, 0x20, 0xd1, 0xab, 0x6c,
-+ 0x57, 0xc3, 0x20, 0xfa, 0xd1, 0xfa, 0x20, 0xd1,
-+ 0xac, 0xda, 0xcc, 0x7f, 0xfa, 0x7f, 0xc3, 0xd1,
-+ 0x54, 0xd1, 0xd3, 0xfa, 0x80, 0xd1, 0xd1, 0x7f,
-+ 0x20, 0xd1, 0xfa, 0x20, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x7f, 0x20, 0xd1, 0x54, 0x7f, 0x20, 0xd1,
-+ 0x7f, 0x20, 0xab, 0xc7, 0x20, 0x54, 0xfa, 0x20,
-+ 0xd1, 0xd1, 0xe9, 0xe2, 0xd1, 0xd1, 0xab, 0xab,
-+ 0xc6, 0xe9, 0x54, 0xc6, 0x6e, 0xd1, 0xe8, 0xcc,
-+ 0x59, 0x9c, 0xd3, 0x4c, 0x59, 0x7f, 0xd1, 0xd1,
-+ 0xbf, 0x80, 0x9c, 0xd1, 0x4c, 0x59, 0x7f, 0xd1,
-+ 0xd1, 0xcc, 0x80, 0x9c, 0xd1, 0x59, 0x59, 0x99,
-+ 0xd1, 0xd3, 0xfd, 0xc3, 0x7f, 0x20, 0xac, 0xfa,
-+ 0xe1, 0x54, 0xd1, 0x7f, 0x20, 0x99, 0x7f, 0x20,
-+ 0x9c, 0x54, 0xd1, 0x80, 0xfd, 0x54, 0xec, 0x20,
-+ 0xd1, 0x7f, 0x80, 0x9a, 0xd3, 0xd1, 0xab, 0x54,
-+ 0x54, 0x59, 0xfd, 0x99, 0xc2, 0x20, 0xd1, 0xc7,
-+ 0x20, 0x99, 0x99, 0xbd, 0x20, 0xd1, 0xc7, 0x20,
-+ 0xc3, 0xfa, 0xe1, 0x96, 0xd1, 0xfa, 0xe1, 0xd1,
-+ 0xd1, 0x7f, 0x80, 0x9a, 0xd3, 0xd1, 0xc3, 0xd1,
-+ 0xd1, 0xfd, 0x99, 0xc7, 0x20, 0xd1, 0xd3, 0xfa,
-+ 0x20, 0xd1, 0xfa, 0xe1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xfa, 0x20, 0x54, 0xd1, 0xfa, 0x20, 0xd1,
-+ 0x54, 0xe2, 0xbf, 0xc3, 0xe2, 0x6c, 0xfa, 0x20,
-+ 0x6c, 0xbf, 0xc2, 0xab, 0xd3, 0xd1, 0x20, 0x7f,
-+ 0x6e, 0x81, 0xd1, 0xec, 0x81, 0xd1, 0xd1, 0xec,
-+ 0x4c, 0xd1, 0xd1, 0xec, 0xbf, 0xd1, 0xd1, 0xd3,
-+ 0xec, 0xcc, 0xd1, 0xd3, 0xf2, 0xcc, 0xd1, 0xd3,
-+ 0x54, 0x6e, 0x6c, 0xd1, 0xc3, 0xec, 0xcc, 0xd1,
-+ 0x54, 0xd1, 0x20, 0xfa, 0xd1, 0xc2, 0x6c, 0x96,
-+ 0x20, 0xd1, 0xd3, 0xac, 0xf2, 0x80, 0xec, 0xf2,
-+ 0x6c, 0xd1, 0xab, 0x81, 0x6c, 0xbf, 0x7b, 0x20,
-+ 0xd1, 0xd1, 0x81, 0xbf, 0xbf, 0xbf, 0xf2, 0xd1,
-+ 0x54, 0x9a, 0x80, 0x6c, 0x57, 0xe1, 0x54, 0xe8,
-+ 0xe2, 0x80, 0xbf, 0x81, 0xe1, 0xab, 0xe8, 0xc2,
-+ 0x59, 0x6e, 0xe2, 0x59, 0xd1, 0x9c, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0x81, 0xbf, 0xbf, 0xbf, 0xec, 0xd1,
-+ 0xd1, 0x20, 0x7f, 0xfa, 0x20, 0x54, 0xd1, 0x7f,
-+ 0xe1, 0xd3, 0xfa, 0x20, 0xd1, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xe8, 0xd1, 0xe8, 0xd3, 0x7f, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1, 0xab,
-+ 0x59, 0xd1, 0xd1, 0x6c, 0xe8, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xe8, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd3, 0xd1, 0xd1, 0xac, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0x54,
-+ 0x54, 0xd1, 0xd1, 0xab, 0xd1, 0xe8, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd3, 0x54, 0xd1, 0x9c, 0x20, 0xd1, 0x54,
-+ 0xd1, 0x54, 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xab, 0xe8, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xab,
-+ 0xd1, 0x54, 0xd1, 0xd3, 0xd1, 0xd1, 0xab, 0xd1,
-+ 0x54, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0x54, 0xd1, 0xd1, 0xd1, 0x7f, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xac, 0xd1, 0xfa,
-+ 0xde, 0x54, 0x9c, 0x6e, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd3, 0xd1,
-+ 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xe8, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0xc3,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd3, 0x7f, 0x20, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xac, 0xd1, 0xd3, 0xd1, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0x54, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xac,
-+ 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xac, 0xac, 0x54, 0xd1, 0xab,
-+ 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xab,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xab, 0xd1,
-+ 0xd1, 0x54, 0xd3, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xc3, 0xd1, 0xd1, 0xd3, 0xd3, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0xac, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0x54, 0xe8, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd3, 0xd1, 0xd3, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd3,
-+ 0x54, 0xac, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xab, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0x54,
-+ 0xe8, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xab, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xab, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xac, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1,
-+ 0xac, 0x54, 0xd1, 0x54, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0xab, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0x54, 0xd3, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0x54, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0x54, 0xd1, 0xd3, 0xd3, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0xe8,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xc3, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0x54,
-+ 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0x54, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd3, 0xd1, 0xab, 0xd1,
-+ 0xab, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0x54,
-+ 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xc7, 0x6e, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xab, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xc7, 0x6e, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd3, 0xd1, 0xac, 0xd1,
-+ 0xc3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0x54, 0x99, 0x6e, 0xd1, 0x7f, 0xe9, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0xab, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0x7f, 0xbd, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x99, 0xec, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd3, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xac, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xc3, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xc3, 0x99, 0x20, 0xab, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0x54, 0x7f, 0xd1, 0x54, 0x7f, 0x54, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xfc, 0x57, 0xab, 0x57, 0xda, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0x9c, 0x20, 0x54, 0xd1,
-+ 0xd1, 0x54, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xc3, 0x99, 0x20, 0xd3, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0x7f, 0x20, 0x54, 0xc7, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x7f, 0x20, 0xd3, 0xd1, 0x54,
-+ 0xd1, 0xab, 0x7f, 0x20, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x9c, 0x20, 0xd1, 0xd1, 0xd1, 0x54, 0xd3,
-+ 0xfa, 0x20, 0x54, 0x7f, 0x80, 0xab, 0xd1, 0x54,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd3, 0xe2, 0xfa, 0x54, 0xe2, 0xfa, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xab, 0xd1, 0xd3,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd3, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0x9c, 0x20, 0xd1, 0xd1, 0xd1, 0x54, 0xd3,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xab, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xab, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0x9c, 0x20, 0xd1, 0x7f, 0x20, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd3, 0xd1, 0xfa, 0x20, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0x54, 0x7f, 0x20, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0xd3, 0x54, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xfa, 0x20, 0x81, 0xbf, 0x20, 0x7b, 0xd1,
-+ 0xc2, 0x20, 0xbf, 0x59, 0x20, 0x82, 0xfd, 0x20,
-+ 0x57, 0x80, 0x6c, 0xfa, 0xd1, 0xd1, 0x20, 0x7f,
-+ 0xd1, 0x99, 0x6c, 0xd1, 0xc3, 0xbf, 0xd3, 0xfa,
-+ 0x82, 0x6c, 0xbd, 0x99, 0xd3, 0x7f, 0x20, 0xcf,
-+ 0x80, 0x6c, 0x9c, 0xd1, 0xfa, 0x20, 0xd1, 0xd1,
-+ 0x57, 0xbd, 0xbf, 0xbd, 0xc3, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xfa, 0x20, 0x81, 0xbf, 0x20, 0x7b, 0xd1,
-+ 0xd1, 0xda, 0xcc, 0x59, 0xf2, 0xd1, 0xe8, 0x7f,
-+ 0x20, 0x81, 0xcc, 0x80, 0xde, 0xd1, 0xd1, 0x7f,
-+ 0xbd, 0xe2, 0xcc, 0x80, 0x54, 0xfa, 0x20, 0x9a,
-+ 0x6c, 0x80, 0x7b, 0x54, 0xd1, 0x57, 0x82, 0xcc,
-+ 0xbd, 0x99, 0xd1, 0xfa, 0x80, 0xd1, 0xd3, 0xc7,
-+ 0xbd, 0xec, 0xbf, 0x20, 0xd1, 0x54, 0x6e, 0x6c,
-+ 0xcc, 0xe9, 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0x9a,
-+ 0xcc, 0xbf, 0xcc, 0xc7, 0xd3, 0xc7, 0x20, 0xfc,
-+ 0xcc, 0xd1, 0x57, 0xe2, 0xe2, 0xbf, 0xc2, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x7f, 0x20, 0xec, 0x99, 0x96, 0x80, 0xd1,
-+ 0xfa, 0x20, 0x54, 0x7f, 0x20, 0xd3, 0x7f, 0x20,
-+ 0xe9, 0xc3, 0xde, 0xcc, 0xd1, 0xd1, 0xab, 0x54,
-+ 0xd1, 0xc6, 0xe9, 0xd1, 0x57, 0xfc, 0xd1, 0x6c,
-+ 0xc6, 0xd1, 0xfc, 0xbd, 0xd1, 0xfa, 0x80, 0xec,
-+ 0xd1, 0x6e, 0xc2, 0xd3, 0x7f, 0x20, 0x54, 0x9c,
-+ 0x59, 0x99, 0xd1, 0xe9, 0xe2, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x7f, 0x20, 0xec, 0x99, 0x96, 0x80, 0xd1,
-+ 0xd1, 0xab, 0xd1, 0xab, 0x20, 0xc7, 0xd1, 0x7f,
-+ 0x20, 0xf2, 0x99, 0xfa, 0x20, 0x54, 0xd1, 0xbf,
-+ 0xfd, 0xd1, 0xfa, 0x20, 0xd1, 0x7f, 0x20, 0xf2,
-+ 0xc3, 0x96, 0x80, 0xd1, 0xfa, 0x59, 0xc7, 0xd1,
-+ 0xe9, 0xec, 0xd1, 0x96, 0x20, 0x54, 0x54, 0xbf,
-+ 0xfd, 0xd3, 0xfa, 0x80, 0x54, 0x7f, 0x20, 0x99,
-+ 0xd1, 0xab, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x6c,
-+ 0xc6, 0xd1, 0xda, 0xc2, 0xd1, 0x9c, 0x80, 0x7b,
-+ 0xd1, 0x9c, 0x80, 0xe8, 0xd3, 0x57, 0xe2, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x7f, 0x20, 0x54, 0xd1, 0x7f, 0x20, 0xd1,
-+ 0xfa, 0xe1, 0x54, 0xfa, 0xe1, 0xd1, 0xfa, 0x20,
-+ 0xd3, 0xd1, 0x9a, 0x80, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xc2, 0xfa, 0xd1, 0xc2, 0x96, 0x99, 0x20,
-+ 0xc3, 0xd1, 0x96, 0xe1, 0xd1, 0x7f, 0x20, 0xd1,
-+ 0xd1, 0x96, 0x20, 0xd1, 0xfa, 0xe1, 0xd1, 0xfc,
-+ 0x4c, 0xe2, 0xec, 0xbd, 0x6c, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x7f, 0x20, 0x54, 0xd1, 0x7f, 0x20, 0xd1,
-+ 0xd1, 0xc3, 0xfd, 0x7b, 0x20, 0x7f, 0xd3, 0xfa,
-+ 0x20, 0xd1, 0xd1, 0x96, 0x80, 0x54, 0x99, 0x20,
-+ 0xc7, 0xd1, 0xfa, 0x20, 0xd1, 0xfa, 0x20, 0xd1,
-+ 0xd1, 0x7f, 0x20, 0xd1, 0xfc, 0x59, 0xec, 0xf2,
-+ 0xbd, 0x6c, 0xd1, 0x7f, 0x20, 0xd1, 0xc7, 0x20,
-+ 0x99, 0xd1, 0x7f, 0x20, 0xd1, 0x54, 0xbf, 0xbf,
-+ 0xfc, 0xab, 0xd3, 0xd1, 0xd1, 0xd1, 0xc7, 0x20,
-+ 0xab, 0xd1, 0x9c, 0x20, 0xd1, 0x7f, 0x20, 0xd1,
-+ 0xd1, 0xfc, 0xbd, 0x54, 0xd1, 0xda, 0xc2, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0x7f, 0x20, 0xe8, 0xd1, 0xfa, 0x20, 0xd1,
-+ 0x7f, 0x20, 0xd1, 0xfa, 0x20, 0xd1, 0x7f, 0x20,
-+ 0xd1, 0x54, 0x9c, 0x80, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xab, 0x6c, 0x54, 0x54, 0x6c, 0xe8, 0x99, 0x20,
-+ 0x54, 0xd1, 0x9c, 0xe1, 0xd1, 0xfa, 0x20, 0xd1,
-+ 0xd1, 0x9c, 0x59, 0x54, 0xfa, 0x20, 0xd1, 0xda,
-+ 0xcc, 0xc7, 0x7f, 0xfa, 0xc7, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xfa, 0x20, 0xd1, 0x54, 0xfa, 0xe1, 0x54,
-+ 0x54, 0x4c, 0xcf, 0xc3, 0x20, 0x9c, 0xd1, 0xfa,
-+ 0x20, 0xd1, 0xab, 0x7f, 0xe1, 0x54, 0x7f, 0x20,
-+ 0xc3, 0xd1, 0xfa, 0x20, 0xd1, 0x7f, 0x20, 0xd1,
-+ 0xd1, 0xfa, 0x20, 0xd1, 0xda, 0xcc, 0x7f, 0xfa,
-+ 0xfa, 0x99, 0xd3, 0x9c, 0xe1, 0xd1, 0xfa, 0xe1,
-+ 0xc3, 0xd3, 0x7f, 0x20, 0xd1, 0xd1, 0xd3, 0x81,
-+ 0xe2, 0x6c, 0xd3, 0xd1, 0x54, 0x54, 0xc3, 0x20,
-+ 0x54, 0xd1, 0x96, 0x80, 0xd1, 0xfa, 0x20, 0xd1,
-+ 0xd1, 0xfd, 0x4c, 0x54, 0xd1, 0xec, 0xc2, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x96, 0x20, 0xd1, 0x54, 0xfa, 0x20, 0xac,
-+ 0xfa, 0xe1, 0xab, 0x99, 0x20, 0xd3, 0x7f, 0x20,
-+ 0xd1, 0x54, 0x7b, 0xf2, 0x54, 0x54, 0xc3, 0xd3,
-+ 0x9a, 0xec, 0xd1, 0x81, 0xec, 0xd1, 0x54, 0x6c,
-+ 0x81, 0x54, 0xda, 0xc2, 0xd3, 0xfa, 0xe1, 0xd1,
-+ 0xd1, 0xec, 0xf2, 0xac, 0x7f, 0xe1, 0x54, 0xc7,
-+ 0x80, 0xc6, 0xd1, 0xd1, 0xc3, 0xd1, 0xd1, 0xcf,
-+ 0x99, 0xfa, 0x20, 0xd1, 0xd1, 0xfa, 0x20, 0xd1,
-+ 0x7f, 0x80, 0xc7, 0x7f, 0x20, 0x7f, 0xd1, 0x7f,
-+ 0x20, 0x54, 0xd1, 0x7f, 0x20, 0xd1, 0x54, 0x80,
-+ 0xfd, 0xd1, 0xf2, 0x20, 0xd1, 0xfa, 0x20, 0xd1,
-+ 0xd1, 0xfa, 0xe1, 0xd3, 0x7f, 0x80, 0x96, 0xd1,
-+ 0xd1, 0x99, 0xd1, 0x7f, 0x20, 0xd1, 0x54, 0x59,
-+ 0xfd, 0xd1, 0xe2, 0x20, 0xd1, 0xc3, 0xe8, 0xd1,
-+ 0xc3, 0x20, 0x7f, 0xd1, 0xfd, 0xd3, 0xd3, 0x6c,
-+ 0xc6, 0xd3, 0xda, 0xc2, 0x54, 0xfa, 0x20, 0x54,
-+ 0x54, 0x99, 0x4c, 0x6e, 0xec, 0xbf, 0xe2, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xfa, 0x20, 0xab, 0xd1, 0x7f, 0x20, 0xd3,
-+ 0xd1, 0xe2, 0x6c, 0x99, 0xc2, 0x6c, 0x96, 0x20,
-+ 0x6c, 0xbf, 0xe2, 0x7f, 0xd1, 0xd1, 0x20, 0x7f,
-+ 0xe2, 0x9a, 0xd1, 0xf2, 0x96, 0xd3, 0xd1, 0x96,
-+ 0xbf, 0xcc, 0x82, 0x7f, 0xd1, 0x9c, 0x20, 0x6c,
-+ 0xbf, 0xf2, 0xc7, 0x54, 0x7f, 0x20, 0xd1, 0xd1,
-+ 0x9a, 0x82, 0x6c, 0xcc, 0xec, 0xd3, 0xd1, 0x20,
-+ 0x7f, 0x7f, 0x80, 0xab, 0xd1, 0x7f, 0x20, 0xd1,
-+ 0xd1, 0xbd, 0x6c, 0xec, 0xf2, 0x59, 0xd3, 0xfa,
-+ 0x20, 0xd1, 0x54, 0x7f, 0x20, 0xd1, 0xd1, 0xc6,
-+ 0x4c, 0xbf, 0xfc, 0x20, 0xab, 0x99, 0x20, 0x54,
-+ 0xd3, 0x7f, 0x20, 0xd1, 0xd1, 0xfd, 0xcc, 0x6c,
-+ 0xbf, 0xf2, 0xd1, 0xfa, 0x20, 0xd1, 0x54, 0xc6,
-+ 0x59, 0xbf, 0xfc, 0x20, 0xd1, 0x99, 0xbf, 0x6c,
-+ 0x4c, 0xfc, 0xd1, 0xab, 0x20, 0x7f, 0xd3, 0xfa,
-+ 0x82, 0x6c, 0x82, 0xc7, 0xd1, 0x7f, 0x20, 0xd1,
-+ 0xd1, 0xd3, 0x7f, 0x57, 0x81, 0x6e, 0xe9, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xab, 0xd1,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xfa, 0x20,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x54,
-+ 0x6c, 0xd1, 0xc3, 0x6c, 0xd3, 0xd1, 0x54, 0xd1,
-+ 0xac, 0xd1, 0xd1, 0xd1, 0xd1, 0xc7, 0x20, 0xd1,
-+ 0xac, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0xab, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd3, 0xe8, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0x54, 0xd1, 0xd1, 0xab, 0xd1,
-+ 0xd1, 0xd1, 0xc3, 0xd1, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xe8, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1, 0xab,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0x99, 0xfa, 0x54, 0x7f, 0x6c, 0x57, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xfa, 0x20,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0x96,
-+ 0x6e, 0xc3, 0xfa, 0xe9, 0x54, 0xd1, 0xd1, 0xe8,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd3, 0xfa, 0x20, 0xd3,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0x54, 0xd1, 0xd3,
-+ 0xe8, 0xd1, 0xd1, 0xd3, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xab,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0x54, 0x54, 0x54, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xab, 0xd1,
-+ 0xd1, 0x54, 0x54, 0xe8, 0xd1, 0xd1, 0xab, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xe8,
-+ 0xd1, 0xe8, 0xe8, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xc6, 0x6c, 0x20, 0x80, 0xde, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xac, 0xd1, 0x54, 0xd1,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0x54,
-+ 0xd1, 0xc3, 0xd1, 0xd1, 0x54, 0xd1, 0xab, 0xd1,
-+ 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xab, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd3, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd1, 0xac, 0xd1,
-+ 0xab, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xab, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xac, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xab, 0xd1, 0xac, 0xd1, 0xab, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0x99, 0xe8, 0xd1,
-+ 0xd1, 0xd1, 0xd3, 0xd1, 0xd1, 0xd1, 0xab, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0xd1, 0xac, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xab, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xab, 0xd1, 0xd1, 0xd3,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd3, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xac, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd3,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0xab, 0xe8, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xe8, 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0x54,
-+ 0x54, 0xd1, 0xd1, 0xd1, 0xd1, 0xe8, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0x54, 0xd1, 0x54, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0x54, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0x54, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd3, 0xd1, 0xd3, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xe8, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xe8, 0xd1, 0x54, 0xd1, 0xd1, 0x54, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0x54,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1,
-+ 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1
- };
-
--#endif
-+#endif /* !__HAVE_ARCH_LINUX_LOGO */
-
--#ifndef __HAVE_ARCH_LINUX_LOGO16
-+#ifndef __HAVE_ARCH_LINUX_LOGOBW
-
--unsigned char linux_logo16_red[] __initdata = {
--0xa5, 0x09, 0x3d, 0x4d, 0xfd, 0xf3, 0x1e, 0xeb, 0x8b, 0xc1, 0x5c, 0x85, 0xca, 0x25, 0x66, 0x00
-+unsigned char linux_logo_bw[] __initdata = {
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xf0, 0x0f, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xcf, 0xf3, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xbf, 0xfc, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfd, 0xff, 0xf3, 0xdf, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfd, 0xff, 0xf7, 0xef, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0x9f, 0x87, 0xfb, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0x0f, 0x03, 0xfb, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0x67, 0x33, 0xfb, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0xe7, 0x79, 0xfb, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0xf7, 0x79, 0xfb, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0xff, 0xf9, 0xf7, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0x60, 0x3b, 0xf7, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0x89, 0x07, 0xfb, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0x00, 0x03, 0xfb, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0x00, 0x0d, 0xfb, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0x80, 0x33, 0xfd, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0xc0, 0xc3, 0xfd, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0xff, 0x0d, 0xdd, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xfb, 0x40, 0x31, 0xee, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xf7, 0x20, 0xc1, 0xee, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xf7, 0x1f, 0x00, 0xff, 0x7f, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xef, 0x00, 0x00, 0x7f, 0xbf, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xee, 0x00, 0x00, 0x7f, 0xbf, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xde, 0x00, 0x00, 0x7f, 0xdf, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xbc, 0x00, 0x00, 0x3f, 0xef, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x3f, 0xf7, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0x7c, 0x00, 0x00, 0x1f, 0xf7, 0xff, 0xff,
-+ 0xff, 0xff, 0xfe, 0xff, 0x1c, 0x07, 0xdf, 0xfb, 0xff, 0xff,
-+ 0xff, 0xff, 0xfd, 0xfc, 0x08, 0x0f, 0xef, 0xfd, 0xff, 0xff,
-+ 0xff, 0xff, 0xfd, 0xf8, 0x00, 0x01, 0xef, 0xfd, 0xff, 0xff,
-+ 0xff, 0xff, 0xfb, 0xf0, 0x00, 0x00, 0x7f, 0xfe, 0xff, 0xff,
-+ 0xff, 0xff, 0xfb, 0xe0, 0x00, 0x00, 0x1f, 0xfe, 0xff, 0xff,
-+ 0xff, 0xff, 0xf7, 0xe0, 0x00, 0x00, 0x07, 0xbf, 0x7f, 0xff,
-+ 0xff, 0xff, 0xf7, 0xc0, 0x00, 0x00, 0x03, 0xbf, 0x7f, 0xff,
-+ 0xff, 0xff, 0xef, 0xc0, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
-+ 0xff, 0xff, 0xef, 0x80, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
-+ 0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x03, 0xdf, 0xbf, 0xff,
-+ 0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x01, 0xef, 0xdf, 0xff,
-+ 0xff, 0xff, 0xdf, 0x80, 0x00, 0x00, 0x01, 0xef, 0xdf, 0xff,
-+ 0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
-+ 0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
-+ 0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
-+ 0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x01, 0xef, 0xdf, 0xff,
-+ 0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x03, 0x03, 0xdf, 0xff,
-+ 0xff, 0xff, 0xbf, 0x00, 0x20, 0x00, 0x02, 0xfd, 0xdf, 0xff,
-+ 0xff, 0xff, 0xa3, 0x80, 0x00, 0x00, 0x1f, 0xff, 0xdf, 0xff,
-+ 0xff, 0xff, 0xc1, 0xc0, 0x00, 0x00, 0x11, 0xff, 0x3f, 0xff,
-+ 0xff, 0xff, 0x80, 0xe0, 0x00, 0x00, 0x21, 0xfe, 0x3f, 0xff,
-+ 0xff, 0xff, 0x00, 0x70, 0x00, 0x00, 0x21, 0xfc, 0x3f, 0xff,
-+ 0xff, 0xfe, 0x00, 0x3c, 0x00, 0x00, 0x20, 0xf8, 0x3f, 0xff,
-+ 0xff, 0xf0, 0x00, 0x3e, 0x00, 0x00, 0x20, 0x00, 0x3f, 0xff,
-+ 0xff, 0xc0, 0x00, 0x1f, 0x00, 0x00, 0x20, 0x00, 0x3f, 0xff,
-+ 0xff, 0xc0, 0x00, 0x1f, 0x80, 0x00, 0x20, 0x00, 0x1f, 0xff,
-+ 0xff, 0xc0, 0x00, 0x0f, 0x80, 0x00, 0x20, 0x00, 0x07, 0xff,
-+ 0xff, 0xc0, 0x00, 0x07, 0x80, 0x00, 0x20, 0x00, 0x03, 0xff,
-+ 0xff, 0xc0, 0x00, 0x07, 0x80, 0x00, 0x60, 0x00, 0x01, 0xff,
-+ 0xff, 0xc0, 0x00, 0x02, 0x00, 0x00, 0xe0, 0x00, 0x01, 0xff,
-+ 0xff, 0xc0, 0x00, 0x01, 0x00, 0x01, 0xe0, 0x00, 0x01, 0xff,
-+ 0xff, 0xc0, 0x00, 0x00, 0x80, 0x07, 0xe0, 0x00, 0x03, 0xff,
-+ 0xff, 0xc0, 0x00, 0x00, 0x80, 0x3f, 0xe0, 0x00, 0x0f, 0xff,
-+ 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x1f, 0xff,
-+ 0xff, 0xc0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0x7f, 0xff,
-+ 0xff, 0xe0, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x00, 0xff, 0xff,
-+ 0xff, 0xfc, 0x00, 0x00, 0x7f, 0xff, 0xc0, 0x03, 0xff, 0xff,
-+ 0xff, 0xff, 0xc0, 0x00, 0x70, 0x00, 0xc0, 0x07, 0xff, 0xff,
-+ 0xff, 0xff, 0xfc, 0x00, 0x8f, 0xff, 0x20, 0x0f, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0x01, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- };
-
--unsigned char linux_logo16_green[] __initdata = {
--0xb7, 0x66, 0x91, 0x57, 0xd0, 0xb7, 0x21, 0xe1, 0x91, 0x97, 0x51, 0x73, 0xb6, 0x3e, 0x66, 0x00
--};
-+#endif /* !__HAVE_ARCH_LINUX_LOGOBW */
-
--unsigned char linux_logo16_blue[] __initdata = {
--0xc9, 0xd4, 0xe9, 0x5e, 0x19, 0x11, 0x23, 0xc4, 0x8b, 0x16, 0x22, 0x22, 0x4e, 0x5c, 0x66, 0x00
--};
-+#ifndef __HAVE_ARCH_LINUX_LOGO16
-
- unsigned char linux_logo16[] __initdata = {
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x66, 0x66, 0x66, 0x66, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x66, 0xd3, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x33, 0x66, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xd3, 0xee, 0xee, 0xee, 0x88, 0xee, 0x88, 0xee, 0xee, 0xee, 0xee, 0x3d, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0x3e, 0xee, 0xee, 0x88, 0x83, 0x80, 0x83, 0x08, 0xe8, 0x00, 0xee, 0x8e, 0xee, 0xee, 0xd6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6d, 0xee, 0xee, 0x80, 0xee, 0x70, 0x03, 0x87, 0x83, 0x08, 0xe8, 0x80, 0xe8, 0x08, 0xee, 0x8e, 0xee, 0x36, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xee, 0xee, 0xee, 0xe0, 0x8e, 0x07, 0x0e, 0x80, 0x8e, 0x88, 0x38, 0x80, 0xe8, 0x80, 0x38, 0x08, 0xee, 0xee, 0x36, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xee, 0xe8, 0x8e, 0xee, 0x30, 0x8e, 0x80, 0x0e, 0xe0, 0x83, 0x88, 0xe8, 0x78, 0x38, 0x08, 0xe0, 0x83, 0xe7, 0x8e, 0xee, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0x3e, 0xee, 0x30, 0x8e, 0xee, 0x38, 0x0e, 0xee, 0xee, 0x3e, 0x8b, 0xee, 0xe3, 0xee, 0xe8, 0x0e, 0x80, 0xee, 0x88, 0x0e, 0xee, 0xee, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6e, 0xee, 0x88, 0x38, 0x7e, 0xee, 0xe3, 0x8e, 0xee, 0xee, 0x87, 0x45, 0x5b, 0xe3, 0x3e, 0xea, 0xee, 0xe0, 0xee, 0x00, 0x8e, 0xee, 0xee, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xee, 0xe8, 0x87, 0xe3, 0x08, 0xee, 0xee, 0xee, 0x31, 0x89, 0xc4, 0x57, 0x77, 0x78, 0x11, 0x11, 0xee, 0x33, 0xe8, 0x00, 0xee, 0xee, 0xe0, 0xee, 0xaf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xae, 0xe8, 0xe3, 0x08, 0x03, 0xe8, 0xee, 0xe3, 0x11, 0x18, 0x55, 0x55, 0x54, 0x77, 0x77, 0xc8, 0x11, 0x11, 0x1e, 0xe3, 0xee, 0xee, 0xee, 0x87, 0x0e, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xee, 0x87, 0x83, 0xe8, 0x8e, 0xee, 0xe1, 0x11, 0x11, 0xc4, 0x54, 0x55, 0x55, 0x54, 0x77, 0x74, 0x81, 0x11, 0x12, 0x23, 0xee, 0xee, 0xe8, 0x70, 0x8e, 0x8e, 0x36, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xee, 0x3e, 0x0e, 0x38, 0xee, 0xe1, 0x11, 0x11, 0x18, 0x45, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x5e, 0x11, 0x12, 0x21, 0x13, 0xee, 0xe8, 0x7e, 0x38, 0x08, 0xe3, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xee, 0xee, 0xe3, 0xe0, 0xe3, 0xe8, 0x22, 0x22, 0x21, 0x24, 0x45, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xd1, 0x11, 0x21, 0x11, 0x1e, 0xe3, 0x8e, 0xe7, 0xee, 0xee, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xde, 0xee, 0xee, 0xee, 0x3e, 0xee, 0x20, 0x22, 0x22, 0x21, 0xc4, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0xed, 0x11, 0x21, 0x11, 0xd1, 0xee, 0x3e, 0x08, 0xee, 0x08, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xf6, 0xee, 0x80, 0xee, 0xee, 0xee, 0x31, 0x11, 0x1d, 0x11, 0x18, 0x44, 0x45, 0x9e, 0x3b, 0xe5, 0x55, 0x55, 0x55, 0x55, 0xc1, 0xd1, 0x81, 0x1d, 0x11, 0x13, 0xe3, 0x88, 0x38, 0x00, 0xee, 0x3f, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0x6e, 0xee, 0x88, 0x08, 0xee, 0xe2, 0x11, 0x11, 0x11, 0x11, 0x1c, 0x4c, 0x4b, 0xe3, 0xd0, 0xa5, 0x55, 0x54, 0x55, 0x54, 0x51, 0xdd, 0x21, 0xd1, 0xdd, 0x11, 0xde, 0x33, 0x87, 0x0e, 0xee, 0xe6, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0x3e, 0xe3, 0x30, 0x80, 0xee, 0x12, 0x11, 0x12, 0x21, 0x11, 0x24, 0x74, 0x49, 0x6e, 0x8e, 0x65, 0x55, 0x55, 0x55, 0xc7, 0x53, 0x11, 0x80, 0x01, 0x11, 0x20, 0x00, 0xee, 0x88, 0x3e, 0x88, 0x8e, 0x6f, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xf3, 0xee, 0x88, 0x3a, 0x88, 0xe1, 0x12, 0x21, 0x11, 0x21, 0x11, 0x07, 0x4c, 0x49, 0xf3, 0x0f, 0xa5, 0x55, 0x54, 0x55, 0x77, 0x48, 0x22, 0x22, 0x22, 0x22, 0x21, 0x12, 0x2e, 0x3e, 0xe8, 0x00, 0x8e, 0x3f, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0x6e, 0xee, 0x07, 0x0e, 0x3e, 0x21, 0x12, 0x21, 0x12, 0x12, 0x12, 0x04, 0x44, 0x48, 0x66, 0x6f, 0xa5, 0x55, 0x54, 0x55, 0x47, 0x48, 0x11, 0x11, 0x11, 0x12, 0x21, 0x11, 0x11, 0xee, 0x87, 0x80, 0xee, 0xed, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xee, 0xe3, 0x80, 0x00, 0xe8, 0x11, 0x12, 0x11, 0x22, 0x22, 0x22, 0xc7, 0xc4, 0x77, 0xc9, 0x99, 0x95, 0x55, 0x55, 0x55, 0x77, 0x7c, 0x11, 0x11, 0x11, 0x11, 0x22, 0x11, 0x11, 0x1e, 0x38, 0x8e, 0xe8, 0x8e, 0x6f, 0xff, 0xff,
--0xff, 0xff, 0xfd, 0xee, 0x8e, 0x33, 0x8e, 0xe2, 0x11, 0x12, 0x11, 0x12, 0x21, 0x11, 0x74, 0x44, 0x44, 0x45, 0x55, 0x55, 0x55, 0x55, 0x55, 0x57, 0x55, 0x81, 0x12, 0x11, 0x11, 0x22, 0x11, 0x21, 0x1e, 0xe3, 0x3e, 0x00, 0xee, 0x3f, 0xff, 0xff,
--0xff, 0xff, 0xfe, 0xe3, 0x80, 0x8e, 0x3e, 0x12, 0x11, 0x12, 0x11, 0x22, 0x21, 0x18, 0x44, 0x45, 0x55, 0x55, 0x55, 0x55, 0x55, 0x54, 0x44, 0x74, 0x4c, 0x81, 0x10, 0x21, 0x12, 0x21, 0x12, 0x01, 0x22, 0xee, 0x87, 0xe3, 0xee, 0xe6, 0xff, 0xff,
--0xff, 0xff, 0xde, 0xee, 0x33, 0x80, 0xe3, 0x12, 0x11, 0x12, 0x11, 0x20, 0x02, 0xcc, 0xcc, 0x55, 0x55, 0x55, 0x55, 0x54, 0x44, 0x47, 0x7c, 0x8b, 0x31, 0x12, 0x12, 0x22, 0x12, 0x11, 0x21, 0x02, 0x12, 0x1e, 0x38, 0xee, 0xe8, 0xe3, 0xff, 0xff,
--0xff, 0xff, 0xee, 0xe0, 0x83, 0x3e, 0xe1, 0x12, 0x11, 0x12, 0x11, 0x10, 0x21, 0x12, 0x16, 0x66, 0x66, 0xaa, 0xaa, 0xaa, 0xaa, 0xba, 0x6f, 0xff, 0xf1, 0x11, 0x22, 0x21, 0x12, 0x22, 0x11, 0x22, 0x12, 0x13, 0xee, 0xe8, 0x08, 0x8e, 0x6f, 0xff,
--0xff, 0xf6, 0xee, 0x87, 0x78, 0x8e, 0x12, 0x22, 0x11, 0x12, 0x22, 0x12, 0x01, 0x22, 0x2f, 0xff, 0x66, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xff, 0xff, 0xfd, 0x12, 0x10, 0x00, 0x20, 0x00, 0x22, 0x00, 0x00, 0x20, 0xee, 0x00, 0x80, 0x8e, 0x3f, 0xff,
--0xff, 0xf3, 0xee, 0x3e, 0x00, 0x8e, 0x12, 0x12, 0x11, 0x12, 0x22, 0x10, 0x21, 0x12, 0x1f, 0xff, 0x66, 0x6f, 0xff, 0xf6, 0xad, 0x66, 0xdf, 0xff, 0xfd, 0x11, 0x12, 0x22, 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0xe3, 0x88, 0x83, 0xee, 0xef, 0xff,
--0xff, 0x6e, 0xe8, 0xe3, 0xae, 0xe1, 0x11, 0x12, 0x21, 0x12, 0x21, 0x12, 0x21, 0x11, 0x1f, 0xfd, 0xe3, 0x6f, 0xff, 0x6e, 0xe8, 0xe6, 0x6f, 0xff, 0xf6, 0x11, 0x11, 0x11, 0x12, 0x22, 0x11, 0x12, 0x22, 0x11, 0x1e, 0x33, 0x3e, 0x88, 0xe6, 0xff,
--0xff, 0x6e, 0xe0, 0x88, 0xee, 0xe1, 0x11, 0x22, 0x21, 0x12, 0x12, 0x11, 0x11, 0x11, 0x1f, 0x68, 0x80, 0xef, 0xff, 0xe0, 0x8e, 0x88, 0xff, 0xff, 0xf6, 0x11, 0x11, 0x11, 0x12, 0x02, 0x21, 0x22, 0x22, 0x22, 0x2e, 0xee, 0x80, 0x00, 0xe3, 0xff,
--0xff, 0x3e, 0x3e, 0x80, 0x08, 0x31, 0x21, 0x12, 0x21, 0x12, 0x11, 0x22, 0x11, 0x21, 0x1f, 0x3e, 0x68, 0x76, 0xf6, 0x00, 0x63, 0xe0, 0x3f, 0xff, 0xf6, 0x11, 0x11, 0x11, 0x12, 0x22, 0x11, 0x12, 0x22, 0x21, 0x11, 0xee, 0x8e, 0x33, 0xee, 0xff,
--0xff, 0xee, 0xe3, 0x33, 0x8e, 0x11, 0x11, 0x12, 0x12, 0x12, 0x21, 0x12, 0x22, 0x22, 0x1f, 0xe3, 0xee, 0x7d, 0x66, 0x78, 0xf3, 0xe0, 0x8f, 0xff, 0xff, 0x22, 0x11, 0x22, 0x20, 0x02, 0x22, 0x22, 0x22, 0x22, 0x11, 0xee, 0x3e, 0xe8, 0xee, 0x6f,
--0xf6, 0xee, 0x80, 0x8e, 0x3e, 0x11, 0x11, 0x22, 0x12, 0x12, 0x11, 0x12, 0x11, 0x12, 0x1f, 0x83, 0x6d, 0x0a, 0x66, 0x08, 0xff, 0xf0, 0x0f, 0xff, 0xf6, 0x22, 0x11, 0x20, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x21, 0xee, 0x80, 0x08, 0x8e, 0xdf,
--0xfd, 0xe3, 0x80, 0x70, 0x8e, 0x12, 0x11, 0x12, 0x11, 0x12, 0x11, 0x11, 0x11, 0x11, 0x1f, 0xe8, 0xfa, 0x95, 0x59, 0xcc, 0x6f, 0x67, 0x8f, 0xff, 0xff, 0x11, 0x11, 0x11, 0x12, 0x11, 0x12, 0x21, 0x12, 0x21, 0x11, 0x1e, 0xee, 0x33, 0xee, 0x3f,
--0xfa, 0xee, 0x87, 0x08, 0xe1, 0x11, 0x11, 0x12, 0x21, 0x12, 0x21, 0x12, 0x22, 0x22, 0x1f, 0x60, 0xb9, 0x95, 0x5c, 0x47, 0xcb, 0x77, 0x3f, 0xff, 0xff, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x11, 0x12, 0x11, 0x11, 0x1e, 0x3e, 0x88, 0x8e, 0x3f,
--0xf3, 0xee, 0xee, 0x88, 0xe1, 0x21, 0x11, 0x12, 0x11, 0x12, 0x11, 0x12, 0x12, 0x12, 0x16, 0xfb, 0x55, 0x55, 0xc4, 0x44, 0x44, 0x4c, 0xaf, 0xff, 0xff, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x11, 0x11, 0x1e, 0xe0, 0x88, 0x08, 0xe6,
--0xfe, 0xee, 0xee, 0x33, 0xe1, 0x11, 0x11, 0x12, 0x21, 0x12, 0x11, 0x11, 0x11, 0x11, 0x16, 0x65, 0x59, 0x55, 0x5c, 0x74, 0x44, 0xcc, 0x9f, 0xff, 0xff, 0xd1, 0x11, 0x11, 0x11, 0x11, 0xd1, 0x12, 0x22, 0x12, 0x11, 0x13, 0xe0, 0x88, 0x0e, 0xe6,
--0xfe, 0xe8, 0x00, 0x0e, 0xe1, 0x12, 0x11, 0x12, 0x11, 0x12, 0x11, 0x11, 0x11, 0x11, 0x16, 0xb5, 0x95, 0x55, 0xc4, 0x4c, 0xc9, 0x99, 0xbf, 0xff, 0xff, 0x12, 0x11, 0x21, 0x12, 0x11, 0x12, 0x22, 0x12, 0x00, 0x00, 0x2e, 0x33, 0xee, 0x3e, 0xe6,
--0x6e, 0x38, 0x8e, 0x00, 0x31, 0x21, 0x11, 0x22, 0x11, 0x12, 0x11, 0x10, 0x11, 0x11, 0x1d, 0x69, 0x55, 0x55, 0x4c, 0x79, 0x99, 0x99, 0xaf, 0xf6, 0xff, 0x61, 0x21, 0x20, 0x22, 0x11, 0x11, 0x20, 0x12, 0x22, 0x21, 0x13, 0xee, 0xee, 0xee, 0xe6,
--0x6e, 0xe3, 0x88, 0x88, 0x31, 0x12, 0x11, 0x22, 0x11, 0x12, 0x22, 0x20, 0x21, 0x12, 0x2d, 0xfb, 0x99, 0x99, 0xc9, 0x99, 0x99, 0x9c, 0xef, 0xfd, 0xdf, 0xfd, 0x21, 0x20, 0x22, 0x21, 0x21, 0x12, 0x22, 0x11, 0x11, 0x13, 0xe8, 0x07, 0x78, 0xed,
--0x6e, 0xee, 0xe3, 0x3e, 0x31, 0x11, 0x11, 0x12, 0x11, 0x11, 0x11, 0x12, 0x11, 0x11, 0x16, 0xf8, 0x99, 0xcc, 0xc9, 0x59, 0x9c, 0x00, 0x8f, 0xff, 0xa6, 0xf6, 0x11, 0x10, 0x22, 0x21, 0x11, 0x12, 0x22, 0x11, 0x11, 0x1d, 0xee, 0x08, 0x88, 0xe6,
--0x6e, 0xe0, 0x08, 0xee, 0x32, 0x11, 0x11, 0x12, 0x16, 0x66, 0x66, 0xdd, 0xdd, 0x11, 0x1f, 0xf8, 0x09, 0xcc, 0x55, 0x99, 0xc0, 0x77, 0x73, 0xff, 0x6f, 0xff, 0x66, 0x66, 0x6d, 0x12, 0x21, 0x20, 0x02, 0x11, 0x11, 0x13, 0xe3, 0x33, 0x3e, 0xed,
--0x6e, 0x38, 0x80, 0x0e, 0x82, 0x22, 0x22, 0x22, 0x6f, 0x30, 0x00, 0x8d, 0xff, 0x6d, 0xdf, 0x60, 0x00, 0xcc, 0x9c, 0x80, 0x07, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff, 0xd8, 0x8e, 0x63, 0x02, 0x00, 0x02, 0x11, 0x11, 0x11, 0xee, 0xee, 0xee, 0xe6,
--0x6e, 0xe3, 0x33, 0x3e, 0xe0, 0x00, 0x07, 0x03, 0xf6, 0x80, 0x00, 0x8d, 0xff, 0xff, 0xff, 0x87, 0x70, 0x00, 0x00, 0x07, 0x77, 0x77, 0x77, 0xef, 0xff, 0xff, 0xff, 0xd8, 0x00, 0x03, 0xf1, 0x12, 0x22, 0x11, 0x11, 0x1e, 0xee, 0xee, 0xee, 0xe6,
--0x6e, 0xee, 0xee, 0xee, 0xe0, 0x20, 0x20, 0x26, 0xf6, 0xe8, 0x88, 0xe6, 0xff, 0x66, 0x6d, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x70, 0x86, 0x66, 0x6f, 0xff, 0x69, 0xc8, 0x08, 0x66, 0x11, 0x11, 0x11, 0x11, 0x13, 0xee, 0xee, 0xee, 0xe6,
--0xfe, 0xee, 0xeb, 0x44, 0xc0, 0x22, 0x85, 0x4a, 0xf6, 0x3e, 0xee, 0xdf, 0xfd, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x35, 0x4c, 0x22, 0x23, 0x94, 0x44, 0x49, 0xe8, 0x66, 0x20, 0x02, 0x22, 0x22, 0x2e, 0xee, 0xe8, 0x88, 0x86,
--0xf3, 0xee, 0x3b, 0x44, 0x40, 0x22, 0x54, 0x4b, 0xff, 0x6d, 0xa6, 0x6f, 0x62, 0x22, 0x22, 0x22, 0x28, 0xcc, 0x11, 0x11, 0x22, 0x22, 0x19, 0x44, 0x22, 0x28, 0x44, 0x99, 0x56, 0xdd, 0x66, 0x00, 0x0c, 0xc2, 0x20, 0x0e, 0xee, 0xe8, 0x00, 0x06,
--0xf3, 0xee, 0x39, 0x44, 0x40, 0x28, 0x44, 0x49, 0xff, 0xff, 0x66, 0xff, 0xd2, 0x12, 0x22, 0x22, 0x29, 0x44, 0x11, 0x11, 0x02, 0x22, 0x1a, 0x44, 0x02, 0x2c, 0x44, 0x6f, 0xff, 0xff, 0xf3, 0x00, 0x94, 0x42, 0x22, 0x0e, 0xee, 0xee, 0xe8, 0xef,
--0xfd, 0xee, 0xe9, 0x44, 0x4c, 0x1c, 0x44, 0x49, 0xff, 0xb9, 0x45, 0xb3, 0x18, 0xc8, 0x84, 0x48, 0x15, 0x44, 0xc0, 0x8c, 0x4c, 0xcc, 0xcd, 0x94, 0xc2, 0x24, 0x49, 0x69, 0x96, 0xfb, 0x54, 0xc8, 0x54, 0x4c, 0x00, 0x44, 0xc9, 0xc9, 0xee, 0x3f,
--0xf6, 0xee, 0x35, 0x45, 0x44, 0x85, 0x45, 0x44, 0x19, 0x44, 0x44, 0x44, 0x39, 0x44, 0x44, 0x44, 0xb4, 0x44, 0x4c, 0x44, 0x44, 0x44, 0x4d, 0xa4, 0x41, 0xb4, 0x42, 0x34, 0x4a, 0xb4, 0x49, 0x58, 0x44, 0x44, 0xc4, 0x44, 0x44, 0x44, 0xee, 0xdf,
--0xf6, 0xee, 0xe5, 0x4b, 0x94, 0x54, 0x5b, 0x45, 0x84, 0x49, 0x3b, 0x44, 0xc9, 0x45, 0x3a, 0x54, 0xbb, 0x45, 0xa5, 0x45, 0xea, 0x94, 0x4d, 0x65, 0x49, 0xc4, 0xc1, 0x34, 0x48, 0x94, 0x5a, 0x1d, 0x94, 0x5b, 0x54, 0x5b, 0xa5, 0x44, 0xee, 0x6f,
--0xff, 0x3e, 0xb4, 0x4b, 0xb4, 0x44, 0x8e, 0x45, 0x94, 0x42, 0x1d, 0x94, 0x99, 0x49, 0x1d, 0x54, 0x3b, 0x44, 0xd5, 0x48, 0x11, 0xb4, 0x4d, 0xdb, 0x44, 0x44, 0xe1, 0x34, 0x40, 0xa4, 0x44, 0x4e, 0xb4, 0xc3, 0x54, 0x93, 0xdb, 0x44, 0xee, 0x6f,
--0xff, 0xde, 0xb4, 0x4e, 0xa5, 0x44, 0x23, 0x55, 0x94, 0x40, 0x11, 0x54, 0x59, 0x4c, 0x11, 0x94, 0x8b, 0x44, 0xd5, 0x4c, 0x11, 0x84, 0x41, 0x1a, 0x44, 0x45, 0x11, 0x34, 0x47, 0xda, 0xb5, 0x4c, 0xb4, 0x43, 0x54, 0xce, 0xe9, 0x44, 0xe3, 0xff,
--0xff, 0x6e, 0x94, 0x4e, 0xd9, 0x4c, 0x11, 0x54, 0xb5, 0x44, 0xc5, 0x44, 0xc9, 0x44, 0x08, 0x54, 0x09, 0x44, 0x09, 0x44, 0xcc, 0x44, 0x41, 0x23, 0x54, 0x4c, 0x00, 0x85, 0x47, 0xcc, 0xc5, 0x4c, 0x94, 0x48, 0x94, 0x45, 0x54, 0x44, 0xed, 0xff,
--0xff, 0xf3, 0x94, 0x5e, 0xea, 0x48, 0x11, 0x54, 0xba, 0x54, 0x44, 0x5b, 0x19, 0x4c, 0x11, 0x94, 0xee, 0x45, 0x2d, 0x94, 0x44, 0x54, 0x52, 0x21, 0xb4, 0x42, 0x21, 0xe4, 0x4b, 0x54, 0x44, 0x5e, 0xb4, 0x52, 0xd9, 0x44, 0x45, 0x45, 0xe6, 0xff,
--0xff, 0xf6, 0xaa, 0xee, 0xea, 0xae, 0x21, 0xde, 0x31, 0xda, 0xba, 0x82, 0x1d, 0xa8, 0x11, 0xbb, 0x1d, 0xa3, 0x12, 0xda, 0xb3, 0x33, 0xe1, 0x22, 0xda, 0x31, 0x11, 0xda, 0x31, 0xda, 0xba, 0x11, 0xd3, 0x31, 0x3a, 0xab, 0xaa, 0xab, 0x3f, 0xff,
--0xff, 0xf6, 0xee, 0xee, 0xee, 0xee, 0x31, 0x12, 0x11, 0x11, 0x11, 0x20, 0x88, 0x11, 0x18, 0x5c, 0x11, 0x11, 0x12, 0x11, 0x11, 0x02, 0x11, 0x22, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0xee, 0x33, 0xee, 0xee, 0x6f, 0xff,
--0xff, 0xff, 0x3e, 0xee, 0xee, 0xee, 0xe2, 0x10, 0x21, 0x12, 0x22, 0x05, 0x45, 0x11, 0x1b, 0x44, 0x11, 0x11, 0x12, 0x11, 0x11, 0x02, 0x22, 0x22, 0x12, 0x12, 0x11, 0x12, 0x11, 0x12, 0x21, 0x11, 0x12, 0x1e, 0xee, 0xee, 0xee, 0xee, 0xff, 0xff,
--0xff, 0xff, 0x6e, 0xee, 0xee, 0xee, 0xee, 0x10, 0x01, 0x12, 0x10, 0x09, 0x44, 0xd1, 0x1d, 0xae, 0x11, 0x11, 0x11, 0x11, 0x11, 0x21, 0x11, 0x21, 0x11, 0x11, 0x11, 0x11, 0x11, 0x20, 0x02, 0x11, 0x11, 0xee, 0xee, 0xee, 0xee, 0xed, 0xff, 0xff,
--0xff, 0xff, 0xf3, 0xee, 0xee, 0xee, 0xee, 0x20, 0x11, 0x12, 0x11, 0x29, 0x45, 0x11, 0x11, 0x33, 0x13, 0x33, 0x38, 0x81, 0x12, 0x02, 0x11, 0x22, 0x22, 0x22, 0x11, 0x1e, 0xe3, 0x20, 0x02, 0xd1, 0x11, 0xee, 0xee, 0xee, 0xee, 0xef, 0xff, 0xff,
--0xff, 0xff, 0xf6, 0xee, 0xee, 0xee, 0xee, 0xe8, 0x11, 0xd1, 0x11, 0x89, 0x44, 0x11, 0x1e, 0x4c, 0xd9, 0x4c, 0x44, 0x45, 0x19, 0x44, 0x1d, 0x94, 0x8a, 0x54, 0xce, 0x54, 0x53, 0x18, 0x23, 0xd1, 0x1e, 0xee, 0xee, 0xee, 0xee, 0x6f, 0xff, 0xff,
--0xff, 0xff, 0xff, 0x6e, 0xee, 0xee, 0xee, 0xee, 0x11, 0x11, 0x11, 0x25, 0x45, 0x20, 0x1a, 0x45, 0x19, 0x44, 0xbb, 0x44, 0xbb, 0x45, 0x11, 0x94, 0x81, 0xa5, 0x44, 0x45, 0xdd, 0xd1, 0xd1, 0x1d, 0xee, 0xee, 0xee, 0xee, 0xe3, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xf3, 0xee, 0xee, 0xee, 0xee, 0xe1, 0x12, 0x11, 0x09, 0x44, 0x70, 0x1e, 0x4c, 0xd9, 0x4c, 0x1d, 0x54, 0x8b, 0x45, 0x11, 0xb4, 0x81, 0x1b, 0x44, 0x4e, 0x11, 0x11, 0x11, 0xd3, 0xee, 0xee, 0xee, 0xee, 0xe6, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xf6, 0xee, 0xee, 0xee, 0xee, 0xee, 0x12, 0x21, 0x09, 0x44, 0x21, 0x1e, 0x45, 0x19, 0x4c, 0x11, 0x44, 0x8b, 0x44, 0x11, 0x94, 0x81, 0x1c, 0x44, 0x4c, 0x11, 0x12, 0x21, 0x3e, 0xee, 0xee, 0xee, 0xee, 0x6f, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0x6e, 0xee, 0xee, 0xee, 0xee, 0xe0, 0x21, 0x09, 0x44, 0xcc, 0xcb, 0x44, 0x29, 0x4c, 0x2e, 0x54, 0xbb, 0x44, 0x88, 0x54, 0x81, 0xc4, 0x59, 0x44, 0xc1, 0x12, 0x28, 0xee, 0xee, 0xee, 0xee, 0xe3, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xf3, 0xee, 0xee, 0xee, 0xee, 0xee, 0x21, 0x05, 0x44, 0x44, 0x49, 0x44, 0x25, 0x4c, 0x2e, 0x44, 0x8d, 0x54, 0x44, 0x44, 0x0c, 0x44, 0xc3, 0x94, 0x4c, 0x12, 0xee, 0xee, 0xee, 0xee, 0xee, 0x3f, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xee, 0xee, 0xee, 0xee, 0xe1, 0x0a, 0xbb, 0xbb, 0xb3, 0xbe, 0x1a, 0xbe, 0x11, 0xbb, 0xe1, 0xdb, 0x99, 0xbe, 0xeb, 0xbb, 0x22, 0xda, 0xbb, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x6f, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0x63, 0xee, 0xee, 0xee, 0xee, 0xee, 0x81, 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x21, 0x1d, 0x11, 0x11, 0xd1, 0x11, 0x11, 0x11, 0x11, 0x11, 0x13, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x21, 0x11, 0x11, 0x11, 0x12, 0x01, 0x11, 0x1d, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x12, 0x11, 0x11, 0x21, 0x01, 0x11, 0x1d, 0x11, 0x11, 0x1d, 0x11, 0x11, 0x11, 0x11, 0x3e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x11, 0x11, 0x12, 0x01, 0x21, 0x1d, 0x11, 0xd1, 0xd1, 0x11, 0x11, 0x13, 0x3e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe1, 0x12, 0x01, 0x11, 0x1d, 0xdd, 0x1d, 0x1d, 0x11, 0x1e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x36, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe3, 0x3d, 0xdd, 0xdd, 0xdd, 0xd3, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x63, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x36, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x63, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xed, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x63, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6d, 0x3e, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xd6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0x63, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x3d, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf6, 0x66, 0xdd, 0xad, 0xad, 0xdd, 0x66, 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
--};
--
--#endif
--
--#ifndef __HAVE_ARCH_LINUX_LOGOBW
--
--unsigned char linux_logo_bw[] __initdata = {
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xbf, 0xf0, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xfc, 0x7f, 0xfc, 0x1f, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xe0, 0xff, 0xfe, 0x1f, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0x81, 0xff, 0xff, 0x19, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0x88, 0x7f, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xc8, 0xbf, 0xff, 0xff,
--0xff, 0xff, 0xf8, 0x47, 0xff, 0xff, 0xa9, 0x1f, 0xff, 0xff,
--0xff, 0xff, 0xf0, 0x07, 0xff, 0xff, 0xba, 0xcf, 0xff, 0xff,
--0xff, 0xff, 0xd1, 0x8f, 0xff, 0xff, 0xce, 0x3f, 0xff, 0xff,
--0xff, 0xff, 0x98, 0x8f, 0xff, 0xff, 0xff, 0xe7, 0xff, 0xff,
--0xff, 0xff, 0x99, 0x5f, 0xff, 0xff, 0xc0, 0x60, 0xff, 0xff,
--0xff, 0xff, 0x13, 0xff, 0xff, 0xff, 0xc0, 0x30, 0x7f, 0xff,
--0xff, 0xff, 0x11, 0x8f, 0xff, 0xff, 0xe4, 0x32, 0x7f, 0xff,
--0xff, 0xfd, 0x13, 0x9f, 0xff, 0xff, 0xe6, 0x66, 0xff, 0xff,
--0xff, 0xfd, 0x13, 0xff, 0xff, 0xff, 0x97, 0x4b, 0x5f, 0xff,
--0xff, 0xf9, 0x11, 0x97, 0xff, 0xff, 0x8e, 0x73, 0x5f, 0xff,
--0xff, 0xf7, 0x1d, 0xbf, 0xff, 0xff, 0xd7, 0xff, 0xff, 0xff,
--0xff, 0xf5, 0x1d, 0x97, 0xff, 0xff, 0xc7, 0xfb, 0xff, 0xff,
--0xff, 0xe1, 0x99, 0x87, 0xff, 0xff, 0xc0, 0x71, 0xc7, 0xff,
--0xff, 0xe3, 0x94, 0x07, 0xff, 0xff, 0xc0, 0x7b, 0xff, 0xff,
--0xff, 0xe9, 0x93, 0x27, 0xff, 0xff, 0xc0, 0x71, 0xe3, 0xff,
--0xff, 0xc1, 0x59, 0xf7, 0xff, 0xff, 0xf3, 0xff, 0xf3, 0xff,
--0xff, 0xc3, 0x51, 0x17, 0xff, 0xff, 0xf3, 0xff, 0xfb, 0xff,
--0xff, 0xd1, 0x10, 0x07, 0xff, 0xff, 0xc0, 0x46, 0x61, 0xff,
--0xff, 0x81, 0x99, 0xf7, 0xff, 0xff, 0xc0, 0x04, 0x41, 0xff,
--0xff, 0xa1, 0x11, 0x57, 0xff, 0xff, 0xc0, 0x00, 0x41, 0xff,
--0xff, 0x81, 0x90, 0x07, 0xff, 0xff, 0xe0, 0x09, 0xd1, 0xff,
--0xff, 0x91, 0x10, 0x07, 0xff, 0xff, 0xd2, 0x47, 0x7f, 0xff,
--0xff, 0xa3, 0x11, 0x07, 0xff, 0xff, 0xeb, 0xc3, 0x79, 0xff,
--0xff, 0x93, 0x1f, 0x9f, 0xff, 0xff, 0xfb, 0xe9, 0xc1, 0xff,
--0xff, 0x81, 0x01, 0x07, 0xff, 0xff, 0xf1, 0xe1, 0xc1, 0xff,
--0xff, 0xc1, 0x7f, 0xc7, 0xff, 0xff, 0xff, 0xdb, 0xc1, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xc1, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x01, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xf0, 0xf7, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xdf, 0xf0, 0xf7, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xdf, 0xff, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xfd, 0xff, 0xff,
--0xff, 0xff, 0xf7, 0xf7, 0xff, 0x3f, 0xfb, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xf3, 0xf3, 0xff, 0x39, 0xf3, 0xff, 0xff, 0xff,
--0xff, 0xf3, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xf3, 0xff, 0x73, 0xff, 0xfe, 0xfb, 0xff, 0xff, 0xff,
--0xff, 0xfb, 0xbf, 0x73, 0x77, 0xfb, 0xe3, 0xbc, 0xef, 0xff,
--0xff, 0xf9, 0x03, 0xc7, 0x04, 0x33, 0x00, 0x00, 0x0f, 0xff,
--0xff, 0xfd, 0x9f, 0xc7, 0x04, 0x3f, 0x51, 0x18, 0x5f, 0xff,
--0xff, 0xfd, 0x97, 0xe7, 0x00, 0x22, 0x00, 0x3c, 0x3f, 0xff,
--0xff, 0xff, 0x13, 0xc3, 0x7e, 0x73, 0xf1, 0xfe, 0x3f, 0xff,
--0xff, 0xff, 0x23, 0xc7, 0xff, 0x77, 0xff, 0xde, 0x7f, 0xff,
--0xff, 0xff, 0x03, 0xf7, 0x7f, 0xf3, 0xbf, 0xe9, 0xff, 0xff,
--0xff, 0xff, 0x93, 0xf7, 0xf7, 0xf3, 0x9f, 0x03, 0xff, 0xff,
--0xff, 0xff, 0xdb, 0xe7, 0x73, 0xf3, 0x9f, 0x1b, 0xff, 0xff,
--0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xbf, 0x9f, 0xff, 0xff,
--0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff,
--0xff, 0xff, 0xfb, 0xff, 0x73, 0xbf, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xfe, 0x00, 0x29, 0x08, 0x00, 0x7f, 0xff, 0xff,
--0xff, 0xff, 0xff, 0x80, 0x61, 0x00, 0x00, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xd0, 0xa1, 0x04, 0x03, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xf0, 0x69, 0x28, 0x1f, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xfe, 0x61, 0xd4, 0x7f, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
--0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x88, 0x88, 0x88, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x88, 0x80, 0x00, 0x00, 0x08, 0x88, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x00,
-+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80,
-+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-+ 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-+ 0x08, 0x70, 0x00, 0x00, 0x00, 0x77, 0x70, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-+ 0x87, 0x77, 0x00, 0x00, 0x07, 0xff, 0xf7, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
-+ 0x77, 0xff, 0x00, 0x00, 0x7f, 0x77, 0xf7, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
-+ 0x70, 0x0f, 0x80, 0x00, 0xf7, 0x08, 0x7f, 0x70,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
-+ 0x80, 0x07, 0x80, 0x00, 0xf8, 0x00, 0x8f, 0x70,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08,
-+ 0x70, 0x07, 0x88, 0x88, 0xf8, 0x00, 0x8f, 0x70,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-+ 0xf0, 0x06, 0xe6, 0xe6, 0xe6, 0x00, 0x8f, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-+ 0x77, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x77, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-+ 0x06, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-+ 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60,
-+ 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
-+ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x60,
-+ 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
-+ 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66, 0x66, 0x80,
-+ 0x08, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
-+ 0x86, 0xe6, 0xe6, 0xe6, 0x66, 0x66, 0x66, 0x80,
-+ 0x08, 0x78, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80,
-+ 0x86, 0x66, 0x66, 0x66, 0x66, 0x66, 0x77, 0x70,
-+ 0x00, 0x77, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-+ 0x87, 0x66, 0x66, 0x66, 0x66, 0x77, 0x77, 0x78,
-+ 0x00, 0x88, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-+ 0x87, 0x76, 0x66, 0x66, 0x77, 0x77, 0xff, 0xf7,
-+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08,
-+ 0xff, 0x77, 0x77, 0x77, 0x77, 0xff, 0xff, 0xff,
-+ 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07,
-+ 0xff, 0x77, 0x77, 0x77, 0x7f, 0xff, 0xff, 0xff,
-+ 0x70, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x8f,
-+ 0xff, 0xf7, 0x77, 0x77, 0xff, 0xff, 0xff, 0xff,
-+ 0xf0, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x7f,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xf8, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xf7, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x08, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x87, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x77,
-+ 0xff, 0xf7, 0x77, 0xff, 0xff, 0xff, 0x77, 0x77,
-+ 0x77, 0x78, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x7f,
-+ 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0x77,
-+ 0x77, 0x78, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x7f, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xf7, 0x77, 0x00, 0x08, 0x80, 0x00, 0x00, 0x80,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x80, 0x08, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0x77, 0x80, 0x00, 0x08, 0x00, 0x00, 0x08,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x08, 0x00, 0x80, 0x07, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0x78, 0x00, 0x08, 0x80, 0x00, 0x08,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x08, 0x08, 0x00, 0x8f, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xf7, 0x08, 0x80, 0x80, 0x00, 0x08,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x08, 0x08, 0x08, 0x7f, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xf7, 0x08, 0x80, 0x80, 0x00, 0x00,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x08, 0x07, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0x80, 0x00, 0x08, 0x00, 0x00,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x80, 0x0f, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x00, 0x80, 0x8f, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x08, 0x00, 0x7f, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0x70, 0x00, 0x08, 0x00, 0x00,
-+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
-+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x00, 0x08, 0x00, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
-+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x00, 0x08, 0x08, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
-+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x00, 0x08, 0x08, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
-+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x00, 0x00, 0x88, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xf0, 0x00, 0x08, 0x00, 0x00,
-+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x00, 0x00, 0x08, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xf0, 0x88, 0x88, 0x80, 0x00,
-+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x06, 0xe6, 0x00, 0x8f, 0xff, 0xff, 0xff,
-+ 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x08, 0x80,
-+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x6e, 0x6e, 0x60, 0x08, 0xff, 0xff, 0xff,
-+ 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x88,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x06, 0xe6, 0xe6, 0xe6, 0x00, 0x8f, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xfe, 0x6e, 0x60, 0x00, 0x00, 0x00, 0x00,
-+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x08, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xf6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x06,
-+ 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xe6, 0xe6,
-+ 0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x8f, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xfe, 0x6e, 0x60, 0x00, 0x00, 0x00, 0x0e,
-+ 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
-+ 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x00, 0x08, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0x76, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0xe6,
-+ 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-+ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x8f,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xf7, 0x7e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-+ 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
-+ 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x00, 0x08,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xf7, 0x76, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-+ 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-+ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00,
-+ 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xf7, 0x7e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-+ 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
-+ 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x60, 0x00,
-+ 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xf7, 0x76, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-+ 0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-+ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe0, 0x00,
-+ 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xf7, 0x8e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-+ 0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
-+ 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x88,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0x78, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-+ 0xe6, 0xe6, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-+ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xef,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7,
-+ 0x80, 0x06, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-+ 0x6e, 0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x6e, 0x6e,
-+ 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78,
-+ 0x00, 0x06, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-+ 0xe6, 0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-+ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-+ 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x80,
-+ 0x00, 0x06, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-+ 0x6e, 0x6e, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x6e, 0x6e, 0x6e,
-+ 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
-+ 0x67, 0xff, 0xff, 0xff, 0xff, 0x78, 0x80, 0x00,
-+ 0x00, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-+ 0xe6, 0xe6, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x06, 0xe6, 0xe6, 0xe6,
-+ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x86, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
-+ 0x66, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x0e, 0x6e, 0x6e, 0x6e,
-+ 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
-+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x86, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xe6, 0xe6,
-+ 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
-+ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x86, 0x6e, 0x6e, 0x6e, 0x6e, 0x66, 0x66,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66,
-+ 0x66, 0x66, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e, 0x66,
-+ 0x60, 0x00, 0x88, 0x88, 0x88, 0x88, 0x88, 0x80,
-+ 0x00, 0x06, 0x66, 0xe6, 0xe6, 0xe6, 0x66, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x66, 0x66, 0x66, 0x66, 0xe6, 0xe6, 0x66,
-+ 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
-+ 0x88, 0x86, 0x66, 0x6e, 0x6e, 0x66, 0x60, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x06, 0x66, 0x66, 0x66, 0x66,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x06, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x66, 0x66, 0x60,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x66, 0x66, 0x66, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- };
-
--#endif
-+#endif /* !__HAVE_ARCH_LINUX_LOGO16 */
-
- #else /* !INCLUDE_LINUX_LOGO_DATA */
-
-@@ -679,4 +10228,3 @@
- extern unsigned char linux_logo16[];
-
- #endif /* !INCLUDE_LINUX_LOGO_DATA */
--
---- linux-2.4.17_mvl21/drivers/video/fbcon.c~opie-logo.patch
-+++ linux-2.4.17_mvl21/drivers/video/fbcon.c
-@@ -97,10 +97,8 @@
- #include <asm/io.h>
- #endif
-
--#ifndef CONFIG_SA1100_BEAGLE
- #define INCLUDE_LINUX_LOGO_DATA
- #include <asm/linux_logo.h>
--#endif
-
- #include <video/fbcon.h>
- #include <video/fbcon-mac.h> /* for 6x11 font on mac */
-@@ -112,13 +110,8 @@
- # define DPRINTK(fmt, args...)
- #endif
-
--#if defined( CONFIG_SA1100_BEAGLE )
--#define LOGO_H 320
--#define LOGO_W 240
--#else
--#define LOGO_H 80
--#define LOGO_W 80
--#endif
-+#define LOGO_W (240)
-+#define LOGO_H (320)
- #define LOGO_LINE (LOGO_W/8)
-
- struct display fb_display[MAX_NR_CONSOLES];
-@@ -2139,27 +2132,6 @@
- }
-
-
--#ifdef CONFIG_SA1100_BEAGLE
--static int __init fbcon_show_logo( void )
--{
-- struct display *p = &fb_display[fg_console]; /* draw to vt in foreground */
-- unsigned char *fb = p->screen_base;
-- int logo_size = LOGO_W * LOGO_H * 2;
--
--#ifdef CONFIG_BLK_DEV_MSYS_DOC
-- static void *vaddr_logo = NULL;
-- vaddr_logo = (void *)ioremap( 0xC1A00000, logo_size );
-- memcpy( fb, vaddr_logo, logo_size );
-- iounmap( vaddr_logo );
--#else
-- memcpy( fb, (char*)0xe8040000, logo_size );
--#endif
--
-- printk( "show big logo %dx%d!\n", LOGO_W, LOGO_H);
--
-- return (LOGO_H + fontheight(p) - 1) / fontheight(p);
--}
--#else
- static int __init fbcon_show_logo( void )
- {
- struct display *p = &fb_display[fg_console]; /* draw to vt in foreground */
-@@ -2488,7 +2460,7 @@
-
- return done ? (LOGO_H + fontheight(p) - 1) / fontheight(p) : 0 ;
- }
--#endif
-+
-
- /*
- * The console `switch' structure for the frame buffer based console
diff --git a/linux/montavista-sa-2.4.17-mvl21/pcmcia_preempt.patch b/linux/montavista-sa-2.4.17-mvl21/pcmcia_preempt.patch
deleted file mode 100644
index 5d4a2d28de..0000000000
--- a/linux/montavista-sa-2.4.17-mvl21/pcmcia_preempt.patch
+++ /dev/null
@@ -1,180 +0,0 @@
-
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- linux-2.4.17_mvl21/drivers/pcmcia/sa1100_generic.c~pcmcia_preempt.patch
-+++ linux-2.4.17_mvl21/drivers/pcmcia/sa1100_generic.c
-@@ -172,7 +172,7 @@
- struct pcmcia_state state[SA1100_PCMCIA_MAX_SOCK];
- struct pcmcia_state_array state_array;
- unsigned int i, clock;
-- unsigned long mecr;
-+ unsigned long mecr, irq_flags;
-
- printk(KERN_INFO "SA-1100 PCMCIA (CS release %s)\n", CS_RELEASE);
-
-@@ -278,10 +278,12 @@
- return -EIO;
- }
-
-+ preempt_disable();
-+
- /* We initialize the MECR to default values here, because we are
- * not guaranteed to see a SetIOMap operation at runtime.
- */
-- mecr=0;
-+ mecr=MECR;
-
- clock = cpufreq_get(0);
-
-@@ -311,11 +313,14 @@
- sa1100_pcmcia_socket[i].speed_mem=SA1100_PCMCIA_5V_MEM_ACCESS;
- }
-
-+ local_irq_save(irq_flags);
- MECR=mecr;
-+ local_irq_restore(irq_flags);
-
- #ifdef CONFIG_CPU_FREQ
- if(cpufreq_register_notifier(&sa1100_pcmcia_notifier_block) < 0){
- printk(KERN_ERR "Unable to register CPU frequency change notifier\n");
-+ preempt_enable();
- return -ENXIO;
- }
- #endif
-@@ -324,12 +329,14 @@
- if(register_ss_entry(sa1100_pcmcia_socket_count,
- &sa1100_pcmcia_operations)<0){
- printk(KERN_ERR "Unable to register socket service routine\n");
-+ preempt_enable();
- return -ENXIO;
- }
-
- /* Start the event poll timer. It will reschedule by itself afterwards. */
- sa1100_pcmcia_poll_event(0);
-
-+ preempt_enable();
- DEBUG(1, "sa1100: initialization complete\n");
-
- return 0;
-@@ -813,7 +820,7 @@
- static int sa1100_pcmcia_set_io_map(unsigned int sock,
- struct pccard_io_map *map){
- unsigned int clock, speed;
-- unsigned long mecr, start;
-+ unsigned long mecr, start, irq_flags;
-
- DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
-
-@@ -836,7 +843,8 @@
- }
-
- if(map->flags&MAP_ACTIVE){
--
-+ preempt_disable();
-+
- speed=(map->speed>0)?map->speed:SA1100_PCMCIA_IO_ACCESS;
-
- clock = cpufreq_get(0);
-@@ -852,8 +860,10 @@
- MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock),
- sock, MECR_BSIO_GET(mecr, sock));
-
-+ local_irq_save(irq_flags);
- MECR=mecr;
--
-+ local_irq_restore(irq_flags);
-+ preempt_enable();
- }
-
- start=map->start;
-@@ -909,8 +919,10 @@
- static int sa1100_pcmcia_set_mem_map(unsigned int sock,
- struct pccard_mem_map *map){
- unsigned int clock, speed;
-- unsigned long mecr, start;
--
-+ unsigned long mecr, start, irq_flags;
-+
-+ preempt_disable();
-+
- DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
-
- DEBUG(4, "\tmap %u speed %u\n\tsys_start %#lx\n"
-@@ -929,6 +941,7 @@
- if(map->map>=MAX_WIN){
- printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
- map->map);
-+ preempt_enable();
- return -1;
- }
-
-@@ -968,9 +981,10 @@
- __FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock,
- MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock),
- sock, MECR_BSIO_GET(mecr, sock));
--
-- MECR=mecr;
-
-+ local_irq_save(irq_flags);
-+ MECR=mecr;
-+ local_irq_restore(irq_flags);
- }
-
- start=map->sys_start;
-@@ -986,6 +1000,8 @@
-
- sa1100_pcmcia_socket[sock].mem_map[map->map]=*map;
-
-+ preempt_enable();
-+
- return 0;
-
- } /* sa1100_pcmcia_set_mem_map() */
-@@ -1026,8 +1042,13 @@
- int count, int *eof, void *data){
- char *p=buf;
- unsigned int sock=(unsigned int)data;
-- unsigned int clock = cpufreq_get(0);
-- unsigned long mecr = MECR;
-+ unsigned int clock;
-+ unsigned long mecr;
-+
-+ preempt_disable();
-+ clock = cpufreq_get(0);
-+ mecr = MECR;
-+ preempt_enable();
-
- p+=sprintf(p, "k_flags : %s%s%s%s%s%s%s\n",
- sa1100_pcmcia_socket[sock].k_state.detect?"detect ":"",
-@@ -1101,8 +1122,13 @@
- void sa1100_pcmcia_update_mecr( void )
- {
- unsigned int sock;
-- unsigned long mecr = MECR;
-- unsigned int clock = cpufreq_get(0);
-+ unsigned long mecr;
-+ unsigned int clock;
-+ unsigned long irq_flags;
-+
-+ preempt_disable();
-+ mecr = MECR;
-+ clock = cpufreq_get(0);
-
- if ( clock <= 148000 )
- clock = 59000;
-@@ -1122,10 +1148,11 @@
- clock));
- }
-
-- cli();
-+ local_irq_save(irq_flags);
- MECR = mecr;
-- sti();
-+ local_irq_restore(irq_flags);
-
-+ preempt_enable();
- }
- #endif
-
diff --git a/linux/montavista-sa-2.4.17-mvl21/remove-montavista-init-stupidity.patch b/linux/montavista-sa-2.4.17-mvl21/remove-montavista-init-stupidity.patch
deleted file mode 100644
index 0fd0a96659..0000000000
--- a/linux/montavista-sa-2.4.17-mvl21/remove-montavista-init-stupidity.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- linux-2.4.17_mvl21/init/main.c~remove-montavista-init-stupidity
-+++ linux-2.4.17_mvl21/init/main.c
-@@ -852,15 +852,11 @@
- * trying to recover a really broken machine.
- */
-
--#ifndef CONFIG_SA1100_BEAGLE
- if (execute_command)
- execve(execute_command,argv_init,envp_init);
- execve("/sbin/init",argv_init,envp_init);
- execve("/etc/init",argv_init,envp_init);
- execve("/bin/init",argv_init,envp_init);
--#else
-- strcpy( argv_init[0], "--login" );
--#endif
- execve("/bin/sh",argv_init,envp_init);
- panic("No init found. Try passing init= option to kernel.");
- }
diff --git a/linux/montavista-sa-2.4.17-mvl21/ucb1x_kill-zombie.patch b/linux/montavista-sa-2.4.17-mvl21/ucb1x_kill-zombie.patch
deleted file mode 100644
index 77fdfa6846..0000000000
--- a/linux/montavista-sa-2.4.17-mvl21/ucb1x_kill-zombie.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- linux-2.4.17_mvl21/drivers/misc/beagle-ts.c~ucb1x_kill_daemon
-+++ linux-2.4.17_mvl21/drivers/misc/beagle-ts.c
-@@ -372,6 +372,7 @@
- ts->rtask = tsk;
-
- daemonize();
-+ reparent_to_init();
- tsk->tty = NULL;
- //tsk->policy = SCHED_FIFO;
- //tsk->rt_priority = 1;
diff --git a/linux/montavista-sa_2.4.17-mvl21.bb b/linux/montavista-sa_2.4.17-mvl21.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/montavista-sa_2.4.17-mvl21.bb
+++ /dev/null
diff --git a/linux/nslu2-linksys-kernel-2.4.22/config-fixes.patch b/linux/nslu2-linksys-kernel-2.4.22/config-fixes.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/nslu2-linksys-kernel-2.4.22/config-fixes.patch
+++ /dev/null
diff --git a/linux/nslu2-linksys-kernel-2.4.22/gcc-registerparanoia.patch b/linux/nslu2-linksys-kernel-2.4.22/gcc-registerparanoia.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/nslu2-linksys-kernel-2.4.22/gcc-registerparanoia.patch
+++ /dev/null
diff --git a/linux/nslu2-linksys-kernel-2.4.22/gcc3-userfuncs.patch b/linux/nslu2-linksys-kernel-2.4.22/gcc3-userfuncs.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/nslu2-linksys-kernel-2.4.22/gcc3-userfuncs.patch
+++ /dev/null
diff --git a/linux/nslu2-linksys-kernel-2.4.22/linux-2.4.24-attribute-used.patch b/linux/nslu2-linksys-kernel-2.4.22/linux-2.4.24-attribute-used.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/nslu2-linksys-kernel-2.4.22/linux-2.4.24-attribute-used.patch
+++ /dev/null
diff --git a/linux/nslu2-linksys-kernel-2.4.22/nofpu.patch b/linux/nslu2-linksys-kernel-2.4.22/nofpu.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/nslu2-linksys-kernel-2.4.22/nofpu.patch
+++ /dev/null
diff --git a/linux/nslu2-linksys-kernel-2.4.22/nslu2/defconfig b/linux/nslu2-linksys-kernel-2.4.22/nslu2/defconfig
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/nslu2-linksys-kernel-2.4.22/nslu2/defconfig
+++ /dev/null
diff --git a/linux/nslu2-linksys-kernel-2.4.22/short_loadbytes.patch b/linux/nslu2-linksys-kernel-2.4.22/short_loadbytes.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/nslu2-linksys-kernel-2.4.22/short_loadbytes.patch
+++ /dev/null
diff --git a/linux/nslu2-linksys-kernel_2.4.22.bb b/linux/nslu2-linksys-kernel_2.4.22.bb
deleted file mode 100644
index 0421d69c6e..0000000000
--- a/linux/nslu2-linksys-kernel_2.4.22.bb
+++ /dev/null
@@ -1,50 +0,0 @@
-SECTION = "kernel"
-DESCRIPTION = "Linux kernel for the Linksys NSLU2 device"
-LICENSE = "GPL"
-MAINTAINER = "Chris Larson <kergoth@handhelds.org>"
-PR = "r2"
-
-SRC_URI = "ftp://ftp.kernel.org/pub/linux/kernel/v2.4/linux-2.4.22.tar.bz2 \
- ftp://oss.sgi.com/projects/xfs/patches/2.4.22/xfs-2.4.22-all-i386.bz2;patch=1 \
- http://openembedded.org/dl/2.4.22-xfs-nslu2.patch.bz2;patch=1 \
- file://config-fixes.patch;patch=1 \
- file://nofpu.patch;patch=1 \
- file://short_loadbytes.patch;patch=1 \
- file://gcc3-userfuncs.patch;patch=1 \
- file://gcc-registerparanoia.patch;patch=1 \
- file://linux-2.4.24-attribute-used.patch;patch=1 \
- file://defconfig"
-S = "${WORKDIR}/linux-2.4.22"
-
-python () {
- # Don't build unless we're targeting an nslu2
- if bb.data.getVar("MACHINE", d, 1) != "nslu2":
- raise bb.parse.SkipPackage("NSLU2 kernel only builds for the Linksys NSLU2")
-}
-
-COMPATIBLE_HOST = 'arm.*-linux'
-
-inherit kernel
-
-ARCH = "arm"
-KERNEL_IMAGETYPE = "zImage"
-KERNEL_SUFFIX ?= "nslu2-linksys"
-CMDLINE_CONSOLE ?= "ttyS0,115200"
-CMDLINE_ROOT = "root=/dev/ram0 initrd=0x01000000,10M mem=32M@0x00000000"
-CMDLINE = "${CMDLINE_CONSOLE} ${CMDLINE_ROOT}"
-
-do_configure_prepend() {
- install -m 0644 ${WORKDIR}/defconfig ${S}/.config
- echo "CONFIG_CMDLINE=\"${CMDLINE}\"" >> ${S}/.config
- rm -rf ${S}/include/asm-arm/arch ${S}/include/asm-arm/proc \
- ${S}/include/asm-arm/.proc ${S}/include/asm-arm/.arch
-}
-
-do_deploy() {
- install -d ${DEPLOY_DIR}/images
- install -m 0644 arch/${ARCH}/boot/${KERNEL_IMAGETYPE} ${DEPLOY_DIR}/images/${KERNEL_IMAGETYPE}-${KERNEL_SUFFIX}
-}
-
-do_deploy[dirs] = "${S}"
-
-addtask deploy before do_build after do_compile
diff --git a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/2.4.25-vrs2-pxa1-jpm1.patch b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/2.4.25-vrs2-pxa1-jpm1.patch
deleted file mode 100644
index 7ae04c21a6..0000000000
--- a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/2.4.25-vrs2-pxa1-jpm1.patch
+++ /dev/null
@@ -1,8760 +0,0 @@
-
-#
-# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux-2.4.25/Makefile~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200
-+++ linux-2.4.25/Makefile 2004-05-02 22:47:57.000000000 +0200
-@@ -1,7 +1,7 @@
- VERSION = 2
- PATCHLEVEL = 4
- SUBLEVEL = 25
--EXTRAVERSION =-vrs2-pxa1
-+EXTRAVERSION =-vrs2-pxa1-jpm1
-
- KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
-
---- linux-2.4.25/arch/arm/mach-sa1100/Makefile~2.4.25-vrs2-pxa1-jpm1.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/Makefile 2004-05-02 22:45:42.000000000 +0200
-@@ -18,7 +18,8 @@
- export-objs := assabet.o consus.o badge4.o dma-sa1100.o dma-sa1111.o \
- flexanet.o freebird.o frodo.o generic.o h3600.o \
- huw_webpanel.o irq.o sa1111.o sa1111-pcibuf.o \
-- system3.o yopy.o usb_ctl.o usb_recv.o usb_send.o simputer.o ssp.o
-+ system3.o yopy.o usb_ctl.o usb_recv.o usb_send.o simputer.o ssp.o \
-+ simpad.o
-
- # These aren't present yet, and prevents a plain -ac kernel building.
- # hwtimer.o
-@@ -30,7 +31,6 @@
- ifeq ($(CONFIG_CPU_FREQ),y)
- obj-$(CONFIG_SA1100_ASSABET) += cpu-sa1110.o
- obj-$(CONFIG_SA1100_CEP) += cpu-sa1110.o
--obj-$(CONFIG_SA1100_CONSUS) += cpu-sa1110.o
- obj-$(CONFIG_SA1100_CERF) += cpu-sa1110.o
- obj-$(CONFIG_SA1100_HACKKIT) += cpu-sa1110.o
- obj-$(CONFIG_SA1100_PT_SYSTEM3) += cpu-sa1110.o
-@@ -52,7 +52,6 @@
- obj-$(CONFIG_SA1100_BRUTUS) += brutus.o
- obj-$(CONFIG_SA1100_CEP) += cep.o
- obj-$(CONFIG_SA1100_CERF) += cerf.o
--obj-$(CONFIG_SA1100_CONSUS) += consus.o
- obj-$(CONFIG_SA1100_EMPEG) += empeg.o
- obj-$(CONFIG_SA1100_FLEXANET) += flexanet.o
- obj-$(CONFIG_SA1100_FREEBIRD) += freebird.o
-@@ -87,7 +86,6 @@
- leds-$(CONFIG_SA1100_ASSABET) += leds-assabet.o
- leds-$(CONFIG_SA1100_BRUTUS) += leds-brutus.o
- leds-$(CONFIG_SA1100_CERF) += leds-cerf.o
--leds-$(CONFIG_SA1100_CONSUS) += leds-consus.o
- leds-$(CONFIG_SA1100_FLEXANET) += leds-flexanet.o
- leds-$(CONFIG_SA1100_FRODO) += leds-frodo.o
- leds-$(CONFIG_SA1100_GRAPHICSCLIENT) += leds-graphicsclient.o
-@@ -108,7 +106,12 @@
-
- # Miscelaneous functions
- obj-$(CONFIG_PM) += pm.o sleep.o
-+obj-$(CONFIG_APM) += apm.o
-
-+# SIMpad specific
-+export-objs += simpad_pm.o
-+obj-$(CONFIG_SIMPAD_PM) += simpad_pm.o
-+
- obj-$(CONFIG_SA1100_SSP) += ssp.o
-
- include $(TOPDIR)/Rules.make
---- linux-2.4.25/drivers/video/fbmem.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200
-+++ linux-2.4.25/drivers/video/fbmem.c 2004-05-02 22:45:42.000000000 +0200
-@@ -109,6 +109,7 @@
- extern int chips_init(void);
- extern int g364fb_init(void);
- extern int sa1100fb_init(void);
-+extern int mq200fb_init(void);
- extern int pxafb_init(void);
- extern int fm2fb_init(void);
- extern int fm2fb_setup(char*);
-@@ -306,6 +307,9 @@
- #ifdef CONFIG_FB_SA1100
- { "sa1100", sa1100fb_init, NULL },
- #endif
-+#ifdef CONFIG_FB_MQ200
-+ { "mq200fb", mq200fb_init, NULL },
-+#endif
- #ifdef CONFIG_FB_PXA
- { "pxa", pxafb_init, NULL },
- #endif
---- linux-2.4.25/arch/arm/config.in~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200
-+++ linux-2.4.25/arch/arm/config.in 2004-05-02 22:45:42.000000000 +0200
-@@ -128,6 +128,9 @@
- dep_bool ' Shannon' CONFIG_SA1100_SHANNON $CONFIG_ARCH_SA1100
- dep_bool ' Sherman' CONFIG_SA1100_SHERMAN $CONFIG_ARCH_SA1100
- dep_bool ' Simpad' CONFIG_SA1100_SIMPAD $CONFIG_ARCH_SA1100
-+if [ "$CONFIG_SA1100_SIMPAD" = "y" ]; then
-+ bool ' T-Sinus PAD' CONFIG_SA1100_SIMPAD_SINUSPAD
-+fi
- dep_bool ' Simputer' CONFIG_SA1100_SIMPUTER $CONFIG_ARCH_SA1100
- dep_bool ' Tulsa' CONFIG_SA1100_PFS168 $CONFIG_ARCH_SA1100
- dep_bool ' Victor' CONFIG_SA1100_VICTOR $CONFIG_ARCH_SA1100
-@@ -587,6 +590,10 @@
- tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
- tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
- dep_bool 'Power Management support (experimental)' CONFIG_PM $CONFIG_EXPERIMENTAL
-+dep_tristate 'Advanced power management emulation support' CONFIG_APM $CONFIG_PM
-+if [ "$CONFIG_APM" != "n" ]; then
-+ bool ' SIMpad power management' CONFIG_SIMPAD_PM
-+fi
- dep_tristate 'RISC OS personality' CONFIG_ARTHUR $CONFIG_CPU_32
- string 'Default kernel command string' CONFIG_CMDLINE ""
-
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/def-configs/simpad 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,967 @@
-+#
-+# Automatically generated by make menuconfig: don't edit
-+#
-+CONFIG_ARM=y
-+# CONFIG_EISA is not set
-+# CONFIG_SBUS is not set
-+# CONFIG_MCA is not set
-+CONFIG_UID16=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-+# CONFIG_GENERIC_BUST_SPINLOCK is not set
-+# CONFIG_GENERIC_ISA_DMA is not set
-+
-+#
-+# Code maturity level options
-+#
-+CONFIG_EXPERIMENTAL=y
-+# CONFIG_OBSOLETE is not set
-+
-+#
-+# Loadable module support
-+#
-+CONFIG_MODULES=y
-+# CONFIG_MODVERSIONS is not set
-+CONFIG_KMOD=y
-+
-+#
-+# System Type
-+#
-+# CONFIG_ARCH_ANAKIN is not set
-+# CONFIG_ARCH_ARCA5K is not set
-+# CONFIG_ARCH_CLPS7500 is not set
-+# CONFIG_ARCH_CLPS711X is not set
-+# CONFIG_ARCH_CO285 is not set
-+# CONFIG_ARCH_EBSA110 is not set
-+# CONFIG_ARCH_CAMELOT is not set
-+# CONFIG_ARCH_FOOTBRIDGE is not set
-+# CONFIG_ARCH_INTEGRATOR is not set
-+# CONFIG_ARCH_OMAHA is not set
-+# CONFIG_ARCH_L7200 is not set
-+# CONFIG_ARCH_MX1ADS is not set
-+# CONFIG_ARCH_RPC is not set
-+# CONFIG_ARCH_RISCSTATION is not set
-+CONFIG_ARCH_SA1100=y
-+# CONFIG_ARCH_SHARK is not set
-+# CONFIG_ARCH_AT91RM9200DK is not set
-+
-+#
-+# Archimedes/A5000 Implementations
-+#
-+# CONFIG_ARCH_ARC is not set
-+# CONFIG_ARCH_A5K is not set
-+
-+#
-+# Footbridge Implementations
-+#
-+# CONFIG_ARCH_CATS is not set
-+# CONFIG_ARCH_PERSONAL_SERVER is not set
-+# CONFIG_ARCH_EBSA285_ADDIN is not set
-+# CONFIG_ARCH_EBSA285_HOST is not set
-+# CONFIG_ARCH_NETWINDER is not set
-+
-+#
-+# SA11x0 Implementations
-+#
-+# CONFIG_SA1100_ACCELENT is not set
-+# CONFIG_SA1100_ASSABET is not set
-+# CONFIG_ASSABET_NEPONSET is not set
-+# CONFIG_SA1100_ADSAGC is not set
-+# CONFIG_SA1100_ADSBITSY is not set
-+# CONFIG_SA1100_ADSBITSYPLUS is not set
-+# CONFIG_SA1100_BRUTUS is not set
-+# CONFIG_SA1100_CEP is not set
-+# CONFIG_SA1100_CERF is not set
-+# CONFIG_SA1100_H3100 is not set
-+# CONFIG_SA1100_H3600 is not set
-+# CONFIG_SA1100_H3800 is not set
-+# CONFIG_SA1100_H3XXX is not set
-+# CONFIG_H3600_SLEEVE is not set
-+# CONFIG_SA1100_EXTENEX1 is not set
-+# CONFIG_SA1100_FLEXANET is not set
-+# CONFIG_SA1100_FREEBIRD is not set
-+# CONFIG_SA1100_FRODO is not set
-+# CONFIG_SA1100_GRAPHICSCLIENT is not set
-+# CONFIG_SA1100_GRAPHICSMASTER is not set
-+# CONFIG_SA1100_HACKKIT is not set
-+# CONFIG_SA1100_BADGE4 is not set
-+# CONFIG_SA1100_JORNADA720 is not set
-+# CONFIG_SA1100_HUW_WEBPANEL is not set
-+# CONFIG_SA1100_ITSY is not set
-+# CONFIG_SA1100_LART is not set
-+# CONFIG_SA1100_NANOENGINE is not set
-+# CONFIG_SA1100_OMNIMETER is not set
-+# CONFIG_SA1100_PANGOLIN is not set
-+# CONFIG_SA1100_PLEB is not set
-+# CONFIG_SA1100_PT_SYSTEM3 is not set
-+# CONFIG_SA1100_SHANNON is not set
-+# CONFIG_SA1100_SHERMAN is not set
-+CONFIG_SA1100_SIMPAD=y
-+# CONFIG_SA1100_SIMPAD_SINUSPAD is not set
-+# CONFIG_SA1100_SIMPUTER is not set
-+# CONFIG_SA1100_PFS168 is not set
-+# CONFIG_SA1100_VICTOR is not set
-+# CONFIG_SA1100_XP860 is not set
-+# CONFIG_SA1100_YOPY is not set
-+CONFIG_SA1100_USB=m
-+CONFIG_SA1100_USB_NETLINK=m
-+CONFIG_SA1100_USB_CHAR=m
-+# CONFIG_SA1100_SSP is not set
-+
-+#
-+# CLPS711X/EP721X Implementations
-+#
-+# CONFIG_ARCH_AUTCPU12 is not set
-+# CONFIG_ARCH_CDB89712 is not set
-+# CONFIG_ARCH_CLEP7312 is not set
-+# CONFIG_ARCH_EDB7211 is not set
-+# CONFIG_ARCH_FORTUNET is not set
-+# CONFIG_ARCH_GUIDEA07 is not set
-+# CONFIG_ARCH_P720T is not set
-+# CONFIG_ARCH_EP7211 is not set
-+# CONFIG_ARCH_EP7212 is not set
-+# CONFIG_ARCH_ACORN is not set
-+# CONFIG_FOOTBRIDGE is not set
-+# CONFIG_FOOTBRIDGE_HOST is not set
-+# CONFIG_FOOTBRIDGE_ADDIN is not set
-+CONFIG_CPU_32=y
-+# CONFIG_CPU_26 is not set
-+# CONFIG_CPU_ARM610 is not set
-+# CONFIG_CPU_ARM710 is not set
-+# CONFIG_CPU_ARM720T is not set
-+# CONFIG_CPU_ARM920T is not set
-+# CONFIG_CPU_ARM922T is not set
-+# CONFIG_PLD is not set
-+# CONFIG_CPU_ARM926T is not set
-+# CONFIG_CPU_ARM1020 is not set
-+# CONFIG_CPU_ARM1026 is not set
-+# CONFIG_CPU_SA110 is not set
-+CONFIG_CPU_SA1100=y
-+# CONFIG_CPU_32v3 is not set
-+CONFIG_CPU_32v4=y
-+CONFIG_DISCONTIGMEM=y
-+
-+#
-+# General setup
-+#
-+# CONFIG_PCI is not set
-+CONFIG_ISA=y
-+# CONFIG_ISA_DMA is not set
-+# CONFIG_ZBOOT_ROM is not set
-+CONFIG_ZBOOT_ROM_TEXT=0
-+CONFIG_ZBOOT_ROM_BSS=0
-+CONFIG_CPU_FREQ=y
-+CONFIG_HOTPLUG=y
-+
-+#
-+# PCMCIA/CardBus support
-+#
-+CONFIG_PCMCIA=y
-+CONFIG_PCMCIA_PROBE=y
-+# CONFIG_I82092 is not set
-+# CONFIG_I82365 is not set
-+# CONFIG_TCIC is not set
-+# CONFIG_PCMCIA_CLPS6700 is not set
-+CONFIG_PCMCIA_SA1100=y
-+CONFIG_NET=y
-+CONFIG_SYSVIPC=y
-+# CONFIG_BSD_PROCESS_ACCT is not set
-+CONFIG_SYSCTL=y
-+CONFIG_FPE_NWFPE=y
-+# CONFIG_FPE_FASTFPE is not set
-+CONFIG_KCORE_ELF=y
-+# CONFIG_KCORE_AOUT is not set
-+# CONFIG_BINFMT_AOUT is not set
-+CONFIG_BINFMT_ELF=y
-+CONFIG_BINFMT_MISC=m
-+CONFIG_PM=y
-+CONFIG_APM=y
-+CONFIG_SIMPAD_PM=y
-+# CONFIG_ARTHUR is not set
-+CONFIG_CMDLINE="mtdparts=sa1100:512k(boot),1m(kernel),-(root) console=ttySA root=1f02 noinitrd mem=64M"
-+CONFIG_LEDS=y
-+CONFIG_LEDS_TIMER=y
-+CONFIG_LEDS_CPU=y
-+CONFIG_ALIGNMENT_TRAP=y
-+
-+#
-+# Parallel port support
-+#
-+# CONFIG_PARPORT is not set
-+
-+#
-+# Memory Technology Devices (MTD)
-+#
-+CONFIG_MTD=y
-+# CONFIG_MTD_DEBUG is not set
-+CONFIG_MTD_PARTITIONS=y
-+# CONFIG_MTD_CONCAT is not set
-+CONFIG_MTD_REDBOOT_PARTS=y
-+CONFIG_MTD_CMDLINE_PARTS=y
-+# CONFIG_MTD_AFS_PARTS is not set
-+CONFIG_MTD_CHAR=y
-+CONFIG_MTD_BLOCK=y
-+# CONFIG_FTL is not set
-+# CONFIG_NFTL is not set
-+
-+#
-+# RAM/ROM/Flash chip drivers
-+#
-+CONFIG_MTD_CFI=y
-+CONFIG_MTD_JEDECPROBE=y
-+CONFIG_MTD_GEN_PROBE=y
-+CONFIG_MTD_CFI_ADV_OPTIONS=y
-+CONFIG_MTD_CFI_NOSWAP=y
-+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-+CONFIG_MTD_CFI_GEOMETRY=y
-+# CONFIG_MTD_CFI_B1 is not set
-+CONFIG_MTD_CFI_B2=y
-+# CONFIG_MTD_CFI_B4 is not set
-+# CONFIG_MTD_CFI_B8 is not set
-+CONFIG_MTD_CFI_I1=y
-+# CONFIG_MTD_CFI_I2 is not set
-+# CONFIG_MTD_CFI_I4 is not set
-+# CONFIG_MTD_CFI_I8 is not set
-+CONFIG_MTD_CFI_INTELEXT=y
-+# CONFIG_MTD_CFI_AMDSTD is not set
-+# CONFIG_MTD_RAM is not set
-+CONFIG_MTD_ROM=y
-+# CONFIG_MTD_ABSENT is not set
-+# CONFIG_MTD_OBSOLETE_CHIPS is not set
-+# CONFIG_MTD_AMDSTD is not set
-+# CONFIG_MTD_SHARP is not set
-+# CONFIG_MTD_JEDEC is not set
-+
-+#
-+# Mapping drivers for chip access
-+#
-+# CONFIG_MTD_PHYSMAP is not set
-+# CONFIG_MTD_NORA is not set
-+# CONFIG_MTD_ARM_INTEGRATOR is not set
-+# CONFIG_MTD_CDB89712 is not set
-+CONFIG_MTD_SA1100=y
-+# CONFIG_MTD_DC21285 is not set
-+# CONFIG_MTD_IQ80310 is not set
-+# CONFIG_MTD_FORTUNET is not set
-+# CONFIG_MTD_EPXA is not set
-+# CONFIG_MTD_AUTCPU12 is not set
-+# CONFIG_MTD_EDB7312 is not set
-+# CONFIG_MTD_IMPA7 is not set
-+# CONFIG_MTD_PCI is not set
-+
-+#
-+# Self-contained MTD device drivers
-+#
-+# CONFIG_MTD_PMC551 is not set
-+# CONFIG_MTD_SLRAM is not set
-+CONFIG_MTD_MTDRAM=y
-+CONFIG_MTDRAM_TOTAL_SIZE=32768
-+CONFIG_MTDRAM_ERASE_SIZE=1
-+CONFIG_MTDRAM_ABS_POS=C2000000
-+# CONFIG_MTD_BLKMTD is not set
-+# CONFIG_MTD_DOC1000 is not set
-+# CONFIG_MTD_DOC2000 is not set
-+# CONFIG_MTD_DOC2001 is not set
-+# CONFIG_MTD_DOCPROBE is not set
-+
-+#
-+# NAND Flash Device Drivers
-+#
-+# CONFIG_MTD_NAND is not set
-+
-+#
-+# Plug and Play configuration
-+#
-+# CONFIG_PNP is not set
-+# CONFIG_ISAPNP is not set
-+
-+#
-+# Block devices
-+#
-+# CONFIG_BLK_DEV_FD is not set
-+# CONFIG_BLK_DEV_XD is not set
-+# CONFIG_PARIDE is not set
-+# CONFIG_BLK_CPQ_DA is not set
-+# CONFIG_BLK_CPQ_CISS_DA is not set
-+# CONFIG_CISS_SCSI_TAPE is not set
-+# CONFIG_BLK_DEV_DAC960 is not set
-+# CONFIG_BLK_DEV_UMEM is not set
-+CONFIG_BLK_DEV_LOOP=y
-+# CONFIG_BLK_DEV_NBD is not set
-+CONFIG_BLK_DEV_RAM=y
-+CONFIG_BLK_DEV_RAM_SIZE=8192
-+# CONFIG_BLK_DEV_INITRD is not set
-+
-+#
-+# Multi-device support (RAID and LVM)
-+#
-+# CONFIG_MD is not set
-+# CONFIG_BLK_DEV_MD is not set
-+# CONFIG_MD_LINEAR is not set
-+# CONFIG_MD_RAID0 is not set
-+# CONFIG_MD_RAID1 is not set
-+# CONFIG_MD_RAID5 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_BLK_DEV_LVM is not set
-+
-+#
-+# Networking options
-+#
-+CONFIG_PACKET=y
-+CONFIG_PACKET_MMAP=y
-+# CONFIG_NETLINK_DEV is not set
-+# CONFIG_NETFILTER is not set
-+# CONFIG_FILTER is not set
-+CONFIG_UNIX=y
-+CONFIG_INET=y
-+# CONFIG_IP_MULTICAST is not set
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+CONFIG_IP_PNP=y
-+CONFIG_IP_PNP_DHCP=y
-+CONFIG_IP_PNP_BOOTP=y
-+# CONFIG_IP_PNP_RARP is not set
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_ARPD is not set
-+# CONFIG_INET_ECN is not set
-+# CONFIG_SYN_COOKIES is not set
-+# CONFIG_IPV6 is not set
-+# CONFIG_KHTTPD is not set
-+# CONFIG_ATM is not set
-+# CONFIG_VLAN_8021Q is not set
-+# CONFIG_IPX is not set
-+# CONFIG_ATALK is not set
-+
-+#
-+# Appletalk devices
-+#
-+# CONFIG_DEV_APPLETALK is not set
-+# CONFIG_DECNET is not set
-+# CONFIG_BRIDGE is not set
-+# CONFIG_X25 is not set
-+# CONFIG_LAPB is not set
-+# CONFIG_LLC is not set
-+# CONFIG_NET_DIVERT is not set
-+# CONFIG_ECONET is not set
-+# CONFIG_WAN_ROUTER is not set
-+# CONFIG_NET_FASTROUTE is not set
-+# CONFIG_NET_HW_FLOWCONTROL is not set
-+
-+#
-+# QoS and/or fair queueing
-+#
-+# CONFIG_NET_SCHED is not set
-+
-+#
-+# Network testing
-+#
-+# CONFIG_NET_PKTGEN is not set
-+
-+#
-+# Network device support
-+#
-+CONFIG_NETDEVICES=y
-+
-+#
-+# ARCnet devices
-+#
-+# CONFIG_ARCNET is not set
-+CONFIG_DUMMY=y
-+# CONFIG_BONDING is not set
-+# CONFIG_EQUALIZER is not set
-+# CONFIG_TUN is not set
-+# CONFIG_ETHERTAP is not set
-+
-+#
-+# Ethernet (10 or 100Mbit)
-+#
-+CONFIG_NET_ETHERNET=y
-+# CONFIG_ARM_AM79C961A is not set
-+# CONFIG_ARM_CIRRUS is not set
-+# CONFIG_SUNLANCE is not set
-+# CONFIG_SUNBMAC is not set
-+# CONFIG_SUNQE is not set
-+# CONFIG_SUNGEM is not set
-+# CONFIG_NET_VENDOR_3COM is not set
-+# CONFIG_LANCE is not set
-+# CONFIG_NET_VENDOR_SMC is not set
-+# CONFIG_NET_VENDOR_RACAL is not set
-+# CONFIG_AT1700 is not set
-+# CONFIG_DEPCA is not set
-+# CONFIG_HP100 is not set
-+# CONFIG_NET_ISA is not set
-+CONFIG_NET_PCI=y
-+# CONFIG_PCNET32 is not set
-+# CONFIG_ADAPTEC_STARFIRE is not set
-+# CONFIG_AC3200 is not set
-+# CONFIG_APRICOT is not set
-+# CONFIG_CS89x0 is not set
-+# CONFIG_TULIP is not set
-+# CONFIG_TC35815 is not set
-+# CONFIG_DM9102 is not set
-+# CONFIG_EEPRO100 is not set
-+# CONFIG_LNE390 is not set
-+# CONFIG_FEALNX is not set
-+# CONFIG_NATSEMI is not set
-+# CONFIG_NE2K_PCI is not set
-+# CONFIG_NE3210 is not set
-+# CONFIG_ES3210 is not set
-+# CONFIG_8139CP is not set
-+# CONFIG_8139TOO is not set
-+# CONFIG_8139TOO_PIO is not set
-+# CONFIG_8139TOO_TUNE_TWISTER is not set
-+# CONFIG_8139TOO_8129 is not set
-+# CONFIG_8139_NEW_RX_RESET is not set
-+# CONFIG_SIS900 is not set
-+# CONFIG_EPIC100 is not set
-+# CONFIG_SUNDANCE is not set
-+# CONFIG_VIA_RHINE is not set
-+# CONFIG_VIA_RHINE_MMIO is not set
-+# CONFIG_WINBOND_840 is not set
-+# CONFIG_NET_POCKET is not set
-+
-+#
-+# Ethernet (1000 Mbit)
-+#
-+# CONFIG_ACENIC is not set
-+# CONFIG_DL2K is not set
-+# CONFIG_MYRI_SBUS is not set
-+# CONFIG_NS83820 is not set
-+# CONFIG_HAMACHI is not set
-+# CONFIG_YELLOWFIN is not set
-+# CONFIG_SK98LIN is not set
-+# CONFIG_TIGON3 is not set
-+# CONFIG_FDDI is not set
-+# CONFIG_HIPPI is not set
-+# CONFIG_PLIP is not set
-+# CONFIG_PPP is not set
-+# CONFIG_SLIP is not set
-+
-+#
-+# Wireless LAN (non-hamradio)
-+#
-+CONFIG_NET_RADIO=y
-+# CONFIG_STRIP is not set
-+# CONFIG_WAVELAN is not set
-+# CONFIG_ARLAN is not set
-+# CONFIG_AIRONET4500 is not set
-+# CONFIG_AIRONET4500_NONCS is not set
-+# CONFIG_AIRONET4500_PROC is not set
-+CONFIG_AIRO=m
-+# CONFIG_HERMES is not set
-+# CONFIG_PCMCIA_HERMES is not set
-+CONFIG_AIRO_CS=m
-+CONFIG_NET_WIRELESS=y
-+
-+#
-+# Token Ring devices
-+#
-+# CONFIG_TR is not set
-+# CONFIG_NET_FC is not set
-+# CONFIG_RCPCI is not set
-+# CONFIG_SHAPER is not set
-+
-+#
-+# Wan interfaces
-+#
-+# CONFIG_WAN is not set
-+
-+#
-+# PCMCIA network device support
-+#
-+CONFIG_NET_PCMCIA=y
-+CONFIG_PCMCIA_3C589=m
-+CONFIG_PCMCIA_3C574=m
-+# CONFIG_PCMCIA_FMVJ18X is not set
-+CONFIG_PCMCIA_PCNET=m
-+# CONFIG_PCMCIA_AXNET is not set
-+# CONFIG_PCMCIA_NMCLAN is not set
-+CONFIG_PCMCIA_SMC91C92=m
-+CONFIG_PCMCIA_XIRC2PS=m
-+# CONFIG_ARCNET_COM20020_CS is not set
-+# CONFIG_PCMCIA_IBMTR is not set
-+CONFIG_NET_PCMCIA_RADIO=y
-+# CONFIG_PCMCIA_RAYCS is not set
-+# CONFIG_PCMCIA_NETWAVE is not set
-+CONFIG_PCMCIA_WAVELAN=m
-+# CONFIG_AIRONET4500_CS is not set
-+
-+#
-+# Amateur Radio support
-+#
-+# CONFIG_HAMRADIO is not set
-+
-+#
-+# IrDA (infrared) support
-+#
-+CONFIG_IRDA=m
-+CONFIG_IRLAN=m
-+# CONFIG_IRNET is not set
-+CONFIG_IRCOMM=m
-+# CONFIG_IRDA_ULTRA is not set
-+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
-+# CONFIG_IRDA_FAST_RR is not set
-+# CONFIG_IRDA_DEBUG is not set
-+
-+#
-+# Infrared-port device drivers
-+#
-+CONFIG_IRTTY_SIR=m
-+CONFIG_IRPORT_SIR=m
-+# CONFIG_DONGLE is not set
-+# CONFIG_USB_IRDA is not set
-+# CONFIG_NSC_FIR is not set
-+# CONFIG_WINBOND_FIR is not set
-+# CONFIG_TOSHIBA_FIR is not set
-+# CONFIG_SMC_IRCC_FIR is not set
-+# CONFIG_ALI_FIR is not set
-+# CONFIG_VLSI_FIR is not set
-+CONFIG_SA1100_FIR=m
-+
-+#
-+# ATA/ATAPI/MFM/RLL support
-+#
-+CONFIG_IDE=m
-+
-+#
-+# IDE, ATA and ATAPI Block devices
-+#
-+CONFIG_BLK_DEV_IDE=m
-+# CONFIG_BLK_DEV_HD_IDE is not set
-+# CONFIG_BLK_DEV_HD is not set
-+CONFIG_BLK_DEV_IDEDISK=m
-+# CONFIG_IDEDISK_MULTI_MODE is not set
-+# CONFIG_IDEDISK_STROKE is not set
-+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-+# CONFIG_BLK_DEV_IDEDISK_WD is not set
-+# CONFIG_BLK_DEV_COMMERIAL is not set
-+# CONFIG_BLK_DEV_TIVO is not set
-+CONFIG_BLK_DEV_IDECS=m
-+# CONFIG_BLK_DEV_IDECD is not set
-+# CONFIG_BLK_DEV_IDETAPE is not set
-+# CONFIG_BLK_DEV_IDEFLOPPY is not set
-+# CONFIG_BLK_DEV_IDESCSI is not set
-+# CONFIG_IDE_TASK_IOCTL is not set
-+# CONFIG_BLK_DEV_CMD640 is not set
-+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-+# CONFIG_BLK_DEV_ISAPNP is not set
-+# CONFIG_IDE_CHIPSETS is not set
-+# CONFIG_IDEDMA_AUTO is not set
-+# CONFIG_DMA_NONPCI is not set
-+# CONFIG_BLK_DEV_IDE_MODES is not set
-+# CONFIG_BLK_DEV_ATARAID is not set
-+# CONFIG_BLK_DEV_ATARAID_PDC is not set
-+# CONFIG_BLK_DEV_ATARAID_HPT is not set
-+
-+#
-+# SCSI support
-+#
-+# CONFIG_SCSI is not set
-+
-+#
-+# I2O device support
-+#
-+# CONFIG_I2O is not set
-+# CONFIG_I2O_BLOCK is not set
-+# CONFIG_I2O_LAN is not set
-+# CONFIG_I2O_SCSI is not set
-+# CONFIG_I2O_PROC is not set
-+
-+#
-+# ISDN subsystem
-+#
-+# CONFIG_ISDN is not set
-+
-+#
-+# Input core support
-+#
-+CONFIG_INPUT=y
-+# CONFIG_INPUT_KEYBDEV is not set
-+# CONFIG_INPUT_MOUSEDEV is not set
-+# CONFIG_INPUT_JOYDEV is not set
-+# CONFIG_INPUT_EVDEV is not set
-+
-+#
-+# Character devices
-+#
-+CONFIG_VT=y
-+CONFIG_VT_CONSOLE=y
-+CONFIG_SERIAL=m
-+# CONFIG_SERIAL_EXTENDED is not set
-+# CONFIG_SERIAL_NONSTANDARD is not set
-+
-+#
-+# Serial drivers
-+#
-+# CONFIG_SERIAL_ANAKIN is not set
-+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-+# CONFIG_SERIAL_AMBA is not set
-+# CONFIG_SERIAL_AMBA_CONSOLE is not set
-+# CONFIG_SERIAL_CLPS711X is not set
-+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-+# CONFIG_SERIAL_21285 is not set
-+# CONFIG_SERIAL_21285_OLD is not set
-+# CONFIG_SERIAL_21285_CONSOLE is not set
-+# CONFIG_SERIAL_UART00 is not set
-+# CONFIG_SERIAL_UART00_CONSOLE is not set
-+CONFIG_SERIAL_SA1100=y
-+CONFIG_SERIAL_SA1100_CONSOLE=y
-+CONFIG_SA1100_DEFAULT_BAUDRATE=115200
-+# CONFIG_SERIAL_OMAHA is not set
-+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
-+# CONFIG_SERIAL_AT91US3 is not set
-+# CONFIG_SERIAL_AT91US3_CONSOLE is not set
-+# CONFIG_SERIAL_8250 is not set
-+# CONFIG_SERIAL_8250_CONSOLE is not set
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+# CONFIG_SERIAL_8250_MANY_PORTS is not set
-+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-+# CONFIG_SERIAL_8250_MULTIPORT is not set
-+# CONFIG_SERIAL_8250_HUB6 is not set
-+CONFIG_SERIAL_CORE=y
-+CONFIG_SERIAL_CORE_CONSOLE=y
-+CONFIG_UNIX98_PTYS=y
-+CONFIG_UNIX98_PTY_COUNT=32
-+
-+#
-+# I2C support
-+#
-+# CONFIG_I2C is not set
-+
-+#
-+# L3 serial bus support
-+#
-+# CONFIG_L3 is not set
-+# CONFIG_L3_ALGOBIT is not set
-+# CONFIG_L3_BIT_SA1100_GPIO is not set
-+# CONFIG_L3_SA1111 is not set
-+# CONFIG_BIT_SA1100_GPIO is not set
-+
-+#
-+# Mice
-+#
-+# CONFIG_BUSMOUSE is not set
-+# CONFIG_MOUSE is not set
-+
-+#
-+# Joysticks
-+#
-+# CONFIG_INPUT_GAMEPORT is not set
-+# CONFIG_INPUT_NS558 is not set
-+# CONFIG_INPUT_LIGHTNING is not set
-+# CONFIG_INPUT_PCIGAME is not set
-+# CONFIG_INPUT_CS461X is not set
-+# CONFIG_INPUT_EMU10K1 is not set
-+# CONFIG_INPUT_SERIO is not set
-+# CONFIG_INPUT_SERPORT is not set
-+# CONFIG_INPUT_ANALOG is not set
-+# CONFIG_INPUT_A3D is not set
-+# CONFIG_INPUT_ADI is not set
-+# CONFIG_INPUT_COBRA is not set
-+# CONFIG_INPUT_GF2K is not set
-+# CONFIG_INPUT_GRIP is not set
-+# CONFIG_INPUT_INTERACT is not set
-+# CONFIG_INPUT_TMDC is not set
-+# CONFIG_INPUT_SIDEWINDER is not set
-+# CONFIG_INPUT_IFORCE_USB is not set
-+# CONFIG_INPUT_IFORCE_232 is not set
-+# CONFIG_INPUT_WARRIOR is not set
-+# CONFIG_INPUT_MAGELLAN is not set
-+# CONFIG_INPUT_SPACEORB is not set
-+# CONFIG_INPUT_SPACEBALL is not set
-+# CONFIG_INPUT_STINGER is not set
-+# CONFIG_INPUT_DB9 is not set
-+# CONFIG_INPUT_GAMECON is not set
-+# CONFIG_INPUT_TURBOGRAFX is not set
-+# CONFIG_QIC02_TAPE is not set
-+
-+#
-+# Watchdog Cards
-+#
-+# CONFIG_WATCHDOG is not set
-+# CONFIG_NVRAM is not set
-+# CONFIG_RTC is not set
-+CONFIG_SA1100_RTC=y
-+# CONFIG_DTLK is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_APPLICOM is not set
-+
-+#
-+# Ftape, the floppy tape device driver
-+#
-+# CONFIG_FTAPE is not set
-+# CONFIG_AGP is not set
-+# CONFIG_DRM is not set
-+
-+#
-+# PCMCIA character devices
-+#
-+CONFIG_PCMCIA_SERIAL_CS=m
-+CONFIG_TDA8007=m
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+
-+#
-+# File systems
-+#
-+# CONFIG_QUOTA is not set
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+CONFIG_REISERFS_FS=m
-+# CONFIG_REISERFS_CHECK is not set
-+CONFIG_REISERFS_PROC_INFO=y
-+# CONFIG_ADFS_FS is not set
-+# CONFIG_ADFS_FS_RW is not set
-+# CONFIG_AFFS_FS is not set
-+# CONFIG_HFS_FS is not set
-+# CONFIG_BFS_FS is not set
-+CONFIG_EXT3_FS=m
-+CONFIG_JBD=m
-+# CONFIG_JBD_DEBUG is not set
-+CONFIG_FAT_FS=m
-+CONFIG_MSDOS_FS=m
-+CONFIG_UMSDOS_FS=m
-+CONFIG_VFAT_FS=m
-+# CONFIG_EFS_FS is not set
-+CONFIG_JFFS_FS=m
-+CONFIG_JFFS_FS_VERBOSE=0
-+CONFIG_JFFS_PROC_FS=y
-+CONFIG_JFFS2_FS=y
-+CONFIG_JFFS2_FS_DEBUG=0
-+CONFIG_CRAMFS=m
-+# CONFIG_TMPFS is not set
-+CONFIG_RAMFS=y
-+# CONFIG_ISO9660_FS is not set
-+# CONFIG_JOLIET is not set
-+# CONFIG_ZISOFS is not set
-+# CONFIG_MINIX_FS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_NTFS_FS is not set
-+# CONFIG_NTFS_RW is not set
-+# CONFIG_HPFS_FS is not set
-+CONFIG_PROC_FS=y
-+CONFIG_DEVFS_FS=y
-+CONFIG_DEVFS_MOUNT=y
-+CONFIG_DEVFS_DEBUG=y
-+# CONFIG_DEVPTS_FS is not set
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_QNX4FS_RW is not set
-+# CONFIG_ROMFS_FS is not set
-+CONFIG_EXT2_FS=m
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UDF_FS is not set
-+# CONFIG_UDF_RW is not set
-+# CONFIG_UFS_FS is not set
-+# CONFIG_UFS_FS_WRITE is not set
-+
-+#
-+# Network File Systems
-+#
-+# CONFIG_CODA_FS is not set
-+# CONFIG_INTERMEZZO_FS is not set
-+CONFIG_NFS_FS=y
-+CONFIG_NFS_V3=y
-+# CONFIG_ROOT_NFS is not set
-+# CONFIG_NFSD is not set
-+# CONFIG_NFSD_V3 is not set
-+CONFIG_SUNRPC=y
-+CONFIG_LOCKD=y
-+CONFIG_LOCKD_V4=y
-+CONFIG_SMB_FS=m
-+# CONFIG_SMB_NLS_DEFAULT is not set
-+# CONFIG_NCP_FS is not set
-+# CONFIG_NCPFS_PACKET_SIGNING is not set
-+# CONFIG_NCPFS_IOCTL_LOCKING is not set
-+# CONFIG_NCPFS_STRONG is not set
-+# CONFIG_NCPFS_NFS_NS is not set
-+# CONFIG_NCPFS_OS2_NS is not set
-+# CONFIG_NCPFS_SMALLDOS is not set
-+# CONFIG_NCPFS_NLS is not set
-+# CONFIG_NCPFS_EXTRAS is not set
-+# CONFIG_ZISOFS_FS is not set
-+CONFIG_ZLIB_FS_INFLATE=m
-+
-+#
-+# Partition Types
-+#
-+# CONFIG_PARTITION_ADVANCED is not set
-+CONFIG_MSDOS_PARTITION=y
-+CONFIG_SMB_NLS=y
-+CONFIG_NLS=y
-+
-+#
-+# Native Language Support
-+#
-+CONFIG_NLS_DEFAULT="iso8859-1"
-+CONFIG_NLS_CODEPAGE_437=y
-+# CONFIG_NLS_CODEPAGE_737 is not set
-+# CONFIG_NLS_CODEPAGE_775 is not set
-+CONFIG_NLS_CODEPAGE_850=y
-+# CONFIG_NLS_CODEPAGE_852 is not set
-+# CONFIG_NLS_CODEPAGE_855 is not set
-+# CONFIG_NLS_CODEPAGE_857 is not set
-+# CONFIG_NLS_CODEPAGE_860 is not set
-+# CONFIG_NLS_CODEPAGE_861 is not set
-+# CONFIG_NLS_CODEPAGE_862 is not set
-+# CONFIG_NLS_CODEPAGE_863 is not set
-+# CONFIG_NLS_CODEPAGE_864 is not set
-+# CONFIG_NLS_CODEPAGE_865 is not set
-+# CONFIG_NLS_CODEPAGE_866 is not set
-+# CONFIG_NLS_CODEPAGE_869 is not set
-+# CONFIG_NLS_CODEPAGE_936 is not set
-+# CONFIG_NLS_CODEPAGE_950 is not set
-+# CONFIG_NLS_CODEPAGE_932 is not set
-+# CONFIG_NLS_CODEPAGE_949 is not set
-+# CONFIG_NLS_CODEPAGE_874 is not set
-+# CONFIG_NLS_ISO8859_8 is not set
-+# CONFIG_NLS_CODEPAGE_1250 is not set
-+# CONFIG_NLS_CODEPAGE_1251 is not set
-+CONFIG_NLS_ISO8859_1=y
-+# CONFIG_NLS_ISO8859_2 is not set
-+# CONFIG_NLS_ISO8859_3 is not set
-+# CONFIG_NLS_ISO8859_4 is not set
-+# CONFIG_NLS_ISO8859_5 is not set
-+# CONFIG_NLS_ISO8859_6 is not set
-+# CONFIG_NLS_ISO8859_7 is not set
-+# CONFIG_NLS_ISO8859_9 is not set
-+# CONFIG_NLS_ISO8859_13 is not set
-+# CONFIG_NLS_ISO8859_14 is not set
-+CONFIG_NLS_ISO8859_15=y
-+# CONFIG_NLS_KOI8_R is not set
-+# CONFIG_NLS_KOI8_U is not set
-+# CONFIG_NLS_UTF8 is not set
-+
-+#
-+# Console drivers
-+#
-+CONFIG_PC_KEYMAP=y
-+# CONFIG_VGA_CONSOLE is not set
-+
-+#
-+# Frame-buffer support
-+#
-+CONFIG_FB=y
-+CONFIG_DUMMY_CONSOLE=y
-+# CONFIG_FB_ACORN is not set
-+# CONFIG_FB_ANAKIN is not set
-+# CONFIG_FB_CLPS711X is not set
-+# CONFIG_FB_SA1100 is not set
-+# CONFIG_FB_CYBER2000 is not set
-+CONFIG_FB_MQ200=y
-+# CONFIG_FB_VIRTUAL is not set
-+CONFIG_FBCON_ADVANCED=y
-+# CONFIG_FBCON_MFB is not set
-+# CONFIG_FBCON_CFB2 is not set
-+CONFIG_FBCON_CFB4=y
-+CONFIG_FBCON_CFB8=y
-+CONFIG_FBCON_CFB16=y
-+# CONFIG_FBCON_CFB24 is not set
-+# CONFIG_FBCON_CFB32 is not set
-+# CONFIG_FBCON_AFB is not set
-+# CONFIG_FBCON_ILBM is not set
-+# CONFIG_FBCON_IPLAN2P2 is not set
-+# CONFIG_FBCON_IPLAN2P4 is not set
-+# CONFIG_FBCON_IPLAN2P8 is not set
-+# CONFIG_FBCON_MAC is not set
-+# CONFIG_FBCON_VGA_PLANES is not set
-+# CONFIG_FBCON_VGA is not set
-+# CONFIG_FBCON_HGA is not set
-+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-+CONFIG_FBCON_FONTS=y
-+CONFIG_FONT_8x8=y
-+CONFIG_FONT_8x16=y
-+# CONFIG_FONT_SUN8x16 is not set
-+# CONFIG_FONT_SUN12x22 is not set
-+# CONFIG_FONT_6x11 is not set
-+# CONFIG_FONT_PEARL_8x8 is not set
-+# CONFIG_FONT_ACORN_8x8 is not set
-+
-+#
-+# Sound
-+#
-+CONFIG_SOUND=y
-+# CONFIG_SOUND_BT878 is not set
-+# CONFIG_SOUND_CMPCI is not set
-+# CONFIG_SOUND_EMU10K1 is not set
-+# CONFIG_MIDI_EMU10K1 is not set
-+# CONFIG_SOUND_FUSION is not set
-+# CONFIG_SOUND_CS4281 is not set
-+# CONFIG_SOUND_ES1370 is not set
-+# CONFIG_SOUND_ES1371 is not set
-+# CONFIG_SOUND_ESSSOLO1 is not set
-+# CONFIG_SOUND_MAESTRO is not set
-+# CONFIG_SOUND_MAESTRO3 is not set
-+# CONFIG_SOUND_ICH is not set
-+# CONFIG_SOUND_RME96XX is not set
-+# CONFIG_SOUND_SONICVIBES is not set
-+# CONFIG_SOUND_TRIDENT is not set
-+# CONFIG_SOUND_MSNDCLAS is not set
-+# CONFIG_SOUND_MSNDPIN is not set
-+# CONFIG_SOUND_VIA82CXXX is not set
-+# CONFIG_MIDI_VIA82CXXX is not set
-+CONFIG_SOUND_SA1100=y
-+# CONFIG_SOUND_UDA1341 is not set
-+# CONFIG_SOUND_ASSABET_UDA1341 is not set
-+# CONFIG_SOUND_H3600_UDA1341 is not set
-+# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
-+# CONFIG_SOUND_SA1111_UDA1341 is not set
-+# CONFIG_SOUND_SA1111_AC97 is not set
-+# CONFIG_SOUND_SA1100SSP is not set
-+# CONFIG_SOUND_OSS is not set
-+# CONFIG_SOUND_VIDC is not set
-+# CONFIG_SOUND_WAVEARTIST is not set
-+# CONFIG_SOUND_TVMIXER is not set
-+
-+#
-+# Multimedia Capabilities Port drivers
-+#
-+CONFIG_MCP=y
-+CONFIG_MCP_SA1100=y
-+CONFIG_MCP_UCB1200=y
-+CONFIG_MCP_UCB1200_AUDIO=y
-+CONFIG_MCP_UCB1200_TS=y
-+
-+#
-+# Console Switches
-+#
-+CONFIG_SWITCHES=y
-+CONFIG_SWITCHES_SA1100=y
-+CONFIG_SWITCHES_UCB1X00=y
-+
-+#
-+# USB support
-+#
-+# CONFIG_USB is not set
-+
-+#
-+# Bluetooth support
-+#
-+# CONFIG_BLUEZ is not set
-+
-+#
-+# Kernel hacking
-+#
-+CONFIG_FRAME_POINTER=y
-+CONFIG_DEBUG_USER=y
-+# CONFIG_DEBUG_INFO is not set
-+# CONFIG_NO_PGT_CACHE is not set
-+# CONFIG_DEBUG_KERNEL is not set
-+# CONFIG_DEBUG_SLAB is not set
-+# CONFIG_MAGIC_SYSRQ is not set
-+# CONFIG_DEBUG_SPINLOCK is not set
-+# CONFIG_DEBUG_WAITQ is not set
-+# CONFIG_DEBUG_BUGVERBOSE is not set
-+# CONFIG_DEBUG_ERRORS is not set
-+# CONFIG_DEBUG_LL is not set
-+# CONFIG_DEBUG_DC21285_PORT is not set
-+# CONFIG_DEBUG_CLPS711X_UART2 is not set
---- linux-2.4.25/arch/arm/kernel/head-armv.S~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200
-+++ linux-2.4.25/arch/arm/kernel/head-armv.S 2004-05-02 22:45:42.000000000 +0200
-@@ -93,6 +93,8 @@
- .section ".text.init",#alloc,#execinstr
- .type stext, #function
- ENTRY(stext)
-+ mov r1, #87
-+ mov r0, #0
- mov r12, r0
- /*
- * NOTE! Any code which is placed here should be done for one of
---- linux-2.4.25/arch/arm/kernel/irq.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:37.000000000 +0200
-+++ linux-2.4.25/arch/arm/kernel/irq.c 2004-05-02 22:45:42.000000000 +0200
-@@ -82,9 +82,9 @@
-
- spin_lock_irqsave(&irq_controller_lock, flags);
- if (!desc->disable_depth++) {
--#ifndef CONFIG_CPU_SA1100
-+// #ifndef CONFIG_CPU_SA1100
- desc->mask(irq);
--#endif
-+// #endif
- }
- spin_unlock_irqrestore(&irq_controller_lock, flags);
- }
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/apm.c 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,520 @@
-+/*
-+ * bios-less APM driver for ARM Linux
-+ * Jamey Hicks <jamey@crl.dec.com>
-+ * adapted from the APM BIOS driver for Linux by Stephen Rothwell (sfr@linuxcare.com)
-+ *
-+ * APM 1.2 Reference:
-+ * Intel Corporation, Microsoft Corporation. Advanced Power Management
-+ * (APM) BIOS Interface Specification, Revision 1.2, February 1996.
-+ *
-+ * [This document is available from Microsoft at:
-+ * http://www.microsoft.com/hwdev/busbios/amp_12.htm]
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/poll.h>
-+#include <linux/types.h>
-+#include <linux/stddef.h>
-+#include <linux/timer.h>
-+#include <linux/fcntl.h>
-+#include <linux/slab.h>
-+#include <linux/stat.h>
-+#include <linux/proc_fs.h>
-+#include <linux/miscdevice.h>
-+#include <linux/apm_bios.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/pm.h>
-+#include <linux/kernel.h>
-+#include <linux/smp_lock.h>
-+
-+#include <asm/system.h>
-+#include <asm/hardware.h>
-+#if FIXME
-+#include <asm/arch-sa1100/pm.h>
-+#endif
-+
-+#ifdef CONFIG_IPAQ_HANDHELD
-+#include <asm/arch-sa1100/h3600_hal.h>
-+#endif
-+
-+#ifdef CONFIG_SA1100_SIMPAD
-+#include <asm/arch-sa1100/simpad_pm.h>
-+#endif
-+
-+#if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT)
-+extern int (*console_blank_hook)(int);
-+#endif
-+
-+struct apm_bios_info apm_bios_info = {
-+ /* this driver simulates APM version 1.2 */
-+ version: 0x102,
-+ flags: APM_32_BIT_SUPPORT
-+};
-+
-+/*
-+ * The apm_bios device is one of the misc char devices.
-+ * This is its minor number.
-+ */
-+#define APM_MINOR_DEV 134
-+
-+/*
-+ * See Documentation/Config.help for the configuration options.
-+ *
-+ * Various options can be changed at boot time as follows:
-+ * (We allow underscores for compatibility with the modules code)
-+ * apm=on/off enable/disable APM
-+ * [no-]debug log some debugging messages
-+ * [no-]power[-_]off power off on shutdown
-+ */
-+
-+/*
-+ * Need to poll the APM BIOS every second
-+ */
-+#define APM_CHECK_TIMEOUT (HZ)
-+
-+/*
-+ * Ignore suspend events for this amount of time after a resume
-+ */
-+#define DEFAULT_BOUNCE_INTERVAL (3 * HZ)
-+
-+/*
-+ * Maximum number of events stored
-+ */
-+#define APM_MAX_EVENTS 20
-+
-+/*
-+ * The per-file APM data
-+ */
-+struct apm_user {
-+ int magic;
-+ struct apm_user * next;
-+ int suser: 1;
-+ int suspend_wait: 1;
-+ int suspend_result;
-+ int suspends_pending;
-+ int standbys_pending;
-+ int suspends_read;
-+ int standbys_read;
-+ int event_head;
-+ int event_tail;
-+ apm_event_t events[APM_MAX_EVENTS];
-+};
-+
-+/*
-+ * The magic number in apm_user
-+ */
-+#define APM_BIOS_MAGIC 0x4101
-+
-+/*
-+ * Local variables
-+ */
-+//static int suspends_pending;
-+//static int standbys_pending;
-+//static int ignore_normal_resume;
-+
-+#ifdef CONFIG_APM_RTC_IS_GMT
-+# define clock_cmos_diff 0
-+# define got_clock_diff 1
-+#else
-+//static long clock_cmos_diff;
-+//static int got_clock_diff;
-+#endif
-+static int debug;
-+static int apm_disabled;
-+#ifdef CONFIG_SMP
-+static int power_off;
-+#else
-+static int power_off = 1;
-+#endif
-+static int exit_kapmd;
-+static int kapmd_running;
-+
-+static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
-+static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
-+static struct apm_user * user_list = NULL;
-+
-+static char driver_version[] = "1.13"; /* no spaces */
-+
-+typedef struct lookup_t {
-+ int key;
-+ char * msg;
-+} lookup_t;
-+
-+static const lookup_t error_table[] = {
-+/* N/A { APM_SUCCESS, "Operation succeeded" }, */
-+ { APM_DISABLED, "Power management disabled" },
-+ { APM_CONNECTED, "Real mode interface already connected" },
-+ { APM_NOT_CONNECTED, "Interface not connected" },
-+ { APM_16_CONNECTED, "16 bit interface already connected" },
-+/* N/A { APM_16_UNSUPPORTED, "16 bit interface not supported" }, */
-+ { APM_32_CONNECTED, "32 bit interface already connected" },
-+ { APM_32_UNSUPPORTED, "32 bit interface not supported" },
-+ { APM_BAD_DEVICE, "Unrecognized device ID" },
-+ { APM_BAD_PARAM, "Parameter out of range" },
-+ { APM_NOT_ENGAGED, "Interface not engaged" },
-+ { APM_BAD_FUNCTION, "Function not supported" },
-+ { APM_RESUME_DISABLED, "Resume timer disabled" },
-+ { APM_BAD_STATE, "Unable to enter requested state" },
-+/* N/A { APM_NO_EVENTS, "No events pending" }, */
-+ { APM_NO_ERROR, "BIOS did not set a return code" },
-+ { APM_NOT_PRESENT, "No APM present" }
-+};
-+#define ERROR_COUNT (sizeof(error_table)/sizeof(lookup_t))
-+
-+static int apm_get_power_status(u_char *ac_line_status,
-+ u_char *battery_status,
-+ u_char *battery_flag,
-+ u_char *battery_percentage,
-+ u_short *battery_life)
-+{
-+#ifdef CONFIG_IPAQ_HANDHELD
-+ h3600_apm_get_power_status(ac_line_status, battery_status, battery_flag, battery_percentage, battery_life);
-+#endif
-+#ifdef CONFIG_SA1100_SIMPAD
-+ simpad_apm_get_power_status(ac_line_status, battery_status, battery_flag, battery_percentage, battery_life);
-+#endif
-+ return APM_SUCCESS;
-+}
-+
-+static int queue_empty(struct apm_user *as)
-+{
-+ return as->event_head == as->event_tail;
-+}
-+
-+static apm_event_t get_queued_event(struct apm_user *as)
-+{
-+ as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
-+ return as->events[as->event_tail];
-+}
-+
-+static int check_apm_user(struct apm_user *as, const char *func)
-+{
-+ if ((as == NULL) || (as->magic != APM_BIOS_MAGIC)) {
-+ printk(KERN_ERR "apm: %s passed bad filp\n", func);
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+static ssize_t do_read(struct file *fp, char *buf, size_t count, loff_t *ppos)
-+{
-+ struct apm_user * as;
-+ int i;
-+ apm_event_t event;
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+ as = fp->private_data;
-+ if (check_apm_user(as, "read"))
-+ return -EIO;
-+ if (count < sizeof(apm_event_t))
-+ return -EINVAL;
-+ if (queue_empty(as)) {
-+ if (fp->f_flags & O_NONBLOCK)
-+ return -EAGAIN;
-+ add_wait_queue(&apm_waitqueue, &wait);
-+ printk("do_read: waiting\n");
-+repeat:
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (queue_empty(as) && !signal_pending(current)) {
-+ schedule();
-+ goto repeat;
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&apm_waitqueue, &wait);
-+ }
-+ i = count;
-+ while ((i >= sizeof(event)) && !queue_empty(as)) {
-+ event = get_queued_event(as);
-+ printk(" do_read: event=%d\n", event);
-+ if (copy_to_user(buf, &event, sizeof(event))) {
-+ if (i < count)
-+ break;
-+ return -EFAULT;
-+ }
-+ switch (event) {
-+ case APM_SYS_SUSPEND:
-+ case APM_USER_SUSPEND:
-+ as->suspends_read++;
-+ break;
-+
-+ case APM_SYS_STANDBY:
-+ case APM_USER_STANDBY:
-+ as->standbys_read++;
-+ break;
-+ }
-+ buf += sizeof(event);
-+ i -= sizeof(event);
-+ }
-+ if (i < count)
-+ return count - i;
-+ if (signal_pending(current))
-+ return -ERESTARTSYS;
-+ return 0;
-+}
-+
-+static unsigned int do_poll(struct file *fp, poll_table * wait)
-+{
-+ struct apm_user * as;
-+
-+ as = fp->private_data;
-+ if (check_apm_user(as, "poll"))
-+ return 0;
-+ poll_wait(fp, &apm_waitqueue, wait);
-+ if (!queue_empty(as))
-+ return POLLIN | POLLRDNORM;
-+ return 0;
-+}
-+
-+static int do_ioctl(struct inode * inode, struct file *filp,
-+ u_int cmd, u_long arg)
-+{
-+ struct apm_user * as;
-+
-+ as = filp->private_data;
-+ if (check_apm_user(as, "ioctl"))
-+ return -EIO;
-+ if (!as->suser)
-+ return -EPERM;
-+ switch (cmd) {
-+ case APM_IOC_SUSPEND:
-+#if FIXME
-+ pm_suggest_suspend();
-+#endif
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ return 0;
-+}
-+
-+static int do_release(struct inode * inode, struct file * filp)
-+{
-+ struct apm_user * as;
-+
-+ as = filp->private_data;
-+ if (check_apm_user(as, "release"))
-+ return 0;
-+ filp->private_data = NULL;
-+ lock_kernel();
-+ unlock_kernel();
-+ kfree(as);
-+ return 0;
-+}
-+
-+static int do_open(struct inode * inode, struct file * filp)
-+{
-+ struct apm_user * as;
-+
-+ as = (struct apm_user *)kmalloc(sizeof(*as), GFP_KERNEL);
-+ if (as == NULL) {
-+ printk(KERN_ERR "apm: cannot allocate struct of size %d bytes\n",
-+ sizeof(*as));
-+ return -ENOMEM;
-+ }
-+ as->magic = APM_BIOS_MAGIC;
-+ as->event_tail = as->event_head = 0;
-+ as->suspends_pending = as->standbys_pending = 0;
-+ as->suspends_read = as->standbys_read = 0;
-+ /*
-+ * XXX - this is a tiny bit broken, when we consider BSD
-+ * process accounting. If the device is opened by root, we
-+ * instantly flag that we used superuser privs. Who knows,
-+ * we might close the device immediately without doing a
-+ * privileged operation -- cevans
-+ */
-+ as->suser = capable(CAP_SYS_ADMIN);
-+ as->next = user_list;
-+ user_list = as;
-+ filp->private_data = as;
-+ return 0;
-+}
-+
-+static int apm_get_info(char *buf, char **start, off_t fpos, int length)
-+{
-+ char * p;
-+ unsigned short dx;
-+ unsigned short error;
-+ unsigned char ac_line_status = 0xff;
-+ unsigned char battery_status = 0xff;
-+ unsigned char battery_flag = 0xff;
-+ unsigned char percentage = 0xff;
-+ int time_units = -1;
-+ char *units = "?";
-+
-+ p = buf;
-+
-+ if ((smp_num_cpus == 1) &&
-+ !(error = apm_get_power_status(&ac_line_status,
-+ &battery_status, &battery_flag, &percentage, &dx))) {
-+ if (apm_bios_info.version > 0x100) {
-+ if (dx != 0xffff) {
-+ units = (dx & 0x8000) ? "min" : "sec";
-+ time_units = dx & 0x7fff;
-+ }
-+ }
-+ }
-+ /* Arguments, with symbols from linux/apm_bios.h. Information is
-+ from the Get Power Status (0x0a) call unless otherwise noted.
-+
-+ 0) Linux driver version (this will change if format changes)
-+ 1) APM BIOS Version. Usually 1.0, 1.1 or 1.2.
-+ 2) APM flags from APM Installation Check (0x00):
-+ bit 0: APM_16_BIT_SUPPORT
-+ bit 1: APM_32_BIT_SUPPORT
-+ bit 2: APM_IDLE_SLOWS_CLOCK
-+ bit 3: APM_BIOS_DISABLED
-+ bit 4: APM_BIOS_DISENGAGED
-+ 3) AC line status
-+ 0x00: Off-line
-+ 0x01: On-line
-+ 0x02: On backup power (BIOS >= 1.1 only)
-+ 0xff: Unknown
-+ 4) Battery status
-+ 0x00: High
-+ 0x01: Low
-+ 0x02: Critical
-+ 0x03: Charging
-+ 0x04: Selected battery not present (BIOS >= 1.2 only)
-+ 0xff: Unknown
-+ 5) Battery flag
-+ bit 0: High
-+ bit 1: Low
-+ bit 2: Critical
-+ bit 3: Charging
-+ bit 7: No system battery
-+ 0xff: Unknown
-+ 6) Remaining battery life (percentage of charge):
-+ 0-100: valid
-+ -1: Unknown
-+ 7) Remaining battery life (time units):
-+ Number of remaining minutes or seconds
-+ -1: Unknown
-+ 8) min = minutes; sec = seconds */
-+
-+ p += sprintf(p, "%s %d.%d 0x%02x 0x%02x 0x%02x 0x%02x %d%% %d %s\n",
-+ driver_version,
-+ (apm_bios_info.version >> 8) & 0xff,
-+ apm_bios_info.version & 0xff,
-+ apm_bios_info.flags,
-+ ac_line_status,
-+ battery_status,
-+ battery_flag,
-+ percentage,
-+ time_units,
-+ units);
-+
-+ return p - buf;
-+}
-+
-+#ifndef MODULE
-+static int __init apm_setup(char *str)
-+{
-+ int invert;
-+
-+ while ((str != NULL) && (*str != '\0')) {
-+ if (strncmp(str, "off", 3) == 0)
-+ apm_disabled = 1;
-+ if (strncmp(str, "on", 2) == 0)
-+ apm_disabled = 0;
-+ invert = (strncmp(str, "no-", 3) == 0);
-+ if (invert)
-+ str += 3;
-+ if (strncmp(str, "debug", 5) == 0)
-+ debug = !invert;
-+ if ((strncmp(str, "power-off", 9) == 0) ||
-+ (strncmp(str, "power_off", 9) == 0))
-+ power_off = !invert;
-+ str = strchr(str, ',');
-+ if (str != NULL)
-+ str += strspn(str, ", \t");
-+ }
-+ return 1;
-+}
-+
-+__setup("apm=", apm_setup);
-+#endif
-+
-+static struct file_operations apm_bios_fops = {
-+ owner: THIS_MODULE,
-+ read: do_read,
-+ poll: do_poll,
-+ ioctl: do_ioctl,
-+ open: do_open,
-+ release: do_release,
-+};
-+
-+static struct miscdevice apm_device = {
-+ APM_MINOR_DEV,
-+ "apm_bios",
-+ &apm_bios_fops
-+};
-+
-+#define APM_INIT_ERROR_RETURN return -1
-+
-+/*
-+ * Just start the APM thread. We do NOT want to do APM BIOS
-+ * calls from anything but the APM thread, if for no other reason
-+ * than the fact that we don't trust the APM BIOS. This way,
-+ * most common APM BIOS problems that lead to protection errors
-+ * etc will have at least some level of being contained...
-+ *
-+ * In short, if something bad happens, at least we have a choice
-+ * of just killing the apm thread..
-+ */
-+static int __init apm_init(void)
-+{
-+ if (apm_bios_info.version == 0) {
-+ printk(KERN_INFO "apm: BIOS not found.\n");
-+ APM_INIT_ERROR_RETURN;
-+ }
-+ printk(KERN_INFO
-+ "apm: BIOS version %d.%d Flags 0x%02x (Driver version %s)\n",
-+ ((apm_bios_info.version >> 8) & 0xff),
-+ (apm_bios_info.version & 0xff),
-+ apm_bios_info.flags,
-+ driver_version);
-+
-+ if (apm_disabled) {
-+ printk(KERN_NOTICE "apm: disabled on user request.\n");
-+ APM_INIT_ERROR_RETURN;
-+ }
-+
-+ if (PM_IS_ACTIVE()) {
-+ printk(KERN_NOTICE "apm: overridden by ACPI.\n");
-+ APM_INIT_ERROR_RETURN;
-+ }
-+ pm_active = 1;
-+
-+ create_proc_info_entry("apm", 0, NULL, apm_get_info);
-+
-+ misc_register(&apm_device);
-+
-+ return 0;
-+}
-+
-+static void __exit apm_exit(void)
-+{
-+ misc_deregister(&apm_device);
-+ remove_proc_entry("apm", NULL);
-+ if (power_off)
-+ pm_power_off = NULL;
-+ exit_kapmd = 1;
-+ while (kapmd_running)
-+ schedule();
-+ pm_active = 0;
-+}
-+
-+module_init(apm_init);
-+module_exit(apm_exit);
-+
-+MODULE_AUTHOR("Jamey Hicks, pulling bits from original by Stephen Rothwell");
-+MODULE_DESCRIPTION("A minimal emulation of APM");
-+MODULE_PARM(debug, "i");
-+MODULE_PARM_DESC(debug, "Enable debug mode");
-+MODULE_PARM(power_off, "i");
-+MODULE_PARM_DESC(power_off, "Enable power off");
-+
-+EXPORT_NO_SYMBOLS;
---- linux-2.4.25/arch/arm/mach-sa1100/leds.c~2.4.25-vrs2-pxa1-jpm1.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/leds.c 2004-05-02 22:45:42.000000000 +0200
-@@ -45,6 +45,8 @@
- leds_event = pfs168_leds_event;
- if (machine_is_pt_system3())
- leds_event = system3_leds_event;
-+ if (machine_is_simpad())
-+ leds_event = simpad_leds_event;
-
- leds_event(led_start);
- return 0;
---- linux-2.4.25/arch/arm/mach-sa1100/leds.h~2.4.25-vrs2-pxa1-jpm1.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/leds.h 2004-05-02 22:45:42.000000000 +0200
-@@ -12,4 +12,6 @@
- extern void hackkit_leds_event(led_event_t evt);
- extern void lart_leds_event(led_event_t evt);
- extern void pfs168_leds_event(led_event_t evt);
-+extern void simpad_leds_event(led_event_t evt);
- extern void system3_leds_event(led_event_t evt);
-+
---- linux-2.4.25/arch/arm/mach-sa1100/pm.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:37.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/pm.c 2004-05-02 22:45:42.000000000 +0200
-@@ -63,6 +63,7 @@
- SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR,
-
- SLEEP_SAVE_ICMR,
-+ SLEEP_SAVE_MECR,
- SLEEP_SAVE_Ser1SDCR0,
-
- SLEEP_SAVE_SIZE
-@@ -109,6 +110,8 @@
-
- SAVE(ICMR);
-
-+ SAVE(MECR);
-+
- /* ... maybe a global variable initialized by arch code to set this? */
- GRER = PWER;
- GFER = 0;
-@@ -163,6 +166,8 @@
- ICCR = 1;
- RESTORE(ICMR);
-
-+ RESTORE(MECR);
-+
- /* restore current time */
- xtime.tv_sec = RCNR + delta;
-
---- linux-2.4.25/arch/arm/mach-sa1100/simpad.c~2.4.25-vrs2-pxa1-jpm1.patch 2003-06-13 16:51:29.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/simpad.c 2004-05-02 22:48:26.000000000 +0200
-@@ -10,6 +10,7 @@
- #include <linux/tty.h>
- #include <linux/proc_fs.h>
- #include <linux/string.h>
-+#include <linux/pm.h>
-
- #include <asm/hardware.h>
- #include <asm/setup.h>
-@@ -28,6 +29,11 @@
- return cs3_shadow;
- }
-
-+void set_cs3(long value)
-+{
-+ *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow = value;
-+}
-+
- void set_cs3_bit(int value)
- {
- cs3_shadow |= value;
-@@ -40,31 +46,62 @@
- *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
- }
-
-+EXPORT_SYMBOL(set_cs3_bit);
-+EXPORT_SYMBOL(clear_cs3_bit);
-+
-+static void simpad_power_off(void)
-+{
-+ cli();
-+ set_cs3(0x800); /* only SD_MEDIAQ */
-+
-+ /* disable internal oscillator, float CS lines */
-+ PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
-+ /* enable wake-up on GPIO0 (Assabet...) */
-+ PWER = GFER = GRER = 1;
-+ /*
-+ * set scratchpad to zero, just in case it is used as a
-+ * restart address by the bootloader.
-+ */
-+ PSPR = 0;
-+ PGSR = 0;
-+ /* enter sleep mode */
-+ PMCR = PMCR_SF;
-+ while(1);
-+}
-+
-+static int __init simpad_init(void)
-+{
-+ pm_power_off = simpad_power_off;
-+ return 0;
-+}
-+
-+__initcall(simpad_init);
-+
- static void __init
- fixup_simpad(struct machine_desc *desc, struct param_struct *params,
- char **cmdline, struct meminfo *mi)
- {
--#ifdef CONFIG_SA1100_SIMPAD_DRAM_64MB /* DRAM */
-- SET_BANK( 0, 0xc0000000, 64*1024*1024 );
--#else
-+#ifdef CONFIG_SA1100_SIMPAD_SINUSPAD
- SET_BANK( 0, 0xc0000000, 32*1024*1024 );
-+#else
-+ SET_BANK( 0, 0xc0000000, 64*1024*1024 );
- #endif
- mi->nr_banks = 1;
-- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
-+
- setup_ramdisk( 1, 0, 0, 8192 );
- setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
- }
-
--
- static struct map_desc simpad_io_desc[] __initdata = {
-- /* virtual physical length domain r w c b */
-- { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 },
-- { 0xf2800000, 0x4b800000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* MQ200 */
-- { 0xf1000000, 0x18000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* Paules CS3, write only */
-+ /* virtual physical length domain r w c b */
-+ { 0xe8000000, 0x00000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 },
-+ { 0xe9000000, 0x08000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 },
-+ { 0xf1000000, 0x18000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* CS3, write only */
-+ { 0xf2000000, 0x40000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* CS4, tda8007 */
-+ { 0xf2800000, 0x4b800000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* MQ200 */
- LAST_DESC
- };
-
--
- static void simpad_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
- {
- if (port->mapbase == (u_int)&Ser1UTCR0) {
-@@ -81,20 +118,32 @@
-
- static void __init simpad_map_io(void)
- {
-- sa1100_map_io();
-- iotable_init(simpad_io_desc);
-+ sa1100_map_io();
-+ iotable_init(simpad_io_desc);
-
-- PSPR = 0xc0008000;
-- GPDR &= ~GPIO_GPIO0;
-- cs3_shadow = (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON |
-- ENABLE_5V | RESET_SIMCARD);
-- *(CS3BUSTYPE *)(CS3_BASE) = cs3_shadow;
-+ set_cs3_bit (EN1 | EN0 | LED2_ON | DISPLAY_ON | RS232_ON |
-+ ENABLE_5V | nRESET_SIMCARD);
-
-- //It is only possible to register 3 UART in serial_sa1100.c
-- sa1100_register_uart(0, 3);
-- sa1100_register_uart(1, 1);
-+ //It is only possible to register 3 UART in serial_sa1100.c
-+ sa1100_register_uart(0, 3);
-+ sa1100_register_uart(1, 1);
-
-- set_GPIO_IRQ_edge(GPIO_UCB1300_IRQ, GPIO_RISING_EDGE);
-+ GAFR |= (GPIO_UART_TXD | GPIO_UART_RXD);
-+ GPDR |= GPIO_UART_TXD;
-+ GPDR &= ~GPIO_UART_RXD;
-+ PPAR |= PPAR_UPR;
-+
-+ set_GPIO_IRQ_edge(GPIO_UCB1300_IRQ, GPIO_RISING_EDGE);
-+ set_GPIO_IRQ_edge(GPIO_POWER_BUTTON, GPIO_FALLING_EDGE);
-+
-+ /*
-+ * Set up registers for sleep mode.
-+ */
-+
-+ PWER = PWER_GPIO0;
-+ PGSR = 0x818;
-+ PCFR = 0;
-+ PSDR = 0;
- }
-
- #ifdef CONFIG_PROC_FS
-@@ -140,7 +189,17 @@
-
- return len;
- }
--
-+
-+static int proc_cs3_write(struct file * file, const char * buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ unsigned long newRegValue;
-+ char *endp;
-+
-+ newRegValue = simple_strtoul(buffer,&endp,0);
-+ set_cs3( newRegValue );
-+ return (count+endp-buffer);
-+}
-
- static struct proc_dir_entry *proc_cs3;
-
-@@ -148,7 +207,10 @@
- {
- proc_cs3 = create_proc_entry("cs3", 0, 0);
- if (proc_cs3)
-+ {
- proc_cs3->read_proc = proc_cs3_read;
-+ proc_cs3->write_proc = (void*)proc_cs3_write;
-+ }
- return 0;
- }
-
-@@ -165,6 +227,7 @@
- MACHINE_START(SIMPAD, "Simpad")
- MAINTAINER("Juergen Messerer")
- BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
-+ BOOT_PARAMS(0xc0000100)
- FIXUP(fixup_simpad)
- MAPIO(simpad_map_io)
- INITIRQ(sa1100_init_irq)
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/simpad_pm.c 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,147 @@
-+/*
-+* Powermanagement layer for SIMPad.
-+*
-+* Copyright 2003 Peter Pregler
-+* Copyright 2000,2001 Compaq Computer Corporation.
-+*
-+* Use consistent with the GNU GPL is permitted,
-+* provided that this copyright notice is
-+* preserved in its entirety in all copies and derived works.
-+*
-+* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
-+* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
-+* FITNESS FOR ANY PARTICULAR PURPOSE.
-+*
-+* Author: Peter Pregler (based on work for ipaq by Andrew Christian)
-+* May, 2003
-+*/
-+
-+#include <linux/module.h>
-+#include <linux/version.h>
-+
-+#include <linux/init.h>
-+#include <linux/fs.h>
-+#include <linux/delay.h>
-+#include <linux/poll.h>
-+#include <asm/uaccess.h> /* get_user,copy_to_user */
-+#include <linux/string.h>
-+#include <linux/interrupt.h>
-+#include <linux/sysctl.h>
-+#include <linux/console.h>
-+#include <linux/devfs_fs_kernel.h>
-+
-+#include <linux/tqueue.h>
-+#include <linux/sched.h>
-+#include <linux/pm.h>
-+#include <linux/proc_fs.h>
-+#include <linux/apm_bios.h>
-+#include <linux/kmod.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/arch-sa1100/simpad_pm.h>
-+
-+MODULE_AUTHOR("Peter Pregler");
-+MODULE_DESCRIPTION("Power manamgement abstraction layer for the SIMpad");
-+
-+/****************************************************************************/
-+/* Functions exported for use by the kernel and kernel modules */
-+/****************************************************************************/
-+
-+int simpad_apm_get_power_status(u_char *ac_line_status,
-+ u_char *battery_status,
-+ u_char *battery_flag,
-+ u_char *battery_percentage,
-+ u_short *battery_life)
-+{
-+ struct simpad_battery bstat;
-+ unsigned char ac = APM_AC_UNKNOWN;
-+ unsigned char level = APM_BATTERY_STATUS_UNKNOWN;
-+ int status, result;
-+
-+ result = simpad_get_battery(&bstat);
-+ if (result) {
-+ printk("%s: unable to access battery information: result=%d\n", __FUNCTION__, result);
-+ return 0;
-+ }
-+
-+ switch (bstat.ac_status) {
-+ case SIMPAD_AC_STATUS_AC_OFFLINE:
-+ ac = APM_AC_OFFLINE;
-+ break;
-+ case SIMPAD_AC_STATUS_AC_ONLINE:
-+ ac = APM_AC_ONLINE;
-+ break;
-+ case SIMPAD_AC_STATUS_AC_BACKUP:
-+ ac = APM_AC_BACKUP;
-+ break;
-+ }
-+
-+ if (ac_line_status != NULL)
-+ *ac_line_status = ac;
-+
-+ status = bstat.status;
-+ if (status & (SIMPAD_BATT_STATUS_CHARGING | SIMPAD_BATT_STATUS_CHARGE_MAIN))
-+ level = APM_BATTERY_STATUS_CHARGING;
-+ else if (status & (SIMPAD_BATT_STATUS_HIGH | SIMPAD_BATT_STATUS_FULL))
-+ level = APM_BATTERY_STATUS_HIGH;
-+ else if (status & SIMPAD_BATT_STATUS_LOW)
-+ level = APM_BATTERY_STATUS_LOW;
-+ else if (status & SIMPAD_BATT_STATUS_CRITICAL)
-+ level = APM_BATTERY_STATUS_CRITICAL;
-+
-+ if (battery_status != NULL)
-+ *battery_status = level;
-+
-+ if (battery_percentage != NULL)
-+ *battery_percentage = bstat.percentage;
-+
-+ /* we have a dumb battery - so we know nothing */
-+ if (battery_life != NULL) {
-+ *battery_life = APM_BATTERY_LIFE_UNKNOWN;
-+ }
-+
-+#if 0
-+ printk("apm_get_power: ac: %02x / bs: %02x / bf: %02x / perc: %02x / life: %d\n",
-+ *ac_line_status, *battery_status, *battery_flag,
-+ *battery_percentage, *battery_life );
-+#endif
-+ return 1;
-+}
-+
-+EXPORT_SYMBOL(simpad_apm_get_power_status);
-+
-+
-+/***********************************************************************************/
-+/* Initialization */
-+/***********************************************************************************/
-+
-+#ifdef CONFIG_FB_MQ200
-+extern void (*mq200_blank_helper)(int blank);
-+#endif
-+
-+int __init simpad_hal_init_module(void)
-+{
-+ int i;
-+ printk(KERN_INFO "SIMpad Registering HAL abstraction layer\n");
-+
-+ /* Request the appropriate underlying module to provide services */
-+
-+#ifdef CONFIG_FB_SA1100
-+ sa1100fb_blank_helper = simpad_hal_backlight_helper;
-+#endif
-+
-+ return 0;
-+}
-+
-+void simpad_hal_cleanup_module(void)
-+{
-+ int i;
-+ printk(KERN_INFO "SIMpad shutting down HAL abstraction layer\n");
-+
-+#ifdef CONFIG_FB_SA1100
-+ sa1100fb_blank_helper = NULL;
-+#endif
-+}
-+
-+module_init(simpad_hal_init_module);
-+module_exit(simpad_hal_cleanup_module);
---- linux-2.4.25/drivers/char/Config.in~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200
-+++ linux-2.4.25/drivers/char/Config.in 2004-05-02 22:45:42.000000000 +0200
-@@ -425,4 +425,7 @@
- tristate ' MT6N TTL I/O suport' CONFIG_TRIZEPS2_TTLIO
- fi
-
-+if [ "$CONFIG_SA1100_SIMPAD" = "y" ]; then
-+ tristate 'Smartcardreader(TDA8007) support' CONFIG_TDA8007
-+fi
- endmenu
---- linux-2.4.25/drivers/char/Makefile~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200
-+++ linux-2.4.25/drivers/char/Makefile 2004-05-02 22:45:42.000000000 +0200
-@@ -376,6 +376,8 @@
- obj-y += ipmi/ipmi.o
- endif
-
-+obj-$(CONFIG_TDA8007) += tda8007.o
-+
- include $(TOPDIR)/Rules.make
-
- fastdep:
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/tda8007.c 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,514 @@
-+/*
-+ * linux/drivers/char/tda8007.c
-+ *
-+ * Copyright (C) 2001 juergen.messerer@freesurf.ch, 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.
-+ *
-+ * The TDA8007B driver provides basic services for handling IO,
-+ * interrupts, and accessing registers.
-+ */
-+
-+#include <linux/delay.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/interrupt.h>
-+#include <linux/proc_fs.h>
-+
-+#include <asm/dma.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/arch/simpad.h>
-+#include <asm/uaccess.h>
-+
-+#include "tda8007b.h"
-+
-+#define TDA8007_DIRNAME "driver/tda8007"
-+#define REG_DIRNAME "registers"
-+
-+extern void clear_cs3_bit(int value);
-+
-+static struct proc_dir_entry *regdir;
-+static struct proc_dir_entry *tda8007dir;
-+
-+static ssize_t proc_tda8007_read(struct file * file, char * buf,
-+ size_t nbytes, loff_t *ppos);
-+static ssize_t proc_tda8007_write(struct file * file, const char * buffer,
-+ size_t count, loff_t *ppos);
-+
-+static struct file_operations proc_reg_operations = {
-+ read: proc_tda8007_read,
-+ write: proc_tda8007_write
-+};
-+
-+static int __init tda8007_init();
-+
-+/* ------------------------------------------------------------------------- */
-+void tda8007_reg_write(int reg, int val)
-+{
-+ printk("Address:%x \n", CS4_BASE+reg);
-+ printk("Value:%x \n", val);
-+ TDA_REG_WRITE(reg,val);
-+}
-+/* ------------------------------------------------------------------------- */
-+int tda8007_reg_read(int reg)
-+{
-+ printk("Address:%x \n", CS4_BASE+reg);
-+ return(TDA_REG_READ(reg)&0xff);
-+}
-+/* ------------------------------------------------------------------------- */
-+int tdaregs[16];
-+/* ------------------------------------------------------------------------- */
-+static void tda8007_irq(int irqnr, void *devid, struct pt_regs *regs)
-+{
-+ printk("\n****tda8007_irq****\n");
-+}
-+/* ------------------------------------------------------------------------- */
-+static int tda_card_present( uint cardport )
-+{
-+ int val=0;
-+
-+ switch( cardport )
-+ {
-+ case CARD_PORT1:
-+ if( tda8007_reg_read(TDA_MSR) & TDA_MSR_PR1 )
-+ val = 1;
-+ break;
-+ case CARD_PORT2:
-+ if( tda8007_reg_read(TDA_MSR) & TDA_MSR_PR2 )
-+ val = 1;
-+ break;
-+ default:
-+ val =0;
-+ break;
-+ }
-+
-+ return val;
-+}
-+/* ------------------------------------------------------------------------- */
-+void tda_inituart(void)
-+{
-+ int hsr_reg, fcr_reg;
-+
-+ printk("Init TDA8007 Uart\n");
-+ hsr_reg = tda8007_reg_read(TDA_HSR);
-+ tda8007_reg_write(TDA_PCR, 0x00);
-+
-+ tda8007_reg_write(TDA_CSR, 0x00);
-+ tda8007_reg_write(TDA_CSR, TDA_CSR_SC1); /* select Card 1 */
-+
-+ tda8007_reg_write(TDA_CSR, TDA_CSR_nRIU|TDA_CSR_SC1);
-+ tda8007_reg_write(TDA_PCR, 0x00);
-+
-+ tda8007_reg_write(TDA_PDR, TDA_PDR_VAL); /* Rat v. jandu 8.9.2000 */
-+ tda8007_reg_write(TDA_UCR2, TDA_UCR2_DIV);
-+
-+ tda8007_reg_write(TDA_CCR, 0x40|TDA_CCR_AC1); /*1=XTAL/2 2=XTAL/4 3=XTAL/8 */
-+ tda8007_reg_write(TDA_GTR, TDA_GTR_GT1);
-+
-+ fcr_reg = tda8007_reg_read(TDA_FCR);
-+ tda8007_reg_write(TDA_FCR, (fcr_reg & 0xf0) | TDA_FCR_FL1);
-+
-+ tda8007_reg_write(TDA_FCR, TDA_FCR_FL2|TDA_FCR_FL1|TDA_FCR_FL0);
-+ tda8007_reg_write(TDA_UCR1, TDA_UCR_SS|TDA_UCR_CONV);
-+ tda8007_reg_write(TDA_PCR, 0x00);
-+
-+ while( tda8007_reg_read(TDA_USR) & TDA_USR_TBE_RBF )
-+ {
-+ hsr_reg = tda8007_reg_read(TDA_URR);
-+ udelay(5);
-+ }
-+}
-+/* ------------------------------------------------------------------------- */
-+void start_tda8007_sync(int volt)
-+{
-+ int i=0,j=0;
-+ if( tda_card_present( CARD_PORT1 ) )
-+ {
-+ printk("Card Present ");
-+ tda8007_reg_write(TDA_TOR1, TDA_TOR1_TOL2|TDA_TOR1_TOL3);
-+ tda8007_reg_write(TDA_TOR2, TDA_TOR2_TOL16|TDA_TOR2_TOL15|
-+ TDA_TOR2_TOL13|TDA_TOR2_TOL12|
-+ TDA_TOR2_TOL11);
-+ tda8007_reg_write(TDA_TOR3, 0x00);
-+ tda8007_reg_write(TDA_TOC, TDA_TOC_MODE2);
-+ tda_inituart();
-+ tda8007_reg_write(TDA_UCR2, TDA_UCR_DISAUX|TDA_UCR2_DIV); // DIS_AUX ASYNC MODE
-+
-+ if( volt == 3 )
-+ volt = TDA_PCR_3V_5V;
-+ else
-+ volt = 0x00;
-+
-+ tda8007_reg_write(TDA_PCR, 0x00|volt); // Set /Reset,3V
-+ udelay(1000);
-+ tda8007_reg_write(TDA_PCR, TDA_PCR_START|volt); // /Reset,3V,Start
-+ udelay(2000);
-+ tda8007_reg_write(TDA_PCR, TDA_PCR_RSTIN|TDA_PCR_START|volt); // Set Reset High
-+ i=0;
-+ while( 1 )// !serstat()
-+ {
-+ if( ((msr[i]=tda8007_reg_read(TDA_MSR)) & TDA_MSR_FE) == 0 )
-+ {
-+ hsr[i]=tda8007_reg_read(TDA_HSR);
-+ usr[i]=tda8007_reg_read(TDA_USR);
-+ csr[i]=tda8007_reg_read(TDA_CSR);
-+ urr[i]=tda8007_reg_read(TDA_URR);
-+ i++;
-+ }
-+ if( i == 1 )
-+ {
-+ /* Reset SS */
-+ tda8007_reg_write(TDA_UCR1,
-+ tda8007_reg_read(TDA_UCR1) & ~TDA_UCR_SS);
-+ /* Set Autoconv high */
-+ tda8007_reg_write(TDA_UCR2,
-+ tda8007_reg_read(TDA_UCR2) | TDA_UCR_nAUTOCONV);
-+ }
-+
-+ if( i >= BUFFSIZE )
-+ {
-+ printk("Buffer Overflow");
-+ break;
-+ }
-+ // tda8007_reg_write(TDA_FCR, TDA_FCR_PEC0|TDA_FCR_FL0);
-+ }
-+ hsr[i]=tda8007_reg_read(TDA_HSR);
-+ msr[i]=tda8007_reg_read(TDA_MSR);
-+ csr[i]=tda8007_reg_read(TDA_CSR);
-+ urr[i]=tda8007_reg_read(TDA_URR);
-+ i++;
-+ //serin();
-+ if( i==1 )
-+ printk("No Characters received\n");
-+ else
-+ for(j=0;j<i-1; j++)
-+ printk("Buffer[%3d]=USR(0x%02x) HSR(0x%02x) MSR(0x%02x) CSR(0x%02x) URR(0x%02x=%c)\n",
-+ j,usr[j],hsr[j],msr[j],csr[j],urr[j],pascii(urr[j]));
-+
-+ printk("Now USR(0x%02x) HSR(0x%02x) MSR(0x%02x) CSR(0x%02x) URR(0x%02x=%c)\n",
-+ usr[j],hsr[j],msr[j],csr[j],urr[j],pascii(urr[j]));
-+
-+ tda8007_reg_write(TDA_PCR, TDA_PCR_RSTIN|volt); // remove start
-+ udelay(2000);
-+ tda8007_reg_write(TDA_PCR, 0x00|volt); // remove Reset
-+
-+ }
-+ else
-+ {
-+ tda8007_reg_write(TDA_PCR, TDA_PCR_3V_5V);
-+ }
-+
-+}
-+/* -------------------------------------------------------------------------*/
-+int test_tda8007(void)
-+{
-+ int c, i,j, reg,end=0;
-+
-+ printk("\nTDA8007 TEST:");
-+
-+ for( i=0; i < 0x10; i++ )
-+ printk("\nTDA8007 Reg %2d = 0x%02x ", i, tda8007_reg_read(i)&0xff);
-+
-+ for( i=0 ;i < 0x10; i++ )
-+ {
-+ tdaregs[i]=tda8007_reg_read(i) & 0xff;
-+ }
-+ do
-+ {
-+ printk("\nTDA8007 IRQ=%s Command:",
-+ (GPLR&(1<<10) ? "HIGH":"LOW"));
-+
-+ //c=serin();
-+ //serout(c);
-+ printk("\n");
-+
-+ switch (c )
-+ {
-+
-+ case 'c':
-+ printk("\nReg?:");
-+ //reg=gethex(serin,serout);
-+ printk("\nVal?:");
-+ //i=gethex(serin,serout);
-+ tda8007_reg_write(reg,i);
-+ j=tda8007_reg_read(reg);
-+ printk("Reg 0x%02x (0x%02x) now 0x%02x\n", reg, i, j);
-+ break;
-+
-+ case 'i':
-+ printk("\nInit\n");
-+ tda8007_init();
-+
-+ case 'p':
-+ for( i=0; i < 0x10; i++ )
-+ printk("\nTDA8007 Reg %2d = 0x%02x ", i,
-+ tda8007_reg_read(i)&0xff);
-+ break;
-+ case 'e':
-+ end=1;
-+ break;
-+
-+ case 'r':
-+ while( 1 ) // serstat() == 0
-+ {
-+ for( i=0 ;i < 0x10; i++ )
-+ {
-+ tdaregs[i]=tda8007_reg_read(i) & 0xff;
-+ }
-+ }
-+ //serin();
-+ break;
-+
-+ case 'S':
-+ start_tda8007_sync(5);
-+ break;
-+ case 's':
-+ start_tda8007_sync(3);
-+ break;
-+ case 'w':
-+ while( 1 )//serstat() == 0
-+ {
-+ for( i=0 ;i < 0x10; i++ )
-+ {
-+ tda8007_reg_write(i,0x10-i);
-+ }
-+ }
-+ //serin();
-+ break;
-+
-+ default :
-+ //serout(0x07);
-+ break;
-+ }
-+
-+ }while( end == 0 );
-+ return(0);
-+}
-+/*-------------------------------------------------------------------------*/
-+static int tda8007_ioctl(struct inode *ino, struct file *filp,
-+ uint cmd, ulong arg)
-+{
-+ unsigned int val, gain;
-+ int ret = 0;
-+
-+ if (_IOC_TYPE(cmd) != 'M')
-+ return -EINVAL;
-+
-+ switch (_IOC_NR(cmd))
-+ {
-+ case TDA_INFO:
-+ break;
-+
-+ case TDA_INIT:
-+ break;
-+
-+ case TDA_SET:
-+ break;
-+
-+ case TDA_CARD_PRESENT:
-+ break;
-+
-+ case TDA_CARD_VOLT:
-+ break;
-+
-+ default:
-+ val = 0;
-+ ret = -EINVAL;
-+ break;
-+ }
-+ return ret;
-+}
-+/* ------------------------------------------------------------------------- */
-+static ssize_t proc_tda8007_read( struct file *file, char *buf, size_t nbytes,
-+ loff_t *ppos)
-+{
-+ char outputbuf[80];
-+ int count = 0;
-+ int i = 0;
-+ int i_ino = (file->f_dentry->d_inode)->i_ino;
-+ tda8007_reg_entry_t* current_reg = NULL;
-+
-+ if ((*ppos) > 0) /* Assume reading completed in previous read*/
-+ return 0;
-+
-+ for (i=0; i<NUM_OF_TDA8007_REG_ENTRY; i++)
-+ {
-+ if (tda8007_regs[i].low_ino==i_ino)
-+ {
-+ if( tda8007_regs[i].mode == 2 ) /* write only */
-+ {
-+ printk("%s\n", tda8007_regs[i].description);
-+ printk("Read operation is on this register not possible!\n");
-+ return -EINVAL;
-+ }
-+ current_reg = &tda8007_regs[i];
-+
-+ break;
-+ }
-+ }
-+
-+ if (current_reg==NULL)
-+ return -EINVAL;
-+
-+ printk("%s\n", current_reg->description);
-+ count += sprintf(outputbuf, "%s: 0x%x\n", current_reg->name,
-+ tda8007_reg_read( current_reg->addr ));
-+ /* count = sprintf(outputbuf, "value: 0x%x\n",
-+ tda8007_reg_read( current_reg->addr ));*/
-+
-+ *ppos+=count;
-+
-+ if (count>nbytes) /* Assume output can be read at one time */
-+ return -EINVAL;
-+
-+ if (copy_to_user(buf, outputbuf, count))
-+ return -EFAULT;
-+
-+ return count;
-+}
-+/* ------------------------------------------------------------------------- */
-+static ssize_t proc_tda8007_write(struct file * file, const char * buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ int i;
-+ unsigned long newRegValue;
-+ char *endp;
-+ int i_ino = (file->f_dentry->d_inode)->i_ino;
-+ tda8007_reg_entry_t* current_reg=NULL;
-+
-+ for (i=0; i<NUM_OF_TDA8007_REG_ENTRY; i++)
-+ {
-+ if (tda8007_regs[i].low_ino==i_ino)
-+ {
-+ if( tda8007_regs[i].mode == 1 ) /* read only */
-+ {
-+ printk("%s\n", tda8007_regs[i].description);
-+ printk("Write operation is on this register not possible!\n");
-+ return -EINVAL;
-+ }
-+ current_reg = &tda8007_regs[i];
-+ break;
-+ }
-+ }
-+ if (current_reg==NULL)
-+ return -EINVAL;
-+
-+ newRegValue = simple_strtoul(buffer,&endp,0);
-+ tda8007_reg_write( current_reg->addr, newRegValue);
-+ return (count+endp-buffer);
-+}
-+/* ------------------------------------------------------------------------- */
-+static int __init tda8007_init()
-+{
-+ int i, hsr_reg, res;
-+ int ret = -ENODEV;
-+ struct proc_dir_entry *entry;
-+ int tda8007_major = 60;
-+
-+ res = register_chrdev( tda8007_major, "tda8007", NULL );
-+
-+ if(res < 0){
-+ printk(KERN_WARNING "tda8007: can't get major%d\n", tda8007_major);
-+ return res;
-+ }
-+
-+ if( tda8007_major == 0 )
-+ tda8007_major = res;
-+
-+ set_GPIO_IRQ_edge(GPIO_SMART_CARD, GPIO_RISING_EDGE);
-+
-+ ret = request_irq( IRQ_GPIO_SMART_CARD, tda8007_irq,
-+ SA_INTERRUPT, "SMARTCARD_CD", NULL );
-+ if (ret) {
-+ printk(KERN_ERR "tda8007: unable to grab irq%d: %d\n",
-+ IRQ_GPIO_SMART_CARD, ret);
-+ return ret;
-+ }
-+
-+ printk("\nInit TDA8007 IRQ=%s\n",
-+ (GPLR&(1<<10) ? "HIGH":"LOW"));
-+
-+// clear_cs3_bit(RESET_SIMCARD);
-+
-+
-+#ifdef CONFIG_PROC_FS
-+ /* Create two dir entries for the TDA8007 */
-+ tda8007dir = proc_mkdir("tda8007"/*TDA8007_DIRNAME*/, NULL);
-+ if (tda8007dir == NULL) {
-+ printk(KERN_ERR "tda80007: can't create /proc/" TDA8007_DIRNAME "\n");
-+ return(-ENOMEM);
-+ }
-+
-+ regdir = proc_mkdir(REG_DIRNAME, tda8007dir);
-+ if (regdir == NULL) {
-+ printk(KERN_ERR "tda8007: can't create /proc/" TDA8007_DIRNAME "/" REG_DIRNAME "\n");
-+ return(-ENOMEM);
-+ }
-+
-+ for(i=0;i<NUM_OF_TDA8007_REG_ENTRY;i++) {
-+ entry = create_proc_entry(tda8007_regs[i].name,
-+ S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH,
-+ regdir);
-+ if(entry) {
-+ tda8007_regs[i].low_ino = entry->low_ino;
-+ entry->proc_fops = &proc_reg_operations;
-+ }
-+ else {
-+ printk( KERN_ERR
-+ "tda8007: can't create /proc/" REG_DIRNAME
-+ "/%s\n", tda8007_regs[i].name);
-+ return(-ENOMEM);
-+ }
-+ }
-+
-+#endif // CONFIG_PROC_FS
-+
-+
-+ tda8007_reg_write(TDA_CSR, 0);
-+ tda8007_reg_write(TDA_CSR, TDA_CSR_nRIU);
-+ for( i=0; i < 16; i++ )
-+ tda8007_reg_write(i,0);
-+
-+ tda8007_reg_write(TDA_CSR, TDA_CSR_nRIU|TDA_CSR_SC2);
-+ tda8007_reg_write(TDA_PCR, 0); /* START=0 */
-+ tda8007_reg_write(TDA_CSR, TDA_CSR_nRIU|TDA_CSR_SC1);
-+ tda8007_reg_write(TDA_PCR, 0); /* START=0 */
-+ tda8007_reg_write(TDA_TOC, 0);
-+ tda8007_reg_write(TDA_FCR, TDA_FCR_FL2|TDA_FCR_FL1|TDA_FCR_FL0);
-+
-+ tda8007_reg_write(TDA_UCR2, TDA_UCR_DISAUX|TDA_UCR2_DIV); // DIS_AUX DIS_CLK
-+ tda8007_reg_write(TDA_UCR2, TDA_UCR_DISAUX|TDA_UCR2_DIV); // DIS_AUX CLK SYNC-MODE
-+ hsr_reg = tda8007_reg_read(TDA_HSR);
-+
-+ tda8007_reg_write(TDA_CCR, TDA_CCR_AC1|TDA_CCR_AC0); /* XTAL/8 */
-+
-+ return 0;
-+}
-+/* ------------------------------------------------------------------------- */
-+static void __exit tda8007_exit(void)
-+{
-+ int i;
-+
-+ free_irq(IRQ_GPIO_SMART_CARD, NULL);
-+ /* kfree(my_ucb);*/
-+
-+ if (regdir)
-+ {
-+ for(i=0;i<NUM_OF_TDA8007_REG_ENTRY;i++) {
-+ remove_proc_entry( tda8007_regs[i].name, regdir);
-+ }
-+ }
-+}
-+/* ------------------------------------------------------------------------- */
-+module_init(tda8007_init);
-+module_exit(tda8007_exit);
-+
-+MODULE_AUTHOR("Juergen Messerer <juergen.messerer@freesurf.ch>");
-+MODULE_DESCRIPTION("TDA8007 driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/tda8007b.h 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,312 @@
-+/*
-+ * Double multiprotocol IC car interface (Philips SmartCard reader)
-+ *
-+ * linux/drivers/char/tda8007b.h
-+ *
-+ * Copyright (C) 2002 juergen.messerer@freesurf.ch, 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.
-+ */
-+#ifndef TDA8007B_H
-+#define TDA8007B_H
-+
-+#define CS4BUSTYPE unsigned volatile long
-+#define CS4_BASE 0xf2000000
-+
-+#define CARD_PORT1 1
-+#define CARD_PORT2 2
-+#define CARD_PORT3 3
-+
-+#define TDA_REG_READ(reg) *(CS4BUSTYPE *)(CS4_BASE+reg)
-+#define TDA_REG_WRITE(reg,val) *(CS4BUSTYPE *)(CS4_BASE+reg)=val
-+
-+#define TDA_MULTIPLEXED_MODE 0
-+
-+#define TDA_UCR2_DIV 0
-+#define TDA_PDR_VAL 12
-+
-+#define pascii(i) ((i>=' ' && i < 0x7f) ? (i):'.')
-+
-+#define BUFFSIZE 128
-+
-+#define TDA_READ 1
-+#define TDA_WRITE 2
-+
-+#define TDA_INFO 1
-+#define TDA_INIT 2
-+#define TDA_SET 3
-+#define TDA_CARD_PRESENT 4
-+#define TDA_CARD_VOLT 5
-+
-+int hsr[BUFFSIZE];
-+int msr[BUFFSIZE];
-+int csr[BUFFSIZE];
-+int urr[BUFFSIZE];
-+int usr[BUFFSIZE];
-+
-+/*************************** Control Register ********************************/
-+
-+/*
-+ * Card select register (read/write)
-+ * all significant bits are cleared execept SC1 which is set (xxxx'0001)
-+ */
-+#define TDA_CSR 0x00
-+#define TDA_CSR_SC1 (1 << 0)
-+#define TDA_CSR_SC2 (1 << 1)
-+#define TDA_CSR_SC3 (1 << 2)
-+#define TDA_CSR_nRIU (1 << 3)
-+
-+/*
-+ * Clock configuration register (read/write)
-+ * all bits are cleared (0000'0000)
-+ */
-+#define TDA_CCR 0x01
-+#define TDA_CCR_AC0 (1 << 0)
-+#define TDA_CCR_AC1 (1 << 1)
-+#define TDA_CCR_AC2 (1 << 2)
-+#define TDA_CCR_SC (1 << 3)
-+#define TDA_CCR_CST (1 << 4)
-+#define TDA_CCR_SHL (1 << 5)
-+
-+/*
-+ * Programmable divider register (read/write)
-+ * all bits are cleared (0000'0000)
-+ */
-+#define TDA_PDR 0x02
-+#define TDA_PDR_PD0 (1 << 0)
-+#define TDA_PDR_PD1 (1 << 1)
-+#define TDA_PDR_PD2 (1 << 2)
-+#define TDA_PDR_PD3 (1 << 3)
-+#define TDA_PDR_PD4 (1 << 4)
-+#define TDA_PDR_PD5 (1 << 5)
-+#define TDA_PDR_PD6 (1 << 6)
-+#define TDA_PDR_PD7 (1 << 7)
-+
-+/*
-+ * UART configuration register 2(read/write)
-+ * all relevant bits are cleared after reset (x000'0000)
-+ */
-+#define TDA_UCR2 0x03
-+#define TDA_UCR_PSC (1 << 0)
-+#define TDA_UCR_CKU (1 << 1)
-+#define TDA_UCR_nAUTOCONV (1 << 2)
-+#define TDA_UCR_SAN (1 << 3)
-+#define TDA_UCR_PDWN (1 << 4)
-+#define TDA_UCR_DISAUX (1 << 5)
-+#define TDA_UCR_DISTBE_RBF (1 << 6)
-+
-+/*
-+ * Guard time register (read/write)
-+ * all bits are cleared (0000'0000)
-+ */
-+#define TDA_GTR 0x05
-+#define TDA_GTR_GT0 (1 << 0)
-+#define TDA_GTR_GT1 (1 << 1)
-+#define TDA_GTR_GT2 (1 << 2)
-+#define TDA_GTR_GT3 (1 << 3)
-+#define TDA_GTR_GT4 (1 << 4)
-+#define TDA_GTR_GT5 (1 << 5)
-+#define TDA_GTR_GT6 (1 << 6)
-+#define TDA_GTR_GT7 (1 << 7)
-+
-+/*
-+ * UART configuration register 1(read/write)
-+ * all relevant bits are cleared after reset (x000'0000)
-+ */
-+#define TDA_UCR1 0x06
-+#define TDA_UCR_CONV (1 << 0)
-+#define TDA_UCR_SS (1 << 1)
-+#define TDA_UCR_LCT (1 << 2)
-+#define TDA_UCR_T_R (1 << 3)
-+#define TDA_UCR_PROT (1 << 4)
-+#define TDA_UCR_FC (1 << 5)
-+#define TDA_UCR_FIP (1 << 6)
-+
-+/*
-+ * Power control register (read/write)
-+ * all relevant bits are cleared after reset (xx11'0000)
-+ */
-+#define TDA_PCR 0x07
-+#define TDA_PCR_START (1 << 0)
-+#define TDA_PCR_3V_5V (1 << 1)
-+#define TDA_PCR_RSTIN (1 << 2)
-+#define TDA_PCR_1V8 (1 << 3)
-+#define TDA_PCR_C4 (1 << 4)
-+#define TDA_PCR_C8 (1 << 5)
-+
-+/*
-+ * Time-out configuration register (read/write)
-+ * all bits are cleared (0000'0000)
-+ */
-+#define TDA_TOC 0x08
-+#define TDA_TOC_STOP_ALL 0x00
-+#define TDA_TOC_MODE1 0x61
-+#define TDA_TOC_MODE2 0x65
-+#define TDA_TOC_MODE3 0x68
-+#define TDA_TOC_MODE4 0x7c
-+#define TDA_TOC_MODE5 0xe5
-+
-+/*
-+ * Time-out register 1(write only)
-+ * all bits are cleared (0000'0000)
-+ */
-+#define TDA_TOR1 0x09
-+#define TDA_TOR1_TOL0 (1 << 0)
-+#define TDA_TOR1_TOL1 (1 << 1)
-+#define TDA_TOR1_TOL2 (1 << 2)
-+#define TDA_TOR1_TOL3 (1 << 3)
-+#define TDA_TOR1_TOL4 (1 << 4)
-+#define TDA_TOR1_TOL5 (1 << 5)
-+#define TDA_TOR1_TOL6 (1 << 6)
-+#define TDA_TOR1_TOL7 (1 << 7)
-+
-+/*
-+ * Time-out register 2(write only)
-+ * all bits are cleared (0000'0000)
-+ */
-+#define TDA_TOR2 0x0a
-+#define TDA_TOR2_TOL10 (1 << 0)
-+#define TDA_TOR2_TOL11 (1 << 1)
-+#define TDA_TOR2_TOL12 (1 << 2)
-+#define TDA_TOR2_TOL13 (1 << 3)
-+#define TDA_TOR2_TOL14 (1 << 4)
-+#define TDA_TOR2_TOL15 (1 << 5)
-+#define TDA_TOR2_TOL16 (1 << 6)
-+#define TDA_TOR2_TOL17 (1 << 7)
-+
-+/*
-+ * Time-out register 3(write only)
-+ * all bits are cleared (0000'0000)
-+ */
-+#define TDA_TOR3 0x0b
-+#define TDA_TOR3_TOL16 (1 << 0)
-+#define TDA_TOR3_TOL17 (1 << 1)
-+#define TDA_TOR3_TOL18 (1 << 2)
-+#define TDA_TOR3_TOL19 (1 << 3)
-+#define TDA_TOR3_TOL20 (1 << 4)
-+#define TDA_TOR3_TOL21 (1 << 5)
-+#define TDA_TOR3_TOL22 (1 << 6)
-+#define TDA_TOR3_TOL23 (1 << 7)
-+
-+/*
-+ * Mixed status register (read only)
-+ * bits TBE, RBF and BGT are cleared, bit FE is set after reset (x10x'xxx0)
-+ */
-+#define TDA_MSR 0x0c
-+#define TDA_MSR_TBE_RBF (1 << 0)
-+#define TDA_MSR_INTAUX (1 << 1)
-+#define TDA_MSR_PR1 (1 << 2)
-+#define TDA_MSR_PR2 (1 << 3)
-+#define TDA_MSR_BGT (1 << 5)
-+#define TDA_MSR_FE (1 << 6)
-+
-+/*
-+ * FIFO control register (write only)
-+ * all relevant bits are cleared after reset (x000'x000)
-+ */
-+#define TDA_FCR 0x0c
-+#define TDA_FCR_FL0 (1 << 0)
-+#define TDA_FCR_FL1 (1 << 1)
-+#define TDA_FCR_FL2 (1 << 2)
-+#define TDA_FCR_PEC0 (1 << 4)
-+#define TDA_FCR_PEC1 (1 << 5)
-+#define TDA_FCR_PEC2 (1 << 6)
-+
-+/*
-+ * UART transmit register (write only)
-+ * all bits are cleared (0000'0000)
-+ */
-+#define TDA_UTR 0x0d
-+#define TDA_UTR_UT0 (1 << 0)
-+#define TDA_UTR_UT1 (1 << 1)
-+#define TDA_UTR_UT2 (1 << 2)
-+#define TDA_UTR_UT3 (1 << 3)
-+#define TDA_UTR_UT4 (1 << 4)
-+#define TDA_UTR_UT5 (1 << 5)
-+#define TDA_UTR_UT6 (1 << 6)
-+#define TDA_UTR_UT7 (1 << 7)
-+
-+/*
-+ * UART receive register (read only)
-+ * all bits are cleared (0000'0000)
-+ */
-+#define TDA_URR 0x0d
-+#define TDA_URR_UR0 (1 << 0)
-+#define TDA_URR_UR1 (1 << 1)
-+#define TDA_URR_UR2 (1 << 2)
-+#define TDA_URR_UR3 (1 << 3)
-+#define TDA_URR_UR4 (1 << 4)
-+#define TDA_URR_UR5 (1 << 5)
-+#define TDA_URR_UR6 (1 << 6)
-+#define TDA_URR_UR7 (1 << 7)
-+
-+/*
-+ * UART status register (read only)
-+ * all bits are cleared (0x00'0000)
-+ */
-+#define TDA_USR 0x0e
-+#define TDA_USR_TBE_RBF (1 << 0)
-+#define TDA_USR_FER (1 << 1)
-+#define TDA_USR_OVR (1 << 2)
-+#define TDA_USR_PE (1 << 3)
-+#define TDA_USR_EA (1 << 4)
-+#define TDA_USR_TO1 (1 << 5)
-+#define TDA_USR_TO3 (1 << 7)
-+
-+/*
-+ * Hardware status register (read only)
-+ * all significant bits are cleared, except SUPL (x001'0000)
-+ */
-+#define TDA_HSR 0x0f
-+#define TDA_HSR_PTL (1 << 0)
-+#define TDA_HSR_INTAUXL (1 << 1)
-+#define TDA_HSR_PRL1 (1 << 2)
-+#define TDA_HSR_PRL2 (1 << 3)
-+#define TDA_HSR_SUPL (1 << 4)
-+#define TDA_HSR_PRTL1 (1 << 5)
-+#define TDA_HSR_PRTL2 (1 << 6)
-+
-+typedef struct tda8007_reg_entry {
-+ u32 addr;
-+ char* name;
-+ char* description;
-+ u8 mode;
-+ unsigned short low_ino;
-+} tda8007_reg_entry_t;
-+
-+
-+/*
-+ * Read : 1
-+ * Write : 2
-+ * Read/Write : 3
-+ */
-+
-+static tda8007_reg_entry_t tda8007_regs[] =
-+{
-+ {TDA_CSR, "TDA_CSR", "Card select register (read/write)", 3},
-+ {TDA_CCR, "TDA_CCR", "Clock configuration register (read/write)", 3},
-+ {TDA_PDR, "TDA_PDR", "Programmable divider register (read/write)", 3},
-+ {TDA_UCR2, "TDA_UCR2", "UART configuration register 2(read/write)", 3},
-+ {TDA_GTR, "TDA_GTR", "Guard time register (read/write)", 3},
-+ {TDA_UCR1, "TDA_UCR1", "UART configuration register 1(read/write)", 3},
-+ {TDA_PCR, "TDA_PCR", "Power control register (read/write)", 3},
-+ {TDA_TOC, "TDA_TOC", "Time-out configuration register (read/write)", 3},
-+ {TDA_MSR, "TDA_MSR", "Mixed status register (read only)", 1},
-+ {TDA_URR, "TDA_URR", "UART receive register (read only)", 1},
-+ {TDA_USR, "TDA_USR", "UART status register (read only)", 1},
-+ {TDA_HSR, "TDA_HSR", "Hardware status register (read only)", 1},
-+ {TDA_TOR1, "TDA_TOR1", "Time-out register 1(write only)", 2},
-+ {TDA_TOR2, "TDA_TOR2", "Time-out register 2(write only)", 2},
-+ {TDA_TOR3, "TDA_TOR3", "Time-out register 3(write only)", 2},
-+ {TDA_FCR, "TDA_FCR", "FIFO control register (write only)", 2},
-+ {TDA_UTR, "TDA_UTR", "UART transmit register (write only)", 2}
-+};
-+#define NUM_OF_TDA8007_REG_ENTRY (sizeof(tda8007_regs)/sizeof(tda8007_reg_entry_t))
-+/*
-+struct tda8007 {
-+
-+};
-+*/
-+#endif /* TDA8007B_H */
---- linux-2.4.25/drivers/misc/Config.in~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200
-+++ linux-2.4.25/drivers/misc/Config.in 2004-05-02 22:45:42.000000000 +0200
-@@ -16,3 +16,15 @@
- dep_tristate ' UCB1400 Touchscreen support' CONFIG_MCP_UCB1400_TS $CONFIG_ARCH_PXA $CONFIG_SOUND
-
- endmenu
-+mainmenu_option next_comment
-+comment 'Console Switches'
-+
-+tristate 'Console Switch Support' CONFIG_SWITCHES
-+if [ "$CONFIG_SWITCHES" != "n" ]; then
-+ dep_bool ' SA-1100 switches' CONFIG_SWITCHES_SA1100 $CONFIG_ARCH_SA1100
-+ if [ "$CONFIG_MCP_UCB1200" != "n" ]; then
-+ bool ' UCB1x00 switches' CONFIG_SWITCHES_UCB1X00
-+ fi
-+fi
-+
-+endmenu
---- linux-2.4.25/drivers/misc/Makefile~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200
-+++ linux-2.4.25/drivers/misc/Makefile 2004-05-02 22:45:42.000000000 +0200
-@@ -21,6 +21,24 @@
- obj-$(CONFIG_MCP_UCB1400_TS) += mcp-pxa.o ucb1x00-core.o ucb1x00-ts.o
- obj-$(CONFIG_PXA_CERF_PDA) += cerf_ucb1400gpio.o
-
-+ifeq ($(CONFIG_SA1100_ASSABET),y)
-+obj-$(CONFIG_MCP_UCB1200) += ucb1x00-assabet.o
-+endif
-+
-+ifeq ($(CONFIG_SA1100_SIMPAD),y)
-+export-objs += ucb1x00-simpad.o
-+obj-$(CONFIG_MCP_UCB1200) += ucb1x00-simpad.o
-+endif
-+
-+obj-$(CONFIG_SWITCHES) += switches.o
-+
-+switches-objs-y += switches-core.o
-+switches-objs-$(CONFIG_SWITCHES_SA1100) += switches-sa1100.o
-+switches-objs-$(CONFIG_SWITCHES_UCB1X00) += switches-ucb1x00.o
-+
- include $(TOPDIR)/Rules.make
-
-+switches.o: $(switches-objs-y)
-+ $(LD) $(LD_RFLAG) -r -o $@ $(switches-objs-y)
-+
- fastdep:
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/misc/switches-core.c 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,226 @@
-+/*
-+ * linux/drivers/misc/switches-core.c
-+ *
-+ * Copyright (C) 2000-2001 John Dorsey
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 5 October 2000 - created.
-+ *
-+ * 25 October 2000 - userland file interface added.
-+ *
-+ * 13 January 2001 - added support for Spot.
-+ *
-+ * 11 September 2001 - UCB1200 driver framework support added.
-+ *
-+ * 19 December 2001 - separated out SA-1100 and UCB1x00 code.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/fs.h>
-+#include <linux/kernel.h>
-+#include <linux/miscdevice.h>
-+#include <linux/module.h>
-+#include <linux/mm.h>
-+#include <linux/poll.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/wait.h>
-+
-+#include <asm/uaccess.h>
-+
-+#include "switches.h"
-+
-+
-+MODULE_AUTHOR("John Dorsey");
-+MODULE_DESCRIPTION("Console switch support");
-+MODULE_LICENSE("GPL");
-+
-+
-+struct switches_action {
-+ struct list_head list;
-+ switches_mask_t mask;
-+};
-+
-+
-+static int switches_users = 0;
-+
-+static spinlock_t switches_lock = SPIN_LOCK_UNLOCKED;
-+
-+DECLARE_WAIT_QUEUE_HEAD(switches_wait);
-+LIST_HEAD(switches_event_queue);
-+
-+
-+static ssize_t switches_read(struct file *file, char *buffer,
-+ size_t count, loff_t *pos)
-+{
-+ unsigned long flags;
-+ struct list_head *event;
-+ struct switches_action *action;
-+
-+ if (count < sizeof(struct switches_mask_t))
-+ return -EINVAL;
-+
-+ while (list_empty(&switches_event_queue)) {
-+
-+ if (file->f_flags & O_NDELAY)
-+ return -EAGAIN;
-+
-+ interruptible_sleep_on(&switches_wait);
-+
-+ if (signal_pending(current))
-+ return -ERESTARTSYS;
-+
-+ }
-+
-+ if (verify_area(VERIFY_WRITE, buffer, sizeof(struct switches_mask_t)))
-+ return -EFAULT;
-+
-+ spin_lock_irqsave(&switches_lock, flags);
-+
-+ event = switches_event_queue.next;
-+ action = list_entry(event, struct switches_action, list);
-+ copy_to_user(buffer, &(action->mask), sizeof(struct switches_mask_t));
-+ list_del(event);
-+ kfree(action);
-+
-+ spin_unlock_irqrestore(&switches_lock, flags);
-+
-+ return sizeof(struct switches_mask_t);
-+
-+}
-+
-+static ssize_t switches_write(struct file *file, const char *buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ return -EINVAL;
-+}
-+
-+static unsigned int switches_poll(struct file *file, poll_table *wait)
-+{
-+
-+ poll_wait(file, &switches_wait, wait);
-+
-+ if (!list_empty(&switches_event_queue))
-+ return POLLIN | POLLRDNORM;
-+
-+ return 0;
-+
-+}
-+
-+static int switches_open(struct inode *inode, struct file *file)
-+{
-+
-+ if (switches_users > 0)
-+ return -EBUSY;
-+
-+ MOD_INC_USE_COUNT;
-+ ++switches_users;
-+ return 0;
-+
-+}
-+
-+static int switches_release(struct inode *inode, struct file *file)
-+{
-+
-+ --switches_users;
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+
-+}
-+
-+static struct file_operations switches_ops = {
-+ read: switches_read,
-+ write: switches_write,
-+ poll: switches_poll,
-+ open: switches_open,
-+ release: switches_release
-+};
-+
-+static struct miscdevice switches_misc = {
-+ MISC_DYNAMIC_MINOR, SWITCHES_NAME, &switches_ops
-+};
-+
-+int switches_event(switches_mask_t *mask)
-+{
-+ struct switches_action *action;
-+
-+ if ((switches_users > 0) && (SWITCHES_COUNT(mask) > 0)) {
-+
-+ if ((action = (struct switches_action *)
-+ kmalloc(sizeof(struct switches_action),
-+ GFP_ATOMIC)) == NULL) {
-+ printk(KERN_ERR "%s: unable to allocate action "
-+ "descriptor\n", SWITCHES_NAME);
-+ return -1;
-+ }
-+
-+ action->mask = *mask;
-+
-+ spin_lock(&switches_lock);
-+ list_add_tail(&action->list, &switches_event_queue);
-+ spin_unlock(&switches_lock);
-+
-+ wake_up_interruptible(&switches_wait);
-+
-+ }
-+
-+ return 0;
-+
-+}
-+
-+static int __init switches_init(void)
-+{
-+
-+#ifdef CONFIG_SWITCHES_SA1100
-+ if (switches_sa1100_init() < 0) {
-+ printk(KERN_ERR "%s: unable to initialize SA-1100 switches\n",
-+ SWITCHES_NAME);
-+ return -EIO;
-+ }
-+#endif
-+
-+#ifdef CONFIG_SWITCHES_UCB1X00
-+ if (switches_ucb1x00_init() < 0) {
-+ printk(KERN_ERR "%s: unable to initialize UCB1x00 switches\n",
-+ SWITCHES_NAME);
-+ return -EIO;
-+ }
-+#endif
-+
-+ if (misc_register(&switches_misc) < 0) {
-+ printk(KERN_ERR "%s: unable to register misc device\n",
-+ SWITCHES_NAME);
-+ return -EIO;
-+ }
-+
-+ printk("Console switches initialized\n");
-+
-+ return 0;
-+
-+}
-+
-+static void __exit switches_exit(void)
-+{
-+
-+#ifdef CONFIG_SWITCHES_SA1100
-+ switches_sa1100_exit();
-+#endif
-+
-+#ifdef CONFIG_SWITCHES_UCB1X00
-+ switches_ucb1x00_exit();
-+#endif
-+
-+ if (misc_deregister(&switches_misc) < 0)
-+ printk(KERN_ERR "%s: unable to deregister misc device\n",
-+ SWITCHES_NAME);
-+
-+}
-+
-+module_init(switches_init);
-+module_exit(switches_exit);
-+
-+EXPORT_NO_SYMBOLS;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/misc/switches-sa1100.c 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,311 @@
-+/*
-+ * linux/drivers/misc/switches-sa1100.c
-+ *
-+ * Copyright (C) 2001 John Dorsey
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 19 December 2001 - created from sa1100_switches.c.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+
-+#ifdef CONFIG_SA1100_ASSABET
-+#include <asm/arch/assabet.h>
-+#endif
-+
-+#ifdef CONFIG_SA1100_SIMPAD
-+#include <asm/arch/simpad.h>
-+#endif
-+
-+#include "switches.h"
-+
-+
-+static void switches_sa1100_handler(int irq, void *dev_id,
-+ struct pt_regs *regs);
-+
-+
-+#ifdef CONFIG_SA1100_ASSABET
-+
-+/* Assabet
-+ * ^^^^^^^
-+ * We have two general-purpose switches, S1 and S2, available via GPIO
-+ * on Assabet. This code sets bits in the range [1, 2] in the mask that
-+ * we return to userland.
-+ */
-+
-+static int assabet_switches_sa1100_init(void)
-+{
-+
-+ if (machine_has_neponset())
-+ NCR_0 |= NCR_GP01_OFF;
-+
-+ set_irq_type(IRQ_GPIO0, IRQT_BOTHEDGE);
-+ set_irq_type(IRQ_GPIO1, IRQT_BOTHEDGE);
-+
-+ if (request_irq(IRQ_GPIO0, switches_sa1100_handler, SA_INTERRUPT,
-+ SWITCHES_NAME, NULL) < 0) {
-+ printk(KERN_ERR "%s: unable to register IRQ for GPIO 0\n",
-+ SWITCHES_NAME);
-+ return -EIO;
-+ }
-+
-+ if (request_irq(IRQ_GPIO1, switches_sa1100_handler, SA_INTERRUPT,
-+ SWITCHES_NAME, NULL) < 0) {
-+ printk(KERN_ERR "%s: unable to register IRQ for GPIO 1\n",
-+ SWITCHES_NAME);
-+ return -EIO;
-+ }
-+
-+ return 0;
-+
-+}
-+
-+static void assabet_switches_sa1100_shutdown(void)
-+{
-+
-+ free_irq(IRQ_GPIO1, NULL);
-+ free_irq(IRQ_GPIO0, NULL);
-+
-+}
-+
-+static void assabet_switches_sa1100_handler(int irq, switches_mask_t *mask)
-+{
-+ unsigned int s, last, this;
-+ static unsigned int states = 0;
-+
-+ switch (irq) {
-+
-+ case IRQ_GPIO0: s = 0; break;
-+
-+ case IRQ_GPIO1: s = 1; break;
-+
-+ default: return;
-+
-+ }
-+
-+ last = ((states & (1 << s)) != 0);
-+ this = ((GPLR & GPIO_GPIO(s)) != 0);
-+
-+ if (last == this) /* debounce */
-+ return;
-+
-+ SWITCHES_SET(mask, s + 1, this);
-+
-+ states = this ? (states | (1 << s)) : (states & ~(1 << s));
-+
-+}
-+#endif /* CONFIG_SA1100_ASSABET */
-+
-+
-+#ifdef CONFIG_SA1100_SPOT
-+
-+/* Spot
-+ * ^^^^
-+ * Spot (R2, R3) has a single general-purpose switch (S1), which is
-+ * also the power-on switch. We set bit [1] in the mask we return to
-+ * userland.
-+ */
-+
-+static int spot_switches_sa1100_init(void)
-+{
-+
-+ set_GPIO_IRQ_edge(GPIO_SW1, GPIO_BOTH_EDGES);
-+
-+ if (request_irq(IRQ_GPIO_SW1, switches_sa1100_handler, SA_INTERRUPT,
-+ SWITCHES_NAME, NULL) < 0) {
-+ printk(KERN_ERR "%s: unable to register IRQ for SW1\n",
-+ SWITCHES_NAME);
-+ return -EIO;
-+ }
-+
-+ return 0;
-+
-+}
-+
-+static void spot_switches_sa1100_shutdown(void)
-+{
-+
-+ free_irq(IRQ_GPIO_SW1, NULL);
-+
-+}
-+
-+static void spot_switches_sa1100_handler(int irq, switches_mask_t *mask)
-+{
-+ unsigned int s, last, this;
-+ static unsigned int states = 0;
-+
-+ switch (irq) {
-+
-+ case IRQ_GPIO_SW1: s = 0; break;
-+
-+ default: return;
-+
-+ }
-+
-+ last = ((states & (1 << s)) != 0);
-+ this = ((GPLR & GPIO_GPIO(s)) != 0);
-+
-+ if (last == this) /* debounce */
-+ return;
-+
-+ SWITCHES_SET(mask, s + 1, this);
-+
-+ states = this ? (states | (1 << s)) : (states & ~(1 << s));
-+
-+}
-+#endif /* CONFIG_SA1100_SPOT */
-+
-+#ifdef CONFIG_SA1100_SIMPAD
-+
-+/* SIMpad
-+ * ^^^^
-+ * SIMpad has a single general-purpose switch (S0), which is
-+ * also the power-on switch. We set bit [1] in the mask we return to
-+ * userland.
-+ */
-+
-+static int simpad_switches_sa1100_init(void)
-+{
-+
-+ set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_BOTH_EDGES);
-+
-+ if (request_irq(IRQ_GPIO0, switches_sa1100_handler, SA_INTERRUPT,
-+ SWITCHES_NAME, NULL) < 0) {
-+ printk(KERN_ERR "%s: unable to register IRQ for SW0\n",
-+ SWITCHES_NAME);
-+ return -EIO;
-+ }
-+
-+ return 0;
-+
-+}
-+
-+static void simpad_switches_sa1100_shutdown(void)
-+{
-+
-+ free_irq(IRQ_GPIO0, NULL);
-+
-+}
-+
-+static void simpad_switches_sa1100_handler(int irq, switches_mask_t *mask)
-+{
-+ unsigned int s, last, this;
-+ static unsigned int states = 0;
-+
-+ switch (irq) {
-+
-+ case IRQ_GPIO0: s = 0; break;
-+
-+ default: return;
-+
-+ }
-+
-+ last = ((states & (1 << s)) != 0);
-+ this = ((GPLR & GPIO_GPIO(s)) != 0);
-+
-+ if (last == this) /* debounce */
-+ return;
-+
-+ SWITCHES_SET(mask, s + 1, this);
-+
-+ states = this ? (states | (1 << s)) : (states & ~(1 << s));
-+
-+}
-+#endif /* CONFIG_SA1100_SIMPAD */
-+
-+
-+
-+/* switches_sa1100_handler()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * This routine is a generalized handler for SA-1100 switches
-+ * which manages action descriptors and calls a board-specific
-+ * service routine. This routine is appropriate for GPIO switches
-+ * or other primary interrupt sources, and can be registered as a
-+ * first-class IRQ handler using request_irq().
-+ */
-+static void switches_sa1100_handler(int irq, void *dev_id,
-+ struct pt_regs *regs)
-+{
-+ switches_mask_t mask;
-+
-+ SWITCHES_ZERO(&mask);
-+
-+ /* Porting note: call a board-specific switch interrupt handler
-+ * here. The handler can assume that sufficient storage for
-+ * `mask' has been allocated, and that the corresponding
-+ * switches_mask_t structure has been zeroed.
-+ */
-+
-+ if (machine_is_assabet()) {
-+#ifdef CONFIG_SA1100_ASSABET
-+ assabet_switches_sa1100_handler(irq, &mask);
-+#endif
-+ } else if (machine_is_spot()) {
-+#ifdef CONFIG_SA1100_SPOT
-+ spot_switches_sa1100_handler(irq, &mask);
-+#endif
-+ } else if (machine_is_simpad()) {
-+#ifdef CONFIG_SA1100_SIMPAD
-+ simpad_switches_sa1100_handler(irq, &mask);
-+#endif
-+ }
-+
-+ switches_event(&mask);
-+
-+}
-+
-+int __init switches_sa1100_init(void)
-+{
-+
-+ /* Porting note: call a board-specific init routine here. */
-+
-+ if (machine_is_assabet()) {
-+#ifdef CONFIG_SA1100_ASSABET
-+ if (assabet_switches_sa1100_init() < 0)
-+ return -EIO;
-+#endif
-+ } else if (machine_is_spot()) {
-+#ifdef CONFIG_SA1100_SPOT
-+ if (spot_switches_sa1100_init() < 0)
-+ return -EIO;
-+#endif
-+ } else if (machine_is_simpad()) {
-+#ifdef CONFIG_SA1100_SIMPAD
-+ if (simpad_switches_sa1100_init() < 0)
-+ return -EIO;
-+#endif
-+ }
-+
-+ return 0;
-+
-+}
-+
-+void __exit switches_sa1100_exit(void)
-+{
-+
-+ /* Porting note: call a board-specific shutdown routine here. */
-+
-+ if (machine_is_assabet()) {
-+#ifdef CONFIG_SA1100_ASSABET
-+ assabet_switches_sa1100_shutdown();
-+#endif
-+ } else if (machine_is_spot()) {
-+#ifdef CONFIG_SA1100_SPOT
-+ spot_switches_sa1100_shutdown();
-+#endif
-+ } else if (machine_is_simpad()) {
-+#ifdef CONFIG_SA1100_SIMPAD
-+ simpad_switches_sa1100_shutdown();
-+#endif
-+ }
-+
-+}
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/misc/switches-ucb1x00.c 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,331 @@
-+/*
-+ * linux/drivers/misc/switches-ucb1x00.c
-+ *
-+ * Copyright (C) 2001 John Dorsey
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 19 December 2001 - created from sa1100_switches.c.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+
-+#include <asm/dma.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+
-+#ifdef CONFIG_SA1100_ASSABET
-+#include <asm/arch/assabet.h>
-+#endif
-+
-+#ifdef CONFIG_SA1100_SIMPAD
-+#include <asm/arch/simpad.h>
-+#endif
-+
-+#include "switches.h"
-+#include "ucb1x00.h"
-+
-+
-+static struct ucb1x00 *ucb1x00;
-+
-+static void switches_ucb1x00_handler(int irq, void *devid);
-+
-+
-+#ifdef CONFIG_SA1100_ASSABET
-+
-+/* Assabet
-+ * ^^^^^^^
-+ * Six switches are routed to GPIO pins on the UCB1300: S3 -- S8.
-+ * This code sets bits in the range [3, 8] in the mask that we
-+ * return to userland. Note that we transpose signals SW7 and SW8;
-+ * see assabet_switches_ucb1x00_handler().
-+ */
-+
-+static int assabet_switches_ucb1x00_init(void)
-+{
-+ int i;
-+
-+ /* Note that ucb1x00_init() must complete before this point: */
-+
-+ if ((ucb1x00 = ucb1x00_get()) == NULL) {
-+ printk(KERN_ERR "%s: UCB1300 driver not ready; switches "
-+ "3 -- 8 will not be available\n",
-+ SWITCHES_NAME);
-+ return 0;
-+ }
-+
-+ ucb1x00_enable(ucb1x00);
-+
-+ ucb1x00_io_set_dir(ucb1x00,
-+ UCB_IO_0 | UCB_IO_1 | UCB_IO_2 |
-+ UCB_IO_3 | UCB_IO_4 | UCB_IO_5, 0);
-+
-+ for (i = 0; i < 6; ++i) {
-+
-+ ucb1x00_enable_irq(ucb1x00, i, UCB_RISING | UCB_FALLING);
-+
-+ if (ucb1x00_hook_irq(ucb1x00, i,
-+ switches_ucb1x00_handler, NULL) < 0) {
-+ printk(KERN_ERR "%s: unable to hook IRQ for "
-+ "UCB1300 IO_%d\n", SWITCHES_NAME, i);
-+ return -EBUSY;
-+ }
-+
-+ }
-+
-+ return 0;
-+
-+}
-+
-+static void assabet_switches_ucb1x00_shutdown(void)
-+{
-+ int i;
-+
-+ for (i = 5; i >= 0; --i) {
-+
-+ ucb1x00_disable_irq(ucb1x00, i, UCB_RISING | UCB_FALLING);
-+
-+ /* Only error conditions are ENOENT and EINVAL; silently
-+ * ignore:
-+ */
-+ ucb1x00_free_irq(ucb1x00, i, NULL);
-+
-+ }
-+
-+}
-+
-+static void assabet_switches_ucb1x00_handler(int irq, switches_mask_t *mask)
-+{
-+ unsigned int last, this;
-+ static unsigned int states = 0;
-+
-+ last = ((states & (1 << irq)) != 0);
-+ this = ((ucb1x00_io_read(ucb1x00) & (1 << irq)) != 0);
-+
-+ if (last == this) /* debounce */
-+ return;
-+
-+ /* Intel StrongARM SA-1110 Development Board
-+ * Schematics Figure 5, Sheet 5 of 12
-+ *
-+ * See switches S8 and S7. Notice their
-+ * relationship to signals SW7 and SW8. Hmmm.
-+ */
-+
-+ switch (irq) {
-+
-+ case 4:
-+
-+ SWITCHES_SET(mask, 8, this);
-+ break;
-+
-+ case 5:
-+
-+ SWITCHES_SET(mask, 7, this);
-+ break;
-+
-+ default:
-+
-+ SWITCHES_SET(mask, irq + 3, this);
-+
-+ }
-+
-+ states = this ? (states | (1 << irq)) : (states & ~(1 << irq));
-+
-+}
-+#endif /* CONFIG_SA1100_ASSABET */
-+
-+#ifdef CONFIG_SA1100_SIMPAD
-+
-+/* SIMpad
-+ * ^^^^^^
-+ * Six switches are routed to GPIO pins on the UCB1300: S3 -- S8.
-+ * This code sets bits in the range [3, 8] in the mask that we
-+ * return to userland.
-+ */
-+
-+static int simpad_switches_ucb1x00_init(void)
-+{
-+ int i;
-+
-+ /* Note that ucb1x00_init() must complete before this point: */
-+
-+ if ((ucb1x00 = ucb1x00_get()) == NULL) {
-+ printk(KERN_ERR "%s: UCB1300 driver not ready; switches "
-+ "3 -- 8 will not be available\n",
-+ SWITCHES_NAME);
-+ return 0;
-+ }
-+
-+ ucb1x00_enable(ucb1x00);
-+
-+ ucb1x00_io_set_dir(ucb1x00,
-+ UCB_IO_0 | UCB_IO_1 | UCB_IO_2 |
-+ UCB_IO_3 | UCB_IO_4 | UCB_IO_5,
-+ UCB_IO_8 | UCB_IO_9);
-+
-+ ucb1x00_disable(ucb1x00);
-+
-+ for (i = 0; i < 6; ++i) {
-+
-+ if (ucb1x00_hook_irq(ucb1x00, i,
-+ switches_ucb1x00_handler, NULL) < 0) {
-+ printk(KERN_ERR "%s: unable to hook IRQ for "
-+ "UCB1300 IO_%d\n", SWITCHES_NAME, i);
-+ return -EBUSY;
-+ }
-+
-+ ucb1x00_enable_irq(ucb1x00, i, UCB_RISING | UCB_FALLING);
-+ }
-+
-+ return 0;
-+
-+}
-+
-+int simpad_switches_ucb1x00_reinit(void)
-+{
-+ int i;
-+ ucb1x00_enable(ucb1x00);
-+
-+ ucb1x00_io_set_dir(ucb1x00,
-+ UCB_IO_0 | UCB_IO_1 | UCB_IO_2 |
-+ UCB_IO_3 | UCB_IO_4 | UCB_IO_5,
-+ UCB_IO_8 | UCB_IO_9);
-+
-+ ucb1x00_disable(ucb1x00);
-+
-+ for (i = 0; i < 6; ++i)
-+ ucb1x00_enable_irq(ucb1x00, i, UCB_RISING | UCB_FALLING);
-+
-+ return 0;
-+}
-+
-+static void simpad_switches_ucb1x00_shutdown(void)
-+{
-+ int i;
-+
-+ for (i = 5; i >= 0; --i) {
-+
-+ ucb1x00_disable_irq(ucb1x00, i, UCB_RISING | UCB_FALLING);
-+
-+ /* Only error conditions are ENOENT and EINVAL; silently
-+ * ignore:
-+ */
-+ ucb1x00_free_irq(ucb1x00, i, NULL);
-+
-+ }
-+
-+}
-+
-+static void simpad_switches_ucb1x00_handler(int irq, switches_mask_t *mask)
-+{
-+ unsigned int last, this;
-+ static unsigned int states = 0;
-+
-+ last = ((states & (1 << irq)) != 0);
-+ this = ((~ucb1x00_io_read(ucb1x00) & (1 << irq)) != 0);
-+
-+ if (last == this) /* debounce */
-+ return;
-+
-+ switch (irq) {
-+
-+ case 4:
-+
-+
-+
-+ case 5:
-+
-+
-+
-+ default:
-+
-+ SWITCHES_SET(mask, irq + 3, this);
-+
-+ }
-+
-+ states = this ? (states | (1 << irq)) : (states & ~(1 << irq));
-+
-+}
-+#endif /* CONFIG_SA1100_SIMPAD */
-+
-+
-+/* switches_ucb1x00_handler()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * This routine is a generalized handler for UCB1x00 GPIO switches
-+ * which calls a board-specific service routine and passes an event
-+ * mask to the core event handler. This routine is appropriate for
-+ * systems which use the ucb1x00 framework, and can be registered
-+ * using ucb1x00_hook_irq().
-+ */
-+static void switches_ucb1x00_handler(int irq, void *devid)
-+{
-+ switches_mask_t mask;
-+
-+ SWITCHES_ZERO(&mask);
-+
-+ /* Porting note: call a board-specific UCB1x00 switch handler here.
-+ * The handler can assume that sufficient storage for `mask' has
-+ * been allocated, and that the corresponding switches_mask_t
-+ * structure has been zeroed.
-+ */
-+
-+ if (machine_is_assabet()) {
-+#ifdef CONFIG_SA1100_ASSABET
-+ assabet_switches_ucb1x00_handler(irq, &mask);
-+#endif
-+ }
-+ if (machine_is_simpad()) {
-+#ifdef CONFIG_SA1100_SIMPAD
-+ simpad_switches_ucb1x00_handler(irq, &mask);
-+#endif
-+ }
-+
-+ switches_event(&mask);
-+
-+}
-+
-+int __init switches_ucb1x00_init(void)
-+{
-+
-+ /* Porting note: call a board-specific init routine here. */
-+
-+ if (machine_is_assabet()) {
-+#ifdef CONFIG_SA1100_ASSABET
-+ if (assabet_switches_ucb1x00_init() < 0)
-+ return -EIO;
-+#endif
-+ }
-+ if (machine_is_simpad()) {
-+#ifdef CONFIG_SA1100_SIMPAD
-+ if (simpad_switches_ucb1x00_init() < 0)
-+ return -EIO;
-+#endif
-+ }
-+
-+ return 0;
-+
-+}
-+
-+void __exit switches_ucb1x00_exit(void)
-+{
-+
-+ /* Porting note: call a board-specific shutdown routine here. */
-+
-+ if (machine_is_assabet()) {
-+#ifdef CONFIG_SA1100_ASSABET
-+ assabet_switches_ucb1x00_shutdown();
-+#endif
-+ }
-+ if (machine_is_simpad()) {
-+#ifdef CONFIG_SA1100_SIMPAD
-+ simpad_switches_ucb1x00_shutdown();
-+#endif
-+ }
-+
-+}
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/misc/switches.h 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,28 @@
-+/*
-+ * linux/drivers/misc/switches.h
-+ *
-+ * Copyright (C) 2001 John Dorsey
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 19 December 2001 - created.
-+ */
-+
-+#if !defined(_SWITCHES_H)
-+# define _SWITCHES_H
-+
-+#include <linux/switches.h>
-+
-+#define SWITCHES_NAME "switches"
-+
-+extern int switches_event(switches_mask_t *mask);
-+
-+extern int switches_sa1100_init(void);
-+extern void switches_sa1100_exit(void);
-+
-+extern int switches_ucb1x00_init(void);
-+extern void switches_ucb1x00_exit(void);
-+
-+#endif /* !defined(_SWITCHES_H) */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/misc/ucb1x00-assabet.c 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,114 @@
-+/*
-+ * linux/drivers/misc/ucb1x00-assabet.c
-+ *
-+ * Copyright (C) 2001 Russell King, 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.
-+ *
-+ * We handle the machine-specific bits of the UCB1x00 driver here.
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/fs.h>
-+#include <linux/proc_fs.h>
-+
-+#include <asm/dma.h>
-+
-+#include "ucb1x00.h"
-+
-+static struct proc_dir_entry *dir;
-+static struct ucb1x00 *ucb;
-+
-+static int ucb1x00_assabet_read_vbatt(struct ucb1x00 *ucb)
-+{
-+ int val;
-+ ucb1x00_adc_enable(ucb);
-+ val = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD1, UCB_NOSYNC);
-+ ucb1x00_adc_disable(ucb);
-+
-+ return val;
-+}
-+
-+static int ucb1x00_assabet_read_vcharger(struct ucb1x00 *ucb)
-+{
-+ int val;
-+ ucb1x00_adc_enable(ucb);
-+ val = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD0, UCB_NOSYNC);
-+ ucb1x00_adc_disable(ucb);
-+
-+ return val;
-+}
-+
-+static int ucb1x00_assabet_read_batt_temp(struct ucb1x00 *ucb)
-+{
-+ int val;
-+ ucb1x00_adc_enable(ucb);
-+ val = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD2, UCB_NOSYNC);
-+ ucb1x00_adc_disable(ucb);
-+
-+ return val;
-+}
-+
-+static int ucb_read(char *page, char **start, off_t off, int count, int *eof, void *data)
-+{
-+ char *p = page;
-+ int (*fn)(struct ucb1x00 *) = data;
-+ int v, len;
-+
-+ v = fn(ucb);
-+
-+ p += sprintf(p, "%d\n", v);
-+
-+ len = (p - page) - off;
-+ if (len < 0)
-+ len = 0;
-+
-+ *eof = (len <= count) ? 1 : 0;
-+ *start = page + off;
-+
-+ return len;
-+}
-+
-+static int __init ucb1x00_assabet_init(void)
-+{
-+ struct proc_dir_entry *res;
-+
-+ ucb = ucb1x00_get();
-+
-+ if (!ucb)
-+ return -ENODEV;
-+
-+ dir = proc_mkdir("ucb1x00", NULL);
-+ if (!dir)
-+ return -ENOMEM;
-+
-+ res = create_proc_read_entry("vbatt", S_IRUGO, dir, ucb_read, ucb1x00_assabet_read_vbatt);
-+ if (!res)
-+ return -ENOMEM;
-+
-+ res = create_proc_read_entry("vcharger", S_IRUGO, dir, ucb_read, ucb1x00_assabet_read_vcharger);
-+ if (!res)
-+ return -ENOMEM;
-+
-+ res = create_proc_read_entry("batt_temp", S_IRUGO, dir, ucb_read, ucb1x00_assabet_read_batt_temp);
-+ if (!res)
-+ return -ENOMEM;
-+
-+ return 0;
-+}
-+
-+static void __exit ucb1x00_assabet_exit(void)
-+{
-+ remove_proc_entry("vbatt", dir);
-+ remove_proc_entry("vcharger", dir);
-+ remove_proc_entry("batt_temp", dir);
-+}
-+
-+module_init(ucb1x00_assabet_init);
-+module_exit(ucb1x00_assabet_exit);
-+
-+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-+MODULE_DESCRIPTION("Assabet noddy testing only example ADC driver");
-+MODULE_LICENSE("GPL");
---- linux-2.4.25/drivers/misc/ucb1x00-audio.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:37.000000000 +0200
-+++ linux-2.4.25/drivers/misc/ucb1x00-audio.c 2004-05-02 22:48:00.000000000 +0200
-@@ -283,7 +283,7 @@
- {
- struct ucb1x00_audio *ucba;
-
-- ucba = kmalloc(sizeof(*ucba), GFP_KERNEL);
-+ ucba = kmalloc(sizeof(*ucba), GFP_ATOMIC);
- if (ucba) {
- memset(ucba, 0, sizeof(*ucba));
-
---- linux-2.4.25/drivers/misc/ucb1x00-core.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200
-+++ linux-2.4.25/drivers/misc/ucb1x00-core.c 2004-05-02 22:45:42.000000000 +0200
-@@ -215,6 +215,9 @@
- ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr);
- ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
- ucb1x00_disable(ucb);
-+#ifdef CONFIG_SA1100_SIMPAD
-+ simpad_switches_ucb1x00_reinit();
-+#endif
- }
-
- return 0;
-@@ -561,8 +564,10 @@
- default_irq = IRQ_GPIO_UCB1300_IRQ;
- #endif
- #ifdef CONFIG_SA1100_SIMPAD
-- if (machine_is_simpad())
-+ if (machine_is_simpad()) {
- default_irq = IRQ_GPIO_UCB1300_IRQ;
-+ irq_gpio_pin = GPIO_UCB1300_IRQ;
-+ }
- #endif
- #ifdef CONFIG_SA1100_SIMPUTER
- if (machine_is_simputer()) {
-@@ -660,7 +665,7 @@
- if (id == UCB_ID_1400 && mcp_reg_read(mcp, 0x00) == 0x002a)
- id = UCB_ID_1400_BUGGY;
-
-- my_ucb = kmalloc(sizeof(struct ucb1x00), GFP_KERNEL);
-+ my_ucb = kmalloc(sizeof(struct ucb1x00), GFP_ATOMIC);
- ret = -ENOMEM;
- if (!my_ucb)
- goto out;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/misc/ucb1x00-simpad.c 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,241 @@
-+/*
-+ * linux/drivers/misc/ucb1x00-simpad.c
-+ *
-+ * Modified by Juergen Messerer for SIMpad
-+ * Copyright (C) 2001 Russell King, 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.
-+ *
-+ * We handle the machine-specific bits of the UCB1x00 driver here.
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/fs.h>
-+#include <linux/proc_fs.h>
-+
-+#include <asm/dma.h>
-+
-+#include <asm/arch-sa1100/simpad_pm.h>
-+
-+#include "ucb1x00.h"
-+
-+/*
-+ * Conversion from AD -> mV
-+ * 7.5V = 1023 7.3313mV/Digit
-+ *
-+ * 400 Units == 9.7V
-+ * a = ADC value
-+ * 21 = ADC error
-+ * 12600 = Divident to get 2*7.3242
-+ * 860 = Divider to get 2*7.3242
-+ * 170 = Voltagedrop over
-+ */
-+#define CALIBRATE_BATTERY(a) ((((a + 21)*12600)/860) + 170)
-+
-+/*
-+ * We have two types of batteries a small and a large one
-+ * To get the right value we to distinguish between those two
-+ * 450 Units == 15 V
-+ */
-+#ifdef SMALL_BATTERY
-+#define CALIBRATE_SUPPLY(a) (((a) * 1500) / 51)
-+#define MIN_SUPPLY 8500 /* Less then 8.5V means no powersupply */
-+#else
-+#define CALIBRATE_SUPPLY(a) (((a) * 1500) / 45)
-+//#define MIN_SUPPLY 14000 /* Less then 14V means no powersupply */
-+#define MIN_SUPPLY 12000 /* Less then 12V means no powersupply */
-+#endif
-+
-+/*
-+ * Charging Current
-+ * if value is >= 50 then charging is on
-+ */
-+#define CALIBRATE_CHARGING(a) (((a)* 1000)/(152/4)))
-+//#define CHARGING_LED_LEVEL 50
-+
-+#ifdef CONFIG_SA1100_SIMPAD_SINUSPAD
-+
-+#define CHARGING_LED_LEVEL 12
-+#define CHARGING_MAX_LEVEL 120
-+#define BATT_FULL 8100
-+#define BATT_LOW 7300
-+#define BATT_CRITICAL 6700
-+#define BATT_EMPTY 6400
-+
-+
-+#else // CONFIG_SA1100_SIMPAD_SINUSPAD
-+
-+#define CHARGING_LED_LEVEL 28
-+#define CHARGING_MAX_LEVEL 265
-+#define BATT_FULL 8300
-+#define BATT_LOW 7400
-+#define BATT_CRITICAL 6800
-+#define BATT_EMPTY 6500
-+
-+#endif // CONFIG_SA1100_SIMPAD_SINUSPAD
-+
-+
-+static struct proc_dir_entry *dir;
-+static struct ucb1x00 *ucb;
-+
-+static int ucb1x00_simpad_read_vbatt(struct ucb1x00 *ucb)
-+{
-+ int val;
-+ ucb1x00_adc_enable(ucb);
-+ val = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD1, UCB_NOSYNC);
-+ ucb1x00_adc_disable(ucb);
-+
-+ return CALIBRATE_BATTERY(val);
-+}
-+
-+static int ucb1x00_simpad_read_vcharger(struct ucb1x00 *ucb)
-+{
-+ int val;
-+ ucb1x00_adc_enable(ucb);
-+ val = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD2, UCB_NOSYNC);
-+ ucb1x00_adc_disable(ucb);
-+
-+ return CALIBRATE_SUPPLY(val);
-+}
-+
-+static int ucb1x00_simpad_read_icharger(struct ucb1x00 *ucb)
-+{
-+ int val;
-+ ucb1x00_adc_enable(ucb);
-+ val = ucb1x00_adc_read(ucb, UCB_ADC_INP_AD3, UCB_NOSYNC);
-+ ucb1x00_adc_disable(ucb);
-+
-+ return val;
-+}
-+
-+static int ucb_read(char *page, char **start, off_t off, int count, int *eof, void *data)
-+{
-+ char *p = page;
-+ int (*fn)(struct ucb1x00 *) = data;
-+ int v, len;
-+
-+ v = fn(ucb);
-+
-+ p += sprintf(p, "%d\n", v);
-+
-+ len = (p - page) - off;
-+ if (len < 0)
-+ len = 0;
-+
-+ *eof = (len <= count) ? 1 : 0;
-+ *start = page + off;
-+
-+ return len;
-+}
-+
-+/****************************************************************************/
-+/* Functions exported for use by the kernel and kernel modules */
-+/****************************************************************************/
-+
-+int simpad_get_battery(struct simpad_battery *bstat)
-+{
-+ int icharger, vcharger, vbatt;
-+
-+ if ( ucb ) {
-+ icharger = ucb1x00_simpad_read_icharger( ucb );
-+ vcharger = ucb1x00_simpad_read_vcharger( ucb );
-+ vbatt = ucb1x00_simpad_read_vbatt( ucb );
-+ } else {
-+ bstat->ac_status = SIMPAD_AC_STATUS_AC_UNKNOWN;
-+ bstat->status = SIMPAD_BATT_STATUS_UNKNOWN;
-+ bstat->percentage = 0x64; /* lets say 100% */
-+ bstat->life = 360; /* lets say a long time */
-+ return 0;
-+ }
-+
-+ /* AC status */
-+ bstat->ac_status = SIMPAD_AC_STATUS_AC_OFFLINE;
-+ if ( vcharger>MIN_SUPPLY ) {
-+ bstat->ac_status = SIMPAD_AC_STATUS_AC_ONLINE;
-+ }
-+
-+ /* charging */
-+ bstat->status = 0x0;
-+ if ( icharger > CHARGING_LED_LEVEL ) {
-+ bstat->status = SIMPAD_BATT_STATUS_CHARGING;
-+ }
-+
-+ if ( vbatt > BATT_LOW )
-+ bstat->status |= SIMPAD_BATT_STATUS_HIGH;
-+ else if ( vbatt < BATT_CRITICAL )
-+ bstat->status |= SIMPAD_BATT_STATUS_CRITICAL;
-+ else
-+ bstat->status |= SIMPAD_BATT_STATUS_LOW;
-+
-+ if (bstat->status & SIMPAD_BATT_STATUS_CHARGING) {
-+ if (icharger > CHARGING_MAX_LEVEL) icharger = CHARGING_MAX_LEVEL;
-+ if (icharger < CHARGING_LED_LEVEL) icharger = CHARGING_LED_LEVEL;
-+ bstat->percentage = 100 - 100 * (icharger - CHARGING_LED_LEVEL) /
-+ (CHARGING_MAX_LEVEL - CHARGING_LED_LEVEL);
-+ } else {
-+ if (vbatt > BATT_FULL) vbatt = BATT_FULL;
-+ if (vbatt < BATT_EMPTY) vbatt = BATT_EMPTY;
-+ bstat->percentage = 100 * (vbatt - BATT_EMPTY) / (BATT_FULL - BATT_EMPTY);
-+ }
-+
-+ /* let's assume: full load is 7h */
-+ /* bstat->life = 420*bstat->percentage/100; */
-+ bstat->life = 0;
-+
-+#if 0
-+ printk("get_battery: ac: %02x / ch: %02x / perc: %02x / life: %d\n",
-+ bstat->ac_status, bstat->status,
-+ bstat->percentage, bstat->life );
-+#endif
-+
-+ return 0;
-+}
-+
-+EXPORT_SYMBOL(simpad_get_battery);
-+
-+/****************************************************************************/
-+/* sample proc interface */
-+/****************************************************************************/
-+static int __init ucb1x00_simpad_init(void)
-+{
-+ struct proc_dir_entry *res;
-+
-+ ucb = ucb1x00_get();
-+
-+ if (!ucb)
-+ return -ENODEV;
-+
-+ dir = proc_mkdir("ucb1x00", NULL);
-+ if (!dir)
-+ return -ENOMEM;
-+
-+ res = create_proc_read_entry("vbatt", S_IRUGO, dir, ucb_read, ucb1x00_simpad_read_vbatt);
-+ if (!res)
-+ return -ENOMEM;
-+
-+ res = create_proc_read_entry("vcharger", S_IRUGO, dir, ucb_read, ucb1x00_simpad_read_vcharger);
-+ if (!res)
-+ return -ENOMEM;
-+
-+ res = create_proc_read_entry("icharger", S_IRUGO, dir, ucb_read, ucb1x00_simpad_read_icharger);
-+ if (!res)
-+ return -ENOMEM;
-+
-+ return 0;
-+}
-+
-+static void __exit ucb1x00_simpad_exit(void)
-+{
-+ remove_proc_entry("vbatt", dir);
-+ remove_proc_entry("vcharger", dir);
-+ remove_proc_entry("icharger", dir);
-+}
-+
-+module_init(ucb1x00_simpad_init);
-+module_exit(ucb1x00_simpad_exit);
-+
-+MODULE_AUTHOR("Juergen Messerer <juergen.messerer@freesurf.ch>");
-+MODULE_DESCRIPTION("SIMpad noddy testing only example ADC driver");
-+MODULE_LICENSE("GPL");
---- linux-2.4.25/drivers/misc/ucb1x00-ts.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200
-+++ linux-2.4.25/drivers/misc/ucb1x00-ts.c 2004-05-02 22:45:42.000000000 +0200
-@@ -356,7 +356,7 @@
- UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
- UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
-
-- udelay(55);
-+ udelay(250); /*former 55*/
-
- return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
- }
-@@ -379,7 +379,7 @@
- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
- UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
-
-- udelay(55);
-+ udelay(250); /*former 55*/
-
- return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);
- }
---- linux-2.4.25/drivers/mtd/Config.in~2.4.25-vrs2-pxa1-jpm1.patch 2003-06-13 16:51:34.000000000 +0200
-+++ linux-2.4.25/drivers/mtd/Config.in 2004-05-02 22:45:42.000000000 +0200
-@@ -11,6 +11,9 @@
- if [ "$CONFIG_MTD_DEBUG" = "y" ]; then
- int ' Debugging verbosity (0 = quiet, 3 = noisy)' CONFIG_MTD_DEBUG_VERBOSE 0
- fi
-+ if [ "$CONFIG_CRAMFS" = "y" ]; then
-+ bool ' Cramfs root partition' CONFIG_ROOT_CRAMFS
-+ fi
- dep_tristate ' MTD partitioning support' CONFIG_MTD_PARTITIONS $CONFIG_MTD
- dep_tristate ' MTD concatenating support' CONFIG_MTD_CONCAT $CONFIG_MTD
- dep_tristate ' RedBoot partition table parsing' CONFIG_MTD_REDBOOT_PARTS $CONFIG_MTD_PARTITIONS
---- linux-2.4.25/drivers/mtd/maps/sa1100-flash.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:37.000000000 +0200
-+++ linux-2.4.25/drivers/mtd/maps/sa1100-flash.c 2004-05-02 22:45:42.000000000 +0200
-@@ -767,40 +767,38 @@
- #endif
-
- #ifdef CONFIG_SA1100_SIMPAD
--#define SIMPAD_FLASH_SIZE 0x02000000
--static struct mtd_partition simpad_partitions[] = {
-- {
-- name: "SIMpad boot firmware",
-- size: 0x00080000,
-- offset: 0,
-- mask_flags: MTD_WRITEABLE, /* force read-only */
-- }, {
-- name: "SIMpad kernel",
-- size: 0x00100000,
-- offset: 0x00080000,
-- }, {
--#ifdef CONFIG_JFFS2_FS
-- name: "SIMpad root jffs2",
-- size: MTDPART_SIZ_FULL,
-- offset: 0x00180000,
-+
-+#ifdef CONFIG_SA1100_SIMPAD_SINUSPAD
-+#define SIMPAD_FLASH_SIZE 0x01000000
- #else
-- name: "SIMpad initrd",
-- size: 0x00300000,
-- offset: 0x00180000,
-- }, {
-- name: "SIMpad root cramfs",
-- size: 0x00300000,
-- offset: 0x00480000,
-- }, {
-- name: "SIMpad usr cramfs",
-- size: 0x005c0000,
-- offset: 0x00780000,
-- }, {
-- name: "SIMpad usr local",
-- size: MTDPART_SIZ_FULL,
-- offset: 0x00d40000,
-+#define SIMPAD_FLASH_SIZE 0x02000000
- #endif
-- }
-+
-+static struct mtd_partition simpad_partitions[] = {
-+ {
-+ name: "SIMpad boot firmware",
-+ offset: 0,
-+ size: 0x00080000,
-+ mask_flags: MTD_WRITEABLE /* force read-only */
-+ },{
-+ name: "SIMpad kernel",
-+ offset: MTDPART_OFS_APPEND,
-+ size: 0x00100000
-+ },{
-+#ifdef CONFIG_ROOT_CRAMFS
-+ name: "SIMpad root cramfs",
-+ offset: MTDPART_OFS_APPEND,
-+ size: 0x00D80000
-+ },{
-+ name: "SIMpad local jffs",
-+ offset: MTDPART_OFS_APPEND,
-+ size: MTDPART_SIZ_FULL
-+#else
-+ name: "SIMpad root jffs2",
-+ offset: MTDPART_OFS_APPEND,
-+ size: MTDPART_SIZ_FULL
-+#endif /* CONFIG_CRAM_FS */
-+ }
- };
- #endif /* CONFIG_SA1100_SIMPAD */
-
---- linux-2.4.25/drivers/pcmcia/sa1100_simpad.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:37.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/sa1100_simpad.c 2004-05-02 22:45:42.000000000 +0200
-@@ -9,20 +9,18 @@
-
- #include <asm/hardware.h>
- #include <asm/irq.h>
-+#include <asm/arch/simpad.h>
-+
- #include "sa1100_generic.h"
--
-+
- extern long get_cs3_shadow(void);
--extern void set_cs3_bit(int value);
-+extern void set_cs3_bit(int value);
- extern void clear_cs3_bit(int value);
-
-
- static int simpad_pcmcia_init(struct pcmcia_init *init){
- int irq, res;
-
-- set_cs3_bit(PCMCIA_RESET);
-- clear_cs3_bit(PCMCIA_BUFF_DIS);
-- clear_cs3_bit(PCMCIA_RESET);
--
- clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
-
- /* Set transition detect */
-@@ -63,6 +61,9 @@
-
- if(state_array->size<2) return -1;
-
-+ memset(state_array->state, 0,
-+ (state_array->size)*sizeof(struct pcmcia_state));
-+
- levels=GPLR;
-
- state_array->state[1].detect=((levels & GPIO_CF_CD)==0)?1:0;
-@@ -100,13 +101,15 @@
- static int simpad_pcmcia_configure_socket(const struct pcmcia_configure
- *configure)
- {
-- unsigned long value, flags;
-+ static int irq_disabled = 0;
-
-- if(configure->sock>1) return -1;
-+ if(configure->sock>1)
-+ return -1;
-
-- if(configure->sock==0) return 0;
-+ if(configure->sock==0)
-+ return 0;
-
-- save_flags_cli(flags);
-+ //local_irq_save(flags);
-
- /* Murphy: see table of MIC2562a-1 */
-
-@@ -116,8 +119,8 @@
- break;
-
- case 33:
-- clear_cs3_bit(VCC_3V_EN|EN0);
-- set_cs3_bit(VCC_5V_EN|EN1);
-+ clear_cs3_bit(VCC_3V_EN|EN1);
-+ set_cs3_bit(VCC_5V_EN|EN0);
- break;
-
- case 50:
-@@ -129,26 +132,50 @@
- printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
- configure->vcc);
- clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1);
-- restore_flags(flags);
-+ //restore_flags(flags);
- return -1;
- }
-
-- /* Silently ignore Vpp, output enable, speaker enable. */
-+ if(configure->reset)
-+ set_cs3_bit(PCMCIA_RESET);
-+ else
-+ clear_cs3_bit(PCMCIA_RESET);
-+
-+ if(configure->output)
-+ clear_cs3_bit(PCMCIA_BUFF_DIS);
-+ else
-+ set_cs3_bit(PCMCIA_BUFF_DIS);
-
-- restore_flags(flags);
-+ if(configure->irq) {
-+ enable_irq(IRQ_GPIO_CF_IRQ);
-+ irq_disabled = 0;
-+ }
-+ else {
-+ if (!irq_disabled) {
-+ disable_irq(IRQ_GPIO_CF_IRQ);
-+ irq_disabled = 1;
-+ }
-+ }
-+
-+ //local_irq_restore(flags);
-
- return 0;
- }
-
- static int simpad_pcmcia_socket_init(int sock)
- {
-- set_GPIO_IRQ_edge(GPIO_CF_CD, GPIO_BOTH_EDGES);
-+ if(sock == 1)
-+ set_GPIO_IRQ_edge(GPIO_CF_CD, GPIO_BOTH_EDGES);
- return 0;
- }
-
- static int simpad_pcmcia_socket_suspend(int sock)
- {
-- set_GPIO_IRQ_edge(GPIO_CF_CD, GPIO_NO_EDGES);
-+ if(sock == 1)
-+ {
-+ set_GPIO_IRQ_edge(GPIO_CF_CD, GPIO_NO_EDGES);
-+ set_cs3_bit(PCMCIA_RESET);
-+ }
- return 0;
- }
-
---- linux-2.4.25/drivers/video/Config.in~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200
-+++ linux-2.4.25/drivers/video/Config.in 2004-05-02 22:45:42.000000000 +0200
-@@ -61,6 +61,10 @@
- fi
- fi
- dep_tristate ' CyberPro 2000/2010/5000 support' CONFIG_FB_CYBER2000 $CONFIG_PCI
-+ if [ "$CONFIG_SA1100_SIMPAD" = "y" -o \
-+ "$CONFIGG_SA1100_GDS2200" = "y" ]; then
-+ bool ' MQ200 VGA support' CONFIG_FB_MQ200
-+ fi
- if [ "$CONFIG_APOLLO" = "y" ]; then
- define_bool CONFIG_FB_APOLLO y
- fi
---- linux-2.4.25/drivers/video/Makefile~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200
-+++ linux-2.4.25/drivers/video/Makefile 2004-05-02 22:45:42.000000000 +0200
-@@ -141,6 +141,7 @@
- obj-$(CONFIG_FB_PVR2) += pvr2fb.o
- obj-$(CONFIG_FB_VOODOO1) += sstfb.o
- obj-$(CONFIG_FB_ANAKIN) += anakinfb.o
-+obj-$(CONFIG_FB_MQ200) += mq200fb.o
-
- # Generic Low Level Drivers
-
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/video/mq200fb.c 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,1963 @@
-+/* MQ200 console frame buffer driver---mq200fb.c
-+ *
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file COPYING in the main directory of this archive for
-+ * more details.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/mm.h>
-+#include <linux/tty.h>
-+#include <linux/slab.h>
-+#include <linux/vmalloc.h>
-+#include <linux/delay.h>
-+#include <linux/pm.h>
-+#include <linux/interrupt.h>
-+#include <linux/proc_fs.h> /* all the /proc functions */
-+#include <linux/ioport.h>
-+#include <asm/uaccess.h>
-+#include <linux/fb.h>
-+#include <linux/init.h>
-+#include <linux/pci.h>
-+#include <asm/io.h>
-+
-+#include <linux/console.h>
-+
-+#include <video/fbcon.h>
-+#ifdef CONFIG_FBCON_MFB
-+#include <video/fbcon-mfb.h>
-+#endif
-+#ifdef CONFIG_FBCON_CFB2
-+#include <video/fbcon-cfb2.h>
-+#endif
-+#ifdef CONFIG_FBCON_CFB4
-+#include <video/fbcon-cfb4.h>
-+#endif
-+#ifdef CONFIG_FBCON_CFB8
-+#include <video/fbcon-cfb8.h>
-+#endif
-+#ifdef CONFIG_FBCON_CFB16
-+#include <video/fbcon-cfb16.h>
-+#endif
-+#ifdef CONFIG_FBCON_CFB24
-+#include <video/fbcon-cfb24.h>
-+#endif
-+#ifdef CONFIG_FBCON_CFB32
-+#include <video/fbcon-cfb32.h>
-+#endif
-+
-+#include <video/MQ200/mq2hw.h>
-+#include <video/MQ200/mqdata.h>
-+#include <video/MQ200/mqplat.h>
-+
-+/* GPIO handling */
-+#include <asm/irq.h>
-+#include <asm/hardware.h>
-+
-+#ifdef TEST
-+#undef PDEBUG /* Safety */
-+
-+#define PDEBUG(fmt, args...) printk(KERN_EMERG fmt, ##args)
-+#else
-+#define PDEBUG(fmt, args...)
-+#endif
-+
-+#define MQ200_DIRNAME "driver/mq200"
-+#define REG_DIRNAME "registers"
-+
-+void enable_cursor(void *pMQMMIO);
-+
-+static ssize_t proc_read_reg(struct file * file, char * buf,
-+ size_t nbytes, loff_t *ppos);
-+static ssize_t proc_write_reg(struct file * file, const char * buffer,
-+ size_t count, loff_t *ppos);
-+
-+static struct file_operations proc_reg_operations = {
-+ read: proc_read_reg,
-+ write: proc_write_reg
-+};
-+
-+typedef struct sa1110_reg_entry {
-+ u32 phyaddr;
-+ char* name;
-+ char* description;
-+ unsigned short low_ino;
-+} sa1110_reg_entry_t;
-+
-+#define CMAPSIZE 32
-+#define arraysize(x) (sizeof(x)/sizeof(*(x)))
-+
-+#define mq200_p2v( x ) \
-+ (((x) - 0x4b800000) + 0xf2800000)
-+
-+/* The following is copied from mq2hw.c for initialization of MQ200 */
-+/* PLL1 data */
-+#define PLL1_83MHZ 0x0EF2082A
-+#define DEF_MIU2_83MHZ 0x4143E086
-+#define PLL1_50MHZ 0x0B200A2A
-+#define DEF_MIU2_50MHZ 0x40C30086
-+
-+/* Miscellaneous default data */
-+#define DEF_D1 0x05000271
-+#define DEF_D2 0x00000271
-+#define DEF_MIU3 0x6D6AABFF
-+#define DEF_MIU4 0x00000001
-+#define DEF_MIU5 0x0000010D
-+
-+#ifdef CONFIG_SA1100_GDS2200
-+#define DEF_GPO_CONTROL 0x00020054
-+#else
-+#define DEF_GPO_CONTROL 0x00000000
-+#endif
-+
-+#define DEF_GPIO_CONTROL 0x00000000
-+#define DEF_PWM_CONTROL 0x00A16c44
-+#define PWMOFFMASK 0xFF0FFF0F
-+
-+struct fb_info_mq200 {
-+ struct fb_info fb_info;
-+ struct fb_fix_screeninfo fix;
-+ struct fb_var_screeninfo var;
-+ struct display disp;
-+ struct {
-+ __u8 red, green, blue;
-+ } palette[256];
-+ struct fb_info_mq200 *next;
-+ unsigned int mqMmioAddrVirt;
-+ unsigned int mqFbAddrVirt;
-+ unsigned int mqMmioAddrPhys;
-+ unsigned int mqFbAddrPhys;
-+#ifdef CONFIG_PM
-+ struct pm_dev *pm;
-+#endif
-+};
-+
-+u32 mqflag;
-+u32 mqMmioAddr, mqFbAddr;
-+
-+/* Interface need to console.c. The following variable are defined in
-+ drivers/char/console.c */
-+
-+extern unsigned char color_table[];
-+extern int default_red[];
-+extern int default_grn[];
-+extern int default_blu[];
-+
-+#ifdef CONFIG_SA1100_SIMPAD
-+ extern void set_cs3_bit(int value);
-+ extern void clear_cs3_bit(int value);
-+ DISPLAY_CONFIG dc = {800, 600, 16, 60, 1600, 0x00130004};
-+#else
-+ DISPLAY_CONFIG dc = {800, 600, 32, 60, 3200, 0x0023000f};
-+#endif
-+
-+static int currcon = 0;
-+static char mq200fb_name[16] = "MQ200FB";
-+
-+static struct fb_var_screeninfo mq200fb_default = {
-+ /* 800x600, 32 bpp */
-+ 800, 600, 800, 600, 0, 0, 32, 0,
-+ {0, 8, 0}, {8, 8, 0}, {16, 8, 0}, {24, 8, 0},
-+ 0, 0, -1, -1, 0, MQ200_FB_SIZE, 64, 64, 32, 32, 64, 2,
-+ 0, FB_VMODE_NONINTERLACED
-+};
-+static union {
-+ u16 cfb16[CMAPSIZE];
-+ u32 cfb24[CMAPSIZE];
-+ u32 cfb32[CMAPSIZE];
-+} fbcon_cmap;
-+
-+static struct proc_dir_entry *regdir;
-+static struct proc_dir_entry *mq200dir;
-+static struct proc_dir_entry *driverdir;
-+
-+/* Functions used to initialize MQ200 chip */
-+void setmqmode(PDISPLAY_CONFIG, void *);
-+void setup_cursor(void *);
-+void onoffdisplay(int, void *);
-+unsigned long getbppbits(int);
-+PDISPLAY_TIMING getgcparam(int, int, int);
-+void setpal(int, unsigned long, void *);
-+void setupfp(int, void *);
-+void setuphfbuffer(int, unsigned long, void *);
-+void setupgc(int, int, int, int, int, void *);
-+void setupgcmem(PDISPLAY_CONFIG, unsigned long, void *);
-+long idmqchip(void *pMQMMIO);
-+void turnoffMQ200(void * pMQMMIO);
-+
-+/* Interface used by the world */
-+int mq200fb_setup(char*);
-+static int mq200fb_open(struct fb_info *info, int user);
-+static int mq200fb_release (struct fb_info *info, int user);
-+static int mq200fb_get_fix(struct fb_fix_screeninfo *fix, int con, \
-+ struct fb_info *info);
-+static int mq200fb_get_var(struct fb_var_screeninfo *var, int con, \
-+ struct fb_info *info);
-+static int mq200fb_set_var(struct fb_var_screeninfo *var, int con, \
-+ struct fb_info *info);
-+static int mq200fb_pan_display(struct fb_var_screeninfo *var, int con, \
-+ struct fb_info *info);
-+static int mq200fb_get_cmap(struct fb_cmap *cmap, int kspc, int con, \
-+ struct fb_info *info);
-+static int mq200fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, \
-+ struct fb_info *info);
-+static int mq200fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-+ u_long arg, int con, struct fb_info *info);
-+
-+/* Interface to the low level console driver */
-+int mq200fb_init(void);
-+static int mq200fbcon_switch(int con, struct fb_info *info);
-+static int mq200fbcon_updatevar(int con, struct fb_info *info);
-+static void mq200fbcon_blank(int blank, struct fb_info *info);
-+
-+/* int sa1100fb_map_video_memory(void * pmem int memsize); */
-+
-+/*
-+ *Internal routines
-+ */
-+
-+static u_long get_line_length(int xres_virtual, int bpp);
-+static void mq200fb_encode_fix(struct fb_fix_screeninfo *fix,
-+ struct fb_var_screeninfo *var);
-+static void set_color_bitfields(struct fb_var_screeninfo *var);
-+static int mq200fb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-+ u_int *transp, struct fb_info *info);
-+static int mq200fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-+ u_int transp, struct fb_info *info);
-+static void do_install_cmap(int con, struct fb_info *info);
-+
-+#ifdef CONFIG_PM
-+static int mq200fb_pm_callback(struct pm_dev *, pm_request_t, void *);
-+#endif
-+
-+#if defined(CONFIG_SA1100_GDS2200) || defined(CONFIG_SA1100_SIMPAD)
-+static void mq200_backlight(void *, int);
-+#endif
-+
-+#ifdef CONFIG_SA1100_SIMPAD
-+static void writeBrightness(void *, int);
-+#endif
-+
-+static struct fb_ops mq200fb_ops = {
-+ owner: THIS_MODULE,
-+ fb_get_fix: mq200fb_get_fix,
-+ fb_get_var: mq200fb_get_var,
-+ fb_set_var: mq200fb_set_var,
-+ fb_get_cmap: mq200fb_get_cmap,
-+ fb_set_cmap: mq200fb_set_cmap,
-+ fb_pan_display: mq200fb_pan_display,
-+ fb_ioctl: mq200fb_ioctl,
-+};
-+
-+typedef struct mq200_reg_entry {
-+ u32 phyaddr;
-+ char* name;
-+ char* description;
-+ unsigned short low_ino;
-+} mq200_reg_entry_t;
-+
-+static mq200_reg_entry_t mq200_regs[] =
-+{
-+ { 0x4be00000, "PM_MISC", "MQ200 PM_MISC" },
-+ { 0x4be00004, "D1_STATE", "MQ200 D1_STATE" },
-+ { 0x4be00008, "D2_STATE", "MQ200 D2_STATE" },
-+ { 0x4be00018, "PLL2_CONTROL", "MQ200 PLL2_CONTROL" },
-+ { 0x4be0001c, "PLL3_CONTROL", "MQ200 PLL3_CONTROL" },
-+ { 0x4be02000, "CPU_CONTROL", "MQ200 CPU_CONTROL" },
-+ { 0x4be02004, "DRAW_STATUS", "MQ200 DRAW_STATUS" },
-+ { 0x4be04000, "MIU_CONTROL1", "MQ200 MIU_CONTROL1" },
-+ { 0x4be04004, "MIU_CONTROL2", "MQ200 MIU_CONTROL2" },
-+ { 0x4be04008, "MIU_CONTROL3", "MQ200 MIU_CONTROL3" },
-+ { 0x4be0400c, "MIU_CONTROL4", "MQ200 MIU_CONTROL4" },
-+ { 0x4be04010, "MIU_CONTROL5", "MQ200 MIU_CONTROL5" },
-+ { 0x4be0a000, "GC1_CONTROL", "MQ200 GC1_CONTROL" },
-+ { 0x4be0a004, "GC1_CRT_CONTROL", "MQ200 GC1_CRT_CONTROL" },
-+ { 0x4be0a008, "HD1_CONTROL", "MQ200 HD1_CONTROL" },
-+ { 0x4be0a00c, "VD1_CONTROL", "MQ200 VD1_CONTROL" },
-+ { 0x4be0a010, "HS1_CONTROL", "MQ200 HS1_CONTROL" },
-+ { 0x4be0a014, "VS1_CONTROL", "MQ200 VS1_CONTROL" },
-+ { 0x4be0a020, "HW1_CONTROL", "MQ200 HW1_CONTROL" },
-+ { 0x4be0a024, "VW1_CONTROL", "MQ200 VW1_CONTROL" },
-+ { 0x4be0a040, "HW_CURSOR1_POS", "MQ200 HW_CURSOR1_POS" },
-+ { 0x4be0a044, "HW_CURSOR1_ADDR", "MQ200 HW_CURSOR1_ADDR" },
-+ { 0x4be0e000, "FP_CONTROL", "MQ200 FP_CONTROL" },
-+ { 0x4be0e004, "FP_PIN_CONTROL", "MQ200 FP_PIN_CONTROL" },
-+ { 0x4be0e008, "FP_GPO_CONTROL", "MQ200 FP_GPO_CONTROL" },
-+ { 0x4be0e00c, "FP_GPIO_CONTROL", "MQ200 FP_GPIO_CONTROL" },
-+ { 0x4be0e010, "STN_CONTROL", "MQ200 STN_CONTROL" },
-+ { 0x4be0e014, "DSTN_FB_CONTROL", "MQ200 DSTN_FB_CONTROL" },
-+ { 0x4be0e03c, "PWM_CONTROL", "MQ200 PWM_CONTROL" },
-+ { 0x4be14000, "DC_0", "MQ200 DC_1" },
-+ { 0x4be14004, "DC_1", "MQ200 DC_2" },
-+ { 0x4be14008, "DC_SW_0", "MQ200 DC_SW_0" },
-+ { 0x4be1400c, "DC_SW_1", "MQ200 DC_SW_1" },
-+ { 0x4be16040, "PMR", "MQ200 PMR" },
-+ { 0x4be16044, "PMCSR", "MQ200 PMCSR" }
-+};
-+
-+#define NUM_OF_MQ200_REG_ENTRY (sizeof(mq200_regs)/sizeof(mq200_reg_entry_t))
-+
-+static int mq200fb_open(struct fb_info *info, int user)
-+{
-+ /*
-+ * Nothing, only a usage count for the moment
-+ */
-+ MOD_INC_USE_COUNT;
-+ return(0);
-+
-+}
-+
-+/* Release console */
-+static int mq200fb_release (struct fb_info *info, int user)
-+{
-+ struct fb_info_mq200 *p = (struct fb_info_mq200 *) info;
-+ turnoffMQ200((void *) p->mqMmioAddrVirt);
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+/* Get the Fixed Part of the Display */
-+static int mq200fb_get_fix(struct fb_fix_screeninfo *fix, int con,
-+ struct fb_info *info)
-+{
-+ struct fb_info_mq200 *p = (struct fb_info_mq200 *) info;
-+
-+ PDEBUG("mq200fb: %i---in mq200fb_get_fix.\n", __LINE__);
-+
-+ *fix = p->fix;
-+ return 0;
-+
-+}
-+
-+
-+ /*
-+ * Get the User Defined Part of the Display
-+ */
-+
-+static int mq200fb_get_var(struct fb_var_screeninfo *var, int con,
-+ struct fb_info *info)
-+{
-+ struct fb_info_mq200 *p = (struct fb_info_mq200 *) info;
-+
-+ PDEBUG("mq200fb: %i---in mq200fb_get_var.\n", __LINE__);
-+
-+ *var = p->var;
-+ return 0;
-+}
-+
-+
-+ /*
-+ * Set the User Defined Part of the Display
-+ */
-+
-+static int mq200fb_set_var(struct fb_var_screeninfo *var, int con,
-+ struct fb_info *info)
-+{
-+ struct fb_info_mq200 * p = (struct fb_info_mq200 *) info;
-+ int err, activate = var->activate;
-+ int oldxres, oldyres, oldvxres, oldvyres, oldbpp;
-+ u_long line_length;
-+
-+ struct display *display;
-+
-+ PDEBUG("mq200fb: %i---in mq200fb_set_var.\n", __LINE__);
-+
-+ if (con >= 0)
-+ display = &fb_display[con];
-+ else
-+ display = &(p->disp); /* used during initialization */
-+
-+ /*
-+ * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
-+ * as FB_VMODE_SMOOTH_XPAN is only used internally
-+ */
-+
-+ if (var->vmode & FB_VMODE_CONUPDATE) {
-+ var->vmode |= FB_VMODE_YWRAP;
-+ var->xoffset = display->var.xoffset;
-+ var->yoffset = display->var.yoffset;
-+ }
-+
-+ /*
-+ * Memory limit
-+ */
-+ line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
-+ if (line_length*var->yres_virtual > MQ200_FB_SIZE)
-+ return -ENOMEM;
-+
-+ set_color_bitfields(var);
-+
-+ if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
-+ oldxres = display->var.xres;
-+ oldyres = display->var.yres;
-+ oldvxres = display->var.xres_virtual;
-+ oldvyres = display->var.yres_virtual;
-+ oldbpp = display->var.bits_per_pixel;
-+ display->var = *var;
-+ if (oldxres != var->xres || oldyres != var->yres ||
-+ oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
-+ oldbpp != var->bits_per_pixel) {
-+
-+ display->screen_base = (char *) p->mqFbAddrVirt;
-+ display->visual = p->fix.visual;
-+ display->type = p->fix.type;
-+ display->type_aux = p->fix.type_aux;
-+ display->ypanstep = p->fix.ypanstep;
-+ display->ywrapstep = p->fix.ywrapstep;
-+ display->line_length = p->fix.line_length;
-+ display->can_soft_blank = 1;
-+ display->inverse = 0;
-+
-+ switch (var->bits_per_pixel) {
-+#ifdef CONFIG_FBCON_MFB
-+ case 1:
-+ display->dispsw = &fbcon_mfb;
-+ break;
-+#endif
-+#ifdef CONFIG_FBCON_CFB2
-+ case 2:
-+ display->dispsw = &fbcon_cfb2;
-+ break;
-+#endif
-+#ifdef CONFIG_FBCON_CFB4
-+ case 4:
-+ display->dispsw = &fbcon_cfb4;
-+ break;
-+#endif
-+#ifdef CONFIG_FBCON_CFB8
-+ case 8:
-+ display->dispsw = &fbcon_cfb8;
-+ break;
-+#endif
-+#ifdef CONFIG_FBCON_CFB16
-+ case 16:
-+ display->dispsw = &fbcon_cfb16;
-+ display->dispsw_data = fbcon_cmap.cfb16;
-+ break;
-+#endif
-+#ifdef CONFIG_FBCON_CFB24
-+ case 24:
-+ display->dispsw = &fbcon_cfb24;
-+ display->dispsw_data = fbcon_cmap.cfb24;
-+ break;
-+#endif
-+#ifdef CONFIG_FBCON_CFB32
-+ case 32:
-+ display->dispsw = &fbcon_cfb32;
-+ display->dispsw_data = fbcon_cmap.cfb32;
-+ break;
-+#endif
-+ default:
-+ display->dispsw = &fbcon_dummy;
-+ break;
-+ }
-+
-+
-+ if (p->fb_info.changevar)
-+ (*p->fb_info.changevar)(con);
-+ }
-+
-+ if (oldbpp != var->bits_per_pixel) {
-+ if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
-+ return err;
-+ do_install_cmap(con, info);
-+ }
-+
-+ }
-+
-+ return 0;
-+}
-+
-+
-+ /*
-+ * Pan or Wrap the Display
-+ *
-+ * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
-+ */
-+
-+static int mq200fb_pan_display(struct fb_var_screeninfo *var, int con,
-+ struct fb_info *info)
-+{
-+ PDEBUG("mq200fb: %i---mq200fb_pan_display.\n", __LINE__);
-+
-+ if (var->vmode & FB_VMODE_YWRAP) {
-+ if (var->yoffset < 0 ||
-+ var->yoffset >= fb_display[con].var.yres_virtual ||
-+ var->xoffset)
-+ return -EINVAL;
-+ } else {
-+ if (var->xoffset+fb_display[con].var.xres >
-+ fb_display[con].var.xres_virtual ||
-+ var->yoffset+fb_display[con].var.yres >
-+ fb_display[con].var.yres_virtual)
-+ return -EINVAL;
-+ }
-+ fb_display[con].var.xoffset = var->xoffset;
-+ fb_display[con].var.yoffset = var->yoffset;
-+ if (var->vmode & FB_VMODE_YWRAP)
-+ fb_display[con].var.vmode |= FB_VMODE_YWRAP;
-+ else
-+ fb_display[con].var.vmode &= ~FB_VMODE_YWRAP;
-+ return 0;
-+}
-+
-+ /*
-+ * Get the Colormap
-+ */
-+
-+static int mq200fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-+ struct fb_info *info)
-+{
-+ PDEBUG("mq200fb: %i---mq200fb_get_cmap.\n", __LINE__);
-+
-+ if (con == currcon) /* current console? */
-+ return fb_get_cmap(cmap, kspc, mq200fb_getcolreg, info);
-+ else if (fb_display[con].cmap.len) /* non default colormap? */
-+ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-+ else
-+ {
-+ int size = (fb_display[con].var.bits_per_pixel <= 8) ? 256 : 16;
-+ fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
-+ }
-+ return 0;
-+}
-+
-+ /*
-+ * Set the Colormap
-+ */
-+
-+static int mq200fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-+ struct fb_info *info)
-+{
-+ int err;
-+
-+ PDEBUG("mq200fb: %i---mq200fb_set_cmap.\n", __LINE__);
-+
-+ if (!fb_display[con].cmap.len) { /* no colormap allocated? */
-+ int size = (fb_display[con].var.bits_per_pixel <= 8) ? 256 : 16;
-+ if ((err = fb_alloc_cmap(&fb_display[con].cmap, size, 0)))
-+ return err;
-+ }
-+ if (con == currcon) /* current console? */
-+ return fb_set_cmap(cmap, kspc, mq200fb_setcolreg, info);
-+ else
-+ fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
-+ return 0;
-+}
-+
-+
-+static int mq200fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-+ u_long arg, int con, struct fb_info *info)
-+{
-+ return -EINVAL;
-+}
-+
-+
-+int __init mq200fb_setup(char *options)
-+{
-+ PDEBUG("mq200fb.c: %i---mq200fb_setup\n", __LINE__);
-+
-+/*
-+ char *this_opt;
-+
-+ fb_info.fontname[0] = '\0';
-+
-+ if (!options || !*options)
-+ return 0;
-+
-+ for (this_opt = strtok(options, ","); this_opt;
-+ this_opt = strtok(NULL, ",")) {
-+ if (!strncmp(this_opt, "font:", 5))
-+ strcpy(fb_info.fontname, this_opt+5);
-+ }
-+*/
-+ return 0;
-+}
-+
-+
-+ /*
-+ * Initialisation
-+ */
-+
-+int __init mq200fb_init(void)
-+{
-+ struct fb_info_mq200 *p = NULL;
-+ int i; /* used as loop counter */
-+ struct proc_dir_entry *entry;
-+
-+ p = (struct fb_info_mq200 *) kmalloc(sizeof(*p), GFP_ATOMIC);
-+ if(p==NULL)
-+ return 0;
-+ memset(p, 0, sizeof(*p));
-+
-+ mq200dir = proc_mkdir(MQ200_DIRNAME, NULL);
-+ if (mq200dir == NULL) {
-+ printk(KERN_ERR "mq200fb: can't create /proc/" MQ200_DIRNAME "\n");
-+ return(-ENOMEM);
-+ }
-+
-+ regdir = proc_mkdir(REG_DIRNAME, mq200dir);
-+ if (regdir == NULL) {
-+ printk(KERN_ERR "mq200fb: can't create /proc/" MQ200_DIRNAME "/" REG_DIRNAME "\n");
-+ return(-ENOMEM);
-+ }
-+
-+ for(i=0;i<NUM_OF_MQ200_REG_ENTRY;i++) {
-+ entry = create_proc_entry(mq200_regs[i].name,
-+ S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH,
-+ regdir);
-+ if(entry) {
-+ mq200_regs[i].low_ino = entry->low_ino;
-+ entry->proc_fops = &proc_reg_operations;
-+ }
-+ else {
-+ printk( KERN_ERR
-+ "mq200fb: can't create /proc/" REG_DIRNAME
-+ "/%s\n", mq200_regs[i].name);
-+ return(-ENOMEM);
-+ }
-+ }
-+
-+
-+#ifdef MQ_SA1110
-+
-+#ifdef CONFIG_SA1100_ASSABET
-+ pCPUReg=(u32 *)ioremap( MSC2, 4);
-+ *pCPUReg = 0x42194449;
-+ iounmap((void *) pCPUReg);
-+
-+ GPDR |= 0x08000000;
-+ GAFR |= 0x08000000;
-+ TUCR |= 0x20000000;
-+
-+ ASSABET_BCR_set(ASSABET_BCR_GFX_RST); /* ASSABET_BCR */
-+
-+ MQ_DELAY(8);
-+ ASSABET_BCR_clear(ASSABET_BCR_GFX_RST);
-+ MQ_DELAY(30);
-+ ASSABET_BCR_set(ASSABET_BCR_GFX_RST); /* ASSABET_BCR */
-+#endif
-+
-+#ifdef CONFIG_SA1100_SIMPAD
-+ GPDR |= (1<<3);
-+ GAFR |= ~(1<<3);
-+ GPSR |= (1<<3);
-+#endif
-+
-+ p->mqMmioAddrPhys=REGISTER_BASE;
-+ p->mqFbAddrPhys=FB_BASE;
-+
-+ p->mqMmioAddrVirt = mqMmioAddr = 0xf2e00000;
-+ p->mqFbAddrVirt = mqFbAddr = 0xf2800000;
-+
-+#endif /* MQ_SA1110 */
-+
-+ mqflag = dc.flag;
-+
-+ PDEBUG("mq200fb.c: line %i, mqMmioAddr = 0X%08X, mqFbAddr = 0X%08X\n",\
-+ __LINE__, mqMmioAddr, mqFbAddr);
-+
-+ /* Setmode for MQ200 chip */
-+ setmqmode(&dc, (void *) mqMmioAddr);
-+
-+ /* Set fb_info_mq200.fix info */
-+ strcpy(p->fix.id, mq200fb_name);
-+ p->fix.smem_start = p->mqFbAddrPhys;
-+ p->fix.smem_len = MQ200_FB_SIZE;
-+ p->fix.mmio_start = p->mqMmioAddrPhys;
-+ p->fix.mmio_len = MQ200_MMIO_SIZE;
-+ p->fix.type = FB_TYPE_PACKED_PIXELS;
-+
-+ if(dc.bpp <= 8)
-+ p->fix.visual = FB_VISUAL_PSEUDOCOLOR;
-+ else if (dc.bpp >= 16)
-+ p->fix.visual = FB_VISUAL_DIRECTCOLOR;
-+
-+ p->fix.line_length = dc.stride;
-+
-+ /* Set fb_info_mq200.var info */
-+ p->var.xres = dc.x;
-+ p->var.yres = dc.y;
-+ p->var.xres_virtual = dc.x;
-+ p->var.yres_virtual = dc.y;
-+ p->var.bits_per_pixel = dc.bpp;
-+
-+ if(dc.bpp == 8) {
-+ p->var.red.offset = 0;
-+ p->var.green.offset = 0;
-+ p->var.blue.offset = 0;
-+ p->var.red.length = p->var.green.length = \
-+ p->var.blue.length = dc.bpp;
-+ p->var.transp.length = 0;
-+ p->var.transp.offset = 0;
-+ }
-+ else if(dc.bpp == 16) {
-+#ifdef CONF
-+ IG_PREP
-+ p->var.red.offset = 2;
-+ p->var.green.offset = -3;
-+ p->var.blue.offset = 8;
-+#else
-+ p->var.red.offset = 11;
-+ p->var.green.offset = 5;
-+ p->var.blue.offset = 0;
-+#endif
-+
-+ p->var.red.length = 5;
-+ p->var.green.length = 6;
-+ p->var.blue.length = 5;
-+ }
-+ else if (dc.bpp == 24) {
-+#ifdef CONFIG_PREP
-+ p->var.red.offset = 8;
-+ p->var.green.offset = 16;
-+ p->var.blue.offset = 24;
-+#else
-+ p->var.red.offset = 16;
-+ p->var.green.offset = 8;
-+ p->var.blue.offset = 0;
-+#endif
-+ p->var.red.length = 8;
-+ p->var.green.length = 8;
-+ p->var.blue.length = 8;
-+ }
-+ else if(dc.bpp == 32) {
-+#ifdef CONFIG_PREP
-+ p->var.red.offset = 8;
-+ p->var.green.offset = 16;
-+ p->var.blue.offset = 24;
-+#else
-+ p->var.red.offset = 0;
-+ p->var.green.offset = 8;
-+ p->var.blue.offset = 16;
-+#endif /* CONFIG_PREP */
-+ p->var.red.length = 8;
-+ p->var.green.length = 8;
-+ p->var.blue.length = 8;
-+ }
-+
-+ p->var.transp.length = 0;
-+ p->var.transp.offset = 0;
-+ p->var.height = p->var.width = -1;
-+ p->var.vmode = FB_VMODE_NONINTERLACED;
-+ p->var.pixclock = 10000;
-+ p->var.left_margin = p->var.right_margin = 16;
-+ p->var.upper_margin = p->var.lower_margin = 16;
-+ p->var.hsync_len = p->var.vsync_len = 8;
-+
-+ /* Set fb_info_mq200.disp info */
-+ p->disp.var = p->var;
-+ p->disp.cmap.red = NULL;
-+ p->disp.cmap.green = NULL;
-+ p->disp.cmap.blue = NULL;
-+ p->disp.cmap.transp = NULL;
-+ p->disp.screen_base = (char *) p->mqFbAddrVirt;
-+ p->disp.visual = p->fix.visual;
-+ p->disp.type = p->fix.type;
-+ p->disp.type_aux = p->fix.type_aux;
-+ p->disp.line_length = p->fix.line_length;
-+ p->disp.can_soft_blank = 1;
-+
-+ switch(dc.bpp) {
-+#ifdef CONFIG_FBCON_CFB8
-+ case 8:
-+ p->disp.dispsw = &fbcon_cfb8;
-+ break;
-+#endif
-+#ifdef CONFIG_FBCON_CFB16
-+ case 16:
-+ p->disp.dispsw = &fbcon_cfb16;
-+ p->disp.dispsw_data = fbcon_cmap.cfb16;
-+ break;
-+#endif
-+#ifdef CONFIG_FBCON_CFB24
-+ case 24:
-+ p->disp.dispsw = &fbcon_cfb24;
-+ p->disp.dispsw_data = fbcon_cmap.cfb24;
-+ break;
-+#endif
-+#ifdef CONFIG_FBCON_CFB32
-+ case 32:
-+ p->disp.dispsw = &fbcon_cfb32;
-+ p->disp.dispsw_data = fbcon_cmap.cfb32;
-+ break;
-+#endif
-+ default:
-+ PDEBUG("mq200fb.c: %i---Wrong configuration options", __LINE__);
-+ }
-+
-+ p->disp.scrollmode = SCROLL_YREDRAW;
-+
-+ strcpy(p->fb_info.modename, p->fix.id);
-+ p->fb_info.changevar = NULL;
-+ p->fb_info.node = NODEV;
-+
-+ p->fb_info.fbops = &mq200fb_ops;
-+ p->fb_info.disp = &(p->disp);
-+ p->fb_info.switch_con = &mq200fbcon_switch;
-+ p->fb_info.updatevar = &mq200fbcon_updatevar;
-+ p->fb_info.blank = &mq200fbcon_blank;
-+ p->fb_info.flags = FBINFO_FLAG_DEFAULT;
-+
-+ for (i = 0; i < 16; i++) {
-+ int j = color_table[i];
-+ p->palette[i].red = default_red[j];
-+ p->palette[i].green = default_grn[j];
-+ p->palette[i].blue = default_blu[j];
-+ }
-+
-+ if (register_framebuffer(&p->fb_info) < 0) {
-+ PDEBUG("Oops...register_framebuffer failed!\n");
-+ iounmap(p);
-+ iounmap((void *)mqMmioAddr);
-+ iounmap((void *)mqFbAddr);
-+ return -EINVAL;
-+ }
-+
-+#ifdef CONFIG_PM
-+ /*
-+ * Note that the console registers this as well, but we want to
-+ * power down the display prior to sleeping.
-+ */
-+ p->pm = pm_register(PM_SYS_DEV, PM_SYS_VGA, mq200fb_pm_callback);
-+ if (p->pm)
-+ p->pm->data = p;
-+#endif
-+ PDEBUG("fb%d: Virtual frame buffer device, using %ldK of video memory\n", \
-+ GET_FB_IDX(p->fb_info.node), MQ200_FB_SIZE >> 10);
-+ return 0;
-+}
-+
-+static int mq200fbcon_switch(int con, struct fb_info *info)
-+{
-+ /* Do we have to save the colormap? */
-+
-+ PDEBUG("mq200fb: mq200fbcon_switch.\n");
-+
-+ if (fb_display[currcon].cmap.len)
-+ fb_get_cmap(&fb_display[currcon].cmap, 1, mq200fb_getcolreg, info);
-+
-+ currcon = con;
-+ /* Install new colormap */
-+ do_install_cmap(con, info);
-+ return 0;
-+}
-+
-+/*
-+ * Update the `var' structure (called by fbcon.c)
-+ */
-+
-+static int mq200fbcon_updatevar(int con, struct fb_info *info)
-+{
-+ /* Nothing */
-+
-+ PDEBUG("mq200fb: mq200fbcon_updatevar.\n");
-+
-+ return 0;
-+}
-+
-+/*
-+ * Blank the display.
-+ */
-+
-+static void mq200fbcon_blank(int blank, struct fb_info *info)
-+{
-+ /*struct fb_info_mq200 *p = (struct fb_info_mq200 *) info;*/
-+
-+ /* Nothing */
-+ /*
-+ if(blank)
-+ onoffdisplay(DISABLE_LCD_GC1, (void *) p->mqMmioAddrVirt);
-+ else
-+ onoffdisplay(ENABLE_LCD_GC1, (void *) p->mqMmioAddrVirt);*/
-+}
-+
-+static u_long get_line_length(int xres_virtual, int bpp)
-+{
-+ u_long length;
-+
-+ PDEBUG("mq200fb: get_line_length.\n");
-+
-+ length = (xres_virtual+bpp-1)/bpp;
-+ length = (length+31)&-32;
-+ length >>= 3;
-+ return(length);
-+}
-+
-+static void mq200fb_encode_fix(struct fb_fix_screeninfo *fix,
-+ struct fb_var_screeninfo *var)
-+{
-+
-+ PDEBUG("mq200fb: mq200fb_encode_fix.\n");
-+
-+ memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-+ strcpy(fix->id, mq200fb_name);
-+ fix->smem_start = mqFbAddr;
-+ fix->smem_len = MQ200_FB_SIZE;
-+ fix->type = FB_TYPE_PACKED_PIXELS;
-+ fix->type_aux = 0;
-+ switch (var->bits_per_pixel) {
-+ case 1:
-+ fix->visual = FB_VISUAL_MONO01;
-+ break;
-+ case 2:
-+ case 4:
-+ case 8:
-+ fix->visual = FB_VISUAL_PSEUDOCOLOR;
-+ break;
-+ case 16:
-+ case 24:
-+ case 32:
-+ fix->visual = FB_VISUAL_DIRECTCOLOR;
-+ break;
-+ }
-+ fix->ywrapstep = 1;
-+ fix->xpanstep = 1;
-+ fix->ypanstep = 1;
-+ fix->line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
-+}
-+
-+static void set_color_bitfields(struct fb_var_screeninfo *var)
-+{
-+
-+ PDEBUG("mq200fb: set_color_bitfields.\n");
-+
-+ switch (var->bits_per_pixel) {
-+ case 1:
-+ case 8:
-+ var->red.offset = 0;
-+ var->red.length = 8;
-+ var->green.offset = 0;
-+ var->green.length = 8;
-+ var->blue.offset = 0;
-+ var->blue.length = 8;
-+ var->transp.offset = 0;
-+ var->transp.length = 0;
-+ break;
-+ case 16: /* RGB 565 */
-+#ifdef CONFIG_PREP
-+ var->red.offset = 2;
-+ var->green.offset = -3;
-+ var->blue.offset = 8;
-+#else
-+ var->red.offset = 11;
-+ var->green.offset = 5;
-+ var->blue.offset = 0;
-+#endif
-+ var->red.length = 5;
-+ var->green.length = 6;
-+ var->blue.length = 5;
-+ var->transp.length = 0;
-+ var->transp.offset = 0;
-+ break;
-+ case 24: /* RGB 888 */
-+#ifdef CONFIG_PREP
-+ var->red.offset = 8;
-+ var->green.offset = 16;
-+ var->blue.offset = 24;
-+#else
-+ var->red.offset = 16;
-+ var->green.offset = 8;
-+ var->blue.offset = 0;
-+#endif
-+ var->red.length = 8;
-+ var->green.length = 8;
-+ var->blue.length = 8;
-+ break;
-+ case 32: /* RGBA 8888 */
-+ var->red.offset = 0;
-+ var->red.length = 8;
-+ var->green.offset = 8;
-+ var->green.length = 8;
-+ var->blue.offset = 16;
-+ var->blue.length = 8;
-+ var->transp.offset = 24;
-+ var->transp.length = 8;
-+ break;
-+ }
-+ var->red.msb_right = 0;
-+ var->green.msb_right = 0;
-+ var->blue.msb_right = 0;
-+ var->transp.msb_right = 0;
-+}
-+
-+
-+ /*
-+ * Read a single color register and split it into
-+ * colors/transparent. Return != 0 for invalid regno.
-+ */
-+
-+static int mq200fb_getcolreg(u_int regno, u_int *red, u_int *green,
-+ u_int *blue, u_int *transp, struct fb_info *info)
-+{
-+ struct fb_info_mq200 *p = (struct fb_info_mq200 *) info;
-+
-+ /*PDEBUG("mq200fb: mq200fb_getcolreg.\n");*/
-+
-+ if (regno > 255)
-+ return 1;
-+ *red = (p->palette[regno].red<<8) | p->palette[regno].red;
-+ *green = (p->palette[regno].green<<8) | p->palette[regno].green;
-+ *blue = (p->palette[regno].blue<<8) | p->palette[regno].blue;
-+ *transp = 0;
-+ return 0;
-+}
-+
-+
-+ /*
-+ * Set a single color register. The values supplied are already
-+ * rounded down to the hardware's capabilities (according to the
-+ * entries in the var structure). Return != 0 for invalid regno.
-+ */
-+
-+static int mq200fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-+ u_int transp, struct fb_info *info)
-+{
-+ struct fb_info_mq200 *p = (struct fb_info_mq200 *) info;
-+ unsigned long color;
-+
-+ if (regno > 255)
-+ return 1;
-+
-+ /*PDEBUG("In mq200fb_setcolreg, regno = %d, 0x%0x\n", regno, red);*/
-+
-+ /*PDEBUG("mq200fb: mq200fb_setcolreg.\n");*/
-+
-+ switch (p->var.bits_per_pixel) {
-+#ifdef CONFIG_FBCON_CFB16
-+ case 16:
-+ if(regno < CMAPSIZE)
-+#ifdef CONFIG_PREP
-+ fbcon_cmap.cfb16[regno] =
-+ ((red & 0xf800) >> 9) |
-+ ((green & 0xf800) >> 14) |
-+ ((green & 0xf800) << 2) | ((blue & 0xf800) >> 3);
-+#else
-+ fbcon_cmap.cfb16[regno] =
-+ ((red & 0xf800) >> 0) |
-+ ((green & 0xf800) >> 5) | ((blue & 0xf800) >> 11);
-+
-+#endif /* CONFIG_PREP */
-+ break;
-+#endif
-+#ifdef CONFIG_FBCON_CFB24
-+ case 24:
-+ if (regno < CMAPSIZE)
-+#ifdef CONFIG_PREP
-+ fbcon_cmap.cfb24[regno] =
-+ ((red & 0xff00)) |
-+ ((green & 0xff00) << 8) | ((blue & 0xff00) << 16);
-+#else
-+ fbcon_cmap.cfb24[regno] =
-+ ((red & 0xff00) << 8) |
-+ ((green & 0xff00)) | ((blue & 0xff00) >> 8);
-+#endif
-+ break;
-+#endif
-+#ifdef CONFIG_FBCON_CFB32
-+ case 32:
-+ if(regno < CMAPSIZE)
-+#ifdef CONFIG_PREP
-+ fbcon_cmap.cfb32[regno] =
-+ ((red & 0xff00)) |
-+ ((green & 0xff00) << 8) | ((blue & 0xff00) << 16);
-+#else
-+ fbcon_cmap.cfb32[regno] =
-+ ((red & 0xff00) >> 8) |
-+ ((green & 0xff00)) | ((blue & 0xff00) << 8);
-+#endif
-+
-+ break;
-+#endif
-+ default:
-+ break;
-+ }
-+
-+ red &= 0xFF;
-+ green &= 0xFF;
-+ blue &= 0xFF;
-+
-+ p->palette[regno].red = red;
-+ p->palette[regno].green = green;
-+ p->palette[regno].blue = blue;
-+
-+ color = red | (green << 8) | (blue << 16);
-+ setpal(regno, color, (void *)p->mqMmioAddrVirt);
-+
-+ return 0;
-+}
-+
-+
-+static void do_install_cmap(int con, struct fb_info *info)
-+{
-+ if (con != currcon)
-+ return;
-+
-+ PDEBUG("mq200fb: do_install_cmap.\n");
-+
-+ if (fb_display[con].cmap.len)
-+ fb_set_cmap(&fb_display[con].cmap, 1, mq200fb_setcolreg, info);
-+ else {
-+ int size = (fb_display[con].var.bits_per_pixel <= 8) ? 256 : 16;
-+ fb_set_cmap(fb_default_cmap(size), 1, mq200fb_setcolreg, info);
-+ }
-+}
-+
-+
-+#ifdef MODULE
-+int init_module(void)
-+{
-+ return mq200fb_init();
-+}
-+
-+void cleanup_module(void)
-+{
-+ unregister_framebuffer(&(fb_info_mq200.fb_info));
-+ iounmap((void *)(fb_info_mq200.mqMmioAddrVirt));
-+ iounmap((void *)(fb_info_mq200.mqFbAddrVirt));
-+}
-+
-+#endif /* MODULE */
-+
-+/* The following is copied from mq2hw.c for initialization of MQ200 */
-+
-+long idmqchip(void *pMQMMIO)
-+{
-+ unsigned long id;
-+
-+ id = READ32(PCI_VENDOR_DEVICE);
-+ return (id);
-+}
-+
-+/* Setmode for MediaQ chip
-+ *
-+ */
-+void setmqmode(PDISPLAY_CONFIG pDC, void *pMQMMIO)
-+{
-+ volatile unsigned long regdata, pmmisc;
-+ int x=0, y=0, freq=0, paneltype; /* i is used as loop counter */
-+ unsigned long screensize, gc_startaddr;
-+
-+ printk("mq200fb: setmqmode - before reset\n");
-+ regdata = SW_CHIP_RESET;
-+ REG32(DC_0, regdata);
-+ MQ_DELAY(10);
-+ /* use 50MHz for LCD only and 83MHz if CRT is on */
-+ if (pDC->flag & CRT_ON)
-+ regdata = PLL1_83MHZ;
-+ else
-+ regdata = PLL1_50MHZ;
-+ REG32(DC_0, regdata);
-+ MQ_DELAY(30);
-+
-+ /* Enter D0 state from reset D3 state */
-+
-+ REG32(PCI_PM_CNTL_STATUS, ENTER_D0);
-+ MQ_DELAY(30);
-+
-+ while(1)
-+ {
-+ if((READ32(PCI_PM_CNTL_STATUS) & POWER_STATE_MASK) == 0x0)
-+ break;
-+ }
-+
-+ /* In stable D3 state here ... */
-+ /*
-+ * Set up PMU misc registers
-+ * - also PMCLK_2048CYCLE and FP_PMCLK_128K if SA1110
-+ */
-+ if ((READ32(DC_1) & BUS_MODE_MASK) == BUS_MODE_SA1110)
-+ regdata = GE_ENABLE|GE_BY_PLL1|PMCLK_2048CYCLE|FP_PMCLK_512;
-+ else
-+ /* the rest of CPUs */
-+ regdata = GE_ENABLE|GE_BY_PLL1;
-+ REG32(PM_MISC, regdata);
-+
-+ REG32(D1_STATE, DEF_D1);
-+ REG32(D2_STATE, DEF_D2);
-+
-+ /* To initialize MIU block ... */
-+ REG32(MIU_CONTROL1, DRAM_RESET_DISABLE);
-+ MQ_DELAY(5);
-+
-+ REG32(MIU_CONTROL1, 0x00);
-+ MQ_DELAY(5);
-+
-+ if (pDC->flag & CRT_ON)
-+ regdata = DEF_MIU2_83MHZ;
-+ else
-+ regdata = DEF_MIU2_50MHZ;
-+ REG32(MIU_CONTROL2, regdata);
-+ REG32(MIU_CONTROL3, DEF_MIU3);
-+ /* MIU REG 5 MUST BE PROGRAMMED BEFORE MIU REG 4 */
-+ REG32(MIU_CONTROL5, DEF_MIU5);
-+ REG32(MIU_CONTROL4, DEF_MIU4);
-+ MQ_DELAY(5);
-+
-+ REG32(MIU_CONTROL1, MIU_ENABLE | MIU_RESET_DISABLE);
-+ MQ_DELAY(5);
-+
-+ /* Here, MIU is supposed to ready to serve ... */
-+
-+ gc_startaddr = 0;
-+ /* Last 1KB is reserved for hardware cursor */
-+ if (mqflag & ENA_HW_CURSOR)
-+ {
-+ printk("mq200fb: enabling hardware cursor\n");
-+ setup_cursor(pMQMMIO);
-+ enable_cursor(pMQMMIO);
-+
-+ }
-+ /* Set up GE Base Address */
-+ REG32(BASE_ADDRESS, gc_startaddr);
-+ /* Set up flat panel parameters
-+ *
-+ */
-+ paneltype = pDC->flag & PANEL_TYPE_MASK;
-+ if (paneltype)
-+ {
-+ /* Panel is used as a display in the system */
-+ setupfp(paneltype, pMQMMIO);
-+
-+ /* Set up DSTN half frame buffer */
-+ screensize = pDC->x * pDC->y * pDC->bpp / 8 + gc_startaddr;
-+ setuphfbuffer(paneltype, screensize, pMQMMIO);
-+
-+ /* Get flat panel frequency */
-+ freq = fpControlData[paneltype].freq;
-+ }
-+
-+ /* Based on display configuration, proper GC is set up .. */
-+ if (pDC->flag & LARGE_DESKTOP)
-+ {
-+ switch (pDC->flag & LCDCRT_POS_MASK)
-+ {
-+ case HORI_CRT_LCD:
-+ case HORI_LCD_CRT:
-+ x = pDC->x / 2;
-+ y = pDC->y;
-+ break;
-+
-+ case VERT_CRT_LCD:
-+ case VERT_LCD_CRT:
-+ x = pDC->x;
-+ y = pDC->y / 2;
-+ break;
-+ }
-+ }
-+ else
-+ {
-+ /* SAME_IMAGE and simultaneous LCD and/or CRT */
-+ x = pDC->x;
-+ y = pDC->y;
-+ }
-+
-+ /* Set up GC memory configuration */
-+ setupgcmem(pDC, gc_startaddr, pMQMMIO);
-+
-+ pmmisc = READ32(PM_MISC);
-+
-+ /* Set up 2 GCs */
-+ if (pDC->flag & USE_2GCs)
-+ {
-+ /* Set up GC1 for CRT */
-+ setupgc(IS_GC1, x, y, pDC->bpp, pDC->refresh, pMQMMIO);
-+
-+ /* Set up GC2 for flat panel */
-+ setupgc(IS_GC2, x, y, pDC->bpp, freq, pMQMMIO);
-+
-+ /* PLL2 and PLL3 are both used ... */
-+ /* to save a little bit power, can shut down PLL3 if both LCD
-+ and CRT are the same frequency...
-+ */
-+ pmmisc |= (PLL2_ENABLE | PLL3_ENABLE);
-+ REG32(PM_MISC, pmmisc);
-+
-+ /* Enable panel and CRT accordingly */
-+ if (pDC->flag & LCD_ON)
-+ onoffdisplay(ENABLE_LCD_GC2, pMQMMIO);
-+
-+ if (pDC->flag & CRT_ON)
-+ onoffdisplay(ENABLE_CRT_GC1, pMQMMIO);
-+ }
-+ else
-+ {
-+ /* Simultaneous mode - set up GC1 only */
-+ if (paneltype)
-+ setupgc(IS_GC1, x, y, pDC->bpp, freq, pMQMMIO);
-+ else
-+ setupgc(IS_GC1, x, y, pDC->bpp, pDC->refresh, pMQMMIO);
-+
-+ /* Use PLL2 */
-+ pmmisc |= PLL2_ENABLE;
-+ REG32(PM_MISC, pmmisc);
-+
-+ /* Enable panel and CRT accordingly */
-+ if (pDC->flag & LCD_ON)
-+ onoffdisplay(ENABLE_LCD_GC1, pMQMMIO);
-+
-+ if (pDC->flag & CRT_ON)
-+ onoffdisplay(ENABLE_CRT_GC1, pMQMMIO);
-+ }
-+}
-+
-+/* Set up flat panel register depending on panel type
-+ *
-+ */
-+void setupfp(int panel, void *pMQMMIO)
-+{
-+ PFPDATA_CONTROL pFP;
-+ int frcaddr, frcidx, i;
-+
-+ /* Locate panel data pointer */
-+ pFP = &fpControlData[panel];
-+ printk("FP_PIN_CONTROL set to %x\n", (u_int)pFP->fpPinControl);
-+ REG32(FP_CONTROL, pFP->fpControl);
-+ REG32(FP_PIN_CONTROL, pFP->fpPinControl);
-+ REG32(STN_CONTROL, pFP->stnControl);
-+ REG32(FP_GPO_CONTROL, DEF_GPO_CONTROL);
-+ REG32(FP_GPIO_CONTROL, DEF_GPIO_CONTROL);
-+ REG32(PWM_CONTROL, DEF_PWM_CONTROL);
-+
-+ /* Program FRC registers for STN panel (DSTN and SSTN) */
-+ frcidx = 0; /* DSTN */
-+ if ( (pFP->fpControl & FP_TYPE_MASK) != FP_TYPE_TFT )
-+ {
-+ if ((pFP->fpControl & FP_TYPE_MASK) == FP_TYPE_SSTN)
-+ frcidx++; /* SSTN index */
-+
-+ for ( i = frcaddr = 0; i < FRC_PATTERN_CNT; i++,frcaddr+=4 )
-+ REG32((FRC_PATTERN + frcaddr),
-+ FRCControlData[frcidx].frcPattern[i]);
-+
-+ for ( i = frcaddr = 0; i < FRC_WEIGHT_CNT; i++,frcaddr+=4 )
-+ REG32((FRC_WEIGHT + frcaddr), FRCControlData[frcidx].frcWeight[i]);
-+ }
-+
-+ /* Set up flat panel GPO and GPIO register from default */
-+ REG32(FP_GPO_CONTROL, DEF_GPO_CONTROL);
-+ REG32(FP_GPIO_CONTROL, DEF_GPIO_CONTROL);
-+
-+ return;
-+}
-+
-+/* Set up DSTN half frame buffer register depending on panel type
-+ *
-+ * panel : panel type
-+ * sizeused : used (occupied) area of frame buffer
-+ *
-+ */
-+void setuphfbuffer(int panel, unsigned long sizeused, void *pMQMMIO)
-+{
-+ PFPDATA_CONTROL pFP;
-+ unsigned long dstnfbsize, dstnstart, dstnend;
-+
-+ /* Locate panel data pointer */
-+ pFP = &fpControlData[panel];
-+
-+ /* Figure out half frame buffer for DSTN panel */
-+ if ( (pFP->fpControl & FP_TYPE_MASK) == FP_TYPE_DSTN )
-+ {
-+ /* Color D-STN memory requirement - no need to *3 for mono dstn panel */
-+ if (pFP->fpControl & FP_MONO)
-+ dstnfbsize = pFP->x;
-+ else
-+ dstnfbsize = pFP->x * 3;
-+ dstnfbsize = (((dstnfbsize + 127) >> 7) * pFP->y) << 3;
-+
-+ /* make it suitable for register bits definition */
-+ dstnstart = (sizeused + 127) >> 7;
-+ dstnend = (sizeused + dstnfbsize + 15) >> 4;
-+ REG32(DSTN_FB_CONTROL, (dstnstart | ((dstnend - 1) << 16)));
-+ }
-+ return;
-+}
-+
-+/* Set up graphics controller (GC1 or GC2) timing registers and PLLx
-+ *
-+ * gc: GC1 or GC2
-+ * x : horizontal viewport size
-+ * y : vertical viewport size
-+ * refresh : refresh rate (mainly VESA-supported mode)
-+ *
-+ */
-+void setupgc(int gc, int x, int y, int bpp, int refresh, void *pMQMMIO)
-+{
-+ PDISPLAY_TIMING pDT;
-+ unsigned long gccontrol;
-+
-+ /* Locate GC timing parameters first */
-+ pDT = getgcparam(x, y, refresh);
-+
-+ /* error checking for pDT here */
-+
-+ gccontrol = getbppbits(bpp) |
-+ FDx_1 | (1L << 24) |
-+ IM_ENABLE;
-+
-+ if (gc == IS_GC1)
-+ {
-+ /* Set up GC window as display */
-+ REG32(HW1_CONTROL, ((x - 1) << 16) | (1 << 28));
-+ REG32(VW1_CONTROL, ((y - 1) << 16));
-+
-+ REG32(HD1_CONTROL, pDT->hd);
-+ REG32(VD1_CONTROL, pDT->vd);
-+ REG32(HS1_CONTROL, pDT->hs);
-+ REG32(VS1_CONTROL, pDT->vs);
-+ REG32(VS1_CONTROL, pDT->vs);
-+ REG32(GC1_CRT_CONTROL, pDT->crtc);
-+
-+ /* Program PLL2 for GC1 */
-+ REG32(PLL2_CONTROL, pDT->pll);
-+
-+ /* GC1 control register */
-+ gccontrol |= GxRCLK_PLL2;
-+ REG32(GC1_CONTROL, gccontrol);
-+ }
-+ else
-+ if (gc == IS_GC2)
-+ {
-+ /* Set up GC window as display */
-+ REG32(HW2_CONTROL, ((x - 1) << 16));
-+ REG32(VW2_CONTROL, ((y - 1) << 16));
-+
-+ REG32(HD2_CONTROL, pDT->hd);
-+ REG32(VD2_CONTROL, pDT->vd);
-+ REG32(HS2_CONTROL, pDT->hs);
-+ REG32(VS2_CONTROL, pDT->vs);
-+ REG32(VS2_CONTROL, pDT->vs);
-+ REG32(GC1_CRT_CONTROL, pDT->crtc);
-+
-+ /* Program PLL3 for GC2 */
-+ REG32(PLL3_CONTROL, pDT->pll);
-+
-+ /* GC2 control register */
-+ gccontrol |= GxRCLK_PLL3;
-+ REG32(GC2_CONTROL, gccontrol);
-+ }
-+ return;
-+}
-+
-+/* Set up graphics controller (GC1 or GC2) memory configuration (stride and
-+ * starting address etc.)
-+ *
-+ * pDC : pointer to active DIPSLAY_CONFIG structure
-+ * startaddr : starting address - 0 if starting from very beginning
-+ *
-+ * - use GC1 for Simultaneous mode (1 GC)
-+ * - use GC1 for CRT and GC2 for LCD at QView mode
-+ *
-+ */
-+void setupgcmem(PDISPLAY_CONFIG pDC, unsigned long startaddr, void *pMQMMIO)
-+{
-+ unsigned long stride=0, start1=0, start2=0;
-+
-+ if (pDC->flag & LARGE_DESKTOP)
-+ {
-+ /* 4 possible layouts */
-+ switch (pDC->flag & LCDCRT_POS_MASK)
-+ {
-+ case HORI_CRT_LCD:
-+ stride = (pDC->x / 2) * pDC->bpp / 8;
-+ start1 = startaddr;
-+ start2 = startaddr + stride;
-+ break;
-+
-+ case HORI_LCD_CRT:
-+ stride = (pDC->x / 2) * pDC->bpp / 8;
-+ start1 = startaddr + stride;
-+ start2 = startaddr;
-+ break;
-+
-+ case VERT_CRT_LCD:
-+ stride = pDC->x * pDC->bpp / 8;
-+ start1 = startaddr;
-+ start2 = startaddr + stride * pDC->y / 2;
-+ break;
-+
-+ case VERT_LCD_CRT:
-+ stride = pDC->x * pDC->bpp / 8;
-+ start1 = startaddr + stride * pDC->y / 2;
-+ start2 = startaddr;
-+ break;
-+ }
-+
-+ /* Program to the chip */
-+ REG32(IW1_STRIDE, stride);
-+ REG32(IW2_STRIDE, stride);
-+
-+ REG32(IW1_START_ADDR, start1);
-+ REG32(IW2_START_ADDR, start2);
-+ }
-+ else
-+ {
-+ /* QView Same Image and Simultaneous LCD and/or CRT
-+ *
-+ * - set up 2 GCs in any cases ...
-+ * - 2 addidtional registers write vs. code size
-+ *
-+ */
-+
-+ /* Calculate stride */
-+ stride = pDC->x * pDC->bpp / 8;
-+
-+ REG32(IW1_STRIDE, stride);
-+ REG32(IW2_STRIDE, stride);
-+
-+ REG32(IW1_START_ADDR, startaddr);
-+ REG32(IW2_START_ADDR, startaddr);
-+ }
-+ return;
-+}
-+
-+/* Program palette entry
-+ *
-+ */
-+void setpal(int index, unsigned long color, void *pMQMMIO)
-+{
-+ /*PDEBUG("mq200fb: setpal. %d %d\n", index, color);*/
-+
-+ REG32_PAL(index, color);
-+}
-+
-+/* Vertical blank time is in progress ..
-+ *
-+ */
-+void invblank(void *pMQMMIO)
-+{
-+ unsigned long *intstat = (unsigned long *)(pMQMMIO+INT_STATUS_REG);
-+
-+ /* Make sure int occurs first */
-+ while ( !(*intstat & ST_GC1_VDE_F) );
-+
-+ /* Reset GC1 VDE F status bit - write 1 to clear the status */
-+ REG32(INT_STATUS_REG,ST_GC1_VDE_F);
-+
-+ /* Wait for next VDE falling edge for DAC access */
-+ while ( !(*intstat & ST_GC1_VDE_F) );
-+
-+ /* Here MQ200 should be in V blank period ... */
-+ return;
-+}
-+
-+/* Retrive graphics controller parameters from supported table
-+ *
-+ */
-+PDISPLAY_TIMING getgcparam(int x, int y, int refresh)
-+{
-+ int i;
-+
-+ for (i=0; i < MAX_MQMODE; i++)
-+ {
-+ if ( TimingParam[i].x == x
-+ && TimingParam[i].y == y
-+ && TimingParam[i].refresh == refresh )
-+ return ( (PDISPLAY_TIMING)&TimingParam[i] );
-+ }
-+ return (NULL); /* not existed */
-+}
-+
-+/* Return color depth setting for GC
-+ *
-+ */
-+unsigned long getbppbits(int bpp)
-+{
-+ unsigned long bppbits = 0;
-+
-+ switch(bpp)
-+ {
-+ case 8UL: bppbits = GC_8BPP; break;
-+ case 16UL: bppbits = GC_16BPP_BP; break;
-+ case 24UL: bppbits = GC_24BPP_BP; break;
-+ case 32UL: bppbits = GC_32BPP_ARGB_BP; break;
-+ case 4UL: bppbits = GC_4BPP; break;
-+ case 2UL: bppbits = GC_2BPP; break;
-+ case 1UL: bppbits = GC_1BPP; break;
-+ }
-+ return (bppbits);
-+}
-+
-+/* Turn on/off LCD or CRT driven by either GC1 or GC2
-+ *
-+ */
-+void onoffdisplay(int display_flag, void *pMQMMIO)
-+{
-+ unsigned long fpcontrol, gccontrol, crtcontrol;
-+
-+ switch (display_flag)
-+ {
-+ case ENABLE_LCD_GC1:
-+ /* Obtain current setting */
-+ fpcontrol = READ32(FP_CONTROL) & FPI_BY_GCxMASK;
-+ gccontrol = READ32(GC1_CONTROL);
-+
-+ /* Turn on GC1 first if remain disabled */
-+ if (!(gccontrol & GC_ENABLE))
-+ REG32(GC1_CONTROL, gccontrol | GC_ENABLE);
-+
-+ /* Flat panel controlled by GC1 */
-+ REG32(FP_CONTROL, fpcontrol | FPI_BY_GC1);
-+
-+#if defined(CONFIG_SA1100_GDS2200) || defined(CONFIG_SA1100_SIMPAD)
-+ mq200_backlight(pMQMMIO, 1);
-+#endif
-+
-+ break;
-+
-+ case ENABLE_LCD_GC2:
-+ /* Obtain current setting */
-+ fpcontrol = READ32(FP_CONTROL) & FPI_BY_GCxMASK;
-+ gccontrol = READ32(GC2_CONTROL);
-+
-+ /* Turn on GC1 first if remain disabled */
-+ if (!(gccontrol & GC_ENABLE))
-+ REG32(GC2_CONTROL, gccontrol | GC_ENABLE);
-+
-+ /* Flat panel controlled by GC1 */
-+ REG32(FP_CONTROL, fpcontrol | FPI_BY_GC2);
-+ break;
-+
-+ case DISABLE_LCD_GC1:
-+ /* Disable flat panel first */
-+ fpcontrol = READ32(FP_CONTROL) & FPI_BY_GCxMASK;
-+ REG32(FP_CONTROL, fpcontrol);
-+
-+ crtcontrol = READ32(GC1_CRT_CONTROL) & (~CRT_BY_GCxMASK);
-+#if defined(CONFIG_SA1100_GDS2200) || defined(CONFIG_SA1100_SIMPAD)
-+ mq200_backlight(pMQMMIO, 0);
-+#endif
-+
-+ /* Disable GC1 if not used for CRT */
-+ if (!(crtcontrol == CRT_BY_GC1))
-+ {
-+ gccontrol = READ32(GC1_CONTROL);
-+ REG32(GC1_CONTROL, gccontrol & GC_DISABLE);
-+ }
-+ break;
-+
-+ case DISABLE_LCD_GC2:
-+ /* Disable flat panel first */
-+ fpcontrol = READ32(FP_CONTROL) & FPI_BY_GCxMASK;
-+ REG32(FP_CONTROL, fpcontrol);
-+
-+ crtcontrol = READ32(GC1_CRT_CONTROL) & (~CRT_BY_GCxMASK);
-+
-+ /* Disable GC2 if not used for CRT */
-+ if (!(crtcontrol == CRT_BY_GC2))
-+ {
-+ gccontrol = READ32(GC2_CONTROL);
-+ REG32(GC2_CONTROL, gccontrol & GC_DISABLE);
-+ }
-+ break;
-+
-+ case ENABLE_CRT_GC1:
-+ /* Enable GC1 if not yet enabled */
-+ gccontrol = READ32(GC1_CONTROL);
-+ if (!(gccontrol & GC_ENABLE))
-+ REG32(GC1_CONTROL, gccontrol | GC_ENABLE);
-+
-+ /* Enable CRT by GC1 */
-+ crtcontrol = READ32(GC1_CRT_CONTROL) & CRT_BY_GCxMASK;
-+ REG32(GC1_CRT_CONTROL, crtcontrol | CRT_BY_GC1);
-+ break;
-+
-+ case ENABLE_CRT_GC2:
-+ /* Enable GC2 if not yet enabled */
-+ gccontrol = READ32(GC2_CONTROL);
-+ if (!(gccontrol & GC_ENABLE))
-+ REG32(GC2_CONTROL, gccontrol | GC_ENABLE);
-+
-+ /* Enable CRT by GC2 */
-+ crtcontrol = READ32(GC1_CRT_CONTROL) & CRT_BY_GCxMASK;
-+ REG32(GC1_CRT_CONTROL, crtcontrol | CRT_BY_GC2);
-+ break;
-+
-+ case DISABLE_CRT_GC1:
-+ /* Disable CRT first */
-+ crtcontrol = READ32(GC1_CRT_CONTROL) & CRT_BY_GCxMASK;
-+ REG32(GC1_CRT_CONTROL, crtcontrol);
-+
-+ fpcontrol = READ32(FP_CONTROL) & (~FPI_BY_GCxMASK);
-+
-+ /* Disable GC1 if not used for CRT */
-+ if (!(crtcontrol == CRT_BY_GC1))
-+ {
-+ gccontrol = READ32(GC1_CONTROL);
-+ REG32(GC1_CONTROL, gccontrol & GC_DISABLE);
-+ }
-+ break;
-+
-+ case DISABLE_CRT_GC2:
-+ /* Disable CRT first */
-+ crtcontrol = READ32(GC1_CRT_CONTROL) & CRT_BY_GCxMASK;
-+ REG32(GC1_CRT_CONTROL, crtcontrol);
-+
-+ fpcontrol = READ32(FP_CONTROL) & (~FPI_BY_GCxMASK);
-+
-+ /* Disable GC2 if not used for CRT */
-+ if (!(crtcontrol == CRT_BY_GC2))
-+ {
-+ gccontrol = READ32(GC2_CONTROL);
-+ REG32(GC2_CONTROL, gccontrol & GC_DISABLE);
-+ }
-+ break;
-+ }
-+ return;
-+}
-+
-+/* Setup hardware cursor data area start address in the frame buffer
-+ *
-+ */
-+void setup_cursor(void *pMQMMIO)
-+{
-+ REG32(HW_CURSOR1_FGCLR, CURSOR_FGCLR);
-+ REG32(HW_CURSOR2_FGCLR, CURSOR_FGCLR);
-+ REG32(HW_CURSOR1_BGCLR, CURSOR_BGCLR);
-+ REG32(HW_CURSOR2_BGCLR, CURSOR_BGCLR);
-+ REG32(HW_CURSOR1_ADDR, 0x000007ff);
-+ REG32(HW_CURSOR2_ADDR, 0x000007ff);
-+}
-+
-+/* Move cursor position and adjust hot spot offset
-+ *
-+ */
-+void move_cursor(unsigned long pos, unsigned long addr, void *pMQMMIO)
-+{
-+ REG32(HW_CURSOR1_POS, pos);
-+ REG32(HW_CURSOR2_POS, pos);
-+}
-+
-+/* Enable hardware cursor
-+ *
-+ */
-+void enable_cursor(void *pMQMMIO)
-+{
-+ u32 temp;
-+
-+ temp = READ32(GC1_CONTROL) | HC_ENABLE;
-+ REG32(GC1_CONTROL, temp);
-+ if (mqflag & USE_2GCs)
-+ {
-+ temp = READ32(GC2_CONTROL) | HC_ENABLE;
-+ REG32(GC2_CONTROL, temp);
-+ }
-+}
-+
-+/* Disable hardware cursor
-+ *
-+ */
-+void disable_cursor(void *pMQMMIO)
-+{
-+ u32 temp;
-+
-+ temp = READ32(GC1_CONTROL) & HC_DISABLE;
-+ REG32(GC1_CONTROL, temp);
-+ if (mqflag & USE_2GCs)
-+ {
-+ temp = READ32(GC2_CONTROL) & HC_DISABLE;
-+ REG32(GC2_CONTROL, temp);
-+ }
-+}
-+/* The above is copied from mq2hw.c for initialization of MQ200 */
-+
-+void turnoffMQ200(void * pMQMMIO)
-+{
-+ volatile u32 temp;
-+
-+ temp = READ32(FP_CONTROL);
-+ temp &=0xfffffffc;
-+ REG32(FP_CONTROL, temp);
-+ udelay(5000);
-+ temp =READ32(FP_CONTROL) & 0x3;
-+ if(temp != 0)
-+ PDEBUG("FP_CONTROL is not cleared properly");
-+ else
-+ PDEBUG("FP_CONTROL is cleared properly");
-+
-+ temp = READ32(FP_PIN_CONTROL);
-+ temp |= 0x1;
-+ REG32(FP_PIN_CONTROL, temp);
-+ udelay(5000);
-+
-+ temp = READ32(GC1_CONTROL);
-+ temp &=0xfffffffe;
-+ REG32(GC1_CONTROL, temp);
-+ udelay(5000);
-+ temp = READ32(GC1_CONTROL) & 0x1;
-+ if(temp != 0)
-+ PDEBUG("GC1_CONTROL is not cleared properly");
-+ else
-+ PDEBUG("GC1_CONTROL is cleared properly");
-+
-+ temp = READ32(GC1_CRT_CONTROL);
-+ temp &=0xfffffffe;
-+ REG32(GC1_CRT_CONTROL, temp);
-+ udelay(5000);
-+
-+ temp = READ32(GC2_CONTROL);
-+ temp &=0xfffffffe;
-+ REG32(GC2_CONTROL, temp);
-+ udelay(5000);
-+ temp = READ32(GC2_CONTROL) & 0x1;
-+ if(temp != 0)
-+ PDEBUG("GC2_CONTROL is not cleared properly");
-+ else
-+ PDEBUG("GC2_CONTROL is cleared properly");
-+
-+ return;
-+}
-+
-+#ifdef CONFIG_PM
-+/*
-+ * Power management hook. Note that we won't be called from IRQ context,
-+ * unlike the blank functions above, so we may sleep.
-+ */
-+static int
-+mq200fb_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data)
-+{
-+ struct fb_info_mq200 *p = (struct fb_info_mq200 *) pm_dev->data;
-+ void * pMQMMIO = (void *) p->mqMmioAddrVirt;
-+
-+ if (req == PM_SUSPEND){
-+
-+ onoffdisplay(DISABLE_LCD_GC1, pMQMMIO);
-+ REG32(PCI_PM_CNTL_STATUS, ENTER_D3);
-+ MQ_DELAY(30);
-+ }
-+ if( req == PM_RESUME){
-+ setmqmode(&dc, pMQMMIO);
-+ onoffdisplay(ENABLE_LCD_GC1, pMQMMIO);
-+ REG32(PCI_PM_CNTL_STATUS, ENTER_D0);
-+ MQ_DELAY(30);
-+ }
-+
-+ return 0;
-+}
-+#endif
-+
-+#if defined(CONFIG_SA1100_GDS2200) || defined(CONFIG_SA1100_SIMPAD)
-+
-+static void mq200_backlight(void *pMQMMIO, int flag)
-+{
-+
-+#ifdef CONFIG_SA1100_GDS2200
-+ unsigned long gpiocontrol, data;
-+ int i;
-+
-+ gpiocontrol = READ32(FP_GPIO_CONTROL) & 0x3f;
-+ data = (flag ? GPIO2_OUT_HIGH : 0);
-+ for(i = 0 ; i < 128 ; i++) {
-+ REG32(FP_GPIO_CONTROL, gpiocontrol | data);
-+ MQ_DELAY(1);
-+ REG32(FP_GPIO_CONTROL, gpiocontrol | GPIO1_OUT_HIGH | data);
-+ MQ_DELAY(1);
-+ REG32(FP_GPIO_CONTROL, gpiocontrol);
-+ MQ_DELAY(1);
-+ }
-+
-+#endif /* CONFIG_SA1100_GDS2200 */
-+
-+#ifdef CONFIG_SA1100_SIMPAD
-+
-+ if(flag)
-+ set_cs3_bit(DISPLAY_ON);
-+ else
-+ clear_cs3_bit(DISPLAY_ON);
-+
-+#endif /* CONFIG_SA1100_SIMPAD */
-+
-+}
-+#endif /* CONFIG_SA1100_GDS2200 || CONFIG_SA1100_SIMPAD */
-+
-+#ifdef CONFIG_SA1100_SIMPAD
-+
-+static void writeBrightness(void *pMQMMIO, int brightness)
-+{
-+ unsigned long dutyCycle, pwmcontrol;
-+ int MAX_BRIGHT_REG = 0x000000fc; /* int 254 */
-+
-+ if(brightness > MAX_BRIGHT_REG)
-+ return;
-+ else
-+ {
-+ /*
-+ *Determine dutyCycle.
-+ *Note: the lower the value, the brighter the display!
-+ */
-+
-+ dutyCycle = MAX_BRIGHT_REG - brightness;
-+
-+ /*
-+ *Configure PWM0 (source clock = oscillator clock, pwm always enabled,
-+ *zero, clock pre-divider = 4) pwm frequency = 12.0kHz
-+ */
-+ pwmcontrol = READ32(PWM_CONTROL);
-+ REG32(PWM_CONTROL, 0x00000044 | (pwmcontrol & 0xffffff00));
-+
-+
-+ /* Write to pwm duty cycle register. */
-+
-+ REG32(PWM_CONTROL, ((dutyCycle << 8) & 0x0000ff00) |
-+ (pwmcontrol & 0xffff00ff));
-+ }
-+}
-+
-+#endif /* CONFIG_SA1100_SIMPAD */
-+
-+static int proc_read_reg(struct file * file, char * buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ int i_ino = (file->f_dentry->d_inode)->i_ino;
-+ char outputbuf[15];
-+ int count;
-+ int i;
-+ mq200_reg_entry_t* current_reg=NULL;
-+ if (*ppos>0) /* Assume reading completed in previous read*/
-+ return 0;
-+ for (i=0;i<NUM_OF_MQ200_REG_ENTRY;i++) {
-+ if (mq200_regs[i].low_ino==i_ino) {
-+ current_reg = &mq200_regs[i];
-+ break;
-+ }
-+ }
-+ if (current_reg==NULL)
-+ return -EINVAL;
-+
-+ count = sprintf(outputbuf, "0x%08X\n",
-+ *((volatile *) mq200_p2v(current_reg->phyaddr)));
-+ *ppos+=count;
-+ if (count>nbytes) /* Assume output can be read at one time */
-+ return -EINVAL;
-+ if (copy_to_user(buf, outputbuf, count))
-+ return -EFAULT;
-+ return count;
-+}
-+
-+static ssize_t proc_write_reg(struct file * file, const char * buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ int i_ino = (file->f_dentry->d_inode)->i_ino;
-+ mq200_reg_entry_t* current_reg=NULL;
-+ int i;
-+ unsigned long newRegValue;
-+ char *endp;
-+
-+ for (i=0;i<NUM_OF_MQ200_REG_ENTRY;i++) {
-+ if (mq200_regs[i].low_ino==i_ino) {
-+ current_reg = &mq200_regs[i];
-+ break;
-+ }
-+ }
-+ if (current_reg==NULL)
-+ return -EINVAL;
-+
-+ newRegValue = simple_strtoul(buffer,&endp,0);
-+ *((volatile *) mq200_p2v(current_reg->phyaddr))=newRegValue;
-+ return (count+endp-buffer);
-+}
-+
---- linux-2.4.25/include/asm-arm/arch-sa1100/simpad.h~2.4.25-vrs2-pxa1-jpm1.patch 2002-08-03 02:39:45.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-sa1100/simpad.h 2004-05-02 22:45:42.000000000 +0200
-@@ -28,6 +28,7 @@
- #define GPIO_UART3_DCD GPIO_GPIO18
- #define GPIO_UART3_DSR GPIO_GPIO17
-
-+#define GPIO_POWER_BUTTON GPIO_GPIO0
- #define GPIO_UCB1300_IRQ GPIO_GPIO (22) /* UCB GPIO and touchscreen */
-
- #define IRQ_UART1_CTS IRQ_GPIO15
-@@ -37,7 +38,12 @@
- #define IRQ_UART3_DCD GPIO_GPIO18
- #define IRQ_UART3_DSR GPIO_GPIO17
-
--#define IRQ_GPIO_UCB1300_IRQ IRQ_GPIO22
-+#define IRQ_GPIO_UCB1300_IRQ IRQ_GPIO22
-+#define IRQ_GPIO_POWER_BUTTON IRQ_GPIO0
-+
-+/*--- SmartCard ---*/
-+#define GPIO_SMART_CARD GPIO_GPIO10
-+#define IRQ_GPIO_SMART_CARD IRQ_GPIO10
-
- /*--- PCMCIA ---*/
- #define GPIO_CF_CD GPIO_GPIO24
-@@ -65,7 +71,7 @@
- #define LED2_ON 0x1000
- #define IRDA_MODE 0x2000 // Fast/Slow IrDA mode
- #define ENABLE_5V 0x4000 // Enable 5V circuit
--#define RESET_SIMCARD 0x8000
-+#define nRESET_SIMCARD 0x8000
-
- #define RS232_ENABLE 0x0440
- #define PCMCIAMASK 0x402f
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-sa1100/simpad_pm.h 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,236 @@
-+/*
-+* Abstraction interface for microcontroller connection to rest of system
-+*
-+* Copyright 2003 Peter Pregler
-+* Copyright 2000,1 Compaq Computer Corporation.
-+*
-+* Use consistent with the GNU GPL is permitted,
-+* provided that this copyright notice is
-+* preserved in its entirety in all copies and derived works.
-+*
-+* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED,
-+* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS
-+* FITNESS FOR ANY PARTICULAR PURPOSE.
-+*
-+* Author: Peter Pregler (based on work for ipaq by Andrew Christian)
-+*
-+*/
-+
-+#ifndef __SIMPAD_HAL_H
-+#define __SIMPAD_HAL_H
-+
-+extern int simpad_apm_get_power_status(unsigned char *ac_line_status, unsigned char *battery_status,
-+ unsigned char *battery_flag, unsigned char *battery_percentage,
-+ unsigned short *battery_life);
-+
-+
-+struct simpad_battery {
-+ unsigned char ac_status; /* line connected yes/no */
-+ unsigned char status; /* battery loading yes/no */
-+ unsigned char percentage; /* percentage loaded */
-+ unsigned short life; /* life till empty */
-+};
-+
-+extern int simpad_get_battery(struct simpad_battery *bstat);
-+
-+/* These should match the apm_bios.h definitions */
-+#define SIMPAD_AC_STATUS_AC_OFFLINE 0x00
-+#define SIMPAD_AC_STATUS_AC_ONLINE 0x01
-+#define SIMPAD_AC_STATUS_AC_BACKUP 0x02 /* What does this mean? */
-+#define SIMPAD_AC_STATUS_AC_UNKNOWN 0xff
-+
-+/* These bitfields are rarely "or'd" together */
-+#define SIMPAD_BATT_STATUS_HIGH 0x01
-+#define SIMPAD_BATT_STATUS_LOW 0x02
-+#define SIMPAD_BATT_STATUS_CRITICAL 0x04
-+#define SIMPAD_BATT_STATUS_CHARGING 0x08
-+#define SIMPAD_BATT_STATUS_CHARGE_MAIN 0x10
-+#define SIMPAD_BATT_STATUS_DEAD 0x20 /* Battery will not charge */
-+#define SIMPAD_BATT_NOT_INSTALLED 0x20 /* For expansion pack batteries */
-+#define SIMPAD_BATT_STATUS_FULL 0x40 /* Battery fully charged (and connected to AC) */
-+#define SIMPAD_BATT_STATUS_NOBATT 0x80
-+#define SIMPAD_BATT_STATUS_UNKNOWN 0xff
-+
-+#if FIXME
-+#include <linux/simpad_ts.h>
-+
-+enum simpad_asset_type {
-+ ASSET_TCHAR = 0,
-+ ASSET_SHORT,
-+ ASSET_LONG
-+};
-+
-+#define TTYPE(_type) (((unsigned int)_type) << 8)
-+#define TCHAR(_len) (TTYPE(ASSET_TCHAR) | (_len))
-+#define TSHORT TTYPE(ASSET_SHORT)
-+#define TLONG TTYPE(ASSET_LONG)
-+#define ASSET(_type,_num) ((((unsigned int)_type)<<16) | (_num))
-+
-+#define ASSET_HM_VERSION ASSET( TCHAR(10), 0 ) /* 1.1, 1.2 */
-+#define ASSET_SERIAL_NUMBER ASSET( TCHAR(40), 1 ) /* Unique iPAQ serial number */
-+#define ASSET_MODULE_ID ASSET( TCHAR(20), 2 ) /* E.g., "iPAQ 3700" */
-+#define ASSET_PRODUCT_REVISION ASSET( TCHAR(10), 3 ) /* 1.0, 2.0 */
-+#define ASSET_PRODUCT_ID ASSET( TSHORT, 4 ) /* 2 = Palm-sized computer */
-+#define ASSET_FRAME_RATE ASSET( TSHORT, 5 )
-+#define ASSET_PAGE_MODE ASSET( TSHORT, 6 ) /* 0 = Flash memory */
-+#define ASSET_COUNTRY_ID ASSET( TSHORT, 7 ) /* 0 = USA */
-+#define ASSET_IS_COLOR_DISPLAY ASSET( TSHORT, 8 ) /* Boolean, 1 = yes */
-+#define ASSET_ROM_SIZE ASSET( TSHORT, 9 ) /* 16, 32 */
-+#define ASSET_RAM_SIZE ASSET( TSHORT, 10 ) /* 32768 */
-+#define ASSET_HORIZONTAL_PIXELS ASSET( TSHORT, 11 ) /* 240 */
-+#define ASSET_VERTICAL_PIXELS ASSET( TSHORT, 12 ) /* 320 */
-+
-+#define ASSET_TYPE(_asset) (((_asset)&0xff000000)>>24)
-+#define ASSET_TCHAR_LEN(_asset) (((_asset)&0x00ff0000)>>16)
-+#define ASSET_NUMBER(_asset) ((_asset)&0x0000ffff)
-+
-+#define MAX_TCHAR_LEN 40
-+
-+struct simpad_asset {
-+ unsigned int type;
-+ union {
-+ unsigned char tchar[ MAX_TCHAR_LEN ];
-+ unsigned short vshort;
-+ unsigned long vlong;
-+ } a;
-+};
-+
-+/********************************************************************
-+ * Interface to the hardware-type specific functions
-+ *
-+ * get_version Read the version number of the microcontroller on the option pack SPI bus
-+ * spi_read Reads from the serial EEPROM memory on the option pack SPI bus
-+ * spi_write Write to the serial EEPROM memory on the option pack SPI bus
-+ * get_option_detect Returns whether or not an option pack is present
-+ *
-+ * get_thermal_sensor Return measured temperature of the unit, in units of 0.125 deg C
-+ * set_notify_led Turns on, off, or blinks the Green LED
-+ * read_light_sensor Returns the value of the front light sensor
-+ * get_battery Returns the current voltage and charging state of all batteries
-+ * audio_clock Sets the audio CODEC to run at a particular rate
-+ * audio_power Turns on/off audio CODEC (internally calls audio_clock)
-+ * audio_mute Mutes the audio CODEC
-+ * asset_read Extracts PocketPC-style asset information from persistent memory
-+ * backlight_control Adjusts the backlight level (only on/off for 3100)
-+ *
-+ *
-+ * iPAQ 3100 only
-+ * ==============
-+ * codec_control Reset/mute/control level of 3100 audio codec
-+ * contrast_control Adjusts the contrast level (only for 3100)
-+ *
-+ * iPAQ 3600, 3700 only
-+ * ====================
-+ * eeprom_read Reads from the asset information on the eeprom of a 3600 (deprecated)
-+ * eeprom_write Writes to the asset information on the eeprom (deprecated)
-+ *
-+ * The interfaces to the EEPROM functions are maintained only because the simpad_ts driver has
-+ * a deprecated ioctl call for them. They are used internally by the "asset_read" function.
-+ *
-+ * iPAQ 3800, 3900 only
-+ * ====================
-+ * set_ebat Tells enhanced PCMCIA sleeves that this iPAQ can handle
-+ * a wider voltage range (applies to 3800, 3900)
-+ *
-+ *********************************************************************/
-+
-+struct simpad_hal_ops {
-+ /* Functions provided by the underlying hardware */
-+ int (*get_version)( struct simpad_ts_version * );
-+ int (*eeprom_read)( unsigned short address, unsigned char *data, unsigned short len );
-+ int (*eeprom_write)( unsigned short address, unsigned char *data, unsigned short len );
-+ int (*get_thermal_sensor)( unsigned short * );
-+ int (*set_notify_led)( unsigned char mode, unsigned char duration,
-+ unsigned char ontime, unsigned char offtime );
-+ int (*read_light_sensor)( unsigned char *result );
-+ int (*get_battery)( struct simpad_battery * );
-+ int (*spi_read)( unsigned short address, unsigned char *data, unsigned short len );
-+ int (*spi_write)( unsigned short address, unsigned char *data, unsigned short len );
-+ int (*codec_control)( unsigned char, unsigned char );
-+ int (*get_option_detect)( int *result );
-+ int (*audio_clock)( long samplerate );
-+ int (*audio_power)( long samplerate );
-+ int (*audio_mute)( int mute );
-+ int (*asset_read)( struct simpad_asset *asset );
-+ int (*set_ebat)( void );
-+
-+ /* Functions indirectly provided by the underlying hardware */
-+ int (*backlight_control)( enum flite_pwr power, unsigned char level );
-+ int (*contrast_control)( unsigned char level );
-+
-+ /* for module use counting */
-+ struct module *owner;
-+};
-+
-+/* Used by the device-specific hardware module to register itself */
-+extern int simpad_hal_register_interface( struct simpad_hal_ops *ops );
-+extern void simpad_hal_unregister_interface( struct simpad_hal_ops *ops );
-+
-+/*
-+ * Calls into HAL from the device-specific hardware module
-+ * These run at interrupt time
-+ */
-+extern void simpad_hal_keypress( unsigned char key );
-+extern void simpad_hal_touchpanel( unsigned short x, unsigned short y, int down );
-+extern void simpad_hal_option_detect( int present );
-+
-+/* Callbacks registered by device drivers */
-+struct simpad_driver_ops {
-+ void (*keypress)( unsigned char key );
-+ void (*touchpanel)( unsigned short x, unsigned short y, int down );
-+ void (*option_detect)( int present );
-+};
-+
-+extern int simpad_hal_register_driver( struct simpad_driver_ops * );
-+extern void simpad_hal_unregister_driver( struct simpad_driver_ops * );
-+
-+
-+/* Calls into HAL from device drivers and other kernel modules */
-+extern void simpad_get_flite( struct simpad_ts_backlight *bl );
-+extern void simpad_get_contrast( unsigned char *contrast );
-+extern int simpad_set_flite( enum flite_pwr pwr, unsigned char brightness );
-+extern int simpad_set_contrast( unsigned char contrast );
-+extern int simpad_toggle_frontlight( void );
-+
-+extern int simpad_apm_get_power_status(unsigned char *ac_line_status, unsigned char *battery_status,
-+ unsigned char *battery_flag, unsigned char *battery_percentage,
-+ unsigned short *battery_life);
-+
-+extern struct simpad_hal_ops *simpad_hal_ops;
-+
-+/* Do not use this macro in driver files - instead, use the inline functions defined below */
-+#define CALL_HAL( f, args... ) \
-+ { int __result = -EIO; \
-+ if ( simpad_hal_ops && simpad_hal_ops->f ) { \
-+ __MOD_INC_USE_COUNT(simpad_hal_ops->owner); \
-+ __result = simpad_hal_ops->f(args); \
-+ __MOD_DEC_USE_COUNT(simpad_hal_ops->owner); \
-+ } \
-+ return __result; }
-+
-+#define HFUNC static __inline__ int
-+
-+/* The eeprom_read/write address + len has a maximum value of 512. Both must be even numbers */
-+HFUNC simpad_eeprom_read( u16 addr, u8 *data, u16 len ) CALL_HAL(eeprom_read,addr,data,len)
-+HFUNC simpad_eeprom_write( u16 addr, u8 *data, u16 len) CALL_HAL(eeprom_write,addr,data,len)
-+HFUNC simpad_spi_read( u8 addr, u8 *data, u16 len) CALL_HAL(spi_read,addr,data,len)
-+HFUNC simpad_spi_write( u8 addr, u8 *data, u16 len) CALL_HAL(spi_write,addr,data,len)
-+HFUNC simpad_get_version( struct simpad_ts_version *v ) CALL_HAL(get_version,v)
-+HFUNC simpad_get_thermal_sensor( u16 *thermal ) CALL_HAL(get_thermal_sensor,thermal)
-+HFUNC simpad_set_led( u8 mode, u8 dur, u8 ont, u8 offt ) CALL_HAL(set_notify_led, mode, dur, ont, offt)
-+HFUNC simpad_get_light_sensor( u8 *result ) CALL_HAL(read_light_sensor,result)
-+HFUNC simpad_get_battery( struct simpad_battery *bat ) CALL_HAL(get_battery,bat)
-+HFUNC simpad_get_option_detect( int *result) CALL_HAL(get_option_detect,result)
-+HFUNC simpad_audio_clock( long samplerate ) CALL_HAL(audio_clock,samplerate)
-+HFUNC simpad_audio_power( long samplerate ) CALL_HAL(audio_power,samplerate)
-+HFUNC simpad_audio_mute( int mute ) CALL_HAL(audio_mute,mute)
-+HFUNC simpad_asset_read( struct simpad_asset *asset ) CALL_HAL(asset_read,asset)
-+HFUNC simpad_set_ebat( void ) CALL_HAL(set_ebat)
-+
-+/* Don't use these functions directly - rather, call {get,set}_{flite,contrast} */
-+ /* Functions indirectly provided by the underlying hardware */
-+HFUNC simpad_backlight_control( enum flite_pwr p, u8 v ) CALL_HAL(backlight_control,p,v)
-+HFUNC simpad_contrast_control( u8 level ) CALL_HAL(contrast_control,level)
-+
-+#endif
-+#endif
---- linux-2.4.25/include/linux/apm_bios.h~2.4.25-vrs2-pxa1-jpm1.patch 2003-08-25 13:44:44.000000000 +0200
-+++ linux-2.4.25/include/linux/apm_bios.h 2004-05-02 22:45:42.000000000 +0200
-@@ -216,4 +216,19 @@
- #define APM_IOC_STANDBY _IO('A', 1)
- #define APM_IOC_SUSPEND _IO('A', 2)
-
-+#define APM_AC_OFFLINE 0
-+#define APM_AC_ONLINE 1
-+#define APM_AC_BACKUP 2
-+#define APM_AC_UNKNOWN 0xFF
-+
-+#define APM_BATTERY_STATUS_HIGH 0
-+#define APM_BATTERY_STATUS_LOW 1
-+#define APM_BATTERY_STATUS_CRITICAL 2
-+#define APM_BATTERY_STATUS_CHARGING 3
-+#define APM_BATTERY_STATUS_UNKNOWN 0xFF
-+
-+#define APM_BATTERY_LIFE_UNKNOWN 0xFFFF
-+#define APM_BATTERY_LIFE_MINUTES 0x8000
-+#define APM_BATTERY_LIFE_VALUE_MASK 0x7FFF
-+
- #endif /* LINUX_APM_H */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/linux/switches.h 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,74 @@
-+/*
-+ * linux/include/linux/switches.h
-+ *
-+ * Copyright (C) 2000 John Dorsey
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 23 October 2000 - created.
-+ */
-+
-+#if !defined(_LINUX_SWITCHES_H)
-+#define _LINUX_SWITCHES_H
-+
-+#define SWITCHES_MASK_SIZE (128)
-+
-+typedef unsigned long switches_bitfield;
-+
-+#define SWITCHES_BITS (sizeof(switches_bitfield) * 8)
-+#define SWITCHES_NUM_FIELDS (SWITCHES_MASK_SIZE / SWITCHES_BITS)
-+#define SWITCHES_FIELD_SELECT(i) ((i) / SWITCHES_BITS)
-+#define SWITCHES_FIELD_MASK(i) ((switches_bitfield)(1 << (i) % \
-+ SWITCHES_BITS))
-+
-+typedef struct switches_mask_t {
-+ unsigned int count;
-+ switches_bitfield events[SWITCHES_NUM_FIELDS];
-+ switches_bitfield states[SWITCHES_NUM_FIELDS];
-+} switches_mask_t;
-+
-+#define SWITCHES_ZERO(m) \
-+do { \
-+ unsigned int sz_i; \
-+ (m)->count = 0; \
-+ for(sz_i = 0; sz_i < SWITCHES_NUM_FIELDS; ++sz_i) \
-+ (m)->events[sz_i] = (m)->states[sz_i] = 0; \
-+} while (0)
-+
-+/* `s' is the state of the switch, either 0 or non-zero: */
-+#define SWITCHES_SET(m, i, s) \
-+do { \
-+ ((m)->events[SWITCHES_FIELD_SELECT((i))] |= \
-+ SWITCHES_FIELD_MASK((i))); \
-+ if(s) \
-+ ((m)->states[SWITCHES_FIELD_SELECT((i))] |= \
-+ SWITCHES_FIELD_MASK((i))); \
-+ else \
-+ ((m)->states[SWITCHES_FIELD_SELECT((i))] &= \
-+ ~SWITCHES_FIELD_MASK((i))); \
-+ ++((m)->count); \
-+} while (0)
-+
-+/* Should only use to clear an event set by SWITCHES_SET(): */
-+#define SWITCHES_CLEAR(m, i) \
-+do { \
-+ ((m)->events[SWITCHES_FIELD_SELECT((i))] &= \
-+ ~SWITCHES_FIELD_MASK((i))); \
-+ ((m)->states[SWITCHES_FIELD_SELECT((i))] &= \
-+ ~SWITCHES_FIELD_MASK((i))); \
-+ --((m)->count); \
-+}
-+
-+#define SWITCHES_COUNT(m) ((m)->count)
-+
-+/* Returns 0 or non-zero: */
-+#define SWITCHES_EVENT(m, i) \
-+((m)->events[SWITCHES_FIELD_SELECT((i))] & SWITCHES_FIELD_MASK((i)))
-+
-+/* Returns 0 or non-zero: */
-+#define SWITCHES_STATE(m, i) \
-+((m)->states[SWITCHES_FIELD_SELECT((i))] & SWITCHES_FIELD_MASK((i)))
-+
-+#endif /* !defined(_LINUX_SWITCHES_H) */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/video/MQ200/mq2ge.h 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,81 @@
-+#ifndef _VIDEO_MQ200_MQ2GE_H
-+#define _VIDEO_MQ200_MQ2GE_H
-+
-+
-+/* Misc. GE Function Macro */
-+#undef CHECK_SRCFIFO
-+#define RGB_RASTER_CHECK
-+#define INCLUDE_GENERIC_CODE
-+
-+#ifdef CHECK_SRCFIFO
-+#define geWAITSRCFIFO(cnt) geWaitSrcFIFO(cnt)
-+#define geWAITCMDFIFO(cnt) geWaitCmdFIFO(cnt)
-+#define geWAITNOTBUSY() geWaitNotBusy()
-+#else
-+#define geWAITSRCFIFO(cnt)
-+#define geWAITCMDFIFO(cnt)
-+#define geWAITNOTBUSY()
-+#endif
-+
-+/* Additional UGL Raster Ops */
-+#define UGL_RASTER_OP_NOP 0x00000000L
-+
-+#define UGL_RASTER_OP_BLACKNESS 0x00000001L
-+#define UGL_RASTER_OP_BSRC_BLACK 0x00000002L
-+#define UGL_RASTER_OP_BSRC_OCOPY 0x00000003L
-+#define UGL_RASTER_OP_BSRC_XCOPY 0x00000004L
-+
-+#define UGL_RASTER_OP_WHITENESS 0x00010001L
-+#define UGL_RASTER_OP_WSRC_COPY 0x00010002L
-+#define UGL_RASTER_OP_WSRC_WHITE 0x00010003L
-+#define UGL_RASTER_OP_WSRC_INVERT 0x00010004L
-+
-+#define UGL_RASTER_OP_SRC_COPY 0x00020001L
-+#define UGL_RASTER_OP_SRCDEST_AND 0x00020002L
-+#define UGL_RASTER_OP_SRCDEST_OR 0x00020003L
-+#define UGL_RASTER_OP_SRCDEST_XOR 0x00020004L
-+
-+#define UGL_RASTER_OP_DEST_COPY 0x00030001L
-+#define UGL_RASTER_OP_DESTSRC_AND 0x00030002L
-+#define UGL_RASTER_OP_DESTSRC_OR 0x00030003L
-+#define UGL_RASTER_OP_DESTSRC_XOR 0x00030004L
-+
-+/* MediaQ Raster Ops */
-+#define MQ200_SOURCE_ROP 0x01
-+#define MQ200_PATTERN_ROP 0x02
-+#define MQ200_GE_NOP 0x000000AAL
-+#define MQ200_GE_BLACKNESS 0x00000000L
-+#define MQ200_GE_WHITENESS 0x000000FFL
-+#define MQ200_GE_SRC_INVERT 0x00000033L
-+#define MQ200_GE_SRC_COPY 0x000000CCL
-+#define MQ200_GE_SRCDEST_XOR 0x00000066L
-+#define MQ200_GE_SRCDEST_AND 0x00000088L
-+#define MQ200_GE_SRCDEST_OR 0x000000EEL
-+#define MQ200_GE_PATTERN_INVERT 0x0000000FL
-+#define MQ200_GE_PATTERN_COPY 0x000000F0L
-+#define MQ200_GE_PATDEST_XOR 0x0000005AL
-+#define MQ200_GE_PATDEST_AND 0x000000A0L
-+#define MQ200_GE_PATDEST_OR 0x000000FAL
-+/* MediaQ Raster Ops mapping table */
-+#define UGL_NR_OPERAND 4
-+#define UGL_NR_OPERATION 5
-+
-+#define geREG_2( idx1, val1, idx2, val2 ) \
-+ geREG( idx2, val2 ); \
-+ geREG( idx1, val1 )
-+#define geREG_3( idx1, val1, idx2, val2, idx3, val3 ) \
-+ geREG_2( idx2, val2, idx3, val3 ); \
-+ geREG( idx1, val1 )
-+#define geREG_4( idx1, val1, idx2, val2, idx3, val3, idx4, val4 ) \
-+ geREG_3( idx2, val2, idx3, val3, idx4, val4 ); \
-+ geREG( idx1, val1 )
-+#define geREG_5( idx1, val1, idx2, val2, idx3, val3, idx4, val4, idx5, val5 ) \
-+ geREG_4( idx2, val2, idx3, val3, idx4, val4, idx5, val5 ); \
-+ geREG( idx1, val1 )
-+
-+/* Declare MQ200 GE Utility Functions */
-+void geWaitNotBusy(void);
-+void geWaitCmdFIFO(u32 cnt);
-+void geWaitSrcFIFO(u32 cnt);
-+
-+#endif /* _VIDEO_MQ200_MQ2GE_H */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/video/MQ200/mq2hw.h 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,879 @@
-+/***************************************************************************
-+ MQ200HW.H
-+
-+ MQ200 chip definition file
-+
-+ Copyright (c) 2000 by MediaQ, Incorporated.
-+ All Rights Reserved.
-+
-+***************************************************************************/
-+#ifndef _VIDEO_MQ200_MQ2HW_H
-+#define _VIDEO_MQ200_MQ2HW_H
-+
-+#define MQ200_VENDOR_ID 0x4D51
-+#define MQ200_DEVICE_ID 0x0200
-+#define MQ200_ID 0x02004D51
-+#define PM_ID_CAP 0x06210001 /* Power management ID/capability */
-+
-+/* Revision ID */
-+#define MQ200_REV_0X 0x00
-+#define MQ200_REV_1A 0x01
-+#define MQ200_REV_1B1C 0x11
-+#define MQ200_REV_1D 0x10
-+
-+/* Some useful defines */
-+#ifndef ULONG
-+#define ULONG unsigned long
-+#endif
-+#ifndef USHORT
-+#define USHORT unsigned short
-+#endif
-+#ifndef BYTE
-+#define BYTE unsigned char
-+#endif
-+
-+/* To access MediaQ memory-mapped IO register (32bit in size) */
-+#define REG32(addr,val) (*(volatile ULONG *)((ULONG)pMQMMIO+addr)=(val))
-+#define READ32(addr) (*((volatile ULONG *)((ULONG)pMQMMIO+addr)))
-+#define geREG(addr,val) (*(volatile ULONG *)(mqMmioAddr+addr)=(val))
-+#define geREAD(addr) (*((volatile ULONG *)(mqMmioAddr+addr)))
-+#define gcREG(addr,val) geREG(addr,val)
-+#define gcREAD(addr) geREAD(addr)
-+#define cpuREG(addr,val) geREG(addr,val)
-+#define cpuREAD(addr) geREAD(addr)
-+#define pmuREG(addr,val) geREG(addr,val)
-+#define pmuREAD(addr) geREAD(addr)
-+#define pciREG(addr,val) geREG(addr,val)
-+#define pciREAD(addr) geREAD(addr)
-+
-+/* To access MediaQ DAC - index-based */
-+#define REG32_PAL(idx,val) (*(ULONG *)((ULONG)pMQMMIO+C1_BASE+idx*4)=(val))
-+#define READ32_PAL(idx) (*(ULONG *)((ULONG)pMQMMIO+C1_BASE+idx*4))
-+
-+/* MQ200 module offset */
-+#define PM_BASE (0) /* Power Management + Clk Gen */
-+#define CC_BASE (0x2000) /* CPU interface */
-+#define MM_BASE (0x4000) /* Memory Controller (m1/m2) */
-+#define VI_BASE (0x6000) /* Video-in controller */
-+#define IN_BASE (0x8000) /* Interrupt controller */
-+#define GC_BASE (0xA000) /* Graphics Controller 1/2 */
-+#define GE_BASE (0xC000) /* Graphics engine */
-+#define GE2_BASE (0xC200) /* Graphics engine (GE2) */
-+#define FP_BASE (0xE000) /* Flat panel interface */
-+#define C1_BASE (0x10000) /* Color palette 1 */
-+#define C2_BASE (0x12000) /* Color palette 2 */
-+#define DC_BASE (0x14000) /* Device Configuration Space */
-+#define PC_BASE (0x16000) /* PCI Configuration Header */
-+#define PSF_BASE (0x18000) /* Primary Source FIFO Space */
-+#define SSF_BASE (0x1A000) /* Secondary Source FIFO Space */
-+
-+#define MQ200_MMIO_SIZE (0x1C0000L)
-+#define MQ200_FB_SIZE (0x200000L) /* 2MB memory */
-+#define GC_OFFSET (0x80)
-+
-+/* Interrupt Controller */
-+#define INT_CONTROL_REG (IN_BASE + 0x00) /* Global interrupt ctrl reg */
-+#define INT_MASK_REG (IN_BASE + 0x04) /* Interrupt mask reg */
-+#define INT_STATUS_REG (IN_BASE + 0x08) /* Interrupt status reg */
-+#define INT_RAW_STATUS_REG (IN_BASE + 0x0C) /* Interrupt pin raw */
-+ /* status reg*/
-+
-+/* INT_CONTROL_REG - Global Interrupt Control Register */
-+#define INT_ENABLE 0x00000001 /* Interrupt to CPU enabled */
-+#define INT_PORLARITY_HIGH 0x00000002 /* Interrupt is active high */
-+#define INT_GPIO1_0To1 0x00000004 /* Interrupt as xition 0 to 1 */
-+#define INT_GPIO2_0To1 0x00000008 /* Interrupt as xition 0 to 1 */
-+#define INT_GPIO3_0To1 0x00000010 /* Interrupt as xtion 0 to 1 */
-+
-+/* INT_MASK_REG -- Interrupt Mask Register */
-+#define UM_GC1_VSE_R 0x00000001 /* GC1 VSE - Rising edge */
-+#define UM_GC1_VSE_F 0x00000002 /* GC1 VSE - Falling edge */
-+#define UM_GC1_VDE_R 0x00000004 /* GC1 VDE - Rising edge */
-+#define UM_GC1_VDE_F 0x00000008 /* GC1 VDE - Falling edge */
-+#define UM_GC2_VSE_R 0x00000010 /* GC2 VSE - Rising edge */
-+#define UM_GC2_VSE_F 0x00000020 /* GC2 VSE - Falling edge */
-+#define UM_GC2_VDE_R 0x00000040 /* GC2 VDE - Rising edge */
-+#define UM_GC2_VDE_F 0x00000080 /* GC2 VDE - Falling edge */
-+#define UM_CFIFO_HALF_EMPTY 0x00000100 /* Command fifo half empty */
-+#define UM_CFIFO_EMPTY 0x00000200 /* Command fifo empty */
-+#define UM_SFIFO_HALF_EMPTY 0x00000400 /* Source fifo half empty */
-+#define UM_SFIFO_EMPTY 0x00000800 /* Source fifo empty */
-+#define UM_GE_IDLE 0x00001000 /* GE is idle */
-+#define UM_GPIO_1 0x00002000 /* GPIO pin 1 */
-+#define UM_GPIO_2 0x00004000 /* GPIO pin 2 */
-+#define UM_GPIO_3 0x00008000 /* GPIO pin 3 */
-+
-+/* INT_STATUS_REG -- Interrupt Status Register */
-+#define ST_GC1_VSE_R 0x00000001 /* GC1 VSE - Rising edge */
-+#define ST_GC1_VSE_F 0x00000002 /* GC1 VSE - Falling edge */
-+#define ST_GC1_VDE_R 0x00000004 /* GC1 VDE - Rising edge */
-+#define ST_GC1_VDE_F 0x00000008 /* GC1 VDE - Falling edge */
-+#define ST_GC2_VSE_R 0x00000010 /* GC2 VSE - Rising edge */
-+#define ST_GC2_VSE_F 0x00000020 /* GC2 VSE - Falling edge */
-+#define ST_GC2_VDE_R 0x00000040 /* GC2 VDE - Rising edge */
-+#define ST_GC2_VDE_F 0x00000080 /* GC2 VDE - Falling edge */
-+#define ST_CFIFO_HALF_EMPTY 0x00000100 /* Command fifo half empty */
-+#define ST_CFIFO_EMPTY 0x00000200 /* Command fifo empty */
-+#define ST_SFIFO_HALF_EMPTY 0x00000400 /* Source fifo half empty */
-+#define ST_SFIFO_EMPTY 0x00000800 /* Source fifo empty */
-+#define ST_GE_IDLE 0x00001000 /* GE is idle */
-+#define ST_GPIO_1 0x00002000 /* GPIO pin 1 */
-+#define ST_GPIO_2 0x00004000 /* GPIO pin 2 */
-+#define ST_GPIO_3 0x00008000 /* GPIO pin 3 */
-+
-+/* INT_RAW_STATUA_REG -- Interrupt Pin Raw Status Register */
-+#define GC1_VSE 0x00000001 /* GC1 - VSE */
-+#define GC1_VDE 0x00000004 /* GC1 - VDE */
-+#define GC2_VSE 0x00000010 /* GC2 - VSE */
-+#define GC2_VDE 0x00000040 /* GC2 - VDE */
-+#define INT_GE_BUSY 0x00000100 /* GE busy */
-+#define SFIFO_EMPTY 0x00000200 /* Source fifo empty */
-+#define SFIFO_HEMPTY 0x00000400 /* Source fifo half empty */
-+#define CFIFO_EMPTY 0x00000800 /* Command fifo empty */
-+#define CFIFO_HEMPTY 0x00001000 /* Command fifo half empty */
-+#define GPIO_PIN_1 0x00002000 /* GPIO pin 1 */
-+#define GPIO_PIN_2 0x00004000 /* GPIO pin 2 */
-+#define GPIO_PIN_3 0x00008000 /* GPIO pin 3 */
-+
-+/* 2D Engine registers - GE1 (0x00 - 0x7F) */
-+#define DRAW_CMD (GE_BASE + 0x00) /* Drawing command register */
-+#define WIDTH_HEIGHT (GE_BASE + 0x04) /* Width/height register */
-+#define LINE_DRAW WIDTH_HEIGHT /* Bresenham Line Draw reg */
-+#define DEST_XY (GE_BASE + 0x08) /* Destination X/Y register */
-+#define LINE_MAJOR_X DEST_XY /* Bresenham Line Start X/Y reg */
-+#define PAT_OFFSET DEST_XY /* Pattern Offset register */
-+#define SRC_XY (GE_BASE + 0x0C) /* Source X/Y register */
-+#define LINE_MINOR_Y SRC_XY /* Bresenham Line Delta register */
-+#define COLOR_COMPARE (GE_BASE + 0x10) /* Color compare register */
-+#define CLIP_LeftT (GE_BASE + 0x14) /* Clip Left/Top register */
-+#define CLIP_RightB (GE_BASE + 0x18) /* Clip Right/Bottom register */
-+#define FG_COLOR (GE_BASE + 0x1C) /* Fg color for Mono src reg */
-+#define BG_COLOR (GE_BASE + 0x20) /* Bg color for Mono src reg */
-+#define SRC_STRIDE_OFFSET (GE_BASE + 0x24) /* Source Stride & Offset Reg */
-+#define DEST_STRIDE (GE_BASE + 0x28) /* Base address register */
-+#define BASE_ADDRESS (GE_BASE + 0x2C) /* Base address register */
-+#define TEST_RESULT_REG (GE_BASE + 0x7C) /* Test result register */
-+#define COLOR_PATTERN (GE_BASE + 0x100) /* Color pattern registers */
-+#define MONO_PATTERN0 COLOR_PATTERN /* Mono Pattern register 0 */
-+#define MONO_PATTERN1 (GE_BASE + 0x104) /* Mono Pattern register 1 */
-+#define PAT_FG_COLOR (GE_BASE + 0x108) /* Mono Pattern Fg color reg */
-+#define PAT_BG_COLOR (GE_BASE + 0x10C) /* Mono Pattern Bg color reg */
-+#define _FIRST_GE DRAW_CMD
-+#define _LAST_GE (COLOR_PATTERN + 0x80)
-+#define SRC_IMAGE_DATA (GE_BASE + 0xC000) /* Source Data register */
-+
-+/* 2D Engine registers - GE2 (0x80 to 0xFF) */
-+#define DRAW_CMD2 (GE2_BASE + 0x00) /* Drawing command register */
-+#define WIDTH_HEIGHT2 (GE2_BASE + 0x04) /* Width/height register */
-+#define LINE_DRAW2 WIDTH_HEIGHT2 /* Bresenham Line Draw register */
-+#define DEST_XY2 (GE2_BASE + 0x08) /* Destination X/Y register */
-+#define LINE_MAJOR_X2 DEST_XY2 /* Bresenham Line Start X/Y reg */
-+#define PAT_OFFSET2 DEST_XY2 /* Pattern Offset register */
-+#define SRC_XY2 (GE2_BASE + 0x0C) /* Source X/Y register */
-+#define LINE_MINOR_Y2 SRC_XY2 /* Bresenham Line Delta register */
-+#define COLOR_COMPARE2 (GE2_BASE + 0x10) /* Color compare register */
-+#define CLIP_LeftT2 (GE2_BASE + 0x14) /* Clip Left/Top register */
-+#define CLIP_RightB2 (GE2_BASE + 0x18) /* Clip Right/Bottom register */
-+#define FG_COLOR2 (GE2_BASE + 0x1C) /* Fg color for Mono src reg */
-+#define BG_COLOR2 (GE2_BASE + 0x20) /* Bg color for Mono src reg */
-+#define SRC_STRIDE_OFFSET2 (GE2_BASE + 0x24) /* Source Stride & Offset Reg */
-+#define DEST_STRIDE2 (GE2_BASE + 0x28) /* Base address register */
-+#define BASE_ADDRESS2 (GE2_BASE + 0x2C) /* Base address register */
-+#define TEST_RESULT_REG2 (GE2_BASE + 0x7C) /* Test result register */
-+#define COLOR_PATTERN2 (GE2_BASE + 0x100) /* Color pattern registers */
-+#define MONO_PATTERN02 COLOR_PATTERN2 /* Mono Pattern register 0 */
-+#define MONO_PATTERN12 (GE2_BASE + 0x104) /* Mono Pattern register 1 */
-+#define PAT_FG_COLOR2 (GE2_BASE + 0x108) /* Mono Pattern Fg color reg */
-+#define PAT_BG_COLOR2 (GE2_BASE + 0x10C) /* Mono Pattern Bg color reg */
-+#define _FIRST_GE2 DRAW_CMD2
-+#define _LAST_GE2 (COLOR_PATTERN2 + 0x80)
-+#define SRC_IMAGE_DATA2 (GE2_BASE + 0xC000) /* Source Data register */
-+
-+
-+/* DEST_STRIDE color depth */
-+#define GE_8BPP 0x00000000 /* 8BPP mode */
-+#define GE_16BPP 0x40000000 /* 16BPP mode */
-+#define GE_24BPP 0x80000000 /* 24BPP mode */
-+#define GE_32BPP 0xC0000000 /* 24BPP mode */
-+
-+/* BASE_ADDRESS */
-+#define GE_TEST_MODE_ENABLE 0x20000000 /* Test mode enabled */
-+#define GE_TEST_MASK 0xc0000000 /* Test mode read path select */
-+#define SEL_CLIP_LR 0x40000000 /* Select clipping left/right */
-+#define SEL_CLIP_TB 0x80000000 /* Select clipping top/bottom */
-+
-+/* Draw command register bits */
-+#define DO_BITBLT 0x00000200
-+#define DO_AAFONT 0x00000300
-+#define DO_LINEDRAW 0x00000400
-+#define X_DIR 0x00000800 /* Negative X direction */
-+#define Y_DIR 0x00001000 /* Negative Y direction */
-+#define SRC_IS_MEMORY 0x00002000 /* Source is in system memory */
-+#define MONO_SRC 0x00004000 /* Source is mono bitmap */
-+#define MONO_PATTERN 0x00008000 /* Pattern is monochrome */
-+#define TRANS_COLOR 0x00010000 /* Transparency is enabled */
-+#define TRANS_NOT_EQUAL 0x00020000 /* Polarity for color */
-+#define TRANS_MONO 0x00040000 /* Mono xparency is enabled */
-+#define TRANS_MONO_FG 0x00080000 /* Polarity for mono */
-+#define PACKED_MODE 0x00100000 /* Memory xfer mode select */
-+#define ALPHA_BYTE_MASK 0x00600000 /* Alpha Byte mask for 32bpp */
-+#define MONO_SOLID 0x00800000 /* Solid Mono Pattern */
-+#define SRC_NE_DEST_STRIDE 0x01000000 /* Src Not Equal Dest Stride */
-+#define ROP2_ENABLE 0x02000000 /* Use Rop2 code */
-+#define CLIP_ENABLE 0x04000000 /* Clipping is enabled */
-+#define AUTO_EXEC 0x08000000 /* Auto execute at dest X/Y */
-+#define VDE_GC2_ENABLE 0x10000000 /* Enable falling edge check */
-+#define VDE_GC1_ENABLE 0x20000000 /* Enable falling edge check */
-+#define COLOR_DEPTH_MASK 0xC0000000 /* Color Depth mask */
-+#define GE_8BPP 0x00000000 /* 8BPP mode */
-+#define GE_16BPP 0x40000000 /* 16BPP mode */
-+#define GE_24BPP 0x80000000 /* 24BPP mode */
-+
-+/* Graphics Controller 1 Registers */
-+#define GC1_CONTROL (GC_BASE + 0x00) /* Graphics Controll 1 Control Reg */
-+#define GC1_CRT_CONTROL (GC_BASE + 0x04) /* CRT controll register */
-+#define HD1_CONTROL (GC_BASE + 0x08) /* Horizontal Display 1 Control */
-+#define VD1_CONTROL (GC_BASE + 0x0C) /* Vertical Display 1 Control */
-+#define HS1_CONTROL (GC_BASE + 0x10) /* Horizontal Sync 1 Control */
-+#define VS1_CONTROL (GC_BASE + 0x14) /* Vertical Sync 1 Control */
-+#define HW1_CONTROL (GC_BASE + 0x20) /* Horizontal Window 1 Control */
-+#define VW1_CONTROL (GC_BASE + 0x24) /* Vertical Window 1 Control */
-+#define AHW1_CONTROL (GC_BASE + 0x28) /* Alt Horizontal Window 1 Control */
-+#define AVW1_CONTROL (GC_BASE + 0x2C) /* Alt Vertical Window 1 Control */
-+#define IW1_START_ADDR (GC_BASE + 0x30) /* Image Window 1 Start Address */
-+#define AIW1_START_ADDR (GC_BASE + 0x34) /* Alt Image Window 1 Start Address */
-+#define IW1_STRIDE (GC_BASE + 0x38) /* (Alt) Image Window 1 Stride */
-+#define IW1_LINE_SIZE (GC_BASE + 0x3C) /* (Alt) Image Window 1 Line Size */
-+#define HW_CURSOR1_POS (GC_BASE + 0x40) /* Hardware cursor 1 position */
-+#define HW_CURSOR1_ADDR (GC_BASE + 0x44) /* Start address and offset */
-+#define HW_CURSOR1_FGCLR (GC_BASE + 0x48) /* Foreground color */
-+#define HW_CURSOR1_BGCLR (GC_BASE + 0x4C) /* Background color */
-+
-+/* Graphics Controller 2 Registers */
-+#define GC2_CONTROL (GC_BASE + 0x80) /* Graphics Controll 2 Control Reg */
-+#define GC2_CRC_CONTROL (GC_BASE + 0x84) /* CRC Control */
-+#define HD2_CONTROL (GC_BASE + 0x88) /* Horizontal Display 2 Control */
-+#define VD2_CONTROL (GC_BASE + 0x8C) /* Vertical Display 2 Control */
-+#define HS2_CONTROL (GC_BASE + 0x90) /* Horizontal Sync 2 Control */
-+#define VS2_CONTROL (GC_BASE + 0x94) /* Vertical Sync 2 Control */
-+#define HW2_CONTROL (GC_BASE + 0xA0) /* Horizontal Window 2 Control */
-+#define VW2_CONTROL (GC_BASE + 0xA4) /* Vertical Window 2 Control */
-+#define AHW2_CONTROL (GC_BASE + 0xA8) /* Alt Horizontal Window 2 Control */
-+#define AVW2_CONTROL (GC_BASE + 0xAC) /* Alt Vertical Window 2 Control */
-+#define IW2_START_ADDR (GC_BASE + 0xB0) /* Image Window 2 Start Address */
-+#define AIW2_START_ADDR (GC_BASE + 0xB4) /* Alt Image Window 2 Start Address */
-+#define IW2_STRIDE (GC_BASE + 0xB8) /* (Alt) Image Window 2 Stride */
-+#define IW2_LINE_SIZE (GC_BASE + 0xBC) /* (Alt) Image Window 2 Line Size */
-+#define HW_CURSOR2_POS (GC_BASE + 0xC0) /* Hardware cursor 2 position */
-+#define HW_CURSOR2_ADDR (GC_BASE + 0xC4) /* Start address and offset */
-+#define HW_CURSOR2_FGCLR (GC_BASE + 0xC8) /* Foreground color */
-+#define HW_CURSOR2_BGCLR (GC_BASE + 0xCC) /* Background color */
-+
-+/* GC1_CONTROL/GC2_CONTROL register */
-+#define GC_ENABLE 0x00000001UL /* Controll 1/2 enabled */
-+#define GC_DISABLE 0xfffffffeUL /* Controll 1/2 disabled */
-+#define HORZ_COUNT_RESET 0x00000002UL /* Horiz counter 1/2 reset */
-+#define VERT_COUNT_RESET 0x00000004UL /* Vertical counter 1/2 reset */
-+#define IM_ENABLE 0x00000008UL /* Image Window 1/2 Enable */
-+#define IM_DISABLE 0xfffffff7UL /* Image Window 1/2 Disable */
-+
-+#define GC_1BPP 0x00000000UL /* GC1/2 color depth */
-+#define GC_2BPP 0x00000010UL
-+#define GC_4BPP 0x00000020UL
-+#define GC_8BPP 0x00000030UL
-+#define GC_16BPP 0x00000040UL /* with color palette enabled */
-+#define GC_24BPP_NBP 0x00000050UL /* with color palette enabled */
-+#define GC_32BPP_ABGR 0x00000060UL /* with color palette enabled */
-+#define GC_32BPP_ARGB 0x00000070UL /* with color palette enabled */
-+#define GC_16BPP_BP 0x000000C0UL /* with color pal bypassed */
-+#define GC_24BPP_BP 0x000000D0UL /* with color pal bypassed */
-+#define GC_32BPP_ABGR_BP 0x000000E0UL /* with color pal bypassed */
-+#define GC_32BPP_ARGB_BP 0x000000F0UL /* with color pal bypassed */
-+#define GC_32BPP GC_32BPP_ARGB /* Default 32bpp with ARGB */
-+#define GC_24BPP GC_24BPP_NBP
-+
-+#define HC_ENABLE 0x00000100UL /* Hardware cursor enable */
-+#define HC_DISABLE 0xfffffeffUL /* And mask to disable HC */
-+#define AIM_ENABLE 0x00000800UL /* Alt Image Win 1/2 Enable */
-+
-+#define AGC_1BPP 0x00000000UL /* Alt GC1/2 color depth */
-+#define AGC_2BPP 0x00001000UL
-+#define AGC_4BPP 0x00002000UL
-+#define AGC_8BPP 0x00003000UL
-+#define AGC_16BPP 0x00004000UL
-+#define AGC_24BPP 0x00005000UL
-+#define AGC_32BPP_ABGR 0x00006000UL
-+#define AGC_32BPP_ARGB 0x00007000UL
-+#define AGC_16BPP_BP 0x0000C000UL
-+#define AGC_24BPP_BP 0x0000D000UL
-+#define AGC_32BPP_ABGR_BP 0x0000E000UL
-+#define AGC_32BPP_ARGB_BP 0x0000F000UL
-+#define AGC_32BPP AGC_32BPP_ARGB_BP /* Default 32bpp w/ ARGB_BP */
-+
-+#define GxRCLK_BUSCLK 0x00000000UL /* G1RCLK source is bus clock */
-+#define GxRCLK_PLL1 0x00010000UL /* G1RCLK source is PLL1 */
-+#define GxRCLK_PLL2 0x00020000UL /* G1RCLK source is PLL2 */
-+#define GxRCLK_PLL3 0x00030000UL /* G1RCLK source is PLL3 */
-+#define GxRCLK_PLL_MASK 0x00030000UL /* G1RCLK source mask */
-+#define GC_TEST_MODE0 0x00040000UL /* Test mode 0 enabled */
-+#define GC_TEST_MODE1 0x00080000UL /* Test mode 1 enabled */
-+
-+#define FDx_1 0x00000000UL /* FD1 = 1 */
-+#define FDx_15 0x00100000UL /* FD1 = 1.5 */
-+#define FDx_25 0x00200000UL /* FD1 = 2.5 */
-+#define FDx_35 0x00300000UL /* FD1 = 3.5 */
-+#define FDx_45 0x00400000UL /* FD1 = 4.5 */
-+#define FDx_55 0x00500000UL /* FD1 = 5.5 */
-+#define FDx_65 0x00600000UL /* FD1 = 6.5 */
-+
-+/* GC1_CRT_CONTROL register */
-+#define CRT_ENABLE 0x00000001UL /* CRT DAC enabled */
-+#define CRT_DISABLE 0xfffffffeUL /* CRT DAC disabled -and mask */
-+#define CRT_BY_GC1 0x00000001UL /* CRT DAC driven by GC1 */
-+#define CRT_BY_GC2 0x00000003UL /* CRT DAC driven by GC2 */
-+#define CRT_BY_GCxMASK 0xfffffffcUL /* Mask for CRT DAC */
-+#define VSYNC_OUT_PMCLK 0x00000004UL /* CRT VSYNC output PMCLK
-+ at PwrDn */
-+#define HSYNC_OUT_PMCLK 0x00000008UL /* CRT HSYNC output PMCLK
-+ at PwrDn */
-+#define HSYNC_OUT_LOW 0x00000010UL /* CRT HSYNC output pin low */
-+#define HSYNC_OUT_HIGH 0x00000020UL /* CRT HSYNC output pin high */
-+#define VSYNC_OUT_LOW 0x00000040UL /* CRT VSYNC output pin low */
-+#define VSYNC_OUT_HIGH 0x00000080UL /* CRT VSYNC output pin high */
-+#define HSYNC_POLARITY_LOW 0x00000100UL /* active low */
-+#define VSYNC_POLARITY_LOW 0x00000200UL /* active low */
-+#define SYNC_PED_ENABLE 0x00000400UL /* Sync pedestal enable */
-+#define BLANK_PED_ENABLE 0x00000800UL /* Blank pedestal enable */
-+#define CSYNC_ENABLE 0x00001000UL /* Composite Sync Enable */
-+#define VREF_EXTERNAL 0x00002000UL /* Select external VREF */
-+#define MON_SENSE_ENABLE 0x00004000UL /* CRT DAC monitor sense
-+ enable */
-+#define CONST_OUT_ENABLE 0x00008000UL /* Constant output enable */
-+#define BLUE_NOT_LOADED 0x01000000UL /* Blue DAC is not loaded */
-+#define GREEN_NOT_LOADED 0x02000000UL /* Green DAC is not loaded */
-+#define RED_NOT_LOADED 0x04000000UL /* Red DAC is not loaded */
-+
-+/* GC2_CRC_CONTROL */
-+#define CRC_ENABLE 0x00000001UL /* Enable CRC logic */
-+#define CRC_2_VSYNC 0x00000002UL /* Wait for 2 vsync */
-+#define CRC_READ_BLUE 0x00000000UL /* Read CRC result for blue */
-+#define CRC_READ_GREEN 0x00000004UL /* Read CRC result for green */
-+#define CRC_READ_RED 0x00000008UL /* Read CRC result for red */
-+#define CRC_RESULT_MASK 0x3fffff00UL /* CRC result mask */
-+
-+/* Flat Panel Interface Registers */
-+#define FP_CONTROL (FP_BASE + 0x00) /* Flat panel control */
-+#define FP_PIN_CONTROL (FP_BASE + 0x04) /* Flat panel pin control */
-+#define FP_GPO_CONTROL (FP_BASE + 0x08) /* FP Gen. purpose output ctrl */
-+#define FP_GPIO_CONTROL (FP_BASE + 0x0C) /* FP Gen. purpose I/O control */
-+#define STN_CONTROL (FP_BASE + 0x10) /* STN panel control */
-+#define DSTN_FB_CONTROL (FP_BASE + 0x14) /* D-STN frame buffer control */
-+#define PWM_CONTROL (FP_BASE + 0x3C) /* PWM control */
-+#define FRC_PATTERN (FP_BASE + 0x40) /* FRC pattern starting index */
-+#define FRC_WEIGHT (FP_BASE + 0xC0) /* FRC weight starting index */
-+
-+/* FP_CONTROL */
-+#define FPI_ENABLE 0x00000001UL /* Trigger fp power up sequence */
-+#define FPI_DISABLE 0xfffffffeUL /* Trigger fp power down sequence */
-+#define FPI_BY_GC1 0x00000001UL /* FPI enabled & driven by GC1 */
-+#define FPI_BY_GC2 0x00000003UL /* FPI enabled & driven by GC2 */
-+#define FPI_BY_GCxMASK 0xfffffffcUL /* mask */
-+#define FP_TYPE_TFT 0x00000000UL /* Flat panel type TFT */
-+#define FP_TYPE_SSTN 0x00000004UL /* Flat panel type S-STN */
-+#define FP_TYPE_DSTN 0x00000008UL /* Flat panel type D-STN */
-+#define FP_TYPE_MASK 0x0000000cUL /* Flat panel type mask */
-+#define FP_COLOR 0x00000000UL /* Color flat panel */
-+#define FP_MONO 0x00000010UL /* Mono flat panel */
-+#define TFT_4BITS_MONO 0x00000000UL /* Specify num of bits/pixel */
-+#define TFT_12BITS_COLOR 0x00000000UL /* Specify num of bits/pixel */
-+#define SSTN_4BITS_MONOCLR 0x00000000UL /* Specify num of bits/pixel */
-+#define DSTN_8BITS_MONOCLR 0x00000000UL /* Specify num of bits/pixel */
-+#define TFT_6BITS_MONO 0x00000020UL /* Specify num of bits/pixel */
-+#define TFT_18BITS_COLOR 0x00000020UL /* Specify num of bits/pixel */
-+#define SSTN_8BITS_MONOCLR 0x00000020UL /* Specify num of bits/pixel */
-+#define DSTN_16BITS_MONOCLR 0x00000020UL /* Specify num of bits/pixel */
-+#define TFT_8BITS_MONO 0x00000040UL /* Specify num of bits/pixel */
-+#define TFT_24BITS_COLOR 0x00000040UL /* Specify num of bits/pixel */
-+#define SSTN_12BITS_COLOR 0x00000040UL /* Specify num of bits/pixel */
-+#define DSTN_24BITS_COLOR 0x00000040UL /* Specify num of bits/pixel */
-+#define SSTN_16BITS_MONOCLR 0x00000060UL /* Specify num of bits/pixel */
-+#define SSTN_24BITS_COLOR 0x00000080UL /* Specify num of bits/pixel */
-+#define DITHER_PATTERN_0 0x00000000UL /* Dither pattern */
-+#define DITHER_PATTERN_1 0x00000100UL /* Dither pattern */
-+#define DITHER_PATTERN_2 0x00000200UL /* Dither pattern */
-+#define DITHER_PATTERN_3 0x00000300UL /* Dither pattern */
-+#define DITHER_BASE_8BITS 0x00000000UL /* No dithering */
-+#define DITHER_BASE_2BITS 0x00002000UL /* Num of bits to be dithered */
-+#define DITHER_BASE_3BITS 0x00003000UL /* Num of bits to be dithered */
-+#define DITHER_BASE_4BITS 0x00004000UL /* Num of bits to be dithered */
-+#define DITHER_BASE_6BITS 0x00006000UL /* Num of bits to be dithered */
-+#define FRC_ALTWIN_DISABLE 0x00008000UL /* Disable Dither/FRC if Alt enabled */
-+#define FRC_2LEVEL 0x00000000UL /* Disable FRC */
-+#define FRC_4LEVEL 0x00010000UL /* 4-level FRC */
-+#define FRC_8LEVEL 0x00020000UL /* 8-level FRC */
-+#define FRC_16LEVEL 0x00030000UL /* 16-level FRC */
-+#define DITHER_PATTERN_ADJ1 0x00fc0000UL /* Dither pattern adjust 1 */
-+#define DITHER_PATTERN_ADJ2 0x07000000UL /* Dither pattern adjust 2 */
-+#define DITHER_PATTERN_ADJ3 0x08000000UL /* Dither pattern adjust 3 */
-+#define TEST_MODE0_ENABLE 0x10000000UL /* Enable test mode 0 */
-+#define TEST_MODE1_ENABLE 0x20000000UL /* Enable test mode 1 */
-+#define TEST_MODE2_ENABLE 0x40000000UL /* Enable test mode 2 */
-+#define TEST_MODE3_ENABLE 0x80000000UL /* Enable test mode 3 */
-+
-+/* FP_PIN_CONTROL */
-+#define FP_PIN_DISABLE 0x00000001UL /* Disable flat panel pins */
-+#define DATA_INV_ENABLE 0x00000002UL /* TFT fp data inversion enabled */
-+#define FP_DISP_ENABLE 0x00000004UL /* FP Display enable control */
-+#define FMOD_ENABLE 0x00000008UL /* Flat panel AC mod enable */
-+#define FD2_SCLK 0x00000010UL /* STN output shift clk on FD2 pin*/
-+#define FSCLK_OUTPUT_ENABLE 0x00000020UL /* FSCLK output enable */
-+#define TFT_SCLK_SELECT 0x00000040UL /* TFT shift clock select */
-+#define SCLK_MASK 0x00000080UL /* Shift clock mask */
-+#define STN_LP_DISABLE 0x00000100UL /* STN LP control */
-+#define SCLK_DISABLE 0x00000200UL /* STN shift clock control */
-+#define STN_ExtraLP_ENABLE 0x00000400UL /* STN extra LP control */
-+#define FP_FD2_MAX 0x00000000UL /* FD2 drive strength - max (16mA)*/
-+#define FP_FD2_MEDIUM 0x00001000UL /* FD2 drive strength - medium */
-+#define FP_FD2_MEDIUM2 0x00002000UL /* FD2 drive strength - medium 2 */
-+#define FP_FD2_MIN 0x00003000UL /* FD2 drive strength - min */
-+#define FP_DATA_MAX 0x00000000UL /* Data drv strength - max (16mA) */
-+#define FP_DATA_MEDIUM 0x00004000UL /* Data drive strength - medium */
-+#define FP_DATA_MEDIUM2 0x00008000UL /* Data drive strength - medium 2 */
-+#define FP_DATA_MIN 0x0000c000UL /* Data drive strength - min */
-+#define FD2_ACTIVE_L 0x00010000UL /* Flat panel data bit 2 polarity */
-+#define FD_ACTIVE_L 0x00020000UL /* Flat panel data polarity */
-+#define FDE_ACTIVE_L 0x00040000UL /* Data enable polarity */
-+#define FHSYNC_ACTIVE_L 0x00080000UL /* Horz sync polarity */
-+#define FVSYNC_ACTIVE_L 0x00100000UL /* Vert sync polarity */
-+#define FSCLK_ACTIVE_L 0x00200000UL /* Shift clock polarity */
-+#define FP_FSCLK_MAX 0x00000000UL /* Sh clk drv strength -max (16mA)*/
-+#define FP_FSCLK_MEDIUM 0x00400000UL /* Sh clk drv strength -medium */
-+#define FP_FSCLK_MEDIUM2 0x00800000UL /* Sh clk drv strength -medium 2 */
-+#define FP_FSCLK_MIN 0x00c00000UL /* Sh clk drv strength -min */
-+#define FSCLK_DELAY 0x07000000UL /* Shift clock delay */
-+
-+/* FP_GPO_CONTROL */
-+#define ENCTL_AS_GPO0 0x00000001UL /* ENCTL used as GPO 0 */
-+#define ENCTL_AS_OSC 0x00000002UL /* ENCTL used as Oscillator clock */
-+#define ENCTL_AS_PLL3 0x00000003UL /* ENCTL used as PLL3 clock */
-+#define ENVEE_AS_GPO1 0x00000004UL /* ENVEE used as GPO 1 */
-+#define PWM0_AS_GPO2 0x00000010UL /* PWM0 pin used as GPO 2 */
-+#define PWM1_AS_GPO3 0x00000040UL /* PWM1 pin used as GPO 3 */
-+#define ENVDD_AS_GPO4 0x00000100UL /* ENVDD pin used as GPO 4 */
-+#define FP_PWM_MAX 0x00000000UL /* PWM0/1 drv strength -max (16mA)*/
-+#define FP_PWM_MEDIUM 0x00000400UL /* PWM0/1 drv strength -medium */
-+#define FP_PWM_MEDIUM2 0x00000800UL /* PWM0/1 drv strength -medium 2 */
-+#define FP_PWM_MIN 0x00000c00UL /* PWM0/1 drv strength -min */
-+#define FP_GPIO_MAX 0x00000000UL /* GPIO0/1/2 drv strgth. -max 16mA*/
-+#define FP_GPIO_MEDIUM 0x00001000UL /* GPIO0/1/2 drv strgth. -medium */
-+#define FP_GPIO_MEDIUM2 0x00002000UL /* GPIO0/1/2 drv strgth. -medium 2*/
-+#define FP_GPIO_MIN 0x00003000UL /* GPIO0/1/2 drv strgth. -min */
-+#define FP_EN_MAX 0x00000000UL /* ENVDD/ENCTL/ENVEE -max (16mA) */
-+#define FP_EN_MEDIUM 0x00004000UL /* ENVDD/ENCTL/ENVEE -medium */
-+#define FP_EN_MEDIUM2 0x00008000UL /* ENVDD/ENCTL/ENVEE -medium 2 */
-+#define FP_EN_MIN 0x0000c000UL /* ENVDD/ENCTL/ENVEE -min */
-+#define GPO0_DATA_HIGH 0x00010000UL /* ENCTL is driven high */
-+#define GPO1_DATA_HIGH 0x00020000UL /* ENVEE is driven high */
-+#define GPO2_DATA_HIGH 0x00040000UL /* PWM0 is driven high */
-+#define GPO3_DATA_HIGH 0x00080000UL /* PWM1 is driven high */
-+#define GPO4_DATA_HIGH 0x00100000UL /* ENVDD is driven high */
-+
-+/* FP_GPIO_CONTROL */
-+#define GPIO0_IN 0x00000000UL /* General-purpose input */
-+#define GPIO0_OUT 0x00000001UL /* General-purpose output */
-+#define GPIO0_PLL1 0x00000002UL /* GPIO0 used to output PLL 1 clk */
-+#define GPIO0_CRC_B 0x00000003UL /* GPIO0 used to output CRC Blue */
-+#define GPIO1_IN 0x00000000UL /* General-purpose input */
-+#define GPIO1_OUT 0x00000004UL /* General-purpose output */
-+#define GPIO1_PLL2 0x00000008UL /* GPIO1 used to output PLL 2 clk */
-+#define GPIO1_CRC_G 0x0000000cUL /* GPIO1 used to output CRC Green */
-+#define GPIO2_IN 0x00000000UL /* General-purpose input */
-+#define GPIO2_OUT 0x00000010UL /* General-purpose output */
-+#define GPIO2_PLL3 0x00000020UL /* GPIO2 used to output PLL 3 clk */
-+#define GPIO2_CRC_R 0x00000030UL /* GPIO2 used to output CRC Red */
-+#define GPIO0_OUT_HIGH 0x00010000UL /* GOIO0 output data */
-+#define GPIO1_OUT_HIGH 0x00020000UL /* GOIO1 output data */
-+#define GPIO2_OUT_HIGH 0x00040000UL /* GOIO2 output data */
-+#define GPIO0_IN_HIGH 0x01000000UL /* GOIO0 input data */
-+#define GPIO1_IN_HIGH 0x02000000UL /* GOIO1 input data */
-+#define GPIO2_IN_HIGH 0x04000000UL /* GOIO2 input data */
-+
-+/* STN_CONTROL */
-+#define FMOD_FRAMECLK 0x00000000UL /* FMOD generated using frame clock */
-+#define FMOD_LINECLK 0x80000000UL /* FMOD generated using line clock */
-+
-+/* PWM_CONTROL */
-+#define PWM0_BY_PLL 0x00000000UL /* PWM 0 signal by PLL */
-+#define PWM0_BY_BUS 0x00000001UL /* PWM 0 signal using bus clk */
-+#define PWM0_BY_PMC 0x00000002UL /* PWM 0 signal by power mgt clock */
-+#define PWM0_ALWAYS_ON 0x00000004UL /* PWM 0 signal always generated */
-+#define PWM0_DC_MASK 0xffff00ffUL /* PWM 0 duty cycle mask */
-+#define PWM0_MASK 0xffff0000UL /* PWM 0 mask */
-+#define PWM1_BY_PLL 0x00000000UL /* PWM 1 signal by PLL */
-+#define PWM1_BY_BUS 0x00010000UL /* PWM 1 signal using bus clk */
-+#define PWM1_BY_PMC 0x00020000UL /* PWM 1 signal by power mgt clock */
-+#define PWM1_ALWAYS_ON 0x00040000UL /* PWM 1 signal always generated */
-+#define PWM1_DC_MASK 0x00ffffffUL /* PWM 0 duty cycle mask */
-+#define PWM1_MASK 0x0000ffffUL /* PWM 1 mask */
-+
-+/* PCI Power Management Interface Registers */
-+#ifndef PCI_VENDOR_DEVICE
-+#define PCI_VENDOR_DEVICE (PC_BASE + 0x00)
-+#endif
-+
-+#ifndef PCI_CMD_STATUS
-+#define PCI_CMD_STATUS (PC_BASE + 0x04)
-+#endif
-+
-+#ifndef PCI_REV_CLASS
-+#define PCI_REV_CLASS (PC_BASE + 0x08)
-+#endif
-+
-+#ifndef PCI_HEADER_TYPE
-+#define PCI_HEADER_TYPE (PC_BASE + 0x0c)
-+#endif
-+
-+#ifndef PCI_SUB_ID
-+#define PCI_SUB_ID (PC_BASE + 0x2c)
-+#endif
-+
-+#ifndef PCI_ROM_BASE
-+#define PCI_ROM_BASE (PC_BASE + 0x30)
-+#endif
-+
-+#ifndef PCI_CAP_PTR
-+#define PCI_CAP_PTR (PC_BASE + 0x34)
-+#endif
-+
-+#ifndef PCI_INTERRUPT
-+#define PCI_INTERRUPT (PC_BASE + 0x3c)
-+#endif
-+
-+#ifndef PCI_PM_REGISTER
-+#define PCI_PM_REGISTER (PC_BASE + 0x40)
-+#endif
-+
-+#ifndef PCI_PM_CNTL_STATUS
-+#define PCI_PM_CNTL_STATUS (PC_BASE + 0x44)
-+#endif
-+
-+/* POWER_STATE */
-+#define POWER_STATE_MASK 0x00000003UL /* Device power state mask */
-+#define ENTER_D0 0x00000000UL /* Enter D0 state */
-+#define ENTER_D1 0x00000001UL /* Enter D1 state */
-+#define ENTER_D2 0x00000002UL /* Enter D2 state */
-+#define ENTER_D3 0x00000003UL /* Enter D3 state */
-+
-+/* DC (Device Configuration Unit) Registers */
-+#define DC_0 (DC_BASE + 0x00) /* Device Configruation Register 0 */
-+#define DC_1 (DC_BASE + 0x04) /* Device Configruation Register 1 */
-+#define DC_SW_0 (DC_BASE + 0x08) /* Software Register 0 */
-+#define DC_SW_1 (DC_BASE + 0x0C) /* Software Register 1 */
-+
-+/* DC_0 */
-+#define OSC_BYPASSED 0x00000001UL /* Oscillator bypassed, powered down */
-+#define OSC_ENABLE 0x00000002UL /* Oscillator control can be enabled */
-+#define PLL1_BYPASSED 0x00000004UL /* PLL1 bypassed */
-+#define PLL1_ENABLE 0x00000008UL /* PLL1 can be enabled */
-+#define PLL1_DIVBY1 0x00000000UL /* PLL1 P output divisor by 1 */
-+#define PLL1_DIVBY2 0x00000010UL /* PLL1 P output divisor by 2 */
-+#define PLL1_DIVBY4 0x00000020UL /* PLL1 P output divisor by 4 */
-+#define PLL1_DIVBY8 0x00000030UL /* PLL1 P output divisor by 8 */
-+#define PLL1_DIVBY16 0x00000040UL /* PLL1 P output divisor by 16 */
-+#define PLL1_DIV_MASK 0x00000070UL /* PLL1 P output divisor mask */
-+#define CIF_DIVBY1 0x00000000UL /* CPU Interface clk divisor by 1 */
-+#define CIF_DIVBY2 0x00000080UL /* CPU Interface clk divisor by 2 */
-+#define STRONGARM_SYNC_F 0x00002000UL /* StrongARM bus intrf at fall edge */
-+#define SW_CHIP_RESET 0x00004000UL /* Software chip reset */
-+#define MEM_STANDBY_DISABLE 0x00008000UL /* Memory Power unit Standby disab. */
-+#define OSC_SHAPER_DISABLE 0x01000000UL /* Oscillator waveform shaper disab. */
-+#define FAST_POWER_DISABLE 0x02000000UL /* Fast Power Sequencing disable */
-+#define OSC_FREQ_SEL_0 0x00000000UL /* Osc frequency select range 0 */
-+#define OSC_FREQ_SEL_1 0x04000000UL /* Osc frequency select range 1 */
-+#define OSC_FREQ_SEL_2 0x08000000UL /* Osc frequency select range 2 */
-+#define OSC_FREQ_SEL_3 0x0c000000UL /* Osc frequency select range 3 */
-+
-+/* DC_1 */
-+#define BUS_MODE_MASK 0x0000003FUL /* Bus interface mode mask */
-+#define BUS_MODE_SH7709 0x00000001UL /* Bus interface mode - SH7709 */
-+#define BUS_MODE_SH7750 0x00000002UL /* Bus interface mode - SH7750 */
-+#define BUS_MODE_VR41xx 0x00000004UL /* Bus interface mode - VR4111/21 */
-+#define BUS_MODE_SA1110 0x00000008UL /* Bus interface mode - SA1110 */
-+#define BUS_MODE_TX3922 0x00000010UL /* Bus interface mode - TX3922 */
-+#define BUS_MODE_PCI 0x00000020UL /* Bus interface mode - PCI */
-+
-+/* PMU (Power Management Unit) Registers */
-+#define PM_MISC (PM_BASE + 0x00) /* Power management misc ctrl */
-+#define D1_STATE (PM_BASE + 0x04) /* D1 state control */
-+#define D2_STATE (PM_BASE + 0x08) /* D2 state control */
-+#define PLL2_CONTROL (PM_BASE + 0x18) /* PLL2 programming */
-+#define PLL3_CONTROL (PM_BASE + 0x1C) /* PLL3 programming */
-+
-+/* PM_MISC */
-+#define PLL1_N_BIT5 0x00000001UL /* Bit 5 of PLL1 N parameter */
-+#define PLL2_ENABLE 0x00000004UL /* PLL2 can be enabled */
-+#define PLL3_ENABLE 0x00000008UL /* PLL3 can be enabled */
-+#define FORCE_POWER_STATE 0x00000020UL /* For testing */
-+#define GE_ENABLE 0x00000100UL /* GE can be enabled */
-+#define GE_CLOCK_ON 0x00000200UL /* GE clock is always running */
-+#define GE_PIPELINE_ON 0x00000400UL /* GE pipeline always running */
-+#define GE_BY_BUS 0x00000000UL /* GE driven by bus intf clk */
-+#define GE_BY_PLL1 0x00000800UL /* GE driven by PLL1 */
-+#define GE_BY_PLL2 0x00001000UL /* GE driven by PLL2 */
-+#define GE_BY_PLL3 0x00001800UL /* GE driven by PLL3 */
-+#define GE_BY_MASK 0x00001800UL /* GE clock select mask */
-+#define GE_CMDFIFO_RESET 0x00002000UL /* GE command FIFO is reset */
-+#define GE_SRCFIFO_RESET 0x00004000UL /* GE CPU src FIFO is reset */
-+#define POWER_ON_IF_MIU_ON 0x00008000UL /* Pwr seq on when MIU enab.*/
-+#define D3_MEM_REFRESF 0x00010000UL /* FrameBuf refreshed in D3 */
-+#define D4_MEM_REFRESF 0x00020000UL /* FrameBuf refreshed in D4 */
-+#define PMCLK_4CYCLE 0x00000000UL /* Power sequencing interval */
-+#define PMCLK_8CYCLE 0x00040000UL /* Power sequencing interval */
-+#define PMCLK_16CYCLE 0x00080000UL /* Power sequencing interval */
-+#define PMCLK_2048CYCLE 0x000c0000UL /* Power sequencing interval */
-+#define FP_PMCLK_512 0x00000000UL /* FP power seq interval */
-+#define FP_PMCLK_1024 0x00100000UL /* FP power seq interval */
-+#define FP_PMCLK_2048 0x00200000UL /* FP power seq interval */
-+#define FP_PMCLK_128K 0x00300000UL /* FP power seq interval */
-+#define POWER_SEQ_ALL 0x00400000UL /* General power seq interval */
-+#define PMU_TEST_MODE 0x008000UL /* PMU test mode */
-+#define PM_POWER_MASK 0x03000000UL /* Power state mask */
-+#define PM_D0_STATE 0x00000000UL /* Power state D0 */
-+#define PM_D1_STATE 0x01000000UL /* Power state D1 */
-+#define PM_D2_STATE 0x02000000UL /* Power state D2 */
-+#define PM_D3_STATE 0x03000000UL /* Power state D3 */
-+#define POWER_IN_PROGRESS 0x04000000UL /* Power seq. active status */
-+
-+/* D1_STATE and D2_STATE */
-+#define DxOSC_ENABLE 0x00000001UL /* Oscillator can be enabled in D1/2 */
-+#define DxPLL1_ENABLE 0x00000002UL /* PLL1 can be enabled in D1/2 */
-+#define DxPLL2_ENABLE 0x00000004UL /* PLL2 can be enabled in D1/2 */
-+#define DxPLL3_ENABLE 0x00000008UL /* PLL3 can be enabled in D1/2 */
-+#define DxMIU_ENABLE 0x00000010UL /* MIU can be enabled in D1/2 */
-+#define DxMEM_REFRESH 0x00000020UL /* Memory is refreshed in D1/2 */
-+#define DxGE_ENABLE 0x00000040UL /* GE can be enabled in D1/2 */
-+#define DxCRT_ENABLE 0x00000100UL /* CRT can be enabled in D1/2 */
-+#define DxFP_ENABLE 0x00000200UL /* Flat panel can be enabled in D1/2 */
-+#define DxGC1_ENABLE 0x00010000UL /* GC1 can be enabled in D1/2 */
-+#define DxW1_ENABLE 0x00020000UL /* Window 1 can be enabled in D1/2 */
-+#define DxAW1_ENABLE 0x00040000UL /* Alt window 1 enabled in D1/2 */
-+#define DxHC1_ENABLE 0x00080000UL /* Cursor 1 enabled in D1/2 */
-+#define DxGC2_ENABLE 0x01000000UL /* GC2 can be enabled in D1/2 */
-+#define DxW2_ENABLE 0x02000000UL /* Window 2 can be enabled in D1/2 */
-+#define DxAW2_ENABLE 0x04000000UL /* Alt window 2 enabled in D1/2 */
-+#define DxHC2_ENABLE 0x08000000UL /* Cursor 2 enabled in D1/2 */
-+
-+/* PLL2_CONTROL/PLL3_CONTROL */
-+#define PLL_FROM_OSC 0x00000000UL /* PLL2/3 ref clock from OSCCLK */
-+#define PLL_FROM_PxCLK 0x00000001UL /* PLL2/3 ref clock from P2CLK */
-+#define PLL_BYPASSED 0x00000002UL /* PLL2/3 is bypassed */
-+#define PLL_DIVBY1 0x00000000UL /* PLL2/3 P output divisor by 1 */
-+#define PLL_DIVBY2 0x00000010UL /* PLL2/3 P output divisor by 2 */
-+#define PLL_DIVBY4 0x00000020UL /* PLL2/3 P output divisor by 4 */
-+#define PLL_DIVBY8 0x00000030UL /* PLL2/3 P output divisor by 8 */
-+#define PLL_DIVBY16 0x00000040UL /* PLL2/3 P output divisor by 16 */
-+#define PLL_DIV_MASK 0x00000070UL /* PLL2/3 P output divisor mask */
-+
-+/* CPU Interface Registers */
-+#define CPU_CONTROL (CC_BASE + 0x00) /* CPU control register */
-+#define DRAW_STATUS (CC_BASE + 0x04) /* Drawing status register */
-+
-+/* CPU_CONTROL */
-+#define SW_RESET 0x00000002UL /* Reset all modules except CIF */
-+#define MIU_READ_REQ 0x00000004UL /* MIU read request */
-+#define CLKRUN_ENABLE 0x00000008UL /* CLKRUN enabled. On Pwr-on, disab. */
-+
-+/* DRAW_STATUS */
-+#define CMD_FIFO_MASK 0x0000001fUL /* Command FIFO entries mask */
-+#define SRC_FIFO_MASK 0x00000f00UL /* Source FIFO entry mask */
-+#define GE_BUSY 0x00010000UL /* Any command in Comm FIFO */
-+#define CMD_FIFO_FULL 0x00000000UL /* Cmd fifo full bit */
-+#define CMD_FIFO_EMPTY 0x00000010UL /* Cmd fifo empty, 16x32 bits free */
-+#define SRC_FIFO_FULL 0x00000000UL /* Src fifo full bit */
-+#define SRC_FIFO_EMPTY 0x00000800UL /* Src fifo empty, 8x128 bits free */
-+
-+#define CMD_FIFO_CNT 16 /* Command FIFO full entry */
-+#define CMD_FIFO_MAX_INDEX 64
-+#define SRC_FIFO_MAX_BYTES 128 /* max pixels in src fifo - 8bits */
-+#define SRC_FIFO_MAX_WORDS 64 /* max pixels in src fifo - 16bits */
-+#define SRC_FIFO_MAX_DWORDS 32 /* max dwords in src fifo - 32bits */
-+
-+/* MIU (Memory Interface Unit) Registers */
-+#define MIU_CONTROL1 (MM_BASE + 0x00) /* Memory interface control 1 */
-+#define MIU_CONTROL2 (MM_BASE + 0x04) /* Memory interface control 2 */
-+#define MIU_CONTROL3 (MM_BASE + 0x08) /* Memory interface control 3 */
-+#define MIU_CONTROL4 (MM_BASE + 0x0C) /* Memory interface control 4 */
-+#define MIU_CONTROL5 (MM_BASE + 0x10) /* Memory interface control 5 */
-+
-+/* MIU_CONTROL1 */
-+#define MIU_ENABLE 0x00000001UL /* Enable MIU */
-+#define MIU_RESET_DISABLE 0x00000002UL /* MIU reset is disabled */
-+#define DRAM_RESET_DISABLE 0x00000004UL /* DRAM reset is disabled */
-+
-+/* MIU_CONTROL2 */
-+#define CLK_FROM_BUS 0x00000001UL /* Bus clk for mem clk src */
-+#define CLK_FROM_PLL2 0x00000001UL /* PLL2 for mem clock source */
-+#define MEM_REFRESH_ENABLE 0x00000002UL /* Mem ref disab at pwr dw mod*/
-+#define CPU_PB_ENABLE 0x00000004UL /* Page Break enab after CPU mem cyc */
-+#define GC1_PB_ENABLE 0x00000008UL /* Page Break after GC1 mem cycles */
-+#define GC2_PB_ENABLE 0x00000010UL /* Page Break after GC2 mem cycles */
-+#define STN_R_PB_ENABLE 0x00000020UL /* Page Break after STN read mem cyc */
-+#define STN_W_PB_ENABLE 0x00000040UL /* Page Break after STN wr. mem cyc */
-+#define GE_PB_ENABLE 0x00000080UL /* Page Break after GE memory cycles */
-+#define AUTO_REF_ENABLE 0x40000000UL /* Standby sig enab. when MIU active */
-+#define STANDBY_ENABLE 0x80000000UL /* Standby sig enab. when MIU active */
-+
-+/* MIU_CONTROL3 */
-+#define DISPLAY_BURST2 0x00000000UL /* Burst size for disp mem refresh */
-+#define DISPLAY_BURST4 0x00000001UL
-+#define DISPLAY_BURST6 0x00000002UL
-+#define DISPLAY_BURST8 0x00000003UL
-+#define STN_R_BURST2 0x00000000UL /* Burst size for STN read mem cycle */
-+#define STN_R_BURST4 0x00000004UL
-+#define STN_R_BURST6 0x00000008UL
-+#define STN_R_BURST8 0x0000000cUL
-+#define STN_W_BURST2 0x00000000UL /* Burst size for STN write mem cyc */
-+#define STN_W_BURST4 0x00000010UL
-+#define STN_W_BURST6 0x00000020UL
-+#define STN_W_BURST8 0x00000030UL
-+#define GE_RW_BURST2 0x00000000UL /* Burst size for GE r/w mem cycle */
-+#define GE_RW_BURST4 0x00000040UL
-+#define GE_RW_BURST6 0x00000080UL
-+#define GE_RW_BURST8 0x000000c0UL
-+#define CPU_RW_BURST2 0x00000000UL /* Burst size for CPU r/w mem cycle */
-+#define CPU_RW_BURST4 0x00000100UL
-+#define CPU_RW_BURST6 0x00000200UL
-+#define CPU_RW_BURST8 0x00000300UL
-+
-+/* MIU_CONTROL4 */
-+#define R_LATENCY_REQUEST 0x00000001UL /* Read Latency Request */
-+
-+/* MIU_CONTROL5 */
-+#define LATENCY_1 0x00000001UL /* EDRAM Latency 1 */
-+#define LATENCY_2 0x00000005UL /* EDRAM Latency 2 */
-+#define LATENCY_3 0x00000007UL /* EDRAM Latency 3 */
-+#define DUMMY_IN_COMMANDS 0x00000008UL /* Dummy cycle insertion betw cmds */
-+#define DUMMY_IN_PRECHARGE 0x00000010UL /* Dummy cyc between precharge cyc */
-+#define DELAY_1ns 0x00000000UL /* Internal memory clock delay */
-+#define ACT_TO_CLOSE_3 0x00000100UL /* Bank activate to close - 3 mclk */
-+#define ACT_TO_CLOSE_4 0x00000200UL /* Bank activate to close - 4 mclk */
-+#define ACT_TO_CLOSE_5 0x00000300UL /* Bank activate to close - 5 mclk */
-+#define ACT_TO_COMMAND_2 0x00000000UL /* Bank activate to cmd r/w - 2 mclk */
-+#define ACT_TO_COMMAND_3 0x00000400UL /* Bank activate to cmd r/w - 3 mclk */
-+#define CLOSE_TO_ACT_2 0x00000000UL /* Bank close to activate - 2 mclk */
-+#define CLOSE_TO_ACT_3 0x00000800UL /* Bank close to activate - 3 mclk */
-+#define ROW_CYCLE_6 0x00000000UL /* Row Cycle time - 6 memory clock */
-+#define ROW_CYCLE_8 0x00001000UL /* Row Cycle time - 8 memory clock */
-+#define DELAY_R_CLOCK_0_0 0x00000000UL /* Delay for read clock - no delay */
-+#define DELAY_R_CLOCK_0_5 0x00010000UL /* Delay for read clock - 0.5ns */
-+#define DELAY_R_CLOCK_1_0 0x00020000UL /* Delay for read clock - 1.0ns */
-+#define DELAY_R_CLOCK_1_5 0x00030000UL /* Delay for read clock - 1.5ns */
-+#define DELAY_M_CLOCK_0_0 0x00000000UL /* Delay for memory clock - no delay */
-+#define DELAY_M_CLOCK_0_5 0x00020000UL /* Delay for memory clock - 0.5ns */
-+#define DELAY_M_CLOCK_1_0 0x00080000UL /* Delay for memory clock - 1.0ns */
-+#define DELAY_M_CLOCK_1_5 0x000c0000UL /* Delay for memory clock - 1.5ns */
-+
-+
-+/*
-+ * Data structure and defines for MQ chip and driver interface
-+ */
-+
-+/* Display configuration structure - for interface */
-+typedef struct DisplayConfig
-+{
-+ int x; /* x resolution */
-+ int y; /* y resolution */
-+ int bpp; /* color depth */
-+ int refresh; /* CRT refresh rate */
-+ int stride; /* memory stride */
-+ unsigned long flag; /* display flag */
-+} DISPLAY_CONFIG, *PDISPLAY_CONFIG;
-+
-+/* Flag definition */
-+#define PANEL_TYPE_MASK 0x000000ff /* Panel type mask */
-+#define PROCESSOR_MASK 0x00003f00 /* Mask of processor type */
-+#define IS_SH3 0x00000000
-+#define IS_SH4 0x00000100
-+#define IS_NEC 0x00000200
-+#define IS_SARM 0x00000300
-+#define IS_TOSHIBA 0x00000400
-+#define IS_PCI 0x00000500
-+#define LCD_ON 0x00010000 /* LCD mode */
-+#define CRT_ON 0x00020000 /* CRT mode */
-+#define LARGE_DESKTOP 0x00040000 /* Large desktop mode is on */
-+#define INDEP_DISPLAY 0x00080000 /* Independent display */
-+#define SAME_IMAGE 0x00100000 /* Use 2 GC but same image */
-+#define USE_2GCs 0x001C0000 /* 2 GCs are used */
-+#define USE_2GCs_MASK 0x001C0000 /* mask for 2 GCs */
-+#define ENA_HW_CURSOR 0x00200000 /* Enable hw cursor */
-+#define HORI_LCD_CRT 0x00000000 /* QView hori arrangement */
-+#define HORI_CRT_LCD 0x10000000 /* QView hori arrangement */
-+#define VERT_CRT_LCD 0x20000000 /* QView vert arrangement */
-+#define VERT_LCD_CRT 0x30000000 /* QView vert arrangement */
-+#define LCDCRT_POS_MASK 0x30000000 /* mask for QV orientation */
-+
-+/* Display timing structure */
-+typedef struct DisplayTiming
-+{
-+ int x; /* x resolution */
-+ int y; /* y resolution */
-+ int refresh; /* refresh rate */
-+ unsigned long hd; /* hori display control */
-+ unsigned long vd; /* vert display control */
-+ unsigned long hs; /* hori sync control */
-+ unsigned long vs; /* vert sync control */
-+ unsigned long crtc; /* crt control */
-+ unsigned long pll; /* PLL2 or PLL3 setting */
-+} DISPLAY_TIMING, *PDISPLAY_TIMING;
-+
-+/* Flat panel register */
-+typedef struct FPControl
-+{
-+ int x; /* panel size x */
-+ int y; /* panel size y */
-+ int freq; /* panel freq */
-+ unsigned long fpControl; /* flat panel control */
-+ unsigned long fpPinControl; /* flat panel pin control */
-+ unsigned long stnControl; /* stn panel control */
-+} FPDATA_CONTROL, *PFPDATA_CONTROL;
-+
-+/* Frame rate control */
-+#define FRC_PATTERN_CNT 32
-+#define FRC_WEIGHT_CNT 8
-+typedef struct FRCControl
-+{
-+ ULONG frcPattern[FRC_PATTERN_CNT]; /* FRC pattern control */
-+ ULONG frcWeight[FRC_WEIGHT_CNT]; /* FRC weight control */
-+} FRC_CONTROL, *PFRC_CONTROL;
-+
-+/* Miscellaneous defines */
-+#define IS_GC1 1
-+#define IS_GC2 2
-+
-+/* Turn on/off display */
-+#define ENABLE_LCD_GC1 0
-+#define ENABLE_LCD_GC2 1
-+#define DISABLE_LCD_GC1 2
-+#define DISABLE_LCD_GC2 3
-+#define ENABLE_CRT_GC1 4
-+#define ENABLE_CRT_GC2 5
-+#define DISABLE_CRT_GC1 6
-+#define DISABLE_CRT_GC2 7
-+
-+/*
-+ * Handy macro
-+ *
-+ */
-+/*
-+#define CHECK_IF_STATE_D(s) {\
-+ unsigned long ulState = (s);\
-+ unsigned long ulPMReg;\
-+ while(1)\
-+ {\
-+ ulPMReg = READ32(PCI_PM_CNTL_STATUS);\
-+ if((ulPMReg &0x03) == ulState)\
-+ break;\
-+ } }
-+*/
-+#endif /* _VIDEO_MQ200_MQ2HW_H */
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/video/MQ200/mqdata.h 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,754 @@
-+/***************************************************************************
-+ MQDATA.C
-+
-+ This file contains timing and flat panel parameters for MediaQ graphics
-+ chip.
-+
-+ Copyright (c) 2000 by MediaQ, Incorporated.
-+ All Rights Reserved.
-+
-+***************************************************************************/
-+#ifndef _VIDEO_MQ200_MQDATA_H
-+#define _VIDEO_MQ200_MQDATA_H
-+/* LCD/CRT timing parameters for each resolution - VESA modes
-+ *
-+ * . the first entry is reserved to provide customized panel timing support
-+ * . OEM can fill in proper timing for non-VESA LCD (or CRT)
-+ *
-+ */
-+DISPLAY_TIMING TimingParam[] =
-+{
-+ { /* customized refresh rate - reserved for non-VESA panel timing */
-+ 0,0,0, /* X/Y/Freq */
-+ 0, /* HD Total + HD End */
-+ 0, /* VD Total + VD End */
-+ 0, /* HS Start + HS End */
-+ 0, /* VS Start + VS End */
-+ 0x00000000, /* CRT control */
-+ 0x00000000, /* PLLx multiplier and control */
-+ },
-+
-+ { /* 640 x 240 90Hz (25.175 MHz) */
-+ 640,240,90, /* X/Y/Freq */
-+ (793-2) | (640L << 16), /* HD Total + HD End */
-+ (262-1) | ((240L-1) << 16), /* VD Total + VD End */
-+ 647 | (704L << 16), /* HS Start + HS End */
-+ 245 | (246L << 16), /* VS Start + VS End */
-+ HSYNC_POLARITY_LOW|VSYNC_POLARITY_LOW|BLANK_PED_ENABLE,
-+ /* CRT control */
-+ 0x00a30930, /* PLLx multiplier and control */
-+ },
-+
-+ { /* 640 x 480 60Hz (25.175 MHz) */
-+ 640,480,60, /* X/Y/Freq */
-+ (800-2) | (640L << 16), /* HD Total + HD End */
-+ (525-1) | ((480L-1) << 16), /* VD Total + VD End */
-+ 656 | (752L << 16), /* HS Start + HS End */
-+ 490 | (492L << 16), /* VS Start + VS End */
-+ HSYNC_POLARITY_LOW|VSYNC_POLARITY_LOW|BLANK_PED_ENABLE,
-+ /* CRT control */
-+ 0x00a30930, /* PLLx multiplier and control */
-+ },
-+
-+ { /* 640 x 480 72Hz (31.5 MHz) */
-+ 640,480,72, /* X/Y/Freq */
-+ (832-2) | (640L << 16), /* HD Total + HD End */
-+ (520-1) | ((480L-1) << 16), /* VD Total + VD End */
-+ 688 | (728L << 16), /* HS Start + HS End */
-+ 489 | (492L << 16), /* VS Start + VS End */
-+ HSYNC_POLARITY_LOW|VSYNC_POLARITY_LOW|BLANK_PED_ENABLE,
-+ /* CRT control */
-+ 0x00f50b30, /* PLLx multiplier and control */
-+ },
-+
-+ { /* 640 x 480 75Hz (31.5 MHz) */
-+ 640,480,75, /* X/Y/Freq */
-+ (840-2) | (640L << 16), /* HD Total + HD End */
-+ (500-1) | ((480L-1) << 16), /* VD Total + VD End */
-+ 680 | (744L << 16), /* HS Start + HS End */
-+ 481 | (484L << 16), /* VS Start + VS End */
-+ HSYNC_POLARITY_LOW|VSYNC_POLARITY_LOW|BLANK_PED_ENABLE,
-+ /* CRT control */
-+ 0x00f50b30, /* PLLx multiplier and control */
-+ },
-+
-+ { /* 640 x 480 85Hz (36 MHz) */
-+ 640,480,85, /* X/Y/Freq */
-+ (832-2) | (640L << 16), /* HD Total + HD End */
-+ (509-1) | ((480L-1) << 16), /* VD Total + VD End */
-+ 696 | (752L << 16), /* HS Start + HS End */
-+ 481 | (484L << 16), /* VS Start + VS End */
-+ HSYNC_POLARITY_LOW|VSYNC_POLARITY_LOW|BLANK_PED_ENABLE,
-+ /* CRT control */
-+ 0x00d20830, /* PLLx multiplier and control */
-+ },
-+
-+ { /* 800 x 600 60Hz (40 MHz) */
-+ 800,600,60, /* X/Y/Freq */
-+ (1056-2) | (800L << 16), /* HD Total + HD End */
-+ (628-1) | ((600L-1) << 16), /* VD Total + VD End */
-+ 839 | (967L << 16), /* HS Start + HS End */
-+ 601 | (605L << 16), /* VS Start + VS End */
-+ BLANK_PED_ENABLE, /* CRT control */
-+ 0x00e90830, /* PLLx multiplier and control */
-+ },
-+
-+ { /* 800 x 600 72Hz 50 MHz) */
-+ 800,600,72, /* X/Y/Freq */
-+ (1040-2) | (800L << 16), /* HD Total + HD End */
-+ (666-1) | ((600L-1) << 16), /* VD Total + VD End */
-+ 856 | (976L << 16), /* HS Start + HS End */
-+ 637 | (643L << 16), /* VS Start + VS End */
-+ BLANK_PED_ENABLE, /* CRT control */
-+ 0x00b20a20, /* PLLx multiplier and control */
-+ },
-+
-+ { /* 800 x 600 75Hz (49.5 MHz) */
-+ 800,600,75, /* X/Y/Freq */
-+ (1056-2) | (800L << 16), /* HD Total + HD End */
-+ (625-1) | ((600L-1) << 16), /* VD Total + VD End */
-+ 816 | (896L << 16), /* HS Start + HS End */
-+ 601 | (604L << 16), /* VS Start + VS End */
-+ BLANK_PED_ENABLE, /* CRT control */
-+ 0x00900820, /* PLLx multiplier and control */
-+ },
-+
-+ { /* 800 x 600 85Hz (56.25 MHz) */
-+ 800,600,85, /* X/Y/Freq */
-+ (1047-2) | (800L << 16), /* HD Total + HD End */
-+ (631-1) | ((600L-1) << 16), /* VD Total + VD End */
-+ 832 | (896L << 16), /* HS Start + HS End */
-+ 601 | (604L << 16), /* VS Start + VS End */
-+ BLANK_PED_ENABLE, /* CRT control */
-+ 0x00b60920, /* PLLx multiplier and control */
-+ },
-+
-+ { /* 1024 x 768 60Hz (65 MHz) */
-+ 1024,768,60, /* X/Y/Freq */
-+ (1344-2) | (1024L << 16), /* HD Total + HD End */
-+ (806-1) | ((768L-1) << 16), /* VD Total + VD End */
-+ 1048 | (1184L << 16), /* HS Start + HS End */
-+ 771 | (777L << 16), /* VS Start + VS End */
-+ HSYNC_POLARITY_LOW|VSYNC_POLARITY_LOW|BLANK_PED_ENABLE,
-+ /* CRT control */
-+ 0x00fd0b20, /* PLLx multiplier and control */
-+ },
-+
-+ { /* 1024 x 768 70Hz (75 MHz) */
-+ 1024,768,70, /* X/Y/Freq */
-+ (1327-2) | (1024L << 16), /* HD Total + HD End */
-+ (806-1) | ((768L-1) << 16), /* VD Total + VD End */
-+ 1047 | (1183L << 16), /* HS Start + HS End */
-+ 771 | (777L << 16), /* VS Start + VS End */
-+ HSYNC_POLARITY_LOW|VSYNC_POLARITY_LOW|BLANK_PED_ENABLE,
-+ /* CRT control */
-+ 0x00f30920, /* PLLx multiplier and control */
-+ },
-+
-+ { /* 1024 x 768 75Hz (78.750 MHz) */
-+ 1024,768,75, /* X/Y/Freq */
-+ (1312-2) | (1024L << 16), /* HD Total + HD End */
-+ (806-1) | ((768L-1) << 16), /* VD Total + VD End */
-+ 1040 | (1136L << 16), /* HS Start + HS End */
-+ 769 | (772L << 16), /* VS Start + VS End */
-+ BLANK_PED_ENABLE, /* CRT control */
-+ 0x00cc0720, /* PLLx multiplier and control */
-+ },
-+
-+ { /* 1024 x 768 85Hz (94.5 MHz) */
-+ 1024,768,85, /* X/Y/Freq */
-+ (1375-2) | (1024L << 16), /* HD Total + HD End */
-+ (808-1) | ((768L-1) << 16), /* VD Total + VD End */
-+ 1072 | (1168L << 16), /* HS Start + HS End */
-+ 769 | (772L << 16), /* VS Start + VS End */
-+ BLANK_PED_ENABLE, /* CRT control */
-+ 0x007a0710, /* PLLx multiplier and control */
-+ }
-+};
-+#define MAX_MQMODE (sizeof(TimingParam) / sizeof(TimingParam[0]))
-+
-+/* Flat panel control registers
-+ */
-+FPDATA_CONTROL fpControlData[] =
-+{
-+ /* Type 0 : OEM Specific panel
-+ */
-+ { /* Flat panel info */
-+ 0, 0, 0,
-+
-+ /* Flat panel Control */
-+ 0
-+ ,
-+
-+ /* Flat panel pin control */
-+ 0
-+ ,
-+
-+ /* STN panel control */
-+ 0x0
-+ },
-+ /* Type 1 : SSTN VGA 8Bit Color - 72Hz
-+ * - Sanyo SSTN 640x480 8-bit color interface
-+ */
-+ { /* Flat panel info */
-+ 640, 480, 72,
-+
-+ /* Flat panel Control */
-+ FP_TYPE_SSTN
-+ | FP_COLOR
-+ | SSTN_8BITS_MONOCLR
-+ | DITHER_PATTERN_3
-+ | DITHER_BASE_4BITS
-+ | FRC_16LEVEL
-+ | 0x00400000
-+ ,
-+
-+ /* Flat panel pin control */
-+ FSCLK_OUTPUT_ENABLE
-+ | SCLK_MASK
-+ | FDE_ACTIVE_L
-+ ,
-+
-+ /* STN panel control */
-+ 0x00bd0000
-+ },
-+
-+ /* Type 2 : DSTN 16 Bit VGA Color - 72Hz
-+ * - Hitachi 8.2" SX21V001
-+ * - Sanyo 10.4" LM-CJ53-22NTK
-+ * - Sharp 10.4" LM64C35P
-+ */
-+ { /* Flat panel info */
-+ 640, 480, 72,
-+
-+ /* Flat panel Control */
-+ FP_TYPE_DSTN
-+ | FP_COLOR
-+ | DSTN_16BITS_MONOCLR
-+ | DITHER_PATTERN_3
-+ | DITHER_BASE_4BITS
-+ | FRC_16LEVEL
-+ | 0x0c840000
-+ ,
-+
-+ /* Flat panel pin control */
-+ FSCLK_OUTPUT_ENABLE
-+ | SCLK_MASK
-+ | FDE_ACTIVE_L
-+ ,
-+
-+ /* STN panel control */
-+ 0x00bd0001
-+ },
-+
-+ /* Type 3 : TFT 18 Bit VGA - 60Hz
-+ * - NEC 10.4" NL6448AC33-24
-+ */
-+ { /* Flat panel info */
-+ 640, 480, 60,
-+
-+ /* Flat panel Control */
-+ FP_TYPE_TFT
-+ | FP_COLOR
-+ | TFT_18BITS_COLOR
-+ | DITHER_PATTERN_3
-+ | DITHER_BASE_6BITS
-+ ,
-+
-+ /* Flat panel pin control */
-+ FSCLK_OUTPUT_ENABLE
-+ ,
-+
-+ /* STN panel control */
-+ 0x00bd0001
-+ },
-+
-+ /* Type 4 : TFT 18 Bit SVGA - 60Hz
-+ * - Hitachi 12.1" 800x600 TX31D24VC1CAA
-+ */
-+ { /* Flat panel info */
-+ 800, 600, 60,
-+
-+ /* Flat panel Control */
-+ FP_TYPE_TFT
-+ | FP_COLOR
-+ | TFT_18BITS_COLOR
-+ | DITHER_PATTERN_3
-+ | DITHER_BASE_6BITS
-+ ,
-+
-+ /* Flat panel pin control */
-+ FSCLK_OUTPUT_ENABLE
-+ ,
-+
-+ /* STN panel control */
-+ 0x00bd0001
-+ },
-+
-+ /* Type 5 : DSTN 16Bit SVGA Color Panel - 72Hz
-+ * - Hitachi 10.0" SX25S001
-+ * - Hitachi 12.1" SX25S003
-+ */
-+ { /* Flat panel info */
-+ 800, 600, 72,
-+
-+ /* Flat panel Control */
-+ FP_TYPE_DSTN
-+ | FP_COLOR
-+ | DSTN_16BITS_MONOCLR
-+ | DITHER_PATTERN_3
-+ | DITHER_BASE_4BITS
-+ | FRC_16LEVEL
-+ | 0x0c840000
-+ ,
-+
-+ /* Flat panel pin control */
-+ FSCLK_OUTPUT_ENABLE
-+ | SCLK_MASK
-+ | FDE_ACTIVE_L
-+ ,
-+
-+ /* STN panel control */
-+ 0x00bd0001
-+ },
-+
-+ /* Type 6 : DSTN 8 Bit VGA Color - 72Hz
-+ */
-+ { /* Flat panel info */
-+ 640, 480, 72,
-+
-+ /* Flat panel Control */
-+ FP_TYPE_DSTN
-+ | FP_COLOR
-+ | DSTN_8BITS_MONOCLR
-+ | DITHER_PATTERN_3
-+ | DITHER_BASE_4BITS
-+ | FRC_16LEVEL
-+ | 0x0c840000
-+ ,
-+
-+ /* Flat panel pin control */
-+ FSCLK_OUTPUT_ENABLE
-+ | SCLK_MASK
-+ | FDE_ACTIVE_L
-+ ,
-+
-+ /* STN panel control */
-+ 0x00bd0001
-+ },
-+
-+ /* Type 7 : SSTN VGA 16Bit Color - 72Hz
-+ */
-+ { /* Flat panel info */
-+ 640, 480, 72,
-+
-+ /* Flat panel Control */
-+ FP_TYPE_SSTN
-+ | FP_COLOR
-+ | SSTN_16BITS_MONOCLR
-+ | DITHER_PATTERN_3
-+ | DITHER_BASE_4BITS
-+ | FRC_16LEVEL
-+ | 0x00400000
-+ ,
-+
-+ /* Flat panel pin control */
-+ FSCLK_OUTPUT_ENABLE
-+ | SCLK_MASK
-+ | FDE_ACTIVE_L
-+ ,
-+
-+ /* STN panel control */
-+ 0x00bd0000
-+ },
-+
-+ /* Type 8 : SSTN VGA 8Bit Color - 60Hz
-+ * - Sanyo SSTN 640x480 8-bit color interface
-+ */
-+ { /* Flat panel info */
-+ 640, 480, 60,
-+
-+ /* Flat panel Control */
-+ FP_TYPE_SSTN
-+ | FP_COLOR
-+ | SSTN_8BITS_MONOCLR
-+ | DITHER_PATTERN_3
-+ | DITHER_BASE_4BITS
-+ | FRC_16LEVEL
-+ | 0x00400000
-+ ,
-+
-+ /* Flat panel pin control */
-+ FSCLK_OUTPUT_ENABLE
-+ | SCLK_MASK
-+ | FDE_ACTIVE_L
-+ ,
-+
-+ /* STN panel control */
-+ 0x00bd0000
-+ },
-+
-+ /* Type 9 : DSTN 16 Bit VGA Color - 60Hz
-+ * - Hitachi 8.2" SX21V001
-+ * - Sanyo 10.4" LM-CJ53-22NTK
-+ * - Sharp 10.4" LM64C35P
-+ */
-+ { /* Flat panel info */
-+ 640, 480, 60,
-+
-+ /* Flat panel Control */
-+ FP_TYPE_DSTN
-+ | FP_COLOR
-+ | DSTN_16BITS_MONOCLR
-+ | DITHER_PATTERN_1
-+ | DITHER_BASE_4BITS
-+ | FRC_16LEVEL
-+ | 0x0c840000
-+ ,
-+
-+ /* Flat panel pin control */
-+ FSCLK_OUTPUT_ENABLE
-+ | SCLK_MASK
-+ | FDE_ACTIVE_L
-+ ,
-+
-+ /* STN panel control */
-+ 0x00bd0001
-+ },
-+
-+ /* Type 10 : DSTN 16Bit SVGA Color Panel - 60Hz
-+ * - Hitachi 10.0" SX25S001
-+ * - Hitachi 12.1" SX25S003
-+ * - Sanyo LM-FC53-22NTK
-+ */
-+ { /* Flat panel info */
-+ 800, 600, 60,
-+
-+ /* Flat panel Control */
-+#if 1
-+ 0x0C1B4128
-+#else
-+ FP_TYPE_DSTN
-+ | FP_COLOR
-+ | DSTN_16BITS_MONOCLR
-+ | DITHER_PATTERN_3
-+ | DITHER_BASE_4BITS
-+ | FRC_16LEVEL
-+ | 0x0C840000
-+#endif
-+ ,
-+
-+ /* Flat panel pin control */
-+ FSCLK_OUTPUT_ENABLE
-+ | SCLK_MASK
-+ | FDE_ACTIVE_L
-+ ,
-+
-+ /* STN panel control */
-+ 0x00bd0001
-+ },
-+
-+ /* Type 11 : DSTN 24Bit XGA Color Panel - 60Hz
-+ * - Hitachi 12.1" SX25S003
-+ */
-+ { /* Flat panel info */
-+ 1024, 768, 60,
-+
-+ /* Flat panel Control */
-+ FP_TYPE_DSTN
-+ | FP_COLOR
-+ | DSTN_24BITS_COLOR
-+ | DITHER_PATTERN_3
-+ | DITHER_BASE_4BITS
-+ | FRC_16LEVEL
-+ | 0x0c840000
-+ ,
-+
-+ /* Flat panel pin control */
-+ FSCLK_OUTPUT_ENABLE
-+ | SCLK_MASK
-+ | FDE_ACTIVE_L
-+ ,
-+
-+ /* STN panel control */
-+ 0x00bd0001
-+ },
-+
-+ /* Type 12 : DSTN 16Bit XGA Color Panel - 60Hz
-+ * - Hitachi 12.1" SX25S003
-+ */
-+ { /* Flat panel info */
-+ 1024, 768, 60,
-+
-+ /* Flat panel Control */
-+ FP_TYPE_DSTN
-+ | FP_COLOR
-+ | DSTN_16BITS_MONOCLR
-+ | DITHER_PATTERN_3
-+ | DITHER_BASE_4BITS
-+ | FRC_16LEVEL
-+ | 0x0c840000
-+ ,
-+
-+ /* Flat panel pin control */
-+ FSCLK_OUTPUT_ENABLE
-+ | SCLK_MASK
-+ | FDE_ACTIVE_L
-+ ,
-+
-+ /* STN panel control */
-+ 0x00bd0001
-+ },
-+
-+ /* Type 13 : TFT 18Bit XGA - 60Hz
-+ * - Hitachi 12.1" 800x600 TX31D24VC1CAA
-+ */
-+ { /* Flat panel info */
-+ 1024, 768, 60,
-+
-+ /* Flat panel Control */
-+ FP_TYPE_TFT
-+ | FP_COLOR
-+ | TFT_18BITS_COLOR
-+ | DITHER_PATTERN_3
-+ | DITHER_BASE_6BITS
-+ ,
-+
-+ /* Flat panel pin control */
-+ FSCLK_OUTPUT_ENABLE
-+ | FHSYNC_ACTIVE_L
-+ | FVSYNC_ACTIVE_L
-+ ,
-+
-+ /* STN panel control */
-+ 0x00bd0001
-+ },
-+
-+ /* Type 14 : TFT 24Bit XGA - 60Hz
-+ * - Hitachi 12.1" 800x600 TX31D24VC1CAA
-+ */
-+ { /* Flat panel info */
-+ 1024, 768, 60,
-+
-+ /* Flat panel Control */
-+ FP_TYPE_TFT
-+ | FP_COLOR
-+ | TFT_24BITS_COLOR
-+ | DITHER_PATTERN_3
-+ | DITHER_BASE_6BITS
-+ ,
-+
-+ /* Flat panel pin control */
-+ FSCLK_OUTPUT_ENABLE
-+ | FHSYNC_ACTIVE_L
-+ | FVSYNC_ACTIVE_L
-+ ,
-+
-+ /* STN panel control */
-+ 0x00bd0001
-+ },
-+
-+ /* Type 15 : TFT 18 Bit SVGA - 60Hz (Similar to type 4)
-+ * - NEC 12.1" 800x600 TX31D24VC1CAA
-+ */
-+ { /* Flat panel control */
-+ 800, 600, 60,
-+
-+ /* Flat panel Control */
-+ FP_TYPE_TFT
-+ | FP_COLOR
-+ | TFT_18BITS_COLOR
-+ | DITHER_PATTERN_3
-+ | DITHER_BASE_6BITS
-+ ,
-+
-+ /* Flat panel pin control */
-+ FSCLK_OUTPUT_ENABLE
-+ | FHSYNC_ACTIVE_L
-+ | FVSYNC_ACTIVE_L
-+ | FSCLK_ACTIVE_L
-+ | FSCLK_DELAY
-+ ,
-+ /* STN panel control */
-+ 0x00bd0001
-+ },
-+
-+ /* Type 16 : SSTN VGA 8Bit Color - 90Hz
-+ * - Sharp LM8M64 SSTN 640x240 8-bit color interface
-+ */
-+ { /* Flat panel control */
-+ 640, 240, 90,
-+
-+ FP_TYPE_SSTN
-+ | FP_COLOR
-+ | SSTN_8BITS_MONOCLR
-+ | DITHER_PATTERN_1
-+ | DITHER_BASE_4BITS
-+ | FRC_16LEVEL
-+ | 0x00400000
-+ ,
-+
-+ FSCLK_OUTPUT_ENABLE
-+ | SCLK_MASK
-+ | FDE_ACTIVE_L
-+ ,
-+
-+ /* STN panel control */
-+ 0x00bd0000
-+ }
-+};
-+
-+/* Flat panel FRC weight/pattern registers - for SSTN and DSTN panel only
-+ *
-+ */
-+FRC_CONTROL FRCControlData[] =
-+{
-+ {
-+ {
-+ 0x97A4C5F8,
-+ 0x61E3DB02,
-+ 0xD3E081BC,
-+ 0x25A79F46,
-+ 0x5B680934,
-+ 0xAD2F17CE,
-+ 0x1F2C4D70,
-+ 0xE96B538A,
-+ 0x0E3D5C61,
-+ 0xF87A429B,
-+ 0x4A791825,
-+ 0xBC3E06DF,
-+ 0xC2F190AD,
-+ 0x34B68E57,
-+ 0x86B5D4E9,
-+ 0x70F2CA13,
-+ 0xF1C2A39E,
-+ 0x0785BD64,
-+ 0xB586E7DA,
-+ 0x43C1F920,
-+ 0x3D0E6F52,
-+ 0xCB4971A8,
-+ 0x794A2B16,
-+ 0x8F0D35EC,
-+ 0x685B3A07,
-+ 0x9E1C24FD,
-+ 0x2C1F7E43,
-+ 0xDA5860B9,
-+ 0xA497F6CB,
-+ 0x52D0E831,
-+ 0xE0D3B28F,
-+ 0x1694AC75,
-+ },
-+
-+ {
-+ /* FRC weight data */
-+ 0x80800000,
-+ 0x88888420,
-+ 0x94a49248,
-+ 0xaaaaaa54,
-+ 0x6b5b55ab,
-+ 0x77776db7,
-+ 0x7f7f7bdf,
-+ 0xffff7fff
-+ }
-+ },
-+
-+ /* FRC Pattern Data - 2FCA (for SSTN) */
-+ {
-+ {
-+ 0x97A4C5F8,
-+ 0x61E3DB02,
-+ 0xD3E081BC,
-+ 0x25A79F46,
-+ 0x4A791825,
-+ 0xBC3E06DF,
-+ 0x0E3D5C61,
-+ 0xF87A429B,
-+ 0xF1C2A39E,
-+ 0x0785BD64,
-+ 0xB586E7DA,
-+ 0x43C1F920,
-+ 0x2C1F7E43,
-+ 0xDA5860B9,
-+ 0x685B3A07,
-+ 0x9E1C24FD,
-+ 0xE0D3B28F,
-+ 0x1694AC75,
-+ 0xA497F6CB,
-+ 0x52D0E831,
-+ 0x3D0E6F52,
-+ 0xCB4971A8,
-+ 0x794A2B16,
-+ 0x8F0D35EC,
-+ 0x86B5D4E9,
-+ 0x70F2CA13,
-+ 0xC2F190AD,
-+ 0x34B68E57,
-+ 0x5B680934,
-+ 0xAD2F17CE,
-+ 0x1F2C4D70,
-+ 0xE96B538A,
-+ },
-+
-+ {
-+ /* FRC weight data */
-+ 0x80800000,
-+ 0x88888420,
-+ 0x94a49248,
-+ 0xaaaaaa54,
-+ 0x6b5b55ab,
-+ 0x77776db7,
-+ 0x7f7f7bdf,
-+ 0xffff7fff
-+ }
-+ },
-+
-+ /* FRC Pattern Data - (for Panletype 4-> Simpad) */
-+ {
-+ {
-+ 0x97A4C5F8,
-+ 0x61E3DB02,
-+ 0x3D0E6F52,
-+ 0xCB4971A8,
-+ 0x794A2B16,
-+ 0x8F0D35EC,
-+ 0xD3E081BC,
-+ 0x25A79F46,
-+ 0x1F2C4D70,
-+ 0xE96B538A,
-+ 0xB586E7DA,
-+ 0x43C1F920,
-+ 0xF1C2A39E,
-+ 0x0785BD64,
-+ 0x5B680934,
-+ 0xAD2F17CE,
-+ 0x794A2B16,
-+ 0x8F0D35EC,
-+ 0xD3E081BC,
-+ 0x25A79F46,
-+ 0x97A4C5F8,
-+ 0x61E3DB02,
-+ 0x3D0E6F52,
-+ 0xCB4971A8,
-+ 0xF1C2A39E,
-+ 0x0785BD64,
-+ 0x5B680934,
-+ 0xAD2F17CE,
-+ 0x1F2C4D70,
-+ 0xE96B538A,
-+ 0xB586E7DA,
-+ 0x43C1F920,
-+ },
-+ {
-+ /* FRC weight data */
-+ 0x80800000,
-+ 0x88888420,
-+ 0x94a49248,
-+ 0xaaaaaa54,
-+ 0x6b5b55ab,
-+ 0x77776db7,
-+ 0x7f7f7bdf,
-+ 0xffff7fff
-+ }
-+ }
-+};
-+#endif /* _VIDEO_MQ200_MQDATA_H */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/video/MQ200/mqmacros.h 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,86 @@
-+#ifndef _VIDEO_MQ200_MQMACROS_H
-+#define _VIDEO_MQ200_MQMACROS_H
-+
-+#ifdef CHECK_SRCFIFO
-+
-+#define PUMP_PACKED_SRCFIFO(pSrcData,srcStride,nDwords,height,extras) \
-+ { \
-+ u32 *pData; \
-+ u32 i,j; \
-+ while( height-- ) \
-+ { \
-+ pData = (u32 *)((u32)(pSrcData + 3UL) & ~0x03UL); \
-+ j = nDwords; \
-+ while ( j >= SRC_FIFO_MAX_DWORDS ) \
-+ { \
-+ geWAITSRCFIFO( SRC_FIFO_MAX_DWORDS ); \
-+ for ( i = 0; i < SRC_FIFO_MAX_DWORDS; i++ ) \
-+ geREG(SRC_IMAGE_DATA, *pData++); \
-+ j -= SRC_FIFO_MAX_DWORDS; \
-+ } \
-+ geWAITSRCFIFO( j ); \
-+ while( j-- ) \
-+ geREG(SRC_IMAGE_DATA, *pData++); \
-+ pSrcData += srcStride; \
-+ } \
-+ geWAITSRCFIFO( extras ); \
-+ while( extras-- ) \
-+ geREG(SRC_IMAGE_DATA, 0UL); \
-+ }
-+
-+
-+#define PUMP_REAL_PACKED_SRCFIFO(pSrcData,nDwords,extras) \
-+ { \
-+ u32 *pData =(u32 *)pSrcData; \
-+ u32 i; \
-+ while(nDwords) \
-+ { \
-+ if (nDwords >= SRC_FIFO_MAX_DWORDS) \
-+ { \
-+ geWAITSRCFIFO( SRC_FIFO_MAX_DWORDS ); \
-+ for (i = SRC_FIFO_MAX_DWORDS; i > 0; i--) \
-+ geREG(SRC_IMAGE_DATA, *pData++); \
-+ nDwords -= SRC_FIFO_MAX_DWORDS; \
-+ } \
-+ else \
-+ { \
-+ geWAITSRCFIFO( nDwords ); \
-+ for (i = nDwords; i > 0; i--) \
-+ geREG(SRC_IMAGE_DATA, *pData++); \
-+ nDwords -= nDwords; \
-+ } \
-+ } \
-+ geWAITSRCFIFO(extras); \
-+ while( extras-- ) \
-+ geREG(SRC_IMAGE_DATA, 0UL); \
-+ }
-+
-+#else /* CHECK_SRCFIFO */
-+
-+#define PUMP_PACKED_SRCFIFO(pSrcData,srcStride,nDwords,height,extras) \
-+ { \
-+ u32 *pData; \
-+ u32 i; \
-+ while( height-- ) \
-+ { \
-+ pData = (u32 *)((u32)(pSrcData + 3UL) & ~0x03UL); \
-+ for ( i = 0; i < nDwords; i++ ) \
-+ geREG(SRC_IMAGE_DATA, *pData++); \
-+ pSrcData += srcStride; \
-+ } \
-+ while( extras-- ) \
-+ geREG(SRC_IMAGE_DATA, 0UL); \
-+ }
-+
-+#define PUMP_REAL_PACKED_SRCFIFO(pSrcData,nDwords,extras) \
-+ { \
-+ u32 *pData =(u32 *)pSrcData; \
-+ while(nDwords--) \
-+ geREG(SRC_IMAGE_DATA, *pData++); \
-+ while( extras-- ) \
-+ geREG(SRC_IMAGE_DATA, 0UL); \
-+ }
-+
-+#endif
-+
-+#endif /* _VIDEO_MQ200_MQMACROS_H */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/video/MQ200/mqplat.h 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,106 @@
-+/***************************************************************************
-+ MQPLAT.H
-+
-+ MQ200 platform, system or OS specific header file
-+
-+ Copyright (c) 2000 by MediaQ, Incorporated.
-+ All Rights Reserved.
-+
-+***************************************************************************/
-+#ifndef _VIDEO_MQ200_MQPLAT_H
-+#define _VIDEO_MQ200_MQPLAT_H
-+
-+/* OS variation - ONLY define one */
-+#undef MQ_VXWORKS
-+#undef MQ_EPOC32
-+#undef MQ_WINCE
-+#undef MQ_OS9
-+#define MQ_LINUX
-+
-+/* CPU variation - ONLY define one */
-+#undef MQ_X86
-+#define MQ_SA1110
-+#undef MQ_MIPS_NEC
-+#undef MQ_MIPS_TOSHIBA
-+#undef MQ_SH4
-+
-+/* PCI support - undef accordingly */
-+#undef MQ_PCI
-+#ifdef MQ_PCI
-+ #warning "MQ200 driver compiled for PCI !"
-+#endif
-+
-+/* Derived equates from CPU type */
-+#ifdef MQ_SHx
-+ #warning "MQ200 driver compiled for SHx !"
-+ #define FB_BASE 0x93800000L /* MQ200 frame buffer adddr */
-+#endif
-+
-+#ifdef MQ_MIPS_NEC
-+ #warning "MQ200 driver compiled for NEC MIPS !"
-+ #define CHECK_FIFO_REQUIRED /* GE fifo checking required */
-+ #define FB_BASE 0xAA000000L
-+
-+ #ifdef MQ_PCI
-+ #define IOREGS_BASE 0xAF000000L /* for VR4122 */
-+ #define IOREGS_SIZE 0x00002000L
-+ #else
-+ #define IOREGS_BASE 0xAB000000L /* for VR 4111/21 */
-+ #define IOREGS_SIZE 0x00001000L
-+ #define CHECK_NOTBUSY /* Needed for NEC MIPS */
-+ #define CHECK_CMDFIFO /* Needed for NEC MIPS */
-+ #endif /* MQ_PCI */
-+#endif
-+
-+#ifdef MQ_MIPS_TOSHIBA
-+ #warning "MQ200 driver compiled for TOSHIBA MIPS !"
-+ #define FB_BASE 0x6D800000L
-+#endif
-+
-+#ifdef MQ_SA1110
-+ #warning "MQ200 driver compiled for Intel SA1110 !"
-+ #define FB_BASE_CS3 0x1b800000L /* configured as CS3 */
-+ #define FB_BASE_CS4 0x43800000L /* configured as CS4 */
-+#define FB_BASE_CS5 0x4b800000L /* configured as CS5 */
-+#define FB_BASE FB_BASE_CS5 /* change accordingly! */
-+#define REGISTER_BASE 0x4be00000L
-+#endif
-+
-+/* OS-derived misc defines */
-+#ifdef MQ_VXWORKS
-+ #warning "MQ200 driver compiled for VxWorks !"
-+ #define MQ_DELAY(cnt) taskDelay(cnt*30);
-+ #define MQ_COLOR_RGB /* Color (32bit):ARGB */
-+#endif
-+
-+#ifdef MQ_WINCE
-+ #warning "MQ200 driver compiled for Window CE !"
-+ #define MQ_DELAY(cnt) Sleep(cnt)
-+#endif
-+
-+#ifdef MQ_LINUX
-+ #warning "MQ200 driver compiled for Linux !"
-+/* #define MQ_DELAY(cnt) {volatile int delay; for (delay=0; delay<10000*cnt; delay++); } */
-+
-+#define MQ_DELAY(cnt) mdelay(cnt * 10)
-+#endif
-+
-+/* Further derivation
-+#ifdef MQ_COLOR_RGB
-+ #define GETR(color) (unsigned char)(color >> 16)
-+ #define GETG(color) (unsigned char)((unsigned short)(color) >> 8)
-+ #define GETB(color) (unsigned char)(color)
-+ #define MAKERGB(r,g,b) ((unsigned long)(((unsigned char)(r)|\
-+ ((unsigned short)((unsigned char)(g))<<8))|\
-+ (((unsigned long)(unsigned char)(b))<<16)))
-+#endif
-+*/
-+
-+/* Cursor color */
-+#ifndef CURSOR_FGCLR
-+ #define CURSOR_FGCLR 0x0000FFFF /* Yellow */
-+#endif
-+#ifndef CURSOR_BGCLR
-+ #define CURSOR_BGCLR 0x00000000 /* Black */
-+#endif
-+#endif /* _VIDEO_MQ200_MQPLAT_H */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/video/MQ200/mqproto.h 2004-05-02 22:45:42.000000000 +0200
-@@ -0,0 +1,19 @@
-+/***************************************************************************
-+ MQPROTO.H
-+
-+ MQ200 common function prototypes
-+
-+ Copyright (c) 2000 by MediaQ, Incorporated.
-+ All Rights Reserved.
-+
-+***************************************************************************/
-+#ifndef MQPROTO_H
-+#define MQPROTO_H
-+
-+/*
-+ * mqdata.h
-+ */
-+extern FPDATA_CONTROL fpControlData[];
-+extern DISPLAY_TIMING TimingParam[];
-+
-+#endif /* MQPROTO_H */
---- linux-2.4.25/init/do_mounts.c~2.4.25-vrs2-pxa1-jpm1.patch 2004-05-02 22:45:40.000000000 +0200
-+++ linux-2.4.25/init/do_mounts.c 2004-05-02 22:45:42.000000000 +0200
-@@ -789,7 +789,13 @@
- return;
- }
- printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying floppy.\n");
-+#ifdef CONFIG_SA1100_SIMPAD
-+ /* no floppy -> cramfs */
-+ printk(KERN_ERR "VFS: Unable to mount root fs via NFS, trying cramfs.\n");
-+ ROOT_DEV = MKDEV(31, 2);
-+#else
- ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
-+#endif
- }
- #endif
- devfs_make_root(root_device_name);
diff --git a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/2.4.25-vrs2-pxa1.patch b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/2.4.25-vrs2-pxa1.patch
deleted file mode 100644
index df59f13544..0000000000
--- a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/2.4.25-vrs2-pxa1.patch
+++ /dev/null
@@ -1,39937 +0,0 @@
-
-#
-# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux-2.4.25/Documentation/Configure.help~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:08.000000000 +0200
-+++ linux-2.4.25/Documentation/Configure.help 2004-03-31 17:15:11.000000000 +0200
-@@ -4526,6 +4526,24 @@
- building a kernel for install/rescue disks or your system is very
- limited in memory.
-
-+Kernel Execute-In-Place from ROM
-+CONFIG_XIP_KERNEL
-+ Execute-In-Place allows the kernel to run directly from
-+ non-volatile storage, such as flash. This saves RAM space since
-+ the text section of the kernel is not loaded from flash to
-+ RAM. Read-write sections, such as the data section and stack,
-+ are still copied to RAM. The XIP kernel is not compressed since it
-+ has to run directly from flash, so it will take more space to store
-+ it. The flash address where the kernel is linked to run from and
-+ is stored is board dependent. Therefore, if you say Y, you must
-+ know the proper physical address where to store the kernel image.
-+
-+ Also note that the make target becomes "make xipImage" rather than
-+ "make zImage" or "make Image". The final kernel binary to put in
-+ ROM memory will be arch/arm/boot/xipImage.
-+
-+ If unsure, say N.
-+
- # Choice: kcore
- Kernel core (/proc/kcore) format
- CONFIG_KCORE_ELF
-@@ -13386,6 +13404,30 @@
-
- If you don't know what this all is, saying Y is a safe choice.
-
-+Workaround for XScale cache errata
-+CONFIG_XSCALE_CACHE_ERRATA
-+ There are couple errata that say that the cache may get confused
-+ whether some cache lines are dirty or not, resulting in some memory
-+ corruptions. The workaround (using the cache only in write through
-+ mode) is performance impairing, and the bug _might_ just not be
-+ that visible or critical to you depending on many esoteric
-+ hardware factors.
-+
-+ Not using the workaround makes Linux unreliable. If you're used
-+ to some other OSes which requires to be rebooted once in a while
-+ then this won't look so bad to you. On the other hand you may
-+ stress test the system for hours without seeing any effect of this
-+ bug.
-+
-+ So this is configurable. Let's hope a future core revision will tell
-+ this was just a bad dream. But in the mean time the risk and
-+ trade-off is yours to decide.
-+
-+ This should apply to all PXA250 up to rev B2 (erratum #120) and
-+ possibly other current XScale cores as well.
-+
-+ If you don't know what to answer, say Y.
-+
- Support CD-ROM drives that are not SCSI or IDE/ATAPI
- CONFIG_CD_NO_IDESCSI
- If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y
-@@ -16568,6 +16610,40 @@
-
- If unsure, say N.
-
-+Use linear addressing for cramfs
-+CONFIG_CRAMFS_LINEAR
-+ This option tells the cramfs driver to load data directly from a linear
-+ adressed memory range (usually non volatile memory like flash) instead
-+ of going through the block device layer. This saves some memory since
-+ no intermediate buffering is necessary.
-+
-+ This is also a prerequisite for XIP of binaries stored on the filesystem.
-+
-+ The location of the cramfs image in memory is board dependent. Therefore,
-+ if you say Y, you must know the proper physical address where to store
-+ the cramfs image and specify it using the physaddr=0x******** mount
-+ option (for example: "mount -t cramfs -o physaddr=0x100000 none /mnt").
-+
-+ If unsure, say N.
-+
-+Support XIP on linear cramfs
-+CONFIG_CRAMFS_LINEAR_XIP
-+ You must say Y to this option if you want to be able to run applications
-+ directly from non-volatile memory. XIP applications are marked by
-+ setting the sticky bit (ie, "chmod +t <app name>"). A cramfs file system
-+ then needs to be created using mkcramfs (with XIP cramfs support
-+ in it). Applications marked for XIP execution will not be compressed
-+ since they have to run directly from flash.
-+
-+Root file system on linear cramfs
-+CONFIG_ROOT_CRAMFS_LINEAR
-+ Say Y if you have enabled linear cramfs, and you want to be able to use
-+ the linear cramfs image as a root file system. To actually have the
-+ kernel mount this cramfs image as a root file system, you must also pass
-+ the command line parameter "root=/dev/null rootflags=physaddr=0x********"
-+ to the kernel (replace 0x******** with the physical address location
-+ of the linear cramfs image to boot with).
-+
- CMS file system support
- CONFIG_CMS_FS
- Read only support for CMS minidisk file systems found on IBM
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/Documentation/arm/XScale/PXA/USB-client 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,38 @@
-+Date: Wed, 05 Jun 2002 13:38:53 -0700
-+From: Frank Becker <fbecker@intrinsyc.com>
-+To: Nicolas Pitre <nico@cam.org>
-+Subject: [PATCH] PXA-USB
-+
-+Hi Nicolas,
-+
-+one more patch...
-+
-+This patch adds minimal USB client (UDC) support.
-+
-+Some notes:
-+It adds just enough to get usb-eth working. I.e.
-+endpoints 0-2, no dma. Performance isn't stellar
-+partially due to UDC bug workarounds...
-+(~350K @ 100Mhz, ~550K @ 200Mhz).
-+
-+Endpoint 1&2 have changed direction compared to
-+the SA, so the host side requires a change to
-+usbnet.c to flip endpoints (in:2/out:1 -> in:1/out:2).
-+
-+usb-eth and usb-char for PXA are almost identical
-+to the SA versions, so they could probably be merged at
-+one point. I made some minor changes to the eth driver
-+to grab the usb resources at open, rather than at init
-+and allow eth&char to be loaded at the same time.
-+
-+Stuart Lynne was working on his own USB client driver
-+(and he was getting higher throughput than my driver).
-+Assuming you guys have something in the oven for USB
-+as well, there should be good selection for best of
-+breed :)
-+
-+Cheers,
-+Frank.
-+--
-+Frank Becker - Intrinsyc Software, Inc. - http://www.intrinsyc.com/
-+Need a break? http://criticalmass.sf.net/
---- linux-2.4.25/Makefile~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:08.000000000 +0200
-+++ linux-2.4.25/Makefile 2004-03-31 17:15:11.000000000 +0200
-@@ -1,11 +1,13 @@
- VERSION = 2
- PATCHLEVEL = 4
- SUBLEVEL = 25
--EXTRAVERSION =-vrs2
-+EXTRAVERSION =-vrs2-pxa1
-
- KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
-
--ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
-+#ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
-+ARCH := arm
-+
- KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g")
-
- CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
-@@ -19,7 +21,7 @@
- HOSTCC = gcc
- HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
-
--CROSS_COMPILE =
-+CROSS_COMPILE = arm-linux-
-
- #
- # Include the make variables (CC, etc...)
-@@ -168,6 +170,7 @@
- DRIVERS-$(CONFIG_SOUND) += drivers/sound/sounddrivers.o
- DRIVERS-$(CONFIG_PCI) += drivers/pci/driver.o
- DRIVERS-$(CONFIG_MTD) += drivers/mtd/mtdlink.o
-+DRIVERS-$(CONFIG_MMC) += drivers/mmc/mmcdrivers.o
- DRIVERS-$(CONFIG_PCMCIA) += drivers/pcmcia/pcmcia.o
- DRIVERS-$(CONFIG_NET_PCMCIA) += drivers/net/pcmcia/pcmcia_net.o
- DRIVERS-$(CONFIG_NET_WIRELESS) += drivers/net/wireless/wireless_net.o
---- linux-2.4.25/arch/arm/Makefile~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:08.000000000 +0200
-+++ linux-2.4.25/arch/arm/Makefile 2004-03-31 17:15:11.000000000 +0200
-@@ -13,10 +13,11 @@
- CFLAGS +=-Uarm -fno-common -pipe
-
- ifeq ($(CONFIG_FRAME_POINTER),y)
--CFLAGS :=$(CFLAGS:-fomit-frame-pointer=-mapcs -mno-sched-prolog)
-+CFLAGS :=$(CFLAGS:-fomit-frame-pointer=)
-+CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
- endif
-
--CFLAGS :=$(CFLAGS:-O2=-Os)
-+#CFLAGS :=$(CFLAGS:-O2=-Os)
-
- ifeq ($(CONFIG_DEBUG_INFO),y)
- CFLAGS +=-g
-@@ -38,6 +39,8 @@
- arch-$(CONFIG_CPU_32v3) :=-D__LINUX_ARM_ARCH__=3 -march=armv3
- arch-$(CONFIG_CPU_32v4) :=-D__LINUX_ARM_ARCH__=4 -march=armv4
- arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 -march=armv5
-+#arch-$(CONFIG_CPU_XSCALE) :=-D__LINUX_ARM_ARCH__=5 -mcpu=xscale
-+arch-$(CONFIG_CPU_XSCALE) :=-D__LINUX_ARM_ARCH__=5 -march=armv4 -Wa,-mcpu=xscale
-
- # This selects how we optimise for the processor.
- tune-y :=
-@@ -49,6 +52,8 @@
- tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi
- tune-$(CONFIG_CPU_SA110) :=-mtune=strongarm110
- tune-$(CONFIG_CPU_SA1100) :=-mtune=strongarm1100
-+tune-$(CONFIG_CPU_XSCALE) :=-mtune=xscale
-+#tune-$(CONFIG_CPU_XSCALE) :=-mtune=strongarm
-
- CFLAGS_BOOT :=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Uarm
- CFLAGS +=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Uarm
-@@ -127,6 +132,10 @@
- MACHINE = sa1100
- endif
-
-+ifeq ($(CONFIG_ARCH_PXA),y)
-+MACHINE = pxa
-+endif
-+
- ifeq ($(CONFIG_ARCH_L7200),y)
- MACHINE = l7200
- endif
-@@ -164,6 +173,17 @@
- MACHINE = omaha
- endif
-
-+ifeq ($(CONFIG_XIP_KERNEL),y)
-+ DATAADDR := $(TEXTADDR)
-+ # Replace phys addr with virt addr while keeping offset from base.
-+ # Virt base addr also defined in include/asm-arm/arch-*/hardware.h
-+ TEXTADDR = $(shell echo 0x`echo $(CONFIG_XIP_PHYS_ADDR)|sed -e's/^0x//'` |\
-+ awk --non-decimal-data '/[:xdigit:]/ \
-+ {printf("0x%x\n",and($$0,0x001fffff)+0xe8000000)}' )
-+ LDSCRIPT = arch/arm/vmlinux-armv-xip.lds.in
-+ export DATAADDR
-+endif
-+
- export MACHINE PROCESSOR TEXTADDR GZFLAGS CFLAGS_BOOT OBJCOPYFLAGS
-
- # Only set INCDIR if its not already defined above
-@@ -269,7 +289,7 @@
- arch/arm/kernel arch/arm/mm arch/arm/lib: dummy
- $(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@)
-
--bzImage zImage zinstall Image bootpImage install: vmlinux
-+bzImage zImage zinstall Image xipImage bootpImage install: vmlinux
- @$(MAKEBOOT) $@
-
- CLEAN_FILES += \
---- linux-2.4.25/arch/arm/boot/Makefile~2.4.25-vrs2-pxa1.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/boot/Makefile 2004-03-31 17:15:11.000000000 +0200
-@@ -113,6 +113,10 @@
- endif
- endif
-
-+ifeq ($(CONFIG_ARCH_PXA),y)
-+ZRELADDR = 0xa0008000
-+endif
-+
- ifeq ($(CONFIG_ARCH_ANAKIN),y)
- ZRELADDR = 0x20008000
- endif
-@@ -140,6 +144,14 @@
- zImage: compressed/vmlinux
- $(OBJCOPY) $(OBJCOPYFLAGS) $< $@
-
-+ifeq ($(CONFIG_XIP_KERNEL),y)
-+xipImage: $(CONFIGURE) $(SYSTEM)
-+ $(OBJCOPY) -S -O binary -R .data $(SYSTEM) vmlinux-text.bin
-+ $(OBJCOPY) -S -O binary -R .init -R .text -R __ex_table -R __ksymtab $(SYSTEM) vmlinux-data.bin
-+ cat vmlinux-text.bin vmlinux-data.bin > $@
-+ $(RM) -f vmlinux-text.bin vmlinux-data.bin
-+endif
-+
- bootpImage: bootp/bootp
- $(OBJCOPY) $(OBJCOPYFLAGS) $< $@
-
-@@ -160,7 +172,7 @@
- sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
-
- clean:
-- $(RM) Image zImage bootpImage
-+ $(RM) Image xipImage zImage bootpImage
- @$(MAKE) -C compressed clean
- @$(MAKE) -C bootp clean
-
---- linux-2.4.25/arch/arm/boot/compressed/Makefile~2.4.25-vrs2-pxa1.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/boot/compressed/Makefile 2004-03-31 17:15:11.000000000 +0200
-@@ -71,6 +71,10 @@
- OBJS += head-sa1100.o
- endif
-
-+ifeq ($(CONFIG_CPU_XSCALE),y)
-+OBJS += head-xscale.o
-+endif
-+
- SEDFLAGS = s/TEXT_START/$(ZTEXTADDR)/;s/LOAD_ADDR/$(ZRELADDR)/;s/BSS_START/$(ZBSSADDR)/
-
- LIBGCC := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/boot/compressed/head-xscale.S 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,50 @@
-+/*
-+ * linux/arch/arm/boot/compressed/head-xscale.S
-+ *
-+ * XScale specific tweaks. This is merged into head.S by the linker.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/linkage.h>
-+#include <asm/mach-types.h>
-+
-+ .section ".start", #alloc, #execinstr
-+
-+__XScale_start:
-+
-+ @ Preserve r8/r7 i.e. kernel entry values
-+
-+ @ Data cache might be active.
-+ @ Be sure to flush kernel binary out of the cache,
-+ @ whatever state it is, before it is turned off.
-+ @ This is done by fetching through currently executed
-+ @ memory to be sure we hit the same cache.
-+ bic r2, pc, #0x1f
-+ add r3, r2, #0x10000 @ 64 kb is quite enough...
-+1: ldr r0, [r2], #32
-+ teq r2, r3
-+ bne 1b
-+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
-+ mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches
-+
-+ @ disabling MMU and caches
-+ mrc p15, 0, r0, c1, c0, 0 @ read control reg
-+ bic r0, r0, #0x05 @ clear DC, MMU
-+ bic r0, r0, #0x1000 @ clear Icache
-+ mcr p15, 0, r0, c1, c0, 0
-+
-+#ifdef CONFIG_ARCH_LUBBOCK
-+ mov r7, #MACH_TYPE_LUBBOCK
-+#endif
-+
-+#ifdef CONFIG_ARCH_PXA_IDP
-+ mov r7, #MACH_TYPE_PXA_IDP
-+#endif
-+
-+#ifdef CONFIG_ARCH_TRIZEPS2
-+ mov r7, #(MACH_TYPE_TRIZEPS2 & 0xFF00)
-+ add r7, r7, #(MACH_TYPE_TRIZEPS2 & 0xFF)
-+#endif
-+
-+
---- linux-2.4.25/arch/arm/boot/compressed/head.S~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:08.000000000 +0200
-+++ linux-2.4.25/arch/arm/boot/compressed/head.S 2004-03-31 17:15:11.000000000 +0200
-@@ -351,7 +351,11 @@
- orr r1, r1, #3 << 10
- add r2, r3, #16384
- 1: cmp r1, r8 @ if virt > start of RAM
-+#ifdef CONFIG_XSCALE_CACHE_ERRATA
-+ orrhs r1, r1, #0x08 @ set cacheable, not bufferable
-+#else
- orrhs r1, r1, #0x0c @ set cacheable, bufferable
-+#endif
- cmp r1, r9 @ if virt > end of RAM
- bichs r1, r1, #0x0c @ clear cacheable, bufferable
- str r1, [r0], #4 @ 1:1 mapping
-@@ -364,7 +368,11 @@
- * so there is no map overlap problem for up to 1 MB compressed kernel.
- * If the execution is in RAM then we would only be duplicating the above.
- */
-+#ifdef CONFIG_XSCALE_CACHE_ERRATA
-+ mov r1, #0x1a
-+#else
- mov r1, #0x1e
-+#endif
- orr r1, r1, #3 << 10
- mov r2, pc, lsr #20
- orr r1, r1, r2, lsl #20
---- linux-2.4.25/arch/arm/config.in~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:08.000000000 +0200
-+++ linux-2.4.25/arch/arm/config.in 2004-03-31 17:15:11.000000000 +0200
-@@ -38,6 +38,7 @@
- Cirrus-CL-PS7500FE CONFIG_ARCH_CLPS7500 \
- CLPS711x/EP721x-based CONFIG_ARCH_CLPS711X \
- Co-EBSA285 CONFIG_ARCH_CO285 \
-+ PXA250/210-based CONFIG_ARCH_PXA \
- EBSA-110 CONFIG_ARCH_EBSA110 \
- Excalibur-ARM CONFIG_ARCH_CAMELOT \
- FootBridge CONFIG_ARCH_FOOTBRIDGE \
-@@ -148,6 +149,47 @@
- endmenu
-
- mainmenu_option next_comment
-+comment 'Intel PXA250/210 Implementations'
-+dep_bool ' Intel DBPXA250 Development Platform' CONFIG_ARCH_LUBBOCK $CONFIG_ARCH_PXA
-+dep_bool ' Accelent Xscale IDP' CONFIG_ARCH_PXA_IDP $CONFIG_ARCH_PXA
-+dep_bool ' Intrinsyc CerfBoard' CONFIG_ARCH_PXA_CERF $CONFIG_ARCH_PXA
-+dep_bool ' Trizeps-II MT6N' CONFIG_ARCH_TRIZEPS2 $CONFIG_ARCH_PXA
-+
-+if [ "$CONFIG_ARCH_PXA_CERF" = "y" ]; then
-+ define_bool CONFIG_PXA_CERF y
-+
-+ choice 'CerfBoard Style' \
-+ "PDA CONFIG_PXA_CERF_PDA \
-+ BOARD CONFIG_PXA_CERF_BOARD" PDA
-+
-+ choice 'CerfBoard RAM Available' \
-+ "128MB CONFIG_PXA_CERF_RAM_128MB \
-+ 64MB CONFIG_PXA_CERF_RAM_64MB \
-+ 32MB CONFIG_PXA_CERF_RAM_32MB \
-+ 16MB CONFIG_PXA_CERF_RAM_16MB" 64MB
-+
-+ choice 'CerfBoard Flash Available' \
-+ "64MB CONFIG_PXA_CERF_FLASH_64MB \
-+ 32MB CONFIG_PXA_CERF_FLASH_32MB \
-+ 16MB CONFIG_PXA_CERF_FLASH_16MB \
-+ 8MB CONFIG_PXA_CERF_FLASH_8MB" 32MB
-+fi
-+
-+if [ "$CONFIG_ARCH_LUBBOCK" = "y" ]; then
-+ define_bool CONFIG_SA1111 y
-+fi
-+
-+if [ "$CONFIG_ARCH_TRIZEPS2" = "y" ]; then
-+ define_bool CONFIG_TRIZEPS2 y
-+fi
-+
-+dep_tristate 'PXA USB function support' CONFIG_PXA_USB $CONFIG_ARCH_PXA
-+dep_tristate ' Support for PXA USB network link function' CONFIG_PXA_USB_NETLINK $CONFIG_PXA_USB
-+dep_tristate ' Support for PXA USB character device emulation' CONFIG_PXA_USB_CHAR $CONFIG_PXA_USB
-+
-+endmenu
-+
-+mainmenu_option next_comment
- comment 'CLPS711X/EP721X Implementations'
- dep_bool ' AUTCPU12' CONFIG_ARCH_AUTCPU12 $CONFIG_ARCH_CLPS711X
- dep_bool ' CDB89712' CONFIG_ARCH_CDB89712 $CONFIG_ARCH_CLPS711X
-@@ -385,6 +427,12 @@
- define_bool CONFIG_CPU_SA1100 n
- fi
-
-+if [ "$CONFIG_ARCH_PXA" = "y" ]; then
-+ define_bool CONFIG_CPU_32v5 y
-+ define_bool CONFIG_CPU_XSCALE y
-+ bool 'Workaround for XScale cache errata (see help)' CONFIG_XSCALE_CACHE_ERRATA
-+fi
-+
- # Figure out what processor architecture version we should be using.
- # This defines the compiler instruction set which depends on the machine type.
-
-@@ -493,6 +541,7 @@
- hex 'Compressed ROM boot loader BSS address' CONFIG_ZBOOT_ROM_BSS 0
-
- if [ "$CONFIG_ARCH_SA1100" = "y" -o \
-+ "$CONFIG_ARCH_PXA" = "y" -o \
- "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
- dep_bool 'Support CPU clock change (EXPERIMENTAL)' CONFIG_CPU_FREQ $CONFIG_EXPERIMENTAL
- fi
-@@ -501,8 +550,10 @@
- bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
- if [ "$CONFIG_HOTPLUG" = "y" ]; then
- source drivers/pcmcia/Config.in
-+ source drivers/mmc/Config.in
- else
- define_bool CONFIG_PCMCIA n
-+ define_bool CONFIG_MMC n
- fi
- if [ "$CONFIG_SA1100_ACCELENT" = "y" ]; then
- if [ "$CONFIG_PCMCIA" != "n" ]; then
-@@ -513,6 +564,14 @@
- bool 'System V IPC' CONFIG_SYSVIPC
- bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
- bool 'Sysctl support' CONFIG_SYSCTL
-+
-+if [ "$CONFIG_ARCH_PXA" = "y" ]; then
-+ dep_bool 'Kernel Execute-In-Place from ROM (EXPERIMENTAL)' CONFIG_XIP_KERNEL $CONFIG_EXPERIMENTAL
-+ if [ "$CONFIG_XIP_KERNEL" = "y" ]; then
-+ hex ' Kernel .text physical address' CONFIG_XIP_PHYS_ADDR 0
-+ fi
-+fi
-+
- comment 'At least one math emulation must be selected'
- tristate 'NWFPE math emulation' CONFIG_FPE_NWFPE
- if [ "$CONFIG_FPE_NWFPE" != "n" ]; then
-@@ -538,6 +597,9 @@
- "$CONFIG_ARCH_SHARK" = "y" -o \
- "$CONFIG_ARCH_CO285" = "y" -o \
- "$CONFIG_ARCH_SA1100" = "y" -o \
-+ "$CONFIG_ARCH_LUBBOCK" = "y" -o \
-+ "$CONFIG_ARCH_PXA_IDP" = "y" -o \
-+ "$CONFIG_ARCH_PXA_CERF" = "y" -o \
- "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
- "$CONFIG_ARCH_CDB89712" = "y" -o \
- "$CONFIG_ARCH_P720T" = "y" -o \
-@@ -549,8 +611,12 @@
- "$CONFIG_ARCH_SHARK" = "y" -o \
- "$CONFIG_ARCH_CO285" = "y" -o \
- "$CONFIG_ARCH_SA1100" = "y" -o \
-+ "$CONFIG_ARCH_LUBBOCK" = "y" -o \
- "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
- "$CONFIG_ARCH_P720T" = "y" -o \
-+ "$CONFIG_ARCH_LUBBOCK" = "y" -o \
-+ "$CONFIG_ARCH_PXA_CERF" = "y" -o \
-+ "$CONFIG_ARCH_PXA_IDP" = "y" -o \
- "$CONFIG_ARCH_OMAHA" = "y" ]; then
- bool ' Timer LED' CONFIG_LEDS_TIMER
- bool ' CPU usage LED' CONFIG_LEDS_CPU
-@@ -684,6 +750,7 @@
- if [ "$CONFIG_FOOTBRIDGE_HOST" = "y" -o \
- "$CONFIG_ARCH_SHARK" = "y" -o \
- "$CONFIG_ARCH_SA1100" = "y" -o \
-+ "$CONFIG_ARCH_PXA" = "y" -o \
- "$CONFIG_ARCH_INTEGRATOR" = "y" -o \
- "$CONFIG_ARCH_TBOX" = "y" -o \
- "$CONFIG_ARCH_CLPS7500" = "y" -o \
-@@ -705,6 +772,7 @@
- "$CONFIG_ARCH_TBOX" = "y" -o \
- "$CONFIG_ARCH_SHARK" = "y" -o \
- "$CONFIG_ARCH_SA1100" = "y" -o \
-+ "$CONFIG_ARCH_PXA" = "y" -o \
- "$CONFIG_PCI" = "y" ]; then
- mainmenu_option next_comment
- comment 'Sound'
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/def-configs/cerfboard_pxa 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,857 @@
-+#
-+# Automatically generated by make menuconfig: don't edit
-+#
-+CONFIG_ARM=y
-+# CONFIG_EISA is not set
-+# CONFIG_SBUS is not set
-+# CONFIG_MCA is not set
-+CONFIG_UID16=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-+# CONFIG_GENERIC_BUST_SPINLOCK is not set
-+# CONFIG_GENERIC_ISA_DMA is not set
-+
-+#
-+# Code maturity level options
-+#
-+CONFIG_EXPERIMENTAL=y
-+# CONFIG_OBSOLETE is not set
-+
-+#
-+# Loadable module support
-+#
-+CONFIG_MODULES=y
-+# CONFIG_MODVERSIONS is not set
-+CONFIG_KMOD=y
-+
-+#
-+# System Type
-+#
-+# CONFIG_ARCH_ANAKIN is not set
-+# CONFIG_ARCH_ARCA5K is not set
-+# CONFIG_ARCH_CLPS7500 is not set
-+# CONFIG_ARCH_CLPS711X is not set
-+# CONFIG_ARCH_CO285 is not set
-+CONFIG_ARCH_PXA=y
-+# CONFIG_ARCH_EBSA110 is not set
-+# CONFIG_ARCH_CAMELOT is not set
-+# CONFIG_ARCH_FOOTBRIDGE is not set
-+# CONFIG_ARCH_INTEGRATOR is not set
-+# CONFIG_ARCH_OMAHA is not set
-+# CONFIG_ARCH_L7200 is not set
-+# CONFIG_ARCH_MX1ADS is not set
-+# CONFIG_ARCH_RPC is not set
-+# CONFIG_ARCH_RISCSTATION is not set
-+# CONFIG_ARCH_SA1100 is not set
-+# CONFIG_ARCH_SHARK is not set
-+
-+#
-+# Archimedes/A5000 Implementations
-+#
-+# CONFIG_ARCH_ARC is not set
-+# CONFIG_ARCH_A5K is not set
-+
-+#
-+# Footbridge Implementations
-+#
-+# CONFIG_ARCH_CATS is not set
-+# CONFIG_ARCH_PERSONAL_SERVER is not set
-+# CONFIG_ARCH_EBSA285_ADDIN is not set
-+# CONFIG_ARCH_EBSA285_HOST is not set
-+# CONFIG_ARCH_NETWINDER is not set
-+
-+#
-+# SA11x0 Implementations
-+#
-+# CONFIG_SA1100_ACCELENT is not set
-+# CONFIG_SA1100_ASSABET is not set
-+# CONFIG_ASSABET_NEPONSET is not set
-+# CONFIG_SA1100_ADSBITSY is not set
-+# CONFIG_SA1100_BRUTUS is not set
-+# CONFIG_SA1100_CEP is not set
-+# CONFIG_SA1100_CERF is not set
-+# CONFIG_SA1100_H3100 is not set
-+# CONFIG_SA1100_H3600 is not set
-+# CONFIG_SA1100_H3800 is not set
-+# CONFIG_SA1100_H3XXX is not set
-+# CONFIG_SA1100_EXTENEX1 is not set
-+# CONFIG_SA1100_FLEXANET is not set
-+# CONFIG_SA1100_FREEBIRD is not set
-+# CONFIG_SA1100_FRODO is not set
-+# CONFIG_SA1100_GRAPHICSCLIENT is not set
-+# CONFIG_SA1100_GRAPHICSMASTER is not set
-+# CONFIG_SA1100_BADGE4 is not set
-+# CONFIG_SA1100_JORNADA720 is not set
-+# CONFIG_SA1100_HUW_WEBPANEL is not set
-+# CONFIG_SA1100_ITSY is not set
-+# CONFIG_SA1100_LART is not set
-+# CONFIG_SA1100_NANOENGINE is not set
-+# CONFIG_SA1100_OMNIMETER is not set
-+# CONFIG_SA1100_PANGOLIN is not set
-+# CONFIG_SA1100_PLEB is not set
-+# CONFIG_SA1100_PT_SYSTEM3 is not set
-+# CONFIG_SA1100_SHANNON is not set
-+# CONFIG_SA1100_SHERMAN is not set
-+# CONFIG_SA1100_SIMPAD is not set
-+# CONFIG_SA1100_SIMPUTER is not set
-+# CONFIG_SA1100_PFS168 is not set
-+# CONFIG_SA1100_VICTOR is not set
-+# CONFIG_SA1100_XP860 is not set
-+# CONFIG_SA1100_YOPY is not set
-+# CONFIG_SA1100_USB is not set
-+# CONFIG_SA1100_USB_NETLINK is not set
-+# CONFIG_SA1100_USB_CHAR is not set
-+# CONFIG_H3600_SLEEVE is not set
-+
-+#
-+# Intel PXA250/210 Implementations
-+#
-+# CONFIG_ARCH_LUBBOCK is not set
-+# CONFIG_ARCH_PXA_IDP is not set
-+CONFIG_ARCH_PXA_CERF=y
-+CONFIG_PXA_CERF=y
-+# CONFIG_PXA_CERF_PDA is not set
-+CONFIG_PXA_CERF_BOARD=y
-+# CONFIG_PXA_CERF_RAM_128MB is not set
-+CONFIG_PXA_CERF_RAM_64MB=y
-+# CONFIG_PXA_CERF_RAM_32MB is not set
-+# CONFIG_PXA_CERF_RAM_16MB is not set
-+# CONFIG_PXA_CERF_FLASH_64MB is not set
-+CONFIG_PXA_CERF_FLASH_32MB=y
-+# CONFIG_PXA_CERF_FLASH_16MB is not set
-+# CONFIG_PXA_CERF_FLASH_8MB is not set
-+CONFIG_PXA_USB=y
-+CONFIG_PXA_USB_NETLINK=y
-+CONFIG_PXA_USB_CHAR=m
-+
-+#
-+# CLPS711X/EP721X Implementations
-+#
-+# CONFIG_ARCH_AUTCPU12 is not set
-+# CONFIG_ARCH_CDB89712 is not set
-+# CONFIG_ARCH_CLEP7312 is not set
-+# CONFIG_ARCH_EDB7211 is not set
-+# CONFIG_ARCH_P720T is not set
-+# CONFIG_ARCH_FORTUNET is not set
-+# CONFIG_ARCH_EP7211 is not set
-+# CONFIG_ARCH_EP7212 is not set
-+# CONFIG_ARCH_ACORN is not set
-+# CONFIG_FOOTBRIDGE is not set
-+# CONFIG_FOOTBRIDGE_HOST is not set
-+# CONFIG_FOOTBRIDGE_ADDIN is not set
-+CONFIG_CPU_32=y
-+# CONFIG_CPU_26 is not set
-+# CONFIG_CPU_ARM610 is not set
-+# CONFIG_CPU_ARM710 is not set
-+# CONFIG_CPU_ARM720T is not set
-+# CONFIG_CPU_ARM920T is not set
-+# CONFIG_CPU_ARM922T is not set
-+# CONFIG_PLD is not set
-+# CONFIG_CPU_ARM926T is not set
-+# CONFIG_CPU_ARM1020 is not set
-+# CONFIG_CPU_ARM1026 is not set
-+# CONFIG_CPU_SA110 is not set
-+# CONFIG_CPU_SA1100 is not set
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_XSCALE=y
-+CONFIG_XSCALE_CACHE_ERRATA=y
-+# CONFIG_CPU_32v3 is not set
-+# CONFIG_CPU_32v4 is not set
-+# CONFIG_DISCONTIGMEM is not set
-+
-+#
-+# General setup
-+#
-+# CONFIG_PCI is not set
-+# CONFIG_ISA is not set
-+# CONFIG_ISA_DMA is not set
-+# CONFIG_ZBOOT_ROM is not set
-+CONFIG_ZBOOT_ROM_TEXT=0
-+CONFIG_ZBOOT_ROM_BSS=0
-+CONFIG_CPU_FREQ=y
-+CONFIG_HOTPLUG=y
-+
-+#
-+# PCMCIA/CardBus support
-+#
-+CONFIG_PCMCIA=y
-+# CONFIG_I82092 is not set
-+# CONFIG_I82365 is not set
-+# CONFIG_TCIC is not set
-+# CONFIG_PCMCIA_CLPS6700 is not set
-+# CONFIG_PCMCIA_SA1100 is not set
-+CONFIG_PCMCIA_PXA=y
-+CONFIG_NET=y
-+CONFIG_SYSVIPC=y
-+CONFIG_BSD_PROCESS_ACCT=y
-+CONFIG_SYSCTL=y
-+CONFIG_FPE_NWFPE=y
-+# CONFIG_FPE_FASTFPE is not set
-+CONFIG_KCORE_ELF=y
-+# CONFIG_KCORE_AOUT is not set
-+# CONFIG_BINFMT_AOUT is not set
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_MISC is not set
-+# CONFIG_PM is not set
-+# CONFIG_ARTHUR is not set
-+CONFIG_CMDLINE="root=1f03 rw console=tty0 console=ttyS0,38400 init=/linuxrc"
-+CONFIG_LEDS=y
-+# CONFIG_LEDS_TIMER is not set
-+CONFIG_LEDS_CPU=y
-+CONFIG_ALIGNMENT_TRAP=y
-+
-+#
-+# Parallel port support
-+#
-+# CONFIG_PARPORT is not set
-+
-+#
-+# Memory Technology Devices (MTD)
-+#
-+CONFIG_MTD=y
-+# CONFIG_MTD_DEBUG is not set
-+CONFIG_MTD_PARTITIONS=y
-+# CONFIG_MTD_CONCAT is not set
-+CONFIG_MTD_REDBOOT_PARTS=y
-+# CONFIG_MTD_CMDLINE_PARTS is not set
-+# CONFIG_MTD_AFS_PARTS is not set
-+CONFIG_MTD_CHAR=y
-+CONFIG_MTD_BLOCK=y
-+# CONFIG_FTL is not set
-+# CONFIG_NFTL is not set
-+
-+#
-+# RAM/ROM/Flash chip drivers
-+#
-+CONFIG_MTD_CFI=y
-+# CONFIG_MTD_JEDECPROBE is not set
-+CONFIG_MTD_GEN_PROBE=y
-+CONFIG_MTD_CFI_ADV_OPTIONS=y
-+CONFIG_MTD_CFI_NOSWAP=y
-+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-+CONFIG_MTD_CFI_GEOMETRY=y
-+# CONFIG_MTD_CFI_B1 is not set
-+# CONFIG_MTD_CFI_B2 is not set
-+CONFIG_MTD_CFI_B4=y
-+# CONFIG_MTD_CFI_B8 is not set
-+# CONFIG_MTD_CFI_I1 is not set
-+CONFIG_MTD_CFI_I2=y
-+# CONFIG_MTD_CFI_I4 is not set
-+# CONFIG_MTD_CFI_I8 is not set
-+CONFIG_MTD_CFI_INTELEXT=y
-+# CONFIG_MTD_CFI_AMDSTD is not set
-+# CONFIG_MTD_RAM is not set
-+# CONFIG_MTD_ROM is not set
-+# CONFIG_MTD_ABSENT is not set
-+# CONFIG_MTD_OBSOLETE_CHIPS is not set
-+# CONFIG_MTD_AMDSTD is not set
-+# CONFIG_MTD_SHARP is not set
-+# CONFIG_MTD_JEDEC is not set
-+
-+#
-+# Mapping drivers for chip access
-+#
-+# CONFIG_MTD_PHYSMAP is not set
-+# CONFIG_MTD_LUBBOCK is not set
-+# CONFIG_MTD_NORA is not set
-+# CONFIG_MTD_ARM_INTEGRATOR is not set
-+# CONFIG_MTD_CDB89712 is not set
-+# CONFIG_MTD_SA1100 is not set
-+# CONFIG_MTD_DC21285 is not set
-+# CONFIG_MTD_IQ80310 is not set
-+# CONFIG_MTD_FORTUNET is not set
-+CONFIG_MTD_PXA_CERF=y
-+# CONFIG_MTD_EPXA10DB is not set
-+# CONFIG_MTD_AUTCPU12 is not set
-+# CONFIG_MTD_EDB7312 is not set
-+# CONFIG_MTD_IMPA7 is not set
-+# CONFIG_MTD_PCI is not set
-+
-+#
-+# Self-contained MTD device drivers
-+#
-+# CONFIG_MTD_PMC551 is not set
-+# CONFIG_MTD_SLRAM is not set
-+# CONFIG_MTD_MTDRAM is not set
-+# CONFIG_MTD_BLKMTD is not set
-+# CONFIG_MTD_DOC1000 is not set
-+# CONFIG_MTD_DOC2000 is not set
-+# CONFIG_MTD_DOC2001 is not set
-+# CONFIG_MTD_DOCPROBE is not set
-+
-+#
-+# NAND Flash Device Drivers
-+#
-+# CONFIG_MTD_NAND is not set
-+
-+#
-+# Plug and Play configuration
-+#
-+# CONFIG_PNP is not set
-+# CONFIG_ISAPNP is not set
-+
-+#
-+# Block devices
-+#
-+# CONFIG_BLK_DEV_FD is not set
-+# CONFIG_BLK_DEV_XD is not set
-+# CONFIG_PARIDE is not set
-+# CONFIG_BLK_CPQ_DA is not set
-+# CONFIG_BLK_CPQ_CISS_DA is not set
-+# CONFIG_CISS_SCSI_TAPE is not set
-+# CONFIG_BLK_DEV_DAC960 is not set
-+# CONFIG_BLK_DEV_UMEM is not set
-+CONFIG_BLK_DEV_LOOP=m
-+# CONFIG_BLK_DEV_NBD is not set
-+CONFIG_BLK_DEV_RAM=y
-+CONFIG_BLK_DEV_RAM_SIZE=4096
-+CONFIG_BLK_DEV_INITRD=y
-+
-+#
-+# Multi-device support (RAID and LVM)
-+#
-+# CONFIG_MD is not set
-+# CONFIG_BLK_DEV_MD is not set
-+# CONFIG_MD_LINEAR is not set
-+# CONFIG_MD_RAID0 is not set
-+# CONFIG_MD_RAID1 is not set
-+# CONFIG_MD_RAID5 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_BLK_DEV_LVM is not set
-+
-+#
-+# Networking options
-+#
-+CONFIG_PACKET=y
-+# CONFIG_PACKET_MMAP is not set
-+# CONFIG_NETLINK_DEV is not set
-+# CONFIG_NETFILTER is not set
-+CONFIG_FILTER=y
-+CONFIG_UNIX=y
-+CONFIG_INET=y
-+# CONFIG_IP_MULTICAST is not set
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+CONFIG_IP_PNP=y
-+CONFIG_IP_PNP_DHCP=y
-+CONFIG_IP_PNP_BOOTP=y
-+CONFIG_IP_PNP_RARP=y
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_ARPD is not set
-+# CONFIG_INET_ECN is not set
-+# CONFIG_SYN_COOKIES is not set
-+# CONFIG_IPV6 is not set
-+# CONFIG_KHTTPD is not set
-+# CONFIG_ATM is not set
-+# CONFIG_VLAN_8021Q is not set
-+# CONFIG_IPX is not set
-+# CONFIG_ATALK is not set
-+
-+#
-+# Appletalk devices
-+#
-+# CONFIG_DEV_APPLETALK is not set
-+# CONFIG_DECNET is not set
-+# CONFIG_BRIDGE is not set
-+# CONFIG_X25 is not set
-+# CONFIG_LAPB is not set
-+# CONFIG_LLC is not set
-+# CONFIG_NET_DIVERT is not set
-+# CONFIG_ECONET is not set
-+# CONFIG_WAN_ROUTER is not set
-+# CONFIG_NET_FASTROUTE is not set
-+# CONFIG_NET_HW_FLOWCONTROL is not set
-+
-+#
-+# QoS and/or fair queueing
-+#
-+# CONFIG_NET_SCHED is not set
-+
-+#
-+# Network testing
-+#
-+# CONFIG_NET_PKTGEN is not set
-+
-+#
-+# Network device support
-+#
-+CONFIG_NETDEVICES=y
-+
-+#
-+# ARCnet devices
-+#
-+# CONFIG_ARCNET is not set
-+# CONFIG_DUMMY is not set
-+# CONFIG_BONDING is not set
-+# CONFIG_EQUALIZER is not set
-+# CONFIG_TUN is not set
-+# CONFIG_ETHERTAP is not set
-+
-+#
-+# Ethernet (10 or 100Mbit)
-+#
-+CONFIG_NET_ETHERNET=y
-+# CONFIG_ARM_AM79C961A is not set
-+# CONFIG_ARM_CIRRUS is not set
-+# CONFIG_SUNLANCE is not set
-+# CONFIG_SUNBMAC is not set
-+# CONFIG_SUNQE is not set
-+# CONFIG_SUNGEM is not set
-+# CONFIG_NET_VENDOR_3COM is not set
-+# CONFIG_LANCE is not set
-+CONFIG_NET_VENDOR_SMC=y
-+# CONFIG_WD80x3 is not set
-+# CONFIG_ULTRAMCA is not set
-+# CONFIG_ULTRA is not set
-+# CONFIG_ULTRA32 is not set
-+# CONFIG_SMC9194 is not set
-+# CONFIG_NET_VENDOR_RACAL is not set
-+# CONFIG_NET_ISA is not set
-+# CONFIG_NET_PCI is not set
-+# CONFIG_NET_POCKET is not set
-+
-+#
-+# Ethernet (1000 Mbit)
-+#
-+# CONFIG_ACENIC is not set
-+# CONFIG_DL2K is not set
-+# CONFIG_MYRI_SBUS is not set
-+# CONFIG_NS83820 is not set
-+# CONFIG_HAMACHI is not set
-+# CONFIG_YELLOWFIN is not set
-+# CONFIG_SK98LIN is not set
-+# CONFIG_TIGON3 is not set
-+# CONFIG_FDDI is not set
-+# CONFIG_HIPPI is not set
-+# CONFIG_PLIP is not set
-+CONFIG_PPP=m
-+# CONFIG_PPP_MULTILINK is not set
-+# CONFIG_PPP_FILTER is not set
-+CONFIG_PPP_ASYNC=m
-+# CONFIG_PPP_SYNC_TTY is not set
-+CONFIG_PPP_DEFLATE=m
-+CONFIG_PPP_BSDCOMP=m
-+# CONFIG_PPPOE is not set
-+# CONFIG_SLIP is not set
-+
-+#
-+# Wireless LAN (non-hamradio)
-+#
-+# CONFIG_NET_RADIO is not set
-+
-+#
-+# Token Ring devices
-+#
-+# CONFIG_TR is not set
-+# CONFIG_NET_FC is not set
-+# CONFIG_RCPCI is not set
-+# CONFIG_SHAPER is not set
-+
-+#
-+# Wan interfaces
-+#
-+# CONFIG_WAN is not set
-+
-+#
-+# PCMCIA network device support
-+#
-+CONFIG_NET_PCMCIA=y
-+CONFIG_PCMCIA_3C589=m
-+CONFIG_PCMCIA_3C574=m
-+CONFIG_PCMCIA_FMVJ18X=m
-+CONFIG_PCMCIA_PCNET=m
-+CONFIG_PCMCIA_AXNET=m
-+CONFIG_PCMCIA_NMCLAN=m
-+CONFIG_PCMCIA_SMC91C92=m
-+CONFIG_PCMCIA_XIRC2PS=m
-+# CONFIG_ARCNET_COM20020_CS is not set
-+# CONFIG_PCMCIA_IBMTR is not set
-+CONFIG_NET_PCMCIA_RADIO=y
-+CONFIG_PCMCIA_RAYCS=m
-+CONFIG_PCMCIA_NETWAVE=m
-+CONFIG_PCMCIA_WAVELAN=m
-+CONFIG_AIRONET4500_CS=m
-+
-+#
-+# Amateur Radio support
-+#
-+# CONFIG_HAMRADIO is not set
-+
-+#
-+# IrDA (infrared) support
-+#
-+# CONFIG_IRDA is not set
-+
-+#
-+# ATA/ATAPI/MFM/RLL support
-+#
-+CONFIG_IDE=y
-+
-+#
-+# IDE, ATA and ATAPI Block devices
-+#
-+CONFIG_BLK_DEV_IDE=y
-+# CONFIG_BLK_DEV_HD_IDE is not set
-+# CONFIG_BLK_DEV_HD is not set
-+CONFIG_BLK_DEV_IDEDISK=y
-+# CONFIG_IDEDISK_MULTI_MODE is not set
-+# CONFIG_IDEDISK_STROKE is not set
-+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-+# CONFIG_BLK_DEV_IDEDISK_WD is not set
-+# CONFIG_BLK_DEV_COMMERIAL is not set
-+# CONFIG_BLK_DEV_TIVO is not set
-+CONFIG_BLK_DEV_IDECS=m
-+# CONFIG_BLK_DEV_IDECD is not set
-+# CONFIG_BLK_DEV_IDETAPE is not set
-+# CONFIG_BLK_DEV_IDEFLOPPY is not set
-+# CONFIG_BLK_DEV_IDESCSI is not set
-+# CONFIG_IDE_TASK_IOCTL is not set
-+# CONFIG_BLK_DEV_CMD640 is not set
-+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-+# CONFIG_BLK_DEV_ISAPNP is not set
-+# CONFIG_IDE_CHIPSETS is not set
-+# CONFIG_IDEDMA_AUTO is not set
-+# CONFIG_DMA_NONPCI is not set
-+# CONFIG_BLK_DEV_IDE_MODES is not set
-+# CONFIG_BLK_DEV_ATARAID is not set
-+# CONFIG_BLK_DEV_ATARAID_PDC is not set
-+# CONFIG_BLK_DEV_ATARAID_HPT is not set
-+
-+#
-+# SCSI support
-+#
-+# CONFIG_SCSI is not set
-+
-+#
-+# I2O device support
-+#
-+# CONFIG_I2O is not set
-+# CONFIG_I2O_BLOCK is not set
-+# CONFIG_I2O_LAN is not set
-+# CONFIG_I2O_SCSI is not set
-+# CONFIG_I2O_PROC is not set
-+
-+#
-+# ISDN subsystem
-+#
-+# CONFIG_ISDN is not set
-+
-+#
-+# Input core support
-+#
-+# CONFIG_INPUT is not set
-+# CONFIG_INPUT_KEYBDEV is not set
-+# CONFIG_INPUT_MOUSEDEV is not set
-+# CONFIG_INPUT_JOYDEV is not set
-+# CONFIG_INPUT_EVDEV is not set
-+
-+#
-+# Character devices
-+#
-+CONFIG_VT=y
-+CONFIG_VT_CONSOLE=y
-+CONFIG_SERIAL=y
-+CONFIG_SERIAL_CONSOLE=y
-+# CONFIG_SERIAL_EXTENDED is not set
-+# CONFIG_SERIAL_NONSTANDARD is not set
-+
-+#
-+# Serial drivers
-+#
-+# CONFIG_SERIAL_ANAKIN is not set
-+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-+# CONFIG_SERIAL_AMBA is not set
-+# CONFIG_SERIAL_AMBA_CONSOLE is not set
-+# CONFIG_SERIAL_CLPS711X is not set
-+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-+# CONFIG_SERIAL_21285 is not set
-+# CONFIG_SERIAL_21285_OLD is not set
-+# CONFIG_SERIAL_21285_CONSOLE is not set
-+# CONFIG_SERIAL_UART00 is not set
-+# CONFIG_SERIAL_UART00_CONSOLE is not set
-+# CONFIG_SERIAL_SA1100 is not set
-+# CONFIG_SERIAL_SA1100_CONSOLE is not set
-+# CONFIG_SERIAL_OMAHA is not set
-+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
-+# CONFIG_SERIAL_8250 is not set
-+# CONFIG_SERIAL_8250_CONSOLE is not set
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+# CONFIG_SERIAL_8250_MANY_PORTS is not set
-+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-+# CONFIG_SERIAL_8250_MULTIPORT is not set
-+# CONFIG_SERIAL_8250_HUB6 is not set
-+CONFIG_UNIX98_PTYS=y
-+CONFIG_UNIX98_PTY_COUNT=256
-+
-+#
-+# I2C support
-+#
-+CONFIG_I2C=y
-+# CONFIG_I2C_ALGOBIT is not set
-+# CONFIG_I2C_ALGOPCF is not set
-+CONFIG_I2C_PXA_ALGO=y
-+CONFIG_I2C_PXA_ADAP=y
-+# CONFIG_I2C_CHARDEV is not set
-+# CONFIG_I2C_PROC is not set
-+# CONFIG_I2C_DS1307 is not set
-+
-+#
-+# L3 serial bus support
-+#
-+# CONFIG_L3 is not set
-+# CONFIG_L3_ALGOBIT is not set
-+# CONFIG_L3_BIT_SA1100_GPIO is not set
-+# CONFIG_L3_SA1111 is not set
-+# CONFIG_BIT_SA1100_GPIO is not set
-+
-+#
-+# Mice
-+#
-+# CONFIG_BUSMOUSE is not set
-+# CONFIG_MOUSE is not set
-+
-+#
-+# Joysticks
-+#
-+# CONFIG_INPUT_GAMEPORT is not set
-+# CONFIG_QIC02_TAPE is not set
-+
-+#
-+# Watchdog Cards
-+#
-+CONFIG_WATCHDOG=y
-+# CONFIG_WATCHDOG_NOWAYOUT is not set
-+# CONFIG_ACQUIRE_WDT is not set
-+# CONFIG_ADVANTECH_WDT is not set
-+# CONFIG_ALIM7101_WDT is not set
-+# CONFIG_SC520_WDT is not set
-+# CONFIG_PCWATCHDOG is not set
-+# CONFIG_21285_WATCHDOG is not set
-+# CONFIG_977_WATCHDOG is not set
-+# CONFIG_SA1100_WATCHDOG is not set
-+CONFIG_PXA_WATCHDOG=m
-+# CONFIG_OMAHA_WATCHDOG is not set
-+# CONFIG_EUROTECH_WDT is not set
-+# CONFIG_IB700_WDT is not set
-+# CONFIG_WAFER_WDT is not set
-+# CONFIG_I810_TCO is not set
-+# CONFIG_MIXCOMWD is not set
-+# CONFIG_60XX_WDT is not set
-+# CONFIG_SC1200_WDT is not set
-+# CONFIG_SOFT_WATCHDOG is not set
-+# CONFIG_W83877F_WDT is not set
-+# CONFIG_WDT is not set
-+# CONFIG_WDTPCI is not set
-+# CONFIG_MACHZ_WDT is not set
-+# CONFIG_NVRAM is not set
-+# CONFIG_RTC is not set
-+# CONFIG_PXA_RTC is not set
-+# CONFIG_DTLK is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_APPLICOM is not set
-+
-+#
-+# Ftape, the floppy tape device driver
-+#
-+# CONFIG_FTAPE is not set
-+# CONFIG_AGP is not set
-+# CONFIG_DRM is not set
-+
-+#
-+# PCMCIA character devices
-+#
-+CONFIG_PCMCIA_SERIAL_CS=y
-+CONFIG_PCMCIA_CHRDEV=y
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+
-+#
-+# File systems
-+#
-+# CONFIG_QUOTA is not set
-+CONFIG_AUTOFS_FS=y
-+CONFIG_AUTOFS4_FS=y
-+# CONFIG_REISERFS_FS is not set
-+# CONFIG_REISERFS_CHECK is not set
-+# CONFIG_REISERFS_PROC_INFO is not set
-+# CONFIG_ADFS_FS is not set
-+# CONFIG_ADFS_FS_RW is not set
-+# CONFIG_AFFS_FS is not set
-+# CONFIG_HFS_FS is not set
-+# CONFIG_BFS_FS is not set
-+# CONFIG_EXT3_FS is not set
-+# CONFIG_JBD is not set
-+# CONFIG_JBD_DEBUG is not set
-+CONFIG_FAT_FS=m
-+CONFIG_MSDOS_FS=m
-+CONFIG_UMSDOS_FS=m
-+CONFIG_VFAT_FS=m
-+# CONFIG_EFS_FS is not set
-+# CONFIG_JFFS_FS is not set
-+CONFIG_JFFS2_FS=y
-+CONFIG_JFFS2_FS_DEBUG=0
-+# CONFIG_CRAMFS is not set
-+CONFIG_TMPFS=y
-+CONFIG_RAMFS=y
-+# CONFIG_ISO9660_FS is not set
-+# CONFIG_JOLIET is not set
-+# CONFIG_ZISOFS is not set
-+# CONFIG_MINIX_FS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_NTFS_FS is not set
-+# CONFIG_NTFS_RW is not set
-+# CONFIG_HPFS_FS is not set
-+CONFIG_PROC_FS=y
-+# CONFIG_DEVFS_FS is not set
-+# CONFIG_DEVFS_MOUNT is not set
-+# CONFIG_DEVFS_DEBUG is not set
-+CONFIG_DEVPTS_FS=y
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_QNX4FS_RW is not set
-+CONFIG_ROMFS_FS=y
-+CONFIG_EXT2_FS=y
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UDF_FS is not set
-+# CONFIG_UDF_RW is not set
-+# CONFIG_UFS_FS is not set
-+# CONFIG_UFS_FS_WRITE is not set
-+
-+#
-+# Network File Systems
-+#
-+# CONFIG_CODA_FS is not set
-+# CONFIG_INTERMEZZO_FS is not set
-+CONFIG_NFS_FS=y
-+CONFIG_NFS_V3=y
-+CONFIG_ROOT_NFS=y
-+# CONFIG_NFSD is not set
-+# CONFIG_NFSD_V3 is not set
-+CONFIG_SUNRPC=y
-+CONFIG_LOCKD=y
-+CONFIG_LOCKD_V4=y
-+# CONFIG_SMB_FS is not set
-+# CONFIG_NCP_FS is not set
-+# CONFIG_NCPFS_PACKET_SIGNING is not set
-+# CONFIG_NCPFS_IOCTL_LOCKING is not set
-+# CONFIG_NCPFS_STRONG is not set
-+# CONFIG_NCPFS_NFS_NS is not set
-+# CONFIG_NCPFS_OS2_NS is not set
-+# CONFIG_NCPFS_SMALLDOS is not set
-+# CONFIG_NCPFS_NLS is not set
-+# CONFIG_NCPFS_EXTRAS is not set
-+# CONFIG_ZISOFS_FS is not set
-+# CONFIG_ZLIB_FS_INFLATE is not set
-+
-+#
-+# Partition Types
-+#
-+# CONFIG_PARTITION_ADVANCED is not set
-+CONFIG_MSDOS_PARTITION=y
-+# CONFIG_SMB_NLS is not set
-+CONFIG_NLS=y
-+
-+#
-+# Native Language Support
-+#
-+CONFIG_NLS_DEFAULT="iso8859-1"
-+CONFIG_NLS_CODEPAGE_437=m
-+# CONFIG_NLS_CODEPAGE_737 is not set
-+# CONFIG_NLS_CODEPAGE_775 is not set
-+CONFIG_NLS_CODEPAGE_850=m
-+CONFIG_NLS_CODEPAGE_852=m
-+# CONFIG_NLS_CODEPAGE_855 is not set
-+# CONFIG_NLS_CODEPAGE_857 is not set
-+# CONFIG_NLS_CODEPAGE_860 is not set
-+# CONFIG_NLS_CODEPAGE_861 is not set
-+# CONFIG_NLS_CODEPAGE_862 is not set
-+CONFIG_NLS_CODEPAGE_863=m
-+# CONFIG_NLS_CODEPAGE_864 is not set
-+# CONFIG_NLS_CODEPAGE_865 is not set
-+# CONFIG_NLS_CODEPAGE_866 is not set
-+# CONFIG_NLS_CODEPAGE_869 is not set
-+# CONFIG_NLS_CODEPAGE_936 is not set
-+# CONFIG_NLS_CODEPAGE_950 is not set
-+# CONFIG_NLS_CODEPAGE_932 is not set
-+# CONFIG_NLS_CODEPAGE_949 is not set
-+# CONFIG_NLS_CODEPAGE_874 is not set
-+# CONFIG_NLS_ISO8859_8 is not set
-+# CONFIG_NLS_CODEPAGE_1250 is not set
-+# CONFIG_NLS_CODEPAGE_1251 is not set
-+CONFIG_NLS_ISO8859_1=m
-+CONFIG_NLS_ISO8859_2=m
-+CONFIG_NLS_ISO8859_3=m
-+CONFIG_NLS_ISO8859_4=m
-+# CONFIG_NLS_ISO8859_5 is not set
-+# CONFIG_NLS_ISO8859_6 is not set
-+# CONFIG_NLS_ISO8859_7 is not set
-+# CONFIG_NLS_ISO8859_9 is not set
-+# CONFIG_NLS_ISO8859_13 is not set
-+# CONFIG_NLS_ISO8859_14 is not set
-+# CONFIG_NLS_ISO8859_15 is not set
-+# CONFIG_NLS_KOI8_R is not set
-+# CONFIG_NLS_KOI8_U is not set
-+# CONFIG_NLS_UTF8 is not set
-+
-+#
-+# Console drivers
-+#
-+CONFIG_PC_KEYMAP=y
-+# CONFIG_VGA_CONSOLE is not set
-+
-+#
-+# Frame-buffer support
-+#
-+# CONFIG_FB is not set
-+
-+#
-+# Sound
-+#
-+# CONFIG_SOUND is not set
-+
-+#
-+# Multimedia Capabilities Port drivers
-+#
-+# CONFIG_MCP is not set
-+# CONFIG_MCP_SA1100 is not set
-+# CONFIG_MCP_UCB1200 is not set
-+# CONFIG_MCP_UCB1200_AUDIO is not set
-+# CONFIG_MCP_UCB1200_TS is not set
-+# CONFIG_MCP_UCB1400_TS is not set
-+
-+#
-+# USB support
-+#
-+# CONFIG_USB is not set
-+
-+#
-+# Bluetooth support
-+#
-+# CONFIG_BLUEZ is not set
-+
-+#
-+# Kernel hacking
-+#
-+CONFIG_FRAME_POINTER=y
-+CONFIG_DEBUG_USER=y
-+# CONFIG_DEBUG_INFO is not set
-+# CONFIG_NO_PGT_CACHE is not set
-+CONFIG_DEBUG_KERNEL=y
-+# CONFIG_DEBUG_SLAB is not set
-+CONFIG_MAGIC_SYSRQ=y
-+# CONFIG_DEBUG_SPINLOCK is not set
-+# CONFIG_DEBUG_WAITQ is not set
-+CONFIG_DEBUG_BUGVERBOSE=y
-+CONFIG_DEBUG_ERRORS=y
-+CONFIG_DEBUG_LL=y
-+# CONFIG_DEBUG_DC21285_PORT is not set
-+# CONFIG_DEBUG_CLPS711X_UART2 is not set
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/def-configs/cerfpda_pxa 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,962 @@
-+#
-+# Automatically generated by make menuconfig: don't edit
-+#
-+CONFIG_ARM=y
-+# CONFIG_EISA is not set
-+# CONFIG_SBUS is not set
-+# CONFIG_MCA is not set
-+CONFIG_UID16=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-+# CONFIG_GENERIC_BUST_SPINLOCK is not set
-+# CONFIG_GENERIC_ISA_DMA is not set
-+
-+#
-+# Code maturity level options
-+#
-+CONFIG_EXPERIMENTAL=y
-+# CONFIG_OBSOLETE is not set
-+
-+#
-+# Loadable module support
-+#
-+CONFIG_MODULES=y
-+# CONFIG_MODVERSIONS is not set
-+CONFIG_KMOD=y
-+
-+#
-+# System Type
-+#
-+# CONFIG_ARCH_ANAKIN is not set
-+# CONFIG_ARCH_ARCA5K is not set
-+# CONFIG_ARCH_CLPS7500 is not set
-+# CONFIG_ARCH_CLPS711X is not set
-+# CONFIG_ARCH_CO285 is not set
-+CONFIG_ARCH_PXA=y
-+# CONFIG_ARCH_EBSA110 is not set
-+# CONFIG_ARCH_CAMELOT is not set
-+# CONFIG_ARCH_FOOTBRIDGE is not set
-+# CONFIG_ARCH_INTEGRATOR is not set
-+# CONFIG_ARCH_L7200 is not set
-+# CONFIG_ARCH_MX1ADS is not set
-+# CONFIG_ARCH_RPC is not set
-+# CONFIG_ARCH_SA1100 is not set
-+# CONFIG_ARCH_SHARK is not set
-+
-+#
-+# Archimedes/A5000 Implementations
-+#
-+# CONFIG_ARCH_ARC is not set
-+# CONFIG_ARCH_A5K is not set
-+
-+#
-+# Footbridge Implementations
-+#
-+# CONFIG_ARCH_CATS is not set
-+# CONFIG_ARCH_PERSONAL_SERVER is not set
-+# CONFIG_ARCH_EBSA285_ADDIN is not set
-+# CONFIG_ARCH_EBSA285_HOST is not set
-+# CONFIG_ARCH_NETWINDER is not set
-+
-+#
-+# SA11x0 Implementations
-+#
-+# CONFIG_SA1100_ASSABET is not set
-+# CONFIG_ASSABET_NEPONSET is not set
-+# CONFIG_SA1100_ADSBITSY is not set
-+# CONFIG_SA1100_BRUTUS is not set
-+# CONFIG_SA1100_CEP is not set
-+# CONFIG_SA1100_CERF is not set
-+# CONFIG_SA1100_H3100 is not set
-+# CONFIG_SA1100_H3600 is not set
-+# CONFIG_SA1100_H3800 is not set
-+# CONFIG_SA1100_H3XXX is not set
-+# CONFIG_SA1100_EXTENEX1 is not set
-+# CONFIG_SA1100_FLEXANET is not set
-+# CONFIG_SA1100_FREEBIRD is not set
-+# CONFIG_SA1100_FRODO is not set
-+# CONFIG_SA1100_GRAPHICSCLIENT is not set
-+# CONFIG_SA1100_GRAPHICSMASTER is not set
-+# CONFIG_SA1100_BADGE4 is not set
-+# CONFIG_SA1100_JORNADA720 is not set
-+# CONFIG_SA1100_HUW_WEBPANEL is not set
-+# CONFIG_SA1100_ITSY is not set
-+# CONFIG_SA1100_LART is not set
-+# CONFIG_SA1100_NANOENGINE is not set
-+# CONFIG_SA1100_OMNIMETER is not set
-+# CONFIG_SA1100_PANGOLIN is not set
-+# CONFIG_SA1100_PLEB is not set
-+# CONFIG_SA1100_PT_SYSTEM3 is not set
-+# CONFIG_SA1100_SHANNON is not set
-+# CONFIG_SA1100_SHERMAN is not set
-+# CONFIG_SA1100_SIMPAD is not set
-+# CONFIG_SA1100_PFS168 is not set
-+# CONFIG_SA1100_VICTOR is not set
-+# CONFIG_SA1100_XP860 is not set
-+# CONFIG_SA1100_YOPY is not set
-+# CONFIG_SA1100_USB is not set
-+# CONFIG_SA1100_USB_NETLINK is not set
-+# CONFIG_SA1100_USB_CHAR is not set
-+# CONFIG_H3600_SLEEVE is not set
-+
-+#
-+# Intel PXA250/210 Implementations
-+#
-+# CONFIG_ARCH_LUBBOCK is not set
-+# CONFIG_ARCH_PXA_IDP is not set
-+CONFIG_ARCH_PXA_CERF=y
-+CONFIG_PXA_CERF=y
-+CONFIG_PXA_CERF_PDA=y
-+# CONFIG_PXA_CERF_BOARD is not set
-+# CONFIG_PXA_CERF_RAM_128MB is not set
-+CONFIG_PXA_CERF_RAM_64MB=y
-+# CONFIG_PXA_CERF_RAM_32MB is not set
-+# CONFIG_PXA_CERF_RAM_16MB is not set
-+# CONFIG_PXA_CERF_FLASH_64MB is not set
-+CONFIG_PXA_CERF_FLASH_32MB=y
-+# CONFIG_PXA_CERF_FLASH_16MB is not set
-+# CONFIG_PXA_CERF_FLASH_8MB is not set
-+CONFIG_PXA_USB=y
-+CONFIG_PXA_USB_NETLINK=y
-+CONFIG_PXA_USB_CHAR=y
-+
-+#
-+# CLPS711X/EP721X Implementations
-+#
-+# CONFIG_ARCH_AUTCPU12 is not set
-+# CONFIG_ARCH_CDB89712 is not set
-+# CONFIG_ARCH_CLEP7312 is not set
-+# CONFIG_ARCH_EDB7211 is not set
-+# CONFIG_ARCH_P720T is not set
-+# CONFIG_ARCH_FORTUNET is not set
-+# CONFIG_ARCH_EP7211 is not set
-+# CONFIG_ARCH_EP7212 is not set
-+# CONFIG_ARCH_ACORN is not set
-+# CONFIG_FOOTBRIDGE is not set
-+# CONFIG_FOOTBRIDGE_HOST is not set
-+# CONFIG_FOOTBRIDGE_ADDIN is not set
-+CONFIG_CPU_32=y
-+# CONFIG_CPU_26 is not set
-+# CONFIG_CPU_32v3 is not set
-+# CONFIG_CPU_32v4 is not set
-+# CONFIG_CPU_ARM610 is not set
-+# CONFIG_CPU_ARM710 is not set
-+# CONFIG_CPU_ARM720T is not set
-+# CONFIG_CPU_ARM920T is not set
-+# CONFIG_CPU_ARM922T is not set
-+# CONFIG_PLD is not set
-+# CONFIG_CPU_ARM926T is not set
-+# CONFIG_CPU_ARM1020 is not set
-+# CONFIG_CPU_SA110 is not set
-+# CONFIG_CPU_SA1100 is not set
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_XSCALE=y
-+# CONFIG_XSCALE_CACHE_ERRATA is not set
-+# CONFIG_ARM_THUMB is not set
-+# CONFIG_DISCONTIGMEM is not set
-+
-+#
-+# General setup
-+#
-+# CONFIG_PCI is not set
-+# CONFIG_ISA is not set
-+# CONFIG_ISA_DMA is not set
-+# CONFIG_ZBOOT_ROM is not set
-+CONFIG_ZBOOT_ROM_TEXT=0
-+CONFIG_ZBOOT_ROM_BSS=0
-+CONFIG_HOTPLUG=y
-+
-+#
-+# PCMCIA/CardBus support
-+#
-+CONFIG_PCMCIA=y
-+# CONFIG_I82092 is not set
-+# CONFIG_I82365 is not set
-+# CONFIG_TCIC is not set
-+# CONFIG_PCMCIA_CLPS6700 is not set
-+# CONFIG_PCMCIA_SA1100 is not set
-+CONFIG_PCMCIA_PXA=y
-+CONFIG_NET=y
-+CONFIG_SYSVIPC=y
-+CONFIG_BSD_PROCESS_ACCT=y
-+CONFIG_SYSCTL=y
-+CONFIG_FPE_NWFPE=y
-+# CONFIG_FPE_FASTFPE is not set
-+CONFIG_KCORE_ELF=y
-+# CONFIG_KCORE_AOUT is not set
-+# CONFIG_BINFMT_AOUT is not set
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_MISC is not set
-+# CONFIG_PM is not set
-+# CONFIG_ARTHUR is not set
-+CONFIG_CMDLINE="root=1f03 rw console=tty0 console=ttyS0,38400 init=/linuxrc"
-+CONFIG_LEDS=y
-+# CONFIG_LEDS_TIMER is not set
-+CONFIG_LEDS_CPU=y
-+CONFIG_ALIGNMENT_TRAP=y
-+
-+#
-+# Parallel port support
-+#
-+# CONFIG_PARPORT is not set
-+
-+#
-+# Memory Technology Devices (MTD)
-+#
-+CONFIG_MTD=y
-+# CONFIG_MTD_DEBUG is not set
-+CONFIG_MTD_PARTITIONS=y
-+# CONFIG_MTD_CONCAT is not set
-+CONFIG_MTD_REDBOOT_PARTS=y
-+# CONFIG_MTD_CMDLINE_PARTS is not set
-+# CONFIG_MTD_AFS_PARTS is not set
-+CONFIG_MTD_CHAR=y
-+CONFIG_MTD_BLOCK=y
-+# CONFIG_FTL is not set
-+# CONFIG_NFTL is not set
-+
-+#
-+# RAM/ROM/Flash chip drivers
-+#
-+CONFIG_MTD_CFI=y
-+# CONFIG_MTD_JEDECPROBE is not set
-+CONFIG_MTD_GEN_PROBE=y
-+CONFIG_MTD_CFI_ADV_OPTIONS=y
-+CONFIG_MTD_CFI_NOSWAP=y
-+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-+CONFIG_MTD_CFI_GEOMETRY=y
-+# CONFIG_MTD_CFI_B1 is not set
-+# CONFIG_MTD_CFI_B2 is not set
-+CONFIG_MTD_CFI_B4=y
-+# CONFIG_MTD_CFI_B8 is not set
-+# CONFIG_MTD_CFI_I1 is not set
-+CONFIG_MTD_CFI_I2=y
-+# CONFIG_MTD_CFI_I4 is not set
-+# CONFIG_MTD_CFI_I8 is not set
-+CONFIG_MTD_CFI_INTELEXT=y
-+# CONFIG_MTD_CFI_AMDSTD is not set
-+# CONFIG_MTD_RAM is not set
-+# CONFIG_MTD_ROM is not set
-+# CONFIG_MTD_ABSENT is not set
-+# CONFIG_MTD_OBSOLETE_CHIPS is not set
-+# CONFIG_MTD_AMDSTD is not set
-+# CONFIG_MTD_SHARP is not set
-+# CONFIG_MTD_JEDEC is not set
-+
-+#
-+# Mapping drivers for chip access
-+#
-+# CONFIG_MTD_PHYSMAP is not set
-+# CONFIG_MTD_LUBBOCK is not set
-+# CONFIG_MTD_NORA is not set
-+# CONFIG_MTD_ARM_INTEGRATOR is not set
-+# CONFIG_MTD_CDB89712 is not set
-+# CONFIG_MTD_SA1100 is not set
-+# CONFIG_MTD_DC21285 is not set
-+# CONFIG_MTD_IQ80310 is not set
-+# CONFIG_MTD_FORTUNET is not set
-+CONFIG_MTD_PXA_CERF=y
-+# CONFIG_MTD_EPXA10DB is not set
-+# CONFIG_MTD_AUTCPU12 is not set
-+# CONFIG_MTD_EDB7312 is not set
-+# CONFIG_MTD_IMPA7 is not set
-+# CONFIG_MTD_PCI is not set
-+
-+#
-+# Self-contained MTD device drivers
-+#
-+# CONFIG_MTD_PMC551 is not set
-+# CONFIG_MTD_SLRAM is not set
-+# CONFIG_MTD_MTDRAM is not set
-+# CONFIG_MTD_BLKMTD is not set
-+# CONFIG_MTD_DOC1000 is not set
-+# CONFIG_MTD_DOC2000 is not set
-+# CONFIG_MTD_DOC2001 is not set
-+# CONFIG_MTD_DOCPROBE is not set
-+
-+#
-+# NAND Flash Device Drivers
-+#
-+# CONFIG_MTD_NAND is not set
-+
-+#
-+# Plug and Play configuration
-+#
-+# CONFIG_PNP is not set
-+# CONFIG_ISAPNP is not set
-+
-+#
-+# Block devices
-+#
-+# CONFIG_BLK_DEV_FD is not set
-+# CONFIG_BLK_DEV_XD is not set
-+# CONFIG_PARIDE is not set
-+# CONFIG_BLK_CPQ_DA is not set
-+# CONFIG_BLK_CPQ_CISS_DA is not set
-+# CONFIG_BLK_DEV_DAC960 is not set
-+CONFIG_BLK_DEV_LOOP=m
-+# CONFIG_BLK_DEV_NBD is not set
-+CONFIG_BLK_DEV_RAM=y
-+CONFIG_BLK_DEV_RAM_SIZE=4096
-+CONFIG_BLK_DEV_INITRD=y
-+
-+#
-+# Multi-device support (RAID and LVM)
-+#
-+# CONFIG_MD is not set
-+# CONFIG_BLK_DEV_MD is not set
-+# CONFIG_MD_LINEAR is not set
-+# CONFIG_MD_RAID0 is not set
-+# CONFIG_MD_RAID1 is not set
-+# CONFIG_MD_RAID5 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_BLK_DEV_LVM is not set
-+
-+#
-+# Networking options
-+#
-+CONFIG_PACKET=y
-+# CONFIG_PACKET_MMAP is not set
-+# CONFIG_NETLINK_DEV is not set
-+# CONFIG_NETFILTER is not set
-+CONFIG_FILTER=y
-+CONFIG_UNIX=y
-+CONFIG_INET=y
-+# CONFIG_IP_MULTICAST is not set
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+CONFIG_IP_PNP=y
-+CONFIG_IP_PNP_DHCP=y
-+CONFIG_IP_PNP_BOOTP=y
-+CONFIG_IP_PNP_RARP=y
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_ARPD is not set
-+# CONFIG_INET_ECN is not set
-+# CONFIG_SYN_COOKIES is not set
-+# CONFIG_IPV6 is not set
-+# CONFIG_KHTTPD is not set
-+# CONFIG_ATM is not set
-+# CONFIG_VLAN_8021Q is not set
-+# CONFIG_IPX is not set
-+# CONFIG_ATALK is not set
-+# CONFIG_DECNET is not set
-+# CONFIG_BRIDGE is not set
-+# CONFIG_X25 is not set
-+# CONFIG_LAPB is not set
-+# CONFIG_LLC is not set
-+# CONFIG_NET_DIVERT is not set
-+# CONFIG_ECONET is not set
-+# CONFIG_WAN_ROUTER is not set
-+# CONFIG_NET_FASTROUTE is not set
-+# CONFIG_NET_HW_FLOWCONTROL is not set
-+
-+#
-+# QoS and/or fair queueing
-+#
-+# CONFIG_NET_SCHED is not set
-+
-+#
-+# Network device support
-+#
-+CONFIG_NETDEVICES=y
-+
-+#
-+# ARCnet devices
-+#
-+# CONFIG_ARCNET is not set
-+# CONFIG_DUMMY is not set
-+# CONFIG_BONDING is not set
-+# CONFIG_EQUALIZER is not set
-+# CONFIG_TUN is not set
-+# CONFIG_ETHERTAP is not set
-+
-+#
-+# Ethernet (10 or 100Mbit)
-+#
-+CONFIG_NET_ETHERNET=y
-+# CONFIG_ARM_AM79C961A is not set
-+# CONFIG_SUNLANCE is not set
-+# CONFIG_SUNBMAC is not set
-+# CONFIG_SUNQE is not set
-+# CONFIG_SUNGEM is not set
-+# CONFIG_NET_VENDOR_3COM is not set
-+# CONFIG_LANCE is not set
-+# CONFIG_NET_VENDOR_SMC is not set
-+# CONFIG_NET_VENDOR_RACAL is not set
-+# CONFIG_NET_ISA is not set
-+# CONFIG_NET_PCI is not set
-+# CONFIG_NET_POCKET is not set
-+
-+#
-+# Ethernet (1000 Mbit)
-+#
-+# CONFIG_ACENIC is not set
-+# CONFIG_DL2K is not set
-+# CONFIG_MYRI_SBUS is not set
-+# CONFIG_NS83820 is not set
-+# CONFIG_HAMACHI is not set
-+# CONFIG_YELLOWFIN is not set
-+# CONFIG_SK98LIN is not set
-+# CONFIG_FDDI is not set
-+# CONFIG_HIPPI is not set
-+# CONFIG_PLIP is not set
-+CONFIG_PPP=m
-+# CONFIG_PPP_MULTILINK is not set
-+# CONFIG_PPP_FILTER is not set
-+CONFIG_PPP_ASYNC=m
-+# CONFIG_PPP_SYNC_TTY is not set
-+CONFIG_PPP_DEFLATE=m
-+CONFIG_PPP_BSDCOMP=m
-+# CONFIG_PPPOE is not set
-+# CONFIG_SLIP is not set
-+
-+#
-+# Wireless LAN (non-hamradio)
-+#
-+# CONFIG_NET_RADIO is not set
-+
-+#
-+# Token Ring devices
-+#
-+# CONFIG_TR is not set
-+# CONFIG_NET_FC is not set
-+# CONFIG_RCPCI is not set
-+# CONFIG_SHAPER is not set
-+
-+#
-+# Wan interfaces
-+#
-+# CONFIG_WAN is not set
-+
-+#
-+# PCMCIA network device support
-+#
-+CONFIG_NET_PCMCIA=y
-+CONFIG_PCMCIA_3C589=m
-+CONFIG_PCMCIA_3C574=m
-+CONFIG_PCMCIA_FMVJ18X=m
-+CONFIG_PCMCIA_PCNET=m
-+CONFIG_PCMCIA_AXNET=m
-+CONFIG_PCMCIA_NMCLAN=m
-+CONFIG_PCMCIA_SMC91C92=m
-+CONFIG_PCMCIA_XIRC2PS=m
-+# CONFIG_ARCNET_COM20020_CS is not set
-+# CONFIG_PCMCIA_IBMTR is not set
-+# CONFIG_NET_PCMCIA_RADIO is not set
-+
-+#
-+# Amateur Radio support
-+#
-+# CONFIG_HAMRADIO is not set
-+
-+#
-+# IrDA (infrared) support
-+#
-+CONFIG_IRDA=y
-+CONFIG_IRLAN=y
-+# CONFIG_IRNET is not set
-+CONFIG_IRCOMM=y
-+CONFIG_IRDA_ULTRA=y
-+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
-+# CONFIG_IRDA_FAST_RR is not set
-+CONFIG_IRDA_DEBUG=y
-+
-+#
-+# Infrared-port device drivers
-+#
-+CONFIG_IRTTY_SIR=y
-+# CONFIG_IRPORT_SIR is not set
-+# CONFIG_DONGLE is not set
-+# CONFIG_USB_IRDA is not set
-+# CONFIG_NSC_FIR is not set
-+# CONFIG_WINBOND_FIR is not set
-+# CONFIG_TOSHIBA_FIR is not set
-+# CONFIG_SMC_IRCC_FIR is not set
-+# CONFIG_ALI_FIR is not set
-+# CONFIG_VLSI_FIR is not set
-+
-+#
-+# ATA/IDE/MFM/RLL support
-+#
-+CONFIG_IDE=y
-+
-+#
-+# IDE, ATA and ATAPI Block devices
-+#
-+CONFIG_BLK_DEV_IDE=y
-+# CONFIG_BLK_DEV_HD_IDE is not set
-+# CONFIG_BLK_DEV_HD is not set
-+CONFIG_BLK_DEV_IDEDISK=y
-+# CONFIG_IDEDISK_MULTI_MODE is not set
-+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-+# CONFIG_BLK_DEV_IDEDISK_WD is not set
-+# CONFIG_BLK_DEV_COMMERIAL is not set
-+# CONFIG_BLK_DEV_TIVO is not set
-+CONFIG_BLK_DEV_IDECS=m
-+# CONFIG_BLK_DEV_IDECD is not set
-+# CONFIG_BLK_DEV_IDETAPE is not set
-+# CONFIG_BLK_DEV_IDEFLOPPY is not set
-+# CONFIG_BLK_DEV_IDESCSI is not set
-+# CONFIG_BLK_DEV_CMD640 is not set
-+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-+# CONFIG_BLK_DEV_ISAPNP is not set
-+# CONFIG_IDE_CHIPSETS is not set
-+# CONFIG_IDEDMA_AUTO is not set
-+# CONFIG_DMA_NONPCI is not set
-+# CONFIG_BLK_DEV_IDE_MODES is not set
-+# CONFIG_BLK_DEV_ATARAID is not set
-+# CONFIG_BLK_DEV_ATARAID_PDC is not set
-+# CONFIG_BLK_DEV_ATARAID_HPT is not set
-+
-+#
-+# SCSI support
-+#
-+# CONFIG_SCSI is not set
-+
-+#
-+# I2O device support
-+#
-+# CONFIG_I2O is not set
-+# CONFIG_I2O_BLOCK is not set
-+# CONFIG_I2O_LAN is not set
-+# CONFIG_I2O_SCSI is not set
-+# CONFIG_I2O_PROC is not set
-+
-+#
-+# ISDN subsystem
-+#
-+# CONFIG_ISDN is not set
-+
-+#
-+# Input core support
-+#
-+CONFIG_INPUT=y
-+# CONFIG_INPUT_KEYBDEV is not set
-+# CONFIG_INPUT_MOUSEDEV is not set
-+# CONFIG_INPUT_JOYDEV is not set
-+CONFIG_INPUT_EVDEV=y
-+
-+#
-+# Character devices
-+#
-+CONFIG_VT=y
-+CONFIG_VT_CONSOLE=y
-+CONFIG_SERIAL=y
-+CONFIG_SERIAL_CONSOLE=y
-+# CONFIG_SERIAL_EXTENDED is not set
-+# CONFIG_SERIAL_NONSTANDARD is not set
-+
-+#
-+# Serial drivers
-+#
-+# CONFIG_SERIAL_ANAKIN is not set
-+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-+# CONFIG_SERIAL_AMBA is not set
-+# CONFIG_SERIAL_AMBA_CONSOLE is not set
-+# CONFIG_SERIAL_CLPS711X is not set
-+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-+# CONFIG_SERIAL_21285 is not set
-+# CONFIG_SERIAL_21285_OLD is not set
-+# CONFIG_SERIAL_21285_CONSOLE is not set
-+# CONFIG_SERIAL_UART00 is not set
-+# CONFIG_SERIAL_UART00_CONSOLE is not set
-+# CONFIG_SERIAL_SA1100 is not set
-+# CONFIG_SERIAL_SA1100_CONSOLE is not set
-+# CONFIG_SERIAL_8250 is not set
-+# CONFIG_SERIAL_8250_CONSOLE is not set
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+# CONFIG_SERIAL_8250_MANY_PORTS is not set
-+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-+# CONFIG_SERIAL_8250_MULTIPORT is not set
-+# CONFIG_SERIAL_8250_HUB6 is not set
-+CONFIG_UNIX98_PTYS=y
-+CONFIG_UNIX98_PTY_COUNT=256
-+
-+#
-+# I2C support
-+#
-+# CONFIG_I2C is not set
-+
-+#
-+# L3 serial bus support
-+#
-+# CONFIG_L3 is not set
-+# CONFIG_L3_ALGOBIT is not set
-+# CONFIG_L3_BIT_SA1100_GPIO is not set
-+# CONFIG_L3_SA1111 is not set
-+# CONFIG_BIT_SA1100_GPIO is not set
-+
-+#
-+# Mice
-+#
-+# CONFIG_BUSMOUSE is not set
-+# CONFIG_MOUSE is not set
-+
-+#
-+# Joysticks
-+#
-+# CONFIG_INPUT_GAMEPORT is not set
-+# CONFIG_INPUT_NS558 is not set
-+# CONFIG_INPUT_LIGHTNING is not set
-+# CONFIG_INPUT_PCIGAME is not set
-+# CONFIG_INPUT_CS461X is not set
-+# CONFIG_INPUT_EMU10K1 is not set
-+# CONFIG_INPUT_SERIO is not set
-+# CONFIG_INPUT_SERPORT is not set
-+# CONFIG_INPUT_ANALOG is not set
-+# CONFIG_INPUT_A3D is not set
-+# CONFIG_INPUT_ADI is not set
-+# CONFIG_INPUT_COBRA is not set
-+# CONFIG_INPUT_GF2K is not set
-+# CONFIG_INPUT_GRIP is not set
-+# CONFIG_INPUT_INTERACT is not set
-+# CONFIG_INPUT_TMDC is not set
-+# CONFIG_INPUT_SIDEWINDER is not set
-+# CONFIG_INPUT_IFORCE_USB is not set
-+# CONFIG_INPUT_IFORCE_232 is not set
-+# CONFIG_INPUT_WARRIOR is not set
-+# CONFIG_INPUT_MAGELLAN is not set
-+# CONFIG_INPUT_SPACEORB is not set
-+# CONFIG_INPUT_SPACEBALL is not set
-+# CONFIG_INPUT_STINGER is not set
-+# CONFIG_INPUT_DB9 is not set
-+# CONFIG_INPUT_GAMECON is not set
-+# CONFIG_INPUT_TURBOGRAFX is not set
-+# CONFIG_QIC02_TAPE is not set
-+
-+#
-+# Watchdog Cards
-+#
-+# CONFIG_WATCHDOG is not set
-+# CONFIG_INTEL_RNG is not set
-+# CONFIG_NVRAM is not set
-+# CONFIG_RTC is not set
-+# CONFIG_DTLK is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_APPLICOM is not set
-+
-+#
-+# Ftape, the floppy tape device driver
-+#
-+# CONFIG_FTAPE is not set
-+# CONFIG_AGP is not set
-+# CONFIG_DRM is not set
-+
-+#
-+# PCMCIA character devices
-+#
-+CONFIG_PCMCIA_SERIAL_CS=y
-+CONFIG_PCMCIA_CHRDEV=y
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+
-+#
-+# File systems
-+#
-+# CONFIG_QUOTA is not set
-+CONFIG_AUTOFS_FS=y
-+CONFIG_AUTOFS4_FS=y
-+# CONFIG_REISERFS_FS is not set
-+# CONFIG_REISERFS_CHECK is not set
-+# CONFIG_REISERFS_PROC_INFO is not set
-+# CONFIG_ADFS_FS is not set
-+# CONFIG_ADFS_FS_RW is not set
-+# CONFIG_AFFS_FS is not set
-+# CONFIG_HFS_FS is not set
-+# CONFIG_BFS_FS is not set
-+# CONFIG_EXT3_FS is not set
-+# CONFIG_JBD is not set
-+# CONFIG_JBD_DEBUG is not set
-+CONFIG_FAT_FS=m
-+CONFIG_MSDOS_FS=m
-+CONFIG_UMSDOS_FS=m
-+CONFIG_VFAT_FS=m
-+# CONFIG_EFS_FS is not set
-+# CONFIG_JFFS_FS is not set
-+CONFIG_JFFS2_FS=y
-+CONFIG_JFFS2_FS_DEBUG=0
-+# CONFIG_CRAMFS is not set
-+CONFIG_TMPFS=y
-+CONFIG_RAMFS=m
-+# CONFIG_ISO9660_FS is not set
-+# CONFIG_JOLIET is not set
-+# CONFIG_ZISOFS is not set
-+# CONFIG_MINIX_FS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_NTFS_FS is not set
-+# CONFIG_NTFS_RW is not set
-+# CONFIG_HPFS_FS is not set
-+CONFIG_PROC_FS=y
-+# CONFIG_DEVFS_FS is not set
-+# CONFIG_DEVFS_MOUNT is not set
-+# CONFIG_DEVFS_DEBUG is not set
-+CONFIG_DEVPTS_FS=y
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_QNX4FS_RW is not set
-+CONFIG_ROMFS_FS=y
-+CONFIG_EXT2_FS=y
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UDF_FS is not set
-+# CONFIG_UDF_RW is not set
-+# CONFIG_UFS_FS is not set
-+# CONFIG_UFS_FS_WRITE is not set
-+
-+#
-+# Network File Systems
-+#
-+# CONFIG_CODA_FS is not set
-+# CONFIG_INTERMEZZO_FS is not set
-+CONFIG_NFS_FS=y
-+CONFIG_NFS_V3=y
-+CONFIG_ROOT_NFS=y
-+# CONFIG_NFSD is not set
-+# CONFIG_NFSD_V3 is not set
-+CONFIG_SUNRPC=y
-+CONFIG_LOCKD=y
-+CONFIG_LOCKD_V4=y
-+# CONFIG_SMB_FS is not set
-+# CONFIG_NCP_FS is not set
-+# CONFIG_NCPFS_PACKET_SIGNING is not set
-+# CONFIG_NCPFS_IOCTL_LOCKING is not set
-+# CONFIG_NCPFS_STRONG is not set
-+# CONFIG_NCPFS_NFS_NS is not set
-+# CONFIG_NCPFS_OS2_NS is not set
-+# CONFIG_NCPFS_SMALLDOS is not set
-+# CONFIG_NCPFS_NLS is not set
-+# CONFIG_NCPFS_EXTRAS is not set
-+# CONFIG_ZISOFS_FS is not set
-+# CONFIG_ZLIB_FS_INFLATE is not set
-+
-+#
-+# Partition Types
-+#
-+# CONFIG_PARTITION_ADVANCED is not set
-+CONFIG_MSDOS_PARTITION=y
-+# CONFIG_SMB_NLS is not set
-+CONFIG_NLS=y
-+
-+#
-+# Native Language Support
-+#
-+CONFIG_NLS_DEFAULT="iso8859-1"
-+CONFIG_NLS_CODEPAGE_437=m
-+# CONFIG_NLS_CODEPAGE_737 is not set
-+# CONFIG_NLS_CODEPAGE_775 is not set
-+CONFIG_NLS_CODEPAGE_850=m
-+CONFIG_NLS_CODEPAGE_852=m
-+# CONFIG_NLS_CODEPAGE_855 is not set
-+# CONFIG_NLS_CODEPAGE_857 is not set
-+# CONFIG_NLS_CODEPAGE_860 is not set
-+# CONFIG_NLS_CODEPAGE_861 is not set
-+# CONFIG_NLS_CODEPAGE_862 is not set
-+CONFIG_NLS_CODEPAGE_863=m
-+# CONFIG_NLS_CODEPAGE_864 is not set
-+# CONFIG_NLS_CODEPAGE_865 is not set
-+# CONFIG_NLS_CODEPAGE_866 is not set
-+# CONFIG_NLS_CODEPAGE_869 is not set
-+# CONFIG_NLS_CODEPAGE_936 is not set
-+# CONFIG_NLS_CODEPAGE_950 is not set
-+# CONFIG_NLS_CODEPAGE_932 is not set
-+# CONFIG_NLS_CODEPAGE_949 is not set
-+# CONFIG_NLS_CODEPAGE_874 is not set
-+# CONFIG_NLS_ISO8859_8 is not set
-+# CONFIG_NLS_CODEPAGE_1250 is not set
-+# CONFIG_NLS_CODEPAGE_1251 is not set
-+CONFIG_NLS_ISO8859_1=m
-+CONFIG_NLS_ISO8859_2=m
-+CONFIG_NLS_ISO8859_3=m
-+CONFIG_NLS_ISO8859_4=m
-+# CONFIG_NLS_ISO8859_5 is not set
-+# CONFIG_NLS_ISO8859_6 is not set
-+# CONFIG_NLS_ISO8859_7 is not set
-+# CONFIG_NLS_ISO8859_9 is not set
-+# CONFIG_NLS_ISO8859_13 is not set
-+# CONFIG_NLS_ISO8859_14 is not set
-+# CONFIG_NLS_ISO8859_15 is not set
-+# CONFIG_NLS_KOI8_R is not set
-+# CONFIG_NLS_KOI8_U is not set
-+# CONFIG_NLS_UTF8 is not set
-+
-+#
-+# Console drivers
-+#
-+CONFIG_PC_KEYMAP=y
-+# CONFIG_VGA_CONSOLE is not set
-+
-+#
-+# Frame-buffer support
-+#
-+CONFIG_FB=y
-+CONFIG_DUMMY_CONSOLE=y
-+# CONFIG_FB_ACORN is not set
-+# CONFIG_FB_ANAKIN is not set
-+# CONFIG_FB_CLPS711X is not set
-+# CONFIG_FB_SA1100 is not set
-+CONFIG_FB_PXA=y
-+# CONFIG_FB_PXA_8BPP is not set
-+CONFIG_FB_PXA_16BPP=y
-+# CONFIG_FB_CYBER2000 is not set
-+# CONFIG_FB_VIRTUAL is not set
-+# CONFIG_FBCON_ADVANCED is not set
-+CONFIG_FBCON_CFB2=y
-+CONFIG_FBCON_CFB4=y
-+CONFIG_FBCON_CFB8=y
-+CONFIG_FBCON_CFB16=y
-+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-+CONFIG_FBCON_FONTS=y
-+# CONFIG_FONT_8x8 is not set
-+# CONFIG_FONT_8x16 is not set
-+# CONFIG_FONT_SUN8x16 is not set
-+# CONFIG_FONT_SUN12x22 is not set
-+# CONFIG_FONT_6x11 is not set
-+# CONFIG_FONT_PEARL_8x8 is not set
-+CONFIG_FONT_ACORN_8x8=y
-+
-+#
-+# Sound
-+#
-+CONFIG_SOUND=y
-+# CONFIG_SOUND_BT878 is not set
-+# CONFIG_SOUND_CMPCI is not set
-+# CONFIG_SOUND_EMU10K1 is not set
-+# CONFIG_MIDI_EMU10K1 is not set
-+# CONFIG_SOUND_FUSION is not set
-+# CONFIG_SOUND_CS4281 is not set
-+# CONFIG_SOUND_ES1370 is not set
-+# CONFIG_SOUND_ES1371 is not set
-+# CONFIG_SOUND_ESSSOLO1 is not set
-+# CONFIG_SOUND_MAESTRO is not set
-+# CONFIG_SOUND_MAESTRO3 is not set
-+# CONFIG_SOUND_ICH is not set
-+# CONFIG_SOUND_RME96XX is not set
-+# CONFIG_SOUND_SONICVIBES is not set
-+# CONFIG_SOUND_TRIDENT is not set
-+# CONFIG_SOUND_MSNDCLAS is not set
-+# CONFIG_SOUND_MSNDPIN is not set
-+# CONFIG_SOUND_VIA82CXXX is not set
-+# CONFIG_MIDI_VIA82CXXX is not set
-+# CONFIG_SOUND_OSS is not set
-+# CONFIG_SOUND_WAVEARTIST is not set
-+CONFIG_SOUND_PXA_AC97=y
-+# CONFIG_SOUND_TVMIXER is not set
-+
-+#
-+# Multimedia Capabilities Port drivers
-+#
-+# CONFIG_MCP is not set
-+# CONFIG_MCP_SA1100 is not set
-+# CONFIG_MCP_UCB1200 is not set
-+# CONFIG_MCP_UCB1200_AUDIO is not set
-+# CONFIG_MCP_UCB1200_TS is not set
-+CONFIG_MCP_UCB1400_TS=y
-+
-+#
-+# USB support
-+#
-+# CONFIG_USB is not set
-+# CONFIG_USB_UHCI is not set
-+# CONFIG_USB_UHCI_ALT is not set
-+# CONFIG_USB_OHCI is not set
-+# CONFIG_USB_OHCI_SA1111 is not set
-+# CONFIG_USB_AUDIO is not set
-+# CONFIG_USB_BLUETOOTH is not set
-+# CONFIG_USB_STORAGE is not set
-+# CONFIG_USB_STORAGE_DEBUG is not set
-+# CONFIG_USB_STORAGE_DATAFAB is not set
-+# CONFIG_USB_STORAGE_FREECOM is not set
-+# CONFIG_USB_STORAGE_ISD200 is not set
-+# CONFIG_USB_STORAGE_DPCM is not set
-+# CONFIG_USB_STORAGE_HP8200e is not set
-+# CONFIG_USB_STORAGE_SDDR09 is not set
-+# CONFIG_USB_STORAGE_JUMPSHOT is not set
-+# CONFIG_USB_ACM is not set
-+# CONFIG_USB_PRINTER is not set
-+# CONFIG_USB_HID is not set
-+# CONFIG_USB_HIDDEV is not set
-+# CONFIG_USB_KBD is not set
-+# CONFIG_USB_MOUSE is not set
-+# CONFIG_USB_WACOM is not set
-+# CONFIG_USB_DC2XX is not set
-+# CONFIG_USB_MDC800 is not set
-+# CONFIG_USB_SCANNER is not set
-+# CONFIG_USB_MICROTEK is not set
-+# CONFIG_USB_HPUSBSCSI is not set
-+# CONFIG_USB_PEGASUS is not set
-+# CONFIG_USB_KAWETH is not set
-+# CONFIG_USB_CATC is not set
-+# CONFIG_USB_CDCETHER is not set
-+# CONFIG_USB_USBNET is not set
-+# CONFIG_USB_USS720 is not set
-+
-+#
-+# USB Serial Converter support
-+#
-+# CONFIG_USB_SERIAL is not set
-+# CONFIG_USB_SERIAL_GENERIC is not set
-+# CONFIG_USB_SERIAL_BELKIN is not set
-+# CONFIG_USB_SERIAL_WHITEHEAT is not set
-+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-+# CONFIG_USB_SERIAL_EMPEG is not set
-+# CONFIG_USB_SERIAL_FTDI_SIO is not set
-+# CONFIG_USB_SERIAL_VISOR is not set
-+# CONFIG_USB_SERIAL_IPAQ is not set
-+# CONFIG_USB_SERIAL_IR is not set
-+# CONFIG_USB_SERIAL_EDGEPORT is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-+# CONFIG_USB_SERIAL_KEYSPAN is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-+# CONFIG_USB_SERIAL_MCT_U232 is not set
-+# CONFIG_USB_SERIAL_KLSI is not set
-+# CONFIG_USB_SERIAL_PL2303 is not set
-+# CONFIG_USB_SERIAL_CYBERJACK is not set
-+# CONFIG_USB_SERIAL_XIRCOM is not set
-+# CONFIG_USB_SERIAL_OMNINET is not set
-+# CONFIG_USB_RIO500 is not set
-+
-+#
-+# Bluetooth support
-+#
-+CONFIG_BLUEZ=y
-+CONFIG_BLUEZ_L2CAP=y
-+
-+#
-+# Bluetooth device drivers
-+#
-+# CONFIG_BLUEZ_HCIUSB is not set
-+CONFIG_BLUEZ_HCIUART=y
-+CONFIG_BLUEZ_HCIVHCI=y
-+
-+#
-+# Kernel hacking
-+#
-+CONFIG_FRAME_POINTER=y
-+CONFIG_DEBUG_USER=y
-+CONFIG_DEBUG_INFO=y
-+# CONFIG_NO_PGT_CACHE is not set
-+CONFIG_DEBUG_KERNEL=y
-+# CONFIG_DEBUG_SLAB is not set
-+CONFIG_MAGIC_SYSRQ=y
-+# CONFIG_DEBUG_SPINLOCK is not set
-+# CONFIG_DEBUG_WAITQ is not set
-+CONFIG_DEBUG_BUGVERBOSE=y
-+CONFIG_DEBUG_ERRORS=y
-+CONFIG_DEBUG_LL=y
-+# CONFIG_DEBUG_DC21285_PORT is not set
-+# CONFIG_DEBUG_CLPS711X_UART2 is not set
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/def-configs/csb226 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,615 @@
-+#
-+# Automatically generated by make menuconfig: don't edit
-+#
-+CONFIG_ARM=y
-+# CONFIG_EISA is not set
-+# CONFIG_SBUS is not set
-+# CONFIG_MCA is not set
-+CONFIG_UID16=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-+# CONFIG_GENERIC_BUST_SPINLOCK is not set
-+# CONFIG_GENERIC_ISA_DMA is not set
-+
-+#
-+# Code maturity level options
-+#
-+CONFIG_EXPERIMENTAL=y
-+# CONFIG_OBSOLETE is not set
-+
-+#
-+# Loadable module support
-+#
-+CONFIG_MODULES=y
-+# CONFIG_MODVERSIONS is not set
-+CONFIG_KMOD=y
-+
-+#
-+# System Type
-+#
-+# CONFIG_ARCH_ANAKIN is not set
-+# CONFIG_ARCH_ARCA5K is not set
-+# CONFIG_ARCH_CLPS7500 is not set
-+# CONFIG_ARCH_CLPS711X is not set
-+# CONFIG_ARCH_CO285 is not set
-+CONFIG_ARCH_PXA=y
-+# CONFIG_ARCH_EBSA110 is not set
-+# CONFIG_ARCH_CAMELOT is not set
-+# CONFIG_ARCH_FOOTBRIDGE is not set
-+# CONFIG_ARCH_INTEGRATOR is not set
-+# CONFIG_ARCH_OMAHA is not set
-+# CONFIG_ARCH_L7200 is not set
-+# CONFIG_ARCH_MX1ADS is not set
-+# CONFIG_ARCH_RPC is not set
-+# CONFIG_ARCH_RISCSTATION is not set
-+# CONFIG_ARCH_SA1100 is not set
-+# CONFIG_ARCH_SHARK is not set
-+# CONFIG_ARCH_AT91RM9200DK is not set
-+
-+#
-+# Archimedes/A5000 Implementations
-+#
-+# CONFIG_ARCH_ARC is not set
-+# CONFIG_ARCH_A5K is not set
-+
-+#
-+# Footbridge Implementations
-+#
-+# CONFIG_ARCH_CATS is not set
-+# CONFIG_ARCH_PERSONAL_SERVER is not set
-+# CONFIG_ARCH_EBSA285_ADDIN is not set
-+# CONFIG_ARCH_EBSA285_HOST is not set
-+# CONFIG_ARCH_NETWINDER is not set
-+
-+#
-+# SA11x0 Implementations
-+#
-+# CONFIG_SA1100_ACCELENT is not set
-+# CONFIG_SA1100_ASSABET is not set
-+# CONFIG_ASSABET_NEPONSET is not set
-+# CONFIG_SA1100_ADSBITSY is not set
-+# CONFIG_SA1100_BRUTUS is not set
-+# CONFIG_SA1100_CEP is not set
-+# CONFIG_SA1100_CERF is not set
-+# CONFIG_SA1100_H3100 is not set
-+# CONFIG_SA1100_H3600 is not set
-+# CONFIG_SA1100_H3800 is not set
-+# CONFIG_SA1100_H3XXX is not set
-+# CONFIG_SA1100_EXTENEX1 is not set
-+# CONFIG_SA1100_FLEXANET is not set
-+# CONFIG_SA1100_FREEBIRD is not set
-+# CONFIG_SA1100_FRODO is not set
-+# CONFIG_SA1100_GRAPHICSCLIENT is not set
-+# CONFIG_SA1100_GRAPHICSMASTER is not set
-+# CONFIG_SA1100_HACKKIT is not set
-+# CONFIG_SA1100_BADGE4 is not set
-+# CONFIG_SA1100_JORNADA720 is not set
-+# CONFIG_SA1100_HUW_WEBPANEL is not set
-+# CONFIG_SA1100_ITSY is not set
-+# CONFIG_SA1100_LART is not set
-+# CONFIG_SA1100_NANOENGINE is not set
-+# CONFIG_SA1100_OMNIMETER is not set
-+# CONFIG_SA1100_PANGOLIN is not set
-+# CONFIG_SA1100_PLEB is not set
-+# CONFIG_SA1100_PT_SYSTEM3 is not set
-+# CONFIG_SA1100_SHANNON is not set
-+# CONFIG_SA1100_SHERMAN is not set
-+# CONFIG_SA1100_SIMPAD is not set
-+# CONFIG_SA1100_SIMPUTER is not set
-+# CONFIG_SA1100_PFS168 is not set
-+# CONFIG_SA1100_VICTOR is not set
-+# CONFIG_SA1100_XP860 is not set
-+# CONFIG_SA1100_YOPY is not set
-+# CONFIG_SA1100_USB is not set
-+# CONFIG_SA1100_USB_NETLINK is not set
-+# CONFIG_SA1100_USB_CHAR is not set
-+# CONFIG_H3600_SLEEVE is not set
-+
-+#
-+# Intel PXA250/210 Board
-+#
-+# CONFIG_ARCH_PXA_IDP is not set
-+# CONFIG_ARCH_INNOKOM is not set
-+CONFIG_ARCH_CSB226=y
-+# CONFIG_ARCH_LUBBOCK is not set
-+# CONFIG_ARCH_PXA_CERF is not set
-+# CONFIG_PXA_USB is not set
-+# CONFIG_PXA_USB_NETLINK is not set
-+# CONFIG_PXA_USB_CHAR is not set
-+
-+#
-+# CLPS711X/EP721X Implementations
-+#
-+# CONFIG_ARCH_AUTCPU12 is not set
-+# CONFIG_ARCH_CDB89712 is not set
-+# CONFIG_ARCH_CLEP7312 is not set
-+# CONFIG_ARCH_EDB7211 is not set
-+# CONFIG_ARCH_P720T is not set
-+# CONFIG_ARCH_FORTUNET is not set
-+# CONFIG_ARCH_EP7211 is not set
-+# CONFIG_ARCH_EP7212 is not set
-+# CONFIG_ARCH_ACORN is not set
-+# CONFIG_FOOTBRIDGE is not set
-+# CONFIG_FOOTBRIDGE_HOST is not set
-+# CONFIG_FOOTBRIDGE_ADDIN is not set
-+CONFIG_CPU_32=y
-+# CONFIG_CPU_26 is not set
-+# CONFIG_CPU_ARM610 is not set
-+# CONFIG_CPU_ARM710 is not set
-+# CONFIG_CPU_ARM720T is not set
-+# CONFIG_CPU_ARM920T is not set
-+# CONFIG_CPU_ARM922T is not set
-+# CONFIG_PLD is not set
-+# CONFIG_CPU_ARM926T is not set
-+# CONFIG_CPU_ARM1020 is not set
-+# CONFIG_CPU_ARM1026 is not set
-+# CONFIG_CPU_SA110 is not set
-+# CONFIG_CPU_SA1100 is not set
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_XSCALE=y
-+CONFIG_XSCALE_CACHE_ERRATA=y
-+# CONFIG_CPU_32v3 is not set
-+# CONFIG_CPU_32v4 is not set
-+# CONFIG_DISCONTIGMEM is not set
-+
-+#
-+# General setup
-+#
-+# CONFIG_PCI is not set
-+# CONFIG_ISA is not set
-+# CONFIG_ISA_DMA is not set
-+# CONFIG_ZBOOT_ROM is not set
-+CONFIG_ZBOOT_ROM_TEXT=0
-+CONFIG_ZBOOT_ROM_BSS=0
-+# CONFIG_CPU_FREQ is not set
-+# CONFIG_HOTPLUG is not set
-+# CONFIG_PCMCIA is not set
-+# CONFIG_MMC is not set
-+CONFIG_NET=y
-+CONFIG_SYSVIPC=y
-+# CONFIG_BSD_PROCESS_ACCT is not set
-+CONFIG_SYSCTL=y
-+# CONFIG_XIP_KERNEL is not set
-+CONFIG_FPE_NWFPE=y
-+# CONFIG_FPE_FASTFPE is not set
-+CONFIG_KCORE_ELF=y
-+# CONFIG_KCORE_AOUT is not set
-+# CONFIG_BINFMT_AOUT is not set
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_MISC is not set
-+# CONFIG_PM is not set
-+# CONFIG_ARTHUR is not set
-+CONFIG_CMDLINE="console=ttyS0,19200"
-+CONFIG_ALIGNMENT_TRAP=y
-+CONFIG_ARM_HWTIMER=y
-+
-+#
-+# Parallel port support
-+#
-+# CONFIG_PARPORT is not set
-+
-+#
-+# Memory Technology Devices (MTD)
-+#
-+# CONFIG_MTD is not set
-+
-+#
-+# Plug and Play configuration
-+#
-+# CONFIG_PNP is not set
-+# CONFIG_ISAPNP is not set
-+
-+#
-+# Block devices
-+#
-+# CONFIG_BLK_DEV_FD is not set
-+# CONFIG_BLK_DEV_XD is not set
-+# CONFIG_PARIDE is not set
-+# CONFIG_BLK_CPQ_DA is not set
-+# CONFIG_BLK_CPQ_CISS_DA is not set
-+# CONFIG_CISS_SCSI_TAPE is not set
-+# CONFIG_BLK_DEV_DAC960 is not set
-+# CONFIG_BLK_DEV_UMEM is not set
-+# CONFIG_BLK_DEV_LOOP is not set
-+# CONFIG_BLK_DEV_NBD is not set
-+# CONFIG_BLK_DEV_RAM is not set
-+# CONFIG_BLK_DEV_INITRD is not set
-+
-+#
-+# Multi-device support (RAID and LVM)
-+#
-+# CONFIG_MD is not set
-+# CONFIG_BLK_DEV_MD is not set
-+# CONFIG_MD_LINEAR is not set
-+# CONFIG_MD_RAID0 is not set
-+# CONFIG_MD_RAID1 is not set
-+# CONFIG_MD_RAID5 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_BLK_DEV_LVM is not set
-+
-+#
-+# Networking options
-+#
-+# CONFIG_PACKET is not set
-+# CONFIG_NETLINK_DEV is not set
-+# CONFIG_NETFILTER is not set
-+# CONFIG_FILTER is not set
-+CONFIG_UNIX=y
-+CONFIG_INET=y
-+# CONFIG_IP_MULTICAST is not set
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+CONFIG_IP_PNP=y
-+# CONFIG_IP_PNP_DHCP is not set
-+CONFIG_IP_PNP_BOOTP=y
-+# CONFIG_IP_PNP_RARP is not set
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_ARPD is not set
-+# CONFIG_INET_ECN is not set
-+# CONFIG_SYN_COOKIES is not set
-+# CONFIG_IPV6 is not set
-+# CONFIG_KHTTPD is not set
-+# CONFIG_ATM is not set
-+# CONFIG_VLAN_8021Q is not set
-+# CONFIG_IPX is not set
-+# CONFIG_ATALK is not set
-+
-+#
-+# Appletalk devices
-+#
-+# CONFIG_DEV_APPLETALK is not set
-+# CONFIG_DECNET is not set
-+# CONFIG_BRIDGE is not set
-+# CONFIG_X25 is not set
-+# CONFIG_LAPB is not set
-+# CONFIG_LLC is not set
-+# CONFIG_NET_DIVERT is not set
-+# CONFIG_ECONET is not set
-+# CONFIG_WAN_ROUTER is not set
-+# CONFIG_NET_FASTROUTE is not set
-+# CONFIG_NET_HW_FLOWCONTROL is not set
-+
-+#
-+# QoS and/or fair queueing
-+#
-+# CONFIG_NET_SCHED is not set
-+
-+#
-+# Network testing
-+#
-+# CONFIG_NET_PKTGEN is not set
-+
-+#
-+# Network device support
-+#
-+CONFIG_NETDEVICES=y
-+
-+#
-+# ARCnet devices
-+#
-+# CONFIG_ARCNET is not set
-+# CONFIG_DUMMY is not set
-+# CONFIG_BONDING is not set
-+# CONFIG_EQUALIZER is not set
-+# CONFIG_TUN is not set
-+# CONFIG_ETHERTAP is not set
-+
-+#
-+# Ethernet (10 or 100Mbit)
-+#
-+CONFIG_NET_ETHERNET=y
-+# CONFIG_ARM_AM79C961A is not set
-+CONFIG_ARM_CIRRUS=y
-+# CONFIG_SUNLANCE is not set
-+# CONFIG_SUNBMAC is not set
-+# CONFIG_SUNQE is not set
-+# CONFIG_SUNGEM is not set
-+# CONFIG_NET_VENDOR_3COM is not set
-+# CONFIG_LANCE is not set
-+# CONFIG_NET_VENDOR_SMC is not set
-+# CONFIG_NET_VENDOR_RACAL is not set
-+# CONFIG_NET_ISA is not set
-+# CONFIG_NET_PCI is not set
-+# CONFIG_NET_POCKET is not set
-+
-+#
-+# Ethernet (1000 Mbit)
-+#
-+# CONFIG_ACENIC is not set
-+# CONFIG_DL2K is not set
-+# CONFIG_MYRI_SBUS is not set
-+# CONFIG_NS83820 is not set
-+# CONFIG_HAMACHI is not set
-+# CONFIG_YELLOWFIN is not set
-+# CONFIG_SK98LIN is not set
-+# CONFIG_TIGON3 is not set
-+# CONFIG_FDDI is not set
-+# CONFIG_HIPPI is not set
-+# CONFIG_PLIP is not set
-+# CONFIG_PPP is not set
-+# CONFIG_SLIP is not set
-+
-+#
-+# Wireless LAN (non-hamradio)
-+#
-+# CONFIG_NET_RADIO is not set
-+
-+#
-+# Token Ring devices
-+#
-+# CONFIG_TR is not set
-+# CONFIG_NET_FC is not set
-+# CONFIG_RCPCI is not set
-+# CONFIG_SHAPER is not set
-+
-+#
-+# Wan interfaces
-+#
-+# CONFIG_WAN is not set
-+
-+#
-+# Amateur Radio support
-+#
-+# CONFIG_HAMRADIO is not set
-+
-+#
-+# IrDA (infrared) support
-+#
-+# CONFIG_IRDA is not set
-+
-+#
-+# ATA/ATAPI/MFM/RLL support
-+#
-+# CONFIG_IDE is not set
-+# CONFIG_BLK_DEV_IDE_MODES is not set
-+# CONFIG_BLK_DEV_HD is not set
-+
-+#
-+# SCSI support
-+#
-+# CONFIG_SCSI is not set
-+
-+#
-+# I2O device support
-+#
-+# CONFIG_I2O is not set
-+# CONFIG_I2O_BLOCK is not set
-+# CONFIG_I2O_LAN is not set
-+# CONFIG_I2O_SCSI is not set
-+# CONFIG_I2O_PROC is not set
-+
-+#
-+# ISDN subsystem
-+#
-+# CONFIG_ISDN is not set
-+
-+#
-+# Input core support
-+#
-+# CONFIG_INPUT is not set
-+# CONFIG_INPUT_KEYBDEV is not set
-+# CONFIG_INPUT_MOUSEDEV is not set
-+# CONFIG_INPUT_JOYDEV is not set
-+# CONFIG_INPUT_EVDEV is not set
-+
-+#
-+# Character devices
-+#
-+# CONFIG_VT is not set
-+CONFIG_SERIAL=y
-+CONFIG_SERIAL_CONSOLE=y
-+# CONFIG_SERIAL_EXTENDED is not set
-+# CONFIG_SERIAL_NONSTANDARD is not set
-+
-+#
-+# Serial drivers
-+#
-+# CONFIG_SERIAL_ANAKIN is not set
-+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-+# CONFIG_SERIAL_AMBA is not set
-+# CONFIG_SERIAL_AMBA_CONSOLE is not set
-+# CONFIG_SERIAL_CLPS711X is not set
-+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-+# CONFIG_SERIAL_21285 is not set
-+# CONFIG_SERIAL_21285_OLD is not set
-+# CONFIG_SERIAL_21285_CONSOLE is not set
-+# CONFIG_SERIAL_UART00 is not set
-+# CONFIG_SERIAL_UART00_CONSOLE is not set
-+# CONFIG_SERIAL_SA1100 is not set
-+# CONFIG_SERIAL_SA1100_CONSOLE is not set
-+# CONFIG_SERIAL_OMAHA is not set
-+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
-+# CONFIG_SERIAL_8250 is not set
-+# CONFIG_SERIAL_8250_CONSOLE is not set
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+# CONFIG_SERIAL_8250_MANY_PORTS is not set
-+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-+# CONFIG_SERIAL_8250_MULTIPORT is not set
-+# CONFIG_SERIAL_8250_HUB6 is not set
-+CONFIG_UNIX98_PTYS=y
-+CONFIG_UNIX98_PTY_COUNT=256
-+
-+#
-+# I2C support
-+#
-+# CONFIG_I2C is not set
-+
-+#
-+# L3 serial bus support
-+#
-+# CONFIG_L3 is not set
-+# CONFIG_L3_ALGOBIT is not set
-+# CONFIG_L3_BIT_SA1100_GPIO is not set
-+# CONFIG_L3_SA1111 is not set
-+# CONFIG_BIT_SA1100_GPIO is not set
-+
-+#
-+# Mice
-+#
-+# CONFIG_BUSMOUSE is not set
-+# CONFIG_MOUSE is not set
-+
-+#
-+# Joysticks
-+#
-+# CONFIG_INPUT_GAMEPORT is not set
-+# CONFIG_QIC02_TAPE is not set
-+
-+#
-+# Watchdog Cards
-+#
-+# CONFIG_WATCHDOG is not set
-+# CONFIG_NVRAM is not set
-+# CONFIG_RTC is not set
-+# CONFIG_PXA_RTC is not set
-+# CONFIG_DTLK is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_APPLICOM is not set
-+
-+#
-+# Ftape, the floppy tape device driver
-+#
-+# CONFIG_FTAPE is not set
-+# CONFIG_AGP is not set
-+# CONFIG_DRM is not set
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+
-+#
-+# File systems
-+#
-+# CONFIG_QUOTA is not set
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+# CONFIG_REISERFS_FS is not set
-+# CONFIG_REISERFS_CHECK is not set
-+# CONFIG_REISERFS_PROC_INFO is not set
-+# CONFIG_ADFS_FS is not set
-+# CONFIG_ADFS_FS_RW is not set
-+# CONFIG_AFFS_FS is not set
-+# CONFIG_HFS_FS is not set
-+# CONFIG_BFS_FS is not set
-+# CONFIG_EXT3_FS is not set
-+# CONFIG_JBD is not set
-+# CONFIG_JBD_DEBUG is not set
-+# CONFIG_FAT_FS is not set
-+# CONFIG_MSDOS_FS is not set
-+# CONFIG_UMSDOS_FS is not set
-+# CONFIG_VFAT_FS is not set
-+# CONFIG_EFS_FS is not set
-+# CONFIG_JFFS_FS is not set
-+# CONFIG_JFFS2_FS is not set
-+# CONFIG_CRAMFS is not set
-+# CONFIG_TMPFS is not set
-+CONFIG_RAMFS=y
-+# CONFIG_ISO9660_FS is not set
-+# CONFIG_JOLIET is not set
-+# CONFIG_ZISOFS is not set
-+# CONFIG_MINIX_FS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_NTFS_FS is not set
-+# CONFIG_NTFS_RW is not set
-+# CONFIG_HPFS_FS is not set
-+CONFIG_PROC_FS=y
-+# CONFIG_DEVFS_FS is not set
-+# CONFIG_DEVFS_MOUNT is not set
-+# CONFIG_DEVFS_DEBUG is not set
-+CONFIG_DEVPTS_FS=y
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_QNX4FS_RW is not set
-+# CONFIG_ROMFS_FS is not set
-+# CONFIG_EXT2_FS is not set
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UDF_FS is not set
-+# CONFIG_UDF_RW is not set
-+# CONFIG_UFS_FS is not set
-+# CONFIG_UFS_FS_WRITE is not set
-+
-+#
-+# Network File Systems
-+#
-+# CONFIG_CODA_FS is not set
-+# CONFIG_INTERMEZZO_FS is not set
-+CONFIG_NFS_FS=y
-+# CONFIG_NFS_V3 is not set
-+CONFIG_ROOT_NFS=y
-+# CONFIG_NFSD is not set
-+# CONFIG_NFSD_V3 is not set
-+CONFIG_SUNRPC=y
-+CONFIG_LOCKD=y
-+# CONFIG_SMB_FS is not set
-+# CONFIG_NCP_FS is not set
-+# CONFIG_NCPFS_PACKET_SIGNING is not set
-+# CONFIG_NCPFS_IOCTL_LOCKING is not set
-+# CONFIG_NCPFS_STRONG is not set
-+# CONFIG_NCPFS_NFS_NS is not set
-+# CONFIG_NCPFS_OS2_NS is not set
-+# CONFIG_NCPFS_SMALLDOS is not set
-+# CONFIG_NCPFS_NLS is not set
-+# CONFIG_NCPFS_EXTRAS is not set
-+# CONFIG_ZISOFS_FS is not set
-+# CONFIG_ZLIB_FS_INFLATE is not set
-+
-+#
-+# Partition Types
-+#
-+CONFIG_PARTITION_ADVANCED=y
-+# CONFIG_ACORN_PARTITION is not set
-+# CONFIG_OSF_PARTITION is not set
-+# CONFIG_AMIGA_PARTITION is not set
-+# CONFIG_ATARI_PARTITION is not set
-+# CONFIG_MAC_PARTITION is not set
-+# CONFIG_MSDOS_PARTITION is not set
-+# CONFIG_LDM_PARTITION is not set
-+# CONFIG_SGI_PARTITION is not set
-+# CONFIG_ULTRIX_PARTITION is not set
-+# CONFIG_SUN_PARTITION is not set
-+# CONFIG_SMB_NLS is not set
-+# CONFIG_NLS is not set
-+
-+#
-+# Sound
-+#
-+# CONFIG_SOUND is not set
-+
-+#
-+# Multimedia Capabilities Port drivers
-+#
-+# CONFIG_MCP is not set
-+# CONFIG_MCP_SA1100 is not set
-+# CONFIG_MCP_UCB1200 is not set
-+# CONFIG_MCP_UCB1200_AUDIO is not set
-+# CONFIG_MCP_UCB1200_TS is not set
-+# CONFIG_MCP_UCB1400_TS is not set
-+
-+#
-+# USB support
-+#
-+# CONFIG_USB is not set
-+
-+#
-+# Bluetooth support
-+#
-+# CONFIG_BLUEZ is not set
-+
-+#
-+# Kernel hacking
-+#
-+CONFIG_FRAME_POINTER=y
-+CONFIG_DEBUG_USER=y
-+CONFIG_DEBUG_INFO=y
-+# CONFIG_NO_PGT_CACHE is not set
-+CONFIG_DEBUG_KERNEL=y
-+CONFIG_DEBUG_SLAB=y
-+CONFIG_MAGIC_SYSRQ=y
-+CONFIG_DEBUG_SPINLOCK=y
-+CONFIG_DEBUG_WAITQ=y
-+CONFIG_DEBUG_BUGVERBOSE=y
-+CONFIG_DEBUG_ERRORS=y
-+CONFIG_DEBUG_LL=y
-+# CONFIG_DEBUG_DC21285_PORT is not set
-+# CONFIG_DEBUG_CLPS711X_UART2 is not set
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/def-configs/innokom 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,699 @@
-+#
-+# Automatically generated by make menuconfig: don't edit
-+#
-+CONFIG_ARM=y
-+# CONFIG_EISA is not set
-+# CONFIG_SBUS is not set
-+# CONFIG_MCA is not set
-+CONFIG_UID16=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-+# CONFIG_GENERIC_BUST_SPINLOCK is not set
-+# CONFIG_GENERIC_ISA_DMA is not set
-+
-+#
-+# Code maturity level options
-+#
-+CONFIG_EXPERIMENTAL=y
-+# CONFIG_OBSOLETE is not set
-+
-+#
-+# Loadable module support
-+#
-+CONFIG_MODULES=y
-+# CONFIG_MODVERSIONS is not set
-+CONFIG_KMOD=y
-+
-+#
-+# System Type
-+#
-+# CONFIG_ARCH_ANAKIN is not set
-+# CONFIG_ARCH_ARCA5K is not set
-+# CONFIG_ARCH_CLPS7500 is not set
-+# CONFIG_ARCH_CLPS711X is not set
-+# CONFIG_ARCH_CO285 is not set
-+CONFIG_ARCH_PXA=y
-+# CONFIG_ARCH_EBSA110 is not set
-+# CONFIG_ARCH_CAMELOT is not set
-+# CONFIG_ARCH_FOOTBRIDGE is not set
-+# CONFIG_ARCH_INTEGRATOR is not set
-+# CONFIG_ARCH_OMAHA is not set
-+# CONFIG_ARCH_L7200 is not set
-+# CONFIG_ARCH_MX1ADS is not set
-+# CONFIG_ARCH_RPC is not set
-+# CONFIG_ARCH_RISCSTATION is not set
-+# CONFIG_ARCH_SA1100 is not set
-+# CONFIG_ARCH_SHARK is not set
-+# CONFIG_ARCH_AT91RM9200DK is not set
-+
-+#
-+# Archimedes/A5000 Implementations
-+#
-+# CONFIG_ARCH_ARC is not set
-+# CONFIG_ARCH_A5K is not set
-+
-+#
-+# Footbridge Implementations
-+#
-+# CONFIG_ARCH_CATS is not set
-+# CONFIG_ARCH_PERSONAL_SERVER is not set
-+# CONFIG_ARCH_EBSA285_ADDIN is not set
-+# CONFIG_ARCH_EBSA285_HOST is not set
-+# CONFIG_ARCH_NETWINDER is not set
-+
-+#
-+# SA11x0 Implementations
-+#
-+# CONFIG_SA1100_ACCELENT is not set
-+# CONFIG_SA1100_ASSABET is not set
-+# CONFIG_ASSABET_NEPONSET is not set
-+# CONFIG_SA1100_ADSBITSY is not set
-+# CONFIG_SA1100_BRUTUS is not set
-+# CONFIG_SA1100_CEP is not set
-+# CONFIG_SA1100_CERF is not set
-+# CONFIG_SA1100_H3100 is not set
-+# CONFIG_SA1100_H3600 is not set
-+# CONFIG_SA1100_H3800 is not set
-+# CONFIG_SA1100_H3XXX is not set
-+# CONFIG_SA1100_EXTENEX1 is not set
-+# CONFIG_SA1100_FLEXANET is not set
-+# CONFIG_SA1100_FREEBIRD is not set
-+# CONFIG_SA1100_FRODO is not set
-+# CONFIG_SA1100_GRAPHICSCLIENT is not set
-+# CONFIG_SA1100_GRAPHICSMASTER is not set
-+# CONFIG_SA1100_HACKKIT is not set
-+# CONFIG_SA1100_BADGE4 is not set
-+# CONFIG_SA1100_JORNADA720 is not set
-+# CONFIG_SA1100_HUW_WEBPANEL is not set
-+# CONFIG_SA1100_ITSY is not set
-+# CONFIG_SA1100_LART is not set
-+# CONFIG_SA1100_NANOENGINE is not set
-+# CONFIG_SA1100_OMNIMETER is not set
-+# CONFIG_SA1100_PANGOLIN is not set
-+# CONFIG_SA1100_PLEB is not set
-+# CONFIG_SA1100_PT_SYSTEM3 is not set
-+# CONFIG_SA1100_SHANNON is not set
-+# CONFIG_SA1100_SHERMAN is not set
-+# CONFIG_SA1100_SIMPAD is not set
-+# CONFIG_SA1100_SIMPUTER is not set
-+# CONFIG_SA1100_PFS168 is not set
-+# CONFIG_SA1100_VICTOR is not set
-+# CONFIG_SA1100_XP860 is not set
-+# CONFIG_SA1100_YOPY is not set
-+# CONFIG_SA1100_USB is not set
-+# CONFIG_SA1100_USB_NETLINK is not set
-+# CONFIG_SA1100_USB_CHAR is not set
-+# CONFIG_H3600_SLEEVE is not set
-+
-+#
-+# Intel PXA250/210 Board
-+#
-+# CONFIG_ARCH_PXA_IDP is not set
-+CONFIG_ARCH_INNOKOM=y
-+# CONFIG_ARCH_CSB226 is not set
-+# CONFIG_ARCH_LUBBOCK is not set
-+# CONFIG_ARCH_PXA_CERF is not set
-+# CONFIG_PXA_USB is not set
-+# CONFIG_PXA_USB_NETLINK is not set
-+# CONFIG_PXA_USB_CHAR is not set
-+
-+#
-+# CLPS711X/EP721X Implementations
-+#
-+# CONFIG_ARCH_AUTCPU12 is not set
-+# CONFIG_ARCH_CDB89712 is not set
-+# CONFIG_ARCH_CLEP7312 is not set
-+# CONFIG_ARCH_EDB7211 is not set
-+# CONFIG_ARCH_P720T is not set
-+# CONFIG_ARCH_FORTUNET is not set
-+# CONFIG_ARCH_EP7211 is not set
-+# CONFIG_ARCH_EP7212 is not set
-+# CONFIG_ARCH_ACORN is not set
-+# CONFIG_FOOTBRIDGE is not set
-+# CONFIG_FOOTBRIDGE_HOST is not set
-+# CONFIG_FOOTBRIDGE_ADDIN is not set
-+CONFIG_CPU_32=y
-+# CONFIG_CPU_26 is not set
-+# CONFIG_CPU_ARM610 is not set
-+# CONFIG_CPU_ARM710 is not set
-+# CONFIG_CPU_ARM720T is not set
-+# CONFIG_CPU_ARM920T is not set
-+# CONFIG_CPU_ARM922T is not set
-+# CONFIG_PLD is not set
-+# CONFIG_CPU_ARM926T is not set
-+# CONFIG_CPU_ARM1020 is not set
-+# CONFIG_CPU_ARM1026 is not set
-+# CONFIG_CPU_SA110 is not set
-+# CONFIG_CPU_SA1100 is not set
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_XSCALE=y
-+CONFIG_XSCALE_CACHE_ERRATA=y
-+# CONFIG_CPU_32v3 is not set
-+# CONFIG_CPU_32v4 is not set
-+# CONFIG_DISCONTIGMEM is not set
-+
-+#
-+# General setup
-+#
-+# CONFIG_PCI is not set
-+# CONFIG_ISA is not set
-+# CONFIG_ISA_DMA is not set
-+# CONFIG_ZBOOT_ROM is not set
-+CONFIG_ZBOOT_ROM_TEXT=0
-+CONFIG_ZBOOT_ROM_BSS=0
-+# CONFIG_CPU_FREQ is not set
-+# CONFIG_HOTPLUG is not set
-+# CONFIG_PCMCIA is not set
-+# CONFIG_MMC is not set
-+CONFIG_NET=y
-+CONFIG_SYSVIPC=y
-+# CONFIG_BSD_PROCESS_ACCT is not set
-+CONFIG_SYSCTL=y
-+# CONFIG_XIP_KERNEL is not set
-+CONFIG_FPE_NWFPE=y
-+# CONFIG_FPE_FASTFPE is not set
-+CONFIG_KCORE_ELF=y
-+# CONFIG_KCORE_AOUT is not set
-+# CONFIG_BINFMT_AOUT is not set
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_MISC is not set
-+# CONFIG_PM is not set
-+# CONFIG_ARTHUR is not set
-+CONFIG_CMDLINE="root=/dev/nfs mem=32M ip=dhcp console=ttyS0,19200"
-+CONFIG_ALIGNMENT_TRAP=y
-+CONFIG_ARM_HWTIMER=y
-+
-+#
-+# Parallel port support
-+#
-+# CONFIG_PARPORT is not set
-+
-+#
-+# Memory Technology Devices (MTD)
-+#
-+CONFIG_MTD=y
-+# CONFIG_MTD_DEBUG is not set
-+CONFIG_MTD_PARTITIONS=y
-+# CONFIG_MTD_CONCAT is not set
-+# CONFIG_MTD_REDBOOT_PARTS is not set
-+CONFIG_MTD_CMDLINE_PARTS=y
-+# CONFIG_MTD_AFS_PARTS is not set
-+CONFIG_MTD_CHAR=y
-+CONFIG_MTD_BLOCK=y
-+# CONFIG_FTL is not set
-+# CONFIG_NFTL is not set
-+
-+#
-+# RAM/ROM/Flash chip drivers
-+#
-+CONFIG_MTD_CFI=y
-+# CONFIG_MTD_JEDECPROBE is not set
-+CONFIG_MTD_GEN_PROBE=y
-+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-+CONFIG_MTD_CFI_INTELEXT=y
-+CONFIG_MTD_CFI_AMDSTD=y
-+# CONFIG_MTD_CFI_STAA is not set
-+# CONFIG_MTD_RAM is not set
-+# CONFIG_MTD_ROM is not set
-+# CONFIG_MTD_ABSENT is not set
-+# CONFIG_MTD_OBSOLETE_CHIPS is not set
-+# CONFIG_MTD_AMDSTD is not set
-+# CONFIG_MTD_SHARP is not set
-+# CONFIG_MTD_JEDEC is not set
-+
-+#
-+# Mapping drivers for chip access
-+#
-+# CONFIG_MTD_PHYSMAP is not set
-+# CONFIG_MTD_NORA is not set
-+# CONFIG_MTD_ARM_INTEGRATOR is not set
-+# CONFIG_MTD_CDB89712 is not set
-+# CONFIG_MTD_SA1100 is not set
-+# CONFIG_MTD_DC21285 is not set
-+# CONFIG_MTD_IQ80310 is not set
-+# CONFIG_MTD_LUBBOCK is not set
-+# CONFIG_MTD_EPXA10DB is not set
-+# CONFIG_MTD_FORTUNET is not set
-+CONFIG_MTD_INNOKOM=y
-+CONFIG_MTD_INNOKOM_16MB=y
-+# CONFIG_MTD_INNOKOM_64MB is not set
-+# CONFIG_MTD_AUTCPU12 is not set
-+# CONFIG_MTD_EDB7312 is not set
-+# CONFIG_MTD_IMPA7 is not set
-+# CONFIG_MTD_CEIVA is not set
-+# CONFIG_MTD_PCI is not set
-+# CONFIG_MTD_PCMCIA is not set
-+
-+#
-+# Self-contained MTD device drivers
-+#
-+# CONFIG_MTD_PMC551 is not set
-+# CONFIG_MTD_SLRAM is not set
-+# CONFIG_MTD_MTDRAM is not set
-+# CONFIG_MTD_BLKMTD is not set
-+# CONFIG_MTD_DOC1000 is not set
-+# CONFIG_MTD_DOC2000 is not set
-+# CONFIG_MTD_DOC2001 is not set
-+# CONFIG_MTD_DOCPROBE is not set
-+
-+#
-+# NAND Flash Device Drivers
-+#
-+# CONFIG_MTD_NAND is not set
-+
-+#
-+# Plug and Play configuration
-+#
-+# CONFIG_PNP is not set
-+# CONFIG_ISAPNP is not set
-+
-+#
-+# Block devices
-+#
-+# CONFIG_BLK_DEV_FD is not set
-+# CONFIG_BLK_DEV_XD is not set
-+# CONFIG_PARIDE is not set
-+# CONFIG_BLK_CPQ_DA is not set
-+# CONFIG_BLK_CPQ_CISS_DA is not set
-+# CONFIG_CISS_SCSI_TAPE is not set
-+# CONFIG_BLK_DEV_DAC960 is not set
-+# CONFIG_BLK_DEV_UMEM is not set
-+# CONFIG_BLK_DEV_LOOP is not set
-+# CONFIG_BLK_DEV_NBD is not set
-+# CONFIG_BLK_DEV_RAM is not set
-+# CONFIG_BLK_DEV_INITRD is not set
-+
-+#
-+# Multi-device support (RAID and LVM)
-+#
-+# CONFIG_MD is not set
-+# CONFIG_BLK_DEV_MD is not set
-+# CONFIG_MD_LINEAR is not set
-+# CONFIG_MD_RAID0 is not set
-+# CONFIG_MD_RAID1 is not set
-+# CONFIG_MD_RAID5 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_BLK_DEV_LVM is not set
-+
-+#
-+# Networking options
-+#
-+# CONFIG_PACKET is not set
-+# CONFIG_NETLINK_DEV is not set
-+# CONFIG_NETFILTER is not set
-+# CONFIG_FILTER is not set
-+CONFIG_UNIX=y
-+CONFIG_INET=y
-+# CONFIG_IP_MULTICAST is not set
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+CONFIG_IP_PNP=y
-+CONFIG_IP_PNP_DHCP=y
-+# CONFIG_IP_PNP_BOOTP is not set
-+# CONFIG_IP_PNP_RARP is not set
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_ARPD is not set
-+# CONFIG_INET_ECN is not set
-+# CONFIG_SYN_COOKIES is not set
-+# CONFIG_IPV6 is not set
-+# CONFIG_KHTTPD is not set
-+# CONFIG_ATM is not set
-+# CONFIG_VLAN_8021Q is not set
-+# CONFIG_IPX is not set
-+# CONFIG_ATALK is not set
-+
-+#
-+# Appletalk devices
-+#
-+# CONFIG_DEV_APPLETALK is not set
-+# CONFIG_DECNET is not set
-+# CONFIG_BRIDGE is not set
-+# CONFIG_X25 is not set
-+# CONFIG_LAPB is not set
-+# CONFIG_LLC is not set
-+# CONFIG_NET_DIVERT is not set
-+# CONFIG_ECONET is not set
-+# CONFIG_WAN_ROUTER is not set
-+# CONFIG_NET_FASTROUTE is not set
-+# CONFIG_NET_HW_FLOWCONTROL is not set
-+
-+#
-+# QoS and/or fair queueing
-+#
-+# CONFIG_NET_SCHED is not set
-+
-+#
-+# Network testing
-+#
-+# CONFIG_NET_PKTGEN is not set
-+
-+#
-+# Network device support
-+#
-+CONFIG_NETDEVICES=y
-+
-+#
-+# ARCnet devices
-+#
-+# CONFIG_ARCNET is not set
-+# CONFIG_DUMMY is not set
-+# CONFIG_BONDING is not set
-+# CONFIG_EQUALIZER is not set
-+# CONFIG_TUN is not set
-+# CONFIG_ETHERTAP is not set
-+
-+#
-+# Ethernet (10 or 100Mbit)
-+#
-+CONFIG_NET_ETHERNET=y
-+# CONFIG_ARM_AM79C961A is not set
-+# CONFIG_ARM_CIRRUS is not set
-+# CONFIG_SUNLANCE is not set
-+# CONFIG_SUNBMAC is not set
-+# CONFIG_SUNQE is not set
-+# CONFIG_SUNGEM is not set
-+# CONFIG_NET_VENDOR_3COM is not set
-+# CONFIG_LANCE is not set
-+CONFIG_NET_VENDOR_SMC=y
-+# CONFIG_WD80x3 is not set
-+# CONFIG_ULTRAMCA is not set
-+# CONFIG_ULTRA is not set
-+# CONFIG_ULTRA32 is not set
-+# CONFIG_SMC9194 is not set
-+CONFIG_SMC91X=y
-+# CONFIG_NET_VENDOR_RACAL is not set
-+# CONFIG_NET_ISA is not set
-+# CONFIG_NET_PCI is not set
-+# CONFIG_NET_POCKET is not set
-+
-+#
-+# Ethernet (1000 Mbit)
-+#
-+# CONFIG_ACENIC is not set
-+# CONFIG_DL2K is not set
-+# CONFIG_MYRI_SBUS is not set
-+# CONFIG_NS83820 is not set
-+# CONFIG_HAMACHI is not set
-+# CONFIG_YELLOWFIN is not set
-+# CONFIG_SK98LIN is not set
-+# CONFIG_TIGON3 is not set
-+# CONFIG_FDDI is not set
-+# CONFIG_HIPPI is not set
-+# CONFIG_PLIP is not set
-+# CONFIG_PPP is not set
-+# CONFIG_SLIP is not set
-+
-+#
-+# Wireless LAN (non-hamradio)
-+#
-+# CONFIG_NET_RADIO is not set
-+
-+#
-+# Token Ring devices
-+#
-+# CONFIG_TR is not set
-+# CONFIG_NET_FC is not set
-+# CONFIG_RCPCI is not set
-+# CONFIG_SHAPER is not set
-+
-+#
-+# Wan interfaces
-+#
-+# CONFIG_WAN is not set
-+
-+#
-+# Amateur Radio support
-+#
-+# CONFIG_HAMRADIO is not set
-+
-+#
-+# IrDA (infrared) support
-+#
-+# CONFIG_IRDA is not set
-+
-+#
-+# ATA/ATAPI/MFM/RLL support
-+#
-+# CONFIG_IDE is not set
-+# CONFIG_BLK_DEV_IDE_MODES is not set
-+# CONFIG_BLK_DEV_HD is not set
-+
-+#
-+# SCSI support
-+#
-+# CONFIG_SCSI is not set
-+
-+#
-+# I2O device support
-+#
-+# CONFIG_I2O is not set
-+# CONFIG_I2O_BLOCK is not set
-+# CONFIG_I2O_LAN is not set
-+# CONFIG_I2O_SCSI is not set
-+# CONFIG_I2O_PROC is not set
-+
-+#
-+# ISDN subsystem
-+#
-+# CONFIG_ISDN is not set
-+
-+#
-+# Input core support
-+#
-+# CONFIG_INPUT is not set
-+# CONFIG_INPUT_KEYBDEV is not set
-+# CONFIG_INPUT_MOUSEDEV is not set
-+# CONFIG_INPUT_JOYDEV is not set
-+# CONFIG_INPUT_EVDEV is not set
-+
-+#
-+# Character devices
-+#
-+# CONFIG_VT is not set
-+CONFIG_SERIAL=y
-+CONFIG_SERIAL_CONSOLE=y
-+# CONFIG_SERIAL_EXTENDED is not set
-+# CONFIG_SERIAL_NONSTANDARD is not set
-+
-+#
-+# Serial drivers
-+#
-+# CONFIG_SERIAL_ANAKIN is not set
-+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-+# CONFIG_SERIAL_AMBA is not set
-+# CONFIG_SERIAL_AMBA_CONSOLE is not set
-+# CONFIG_SERIAL_CLPS711X is not set
-+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-+# CONFIG_SERIAL_21285 is not set
-+# CONFIG_SERIAL_21285_OLD is not set
-+# CONFIG_SERIAL_21285_CONSOLE is not set
-+# CONFIG_SERIAL_UART00 is not set
-+# CONFIG_SERIAL_UART00_CONSOLE is not set
-+# CONFIG_SERIAL_SA1100 is not set
-+# CONFIG_SERIAL_SA1100_CONSOLE is not set
-+# CONFIG_SERIAL_OMAHA is not set
-+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
-+# CONFIG_SERIAL_8250 is not set
-+# CONFIG_SERIAL_8250_CONSOLE is not set
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+# CONFIG_SERIAL_8250_MANY_PORTS is not set
-+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-+# CONFIG_SERIAL_8250_MULTIPORT is not set
-+# CONFIG_SERIAL_8250_HUB6 is not set
-+CONFIG_UNIX98_PTYS=y
-+CONFIG_UNIX98_PTY_COUNT=256
-+
-+#
-+# I2C support
-+#
-+CONFIG_I2C=y
-+# CONFIG_I2C_ALGOBIT is not set
-+# CONFIG_I2C_ALGOPCF is not set
-+CONFIG_I2C_PXA_ALGO=y
-+CONFIG_I2C_PXA_ADAP=y
-+CONFIG_I2C_CHARDEV=y
-+CONFIG_I2C_PROC=y
-+# CONFIG_I2C_DS1307 is not set
-+
-+#
-+# L3 serial bus support
-+#
-+# CONFIG_L3 is not set
-+# CONFIG_L3_ALGOBIT is not set
-+# CONFIG_L3_BIT_SA1100_GPIO is not set
-+# CONFIG_L3_SA1111 is not set
-+# CONFIG_BIT_SA1100_GPIO is not set
-+
-+#
-+# Mice
-+#
-+# CONFIG_BUSMOUSE is not set
-+# CONFIG_MOUSE is not set
-+
-+#
-+# Joysticks
-+#
-+# CONFIG_INPUT_GAMEPORT is not set
-+# CONFIG_QIC02_TAPE is not set
-+
-+#
-+# Watchdog Cards
-+#
-+# CONFIG_WATCHDOG is not set
-+# CONFIG_NVRAM is not set
-+# CONFIG_RTC is not set
-+# CONFIG_PXA_RTC is not set
-+# CONFIG_DTLK is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_APPLICOM is not set
-+
-+#
-+# Ftape, the floppy tape device driver
-+#
-+# CONFIG_FTAPE is not set
-+# CONFIG_AGP is not set
-+# CONFIG_DRM is not set
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+
-+#
-+# File systems
-+#
-+# CONFIG_QUOTA is not set
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+# CONFIG_REISERFS_FS is not set
-+# CONFIG_REISERFS_CHECK is not set
-+# CONFIG_REISERFS_PROC_INFO is not set
-+# CONFIG_ADFS_FS is not set
-+# CONFIG_ADFS_FS_RW is not set
-+# CONFIG_AFFS_FS is not set
-+# CONFIG_HFS_FS is not set
-+# CONFIG_BFS_FS is not set
-+# CONFIG_EXT3_FS is not set
-+# CONFIG_JBD is not set
-+# CONFIG_JBD_DEBUG is not set
-+# CONFIG_FAT_FS is not set
-+# CONFIG_MSDOS_FS is not set
-+# CONFIG_UMSDOS_FS is not set
-+# CONFIG_VFAT_FS is not set
-+# CONFIG_EFS_FS is not set
-+# CONFIG_JFFS_FS is not set
-+CONFIG_JFFS2_FS=y
-+CONFIG_JFFS2_FS_DEBUG=0
-+# CONFIG_JFFS2_FS_NAND is not set
-+# CONFIG_CRAMFS is not set
-+# CONFIG_TMPFS is not set
-+CONFIG_RAMFS=y
-+# CONFIG_ISO9660_FS is not set
-+# CONFIG_JOLIET is not set
-+# CONFIG_ZISOFS is not set
-+# CONFIG_MINIX_FS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_NTFS_FS is not set
-+# CONFIG_NTFS_RW is not set
-+# CONFIG_HPFS_FS is not set
-+CONFIG_PROC_FS=y
-+CONFIG_DEVFS_FS=y
-+CONFIG_DEVFS_MOUNT=y
-+# CONFIG_DEVFS_DEBUG is not set
-+CONFIG_DEVPTS_FS=y
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_QNX4FS_RW is not set
-+# CONFIG_ROMFS_FS is not set
-+# CONFIG_EXT2_FS is not set
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UDF_FS is not set
-+# CONFIG_UDF_RW is not set
-+# CONFIG_UFS_FS is not set
-+# CONFIG_UFS_FS_WRITE is not set
-+
-+#
-+# Network File Systems
-+#
-+# CONFIG_CODA_FS is not set
-+# CONFIG_INTERMEZZO_FS is not set
-+CONFIG_NFS_FS=y
-+CONFIG_NFS_V3=y
-+CONFIG_ROOT_NFS=y
-+# CONFIG_NFSD is not set
-+# CONFIG_NFSD_V3 is not set
-+CONFIG_SUNRPC=y
-+CONFIG_LOCKD=y
-+CONFIG_LOCKD_V4=y
-+# CONFIG_SMB_FS is not set
-+# CONFIG_NCP_FS is not set
-+# CONFIG_NCPFS_PACKET_SIGNING is not set
-+# CONFIG_NCPFS_IOCTL_LOCKING is not set
-+# CONFIG_NCPFS_STRONG is not set
-+# CONFIG_NCPFS_NFS_NS is not set
-+# CONFIG_NCPFS_OS2_NS is not set
-+# CONFIG_NCPFS_SMALLDOS is not set
-+# CONFIG_NCPFS_NLS is not set
-+# CONFIG_NCPFS_EXTRAS is not set
-+# CONFIG_ZISOFS_FS is not set
-+# CONFIG_ZLIB_FS_INFLATE is not set
-+
-+#
-+# Partition Types
-+#
-+CONFIG_PARTITION_ADVANCED=y
-+# CONFIG_ACORN_PARTITION is not set
-+# CONFIG_OSF_PARTITION is not set
-+# CONFIG_AMIGA_PARTITION is not set
-+# CONFIG_ATARI_PARTITION is not set
-+# CONFIG_MAC_PARTITION is not set
-+# CONFIG_MSDOS_PARTITION is not set
-+# CONFIG_LDM_PARTITION is not set
-+# CONFIG_SGI_PARTITION is not set
-+# CONFIG_ULTRIX_PARTITION is not set
-+# CONFIG_SUN_PARTITION is not set
-+# CONFIG_SMB_NLS is not set
-+# CONFIG_NLS is not set
-+
-+#
-+# Sound
-+#
-+# CONFIG_SOUND is not set
-+
-+#
-+# Multimedia Capabilities Port drivers
-+#
-+# CONFIG_MCP is not set
-+# CONFIG_MCP_SA1100 is not set
-+# CONFIG_MCP_UCB1200 is not set
-+# CONFIG_MCP_UCB1200_AUDIO is not set
-+# CONFIG_MCP_UCB1200_TS is not set
-+# CONFIG_MCP_UCB1400_TS is not set
-+
-+#
-+# USB support
-+#
-+# CONFIG_USB is not set
-+
-+#
-+# Bluetooth support
-+#
-+# CONFIG_BLUEZ is not set
-+
-+#
-+# Kernel hacking
-+#
-+CONFIG_FRAME_POINTER=y
-+CONFIG_DEBUG_USER=y
-+CONFIG_DEBUG_INFO=y
-+# CONFIG_NO_PGT_CACHE is not set
-+CONFIG_DEBUG_KERNEL=y
-+CONFIG_DEBUG_SLAB=y
-+CONFIG_MAGIC_SYSRQ=y
-+CONFIG_DEBUG_SPINLOCK=y
-+CONFIG_DEBUG_WAITQ=y
-+CONFIG_DEBUG_BUGVERBOSE=y
-+CONFIG_DEBUG_ERRORS=y
-+CONFIG_DEBUG_LL=y
-+# CONFIG_DEBUG_DC21285_PORT is not set
-+# CONFIG_DEBUG_CLPS711X_UART2 is not set
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/def-configs/lubbock 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,971 @@
-+#
-+# Automatically generated make config: don't edit
-+#
-+CONFIG_ARM=y
-+# CONFIG_EISA is not set
-+# CONFIG_SBUS is not set
-+# CONFIG_MCA is not set
-+CONFIG_UID16=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-+# CONFIG_GENERIC_BUST_SPINLOCK is not set
-+# CONFIG_GENERIC_ISA_DMA is not set
-+
-+#
-+# Code maturity level options
-+#
-+CONFIG_EXPERIMENTAL=y
-+# CONFIG_OBSOLETE is not set
-+
-+#
-+# Loadable module support
-+#
-+CONFIG_MODULES=y
-+# CONFIG_MODVERSIONS is not set
-+# CONFIG_KMOD is not set
-+
-+#
-+# System Type
-+#
-+# CONFIG_ARCH_ANAKIN is not set
-+# CONFIG_ARCH_ARCA5K is not set
-+# CONFIG_ARCH_CLPS7500 is not set
-+# CONFIG_ARCH_CLPS711X is not set
-+# CONFIG_ARCH_CO285 is not set
-+CONFIG_ARCH_PXA=y
-+# CONFIG_ARCH_EBSA110 is not set
-+# CONFIG_ARCH_CAMELOT is not set
-+# CONFIG_ARCH_FOOTBRIDGE is not set
-+# CONFIG_ARCH_INTEGRATOR is not set
-+# CONFIG_ARCH_OMAHA is not set
-+# CONFIG_ARCH_L7200 is not set
-+# CONFIG_ARCH_MX1ADS is not set
-+# CONFIG_ARCH_RPC is not set
-+# CONFIG_ARCH_RISCSTATION is not set
-+# CONFIG_ARCH_SA1100 is not set
-+# CONFIG_ARCH_SHARK is not set
-+# CONFIG_ARCH_AT91RM9200 is not set
-+
-+#
-+# Archimedes/A5000 Implementations
-+#
-+
-+#
-+# Archimedes/A5000 Implementations (select only ONE)
-+#
-+# CONFIG_ARCH_ARC is not set
-+# CONFIG_ARCH_A5K is not set
-+
-+#
-+# Footbridge Implementations
-+#
-+# CONFIG_ARCH_CATS is not set
-+# CONFIG_ARCH_PERSONAL_SERVER is not set
-+# CONFIG_ARCH_EBSA285_ADDIN is not set
-+# CONFIG_ARCH_EBSA285_HOST is not set
-+# CONFIG_ARCH_NETWINDER is not set
-+
-+#
-+# SA11x0 Implementations
-+#
-+# CONFIG_SA1100_ACCELENT is not set
-+# CONFIG_SA1100_ASSABET is not set
-+# CONFIG_ASSABET_NEPONSET is not set
-+# CONFIG_SA1100_ADSAGC is not set
-+# CONFIG_SA1100_ADSBITSY is not set
-+# CONFIG_SA1100_ADSBITSYPLUS is not set
-+# CONFIG_SA1100_BRUTUS is not set
-+# CONFIG_SA1100_CEP is not set
-+# CONFIG_SA1100_CERF is not set
-+# CONFIG_SA1100_H3100 is not set
-+# CONFIG_SA1100_H3600 is not set
-+# CONFIG_SA1100_H3800 is not set
-+# CONFIG_SA1100_H3XXX is not set
-+# CONFIG_H3600_SLEEVE is not set
-+# CONFIG_SA1100_EXTENEX1 is not set
-+# CONFIG_SA1100_FLEXANET is not set
-+# CONFIG_SA1100_FREEBIRD is not set
-+# CONFIG_SA1100_FRODO is not set
-+# CONFIG_SA1100_GRAPHICSCLIENT is not set
-+# CONFIG_SA1100_GRAPHICSMASTER is not set
-+# CONFIG_SA1100_HACKKIT is not set
-+# CONFIG_SA1100_BADGE4 is not set
-+# CONFIG_SA1100_JORNADA720 is not set
-+# CONFIG_SA1100_HUW_WEBPANEL is not set
-+# CONFIG_SA1100_ITSY is not set
-+# CONFIG_SA1100_LART is not set
-+# CONFIG_SA1100_NANOENGINE is not set
-+# CONFIG_SA1100_OMNIMETER is not set
-+# CONFIG_SA1100_PANGOLIN is not set
-+# CONFIG_SA1100_PLEB is not set
-+# CONFIG_SA1100_PT_SYSTEM3 is not set
-+# CONFIG_SA1100_SHANNON is not set
-+# CONFIG_SA1100_SHERMAN is not set
-+# CONFIG_SA1100_SIMPAD is not set
-+# CONFIG_SA1100_SIMPUTER is not set
-+# CONFIG_SA1100_PFS168 is not set
-+# CONFIG_SA1100_VICTOR is not set
-+# CONFIG_SA1100_XP860 is not set
-+# CONFIG_SA1100_YOPY is not set
-+# CONFIG_SA1100_USB is not set
-+# CONFIG_SA1100_USB_NETLINK is not set
-+# CONFIG_SA1100_USB_CHAR is not set
-+# CONFIG_SA1100_SSP is not set
-+
-+#
-+# AT91RM9200 Implementations
-+#
-+# CONFIG_ARCH_AT91RM9200DK is not set
-+
-+#
-+# Intel PXA250/210 Implementations
-+#
-+CONFIG_ARCH_LUBBOCK=y
-+# CONFIG_ARCH_PXA_IDP is not set
-+# CONFIG_ARCH_PXA_CERF is not set
-+# CONFIG_ARCH_TRIZEPS2 is not set
-+CONFIG_SA1111=y
-+# CONFIG_PXA_USB is not set
-+# CONFIG_PXA_USB_NETLINK is not set
-+# CONFIG_PXA_USB_CHAR is not set
-+
-+#
-+# CLPS711X/EP721X Implementations
-+#
-+# CONFIG_ARCH_AUTCPU12 is not set
-+# CONFIG_ARCH_CDB89712 is not set
-+# CONFIG_ARCH_CLEP7312 is not set
-+# CONFIG_ARCH_EDB7211 is not set
-+# CONFIG_ARCH_FORTUNET is not set
-+# CONFIG_ARCH_GUIDEA07 is not set
-+# CONFIG_ARCH_P720T is not set
-+# CONFIG_ARCH_EP7211 is not set
-+# CONFIG_ARCH_EP7212 is not set
-+# CONFIG_ARCH_ACORN is not set
-+# CONFIG_FOOTBRIDGE is not set
-+# CONFIG_FOOTBRIDGE_HOST is not set
-+# CONFIG_FOOTBRIDGE_ADDIN is not set
-+
-+#
-+# Processor Type
-+#
-+CONFIG_CPU_32=y
-+# CONFIG_CPU_26 is not set
-+# CONFIG_CPU_ARM610 is not set
-+# CONFIG_CPU_ARM710 is not set
-+# CONFIG_CPU_ARM720T is not set
-+# CONFIG_CPU_ARM920T is not set
-+# CONFIG_CPU_ARM922T is not set
-+# CONFIG_PLD is not set
-+# CONFIG_CPU_ARM926T is not set
-+# CONFIG_CPU_ARM1020 is not set
-+# CONFIG_CPU_ARM1026 is not set
-+# CONFIG_CPU_SA110 is not set
-+# CONFIG_CPU_SA1100 is not set
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_XSCALE=y
-+# CONFIG_XSCALE_CACHE_ERRATA is not set
-+# CONFIG_CPU_32v3 is not set
-+# CONFIG_CPU_32v4 is not set
-+
-+#
-+# Processor Features
-+#
-+# CONFIG_DISCONTIGMEM is not set
-+
-+#
-+# General setup
-+#
-+# CONFIG_PCI is not set
-+# CONFIG_ISA is not set
-+# CONFIG_ISA_DMA is not set
-+# CONFIG_ZBOOT_ROM is not set
-+CONFIG_ZBOOT_ROM_TEXT=0
-+CONFIG_ZBOOT_ROM_BSS=0
-+CONFIG_CPU_FREQ=y
-+CONFIG_HOTPLUG=y
-+
-+#
-+# PCMCIA/CardBus support
-+#
-+CONFIG_PCMCIA=y
-+# CONFIG_I82092 is not set
-+# CONFIG_I82365 is not set
-+# CONFIG_TCIC is not set
-+# CONFIG_PCMCIA_CLPS6700 is not set
-+# CONFIG_PCMCIA_SA1100 is not set
-+CONFIG_PCMCIA_PXA=y
-+
-+#
-+# MMC device drivers
-+#
-+CONFIG_MMC=m
-+CONFIG_MMC_PXA=m
-+CONFIG_MMC_BLOCK=m
-+CONFIG_MMC_PARTITIONS=y
-+CONFIG_NET=y
-+CONFIG_SYSVIPC=y
-+# CONFIG_BSD_PROCESS_ACCT is not set
-+CONFIG_SYSCTL=y
-+# CONFIG_XIP_KERNEL is not set
-+
-+#
-+# At least one math emulation must be selected
-+#
-+CONFIG_FPE_NWFPE=y
-+# CONFIG_FPE_NWFPE_XP is not set
-+# CONFIG_FPE_FASTFPE is not set
-+CONFIG_KCORE_ELF=y
-+# CONFIG_KCORE_AOUT is not set
-+# CONFIG_BINFMT_AOUT is not set
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_MISC is not set
-+CONFIG_PM=y
-+# CONFIG_ARTHUR is not set
-+CONFIG_CMDLINE="root=/dev/nfs ip=bootp console=ttyS0,115200 mem=32M"
-+CONFIG_LEDS=y
-+CONFIG_LEDS_TIMER=y
-+CONFIG_LEDS_CPU=y
-+CONFIG_ALIGNMENT_TRAP=y
-+
-+#
-+# Parallel port support
-+#
-+# CONFIG_PARPORT is not set
-+
-+#
-+# Memory Technology Devices (MTD)
-+#
-+CONFIG_MTD=y
-+# CONFIG_MTD_DEBUG is not set
-+CONFIG_MTD_PARTITIONS=y
-+# CONFIG_MTD_CONCAT is not set
-+CONFIG_MTD_REDBOOT_PARTS=y
-+# CONFIG_MTD_CMDLINE_PARTS is not set
-+# CONFIG_MTD_AFS_PARTS is not set
-+
-+#
-+# User Modules And Translation Layers
-+#
-+CONFIG_MTD_CHAR=y
-+CONFIG_MTD_BLOCK=y
-+# CONFIG_FTL is not set
-+# CONFIG_NFTL is not set
-+
-+#
-+# RAM/ROM/Flash chip drivers
-+#
-+CONFIG_MTD_CFI=y
-+# CONFIG_MTD_JEDECPROBE is not set
-+CONFIG_MTD_GEN_PROBE=y
-+CONFIG_MTD_CFI_ADV_OPTIONS=y
-+CONFIG_MTD_CFI_NOSWAP=y
-+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-+CONFIG_MTD_CFI_GEOMETRY=y
-+# CONFIG_MTD_CFI_B1 is not set
-+CONFIG_MTD_CFI_B2=y
-+CONFIG_MTD_CFI_B4=y
-+# CONFIG_MTD_CFI_B8 is not set
-+CONFIG_MTD_CFI_I1=y
-+CONFIG_MTD_CFI_I2=y
-+# CONFIG_MTD_CFI_I4 is not set
-+# CONFIG_MTD_CFI_I8 is not set
-+CONFIG_MTD_CFI_INTELEXT=y
-+# CONFIG_MTD_CFI_AMDSTD is not set
-+# CONFIG_MTD_CFI_STAA is not set
-+# CONFIG_MTD_RAM is not set
-+# CONFIG_MTD_ROM is not set
-+# CONFIG_MTD_ABSENT is not set
-+# CONFIG_MTD_OBSOLETE_CHIPS is not set
-+# CONFIG_MTD_AMDSTD is not set
-+# CONFIG_MTD_SHARP is not set
-+# CONFIG_MTD_JEDEC is not set
-+
-+#
-+# Mapping drivers for chip access
-+#
-+# CONFIG_MTD_PHYSMAP is not set
-+CONFIG_MTD_LUBBOCK=y
-+# CONFIG_MTD_NORA is not set
-+# CONFIG_MTD_ARM_INTEGRATOR is not set
-+# CONFIG_MTD_CDB89712 is not set
-+# CONFIG_MTD_SA1100 is not set
-+# CONFIG_MTD_DC21285 is not set
-+# CONFIG_MTD_IQ80310 is not set
-+# CONFIG_MTD_FORTUNET is not set
-+# CONFIG_MTD_EPXA is not set
-+# CONFIG_MTD_AUTCPU12 is not set
-+# CONFIG_MTD_EDB7312 is not set
-+# CONFIG_MTD_IMPA7 is not set
-+# CONFIG_MTD_CEIVA is not set
-+# CONFIG_MTD_PCI is not set
-+# CONFIG_MTD_PCMCIA is not set
-+
-+#
-+# Self-contained MTD device drivers
-+#
-+# CONFIG_MTD_PMC551 is not set
-+# CONFIG_MTD_SLRAM is not set
-+# CONFIG_MTD_MTDRAM is not set
-+# CONFIG_MTD_BLKMTD is not set
-+
-+#
-+# Disk-On-Chip Device Drivers
-+#
-+# CONFIG_MTD_DOC1000 is not set
-+# CONFIG_MTD_DOC2000 is not set
-+# CONFIG_MTD_DOC2001 is not set
-+# CONFIG_MTD_DOCPROBE is not set
-+
-+#
-+# NAND Flash Device Drivers
-+#
-+# CONFIG_MTD_NAND is not set
-+
-+#
-+# Plug and Play configuration
-+#
-+# CONFIG_PNP is not set
-+# CONFIG_ISAPNP is not set
-+
-+#
-+# Block devices
-+#
-+# CONFIG_BLK_DEV_FD is not set
-+# CONFIG_BLK_DEV_XD is not set
-+# CONFIG_PARIDE is not set
-+# CONFIG_BLK_CPQ_DA is not set
-+# CONFIG_BLK_CPQ_CISS_DA is not set
-+# CONFIG_CISS_SCSI_TAPE is not set
-+# CONFIG_BLK_DEV_DAC960 is not set
-+# CONFIG_BLK_DEV_UMEM is not set
-+# CONFIG_BLK_DEV_LOOP is not set
-+# CONFIG_BLK_DEV_NBD is not set
-+# CONFIG_BLK_DEV_RAM is not set
-+# CONFIG_BLK_DEV_INITRD is not set
-+# CONFIG_BLK_STATS is not set
-+
-+#
-+# Multi-device support (RAID and LVM)
-+#
-+# CONFIG_MD is not set
-+# CONFIG_BLK_DEV_MD is not set
-+# CONFIG_MD_LINEAR is not set
-+# CONFIG_MD_RAID0 is not set
-+# CONFIG_MD_RAID1 is not set
-+# CONFIG_MD_RAID5 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_BLK_DEV_LVM is not set
-+
-+#
-+# Networking options
-+#
-+# CONFIG_PACKET is not set
-+# CONFIG_NETLINK_DEV is not set
-+# CONFIG_NETFILTER is not set
-+# CONFIG_FILTER is not set
-+CONFIG_UNIX=y
-+CONFIG_INET=y
-+# CONFIG_IP_MULTICAST is not set
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+CONFIG_IP_PNP=y
-+# CONFIG_IP_PNP_DHCP is not set
-+CONFIG_IP_PNP_BOOTP=y
-+# CONFIG_IP_PNP_RARP is not set
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_ARPD is not set
-+# CONFIG_INET_ECN is not set
-+# CONFIG_SYN_COOKIES is not set
-+# CONFIG_IPV6 is not set
-+# CONFIG_KHTTPD is not set
-+# CONFIG_ATM is not set
-+# CONFIG_VLAN_8021Q is not set
-+
-+#
-+#
-+#
-+# CONFIG_IPX is not set
-+# CONFIG_ATALK is not set
-+
-+#
-+# Appletalk devices
-+#
-+# CONFIG_DEV_APPLETALK is not set
-+# CONFIG_DECNET is not set
-+# CONFIG_BRIDGE is not set
-+# CONFIG_X25 is not set
-+# CONFIG_LAPB is not set
-+# CONFIG_LLC is not set
-+# CONFIG_NET_DIVERT is not set
-+# CONFIG_ECONET is not set
-+# CONFIG_WAN_ROUTER is not set
-+# CONFIG_NET_FASTROUTE is not set
-+# CONFIG_NET_HW_FLOWCONTROL is not set
-+
-+#
-+# QoS and/or fair queueing
-+#
-+# CONFIG_NET_SCHED is not set
-+
-+#
-+# Network testing
-+#
-+# CONFIG_NET_PKTGEN is not set
-+
-+#
-+# Network device support
-+#
-+CONFIG_NETDEVICES=y
-+
-+#
-+# ARCnet devices
-+#
-+# CONFIG_ARCNET is not set
-+# CONFIG_DUMMY is not set
-+# CONFIG_BONDING is not set
-+# CONFIG_EQUALIZER is not set
-+# CONFIG_TUN is not set
-+# CONFIG_ETHERTAP is not set
-+
-+#
-+# Ethernet (10 or 100Mbit)
-+#
-+CONFIG_NET_ETHERNET=y
-+# CONFIG_ARM_AM79C961A is not set
-+# CONFIG_ARM_CIRRUS is not set
-+# CONFIG_SUNLANCE is not set
-+# CONFIG_SUNBMAC is not set
-+# CONFIG_SUNQE is not set
-+# CONFIG_SUNGEM is not set
-+# CONFIG_NET_VENDOR_3COM is not set
-+# CONFIG_LANCE is not set
-+CONFIG_NET_VENDOR_SMC=y
-+# CONFIG_WD80x3 is not set
-+# CONFIG_ULTRAMCA is not set
-+# CONFIG_ULTRA is not set
-+# CONFIG_ULTRA32 is not set
-+# CONFIG_SMC9194 is not set
-+CONFIG_SMC91X=y
-+# CONFIG_NET_VENDOR_RACAL is not set
-+# CONFIG_NET_ISA is not set
-+# CONFIG_NET_PCI is not set
-+# CONFIG_NET_POCKET is not set
-+
-+#
-+# Ethernet (1000 Mbit)
-+#
-+# CONFIG_ACENIC is not set
-+# CONFIG_DL2K is not set
-+# CONFIG_E1000 is not set
-+# CONFIG_MYRI_SBUS is not set
-+# CONFIG_NS83820 is not set
-+# CONFIG_HAMACHI is not set
-+# CONFIG_YELLOWFIN is not set
-+# CONFIG_R8169 is not set
-+# CONFIG_SK98LIN is not set
-+# CONFIG_TIGON3 is not set
-+# CONFIG_FDDI is not set
-+# CONFIG_HIPPI is not set
-+# CONFIG_PLIP is not set
-+# CONFIG_PPP is not set
-+# CONFIG_SLIP is not set
-+
-+#
-+# Wireless LAN (non-hamradio)
-+#
-+# CONFIG_NET_RADIO is not set
-+
-+#
-+# Token Ring devices
-+#
-+# CONFIG_TR is not set
-+# CONFIG_NET_FC is not set
-+# CONFIG_RCPCI is not set
-+# CONFIG_SHAPER is not set
-+
-+#
-+# Wan interfaces
-+#
-+# CONFIG_WAN is not set
-+
-+#
-+# PCMCIA network device support
-+#
-+CONFIG_NET_PCMCIA=y
-+# CONFIG_PCMCIA_3C589 is not set
-+# CONFIG_PCMCIA_3C574 is not set
-+# CONFIG_PCMCIA_FMVJ18X is not set
-+CONFIG_PCMCIA_PCNET=y
-+# CONFIG_PCMCIA_AXNET is not set
-+# CONFIG_PCMCIA_NMCLAN is not set
-+# CONFIG_PCMCIA_SMC91C92 is not set
-+# CONFIG_PCMCIA_XIRC2PS is not set
-+# CONFIG_ARCNET_COM20020_CS is not set
-+# CONFIG_PCMCIA_IBMTR is not set
-+# CONFIG_NET_PCMCIA_RADIO is not set
-+
-+#
-+# Amateur Radio support
-+#
-+# CONFIG_HAMRADIO is not set
-+
-+#
-+# IrDA (infrared) support
-+#
-+# CONFIG_IRDA is not set
-+
-+#
-+# ATA/ATAPI/MFM/RLL support
-+#
-+CONFIG_IDE=y
-+
-+#
-+# IDE, ATA and ATAPI Block devices
-+#
-+CONFIG_BLK_DEV_IDE=y
-+
-+#
-+# Please see Documentation/ide.txt for help/info on IDE drives
-+#
-+# CONFIG_BLK_DEV_HD_IDE is not set
-+# CONFIG_BLK_DEV_HD is not set
-+CONFIG_BLK_DEV_IDEDISK=y
-+# CONFIG_IDEDISK_MULTI_MODE is not set
-+# CONFIG_IDEDISK_STROKE is not set
-+CONFIG_BLK_DEV_IDECS=y
-+# CONFIG_BLK_DEV_IDECD is not set
-+# CONFIG_BLK_DEV_IDETAPE is not set
-+# CONFIG_BLK_DEV_IDEFLOPPY is not set
-+# CONFIG_BLK_DEV_IDESCSI is not set
-+# CONFIG_IDE_TASK_IOCTL is not set
-+
-+#
-+# IDE chipset support/bugfixes
-+#
-+# CONFIG_BLK_DEV_CMD640 is not set
-+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-+# CONFIG_BLK_DEV_ISAPNP is not set
-+# CONFIG_IDE_CHIPSETS is not set
-+# CONFIG_IDEDMA_AUTO is not set
-+# CONFIG_DMA_NONPCI is not set
-+CONFIG_BLK_DEV_IDE_MODES=y
-+# CONFIG_BLK_DEV_ATARAID is not set
-+# CONFIG_BLK_DEV_ATARAID_PDC is not set
-+# CONFIG_BLK_DEV_ATARAID_HPT is not set
-+# CONFIG_BLK_DEV_ATARAID_SII is not set
-+
-+#
-+# SCSI support
-+#
-+# CONFIG_SCSI is not set
-+
-+#
-+# I2O device support
-+#
-+# CONFIG_I2O is not set
-+# CONFIG_I2O_BLOCK is not set
-+# CONFIG_I2O_LAN is not set
-+# CONFIG_I2O_SCSI is not set
-+# CONFIG_I2O_PROC is not set
-+
-+#
-+# ISDN subsystem
-+#
-+# CONFIG_ISDN is not set
-+
-+#
-+# Input core support
-+#
-+CONFIG_INPUT=y
-+# CONFIG_INPUT_KEYBDEV is not set
-+# CONFIG_INPUT_MOUSEDEV is not set
-+# CONFIG_INPUT_JOYDEV is not set
-+CONFIG_INPUT_EVDEV=y
-+# CONFIG_INPUT_MX1TS is not set
-+
-+#
-+# Character devices
-+#
-+CONFIG_VT=y
-+# CONFIG_VT_CONSOLE is not set
-+CONFIG_SERIAL=y
-+CONFIG_SERIAL_CONSOLE=y
-+# CONFIG_SERIAL_EXTENDED is not set
-+# CONFIG_SERIAL_NONSTANDARD is not set
-+
-+#
-+# Serial drivers
-+#
-+# CONFIG_SERIAL_ANAKIN is not set
-+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-+# CONFIG_SERIAL_AMBA is not set
-+# CONFIG_SERIAL_AMBA_CONSOLE is not set
-+# CONFIG_SERIAL_CLPS711X is not set
-+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-+# CONFIG_SERIAL_21285 is not set
-+# CONFIG_SERIAL_21285_OLD is not set
-+# CONFIG_SERIAL_21285_CONSOLE is not set
-+# CONFIG_SERIAL_UART00 is not set
-+# CONFIG_SERIAL_UART00_CONSOLE is not set
-+# CONFIG_SERIAL_SA1100 is not set
-+# CONFIG_SERIAL_SA1100_CONSOLE is not set
-+# CONFIG_SERIAL_OMAHA is not set
-+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
-+# CONFIG_SERIAL_AT91 is not set
-+# CONFIG_SERIAL_AT91_CONSOLE is not set
-+# CONFIG_SERIAL_8250 is not set
-+# CONFIG_SERIAL_8250_CONSOLE is not set
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+# CONFIG_SERIAL_8250_MANY_PORTS is not set
-+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-+# CONFIG_SERIAL_8250_MULTIPORT is not set
-+# CONFIG_SERIAL_8250_HUB6 is not set
-+CONFIG_UNIX98_PTYS=y
-+CONFIG_UNIX98_PTY_COUNT=256
-+
-+#
-+# I2C support
-+#
-+# CONFIG_I2C is not set
-+
-+#
-+# L3 serial bus support
-+#
-+# CONFIG_L3 is not set
-+# CONFIG_L3_ALGOBIT is not set
-+# CONFIG_L3_BIT_SA1100_GPIO is not set
-+
-+#
-+# Other L3 adapters
-+#
-+# CONFIG_L3_SA1111 is not set
-+# CONFIG_BIT_SA1100_GPIO is not set
-+
-+#
-+# Mice
-+#
-+CONFIG_BUSMOUSE=y
-+# CONFIG_ATIXL_BUSMOUSE is not set
-+# CONFIG_LOGIBUSMOUSE is not set
-+# CONFIG_MS_BUSMOUSE is not set
-+CONFIG_MOUSE=y
-+CONFIG_PSMOUSE=y
-+# CONFIG_82C710_MOUSE is not set
-+# CONFIG_PC110_PAD is not set
-+# CONFIG_MK712_MOUSE is not set
-+
-+#
-+# Joysticks
-+#
-+# CONFIG_INPUT_GAMEPORT is not set
-+# CONFIG_INPUT_NS558 is not set
-+# CONFIG_INPUT_LIGHTNING is not set
-+# CONFIG_INPUT_PCIGAME is not set
-+# CONFIG_INPUT_CS461X is not set
-+# CONFIG_INPUT_EMU10K1 is not set
-+# CONFIG_INPUT_SERIO is not set
-+# CONFIG_INPUT_SERPORT is not set
-+
-+#
-+# Joysticks
-+#
-+# CONFIG_INPUT_ANALOG is not set
-+# CONFIG_INPUT_A3D is not set
-+# CONFIG_INPUT_ADI is not set
-+# CONFIG_INPUT_COBRA is not set
-+# CONFIG_INPUT_GF2K is not set
-+# CONFIG_INPUT_GRIP is not set
-+# CONFIG_INPUT_INTERACT is not set
-+# CONFIG_INPUT_TMDC is not set
-+# CONFIG_INPUT_SIDEWINDER is not set
-+# CONFIG_INPUT_IFORCE_USB is not set
-+# CONFIG_INPUT_IFORCE_232 is not set
-+# CONFIG_INPUT_WARRIOR is not set
-+# CONFIG_INPUT_MAGELLAN is not set
-+# CONFIG_INPUT_SPACEORB is not set
-+# CONFIG_INPUT_SPACEBALL is not set
-+# CONFIG_INPUT_STINGER is not set
-+# CONFIG_INPUT_DB9 is not set
-+# CONFIG_INPUT_GAMECON is not set
-+# CONFIG_INPUT_TURBOGRAFX is not set
-+# CONFIG_QIC02_TAPE is not set
-+# CONFIG_IPMI_HANDLER is not set
-+# CONFIG_IPMI_PANIC_EVENT is not set
-+# CONFIG_IPMI_DEVICE_INTERFACE is not set
-+# CONFIG_IPMI_KCS is not set
-+# CONFIG_IPMI_WATCHDOG is not set
-+
-+#
-+# Watchdog Cards
-+#
-+# CONFIG_WATCHDOG is not set
-+# CONFIG_SCx200_GPIO is not set
-+# CONFIG_AMD_PM768 is not set
-+# CONFIG_NVRAM is not set
-+# CONFIG_RTC is not set
-+CONFIG_PXA_RTC=y
-+# CONFIG_DTLK is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_APPLICOM is not set
-+
-+#
-+# Ftape, the floppy tape device driver
-+#
-+# CONFIG_FTAPE is not set
-+# CONFIG_AGP is not set
-+# CONFIG_DRM is not set
-+
-+#
-+# PCMCIA character devices
-+#
-+# CONFIG_PCMCIA_SERIAL_CS is not set
-+# CONFIG_SYNCLINK_CS is not set
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+
-+#
-+# File systems
-+#
-+# CONFIG_QUOTA is not set
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+# CONFIG_REISERFS_FS is not set
-+# CONFIG_REISERFS_CHECK is not set
-+# CONFIG_REISERFS_PROC_INFO is not set
-+# CONFIG_ADFS_FS is not set
-+# CONFIG_ADFS_FS_RW is not set
-+# CONFIG_AFFS_FS is not set
-+# CONFIG_HFS_FS is not set
-+# CONFIG_BEFS_FS is not set
-+# CONFIG_BEFS_DEBUG is not set
-+# CONFIG_BFS_FS is not set
-+# CONFIG_EXT3_FS is not set
-+# CONFIG_JBD is not set
-+# CONFIG_JBD_DEBUG is not set
-+CONFIG_FAT_FS=y
-+CONFIG_MSDOS_FS=y
-+# CONFIG_UMSDOS_FS is not set
-+# CONFIG_VFAT_FS is not set
-+# CONFIG_EFS_FS is not set
-+# CONFIG_JFFS_FS is not set
-+CONFIG_JFFS2_FS=y
-+CONFIG_JFFS2_FS_DEBUG=0
-+# CONFIG_CRAMFS is not set
-+# CONFIG_CRAMFS_LINEAR is not set
-+# CONFIG_CRAMFS_LINEAR_XIP is not set
-+# CONFIG_ROOT_CRAMFS_LINEAR is not set
-+# CONFIG_TMPFS is not set
-+CONFIG_RAMFS=y
-+# CONFIG_ISO9660_FS is not set
-+# CONFIG_JOLIET is not set
-+# CONFIG_ZISOFS is not set
-+# CONFIG_JFS_FS is not set
-+# CONFIG_JFS_DEBUG is not set
-+# CONFIG_JFS_STATISTICS is not set
-+# CONFIG_MINIX_FS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_NTFS_FS is not set
-+# CONFIG_NTFS_RW is not set
-+# CONFIG_HPFS_FS is not set
-+CONFIG_PROC_FS=y
-+CONFIG_DEVFS_FS=y
-+CONFIG_DEVFS_MOUNT=y
-+# CONFIG_DEVFS_DEBUG is not set
-+CONFIG_DEVPTS_FS=y
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_QNX4FS_RW is not set
-+# CONFIG_ROMFS_FS is not set
-+CONFIG_EXT2_FS=y
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UDF_FS is not set
-+# CONFIG_UDF_RW is not set
-+# CONFIG_UFS_FS is not set
-+# CONFIG_UFS_FS_WRITE is not set
-+
-+#
-+# Network File Systems
-+#
-+# CONFIG_CODA_FS is not set
-+# CONFIG_INTERMEZZO_FS is not set
-+CONFIG_NFS_FS=y
-+# CONFIG_NFS_V3 is not set
-+CONFIG_ROOT_NFS=y
-+# CONFIG_NFSD is not set
-+# CONFIG_NFSD_V3 is not set
-+# CONFIG_NFSD_TCP is not set
-+CONFIG_SUNRPC=y
-+CONFIG_LOCKD=y
-+# CONFIG_SMB_FS is not set
-+# CONFIG_NCP_FS is not set
-+# CONFIG_NCPFS_PACKET_SIGNING is not set
-+# CONFIG_NCPFS_IOCTL_LOCKING is not set
-+# CONFIG_NCPFS_STRONG is not set
-+# CONFIG_NCPFS_NFS_NS is not set
-+# CONFIG_NCPFS_OS2_NS is not set
-+# CONFIG_NCPFS_SMALLDOS is not set
-+# CONFIG_NCPFS_NLS is not set
-+# CONFIG_NCPFS_EXTRAS is not set
-+# CONFIG_ZISOFS_FS is not set
-+
-+#
-+# Partition Types
-+#
-+# CONFIG_PARTITION_ADVANCED is not set
-+CONFIG_MSDOS_PARTITION=y
-+# CONFIG_SMB_NLS is not set
-+CONFIG_NLS=y
-+
-+#
-+# Native Language Support
-+#
-+CONFIG_NLS_DEFAULT="iso8859-1"
-+# CONFIG_NLS_CODEPAGE_437 is not set
-+# CONFIG_NLS_CODEPAGE_737 is not set
-+# CONFIG_NLS_CODEPAGE_775 is not set
-+# CONFIG_NLS_CODEPAGE_850 is not set
-+# CONFIG_NLS_CODEPAGE_852 is not set
-+# CONFIG_NLS_CODEPAGE_855 is not set
-+# CONFIG_NLS_CODEPAGE_857 is not set
-+# CONFIG_NLS_CODEPAGE_860 is not set
-+# CONFIG_NLS_CODEPAGE_861 is not set
-+# CONFIG_NLS_CODEPAGE_862 is not set
-+# CONFIG_NLS_CODEPAGE_863 is not set
-+# CONFIG_NLS_CODEPAGE_864 is not set
-+# CONFIG_NLS_CODEPAGE_865 is not set
-+# CONFIG_NLS_CODEPAGE_866 is not set
-+# CONFIG_NLS_CODEPAGE_869 is not set
-+# CONFIG_NLS_CODEPAGE_936 is not set
-+# CONFIG_NLS_CODEPAGE_950 is not set
-+# CONFIG_NLS_CODEPAGE_932 is not set
-+# CONFIG_NLS_CODEPAGE_949 is not set
-+# CONFIG_NLS_CODEPAGE_874 is not set
-+# CONFIG_NLS_ISO8859_8 is not set
-+# CONFIG_NLS_CODEPAGE_1250 is not set
-+# CONFIG_NLS_CODEPAGE_1251 is not set
-+CONFIG_NLS_ISO8859_1=y
-+# CONFIG_NLS_ISO8859_2 is not set
-+# CONFIG_NLS_ISO8859_3 is not set
-+# CONFIG_NLS_ISO8859_4 is not set
-+# CONFIG_NLS_ISO8859_5 is not set
-+# CONFIG_NLS_ISO8859_6 is not set
-+# CONFIG_NLS_ISO8859_7 is not set
-+# CONFIG_NLS_ISO8859_9 is not set
-+# CONFIG_NLS_ISO8859_13 is not set
-+# CONFIG_NLS_ISO8859_14 is not set
-+# CONFIG_NLS_ISO8859_15 is not set
-+# CONFIG_NLS_KOI8_R is not set
-+# CONFIG_NLS_KOI8_U is not set
-+# CONFIG_NLS_UTF8 is not set
-+
-+#
-+# Console drivers
-+#
-+CONFIG_PC_KEYMAP=y
-+# CONFIG_VGA_CONSOLE is not set
-+
-+#
-+# Frame-buffer support
-+#
-+CONFIG_FB=y
-+CONFIG_DUMMY_CONSOLE=y
-+# CONFIG_FB_ACORN is not set
-+# CONFIG_FB_ANAKIN is not set
-+# CONFIG_FB_CLPS711X is not set
-+# CONFIG_FB_SA1100 is not set
-+# CONFIG_FB_DBMX1 is not set
-+CONFIG_FB_PXA=y
-+# CONFIG_FB_PXA_8BPP is not set
-+CONFIG_FB_PXA_16BPP=y
-+# CONFIG_FB_PXA_QVGA is not set
-+# CONFIG_FB_CYBER2000 is not set
-+# CONFIG_FB_VIRTUAL is not set
-+# CONFIG_FBCON_ADVANCED is not set
-+CONFIG_FBCON_CFB2=y
-+CONFIG_FBCON_CFB4=y
-+CONFIG_FBCON_CFB8=y
-+CONFIG_FBCON_CFB16=y
-+CONFIG_FBCON_FONTWIDTH8_ONLY=y
-+# CONFIG_FBCON_FONTS is not set
-+CONFIG_FONT_8x8=y
-+CONFIG_FONT_8x16=y
-+
-+#
-+# Sound
-+#
-+CONFIG_SOUND=y
-+# CONFIG_SOUND_ALI5455 is not set
-+# CONFIG_SOUND_BT878 is not set
-+# CONFIG_SOUND_CMPCI is not set
-+# CONFIG_SOUND_EMU10K1 is not set
-+# CONFIG_MIDI_EMU10K1 is not set
-+# CONFIG_SOUND_FUSION is not set
-+# CONFIG_SOUND_CS4281 is not set
-+# CONFIG_SOUND_ES1370 is not set
-+# CONFIG_SOUND_ES1371 is not set
-+# CONFIG_SOUND_ESSSOLO1 is not set
-+# CONFIG_SOUND_MAESTRO is not set
-+# CONFIG_SOUND_MAESTRO3 is not set
-+# CONFIG_SOUND_FORTE is not set
-+# CONFIG_SOUND_ICH is not set
-+# CONFIG_SOUND_RME96XX is not set
-+# CONFIG_SOUND_SONICVIBES is not set
-+# CONFIG_SOUND_TRIDENT is not set
-+# CONFIG_SOUND_MSNDCLAS is not set
-+# CONFIG_SOUND_MSNDPIN is not set
-+# CONFIG_SOUND_VIA82CXXX is not set
-+# CONFIG_MIDI_VIA82CXXX is not set
-+# CONFIG_SOUND_OSS is not set
-+# CONFIG_SOUND_VIDC is not set
-+# CONFIG_SOUND_WAVEARTIST is not set
-+CONFIG_SOUND_PXA_AC97=y
-+# CONFIG_SOUND_TVMIXER is not set
-+
-+#
-+# Multimedia Capabilities Port drivers
-+#
-+# CONFIG_MCP is not set
-+# CONFIG_MCP_SA1100 is not set
-+# CONFIG_MCP_UCB1200 is not set
-+# CONFIG_MCP_UCB1200_AUDIO is not set
-+# CONFIG_MCP_UCB1200_TS is not set
-+CONFIG_MCP_UCB1400_TS=y
-+
-+#
-+# USB support
-+#
-+# CONFIG_USB is not set
-+
-+#
-+# Bluetooth support
-+#
-+# CONFIG_BLUEZ is not set
-+
-+#
-+# Kernel hacking
-+#
-+CONFIG_FRAME_POINTER=y
-+CONFIG_DEBUG_USER=y
-+CONFIG_DEBUG_INFO=y
-+# CONFIG_NO_PGT_CACHE is not set
-+CONFIG_DEBUG_KERNEL=y
-+# CONFIG_DEBUG_SLAB is not set
-+CONFIG_MAGIC_SYSRQ=y
-+# CONFIG_DEBUG_SPINLOCK is not set
-+# CONFIG_DEBUG_WAITQ is not set
-+CONFIG_DEBUG_BUGVERBOSE=y
-+CONFIG_DEBUG_ERRORS=y
-+CONFIG_DEBUG_LL=y
-+# CONFIG_DEBUG_DC21285_PORT is not set
-+# CONFIG_DEBUG_CLPS711X_UART2 is not set
-+
-+#
-+# Library routines
-+#
-+CONFIG_ZLIB_INFLATE=y
-+CONFIG_ZLIB_DEFLATE=y
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/def-configs/pxa_idp 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,933 @@
-+#
-+# Automatically generated by make menuconfig: don't edit
-+#
-+CONFIG_ARM=y
-+# CONFIG_EISA is not set
-+# CONFIG_SBUS is not set
-+# CONFIG_MCA is not set
-+CONFIG_UID16=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-+# CONFIG_GENERIC_BUST_SPINLOCK is not set
-+# CONFIG_GENERIC_ISA_DMA is not set
-+
-+#
-+# Code maturity level options
-+#
-+CONFIG_EXPERIMENTAL=y
-+# CONFIG_OBSOLETE is not set
-+
-+#
-+# Loadable module support
-+#
-+CONFIG_MODULES=y
-+# CONFIG_MODVERSIONS is not set
-+CONFIG_KMOD=y
-+
-+#
-+# System Type
-+#
-+# CONFIG_ARCH_ANAKIN is not set
-+# CONFIG_ARCH_ARCA5K is not set
-+# CONFIG_ARCH_CLPS7500 is not set
-+# CONFIG_ARCH_CLPS711X is not set
-+# CONFIG_ARCH_CO285 is not set
-+CONFIG_ARCH_PXA=y
-+# CONFIG_ARCH_EBSA110 is not set
-+# CONFIG_ARCH_CAMELOT is not set
-+# CONFIG_ARCH_FOOTBRIDGE is not set
-+# CONFIG_ARCH_INTEGRATOR is not set
-+# CONFIG_ARCH_OMAHA is not set
-+# CONFIG_ARCH_L7200 is not set
-+# CONFIG_ARCH_MX1ADS is not set
-+# CONFIG_ARCH_RPC is not set
-+# CONFIG_ARCH_RISCSTATION is not set
-+# CONFIG_ARCH_SA1100 is not set
-+# CONFIG_ARCH_SHARK is not set
-+
-+#
-+# Archimedes/A5000 Implementations
-+#
-+# CONFIG_ARCH_ARC is not set
-+# CONFIG_ARCH_A5K is not set
-+
-+#
-+# Footbridge Implementations
-+#
-+# CONFIG_ARCH_CATS is not set
-+# CONFIG_ARCH_PERSONAL_SERVER is not set
-+# CONFIG_ARCH_EBSA285_ADDIN is not set
-+# CONFIG_ARCH_EBSA285_HOST is not set
-+# CONFIG_ARCH_NETWINDER is not set
-+
-+#
-+# SA11x0 Implementations
-+#
-+# CONFIG_SA1100_ACCELENT is not set
-+# CONFIG_SA1100_ASSABET is not set
-+# CONFIG_ASSABET_NEPONSET is not set
-+# CONFIG_SA1100_ADSBITSY is not set
-+# CONFIG_SA1100_BRUTUS is not set
-+# CONFIG_SA1100_CEP is not set
-+# CONFIG_SA1100_CERF is not set
-+# CONFIG_SA1100_H3100 is not set
-+# CONFIG_SA1100_H3600 is not set
-+# CONFIG_SA1100_H3800 is not set
-+# CONFIG_SA1100_H3XXX is not set
-+# CONFIG_SA1100_EXTENEX1 is not set
-+# CONFIG_SA1100_FLEXANET is not set
-+# CONFIG_SA1100_FREEBIRD is not set
-+# CONFIG_SA1100_FRODO is not set
-+# CONFIG_SA1100_GRAPHICSCLIENT is not set
-+# CONFIG_SA1100_GRAPHICSMASTER is not set
-+# CONFIG_SA1100_BADGE4 is not set
-+# CONFIG_SA1100_JORNADA720 is not set
-+# CONFIG_SA1100_HUW_WEBPANEL is not set
-+# CONFIG_SA1100_ITSY is not set
-+# CONFIG_SA1100_LART is not set
-+# CONFIG_SA1100_NANOENGINE is not set
-+# CONFIG_SA1100_OMNIMETER is not set
-+# CONFIG_SA1100_PANGOLIN is not set
-+# CONFIG_SA1100_PLEB is not set
-+# CONFIG_SA1100_PT_SYSTEM3 is not set
-+# CONFIG_SA1100_SHANNON is not set
-+# CONFIG_SA1100_SHERMAN is not set
-+# CONFIG_SA1100_SIMPAD is not set
-+# CONFIG_SA1100_SIMPUTER is not set
-+# CONFIG_SA1100_PFS168 is not set
-+# CONFIG_SA1100_VICTOR is not set
-+# CONFIG_SA1100_XP860 is not set
-+# CONFIG_SA1100_YOPY is not set
-+# CONFIG_SA1100_USB is not set
-+# CONFIG_SA1100_USB_NETLINK is not set
-+# CONFIG_SA1100_USB_CHAR is not set
-+# CONFIG_H3600_SLEEVE is not set
-+
-+#
-+# Intel PXA250/210 Implementations
-+#
-+# CONFIG_ARCH_LUBBOCK is not set
-+CONFIG_ARCH_PXA_IDP=y
-+# CONFIG_ARCH_PXA_CERF is not set
-+CONFIG_PXA_USB=m
-+CONFIG_PXA_USB_NETLINK=m
-+CONFIG_PXA_USB_CHAR=m
-+
-+#
-+# CLPS711X/EP721X Implementations
-+#
-+# CONFIG_ARCH_AUTCPU12 is not set
-+# CONFIG_ARCH_CDB89712 is not set
-+# CONFIG_ARCH_CLEP7312 is not set
-+# CONFIG_ARCH_EDB7211 is not set
-+# CONFIG_ARCH_P720T is not set
-+# CONFIG_ARCH_FORTUNET is not set
-+# CONFIG_ARCH_EP7211 is not set
-+# CONFIG_ARCH_EP7212 is not set
-+# CONFIG_ARCH_ACORN is not set
-+# CONFIG_FOOTBRIDGE is not set
-+# CONFIG_FOOTBRIDGE_HOST is not set
-+# CONFIG_FOOTBRIDGE_ADDIN is not set
-+CONFIG_CPU_32=y
-+# CONFIG_CPU_26 is not set
-+# CONFIG_CPU_ARM610 is not set
-+# CONFIG_CPU_ARM710 is not set
-+# CONFIG_CPU_ARM720T is not set
-+# CONFIG_CPU_ARM920T is not set
-+# CONFIG_CPU_ARM922T is not set
-+# CONFIG_PLD is not set
-+# CONFIG_CPU_ARM926T is not set
-+# CONFIG_CPU_ARM1020 is not set
-+# CONFIG_CPU_ARM1026 is not set
-+# CONFIG_CPU_SA110 is not set
-+# CONFIG_CPU_SA1100 is not set
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_XSCALE=y
-+# CONFIG_XSCALE_CACHE_ERRATA is not set
-+# CONFIG_CPU_32v3 is not set
-+# CONFIG_CPU_32v4 is not set
-+# CONFIG_DISCONTIGMEM is not set
-+
-+#
-+# General setup
-+#
-+# CONFIG_PCI is not set
-+# CONFIG_ISA is not set
-+# CONFIG_ISA_DMA is not set
-+# CONFIG_ZBOOT_ROM is not set
-+CONFIG_ZBOOT_ROM_TEXT=0
-+CONFIG_ZBOOT_ROM_BSS=0
-+CONFIG_HOTPLUG=y
-+
-+#
-+# PCMCIA/CardBus support
-+#
-+CONFIG_PCMCIA=y
-+# CONFIG_I82092 is not set
-+# CONFIG_I82365 is not set
-+# CONFIG_TCIC is not set
-+# CONFIG_PCMCIA_CLPS6700 is not set
-+# CONFIG_PCMCIA_SA1100 is not set
-+CONFIG_PCMCIA_PXA=y
-+CONFIG_NET=y
-+CONFIG_SYSVIPC=y
-+# CONFIG_BSD_PROCESS_ACCT is not set
-+CONFIG_SYSCTL=y
-+CONFIG_FPE_NWFPE=y
-+# CONFIG_FPE_FASTFPE is not set
-+CONFIG_KCORE_ELF=y
-+# CONFIG_KCORE_AOUT is not set
-+# CONFIG_BINFMT_AOUT is not set
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_MISC is not set
-+CONFIG_PM=y
-+# CONFIG_ARTHUR is not set
-+CONFIG_CMDLINE="root=/dev/mtdblock2 init=/linuxrc console=ttyS0,115200"
-+CONFIG_LEDS=y
-+CONFIG_LEDS_TIMER=y
-+CONFIG_LEDS_CPU=y
-+CONFIG_ALIGNMENT_TRAP=y
-+
-+#
-+# Parallel port support
-+#
-+# CONFIG_PARPORT is not set
-+
-+#
-+# Memory Technology Devices (MTD)
-+#
-+CONFIG_MTD=y
-+# CONFIG_MTD_DEBUG is not set
-+CONFIG_MTD_PARTITIONS=y
-+# CONFIG_MTD_CONCAT is not set
-+# CONFIG_MTD_REDBOOT_PARTS is not set
-+# CONFIG_MTD_CMDLINE_PARTS is not set
-+# CONFIG_MTD_AFS_PARTS is not set
-+CONFIG_MTD_CHAR=y
-+CONFIG_MTD_BLOCK=y
-+# CONFIG_FTL is not set
-+# CONFIG_NFTL is not set
-+
-+#
-+# RAM/ROM/Flash chip drivers
-+#
-+CONFIG_MTD_CFI=y
-+# CONFIG_MTD_JEDECPROBE is not set
-+CONFIG_MTD_GEN_PROBE=y
-+CONFIG_MTD_CFI_ADV_OPTIONS=y
-+CONFIG_MTD_CFI_NOSWAP=y
-+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-+CONFIG_MTD_CFI_GEOMETRY=y
-+# CONFIG_MTD_CFI_B1 is not set
-+# CONFIG_MTD_CFI_B2 is not set
-+CONFIG_MTD_CFI_B4=y
-+# CONFIG_MTD_CFI_B8 is not set
-+# CONFIG_MTD_CFI_I1 is not set
-+CONFIG_MTD_CFI_I2=y
-+# CONFIG_MTD_CFI_I4 is not set
-+# CONFIG_MTD_CFI_I8 is not set
-+CONFIG_MTD_CFI_INTELEXT=y
-+# CONFIG_MTD_CFI_AMDSTD is not set
-+# CONFIG_MTD_RAM is not set
-+# CONFIG_MTD_ROM is not set
-+# CONFIG_MTD_ABSENT is not set
-+# CONFIG_MTD_OBSOLETE_CHIPS is not set
-+# CONFIG_MTD_AMDSTD is not set
-+# CONFIG_MTD_SHARP is not set
-+# CONFIG_MTD_JEDEC is not set
-+
-+#
-+# Mapping drivers for chip access
-+#
-+# CONFIG_MTD_PHYSMAP is not set
-+CONFIG_MTD_LUBBOCK=y
-+# CONFIG_MTD_NORA is not set
-+# CONFIG_MTD_ARM_INTEGRATOR is not set
-+# CONFIG_MTD_CDB89712 is not set
-+# CONFIG_MTD_SA1100 is not set
-+# CONFIG_MTD_DC21285 is not set
-+# CONFIG_MTD_IQ80310 is not set
-+# CONFIG_MTD_FORTUNET is not set
-+# CONFIG_MTD_PXA_CERF is not set
-+# CONFIG_MTD_EPXA10DB is not set
-+# CONFIG_MTD_AUTCPU12 is not set
-+# CONFIG_MTD_EDB7312 is not set
-+# CONFIG_MTD_IMPA7 is not set
-+CONFIG_ASI_MTD0_SIZE=40000
-+CONFIG_ASI_MTD1_SIZE=100000
-+CONFIG_ASI_MTD2_SIZE=1e00000
-+# CONFIG_MTD_PCI is not set
-+
-+#
-+# Self-contained MTD device drivers
-+#
-+# CONFIG_MTD_PMC551 is not set
-+# CONFIG_MTD_SLRAM is not set
-+# CONFIG_MTD_MTDRAM is not set
-+# CONFIG_MTD_BLKMTD is not set
-+# CONFIG_MTD_DOC1000 is not set
-+# CONFIG_MTD_DOC2000 is not set
-+# CONFIG_MTD_DOC2001 is not set
-+# CONFIG_MTD_DOCPROBE is not set
-+
-+#
-+# NAND Flash Device Drivers
-+#
-+# CONFIG_MTD_NAND is not set
-+
-+#
-+# Plug and Play configuration
-+#
-+# CONFIG_PNP is not set
-+# CONFIG_ISAPNP is not set
-+
-+#
-+# Block devices
-+#
-+# CONFIG_BLK_DEV_FD is not set
-+# CONFIG_BLK_DEV_XD is not set
-+# CONFIG_PARIDE is not set
-+# CONFIG_BLK_CPQ_DA is not set
-+# CONFIG_BLK_CPQ_CISS_DA is not set
-+# CONFIG_CISS_SCSI_TAPE is not set
-+# CONFIG_BLK_DEV_DAC960 is not set
-+# CONFIG_BLK_DEV_UMEM is not set
-+CONFIG_BLK_DEV_LOOP=y
-+# CONFIG_BLK_DEV_NBD is not set
-+CONFIG_BLK_DEV_RAM=y
-+CONFIG_BLK_DEV_RAM_SIZE=4096
-+CONFIG_BLK_DEV_INITRD=y
-+
-+#
-+# Multi-device support (RAID and LVM)
-+#
-+# CONFIG_MD is not set
-+# CONFIG_BLK_DEV_MD is not set
-+# CONFIG_MD_LINEAR is not set
-+# CONFIG_MD_RAID0 is not set
-+# CONFIG_MD_RAID1 is not set
-+# CONFIG_MD_RAID5 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_BLK_DEV_LVM is not set
-+
-+#
-+# Networking options
-+#
-+CONFIG_PACKET=y
-+# CONFIG_PACKET_MMAP is not set
-+# CONFIG_NETLINK_DEV is not set
-+# CONFIG_NETFILTER is not set
-+# CONFIG_FILTER is not set
-+CONFIG_UNIX=y
-+CONFIG_INET=y
-+# CONFIG_IP_MULTICAST is not set
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+# CONFIG_IP_PNP is not set
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_ARPD is not set
-+# CONFIG_INET_ECN is not set
-+# CONFIG_SYN_COOKIES is not set
-+# CONFIG_IPV6 is not set
-+# CONFIG_KHTTPD is not set
-+# CONFIG_ATM is not set
-+# CONFIG_VLAN_8021Q is not set
-+# CONFIG_IPX is not set
-+# CONFIG_ATALK is not set
-+
-+#
-+# Appletalk devices
-+#
-+# CONFIG_DEV_APPLETALK is not set
-+# CONFIG_DECNET is not set
-+# CONFIG_BRIDGE is not set
-+# CONFIG_X25 is not set
-+# CONFIG_LAPB is not set
-+# CONFIG_LLC is not set
-+# CONFIG_NET_DIVERT is not set
-+# CONFIG_ECONET is not set
-+# CONFIG_WAN_ROUTER is not set
-+# CONFIG_NET_FASTROUTE is not set
-+# CONFIG_NET_HW_FLOWCONTROL is not set
-+
-+#
-+# QoS and/or fair queueing
-+#
-+# CONFIG_NET_SCHED is not set
-+
-+#
-+# Network testing
-+#
-+# CONFIG_NET_PKTGEN is not set
-+
-+#
-+# Network device support
-+#
-+CONFIG_NETDEVICES=y
-+
-+#
-+# ARCnet devices
-+#
-+# CONFIG_ARCNET is not set
-+# CONFIG_DUMMY is not set
-+# CONFIG_BONDING is not set
-+# CONFIG_EQUALIZER is not set
-+# CONFIG_TUN is not set
-+# CONFIG_ETHERTAP is not set
-+
-+#
-+# Ethernet (10 or 100Mbit)
-+#
-+CONFIG_NET_ETHERNET=y
-+# CONFIG_ARM_AM79C961A is not set
-+# CONFIG_ARM_CIRRUS is not set
-+# CONFIG_SUNLANCE is not set
-+# CONFIG_SUNBMAC is not set
-+# CONFIG_SUNQE is not set
-+# CONFIG_SUNGEM is not set
-+# CONFIG_NET_VENDOR_3COM is not set
-+# CONFIG_LANCE is not set
-+CONFIG_NET_VENDOR_SMC=y
-+# CONFIG_WD80x3 is not set
-+# CONFIG_ULTRAMCA is not set
-+# CONFIG_ULTRA is not set
-+# CONFIG_ULTRA32 is not set
-+# CONFIG_SMC9194 is not set
-+CONFIG_SMC91111=m
-+# CONFIG_NET_VENDOR_RACAL is not set
-+# CONFIG_NET_ISA is not set
-+# CONFIG_NET_PCI is not set
-+CONFIG_NET_POCKET=y
-+# CONFIG_DE600 is not set
-+# CONFIG_DE620 is not set
-+
-+#
-+# Ethernet (1000 Mbit)
-+#
-+# CONFIG_ACENIC is not set
-+# CONFIG_DL2K is not set
-+# CONFIG_MYRI_SBUS is not set
-+# CONFIG_NS83820 is not set
-+# CONFIG_HAMACHI is not set
-+# CONFIG_YELLOWFIN is not set
-+# CONFIG_SK98LIN is not set
-+# CONFIG_TIGON3 is not set
-+# CONFIG_FDDI is not set
-+# CONFIG_HIPPI is not set
-+# CONFIG_PLIP is not set
-+# CONFIG_PPP is not set
-+# CONFIG_SLIP is not set
-+
-+#
-+# Wireless LAN (non-hamradio)
-+#
-+CONFIG_NET_RADIO=y
-+# CONFIG_STRIP is not set
-+CONFIG_WAVELAN=m
-+# CONFIG_ARLAN is not set
-+CONFIG_AIRONET4500=y
-+# CONFIG_AIRONET4500_NONCS is not set
-+# CONFIG_AIRONET4500_PROC is not set
-+CONFIG_HERMES=m
-+CONFIG_PCMCIA_HERMES=m
-+CONFIG_AIRO_CS=m
-+CONFIG_NET_WIRELESS=y
-+
-+#
-+# Token Ring devices
-+#
-+# CONFIG_TR is not set
-+# CONFIG_NET_FC is not set
-+# CONFIG_RCPCI is not set
-+# CONFIG_SHAPER is not set
-+
-+#
-+# Wan interfaces
-+#
-+# CONFIG_WAN is not set
-+
-+#
-+# PCMCIA network device support
-+#
-+CONFIG_NET_PCMCIA=y
-+# CONFIG_PCMCIA_3C589 is not set
-+# CONFIG_PCMCIA_3C574 is not set
-+# CONFIG_PCMCIA_FMVJ18X is not set
-+CONFIG_PCMCIA_PCNET=m
-+# CONFIG_PCMCIA_AXNET is not set
-+CONFIG_PCMCIA_NMCLAN=m
-+CONFIG_PCMCIA_SMC91C92=m
-+CONFIG_PCMCIA_XIRC2PS=m
-+# CONFIG_ARCNET_COM20020_CS is not set
-+# CONFIG_PCMCIA_IBMTR is not set
-+CONFIG_NET_PCMCIA_RADIO=y
-+CONFIG_PCMCIA_RAYCS=m
-+CONFIG_PCMCIA_NETWAVE=m
-+CONFIG_PCMCIA_WAVELAN=m
-+CONFIG_AIRONET4500_CS=m
-+
-+#
-+# Amateur Radio support
-+#
-+# CONFIG_HAMRADIO is not set
-+
-+#
-+# IrDA (infrared) support
-+#
-+CONFIG_IRDA=m
-+CONFIG_IRLAN=m
-+# CONFIG_IRNET is not set
-+CONFIG_IRCOMM=m
-+CONFIG_IRDA_ULTRA=y
-+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
-+# CONFIG_IRDA_FAST_RR is not set
-+CONFIG_IRDA_DEBUG=y
-+
-+#
-+# Infrared-port device drivers
-+#
-+CONFIG_IRTTY_SIR=m
-+# CONFIG_IRPORT_SIR is not set
-+# CONFIG_DONGLE is not set
-+# CONFIG_USB_IRDA is not set
-+# CONFIG_NSC_FIR is not set
-+# CONFIG_WINBOND_FIR is not set
-+# CONFIG_TOSHIBA_FIR is not set
-+# CONFIG_SMC_IRCC_FIR is not set
-+# CONFIG_ALI_FIR is not set
-+# CONFIG_VLSI_FIR is not set
-+CONFIG_PXA_FIR=m
-+
-+#
-+# ATA/ATAPI/MFM/RLL support
-+#
-+CONFIG_IDE=y
-+
-+#
-+# IDE, ATA and ATAPI Block devices
-+#
-+CONFIG_BLK_DEV_IDE=y
-+# CONFIG_BLK_DEV_HD_IDE is not set
-+# CONFIG_BLK_DEV_HD is not set
-+CONFIG_BLK_DEV_IDEDISK=y
-+# CONFIG_IDEDISK_MULTI_MODE is not set
-+# CONFIG_IDEDISK_STROKE is not set
-+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-+# CONFIG_BLK_DEV_IDEDISK_WD is not set
-+# CONFIG_BLK_DEV_COMMERIAL is not set
-+# CONFIG_BLK_DEV_TIVO is not set
-+CONFIG_BLK_DEV_IDECS=m
-+# CONFIG_BLK_DEV_IDECD is not set
-+# CONFIG_BLK_DEV_IDETAPE is not set
-+# CONFIG_BLK_DEV_IDEFLOPPY is not set
-+# CONFIG_BLK_DEV_IDESCSI is not set
-+# CONFIG_IDE_TASK_IOCTL is not set
-+# CONFIG_BLK_DEV_CMD640 is not set
-+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-+# CONFIG_BLK_DEV_ISAPNP is not set
-+# CONFIG_IDE_CHIPSETS is not set
-+# CONFIG_IDEDMA_AUTO is not set
-+# CONFIG_DMA_NONPCI is not set
-+# CONFIG_BLK_DEV_IDE_MODES is not set
-+# CONFIG_BLK_DEV_ATARAID is not set
-+# CONFIG_BLK_DEV_ATARAID_PDC is not set
-+# CONFIG_BLK_DEV_ATARAID_HPT is not set
-+
-+#
-+# SCSI support
-+#
-+# CONFIG_SCSI is not set
-+
-+#
-+# I2O device support
-+#
-+# CONFIG_I2O is not set
-+# CONFIG_I2O_BLOCK is not set
-+# CONFIG_I2O_LAN is not set
-+# CONFIG_I2O_SCSI is not set
-+# CONFIG_I2O_PROC is not set
-+
-+#
-+# ISDN subsystem
-+#
-+# CONFIG_ISDN is not set
-+
-+#
-+# Input core support
-+#
-+CONFIG_INPUT=y
-+CONFIG_INPUT_KEYBDEV=m
-+CONFIG_INPUT_MOUSEDEV=m
-+CONFIG_INPUT_MOUSEDEV_SCREEN_X=640
-+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=480
-+# CONFIG_INPUT_JOYDEV is not set
-+CONFIG_INPUT_EVDEV=y
-+
-+#
-+# Character devices
-+#
-+CONFIG_VT=y
-+# CONFIG_VT_CONSOLE is not set
-+CONFIG_SERIAL=y
-+CONFIG_SERIAL_CONSOLE=y
-+# CONFIG_SERIAL_EXTENDED is not set
-+# CONFIG_SERIAL_NONSTANDARD is not set
-+
-+#
-+# Serial drivers
-+#
-+# CONFIG_SERIAL_ANAKIN is not set
-+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-+# CONFIG_SERIAL_AMBA is not set
-+# CONFIG_SERIAL_AMBA_CONSOLE is not set
-+# CONFIG_SERIAL_CLPS711X is not set
-+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-+# CONFIG_SERIAL_21285 is not set
-+# CONFIG_SERIAL_21285_OLD is not set
-+# CONFIG_SERIAL_21285_CONSOLE is not set
-+# CONFIG_SERIAL_UART00 is not set
-+# CONFIG_SERIAL_UART00_CONSOLE is not set
-+# CONFIG_SERIAL_SA1100 is not set
-+# CONFIG_SERIAL_SA1100_CONSOLE is not set
-+# CONFIG_SERIAL_OMAHA is not set
-+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
-+# CONFIG_SERIAL_8250 is not set
-+# CONFIG_SERIAL_8250_CONSOLE is not set
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+# CONFIG_SERIAL_8250_MANY_PORTS is not set
-+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-+# CONFIG_SERIAL_8250_MULTIPORT is not set
-+# CONFIG_SERIAL_8250_HUB6 is not set
-+# CONFIG_IDP_KEYB is not set
-+CONFIG_MATRIX_KEYBOARD=y
-+# CONFIG_SA1111_PS2_KEYB is not set
-+CONFIG_UNIX98_PTYS=y
-+CONFIG_UNIX98_PTY_COUNT=256
-+
-+#
-+# I2C support
-+#
-+# CONFIG_I2C is not set
-+
-+#
-+# L3 serial bus support
-+#
-+# CONFIG_L3 is not set
-+# CONFIG_L3_ALGOBIT is not set
-+# CONFIG_L3_BIT_SA1100_GPIO is not set
-+# CONFIG_L3_SA1111 is not set
-+# CONFIG_BIT_SA1100_GPIO is not set
-+
-+#
-+# Mice
-+#
-+CONFIG_BUSMOUSE=y
-+# CONFIG_ATIXL_BUSMOUSE is not set
-+# CONFIG_LOGIBUSMOUSE is not set
-+# CONFIG_MS_BUSMOUSE is not set
-+CONFIG_MOUSE=y
-+CONFIG_PSMOUSE=y
-+# CONFIG_82C710_MOUSE is not set
-+# CONFIG_PC110_PAD is not set
-+# CONFIG_MK712_MOUSE is not set
-+
-+#
-+# Joysticks
-+#
-+# CONFIG_INPUT_GAMEPORT is not set
-+# CONFIG_INPUT_NS558 is not set
-+# CONFIG_INPUT_LIGHTNING is not set
-+# CONFIG_INPUT_PCIGAME is not set
-+# CONFIG_INPUT_CS461X is not set
-+# CONFIG_INPUT_EMU10K1 is not set
-+# CONFIG_INPUT_SERIO is not set
-+# CONFIG_INPUT_SERPORT is not set
-+# CONFIG_INPUT_ANALOG is not set
-+# CONFIG_INPUT_A3D is not set
-+# CONFIG_INPUT_ADI is not set
-+# CONFIG_INPUT_COBRA is not set
-+# CONFIG_INPUT_GF2K is not set
-+# CONFIG_INPUT_GRIP is not set
-+# CONFIG_INPUT_INTERACT is not set
-+# CONFIG_INPUT_TMDC is not set
-+# CONFIG_INPUT_SIDEWINDER is not set
-+# CONFIG_INPUT_IFORCE_USB is not set
-+# CONFIG_INPUT_IFORCE_232 is not set
-+# CONFIG_INPUT_WARRIOR is not set
-+# CONFIG_INPUT_MAGELLAN is not set
-+# CONFIG_INPUT_SPACEORB is not set
-+# CONFIG_INPUT_SPACEBALL is not set
-+# CONFIG_INPUT_STINGER is not set
-+# CONFIG_INPUT_DB9 is not set
-+# CONFIG_INPUT_GAMECON is not set
-+# CONFIG_INPUT_TURBOGRAFX is not set
-+# CONFIG_QIC02_TAPE is not set
-+
-+#
-+# Watchdog Cards
-+#
-+# CONFIG_WATCHDOG is not set
-+# CONFIG_NVRAM is not set
-+# CONFIG_RTC is not set
-+# CONFIG_PXA_RTC is not set
-+# CONFIG_DTLK is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_APPLICOM is not set
-+
-+#
-+# Ftape, the floppy tape device driver
-+#
-+# CONFIG_FTAPE is not set
-+# CONFIG_AGP is not set
-+# CONFIG_DRM is not set
-+
-+#
-+# PCMCIA character devices
-+#
-+CONFIG_PCMCIA_SERIAL_CS=m
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+
-+#
-+# File systems
-+#
-+# CONFIG_QUOTA is not set
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+# CONFIG_REISERFS_FS is not set
-+# CONFIG_REISERFS_CHECK is not set
-+# CONFIG_REISERFS_PROC_INFO is not set
-+# CONFIG_ADFS_FS is not set
-+# CONFIG_ADFS_FS_RW is not set
-+# CONFIG_AFFS_FS is not set
-+# CONFIG_HFS_FS is not set
-+# CONFIG_BFS_FS is not set
-+CONFIG_EXT3_FS=m
-+CONFIG_JBD=m
-+# CONFIG_JBD_DEBUG is not set
-+CONFIG_FAT_FS=m
-+CONFIG_MSDOS_FS=m
-+# CONFIG_UMSDOS_FS is not set
-+CONFIG_VFAT_FS=m
-+# CONFIG_EFS_FS is not set
-+# CONFIG_JFFS_FS is not set
-+CONFIG_JFFS2_FS=y
-+CONFIG_JFFS2_FS_DEBUG=0
-+CONFIG_CRAMFS=y
-+# CONFIG_TMPFS is not set
-+CONFIG_RAMFS=y
-+# CONFIG_ISO9660_FS is not set
-+# CONFIG_JOLIET is not set
-+# CONFIG_ZISOFS is not set
-+# CONFIG_MINIX_FS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_NTFS_FS is not set
-+# CONFIG_NTFS_RW is not set
-+# CONFIG_HPFS_FS is not set
-+CONFIG_PROC_FS=y
-+CONFIG_DEVFS_FS=y
-+CONFIG_DEVFS_MOUNT=y
-+# CONFIG_DEVFS_DEBUG is not set
-+CONFIG_DEVPTS_FS=y
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_QNX4FS_RW is not set
-+# CONFIG_ROMFS_FS is not set
-+CONFIG_EXT2_FS=y
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UDF_FS is not set
-+# CONFIG_UDF_RW is not set
-+# CONFIG_UFS_FS is not set
-+# CONFIG_UFS_FS_WRITE is not set
-+
-+#
-+# Network File Systems
-+#
-+# CONFIG_CODA_FS is not set
-+# CONFIG_INTERMEZZO_FS is not set
-+CONFIG_NFS_FS=y
-+CONFIG_NFS_V3=y
-+# CONFIG_ROOT_NFS is not set
-+# CONFIG_NFSD is not set
-+# CONFIG_NFSD_V3 is not set
-+CONFIG_SUNRPC=y
-+CONFIG_LOCKD=y
-+CONFIG_LOCKD_V4=y
-+# CONFIG_SMB_FS is not set
-+# CONFIG_NCP_FS is not set
-+# CONFIG_NCPFS_PACKET_SIGNING is not set
-+# CONFIG_NCPFS_IOCTL_LOCKING is not set
-+# CONFIG_NCPFS_STRONG is not set
-+# CONFIG_NCPFS_NFS_NS is not set
-+# CONFIG_NCPFS_OS2_NS is not set
-+# CONFIG_NCPFS_SMALLDOS is not set
-+# CONFIG_NCPFS_NLS is not set
-+# CONFIG_NCPFS_EXTRAS is not set
-+# CONFIG_ZISOFS_FS is not set
-+CONFIG_ZLIB_FS_INFLATE=y
-+
-+#
-+# Partition Types
-+#
-+CONFIG_PARTITION_ADVANCED=y
-+# CONFIG_ACORN_PARTITION is not set
-+# CONFIG_OSF_PARTITION is not set
-+# CONFIG_AMIGA_PARTITION is not set
-+# CONFIG_ATARI_PARTITION is not set
-+# CONFIG_MAC_PARTITION is not set
-+CONFIG_MSDOS_PARTITION=y
-+# CONFIG_BSD_DISKLABEL is not set
-+# CONFIG_MINIX_SUBPARTITION is not set
-+# CONFIG_SOLARIS_X86_PARTITION is not set
-+# CONFIG_UNIXWARE_DISKLABEL is not set
-+# CONFIG_LDM_PARTITION is not set
-+# CONFIG_SGI_PARTITION is not set
-+# CONFIG_ULTRIX_PARTITION is not set
-+# CONFIG_SUN_PARTITION is not set
-+# CONFIG_SMB_NLS is not set
-+CONFIG_NLS=y
-+
-+#
-+# Native Language Support
-+#
-+CONFIG_NLS_DEFAULT="iso8859-1"
-+CONFIG_NLS_CODEPAGE_437=m
-+# CONFIG_NLS_CODEPAGE_737 is not set
-+# CONFIG_NLS_CODEPAGE_775 is not set
-+# CONFIG_NLS_CODEPAGE_850 is not set
-+# CONFIG_NLS_CODEPAGE_852 is not set
-+# CONFIG_NLS_CODEPAGE_855 is not set
-+# CONFIG_NLS_CODEPAGE_857 is not set
-+# CONFIG_NLS_CODEPAGE_860 is not set
-+# CONFIG_NLS_CODEPAGE_861 is not set
-+# CONFIG_NLS_CODEPAGE_862 is not set
-+# CONFIG_NLS_CODEPAGE_863 is not set
-+# CONFIG_NLS_CODEPAGE_864 is not set
-+# CONFIG_NLS_CODEPAGE_865 is not set
-+# CONFIG_NLS_CODEPAGE_866 is not set
-+# CONFIG_NLS_CODEPAGE_869 is not set
-+# CONFIG_NLS_CODEPAGE_936 is not set
-+# CONFIG_NLS_CODEPAGE_950 is not set
-+# CONFIG_NLS_CODEPAGE_932 is not set
-+# CONFIG_NLS_CODEPAGE_949 is not set
-+# CONFIG_NLS_CODEPAGE_874 is not set
-+# CONFIG_NLS_ISO8859_8 is not set
-+# CONFIG_NLS_CODEPAGE_1250 is not set
-+# CONFIG_NLS_CODEPAGE_1251 is not set
-+CONFIG_NLS_ISO8859_1=y
-+# CONFIG_NLS_ISO8859_2 is not set
-+# CONFIG_NLS_ISO8859_3 is not set
-+# CONFIG_NLS_ISO8859_4 is not set
-+# CONFIG_NLS_ISO8859_5 is not set
-+# CONFIG_NLS_ISO8859_6 is not set
-+# CONFIG_NLS_ISO8859_7 is not set
-+# CONFIG_NLS_ISO8859_9 is not set
-+# CONFIG_NLS_ISO8859_13 is not set
-+# CONFIG_NLS_ISO8859_14 is not set
-+# CONFIG_NLS_ISO8859_15 is not set
-+# CONFIG_NLS_KOI8_R is not set
-+# CONFIG_NLS_KOI8_U is not set
-+# CONFIG_NLS_UTF8 is not set
-+
-+#
-+# Console drivers
-+#
-+CONFIG_PC_KEYMAP=y
-+# CONFIG_VGA_CONSOLE is not set
-+
-+#
-+# Frame-buffer support
-+#
-+CONFIG_FB=y
-+CONFIG_DUMMY_CONSOLE=y
-+# CONFIG_FB_ACORN is not set
-+# CONFIG_FB_ANAKIN is not set
-+# CONFIG_FB_CLPS711X is not set
-+# CONFIG_FB_SA1100 is not set
-+CONFIG_FB_PXA=y
-+# CONFIG_FB_CYBER2000 is not set
-+# CONFIG_FB_VIRTUAL is not set
-+# CONFIG_FBCON_ADVANCED is not set
-+CONFIG_FBCON_CFB2=y
-+CONFIG_FBCON_CFB4=y
-+CONFIG_FBCON_CFB8=y
-+CONFIG_FBCON_CFB16=y
-+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-+# CONFIG_FBCON_FONTS is not set
-+CONFIG_FONT_8x8=y
-+CONFIG_FONT_8x16=y
-+
-+#
-+# Sound
-+#
-+CONFIG_SOUND=y
-+# CONFIG_SOUND_BT878 is not set
-+# CONFIG_SOUND_CMPCI is not set
-+# CONFIG_SOUND_EMU10K1 is not set
-+# CONFIG_MIDI_EMU10K1 is not set
-+# CONFIG_SOUND_FUSION is not set
-+# CONFIG_SOUND_CS4281 is not set
-+# CONFIG_SOUND_ES1370 is not set
-+# CONFIG_SOUND_ES1371 is not set
-+# CONFIG_SOUND_ESSSOLO1 is not set
-+# CONFIG_SOUND_MAESTRO is not set
-+# CONFIG_SOUND_MAESTRO3 is not set
-+# CONFIG_SOUND_ICH is not set
-+# CONFIG_SOUND_RME96XX is not set
-+# CONFIG_SOUND_SONICVIBES is not set
-+# CONFIG_SOUND_TRIDENT is not set
-+# CONFIG_SOUND_MSNDCLAS is not set
-+# CONFIG_SOUND_MSNDPIN is not set
-+# CONFIG_SOUND_VIA82CXXX is not set
-+# CONFIG_MIDI_VIA82CXXX is not set
-+# CONFIG_SOUND_OSS is not set
-+# CONFIG_SOUND_WAVEARTIST is not set
-+CONFIG_SOUND_PXA_AC97=y
-+# CONFIG_SOUND_TVMIXER is not set
-+
-+#
-+# Multimedia Capabilities Port drivers
-+#
-+# CONFIG_MCP is not set
-+# CONFIG_MCP_SA1100 is not set
-+# CONFIG_MCP_UCB1200 is not set
-+# CONFIG_MCP_UCB1200_AUDIO is not set
-+# CONFIG_MCP_UCB1200_TS is not set
-+CONFIG_MCP_UCB1400_TS=m
-+
-+#
-+# USB support
-+#
-+# CONFIG_USB is not set
-+
-+#
-+# Bluetooth support
-+#
-+# CONFIG_BLUEZ is not set
-+
-+#
-+# Kernel hacking
-+#
-+CONFIG_FRAME_POINTER=y
-+CONFIG_DEBUG_USER=y
-+# CONFIG_DEBUG_INFO is not set
-+# CONFIG_NO_PGT_CACHE is not set
-+CONFIG_DEBUG_KERNEL=y
-+CONFIG_DEBUG_SLAB=y
-+# CONFIG_MAGIC_SYSRQ is not set
-+# CONFIG_DEBUG_SPINLOCK is not set
-+# CONFIG_DEBUG_WAITQ is not set
-+CONFIG_DEBUG_BUGVERBOSE=y
-+CONFIG_DEBUG_ERRORS=y
-+# CONFIG_DEBUG_LL is not set
-+# CONFIG_DEBUG_DC21285_PORT is not set
-+# CONFIG_DEBUG_CLPS711X_UART2 is not set
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/def-configs/trizeps2 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,873 @@
-+#
-+# Automatically generated by make menuconfig: don't edit
-+#
-+CONFIG_ARM=y
-+# CONFIG_EISA is not set
-+# CONFIG_SBUS is not set
-+# CONFIG_MCA is not set
-+CONFIG_UID16=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-+# CONFIG_GENERIC_BUST_SPINLOCK is not set
-+# CONFIG_GENERIC_ISA_DMA is not set
-+
-+#
-+# Code maturity level options
-+#
-+CONFIG_EXPERIMENTAL=y
-+# CONFIG_OBSOLETE is not set
-+
-+#
-+# Loadable module support
-+#
-+CONFIG_MODULES=y
-+# CONFIG_MODVERSIONS is not set
-+CONFIG_KMOD=y
-+
-+#
-+# System Type
-+#
-+# CONFIG_ARCH_ANAKIN is not set
-+# CONFIG_ARCH_ARCA5K is not set
-+# CONFIG_ARCH_CLPS7500 is not set
-+# CONFIG_ARCH_CLPS711X is not set
-+# CONFIG_ARCH_CO285 is not set
-+CONFIG_ARCH_PXA=y
-+# CONFIG_ARCH_EBSA110 is not set
-+# CONFIG_ARCH_CAMELOT is not set
-+# CONFIG_ARCH_FOOTBRIDGE is not set
-+# CONFIG_ARCH_INTEGRATOR is not set
-+# CONFIG_ARCH_OMAHA is not set
-+# CONFIG_ARCH_L7200 is not set
-+# CONFIG_ARCH_MX1ADS is not set
-+# CONFIG_ARCH_RPC is not set
-+# CONFIG_ARCH_RISCSTATION is not set
-+# CONFIG_ARCH_SA1100 is not set
-+# CONFIG_ARCH_SHARK is not set
-+
-+#
-+# Archimedes/A5000 Implementations
-+#
-+# CONFIG_ARCH_ARC is not set
-+# CONFIG_ARCH_A5K is not set
-+
-+#
-+# Footbridge Implementations
-+#
-+# CONFIG_ARCH_CATS is not set
-+# CONFIG_ARCH_PERSONAL_SERVER is not set
-+# CONFIG_ARCH_EBSA285_ADDIN is not set
-+# CONFIG_ARCH_EBSA285_HOST is not set
-+# CONFIG_ARCH_NETWINDER is not set
-+
-+#
-+# SA11x0 Implementations
-+#
-+# CONFIG_SA1100_ACCELENT is not set
-+# CONFIG_SA1100_ASSABET is not set
-+# CONFIG_ASSABET_NEPONSET is not set
-+# CONFIG_SA1100_ADSBITSY is not set
-+# CONFIG_SA1100_BRUTUS is not set
-+# CONFIG_SA1100_CEP is not set
-+# CONFIG_SA1100_CERF is not set
-+# CONFIG_SA1100_H3100 is not set
-+# CONFIG_SA1100_H3600 is not set
-+# CONFIG_SA1100_H3800 is not set
-+# CONFIG_SA1100_H3XXX is not set
-+# CONFIG_SA1100_EXTENEX1 is not set
-+# CONFIG_SA1100_FLEXANET is not set
-+# CONFIG_SA1100_FREEBIRD is not set
-+# CONFIG_SA1100_FRODO is not set
-+# CONFIG_SA1100_GRAPHICSCLIENT is not set
-+# CONFIG_SA1100_GRAPHICSMASTER is not set
-+# CONFIG_SA1100_BADGE4 is not set
-+# CONFIG_SA1100_JORNADA720 is not set
-+# CONFIG_SA1100_HUW_WEBPANEL is not set
-+# CONFIG_SA1100_ITSY is not set
-+# CONFIG_SA1100_LART is not set
-+# CONFIG_SA1100_NANOENGINE is not set
-+# CONFIG_SA1100_OMNIMETER is not set
-+# CONFIG_SA1100_PANGOLIN is not set
-+# CONFIG_SA1100_PLEB is not set
-+# CONFIG_SA1100_PT_SYSTEM3 is not set
-+# CONFIG_SA1100_SHANNON is not set
-+# CONFIG_SA1100_SHERMAN is not set
-+# CONFIG_SA1100_SIMPAD is not set
-+# CONFIG_SA1100_SIMPUTER is not set
-+# CONFIG_SA1100_PFS168 is not set
-+# CONFIG_SA1100_VICTOR is not set
-+# CONFIG_SA1100_XP860 is not set
-+# CONFIG_SA1100_YOPY is not set
-+# CONFIG_SA1100_USB is not set
-+# CONFIG_SA1100_USB_NETLINK is not set
-+# CONFIG_SA1100_USB_CHAR is not set
-+# CONFIG_H3600_SLEEVE is not set
-+
-+#
-+# Intel PXA250/210 Implementations
-+#
-+# CONFIG_ARCH_LUBBOCK is not set
-+# CONFIG_ARCH_PXA_IDP is not set
-+# CONFIG_ARCH_PXA_CERF is not set
-+CONFIG_ARCH_TRIZEPS2=y
-+CONFIG_TRIZEPS2=y
-+CONFIG_PXA_USB=y
-+# CONFIG_PXA_USB_NETLINK is not set
-+# CONFIG_PXA_USB_CHAR is not set
-+
-+#
-+# CLPS711X/EP721X Implementations
-+#
-+# CONFIG_ARCH_AUTCPU12 is not set
-+# CONFIG_ARCH_CDB89712 is not set
-+# CONFIG_ARCH_CLEP7312 is not set
-+# CONFIG_ARCH_EDB7211 is not set
-+# CONFIG_ARCH_P720T is not set
-+# CONFIG_ARCH_FORTUNET is not set
-+# CONFIG_ARCH_EP7211 is not set
-+# CONFIG_ARCH_EP7212 is not set
-+# CONFIG_ARCH_ACORN is not set
-+# CONFIG_FOOTBRIDGE is not set
-+# CONFIG_FOOTBRIDGE_HOST is not set
-+# CONFIG_FOOTBRIDGE_ADDIN is not set
-+CONFIG_CPU_32=y
-+# CONFIG_CPU_26 is not set
-+# CONFIG_CPU_ARM610 is not set
-+# CONFIG_CPU_ARM710 is not set
-+# CONFIG_CPU_ARM720T is not set
-+# CONFIG_CPU_ARM920T is not set
-+# CONFIG_CPU_ARM922T is not set
-+# CONFIG_PLD is not set
-+# CONFIG_CPU_ARM926T is not set
-+# CONFIG_CPU_ARM1020 is not set
-+# CONFIG_CPU_ARM1026 is not set
-+# CONFIG_CPU_SA110 is not set
-+# CONFIG_CPU_SA1100 is not set
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_XSCALE=y
-+# CONFIG_XSCALE_CACHE_ERRATA is not set
-+# CONFIG_CPU_32v3 is not set
-+# CONFIG_CPU_32v4 is not set
-+# CONFIG_DISCONTIGMEM is not set
-+
-+#
-+# General setup
-+#
-+# CONFIG_PCI is not set
-+# CONFIG_ISA is not set
-+# CONFIG_ISA_DMA is not set
-+# CONFIG_ZBOOT_ROM is not set
-+CONFIG_ZBOOT_ROM_TEXT=0
-+CONFIG_ZBOOT_ROM_BSS=0
-+CONFIG_HOTPLUG=y
-+
-+#
-+# PCMCIA/CardBus support
-+#
-+CONFIG_PCMCIA=y
-+# CONFIG_I82092 is not set
-+# CONFIG_I82365 is not set
-+# CONFIG_TCIC is not set
-+# CONFIG_PCMCIA_CLPS6700 is not set
-+# CONFIG_PCMCIA_SA1100 is not set
-+CONFIG_PCMCIA_PXA=y
-+CONFIG_NET=y
-+CONFIG_SYSVIPC=y
-+# CONFIG_BSD_PROCESS_ACCT is not set
-+CONFIG_SYSCTL=y
-+CONFIG_FPE_NWFPE=y
-+# CONFIG_FPE_FASTFPE is not set
-+CONFIG_KCORE_ELF=y
-+# CONFIG_KCORE_AOUT is not set
-+# CONFIG_BINFMT_AOUT is not set
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_MISC is not set
-+# CONFIG_PM is not set
-+# CONFIG_ARTHUR is not set
-+CONFIG_CMDLINE="root=/dev/mtdblock3 rw console=ttyS0,38400 mem=32M noinitrd init=/linuxrc"
-+CONFIG_ALIGNMENT_TRAP=y
-+
-+#
-+# Parallel port support
-+#
-+# CONFIG_PARPORT is not set
-+
-+#
-+# Memory Technology Devices (MTD)
-+#
-+CONFIG_MTD=y
-+# CONFIG_MTD_DEBUG is not set
-+CONFIG_MTD_PARTITIONS=y
-+# CONFIG_MTD_CONCAT is not set
-+CONFIG_MTD_REDBOOT_PARTS=y
-+CONFIG_MTD_CMDLINE_PARTS=y
-+# CONFIG_MTD_AFS_PARTS is not set
-+CONFIG_MTD_CHAR=y
-+CONFIG_MTD_BLOCK=y
-+# CONFIG_FTL is not set
-+# CONFIG_NFTL is not set
-+
-+#
-+# RAM/ROM/Flash chip drivers
-+#
-+CONFIG_MTD_CFI=y
-+# CONFIG_MTD_JEDECPROBE is not set
-+CONFIG_MTD_GEN_PROBE=y
-+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-+CONFIG_MTD_CFI_INTELEXT=y
-+# CONFIG_MTD_CFI_AMDSTD is not set
-+# CONFIG_MTD_RAM is not set
-+# CONFIG_MTD_ROM is not set
-+# CONFIG_MTD_ABSENT is not set
-+# CONFIG_MTD_OBSOLETE_CHIPS is not set
-+# CONFIG_MTD_AMDSTD is not set
-+# CONFIG_MTD_SHARP is not set
-+# CONFIG_MTD_JEDEC is not set
-+
-+#
-+# Mapping drivers for chip access
-+#
-+# CONFIG_MTD_PHYSMAP is not set
-+# CONFIG_MTD_LUBBOCK is not set
-+# CONFIG_MTD_NORA is not set
-+# CONFIG_MTD_ARM_INTEGRATOR is not set
-+# CONFIG_MTD_CDB89712 is not set
-+# CONFIG_MTD_SA1100 is not set
-+# CONFIG_MTD_DC21285 is not set
-+# CONFIG_MTD_IQ80310 is not set
-+# CONFIG_MTD_FORTUNET is not set
-+# CONFIG_MTD_PXA_CERF is not set
-+# CONFIG_MTD_EPXA10DB is not set
-+# CONFIG_MTD_AUTCPU12 is not set
-+# CONFIG_MTD_EDB7312 is not set
-+# CONFIG_MTD_IMPA7 is not set
-+CONFIG_MTD_TRIZEPS2=y
-+# CONFIG_MTD_PCI is not set
-+
-+#
-+# Self-contained MTD device drivers
-+#
-+# CONFIG_MTD_PMC551 is not set
-+# CONFIG_MTD_SLRAM is not set
-+# CONFIG_MTD_MTDRAM is not set
-+# CONFIG_MTD_BLKMTD is not set
-+# CONFIG_MTD_DOC1000 is not set
-+# CONFIG_MTD_DOC2000 is not set
-+# CONFIG_MTD_DOC2001 is not set
-+# CONFIG_MTD_DOCPROBE is not set
-+
-+#
-+# NAND Flash Device Drivers
-+#
-+# CONFIG_MTD_NAND is not set
-+
-+#
-+# Plug and Play configuration
-+#
-+# CONFIG_PNP is not set
-+# CONFIG_ISAPNP is not set
-+
-+#
-+# Block devices
-+#
-+# CONFIG_BLK_DEV_FD is not set
-+# CONFIG_BLK_DEV_XD is not set
-+# CONFIG_PARIDE is not set
-+# CONFIG_BLK_CPQ_DA is not set
-+# CONFIG_BLK_CPQ_CISS_DA is not set
-+# CONFIG_CISS_SCSI_TAPE is not set
-+# CONFIG_BLK_DEV_DAC960 is not set
-+# CONFIG_BLK_DEV_UMEM is not set
-+CONFIG_BLK_DEV_LOOP=y
-+# CONFIG_BLK_DEV_NBD is not set
-+# CONFIG_BLK_DEV_RAM is not set
-+# CONFIG_BLK_DEV_INITRD is not set
-+
-+#
-+# Multi-device support (RAID and LVM)
-+#
-+# CONFIG_MD is not set
-+# CONFIG_BLK_DEV_MD is not set
-+# CONFIG_MD_LINEAR is not set
-+# CONFIG_MD_RAID0 is not set
-+# CONFIG_MD_RAID1 is not set
-+# CONFIG_MD_RAID5 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_BLK_DEV_LVM is not set
-+
-+#
-+# Networking options
-+#
-+# CONFIG_PACKET is not set
-+# CONFIG_NETLINK_DEV is not set
-+# CONFIG_NETFILTER is not set
-+# CONFIG_FILTER is not set
-+CONFIG_UNIX=y
-+CONFIG_INET=y
-+# CONFIG_IP_MULTICAST is not set
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+CONFIG_IP_PNP=y
-+# CONFIG_IP_PNP_DHCP is not set
-+CONFIG_IP_PNP_BOOTP=y
-+# CONFIG_IP_PNP_RARP is not set
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_ARPD is not set
-+# CONFIG_INET_ECN is not set
-+# CONFIG_SYN_COOKIES is not set
-+# CONFIG_IPV6 is not set
-+# CONFIG_KHTTPD is not set
-+# CONFIG_ATM is not set
-+# CONFIG_VLAN_8021Q is not set
-+# CONFIG_IPX is not set
-+# CONFIG_ATALK is not set
-+
-+#
-+# Appletalk devices
-+#
-+# CONFIG_DEV_APPLETALK is not set
-+# CONFIG_DECNET is not set
-+# CONFIG_BRIDGE is not set
-+# CONFIG_X25 is not set
-+# CONFIG_LAPB is not set
-+# CONFIG_LLC is not set
-+# CONFIG_NET_DIVERT is not set
-+# CONFIG_ECONET is not set
-+# CONFIG_WAN_ROUTER is not set
-+# CONFIG_NET_FASTROUTE is not set
-+# CONFIG_NET_HW_FLOWCONTROL is not set
-+
-+#
-+# QoS and/or fair queueing
-+#
-+# CONFIG_NET_SCHED is not set
-+
-+#
-+# Network testing
-+#
-+# CONFIG_NET_PKTGEN is not set
-+
-+#
-+# Network device support
-+#
-+CONFIG_NETDEVICES=y
-+
-+#
-+# ARCnet devices
-+#
-+# CONFIG_ARCNET is not set
-+# CONFIG_DUMMY is not set
-+# CONFIG_BONDING is not set
-+# CONFIG_EQUALIZER is not set
-+# CONFIG_TUN is not set
-+# CONFIG_ETHERTAP is not set
-+
-+#
-+# Ethernet (10 or 100Mbit)
-+#
-+CONFIG_NET_ETHERNET=y
-+# CONFIG_ARM_AM79C961A is not set
-+# CONFIG_ARM_CIRRUS is not set
-+# CONFIG_SUNLANCE is not set
-+# CONFIG_SUNBMAC is not set
-+# CONFIG_SUNQE is not set
-+# CONFIG_SUNGEM is not set
-+# CONFIG_NET_VENDOR_3COM is not set
-+# CONFIG_LANCE is not set
-+CONFIG_NET_VENDOR_SMC=y
-+# CONFIG_WD80x3 is not set
-+# CONFIG_ULTRAMCA is not set
-+# CONFIG_ULTRA is not set
-+# CONFIG_ULTRA32 is not set
-+CONFIG_SMC9194=y
-+# CONFIG_NET_VENDOR_RACAL is not set
-+# CONFIG_NET_ISA is not set
-+# CONFIG_NET_PCI is not set
-+# CONFIG_NET_POCKET is not set
-+
-+#
-+# Ethernet (1000 Mbit)
-+#
-+# CONFIG_ACENIC is not set
-+# CONFIG_DL2K is not set
-+# CONFIG_MYRI_SBUS is not set
-+# CONFIG_NS83820 is not set
-+# CONFIG_HAMACHI is not set
-+# CONFIG_YELLOWFIN is not set
-+# CONFIG_SK98LIN is not set
-+# CONFIG_TIGON3 is not set
-+# CONFIG_FDDI is not set
-+# CONFIG_HIPPI is not set
-+# CONFIG_PLIP is not set
-+CONFIG_PPP=m
-+# CONFIG_PPP_MULTILINK is not set
-+# CONFIG_PPP_FILTER is not set
-+CONFIG_PPP_ASYNC=m
-+CONFIG_PPP_SYNC_TTY=m
-+CONFIG_PPP_DEFLATE=m
-+CONFIG_PPP_BSDCOMP=m
-+# CONFIG_PPPOE is not set
-+# CONFIG_SLIP is not set
-+
-+#
-+# Wireless LAN (non-hamradio)
-+#
-+CONFIG_NET_RADIO=y
-+# CONFIG_STRIP is not set
-+# CONFIG_WAVELAN is not set
-+# CONFIG_ARLAN is not set
-+# CONFIG_AIRONET4500 is not set
-+# CONFIG_AIRONET4500_NONCS is not set
-+# CONFIG_AIRONET4500_PROC is not set
-+# CONFIG_HERMES is not set
-+# CONFIG_PCMCIA_HERMES is not set
-+CONFIG_AIRO_CS=m
-+CONFIG_NET_WIRELESS=y
-+
-+#
-+# Token Ring devices
-+#
-+# CONFIG_TR is not set
-+# CONFIG_NET_FC is not set
-+# CONFIG_RCPCI is not set
-+# CONFIG_SHAPER is not set
-+
-+#
-+# Wan interfaces
-+#
-+# CONFIG_WAN is not set
-+
-+#
-+# PCMCIA network device support
-+#
-+CONFIG_NET_PCMCIA=y
-+# CONFIG_PCMCIA_3C589 is not set
-+CONFIG_PCMCIA_3C574=m
-+# CONFIG_PCMCIA_FMVJ18X is not set
-+# CONFIG_PCMCIA_PCNET is not set
-+# CONFIG_PCMCIA_AXNET is not set
-+# CONFIG_PCMCIA_NMCLAN is not set
-+# CONFIG_PCMCIA_SMC91C92 is not set
-+# CONFIG_PCMCIA_XIRC2PS is not set
-+# CONFIG_ARCNET_COM20020_CS is not set
-+# CONFIG_PCMCIA_IBMTR is not set
-+CONFIG_NET_PCMCIA_RADIO=y
-+# CONFIG_PCMCIA_RAYCS is not set
-+# CONFIG_PCMCIA_NETWAVE is not set
-+# CONFIG_PCMCIA_WAVELAN is not set
-+# CONFIG_AIRONET4500_CS is not set
-+
-+#
-+# Amateur Radio support
-+#
-+# CONFIG_HAMRADIO is not set
-+
-+#
-+# IrDA (infrared) support
-+#
-+# CONFIG_IRDA is not set
-+
-+#
-+# ATA/ATAPI/MFM/RLL support
-+#
-+CONFIG_IDE=m
-+
-+#
-+# IDE, ATA and ATAPI Block devices
-+#
-+CONFIG_BLK_DEV_IDE=m
-+# CONFIG_BLK_DEV_HD_IDE is not set
-+# CONFIG_BLK_DEV_HD is not set
-+CONFIG_BLK_DEV_IDEDISK=m
-+# CONFIG_IDEDISK_MULTI_MODE is not set
-+# CONFIG_IDEDISK_STROKE is not set
-+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-+# CONFIG_BLK_DEV_IDEDISK_WD is not set
-+# CONFIG_BLK_DEV_COMMERIAL is not set
-+# CONFIG_BLK_DEV_TIVO is not set
-+CONFIG_BLK_DEV_IDECS=m
-+# CONFIG_BLK_DEV_IDECD is not set
-+# CONFIG_BLK_DEV_IDETAPE is not set
-+# CONFIG_BLK_DEV_IDEFLOPPY is not set
-+# CONFIG_BLK_DEV_IDESCSI is not set
-+# CONFIG_IDE_TASK_IOCTL is not set
-+# CONFIG_BLK_DEV_CMD640 is not set
-+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-+# CONFIG_BLK_DEV_ISAPNP is not set
-+# CONFIG_IDE_CHIPSETS is not set
-+# CONFIG_IDEDMA_AUTO is not set
-+# CONFIG_DMA_NONPCI is not set
-+# CONFIG_BLK_DEV_IDE_MODES is not set
-+# CONFIG_BLK_DEV_ATARAID is not set
-+# CONFIG_BLK_DEV_ATARAID_PDC is not set
-+# CONFIG_BLK_DEV_ATARAID_HPT is not set
-+
-+#
-+# SCSI support
-+#
-+# CONFIG_SCSI is not set
-+
-+#
-+# I2O device support
-+#
-+# CONFIG_I2O is not set
-+# CONFIG_I2O_BLOCK is not set
-+# CONFIG_I2O_LAN is not set
-+# CONFIG_I2O_SCSI is not set
-+# CONFIG_I2O_PROC is not set
-+
-+#
-+# ISDN subsystem
-+#
-+# CONFIG_ISDN is not set
-+
-+#
-+# Input core support
-+#
-+# CONFIG_INPUT is not set
-+# CONFIG_INPUT_KEYBDEV is not set
-+# CONFIG_INPUT_MOUSEDEV is not set
-+# CONFIG_INPUT_JOYDEV is not set
-+# CONFIG_INPUT_EVDEV is not set
-+
-+#
-+# Character devices
-+#
-+CONFIG_VT=y
-+# CONFIG_VT_CONSOLE is not set
-+CONFIG_SERIAL=y
-+CONFIG_SERIAL_CONSOLE=y
-+# CONFIG_SERIAL_EXTENDED is not set
-+# CONFIG_SERIAL_NONSTANDARD is not set
-+
-+#
-+# Serial drivers
-+#
-+# CONFIG_SERIAL_ANAKIN is not set
-+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-+# CONFIG_SERIAL_AMBA is not set
-+# CONFIG_SERIAL_AMBA_CONSOLE is not set
-+# CONFIG_SERIAL_CLPS711X is not set
-+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-+# CONFIG_SERIAL_21285 is not set
-+# CONFIG_SERIAL_21285_OLD is not set
-+# CONFIG_SERIAL_21285_CONSOLE is not set
-+# CONFIG_SERIAL_UART00 is not set
-+# CONFIG_SERIAL_UART00_CONSOLE is not set
-+# CONFIG_SERIAL_SA1100 is not set
-+# CONFIG_SERIAL_SA1100_CONSOLE is not set
-+# CONFIG_SERIAL_OMAHA is not set
-+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
-+# CONFIG_SERIAL_8250 is not set
-+# CONFIG_SERIAL_8250_CONSOLE is not set
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+# CONFIG_SERIAL_8250_MANY_PORTS is not set
-+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-+# CONFIG_SERIAL_8250_MULTIPORT is not set
-+# CONFIG_SERIAL_8250_HUB6 is not set
-+CONFIG_UNIX98_PTYS=y
-+CONFIG_UNIX98_PTY_COUNT=256
-+
-+#
-+# I2C support
-+#
-+CONFIG_I2C=y
-+# CONFIG_I2C_ALGOBIT is not set
-+# CONFIG_I2C_ALGOPCF is not set
-+CONFIG_I2C_PXA_ALGO=y
-+CONFIG_I2C_PXA_ADAP=y
-+CONFIG_I2C_CHARDEV=y
-+CONFIG_I2C_PROC=y
-+# CONFIG_I2C_DS1307 is not set
-+
-+#
-+# L3 serial bus support
-+#
-+# CONFIG_L3 is not set
-+# CONFIG_L3_ALGOBIT is not set
-+# CONFIG_L3_BIT_SA1100_GPIO is not set
-+# CONFIG_L3_SA1111 is not set
-+# CONFIG_BIT_SA1100_GPIO is not set
-+
-+#
-+# Mice
-+#
-+# CONFIG_BUSMOUSE is not set
-+# CONFIG_MOUSE is not set
-+
-+#
-+# Joysticks
-+#
-+# CONFIG_INPUT_GAMEPORT is not set
-+# CONFIG_QIC02_TAPE is not set
-+
-+#
-+# Watchdog Cards
-+#
-+# CONFIG_WATCHDOG is not set
-+# CONFIG_NVRAM is not set
-+# CONFIG_RTC is not set
-+CONFIG_PXA_RTC=y
-+# CONFIG_DTLK is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_APPLICOM is not set
-+
-+#
-+# Ftape, the floppy tape device driver
-+#
-+# CONFIG_FTAPE is not set
-+# CONFIG_AGP is not set
-+# CONFIG_DRM is not set
-+
-+#
-+# PCMCIA character devices
-+#
-+# CONFIG_PCMCIA_SERIAL_CS is not set
-+CONFIG_TRIZEPS2_TTLIO=m
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+
-+#
-+# File systems
-+#
-+# CONFIG_QUOTA is not set
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+# CONFIG_REISERFS_FS is not set
-+# CONFIG_REISERFS_CHECK is not set
-+# CONFIG_REISERFS_PROC_INFO is not set
-+# CONFIG_ADFS_FS is not set
-+# CONFIG_ADFS_FS_RW is not set
-+# CONFIG_AFFS_FS is not set
-+# CONFIG_HFS_FS is not set
-+# CONFIG_BFS_FS is not set
-+CONFIG_EXT3_FS=y
-+CONFIG_JBD=y
-+# CONFIG_JBD_DEBUG is not set
-+CONFIG_FAT_FS=m
-+CONFIG_MSDOS_FS=m
-+# CONFIG_UMSDOS_FS is not set
-+CONFIG_VFAT_FS=m
-+# CONFIG_EFS_FS is not set
-+# CONFIG_JFFS_FS is not set
-+CONFIG_JFFS2_FS=y
-+CONFIG_JFFS2_FS_DEBUG=0
-+# CONFIG_CRAMFS is not set
-+CONFIG_TMPFS=y
-+CONFIG_RAMFS=y
-+# CONFIG_ISO9660_FS is not set
-+# CONFIG_JOLIET is not set
-+# CONFIG_ZISOFS is not set
-+# CONFIG_MINIX_FS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_NTFS_FS is not set
-+# CONFIG_NTFS_RW is not set
-+# CONFIG_HPFS_FS is not set
-+CONFIG_PROC_FS=y
-+# CONFIG_DEVFS_FS is not set
-+# CONFIG_DEVFS_MOUNT is not set
-+# CONFIG_DEVFS_DEBUG is not set
-+CONFIG_DEVPTS_FS=y
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_QNX4FS_RW is not set
-+# CONFIG_ROMFS_FS is not set
-+CONFIG_EXT2_FS=y
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UDF_FS is not set
-+# CONFIG_UDF_RW is not set
-+# CONFIG_UFS_FS is not set
-+# CONFIG_UFS_FS_WRITE is not set
-+
-+#
-+# Network File Systems
-+#
-+# CONFIG_CODA_FS is not set
-+# CONFIG_INTERMEZZO_FS is not set
-+CONFIG_NFS_FS=m
-+# CONFIG_NFS_V3 is not set
-+# CONFIG_ROOT_NFS is not set
-+# CONFIG_NFSD is not set
-+# CONFIG_NFSD_V3 is not set
-+CONFIG_SUNRPC=m
-+CONFIG_LOCKD=m
-+# CONFIG_SMB_FS is not set
-+# CONFIG_NCP_FS is not set
-+# CONFIG_NCPFS_PACKET_SIGNING is not set
-+# CONFIG_NCPFS_IOCTL_LOCKING is not set
-+# CONFIG_NCPFS_STRONG is not set
-+# CONFIG_NCPFS_NFS_NS is not set
-+# CONFIG_NCPFS_OS2_NS is not set
-+# CONFIG_NCPFS_SMALLDOS is not set
-+# CONFIG_NCPFS_NLS is not set
-+# CONFIG_NCPFS_EXTRAS is not set
-+# CONFIG_ZISOFS_FS is not set
-+# CONFIG_ZLIB_FS_INFLATE is not set
-+
-+#
-+# Partition Types
-+#
-+# CONFIG_PARTITION_ADVANCED is not set
-+CONFIG_MSDOS_PARTITION=y
-+# CONFIG_SMB_NLS is not set
-+CONFIG_NLS=y
-+
-+#
-+# Native Language Support
-+#
-+CONFIG_NLS_DEFAULT="iso8859-1"
-+# CONFIG_NLS_CODEPAGE_437 is not set
-+# CONFIG_NLS_CODEPAGE_737 is not set
-+# CONFIG_NLS_CODEPAGE_775 is not set
-+# CONFIG_NLS_CODEPAGE_850 is not set
-+# CONFIG_NLS_CODEPAGE_852 is not set
-+# CONFIG_NLS_CODEPAGE_855 is not set
-+# CONFIG_NLS_CODEPAGE_857 is not set
-+# CONFIG_NLS_CODEPAGE_860 is not set
-+# CONFIG_NLS_CODEPAGE_861 is not set
-+# CONFIG_NLS_CODEPAGE_862 is not set
-+# CONFIG_NLS_CODEPAGE_863 is not set
-+# CONFIG_NLS_CODEPAGE_864 is not set
-+# CONFIG_NLS_CODEPAGE_865 is not set
-+# CONFIG_NLS_CODEPAGE_866 is not set
-+# CONFIG_NLS_CODEPAGE_869 is not set
-+# CONFIG_NLS_CODEPAGE_936 is not set
-+# CONFIG_NLS_CODEPAGE_950 is not set
-+# CONFIG_NLS_CODEPAGE_932 is not set
-+# CONFIG_NLS_CODEPAGE_949 is not set
-+# CONFIG_NLS_CODEPAGE_874 is not set
-+# CONFIG_NLS_ISO8859_8 is not set
-+# CONFIG_NLS_CODEPAGE_1250 is not set
-+# CONFIG_NLS_CODEPAGE_1251 is not set
-+CONFIG_NLS_ISO8859_1=y
-+# CONFIG_NLS_ISO8859_2 is not set
-+# CONFIG_NLS_ISO8859_3 is not set
-+# CONFIG_NLS_ISO8859_4 is not set
-+# CONFIG_NLS_ISO8859_5 is not set
-+# CONFIG_NLS_ISO8859_6 is not set
-+# CONFIG_NLS_ISO8859_7 is not set
-+# CONFIG_NLS_ISO8859_9 is not set
-+# CONFIG_NLS_ISO8859_13 is not set
-+# CONFIG_NLS_ISO8859_14 is not set
-+# CONFIG_NLS_ISO8859_15 is not set
-+# CONFIG_NLS_KOI8_R is not set
-+# CONFIG_NLS_KOI8_U is not set
-+# CONFIG_NLS_UTF8 is not set
-+
-+#
-+# Console drivers
-+#
-+CONFIG_PC_KEYMAP=y
-+# CONFIG_VGA_CONSOLE is not set
-+
-+#
-+# Frame-buffer support
-+#
-+CONFIG_FB=y
-+CONFIG_DUMMY_CONSOLE=y
-+# CONFIG_FB_ACORN is not set
-+# CONFIG_FB_ANAKIN is not set
-+# CONFIG_FB_CLPS711X is not set
-+# CONFIG_FB_SA1100 is not set
-+CONFIG_FB_PXA=y
-+# CONFIG_FB_CYBER2000 is not set
-+# CONFIG_FB_VIRTUAL is not set
-+CONFIG_FBCON_ADVANCED=y
-+# CONFIG_FBCON_MFB is not set
-+# CONFIG_FBCON_CFB2 is not set
-+# CONFIG_FBCON_CFB4 is not set
-+# CONFIG_FBCON_CFB8 is not set
-+CONFIG_FBCON_CFB16=y
-+# CONFIG_FBCON_CFB24 is not set
-+# CONFIG_FBCON_CFB32 is not set
-+# CONFIG_FBCON_AFB is not set
-+# CONFIG_FBCON_ILBM is not set
-+# CONFIG_FBCON_IPLAN2P2 is not set
-+# CONFIG_FBCON_IPLAN2P4 is not set
-+# CONFIG_FBCON_IPLAN2P8 is not set
-+# CONFIG_FBCON_MAC is not set
-+# CONFIG_FBCON_VGA_PLANES is not set
-+# CONFIG_FBCON_VGA is not set
-+# CONFIG_FBCON_HGA is not set
-+CONFIG_FBCON_FONTWIDTH8_ONLY=y
-+CONFIG_FBCON_FONTS=y
-+# CONFIG_FONT_8x8 is not set
-+# CONFIG_FONT_8x16 is not set
-+# CONFIG_FONT_SUN8x16 is not set
-+# CONFIG_FONT_PEARL_8x8 is not set
-+CONFIG_FONT_ACORN_8x8=y
-+
-+#
-+# Sound
-+#
-+CONFIG_SOUND=y
-+# CONFIG_SOUND_BT878 is not set
-+# CONFIG_SOUND_CMPCI is not set
-+# CONFIG_SOUND_EMU10K1 is not set
-+# CONFIG_MIDI_EMU10K1 is not set
-+# CONFIG_SOUND_FUSION is not set
-+# CONFIG_SOUND_CS4281 is not set
-+# CONFIG_SOUND_ES1370 is not set
-+# CONFIG_SOUND_ES1371 is not set
-+# CONFIG_SOUND_ESSSOLO1 is not set
-+# CONFIG_SOUND_MAESTRO is not set
-+# CONFIG_SOUND_MAESTRO3 is not set
-+# CONFIG_SOUND_ICH is not set
-+# CONFIG_SOUND_RME96XX is not set
-+# CONFIG_SOUND_SONICVIBES is not set
-+# CONFIG_SOUND_TRIDENT is not set
-+# CONFIG_SOUND_MSNDCLAS is not set
-+# CONFIG_SOUND_MSNDPIN is not set
-+# CONFIG_SOUND_VIA82CXXX is not set
-+# CONFIG_MIDI_VIA82CXXX is not set
-+# CONFIG_SOUND_OSS is not set
-+# CONFIG_SOUND_WAVEARTIST is not set
-+CONFIG_SOUND_PXA_AC97=y
-+# CONFIG_SOUND_TVMIXER is not set
-+
-+#
-+# Multimedia Capabilities Port drivers
-+#
-+CONFIG_MCP=y
-+# CONFIG_MCP_SA1100 is not set
-+# CONFIG_MCP_UCB1200 is not set
-+# CONFIG_MCP_UCB1200_AUDIO is not set
-+# CONFIG_MCP_UCB1200_TS is not set
-+CONFIG_MCP_UCB1400_TS=y
-+CONFIG_MCP_UCB1X00_TS_COMPAT=y
-+
-+#
-+# USB support
-+#
-+# CONFIG_USB is not set
-+
-+#
-+# Bluetooth support
-+#
-+# CONFIG_BLUEZ is not set
-+
-+#
-+# Kernel hacking
-+#
-+CONFIG_FRAME_POINTER=y
-+CONFIG_DEBUG_USER=y
-+CONFIG_DEBUG_INFO=y
-+# CONFIG_NO_PGT_CACHE is not set
-+CONFIG_DEBUG_KERNEL=y
-+# CONFIG_DEBUG_SLAB is not set
-+CONFIG_MAGIC_SYSRQ=y
-+# CONFIG_DEBUG_SPINLOCK is not set
-+# CONFIG_DEBUG_WAITQ is not set
-+CONFIG_DEBUG_BUGVERBOSE=y
-+CONFIG_DEBUG_ERRORS=y
-+CONFIG_DEBUG_LL=y
-+# CONFIG_DEBUG_DC21285_PORT is not set
-+# CONFIG_DEBUG_CLPS711X_UART2 is not set
---- linux-2.4.25/arch/arm/kernel/Makefile~2.4.25-vrs2-pxa1.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/kernel/Makefile 2004-03-31 17:15:11.000000000 +0200
-@@ -10,7 +10,7 @@
- HEAD_OBJ = head-$(PROCESSOR).o
- ENTRY_OBJ = entry-$(PROCESSOR).o
-
--AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR)
-+AFLAGS_head-armv.o := -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR)
- AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR)
-
- # This is depreciated.
-@@ -45,7 +45,7 @@
- $(CONFIG_FOOTBRIDGE) $(CONFIG_ARCH_EBSA110) \
- $(CONFIG_ARCH_SA1100) $(CONFIG_ARCH_CAMELOT) \
- $(CONFIG_ARCH_MX1ADS) $(CONFIG_ARCH_OMAHA) \
-- $(CONFIG_ARCH_AT91RM9200)
-+ $(CONFIG_ARCH_AT91RM9200) $(CONFIG_ARCH_PXA)
-
- ifneq ($(findstring y,$(no-irq-arch)),y)
- obj-y += irq-arch.o
---- linux-2.4.25/arch/arm/kernel/debug-armv.S~2.4.25-vrs2-pxa1.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/kernel/debug-armv.S 2004-03-31 17:15:11.000000000 +0200
-@@ -221,6 +221,31 @@
- bne 1001b
- .endm
-
-+#elif defined(CONFIG_ARCH_PXA)
-+
-+ .macro addruart,rx
-+ mrc p15, 0, \rx, c1, c0
-+ tst \rx, #1 @ MMU enabled?
-+ moveq \rx, #0x40000000 @ physical
-+ movne \rx, #io_p2v(0x40000000) @ virtual
-+ orr \rx, \rx, #0x00100000 @ FFUART
-+ .endm
-+
-+ .macro senduart,rd,rx
-+ str \rd, [\rx, #0]
-+ .endm
-+
-+ .macro busyuart,rd,rx
-+1002: ldr \rd, [\rx, #0x14]
-+ tst \rd, #(1 << 6)
-+ beq 1002b
-+ .endm
-+
-+ .macro waituart,rd,rx
-+1001: ldr \rd, [\rx, #0x14]
-+ tst \rd, #(1 << 5)
-+ beq 1001b
-+ .endm
- #elif defined(CONFIG_ARCH_CLPS7500)
- .macro addruart,rx
- mov \rx, #0xe0000000
---- linux-2.4.25/arch/arm/kernel/entry-armv.S~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:08.000000000 +0200
-+++ linux-2.4.25/arch/arm/kernel/entry-armv.S 2004-03-31 17:15:11.000000000 +0200
-@@ -615,6 +615,27 @@
- .text
- .endm
-
-+#elif CONFIG_ARCH_PXA
-+
-+ .macro disable_fiq
-+ .endm
-+
-+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
-+ mov \base, #io_p2v(0x40000000) @ IIR Ctl = 0x40d00000
-+ add \base, \base, #0x00d00000
-+ ldr \irqstat, [\base, #0] @ ICIP
-+ ldr \irqnr, [\base, #4] @ ICMR
-+ ands \irqstat, \irqstat, \irqnr
-+ beq 1001f
-+ rsb \irqnr, \irqstat, #0
-+ and \irqstat, \irqstat, \irqnr
-+ clz \irqnr, \irqstat
-+ rsb \irqnr, \irqnr, #(31 - PXA_IRQ_SKIP)
-+1001:
-+ .endm
-+
-+ .macro irq_prio_table
-+ .endm
- #else
- #error Unknown architecture
- #endif
-@@ -891,9 +912,17 @@
- stmfd sp!, {r4 - sl, fp, lr} @ Store most regs on stack
- mrs ip, cpsr
- str ip, [sp, #-4]! @ Save cpsr_SVC
-+#ifdef CONFIG_CPU_XSCALE
-+ mra r4, r5, acc0
-+ stmfd sp!, {r4, r5}
-+#endif
- str sp, [r0, #TSS_SAVE] @ Save sp_SVC
- ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC
- ldr r2, [r1, #TSS_DOMAIN]
-+#ifdef CONFIG_CPU_XSCALE
-+ ldmfd sp!, {r4, r5}
-+ mar acc0, r4, r5
-+#endif
- ldr ip, [sp], #4
- mcr p15, 0, r2, c3, c0 @ Set domain register
- msr spsr, ip @ Save tasks CPSR into SPSR for this return
---- linux-2.4.25/arch/arm/kernel/head-armv.S~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:08.000000000 +0200
-+++ linux-2.4.25/arch/arm/kernel/head-armv.S 2004-03-31 17:15:11.000000000 +0200
-@@ -30,6 +30,7 @@
- *
- * swapper_pg_dir, pgtbl and krnladr are all closely related.
- */
-+#ifndef CONFIG_XIP_KERNEL
- #if (TEXTADDR & 0xffff) != 0x8000
- #error TEXTADDR must start at 0xXXXX8000
- #endif
-@@ -41,6 +42,26 @@
- adr \reg, stext
- sub \reg, \reg, #0x4000
- .endm
-+#else
-+#if (DATAADDR & 0xffff) != 0x8000
-+#error DATAADDR must start at 0xXXXX8000
-+#endif
-+
-+#define PAGE_OFFSET 0xc0000000
-+#ifdef CONFIG_ARCH_LUBBOCK
-+#define PHYS_OFFSET 0xa0000000
-+#elif CONFIG_ARCH_OMAP
-+#define PHYS_OFFSET 0x10000000
-+#endif
-+
-+ .globl SYMBOL_NAME(swapper_pg_dir)
-+ .equ SYMBOL_NAME(swapper_pg_dir), DATAADDR - 0x4000
-+
-+ .macro pgtbl, reg, rambase
-+ ldr \reg, PGTBL
-+ add \reg, \reg, #PHYS_OFFSET - PAGE_OFFSET
-+ .endm
-+#endif
-
- /*
- * Since the page table is closely related to the kernel start address, we
-@@ -131,6 +152,32 @@
- mov r1, #MACH_TYPE_L7200
- #endif
-
-+#ifdef CONFIG_XIP_KERNEL
-+
-+#if defined(CONFIG_ARCH_LUBBOCK)
-+ mov r1, #MACH_TYPE_LUBBOCK
-+#endif
-+
-+ @ Data cache might be active.
-+ @ Be sure to flush kernel binary out of the cache,
-+ @ whatever state it is, before it is turned off.
-+ @ This is done by fetching through currently executed
-+ @ memory to be sure we hit the same cache.
-+ bic r2, pc, #0x1f
-+ add r3, r2, #0x10000 @ 64 kb is quite enough...
-+1: ldr r0, [r2], #32
-+ teq r2, r3
-+ bne 1b
-+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
-+ mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches
-+
-+ @ disabling MMU and caches
-+ mrc p15, 0, r0, c1, c0, 0 @ read control reg
-+ bic r0, r0, #0x05 @ clear DC, MMU
-+ bic r0, r0, #0x1000 @ clear Icache
-+ mcr p15, 0, r0, c1, c0, 0
-+#endif
-+
- mov r0, #F_BIT | I_BIT | MODE_SVC @ make sure svc mode
- msr cpsr_c, r0 @ and all irqs disabled
- bl __lookup_processor_type
-@@ -179,6 +226,17 @@
- */
- .align 5
- __mmap_switched:
-+#ifdef CONFIG_XIP_KERNEL
-+ ldr r3, ETEXT @ data section copy
-+ ldr r4, SDATA
-+ ldr r5, EDATA
-+1:
-+ ldr r6, [r3], #4
-+ str r6, [r4], #4
-+ cmp r4, r5
-+ blo 1b
-+#endif
-+
- adr r3, __switch_data + 4
- ldmia r3, {r4, r5, r6, r7, r8, sp}@ r2 = compat
- @ sp = stack pointer
-@@ -233,6 +291,8 @@
- teq r0, r2
- bne 1b
-
-+#ifndef CONFIG_XIP_KERNEL
-+
- /*
- * Create identity mapping for first MB of kernel to
- * cater for the MMU enable. This identity mapping
-@@ -271,6 +331,43 @@
- add r3, r8, r2 @ flags + rambase
- str r3, [r0]
-
-+#else /* CONFIG_XIP_KERNEL */
-+
-+ mov r3, pc, lsr #20
-+ mov r3, r3, lsl #20 @ phys kernel start
-+
-+ add r0, r4, r3, lsr #18
-+ orr r3, r3, r8
-+ str r3, [r0]
-+
-+ mov r0, #TEXTADDR & 0xff000000
-+ add r0, r0, #TEXTADDR & 0x00f00000 @ virt kernel start
-+ add r0, r4, r0, lsr #18
-+ add r2, r3, #4 << 20 @ kernel + 4MB
-+
-+1:
-+ str r3, [r0], #4
-+ add r3, r3, #1 << 20
-+ cmp r3, r2
-+ bne 1b
-+
-+ bic r3, r4, #0x000ff000 @ ram start
-+ add r0, r4, r3, lsr #18
-+ orr r3, r3, r8
-+ str r3, [r0], #4
-+
-+ add r0, r3, #PAGE_OFFSET - PHYS_OFFSET
-+ add r0, r4, r0, lsr #18
-+ add r2, r3, #4 << 20 @ ram + 4MB
-+
-+1:
-+ str r3, [r0], #4
-+ add r3, r3, #1 << 20
-+ cmp r3, r2
-+ bne 1b
-+
-+#endif /* CONFIG_XIP_KERNEL */
-+
- bic r8, r8, #0x0c @ turn off cacheable
- @ and bufferable bits
- #ifdef CONFIG_DEBUG_LL
-@@ -433,3 +530,13 @@
- mov pc, lr
- 2: ldmib r4, {r5, r6, r7} @ found, get results
- mov pc, lr
-+
-+#ifdef CONFIG_XIP_KERNEL
-+
-+PGTBL: .long SYMBOL_NAME(swapper_pg_dir)
-+
-+ETEXT: .long SYMBOL_NAME(_endtext)
-+SDATA: .long SYMBOL_NAME(_sdata)
-+EDATA: .long SYMBOL_NAME(__bss_start)
-+
-+#endif
---- linux-2.4.25/arch/arm/kernel/setup.c~2.4.25-vrs2-pxa1.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/kernel/setup.c 2004-03-31 17:15:11.000000000 +0200
-@@ -55,6 +55,10 @@
- extern void reboot_setup(char *str);
- extern int root_mountflags;
- extern int _stext, _text, _etext, _edata, _end;
-+#ifdef CONFIG_XIP_KERNEL
-+extern int _endtext, _sdata;
-+#endif
-+
-
- unsigned int processor_id;
- unsigned int __machine_arch_type;
-@@ -105,6 +109,109 @@
- #define lp1 io_res[1]
- #define lp2 io_res[2]
-
-+#ifdef CONFIG_CPU_32
-+static const char *cache_types[16] = {
-+ "write-through",
-+ "write-back",
-+ "write-back",
-+ "undefined 3",
-+ "undefined 4",
-+ "undefined 5",
-+ "write-back",
-+ "write-back",
-+ "undefined 8",
-+ "undefined 9",
-+ "undefined 10",
-+ "undefined 11",
-+ "undefined 12",
-+ "undefined 13",
-+ "undefined 14",
-+ "undefined 15",
-+};
-+
-+static const char *cache_clean[16] = {
-+ "not required",
-+ "read-block",
-+ "cp15 c7 ops",
-+ "undefined 3",
-+ "undefined 4",
-+ "undefined 5",
-+ "cp15 c7 ops",
-+ "cp15 c7 ops",
-+ "undefined 8",
-+ "undefined 9",
-+ "undefined 10",
-+ "undefined 11",
-+ "undefined 12",
-+ "undefined 13",
-+ "undefined 14",
-+ "undefined 15",
-+};
-+
-+static const char *cache_lockdown[16] = {
-+ "not supported",
-+ "not supported",
-+ "not supported",
-+ "undefined 3",
-+ "undefined 4",
-+ "undefined 5",
-+ "format A",
-+ "format B",
-+ "undefined 8",
-+ "undefined 9",
-+ "undefined 10",
-+ "undefined 11",
-+ "undefined 12",
-+ "undefined 13",
-+ "undefined 14",
-+ "undefined 15",
-+};
-+
-+#define CACHE_TYPE(x) (((x) >> 25) & 15)
-+#define CACHE_S(x) ((x) & (1 << 24))
-+#define CACHE_DSIZE(x) (((x) >> 12) & 4095) /* only if S=1 */
-+#define CACHE_ISIZE(x) ((x) & 4095)
-+
-+#define CACHE_SIZE(y) (((y) >> 6) & 7)
-+#define CACHE_ASSOC(y) (((y) >> 3) & 7)
-+#define CACHE_M(y) ((y) & (1 << 2))
-+#define CACHE_LINE(y) ((y) & 3)
-+
-+static inline void dump_cache(const char *prefix, unsigned int cache)
-+{
-+ unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0);
-+
-+ printk("%s size %dK associativity %d line length %d sets %d\n",
-+ prefix,
-+ mult << (8 + CACHE_SIZE(cache)),
-+ (mult << CACHE_ASSOC(cache)) >> 1,
-+ 8 << CACHE_LINE(cache),
-+ 1 << (6 + CACHE_SIZE(cache) - CACHE_ASSOC(cache) -
-+ CACHE_LINE(cache)));
-+}
-+
-+static inline void dump_cpu_cache_id(void)
-+{
-+ unsigned int cache_info;
-+
-+ asm("mrc p15, 0, %0, c0, c0, 1" : "=r" (cache_info));
-+
-+ if (cache_info == processor_id)
-+ return;
-+
-+ printk("CPU: D %s cache\n", cache_types[CACHE_TYPE(cache_info)]);
-+ if (CACHE_S(cache_info)) {
-+ dump_cache("CPU: I cache", CACHE_ISIZE(cache_info));
-+ dump_cache("CPU: D cache", CACHE_DSIZE(cache_info));
-+ } else {
-+ dump_cache("CPU: cache", CACHE_ISIZE(cache_info));
-+ }
-+}
-+
-+#else
-+#define dump_cpu_cache_id() do { } while (0)
-+#endif
-+
- static void __init setup_processor(void)
- {
- extern struct proc_info_list __proc_info_begin, __proc_info_end;
-@@ -272,7 +379,11 @@
-
- kernel_code.start = __virt_to_phys(init_mm.start_code);
- kernel_code.end = __virt_to_phys(init_mm.end_code - 1);
-+#ifndef CONFIG_XIP_KERNEL
- kernel_data.start = __virt_to_phys(init_mm.end_code);
-+#else
-+ kernel_data.start = __virt_to_phys(init_mm.start_data);
-+#endif
- kernel_data.end = __virt_to_phys(init_mm.brk - 1);
-
- for (i = 0; i < mi->nr_banks; i++) {
-@@ -531,7 +642,12 @@
- }
-
- init_mm.start_code = (unsigned long) &_text;
-+#ifndef CONFIG_XIP_KERNEL
- init_mm.end_code = (unsigned long) &_etext;
-+#else
-+ init_mm.end_code = (unsigned long) &_endtext;
-+ init_mm.start_data = (unsigned long) &_sdata;
-+#endif
- init_mm.end_data = (unsigned long) &_edata;
- init_mm.brk = (unsigned long) &_end;
-
-@@ -568,6 +684,41 @@
- NULL
- };
-
-+static const char *proc_arch[16] = {
-+ "undefined 0",
-+ "4",
-+ "4T",
-+ "5",
-+ "5T",
-+ "5TE",
-+ "undefined 6",
-+ "undefined 7",
-+ "undefined 8",
-+ "undefined 9",
-+ "undefined 10",
-+ "undefined 11",
-+ "undefined 12",
-+ "undefined 13",
-+ "undefined 14",
-+ "undefined 15"
-+};
-+
-+static void
-+c_show_cache(struct seq_file *m, const char *type, unsigned int cache)
-+{
-+ unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0);
-+
-+ seq_printf(m, "%s size\t\t: %d\n"
-+ "%s assoc\t\t: %d\n"
-+ "%s line length\t: %d\n"
-+ "%s sets\t\t: %d\n",
-+ type, mult << (8 + CACHE_SIZE(cache)),
-+ type, (mult << CACHE_ASSOC(cache)) >> 1,
-+ type, 8 << CACHE_LINE(cache),
-+ type, 1 << (6 + CACHE_SIZE(cache) - CACHE_ASSOC(cache) -
-+ CACHE_LINE(cache)));
-+}
-+
- static int c_show(struct seq_file *m, void *v)
- {
- int i;
-@@ -586,7 +737,60 @@
- if (elf_hwcap & (1 << i))
- seq_printf(m, "%s ", hwcap_str[i]);
-
-- seq_puts(m, "\n\n");
-+ seq_puts(m, "\n");
-+
-+ if ((processor_id & 0x0000f000) == 0x00000000) {
-+ /* pre-ARM7 */
-+ seq_printf(m, "CPU part\t\t: %07x\n", processor_id >> 4);
-+ } else if ((processor_id & 0x0000f000) == 0x00007000) {
-+ /* ARM7 */
-+ seq_printf(m, "CPU implementor\t: 0x%02x\n"
-+ "CPU architecture: %s\n"
-+ "CPU variant\t: 0x%02x\n"
-+ "CPU part\t: 0x%03x\n",
-+ processor_id >> 24,
-+ processor_id & (1 << 23) ? "4T" : "3",
-+ (processor_id >> 16) & 127,
-+ (processor_id >> 4) & 0xfff);
-+ } else {
-+ /* post-ARM7 */
-+ seq_printf(m, "CPU implementor\t: 0x%02x\n"
-+ "CPU architecture: %s\n"
-+ "CPU variant\t: 0x%x\n"
-+ "CPU part\t: 0x%03x\n",
-+ processor_id >> 24,
-+ proc_arch[(processor_id >> 16) & 15],
-+ (processor_id >> 20) & 15,
-+ (processor_id >> 4) & 0xfff);
-+ }
-+ seq_printf(m, "CPU revision\t: %d\n", processor_id & 15);
-+
-+#ifdef CONFIG_CPU_32
-+ {
-+ unsigned int cache_info;
-+
-+ asm("mrc p15, 0, %0, c0, c0, 1" : "=r" (cache_info));
-+ if (cache_info != processor_id) {
-+ seq_printf(m, "Cache type\t: %s\n"
-+ "Cache clean\t: %s\n"
-+ "Cache lockdown\t: %s\n"
-+ "Cache unified\t: %s\n",
-+ cache_types[CACHE_TYPE(cache_info)],
-+ cache_clean[CACHE_TYPE(cache_info)],
-+ cache_lockdown[CACHE_TYPE(cache_info)],
-+ CACHE_S(cache_info) ? "harvard" : "unified");
-+
-+ if (CACHE_S(cache_info)) {
-+ c_show_cache(m, "I", CACHE_ISIZE(cache_info));
-+ c_show_cache(m, "D", CACHE_DSIZE(cache_info));
-+ } else {
-+ c_show_cache(m, "Cache", CACHE_ISIZE(cache_info));
-+ }
-+ }
-+ }
-+#endif
-+
-+ seq_puts(m, "\n");
-
- seq_printf(m, "Hardware\t: %s\n", machine_name);
- seq_printf(m, "Revision\t: %04x\n", system_rev);
---- linux-2.4.25/arch/arm/lib/copy_page.S~2.4.25-vrs2-pxa1.patch 2001-03-07 04:44:35.000000000 +0100
-+++ linux-2.4.25/arch/arm/lib/copy_page.S 2004-03-31 17:15:11.000000000 +0200
-@@ -13,6 +13,8 @@
- #include <asm/assembler.h>
- #include <asm/constants.h>
-
-+#define COPY_COUNT (PAGE_SZ/64 PLD( -1 ))
-+
- .text
- .align 5
- /*
-@@ -23,9 +25,13 @@
- */
- ENTRY(copy_page)
- stmfd sp!, {r4, lr} @ 2
-- mov r2, #PAGE_SZ/64 @ 1
-+ PLD( pld [r1, #0] )
-+ PLD( pld [r1, #32] )
-+ mov r2, #COPY_COUNT @ 1
- ldmia r1!, {r3, r4, ip, lr} @ 4+1
--1: stmia r0!, {r3, r4, ip, lr} @ 4
-+1: PLD( pld [r1, #64] )
-+ PLD( pld [r1, #96] )
-+2: stmia r0!, {r3, r4, ip, lr} @ 4
- ldmia r1!, {r3, r4, ip, lr} @ 4+1
- stmia r0!, {r3, r4, ip, lr} @ 4
- ldmia r1!, {r3, r4, ip, lr} @ 4+1
-@@ -33,6 +39,8 @@
- ldmia r1!, {r3, r4, ip, lr} @ 4
- subs r2, r2, #1 @ 1
- stmia r0!, {r3, r4, ip, lr} @ 4
-- ldmneia r1!, {r3, r4, ip, lr} @ 4
-- bne 1b @ 1
-+ ldmgtia r1!, {r3, r4, ip, lr} @ 4
-+ bgt 1b @ 1
-+ PLD( ldmeqia r1!, {r3, r4, ip, lr} )
-+ PLD( beq 2b )
- LOADREGS(fd, sp!, {r4, pc}) @ 3
---- linux-2.4.25/arch/arm/lib/findbit.S~2.4.25-vrs2-pxa1.patch 2000-09-19 00:15:25.000000000 +0200
-+++ linux-2.4.25/arch/arm/lib/findbit.S 2004-03-31 17:15:11.000000000 +0200
-@@ -43,7 +43,15 @@
- /*
- * One or more bits in the LSB of r3 are assumed to be set.
- */
--.found: tst r3, #0x0f
-+.found:
-+#if __LINUX_ARM_ARCH__ >= 5
-+ rsb r1, r3, #0
-+ and r3, r3, r1
-+ clz r3, r3
-+ rsb r3, r3, #31
-+ add r0, r2, r3
-+#else
-+ tst r3, #0x0f
- addeq r2, r2, #4
- movne r3, r3, lsl #4
- tst r3, #0x30
-@@ -52,5 +60,6 @@
- tst r3, #0x40
- addeq r2, r2, #1
- mov r0, r2
-+#endif
- RETINSTR(mov,pc,lr)
-
---- linux-2.4.25/arch/arm/lib/getuser.S~2.4.25-vrs2-pxa1.patch 2002-08-03 02:39:42.000000000 +0200
-+++ linux-2.4.25/arch/arm/lib/getuser.S 2004-03-31 17:15:11.000000000 +0200
-@@ -18,7 +18,7 @@
- * Inputs: r0 contains the address
- * Outputs: r0 is the error code
- * r1, r2 contains the zero-extended value
-- * lr corrupted
-+ * ip, lr corrupted
- *
- * No other registers must be altered. (see include/asm-arm/uaccess.h
- * for specific ASM register usage).
-@@ -42,14 +42,14 @@
-
- .global __get_user_2
- __get_user_2:
-- bic r2, sp, #0x1f00
-- bic r2, r2, #0x00ff
-- ldr r2, [r2, #TSK_ADDR_LIMIT]
-- sub r2, r2, #2
-- cmp r0, r2
-+ bic ip, sp, #0x1f00
-+ bic ip, ip, #0x00ff
-+ ldr ip, [ip, #TSK_ADDR_LIMIT]
-+ sub ip, ip, #2
-+ cmp r0, ip
- 2: ldrlsbt r1, [r0], #1
--3: ldrlsbt r2, [r0]
-- orrls r1, r1, r2, lsl #8
-+3: ldrlsbt ip, [r0]
-+ orrls r1, r1, ip, lsl #8
- movls r0, #0
- movls pc, lr
- b __get_user_bad
---- linux-2.4.25/arch/arm/lib/memcpy.S~2.4.25-vrs2-pxa1.patch 2001-03-07 04:44:35.000000000 +0100
-+++ linux-2.4.25/arch/arm/lib/memcpy.S 2004-03-31 17:15:11.000000000 +0200
-@@ -8,6 +8,9 @@
- * published by the Free Software Foundation.
- *
- * ASM optimised string functions
-+ *
-+ * Big Endian, prefetching and code factorization provided by Nicolas Pitre:
-+ * Copyright (C) 2002-2003 MontaVista Software, Inc.
- */
- #include <linux/linkage.h>
- #include <asm/assembler.h>
-@@ -27,15 +30,16 @@
-
- /*
- * Prototype: void memcpy(void *to,const void *from,unsigned long n);
-- * ARM3: cant use memcopy here!!!
- */
- ENTRY(memcpy)
- ENTRY(memmove)
- ENTER
-- cmp r1, r0
-- bcc 19f
-+ subs ip, r0, r1
-+ cmphi r2, ip
-+ bhi 18f
- subs r2, r2, #4
- blt 6f
-+ PLD( pld [r1, #0] )
- ands ip, r0, #3
- bne 7f
- ands ip, r1, #3
-@@ -43,29 +47,59 @@
-
- 1: subs r2, r2, #8
- blt 5f
-- subs r2, r2, #0x14
-- blt 3f
--2: ldmia r1!,{r3 - r9, ip}
-- stmia r0!,{r3 - r9, ip}
-+ subs r2, r2, #20
-+ blt 4f
-+
-+ PLD( subs r2, r2, #65 )
-+ PLD( blt 3f )
-+ PLD( pld [r1, #32] )
-+
-+ PLD( @ cache alignment )
-+ PLD( ands ip, r1, #31 )
-+ PLD( pld [r1, #64] )
-+ PLD( beq 2f )
-+ PLD( rsb ip, ip, #32 )
-+ PLD( cmp r2, ip )
-+ PLD( pld [r1, #96] )
-+ PLD( blt 2f )
-+ PLD( cmp ip, #16 )
-+ PLD( sub r2, r2, ip )
-+ PLD( ldmgeia r1!, {r3 - r6} )
-+ PLD( stmgeia r0!, {r3 - r6} )
-+ PLD( beq 2f )
-+ PLD( and ip, ip, #15 )
-+ PLD( cmp ip, #8 )
-+ PLD( ldr r3, [r1], #4 )
-+ PLD( ldrge r4, [r1], #4 )
-+ PLD( ldrgt r5, [r1], #4 )
-+ PLD( str r3, [r0], #4 )
-+ PLD( strge r4, [r0], #4 )
-+ PLD( strgt r5, [r0], #4 )
-+
-+2: PLD( pld [r1, #96] )
-+3: ldmia r1!, {r3 - r9, ip}
- subs r2, r2, #32
-+ stmia r0!, {r3 - r9, ip}
- bge 2b
-- cmn r2, #16
-+ PLD( cmn r2, #65 )
-+ PLD( bge 3b )
-+ PLD( add r2, r2, #65 )
-+4: cmn r2, #16
- ldmgeia r1!, {r3 - r6}
-+ subge r2, r2, #16
- stmgeia r0!, {r3 - r6}
-- subge r2, r2, #0x10
--3: adds r2, r2, #0x14
--4: ldmgeia r1!, {r3 - r5}
-+ adds r2, r2, #20
-+ ldmgeia r1!, {r3 - r5}
-+ subge r2, r2, #12
- stmgeia r0!, {r3 - r5}
-- subges r2, r2, #12
-- bge 4b
- 5: adds r2, r2, #8
- blt 6f
- subs r2, r2, #4
- ldrlt r3, [r1], #4
- ldmgeia r1!, {r4, r5}
-+ subge r2, r2, #4
- strlt r3, [r0], #4
- stmgeia r0!, {r4, r5}
-- subge r2, r2, #4
-
- 6: adds r2, r2, #4
- EXITEQ
-@@ -92,122 +126,175 @@
- beq 1b
-
- 8: bic r1, r1, #3
-- ldr r7, [r1], #4
- cmp ip, #2
-- bgt 15f
-- beq 11f
-+ ldr lr, [r1], #4
-+ bgt 17f
-+ beq 16f
-+
-+
-+ .macro forward_copy_shift pull push
-+
- cmp r2, #12
-- blt 10f
-- sub r2, r2, #12
--9: mov r3, r7, lsr #8
-- ldmia r1!, {r4 - r7}
-- orr r3, r3, r4, lsl #24
-- mov r4, r4, lsr #8
-- orr r4, r4, r5, lsl #24
-- mov r5, r5, lsr #8
-- orr r5, r5, r6, lsl #24
-- mov r6, r6, lsr #8
-- orr r6, r6, r7, lsl #24
-+ PLD( pld [r1, #0] )
-+ blt 14f
-+ subs r2, r2, #28
-+ blt 12f
-+
-+ PLD( subs r2, r2, #97 )
-+ PLD( blt 11f )
-+ PLD( pld [r1, #32] )
-+
-+ PLD( @ cache alignment )
-+ PLD( rsb ip, r1, #36 )
-+ PLD( pld [r1, #64] )
-+ PLD( ands ip, ip, #31 )
-+ PLD( pld [r1, #96] )
-+ PLD( beq 10f )
-+ PLD( cmp r2, ip )
-+ PLD( pld [r1, #128] )
-+ PLD( blt 10f )
-+ PLD( sub r2, r2, ip )
-+9: PLD( mov r3, lr, pull #\pull )
-+ PLD( ldr lr, [r1], #4 )
-+ PLD( subs ip, ip, #4 )
-+ PLD( orr r3, r3, lr, push #\push )
-+ PLD( str r3, [r0], #4 )
-+ PLD( bgt 9b )
-+
-+10: PLD( pld [r1, #128] )
-+11: mov r3, lr, pull #\pull
-+ ldmia r1!, {r4 - r9, ip, lr}
-+ subs r2, r2, #32
-+ orr r3, r3, r4, push #\push
-+ mov r4, r4, pull #\pull
-+ orr r4, r4, r5, push #\push
-+ mov r5, r5, pull #\pull
-+ orr r5, r5, r6, push #\push
-+ mov r6, r6, pull #\pull
-+ orr r6, r6, r7, push #\push
-+ mov r7, r7, pull #\pull
-+ orr r7, r7, r8, push #\push
-+ mov r8, r8, pull #\pull
-+ orr r8, r8, r9, push #\push
-+ mov r9, r9, pull #\pull
-+ orr r9, r9, ip, push #\push
-+ mov ip, ip, pull #\pull
-+ orr ip, ip, lr, push #\push
-+ stmia r0!, {r3 - r9, ip}
-+ bge 10b
-+ PLD( cmn r2, #97 )
-+ PLD( bge 11b )
-+ PLD( add r2, r2, #97 )
-+ cmn r2, #16
-+ blt 13f
-+12: mov r3, lr, pull #\pull
-+ ldmia r1!, {r4 - r6, lr}
-+ sub r2, r2, #16
-+ orr r3, r3, r4, push #\push
-+ mov r4, r4, pull #\pull
-+ orr r4, r4, r5, push #\push
-+ mov r5, r5, pull #\pull
-+ orr r5, r5, r6, push #\push
-+ mov r6, r6, pull #\pull
-+ orr r6, r6, lr, push #\push
- stmia r0!, {r3 - r6}
-- subs r2, r2, #16
-- bge 9b
-- adds r2, r2, #12
-- blt 100f
--10: mov r3, r7, lsr #8
-- ldr r7, [r1], #4
-+13: adds r2, r2, #28
-+ blt 15f
-+14: mov r3, lr, pull #\pull
-+ ldr lr, [r1], #4
- subs r2, r2, #4
-- orr r3, r3, r7, lsl #24
-+ orr r3, r3, lr, push #\push
- str r3, [r0], #4
-- bge 10b
--100: sub r1, r1, #3
-+ bge 14b
-+15:
-+ .endm
-+
-+
-+ forward_copy_shift pull=8 push=24
-+ sub r1, r1, #3
- b 6b
-
--11: cmp r2, #12
-- blt 13f /* */
-- sub r2, r2, #12
--12: mov r3, r7, lsr #16
-- ldmia r1!, {r4 - r7}
-- orr r3, r3, r4, lsl #16
-- mov r4, r4, lsr #16
-- orr r4, r4, r5, lsl #16
-- mov r5, r5, lsr #16
-- orr r5, r5, r6, lsl #16
-- mov r6, r6, lsr #16
-- orr r6, r6, r7,LSL#16
-- stmia r0!, {r3 - r6}
-- subs r2, r2, #16
-- bge 12b
-- adds r2, r2, #12
-- blt 14f
--13: mov r3, r7, lsr #16
-- ldr r7, [r1], #4
-- subs r2, r2, #4
-- orr r3, r3, r7, lsl #16
-- str r3, [r0], #4
-- bge 13b
--14: sub r1, r1, #2
-+16: forward_copy_shift pull=16 push=16
-+ sub r1, r1, #2
- b 6b
-
--15: cmp r2, #12
-- blt 17f
-- sub r2, r2, #12
--16: mov r3, r7, lsr #24
-- ldmia r1!,{r4 - r7}
-- orr r3, r3, r4, lsl #8
-- mov r4, r4, lsr #24
-- orr r4, r4, r5, lsl #8
-- mov r5, r5, lsr #24
-- orr r5, r5, r6, lsl #8
-- mov r6, r6, lsr #24
-- orr r6, r6, r7, lsl #8
-- stmia r0!, {r3 - r6}
-- subs r2, r2, #16
-- bge 16b
-- adds r2, r2, #12
-- blt 18f
--17: mov r3, r7, lsr #24
-- ldr r7, [r1], #4
-- subs r2, r2, #4
-- orr r3, r3, r7, lsl#8
-- str r3, [r0], #4
-- bge 17b
--18: sub r1, r1, #1
-+17: forward_copy_shift pull=24 push=8
-+ sub r1, r1, #1
- b 6b
-
-
--19: add r1, r1, r2
-+18: add r1, r1, r2
- add r0, r0, r2
- subs r2, r2, #4
- blt 24f
-+ PLD( pld [r1, #-4] )
- ands ip, r0, #3
- bne 25f
- ands ip, r1, #3
- bne 26f
-
--20: subs r2, r2, #8
-+19: subs r2, r2, #8
- blt 23f
-- subs r2, r2, #0x14
-+ subs r2, r2, #20
- blt 22f
--21: ldmdb r1!, {r3 - r9, ip}
-- stmdb r0!, {r3 - r9, ip}
-+
-+ PLD( subs r2, r2, #96 )
-+ PLD( pld [r1, #-32] )
-+ PLD( blt 21f )
-+
-+ PLD( @ cache alignment )
-+ PLD( ands ip, r1, #31 )
-+ PLD( pld [r1, #-64] )
-+ PLD( beq 20f )
-+ PLD( cmp r2, ip )
-+ PLD( pld [r1, #-96] )
-+ PLD( blt 20f )
-+ PLD( cmp ip, #16 )
-+ PLD( sub r2, r2, ip )
-+ PLD( ldmgedb r1!, {r3 - r6} )
-+ PLD( stmgedb r0!, {r3 - r6} )
-+ PLD( beq 20f )
-+ PLD( and ip, ip, #15 )
-+ PLD( cmp ip, #8 )
-+ PLD( ldr r3, [r1, #-4]! )
-+ PLD( ldrge r4, [r1, #-4]! )
-+ PLD( ldrgt r5, [r1, #-4]! )
-+ PLD( str r3, [r0, #-4]! )
-+ PLD( strge r4, [r0, #-4]! )
-+ PLD( strgt r5, [r0, #-4]! )
-+
-+20: PLD( pld [r1, #-96] )
-+ PLD( pld [r1, #-128] )
-+21: ldmdb r1!, {r3 - r6}
- subs r2, r2, #32
-- bge 21b
--22: cmn r2, #16
-+ stmdb r0!, {r3 - r6}
-+ ldmdb r1!, {r3 - r6}
-+ stmgedb r0!, {r3 - r6}
- ldmgedb r1!, {r3 - r6}
- stmgedb r0!, {r3 - r6}
-+ ldmgedb r1!, {r3 - r6}
-+ subges r2, r2, #32
-+ stmdb r0!, {r3 - r6}
-+ bge 20b
-+ PLD( cmn r2, #96 )
-+ PLD( bge 21b )
-+ PLD( add r2, r2, #96 )
-+22: cmn r2, #16
-+ ldmgedb r1!, {r3 - r6}
- subge r2, r2, #16
-+ stmgedb r0!, {r3 - r6}
- adds r2, r2, #20
- ldmgedb r1!, {r3 - r5}
-- stmgedb r0!, {r3 - r5}
- subge r2, r2, #12
-+ stmgedb r0!, {r3 - r5}
- 23: adds r2, r2, #8
- blt 24f
- subs r2, r2, #4
- ldrlt r3, [r1, #-4]!
- ldmgedb r1!, {r4, r5}
-+ subge r2, r2, #4
- strlt r3, [r0, #-4]!
- stmgedb r0!, {r4, r5}
-- subge r2, r2, #4
-
- 24: adds r2, r2, #4
- EXITEQ
-@@ -230,89 +317,101 @@
- subs r2, r2, ip
- blt 24b
- ands ip, r1, #3
-- beq 20b
-+ beq 19b
-
- 26: bic r1, r1, #3
-- ldr r3, [r1], #0
- cmp ip, #2
-- blt 34f
-- beq 30f
-- cmp r2, #12
-- blt 28f
-- sub r2, r2, #12
--27: mov r7, r3, lsl #8
-- ldmdb r1!, {r3, r4, r5, r6}
-- orr r7, r7, r6, lsr #24
-- mov r6, r6, lsl #8
-- orr r6, r6, r5, lsr #24
-- mov r5, r5, lsl #8
-- orr r5, r5, r4, lsr #24
-- mov r4, r4, lsl #8
-- orr r4, r4, r3, lsr #24
-- stmdb r0!, {r4, r5, r6, r7}
-- subs r2, r2, #16
-- bge 27b
-- adds r2, r2, #12
-- blt 29f
--28: mov ip, r3, lsl #8
-- ldr r3, [r1, #-4]!
-- subs r2, r2, #4
-- orr ip, ip, r3, lsr #24
-- str ip, [r0, #-4]!
-- bge 28b
--29: add r1, r1, #3
-- b 24b
-+ ldr r3, [r1], #0
-+ blt 35f
-+ beq 34f
-
--30: cmp r2, #12
-+
-+ .macro backward_copy_shift push pull
-+
-+ cmp r2, #12
-+ PLD( pld [r1, #-4] )
- blt 32f
-- sub r2, r2, #12
--31: mov r7, r3, lsl #16
-- ldmdb r1!, {r3, r4, r5, r6}
-- orr r7, r7, r6, lsr #16
-- mov r6, r6, lsl #16
-- orr r6, r6, r5, lsr #16
-- mov r5, r5, lsl #16
-- orr r5, r5, r4, lsr #16
-- mov r4, r4, lsl #16
-- orr r4, r4, r3, lsr #16
-- stmdb r0!, {r4, r5, r6, r7}
-- subs r2, r2, #16
-- bge 31b
-- adds r2, r2, #12
-+ subs r2, r2, #28
-+ blt 30f
-+
-+ PLD( subs r2, r2, #96 )
-+ PLD( pld [r1, #-32] )
-+ PLD( blt 29f )
-+ PLD( pld [r1, #-64] )
-+
-+ PLD( @ cache alignment )
-+ PLD( ands ip, r1, #31 )
-+ PLD( pld [r1, #-96] )
-+ PLD( beq 28f )
-+ PLD( cmp r2, ip )
-+ PLD( pld [r1, #-128] )
-+ PLD( blt 28f )
-+ PLD( sub r2, r2, ip )
-+27: PLD( mov r4, r3, push #\push )
-+ PLD( ldr r3, [r1, #-4]! )
-+ PLD( subs ip, ip, #4 )
-+ PLD( orr r4, r4, r3, pull #\pull )
-+ PLD( str r4, [r0, #-4]! )
-+ PLD( bgt 27b )
-+
-+28: PLD( pld [r1, #-128] )
-+29: mov lr, r3, push #\push
-+ ldmdb r1!, {r3 - r9, ip}
-+ subs r2, r2, #32
-+ orr lr, lr, ip, pull #\pull
-+ mov ip, ip, push #\push
-+ orr ip, ip, r9, pull #\pull
-+ mov r9, r9, push #\push
-+ orr r9, r9, r8, pull #\pull
-+ mov r8, r8, push #\push
-+ orr r8, r8, r7, pull #\pull
-+ mov r7, r7, push #\push
-+ orr r7, r7, r6, pull #\pull
-+ mov r6, r6, push #\push
-+ orr r6, r6, r5, pull #\pull
-+ mov r5, r5, push #\push
-+ orr r5, r5, r4, pull #\pull
-+ mov r4, r4, push #\push
-+ orr r4, r4, r3, pull #\pull
-+ stmdb r0!, {r4 - r9, ip, lr}
-+ bge 28b
-+ PLD( cmn r2, #96 )
-+ PLD( bge 29b )
-+ PLD( add r2, r2, #96 )
-+ cmn r2, #16
-+ blt 31f
-+30: mov r7, r3, push #\push
-+ ldmdb r1!, {r3 - r6}
-+ sub r2, r2, #16
-+ orr r7, r7, r6, pull #\pull
-+ mov r6, r6, push #\push
-+ orr r6, r6, r5, pull #\pull
-+ mov r5, r5, push #\push
-+ orr r5, r5, r4, pull #\pull
-+ mov r4, r4, push #\push
-+ orr r4, r4, r3, pull #\pull
-+ stmdb r0!, {r4 - r7}
-+31: adds r2, r2, #28
- blt 33f
--32: mov ip, r3, lsl #16
-+32: mov r4, r3, push #\push
- ldr r3, [r1, #-4]!
- subs r2, r2, #4
-- orr ip, ip, r3, lsr #16
-- str ip, [r0, #-4]!
-+ orr r4, r4, r3, pull #\pull
-+ str r4, [r0, #-4]!
- bge 32b
--33: add r1, r1, #2
-+33:
-+ .endm
-+
-+
-+ backward_copy_shift push=8 pull=24
-+ add r1, r1, #3
- b 24b
-
--34: cmp r2, #12
-- blt 36f
-- sub r2, r2, #12
--35: mov r7, r3, lsl #24
-- ldmdb r1!, {r3, r4, r5, r6}
-- orr r7, r7, r6, lsr #8
-- mov r6, r6, lsl #24
-- orr r6, r6, r5, lsr #8
-- mov r5, r5, lsl #24
-- orr r5, r5, r4, lsr #8
-- mov r4, r4, lsl #24
-- orr r4, r4, r3, lsr #8
-- stmdb r0!, {r4, r5, r6, r7}
-- subs r2, r2, #16
-- bge 35b
-- adds r2, r2, #12
-- blt 37f
--36: mov ip, r3, lsl #24
-- ldr r3, [r1, #-4]!
-- subs r2, r2, #4
-- orr ip, ip, r3, lsr #8
-- str ip, [r0, #-4]!
-- bge 36b
--37: add r1, r1, #1
-+34: backward_copy_shift push=16 pull=16
-+ add r1, r1, #2
-+ b 24b
-+
-+35: backward_copy_shift push=24 pull=8
-+ add r1, r1, #1
- b 24b
-
-- .align
---- linux-2.4.25/arch/arm/lib/uaccess.S~2.4.25-vrs2-pxa1.patch 2000-09-19 00:15:25.000000000 +0200
-+++ linux-2.4.25/arch/arm/lib/uaccess.S 2004-03-31 17:15:11.000000000 +0200
-@@ -43,6 +43,8 @@
- stmfd sp!, {r2, r4 - r7, lr}
- cmp r2, #4
- blt .c2u_not_enough
-+ PLD( pld [r1, #0] )
-+ PLD( pld [r0, #0] )
- ands ip, r0, #3
- bne .c2u_dest_not_aligned
- .c2u_dest_aligned:
-@@ -71,13 +73,26 @@
- sub r2, r2, ip
- subs ip, ip, #32
- blt .c2u_0rem8lp
-+ PLD( pld [r1, #28] )
-+ PLD( pld [r0, #28] )
-+ PLD( subs ip, ip, #64 )
-+ PLD( blt .c2u_0cpynopld )
-+ PLD( pld [r1, #60] )
-+ PLD( pld [r0, #60] )
-
--.c2u_0cpy8lp: ldmia r1!, {r3 - r6}
-+.c2u_0cpy8lp:
-+ PLD( pld [r1, #92] )
-+ PLD( pld [r0, #92] )
-+.c2u_0cpynopld: ldmia r1!, {r3 - r6}
- stmia r0!, {r3 - r6} @ Shouldnt fault
- ldmia r1!, {r3 - r6}
-- stmia r0!, {r3 - r6} @ Shouldnt fault
- subs ip, ip, #32
-+ stmia r0!, {r3 - r6} @ Shouldnt fault
- bpl .c2u_0cpy8lp
-+ PLD( cmn ip, #64 )
-+ PLD( bge .c2u_0cpynopld )
-+ PLD( add ip, ip, #64 )
-+
- .c2u_0rem8lp: cmn ip, #16
- ldmgeia r1!, {r3 - r6}
- stmgeia r0!, {r3 - r6} @ Shouldnt fault
-@@ -115,9 +130,9 @@
- .c2u_1fupi: subs r2, r2, #4
- addmi ip, r2, #4
- bmi .c2u_1nowords
-- mov r3, r7, lsr #8
-+ mov r3, r7, pull #8
- ldr r7, [r1], #4
-- orr r3, r3, r7, lsl #24
-+ orr r3, r3, r7, push #24
- USER( strt r3, [r0], #4) @ May fault
- mov ip, r0, lsl #32 - PAGE_SHIFT
- rsb ip, ip, #0
-@@ -128,50 +143,63 @@
- sub r2, r2, ip
- subs ip, ip, #16
- blt .c2u_1rem8lp
-+ PLD( pld [r1, #12] )
-+ PLD( pld [r0, #12] )
-+ PLD( subs ip, ip, #32 )
-+ PLD( blt .c2u_1cpynopld )
-+ PLD( pld [r1, #28] )
-+ PLD( pld [r0, #28] )
-
--.c2u_1cpy8lp: mov r3, r7, lsr #8
-+.c2u_1cpy8lp:
-+ PLD( pld [r1, #44] )
-+ PLD( pld [r0, #44] )
-+.c2u_1cpynopld: mov r3, r7, pull #8
- ldmia r1!, {r4 - r7}
-- orr r3, r3, r4, lsl #24
-- mov r4, r4, lsr #8
-- orr r4, r4, r5, lsl #24
-- mov r5, r5, lsr #8
-- orr r5, r5, r6, lsl #24
-- mov r6, r6, lsr #8
-- orr r6, r6, r7, lsl #24
-- stmia r0!, {r3 - r6} @ Shouldnt fault
- subs ip, ip, #16
-+ orr r3, r3, r4, push #24
-+ mov r4, r4, pull #8
-+ orr r4, r4, r5, push #24
-+ mov r5, r5, pull #8
-+ orr r5, r5, r6, push #24
-+ mov r6, r6, pull #8
-+ orr r6, r6, r7, push #24
-+ stmia r0!, {r3 - r6} @ Shouldnt fault
- bpl .c2u_1cpy8lp
-+ PLD( cmn ip, #32 )
-+ PLD( bge .c2u_1cpynopld )
-+ PLD( add ip, ip, #32 )
-+
- .c2u_1rem8lp: tst ip, #8
-- movne r3, r7, lsr #8
-+ movne r3, r7, pull #8
- ldmneia r1!, {r4, r7}
-- orrne r3, r3, r4, lsl #24
-- movne r4, r4, lsr #8
-- orrne r4, r4, r7, lsl #24
-+ orrne r3, r3, r4, push #24
-+ movne r4, r4, pull #8
-+ orrne r4, r4, r7, push #24
- stmneia r0!, {r3 - r4} @ Shouldnt fault
- tst ip, #4
-- movne r3, r7, lsr #8
-+ movne r3, r7, pull #8
- ldrne r7, [r1], #4
-- orrne r3, r3, r7, lsl #24
-+ orrne r3, r3, r7, push #24
- strnet r3, [r0], #4 @ Shouldnt fault
- ands ip, ip, #3
- beq .c2u_1fupi
--.c2u_1nowords: mov r3, r7, lsr #8
-+.c2u_1nowords: mov r3, r7, lsr #byte(1)
- teq ip, #0
- beq .c2u_finished
- cmp ip, #2
- USER( strbt r3, [r0], #1) @ May fault
-- movge r3, r3, lsr #8
-+ movge r3, r7, lsr #byte(2)
- USER( strgebt r3, [r0], #1) @ May fault
-- movgt r3, r3, lsr #8
-+ movgt r3, r7, lsr #byte(3)
- USER( strgtbt r3, [r0], #1) @ May fault
- b .c2u_finished
-
- .c2u_2fupi: subs r2, r2, #4
- addmi ip, r2, #4
- bmi .c2u_2nowords
-- mov r3, r7, lsr #16
-+ mov r3, r7, pull #16
- ldr r7, [r1], #4
-- orr r3, r3, r7, lsl #16
-+ orr r3, r3, r7, push #16
- USER( strt r3, [r0], #4) @ May fault
- mov ip, r0, lsl #32 - PAGE_SHIFT
- rsb ip, ip, #0
-@@ -182,39 +210,52 @@
- sub r2, r2, ip
- subs ip, ip, #16
- blt .c2u_2rem8lp
-+ PLD( pld [r1, #12] )
-+ PLD( pld [r0, #12] )
-+ PLD( subs ip, ip, #32 )
-+ PLD( blt .c2u_2cpynopld )
-+ PLD( pld [r1, #28] )
-+ PLD( pld [r0, #28] )
-
--.c2u_2cpy8lp: mov r3, r7, lsr #16
-+.c2u_2cpy8lp:
-+ PLD( pld [r1, #44] )
-+ PLD( pld [r0, #44] )
-+.c2u_2cpynopld: mov r3, r7, pull #16
- ldmia r1!, {r4 - r7}
-- orr r3, r3, r4, lsl #16
-- mov r4, r4, lsr #16
-- orr r4, r4, r5, lsl #16
-- mov r5, r5, lsr #16
-- orr r5, r5, r6, lsl #16
-- mov r6, r6, lsr #16
-- orr r6, r6, r7, lsl #16
-- stmia r0!, {r3 - r6} @ Shouldnt fault
- subs ip, ip, #16
-+ orr r3, r3, r4, push #16
-+ mov r4, r4, pull #16
-+ orr r4, r4, r5, push #16
-+ mov r5, r5, pull #16
-+ orr r5, r5, r6, push #16
-+ mov r6, r6, pull #16
-+ orr r6, r6, r7, push #16
-+ stmia r0!, {r3 - r6} @ Shouldnt fault
- bpl .c2u_2cpy8lp
-+ PLD( cmn ip, #32 )
-+ PLD( bge .c2u_2cpynopld )
-+ PLD( add ip, ip, #32 )
-+
- .c2u_2rem8lp: tst ip, #8
-- movne r3, r7, lsr #16
-+ movne r3, r7, pull #16
- ldmneia r1!, {r4, r7}
-- orrne r3, r3, r4, lsl #16
-- movne r4, r4, lsr #16
-- orrne r4, r4, r7, lsl #16
-+ orrne r3, r3, r4, push #16
-+ movne r4, r4, pull #16
-+ orrne r4, r4, r7, push #16
- stmneia r0!, {r3 - r4} @ Shouldnt fault
- tst ip, #4
-- movne r3, r7, lsr #16
-+ movne r3, r7, pull #16
- ldrne r7, [r1], #4
-- orrne r3, r3, r7, lsl #16
-+ orrne r3, r3, r7, push #16
- strnet r3, [r0], #4 @ Shouldnt fault
- ands ip, ip, #3
- beq .c2u_2fupi
--.c2u_2nowords: mov r3, r7, lsr #16
-+.c2u_2nowords: mov r3, r7, lsr #byte(2)
- teq ip, #0
- beq .c2u_finished
- cmp ip, #2
- USER( strbt r3, [r0], #1) @ May fault
-- movge r3, r3, lsr #8
-+ movge r3, r7, lsr #byte(3)
- USER( strgebt r3, [r0], #1) @ May fault
- ldrgtb r3, [r1], #0
- USER( strgtbt r3, [r0], #1) @ May fault
-@@ -223,9 +264,9 @@
- .c2u_3fupi: subs r2, r2, #4
- addmi ip, r2, #4
- bmi .c2u_3nowords
-- mov r3, r7, lsr #24
-+ mov r3, r7, pull #24
- ldr r7, [r1], #4
-- orr r3, r3, r7, lsl #8
-+ orr r3, r3, r7, push #8
- USER( strt r3, [r0], #4) @ May fault
- mov ip, r0, lsl #32 - PAGE_SHIFT
- rsb ip, ip, #0
-@@ -236,41 +277,54 @@
- sub r2, r2, ip
- subs ip, ip, #16
- blt .c2u_3rem8lp
-+ PLD( pld [r1, #12] )
-+ PLD( pld [r0, #12] )
-+ PLD( subs ip, ip, #32 )
-+ PLD( blt .c2u_3cpynopld )
-+ PLD( pld [r1, #28] )
-+ PLD( pld [r0, #28] )
-
--.c2u_3cpy8lp: mov r3, r7, lsr #24
-+.c2u_3cpy8lp:
-+ PLD( pld [r1, #44] )
-+ PLD( pld [r0, #44] )
-+.c2u_3cpynopld: mov r3, r7, pull #24
- ldmia r1!, {r4 - r7}
-- orr r3, r3, r4, lsl #8
-- mov r4, r4, lsr #24
-- orr r4, r4, r5, lsl #8
-- mov r5, r5, lsr #24
-- orr r5, r5, r6, lsl #8
-- mov r6, r6, lsr #24
-- orr r6, r6, r7, lsl #8
-- stmia r0!, {r3 - r6} @ Shouldnt fault
- subs ip, ip, #16
-+ orr r3, r3, r4, push #8
-+ mov r4, r4, pull #24
-+ orr r4, r4, r5, push #8
-+ mov r5, r5, pull #24
-+ orr r5, r5, r6, push #8
-+ mov r6, r6, pull #24
-+ orr r6, r6, r7, push #8
-+ stmia r0!, {r3 - r6} @ Shouldnt fault
- bpl .c2u_3cpy8lp
-+ PLD( cmn ip, #32 )
-+ PLD( bge .c2u_3cpynopld )
-+ PLD( add ip, ip, #32 )
-+
- .c2u_3rem8lp: tst ip, #8
-- movne r3, r7, lsr #24
-+ movne r3, r7, pull #24
- ldmneia r1!, {r4, r7}
-- orrne r3, r3, r4, lsl #8
-- movne r4, r4, lsr #24
-- orrne r4, r4, r7, lsl #8
-+ orrne r3, r3, r4, push #8
-+ movne r4, r4, pull #24
-+ orrne r4, r4, r7, push #8
- stmneia r0!, {r3 - r4} @ Shouldnt fault
- tst ip, #4
-- movne r3, r7, lsr #24
-+ movne r3, r7, pull #24
- ldrne r7, [r1], #4
-- orrne r3, r3, r7, lsl #8
-+ orrne r3, r3, r7, push #8
- strnet r3, [r0], #4 @ Shouldnt fault
- ands ip, ip, #3
- beq .c2u_3fupi
--.c2u_3nowords: mov r3, r7, lsr #24
-+.c2u_3nowords: mov r3, r7, lsr #byte(3)
- teq ip, #0
- beq .c2u_finished
- cmp ip, #2
- USER( strbt r3, [r0], #1) @ May fault
-- ldrge r3, [r1], #0
-+ ldrgeb r3, [r1], #1
- USER( strgebt r3, [r0], #1) @ May fault
-- movgt r3, r3, lsr #8
-+ ldrgtb r3, [r1], #0
- USER( strgtbt r3, [r0], #1) @ May fault
- b .c2u_finished
-
-@@ -302,6 +356,8 @@
- stmfd sp!, {r0, r2, r4 - r7, lr}
- cmp r2, #4
- blt .cfu_not_enough
-+ PLD( pld [r1, #0] )
-+ PLD( pld [r0, #0] )
- ands ip, r0, #3
- bne .cfu_dest_not_aligned
- .cfu_dest_aligned:
-@@ -329,13 +385,26 @@
- sub r2, r2, ip
- subs ip, ip, #32
- blt .cfu_0rem8lp
-+ PLD( pld [r1, #28] )
-+ PLD( pld [r0, #28] )
-+ PLD( subs ip, ip, #64 )
-+ PLD( blt .cfu_0cpynopld )
-+ PLD( pld [r1, #60] )
-+ PLD( pld [r0, #60] )
-
--.cfu_0cpy8lp: ldmia r1!, {r3 - r6} @ Shouldnt fault
-+.cfu_0cpy8lp:
-+ PLD( pld [r1, #92] )
-+ PLD( pld [r0, #92] )
-+.cfu_0cpynopld: ldmia r1!, {r3 - r6} @ Shouldnt fault
- stmia r0!, {r3 - r6}
- ldmia r1!, {r3 - r6} @ Shouldnt fault
-- stmia r0!, {r3 - r6}
- subs ip, ip, #32
-+ stmia r0!, {r3 - r6}
- bpl .cfu_0cpy8lp
-+ PLD( cmn ip, #64 )
-+ PLD( bge .cfu_0cpynopld )
-+ PLD( add ip, ip, #64 )
-+
- .cfu_0rem8lp: cmn ip, #16
- ldmgeia r1!, {r3 - r6} @ Shouldnt fault
- stmgeia r0!, {r3 - r6}
-@@ -374,9 +443,9 @@
- .cfu_1fupi: subs r2, r2, #4
- addmi ip, r2, #4
- bmi .cfu_1nowords
-- mov r3, r7, lsr #8
-+ mov r3, r7, pull #8
- USER( ldrt r7, [r1], #4) @ May fault
-- orr r3, r3, r7, lsl #24
-+ orr r3, r3, r7, push #24
- str r3, [r0], #4
- mov ip, r1, lsl #32 - PAGE_SHIFT
- rsb ip, ip, #0
-@@ -387,50 +456,63 @@
- sub r2, r2, ip
- subs ip, ip, #16
- blt .cfu_1rem8lp
-+ PLD( pld [r1, #12] )
-+ PLD( pld [r0, #12] )
-+ PLD( subs ip, ip, #32 )
-+ PLD( blt .cfu_1cpynopld )
-+ PLD( pld [r1, #28] )
-+ PLD( pld [r0, #28] )
-
--.cfu_1cpy8lp: mov r3, r7, lsr #8
-+.cfu_1cpy8lp:
-+ PLD( pld [r1, #44] )
-+ PLD( pld [r0, #44] )
-+.cfu_1cpynopld: mov r3, r7, pull #8
- ldmia r1!, {r4 - r7} @ Shouldnt fault
-- orr r3, r3, r4, lsl #24
-- mov r4, r4, lsr #8
-- orr r4, r4, r5, lsl #24
-- mov r5, r5, lsr #8
-- orr r5, r5, r6, lsl #24
-- mov r6, r6, lsr #8
-- orr r6, r6, r7, lsl #24
-- stmia r0!, {r3 - r6}
- subs ip, ip, #16
-+ orr r3, r3, r4, push #24
-+ mov r4, r4, pull #8
-+ orr r4, r4, r5, push #24
-+ mov r5, r5, pull #8
-+ orr r5, r5, r6, push #24
-+ mov r6, r6, pull #8
-+ orr r6, r6, r7, push #24
-+ stmia r0!, {r3 - r6}
- bpl .cfu_1cpy8lp
-+ PLD( cmn ip, #32 )
-+ PLD( bge .cfu_1cpynopld )
-+ PLD( add ip, ip, #32 )
-+
- .cfu_1rem8lp: tst ip, #8
-- movne r3, r7, lsr #8
-+ movne r3, r7, pull #8
- ldmneia r1!, {r4, r7} @ Shouldnt fault
-- orrne r3, r3, r4, lsl #24
-- movne r4, r4, lsr #8
-- orrne r4, r4, r7, lsl #24
-+ orrne r3, r3, r4, push #24
-+ movne r4, r4, pull #8
-+ orrne r4, r4, r7, push #24
- stmneia r0!, {r3 - r4}
- tst ip, #4
-- movne r3, r7, lsr #8
-+ movne r3, r7, pull #8
- USER( ldrnet r7, [r1], #4) @ May fault
-- orrne r3, r3, r7, lsl #24
-+ orrne r3, r3, r7, push #24
- strne r3, [r0], #4
- ands ip, ip, #3
- beq .cfu_1fupi
--.cfu_1nowords: mov r3, r7, lsr #8
-+.cfu_1nowords: mov r3, r7, lsr #byte(1)
- teq ip, #0
- beq .cfu_finished
- cmp ip, #2
- strb r3, [r0], #1
-- movge r3, r3, lsr #8
-+ movge r3, r7, lsr #byte(2)
- strgeb r3, [r0], #1
-- movgt r3, r3, lsr #8
-+ movgt r3, r7, lsr #byte(3)
- strgtb r3, [r0], #1
- b .cfu_finished
-
- .cfu_2fupi: subs r2, r2, #4
- addmi ip, r2, #4
- bmi .cfu_2nowords
-- mov r3, r7, lsr #16
-+ mov r3, r7, pull #16
- USER( ldrt r7, [r1], #4) @ May fault
-- orr r3, r3, r7, lsl #16
-+ orr r3, r3, r7, push #16
- str r3, [r0], #4
- mov ip, r1, lsl #32 - PAGE_SHIFT
- rsb ip, ip, #0
-@@ -441,39 +523,52 @@
- sub r2, r2, ip
- subs ip, ip, #16
- blt .cfu_2rem8lp
-+ PLD( pld [r1, #12] )
-+ PLD( pld [r0, #12] )
-+ PLD( subs ip, ip, #32 )
-+ PLD( blt .cfu_2cpynopld )
-+ PLD( pld [r1, #28] )
-+ PLD( pld [r0, #28] )
-
--.cfu_2cpy8lp: mov r3, r7, lsr #16
-+.cfu_2cpy8lp:
-+ PLD( pld [r1, #44] )
-+ PLD( pld [r0, #44] )
-+.cfu_2cpynopld: mov r3, r7, pull #16
- ldmia r1!, {r4 - r7} @ Shouldnt fault
-- orr r3, r3, r4, lsl #16
-- mov r4, r4, lsr #16
-- orr r4, r4, r5, lsl #16
-- mov r5, r5, lsr #16
-- orr r5, r5, r6, lsl #16
-- mov r6, r6, lsr #16
-- orr r6, r6, r7, lsl #16
-- stmia r0!, {r3 - r6}
- subs ip, ip, #16
-+ orr r3, r3, r4, push #16
-+ mov r4, r4, pull #16
-+ orr r4, r4, r5, push #16
-+ mov r5, r5, pull #16
-+ orr r5, r5, r6, push #16
-+ mov r6, r6, pull #16
-+ orr r6, r6, r7, push #16
-+ stmia r0!, {r3 - r6}
- bpl .cfu_2cpy8lp
-+ PLD( cmn ip, #32 )
-+ PLD( bge .cfu_2cpynopld )
-+ PLD( add ip, ip, #32 )
-+
- .cfu_2rem8lp: tst ip, #8
-- movne r3, r7, lsr #16
-+ movne r3, r7, pull #16
- ldmneia r1!, {r4, r7} @ Shouldnt fault
-- orrne r3, r3, r4, lsl #16
-- movne r4, r4, lsr #16
-- orrne r4, r4, r7, lsl #16
-+ orrne r3, r3, r4, push #16
-+ movne r4, r4, pull #16
-+ orrne r4, r4, r7, push #16
- stmneia r0!, {r3 - r4}
- tst ip, #4
-- movne r3, r7, lsr #16
-+ movne r3, r7, pull #16
- USER( ldrnet r7, [r1], #4) @ May fault
-- orrne r3, r3, r7, lsl #16
-+ orrne r3, r3, r7, push #16
- strne r3, [r0], #4
- ands ip, ip, #3
- beq .cfu_2fupi
--.cfu_2nowords: mov r3, r7, lsr #16
-+.cfu_2nowords: mov r3, r7, lsr #byte(2)
- teq ip, #0
- beq .cfu_finished
- cmp ip, #2
- strb r3, [r0], #1
-- movge r3, r3, lsr #8
-+ movge r3, r7, lsr #byte(3)
- strgeb r3, [r0], #1
- USER( ldrgtbt r3, [r1], #0) @ May fault
- strgtb r3, [r0], #1
-@@ -482,9 +577,9 @@
- .cfu_3fupi: subs r2, r2, #4
- addmi ip, r2, #4
- bmi .cfu_3nowords
-- mov r3, r7, lsr #24
-+ mov r3, r7, pull #24
- USER( ldrt r7, [r1], #4) @ May fault
-- orr r3, r3, r7, lsl #8
-+ orr r3, r3, r7, push #8
- str r3, [r0], #4
- mov ip, r1, lsl #32 - PAGE_SHIFT
- rsb ip, ip, #0
-@@ -495,41 +590,54 @@
- sub r2, r2, ip
- subs ip, ip, #16
- blt .cfu_3rem8lp
-+ PLD( pld [r1, #12] )
-+ PLD( pld [r0, #12] )
-+ PLD( subs ip, ip, #32 )
-+ PLD( blt .cfu_3cpynopld )
-+ PLD( pld [r1, #28] )
-+ PLD( pld [r0, #28] )
-
--.cfu_3cpy8lp: mov r3, r7, lsr #24
-+.cfu_3cpy8lp:
-+ PLD( pld [r1, #44] )
-+ PLD( pld [r0, #44] )
-+.cfu_3cpynopld: mov r3, r7, pull #24
- ldmia r1!, {r4 - r7} @ Shouldnt fault
-- orr r3, r3, r4, lsl #8
-- mov r4, r4, lsr #24
-- orr r4, r4, r5, lsl #8
-- mov r5, r5, lsr #24
-- orr r5, r5, r6, lsl #8
-- mov r6, r6, lsr #24
-- orr r6, r6, r7, lsl #8
-+ orr r3, r3, r4, push #8
-+ mov r4, r4, pull #24
-+ orr r4, r4, r5, push #8
-+ mov r5, r5, pull #24
-+ orr r5, r5, r6, push #8
-+ mov r6, r6, pull #24
-+ orr r6, r6, r7, push #8
- stmia r0!, {r3 - r6}
- subs ip, ip, #16
- bpl .cfu_3cpy8lp
-+ PLD( cmn ip, #32 )
-+ PLD( bge .cfu_3cpynopld )
-+ PLD( add ip, ip, #32 )
-+
- .cfu_3rem8lp: tst ip, #8
-- movne r3, r7, lsr #24
-+ movne r3, r7, pull #24
- ldmneia r1!, {r4, r7} @ Shouldnt fault
-- orrne r3, r3, r4, lsl #8
-- movne r4, r4, lsr #24
-- orrne r4, r4, r7, lsl #8
-+ orrne r3, r3, r4, push #8
-+ movne r4, r4, pull #24
-+ orrne r4, r4, r7, push #8
- stmneia r0!, {r3 - r4}
- tst ip, #4
-- movne r3, r7, lsr #24
-+ movne r3, r7, pull #24
- USER( ldrnet r7, [r1], #4) @ May fault
-- orrne r3, r3, r7, lsl #8
-+ orrne r3, r3, r7, push #8
- strne r3, [r0], #4
- ands ip, ip, #3
- beq .cfu_3fupi
--.cfu_3nowords: mov r3, r7, lsr #24
-+.cfu_3nowords: mov r3, r7, lsr #byte(3)
- teq ip, #0
- beq .cfu_finished
- cmp ip, #2
- strb r3, [r0], #1
--USER( ldrget r3, [r1], #0) @ May fault
-+USER( ldrgebt r3, [r1], #1) @ May fault
- strgeb r3, [r0], #1
-- movgt r3, r3, lsr #8
-+USER( ldrgtbt r3, [r1], #1) @ May fault
- strgtb r3, [r0], #1
- b .cfu_finished
-
-@@ -544,7 +652,7 @@
- ldr r1, [sp], #4 @ unsigned long count
- subs r4, r1, r2 @ bytes left to copy
- movne r1, r4
-- blne SYMBOL_NAME(__memzero)
-+ blne __memzero
- mov r0, r4
- LOADREGS(fd,sp!, {r4 - r7, pc})
- .previous
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/Makefile 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,56 @@
-+#
-+# Makefile for the linux kernel.
-+#
-+# Note! Dependencies are done automagically by 'make dep', which also
-+# removes any old dependencies. DON'T put your own dependencies here
-+# unless it's something special (ie not a .c file).
-+
-+USE_STANDARD_AS_RULE := true
-+
-+O_TARGET := pxa.o
-+
-+obj-y :=
-+obj-m :=
-+obj-n :=
-+obj- :=
-+
-+export-objs := generic.o irq.o dma.o sa1111.o \
-+ usb_ctl.o usb_recv.o usb_send.o
-+
-+# Common support (must be linked before board specific support)
-+obj-y += generic.o irq.o dma.o
-+obj-$(CONFIG_SA1111) += sa1111.o
-+
-+# Specific board support
-+obj-$(CONFIG_ARCH_CSB226) += csb226.o
-+obj-$(CONFIG_ARCH_INNOKOM) += innokom.o
-+obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
-+obj-$(CONFIG_ARCH_PXA_CERF) += cerf.o
-+obj-$(CONFIG_ARCH_PXA_IDP) += idp.o
-+obj-$(CONFIG_ARCH_TRIZEPS2) += trizeps2.o
-+
-+# Support for blinky lights
-+leds-y := leds.o
-+leds-$(CONFIG_ARCH_CSB226) += leds-csb226.o
-+leds-$(CONFIG_ARCH_INNOKOM) += leds-innokom.o
-+leds-$(CONFIG_ARCH_LUBBOCK) += leds-lubbock.o
-+leds-$(CONFIG_ARCH_PXA_IDP) += leds-idp.o
-+leds-$(CONFIG_ARCH_PXA_CERF) += leds-cerf.o
-+
-+obj-$(CONFIG_LEDS) += $(leds-y)
-+
-+# PXA USB client support
-+list-multi += pxausb_core.o
-+pxausb_core-objs := usb_ctl.o usb_ep0.o usb_recv.o usb_send.o
-+obj-$(CONFIG_PXA_USB) += pxausb_core.o
-+obj-$(CONFIG_PXA_USB_NETLINK) += usb-eth.o
-+obj-$(CONFIG_PXA_USB_CHAR) += usb-char.o
-+
-+# Misc features
-+obj-$(CONFIG_PM) += pm.o sleep.o
-+obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o
-+
-+include $(TOPDIR)/Rules.make
-+
-+pxausb_core.o: $(pxausb_core-objs)
-+ $(LD) -r -o $@ $(pxausb_core-objs)
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/cerf.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,266 @@
-+/*
-+ * linux/arch/arm/mach-pxa/cerf.c
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/init.h>
-+#include <linux/major.h>
-+#include <linux/fs.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+
-+#include <asm/types.h>
-+#include <asm/setup.h>
-+#include <asm/memory.h>
-+#include <asm/mach-types.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+
-+#include <asm/mach/arch.h>
-+#include <asm/mach/map.h>
-+#include <asm/mach/irq.h>
-+
-+#include <asm/io.h>
-+#include <asm/arch/irq.h>
-+
-+#include "generic.h"
-+
-+/*
-+ * Set this to zero to remove all the debug statements via
-+ * dead code elimination.
-+ */
-+#define DEBUGGING 1
-+
-+#if DEBUGGING
-+static unsigned int cerf_debug = DEBUGGING;
-+#else
-+#define cerf_debug 0
-+#endif
-+
-+static void __init cerf_init_irq(void)
-+{
-+ pxa_init_irq();
-+
-+ if( cerf_debug > 1)
-+ {
-+#if 0
-+ GPDR0 = 0xc05b9130;
-+ GPDR1 = 0xfcffab82;
-+ GPDR2 = 0x0001ffff;
-+#endif
-+
-+ printk(KERN_INFO "Pin directions:\n");
-+ printk(KERN_INFO "GPDR0 0x%08x\n", GPDR0);
-+ printk(KERN_INFO "GPDR1 0x%08x\n", GPDR1);
-+ printk(KERN_INFO "GPDR2 0x%08x\n", GPDR2);
-+
-+ printk(KERN_INFO "Pin State:\n");
-+ printk(KERN_INFO "GPLR0 0x%08x\n", GPLR0);
-+ printk(KERN_INFO "GPLR1 0x%08x\n", GPLR1);
-+ printk(KERN_INFO "GPLR2 0x%08x\n", GPLR2);
-+
-+ printk(KERN_INFO "Rising Edge:\n");
-+ printk(KERN_INFO "GRER0 0x%08x\n", GRER0);
-+ printk(KERN_INFO "GRER1 0x%08x\n", GRER1);
-+ printk(KERN_INFO "GRER2 0x%08x\n", GRER2);
-+
-+ printk(KERN_INFO "Falling Edge:\n");
-+ printk(KERN_INFO "GFER0 0x%08x\n", GFER0);
-+ printk(KERN_INFO "GFER1 0x%08x\n", GFER1);
-+ printk(KERN_INFO "GFER2 0x%08x\n", GFER2);
-+ }
-+
-+ /* set_GPIO_IRQ_edge has to be called before an irq can be requested */
-+ set_GPIO_IRQ_edge( 0, GPIO_FALLING_EDGE); /* CPLD */
-+#ifdef CONFIG_PXA_CERF_PDA
-+ set_GPIO_IRQ_edge( 2, GPIO_RISING_EDGE); /* UART B Interrupt */
-+ set_GPIO_IRQ_edge( 3, GPIO_RISING_EDGE); /* UART A Interrupt */
-+ set_GPIO_IRQ_edge( 32, GPIO_RISING_EDGE); /* UCB1400 Interrupt */
-+#endif
-+ set_GPIO_IRQ_edge( 14, GPIO_FALLING_EDGE); /* PCMCIA Card Detect */
-+ set_GPIO_IRQ_edge( 21, GPIO_RISING_EDGE); /* Ethernet Interrupt */
-+}
-+
-+static int __init cerf_init(void)
-+{
-+ /*
-+ * All of the code that was here was SA1111 init code
-+ * which we do not have.
-+ */
-+ return 0;
-+}
-+
-+__initcall(cerf_init);
-+
-+static void __init
-+fixup_cerf(struct machine_desc *desc, struct param_struct *params,
-+ char **cmdline, struct meminfo *mi)
-+{
-+ SET_BANK (0, CERF_RAM_BASE, CERF_RAM_SIZE);
-+ mi->nr_banks = 1;
-+
-+#if 0 // Enable this stuff if you plan on not using jffs2
-+ setup_ramdisk (1, 0, 0, 8192);
-+ setup_initrd (__phys_to_virt(0xa1000000), 4*1024*1024);
-+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
-+#endif
-+}
-+
-+/*
-+ * IO map for the devices.
-+ */
-+static struct map_desc cerf_io_desc[] __initdata = {
-+ /* virtual physical length domain r w c b */
-+ { CERF_FLASH_BASE , CERF_FLASH_PHYS , CERF_FLASH_SIZE , DOMAIN_IO, 0, 1, 0, 0 },
-+ { CERF_ETH_BASE , CERF_ETH_PHYS , CERF_ETH_SIZE , DOMAIN_IO, 0, 1, 0, 0 },
-+#ifdef CONFIG_PXA_CERF_PDA
-+ { CERF_BT_BASE , CERF_BT_PHYS , CERF_BT_SIZE , DOMAIN_IO, 0, 1, 0, 0 },
-+ { CERF_SERIAL_BASE, CERF_SERIAL_PHYS, CERF_SERIAL_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
-+ { CERF_CPLD_BASE , CERF_CPLD_PHYS , CERF_CPLD_SIZE , DOMAIN_IO, 0, 1, 0, 0 },
-+#endif
-+
-+ LAST_DESC
-+};
-+
-+static void __init cerf_map_io(void)
-+{
-+ pxa_map_io();
-+ iotable_init(cerf_io_desc);
-+
-+ if( cerf_debug > 1)
-+ {
-+ printk(KERN_INFO "origMCS0 = 0x%08x\n", MSC0);
-+ printk(KERN_INFO "origMCS1 = 0x%08x\n", MSC1);
-+ printk(KERN_INFO "origMCS2 = 0x%08x\n", MSC2);
-+ }
-+
-+ /* setup memory timing for CS0/1 */
-+ MSC0 = MSC_CS(0, MSC_RBUFF(MSC_RBUFF_SLOW) |
-+ MSC_RRR(3) |
-+ MSC_RDN(15) |
-+ MSC_RDF(13) |
-+ MSC_RBW(0) |
-+ MSC_RT(0)) |
-+#ifdef CONFIG_PXA_CERF_PDA
-+ MSC_CS(1, MSC_RBUFF(MSC_RBUFF_SLOW) |
-+ MSC_RRR(7) |
-+ MSC_RDN(15) |
-+ MSC_RDF(15) |
-+ MSC_RBW(1) |
-+ MSC_RT(0));
-+#elif defined(CONFIG_PXA_CERF_BOARD)
-+ MSC_CS(1, MSC_RBUFF(MSC_RBUFF_SLOW) |
-+ MSC_RRR(1) |
-+ MSC_RDN(2) |
-+ MSC_RDF(4) |
-+ MSC_RBW(0) |
-+ MSC_RT(4));
-+#endif
-+ printk(KERN_INFO "MCS0 = 0x%08x\n", MSC0);
-+
-+ /* setup memory timing for CS2/3 */
-+ MSC1 = MSC_CS(2, MSC_RBUFF(MSC_RBUFF_SLOW) |
-+ MSC_RRR(5) |
-+ MSC_RDN(10) |
-+ MSC_RDF(10) |
-+ MSC_RBW(1) |
-+ MSC_RT(0)) |
-+ MSC_CS(3, MSC_RBUFF(MSC_RBUFF_SLOW) |
-+ MSC_RRR(5) |
-+ MSC_RDN(10) |
-+ MSC_RDF(10) |
-+ MSC_RBW(1) |
-+ MSC_RT(0));
-+ printk(KERN_INFO "MCS1 = 0x%08x\n", MSC1);
-+
-+ /* setup memory timing for CS4/5 */
-+ MSC2 = MSC_CS(4, MSC_RBUFF(MSC_RBUFF_SLOW) |
-+ MSC_RRR(2) |
-+ MSC_RDN(4) |
-+ MSC_RDF(4) |
-+ MSC_RBW(1) |
-+ MSC_RT(0)) |
-+ MSC_CS(5, MSC_RBUFF(MSC_RBUFF_SLOW) |
-+ MSC_RRR(2) |
-+ MSC_RDN(4) |
-+ MSC_RDF(4) |
-+ MSC_RBW(1) |
-+ MSC_RT(0));
-+ printk(KERN_INFO "MCS2 = 0x%08x\n", MSC2);
-+
-+#ifdef CONFIG_SOUND_PXA_AC97
-+ printk(KERN_INFO "Enabling sound amp for pxa cerf pda.\n");
-+ outw( CERF_PDA_SOUND_ENABLE, CERF_CPLD_BASE+CERF_PDA_CPLD_SOUND_ENA);
-+#endif
-+
-+#ifdef CONFIG_FB_PXA
-+ printk(KERN_INFO "Setting LCD to brightness to %d/15\n", CERF_PDA_DEFAULT_BRIGHTNESS);
-+ outw( CERF_PDA_DEFAULT_BRIGHTNESS, CERF_CPLD_BASE+CERF_PDA_CPLD_BRIGHTNESS);
-+#endif
-+
-+#ifdef CONFIG_IRDA
-+ /* Enable IrDA UART (SIR)*/
-+ CKEN |= CKEN5_STUART;
-+
-+ /* We want to get our goods from the STUART */
-+ set_GPIO_mode(GPIO46_STRXD_MD);
-+ set_GPIO_mode(GPIO47_STTXD_MD);
-+
-+ /* make sure FIR ICP is off */
-+ ICCR0 = 0;
-+
-+ /* configure STUART to for SIR
-+ * NOTE: RCVEIR and XMITIR must not be set at the same time!
-+ * Start with receive in IR mode, and switch transmit to IR only
-+ * when we need to send something in serial driver.
-+ */
-+ STISR = IrSR_IR_RECEIVE_ON;
-+#endif
-+
-+#if 0
-+ /* Connect FIR ICP to GPIO pins */
-+ CKEN |= CKEN13_FICP;
-+ set_GPIO_mode(GPIO46_ICPRXD_MD);
-+ set_GPIO_mode(GPIO47_ICPTXD_MD);
-+ ICCR0 = 0x1 | 0x18; //ICP unit enable
-+#endif
-+
-+#if 0
-+ /* Enable BT UART */
-+ CKEN |= CKEN7_BTUART;
-+ set_GPIO_mode(GPIO42_BTRXD_MD);
-+ set_GPIO_mode(GPIO43_BTTXD_MD);
-+ set_GPIO_mode(GPIO44_BTCTS_MD);
-+ set_GPIO_mode(GPIO45_BTRTS_MD);
-+#endif
-+
-+ if( cerf_debug > 1)
-+ {
-+ printk(KERN_INFO "GPDR0 0x%08x\n", GPDR0);
-+ printk(KERN_INFO "GPDR1 0x%08x\n", GPDR1);
-+ printk(KERN_INFO "GPDR2 0x%08x\n", GPDR2);
-+ printk(KERN_INFO "GPLR0 0x%08x\n", GPLR0);
-+ printk(KERN_INFO "GPLR1 0x%08x\n", GPLR1);
-+ printk(KERN_INFO "GPLR2 0x%08x\n", GPLR2);
-+ printk(KERN_INFO "GAFR0_L 0x%08x\n", GAFR0_L);
-+ printk(KERN_INFO "GAFR0_U 0x%08x\n", GAFR0_U);
-+ printk(KERN_INFO "GAFR1_L 0x%08x\n", GAFR1_L);
-+ printk(KERN_INFO "GAFR1_U 0x%08x\n", GAFR1_U);
-+ printk(KERN_INFO "GAFR2_L 0x%08x\n", GAFR2_L);
-+ printk(KERN_INFO "GAFR2_U 0x%08x\n", GAFR2_U);
-+ printk(KERN_INFO "CKEN = 0x%08x\n", CKEN);
-+ printk(KERN_INFO "ICCR0 = 0x%08x\n", ICCR0);
-+ printk(KERN_INFO "STISR = 0x%08x\n", STISR);
-+ }
-+}
-+
-+MACHINE_START(PXA_CERF, "CerfBoard PXA Reference Board")
-+ MAINTAINER("Intrinsyc Software Inc.")
-+ BOOT_MEM(0xa0000000, 0x40000000, 0xfc000000)
-+ BOOT_PARAMS(0xa0000100)
-+ FIXUP(fixup_cerf)
-+ MAPIO(cerf_map_io)
-+ INITIRQ(cerf_init_irq)
-+MACHINE_END
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/cpu-pxa.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,240 @@
-+/*
-+ * linux/arch/arm/mach-pxa/cpu-pxa.c
-+ *
-+ * Copyright (C) 2002,2003 Intrinsyc Software
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * History:
-+ * 31-Jul-2002 : Initial version [FB]
-+ * 29-Jan-2003 : added PXA255 support [FB]
-+ *
-+ * Note:
-+ *
-+ * Quote from erratum 134:
-+ * ""If the operation of these peripherals would be adversely affected,
-+ * then these peripherals would have to be disabled during a frequency
-+ * change. (MMC,FFUART,STUART,BTUART,IRDA,SSP,UDC,AC97)""
-+ *
-+ * This sounds like they are not sure what the bug is...
-+ * If you run into problems with any of these peripherals, the effected
-+ * driver should register with cpu freq notification and disable/enable
-+ * the peripheral on CPUFREQ_PRECHANGE and CPUFREQ_POSTCHANGE.
-+ *
-+ * So far I've tested this code only under light load. It works for me.
-+ *
-+ * TODO:
-+ * - determine min/max freq at runtime
-+ * - determine pxbus value at runtime
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/sched.h>
-+#include <linux/init.h>
-+#include <linux/cpufreq.h>
-+
-+#include <asm/hardware.h>
-+
-+#define DEBUGGING 1
-+
-+#if DEBUGGING
-+static unsigned int freq_debug = DEBUGGING;
-+#else
-+#define freq_debug 0
-+#endif
-+
-+typedef struct
-+{
-+ unsigned int khz;
-+ unsigned int cccr;
-+ unsigned int pxbus;
-+} pxa_freqs_t;
-+
-+#define CCLKCFG_TURBO 0x1
-+#define CCLKCFG_FCS 0x2
-+
-+#define PXA250_REV_A1 0x1
-+#define PXA250_REV_B2 0x4
-+#define PXA25x_MIN_FREQ 99000
-+
-+//#define PXA25x_ALLOW_OVERCLOCK
-+
-+#ifdef PXA25x_ALLOW_OVERCLOCK
-+#warning *** Overclocking enabled - this may fry your hardware - you have been warned ***
-+#define OC(x...) x
-+#define PXA25x_MAX_FREQ 471000
-+#else
-+#define OC(x...)
-+#define PXA25x_MAX_FREQ 400000
-+#endif
-+
-+/* If CONFIG_CPU_FREQ is turned on but we find (at runtime)
-+ * we can't support scaling, try to handle requests gracefully.
-+ */
-+static int supported;
-+
-+static pxa_freqs_t pxa250_valid_freqs[] =
-+{
-+ {199100, 0x141, 99}, /* mem= 99, run=199, turbo=199, PXbus= 99 */
-+ {298600, 0x1c1, 99}, /* mem= 99, run=199, turbo=298, PXbus= 99 */
-+ {398100, 0x241, 99}, /* mem= 99, run=199, turbo=398, PXbus= 99 */
-+ {0,0}
-+};
-+
-+static pxa_freqs_t pxa255_valid_freqs[] =
-+{
-+ { 99000, 0x121, 50}, /* mem= 99, run= 99, turbo= 99, PXbus= 50 */
-+OC( {118000, 0x122, 59},)/* mem=118, run=118, turbo=118, PXbus= 59 OC'd mem */
-+ {199100, 0x141, 99}, /* mem= 99, run=199, turbo=199, PXbus= 99 */
-+OC( {236000, 0x142,118},)/* mem=118, run=236, turbo=236, PXbus=118 OC'd mem */
-+ {298600, 0x1c1, 99}, /* mem= 99, run=199, turbo=298, PXbus= 99 */
-+OC( {354000, 0x1c2,118},)/* mem=118, run=236, turbo=354, PXbus=118 OC'd mem */
-+ {398099, 0x241, 99}, /* mem= 99, run=199, turbo=398, PXbus= 99 */
-+ {398100, 0x161,196}, /* mem= 99, run=398, turbo=398, PXbus=196 */
-+OC( {471000, 0x162,236},)/* mem=118, run=471, turbo=471, PXbus=236 OC'd mem/core/bus */
-+ {0,0}
-+};
-+
-+static pxa_freqs_t *pxa_valid_freqs;
-+
-+/* This should be called with a valid freq point that was
-+ * obtained via pxa_validate_speed
-+ */
-+static pxa_freqs_t * pxa_get_freq_info( unsigned int khz)
-+{
-+ int i=0;
-+ while( pxa_valid_freqs[i].khz)
-+ {
-+ if( pxa_valid_freqs[i].khz == khz)
-+ return &pxa_valid_freqs[i];
-+ i++;
-+ }
-+
-+ /* shouldn't get here */
-+ return 0;
-+}
-+
-+/* find a valid frequency point */
-+static unsigned int pxa_validate_speed(unsigned int khz)
-+{
-+ int i=0;
-+ unsigned int vfreq = 0;
-+ while( pxa_valid_freqs[i].khz && (khz >= pxa_valid_freqs[i].khz))
-+ {
-+ vfreq = pxa_valid_freqs[i].khz;
-+ i++;
-+ }
-+ return vfreq;
-+}
-+
-+/* This should be called with a valid freq point that was
-+ * obtained via pxa_validate_speed
-+ */
-+static void pxa_setspeed(unsigned int khz)
-+{
-+ unsigned long flags;
-+ unsigned int unused;
-+ void *ramstart = phys_to_virt(0xa0000000);
-+ pxa_freqs_t *freq_info;
-+
-+ if( ! supported) return;
-+
-+ freq_info = pxa_get_freq_info( khz);
-+
-+ if( ! freq_info) return;
-+
-+ CCCR = freq_info->cccr;
-+ if( freq_debug)
-+ printk(KERN_INFO "Changing CPU frequency to %d Mhz (PXbus=%dMhz).\n",
-+ khz/1000, freq_info->pxbus);
-+
-+ local_irq_save(flags);
-+ __asm__ __volatile__("\
-+ ldr r4, [%1] @load MDREFR \n\
-+ b 2f \n\
-+ .align 5 \n\
-+1: \n\
-+ mcr p14, 0, %2, c6, c0, 0 @ set CCLKCFG[FCS] \n\
-+ \n\
-+ @ restart sdcke 0 / 1 \n\
-+ bic r5, r4, #(0x00001000 | 0x00008000) @ MDREFR_E0PIN | MDREFR_E1PIN \n\
-+ str r5, [%1] @clear \n\
-+ str r4, [%1] @restore \n\
-+ \n\
-+ @ Generate refresh cycles for all banks \n\
-+ ldr r4, [%3] \n\
-+ str r4, [%3] \n\
-+ str r4, [%3] \n\
-+ str r4, [%3] \n\
-+ str r4, [%3] \n\
-+ str r4, [%3] \n\
-+ str r4, [%3] \n\
-+ str r4, [%3] \n\
-+ str r4, [%3] \n\
-+ \n\
-+ b 3f \n\
-+2: b 1b \n\
-+3: nop \n\
-+ "
-+ : "=&r" (unused)
-+ : "r" (&MDREFR), "r" (CCLKCFG_TURBO|CCLKCFG_FCS), "r" (ramstart)
-+ : "r4", "r5");
-+ local_irq_restore(flags);
-+}
-+
-+static int pxa_init_freqs( void)
-+{
-+ int cpu_ver;
-+ asm("mrc%? p15, 0, %0, c0, c0" : "=r" (cpu_ver));
-+
-+ if( (cpu_ver & 0xf) <= PXA250_REV_A1)
-+ {
-+ return 0;
-+ }
-+
-+ if( (cpu_ver & 0xf) <= PXA250_REV_B2)
-+ {
-+ if( freq_debug) printk(KERN_INFO "Using PXA250 frequency points.\n");
-+ pxa_valid_freqs = pxa250_valid_freqs;
-+ }
-+ else /* C0 and above */
-+ {
-+ if( freq_debug) printk(KERN_INFO "Using PXA255 frequency points.\n");
-+ pxa_valid_freqs = pxa255_valid_freqs;
-+ }
-+
-+ return 1;
-+}
-+
-+static int __init pxa_clk_init(void)
-+{
-+ if( pxa_init_freqs())
-+ {
-+ if( freq_debug) printk(KERN_INFO "Registering CPU frequency change support.\n");
-+ supported = 1;
-+
-+ cpufreq_init( get_clk_frequency_khz(0), PXA25x_MIN_FREQ, PXA25x_MAX_FREQ);
-+ cpufreq_setfunctions(pxa_validate_speed, pxa_setspeed);
-+ }
-+ else
-+ {
-+ if( freq_debug) printk(KERN_INFO "Disabling CPU frequency change support.\n");
-+ /* Note that we have to initialize the generic code in order to
-+ * release a lock (cpufreq_sem). Any registration for freq changes
-+ * (e.g. lcd driver) will get blocked otherwise.
-+ */
-+ cpufreq_init( 0, 0, 0);
-+ cpufreq_setfunctions(pxa_validate_speed, pxa_setspeed);
-+ }
-+
-+ return 0;
-+}
-+
-+module_init(pxa_clk_init);
-+
-+MODULE_AUTHOR ("Intrinsyc Software Inc.");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/csb226.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,180 @@
-+/*
-+ * linux/arch/arm/mach-pxa/csb226.c
-+ *
-+ * (c) 2003 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/major.h>
-+#include <linux/fs.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+
-+#include <asm/types.h>
-+#include <asm/setup.h>
-+#include <asm/memory.h>
-+#include <asm/mach-types.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+
-+#include <asm/mach/arch.h>
-+#include <asm/mach/map.h>
-+#include <asm/mach/irq.h>
-+
-+#include <asm/arch/irq.h>
-+#include <asm/arch/irqs.h>
-+#include <asm/hardware/sa1111.h>
-+
-+#include "generic.h"
-+
-+static unsigned long csb226_irq_en_mask;
-+
-+static void csb226_mask_and_ack_irq(unsigned int irq)
-+{
-+ int csb226_irq = (irq - CSB226_IRQ(0));
-+ csb226_irq_en_mask &= ~(1 << csb226_irq);
-+ CSB226_IRQ_MASK_EN &= ~(1 << csb226_irq);
-+ CSB226_IRQ_SET_CLR &= ~(1 << csb226_irq);
-+}
-+
-+static void csb226_mask_irq(unsigned int irq)
-+{
-+ int csb226_irq = (irq - CSB226_IRQ(0));
-+ csb226_irq_en_mask &= ~(1 << csb226_irq);
-+ CSB226_IRQ_MASK_EN &= ~(1 << csb226_irq);
-+}
-+
-+static void csb226_unmask_irq(unsigned int irq)
-+{
-+ int csb226_irq = (irq - CSB226_IRQ(0));
-+ csb226_irq_en_mask |= (1 << csb226_irq);
-+ CSB226_IRQ_MASK_EN |= (1 << csb226_irq);
-+}
-+
-+void csb226_irq_demux(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ unsigned long irq_status;
-+ int i;
-+
-+ while ((irq_status = CSB226_IRQ_SET_CLR & csb226_irq_en_mask)) {
-+ for (i = 0; i < 6; i++) {
-+ if(irq_status & (1<<i))
-+ do_IRQ(CSB226_IRQ(i), regs);
-+ }
-+ }
-+}
-+
-+/* FIXME: this should not be necessary on csb226 */
-+static struct irqaction csb226_irq = {
-+ name: "CSB226 FPGA",
-+ handler: csb226_irq_demux,
-+ flags: SA_INTERRUPT
-+};
-+
-+static void __init csb226_init_irq(void)
-+{
-+ int irq;
-+
-+ pxa_init_irq();
-+
-+ /* setup extra csb226 irqs */
-+/* RS: ???
-+ for(irq = CSB226_IRQ(0); irq <= CSB226_IRQ(5); irq++)
-+ {
-+ irq_desc[irq].valid = 1;
-+ irq_desc[irq].probe_ok = 1;
-+ irq_desc[irq].mask_ack = csb226_mask_and_ack_irq;
-+ irq_desc[irq].mask = csb226_mask_irq;
-+ irq_desc[irq].unmask = csb226_unmask_irq;
-+ }
-+
-+ set_GPIO_IRQ_edge(GPIO_CSB226_IRQ, GPIO_FALLING_EDGE);
-+ setup_arm_irq(IRQ_GPIO_CSB226_IRQ, &csb226_irq);
-+*/
-+}
-+
-+/* FIXME: not necessary on CSB226? */
-+static int __init csb226_init(void)
-+{
-+ int ret;
-+
-+ return 0;
-+}
-+
-+__initcall(csb226_init);
-+
-+static void __init
-+fixup_csb226(struct machine_desc *desc, struct param_struct *params,
-+ char **cmdline, struct meminfo *mi)
-+{
-+ SET_BANK (0, 0xa0000000, 64*1024*1024);
-+ mi->nr_banks = 1;
-+#if 0
-+ setup_ramdisk (1, 0, 0, 8192);
-+ setup_initrd (__phys_to_virt(0xa1000000), 4*1024*1024);
-+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
-+#endif
-+}
-+
-+/* FIXME: shouldn't this be moved to arch/arm/mach-pxa/mm.c? [RS] */
-+static struct map_desc csb226_io_desc[] __initdata = {
-+ /* virtual physical length domain r w c b */
-+// { 0xf4000000, 0x04000000, 0x00ffffff, DOMAIN_IO, 1, 1, 0, 0 }, /* HT4562B PS/2 controller */
-+ { 0xf8000000, 0x08000000, 1024*1024, DOMAIN_IO, 0, 1, 0, 0 }, /* CS8900 LAN controller */
-+// { 0xe0000000, 0x20000000, 0x0fffffff, DOMAIN_IO, 1, 1, 0, 0 }, /* CompactFlash */
-+#if 0
-+ { 0xf0000000, 0x08000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */
-+ { 0xf1000000, 0x0c000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* LAN91C96 IO */
-+ { 0xf1100000, 0x0e000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* LAN91C96 Attr */
-+ { 0xf4000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA1111 */
-+#endif
-+ LAST_DESC
-+};
-+
-+static void __init csb226_map_io(void)
-+{
-+ pxa_map_io();
-+ iotable_init(csb226_io_desc);
-+
-+ /* This enables the BTUART */
-+ CKEN |= CKEN7_BTUART;
-+ set_GPIO_mode(GPIO42_BTRXD_MD);
-+ set_GPIO_mode(GPIO43_BTTXD_MD);
-+ set_GPIO_mode(GPIO44_BTCTS_MD);
-+ set_GPIO_mode(GPIO45_BTRTS_MD);
-+
-+ /* This is for the CS8900 chip select */
-+ set_GPIO_mode(GPIO78_nCS_2_MD);
-+
-+ /* setup sleep mode values */
-+ PWER = 0x00000002;
-+ PFER = 0x00000000;
-+ PRER = 0x00000002;
-+ PGSR0 = 0x00008000;
-+ PGSR1 = 0x003F0202;
-+ PGSR2 = 0x0001C000;
-+ PCFR |= PCFR_OPDE;
-+}
-+
-+MACHINE_START(CSB226, "Cogent CSB226 Development Platform")
-+ MAINTAINER("Robert Schwebel, Pengutronix")
-+ BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-+ BOOT_PARAMS(0xa0000100)
-+ FIXUP(fixup_csb226)
-+ MAPIO(csb226_map_io)
-+ INITIRQ(csb226_init_irq)
-+MACHINE_END
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/dma.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,131 @@
-+/*
-+ * linux/arch/arm/mach-pxa/dma.c
-+ *
-+ * PXA DMA registration and IRQ dispatching
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Nov 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+
-+#include <asm/system.h>
-+#include <asm/irq.h>
-+#include <asm/hardware.h>
-+#include <asm/dma.h>
-+
-+
-+static struct dma_channel {
-+ char *name;
-+ void (*irq_handler)(int, void *, struct pt_regs *);
-+ void *data;
-+} dma_channels[16];
-+
-+
-+int pxa_request_dma (char *name, pxa_dma_prio prio,
-+ void (*irq_handler)(int, void *, struct pt_regs *),
-+ void *data)
-+{
-+ unsigned long flags;
-+ int i, found = 0;
-+
-+ /* basic sanity checks */
-+ if (!name || !irq_handler)
-+ return -EINVAL;
-+
-+ local_irq_save(flags);
-+
-+ /* try grabbing a DMA channel with the requested priority */
-+ for (i = prio; i < prio + (prio == DMA_PRIO_LOW) ? 8 : 4; i++) {
-+ if (!dma_channels[i].name) {
-+ found = 1;
-+ break;
-+ }
-+ }
-+
-+ if (!found) {
-+ /* requested prio group is full, try hier priorities */
-+ for (i = prio-1; i >= 0; i--) {
-+ if (!dma_channels[i].name) {
-+ found = 1;
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (found) {
-+ DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
-+ dma_channels[i].name = name;
-+ dma_channels[i].irq_handler = irq_handler;
-+ dma_channels[i].data = data;
-+ } else {
-+ printk (KERN_WARNING "No more available DMA channels for %s\n", name);
-+ i = -ENODEV;
-+ }
-+
-+ local_irq_restore(flags);
-+ return i;
-+}
-+
-+void pxa_free_dma (int dma_ch)
-+{
-+ unsigned long flags;
-+
-+ if (!dma_channels[dma_ch].name) {
-+ printk (KERN_CRIT __FUNCTION__
-+ ": trying to free channel %d which is already freed\n",
-+ dma_ch);
-+ return;
-+ }
-+
-+ local_irq_save(flags);
-+ DCSR(dma_ch) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
-+ dma_channels[dma_ch].name = NULL;
-+ local_irq_restore(flags);
-+}
-+
-+static void dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ int i, dint = DINT;
-+
-+ for (i = 0; i < 16; i++) {
-+ if (dint & (1 << i)) {
-+ struct dma_channel *channel = &dma_channels[i];
-+ if (channel->name && channel->irq_handler) {
-+ channel->irq_handler(i, channel->data, regs);
-+ } else {
-+ /*
-+ * IRQ for an unregistered DMA channel:
-+ * let's clear the interrupts and disable it.
-+ */
-+ printk (KERN_WARNING "spurious IRQ for DMA channel %d\n", i);
-+ DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR;
-+ }
-+ }
-+ }
-+}
-+
-+static int __init pxa_dma_init (void)
-+{
-+ int ret;
-+
-+ ret = request_irq (IRQ_DMA, dma_irq_handler, 0, "DMA", NULL);
-+ if (ret)
-+ printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n");
-+ return ret;
-+}
-+
-+__initcall(pxa_dma_init);
-+
-+EXPORT_SYMBOL(pxa_request_dma);
-+EXPORT_SYMBOL(pxa_free_dma);
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/generic.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,142 @@
-+/*
-+ * linux/arch/arm/mach-pxa/generic.c
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Jun 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * Code common to all PXA machines.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Since this file should be linked before any other machine specific file,
-+ * the __initcall() here will be executed first. This serves as default
-+ * initialization stuff for PXA machines which can be overriden later if
-+ * need be.
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/pm.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/system.h>
-+#include <asm/pgtable.h>
-+#include <asm/mach/map.h>
-+
-+#include "generic.h"
-+
-+/*
-+ * Various clock factors driven by the CCCR register.
-+ */
-+
-+/* Crystal Frequency to Memory Frequency Multiplier (L) */
-+static unsigned char L_clk_mult[32] = { 0, 27, 32, 36, 40, 45, 0, };
-+
-+/* Memory Frequency to Run Mode Frequency Multiplier (M) */
-+static unsigned char M_clk_mult[4] = { 0, 1, 2, 4 };
-+
-+/* Run Mode Frequency to Turbo Mode Frequency Multiplier (N) */
-+/* Note: we store the value N * 2 here. */
-+static unsigned char N2_clk_mult[8] = { 0, 0, 2, 3, 4, 0, 6, 0 };
-+
-+/* Crystal clock */
-+#define BASE_CLK 3686400
-+
-+/*
-+ * Get the clock frequency as reflected by CCCR and the turbo flag.
-+ * We assume these values have been applied via a fcs.
-+ * If info is not 0 we also display the current settings.
-+ */
-+unsigned int get_clk_frequency_khz( int info)
-+{
-+ unsigned long cccr, turbo;
-+ unsigned int l, L, m, M, n2, N;
-+
-+ cccr = CCCR;
-+ asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (turbo) );
-+
-+ l = L_clk_mult[(cccr >> 0) & 0x1f];
-+ m = M_clk_mult[(cccr >> 5) & 0x03];
-+ n2 = N2_clk_mult[(cccr >> 7) & 0x07];
-+
-+ L = l * BASE_CLK;
-+ M = m * L;
-+ N = n2 * M / 2;
-+
-+ if( info)
-+ {
-+ L += 5000;
-+ printk( KERN_INFO "Memory clock: %d.%02dMHz (*%d)\n",
-+ L / 1000000, (L % 1000000) / 10000, l );
-+ M += 5000;
-+ printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n",
-+ M / 1000000, (M % 1000000) / 10000, m );
-+ N += 5000;
-+ printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n",
-+ N / 1000000, (N % 1000000) / 10000, n2 / 2, (n2 % 2) * 5,
-+ (turbo & 1) ? "" : "in" );
-+ }
-+
-+ return (turbo & 1) ? (N/1000) : (M/1000);
-+}
-+
-+EXPORT_SYMBOL(get_clk_frequency_khz);
-+
-+/*
-+ * Return the current lclk requency in units of 10kHz
-+ */
-+unsigned int get_lclk_frequency_10khz(void)
-+{
-+ return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK / 10000;
-+}
-+
-+EXPORT_SYMBOL(get_lclk_frequency_10khz);
-+
-+/*
-+ * Handy function to set GPIO alternate functions
-+ */
-+
-+void set_GPIO_mode(int gpio_mode)
-+{
-+ long flags;
-+ int gpio = gpio_mode & GPIO_MD_MASK_NR;
-+ int fn = (gpio_mode & GPIO_MD_MASK_FN) >> 8;
-+ int gafr;
-+
-+ local_irq_save(flags);
-+ if (gpio_mode & GPIO_MD_MASK_DIR)
-+ GPDR(gpio) |= GPIO_bit(gpio);
-+ else
-+ GPDR(gpio) &= ~GPIO_bit(gpio);
-+ gafr = GAFR(gpio) & ~(0x3 << (((gpio) & 0xf)*2));
-+ GAFR(gpio) = gafr | (fn << (((gpio) & 0xf)*2));
-+ local_irq_restore(flags);
-+}
-+
-+EXPORT_SYMBOL(set_GPIO_mode);
-+
-+/*
-+ * Note that 0xfffe0000-0xffffffff is reserved for the vector table and
-+ * cache flush area.
-+ */
-+static struct map_desc standard_io_desc[] __initdata = {
-+ /* virtual physical length domain r w c b */
-+ { 0xf6000000, 0x20000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA0 IO */
-+ { 0xf7000000, 0x30000000, 0x01000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA1 IO */
-+ { 0xf8000000, 0x40000000, 0x01800000, DOMAIN_IO, 0, 1, 0, 0 }, /* Devs */
-+ { 0xfa000000, 0x44000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* LCD */
-+ { 0xfc000000, 0x48000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* Mem Ctl */
-+ { 0xff000000, 0x00000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* UNCACHED_PHYS_0 */
-+ LAST_DESC
-+};
-+
-+void __init pxa_map_io(void)
-+{
-+ iotable_init(standard_io_desc);
-+ get_clk_frequency_khz( 1);
-+}
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/generic.h 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,19 @@
-+/*
-+ * linux/arch/arm/mach-pxa/generic.h
-+ *
-+ * Author: Nicolas Pitre
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+extern void __init pxa_map_io(void);
-+extern void __init pxa_init_irq(void);
-+
-+#define SET_BANK(__nr,__start,__size) \
-+ mi->bank[__nr].start = (__start), \
-+ mi->bank[__nr].size = (__size), \
-+ mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27)
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/idp.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,142 @@
-+/*
-+ * linux/arch/arm/mach-pxa/idp.c
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Copyright (c) 2001 Cliff Brake, Accelent Systems Inc.
-+ *
-+ * 2001-09-13: Cliff Brake <cbrake@accelent.com>
-+ * Initial code
-+ */
-+#include <linux/init.h>
-+#include <linux/major.h>
-+#include <linux/fs.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+
-+#include <asm/types.h>
-+#include <asm/setup.h>
-+#include <asm/memory.h>
-+#include <asm/mach-types.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+
-+#include <asm/mach/arch.h>
-+#include <asm/mach/map.h>
-+#include <asm/mach/irq.h>
-+
-+#include <asm/arch/irq.h>
-+
-+#include "generic.h"
-+
-+#define PXA_IDP_REV02
-+
-+#ifndef PXA_IDP_REV02
-+/* shadow registers for write only registers */
-+unsigned int idp_cpld_led_control_shadow = 0x1;
-+unsigned int idp_cpld_periph_pwr_shadow = 0xd;
-+unsigned int ipd_cpld_cir_shadow = 0;
-+unsigned int idp_cpld_kb_col_high_shadow = 0;
-+unsigned int idp_cpld_kb_col_low_shadow = 0;
-+unsigned int idp_cpld_pccard_en_shadow = 0xC3;
-+unsigned int idp_cpld_gpioh_dir_shadow = 0;
-+unsigned int idp_cpld_gpioh_value_shadow = 0;
-+unsigned int idp_cpld_gpiol_dir_shadow = 0;
-+unsigned int idp_cpld_gpiol_value_shadow = 0;
-+
-+/*
-+ * enable all LCD signals -- they should still be on
-+ * write protect flash
-+ * enable all serial port transceivers
-+ */
-+
-+unsigned int idp_control_port_shadow = ((0x7 << 21) | /* LCD power */
-+ (0x1 << 19) | /* disable flash write enable */
-+ (0x7 << 9)); /* enable serial port transeivers */
-+
-+#endif
-+
-+static int __init idp_init(void)
-+{
-+ printk("idp_init()\n");
-+ return 0;
-+}
-+
-+__initcall(idp_init);
-+
-+static void __init idp_init_irq(void)
-+{
-+ pxa_init_irq();
-+}
-+
-+static void __init
-+fixup_idp(struct machine_desc *desc, struct param_struct *params,
-+ char **cmdline, struct meminfo *mi)
-+{
-+#ifdef PXA_IDP_REV02
-+ SET_BANK (0, 0xa0000000, 64*1024*1024);
-+#else
-+ SET_BANK (0, 0xa0000000, 32*1024*1024);
-+#endif
-+ mi->nr_banks = 1;
-+#if 0
-+ setup_ramdisk (1, 0, 0, 8192);
-+ setup_initrd (__phys_to_virt(0xa1000000), 4*1024*1024);
-+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
-+#endif
-+}
-+
-+static struct map_desc idp_io_desc[] __initdata = {
-+ /* virtual physical length domain r w c b */
-+
-+
-+#ifndef PXA_IDP_REV02
-+ { IDP_CTRL_PORT_BASE,
-+ IDP_CTRL_PORT_PHYS,
-+ IDP_CTRL_PORT_SIZE,
-+ DOMAIN_IO,
-+ 0, 1, 0, 0 },
-+#endif
-+
-+ { IDP_IDE_BASE,
-+ IDP_IDE_PHYS,
-+ IDP_IDE_SIZE,
-+ DOMAIN_IO,
-+ 0, 1, 0, 0 },
-+ { IDP_ETH_BASE,
-+ IDP_ETH_PHYS,
-+ IDP_ETH_SIZE,
-+ DOMAIN_IO,
-+ 0, 1, 0, 0 },
-+ { IDP_COREVOLT_BASE,
-+ IDP_COREVOLT_PHYS,
-+ IDP_COREVOLT_SIZE,
-+ DOMAIN_IO,
-+ 0, 1, 0, 0 },
-+ { IDP_CPLD_BASE,
-+ IDP_CPLD_PHYS,
-+ IDP_CPLD_SIZE,
-+ DOMAIN_IO,
-+ 0, 1, 0, 0 },
-+
-+ LAST_DESC
-+};
-+
-+static void __init idp_map_io(void)
-+{
-+ pxa_map_io();
-+ iotable_init(idp_io_desc);
-+
-+ set_GPIO_IRQ_edge(IRQ_TO_GPIO(TOUCH_PANEL_IRQ), TOUCH_PANEL_IRQ_EDGE);
-+ set_GPIO_IRQ_edge(IRQ_TO_GPIO(SMC_IRQ), GPIO_RISING_EDGE);
-+}
-+
-+MACHINE_START(PXA_IDP, "Accelent Xscale IDP")
-+ MAINTAINER("Accelent Systems Inc.")
-+ BOOT_MEM(0xa0000000, 0x40000000, 0xfc000000)
-+ FIXUP(fixup_idp)
-+ MAPIO(idp_map_io)
-+ INITIRQ(idp_init_irq)
-+MACHINE_END
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/innokom.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,129 @@
-+/*
-+ * linux/arch/arm/mach-pxa/innokom.c
-+ *
-+ * (c) 2003 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/major.h>
-+#include <linux/fs.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+
-+#include <asm/types.h>
-+#include <asm/setup.h>
-+#include <asm/memory.h>
-+#include <asm/mach-types.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+
-+#include <asm/mach/arch.h>
-+#include <asm/mach/map.h>
-+#include <asm/mach/irq.h>
-+
-+#include <asm/arch/irq.h>
-+#include <asm/arch/irqs.h>
-+#include <asm/hardware/sa1111.h>
-+
-+#include "generic.h"
-+
-+
-+static void __init innokom_init_irq(void)
-+{
-+ pxa_init_irq();
-+}
-+
-+
-+void sw_update_handler( int irq, void* dev_id,struct pt_regs* regs)
-+{
-+}
-+
-+
-+void reset_handler( int irq, void* dev_id,struct pt_regs* regs)
-+{
-+}
-+
-+
-+static int __init innokom_init(void)
-+{
-+ int sw_irq = GPIO_2_80_TO_IRQ(11); /* software update button */
-+ int reset_irq = GPIO_2_80_TO_IRQ(3); /* reset button */
-+
-+ set_GPIO_IRQ_edge(11,GPIO_FALLING_EDGE);
-+ if (request_irq(sw_irq,sw_update_handler,SA_INTERRUPT,"software update button",NULL))
-+ printk(KERN_INFO "innokom: can't get assigned irq %i\n",sw_irq);
-+
-+ set_GPIO_IRQ_edge(3,GPIO_FALLING_EDGE);
-+ if (request_irq(reset_irq,reset_handler,SA_INTERRUPT,"reset button",NULL))
-+ printk(KERN_INFO "innokom: can't get assigned irq %i\n",reset_irq);
-+
-+ return 0;
-+}
-+
-+
-+__initcall(innokom_init);
-+
-+
-+static void __init
-+fixup_innokom(struct machine_desc *desc, struct param_struct *params,
-+ char **cmdline, struct meminfo *mi)
-+{
-+ /* we probably want to get this information from the bootloader later */
-+ SET_BANK (0, 0xa0000000, 64*1024*1024);
-+ mi->nr_banks = 1;
-+}
-+
-+
-+/* memory mapping */
-+static struct map_desc innokom_io_desc[] __initdata = {
-+/* virtual physical length domain r w c b */
-+ { INNOKOM_ETH_BASE, INNOKOM_ETH_PHYS, INNOKOM_ETH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, /* ETH SMSC 91111 */
-+ LAST_DESC
-+};
-+
-+static void __init innokom_map_io(void)
-+{
-+ pxa_map_io();
-+ iotable_init(innokom_io_desc);
-+
-+ /* Enable the BTUART */
-+ CKEN |= CKEN7_BTUART;
-+ set_GPIO_mode(GPIO42_BTRXD_MD);
-+ set_GPIO_mode(GPIO43_BTTXD_MD);
-+ set_GPIO_mode(GPIO44_BTCTS_MD);
-+ set_GPIO_mode(GPIO45_BTRTS_MD);
-+
-+ set_GPIO_mode(GPIO33_nCS_5_MD); /* SMSC network chip */
-+
-+ /* setup sleep mode values */
-+ PWER = 0x00000002;
-+ PFER = 0x00000000;
-+ PRER = 0x00000002;
-+ PGSR0 = 0x00008000;
-+ PGSR1 = 0x003F0202;
-+ PGSR2 = 0x0001C000;
-+ PCFR |= PCFR_OPDE;
-+}
-+
-+MACHINE_START(INNOKOM, "Auerswald Innokom")
-+ MAINTAINER("Robert Schwebel, Pengutronix")
-+ BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-+ BOOT_PARAMS(0xa0000100)
-+ FIXUP(fixup_innokom)
-+ MAPIO(innokom_map_io)
-+ INITIRQ(innokom_init_irq)
-+MACHINE_END
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/irq.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,282 @@
-+/*
-+ * linux/arch/arm/mach-pxa/irq.c
-+ *
-+ * Generic PXA IRQ handling, GPIO IRQ demultiplexing, etc.
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Jun 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/ptrace.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/mach/irq.h>
-+#include <asm/arch/irq.h>
-+
-+#include "generic.h"
-+
-+
-+/*
-+ * PXA GPIO edge detection for IRQs:
-+ * IRQs are generated on Falling-Edge, Rising-Edge, or both.
-+ * This must be called *before* the appropriate IRQ is registered.
-+ * Use this instead of directly setting GRER/GFER.
-+ */
-+
-+static int GPIO_IRQ_rising_edge[3];
-+static int GPIO_IRQ_falling_edge[3];
-+
-+void set_GPIO_IRQ_edge (int gpio_nr, int edge)
-+{
-+ long flags;
-+ local_irq_save(flags);
-+ set_GPIO_mode(gpio_nr | GPIO_IN);
-+ if (edge & GPIO_FALLING_EDGE)
-+ set_bit (gpio_nr, GPIO_IRQ_falling_edge);
-+ else
-+ clear_bit (gpio_nr, GPIO_IRQ_falling_edge);
-+ if (edge & GPIO_RISING_EDGE)
-+ set_bit (gpio_nr, GPIO_IRQ_rising_edge);
-+ else
-+ clear_bit (gpio_nr, GPIO_IRQ_rising_edge);
-+ irq_desc[IRQ_GPIO(gpio_nr)].valid = 1;
-+ local_irq_restore(flags);
-+}
-+
-+EXPORT_SYMBOL(set_GPIO_IRQ_edge);
-+
-+
-+/*
-+ * We don't need to ACK IRQs on the PXA unless they're GPIOs
-+ * this is for IRQs known as PXA_IRQ([10...31]).
-+ */
-+
-+static void pxa_mask_irq(unsigned int irq)
-+{
-+ ICMR &= ~(1 << (irq + PXA_IRQ_SKIP));
-+}
-+
-+static void pxa_unmask_irq(unsigned int irq)
-+{
-+ ICMR |= (1 << (irq + PXA_IRQ_SKIP));
-+}
-+
-+/*
-+ * GPIO IRQs must be acknoledged. This is for GPIO 0 and 1.
-+ */
-+
-+static void pxa_mask_and_ack_GPIO_0_1_irq(unsigned int irq)
-+{
-+ ICMR &= ~(1 << (irq + PXA_IRQ_SKIP));
-+ GEDR0 = (1 << (irq - IRQ_GPIO0));
-+}
-+
-+static void pxa_mask_GPIO_0_1_irq(unsigned int irq)
-+{
-+ ICMR &= ~(1 << (irq + PXA_IRQ_SKIP));
-+}
-+
-+static void pxa_unmask_GPIO_0_1_irq(unsigned int irq)
-+{
-+ int gpio = irq - IRQ_GPIO0;
-+ GRER0 = (GRER0 & ~(1 << gpio))|(GPIO_IRQ_rising_edge[0] & (1 << gpio));
-+ GFER0 = (GFER0 & ~(1 << gpio))|(GPIO_IRQ_falling_edge[0] & (1 << gpio));
-+ ICMR |= (1 << (irq + PXA_IRQ_SKIP));
-+}
-+
-+/*
-+ * Demux handler for GPIO 2-80 edge detect interrupts
-+ */
-+
-+static int GPIO_2_80_enabled[3]; /* enabled i.e. unmasked GPIO IRQs */
-+static int GPIO_2_80_spurious[3]; /* GPIOs that triggered when masked */
-+
-+static void pxa_GPIO_2_80_demux(int irq, void *dev_id,
-+ struct pt_regs *regs)
-+{
-+ int i, gedr, spurious;
-+
-+ while ((gedr = (GEDR0 & ~3))) {
-+ /*
-+ * We don't want to clear GRER/GFER when the corresponding
-+ * IRQ is masked because we could miss a level transition
-+ * i.e. an IRQ which need servicing as soon as it is
-+ * unmasked. However, such situation should happen only
-+ * during the loop below. Thus all IRQs which aren't
-+ * enabled at this point are considered spurious. Those
-+ * are cleared but only de-activated if they happen twice.
-+ */
-+ spurious = gedr & ~GPIO_2_80_enabled[0];
-+ if (spurious) {
-+ GEDR0 = spurious;
-+ GRER0 &= ~(spurious & GPIO_2_80_spurious[0]);
-+ GFER0 &= ~(spurious & GPIO_2_80_spurious[0]);
-+ GPIO_2_80_spurious[0] |= spurious;
-+ gedr ^= spurious;
-+ if (!gedr) continue;
-+ }
-+
-+ for (i = 2; i < 32; ++i) {
-+ if (gedr & (1<<i)) {
-+ do_IRQ (IRQ_GPIO(2) + i - 2, regs);
-+ }
-+ }
-+ }
-+ while ((gedr = GEDR1)) {
-+ spurious = gedr & ~GPIO_2_80_enabled[1];
-+ if (spurious) {
-+ GEDR1 = spurious;
-+ GRER1 &= ~(spurious & GPIO_2_80_spurious[1]);
-+ GFER1 &= ~(spurious & GPIO_2_80_spurious[1]);
-+ GPIO_2_80_spurious[1] |= spurious;
-+ gedr ^= spurious;
-+ if (!gedr) continue;
-+ }
-+
-+ for (i = 0; i < 32; ++i) {
-+ if (gedr & (1<<i)) {
-+ do_IRQ (IRQ_GPIO(32) + i, regs);
-+ }
-+ }
-+ }
-+ while ((gedr = (GEDR2 & 0x0001ffff))) {
-+ spurious = gedr & ~GPIO_2_80_enabled[2];
-+ if (spurious) {
-+ GEDR2 = spurious;
-+ GRER2 &= ~(spurious & GPIO_2_80_spurious[2]);
-+ GFER2 &= ~(spurious & GPIO_2_80_spurious[2]);
-+ GPIO_2_80_spurious[2] |= spurious;
-+ gedr ^= spurious;
-+ if (!gedr) continue;
-+ }
-+
-+ for (i = 0; i < 17; ++i) {
-+ if (gedr & (1<<i)) {
-+ do_IRQ (IRQ_GPIO(64) + i, regs);
-+ }
-+ }
-+ }
-+}
-+
-+static struct irqaction GPIO_2_80_irqaction = {
-+ name: "GPIO 2-80",
-+ handler: pxa_GPIO_2_80_demux,
-+ flags: SA_INTERRUPT
-+};
-+
-+#define GRER_x(i) (*(&GRER0 + (i)))
-+#define GFER_x(i) (*(&GFER0 + (i)))
-+#define GEDR_x(i) (*(&GEDR0 + (i)))
-+#define GPLR_x(i) (*(&GPLR0 + (i)))
-+
-+static void pxa_mask_and_ack_GPIO_2_80_irq(unsigned int irq)
-+{
-+ int gpio_nr = IRQ_TO_GPIO_2_80(irq);
-+ int mask = 1 << (gpio_nr & 0x1f);
-+ int index = gpio_nr >> 5;
-+ GPIO_2_80_spurious[index] &= ~mask;
-+ GPIO_2_80_enabled[index] &= ~mask;
-+ GEDR_x(index) = mask;
-+}
-+
-+static void pxa_mask_GPIO_2_80_irq(unsigned int irq)
-+{
-+ int gpio_nr = IRQ_TO_GPIO_2_80(irq);
-+ int mask = 1 << (gpio_nr & 0x1f);
-+ int index = gpio_nr >> 5;
-+ GPIO_2_80_spurious[index] &= ~mask;
-+ GPIO_2_80_enabled[index] &= ~mask;
-+}
-+
-+static void pxa_unmask_GPIO_2_80_irq(unsigned int irq)
-+{
-+ int gpio_nr = IRQ_TO_GPIO_2_80(irq);
-+ int mask = 1 << (gpio_nr & 0x1f);
-+ int index = gpio_nr >> 5;
-+ if (GPIO_2_80_spurious[index] & mask) {
-+ /*
-+ * We don't want to miss an interrupt that would have occurred
-+ * while it was masked. Simulate it if it is the case.
-+ */
-+ int state = GPLR_x(index);
-+ if (((state & GPIO_IRQ_rising_edge[index]) |
-+ (~state & GPIO_IRQ_falling_edge[index])) & mask)
-+ {
-+ /* just in case it gets referenced: */
-+ struct pt_regs dummy;
-+
-+ memzero(&dummy, sizeof(dummy));
-+ do_IRQ(irq, &dummy);
-+
-+ /* we are being called recursively from do_IRQ() */
-+ return;
-+ }
-+ }
-+ GPIO_2_80_enabled[index] |= mask;
-+ GRER_x(index) =
-+ (GRER_x(index) & ~mask) | (GPIO_IRQ_rising_edge[index] & mask);
-+ GFER_x(index) =
-+ (GFER_x(index) & ~mask) | (GPIO_IRQ_falling_edge[index] & mask);
-+}
-+
-+
-+void __init pxa_init_irq(void)
-+{
-+ int irq;
-+
-+ /* disable all IRQs */
-+ ICMR = 0;
-+
-+ /* all IRQs are IRQ, not FIQ */
-+ ICLR = 0;
-+
-+ /* clear all GPIO edge detects */
-+ GFER0 = GFER1 = GFER2 = 0;
-+ GRER0 = GRER1 = GRER2 = 0;
-+ GEDR0 = GEDR0;
-+ GEDR1 = GEDR1;
-+ GEDR2 = GEDR2;
-+
-+ /* only unmasked interrupts kick us out of idle */
-+ ICCR = 1;
-+
-+ for (irq = PXA_IRQ(PXA_IRQ_SKIP); irq <= PXA_IRQ(31); irq++) {
-+ irq_desc[irq].valid = 1;
-+ irq_desc[irq].probe_ok = 0;
-+ irq_desc[irq].mask_ack = pxa_mask_irq;
-+ irq_desc[irq].mask = pxa_mask_irq;
-+ irq_desc[irq].unmask = pxa_unmask_irq;
-+ }
-+
-+ /*
-+ * Note: GPIO IRQs are initially invalid until set_GPIO_IRQ_edge()
-+ * is called at least once.
-+ */
-+
-+ for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
-+ irq_desc[irq].valid = 0;
-+ irq_desc[irq].probe_ok = 1;
-+ irq_desc[irq].mask_ack = pxa_mask_and_ack_GPIO_0_1_irq;
-+ irq_desc[irq].mask = pxa_mask_GPIO_0_1_irq;
-+ irq_desc[irq].unmask = pxa_unmask_GPIO_0_1_irq;
-+ }
-+
-+ for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(80); irq++) {
-+ irq_desc[irq].valid = 0;
-+ irq_desc[irq].probe_ok = 1;
-+ irq_desc[irq].mask_ack = pxa_mask_and_ack_GPIO_2_80_irq;
-+ irq_desc[irq].mask = pxa_mask_GPIO_2_80_irq;
-+ irq_desc[irq].unmask = pxa_unmask_GPIO_2_80_irq;
-+ }
-+ setup_arm_irq( IRQ_GPIO_2_80, &GPIO_2_80_irqaction );
-+}
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/leds-cerf.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,135 @@
-+/*
-+ * linux/arch/arm/mach-pxa/leds-cerf.c
-+ *
-+ * Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu>
-+ *
-+ * Copyright (c) 2001 Jeff Sutherland <jeffs@accelent.com>
-+ *
-+ * Original (leds-footbridge.c) by Russell King
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/leds.h>
-+#include <asm/system.h>
-+
-+#include "leds.h"
-+
-+
-+#define LED_STATE_ENABLED 1
-+#define LED_STATE_CLAIMED 2
-+
-+static unsigned int led_state;
-+static unsigned int hw_led_state;
-+
-+void pxa_cerf_leds_event(led_event_t evt)
-+{
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+
-+ switch (evt) {
-+ case led_start:
-+ hw_led_state = CERF_HEARTBEAT_LED;
-+ led_state = LED_STATE_ENABLED;
-+ break;
-+
-+ case led_stop:
-+ led_state &= ~LED_STATE_ENABLED;
-+ break;
-+
-+ case led_claim:
-+ led_state |= LED_STATE_CLAIMED;
-+ hw_led_state = CERF_HEARTBEAT_LED;
-+ break;
-+
-+ case led_release:
-+ led_state &= ~LED_STATE_CLAIMED;
-+ hw_led_state = CERF_HEARTBEAT_LED;
-+ break;
-+
-+#ifdef CONFIG_LEDS_TIMER
-+ case led_timer:
-+ if (!(led_state & LED_STATE_CLAIMED))
-+ hw_led_state ^= CERF_HEARTBEAT_LED;
-+ break;
-+#endif
-+
-+#ifdef CONFIG_LEDS_CPU
-+ case led_idle_start:
-+ if (!(led_state & LED_STATE_CLAIMED))
-+ hw_led_state |= CERF_SYS_BUSY_LED;
-+ break;
-+
-+ case led_idle_end:
-+ if (!(led_state & LED_STATE_CLAIMED))
-+ hw_led_state &= ~CERF_SYS_BUSY_LED;
-+ break;
-+#endif
-+
-+ case led_halted:
-+ break;
-+
-+ case led_green_on:
-+ if (led_state & LED_STATE_CLAIMED)
-+ hw_led_state &= ~CERF_HEARTBEAT_LED;
-+ break;
-+
-+ case led_green_off:
-+ if (led_state & LED_STATE_CLAIMED)
-+ hw_led_state |= CERF_HEARTBEAT_LED;
-+ break;
-+
-+ case led_amber_on:
-+ break;
-+
-+ case led_amber_off:
-+ break;
-+
-+#ifndef CONFIG_PXA_CERF_PDA
-+ case led_red_on:
-+ if (led_state & LED_STATE_CLAIMED)
-+ hw_led_state &= ~CERF_SYS_BUSY_LED;
-+ break;
-+
-+ case led_red_off:
-+ if (led_state & LED_STATE_CLAIMED)
-+ hw_led_state |= CERF_SYS_BUSY_LED;
-+ break;
-+#endif
-+ default:
-+ break;
-+ }
-+
-+ if (led_state & LED_STATE_ENABLED)
-+ {
-+ switch (hw_led_state) {
-+ case 0: // all on
-+ CERF_HEARTBEAT_LED_ON;
-+ CERF_SYS_BUSY_LED_ON;
-+ break;
-+ case 1: // turn off heartbeat, status on:
-+ CERF_HEARTBEAT_LED_OFF;
-+ CERF_SYS_BUSY_LED_ON;
-+ break;
-+ case 2: // status off, heartbeat on:
-+ CERF_HEARTBEAT_LED_ON;
-+ CERF_SYS_BUSY_LED_OFF;
-+ break;
-+ case 3: // turn them both off...
-+ CERF_HEARTBEAT_LED_OFF;
-+ CERF_SYS_BUSY_LED_OFF;
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ local_irq_restore(flags);
-+}
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/leds-idp.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,112 @@
-+/*
-+ * linux/arch/arm/mach-pxa/leds-idp.c
-+ *
-+ * Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu>
-+ *
-+ * Copyright (c) 2001 Jeff Sutherland <jeffs@accelent.com>
-+ *
-+ * Original (leds-footbridge.c) by Russell King
-+ *
-+ * Macros for actual LED manipulation should be in machine specific
-+ * files in this 'mach' directory.
-+ */
-+
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/leds.h>
-+#include <asm/system.h>
-+
-+#include "leds.h"
-+
-+#define LED_STATE_ENABLED 1
-+#define LED_STATE_CLAIMED 2
-+
-+static unsigned int led_state;
-+static unsigned int hw_led_state;
-+
-+void idp_leds_event(led_event_t evt)
-+{
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+
-+ switch (evt) {
-+ case led_start:
-+ hw_led_state = IDP_HB_LED | IDP_BUSY_LED;
-+ led_state = LED_STATE_ENABLED;
-+ break;
-+
-+ case led_stop:
-+ led_state &= ~LED_STATE_ENABLED;
-+ break;
-+
-+ case led_claim:
-+ led_state |= LED_STATE_CLAIMED;
-+ hw_led_state = IDP_HB_LED | IDP_BUSY_LED;
-+ break;
-+
-+ case led_release:
-+ led_state &= ~LED_STATE_CLAIMED;
-+ hw_led_state = IDP_HB_LED | IDP_BUSY_LED;
-+ break;
-+
-+#ifdef CONFIG_LEDS_TIMER
-+ case led_timer:
-+ if (!(led_state & LED_STATE_CLAIMED))
-+ hw_led_state ^= IDP_HB_LED;
-+ break;
-+#endif
-+
-+#ifdef CONFIG_LEDS_CPU
-+ case led_idle_start:
-+ if (!(led_state & LED_STATE_CLAIMED))
-+ hw_led_state |= IDP_BUSY_LED;
-+ break;
-+
-+ case led_idle_end:
-+ if (!(led_state & LED_STATE_CLAIMED))
-+ hw_led_state &= ~IDP_BUSY_LED;
-+ break;
-+#endif
-+
-+ case led_halted:
-+ break;
-+
-+ case led_green_on:
-+ if (led_state & LED_STATE_CLAIMED)
-+ hw_led_state &= ~IDP_HB_LED;
-+ break;
-+
-+ case led_green_off:
-+ if (led_state & LED_STATE_CLAIMED)
-+ hw_led_state |= IDP_HB_LED;
-+ break;
-+
-+ case led_amber_on:
-+ break;
-+
-+ case led_amber_off:
-+ break;
-+
-+ case led_red_on:
-+ if (led_state & LED_STATE_CLAIMED)
-+ hw_led_state &= ~IDP_BUSY_LED;
-+ break;
-+
-+ case led_red_off:
-+ if (led_state & LED_STATE_CLAIMED)
-+ hw_led_state |= IDP_BUSY_LED;
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ if (led_state & LED_STATE_ENABLED)
-+ IDP_WRITE_LEDS(hw_led_state);
-+
-+ local_irq_restore(flags);
-+}
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/leds-lubbock.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,134 @@
-+/*
-+ * linux/arch/arm/mach-pxa/leds-lubbock.c
-+ *
-+ * Copyright (C) 2000 John Dorsey <john+@cs.cmu.edu>
-+ *
-+ * Copyright (c) 2001 Jeff Sutherland <jeffs@accelent.com>
-+ *
-+ * Original (leds-footbridge.c) by Russell King
-+ *
-+ * See leds.h for bit definitions. The first version defines D28 on the
-+ * Lubbock dev board as the heartbeat, and D27 as the Sys_busy led.
-+ * There's plenty more if you're interested in adding them :)
-+ */
-+
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/leds.h>
-+#include <asm/system.h>
-+
-+#include "leds.h"
-+
-+
-+#define LED_STATE_ENABLED 1
-+#define LED_STATE_CLAIMED 2
-+
-+static unsigned int led_state;
-+static unsigned int hw_led_state;
-+
-+void lubbock_leds_event(led_event_t evt)
-+{
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+
-+ switch (evt) {
-+ case led_start:
-+ hw_led_state = HEARTBEAT_LED | SYS_BUSY_LED;
-+ led_state = LED_STATE_ENABLED;
-+ break;
-+
-+ case led_stop:
-+ led_state &= ~LED_STATE_ENABLED;
-+ break;
-+
-+ case led_claim:
-+ led_state |= LED_STATE_CLAIMED;
-+ hw_led_state = HEARTBEAT_LED | SYS_BUSY_LED;
-+ break;
-+
-+ case led_release:
-+ led_state &= ~LED_STATE_CLAIMED;
-+ hw_led_state = HEARTBEAT_LED | SYS_BUSY_LED;
-+ break;
-+
-+#ifdef CONFIG_LEDS_TIMER
-+ case led_timer:
-+ if (!(led_state & LED_STATE_CLAIMED))
-+ hw_led_state ^= HEARTBEAT_LED;
-+ break;
-+#endif
-+
-+#ifdef CONFIG_LEDS_CPU
-+ case led_idle_start:
-+ if (!(led_state & LED_STATE_CLAIMED))
-+ hw_led_state |= SYS_BUSY_LED;
-+ break;
-+
-+ case led_idle_end:
-+ if (!(led_state & LED_STATE_CLAIMED))
-+ hw_led_state &= ~SYS_BUSY_LED;
-+ break;
-+#endif
-+
-+ case led_halted:
-+ break;
-+
-+ case led_green_on:
-+ if (led_state & LED_STATE_CLAIMED)
-+ hw_led_state &= ~HEARTBEAT_LED;
-+ break;
-+
-+ case led_green_off:
-+ if (led_state & LED_STATE_CLAIMED)
-+ hw_led_state |= HEARTBEAT_LED;
-+ break;
-+
-+ case led_amber_on:
-+ break;
-+
-+ case led_amber_off:
-+ break;
-+
-+ case led_red_on:
-+ if (led_state & LED_STATE_CLAIMED)
-+ hw_led_state &= ~SYS_BUSY_LED;
-+ break;
-+
-+ case led_red_off:
-+ if (led_state & LED_STATE_CLAIMED)
-+ hw_led_state |= SYS_BUSY_LED;
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ if (led_state & LED_STATE_ENABLED)
-+ {
-+ switch (hw_led_state) {
-+ case 0: // all on
-+ HEARTBEAT_LED_ON;
-+ SYS_BUSY_LED_ON;
-+ break;
-+ case 1: // turn off heartbeat, status on:
-+ HEARTBEAT_LED_OFF;
-+ SYS_BUSY_LED_ON;
-+ break;
-+ case 2: // status off, heartbeat on:
-+ HEARTBEAT_LED_ON;
-+ SYS_BUSY_LED_OFF;
-+ break;
-+ case 3: // turn them both off...
-+ HEARTBEAT_LED_OFF;
-+ SYS_BUSY_LED_OFF;
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ local_irq_restore(flags);
-+}
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/leds.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,32 @@
-+/*
-+ * linux/arch/arm/mach-pxa/leds.c
-+ *
-+ * xscale LEDs dispatcher
-+ *
-+ * Copyright (C) 2001 Nicolas Pitre
-+ *
-+ * Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc.
-+ */
-+#include <linux/config.h>
-+#include <linux/init.h>
-+
-+#include <asm/leds.h>
-+#include <asm/mach-types.h>
-+
-+#include "leds.h"
-+
-+static int __init
-+pxa_leds_init(void)
-+{
-+ if (machine_is_lubbock())
-+ leds_event = lubbock_leds_event;
-+ if (machine_is_pxa_idp())
-+ leds_event = idp_leds_event;
-+ if (machine_is_pxa_cerf())
-+ leds_event = pxa_cerf_leds_event;
-+
-+ leds_event(led_start);
-+ return 0;
-+}
-+
-+__initcall(pxa_leds_init);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/leds.h 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,12 @@
-+/*
-+ * include/asm-arm/arch-pxa/leds.h
-+ *
-+ * Copyright (c) 2001 Jeff Sutherland, Accelent Systems Inc.
-+ *
-+ * blinky lights for various PXA-based systems:
-+ *
-+ */
-+
-+extern void lubbock_leds_event(led_event_t evt);
-+extern void idp_leds_event(led_event_t evt);
-+extern void pxa_cerf_leds_event(led_event_t evt);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/lubbock.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,157 @@
-+/*
-+ * linux/arch/arm/mach-pxa/lubbock.c
-+ *
-+ * Support for the Intel DBPXA250 Development Platform.
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Jun 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/init.h>
-+#include <linux/major.h>
-+#include <linux/fs.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+#include <linux/bitops.h>
-+
-+#include <asm/types.h>
-+#include <asm/setup.h>
-+#include <asm/memory.h>
-+#include <asm/mach-types.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+
-+#include <asm/mach/arch.h>
-+#include <asm/mach/map.h>
-+#include <asm/mach/irq.h>
-+
-+#include <asm/arch/irq.h>
-+#include <asm/hardware/sa1111.h>
-+
-+#include "generic.h"
-+
-+#ifdef CONFIG_SA1111
-+ #include "sa1111.h"
-+#endif
-+
-+
-+static unsigned long lubbock_irq_enabled;
-+
-+static void lubbock_mask_irq(unsigned int irq)
-+{
-+ int lubbock_irq = (irq - LUBBOCK_IRQ(0));
-+ LUB_IRQ_MASK_EN = (lubbock_irq_enabled &= ~(1 << lubbock_irq));
-+}
-+
-+static void lubbock_unmask_irq(unsigned int irq)
-+{
-+ int lubbock_irq = (irq - LUBBOCK_IRQ(0));
-+ /* the irq can be acknowledged only if deasserted, so it's done here */
-+ LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq);
-+ LUB_IRQ_MASK_EN = (lubbock_irq_enabled |= (1 << lubbock_irq));
-+}
-+
-+void lubbock_irq_demux(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
-+ do {
-+ GEDR(0) = GPIO_bit(0); /* clear useless edge notification */
-+ if (likely(pending))
-+ do_IRQ( LUBBOCK_IRQ(0) + __ffs(pending), regs );
-+ pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
-+ } while (pending);
-+}
-+
-+static struct irqaction lubbock_irq = {
-+ name: "Lubbock FPGA",
-+ handler: lubbock_irq_demux,
-+ flags: SA_INTERRUPT
-+};
-+
-+static void __init lubbock_init_irq(void)
-+{
-+ int irq;
-+
-+ pxa_init_irq();
-+
-+ /* setup extra lubbock irqs */
-+ for(irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) {
-+ irq_desc[irq].valid = 1;
-+ irq_desc[irq].probe_ok = 1;
-+ irq_desc[irq].mask_ack = lubbock_mask_irq;
-+ irq_desc[irq].mask = lubbock_mask_irq;
-+ irq_desc[irq].unmask = lubbock_unmask_irq;
-+ }
-+
-+ set_GPIO_IRQ_edge(GPIO_LUBBOCK_IRQ, GPIO_FALLING_EDGE);
-+ setup_arm_irq(IRQ_GPIO_LUBBOCK_IRQ, &lubbock_irq);
-+}
-+
-+static int __init lubbock_init(void)
-+{
-+ int ret;
-+
-+ ret = sa1111_probe(LUBBOCK_SA1111_BASE);
-+ if (ret)
-+ return ret;
-+ sa1111_wake();
-+ sa1111_init_irq(LUBBOCK_SA1111_IRQ);
-+ return 0;
-+}
-+
-+__initcall(lubbock_init);
-+
-+static void __init
-+fixup_lubbock(struct machine_desc *desc, struct param_struct *params,
-+ char **cmdline, struct meminfo *mi)
-+{
-+ /* Some boards have 32MB some 64MB. Let's use a safe default */
-+ SET_BANK (0, 0xa0000000, 32*1024*1024);
-+ mi->nr_banks = 1;
-+}
-+
-+static struct map_desc lubbock_io_desc[] __initdata = {
-+ /* virtual physical length domain r w c b */
-+ { 0xf0000000, 0x08000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */
-+ { 0xf1000000, 0x0c000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* LAN91C96 IO */
-+ { 0xf1100000, 0x0e000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* LAN91C96 Attr */
-+ { 0xf4000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA1111 */
-+ LAST_DESC
-+};
-+
-+static void __init lubbock_map_io(void)
-+{
-+ pxa_map_io();
-+ iotable_init(lubbock_io_desc);
-+
-+ /* This enables the BTUART */
-+ CKEN |= CKEN7_BTUART;
-+ set_GPIO_mode(GPIO42_BTRXD_MD);
-+ set_GPIO_mode(GPIO43_BTTXD_MD);
-+ set_GPIO_mode(GPIO44_BTCTS_MD);
-+ set_GPIO_mode(GPIO45_BTRTS_MD);
-+
-+ /* This is for the SMC chip select */
-+ set_GPIO_mode(GPIO79_nCS_3_MD);
-+
-+ /* setup sleep mode values */
-+ PWER = 0x00000002;
-+ PFER = 0x00000000;
-+ PRER = 0x00000002;
-+ PGSR0 = 0x00008000;
-+ PGSR1 = 0x003F0202;
-+ PGSR2 = 0x0001C000;
-+ PCFR |= PCFR_OPDE;
-+}
-+
-+MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform")
-+ MAINTAINER("MontaVista Software Inc.")
-+ BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-+ FIXUP(fixup_lubbock)
-+ MAPIO(lubbock_map_io)
-+ INITIRQ(lubbock_init_irq)
-+MACHINE_END
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/pm.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,265 @@
-+/*
-+ * PXA250/210 Power Management Routines
-+ *
-+ * Original code for the SA11x0:
-+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
-+ *
-+ * Modified for the PXA250 by Nicolas Pitre:
-+ * Copyright (c) 2002 Monta Vista Software, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/pm.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/sysctl.h>
-+#include <linux/errno.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/memory.h>
-+#include <asm/system.h>
-+#include <asm/leds.h>
-+
-+
-+/*
-+ * Debug macros
-+ */
-+#undef DEBUG
-+
-+extern void pxa_cpu_suspend(void);
-+extern void pxa_cpu_resume(void);
-+
-+#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
-+#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
-+
-+/*
-+ * List of global PXA peripheral registers to preserve.
-+ * More ones like CP and general purpose register values are preserved
-+ * with the stack pointer in sleep.S.
-+ */
-+enum { SLEEP_SAVE_START = 0,
-+
-+ SLEEP_SAVE_OSCR, SLEEP_SAVE_OIER,
-+ SLEEP_SAVE_OSMR0, SLEEP_SAVE_OSMR1, SLEEP_SAVE_OSMR2, SLEEP_SAVE_OSMR3,
-+
-+ SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2,
-+ SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2,
-+ SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2,
-+ SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR2_L,
-+ SLEEP_SAVE_GAFR0_U, SLEEP_SAVE_GAFR1_U, SLEEP_SAVE_GAFR2_U,
-+
-+ SLEEP_SAVE_FFIER, SLEEP_SAVE_FFLCR, SLEEP_SAVE_FFMCR,
-+ SLEEP_SAVE_FFSPR, SLEEP_SAVE_FFISR,
-+ SLEEP_SAVE_FFDLL, SLEEP_SAVE_FFDLH,
-+
-+ SLEEP_SAVE_ICMR,
-+ SLEEP_SAVE_CKEN,
-+
-+ SLEEP_SAVE_CKSUM,
-+
-+ SLEEP_SAVE_SIZE
-+};
-+
-+
-+int pm_do_suspend(void)
-+{
-+ unsigned long sleep_save[SLEEP_SAVE_SIZE];
-+ unsigned long checksum = 0;
-+ int i;
-+
-+ cli();
-+ clf();
-+
-+ leds_event(led_stop);
-+
-+ /* preserve current time */
-+ RCNR = xtime.tv_sec;
-+
-+ /*
-+ * Temporary solution. This won't be necessary once
-+ * we move pxa support into the serial/* driver
-+ * Save the FF UART
-+ */
-+ SAVE(FFIER);
-+ SAVE(FFLCR);
-+ SAVE(FFMCR);
-+ SAVE(FFSPR);
-+ SAVE(FFISR);
-+ FFLCR |= 0x80;
-+ SAVE(FFDLL);
-+ SAVE(FFDLH);
-+ FFLCR &= 0xef;
-+
-+ /* save vital registers */
-+ SAVE(OSCR);
-+ SAVE(OSMR0);
-+ SAVE(OSMR1);
-+ SAVE(OSMR2);
-+ SAVE(OSMR3);
-+ SAVE(OIER);
-+
-+ SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2);
-+ SAVE(GRER0); SAVE(GRER1); SAVE(GRER2);
-+ SAVE(GFER0); SAVE(GFER1); SAVE(GFER2);
-+ SAVE(GAFR0_L); SAVE(GAFR0_U);
-+ SAVE(GAFR1_L); SAVE(GAFR1_U);
-+ SAVE(GAFR2_L); SAVE(GAFR2_U);
-+
-+ SAVE(ICMR);
-+ ICMR = 0;
-+
-+ SAVE(CKEN);
-+ CKEN = 0;
-+
-+ /* Note: wake up source are set up in each machine specific files */
-+
-+ /* clear GPIO transition detect bits */
-+ GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2;
-+
-+ /* Clear sleep reset status */
-+ RCSR = RCSR_SMR;
-+
-+ /* set resume return address */
-+ PSPR = virt_to_phys(pxa_cpu_resume);
-+
-+ /* before sleeping, calculate and save a checksum */
-+ for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
-+ checksum += sleep_save[i];
-+ sleep_save[SLEEP_SAVE_CKSUM] = checksum;
-+
-+ /* *** go zzz *** */
-+ pxa_cpu_suspend();
-+
-+ /* after sleeping, validate the checksum */
-+ checksum = 0;
-+ for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
-+ checksum += sleep_save[i];
-+
-+ /* if invalid, display message and wait for a hardware reset */
-+ if (checksum != sleep_save[SLEEP_SAVE_CKSUM]) {
-+#ifdef CONFIG_ARCH_LUBBOCK
-+ LUB_HEXLED = 0xbadbadc5;
-+#endif
-+ while (1);
-+ }
-+
-+ /* ensure not to come back here if it wasn't intended */
-+ PSPR = 0;
-+
-+ /* restore registers */
-+ RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2);
-+ RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2);
-+ RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2);
-+ RESTORE(GAFR0_L); RESTORE(GAFR0_U);
-+ RESTORE(GAFR1_L); RESTORE(GAFR1_U);
-+ RESTORE(GAFR2_L); RESTORE(GAFR2_U);
-+
-+ PSSR = PSSR_PH;
-+
-+ RESTORE(OSMR0);
-+ RESTORE(OSMR1);
-+ RESTORE(OSMR2);
-+ RESTORE(OSMR3);
-+ RESTORE(OSCR);
-+ RESTORE(OIER);
-+
-+ RESTORE(CKEN);
-+
-+ ICLR = 0;
-+ ICCR = 1;
-+ RESTORE(ICMR);
-+
-+ /*
-+ * Temporary solution. This won't be necessary once
-+ * we move pxa support into the serial/* driver.
-+ * Restore the FF UART.
-+ */
-+ RESTORE(FFMCR);
-+ RESTORE(FFSPR);
-+ RESTORE(FFLCR);
-+ FFLCR |= 0x80;
-+ RESTORE(FFDLH);
-+ RESTORE(FFDLL);
-+ RESTORE(FFLCR);
-+ RESTORE(FFISR);
-+ FFFCR = 0x07;
-+ RESTORE(FFIER);
-+
-+ /* restore current time */
-+ xtime.tv_sec = RCNR;
-+
-+#ifdef DEBUG
-+ printk(KERN_DEBUG "*** made it back from resume\n");
-+#endif
-+
-+ leds_event(led_start);
-+
-+ sti();
-+
-+ return 0;
-+}
-+
-+unsigned long sleep_phys_sp(void *sp)
-+{
-+ return virt_to_phys(sp);
-+}
-+
-+#ifdef CONFIG_SYSCTL
-+/*
-+ * ARGH! ACPI people defined CTL_ACPI in linux/acpi.h rather than
-+ * linux/sysctl.h.
-+ *
-+ * This means our interface here won't survive long - it needs a new
-+ * interface. Quick hack to get this working - use sysctl id 9999.
-+ */
-+#warning ACPI broke the kernel, this interface needs to be fixed up.
-+#define CTL_ACPI 9999
-+#define ACPI_S1_SLP_TYP 19
-+
-+/*
-+ * Send us to sleep.
-+ */
-+static int sysctl_pm_do_suspend(void)
-+{
-+ int retval;
-+
-+ retval = pm_send_all(PM_SUSPEND, (void *)3);
-+
-+ if (retval == 0) {
-+ retval = pm_do_suspend();
-+
-+ pm_send_all(PM_RESUME, (void *)0);
-+ }
-+
-+ return retval;
-+}
-+
-+static struct ctl_table pm_table[] =
-+{
-+ {ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, (proc_handler *)&sysctl_pm_do_suspend},
-+ {0}
-+};
-+
-+static struct ctl_table pm_dir_table[] =
-+{
-+ {CTL_ACPI, "pm", NULL, 0, 0555, pm_table},
-+ {0}
-+};
-+
-+/*
-+ * Initialize power interface
-+ */
-+static int __init pm_init(void)
-+{
-+ register_sysctl_table(pm_dir_table, 1);
-+ return 0;
-+}
-+
-+__initcall(pm_init);
-+
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/pxa_usb.h 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,230 @@
-+/*
-+ * pxa_usb.h
-+ *
-+ * Public interface to the pxa USB core. For use by client modules
-+ * like usb-eth and usb-char.
-+ *
-+ * 02-May-2002
-+ * Frank Becker (Intrinsyc) - derived from sa1100_usb.h
-+ *
-+ */
-+
-+#ifndef _PXA_USB_H
-+#define _PXA_USB_H
-+#include <asm/byteorder.h>
-+
-+typedef void (*usb_callback_t)(int flag, int size);
-+
-+/* in usb_ctl.c (see also descriptor methods at bottom of file) */
-+
-+// Open the USB client for client and initialize data structures
-+// to default values, but _do not_ start UDC.
-+int pxa_usb_open( const char * client_name );
-+
-+// Start UDC running
-+int pxa_usb_start( void );
-+
-+// Immediately stop udc, fire off completion routines w/-EINTR
-+int pxa_usb_stop( void ) ;
-+
-+// Disconnect client from usb core
-+int pxa_usb_close( void ) ;
-+
-+// set notify callback for when core reaches configured state
-+// return previous pointer (if any)
-+typedef void (*usb_notify_t)(void);
-+usb_notify_t pxa_set_configured_callback( usb_notify_t callback );
-+
-+/* in usb_send.c */
-+int pxa_usb_xmitter_avail( void );
-+int pxa_usb_send(char *buf, int len, usb_callback_t callback);
-+void sa110a_usb_send_reset(void);
-+
-+/* in usb_recev.c */
-+int pxa_usb_recv(char *buf, int len, usb_callback_t callback);
-+void pxa_usb_recv_reset(void);
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Descriptor Management
-+//////////////////////////////////////////////////////////////////////////////
-+
-+#define DescriptorHeader \
-+ __u8 bLength; \
-+ __u8 bDescriptorType
-+
-+
-+// --- Device Descriptor -------------------
-+
-+typedef struct {
-+ DescriptorHeader;
-+ __u16 bcdUSB; /* USB specification revision number in BCD */
-+ __u8 bDeviceClass; /* USB class for entire device */
-+ __u8 bDeviceSubClass; /* USB subclass information for entire device */
-+ __u8 bDeviceProtocol; /* USB protocol information for entire device */
-+ __u8 bMaxPacketSize0; /* Max packet size for endpoint zero */
-+ __u16 idVendor; /* USB vendor ID */
-+ __u16 idProduct; /* USB product ID */
-+ __u16 bcdDevice; /* vendor assigned device release number */
-+ __u8 iManufacturer; /* index of manufacturer string */
-+ __u8 iProduct; /* index of string that describes product */
-+ __u8 iSerialNumber; /* index of string containing device serial number */
-+ __u8 bNumConfigurations; /* number fo configurations */
-+} __attribute__ ((packed)) device_desc_t;
-+
-+// --- Configuration Descriptor ------------
-+
-+typedef struct {
-+ DescriptorHeader;
-+ __u16 wTotalLength; /* total # of bytes returned in the cfg buf 4 this cfg */
-+ __u8 bNumInterfaces; /* number of interfaces in this cfg */
-+ __u8 bConfigurationValue; /* used to uniquely ID this cfg */
-+ __u8 iConfiguration; /* index of string describing configuration */
-+ __u8 bmAttributes; /* bitmap of attributes for ths cfg */
-+ __u8 MaxPower; /* power draw in 2ma units */
-+} __attribute__ ((packed)) config_desc_t;
-+
-+// bmAttributes:
-+enum {
-+ USB_CONFIG_REMOTEWAKE=0x20,
-+ USB_CONFIG_SELFPOWERED=0x40,
-+ USB_CONFIG_BUSPOWERED=0x80
-+};
-+
-+// MaxPower:
-+#define USB_POWER( x) ((x)>>1) /* convert mA to descriptor units of A for MaxPower */
-+
-+// --- Interface Descriptor ---------------
-+
-+typedef struct {
-+ DescriptorHeader;
-+ __u8 bInterfaceNumber; /* Index uniquely identfying this interface */
-+ __u8 bAlternateSetting; /* ids an alternate setting for this interface */
-+ __u8 bNumEndpoints; /* number of endpoints in this interface */
-+ __u8 bInterfaceClass; /* USB class info applying to this interface */
-+ __u8 bInterfaceSubClass; /* USB subclass info applying to this interface */
-+ __u8 bInterfaceProtocol; /* USB protocol info applying to this interface */
-+ __u8 iInterface; /* index of string describing interface */
-+} __attribute__ ((packed)) intf_desc_t;
-+
-+// --- Endpoint Descriptor ---------------
-+
-+typedef struct {
-+ DescriptorHeader;
-+ __u8 bEndpointAddress; /* 0..3 ep num, bit 7: 0 = 0ut 1= in */
-+ __u8 bmAttributes; /* 0..1 = 0: ctrl, 1: isoc, 2: bulk 3: intr */
-+ __u16 wMaxPacketSize; /* data payload size for this ep in this cfg */
-+ __u8 bInterval; /* polling interval for this ep in this cfg */
-+} __attribute__ ((packed)) ep_desc_t;
-+
-+// bEndpointAddress:
-+enum {
-+ USB_OUT =0,
-+ USB_IN =1
-+};
-+
-+#define USB_EP_ADDRESS(a,d) (((a)&0xf) | ((d) << 7))
-+// bmAttributes:
-+enum {
-+ USB_EP_CNTRL =0,
-+ USB_EP_BULK =2,
-+ USB_EP_INT =3,
-+ USB_EP_ISO =4
-+};
-+
-+// --- String Descriptor -------------------
-+
-+typedef struct {
-+ DescriptorHeader;
-+ __u16 bString[1]; /* unicode string .. actaully 'n' __u16s */
-+} __attribute__ ((packed)) string_desc_t;
-+
-+/*=======================================================
-+ * Handy helpers when working with above
-+ *
-+ */
-+// these are x86-style 16 bit "words" ...
-+#define make_word_c( w ) __constant_cpu_to_le16(w)
-+#define make_word( w ) __cpu_to_le16(w)
-+
-+// descriptor types
-+enum {
-+ USB_DESC_DEVICE = 1,
-+ USB_DESC_CONFIG = 2,
-+ USB_DESC_STRING = 3,
-+ USB_DESC_INTERFACE = 4,
-+ USB_DESC_ENDPOINT = 5
-+};
-+
-+
-+/*=======================================================
-+ * Default descriptor layout for SA-1100 and SA-1110 UDC
-+ */
-+
-+enum {
-+ UNUSED = 0,
-+
-+ BULK_IN1 = 1,
-+ BULK_OUT1 = 2,
-+ ISO_IN1 = 3,
-+ ISO_OUT1 = 4,
-+ INT_IN1 = 5,
-+
-+ BULK_IN2 = 6,
-+ BULK_OUT2 = 7,
-+ ISO_IN2 = 8,
-+ ISO_OUT2 = 9,
-+ INT_IN2 = 10,
-+
-+ BULK_IN3 = 11,
-+ BULK_OUT3 = 12,
-+ ISO_IN3 = 13,
-+ ISO_OUT3 = 14,
-+ INT_IN3 = 15
-+} /*endpoint_type*/;
-+
-+/* "config descriptor buffer" - that is, one config,
-+ ..one interface and 2 endpoints */
-+struct cdb {
-+ config_desc_t cfg;
-+ intf_desc_t intf;
-+ ep_desc_t ep1;
-+ ep_desc_t ep2;
-+} __attribute__ ((packed));
-+
-+/* all SA device descriptors */
-+typedef struct {
-+ device_desc_t dev; /* device descriptor */
-+ struct cdb b; /* bundle of descriptors for this cfg */
-+} __attribute__ ((packed)) desc_t;
-+
-+
-+/*=======================================================
-+ * Descriptor API
-+ */
-+
-+/* Get the address of the statically allocated desc_t structure
-+ in the usb core driver. Clients can modify this between
-+ the time they call pxa_usb_open() and pxa_usb_start()
-+*/
-+desc_t *
-+pxa_usb_get_descriptor_ptr( void );
-+
-+
-+/* Set a pointer to the string descriptor at "index". The driver
-+ ..has room for 8 string indicies internally. Index zero holds
-+ ..a LANGID code and is set to US English by default. Inidices
-+ ..1-7 are available for use in the config descriptors as client's
-+ ..see fit. This pointer is assumed to be good as long as the
-+ ..SA usb core is open (so statically allocate them). Returnes -EINVAL
-+ ..if index out of range */
-+int pxa_usb_set_string_descriptor( int index, string_desc_t * p );
-+
-+/* reverse of above */
-+string_desc_t *
-+pxa_usb_get_string_descriptor( int index );
-+
-+/* kmalloc() a string descriptor and convert "p" to unicode in it */
-+string_desc_t *
-+pxa_usb_kmalloc_string_descriptor( const char * p );
-+
-+#endif /* _PXA_USB_H */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/sa1111.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,3 @@
-+#include "../mach-sa1100/sa1111.c"
-+
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/sa1111.h 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,2 @@
-+#include "../mach-sa1100/sa1111.h"
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/sleep.S 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,150 @@
-+/*
-+ * Low-level PXA250/210 sleep/wakeUp support
-+ *
-+ * Initial SA1110 code:
-+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
-+ *
-+ * Adapted for PXA by Nicolas Pitre:
-+ * Copyright (c) 2002 Monta Vista Software, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/linkage.h>
-+#include <asm/assembler.h>
-+#include <asm/hardware.h>
-+
-+ .text
-+
-+/*
-+ * pxa_cpu_suspend()
-+ *
-+ * Forces CPU into sleep state
-+ */
-+
-+ENTRY(pxa_cpu_suspend)
-+
-+ mra r2, r3, acc0
-+ stmfd sp!, {r2 - r12, lr} @ save registers on stack
-+
-+ @ get coprocessor registers
-+ mrc p15, 0, r4, c15, c1, 0 @ CP access reg
-+ mrc p15, 0, r5, c13, c0, 0 @ PID
-+ mrc p15, 0, r6, c3, c0, 0 @ domain ID
-+ mrc p15, 0, r7, c2, c0, 0 @ translation table base addr
-+ mrc p15, 0, r8, c1, c1, 0 @ auxiliary control reg
-+ mrc p15, 0, r9, c1, c0, 0 @ control reg
-+
-+ @ store them plus current virtual stack ptr on stack
-+ mov r10, sp
-+ stmfd sp!, {r4 - r10}
-+
-+ @ preserve phys address of stack
-+ mov r0, sp
-+ bl sleep_phys_sp
-+ ldr r1, =sleep_save_sp
-+ str r0, [r1]
-+
-+ @ clean data cache
-+ bl cpu_xscale_cache_clean_invalidate_all
-+
-+ @ Put the processor to sleep
-+ @ (also workaround for sighting 28071)
-+
-+ @ prepare value for sleep mode
-+ mov r1, #3 @ sleep mode
-+
-+ @ prepare to put SDRAM into self-refresh manually
-+ ldr r4, =MDREFR
-+ ldr r5, [r4]
-+ orr r5, r5, #MDREFR_SLFRSH
-+
-+ @ prepare pointer to physical address 0 (virtual mapping in generic.c)
-+ mov r2, #UNCACHED_PHYS_0
-+
-+ @ align execution to a cache line
-+ b 1f
-+
-+ .ltorg
-+ .align 5
-+1:
-+
-+ @ All needed values are now in registers.
-+ @ These last instructions should be in cache
-+
-+ @ put SDRAM into self-refresh
-+ str r5, [r4]
-+
-+ @ force address lines low by reading at physical address 0
-+ ldr r3, [r2]
-+
-+ @ enter sleep mode
-+ mcr p14, 0, r1, c7, c0, 0
-+
-+20: nop
-+ b 20b @ loop waiting for sleep
-+
-+/*
-+ * cpu_pxa_resume()
-+ *
-+ * entry point from bootloader into kernel during resume
-+ *
-+ * Note: Yes, part of the following code is located into the .data section.
-+ * This is to allow sleep_save_sp to be accessed with a relative load
-+ * while we can't rely on any MMU translation. We could have put
-+ * sleep_save_sp in the .text section as well, but some setups might
-+ * insist on it to be truely read-only.
-+ */
-+
-+ .data
-+ .align 5
-+ENTRY(pxa_cpu_resume)
-+ mov r0, #I_BIT | F_BIT | MODE_SVC @ set SVC, irqs off
-+ msr cpsr_c, r0
-+
-+ ldr r0, sleep_save_sp @ stack phys addr
-+ ldr r2, =resume_after_mmu @ its absolute virtual address
-+ ldmfd r0, {r4 - r9, sp} @ CP regs + virt stack ptr
-+
-+ mov r1, #0
-+ mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
-+ mcr p15, 0, r1, c7, c7, 0 @ invalidate I & D caches, BTB
-+
-+#ifdef CONFIG_XSCALE_CACHE_ERRATA
-+ bic r9, r9, #0x0004 @ see cpu_xscale_proc_init
-+#endif
-+
-+ mcr p15, 0, r4, c15, c1, 0 @ CP access reg
-+ mcr p15, 0, r5, c13, c0, 0 @ PID
-+ mcr p15, 0, r6, c3, c0, 0 @ domain ID
-+ mcr p15, 0, r7, c2, c0, 0 @ translation table base addr
-+ mcr p15, 0, r8, c1, c1, 0 @ auxiliary control reg
-+ b resume_turn_on_mmu @ cache align execution
-+
-+ .align 5
-+resume_turn_on_mmu:
-+ mcr p15, 0, r9, c1, c0, 0 @ turn on MMU, caches, etc.
-+
-+ @ Let us ensure we jump to resume_after_mmu only when the mcr above
-+ @ actually took effect. They call it the "cpwait" operation.
-+ mrc p15, 0, r1, c2, c0, 0 @ queue a dependency on CP15
-+ sub pc, r2, r1, lsr #32 @ jump to virtual addr
-+ nop
-+ nop
-+ nop
-+
-+sleep_save_sp:
-+ .word 0 @ preserve stack phys ptr here
-+
-+ .text
-+resume_after_mmu:
-+#ifdef CONFIG_XSCALE_CACHE_ERRATA
-+ bl cpu_xscale_proc_init
-+#endif
-+ ldmfd sp!, {r2, r3}
-+ mar acc0, r2, r3
-+ ldmfd sp!, {r4 - r12, pc} @ return to caller
-+
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/trizeps2.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,105 @@
-+/*
-+ * linux/arch/arm/mach-pxa/trizeps2.c
-+ *
-+ * Support for the Keith&Koep MT6N Development Platform.
-+ *
-+ * Author: Luc De Cock
-+ * Created: Jan 13, 2003
-+ * Copyright: Teradyne DS, Ltd.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/init.h>
-+#include <linux/major.h>
-+#include <linux/fs.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+
-+#include <asm/types.h>
-+#include <asm/setup.h>
-+#include <asm/memory.h>
-+#include <asm/mach-types.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+
-+#include <asm/mach/arch.h>
-+#include <asm/mach/map.h>
-+#include <asm/mach/irq.h>
-+
-+#include <asm/arch/irq.h>
-+
-+#include "generic.h"
-+
-+static unsigned long trizeps2_irq_en_mask;
-+unsigned short trizeps2_bcr_shadow = 0x50; // 0x70
-+
-+
-+static void __init trizeps2_init_irq(void)
-+{
-+ int irq;
-+
-+ pxa_init_irq();
-+
-+ set_GPIO_IRQ_edge(GPIO_ETHERNET_IRQ, GPIO_RISING_EDGE);
-+}
-+
-+static int __init trizeps2_init(void)
-+{
-+ /* Configure the BCR register */
-+ unsigned short *bcr = (unsigned short *) TRIZEPS2_BCR_BASE;
-+
-+ *bcr = trizeps2_bcr_shadow;
-+ return 0;
-+}
-+
-+__initcall(trizeps2_init);
-+
-+static void __init
-+fixup_trizeps2(struct machine_desc *desc, struct param_struct *params,
-+ char **cmdline, struct meminfo *mi)
-+{
-+#ifdef TRIZEPS2_MEM_64MB
-+ SET_BANK (0, 0xa0000000, 64*1024*1024);
-+#else
-+ SET_BANK (0, 0xa0000000, 32*1024*1024);
-+#endif
-+ mi->nr_banks = 1;
-+}
-+
-+static struct map_desc trizeps2_io_desc[] __initdata = {
-+ /* virtual physical length domain r w c b */
-+ { 0xf0000000, 0x0e000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* BCR */
-+ { 0xf0100000, 0x0c000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCMCIA STATUS */
-+ { 0xf1000000, 0x0c800000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* LAN91C96 IO */
-+ { 0xf1100000, 0x0e000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* LAN91C96 Attr */
-+ { 0xf2000000, 0x0d800000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }, /* TTL-IO */
-+ LAST_DESC
-+};
-+
-+static void __init trizeps2_map_io(void)
-+{
-+ pxa_map_io();
-+ iotable_init(trizeps2_io_desc);
-+
-+ /* This is for the SMC chip select */
-+ set_GPIO_mode(GPIO79_nCS_3_MD);
-+
-+ /* setup sleep mode values */
-+ PWER = 0x00000002;
-+ PFER = 0x00000000;
-+ PRER = 0x00000002;
-+ PGSR0 = 0x00008000;
-+ PGSR1 = 0x003F0202;
-+ PGSR2 = 0x0001C000;
-+ PCFR |= PCFR_OPDE;
-+}
-+
-+MACHINE_START(TRIZEPS2, "Keith-n-Koep MT6N Development Platform")
-+ MAINTAINER("Luc De Cock")
-+ BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-+ FIXUP(fixup_trizeps2)
-+ MAPIO(trizeps2_map_io)
-+ INITIRQ(trizeps2_init_irq)
-+MACHINE_END
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/usb-char.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,719 @@
-+/*
-+ * (C) Copyright 2000-2001 Extenex Corporation
-+ *
-+ * 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.
-+ *
-+ * usb-char.c
-+ *
-+ * Miscellaneous character device interface for SA1100 USB function
-+ * driver.
-+ *
-+ * Background:
-+ * The SA1100 function driver ported from the Compaq Itsy project
-+ * has an interface, usb-eth.c, to feed network packets over the
-+ * usb wire and into the Linux TCP/IP stack.
-+ *
-+ * This file replaces that one with a simple character device
-+ * interface that allows unstructured "byte pipe" style reads and
-+ * writes over the USB bulk endpoints by userspace programs.
-+ *
-+ * A new define, CONFIG_SA1100_USB_NETLINK, has been created that,
-+ * when set, (the default) causes the ethernet interface to be used.
-+ * When not set, this more pedestrian character interface is linked
-+ * in instead.
-+ *
-+ * Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
-+ *
-+ * ward.willats@extenex.com
-+ *
-+ * To do:
-+ * - Can't dma into ring buffer directly with pci_map/unmap usb_recv
-+ * uses and get bytes out at the same time DMA is going on. Investigate:
-+ * a) changing usb_recv to use alloc_consistent() at client request; or
-+ * b) non-ring-buffer based data structures. In the meantime, I am using
-+ * a bounce buffer. Simple, but wasteful.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/config.h>
-+#include <linux/miscdevice.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/cache.h>
-+#include <linux/poll.h>
-+#include <linux/circ_buf.h>
-+#include <linux/timer.h>
-+
-+#include <asm/io.h>
-+#include <asm/semaphore.h>
-+#include <asm/proc/page.h>
-+#include <asm/mach-types.h>
-+
-+#include "usb-char.h"
-+#include "pxa_usb.h"
-+
-+
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Driver Options
-+//////////////////////////////////////////////////////////////////////////////
-+
-+#define VERSION "0.4"
-+
-+
-+#define VERBOSITY 1
-+
-+#if VERBOSITY
-+# define PRINTK(x, a...) printk (x, ## a)
-+#else
-+# define PRINTK(x, a...) /**/
-+#endif
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Globals - Macros - Enums - Structures
-+//////////////////////////////////////////////////////////////////////////////
-+#ifndef MIN
-+#define MIN( a, b ) ((a)<(b)?(a):(b))
-+#endif
-+
-+typedef int bool; enum { false = 0, true = 1 };
-+
-+static const char pszMe[] = "usbchr: ";
-+
-+static wait_queue_head_t wq_read;
-+static wait_queue_head_t wq_write;
-+static wait_queue_head_t wq_poll;
-+
-+/* Serialze multiple writers onto the transmit hardware
-+.. since we sleep the writer during transmit to stay in
-+.. sync. (Multiple writers don't make much sense, but..) */
-+static DECLARE_MUTEX( xmit_sem );
-+
-+// size of usb DATA0/1 packets. 64 is standard maximum
-+// for bulk transport, though most hosts seem to be able
-+// to handle larger.
-+#define TX_PACKET_SIZE 64
-+#define RX_PACKET_SIZE 64
-+#define RBUF_SIZE (4*PAGE_SIZE)
-+
-+static struct wcirc_buf {
-+ char *buf;
-+ int in;
-+ int out;
-+} rx_ring = { NULL, 0, 0 };
-+
-+static struct {
-+ unsigned long cnt_rx_complete;
-+ unsigned long cnt_rx_errors;
-+ unsigned long bytes_rx;
-+ unsigned long cnt_tx_timeouts;
-+ unsigned long cnt_tx_errors;
-+ unsigned long bytes_tx;
-+} charstats;
-+
-+
-+static char * tx_buf = NULL;
-+static char * packet_buffer = NULL;
-+static int sending = 0;
-+static int usb_ref_count = 0;
-+static int last_tx_result = 0;
-+static int last_rx_result = 0;
-+static int last_tx_size = 0;
-+static struct timer_list tx_timer;
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Prototypes
-+//////////////////////////////////////////////////////////////////////////////
-+static char * what_the_f( int e );
-+static void free_txrx_buffers( void );
-+static void twiddle_descriptors( void );
-+static void free_string_descriptors( void ) ;
-+static int usbc_open( struct inode *pInode, struct file *pFile );
-+static void rx_done_callback_packet_buffer( int flag, int size );
-+
-+static void tx_timeout( unsigned long );
-+static void tx_done_callback( int flag, int size );
-+
-+static ssize_t usbc_read( struct file *, char *, size_t, loff_t * );
-+static ssize_t usbc_write( struct file *, const char *, size_t, loff_t * );
-+static unsigned int usbc_poll( struct file *pFile, poll_table * pWait );
-+static int usbc_ioctl( struct inode *pInode, struct file *pFile,
-+ unsigned int nCmd, unsigned long argument );
-+static int usbc_close( struct inode *pInode, struct file *pFile );
-+
-+#ifdef CONFIG_SA1100_EXTENEX1
-+static void extenex_configured_notify_proc( void );
-+#endif
-+//////////////////////////////////////////////////////////////////////////////
-+// Private Helpers
-+//////////////////////////////////////////////////////////////////////////////
-+
-+static char * what_the_f( int e )
-+{
-+ char * p;
-+ switch( e ) {
-+ case 0:
-+ p = "noErr";
-+ break;
-+ case -ENODEV:
-+ p = "ENODEV - usb not in config state";
-+ break;
-+ case -EBUSY:
-+ p = "EBUSY - another request on the hardware";
-+ break;
-+ case -EAGAIN:
-+ p = "EAGAIN";
-+ break;
-+ case -EINTR:
-+ p = "EINTR - interrupted\n";
-+ break;
-+ case -EPIPE:
-+ p = "EPIPE - zero length xfer\n";
-+ break;
-+ default:
-+ p = "????";
-+ break;
-+ }
-+ return p;
-+}
-+
-+static void free_txrx_buffers( void )
-+{
-+ if ( rx_ring.buf != NULL ) {
-+ kfree( rx_ring.buf );
-+ rx_ring.buf = NULL;
-+ }
-+ if ( packet_buffer != NULL ) {
-+ kfree( packet_buffer );
-+ packet_buffer = NULL;
-+ }
-+ if ( tx_buf != NULL ) {
-+ kfree( tx_buf );
-+ tx_buf = NULL;
-+ }
-+}
-+
-+/* twiddle_descriptors()
-+ * It is between open() and start(). Setup descriptors.
-+ */
-+static void twiddle_descriptors( void )
-+{
-+ desc_t * pDesc = pxa_usb_get_descriptor_ptr();
-+ string_desc_t * pString;
-+
-+ pDesc->b.ep1.wMaxPacketSize = make_word_c( RX_PACKET_SIZE );
-+ pDesc->b.ep1.bmAttributes = USB_EP_BULK;
-+ pDesc->b.ep2.wMaxPacketSize = make_word_c( TX_PACKET_SIZE );
-+ pDesc->b.ep2.bmAttributes = USB_EP_BULK;
-+
-+ if ( machine_is_extenex1() ) {
-+#ifdef CONFIG_SA1100_EXTENEX1
-+ pDesc->dev.idVendor = make_word_c( 0xC9F );
-+ pDesc->dev.idProduct = 1;
-+ pDesc->dev.bcdDevice = make_word_c( 0x0001 );
-+ pDesc->b.cfg.bmAttributes = USB_CONFIG_SELFPOWERED;
-+ pDesc->b.cfg.MaxPower = 0;
-+
-+ pString = pxa_usb_kmalloc_string_descriptor( "Extenex" );
-+ if ( pString ) {
-+ pxa_usb_set_string_descriptor( 1, pString );
-+ pDesc->dev.iManufacturer = 1;
-+ }
-+
-+ pString = pxa_usb_kmalloc_string_descriptor( "Handheld Theater" );
-+ if ( pString ) {
-+ pxa_usb_set_string_descriptor( 2, pString );
-+ pDesc->dev.iProduct = 2;
-+ }
-+
-+ pString = pxa_usb_kmalloc_string_descriptor( "00000000" );
-+ if ( pString ) {
-+ pxa_usb_set_string_descriptor( 3, pString );
-+ pDesc->dev.iSerialNumber = 3;
-+ }
-+
-+ pString = pxa_usb_kmalloc_string_descriptor( "HHT Bulk Transfer" );
-+ if ( pString ) {
-+ pxa_usb_set_string_descriptor( 4, pString );
-+ pDesc->b.intf.iInterface = 4;
-+ }
-+ pxa_set_configured_callback( extenex_configured_notify_proc );
-+#endif
-+ }
-+}
-+
-+static void free_string_descriptors( void )
-+{
-+ if ( machine_is_extenex1() ) {
-+ string_desc_t * pString;
-+ int i;
-+ for( i = 1 ; i <= 4 ; i++ ) {
-+ pString = pxa_usb_get_string_descriptor( i );
-+ if ( pString )
-+ kfree( pString );
-+ }
-+ }
-+}
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// ASYNCHRONOUS
-+//////////////////////////////////////////////////////////////////////////////
-+static void kick_start_rx( void )
-+{
-+ if ( usb_ref_count ) {
-+ int total_space = CIRC_SPACE( rx_ring.in, rx_ring.out, RBUF_SIZE );
-+ if ( total_space >= RX_PACKET_SIZE ) {
-+ pxa_usb_recv( packet_buffer,
-+ RX_PACKET_SIZE,
-+ rx_done_callback_packet_buffer
-+ );
-+ }
-+ }
-+}
-+/*
-+ * rx_done_callback_packet_buffer()
-+ * We have completed a DMA xfer into the temp packet buffer.
-+ * Move to ring.
-+ *
-+ * flag values:
-+ * on init, -EAGAIN
-+ * on reset, -EINTR
-+ * on RPE, -EIO
-+ * on short packet -EPIPE
-+ */
-+static void
-+rx_done_callback_packet_buffer( int flag, int size )
-+{
-+ charstats.cnt_rx_complete++;
-+
-+ if ( flag == 0 || flag == -EPIPE ) {
-+ size_t n;
-+
-+ charstats.bytes_rx += size;
-+
-+ n = CIRC_SPACE_TO_END( rx_ring.in, rx_ring.out, RBUF_SIZE );
-+ n = MIN( n, size );
-+ size -= n;
-+
-+ memcpy( &rx_ring.buf[ rx_ring.in ], packet_buffer, n );
-+ rx_ring.in = (rx_ring.in + n) & (RBUF_SIZE-1);
-+ memcpy( &rx_ring.buf[ rx_ring.in ], packet_buffer + n, size );
-+ rx_ring.in = (rx_ring.in + size) & (RBUF_SIZE-1);
-+
-+ wake_up_interruptible( &wq_read );
-+ wake_up_interruptible( &wq_poll );
-+
-+ last_rx_result = 0;
-+
-+ kick_start_rx();
-+
-+ } else if ( flag != -EAGAIN ) {
-+ charstats.cnt_rx_errors++;
-+ last_rx_result = flag;
-+ wake_up_interruptible( &wq_read );
-+ wake_up_interruptible( &wq_poll );
-+ }
-+ else /* init, start a read */
-+ kick_start_rx();
-+}
-+
-+
-+static void tx_timeout( unsigned long unused )
-+{
-+ printk( "%stx timeout\n", pszMe );
-+ pxa_usb_send_reset();
-+ charstats.cnt_tx_timeouts++;
-+}
-+
-+
-+// on init, -EAGAIN
-+// on reset, -EINTR
-+// on TPE, -EIO
-+static void tx_done_callback( int flags, int size )
-+{
-+ if ( flags == 0 )
-+ charstats.bytes_tx += size;
-+ else
-+ charstats.cnt_tx_errors++;
-+ last_tx_size = size;
-+ last_tx_result = flags;
-+ sending = 0;
-+ wake_up_interruptible( &wq_write );
-+ wake_up_interruptible( &wq_poll );
-+}
-+
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Workers
-+//////////////////////////////////////////////////////////////////////////////
-+
-+static int usbc_open( struct inode *pInode, struct file *pFile )
-+{
-+ int retval = 0;
-+
-+ PRINTK( KERN_DEBUG "%sopen()\n", pszMe );
-+
-+ /* start usb core */
-+ retval = pxa_usb_open( "usb-char" );
-+ if ( retval ) return retval;
-+
-+ /* allocate memory */
-+ if ( usb_ref_count == 0 ) {
-+ tx_buf = (char*) kmalloc( TX_PACKET_SIZE, GFP_KERNEL | GFP_DMA );
-+ if ( tx_buf == NULL ) {
-+ printk( "%sARGHH! COULD NOT ALLOCATE TX BUFFER\n", pszMe );
-+ goto malloc_fail;
-+ }
-+ rx_ring.buf =
-+ (char*) kmalloc( RBUF_SIZE, GFP_KERNEL );
-+
-+ if ( rx_ring.buf == NULL ) {
-+ printk( "%sARGHH! COULD NOT ALLOCATE RX BUFFER\n", pszMe );
-+ goto malloc_fail;
-+ }
-+
-+ packet_buffer =
-+ (char*) kmalloc( RX_PACKET_SIZE, GFP_KERNEL | GFP_DMA );
-+
-+ if ( packet_buffer == NULL ) {
-+ printk( "%sARGHH! COULD NOT ALLOCATE RX PACKET BUFFER\n", pszMe );
-+ goto malloc_fail;
-+ }
-+ rx_ring.in = rx_ring.out = 0;
-+ memset( &charstats, 0, sizeof( charstats ) );
-+ sending = 0;
-+ last_tx_result = 0;
-+ last_tx_size = 0;
-+ }
-+
-+ /* modify default descriptors */
-+ twiddle_descriptors();
-+
-+ retval = pxa_usb_start();
-+ if ( retval ) {
-+ printk( "%sAGHH! Could not USB core\n", pszMe );
-+ free_txrx_buffers();
-+ return retval;
-+ }
-+ usb_ref_count++; /* must do _before_ kick_start() */
-+ MOD_INC_USE_COUNT;
-+ kick_start_rx();
-+ return 0;
-+
-+ malloc_fail:
-+ free_txrx_buffers();
-+ return -ENOMEM;
-+}
-+
-+/*
-+ * Read endpoint. Note that you can issue a read to an
-+ * unconfigured endpoint. Eventually, the host may come along
-+ * and configure underneath this module and data will appear.
-+ */
-+static ssize_t usbc_read( struct file *pFile, char *pUserBuffer,
-+ size_t stCount, loff_t *pPos )
-+{
-+ ssize_t retval;
-+ int flags;
-+ DECLARE_WAITQUEUE( wait, current );
-+
-+ PRINTK( KERN_DEBUG "%sread()\n", pszMe );
-+
-+ local_irq_save( flags );
-+ if ( last_rx_result == 0 ) {
-+ local_irq_restore( flags );
-+ } else { /* an error happended and receiver is paused */
-+ local_irq_restore( flags );
-+ last_rx_result = 0;
-+ kick_start_rx();
-+ }
-+
-+ add_wait_queue( &wq_read, &wait );
-+ while( 1 ) {
-+ ssize_t bytes_avail;
-+ ssize_t bytes_to_end;
-+
-+ set_current_state( TASK_INTERRUPTIBLE );
-+
-+ /* snap ring buf state */
-+ local_irq_save( flags );
-+ bytes_avail = CIRC_CNT( rx_ring.in, rx_ring.out, RBUF_SIZE );
-+ bytes_to_end = CIRC_CNT_TO_END( rx_ring.in, rx_ring.out, RBUF_SIZE );
-+ local_irq_restore( flags );
-+
-+ if ( bytes_avail != 0 ) {
-+ ssize_t bytes_to_move = MIN( stCount, bytes_avail );
-+ retval = 0; // will be bytes transfered
-+ if ( bytes_to_move != 0 ) {
-+ size_t n = MIN( bytes_to_end, bytes_to_move );
-+ if ( copy_to_user( pUserBuffer,
-+ &rx_ring.buf[ rx_ring.out ],
-+ n ) ) {
-+ retval = -EFAULT;
-+ break;
-+ }
-+ bytes_to_move -= n;
-+ retval += n;
-+ // might go 1 char off end, so wrap
-+ rx_ring.out = ( rx_ring.out + n ) & (RBUF_SIZE-1);
-+ if ( copy_to_user( pUserBuffer + n,
-+ &rx_ring.buf[ rx_ring.out ],
-+ bytes_to_move )
-+ ) {
-+ retval = -EFAULT;
-+ break;
-+ }
-+ rx_ring.out += bytes_to_move; // cannot wrap
-+ retval += bytes_to_move;
-+ kick_start_rx();
-+ }
-+ break;
-+ }
-+ else if ( last_rx_result ) {
-+ retval = last_rx_result;
-+ break;
-+ }
-+ else if ( pFile->f_flags & O_NONBLOCK ) { // no data, can't sleep
-+ retval = -EAGAIN;
-+ break;
-+ }
-+ else if ( signal_pending( current ) ) { // no data, can sleep, but signal
-+ retval = -ERESTARTSYS;
-+ break;
-+ }
-+ schedule(); // no data, can sleep
-+ }
-+ set_current_state( TASK_RUNNING );
-+ remove_wait_queue( &wq_read, &wait );
-+
-+ if ( retval < 0 )
-+ printk( "%sread error %d - %s\n", pszMe, retval, what_the_f( retval ) );
-+ return retval;
-+}
-+
-+/*
-+ * Write endpoint. This routine attempts to break the passed in buffer
-+ * into usb DATA0/1 packet size chunks and send them to the host.
-+ * (The lower-level driver tries to do this too, but easier for us
-+ * to manage things here.)
-+ *
-+ * We are at the mercy of the host here, in that it must send an IN
-+ * token to us to pull this data back, so hopefully some higher level
-+ * protocol is expecting traffic to flow in that direction so the host
-+ * is actually polling us. To guard against hangs, a 5 second timeout
-+ * is used.
-+ *
-+ * This routine takes some care to only report bytes sent that have
-+ * actually made it across the wire. Thus we try to stay in lockstep
-+ * with the completion routine and only have one packet on the xmit
-+ * hardware at a time. Multiple simultaneous writers will get
-+ * "undefined" results.
-+ *
-+ */
-+static ssize_t usbc_write( struct file *pFile, const char * pUserBuffer,
-+ size_t stCount, loff_t *pPos )
-+{
-+ ssize_t retval = 0;
-+ ssize_t stSent = 0;
-+
-+ DECLARE_WAITQUEUE( wait, current );
-+
-+ PRINTK( KERN_DEBUG "%swrite() %d bytes\n", pszMe, stCount );
-+
-+ down( &xmit_sem ); // only one thread onto the hardware at a time
-+
-+ while( stCount != 0 && retval == 0 ) {
-+ int nThisTime = MIN( TX_PACKET_SIZE, stCount );
-+ copy_from_user( tx_buf, pUserBuffer, nThisTime );
-+ sending = nThisTime;
-+ retval = pxa_usb_send( tx_buf, nThisTime, tx_done_callback );
-+ if ( retval < 0 ) {
-+ char * p = what_the_f( retval );
-+ printk( "%sCould not queue xmission. rc=%d - %s\n",
-+ pszMe, retval, p );
-+ sending = 0;
-+ break;
-+ }
-+ /* now have something on the diving board */
-+ add_wait_queue( &wq_write, &wait );
-+ tx_timer.expires = jiffies + ( HZ * 5 );
-+ add_timer( &tx_timer );
-+ while( 1 ) {
-+ set_current_state( TASK_INTERRUPTIBLE );
-+ if ( sending == 0 ) { /* it jumped into the pool */
-+ del_timer( &tx_timer );
-+ retval = last_tx_result;
-+ if ( retval == 0 ) {
-+ stSent += last_tx_size;
-+ pUserBuffer += last_tx_size;
-+ stCount -= last_tx_size;
-+ }
-+ else
-+ printk( "%sxmission error rc=%d - %s\n",
-+ pszMe, retval, what_the_f(retval) );
-+ break;
-+ }
-+ else if ( signal_pending( current ) ) {
-+ del_timer( &tx_timer );
-+ printk( "%ssignal\n", pszMe );
-+ retval = -ERESTARTSYS;
-+ break;
-+ }
-+ schedule();
-+ }
-+ set_current_state( TASK_RUNNING );
-+ remove_wait_queue( &wq_write, &wait );
-+ }
-+
-+ up( &xmit_sem );
-+
-+ if ( 0 == retval )
-+ retval = stSent;
-+ return retval;
-+}
-+
-+static unsigned int usbc_poll( struct file *pFile, poll_table * pWait )
-+{
-+ unsigned int retval = 0;
-+
-+ PRINTK( KERN_DEBUG "%poll()\n", pszMe );
-+
-+ poll_wait( pFile, &wq_poll, pWait );
-+
-+ if ( CIRC_CNT( rx_ring.in, rx_ring.out, RBUF_SIZE ) )
-+ retval |= POLLIN | POLLRDNORM;
-+ if ( pxa_usb_xmitter_avail() )
-+ retval |= POLLOUT | POLLWRNORM;
-+ return retval;
-+}
-+
-+static int usbc_ioctl( struct inode *pInode, struct file *pFile,
-+ unsigned int nCmd, unsigned long argument )
-+{
-+ int retval = 0;
-+
-+ switch( nCmd ) {
-+
-+ case USBC_IOC_FLUSH_RECEIVER:
-+ pxa_usb_recv_reset();
-+ rx_ring.in = rx_ring.out = 0;
-+ break;
-+
-+ case USBC_IOC_FLUSH_TRANSMITTER:
-+ pxa_usb_send_reset();
-+ break;
-+
-+ case USBC_IOC_FLUSH_ALL:
-+ pxa_usb_recv_reset();
-+ rx_ring.in = rx_ring.out = 0;
-+ pxa_usb_send_reset();
-+ break;
-+
-+ default:
-+ retval = -ENOIOCTLCMD;
-+ break;
-+
-+ }
-+ return retval;
-+}
-+
-+
-+static int usbc_close( struct inode *pInode, struct file * pFile )
-+{
-+ PRINTK( KERN_DEBUG "%sclose()\n", pszMe );
-+ if ( --usb_ref_count == 0 ) {
-+ down( &xmit_sem );
-+ pxa_usb_stop();
-+ free_txrx_buffers();
-+ free_string_descriptors();
-+ del_timer( &tx_timer );
-+ pxa_usb_close();
-+ up( &xmit_sem );
-+ }
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+#ifdef CONFIG_SA1100_EXTENEX1
-+#include "../../../drivers/char/ex_gpio.h"
-+void extenex_configured_notify_proc( void )
-+{
-+ if ( exgpio_play_string( "440,1:698,1" ) == -EAGAIN )
-+ printk( "%sWanted to BEEP but ex_gpio not open\n", pszMe );
-+}
-+#endif
-+//////////////////////////////////////////////////////////////////////////////
-+// Initialization
-+//////////////////////////////////////////////////////////////////////////////
-+
-+static struct file_operations usbc_fops = {
-+ owner: THIS_MODULE,
-+ open: usbc_open,
-+ read: usbc_read,
-+ write: usbc_write,
-+ poll: usbc_poll,
-+ ioctl: usbc_ioctl,
-+ release: usbc_close,
-+};
-+
-+static struct miscdevice usbc_misc_device = {
-+ USBC_MINOR, "usb_char", &usbc_fops
-+};
-+
-+/*
-+ * usbc_init()
-+ */
-+
-+int __init usbc_init( void )
-+{
-+ int rc;
-+
-+ if ( (rc = misc_register( &usbc_misc_device )) != 0 ) {
-+ printk( KERN_WARNING "%sCould not register device 10, "
-+ "%d. (%d)\n", pszMe, USBC_MINOR, rc );
-+ return -EBUSY;
-+ }
-+
-+ // initialize wait queues
-+ init_waitqueue_head( &wq_read );
-+ init_waitqueue_head( &wq_write );
-+ init_waitqueue_head( &wq_poll );
-+
-+ // initialize tx timeout timer
-+ init_timer( &tx_timer );
-+ tx_timer.function = tx_timeout;
-+
-+ printk( KERN_INFO "USB Function Character Driver Interface"
-+ " - %s, (C) 2001, Extenex Corp.\n", VERSION
-+ );
-+
-+ return rc;
-+}
-+
-+void __exit usbc_exit( void )
-+{
-+}
-+
-+EXPORT_NO_SYMBOLS;
-+
-+module_init(usbc_init);
-+module_exit(usbc_exit);
-+
-+
-+
-+// end: usb-char.c
-+
-+
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/usb-char.h 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,34 @@
-+/*
-+ * Copyright (C) 2001 Extenex Corporation
-+ *
-+ * usb-char.h
-+ *
-+ * Character device emulation client for SA-1100 client usb core.
-+ *
-+ *
-+ *
-+ */
-+#ifndef _USB_CHAR_H
-+#define _USB_CHAR_H
-+
-+#define USBC_MAJOR 10 /* miscellaneous character device */
-+#define USBC_MINOR 240 /* in the "reserved for local use" range */
-+
-+#define USBC_MAGIC 0x8E
-+
-+/* zap everything in receive ring buffer */
-+#define USBC_IOC_FLUSH_RECEIVER _IO( USBC_MAGIC, 0x01 )
-+
-+/* reset transmitter */
-+#define USBC_IOC_FLUSH_TRANSMITTER _IO( USBC_MAGIC, 0x02 )
-+
-+/* do both of above */
-+#define USBC_IOC_FLUSH_ALL _IO( USBC_MAGIC, 0x03 )
-+
-+
-+
-+
-+
-+
-+#endif /* _USB_CHAR_H */
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/usb-eth.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,479 @@
-+/*
-+ * Ethernet driver for the PXA USB client function
-+ * Copyright (c) 2001 by Nicolas Pitre
-+ *
-+ * This code was loosely inspired by the original initial ethernet test driver
-+ * Copyright (c) Compaq Computer Corporation, 1999
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This is still work in progress...
-+ *
-+ * 19/02/2001 - Now we are compatible with generic usbnet driver. green@iXcelerator.com
-+ * 09/03/2001 - Dropped 'framing' scheme, as it seems to cause a lot of problems with little benefit.
-+ * Now, since we do not know what size of packet we are receiving
-+ * last usb packet in sequence will always be less than max packet
-+ * receive endpoint can accept.
-+ * Now the only way to check correct start of frame is to compare
-+ * MAC address. Also now we are stalling on each receive error.
-+ *
-+ * 15/03/2001 - Using buffer to get data from UDC. DMA needs to have 8 byte
-+ * aligned buffer, but this breaks IP code (unaligned access).
-+ *
-+ * 01/04/2001 - stall endpoint operations appeared to be very unstable, so
-+ * they are disabled now.
-+ *
-+ * 03/06/2001 - Readded "zerocopy" receive path (tunable).
-+ *
-+ */
-+
-+// Define DMA_NO_COPY if you want data to arrive directly into the
-+// receive network buffers, instead of arriving into bounce buffer
-+// and then get copied to network buffer.
-+// This does not work correctly right now.
-+#undef DMA_NO_COPY
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/timer.h>
-+
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/random.h>
-+
-+#include "pxa_usb.h"
-+
-+
-+#define ETHERNET_VENDOR_ID 0x49f
-+#define ETHERNET_PRODUCT_ID 0x505A
-+#define MAX_PACKET 32768
-+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-+
-+// Should be global, so that insmod can change these
-+int usb_rsize=64;
-+int usb_wsize=64;
-+
-+static struct usbe_info_t {
-+ struct net_device *dev;
-+ u16 packet_id;
-+ struct net_device_stats stats;
-+} usbe_info;
-+
-+static char usb_eth_name[16] = "usbf";
-+static struct net_device usb_eth_device;
-+static struct sk_buff *cur_tx_skb, *next_tx_skb;
-+static struct sk_buff *cur_rx_skb, *next_rx_skb;
-+static volatile int terminating;
-+#ifndef DMA_NO_COPY
-+static char *dmabuf; // we need that, as dma expect it's buffers to be aligned on 8 bytes boundary
-+#endif
-+
-+static int usb_change_mtu (struct net_device *net, int new_mtu)
-+{
-+ if (new_mtu <= sizeof (struct ethhdr) || new_mtu > MAX_PACKET)
-+ return -EINVAL;
-+ // no second zero-length packet read wanted after mtu-sized packets
-+ if (((new_mtu + sizeof (struct ethhdr)) % usb_rsize) == 0)
-+ return -EDOM;
-+
-+ net->mtu = new_mtu;
-+ return 0;
-+}
-+
-+static struct sk_buff *
-+usb_new_recv_skb(void)
-+{
-+ struct sk_buff *skb = alloc_skb( 2 + sizeof (struct ethhdr) + usb_eth_device.mtu,GFP_ATOMIC);
-+
-+ if (skb) {
-+ skb_reserve(skb, 2);
-+ }
-+ return skb;
-+}
-+
-+static u8 bcast_hwaddr[ETH_ALEN]={0xff,0xff,0xff,0xff,0xff,0xff};
-+static void
-+usb_recv_callback(int flag, int size)
-+{
-+ struct sk_buff *skb;
-+
-+ if (terminating)
-+ return;
-+
-+ skb = cur_rx_skb;
-+
-+ /* flag validation */
-+ if (flag == 0) {
-+ if ( skb_tailroom (skb) < size ) { // hey! we are overloaded!!!
-+ usbe_info.stats.rx_over_errors++;
-+ goto error;
-+ }
-+#ifndef DMA_NO_COPY
-+ memcpy(skb->tail,dmabuf,size);
-+#endif
-+ skb_put(skb, size);
-+ } else {
-+ if (flag == -EIO) {
-+ usbe_info.stats.rx_errors++;
-+ }
-+ goto error;
-+ }
-+
-+
-+ /*
-+ * If the real size of the packet is divisible by usb_rsize
-+ * an extra byte will be added. Thus size == usb_rsize
-+ * should only happen if more data is to come.
-+ */
-+ /* validate packet length */
-+ if (size == usb_rsize ) {
-+ /* packet not complete yet */
-+ skb = NULL;
-+ }
-+
-+ /*
-+ * At this point skb is non null if we have a complete packet.
-+ * If so take a fresh skb right away and restart USB receive without
-+ * further delays, then process the packet. Otherwise resume USB
-+ * receive on the current skb and exit.
-+ */
-+
-+ if (skb)
-+ cur_rx_skb = next_rx_skb;
-+#ifndef DMA_NO_COPY
-+ pxa_usb_recv(dmabuf, usb_rsize,
-+ usb_recv_callback);
-+#else
-+ pxa_usb_recv(cur_rx_skb->tail, MIN(usb_rsize, skb_tailroom (cur_rx_skb)),
-+ usb_recv_callback);
-+#endif
-+ if (!skb)
-+ return;
-+
-+ next_rx_skb = usb_new_recv_skb();
-+ if (!next_rx_skb) {
-+ /*
-+ * We can't aford loosing buffer space...
-+ * So we drop the current packet and recycle its skb.
-+ */
-+ printk("%s: can't allocate new skb\n", __FUNCTION__);
-+ usbe_info.stats.rx_dropped++;
-+ skb_trim(skb, 0);
-+ next_rx_skb = skb;
-+ return;
-+ }
-+ if ( skb->len >= sizeof(struct ethhdr)) {
-+ if (memcmp(skb->data,usb_eth_device.dev_addr,ETH_ALEN) && memcmp(skb->data,bcast_hwaddr,ETH_ALEN) ) {
-+ // This frame is not for us. nor it is broadcast
-+ usbe_info.stats.rx_frame_errors++;
-+ kfree_skb(skb);
-+ goto error;
-+ }
-+
-+#if 0
-+{
-+ int i;
-+
-+ for (i = 0; i < skb->len; i++)
-+ {
-+ printk("%02X ", skb->data[i]);
-+ if( (i%8)==7) printk("\n");
-+ }
-+ printk("...\n");
-+}
-+#endif
-+
-+ }
-+
-+ if (skb->len) {
-+ int status;
-+// FIXME: eth_copy_and_csum "small" packets to new SKB (small < ~200 bytes) ?
-+
-+ skb->dev = &usb_eth_device;
-+ skb->protocol = eth_type_trans (skb, &usb_eth_device);
-+ usbe_info.stats.rx_packets++;
-+ usbe_info.stats.rx_bytes += skb->len;
-+ skb->ip_summed = CHECKSUM_NONE;
-+ status = netif_rx (skb);
-+ if (status != NET_RX_SUCCESS)
-+ printk("netif_rx failed with code %d\n",status);
-+ } else {
-+error:
-+//printk("ERROR... tailroom=%d size=%d len=%d flag=%d\n", skb_tailroom(skb), size, skb->len, flag);
-+ /*
-+ * Error due to HW addr mismatch, or IO error.
-+ * Recycle the current skb and reset USB reception.
-+ */
-+ skb_trim(cur_rx_skb, 0);
-+// if ( flag == -EINTR || flag == -EAGAIN ) // only if we are coming out of stall
-+#ifndef DMA_NO_COPY
-+ pxa_usb_recv(dmabuf, usb_rsize, usb_recv_callback);
-+#else
-+ pxa_usb_recv(cur_rx_skb->tail, MIN(usb_rsize, skb_tailroom (cur_rx_skb)), usb_recv_callback);
-+#endif
-+ }
-+}
-+
-+
-+static void
-+usb_send_callback(int flag, int size)
-+{
-+ struct net_device *dev = usbe_info.dev;
-+ struct net_device_stats *stats;
-+ struct sk_buff *skb=cur_tx_skb;
-+ int ret;
-+
-+ if (terminating)
-+ return;
-+
-+ stats = &usbe_info.stats;
-+ switch (flag) {
-+ case 0:
-+ stats->tx_packets++;
-+ stats->tx_bytes += size;
-+ break;
-+ case -EIO:
-+ stats->tx_errors++;
-+ break;
-+ default:
-+ stats->tx_dropped++;
-+ break;
-+ }
-+
-+ cur_tx_skb = next_tx_skb;
-+ next_tx_skb = NULL;
-+ dev_kfree_skb_irq(skb);
-+ if (!cur_tx_skb)
-+ return;
-+
-+ dev->trans_start = jiffies;
-+ ret = pxa_usb_send(cur_tx_skb->data, cur_tx_skb->len, usb_send_callback);
-+ if (ret) {
-+ /* If the USB core can't accept the packet, we drop it. */
-+ dev_kfree_skb_irq(cur_tx_skb);
-+ cur_tx_skb = NULL;
-+ usbe_info.stats.tx_carrier_errors++;
-+ }
-+ netif_wake_queue(dev);
-+}
-+
-+static int
-+usb_eth_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+ int ret;
-+ long flags;
-+
-+ if (next_tx_skb) {
-+ printk("%s: called with next_tx_skb != NULL\n", __FUNCTION__);
-+ return 1;
-+ }
-+
-+ if (skb_shared (skb)) {
-+ struct sk_buff *skb2 = skb_unshare(skb, GFP_ATOMIC);
-+ if (!skb2) {
-+ usbe_info.stats.tx_dropped++;
-+ dev_kfree_skb(skb);
-+ return 1;
-+ }
-+ skb = skb2;
-+ }
-+
-+ if ((skb->len % usb_wsize) == 0) {
-+ skb->len++; // other side will ignore this one, anyway.
-+ }
-+
-+ save_flags_cli(flags);
-+ if (cur_tx_skb) {
-+ next_tx_skb = skb;
-+ netif_stop_queue(dev);
-+ } else {
-+ cur_tx_skb = skb;
-+ dev->trans_start = jiffies;
-+ ret = pxa_usb_send(skb->data, skb->len, usb_send_callback);
-+ if (ret) {
-+ /* If the USB core can't accept the packet, we drop it. */
-+ dev_kfree_skb(skb);
-+ cur_tx_skb = NULL;
-+ usbe_info.stats.tx_carrier_errors++;
-+ }
-+ }
-+ restore_flags(flags);
-+ return 0;
-+}
-+
-+static void
-+usb_xmit_timeout(struct net_device *dev )
-+{
-+ pxa_usb_send_reset();
-+ dev->trans_start = jiffies;
-+ netif_wake_queue(dev);
-+}
-+
-+
-+static int
-+usb_eth_open(struct net_device *dev)
-+{
-+ int rc;
-+ rc = pxa_usb_open( "usb-eth" );
-+ if ( rc == 0 ) {
-+ string_desc_t * pstr;
-+ desc_t * pd = pxa_usb_get_descriptor_ptr();
-+
-+ pd->b.ep1.wMaxPacketSize = make_word( usb_rsize );
-+ pd->b.ep2.wMaxPacketSize = make_word( usb_wsize );
-+ pd->dev.idVendor = ETHERNET_VENDOR_ID;
-+ pd->dev.idProduct = ETHERNET_PRODUCT_ID;
-+ pstr = pxa_usb_kmalloc_string_descriptor( "PXA USB NIC" );
-+ if ( pstr ) {
-+ pxa_usb_set_string_descriptor( 1, pstr );
-+ pd->dev.iProduct = 1;
-+ }
-+ rc = pxa_usb_start();
-+ }
-+
-+ if( rc == 0)
-+ {
-+ terminating = 0;
-+ cur_tx_skb = next_tx_skb = NULL;
-+ cur_rx_skb = usb_new_recv_skb();
-+ next_rx_skb = usb_new_recv_skb();
-+ if (!cur_rx_skb || !next_rx_skb) {
-+ printk("%s: can't allocate new skb\n", __FUNCTION__);
-+ if (cur_rx_skb)
-+ kfree_skb(cur_rx_skb);
-+ if (next_rx_skb)
-+ kfree_skb(next_rx_skb);
-+
-+ pxa_usb_stop();
-+ pxa_usb_close();
-+ return -ENOMEM;;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+#ifndef DMA_NO_COPY
-+ pxa_usb_recv(dmabuf, usb_rsize, usb_recv_callback);
-+#else
-+ pxa_usb_recv(cur_rx_skb->tail, MIN(usb_rsize, skb_tailroom (cur_rx_skb)),
-+ usb_recv_callback);
-+#endif
-+ }
-+
-+ return rc;
-+}
-+
-+static int
-+usb_eth_release(struct net_device *dev)
-+{
-+ string_desc_t * pstr;
-+
-+ terminating = 1;
-+ pxa_usb_send_reset();
-+ pxa_usb_recv_reset();
-+ if (cur_tx_skb)
-+ kfree_skb(cur_tx_skb);
-+ if (next_tx_skb)
-+ kfree_skb(next_tx_skb);
-+ if (cur_rx_skb)
-+ kfree_skb(cur_rx_skb);
-+ if (next_rx_skb)
-+ kfree_skb(next_rx_skb);
-+
-+ pxa_usb_stop();
-+ pxa_usb_close();
-+ if ( (pstr = pxa_usb_get_string_descriptor(1)) != NULL )
-+ kfree( pstr );
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static struct net_device_stats *
-+usb_eth_stats(struct net_device *dev)
-+{
-+ struct usbe_info_t *priv = (struct usbe_info_t*) dev->priv;
-+ struct net_device_stats *stats=NULL;
-+
-+ if (priv)
-+ stats = &priv->stats;
-+ return stats;
-+}
-+
-+static int
-+usb_eth_probe(struct net_device *dev)
-+{
-+ u8 node_id [ETH_ALEN];
-+
-+ get_random_bytes (node_id, sizeof node_id);
-+ node_id [0] &= 0xfe; // clear multicast bit
-+
-+ /*
-+ * Assign the hardware address of the board:
-+ * generate it randomly, as there can be many such
-+ * devices on the bus.
-+ */
-+ memcpy (dev->dev_addr, node_id, sizeof node_id);
-+
-+ dev->open = usb_eth_open;
-+ dev->change_mtu = usb_change_mtu;
-+ dev->stop = usb_eth_release;
-+ dev->hard_start_xmit = usb_eth_xmit;
-+ dev->get_stats = usb_eth_stats;
-+ dev->watchdog_timeo = 1*HZ;
-+ dev->tx_timeout = usb_xmit_timeout;
-+ dev->priv = &usbe_info;
-+
-+ usbe_info.dev = dev;
-+
-+ /* clear the statistics */
-+ memset(&usbe_info.stats, 0, sizeof(struct net_device_stats));
-+
-+ ether_setup(dev);
-+ dev->flags &= ~IFF_MULTICAST;
-+ dev->flags &= ~IFF_BROADCAST;
-+ //dev->flags |= IFF_NOARP;
-+
-+ return 0;
-+}
-+
-+#ifdef MODULE
-+MODULE_PARM(usb_rsize, "1i");
-+MODULE_PARM_DESC(usb_rsize, "number of bytes in packets from host to pxa");
-+MODULE_PARM(usb_wsize, "1i");
-+MODULE_PARM_DESC(usb_wsize, "number of bytes in packets from pxa to host");
-+#endif
-+
-+static int __init
-+usb_eth_init(void)
-+{
-+#ifndef DMA_NO_COPY
-+ dmabuf = kmalloc( usb_rsize, GFP_KERNEL | GFP_DMA );
-+ if (!dmabuf)
-+ return -ENOMEM;
-+#endif
-+ strncpy(usb_eth_device.name, usb_eth_name, IFNAMSIZ);
-+ usb_eth_device.init = usb_eth_probe;
-+ if (register_netdev(&usb_eth_device) != 0)
-+ return -EIO;
-+
-+ printk( KERN_INFO "USB Function Ethernet Driver Interface\n");
-+
-+ return 0;
-+}
-+
-+static void __exit
-+usb_eth_cleanup(void)
-+{
-+#ifndef DMA_NO_COPY
-+ kfree(dmabuf);
-+#endif
-+ unregister_netdev(&usb_eth_device);
-+}
-+
-+module_init(usb_eth_init);
-+module_exit(usb_eth_cleanup);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/usb_ctl.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,769 @@
-+/*
-+ * Copyright (C) Compaq Computer Corporation, 1998, 1999
-+ * Copyright (C) Extenex Corporation, 2001
-+ * Copyright (C) Intrinsyc, Inc., 2002
-+ *
-+ * PXA USB controller core driver.
-+ *
-+ * This file provides interrupt routing and overall coordination
-+ * of the endpoints.
-+ *
-+ * Please see:
-+ * linux/Documentation/arm/SA1100/SA1100_USB
-+ * for more info.
-+ *
-+ * 02-May-2002
-+ * Frank Becker (Intrinsyc) - derived from sa1100 usb_ctl.c
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/proc_fs.h>
-+#include <linux/tqueue.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <asm/io.h>
-+#include <asm/dma.h>
-+#include <asm/irq.h>
-+#include <asm/mach-types.h>
-+
-+#include "pxa_usb.h"
-+#include "usb_ctl.h"
-+
-+//#define DEBUG 1
-+
-+#if DEBUG
-+static unsigned int usb_debug = DEBUG;
-+#else
-+#define usb_debug 0 /* gcc will remove all the debug code for us */
-+#endif
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Prototypes
-+//////////////////////////////////////////////////////////////////////////////
-+
-+int usbctl_next_state_on_event( int event );
-+static void udc_int_hndlr(int, void *, struct pt_regs *);
-+static void initialize_descriptors( void );
-+static void soft_connect_hook( int enable );
-+static void udc_disable(void);
-+static void udc_enable(void);
-+
-+#if CONFIG_PROC_FS
-+#define PROC_NODE_NAME "driver/pxausb"
-+static int usbctl_read_proc(char *page, char **start, off_t off,
-+ int count, int *eof, void *data);
-+#endif
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Globals
-+//////////////////////////////////////////////////////////////////////////////
-+static const char pszMe[] = "usbctl: ";
-+struct usb_info_t usbd_info; /* global to ep0, usb_recv, usb_send */
-+
-+/* device descriptors */
-+static desc_t desc;
-+
-+#define MAX_STRING_DESC 8
-+static string_desc_t * string_desc_array[ MAX_STRING_DESC ];
-+static string_desc_t sd_zero; /* special sd_zero holds language codes */
-+
-+// called when configured
-+static usb_notify_t configured_callback = NULL;
-+
-+enum {
-+ kStateZombie = 0,
-+ kStateZombieSuspend = 1,
-+ kStateDefault = 2,
-+ kStateDefaultSuspend = 3,
-+ kStateAddr = 4,
-+ kStateAddrSuspend = 5,
-+ kStateConfig = 6,
-+ kStateConfigSuspend = 7
-+};
-+
-+/*
-+ * FIXME: The PXA UDC handles several host device requests without user
-+ * notification/intervention. The table could be collapsed quite a bit...
-+ */
-+static int device_state_machine[8][6] = {
-+// suspend reset resume adddr config deconfig
-+/* zombie */ { kStateZombieSuspend , kStateDefault, kStateZombie , kError , kError , kError },
-+/* zom sus */ { kStateZombieSuspend , kStateDefault, kStateZombie , kError , kError , kError },
-+/* default */ { kStateDefaultSuspend, kStateDefault, kStateDefault, kStateAddr, kStateConfig, kError },
-+/* def sus */ { kStateDefaultSuspend, kStateDefault, kStateDefault, kError , kError , kError },
-+/* addr */ { kStateAddrSuspend , kStateDefault, kStateAddr , kError , kStateConfig, kError },
-+/* addr sus */{ kStateAddrSuspend , kStateDefault, kStateAddr , kError , kError , kError },
-+/* config */ { kStateConfigSuspend , kStateDefault, kStateConfig , kError , kError , kStateDefault },
-+/* cfg sus */ { kStateConfigSuspend , kStateDefault, kStateConfig , kError , kError , kError }
-+};
-+
-+/* "device state" is the usb device framework state, as opposed to the
-+ "state machine state" which is whatever the driver needs and is much
-+ more fine grained
-+*/
-+static int sm_state_to_device_state[8] = {
-+// zombie zom suspend
-+USB_STATE_POWERED, USB_STATE_SUSPENDED,
-+// default default sus
-+USB_STATE_DEFAULT, USB_STATE_SUSPENDED,
-+// addr addr sus
-+USB_STATE_ADDRESS, USB_STATE_SUSPENDED,
-+// config config sus
-+USB_STATE_CONFIGURED, USB_STATE_SUSPENDED
-+};
-+
-+static char * state_names[8] =
-+{ "zombie", "zombie suspended",
-+ "default", "default suspended",
-+ "address", "address suspended",
-+ "configured", "config suspended"
-+};
-+
-+static char * event_names[6] =
-+{ "suspend", "reset", "resume",
-+ "address assigned", "configure", "de-configure"
-+};
-+
-+static char * device_state_names[] =
-+{ "not attached", "attached", "powered", "default",
-+ "address", "configured", "suspended" };
-+
-+static int sm_state = kStateZombie;
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Async
-+//////////////////////////////////////////////////////////////////////////////
-+
-+/* The UDCCR reg contains mask and interrupt status bits,
-+ * so using '|=' isn't safe as it may ack an interrupt.
-+ */
-+
-+void udc_set_mask_UDCCR( int mask )
-+{
-+ UDCCR = (UDCCR & UDCCR_MASK_BITS) | (mask & UDCCR_MASK_BITS);
-+}
-+
-+void udc_clear_mask_UDCCR( int mask)
-+{
-+ UDCCR = (UDCCR & UDCCR_MASK_BITS) & ~(mask & UDCCR_MASK_BITS);
-+}
-+
-+void udc_ack_int_UDCCR( int mask)
-+{
-+ /* udccr contains the bits we dont want to change */
-+ __u32 udccr = UDCCR & UDCCR_MASK_BITS;
-+
-+ UDCCR = udccr | (mask & ~UDCCR_MASK_BITS);
-+}
-+
-+static void
-+udc_int_hndlr(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ __u32 status = UDCCR;
-+ __u32 ir0_status = USIR0;
-+ __u32 ir1_status = USIR1;
-+ __u32 uicr0 = UICR0;
-+ __u32 uicr1 = UICR1;
-+
-+ //mask ints
-+ udc_set_mask_UDCCR( UDCCR_REM | UDCCR_SRM);
-+ UICR0 = 0xff;
-+ UICR1 = 0xff;
-+
-+ if( usb_debug > 2)
-+ {
-+ printk("%s--- udc_int_hndlr\n"
-+ "UDCCR=0x%08x UDCCS0=0x%08x UDCCS1=0x%08x UDCCS2=0x%08x\n"
-+ "USIR0=0x%08x USIR1=0x%08x UICR0=0x%08x UICR1=0x%08x\n",
-+ pszMe, status, UDCCS0, UDCCS1, UDCCS2, ir0_status, ir1_status, uicr0, uicr1);
-+ }
-+
-+ /* SUSpend Interrupt Request */
-+ if ( status & UDCCR_SUSIR )
-+ {
-+ udc_ack_int_UDCCR( UDCCR_SUSIR);
-+ if( usb_debug) printk("%sSuspend...\n", pszMe);
-+ usbctl_next_state_on_event( kEvSuspend );
-+ }
-+
-+ /* RESume Interrupt Request */
-+ if ( status & UDCCR_RESIR )
-+ {
-+ udc_ack_int_UDCCR( UDCCR_RESIR);
-+ if( usb_debug) printk("%sResume...\n", pszMe);
-+ usbctl_next_state_on_event( kEvResume );
-+ }
-+
-+ /* ReSeT Interrupt Request - UDC has been reset */
-+ if ( status & UDCCR_RSTIR )
-+ {
-+ /* clear the reset interrupt */
-+ udc_ack_int_UDCCR( UDCCR_RSTIR);
-+
-+ /* check type of reset */
-+ if( (UDCCR & UDCCR_UDA) == 0)
-+ {
-+ /* reset assertion took place, nothing to do */
-+ if( usb_debug) printk("%sReset assertion...\n", pszMe);
-+ }
-+
-+ /* ok, it's a reset negation, go on with reset */
-+ else if ( usbctl_next_state_on_event( kEvReset ) != kError )
-+ {
-+ /* starting reset sequence now... */
-+ if( usb_debug) printk("%sResetting\n", pszMe);
-+
-+ ep0_reset();
-+ ep_bulk_in1_reset();
-+ ep_bulk_out1_reset();
-+
-+ usbctl_next_state_on_event( kEvConfig );
-+ }
-+ else
-+ {
-+ printk("%sUnexpected reset\n", pszMe);
-+ }
-+ }
-+ else
-+ {
-+ /* ep0 int */
-+ if (ir0_status & USIR0_IR0)
-+ ep0_int_hndlr();
-+
-+ /* transmit bulk */
-+ if (ir0_status & USIR0_IR1)
-+ ep_bulk_in1_int_hndlr(ir0_status);
-+
-+ /* receive bulk */
-+ if ( ir0_status & USIR0_IR2)
-+ ep_bulk_out1_int_hndlr(ir0_status);
-+
-+ while (UDCCS2 & UDCCS_BO_RNE)
-+ {
-+ if( usb_debug) printk("More Bulk-out data...\n");
-+ ep_bulk_out1_int_hndlr(ir0_status);
-+ }
-+ }
-+
-+ UICR0 = uicr0;
-+ UICR1 = uicr1;
-+ udc_clear_mask_UDCCR( UDCCR_SRM | UDCCR_REM); /* enable suspend/resume, reset */
-+
-+ /* clear all endpoint ints */
-+ USIR0 |= 0xff;
-+ USIR1 |= 0xff;
-+
-+ if( usb_debug > 2)
-+ {
-+ printk("%sudc_int_hndlr\n"
-+ "UDCCR=0x%08x UDCCS0=0x%08x UDCCS1=0x%08x UDCCS2=0x%08x\n"
-+ "USIR0=0x%08x USIR1=0x%08x UICR0=0x%08x UICR1=0x%08x\n",
-+ pszMe, UDCCR, UDCCS0, UDCCS1, UDCCS2, USIR0, USIR1, UICR0, UICR1);
-+ }
-+}
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Public Interface
-+//////////////////////////////////////////////////////////////////////////////
-+
-+/* Open PXA usb core on behalf of a client, but don't start running */
-+
-+int
-+pxa_usb_open( const char * client )
-+{
-+ if ( usbd_info.client_name != NULL )
-+ {
-+ printk( "%sUnable to register %s (%s already registered).\n",
-+ pszMe, client, usbd_info.client_name );
-+ return -EBUSY;
-+ }
-+
-+ usbd_info.client_name = (char*) client;
-+ memset(&usbd_info.stats, 0, sizeof(struct usb_stats_t));
-+ memset(string_desc_array, 0, sizeof(string_desc_array));
-+
-+ /* hack to start in zombie suspended state */
-+ sm_state = kStateZombieSuspend;
-+ usbd_info.state = USB_STATE_SUSPENDED;
-+
-+ /* create descriptors for enumeration */
-+ initialize_descriptors();
-+
-+ printk( "%s%s registered.\n", pszMe, client );
-+ return 0;
-+}
-+
-+/* Start running. Must have called usb_open (above) first */
-+int
-+pxa_usb_start( void )
-+{
-+ if ( usbd_info.client_name == NULL ) {
-+ printk( "%s%s - no client registered\n",
-+ pszMe, __FUNCTION__ );
-+ return -EPERM;
-+ }
-+
-+ /* start UDC internal machinery running */
-+ udc_enable();
-+ udelay( 100 );
-+
-+ /* flush DMA and fire through some -EAGAINs */
-+ ep_bulk_out1_init( usbd_info.dmach_rx );
-+ ep_bulk_in1_init( usbd_info.dmach_tx );
-+
-+ /* give endpoint notification we are starting */
-+ ep_bulk_out1_state_change_notify( USB_STATE_SUSPENDED );
-+ ep_bulk_in1_state_change_notify( USB_STATE_SUSPENDED );
-+
-+ /* enable any platform specific hardware */
-+ soft_connect_hook( 1 );
-+
-+ /* enable suspend/resume, reset */
-+ udc_clear_mask_UDCCR( UDCCR_SRM | UDCCR_REM);
-+ /* enable ep0, ep1, ep2 */
-+ UICR0 &= ~(UICR0_IM0 | UICR0_IM1 | UICR0_IM2);
-+
-+ if( usb_debug) printk( "%sStarted %s\n", pszMe, usbd_info.client_name );
-+ return 0;
-+}
-+
-+/* Stop USB core from running */
-+int
-+pxa_usb_stop( void )
-+{
-+ if ( usbd_info.client_name == NULL ) {
-+ printk( "%s%s - no client registered\n",
-+ pszMe, __FUNCTION__ );
-+ return -EPERM;
-+ }
-+ /* mask everything */
-+ /* disable suspend/resume, reset */
-+ udc_set_mask_UDCCR( UDCCR_SRM | UDCCR_REM);
-+ /* disable ep0, ep1, ep2 */
-+ UICR0 |= (UICR0_IM0 | UICR0_IM1 | UICR0_IM2);
-+
-+ ep_bulk_out1_reset();
-+ ep_bulk_in1_reset();
-+
-+ udc_disable();
-+ if( usb_debug) printk( "%sStopped %s\n", pszMe, usbd_info.client_name );
-+ return 0;
-+}
-+
-+/* Tell PXA core client is through using it */
-+int
-+pxa_usb_close( void )
-+{
-+ if ( usbd_info.client_name == NULL ) {
-+ printk( "%s%s - no client registered\n",
-+ pszMe, __FUNCTION__ );
-+ return -EPERM;
-+ }
-+ printk( "%s%s closed.\n", pszMe, (char*)usbd_info.client_name );
-+ usbd_info.client_name = NULL;
-+ return 0;
-+}
-+
-+/* set a proc to be called when device is configured */
-+usb_notify_t pxa_set_configured_callback( usb_notify_t func )
-+{
-+ usb_notify_t retval = configured_callback;
-+ configured_callback = func;
-+ return retval;
-+}
-+
-+/*====================================================
-+ * Descriptor Manipulation.
-+ * Use these between open() and start() above to setup
-+ * the descriptors for your device.
-+ *
-+ */
-+
-+/* get pointer to static default descriptor */
-+desc_t *
-+pxa_usb_get_descriptor_ptr( void ) { return &desc; }
-+
-+/* optional: set a string descriptor */
-+int
-+pxa_usb_set_string_descriptor( int i, string_desc_t * p )
-+{
-+ int retval;
-+ if ( i < MAX_STRING_DESC ) {
-+ string_desc_array[i] = p;
-+ retval = 0;
-+ } else {
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+/* optional: get a previously set string descriptor */
-+string_desc_t *
-+pxa_usb_get_string_descriptor( int i )
-+{
-+ return ( i < MAX_STRING_DESC )
-+ ? string_desc_array[i]
-+ : NULL;
-+}
-+
-+
-+/* optional: kmalloc and unicode up a string descriptor */
-+string_desc_t *
-+pxa_usb_kmalloc_string_descriptor( const char * p )
-+{
-+ string_desc_t * pResult = NULL;
-+
-+ if ( p ) {
-+ int len = strlen( p );
-+ int uni_len = len * sizeof( __u16 );
-+ pResult = (string_desc_t*) kmalloc( uni_len + 2, GFP_KERNEL ); /* ugh! */
-+ if ( pResult != NULL ) {
-+ int i;
-+ pResult->bLength = uni_len + 2;
-+ pResult->bDescriptorType = USB_DESC_STRING;
-+ for( i = 0; i < len ; i++ ) {
-+ pResult->bString[i] = make_word( (__u16) p[i] );
-+ }
-+ }
-+ }
-+ return pResult;
-+}
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Exports to rest of driver
-+//////////////////////////////////////////////////////////////////////////////
-+
-+/* called by the int handler here and the two endpoint files when interesting
-+ .."events" happen */
-+
-+int
-+usbctl_next_state_on_event( int event )
-+{
-+ int next_state = device_state_machine[ sm_state ][ event ];
-+ if ( next_state != kError )
-+ {
-+ int next_device_state = sm_state_to_device_state[ next_state ];
-+ if( usb_debug) printk( "%s%s --> [%s] --> %s. Device in %s state.\n",
-+ pszMe, state_names[ sm_state ], event_names[ event ],
-+ state_names[ next_state ], device_state_names[ next_device_state ] );
-+
-+ sm_state = next_state;
-+ if ( usbd_info.state != next_device_state )
-+ {
-+ if ( configured_callback != NULL
-+ &&
-+ next_device_state == USB_STATE_CONFIGURED
-+ &&
-+ usbd_info.state != USB_STATE_SUSPENDED
-+ ) {
-+ configured_callback();
-+ }
-+ usbd_info.state = next_device_state;
-+
-+ ep_bulk_out1_state_change_notify( next_device_state );
-+ ep_bulk_in1_state_change_notify( next_device_state );
-+ }
-+ }
-+#if 1
-+ else
-+ printk( "%s%s --> [%s] --> ??? is an error.\n",
-+ pszMe, state_names[ sm_state ], event_names[ event ] );
-+#endif
-+ return next_state;
-+}
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Private Helpers
-+//////////////////////////////////////////////////////////////////////////////
-+
-+/* setup default descriptors */
-+
-+static void
-+initialize_descriptors(void)
-+{
-+ desc.dev.bLength = sizeof( device_desc_t );
-+ desc.dev.bDescriptorType = USB_DESC_DEVICE;
-+ desc.dev.bcdUSB = 0x100; /* 1.0 */
-+ desc.dev.bDeviceClass = 0xFF; /* vendor specific */
-+ desc.dev.bDeviceSubClass = 0;
-+ desc.dev.bDeviceProtocol = 0;
-+ desc.dev.bMaxPacketSize0 = 16; /* ep0 max fifo size */
-+ desc.dev.idVendor = 0; /* vendor ID undefined */
-+ desc.dev.idProduct = 0; /* product */
-+ desc.dev.bcdDevice = 0; /* vendor assigned device release num */
-+ desc.dev.iManufacturer = 0; /* index of manufacturer string */
-+ desc.dev.iProduct = 0; /* index of product description string */
-+ desc.dev.iSerialNumber = 0; /* index of string holding product s/n */
-+ desc.dev.bNumConfigurations = 1;
-+
-+ desc.b.cfg.bLength = sizeof( config_desc_t );
-+ desc.b.cfg.bDescriptorType = USB_DESC_CONFIG;
-+ desc.b.cfg.wTotalLength = make_word_c( sizeof(struct cdb) );
-+ desc.b.cfg.bNumInterfaces = 1;
-+ desc.b.cfg.bConfigurationValue = 1;
-+ desc.b.cfg.iConfiguration = 0;
-+ desc.b.cfg.bmAttributes = USB_CONFIG_BUSPOWERED;
-+ desc.b.cfg.MaxPower = USB_POWER( 500 );
-+
-+ desc.b.intf.bLength = sizeof( intf_desc_t );
-+ desc.b.intf.bDescriptorType = USB_DESC_INTERFACE;
-+ desc.b.intf.bInterfaceNumber = 0; /* unique intf index*/
-+ desc.b.intf.bAlternateSetting = 0;
-+ desc.b.intf.bNumEndpoints = 2;
-+ desc.b.intf.bInterfaceClass = 0xFF; /* vendor specific */
-+ desc.b.intf.bInterfaceSubClass = 0;
-+ desc.b.intf.bInterfaceProtocol = 0;
-+ desc.b.intf.iInterface = 0;
-+
-+/*
-+ * FIXME...
-+ * The host usbnet driver expects EP1=out EP2=in. On the PXA UDC EP1=in, EP2=out
-+ */
-+ desc.b.ep1.bLength = sizeof( ep_desc_t );
-+ desc.b.ep1.bDescriptorType = USB_DESC_ENDPOINT;
-+ desc.b.ep1.bEndpointAddress = USB_EP_ADDRESS( 1, USB_IN );
-+ desc.b.ep1.bmAttributes = USB_EP_BULK;
-+ desc.b.ep1.wMaxPacketSize = make_word_c( 64 );
-+ desc.b.ep1.bInterval = 0;
-+
-+ desc.b.ep2.bLength = sizeof( ep_desc_t );
-+ desc.b.ep2.bDescriptorType = USB_DESC_ENDPOINT;
-+ desc.b.ep2.bEndpointAddress = USB_EP_ADDRESS( 2, USB_OUT );
-+ desc.b.ep2.bmAttributes = USB_EP_BULK;
-+ desc.b.ep2.wMaxPacketSize = make_word_c( 64 );
-+ desc.b.ep2.bInterval = 0;
-+
-+// FIXME: Add support for all endpoint...
-+
-+ /* set language */
-+ /* See: http://www.usb.org/developers/data/USB_LANGIDs.pdf */
-+ sd_zero.bDescriptorType = USB_DESC_STRING;
-+ sd_zero.bLength = sizeof( string_desc_t );
-+ sd_zero.bString[0] = make_word_c( 0x409 ); /* American English */
-+ pxa_usb_set_string_descriptor( 0, &sd_zero );
-+}
-+
-+/* soft_connect_hook()
-+ * Some devices have platform-specific circuitry to make USB
-+ * not seem to be plugged in, even when it is. This allows
-+ * software to control when a device 'appears' on the USB bus
-+ * (after Linux has booted and this driver has loaded, for
-+ * example). If you have such a circuit, control it here.
-+ */
-+static void
-+soft_connect_hook( int enable )
-+{
-+}
-+
-+/* disable the UDC at the source */
-+static void
-+udc_disable(void)
-+{
-+ soft_connect_hook( 0 );
-+ /* clear UDC-enable */
-+ udc_clear_mask_UDCCR( UDCCR_UDE);
-+
-+ /* Disable clock for USB device */
-+ CKEN &= ~CKEN11_USB;
-+}
-+
-+
-+/* enable the udc at the source */
-+static void
-+udc_enable(void)
-+{
-+ /* Enable clock for USB device */
-+ CKEN |= CKEN11_USB;
-+
-+ /* try to clear these bits before we enable the udc */
-+ udc_ack_int_UDCCR( UDCCR_SUSIR);
-+ udc_ack_int_UDCCR( UDCCR_RSTIR);
-+ udc_ack_int_UDCCR( UDCCR_RESIR);
-+
-+ /* set UDC-enable */
-+ udc_set_mask_UDCCR( UDCCR_UDE);
-+ if( (UDCCR & UDCCR_UDA) == 0)
-+ {
-+ /* There's a reset on the bus,
-+ * clear the interrupt bit and keep going
-+ */
-+ udc_ack_int_UDCCR( UDCCR_RSTIR);
-+ }
-+
-+ /* "USB test mode" to work around errata 40-42 (stepping a0, a1)
-+ * which could result in missing packets and interrupts.
-+ * Supposedly this turns off double buffering for all endpoints.
-+ */
-+ if( usb_debug) printk( "USB RES1=%x RES2=%x RES3=%x\n", UDC_RES1, UDC_RES2, UDC_RES3);
-+ UDC_RES1 = 0x00;
-+ UDC_RES2 = 0x00;
-+ if( usb_debug) printk( "USB RES1=%x RES2=%x RES3=%x\n", UDC_RES1, UDC_RES2, UDC_RES3);
-+}
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Proc Filesystem Support
-+//////////////////////////////////////////////////////////////////////////////
-+
-+#if CONFIG_PROC_FS
-+
-+#define SAY( fmt, args... ) p += sprintf(p, fmt, ## args )
-+#define SAYV( num ) p += sprintf(p, num_fmt, "Value", num )
-+#define SAYC( label, yn ) p += sprintf(p, yn_fmt, label, yn )
-+#define SAYS( label, v ) p += sprintf(p, cnt_fmt, label, v )
-+
-+static int usbctl_read_proc(char *page, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ const char * num_fmt = "%25.25s: %8.8lX\n";
-+ const char * cnt_fmt = "%25.25s: %lu\n";
-+ const char * yn_fmt = "%25.25s: %s\n";
-+ const char * yes = "YES";
-+ const char * no = "NO";
-+ unsigned long v;
-+ char * p = page;
-+ int len;
-+
-+ SAY( "PXA USB Controller Core\n" );
-+ SAY( "Active Client: %s\n", usbd_info.client_name ? usbd_info.client_name : "none");
-+ SAY( "USB state: %s (%s) %d\n",
-+ device_state_names[ sm_state_to_device_state[ sm_state ] ],
-+ state_names[ sm_state ],
-+ sm_state );
-+
-+ SAYS( "ep0 bytes read", usbd_info.stats.ep0_bytes_read );
-+ SAYS( "ep0 bytes written", usbd_info.stats.ep0_bytes_written );
-+ SAYS( "ep0 FIFO read failures", usbd_info.stats.ep0_fifo_write_failures );
-+ SAYS( "ep0 FIFO write failures", usbd_info.stats.ep0_fifo_write_failures );
-+
-+ SAY( "\n" );
-+
-+ v = UDCCR;
-+ SAY( "\nUDC Control Register\n" );
-+ SAYV( v );
-+ SAYC( "UDC Enabled", ( v & UDCCR_UDE ) ? yes : no );
-+ SAYC( "UDC Active", ( v & UDCCR_UDA ) ? yes : no );
-+ SAYC( "Suspend/Resume interrupts masked", ( v & UDCCR_SRM ) ? yes : no );
-+ SAYC( "Reset interrupts masked", ( v & UDCCR_REM ) ? yes : no );
-+ SAYC( "Reset pending", ( v & UDCCR_RSTIR ) ? yes : no );
-+ SAYC( "Suspend pending", ( v & UDCCR_SUSIR ) ? yes : no );
-+ SAYC( "Resume pending", ( v & UDCCR_RESIR ) ? yes : no );
-+
-+ len = ( p - page ) - off;
-+ if ( len < 0 )
-+ len = 0;
-+ *eof = ( len <=count ) ? 1 : 0;
-+ *start = page + off;
-+ return len;
-+}
-+
-+#endif /* CONFIG_PROC_FS */
-+
-+#if 0
-+static void irq_handler(int channel, void *data, struct pt_regs *regs)
-+{
-+ if( channel == usbd_info.dmach_rx)
-+ {
-+ printk( "USB receive DMA\n");
-+ }
-+ else if( channel == usbd_info.dmach_tx)
-+ {
-+ printk( "USB transmit DMA\n");
-+ }
-+ else
-+ {
-+ printk( "USB unknown DMA channel\n");
-+ }
-+}
-+#endif
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Module Initialization and Shutdown
-+//////////////////////////////////////////////////////////////////////////////
-+/*
-+ * usbctl_init()
-+ * Module load time. Allocate dma and interrupt resources. Setup /proc fs
-+ * entry. Leave UDC disabled.
-+ */
-+int __init usbctl_init( void )
-+{
-+ int retval = 0;
-+
-+ udc_disable();
-+
-+ memset( &usbd_info, 0, sizeof( usbd_info ) );
-+
-+#if CONFIG_PROC_FS
-+ create_proc_read_entry ( PROC_NODE_NAME, 0, NULL, usbctl_read_proc, NULL);
-+#endif
-+
-+#if 0
-+ /* setup rx dma */
-+ usbd_info.dmach_rx = pxa_request_dma("USB receive", DMA_PRIO_MEDIUM, irq_handler, 0 /*data; DMA_Ser0UDCRd*/);
-+ if (usbd_info.dmach_rx < 0) {
-+ printk("%sunable to register for rx dma rc=%d\n", pszMe, usbd_info.dmach_rx );
-+ goto err_rx_dma;
-+ }
-+
-+ /* setup tx dma */
-+ usbd_info.dmach_tx = pxa_request_dma("USB receive", DMA_PRIO_MEDIUM, irq_handler, 0 /*data; DMA_Ser0UDCRd*/);
-+ if (usbd_info.dmach_tx < 0) {
-+ printk("%sunable to register for tx dma rc=%d\n",pszMe,usbd_info.dmach_tx);
-+ goto err_tx_dma;
-+ }
-+#endif
-+
-+ /* now allocate the IRQ. */
-+ retval = request_irq(IRQ_USB, udc_int_hndlr, SA_INTERRUPT, "PXA USB core", NULL);
-+ if (retval) {
-+ printk("%sCouldn't request USB irq rc=%d\n",pszMe, retval);
-+ goto err_irq;
-+ }
-+
-+ printk( "PXA USB Controller Core Initialized\n");
-+ return 0;
-+
-+err_irq:
-+#if 0
-+ pxa_free_dma(usbd_info.dmach_tx);
-+ usbd_info.dmach_tx = 0;
-+err_tx_dma:
-+ pxa_free_dma(usbd_info.dmach_rx);
-+ usbd_info.dmach_rx = 0;
-+err_rx_dma:
-+#endif
-+ return retval;
-+}
-+/*
-+ * usbctl_exit()
-+ * Release DMA and interrupt resources
-+ */
-+void __exit usbctl_exit( void )
-+{
-+ printk("Unloading PXA USB Controller\n");
-+
-+ udc_disable();
-+
-+#if CONFIG_PROC_FS
-+ remove_proc_entry ( PROC_NODE_NAME, NULL);
-+#endif
-+
-+ pxa_free_dma(usbd_info.dmach_rx);
-+ pxa_free_dma(usbd_info.dmach_tx);
-+ free_irq(IRQ_USB, NULL);
-+}
-+
-+module_init( usbctl_init );
-+module_exit( usbctl_exit );
-+
-+EXPORT_SYMBOL( pxa_usb_open );
-+EXPORT_SYMBOL( pxa_usb_start );
-+EXPORT_SYMBOL( pxa_usb_stop );
-+EXPORT_SYMBOL( pxa_usb_close );
-+EXPORT_SYMBOL( pxa_usb_get_descriptor_ptr );
-+EXPORT_SYMBOL( pxa_usb_set_string_descriptor );
-+EXPORT_SYMBOL( pxa_usb_get_string_descriptor );
-+EXPORT_SYMBOL( pxa_usb_kmalloc_string_descriptor );
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/usb_ctl.h 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,89 @@
-+/*
-+ * Copyright (C) Compaq Computer Corporation, 1998, 1999
-+ * Copyright (C) Extenex Corporation 2001
-+ * Copyright (C) Intrinsyc, Inc., 2002
-+ *
-+ * usb_ctl.h
-+ *
-+ * PRIVATE interface used to share info among components of the PXA USB
-+ * core: usb_ctl, usb_ep0, usb_recv and usb_send. Clients of the USB core
-+ * should use pxa_usb.h.
-+ *
-+ * 02-May-2002
-+ * Frank Becker (Intrinsyc) - derived from sa1100 usb_ctl.h
-+ *
-+ */
-+
-+#ifndef _USB_CTL_H
-+#define _USB_CTL_H
-+
-+/* Interrupt mask bits and UDC enable bit */
-+#define UDCCR_MASK_BITS (UDCCR_REM | UDCCR_SRM | UDCCR_UDE)
-+
-+/*
-+ * These states correspond to those in the USB specification v1.0
-+ * in chapter 8, Device Framework.
-+ */
-+enum {
-+ USB_STATE_NOTATTACHED =0,
-+ USB_STATE_ATTACHED =1,
-+ USB_STATE_POWERED =2,
-+ USB_STATE_DEFAULT =3,
-+ USB_STATE_ADDRESS =4,
-+ USB_STATE_CONFIGURED =5,
-+ USB_STATE_SUSPENDED =6
-+};
-+
-+struct usb_stats_t {
-+ unsigned long ep0_fifo_write_failures;
-+ unsigned long ep0_bytes_written;
-+ unsigned long ep0_fifo_read_failures;
-+ unsigned long ep0_bytes_read;
-+};
-+
-+struct usb_info_t
-+{
-+ char * client_name;
-+ dmach_t dmach_tx, dmach_rx;
-+ int state;
-+ unsigned char address;
-+ struct usb_stats_t stats;
-+};
-+
-+/* in usb_ctl.c */
-+extern struct usb_info_t usbd_info;
-+
-+/*
-+ * Function Prototypes
-+ */
-+enum {
-+ kError =-1,
-+ kEvSuspend =0,
-+ kEvReset =1,
-+ kEvResume =2,
-+ kEvAddress =3,
-+ kEvConfig =4,
-+ kEvDeConfig =5
-+};
-+int usbctl_next_state_on_event( int event );
-+
-+/* endpoint zero */
-+void ep0_reset(void);
-+void ep0_int_hndlr(void);
-+
-+/* receiver */
-+void ep_bulk_out1_state_change_notify( int new_state );
-+int ep_bulk_out1_recv(void);
-+int ep_bulk_out1_init(int chn);
-+void ep_bulk_out1_int_hndlr(int status);
-+void ep_bulk_out1_reset(void);
-+void ep_bulk_out1_stall(void);
-+
-+/* xmitter */
-+void ep_bulk_in1_state_change_notify( int new_state );
-+void ep_bulk_in1_reset(void);
-+int ep_bulk_in1_init(int chn);
-+void ep_bulk_in1_int_hndlr(int status);
-+void ep_bulk_in1_stall(void);
-+
-+#endif /* _USB_CTL_H */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/usb_ep0.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,556 @@
-+/*
-+ * Copyright (C) Extenex Corporation 2001
-+ * Copyright (C) Compaq Computer Corporation, 1998, 1999
-+ * Copyright (C) Intrinsyc, Inc., 2002
-+ *
-+ * PXA USB controller driver - Endpoint zero management
-+ *
-+ * Please see:
-+ * linux/Documentation/arm/SA1100/SA1100_USB
-+ * for more info.
-+ *
-+ * 02-May-2002
-+ * Frank Becker (Intrinsyc) - derived from sa1100 usb_ctl.c
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/tqueue.h>
-+#include <linux/delay.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <asm/io.h>
-+#include <asm/dma.h>
-+#include <asm/irq.h>
-+
-+#include "pxa_usb.h" /* public interface */
-+#include "usb_ctl.h" /* private stuff */
-+#include "usb_ep0.h"
-+
-+
-+// 1 == lots of trace noise, 0 = only "important' stuff
-+#define VERBOSITY 0
-+
-+enum { true = 1, false = 0 };
-+typedef int bool;
-+#ifndef MIN
-+#define MIN( a, b ) ((a)<(b)?(a):(b))
-+#endif
-+
-+#if 1 && !defined( ASSERT )
-+# define ASSERT(expr) \
-+if(!(expr)) { \
-+ printk( "Assertion failed! %s,%s,%s,line=%d\n",\
-+#expr,__FILE__,__FUNCTION__,__LINE__); \
-+}
-+#else
-+# define ASSERT(expr)
-+#endif
-+
-+#if VERBOSITY
-+#define PRINTKD(fmt, args...) printk( fmt , ## args)
-+#else
-+#define PRINTKD(fmt, args...)
-+#endif
-+
-+static EP0_state ep0_state = EP0_IDLE;
-+
-+/***************************************************************************
-+ Prototypes
-+ ***************************************************************************/
-+/* "setup handlers" -- the main functions dispatched to by the
-+ .. isr. These represent the major "modes" of endpoint 0 operation */
-+static void sh_setup_begin(void); /* setup begin (idle) */
-+static void sh_write( void ); /* writing data */
-+static int read_fifo( usb_dev_request_t * p );
-+static void write_fifo( void );
-+static void get_descriptor( usb_dev_request_t * pReq );
-+static void queue_and_start_write( void * p, int req, int act );
-+
-+/***************************************************************************
-+ Inline Helpers
-+ ***************************************************************************/
-+
-+inline int type_code_from_request( __u8 by ) { return (( by >> 4 ) & 3); }
-+
-+/* print string descriptor */
-+static inline void psdesc( string_desc_t * p )
-+{
-+ int i;
-+ int nchars = ( p->bLength - 2 ) / sizeof( __u16 );
-+ printk( "'" );
-+ for( i = 0 ; i < nchars ; i++ ) {
-+ printk( "%c", (char) p->bString[i] );
-+ }
-+ printk( "'\n" );
-+}
-+
-+#if VERBOSITY
-+/* "pcs" == "print control status" */
-+static inline void pcs( void )
-+{
-+ __u32 foo = UDCCS0;
-+ printk( "%08x: %s %s %s %s %s %s\n",
-+ foo,
-+ foo & UDCCS0_SA ? "SA" : "",
-+ foo & UDCCS0_OPR ? "OPR" : "",
-+ foo & UDCCS0_RNE ? "RNE" : "",
-+ foo & UDCCS0_SST ? "SST" : "",
-+ foo & UDCCS0_FST ? "FST" : "",
-+ foo & UDCCS0_DRWF ? "DRWF" : ""
-+ );
-+}
-+static inline void preq( usb_dev_request_t * pReq )
-+{
-+ static char * tnames[] = { "dev", "intf", "ep", "oth" };
-+ static char * rnames[] = { "std", "class", "vendor", "???" };
-+ char * psz;
-+ switch( pReq->bRequest ) {
-+ case GET_STATUS: psz = "get stat"; break;
-+ case CLEAR_FEATURE: psz = "clr feat"; break;
-+ case SET_FEATURE: psz = "set feat"; break;
-+ case SET_ADDRESS: psz = "set addr"; break;
-+ case GET_DESCRIPTOR: psz = "get desc"; break;
-+ case SET_DESCRIPTOR: psz = "set desc"; break;
-+ case GET_CONFIGURATION: psz = "get cfg"; break;
-+ case SET_CONFIGURATION: psz = "set cfg"; break;
-+ case GET_INTERFACE: psz = "get intf"; break;
-+ case SET_INTERFACE: psz = "set intf"; break;
-+ case SYNCH_FRAME: psz = "synch frame"; break;
-+ default: psz = "unknown"; break;
-+ }
-+ printk( "- [%s: %s req to %s. dir=%s]\n", psz,
-+ rnames[ (pReq->bmRequestType >> 5) & 3 ],
-+ tnames[ pReq->bmRequestType & 3 ],
-+ ( pReq->bmRequestType & 0x80 ) ? "in" : "out" );
-+}
-+
-+#else
-+static inline void pcs( void ){}
-+static inline void preq( usb_dev_request_t *x){}
-+#endif
-+
-+/***************************************************************************
-+ Globals
-+ ***************************************************************************/
-+static const char pszMe[] = "usbep0: ";
-+
-+/* pointer to current setup handler */
-+static void (*current_handler)(void) = sh_setup_begin;
-+
-+/* global write struct to keep write
-+ ..state around across interrupts */
-+static struct {
-+ unsigned char *p;
-+ int bytes_left;
-+} wr;
-+
-+/***************************************************************************
-+ Public Interface
-+ ***************************************************************************/
-+
-+/* reset received from HUB (or controller just went nuts and reset by itself!)
-+ so udc core has been reset, track this state here */
-+void ep0_reset(void)
-+{
-+ PRINTKD( "%sep0_reset\n", pszMe);
-+ /* reset state machine */
-+ current_handler = sh_setup_begin;
-+ wr.p = NULL;
-+ wr.bytes_left = 0;
-+ usbd_info.address=0;
-+}
-+
-+/* handle interrupt for endpoint zero */
-+void ep0_int_hndlr( void )
-+{
-+ PRINTKD( "%sep0_int_hndlr\n", pszMe);
-+ pcs();
-+ (*current_handler)();
-+}
-+
-+/***************************************************************************
-+ Setup Handlers
-+ ***************************************************************************/
-+/*
-+ * sh_setup_begin()
-+ * This setup handler is the "idle" state of endpoint zero. It looks for OPR
-+ * (OUT packet ready) to see if a setup request has been been received from the
-+ * host.
-+ *
-+ */
-+static void sh_setup_begin( void )
-+{
-+ usb_dev_request_t req;
-+ int request_type;
-+ int n;
-+ __u32 cs_reg_in = UDCCS0;
-+
-+ PRINTKD( "%ssh_setup_begin\n", pszMe);
-+
-+ /* Be sure out packet ready, otherwise something is wrong */
-+ if ( (cs_reg_in & UDCCS0_OPR) == 0 ) {
-+ /* we can get here early...if so, we'll int again in a moment */
-+ PRINTKD( "%ssetup begin: no OUT packet available. Exiting\n", pszMe );
-+ goto sh_sb_end;
-+ }
-+
-+ if( ((cs_reg_in & UDCCS0_SA) == 0) && (ep0_state == EP0_IN_DATA_PHASE))
-+ {
-+ PRINTKD( "%ssetup begin: premature status\n", pszMe );
-+
-+ /* premature status, reset tx fifo and go back to idle state*/
-+ UDCCS0 = UDCCS0_OPR | UDCCS0_FTF;
-+
-+ ep0_state = EP0_IDLE;
-+ return;
-+ }
-+
-+ if( (UDCCS0 & UDCCS0_RNE) == 0)
-+ {
-+ /* zero-length OUT? */
-+ printk( "%ssetup begin: zero-length OUT?\n", pszMe );
-+ goto sh_sb_end;
-+ }
-+
-+ /* read the setup request */
-+ n = read_fifo( &req );
-+ if ( n != sizeof( req ) ) {
-+ printk( "%ssetup begin: fifo READ ERROR wanted %d bytes got %d. "
-+ " Stalling out...\n",
-+ pszMe, sizeof( req ), n );
-+ /* force stall, serviced out */
-+ UDCCS0 = UDCCS0_FST;
-+ goto sh_sb_end;
-+ }
-+
-+ /* Is it a standard request? (not vendor or class request) */
-+ request_type = type_code_from_request( req.bmRequestType );
-+ if ( request_type != 0 ) {
-+ printk( "%ssetup begin: unsupported bmRequestType: %d ignored\n",
-+ pszMe, request_type );
-+ goto sh_sb_end;
-+ }
-+
-+#if VERBOSITY
-+ {
-+ unsigned char * pdb = (unsigned char *) &req;
-+ PRINTKD( "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X ",
-+ pdb[0], pdb[1], pdb[2], pdb[3], pdb[4], pdb[5], pdb[6], pdb[7]
-+ );
-+ preq( &req );
-+ }
-+#endif
-+
-+ /* Handle it */
-+ switch( req.bRequest ) {
-+
-+ case SET_ADDRESS:
-+ PRINTKD( "%sSET_ADDRESS handled by UDC\n", pszMe);
-+ break;
-+#if 0 /* NOT_NEEDED */
-+
-+ case SET_FEATURE:
-+ PRINTKD( "%sSET_FEATURE handled by UDC\n", pszMe);
-+ break;
-+
-+ case CLEAR_FEATURE:
-+ PRINTKD( "%sCLEAR_FEATURE handled by UDC\n", pszMe);
-+ break;
-+
-+ case GET_CONFIGURATION:
-+ PRINTKD( "%sGET_CONFIGURATION handled by UDC\n", pszMe );
-+ break;
-+
-+ case GET_STATUS:
-+ PRINTKD( "%s%sGET_STATUS handled by UDC\n", pszMe );
-+ break;
-+
-+ case GET_INTERFACE:
-+ PRINTKD( "%sGET_INTERFACE handled by UDC\n", pszMe);
-+ break;
-+
-+ case SYNCH_FRAME:
-+ PRINTKD( "%sSYNCH_FRAME handled by UDC\n", pszMe );
-+ break;
-+#endif
-+
-+ case GET_DESCRIPTOR:
-+ PRINTKD( "%sGET_DESCRIPTOR\n", pszMe );
-+ get_descriptor( &req );
-+ break;
-+
-+ case SET_INTERFACE:
-+ PRINTKD( "%sSET_INTERFACE TODO...\n", pszMe);
-+ break;
-+
-+ case SET_DESCRIPTOR:
-+ PRINTKD( "%sSET_DESCRIPTOR TODO...\n", pszMe );
-+ break;
-+
-+ case SET_CONFIGURATION:
-+ PRINTKD( "%sSET_CONFIGURATION %d\n", pszMe, req.wValue);
-+
-+/*
-+ * FIXME: Something is not quite right here... I only ever get a
-+ * de-configure from the host. Ignoring it for now, since usb
-+ * ethernet won't do anything unless usb is 'configured'.
-+ *
-+ */
-+#if 0
-+ switch( req.wValue)
-+ {
-+ case 0:
-+ /* configured */
-+ usbctl_next_state_on_event( kEvConfig );
-+ break;
-+ case 1:
-+ /* de-configured */
-+ usbctl_next_state_on_event( kEvDeConfig );
-+ break;
-+ default:
-+ PRINTKD( "%sSET_CONFIGURATION: unknown configuration value (%d)\n", pszMe, req.wValue);
-+ break;
-+ }
-+#endif
-+ break;
-+ default :
-+ printk("%sunknown request 0x%x\n", pszMe, req.bRequest);
-+ break;
-+ } /* switch( bRequest ) */
-+
-+sh_sb_end:
-+ return;
-+}
-+
-+/*
-+ * sh_write()
-+ *
-+ * Due to UDC bugs we push everything into the fifo in one go.
-+ * Using interrupts just didn't work right...
-+ * This should be ok, since control request are small.
-+ */
-+static void sh_write()
-+{
-+ PRINTKD( "sh_write\n" );
-+ do
-+ {
-+ write_fifo();
-+ } while( ep0_state != EP0_END_XFER);
-+}
-+
-+/***************************************************************************
-+ Other Private Subroutines
-+ ***************************************************************************/
-+/*
-+ * queue_and_start_write()
-+ * data == data to send
-+ * req == bytes host requested
-+ * act == bytes we actually have
-+ *
-+ * Sets up the global "wr"-ite structure and load the outbound FIFO
-+ * with data.
-+ *
-+ */
-+static void queue_and_start_write( void * data, int req, int act )
-+{
-+ PRINTKD( "write start: bytes requested=%d actual=%d\n", req, act);
-+
-+ wr.p = (unsigned char*) data;
-+ wr.bytes_left = MIN( act, req );
-+
-+ ep0_state = EP0_IN_DATA_PHASE;
-+ sh_write();
-+
-+ return;
-+}
-+/*
-+ * write_fifo()
-+ * Stick bytes in the endpoint zero FIFO.
-+ *
-+ */
-+static void write_fifo( void )
-+{
-+ int bytes_this_time = MIN( wr.bytes_left, EP0_FIFO_SIZE );
-+ int bytes_written = 0;
-+
-+ while( bytes_this_time-- ) {
-+// PRINTKD( "%2.2X ", *wr.p );
-+ UDDR0 = *wr.p++;
-+ bytes_written++;
-+ }
-+ wr.bytes_left -= bytes_written;
-+
-+ usbd_info.stats.ep0_bytes_written += bytes_written;
-+
-+ if( (wr.bytes_left==0))
-+ {
-+ wr.p = NULL; /* be anal */
-+
-+ if(bytes_written < EP0_FIFO_SIZE)
-+ {
-+ int count;
-+ int udccs0;
-+
-+ /* We always end the transfer with a short or zero length packet */
-+ ep0_state = EP0_END_XFER;
-+ current_handler = sh_setup_begin;
-+
-+ /* Let the packet go... */
-+ UDCCS0 = UDCCS0_IPR;
-+
-+ /* Wait until we get to status-stage, then ack.
-+ *
-+ * When the UDC sets the UDCCS0[OPR] bit, an interrupt
-+ * is supposed to be generated (see 12.5.1 step 14ff, PXA Dev Manual).
-+ * That approach didn't work out. Usually a new SETUP command was
-+ * already in the fifo. I tried many approaches but was always losing
-+ * at least some OPR interrupts. Thus the polling below...
-+ */
-+ count = 1000;
-+ udccs0 = UDCCS0;
-+ do
-+ {
-+ if( (UDCCS0 & UDCCS0_OPR))
-+ {
-+ /* clear OPR, generate ack */
-+ UDCCS0 = UDCCS0_OPR;
-+ break;
-+ }
-+ count--;
-+ udelay(1);
-+ } while( count);
-+
-+ PRINTKD( "write fifo: count=%d UDCCS0=%x UDCCS0=%x\n", count, udccs0, UDCCS0);
-+ }
-+ }
-+ /* something goes poopy if I dont wait here ... */
-+ udelay(500);
-+
-+ PRINTKD( "write fifo: bytes sent=%d, bytes left=%d\n", bytes_written, wr.bytes_left);
-+}
-+
-+/*
-+ * read_fifo()
-+ * Read bytes out of FIFO and put in request.
-+ * Called to do the initial read of setup requests
-+ * from the host. Return number of bytes read.
-+ *
-+ */
-+static int read_fifo( usb_dev_request_t * request )
-+{
-+ int bytes_read = 0;
-+ unsigned char * pOut = (unsigned char*) request;
-+
-+ int udccs0 = UDCCS0;
-+
-+ if( (udccs0 & SETUP_READY) == SETUP_READY)
-+ {
-+ /* ok it's a setup command */
-+ while( UDCCS0 & UDCCS0_RNE)
-+ {
-+ if( bytes_read >= sizeof( usb_dev_request_t))
-+ {
-+ /* We've already read enought o fill usb_dev_request_t.
-+ * Our tummy is full. Go barf...
-+ */
-+ printk( "%sread_fifo(): read failure\n", pszMe );
-+ usbd_info.stats.ep0_fifo_read_failures++;
-+ break;
-+ }
-+
-+ *pOut++ = UDDR0;
-+ bytes_read++;
-+ }
-+ }
-+ PRINTKD( "read_fifo %d bytes\n", bytes_read );
-+
-+ /* clear SA & OPR */
-+ UDCCS0 = SETUP_READY;
-+
-+ usbd_info.stats.ep0_bytes_read += bytes_read;
-+ return bytes_read;
-+}
-+
-+/*
-+ * get_descriptor()
-+ * Called from sh_setup_begin to handle data return
-+ * for a GET_DESCRIPTOR setup request.
-+ */
-+static void get_descriptor( usb_dev_request_t * pReq )
-+{
-+ string_desc_t * pString;
-+ ep_desc_t * pEndpoint = 0;
-+
-+ desc_t * pDesc = pxa_usb_get_descriptor_ptr();
-+ int type = pReq->wValue >> 8;
-+ int idx = pReq->wValue & 0xFF;
-+
-+// PRINTKD( "%sget_descriptor for %d\n", pszMe, type );
-+ switch( type ) {
-+ case USB_DESC_DEVICE:
-+ queue_and_start_write( &pDesc->dev,
-+ pReq->wLength,
-+ pDesc->dev.bLength );
-+ break;
-+
-+ // return config descriptor buffer, cfg, intf, 2 ep
-+ case USB_DESC_CONFIG:
-+ queue_and_start_write( &pDesc->b,
-+ pReq->wLength,
-+ sizeof( struct cdb ) );
-+ break;
-+
-+ // not quite right, since doesn't do language code checking
-+ case USB_DESC_STRING:
-+ pString = pxa_usb_get_string_descriptor( idx );
-+ if ( pString ) {
-+ if ( idx != 0 ) { // if not language index
-+ printk( "%sReturn string %d: ", pszMe, idx );
-+ psdesc( pString );
-+ }
-+ queue_and_start_write( pString,
-+ pReq->wLength,
-+ pString->bLength );
-+ }
-+ else {
-+ printk("%sunkown string index %d Stall.\n", pszMe, idx );
-+ }
-+ break;
-+
-+ case USB_DESC_INTERFACE:
-+ if ( idx == pDesc->b.intf.bInterfaceNumber ) {
-+ queue_and_start_write( &pDesc->b.intf,
-+ pReq->wLength,
-+ pDesc->b.intf.bLength );
-+ }
-+ break;
-+
-+ case USB_DESC_ENDPOINT: /* correct? 21Feb01ww */
-+ if ( idx == 1 )
-+ pEndpoint = &pDesc->b.ep1; //[BULK_IN1];
-+ else if ( idx == 2 )
-+ pEndpoint = &pDesc->b.ep2; //[BULK_OUT1];
-+ else
-+ pEndpoint = NULL;
-+ if ( pEndpoint ) {
-+ queue_and_start_write( pEndpoint,
-+ pReq->wLength,
-+ pEndpoint->bLength );
-+ } else {
-+ printk("%sunkown endpoint index %d Stall.\n", pszMe, idx );
-+ }
-+ break;
-+
-+
-+ default :
-+ printk("%sunknown descriptor type %d. Stall.\n", pszMe, type );
-+ break;
-+
-+ }
-+}
-+
-+/* end usb_ep0.c - who needs this comment? */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/usb_ep0.h 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,66 @@
-+/*
-+ * Copyright (C) Intrinsyc, Inc., 2002
-+ *
-+ * usb_ep0.h - PXA USB controller driver.
-+ * Endpoint zero management
-+ *
-+ * Please see:
-+ * linux/Documentation/arm/SA1100/SA1100_USB
-+ * for details.
-+ *
-+ * 02-May-2002
-+ * Frank Becker (Intrinsyc) -
-+ *
-+ */
-+
-+#ifndef __USB_EP0_H
-+#define __USB_EP0_H
-+
-+#define EP0_FIFO_SIZE 16
-+#define SETUP_READY (UDCCS0_SA | UDCCS0_OPR)
-+
-+/*================================================
-+ * USB Protocol Stuff
-+ */
-+
-+/* Request Codes */
-+enum {
-+ GET_STATUS =0,
-+ CLEAR_FEATURE =1,
-+ /* reserved =2 */
-+ SET_FEATURE =3,
-+ /* reserved =4 */
-+ SET_ADDRESS =5,
-+ GET_DESCRIPTOR =6,
-+ SET_DESCRIPTOR =7,
-+ GET_CONFIGURATION =8,
-+ SET_CONFIGURATION =9,
-+ GET_INTERFACE =10,
-+ SET_INTERFACE =11,
-+ SYNCH_FRAME =12
-+};
-+
-+typedef enum {
-+ EP0_IDLE,
-+ EP0_IN_DATA_PHASE,
-+ EP0_END_XFER,
-+ EP0_OUT_DATA_PHASE
-+} EP0_state;
-+
-+/* USB Device Requests */
-+typedef struct
-+{
-+ __u8 bmRequestType;
-+ __u8 bRequest;
-+ __u16 wValue;
-+ __u16 wIndex;
-+ __u16 wLength;
-+} usb_dev_request_t __attribute__ ((packed));
-+
-+/* Data extraction from usb_request_t fields */
-+enum {
-+ kTargetDevice =0,
-+ kTargetInterface=1,
-+ kTargetEndpoint =2
-+};
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/usb_recv.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,173 @@
-+/*
-+ * Generic receive layer for the PXA USB client function
-+ *
-+ * This code was loosely inspired by the original version which was
-+ * Copyright (c) Compaq Computer Corporation, 1998-1999
-+ * Copyright (c) 2001 by Nicolas Pitre
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 02-May-2002
-+ * Frank Becker (Intrinsyc) - derived from sa1100 usb_recv.c
-+ *
-+ * TODO: Add support for DMA.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+#include <linux/errno.h>
-+#include <asm/dma.h>
-+#include <asm/system.h>
-+
-+#include "pxa_usb.h"
-+#include "usb_ctl.h"
-+
-+#if DEBUG
-+static unsigned int usb_debug = DEBUG;
-+#else
-+#define usb_debug 0 /* gcc will remove all the debug code for us */
-+#endif
-+
-+static char *ep_bulk_out1_buf;
-+static int ep_bulk_out1_len;
-+static int ep_bulk_out1_remain;
-+static usb_callback_t ep_bulk_out1_callback;
-+static int rx_pktsize;
-+
-+static void
-+ep_bulk_out1_start(void)
-+{
-+ /* disable DMA */
-+ UDCCS2 &= ~UDCCS_BO_DME;
-+
-+ /* enable interrupts for endpoint 2 (bulk out) */
-+ UICR0 &= ~UICR0_IM2;
-+}
-+
-+static void
-+ep_bulk_out1_done(int flag)
-+{
-+ int size = ep_bulk_out1_len - ep_bulk_out1_remain;
-+
-+ if (!ep_bulk_out1_len)
-+ return;
-+
-+ ep_bulk_out1_len = 0;
-+ if (ep_bulk_out1_callback) {
-+ ep_bulk_out1_callback(flag, size);
-+ }
-+}
-+
-+void
-+ep_bulk_out1_state_change_notify( int new_state )
-+{
-+}
-+
-+void
-+ep_bulk_out1_stall( void )
-+{
-+ /* SET_FEATURE force stall at UDC */
-+ UDCCS2 |= UDCCS_BO_FST;
-+}
-+
-+int
-+ep_bulk_out1_init(int chn)
-+{
-+ desc_t * pd = pxa_usb_get_descriptor_ptr();
-+ rx_pktsize = __le16_to_cpu( pd->b.ep1.wMaxPacketSize );
-+ ep_bulk_out1_done(-EAGAIN);
-+ return 0;
-+}
-+
-+void
-+ep_bulk_out1_reset(void)
-+{
-+ desc_t * pd = pxa_usb_get_descriptor_ptr();
-+ rx_pktsize = __le16_to_cpu( pd->b.ep1.wMaxPacketSize );
-+ UDCCS2 &= ~UDCCS_BO_FST;
-+ ep_bulk_out1_done(-EINTR);
-+}
-+
-+void
-+ep_bulk_out1_int_hndlr(int udcsr)
-+{
-+ int status = UDCCS2;
-+ if( usb_debug) printk("ep_bulk_out1_int_hndlr: UDCCS2=%x\n", status);
-+
-+ if( (status & (UDCCS_BO_RNE | UDCCS_BO_RSP)) == UDCCS_BO_RSP)
-+ {
-+ /* zero-length packet */
-+ }
-+
-+ if( status & UDCCS_BO_RNE)
-+ {
-+ int len;
-+ int i;
-+ char *buf = ep_bulk_out1_buf + ep_bulk_out1_len - ep_bulk_out1_remain;
-+
-+ /* bytes in FIFO */
-+ len = (UBCR2 & 0xff) +1;
-+
-+ if( usb_debug) printk("usb_recv: "
-+ "len=%d out1_len=%d out1_remain=%d\n",
-+ len,ep_bulk_out1_len,ep_bulk_out1_remain);
-+
-+ if( len > ep_bulk_out1_remain)
-+ {
-+ /* FIXME: if this happens, we need a temporary overflow buffer */
-+ printk("usb_recv: Buffer overwrite warning...\n");
-+ len = ep_bulk_out1_remain;
-+ }
-+
-+ /* read data out of fifo */
-+ for( i=0; i<len; i++)
-+ {
-+ *buf++ = UDDR2 & 0xff;
-+ }
-+
-+ ep_bulk_out1_remain -= len;
-+ ep_bulk_out1_done((len) ? 0 : -EPIPE);
-+ }
-+
-+ /* ack RPC - FIXME: '|=' we may ack SST here, too */
-+ UDCCS2 |= UDCCS_BO_RPC;
-+ return;
-+}
-+
-+int
-+pxa_usb_recv(char *buf, int len, usb_callback_t callback)
-+{
-+ int flags;
-+
-+ if (ep_bulk_out1_len)
-+ return -EBUSY;
-+
-+ local_irq_save(flags);
-+ ep_bulk_out1_buf = buf;
-+ ep_bulk_out1_len = len;
-+ ep_bulk_out1_callback = callback;
-+ ep_bulk_out1_remain = len;
-+ ep_bulk_out1_start();
-+ local_irq_restore(flags);
-+
-+ return 0;
-+}
-+
-+void
-+pxa_usb_recv_reset(void)
-+{
-+ ep_bulk_out1_reset();
-+}
-+
-+void
-+pxa_usb_recv_stall(void)
-+{
-+ ep_bulk_out1_stall();
-+}
-+
-+EXPORT_SYMBOL(pxa_usb_recv_stall);
-+EXPORT_SYMBOL(pxa_usb_recv);
-+EXPORT_SYMBOL(pxa_usb_recv_reset);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-pxa/usb_send.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,190 @@
-+/*
-+ * Generic xmit layer for the PXA USB client function
-+ *
-+ * This code was loosely inspired by the original version which was
-+ * Copyright (c) Compaq Computer Corporation, 1998-1999
-+ * Copyright (c) 2001 by Nicolas Pitre
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 02-May-2002
-+ * Frank Becker (Intrinsyc) - derived from sa1100 usb_send.c
-+ *
-+ * TODO: Add support for DMA.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+#include <linux/errno.h>
-+#include <asm/hardware.h>
-+#include <asm/dma.h>
-+#include <asm/system.h>
-+#include <asm/byteorder.h>
-+
-+#include "pxa_usb.h"
-+#include "usb_ctl.h"
-+
-+#if DEBUG
-+static unsigned int usb_debug = DEBUG;
-+#else
-+#define usb_debug 0 /* gcc will remove all the debug code for us */
-+#endif
-+
-+static char *ep_bulk_in1_buf;
-+static int ep_bulk_in1_len;
-+static int ep_bulk_in1_remain;
-+static usb_callback_t ep_bulk_in1_callback;
-+static int tx_pktsize;
-+
-+/* device state is changing, async */
-+void
-+ep_bulk_in1_state_change_notify( int new_state )
-+{
-+}
-+
-+/* set feature stall executing, async */
-+void
-+ep_bulk_in1_stall( void )
-+{
-+ UDCCS1 |= UDCCS_BI_FST;
-+}
-+
-+static void
-+ep_bulk_in1_send_packet(void)
-+{
-+ int i;
-+ char *buf = ep_bulk_in1_buf + ep_bulk_in1_len - ep_bulk_in1_remain;
-+ int out_size = tx_pktsize;
-+
-+ if( usb_debug) printk( "ep_bulk_in1_send_packet: UICR0=%x UDCCS1=%x\n", UICR0, UDCCS1);
-+
-+ if( out_size > ep_bulk_in1_remain)
-+ {
-+ out_size = ep_bulk_in1_remain;
-+ }
-+
-+ for( i=0; i<out_size; i++)
-+ {
-+ UDDR1 = *buf++;
-+ }
-+
-+ UDCCS1 = UDCCS_BI_TPC;
-+ if( out_size < tx_pktsize)
-+ {
-+ /* short packet */
-+ UDCCS1 = UDCCS_BI_TSP;
-+ }
-+ ep_bulk_in1_remain -= out_size;
-+
-+ if( usb_debug) printk( "ep_bulk_in1_send_packet: "
-+ "UICR0=%x UDCCS1=%x send bytes=%d left=%d\n",
-+ UICR0, UDCCS1, out_size, ep_bulk_in1_remain);
-+}
-+
-+static void
-+ep_bulk_in1_start(void)
-+{
-+ if (!ep_bulk_in1_len)
-+ return;
-+
-+ UICR0 &= ~UICR0_IM1;
-+
-+ ep_bulk_in1_send_packet();
-+}
-+
-+static void
-+ep_bulk_in1_done(int flag)
-+{
-+ int size = ep_bulk_in1_len - ep_bulk_in1_remain;
-+ if (ep_bulk_in1_len) {
-+ ep_bulk_in1_len = 0;
-+ if (ep_bulk_in1_callback)
-+ ep_bulk_in1_callback(flag, size);
-+ }
-+}
-+
-+int
-+ep_bulk_in1_init(int chn)
-+{
-+ desc_t * pd = pxa_usb_get_descriptor_ptr();
-+ tx_pktsize = __le16_to_cpu( pd->b.ep2.wMaxPacketSize );
-+ ep_bulk_in1_done(-EAGAIN);
-+ return 0;
-+}
-+
-+void
-+ep_bulk_in1_reset(void)
-+{
-+ desc_t * pd = pxa_usb_get_descriptor_ptr();
-+ tx_pktsize = __le16_to_cpu( pd->b.ep2.wMaxPacketSize );
-+ UDCCS1 &= ~UDCCS_BI_FST;
-+ ep_bulk_in1_done(-EINTR);
-+}
-+
-+void
-+ep_bulk_in1_int_hndlr(int usir0)
-+{
-+ int status = UDCCS1;
-+
-+ if (ep_bulk_in1_remain != 0) {
-+ /* more data to go */
-+ ep_bulk_in1_start();
-+ } else {
-+ if( status & UDCCS_BI_TPC)
-+ {
-+ UDCCS1 = UDCCS_BI_TPC;
-+ }
-+ ep_bulk_in1_done(0);
-+ }
-+}
-+
-+int
-+pxa_usb_send(char *buf, int len, usb_callback_t callback)
-+{
-+ int flags;
-+
-+ if( usb_debug) printk( "pxa_usb_send: "
-+ "data len=%d state=%d blen=%d\n",
-+ len, usbd_info.state, ep_bulk_in1_len);
-+
-+ if (usbd_info.state != USB_STATE_CONFIGURED)
-+ return -ENODEV;
-+
-+ if (ep_bulk_in1_len)
-+ return -EBUSY;
-+
-+ local_irq_save(flags);
-+ ep_bulk_in1_buf = buf;
-+ ep_bulk_in1_len = len;
-+ ep_bulk_in1_callback = callback;
-+ ep_bulk_in1_remain = len;
-+ ep_bulk_in1_start();
-+ local_irq_restore(flags);
-+
-+ return 0;
-+}
-+
-+
-+void
-+pxa_usb_send_reset(void)
-+{
-+ ep_bulk_in1_reset();
-+}
-+
-+int
-+pxa_usb_xmitter_avail( void )
-+{
-+ if (usbd_info.state != USB_STATE_CONFIGURED)
-+ return -ENODEV;
-+ if (ep_bulk_in1_len)
-+ return -EBUSY;
-+ return 0;
-+}
-+
-+
-+EXPORT_SYMBOL(pxa_usb_xmitter_avail);
-+EXPORT_SYMBOL(pxa_usb_send);
-+EXPORT_SYMBOL(pxa_usb_send_reset);
---- linux-2.4.25/arch/arm/mach-sa1100/sa1111-ohci.c~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/sa1111-ohci.c 2004-03-31 17:15:11.000000000 +0200
-@@ -54,7 +54,7 @@
- * address as its return value, and the DMA address via
- * the dma_addr_t pointer.
- */
-- vbuf = consistent_alloc(GFP_KERNEL | GFP_DMA, 4, &dma_buf);
-+ vbuf = consistent_alloc(GFP_KERNEL | GFP_DMA, 4, &dma_buf, 0);
-
- SADTSA = (unsigned long)dma_buf;
- SADTCA = 4;
---- linux-2.4.25/arch/arm/mach-sa1100/sa1111.c~2.4.25-vrs2-pxa1.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/sa1111.c 2004-03-31 17:15:11.000000000 +0200
-@@ -243,9 +243,15 @@
- * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
- * (SA-1110 Developer's Manual, section 9.1.2.1)
- */
-+#if CONFIG_ARCH_SA1100
- GAFR |= GPIO_32_768kHz;
- GPDR |= GPIO_32_768kHz;
- TUCR = TUCR_3_6864MHz;
-+#elif CONFIG_ARCH_PXA
-+ set_GPIO_mode(GPIO11_3_6MHz_MD);
-+#else
-+#error missing clock setup
-+#endif
-
- /*
- * Turn VCO on, and disable PLL Bypass.
-@@ -300,6 +306,8 @@
- SBI_SMCR = smcr;
- }
-
-+#ifdef CONFIG_ARCH_SA1100
-+
- /*
- * Disable the memory bus request/grant signals on the SA1110 to
- * ensure that we don't receive spurious memory requests. We set
-@@ -341,5 +349,7 @@
- local_irq_restore(flags);
- }
-
-+#endif
-+
- EXPORT_SYMBOL(sa1111_wake);
- EXPORT_SYMBOL(sa1111_doze);
---- linux-2.4.25/arch/arm/mm/Makefile~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/Makefile 2004-03-31 17:15:11.000000000 +0200
-@@ -44,6 +44,7 @@
- p-$(CONFIG_CPU_ARM1026) += proc-arm1026.o
- p-$(CONFIG_CPU_SA110) += proc-sa110.o
- p-$(CONFIG_CPU_SA1100) += proc-sa110.o
-+p-$(CONFIG_CPU_XSCALE) += proc-xscale.o
-
- # Integrator follows "new style"
- # Soon, others will do too, and we can get rid of this
---- linux-2.4.25/arch/arm/mm/consistent.c~2.4.25-vrs2-pxa1.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/consistent.c 2004-03-31 17:15:11.000000000 +0200
-@@ -37,7 +37,8 @@
- *
- * Note that this does *not* zero the allocated area!
- */
--void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
-+void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle,
-+ unsigned long cache_flags)
- {
- struct page *page, *end, *free;
- unsigned long order;
-@@ -55,7 +56,7 @@
- goto no_page;
-
- *dma_handle = page_to_bus(page);
-- ret = __ioremap(page_to_pfn(page) << PAGE_SHIFT, size, 0);
-+ ret = __ioremap(page_to_pfn(page) << PAGE_SHIFT, size, cache_flags);
- if (!ret)
- goto no_remap;
-
-@@ -106,7 +107,7 @@
- #endif
- gfp |= GFP_DMA;
-
-- return consistent_alloc(gfp, size, handle);
-+ return consistent_alloc(gfp, size, handle, 0);
- }
-
- /*
---- linux-2.4.25/arch/arm/mm/init.c~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/init.c 2004-03-31 17:15:11.000000000 +0200
-@@ -49,6 +49,9 @@
- static unsigned long totalram_pages;
- extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
- extern char _stext, _text, _etext, _end, __init_begin, __init_end;
-+#ifdef CONFIG_XIP_KERNEL
-+extern char _endtext, _sdata;
-+#endif
- extern unsigned long phys_initrd_start;
- extern unsigned long phys_initrd_size;
-
-@@ -347,7 +350,11 @@
- * Register the kernel text and data with bootmem.
- * Note that this can only be in node 0.
- */
-+#ifdef CONFIG_XIP_KERNEL
-+ reserve_bootmem_node(pgdat, __pa(&_sdata), &_end - &_sdata);
-+#else
- reserve_bootmem_node(pgdat, __pa(&_stext), &_end - &_stext);
-+#endif
-
- #ifdef CONFIG_CPU_32
- /*
-@@ -601,8 +608,13 @@
- unsigned int codepages, datapages, initpages;
- int i, node;
-
-+#ifndef CONFIG_XIP_KERNEL
- codepages = &_etext - &_text;
- datapages = &_end - &_etext;
-+#else
-+ codepages = &_endtext - &_text;
-+ datapages = &_end - &_sdata;
-+#endif
- initpages = &__init_end - &__init_begin;
-
- high_memory = (void *)__va(meminfo.end);
-@@ -658,11 +670,13 @@
-
- void free_initmem(void)
- {
-+#ifndef CONFIG_XIP_KERNEL
- if (!machine_is_integrator()) {
- free_area((unsigned long)(&__init_begin),
- (unsigned long)(&__init_end),
- "init");
- }
-+#endif
- }
-
- #ifdef CONFIG_BLK_DEV_INITRD
---- linux-2.4.25/arch/arm/mm/mm-armv.c~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/mm-armv.c 2004-03-31 17:15:11.000000000 +0200
-@@ -356,6 +356,19 @@
- p ++;
- #endif
-
-+#ifdef CONFIG_XIP_KERNEL
-+ p->physical = KERNEL_XIP_BASE_PHYS;
-+ p->virtual = KERNEL_XIP_BASE_VIRT;
-+ p->length = PGDIR_SIZE * 8;
-+ p->domain = DOMAIN_KERNEL;
-+ p->prot_read = 0; /* r=0, b=0 --> read-only for kernel mode */
-+ p->prot_write = 0;
-+ p->cacheable = 1;
-+ p->bufferable = 1;
-+
-+ p ++;
-+#endif
-+
- /*
- * Go through the initial mappings, but clear out any
- * pgdir entries that are not in the description.
-@@ -386,7 +399,7 @@
- init_maps->prot_read = 0;
- init_maps->prot_write = 0;
- init_maps->cacheable = 1;
-- init_maps->bufferable = 0;
-+ init_maps->bufferable = 1;
-
- create_mapping(init_maps);
-
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/proc-xscale.S 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,1086 @@
-+/*
-+ * linux/arch/arm/mm/proc-xscale.S
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: November 2000
-+ * Copyright: (C) 2000, 2001 MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * MMU functions for the Intel XScale CPUs
-+ *
-+ * 2001 Aug 21:
-+ * some contributions by Brett Gaines <brett.w.gaines@intel.com>
-+ * Copyright 2001 by Intel Corp.
-+ *
-+ * 2001 Sep 08:
-+ * Completely revisited, many important fixes
-+ * Nicolas Pitre <nico@cam.org>
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/linkage.h>
-+#include <asm/assembler.h>
-+#include <asm/constants.h>
-+#include <asm/procinfo.h>
-+#include <asm/hardware.h>
-+#include <asm/proc/pgtable.h>
-+
-+/*
-+ * Some knobs for cache allocation policy.
-+ * Allocate on write may or may not be beneficial depending on the memory
-+ * usage pattern of your main application. Write through cache is definitely
-+ * a performance loss in most cases, but might be used for special purposes.
-+ */
-+#define PMD_CACHE_WRITE_ALLOCATE 1
-+#define PTE_CACHE_WRITE_ALLOCATE 1
-+#define CACHE_WRITE_THROUGH 0
-+
-+/*
-+ * There are errata that say that dirty status bits in the cache may get
-+ * corrupted. The workaround significantly affects performance, and the bug
-+ * _might_ just not be that visible or critical to you, so it is configurable.
-+ * Let's hope a future core revision will tell us this was only a bad dream.
-+ * But in the mean time the risk and tradeoff is yours to decide....
-+ */
-+#ifdef CONFIG_XSCALE_CACHE_ERRATA
-+#undef CACHE_WRITE_THROUGH
-+#define CACHE_WRITE_THROUGH 1
-+#endif
-+
-+/*
-+ * This is the maximum size of an area which will be flushed. If the area
-+ * is larger than this, then we flush the whole cache
-+ */
-+#define MAX_AREA_SIZE 32768
-+
-+/*
-+ * the cache line size of the I and D cache
-+ */
-+#define CACHELINESIZE 32
-+
-+/*
-+ * the size of the data cache
-+ */
-+#define CACHESIZE 32768
-+
-+/*
-+ * and the page size
-+ */
-+#define PAGESIZE 4096
-+
-+/*
-+ * Virtual address used to allocate the cache when flushed
-+ *
-+ * This must be an address range which is _never_ used. It should
-+ * apparently have a mapping in the corresponding page table for
-+ * compatibility with future CPUs that _could_ require it. For instance we
-+ * don't care.
-+ *
-+ * This must be aligned on a 2*CACHESIZE boundary. The code selects one of
-+ * the 2 areas in alternance each time the clean_d_cache macro is used.
-+ * Without this the XScale core exhibits cache eviction problems and no one
-+ * knows why.
-+ *
-+ * Reminder: the vector table is located at 0xffff0000-0xffff0fff.
-+ */
-+#define CLEAN_ADDR 0xfffe0000
-+
-+/*
-+ * This macro is used to wait for a CP15 write and is needed
-+ * when we have to ensure that the last operation to the co-pro
-+ * was completed before continuing with operation.
-+ */
-+ .macro cpwait, rd
-+ mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15
-+ mov \rd, \rd @ wait for completion
-+ sub pc, pc, #4 @ flush instruction pipeline
-+ .endm
-+
-+ .macro cpwait_ret, lr, rd
-+ mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15
-+ sub pc, \lr, \rd, LSR #32 @ wait for completion and
-+ @ flush instruction pipeline
-+ .endm
-+
-+#if !CACHE_WRITE_THROUGH
-+
-+/*
-+ * This macro cleans the entire dcache using line allocate.
-+ * The main loop has been unrolled to reduce loop overhead.
-+ * rd and rs are two scratch registers.
-+ */
-+ .macro clean_d_cache, rd, rs
-+ ldr \rs, =clean_addr
-+ ldr \rd, [\rs]
-+ eor \rd, \rd, #CACHESIZE
-+ str \rd, [\rs]
-+ add \rs, \rd, #CACHESIZE
-+1: mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line
-+ add \rd, \rd, #CACHELINESIZE
-+ mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line
-+ add \rd, \rd, #CACHELINESIZE
-+ mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line
-+ add \rd, \rd, #CACHELINESIZE
-+ mcr p15, 0, \rd, c7, c2, 5 @ allocate D cache line
-+ add \rd, \rd, #CACHELINESIZE
-+ teq \rd, \rs
-+ bne 1b
-+ .endm
-+
-+ .macro clean_d_line, rd
-+ mcr p15, 0, \rd, c7, c10, 1
-+ .endm
-+
-+ .data
-+clean_addr: .word CLEAN_ADDR
-+
-+#else
-+
-+/*
-+ * If cache is write-through, there is no need to clean it.
-+ * Simply invalidating will do.
-+ */
-+
-+ .macro clean_d_cache, rd, rs
-+ mcr p15, 0, \rd, c7, c6, 0
-+ .endm
-+
-+ /* let's try to skip this needless operations at least within loops */
-+ .macro clean_d_line, rd
-+ .endm
-+
-+#endif
-+
-+ .text
-+
-+/*
-+ * cpu_xscale_data_abort()
-+ *
-+ * obtain information about current aborted instruction.
-+ * Note: we read user space. This means we might cause a data
-+ * abort here if the I-TLB and D-TLB aren't seeing the same
-+ * picture. Unfortunately, this does happen. We live with it.
-+ *
-+ * r2 = address of aborted instruction
-+ * r3 = saved SPSR
-+ *
-+ * Returns:
-+ * r0 = address of abort
-+ * r1 = FSR, bit 11 = write
-+ * r3 = corrupted
-+ */
-+ .align 5
-+ENTRY(cpu_xscale_data_abort)
-+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
-+ mrc p15, 0, r0, c6, c0, 0 @ get FAR
-+ ldr r3, [r2] @ read aborted instruction
-+ bic r1, r1, #1 << 11 @ clear bits 11 of FSR
-+ tst r3, #1 << 20 @ check write
-+ orreq r1, r1, #1 << 11
-+ mov pc, lr
-+
-+/*
-+ * cpu_xscale_check_bugs()
-+ */
-+ENTRY(cpu_xscale_check_bugs)
-+ mrs ip, cpsr
-+ bic ip, ip, #F_BIT
-+ msr cpsr, ip
-+ mov pc, lr
-+
-+#ifndef CONFIG_XSCALE_CACHE_ERRATA
-+/*
-+ * cpu_xscale_proc_init()
-+ *
-+ * Nothing too exciting at the moment
-+ */
-+ENTRY(cpu_xscale_proc_init)
-+ mov pc, lr
-+#else
-+/*
-+ * We enable the cache here, but we make sure all the status bits for dirty
-+ * lines are cleared as well (see PXA250 erratum #120).
-+ */
-+ENTRY(cpu_xscale_proc_init)
-+ @ enable data cache
-+ ldr r0, cr_p
-+ ldmia r0, {r1, r2}
-+ orr r1, r1, #0x4
-+ orr r2, r2, #0x4
-+ stmia r0, {r1, r2}
-+ mcr p15, 0, r1, c1, c0, 0
-+ cpwait r0
-+
-+ @ invalidate data cache
-+ mcr p15, 0, r0, c7, c6, 0
-+
-+ @ fill main cache with write-through lines
-+ bic r0, pc, #0x1f
-+ add r1, r0, #CACHESIZE
-+1: ldr r2, [r0], #32
-+ cmp r0, r1
-+ bne 1b
-+
-+ @ enable test feature to force all fills to the mini-cache
-+ mov r1, #0x8
-+ mcr p15, 0, r1, c15, c15, 3
-+
-+ @ fill mini-cache with write-through lines (2kbytes, 64 lines)
-+ add r1, r0, #2048
-+2: ldr r2, [r0], #32
-+ cmp r0, r1
-+ bne 2b
-+
-+ @ disable test feature to force all fills to the mini-cache
-+ mov r1, #0x0
-+ mcr p15, 0, r1, c15, c15, 3
-+
-+ @ invalidate data cache again
-+ mcr p15, 0, r1, c7, c6, 0
-+ mov pc, lr
-+
-+cr_p: .long SYMBOL_NAME(cr_alignment)
-+#endif
-+
-+/*
-+ * cpu_xscale_proc_fin()
-+ */
-+ENTRY(cpu_xscale_proc_fin)
-+ str lr, [sp, #-4]!
-+ mov r0, #F_BIT|I_BIT|SVC_MODE
-+ msr cpsr_c, r0
-+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
-+ bic r0, r0, #0x1800 @ ...IZ...........
-+ bic r0, r0, #0x0006 @ .............CA.
-+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
-+ bl cpu_xscale_cache_clean_invalidate_all @ clean caches
-+ ldr pc, [sp], #4
-+
-+/*
-+ * cpu_xscale_reset(loc)
-+ *
-+ * Perform a soft reset of the system. Put the CPU into the
-+ * same state as it would be if it had been reset, and branch
-+ * to what would be the reset vector.
-+ *
-+ * loc: location to jump to for soft reset
-+ */
-+ .align 5
-+ENTRY(cpu_xscale_reset)
-+ mov r1, #F_BIT|I_BIT|SVC_MODE
-+ msr cpsr_c, r1 @ reset CPSR
-+ mrc p15, 0, r1, c1, c0, 0 @ ctrl register
-+ bic r1, r1, #0x0086 @ ........B....CA.
-+ bic r1, r1, #0x1900 @ ...IZ..S........
-+ mcr p15, 0, r1, c1, c0, 0 @ ctrl register
-+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches & BTB
-+ bic r1, r1, #0x0001 @ ...............M
-+ mcr p15, 0, r1, c1, c0, 0 @ ctrl register
-+ @ CAUTION: MMU turned off from this point. We count on the pipeline
-+ @ already containing those two last instructions to survive.
-+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
-+ mov pc, r0
-+
-+/*
-+ * cpu_xscale_do_idle(type)
-+ *
-+ * Cause the processor to idle
-+ *
-+ * type:
-+ * 0 = slow idle
-+ * 1 = fast idle
-+ * 2 = switch to slow processor clock
-+ * 3 = switch to fast processor clock
-+ *
-+ * For now we do nothing but go to idle mode for every case
-+ *
-+ * XScale supports clock switching, but using idle mode support
-+ * allows external hardware to react to system state changes.
-+ */
-+ .align 5
-+
-+ENTRY(cpu_xscale_do_idle)
-+ mov r0, #1
-+ mcr p14, 0, r0, c7, c0, 0 @ Go to IDLE
-+ mov pc, lr
-+
-+/* ================================= CACHE ================================ */
-+
-+/*
-+ * cpu_xscale_cache_clean_invalidate_all (void)
-+ *
-+ * clean and invalidate all cache lines
-+ *
-+ * Note:
-+ * 1. We should preserve r0 at all times.
-+ * 2. Even if this function implies cache "invalidation" by its name,
-+ * we don't need to actually use explicit invalidation operations
-+ * since the goal is to discard all valid references from the cache
-+ * and the cleaning of it already has that effect.
-+ * 3. Because of 2 above and the fact that kernel space memory is always
-+ * coherent across task switches there is no need to worry about
-+ * inconsistencies due to interrupts, ence no irq disabling.
-+ */
-+ .align 5
-+ENTRY(cpu_xscale_cache_clean_invalidate_all)
-+ mov r2, #1
-+cpu_xscale_cache_clean_invalidate_all_r2:
-+ clean_d_cache r0, r1
-+ teq r2, #0
-+ mcrne p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ mov pc, lr
-+
-+/*
-+ * cpu_xscale_cache_clean_invalidate_range(start, end, flags)
-+ *
-+ * clean and invalidate all cache lines associated with this area of memory
-+ *
-+ * start: Area start address
-+ * end: Area end address
-+ * flags: nonzero for I cache as well
-+ */
-+ .align 5
-+ENTRY(cpu_xscale_cache_clean_invalidate_range)
-+ bic r0, r0, #CACHELINESIZE - 1 @ round down to cache line
-+ sub r3, r1, r0
-+ cmp r3, #MAX_AREA_SIZE
-+ bhi cpu_xscale_cache_clean_invalidate_all_r2
-+1: clean_d_line r0 @ Clean D cache line
-+ mcr p15, 0, r0, c7, c6, 1 @ Invalidate D cache line
-+ add r0, r0, #CACHELINESIZE
-+ cmp r0, r1
-+ blo 1b
-+ teq r2, #0
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ moveq pc, lr
-+ sub r0, r0, r3
-+1: mcr p15, 0, r0, c7, c5, 1 @ Invalidate I cache line
-+ add r0, r0, #CACHELINESIZE
-+ cmp r0, r1
-+ blo 1b
-+ mcr p15, 0, ip, c7, c5, 6 @ Invalidate BTB
-+ mov pc, lr
-+
-+/*
-+ * cpu_xscale_flush_ram_page(page)
-+ *
-+ * clean all cache lines associated with this memory page
-+ *
-+ * page: page to clean
-+ */
-+ .align 5
-+ENTRY(cpu_xscale_flush_ram_page)
-+#if !CACHE_WRITE_THROUGH
-+ mov r1, #PAGESIZE
-+1: mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
-+ add r0, r0, #CACHELINESIZE
-+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
-+ add r0, r0, #CACHELINESIZE
-+ subs r1, r1, #2 * CACHELINESIZE
-+ bne 1b
-+#endif
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ mov pc, lr
-+
-+/* ================================ D-CACHE =============================== */
-+
-+/*
-+ * cpu_xscale_dcache_invalidate_range(start, end)
-+ *
-+ * throw away all D-cached data in specified region without an obligation
-+ * to write them back. Note however that on XScale we must clean all
-+ * entries also due to hardware errata (80200 A0 & A1 only).
-+ *
-+ * start: virtual start address
-+ * end: virtual end address
-+ */
-+ .align 5
-+ENTRY(cpu_xscale_dcache_invalidate_range)
-+ mrc p15, 0, r2, c0, c0, 0 @ Read part no.
-+ eor r2, r2, #0x69000000
-+ eor r2, r2, #0x00052000 @ 80200 XX part no.
-+ bics r2, r2, #0x1 @ Clear LSB in revision field
-+ moveq r2, #0
-+ beq cpu_xscale_cache_clean_invalidate_range @ An 80200 A0 or A1
-+
-+ tst r0, #CACHELINESIZE - 1
-+ mcrne p15, 0, r0, c7, c10, 1 @ Clean D cache line
-+ tst r1, #CACHELINESIZE - 1
-+ mcrne p15, 0, r1, c7, c10, 1 @ Clean D cache line
-+ bic r0, r0, #CACHELINESIZE - 1 @ round down to cache line
-+1: mcr p15, 0, r0, c7, c6, 1 @ Invalidate D cache line
-+ add r0, r0, #CACHELINESIZE
-+ cmp r0, r1
-+ blo 1b
-+ mov pc, lr
-+
-+/*
-+ * cpu_xscale_dcache_clean_range(start, end)
-+ *
-+ * For the specified virtual address range, ensure that all caches contain
-+ * clean data, such that peripheral accesses to the physical RAM fetch
-+ * correct data.
-+ *
-+ * start: virtual start address
-+ * end: virtual end address
-+ */
-+ .align 5
-+ENTRY(cpu_xscale_dcache_clean_range)
-+#if !CACHE_WRITE_THROUGH
-+ bic r0, r0, #CACHELINESIZE - 1
-+ sub r2, r1, r0
-+ cmp r2, #MAX_AREA_SIZE
-+ movhi r2, #0
-+ bhi cpu_xscale_cache_clean_invalidate_all_r2
-+
-+1: mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
-+ add r0, r0, #CACHELINESIZE
-+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
-+ add r0, r0, #CACHELINESIZE
-+ cmp r0, r1
-+ blo 1b
-+#endif
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ mov pc, lr
-+
-+/*
-+ * cpu_xscale_clean_dcache_page(page)
-+ *
-+ * Cleans a single page of dcache so that if we have any future aliased
-+ * mappings, they will be consistent at the time that they are created.
-+ *
-+ * Note:
-+ * 1. we don't need to flush the write buffer in this case. [really? -Nico]
-+ * 2. we don't invalidate the entries since when we write the page
-+ * out to disk, the entries may get reloaded into the cache.
-+ */
-+ .align 5
-+ENTRY(cpu_xscale_dcache_clean_page)
-+#if !CACHE_WRITE_THROUGH
-+ mov r1, #PAGESIZE
-+1: mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
-+ add r0, r0, #CACHELINESIZE
-+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
-+ add r0, r0, #CACHELINESIZE
-+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
-+ add r0, r0, #CACHELINESIZE
-+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
-+ add r0, r0, #CACHELINESIZE
-+ subs r1, r1, #4 * CACHELINESIZE
-+ bne 1b
-+#endif
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ mov pc, lr
-+
-+/*
-+ * cpu_xscale_dcache_clean_entry(addr)
-+ *
-+ * Clean the specified entry of any caches such that the MMU
-+ * translation fetches will obtain correct data.
-+ *
-+ * addr: cache-unaligned virtual address
-+ */
-+ .align 5
-+ENTRY(cpu_xscale_dcache_clean_entry)
-+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ mov pc, lr
-+
-+/* ================================ I-CACHE =============================== */
-+
-+/*
-+ * cpu_xscale_icache_invalidate_range(start, end)
-+ *
-+ * invalidate a range of virtual addresses from the Icache
-+ *
-+ * start: virtual start address
-+ * end: virtual end address
-+ *
-+ * Note: This is vaguely defined as supposed to bring the dcache and the
-+ * icache in sync by the way this function is used.
-+ */
-+ .align 5
-+ENTRY(cpu_xscale_icache_invalidate_range)
-+ bic r0, r0, #CACHELINESIZE - 1
-+1: clean_d_line r0 @ Clean D cache line
-+ mcr p15, 0, r0, c7, c5, 1 @ Invalidate I cache line
-+ add r0, r0, #CACHELINESIZE
-+ cmp r0, r1
-+ blo 1b
-+ mcr p15, 0, ip, c7, c5, 6 @ Invalidate BTB
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ mov pc, lr
-+
-+/*
-+ * cpu_xscale_icache_invalidate_page(page)
-+ *
-+ * invalidate all Icache lines associated with this area of memory
-+ *
-+ * page: page to invalidate
-+ */
-+ .align 5
-+ENTRY(cpu_xscale_icache_invalidate_page)
-+ mov r1, #PAGESIZE
-+1: mcr p15, 0, r0, c7, c5, 1 @ Invalidate I cache line
-+ add r0, r0, #CACHELINESIZE
-+ mcr p15, 0, r0, c7, c5, 1 @ Invalidate I cache line
-+ add r0, r0, #CACHELINESIZE
-+ mcr p15, 0, r0, c7, c5, 1 @ Invalidate I cache line
-+ add r0, r0, #CACHELINESIZE
-+ mcr p15, 0, r0, c7, c5, 1 @ Invalidate I cache line
-+ add r0, r0, #CACHELINESIZE
-+ subs r1, r1, #4 * CACHELINESIZE
-+ bne 1b
-+ mcr p15, 0, r0, c7, c5, 6 @ Invalidate BTB
-+ mov pc, lr
-+
-+/* ================================ CACHE LOCKING============================
-+ *
-+ * The XScale MicroArchitecture implements support for locking entries into
-+ * the data and instruction cache. The following functions implement the core
-+ * low level instructions needed to accomplish the locking. The developer's
-+ * manual states that the code that performs the locking must be in non-cached
-+ * memory. To accomplish this, the code in xscale-cache-lock.c copies the
-+ * following functions from the cache into a non-cached memory region that
-+ * is allocated through consistent_alloc().
-+ *
-+ */
-+ .align 5
-+/*
-+ * xscale_icache_lock
-+ *
-+ * r0: starting address to lock
-+ * r1: end address to lock
-+ */
-+ENTRY(xscale_icache_lock)
-+
-+iLockLoop:
-+ bic r0, r0, #CACHELINESIZE - 1
-+ mcr p15, 0, r0, c9, c1, 0 @ lock into cache
-+ cmp r0, r1 @ are we done?
-+ add r0, r0, #CACHELINESIZE @ advance to next cache line
-+ bls iLockLoop
-+ mov pc, lr
-+
-+/*
-+ * xscale_icache_unlock
-+ */
-+ENTRY(xscale_icache_unlock)
-+ mcr p15, 0, r0, c9, c1, 1 @ Unlock icache
-+ mov pc, lr
-+
-+/*
-+ * xscale_dcache_lock
-+ *
-+ * r0: starting address to lock
-+ * r1: end address to lock
-+ */
-+ENTRY(xscale_dcache_lock)
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ mov r2, #1
-+ mcr p15, 0, r2, c9, c2, 0 @ Put dcache in lock mode
-+ cpwait ip @ Wait for completion
-+
-+ mrs r2, cpsr
-+ orr r3, r2, #F_BIT | I_BIT
-+dLockLoop:
-+ msr cpsr_c, r3
-+ mcr p15, 0, r0, c7, c10, 1 @ Write back line if it is dirty
-+ mcr p15, 0, r0, c7, c6, 1 @ Flush/invalidate line
-+ msr cpsr_c, r2
-+ ldr ip, [r0], #CACHELINESIZE @ Preload 32 bytes into cache from
-+ @ location [r0]. Post-increment
-+ @ r3 to next cache line
-+ cmp r0, r1 @ Are we done?
-+ bls dLockLoop
-+
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ mov r2, #0
-+ mcr p15, 0, r2, c9, c2, 0 @ Get out of lock mode
-+ cpwait_ret lr, ip
-+
-+/*
-+ * xscale_dcache_unlock
-+ */
-+ENTRY(xscale_dcache_unlock)
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ mcr p15, 0, ip, c9, c2, 1 @ Unlock cache
-+ mov pc, lr
-+
-+/*
-+ * Needed to determine the length of the code that needs to be copied.
-+ */
-+ .align 5
-+ENTRY(xscale_cache_dummy)
-+ mov pc, lr
-+
-+/* ================================== TLB ================================= */
-+
-+/*
-+ * cpu_xscale_tlb_invalidate_all()
-+ *
-+ * Invalidate all TLB entries
-+ */
-+ .align 5
-+ENTRY(cpu_xscale_tlb_invalidate_all)
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
-+ cpwait_ret lr, ip
-+
-+/*
-+ * cpu_xscale_tlb_invalidate_range(start, end)
-+ *
-+ * invalidate TLB entries covering the specified range
-+ *
-+ * start: range start address
-+ * end: range end address
-+ */
-+ .align 5
-+ENTRY(cpu_xscale_tlb_invalidate_range)
-+ bic r0, r0, #(PAGESIZE - 1) & 0x00ff
-+ bic r0, r0, #(PAGESIZE - 1) & 0xff00
-+ sub r3, r1, r0
-+ cmp r3, #256 * PAGESIZE @ arbitrary, should be tuned
-+ bhi cpu_xscale_tlb_invalidate_all
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
-+ mcr p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
-+ add r0, r0, #PAGESIZE
-+ cmp r0, r1
-+ blo 1b
-+ cpwait_ret lr, ip
-+
-+/*
-+ * cpu_xscale_tlb_invalidate_page(page, flags)
-+ *
-+ * invalidate the TLB entries for the specified page.
-+ *
-+ * page: page to invalidate
-+ * flags: non-zero if we include the I TLB
-+ */
-+ .align 5
-+ENTRY(cpu_xscale_tlb_invalidate_page)
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ teq r1, #0
-+ mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
-+ mcrne p15, 0, r3, c8, c5, 1 @ invalidate I TLB entry
-+ cpwait_ret lr, ip
-+
-+/* ================================ TLB LOCKING==============================
-+ *
-+ * The XScale MicroArchitecture implements support for locking entries into
-+ * the Instruction and Data TLBs. The following functions provide the
-+ * low level support for supporting these under Linux. xscale-lock.c
-+ * implements some higher level management code. Most of the following
-+ * is taken straight out of the Developer's Manual.
-+ */
-+
-+/*
-+ * Lock I-TLB entry
-+ *
-+ * r0: Virtual address to translate and lock
-+ */
-+ .align 5
-+ENTRY(xscale_itlb_lock)
-+ mrs r2, cpsr
-+ orr r3, r2, #F_BIT | I_BIT
-+ msr cpsr_c, r3 @ Disable interrupts
-+ mcr p15, 0, r0, c8, c5, 1 @ Invalidate I-TLB entry
-+ mcr p15, 0, r0, c10, c4, 0 @ Translate and lock
-+ msr cpsr_c, r2 @ Restore interrupts
-+ cpwait_ret lr, ip
-+
-+/*
-+ * Lock D-TLB entry
-+ *
-+ * r0: Virtual address to translate and lock
-+ */
-+ .align 5
-+ENTRY(xscale_dtlb_lock)
-+ mrs r2, cpsr
-+ orr r3, r2, #F_BIT | I_BIT
-+ msr cpsr_c, r3 @ Disable interrupts
-+ mcr p15, 0, r0, c8, c6, 1 @ Invalidate D-TLB entry
-+ mcr p15, 0, r0, c10, c8, 0 @ Translate and lock
-+ msr cpsr_c, r2 @ Restore interrupts
-+ cpwait_ret lr, ip
-+
-+/*
-+ * Unlock all I-TLB entries
-+ */
-+ .align 5
-+ENTRY(xscale_itlb_unlock)
-+ mcr p15, 0, ip, c10, c4, 1 @ Unlock I-TLB
-+ mcr p15, 0, ip, c8, c5, 0 @ Invalidate I-TLB
-+ cpwait_ret lr, ip
-+
-+/*
-+ * Unlock all D-TLB entries
-+ */
-+ENTRY(xscale_dtlb_unlock)
-+ mcr p15, 0, ip, c10, c8, 1 @ Unlock D-TBL
-+ mcr p15, 0, ip, c8, c6, 0 @ Invalidate D-TLB
-+ cpwait_ret lr, ip
-+
-+/* =============================== PageTable ============================== */
-+
-+/*
-+ * cpu_xscale_set_pgd(pgd)
-+ *
-+ * Set the translation base pointer to be as described by pgd.
-+ *
-+ * pgd: new page tables
-+ */
-+ .align 5
-+ENTRY(cpu_xscale_set_pgd)
-+ clean_d_cache r1, r2
-+ mcr p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
-+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
-+ cpwait_ret lr, ip
-+
-+/*
-+ * cpu_xscale_set_pmd(pmdp, pmd)
-+ *
-+ * Set a level 1 translation table entry, and clean it out of
-+ * any caches such that the MMUs can load it correctly.
-+ *
-+ * pmdp: pointer to PMD entry
-+ * pmd: PMD value to store
-+ */
-+ .align 5
-+ENTRY(cpu_xscale_set_pmd)
-+#if PMD_CACHE_WRITE_ALLOCATE && !CACHE_WRITE_THROUGH
-+ and r2, r1, #PMD_TYPE_MASK|PMD_SECT_CACHEABLE|PMD_SECT_BUFFERABLE
-+ cmp r2, #PMD_TYPE_SECT|PMD_SECT_CACHEABLE|PMD_SECT_BUFFERABLE
-+ orreq r1, r1, #PMD_SECT_TEX(1)
-+#elif CACHE_WRITE_THROUGH
-+ and r2, r1, #PMD_TYPE_MASK|PMD_SECT_CACHEABLE|PMD_SECT_BUFFERABLE
-+ cmp r2, #PMD_TYPE_SECT|PMD_SECT_CACHEABLE|PMD_SECT_BUFFERABLE
-+ biceq r1, r1, #PMD_SECT_BUFFERABLE
-+#endif
-+ str r1, [r0]
-+ mov ip, #0
-+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ mov pc, lr
-+
-+/*
-+ * cpu_xscale_set_pte(ptep, pte)
-+ *
-+ * Set a PTE and flush it out
-+ *
-+ * Errata 40: must set memory to write-through for user read-only pages.
-+ */
-+ .align 5
-+ENTRY(cpu_xscale_set_pte)
-+ str r1, [r0], #-1024 @ linux version
-+
-+ bic r2, r1, #0xff0
-+ orr r2, r2, #PTE_TYPE_EXT @ extended page
-+
-+ eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
-+
-+ tst r3, #L_PTE_USER | L_PTE_EXEC @ User or Exec?
-+ orrne r2, r2, #PTE_EXT_AP_URO_SRW @ yes -> user r/o, system r/w
-+
-+ tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty?
-+ orreq r2, r2, #PTE_EXT_AP_UNO_SRW @ yes -> user n/a, system r/w
-+ @ combined with user -> user r/w
-+
-+ @
-+ @ Handle the X bit. We want to set this bit for the minicache
-+ @ (U = E = B = W = 0, C = 1) or when write allocate is enabled,
-+ @ and we have a writeable, cacheable region. If we ignore the
-+ @ U and E bits, we can allow user space to use the minicache as
-+ @ well.
-+ @
-+ @ X = C & ~W & ~B
-+ @ | C & W & B & write_allocate
-+ @
-+ eor ip, r1, #L_PTE_CACHEABLE
-+ tst ip, #L_PTE_CACHEABLE | L_PTE_WRITE | L_PTE_BUFFERABLE
-+#if PTE_CACHE_WRITE_ALLOCATE && !CACHE_WRITE_THROUGH
-+ eorne ip, r1, #L_PTE_CACHEABLE | L_PTE_WRITE | L_PTE_BUFFERABLE
-+ tstne ip, #L_PTE_CACHEABLE | L_PTE_WRITE | L_PTE_BUFFERABLE
-+#endif
-+ orreq r2, r2, #PTE_EXT_TEX(1)
-+
-+#if CACHE_WRITE_THROUGH
-+ tst r1, #L_PTE_CACHEABLE
-+ bicne r2, r2, #L_PTE_BUFFERABLE @ clear B only if C is set
-+#else
-+ @
-+ @ Errata 40: The B bit must be cleared for a user read-only
-+ @ cacheable page.
-+ @
-+ @ B = B & ~((U|E) & C & ~W)
-+ @
-+ and ip, r1, #L_PTE_USER | L_PTE_EXEC | L_PTE_WRITE | L_PTE_CACHEABLE
-+ teq ip, #L_PTE_USER | L_PTE_CACHEABLE
-+ teqne ip, #L_PTE_EXEC | L_PTE_CACHEABLE
-+ teqne ip, #L_PTE_USER | L_PTE_EXEC | L_PTE_CACHEABLE
-+ biceq r2, r2, #PTE_BUFFERABLE
-+#endif
-+
-+ tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young?
-+ movne r2, #0 @ no -> fault
-+
-+ str r2, [r0] @ hardware version
-+
-+ @ We try to map 64K page entries when possible.
-+ @ We do that for kernel space only since the usage pattern from
-+ @ the setting of VM area is quite simple. User space is not worth
-+ @ the implied complexity because of ever randomly changing PTEs
-+ @ (page aging, swapout, etc) requiring constant coherency checks.
-+ @ Since PTEs are usually set in increasing order, we test the
-+ @ possibility for a large page only when given the last PTE of a
-+ @ 64K boundary.
-+ tsteq r1, #L_PTE_USER
-+ andeq r1, r0, #(15 << 2)
-+ teqeq r1, #(15 << 2)
-+ beq 1f
-+
-+ mov ip, #0
-+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ mov pc, lr
-+
-+ @ See if we have 16 identical PTEs but with consecutive base addresses
-+1: bic r3, r2, #0x0000f000
-+ mov r1, #0x0000f000
-+2: eor r2, r2, r3
-+ teq r2, r1
-+ bne 4f
-+ subs r1, r1, #0x00001000
-+ ldr r2, [r0, #-4]!
-+ bne 2b
-+ eors r2, r2, r3
-+ bne 4f
-+
-+ @ Now create our LARGE PTE from the current EXT one.
-+ bic r3, r3, #PTE_TYPE_MASK
-+ orr r3, r3, #PTE_TYPE_LARGE
-+ and r2, r3, #0x30 @ EXT_AP --> LARGE_AP0
-+ orr r2, r2, r2, lsl #2 @ add LARGE_AP1
-+ orr r2, r2, r2, lsl #4 @ add LARGE_AP3 + LARGE_AP2
-+ and r1, r3, #0x3c0 @ EXT_TEX
-+ bic r3, r3, #0x3c0
-+ orr r2, r2, r1, lsl #(12 - 6) @ --> LARGE_TEX
-+ orr r2, r2, r3 @ add remaining bits
-+
-+ @ then put it in the pagetable
-+ mov r3, r2
-+3: strd r2, [r0], #8
-+ tst r0, #(15 << 2)
-+ bne 3b
-+
-+ @ Then sync the 2 corresponding cache lines
-+ sub r0, r0, #(16 << 2)
-+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
-+4: orr r0, r0, #(15 << 2)
-+ mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line
-+ mov ip, #0
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ mov pc, lr
-+
-+ .ltorg
-+
-+cpu_manu_name:
-+ .asciz "Intel"
-+
-+cpu_80200_name:
-+ .asciz "XScale-80200"
-+
-+cpu_pxa210_name:
-+ .asciz "XScale-PXA210"
-+
-+cpu_pxa250_name:
-+ .asciz "XScale-PXA250"
-+
-+cpu_pxa255_name:
-+ .asciz "XScale-PXA255"
-+
-+ .align
-+
-+ .section ".text.init", #alloc, #execinstr
-+
-+__xscale_setup:
-+ mov r0, #F_BIT|I_BIT|SVC_MODE
-+ msr cpsr_c, r0
-+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I, D caches & BTB
-+ mcr p15, 0, ip, c7, c10, 4 @ Drain Write (& Fill) Buffer
-+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I, D TLBs
-+ mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
-+ mov r0, #0x1f @ Domains 0, 1 = client
-+ mcr p15, 0, r0, c3, c0, 0 @ load domain access register
-+ mov r0, #1 @ Allow user space to access
-+ mcr p15, 0, r0, c15, c1, 0 @ ... CP 0 only.
-+#if CACHE_WRITE_THROUGH
-+ mov r0, #0x20
-+#else
-+ mov r0, #0x00
-+#endif
-+ mcr p15, 0, r0, c1, c1, 0 @ set auxiliary control reg
-+ mrc p15, 0, r0, c1, c0, 0 @ get control register
-+ bic r0, r0, #0x0200 @ ......R.........
-+ bic r0, r0, #0x0082 @ ........B.....A.
-+ orr r0, r0, #0x0005 @ .............C.M
-+ orr r0, r0, #0x3900 @ ..VIZ..S........
-+#ifdef CONFIG_XSCALE_CACHE_ERRATA
-+ bic r0, r0, #0x0004 @ see cpu_xscale_proc_init
-+#endif
-+ mov pc, lr
-+
-+ .text
-+
-+/*
-+ * Purpose : Function pointers used to access above functions - all calls
-+ * come through these
-+ */
-+
-+ .type xscale_processor_functions, #object
-+ENTRY(xscale_processor_functions)
-+ .word cpu_xscale_data_abort
-+ .word cpu_xscale_check_bugs
-+ .word cpu_xscale_proc_init
-+ .word cpu_xscale_proc_fin
-+ .word cpu_xscale_reset
-+ .word cpu_xscale_do_idle
-+
-+ /* cache */
-+ .word cpu_xscale_cache_clean_invalidate_all
-+ .word cpu_xscale_cache_clean_invalidate_range
-+ .word cpu_xscale_flush_ram_page
-+
-+ /* dcache */
-+ .word cpu_xscale_dcache_invalidate_range
-+ .word cpu_xscale_dcache_clean_range
-+ .word cpu_xscale_dcache_clean_page
-+ .word cpu_xscale_dcache_clean_entry
-+
-+ /* icache */
-+ .word cpu_xscale_icache_invalidate_range
-+ .word cpu_xscale_icache_invalidate_page
-+
-+ /* tlb */
-+ .word cpu_xscale_tlb_invalidate_all
-+ .word cpu_xscale_tlb_invalidate_range
-+ .word cpu_xscale_tlb_invalidate_page
-+
-+ /* pgtable */
-+ .word cpu_xscale_set_pgd
-+ .word cpu_xscale_set_pmd
-+ .word cpu_xscale_set_pte
-+ .size xscale_processor_functions, . - xscale_processor_functions
-+
-+ .type cpu_80200_info, #object
-+cpu_80200_info:
-+ .long cpu_manu_name
-+ .long cpu_80200_name
-+ .size cpu_80200_info, . - cpu_80200_info
-+
-+ .type cpu_pxa210_info, #object
-+cpu_pxa210_info:
-+ .long cpu_manu_name
-+ .long cpu_pxa210_name
-+ .size cpu_pxa210_info, . - cpu_pxa210_info
-+
-+ .type cpu_pxa250_info, #object
-+cpu_pxa250_info:
-+ .long cpu_manu_name
-+ .long cpu_pxa250_name
-+ .size cpu_pxa250_info, . - cpu_pxa250_info
-+
-+ .type cpu_pxa255_info, #object
-+cpu_pxa255_info:
-+ .long cpu_manu_name
-+ .long cpu_pxa255_name
-+ .size cpu_pxa255_info, . - cpu_pxa255_info
-+
-+ .type cpu_arch_name, #object
-+cpu_arch_name:
-+ .asciz "armv5te"
-+ .size cpu_arch_name, . - cpu_arch_name
-+
-+ .type cpu_elf_name, #object
-+cpu_elf_name:
-+ .asciz "v5"
-+ .size cpu_elf_name, . - cpu_elf_name
-+ .align
-+
-+ .section ".proc.info", #alloc, #execinstr
-+
-+ .type __80200_proc_info,#object
-+__80200_proc_info:
-+ .long 0x69052000
-+ .long 0xfffffff0
-+#if CACHE_WRITE_THROUGH
-+ .long 0x00000c0a
-+#else
-+ .long 0x00000c0e
-+#endif
-+ b __xscale_setup
-+ .long cpu_arch_name
-+ .long cpu_elf_name
-+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_XSCALE
-+ .long cpu_80200_info
-+ .long xscale_processor_functions
-+ .size __80200_proc_info, . - __80200_proc_info
-+
-+ .type __pxa210_proc_info,#object
-+__pxa210_proc_info:
-+ .long 0x69052120
-+ .long 0xfffff3f0
-+#if CACHE_WRITE_THROUGH
-+ .long 0x00000c0a
-+#else
-+ .long 0x00000c0e
-+#endif
-+ b __xscale_setup
-+ .long cpu_arch_name
-+ .long cpu_elf_name
-+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_XSCALE
-+ .long cpu_pxa210_info
-+ .long xscale_processor_functions
-+ .size __pxa210_proc_info, . - __pxa210_proc_info
-+
-+ .type __pxa250_proc_info,#object
-+__pxa250_proc_info:
-+ .long 0x69052100
-+ .long 0xfffff7f0
-+#if CACHE_WRITE_THROUGH
-+ .long 0x00000c0a
-+#else
-+ .long 0x00000c0e
-+#endif
-+ b __xscale_setup
-+ .long cpu_arch_name
-+ .long cpu_elf_name
-+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_XSCALE
-+ .long cpu_pxa250_info
-+ .long xscale_processor_functions
-+ .size __pxa250_proc_info, . - __pxa250_proc_info
-+
-+ .type __pxa255_proc_info,#object
-+__pxa255_proc_info:
-+ .long 0x69052d00
-+ .long 0xfffffff0
-+#if CACHE_WRITE_THROUGH
-+ .long 0x00000c0a
-+#else
-+ .long 0x00000c0e
-+#endif
-+ b __xscale_setup
-+ .long cpu_arch_name
-+ .long cpu_elf_name
-+ .long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_XSCALE
-+ .long cpu_pxa255_info
-+ .long xscale_processor_functions
-+ .size __pxa255_proc_info, . - __pxa255_proc_info
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/vmlinux-armv-xip.lds.in 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,125 @@
-+/*
-+ * ld script to make ARM Linux kernel
-+ *
-+ * (C) Copyright 2001 Lineo Japan, Inc.
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ *
-+ * Based on arch/arm/vmlinux-armv.lds.in
-+ *
-+ * taken from the i386 version by Russell King
-+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
-+ */
-+OUTPUT_ARCH(arm)
-+ENTRY(stext)
-+SECTIONS
-+{
-+ . = TEXTADDR;
-+ .init : { /* Init code and data */
-+ _stext = .;
-+ __init_begin = .;
-+ *(.text.init)
-+ __proc_info_begin = .;
-+ *(.proc.info)
-+ __proc_info_end = .;
-+ __arch_info_begin = .;
-+ *(.arch.info)
-+ __arch_info_end = .;
-+ __tagtable_begin = .;
-+ *(.taglist)
-+ __tagtable_end = .;
-+ . = ALIGN(16);
-+ __setup_start = .;
-+ *(.setup.init)
-+ __setup_end = .;
-+ __initcall_start = .;
-+ *(.initcall.init)
-+ __initcall_end = .;
-+ . = ALIGN(4096);
-+ __init_end = .;
-+ }
-+
-+ /DISCARD/ : { /* Exit code and data */
-+ *(.text.exit)
-+ *(.data.exit)
-+ *(.exitcall.exit)
-+ }
-+
-+ .text : { /* Real text segment */
-+ _text = .; /* Text and read-only data */
-+ *(.text)
-+ *(.fixup)
-+ *(.gnu.warning)
-+ *(.text.lock) /* out-of-line lock text */
-+ *(.rodata)
-+ *(.rodata.*)
-+ *(.glue_7)
-+ *(.glue_7t)
-+ *(.kstrtab)
-+ *(.got) /* Global offset table */
-+ *(.got.plt)
-+
-+ _etext = .; /* End of text section */
-+ }
-+
-+ . = ALIGN(16);
-+ __ex_table : { /* Exception table */
-+ __start___ex_table = .;
-+ *(__ex_table)
-+ __stop___ex_table = .;
-+ }
-+
-+ __ksymtab : { /* Kernel symbol table */
-+ __start___ksymtab = .;
-+ *(__ksymtab)
-+ __stop___ksymtab = .;
-+ }
-+
-+ _endtext = .;
-+
-+ . = DATAADDR;
-+
-+ _sdata = .;
-+
-+ . = ALIGN(8192);
-+
-+ .data : {
-+ /*
-+ * first, the init task union, aligned
-+ * to an 8192 byte boundary.
-+ */
-+ *(.init.task)
-+
-+ /*
-+ * then the cacheline aligned data
-+ */
-+ . = ALIGN(32);
-+ *(.data.cacheline_aligned)
-+
-+ /*
-+ * and the usual data section
-+ */
-+ *(.data)
-+ CONSTRUCTORS
-+
-+ *(.data.init)
-+
-+ _edata = .;
-+ }
-+
-+ .bss : {
-+ __bss_start = .; /* BSS */
-+ *(.bss)
-+ *(COMMON)
-+ _end = . ;
-+ }
-+ /* Stabs debugging sections. */
-+ .stab 0 : { *(.stab) }
-+ .stabstr 0 : { *(.stabstr) }
-+ .stab.excl 0 : { *(.stab.excl) }
-+ .stab.exclstr 0 : { *(.stab.exclstr) }
-+ .stab.index 0 : { *(.stab.index) }
-+ .stab.indexstr 0 : { *(.stab.indexstr) }
-+ .comment 0 : { *(.comment) }
-+}
---- linux-2.4.25/drivers/Makefile~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/Makefile 2004-03-31 17:15:11.000000000 +0200
-@@ -25,6 +25,7 @@
- subdir-$(CONFIG_NUBUS) += nubus
- subdir-$(CONFIG_TC) += tc
- subdir-$(CONFIG_VT) += video
-+subdir-$(CONFIG_MMC) += mmc
- subdir-$(CONFIG_MAC) += macintosh
- subdir-$(CONFIG_PPC32) += macintosh
- subdir-$(CONFIG_USB) += usb
---- linux-2.4.25/drivers/char/Config.in~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/char/Config.in 2004-03-31 17:15:11.000000000 +0200
-@@ -253,6 +253,7 @@
- dep_tristate ' DC21285 watchdog' CONFIG_21285_WATCHDOG $CONFIG_FOOTBRIDGE
- dep_tristate ' NetWinder WB83C977 watchdog' CONFIG_977_WATCHDOG $CONFIG_ARCH_NETWINDER
- dep_tristate ' SA1100 watchdog' CONFIG_SA1100_WATCHDOG $CONFIG_ARCH_SA1100
-+ dep_tristate ' PXA250/210 watchdog' CONFIG_SA1100_WATCHDOG $CONFIG_ARCH_PXA
- dep_tristate ' EPXA watchdog' CONFIG_EPXA_WATCHDOG $CONFIG_ARCH_CAMELOT
- dep_tristate ' Omaha watchdog' CONFIG_OMAHA_WATCHDOG $CONFIG_ARCH_OMAHA
- dep_tristate ' AT91RM9200 watchdog' CONFIG_AT91_WATCHDOG $CONFIG_ARCH_AT91RM9200
-@@ -335,6 +336,9 @@
- if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
- tristate 'SA1100 Real Time Clock' CONFIG_SA1100_RTC
- fi
-+if [ "$CONFIG_ARCH_PXA" = "y" ]; then
-+ tristate 'PXA250/210 Real Time Clock' CONFIG_PXA_RTC
-+fi
- if [ "$CONFIG_ARCH_OMAHA" = "y" ]; then
- tristate 'Omaha Real Time Clock' CONFIG_OMAHA_RTC
- fi
-@@ -417,4 +421,8 @@
- dep_tristate 'HP OB600 C/CT Pop-up mouse support' CONFIG_OBMOUSE $CONFIG_INPUT_MOUSEDEV
- fi
-
-+if [ "$CONFIG_ARCH_TRIZEPS2" = "y" ]; then
-+ tristate ' MT6N TTL I/O suport' CONFIG_TRIZEPS2_TTLIO
-+fi
-+
- endmenu
---- linux-2.4.25/drivers/char/Makefile~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/char/Makefile 2004-03-31 17:15:11.000000000 +0200
-@@ -280,6 +280,7 @@
- obj-$(CONFIG_MIPS_RTC) += mips_rtc.o
- obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o
- obj-$(CONFIG_SA1100_RTC) += sa1100-rtc.o
-+obj-$(CONFIG_PXA_RTC) += sa1100-rtc.o
- obj-$(CONFIG_OMAHA_RTC) += omaha-rtc.o
- ifeq ($(CONFIG_PPC),)
- obj-$(CONFIG_NVRAM) += nvram.o
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/mt6n_ttl.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,316 @@
-+/*
-+ * Trizeps-2 MT6N development board TTL-IO interface for Linux
-+ *
-+ * Copyright (C) 2003 Luc De Cock
-+ *
-+ * This driver allows use of the TTL-IO interface on the MT6N
-+ * from user space. It exports the /dev/ttlio interface supporting
-+ * some ioctl() and also the /proc/driver/ttlio pseudo-file
-+ * for status information.
-+ *
-+ * The ioctls can be used to set individual TTL output lines.
-+ * Only ioctls are supported.
-+ *
-+ * 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.
-+ *
-+ * Based on other minimal char device drivers, like Alan's
-+ * watchdog, Ted's random, Paul's rtc, etc. etc.
-+ *
-+ * 1.00 Luc De Cock: initial version.
-+ */
-+
-+#define TTLIO_VERSION "1.00"
-+
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/types.h>
-+#include <linux/miscdevice.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/poll.h>
-+#include <linux/proc_fs.h>
-+
-+#include <asm/io.h>
-+#include <asm/uaccess.h>
-+#include <asm/system.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+
-+/* Writing to the register sets the output lines
-+* Reading from the register returns the status of the input lines
-+*/
-+static unsigned short *ttlio_base = (unsigned short *) TRIZEPS2_TTLIO_BASE;
-+static unsigned short ttlio_shadow = 0;
-+
-+/* interrupt stuff */
-+static struct fasync_struct *ttlio_async_queue;
-+static DECLARE_WAIT_QUEUE_HEAD(ttlio_wait);
-+static int ttlio_irq_arrived = 0;
-+static spinlock_t ttlio_lock;
-+static unsigned short ttlio_in = 0;
-+static volatile unsigned long teller = 0;
-+
-+
-+static int ttlio_ioctl(struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg);
-+
-+static int ttlio_read_proc(char *page, char **start, off_t off,
-+ int count, int *eof, void *data);
-+
-+
-+static void ttlio_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ ttlio_in = *ttlio_base;
-+
-+ ttlio_irq_arrived = 1;
-+ teller++;
-+
-+ /* wake up the waiting process */
-+ wake_up_interruptible(&ttlio_wait);
-+ kill_fasync(&ttlio_async_queue, SIGIO, POLL_IN);
-+}
-+
-+/*
-+ * Now all the various file operations that we export.
-+ */
-+
-+static int ttlio_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
-+ unsigned long arg)
-+{
-+ unsigned long ttlio_val;
-+
-+ switch (cmd) {
-+ case TTLIO_RESET: /* clear all lines */
-+ {
-+ *ttlio_base = 0;
-+ return 0;
-+ }
-+ case TTLIO_GET: /* get state of TTL input lines */
-+ {
-+ ttlio_val = *ttlio_base;
-+ return put_user(ttlio_val, (unsigned long *)arg);
-+ }
-+ case TTLIO_SET: /* set state of TTL output lines */
-+ {
-+ unsigned long user_val;
-+ if (copy_from_user(&user_val, arg, sizeof(unsigned long)))
-+ return -EFAULT;
-+ ttlio_shadow |= (unsigned short) user_val;
-+ *ttlio_base = ttlio_shadow;
-+ return 0;
-+ }
-+ case TTLIO_UNSET: /* unset (clear) state of TTL output lines */
-+ {
-+ unsigned long user_val;
-+ if (copy_from_user(&user_val, arg, sizeof(unsigned long)))
-+ return -EFAULT;
-+ ttlio_shadow &= ~((unsigned short) user_val);
-+ *ttlio_base = ttlio_shadow;
-+ return 0;
-+ }
-+ case 100: /* get counter */
-+ {
-+ return put_user(teller, (unsigned long *)arg);
-+ }
-+ case 101: /* reset counter */
-+ {
-+ teller = 0;
-+ return 0;
-+ }
-+ default:
-+ return -ENOTTY;
-+ }
-+ return 0;
-+}
-+
-+static ssize_t ttlio_read(struct file *file, char *buf,
-+ size_t count, loff_t *ppos)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ unsigned short data;
-+ ssize_t retval;
-+
-+ if (count < sizeof(unsigned short))
-+ return -EINVAL;
-+
-+ if (file->f_flags & O_NONBLOCK) {
-+ spin_lock_irq(&ttlio_lock);
-+ data = *ttlio_base;
-+ spin_unlock_irq(&ttlio_lock);
-+ retval = put_user(data, (unsigned short *) buf);
-+ if (!retval)
-+ retval = sizeof(unsigned short);
-+ return retval;
-+ }
-+ /* blocking read: wait for interrupt */
-+ add_wait_queue(&ttlio_wait, &wait);
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ for (;;) {
-+ spin_lock_irq(&ttlio_lock);
-+ data = *ttlio_base;
-+ if (ttlio_irq_arrived) {
-+ ttlio_irq_arrived = 0;
-+ break;
-+ }
-+ spin_unlock_irq(&ttlio_lock);
-+
-+ if (signal_pending(current)) {
-+ retval = -ERESTARTSYS;
-+ goto out;
-+ }
-+ schedule();
-+ }
-+
-+ spin_unlock_irq(&ttlio_lock);
-+ retval = put_user(data, (unsigned short *)buf);
-+ if (!retval)
-+ retval = sizeof(unsigned short);
-+
-+out:
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&ttlio_wait, &wait);
-+ return retval;
-+}
-+
-+static ssize_t ttlio_write(struct file *file,
-+ const char *buf, size_t count, loff_t *ppos)
-+{
-+ unsigned short content;
-+
-+ if (count < sizeof(unsigned short))
-+ return -EINVAL;
-+
-+ if (copy_from_user (&content, buf, sizeof(unsigned short)))
-+ return -EFAULT;
-+
-+ ttlio_shadow = content;
-+ *ttlio_base = ttlio_shadow;
-+
-+ *ppos += sizeof(unsigned short);
-+
-+ return sizeof(unsigned short);
-+}
-+
-+static int ttlio_open(struct inode *inode, struct file *file)
-+{
-+ ttlio_irq_arrived = 0;
-+ return 0;
-+}
-+
-+static int ttlio_fasync(int fd, struct file *filp, int on)
-+{
-+ return fasync_helper(fd, filp, on, &ttlio_async_queue);
-+}
-+
-+static unsigned int ttlio_poll(struct file *file, poll_table *wait)
-+{
-+ poll_wait(file, &ttlio_wait, wait);
-+ return ttlio_irq_arrived ? 0 : POLLIN | POLLRDNORM;
-+}
-+
-+static loff_t ttlio_llseek(struct file *file, loff_t offset, int origin)
-+{
-+ return -ESPIPE;
-+}
-+
-+/*
-+ * The various file operations we support.
-+ */
-+
-+static struct file_operations ttlio_fops = {
-+ owner: THIS_MODULE,
-+ llseek: ttlio_llseek,
-+ read: ttlio_read,
-+ poll: ttlio_poll,
-+ write: ttlio_write,
-+ ioctl: ttlio_ioctl,
-+ open: ttlio_open,
-+ fasync: ttlio_fasync,
-+};
-+
-+static struct miscdevice ttlio_dev = {
-+ TTLIO_MINOR,
-+ "ttlio",
-+ &ttlio_fops
-+};
-+
-+static int __init ttlio_init(void)
-+{
-+ printk(KERN_INFO "MT6N TTL-I/O driver (release %s)\n",
-+ TTLIO_VERSION);
-+
-+ misc_register(&ttlio_dev);
-+ create_proc_read_entry ("driver/ttlio", 0, 0, ttlio_read_proc, NULL);
-+
-+ set_GPIO_IRQ_edge(GPIO_TTLIO_IRQ, GPIO_FALLING_EDGE);
-+ if (request_irq(TTLIO_IRQ, ttlio_interrupt, SA_INTERRUPT, "ttlio irq", NULL)) {
-+ printk(KERN_ERR "ttlio: irq %d already in use\n", TTLIO_IRQ);
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+static void __exit ttlio_exit(void)
-+{
-+ free_irq(TTLIO_IRQ, NULL);
-+ remove_proc_entry ("driver/ttlio", NULL);
-+ misc_deregister(&ttlio_dev);
-+}
-+
-+module_init(ttlio_init);
-+module_exit(ttlio_exit);
-+EXPORT_NO_SYMBOLS;
-+
-+/*
-+ * Info exported via "/proc/driver/ttlio".
-+ */
-+
-+static int ttlio_proc_output(char *buf)
-+{
-+ char *p;
-+ unsigned short val;
-+ int i;
-+
-+ p = buf;
-+
-+ p += sprintf(p, "input : ");
-+ /* write the state of the input lines */
-+ val = *ttlio_base;
-+ for (i = 0; i < 8*sizeof(unsigned short); i++) {
-+ *p++ = (val & 1) ? '1' : '0';
-+ val >>= 1;
-+ }
-+ *p = 0;
-+ p += sprintf(p, "\noutput: ");
-+ /* write the state of the output lines */
-+ val = ttlio_shadow;
-+ for (i = 0; i < 8*sizeof(unsigned short); i++) {
-+ *p++ = (val & 1) ? '1' : '0';
-+ val >>= 1;
-+ }
-+ *p = 0;
-+ p += sprintf(p, "\n");
-+
-+ return p - buf;
-+}
-+
-+static int ttlio_read_proc(char *page, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ int len = ttlio_proc_output (page);
-+ if (len <= off+count) *eof = 1;
-+ *start = page + off;
-+ len -= off;
-+ if (len > count) len = count;
-+ if (len < 0) len = 0;
-+ return len;
-+}
-+
-+MODULE_AUTHOR("Luc De Cock");
-+MODULE_DESCRIPTION("MT6N TTL-I/O driver");
-+MODULE_LICENSE("GPL");
---- linux-2.4.25/drivers/char/sa1100-rtc.c~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/char/sa1100-rtc.c 2004-03-31 17:15:11.000000000 +0200
-@@ -1,5 +1,6 @@
- /*
- * Real Time Clock interface for Linux on StrongARM SA1100
-+ * and XScale PXA250/210.
- *
- * Copyright (c) 2000 Nils Faerber
- *
-@@ -470,5 +471,5 @@
- module_exit(rtc_exit);
-
- MODULE_AUTHOR("Nils Faerber <nils@@kernelconcepts.de>");
--MODULE_DESCRIPTION("SA1100 Realtime Clock Driver (RTC)");
-+MODULE_DESCRIPTION("SA1100/PXA Realtime Clock Driver (RTC)");
- EXPORT_NO_SYMBOLS;
---- linux-2.4.25/drivers/char/sa1100_wdt.c~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/char/sa1100_wdt.c 2004-03-31 17:15:11.000000000 +0200
-@@ -1,5 +1,5 @@
- /*
-- * Watchdog driver for the SA11x0
-+ * Watchdog driver for the SA11x0/PXA
- *
- * (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
- * Based on SoftDog driver by Alan Cox <alan@redhat.com>
-@@ -35,13 +35,20 @@
-
- #define TIMER_MARGIN 60 /* (secs) Default is 1 minute */
-
--static int sa1100_margin = TIMER_MARGIN; /* in seconds */
-+static int timer_margin = TIMER_MARGIN; /* in seconds */
- static int sa1100wdt_users;
- static int pre_margin;
- #ifdef MODULE
--MODULE_PARM(sa1100_margin,"i");
-+MODULE_PARM(timer_margin,"i");
- #endif
-
-+static void sa1100dog_ping( void)
-+{
-+ /* reload counter with (new) margin */
-+ pre_margin=3686400 * timer_margin;
-+ OSMR3 = OSCR + pre_margin;
-+}
-+
- /*
- * Allow only one person to hold it open
- */
-@@ -51,9 +58,7 @@
- if(test_and_set_bit(1,&sa1100wdt_users))
- return -EBUSY;
- MOD_INC_USE_COUNT;
-- /* Activate SA1100 Watchdog timer */
-- pre_margin=3686400 * sa1100_margin;
-- OSMR3 = OSCR + pre_margin;
-+ sa1100dog_ping();
- OSSR = OSSR_M3;
- OWER = OWER_WME;
- OIER |= OIER_E3;
-@@ -93,8 +98,11 @@
- unsigned int cmd, unsigned long arg)
- {
- static struct watchdog_info ident = {
-- identity: "SA1100 Watchdog",
-+ identity: "PXA/SA1100 Watchdog",
-+ options: WDIOF_SETTIMEOUT,
-+ firmware_version: 0,
- };
-+ int new_margin;
-
- switch(cmd){
- default:
-@@ -108,6 +116,16 @@
- case WDIOC_KEEPALIVE:
- OSMR3 = OSCR + pre_margin;
- return 0;
-+ case WDIOC_SETTIMEOUT:
-+ if (get_user(new_margin, (int *)arg))
-+ return -EFAULT;
-+ if (new_margin < 1)
-+ return -EINVAL;
-+ timer_margin = new_margin;
-+ sa1100dog_ping();
-+ /* Fall */
-+ case WDIOC_GETTIMEOUT:
-+ return put_user(timer_margin, (int *)arg);
- }
- }
-
-@@ -123,7 +141,11 @@
- static struct miscdevice sa1100dog_miscdev=
- {
- WATCHDOG_MINOR,
-- "SA1100 watchdog",
-+#if defined(CONFIG_SA1100_WATCHDOG)
-+ "SA1100_watchdog",
-+#elif defined(CONFIG_PXA_WATCHDOG)
-+ "PXA_watchdog",
-+#endif
- &sa1100dog_fops
- };
-
-@@ -136,7 +158,7 @@
- if (ret)
- return ret;
-
-- printk("SA1100 Watchdog Timer: timer margin %d sec\n", sa1100_margin);
-+ printk("SA1100/PXA Watchdog Timer: timer margin %d sec\n", timer_margin);
-
- return 0;
- }
---- linux-2.4.25/drivers/char/serial.c~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/char/serial.c 2004-03-31 17:15:11.000000000 +0200
-@@ -133,6 +133,16 @@
- #endif
- #endif
-
-+#ifdef CONFIG_ARCH_PXA
-+#define pxa_port(x) ((x) == PORT_PXA)
-+#define pxa_buggy_port(x) ({ \
-+ int cpu_ver; asm("mrc%? p15, 0, %0, c0, c0" : "=r" (cpu_ver)); \
-+ ((x) == PORT_PXA && (cpu_ver & ~1) == 0x69052100); })
-+#else
-+#define pxa_port(x) (0)
-+#define pxa_buggy_port(x) (0)
-+#endif
-+
- /* Set of debugging defines */
-
- #undef SERIAL_DEBUG_INTR
-@@ -311,6 +321,7 @@
- { "XR16850", 128, UART_CLEAR_FIFO | UART_USE_FIFO |
- UART_STARTECH },
- { "RSA", 2048, UART_CLEAR_FIFO | UART_USE_FIFO },
-+ { "PXA UART", 32, UART_CLEAR_FIFO | UART_USE_FIFO },
- { 0, 0}
- };
-
-@@ -424,6 +435,9 @@
- case SERIAL_IO_MEM:
- return readb((unsigned long) info->iomem_base +
- (offset<<info->iomem_reg_shift));
-+ case SERIAL_IO_MEM32:
-+ return readl((unsigned long) info->iomem_base +
-+ (offset<<info->iomem_reg_shift));
- default:
- return inb(info->port + offset);
- }
-@@ -443,6 +457,10 @@
- writeb(value, (unsigned long) info->iomem_base +
- (offset<<info->iomem_reg_shift));
- break;
-+ case SERIAL_IO_MEM32:
-+ writel(value, (unsigned long) info->iomem_base +
-+ (offset<<info->iomem_reg_shift));
-+ break;
- default:
- outb(value, info->port+offset);
- }
-@@ -1306,6 +1324,16 @@
- }
- #endif
-
-+#ifdef CONFIG_ARCH_PXA
-+ if (state->type == PORT_PXA) {
-+ switch ((long)state->iomem_base) {
-+ case (long)&FFUART: CKEN |= CKEN6_FFUART; break;
-+ case (long)&BTUART: CKEN |= CKEN7_BTUART; break;
-+ case (long)&STUART: CKEN |= CKEN5_STUART; break;
-+ }
-+ }
-+#endif
-+
- /*
- * Clear the FIFO buffers and disable them
- * (they will be reenabled in change_speed())
-@@ -1403,6 +1431,8 @@
- {
- if (state->irq != 0)
- info->MCR |= UART_MCR_OUT2;
-+ if (pxa_buggy_port(state->type) && state->irq != 0)
-+ info->MCR ^= UART_MCR_OUT2;
- }
- info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */
- serial_outp(info, UART_MCR, info->MCR);
-@@ -1411,6 +1441,8 @@
- * Finally, enable interrupts
- */
- info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
-+ if (pxa_port(state->type))
-+ info->IER |= UART_IER_UUE | UART_IER_RTOIE;
- serial_outp(info, UART_IER, info->IER); /* enable interrupts */
-
- #ifdef CONFIG_SERIAL_MANY_PORTS
-@@ -1542,6 +1574,8 @@
- } else
- #endif
- info->MCR &= ~UART_MCR_OUT2;
-+ if (pxa_buggy_port(state->type))
-+ info->MCR ^= UART_MCR_OUT2;
- info->MCR |= ALPHA_KLUDGE_MCR; /* Don't ask */
-
- /* disable break condition */
-@@ -1567,6 +1601,20 @@
- state->baud_base = SERIAL_RSA_BAUD_BASE_LO;
- #endif
-
-+#ifdef CONFIG_ARCH_PXA
-+ if (state->type == PORT_PXA
-+#ifdef CONFIG_SERIAL_CONSOLE
-+ && sercons.index != info->line
-+#endif
-+ ) {
-+ switch ((long)state->iomem_base) {
-+ case (long)&FFUART: CKEN &= ~CKEN6_FFUART; break;
-+ case (long)&BTUART: CKEN &= ~CKEN7_BTUART; break;
-+ case (long)&STUART: CKEN &= ~CKEN5_STUART; break;
-+ }
-+ }
-+#endif
-+
-
- (void)serial_in(info, UART_RX); /* read data port to reset things */
-
-@@ -1857,6 +1905,8 @@
- save_flags(flags); cli();
- info->IER |= UART_IER_THRI;
- serial_out(info, UART_IER, info->IER);
-+ if (pxa_buggy_port(info->state->type))
-+ rs_interrupt_single(info->state->irq, NULL, NULL);
- restore_flags(flags);
- }
-
-@@ -1933,6 +1983,11 @@
- && !(info->IER & UART_IER_THRI)) {
- info->IER |= UART_IER_THRI;
- serial_out(info, UART_IER, info->IER);
-+ if (pxa_buggy_port(info->state->type)) {
-+ save_flags(flags); cli();
-+ rs_interrupt_single(info->state->irq, NULL, NULL);
-+ restore_flags(flags);
-+ }
- }
- return ret;
- }
-@@ -1990,6 +2045,8 @@
- /* Make sure transmit interrupts are on */
- info->IER |= UART_IER_THRI;
- serial_out(info, UART_IER, info->IER);
-+ if (pxa_buggy_port(info->state->type))
-+ rs_interrupt_single(info->state->irq, NULL, NULL);
- }
- }
-
-@@ -5517,7 +5574,6 @@
- for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
- state->magic = SSTATE_MAGIC;
- state->line = i;
-- state->type = PORT_UNKNOWN;
- state->custom_divisor = 0;
- state->close_delay = 5*HZ/10;
- state->closing_wait = 30*HZ;
-@@ -5531,14 +5587,18 @@
- state->irq = irq_cannonicalize(state->irq);
- if (state->hub6)
- state->io_type = SERIAL_IO_HUB6;
-- if (state->port && check_region(state->port,8))
-+ if (state->port && check_region(state->port,8)) {
-+ state->type = PORT_UNKNOWN;
- continue;
-+ }
- #ifdef CONFIG_MCA
- if ((state->flags & ASYNC_BOOT_ONLYMCA) && !MCA_bus)
- continue;
- #endif
-- if (state->flags & ASYNC_BOOT_AUTOCONF)
-+ if (state->flags & ASYNC_BOOT_AUTOCONF) {
-+ state->type = PORT_UNKNOWN;
- autoconfig(state);
-+ }
- }
- for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
- if (state->type == PORT_UNKNOWN)
-@@ -5858,6 +5918,8 @@
- */
- ier = serial_in(info, UART_IER);
- serial_out(info, UART_IER, 0x00);
-+ if (pxa_port(info->state->type))
-+ serial_out(info, UART_IER, UART_IER_UUE);
-
- /*
- * Now, do each character
-@@ -6009,6 +6071,8 @@
- serial_out(info, UART_DLM, quot >> 8); /* MS of divisor */
- serial_out(info, UART_LCR, cval); /* reset DLAB */
- serial_out(info, UART_IER, 0);
-+ if (pxa_port(info->state->type))
-+ serial_out(info, UART_IER, UART_IER_UUE);
- serial_out(info, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
-
- /*
---- linux-2.4.25/drivers/i2c/Config.in~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/i2c/Config.in 2004-03-31 17:15:11.000000000 +0200
-@@ -54,6 +54,11 @@
- fi
- fi
-
-+ if [ "$CONFIG_ARCH_PXA" = "y" ]; then
-+ dep_tristate 'PXA I2C Algorithm' CONFIG_I2C_PXA_ALGO $CONFIG_I2C
-+ dep_tristate 'PXA I2C Adapter' CONFIG_I2C_PXA_ADAP $CONFIG_I2C_PXA_ALGO
-+ fi
-+
- if [ "$CONFIG_ALL_PPC" = "y" ] ; then
- dep_tristate 'Keywest I2C interface in Apple Core99 machines' CONFIG_I2C_KEYWEST $CONFIG_I2C
- fi
---- linux-2.4.25/drivers/i2c/Makefile~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/i2c/Makefile 2004-03-31 17:15:11.000000000 +0200
-@@ -6,7 +6,7 @@
-
- export-objs := i2c-core.o i2c-algo-bit.o i2c-algo-pcf.o \
- i2c-algo-ite.o i2c-algo-sibyte.o i2c-algo-sgi.o \
-- i2c-proc.o
-+ i2c-algo-pxa.o i2c-proc.o
-
- # Init order: core, chardev, bit adapters, pcf adapters
-
-@@ -35,6 +35,10 @@
- obj-$(CONFIG_I2C_MAX1617) += i2c-max1617.o
- obj-$(CONFIG_I2C_ALGO_SGI) += i2c-algo-sgi.o
-
-+# PXA adapters
-+obj-$(CONFIG_I2C_PXA_ALGO) += i2c-algo-pxa.o
-+obj-$(CONFIG_I2C_PXA_ADAP) += i2c-adap-pxa.o
-+
- # This is needed for automatic patch generation: sensors code starts here
- # This is needed for automatic patch generation: sensors code ends here
-
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/i2c/i2c-adap-pxa.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,396 @@
-+/*
-+ * i2c_adap_pxa.c
-+ *
-+ * I2C adapter for the PXA I2C bus access.
-+ *
-+ * Copyright (C) 2002 Intrinsyc Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * History:
-+ * Apr 2002: Initial version [CS]
-+ * Jun 2002: Properly seperated algo/adap [FB]
-+ * Jan 2003: Fixed several bugs concerning interrupt handling [Kai-Uwe Bloem]
-+ * Jan 2003: added limited signal handling [Kai-Uwe Bloem]
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+
-+#include <linux/i2c.h>
-+#include <linux/i2c-id.h>
-+#include <linux/init.h>
-+#include <linux/time.h>
-+#include <linux/sched.h>
-+#include <linux/delay.h>
-+#include <linux/errno.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/arch/irqs.h> /* for IRQ_I2C */
-+
-+#include "i2c-pxa.h"
-+
-+/*
-+ * Set this to zero to remove all debug statements via dead code elimination.
-+ */
-+//#define DEBUG 1
-+
-+#if DEBUG
-+static unsigned int i2c_debug = DEBUG;
-+#else
-+#define i2c_debug 0
-+#endif
-+
-+static int irq = 0;
-+static volatile int i2c_pending = 0; /* interrupt pending when 1 */
-+static volatile int bus_error = 0;
-+static volatile int tx_finished = 0;
-+static volatile int rx_finished = 0;
-+
-+static wait_queue_head_t i2c_wait;
-+static void i2c_pxa_transfer( int lastbyte, int receive, int midbyte);
-+
-+/* place a byte in the transmit register */
-+static void i2c_pxa_write_byte(u8 value)
-+{
-+ IDBR = value;
-+}
-+
-+/* read byte in the receive register */
-+static u8 i2c_pxa_read_byte(void)
-+{
-+ return (u8) (0xff & IDBR);
-+}
-+
-+static void i2c_pxa_start(void)
-+{
-+ unsigned long icr = ICR;
-+ icr |= ICR_START;
-+ icr &= ~(ICR_STOP | ICR_ALDIE | ICR_ACKNAK);
-+ ICR = icr;
-+
-+ bus_error=0; /* clear any bus_error from previous txfers */
-+ tx_finished=0; /* clear rx and tx interrupts from previous txfers */
-+ rx_finished=0;
-+ i2c_pending = 0;
-+}
-+
-+static void i2c_pxa_repeat_start(void)
-+{
-+ unsigned long icr = ICR;
-+ icr |= ICR_START;
-+ icr &= ~(ICR_STOP | ICR_ALDIE);
-+ ICR = icr;
-+
-+ bus_error=0; /* clear any bus_error from previous txfers */
-+ tx_finished=0; /* clear rx and tx interrupts from previous txfers */
-+ rx_finished=0;
-+ i2c_pending = 0;
-+}
-+
-+static void i2c_pxa_stop(void)
-+{
-+ unsigned long icr = ICR;
-+ icr |= ICR_STOP;
-+ icr &= ~(ICR_START);
-+ ICR = icr;
-+}
-+
-+static void i2c_pxa_midbyte(void)
-+{
-+ unsigned long icr = ICR;
-+ icr &= ~(ICR_START | ICR_STOP);
-+ ICR = icr;
-+}
-+
-+static void i2c_pxa_abort(void)
-+{
-+ unsigned long timeout = jiffies + HZ/4;
-+
-+#ifdef PXA_ABORT_MA
-+ while ((long)(timeout - jiffies) > 0 && (ICR & ICR_TB)) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(1);
-+ }
-+
-+ ICR |= ICR_MA;
-+ udelay(100);
-+#else
-+ while ((long)(timeout - jiffies) > 0 && (IBMR & 0x1) == 0) {
-+ i2c_pxa_transfer( 1, I2C_RECEIVE, 1);
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(1);
-+ }
-+#endif
-+ ICR &= ~(ICR_MA | ICR_START | ICR_STOP);
-+}
-+
-+static int i2c_pxa_wait_bus_not_busy( void)
-+{
-+ int timeout = DEF_TIMEOUT;
-+
-+ while (timeout-- && (ISR & ISR_IBB)) {
-+ udelay(100); /* wait for 100 us */
-+ }
-+
-+ return (timeout<=0);
-+}
-+
-+static void i2c_pxa_wait_for_ite(void){
-+ unsigned long flags;
-+ if (irq > 0) {
-+ save_flags_cli(flags);
-+ if (i2c_pending == 0) {
-+ interruptible_sleep_on_timeout(&i2c_wait, I2C_SLEEP_TIMEOUT );
-+ }
-+ i2c_pending = 0;
-+ restore_flags(flags);
-+ } else {
-+ udelay(100);
-+ }
-+}
-+
-+static int i2c_pxa_wait_for_int( int wait_type)
-+{
-+ int timeout = DEF_TIMEOUT;
-+#ifdef DEBUG
-+ if (bus_error)
-+ printk(KERN_INFO"i2c_pxa_wait_for_int: Bus error on enter\n");
-+ if (rx_finished)
-+ printk(KERN_INFO"i2c_pxa_wait_for_int: Receive interrupt on enter\n");
-+ if (tx_finished)
-+ printk(KERN_INFO"i2c_pxa_wait_for_int: Transmit interrupt on enter\n");
-+#endif
-+
-+ if (wait_type == I2C_RECEIVE){ /* wait on receive */
-+
-+ do {
-+ i2c_pxa_wait_for_ite();
-+ } while (!(rx_finished) && timeout-- && !signal_pending(current));
-+
-+#ifdef DEBUG
-+ if (timeout<0){
-+ if (tx_finished)
-+ printk("Error: i2c-algo-pxa.o: received a tx"
-+ " interrupt while waiting on a rx in wait_for_int");
-+ }
-+#endif
-+ } else { /* wait on transmit */
-+
-+ do {
-+ i2c_pxa_wait_for_ite();
-+ } while (!(tx_finished) && timeout-- && !signal_pending(current));
-+
-+#ifdef DEBUG
-+ if (timeout<0){
-+ if (rx_finished)
-+ printk("Error: i2c-algo-pxa.o: received a rx"
-+ " interrupt while waiting on a tx in wait_for_int");
-+ }
-+#endif
-+ }
-+
-+ udelay(ACK_DELAY); /* this is needed for the bus error */
-+
-+ tx_finished=0;
-+ rx_finished=0;
-+
-+ if (bus_error){
-+ bus_error=0;
-+ if( i2c_debug > 2)printk("wait_for_int: error - no ack.\n");
-+ return BUS_ERROR;
-+ }
-+
-+ if (signal_pending(current)) {
-+ return (-ERESTARTSYS);
-+ } else if (timeout < 0) {
-+ if( i2c_debug > 2)printk("wait_for_int: timeout.\n");
-+ return(-EIO);
-+ } else
-+ return(0);
-+}
-+
-+static void i2c_pxa_transfer( int lastbyte, int receive, int midbyte)
-+{
-+ if( lastbyte)
-+ {
-+ if( receive==I2C_RECEIVE) ICR |= ICR_ACKNAK;
-+ i2c_pxa_stop();
-+ }
-+ else if( midbyte)
-+ {
-+ i2c_pxa_midbyte();
-+ }
-+ ICR |= ICR_TB;
-+}
-+
-+static void i2c_pxa_reset( void)
-+{
-+#ifdef DEBUG
-+ printk("Resetting I2C Controller Unit\n");
-+#endif
-+
-+ /* abort any transfer currently under way */
-+ i2c_pxa_abort();
-+
-+ /* reset according to 9.8 */
-+ ICR = ICR_UR;
-+ ISR = I2C_ISR_INIT;
-+ ICR &= ~ICR_UR;
-+
-+ /* set the global I2C clock on */
-+ CKEN |= CKEN14_I2C;
-+
-+ /* set our slave address */
-+ ISAR = I2C_PXA_SLAVE_ADDR;
-+
-+ /* set control register values */
-+ ICR = I2C_ICR_INIT;
-+
-+ /* clear any leftover states from prior transmissions */
-+ i2c_pending = rx_finished = tx_finished = bus_error = 0;
-+
-+ /* enable unit */
-+ ICR |= ICR_IUE;
-+ udelay(100);
-+}
-+
-+static void i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *regs)
-+{
-+ int status, wakeup = 0;
-+ status = (ISR);
-+
-+ if (status & ISR_BED){
-+ (ISR) |= ISR_BED;
-+ bus_error=ISR_BED;
-+ wakeup = 1;
-+ }
-+ if (status & ISR_ITE){
-+ (ISR) |= ISR_ITE;
-+ tx_finished=ISR_ITE;
-+ wakeup = 1;
-+ }
-+ if (status & ISR_IRF){
-+ (ISR) |= ISR_IRF;
-+ rx_finished=ISR_IRF;
-+ wakeup = 1;
-+ }
-+ if (wakeup) {
-+ i2c_pending = 1;
-+ wake_up_interruptible(&i2c_wait);
-+ }
-+}
-+
-+static int i2c_pxa_resource_init( void)
-+{
-+ init_waitqueue_head(&i2c_wait);
-+
-+ if (request_irq(IRQ_I2C, &i2c_pxa_handler, SA_INTERRUPT, "I2C_PXA", 0) < 0) {
-+ irq = 0;
-+ if( i2c_debug)
-+ printk(KERN_INFO "I2C: Failed to register I2C irq %i\n", IRQ_I2C);
-+ return -ENODEV;
-+ }else{
-+ irq = IRQ_I2C;
-+ enable_irq(irq);
-+ }
-+ return 0;
-+}
-+
-+static void i2c_pxa_resource_release( void)
-+{
-+ if( irq > 0)
-+ {
-+ disable_irq(irq);
-+ free_irq(irq,0);
-+ irq=0;
-+ }
-+}
-+
-+static void i2c_pxa_inc_use(struct i2c_adapter *adap)
-+{
-+#ifdef MODULE
-+ MOD_INC_USE_COUNT;
-+#endif
-+}
-+
-+static void i2c_pxa_dec_use(struct i2c_adapter *adap)
-+{
-+#ifdef MODULE
-+ MOD_DEC_USE_COUNT;
-+#endif
-+}
-+
-+static int i2c_pxa_client_register(struct i2c_client *client)
-+{
-+ return 0;
-+}
-+
-+static int i2c_pxa_client_unregister(struct i2c_client *client)
-+{
-+ return 0;
-+}
-+
-+static struct i2c_algo_pxa_data i2c_pxa_data = {
-+ write_byte: i2c_pxa_write_byte,
-+ read_byte: i2c_pxa_read_byte,
-+
-+ start: i2c_pxa_start,
-+ repeat_start: i2c_pxa_repeat_start,
-+ stop: i2c_pxa_stop,
-+ abort: i2c_pxa_abort,
-+
-+ wait_bus_not_busy: i2c_pxa_wait_bus_not_busy,
-+ wait_for_interrupt: i2c_pxa_wait_for_int,
-+ transfer: i2c_pxa_transfer,
-+ reset: i2c_pxa_reset,
-+
-+ udelay: 10,
-+ timeout: DEF_TIMEOUT,
-+};
-+
-+static struct i2c_adapter i2c_pxa_ops = {
-+ name: "PXA-I2C-Adapter",
-+ id: I2C_ALGO_PXA,
-+ algo_data: &i2c_pxa_data,
-+ inc_use: i2c_pxa_inc_use,
-+ dec_use: i2c_pxa_dec_use,
-+ client_register: i2c_pxa_client_register,
-+ client_unregister: i2c_pxa_client_unregister,
-+ retries: 2,
-+};
-+
-+extern int i2c_pxa_add_bus(struct i2c_adapter *);
-+extern int i2c_pxa_del_bus(struct i2c_adapter *);
-+
-+static int __init i2c_adap_pxa_init(void)
-+{
-+ if( i2c_pxa_resource_init() == 0) {
-+
-+ if (i2c_pxa_add_bus(&i2c_pxa_ops) < 0) {
-+ i2c_pxa_resource_release();
-+ printk(KERN_INFO "I2C: Failed to add bus\n");
-+ return -ENODEV;
-+ }
-+ } else {
-+ return -ENODEV;
-+ }
-+
-+ printk(KERN_INFO "I2C: Successfully added bus\n");
-+
-+ return 0;
-+}
-+
-+static void i2c_adap_pxa_exit(void)
-+{
-+ i2c_pxa_del_bus( &i2c_pxa_ops);
-+ i2c_pxa_resource_release();
-+
-+ printk(KERN_INFO "I2C: Successfully removed bus\n");
-+}
-+
-+module_init(i2c_adap_pxa_init);
-+module_exit(i2c_adap_pxa_exit);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/i2c/i2c-algo-pxa.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,376 @@
-+/*
-+ * i2c-algo-pxa.c
-+ *
-+ * I2C algorithm for the PXA I2C bus access.
-+ * Byte driven algorithm similar to pcf.
-+ *
-+ * Copyright (C) 2002 Intrinsyc Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * History:
-+ * Apr 2002: Initial version [CS]
-+ * Jun 2002: Properly seperated algo/adap [FB]
-+ * Jan 2003: added limited signal handling [Kai-Uwe Bloem]
-+ * Jan 2003: allow SMBUS_QUICK as valid msg [FB]
-+ *
-+ */
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/errno.h>
-+#include <linux/i2c.h> /* struct i2c_msg and others */
-+#include <linux/i2c-id.h>
-+
-+#include "i2c-pxa.h"
-+
-+/*
-+ * Set this to zero to remove all the debug statements via dead code elimination.
-+ */
-+//#define DEBUG 1
-+
-+#if DEBUG
-+static unsigned int i2c_debug = DEBUG;
-+#else
-+#define i2c_debug 0
-+#endif
-+
-+static int pxa_scan = 1;
-+
-+static int i2c_pxa_valid_messages( struct i2c_msg msgs[], int num)
-+{
-+ int i;
-+ if (num < 1 || num > MAX_MESSAGES){
-+ if( i2c_debug)
-+ printk(KERN_INFO "Invalid number of messages (max=%d, num=%d)\n",
-+ MAX_MESSAGES, num);
-+ return -EINVAL;
-+ }
-+
-+ /* check consistency of our messages */
-+ for (i=0;i<num;i++){
-+ if (&msgs[i]==NULL){
-+ if( i2c_debug) printk(KERN_INFO "Msgs is NULL\n");
-+ return -EINVAL;
-+ } else {
-+ if (msgs[i].len < 0 || msgs[i].buf == NULL){
-+ if( i2c_debug)printk(KERN_INFO "Length is less than zero");
-+ return -EINVAL;
-+ }
-+ }
-+ }
-+
-+ return 1;
-+}
-+
-+static int i2c_pxa_readbytes(struct i2c_adapter *i2c_adap, char *buf,
-+ int count, int last)
-+{
-+
-+ int i, timeout=0;
-+ struct i2c_algo_pxa_data *adap = i2c_adap->algo_data;
-+
-+ /* increment number of bytes to read by one -- read dummy byte */
-+ for (i = 0; i <= count; i++) {
-+ if (i!=0){
-+ /* set ACK to NAK for last received byte ICR[ACKNAK] = 1
-+ only if not a repeated start */
-+
-+ if ((i == count) && last) {
-+ adap->transfer( last, I2C_RECEIVE, 0);
-+ }else{
-+ adap->transfer( 0, I2C_RECEIVE, 1);
-+ }
-+
-+ timeout = adap->wait_for_interrupt(I2C_RECEIVE);
-+
-+#ifdef DEBUG
-+ if (timeout==BUS_ERROR){
-+ printk(KERN_INFO "i2c_pxa_readbytes: bus error -> forcing reset\n");
-+ adap->reset();
-+ return I2C_RETRY;
-+ } else
-+#endif
-+ if (timeout == -ERESTARTSYS) {
-+ adap->abort();
-+ return timeout;
-+ } else
-+ if (timeout){
-+#ifdef DEBUG
-+ printk(KERN_INFO "i2c_pxa_readbytes: timeout -> forcing reset\n");
-+#endif
-+ adap->reset();
-+ return I2C_RETRY;
-+ }
-+
-+ }
-+
-+ if (i) {
-+ buf[i - 1] = adap->read_byte();
-+ } else {
-+ adap->read_byte(); /* dummy read */
-+ }
-+ }
-+ return (i - 1);
-+}
-+
-+static int i2c_pxa_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
-+ int count, int last)
-+{
-+
-+ struct i2c_algo_pxa_data *adap = i2c_adap->algo_data;
-+ int wrcount, timeout;
-+
-+ for (wrcount=0; wrcount<count; ++wrcount) {
-+
-+ adap->write_byte(buf[wrcount]);
-+ if ((wrcount==(count-1)) && last) {
-+ adap->transfer( last, I2C_TRANSMIT, 0);
-+ }else{
-+ adap->transfer( 0, I2C_TRANSMIT, 1);
-+ }
-+
-+ timeout = adap->wait_for_interrupt(I2C_TRANSMIT);
-+
-+#ifdef DEBUG
-+ if (timeout==BUS_ERROR) {
-+ printk(KERN_INFO "i2c_pxa_sendbytes: bus error -> forcing reset.\n");
-+ adap->reset();
-+ return I2C_RETRY;
-+ } else
-+#endif
-+ if (timeout == -ERESTARTSYS) {
-+ adap->abort();
-+ return timeout;
-+ } else
-+ if (timeout) {
-+#ifdef DEBUG
-+ printk(KERN_INFO "i2c_pxa_sendbytes: timeout -> forcing reset\n");
-+#endif
-+ adap->reset();
-+ return I2C_RETRY;
-+ }
-+ }
-+ return (wrcount);
-+}
-+
-+
-+static inline int i2c_pxa_set_ctrl_byte(struct i2c_algo_pxa_data * adap, struct i2c_msg *msg)
-+{
-+ u16 flags = msg->flags;
-+ u8 addr;
-+ addr = (u8) ( (0x7f & msg->addr) << 1 );
-+ if (flags & I2C_M_RD )
-+ addr |= 1;
-+ if (flags & I2C_M_REV_DIR_ADDR )
-+ addr ^= 1;
-+ adap->write_byte(addr);
-+ return 0;
-+}
-+
-+static int i2c_pxa_do_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
-+{
-+ struct i2c_algo_pxa_data * adap;
-+ struct i2c_msg *pmsg=NULL;
-+ int i;
-+ int ret=0, timeout;
-+
-+ adap = i2c_adap->algo_data;
-+
-+ timeout = adap->wait_bus_not_busy();
-+
-+ if (timeout) {
-+ return I2C_RETRY;
-+ }
-+
-+ for (i = 0;ret >= 0 && i < num; i++) {
-+ int last = i + 1 == num;
-+ pmsg = &msgs[i];
-+
-+ ret = i2c_pxa_set_ctrl_byte(adap,pmsg);
-+
-+ /* Send START */
-+ if (i == 0) {
-+ adap->start();
-+ }else{
-+ adap->repeat_start();
-+ }
-+
-+ adap->transfer(0, I2C_TRANSMIT, 0);
-+
-+ /* Wait for ITE (transmit empty) */
-+ timeout = adap->wait_for_interrupt(I2C_TRANSMIT);
-+
-+#ifdef DEBUG
-+ /* Check for ACK (bus error) */
-+ if (timeout==BUS_ERROR){
-+ printk(KERN_INFO "i2c_pxa_do_xfer: bus error -> forcing reset\n");
-+ adap->reset();
-+ return I2C_RETRY;
-+ } else
-+#endif
-+ if (timeout == -ERESTARTSYS) {
-+ adap->abort();
-+ return timeout;
-+ } else
-+ if (timeout) {
-+#ifdef DEBUG
-+ printk(KERN_INFO "i2c_pxa_do_xfer: timeout -> forcing reset\n");
-+#endif
-+ adap->reset();
-+ return I2C_RETRY;
-+ }
-+/* FIXME: handle arbitration... */
-+#if 0
-+ /* Check for bus arbitration loss */
-+ if (adap->arbitration_loss()){
-+ printk("Arbitration loss detected \n");
-+ adap->reset();
-+ return I2C_RETRY;
-+ }
-+#endif
-+
-+ /* Read */
-+ if (pmsg->flags & I2C_M_RD) {
-+ /* read bytes into buffer*/
-+ ret = i2c_pxa_readbytes(i2c_adap, pmsg->buf, pmsg->len, last);
-+#if DEBUG > 2
-+ if (ret != pmsg->len) {
-+ printk(KERN_INFO"i2c_pxa_do_xfer: read %d/%d bytes.\n",
-+ ret, pmsg->len);
-+ } else {
-+ printk(KERN_INFO"i2c_pxa_do_xfer: read %d bytes.\n",ret);
-+ }
-+#endif
-+ } else { /* Write */
-+ ret = i2c_pxa_sendbytes(i2c_adap, pmsg->buf, pmsg->len, last);
-+#if DEBUG > 2
-+ if (ret != pmsg->len) {
-+ printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d/%d bytes.\n",
-+ ret, pmsg->len);
-+ } else {
-+ printk(KERN_INFO"i2c_pxa_do_xfer: wrote %d bytes.\n",ret);
-+ }
-+#endif
-+ }
-+ }
-+
-+ if (ret<0){
-+ return ret;
-+ }else{
-+ return i;
-+ }
-+}
-+
-+static int i2c_pxa_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
-+{
-+ int retval = i2c_pxa_valid_messages( msgs, num);
-+ if( retval > 0)
-+ {
-+ int i;
-+ for (i=i2c_adap->retries; i>=0; i--){
-+ int retval = i2c_pxa_do_xfer(i2c_adap,msgs,num);
-+ if (retval!=I2C_RETRY){
-+ return retval;
-+ }
-+ if( i2c_debug)printk(KERN_INFO"Retrying transmission \n");
-+ udelay(100);
-+ }
-+ if( i2c_debug)printk(KERN_INFO"Retried %i times\n",i2c_adap->retries);
-+ return -EREMOTEIO;
-+
-+ }
-+ return retval;
-+}
-+
-+struct i2c_algorithm i2c_pxa_algorithm = {
-+ name: "PXA-I2C-Algorithm",
-+ id: I2C_ALGO_PXA,
-+ master_xfer: i2c_pxa_xfer,
-+ smbus_xfer: NULL,
-+ slave_send: NULL,
-+ slave_recv: NULL,
-+ algo_control: NULL,
-+};
-+
-+/*
-+ * registering functions to load algorithms at runtime
-+ */
-+int i2c_pxa_add_bus(struct i2c_adapter *i2c_adap)
-+{
-+ struct i2c_algo_pxa_data *adap = i2c_adap->algo_data;
-+
-+ printk(KERN_INFO"I2C: Adding %s.\n", i2c_adap->name);
-+
-+ i2c_adap->algo = &i2c_pxa_algorithm;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ /* register new adapter to i2c module... */
-+ i2c_add_adapter(i2c_adap);
-+
-+ adap->reset();
-+
-+ /* scan bus */
-+ if (pxa_scan) {
-+ int i;
-+ printk(KERN_INFO "I2C: Scanning bus ");
-+ for (i = 0x02; i < 0xff; i+=2) {
-+ if( i==(I2C_PXA_SLAVE_ADDR<<1)) continue;
-+
-+ if (adap->wait_bus_not_busy()) {
-+ printk(KERN_INFO "I2C: scanning bus %s - TIMEOUTed.\n",
-+ i2c_adap->name);
-+ return -EIO;
-+ }
-+ adap->write_byte(i);
-+ adap->start();
-+ adap->transfer(0, I2C_TRANSMIT, 0);
-+
-+ if ((adap->wait_for_interrupt(I2C_TRANSMIT) != BUS_ERROR)) {
-+ printk("(%02x)",i>>1);
-+ adap->abort();
-+ } else {
-+// printk(".");
-+ adap->stop();
-+ }
-+ udelay(adap->udelay);
-+ }
-+ printk("\n");
-+ }
-+ return 0;
-+}
-+
-+int i2c_pxa_del_bus(struct i2c_adapter *i2c_adap)
-+{
-+ int res;
-+ if ((res = i2c_del_adapter(i2c_adap)) < 0)
-+ return res;
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ printk(KERN_INFO "I2C: Removing %s.\n", i2c_adap->name);
-+
-+ return 0;
-+}
-+
-+static int __init i2c_algo_pxa_init (void)
-+{
-+ printk(KERN_INFO "I2C: PXA algorithm module loaded.\n");
-+ return 0;
-+}
-+
-+EXPORT_SYMBOL(i2c_pxa_add_bus);
-+EXPORT_SYMBOL(i2c_pxa_del_bus);
-+
-+MODULE_PARM(pxa_scan, "i");
-+MODULE_PARM_DESC(pxa_scan, "Scan for active chips on the bus");
-+
-+MODULE_AUTHOR("Intrinsyc Software Inc.");
-+MODULE_LICENSE("GPL");
-+
-+module_init(i2c_algo_pxa_init);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/i2c/i2c-pxa.h 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,76 @@
-+/*
-+ * i2c_pxa.h
-+ *
-+ * Copyright (C) 2002 Intrinsyc Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ */
-+#ifndef _I2C_PXA_H_
-+#define _I2C_PXA_H_
-+
-+struct i2c_algo_pxa_data
-+{
-+ void (*write_byte) (u8 value);
-+ u8 (*read_byte) (void);
-+ void (*start) (void);
-+ void (*repeat_start) (void);
-+ void (*stop) (void);
-+ void (*abort) (void);
-+ int (*wait_bus_not_busy) (void);
-+ int (*wait_for_interrupt) (int wait_type);
-+ void (*transfer) (int lastbyte, int receive, int midbyte);
-+ void (*reset) (void);
-+
-+ int udelay;
-+ int timeout;
-+};
-+
-+#define DEF_TIMEOUT 3
-+#define BUS_ERROR (-EREMOTEIO)
-+#define ACK_DELAY 0 /* time to delay before checking bus error */
-+#define MAX_MESSAGES 65536 /* maximum number of messages to send */
-+
-+#define I2C_SLEEP_TIMEOUT 2 /* time to sleep for on i2c transactions */
-+#define I2C_RETRY (-2000) /* an error has occurred retry transmit */
-+#define I2C_TRANSMIT 1
-+#define I2C_RECEIVE 0
-+#define I2C_PXA_SLAVE_ADDR 0x1 /* slave pxa unit address */
-+#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE) /* ICR initialization value */
-+/* ICR initialize bit values
-+*
-+* 15. FM 0 (100 Khz operation)
-+* 14. UR 0 (No unit reset)
-+* 13. SADIE 0 (Disables the unit from interrupting on slave addresses
-+* matching its slave address)
-+* 12. ALDIE 0 (Disables the unit from interrupt when it loses arbitration
-+* in master mode)
-+* 11. SSDIE 0 (Disables interrupts from a slave stop detected, in slave mode)
-+* 10. BEIE 1 (Enable interrupts from detected bus errors, no ACK sent)
-+* 9. IRFIE 1 (Enable interrupts from full buffer received)
-+* 8. ITEIE 1 (Enables the I2C unit to interrupt when transmit buffer empty)
-+* 7. GCD 1 (Disables i2c unit response to general call messages as a slave)
-+* 6. IUE 0 (Disable unit until we change settings)
-+* 5. SCLE 1 (Enables the i2c clock output for master mode (drives SCL)
-+* 4. MA 0 (Only send stop with the ICR stop bit)
-+* 3. TB 0 (We are not transmitting a byte initially)
-+* 2. ACKNAK 0 (Send an ACK after the unit receives a byte)
-+* 1. STOP 0 (Do not send a STOP)
-+* 0. START 0 (Do not send a START)
-+*
-+*/
-+
-+#define I2C_ISR_INIT 0x7FF /* status register init */
-+/* I2C status register init values
-+ *
-+ * 10. BED 1 (Clear bus error detected)
-+ * 9. SAD 1 (Clear slave address detected)
-+ * 7. IRF 1 (Clear IDBR Receive Full)
-+ * 6. ITE 1 (Clear IDBR Transmit Empty)
-+ * 5. ALD 1 (Clear Arbitration Loss Detected)
-+ * 4. SSD 1 (Clear Slave Stop Detected)
-+ */
-+
-+#endif
---- linux-2.4.25/drivers/misc/Config.in~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/misc/Config.in 2004-03-31 17:15:11.000000000 +0200
-@@ -13,5 +13,6 @@
- dep_tristate 'Support for UCB1200 / UCB1300' CONFIG_MCP_UCB1200 $CONFIG_MCP
- dep_tristate ' Audio / Telephony interface support' CONFIG_MCP_UCB1200_AUDIO $CONFIG_MCP_UCB1200 $CONFIG_SOUND
- dep_tristate ' Touchscreen interface support' CONFIG_MCP_UCB1200_TS $CONFIG_MCP_UCB1200
-+dep_tristate ' UCB1400 Touchscreen support' CONFIG_MCP_UCB1400_TS $CONFIG_ARCH_PXA $CONFIG_SOUND
-
- endmenu
---- linux-2.4.25/drivers/misc/Makefile~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/misc/Makefile 2004-03-31 17:15:11.000000000 +0200
-@@ -11,13 +11,15 @@
-
- O_TARGET := misc.o
-
--export-objs := mcp-core.o mcp-sa1100.o ucb1x00-core.o
-+export-objs := mcp-core.o mcp-sa1100.o mcp-pxa.o \
-+ ucb1x00-core.o
-
--obj-$(CONFIG_MCP) += mcp-core.o
--obj-$(CONFIG_MCP_SA1100) += mcp-sa1100.o
-+obj-$(CONFIG_MCP_SA1100) += mcp-core.o mcp-sa1100.o
- obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
- obj-$(CONFIG_MCP_UCB1200_AUDIO) += ucb1x00-audio.o
- obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o
-+obj-$(CONFIG_MCP_UCB1400_TS) += mcp-pxa.o ucb1x00-core.o ucb1x00-ts.o
-+obj-$(CONFIG_PXA_CERF_PDA) += cerf_ucb1400gpio.o
-
- include $(TOPDIR)/Rules.make
-
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/misc/cerf_ucb1400gpio.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,189 @@
-+/*
-+ * cerf_ucb1400gpio.c
-+ *
-+ * UCB1400 GPIO control stuff for the cerf.
-+ *
-+ * Copyright (C) 2002 Intrinsyc Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * History:
-+ * Mar 2002: Initial version [FB]
-+ * Jun 2002: Removed ac97 dependency [FB]
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/ctype.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+
-+#include <asm/system.h>
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+
-+#include "ucb1x00.h"
-+
-+/*
-+ * Set this to zero to remove all the debug statements via
-+ * dead code elimination.
-+ */
-+#define DEBUGGING 0
-+
-+#if DEBUGGING
-+static unsigned int ucb_debug = DEBUGGING;
-+#else
-+#define ucb_debug 0
-+#endif
-+
-+#define UP 1
-+#define DOWN 0
-+
-+/* -- -- */
-+
-+void cerf_ucb1400gpio_lcd_enable( void)
-+{
-+ struct ucb1x00 * ucb = ucb1x00_get();
-+ if( ucb_debug > 2) printk( KERN_INFO "Enabling LCD.\n");
-+ /* Enable [not] LCD_RESET to enable the LCD display */
-+ ucb1x00_io_set_dir( ucb, 0, UCB1400_GPIO_LCD_RESET);
-+ ucb1x00_io_write( ucb, UCB1400_GPIO_LCD_RESET, 0);
-+
-+ /* Enable the Contrast circuit */
-+ ucb1x00_io_set_dir( ucb, 0, UCB1400_GPIO_CONT_ENA);
-+ ucb1x00_io_write( ucb, UCB1400_GPIO_CONT_ENA, 0);
-+}
-+
-+void cerf_ucb1400gpio_lcd_disable( void)
-+{
-+ struct ucb1x00 * ucb = ucb1x00_get();
-+ if( ucb_debug > 2) printk( KERN_INFO "Disabling LCD.\n");
-+ /* Disable the Contrast circuit */
-+ ucb1x00_io_set_dir( ucb, 0, UCB1400_GPIO_CONT_ENA);
-+ ucb1x00_io_write( ucb, 0, UCB1400_GPIO_CONT_ENA);
-+
-+ /* Disable [not] LCD_RESET to enable the LCD display */
-+ ucb1x00_io_set_dir( ucb, 0, UCB1400_GPIO_LCD_RESET);
-+ ucb1x00_io_write( ucb, 0, UCB1400_GPIO_LCD_RESET);
-+}
-+
-+void cerf_ucb1400gpio_lcd_contrast_step( int direction)
-+{
-+ struct ucb1x00 * ucb = ucb1x00_get();
-+ // Assert the chip select and the up modifier
-+ ucb1x00_io_set_dir( ucb, 0,
-+ (UCB1400_GPIO_CONT_CS |
-+ UCB1400_GPIO_CONT_DOWN |
-+ UCB1400_GPIO_CONT_INC));
-+
-+ if( direction == DOWN)
-+ {
-+ if( ucb_debug > 3)
-+ printk(KERN_INFO "cerf_ucb1400gpio_lcd_contrast_step: "
-+ "stepping up\n");
-+ //goin' up
-+ ucb1x00_io_write( ucb, UCB1400_GPIO_CONT_DOWN, 0);
-+ }
-+ else
-+ {
-+ if( ucb_debug > 3)
-+ printk(KERN_INFO "cerf_ucb1400gpio_lcd_contrast_step: "
-+ "stepping down\n");
-+ //goin' down
-+ ucb1x00_io_write( ucb, 0, UCB1400_GPIO_CONT_DOWN);
-+ }
-+
-+ ucb1x00_io_write( ucb, 0, UCB1400_GPIO_CONT_CS);
-+
-+ // Assert the line up, down then up again
-+ ucb1x00_io_write( ucb, 0, UCB1400_GPIO_CONT_INC);
-+ udelay(1);
-+ ucb1x00_io_write( ucb, UCB1400_GPIO_CONT_INC, 0);
-+ udelay(1);
-+ ucb1x00_io_write( ucb, 0, UCB1400_GPIO_CONT_INC);
-+
-+ // Deassert the chip select and the up modifier
-+ ucb1x00_io_write( ucb, 0, UCB1400_GPIO_CONT_DOWN);
-+ ucb1x00_io_write( ucb, UCB1400_GPIO_CONT_CS, 0);
-+}
-+
-+/* -- -- */
-+
-+void cerf_ucb1400gpio_irda_enable( void)
-+{
-+ struct ucb1x00 * ucb = ucb1x00_get();
-+ printk( KERN_INFO "Enabling IRDA.\n");
-+ /* Enable IRDA (active low) */
-+ ucb1x00_io_set_dir( ucb, 0, UCB1400_GPIO_IRDA_ENABLE);
-+ ucb1x00_io_write( ucb, 0, UCB1400_GPIO_IRDA_ENABLE);
-+}
-+
-+void cerf_ucb1400gpio_irda_disable( void)
-+{
-+ struct ucb1x00 * ucb = ucb1x00_get();
-+ printk( KERN_INFO "Disabling IRDA.\n");
-+ /* Disable IRDA (active low) */
-+ ucb1x00_io_set_dir( ucb, 0, UCB1400_GPIO_IRDA_ENABLE);
-+ ucb1x00_io_write( ucb, UCB1400_GPIO_IRDA_ENABLE, 0);
-+}
-+
-+/* -- -- */
-+
-+void cerf_ucb1400gpio_bt_enable( void)
-+{
-+ struct ucb1x00 * ucb = ucb1x00_get();
-+ printk( KERN_INFO "Enabling Bluetooth.\n");
-+ /* Enable BT (active low) */
-+ ucb1x00_io_set_dir( ucb, 0, UCB1400_GPIO_BT_ENABLE);
-+ ucb1x00_io_write( ucb, 0, UCB1400_GPIO_BT_ENABLE);
-+}
-+
-+void cerf_ucb1400gpio_bt_disable( void)
-+{
-+ struct ucb1x00 * ucb = ucb1x00_get();
-+ printk( KERN_INFO "Disabling Bluetooth.\n");
-+ /* Disable BT (active low) */
-+ ucb1x00_io_set_dir( ucb, 0, UCB1400_GPIO_BT_ENABLE);
-+ ucb1x00_io_write( ucb, UCB1400_GPIO_BT_ENABLE, 0);
-+}
-+
-+/* -- -- */
-+
-+/* -- Enable Bluetooth and IRDA automatically via pseudo module -- */
-+#if defined(CONFIG_BLUEZ) || defined(CONFIG_IRDA)
-+static int __init cerf_ucb1400gpio_module_init (void)
-+{
-+#ifdef CONFIG_BLUEZ
-+ cerf_ucb1400gpio_bt_enable();
-+#endif
-+
-+#ifdef CONFIG_IRDA
-+ cerf_ucb1400gpio_irda_enable();
-+#endif
-+ return 0;
-+}
-+
-+static void __exit cerf_ucb1400gpio_module_exit (void)
-+{
-+#ifdef CONFIG_BLUEZ
-+ cerf_ucb1400gpio_bt_disable();
-+#endif
-+
-+#ifdef CONFIG_IRDA
-+ cerf_ucb1400gpio_irda_disable();
-+#endif
-+}
-+
-+module_init(cerf_ucb1400gpio_module_init);
-+module_exit(cerf_ucb1400gpio_module_exit);
-+#endif
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/misc/mcp-pxa.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,57 @@
-+/*
-+ * linux/drivers/misc/mcp-pxa.c
-+ *
-+ * 2002-01-10 Jeff Sutherland <jeffs@accelent.com>
-+ *
-+ * 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.
-+ *
-+ * NOTE: This is a quick hack to gain access to the aclink codec's
-+ * touch screen facility. Its audio is handled by a separate
-+ * (non-mcp) driver at the present time.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/ac97_codec.h>
-+
-+#include "mcp.h"
-+
-+
-+extern int pxa_ac97_get(struct ac97_codec **codec);
-+extern void pxa_ac97_put(void);
-+
-+
-+struct mcp *mcp_get(void)
-+{
-+ struct ac97_codec *codec;
-+ if (pxa_ac97_get(&codec) < 0)
-+ return NULL;
-+ return (struct mcp *)codec;
-+}
-+
-+void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val)
-+{
-+ struct ac97_codec *codec = (struct ac97_codec *)mcp;
-+ codec->codec_write(codec, reg, val);
-+}
-+
-+unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg)
-+{
-+ struct ac97_codec *codec = (struct ac97_codec *)mcp;
-+ return codec->codec_read(codec, reg);
-+}
-+
-+void mcp_enable(struct mcp *mcp)
-+{
-+ /*
-+ * Should we do something here to make sure the aclink
-+ * codec is alive???
-+ * A: not for now --NP
-+ */
-+}
-+
-+void mcp_disable(struct mcp *mcp)
-+{
-+}
---- linux-2.4.25/drivers/misc/mcp.h~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/misc/mcp.h 2004-03-31 17:15:11.000000000 +0200
-@@ -10,16 +10,22 @@
- #ifndef MCP_H
- #define MCP_H
-
-+#ifdef CONFIG_ARCH_SA1100
-+#include <asm/dma.h>
-+#endif
-+
- struct mcp {
- struct module *owner;
- spinlock_t lock;
- int use_count;
- unsigned int sclk_rate;
- unsigned int rw_timeout;
-+#ifdef CONFIG_ARCH_SA1100
- dma_device_t dma_audio_rd;
- dma_device_t dma_audio_wr;
- dma_device_t dma_telco_rd;
- dma_device_t dma_telco_wr;
-+#endif
- void (*set_telecom_divisor)(struct mcp *, unsigned int);
- void (*set_audio_divisor)(struct mcp *, unsigned int);
- void (*reg_write)(struct mcp *, unsigned int, unsigned int);
---- linux-2.4.25/drivers/misc/ucb1x00-core.c~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/misc/ucb1x00-core.c 2004-03-31 17:15:11.000000000 +0200
-@@ -23,12 +23,18 @@
- #include <linux/errno.h>
- #include <linux/interrupt.h>
- #include <linux/pm.h>
-+#include <linux/tqueue.h>
-+#include <linux/config.h>
-
--#include <asm/dma.h>
--#include <asm/hardware.h>
- #include <asm/irq.h>
- #include <asm/mach-types.h>
-+
-+#ifdef CONFIG_ARCH_SA1100
-+#include <asm/arch/assabet.h>
- #include <asm/arch/shannon.h>
-+#endif
-+
-+#include <asm/hardware.h>
-
- #include "ucb1x00.h"
-
-@@ -155,6 +161,10 @@
- *
- * If called for a synchronised ADC conversion, it may sleep
- * with the ADC semaphore held.
-+ *
-+ * See ucb1x00.h for definition of the UCB_ADC_DAT macro. It
-+ * addresses a bug in the ucb1200/1300 which, of course, Philips
-+ * decided to finally fix in the ucb1400 ;-) -jws
- */
- unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync)
- {
-@@ -218,22 +228,75 @@
- * Since we need to read an internal register, we must re-enable
- * SIBCLK to talk to the chip. We leave the clock running until
- * we have finished processing all interrupts from the chip.
-+ *
-+ * A restriction with interrupts exists when using the ucb1400, as
-+ * the codec read/write routines may sleep while waiting for codec
-+ * access completion and uses semaphores for access control to the
-+ * AC97 bus. A complete codec read cycle could take anywhere from
-+ * 60 to 100uSec so we *definitely* don't want to spin inside the
-+ * interrupt handler waiting for codec access. So, we handle the
-+ * interrupt by scheduling a RT kernel thread to run in process
-+ * context instead of interrupt context.
- */
--static void ucb1x00_irq(int irqnr, void *devid, struct pt_regs *regs)
-+
-+static int ucb1x00_thread(void *_ucb)
- {
-- struct ucb1x00 *ucb = devid;
-+ struct task_struct *tsk = current;
-+ DECLARE_WAITQUEUE(wait, tsk);
-+ struct ucb1x00 *ucb = _ucb;
- struct ucb1x00_irq *irq;
- unsigned int isr, i;
-
-- ucb1x00_enable(ucb);
-- isr = ucb1x00_reg_read(ucb, UCB_IE_STATUS);
-- ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr);
-- ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
-+ ucb->rtask = tsk;
-
-- for (i = 0, irq = ucb->irq_handler; i < 16 && isr; i++, isr >>= 1, irq++)
-- if (isr & 1 && irq->fn)
-- irq->fn(i, irq->devid);
-- ucb1x00_disable(ucb);
-+ daemonize();
-+ reparent_to_init();
-+ tsk->tty = NULL;
-+ tsk->policy = SCHED_FIFO;
-+ tsk->rt_priority = 1;
-+ strcpy(tsk->comm, "kUCB1x00d");
-+
-+ /* only want to receive SIGKILL */
-+ spin_lock_irq(&tsk->sigmask_lock);
-+ siginitsetinv(&tsk->blocked, sigmask(SIGKILL));
-+ recalc_sigpending(tsk);
-+ spin_unlock_irq(&tsk->sigmask_lock);
-+
-+ add_wait_queue(&ucb->irq_wait, &wait);
-+ set_task_state(tsk, TASK_INTERRUPTIBLE);
-+ complete(&ucb->complete);
-+
-+ for (;;) {
-+ if (signal_pending(tsk))
-+ break;
-+ enable_irq(ucb->irq);
-+ schedule();
-+
-+ ucb1x00_enable(ucb);
-+ isr = ucb1x00_reg_read(ucb, UCB_IE_STATUS);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
-+
-+ for (i = 0, irq = ucb->irq_handler;
-+ i < 16 && isr;
-+ i++, isr >>= 1, irq++)
-+ if (isr & 1 && irq->fn)
-+ irq->fn(i, irq->devid);
-+ ucb1x00_disable(ucb);
-+
-+ set_task_state(tsk, TASK_INTERRUPTIBLE);
-+ }
-+
-+ remove_wait_queue(&ucb->irq_wait, &wait);
-+ ucb->rtask = NULL;
-+ complete_and_exit(&ucb->complete, 0);
-+}
-+
-+static void ucb1x00_irq(int irqnr, void *devid, struct pt_regs *regs)
-+{
-+ struct ucb1x00 *ucb = devid;
-+ disable_irq(irqnr);
-+ wake_up(&ucb->irq_wait);
- }
-
- /**
-@@ -291,6 +354,11 @@
- spin_lock_irqsave(&ucb->lock, flags);
-
- ucb1x00_enable(ucb);
-+
-+ /* This prevents spurious interrupts on the UCB1400 */
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 1 << idx);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
-+
- if (edges & UCB_RISING) {
- ucb->irq_ris_enbl |= 1 << idx;
- ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
-@@ -456,6 +524,7 @@
- unsigned int irq_gpio_pin = 0;
- int irq, default_irq = NO_IRQ;
-
-+#ifdef CONFIG_ARCH_SA1100
- if (machine_is_adsbitsy())
- default_irq = IRQ_GPCIN4;
-
-@@ -514,12 +583,40 @@
- }
- #endif
-
-+#endif /* CONFIG_ARCH_SA1100 */
-+
-+#ifdef CONFIG_ARCH_PXA_IDP
-+ if (machine_is_pxa_idp()) {
-+ default_irq = TOUCH_PANEL_IRQ;
-+ irq_gpio_pin = IRQ_TO_GPIO_2_80(TOUCH_PANEL_IRQ);
-+ GPDR(irq_gpio_pin) &= ~GPIO_bit(irq_gpio_pin);
-+ }
-+#endif
-+
-+#ifdef CONFIG_ARCH_TRIZEPS2
-+ if (machine_is_trizeps2()) {
-+ default_irq = TOUCH_PANEL_IRQ;
-+ irq_gpio_pin = IRQ_TO_GPIO_2_80(TOUCH_PANEL_IRQ);
-+ GPDR(irq_gpio_pin) &= ~GPIO_bit(irq_gpio_pin);
-+ }
-+#endif
-+
-+
-+#ifdef CONFIG_PXA_CERF_PDA
-+ if (machine_is_pxa_cerf()) {
-+ irq_gpio_pin = CERF_GPIO_UCB1400_IRQ;
-+ }
-+#endif
-+
- /*
- * Eventually, this will disappear.
- */
- if (irq_gpio_pin)
-+#ifdef CONFIG_ARCH_PXA_IDP
-+ set_GPIO_IRQ_edge(irq_gpio_pin, GPIO_FALLING_EDGE);
-+#else
- set_GPIO_IRQ_edge(irq_gpio_pin, GPIO_RISING_EDGE);
--
-+#endif
- irq = ucb1x00_detect_irq(ucb);
- if (irq != NO_IRQ) {
- if (default_irq != NO_IRQ && irq != default_irq)
-@@ -541,21 +638,7 @@
-
- struct ucb1x00 *my_ucb;
-
--/**
-- * ucb1x00_get - get the UCB1x00 structure describing a chip
-- * @ucb: UCB1x00 structure describing chip
-- *
-- * Return the UCB1x00 structure describing a chip.
-- *
-- * FIXME: Currently very noddy indeed, which currently doesn't
-- * matter since we only support one chip.
-- */
--struct ucb1x00 *ucb1x00_get(void)
--{
-- return my_ucb;
--}
--
--static int __init ucb1x00_init(void)
-+static int ucb1x00_init_helper(void)
- {
- struct mcp *mcp;
- unsigned int id;
-@@ -568,23 +651,28 @@
- mcp_enable(mcp);
- id = mcp_reg_read(mcp, UCB_ID);
-
-- if (id != UCB_ID_1200 && id != UCB_ID_1300) {
-+ if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_1400) {
- printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id);
- goto out;
- }
-
-+ /* distinguish between UCB1400 revs 1B and 2A */
-+ if (id == UCB_ID_1400 && mcp_reg_read(mcp, 0x00) == 0x002a)
-+ id = UCB_ID_1400_BUGGY;
-+
- my_ucb = kmalloc(sizeof(struct ucb1x00), GFP_KERNEL);
- ret = -ENOMEM;
- if (!my_ucb)
- goto out;
-
-+#ifdef CONFIG_ARCH_SA1100
- if (machine_is_shannon()) {
- /* reset the codec */
- GPDR |= SHANNON_GPIO_CODEC_RESET;
- GPCR = SHANNON_GPIO_CODEC_RESET;
- GPSR = SHANNON_GPIO_CODEC_RESET;
--
- }
-+#endif
-
- memset(my_ucb, 0, sizeof(struct ucb1x00));
-
-@@ -599,13 +687,12 @@
- if (ret)
- goto out;
-
-+ init_waitqueue_head(&my_ucb->irq_wait);
- ret = request_irq(my_ucb->irq, ucb1x00_irq, 0, "UCB1x00", my_ucb);
- if (ret) {
- printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
- my_ucb->irq, ret);
-- kfree(my_ucb);
-- my_ucb = NULL;
-- goto out;
-+ goto irq_err;
- }
-
- #ifdef CONFIG_PM
-@@ -616,16 +703,55 @@
- my_ucb->pmdev->data = my_ucb;
- #endif
-
-+ init_completion(&my_ucb->complete);
-+ ret = kernel_thread(ucb1x00_thread, my_ucb, CLONE_FS | CLONE_FILES);
-+ if (ret >= 0) {
-+ wait_for_completion(&my_ucb->complete);
-+ ret = 0;
-+ goto out;
-+ }
-+
-+ free_irq(my_ucb->irq, my_ucb);
-+irq_err:
-+ kfree(my_ucb);
-+ my_ucb = NULL;
- out:
- mcp_disable(mcp);
- no_mcp:
- return ret;
- }
-
-+/**
-+ * ucb1x00_get - get the UCB1x00 structure describing a chip
-+ * @ucb: UCB1x00 structure describing chip
-+ *
-+ * Return the UCB1x00 structure describing a chip.
-+ *
-+ * FIXME: Currently very noddy indeed, which currently doesn't
-+ * matter since we only support one chip.
-+ */
-+struct ucb1x00 *ucb1x00_get(void)
-+{
-+ if( !my_ucb) ucb1x00_init_helper();
-+
-+ return my_ucb;
-+}
-+
-+static int __init ucb1x00_init(void)
-+{
-+ /* check if driver is already initialized */
-+ if( my_ucb) return 0;
-+
-+ return ucb1x00_init_helper();
-+}
-+
- static void __exit ucb1x00_exit(void)
- {
-+ send_sig(SIGKILL, my_ucb->rtask, 1);
-+ wait_for_completion(&my_ucb->complete);
- free_irq(my_ucb->irq, my_ucb);
- kfree(my_ucb);
-+ my_ucb = 0;
- }
-
- module_init(ucb1x00_init);
---- linux-2.4.25/drivers/misc/ucb1x00-ts.c~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/misc/ucb1x00-ts.c 2004-03-31 17:15:11.000000000 +0200
-@@ -35,7 +35,11 @@
- /*
- * Define this if you want the UCB1x00 stuff to talk to the input layer
- */
-+#ifdef CONFIG_INPUT
-+#define USE_INPUT
-+#else
- #undef USE_INPUT
-+#endif
-
- #ifndef USE_INPUT
-
-@@ -73,7 +77,7 @@
- struct pm_dev *pmdev;
- #endif
-
-- wait_queue_head_t irq_wait;
-+ struct semaphore irq_wait;
- struct semaphore sem;
- struct completion init_exit;
- struct task_struct *rtask;
-@@ -259,6 +263,11 @@
- input_report_abs(&ts->idev, ABS_PRESSURE, pressure);
- }
-
-+static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
-+{
-+ input_report_abs(&ts->idev, ABS_PRESSURE, 0);
-+}
-+
- static int ucb1x00_ts_open(struct input_dev *idev)
- {
- struct ucb1x00_ts *ts = (struct ucb1x00_ts *)idev;
-@@ -304,10 +313,15 @@
- */
- static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts)
- {
-- ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-- UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
-- UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
-- UCB_TS_CR_MODE_INT);
-+ if (ts->ucb->id == UCB_ID_1400_BUGGY)
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
-+ UCB_TS_CR_MODE_INT);
-+ else
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
-+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
-+ UCB_TS_CR_MODE_INT);
- }
-
- /*
-@@ -397,13 +411,13 @@
- /*
- * This is a RT kernel thread that handles the ADC accesses
- * (mainly so we can use semaphores in the UCB1200 core code
-- * to serialise accesses to the ADC).
-+ * to serialise accesses to the ADC). The UCB1400 access
-+ * functions are expected to be able to sleep as well.
- */
- static int ucb1x00_thread(void *_ts)
- {
- struct ucb1x00_ts *ts = _ts;
- struct task_struct *tsk = current;
-- DECLARE_WAITQUEUE(wait, tsk);
- int valid;
-
- ts->rtask = tsk;
-@@ -429,10 +443,8 @@
-
- valid = 0;
-
-- add_wait_queue(&ts->irq_wait, &wait);
- for (;;) {
- unsigned int x, y, p, val;
-- signed long timeout;
-
- ts->restart = 0;
-
-@@ -457,8 +469,6 @@
- val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
-
- if (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW)) {
-- set_task_state(tsk, TASK_INTERRUPTIBLE);
--
- ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
- ucb1x00_disable(ts->ucb);
-
-@@ -471,7 +481,15 @@
- valid = 0;
- }
-
-- timeout = MAX_SCHEDULE_TIMEOUT;
-+ /*
-+ * Since ucb1x00_enable_irq() might sleep due
-+ * to the way the UCB1400 regs are accessed, we
-+ * can't use set_task_state() before that call,
-+ * and not changing state before enabling the
-+ * interrupt is racy. A semaphore solves all
-+ * those issues quite nicely.
-+ */
-+ down_interruptible(&ts->irq_wait);
- } else {
- ucb1x00_disable(ts->ucb);
-
-@@ -486,16 +504,13 @@
- }
-
- set_task_state(tsk, TASK_INTERRUPTIBLE);
-- timeout = HZ / 100;
-+ schedule_timeout(HZ / 100);
- }
-
-- schedule_timeout(timeout);
- if (signal_pending(tsk))
- break;
- }
-
-- remove_wait_queue(&ts->irq_wait, &wait);
--
- ts->rtask = NULL;
- ucb1x00_ts_evt_clear(ts);
- complete_and_exit(&ts->init_exit, 0);
-@@ -509,7 +524,7 @@
- {
- struct ucb1x00_ts *ts = id;
- ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
-- wake_up(&ts->irq_wait);
-+ up(&ts->irq_wait);
- }
-
- static int ucb1x00_ts_startup(struct ucb1x00_ts *ts)
-@@ -525,7 +540,7 @@
- if (ts->rtask)
- panic("ucb1x00: rtask running?");
-
-- init_waitqueue_head(&ts->irq_wait);
-+ sema_init(&ts->irq_wait, 0);
- ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts);
- if (ret < 0)
- goto out;
-@@ -585,7 +600,7 @@
- * after sleep.
- */
- ts->restart = 1;
-- wake_up(&ts->irq_wait);
-+ up(&ts->irq_wait);
- }
- return 0;
- }
---- linux-2.4.25/drivers/misc/ucb1x00.h~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/misc/ucb1x00.h 2004-03-31 17:15:11.000000000 +0200
-@@ -10,8 +10,47 @@
- #ifndef UCB1200_H
- #define UCB1200_H
-
-+#ifdef CONFIG_ARCH_PXA
-+
-+/* ucb1400 aclink register mappings: */
-+
-+#define UCB_IO_DATA 0x5a
-+#define UCB_IO_DIR 0x5c
-+#define UCB_IE_RIS 0x5e
-+#define UCB_IE_FAL 0x60
-+#define UCB_IE_STATUS 0x62
-+#define UCB_IE_CLEAR 0x62
-+#define UCB_TS_CR 0x64
-+#define UCB_ADC_CR 0x66
-+#define UCB_ADC_DATA 0x68
-+#define UCB_ID 0x7e /* 7c is mfr id, 7e part id (from aclink spec) */
-+
-+#define UCB_ADC_DAT(x) ((x) & 0x3ff)
-+
-+#else
-+
-+/* ucb1x00 SIB register mappings: */
-+
- #define UCB_IO_DATA 0x00
- #define UCB_IO_DIR 0x01
-+#define UCB_IE_RIS 0x02
-+#define UCB_IE_FAL 0x03
-+#define UCB_IE_STATUS 0x04
-+#define UCB_IE_CLEAR 0x04
-+#define UCB_TC_A 0x05
-+#define UCB_TC_B 0x06
-+#define UCB_AC_A 0x07
-+#define UCB_AC_B 0x08
-+#define UCB_TS_CR 0x09
-+#define UCB_ADC_CR 0x0a
-+#define UCB_ADC_DATA 0x0b
-+#define UCB_ID 0x0c
-+#define UCB_MODE 0x0d
-+
-+#define UCB_ADC_DAT(x) (((x) & 0x7fe0) >> 5)
-+
-+#endif
-+
-
- #define UCB_IO_0 (1 << 0)
- #define UCB_IO_1 (1 << 1)
-@@ -24,10 +63,6 @@
- #define UCB_IO_8 (1 << 8)
- #define UCB_IO_9 (1 << 9)
-
--#define UCB_IE_RIS 0x02
--#define UCB_IE_FAL 0x03
--#define UCB_IE_STATUS 0x04
--#define UCB_IE_CLEAR 0x04
- #define UCB_IE_ADC (1 << 11)
- #define UCB_IE_TSPX (1 << 12)
- #define UCB_IE_TSMX (1 << 13)
-@@ -36,11 +71,9 @@
-
- #define UCB_IRQ_TSPX 12
-
--#define UCB_TC_A 0x05
- #define UCB_TC_A_LOOP (1 << 7) /* UCB1200 */
- #define UCB_TC_A_AMPL (1 << 7) /* UCB1300 */
-
--#define UCB_TC_B 0x06
- #define UCB_TC_B_VOICE_ENA (1 << 3)
- #define UCB_TC_B_CLIP (1 << 4)
- #define UCB_TC_B_ATT (1 << 6)
-@@ -49,14 +82,11 @@
- #define UCB_TC_B_IN_ENA (1 << 14)
- #define UCB_TC_B_OUT_ENA (1 << 15)
-
--#define UCB_AC_A 0x07
--#define UCB_AC_B 0x08
- #define UCB_AC_B_LOOP (1 << 8)
- #define UCB_AC_B_MUTE (1 << 13)
- #define UCB_AC_B_IN_ENA (1 << 14)
- #define UCB_AC_B_OUT_ENA (1 << 15)
-
--#define UCB_TS_CR 0x09
- #define UCB_TS_CR_TSMX_POW (1 << 0)
- #define UCB_TS_CR_TSPX_POW (1 << 1)
- #define UCB_TS_CR_TSMY_POW (1 << 2)
-@@ -72,7 +102,6 @@
- #define UCB_TS_CR_TSPX_LOW (1 << 12)
- #define UCB_TS_CR_TSMX_LOW (1 << 13)
-
--#define UCB_ADC_CR 0x0a
- #define UCB_ADC_SYNC_ENA (1 << 0)
- #define UCB_ADC_VREFBYP_CON (1 << 1)
- #define UCB_ADC_INP_TSPX (0 << 2)
-@@ -87,15 +116,13 @@
- #define UCB_ADC_START (1 << 7)
- #define UCB_ADC_ENA (1 << 15)
-
--#define UCB_ADC_DATA 0x0b
- #define UCB_ADC_DAT_VAL (1 << 15)
--#define UCB_ADC_DAT(x) (((x) & 0x7fe0) >> 5)
-
--#define UCB_ID 0x0c
- #define UCB_ID_1200 0x1004
- #define UCB_ID_1300 0x1005
-+#define UCB_ID_1400 0x4304
-+#define UCB_ID_1400_BUGGY 0x4303 /* fake ID */
-
--#define UCB_MODE 0x0d
- #define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
- #define UCB_MODE_AUD_OFF_CAN (1 << 13)
-
-@@ -115,6 +142,9 @@
- unsigned int irq;
- struct semaphore adc_sem;
- spinlock_t io_lock;
-+ wait_queue_head_t irq_wait;
-+ struct completion complete;
-+ struct task_struct *rtask;
- u16 id;
- u16 io_dir;
- u16 io_out;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/mmc/Config.in 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,12 @@
-+mainmenu_option next_comment
-+comment 'MMC device drivers'
-+tristate 'Multi Media Card support' CONFIG_MMC
-+if [ "$CONFIG_MMC" = "y" -o "$CONFIG_MMC" = "m" ]; then
-+ dep_tristate 'PXA250 MMC driver' CONFIG_MMC_PXA $CONFIG_MMC
-+ dep_tristate 'MMC block driver' CONFIG_MMC_BLOCK $CONFIG_MMC
-+ if [ "$CONFIG_MMC_BLOCK" = "y" -o "$CONFIG_MMC_BLOCK" = "m" ]; then
-+ bool ' MMC partitioning support' CONFIG_MMC_PARTITIONS
-+ fi
-+fi
-+endmenu
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/mmc/Makefile 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,14 @@
-+#
-+# Makefile for MMC drivers
-+#
-+
-+export-objs := mmc_core.o
-+
-+obj-$(CONFIG_MMC) += mmc_core.o # mmc_test.o
-+obj-$(CONFIG_MMC_BLOCK) += mmc_block.o
-+obj-$(CONFIG_MMC_PXA) += mmc_pxa.o
-+# EXTRA_CFLAGS += -DCONFIG_MMC_DEBUG -DCONFIG_MMC_DEBUG_VERBOSE=2
-+
-+O_TARGET := mmcdrivers.o
-+
-+include $(TOPDIR)/Rules.make
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/mmc/error.h 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,70 @@
-+/*
-+ * linux/include/linux/mmc/error.h
-+ *
-+ * Author: Vladimir Shebordaev
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#ifndef __MMC_ERROR_H__
-+#define __MMC_ERROR_H__
-+
-+/* MMC protocol card error codes */
-+#define MMC_CARD_STATUS_OUT_OF_RANGE (1<<31)
-+#define MMC_CARD_STATUS_ADDRESS_ERROR (1<<30)
-+#define MMC_CARD_STATUS_BLOCK_LEN_ERROR (1<<29)
-+#define MMC_CARD_STATUS_ERASE_SEQ_ERROR (1<<28)
-+#define MMC_CARD_STATUS_ERASE_PARAM (1<<27)
-+#define MMC_CARD_STATUS_WP_VIOLATION (1<<26)
-+#define MMC_CARD_STATUS_CARD_IS_LOCKED (1<<25)
-+#define MMC_CARD_STATUS_LOCK_UNLOCK_FAILED (1<<24)
-+#define MMC_CARD_STATUS_COM_CRC_ERROR (1<<23)
-+#define MMC_CARD_STATUS_ILLEGAL_COMMAND (1<<22)
-+#define MMC_CARD_STATUS_CARD_ECC_FAILED (1<<21)
-+#define MMC_CARD_STATUS_CC_ERROR (1<<20)
-+#define MMC_CARD_STATUS_ERROR (1<<19)
-+#define MMC_CARD_STATUS_UNDERRUN (1<<18)
-+#define MMC_CARD_STATUS_OVERRUN (1<<17)
-+#define MMC_CARD_STATUS_CID_CSD_OVERWRITE (1<<16)
-+#define MMC_CARD_STATUS_ERASE_RESET (1<<13)
-+
-+#define MMC_ERROR( fmt, args... ) printk( KERN_ERR "%s(): " fmt, __FUNCTION__, ##args )
-+
-+/*
-+ * Error codes returned by MMC subsystem functions and
-+ * error reporting function prototypes
-+ */
-+enum _mmc_error {
-+/* controller errors */
-+ MMC_ERROR_GENERIC = -10000,
-+ MMC_ERROR_CRC_WRITE_ERROR = -10001,
-+ MMC_ERROR_CRC_READ_ERROR = -10002,
-+ MMC_ERROR_RES_CRC_ERROR = -10003,
-+ MMC_ERROR_READ_TIME_OUT = -10004,
-+ MMC_ERROR_TIME_OUT_RESPONSE = -10005,
-+ MMC_ERROR_INVAL = -10006,
-+/* protocol errors reported in card status (R1 response) */
-+ MMC_ERROR_OUT_OF_RANGE = -10007,
-+ MMC_ERROR_ADDRESS_ERROR = -10008,
-+ MMC_ERROR_BLOCK_LEN_ERROR = -10009,
-+ MMC_ERROR_ERASE_SEQ_ERROR = -10010,
-+ MMC_ERROR_ERASE_PARAM = -10011,
-+ MMC_ERROR_WP_VIOLATION = -10012,
-+ MMC_ERROR_CARD_IS_LOCKED = -10013,
-+ MMC_ERROR_LOCK_UNLOCK_FAILED = -10014,
-+ MMC_ERROR_COM_CRC_ERROR = -10015,
-+ MMC_ERROR_ILLEGAL_COMMAND = -10016,
-+ MMC_ERROR_CARD_ECC_FAILED = -10017,
-+ MMC_ERROR_CC_ERROR = -10018,
-+ MMC_ERROR_ERROR = -10019,
-+ MMC_ERROR_UNDERRUN = -10020,
-+ MMC_ERROR_OVERRUN = -10021,
-+ MMC_ERROR_CID_CSD_OVERWRITE = -10022,
-+ /* FIXME: incomplete */
-+ MMC_ERROR_ERASE_RESET = -10025
-+};
-+#endif /* __MMC_ERROR_H__ */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/mmc/mmc.h 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,463 @@
-+/*
-+ * linux/drivers/mmc/mmc.h
-+ *
-+ * Author: Vladimir Shebordaev
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#ifndef __MMC_P_H__
-+#define __MMC_P_H__
-+
-+#ifdef __KERNEL__
-+
-+#include <linux/types.h>
-+#include <linux/slab.h>
-+
-+#include <linux/spinlock.h>
-+
-+#ifdef CONFIG_PROC_FS
-+#include <linux/proc_fs.h>
-+#endif
-+
-+#include <asm/semaphore.h>
-+#include <mmc/types.h>
-+#include <mmc/mmc.h>
-+
-+#include "types.h"
-+
-+#include "error.h"
-+
-+#define MMC_CONTROLLERS_MAX (4)
-+#define MMC_CARDS_MAX (16)
-+
-+/* test device */
-+#define MMC_TEST_MAJOR (240)
-+#define MMC_TEST_TRANSFER_MODE_DEFAULT MMC_TRANSFER_MODE_BLOCK_SINGLE
-+
-+/* block device */
-+#define MMC_BLOCK_MAJOR (241) /* FIXME: MMC_MAJOR */
-+#define MMC_BLOCK_DEVICES_MAX (1<<MINORBITS) /* FIXME */
-+#define MMC_BLOCK_SECT_SIZE (512) /* FIXME */
-+#define MMC_BLOCK_PARTNBITS (3)
-+
-+/* Device minor number encoding:
-+ * [7:6] - host
-+ * [5:3] - card slot number
-+ * [2:0] - partition number
-+ */
-+#define MMC_MINOR_HOST_SHIFT (6)
-+#define MMC_MINOR_CARD_MASK (0x07)
-+
-+/*
-+ * MMC controller abstraction
-+ */
-+enum _mmc_controller_state {
-+ MMC_CONTROLLER_ABSENT = 0,
-+ MMC_CONTROLLER_FOUND,
-+ MMC_CONTROLLER_INITIALIZED,
-+ MMC_CONTROLLER_UNPLUGGED
-+};
-+
-+enum _mmc_dir {
-+ MMC_READ = 1,
-+ MMC_WRITE
-+};
-+
-+enum _mmc_buftype {
-+ MMC_USER = 1,
-+ MMC_KERNEL
-+};
-+
-+struct _mmc_data_transfer_req_rec {
-+ mmc_dir_t cmd; /* read or write operation requested */
-+ mmc_transfer_mode_t mode; /* requested data transfer mode */
-+ mmc_buftype_t type; /* whether supplied buffer resides in user or kernel space */
-+ char *buf; /* poiner to the caller's buffer */
-+ ssize_t cnt; /* number of bytes to transfer */
-+ loff_t addr; /* card address */
-+ ssize_t blksz; /* block size as for CSD[READ_BL_LEN] or CSD[WRITE_BL_LEN] */
-+ ssize_t nob; /* number of blocks to transfer */
-+};
-+
-+struct _mmc_controller_tmpl_rec {
-+ struct module *owner; /* driver module */
-+ char name[16];
-+
-+ const ssize_t block_size_max; /* max acceptable block size */
-+ const ssize_t nob_max; /* max blocks per one data transfer */
-+
-+ int (*probe)( mmc_controller_t ); /* hardware probe */
-+ int (*init)( mmc_controller_t ); /* initialize, e.g. request irq, DMA and allocate buffers */
-+ void (*remove)( mmc_controller_t ); /* free resources */
-+#if 0 /* CONFIG_HOTPLUG */
-+ void (*attach)( void ); /|* controller hotplug callbacks *|/
-+ void (*detach)( void );
-+#endif
-+#ifdef CONFIG_PM
-+ int (*suspend)( mmc_controller_t ); /* power management callbacks */
-+ void (*resume)( mmc_controller_t );
-+#endif
-+
-+/* MMC protocol macros, v3.4, p.120 */
-+ int (*init_card_stack)( mmc_controller_t );
-+ int (*update_acq)( mmc_controller_t ); /* update card stack management data */
-+ int (*single_card_acq)( mmc_controller_t );
-+ int (*check_card_stack)( mmc_controller_t );
-+ int (*setup_card)( mmc_controller_t, mmc_card_t );
-+ int (*stream_read)( mmc_controller_t, mmc_data_transfer_req_t );
-+ int (*read_block)( mmc_controller_t, mmc_data_transfer_req_t );
-+ int (*read_mblock)( mmc_controller_t, mmc_data_transfer_req_t );
-+ int (*stream_write)( mmc_controller_t, mmc_data_transfer_req_t );
-+ int (*write_block)( mmc_controller_t, mmc_data_transfer_req_t );
-+ int (*write_mblock)( mmc_controller_t, mmc_data_transfer_req_t );
-+/* TODO:
-+ int (*sg_io)( mmc_controller_t, sg_list_t );
-+*/
-+/* TODO:
-+ * 1) erase group macros
-+ * int (*erase_group)( mmc_controller_t, mmc_erase_group_info_t );
-+ * 2) write protection macros;
-+ * int (*set_write_prot)( mmc_controller_t, mmc_write_protection_info_t )
-+ * 3) lock/password management macros;
-+ */
-+};
-+
-+#ifndef MMC_CTRLR_BLKSZ_DEFAULT
-+#define MMC_CTRLR_BLKSZ_DEFAULT (512)
-+#endif
-+
-+#ifndef MMC_CTRLR_NOB_DEFAULT
-+#define MMC_CTRLR_NOB_DEFAULT (1)
-+#endif
-+
-+struct _mmc_card_rec {
-+/* public card interface */
-+ struct _mmc_card_info_rec info; /* see <linux/mmc/mmc.h> */
-+
-+/* private kernel specific data */
-+ mmc_state_t state; /* card's state as per last operation */
-+ mmc_card_t next; /* link to the stack */
-+ mmc_controller_t ctrlr; /* back reference to the controller */
-+ int usage; /* reference count */
-+ int slot; /* card's number for device reference */
-+/* TODO: async I/O queue */
-+#ifdef CONFIG_PROC_FS
-+ proc_dir_entry_t proc;
-+ char proc_name[16];
-+#endif
-+ unsigned long card_data[0] /* card specific data */
-+ __attribute__((aligned (sizeof(unsigned long))));
-+};
-+
-+struct _mmc_card_stack_rec {
-+ mmc_card_t first; /* first card on the stack */
-+ mmc_card_t last; /* last card on the stack */
-+ mmc_card_t selected; /* currently selected card */
-+ int ncards;
-+};
-+
-+struct _mmc_controller_rec {
-+ mmc_controller_state_t state; /* found, initialized, unplugged... */
-+ int usage; /* reference count */
-+ int slot; /* host's number for device reference */
-+ semaphore_t io_sem; /* I/O serialization */
-+ rwsemaphore_t update_sem; /* card stack check/update serialization */
-+
-+ mmc_controller_tmpl_t tmpl; /* methods provided by the driver */
-+ mmc_card_stack_rec_t stack; /* card stack management data */
-+
-+ u32 rca_next; /* next RCA to assign */
-+ int slot_next; /* next slot number to assign */
-+#ifdef CONFIG_PROC_FS
-+ char proc_name[16];
-+ proc_dir_entry_t proc;
-+#endif
-+ unsigned long host_data[0] /* driver can request some extra space */
-+ __attribute__((aligned (sizeof(unsigned long))));
-+};
-+
-+/*
-+ * MMC core interface
-+ */
-+enum _mmc_reg_type {
-+ MMC_REG_TYPE_USER = 1,
-+ MMC_REG_TYPE_HOST,
-+ MMC_REG_TYPE_CARD
-+};
-+
-+struct _mmc_notifier_rec {
-+ struct _mmc_notifier_rec *next;
-+ mmc_notifier_fn_t add;
-+ mmc_notifier_fn_t remove;
-+};
-+
-+enum _mmc_response {
-+ MMC_NORESPONSE = 1,
-+ MMC_R1,
-+ MMC_R2,
-+ MMC_R3,
-+ MMC_R4,
-+ MMC_R5
-+};
-+
-+#undef EXTERN
-+#ifndef __MMC_CORE_IMPLEMENTATION__
-+#define EXTERN extern
-+#else
-+#define EXTERN /* empty */
-+#endif
-+
-+EXTERN void *mmc_register( mmc_reg_type_t, void *, size_t );
-+EXTERN void mmc_unregister( mmc_reg_type_t, void * );
-+EXTERN int mmc_update_card_stack( int );
-+
-+EXTERN mmc_card_t mmc_get_card( int, int );/* get reference to the card */
-+EXTERN void mmc_put_card( mmc_card_t ); /* release card reference */
-+
-+EXTERN int mmc_notify_add( mmc_card_t ); /* user notification */
-+EXTERN int mmc_notify_remove( mmc_card_t );
-+
-+EXTERN ssize_t mmc_read( mmc_card_t, mmc_transfer_mode_t, char *, size_t, loff_t * ); /* generic read */
-+EXTERN ssize_t mmc_write( mmc_card_t, mmc_transfer_mode_t, const char *, size_t, loff_t * ); /* generic write */
-+EXTERN int mmc_ioctl( mmc_card_t, unsigned int, unsigned long ); /* generic ioctl */
-+/*
-+ * TODO: [?m.b. ioctl()] to erase, lock and write protect
-+ * 1) mmc_erase
-+ * 2) mmc_write_prot
-+ * 3) mmc_lock
-+ */
-+#undef EXTERN
-+
-+static inline mmc_card_t __mmc_card_alloc( size_t extra )
-+{
-+ mmc_card_t ret = kmalloc( sizeof( mmc_card_rec_t ) + extra, GFP_KERNEL );
-+
-+ if ( ret ) {
-+ memset( ret, 0, sizeof( mmc_card_rec_t ) + extra );
-+ }
-+
-+ return ret;
-+}
-+
-+static inline void __mmc_card_free( mmc_card_t card )
-+{
-+ if ( card ) {
-+ kfree( card );
-+ }
-+}
-+
-+static inline mmc_card_stack_t __mmc_card_stack_init( mmc_card_stack_t stack )
-+{
-+ mmc_card_stack_t ret = NULL;
-+ if ( stack ) {
-+ memset( stack, 0, sizeof( mmc_card_stack_rec_t ) );
-+ ret = stack;
-+ }
-+ return ret;
-+}
-+
-+static inline mmc_card_stack_t __mmc_card_stack_add( mmc_card_stack_t stack, mmc_card_t card )
-+{
-+ mmc_card_stack_t ret = NULL;
-+
-+ if ( stack && card ) {
-+ card->next = NULL;
-+
-+ if ( stack->first ) {
-+ stack->last->next = card;
-+ stack->last = card;
-+ } else
-+ stack->first = stack->last = card;
-+
-+ ++stack->ncards;
-+ ret = stack;
-+ }
-+ return ret;
-+}
-+
-+static inline mmc_card_stack_t __mmc_card_stack_remove( mmc_card_stack_t stack, mmc_card_t card )
-+{
-+ mmc_card_stack_t ret = NULL;
-+ register mmc_card_t prev;
-+ int found = FALSE;
-+
-+ if ( !stack || !card )
-+ goto error;
-+
-+ if ( stack->ncards > 0 ) {
-+ if ( stack->first == card ) {
-+ stack->first = stack->first->next;
-+ if ( stack->last == card )
-+ stack->last = stack->last->next;
-+ found = TRUE;
-+ } else {
-+ for ( prev = stack->first; prev; prev = prev->next )
-+ if ( prev->next == card ) {
-+ found = TRUE;
-+ break;
-+ }
-+ if ( found ) {
-+ if ( prev->next == stack->last )
-+ stack->last = prev->next;
-+ prev->next = prev->next->next;
-+ }
-+ }
-+ if ( found ) {
-+ --stack->ncards;
-+ ret = stack;
-+ }
-+ }
-+error:
-+ return ret;
-+}
-+
-+static inline void __mmc_card_stack_free( mmc_card_stack_t stack )
-+{
-+ mmc_card_t card, next;
-+
-+ if ( stack && (stack->ncards > 0) ) {
-+ card = stack->first;
-+ while ( card ) {
-+ next = card->next;
-+ kfree( card );
-+ card = next;
-+ }
-+ __mmc_card_stack_init( stack );
-+ }
-+}
-+
-+static inline int __mmc_card_stack_foreach( mmc_card_stack_t stack, mmc_notifier_fn_t fn, int unplugged_also )
-+{
-+ int ret = 0;
-+ register mmc_card_t card = NULL;
-+
-+ if ( stack && fn ) {
-+ for ( card = stack->first; card; card = card->next )
-+ if ( (card->state != MMC_CARD_STATE_UNPLUGGED)
-+ || unplugged_also )
-+ if ( fn( card ) ) {
-+ ret = -card->slot;
-+ break;
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+/*
-+ * Debugging macros
-+ */
-+#ifdef CONFIG_MMC_DEBUG
-+
-+#define MMC_DEBUG_LEVEL0 (0) /* major */
-+#define MMC_DEBUG_LEVEL1 (1)
-+#define MMC_DEBUG_LEVEL2 (2) /* device */
-+#define MMC_DEBUG_LEVEL3 (3) /* protocol */
-+#define MMC_DEBUG_LEVEL4 (4) /* everything */
-+
-+#define MMC_DEBUG(n, args...) \
-+if (n <= CONFIG_MMC_DEBUG_VERBOSE) { \
-+ printk(KERN_INFO __FUNCTION__ "(): " args); \
-+}
-+#define __ENTER0( ) MMC_DEBUG( MMC_DEBUG_LEVEL2, "entry\n" );
-+#define __LEAVE0( ) MMC_DEBUG( MMC_DEBUG_LEVEL2, "exit\n" );
-+#define __ENTER( format, args... ) MMC_DEBUG( MMC_DEBUG_LEVEL2, "entry: " format "\n", args );
-+#define __LEAVE( format, args... ) MMC_DEBUG( MMC_DEBUG_LEVEL2, "exit: " format "\n", args );
-+
-+#define MMC_DUMP_CSD( card ) MMC_DEBUG( MMC_DEBUG_LEVEL3, \
-+"CSD register:\n" \
-+" csd_structure=%u\n" \
-+" spec_vers=%u\n" \
-+" taac=%x\n" \
-+" nsac=%x\n" \
-+" tran_speed=%x\n" \
-+" ccc=%x\n" \
-+" read_bl_len=%u\n" \
-+" read_bl_partial=%u\n" \
-+" write_blk_misalign=%u\n" \
-+" read_blk_misalign=%u\n" \
-+" dsr_imp=%u\n" \
-+" c_size=%u\n" \
-+" vdd_r_curr_min=%u\n" \
-+" vdd_r_curr_max=%u\n" \
-+" vdd_w_curr_min=%u\n" \
-+" vdd_w_curr_max=%u\n" \
-+" c_size_mult=%u\n" \
-+" erase_grp_size=%u\n" \
-+" erase_grp_mult=%u\n" \
-+" wp_grp_size=%u\n" \
-+" wp_grp_enable=%u\n" \
-+" default_ecc=%u\n" \
-+" r2w_factor=%u\n" \
-+" write_bl_len=%u\n" \
-+" write_bl_partial=%u\n" \
-+" content_prot_app=%u\n" \
-+" file_format_grp=%u\n" \
-+" copy=%u\n" \
-+" perm_write_protect=%d\n" \
-+" tmp_write_protect=%d\n" \
-+" file_format=%d\n" \
-+" ecc=%d\n", \
-+card->info.csd.csd_structure, \
-+card->info.csd.spec_vers, \
-+card->info.csd.taac, \
-+card->info.csd.nsac, \
-+card->info.csd.tran_speed, \
-+card->info.csd.ccc, \
-+card->info.csd.read_bl_len, \
-+card->info.csd.read_bl_partial, \
-+card->info.csd.write_blk_misalign, \
-+card->info.csd.read_blk_misalign, \
-+card->info.csd.dsr_imp, \
-+card->info.csd.c_size, \
-+card->info.csd.vdd_r_curr_min, \
-+card->info.csd.vdd_r_curr_max, \
-+card->info.csd.vdd_w_curr_min, \
-+card->info.csd.vdd_w_curr_max, \
-+card->info.csd.c_size_mult, \
-+card->info.csd.erase_grp_size, \
-+card->info.csd.erase_grp_mult, \
-+card->info.csd.wp_grp_size, \
-+card->info.csd.wp_grp_enable, \
-+card->info.csd.default_ecc, \
-+card->info.csd.r2w_factor, \
-+card->info.csd.write_bl_len, \
-+card->info.csd.write_bl_partial, \
-+card->info.csd.content_prot_app, \
-+card->info.csd.file_format_grp, \
-+card->info.csd.copy, \
-+card->info.csd.perm_write_protect, \
-+card->info.csd.tmp_write_protect, \
-+card->info.csd.file_format, \
-+card->info.csd.ecc );
-+
-+#else /* CONFIG_MMC_DEBUG */
-+#define MMC_DEBUG(n, args...) /* empty */
-+#define __ENTER0( ) /* empty */
-+#define __LEAVE0( ) /* empty */
-+#define __ENTER( args... ) /* empty */
-+#define __LEAVE( args... ) /* empty */
-+#define MMC_DUMP_CSD( card ) /* empty */
-+#endif /* CONFIG_MMC_DEBUG */
-+
-+/*
-+ * Miscellaneous defines
-+ */
-+#ifndef MMC_DUMP_R1
-+#define MMC_DUMP_R1( ctrlr ) /* empty */
-+#endif
-+#ifndef MMC_DUMP_R2
-+#define MMC_DUMP_R2( ctrlr ) /* empty */
-+#endif
-+#ifndef MMC_DUMP_R3
-+#define MMC_DUMP_R3( ctrlr ) /* empty */
-+#endif
-+
-+#endif /* __KERNEL__ */
-+
-+#endif /* __MMC_P_H__ */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/mmc/mmc_block.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,989 @@
-+/*
-+ * linux/drivers/mmc/mmc_block.c
-+ * driver for the block device on the MMC card
-+ *
-+ * Author: Vladimir Shebordaev
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/version.h>
-+#include <linux/config.h>
-+#include <linux/types.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/devfs_fs_kernel.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/hdreg.h>
-+#include <linux/blkpg.h>
-+#include <asm/uaccess.h>
-+
-+#include <mmc/types.h>
-+#include <mmc/mmc.h>
-+
-+#include "types.h"
-+#include "mmc.h"
-+#include "error.h"
-+
-+#define MAJOR_NR MMC_BLOCK_MAJOR
-+#define MAJOR_NAME "mmc"
-+#define DEVICE_NAME "mmc_block"
-+#define DEVICE_REQUEST mmc_block_request
-+#define DEVICE_NR(device) (device)
-+#define DEVICE_ON(device)
-+#define DEVICE_OFF(device)
-+#define DEVICE_NO_RANDOM
-+#include <linux/blk.h>
-+/* for old kernels... */
-+#ifndef QUEUE_EMPTY
-+#define QUEUE_EMPTY (!CURRENT)
-+#endif
-+#if LINUX_VERSION_CODE < 0x20300
-+#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].plug_tq.sync)
-+#else
-+#define QUEUE_PLUGGED (blk_dev[MAJOR_NR].request_queue.plugged)
-+#endif
-+
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,14)
-+#define BLK_INC_USE_COUNT MOD_INC_USE_COUNT
-+#define BLK_DEC_USE_COUNT MOD_DEC_USE_COUNT
-+#else
-+#define BLK_INC_USE_COUNT do {} while(0)
-+#define BLK_DEC_USE_COUNT do {} while(0)
-+#endif
-+
-+#define MMC_BLOCK_RAW_DEVICE( device ) ((device>>MMC_BLOCK_PARTNBITS)<<MMC_BLOCK_PARTNBITS)
-+#define MMC_BLOCK_MKDEV( host, slot ) \
-+ MKDEV( MMC_BLOCK_MAJOR, \
-+ (host<<MMC_MINOR_HOST_SHIFT) \
-+ | (slot<<MMC_BLOCK_PARTNBITS) )
-+
-+typedef struct _mmc_block_device mmc_block_device_rec_t;
-+typedef struct _mmc_block_device *mmc_block_device_t;
-+
-+struct _mmc_block_device {
-+ mmc_card_t card;
-+ int host;
-+ int slot;
-+ kdev_t rdev;
-+ int usage;
-+ semaphore_t sem;
-+};
-+
-+static int mmc_block_blk_sizes[1<<MINORBITS];
-+static int mmc_block_blk_blksizes[1<<MINORBITS];
-+static int mmc_block_hardsect_sizes[1<<MINORBITS];
-+static struct hd_struct mmc_block_partitions[1<<MINORBITS];
-+
-+/* Accessed under device table lock */
-+static gendisk_rec_t mmc_block_gendisk = {
-+ major: MMC_BLOCK_MAJOR,
-+ major_name: MAJOR_NAME,
-+ minor_shift: MMC_BLOCK_PARTNBITS,
-+ max_p: (1<<MMC_BLOCK_PARTNBITS),
-+ sizes: mmc_block_blk_sizes,
-+ part: mmc_block_partitions
-+};
-+
-+static mmc_block_device_rec_t mmc_block_device[1<<MINORBITS];
-+static rwsemaphore_t mmc_block_device_sem;
-+
-+static inline void __mmc_block_rdlock_devices( void )
-+{
-+ down_read( &mmc_block_device_sem );
-+}
-+
-+static inline void __mmc_block_rdunlock_devices( void )
-+{
-+ up_read( &mmc_block_device_sem );
-+}
-+
-+static inline void __mmc_block_wrlock_devices( void )
-+{
-+ down_write( &mmc_block_device_sem );
-+}
-+
-+static inline void __mmc_block_wrunlock_devices( void )
-+{
-+ up_write( &mmc_block_device_sem );
-+}
-+
-+static inline void __mmc_block_lock_device( kdev_t rdev )
-+{
-+ __mmc_block_rdlock_devices();
-+ down( &mmc_block_device[MINOR( rdev )].sem );
-+}
-+
-+static inline void __mmc_block_unlock_device( kdev_t rdev )
-+{
-+ up( &mmc_block_device[MINOR( rdev )].sem );
-+ __mmc_block_rdunlock_devices();
-+}
-+
-+static inline void __mmc_block_device_init( int minor )
-+{
-+ mmc_block_device_t dev = &mmc_block_device[minor];
-+
-+ dev->usage = 0;
-+ dev->card = NULL;
-+ dev->host = minor >> MMC_MINOR_HOST_SHIFT;
-+ dev->slot = (minor & MMC_MINOR_CARD_MASK)>>MMC_BLOCK_PARTNBITS;
-+ dev->rdev = MKDEV( MMC_BLOCK_MAJOR, minor );
-+}
-+
-+static inline int __mmc_block_validate_device( kdev_t rdev )
-+{
-+ int ret = -1;
-+ int minor = MINOR( rdev );
-+
-+ if ( mmc_block_device[minor].card
-+ && (mmc_block_gendisk.part[minor].nr_sects > 0) )
-+ ret = 0;
-+
-+ return ret;
-+}
-+
-+static inline int __mmc_block_invalidate_card( mmc_card_t card, int invalidate )
-+{
-+ int ret = 0;
-+ kdev_t start;
-+ int minor;
-+
-+ __ENTER( "card = 0x%p", card );
-+
-+ if ( card && card->ctrlr ) {
-+ register int i;
-+
-+ start = MMC_BLOCK_MKDEV( card->ctrlr->slot, card->slot );
-+ minor = MINOR( start );
-+
-+ __mmc_block_wrlock_devices();
-+ for ( i = mmc_block_gendisk.max_p - 1; i >= 0; --i ) {
-+ if ( invalidate )
-+ invalidate_device( start + i, 0 );
-+
-+ __mmc_block_device_init( minor + i );
-+
-+ mmc_block_gendisk.part[minor + i].nr_sects = 0;
-+ mmc_block_gendisk.part[minor + i].start_sect = 0;
-+ }
-+ __mmc_block_wrunlock_devices();
-+ }
-+
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+
-+static inline int mmc_block_invalidate_card( int host, int slot, int invalidate )
-+{
-+ int ret = 0;
-+ kdev_t start;
-+ int minor;
-+
-+ __ENTER( "host=%d slot=%d", host, slot );
-+
-+ if ( (host >= 0) && (slot >= 0) ) {
-+ register int i;
-+ mmc_card_t card = NULL;
-+
-+ start = MMC_BLOCK_MKDEV( host, slot );
-+ minor = MINOR( start );
-+
-+ __mmc_block_wrlock_devices();
-+ for ( i = mmc_block_gendisk.max_p - 1; i >= 0; --i ) {
-+ if ( !card )
-+ card = mmc_block_device[minor + i].card;
-+
-+ if ( invalidate )
-+ invalidate_device( start + i, 0 );
-+
-+ __mmc_block_device_init( minor + i );
-+
-+ mmc_block_gendisk.part[minor + i].nr_sects = 0;
-+ mmc_block_gendisk.part[minor + i].start_sect = 0;
-+ }
-+ if ( card )
-+ mmc_put_card( card );
-+ __mmc_block_wrunlock_devices();
-+ }
-+
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+
-+/* Get device reference locked for writing */
-+static inline mmc_block_device_t __mmc_block_get_device( kdev_t rdev )
-+{
-+ mmc_block_device_t ret = NULL;
-+ u8 minor = MINOR( rdev );
-+ int host_no, card_no;
-+
-+ __ENTER( "rdev=%x:%x", MAJOR( rdev ), MINOR( rdev ) );
-+
-+ host_no = minor >> MMC_MINOR_HOST_SHIFT;
-+ if ( host_no >= MMC_CONTROLLERS_MAX )
-+ goto error;
-+
-+ card_no = (minor & MMC_MINOR_CARD_MASK)>>MMC_BLOCK_PARTNBITS;
-+ if ( card_no >= MMC_CARDS_MAX )
-+ goto error;
-+
-+ __mmc_block_lock_device( rdev );
-+ if ( __mmc_block_validate_device( rdev ) ) {
-+ __mmc_block_unlock_device( rdev );
-+ goto error;
-+ }
-+
-+ ret = &mmc_block_device[minor];
-+ MMC_DEBUG( MMC_DEBUG_LEVEL2, "(%x:%x) card=%p, dusage=%d\n",
-+ MAJOR( ret->rdev ), MINOR( ret->rdev ),
-+ ret->card, ret->usage );
-+error:
-+ __LEAVE( "ret=0x%p", ret );
-+ return ret;
-+}
-+
-+/* Unlocks the device */
-+static inline void __mmc_block_put_device( mmc_block_device_t dev )
-+{
-+ __ENTER0();
-+
-+ if ( dev ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL2, "(%x:%x) card=%p, dusage=%d\n",
-+ MAJOR( dev->rdev ), MINOR( dev->rdev ),
-+ dev->card, dev->usage );
-+ __mmc_block_unlock_device( dev->rdev );
-+ }
-+
-+ __LEAVE0();
-+}
-+
-+/* Atomically increases use count of the valid device */
-+static inline mmc_block_device_t mmc_block_get_device( kdev_t rdev )
-+{
-+ mmc_block_device_t ret = NULL;
-+
-+ __ENTER0();
-+
-+ ret = __mmc_block_get_device( rdev );
-+ if ( !ret )
-+ goto error;
-+
-+ ret->usage++;
-+ __mmc_block_put_device( ret );
-+error:
-+ __LEAVE( "ret=0x%p dusage=%d card=0x%p cusage=%d",
-+ ret, ret ? ret->usage : -1,
-+ ret ? ret->card : NULL,
-+ ret ? (ret->card ? ret->card->usage : -1) : -1 );
-+ return ret;
-+}
-+
-+/* Check is there references to the card */
-+static inline int __mmc_block_check_card( kdev_t rdev )
-+{
-+ int ret = TRUE;
-+ int start = MINOR( MMC_BLOCK_RAW_DEVICE( rdev ) );
-+ register int i;
-+
-+ for ( i = 0; i < mmc_block_gendisk.max_p; i++ )
-+ if ( mmc_block_device[start + i].usage > 0 ) {
-+ ret = FALSE;
-+ break;
-+ }
-+
-+ return ret;
-+}
-+
-+/* Atomically decreases device use count */
-+static inline void mmc_block_put_device( mmc_block_device_t dev )
-+{
-+ __ENTER0();
-+
-+ if ( dev ) {
-+ int invalidate = FALSE;
-+
-+ __mmc_block_get_device( dev->rdev );
-+ if ( dev->usage > 0 )
-+ --dev->usage;
-+
-+ if ( dev->usage ) {
-+ __mmc_block_put_device( dev );
-+ goto out;
-+
-+ } else {
-+ int host, slot;
-+ mmc_card_t card = NULL;
-+
-+ invalidate = __mmc_block_check_card( dev->rdev );
-+ if ( invalidate ) {
-+ host = dev->card->ctrlr->slot;
-+ slot = dev->card->slot;
-+
-+ if ( dev->card ) {
-+ card = dev->card;
-+ mmc_put_card( dev->card );
-+ dev->card = NULL;
-+ }
-+ }
-+ __mmc_block_put_device( dev );
-+
-+ if ( invalidate )
-+ __mmc_block_invalidate_card( card, TRUE );
-+ }
-+
-+ }
-+out:
-+ __LEAVE0();
-+}
-+
-+static int mmc_block_open( struct inode *inode, struct file *file )
-+{
-+ int ret = -ENODEV;
-+ mmc_block_device_t dev = NULL;
-+
-+ __ENTER0();
-+
-+ if ( !inode || !file )
-+ goto error;
-+
-+ BLK_INC_USE_COUNT;
-+
-+ check_disk_change( inode->i_rdev );
-+
-+ dev = mmc_block_get_device( inode->i_rdev );
-+ if ( !dev )
-+ goto error;
-+
-+ dev = __mmc_block_get_device( inode->i_rdev );
-+ if ( !dev )
-+ goto error;
-+
-+ if ( file->f_mode & FMODE_WRITE ) { /* FIXME */
-+ if ( dev->usage > 1 ) {
-+ ret = -EBUSY;
-+ __mmc_block_put_device( dev );
-+ mmc_block_put_device( dev );
-+ goto error;
-+ }
-+ }
-+
-+ __mmc_block_put_device( dev );
-+
-+ if ( file )
-+ file->private_data = dev;
-+
-+ ret = 0;
-+ goto out;
-+error:
-+ BLK_DEC_USE_COUNT;
-+out:
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+
-+static int mmc_block_release( struct inode *inode, struct file *file )
-+{
-+ int ret = -EINVAL;
-+ mmc_block_device_t dev = NULL;
-+
-+ __ENTER( "inode=0x%p file=0x%p rdev=(%x:%x)", inode, file,
-+ inode ? MAJOR( inode->i_rdev ) : 0xff,
-+ inode ? MINOR( inode->i_rdev ) : 0xff );
-+
-+ if ( !file && !inode )
-+ goto error;
-+
-+ if ( file )
-+ dev = file->private_data;
-+ else
-+ dev = __mmc_block_get_device( inode->i_rdev );
-+
-+ if ( !dev ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "invalid device\n" );
-+ goto error;
-+ }
-+
-+ if ( file ) {
-+ mmc_block_put_device( dev );
-+ file->private_data = NULL;
-+
-+ } else {
-+ int invalidate = FALSE;
-+
-+ if ( dev->usage > 0 )
-+ --dev->usage;
-+
-+ if ( dev->usage ) {
-+ __mmc_block_put_device( dev );
-+ goto out;
-+
-+ } else {
-+ int host, slot;
-+ mmc_card_t card = NULL;
-+
-+ invalidate = __mmc_block_check_card( dev->rdev );
-+ if ( invalidate ) {
-+ host = dev->card->ctrlr->slot;
-+ slot = dev->card->slot;
-+
-+ if ( dev->card ) {
-+ card = dev->card;
-+ mmc_put_card( dev->card );
-+ dev->card = NULL;
-+ }
-+ }
-+ __mmc_block_put_device( dev );
-+
-+ if ( invalidate )
-+ __mmc_block_invalidate_card( card, TRUE );
-+
-+ }
-+ }
-+
-+out:
-+ BLK_DEC_USE_COUNT;
-+ ret = 0;
-+error:
-+ __LEAVE0();
-+ return ret;
-+}
-+
-+static int mmc_block_check_disk_change( kdev_t rdev )
-+{
-+ int ret = 0;
-+#if 0
-+ mmc_block_device_t dev = &mmc_block_device[MINOR( rdev )];
-+
-+ __mmc_block_lock_device( rdev );
-+ if ( !dev->card )
-+ ret = 1;
-+ __mmc_block_unlock_device( rdev );
-+#else
-+ ret = 1;
-+#endif
-+ return ret;
-+}
-+
-+static int mmc_block_revalidate( kdev_t rdev )
-+{
-+ int ret = 1;
-+ mmc_card_t card;
-+ mmc_block_device_t dev;
-+ kdev_t start = MMC_BLOCK_RAW_DEVICE( rdev );
-+ int minor = MINOR( start );
-+ int host, slot;
-+ int i;
-+
-+ __ENTER0();
-+
-+ (void)mmc_update_card_stack( MINOR( start )>>MMC_MINOR_HOST_SHIFT );
-+
-+ __mmc_block_wrlock_devices();
-+
-+ dev = &mmc_block_device[minor];
-+ host = dev->host;
-+ slot = dev->slot;
-+
-+ if ( dev->card ) { /* card has not been changed actually */
-+ __mmc_block_wrunlock_devices();
-+ goto out;
-+
-+ } else {
-+ card = mmc_get_card( host, slot );
-+ if ( !card ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL2, "failed to get card: "
-+ "host=%d, slot=%d\n", host, slot );
-+ __mmc_block_wrunlock_devices();
-+ goto error;
-+ }
-+ dev->card = card;
-+ }
-+ __mmc_block_wrunlock_devices();
-+ /* FIXME */
-+ __mmc_block_rdlock_devices(); /* handle the request for sector 0 */
-+ grok_partitions( &mmc_block_gendisk, MINOR( start ),
-+ mmc_block_gendisk.max_p,
-+ card->info.capacity>>9 /* sectors */
-+ );
-+ __mmc_block_rdunlock_devices();
-+ /* FIXME */
-+ __mmc_block_wrlock_devices();
-+ for ( i = start + mmc_block_gendisk.max_p - 1; i >= 0; --i ) {
-+ int minor = MINOR( i );
-+
-+ dev = &mmc_block_device[minor];
-+ if ( mmc_block_gendisk.part[minor].nr_sects > 0 )
-+ dev->card = card;
-+ }
-+ __mmc_block_wrunlock_devices();
-+out:
-+error:
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+
-+static void mmc_block_handle_request( void )
-+{
-+ struct request *request;
-+ mmc_block_device_t dev;
-+ mmc_card_t card;
-+ char *buf;
-+ loff_t pos;
-+ unsigned int result = 0;
-+
-+ for (;;) {
-+ int minor;
-+
-+ INIT_REQUEST;
-+ request = CURRENT;
-+ spin_unlock_irq( &io_request_lock );
-+
-+ minor = MINOR( request->rq_dev );
-+ dev = __mmc_block_get_device( request->rq_dev );
-+ if ( !dev ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL2, "invalid device (%x:%x)\n",
-+ MAJOR( request->rq_dev ), minor );
-+
-+ goto end_req;
-+ }
-+
-+ card = dev->card;
-+ (void)__mmc_block_put_device( dev );
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL2,
-+// printk( KERN_INFO __FUNCTION__"(): "
-+ "request %p: cmd %i sec %li (nr. %li)\n",
-+ CURRENT, CURRENT->cmd, CURRENT->sector,
-+ CURRENT->current_nr_sectors );
-+
-+ if ( request->current_nr_sectors >
-+ mmc_block_gendisk.part[minor].nr_sects )
-+ goto end_req;
-+
-+ // Handle the request
-+ // TODO: handle clusterred requests in multiple block transfer mode
-+ buf = request->buffer;
-+ pos = (mmc_block_gendisk.part[minor].start_sect +
-+ request->sector) * MMC_BLOCK_SECT_SIZE;
-+
-+ switch ( request->cmd )
-+ {
-+ int i, ret;
-+
-+ case READ:
-+#if 0
-+ ret = mmc_read( card,
-+ (request->current_nr_sectors > 1) ?
-+ MMC_TRANSFER_MODE_BLOCK_MULTIPLE :
-+ MMC_TRANSFER_MODE_BLOCK_SINGLE,
-+ buf,
-+ request->current_nr_sectors
-+ * MMC_BLOCK_SECT_SIZE, /* FIXME */
-+ &pos );
-+ if ( ret < 0 )
-+ goto end_req;
-+
-+#else
-+ for ( i = 0;
-+ i < request->current_nr_sectors;
-+ i++ ) {
-+ ret = mmc_read( card,
-+ MMC_TRANSFER_MODE_BLOCK_SINGLE,
-+ buf,
-+ MMC_BLOCK_SECT_SIZE, /* FIXME */
-+ &pos );
-+ if ( ret < 0 )
-+ goto end_req;
-+ else
-+ buf += ret;
-+ }
-+#endif
-+ result = 1;
-+ break;
-+
-+ case WRITE:
-+ // TODO: Read only device
-+#if 0
-+ ret = mmc_write( card,
-+ (request->current_nr_sectors > 1) ?
-+ MMC_TRANSFER_MODE_BLOCK_MULTIPLE :
-+ MMC_TRANSFER_MODE_BLOCK_SINGLE,
-+ buf,
-+ request->current_nr_sectors
-+ * MMC_BLOCK_SECT_SIZE, /* FIXME */
-+ &pos );
-+ if ( ret < 0 )
-+ goto end_req;
-+
-+#else
-+ for ( i = 0;
-+ i < request->current_nr_sectors;
-+ i++ ) {
-+ ret = mmc_write( card,
-+ MMC_TRANSFER_MODE_BLOCK_SINGLE,
-+ buf,
-+ MMC_BLOCK_SECT_SIZE, /* FIXME */
-+ &pos );
-+ if ( ret < 0 )
-+ goto end_req;
-+ else
-+ buf += ret;
-+ }
-+#endif
-+ result = 1;
-+ break;
-+ }
-+
-+end_req:
-+ __LEAVE( "result=%d", result );
-+ spin_lock_irq( &io_request_lock );
-+ end_request( result );
-+ }
-+}
-+
-+static volatile int leaving = 0;
-+static DECLARE_MUTEX_LOCKED( thread_sem );
-+static DECLARE_WAIT_QUEUE_HEAD( thr_wq );
-+static pid_t thr_id = -1;
-+
-+int mmc_block_thread( void *arg )
-+{
-+ struct task_struct *task = current;
-+ DECLARE_WAITQUEUE(wait, task);
-+
-+ __ENTER0();
-+
-+ task->session = 1;
-+ task->pgrp = 1;
-+ task->flags |= PF_MEMALLOC;
-+ strcpy( task->comm, "mmcblockd" );
-+ task->tty = NULL;
-+ spin_lock_irq( &task->sigmask_lock );
-+ sigfillset( &task->blocked );
-+ recalc_sigpending( task );
-+ spin_unlock_irq( &task->sigmask_lock );
-+ exit_mm( task );
-+ exit_files( task );
-+ exit_sighand( task );
-+ exit_fs( task );
-+
-+ while ( !leaving ) {
-+ add_wait_queue( &thr_wq, &wait);
-+ set_current_state( TASK_INTERRUPTIBLE );
-+ spin_lock_irq( &io_request_lock );
-+ if ( QUEUE_EMPTY || QUEUE_PLUGGED ) {
-+ spin_unlock_irq( &io_request_lock );
-+ schedule();
-+ remove_wait_queue( &thr_wq, &wait );
-+ } else {
-+ remove_wait_queue( &thr_wq, &wait );
-+ set_current_state( TASK_RUNNING );
-+ mmc_block_handle_request(); /* handle the request */
-+ spin_unlock_irq( &io_request_lock );
-+ }
-+ }
-+
-+ up( &thread_sem );
-+
-+ __LEAVE0();
-+ return 0;
-+}
-+
-+#if LINUX_VERSION_CODE < 0x20300
-+#define RQFUNC_ARG void
-+#else
-+#define RQFUNC_ARG request_queue_t *q
-+#endif
-+
-+static void mmc_block_request( RQFUNC_ARG )
-+{
-+ wake_up( &thr_wq );
-+}
-+
-+static int mmc_block_ioctl( struct inode * inode, struct file * file,
-+ unsigned int cmd, unsigned long arg )
-+{
-+ int ret = -ENODEV;
-+ mmc_block_device_t dev;
-+ mmc_card_t card;
-+ int minor;
-+ __ENTER0();
-+
-+ if ( !inode || !file ) {
-+ ret = -EINVAL;
-+ goto error;
-+ }
-+ minor = MINOR( inode->i_rdev );
-+
-+ dev = __mmc_block_get_device( inode->i_rdev );
-+ if ( !dev ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "invalid device\n" );
-+ goto error;
-+ }
-+
-+ card = dev->card;
-+ __mmc_block_put_device( dev );
-+
-+ switch ( cmd ) {
-+ case BLKGETSIZE: /* Return device size */
-+ {
-+ unsigned long value;
-+
-+ __mmc_block_rdlock_devices();
-+ value = mmc_block_gendisk.part[minor].nr_sects;
-+ __mmc_block_rdunlock_devices();
-+
-+ if ( put_user( value, (unsigned long *) arg) ) {
-+ ret = -EFAULT;
-+ goto error;
-+ }
-+ }
-+ break;
-+
-+#ifdef BLKGETSIZE64
-+ case BLKGETSIZE64:
-+ {
-+ unsigned long value;
-+
-+ __mmc_block_rdlock_devices();
-+ value = mmc_block_gendisk.part[minor].nr_sects;
-+ __mmc_block_rdunlock_devices();
-+
-+ if ( put_user( (u64)value, (u64 *) arg) ) {
-+ ret = -EFAULT;
-+ goto error;
-+ }
-+ }
-+ break;
-+#endif
-+
-+ case HDIO_GETGEO:
-+ {
-+ struct hd_geometry geo;
-+
-+ ret = !access_ok( VERIFY_WRITE, arg, sizeof( geo ) );
-+ if ( ret ) {
-+ ret = -EFAULT;
-+ goto error;
-+ }
-+
-+ geo.heads = 1;
-+ geo.sectors = 1;
-+
-+ __mmc_block_rdlock_devices();
-+ geo.cylinders = mmc_block_gendisk.part[minor].nr_sects;
-+ geo.start = mmc_block_gendisk.part[minor].start_sect;
-+ __mmc_block_rdunlock_devices();
-+
-+ if ( copy_to_user( (int *)arg, &geo, sizeof( geo ) ) ) {
-+ ret = -EFAULT;
-+ goto error;
-+ }
-+ }
-+ break;
-+
-+ case BLKRRPART:
-+ if ( !capable( CAP_SYS_ADMIN ) ) {
-+ ret = -EACCES;
-+ goto error;
-+ }
-+ (void)mmc_block_revalidate( inode->i_rdev );
-+ break;
-+
-+ default:
-+ ret = blk_ioctl( inode->i_rdev, cmd, arg );
-+ goto out;
-+ }
-+
-+ ret = 0;
-+error:
-+out:
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+
-+#if LINUX_VERSION_CODE < 0x20326
-+static struct file_operations mmc_block_fops =
-+{
-+ open: mmc_block_open,
-+ ioctl: mmc_block_ioctl,
-+ release: mmc_block_release,
-+ check_media_change: mmc_block_check_disk_change,
-+ revalidate: mmc_block_revalidate,
-+ read: block_read,
-+ write: block_write
-+};
-+#else
-+static struct block_device_operations mmc_block_fops =
-+{
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,14)
-+ owner: THIS_MODULE,
-+#endif
-+ open: mmc_block_open,
-+ release: mmc_block_release,
-+ ioctl: mmc_block_ioctl,
-+ check_media_change: mmc_block_check_disk_change,
-+ revalidate: mmc_block_revalidate
-+};
-+#endif
-+
-+
-+static int mmc_block_notify_add( mmc_card_t card )
-+{
-+ int ret = -1;
-+ mmc_block_device_t dev;
-+ kdev_t start;
-+ int minor;
-+
-+ __ENTER0();
-+
-+ if ( !card || !card->ctrlr )
-+ goto error;
-+
-+ start = MMC_BLOCK_MKDEV( card->ctrlr->slot, card->slot );
-+ dev = &mmc_block_device[MINOR( start )];
-+
-+ __mmc_block_wrlock_devices();
-+ if ( !dev->card ) {
-+ dev->card = card;
-+ ret = 0;
-+ }
-+ __mmc_block_wrunlock_devices();
-+
-+ if ( !ret ) {
-+ int i;
-+
-+ /* allow to read partition table */
-+ __mmc_block_rdlock_devices();
-+ grok_partitions( &mmc_block_gendisk, MINOR( start ),
-+ mmc_block_gendisk.max_p,
-+ card->info.capacity>>9 /* sectors */
-+ );
-+ __mmc_block_rdunlock_devices();
-+
-+ __mmc_block_wrlock_devices();
-+ for ( i = start + mmc_block_gendisk.max_p - 1; i >= 0; --i ) {
-+ minor = MINOR( i );
-+ dev = &mmc_block_device[minor];
-+ if ( mmc_block_gendisk.part[minor].nr_sects > 0 )
-+ dev->card = card;
-+ }
-+ __mmc_block_wrunlock_devices();
-+ }
-+error:
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+
-+
-+static int mmc_block_notify_remove( mmc_card_t card )
-+{
-+ int ret = -1;
-+
-+ __ENTER( "card=0x%p", card );
-+
-+ if ( card && card->ctrlr )
-+ ret = __mmc_block_invalidate_card( card, FALSE );
-+
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+
-+static mmc_notifier_rec_t mmc_block_notifier = {
-+ add: mmc_block_notify_add,
-+ remove: mmc_block_notify_remove
-+};
-+
-+static int __init mmc_block_module_init( void )
-+{
-+ int ret = -ENODEV;
-+ int i;
-+
-+ __ENTER0();
-+
-+ init_rwsem( &mmc_block_device_sem );
-+
-+ if ( devfs_register_blkdev( MAJOR_NR, MAJOR_NAME, &mmc_block_fops ) ) {
-+ MMC_ERROR( "Can't allocate major number %d for MMC block devices.\n", MMC_BLOCK_MAJOR );
-+ ret = -EAGAIN;
-+ goto error;
-+ }
-+
-+ for ( i = 0; i < (1<<MINORBITS); i++ ) {
-+ __mmc_block_device_init( i );
-+ init_MUTEX( &mmc_block_device[i].sem );
-+
-+ /* We fill it in at open() time. */
-+ mmc_block_blk_sizes[i] = 0;
-+ mmc_block_blk_blksizes[i] = BLOCK_SIZE;
-+ mmc_block_hardsect_sizes[i] = 0;
-+ }
-+
-+ init_waitqueue_head( &thr_wq );
-+ /* Allow the block size to default to BLOCK_SIZE. */
-+ blksize_size[MAJOR_NR] = mmc_block_blk_blksizes;
-+ hardsect_size[MAJOR_NR] = mmc_block_hardsect_sizes;
-+ /* Gendisk stuff */
-+ memset( mmc_block_partitions, 0, sizeof( mmc_block_partitions ) );
-+ add_gendisk( &mmc_block_gendisk );
-+
-+/* FIXME: per controller request queue, I/O and card stack update threads */
-+ blk_init_queue( BLK_DEFAULT_QUEUE( MAJOR_NR ), &mmc_block_request );
-+ thr_id = kernel_thread( mmc_block_thread, NULL,
-+ CLONE_FS|CLONE_FILES|CLONE_SIGHAND );
-+
-+ if ( !mmc_register( MMC_REG_TYPE_USER, &mmc_block_notifier, 0 ) ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "failed to register with MMC core\n" );
-+ goto error;
-+ }
-+
-+ ret = 0;
-+ goto out;
-+error:
-+ if ( thr_id != -1 ) {
-+/* quit the thread */
-+ leaving = 1;
-+ wake_up(&thr_wq);
-+
-+ down(&thread_sem);
-+ }
-+ blksize_size[MAJOR_NR] = NULL;
-+ blk_size[MAJOR_NR] = NULL;
-+ hardsect_size[MAJOR_NR] = NULL;
-+out:
-+ __LEAVE0();
-+ return ret;
-+}
-+
-+static void __exit mmc_block_module_cleanup( void )
-+{
-+/* quit the thread */
-+ leaving = 1;
-+ wake_up(&thr_wq);
-+
-+ down(&thread_sem);
-+
-+ mmc_unregister( MMC_REG_TYPE_USER, &mmc_block_notifier );
-+ del_gendisk( &mmc_block_gendisk );
-+ devfs_unregister_blkdev( MAJOR_NR, MAJOR_NAME );
-+
-+ blk_cleanup_queue( BLK_DEFAULT_QUEUE( MAJOR_NR ) );
-+ blksize_size[MAJOR_NR] = NULL;
-+ blk_size[MAJOR_NR] = NULL;
-+ hardsect_size[MAJOR_NR] = NULL;
-+}
-+
-+EXPORT_NO_SYMBOLS;
-+
-+module_init( mmc_block_module_init );
-+module_exit( mmc_block_module_cleanup );
-+
-+
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/mmc/mmc_core.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,1124 @@
-+/*
-+ * linux/drivers/mmc/mmc_core.c
-+ * MultiMediaCard subsystem core implementation
-+ *
-+ * Author: Vladimir Shebordaev
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/version.h>
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+
-+#include <linux/slab.h>
-+#include <asm/uaccess.h>
-+#include <asm/semaphore.h>
-+
-+#ifdef CONFIG_PM
-+#include <linux/pm.h>
-+#endif
-+
-+#include <mmc/types.h>
-+#include <mmc/mmc.h>
-+#include <mmc/ioctl.h>
-+
-+#include "types.h"
-+
-+#define __MMC_CORE_IMPLEMENTATION__
-+#include "mmc.h"
-+
-+/* MMC controllers registered in the system */
-+static mmc_controller_t mmc_controller[MMC_CONTROLLERS_MAX];
-+static int mmc_ncontrollers = 0;
-+static rwsemaphore_t mmc_controller_sem; /* controller table lock */
-+#ifdef CONFIG_PM
-+static struct pm_dev *mmc_pm_dev = NULL;
-+#endif
-+
-+/* users' notification list */
-+static mmc_notifier_t mmc_notifier = NULL;
-+static rwsemaphore_t mmc_notifier_sem; /* notifiers' list lock */
-+#ifdef CONFIG_PROC_FS
-+static proc_dir_entry_t mmc_proc_dir = NULL;
-+#endif
-+
-+/************************************************
-+ * service function prototypes and declarations *
-+ ************************************************/
-+static inline int mmc_acquire_io( mmc_controller_t ctrlr, mmc_card_t card )
-+{
-+ int ret = -EIO;
-+
-+ __ENTER0();
-+
-+ if ( !card || !ctrlr ) {
-+ ret = -EINVAL;
-+ goto error;
-+ }
-+#ifdef CONFIG_HOTPLUG
-+/* TODO: account for controller removal */
-+#endif
-+ down( &ctrlr->io_sem );
-+#if 0
-+ down_read( &ctrlr->update_sem ); /* FIXME */
-+ if ( card->state != MMC_CARD_STATE_UNPLUGGED )
-+ ret = 0;
-+ up_read( &ctrlr->update_sem );
-+
-+ if ( ret )
-+ up( &ctrlr->io_sem );
-+#else
-+ ret = 0;
-+#endif
-+
-+error:
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+
-+static inline void mmc_release_io( mmc_controller_t ctrlr, mmc_card_t card )
-+{
-+ __ENTER0();
-+#ifdef CONFIG_HOTPLUG
-+/* TODO: account for controller removal */
-+#endif
-+ if ( !card && !ctrlr ) { /* FIXME */
-+ MMC_DEBUG( MMC_DEBUG_LEVEL2, "bad card reference\n" );
-+ goto error;
-+ }
-+ up( &ctrlr->io_sem );
-+error:
-+ __LEAVE0();
-+}
-+
-+/* TODO: there should be a separate context to be awaken
-+ * by the card intertion interrupt; called under ctrlr->update_sem
-+ * held down by now */
-+static int __mmc_update_card_stack( mmc_controller_t ctrlr )
-+{
-+ int ret = -1;
-+ mmc_card_t card, prev;
-+
-+ __ENTER0();
-+
-+ if ( !ctrlr || !ctrlr->tmpl )
-+ goto error;
-+
-+ /* check unplugged cards first... */
-+ if ( (ret = ctrlr->tmpl->check_card_stack( ctrlr )) )
-+ goto error;
-+
-+ /* unregister unplugged cards and free 'em immediately */
-+ if ( ctrlr->stack.ncards > 0 ) {
-+ prev = ctrlr->stack.first;
-+ /* process the stack tail first */
-+ if ( prev->next ) {
-+ card = prev->next;
-+ while ( card ) {
-+ if ( card->state == MMC_CARD_STATE_UNPLUGGED ) {
-+ if ( ctrlr->stack.selected == card )
-+ ctrlr->stack.selected = NULL;
-+#ifdef CONFIG_PROC_FS
-+ if ( card->proc ) {
-+ remove_proc_entry( card->proc_name, ctrlr->proc );
-+ card->proc = NULL;
-+ }
-+#endif
-+ ctrlr->slot_next = card->slot; /* FIXME */
-+ prev->next = card->next;
-+ if ( ctrlr->stack.last == card )
-+ ctrlr->stack.last = prev;
-+ /* FIXME: controller use count */
-+ mmc_notify_remove( card );
-+ --ctrlr->stack.ncards;
-+ if ( (ctrlr->usage > 0) && ctrlr->tmpl->owner ) {
-+ --ctrlr->usage;
-+ MMC_DEBUG( MMC_DEBUG_LEVEL2,
-+ "'%s' use count "
-+ "decreased (%d)\n",
-+ ctrlr->tmpl->name,
-+ ctrlr->usage );
-+ __MOD_DEC_USE_COUNT(
-+ ctrlr->tmpl->owner );
-+ }
-+ __mmc_card_free( card );
-+
-+ card = prev->next;
-+ }
-+ }
-+ }
-+ /* then the head */
-+ card = ctrlr->stack.first;
-+ if ( card && (card->state == MMC_CARD_STATE_UNPLUGGED) ) {
-+ if ( ctrlr->stack.selected == card )
-+ ctrlr->stack.selected = NULL;
-+#ifdef CONFIG_PROC_FS
-+ if ( card->proc ) {
-+ remove_proc_entry( card->proc_name, ctrlr->proc );
-+ card->proc = NULL;
-+ }
-+#endif
-+ ctrlr->slot_next = card->slot; /* FIXME */
-+ mmc_notify_remove( card ); /* FIXME: should unregister here */
-+ ctrlr->stack.first = card->next;
-+ if ( ctrlr->stack.last == card )
-+ ctrlr->stack.last = NULL;
-+ /* FIXME: controller use count */
-+ --ctrlr->stack.ncards;
-+ if ( (ctrlr->usage > 0) && ctrlr->tmpl->owner ) {
-+ --ctrlr->usage;
-+ MMC_DEBUG( MMC_DEBUG_LEVEL2, "'%s' use count "
-+ "decreased (%d)\n", ctrlr->tmpl->name,
-+ ctrlr->usage );
-+ __MOD_DEC_USE_COUNT( ctrlr->tmpl->owner );
-+ }
-+ __mmc_card_free( card );
-+ }
-+ }
-+ MMC_DEBUG( MMC_DEBUG_LEVEL2, "after stack check: ncards=%d"
-+ " first=0x%x last=0x%x\n", ctrlr->stack.ncards,
-+ ctrlr->stack.first, ctrlr->stack.last );
-+ /* ...then add newly inserted ones */
-+ if ( (ret = ctrlr->tmpl->update_acq( ctrlr )) )
-+ goto error;
-+ /* ret = 0; */
-+error:
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+
-+/*
-+ * 1) check error code returned by controller; it's up to
-+ * controller to detect error conditions reported by the card
-+ * and to abort data transfer requests properly (e.g. send
-+ * CMD12(STOP_TRANSMISSION) to abort ADDRESS_ERROR multiple
-+ * block transfers)
-+ * 2) arrange for card stack update when necessary
-+ * (all pending i/o requests must be held pending,
-+ * update procedure must start immediately after
-+ * error has been detected)
-+ */
-+static inline int __mmc_check_error( mmc_card_t card, int err )
-+{
-+ int ret = -EIO;
-+ mmc_controller_t ctrlr;
-+
-+ __ENTER0();
-+
-+ if ( !card || !card->ctrlr )
-+ goto error;
-+
-+ ctrlr = card->ctrlr;
-+
-+ if ( err < 0 ) {
-+ switch ( err ) {
-+ /* bus error occurred */
-+ case MMC_ERROR_CRC_WRITE_ERROR:
-+ case MMC_ERROR_CRC_READ_ERROR:
-+ case MMC_ERROR_RES_CRC_ERROR:
-+ case MMC_ERROR_READ_TIME_OUT:
-+ case MMC_ERROR_TIME_OUT_RESPONSE:
-+ down_write( &ctrlr->update_sem ); /* FIXME */
-+ if ( !__mmc_update_card_stack( ctrlr ) )
-+ ret = -ENXIO;
-+ up_write( &ctrlr->update_sem );
-+ break;
-+ }
-+ } else
-+ ret = err;
-+error:
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+
-+static inline void __mmc_free_controller( mmc_controller_t ctrlr )
-+{
-+ if ( ctrlr ) {
-+ if ( ctrlr->stack.ncards > 0 )
-+ __mmc_card_stack_free( &ctrlr->stack );
-+ kfree( ctrlr );
-+ }
-+}
-+
-+#ifdef CONFIG_PROC_FS
-+static int mmc_proc_read_card_info( char *page, char **start, off_t off, int count, int *eof, void *data )
-+{
-+ int ret = -EINVAL;
-+ mmc_card_t card = (mmc_card_t)data;
-+ char *cp = page;
-+
-+ if ( !card )
-+ goto error;
-+
-+ down_read( &card->ctrlr->update_sem );
-+/* TODO: proc report
-+ * Type: RO, RW or IO (by CCC)
-+ * MID: 0x%02x card->info.cid.mid
-+ * OID: 0x%04x card->info.cid.oid
-+ * PNM: %s card->info.pnm
-+ * PRV: %s card->info.prv
-+ * PSN: 0x%08x card->info.cid.psn
-+ * MDT: %s card->info.mdt
-+ * Capacity: card->info.capacity (Bytes)
-+ */
-+#if 1
-+ cp += sprintf( cp, "Capacity: %dKb.\n\n", (card->info.capacity>>10) );
-+#else /* TODO */
-+ cp += sprintf( cp, "Type : %s\n", card->info.type );
-+ cp += sprintf( cp, "MID : 0x%02x\n", card->info.cid.mid );
-+ cp += sprintf( cp, "OID : 0x%04x\n", card->info.cid.oid );
-+ cp += sprintf( cp, "PNM : %s\n", card->info.pnm );
-+ cp += sprintf( cp, "PRV : %s\n", card->info.prv );
-+ cp += sprintf( cp, "PSN : 0x%08x\n", card->info.cid.psn );
-+ cp += sprintf( cp, "MDT : %s\n", card->info.mdt );
-+ cp += sprintf( cp, "Capacity: %dKB\n",
-+ (card->info.capacity>>10) );
-+#endif
-+ up_read( &card->ctrlr->update_sem );
-+
-+ ret = cp - page;
-+error:
-+ return ret;
-+}
-+#endif
-+
-+/*************************************
-+ * MMC core interface implementation *
-+ *************************************/
-+int mmc_notify_add( mmc_card_t card )
-+{
-+ int ret = 0;
-+ mmc_notifier_t notifier;
-+
-+ __ENTER0();
-+ if ( card ) {
-+ for ( notifier = mmc_notifier; notifier;
-+ notifier = notifier->next )
-+ if ( notifier->add )
-+ if ( (ret = notifier->add( card )) )
-+ break;
-+ }
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+EXPORT_SYMBOL( mmc_notify_add );
-+
-+int mmc_notify_remove( mmc_card_t card )
-+{
-+ int ret = 0;
-+ mmc_notifier_t notifier;
-+
-+ __ENTER0();
-+ if ( card ) {
-+ for ( notifier = mmc_notifier; notifier;
-+ notifier = notifier->next )
-+ if ( notifier->remove )
-+ if ( (ret = notifier->remove( card )) )
-+ break;
-+ }
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+EXPORT_SYMBOL( mmc_notify_remove );
-+
-+int mmc_update_card_stack( int host )
-+{
-+ int ret = -EINVAL;
-+ mmc_controller_t ctrlr;
-+
-+ __ENTER0();
-+
-+ if ( (host < 0) || (host >= MMC_CONTROLLERS_MAX) )
-+ goto error;
-+
-+ down_read( &mmc_controller_sem );
-+ if ( (ctrlr = mmc_controller[host]) ) {
-+ down_write( &ctrlr->update_sem );
-+ (void)__mmc_update_card_stack( ctrlr );
-+ up_write( &ctrlr->update_sem );
-+ }
-+ up_read( &mmc_controller_sem );
-+ ret = 0;
-+error:
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+EXPORT_SYMBOL( mmc_update_card_stack );
-+
-+ssize_t mmc_read( mmc_card_t card, mmc_transfer_mode_t mode, char *buf, size_t size, loff_t *paddr )
-+{
-+ ssize_t ret = -EIO;
-+ mmc_controller_t ctrlr;
-+ mmc_data_transfer_req_rec_t transfer;
-+
-+ if ( !paddr ) {
-+ ret = -EINVAL;
-+ goto error;
-+ }
-+
-+ if ( !card ) {
-+ ret = -ENODEV;
-+ goto error;
-+ }
-+
-+ __ENTER( "card=%p usage=%d mode=%d buf=%p size=%d addr=%x",
-+ card, card->usage, mode, buf, size, *paddr );
-+
-+ ctrlr = card->ctrlr;
-+ if ( (ret = mmc_acquire_io( ctrlr, card )) )
-+ goto error;
-+
-+ memset( &transfer, 0, sizeof( mmc_data_transfer_req_rec_t ) );
-+ transfer.cmd = MMC_READ;
-+ transfer.mode = mode;
-+ transfer.type = MMC_USER; /* FIXME: buffer cache */
-+ transfer.buf = buf;
-+ transfer.addr = *paddr;
-+ transfer.cnt = size;
-+
-+/* max block size defined by CSD[read_bl_len] */
-+ transfer.blksz = card->info.read_bl_len;
-+ transfer.nob = size / transfer.blksz;
-+ if ( (size - (transfer.nob * transfer.blksz)) > 0 )
-+ transfer.nob++;
-+
-+/* TODO: controller may restrict maximum block size; set block size
-+ * and number of blocks that their accumulated length fit to
-+ * CSD[READ_BL_LEN] not to bother with block misalignment in multiple
-+ * block transfers */
-+ ctrlr = card->ctrlr;
-+ if ( transfer.blksz > ctrlr->tmpl->block_size_max ) {
-+ ret = -EINVAL; /* FIXME */
-+ goto error;
-+ }
-+
-+ if ( ctrlr->stack.selected != card ) {
-+ if ( (ret = ctrlr->tmpl->setup_card( ctrlr, card )) )
-+ goto err_mmc;
-+ ctrlr->stack.selected = card;
-+ }
-+
-+ switch( mode ) {
-+ case MMC_TRANSFER_MODE_STREAM:
-+ if ( !ctrlr->tmpl->stream_read ) {
-+ ret = -ENXIO;
-+ goto err_down;
-+ }
-+/* TODO: The max clock frequency for stream read operation is given by
-+ the following formula:
-+ max speed = min ( TRAN_SPEED, 8*2^(READ_BL_LEN) - NSAC/TAAC )
-+
-+ If the card is not able to sustain data transfer it will set the
-+ UNDERRUN error bit in the status register, abort the transmission
-+ and wait in the Data state for a stop command
-+ */
-+ ret = ctrlr->tmpl->stream_read( ctrlr, &transfer );
-+ break;
-+
-+ case MMC_TRANSFER_MODE_BLOCK_SINGLE:
-+ if ( !ctrlr->tmpl->read_block ) {
-+ ret = -ENXIO;
-+ goto err_down;
-+ }
-+/* TODO: buffer size and data alignment (v3.4, p.29):
-+ if CSD[READ_BL_PARTIAL] is set, smaller blocks whose starting
-+ and ending address are entirely contained within one physical
-+ block (as defined by CSD[READ_BL_LEN]) may also be transmitted
-+ */
-+ transfer.type = MMC_KERNEL; /* FIXME */
-+ ret = ctrlr->tmpl->read_block( ctrlr, &transfer );
-+ break;
-+
-+ case MMC_TRANSFER_MODE_BLOCK_MULTIPLE:
-+ if ( !ctrlr->tmpl->read_mblock ) {
-+ ret = -ENXIO;
-+ goto err_down;
-+ }
-+
-+ if ( transfer.nob > ctrlr->tmpl->nob_max ) {
-+ ret = -EINVAL;
-+ goto error;
-+ }
-+/* TODO: buffer size and data alignment (v3.4, p.29):
-+ if the host uses patrial blocks whose accumulated length is
-+ not block aligned and block misalignment is not allowed, the
-+ card should detect a block misalignment error condition at the
-+ beginning of the first misaligned block
-+ */
-+ transfer.type = MMC_KERNEL; /* FIXME */
-+ ret = ctrlr->tmpl->read_mblock( card->ctrlr, &transfer );
-+ break;
-+
-+ default:
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "request for unknown transfer type\n" );
-+ ret = -EINVAL;
-+ }
-+err_mmc:
-+ ret = __mmc_check_error( card, ret );
-+ if ( ret >= 0 ) {
-+ ret = size - transfer.cnt;
-+ *paddr += ret;
-+ }
-+err_down:
-+ mmc_release_io( ctrlr, card );
-+error:
-+ __LEAVE("ret=%d", ret);
-+ return ret;
-+}
-+EXPORT_SYMBOL( mmc_read );
-+
-+ssize_t mmc_write( mmc_card_t card, mmc_transfer_mode_t mode, const char *buf, size_t size, loff_t *paddr )
-+{
-+ ssize_t ret = -ESPIPE;
-+ mmc_controller_t ctrlr;
-+ mmc_data_transfer_req_rec_t transfer;
-+
-+ if ( !paddr ) {
-+ ret = -EINVAL;
-+ goto error;
-+ }
-+
-+ if ( !card ) {
-+ ret = -ENODEV;
-+ goto error;
-+ }
-+
-+ __ENTER( "card=%p usage=%d mode=%d buf=%p size=%d addr=%llx",
-+ card, card->usage, mode, buf, size, *paddr );
-+
-+ ctrlr = card->ctrlr;
-+ if ( (ret = mmc_acquire_io( ctrlr, card )) )
-+ goto error;
-+
-+ memset( &transfer, 0, sizeof( mmc_data_transfer_req_rec_t ) );
-+ transfer.cmd = MMC_WRITE;
-+ transfer.mode = mode;
-+ transfer.type = MMC_USER; /* FIXME: buffer cache */
-+ transfer.buf = (char *)buf;
-+ transfer.addr = *paddr;
-+ transfer.cnt = size;
-+
-+/* max block size defined by CSD[write_bl_len] */
-+ transfer.blksz = card->info.write_bl_len;
-+ transfer.nob = size / transfer.blksz;
-+ if ( (size - (transfer.nob * transfer.blksz)) > 0 )
-+ transfer.nob++;
-+
-+/* TODO: controller may restrict maximum block size; set block size
-+ * and number of blocks that their accumulated length fit to
-+ * CSD[WRITE_BL_LEN] not to bother with block misalignment in multiple
-+ * block transfers */
-+ ctrlr = card->ctrlr;
-+ if ( transfer.blksz > ctrlr->tmpl->block_size_max ) {
-+ ret = -EINVAL; /* FIXME */
-+ goto error;
-+ }
-+
-+ if ( ctrlr->stack.selected != card ) {
-+ if ( (ret = ctrlr->tmpl->setup_card( ctrlr, card )) )
-+ goto err_mmc;
-+ ctrlr->stack.selected = card;
-+ }
-+
-+ transfer.cmd = MMC_WRITE;
-+ transfer.mode = mode;
-+ transfer.type = MMC_USER;
-+ switch( mode ) {
-+ case MMC_TRANSFER_MODE_STREAM:
-+ if ( !ctrlr->tmpl->stream_write ) {
-+ ret = -ENXIO;
-+ goto err_down;
-+ }
-+ ret = ctrlr->tmpl->stream_write( ctrlr, &transfer );
-+ break;
-+
-+ case MMC_TRANSFER_MODE_BLOCK_SINGLE:
-+ if ( !ctrlr->tmpl->write_block ) {
-+ ret = -ENXIO;
-+ goto err_down;
-+ }
-+ transfer.type = MMC_KERNEL; /* FIXME */
-+ ret = ctrlr->tmpl->write_block( ctrlr, &transfer );
-+ break;
-+
-+ case MMC_TRANSFER_MODE_BLOCK_MULTIPLE:
-+ if ( !ctrlr->tmpl->write_mblock ) {
-+ ret = -ENXIO;
-+ goto err_down;
-+ }
-+ transfer.type = MMC_KERNEL; /* FIXME */
-+ ret = ctrlr->tmpl->write_mblock( card->ctrlr, &transfer );
-+ break;
-+
-+ default:
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "request for unknown transfer type\n" );
-+ }
-+
-+err_mmc:
-+ ret = __mmc_check_error( card, ret ); /* FIXME */
-+ if ( ret >= 0 ) {
-+ ret = size - transfer.cnt;
-+ *paddr += ret;
-+ }
-+err_down:
-+ mmc_release_io( ctrlr, card );
-+error:
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+EXPORT_SYMBOL( mmc_write );
-+
-+int mmc_ioctl( mmc_card_t card, unsigned int cmd, unsigned long arg )
-+{
-+ int ret = -EINVAL;
-+ mmc_controller_t ctrlr;
-+
-+ if ( !card ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "bad card reference\n" )
-+ goto error;
-+ }
-+
-+ ctrlr = card->ctrlr;
-+ if ( mmc_acquire_io( ctrlr, card ) ) {
-+ ret = -ENXIO;
-+ goto error;
-+ }
-+
-+ switch ( cmd ) {
-+ case IOCMMCGCARDESC:
-+ if ( copy_to_user( (void *)arg, &card->info, sizeof( mmc_card_info_rec_t ) ) )
-+ ret = -EFAULT;
-+ break;
-+/*
-+ * 1. TODO: erase region
-+ * 2. TODO: set/unset write protection, lock/password
-+ */
-+ default:
-+ ret = -ENOIOCTLCMD;
-+ }
-+
-+ mmc_release_io( ctrlr, card );
-+error:
-+ return ret;
-+}
-+EXPORT_SYMBOL( mmc_ioctl );
-+
-+/*
-+ * registry stuff
-+ */
-+mmc_card_t mmc_get_card( int host, int slot )
-+{
-+ mmc_card_t ret = NULL;
-+ mmc_controller_t ctrlr = NULL;
-+ int found;
-+
-+ __ENTER( "host=%d, card=%d", host, slot );
-+
-+ if ( ((host < 0) || (host >= MMC_CONTROLLERS_MAX))
-+ && ((slot < 0) || (slot >= MMC_CARDS_MAX)) )
-+ goto error;
-+
-+ down_read( &mmc_controller_sem );
-+
-+ if ( (ctrlr = mmc_controller[host]) ) {
-+ down_write( &ctrlr->update_sem );
-+ if ( ctrlr->stack.ncards > 0 ) {
-+ ret = ctrlr->stack.first;
-+ found = FALSE;
-+ while ( ret ) {
-+ if ( (ret->slot == slot) && (ret->state !=
-+ MMC_CARD_STATE_UNPLUGGED) ) {
-+ found = TRUE;
-+ break;
-+ }
-+ ret = ret->next;
-+ }
-+
-+ if ( found ) {
-+ if ( ctrlr->tmpl->owner ) {
-+ ++ctrlr->usage;
-+ MMC_DEBUG( MMC_DEBUG_LEVEL2,
-+ "'%s' use count increased (%d)\n",
-+ ctrlr->tmpl->name, ctrlr->usage );
-+ __MOD_INC_USE_COUNT( ctrlr->tmpl->owner );
-+ }
-+ ++ret->usage;
-+ } else
-+ ret = NULL;
-+ }
-+ up_write( &ctrlr->update_sem );
-+ }
-+ up_read( &mmc_controller_sem );
-+error:
-+ __LEAVE("ret=0x%p usage=%d", ret, ret ? ret->usage : -1 );
-+ return ret;
-+}
-+EXPORT_SYMBOL( mmc_get_card );
-+
-+void mmc_put_card( mmc_card_t card )
-+{
-+ mmc_card_t tmp = NULL;
-+ mmc_controller_t ctrlr;
-+ int found;
-+
-+ __ENTER( "card=0x%p", card );
-+
-+ if ( !card )
-+ goto error;
-+
-+ ctrlr = card->ctrlr;
-+
-+ down_read( &mmc_controller_sem );
-+ if ( !ctrlr || (ctrlr != mmc_controller[ctrlr->slot]) ) {
-+ MMC_ERROR( "bad controller reference: ctrlr=0x%p\n", ctrlr );
-+ goto err_down;
-+ }
-+
-+ down_write( &ctrlr->update_sem );
-+ if ( ctrlr->stack.ncards > 0 ) {
-+ tmp = ctrlr->stack.first;
-+ found = FALSE;
-+ while ( tmp ) {
-+ if ( tmp == card ) {
-+ found = TRUE;
-+ break;
-+ }
-+ tmp = tmp->next;
-+ }
-+
-+ if ( found ) {
-+ if ( tmp->usage > 0 ) {
-+ --tmp->usage;
-+ MMC_DEBUG( MMC_DEBUG_LEVEL2, "usage=%d"
-+ "owner=0x%p\n", tmp->usage,
-+ ctrlr->tmpl->owner );
-+ if ( !tmp->usage && (ctrlr->usage > 0)
-+ && ctrlr->tmpl->owner ) {
-+ --ctrlr->usage;
-+ MMC_DEBUG( MMC_DEBUG_LEVEL2,
-+ "'%s' use count "
-+ "decreased (%d)\n",
-+ ctrlr->tmpl->name,
-+ ctrlr->usage );
-+ __MOD_DEC_USE_COUNT(
-+ ctrlr->tmpl->owner );
-+ }
-+ }
-+ } else
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "bad card reference\n" );
-+
-+ }
-+ up_write( &ctrlr->update_sem );
-+err_down:
-+ up_read( &mmc_controller_sem );
-+error:
-+ __LEAVE( "found=%d", found );
-+ return;
-+}
-+EXPORT_SYMBOL( mmc_put_card );
-+
-+static inline void *mmc_register_user( mmc_notifier_t notifier )
-+{
-+ mmc_notifier_t ret = NULL, last = mmc_notifier;
-+
-+ MOD_INC_USE_COUNT;
-+ if ( notifier ) {
-+ down_write( &mmc_notifier_sem );
-+
-+ notifier->next = NULL;
-+ if ( !last ) {
-+ mmc_notifier = notifier;
-+ ret = notifier;
-+ } else {
-+ while ( last->next ) {
-+ if ( last == notifier ) {
-+ MOD_DEC_USE_COUNT;
-+ break;
-+ }
-+ last = last->next;
-+ }
-+ if ( last != notifier ) {
-+ last->next = notifier;
-+ ret = notifier;
-+ }
-+ }
-+ up_write( &mmc_notifier_sem );
-+ }
-+/* notify new user about the cards present in the system */
-+ if ( ret && ret->add ) {
-+ int i;
-+
-+ down_read( &mmc_controller_sem );
-+ for ( i = 0; i < mmc_ncontrollers; i++ ) {
-+ mmc_controller_t ctrlr = mmc_controller[i];
-+
-+ down_read( &ctrlr->update_sem ); /* FIXME */
-+ __mmc_card_stack_foreach( &ctrlr->stack,
-+ ret->add, FALSE );
-+ up_read( &ctrlr->update_sem ); /* FIXME */
-+ }
-+ up_read( &mmc_controller_sem );
-+ }
-+/* error: */
-+ __LEAVE( "mmc_notifier=0x%p, mmc_notifier->next=0x%p",
-+ mmc_notifier, mmc_notifier ? mmc_notifier->next : NULL );
-+ return ret;
-+}
-+
-+static inline mmc_controller_t mmc_register_controller( mmc_controller_tmpl_t tmpl, size_t extra )
-+{
-+ mmc_controller_t ret = NULL;
-+ int found;
-+ int i;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ down_write( &mmc_controller_sem );
-+
-+ if ( mmc_ncontrollers >= MMC_CONTROLLERS_MAX ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "there're too many controllers\n" );
-+ goto error;
-+ }
-+
-+ found = FALSE;
-+ for ( i = 0; i < MMC_CONTROLLERS_MAX; i++ )
-+ if ( !mmc_controller[i] ) {
-+ found = TRUE;
-+ break;
-+ }
-+
-+ if ( !found ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "there're no empty slots\n" );
-+ goto error;
-+ }
-+
-+ if ( !tmpl->init ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "host template lacks 'init()'\n" );
-+ goto error;
-+ }
-+
-+ if ( !tmpl->probe ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "host template lacks 'probe()'\n" );
-+ goto error;
-+ }
-+
-+ if ( !tmpl->init_card_stack ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "host template lacks 'init_card_stack()'\n" );
-+ goto error;
-+ }
-+
-+ if ( !tmpl->update_acq ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "host template lacks 'update_acq()'\n" );
-+ goto error;
-+ }
-+
-+ if ( !tmpl->check_card_stack ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "host template lacks 'check_card_stack()'\n" );
-+ goto error;
-+ }
-+
-+ if ( !tmpl->setup_card ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "host template lacks 'setup_card()'\n" );
-+ goto error;
-+ }
-+
-+ ret = kmalloc( sizeof( mmc_controller_rec_t ) + extra, GFP_ATOMIC ); /* FIXME: ISA + GFP_DMA */
-+ if ( !ret ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "out of memory\n" );
-+ goto error;
-+ }
-+
-+ memset( ret, 0, sizeof( mmc_controller_rec_t ) + extra );
-+
-+ if ( (tmpl->probe( ret ) != 1) ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "controller probe failed\n" );
-+ goto err_free;
-+ }
-+
-+ if ( tmpl->init( ret ) ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "controller initialization failure\n" );
-+ goto err_free;
-+ }
-+
-+ ret->state = MMC_CONTROLLER_FOUND;
-+ ret->slot = i;
-+ ret->tmpl = tmpl;
-+ init_MUTEX( &ret->io_sem );
-+ init_rwsem( &ret->update_sem );
-+#ifdef CONFIG_PROC_FS
-+ if ( mmc_proc_dir ) {
-+ snprintf( ret->proc_name, sizeof( ret->proc_name ),
-+ "host%d", ret->slot );
-+ ret->proc = proc_mkdir( ret->proc_name, mmc_proc_dir );
-+ }
-+#endif
-+
-+/* initialize card stack */
-+ if ( ret->tmpl->init_card_stack( ret ) ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "card stack initialization failure\n" );
-+ if ( ret->tmpl->remove )
-+ ret->tmpl->remove( ret ); /* FIXME */
-+ goto err_free;
-+ }
-+
-+ mmc_controller[ret->slot] = ret;
-+ ++mmc_ncontrollers;
-+
-+/* notify users */
-+ if ( ret->stack.ncards > 0 ) {
-+ down_read( &mmc_notifier_sem );
-+ if ( (i = __mmc_card_stack_foreach( &ret->stack, mmc_notify_add, FALSE ) ) < 0 )
-+ MMC_ERROR( "device add notification failed at slot %d\n", -i );
-+ up_read( &mmc_notifier_sem );
-+ }
-+ goto out;
-+
-+err_free:
-+#ifdef CONFIG_PROC_FS
-+ if ( ret->proc )
-+ remove_proc_entry( ret->proc_name, mmc_proc_dir );
-+#endif
-+ kfree( ret );
-+error:
-+ ret = NULL;
-+ MOD_DEC_USE_COUNT;
-+out:
-+ up_write( &mmc_controller_sem );
-+ return ret;
-+}
-+
-+static inline mmc_card_t mmc_register_card( mmc_card_t card )
-+{
-+ mmc_card_t ret = NULL;
-+ mmc_controller_t ctrlr;
-+
-+ if ( !card || !card->ctrlr )
-+ goto error;
-+
-+ ctrlr = card->ctrlr;
-+#ifdef CONFIG_PROC_FS
-+ if ( ctrlr->proc ) {
-+ snprintf( card->proc_name, sizeof( card->proc_name ),
-+ "card%d", card->slot );
-+ card->proc = create_proc_read_entry( card->proc_name,
-+ 0444, ctrlr->proc,
-+ mmc_proc_read_card_info, card );
-+ }
-+#endif
-+ mmc_notify_add( card );
-+error:
-+ return ret;
-+}
-+
-+void *mmc_register( mmc_reg_type_t reg_type, void *tmpl, size_t extra )
-+{
-+ void *ret = NULL;
-+
-+ switch ( reg_type ) {
-+ case MMC_REG_TYPE_CARD:
-+ ret = mmc_register_card( (mmc_card_t)tmpl );
-+ break;
-+
-+ case MMC_REG_TYPE_USER:
-+ ret = mmc_register_user( (mmc_notifier_t)tmpl );
-+ break;
-+
-+ case MMC_REG_TYPE_HOST:
-+ ret = mmc_register_controller( (mmc_controller_tmpl_t)tmpl, extra );
-+ break;
-+
-+ default:
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "register request for unknown type\n" );
-+ }
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL( mmc_register );
-+
-+static inline void mmc_unregister_user( mmc_notifier_t notifier )
-+{
-+ mmc_notifier_t prev = mmc_notifier;
-+ int found = FALSE;
-+
-+ if ( notifier ) {
-+ down_write( &mmc_notifier_sem );
-+
-+ if ( mmc_notifier == notifier) {
-+ mmc_notifier = prev->next;
-+ found = TRUE;
-+
-+ } else if ( mmc_notifier ) {
-+ while( prev ) {
-+ if ( prev->next == notifier ) {
-+ found = TRUE;
-+ prev->next = prev->next->next;
-+ break;
-+ }
-+ prev = prev->next;
-+ }
-+ }
-+
-+ if ( found ) {
-+ if ( notifier->remove ) {
-+ int i;
-+
-+ down_read( &mmc_controller_sem );
-+ for ( i = 0; i < mmc_ncontrollers; i++ ) {
-+ mmc_controller_t ctrlr =
-+ mmc_controller[i];
-+
-+ down_read( &ctrlr->update_sem );
-+ __mmc_card_stack_foreach( &ctrlr->stack, notifier->remove, FALSE );
-+ up_read( &ctrlr->update_sem );
-+ }
-+ up_read( &mmc_controller_sem );
-+ }
-+ }
-+
-+ up_write( &mmc_notifier_sem );
-+ }
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static inline void mmc_unregister_controller( mmc_controller_t ctrlr )
-+{
-+ if ( !ctrlr || (mmc_controller[ctrlr->slot] != ctrlr ) ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "bad unregister request\n" );
-+ goto error;
-+ }
-+
-+ down_write( &mmc_controller_sem );
-+
-+/* notify users */
-+ if ( ctrlr->stack.ncards > 0 ) {
-+ int slot;
-+
-+ down_read( &mmc_notifier_sem );
-+ if ( (slot = __mmc_card_stack_foreach( &ctrlr->stack, mmc_notify_remove, FALSE ) ) )
-+ MMC_ERROR( "device remove notification failed at slot %d\n", -slot );
-+ up_read( &mmc_notifier_sem );
-+ }
-+
-+#ifdef CONFIG_PROC_FS
-+ if ( ctrlr->proc )
-+ remove_proc_entry( ctrlr->proc_name, mmc_proc_dir );
-+#endif
-+
-+ if ( ctrlr->tmpl && ctrlr->tmpl->remove )
-+ ctrlr->tmpl->remove( ctrlr );
-+
-+ mmc_controller[ctrlr->slot] = NULL;
-+ --mmc_ncontrollers;
-+
-+ __mmc_free_controller( ctrlr );
-+
-+ up_write( &mmc_controller_sem );
-+ MOD_DEC_USE_COUNT;
-+error:
-+ return;
-+}
-+
-+void mmc_unregister( mmc_reg_type_t reg_type, void *tmpl )
-+{
-+ switch ( reg_type ) {
-+ case MMC_REG_TYPE_USER:
-+ mmc_unregister_user( (mmc_notifier_t)tmpl );
-+ break;
-+
-+ case MMC_REG_TYPE_HOST:
-+ mmc_unregister_controller( (mmc_controller_t)tmpl );
-+ break;
-+
-+ default:
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "unregister request for unknown type\n" );
-+ }
-+}
-+EXPORT_SYMBOL( mmc_unregister );
-+
-+#ifdef CONFIG_PM
-+/* power management support */
-+static int mmc_pm_callback( struct pm_dev *pmdev, pm_request_t pmreq, void *pmdata )
-+{
-+ int ret = -EINVAL;
-+ mmc_controller_t ctrlr;
-+ int i;
-+
-+ __ENTER( "pmreq=%d", pmreq );
-+
-+ down_read( &mmc_controller_sem );
-+
-+ switch ( pmreq ) {
-+ case PM_SUSPEND:
-+ for ( ret = 0, i = 0; !ret && (i < mmc_ncontrollers); i++ ) {
-+ ctrlr = mmc_controller[i];
-+ if ( ctrlr->tmpl->suspend )
-+ ret = ctrlr->tmpl->suspend( ctrlr );
-+ }
-+ if ( !ret )
-+ break;
-+
-+ case PM_RESUME:
-+ for ( i = mmc_ncontrollers - 1; i >= 0; i-- ) {
-+ ctrlr = mmc_controller[i];
-+ if ( ctrlr->tmpl->resume )
-+ ctrlr->tmpl->resume( ctrlr );
-+ }
-+ ret = 0;
-+ break;
-+
-+ default:
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "unsupported PM request %d\n",
-+ pmreq );
-+ }
-+
-+ up_read( &mmc_controller_sem );
-+/* error: */
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+#endif
-+
-+/* kernel module stuff */
-+static int __init mmc_core_module_init( void )
-+{
-+ int ret = -ENODEV;
-+
-+ memset( &mmc_controller, 0, sizeof( mmc_controller ) );
-+
-+ init_rwsem( &mmc_controller_sem );
-+ init_rwsem( &mmc_notifier_sem );
-+#ifdef CONFIG_PM
-+ if ( !(mmc_pm_dev = pm_register( PM_UNKNOWN_DEV, 0, mmc_pm_callback )) ) MMC_DEBUG( MMC_DEBUG_LEVEL0, "failed to register PM callback\n" );
-+#endif
-+#ifdef CONFIG_PROC_FS
-+ mmc_proc_dir = proc_mkdir( "mmc", NULL );
-+#endif
-+ ret = 0;
-+/* error: */
-+ return ret;
-+}
-+
-+static void __exit mmc_core_module_cleanup( void )
-+{
-+#ifdef CONFIG_PROC_FS
-+ if ( mmc_proc_dir )
-+ remove_proc_entry( "mmc", NULL );
-+#endif
-+#ifdef CONFIG_PM
-+ pm_unregister( mmc_pm_dev );
-+#endif
-+}
-+
-+module_init( mmc_core_module_init );
-+module_exit( mmc_core_module_cleanup );
-+
-+MODULE_LICENSE( "GPL" );
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/mmc/mmc_pxa.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,1902 @@
-+/*
-+ * linux/drivers/mmc/mmc_pxa.c
-+ * driver for Cotulla MMC controller
-+ *
-+ * Authors: Vladimir Shebordaev, Igor Oblakov
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/version.h>
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/delay.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/dma.h>
-+
-+#include <asm/uaccess.h>
-+#include <asm/semaphore.h>
-+
-+#include <mmc/types.h>
-+#include <mmc/mmc.h>
-+#include <mmc/ioctl.h>
-+
-+#include "types.h"
-+#include "mmc.h"
-+#include "mmc_pxa.h"
-+
-+static mmc_controller_t host = NULL;
-+
-+/* service routines */
-+static inline int pxa_mmc_check_state( mmc_controller_t ctrlr, pxa_mmc_state_t state )
-+{
-+ int ret = -1;
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+
-+ if ( hostdata->state != state ) {
-+ //MMC_DEBUG( MMC_DEBUG_LEVEL3, "state (%s vs %s)\n", PXA_MMC_STATE_LABEL( hostdata->state ), PXA_MMC_STATE_LABEL( state ) );
-+ goto error;
-+ }
-+ ret = 0;
-+error:
-+ return ret;
-+}
-+
-+static inline void pxa_mmc_set_state( mmc_controller_t ctrlr, pxa_mmc_state_t state )
-+{
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+
-+ hostdata->state = state;
-+}
-+
-+static inline int pxa_mmc_init_completion( mmc_controller_t ctrlr, u32 mask )
-+{
-+ int ret = -1;
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+
-+ if ( xchg( &hostdata->busy, 1 ) ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "another interrupt "
-+ "is already been expected\n" );
-+ goto error;
-+ }
-+
-+#if CONFIG_MMC_DEBUG_IRQ
-+ hostdata->irqcnt = 1000;
-+#endif
-+ init_completion( &hostdata->completion );
-+
-+ MMC_I_MASK = MMC_I_MASK_ALL & ~mask;
-+ ret = 0;
-+error:
-+ return ret;
-+}
-+
-+#if CONFIG_MMC_DEBUG_IRQ
-+static struct timer_list timer;
-+static void wait_timeo( unsigned long arg ) {
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)arg;
-+ hostdata->timeo = 1;
-+ complete( &hostdata->completion );
-+ return;
-+}
-+#endif
-+
-+static inline int pxa_mmc_wait_for_completion( mmc_controller_t ctrlr, u32 mask )
-+{
-+ int ret = -1;
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+
-+ if ( !xchg( &hostdata->busy, 1 ) ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "there were no "
-+ "interrupt awaited for\n" );
-+ goto error;
-+ }
-+
-+#if CONFIG_MMC_DEBUG_IRQ
-+ hostdata->timeo = 0;
-+ del_timer( &timer );
-+ timer.function = wait_timeo;
-+ timer.expires = jiffies + 1UL*HZ;
-+ timer.data = (unsigned long)hostdata;
-+ add_timer( &timer );
-+#endif
-+ wait_for_completion( &hostdata->completion );
-+#if CONFIG_MMC_DEBUG_IRQ
-+ del_timer( &timer );
-+ if ( hostdata->timeo ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "irq timed out: " "mask=%x stat=%x\n", mask, MMC_STAT );
-+ goto error;
-+ }
-+#endif
-+ /* verify interrupt */
-+ if ( (mask == ~0UL) || !( hostdata->mmc_i_reg & ~mask ) )
-+ ret = 0;
-+
-+error:
-+ xchg( &hostdata->busy, 0 );
-+ return ret;
-+}
-+
-+static inline int pxa_mmc_stop_bus_clock( mmc_controller_t ctrlr )
-+{
-+ int ret = -1;
-+
-+ if ( !pxa_mmc_check_state( ctrlr, PXA_MMC_FSM_CLK_OFF ) )
-+ goto out;
-+
-+ if ( !pxa_mmc_check_state( ctrlr, PXA_MMC_FSM_BUFFER_IN_TRANSIT ) ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "BUFFER_IN_TRANSIT\n" );
-+ goto error;
-+ }
-+
-+ if ( pxa_mmc_init_completion( ctrlr, MMC_I_MASK_CLK_IS_OFF ) )
-+ goto error;
-+
-+ MMC_STRPCL = MMC_STRPCL_STOP_CLK;
-+
-+ if ( pxa_mmc_wait_for_completion( ctrlr, MMC_I_REG_CLK_IS_OFF ) )
-+ goto error;
-+
-+ //MMC_DEBUG( MMC_DEBUG_LEVEL3, "clock is off\n" );
-+ pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_CLK_OFF );
-+out:
-+ ret = 0;
-+error:
-+ return ret;
-+}
-+
-+static inline int pxa_mmc_start_bus_clock( mmc_controller_t ctrlr )
-+{
-+ int ret = -1;
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+
-+ if ( (hostdata->state != PXA_MMC_FSM_CLK_OFF)
-+ && (hostdata->state != PXA_MMC_FSM_END_IO) ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "illegal state %s\n", PXA_MMC_STATE_LABEL( hostdata->state ) );
-+ goto error;
-+ }
-+
-+ MMC_STRPCL = MMC_STRPCL_START_CLK;
-+ wmb();
-+ //MMC_DEBUG( MMC_DEBUG_LEVEL3, "clock is on\n" );
-+ ret = 0;
-+error:
-+ return ret;
-+}
-+
-+/*
-+int pxa_mmc_complete_cmd( mmc_controller_t ctrlr, mmc_response_fmt_t response )
-+
-+Effects: initializes completion to wait for END_CMD_RES intr,
-+ waits for intr to occur, checks controller and card status
-+Requiers: controller is in CLK_OFF state
-+Modifies: moves controller to the END_CMD state
-+Returns:
-+*/
-+static mmc_error_t pxa_mmc_complete_cmd( mmc_controller_t ctrlr, mmc_response_fmt_t format, int send_abort )
-+{
-+ mmc_error_t ret = MMC_ERROR_GENERIC;
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+ int mask, nwords;
-+ u32 status;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD%d(0x%04x%04x)\n", MMC_CMD & 0x3f, MMC_ARGH, MMC_ARGL);
-+
-+/* FIXME: check arguments */
-+
-+ if ( (hostdata->state != PXA_MMC_FSM_CLK_OFF)
-+ && (hostdata->state != PXA_MMC_FSM_END_IO) ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "illegal state %s\n",
-+ PXA_MMC_STATE_LABEL( hostdata->state ) );
-+ goto error;
-+ }
-+
-+ mask = MMC_I_MASK_END_CMD_RES;
-+ if ( pxa_mmc_init_completion( ctrlr, mask ) )
-+ goto error;
-+
-+ MMC_PRTBUF = MMC_PRTBUF_BUF_FULL;
-+/* start the clock */
-+ if ( pxa_mmc_start_bus_clock( ctrlr ) )
-+ goto error;
-+
-+/* wait for END_CMD_RES intr */
-+ if ( pxa_mmc_wait_for_completion( ctrlr, MMC_I_REG_END_CMD_RES ) )
-+ goto error;
-+
-+/* check status */
-+ if ( hostdata->mmc_stat & MMC_STAT_TIME_OUT_RESPONSE ) {
-+ // MMC_DEBUG(MMC_DEBUG_LEVEL3, "response timeout\n");
-+ ret = MMC_ERROR_TIME_OUT_RESPONSE;
-+ goto error;
-+
-+ } else if ( hostdata->mmc_stat & MMC_STAT_READ_TIME_OUT ) {
-+ // MMC_DEBUG(MMC_DEBUG_LEVEL3, "read timeout\n");
-+ ret = MMC_ERROR_READ_TIME_OUT;
-+ goto error;
-+
-+ } else if ( hostdata->mmc_stat & MMC_STAT_RES_CRC_ERROR ) {
-+ // MMC_DEBUG(MMC_DEBUG_LEVEL3, "response crc err\n");
-+ ret = MMC_ERROR_RES_CRC_ERROR;
-+ goto error;
-+
-+ } else if ( hostdata->mmc_stat & MMC_STAT_CRC_READ_ERROR ) {
-+ // MMC_DEBUG(MMC_DEBUG_LEVEL3, "read crc err\n");
-+ ret = MMC_ERROR_CRC_READ_ERROR;
-+ goto error;
-+
-+ } else if ( hostdata->mmc_stat & MMC_STAT_CRC_WRITE_ERROR ) {
-+ // MMC_DEBUG(MMC_DEBUG_LEVEL3, "write crc err\n");
-+ ret = MMC_ERROR_CRC_WRITE_ERROR;
-+ goto error;
-+ }
-+
-+ nwords = (format == MMC_NORESPONSE) ? 0 :
-+ (format == MMC_R1) ? 3 :
-+ (format == MMC_R2) ? 8 :
-+ (format == MMC_R3) ? 3 :
-+ -1;
-+ ret = nwords;
-+ if ( nwords > 0 ) {
-+ register int i;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "nwords=%d\n", nwords );
-+ for ( i = nwords - 1; i >= 0 ; i-- ) {
-+ u32 res = MMC_RES;
-+ int ibase = i<<1;
-+
-+ hostdata->mmc_res[ibase] = ((u8 *)&res)[0];
-+ hostdata->mmc_res[ibase + 1] = ((u8 *)&res)[1];
-+ --ret;
-+ }
-+#ifdef CONFIG_MMC_DEBUG
-+ switch ( format ) {
-+ case MMC_R1:
-+ MMC_DUMP_R1( ctrlr );
-+ break;
-+ case MMC_R2:
-+ MMC_DUMP_R2( ctrlr );
-+ break;
-+ case MMC_R3:
-+ MMC_DUMP_R3( ctrlr );
-+ break;
-+ default:
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3,
-+ "unknown response format\n" );
-+ ret = MMC_ERROR_GENERIC;
-+ goto error;
-+ }
-+#endif
-+
-+/* check card status for R1(b) commands */
-+ if ( format == MMC_R1 ) {
-+ u8 cmd;
-+
-+ ((u8 *)&status)[0] = hostdata->mmc_res[1];
-+ ((u8 *)&status)[1] = hostdata->mmc_res[2];
-+ ((u8 *)&status)[2] = hostdata->mmc_res[3];
-+ ((u8 *)&status)[3] = hostdata->mmc_res[4];
-+ cmd = PXA_MMC_RESPONSE( ctrlr, 5 )&0x3f;
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3,
-+ //printk( KERN_INFO __FUNCTION__"(): "
-+ "cmd=%u status: 0x%08x\n",
-+ cmd, status );
-+ switch ( cmd ) {
-+ case 11:
-+ case 18:
-+ case 20:
-+ case 25:
-+ if ( !(status & 0x00000100) ) /* FIXME */
-+ goto mmc_error;
-+ default:
-+ break;
-+ }
-+ if ( status & MMC_CARD_STATUS_OUT_OF_RANGE ) {
-+ ret = MMC_ERROR_OUT_OF_RANGE;
-+ goto mmc_error;
-+ } else if ( status & MMC_CARD_STATUS_ADDRESS_ERROR ) {
-+ ret = MMC_ERROR_ADDRESS_ERROR;
-+ goto mmc_error;
-+ } else if ( status & MMC_CARD_STATUS_BLOCK_LEN_ERROR ) {
-+ ret = MMC_ERROR_ADDRESS_ERROR;
-+ goto mmc_error;
-+ } else if ( status & MMC_CARD_STATUS_ERASE_SEQ_ERROR ) {
-+ ret = MMC_ERROR_ERASE_SEQ_ERROR;
-+ goto mmc_error;
-+ } else if ( status & MMC_CARD_STATUS_ERASE_PARAM ) {
-+ ret = MMC_ERROR_ERASE_PARAM;
-+ goto mmc_error;
-+ } else if ( status & MMC_CARD_STATUS_WP_VIOLATION ) {
-+ ret = MMC_ERROR_WP_VIOLATION;
-+ goto mmc_error;
-+ } else if ( status & MMC_CARD_STATUS_CARD_IS_LOCKED ) {
-+ ret = MMC_ERROR_CARD_IS_LOCKED;
-+ goto mmc_error;
-+ } else if ( status & MMC_CARD_STATUS_LOCK_UNLOCK_FAILED ) {
-+ ret = MMC_ERROR_LOCK_UNLOCK_FAILED;
-+ goto mmc_error;
-+ } else if ( status & MMC_CARD_STATUS_COM_CRC_ERROR ) {
-+ ret = MMC_ERROR_COM_CRC_ERROR;
-+ goto mmc_error;
-+ } else if ( status & MMC_CARD_STATUS_ILLEGAL_COMMAND ) {
-+ ret = MMC_ERROR_ILLEGAL_COMMAND;
-+ goto mmc_error;
-+ } else if ( status & MMC_CARD_STATUS_CARD_ECC_FAILED ) {
-+ ret = MMC_ERROR_CARD_ECC_FAILED;
-+ goto mmc_error;
-+ } else if ( status & MMC_CARD_STATUS_CC_ERROR ) {
-+ ret = MMC_ERROR_CC_ERROR;
-+ goto mmc_error;
-+ } else if ( status & MMC_CARD_STATUS_ERROR ) {
-+ ret = MMC_ERROR_ERROR;
-+ goto mmc_error;
-+ } else if ( status & MMC_CARD_STATUS_UNDERRUN ) {
-+ ret = MMC_ERROR_UNDERRUN;
-+ goto mmc_error;
-+ } else if ( status & MMC_CARD_STATUS_OVERRUN ) {
-+ ret = MMC_ERROR_OVERRUN;
-+ goto mmc_error;
-+ } else if ( status & MMC_CARD_STATUS_CID_CSD_OVERWRITE ) {
-+ ret = MMC_ERROR_CID_CSD_OVERWRITE;
-+ goto mmc_error;
-+ } else if ( status & MMC_CARD_STATUS_ERASE_RESET ) {
-+ ret = MMC_ERROR_ERASE_RESET;
-+ goto mmc_error;
-+ }
-+ }
-+ }
-+
-+ if ( ret >= 0 )
-+ pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_END_CMD );
-+ goto out;
-+mmc_error:
-+#if 1
-+ if ( send_abort ) {
-+ /* send CMD12 to abort failed transfer */
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+ MMC_CMD = CMD(12); /* STOP_TRANSMISSION */
-+ MMC_CMDAT = MMC_CMDAT_R1;
-+
-+ if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) )
-+ goto error;
-+
-+ ret = -EIO;
-+ goto error;
-+ }
-+#endif
-+error:
-+ /* move controller to the IDLE state */
-+ pxa_mmc_stop_bus_clock( ctrlr );
-+ pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_IDLE );
-+out:
-+ return ret;
-+}
-+
-+/*
-+int pxa_mmc_complete_io( mmc_controller_t ctrlr, mmc_dir_t cmd, mmc_dir_t dir, mmc_transfer_mode_t mode )
-+
-+Effects: finilizes data transfer request
-+Reqires: controller is in the END_BUFFER state
-+Modifies: moves controller to the IDLE state
-+Returns: zero upon success or error condition code otherwise
-+ */
-+static mmc_error_t pxa_mmc_complete_io( mmc_controller_t ctrlr, mmc_dir_t dir, mmc_transfer_mode_t mode )
-+{
-+ int ret = MMC_ERROR_GENERIC;
-+
-+ if ( pxa_mmc_check_state( ctrlr, PXA_MMC_FSM_END_IO ) )
-+ goto error;
-+
-+ switch ( mode ) {
-+ case MMC_TRANSFER_MODE_STREAM: /* FIXME */
-+ if ( dir == MMC_WRITE ) {
-+ /* 1. wait for STOP_CMD intr */
-+ if ( (ret = pxa_mmc_init_completion( ctrlr,
-+ MMC_I_MASK_STOP_CMD )) )
-+ goto error;
-+ if ( (ret = pxa_mmc_wait_for_completion( ctrlr,
-+ MMC_I_REG_STOP_CMD )) )
-+ goto error;
-+ }
-+ /* 2. send CMD12 */
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+ MMC_CMD = CMD(12); /* STOP_TRANSMISSION */
-+ MMC_CMDAT = MMC_CMDAT_R1;
-+ if ( dir == MMC_WRITE )
-+ MMC_CMDAT |= MMC_CMDAT_BUSY;
-+
-+ /* 3. wait for CMD12 to complete */
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "ready for CMD12\n" );
-+ if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) )
-+ goto error;
-+
-+ /* 4. wait for DATA_TRAN_DONE intr */
-+ if ( (ret = pxa_mmc_init_completion( ctrlr,
-+ MMC_I_MASK_DATA_TRAN_DONE )) )
-+ goto error;
-+ if ( (ret = pxa_mmc_wait_for_completion( ctrlr,
-+ MMC_I_REG_DATA_TRAN_DONE )) )
-+ goto error;
-+
-+ if ( dir == MMC_WRITE ) {
-+ /* 5. wait for PRG_DONE intr */
-+ if ( (ret = pxa_mmc_init_completion( ctrlr,
-+ MMC_I_MASK_PRG_DONE )) )
-+ goto error;
-+ if ( (ret = pxa_mmc_wait_for_completion( ctrlr,
-+ MMC_I_REG_PRG_DONE )) )
-+ goto error;
-+ }
-+ break;
-+ case MMC_TRANSFER_MODE_BLOCK_MULTIPLE:
-+ /* 1. wait for DATA_TRAN done intr */
-+ if ( (ret = pxa_mmc_init_completion( ctrlr,
-+ MMC_I_MASK_DATA_TRAN_DONE )) )
-+ goto error;
-+ if ( (ret = pxa_mmc_wait_for_completion( ctrlr,
-+ MMC_I_REG_DATA_TRAN_DONE )) )
-+ goto error;
-+
-+ /* 2. send CMD12 */
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+ MMC_CMD = CMD(12); /* STOP_TRANSMISSION */
-+ MMC_CMDAT = MMC_CMDAT_R1;
-+ if ( dir == MMC_WRITE )
-+ MMC_CMDAT |= MMC_CMDAT_BUSY;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD12\n" );
-+ if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) )
-+ goto error;
-+
-+ if ( dir == MMC_WRITE ) {
-+ /* 3. wait for PRG_DONE intr */
-+ if ( (ret = pxa_mmc_init_completion( ctrlr,
-+ MMC_I_MASK_PRG_DONE )) )
-+ goto error;
-+ if ( (ret = pxa_mmc_wait_for_completion( ctrlr,
-+ MMC_I_REG_PRG_DONE )) )
-+ goto error;
-+ }
-+ break;
-+ case MMC_TRANSFER_MODE_BLOCK_SINGLE:
-+ /* 1. wait for DATA_TRAN_DONE intr */
-+ if ( (ret = pxa_mmc_init_completion( ctrlr,
-+ MMC_I_MASK_DATA_TRAN_DONE )) )
-+ goto error;
-+ if ( (ret = pxa_mmc_wait_for_completion( ctrlr,
-+ MMC_I_REG_DATA_TRAN_DONE )) )
-+ goto error;
-+
-+ if ( dir == MMC_WRITE ) {
-+ /* 2. wait for PRG_DONE intr */
-+ if ( (ret = pxa_mmc_init_completion( ctrlr,
-+ MMC_I_MASK_PRG_DONE )) )
-+ goto error;
-+ if ( (ret = pxa_mmc_wait_for_completion( ctrlr,
-+ MMC_I_REG_PRG_DONE )) )
-+ goto error;
-+ }
-+ break;
-+ default:
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "unknown transfer mode\n" );
-+ goto error;
-+ }
-+/* move the controller to the IDLE state */
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+ pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_IDLE );
-+
-+ ret = 0;
-+error:
-+ return ret;
-+}
-+
-+static inline int pxa_mmc_update_acq( mmc_controller_t ctrlr )
-+{
-+ int ret = -EINVAL;
-+ pxa_mmc_hostdata_t hostdata = NULL;
-+ mmc_card_t card = NULL;
-+ mmc_card_stack_rec_t fake;
-+ mmc_card_stack_t stack = &fake;
-+ u16 argl = 0U, argh = 0U;
-+ int ncards = 0;
-+
-+ if ( !ctrlr )
-+ goto error;
-+
-+ hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+
-+ __mmc_card_stack_init( stack );
-+
-+ /* max open-drain mode frequency is 400kHZ */
-+ MMC_CLKRT = MMC_CLKRT_0_3125MHZ;
-+ MMC_RESTO = MMC_RES_TO_MAX; /* set response timeout */
-+
-+ /* discover and add cards to the stack */
-+ /* I. bus operation condition setup */
-+ /* 1) send CMD1 */
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto err_free;
-+
-+ argl = 0x0000;
-+ argh = 0x0004;
-+
-+ MMC_CMD = CMD(1);
-+ MMC_ARGH = argh;
-+ MMC_ARGL = argl;
-+
-+ MMC_CMDAT = MMC_CMDAT_BUSY|MMC_CMDAT_R3;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD1(0x%04x%04x)\n", argh, argl );
-+ ret = pxa_mmc_complete_cmd( ctrlr, MMC_R3, FALSE );
-+ if ( !ret ) {
-+ argh = (PXA_MMC_RESPONSE( ctrlr, 4 ) << 8)
-+ | PXA_MMC_RESPONSE( ctrlr, 3 );
-+ argl = (PXA_MMC_RESPONSE( ctrlr, 2 ) << 8)
-+ | PXA_MMC_RESPONSE( ctrlr, 1 );
-+
-+ } else if ( ret != MMC_ERROR_TIME_OUT_RESPONSE )
-+ goto err_free;
-+
-+ if ( !argh && !argl ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3,
-+ "assuming full voltage range support\n" );
-+ argh = 0x00ff;
-+ argl = 0xff00;
-+ }
-+
-+ /* 2) continuously send CMD1 'till there're busy cards */
-+ for(;;) {
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto err_free;
-+
-+ MMC_CMD = CMD(1);
-+ MMC_ARGH = argh;
-+ MMC_ARGL = argl;
-+
-+ MMC_CMDAT = MMC_CMDAT_BUSY|MMC_CMDAT_R3;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD1(0x%04x%04x)\n", argh, argl );
-+ ret = pxa_mmc_complete_cmd( ctrlr, MMC_R3, FALSE );
-+ if ( ret == MMC_ERROR_TIME_OUT_RESPONSE )
-+ break;
-+
-+ else if ( !ret ) {
-+ /* busy state reported by LOW signal level
-+ * (MMC v3.2, p.58)
-+ *
-+ * Thanks to Alexander Samoutin :)
-+ */
-+ if ( !(PXA_MMC_RESPONSE( ctrlr, 4 ) & 0x80) ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "busy state reported\n");
-+ udelay( 20 );
-+ continue;
-+ } else
-+ break;
-+ } else
-+ goto err_free;
-+ }
-+
-+/* II. card identification: the cards in Ready state
-+ * are the only expected to respond
-+ */
-+ for (;;) {
-+ argh = 0U;
-+ argl = 0U;
-+
-+ /* 1) send CMD2 */
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto err_free;
-+
-+ MMC_CMD = CMD(2);
-+ MMC_ARGH = 0x0003;
-+ MMC_ARGL = 0xf300;
-+ MMC_CMDAT = MMC_CMDAT_R2;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD2(0x%04x%04x)\n", argh, argl );
-+ ret = pxa_mmc_complete_cmd( ctrlr, MMC_R2, FALSE );
-+ if ( ret == MMC_ERROR_TIME_OUT_RESPONSE )
-+ break;
-+
-+ else if ( ret ) /* bus error */
-+ goto err_free;
-+
-+ /* TODO: store CID for the card */
-+
-+ /* 2) assign RCA */
-+ if ( !++ctrlr->rca_next ) /* overflow */
-+ ++ctrlr->rca_next;
-+ argh = ctrlr->rca_next;
-+
-+ /* 3) send it to the card last responded (CMD3) */
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto err_free;
-+
-+ MMC_CMD = CMD(3);
-+ MMC_ARGH = argh;
-+ MMC_ARGL = argl;
-+ MMC_CMDAT = MMC_CMDAT_R1;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD3(0x%04x%04x)\n", argh, argl );
-+ ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE );
-+ if ( ret ) /* CMD3 failed */
-+ goto err_free;
-+
-+ card = __mmc_card_alloc( sizeof( pxa_mmc_card_data_rec_t ) );
-+ if ( !card ) {
-+ MMC_ERROR( "out of memory\n" );
-+ goto err_free;
-+ }
-+
-+ card->info.rca = argh;
-+ card->slot = ctrlr->slot_next++; /* FIXME: minor encoding */
-+ card->ctrlr = ctrlr;
-+
-+ if ( !__mmc_card_stack_add( stack, card ) )
-+ goto err_free;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL2, "added card: "
-+ "slot %d, RCA=0x%04x\n", card->slot, argh );
-+ ++ncards;
-+ }
-+
-+ if ( ncards ) {
-+/* III. read CSD registers of all cards; DSR support also reported there */
-+ for ( card = stack->first; card; card = card->next ) {
-+ pxa_mmc_card_data_t card_data =
-+ (pxa_mmc_card_data_t)card->card_data;
-+
-+ /* 1) send CMD9 */
-+ argh = card->info.rca;
-+ argl = 0U;
-+
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto err_free;
-+
-+ MMC_CMD = CMD(9);
-+ MMC_ARGH = argh;
-+ MMC_ARGL = argl;
-+ MMC_CMDAT = MMC_CMDAT_R2;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3,
-+ "CMD9(0x%04x%04x)\n", argh, argl );
-+ if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R2, FALSE )) )
-+ goto err_free;
-+
-+ memcpy( &card->info.csd, hostdata->mmc_res, 15 );
-+ MMC_DUMP_CSD( card );
-+
-+ card->info.read_bl_len = (1<<card->info.csd.read_bl_len);
-+ card->info.write_bl_len = (1<<card->info.csd.write_bl_len);
-+ card->info.capacity = (card->info.csd.c_size + 1)
-+ * (1<<(card->info.csd.c_size_mult + 2))
-+ * card->info.read_bl_len;
-+ MMC_DEBUG( MMC_DEBUG_LEVEL2, "card capacity=%dMb\n",
-+ card->info.capacity>>20 );
-+ card->info.tran_speed = 20*1024; /* FIXME */
-+ card->info.transfer_mode = MMC_TRANSFER_MODE_BLOCK_SINGLE;
-+ /* 2) set bus operation freq */
-+ card_data->clkrt = pxa_mmc_clkrt( card->info.tran_speed );
-+ /* 3) register card with MMC core */
-+ mmc_register( MMC_REG_TYPE_CARD, card, 0 );
-+ }
-+/* IV. set DSR registers of the cards */
-+#if 0 /* TODO */
-+ if ( card->info.csd.dsr_imp ) {
-+ set_dsr = TRUE;
-+ /* calculate DSR */
-+ }
-+#endif
-+ }
-+#if 0 /* TODO */
-+ if ( set_dsr ) {
-+ /* send CMD4 */
-+ }
-+#endif
-+/* merge list of the newly inserted cards into controller card stack */
-+ if ( !ctrlr->stack.ncards ) {
-+ ctrlr->stack.first = stack->first;
-+ ctrlr->stack.last = stack->last;
-+ } else
-+ ctrlr->stack.last->next = stack->first;
-+
-+ ctrlr->stack.ncards += stack->ncards;
-+
-+ ret = 0;
-+ goto out;
-+err_free:
-+ __mmc_card_stack_free( stack );
-+error:
-+out:
-+ return ret;
-+}
-+
-+/* MMC protocol macros: v3.4, p.120 */
-+static int pxa_mmc_init_card_stack( mmc_controller_t ctrlr )
-+{
-+ int ret = -EIO;
-+ u16 argl = 0U, argh = 0U;
-+
-+ if ( !ctrlr || ctrlr->stack.ncards ) {
-+ ret = -EINVAL;
-+ goto error;
-+ }
-+
-+ /* initialize stack */
-+ /* 1) send CMD0 */
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+ /* max open-drain mode frequency is 400kHZ */
-+ MMC_CLKRT = MMC_CLKRT_0_3125MHZ;
-+ MMC_RESTO = MMC_RES_TO_MAX; /* set response timeout */
-+ MMC_SPI = MMC_SPI_DISABLE;
-+
-+ MMC_CMD = CMD(0); /* CMD0 with zero argument */
-+ MMC_ARGH = argh;
-+ MMC_ARGL = argl;
-+ MMC_CMDAT = MMC_CMDAT_INIT;
-+
-+ //MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD0(0x%04x%04x)\n", argh, argl );
-+ if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_NORESPONSE, FALSE )) )
-+ goto error;
-+
-+ /* update card stack */
-+ if ( (ret = pxa_mmc_update_acq( ctrlr )) )
-+ goto err_free;
-+
-+ /* move the controller to the IDLE state */
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto err_free;
-+
-+ pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_IDLE );
-+
-+ ret = 0;
-+ MMC_DEBUG( MMC_DEBUG_LEVEL2, "ncards=%d\n", ctrlr->stack.ncards );
-+ goto out;
-+
-+err_free:
-+ __mmc_card_stack_free( &ctrlr->stack );
-+error:
-+out:
-+ return ret;
-+}
-+
-+static int pxa_mmc_check_card_stack( mmc_controller_t ctrlr )
-+{
-+ int ret = -1;
-+ mmc_card_t card;
-+
-+ if ( !ctrlr )
-+ goto error;
-+
-+ if ( ctrlr->stack.ncards > 0 ) {
-+/* for each card in the stack: */
-+ for( card = ctrlr->stack.first; card; card = card->next ) {
-+ u16 argh = card->info.rca;
-+ u16 argl = 0UL;
-+
-+/* 1) send CMD9( card->rca ) */
-+ if ( pxa_mmc_stop_bus_clock( ctrlr ) )
-+ goto error;
-+
-+ /* SanDisk's cards do not respond to CMD9 */
-+ MMC_CMD = CMD(13);
-+ MMC_ARGH = argh;
-+ MMC_ARGL = argl;
-+ MMC_CMDAT = MMC_CMDAT_R1;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD13(0x%04x%04x)\n",
-+ argh, argl );
-+ ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE );
-+/* 2) if card responded, it is still there */
-+ if ( ret )
-+ card->state = MMC_CARD_STATE_UNPLUGGED;
-+ }
-+ }
-+ ret = 0;
-+error:
-+ return ret;
-+}
-+
-+/* This procedure links the bus master with a single card
-+ * 1) cross checks with the internal stack management data if a card still
-+ * exists in the slot
-+ * 2) send CMD7( card->public.rca )
-+ * 3) setup data path and controller options
-+ */
-+static int pxa_mmc_setup_card( mmc_controller_t ctrlr, mmc_card_t card )
-+{
-+ int ret = -ENODEV;
-+ pxa_mmc_hostdata_t hostdata;
-+ pxa_mmc_card_data_t card_data;
-+ u16 argh = 0U;
-+#ifdef CONFIG_MMC_DEBUG
-+ u16 argl = 0U;
-+#endif
-+
-+ if ( !ctrlr || !card ) {
-+ ret = -EINVAL;
-+ goto error;
-+ }
-+
-+ if ( card->ctrlr != ctrlr ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "card is on another bus\n" );
-+ goto error;
-+ }
-+
-+ hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+ card_data = (pxa_mmc_card_data_t)card->card_data;
-+
-+ argh = card->info.rca;
-+
-+/* select requested card */
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+ MMC_CMD = CMD(7);
-+ MMC_ARGH = argh;
-+ MMC_CMDAT = MMC_CMDAT_R1;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD7(0x%04x%04x)\n", argh, argl );
-+ if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) )
-+ goto error;
-+
-+/* set controller options */
-+#ifndef CONFIG_MMC_DEBUG
-+ MMC_CLKRT = card_data->clkrt;
-+#endif
-+/* move the controller to the IDLE state */
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+ pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_IDLE );
-+
-+ ret = 0;
-+error:
-+ return ret;
-+}
-+
-+static inline int pxa_mmc_iobuf_init( mmc_controller_t ctrlr, ssize_t cnt )
-+{
-+#ifdef PIO
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+#endif
-+#ifndef PIO
-+/* TODO */
-+#else
-+ hostdata->iobuf.buf.pos = hostdata->iobuf.iodata;
-+ hostdata->iobuf.buf.cnt = cnt;
-+#endif
-+ return 0;
-+}
-+/* TODO: ssize_t pxa_mmc_read_buffer( mmc_controller_t ctrlr, ssize_t cnt )
-+effects: reads at most cnt bytes from the card to the controller I/O buffer;
-+ takes care of partial data transfers
-+requieres:
-+modifies: ctrlr->iobuf
-+returns: number of bytes actually transferred or negative error code if there were any errors
-+ */
-+ssize_t pxa_mmc_read_buffer( mmc_controller_t ctrlr, ssize_t cnt )
-+{
-+ ssize_t ret = -EIO;
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+#ifndef PIO
-+ register int ndesc;
-+ int chan = hostdata->iobuf.buf.chan;
-+ pxa_dma_desc *desc;
-+#endif
-+
-+ if ( (hostdata->state != PXA_MMC_FSM_END_CMD) && (hostdata->state != PXA_MMC_FSM_END_BUFFER) ) {
-+ goto error;
-+ }
-+
-+ if ( cnt > hostdata->iobuf.bufsz )
-+ cnt = hostdata->iobuf.bufsz;
-+
-+ if ( (ret = pxa_mmc_iobuf_init( ctrlr, cnt )) )
-+ goto error;
-+
-+ pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_BUFFER_IN_TRANSIT );
-+#ifndef PIO
-+ if ( pxa_mmc_init_completion( ctrlr, ~MMC_I_MASK_ALL ) ) /* FIXME */
-+ goto error;
-+
-+ if ( (desc = hostdata->iobuf.buf.last_read_desc) ) {
-+ desc->ddadr &= ~DDADR_STOP;
-+ desc->dcmd &= ~(DCMD_ENDIRQEN|DCMD_LENGTH);
-+ desc->dcmd |= (1<<5);
-+ }
-+/* 1) setup descriptors for DMA transfer from the device */
-+ ndesc = (cnt>>5) - 1; /* FIXME: partial read */
-+ desc = &hostdata->iobuf.buf.read_desc[ndesc];
-+ hostdata->iobuf.buf.last_read_desc = desc;
-+ /* TODO: partial read */
-+ desc->ddadr |= DDADR_STOP;
-+ desc->dcmd |= DCMD_ENDIRQEN;
-+/* 2) start DMA channel */
-+ DDADR( chan ) = hostdata->iobuf.buf.read_desc_phys_addr;
-+ DCSR( chan ) |= DCSR_RUN;
-+#else
-+ if ( pxa_mmc_init_completion( ctrlr, MMC_I_MASK_RXFIFO_RD_REQ ) )
-+ goto error;
-+#endif
-+
-+ if ( pxa_mmc_wait_for_completion( ctrlr, ~0UL ) )
-+ goto error;
-+
-+ if ( pxa_mmc_check_state( ctrlr, PXA_MMC_FSM_END_BUFFER ) )
-+ goto error;
-+
-+ if ( !(hostdata->mmc_stat & MMC_STAT_ERRORS) ) /* FIXME */
-+ ret = cnt;
-+error:
-+ return ret;
-+}
-+
-+ssize_t pxa_mmc_write_buffer( mmc_controller_t ctrlr, ssize_t cnt )
-+{
-+ ssize_t ret = -EIO;
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+#ifndef PIO
-+ register int ndesc;
-+ int chan = hostdata->iobuf.buf.chan;
-+ pxa_dma_desc *desc;
-+#endif
-+
-+ if ( (hostdata->state != PXA_MMC_FSM_END_CMD)
-+ && (hostdata->state != PXA_MMC_FSM_END_BUFFER) ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "unexpected state (%s)\n",
-+ PXA_MMC_STATE_LABEL( hostdata->state ) );
-+ goto error;
-+ }
-+
-+ if ( cnt > hostdata->iobuf.bufsz )
-+ cnt = hostdata->iobuf.bufsz;
-+
-+ if ( (ret = pxa_mmc_iobuf_init( ctrlr, cnt )) )
-+ goto error;
-+
-+ pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_BUFFER_IN_TRANSIT );
-+#ifndef PIO
-+ if ( pxa_mmc_init_completion( ctrlr, ~MMC_I_MASK_ALL ) ) /* FIXME */
-+ goto error;
-+ if ( (desc = hostdata->iobuf.buf.last_write_desc) ) {
-+ desc->ddadr &= ~DDADR_STOP;
-+ desc->dcmd &= ~(DCMD_ENDIRQEN|DCMD_LENGTH);
-+ desc->dcmd |= (1<<5);
-+ }
-+/* 1) setup descriptors for DMA transfer to the device */
-+ ndesc = (cnt>>5) - 1; /* FIXME: partial write */
-+ desc = &hostdata->iobuf.buf.write_desc[ndesc];
-+ /* TODO: partial write */
-+ hostdata->iobuf.buf.last_write_desc = desc;
-+ desc->ddadr |= DDADR_STOP;
-+ desc->dcmd |= DCMD_ENDIRQEN;
-+/* 2) start DMA channel */
-+ DDADR( chan ) = hostdata->iobuf.buf.write_desc_phys_addr;
-+ DCSR( chan ) |= DCSR_RUN;
-+#else
-+ if ( pxa_mmc_init_completion( ctrlr, MMC_I_MASK_TXFIFO_WR_REQ ) )
-+ goto error;
-+#endif
-+ if ( pxa_mmc_wait_for_completion( ctrlr, ~0UL ) )
-+ goto error;
-+
-+ if ( pxa_mmc_check_state( ctrlr, PXA_MMC_FSM_END_BUFFER ) )
-+ goto error;
-+
-+ if ( !(hostdata->mmc_stat & MMC_STAT_ERRORS) ) /* FIXME */
-+ ret = cnt;
-+error:
-+ return ret;
-+}
-+
-+/* TODO: ssize_t pxa_mmc_copy_from_buffer( ctrlr, mmc_buftype_t to, char *buf, ssize_t cnt )
-+effects: copies at most cnt bytes from the controller I/O buffer to the user or kernel buffer
-+ pointed by buf
-+requiers:
-+modifies:
-+returns: number of bytes actually transferred or negative error code if there were any errors
-+ */
-+ssize_t pxa_mmc_copy_from_buffer( mmc_controller_t ctrlr, mmc_buftype_t to, char *buf, ssize_t cnt )
-+{
-+ ssize_t ret = -EIO;
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+
-+#ifndef PIO
-+/* TODO: check that DMA channel is not running */
-+#endif
-+ switch ( to ) {
-+ case MMC_USER:
-+ if ( copy_to_user( buf, hostdata->iobuf.iodata, cnt ) ) {
-+ ret = -EFAULT;
-+ goto error;
-+ }
-+ break;
-+ case MMC_KERNEL:
-+ memcpy( buf, hostdata->iobuf.iodata, cnt );
-+ break;
-+ default:
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "unknown buffer type\n" );
-+ goto error;
-+ }
-+ ret = cnt;
-+error:
-+ return ret;
-+}
-+
-+ssize_t pxa_mmc_copy_to_buffer( mmc_controller_t ctrlr, mmc_buftype_t to, char *buf, ssize_t cnt )
-+{
-+ ssize_t ret = -EIO;
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+#ifndef PIO
-+/* check that DMA channel is not running */
-+#endif
-+ switch ( to ) {
-+ case MMC_USER:
-+ if ( copy_from_user( hostdata->iobuf.iodata, buf, cnt ) ) {
-+ ret = -EFAULT;
-+ goto error;
-+ }
-+ break;
-+ case MMC_KERNEL:
-+ memcpy( hostdata->iobuf.iodata, buf, cnt );
-+ break;
-+ default:
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "unknown buffer type\n" );
-+ goto error;
-+ }
-+ ret = cnt;
-+error:
-+ return ret;
-+}
-+
-+/* This procedure sequentally passes the data from the user buffer to the card */
-+static int pxa_mmc_stream_read( mmc_controller_t ctrlr, mmc_data_transfer_req_t transfer )
-+{
-+ int ret = -EIO;
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+ u16 argh = 0UL, argl = 0UL;
-+ ssize_t size = 0;
-+
-+ while ( transfer->cnt > 0 ) {
-+ size = (transfer->cnt < hostdata->iobuf.blksz) ?
-+ transfer->cnt : hostdata->iobuf.blksz;
-+ /* 1. send CMD11 */
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+ argh = transfer->addr >> 16;
-+ argl = transfer->addr;
-+ /* 2. setup controller registers to start stream data transfer */
-+ MMC_CMD = CMD(11); /* READ_DAT_UNTIL_STOP */
-+ MMC_ARGH = argh;
-+ MMC_ARGL = argl;
-+ MMC_NOB = 0xffff;
-+ MMC_BLKLEN = size;
-+ MMC_CMDAT = MMC_CMDAT_R1|MMC_CMDAT_READ|MMC_CMDAT_STREAM|MMC_CMDAT_DATA_EN;
-+#ifndef PIO
-+ MMC_CMDAT |= MMC_CMDAT_MMC_DMA_EN;
-+#endif
-+ /* 3. wait for cmd to complete */
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD11(0x%04x%04x)\n", argh, argl );
-+ if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, TRUE )) )
-+ goto error;
-+
-+ /* 4. transfer the data to the caller supplied buffer */
-+ if ( (ret = pxa_mmc_read_buffer( ctrlr, size )) < 0 )
-+ goto error;
-+
-+ if ( (ret = pxa_mmc_copy_from_buffer( ctrlr, transfer->type, transfer->buf, ret )) < 0 )
-+ goto error;
-+
-+ pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_END_IO );
-+
-+ if ( (ret = pxa_mmc_complete_io( ctrlr, transfer->cmd, transfer->mode )) )
-+ goto error;
-+
-+ transfer->buf += ret;
-+ transfer->addr += ret;
-+ transfer->cnt -= ret;
-+ }
-+ ret = 0;
-+error:
-+ return ret;
-+}
-+
-+/* This procedure reads a data block from a card at a given kernel address */
-+static int pxa_mmc_read_block( mmc_controller_t ctrlr, mmc_data_transfer_req_t transfer )
-+{
-+ int ret = -ENODEV;
-+ u16 argh = 0UL, argl = 0UL;
-+
-+/* send CMD16 (SET_BLOCK_LEN) when requested block size is not the default
-+ * for the current card */
-+ if ( transfer->blksz != ctrlr->stack.selected->info.read_bl_len ) {
-+ argh = transfer->blksz >> 16;
-+ argl = transfer->blksz;
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+ MMC_CMD = CMD(16); /* SET_BLOCK_LEN */
-+ MMC_ARGH = argh;
-+ MMC_ARGL = argl;
-+ MMC_CMDAT = MMC_CMDAT_R1;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3,
-+ "CMD16(0x%04x%04x)\n", argh, argl );
-+ if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) )
-+ goto error;
-+ }
-+
-+/* CMD17 (READ_SINGLE_BLOCK) */
-+ argh = transfer->addr >> 16;
-+ argl = transfer->addr;
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+ MMC_CMD = CMD(17); /* READ_SINGLE_BLOCK */
-+ MMC_ARGH = argh;
-+ MMC_ARGL = argl;
-+ MMC_CMDAT = MMC_CMDAT_R1|MMC_CMDAT_READ|MMC_CMDAT_BLOCK|MMC_CMDAT_DATA_EN;
-+ MMC_NOB = 1;
-+ MMC_BLKLEN = transfer->blksz;
-+#ifndef PIO
-+ MMC_CMDAT |= MMC_CMDAT_MMC_DMA_EN;
-+#endif
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD17(0x%04x%04x)\n", argh, argl );
-+ if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) )
-+ goto error;
-+
-+/* transfer the data to the caller supplied buffer */
-+ if ( (ret = pxa_mmc_read_buffer( ctrlr, transfer->blksz )) < 0 )
-+ goto error;
-+
-+ if ( (ret = pxa_mmc_copy_from_buffer( ctrlr, transfer->type, transfer->buf, ret )) < 0 )
-+ goto error;
-+
-+ transfer->buf += ret;
-+ transfer->cnt -= ret;
-+ transfer->nob -= 1;
-+
-+ pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_END_IO );
-+
-+ if ( (ret = pxa_mmc_complete_io( ctrlr, transfer->cmd, transfer->mode )) )
-+ goto error;
-+
-+ ret = 0;
-+error:
-+ return ret;
-+}
-+
-+/* This procedure sequentally reads data blocks from
-+ * a card to the user buffer. Controller options and block size
-+ * are already set by setup_card(). Data alignment and partial
-+ * data accessibility assumed to be checked by mmc_core */
-+static int pxa_mmc_read_mblock( mmc_controller_t ctrlr, mmc_data_transfer_req_t transfer )
-+{
-+ int ret = -EIO;
-+ u16 argh = 0UL, argl = 0UL;
-+
-+/* send CMD16 (SET_BLOCK_LEN) when requested block size is not the default
-+ * for the current card */
-+ if ( transfer->blksz != ctrlr->stack.selected->info.read_bl_len ) {
-+ argh = transfer->blksz >> 16;
-+ argl = transfer->blksz;
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+ MMC_CMD = CMD(16); /* SET_BLOCK_LEN */
-+ MMC_ARGH = argh;
-+ MMC_ARGL = argl;
-+ MMC_CMDAT = MMC_CMDAT_R1;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD16(0x%04x%04x)\n", argh, argl );
-+ if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) )
-+ goto error;
-+ }
-+
-+ argh = transfer->addr >> 16;
-+ argl = transfer->addr;
-+/* 1. stop bus clock */
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+/* 2. setup controller registers to start multiple block transfer */
-+ MMC_CMD = CMD(18); /* READ_MULTIPLE_BLOCK */
-+ MMC_ARGH = argh;
-+ MMC_ARGL = argl;
-+ MMC_NOB = transfer->nob;
-+ MMC_BLKLEN = transfer->blksz;
-+ MMC_CMDAT = MMC_CMDAT_R1|MMC_CMDAT_READ|MMC_CMDAT_BLOCK|MMC_CMDAT_DATA_EN;
-+#ifndef PIO
-+ MMC_CMDAT |= MMC_CMDAT_MMC_DMA_EN;
-+#endif
-+
-+/* 3. start clock */
-+ if ( (ret = pxa_mmc_start_bus_clock( ctrlr )) )
-+ goto error;
-+
-+/* 4. wait for cmd to complete */
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD18(0x%04x%04x)\n", argh, argl );
-+ if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, TRUE )) )
-+ goto error;
-+
-+/* 6. transfer the data to the caller supplied buffer */
-+ while ( transfer->cnt > 0 ) {
-+ if ( (ret = pxa_mmc_read_buffer( ctrlr, transfer->cnt )) < 0 )
-+ goto error;
-+
-+ if ( (ret = pxa_mmc_copy_from_buffer( ctrlr, transfer->type, transfer->buf, ret )) < 0 )
-+ goto error;
-+
-+ transfer->buf += ret;
-+ transfer->cnt -= ret;
-+ }
-+
-+ pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_END_IO );
-+
-+ if ( (ret = pxa_mmc_complete_io( ctrlr, transfer->cmd, transfer->mode )) )
-+ goto error;
-+
-+ ret = 0;
-+error:
-+ return ret;
-+}
-+
-+/* Sequentally writes the data from a user buffer to the card */
-+static int pxa_mmc_stream_write( mmc_controller_t ctrlr, mmc_data_transfer_req_t transfer )
-+{
-+ int ret = -EIO;
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+ u16 argh = 0UL, argl = 0UL;
-+ ssize_t size = 0;
-+
-+ __ENTER( "transfer: cmd=%d mode=%d type=%d blksz=%d "
-+ "nob=%d buf=%p cnt=%d addr=%Lx", transfer->cmd,
-+ transfer->mode, transfer->type, transfer->blksz,
-+ transfer->nob, transfer->buf, transfer->cnt, transfer->addr );
-+
-+ argh = transfer->addr >> 16;
-+ argl = transfer->addr;
-+/* 1. stop bus clock */
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+/* 2. setup controller registers to start stream data transfer */
-+ MMC_CMD = CMD(20); /* WRITE_DAT_UNTIL_STOP */
-+ MMC_ARGH = argh;
-+ MMC_ARGL = argl;
-+ MMC_NOB = 0xffff;
-+ MMC_BLKLEN = hostdata->iobuf.blksz;
-+ MMC_CMDAT = MMC_CMDAT_R1|MMC_CMDAT_WRITE|MMC_CMDAT_STREAM|MMC_CMDAT_DATA_EN;
-+#ifndef PIO
-+ MMC_CMDAT |= MMC_CMDAT_MMC_DMA_EN;
-+#endif
-+
-+/* 3. wait for cmd to complete */
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD20(0x%04x%04x)\n", argh, argl );
-+ if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, TRUE )) )
-+ goto error;
-+
-+/* 4. transfer the data to the caller supplied buffer */
-+ while ( transfer->cnt > 0 ) {
-+ size = (transfer->cnt < hostdata->iobuf.blksz) ?
-+ transfer->cnt : hostdata->iobuf.blksz;
-+ if ( (ret = pxa_mmc_copy_to_buffer( ctrlr,
-+ transfer->type, transfer->buf, size )) < 0 )
-+ goto error;
-+
-+ if ( (ret = pxa_mmc_write_buffer( ctrlr, ret )) < 0 )
-+ goto error;
-+
-+ transfer->buf += ret;
-+ transfer->cnt -= ret;
-+ }
-+
-+ pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_END_IO );
-+
-+ if ( (ret = pxa_mmc_complete_io( ctrlr, transfer->cmd, transfer->mode )) )
-+ goto error;
-+
-+ ret = 0;
-+error:
-+ return ret;
-+}
-+
-+/* This procedure writes a data block to a card at a given address */
-+static int pxa_mmc_write_block( mmc_controller_t ctrlr, mmc_data_transfer_req_t transfer )
-+{
-+ int ret = -ENODEV;
-+ u16 argh = 0UL, argl = 0UL;
-+
-+/* send CMD16 (SET_BLOCK_LEN) when requested block size is not the default
-+ * for the current card */
-+ if ( transfer->blksz != ctrlr->stack.selected->info.read_bl_len ) {
-+ argh = transfer->blksz >> 16;
-+ argl = transfer->blksz;
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+ MMC_CMD = CMD(16); /* SET_BLOCK_LEN */
-+ MMC_ARGH = argh;
-+ MMC_ARGL = argl;
-+ MMC_CMDAT = MMC_CMDAT_R1;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD16(0x%04x%04x)\n", argh, argl );
-+ if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) )
-+ goto error;
-+ }
-+
-+/* CMD17 (READ_SINGLE_BLOCK) */
-+ argh = transfer->addr >> 16;
-+ argl = transfer->addr;
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+ MMC_CMD = CMD(24); /* WRITE_BLOCK */
-+ MMC_ARGH = argh;
-+ MMC_ARGL = argl;
-+ MMC_CMDAT = MMC_CMDAT_R1|MMC_CMDAT_WRITE|MMC_CMDAT_BLOCK|MMC_CMDAT_DATA_EN;
-+#ifndef PIO
-+ MMC_CMDAT |= MMC_CMDAT_MMC_DMA_EN;
-+#endif
-+ MMC_NOB = 1;
-+ MMC_BLKLEN = transfer->blksz;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD24(0x%04x%04x)\n", argh, argl );
-+ if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) )
-+ goto error;
-+
-+/* transfer the data to the caller supplied buffer */
-+ if ( (ret = pxa_mmc_copy_to_buffer( ctrlr, transfer->type, transfer->buf, transfer->cnt )) < 0 )
-+ goto error;
-+
-+ if ( (ret = pxa_mmc_write_buffer( ctrlr, ret )) < 0 )
-+ goto error;
-+
-+ transfer->buf += ret;
-+ transfer->cnt -= ret;
-+ transfer->nob -= 1;
-+
-+ pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_END_IO );
-+
-+ if ( (ret = pxa_mmc_complete_io( ctrlr, transfer->cmd, transfer->mode )) )
-+ goto error;
-+
-+ ret = 0;
-+error:
-+ return ret;
-+}
-+
-+/* This procedure sequentally writes data blocks to a card at a given address */
-+static ssize_t pxa_mmc_write_mblock( mmc_controller_t ctrlr, mmc_data_transfer_req_t transfer )
-+{
-+ int ret = -EIO;
-+ u16 argh = 0UL, argl = 0UL;
-+
-+/* send CMD16 (SET_BLOCK_LEN) when requested block size is not the default
-+ * for the current card */
-+ if ( transfer->blksz != ctrlr->stack.selected->info.write_bl_len ) {
-+ argh = transfer->blksz >> 16;
-+ argl = transfer->blksz;
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+ MMC_CMD = CMD(16); /* SET_BLOCK_LEN */
-+ MMC_ARGH = argh;
-+ MMC_ARGL = argl;
-+ MMC_CMDAT = MMC_CMDAT_R1;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD16(0x%04x%04x)\n", argh, argl );
-+ if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, FALSE )) )
-+ goto error;
-+ }
-+
-+ argh = transfer->addr >> 16;
-+ argl = transfer->addr;
-+/* 1. stop bus clock */
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+/* 2. setup controller registers to start multiple block transfer */
-+ MMC_CMD = CMD(25); /* WRITE_MULTIPLE_BLOCK */
-+ MMC_ARGH = argh;
-+ MMC_ARGL = argl;
-+ MMC_NOB = transfer->nob;
-+ MMC_BLKLEN = transfer->blksz;
-+ MMC_CMDAT = MMC_CMDAT_R1|MMC_CMDAT_WRITE|MMC_CMDAT_BLOCK|MMC_CMDAT_DATA_EN;
-+#ifndef PIO
-+ MMC_CMDAT |= MMC_CMDAT_MMC_DMA_EN;
-+#endif
-+
-+/* 3. start clock */
-+ if ( (ret = pxa_mmc_start_bus_clock( ctrlr )) )
-+ goto error;
-+
-+/* 4. wait for cmd to complete */
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD25(0x%04x%04x)\n", argh, argl );
-+ if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_R1, TRUE )) )
-+ goto error;
-+
-+/* 6. transfer the data to the caller supplied buffer */
-+ while ( transfer->cnt > 0 ) {
-+ if ( (ret = pxa_mmc_copy_to_buffer( ctrlr, transfer->type,
-+ transfer->buf, transfer->cnt )) < 0 )
-+ goto error;
-+
-+ if ( (ret = pxa_mmc_write_buffer( ctrlr, ret )) < 0 )
-+ goto error;
-+
-+ transfer->buf += ret;
-+ transfer->cnt -= ret;
-+ }
-+
-+ pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_END_IO );
-+
-+ if ( (ret = pxa_mmc_complete_io( ctrlr, transfer->cmd, transfer->mode )) )
-+ goto error;
-+
-+ ret = 0;
-+error:
-+ return ret;
-+}
-+
-+static void pxa_mmc_irq( int irq, void *dev_id, struct pt_regs *regs )
-+{
-+ mmc_controller_t ctrlr = (mmc_controller_t)dev_id;
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+#ifdef PIO
-+ register int i, cnt;
-+ register char *buf;
-+#endif
-+
-+ hostdata->mmc_i_reg = MMC_I_REG;
-+ hostdata->mmc_stat = MMC_STAT;
-+ hostdata->mmc_cmdat = MMC_CMDAT;
-+#if 0
-+ if (hostdata->mmc_i_reg != 0x0010) {
-+ printk("IREG %08x", hostdata->mmc_i_reg);
-+ if (hostdata->mmc_i_reg & 0x0001) printk(" DATA_TRAN_DONE");
-+ if (hostdata->mmc_i_reg & 0x0002) printk(" PRG_DONE");
-+ if (hostdata->mmc_i_reg & 0x0004) printk(" END_CMD");
-+ if (hostdata->mmc_i_reg & 0x0008) printk(" STOP_CMD");
-+ if (hostdata->mmc_i_reg & 0x0010) printk(" CLK_OFF");
-+ if (hostdata->mmc_i_reg & 0x0020) printk(" RX_FIFO");
-+ if (hostdata->mmc_i_reg & 0x0040) printk(" TX_FIFO");
-+ printk("\nSTAT %08x", hostdata->mmc_stat);
-+ if (hostdata->mmc_stat & 0x0001) printk(" READ_TO");
-+ if (hostdata->mmc_stat & 0x0002) printk(" RESP_TO");
-+ if (hostdata->mmc_stat & 0x0004) printk(" WR_CRC");
-+ if (hostdata->mmc_stat & 0x0008) printk(" READ_CRC");
-+ if (hostdata->mmc_stat & 0x0010) printk(" SPI_RD_TKN");
-+ if (hostdata->mmc_stat & 0x0020) printk(" RESP_CRC");
-+ if (hostdata->mmc_stat & 0x0040) printk(" TX_FIFO");
-+ if (hostdata->mmc_stat & 0x0080) printk(" RX_FIFO");
-+ if (hostdata->mmc_stat & 0x0100) printk(" CLK");
-+ if (hostdata->mmc_stat & 0x0800) printk(" DATA_TRAN_DONE");
-+ if (hostdata->mmc_stat & 0x1000) printk(" PRG_DONE");
-+ if (hostdata->mmc_stat & 0x2000) printk(" END_CMD");
-+ printk("\n");
-+ }
-+#endif
-+
-+#if CONFIG_MMC_DEBUG_IRQ
-+ if ( --hostdata->irqcnt <= 0 ) {
-+ printk( KERN_INFO __FUNCTION__"(): irqcnt exceeded\n" );
-+ goto complete;
-+ }
-+#endif
-+ switch ( hostdata->state ) {
-+ case PXA_MMC_FSM_IDLE:
-+ case PXA_MMC_FSM_CLK_OFF:
-+ case PXA_MMC_FSM_END_IO:
-+ case PXA_MMC_FSM_END_BUFFER:
-+ case PXA_MMC_FSM_END_CMD:
-+ goto complete;
-+#ifdef PIO
-+ case PXA_MMC_FSM_BUFFER_IN_TRANSIT:
-+ if ( hostdata->mmc_stat & MMC_STAT_ERRORS )
-+ goto complete;
-+
-+ buf = hostdata->iobuf.buf.pos;
-+ cnt = (hostdata->iobuf.buf.cnt < 32) ?
-+ hostdata->iobuf.buf.cnt : 32;
-+ if ( hostdata->mmc_cmdat & MMC_CMDAT_WRITE ) {
-+ if ( !(hostdata->mmc_stat & MMC_STAT_XMIT_FIFO_EMPTY) )
-+ break;
-+ for ( i = 0; i < cnt; i++ )
-+ MMC_TXFIFO = *buf++;
-+ if ( cnt < 32 )
-+ MMC_PRTBUF = MMC_PRTBUF_BUF_PART_FULL;
-+ } else { /* i.e. MMC_CMDAT_READ */
-+ if( !(hostdata->mmc_stat & MMC_STAT_RECV_FIFO_FULL) )
-+ break;
-+ for( i = 0; i < cnt; i++ )
-+ *buf++ = MMC_RXFIFO;
-+ }
-+
-+ hostdata->iobuf.buf.pos = buf;
-+ hostdata->iobuf.buf.cnt -= i;
-+ if ( hostdata->iobuf.buf.cnt <= 0 ) {
-+ pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_END_BUFFER );
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "buffer transferred\n" );
-+ goto complete;
-+ }
-+ break;
-+#endif /* PIO */
-+ default:
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "unexpected state %d\n",
-+ hostdata->state );
-+ goto complete;
-+ }
-+ return;
-+complete:
-+ MMC_I_MASK = MMC_I_MASK_ALL;
-+ complete( &hostdata->completion );
-+ return;
-+}
-+
-+#ifndef PIO
-+static void pxa_mmc_dma_irq( int irq, void *dev_id, struct pt_regs *regs )
-+{
-+ mmc_controller_t ctrlr = (mmc_controller_t)dev_id;
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+ u32 dcsr;
-+ u32 ddadr;
-+ int chan = hostdata->iobuf.buf.chan;
-+
-+ ddadr = DDADR( chan );
-+ dcsr = DCSR( chan );
-+ DCSR( chan ) = dcsr & ~DCSR_STOPIRQEN;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3,
-+ "MMC DMA interrupt: chan=%d ddadr=0x%08x "
-+ "dcmd=0x%08x dcsr=0x%08x\n",
-+ chan, ddadr, DCMD( chan ), dcsr );
-+/* bus error */
-+ if ( dcsr & DCSR_BUSERR ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "bus error on DMA channel %d\n",
-+ chan );
-+ pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_ERROR );
-+ goto complete;
-+ }
-+/* data transfer completed */
-+ if ( dcsr & DCSR_ENDINTR ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "buffer transferred\n" );
-+ pxa_mmc_set_state( ctrlr, PXA_MMC_FSM_END_BUFFER );
-+ goto complete;
-+ }
-+ return;
-+complete:
-+ complete( &hostdata->completion );
-+ return;
-+}
-+#endif
-+
-+
-+static int pxa_mmc_init( mmc_controller_t ctrlr )
-+{
-+ int ret = -ENODEV;
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+#ifndef PIO
-+ register int i;
-+ register pxa_dma_desc *desc;
-+#endif
-+
-+/* hardware initialization */
-+/* I. prepare to transfer data */
-+/* 1. allocate buffer */
-+#ifndef PIO
-+ hostdata->iobuf.buf.read_desc = consistent_alloc( GFP_KERNEL,
-+ (PXA_MMC_IODATA_SIZE>>5)
-+ * sizeof( pxa_dma_desc ),
-+ &hostdata->iobuf.buf.read_desc_phys_addr, 0 );
-+ if ( !hostdata->iobuf.buf.read_desc ) {
-+ ret = -ENOMEM;
-+ goto error;
-+ }
-+ hostdata->iobuf.buf.write_desc = consistent_alloc( GFP_KERNEL,
-+ (PXA_MMC_IODATA_SIZE>>5)
-+ * sizeof( pxa_dma_desc ),
-+ &hostdata->iobuf.buf.write_desc_phys_addr, 0 );
-+ if ( !hostdata->iobuf.buf.write_desc ) {
-+ ret = -ENOMEM;
-+ goto error;
-+ }
-+ hostdata->iobuf.iodata = consistent_alloc( GFP_ATOMIC,
-+ PXA_MMC_IODATA_SIZE,
-+ &hostdata->iobuf.buf.phys_addr, 0 );
-+#else
-+ hostdata->iobuf.iodata = kmalloc( PXA_MMC_IODATA_SIZE, GFP_ATOMIC );
-+#endif
-+ if ( !hostdata->iobuf.iodata ) {
-+ ret = -ENOMEM;
-+ goto error;
-+ }
-+/* 2. initialize iobuf */
-+ hostdata->iobuf.blksz = PXA_MMC_BLKSZ_MAX;
-+ hostdata->iobuf.bufsz = PXA_MMC_IODATA_SIZE;
-+ hostdata->iobuf.nob = PXA_MMC_BLOCKS_PER_BUFFER;
-+#ifndef PIO
-+ /* request DMA channel */
-+ if ( (hostdata->iobuf.buf.chan = pxa_request_dma( "MMC", DMA_PRIO_LOW,
-+ pxa_mmc_dma_irq, ctrlr )) < 0 ) {
-+ MMC_ERROR( "failed to request DMA channel\n" );
-+ goto error;
-+ }
-+
-+ DRCMRRXMMC = hostdata->iobuf.buf.chan | DRCMR_MAPVLD;
-+ DRCMRTXMMC = hostdata->iobuf.buf.chan | DRCMR_MAPVLD;
-+
-+ for ( i = 0; i < ((PXA_MMC_IODATA_SIZE>>5) - 1); i++ ) {
-+ desc = &hostdata->iobuf.buf.read_desc[i];
-+ desc->ddadr = hostdata->iobuf.buf.read_desc_phys_addr
-+ + ((i + 1) * sizeof( pxa_dma_desc ));
-+ desc->dsadr = MMC_RXFIFO_PHYS_ADDR;
-+ desc->dtadr = hostdata->iobuf.buf.phys_addr + (i<<5);
-+ desc->dcmd = DCMD_FLOWSRC|DCMD_INCTRGADDR
-+ |DCMD_WIDTH1|DCMD_BURST32|(1<<5);
-+
-+ desc = &hostdata->iobuf.buf.write_desc[i];
-+ desc->ddadr = hostdata->iobuf.buf.write_desc_phys_addr
-+ + ((i + 1) * sizeof( pxa_dma_desc ));
-+ desc->dsadr = hostdata->iobuf.buf.phys_addr + (i<<5);
-+ desc->dtadr = MMC_TXFIFO_PHYS_ADDR;
-+ desc->dcmd = DCMD_FLOWTRG|DCMD_INCSRCADDR
-+ |DCMD_WIDTH1|DCMD_BURST32|(1<<5);
-+ }
-+ desc = &hostdata->iobuf.buf.read_desc[i];
-+ desc->ddadr = (hostdata->iobuf.buf.read_desc_phys_addr +
-+ (i + 1) * sizeof( pxa_dma_desc))|DDADR_STOP;
-+ desc->dsadr = MMC_RXFIFO_PHYS_ADDR;
-+ desc->dtadr = hostdata->iobuf.buf.phys_addr + (i<<5);
-+ desc->dcmd = DCMD_FLOWSRC|DCMD_INCTRGADDR
-+ |DCMD_WIDTH1|DCMD_BURST32|(1<<5);
-+
-+ desc = &hostdata->iobuf.buf.write_desc[i];
-+ desc->ddadr = (hostdata->iobuf.buf.write_desc_phys_addr +
-+ (i + 1) * sizeof( pxa_dma_desc))|DDADR_STOP;
-+ desc->dsadr = hostdata->iobuf.buf.phys_addr + (i<<5);
-+ desc->dtadr = MMC_TXFIFO_PHYS_ADDR;
-+ desc->dcmd = DCMD_FLOWTRG|DCMD_INCSRCADDR
-+ |DCMD_WIDTH1|DCMD_BURST32|(1<<5);
-+#endif
-+/* II. MMC */
-+/* 1) request irq */
-+ if ( request_irq( IRQ_MMC, pxa_mmc_irq, 0, "MMC", ctrlr ) ) {
-+ MMC_ERROR( "failed to request IRQ_MMC\n" );
-+ goto error;
-+ }
-+
-+/* 2) initialize h/w and ctrlr */
-+ set_GPIO_mode( GPIO6_MMCCLK_MD );
-+ CKEN |= CKEN12_MMC; /* enable MMC unit clock */
-+
-+ ret = 0;
-+ goto out;
-+error:
-+#ifndef PIO
-+/* free DMA resources */
-+ if ( hostdata->iobuf.buf.chan >= 0 ) {
-+ DRCMRRXMMC = 0;
-+ DRCMRTXMMC = 0;
-+ pxa_free_dma( hostdata->iobuf.buf.chan );
-+ }
-+ if ( hostdata->iobuf.iodata )
-+ consistent_free( hostdata->iobuf.iodata,
-+ PXA_MMC_IODATA_SIZE,
-+ hostdata->iobuf.buf.phys_addr );
-+ if ( hostdata->iobuf.buf.read_desc )
-+ consistent_free( hostdata->iobuf.buf.read_desc,
-+ (PXA_MMC_IODATA_SIZE>>5)
-+ * sizeof( pxa_dma_desc ),
-+ hostdata->iobuf.buf.read_desc_phys_addr );
-+ if ( hostdata->iobuf.buf.write_desc )
-+ consistent_free( hostdata->iobuf.buf.write_desc,
-+ (PXA_MMC_IODATA_SIZE>>5)
-+ * sizeof( pxa_dma_desc ),
-+ hostdata->iobuf.buf.write_desc_phys_addr );
-+#else
-+ kfree( hostdata->iobuf.iodata );
-+#endif
-+out:
-+ return ret;
-+}
-+
-+static void pxa_mmc_remove( mmc_controller_t ctrlr )
-+{
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+
-+/* 1) free buffer(s) */
-+#ifndef PIO
-+ consistent_free( hostdata->iobuf.iodata, PXA_MMC_IODATA_SIZE,
-+ hostdata->iobuf.buf.phys_addr );
-+ consistent_free( hostdata->iobuf.buf.read_desc,
-+ (PXA_MMC_IODATA_SIZE>>5)
-+ * sizeof( pxa_dma_desc ),
-+ hostdata->iobuf.buf.read_desc_phys_addr );
-+ consistent_free( hostdata->iobuf.buf.write_desc,
-+ (PXA_MMC_IODATA_SIZE>>5)
-+ * sizeof( pxa_dma_desc ),
-+ hostdata->iobuf.buf.write_desc_phys_addr );
-+/* 2) release DMA channel */
-+ if ( hostdata->iobuf.buf.chan >= 0 ) {
-+ DRCMRRXMMC = 0;
-+ DRCMRTXMMC = 0;
-+ pxa_free_dma( hostdata->iobuf.buf.chan );
-+ }
-+#else
-+ kfree( hostdata->iobuf.iodata );
-+#endif
-+/* II. MMC */
-+/* 1) release irq */
-+ free_irq( IRQ_MMC, ctrlr );
-+ CKEN &= ~CKEN12_MMC; /* disable MMC unit clock */
-+}
-+
-+static int pxa_mmc_probe( mmc_controller_t ctrlr )
-+{
-+ return 1;
-+}
-+
-+#ifdef CONFIG_PM
-+static int pxa_mmc_suspend( mmc_controller_t ctrlr )
-+{
-+ int ret = -EBUSY;
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL2, "state=%s\n",
-+ PXA_MMC_STATE_LABEL( hostdata->state ) );
-+
-+ if ( hostdata->state == PXA_MMC_FSM_IDLE ) {
-+ /* save registers */
-+ SAVED_MMC_CLKRT = MMC_CLKRT;
-+ SAVED_MMC_RESTO = MMC_RESTO;
-+ SAVED_MMC_SPI = MMC_SPI;
-+ SAVED_DRCMRRXMMC = DRCMRRXMMC;
-+ SAVED_DRCMRTXMMC = DRCMRTXMMC;
-+
-+#if 0 /* FIXME */
-+ /* send CMD0 */
-+ if ( (ret = pxa_mmc_stop_bus_clock( ctrlr )) )
-+ goto error;
-+
-+ MMC_CMD = CMD(0); /* CMD0 with zero argument */
-+ MMC_ARGH = 0UL;
-+ MMC_ARGL = 0UL;
-+ MMC_CMDAT = 0UL;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL3, "CMD0(0x%04x%04x)\n", 0UL, 0UL );
-+ if ( (ret = pxa_mmc_complete_cmd( ctrlr, MMC_NORESPONSE,
-+ FALSE )) )
-+ {
-+ ret = -EIO;
-+ goto error;
-+ }
-+#endif
-+
-+ set_GPIO_mode( GPIO6_MMCCLK );
-+ CKEN &= ~CKEN12_MMC; /* disable MMC unit clock */
-+
-+ hostdata->suspended = TRUE;
-+ ret = 0;
-+ }
-+error:
-+ return ret;
-+}
-+
-+static void pxa_mmc_resume( mmc_controller_t ctrlr )
-+{
-+ pxa_mmc_hostdata_t hostdata = (pxa_mmc_hostdata_t)ctrlr->host_data;
-+
-+ if ( hostdata->suspended == TRUE ) {
-+ set_GPIO_mode( GPIO6_MMCCLK_MD );
-+ CKEN |= CKEN12_MMC; /* enable MMC unit clock */
-+
-+ /* restore registers */
-+ MMC_CLKRT = SAVED_MMC_CLKRT;
-+ MMC_RESTO = SAVED_MMC_RESTO;
-+ MMC_SPI = SAVED_MMC_SPI;
-+ DRCMRRXMMC = SAVED_DRCMRRXMMC;
-+ DRCMRTXMMC = SAVED_DRCMRTXMMC;
-+
-+ hostdata->suspended = FALSE;
-+
-+ mmc_update_card_stack( ctrlr->slot ); /* FIXME */
-+ }
-+
-+ return;
-+}
-+#endif
-+
-+static mmc_controller_tmpl_rec_t pxa_mmc_controller_tmpl_rec = {
-+ owner: THIS_MODULE,
-+ name: "PXA250",
-+ block_size_max: PXA_MMC_BLKSZ_MAX,
-+ nob_max: PXA_MMC_NOB_MAX,
-+ probe: pxa_mmc_probe,
-+ init: pxa_mmc_init,
-+ remove: __devexit_p( pxa_mmc_remove ),
-+#ifdef CONFIG_PM
-+ suspend: pxa_mmc_suspend,
-+ resume: pxa_mmc_resume,
-+#endif /* CONFIG_PM */
-+ update_acq: pxa_mmc_update_acq,
-+// single_card_acq: pxa_mmc_single_card_acq,
-+ init_card_stack: pxa_mmc_init_card_stack,
-+ check_card_stack: pxa_mmc_check_card_stack,
-+ setup_card: pxa_mmc_setup_card,
-+ stream_read: pxa_mmc_stream_read,
-+ read_block: pxa_mmc_read_block,
-+ read_mblock: pxa_mmc_read_mblock,
-+ stream_write: pxa_mmc_stream_write,
-+ write_block: pxa_mmc_write_block,
-+ write_mblock: pxa_mmc_write_mblock
-+ /* TODO
-+ sg_io: pxa_mmc_sg_io
-+ */
-+ /* TODO:
-+ * erase,
-+ * write protection,
-+ * lock/password management methods
-+ */
-+};
-+
-+static int __devinit mmc_pxa_module_init( void )
-+{
-+ int ret = -ENODEV;
-+#ifdef CONFIG_ARCH_RAMSES
-+ RAMSES_MMC_ON();
-+ udelay(1000);
-+#endif
-+
-+ host = mmc_register( MMC_REG_TYPE_HOST, &pxa_mmc_controller_tmpl_rec,
-+ sizeof( pxa_mmc_hostdata_rec_t ) );
-+ if ( !host ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0,
-+ "failed to register with MMC core\n" );
-+ goto error;
-+ }
-+
-+ ret = 0;
-+error:
-+ return ret;
-+}
-+
-+static void __devexit mmc_pxa_module_cleanup( void )
-+{
-+ mmc_unregister( MMC_REG_TYPE_HOST, host );
-+#ifdef CONFIG_ARCH_RAMSES
-+ RAMSES_MMC_OFF();
-+#endif
-+}
-+
-+EXPORT_NO_SYMBOLS;
-+
-+MODULE_LICENSE( "GPL" );
-+
-+module_init( mmc_pxa_module_init );
-+module_exit( mmc_pxa_module_cleanup );
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/mmc/mmc_pxa.h 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,278 @@
-+/*
-+ * linux/drivers/mmc/mmc_pxa.h
-+ *
-+ * Author: Vladimir Shebordaev, Igor Oblakov
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#ifndef __MMC_PXA_P_H__
-+#define __MMC_PXA_P_H__
-+
-+#include <linux/completion.h>
-+
-+#define PIO
-+
-+/* PXA-250 MMC controller registers */
-+
-+/* MMC_STRPCL */
-+#define MMC_STRPCL_STOP_CLK (0x0001UL)
-+#define MMC_STRPCL_START_CLK (0x0002UL)
-+
-+/* MMC_STAT */
-+#define MMC_STAT_END_CMD_RES (0x0001UL << 13)
-+#define MMC_STAT_PRG_DONE (0x0001UL << 12)
-+#define MMC_STAT_DATA_TRAN_DONE (0x0001UL << 11)
-+#define MMC_STAT_CLK_EN (0x0001UL << 8)
-+#define MMC_STAT_RECV_FIFO_FULL (0x0001UL << 7)
-+#define MMC_STAT_XMIT_FIFO_EMPTY (0x0001UL << 6)
-+#define MMC_STAT_RES_CRC_ERROR (0x0001UL << 5)
-+#define MMC_STAT_SPI_READ_ERROR_TOKEN (0x0001UL << 4)
-+#define MMC_STAT_CRC_READ_ERROR (0x0001UL << 3)
-+#define MMC_STAT_CRC_WRITE_ERROR (0x0001UL << 2)
-+#define MMC_STAT_TIME_OUT_RESPONSE (0x0001UL << 1)
-+#define MMC_STAT_READ_TIME_OUT (0x0001UL)
-+
-+#define MMC_STAT_ERRORS (MMC_STAT_RES_CRC_ERROR|MMC_STAT_SPI_READ_ERROR_TOKEN\
-+ |MMC_STAT_CRC_READ_ERROR|MMC_STAT_TIME_OUT_RESPONSE\
-+ |MMC_STAT_READ_TIME_OUT)
-+
-+/* MMC_CLKRT */
-+#define MMC_CLKRT_20MHZ (0x0000UL)
-+#define MMC_CLKRT_10MHZ (0x0001UL)
-+#define MMC_CLKRT_5MHZ (0x0002UL)
-+#define MMC_CLKRT_2_5MHZ (0x0003UL)
-+#define MMC_CLKRT_1_25MHZ (0x0004UL)
-+#define MMC_CLKRT_0_625MHZ (0x0005UL)
-+#define MMC_CLKRT_0_3125MHZ (0x0006UL)
-+
-+/* MMC_SPI */
-+#define MMC_SPI_DISABLE (0x00UL)
-+#define MMC_SPI_EN (0x01UL)
-+#define MMC_SPI_CS_EN (0x01UL << 2)
-+#define MMC_SPI_CS_ADDRESS (0x01UL << 3)
-+#define MMC_SPI_CRC_ON (0x01UL << 1)
-+
-+/* MMC_CMDAT */
-+#define MMC_CMDAT_MMC_DMA_EN (0x0001UL << 7)
-+#define MMC_CMDAT_INIT (0x0001UL << 6)
-+#define MMC_CMDAT_BUSY (0x0001UL << 5)
-+#define MMC_CMDAT_STREAM (0x0001UL << 4)
-+#define MMC_CMDAT_BLOCK (0x0000UL << 4)
-+#define MMC_CMDAT_WRITE (0x0001UL << 3)
-+#define MMC_CMDAT_READ (0x0000UL << 3)
-+#define MMC_CMDAT_DATA_EN (0x0001UL << 2)
-+#define MMC_CMDAT_R1 (0x0001UL)
-+#define MMC_CMDAT_R2 (0x0002UL)
-+#define MMC_CMDAT_R3 (0x0003UL)
-+
-+/* MMC_RESTO */
-+#define MMC_RES_TO_MAX (0x007fUL) /* [6:0] */
-+
-+/* MMC_RDTO */
-+#define MMC_READ_TO_MAX (0x0ffffUL) /* [15:0] */
-+
-+/* MMC_BLKLEN */
-+#define MMC_BLK_LEN_MAX (0x03ffUL) /* [9:0] */
-+
-+/* MMC_PRTBUF */
-+#define MMC_PRTBUF_BUF_PART_FULL (0x01UL)
-+#define MMC_PRTBUF_BUF_FULL (0x00UL )
-+
-+/* MMC_I_MASK */
-+#define MMC_I_MASK_TXFIFO_WR_REQ (0x01UL << 6)
-+#define MMC_I_MASK_RXFIFO_RD_REQ (0x01UL << 5)
-+#define MMC_I_MASK_CLK_IS_OFF (0x01UL << 4)
-+#define MMC_I_MASK_STOP_CMD (0x01UL << 3)
-+#define MMC_I_MASK_END_CMD_RES (0x01UL << 2)
-+#define MMC_I_MASK_PRG_DONE (0x01UL << 1)
-+#define MMC_I_MASK_DATA_TRAN_DONE (0x01UL)
-+#define MMC_I_MASK_ALL (0x07fUL)
-+
-+
-+/* MMC_I_REG */
-+#define MMC_I_REG_TXFIFO_WR_REQ (0x01UL << 6)
-+#define MMC_I_REG_RXFIFO_RD_REQ (0x01UL << 5)
-+#define MMC_I_REG_CLK_IS_OFF (0x01UL << 4)
-+#define MMC_I_REG_STOP_CMD (0x01UL << 3)
-+#define MMC_I_REG_END_CMD_RES (0x01UL << 2)
-+#define MMC_I_REG_PRG_DONE (0x01UL << 1)
-+#define MMC_I_REG_DATA_TRAN_DONE (0x01UL)
-+#define MMC_I_REG_ALL (0x007fUL)
-+
-+/* MMC_CMD */
-+#define MMC_CMD_INDEX_MAX (0x006fUL) /* [5:0] */
-+#define CMD(x) (x)
-+
-+/* MMC_ARGH */
-+/* MMC_ARGL */
-+/* MMC_RES */
-+/* MMC_RXFIFO */
-+#define MMC_RXFIFO_PHYS_ADDR 0x41100040 //MMC_RXFIFO physical address
-+/* MMC_TXFIFO */
-+#define MMC_TXFIFO_PHYS_ADDR 0x41100044 //MMC_TXFIFO physical address
-+
-+/* implementation specific declarations */
-+#define PXA_MMC_BLKSZ_MAX (1<<9) /* actually 1023 */
-+#define PXA_MMC_NOB_MAX ((1<<16)-2)
-+#define PXA_MMC_BLOCKS_PER_BUFFER (2)
-+
-+#define PXA_MMC_IODATA_SIZE (PXA_MMC_BLOCKS_PER_BUFFER*PXA_MMC_BLKSZ_MAX) /* 1K */
-+
-+typedef enum _pxa_mmc_fsm { /* command processing FSM */
-+ PXA_MMC_FSM_IDLE = 1,
-+ PXA_MMC_FSM_CLK_OFF,
-+ PXA_MMC_FSM_END_CMD,
-+ PXA_MMC_FSM_BUFFER_IN_TRANSIT,
-+ PXA_MMC_FSM_END_BUFFER,
-+ PXA_MMC_FSM_END_IO,
-+ PXA_MMC_FSM_END_PRG,
-+ PXA_MMC_FSM_ERROR
-+} pxa_mmc_state_t;
-+
-+#define PXA_MMC_STATE_LABEL( state ) (\
-+ (state == PXA_MMC_FSM_IDLE) ? "IDLE" :\
-+ (state == PXA_MMC_FSM_CLK_OFF) ? "CLK_OFF" :\
-+ (state == PXA_MMC_FSM_END_CMD) ? "END_CMD" :\
-+ (state == PXA_MMC_FSM_BUFFER_IN_TRANSIT) ? "IN_TRANSIT" :\
-+ (state == PXA_MMC_FSM_END_BUFFER) ? "END_BUFFER" :\
-+ (state == PXA_MMC_FSM_END_IO) ? "END_IO" :\
-+ (state == PXA_MMC_FSM_END_PRG) ? "END_PRG" : "UNKNOWN" )
-+
-+typedef enum _pxa_mmc_result {
-+ PXA_MMC_NORMAL = 0,
-+ PXA_MMC_INVALID_STATE = -1,
-+ PXA_MMC_TIMEOUT = -2,
-+ PXA_MMC_ERROR = -3
-+} pxa_mmc_result_t;
-+
-+typedef u32 pxa_mmc_clkrt_t;
-+
-+typedef char *pxa_mmc_iodata_t;
-+#ifdef PIO
-+typedef struct _pxa_mmc_piobuf_rec {
-+ char *pos; /* current buffer position */
-+ int cnt; /* byte counter */
-+} pxa_mmc_piobuf_rec_t, *pxa_mmc_piobuf_t;
-+#else /* i.e. DMA */
-+typedef struct _pxa_mmc_dmabuf_rec { /* TODO: buffer ring, DMA irq completion */
-+ int chan; /* dma channel no */
-+ dma_addr_t phys_addr; /* iodata physical address */
-+ pxa_dma_desc *read_desc; /* input descriptor array virtual address */
-+ pxa_dma_desc *write_desc; /* output descriptor array virtual address */
-+ dma_addr_t read_desc_phys_addr; /* descriptor array physical address */
-+ dma_addr_t write_desc_phys_addr; /* descriptor array physical address */
-+ pxa_dma_desc *last_read_desc; /* last input descriptor
-+ * used by the previous transfer
-+ */
-+ pxa_dma_desc *last_write_desc; /* last output descriptor
-+ * used by the previous transfer
-+ */
-+} pxa_mmc_dmabuf_rec_t, *pxa_mmc_dmabuf_t;
-+#endif
-+
-+typedef struct _pxa_mmc_iobuf_rec {
-+ ssize_t blksz; /* current block size in bytes */
-+ ssize_t bufsz; /* buffer size for each transfer */
-+ ssize_t nob; /* number of blocks pers buffer */
-+#ifndef PIO
-+ pxa_mmc_dmabuf_rec_t buf; /* i.e. DMA buffer ring on the iodata */
-+#else /* i.e. DMA */
-+ pxa_mmc_piobuf_rec_t buf; /* PIO buffer accounting */
-+#endif
-+ pxa_mmc_iodata_t iodata; /* I/O data buffer */
-+} pxa_mmc_iobuf_rec_t, *pxa_mmc_iobuf_t;
-+
-+typedef struct _pxa_mmc_hostdata_rec {
-+ pxa_mmc_state_t state; /* FSM */
-+#ifdef CONFIG_PM
-+ int suspended;
-+#endif
-+ pxa_mmc_iobuf_rec_t iobuf; /* data transfer state */
-+
-+ int busy; /* atomic busy flag */
-+ struct completion completion; /* completion */
-+#if CONFIG_MMC_DEBUG_IRQ
-+ int irqcnt;
-+ int timeo;
-+#endif
-+
-+/* cached controller state */
-+ u32 mmc_i_reg; /* interrupt last requested */
-+ u32 mmc_i_mask; /* mask to be set by intr handler */
-+ u32 mmc_stat; /* status register at the last intr */
-+ u32 mmc_cmdat; /* MMC_CMDAT at the last inr */
-+ u8 mmc_res[16]; /* response to the last command in host order */
-+ u32 saved_mmc_clkrt;
-+ u32 saved_mmc_resto;
-+ u32 saved_mmc_spi;
-+ u32 saved_drcmrrxmmc;
-+ u32 saved_drcmrtxmmc;
-+
-+/* controller options */
-+ pxa_mmc_clkrt_t clkrt; /* current bus clock rate */
-+} pxa_mmc_hostdata_rec_t, *pxa_mmc_hostdata_t;
-+
-+#define PXA_MMC_STATUS( ctrlr ) (((pxa_mmc_hostdata_t)ctrlr->host_data)->mmc_stat)
-+#define PXA_MMC_RESPONSE( ctrlr, idx ) ((((pxa_mmc_hostdata_t)ctrlr->host_data)->mmc_res)[idx])
-+#define PXA_MMC_CLKRT( ctrlr ) (((pxa_mmc_hostdata_t)ctrlr->host_data)->clkrt)
-+
-+#define SAVED_MMC_CLKRT (hostdata->saved_mmc_clkrt)
-+#define SAVED_MMC_RESTO (hostdata->saved_mmc_resto)
-+#define SAVED_MMC_SPI (hostdata->saved_mmc_spi)
-+#define SAVED_DRCMRRXMMC (hostdata->saved_drcmrrxmmc )
-+#define SAVED_DRCMRTXMMC (hostdata->saved_drcmrtxmmc )
-+
-+static inline int pxa_mmc_clkrt( int speed )
-+{
-+ return MMC_CLKRT_20MHZ; /* TODO */
-+}
-+
-+/* PXA MMC controller specific card data */
-+typedef struct _pxa_mmc_card_data_rec {
-+ pxa_mmc_clkrt_t clkrt; /* clock rate to be set for the card */
-+} pxa_mmc_card_data_rec_t, *pxa_mmc_card_data_t;
-+
-+#ifdef CONFIG_MMC_DEBUG
-+#undef MMC_DUMP_R1
-+#undef MMC_DUMP_R2
-+#undef MMC_DUMP_R3
-+#define MMC_DUMP_R2( ctrlr ) MMC_DEBUG( MMC_DEBUG_LEVEL3, \
-+"R2 response: %02x %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", \
-+PXA_MMC_RESPONSE( ctrlr, 15 ), \
-+PXA_MMC_RESPONSE( ctrlr, 14 ), \
-+PXA_MMC_RESPONSE( ctrlr, 13 ), \
-+PXA_MMC_RESPONSE( ctrlr, 12 ), \
-+PXA_MMC_RESPONSE( ctrlr, 11 ), \
-+PXA_MMC_RESPONSE( ctrlr, 10 ), \
-+PXA_MMC_RESPONSE( ctrlr, 9 ), \
-+PXA_MMC_RESPONSE( ctrlr, 8 ), \
-+PXA_MMC_RESPONSE( ctrlr, 7 ), \
-+PXA_MMC_RESPONSE( ctrlr, 6 ), \
-+PXA_MMC_RESPONSE( ctrlr, 5 ), \
-+PXA_MMC_RESPONSE( ctrlr, 4 ), \
-+PXA_MMC_RESPONSE( ctrlr, 3 ), \
-+PXA_MMC_RESPONSE( ctrlr, 2 ), \
-+PXA_MMC_RESPONSE( ctrlr, 1 ), \
-+PXA_MMC_RESPONSE( ctrlr, 0 ) );
-+#define MMC_DUMP_R1( ctrlr ) MMC_DEBUG( MMC_DEBUG_LEVEL3, \
-+"R1(b) response: %02x %02x%02x%02x%02x\n", \
-+PXA_MMC_RESPONSE( ctrlr, 5 ), \
-+PXA_MMC_RESPONSE( ctrlr, 4 ), \
-+PXA_MMC_RESPONSE( ctrlr, 3 ), \
-+PXA_MMC_RESPONSE( ctrlr, 2 ), \
-+PXA_MMC_RESPONSE( ctrlr, 1 ) );
-+#define MMC_DUMP_R3( ctrlr ) MMC_DEBUG( MMC_DEBUG_LEVEL3, \
-+"R3 response: %02x %02x%02x%02x%02x\n", \
-+PXA_MMC_RESPONSE( ctrlr, 5 ), \
-+PXA_MMC_RESPONSE( ctrlr, 4 ), \
-+PXA_MMC_RESPONSE( ctrlr, 3 ), \
-+PXA_MMC_RESPONSE( ctrlr, 2 ), \
-+PXA_MMC_RESPONSE( ctrlr, 1 ) );
-+
-+#endif
-+#endif /* __MMC_PXA_P_H__ */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/mmc/mmc_test.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,538 @@
-+/*
-+ * linux/drivers/mmc/mmc_test.c
-+ *
-+ * Author: Vladimir Shebordaev
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/version.h>
-+#include <linux/config.h>
-+#include <linux/types.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+
-+#include <linux/fs.h>
-+#ifdef CONFIG_DEVFS_FS
-+#include <linux/devfs_fs_kernel.h>
-+#endif
-+
-+#include <asm/uaccess.h>
-+
-+#include <mmc/types.h>
-+#include <mmc/mmc.h>
-+#include <mmc/ioctl.h>
-+
-+#include "types.h"
-+#include "mmc.h"
-+
-+typedef struct _mmc_test_device_rec mmc_test_device_rec_t;
-+typedef struct _mmc_test_device_rec *mmc_test_device_t;
-+
-+struct _mmc_test_device_rec {
-+ mmc_card_t card;
-+ mmc_transfer_mode_t transfer_mode;
-+ int usage;
-+#ifdef CONFIG_DEVFS_FS
-+ devfs_handle_t devfs_handle;
-+#endif
-+};
-+
-+/* MMC device table */
-+static mmc_test_device_rec_t mmc_test_device[MMC_CONTROLLERS_MAX][MMC_CARDS_MAX];
-+static DECLARE_MUTEX(mmc_test_device_mutex);
-+
-+static inline mmc_test_device_t __mmc_test_get_device( kdev_t rdev )
-+{
-+ mmc_test_device_t ret = NULL;
-+ u8 minor = MINOR( rdev );
-+ int host_no, card_no;
-+
-+ host_no = minor >> MMC_MINOR_HOST_SHIFT;
-+ if ( host_no >= MMC_CONTROLLERS_MAX )
-+ goto error;
-+
-+ card_no = minor & MMC_MINOR_CARD_MASK;
-+ if ( card_no >= MMC_CARDS_MAX )
-+ goto error;
-+
-+ ret = &mmc_test_device[host_no][card_no];
-+ if ( !ret->card ) {
-+ ret->card = mmc_get_card( host_no, card_no );
-+ if ( !ret->card ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "failed to get card: host=%d, card=%d\n", host_no, card_no );
-+ ret = NULL;
-+ goto error;
-+ }
-+
-+ }
-+ ++ret->usage;
-+
-+error:
-+ return ret;
-+}
-+
-+static inline void __mmc_test_put_device( mmc_test_device_t dev )
-+{
-+ mmc_put_card( dev->card );
-+ --dev->usage;
-+}
-+
-+static inline mmc_test_device_t mmc_test_get_device( kdev_t kdev )
-+{
-+ mmc_test_device_t ret = NULL;
-+
-+ down( &mmc_test_device_mutex );
-+ ret = __mmc_test_get_device( kdev );
-+ up( &mmc_test_device_mutex );
-+
-+ return ret;
-+}
-+
-+static inline void mmc_test_put_device( mmc_test_device_t dev )
-+{
-+ if ( dev ) {
-+ down( &mmc_test_device_mutex );
-+ __mmc_test_put_device( dev );
-+ if ( !dev->usage ) {
-+ if ( dev->card ) {
-+ if ( dev->card->usage ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0,
-+ "broken card reference\n" );
-+ }
-+ memset( dev, 0, sizeof( mmc_test_device_rec_t ) );
-+ }
-+ }
-+ up( &mmc_test_device_mutex );
-+ }
-+}
-+
-+static inline int mmc_test_set_transfer_mode( mmc_test_device_t dev, mmc_transfer_mode_t mode )
-+{
-+ int ret = -1;
-+
-+ if ( dev ) {
-+ down( &mmc_test_device_mutex );
-+ dev->transfer_mode = mode;
-+ ret = 0;
-+ up( &mmc_test_device_mutex );
-+ }
-+ return ret;
-+}
-+
-+static inline mmc_transfer_mode_t mmc_test_get_transfer_mode( mmc_test_device_t dev )
-+{
-+ mmc_transfer_mode_t ret = MMC_TRANSFER_MODE_UNDEFINED;
-+
-+ if ( dev ) {
-+ down( &mmc_test_device_mutex );
-+ ret = dev->transfer_mode;
-+ up( &mmc_test_device_mutex );
-+ }
-+ return ret;
-+}
-+
-+static int mmc_test_open( struct inode *inode, struct file *file )
-+{
-+ int ret = -ENODEV;
-+ mmc_test_device_t dev = NULL;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ __ENTER0( );
-+ dev = mmc_test_get_device( inode->i_rdev );
-+ if ( !dev || !dev->card ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "failed to acquire device\n" );
-+ goto error;
-+ }
-+
-+ if ( dev->card->usage > 1 ) {
-+ ret = -EBUSY;
-+ goto error;
-+ }
-+
-+ dev->transfer_mode = MMC_TEST_TRANSFER_MODE_DEFAULT; /* FIXME: should check card CCC */
-+ file->private_data = dev;
-+
-+ __LEAVE0( );
-+ return 0;
-+error:
-+ MOD_DEC_USE_COUNT;
-+ mmc_test_put_device( dev );
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+
-+static int mmc_test_release( struct inode *inode, struct file *file )
-+{
-+ int ret = -ENODEV;
-+ mmc_test_device_t dev = (mmc_test_device_t)file->private_data;
-+
-+ if ( !dev ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "file->private_data == NULL\n" );
-+ goto error;
-+ }
-+
-+ __ENTER( "host=%d, card=%d", dev->card->ctrlr->slot, dev->card->slot );
-+
-+ file->private_data = NULL;
-+
-+ mmc_test_put_device( dev );
-+ MOD_DEC_USE_COUNT;
-+
-+ ret = 0;
-+error:
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+
-+static ssize_t mmc_test_read( struct file *file, char *buf, size_t size, loff_t *ppos )
-+{
-+ ssize_t ret = -ENODEV;
-+ ssize_t retsize = 0;
-+ mmc_test_device_t dev = (mmc_test_device_t)file->private_data;
-+
-+ __ENTER( "host=%d, card=%d, size=%d", dev->card->ctrlr->slot, dev->card->slot, size );
-+
-+ if ( !dev ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "file->private_data == NULL\n" );
-+ goto error;
-+ }
-+
-+ switch ( dev->transfer_mode ) {
-+ char *mbuf;
-+
-+ case MMC_TRANSFER_MODE_BLOCK_SINGLE:
-+ mbuf = kmalloc( 512, GFP_ATOMIC ); /* FIXME: actual read_bl_len or ctrlr->block_size_max whichever is less ), GFP_KERNEL */
-+ if ( !mbuf ) {
-+ ret = -ENOMEM;
-+ goto error;
-+ }
-+
-+ while( size > 0 ) {
-+ int lsize = (size > 512) ? 512 : size;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL4,
-+ "before mmc_read mbuf=0x%x "
-+ "lsize=%d ppos=0x%x *ppos=%d\n",
-+ mbuf, lsize, ppos, *ppos );
-+ ret = mmc_read( dev->card,
-+ MMC_TRANSFER_MODE_BLOCK_SINGLE,
-+ mbuf, lsize, ppos );
-+ if ( ret <= 0 )
-+ break;
-+
-+ /* Copy to user */
-+ if ( copy_to_user( buf, mbuf, ret ) ) {
-+ ret = -EFAULT;
-+ break;
-+ }
-+ retsize += ret;
-+ buf += ret;
-+ size -= ret;
-+ }
-+
-+ if ( retsize > 0 )
-+ ret = retsize;
-+ kfree(mbuf);
-+ break;
-+
-+ case MMC_TRANSFER_MODE_BLOCK_MULTIPLE:
-+ mbuf = kmalloc( 1024, GFP_ATOMIC ); /* FIXME */
-+ if ( !mbuf ) {
-+ ret = -ENOMEM;
-+ goto error;
-+ }
-+
-+ while( size > 0 ) {
-+ int lsize = (size > 1024) ? 1024 : size;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL4,
-+ "before mmc_read mbuf=0x%x "
-+ "lsize=%d ppos=0x%x *ppos=%d\n",
-+ mbuf, lsize, ppos, *ppos );
-+ ret = mmc_read( dev->card,
-+ MMC_TRANSFER_MODE_BLOCK_MULTIPLE,
-+ mbuf, lsize, ppos );
-+ if ( ret <= 0 )
-+ break;
-+
-+ /* Copy to user */
-+ if ( copy_to_user( buf, mbuf, ret ) ) {
-+ ret = -EFAULT;
-+ break;
-+ }
-+ retsize += ret;
-+ buf += ret;
-+ size -= ret;
-+ }
-+
-+ if ( retsize > 0 )
-+ ret = retsize;
-+ kfree(mbuf);
-+ break;
-+
-+ case MMC_TRANSFER_MODE_STREAM:
-+ ret = mmc_read( dev->card, dev->transfer_mode,
-+ buf, size, ppos );
-+ break;
-+
-+ default:
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "invalid transfer mode\n" );
-+ }
-+error:
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+
-+static ssize_t mmc_test_write( struct file *file, const char *buf, size_t size, loff_t *ppos )
-+{
-+ ssize_t ret = -ENODEV;
-+ mmc_test_device_t dev = (mmc_test_device_t)file->private_data;
-+ int retsize=0;
-+
-+ __ENTER( "host=%d, card=%d, size=%d", dev->card->ctrlr->slot, dev->card->slot, size );
-+
-+ if ( !dev ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "file->private_data == NULL\n" );
-+ goto error;
-+ }
-+
-+ switch ( dev->transfer_mode ) {
-+ char *mbuf;
-+
-+ case MMC_TRANSFER_MODE_BLOCK_SINGLE:
-+ mbuf = kmalloc( 512, GFP_ATOMIC ); /* FIXME: actual write_bl_len or ctrlr->block_size_max whichever is less, GFP_KERNEL */
-+ if ( !mbuf ) {
-+ ret = -ENOMEM;
-+ goto error;
-+ }
-+
-+ while ( size > 0 ) {
-+ int lsize = ( size > 512 ) ? 512 : size;
-+
-+ /* Copy from user */
-+ if ( copy_from_user( mbuf, buf, lsize ) ) {
-+ ret = -EFAULT;
-+ break;
-+ }
-+
-+ ret = mmc_write( dev->card,
-+ MMC_TRANSFER_MODE_BLOCK_SINGLE,
-+ mbuf, lsize, ppos );
-+ if( ret <= 0 )
-+ break;
-+
-+ retsize += ret;
-+ buf += ret;
-+ size -= ret;
-+ }
-+
-+ if ( retsize > 0 )
-+ ret = retsize;
-+
-+ kfree( mbuf );
-+ break;
-+
-+ case MMC_TRANSFER_MODE_BLOCK_MULTIPLE:
-+ mbuf = kmalloc( 1024, GFP_ATOMIC ); /* FIXME */
-+ if ( !mbuf ) {
-+ ret = -ENOMEM;
-+ goto error;
-+ }
-+
-+ while( size > 0 ) {
-+ int lsize = (size > 1024) ? 1024 : size;
-+
-+ MMC_DEBUG( MMC_DEBUG_LEVEL4,
-+ "before mmc_read mbuf=0x%x "
-+ "lsize=%d ppos=0x%x *ppos=%d\n",
-+ mbuf, lsize, ppos, *ppos );
-+ ret = mmc_write( dev->card,
-+ MMC_TRANSFER_MODE_BLOCK_MULTIPLE,
-+ mbuf, lsize, ppos );
-+ if ( ret <= 0 )
-+ break;
-+
-+ /* Copy to user */
-+ if ( copy_to_user( (char *)buf, mbuf, ret ) ) {
-+ ret = -EFAULT;
-+ break;
-+ }
-+ retsize += ret;
-+ buf += ret;
-+ size -= ret;
-+ }
-+
-+ if ( retsize > 0 )
-+ ret = retsize;
-+ kfree(mbuf);
-+ break;
-+ case MMC_TRANSFER_MODE_STREAM:
-+ ret = mmc_write( dev->card, dev->transfer_mode,
-+ buf, size, ppos );
-+ break;
-+
-+ default:
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "invalid transfer mode\n" );
-+ }
-+error:
-+ __LEAVE( "ret=%d", ret );
-+ return ret;
-+}
-+
-+static loff_t mmc_test_llseek( struct file *file, loff_t offset, int origin )
-+{
-+ loff_t ret = -ESPIPE;
-+ mmc_test_device_t dev = (mmc_test_device_t)file->private_data;
-+ mmc_card_t card;
-+
-+ if ( !dev ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "file->private_data == NULL\n" );
-+ ret = -ENODEV;
-+ goto error;
-+ }
-+
-+ __ENTER( "host=%d, card=%d, off=%ld, orig=%d", dev->card->ctrlr->slot, dev->card->slot, (long)offset, origin );
-+
-+ card = dev->card;
-+
-+ switch ( origin ) {
-+ case SEEK_CUR:
-+ file->f_pos += offset;
-+ break;
-+
-+ case SEEK_END:
-+ file->f_pos = card->info.capacity + offset;
-+ break;
-+
-+ case SEEK_SET:
-+ file->f_pos = offset;
-+ break;
-+
-+ default:
-+ ret = -EINVAL;
-+ goto error;
-+ }
-+
-+ ret = file->f_pos;
-+error:
-+ __LEAVE( "ret=%ld", (long)ret );
-+ return ret;
-+}
-+
-+static int mmc_test_ioctl( struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg )
-+{
-+ int ret = -ENODEV;
-+ mmc_test_device_t dev = (mmc_test_device_t)file->private_data;
-+
-+ if ( !dev ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "file->private_data == NULL\n" );
-+ goto error;
-+ }
-+
-+ switch ( cmd ) {
-+ case IOCMMCSTRNSMODE:
-+ if ( get_user( ret, (int *)arg ) ) {
-+ ret = -EFAULT;
-+ goto error;
-+ }
-+ ret = mmc_test_set_transfer_mode( dev, ret );
-+ break;
-+
-+ case IOCMMCGTRNSMODE:
-+ ret = mmc_test_get_transfer_mode( dev );
-+ if ( put_user( ret, (int *)arg ) )
-+ ret = -EFAULT;
-+ break;
-+
-+ default:
-+ ret = mmc_ioctl( dev->card, cmd, arg );
-+ }
-+
-+error:
-+ return ret;
-+}
-+
-+struct file_operations mmc_test_fops = {
-+ owner: THIS_MODULE,
-+ open: mmc_test_open,
-+ release: mmc_test_release,
-+ read: mmc_test_read,
-+ write: mmc_test_write,
-+ ioctl: mmc_test_ioctl,
-+ llseek: mmc_test_llseek
-+};
-+
-+#ifdef CONFIG_DEVFS_FS
-+static int mmc_test_add_card( mmc_card_t card ) /* TODO */
-+{
-+ int ret = -1;
-+ __ENTER( "host=%d, card=%d", card->ctrlr->slot, card->slot );
-+/* TODO: make kdev; register with devfs */
-+ __LEAVE0( );
-+ return ret;
-+}
-+
-+static int mmc_test_remove_card( mmc_card_t card ) /* TODO */
-+{
-+ int ret = -1;
-+ __ENTER( "host=%d, card=%d", card->ctrlr->slot, card->slot );
-+/* TODO: make kdev; unregister with devfs */
-+ __LEAVE0( );
-+ return ret;
-+}
-+
-+static mmc_notifier_rec_t mmc_test_notifier = {
-+ add: mmc_test_add_card,
-+ remove: mmc_test_remove_card
-+};
-+#endif /* CONFIG_DEVFS_FS */
-+
-+static int __init mmc_test_module_init( void )
-+{
-+ int ret = -ENODEV;
-+
-+#ifdef CONFIG_DEVFS_FS
-+ if ( !mmc_register( MMC_REG_TYPE_USER, &mmc_test_notifier, 0 ) ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0, "failed to register with MMC core\n" );
-+ goto error;
-+ }
-+#else
-+ mmc_register( MMC_REG_TYPE_USER, NULL, 0 );
-+ if ( register_chrdev( MMC_TEST_MAJOR, "mmc_test", &mmc_test_fops ) ) {
-+ MMC_DEBUG( MMC_DEBUG_LEVEL0,
-+ "failed to request device major number\n" );
-+ mmc_unregister( MMC_REG_TYPE_USER, NULL );
-+ goto error;
-+ }
-+#endif
-+
-+ memset( mmc_test_device, 0, sizeof( mmc_test_device ) );
-+
-+ ret = 0;
-+error:
-+ return ret;
-+}
-+
-+static void __exit mmc_test_module_cleanup( void )
-+{
-+#ifdef CONFIG_DEVFS_FS
-+ mmc_unregister( MMC_REG_TYPE_USER, &mmc_test_notifier );
-+#else
-+ mmc_unregister( MMC_REG_TYPE_USER, NULL );
-+ unregister_chrdev( MMC_TEST_MAJOR, "mmc_test" );
-+#endif
-+}
-+
-+EXPORT_NO_SYMBOLS;
-+
-+module_init( mmc_test_module_init );
-+module_exit( mmc_test_module_cleanup );
-+
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/mmc/pm_test.c 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,29 @@
-+/* Power Managment Test Module. RTSoft Co. 2002 */
-+
-+/* The necessary header files */
-+
-+/* Standard in kernel modules */
-+#include <linux/kernel.h> /* We're doing kernel work */
-+#include <linux/module.h> /* Specifically, a module */
-+#define CONFIG_PM
-+#include <linux/pm.h>
-+
-+
-+static int pmdata = -1;
-+
-+/* Initialize the module - register the proc file */
-+
-+int init_module()
-+{
-+ pm_send_all(PM_SUSPEND,&pmdata);
-+ return(0);
-+}
-+
-+
-+/* Cleanup - unregister our file from /proc */
-+void cleanup_module()
-+{
-+ pm_send_all(PM_RESUME,NULL);
-+}
-+
-+MODULE_LICENSE( "GPL" );
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/mmc/types.h 2004-03-31 17:15:11.000000000 +0200
-@@ -0,0 +1,59 @@
-+/*
-+ * linux/drivers/mmc/types.h
-+ *
-+ * Author: Vladimir Shebordaev
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#ifndef __MMC_TYPES_P_H__
-+#define __MMC_TYPES_P_H__
-+
-+#ifdef __KERNEL__
-+#include <linux/kdev_t.h>
-+
-+typedef enum _mmc_reg_type mmc_reg_type_t;
-+typedef enum _mmc_response mmc_response_fmt_t;
-+
-+/* MMC card private description */
-+typedef struct _mmc_card_rec mmc_card_rec_t;
-+typedef struct _mmc_card_rec *mmc_card_t;
-+typedef enum _mmc_dir mmc_dir_t;
-+typedef enum _mmc_buftype mmc_buftype_t;
-+
-+/* notifier declarations */
-+typedef struct _mmc_notifier_rec mmc_notifier_rec_t;
-+typedef struct _mmc_notifier_rec *mmc_notifier_t;
-+
-+typedef int (*mmc_notifier_fn_t) ( mmc_card_t );
-+
-+/* MMC card stack */
-+typedef struct _mmc_card_stack_rec mmc_card_stack_rec_t;
-+typedef struct _mmc_card_stack_rec *mmc_card_stack_t;
-+
-+typedef struct _mmc_data_transfer_req_rec mmc_data_transfer_req_rec_t;
-+typedef struct _mmc_data_transfer_req_rec *mmc_data_transfer_req_t;
-+
-+/* MMC controller */
-+typedef struct _mmc_controller_tmpl_rec mmc_controller_tmpl_rec_t;
-+typedef struct _mmc_controller_tmpl_rec *mmc_controller_tmpl_t;
-+
-+typedef enum _mmc_controller_state mmc_controller_state_t;
-+typedef struct _mmc_controller_rec mmc_controller_rec_t;
-+typedef struct _mmc_controller_rec *mmc_controller_t;
-+
-+/* various kernel types */
-+typedef struct semaphore semaphore_t;
-+typedef struct rw_semaphore rwsemaphore_t;
-+typedef struct proc_dir_entry proc_dir_entry_rec_t;
-+typedef struct proc_dir_entry *proc_dir_entry_t;
-+typedef struct gendisk gendisk_rec_t;
-+typedef struct gendisk *gendisk_t;
-+#endif /* __KERNEL__ */
-+
-+#endif /* __MMC_TYPES_P_H__ */
-+
---- linux-2.4.25/drivers/net/Config.in~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/net/Config.in 2004-03-31 17:15:11.000000000 +0200
-@@ -125,6 +125,7 @@
- dep_tristate ' SMC Ultra support' CONFIG_ULTRA $CONFIG_ISA
- dep_tristate ' SMC Ultra32 EISA support' CONFIG_ULTRA32 $CONFIG_EISA
- dep_tristate ' SMC 9194 support' CONFIG_SMC9194 $CONFIG_ISA
-+ tristate ' SMC 91C9x/91C1xx support' CONFIG_SMC91X
- fi
- bool ' Racal-Interlan (Micom) NI cards' CONFIG_NET_VENDOR_RACAL
- if [ "$CONFIG_NET_VENDOR_RACAL" = "y" ]; then
---- linux-2.4.25/drivers/net/Makefile~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/net/Makefile 2004-03-31 17:15:11.000000000 +0200
-@@ -137,6 +137,7 @@
- obj-$(CONFIG_SK_G16) += sk_g16.o
- obj-$(CONFIG_HP100) += hp100.o
- obj-$(CONFIG_SMC9194) += smc9194.o
-+obj-$(CONFIG_SMC91X) += smc91x.o
- obj-$(CONFIG_ARM_AM79C961A) += am79c961a.o
- obj-$(CONFIG_ARM_ETHERH) += 8390.o
- obj-$(CONFIG_WD80x3) += wd.o 8390.o
---- linux-2.4.25/drivers/net/cirrus.c~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/net/cirrus.c 2004-03-31 17:15:11.000000000 +0200
-@@ -67,6 +67,9 @@
- #elif CONFIG_ARCH_CDB89712
- # define CIRRUS_DEFAULT_IO ETHER_BASE + 0x300
- # define CIRRUS_DEFAULT_IRQ IRQ_EINT3
-+#elif CONFIG_ARCH_CSB226
-+# define CIRRUS_DEFAULT_IO 0xF8000000
-+# define CIRRUS_DEFAULT_IRQ IRQ_GPIO(14)
- #else
- # define CIRRUS_DEFAULT_IO 0
- # define CIRRUS_DEFAULT_IRQ 0
---- linux-2.4.25/drivers/net/irda/Config.in~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/net/irda/Config.in 2004-03-31 17:15:11.000000000 +0200
-@@ -42,5 +42,7 @@
- if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
- dep_tristate 'SA1100 Internal IR' CONFIG_SA1100_FIR $CONFIG_IRDA $CONFIG_EXPERIMENTAL
- fi
--
-+if [ "$CONFIG_ARCH_PXA" = "y" ]; then
-+ dep_tristate 'Intel PXA2xx Internal IR' CONFIG_PXA_FIR $CONFIG_IRDA $CONFIG_EXPERIMENTAL
-+fi
- endmenu
---- linux-2.4.25/drivers/net/irda/Makefile~2.4.25-vrs2-pxa1.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/net/irda/Makefile 2004-03-31 17:15:12.000000000 +0200
-@@ -16,6 +16,7 @@
- obj-$(CONFIG_USB_IRDA) += irda-usb.o
- obj-$(CONFIG_NSC_FIR) += nsc-ircc.o
- obj-$(CONFIG_WINBOND_FIR) += w83977af_ir.o
-+obj-$(CONFIG_PXA_FIR) += pxa_ir.o
- obj-$(CONFIG_SA1100_FIR) += sa1100_ir.o
- obj-$(CONFIG_TOSHIBA_OLD) += toshoboe.o
- obj-$(CONFIG_TOSHIBA_FIR) += donauboe.o
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/net/irda/pxa_ir.c 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,1545 @@
-+/*
-+ * linux/drivers/net/irda/pxa_ir.c
-+ *
-+ * Author:
-+ * Alexey Lugovskoy RTSoft.
-+ * lugovskoy@rtsoft.msk.ru
-+ *
-+ * Dmitrij Frasenyak RTSoft.
-+ * sed@mipt.sw.ru
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Infra-red SIR and FIR driver for the PXA 210/250 embedded microprocessors
-+ * Based on linux/drivers/net/irda/sa1100_ir.c
-+ *
-+ */
-+
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/netdevice.h>
-+#include <linux/slab.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/interrupt.h>
-+#include <linux/delay.h>
-+#include <linux/ioport.h>
-+#include <linux/delay.h>
-+
-+#include <linux/pm.h>
-+
-+#include <net/irda/irda.h>
-+#include <net/irda/irmod.h>
-+#include <net/irda/wrapper.h>
-+#include <net/irda/irda_device.h>
-+
-+#include <asm/irq.h>
-+#include <asm/dma.h>
-+#include <asm/hardware.h>
-+#include <asm/mach-types.h>
-+#include <asm/arch/lubbock.h>
-+
-+
-+static int rx_count = 0;
-+static int tx_count = 0;
-+
-+/*
-+ * Our netdevice. There is only ever one of these.
-+ */
-+
-+static struct net_device *netdev;
-+
-+struct pxa250_irda {
-+
-+ unsigned char open;
-+
-+ int speed;
-+ int newspeed;
-+
-+ struct sk_buff *txskb;
-+ struct sk_buff *rxskb;
-+
-+
-+ /* => FIR */
-+ unsigned int fir_irq;
-+ int txdma_ch;
-+ int rxdma_ch;
-+ dma_addr_t txbuf_dma;
-+ dma_addr_t rxbuf_dma;
-+ void* txbuf_dma_virt;
-+ void* rxbuf_dma_virt;
-+ /* <= FIR*/
-+ struct net_device_stats stats;
-+ struct irlap_cb *irlap;
-+ struct pm_dev *pmdev;
-+ struct qos_info qos;
-+
-+ /* => SIR */
-+ iobuff_t tx_buff;
-+ iobuff_t rx_buff;
-+ /* <= SIR */
-+};
-+
-+#define IS_FIR(si) ((si)->speed >= 4000000)
-+
-+#define HPSIR_MAX_RXLEN 2050
-+#define HPSIR_MAX_TXLEN 2050
-+#define TXBUFF_MAX_SIZE HPSIR_MAX_TXLEN
-+#define SET_SIR_MODE STISR = STISR_RCVEIR | STISR_XMITIR | STISR_XMODE
-+
-+/*
-+ * If you want to disable debug information
-+ * please uncomment line bellow
-+ */
-+
-+#define PXA_FIR_DUMP_ENABLE
-+#undef PXA_FIR_DUMP_ENABLE
-+
-+
-+#define PXA_FIR_DEBUG_ENABLE
-+#undef PXA_FIR_DEBUG_ENABLE
-+
-+#define PXA_FIR_IRQ_DEBUG_ENABLE
-+#undef PXA_FIR_IRQ_DEBUG_ENABLE
-+
-+#ifdef PXA_FIR_DEBUG_ENABLE
-+#define __ECHO_IN printk(KERN_ERR "%s: enter\n",__FUNCTION__);
-+#define __ECHO_OUT printk(KERN_ERR "%s: exit\n",__FUNCTION__);
-+#define DBG(args...) printk(KERN_ERR __FUNCTION__"():"args);
-+#else
-+#define __ECHO_IN
-+#define __ECHO_OUT
-+#define DBG(args...)
-+#endif
-+
-+#ifdef PXA_FIR_IRQ_DEBUG_ENABLE
-+#define DBG_IRQ(args...) printk(KERN_ERR __FUNCTION__"():"args);
-+#else
-+#define DBG_IRQ(args...)
-+#endif
-+
-+
-+static int pxa250_irda_set_speed(struct net_device *dev,int speed);
-+static void pxa250_start_rx_dma(struct net_device *dev);
-+
-+
-+
-+/**************************************************************************
-+ * Misc FIR/SIR functions *
-+ **************************************************************************/
-+/*
-+ * Allocate the receive buffer, unless it is already allocated.
-+ */
-+
-+static int pxa250_irda_rx_alloc(struct pxa250_irda *si)
-+{
-+ __ECHO_IN;
-+
-+ if (si->rxskb)
-+ return 0;
-+
-+ si->rxskb = alloc_skb(HPSIR_MAX_RXLEN + 1, GFP_ATOMIC);
-+
-+ if (!si->rxskb) {
-+ printk(KERN_ERR "pxa250_ir: out of memory for RX SKB\n");
-+ return -ENOMEM;
-+ }
-+
-+ /*
-+ * Align any IP headers that may be contained
-+ * within the frame.
-+ */
-+ skb_reserve(si->rxskb, 1);
-+
-+ __ECHO_OUT;
-+
-+ return 0;
-+}
-+
-+
-+
-+/**************************************************************************
-+ * FIR *
-+ **************************************************************************/
-+
-+
-+
-+
-+static inline void pxa250_dma_stop(int ch)
-+{
-+ __ECHO_IN;
-+
-+ DCSR(ch) &= ~DCSR_RUN;
-+
-+ __ECHO_OUT;
-+
-+}
-+
-+
-+static void pxa250_ficp_rx_start(void)
-+{
-+ ICCR0 = 0;
-+ ICCR2 = 1 << 2 | 0 << 3 ;
-+ ICCR0 = ICCR0_ITR ;
-+ ICCR0 |= ICCR0_RIE | ICCR0_RXE ;
-+}
-+
-+/*
-+ * Change Alternative Function encoding
-+ * Enable ICP unit
-+ * Disabe STUART unit
-+ * Enable IRQ unit clock;
-+ * Configure direction of GPIO used by ICP
-+ */
-+
-+
-+static void pxa250_do_fir_GPIO_config(void)
-+{
-+ /*
-+ * Modify GPIO 46 and 47 Alternate Function
-+ */
-+
-+ __ECHO_IN;
-+
-+ /*Switch AF*/
-+ set_GPIO_mode (GPIO46_ICPRXD_MD);
-+ set_GPIO_mode (GPIO47_ICPTXD_MD);
-+
-+ if (machine_is_lubbock())
-+ LUB_MISC_WR |= 1 << 4;
-+
-+ /*init clock*/
-+ CKEN |= CKEN13_FICP;
-+
-+ __ECHO_OUT;
-+}
-+
-+/*
-+ * Low level hardware configuration and startup.
-+ */
-+
-+static int pxa250_fir_irda_startup(struct pxa250_irda *si)
-+{
-+
-+ __ECHO_IN;
-+
-+ /*
-+ * Disable STUART
-+ */
-+
-+ STIER &= ~IER_UUE;
-+
-+ /*Disable STUART FIFO */
-+ STFCR = 0;
-+
-+ /*
-+ * Do low level configuration for HW AF and clock
-+ */
-+ pxa250_do_fir_GPIO_config();
-+
-+ __ECHO_OUT;
-+ return 0;
-+}
-+
-+
-+/*
-+ * Aieeeeee .. we should never get here :(
-+ */
-+static void pxa250_irda_rxdma_irq(int ch,void *id, struct pt_regs *regs)
-+{
-+ struct net_device *dev=id;
-+ struct pxa250_irda *si=dev->priv;
-+ u_int dcsr;
-+
-+
-+ __ECHO_IN;
-+
-+ /*
-+ * Make sure that irq is our.
-+ */
-+
-+ if ( ch != si->rxdma_ch )
-+ /*just*/ return;
-+
-+ /*
-+ * Check status
-+ */
-+ dcsr = DCSR(ch);
-+
-+ DBG("DCSR=%x\n",dcsr);
-+
-+ if (dcsr & DCSR_STOPSTATE )
-+ {
-+ DBG_IRQ("Chanel %d in stop state\n",ch);
-+ }
-+
-+ if (dcsr & DCSR_BUSERR )
-+ {
-+ /*
-+ * BUS Error we must restart reception
-+ */
-+
-+ DBG("PXA IrDA: bus error interrupt on channel %d\n", ch);
-+ DCSR(ch) |= DCSR_BUSERR;
-+ }
-+
-+ if (dcsr & DCSR_ENDINTR )
-+ {
-+ DBG("PXA IrDA: Normal end of dma channel %d - packet to big\n", ch);
-+ DCSR(ch) |= DCSR_ENDINTR;
-+ }
-+
-+ /* no mater what restart rx*/
-+ pxa250_start_rx_dma(dev);
-+
-+ return ;
-+
-+}
-+
-+
-+static void pxa250_irda_txdma_irq(int ch, void *id , struct pt_regs *regs)
-+{
-+ struct net_device *dev=id;
-+ struct pxa250_irda *si=dev->priv;
-+ struct sk_buff *skb = si->txskb;
-+ u_int dcsr;
-+
-+
-+ __ECHO_IN;
-+ DBG_IRQ("transmit\n");
-+
-+
-+ /*
-+ * Make sure that irq is our.
-+ */
-+
-+ if ( ch != si->txdma_ch )
-+ /*just*/ return;
-+
-+
-+ /*
-+ * Check status
-+ */
-+ dcsr = DCSR(ch);
-+
-+ DBG("DCSR=%x",dcsr);
-+
-+ if (dcsr & DCSR_STOPSTATE )
-+ {
-+ DBG("Chanel %d in stop state\n",ch);
-+ }
-+
-+ if (dcsr & DCSR_BUSERR )
-+ {
-+ DBG("PXA IrDA: bus error interrupt on channel %d\n", ch);
-+ DCSR(ch) |= DCSR_BUSERR;
-+ si->txskb = NULL;
-+ }
-+
-+ if (dcsr & DCSR_ENDINTR )
-+ {
-+ DBG("PXA IrDA: Normal end of dma channel %d\n", ch);
-+ DCSR(ch) |= DCSR_ENDINTR;
-+ si->txskb = NULL;
-+ }
-+
-+ /*
-+ * Account and free the packet.
-+ */
-+ if (skb)
-+ {
-+ si->stats.tx_packets ++;
-+ si->stats.tx_bytes += skb->len;
-+ dev_kfree_skb_irq(skb);
-+ }
-+
-+ /*Disable transceiver and enable receiver*/
-+
-+ if (si->newspeed) {
-+ pxa250_irda_set_speed(dev, si->newspeed);
-+ si->newspeed = 0;
-+ }
-+
-+ while (ICSR1 & ICSR1_TBY)
-+ udelay(1);
-+
-+ ICCR0 &= ~ICCR0_TXE;
-+
-+
-+ enable_irq(si->fir_irq);
-+
-+ ICCR0 |= ICCR0_RXE;
-+
-+ /*
-+ * Make sure that the TX queue is available for sending
-+ * (for retries). TX has priority over RX at all times.
-+ */
-+ netif_wake_queue(dev);
-+
-+ __ECHO_OUT;
-+}
-+
-+
-+static void pxa250_start_rx_dma(struct net_device *dev)
-+{
-+ struct pxa250_irda *si = dev->priv;
-+ int ch=si->rxdma_ch;
-+
-+ if (!si->rxskb) {
-+ DBG("rx buffer went missing\n");
-+/* return; */
-+ }
-+
-+ DCSR(ch)=0;
-+ DCSR(ch)=DCSR_NODESC;
-+ DSADR(ch) = __PREG(ICDR);
-+ DTADR(ch) = si->rxbuf_dma; /* phisical address */;
-+
-+ /* We should never do END_IRQ. !!!*/
-+ DCMD(ch) = DCMD_ENDIRQEN| DCMD_INCTRGADDR | DCMD_FLOWSRC | DCMD_BURST8 | DCMD_WIDTH1 | HPSIR_MAX_RXLEN;
-+
-+ /*
-+ * All right information will be available as soon as we set RXE flag
-+ */
-+
-+ DCSR(ch) = DCSR_ENDINTR | DCSR_BUSERR;
-+ DCSR(ch) = DCSR_RUN | DCSR_NODESC ;
-+
-+}
-+
-+
-+
-+
-+static int pxa250_get_rx_len(struct pxa250_irda *si)
-+{
-+ /*
-+ * DMA have to be stoped here
-+ */
-+
-+ if ( ! (DCSR(si->rxdma_ch) & DCSR_STOPSTATE) )
-+ printk("warning dma have to be stoped befor counting len\n");
-+
-+ return ( HPSIR_MAX_RXLEN - ( DCMD(si->rxdma_ch) & DCMD_LENGTH ) );
-+
-+}
-+
-+static void pxa250_irda_fir_error(struct net_device *dev)
-+{
-+ struct pxa250_irda *si = dev->priv;
-+ struct sk_buff *skb = si->rxskb;
-+ int len;
-+ int stat,data;
-+
-+ __ECHO_IN;
-+
-+ if (!skb)
-+ {
-+ printk("pxa250 fir_error: SKB is NULL!\n");
-+ return;
-+ }
-+
-+ /*
-+ * Get the current data position.
-+ */
-+
-+ len=pxa250_get_rx_len(si);
-+ DBG("RXLEN=%d\n",len);
-+ memcpy(skb->data, si->rxbuf_dma_virt, len);
-+
-+ do {
-+ /*
-+ * Read Status, and then Data.
-+ */
-+ stat = ICSR1;
-+ rmb();
-+ data = ICDR;
-+ if (stat & (ICSR1_CRE | ICSR1_ROR)) {
-+ si->stats.rx_errors++;
-+ if (stat & ICSR1_CRE)
-+ si->stats.rx_crc_errors++;
-+ if (stat & ICSR1_ROR)
-+ si->stats.rx_frame_errors++;
-+ } else
-+ skb->data[len++] = data;
-+
-+ /*
-+ * If we hit the end of frame, there's
-+ * no point in continuing.
-+ */
-+ if (stat & ICSR1_EOF)
-+ break;
-+ } while (ICSR0 & ICSR0_EIF);
-+
-+ if (stat & ICSR1_EOF) {
-+ si->rxskb = NULL;
-+
-+ skb_put(skb, len);
-+ skb->dev = dev;
-+ skb->mac.raw = skb->data;
-+ skb->protocol = htons(ETH_P_IRDA);
-+ si->stats.rx_packets++;
-+ si->stats.rx_bytes += len;
-+
-+ /*
-+ * Before we pass the buffer up, allocate a new one.
-+ */
-+
-+ si->rxskb = alloc_skb(HPSIR_MAX_RXLEN + 1, GFP_ATOMIC);
-+
-+ if (!si->rxskb) {
-+ printk(KERN_ERR "pxa250_ir: out of memory for RX SKB\n");
-+ return;
-+ }
-+
-+ /*
-+ * Align any IP headers that may be contained
-+ * within the frame.
-+ */
-+ skb_reserve(si->rxskb, 1);
-+
-+ netif_rx(skb);
-+ }
-+}
-+
-+/*
-+ * FIR format interrupt service routine. We only have to
-+ * handle RX events; transmit events go via the TX DMA irq handler.
-+ *
-+ * No matter what, we disable RX, process, and then restart RX.
-+ */
-+
-+static void pxa250_irda_fir_irq(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct net_device *dev = dev_id;
-+ struct pxa250_irda *si = dev->priv;
-+ int status;
-+
-+ /*
-+ * Stop RX
-+ */
-+
-+ __ECHO_IN;
-+
-+ pxa250_dma_stop(si->rxdma_ch);
-+
-+
-+ /*
-+ * Framing error - we throw away the packet completely.
-+ * Clearing RXE flushes the error conditions and data
-+ * from the fifo.
-+ */
-+ status=ICSR0;
-+
-+ if (status & (ICSR0_FRE | ICSR0_RAB)) {
-+ DBG_IRQ("Framing error or RAB\n");
-+
-+ si->stats.rx_errors++;
-+
-+ if (ICSR0 & ICSR0_FRE)
-+ si->stats.rx_frame_errors++;
-+
-+ /* Clear RX fifo
-+ * DMA will be cleared when we restart RX
-+ * Should we check RNE after that?
-+ */
-+
-+ ICCR0 &= ~ICCR0_RXE;
-+
-+ /*
-+ * Clear selected status bits now, so we
-+ * don't miss them next time around.
-+ */
-+ ICSR0 = status & (ICSR0_FRE | ICSR0_RAB);
-+ }
-+
-+
-+ /*
-+ * Deal with any receive errors. The any of the lowest
-+ * 8 bytes in the FIFO may contain an error. We must read
-+ * them one by one. The "error" could even be the end of
-+ * packet!
-+ */
-+ if (ICSR0 & ICSR0_EIF)
-+ pxa250_irda_fir_error(dev);
-+
-+ /*
-+ * No matter what happens, we must restart reception.
-+ */
-+
-+ ICCR0 = 0;
-+ pxa250_start_rx_dma(dev);
-+ pxa250_ficp_rx_start();
-+ __ECHO_OUT;
-+}
-+
-+
-+
-+
-+
-+/**************************************************************************
-+ * SIR *
-+ **************************************************************************/
-+/*
-+ * HP-SIR format interrupt service routines.
-+ */
-+static void pxa250_sir_transmit(struct net_device *dev)
-+{
-+ struct pxa250_irda *si = dev->priv;
-+
-+ if (si->tx_buff.len)
-+ {
-+ /* Disable receiver and enable transmiter*/
-+
-+
-+
-+ STISR &= ~STISR_RCVEIR;
-+// STISR |= STISR_XMITIR;
-+
-+
-+
-+ disable_irq(dev->irq);
-+
-+ do
-+ {
-+
-+ if (STLSR & LSR_TDRQ)
-+ {
-+ STTHR = *si->tx_buff.data++;
-+ si->tx_buff.len -= 1;
-+
-+ tx_count++;
-+ }
-+
-+
-+ } while (si->tx_buff.len);
-+
-+
-+ if (si->tx_buff.len == 0)
-+ {
-+
-+
-+ si->stats.tx_packets++;
-+ si->stats.tx_bytes += si->tx_buff.data -
-+ si->tx_buff.head;
-+
-+ /*
-+ * We need to ensure that the transmitter has
-+ * finished.
-+ */
-+
-+ do
-+ {
-+ udelay(1);
-+
-+ }
-+ while ( ! (STLSR & LSR_TEMT) );
-+
-+
-+ /*
-+
-+ * Ok, we've finished transmitting. Now enable
-+ * the receiver. Sometimes we get a receive IRQ
-+ * immediately after a transmit...
-+ */
-+
-+ if (si->newspeed)
-+ {
-+ pxa250_irda_set_speed(dev, si->newspeed);
-+ si->newspeed = 0;
-+ }
-+
-+ /* I'm hungry! */
-+ netif_wake_queue(dev);
-+ }
-+
-+ enable_irq (dev->irq);
-+ STIER = (IER_RAVIE | IER_UUE | IER_RTIOE);
-+
-+ STISR |= STISR_RCVEIR;
-+// STISR &= ~STISR_XMITIR;
-+ }
-+}
-+
-+static void pxa250_irda_hpsir_irq(struct net_device *dev)
-+{
-+ struct pxa250_irda *si = dev->priv;
-+
-+ /*
-+ * Deal with any receive errors first. The bytes in error may be
-+ * the only bytes in the receive FIFO, so we do this first.
-+ */
-+ __ECHO_IN;
-+
-+ while (STLSR & LSR_FIFOE)
-+ {
-+ int stat, data;
-+
-+ stat = STLSR;
-+ data = STRBR;
-+
-+
-+ if (stat & (LSR_FE | LSR_OE | LSR_PE))
-+
-+ {
-+ si->stats.rx_errors++;
-+ if (stat & LSR_FE)
-+ si->stats.rx_frame_errors++;
-+ if (stat & LSR_OE)
-+ si->stats.rx_fifo_errors++;
-+
-+ } else
-+ {
-+ rx_count++;
-+ async_unwrap_char(dev, &si->stats, &si->rx_buff, data);
-+ }
-+
-+ }
-+
-+ /*
-+ * We must clear certain bits.
-+ */
-+
-+ if (STLSR & (LSR_DR))
-+ {
-+ /*
-+ * Fifo contains at least 1 character.
-+ */
-+ do
-+ {
-+ int data;
-+
-+ data = STRBR;
-+
-+ async_unwrap_char(dev, &si->stats, &si->rx_buff,
-+ data); /* was Ser2UTDR); Clo */
-+ rx_count++;
-+
-+ } while (STLSR & LSR_DR);
-+
-+ dev->last_rx = jiffies;
-+ }
-+
-+ __ECHO_OUT;
-+}
-+
-+static void pxa250_sir_irda_shutdown(struct pxa250_irda *si)
-+{
-+
-+ STIER = 0;
-+ STFCR = 0;
-+ STISR = 0;
-+ CKEN &= ~CKEN5_STUART;
-+}
-+
-+
-+/************************************************************************************/
-+
-+/*Low level init/uninstall function PM control and IrDA protocol stack registration */
-+
-+/*
-+ * Set the IrDA communications speed.
-+ * Interrupt have to be disabled here.
-+ */
-+
-+static int pxa250_irda_startup(struct net_device *dev)
-+{
-+
-+
-+ __ECHO_IN;
-+
-+ /*
-+ * Ensure that the ports for this device are setup correctly.
-+ */
-+
-+
-+ set_GPIO_mode (GPIO46_STRXD_MD);
-+ set_GPIO_mode (GPIO47_STTXD_MD);
-+
-+ STMCR = MCR_OUT2;
-+ STLCR = LCR_WLS1 | LCR_WLS0;
-+
-+ SET_SIR_MODE;
-+ CKEN |= CKEN5_STUART;
-+ /* enable irq from stuart */
-+ ICMR |= ( 1 << 20 );
-+
-+ /*reset FIFO*/
-+
-+/* STFCR = FCR_TRFIFOE | FCR_RESETTF | FCR_RESETRF;// | FCR_ITL_16;
-+
-+ STIER = IER_UUE | IER_RAVIE | IER_RTOIE;
-+*/
-+ __ECHO_OUT;
-+
-+ return 0;
-+
-+}
-+
-+
-+#ifdef CONFIG_PM
-+/*
-+ * Suspend the IrDA interface.
-+ */
-+
-+static int pxa250_irda_shutdown(struct pxa250_irda *si)
-+{
-+
-+ pxa250_sir_irda_shutdown(si);
-+ return 0;
-+
-+}
-+
-+
-+static int pxa250_irda_suspend(struct net_device *dev, int state)
-+{
-+ struct pxa250_irda *si = dev->priv;
-+
-+ if (si && si->open) {
-+ /*
-+ * Stop the transmit queue
-+ */
-+ if (IS_FIR(si))
-+ return -1;
-+
-+ netif_stop_queue(dev);
-+ disable_irq(dev->irq);
-+ disable_irq(si->fir_irq);
-+ pxa250_sir_irda_shutdown(si);
-+ }
-+
-+ return 0;
-+}
-+
-+/*
-+ * Resume the IrDA interface.
-+ */
-+
-+static int pxa250_irda_resume(struct net_device *dev)
-+{
-+ struct pxa250_irda *si = dev->priv;
-+
-+ __ECHO_IN;
-+
-+ if (si && si->open) {
-+ /*
-+ * If we missed a speed change, initialise at the new speed
-+ * directly. It is debatable whether this is actually
-+ * required, but in the interests of continuing from where
-+ * we left off it is desireable. The converse argument is
-+ * that we should re-negotiate at 9600 baud again.
-+ */
-+ if (si->newspeed) {
-+ si->speed = si->newspeed;
-+ si->newspeed = 0;
-+ }
-+
-+ pxa250_irda_startup(dev);
-+ enable_irq(dev->irq);
-+
-+ /*
-+ * This automatically wakes up the queue
-+ */
-+ netif_wake_queue(dev);
-+ pxa250_irda_set_speed(dev,si->speed = 9600);
-+
-+ }
-+
-+ __ECHO_OUT;
-+ return 0;
-+}
-+
-+static int pxa250_irda_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data)
-+{
-+ int ret;
-+
-+
-+ if (!dev->data)
-+ return -EINVAL;
-+
-+
-+ switch (rqst) {
-+ case PM_SUSPEND:
-+ ret = pxa250_irda_suspend((struct net_device *)dev->data,
-+ (int)data);
-+ break;
-+
-+ case PM_RESUME:
-+ ret = pxa250_irda_resume((struct net_device *)dev->data);
-+ break;
-+
-+ default:
-+
-+ ret = -EINVAL;
-+ break;
-+ }
-+
-+ return ret;
-+}
-+#endif
-+
-+
-+
-+
-+static void pxa250_irda_irq(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct net_device *dev = dev_id;
-+
-+ pxa250_irda_hpsir_irq(dev);
-+
-+}
-+
-+
-+static int pxa250_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+ struct pxa250_irda *si = dev->priv;
-+ int speed = irda_get_next_speed(skb);
-+ int mtt;
-+
-+ __ECHO_IN;
-+
-+ /*
-+ * Does this packet contain a request to change the interface
-+ * speed? If so, remember it until we complete the transmission
-+ * of this frame.
-+ */
-+ if (speed != si->speed && speed != -1)
-+ si->newspeed = speed;
-+
-+ /*
-+ * If this is an empty frame, we can bypass a lot.
-+ */
-+ if (skb->len == 0) {
-+ if (si->newspeed) {
-+ si->newspeed = 0;
-+ pxa250_irda_set_speed(dev, speed);
-+ }
-+ dev_kfree_skb(skb);
-+ return 0;
-+ }
-+
-+
-+ DBG("stop queue\n");
-+ netif_stop_queue(dev);
-+
-+ if(!IS_FIR(si))
-+ {
-+
-+ si->tx_buff.data = si->tx_buff.head;
-+ si->tx_buff.len = async_wrap_skb(skb, si->tx_buff.data,
-+ si->tx_buff.truesize);
-+
-+
-+ pxa250_sir_transmit(dev);
-+
-+
-+
-+ dev_kfree_skb(skb);
-+
-+ dev->trans_start = jiffies;
-+
-+ return 0;
-+ }
-+ else /* FIR */
-+ {
-+ DBG("Enter FIR transmit\n");
-+ /*
-+ * We must not be transmitting...
-+ */
-+ if (si->txskb)
-+ BUG();
-+
-+ disable_irq(si->fir_irq);
-+
-+ netif_stop_queue(dev);
-+ DBG("queue stoped\n");
-+ si->txskb = skb;
-+
-+ /* we could not just map so we'll need some triks */
-+ /* skb->data may be not DMA capable -Sed- */
-+
-+
-+ if (skb->len > TXBUFF_MAX_SIZE)
-+ {
-+ printk (KERN_ERR "skb data too large\n");
-+ printk (KERN_ERR "len=%d",skb->len);
-+ BUG();
-+ }
-+
-+
-+ DBG("gonna copy %d bytes to txbuf\n",skb->len);
-+
-+ memcpy (si->txbuf_dma_virt, skb->data , skb->len);
-+
-+ /* Actual sending ;must not be receiving !!! */
-+ /* Write data and source address */
-+
-+ DBG("ICSR1 & RNE =%d\n",(ICSR1 & ICSR1_RNE) ? 1 : 0 );
-+
-+ /*Disable receiver and enable transifer */
-+ ICCR0 &= ~ICCR0_RXE;
-+
-+ if (ICSR1 & ICSR1_TBY)
-+ BUG();
-+
-+ ICCR0 |= ICCR0_TXE;
-+
-+ DBG("FICP status %x\n",ICSR0);
-+
-+ if (0){
-+ int i;
-+
-+ DBG("sending packet\n");
-+ for (i=0;i<skb->len;i++)
-+ (i % 64) ? printk ("%2x ",skb->data[i]) : printk ("%2x \n",skb->data[i]) ;
-+ DBG(" done\n");
-+
-+ }
-+ /*
-+ * If we have a mean turn-around time, impose the specified
-+ * specified delay. We could shorten this by timing from
-+ * the point we received the packet.
-+ */
-+
-+ mtt = irda_get_mtt(skb);
-+ if(mtt)
-+ udelay(mtt);
-+
-+ DCSR(si->txdma_ch)=0;
-+ DCSR(si->txdma_ch)=DCSR_NODESC;
-+ DSADR(si->txdma_ch) = si->txbuf_dma; /* phisic address */
-+ DTADR(si->txdma_ch) = __PREG(ICDR);
-+
-+ DCMD(si->txdma_ch) = DCMD_ENDIRQEN| DCMD_INCSRCADDR | DCMD_FLOWTRG | DCMD_BURST8 | DCMD_WIDTH1 | skb->len;
-+
-+ DCSR(si->txdma_ch) = DCSR_ENDINTR | DCSR_BUSERR;
-+ DCSR(si->txdma_ch) = DCSR_RUN | DCSR_NODESC ;
-+
-+ DBG("FICP status %x\n",ICSR0);
-+
-+ return 0;
-+ }
-+
-+}
-+
-+static int
-+pxa250_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
-+{
-+ struct if_irda_req *rq = (struct if_irda_req *)ifreq;
-+ struct pxa250_irda *si = dev->priv;
-+ int ret = -EOPNOTSUPP;
-+
-+ __ECHO_IN;
-+
-+ switch (cmd) {
-+ case SIOCSBANDWIDTH:
-+ if (capable(CAP_NET_ADMIN)) {
-+ /*
-+ * We are unable to set the speed if the
-+ * device is not running.
-+ */
-+ if (si->open) {
-+ ret = pxa250_irda_set_speed(dev,
-+ rq->ifr_baudrate);
-+ } else {
-+ printk("pxa250_irda_ioctl: SIOCSBANDWIDTH: !netif_running\n");
-+ ret = 0;
-+ }
-+ }
-+ break;
-+
-+ case SIOCSMEDIABUSY:
-+ ret = -EPERM;
-+ if (capable(CAP_NET_ADMIN)) {
-+ irda_device_set_media_busy(dev, TRUE);
-+ ret = 0;
-+ }
-+ break;
-+
-+ case SIOCGRECEIVING:
-+ rq->ifr_receiving = IS_FIR(si) ? 0
-+ : si->rx_buff.state != OUTSIDE_FRAME;
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ __ECHO_OUT;
-+
-+ return ret;
-+}
-+
-+static struct net_device_stats *pxa250_irda_stats(struct net_device *dev)
-+{
-+ struct pxa250_irda *si = dev->priv;
-+ return &si->stats;
-+}
-+
-+static int pxa250_irda_start(struct net_device *dev)
-+{
-+ struct pxa250_irda *si = dev->priv;
-+ int err;
-+ unsigned int flags;
-+
-+
-+ MOD_INC_USE_COUNT;
-+
-+ __ECHO_IN;
-+ si->speed = 9600;
-+
-+ local_irq_save(flags);
-+
-+ err = request_irq(si->fir_irq, pxa250_irda_fir_irq, 0, dev->name, dev);
-+ if (err)
-+ goto err_fir_irq;
-+
-+ err = request_irq(dev->irq, pxa250_irda_irq, 0, dev->name, dev);
-+ if (err)
-+ goto err_irq;
-+
-+ /*
-+ * The interrupt must remain disabled for now.
-+ */
-+
-+ disable_irq(dev->irq);
-+ disable_irq(si->fir_irq);
-+
-+ local_irq_restore(flags);
-+
-+
-+ /* Allocate DMA channel for receiver (not used) */
-+ err = pxa_request_dma("IrDA receive", DMA_PRIO_LOW, pxa250_irda_rxdma_irq, dev);
-+ if (err < 0 )
-+ goto err_rx_dma;
-+ si->rxdma_ch=err;
-+
-+ DRCMRRXICDR = DRCMR_MAPVLD | si->rxdma_ch;
-+
-+
-+ /* Allocate DMA channel for transmit */
-+ err = pxa_request_dma("IrDA transmit", DMA_PRIO_LOW, pxa250_irda_txdma_irq , dev);
-+ if (err < 0 )
-+ goto err_tx_dma;
-+
-+ si->txdma_ch=err;
-+
-+ /*
-+ * Make sure that ICP will be able
-+ * to assert the transmit dma request bit
-+ * through the peripherals request bus (PREQ)
-+ */
-+
-+ DRCMRTXICDR = DRCMR_MAPVLD | si->txdma_ch;
-+
-+ DBG("rx(not used) channel=%d tx channel=%d\n",si->rxdma_ch,si->txdma_ch);
-+
-+ /* allocate consistent buffers for dma access
-+ * buffers have to be aligned and situated in dma capable memory region;
-+ */
-+ si->rxbuf_dma_virt = consistent_alloc(GFP_KERNEL | GFP_DMA ,HPSIR_MAX_RXLEN , &si->rxbuf_dma);
-+ if (! si->rxbuf_dma_virt )
-+ goto err_rxbuf_dma;
-+
-+ si->txbuf_dma_virt = consistent_alloc(GFP_KERNEL | GFP_DMA, HPSIR_MAX_TXLEN, &si->txbuf_dma);
-+ if (! si->txbuf_dma_virt )
-+ goto err_txbuf_dma;
-+
-+ /* Alocate skb for receiver */
-+ err=pxa250_irda_rx_alloc(si);
-+ if (err)
-+ goto err_rx_alloc;
-+
-+ /*
-+ * Setup the serial port for the specified config.
-+ */
-+ err = pxa250_irda_startup(dev);
-+ if (err)
-+ goto err_startup;
-+
-+ pxa250_irda_set_speed(dev,si->speed = 9600);
-+
-+
-+ /*
-+ * Open a new IrLAP layer instance.
-+ */
-+ si->irlap = irlap_open(dev, &si->qos, "pxa250");
-+ err = -ENOMEM;
-+ if (!si->irlap)
-+ goto err_irlap;
-+
-+ /*
-+ * Now enable the interrupt and start the queue
-+ */
-+ si->open = 1;
-+ enable_irq(dev->irq);
-+ netif_start_queue(dev);
-+ return 0;
-+
-+err_irlap:
-+ si->open = 0;
-+ pxa250_sir_irda_shutdown(si);
-+err_startup:
-+ dev_kfree_skb(si->rxskb);
-+err_rx_alloc:
-+ consistent_free (si->txbuf_dma_virt,HPSIR_MAX_TXLEN,si->txbuf_dma);
-+err_txbuf_dma:
-+ consistent_free (si->rxbuf_dma_virt,HPSIR_MAX_RXLEN,si->rxbuf_dma);
-+err_rxbuf_dma:
-+ pxa_free_dma(si->txdma_ch);
-+err_tx_dma:
-+ pxa_free_dma(si->rxdma_ch);
-+err_rx_dma:
-+ free_irq(dev->irq, dev);
-+err_irq:
-+ free_irq(si->fir_irq, dev);
-+err_fir_irq:
-+ MOD_DEC_USE_COUNT;
-+ return err;
-+}
-+
-+static int pxa250_irda_stop(struct net_device *dev)
-+{
-+ struct pxa250_irda *si = dev->priv;
-+
-+ printk(KERN_ERR "Irda stop... RX = %d TX = %d\n",rx_count,tx_count);
-+
-+ disable_irq(dev->irq);
-+ disable_irq(si->fir_irq);
-+/* pxa250_irda_shutdown(si); */
-+
-+ /*
-+ * If we have been doing DMA receive, make sure we
-+ * tidy that up cleanly.
-+ */
-+ if (si->rxskb) {
-+ dev_kfree_skb(si->rxskb);
-+ si->rxskb = NULL;
-+ }
-+
-+ /* Stop IrLAP */
-+ if (si->irlap) {
-+ irlap_close(si->irlap);
-+ si->irlap = NULL;
-+ }
-+
-+ consistent_free (si->txbuf_dma_virt,HPSIR_MAX_TXLEN,si->txbuf_dma);
-+ consistent_free (si->rxbuf_dma_virt,HPSIR_MAX_RXLEN,si->rxbuf_dma);
-+ pxa_free_dma(si->txdma_ch);
-+ pxa_free_dma(si->rxdma_ch);
-+
-+ netif_stop_queue(dev);
-+ si->open = 0;
-+
-+ /*
-+ * Free resources
-+ */
-+ free_irq(dev->irq, dev);
-+ free_irq(si->fir_irq, dev);
-+
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ return 0;
-+}
-+
-+static int pxa250_irda_init_iobuf(iobuff_t *io, int size)
-+{
-+ io->head = kmalloc(size, GFP_KERNEL | GFP_DMA);
-+ if (io->head != NULL) {
-+ io->truesize = size;
-+ io->in_frame = FALSE;
-+ io->state = OUTSIDE_FRAME;
-+ io->data = io->head;
-+ }
-+ return io->head ? 0 : -ENOMEM;
-+}
-+
-+
-+
-+
-+static int pxa250_stop_fir(struct net_device *dev)
-+{
-+ struct pxa250_irda *si = dev->priv;
-+ unsigned int flag;
-+
-+ save_flags(flag);
-+ cli();
-+
-+ pxa250_dma_stop(si->txdma_ch);
-+ pxa250_dma_stop(si->rxdma_ch);
-+
-+ if (si->txskb)
-+ dev_kfree_skb_irq(si->txskb);
-+
-+ ICCR0 &= ~(ICCR0_RXE | ICCR0_TXE );
-+ disable_irq(si->fir_irq);
-+ CKEN &= ~CKEN13_FICP;
-+
-+ restore_flags(flag);
-+
-+ return 0;
-+}
-+
-+
-+
-+static int pxa250_irda_set_speed(struct net_device *dev, int speed)
-+{
-+ struct pxa250_irda *si = dev->priv;
-+ int brd, ret = -EINVAL;
-+ static int last_fir_speed=0;
-+
-+ __ECHO_IN;
-+
-+
-+
-+ switch (speed) {
-+ case 9600: case 19200: case 38400:
-+ case 57600: case 115200:
-+
-+ /* Baud rate fixed - Clo */
-+
-+ /*
-+ * FIXME
-+ */
-+ if (last_fir_speed)
-+ {
-+
-+ pxa250_stop_fir(dev);
-+ set_GPIO_mode (GPIO46_STRXD_MD);
-+ set_GPIO_mode (GPIO47_STTXD_MD);
-+
-+ enable_irq(dev->irq);
-+ netif_wake_queue(dev);
-+ last_fir_speed=0;
-+ }
-+
-+
-+ LUB_MISC_WR &= ~(1 << 4);
-+
-+ brd = 14745600 / (16 * speed);
-+
-+ STLCR |= LCR_DLAB;
-+
-+ STDLH = brd >> 8; /* Clo: set Divisor Latch High */
-+ STDLL = brd & 0xFF; /* Clo: set Devisor Latch Low */
-+
-+ STLCR &= ~LCR_DLAB; /* Clo: clear DLAB bit */
-+
-+ STMCR = MCR_OUT2;
-+
-+ CKEN |= CKEN5_STUART;
-+
-+ ICMR |= ( 1 << 20 );
-+
-+ STLCR = LCR_WLS1 | LCR_WLS0;
-+
-+ SET_SIR_MODE;
-+
-+ STFCR = FCR_TRFIFOE | FCR_RESETTF | FCR_RESETRF | FCR_ITL_1 ;// | FCR_ITL_16;
-+
-+ STIER = IER_UUE | IER_RAVIE | IER_RTIOE;
-+
-+ si->speed = speed;
-+
-+ ret = 0;
-+ break;
-+
-+ case 4000000:
-+
-+ if (last_fir_speed)
-+ goto speed_out;
-+
-+ disable_irq(dev->irq);
-+
-+ pxa250_sir_irda_shutdown(si);
-+ pxa250_fir_irda_startup(si);
-+ pxa250_irda_rx_alloc(si);
-+ ICCR0=0;
-+ pxa250_start_rx_dma(dev);
-+ pxa250_ficp_rx_start();
-+
-+ enable_irq(si->fir_irq);
-+ DBG("enable FIR \n");
-+ si->speed = speed;
-+
-+ netif_wake_queue(dev);
-+ last_fir_speed=1;
-+speed_out:
-+
-+ ret=0;
-+
-+ break;
-+
-+ default:
-+ break;
-+ }
-+ __ECHO_OUT;
-+
-+ return ret;
-+}
-+
-+
-+static int pxa250_irda_net_init(struct net_device *dev)
-+{
-+ struct pxa250_irda *si = dev->priv;
-+ unsigned int baudrate_mask;
-+ int err = -ENOMEM;
-+
-+ si = kmalloc(sizeof(struct pxa250_irda), GFP_KERNEL);
-+ if (!si)
-+ goto out;
-+
-+ memset(si, 0, sizeof(*si));
-+
-+ /*
-+ * Initialise the HP-SIR buffers
-+ */
-+
-+ err = pxa250_irda_init_iobuf(&si->rx_buff, 14384);
-+ if (err)
-+ goto out;
-+ err = pxa250_irda_init_iobuf(&si->tx_buff, 4000);
-+ if (err)
-+ goto out_free_rx;
-+
-+ si->fir_irq = IRQ_ICP;
-+ dev->priv = si;
-+ dev->hard_start_xmit = pxa250_irda_hard_xmit;
-+ dev->open = pxa250_irda_start;
-+ dev->stop = pxa250_irda_stop;
-+ dev->do_ioctl = pxa250_irda_ioctl;
-+ dev->get_stats = pxa250_irda_stats;
-+
-+ irda_device_setup(dev);
-+ irda_init_max_qos_capabilies(&si->qos);
-+
-+ /*
-+ * We support original IRDA up to 115k2. (we don't currently
-+ * support 4Mbps). Min Turn Time set to 1ms or greater.
-+ */
-+ baudrate_mask = IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
-+ baudrate_mask |= IR_4000000 << 8;
-+ si->qos.baud_rate.bits &= baudrate_mask;
-+ si->qos.min_turn_time.bits = 7;
-+
-+ irda_qos_bits_to_value(&si->qos);
-+
-+#ifdef CONFIG_PM
-+ /*
-+ * Power-Management is optional.
-+ */
-+ si->pmdev = pm_register(PM_SYS_DEV, PM_SYS_IRDA, pxa250_irda_pmproc);
-+ if (si->pmdev)
-+ si->pmdev->data = dev;
-+#endif
-+
-+ return 0;
-+
-+ kfree(si->tx_buff.head);
-+out_free_rx:
-+ kfree(si->rx_buff.head);
-+out:
-+ kfree(si);
-+
-+ return err;
-+}
-+
-+/*
-+ * Remove all traces of this driver module from the kernel, so we can't be
-+ * called. Note that the device has already been stopped, so we don't have
-+ * to worry about interrupts or dma.
-+ */
-+static void pxa250_irda_net_uninit(struct net_device *dev)
-+{
-+ struct pxa250_irda *si = dev->priv;
-+
-+ dev->hard_start_xmit = NULL;
-+ dev->open = NULL;
-+ dev->stop = NULL;
-+ dev->do_ioctl = NULL;
-+ dev->get_stats = NULL;
-+ dev->priv = NULL;
-+
-+ pm_unregister(si->pmdev);
-+
-+ kfree(si->tx_buff.head);
-+ kfree(si->rx_buff.head);
-+ kfree(si);
-+}
-+
-+static int __init pxa250_irda_init(void)
-+{
-+ struct net_device *dev;
-+ int err;
-+
-+ /* STUART */
-+ err = request_mem_region(__PREG(STRBR), 0x24, "IrDA") ? 0 : -EBUSY;
-+ if (err)
-+ goto err_mem_1;
-+
-+ /* FIR */
-+ err = request_mem_region(__PREG(ICCR0), 0x1c, "IrDA") ? 0 : -EBUSY;
-+ if (err)
-+ goto err_mem_2;
-+
-+
-+ rtnl_lock();
-+ dev = dev_alloc("irda%d", &err);
-+ if (dev) {
-+ dev->irq = IRQ_STUART;
-+ dev->init = pxa250_irda_net_init;
-+ dev->uninit = pxa250_irda_net_uninit;
-+
-+ err = register_netdevice(dev);
-+
-+ if (err)
-+ kfree(dev);
-+ else
-+ netdev = dev;
-+ }
-+ rtnl_unlock();
-+
-+ if (err) {
-+ release_mem_region(__PREG(ICCR0), 0x1c);
-+err_mem_2:
-+ release_mem_region(__PREG(STRBR), 0x24);
-+ }
-+err_mem_1:
-+ return err;
-+}
-+
-+static void __exit pxa250_irda_exit(void)
-+{
-+ struct net_device *dev = netdev;
-+
-+ netdev = NULL;
-+ if (dev) {
-+ rtnl_lock();
-+ unregister_netdevice(dev);
-+ rtnl_unlock();
-+ }
-+
-+ release_mem_region(__PREG(ICCR0), 0x1c);
-+
-+ release_mem_region(__PREG(STRBR), 0x24);
-+
-+ /*
-+ * We now know that the netdevice is no longer in use, and all
-+ * references to our driver have been removed. The only structure
-+ * which may still be present is the netdevice, which will get
-+ * cleaned up by net/core/dev.c
-+ */
-+}
-+
-+module_init(pxa250_irda_init);
-+module_exit(pxa250_irda_exit);
-+
-+MODULE_AUTHOR("Alexey Lugovskoy Frasenyak Dmitrij");
-+MODULE_DESCRIPTION("PXA250 SIR/FIR");
-+MODULE_LICENSE("GPL");
-+EXPORT_NO_SYMBOLS;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/net/smc91x.c 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,2123 @@
-+/*------------------------------------------------------------------------
-+ . smc91x.c
-+ . This is a driver for SMSC's 91C9x/91C1xx single-chip Ethernet devices.
-+ .
-+ . Copyright (C) 1996 by Erik Stahlman
-+ . Copyright (C) 2001 Standard Microsystems Corporation
-+ . Developed by Simple Network Magic Corporation
-+ . Copyright (C) 2003 Monta Vista Software, Inc.
-+ . Unified SMC91x driver by Nicolas Pitre
-+ .
-+ . 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ .
-+ . Arguments:
-+ . io = for the base address
-+ . irq = for the IRQ
-+ . nowait = 0 for normal wait states, 1 eliminates additional wait states
-+ .
-+ . original author:
-+ . Erik Stahlman <erik@vt.edu>
-+ .
-+ . hardware multicast code:
-+ . Peter Cammaert <pc@denkart.be>
-+ .
-+ . contributors:
-+ . Daris A Nevil <dnevil@snmc.com>
-+ . Nicolas Pitre <nico@cam.org>
-+ .
-+ . History:
-+ . 08/20/00 Arnaldo Melo fix kfree(skb) in smc_hardware_send_packet
-+ . 12/15/00 Christian Jullien fix "Warning: kfree_skb on hard IRQ"
-+ . 03/16/01 Daris A Nevil modified smc9194.c for use with LAN91C111
-+ . 08/22/01 Scott Anderson merge changes from smc9194 to smc91111
-+ . 08/21/01 Pramod B Bhardwaj added support for RevB of LAN91C111
-+ . 12/20/01 Jeff Sutherland initial port to Xscale PXA with DMA support
-+ . 04/07/03 Nicolas Pitre unified SMC91x driver, killed irq races,
-+ . more bus abstraction, big cleanup, etc.
-+ ----------------------------------------------------------------------------*/
-+
-+static const char version[] =
-+ "smc91x.c: v1.0, mar 07 2003 by Nicolas Pitre <nico@cam.org>\n";
-+
-+/* Debugging level */
-+#ifndef SMC_DEBUG
-+#define SMC_DEBUG 0
-+#endif
-+
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/delay.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/ioport.h>
-+
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+#ifdef CONFIG_PM
-+#include <linux/pm.h>
-+#endif
-+
-+#include <asm/io.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+
-+#include "smc91x.h"
-+
-+
-+#ifdef CONFIG_ISA
-+/*
-+ . the LAN91C111 can be at any of the following port addresses. To change,
-+ . for a slightly different card, you can add it to the array. Keep in
-+ . mind that the array must end in zero.
-+*/
-+static unsigned int smc_portlist[] __initdata = {
-+ 0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
-+ 0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0, 0
-+};
-+#endif /* CONFIG_ISA */
-+
-+#ifndef SMC_IOADDR
-+# define SMC_IOADDR -1
-+#endif
-+static int io = SMC_IOADDR;
-+
-+#ifndef SMC_IRQ
-+# define SMC_IRQ -1
-+#endif
-+static int irq = SMC_IRQ;
-+
-+#ifndef SMC_NOWAIT
-+# define SMC_NOWAIT 0
-+#endif
-+static int nowait = SMC_NOWAIT;
-+
-+MODULE_PARM(io, "i");
-+MODULE_PARM(irq, "i");
-+MODULE_PARM(nowait, "i");
-+MODULE_PARM_DESC(io, "I/O base address");
-+MODULE_PARM_DESC(irq, "IRQ number");
-+MODULE_PARM_DESC(nowait, "set to 1 for no wait state");
-+
-+
-+/*------------------------------------------------------------------------
-+ .
-+ . The internal workings of the driver. If you are changing anything
-+ . here with the SMC stuff, you should have the datasheet and know
-+ . what you are doing.
-+ .
-+ -------------------------------------------------------------------------*/
-+#define CARDNAME "LAN91x"
-+
-+// Use power-down feature of the chip
-+#define POWER_DOWN 1
-+
-+/*
-+ . Wait time for memory to be free. This probably shouldn't be
-+ . tuned that much, as waiting for this means nothing else happens
-+ . in the system
-+*/
-+#define MEMORY_WAIT_TIME 16
-+
-+/*
-+ . This selects whether TX packets are sent one by one to the SMC91x internal
-+ . memory ans throttled until transmission completes. This may prevent
-+ . RX overruns a litle by keeping much of the memory free for RX packets
-+ . but to the expense of reduced TX throughput and increased IRQ overhead.
-+ . Note this is not a cure for a too slow data bus or too high IRQ latency.
-+ */
-+#define THROTTLE_TX_PKTS 0
-+
-+
-+/* store this information for the driver.. */
-+struct smc_local {
-+
-+ // If I have to wait until memory is available to send
-+ // a packet, I will store the skbuff here, until I get the
-+ // desired memory. Then, I'll send it out and free it.
-+ struct sk_buff *saved_skb;
-+
-+ // these are things that the kernel wants me to keep, so users
-+ // can find out semi-useless statistics of how well the card is
-+ // performing
-+ struct net_device_stats stats;
-+
-+ // version/revision of the SMC91x chip
-+ int version;
-+
-+ // Set to true during the auto-negotiation sequence
-+ int autoneg_active;
-+
-+ // Address of our PHY port
-+ int phyaddr;
-+
-+ // Type of PHY
-+ int phytype;
-+
-+ // Last contents of PHY Register 18
-+ int lastPhy18;
-+
-+ // Contains the current active transmission mode
-+ int tcr_cur_mode;
-+
-+ // Contains the current active receive mode
-+ int rcr_cur_mode;
-+
-+ // Contains the current active receive/phy mode
-+ int rpc_cur_mode;
-+ int ctl_autoneg;
-+ int ctl_rfduplx;
-+ int ctl_rspeed;
-+
-+#ifdef CONFIG_PM
-+ struct pm_dev* pm;
-+#endif
-+
-+};
-+
-+
-+#if SMC_DEBUG > 2
-+#define PRINTK3(args...) printk(args)
-+#else
-+#define PRINTK3(args...) do { } while(0)
-+#endif
-+
-+#if SMC_DEBUG > 1
-+#define PRINTK2(args...) printk(args)
-+#else
-+#define PRINTK2(args...) do { } while(0)
-+#endif
-+
-+#if SMC_DEBUG > 0
-+#define PRINTK1(args...) printk(args)
-+#define PRINTK(args...) printk(args)
-+#else
-+#define PRINTK1(args...) do { } while(0)
-+#define PRINTK(args...) printk(KERN_DEBUG args)
-+#endif
-+
-+#if SMC_DEBUG > 3
-+static void PRINT_PKT(u_char *buf, int length)
-+{
-+ int i;
-+ int remainder;
-+ int lines;
-+
-+ lines = length / 16;
-+ remainder = length % 16;
-+
-+ for (i = 0; i < lines ; i ++) {
-+ int cur;
-+ for (cur = 0; cur < 8; cur++) {
-+ u_char a, b;
-+ a = *buf++;
-+ b = *buf++;
-+ printk("%02x%02x ", a, b);
-+ }
-+ printk("\n");
-+ }
-+ for (i = 0; i < remainder/2 ; i++) {
-+ u_char a, b;
-+ a = *buf++;
-+ b = *buf++;
-+ printk("%02x%02x ", a, b );
-+ }
-+ printk("\n");
-+}
-+#else
-+#define PRINT_PKT(x...) do { } while(0)
-+#endif
-+
-+
-+/* this enables an interrupt in the interrupt mask register */
-+#define SMC_ENABLE_INT(x) do { \
-+ unsigned long flags; \
-+ unsigned char mask; \
-+ local_irq_save(flags); \
-+ mask = SMC_GET_INT_MASK(); \
-+ mask |= (x); \
-+ SMC_SET_INT_MASK(mask); \
-+ local_irq_restore(flags); \
-+} while (0)
-+
-+/* this disables an interrupt from the interrupt mask register */
-+#define SMC_DISABLE_INT(x) do { \
-+ unsigned long flags; \
-+ unsigned char mask; \
-+ local_irq_save(flags); \
-+ mask = SMC_GET_INT_MASK(); \
-+ mask &= ~(x); \
-+ SMC_SET_INT_MASK(mask); \
-+ local_irq_restore(flags); \
-+} while (0)
-+
-+/* wait while MMU is busy */
-+#define SMC_WAIT_MMU_BUSY() do { \
-+ if (unlikely(SMC_GET_MMU_CMD() & MC_BUSY)) { \
-+ unsigned long timeout = jiffies + 2; \
-+ while (SMC_GET_MMU_CMD() & MC_BUSY) { \
-+ if (time_after(jiffies, timeout)) { \
-+ printk("%s: timeout %s line %d\n", \
-+ dev->name, __FILE__, __LINE__); \
-+ break; \
-+ } \
-+ } \
-+ } \
-+} while (0)
-+
-+
-+/* this does a soft reset on the device */
-+static void
-+smc_reset(struct net_device *dev)
-+{
-+ unsigned long ioaddr = dev->base_addr;
-+ struct smc_local *lp = (struct smc_local *)dev->priv;
-+ int phyaddr = lp->phyaddr;
-+ int status;
-+ PRINTK2("%s: %s\n", dev->name, __FUNCTION__);
-+
-+ /* This resets the registers mostly to defaults, but doesn't
-+ affect EEPROM. That seems unnecessary */
-+ SMC_SELECT_BANK( 0 );
-+ SMC_SET_RCR( RCR_SOFTRST );
-+
-+ /* Setup the Configuration Register */
-+ /* This is necessary because the CONFIG_REG is not affected */
-+ /* by a soft reset */
-+ SMC_SELECT_BANK( 1 );
-+ SMC_SET_CONFIG( CONFIG_DEFAULT );
-+
-+ /* Setup for fast accesses if requested */
-+ /* If the card/system can't handle it then there will */
-+ /* be no recovery except for a hard reset or power cycle */
-+ if (nowait)
-+ SMC_SET_CONFIG( SMC_GET_CONFIG() | CONFIG_NO_WAIT );
-+
-+#ifdef POWER_DOWN
-+ /* Release from possible power-down state */
-+ /* Configuration register is not affected by Soft Reset */
-+ SMC_SELECT_BANK( 1 );
-+ SMC_SET_CONFIG( SMC_GET_CONFIG() | CONFIG_EPH_POWER_EN );
-+ status = smc_read_phy_register(ioaddr, phyaddr, PHY_CNTL_REG);
-+ status &= ~PHY_CNTL_PDN;
-+ smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG);
-+#endif
-+
-+ /* this should pause enough for the chip to be happy */
-+ udelay(1);
-+
-+ /* Disable transmit and receive functionality */
-+ SMC_SELECT_BANK( 0 );
-+ SMC_SET_RCR( RCR_CLEAR );
-+ SMC_SET_TCR( TCR_CLEAR );
-+
-+ /* set the control register to automatically
-+ release successfully transmitted packets, to make the best
-+ use out of our limited memory */
-+ SMC_SELECT_BANK( 1 );
-+#if ! THROTTLE_TX_PKTS
-+ SMC_SET_CTL( SMC_GET_CTL() | CTL_AUTO_RELEASE );
-+#else
-+ SMC_SET_CTL( SMC_GET_CTL() & ~CTL_AUTO_RELEASE );
-+#endif
-+
-+ /* Disable all interrupts */
-+ SMC_SELECT_BANK( 2 );
-+ SMC_SET_INT_MASK( 0 );
-+
-+ /* Reset the MMU */
-+ SMC_SET_MMU_CMD( MC_RESET );
-+ SMC_WAIT_MMU_BUSY();
-+}
-+
-+/* Enable Interrupts, Receive, and Transmit */
-+static void
-+smc_enable(struct net_device *dev)
-+{
-+ unsigned long ioaddr = dev->base_addr;
-+ struct smc_local *lp = (struct smc_local *)dev->priv;
-+ int mask;
-+
-+ PRINTK2("%s: %s\n", dev->name, __FUNCTION__);
-+
-+ /* see the header file for options in TCR/RCR DEFAULT*/
-+ SMC_SELECT_BANK( 0 );
-+ SMC_SET_TCR( lp->tcr_cur_mode );
-+ SMC_SET_RCR( lp->rcr_cur_mode );
-+
-+ /* now, enable interrupts */
-+ mask = IM_EPH_INT|IM_RX_OVRN_INT|IM_RCV_INT;
-+ if (lp->version >= 0x70)
-+ mask |= IM_MDINT;
-+ SMC_SELECT_BANK( 2 );
-+ SMC_SET_INT_MASK( mask );
-+}
-+
-+/* this puts the device in an inactive state */
-+static void
-+smc_shutdown(struct net_device *dev)
-+{
-+ int ioaddr = dev->base_addr;
-+ struct smc_local *lp = (struct smc_local *)dev->priv;
-+ int phyaddr = lp->phyaddr;
-+ int status;
-+
-+ PRINTK2("%s: %s\n", CARDNAME, __FUNCTION__);
-+
-+ /* no more interrupts for me */
-+ SMC_SELECT_BANK( 2 );
-+ SMC_SET_INT_MASK( 0 );
-+
-+ /* and tell the card to stay away from that nasty outside world */
-+ SMC_SELECT_BANK( 0 );
-+ SMC_SET_RCR( RCR_CLEAR );
-+ SMC_SET_TCR( TCR_CLEAR );
-+
-+#ifdef POWER_DOWN
-+ status = smc_read_phy_register(ioaddr, phyaddr, PHY_CNTL_REG);
-+ status |= PHY_CNTL_PDN;
-+ smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG);
-+
-+ /* finally, shut the chip down */
-+ SMC_SELECT_BANK( 1 );
-+ SMC_SET_CONFIG( SMC_GET_CONFIG() & ~CONFIG_EPH_POWER_EN );
-+#endif
-+}
-+
-+/* This is the procedure to handle the receipt of a packet. */
-+static inline void
-+smc_rcv(struct net_device *dev)
-+{
-+ struct smc_local *lp = (struct smc_local *)dev->priv;
-+ unsigned long ioaddr = dev->base_addr;
-+ unsigned int packet_number, status, packet_len;
-+
-+ PRINTK3("%s: %s\n", dev->name, __FUNCTION__);
-+
-+ packet_number = SMC_GET_RXFIFO();
-+ if (unlikely(packet_number & RXFIFO_REMPTY)) {
-+ PRINTK("%s: smc_rcv with nothing on FIFO.\n", dev->name);
-+ return;
-+ }
-+
-+ /* read from start of packet */
-+ SMC_SET_PTR( PTR_READ | PTR_RCV | PTR_AUTOINC );
-+
-+ /* First two words are status and packet length */
-+ SMC_GET_PKT_HDR(status, packet_len);
-+ packet_len &= 0x07ff; /* mask off top bits */
-+ PRINTK2("%s: RX PNR 0x%x STATUS 0x%04x LENGTH 0x%04x (%d)\n",
-+ dev->name, packet_number, status,
-+ packet_len, packet_len);
-+
-+ if (unlikely(status & RS_ERRORS)) {
-+ lp->stats.rx_errors++;
-+ if (status & RS_ALGNERR)
-+ lp->stats.rx_frame_errors++;
-+ if (status & (RS_TOOSHORT | RS_TOOLONG))
-+ lp->stats.rx_length_errors++;
-+ if (status & RS_BADCRC)
-+ lp->stats.rx_crc_errors++;
-+ } else {
-+ struct sk_buff *skb;
-+ unsigned char *data;
-+ unsigned int data_len;
-+
-+ /* set multicast stats */
-+ if (status & RS_MULTICAST)
-+ lp->stats.multicast++;
-+
-+ /*
-+ * Actual payload is packet_len - 4 (or 3 if odd byte).
-+ * We want skb_reserve(2) and the final ctrl word
-+ * (2 bytes, possibly containing the payload odd byte).
-+ * Ence packet_len - 4 + 2 + 2.
-+ */
-+ skb = dev_alloc_skb(packet_len);
-+ if (unlikely(skb == NULL)) {
-+ printk(KERN_NOTICE "%s: Low memory, packet dropped.\n",
-+ dev->name);
-+ lp->stats.rx_dropped++;
-+ goto done;
-+ }
-+
-+ /* Align IP header to 32 bits */
-+ skb_reserve(skb, 2);
-+
-+ /* BUG: the LAN91C111 rev A never sets this bit. Force it. */
-+ if (lp->version == 0x90)
-+ status |= RS_ODDFRAME;
-+
-+ /*
-+ * If odd length: packet_len - 3,
-+ * otherwise packet_len - 4.
-+ */
-+ data_len = packet_len - ((status & RS_ODDFRAME) ? 3 : 4);
-+ data = skb_put(skb, data_len);
-+ SMC_PULL_DATA(data, packet_len - 2);
-+
-+ PRINT_PKT(data, packet_len - 2);
-+
-+ dev->last_rx = jiffies;
-+ skb->dev = dev;
-+ skb->protocol = eth_type_trans(skb, dev);
-+ netif_rx(skb);
-+ lp->stats.rx_packets++;
-+ lp->stats.rx_bytes += data_len;
-+ }
-+
-+done:
-+ SMC_WAIT_MMU_BUSY();
-+ SMC_SET_MMU_CMD( MC_RELEASE );
-+}
-+
-+/*
-+ * This is called to actually send a packet to the chip.
-+ * Returns non-zero when successful.
-+ */
-+static void
-+smc_hardware_send_packet(struct net_device *dev)
-+{
-+ struct smc_local *lp = (struct smc_local *)dev->priv;
-+ unsigned long ioaddr = dev->base_addr;
-+ struct sk_buff *skb = lp->saved_skb;
-+ unsigned int packet_no, len;
-+ unsigned char *buf;
-+
-+ PRINTK3("%s: %s\n", dev->name, __FUNCTION__);
-+
-+ if (unlikely(!skb)) {
-+ printk ("%s: In XMIT with no packet to send\n", dev->name);
-+ return;
-+ }
-+
-+ packet_no = SMC_GET_AR();
-+ if (unlikely(packet_no & AR_FAILED)) {
-+ printk("%s: Memory allocation failed.\n", dev->name);
-+ lp->saved_skb = NULL;
-+ lp->stats.tx_errors++;
-+ lp->stats.tx_fifo_errors++;
-+ dev_kfree_skb_any(skb);
-+ return;
-+ }
-+
-+ /* point to the beginning of the packet */
-+ SMC_SET_PN( packet_no );
-+ SMC_SET_PTR( PTR_AUTOINC );
-+
-+ buf = skb->data;
-+ len = skb->len;
-+ PRINTK2("%s: TX PNR 0x%x lENGTH 0x%04x (%d) BUF 9x%p\n",
-+ dev->name, packet_no, len, len, buf);
-+ PRINT_PKT(buf, len);
-+
-+ /*
-+ * Send the packet length ( +6 for status words, length, and ctl.
-+ * The card will pad to 64 bytes with zeroes if packet is too small.
-+ */
-+ SMC_PUT_PKT_HDR(0, len + 6);
-+
-+ /* send the actual data */
-+ SMC_PUSH_DATA(buf, len & ~1);
-+
-+ /* Send final ctl word with the last byte if there is one */
-+ SMC_outw( ((len & 1) ? (0x2000 | buf[len-1]) : 0), ioaddr, DATA_REG );
-+
-+ /* and let the chipset deal with it */
-+ SMC_SET_MMU_CMD( MC_ENQUEUE );
-+ SMC_ACK_INT( IM_TX_EMPTY_INT );
-+
-+ dev->trans_start = jiffies;
-+ dev_kfree_skb_any(skb);
-+ lp->saved_skb = NULL;
-+ lp->stats.tx_packets++;
-+ lp->stats.tx_bytes += len;
-+}
-+
-+/*
-+ . Since I am not sure if I will have enough room in the chip's ram
-+ . to store the packet, I call this routine which either sends it
-+ . now, or set the card to generates an interrupt when ready
-+ . for the packet.
-+ */
-+static int
-+smc_hard_start_xmit( struct sk_buff * skb, struct net_device * dev )
-+{
-+ struct smc_local *lp = (struct smc_local *)dev->priv;
-+ unsigned long ioaddr = dev->base_addr;
-+ unsigned int numPages, poll_count, status, saved_bank;
-+
-+ PRINTK3("%s: %s\n", dev->name, __FUNCTION__);
-+
-+ if (unlikely(lp->saved_skb != NULL)) {
-+ /* THIS SHOULD NEVER HAPPEN. */
-+ printk( KERN_CRIT
-+ "%s: Bad Craziness - sent packet while busy.\n",
-+ dev->name );
-+ lp->stats.tx_errors++;
-+ lp->stats.tx_aborted_errors++;
-+ return 1;
-+ }
-+ lp->saved_skb = skb;
-+
-+ /*
-+ ** The MMU wants the number of pages to be the number of 256 bytes
-+ ** 'pages', minus 1 ( since a packet can't ever have 0 pages :) )
-+ **
-+ ** The 91C111 ignores the size bits, but the code is left intact
-+ ** for backwards and future compatibility.
-+ **
-+ ** Pkt size for allocating is data length +6 (for additional status
-+ ** words, length and ctl!)
-+ **
-+ ** If odd size then last byte is included in ctl word.
-+ */
-+ numPages = ((skb->len & ~1) + (6 - 1)) >> 8;
-+ if (unlikely(numPages > 7)) {
-+ printk("%s: Far too big packet error.\n", dev->name);
-+ lp->saved_skb = NULL;
-+ lp->stats.tx_errors++;
-+ lp->stats.tx_dropped++;
-+ dev_kfree_skb(skb);
-+ return 0;
-+ }
-+
-+ /* now, try to allocate the memory */
-+ saved_bank = SMC_CURRENT_BANK();
-+ SMC_SELECT_BANK( 2 );
-+ SMC_SET_MMU_CMD( MC_ALLOC | numPages );
-+
-+ /*
-+ * Poll the chip for a short amount of time in case the
-+ * allocation succeeds quickly.
-+ */
-+ poll_count = MEMORY_WAIT_TIME;
-+ do {
-+ status = SMC_GET_INT();
-+ if (status & IM_ALLOC_INT) {
-+ SMC_ACK_INT( IM_ALLOC_INT );
-+ break;
-+ }
-+ } while (--poll_count);
-+
-+ if (!poll_count) {
-+ /* oh well, wait until the chip finds memory later */
-+ netif_stop_queue(dev);
-+ PRINTK2("%s: TX memory allocation deferred.\n", dev->name);
-+ SMC_ENABLE_INT( IM_ALLOC_INT );
-+ } else {
-+ /* Send current packet immediately.. */
-+#if THROTTLE_TX_PKTS
-+ netif_stop_queue(dev);
-+#endif
-+ smc_hardware_send_packet(dev);
-+ SMC_ENABLE_INT( IM_TX_INT | IM_TX_EMPTY_INT );
-+ }
-+
-+ SMC_SELECT_BANK( saved_bank );
-+ return 0;
-+}
-+
-+/*
-+ . This handles a TX interrupt, which is only called when an error
-+ . relating to a packet is sent or CTL_AUTO_RELEASE is not set.
-+*/
-+static void
-+smc_tx(struct net_device *dev)
-+{
-+ unsigned long ioaddr = dev->base_addr;
-+ struct smc_local *lp = (struct smc_local *)dev->priv;
-+ unsigned int saved_packet, packet_no, tx_status, pkt_len;
-+
-+ PRINTK3("%s: %s\n", dev->name, __FUNCTION__);
-+
-+ /* If the TX FIFO is empty then nothing to do */
-+ packet_no = SMC_GET_TXFIFO();
-+ if (unlikely(packet_no & TXFIFO_TEMPTY)) {
-+ PRINTK("%s: smc_tx with nothing on FIFO.\n", dev->name);
-+ return;
-+ }
-+
-+ /* select packet to read from */
-+ saved_packet = SMC_GET_PN();
-+ SMC_SET_PN( packet_no );
-+
-+ /* read the first word (status word) from this packet */
-+ SMC_SET_PTR( PTR_AUTOINC | PTR_READ );
-+ SMC_GET_PKT_HDR(tx_status, pkt_len);
-+ PRINTK2("%s: TX STATUS 0x%04x PNR 0x%02x\n",
-+ dev->name, tx_status, packet_no);
-+
-+ if (!(tx_status & TS_SUCCESS))
-+ lp->stats.tx_errors++;
-+ if (tx_status & TS_LOSTCAR)
-+ lp->stats.tx_carrier_errors++;
-+ if (tx_status & TS_LATCOL) {
-+ printk( KERN_DEBUG
-+ "%s: Late collision occurred on last xmit.\n",
-+ dev->name);
-+ lp->stats.tx_window_errors++;
-+ }
-+
-+ /* kill the packet */
-+ SMC_WAIT_MMU_BUSY();
-+ SMC_SET_MMU_CMD( MC_FREEPKT );
-+
-+ /* Don't restore Packet Number Reg until busy bit is cleared */
-+ SMC_WAIT_MMU_BUSY();
-+ SMC_SET_PN( saved_packet );
-+
-+ /* re-enable transmit */
-+ SMC_SELECT_BANK( 0 );
-+ SMC_SET_TCR( lp->tcr_cur_mode );
-+ SMC_SELECT_BANK( 2 );
-+}
-+
-+
-+//---PHY CONTROL AND CONFIGURATION-----------------------------------------
-+
-+/*------------------------------------------------------------
-+ . Debugging function for viewing MII Management serial bitstream
-+ .-------------------------------------------------------------*/
-+#if SMC_DEBUG > 3
-+static void
-+PRINT_MII_STREAM(u_char *bits, int size)
-+{
-+ int i;
-+
-+ printk("BIT#:");
-+ for (i = 0; i < size; ++i)
-+ printk("%d", i%10);
-+
-+ printk("\nMDOE:");
-+ for (i = 0; i < size; ++i) {
-+ if (bits[i] & MII_MDOE)
-+ printk("1");
-+ else
-+ printk("0");
-+ }
-+
-+ printk("\nMDO :");
-+ for (i = 0; i < size; ++i) {
-+ if (bits[i] & MII_MDO)
-+ printk("1");
-+ else
-+ printk("0");
-+ }
-+
-+ printk("\nMDI :");
-+ for (i = 0; i < size; ++i) {
-+ if (bits[i] & MII_MDI)
-+ printk("1");
-+ else
-+ printk("0");
-+ }
-+
-+ printk("\n");
-+}
-+#else
-+#define PRINT_MII_STREAM(x...)
-+#endif
-+
-+/*------------------------------------------------------------
-+ . Reads a register from the MII Management serial interface
-+ .-------------------------------------------------------------*/
-+static int
-+smc_read_phy_register(unsigned long ioaddr, int phyaddr, int phyreg)
-+{
-+ int oldBank;
-+ int i, mask, mii_reg;
-+ u_char bits[64];
-+ int input_idx, phydata;
-+ int clk_idx = 0;
-+
-+ // 32 consecutive ones on MDO to establish sync
-+ for (i = 0; i < 32; ++i)
-+ bits[clk_idx++] = MII_MDOE | MII_MDO;
-+
-+ // Start code <01>
-+ bits[clk_idx++] = MII_MDOE;
-+ bits[clk_idx++] = MII_MDOE | MII_MDO;
-+
-+ // Read command <10>
-+ bits[clk_idx++] = MII_MDOE | MII_MDO;
-+ bits[clk_idx++] = MII_MDOE;
-+
-+ // Output the PHY address, msb first
-+ mask = 0x10;
-+ for (i = 0; i < 5; ++i) {
-+ if (phyaddr & mask)
-+ bits[clk_idx++] = MII_MDOE | MII_MDO;
-+ else
-+ bits[clk_idx++] = MII_MDOE;
-+
-+ // Shift to next lowest bit
-+ mask >>= 1;
-+ }
-+
-+ // Output the phy register number, msb first
-+ mask = 0x10;
-+ for (i = 0; i < 5; ++i) {
-+ if (phyreg & mask)
-+ bits[clk_idx++] = MII_MDOE | MII_MDO;
-+ else
-+ bits[clk_idx++] = MII_MDOE;
-+
-+ // Shift to next lowest bit
-+ mask >>= 1;
-+ }
-+
-+ // Tristate and turnaround (2 bit times)
-+ bits[clk_idx++] = 0;
-+ //bits[clk_idx++] = 0;
-+
-+ // Input starts at this bit time
-+ input_idx = clk_idx;
-+
-+ // Will input 16 bits
-+ for (i = 0; i < 16; ++i)
-+ bits[clk_idx++] = 0;
-+
-+ // Final clock bit
-+ bits[clk_idx++] = 0;
-+
-+ // Save the current bank
-+ oldBank = SMC_CURRENT_BANK();
-+
-+ // Select bank 3
-+ SMC_SELECT_BANK( 3 );
-+
-+ // Get the current MII register value
-+ mii_reg = SMC_GET_MII();
-+
-+ // Turn off all MII Interface bits
-+ mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO);
-+
-+ // Clock all 64 cycles
-+ for (i = 0; i < sizeof bits; ++i) {
-+ // Clock Low - output data
-+ SMC_SET_MII( mii_reg | bits[i] );
-+ udelay(50);
-+
-+ // Clock Hi - input data
-+ SMC_SET_MII( mii_reg | bits[i] | MII_MCLK );
-+ udelay(50);
-+ bits[i] |= SMC_GET_MII() & MII_MDI;
-+ }
-+
-+ // Return to idle state
-+ // Set clock to low, data to low, and output tristated
-+ SMC_SET_MII( mii_reg );
-+ udelay(50);
-+
-+ // Restore original bank select
-+ SMC_SELECT_BANK( oldBank );
-+
-+ // Recover input data
-+ phydata = 0;
-+ for (i = 0; i < 16; ++i) {
-+ phydata <<= 1;
-+
-+ if (bits[input_idx++] & MII_MDI)
-+ phydata |= 0x0001;
-+ }
-+
-+ PRINTK3("%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
-+ __FUNCTION__, phyaddr, phyreg, phydata);
-+ PRINT_MII_STREAM(bits, sizeof(bits));
-+
-+ return phydata;
-+}
-+
-+/*------------------------------------------------------------
-+ . Writes a register to the MII Management serial interface
-+ .-------------------------------------------------------------*/
-+static void
-+smc_write_phy_register( unsigned long ioaddr, int phyaddr,
-+ int phyreg, int phydata )
-+{
-+ int oldBank;
-+ int i, mask, mii_reg;
-+ u_char bits[65];
-+ int clk_idx = 0;
-+
-+ // 32 consecutive ones on MDO to establish sync
-+ for (i = 0; i < 32; ++i)
-+ bits[clk_idx++] = MII_MDOE | MII_MDO;
-+
-+ // Start code <01>
-+ bits[clk_idx++] = MII_MDOE;
-+ bits[clk_idx++] = MII_MDOE | MII_MDO;
-+
-+ // Write command <01>
-+ bits[clk_idx++] = MII_MDOE;
-+ bits[clk_idx++] = MII_MDOE | MII_MDO;
-+
-+ // Output the PHY address, msb first
-+ mask = 0x10;
-+ for (i = 0; i < 5; ++i) {
-+ if (phyaddr & mask)
-+ bits[clk_idx++] = MII_MDOE | MII_MDO;
-+ else
-+ bits[clk_idx++] = MII_MDOE;
-+
-+ // Shift to next lowest bit
-+ mask >>= 1;
-+ }
-+
-+ // Output the phy register number, msb first
-+ mask = 0x10;
-+ for (i = 0; i < 5; ++i) {
-+ if (phyreg & mask)
-+ bits[clk_idx++] = MII_MDOE | MII_MDO;
-+ else
-+ bits[clk_idx++] = MII_MDOE;
-+
-+ // Shift to next lowest bit
-+ mask >>= 1;
-+ }
-+
-+ // Tristate and turnaround (2 bit times)
-+ bits[clk_idx++] = 0;
-+ bits[clk_idx++] = 0;
-+
-+ // Write out 16 bits of data, msb first
-+ mask = 0x8000;
-+ for (i = 0; i < 16; ++i) {
-+ if (phydata & mask)
-+ bits[clk_idx++] = MII_MDOE | MII_MDO;
-+ else
-+ bits[clk_idx++] = MII_MDOE;
-+
-+ // Shift to next lowest bit
-+ mask >>= 1;
-+ }
-+
-+ // Final clock bit (tristate)
-+ bits[clk_idx++] = 0;
-+
-+ // Save the current bank
-+ oldBank = SMC_CURRENT_BANK();
-+
-+ // Select bank 3
-+ SMC_SELECT_BANK( 3 );
-+
-+ // Get the current MII register value
-+ mii_reg = SMC_GET_MII();
-+
-+ // Turn off all MII Interface bits
-+ mii_reg &= ~(MII_MDOE|MII_MCLK|MII_MDI|MII_MDO);
-+
-+ // Clock all cycles
-+ for (i = 0; i < sizeof bits; ++i) {
-+ // Clock Low - output data
-+ SMC_SET_MII( mii_reg | bits[i] );
-+ udelay(50);
-+
-+ // Clock Hi - input data
-+ SMC_SET_MII( mii_reg | bits[i] | MII_MCLK );
-+ udelay(50);
-+ bits[i] |= SMC_GET_MII() & MII_MDI;
-+ }
-+
-+ // Return to idle state
-+ // Set clock to low, data to low, and output tristated
-+ SMC_SET_MII( mii_reg );
-+ udelay(50);
-+
-+ // Restore original bank select
-+ SMC_SELECT_BANK( oldBank );
-+
-+ PRINTK3("%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n",
-+ __FUNCTION__, phyaddr, phyreg, phydata);
-+ PRINT_MII_STREAM(bits, sizeof(bits));
-+}
-+
-+
-+/*------------------------------------------------------------
-+ . Finds and reports the PHY address
-+ .-------------------------------------------------------------*/
-+static int smc_detect_phy(struct net_device* dev)
-+{
-+ struct smc_local *lp = (struct smc_local *)dev->priv;
-+ unsigned long ioaddr = dev->base_addr;
-+ int phy_id1, phy_id2;
-+ int phyaddr;
-+ int found = 0;
-+
-+ PRINTK2("%s: %s\n", dev->name, __FUNCTION__);
-+
-+ // Scan all 32 PHY addresses if necessary
-+ for (phyaddr = 0; phyaddr < 32; ++phyaddr) {
-+ // Read the PHY identifiers
-+ phy_id1 = smc_read_phy_register(ioaddr, phyaddr, PHY_ID1_REG);
-+ phy_id2 = smc_read_phy_register(ioaddr, phyaddr, PHY_ID2_REG);
-+
-+ PRINTK3("%s: phy_id1=0x%x, phy_id2=0x%x\n",
-+ dev->name, phy_id1, phy_id2);
-+
-+ // Make sure it is a valid identifier
-+ if ((phy_id2 > 0x0000) && (phy_id2 < 0xffff) &&
-+ (phy_id1 > 0x0000) && (phy_id1 < 0xffff)) {
-+ if ((phy_id1 != 0x8000) && (phy_id2 != 0x8000)) {
-+ // Save the PHY's address
-+ lp->phyaddr = phyaddr;
-+ found = 1;
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (!found) {
-+ PRINTK("%s: No PHY found\n", dev->name);
-+ return(0);
-+ }
-+
-+ // Set the PHY type
-+ if ( (phy_id1 == 0x0016) && ((phy_id2 & 0xFFF0) == 0xF840 ) ) {
-+ lp->phytype = PHY_LAN83C183;
-+ PRINTK("%s: PHY=LAN83C183 (LAN91C111 Internal)\n", dev->name);
-+ }
-+
-+ if ( (phy_id1 == 0x0282) && ((phy_id2 & 0xFFF0) == 0x1C50) ) {
-+ lp->phytype = PHY_LAN83C180;
-+ PRINTK("%s: PHY=LAN83C180\n", dev->name);
-+ }
-+
-+ return 1;
-+}
-+
-+/*------------------------------------------------------------
-+ . Waits the specified number of milliseconds - kernel friendly
-+ .-------------------------------------------------------------*/
-+static void
-+smc_wait_ms(unsigned int ms)
-+{
-+ if (!in_interrupt()) {
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ schedule_timeout(1 + ms * HZ / 1000);
-+ } else {
-+ /* if this happens it must be fixed */
-+ printk( KERN_WARNING "%s: busy wait while in interrupt!\n",
-+ __FUNCTION__);
-+ mdelay(ms);
-+ }
-+}
-+
-+/*------------------------------------------------------------
-+ . Sets the PHY to a configuration as determined by the user
-+ .-------------------------------------------------------------*/
-+static int
-+smc_phy_fixed(struct net_device *dev)
-+{
-+ unsigned long ioaddr = dev->base_addr;
-+ struct smc_local *lp = (struct smc_local *)dev->priv;
-+ int phyaddr = lp->phyaddr;
-+ int my_fixed_caps, cfg1;
-+
-+ PRINTK3("%s: %s\n", dev->name, __FUNCTION__);
-+
-+ // Enter Link Disable state
-+ cfg1 = smc_read_phy_register(ioaddr, phyaddr, PHY_CFG1_REG);
-+ cfg1 |= PHY_CFG1_LNKDIS;
-+ smc_write_phy_register(ioaddr, phyaddr, PHY_CFG1_REG, cfg1);
-+
-+ // Set our fixed capabilities
-+ // Disable auto-negotiation
-+ my_fixed_caps = 0;
-+
-+ if (lp->ctl_rfduplx)
-+ my_fixed_caps |= PHY_CNTL_DPLX;
-+
-+ if (lp->ctl_rspeed == 100)
-+ my_fixed_caps |= PHY_CNTL_SPEED;
-+
-+ // Write our capabilities to the phy control register
-+ smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG, my_fixed_caps);
-+
-+ // Re-Configure the Receive/Phy Control register
-+ SMC_SET_RPC( lp->rpc_cur_mode );
-+
-+ // Success
-+ return(1);
-+}
-+
-+/*------------------------------------------------------------
-+ . Configures the specified PHY through the MII management interface
-+ . using Autonegotiation.
-+ . Calls smc_phy_fixed() if the user has requested a certain config.
-+ .-------------------------------------------------------------*/
-+static void
-+smc_phy_configure(struct net_device* dev)
-+{
-+ unsigned long ioaddr = dev->base_addr;
-+ struct smc_local *lp = (struct smc_local *)dev->priv;
-+ int timeout;
-+ int phyaddr;
-+ int my_phy_caps; // My PHY capabilities
-+ int my_ad_caps; // My Advertised capabilities
-+ int status;
-+
-+ PRINTK3("%s:smc_program_phy()\n", dev->name);
-+
-+ // Set the blocking flag
-+ lp->autoneg_active = 1;
-+
-+ // Find the address and type of our phy
-+ if (!smc_detect_phy(dev))
-+ goto smc_phy_configure_exit;
-+
-+ // Get the detected phy address
-+ phyaddr = lp->phyaddr;
-+
-+ // Reset the PHY, setting all other bits to zero
-+ smc_write_phy_register(ioaddr, phyaddr, PHY_CNTL_REG, PHY_CNTL_RST);
-+
-+ // Wait for the reset to complete, or time out
-+ timeout = 6; // Wait up to 3 seconds
-+ while (timeout--) {
-+ if (!(smc_read_phy_register(ioaddr, phyaddr, PHY_CNTL_REG)
-+ & PHY_CNTL_RST))
-+ // reset complete
-+ break;
-+ smc_wait_ms(500); // wait 500 millisecs
-+ if (signal_pending(current)) { // Exit anyway if signaled
-+ PRINTK("%s: PHY reset interrupted by signal\n",
-+ dev->name);
-+ timeout = 0;
-+ break;
-+ }
-+ }
-+
-+ if (timeout < 1) {
-+ printk("%s: PHY reset timed out\n", dev->name);
-+ goto smc_phy_configure_exit;
-+ }
-+
-+ // Read PHY Register 18, Status Output
-+ lp->lastPhy18 = smc_read_phy_register(ioaddr, phyaddr, PHY_INT_REG);
-+
-+ // Enable PHY Interrupts (for register 18)
-+ // Interrupts listed here are disabled
-+ smc_write_phy_register(ioaddr, phyaddr, PHY_MASK_REG,
-+ PHY_INT_LOSSSYNC | PHY_INT_CWRD | PHY_INT_SSD |
-+ PHY_INT_ESD | PHY_INT_RPOL | PHY_INT_JAB |
-+ PHY_INT_SPDDET | PHY_INT_DPLXDET);
-+
-+ /* Configure the Receive/Phy Control register */
-+ SMC_SELECT_BANK( 0 );
-+ SMC_SET_RPC( lp->rpc_cur_mode );
-+
-+ // Copy our capabilities from PHY_STAT_REG to PHY_AD_REG
-+ my_phy_caps = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG);
-+
-+ // If the user requested no auto neg, then go set his request
-+ if (!(lp->ctl_autoneg)) {
-+ smc_phy_fixed(dev);
-+ goto smc_phy_configure_exit;
-+ }
-+
-+ if( !( my_phy_caps & PHY_STAT_CAP_ANEG))
-+ {
-+ printk(KERN_INFO "Auto negotiation NOT supported\n");
-+ smc_phy_fixed(dev);
-+ goto smc_phy_configure_exit;
-+ }
-+
-+ my_ad_caps = PHY_AD_CSMA; // I am CSMA capable
-+
-+ if (my_phy_caps & PHY_STAT_CAP_T4)
-+ my_ad_caps |= PHY_AD_T4;
-+
-+ if (my_phy_caps & PHY_STAT_CAP_TXF)
-+ my_ad_caps |= PHY_AD_TX_FDX;
-+
-+ if (my_phy_caps & PHY_STAT_CAP_TXH)
-+ my_ad_caps |= PHY_AD_TX_HDX;
-+
-+ if (my_phy_caps & PHY_STAT_CAP_TF)
-+ my_ad_caps |= PHY_AD_10_FDX;
-+
-+ if (my_phy_caps & PHY_STAT_CAP_TH)
-+ my_ad_caps |= PHY_AD_10_HDX;
-+
-+ // Disable capabilities not selected by our user
-+ if (lp->ctl_rspeed != 100)
-+ my_ad_caps &= ~(PHY_AD_T4|PHY_AD_TX_FDX|PHY_AD_TX_HDX);
-+
-+ if (!lp->ctl_rfduplx)
-+ my_ad_caps &= ~(PHY_AD_TX_FDX|PHY_AD_10_FDX);
-+
-+ // Update our Auto-Neg Advertisement Register
-+ smc_write_phy_register(ioaddr, phyaddr, PHY_AD_REG, my_ad_caps);
-+
-+ // Read the register back. Without this, it appears that when
-+ // auto-negotiation is restarted, sometimes it isn't ready and
-+ // the link does not come up.
-+ status = smc_read_phy_register(ioaddr, phyaddr, PHY_AD_REG);
-+
-+ PRINTK2("%s: phy caps=%x\n", dev->name, my_phy_caps);
-+ PRINTK2("%s: phy advertised caps=%x\n", dev->name, my_ad_caps);
-+
-+ // Restart auto-negotiation process in order to advertise my caps
-+ smc_write_phy_register( ioaddr, phyaddr, PHY_CNTL_REG,
-+ PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST );
-+
-+ // Wait for the auto-negotiation to complete. This may take from
-+ // 2 to 3 seconds.
-+ // Wait for the reset to complete, or time out
-+ timeout = 20; // Wait up to 10 seconds
-+ while (timeout--) {
-+ status = smc_read_phy_register(ioaddr, phyaddr, PHY_RMT_REG);
-+ if (status & PHY_AD_ACK)
-+ // auto-negotiate complete
-+ break;
-+
-+ smc_wait_ms(500); // wait 500 millisecs
-+ if (signal_pending(current)) { // Exit anyway if signaled
-+ printk(KERN_DEBUG
-+ "%s: PHY auto-negotiate interrupted by signal\n",
-+ dev->name);
-+ timeout = 0;
-+ break;
-+ }
-+ }
-+ status = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG);
-+
-+ if (timeout < 1) {
-+ PRINTK("%s: PHY auto-negotiate timed out\n", dev->name);
-+ }
-+
-+ // Fail if we detected an auto-negotiate remote fault
-+ if (status & PHY_STAT_REM_FLT) {
-+ PRINTK("%s: PHY remote fault detected\n", dev->name);
-+ }
-+
-+ // Wait for link. Once the link is up, phy18 should be up to date
-+ timeout = 200;
-+ do
-+ {
-+ udelay(100);
-+ status = smc_read_phy_register(ioaddr, phyaddr, PHY_STAT_REG);
-+ } while ( ((status & PHY_STAT_LINK)==0) && --timeout);
-+
-+ if (status & PHY_STAT_LINK)
-+ {
-+ PRINTK("%s: Ethernet Link Detected\n", dev->name);
-+ }
-+
-+ // The smc_phy_interrupt() routine will be called to update lastPhy18
-+
-+ // Set our sysctl parameters to match auto-negotiation results
-+ if ( lp->lastPhy18 & PHY_INT_SPDDET ) {
-+ PRINTK("%s: PHY 100BaseT\n", dev->name);
-+ lp->rpc_cur_mode |= RPC_SPEED;
-+ } else {
-+ PRINTK("%s: PHY 10BaseT\n", dev->name);
-+ lp->rpc_cur_mode &= ~RPC_SPEED;
-+ }
-+
-+ if ( lp->lastPhy18 & PHY_INT_DPLXDET ) {
-+ PRINTK("%s: PHY Full Duplex\n", dev->name);
-+ lp->rpc_cur_mode |= RPC_DPLX;
-+ lp->tcr_cur_mode |= TCR_SWFDUP;
-+ } else {
-+ PRINTK("%s: PHY Half Duplex\n", dev->name);
-+ lp->rpc_cur_mode &= ~RPC_DPLX;
-+ lp->tcr_cur_mode &= ~TCR_SWFDUP;
-+ }
-+
-+ // Re-Configure the Receive/Phy Control register and TCR
-+ SMC_SET_RPC( lp->rpc_cur_mode );
-+ SMC_SET_TCR( lp->tcr_cur_mode );
-+
-+smc_phy_configure_exit:
-+ // Exit auto-negotiation
-+ lp->autoneg_active = 0;
-+}
-+
-+/*************************************************************************
-+ . smc_phy_interrupt
-+ .
-+ . Purpose: Handle interrupts relating to PHY register 18. This is
-+ . called from the "hard" interrupt handler.
-+ .
-+ ************************************************************************/
-+static void
-+smc_phy_interrupt(struct net_device* dev)
-+{
-+ unsigned long ioaddr = dev->base_addr;
-+ struct smc_local *lp = (struct smc_local *)dev->priv;
-+ int phyaddr = lp->phyaddr;
-+ int phy18;
-+
-+ PRINTK2("%s: %s\n", dev->name, __FUNCTION__);
-+
-+ for(;;) {
-+ // Read PHY Register 18, Status Output
-+ phy18 = smc_read_phy_register(ioaddr, phyaddr, PHY_INT_REG);
-+
-+ // Exit if not more changes
-+ if (phy18 == lp->lastPhy18)
-+ break;
-+
-+#if SMC_DEBUG > 1
-+ PRINTK2("%s: phy18=0x%04x\n", dev->name, phy18);
-+ PRINTK2("%s: lastPhy18=0x%04x\n", dev->name, lp->lastPhy18);
-+
-+ // Handle events
-+ if ((phy18 & PHY_INT_LNKFAIL) !=
-+ (lp->lastPhy18 & PHY_INT_LNKFAIL))
-+ PRINTK2("%s: PHY Link Fail=%x\n", dev->name,
-+ phy18 & PHY_INT_LNKFAIL);
-+
-+ if ((phy18 & PHY_INT_LOSSSYNC) !=
-+ (lp->lastPhy18 & PHY_INT_LOSSSYNC))
-+ PRINTK2("%s: PHY LOSS SYNC=%x\n", dev->name,
-+ phy18 & PHY_INT_LOSSSYNC);
-+
-+ if ((phy18 & PHY_INT_CWRD) != (lp->lastPhy18 & PHY_INT_CWRD))
-+ PRINTK2("%s: PHY INVALID 4B5B code=%x\n", dev->name,
-+ phy18 & PHY_INT_CWRD);
-+
-+ if ((phy18 & PHY_INT_SSD) != (lp->lastPhy18 & PHY_INT_SSD))
-+ PRINTK2("%s: PHY No Start Of Stream=%x\n", dev->name,
-+ phy18 & PHY_INT_SSD);
-+
-+ if ((phy18 & PHY_INT_ESD) != (lp->lastPhy18 & PHY_INT_ESD))
-+
-+ PRINTK2("%s: PHY No End Of Stream=%x\n", dev->name,
-+ phy18 & PHY_INT_ESD);
-+
-+ if ((phy18 & PHY_INT_RPOL) != (lp->lastPhy18 & PHY_INT_RPOL))
-+ PRINTK2("%s: PHY Reverse Polarity Detected=%x\n",
-+ dev->name, phy18 & PHY_INT_RPOL);
-+
-+ if ((phy18 & PHY_INT_JAB) != (lp->lastPhy18 & PHY_INT_JAB))
-+ PRINTK2("%s: PHY Jabber Detected=%x\n", dev->name,
-+ phy18 & PHY_INT_JAB);
-+
-+ if ((phy18 & PHY_INT_SPDDET) !=
-+ (lp->lastPhy18 & PHY_INT_SPDDET))
-+ PRINTK2("%s: PHY Speed Detect=%x\n", dev->name,
-+ phy18 & PHY_INT_SPDDET);
-+
-+ if ((phy18 & PHY_INT_DPLXDET) !=
-+ (lp->lastPhy18 & PHY_INT_DPLXDET))
-+ PRINTK2("%s: PHY Duplex Detect=%x\n", dev->name,
-+ phy18 & PHY_INT_DPLXDET);
-+#endif
-+ // Update the last phy 18 variable
-+ lp->lastPhy18 = phy18;
-+ }
-+}
-+
-+//--- END PHY CONTROL AND CONFIGURATION-------------------------------------
-+
-+
-+/*
-+ * This is the main routine of the driver, to handle the device when
-+ * it needs some attention.
-+ */
-+static void
-+smc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct net_device *dev = dev_id;
-+ unsigned long ioaddr = dev->base_addr;
-+ struct smc_local *lp = (struct smc_local *)dev->priv;
-+ int status, mask, timeout, card_stats;
-+ int saved_bank, saved_pointer;
-+
-+ PRINTK3("%s: %s\n", dev->name, __FUNCTION__);
-+
-+ saved_bank = SMC_CURRENT_BANK();
-+ SMC_SELECT_BANK(2);
-+ saved_pointer = SMC_GET_PTR();
-+ mask = SMC_GET_INT_MASK();
-+ SMC_SET_INT_MASK( 0 );
-+
-+ /* set a timeout value, so I don't stay here forever */
-+ timeout = 8;
-+
-+ do {
-+ status = SMC_GET_INT();
-+
-+ PRINTK2("%s: IRQ 0x%02x MASK 0x%02x MEM 0x%04x FIFO 0x%04x\n",
-+ dev->name, status, mask,
-+ ({ int meminfo; SMC_SELECT_BANK(0);
-+ meminfo = SMC_GET_MIR();
-+ SMC_SELECT_BANK(2); meminfo; }),
-+ SMC_GET_FIFO());
-+
-+ status &= mask;
-+ if (!status)
-+ break;
-+
-+ if (status & IM_RCV_INT) {
-+ PRINTK3("%s: RX irq\n", dev->name);
-+ smc_rcv(dev);
-+ } else if (status & IM_TX_INT) {
-+ PRINTK3("%s: TX int\n", dev->name);
-+ smc_tx(dev);
-+ SMC_ACK_INT( IM_TX_INT );
-+#if THROTTLE_TX_PKTS
-+ netif_wake_queue(dev);
-+#endif
-+ } else if (status & IM_ALLOC_INT) {
-+ PRINTK3("%s: Allocation irq\n", dev->name);
-+ smc_hardware_send_packet(dev);
-+ mask |= (IM_TX_INT | IM_TX_EMPTY_INT);
-+ mask &= ~IM_ALLOC_INT;
-+#if ! THROTTLE_TX_PKTS
-+ netif_wake_queue(dev);
-+#endif
-+ } else if (status & IM_TX_EMPTY_INT) {
-+ PRINTK3("%s: TX empty\n", dev->name);
-+ mask &= ~IM_TX_EMPTY_INT;
-+
-+ /* update stats */
-+ SMC_SELECT_BANK( 0 );
-+ card_stats = SMC_GET_COUNTER();
-+ SMC_SELECT_BANK( 2 );
-+
-+ /* single collisions */
-+ lp->stats.collisions += card_stats & 0xF;
-+ card_stats >>= 4;
-+
-+ /* multiple collisions */
-+ lp->stats.collisions += card_stats & 0xF;
-+ } else if (status & IM_RX_OVRN_INT) {
-+ PRINTK1( "%s: RX overrun\n", dev->name);
-+ SMC_ACK_INT( IM_RX_OVRN_INT );
-+ lp->stats.rx_errors++;
-+ lp->stats.rx_fifo_errors++;
-+ } else if (status & IM_EPH_INT) {
-+ PRINTK("%s: UNSUPPORTED: EPH INTERRUPT\n", dev->name);
-+ } else if (status & IM_MDINT) {
-+ SMC_ACK_INT( IM_MDINT );
-+ smc_phy_interrupt(dev);
-+ } else if (status & IM_ERCV_INT ) {
-+ SMC_ACK_INT( IM_ERCV_INT );
-+ PRINTK("%s: UNSUPPORTED: ERCV INTERRUPT \n", dev->name);
-+ }
-+ } while (--timeout);
-+
-+ /* restore register states */
-+ SMC_SET_INT_MASK( mask );
-+ SMC_SET_PTR( saved_pointer );
-+ SMC_SELECT_BANK( saved_bank );
-+
-+ PRINTK3("%s: Interrupt done\n", dev->name);
-+}
-+
-+/* Our watchdog timed out. Called by the networking layer */
-+static void
-+smc_timeout(struct net_device *dev)
-+{
-+ struct smc_local *lp = (struct smc_local *)dev->priv;
-+
-+ PRINTK2("%s: %s\n", dev->name, __FUNCTION__);
-+
-+ smc_reset(dev);
-+ smc_enable(dev);
-+
-+#if 0
-+ /* Reconfiguring the PHY doesn't seem like a bad idea here, but
-+ * it introduced a problem. Now that this is a timeout routine,
-+ * we are getting called from within an interrupt context.
-+ * smc_phy_configure() calls smc_wait_ms() which calls
-+ * schedule_timeout() which calls schedule(). When schedule()
-+ * is called from an interrupt context, it prints out
-+ * "Scheduling in interrupt" and then calls BUG(). This is
-+ * obviously not desirable. This was worked around by removing
-+ * the call to smc_phy_configure() here because it didn't seem
-+ * absolutely necessary. Ultimately, if smc_wait_ms() is
-+ * supposed to be usable from an interrupt context (which it
-+ * looks like it thinks it should handle), it should be fixed.
-+ */
-+ /* Reconfigure the PHY */
-+ smc_phy_configure(dev);
-+#endif
-+
-+ /* clear anything saved */
-+ if (lp->saved_skb != NULL) {
-+ dev_kfree_skb (lp->saved_skb);
-+ lp->saved_skb = NULL;
-+ lp->stats.tx_errors++;
-+ lp->stats.tx_aborted_errors++;
-+ }
-+ dev->trans_start = jiffies;
-+ netif_wake_queue(dev);
-+}
-+
-+/*
-+ * Finds the CRC32 of a set of bytes.
-+ * (from Peter Cammaert's code)
-+ */
-+static int
-+crc32(char *s, int length)
-+{
-+ /* indices */
-+ int perByte;
-+ int perBit;
-+ /* crc polynomial for Ethernet */
-+ const unsigned long poly = 0xedb88320;
-+ /* crc value - preinitialized to all 1's */
-+ unsigned long crc_value = 0xffffffff;
-+
-+ for ( perByte = 0; perByte < length; perByte ++ ) {
-+ unsigned char c;
-+
-+ c = *(s++);
-+ for ( perBit = 0; perBit < 8; perBit++ ) {
-+ crc_value = (crc_value>>1)^
-+ (((crc_value^c)&0x01)?poly:0);
-+ c >>= 1;
-+ }
-+ }
-+ return crc_value;
-+}
-+
-+/*
-+ . This sets the internal hardware table to filter out unwanted multicast
-+ . packets before they take up memory.
-+ .
-+ . The SMC chip uses a hash table where the high 6 bits of the CRC of
-+ . address are the offset into the table. If that bit is 1, then the
-+ . multicast packet is accepted. Otherwise, it's dropped silently.
-+ .
-+ . To use the 6 bits as an offset into the table, the high 3 bits are the
-+ . number of the 8 bit register, while the low 3 bits are the bit within
-+ . that register.
-+ .
-+ . This routine is based very heavily on the one provided by Peter Cammaert.
-+*/
-+static void
-+smc_setmulticast(unsigned long ioaddr, int count, struct dev_mc_list *addrs)
-+{
-+ int i;
-+ unsigned char multicast_table[ 8 ];
-+ struct dev_mc_list *cur_addr;
-+
-+ /* table for flipping the order of 3 bits */
-+ static unsigned char invert3[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
-+
-+ /* start with a table of all zeros: reject all */
-+ memset( multicast_table, 0, sizeof( multicast_table ) );
-+
-+ cur_addr = addrs;
-+ for ( i = 0; i < count ; i ++, cur_addr = cur_addr->next ) {
-+ int position;
-+
-+ /* do we have a pointer here? */
-+ if ( !cur_addr )
-+ break;
-+ /* make sure this is a multicast address - shouldn't this
-+ be a given if we have it here ? */
-+ if ( !( *cur_addr->dmi_addr & 1 ) )
-+ continue;
-+
-+ /* only use the low order bits */
-+ position = crc32( cur_addr->dmi_addr, 6 ) & 0x3f;
-+
-+ /* do some messy swapping to put the bit in the right spot */
-+ multicast_table[invert3[position&7]] |=
-+ (1<<invert3[(position>>3)&7]);
-+
-+ }
-+ /* now, the table can be loaded into the chipset */
-+ SMC_SELECT_BANK( 3 );
-+ SMC_SET_MCAST( multicast_table );
-+}
-+
-+/*
-+ . This routine will, depending on the values passed to it,
-+ . either make it accept multicast packets, go into
-+ . promiscuous mode ( for TCPDUMP and cousins ) or accept
-+ . a select set of multicast packets
-+*/
-+static void smc_set_multicast_list(struct net_device *dev)
-+{
-+ struct smc_local *lp = (struct smc_local *)dev->priv;
-+ unsigned long ioaddr = dev->base_addr;
-+
-+ PRINTK2("%s: %s\n", dev->name, __FUNCTION__);
-+
-+ SMC_SELECT_BANK(0);
-+ if ( dev->flags & IFF_PROMISC ) {
-+ PRINTK2("%s: RCR_PRMS\n", dev->name);
-+ lp->rcr_cur_mode |= RCR_PRMS;
-+ SMC_SET_RCR( lp->rcr_cur_mode );
-+ }
-+
-+/* BUG? I never disable promiscuous mode if multicasting was turned on.
-+ Now, I turn off promiscuous mode, but I don't do anything to multicasting
-+ when promiscuous mode is turned on.
-+*/
-+
-+ /* Here, I am setting this to accept all multicast packets.
-+ I don't need to zero the multicast table, because the flag is
-+ checked before the table is
-+ */
-+ else if (dev->flags & IFF_ALLMULTI) {
-+ lp->rcr_cur_mode |= RCR_ALMUL;
-+ SMC_SET_RCR( lp->rcr_cur_mode );
-+ PRINTK2("%s: RCR_ALMUL\n", dev->name);
-+ }
-+
-+ /* We just get all multicast packets even if we only want them
-+ . from one source. This will be changed at some future
-+ . point. */
-+ else if (dev->mc_count ) {
-+ /* support hardware multicasting */
-+
-+ /* be sure I get rid of flags I might have set */
-+ lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL);
-+ SMC_SET_RCR( lp->rcr_cur_mode );
-+ /* NOTE: this has to set the bank, so make sure it is the
-+ last thing called. The bank is set to zero at the top */
-+ smc_setmulticast( ioaddr, dev->mc_count, dev->mc_list );
-+ } else {
-+ PRINTK2("%s: ~(RCR_PRMS|RCR_ALMUL)\n", dev->name);
-+ lp->rcr_cur_mode &= ~(RCR_PRMS | RCR_ALMUL);
-+ SMC_SET_RCR( lp->rcr_cur_mode );
-+
-+ /*
-+ since I'm disabling all multicast entirely, I need to
-+ clear the multicast list
-+ */
-+ SMC_SELECT_BANK( 3 );
-+ SMC_CLEAR_MCAST();
-+ }
-+}
-+
-+
-+/*
-+ * Open and Initialize the board
-+ *
-+ * Set up everything, reset the card, etc ..
-+ */
-+static int
-+smc_open(struct net_device *dev)
-+{
-+ struct smc_local *lp = (struct smc_local *)dev->priv;
-+ unsigned long ioaddr = dev->base_addr;
-+
-+ PRINTK2("%s: %s\n", dev->name, __FUNCTION__);
-+
-+ /* clear out all the junk that was put here before... */
-+ memset(dev->priv, 0, sizeof(struct smc_local));
-+
-+ // Setup the default Register Modes
-+ lp->tcr_cur_mode = TCR_DEFAULT;
-+ lp->rcr_cur_mode = RCR_DEFAULT;
-+ lp->rpc_cur_mode = RPC_DEFAULT;
-+
-+ /* Set default parameters */
-+#ifdef CONFIG_ARCH_RAMSES
-+ lp->ctl_autoneg = 0;
-+ lp->ctl_rfduplx = 0;
-+ lp->ctl_rspeed = 10;
-+#else
-+ lp->ctl_autoneg = 1;
-+ lp->ctl_rfduplx = 1;
-+ lp->ctl_rspeed = 100;
-+#endif
-+
-+ SMC_SELECT_BANK(3);
-+ lp->version = SMC_GET_REV() & 0xff;
-+
-+ /* reset the hardware */
-+ smc_reset(dev);
-+ smc_enable(dev);
-+
-+ SMC_SELECT_BANK( 1 );
-+ SMC_SET_MAC_ADDR(dev->dev_addr);
-+
-+ /* Configure the PHY */
-+ if (lp->version >= 0x70)
-+ smc_phy_configure(dev);
-+
-+ netif_start_queue(dev);
-+ return 0;
-+}
-+
-+/*----------------------------------------------------
-+ . smc_close
-+ .
-+ . this makes the board clean up everything that it can
-+ . and not talk to the outside world. Caused by
-+ . an 'ifconfig ethX down'
-+ .
-+ -----------------------------------------------------*/
-+static int
-+smc_close(struct net_device *dev)
-+{
-+ PRINTK2("%s: %s\n", dev->name, __FUNCTION__);
-+
-+ netif_stop_queue(dev);
-+
-+ /* clear everything */
-+ smc_shutdown(dev);
-+
-+ return 0;
-+}
-+
-+/*------------------------------------------------------------
-+ . Get the current statistics.
-+ . This may be called with the card open or closed.
-+ .-------------------------------------------------------------*/
-+static struct net_device_stats *
-+smc_query_statistics(struct net_device *dev)
-+{
-+ struct smc_local *lp = (struct smc_local *)dev->priv;
-+
-+ PRINTK2("%s: %s\n", dev->name, __FUNCTION__);
-+
-+ return &lp->stats;
-+}
-+
-+/*----------------------------------------------------------------------
-+ . smc_findirq
-+ .
-+ . This routine has a simple purpose -- make the SMC chip generate an
-+ . interrupt, so an auto-detect routine can detect it, and find the IRQ,
-+ ------------------------------------------------------------------------
-+*/
-+int __init
-+smc_findirq( unsigned long ioaddr )
-+{
-+ int timeout = 20;
-+ unsigned long cookie;
-+
-+ PRINTK2("%s: %s\n", CARDNAME, __FUNCTION__);
-+
-+ cookie = probe_irq_on();
-+
-+ /*
-+ * What I try to do here is trigger an ALLOC_INT. This is done
-+ * by allocating a small chunk of memory, which will give an interrupt
-+ * when done.
-+ */
-+
-+ /* enable ALLOCation interrupts ONLY */
-+ SMC_SELECT_BANK(2);
-+ SMC_SET_INT_MASK( IM_ALLOC_INT );
-+
-+ /*
-+ . Allocate 512 bytes of memory. Note that the chip was just
-+ . reset so all the memory is available
-+ */
-+ SMC_SET_MMU_CMD( MC_ALLOC | 1 );
-+
-+ /*
-+ . Wait until positive that the interrupt has been generated
-+ */
-+ do {
-+ int int_status;
-+ udelay(10);
-+ int_status = SMC_GET_INT();
-+ if (int_status & IM_ALLOC_INT)
-+ break; /* got the interrupt */
-+ } while (--timeout);
-+
-+ /* there is really nothing that I can do here if timeout fails,
-+ as autoirq_report will return a 0 anyway, which is what I
-+ want in this case. Plus, the clean up is needed in both
-+ cases. */
-+
-+ /* and disable all interrupts again */
-+ SMC_SET_INT_MASK( 0 );
-+
-+ /* and return what I found */
-+ return probe_irq_off(cookie);
-+}
-+
-+/*----------------------------------------------------------------------
-+ . Function: smc_probe( unsigned long ioaddr )
-+ .
-+ . Purpose:
-+ . Tests to see if a given ioaddr points to an SMC91x chip.
-+ . Returns a 0 on success
-+ .
-+ . Algorithm:
-+ . (1) see if the high byte of BANK_SELECT is 0x33
-+ . (2) compare the ioaddr with the base register's address
-+ . (3) see if I recognize the chip ID in the appropriate register
-+ .
-+ .---------------------------------------------------------------------
-+ */
-+/*---------------------------------------------------------------
-+ . Here I do typical initialization tasks.
-+ .
-+ . o Initialize the structure if needed
-+ . o print out my vanity message if not done so already
-+ . o print out what type of hardware is detected
-+ . o print out the ethernet address
-+ . o find the IRQ
-+ . o set up my private data
-+ . o configure the dev structure with my subroutines
-+ . o actually GRAB the irq.
-+ . o GRAB the region
-+ .-----------------------------------------------------------------
-+*/
-+static int __init
-+smc_probe(struct net_device *dev, unsigned long ioaddr)
-+{
-+ struct smc_local *lp = (struct smc_local *)dev->priv;
-+ static int version_printed = 0;
-+ int i, retval;
-+ unsigned int val, revision_register;
-+ const char *version_string;
-+
-+ PRINTK2("%s: %s\n", CARDNAME, __FUNCTION__);
-+
-+ /* Grab the region so that no one else tries to probe our ioports. */
-+ if (!request_region(ioaddr, SMC_IO_EXTENT, dev->name))
-+ return -EBUSY;
-+
-+ /* First, see if the high byte is 0x33 */
-+ val = SMC_CURRENT_BANK();
-+ PRINTK2("%s: bank signature probe returned 0x%04x\n", CARDNAME, val);
-+ if ( (val & 0xFF00) != 0x3300 ) {
-+ if ( (val & 0xFF) == 0x33 ) {
-+ printk( KERN_WARNING
-+ "%s: Detected possible byte-swapped interface"
-+ " at IOADDR 0x%lx\n", CARDNAME, ioaddr);
-+ }
-+ retval = -ENODEV;
-+ goto err_out;
-+ }
-+
-+ /* The above MIGHT indicate a device, but I need to write to further
-+ test this. */
-+ SMC_SELECT_BANK(0);
-+ val = SMC_CURRENT_BANK();
-+ if ( (val & 0xFF00 ) != 0x3300 ) {
-+ retval = -ENODEV;
-+ goto err_out;
-+ }
-+
-+ /* well, we've already written once, so hopefully another time won't
-+ hurt. This time, I need to switch the bank register to bank 1,
-+ so I can access the base address register */
-+ SMC_SELECT_BANK(1);
-+ val = SMC_GET_BASE();
-+ val = ((val & 0x1F00) >> 3) << SMC_IO_SHIFT;
-+ if ( (ioaddr & ((PAGE_SIZE-1)<<SMC_IO_SHIFT)) != val ) {
-+ printk( "%s: IOADDR %lx doesn't match configuration (%x).\n",
-+ CARDNAME, ioaddr, val );
-+ }
-+
-+ /* check if the revision register is something that I recognize.
-+ These might need to be added to later, as future revisions
-+ could be added. */
-+ SMC_SELECT_BANK(3);
-+ revision_register = SMC_GET_REV();
-+ PRINTK2("%s: revision = 0x%04x\n", CARDNAME, revision_register);
-+ version_string = chip_ids[ (revision_register >> 4) & 0xF];
-+ if (!version_string || (revision_register & 0xff00) != 0x3300) {
-+ /* I don't recognize this chip, so... */
-+ printk( "%s: IO 0x%lx: Unrecognized revision register 0x%04x"
-+ ", Contact author.\n", CARDNAME,
-+ ioaddr, revision_register);
-+
-+ retval = -ENODEV;
-+ goto err_out;
-+ }
-+
-+ /* At this point I'll assume that the chip is an SMC91x. */
-+ if (version_printed++ == 0)
-+ printk("%s", version);
-+
-+ /* set the private data to zero by default */
-+ memset(lp, 0, sizeof(struct smc_local));
-+
-+ /* fill in some of the fields */
-+ dev->base_addr = ioaddr;
-+ lp->version = revision_register & 0xff;
-+
-+ /* Get the MAC address */
-+ SMC_SELECT_BANK( 1 );
-+ SMC_GET_MAC_ADDR(dev->dev_addr);
-+
-+ /* now, reset the chip, and put it into a known state */
-+ smc_reset( dev );
-+
-+ /*
-+ . If dev->irq is 0, then the device has to be banged on to see
-+ . what the IRQ is.
-+ .
-+ . This banging doesn't always detect the IRQ, for unknown reasons.
-+ . a workaround is to reset the chip and try again.
-+ .
-+ . Interestingly, the DOS packet driver *SETS* the IRQ on the card to
-+ . be what is requested on the command line. I don't do that, mostly
-+ . because the card that I have uses a non-standard method of accessing
-+ . the IRQs, and because this _should_ work in most configurations.
-+ .
-+ . Specifying an IRQ is done with the assumption that the user knows
-+ . what (s)he is doing. No checking is done!!!!
-+ .
-+ */
-+ if ( dev->irq < 1 ) {
-+ int trials;
-+
-+ trials = 3;
-+ while ( trials-- ) {
-+ dev->irq = smc_findirq( ioaddr );
-+ if ( dev->irq )
-+ break;
-+ /* kick the card and try again */
-+ smc_reset( dev );
-+ }
-+ }
-+ if (dev->irq == 0 ) {
-+ printk("%s: Couldn't autodetect your IRQ. Use irq=xx.\n",
-+ dev->name);
-+ retval = -ENODEV;
-+ goto err_out;
-+ }
-+ dev->irq = irq_cannonicalize(dev->irq);
-+
-+ /* now, print out the card info, in a short format.. */
-+ printk( "%s: %s (rev %d) at %#lx IRQ %d%s%s\n",
-+ dev->name, version_string, revision_register & 0x0f,
-+ ioaddr, dev->irq, nowait ? " [nowait]" : "",
-+ THROTTLE_TX_PKTS ? " [throttle_tx]" : "" );
-+
-+ /* Print the Ethernet address */
-+ printk("%s: Ethernet addr: ", dev->name);
-+ for (i = 0; i < 5; i++)
-+ printk("%2.2x:", dev->dev_addr[i] );
-+ printk("%2.2x\n", dev->dev_addr[5] );
-+
-+ /* Fill in the fields of the device structure with ethernet values. */
-+ ether_setup(dev);
-+
-+ /* Grab the IRQ */
-+ retval = request_irq(dev->irq, &smc_interrupt, 0, dev->name, dev);
-+ if (retval) {
-+ goto err_out;
-+ }
-+
-+ dev->open = smc_open;
-+ dev->stop = smc_close;
-+ dev->hard_start_xmit = smc_hard_start_xmit;
-+ dev->tx_timeout = smc_timeout;
-+ dev->watchdog_timeo = HZ/10;
-+ dev->get_stats = smc_query_statistics;
-+ dev->set_multicast_list = smc_set_multicast_list;
-+
-+ return 0;
-+
-+err_out:
-+ release_region(ioaddr, SMC_IO_EXTENT);
-+ return retval;
-+}
-+
-+/*-------------------------------------------------------------------------
-+ |
-+ | smc_init( void )
-+ | Input parameters:
-+ | dev->base_addr == 0, try to find all possible locations
-+ | dev->base_addr > 0x1ff, this is the address to check
-+ | dev->base_addr == <anything else>, return failure code
-+ |
-+ | Output:
-+ | 0 --> there is a device
-+ | anything else, error
-+ |
-+ ---------------------------------------------------------------------------
-+*/
-+static struct net_device *global_dev = NULL; /* needs to be fixed */
-+
-+#ifdef CONFIG_PM
-+
-+static int smc_pm_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
-+{
-+ unsigned long ioaddr = global_dev->base_addr;
-+ struct smc_local *lp = (struct smc_local *)global_dev->priv;
-+
-+ switch (rqst) {
-+ case PM_SUSPEND:
-+ smc_shutdown(global_dev);
-+ break;
-+ case PM_RESUME:
-+ smc_reset(global_dev);
-+ smc_enable(global_dev);
-+ SMC_SELECT_BANK( 1 );
-+ SMC_SET_MAC_ADDR(global_dev->dev_addr);
-+ if (lp->version >= 0x70)
-+ smc_phy_configure(global_dev);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+#endif
-+
-+static int __init
-+smc_init(void)
-+{
-+ int ret;
-+
-+ PRINTK2("%s: %s\n", CARDNAME, __FUNCTION__);
-+
-+#ifdef MODULE
-+ if (io == -1)
-+ printk( KERN_WARNING
-+ "%s: You shouldn't use auto-probing with insmod!\n",
-+ CARDNAME );
-+#endif
-+
-+ if (global_dev) {
-+ printk("%s: already initialized.\n", CARDNAME);
-+ return -EBUSY;
-+ }
-+
-+ global_dev = init_etherdev(0, sizeof(struct smc_local));
-+ if (!global_dev) {
-+ printk("%s: could not allocate device.\n", CARDNAME);
-+ return -ENOMEM;
-+ }
-+ SET_MODULE_OWNER(global_dev);
-+
-+ /* copy the parameters from insmod into the device structure */
-+ if (io != -1)
-+ global_dev->base_addr = io;
-+ if (irq != -1)
-+ global_dev->irq = irq;
-+
-+#ifdef CONFIG_ISA
-+ /* try a specific location */
-+ if (global_dev->base_addr > 0x1ff)
-+ ret = smc_probe(global_dev, global_dev->base_addr);
-+ else if (global_dev->base_addr != 0)
-+ ret = -ENXIO;
-+ else {
-+ int i;
-+
-+ /* check every ethernet address */
-+ for (i = 0; smc_portlist[i]; i++) {
-+ ret = smc_probe(global_dev, smc_portlist[i]);
-+ if (ret == 0)
-+ break;
-+ }
-+ }
-+#elif defined(CONFIG_ARCH_LUBBOCK)
-+ {
-+ int ioaddr = LUBBOCK_ETH_VIRT + (0x300 << 2);
-+ volatile int *attaddr = (int *)(LUBBOCK_ETH_VIRT + 0x100000);
-+ unsigned long flags;
-+
-+ /* first reset, then enable the device. Sequence is critical */
-+ local_irq_save(flags);
-+ attaddr[ECOR] |= ECOR_RESET;
-+ udelay(100);
-+ attaddr[ECOR] &= ~ECOR_RESET;
-+ attaddr[ECOR] |= ECOR_ENABLE;
-+
-+ /* force 16-bit mode */
-+ attaddr[ECSR] &= ~ECSR_IOIS8;
-+ mdelay(1);
-+ local_irq_restore(flags);
-+
-+ global_dev->irq = LUBBOCK_ETH_IRQ;
-+ ret = smc_probe(global_dev, ioaddr);
-+ }
-+#elif defined(CONFIG_ARCH_PXA_IDP)
-+ {
-+ int ioaddr = IDP_ETH_BASE + 0x300;
-+ global_dev->irq = SMC_IRQ;
-+ ret = smc_probe(global_dev, ioaddr);
-+ }
-+#elif defined(CONFIG_ARCH_RAMSES)
-+ {
-+ int ioaddr = RAMSES_ETH_BASE + 0x300;
-+ global_dev->irq = SMC_IRQ;
-+ ret = smc_probe(global_dev, ioaddr);
-+ }
-+#else
-+ if (global_dev->base_addr == -1) {
-+ printk(KERN_WARNING"%s: SMC91X_BASE_ADDR not set!\n", CARDNAME);
-+ ret = -ENXIO;
-+ } else {
-+ void *ioaddr = ioremap(global_dev->base_addr, SMC_IO_EXTENT);
-+ ret = smc_probe(global_dev, (unsigned long)ioaddr);
-+ if (ret != 0)
-+ iounmap(ioaddr);
-+ }
-+#endif
-+
-+#ifdef SMC_USE_PXA_DMA
-+ if (ret == 0) {
-+ int dma = pxa_request_dma(global_dev->name, DMA_PRIO_LOW,
-+ smc_pxa_dma_irq, NULL);
-+ if (dma >= 0) {
-+ global_dev->dma = dma;
-+ PRINTK("%s: using DMA channel %d\n", global_dev->name, dma);
-+ } else {
-+ global_dev->dma = -1;
-+ }
-+ }
-+#endif
-+
-+#ifdef CONFIG_PM
-+ if (ret == 0) {
-+ struct smc_local *lp = (struct smc_local *)global_dev->priv;
-+ lp->pm = pm_register(PM_SYS_UNKNOWN, 0x73393178, smc_pm_callback);
-+ }
-+#endif
-+
-+ if (ret != 0) {
-+ printk("%s: not found.\n", CARDNAME);
-+ kfree(global_dev->priv);
-+ unregister_netdev(global_dev);
-+ kfree(global_dev);
-+ }
-+
-+ return ret;
-+}
-+
-+static void __exit
-+smc_cleanup(void)
-+{
-+ unregister_netdev(global_dev);
-+#ifdef CONFIG_PM
-+ {
-+ struct smc_local *lp = (struct smc_local *)global_dev->priv;
-+ pm_unregister(lp->pm);
-+ }
-+#endif
-+ free_irq(global_dev->irq, global_dev);
-+ release_region(global_dev->base_addr, SMC_IO_EXTENT);
-+
-+#ifndef CONFIG_ISA
-+ iounmap((void *)global_dev->base_addr);
-+#endif
-+
-+ kfree(global_dev);
-+ global_dev = NULL;
-+}
-+
-+module_init(smc_init);
-+module_exit(smc_cleanup);
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/net/smc91x.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,835 @@
-+/*------------------------------------------------------------------------
-+ . smc91x.h - macros for SMSC's 91C9x/91C1xx single-chip Ethernet device.
-+ .
-+ . Copyright (C) 1996 by Erik Stahlman
-+ . Copyright (C) 2001 Standard Microsystems Corporation
-+ . Developed by Simple Network Magic Corporation
-+ . Copyright (C) 2003 Monta Vista Software, Inc.
-+ . Unified SMC91x driver by Nicolas Pitre
-+ .
-+ . 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ .
-+ . Information contained in this file was obtained from the LAN91C111
-+ . manual from SMC. To get a copy, if you really want one, you can find
-+ . information under www.smsc.com.
-+ .
-+ . Authors
-+ . Erik Stahlman <erik@vt.edu>
-+ . Daris A Nevil <dnevil@snmc.com>
-+ . Nicolas Pitre <nico@cam.org>
-+ .
-+ ---------------------------------------------------------------------------*/
-+#ifndef _SMC91X_H_
-+#define _SMC91X_H_
-+
-+
-+/*
-+ * Define your architecture specific configuration parameters here.
-+ */
-+
-+#if defined(CONFIG_SA1100_GRAPHICSCLIENT) || \
-+ defined(CONFIG_SA1100_PFS168) || \
-+ defined(CONFIG_SA1100_FLEXANET) || \
-+ defined(CONFIG_SA1100_GRAPHICSMASTER) || \
-+ defined(CONFIG_ARCH_LUBBOCK)
-+
-+/* We can only do 16-bit reads and writes in the static memory space. */
-+#define SMC_CAN_USE_8BIT 0
-+#define SMC_CAN_USE_16BIT 1
-+#define SMC_CAN_USE_32BIT 0
-+#define SMC_NOWAIT 1
-+
-+/* The first two address lines aren't connected... */
-+#define SMC_IO_SHIFT 2
-+
-+#define SMC_inw(a, r) readw((a) + (r))
-+#define SMC_outw(v, a, r) writew(v, (a) + (r))
-+#define SMC_insw(a, r, p, l) insw((a) + (r), p, l)
-+#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
-+
-+#ifdef CONFIG_ARCH_LUBBOCK
-+#define SMC_IOADDR LUBBOCK_ETH_PHYS
-+#endif
-+
-+#elif defined(CONFIG_ARCH_MAINSTONE) || defined(CONFIG_ARCH_PXA_IDP) || defined(CONFIG_ARCH_RAMSES)
-+
-+#ifdef CONFIG_ARCH_MAINSTONE
-+#include <asm/arch/mainstone.h>
-+#define SMC_IOADDR (MST_ETH_PHYS + 0x300)
-+#define SMC_IRQ MAINSTONE_IRQ(3)
-+
-+#elif CONFIG_ARCH_PXA_IDP
-+#include <asm/arch/idp.h>
-+#define SMC_IOADDR (IDP_ETH_PHYS + 0x300)
-+#define SMC_IRQ ETHERNET_IRQ
-+
-+#elif CONFIG_ARCH_RAMSES
-+#include <asm/arch/ramses.h>
-+#define SMC_IOADDR (RAMSES_ETH_PHYS + 0x300)
-+#define SMC_IRQ ETHERNET_IRQ
-+#endif
-+
-+#define SMC_CAN_USE_8BIT 1
-+#define SMC_CAN_USE_16BIT 1
-+#define SMC_CAN_USE_32BIT 1
-+#define SMC_IO_SHIFT 0
-+#define SMC_NOWAIT 1
-+#define SMC_USE_PXA_DMA 1
-+
-+#define SMC_inb(a, r) readb((a) + (r))
-+#define SMC_inw(a, r) readw((a) + (r))
-+#define SMC_inl(a, r) readl((a) + (r))
-+#define SMC_outb(v, a, r) writeb(v, (a) + (r))
-+#define SMC_outl(v, a, r) writel(v, (a) + (r))
-+#define SMC_insl(a, r, p, l) insl((a) + (r), p, l)
-+#define SMC_outsl(a, r, p, l) outsl((a) + (r), p, l)
-+
-+/* We actually can't write halfwords properly if not word aligned */
-+static inline void
-+SMC_outw(u16 val, unsigned long ioaddr, int reg)
-+{
-+ if (reg & 2) {
-+ unsigned int v = val << 16;
-+ v |= readl(ioaddr + (reg & ~2)) & 0xffff;
-+ writel(v, ioaddr + (reg & ~2));
-+ } else {
-+ writew(val, ioaddr + reg);
-+ }
-+}
-+
-+#elif defined(CONFIG_ISA)
-+
-+#define SMC_CAN_USE_8BIT 1
-+#define SMC_CAN_USE_16BIT 1
-+#define SMC_CAN_USE_32BIT 0
-+
-+#define SMC_inb(a, r) inb((a) + (r))
-+#define SMC_inw(a, r) inw((a) + (r))
-+#define SMC_outb(v, a, r) outb(v, (a) + (r))
-+#define SMC_outw(v, a, r) outw(v, (a) + (r))
-+#define SMC_insw(a, r, p, l) insw((a) + (r), p, l)
-+#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l)
-+
-+#endif
-+
-+
-+#ifdef SMC_USE_PXA_DMA
-+/*
-+ * Let's use the DMA engine on the XScale PXA2xx for RX packets. This is
-+ * always happening in irq context so no need to worry about races. TX is
-+ * different and probably not worth it for that reason, and not as critical
-+ * as RX which can overrun memory and lose packets.
-+ */
-+#include <linux/pci.h>
-+#include <asm/dma.h>
-+
-+#ifdef SMC_insl
-+#undef SMC_insl
-+#define SMC_insl(a, r, p, l) smc_pxa_dma_insl(a, r, dev->dma, p, l)
-+static inline void
-+smc_pxa_dma_insl(u_long ioaddr, int reg, int dma, u_char *buf, int len)
-+{
-+ dma_addr_t dmabuf;
-+
-+ /* fallback if no DMA available */
-+ if (dma == -1) {
-+ insl(ioaddr + reg, buf, len);
-+ return;
-+ }
-+
-+ /* 64 bit alignment is required for memory to memory DMA */
-+ if ((long)buf & 4) {
-+ *((u32 *)buf)++ = SMC_inl(ioaddr, reg);
-+ len--;
-+ }
-+
-+ len *= 4;
-+ dmabuf = pci_map_single(NULL, buf, len, PCI_DMA_FROMDEVICE);
-+ DCSR(dma) = DCSR_NODESC;
-+ DTADR(dma) = dmabuf;
-+ DSADR(dma) = SMC_IOADDR + reg;
-+ DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
-+ DCMD_WIDTH4 | (DCMD_LENGTH & len));
-+ DCSR(dma) = DCSR_NODESC | DCSR_RUN;
-+ while (!(DCSR(dma) & DCSR_STOPSTATE));
-+ DCSR(dma) = 0;
-+ pci_unmap_single(NULL, dmabuf,len, PCI_DMA_FROMDEVICE);
-+}
-+#endif
-+
-+#ifdef SMC_insw
-+#undef SMC_insw
-+#define SMC_insw(a, r, p, l) smc_pxa_dma_insw(a, r, dev->dma, p, l)
-+static inline void
-+smc_pxa_dma_insw(u_long ioaddr, int reg, int dma, u_char *buf, int len)
-+{
-+ dma_addr_t dmabuf;
-+
-+ /* fallback if no DMA available */
-+ if (dma == -1) {
-+ insw(ioaddr + reg, buf, len);
-+ return;
-+ }
-+
-+ /* 64 bit alignment is required for memory to memory DMA */
-+ while ((long)buf & 6) {
-+ *((u16 *)buf)++ = SMC_inw(ioaddr, reg);
-+ len--;
-+ }
-+
-+ len *= 2;
-+ dmabuf = pci_map_single(NULL, buf, len, PCI_DMA_FROMDEVICE);
-+ DCSR(dma) = DCSR_NODESC;
-+ DTADR(dma) = dmabuf;
-+ DSADR(dma) = SMC_IOADDR + reg;
-+ DCMD(dma) = (DCMD_INCTRGADDR | DCMD_BURST32 |
-+ DCMD_WIDTH2 | (DCMD_LENGTH & len));
-+ DCSR(dma) = DCSR_NODESC | DCSR_RUN;
-+ while (!(DCSR(dma) & DCSR_STOPSTATE));
-+ DCSR(dma) = 0;
-+ pci_unmap_single(NULL, dmabuf,len, PCI_DMA_FROMDEVICE);
-+}
-+#endif
-+
-+static void
-+smc_pxa_dma_irq(int dma, void *dummy, struct pt_regs *regs)
-+{
-+ DCSR(dma) = 0;
-+}
-+#endif /* SMC_USE_PXA_DMA */
-+
-+
-+/* Because of bank switching, the LAN91xxx uses only 16 I/O ports */
-+#ifndef SMC_IO_SHIFT
-+#define SMC_IO_SHIFT 0
-+#endif
-+#define SMC_IO_EXTENT (16 << SMC_IO_SHIFT)
-+
-+
-+/*
-+ . Bank Select Register:
-+ .
-+ . yyyy yyyy 0000 00xx
-+ . xx = bank number
-+ . yyyy yyyy = 0x33, for identification purposes.
-+*/
-+#define BANK_SELECT (14 << SMC_IO_SHIFT)
-+
-+
-+// Transmit Control Register
-+/* BANK 0 */
-+#define TCR_REG SMC_REG(0x0000, 0)
-+#define TCR_ENABLE 0x0001 // When 1 we can transmit
-+#define TCR_LOOP 0x0002 // Controls output pin LBK
-+#define TCR_FORCOL 0x0004 // When 1 will force a collision
-+#define TCR_PAD_EN 0x0080 // When 1 will pad tx frames < 64 bytes w/0
-+#define TCR_NOCRC 0x0100 // When 1 will not append CRC to tx frames
-+#define TCR_MON_CSN 0x0400 // When 1 tx monitors carrier
-+#define TCR_FDUPLX 0x0800 // When 1 enables full duplex operation
-+#define TCR_STP_SQET 0x1000 // When 1 stops tx if Signal Quality Error
-+#define TCR_EPH_LOOP 0x2000 // When 1 enables EPH block loopback
-+#define TCR_SWFDUP 0x8000 // When 1 enables Switched Full Duplex mode
-+
-+#define TCR_CLEAR 0 /* do NOTHING */
-+/* the default settings for the TCR register : */
-+#define TCR_DEFAULT (TCR_ENABLE | TCR_PAD_EN)
-+
-+
-+// EPH Status Register
-+/* BANK 0 */
-+#define EPH_STATUS_REG SMC_REG(0x0002, 0)
-+#define ES_TX_SUC 0x0001 // Last TX was successful
-+#define ES_SNGL_COL 0x0002 // Single collision detected for last tx
-+#define ES_MUL_COL 0x0004 // Multiple collisions detected for last tx
-+#define ES_LTX_MULT 0x0008 // Last tx was a multicast
-+#define ES_16COL 0x0010 // 16 Collisions Reached
-+#define ES_SQET 0x0020 // Signal Quality Error Test
-+#define ES_LTXBRD 0x0040 // Last tx was a broadcast
-+#define ES_TXDEFR 0x0080 // Transmit Deferred
-+#define ES_LATCOL 0x0200 // Late collision detected on last tx
-+#define ES_LOSTCARR 0x0400 // Lost Carrier Sense
-+#define ES_EXC_DEF 0x0800 // Excessive Deferral
-+#define ES_CTR_ROL 0x1000 // Counter Roll Over indication
-+#define ES_LINK_OK 0x4000 // Driven by inverted value of nLNK pin
-+#define ES_TXUNRN 0x8000 // Tx Underrun
-+
-+
-+// Receive Control Register
-+/* BANK 0 */
-+#define RCR_REG SMC_REG(0x0004, 0)
-+#define RCR_RX_ABORT 0x0001 // Set if a rx frame was aborted
-+#define RCR_PRMS 0x0002 // Enable promiscuous mode
-+#define RCR_ALMUL 0x0004 // When set accepts all multicast frames
-+#define RCR_RXEN 0x0100 // IFF this is set, we can receive packets
-+#define RCR_STRIP_CRC 0x0200 // When set strips CRC from rx packets
-+#define RCR_ABORT_ENB 0x0200 // When set will abort rx on collision
-+#define RCR_FILT_CAR 0x0400 // When set filters leading 12 bit s of carrier
-+#define RCR_SOFTRST 0x8000 // resets the chip
-+
-+/* the normal settings for the RCR register : */
-+#define RCR_DEFAULT (RCR_STRIP_CRC | RCR_RXEN)
-+#define RCR_CLEAR 0x0 // set it to a base state
-+
-+
-+// Counter Register
-+/* BANK 0 */
-+#define COUNTER_REG SMC_REG(0x0006, 0)
-+
-+
-+// Memory Information Register
-+/* BANK 0 */
-+#define MIR_REG SMC_REG(0x0008, 0)
-+
-+
-+// Receive/Phy Control Register
-+/* BANK 0 */
-+#define RPC_REG SMC_REG(0x000A, 0)
-+#define RPC_SPEED 0x2000 // When 1 PHY is in 100Mbps mode.
-+#define RPC_DPLX 0x1000 // When 1 PHY is in Full-Duplex Mode
-+#define RPC_ANEG 0x0800 // When 1 PHY is in Auto-Negotiate Mode
-+#define RPC_LSXA_SHFT 5 // Bits to shift LS2A,LS1A,LS0A to lsb
-+#define RPC_LSXB_SHFT 2 // Bits to get LS2B,LS1B,LS0B to lsb
-+#define RPC_LED_100_10 (0x00) // LED = 100Mbps OR's with 10Mbps link detect
-+#define RPC_LED_RES (0x01) // LED = Reserved
-+#define RPC_LED_10 (0x02) // LED = 10Mbps link detect
-+#define RPC_LED_FD (0x03) // LED = Full Duplex Mode
-+#define RPC_LED_TX_RX (0x04) // LED = TX or RX packet occurred
-+#define RPC_LED_100 (0x05) // LED = 100Mbps link dectect
-+#define RPC_LED_TX (0x06) // LED = TX packet occurred
-+#define RPC_LED_RX (0x07) // LED = RX packet occurred
-+#define RPC_DEFAULT (RPC_ANEG | (RPC_LED_100 << RPC_LSXA_SHFT) | (RPC_LED_FD << RPC_LSXB_SHFT) | RPC_SPEED | RPC_DPLX)
-+
-+
-+/* Bank 0 0x0C is reserved */
-+
-+// Bank Select Register
-+/* All Banks */
-+#define BSR_REG 0x000E
-+
-+
-+// Configuration Reg
-+/* BANK 1 */
-+#define CONFIG_REG SMC_REG(0x0000, 1)
-+#define CONFIG_EXT_PHY 0x0200 // 1=external MII, 0=internal Phy
-+#define CONFIG_GPCNTRL 0x0400 // Inverse value drives pin nCNTRL
-+#define CONFIG_NO_WAIT 0x1000 // When 1 no extra wait states on ISA bus
-+#define CONFIG_EPH_POWER_EN 0x8000 // When 0 EPH is placed into low power mode.
-+
-+// Default is powered-up, Internal Phy, Wait States, and pin nCNTRL=low
-+#define CONFIG_DEFAULT (CONFIG_EPH_POWER_EN)
-+
-+
-+// Base Address Register
-+/* BANK 1 */
-+#define BASE_REG SMC_REG(0x0002, 1)
-+
-+
-+// Individual Address Registers
-+/* BANK 1 */
-+#define ADDR0_REG SMC_REG(0x0004, 1)
-+#define ADDR1_REG SMC_REG(0x0006, 1)
-+#define ADDR2_REG SMC_REG(0x0008, 1)
-+
-+
-+// General Purpose Register
-+/* BANK 1 */
-+#define GP_REG SMC_REG(0x000A, 1)
-+
-+
-+// Control Register
-+/* BANK 1 */
-+#define CTL_REG SMC_REG(0x000C, 1)
-+#define CTL_RCV_BAD 0x4000 // When 1 bad CRC packets are received
-+#define CTL_AUTO_RELEASE 0x0800 // When 1 tx pages are released automatically
-+#define CTL_LE_ENABLE 0x0080 // When 1 enables Link Error interrupt
-+#define CTL_CR_ENABLE 0x0040 // When 1 enables Counter Rollover interrupt
-+#define CTL_TE_ENABLE 0x0020 // When 1 enables Transmit Error interrupt
-+#define CTL_EEPROM_SELECT 0x0004 // Controls EEPROM reload & store
-+#define CTL_RELOAD 0x0002 // When set reads EEPROM into registers
-+#define CTL_STORE 0x0001 // When set stores registers into EEPROM
-+
-+
-+// MMU Command Register
-+/* BANK 2 */
-+#define MMU_CMD_REG SMC_REG(0x0000, 2)
-+#define MC_BUSY 1 // When 1 the last release has not completed
-+#define MC_NOP (0<<5) // No Op
-+#define MC_ALLOC (1<<5) // OR with number of 256 byte packets
-+#define MC_RESET (2<<5) // Reset MMU to initial state
-+#define MC_REMOVE (3<<5) // Remove the current rx packet
-+#define MC_RELEASE (4<<5) // Remove and release the current rx packet
-+#define MC_FREEPKT (5<<5) // Release packet in PNR register
-+#define MC_ENQUEUE (6<<5) // Enqueue the packet for transmit
-+#define MC_RSTTXFIFO (7<<5) // Reset the TX FIFOs
-+
-+
-+// Packet Number Register
-+/* BANK 2 */
-+#define PN_REG SMC_REG(0x0002, 2)
-+
-+
-+// Allocation Result Register
-+/* BANK 2 */
-+#define AR_REG SMC_REG(0x0003, 2)
-+#define AR_FAILED 0x80 // Alocation Failed
-+
-+
-+// TX FIFO Ports Register
-+/* BANK 2 */
-+#define TXFIFO_REG SMC_REG(0x0004, 2)
-+#define TXFIFO_TEMPTY 0x80 // TX FIFO Empty
-+
-+// RX FIFO Ports Register
-+/* BANK 2 */
-+#define RXFIFO_REG SMC_REG(0x0005, 2)
-+#define RXFIFO_REMPTY 0x80 // RX FIFO Empty
-+
-+#define FIFO_REG SMC_REG(0x0004, 2)
-+
-+// Pointer Register
-+/* BANK 2 */
-+#define PTR_REG SMC_REG(0x0006, 2)
-+#define PTR_RCV 0x8000 // 1=Receive area, 0=Transmit area
-+#define PTR_AUTOINC 0x4000 // Auto increment the pointer on each access
-+#define PTR_READ 0x2000 // When 1 the operation is a read
-+
-+
-+// Data Register
-+/* BANK 2 */
-+#define DATA_REG SMC_REG(0x0008, 2)
-+
-+
-+// Interrupt Status/Acknowledge Register
-+/* BANK 2 */
-+#define INT_REG SMC_REG(0x000C, 2)
-+
-+
-+// Interrupt Mask Register
-+/* BANK 2 */
-+#define IM_REG SMC_REG(0x000D, 2)
-+#define IM_MDINT 0x80 // PHY MI Register 18 Interrupt
-+#define IM_ERCV_INT 0x40 // Early Receive Interrupt
-+#define IM_EPH_INT 0x20 // Set by Ethernet Protocol Handler section
-+#define IM_RX_OVRN_INT 0x10 // Set by Receiver Overruns
-+#define IM_ALLOC_INT 0x08 // Set when allocation request is completed
-+#define IM_TX_EMPTY_INT 0x04 // Set if the TX FIFO goes empty
-+#define IM_TX_INT 0x02 // Transmit Interrupt
-+#define IM_RCV_INT 0x01 // Receive Interrupt
-+
-+
-+// Multicast Table Registers
-+/* BANK 3 */
-+#define MCAST_REG1 SMC_REG(0x0000, 3)
-+#define MCAST_REG2 SMC_REG(0x0002, 3)
-+#define MCAST_REG3 SMC_REG(0x0004, 3)
-+#define MCAST_REG4 SMC_REG(0x0006, 3)
-+
-+
-+// Management Interface Register (MII)
-+/* BANK 3 */
-+#define MII_REG SMC_REG(0x0008, 3)
-+#define MII_MSK_CRS100 0x4000 // Disables CRS100 detection during tx half dup
-+#define MII_MDOE 0x0008 // MII Output Enable
-+#define MII_MCLK 0x0004 // MII Clock, pin MDCLK
-+#define MII_MDI 0x0002 // MII Input, pin MDI
-+#define MII_MDO 0x0001 // MII Output, pin MDO
-+
-+
-+// Revision Register
-+/* BANK 3 */
-+/* ( hi: chip id low: rev # ) */
-+#define REV_REG SMC_REG(0x000A, 3)
-+
-+
-+// Early RCV Register
-+/* BANK 3 */
-+/* this is NOT on SMC9192 */
-+#define ERCV_REG SMC_REG(0x000C, 3)
-+#define ERCV_RCV_DISCRD 0x0080 // When 1 discards a packet being received
-+#define ERCV_THRESHOLD 0x001F // ERCV Threshold Mask
-+
-+
-+// External Register
-+/* BANK 7 */
-+#define EXT_REG SMC_REG(0x0000, 7)
-+
-+
-+#define CHIP_9192 3
-+#define CHIP_9194 4
-+#define CHIP_9195 5
-+#define CHIP_9196 6
-+#define CHIP_91100 7
-+#define CHIP_91100FD 8
-+#define CHIP_91111FD 9
-+
-+static const char * chip_ids[ 16 ] = {
-+ NULL, NULL, NULL,
-+ /* 3 */ "SMC91C90/91C92",
-+ /* 4 */ "SMC91C94",
-+ /* 5 */ "SMC91C95",
-+ /* 6 */ "SMC91C96",
-+ /* 7 */ "SMC91C100",
-+ /* 8 */ "SMC91C100FD",
-+ /* 9 */ "SMC91C11xFD",
-+ NULL, NULL, NULL,
-+ NULL, NULL, NULL};
-+
-+
-+/*
-+ . Transmit status bits
-+*/
-+#define TS_SUCCESS 0x0001
-+#define TS_LOSTCAR 0x0400
-+#define TS_LATCOL 0x0200
-+#define TS_16COL 0x0010
-+
-+/*
-+ . Receive status bits
-+*/
-+#define RS_ALGNERR 0x8000
-+#define RS_BRODCAST 0x4000
-+#define RS_BADCRC 0x2000
-+#define RS_ODDFRAME 0x1000
-+#define RS_TOOLONG 0x0800
-+#define RS_TOOSHORT 0x0400
-+#define RS_MULTICAST 0x0001
-+#define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
-+
-+
-+// PHY Types
-+enum {
-+ PHY_LAN83C183 = 1, // LAN91C111 Internal PHY
-+ PHY_LAN83C180
-+};
-+
-+
-+// PHY Register Addresses (LAN91C111 Internal PHY)
-+
-+// PHY Control Register
-+#define PHY_CNTL_REG 0x00
-+#define PHY_CNTL_RST 0x8000 // 1=PHY Reset
-+#define PHY_CNTL_LPBK 0x4000 // 1=PHY Loopback
-+#define PHY_CNTL_SPEED 0x2000 // 1=100Mbps, 0=10Mpbs
-+#define PHY_CNTL_ANEG_EN 0x1000 // 1=Enable Auto negotiation
-+#define PHY_CNTL_PDN 0x0800 // 1=PHY Power Down mode
-+#define PHY_CNTL_MII_DIS 0x0400 // 1=MII 4 bit interface disabled
-+#define PHY_CNTL_ANEG_RST 0x0200 // 1=Reset Auto negotiate
-+#define PHY_CNTL_DPLX 0x0100 // 1=Full Duplex, 0=Half Duplex
-+#define PHY_CNTL_COLTST 0x0080 // 1= MII Colision Test
-+
-+// PHY Status Register
-+#define PHY_STAT_REG 0x01
-+#define PHY_STAT_CAP_T4 0x8000 // 1=100Base-T4 capable
-+#define PHY_STAT_CAP_TXF 0x4000 // 1=100Base-X full duplex capable
-+#define PHY_STAT_CAP_TXH 0x2000 // 1=100Base-X half duplex capable
-+#define PHY_STAT_CAP_TF 0x1000 // 1=10Mbps full duplex capable
-+#define PHY_STAT_CAP_TH 0x0800 // 1=10Mbps half duplex capable
-+#define PHY_STAT_CAP_SUPR 0x0040 // 1=recv mgmt frames with not preamble
-+#define PHY_STAT_ANEG_ACK 0x0020 // 1=ANEG has completed
-+#define PHY_STAT_REM_FLT 0x0010 // 1=Remote Fault detected
-+#define PHY_STAT_CAP_ANEG 0x0008 // 1=Auto negotiate capable
-+#define PHY_STAT_LINK 0x0004 // 1=valid link
-+#define PHY_STAT_JAB 0x0002 // 1=10Mbps jabber condition
-+#define PHY_STAT_EXREG 0x0001 // 1=extended registers implemented
-+
-+// PHY Identifier Registers
-+#define PHY_ID1_REG 0x02 // PHY Identifier 1
-+#define PHY_ID2_REG 0x03 // PHY Identifier 2
-+
-+// PHY Auto-Negotiation Advertisement Register
-+#define PHY_AD_REG 0x04
-+#define PHY_AD_NP 0x8000 // 1=PHY requests exchange of Next Page
-+#define PHY_AD_ACK 0x4000 // 1=got link code word from remote
-+#define PHY_AD_RF 0x2000 // 1=advertise remote fault
-+#define PHY_AD_T4 0x0200 // 1=PHY is capable of 100Base-T4
-+#define PHY_AD_TX_FDX 0x0100 // 1=PHY is capable of 100Base-TX FDPLX
-+#define PHY_AD_TX_HDX 0x0080 // 1=PHY is capable of 100Base-TX HDPLX
-+#define PHY_AD_10_FDX 0x0040 // 1=PHY is capable of 10Base-T FDPLX
-+#define PHY_AD_10_HDX 0x0020 // 1=PHY is capable of 10Base-T HDPLX
-+#define PHY_AD_CSMA 0x0001 // 1=PHY is capable of 802.3 CMSA
-+
-+// PHY Auto-negotiation Remote End Capability Register
-+#define PHY_RMT_REG 0x05
-+// Uses same bit definitions as PHY_AD_REG
-+
-+// PHY Configuration Register 1
-+#define PHY_CFG1_REG 0x10
-+#define PHY_CFG1_LNKDIS 0x8000 // 1=Rx Link Detect Function disabled
-+#define PHY_CFG1_XMTDIS 0x4000 // 1=TP Transmitter Disabled
-+#define PHY_CFG1_XMTPDN 0x2000 // 1=TP Transmitter Powered Down
-+#define PHY_CFG1_BYPSCR 0x0400 // 1=Bypass scrambler/descrambler
-+#define PHY_CFG1_UNSCDS 0x0200 // 1=Unscramble Idle Reception Disable
-+#define PHY_CFG1_EQLZR 0x0100 // 1=Rx Equalizer Disabled
-+#define PHY_CFG1_CABLE 0x0080 // 1=STP(150ohm), 0=UTP(100ohm)
-+#define PHY_CFG1_RLVL0 0x0040 // 1=Rx Squelch level reduced by 4.5db
-+#define PHY_CFG1_TLVL_SHIFT 2 // Transmit Output Level Adjust
-+#define PHY_CFG1_TLVL_MASK 0x003C
-+#define PHY_CFG1_TRF_MASK 0x0003 // Transmitter Rise/Fall time
-+
-+
-+// PHY Configuration Register 2
-+#define PHY_CFG2_REG 0x11
-+#define PHY_CFG2_APOLDIS 0x0020 // 1=Auto Polarity Correction disabled
-+#define PHY_CFG2_JABDIS 0x0010 // 1=Jabber disabled
-+#define PHY_CFG2_MREG 0x0008 // 1=Multiple register access (MII mgt)
-+#define PHY_CFG2_INTMDIO 0x0004 // 1=Interrupt signaled with MDIO pulseo
-+
-+// PHY Status Output (and Interrupt status) Register
-+#define PHY_INT_REG 0x12 // Status Output (Interrupt Status)
-+#define PHY_INT_INT 0x8000 // 1=bits have changed since last read
-+#define PHY_INT_LNKFAIL 0x4000 // 1=Link Not detected
-+#define PHY_INT_LOSSSYNC 0x2000 // 1=Descrambler has lost sync
-+#define PHY_INT_CWRD 0x1000 // 1=Invalid 4B5B code detected on rx
-+#define PHY_INT_SSD 0x0800 // 1=No Start Of Stream detected on rx
-+#define PHY_INT_ESD 0x0400 // 1=No End Of Stream detected on rx
-+#define PHY_INT_RPOL 0x0200 // 1=Reverse Polarity detected
-+#define PHY_INT_JAB 0x0100 // 1=Jabber detected
-+#define PHY_INT_SPDDET 0x0080 // 1=100Base-TX mode, 0=10Base-T mode
-+#define PHY_INT_DPLXDET 0x0040 // 1=Device in Full Duplex
-+
-+// PHY Interrupt/Status Mask Register
-+#define PHY_MASK_REG 0x13 // Interrupt Mask
-+// Uses the same bit definitions as PHY_INT_REG
-+
-+
-+/*
-+ * SMC91C96 ethernet config and status registers.
-+ * These are in the "attribute" space.
-+ */
-+#define ECOR 0x8000
-+#define ECOR_RESET 0x80
-+#define ECOR_LEVEL_IRQ 0x40
-+#define ECOR_WR_ATTRIB 0x04
-+#define ECOR_ENABLE 0x01
-+
-+#define ECSR 0x8002
-+#define ECSR_IOIS8 0x20
-+#define ECSR_PWRDWN 0x04
-+#define ECSR_INT 0x02
-+
-+
-+/*
-+ * Macros to abstract register access according to the data bus
-+ * capabilities. Please try to use those and not the in/out primitives.
-+ * Note: the following macros do *not* select the bank -- this must
-+ * be done separately as needed in the main code. The SMC_REG() macro
-+ * only uses the bank argument for debugging purposes.
-+ */
-+
-+#if SMC_DEBUG > 0
-+#define SMC_REG(reg, bank) \
-+ ({ \
-+ int __b = SMC_CURRENT_BANK(); \
-+ if ((__b & ~0xf0) != (0x3300 | bank)) { \
-+ printk( "%s: bank reg screwed (0x%04x)\n", \
-+ CARDNAME, __b ); \
-+ BUG(); \
-+ } \
-+ reg<<SMC_IO_SHIFT; \
-+ })
-+#else
-+#define SMC_REG(reg, bank) (reg<<SMC_IO_SHIFT)
-+#endif
-+
-+#if SMC_CAN_USE_8BIT
-+#define SMC_GET_PN() SMC_inb( ioaddr, PN_REG )
-+#define SMC_SET_PN(x) SMC_outb( x, ioaddr, PN_REG )
-+#define SMC_GET_AR() SMC_inb( ioaddr, AR_REG )
-+#define SMC_GET_TXFIFO() SMC_inb( ioaddr, TXFIFO_REG )
-+#define SMC_GET_RXFIFO() SMC_inb( ioaddr, RXFIFO_REG )
-+#define SMC_GET_INT() SMC_inb( ioaddr, INT_REG )
-+#define SMC_ACK_INT(x) SMC_outb( x, ioaddr, INT_REG )
-+#define SMC_GET_INT_MASK() SMC_inb( ioaddr, IM_REG )
-+#define SMC_SET_INT_MASK(x) SMC_outb( x, ioaddr, IM_REG )
-+#else
-+#define SMC_GET_PN() (SMC_inw( ioaddr, PN_REG ) & 0xFF)
-+#define SMC_SET_PN(x) SMC_outw( x, ioaddr, PN_REG )
-+#define SMC_GET_AR() (SMC_inw( ioaddr, PN_REG ) >> 8)
-+#define SMC_GET_TXFIFO() (SMC_inw( ioaddr, TXFIFO_REG ) & 0xFF)
-+#define SMC_GET_RXFIFO() (SMC_inw( ioaddr, TXFIFO_REG ) >> 8)
-+#define SMC_GET_INT() (SMC_inw( ioaddr, INT_REG ) & 0xFF)
-+#define SMC_ACK_INT(x) \
-+ do { \
-+ unsigned long __flags; \
-+ int __mask; \
-+ local_irq_save(__flags); \
-+ __mask = SMC_inw( ioaddr, INT_REG ) & ~0xff; \
-+ SMC_outw( __mask | (x), ioaddr, INT_REG ); \
-+ local_irq_restore(__flags); \
-+ } while (0)
-+#define SMC_GET_INT_MASK() (SMC_inw( ioaddr, INT_REG ) >> 8)
-+#define SMC_SET_INT_MASK(x) SMC_outw( (x) << 8, ioaddr, INT_REG )
-+#endif
-+
-+#define SMC_CURRENT_BANK() SMC_inw( ioaddr, BANK_SELECT )
-+#define SMC_SELECT_BANK(x) SMC_outw( x, ioaddr, BANK_SELECT )
-+#define SMC_GET_BASE() SMC_inw( ioaddr, BASE_REG )
-+#define SMC_SET_BASE(x) SMC_outw( x, ioaddr, BASE_REG )
-+#define SMC_GET_CONFIG() SMC_inw( ioaddr, CONFIG_REG )
-+#define SMC_SET_CONFIG(x) SMC_outw( x, ioaddr, CONFIG_REG )
-+#define SMC_GET_COUNTER() SMC_inw( ioaddr, COUNTER_REG )
-+#define SMC_GET_CTL() SMC_inw( ioaddr, CTL_REG )
-+#define SMC_SET_CTL(x) SMC_outw( x, ioaddr, CTL_REG )
-+#define SMC_GET_MII() SMC_inw( ioaddr, MII_REG )
-+#define SMC_SET_MII(x) SMC_outw( x, ioaddr, MII_REG )
-+#define SMC_GET_MIR() SMC_inw( ioaddr, MIR_REG )
-+#define SMC_SET_MIR(x) SMC_outw( x, ioaddr, MIR_REG )
-+#define SMC_GET_MMU_CMD() SMC_inw( ioaddr, MMU_CMD_REG )
-+#define SMC_SET_MMU_CMD(x) SMC_outw( x, ioaddr, MMU_CMD_REG )
-+#define SMC_GET_FIFO() SMC_inw( ioaddr, FIFO_REG )
-+#define SMC_GET_PTR() SMC_inw( ioaddr, PTR_REG )
-+#define SMC_SET_PTR(x) SMC_outw( x, ioaddr, PTR_REG )
-+#define SMC_GET_RCR() SMC_inw( ioaddr, RCR_REG )
-+#define SMC_SET_RCR(x) SMC_outw( x, ioaddr, RCR_REG )
-+#define SMC_GET_REV() SMC_inw( ioaddr, REV_REG )
-+#define SMC_GET_RPC() SMC_inw( ioaddr, RPC_REG )
-+#define SMC_SET_RPC(x) SMC_outw( x, ioaddr, RPC_REG )
-+#define SMC_GET_TCR() SMC_inw( ioaddr, TCR_REG )
-+#define SMC_SET_TCR(x) SMC_outw( x, ioaddr, TCR_REG )
-+
-+#ifndef SMC_GET_MAC_ADDR
-+#define SMC_GET_MAC_ADDR(addr) \
-+ do { \
-+ unsigned int __v; \
-+ __v = SMC_inw( ioaddr, ADDR0_REG ); \
-+ addr[0] = __v; addr[1] = __v >> 8; \
-+ __v = SMC_inw( ioaddr, ADDR1_REG ); \
-+ addr[2] = __v; addr[3] = __v >> 8; \
-+ __v = SMC_inw( ioaddr, ADDR2_REG ); \
-+ addr[4] = __v; addr[5] = __v >> 8; \
-+ } while (0)
-+#endif
-+
-+#define SMC_SET_MAC_ADDR(addr) \
-+ do { \
-+ SMC_outw( addr[0]|(addr[1] << 8), ioaddr, ADDR0_REG ); \
-+ SMC_outw( addr[2]|(addr[3] << 8), ioaddr, ADDR1_REG ); \
-+ SMC_outw( addr[4]|(addr[5] << 8), ioaddr, ADDR2_REG ); \
-+ } while (0)
-+
-+#define SMC_CLEAR_MCAST() \
-+ do { \
-+ SMC_outw( 0, ioaddr, MCAST_REG1 ); \
-+ SMC_outw( 0, ioaddr, MCAST_REG2 ); \
-+ SMC_outw( 0, ioaddr, MCAST_REG3 ); \
-+ SMC_outw( 0, ioaddr, MCAST_REG4 ); \
-+ } while (0)
-+#define SMC_SET_MCAST(x) \
-+ do { \
-+ unsigned char *mt = (x); \
-+ SMC_outw( mt[0] | (mt[1] << 8), ioaddr, MCAST_REG1 ); \
-+ SMC_outw( mt[2] | (mt[3] << 8), ioaddr, MCAST_REG2 ); \
-+ SMC_outw( mt[4] | (mt[5] << 8), ioaddr, MCAST_REG3 ); \
-+ SMC_outw( mt[6] | (mt[7] << 8), ioaddr, MCAST_REG4 ); \
-+ } while (0)
-+
-+#if SMC_CAN_USE_32BIT
-+/*
-+ * Some setups just can't write 8 or 16 bits reliably when not aligned
-+ * to a 32 bit boundary. I tell you that exists!
-+ * We do the ones that can have their low parts written to 0 here.
-+ */
-+#undef SMC_SELECT_BANK
-+#define SMC_SELECT_BANK(x) SMC_outl( (x)<<16, ioaddr, 12<<SMC_IO_SHIFT )
-+#undef SMC_SET_RPC
-+#define SMC_SET_RPC(x) SMC_outl( (x)<<16, ioaddr, SMC_REG(8, 0) )
-+#undef SMC_SET_PN
-+#define SMC_SET_PN(x) SMC_outl( (x)<<16, ioaddr, SMC_REG(0, 2) )
-+#undef SMC_SET_PTR
-+#define SMC_SET_PTR(x) SMC_outl( (x)<<16, ioaddr, SMC_REG(4, 2) )
-+#endif
-+
-+#if SMC_CAN_USE_32BIT
-+#define SMC_PUT_PKT_HDR(status, length) \
-+ SMC_outl( (status) | (length) << 16, ioaddr, DATA_REG )
-+#define SMC_GET_PKT_HDR(status, length) \
-+ do { \
-+ unsigned int __val = SMC_inl( ioaddr, DATA_REG ); \
-+ (status) = __val & 0xffff; \
-+ (length) = __val >> 16; \
-+ } while (0)
-+#else
-+#define SMC_PUT_PKT_HDR(status, length) \
-+ do { \
-+ SMC_outw( status, ioaddr, DATA_REG ); \
-+ SMC_outw( length, ioaddr, DATA_REG ); \
-+ } while (0)
-+#define SMC_GET_PKT_HDR(status, length) \
-+ do { \
-+ (status) = SMC_inw( ioaddr, DATA_REG ); \
-+ (length) = SMC_inw( ioaddr, DATA_REG ); \
-+ } while (0)
-+#endif
-+
-+#if SMC_CAN_USE_32BIT
-+#define SMC_PUSH_DATA(p, l) \
-+ do { \
-+ char *__ptr = (p); \
-+ int __len = (l); \
-+ if (__len >= 2 && (long)__ptr & 2) { \
-+ __len -= 2; \
-+ SMC_outw( *((u16 *)__ptr)++, ioaddr, DATA_REG );\
-+ } \
-+ SMC_outsl( ioaddr, DATA_REG, __ptr, __len >> 2); \
-+ if (__len & 2) { \
-+ __ptr += (__len & ~3); \
-+ SMC_outw( *((u16 *)__ptr), ioaddr, DATA_REG ); \
-+ } \
-+ } while (0)
-+#define SMC_PULL_DATA(p, l) \
-+ do { \
-+ char *__ptr = (p); \
-+ int __len = (l); \
-+ if ((long)__ptr & 2) { \
-+ /* \
-+ * We want 32bit alignment here. \
-+ * Since some buses perform a full 32bit \
-+ * fetch even for 16bit data we can't use \
-+ * SMC_inw() here. Back both source (on chip \
-+ * and destination) pointers of 2 bytes. \
-+ */ \
-+ (long)__ptr &= ~2; \
-+ __len += 2; \
-+ SMC_SET_PTR( 2|PTR_READ|PTR_RCV|PTR_AUTOINC ); \
-+ } \
-+ __len += 2; \
-+ SMC_insl( ioaddr, DATA_REG, __ptr, __len >> 2); \
-+ } while (0)
-+#elif SMC_CAN_USE_16BIT
-+#define SMC_PUSH_DATA(p, l) SMC_outsw( ioaddr, DATA_REG, p, (l) >> 1 )
-+#define SMC_PULL_DATA(p, l) SMC_insw ( ioaddr, DATA_REG, p, (l) >> 1 )
-+#elif SMC_CAN_USE_8BIT
-+#define SMC_PUSH_DATA(p, l) SMC_outsb( ioaddr, DATA_REG, p, l )
-+#define SMC_PULL_DATA(p, l) SMC_insb ( ioaddr, DATA_REG, p, l )
-+#endif
-+
-+#if ! SMC_CAN_USE_16BIT
-+#define SMC_outw(x, ioaddr, reg) \
-+ do { \
-+ unsigned int __val16 = (x); \
-+ SMC_outb( __val16, ioaddr, reg ); \
-+ SMC_outb( __val16 >> 8, ioaddr, reg + 1 ); \
-+ } while (0)
-+#define SMC_inw(ioaddr, reg) \
-+ ({ \
-+ unsigned int __val16; \
-+ __val16 = SMC_inb( ioaddr, reg ); \
-+ __val16 |= SMC_inb( ioaddr, reg + 1 ) << 8; \
-+ __val16; \
-+ })
-+#endif
-+
-+
-+#endif /* _SMC91X_H_ */
---- linux-2.4.25/drivers/pcmcia/Config.in~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/Config.in 2004-03-31 17:15:12.000000000 +0200
-@@ -45,6 +45,7 @@
- if [ "$CONFIG_ARM" = "y" ]; then
- dep_tristate ' CLPS6700 support' CONFIG_PCMCIA_CLPS6700 $CONFIG_ARCH_CLPS711X $CONFIG_PCMCIA
- dep_tristate ' SA1100 support' CONFIG_PCMCIA_SA1100 $CONFIG_ARCH_SA1100 $CONFIG_PCMCIA
-+ dep_tristate ' PXA250/210 support' CONFIG_PCMCIA_PXA $CONFIG_ARCH_PXA $CONFIG_PCMCIA
- fi
-
- endmenu
---- linux-2.4.25/drivers/pcmcia/Makefile~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/Makefile 2004-03-31 17:15:12.000000000 +0200
-@@ -94,6 +94,11 @@
-
- obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o
-
-+subdir-$(CONFIG_PCMCIA_PXA) += pxa
-+ifeq ($(CONFIG_PCMCIA_PXA),y)
-+ obj-y += pxa/pxa_cs.o
-+endif
-+
- include $(TOPDIR)/Rules.make
-
- pcmcia_core.o: $(pcmcia_core-objs)
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/pxa/Makefile 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,18 @@
-+#
-+# Makefile for the Intel PXA250/210 PCMCIA driver
-+#
-+# Note! Dependencies are done automagically by 'make dep', which also
-+# removes any old dependencies. DON'T put your own dependencies here
-+# unless it's something special (ie not a .c file).
-+
-+O_TARGET := pxa_cs.o
-+
-+obj-y := pxa.o
-+obj-$(CONFIG_ARCH_LUBBOCK) += lubbock.o
-+obj-$(CONFIG_ARCH_PXA_IDP) += pxa_idp.o
-+obj-$(CONFIG_ARCH_TRIZEPS2) += trizeps2.o
-+obj-$(CONFIG_ARCH_PXA_CERF) += ../sa1100_cerf.o
-+
-+obj-m := $(O_TARGET)
-+
-+include $(TOPDIR)/Rules.make
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/pxa/lubbock.c 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,329 @@
-+/*
-+ * linux/drivers/pcmcia/pxa/lubbock.c
-+ *
-+ * Author: George Davis
-+ * Created: Jan 10, 2002
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Originally based upon linux/drivers/pcmcia/sa1100_neponset.c
-+ *
-+ * Lubbock PCMCIA specific routines.
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+
-+#include <pcmcia/ss.h>
-+
-+#include <asm/delay.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/arch/pcmcia.h>
-+#include <asm/hardware/sa1111.h>
-+
-+/*
-+ * I'd really like to move the INTPOL stuff to arch/arm/mach-sa1100/sa1111.c
-+ * ... and maybe even arch/arm/mach-pxa/sa1111.c now too! : )
-+ */
-+#define SA1111_IRQMASK_LO(x) (1 << (x - IRQ_SA1111_START))
-+#define SA1111_IRQMASK_HI(x) (1 << (x - IRQ_SA1111_START - 32))
-+
-+static int lubbock_pcmcia_init(struct pcmcia_init *init){
-+ int return_val=0;
-+
-+ /* Set PCMCIA Socket 0 power to standby mode.
-+ */
-+ PA_DWR &= ~(GPIO_bit(0) | GPIO_bit(1) | GPIO_bit(2) | GPIO_bit(3));
-+
-+ /* Set GPIO_A<3:0> to be outputs for PCMCIA (socket 0) power controller.
-+ * Note that this is done only after first initializing GPIO_A<3:0>
-+ * output state above to be certain that we drive signals to the same
-+ * state as the pull-downs connected to these lines. The pull-downs are
-+ * req'd to make sure PCMCIA power is OFF until we can get around to
-+ * setting up the GPIO_A<3:0> state and direction.
-+ */
-+ PA_DDR &= ~(GPIO_bit(0) | GPIO_bit(1) | GPIO_bit(2) | GPIO_bit(3));
-+
-+ /* Set CF Socket 1 power to standby mode. */
-+ LUB_MISC_WR &= ~(GPIO_bit(15) | GPIO_bit(14));
-+
-+ INTPOL1 |= SA1111_IRQMASK_HI(S0_READY_NINT) |
-+ SA1111_IRQMASK_HI(S1_READY_NINT) |
-+ SA1111_IRQMASK_HI(S0_CD_VALID) |
-+ SA1111_IRQMASK_HI(S1_CD_VALID) |
-+ SA1111_IRQMASK_HI(S0_BVD1_STSCHG) |
-+ SA1111_IRQMASK_HI(S1_BVD1_STSCHG);
-+
-+#warning what if a request_irq fails?
-+ return_val+=request_irq(S0_CD_VALID, init->handler, SA_INTERRUPT,
-+ "Lubbock PCMCIA (0) CD", NULL);
-+ return_val+=request_irq(S1_CD_VALID, init->handler, SA_INTERRUPT,
-+ "Lubbock CF (1) CD", NULL);
-+ return_val+=request_irq(S0_BVD1_STSCHG, init->handler, SA_INTERRUPT,
-+ "Lubbock PCMCIA (0) BVD1", NULL);
-+ return_val+=request_irq(S1_BVD1_STSCHG, init->handler, SA_INTERRUPT,
-+ "Lubbock CF (1) BVD1", NULL);
-+
-+ return (return_val<0) ? -1 : 2;
-+}
-+
-+static int lubbock_pcmcia_shutdown(void){
-+
-+ free_irq(S0_CD_VALID, NULL);
-+ free_irq(S1_CD_VALID, NULL);
-+ free_irq(S0_BVD1_STSCHG, NULL);
-+ free_irq(S1_BVD1_STSCHG, NULL);
-+
-+ INTPOL1 &= ~(SA1111_IRQMASK_HI(S0_CD_VALID) |
-+ SA1111_IRQMASK_HI(S1_CD_VALID) |
-+ SA1111_IRQMASK_HI(S0_BVD1_STSCHG) |
-+ SA1111_IRQMASK_HI(S1_BVD1_STSCHG));
-+
-+ return 0;
-+}
-+
-+static int lubbock_pcmcia_socket_state(struct pcmcia_state_array
-+ *state_array){
-+ unsigned long status;
-+ int return_val=1;
-+
-+ if(state_array->size<2) return -1;
-+
-+ memset(state_array->state, 0,
-+ (state_array->size)*sizeof(struct pcmcia_state));
-+
-+ status=PCSR;
-+
-+ state_array->state[0].detect=((status & PCSR_S0_DETECT)==0)?1:0;
-+
-+ state_array->state[0].ready=((status & PCSR_S0_READY)==0)?0:1;
-+
-+ state_array->state[0].bvd1=((status & PCSR_S0_BVD1)==0)?0:1;
-+
-+ state_array->state[0].bvd2=((status & PCSR_S0_BVD2)==0)?0:1;
-+
-+ state_array->state[0].wrprot=((status & PCSR_S0_WP)==0)?0:1;
-+
-+ state_array->state[0].vs_3v=((status & PCSR_S0_VS1)==0)?1:0;
-+
-+ state_array->state[0].vs_Xv=((status & PCSR_S0_VS2)==0)?1:0;
-+
-+ state_array->state[1].detect=((status & PCSR_S1_DETECT)==0)?1:0;
-+
-+ state_array->state[1].ready=((status & PCSR_S1_READY)==0)?0:1;
-+
-+ state_array->state[1].bvd1=((status & PCSR_S1_BVD1)==0)?0:1;
-+
-+ state_array->state[1].bvd2=((status & PCSR_S1_BVD2)==0)?0:1;
-+
-+ state_array->state[1].wrprot=((status & PCSR_S1_WP)==0)?0:1;
-+
-+ state_array->state[1].vs_3v=((status & PCSR_S1_VS1)==0)?1:0;
-+
-+ state_array->state[1].vs_Xv=((status & PCSR_S1_VS2)==0)?1:0;
-+
-+ return return_val;
-+}
-+
-+static int lubbock_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
-+
-+ switch(info->sock){
-+ case 0:
-+ info->irq=S0_READY_NINT;
-+ break;
-+
-+ case 1:
-+ info->irq=S1_READY_NINT;
-+ break;
-+
-+ default:
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+lubbock_pcmcia_configure_socket(unsigned int sock, socket_state_t *state)
-+{
-+ unsigned long flags, pccr, gpio, misc_wr, status;
-+ int ret=1;
-+
-+ local_irq_save(flags);
-+
-+ pccr=PCCR;
-+ gpio=PA_DWR;
-+ misc_wr = LUB_MISC_WR;
-+
-+ /* Lubbock uses the Maxim MAX1602, with the following connections:
-+ *
-+ * Socket 0 (PCMCIA):
-+ * MAX1602 Lubbock Register
-+ * Pin Signal
-+ * ----- ------- ----------------------
-+ * A0VPP S0_PWR0 SA-1111 GPIO A<0>
-+ * A1VPP S0_PWR1 SA-1111 GPIO A<1>
-+ * A0VCC S0_PWR2 SA-1111 GPIO A<2>
-+ * A1VCC S0_PWR3 SA-1111 GPIO A<3>
-+ * VX VCC
-+ * VY +3.3V
-+ * 12IN +12V
-+ * CODE +3.3V Cirrus Code, CODE = High (VY)
-+ *
-+ * Socket 1 (CF):
-+ * MAX1602 Lubbock Register
-+ * Pin Signal
-+ * ----- ------- ----------------------
-+ * A0VPP GND VPP is not connected
-+ * A1VPP GND VPP is not connected
-+ * A0VCC S1_PWR0 MISC_WR<14>
-+ * A1VCC S1_PWR0 MISC_WR<15>
-+ * VX VCC
-+ * VY +3.3V
-+ * 12IN GND VPP is not connected
-+ * CODE +3.3V Cirrus Code, CODE = High (VY)
-+ *
-+ */
-+
-+again:
-+ switch(sock){
-+ case 0:
-+
-+ switch(state->Vcc){
-+ case 0:
-+ pccr = (pccr & ~PCCR_S0_FLT);
-+ gpio &= ~(GPIO_bit(2) | GPIO_bit(3));
-+ break;
-+
-+ case 33:
-+ pccr = (pccr & ~PCCR_S0_PSE) | PCCR_S0_FLT | PCCR_S0_PWAITEN;
-+ gpio = (gpio & ~(GPIO_bit(2) | GPIO_bit(3))) | GPIO_bit(3);
-+ break;
-+
-+ case 50:
-+ pccr = (pccr | PCCR_S0_PSE | PCCR_S0_FLT | PCCR_S0_PWAITEN);
-+ gpio = (gpio & ~(GPIO_bit(2) | GPIO_bit(3))) | GPIO_bit(2);
-+ break;
-+
-+ default:
-+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__, state->Vcc);
-+ ret = -1;
-+ break;
-+ }
-+
-+ switch(state->Vpp){
-+ case 0:
-+ gpio &= ~(GPIO_bit(0) | GPIO_bit(1));
-+ break;
-+
-+ case 120:
-+ gpio = (gpio & ~(GPIO_bit(0) | GPIO_bit(1))) | GPIO_bit(1);
-+ break;
-+
-+ default:
-+ /* REVISIT: I'm not sure about this? Is this correct?
-+ Is it always safe or do we have potential problems
-+ with bogus combinations of Vcc and Vpp settings? */
-+ if(state->Vpp == state->Vcc)
-+ gpio = (gpio & ~(GPIO_bit(0) | GPIO_bit(1))) | GPIO_bit(0);
-+ else {
-+ printk(KERN_ERR "%s(): unrecognized Vpp %u\n", __FUNCTION__, state->Vpp);
-+ ret = -1;
-+ break;
-+ }
-+ }
-+
-+ pccr = (state->flags&SS_RESET) ? (pccr|PCCR_S0_RST) : (pccr&~PCCR_S0_RST);
-+
-+ break;
-+
-+ case 1:
-+ switch(state->Vcc){
-+ case 0:
-+ pccr = (pccr & ~PCCR_S1_FLT);
-+ misc_wr &= ~((1 << 15) | (1 << 14));
-+ break;
-+
-+ case 33:
-+ pccr = (pccr & ~PCCR_S1_PSE) | PCCR_S1_FLT | PCCR_S1_PWAITEN;
-+ misc_wr = (misc_wr & ~(1 << 15)) | (1 << 14);
-+ gpio = (gpio & ~(GPIO_bit(2) | GPIO_bit(3))) | GPIO_bit(2);
-+ break;
-+
-+ case 50:
-+ pccr = (pccr | PCCR_S1_PSE | PCCR_S1_FLT | PCCR_S1_PWAITEN);
-+ misc_wr = (misc_wr & ~(1 << 15)) | (1 << 14);
-+ break;
-+
-+ default:
-+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__, state->Vcc);
-+ ret = -1;
-+ break;
-+ }
-+
-+ if(state->Vpp!=state->Vcc && state->Vpp!=0){
-+ printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", __FUNCTION__, state->Vpp);
-+ ret = -1;
-+ break;
-+ }
-+
-+ pccr = (state->flags&SS_RESET) ? (pccr|PCCR_S1_RST) : (pccr&~PCCR_S1_RST);
-+
-+ break;
-+
-+ default:
-+ ret = -1;
-+ }
-+
-+ if (ret >= 0) {
-+ PCCR = pccr;
-+ LUB_MISC_WR = misc_wr;
-+ PA_DWR = gpio;
-+ }
-+
-+ if (ret > 0) {
-+ ret = 0;
-+ /*
-+ * HACK ALERT:
-+ * We can't sense the voltage properly on Lubbock before actually
-+ * applying some power to the socket (catch 22).
-+ * Resense the socket Voltage Sense pins after applying socket power.
-+ */
-+ if (sock == 0)
-+ status = PCSR & (PCSR_S0_VS1 | PCSR_S0_VS2);
-+ else
-+ status = PCSR & (PCSR_S1_VS1 | PCSR_S1_VS2);
-+
-+ if ((status == (PCSR_S0_VS1 | PCSR_S0_VS2)) && (state->Vcc == 33)) {
-+ /* Switch to 5V, Configure socket 0 with 5V voltage */
-+ PA_DWR &= ~(GPIO_bit(0) | GPIO_bit(1) | GPIO_bit(2) | GPIO_bit(3));
-+ PA_DDR &= ~(GPIO_bit(0) | GPIO_bit(1) | GPIO_bit(2) | GPIO_bit(3));
-+ state->Vcc = 50;
-+ state->Vpp = 50;
-+ goto again;
-+ }
-+ if ((status == (PCSR_S1_VS1 | PCSR_S1_VS2)) && (state->Vcc == 33)) {
-+ /* Switch to 5V, Configure socket 1 with 5V voltage */
-+ LUB_MISC_WR &= ~((1 << 15) | (1 << 14));
-+ state->Vcc = 50;
-+ state->Vpp = 50;
-+ goto again;
-+ }
-+ }
-+
-+ local_irq_restore(flags);
-+ return ret;
-+}
-+
-+struct pcmcia_low_level lubbock_pcmcia_ops = {
-+ lubbock_pcmcia_init,
-+ lubbock_pcmcia_shutdown,
-+ lubbock_pcmcia_socket_state,
-+ lubbock_pcmcia_get_irq_info,
-+ lubbock_pcmcia_configure_socket
-+};
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/pxa/pxa.c 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,1247 @@
-+/*
-+ * linux/drivers/pcmcia/pxa/pxa.c
-+ *
-+ * Author: George Davis
-+ * Created: Jan 10, 2002
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Originally based upon linux/drivers/pcmcia/sa1100_generic.c
-+ *
-+ */
-+
-+/*======================================================================
-+
-+ Device driver for the PCMCIA control functionality of Intel
-+ PXA250/210 microprocessors.
-+
-+ The contents of this file are subject to the Mozilla Public
-+ License Version 1.1 (the "License"); you may not use this file
-+ except in compliance with the License. You may obtain a copy of
-+ the License at http://www.mozilla.org/MPL/
-+
-+ Software distributed under the License is distributed on an "AS
-+ IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ implied. See the License for the specific language governing
-+ rights and limitations under the License.
-+
-+ The initial developer of the original code is John G. Dorsey
-+ <john+@cs.cmu.edu>. Portions created by John G. Dorsey are
-+ Copyright (C) 1999 John G. Dorsey. All Rights Reserved.
-+
-+ Alternatively, the contents of this file may be used under the
-+ terms of the GNU Public License version 2 (the "GPL"), in which
-+ case the provisions of the GPL are applicable instead of the
-+ above. If you wish to allow the use of your version of this file
-+ only under the terms of the GPL and not to allow others to use
-+ your version of this file under the MPL, indicate your decision
-+ by deleting the provisions above and replace them with the notice
-+ and other provisions required by the GPL. If you do not delete
-+ the provisions above, a recipient may use your version of this
-+ file under either the MPL or the GPL.
-+
-+======================================================================*/
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/config.h>
-+#include <linux/cpufreq.h>
-+#include <linux/delay.h>
-+#include <linux/ioport.h>
-+#include <linux/kernel.h>
-+#include <linux/tqueue.h>
-+#include <linux/timer.h>
-+#include <linux/mm.h>
-+#include <linux/notifier.h>
-+#include <linux/proc_fs.h>
-+#include <linux/version.h>
-+#include <linux/cpufreq.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/ss.h>
-+#include <pcmcia/bus_ops.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/system.h>
-+#include <asm/arch/lubbock.h>
-+
-+#include "pxa.h"
-+
-+#ifdef PCMCIA_DEBUG
-+static int pc_debug;
-+#endif
-+
-+MODULE_AUTHOR("George Davis <davis_g@mvista.com>");
-+MODULE_DESCRIPTION("Linux PCMCIA Card Services: PXA250/210 Socket Controller");
-+
-+/* This structure maintains housekeeping state for each socket, such
-+ * as the last known values of the card detect pins, or the Card Services
-+ * callback value associated with the socket:
-+ */
-+static struct pxa_pcmcia_socket
-+pxa_pcmcia_socket[PXA_PCMCIA_MAX_SOCK];
-+
-+static int pxa_pcmcia_socket_count;
-+
-+
-+/* Returned by the low-level PCMCIA interface: */
-+static struct pcmcia_low_level *pcmcia_low_level;
-+
-+/* Event poll timer structure */
-+static struct timer_list poll_timer;
-+
-+
-+/* Prototypes for routines which are used internally: */
-+
-+static int pxa_pcmcia_driver_init(void);
-+static void pxa_pcmcia_driver_shutdown(void);
-+static void pxa_pcmcia_task_handler(void *data);
-+static void pxa_pcmcia_poll_event(unsigned long data);
-+static void pxa_pcmcia_interrupt(int irq, void *dev,
-+ struct pt_regs *regs);
-+static struct tq_struct pxa_pcmcia_task;
-+
-+#ifdef CONFIG_PROC_FS
-+static int pxa_pcmcia_proc_status(char *buf, char **start, off_t pos,
-+ int count, int *eof, void *data);
-+#endif
-+
-+
-+/* Prototypes for operations which are exported to the
-+ * new-and-impr^H^H^H^H^H^H^H^H^H^H in-kernel PCMCIA core:
-+ */
-+
-+static int pxa_pcmcia_init(unsigned int sock);
-+static int pxa_pcmcia_suspend(unsigned int sock);
-+static int pxa_pcmcia_register_callback(unsigned int sock,
-+ void (*handler)(void *,
-+ unsigned int),
-+ void *info);
-+static int pxa_pcmcia_inquire_socket(unsigned int sock,
-+ socket_cap_t *cap);
-+static int pxa_pcmcia_get_status(unsigned int sock, u_int *value);
-+static int pxa_pcmcia_get_socket(unsigned int sock,
-+ socket_state_t *state);
-+static int pxa_pcmcia_set_socket(unsigned int sock,
-+ socket_state_t *state);
-+static int pxa_pcmcia_get_io_map(unsigned int sock,
-+ struct pccard_io_map *io);
-+static int pxa_pcmcia_set_io_map(unsigned int sock,
-+ struct pccard_io_map *io);
-+static int pxa_pcmcia_get_mem_map(unsigned int sock,
-+ struct pccard_mem_map *mem);
-+static int pxa_pcmcia_set_mem_map(unsigned int sock,
-+ struct pccard_mem_map *mem);
-+#ifdef CONFIG_PROC_FS
-+static void pxa_pcmcia_proc_setup(unsigned int sock,
-+ struct proc_dir_entry *base);
-+#endif
-+
-+static struct pccard_operations pxa_pcmcia_operations = {
-+ pxa_pcmcia_init,
-+ pxa_pcmcia_suspend,
-+ pxa_pcmcia_register_callback,
-+ pxa_pcmcia_inquire_socket,
-+ pxa_pcmcia_get_status,
-+ pxa_pcmcia_get_socket,
-+ pxa_pcmcia_set_socket,
-+ pxa_pcmcia_get_io_map,
-+ pxa_pcmcia_set_io_map,
-+ pxa_pcmcia_get_mem_map,
-+ pxa_pcmcia_set_mem_map,
-+#ifdef CONFIG_PROC_FS
-+ pxa_pcmcia_proc_setup
-+#endif
-+};
-+
-+#ifdef CONFIG_CPU_FREQ
-+/* forward declaration */
-+static struct notifier_block pxa_pcmcia_notifier_block;
-+#endif
-+
-+
-+/* pxa_pcmcia_driver_init()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ *
-+ * This routine performs a basic sanity check to ensure that this
-+ * kernel has been built with the appropriate board-specific low-level
-+ * PCMCIA support, performs low-level PCMCIA initialization, registers
-+ * this socket driver with Card Services, and then spawns the daemon
-+ * thread which is the real workhorse of the socket driver.
-+ *
-+ * Please see linux/Documentation/arm/SA1100/PCMCIA for more information
-+ * on the low-level kernel interface.
-+ *
-+ * Returns: 0 on success, -1 on error
-+ */
-+static int __init pxa_pcmcia_driver_init(void){
-+ servinfo_t info;
-+ struct pcmcia_init pcmcia_init;
-+ struct pcmcia_state state[PXA_PCMCIA_MAX_SOCK];
-+ struct pcmcia_state_array state_array;
-+ unsigned int i, clock;
-+ unsigned long mecr;
-+
-+ printk(KERN_INFO "Intel PXA250/210 PCMCIA (CS release %s)\n", CS_RELEASE);
-+
-+ CardServices(GetCardServicesInfo, &info);
-+
-+ if(info.Revision!=CS_RELEASE_CODE){
-+ printk(KERN_ERR "Card Services release codes do not match\n");
-+ return -1;
-+ }
-+
-+ /* Setup GPIOs for PCMCIA/CF alternate function mode.
-+ *
-+ * It would be nice if set_GPIO_mode included support
-+ * for driving GPIO outputs to default high/low state
-+ * before programming GPIOs as outputs. Setting GPIO
-+ * outputs to default high/low state via GPSR/GPCR
-+ * before defining them as outputs should reduce
-+ * the possibility of glitching outputs during GPIO
-+ * setup. This of course assumes external terminators
-+ * are present to hold GPIOs in a defined state.
-+ *
-+ * In the meantime, setup default state of GPIO
-+ * outputs before we enable them as outputs.
-+ */
-+
-+ GPSR(GPIO48_nPOE) = GPIO_bit(GPIO48_nPOE) |
-+ GPIO_bit(GPIO49_nPWE) |
-+ GPIO_bit(GPIO50_nPIOR) |
-+ GPIO_bit(GPIO51_nPIOW) |
-+ GPIO_bit(GPIO52_nPCE_1) |
-+ GPIO_bit(GPIO53_nPCE_2);
-+
-+ set_GPIO_mode(GPIO48_nPOE_MD);
-+ set_GPIO_mode(GPIO49_nPWE_MD);
-+ set_GPIO_mode(GPIO50_nPIOR_MD);
-+ set_GPIO_mode(GPIO51_nPIOW_MD);
-+ set_GPIO_mode(GPIO52_nPCE_1_MD);
-+ set_GPIO_mode(GPIO53_nPCE_2_MD);
-+ set_GPIO_mode(GPIO54_pSKTSEL_MD); /* REVISIT: s/b dependent on num sockets */
-+ set_GPIO_mode(GPIO55_nPREG_MD);
-+ set_GPIO_mode(GPIO56_nPWAIT_MD);
-+ set_GPIO_mode(GPIO57_nIOIS16_MD);
-+
-+
-+ if(machine_is_lubbock()){
-+#if defined(CONFIG_ARCH_LUBBOCK) || defined(CONFIG_ARCH_CSB226)
-+ pcmcia_low_level=&lubbock_pcmcia_ops;
-+#endif
-+ } else if (machine_is_pxa_idp()) {
-+ pcmcia_low_level=&pxa_idp_pcmcia_ops;
-+ } else if( machine_is_pxa_cerf()){
-+ pcmcia_low_level=&cerf_pcmcia_ops;
-+ } else if (machine_is_trizeps2()){
-+#ifdef CONFIG_ARCH_TRIZEPS2
-+ pcmcia_low_level=&trizeps2_pcmcia_ops;
-+#endif
-+ }
-+
-+ if (!pcmcia_low_level) {
-+ printk(KERN_ERR "This hardware is not supported by the PXA250/210 Card Service driver\n");
-+ return -ENODEV;
-+ }
-+
-+ pcmcia_init.handler=pxa_pcmcia_interrupt;
-+
-+ if((pxa_pcmcia_socket_count=pcmcia_low_level->init(&pcmcia_init))<0){
-+ printk(KERN_ERR "Unable to initialize kernel PCMCIA service.\n");
-+ return -EIO;
-+ }
-+
-+ state_array.size=pxa_pcmcia_socket_count;
-+ state_array.state=state;
-+
-+ /* Configure MECR based on the number of sockets present. */
-+ if (pxa_pcmcia_socket_count == 2) {
-+ MECR |= GPIO_bit(0);
-+ } else {
-+ MECR &= ~GPIO_bit(0);
-+ }
-+
-+ if(pcmcia_low_level->socket_state(&state_array)<0){
-+ printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
-+ return -EIO;
-+ }
-+
-+ /* Well, it looks good to go. So we can now enable the PCMCIA
-+ * controller.
-+ */
-+ MECR |= GPIO_bit(1);
-+
-+ /* We need to initialize the MCXX registers to default values
-+ * here because we're not guaranteed to see a SetIOMap operation
-+ * at runtime.
-+ */
-+
-+ clock = get_lclk_frequency_10khz();
-+
-+ for(i=0; i<pxa_pcmcia_socket_count; ++i){
-+ pxa_pcmcia_socket[i].k_state=state[i];
-+
-+ /* This is an interim fix. Apparently, SetSocket is no longer
-+ * called to initialize each socket (prior to the first detect
-+ * event). For now, we'll just manually set up the mask.
-+ */
-+ pxa_pcmcia_socket[i].cs_state.csc_mask=SS_DETECT;
-+
-+ pxa_pcmcia_socket[i].virt_io=(i==0)?PCMCIA_IO_0_BASE:PCMCIA_IO_1_BASE;
-+ pxa_pcmcia_socket[i].phys_attr=_PCMCIAAttr(i);
-+ pxa_pcmcia_socket[i].phys_mem=_PCMCIAMem(i);
-+
-+ /* REVISIT: cleanup these macros */
-+ //MCIO_SET(i, PXA_PCMCIA_IO_ACCESS, clock);
-+ //MCATTR_SET(i, PXA_PCMCIA_5V_MEM_ACCESS, clock);
-+ //MCMEM_SET(i, PXA_PCMCIA_5V_MEM_ACCESS, clock);
-+
-+ pxa_pcmcia_socket[i].speed_io=PXA_PCMCIA_IO_ACCESS;
-+ pxa_pcmcia_socket[i].speed_attr=PXA_PCMCIA_ATTR_MEM_ACCESS;
-+ pxa_pcmcia_socket[i].speed_mem=PXA_PCMCIA_5V_MEM_ACCESS;
-+ }
-+
-+/* REVISIT: cleanup these macros */
-+MCMEM0 = ((pxa_mcxx_setup(PXA_PCMCIA_5V_MEM_ACCESS, clock)
-+ & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-+ | ((pxa_mcxx_asst(PXA_PCMCIA_5V_MEM_ACCESS, clock)
-+ & MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-+ | ((pxa_mcxx_hold(PXA_PCMCIA_5V_MEM_ACCESS, clock)
-+ & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
-+MCMEM1 = ((pxa_mcxx_setup(PXA_PCMCIA_5V_MEM_ACCESS, clock)
-+ & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-+ | ((pxa_mcxx_asst(PXA_PCMCIA_5V_MEM_ACCESS, clock)
-+ & MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-+ | ((pxa_mcxx_hold(PXA_PCMCIA_5V_MEM_ACCESS, clock)
-+ & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
-+MCATT0 = ((pxa_mcxx_setup(PXA_PCMCIA_ATTR_MEM_ACCESS, clock)
-+ & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-+ | ((pxa_mcxx_asst(PXA_PCMCIA_ATTR_MEM_ACCESS, clock)
-+ & MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-+ | ((pxa_mcxx_hold(PXA_PCMCIA_ATTR_MEM_ACCESS, clock)
-+ & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
-+MCATT1 = ((pxa_mcxx_setup(PXA_PCMCIA_ATTR_MEM_ACCESS, clock)
-+ & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-+ | ((pxa_mcxx_asst(PXA_PCMCIA_ATTR_MEM_ACCESS, clock)
-+ & MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-+ | ((pxa_mcxx_hold(PXA_PCMCIA_ATTR_MEM_ACCESS, clock)
-+ & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
-+MCIO0 = ((pxa_mcxx_setup(PXA_PCMCIA_IO_ACCESS, clock)
-+ & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-+ | ((pxa_mcxx_asst(PXA_PCMCIA_IO_ACCESS, clock)
-+ & MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-+ | ((pxa_mcxx_hold(PXA_PCMCIA_IO_ACCESS, clock)
-+ & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
-+MCIO1 = ((pxa_mcxx_setup(PXA_PCMCIA_IO_ACCESS, clock)
-+ & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-+ | ((pxa_mcxx_asst(PXA_PCMCIA_IO_ACCESS, clock)
-+ & MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-+ | ((pxa_mcxx_hold(PXA_PCMCIA_IO_ACCESS, clock)
-+ & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
-+
-+#ifdef CONFIG_CPU_FREQ
-+ if(cpufreq_register_notifier(&pxa_pcmcia_notifier_block) < 0){
-+ printk(KERN_ERR "Unable to register CPU frequency change notifier\n");
-+ return -ENXIO;
-+ }
-+#endif
-+
-+ /* Only advertise as many sockets as we can detect: */
-+ if(register_ss_entry(pxa_pcmcia_socket_count,
-+ &pxa_pcmcia_operations)<0){
-+ printk(KERN_ERR "Unable to register socket service routine\n");
-+ return -ENXIO;
-+ }
-+
-+ /* Start the event poll timer. It will reschedule by itself afterwards. */
-+ pxa_pcmcia_poll_event(0);
-+
-+ DEBUG(1, "pxa_cs: initialization complete\n");
-+
-+ return 0;
-+
-+} /* pxa_pcmcia_driver_init() */
-+
-+module_init(pxa_pcmcia_driver_init);
-+
-+
-+/* pxa_pcmcia_driver_shutdown()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * Invokes the low-level kernel service to free IRQs associated with this
-+ * socket controller and reset GPIO edge detection.
-+ */
-+static void __exit pxa_pcmcia_driver_shutdown(void){
-+
-+ del_timer_sync(&poll_timer);
-+ unregister_ss_entry(&pxa_pcmcia_operations);
-+#ifdef CONFIG_CPU_FREQ
-+ cpufreq_unregister_notifier(&pxa_pcmcia_notifier_block);
-+#endif
-+ pcmcia_low_level->shutdown();
-+ flush_scheduled_tasks();
-+
-+ DEBUG(1, "pxa_cs: shutdown complete\n");
-+}
-+
-+module_exit(pxa_pcmcia_driver_shutdown);
-+
-+
-+/* pxa_pcmcia_init()
-+ * ^^^^^^^^^^^^^^^^^^^^
-+ * We perform all of the interesting initialization tasks in
-+ * pxa_pcmcia_driver_init().
-+ *
-+ * Returns: 0
-+ */
-+static int pxa_pcmcia_init(unsigned int sock){
-+
-+ DEBUG(2, "%s(): initializing socket %u\n", __FUNCTION__, sock);
-+
-+ return 0;
-+}
-+
-+
-+/* pxa_pcmcia_suspend()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^
-+ * We don't currently perform any actions on a suspend.
-+ *
-+ * Returns: 0
-+ */
-+static int pxa_pcmcia_suspend(unsigned int sock)
-+{
-+ socket_state_t st;
-+ int ret;
-+
-+ DEBUG(2, "%s(): suspending socket %u\n", __FUNCTION__, sock);
-+
-+ st.Vcc = 0;
-+ st.Vpp = 0;
-+ st.flags = SS_RESET;
-+
-+ ret = pcmcia_low_level->configure_socket(sock, &st);
-+
-+ if (ret == 0)
-+ pxa_pcmcia_socket[sock].cs_state = dead_socket;
-+
-+ return ret;
-+}
-+
-+
-+/* pxa_pcmcia_events()
-+ * ^^^^^^^^^^^^^^^^^^^^^^
-+ * Helper routine to generate a Card Services event mask based on
-+ * state information obtained from the kernel low-level PCMCIA layer
-+ * in a recent (and previous) sampling. Updates `prev_state'.
-+ *
-+ * Returns: an event mask for the given socket state.
-+ */
-+static inline unsigned pxa_pcmcia_events(struct pcmcia_state *state,
-+ struct pcmcia_state *prev_state,
-+ unsigned int mask,
-+ unsigned int flags){
-+ unsigned int events=0;
-+
-+ if(state->detect!=prev_state->detect){
-+
-+ DEBUG(2, "%s(): card detect value %u\n", __FUNCTION__, state->detect);
-+
-+ events|=mask&SS_DETECT;
-+ }
-+
-+ if(state->ready!=prev_state->ready){
-+
-+ DEBUG(2, "%s(): card ready value %u\n", __FUNCTION__, state->ready);
-+
-+ events|=mask&((flags&SS_IOCARD)?0:SS_READY);
-+ }
-+
-+ if(state->bvd1!=prev_state->bvd1){
-+
-+ DEBUG(2, "%s(): card BVD1 value %u\n", __FUNCTION__, state->bvd1);
-+
-+ events|=mask&(flags&SS_IOCARD)?SS_STSCHG:SS_BATDEAD;
-+ }
-+
-+ if(state->bvd2!=prev_state->bvd2){
-+
-+ DEBUG(2, "%s(): card BVD2 value %u\n", __FUNCTION__, state->bvd2);
-+
-+ events|=mask&(flags&SS_IOCARD)?0:SS_BATWARN;
-+ }
-+
-+ DEBUG(2, "events: %s%s%s%s%s%s\n",
-+ (events==0)?"<NONE>":"",
-+ (events&SS_DETECT)?"DETECT ":"",
-+ (events&SS_READY)?"READY ":"",
-+ (events&SS_BATDEAD)?"BATDEAD ":"",
-+ (events&SS_BATWARN)?"BATWARN ":"",
-+ (events&SS_STSCHG)?"STSCHG ":"");
-+
-+ *prev_state=*state;
-+
-+ return events;
-+
-+} /* pxa_pcmcia_events() */
-+
-+
-+/* pxa_pcmcia_task_handler()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * Processes serviceable socket events using the "eventd" thread context.
-+ *
-+ * Event processing (specifically, the invocation of the Card Services event
-+ * callback) occurs in this thread rather than in the actual interrupt
-+ * handler due to the use of scheduling operations in the PCMCIA core.
-+ */
-+static void pxa_pcmcia_task_handler(void *data) {
-+ struct pcmcia_state state[PXA_PCMCIA_MAX_SOCK];
-+ struct pcmcia_state_array state_array;
-+ int i, events, all_events, irq_status;
-+
-+ DEBUG(2, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__);
-+
-+ state_array.size=pxa_pcmcia_socket_count;
-+ state_array.state=state;
-+
-+ do {
-+
-+ DEBUG(3, "%s(): interrogating low-level PCMCIA service\n", __FUNCTION__);
-+
-+ if((irq_status=pcmcia_low_level->socket_state(&state_array))<0)
-+ printk(KERN_ERR "Error in kernel low-level PCMCIA service.\n");
-+
-+ all_events=0;
-+
-+ if(irq_status>0){
-+
-+ for(i=0; i<state_array.size; ++i, all_events|=events)
-+ if((events=
-+ pxa_pcmcia_events(&state[i],
-+ &pxa_pcmcia_socket[i].k_state,
-+ pxa_pcmcia_socket[i].cs_state.csc_mask,
-+ pxa_pcmcia_socket[i].cs_state.flags)))
-+ if(pxa_pcmcia_socket[i].handler!=NULL)
-+ pxa_pcmcia_socket[i].handler(pxa_pcmcia_socket[i].handler_info,
-+ events);
-+ }
-+
-+ } while(all_events);
-+} /* pxa_pcmcia_task_handler() */
-+
-+static struct tq_struct pxa_pcmcia_task = {
-+ routine: pxa_pcmcia_task_handler
-+};
-+
-+
-+/* pxa_pcmcia_poll_event()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * Let's poll for events in addition to IRQs since IRQ only is unreliable...
-+ */
-+static void pxa_pcmcia_poll_event(unsigned long dummy)
-+{
-+ DEBUG(3, "%s(): polling for events\n", __FUNCTION__);
-+ poll_timer.function = pxa_pcmcia_poll_event;
-+ poll_timer.expires = jiffies + PXA_PCMCIA_POLL_PERIOD;
-+ add_timer(&poll_timer);
-+ schedule_task(&pxa_pcmcia_task);
-+}
-+
-+
-+/* pxa_pcmcia_interrupt()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * Service routine for socket driver interrupts (requested by the
-+ * low-level PCMCIA init() operation via pxa_pcmcia_thread()).
-+ * The actual interrupt-servicing work is performed by
-+ * pxa_pcmcia_thread(), largely because the Card Services event-
-+ * handling code performs scheduling operations which cannot be
-+ * executed from within an interrupt context.
-+ */
-+static void pxa_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs){
-+ DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq);
-+ schedule_task(&pxa_pcmcia_task);
-+}
-+
-+
-+/* pxa_pcmcia_register_callback()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * Implements the register_callback() operation for the in-kernel
-+ * PCMCIA service (formerly SS_RegisterCallback in Card Services). If
-+ * the function pointer `handler' is not NULL, remember the callback
-+ * location in the state for `sock', and increment the usage counter
-+ * for the driver module. (The callback is invoked from the interrupt
-+ * service routine, pxa_pcmcia_interrupt(), to notify Card Services
-+ * of interesting events.) Otherwise, clear the callback pointer in the
-+ * socket state and decrement the module usage count.
-+ *
-+ * Returns: 0
-+ */
-+static int pxa_pcmcia_register_callback(unsigned int sock,
-+ void (*handler)(void *,
-+ unsigned int),
-+ void *info){
-+ if(handler==NULL){
-+ pxa_pcmcia_socket[sock].handler=NULL;
-+ MOD_DEC_USE_COUNT;
-+ } else {
-+ MOD_INC_USE_COUNT;
-+ pxa_pcmcia_socket[sock].handler=handler;
-+ pxa_pcmcia_socket[sock].handler_info=info;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+/* pxa_pcmcia_inquire_socket()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * Implements the inquire_socket() operation for the in-kernel PCMCIA
-+ * service (formerly SS_InquireSocket in Card Services). Of note is
-+ * the setting of the SS_CAP_PAGE_REGS bit in the `features' field of
-+ * `cap' to "trick" Card Services into tolerating large "I/O memory"
-+ * addresses. Also set is SS_CAP_STATIC_MAP, which disables the memory
-+ * resource database check. (Mapped memory is set up within the socket
-+ * driver itself.)
-+ *
-+ * In conjunction with the STATIC_MAP capability is a new field,
-+ * `io_offset', recommended by David Hinds. Rather than go through
-+ * the SetIOMap interface (which is not quite suited for communicating
-+ * window locations up from the socket driver), we just pass up
-+ * an offset which is applied to client-requested base I/O addresses
-+ * in alloc_io_space().
-+ *
-+ * Returns: 0 on success, -1 if no pin has been configured for `sock'
-+ */
-+static int pxa_pcmcia_inquire_socket(unsigned int sock,
-+ socket_cap_t *cap){
-+ struct pcmcia_irq_info irq_info;
-+
-+ DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
-+
-+ if(sock>=pxa_pcmcia_socket_count){
-+ printk(KERN_ERR "pxa_cs: socket %u not configured\n", sock);
-+ return -1;
-+ }
-+
-+ /* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the
-+ * force_low argument to validate_mem() in rsrc_mgr.c -- since in
-+ * general, the mapped * addresses of the PCMCIA memory regions
-+ * will not be within 0xffff, setting force_low would be
-+ * undesirable.
-+ *
-+ * SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory
-+ * resource database; we instead pass up physical address ranges
-+ * and allow other parts of Card Services to deal with remapping.
-+ *
-+ * SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but
-+ * not 32-bit CardBus devices.
-+ */
-+ cap->features=(SS_CAP_PAGE_REGS | SS_CAP_STATIC_MAP | SS_CAP_PCCARD);
-+
-+ irq_info.sock=sock;
-+ irq_info.irq=-1;
-+
-+ if(pcmcia_low_level->get_irq_info(&irq_info)<0){
-+ printk(KERN_ERR "Error obtaining IRQ info from kernel for socket %u\n",
-+ sock);
-+ return -1;
-+ }
-+
-+ cap->irq_mask=0;
-+ cap->map_size=PAGE_SIZE;
-+ cap->pci_irq=irq_info.irq;
-+ cap->io_offset=pxa_pcmcia_socket[sock].virt_io;
-+
-+ return 0;
-+
-+} /* pxa_pcmcia_inquire_socket() */
-+
-+
-+/* pxa_pcmcia_get_status()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * Implements the get_status() operation for the in-kernel PCMCIA
-+ * service (formerly SS_GetStatus in Card Services). Essentially just
-+ * fills in bits in `status' according to internal driver state or
-+ * the value of the voltage detect chipselect register.
-+ *
-+ * As a debugging note, during card startup, the PCMCIA core issues
-+ * three set_socket() commands in a row the first with RESET deasserted,
-+ * the second with RESET asserted, and the last with RESET deasserted
-+ * again. Following the third set_socket(), a get_status() command will
-+ * be issued. The kernel is looking for the SS_READY flag (see
-+ * setup_socket(), reset_socket(), and unreset_socket() in cs.c).
-+ *
-+ * Returns: 0
-+ */
-+static int pxa_pcmcia_get_status(unsigned int sock,
-+ unsigned int *status){
-+ struct pcmcia_state state[PXA_PCMCIA_MAX_SOCK];
-+ struct pcmcia_state_array state_array;
-+
-+ DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
-+
-+ state_array.size=pxa_pcmcia_socket_count;
-+ state_array.state=state;
-+
-+ if((pcmcia_low_level->socket_state(&state_array))<0){
-+ printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n");
-+ return -1;
-+ }
-+
-+ pxa_pcmcia_socket[sock].k_state=state[sock];
-+
-+ *status=state[sock].detect?SS_DETECT:0;
-+
-+ *status|=state[sock].ready?SS_READY:0;
-+
-+ /* The power status of individual sockets is not available
-+ * explicitly from the hardware, so we just remember the state
-+ * and regurgitate it upon request:
-+ */
-+ *status|=pxa_pcmcia_socket[sock].cs_state.Vcc?SS_POWERON:0;
-+
-+ if(pxa_pcmcia_socket[sock].cs_state.flags&SS_IOCARD)
-+ *status|=state[sock].bvd1?SS_STSCHG:0;
-+ else {
-+ if(state[sock].bvd1==0)
-+ *status|=SS_BATDEAD;
-+ else if(state[sock].bvd2==0)
-+ *status|=SS_BATWARN;
-+ }
-+
-+ *status|=state[sock].vs_3v?SS_3VCARD:0;
-+
-+ *status|=state[sock].vs_Xv?SS_XVCARD:0;
-+
-+ DEBUG(3, "\tstatus: %s%s%s%s%s%s%s%s\n",
-+ (*status&SS_DETECT)?"DETECT ":"",
-+ (*status&SS_READY)?"READY ":"",
-+ (*status&SS_BATDEAD)?"BATDEAD ":"",
-+ (*status&SS_BATWARN)?"BATWARN ":"",
-+ (*status&SS_POWERON)?"POWERON ":"",
-+ (*status&SS_STSCHG)?"STSCHG ":"",
-+ (*status&SS_3VCARD)?"3VCARD ":"",
-+ (*status&SS_XVCARD)?"XVCARD ":"");
-+
-+ return 0;
-+
-+} /* pxa_pcmcia_get_status() */
-+
-+
-+/* pxa_pcmcia_get_socket()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * Implements the get_socket() operation for the in-kernel PCMCIA
-+ * service (formerly SS_GetSocket in Card Services). Not a very
-+ * exciting routine.
-+ *
-+ * Returns: 0
-+ */
-+static int pxa_pcmcia_get_socket(unsigned int sock,
-+ socket_state_t *state){
-+
-+ DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
-+
-+ /* This information was given to us in an earlier call to set_socket(),
-+ * so we're just regurgitating it here:
-+ */
-+ *state=pxa_pcmcia_socket[sock].cs_state;
-+
-+ return 0;
-+}
-+
-+
-+/* pxa_pcmcia_set_socket()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * Implements the set_socket() operation for the in-kernel PCMCIA
-+ * service (formerly SS_SetSocket in Card Services). We more or
-+ * less punt all of this work and let the kernel handle the details
-+ * of power configuration, reset, &c. We also record the value of
-+ * `state' in order to regurgitate it to the PCMCIA core later.
-+ *
-+ * Returns: 0
-+ */
-+static int pxa_pcmcia_set_socket(unsigned int sock,
-+ socket_state_t *state){
-+
-+ DEBUG(3, "%s() for sock %u\n", __FUNCTION__, sock);
-+
-+ DEBUG(3, "\tmask: %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n"
-+ "\tVcc %d Vpp %d irq %d\n",
-+ (state->csc_mask==0)?"<NONE>":"",
-+ (state->csc_mask&SS_DETECT)?"DETECT ":"",
-+ (state->csc_mask&SS_READY)?"READY ":"",
-+ (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"",
-+ (state->csc_mask&SS_BATWARN)?"BATWARN ":"",
-+ (state->csc_mask&SS_STSCHG)?"STSCHG ":"",
-+ (state->flags==0)?"<NONE>":"",
-+ (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"",
-+ (state->flags&SS_IOCARD)?"IOCARD ":"",
-+ (state->flags&SS_RESET)?"RESET ":"",
-+ (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",
-+ (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"",
-+ state->Vcc, state->Vpp, state->io_irq);
-+
-+ if(pcmcia_low_level->configure_socket(sock, state)<0){
-+ printk(KERN_ERR "Unable to configure socket %u\n", sock);
-+ return -1;
-+ }
-+
-+ pxa_pcmcia_socket[sock].cs_state=*state;
-+
-+ return 0;
-+
-+} /* pxa_pcmcia_set_socket() */
-+
-+
-+/* pxa_pcmcia_get_io_map()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * Implements the get_io_map() operation for the in-kernel PCMCIA
-+ * service (formerly SS_GetIOMap in Card Services). Just returns an
-+ * I/O map descriptor which was assigned earlier by a set_io_map().
-+ *
-+ * Returns: 0 on success, -1 if the map index was out of range
-+ */
-+static int pxa_pcmcia_get_io_map(unsigned int sock,
-+ struct pccard_io_map *map){
-+
-+ DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
-+
-+ if(map->map>=MAX_IO_WIN){
-+ printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
-+ map->map);
-+ return -1;
-+ }
-+
-+ *map=pxa_pcmcia_socket[sock].io_map[map->map];
-+
-+ return 0;
-+}
-+
-+
-+/* pxa_pcmcia_set_io_map()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * Implements the set_io_map() operation for the in-kernel PCMCIA
-+ * service (formerly SS_SetIOMap in Card Services). We configure
-+ * the map speed as requested, but override the address ranges
-+ * supplied by Card Services.
-+ *
-+ * Returns: 0 on success, -1 on error
-+ */
-+static int pxa_pcmcia_set_io_map(unsigned int sock,
-+ struct pccard_io_map *map){
-+ unsigned int clock, speed;
-+ unsigned long mecr, start;
-+
-+ DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
-+
-+ DEBUG(4, "\tmap %u speed %u\n\tstart 0x%08lx stop 0x%08lx\n"
-+ "\tflags: %s%s%s%s%s%s%s%s\n",
-+ map->map, map->speed, map->start, map->stop,
-+ (map->flags==0)?"<NONE>":"",
-+ (map->flags&MAP_ACTIVE)?"ACTIVE ":"",
-+ (map->flags&MAP_16BIT)?"16BIT ":"",
-+ (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"",
-+ (map->flags&MAP_0WS)?"0WS ":"",
-+ (map->flags&MAP_WRPROT)?"WRPROT ":"",
-+ (map->flags&MAP_USE_WAIT)?"USE_WAIT ":"",
-+ (map->flags&MAP_PREFETCH)?"PREFETCH ":"");
-+
-+ if(map->map>=MAX_IO_WIN){
-+ printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
-+ map->map);
-+ return -1;
-+ }
-+
-+ if(map->flags&MAP_ACTIVE){
-+
-+ speed=(map->speed>0)?map->speed:PXA_PCMCIA_IO_ACCESS;
-+
-+ clock = get_lclk_frequency_10khz();
-+
-+ pxa_pcmcia_socket[sock].speed_io=speed;
-+
-+ if (sock == 0) {
-+ MCIO0 = ((pxa_mcxx_setup(speed, clock)
-+ & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-+ | ((pxa_mcxx_asst(speed, clock)
-+ & MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-+ | ((pxa_mcxx_hold(speed, clock)
-+ & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
-+ } else {
-+ MCIO1 = ((pxa_mcxx_setup(speed, clock)
-+ & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-+ | ((pxa_mcxx_asst(speed, clock)
-+ & MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-+ | ((pxa_mcxx_hold(speed, clock)
-+ & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
-+ }
-+
-+ DEBUG(4, "%s(): FAST%u %lx BSM%u %lx BSA%u %lx BSIO%u %lx\n",
-+ __FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock,
-+ MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock),
-+ sock, MECR_BSIO_GET(mecr, sock));
-+
-+ }
-+
-+ start=map->start;
-+
-+ if(map->stop==1)
-+ map->stop=PAGE_SIZE-1;
-+
-+ map->start=pxa_pcmcia_socket[sock].virt_io;
-+ map->stop=map->start+(map->stop-start);
-+
-+ pxa_pcmcia_socket[sock].io_map[map->map]=*map;
-+
-+ return 0;
-+
-+} /* pxa_pcmcia_set_io_map() */
-+
-+
-+/* pxa_pcmcia_get_mem_map()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * Implements the get_mem_map() operation for the in-kernel PCMCIA
-+ * service (formerly SS_GetMemMap in Card Services). Just returns a
-+ * memory map descriptor which was assigned earlier by a
-+ * set_mem_map() request.
-+ *
-+ * Returns: 0 on success, -1 if the map index was out of range
-+ */
-+static int pxa_pcmcia_get_mem_map(unsigned int sock,
-+ struct pccard_mem_map *map){
-+
-+ DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
-+
-+ if(map->map>=MAX_WIN){
-+ printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
-+ map->map);
-+ return -1;
-+ }
-+
-+ *map=pxa_pcmcia_socket[sock].mem_map[map->map];
-+
-+ return 0;
-+}
-+
-+
-+/* pxa_pcmcia_set_mem_map()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * Implements the set_mem_map() operation for the in-kernel PCMCIA
-+ * service (formerly SS_SetMemMap in Card Services). We configure
-+ * the map speed as requested, but override the address ranges
-+ * supplied by Card Services.
-+ *
-+ * Returns: 0 on success, -1 on error
-+ */
-+static int pxa_pcmcia_set_mem_map(unsigned int sock,
-+ struct pccard_mem_map *map){
-+ unsigned int clock, speed;
-+ unsigned long mecr, start;
-+
-+ DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
-+
-+ DEBUG(4, "\tmap %u speed %u\n\tsys_start %#lx\n"
-+ "\tsys_stop %#lx\n\tcard_start %#x\n"
-+ "\tflags: %s%s%s%s%s%s%s%s\n",
-+ map->map, map->speed, map->sys_start, map->sys_stop,
-+ map->card_start, (map->flags==0)?"<NONE>":"",
-+ (map->flags&MAP_ACTIVE)?"ACTIVE ":"",
-+ (map->flags&MAP_16BIT)?"16BIT ":"",
-+ (map->flags&MAP_AUTOSZ)?"AUTOSZ ":"",
-+ (map->flags&MAP_0WS)?"0WS ":"",
-+ (map->flags&MAP_WRPROT)?"WRPROT ":"",
-+ (map->flags&MAP_ATTRIB)?"ATTRIB ":"",
-+ (map->flags&MAP_USE_WAIT)?"USE_WAIT ":"");
-+
-+ if(map->map>=MAX_WIN){
-+ printk(KERN_ERR "%s(): map (%d) out of range\n", __FUNCTION__,
-+ map->map);
-+ return -1;
-+ }
-+
-+ if(map->flags&MAP_ACTIVE){
-+ /* When clients issue RequestMap, the access speed is not always
-+ * properly configured:
-+ */
-+ if(map->speed > 0)
-+ speed = map->speed;
-+ else
-+ switch(pxa_pcmcia_socket[sock].cs_state.Vcc){
-+ case 33:
-+ speed = PXA_PCMCIA_3V_MEM_ACCESS;
-+ break;
-+ default:
-+ speed = PXA_PCMCIA_5V_MEM_ACCESS;
-+ }
-+
-+ clock = get_lclk_frequency_10khz();
-+
-+ if(map->flags&MAP_ATTRIB){
-+ if (sock == 0) {
-+ MCATT0 = ((pxa_mcxx_setup(PXA_PCMCIA_ATTR_MEM_ACCESS, clock)
-+ & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-+ | ((pxa_mcxx_asst(PXA_PCMCIA_ATTR_MEM_ACCESS, clock)
-+ & MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-+ | ((pxa_mcxx_hold(PXA_PCMCIA_ATTR_MEM_ACCESS, clock)
-+ & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
-+ } else {
-+ MCATT1 = ((pxa_mcxx_setup(PXA_PCMCIA_ATTR_MEM_ACCESS, clock)
-+ & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-+ | ((pxa_mcxx_asst(PXA_PCMCIA_ATTR_MEM_ACCESS, clock)
-+ & MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-+ | ((pxa_mcxx_hold(PXA_PCMCIA_ATTR_MEM_ACCESS, clock)
-+ & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
-+ }
-+ pxa_pcmcia_socket[sock].speed_attr=speed;
-+ } else {
-+ if (sock == 0) {
-+ MCMEM0 = ((pxa_mcxx_setup(speed, clock)
-+ & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-+ | ((pxa_mcxx_asst(speed, clock)
-+ & MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-+ | ((pxa_mcxx_hold(speed, clock)
-+ & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
-+ } else {
-+ MCMEM1 = ((pxa_mcxx_setup(speed, clock)
-+ & MCXX_SETUP_MASK) << MCXX_SETUP_SHIFT)
-+ | ((pxa_mcxx_asst(speed, clock)
-+ & MCXX_ASST_MASK) << MCXX_ASST_SHIFT)
-+ | ((pxa_mcxx_hold(speed, clock)
-+ & MCXX_HOLD_MASK) << MCXX_HOLD_SHIFT);
-+ }
-+ pxa_pcmcia_socket[sock].speed_mem=speed;
-+ }
-+ DEBUG(4, "%s(): FAST%u %lx BSM%u %lx BSA%u %lx BSIO%u %lx\n",
-+ __FUNCTION__, sock, MECR_FAST_GET(mecr, sock), sock,
-+ MECR_BSM_GET(mecr, sock), sock, MECR_BSA_GET(mecr, sock),
-+ sock, MECR_BSIO_GET(mecr, sock));
-+ }
-+
-+ start=map->sys_start;
-+
-+ if(map->sys_stop==0)
-+ map->sys_stop=PAGE_SIZE-1;
-+
-+ map->sys_start=(map->flags & MAP_ATTRIB)?\
-+ pxa_pcmcia_socket[sock].phys_attr:\
-+ pxa_pcmcia_socket[sock].phys_mem;
-+
-+ map->sys_stop=map->sys_start+(map->sys_stop-start);
-+
-+ pxa_pcmcia_socket[sock].mem_map[map->map]=*map;
-+
-+ return 0;
-+
-+} /* pxa_pcmcia_set_mem_map() */
-+
-+
-+#if defined(CONFIG_PROC_FS)
-+
-+/* pxa_pcmcia_proc_setup()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * Implements the proc_setup() operation for the in-kernel PCMCIA
-+ * service (formerly SS_ProcSetup in Card Services).
-+ *
-+ * Returns: 0 on success, -1 on error
-+ */
-+static void pxa_pcmcia_proc_setup(unsigned int sock,
-+ struct proc_dir_entry *base){
-+ struct proc_dir_entry *entry;
-+
-+ DEBUG(4, "%s() for sock %u\n", __FUNCTION__, sock);
-+
-+ if((entry=create_proc_entry("status", 0, base))==NULL){
-+ printk(KERN_ERR "Unable to install \"status\" procfs entry\n");
-+ return;
-+ }
-+
-+ entry->read_proc=pxa_pcmcia_proc_status;
-+ entry->data=(void *)sock;
-+}
-+
-+
-+/* pxa_pcmcia_proc_status()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * Implements the /proc/bus/pccard/??/status file.
-+ *
-+ * Returns: the number of characters added to the buffer
-+ */
-+static int pxa_pcmcia_proc_status(char *buf, char **start, off_t pos,
-+ int count, int *eof, void *data){
-+ char *p=buf;
-+ unsigned int sock=(unsigned int)data;
-+ unsigned int clock = get_lclk_frequency_10khz();
-+ unsigned long mecr = MECR;
-+
-+ p+=sprintf(p, "k_flags : %s%s%s%s%s%s%s\n",
-+ pxa_pcmcia_socket[sock].k_state.detect?"detect ":"",
-+ pxa_pcmcia_socket[sock].k_state.ready?"ready ":"",
-+ pxa_pcmcia_socket[sock].k_state.bvd1?"bvd1 ":"",
-+ pxa_pcmcia_socket[sock].k_state.bvd2?"bvd2 ":"",
-+ pxa_pcmcia_socket[sock].k_state.wrprot?"wrprot ":"",
-+ pxa_pcmcia_socket[sock].k_state.vs_3v?"vs_3v ":"",
-+ pxa_pcmcia_socket[sock].k_state.vs_Xv?"vs_Xv ":"");
-+
-+ p+=sprintf(p, "status : %s%s%s%s%s%s%s%s%s\n",
-+ pxa_pcmcia_socket[sock].k_state.detect?"SS_DETECT ":"",
-+ pxa_pcmcia_socket[sock].k_state.ready?"SS_READY ":"",
-+ pxa_pcmcia_socket[sock].cs_state.Vcc?"SS_POWERON ":"",
-+ pxa_pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
-+ "SS_IOCARD ":"",
-+ (pxa_pcmcia_socket[sock].cs_state.flags&SS_IOCARD &&
-+ pxa_pcmcia_socket[sock].k_state.bvd1)?"SS_STSCHG ":"",
-+ ((pxa_pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
-+ (pxa_pcmcia_socket[sock].k_state.bvd1==0))?"SS_BATDEAD ":"",
-+ ((pxa_pcmcia_socket[sock].cs_state.flags&SS_IOCARD)==0 &&
-+ (pxa_pcmcia_socket[sock].k_state.bvd2==0))?"SS_BATWARN ":"",
-+ pxa_pcmcia_socket[sock].k_state.vs_3v?"SS_3VCARD ":"",
-+ pxa_pcmcia_socket[sock].k_state.vs_Xv?"SS_XVCARD ":"");
-+
-+ p+=sprintf(p, "mask : %s%s%s%s%s\n",
-+ pxa_pcmcia_socket[sock].cs_state.csc_mask&SS_DETECT?\
-+ "SS_DETECT ":"",
-+ pxa_pcmcia_socket[sock].cs_state.csc_mask&SS_READY?\
-+ "SS_READY ":"",
-+ pxa_pcmcia_socket[sock].cs_state.csc_mask&SS_BATDEAD?\
-+ "SS_BATDEAD ":"",
-+ pxa_pcmcia_socket[sock].cs_state.csc_mask&SS_BATWARN?\
-+ "SS_BATWARN ":"",
-+ pxa_pcmcia_socket[sock].cs_state.csc_mask&SS_STSCHG?\
-+ "SS_STSCHG ":"");
-+
-+ p+=sprintf(p, "cs_flags : %s%s%s%s%s\n",
-+ pxa_pcmcia_socket[sock].cs_state.flags&SS_PWR_AUTO?\
-+ "SS_PWR_AUTO ":"",
-+ pxa_pcmcia_socket[sock].cs_state.flags&SS_IOCARD?\
-+ "SS_IOCARD ":"",
-+ pxa_pcmcia_socket[sock].cs_state.flags&SS_RESET?\
-+ "SS_RESET ":"",
-+ pxa_pcmcia_socket[sock].cs_state.flags&SS_SPKR_ENA?\
-+ "SS_SPKR_ENA ":"",
-+ pxa_pcmcia_socket[sock].cs_state.flags&SS_OUTPUT_ENA?\
-+ "SS_OUTPUT_ENA ":"");
-+
-+ p+=sprintf(p, "Vcc : %d\n", pxa_pcmcia_socket[sock].cs_state.Vcc);
-+
-+ p+=sprintf(p, "Vpp : %d\n", pxa_pcmcia_socket[sock].cs_state.Vpp);
-+
-+ p+=sprintf(p, "irq : %d\n", pxa_pcmcia_socket[sock].cs_state.io_irq);
-+
-+ p+=sprintf(p, "I/O : %u (%u)\n", pxa_pcmcia_socket[sock].speed_io,
-+ sock ?
-+ pxa_pcmcia_cmd_time(clock,
-+ ((MCIO1 >> MCXX_ASST_SHIFT) & MCXX_ASST_MASK)) :
-+ pxa_pcmcia_cmd_time(clock,
-+ ((MCIO0 >> MCXX_ASST_SHIFT) & MCXX_ASST_MASK)));
-+
-+ p+=sprintf(p, "attribute: %u (%u)\n", pxa_pcmcia_socket[sock].speed_attr,
-+ sock ?
-+ pxa_pcmcia_cmd_time(clock,
-+ ((MCATT1 >> MCXX_ASST_SHIFT) & MCXX_ASST_MASK)) :
-+ pxa_pcmcia_cmd_time(clock,
-+ ((MCATT0 >> MCXX_ASST_SHIFT) & MCXX_ASST_MASK)));
-+
-+ p+=sprintf(p, "common : %u (%u)\n", pxa_pcmcia_socket[sock].speed_mem,
-+ sock ?
-+ pxa_pcmcia_cmd_time(clock,
-+ ((MCMEM1 >> MCXX_ASST_SHIFT) & MCXX_ASST_MASK)) :
-+ pxa_pcmcia_cmd_time(clock,
-+ ((MCMEM0 >> MCXX_ASST_SHIFT) & MCXX_ASST_MASK)));
-+
-+ return p-buf;
-+}
-+
-+#endif /* defined(CONFIG_PROC_FS) */
-+
-+
-+#ifdef CONFIG_CPU_FREQ
-+
-+/* pxa_pcmcia_update_mecr()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * When pxa_pcmcia_notifier() decides that a MECR adjustment (due
-+ * to a core clock frequency change) is needed, this routine establishes
-+ * new BS_xx values consistent with the clock speed `clock'.
-+ */
-+static void pxa_pcmcia_update_mecr(unsigned int clock){
-+ unsigned int sock;
-+
-+ for(sock = 0; sock < PXA_PCMCIA_MAX_SOCK; ++sock){
-+
-+ // REVISIT: MCXX macros needed here
-+ // MECR_BSIO_SET(mecr, sock,
-+// pxa_pcmcia_mecr_bs(pxa_pcmcia_socket[sock].speed_io,
-+// clock));
-+ // MECR_BSA_SET(mecr, sock,
-+// pxa_pcmcia_mecr_bs(pxa_pcmcia_socket[sock].speed_attr,
-+// clock));
-+ // MECR_BSM_SET(mecr, sock,
-+// pxa_pcmcia_mecr_bs(pxa_pcmcia_socket[sock].speed_mem,
-+// clock));
-+ }
-+}
-+
-+/* pxa_pcmcia_notifier()
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^
-+ * When changing the processor core clock frequency, it is necessary
-+ * to adjust the MECR timings accordingly. We've recorded the timings
-+ * requested by Card Services, so this is just a matter of finding
-+ * out what our current speed is, and then recomputing the new MECR
-+ * values.
-+ *
-+ * Returns: 0 on success, -1 on error
-+ */
-+static int pxa_pcmcia_notifier(struct notifier_block *nb,
-+ unsigned long val, void *data){
-+ struct cpufreq_info *ci = data;
-+
-+ switch(val){
-+ case CPUFREQ_MINMAX:
-+
-+ break;
-+
-+ case CPUFREQ_PRECHANGE:
-+
-+ if(ci->new_freq > ci->old_freq){
-+ DEBUG(2, "%s(): new frequency %u.%uMHz > %u.%uMHz, pre-updating\n",
-+ __FUNCTION__,
-+ ci->new_freq / 1000, (ci->new_freq / 100) % 10,
-+ ci->old_freq / 1000, (ci->old_freq / 100) % 10);
-+ pxa_pcmcia_update_mecr(ci->new_freq);
-+ }
-+
-+ break;
-+
-+ case CPUFREQ_POSTCHANGE:
-+
-+ if(ci->new_freq < ci->old_freq){
-+ DEBUG(2, "%s(): new frequency %u.%uMHz < %u.%uMHz, post-updating\n",
-+ __FUNCTION__,
-+ ci->new_freq / 1000, (ci->new_freq / 100) % 10,
-+ ci->old_freq / 1000, (ci->old_freq / 100) % 10);
-+ pxa_pcmcia_update_mecr(ci->new_freq);
-+ }
-+
-+ break;
-+
-+ default:
-+ printk(KERN_ERR "%s(): unknown CPU frequency event %lx\n", __FUNCTION__,
-+ val);
-+ return -1;
-+
-+ }
-+
-+ return 0;
-+
-+}
-+
-+static struct notifier_block pxa_pcmcia_notifier_block = {
-+ notifier_call: pxa_pcmcia_notifier
-+};
-+
-+#endif
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/pxa/pxa.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,233 @@
-+/*
-+ * linux/drivers/pcmcia/pxa/pxa.h
-+ *
-+ * Author: George Davis
-+ * Created: Jan 10, 2002
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Originally based upon linux/drivers/pcmcia/sa1100_generic.h
-+ *
-+ */
-+
-+/*======================================================================
-+
-+ Device driver for the PCMCIA control functionality of Intel
-+ PXA250/210 microprocessors.
-+
-+ The contents of this file are subject to the Mozilla Public
-+ License Version 1.1 (the "License"); you may not use this file
-+ except in compliance with the License. You may obtain a copy of
-+ the License at http://www.mozilla.org/MPL/
-+
-+ Software distributed under the License is distributed on an "AS
-+ IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ implied. See the License for the specific language governing
-+ rights and limitations under the License.
-+
-+ The initial developer of the original code is John G. Dorsey
-+ <john+@cs.cmu.edu>. Portions created by John G. Dorsey are
-+ Copyright (C) 1999 John G. Dorsey. All Rights Reserved.
-+
-+ Alternatively, the contents of this file may be used under the
-+ terms of the GNU Public License version 2 (the "GPL"), in which
-+ case the provisions of the GPL are applicable instead of the
-+ above. If you wish to allow the use of your version of this file
-+ only under the terms of the GPL and not to allow others to use
-+ your version of this file under the MPL, indicate your decision
-+ by deleting the provisions above and replace them with the notice
-+ and other provisions required by the GPL. If you do not delete
-+ the provisions above, a recipient may use your version of this
-+ file under either the MPL or the GPL.
-+
-+======================================================================*/
-+
-+#if !defined(_PCMCIA_PXA_H)
-+# define _PCMCIA_PXA_H
-+
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/ss.h>
-+#include <pcmcia/bulkmem.h>
-+#include <pcmcia/cistpl.h>
-+#include "../cs_internal.h"
-+
-+#include <asm/arch/pcmcia.h>
-+
-+
-+/* MECR: Expansion Memory Configuration Register
-+ * (SA-1100 Developers Manual, p.10-13; SA-1110 Developers Manual, p.10-24)
-+ *
-+ * MECR layout is:
-+ *
-+ * FAST1 BSM1<4:0> BSA1<4:0> BSIO1<4:0> FAST0 BSM0<4:0> BSA0<4:0> BSIO0<4:0>
-+ *
-+ * (This layout is actually true only for the SA-1110; the FASTn bits are
-+ * reserved on the SA-1100.)
-+ */
-+
-+#define MCXX_SETUP_MASK (0x7f)
-+#define MCXX_ASST_MASK (0x1f)
-+#define MCXX_HOLD_MASK (0x3f)
-+#define MCXX_SETUP_SHIFT (0)
-+#define MCXX_ASST_SHIFT (7)
-+#define MCXX_HOLD_SHIFT (14)
-+
-+
-+#define MECR_SET(mecr, sock, shift, mask, bs) \
-+((mecr)=((mecr)&~(((mask)<<(shift))<<\
-+ ((sock)==0?MECR_SOCKET_0_SHIFT:MECR_SOCKET_1_SHIFT)))|\
-+ (((bs)<<(shift))<<((sock)==0?MECR_SOCKET_0_SHIFT:MECR_SOCKET_1_SHIFT)))
-+
-+#define MECR_GET(mecr, sock, shift, mask) \
-+((((mecr)>>(((sock)==0)?MECR_SOCKET_0_SHIFT:MECR_SOCKET_1_SHIFT))>>\
-+ (shift))&(mask))
-+
-+#define MECR_BSIO_SET(mecr, sock, bs) \
-+MECR_SET((mecr), (sock), MECR_BSIO_SHIFT, MECR_BS_MASK, (bs))
-+
-+#define MECR_BSIO_GET(mecr, sock) \
-+MECR_GET((mecr), (sock), MECR_BSIO_SHIFT, MECR_BS_MASK)
-+
-+#define MECR_BSA_SET(mecr, sock, bs) \
-+MECR_SET((mecr), (sock), MECR_BSA_SHIFT, MECR_BS_MASK, (bs))
-+
-+#define MECR_BSA_GET(mecr, sock) \
-+MECR_GET((mecr), (sock), MECR_BSA_SHIFT, MECR_BS_MASK)
-+
-+#define MECR_BSM_SET(mecr, sock, bs) \
-+MECR_SET((mecr), (sock), MECR_BSM_SHIFT, MECR_BS_MASK, (bs))
-+
-+#define MECR_BSM_GET(mecr, sock) \
-+MECR_GET((mecr), (sock), MECR_BSM_SHIFT, MECR_BS_MASK)
-+
-+#define MECR_FAST_SET(mecr, sock, fast) \
-+MECR_SET((mecr), (sock), MECR_FAST_SHIFT, MECR_FAST_MODE_MASK, (fast))
-+
-+#define MECR_FAST_GET(mecr, sock) \
-+MECR_GET((mecr), (sock), MECR_FAST_SHIFT, MECR_FAST_MODE_MASK)
-+
-+
-+/* This function implements the BS value calculation for setting the MECR
-+ * using integer arithmetic:
-+ */
-+static inline unsigned int pxa_pcmcia_mecr_bs(unsigned int pcmcia_cycle_ns,
-+ unsigned int cpu_clock_khz){
-+ unsigned int t = ((pcmcia_cycle_ns * cpu_clock_khz) / 6) - 1000000;
-+ return (t / 1000000) + (((t % 1000000) == 0) ? 0 : 1);
-+}
-+
-+static inline u_int pxa_mcxx_hold(u_int pcmcia_cycle_ns,
-+ u_int mem_clk_10khz){
-+ u_int code = pcmcia_cycle_ns * mem_clk_10khz;
-+ return (code / 300000) + ((code % 300000) ? 1 : 0);
-+}
-+
-+static inline u_int pxa_mcxx_asst(u_int pcmcia_cycle_ns,
-+ u_int mem_clk_10khz){
-+ u_int code = pcmcia_cycle_ns * mem_clk_10khz;
-+ return (code / 300000) + ((code % 300000) ? 1 : 0);
-+}
-+
-+static inline u_int pxa_mcxx_setup(u_int pcmcia_cycle_ns,
-+ u_int mem_clk_10khz){
-+ u_int code = pcmcia_cycle_ns * mem_clk_10khz;
-+ return (code / 100000) + ((code % 100000) ? 1 : 0) + 1;
-+}
-+
-+/* This function returns the (approxmiate) command assertion period, in
-+ * nanoseconds, for a given CPU clock frequency and MCXX_ASST value:
-+ */
-+
-+static inline u_int pxa_pcmcia_cmd_time(u_int mem_clk_10khz,
-+ u_int pcmcia_mcxx_asst){
-+ return (300000 * (pcmcia_mcxx_asst + 1) / mem_clk_10khz);
-+}
-+
-+
-+/* SA-1100 PCMCIA Memory and I/O timing
-+ * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-+ * The SA-1110 Developer's Manual, section 10.2.5, says the following:
-+ *
-+ * "To calculate the recommended BS_xx value for each address space:
-+ * divide the command width time (the greater of twIOWR and twIORD,
-+ * or the greater of twWE and twOE) by processor cycle time; divide
-+ * by 2; divide again by 3 (number of BCLK's per command assertion);
-+ * round up to the next whole number; and subtract 1."
-+ *
-+ * The PC Card Standard, Release 7, section 4.13.4, says that twIORD
-+ * has a minimum value of 165ns. Section 4.13.5 says that twIOWR has
-+ * a minimum value of 165ns, as well. Section 4.7.2 (describing
-+ * common and attribute memory write timing) says that twWE has a
-+ * minimum value of 150ns for a 250ns cycle time (for 5V operation;
-+ * see section 4.7.4), or 300ns for a 600ns cycle time (for 3.3V
-+ * operation, also section 4.7.4). Section 4.7.3 says that taOE
-+ * has a maximum value of 150ns for a 300ns cycle time (for 5V
-+ * operation), or 300ns for a 600ns cycle time (for 3.3V operation).
-+ *
-+ * When configuring memory maps, Card Services appears to adopt the policy
-+ * that a memory access time of "0" means "use the default." The default
-+ * PCMCIA I/O command width time is 165ns. The default PCMCIA 5V attribute
-+ * and memory command width time is 150ns; the PCMCIA 3.3V attribute and
-+ * memory command width time is 300ns.
-+ */
-+
-+/* The PXA 250 and PXA 210 Application Processors Developer's Manual
-+ * was used to determine correct PXA_PCMCIA_IO_ACCES time
-+ */
-+
-+#define PXA_PCMCIA_IO_ACCESS (165)
-+
-+/* Default PC Card Common Memory timings*/
-+
-+#define PXA_PCMCIA_5V_MEM_ACCESS (250)
-+#define PXA_PCMCIA_3V_MEM_ACCESS (250)
-+
-+/* Atrribute Memory timing - must be constant via PC Card standart*/
-+
-+#define PXA_PCMCIA_ATTR_MEM_ACCESS (300)
-+
-+
-+/* The socket driver actually works nicely in interrupt-driven form,
-+ * so the (relatively infrequent) polling is "just to be sure."
-+ */
-+#define PXA_PCMCIA_POLL_PERIOD (2*HZ)
-+
-+
-+/* This structure encapsulates per-socket state which we might need to
-+ * use when responding to a Card Services query of some kind.
-+ */
-+struct pxa_pcmcia_socket {
-+ socket_state_t cs_state;
-+ struct pcmcia_state k_state;
-+ unsigned int irq;
-+ void (*handler)(void *, unsigned int);
-+ void *handler_info;
-+ pccard_io_map io_map[MAX_IO_WIN];
-+ pccard_mem_map mem_map[MAX_WIN];
-+ ioaddr_t virt_io, phys_attr, phys_mem;
-+ unsigned short speed_io, speed_attr, speed_mem;
-+};
-+
-+
-+/* I/O pins replacing memory pins
-+ * (PCMCIA System Architecture, 2nd ed., by Don Anderson, p.75)
-+ *
-+ * These signals change meaning when going from memory-only to
-+ * memory-or-I/O interface:
-+ */
-+#define iostschg bvd1
-+#define iospkr bvd2
-+
-+
-+/*
-+ * Declaration for all implementation specific low_level operations.
-+ */
-+extern struct pcmcia_low_level lubbock_pcmcia_ops;
-+extern struct pcmcia_low_level pxa_idp_pcmcia_ops;
-+extern struct pcmcia_low_level cerf_pcmcia_ops;
-+extern struct pcmcia_low_level trizeps2_pcmcia_ops;
-+
-+#endif /* !defined(_PCMCIA_PXA_H) */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/pxa/pxa_idp.c 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,297 @@
-+/*
-+ * linux/drivers/pcmcia/pxa/pxa_idp.c
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Copyright (c) 2002 Accelent Systems, Inc. All Rights Reserved
-+ *
-+ * Platform specific routines for the Accelent PXA250 IDP, based on those
-+ * first done for the Lubbock.
-+ *
-+ * Version 1.0 2002-05-02 Jeff Sutherland <jeffs@accelent.com>
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+
-+#include <pcmcia/ss.h>
-+
-+#include <asm/delay.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/arch/pcmcia.h>
-+
-+static int
-+pxa_idp_pcmcia_init(struct pcmcia_init *init)
-+{
-+ int return_val = 0;
-+
-+ /* Set PCMCIA Socket 0 power to standby mode.
-+ * PXA IDP has dedicated CPLD pins for all this stuff :-)
-+ */
-+
-+ /* both slots disabled, reset NOT active */
-+ IDP_CPLD_PCCARD_EN = PCC0_ENABLE | PCC1_ENABLE;
-+
-+ IDP_CPLD_PCCARD_PWR = 0; //all power to both slots off
-+
-+ GPDR(IRQ_TO_GPIO_2_80(PCMCIA_S0_CD_VALID)) &=
-+ ~GPIO_bit(IRQ_TO_GPIO_2_80(PCMCIA_S0_CD_VALID));
-+ GPDR(IRQ_TO_GPIO_2_80(PCMCIA_S1_CD_VALID)) &=
-+ ~GPIO_bit(IRQ_TO_GPIO_2_80(PCMCIA_S1_CD_VALID));
-+
-+ set_GPIO_IRQ_edge(IRQ_TO_GPIO_2_80(PCMCIA_S0_CD_VALID),
-+ GPIO_BOTH_EDGES);
-+ set_GPIO_IRQ_edge(IRQ_TO_GPIO_2_80(PCMCIA_S1_CD_VALID),
-+ GPIO_BOTH_EDGES);
-+
-+ /* irq's for slots: */
-+ GPDR(IRQ_TO_GPIO_2_80(PCMCIA_S0_RDYINT)) &=
-+ ~GPIO_bit(IRQ_TO_GPIO_2_80(PCMCIA_S0_RDYINT));
-+ GPDR(IRQ_TO_GPIO_2_80(PCMCIA_S1_RDYINT)) &=
-+ ~GPIO_bit(IRQ_TO_GPIO_2_80(PCMCIA_S1_RDYINT));
-+
-+ set_GPIO_IRQ_edge(IRQ_TO_GPIO_2_80(PCMCIA_S0_RDYINT),
-+ GPIO_FALLING_EDGE);
-+ set_GPIO_IRQ_edge(IRQ_TO_GPIO_2_80(PCMCIA_S1_RDYINT),
-+ GPIO_FALLING_EDGE);
-+
-+ return_val =
-+ request_irq(PCMCIA_S0_CD_VALID, init->handler, SA_INTERRUPT,
-+ "PXA PCMCIA CD0", NULL);
-+
-+ if (return_val < 0)
-+ return -1;
-+
-+ return_val +=
-+ request_irq(PCMCIA_S1_CD_VALID, init->handler, SA_INTERRUPT,
-+ "PXA PCMCIA CD1", NULL);
-+
-+ if (return_val < 0) {
-+ free_irq(PCMCIA_S0_CD_VALID, NULL);
-+ return -1;
-+ }
-+
-+ return 2;
-+}
-+
-+static int
-+pxa_idp_pcmcia_shutdown(void)
-+{
-+
-+ free_irq(PCMCIA_S0_CD_VALID, NULL);
-+ free_irq(PCMCIA_S1_CD_VALID, NULL);
-+
-+ IDP_CPLD_PCCARD_EN = 0x03; //disable slots
-+ udelay(200);
-+ IDP_CPLD_PCCARD_PWR = 0; //shut off all power
-+
-+ return 0;
-+}
-+
-+static int
-+pxa_idp_pcmcia_socket_state(struct pcmcia_state_array *state_array)
-+{
-+ unsigned long status;
-+ int return_val = 1;
-+ int i;
-+ volatile unsigned long *stat_regs[2] = { &IDP_CPLD_PCCARD0_STATUS,
-+ &IDP_CPLD_PCCARD1_STATUS
-+ };
-+
-+ if (state_array->size < 2)
-+ return -1;
-+
-+ memset(state_array->state, 0,
-+ (state_array->size) * sizeof (struct pcmcia_state));
-+
-+ for (i = 0; i < 2; i++) {
-+
-+ status = *stat_regs[i];
-+
-+ /* this one is a gpio */
-+ state_array->state[i].detect = (PCC_DETECT(i)) ? 0 : 1;
-+
-+ state_array->state[i].ready =
-+ ((status & _PCC_IRQ) == 0) ? 0 : 1;
-+ state_array->state[i].bvd1 = (status & PCC_BVD1) ? 0 : 1;
-+ state_array->state[i].bvd2 = (status & PCC_BVD2) ? 0 : 1;
-+ state_array->state[i].wrprot =
-+ (status & _PCC_WRPROT) ? 1 : 0;
-+ state_array->state[i].vs_3v = (status & PCC_VS1) ? 0 : 1;
-+ state_array->state[i].vs_Xv = (status & PCC_VS2) ? 0 : 1;
-+ }
-+
-+ return return_val;
-+}
-+
-+static int
-+pxa_idp_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-+{
-+ switch (info->sock) {
-+ case 0:
-+ info->irq = PCMCIA_S0_RDYINT;
-+ break;
-+
-+ case 1:
-+ info->irq = PCMCIA_S1_RDYINT;
-+ break;
-+
-+ default:
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+pxa_idp_pcmcia_configure_socket(unsigned int sock, socket_state_t *state)
-+{
-+ /* The PXA Idp uses the Maxim MAX1602, with the following connections:
-+ *
-+ * Socket 0 (PCMCIA):
-+ * MAX1602 PXA_IDP Register
-+ * Pin Signal IDP_CPLD_PCCARD_PWR:
-+ * ----- ------- ----------------------
-+ * A0VPP PCC0_PWR0 bit0
-+ * A1VPP PCC0_PWR1 bit1
-+ * A0VCC PCC0_PWR2 bit2
-+ * A1VCC PCC0_PWR3 bit3
-+ * VX VCC
-+ * VY +3.3V
-+ * 12IN +12V
-+ * CODE +3.3V Cirrus Code, CODE = High (VY)
-+ *
-+ * Socket 1 (PCMCIA):
-+ * MAX1602 PXA_IDP Register
-+ * Pin Signal IDP_CPLD_PCCARD_PWR:
-+ * ----- ------- ----------------------
-+ * A0VPP PCC1_PWR0 bit4
-+ * A1VPP PCC1_PWR1 bit5
-+ * A0VCC PCC1_PWR2 bit6
-+ * A1VCC PCC1_PWR3 bit7
-+ * VX VCC
-+ * VY +3.3V
-+ * 12IN +12V
-+ * CODE +3.3V Cirrus Code, CODE = High (VY)
-+ *
-+ */
-+
-+ switch (sock) {
-+ case 0:
-+ switch (state->Vcc) {
-+ case 0:
-+ IDP_CPLD_PCCARD_EN |= PCC0_ENABLE; // disable socket
-+ udelay(200);
-+ IDP_CPLD_PCCARD_PWR &= ~(PCC0_PWR2 | PCC0_PWR3);
-+ break;
-+
-+ case 33:
-+ IDP_CPLD_PCCARD_PWR &= ~(PCC0_PWR2 | PCC0_PWR3);
-+ IDP_CPLD_PCCARD_PWR |= PCC0_PWR3;
-+ IDP_CPLD_PCCARD_EN &= ~PCC0_ENABLE; //turn it on
-+ break;
-+
-+ case 50:
-+ IDP_CPLD_PCCARD_PWR &= ~(PCC0_PWR2 | PCC0_PWR3);
-+ IDP_CPLD_PCCARD_PWR |= PCC0_PWR2;
-+ IDP_CPLD_PCCARD_EN &= ~PCC0_ENABLE;
-+ break;
-+
-+ default:
-+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-+ __FUNCTION__, state->Vcc);
-+ return -1;
-+ }
-+
-+ switch (state->Vpp) {
-+ case 0:
-+ IDP_CPLD_PCCARD_PWR &= ~(PCC0_PWR0 | PCC0_PWR1);
-+ break;
-+
-+ case 120:
-+ IDP_CPLD_PCCARD_PWR &= ~(PCC0_PWR0 | PCC0_PWR1);
-+ IDP_CPLD_PCCARD_PWR |= PCC0_PWR1;
-+ break;
-+
-+ default:
-+ if (state->Vpp == state->Vcc)
-+ IDP_CPLD_PCCARD_PWR =
-+ (IDP_CPLD_PCCARD_PWR &
-+ ~(PCC0_PWR0 | PCC0_PWR1)) | PCC0_PWR0;
-+ else {
-+ printk(KERN_ERR "%s(): unrecognized Vpp %u\n",
-+ __FUNCTION__, state->Vpp);
-+ return -1;
-+ }
-+ }
-+
-+ IDP_CPLD_PCCARD_EN =
-+ (state->flags & SS_RESET) ? (IDP_CPLD_PCCARD_EN | PCC0_RESET)
-+ : (IDP_CPLD_PCCARD_EN & ~PCC0_RESET);
-+ break;
-+
-+ case 1:
-+ switch (state->Vcc) {
-+ case 0:
-+ IDP_CPLD_PCCARD_EN |= PCC1_ENABLE; // disable socket
-+ udelay(200);
-+ IDP_CPLD_PCCARD_PWR &= ~(PCC1_PWR2 | PCC1_PWR3);
-+ break;
-+
-+ case 33:
-+ IDP_CPLD_PCCARD_PWR &= ~(PCC1_PWR2 | PCC1_PWR3);
-+ IDP_CPLD_PCCARD_PWR |= PCC1_PWR3;
-+ IDP_CPLD_PCCARD_EN &= ~PCC1_ENABLE; //turn it on
-+ break;
-+
-+ case 50:
-+ IDP_CPLD_PCCARD_PWR &= ~(PCC1_PWR2 | PCC1_PWR3);
-+ IDP_CPLD_PCCARD_PWR |= PCC1_PWR2;
-+ IDP_CPLD_PCCARD_EN &= ~PCC1_ENABLE;
-+ break;
-+
-+ default:
-+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-+ __FUNCTION__, state->Vcc);
-+ return -1;
-+ }
-+
-+ switch (state->Vpp) {
-+ case 0:
-+ IDP_CPLD_PCCARD_PWR &= ~(PCC1_PWR0 | PCC1_PWR1);
-+ break;
-+
-+ case 120:
-+ IDP_CPLD_PCCARD_PWR &= ~(PCC1_PWR0 | PCC1_PWR1);
-+ IDP_CPLD_PCCARD_PWR |= PCC1_PWR1;
-+ break;
-+
-+ default:
-+ if (state->Vpp == state->Vcc)
-+ IDP_CPLD_PCCARD_PWR =
-+ (IDP_CPLD_PCCARD_PWR &
-+ ~(PCC1_PWR0 | PCC1_PWR1)) | PCC1_PWR0;
-+ else {
-+ printk(KERN_ERR "%s(): unrecognized Vpp %u\n",
-+ __FUNCTION__, state->Vpp);
-+ return -1;
-+ }
-+ }
-+ IDP_CPLD_PCCARD_EN = (state->flags & SS_RESET) ? (IDP_CPLD_PCCARD_EN | PCC1_RESET)
-+ : (IDP_CPLD_PCCARD_EN & ~PCC1_RESET);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+struct pcmcia_low_level pxa_idp_pcmcia_ops = {
-+ pxa_idp_pcmcia_init,
-+ pxa_idp_pcmcia_shutdown,
-+ pxa_idp_pcmcia_socket_state,
-+ pxa_idp_pcmcia_get_irq_info,
-+ pxa_idp_pcmcia_configure_socket
-+};
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/pxa/trizeps2.c 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,187 @@
-+/*
-+ * linux/drivers/pcmcia/pxa/trizeps2.c
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Copyright (c) 2002 Accelent Systems, Inc. All Rights Reserved
-+ *
-+ * Platform specific routines for the Keith-n-Koep Trizeps-II, based on IDP
-+ *
-+ * Copyright (c) 2003 Teradyne DS, Ltd.
-+ * Port to Trizeps-2 MT6N board by Luc De Cock
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+
-+#include <pcmcia/ss.h>
-+
-+#include <asm/delay.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/arch/pcmcia.h>
-+
-+static int trizeps2_pcmcia_init(struct pcmcia_init *init)
-+{
-+ int return_val = 0;
-+ unsigned short *bcr = (unsigned short *) TRIZEPS2_BCR_BASE;
-+ unsigned short val;
-+
-+ /* reset the PCMCIA controller */
-+ val = trizeps2_bcr_shadow | BCR_PCMCIA_RESET;
-+ *bcr = val;
-+ udelay(500);
-+ /* un-reset it again */
-+ trizeps2_bcr_shadow &= ~BCR_PCMCIA_RESET;
-+ /* enable the PCMCIA buffer */
-+ trizeps2_bcr_shadow &= ~(1 << 5);
-+ *bcr = trizeps2_bcr_shadow;
-+
-+ GPDR(IRQ_TO_GPIO_2_80(PCMCIA_S_CD_VALID)) &=
-+ ~GPIO_bit(IRQ_TO_GPIO_2_80(PCMCIA_S_CD_VALID));
-+ set_GPIO_IRQ_edge(IRQ_TO_GPIO_2_80(PCMCIA_S_CD_VALID),
-+ PCMCIA_S_CD_VALID_EDGE);
-+ GPDR(IRQ_TO_GPIO(PCMCIA_S_RDYINT)) &=
-+ ~GPIO_bit(IRQ_TO_GPIO(PCMCIA_S_RDYINT));
-+ set_GPIO_IRQ_edge(IRQ_TO_GPIO(PCMCIA_S_RDYINT),
-+ PCMCIA_S_RDYINT_EDGE);
-+
-+ return_val = request_irq(PCMCIA_S_CD_VALID, init->handler, SA_INTERRUPT,
-+ "PXA PCMCIA CD", NULL);
-+ if (return_val < 0) {
-+ return -1;
-+ }
-+ /* only 1 slot */
-+ return 1;
-+}
-+
-+static int trizeps2_pcmcia_shutdown(void)
-+{
-+ free_irq(PCMCIA_S_CD_VALID, NULL);
-+
-+ unsigned short *bcr = (unsigned short *) TRIZEPS2_BCR_BASE;
-+ trizeps2_bcr_shadow |= (1 << 5); /* pcmcia buffer off */
-+ *bcr = trizeps2_bcr_shadow;
-+ trizeps2_bcr_shadow &= 0xFFF0; /* pcmcia control logic grounded */
-+ *bcr = trizeps2_bcr_shadow;
-+
-+ return 0;
-+}
-+
-+static int trizeps2_pcmcia_socket_state(struct pcmcia_state_array *state_array)
-+{
-+ unsigned long status;
-+ int return_val = 1;
-+ volatile unsigned short *stat_regs[1] = {
-+ &TRIZEPS2_PCCARD_STATUS
-+ };
-+
-+ if (state_array->size < 1)
-+ return -1;
-+
-+ memset(state_array->state, 0,
-+ (state_array->size) * sizeof (struct pcmcia_state));
-+
-+ status = *stat_regs[0];
-+
-+ /* this one is a gpio */
-+ state_array->state[0].detect = (PCC_DETECT) ? 0 : 1;
-+ state_array->state[0].ready = (PCC_READY) ? 1 : 0;
-+ state_array->state[0].bvd1 = (status & PCC_BVD1) ? 1 : 0;
-+ state_array->state[0].bvd2 = (status & PCC_BVD2) ? 1 : 0;
-+ state_array->state[0].wrprot = 0; /* r/w all the time */
-+ state_array->state[0].vs_3v = (status & PCC_VS1) ? 0 : 1;
-+ state_array->state[0].vs_Xv = (status & PCC_VS2) ? 0 : 1;
-+
-+ return return_val;
-+}
-+
-+static int trizeps2_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-+{
-+ switch (info->sock) {
-+ case 0:
-+ info->irq = PCMCIA_S_RDYINT;
-+ break;
-+
-+ default:
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+static int trizeps2_pcmcia_configure_socket(unsigned int sock, socket_state_t *state)
-+{
-+ unsigned short cntr_logic = trizeps2_bcr_shadow & 0xF;
-+ unsigned short *bcr = (unsigned short *) TRIZEPS2_BCR_BASE;
-+
-+ /* configure Vcc and Vpp */
-+ switch (sock) {
-+ case 0:
-+ switch (state->Vcc) {
-+ case 0:
-+ cntr_logic &= ~(PCC_3V | PCC_5V);
-+ break;
-+
-+ case 33:
-+ cntr_logic &= ~(PCC_3V | PCC_5V);
-+ cntr_logic |= PCC_3V;
-+ break;
-+
-+ case 50:
-+ cntr_logic &= ~(PCC_3V | PCC_5V);
-+ cntr_logic |= PCC_5V;
-+ break;
-+
-+ default:
-+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-+ __FUNCTION__, state->Vcc);
-+ return -1;
-+ }
-+
-+ switch (state->Vpp) {
-+ case 0:
-+ cntr_logic &= ~(PCC_EN0 | PCC_EN1);
-+ break;
-+
-+ case 120:
-+ cntr_logic &= ~(PCC_EN0 | PCC_EN1);
-+ cntr_logic |= PCC_EN1;
-+ break;
-+
-+ default:
-+ if (state->Vpp == state->Vcc) {
-+ cntr_logic &= ~(PCC_EN0 | PCC_EN1);
-+ cntr_logic |= PCC_EN0;
-+ }
-+ else {
-+ printk(KERN_ERR "%s(): unrecognized Vpp %u\n",
-+ __FUNCTION__, state->Vpp);
-+ return -1;
-+ }
-+ }
-+ trizeps2_bcr_shadow &= ~(PCC_EN0 | PCC_EN1 | PCC_3V | PCC_5V |
-+ BCR_PCMCIA_RESET);
-+ trizeps2_bcr_shadow |= cntr_logic;
-+ *bcr = trizeps2_bcr_shadow;
-+ /* reset PCMCIA controller if requested */
-+ trizeps2_bcr_shadow |=
-+ (state->flags & SS_RESET) ? BCR_PCMCIA_RESET : 0;
-+ *bcr = trizeps2_bcr_shadow;
-+ udelay(500);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+struct pcmcia_low_level trizeps2_pcmcia_ops = {
-+ trizeps2_pcmcia_init,
-+ trizeps2_pcmcia_shutdown,
-+ trizeps2_pcmcia_socket_state,
-+ trizeps2_pcmcia_get_irq_info,
-+ trizeps2_pcmcia_configure_socket
-+};
-+
---- linux-2.4.25/drivers/pcmcia/sa1100_cerf.c~2.4.25-vrs2-pxa1.patch 2002-08-03 02:39:44.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/sa1100_cerf.c 2004-03-31 17:15:12.000000000 +0200
-@@ -7,15 +7,25 @@
- */
- #include <linux/kernel.h>
- #include <linux/sched.h>
-+#include <linux/delay.h>
-
- #include <asm/hardware.h>
- #include <asm/irq.h>
--#include "sa1100_generic.h"
-
--#ifdef CONFIG_SA1100_CERF_CPLD
--#define CERF_SOCKET 0
-+#include <pcmcia/ss.h>
-+#include <asm/arch/pcmcia.h>
-+#include "sa1100_cerf.h"
-+
-+/*
-+ * Set this to zero to remove all the debug statements via
-+ * dead code elimination
-+ */
-+//#define DEBUGGING 1
-+
-+#if DEBUGGING
-+static unsigned int pcmcia_debug = DEBUGGING;
- #else
--#define CERF_SOCKET 1
-+#define pcmcia_debug 0 /* gcc will remove all the debug code for us */
- #endif
-
- static struct irqs {
-@@ -23,122 +33,178 @@
- unsigned int gpio;
- const char *str;
- } irqs[] = {
-- { IRQ_GPIO_CF_CD, GPIO_CF_CD, "CF_CD" },
-- { IRQ_GPIO_CF_BVD2, GPIO_CF_BVD2, "CF_BVD2" },
-- { IRQ_GPIO_CF_BVD1, GPIO_CF_BVD1, "CF_BVD1" }
-+ { PCMCIA_IRQ_CF_CD, PCMCIA_GPIO_CF_CD_EDGE, "CF_CD" },
-+ { PCMCIA_IRQ_CF_BVD2, PCMCIA_GPIO_CF_BVD2_EDGE, "CF_BVD2" },
-+ { PCMCIA_IRQ_CF_BVD1, PCMCIA_GPIO_CF_BVD1_EDGE, "CF_BVD1" }
- };
-
-+static void cerf_pcmcia_reset( void)
-+{
-+ int i;
-+
-+ // Make sure SKTSEL is 0 (single slot)
-+ set_GPIO_mode(54 | GPIO_OUT);
-+ GPCR1 = GPIO_bit(54);
-+ set_GPIO_mode(GPIO54_pSKTSEL_MD);
-+
-+ PCMCIA_GPCR = PCMCIA_GPIO_CF_RESET_MASK;
-+ mdelay(300);
-+
-+ PCMCIA_GPSR = PCMCIA_GPIO_CF_RESET_MASK;
-+ udelay(20);
-+
-+ PCMCIA_GPCR = PCMCIA_GPIO_CF_RESET_MASK;
-+ mdelay(50);
-+
-+ for( i=0; i<10; i++)
-+ {
-+ if( cerf_pcmcia_level_ready()) break;
-+ mdelay(100);
-+ }
-+}
-+
- static int cerf_pcmcia_init(struct pcmcia_init *init)
- {
-- int i, res;
-+ int i, res;
-
-- set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
-+ if( pcmcia_debug)
-+ printk( KERN_INFO "cerf_pcmcia_init: enter\n");
-
-- for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-- set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_NO_EDGES);
-- res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
-- irqs[i].str, NULL);
-- if (res)
-- goto irq_err;
-- }
-+ cerf_pcmcia_set_gpio_direction();
-
-- return 2;
-+ set_GPIO_IRQ_edge( PCMCIA_GPIO_CF_IRQ_EDGE, GPIO_FALLING_EDGE );
-
-- irq_err:
-- printk(KERN_ERR "%s: Request for IRQ%d failed\n", __FUNCTION__, irqs[i].irq);
-+ for (i = 0; i < ARRAY_SIZE(irqs); i++) {
-
-- while (i--)
-- free_irq(irqs[i].irq, NULL);
-+ set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_BOTH_EDGES);
-
-- return -1;
-+ res = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
-+ irqs[i].str, NULL);
-+ if (res)
-+ goto irq_err;
-+ }
-+
-+ printk( KERN_INFO "PCMCIA for Cerf: OK\n");
-+
-+ return CERF_SOCKET+1; /* last socket used +1 */
-+
-+irq_err:
-+ printk(KERN_ERR "%s: Request for IRQ%d failed\n",
-+ __FUNCTION__, irqs[i].irq);
-+
-+ while (i--)
-+ free_irq(irqs[i].irq, NULL);
-+
-+ return -1;
- }
-
- static int cerf_pcmcia_shutdown(void)
- {
-- int i;
-+ int i;
-+ if( pcmcia_debug)
-+ printk( KERN_INFO "cerf_pcmcia_shutdown: enter\n");
-
-- for (i = 0; i < ARRAY_SIZE(irqs); i++)
-- free_irq(irqs[i].irq, NULL);
-+ for (i = 0; i < ARRAY_SIZE(irqs); i++)
-+ free_irq(irqs[i].irq, NULL);
-
-- return 0;
-+ return 0;
- }
-
--static int cerf_pcmcia_socket_state(struct pcmcia_state_array
-- *state_array){
-- unsigned long levels;
-- int i = CERF_SOCKET;
-+static int cerf_pcmcia_socket_state(struct pcmcia_state_array *state_array)
-+{
-+ int i = CERF_SOCKET;
-
-- if(state_array->size<2) return -1;
-+ if( pcmcia_debug > 3)
-+ printk( KERN_INFO "cerf_pcmcia_socket_state: i=%d, size=%d\n",
-+ i, state_array->size);
-
-- levels=GPLR;
-+ memset(state_array->state, 0,
-+ (state_array->size)*sizeof(struct pcmcia_state));
-
-- state_array->state[i].detect=((levels & GPIO_CF_CD)==0)?1:0;
-- state_array->state[i].ready=(levels & GPIO_CF_IRQ)?1:0;
-- state_array->state[i].bvd1=(levels & GPIO_CF_BVD1)?1:0;
-- state_array->state[i].bvd2=(levels & GPIO_CF_BVD2)?1:0;
-- state_array->state[i].wrprot=0;
-- state_array->state[i].vs_3v=1;
-- state_array->state[i].vs_Xv=0;
-+ state_array->state[i].detect = cerf_pcmcia_level_detect();
-+ state_array->state[i].ready = cerf_pcmcia_level_ready();
-+ state_array->state[i].bvd1 = cerf_pcmcia_level_bvd1();
-+ state_array->state[i].bvd2 = cerf_pcmcia_level_bvd2();
-+ state_array->state[i].wrprot=0;
-+ state_array->state[i].vs_3v=1;
-+ state_array->state[i].vs_Xv=0;
-
-- return 1;
-+ if( pcmcia_debug > 3)
-+ printk( KERN_INFO "cerf_pcmcia_socket_state: "
-+ "detect=%d ready=%d bvd1=%d bvd2=%d\n",
-+ state_array->state[i].detect,
-+ state_array->state[i].ready,
-+ state_array->state[i].bvd1,
-+ state_array->state[i].bvd2);
-+
-+ return 1;
- }
-
- static int cerf_pcmcia_get_irq_info(struct pcmcia_irq_info *info){
-
-- if(info->sock>1) return -1;
-+ if( pcmcia_debug)
-+ printk( KERN_INFO "cerf_pcmcia_get_irq_info: "
-+ "sock=%d\n", info->sock);
-
-- if (info->sock == CERF_SOCKET)
-- info->irq=IRQ_GPIO_CF_IRQ;
-+ if(info->sock>1) return -1;
-
-- return 0;
-+ if (info->sock == CERF_SOCKET)
-+ info->irq=PCMCIA_IRQ_CF_IRQ;
-+
-+ if( pcmcia_debug)
-+ printk( KERN_INFO "cerf_pcmcia_get_irq_info: irq=%d\n",info->irq);
-+
-+ return 0;
- }
-
--static int cerf_pcmcia_configure_socket(const struct pcmcia_configure
-- *configure)
-+static int cerf_pcmcia_configure_socket( unsigned int sock, socket_state_t *state)
- {
-- if(configure->sock>1)
-- return -1;
-+ if( pcmcia_debug)
-+ printk( KERN_INFO "cerf_pcmcia_configure_socket:"
-+ "sock=%d vcc=%d flags=%x\n",
-+ sock, state->Vcc, state->flags);
-
-- if (configure->sock != CERF_SOCKET)
-- return 0;
-+ if(sock>1)
-+ return -1;
-
-- switch(configure->vcc){
-- case 0:
-- break;
-+ if (sock != CERF_SOCKET)
-+ return 0;
-
-- case 50:
-- case 33:
--#ifdef CONFIG_SA1100_CERF_CPLD
-- GPCR = GPIO_PWR_SHUTDOWN;
-+ switch(state->Vcc){
-+ case 0:
-+ break;
-+
-+ case 50:
-+ case 33:
-+#if defined(CONFIG_SA1100_CERF_CPLD)
-+ PCMCIA_GPDR |= PCMCIA_PWR_SHUTDOWN;
-+ PCMCIA_GPCR |= PCMCIA_PWR_SHUTDOWN;
- #endif
-- break;
-+ /* voltage selected automatically */
-+ break;
-
-- default:
-- printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
-- configure->vcc);
-- return -1;
-- }
-+ default:
-+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-+ __FUNCTION__, state->Vcc);
-+ return -1;
-+ }
-
-- if(configure->reset)
-- {
--#ifdef CONFIG_SA1100_CERF_CPLD
-- GPSR = GPIO_CF_RESET;
--#endif
-- }
-- else
-- {
--#ifdef CONFIG_SA1100_CERF_CPLD
-- GPCR = GPIO_CF_RESET;
--#endif
-- }
-+ if(state->flags&SS_RESET)
-+ {
-+ cerf_pcmcia_reset();
-+ }
-
-- return 0;
-+ return 0;
- }
-
-+#ifdef CONFIG_SA1100_CERF
- static int cerf_pcmcia_socket_init(int sock)
- {
- int i;
-
-+ if( pcmcia_debug)
-+ printk( KERN_INFO "cerf_pcmcia_socket_init: sock=%d\n",sock);
-+
- if (sock == CERF_SOCKET)
- for (i = 0; i < ARRAY_SIZE(irqs); i++)
- set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_BOTH_EDGES);
-@@ -150,21 +216,26 @@
- {
- int i;
-
-+ if( pcmcia_debug)
-+ printk( KERN_INFO "cerf_pcmcia_socket_suspend: sock=%d\n",sock);
-+
- if (sock == CERF_SOCKET)
- for (i = 0; i < ARRAY_SIZE(irqs); i++)
- set_GPIO_IRQ_edge(irqs[i].gpio, GPIO_NO_EDGES);
-
- return 0;
- }
-+#endif
-
- struct pcmcia_low_level cerf_pcmcia_ops = {
-- init: cerf_pcmcia_init,
-- shutdown: cerf_pcmcia_shutdown,
-- socket_state: cerf_pcmcia_socket_state,
-- get_irq_info: cerf_pcmcia_get_irq_info,
-- configure_socket: cerf_pcmcia_configure_socket,
-+init: cerf_pcmcia_init,
-+shutdown: cerf_pcmcia_shutdown,
-+socket_state: cerf_pcmcia_socket_state,
-+get_irq_info: cerf_pcmcia_get_irq_info,
-+configure_socket: cerf_pcmcia_configure_socket,
-
-- socket_init: cerf_pcmcia_socket_init,
-- socket_suspend: cerf_pcmcia_socket_suspend,
-+#ifdef CONFIG_SA1100_CERF
-+socket_init: cerf_pcmcia_socket_init,
-+socket_suspend: cerf_pcmcia_socket_suspend,
-+#endif
- };
--
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/sa1100_cerf.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,138 @@
-+/*
-+ * drivers/pcmcia/cerf.h
-+ *
-+ * PCMCIA implementation routines for CerfBoard
-+ * Based off the Assabet.
-+ *
-+ */
-+#ifndef _LINUX_PCMCIA_CERF_H
-+#define _LINUX_PCMCIA_CERF_H
-+
-+#include <linux/config.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/arch/pcmcia.h>
-+
-+#ifdef CONFIG_PXA_CERF /* PXA */
-+
-+#define PCMCIA_GPCR GPCR0
-+#define PCMCIA_GPSR GPSR0
-+
-+#define PCMCIA_GPIO_CF_CD 14
-+#define PCMCIA_GPIO_CF_IRQ 13
-+#define PCMCIA_GPIO_CF_RESET 12
-+#ifdef CONFIG_PXA_CERF_PDA
-+# define PCMCIA_GPIO_CF_BVD1 11
-+# define PCMCIA_GPIO_CF_BVD2 10
-+#elif defined( CONFIG_PXA_CERF_BOARD)
-+# define PCMCIA_GPIO_CF_BVD1 32
-+# define PCMCIA_GPIO_CF_BVD2 10
-+#endif
-+
-+#define PCMCIA_GPIO_CF_CD_MASK (GPIO_bit(PCMCIA_GPIO_CF_CD))
-+#define PCMCIA_GPIO_CF_IRQ_MASK (GPIO_bit(PCMCIA_GPIO_CF_IRQ))
-+#define PCMCIA_GPIO_CF_RESET_MASK (GPIO_bit(PCMCIA_GPIO_CF_RESET))
-+#define PCMCIA_GPIO_CF_BVD1_MASK (GPIO_bit(PCMCIA_GPIO_CF_BVD1))
-+#define PCMCIA_GPIO_CF_BVD2_MASK (GPIO_bit(PCMCIA_GPIO_CF_BVD2))
-+
-+#define PCMCIA_GPIO_CF_CD_EDGE PCMCIA_GPIO_CF_CD
-+#define PCMCIA_GPIO_CF_IRQ_EDGE PCMCIA_GPIO_CF_IRQ
-+#define PCMCIA_GPIO_CF_RESET_EDGE PCMCIA_GPIO_CF_RESET
-+#define PCMCIA_GPIO_CF_BVD1_EDGE PCMCIA_GPIO_CF_BVD1
-+#define PCMCIA_GPIO_CF_BVD2_EDGE PCMCIA_GPIO_CF_BVD2
-+
-+#define PCMCIA_IRQ_CF_CD IRQ_GPIO(PCMCIA_GPIO_CF_CD)
-+#define PCMCIA_IRQ_CF_IRQ IRQ_GPIO(PCMCIA_GPIO_CF_IRQ)
-+#define PCMCIA_IRQ_CF_BVD1 IRQ_GPIO(PCMCIA_GPIO_CF_BVD1)
-+#define PCMCIA_IRQ_CF_BVD2 IRQ_GPIO(PCMCIA_GPIO_CF_BVD2)
-+
-+#define PCMCIA_PWR_SHUTDOWN 0 /* not needed */
-+#define CERF_SOCKET 0
-+
-+inline void cerf_pcmcia_set_gpio_direction(void)
-+{
-+ GPDR(PCMCIA_GPIO_CF_CD) &= ~(PCMCIA_GPIO_CF_CD_MASK);
-+ GPDR(PCMCIA_GPIO_CF_BVD1) &= ~(PCMCIA_GPIO_CF_BVD1_MASK);
-+ GPDR(PCMCIA_GPIO_CF_BVD2) &= ~(PCMCIA_GPIO_CF_BVD2_MASK);
-+ GPDR(PCMCIA_GPIO_CF_IRQ) &= ~(PCMCIA_GPIO_CF_IRQ_MASK);
-+ GPDR(PCMCIA_GPIO_CF_RESET)|= (PCMCIA_GPIO_CF_RESET_MASK);
-+}
-+
-+inline int cerf_pcmcia_level_detect( void)
-+{
-+ return ((GPLR(PCMCIA_GPIO_CF_CD)&PCMCIA_GPIO_CF_CD_MASK)==0)?1:0;
-+}
-+inline int cerf_pcmcia_level_ready( void)
-+{
-+ return (GPLR(PCMCIA_GPIO_CF_IRQ)&PCMCIA_GPIO_CF_IRQ_MASK)?1:0;
-+}
-+inline int cerf_pcmcia_level_bvd1( void)
-+{
-+ return (GPLR(PCMCIA_GPIO_CF_BVD1)&PCMCIA_GPIO_CF_BVD1_MASK)?1:0;
-+}
-+inline int cerf_pcmcia_level_bvd2( void)
-+{
-+ return (GPLR(PCMCIA_GPIO_CF_BVD2)&PCMCIA_GPIO_CF_BVD2_MASK)?1:0;
-+}
-+
-+#elif defined(CONFIG_SA1100_CERF) /* SA1100 */
-+
-+#define PCMCIA_GPDR GPDR
-+#define PCMCIA_GPCR GPCR
-+#define PCMCIA_GPSR GPSR
-+#define PCMCIA_GPLR GPLR
-+
-+#define PCMCIA_GPIO_CF_CD_MASK GPIO_CF_CD
-+#define PCMCIA_GPIO_CF_IRQ_MASK GPIO_CF_IRQ
-+#define PCMCIA_GPIO_CF_RESET_MASK GPIO_CF_RESET
-+#define PCMCIA_GPIO_CF_BVD1_MASK GPIO_CF_BVD1
-+#define PCMCIA_GPIO_CF_BVD2_MASK GPIO_CF_BVD2
-+
-+#define PCMCIA_GPIO_CF_CD_EDGE PCMCIA_GPIO_CF_CD_MASK
-+#define PCMCIA_GPIO_CF_IRQ_EDGE PCMCIA_GPIO_CF_IRQ_MASK
-+#define PCMCIA_GPIO_CF_RESET_EDGE PCMCIA_GPIO_CF_RESET_MASK
-+#define PCMCIA_GPIO_CF_BVD1_EDGE PCMCIA_GPIO_CF_BVD1_MASK
-+#define PCMCIA_GPIO_CF_BVD2_EDGE PCMCIA_GPIO_CF_BVD2_MASK
-+
-+#define PCMCIA_IRQ_CF_CD IRQ_GPIO_CF_CD
-+#define PCMCIA_IRQ_CF_IRQ IRQ_GPIO_CF_IRQ
-+#define PCMCIA_IRQ_CF_BVD1 IRQ_GPIO_CF_BVD1
-+#define PCMCIA_IRQ_CF_BVD2 IRQ_GPIO_CF_BVD2
-+
-+#define PCMCIA_PWR_SHUTDOWN GPIO_PWR_SHUTDOWN
-+
-+#ifdef CONFIG_SA1100_CERF_CPLD
-+#define CERF_SOCKET 0
-+#else
-+#define CERF_SOCKET 1
-+#endif
-+
-+inline void cerf_pcmcia_set_gpio_direction(void)
-+{
-+ PCMCIA_GPDR &= ~(PCMCIA_GPIO_CF_CD_MASK |
-+ PCMCIA_GPIO_CF_BVD1_MASK |
-+ PCMCIA_GPIO_CF_BVD2_MASK |
-+ PCMCIA_GPIO_CF_IRQ_MASK);
-+ PCMCIA_GPDR |= PCMCIA_GPIO_CF_RESET_MASK;
-+}
-+
-+inline int cerf_pcmcia_level_detect( void)
-+{
-+ return ((PCMCIA_GPLR & PCMCIA_GPIO_CF_CD_MASK)==0)?1:0;
-+}
-+inline int cerf_pcmcia_level_ready( void)
-+{
-+ return (PCMCIA_GPLR & PCMCIA_GPIO_CF_IRQ_MASK)?1:0;
-+}
-+inline int cerf_pcmcia_level_bvd1( void)
-+{
-+ return (PCMCIA_GPLR & PCMCIA_GPIO_CF_BVD1_MASK)?1:0;
-+}
-+inline int cerf_pcmcia_level_bvd2( void)
-+{
-+ return (PCMCIA_GPLR & PCMCIA_GPIO_CF_BVD2_MASK)?1:0;
-+}
-+
-+#endif
-+
-+#endif
---- linux-2.4.25/drivers/sound/Config.in~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/sound/Config.in 2004-03-31 17:15:12.000000000 +0200
-@@ -239,6 +239,7 @@
- dep_tristate ' VIDC 16-bit sound' CONFIG_SOUND_VIDC $CONFIG_SOUND_OSS
- fi
- dep_tristate ' Netwinder WaveArtist' CONFIG_SOUND_WAVEARTIST $CONFIG_SOUND_OSS $CONFIG_ARCH_NETWINDER
-+ dep_tristate ' Intel PXA250/210 AC97 audio' CONFIG_SOUND_PXA_AC97 $CONFIG_ARCH_PXA $CONFIG_SOUND
- fi
-
- dep_tristate ' TV card (bt848) mixer support' CONFIG_SOUND_TVMIXER $CONFIG_SOUND $CONFIG_I2C
---- linux-2.4.25/drivers/sound/Makefile~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/sound/Makefile 2004-03-31 17:15:12.000000000 +0200
-@@ -11,7 +11,7 @@
- msnd.o opl3.o sb_common.o sequencer_syms.o \
- sound_core.o sound_syms.o uart401.o \
- nm256_audio.o ac97.o ac97_codec.o aci.o \
-- sa1100-audio.o
-+ sa1100-audio.o pxa-audio.o pxa-ac97.o
-
- # Each configuration option enables a list of files.
-
-@@ -85,6 +85,7 @@
- obj-$(CONFIG_SOUND_SA1111_UDA1341) += sa1111-uda1341.o
- obj-$(CONFIG_SOUND_SA1111_AC97) += sa1111-ac97.o ac97_codec.o
- obj-$(CONFIG_SOUND_SA1100SSP) += sa1100ssp.o
-+obj-$(CONFIG_SOUND_PXA_AC97)+= pxa-ac97.o pxa-audio.o ac97_codec.o
- obj-$(CONFIG_SOUND_EMU10K1) += ac97_codec.o
- obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o
- obj-$(CONFIG_SOUND_RME96XX) += rme96xx.o
---- linux-2.4.25/drivers/sound/ac97_codec.c~2.4.25-vrs2-pxa1.patch 2003-11-28 19:26:20.000000000 +0100
-+++ linux-2.4.25/drivers/sound/ac97_codec.c 2004-03-31 17:15:12.000000000 +0200
-@@ -155,6 +155,7 @@
- {0x45838308, "ESS Allegro ES1988", &null_ops},
- {0x49434511, "ICE1232", &null_ops}, /* I hope --jk */
- {0x4e534331, "National Semiconductor LM4549", &null_ops},
-+ {0x50534304, "Philips UCB1400", &default_ops},
- {0x53494c22, "Silicon Laboratory Si3036", &null_ops},
- {0x53494c23, "Silicon Laboratory Si3038", &null_ops},
- {0x545200FF, "TriTech TR?????", &tritech_m_ops},
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/sound/pxa-ac97.c 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,370 @@
-+/*
-+ * linux/drivers/sound/pxa-ac97.c -- AC97 interface for the Cotula chip
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Aug 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * AC97 GPIO Changes:-
-+ * In order to read/write codec GPIO bits using AC97 link slot 12,
-+ * all IO to AC97_GPIO_STATUS must be via the Xscale modem codec
-+ * address space.
-+ * Liam Girdwood <liam.girdwood@wolfsonmicro.com>
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/pci.h>
-+#include <linux/completion.h>
-+#include <linux/delay.h>
-+#include <linux/poll.h>
-+#include <linux/sound.h>
-+#include <linux/soundcard.h>
-+#include <linux/ac97_codec.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+#include <asm/semaphore.h>
-+#include <asm/dma.h>
-+
-+#include "pxa-audio.h"
-+
-+static struct completion CAR_completion;
-+static int waitingForMask;
-+static DECLARE_MUTEX(CAR_mutex);
-+
-+static u16 pxa_ac97_read(struct ac97_codec *codec, u8 reg)
-+{
-+ u16 val = -1;
-+
-+ down(&CAR_mutex);
-+ if (!(CAR & CAR_CAIP)) {
-+ volatile u32 *reg_addr;
-+
-+ // if we are reading the GPIO status then this is cached
-+ // in hardware so we don't need to read over the link.
-+ if (reg == AC97_GPIO_STATUS) {
-+ reg_addr = (u32 *)&PMC_REG_BASE + (reg >> 1);
-+ val = *reg_addr;
-+ return val;
-+ }
-+
-+ reg_addr = (u32 *)&PAC_REG_BASE + (reg >> 1);
-+
-+ waitingForMask=GSR_SDONE;
-+
-+ init_completion(&CAR_completion);
-+ (void)*reg_addr; //start read access across the ac97 link
-+ wait_for_completion(&CAR_completion);
-+
-+ if (GSR & GSR_RDCS) {
-+ GSR |= GSR_RDCS; //write a 1 to clear
-+ printk(KERN_CRIT __FUNCTION__": read codec register timeout.\n");
-+ }
-+
-+ init_completion(&CAR_completion);
-+ val = *reg_addr; //valid data now but we've just started another cycle...
-+ wait_for_completion(&CAR_completion);
-+
-+ } else {
-+ printk(KERN_CRIT __FUNCTION__": CAR_CAIP already set\n");
-+ }
-+ up(&CAR_mutex);
-+ //printk("%s(0x%02x) = 0x%04x\n", __FUNCTION__, reg, val);
-+ return val;
-+}
-+
-+static void pxa_ac97_write(struct ac97_codec *codec, u8 reg, u16 val)
-+{
-+ down(&CAR_mutex);
-+ if (!(CAR & CAR_CAIP)) {
-+ volatile u32 *reg_addr;
-+
-+ // if we are writing to the codec GPIO using slot 12
-+ // then we have to write to the modem register space
-+ if (reg == AC97_GPIO_STATUS) {
-+ reg_addr = (u32 *)&PMC_REG_BASE + (reg >> 1);
-+ *reg_addr = val;
-+ return;
-+ }
-+
-+ reg_addr = (u32 *)&PAC_REG_BASE + (reg >> 1);
-+
-+ waitingForMask=GSR_CDONE;
-+ init_completion(&CAR_completion);
-+ *reg_addr = val;
-+ wait_for_completion(&CAR_completion);
-+ } else {
-+ printk(KERN_CRIT __FUNCTION__": CAR_CAIP already set\n");
-+ }
-+ up(&CAR_mutex);
-+ //printk("%s(0x%02x, 0x%04x)\n", __FUNCTION__, reg, val);
-+}
-+
-+static void pxa_ac97_irq(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ int gsr = GSR;
-+ GSR = gsr & (GSR_SDONE|GSR_CDONE); //write a 1 to clear
-+ if (gsr & waitingForMask)
-+ {
-+ complete(&CAR_completion);
-+ }
-+}
-+
-+static struct ac97_codec pxa_ac97_codec = {
-+ codec_read: pxa_ac97_read,
-+ codec_write: pxa_ac97_write,
-+};
-+
-+static DECLARE_MUTEX(pxa_ac97_mutex);
-+static int pxa_ac97_refcount;
-+
-+int pxa_ac97_get(struct ac97_codec **codec)
-+{
-+ int ret;
-+
-+ *codec = NULL;
-+ down(&pxa_ac97_mutex);
-+
-+ if (!pxa_ac97_refcount) {
-+ ret = request_irq(IRQ_AC97, pxa_ac97_irq, 0, "AC97", NULL);
-+ if (ret)
-+ return ret;
-+
-+ CKEN |= CKEN2_AC97;
-+ set_GPIO_mode(GPIO31_SYNC_AC97_MD);
-+ set_GPIO_mode(GPIO30_SDATA_OUT_AC97_MD);
-+ set_GPIO_mode(GPIO28_BITCLK_AC97_MD);
-+ set_GPIO_mode(GPIO29_SDATA_IN_AC97_MD);
-+
-+ GCR = 0;
-+ udelay(10);
-+ GCR = GCR_COLD_RST|GCR_CDONE_IE|GCR_SDONE_IE;
-+ while (!(GSR & GSR_PCR)) {
-+ schedule();
-+ }
-+
-+ ret = ac97_probe_codec(&pxa_ac97_codec);
-+ if (ret != 1) {
-+ free_irq(IRQ_AC97, NULL);
-+ GCR = GCR_ACLINK_OFF;
-+ CKEN &= ~CKEN2_AC97;
-+ return ret;
-+ }
-+
-+ // need little hack for UCB1400 (should be moved elsewhere)
-+ pxa_ac97_write(&pxa_ac97_codec,AC97_EXTENDED_STATUS,1);
-+ //pxa_ac97_write(&pxa_ac97_codec, 0x6a, 0x1ff7);
-+ pxa_ac97_write(&pxa_ac97_codec, 0x6a, 0x0050);
-+ pxa_ac97_write(&pxa_ac97_codec, 0x6c, 0x0030);
-+ }
-+
-+ pxa_ac97_refcount++;
-+ up(&pxa_ac97_mutex);
-+ *codec = &pxa_ac97_codec;
-+ return 0;
-+}
-+
-+void pxa_ac97_put(void)
-+{
-+ down(&pxa_ac97_mutex);
-+ pxa_ac97_refcount--;
-+ if (!pxa_ac97_refcount) {
-+ GCR = GCR_ACLINK_OFF;
-+ CKEN &= ~CKEN2_AC97;
-+ free_irq(IRQ_AC97, NULL);
-+ }
-+ up(&pxa_ac97_mutex);
-+}
-+
-+EXPORT_SYMBOL(pxa_ac97_get);
-+EXPORT_SYMBOL(pxa_ac97_put);
-+
-+
-+/*
-+ * Audio Mixer stuff
-+ */
-+
-+static audio_state_t ac97_audio_state;
-+static audio_stream_t ac97_audio_in;
-+
-+static int mixer_ioctl( struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ int ret, val;
-+
-+ ret = pxa_ac97_codec.mixer_ioctl(&pxa_ac97_codec, cmd, arg);
-+ if (ret)
-+ return ret;
-+
-+ /* We must snoop for some commands to provide our own extra processing */
-+ switch (cmd) {
-+ case SOUND_MIXER_WRITE_RECSRC:
-+ /*
-+ * According to the PXA250 spec, mic-in should use different
-+ * DRCMR and different AC97 FIFO.
-+ * Unfortunately current UCB1400 versions (up to ver 2A) don't
-+ * produce slot 6 for the audio input frame, therefore the PXA
-+ * AC97 mic-in FIFO is always starved.
-+ */
-+#if 0
-+ ret = get_user(val, (int *)arg);
-+ if (ret)
-+ return ret;
-+ pxa_audio_clear_buf(&ac97_audio_in);
-+ *ac97_audio_in.drcmr = 0;
-+ if (val & (1 << SOUND_MIXER_MIC)) {
-+ ac97_audio_in.dcmd = DCMD_RXMCDR;
-+ ac97_audio_in.drcmr = &DRCMRRXMCDR;
-+ ac97_audio_in.dev_addr = __PREG(MCDR);
-+ } else {
-+ ac97_audio_in.dcmd = DCMD_RXPCDR;
-+ ac97_audio_in.drcmr = &DRCMRRXPCDR;
-+ ac97_audio_in.dev_addr = __PREG(PCDR);
-+ }
-+ if (ac97_audio_state.rd_ref)
-+ *ac97_audio_in.drcmr =
-+ ac97_audio_in.dma_ch | DRCMR_MAPVLD;
-+#endif
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static struct file_operations mixer_fops = {
-+ ioctl: mixer_ioctl,
-+ llseek: no_llseek,
-+ owner: THIS_MODULE
-+};
-+
-+/*
-+ * AC97 codec ioctls
-+ */
-+
-+static int codec_adc_rate = 48000;
-+static int codec_dac_rate = 48000;
-+
-+static int ac97_ioctl(struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ int ret;
-+ long val;
-+
-+ switch(cmd) {
-+ case SNDCTL_DSP_STEREO:
-+ ret = get_user(val, (int *) arg);
-+ if (ret)
-+ return ret;
-+ /* FIXME: do we support mono? */
-+ ret = (val == 0) ? -EINVAL : 1;
-+ return put_user(ret, (int *) arg);
-+
-+ case SNDCTL_DSP_CHANNELS:
-+ case SOUND_PCM_READ_CHANNELS:
-+ /* FIXME: do we support mono? */
-+ return put_user(2, (long *) arg);
-+
-+ case SNDCTL_DSP_SPEED:
-+ ret = get_user(val, (long *) arg);
-+ if (ret)
-+ return ret;
-+ if (file->f_mode & FMODE_READ)
-+ codec_adc_rate = ac97_set_adc_rate(&pxa_ac97_codec, val);
-+ if (file->f_mode & FMODE_WRITE)
-+ codec_dac_rate = ac97_set_dac_rate(&pxa_ac97_codec, val);
-+ /* fall through */
-+
-+ case SOUND_PCM_READ_RATE:
-+ if (file->f_mode & FMODE_READ)
-+ val = codec_adc_rate;
-+ if (file->f_mode & FMODE_WRITE)
-+ val = codec_dac_rate;
-+ return put_user(val, (long *) arg);
-+
-+ case SNDCTL_DSP_SETFMT:
-+ case SNDCTL_DSP_GETFMTS:
-+ /* FIXME: can we do other fmts? */
-+ return put_user(AFMT_S16_LE, (long *) arg);
-+
-+ default:
-+ /* Maybe this is meant for the mixer (As per OSS Docs) */
-+ return mixer_ioctl(inode, file, cmd, arg);
-+ }
-+ return 0;
-+}
-+
-+
-+/*
-+ * Audio stuff
-+ */
-+
-+static audio_stream_t ac97_audio_out = {
-+ name: "AC97 audio out",
-+ dcmd: DCMD_TXPCDR,
-+ drcmr: &DRCMRTXPCDR,
-+ dev_addr: __PREG(PCDR),
-+};
-+
-+static audio_stream_t ac97_audio_in = {
-+ name: "AC97 audio in",
-+ dcmd: DCMD_RXPCDR,
-+ drcmr: &DRCMRRXPCDR,
-+ dev_addr: __PREG(PCDR),
-+};
-+
-+static audio_state_t ac97_audio_state = {
-+ output_stream: &ac97_audio_out,
-+ input_stream: &ac97_audio_in,
-+ client_ioctl: ac97_ioctl,
-+ sem: __MUTEX_INITIALIZER(ac97_audio_state.sem),
-+};
-+
-+static int ac97_audio_open(struct inode *inode, struct file *file)
-+{
-+ return pxa_audio_attach(inode, file, &ac97_audio_state);
-+}
-+
-+/*
-+ * Missing fields of this structure will be patched with the call
-+ * to pxa_audio_attach().
-+ */
-+
-+static struct file_operations ac97_audio_fops = {
-+ open: ac97_audio_open,
-+ owner: THIS_MODULE
-+};
-+
-+
-+static int __init pxa_ac97_init(void)
-+{
-+ int ret;
-+ struct ac97_codec *dummy;
-+
-+ ret = pxa_ac97_get(&dummy);
-+ if (ret)
-+ return ret;
-+
-+ ac97_audio_state.dev_dsp = register_sound_dsp(&ac97_audio_fops, -1);
-+ pxa_ac97_codec.dev_mixer = register_sound_mixer(&mixer_fops, -1);
-+
-+ return 0;
-+}
-+
-+static void __exit pxa_ac97_exit(void)
-+{
-+ unregister_sound_dsp(ac97_audio_state.dev_dsp);
-+ unregister_sound_mixer(pxa_ac97_codec.dev_mixer);
-+ pxa_ac97_put();
-+}
-+
-+
-+module_init(pxa_ac97_init);
-+module_exit(pxa_ac97_exit);
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/sound/pxa-audio.c 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,853 @@
-+/*
-+ * linux/drivers/sound/pxa-audio.c -- audio interface for the Cotula chip
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Aug 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/pci.h>
-+#include <linux/poll.h>
-+#include <linux/sound.h>
-+#include <linux/soundcard.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+#include <asm/semaphore.h>
-+#include <asm/dma.h>
-+
-+#include "pxa-audio.h"
-+
-+
-+#define AUDIO_NBFRAGS_DEFAULT 8
-+#define AUDIO_FRAGSIZE_DEFAULT 8192
-+
-+#define MAX_DMA_SIZE 4096
-+#define DMA_DESC_SIZE sizeof(pxa_dma_desc)
-+
-+
-+/*
-+ * This function frees all buffers
-+ */
-+#define audio_clear_buf pxa_audio_clear_buf
-+
-+void pxa_audio_clear_buf(audio_stream_t * s)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ int frag;
-+
-+ if (!s->buffers)
-+ return;
-+
-+ /* Ensure DMA isn't running */
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ add_wait_queue(&s->stop_wq, &wait);
-+ DCSR(s->dma_ch) = DCSR_STOPIRQEN;
-+ schedule();
-+ remove_wait_queue(&s->stop_wq, &wait);
-+
-+ /* free DMA buffers */
-+ for (frag = 0; frag < s->nbfrags; frag++) {
-+ audio_buf_t *b = &s->buffers[frag];
-+ if (!b->master)
-+ continue;
-+ consistent_free(b->data, b->master, b->dma_desc->dsadr);
-+ }
-+
-+ /* free descriptor ring */
-+ if (s->buffers->dma_desc)
-+ consistent_free(s->buffers->dma_desc,
-+ s->nbfrags * s->descs_per_frag * DMA_DESC_SIZE,
-+ s->dma_desc_phys);
-+
-+ /* free buffer structure array */
-+ kfree(s->buffers);
-+ s->buffers = NULL;
-+}
-+
-+/*
-+ * This function allocates the DMA descriptor array and buffer data space
-+ * according to the current number of fragments and fragment size.
-+ */
-+static int audio_setup_buf(audio_stream_t * s)
-+{
-+ pxa_dma_desc *dma_desc;
-+ dma_addr_t dma_desc_phys;
-+ int nb_desc, frag, i, buf_size = 0;
-+ char *dma_buf = NULL;
-+ dma_addr_t dma_buf_phys = 0;
-+
-+ if (s->buffers)
-+ return -EBUSY;
-+
-+ /* Our buffer structure array */
-+ s->buffers = kmalloc(sizeof(audio_buf_t) * s->nbfrags, GFP_KERNEL);
-+ if (!s->buffers)
-+ goto err;
-+ memzero(s->buffers, sizeof(audio_buf_t) * s->nbfrags);
-+
-+ /*
-+ * Our DMA descriptor array:
-+ * for Each fragment we have one checkpoint descriptor plus one
-+ * descriptor per MAX_DMA_SIZE byte data blocks.
-+ */
-+ nb_desc = (1 + (s->fragsize + MAX_DMA_SIZE - 1)/MAX_DMA_SIZE) * s->nbfrags;
-+ dma_desc = consistent_alloc(GFP_KERNEL,
-+ nb_desc * DMA_DESC_SIZE,
-+ &dma_desc_phys,
-+ 0);
-+ if (!dma_desc)
-+ goto err;
-+ s->descs_per_frag = nb_desc / s->nbfrags;
-+ s->buffers->dma_desc = dma_desc;
-+ s->dma_desc_phys = dma_desc_phys;
-+ for (i = 0; i < nb_desc - 1; i++)
-+ dma_desc[i].ddadr = dma_desc_phys + (i + 1) * DMA_DESC_SIZE;
-+ dma_desc[i].ddadr = dma_desc_phys;
-+
-+ /* Our actual DMA buffers */
-+ for (frag = 0; frag < s->nbfrags; frag++) {
-+ audio_buf_t *b = &s->buffers[frag];
-+
-+ /*
-+ * Let's allocate non-cached memory for DMA buffers.
-+ * We try to allocate all memory at once.
-+ * If this fails (a common reason is memory fragmentation),
-+ * then we'll try allocating smaller buffers.
-+ */
-+ if (!buf_size) {
-+ buf_size = (s->nbfrags - frag) * s->fragsize;
-+ do {
-+ dma_buf = consistent_alloc(GFP_KERNEL,
-+ buf_size,
-+ &dma_buf_phys,
-+ 0);
-+ if (!dma_buf)
-+ buf_size -= s->fragsize;
-+ } while (!dma_buf && buf_size);
-+ if (!dma_buf)
-+ goto err;
-+ b->master = buf_size;
-+ memzero(dma_buf, buf_size);
-+ }
-+
-+ /*
-+ * Set up our checkpoint descriptor. Since the count
-+ * is always zero, we'll abuse the dsadr and dtadr fields
-+ * just in case this one is picked up by the hardware
-+ * while processing SOUND_DSP_GETPTR.
-+ */
-+ dma_desc->dsadr = dma_buf_phys;
-+ dma_desc->dtadr = dma_buf_phys;
-+ dma_desc->dcmd = DCMD_ENDIRQEN;
-+ if (s->output && !s->mapped)
-+ dma_desc->ddadr |= DDADR_STOP;
-+ b->dma_desc = dma_desc++;
-+
-+ /* set up the actual data descriptors */
-+ for (i = 0; (i * MAX_DMA_SIZE) < s->fragsize; i++) {
-+ dma_desc[i].dsadr = (s->output) ?
-+ (dma_buf_phys + i*MAX_DMA_SIZE) : s->dev_addr;
-+ dma_desc[i].dtadr = (s->output) ?
-+ s->dev_addr : (dma_buf_phys + i*MAX_DMA_SIZE);
-+ dma_desc[i].dcmd = s->dcmd |
-+ ((s->fragsize < MAX_DMA_SIZE) ?
-+ s->fragsize : MAX_DMA_SIZE);
-+ }
-+ dma_desc += i;
-+
-+ /* handle buffer pointers */
-+ b->data = dma_buf;
-+ dma_buf += s->fragsize;
-+ dma_buf_phys += s->fragsize;
-+ buf_size -= s->fragsize;
-+ }
-+
-+ s->usr_frag = s->dma_frag = 0;
-+ s->bytecount = 0;
-+ s->fragcount = 0;
-+ sema_init(&s->sem, (s->output) ? s->nbfrags : 0);
-+ return 0;
-+
-+err:
-+ printk("pxa-audio: unable to allocate audio memory\n ");
-+ audio_clear_buf(s);
-+ return -ENOMEM;
-+}
-+
-+/*
-+ * Our DMA interrupt handler
-+ */
-+static void audio_dma_irq(int ch, void *dev_id, struct pt_regs *regs)
-+{
-+ audio_stream_t *s = dev_id;
-+ u_int dcsr;
-+
-+ dcsr = DCSR(ch);
-+ DCSR(ch) = dcsr & ~DCSR_STOPIRQEN;
-+
-+ if (!s->buffers) {
-+ printk("AC97 DMA: wow... received IRQ for channel %d but no buffer exists\n", ch);
-+ return;
-+ }
-+
-+ if (dcsr & DCSR_BUSERR)
-+ printk("AC97 DMA: bus error interrupt on channel %d\n", ch);
-+
-+ if (dcsr & DCSR_ENDINTR) {
-+ u_long cur_dma_desc;
-+ u_int cur_dma_frag;
-+
-+ /*
-+ * Find out which DMA desc is current. Note that DDADR
-+ * points to the next desc, not the current one.
-+ */
-+ cur_dma_desc = DDADR(ch) - s->dma_desc_phys - DMA_DESC_SIZE;
-+
-+ /*
-+ * Let the compiler nicely optimize constant divisors into
-+ * multiplications for the common cases which is much faster.
-+ * Common cases: x = 1 + (1 << y) for y = [0..3]
-+ */
-+ switch (s->descs_per_frag) {
-+ case 2: cur_dma_frag = cur_dma_desc / (2*DMA_DESC_SIZE); break;
-+ case 3: cur_dma_frag = cur_dma_desc / (3*DMA_DESC_SIZE); break;
-+ case 5: cur_dma_frag = cur_dma_desc / (5*DMA_DESC_SIZE); break;
-+ case 9: cur_dma_frag = cur_dma_desc / (9*DMA_DESC_SIZE); break;
-+ default: cur_dma_frag =
-+ cur_dma_desc / (s->descs_per_frag * DMA_DESC_SIZE);
-+ }
-+
-+ /* Account for possible wrap back of cur_dma_desc above */
-+ if (cur_dma_frag >= s->nbfrags)
-+ cur_dma_frag = s->nbfrags - 1;
-+
-+ while (s->dma_frag != cur_dma_frag) {
-+ if (!s->mapped) {
-+ /*
-+ * This fragment is done - set the checkpoint
-+ * descriptor to STOP until it is gets
-+ * processed by the read or write function.
-+ */
-+ s->buffers[s->dma_frag].dma_desc->ddadr |= DDADR_STOP;
-+ up(&s->sem);
-+ }
-+ if (++s->dma_frag >= s->nbfrags)
-+ s->dma_frag = 0;
-+
-+ /* Accounting */
-+ s->bytecount += s->fragsize;
-+ s->fragcount++;
-+ }
-+
-+ /* ... and for polling processes */
-+ wake_up(&s->frag_wq);
-+ }
-+
-+ if ((dcsr & DCSR_STOPIRQEN) && (dcsr & DCSR_STOPSTATE))
-+ wake_up(&s->stop_wq);
-+}
-+
-+/*
-+ * Validate and sets up buffer fragments, etc.
-+ */
-+static int audio_set_fragments(audio_stream_t *s, int val)
-+{
-+ if (s->mapped || DCSR(s->dma_ch) & DCSR_RUN)
-+ return -EBUSY;
-+ if (s->buffers)
-+ audio_clear_buf(s);
-+ s->nbfrags = (val >> 16) & 0x7FFF;
-+ val &= 0xffff;
-+ if (val < 5)
-+ val = 5;
-+ if (val > 15)
-+ val = 15;
-+ s->fragsize = 1 << val;
-+ if (s->nbfrags < 2)
-+ s->nbfrags = 2;
-+ if (s->nbfrags * s->fragsize > 256 * 1024)
-+ s->nbfrags = 256 * 1024 / s->fragsize;
-+ if (audio_setup_buf(s))
-+ return -ENOMEM;
-+ return val|(s->nbfrags << 16);
-+}
-+
-+
-+/*
-+ * The fops functions
-+ */
-+
-+static int audio_write(struct file *file, const char *buffer,
-+ size_t count, loff_t * ppos)
-+{
-+ const char *buffer0 = buffer;
-+ audio_state_t *state = (audio_state_t *)file->private_data;
-+ audio_stream_t *s = state->output_stream;
-+ int chunksize, ret = 0;
-+
-+ if (ppos != &file->f_pos)
-+ return -ESPIPE;
-+ if (s->mapped)
-+ return -ENXIO;
-+ if (!s->buffers && audio_setup_buf(s))
-+ return -ENOMEM;
-+
-+ while (count > 0) {
-+ audio_buf_t *b = &s->buffers[s->usr_frag];
-+
-+ /* Grab a fragment */
-+ if (file->f_flags & O_NONBLOCK) {
-+ ret = -EAGAIN;
-+ if (down_trylock(&s->sem))
-+ break;
-+ } else {
-+ ret = -ERESTARTSYS;
-+ if (down_interruptible(&s->sem))
-+ break;
-+ }
-+
-+ /* Feed the current buffer */
-+ chunksize = s->fragsize - b->offset;
-+ if (chunksize > count)
-+ chunksize = count;
-+ if (copy_from_user(b->data + b->offset, buffer, chunksize)) {
-+ up(&s->sem);
-+ return -EFAULT;
-+ }
-+ b->offset += chunksize;
-+ buffer += chunksize;
-+ count -= chunksize;
-+ if (b->offset < s->fragsize) {
-+ up(&s->sem);
-+ break;
-+ }
-+
-+ /*
-+ * Activate DMA on current buffer.
-+ * We unlock this fragment's checkpoint descriptor and
-+ * kick DMA if it is idle. Using checkpoint descriptors
-+ * allows for control operations without the need for
-+ * stopping the DMA channel if it is already running.
-+ */
-+ b->offset = 0;
-+ b->dma_desc->ddadr &= ~DDADR_STOP;
-+ if (DCSR(s->dma_ch) & DCSR_STOPSTATE) {
-+ DDADR(s->dma_ch) = b->dma_desc->ddadr;
-+ DCSR(s->dma_ch) = DCSR_RUN;
-+ }
-+
-+ /* move the index to the next fragment */
-+ if (++s->usr_frag >= s->nbfrags)
-+ s->usr_frag = 0;
-+ }
-+
-+ if ((buffer - buffer0))
-+ ret = buffer - buffer0;
-+ return ret;
-+}
-+
-+
-+static int audio_read(struct file *file, char *buffer,
-+ size_t count, loff_t * ppos)
-+{
-+ char *buffer0 = buffer;
-+ audio_state_t *state = file->private_data;
-+ audio_stream_t *s = state->input_stream;
-+ int chunksize, ret = 0;
-+
-+ if (ppos != &file->f_pos)
-+ return -ESPIPE;
-+ if (s->mapped)
-+ return -ENXIO;
-+ if (!s->buffers && audio_setup_buf(s))
-+ return -ENOMEM;
-+
-+ while (count > 0) {
-+ audio_buf_t *b = &s->buffers[s->usr_frag];
-+
-+ /* prime DMA */
-+ if (DCSR(s->dma_ch) & DCSR_STOPSTATE) {
-+ DDADR(s->dma_ch) =
-+ s->buffers[s->dma_frag].dma_desc->ddadr;
-+ DCSR(s->dma_ch) = DCSR_RUN;
-+ }
-+
-+ /* Wait for a buffer to become full */
-+ if (file->f_flags & O_NONBLOCK) {
-+ ret = -EAGAIN;
-+ if (down_trylock(&s->sem))
-+ break;
-+ } else {
-+ ret = -ERESTARTSYS;
-+ if (down_interruptible(&s->sem))
-+ break;
-+ }
-+
-+ /* Grab data from current buffer */
-+ chunksize = s->fragsize - b->offset;
-+ if (chunksize > count)
-+ chunksize = count;
-+ if (copy_to_user(buffer, b->data + b->offset, chunksize)) {
-+ up(&s->sem);
-+ return -EFAULT;
-+ }
-+ b->offset += chunksize;
-+ buffer += chunksize;
-+ count -= chunksize;
-+ if (b->offset < s->fragsize) {
-+ up(&s->sem);
-+ break;
-+ }
-+
-+ /*
-+ * Make this buffer available for DMA again.
-+ * We unlock this fragment's checkpoint descriptor and
-+ * kick DMA if it is idle. Using checkpoint descriptors
-+ * allows for control operations without the need for
-+ * stopping the DMA channel if it is already running.
-+ */
-+ b->offset = 0;
-+ b->dma_desc->ddadr &= ~DDADR_STOP;
-+
-+ /* move the index to the next fragment */
-+ if (++s->usr_frag >= s->nbfrags)
-+ s->usr_frag = 0;
-+ }
-+
-+ if ((buffer - buffer0))
-+ ret = buffer - buffer0;
-+ return ret;
-+}
-+
-+
-+static int audio_sync(struct file *file)
-+{
-+ audio_state_t *state = file->private_data;
-+ audio_stream_t *s = state->output_stream;
-+ audio_buf_t *b;
-+ pxa_dma_desc *final_desc;
-+ u_long dcmd_save = 0;
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+ if (!(file->f_mode & FMODE_WRITE) || !s->buffers || s->mapped)
-+ return 0;
-+
-+ /*
-+ * Send current buffer if it contains data. Be sure to send
-+ * a full sample count.
-+ */
-+ final_desc = NULL;
-+ b = &s->buffers[s->usr_frag];
-+ if (b->offset &= ~3) {
-+ final_desc = &b->dma_desc[1 + b->offset/MAX_DMA_SIZE];
-+ b->offset &= (MAX_DMA_SIZE-1);
-+ dcmd_save = final_desc->dcmd;
-+ final_desc->dcmd = b->offset | s->dcmd | DCMD_ENDIRQEN;
-+ final_desc->ddadr |= DDADR_STOP;
-+ b->offset = 0;
-+ b->dma_desc->ddadr &= ~DDADR_STOP;
-+ if (DCSR(s->dma_ch) & DCSR_STOPSTATE) {
-+ DDADR(s->dma_ch) = b->dma_desc->ddadr;
-+ DCSR(s->dma_ch) = DCSR_RUN;
-+ }
-+ }
-+
-+ /* Wait for DMA to complete. */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+#if 0
-+ /*
-+ * The STOPSTATE IRQ never seem to occur if DCSR_STOPIRQEN is set
-+ * along wotj DCSR_RUN. Silicon bug?
-+ */
-+ add_wait_queue(&s->stop_wq, &wait);
-+ DCSR(s->dma_ch) |= DCSR_STOPIRQEN;
-+ schedule();
-+#else
-+ add_wait_queue(&s->frag_wq, &wait);
-+ while ((DCSR(s->dma_ch) & DCSR_RUN) && !signal_pending(current)) {
-+ schedule();
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ }
-+#endif
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&s->frag_wq, &wait);
-+
-+ /* Restore the descriptor chain. */
-+ if (final_desc) {
-+ final_desc->dcmd = dcmd_save;
-+ final_desc->ddadr &= ~DDADR_STOP;
-+ b->dma_desc->ddadr |= DDADR_STOP;
-+ }
-+ return 0;
-+}
-+
-+
-+static unsigned int audio_poll(struct file *file,
-+ struct poll_table_struct *wait)
-+{
-+ audio_state_t *state = file->private_data;
-+ audio_stream_t *is = state->input_stream;
-+ audio_stream_t *os = state->output_stream;
-+ unsigned int mask = 0;
-+
-+ if (file->f_mode & FMODE_READ) {
-+ /* Start audio input if not already active */
-+ if (!is->buffers && audio_setup_buf(is))
-+ return -ENOMEM;
-+ if (DCSR(is->dma_ch) & DCSR_STOPSTATE) {
-+ DDADR(is->dma_ch) =
-+ is->buffers[is->dma_frag].dma_desc->ddadr;
-+ DCSR(is->dma_ch) = DCSR_RUN;
-+ }
-+ poll_wait(file, &is->frag_wq, wait);
-+ }
-+
-+ if (file->f_mode & FMODE_WRITE) {
-+ if (!os->buffers && audio_setup_buf(os))
-+ return -ENOMEM;
-+ poll_wait(file, &os->frag_wq, wait);
-+ }
-+
-+ if (file->f_mode & FMODE_READ)
-+ if (( is->mapped && is->bytecount > 0) ||
-+ (!is->mapped && atomic_read(&is->sem.count) > 0))
-+ mask |= POLLIN | POLLRDNORM;
-+
-+ if (file->f_mode & FMODE_WRITE)
-+ if (( os->mapped && os->bytecount > 0) ||
-+ (!os->mapped && atomic_read(&os->sem.count) > 0))
-+ mask |= POLLOUT | POLLWRNORM;
-+
-+ return mask;
-+}
-+
-+
-+static int audio_ioctl( struct inode *inode, struct file *file,
-+ uint cmd, ulong arg)
-+{
-+ audio_state_t *state = file->private_data;
-+ audio_stream_t *os = state->output_stream;
-+ audio_stream_t *is = state->input_stream;
-+ long val;
-+
-+ switch (cmd) {
-+ case OSS_GETVERSION:
-+ return put_user(SOUND_VERSION, (int *)arg);
-+
-+ case SNDCTL_DSP_GETBLKSIZE:
-+ if (file->f_mode & FMODE_WRITE)
-+ return put_user(os->fragsize, (int *)arg);
-+ else
-+ return put_user(is->fragsize, (int *)arg);
-+
-+ case SNDCTL_DSP_GETCAPS:
-+ val = DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP;
-+ if (is && os)
-+ val |= DSP_CAP_DUPLEX;
-+ return put_user(val, (int *)arg);
-+
-+ case SNDCTL_DSP_SETFRAGMENT:
-+ if (get_user(val, (long *) arg))
-+ return -EFAULT;
-+ if (file->f_mode & FMODE_READ) {
-+ int ret = audio_set_fragments(is, val);
-+ if (ret < 0)
-+ return ret;
-+ ret = put_user(ret, (int *)arg);
-+ if (ret)
-+ return ret;
-+ }
-+ if (file->f_mode & FMODE_WRITE) {
-+ int ret = audio_set_fragments(os, val);
-+ if (ret < 0)
-+ return ret;
-+ ret = put_user(ret, (int *)arg);
-+ if (ret)
-+ return ret;
-+ }
-+ return 0;
-+
-+ case SNDCTL_DSP_SYNC:
-+ return audio_sync(file);
-+
-+ case SNDCTL_DSP_SETDUPLEX:
-+ return 0;
-+
-+ case SNDCTL_DSP_POST:
-+ return 0;
-+
-+ case SNDCTL_DSP_GETTRIGGER:
-+ val = 0;
-+ if (file->f_mode & FMODE_READ && DCSR(is->dma_ch) & DCSR_RUN)
-+ val |= PCM_ENABLE_INPUT;
-+ if (file->f_mode & FMODE_WRITE && DCSR(os->dma_ch) & DCSR_RUN)
-+ val |= PCM_ENABLE_OUTPUT;
-+ return put_user(val, (int *)arg);
-+
-+ case SNDCTL_DSP_SETTRIGGER:
-+ if (get_user(val, (int *)arg))
-+ return -EFAULT;
-+ if (file->f_mode & FMODE_READ) {
-+ if (val & PCM_ENABLE_INPUT) {
-+ if (!is->buffers && audio_setup_buf(is))
-+ return -ENOMEM;
-+ if (!(DCSR(is->dma_ch) & DCSR_RUN)) {
-+ audio_buf_t *b = &is->buffers[is->dma_frag];
-+ DDADR(is->dma_ch) = b->dma_desc->ddadr;
-+ DCSR(is->dma_ch) = DCSR_RUN;
-+ }
-+ } else {
-+ DCSR(is->dma_ch) = 0;
-+ }
-+ }
-+ if (file->f_mode & FMODE_WRITE) {
-+ if (val & PCM_ENABLE_OUTPUT) {
-+ if (!os->buffers && audio_setup_buf(os))
-+ return -ENOMEM;
-+ if (!(DCSR(os->dma_ch) & DCSR_RUN)) {
-+ audio_buf_t *b = &os->buffers[os->dma_frag];
-+ DDADR(os->dma_ch) = b->dma_desc->ddadr;
-+ DCSR(os->dma_ch) = DCSR_RUN;
-+ }
-+ } else {
-+ DCSR(os->dma_ch) = 0;
-+ }
-+ }
-+ return 0;
-+
-+ case SNDCTL_DSP_GETOSPACE:
-+ case SNDCTL_DSP_GETISPACE:
-+ {
-+ audio_buf_info inf = { 0, };
-+ audio_stream_t *s = (cmd == SNDCTL_DSP_GETOSPACE) ? os : is;
-+
-+ if ((s == is && !(file->f_mode & FMODE_READ)) ||
-+ (s == os && !(file->f_mode & FMODE_WRITE)))
-+ return -EINVAL;
-+ if (!s->buffers && audio_setup_buf(s))
-+ return -ENOMEM;
-+ inf.bytes = atomic_read(&s->sem.count) * s->fragsize;
-+ inf.bytes -= s->buffers[s->usr_frag].offset;
-+ inf.fragments = inf.bytes / s->fragsize;
-+ inf.fragsize = s->fragsize;
-+ inf.fragstotal = s->nbfrags;
-+ return copy_to_user((void *)arg, &inf, sizeof(inf));
-+ }
-+
-+ case SNDCTL_DSP_GETOPTR:
-+ case SNDCTL_DSP_GETIPTR:
-+ {
-+ count_info inf = { 0, };
-+ audio_stream_t *s = (cmd == SNDCTL_DSP_GETOPTR) ? os : is;
-+ dma_addr_t ptr;
-+ int bytecount, offset, flags;
-+
-+ if ((s == is && !(file->f_mode & FMODE_READ)) ||
-+ (s == os && !(file->f_mode & FMODE_WRITE)))
-+ return -EINVAL;
-+ if (DCSR(s->dma_ch) & DCSR_RUN) {
-+ audio_buf_t *b;
-+ save_flags_cli(flags);
-+ ptr = (s->output) ? DSADR(s->dma_ch) : DTADR(s->dma_ch);
-+ b = &s->buffers[s->dma_frag];
-+ offset = ptr - b->dma_desc->dsadr;
-+ if (offset >= s->fragsize)
-+ offset = s->fragsize - 4;
-+ } else {
-+ save_flags(flags);
-+ offset = 0;
-+ }
-+ inf.ptr = s->dma_frag * s->fragsize + offset;
-+ bytecount = s->bytecount + offset;
-+ s->bytecount = -offset;
-+ inf.blocks = s->fragcount;
-+ s->fragcount = 0;
-+ restore_flags(flags);
-+ if (bytecount < 0)
-+ bytecount = 0;
-+ inf.bytes = bytecount;
-+ return copy_to_user((void *)arg, &inf, sizeof(inf));
-+ }
-+
-+ case SNDCTL_DSP_NONBLOCK:
-+ file->f_flags |= O_NONBLOCK;
-+ return 0;
-+
-+ case SNDCTL_DSP_RESET:
-+ if (file->f_mode & FMODE_WRITE)
-+ audio_clear_buf(os);
-+ if (file->f_mode & FMODE_READ)
-+ audio_clear_buf(is);
-+ return 0;
-+
-+ default:
-+ return state->client_ioctl(inode, file, cmd, arg);
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static int audio_mmap(struct file *file, struct vm_area_struct *vma)
-+{
-+ audio_state_t *state = file->private_data;
-+ audio_stream_t *s;
-+ unsigned long size, vma_addr;
-+ int i, ret;
-+
-+ if (vma->vm_pgoff != 0)
-+ return -EINVAL;
-+
-+ if (vma->vm_flags & VM_WRITE) {
-+ if (!state->wr_ref)
-+ return -EINVAL;;
-+ s = state->output_stream;
-+ } else if (vma->vm_flags & VM_READ) {
-+ if (!state->rd_ref)
-+ return -EINVAL;
-+ s = state->input_stream;
-+ } else return -EINVAL;
-+
-+ if (s->mapped)
-+ return -EINVAL;
-+ size = vma->vm_end - vma->vm_start;
-+ if (size != s->fragsize * s->nbfrags)
-+ return -EINVAL;
-+ if (!s->buffers && audio_setup_buf(s))
-+ return -ENOMEM;
-+ vma_addr = vma->vm_start;
-+ for (i = 0; i < s->nbfrags; i++) {
-+ audio_buf_t *buf = &s->buffers[i];
-+ if (!buf->master)
-+ continue;
-+ ret = remap_page_range(vma_addr, buf->dma_desc->dsadr,
-+ buf->master, vma->vm_page_prot);
-+ if (ret)
-+ return ret;
-+ vma_addr += buf->master;
-+ }
-+ for (i = 0; i < s->nbfrags; i++)
-+ s->buffers[i].dma_desc->ddadr &= ~DDADR_STOP;
-+ s->mapped = 1;
-+ return 0;
-+}
-+
-+
-+static int audio_release(struct inode *inode, struct file *file)
-+{
-+ audio_state_t *state = file->private_data;
-+
-+ down(&state->sem);
-+
-+ if (file->f_mode & FMODE_READ) {
-+ audio_clear_buf(state->input_stream);
-+ *state->input_stream->drcmr = 0;
-+ pxa_free_dma(state->input_stream->dma_ch);
-+ state->rd_ref = 0;
-+ }
-+
-+ if (file->f_mode & FMODE_WRITE) {
-+ audio_sync(file);
-+ audio_clear_buf(state->output_stream);
-+ *state->output_stream->drcmr = 0;
-+ pxa_free_dma(state->output_stream->dma_ch);
-+ state->wr_ref = 0;
-+ }
-+
-+ up(&state->sem);
-+ return 0;
-+}
-+
-+
-+int pxa_audio_attach(struct inode *inode, struct file *file,
-+ audio_state_t *state)
-+{
-+ audio_stream_t *is = state->input_stream;
-+ audio_stream_t *os = state->output_stream;
-+ int err;
-+
-+ down(&state->sem);
-+
-+ /* access control */
-+ err = -ENODEV;
-+ if ((file->f_mode & FMODE_WRITE) && !os)
-+ goto out;
-+ if ((file->f_mode & FMODE_READ) && !is)
-+ goto out;
-+ err = -EBUSY;
-+ if ((file->f_mode & FMODE_WRITE) && state->wr_ref)
-+ goto out;
-+ if ((file->f_mode & FMODE_READ) && state->rd_ref)
-+ goto out;
-+
-+ /* request DMA channels */
-+ if (file->f_mode & FMODE_WRITE) {
-+ err = pxa_request_dma(os->name, DMA_PRIO_LOW,
-+ audio_dma_irq, os);
-+ if (err < 0)
-+ goto out;
-+ os->dma_ch = err;
-+ }
-+ if (file->f_mode & FMODE_READ) {
-+ err = pxa_request_dma(is->name, DMA_PRIO_LOW,
-+ audio_dma_irq, is);
-+ if (err < 0) {
-+ if (file->f_mode & FMODE_WRITE) {
-+ *os->drcmr = 0;
-+ pxa_free_dma(os->dma_ch);
-+ }
-+ goto out;
-+ }
-+ is->dma_ch = err;
-+ }
-+
-+ file->private_data = state;
-+ file->f_op->release = audio_release;
-+ file->f_op->write = audio_write;
-+ file->f_op->read = audio_read;
-+ file->f_op->mmap = audio_mmap;
-+ file->f_op->poll = audio_poll;
-+ file->f_op->ioctl = audio_ioctl;
-+ file->f_op->llseek = no_llseek;
-+
-+ if ((file->f_mode & FMODE_WRITE)) {
-+ state->wr_ref = 1;
-+ os->fragsize = AUDIO_FRAGSIZE_DEFAULT;
-+ os->nbfrags = AUDIO_NBFRAGS_DEFAULT;
-+ os->output = 1;
-+ os->mapped = 0;
-+ init_waitqueue_head(&os->frag_wq);
-+ init_waitqueue_head(&os->stop_wq);
-+ *os->drcmr = os->dma_ch | DRCMR_MAPVLD;
-+ }
-+ if (file->f_mode & FMODE_READ) {
-+ state->rd_ref = 1;
-+ is->fragsize = AUDIO_FRAGSIZE_DEFAULT;
-+ is->nbfrags = AUDIO_NBFRAGS_DEFAULT;
-+ is->output = 0;
-+ is->mapped = 0;
-+ init_waitqueue_head(&is->frag_wq);
-+ init_waitqueue_head(&is->stop_wq);
-+ *is->drcmr = is->dma_ch | DRCMR_MAPVLD;
-+ }
-+
-+ err = 0;
-+
-+out:
-+ up(&state->sem);
-+ return err;
-+}
-+
-+EXPORT_SYMBOL(pxa_audio_attach);
-+EXPORT_SYMBOL(pxa_audio_clear_buf);
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/sound/pxa-audio.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,55 @@
-+/*
-+ * linux/drivers/sound/pxa-audio.h -- audio interface for the Cotula chip
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Aug 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+typedef struct {
-+ int offset; /* current buffer position */
-+ char *data; /* actual buffer */
-+ pxa_dma_desc *dma_desc; /* pointer to the starting desc */
-+ int master; /* owner for buffer allocation, contain size whn true */
-+} audio_buf_t;
-+
-+typedef struct {
-+ char *name; /* stream identifier */
-+ audio_buf_t *buffers; /* pointer to audio buffer array */
-+ u_int usr_frag; /* user fragment index */
-+ u_int dma_frag; /* DMA fragment index */
-+ u_int fragsize; /* fragment size */
-+ u_int nbfrags; /* number of fragments */
-+ u_int dma_ch; /* DMA channel number */
-+ dma_addr_t dma_desc_phys; /* phys addr of descriptor ring */
-+ u_int descs_per_frag; /* nbr descriptors per fragment */
-+ int bytecount; /* nbr of processed bytes */
-+ int fragcount; /* nbr of fragment transitions */
-+ struct semaphore sem; /* account for fragment usage */
-+ wait_queue_head_t frag_wq; /* for poll(), etc. */
-+ wait_queue_head_t stop_wq; /* for users of DCSR_STOPIRQEN */
-+ u_long dcmd; /* DMA descriptor dcmd field */
-+ volatile u32 *drcmr; /* the DMA request channel to use */
-+ u_long dev_addr; /* device physical address for DMA */
-+ int mapped:1; /* mmap()'ed buffers */
-+ int output:1; /* 0 for input, 1 for output */
-+} audio_stream_t;
-+
-+typedef struct {
-+ audio_stream_t *output_stream;
-+ audio_stream_t *input_stream;
-+ int dev_dsp; /* audio device handle */
-+ int rd_ref:1; /* open reference for recording */
-+ int wr_ref:1; /* open reference for playback */
-+ int (*client_ioctl)(struct inode *, struct file *, uint, ulong);
-+ struct semaphore sem; /* prevent races in attach/release */
-+} audio_state_t;
-+
-+extern int pxa_audio_attach(struct inode *inode, struct file *file,
-+ audio_state_t *state);
-+extern void pxa_audio_clear_buf(audio_stream_t *s);
-+
---- linux-2.4.25/drivers/sound/sa1100-audio.c~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/sound/sa1100-audio.c 2004-03-31 17:15:12.000000000 +0200
-@@ -148,7 +148,8 @@
- do {
- dmabuf = consistent_alloc(GFP_KERNEL|GFP_DMA,
- dmasize,
-- &dmaphys);
-+ &dmaphys,
-+ 0);
- if (!dmabuf)
- dmasize -= s->fragsize;
- } while (!dmabuf && dmasize);
---- linux-2.4.25/drivers/video/Config.in~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/video/Config.in 2004-03-31 17:15:12.000000000 +0200
-@@ -50,6 +50,15 @@
- if [ "$CONFIG_FB_SA1100" = "y" -a "$CONFIG_SA1100_CERF_CPLD" = "y" ]; then
- bool 'Cerfboard Backlight (CerfPDA)' CONFIG_SA1100_CERF_LCD_BACKLIGHT
- fi
-+ tristate ' PXA LCD support' CONFIG_FB_PXA $CONFIG_ARCH_PXA
-+ if [ "$CONFIG_FB_PXA" != "n" ]; then
-+ choice 'LCD Bit Depth' \
-+ "8-Bpp CONFIG_FB_PXA_8BPP \
-+ 16-Bpp CONFIG_FB_PXA_16BPP" Bit-Depth
-+ fi
-+ if [ "$CONFIG_FB_PXA" != "n" -a "$CONFIG_ARCH_LUBBOCK" = "y" ]; then
-+ bool ' Lubbock QVGA LCD support instead of DSTN' CONFIG_FB_PXA_QVGA
-+ fi
- fi
- dep_tristate ' CyberPro 2000/2010/5000 support' CONFIG_FB_CYBER2000 $CONFIG_PCI
- if [ "$CONFIG_APOLLO" = "y" ]; then
-@@ -295,7 +304,7 @@
- if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
- "$CONFIG_FB_SA1100" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
- "$CONFIG_FB_TX3912" = "y" -o "$CONFIG_FB_CLPS711X" = "y" -o \
-- "$CONFIG_FB_DBMX1" = "y" ]; then
-+ "$CONFIG_FB_DBMX1" = "y" -o "$CONFIG_FB_PXA" = "y" ]; then
- define_tristate CONFIG_FBCON_CFB2 y
- define_tristate CONFIG_FBCON_CFB4 y
- else
-@@ -329,7 +338,7 @@
- "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_NEOMAGIC" = "y" -o \
- "$CONFIG_FB_STI" = "y" -o "$CONFIG_FB_HP300" = "y" -o \
- "$CONFIG_FB_INTEL" = "y" -o \
-- "$CONFIG_FB_DBMX1" = "y" ]; then
-+ "$CONFIG_FB_DBMX1" = "y" -o "$CONFIG_FB_PXA" = "y" ]; then
- define_tristate CONFIG_FBCON_CFB8 y
- else
- if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
-@@ -372,7 +381,7 @@
- "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SA1100" = "y" -o \
- "$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_VOODOO1" = "y" -o \
- "$CONFIG_FB_NEOMAGIC" = "y" -o "$CONFIG_FB_INTEL" = "y" -o \
-- "$CONFIG_FB_ANAKIN" = "y" -o \
-+ "$CONFIG_FB_ANAKIN" = "y" -o "$CONFIG_FB_PXA" = "y" -o \
- "$CONFIG_FB_DBMX1" = "y" ]; then
- define_tristate CONFIG_FBCON_CFB16 y
- else
---- linux-2.4.25/drivers/video/Makefile~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/video/Makefile 2004-03-31 17:15:12.000000000 +0200
-@@ -14,7 +14,7 @@
- fbcon-vga.o fbcon-iplan2p2.o fbcon-iplan2p4.o \
- fbcon-iplan2p8.o fbcon-vga-planes.o fbcon-cfb16.o \
- fbcon-cfb2.o fbcon-cfb24.o fbcon-cfb32.o fbcon-cfb4.o \
-- fbcon-cfb8.o fbcon-mac.o fbcon-mfb.o \
-+ fbcon-cfb8.o fbcon-mac.o fbcon-mfb.o pxafb.o \
- cyber2000fb.o sa1100fb.o fbcon-hga.o fbgen.o
-
- # Each configuration option enables a list of files.
-@@ -129,6 +129,10 @@
- obj-$(CONFIG_FB_BWTWO) += bwtwofb.o
- obj-$(CONFIG_FB_HGA) += hgafb.o
- obj-$(CONFIG_FB_SA1100) += sa1100fb.o
-+obj-$(CONFIG_FB_PXA) += pxafb.o
-+ifeq ($(CONFIG_PXA_CERF_PDA),y)
-+ obj-$(CONFIG_FB_PXA) += lcdctrl.o lcdctrl_cerf.o
-+endif
- obj-$(CONFIG_FB_DBMX1) += dbmx1fb.o
- obj-$(CONFIG_FB_VIRTUAL) += vfb.o
- obj-$(CONFIG_FB_HIT) += hitfb.o fbgen.o
---- linux-2.4.25/drivers/video/fbmem.c~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/video/fbmem.c 2004-03-31 17:15:12.000000000 +0200
-@@ -109,6 +109,7 @@
- extern int chips_init(void);
- extern int g364fb_init(void);
- extern int sa1100fb_init(void);
-+extern int pxafb_init(void);
- extern int fm2fb_init(void);
- extern int fm2fb_setup(char*);
- extern int q40fb_init(void);
-@@ -305,6 +306,9 @@
- #ifdef CONFIG_FB_SA1100
- { "sa1100", sa1100fb_init, NULL },
- #endif
-+#ifdef CONFIG_FB_PXA
-+ { "pxa", pxafb_init, NULL },
-+#endif
- #ifdef CONFIG_FB_SUN3
- { "sun3", sun3fb_init, sun3fb_setup },
- #endif
-@@ -675,13 +679,13 @@
- #elif defined(__i386__) || defined(__x86_64__)
- if (boot_cpu_data.x86 > 3)
- pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
--#elif defined(__arm__) || defined(__mips__)
-+#elif defined(__mips__)
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- #elif defined(__sh__)
- pgprot_val(vma->vm_page_prot) &= ~_PAGE_CACHABLE;
- #elif defined(__hppa__)
- pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
--#elif defined(__ia64__)
-+#elif defined(__ia64__) || defined(__arm__)
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
- #elif defined(__hppa__)
- pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/video/lcdctrl.c 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,223 @@
-+/*
-+ * lcdctrl.c
-+ *
-+ * Generic LCD control for brightness, contrast, etc.
-+ * Device specific drivers implement a lcdctrl_device and
-+ * provides access to it via lcdctrl_device_get_ops().
-+ *
-+ * Copyright (C) 2002 Intrinsyc Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * History:
-+ * Mar 2002: Initial version [FB]
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/ctype.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+
-+#include <asm/system.h>
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+
-+#include <video/lcdctrl.h>
-+
-+/*
-+ * Set this to zero to remove all the debug statements via
-+ * dead code elimination.
-+ */
-+#define DEBUGGING 0
-+
-+#if DEBUGGING
-+static unsigned int lcd_debug = DEBUGGING;
-+#else
-+#define lcd_debug 0
-+#endif
-+
-+/* -- prototypes -- */
-+
-+static int lcdctrl_ioctl(struct inode * inode, struct file *filp,
-+ unsigned int cmd , unsigned long arg);
-+static int lcdctrl_open(struct inode *inode, struct file *filp);
-+static int lcdctrl_close(struct inode *inode, struct file *filp);
-+
-+/* -- variables -- */
-+
-+struct lcdctrl_device *lcd_device;
-+
-+static int intensity;
-+static int brightness;
-+static int contrast;
-+
-+static int enabled;
-+static int sync_needed;
-+static int chrdev_major;
-+
-+static struct file_operations lcdctrl_fops = {
-+ ioctl: lcdctrl_ioctl,
-+ open: lcdctrl_open,
-+ release: lcdctrl_close
-+};
-+
-+/* -- ioctl -- */
-+
-+static int lcdctrl_ioctl(struct inode * inode, struct file *filp,
-+ unsigned int cmd , unsigned long arg)
-+{
-+ int ret;
-+ ret = -EINVAL;
-+
-+ if( lcd_debug)
-+ printk(KERN_INFO "lcdctrl_ioctl: cmd=%d, arg=%ld\n", cmd, arg);
-+
-+ switch(cmd)
-+ {
-+ case _LCDCTRL_IOCTL_ON:
-+ ret = lcdctrl_enable();
-+ break;
-+ case _LCDCTRL_IOCTL_OFF:
-+ ret = lcdctrl_disable();
-+ break;
-+ case _LCDCTRL_IOCTL_INTENSITY:
-+ if ((arg >=0) && (arg <= 100))
-+ ret = lcdctrl_set_intensity(arg);
-+ break;
-+ case _LCDCTRL_IOCTL_BRIGHTNESS:
-+ if ((arg >=0) && (arg <= 100))
-+ ret = lcdctrl_set_brightness(arg);
-+ break;
-+ case _LCDCTRL_IOCTL_CONTRAST:
-+ if ((arg >=0) && (arg <= 100))
-+ ret = lcdctrl_set_contrast(arg, LCD_NO_SYNC);
-+ break;
-+ case _LCDCTRL_IOCTL_GET_BRIGHTNESS:
-+ ret = brightness;
-+ break;
-+ case _LCDCTRL_IOCTL_GET_CONTRAST:
-+ ret = contrast;
-+ break;
-+ case _LCDCTRL_IOCTL_GET_INTENSITY:
-+ ret = intensity;
-+ break;
-+
-+ default:
-+ printk(KERN_ERR "lcdctrl_ioctl: invalid ioctl\n");
-+ break;
-+ }
-+
-+ return ret;
-+}
-+
-+static int lcdctrl_open(struct inode *inode, struct file *filp)
-+{
-+// MOD_INC_USE_COUNT;
-+ return 0;
-+}
-+
-+static int lcdctrl_close(struct inode *inode, struct file *filp)
-+{
-+// MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+/* -- -- */
-+
-+int lcdctrl_enable( void)
-+{
-+ int result;
-+
-+ if( enabled) return 0;
-+
-+ result = lcd_device->enable();
-+
-+ lcdctrl_set_intensity( intensity);
-+ lcdctrl_set_brightness( brightness);
-+ lcdctrl_set_contrast( contrast, sync_needed);
-+ sync_needed = LCD_NO_SYNC;
-+
-+ enabled = 1;
-+ return result;
-+}
-+
-+int lcdctrl_disable( void)
-+{
-+ enabled = 0;
-+ return lcd_device->disable();
-+}
-+
-+int lcdctrl_set_intensity( int i)
-+{
-+ intensity = i;
-+ return lcd_device->set_intensity( i);
-+}
-+
-+int lcdctrl_set_brightness( int b)
-+{
-+ brightness = b;
-+ return lcd_device->set_brightness( b);
-+}
-+
-+int lcdctrl_set_contrast( int c, int sync)
-+{
-+ contrast = c;
-+ return lcd_device->set_contrast( c, sync);
-+}
-+
-+int lcdctrl_get_intensity( void)
-+{
-+ return intensity;
-+}
-+
-+int lcdctrl_get_brightness( void)
-+{
-+ return brightness;
-+}
-+
-+int lcdctrl_get_contrast( void)
-+{
-+ return contrast;
-+}
-+
-+/* -- -- */
-+
-+/* the device specific driver should implement this */
-+struct lcdctrl_device *lcdctrl_device_get_ops(void);
-+
-+int lcdctrl_init( void)
-+{
-+ int ret;
-+
-+ lcd_device = lcdctrl_device_get_ops();
-+
-+ if( !lcd_device)
-+ {
-+ printk(KERN_ERR "lcdctrl_init: No lcd_device registered.\n");
-+ return -EINVAL;
-+ }
-+
-+ ret = lcd_device->init( &intensity, &brightness, &contrast);
-+
-+ sync_needed = LCD_SYNC_NEEDED;
-+
-+ if( ret == 0)
-+ {
-+ chrdev_major =
-+ register_chrdev( 0,_LCD_CONTROL_NAME,&lcdctrl_fops);
-+ if( lcd_debug)
-+ printk(KERN_INFO "lcdctrl_init: OK\n");
-+ }
-+ return ret;
-+}
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/video/lcdctrl_cerf.c 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,175 @@
-+/*
-+ * lcdctrl_cerf.c
-+ *
-+ * Cerf LCD control for brightness and contrast.
-+ *
-+ * Copyright (C) 2002 Intrinsyc Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * History:
-+ * Mar 2002: Initial version [FB]
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/ctype.h>
-+#include <linux/mm.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+
-+#include <asm/system.h>
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+#include <asm/arch/cerf_ucb1400gpio.h>
-+
-+#include <video/lcdctrl.h>
-+
-+/*
-+ * Set this to zero to remove all the debug statements via
-+ * dead code elimination.
-+ */
-+#define DEBUGGING 0
-+
-+#if DEBUGGING
-+static unsigned int lcd_debug = DEBUGGING;
-+#else
-+#define lcd_debug 0
-+#endif
-+
-+#define LCD_MAX_INTENSITY 0
-+#define LCD_MAX_BRIGHTNESS 15
-+#define LCD_MAX_CONTRAST 100
-+
-+#define LCD_DEFAULT_INTENSITY 0
-+#define LCD_DEFAULT_BRIGHTNESS 14*100/(LCD_MAX_BRIGHTNESS)
-+#define LCD_DEFAULT_CONTRAST 90*100/(LCD_MAX_CONTRAST)
-+
-+#define UP 1
-+#define DOWN 0
-+
-+/* -- prototypes -- */
-+
-+static int cerf_lcdctrl_init( int *intensity, int *brightness, int *contrast);
-+static int cerf_lcdctrl_enable(void);
-+static int cerf_lcdctrl_disable(void);
-+static int cerf_lcdctrl_set_intensity( int i);
-+static int cerf_lcdctrl_set_brightness( int b);
-+static int cerf_lcdctrl_set_contrast( int c, int sync);
-+
-+static void cerf_lcdctrl_contrast_step( int direction);
-+
-+/* -- variables -- */
-+
-+static int dev_contrast;
-+
-+/* -- -- */
-+
-+static struct lcdctrl_device cerf_dev = {
-+ init: cerf_lcdctrl_init,
-+ enable: cerf_lcdctrl_enable,
-+ disable: cerf_lcdctrl_disable,
-+ set_intensity: cerf_lcdctrl_set_intensity,
-+ set_brightness: cerf_lcdctrl_set_brightness,
-+ set_contrast: cerf_lcdctrl_set_contrast
-+};
-+
-+static int cerf_lcdctrl_enable( void)
-+{
-+ cerf_ucb1400gpio_lcd_enable();
-+
-+ return 0;
-+}
-+
-+static int cerf_lcdctrl_disable( void)
-+{
-+ cerf_ucb1400gpio_lcd_disable();
-+
-+ return 0;
-+}
-+
-+static int cerf_lcdctrl_set_intensity( int i)
-+{
-+ int dev_intensity = LCD_MAX_INTENSITY*i/100;
-+ if( lcd_debug)
-+ printk(KERN_INFO "cerf_lcdctrl_set_intensity: "
-+ "dev_intensity = %d\n", dev_intensity);
-+ return 0;
-+}
-+
-+static int cerf_lcdctrl_set_brightness( int b)
-+{
-+ int dev_brightness = LCD_MAX_BRIGHTNESS*b/100;
-+ outw( dev_brightness, CERF_PDA_CPLD+CERF_PDA_CPLD_BRIGHTNESS);
-+ if( lcd_debug)
-+ printk(KERN_INFO "cerf_lcdctrl_set_brightness: "
-+ "dev_brightness = %d\n", dev_brightness);
-+ return 0;
-+}
-+
-+static int cerf_lcdctrl_set_contrast( int c, int sync)
-+{
-+ int new_dev_contrast = LCD_MAX_CONTRAST*c/100;
-+ int i;
-+ int count;
-+ int direction = UP;
-+ if( sync == LCD_SYNC_NEEDED)
-+ {
-+ /* In order to sync we step down to the lowest contrast level */
-+ for( i=0; i<LCD_MAX_CONTRAST; i++)
-+ cerf_lcdctrl_contrast_step(DOWN);
-+ dev_contrast = 0;
-+ }
-+
-+ count = new_dev_contrast - dev_contrast;
-+ if( count < 0)
-+ {
-+ /* new contrast is lower then current setting */
-+ direction = DOWN;
-+ count = -count;
-+ }
-+
-+ for( i=0; i<count; i++)
-+ cerf_lcdctrl_contrast_step(direction);
-+
-+ if( lcd_debug)
-+ printk(KERN_INFO "cerf_lcdctrl_set_contrast: "
-+ "dev_contrast = %d\n", new_dev_contrast);
-+ dev_contrast = new_dev_contrast;
-+
-+ return 0;
-+}
-+
-+/* -- -- */
-+
-+static void cerf_lcdctrl_contrast_step( int direction)
-+{
-+ cerf_ucb1400gpio_lcd_contrast_step( direction);
-+}
-+
-+/* -- -- */
-+
-+static int cerf_lcdctrl_init( int *intensity, int *brightness, int *contrast)
-+{
-+ *intensity = LCD_DEFAULT_INTENSITY;
-+ *brightness = LCD_DEFAULT_BRIGHTNESS;
-+ *contrast = LCD_DEFAULT_CONTRAST;
-+
-+ if( lcd_debug)
-+ printk(KERN_INFO "cerf_lcdctrl_init: OK\n");
-+ return 0;
-+}
-+
-+/* this is the hook for lcdctrl to access to the device specifics */
-+struct lcdctrl_device *lcdctrl_device_get_ops(void)
-+{
-+ return &cerf_dev;
-+}
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/video/pxafb.c 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,1410 @@
-+/*
-+ * linux/drivers/video/pxafb.c
-+ *
-+ * Copyright (C) 1999 Eric A. Thomas
-+ * Based on acornfb.c Copyright (C) Russell King.
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file COPYING in the main directory of this archive for
-+ * more details.
-+ *
-+ * Intel PXA250/210 LCD Controller Frame Buffer Driver
-+ *
-+ * Please direct your questions and comments on this driver to the following
-+ * email address:
-+ *
-+ * linux-arm-kernel@lists.arm.linux.org.uk
-+ *
-+ *
-+ * Code Status:
-+ *
-+ * 2001/08/03: <cbrake@accelent.com>
-+ * - Ported from SA1100 to PXA250
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/interrupt.h>
-+#include <linux/slab.h>
-+#include <linux/fb.h>
-+#include <linux/delay.h>
-+#include <linux/pm.h>
-+#include <linux/init.h>
-+#include <linux/notifier.h>
-+#include <linux/cpufreq.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/mach-types.h>
-+#include <asm/uaccess.h>
-+
-+#include <video/fbcon.h>
-+#include <video/fbcon-mfb.h>
-+#include <video/fbcon-cfb4.h>
-+#include <video/fbcon-cfb8.h>
-+#include <video/fbcon-cfb16.h>
-+#include <video/lcdctrl.h> /* brightness, contrast, etc. control */
-+
-+/*
-+ * debugging?
-+ */
-+#define DEBUG 0
-+/*
-+ * Complain if VAR is out of range.
-+ */
-+#define DEBUG_VAR 1
-+
-+#undef ASSABET_PAL_VIDEO
-+
-+#include "pxafb.h"
-+
-+void (*pxafb_blank_helper)(int blank);
-+EXPORT_SYMBOL(pxafb_blank_helper);
-+
-+/*
-+ * IMHO this looks wrong. In 8BPP, length should be 8.
-+ */
-+static struct pxafb_rgb rgb_8 = {
-+ red: { offset: 0, length: 4, },
-+ green: { offset: 0, length: 4, },
-+ blue: { offset: 0, length: 4, },
-+ transp: { offset: 0, length: 0, },
-+};
-+
-+static struct pxafb_rgb def_rgb_16 = {
-+ red: { offset: 11, length: 5, },
-+ green: { offset: 5, length: 6, },
-+ blue: { offset: 0, length: 5, },
-+ transp: { offset: 0, length: 0, },
-+};
-+
-+static struct pxafb_mach_info pxa_fb_info __initdata = {
-+ pixclock: LCD_PIXCLOCK, /* clock period in ps */
-+ bpp: LCD_BPP,
-+ xres: LCD_XRES,
-+ yres: LCD_YRES,
-+ hsync_len: LCD_HORIZONTAL_SYNC_PULSE_WIDTH,
-+ vsync_len: LCD_VERTICAL_SYNC_PULSE_WIDTH,
-+ left_margin: LCD_BEGIN_OF_LINE_WAIT_COUNT,
-+ upper_margin: LCD_BEGIN_FRAME_WAIT_COUNT,
-+ right_margin: LCD_END_OF_LINE_WAIT_COUNT,
-+ lower_margin: LCD_END_OF_FRAME_WAIT_COUNT,
-+ sync: LCD_SYNC,
-+ lccr0: LCD_LCCR0,
-+ lccr3: LCD_LCCR3
-+};
-+
-+static struct pxafb_mach_info * __init
-+pxafb_get_machine_info(struct pxafb_info *fbi)
-+{
-+ return &pxa_fb_info;
-+}
-+
-+static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *);
-+static void set_ctrlr_state(struct pxafb_info *fbi, u_int state);
-+
-+static inline void pxafb_schedule_task(struct pxafb_info *fbi, u_int state)
-+{
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+ /*
-+ * We need to handle two requests being made at the same time.
-+ * There are two important cases:
-+ * 1. When we are changing VT (C_REENABLE) while unblanking (C_ENABLE)
-+ * We must perform the unblanking, which will do our REENABLE for us.
-+ * 2. When we are blanking, but immediately unblank before we have
-+ * blanked. We do the "REENABLE" thing here as well, just to be sure.
-+ */
-+ if (fbi->task_state == C_ENABLE && state == C_REENABLE)
-+ state = (u_int) -1;
-+ if (fbi->task_state == C_DISABLE && state == C_ENABLE)
-+ state = C_REENABLE;
-+
-+ if (state != (u_int)-1) {
-+ fbi->task_state = state;
-+ schedule_task(&fbi->task);
-+ }
-+ local_irq_restore(flags);
-+}
-+
-+/*
-+ * Get the VAR structure pointer for the specified console
-+ */
-+static inline struct fb_var_screeninfo *get_con_var(struct fb_info *info, int con)
-+{
-+ struct pxafb_info *fbi = (struct pxafb_info *)info;
-+ return (con == fbi->currcon || con == -1) ? &fbi->fb.var : &fb_display[con].var;
-+}
-+
-+/*
-+ * Get the DISPLAY structure pointer for the specified console
-+ */
-+static inline struct display *get_con_display(struct fb_info *info, int con)
-+{
-+ struct pxafb_info *fbi = (struct pxafb_info *)info;
-+ return (con < 0) ? fbi->fb.disp : &fb_display[con];
-+}
-+
-+/*
-+ * Get the CMAP pointer for the specified console
-+ */
-+static inline struct fb_cmap *get_con_cmap(struct fb_info *info, int con)
-+{
-+ struct pxafb_info *fbi = (struct pxafb_info *)info;
-+ return (con == fbi->currcon || con == -1) ? &fbi->fb.cmap : &fb_display[con].cmap;
-+}
-+
-+static inline u_int
-+chan_to_field(u_int chan, struct fb_bitfield *bf)
-+{
-+ chan &= 0xffff;
-+ chan >>= 16 - bf->length;
-+ return chan << bf->offset;
-+}
-+
-+static int
-+pxafb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
-+ u_int trans, struct fb_info *info)
-+{
-+ struct pxafb_info *fbi = (struct pxafb_info *)info;
-+ u_int val, ret = 1;
-+
-+ if (regno < fbi->palette_size) {
-+ val = ((red >> 0) & 0xf800);
-+ val |= ((green >> 5) & 0x07e0);
-+ val |= ((blue >> 11) & 0x001f);
-+
-+ fbi->palette_cpu[regno] = val;
-+ ret = 0;
-+ }
-+ return ret;
-+}
-+
-+static int
-+pxafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-+ u_int trans, struct fb_info *info)
-+{
-+ struct pxafb_info *fbi = (struct pxafb_info *)info;
-+ u_int val;
-+ int ret = 1;
-+
-+ /*
-+ * If greyscale is true, then we convert the RGB value
-+ * to greyscale no mater what visual we are using.
-+ */
-+ if (fbi->fb.var.grayscale)
-+ red = green = blue = (19595 * red + 38470 * green +
-+ 7471 * blue) >> 16;
-+
-+ switch (fbi->fb.disp->visual) {
-+ case FB_VISUAL_TRUECOLOR:
-+ case FB_VISUAL_DIRECTCOLOR:
-+ /*
-+ * 12 or 16-bit True Colour. We encode the RGB value
-+ * according to the RGB bitfield information.
-+ */
-+ if (regno <= 16) {
-+ u16 *pal = fbi->fb.pseudo_palette;
-+
-+ val = chan_to_field(red, &fbi->fb.var.red);
-+ val |= chan_to_field(green, &fbi->fb.var.green);
-+ val |= chan_to_field(blue, &fbi->fb.var.blue);
-+
-+ pal[regno] = val;
-+ ret = 0;
-+ }
-+ break;
-+
-+ case FB_VISUAL_PSEUDOCOLOR:
-+ ret = pxafb_setpalettereg(regno, red, green, blue, trans, info);
-+ break;
-+ }
-+
-+ return ret;
-+}
-+
-+/*
-+ * pxafb_decode_var():
-+ * Get the video params out of 'var'. If a value doesn't fit, round it up,
-+ * if it's too big, return -EINVAL.
-+ *
-+ * Suggestion: Round up in the following order: bits_per_pixel, xres,
-+ * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
-+ * bitfields, horizontal timing, vertical timing.
-+ */
-+static int pxafb_validate_var(struct fb_var_screeninfo *var,
-+ struct pxafb_info *fbi)
-+{
-+ int ret = -EINVAL;
-+
-+ if (var->xres < MIN_XRES)
-+ var->xres = MIN_XRES;
-+ if (var->yres < MIN_YRES)
-+ var->yres = MIN_YRES;
-+ if (var->xres > fbi->max_xres)
-+ var->xres = fbi->max_xres;
-+ if (var->yres > fbi->max_yres)
-+ var->yres = fbi->max_yres;
-+ var->xres_virtual =
-+ var->xres_virtual < var->xres ? var->xres : var->xres_virtual;
-+ var->yres_virtual =
-+ var->yres_virtual < var->yres ? var->yres : var->yres_virtual;
-+
-+ DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel);
-+ switch (var->bits_per_pixel) {
-+#ifdef FBCON_HAS_CFB4
-+ case 4: ret = 0; break;
-+#endif
-+#ifdef FBCON_HAS_CFB8
-+ case 8: ret = 0; break;
-+#endif
-+#ifdef FBCON_HAS_CFB16
-+ case 12:
-+ /* make sure we are in passive mode */
-+ if (!(fbi->lccr0 & LCCR0_PAS))
-+ ret = 0;
-+ break;
-+
-+ case 16:
-+ /*
-+ * 16 bits works apparemtly fine in passive mode for those,
-+ * so don't complain
-+ */
-+ if (machine_is_lubbock() ||
-+ machine_is_pxa_cerf()) {
-+ ret = 0;
-+ } else
-+ /* make sure we are in active mode */
-+ if ((fbi->lccr0 & LCCR0_PAS))
-+ ret = 0;
-+ break;
-+#endif
-+ default:
-+ break;
-+ }
-+
-+ return ret;
-+}
-+
-+static inline void pxafb_set_truecolor(u_int is_true_color)
-+{
-+ DPRINTK("true_color = %d\n", is_true_color);
-+}
-+
-+static void
-+pxafb_hw_set_var(struct fb_var_screeninfo *var, struct pxafb_info *fbi)
-+{
-+
-+ fb_set_cmap(&fbi->fb.cmap, 1, pxafb_setcolreg, &fbi->fb);
-+
-+ /* Set board control register to handle new color depth */
-+ pxafb_set_truecolor(var->bits_per_pixel >= 16);
-+
-+ pxafb_activate_var(var, fbi);
-+
-+}
-+
-+/*
-+ * pxafb_set_var():
-+ * Set the user defined part of the display for the specified console
-+ */
-+static int
-+pxafb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-+{
-+ struct pxafb_info *fbi = (struct pxafb_info *)info;
-+ struct fb_var_screeninfo *dvar = get_con_var(&fbi->fb, con);
-+ struct display *display = get_con_display(&fbi->fb, con);
-+ int err, chgvar = 0, rgbidx;
-+
-+ DPRINTK("set_var\n");
-+
-+ /*
-+ * Decode var contents into a par structure, adjusting any
-+ * out of range values.
-+ */
-+ err = pxafb_validate_var(var, fbi);
-+ if (err)
-+ return err;
-+
-+ if (var->activate & FB_ACTIVATE_TEST)
-+ return 0;
-+
-+ if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
-+ return -EINVAL;
-+
-+ if (dvar->xres != var->xres)
-+ chgvar = 1;
-+ if (dvar->yres != var->yres)
-+ chgvar = 1;
-+ if (dvar->xres_virtual != var->xres_virtual)
-+ chgvar = 1;
-+ if (dvar->yres_virtual != var->yres_virtual)
-+ chgvar = 1;
-+ if (dvar->bits_per_pixel != var->bits_per_pixel)
-+ chgvar = 1;
-+ if (con < 0)
-+ chgvar = 0;
-+
-+ switch (var->bits_per_pixel) {
-+#ifdef FBCON_HAS_CFB4
-+ case 4:
-+ if (fbi->cmap_static)
-+ display->visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
-+ else
-+ display->visual = FB_VISUAL_PSEUDOCOLOR;
-+ display->line_length = var->xres / 2;
-+ display->dispsw = &fbcon_cfb4;
-+ rgbidx = RGB_8;
-+ break;
-+#endif
-+#ifdef FBCON_HAS_CFB8
-+ case 8:
-+ if (fbi->cmap_static)
-+ display->visual = FB_VISUAL_STATIC_PSEUDOCOLOR;
-+ else
-+ display->visual = FB_VISUAL_PSEUDOCOLOR;
-+ display->line_length = var->xres;
-+ display->dispsw = &fbcon_cfb8;
-+ rgbidx = RGB_8;
-+ break;
-+#endif
-+#ifdef FBCON_HAS_CFB16
-+ case 12:
-+ case 16:
-+ display->visual = FB_VISUAL_TRUECOLOR;
-+ display->line_length = var->xres * 2;
-+ display->dispsw = &fbcon_cfb16;
-+ display->dispsw_data = fbi->fb.pseudo_palette;
-+ rgbidx = RGB_16;
-+ break;
-+#endif
-+ default:
-+ rgbidx = 0;
-+ display->dispsw = &fbcon_dummy;
-+ break;
-+ }
-+
-+ display->screen_base = fbi->screen_cpu;
-+ display->next_line = display->line_length;
-+ display->type = fbi->fb.fix.type;
-+ display->type_aux = fbi->fb.fix.type_aux;
-+ display->ypanstep = fbi->fb.fix.ypanstep;
-+ display->ywrapstep = fbi->fb.fix.ywrapstep;
-+ display->can_soft_blank = 1;
-+ display->inverse = 0;
-+
-+ *dvar = *var;
-+ dvar->activate &= ~FB_ACTIVATE_ALL;
-+
-+ /*
-+ * Copy the RGB parameters for this display
-+ * from the machine specific parameters.
-+ */
-+ dvar->red = fbi->rgb[rgbidx]->red;
-+ dvar->green = fbi->rgb[rgbidx]->green;
-+ dvar->blue = fbi->rgb[rgbidx]->blue;
-+ dvar->transp = fbi->rgb[rgbidx]->transp;
-+
-+ DPRINTK("RGBT length = %d:%d:%d:%d\n",
-+ dvar->red.length, dvar->green.length, dvar->blue.length,
-+ dvar->transp.length);
-+
-+ DPRINTK("RGBT offset = %d:%d:%d:%d\n",
-+ dvar->red.offset, dvar->green.offset, dvar->blue.offset,
-+ dvar->transp.offset);
-+
-+ /*
-+ * Update the old var. The fbcon drivers still use this.
-+ * Once they are using fbi->fb.var, this can be dropped.
-+ */
-+ display->var = *dvar;
-+
-+ /*
-+ * If we are setting all the virtual consoles, also set the
-+ * defaults used to create new consoles.
-+ */
-+ if (var->activate & FB_ACTIVATE_ALL)
-+ fbi->fb.disp->var = *dvar;
-+
-+ /*
-+ * If the console has changed and the console has defined
-+ * a changevar function, call that function.
-+ */
-+ if (chgvar && info && fbi->fb.changevar)
-+ fbi->fb.changevar(con);
-+
-+ /* If the current console is selected, activate the new var. */
-+ if (con != fbi->currcon)
-+ return 0;
-+
-+ pxafb_hw_set_var(dvar, fbi);
-+
-+ return 0;
-+}
-+
-+static int
-+__do_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-+ struct fb_info *info)
-+{
-+ struct pxafb_info *fbi = (struct pxafb_info *)info;
-+ struct fb_cmap *dcmap = get_con_cmap(info, con);
-+ int err = 0;
-+
-+ if (con == -1)
-+ con = fbi->currcon;
-+
-+ /* no colormap allocated? (we always have "this" colour map allocated) */
-+ if (con >= 0)
-+ err = fb_alloc_cmap(&fb_display[con].cmap, fbi->palette_size, 0);
-+
-+ if (!err && con == fbi->currcon)
-+ err = fb_set_cmap(cmap, kspc, pxafb_setcolreg, info);
-+
-+ if (!err)
-+ fb_copy_cmap(cmap, dcmap, kspc ? 0 : 1);
-+
-+ return err;
-+}
-+
-+static int
-+pxafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-+ struct fb_info *info)
-+{
-+ struct display *disp = get_con_display(info, con);
-+
-+ if (disp->visual == FB_VISUAL_TRUECOLOR)
-+ return -EINVAL;
-+
-+ return __do_set_cmap(cmap, kspc, con, info);
-+}
-+
-+static int
-+pxafb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
-+{
-+ struct display *display = get_con_display(info, con);
-+
-+ *fix = info->fix;
-+
-+ fix->line_length = display->line_length;
-+ fix->visual = display->visual;
-+ return 0;
-+}
-+
-+static int
-+pxafb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-+{
-+ *var = *get_con_var(info, con);
-+ return 0;
-+}
-+
-+static int
-+pxafb_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
-+{
-+ struct fb_cmap *dcmap = get_con_cmap(info, con);
-+ fb_copy_cmap(dcmap, cmap, kspc ? 0 : 2);
-+ return 0;
-+}
-+
-+static struct fb_ops pxafb_ops = {
-+ owner: THIS_MODULE,
-+ fb_get_fix: pxafb_get_fix,
-+ fb_get_var: pxafb_get_var,
-+ fb_set_var: pxafb_set_var,
-+ fb_get_cmap: pxafb_get_cmap,
-+ fb_set_cmap: pxafb_set_cmap,
-+};
-+
-+/*
-+ * pxafb_switch():
-+ * Change to the specified console. Palette and video mode
-+ * are changed to the console's stored parameters.
-+ *
-+ * Uh oh, this can be called from a tasklet (IRQ)
-+ */
-+static int pxafb_switch(int con, struct fb_info *info)
-+{
-+ struct pxafb_info *fbi = (struct pxafb_info *)info;
-+ struct display *disp;
-+ struct fb_cmap *cmap;
-+
-+ DPRINTK("con=%d info->modename=%s\n", con, fbi->fb.modename);
-+
-+ if (con == fbi->currcon)
-+ return 0;
-+
-+ if (fbi->currcon >= 0) {
-+ disp = fb_display + fbi->currcon;
-+
-+ /*
-+ * Save the old colormap and video mode.
-+ */
-+ disp->var = fbi->fb.var;
-+
-+ if (disp->cmap.len)
-+ fb_copy_cmap(&fbi->fb.cmap, &disp->cmap, 0);
-+ }
-+
-+ fbi->currcon = con;
-+ disp = fb_display + con;
-+
-+ /*
-+ * Make sure that our colourmap contains 256 entries.
-+ */
-+ fb_alloc_cmap(&fbi->fb.cmap, 256, 0);
-+
-+ if (disp->cmap.len)
-+ cmap = &disp->cmap;
-+ else
-+ cmap = fb_default_cmap(1 << disp->var.bits_per_pixel);
-+
-+ fb_copy_cmap(cmap, &fbi->fb.cmap, 0);
-+
-+ fbi->fb.var = disp->var;
-+ fbi->fb.var.activate = FB_ACTIVATE_NOW;
-+
-+ pxafb_set_var(&fbi->fb.var, con, info);
-+ return 0;
-+}
-+
-+/*
-+ * Formal definition of the VESA spec:
-+ * On
-+ * This refers to the state of the display when it is in full operation
-+ * Stand-By
-+ * This defines an optional operating state of minimal power reduction with
-+ * the shortest recovery time
-+ * Suspend
-+ * This refers to a level of power management in which substantial power
-+ * reduction is achieved by the display. The display can have a longer
-+ * recovery time from this state than from the Stand-by state
-+ * Off
-+ * This indicates that the display is consuming the lowest level of power
-+ * and is non-operational. Recovery from this state may optionally require
-+ * the user to manually power on the monitor
-+ *
-+ * Now, the fbdev driver adds an additional state, (blank), where they
-+ * turn off the video (maybe by colormap tricks), but don't mess with the
-+ * video itself: think of it semantically between on and Stand-By.
-+ *
-+ * So here's what we should do in our fbdev blank routine:
-+ *
-+ * VESA_NO_BLANKING (mode 0) Video on, front/back light on
-+ * VESA_VSYNC_SUSPEND (mode 1) Video on, front/back light off
-+ * VESA_HSYNC_SUSPEND (mode 2) Video on, front/back light off
-+ * VESA_POWERDOWN (mode 3) Video off, front/back light off
-+ *
-+ * This will match the matrox implementation.
-+ */
-+/*
-+ * pxafb_blank():
-+ * Blank the display by setting all palette values to zero. Note, the
-+ * 12 and 16 bpp modes don't really use the palette, so this will not
-+ * blank the display in all modes.
-+ */
-+static void pxafb_blank(int blank, struct fb_info *info)
-+{
-+ struct pxafb_info *fbi = (struct pxafb_info *)info;
-+ int i;
-+
-+ DPRINTK("pxafb_blank: blank=%d info->modename=%s\n", blank,
-+ fbi->fb.modename);
-+
-+ switch (blank) {
-+ case VESA_POWERDOWN:
-+ case VESA_VSYNC_SUSPEND:
-+ case VESA_HSYNC_SUSPEND:
-+ if (fbi->fb.disp->visual == FB_VISUAL_PSEUDOCOLOR ||
-+ fbi->fb.disp->visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
-+ for (i = 0; i < fbi->palette_size; i++)
-+ pxafb_setpalettereg(i, 0, 0, 0, 0, info);
-+ pxafb_schedule_task(fbi, C_DISABLE);
-+ if (pxafb_blank_helper)
-+ pxafb_blank_helper(blank);
-+ break;
-+
-+ case VESA_NO_BLANKING:
-+ if (pxafb_blank_helper)
-+ pxafb_blank_helper(blank);
-+ if (fbi->fb.disp->visual == FB_VISUAL_PSEUDOCOLOR ||
-+ fbi->fb.disp->visual == FB_VISUAL_STATIC_PSEUDOCOLOR)
-+ fb_set_cmap(&fbi->fb.cmap, 1, pxafb_setcolreg, info);
-+ pxafb_schedule_task(fbi, C_ENABLE);
-+ }
-+}
-+
-+static int pxafb_updatevar(int con, struct fb_info *info)
-+{
-+ DPRINTK("entered\n");
-+ return 0;
-+}
-+
-+/*
-+ * Calculate the PCD value from the clock rate (in picoseconds).
-+ * We take account of the PPCR clock setting.
-+ */
-+static inline int get_pcd(unsigned int pixclock)
-+{
-+ unsigned int pcd;
-+
-+ if (pixclock) {
-+ pcd = get_lclk_frequency_10khz() * pixclock;
-+ pcd /= 100000000;
-+ pcd += 1; /* make up for integer math truncations */
-+ } else {
-+ printk(KERN_WARNING "Please convert me to use the PCD calculations\n");
-+ pcd = 0;
-+ }
-+ return pcd;
-+}
-+
-+/*
-+ * pxafb_activate_var():
-+ * Configures LCD Controller based on entries in var parameter. Settings are
-+ * only written to the controller if changes were made.
-+ */
-+static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *fbi)
-+{
-+ struct pxafb_lcd_reg new_regs;
-+// u_int pcd = get_pcd(var->pixclock);
-+ u_long flags;
-+
-+ DPRINTK("Configuring PXA LCD\n");
-+
-+ DPRINTK("var: xres=%d hslen=%d lm=%d rm=%d\n",
-+ var->xres, var->hsync_len,
-+ var->left_margin, var->right_margin);
-+ DPRINTK("var: yres=%d vslen=%d um=%d bm=%d\n",
-+ var->yres, var->vsync_len,
-+ var->upper_margin, var->lower_margin);
-+
-+#if DEBUG_VAR
-+ if (var->xres < 16 || var->xres > 1024)
-+ printk(KERN_ERR "%s: invalid xres %d\n",
-+ fbi->fb.fix.id, var->xres);
-+ if (var->hsync_len < 1 || var->hsync_len > 64)
-+ printk(KERN_ERR "%s: invalid hsync_len %d\n",
-+ fbi->fb.fix.id, var->hsync_len);
-+ if (var->left_margin < 1 || var->left_margin > 255)
-+ printk(KERN_ERR "%s: invalid left_margin %d\n",
-+ fbi->fb.fix.id, var->left_margin);
-+ if (var->right_margin < 1 || var->right_margin > 255)
-+ printk(KERN_ERR "%s: invalid right_margin %d\n",
-+ fbi->fb.fix.id, var->right_margin);
-+ if (var->yres < 1 || var->yres > 1024)
-+ printk(KERN_ERR "%s: invalid yres %d\n",
-+ fbi->fb.fix.id, var->yres);
-+ if (var->vsync_len < 1 || var->vsync_len > 64)
-+ printk(KERN_ERR "%s: invalid vsync_len %d\n",
-+ fbi->fb.fix.id, var->vsync_len);
-+ if (var->upper_margin < 0 || var->upper_margin > 255)
-+ printk(KERN_ERR "%s: invalid upper_margin %d\n",
-+ fbi->fb.fix.id, var->upper_margin);
-+ if (var->lower_margin < 0 || var->lower_margin > 255)
-+ printk(KERN_ERR "%s: invalid lower_margin %d\n",
-+ fbi->fb.fix.id, var->lower_margin);
-+#endif
-+
-+#if defined (CONFIG_PXA_CERF_PDA)
-+ new_regs.lccr0 = fbi->lccr0;
-+ new_regs.lccr1 =
-+ LCCR1_DisWdth(var->xres) +
-+ LCCR1_HorSnchWdth(var->hsync_len) +
-+ LCCR1_BegLnDel(var->left_margin) +
-+ LCCR1_EndLnDel(var->right_margin);
-+
-+ new_regs.lccr2 =
-+ LCCR2_DisHght(var->yres) +
-+ LCCR2_VrtSnchWdth(var->vsync_len) +
-+ LCCR2_BegFrmDel(var->upper_margin) +
-+ LCCR2_EndFrmDel(var->lower_margin);
-+
-+ new_regs.lccr3 = fbi->lccr3
-+ |
-+ (var->sync & FB_SYNC_HOR_HIGH_ACT ? LCCR3_HorSnchH : LCCR3_HorSnchL) |
-+ (var->sync & FB_SYNC_VERT_HIGH_ACT ? LCCR3_VrtSnchH : LCCR3_VrtSnchL);
-+#elif defined (CONFIG_FB_PXA_QVGA)
-+ new_regs.lccr0 = fbi->lccr0;
-+ new_regs.lccr1 =
-+ LCCR1_DisWdth(var->xres) +
-+ LCCR1_HorSnchWdth(var->hsync_len) +
-+ LCCR1_BegLnDel(var->left_margin) +
-+ LCCR1_EndLnDel(var->right_margin);
-+ new_regs.lccr2 =
-+ LCCR2_DisHght(var->yres) +
-+ LCCR2_VrtSnchWdth(var->vsync_len) +
-+ LCCR2_BegFrmDel(var->upper_margin) +
-+ LCCR2_EndFrmDel(var->lower_margin);
-+ new_regs.lccr3 = fbi->lccr3;
-+#else
-+ // FIXME using hardcoded values for now
-+ new_regs.lccr0 = fbi->lccr0;
-+// |
-+// LCCR0_LEN | LCCR0_LDM | LCCR0_BAM |
-+// LCCR0_ERM | LCCR0_LtlEnd | LCCR0_DMADel(0);
-+
-+ new_regs.lccr1 = 0x3030A7F;
-+// LCCR1_DisWdth(var->xres) +
-+// LCCR1_HorSnchWdth(var->hsync_len) +
-+// LCCR1_BegLnDel(var->left_margin) +
-+// LCCR1_EndLnDel(var->right_margin);
-+
-+ new_regs.lccr2 = 0x4EF;
-+// LCCR2_DisHght(var->yres) +
-+// LCCR2_VrtSnchWdth(var->vsync_len) +
-+// LCCR2_BegFrmDel(var->upper_margin) +
-+// LCCR2_EndFrmDel(var->lower_margin);
-+
-+ new_regs.lccr3 = fbi->lccr3;
-+// |
-+// (var->sync & FB_SYNC_HOR_HIGH_ACT ? LCCR3_HorSnchH : LCCR3_HorSnchL) |
-+// (var->sync & FB_SYNC_VERT_HIGH_ACT ? LCCR3_VrtSnchH : LCCR3_VrtSnchL) |
-+// LCCR3_ACBsCntOff;
-+#endif
-+
-+// if (pcd)
-+// new_regs.lccr3 |= LCCR3_PixClkDiv(pcd);
-+
-+ DPRINTK("nlccr0 = 0x%08x\n", new_regs.lccr0);
-+ DPRINTK("nlccr1 = 0x%08x\n", new_regs.lccr1);
-+ DPRINTK("nlccr2 = 0x%08x\n", new_regs.lccr2);
-+ DPRINTK("nlccr3 = 0x%08x\n", new_regs.lccr3);
-+
-+ /* Update shadow copy atomically */
-+ local_irq_save(flags);
-+
-+ /* setup dma descriptors */
-+ fbi->dmadesc_fblow_cpu = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette_cpu - 3*16);
-+ fbi->dmadesc_fbhigh_cpu = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette_cpu - 2*16);
-+ fbi->dmadesc_palette_cpu = (struct pxafb_dma_descriptor *)((unsigned int)fbi->palette_cpu - 1*16);
-+
-+ fbi->dmadesc_fblow_dma = fbi->palette_dma - 3*16;
-+ fbi->dmadesc_fbhigh_dma = fbi->palette_dma - 2*16;
-+ fbi->dmadesc_palette_dma = fbi->palette_dma - 1*16;
-+
-+ #define BYTES_PER_PANEL ((fbi->lccr0 & LCCR0_SDS) ? (var->xres * var->yres * var->bits_per_pixel / 8 / 2) : \
-+ (var->xres * var->yres * var->bits_per_pixel / 8))
-+
-+ /* populate descriptors */
-+ fbi->dmadesc_fblow_cpu->fdadr = fbi->dmadesc_fblow_dma;
-+ fbi->dmadesc_fblow_cpu->fsadr = fbi->screen_dma + BYTES_PER_PANEL;
-+ fbi->dmadesc_fblow_cpu->fidr = 0;
-+ fbi->dmadesc_fblow_cpu->ldcmd = BYTES_PER_PANEL;
-+
-+ fbi->fdadr1 = fbi->dmadesc_fblow_dma; /* only used in dual-panel mode */
-+
-+ fbi->dmadesc_fbhigh_cpu->fsadr = fbi->screen_dma;
-+ fbi->dmadesc_fbhigh_cpu->fidr = 0;
-+ fbi->dmadesc_fbhigh_cpu->ldcmd = BYTES_PER_PANEL;
-+
-+ fbi->dmadesc_palette_cpu->fsadr = fbi->palette_dma;
-+ fbi->dmadesc_palette_cpu->fidr = 0;
-+ fbi->dmadesc_palette_cpu->ldcmd = (fbi->palette_size * 2) | LDCMD_PAL;
-+
-+ if( var->bits_per_pixel < 12)
-+ {
-+ /* assume any mode with <12 bpp is palette driven */
-+ fbi->dmadesc_palette_cpu->fdadr = fbi->dmadesc_fbhigh_dma;
-+ fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_palette_dma;
-+ fbi->fdadr0 = fbi->dmadesc_palette_dma; /* flips back and forth between pal and fbhigh */
-+ }
-+ else
-+ {
-+ /* palette shouldn't be loaded in true-color mode */
-+ fbi->dmadesc_fbhigh_cpu->fdadr = fbi->dmadesc_fbhigh_dma;
-+ fbi->fdadr0 = fbi->dmadesc_fbhigh_dma; /* no pal just fbhigh */
-+ }
-+
-+ DPRINTK("fbi->dmadesc_fblow_cpu = 0x%x\n", fbi->dmadesc_fblow_cpu);
-+ DPRINTK("fbi->dmadesc_fbhigh_cpu = 0x%x\n", fbi->dmadesc_fbhigh_cpu);
-+ DPRINTK("fbi->dmadesc_palette_cpu = 0x%x\n", fbi->dmadesc_palette_cpu);
-+ DPRINTK("fbi->dmadesc_fblow_dma = 0x%x\n", fbi->dmadesc_fblow_dma);
-+ DPRINTK("fbi->dmadesc_fbhigh_dma = 0x%x\n", fbi->dmadesc_fbhigh_dma);
-+ DPRINTK("fbi->dmadesc_palette_dma = 0x%x\n", fbi->dmadesc_palette_dma);
-+
-+ DPRINTK("fbi->dmadesc_fblow_cpu->fdadr = 0x%x\n", fbi->dmadesc_fblow_cpu->fdadr);
-+ DPRINTK("fbi->dmadesc_fbhigh_cpu->fdadr = 0x%x\n", fbi->dmadesc_fbhigh_cpu->fdadr);
-+ DPRINTK("fbi->dmadesc_palette_cpu->fdadr = 0x%x\n", fbi->dmadesc_palette_cpu->fdadr);
-+
-+ DPRINTK("fbi->dmadesc_fblow_cpu->fsadr = 0x%x\n", fbi->dmadesc_fblow_cpu->fsadr);
-+ DPRINTK("fbi->dmadesc_fbhigh_cpu->fsadr = 0x%x\n", fbi->dmadesc_fbhigh_cpu->fsadr);
-+ DPRINTK("fbi->dmadesc_palette_cpu->fsadr = 0x%x\n", fbi->dmadesc_palette_cpu->fsadr);
-+
-+ DPRINTK("fbi->dmadesc_fblow_cpu->ldcmd = 0x%x\n", fbi->dmadesc_fblow_cpu->ldcmd);
-+ DPRINTK("fbi->dmadesc_fbhigh_cpu->ldcmd = 0x%x\n", fbi->dmadesc_fbhigh_cpu->ldcmd);
-+ DPRINTK("fbi->dmadesc_palette_cpu->ldcmd = 0x%x\n", fbi->dmadesc_palette_cpu->ldcmd);
-+
-+ fbi->reg_lccr0 = new_regs.lccr0;
-+ fbi->reg_lccr1 = new_regs.lccr1;
-+ fbi->reg_lccr2 = new_regs.lccr2;
-+ fbi->reg_lccr3 = new_regs.lccr3;
-+ local_irq_restore(flags);
-+
-+ /*
-+ * Only update the registers if the controller is enabled
-+ * and something has changed.
-+ */
-+ if ((LCCR0 != fbi->reg_lccr0) || (LCCR1 != fbi->reg_lccr1) ||
-+ (LCCR2 != fbi->reg_lccr2) || (LCCR3 != fbi->reg_lccr3) ||
-+ (FDADR0 != fbi->fdadr0) || (FDADR1 != fbi->fdadr1))
-+ pxafb_schedule_task(fbi, C_REENABLE);
-+
-+ return 0;
-+}
-+
-+/*
-+ * NOTE! The following functions are purely helpers for set_ctrlr_state.
-+ * Do not call them directly; set_ctrlr_state does the correct serialisation
-+ * to ensure that things happen in the right way 100% of time time.
-+ * -- rmk
-+ */
-+
-+/*
-+ * FIXME: move LCD power stuff into pxafb_power_up_lcd()
-+ * Also, I'm expecting that the backlight stuff should
-+ * be handled differently.
-+ */
-+static void pxafb_backlight_on(struct pxafb_info *fbi)
-+{
-+ DPRINTK("backlight on\n");
-+
-+#ifdef CONFIG_ARCH_PXA_IDP
-+ if(machine_is_pxa_idp()) {
-+ FB_BACKLIGHT_ON();
-+ }
-+#endif
-+}
-+
-+/*
-+ * FIXME: move LCD power stuf into pxafb_power_down_lcd()
-+ * Also, I'm expecting that the backlight stuff should
-+ * be handled differently.
-+ */
-+static void pxafb_backlight_off(struct pxafb_info *fbi)
-+{
-+ DPRINTK("backlight off\n");
-+
-+#ifdef CONFIG_ARCH_PXA_IDP
-+ if(machine_is_pxa_idp()) {
-+ FB_BACKLIGHT_OFF();
-+ }
-+#endif
-+
-+}
-+
-+static void pxafb_power_up_lcd(struct pxafb_info *fbi)
-+{
-+ DPRINTK("LCD power on\n");
-+ CKEN |= CKEN16_LCD;
-+
-+ if(machine_is_pxa_cerf()) {
-+ lcdctrl_enable();
-+ }
-+
-+#if CONFIG_ARCH_PXA_IDP
-+ /* set GPIOs, etc */
-+ if(machine_is_pxa_idp()) {
-+ // FIXME need to add proper delays
-+ FB_PWR_ON();
-+ FB_VLCD_ON(); // FIXME this should be after scanning starts
-+ }
-+#endif
-+}
-+
-+static void pxafb_power_down_lcd(struct pxafb_info *fbi)
-+{
-+ DPRINTK("LCD power off\n");
-+ CKEN &= ~CKEN16_LCD;
-+
-+ if(machine_is_pxa_cerf()) {
-+ lcdctrl_disable();
-+ }
-+
-+ /* set GPIOs, etc */
-+#if CONFIG_ARCH_PXA_IDP
-+ if(machine_is_pxa_idp()) {
-+ // FIXME need to add proper delays
-+ FB_PWR_OFF();
-+ FB_VLCD_OFF(); // FIXME this should be before scanning stops
-+ }
-+#endif
-+
-+}
-+
-+static void pxafb_setup_gpio(struct pxafb_info *fbi)
-+{
-+ unsigned int lccr0;
-+
-+ /*
-+ * setup is based on type of panel supported
-+ */
-+
-+ lccr0 = fbi->lccr0;
-+
-+ /* 4 bit interface */
-+ if ((lccr0 & LCCR0_CMS) && (lccr0 & LCCR0_SDS) && !(lccr0 & LCCR0_DPD))
-+ {
-+ // bits 58-61
-+ GPDR1 |= (0xf << 26);
-+ GAFR1_U = (GAFR1_U & ~(0xff << 20)) | (0xaa << 20);
-+
-+ // bits 74-77
-+ GPDR2 |= (0xf << 10);
-+ GAFR2_L = (GAFR2_L & ~(0xff << 20)) | (0xaa << 20);
-+ }
-+
-+ /* 8 bit interface */
-+ else if (((lccr0 & LCCR0_CMS) && ((lccr0 & LCCR0_SDS) || (lccr0 & LCCR0_DPD))) ||
-+ (!(lccr0 & LCCR0_CMS) && !(lccr0 & LCCR0_PAS) && !(lccr0 & LCCR0_SDS)))
-+ {
-+ // bits 58-65
-+ GPDR1 |= (0x3f << 26);
-+ GPDR2 |= (0x3);
-+
-+ GAFR1_U = (GAFR1_U & ~(0xfff << 20)) | (0xaaa << 20);
-+ GAFR2_L = (GAFR2_L & ~0xf) | (0xa);
-+
-+ // bits 74-77
-+ GPDR2 |= (0xf << 10);
-+ GAFR2_L = (GAFR2_L & ~(0xff << 20)) | (0xaa << 20);
-+ }
-+
-+ /* 16 bit interface */
-+ else if (!(lccr0 & LCCR0_CMS) && ((lccr0 & LCCR0_SDS) || (lccr0 & LCCR0_PAS)))
-+ {
-+ // bits 58-77
-+ GPDR1 |= (0x3f << 26);
-+ GPDR2 |= 0x00003fff;
-+
-+ GAFR1_U = (GAFR1_U & ~(0xfff << 20)) | (0xaaa << 20);
-+ GAFR2_L = (GAFR2_L & 0xf0000000) | 0x0aaaaaaa;
-+ }
-+ else
-+ {
-+ printk( KERN_ERR "pxafb_setup_gpio: unable to determine bits per pixel\n");
-+ }
-+}
-+
-+static void pxafb_enable_controller(struct pxafb_info *fbi)
-+{
-+ DPRINTK("Enabling LCD controller\n");
-+
-+ /* Sequence from 11.7.10 */
-+ LCCR3 = fbi->reg_lccr3;
-+ LCCR2 = fbi->reg_lccr2;
-+ LCCR1 = fbi->reg_lccr1;
-+ LCCR0 = fbi->reg_lccr0 & ~LCCR0_ENB;
-+
-+ /* FIXME we used to have LCD power control here */
-+
-+ FDADR0 = fbi->fdadr0;
-+ FDADR1 = fbi->fdadr1;
-+ LCCR0 |= LCCR0_ENB;
-+
-+ DPRINTK("FDADR0 = 0x%08x\n", (unsigned int)FDADR0);
-+ DPRINTK("FDADR1 = 0x%08x\n", (unsigned int)FDADR1);
-+ DPRINTK("LCCR0 = 0x%08x\n", (unsigned int)LCCR0);
-+ DPRINTK("LCCR1 = 0x%08x\n", (unsigned int)LCCR1);
-+ DPRINTK("LCCR2 = 0x%08x\n", (unsigned int)LCCR2);
-+ DPRINTK("LCCR3 = 0x%08x\n", (unsigned int)LCCR3);
-+}
-+
-+static void pxafb_disable_controller(struct pxafb_info *fbi)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+ DPRINTK("Disabling LCD controller\n");
-+
-+ /* FIXME add power down GPIO stuff here */
-+
-+ add_wait_queue(&fbi->ctrlr_wait, &wait);
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+
-+ LCSR = 0xffffffff; /* Clear LCD Status Register */
-+ LCCR0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */
-+ LCCR0 &= ~LCCR0_ENB; /* Disable LCD Controller */
-+
-+ schedule_timeout(20 * HZ / 1000);
-+ current->state = TASK_RUNNING;
-+ remove_wait_queue(&fbi->ctrlr_wait, &wait);
-+}
-+
-+/*
-+ * pxafb_handle_irq: Handle 'LCD DONE' interrupts.
-+ */
-+static void pxafb_handle_irq(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct pxafb_info *fbi = dev_id;
-+ unsigned int lcsr = LCSR;
-+
-+ if (lcsr & LCSR_LDD) {
-+ LCCR0 |= LCCR0_LDM;
-+ wake_up(&fbi->ctrlr_wait);
-+ }
-+
-+ LCSR = lcsr;
-+}
-+
-+/*
-+ * This function must be called from task context only, since it will
-+ * sleep when disabling the LCD controller, or if we get two contending
-+ * processes trying to alter state.
-+ */
-+static void set_ctrlr_state(struct pxafb_info *fbi, u_int state)
-+{
-+ u_int old_state;
-+
-+ down(&fbi->ctrlr_sem);
-+
-+ old_state = fbi->state;
-+
-+ switch (state) {
-+ case C_DISABLE_CLKCHANGE:
-+ /*
-+ * Disable controller for clock change. If the
-+ * controller is already disabled, then do nothing.
-+ */
-+ if (old_state != C_DISABLE) {
-+ fbi->state = state;
-+ pxafb_disable_controller(fbi);
-+ }
-+ break;
-+
-+ case C_DISABLE:
-+ /*
-+ * Disable controller
-+ */
-+ if (old_state != C_DISABLE) {
-+ fbi->state = state;
-+
-+ pxafb_backlight_off(fbi);
-+ if (old_state != C_DISABLE_CLKCHANGE)
-+ pxafb_disable_controller(fbi);
-+ pxafb_power_down_lcd(fbi);
-+ }
-+ break;
-+
-+ case C_ENABLE_CLKCHANGE:
-+ /*
-+ * Enable the controller after clock change. Only
-+ * do this if we were disabled for the clock change.
-+ */
-+ if (old_state == C_DISABLE_CLKCHANGE) {
-+ fbi->state = C_ENABLE;
-+ pxafb_enable_controller(fbi);
-+ }
-+ break;
-+
-+ case C_REENABLE:
-+ /*
-+ * Re-enable the controller only if it was already
-+ * enabled. This is so we reprogram the control
-+ * registers.
-+ */
-+ if (old_state == C_ENABLE) {
-+ pxafb_disable_controller(fbi);
-+ pxafb_setup_gpio(fbi);
-+ pxafb_enable_controller(fbi);
-+ }
-+ break;
-+
-+ case C_ENABLE:
-+ /*
-+ * Power up the LCD screen, enable controller, and
-+ * turn on the backlight.
-+ */
-+ if (old_state != C_ENABLE) {
-+ fbi->state = C_ENABLE;
-+ pxafb_setup_gpio(fbi);
-+ pxafb_power_up_lcd(fbi);
-+ pxafb_enable_controller(fbi);
-+ pxafb_backlight_on(fbi);
-+ }
-+ break;
-+ }
-+ up(&fbi->ctrlr_sem);
-+}
-+
-+/*
-+ * Our LCD controller task (which is called when we blank or unblank)
-+ * via keventd.
-+ */
-+static void pxafb_task(void *dummy)
-+{
-+ struct pxafb_info *fbi = dummy;
-+ u_int state = xchg(&fbi->task_state, -1);
-+
-+ set_ctrlr_state(fbi, state);
-+}
-+
-+#ifdef CONFIG_CPU_FREQ
-+/*
-+ * CPU clock speed change handler. We need to adjust the LCD timing
-+ * parameters when the CPU clock is adjusted by the power management
-+ * subsystem.
-+ */
-+static int
-+pxafb_clkchg_notifier(struct notifier_block *nb, unsigned long val,
-+ void *data)
-+{
-+ struct pxafb_info *fbi = TO_INF(nb, clockchg);
-+ u_int pcd;
-+
-+ switch (val) {
-+ case CPUFREQ_MINMAX:
-+ /* todo: fill in min/max values */
-+ break;
-+
-+ case CPUFREQ_PRECHANGE:
-+ set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE);
-+ break;
-+
-+ case CPUFREQ_POSTCHANGE:
-+ pcd = get_pcd(fbi->fb.var.pixclock);
-+ fbi->reg_lccr3 = (fbi->reg_lccr3 & ~0xff) | LCCR3_PixClkDiv(pcd);
-+ set_ctrlr_state(fbi, C_ENABLE_CLKCHANGE);
-+ break;
-+ }
-+ return 0;
-+}
-+#endif
-+
-+#ifdef CONFIG_PM
-+/*
-+ * Power management hook. Note that we won't be called from IRQ context,
-+ * unlike the blank functions above, so we may sleep.
-+ */
-+static int
-+pxafb_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data)
-+{
-+ struct pxafb_info *fbi = pm_dev->data;
-+
-+ DPRINTK("pm_callback: %d\n", req);
-+
-+ if (req == PM_SUSPEND || req == PM_RESUME) {
-+ int state = (int)data;
-+
-+ if (state == 0) {
-+ /* Enter D0. */
-+ set_ctrlr_state(fbi, C_ENABLE);
-+ } else {
-+ /* Enter D1-D3. Disable the LCD controller. */
-+ set_ctrlr_state(fbi, C_DISABLE);
-+ }
-+ }
-+ DPRINTK("done\n");
-+ return 0;
-+}
-+#endif
-+
-+/*
-+ * pxafb_map_video_memory():
-+ * Allocates the DRAM memory for the frame buffer. This buffer is
-+ * remapped into a non-cached, non-buffered, memory region to
-+ * allow palette and pixel writes to occur without flushing the
-+ * cache. Once this area is remapped, all virtual memory
-+ * access to the video memory should occur at the new region.
-+ */
-+static int __init pxafb_map_video_memory(struct pxafb_info *fbi)
-+{
-+ u_long palette_mem_size;
-+
-+ /*
-+ * We reserve one page for the palette, plus the size
-+ * of the framebuffer.
-+ *
-+ * layout of stuff in memory
-+ *
-+ * fblow descriptor
-+ * fbhigh descriptor
-+ * palette descriptor
-+ * palette
-+ * page boundary->
-+ * frame buffer
-+ */
-+ fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len + PAGE_SIZE);
-+ fbi->map_cpu = consistent_alloc(GFP_KERNEL, fbi->map_size,
-+ &fbi->map_dma, PTE_BUFFERABLE);
-+
-+ if (fbi->map_cpu) {
-+ fbi->screen_cpu = fbi->map_cpu + PAGE_SIZE;
-+ fbi->screen_dma = fbi->map_dma + PAGE_SIZE;
-+ fbi->fb.fix.smem_start = fbi->screen_dma;
-+
-+ fbi->palette_size = fbi->fb.var.bits_per_pixel == 8 ? 256 : 16;
-+
-+ palette_mem_size = fbi->palette_size * sizeof(u16);
-+
-+ DPRINTK("palette_mem_size = 0x%08lx\n", (u_long) palette_mem_size);
-+
-+ fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size);
-+ fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size;
-+
-+ }
-+
-+ return fbi->map_cpu ? 0 : -ENOMEM;
-+}
-+
-+/* Fake monspecs to fill in fbinfo structure */
-+static struct fb_monspecs monspecs __initdata = {
-+ 30000, 70000, 50, 65, 0 /* Generic */
-+};
-+
-+
-+static struct pxafb_info * __init pxafb_init_fbinfo(void)
-+{
-+ struct pxafb_mach_info *inf;
-+ struct pxafb_info *fbi;
-+
-+ fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(struct display) +
-+ sizeof(u16) * 16, GFP_KERNEL);
-+ if (!fbi)
-+ return NULL;
-+
-+ memset(fbi, 0, sizeof(struct pxafb_info) + sizeof(struct display));
-+
-+ fbi->currcon = -1;
-+
-+ strcpy(fbi->fb.fix.id, PXA_NAME);
-+
-+ fbi->fb.fix.type = FB_TYPE_PACKED_PIXELS;
-+ fbi->fb.fix.type_aux = 0;
-+ fbi->fb.fix.xpanstep = 0;
-+ fbi->fb.fix.ypanstep = 0;
-+ fbi->fb.fix.ywrapstep = 0;
-+ fbi->fb.fix.accel = FB_ACCEL_NONE;
-+
-+ fbi->fb.var.nonstd = 0;
-+ fbi->fb.var.activate = FB_ACTIVATE_NOW;
-+ fbi->fb.var.height = -1;
-+ fbi->fb.var.width = -1;
-+ fbi->fb.var.accel_flags = 0;
-+ fbi->fb.var.vmode = FB_VMODE_NONINTERLACED;
-+
-+ strcpy(fbi->fb.modename, PXA_NAME);
-+ strcpy(fbi->fb.fontname, "Acorn8x8");
-+
-+ fbi->fb.fbops = &pxafb_ops;
-+ fbi->fb.changevar = NULL;
-+ fbi->fb.switch_con = pxafb_switch;
-+ fbi->fb.updatevar = pxafb_updatevar;
-+ fbi->fb.blank = pxafb_blank;
-+ fbi->fb.flags = FBINFO_FLAG_DEFAULT;
-+ fbi->fb.node = -1;
-+ fbi->fb.monspecs = monspecs;
-+ fbi->fb.disp = (struct display *)(fbi + 1);
-+ fbi->fb.pseudo_palette = (void *)(fbi->fb.disp + 1);
-+
-+ fbi->rgb[RGB_8] = &rgb_8;
-+ fbi->rgb[RGB_16] = &def_rgb_16;
-+
-+ inf = pxafb_get_machine_info(fbi);
-+
-+ fbi->max_xres = inf->xres;
-+ fbi->fb.var.xres = inf->xres;
-+ fbi->fb.var.xres_virtual = inf->xres;
-+ fbi->max_yres = inf->yres;
-+ fbi->fb.var.yres = inf->yres;
-+ fbi->fb.var.yres_virtual = inf->yres;
-+ fbi->max_bpp = inf->bpp;
-+ fbi->fb.var.bits_per_pixel = inf->bpp;
-+ fbi->fb.var.pixclock = inf->pixclock;
-+ fbi->fb.var.hsync_len = inf->hsync_len;
-+ fbi->fb.var.left_margin = inf->left_margin;
-+ fbi->fb.var.right_margin = inf->right_margin;
-+ fbi->fb.var.vsync_len = inf->vsync_len;
-+ fbi->fb.var.upper_margin = inf->upper_margin;
-+ fbi->fb.var.lower_margin = inf->lower_margin;
-+ fbi->fb.var.sync = inf->sync;
-+ fbi->fb.var.grayscale = inf->cmap_greyscale;
-+ fbi->cmap_inverse = inf->cmap_inverse;
-+ fbi->cmap_static = inf->cmap_static;
-+ fbi->lccr0 = inf->lccr0;
-+ fbi->lccr3 = inf->lccr3;
-+ fbi->state = C_DISABLE;
-+ fbi->task_state = (u_char)-1;
-+ fbi->fb.fix.smem_len = fbi->max_xres * fbi->max_yres *
-+ fbi->max_bpp / 8;
-+
-+ init_waitqueue_head(&fbi->ctrlr_wait);
-+ INIT_TQUEUE(&fbi->task, pxafb_task, fbi);
-+ init_MUTEX(&fbi->ctrlr_sem);
-+
-+ return fbi;
-+}
-+
-+int __init pxafb_init(void)
-+{
-+ struct pxafb_info *fbi;
-+ int ret;
-+
-+ fbi = pxafb_init_fbinfo();
-+ ret = -ENOMEM;
-+ if (!fbi)
-+ goto failed;
-+
-+ if(machine_is_pxa_cerf()) {
-+ // brightness&contrast is handled via lcdctrl.
-+ lcdctrl_init();
-+ }
-+
-+ /* Initialize video memory */
-+ ret = pxafb_map_video_memory(fbi);
-+ if (ret)
-+ goto failed;
-+
-+ ret = request_irq(IRQ_LCD, pxafb_handle_irq, SA_INTERRUPT,
-+ "LCD", fbi);
-+ if (ret) {
-+ printk(KERN_ERR "pxafb: failed in request_irq: %d\n", ret);
-+ goto failed;
-+ }
-+
-+ pxafb_set_var(&fbi->fb.var, -1, &fbi->fb);
-+
-+ ret = register_framebuffer(&fbi->fb);
-+ if (ret < 0)
-+ goto failed;
-+
-+#ifdef CONFIG_PM
-+ /*
-+ * Note that the console registers this as well, but we want to
-+ * power down the display prior to sleeping.
-+ */
-+ fbi->pm = pm_register(PM_SYS_DEV, PM_SYS_VGA, pxafb_pm_callback);
-+ if (fbi->pm)
-+ fbi->pm->data = fbi;
-+#endif
-+#ifdef CONFIG_CPU_FREQ
-+ fbi->clockchg.notifier_call = pxafb_clkchg_notifier;
-+ cpufreq_register_notifier(&fbi->clockchg);
-+#endif
-+
-+ /*
-+ * Ok, now enable the LCD controller
-+ */
-+ set_ctrlr_state(fbi, C_ENABLE);
-+
-+ /* This driver cannot be unloaded at the moment */
-+ MOD_INC_USE_COUNT;
-+
-+ return 0;
-+
-+failed:
-+ if (fbi)
-+ kfree(fbi);
-+ return ret;
-+}
-+
-+
-+#ifdef MODULE
-+module_init(pxafb_init);
-+#endif
-+
-+MODULE_DESCRIPTION("loadable framebuffer driver for PXA");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/video/pxafb.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,238 @@
-+/*
-+ * linux/drivers/video/pxafb.h
-+ * -- Intel PXA250/210 LCD Controller Frame Buffer Device
-+ *
-+ * Copyright (C) 1999 Eric A. Thomas
-+ * Based on acornfb.c Copyright (C) Russell King.
-+ *
-+ * 2001-08-03: Cliff Brake <cbrake@acclent.com>
-+ * - ported SA1100 code to PXA
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file COPYING in the main directory of this archive
-+ * for more details.
-+ */
-+
-+/*
-+ * These are the bitfields for each
-+ * display depth that we support.
-+ */
-+struct pxafb_rgb {
-+ struct fb_bitfield red;
-+ struct fb_bitfield green;
-+ struct fb_bitfield blue;
-+ struct fb_bitfield transp;
-+};
-+
-+/*
-+ * This structure describes the machine which we are running on.
-+ */
-+struct pxafb_mach_info {
-+ u_long pixclock;
-+
-+ u_short xres;
-+ u_short yres;
-+
-+ u_char bpp;
-+ u_char hsync_len;
-+ u_char left_margin;
-+ u_char right_margin;
-+
-+ u_char vsync_len;
-+ u_char upper_margin;
-+ u_char lower_margin;
-+ u_char sync;
-+
-+ u_int cmap_greyscale:1,
-+ cmap_inverse:1,
-+ cmap_static:1,
-+ unused:29;
-+
-+ u_int lccr0;
-+ u_int lccr3;
-+};
-+
-+/* Shadows for LCD controller registers */
-+struct pxafb_lcd_reg {
-+ unsigned int lccr0;
-+ unsigned int lccr1;
-+ unsigned int lccr2;
-+ unsigned int lccr3;
-+};
-+
-+/* PXA LCD DMA descriptor */
-+struct pxafb_dma_descriptor {
-+ unsigned int fdadr;
-+ unsigned int fsadr;
-+ unsigned int fidr;
-+ unsigned int ldcmd;
-+};
-+
-+#define RGB_8 (0)
-+#define RGB_16 (1)
-+#define NR_RGB 2
-+
-+struct pxafb_info {
-+ struct fb_info fb;
-+ signed int currcon;
-+
-+ struct pxafb_rgb *rgb[NR_RGB];
-+
-+ u_int max_bpp;
-+ u_int max_xres;
-+ u_int max_yres;
-+
-+ /*
-+ * These are the addresses we mapped
-+ * the framebuffer memory region to.
-+ */
-+
-+ /* raw memory addresses */
-+ dma_addr_t map_dma; /* physical */
-+ u_char * map_cpu; /* virtual */
-+ u_int map_size;
-+
-+ /* addresses of pieces placed in raw buffer */
-+ u_char * screen_cpu; /* virtual address of frame buffer */
-+ dma_addr_t screen_dma; /* physical address of frame buffer */
-+ u16 * palette_cpu; /* virtual address of palette memory */
-+ dma_addr_t palette_dma; /* physical address of palette memory */
-+ u_int palette_size;
-+
-+ /* DMA descriptors */
-+ struct pxafb_dma_descriptor * dmadesc_fblow_cpu;
-+ dma_addr_t dmadesc_fblow_dma;
-+ struct pxafb_dma_descriptor * dmadesc_fbhigh_cpu;
-+ dma_addr_t dmadesc_fbhigh_dma;
-+ struct pxafb_dma_descriptor * dmadesc_palette_cpu;
-+ dma_addr_t dmadesc_palette_dma;
-+
-+ dma_addr_t fdadr0;
-+ dma_addr_t fdadr1;
-+
-+ u_int lccr0;
-+ u_int lccr3;
-+ u_int cmap_inverse:1,
-+ cmap_static:1,
-+ unused:30;
-+
-+ u_int reg_lccr0;
-+ u_int reg_lccr1;
-+ u_int reg_lccr2;
-+ u_int reg_lccr3;
-+
-+ volatile u_char state;
-+ volatile u_char task_state;
-+ struct semaphore ctrlr_sem;
-+ wait_queue_head_t ctrlr_wait;
-+ struct tq_struct task;
-+
-+#ifdef CONFIG_PM
-+ struct pm_dev *pm;
-+#endif
-+#ifdef CONFIG_CPU_FREQ
-+ struct notifier_block clockchg;
-+#endif
-+};
-+
-+#define __type_entry(ptr,type,member) ((type *)((char *)(ptr)-offsetof(type,member)))
-+
-+#define TO_INF(ptr,member) __type_entry(ptr,struct pxafb_info,member)
-+
-+/*
-+ * These are the actions for set_ctrlr_state
-+ */
-+#define C_DISABLE (0)
-+#define C_ENABLE (1)
-+#define C_DISABLE_CLKCHANGE (2)
-+#define C_ENABLE_CLKCHANGE (3)
-+#define C_REENABLE (4)
-+
-+#define PXA_NAME "PXA"
-+
-+/*
-+ * Debug macros
-+ */
-+#if DEBUG
-+# define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
-+#else
-+# define DPRINTK(fmt, args...)
-+#endif
-+
-+/*
-+ * Minimum X and Y resolutions
-+ */
-+#define MIN_XRES 64
-+#define MIN_YRES 64
-+
-+/*
-+ * Are we configured for 8 or 16 bits per pixel?
-+ */
-+#ifdef CONFIG_FB_PXA_8BPP
-+# define PXAFB_BPP 8
-+# define PXAFB_BPP_BITS 0x03
-+#elif CONFIG_FB_PXA_16BPP
-+# define PXAFB_BPP 16
-+# define PXAFB_BPP_BITS 0x04
-+#endif
-+
-+#if defined(CONFIG_ARCH_LUBBOCK)
-+#define LCD_PIXCLOCK 150000
-+#define LCD_BPP PXAFB_BPP
-+#ifdef CONFIG_FB_PXA_QVGA
-+#define LCD_XRES 320
-+#define LCD_YRES 240
-+#define LCD_HORIZONTAL_SYNC_PULSE_WIDTH 51
-+#define LCD_VERTICAL_SYNC_PULSE_WIDTH 1
-+#define LCD_BEGIN_OF_LINE_WAIT_COUNT 1
-+#define LCD_BEGIN_FRAME_WAIT_COUNT 8
-+#define LCD_END_OF_LINE_WAIT_COUNT 1
-+#define LCD_END_OF_FRAME_WAIT_COUNT 1
-+#define LCD_SYNC (FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT)
-+#define LCD_LCCR0 0x003008F8
-+#define LCD_LCCR3 (0x0040FF0C | (PXAFB_BPP_BITS << 24))
-+#else
-+#define LCD_XRES 640
-+#define LCD_YRES 480
-+#define LCD_HORIZONTAL_SYNC_PULSE_WIDTH 1
-+#define LCD_VERTICAL_SYNC_PULSE_WIDTH 1
-+#define LCD_BEGIN_OF_LINE_WAIT_COUNT 3
-+#define LCD_BEGIN_FRAME_WAIT_COUNT 0
-+#define LCD_END_OF_LINE_WAIT_COUNT 3
-+#define LCD_END_OF_FRAME_WAIT_COUNT 0
-+#define LCD_SYNC (FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT)
-+#define LCD_LCCR0 0x0030087C
-+#define LCD_LCCR3 (0x0040FF0C | (PXAFB_BPP_BITS << 24))
-+#endif
-+
-+#elif defined (CONFIG_ARCH_PXA_IDP)
-+#define LCD_PIXCLOCK 150000
-+#define LCD_BPP PXAFB_BPP
-+#define LCD_XRES 640
-+#define LCD_YRES 480
-+#define LCD_HORIZONTAL_SYNC_PULSE_WIDTH 1
-+#define LCD_VERTICAL_SYNC_PULSE_WIDTH 1
-+#define LCD_BEGIN_OF_LINE_WAIT_COUNT 3
-+#define LCD_BEGIN_FRAME_WAIT_COUNT 0
-+#define LCD_END_OF_LINE_WAIT_COUNT 3
-+#define LCD_END_OF_FRAME_WAIT_COUNT 0
-+#define LCD_SYNC (FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT)
-+#define LCD_LCCR0 0x0030087C
-+#define LCD_LCCR3 (0x0040FF0C | (PXAFB_BPP_BITS << 24))
-+
-+#elif defined CONFIG_PXA_CERF_PDA
-+#define LCD_PIXCLOCK 171521
-+#define LCD_BPP PXAFB_BPP
-+#define LCD_XRES 240
-+#define LCD_YRES 320
-+#define LCD_HORIZONTAL_SYNC_PULSE_WIDTH 7
-+#define LCD_VERTICAL_SYNC_PULSE_WIDTH 2
-+#define LCD_BEGIN_OF_LINE_WAIT_COUNT 17
-+#define LCD_BEGIN_FRAME_WAIT_COUNT 0
-+#define LCD_END_OF_LINE_WAIT_COUNT 17
-+#define LCD_END_OF_FRAME_WAIT_COUNT 0
-+#define LCD_SYNC (FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT)
-+#define LCD_LCCR0 (LCCR0_LDM | LCCR0_SFM | LCCR0_IUM | LCCR0_EFM | LCCR0_QDM | LCCR0_BM | LCCR0_OUM)
-+#define LCD_LCCR3 (LCCR3_PCP | LCCR3_PixClkDiv(0x12) | LCCR3_Bpp(PXAFB_BPP_BITS) | LCCR3_Acb(0x18))
-+
-+#endif
---- linux-2.4.25/drivers/video/sa1100fb.c~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/drivers/video/sa1100fb.c 2004-03-31 17:15:12.000000000 +0200
-@@ -2175,7 +2175,7 @@
- */
- fbi->map_size = PAGE_ALIGN(fbi->fb.fix.smem_len + PAGE_SIZE);
- fbi->map_cpu = consistent_alloc(GFP_KERNEL, fbi->map_size,
-- &fbi->map_dma);
-+ &fbi->map_dma, PTE_BUFFERABLE);
-
- if (fbi->map_cpu) {
- fbi->screen_cpu = fbi->map_cpu + PAGE_SIZE;
---- linux-2.4.25/fs/Config.in~2.4.25-vrs2-pxa1.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/fs/Config.in 2004-03-31 17:15:12.000000000 +0200
-@@ -51,6 +51,9 @@
- int 'JFFS2 debugging verbosity (0 = quiet, 2 = noisy)' CONFIG_JFFS2_FS_DEBUG 0
- fi
- tristate 'Compressed ROM file system support' CONFIG_CRAMFS
-+dep_mbool ' Use linear addressing for cramfs' CONFIG_CRAMFS_LINEAR $CONFIG_CRAMFS
-+dep_bool ' Support XIP on linear cramfs' CONFIG_CRAMFS_LINEAR_XIP $CONFIG_CRAMFS_LINEAR
-+dep_bool ' Root file system on linear cramfs' CONFIG_ROOT_CRAMFS_LINEAR $CONFIG_CRAMFS_LINEAR
- bool 'Virtual memory file system support (former shm fs)' CONFIG_TMPFS
- define_bool CONFIG_RAMFS y
-
---- linux-2.4.25/fs/cramfs/inode.c~2.4.25-vrs2-pxa1.patch 2002-08-03 02:39:45.000000000 +0200
-+++ linux-2.4.25/fs/cramfs/inode.c 2004-03-31 17:15:12.000000000 +0200
-@@ -4,11 +4,29 @@
- * Copyright (C) 1999 Linus Torvalds.
- *
- * This file is released under the GPL.
-- */
--
--/*
-+ *
- * These are the VFS interfaces to the compressed rom filesystem.
- * The actual compression is based on zlib, see the other files.
-+ *
-+ * Linear Addressing code
-+ * Copyright (C) 2000 Shane Nay.
-+ *
-+ * Allows you to have a linearly addressed cramfs filesystem.
-+ * Saves the need for buffer, and the munging of the buffer.
-+ * Savings a bit over 32k with default PAGE_SIZE, BUFFER_SIZE
-+ * etc. Usefull on embedded platform with ROM :-).
-+ *
-+ * Downsides- Currently linear addressed cramfs partitions
-+ * don't co-exist with block cramfs partitions.
-+ *
-+ * 28-Dec-2000: XIP mode for linear cramfs
-+ * Copyright (C) 2000 Robert Leslie <rob@mars.org>
-+ *
-+ * Dynamic allocation of linear cramfs space by Nicolas Pitre
-+ * Copyright (C) 2003 Monta Vista Software, Inc.
-+ *
-+ * Linear cramfs now requires that you pass the physaddr= parameter to
-+ * the mount process. Allows for multiple linear cramfs partitions.
- */
-
- #include <linux/module.h>
-@@ -16,10 +34,12 @@
- #include <linux/pagemap.h>
- #include <linux/init.h>
- #include <linux/string.h>
-+#include <linux/kernel.h>
- #include <linux/locks.h>
- #include <linux/blkdev.h>
- #include <linux/cramfs_fs.h>
- #include <asm/semaphore.h>
-+#include <asm/io.h>
-
- #include <asm/uaccess.h>
-
-@@ -28,6 +48,8 @@
- #define CRAMFS_SB_BLOCKS u.cramfs_sb.blocks
- #define CRAMFS_SB_FILES u.cramfs_sb.files
- #define CRAMFS_SB_FLAGS u.cramfs_sb.flags
-+#define CRAMFS_SB_LINEAR_PHYS_ADDR u.cramfs_sb.linear_phys_addr
-+#define CRAMFS_SB_LINEAR_VIRT_ADDR u.cramfs_sb.linear_virt_addr
-
- static struct super_operations cramfs_ops;
- static struct inode_operations cramfs_dir_inode_operations;
-@@ -42,6 +64,74 @@
- #define CRAMINO(x) ((x)->offset?(x)->offset<<2:1)
- #define OFFSET(x) ((x)->i_ino)
-
-+
-+#ifdef CONFIG_CRAMFS_LINEAR_XIP
-+
-+static int cramfs_mmap(struct file *file, struct vm_area_struct *vma)
-+{
-+ unsigned long address, length;
-+ struct inode *inode = file->f_dentry->d_inode;
-+ struct super_block *sb = inode->i_sb;
-+
-+ /* this is only used in the case of read-only maps for XIP */
-+
-+ if (vma->vm_flags & VM_WRITE)
-+ return generic_file_mmap(file, vma);
-+
-+ if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE))
-+ return -EINVAL;
-+
-+ address = PAGE_ALIGN(sb->CRAMFS_SB_LINEAR_PHYS_ADDR + OFFSET(inode));
-+ address += vma->vm_pgoff << PAGE_SHIFT;
-+
-+ length = vma->vm_end - vma->vm_start;
-+
-+ if (length > inode->i_size)
-+ length = inode->i_size;
-+
-+ length = PAGE_ALIGN(length);
-+
-+
-+#if 0
-+ /* Doing the following makes it slower and more broken. bdl */
-+ /*
-+ * Accessing memory above the top the kernel knows about or
-+ * through a file pointer that was marked O_SYNC will be
-+ * done non-cached.
-+ */
-+ vma->vm_page_prot =
-+ __pgprot((pgprot_val(vma->vm_page_prot) & ~_CACHE_MASK)
-+ | _CACHE_UNCACHED);
-+#endif
-+
-+ /*
-+ * Don't dump addresses that are not real memory to a core file.
-+ */
-+ vma->vm_flags |= VM_IO;
-+ flush_tlb_page(vma, address);
-+ if (remap_page_range(vma->vm_start, address, length,
-+ vma->vm_page_prot))
-+ return -EAGAIN;
-+
-+#ifdef DEBUG_CRAMFS_XIP
-+ printk("cramfs_mmap: mapped %s at 0x%08lx, length %lu to vma 0x%08lx"
-+ ", page_prot 0x%08lx\n",
-+ file->f_dentry->d_name.name, address, length,
-+ vma->vm_start, pgprot_val(vma->vm_page_prot));
-+#endif
-+
-+ return 0;
-+}
-+
-+static struct file_operations cramfs_linear_xip_fops = {
-+ read: generic_file_read,
-+ mmap: cramfs_mmap,
-+};
-+
-+#define CRAMFS_INODE_IS_XIP(x) ((x)->i_mode & S_ISVTX)
-+
-+#endif
-+
- static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inode * cramfs_inode)
- {
- struct inode * inode = new_inode(sb);
-@@ -60,7 +150,11 @@
- without -noleaf option. */
- insert_inode_hash(inode);
- if (S_ISREG(inode->i_mode)) {
-+#ifdef CONFIG_CRAMFS_LINEAR_XIP
-+ inode->i_fop = CRAMFS_INODE_IS_XIP(inode) ? &cramfs_linear_xip_fops : &generic_ro_fops;
-+#else
- inode->i_fop = &generic_ro_fops;
-+#endif
- inode->i_data.a_ops = &cramfs_aops;
- } else if (S_ISDIR(inode->i_mode)) {
- inode->i_op = &cramfs_dir_inode_operations;
-@@ -76,6 +170,18 @@
- return inode;
- }
-
-+#ifdef CONFIG_CRAMFS_LINEAR
-+/*
-+ * Return a pointer to the block in the linearly addressed cramfs image.
-+ */
-+static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned int len)
-+{
-+ if (!len)
-+ return NULL;
-+ return (void*)(sb->CRAMFS_SB_LINEAR_VIRT_ADDR + offset);
-+}
-+
-+#else /* Not linear addressing - aka regular block mode. */
- /*
- * We have our own block cache: don't fill up the buffer cache
- * with the rom-image, because the way the filesystem is set
-@@ -186,23 +292,65 @@
- }
- return read_buffers[buffer] + offset;
- }
--
-+#endif /* !CONFIG_CRAMFS_LINEAR */
-
- static struct super_block * cramfs_read_super(struct super_block *sb, void *data, int silent)
- {
-+#ifndef CONFIG_CRAMFS_LINEAR
- int i;
-+#else
-+ char *p;
-+#endif
- struct cramfs_super super;
- unsigned long root_offset;
- struct super_block * retval = NULL;
-
-- set_blocksize(sb->s_dev, PAGE_CACHE_SIZE);
- sb->s_blocksize = PAGE_CACHE_SIZE;
- sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-
-+#ifndef CONFIG_CRAMFS_LINEAR
-+
-+ set_blocksize(sb->s_dev, PAGE_CACHE_SIZE);
-+
- /* Invalidate the read buffers on mount: think disk change.. */
- for (i = 0; i < READ_BUFFERS; i++)
- buffer_blocknr[i] = -1;
-
-+#else
-+
-+ /*
-+ * The physical location of the cramfs image is specified as
-+ * a mount parameter. This parameter is mandatory for obvious
-+ * reasons. Some validation is made on the phys address but this
-+ * is not exhaustive and we count on the fact that someone using
-+ * this feature is supposed to know what he/she's doing.
-+ */
-+ if (!data || !(p = strstr((char *)data, "physaddr="))) {
-+ printk(KERN_ERR "cramfs: unknown physical address for linear cramfs image\n");
-+ goto out;
-+ }
-+ sb->CRAMFS_SB_LINEAR_PHYS_ADDR = simple_strtoul(p + 9, NULL, 0);
-+ if (sb->CRAMFS_SB_LINEAR_PHYS_ADDR & (PAGE_SIZE-1)) {
-+ printk(KERN_ERR "cramfs: physical address 0x%lx for linear cramfs isn't aligned to a page boundary\n",
-+ sb->CRAMFS_SB_LINEAR_PHYS_ADDR);
-+ goto out;
-+ }
-+ if (sb->CRAMFS_SB_LINEAR_PHYS_ADDR == 0) {
-+ printk(KERN_ERR "cramfs: physical address for linear cramfs image can't be 0\n");
-+ goto out;
-+ }
-+ printk(KERN_INFO "cramfs: checking physical address 0x%lx for linear cramfs image\n",
-+ sb->CRAMFS_SB_LINEAR_PHYS_ADDR);
-+
-+ /* Map only one page for now. Will remap it when fs size is known. */
-+ sb->CRAMFS_SB_LINEAR_VIRT_ADDR =
-+ ioremap(sb->CRAMFS_SB_LINEAR_PHYS_ADDR, PAGE_SIZE);
-+ if (!sb->CRAMFS_SB_LINEAR_VIRT_ADDR) {
-+ printk(KERN_ERR "cramfs: ioremap of the linear cramfs image failed\n");
-+ goto out;
-+ }
-+#endif
-+
- down(&read_mutex);
- /* Read the first block and get the superblock from it */
- memcpy(&super, cramfs_read(sb, 0, sizeof(super)), sizeof(super));
-@@ -254,8 +402,26 @@
- /* Set it all up.. */
- sb->s_op = &cramfs_ops;
- sb->s_root = d_alloc_root(get_cramfs_inode(sb, &super.root));
-+
-+#ifdef CONFIG_CRAMFS_LINEAR
-+ /* Remap the whole filesystem now */
-+ iounmap(sb->CRAMFS_SB_LINEAR_VIRT_ADDR);
-+ printk(KERN_INFO "cramfs: linear cramfs image appears to be %lu KB in size\n",
-+ sb->CRAMFS_SB_SIZE/1024);
-+ sb->CRAMFS_SB_LINEAR_VIRT_ADDR =
-+ ioremap(sb->CRAMFS_SB_LINEAR_PHYS_ADDR, sb->CRAMFS_SB_SIZE);
-+ if (!sb->CRAMFS_SB_LINEAR_VIRT_ADDR) {
-+ printk(KERN_ERR "cramfs: ioremap of the linear cramfs image failed\n");
-+ goto out;
-+ }
-+#endif
-+
- retval = sb;
- out:
-+#ifdef CONFIG_CRAMFS_LINEAR
-+ if (!retval && sb->CRAMFS_SB_LINEAR_VIRT_ADDR)
-+ iounmap(sb->CRAMFS_SB_LINEAR_VIRT_ADDR);
-+#endif
- return retval;
- }
-
-@@ -388,6 +554,18 @@
-
- maxblock = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
- bytes_filled = 0;
-+#ifdef CONFIG_CRAMFS_LINEAR_XIP
-+ if (page->index < maxblock && CRAMFS_INODE_IS_XIP(inode)) {
-+ struct super_block *sb = inode->i_sb;
-+ u32 blkptr_offset = PAGE_ALIGN(OFFSET(inode)) +
-+ page->index * PAGE_CACHE_SIZE;
-+ memcpy( page_address(page),
-+ (void*)(sb->CRAMFS_SB_LINEAR_VIRT_ADDR + blkptr_offset),
-+ PAGE_CACHE_SIZE );
-+ bytes_filled = PAGE_CACHE_SIZE;
-+ pgdata = kmap(page);
-+ } else
-+#endif
- if (page->index < maxblock) {
- struct super_block *sb = inode->i_sb;
- u32 blkptr_offset = OFFSET(inode) + page->index*4;
-@@ -444,7 +622,11 @@
- statfs: cramfs_statfs,
- };
-
-+#ifndef CONFIG_CRAMFS_LINEAR
- static DECLARE_FSTYPE_DEV(cramfs_fs_type, "cramfs", cramfs_read_super);
-+#else
-+static DECLARE_FSTYPE(cramfs_fs_type, "cramfs", cramfs_read_super, 0);
-+#endif
-
- static int __init init_cramfs_fs(void)
- {
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/fs/cramfs/mkcramfs.c 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,821 @@
-+/*
-+ * mkcramfs - make a cramfs file system, optionally with XIP files.
-+ *
-+ * Copyright (C) 1999-2001 Transmeta Corporation
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+#include <sys/types.h>
-+#include <stdio.h>
-+#include <sys/stat.h>
-+#include <unistd.h>
-+#include <sys/mman.h>
-+#include <sys/fcntl.h>
-+#include <dirent.h>
-+#include <stdlib.h>
-+#include <errno.h>
-+#include <string.h>
-+#include <assert.h>
-+#include <getopt.h>
-+#include <linux/cramfs_fs.h>
-+#include <zlib.h>
-+
-+#define PAD_SIZE 512 /* only 0 and 512 supported by kernel */
-+
-+static const char *progname = "mkcramfs";
-+
-+/* N.B. If you change the disk format of cramfs, please update fs/cramfs/README. */
-+
-+/* Input status of 0 to print help and exit without an error. */
-+static void usage(int status)
-+{
-+ FILE *stream = status ? stderr : stdout;
-+
-+ fprintf(stream, "usage: %s [-h] [-e edition] [-i file] [-n name] dirname outfile\n"
-+ " -h print this help\n"
-+ " -E make all warnings errors (non-zero exit status)\n"
-+ " -e edition set edition number (part of fsid)\n"
-+ " -i file insert a file image into the filesystem (requires >= 2.4.0)\n"
-+ " -n name set name of cramfs filesystem\n"
-+ " -p pad by %d bytes for boot code\n"
-+ " -s sort directory entries (old option, ignored)\n"
-+ " -x make marked files eXecute In Place\n"
-+ " -z make explicit holes (requires >= 2.3.39)\n"
-+ " dirname root of the filesystem to be compressed\n"
-+ " outfile output file\n", progname, PAD_SIZE);
-+
-+ exit(status);
-+}
-+
-+#define PAGE_SIZE (4096)
-+#define PAGE_ALIGN(x) (((x) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
-+#define ROM_OFFSET 0
-+#define ROM_ALIGN(x) (PAGE_ALIGN((x) + ROM_OFFSET) - ROM_OFFSET)
-+#define PAGE_CACHE_SIZE (4096)
-+/* The kernel assumes PAGE_CACHE_SIZE as block size. */
-+static unsigned int blksize = PAGE_CACHE_SIZE;
-+static long total_blocks = 0, total_nodes = 1; /* pre-count the root node */
-+static int image_length = 0;
-+
-+/*
-+ * If opt_holes is set, then mkcramfs can create explicit holes in the
-+ * data, which saves 26 bytes per hole (which is a lot smaller a
-+ * saving than most most filesystems).
-+ *
-+ * Note that kernels up to at least 2.3.39 don't support cramfs holes,
-+ * which is why this is turned off by default.
-+ */
-+static int opt_edition = 0;
-+static int opt_errors = 0;
-+static int opt_holes = 0;
-+static int opt_xip = 0;
-+static int opt_pad = 0;
-+static char *opt_image = NULL;
-+static char *opt_name = NULL;
-+
-+static int warn_dev, warn_gid, warn_namelen, warn_skip, warn_size, warn_uid;
-+
-+#ifndef MIN
-+# define MIN(_a,_b) ((_a) < (_b) ? (_a) : (_b))
-+#endif
-+
-+/* In-core version of inode / directory entry. */
-+struct entry {
-+ /* stats */
-+ char *name;
-+ unsigned int mode, size, uid, gid;
-+
-+ /* FS data */
-+ void *uncompressed;
-+ /* points to other identical file */
-+ struct entry *same;
-+ unsigned int offset; /* pointer to compressed data in archive */
-+ unsigned int dir_offset; /* Where in the archive is the directory entry? */
-+
-+ /* organization */
-+ struct entry *child; /* null for non-directories and empty directories */
-+ struct entry *next;
-+};
-+
-+/*
-+ * The longest file name component to allow for in the input directory tree.
-+ * Ext2fs (and many others) allow up to 255 bytes. A couple of filesystems
-+ * allow longer (e.g. smbfs 1024), but there isn't much use in supporting
-+ * >255-byte names in the input directory tree given that such names get
-+ * truncated to 255 bytes when written to cramfs.
-+ */
-+#define MAX_INPUT_NAMELEN 255
-+
-+static int find_identical_file(struct entry *orig,struct entry *newfile)
-+{
-+ if(orig==newfile) return 1;
-+ if(!orig) return 0;
-+ if(orig->size==newfile->size && orig->uncompressed && !memcmp(orig->uncompressed,newfile->uncompressed,orig->size)) {
-+ newfile->same=orig;
-+ return 1;
-+ }
-+ return find_identical_file(orig->child,newfile) ||
-+ find_identical_file(orig->next,newfile);
-+}
-+
-+static void eliminate_doubles(struct entry *root,struct entry *orig) {
-+ if(orig) {
-+ if(orig->size && orig->uncompressed)
-+ find_identical_file(root,orig);
-+ eliminate_doubles(root,orig->child);
-+ eliminate_doubles(root,orig->next);
-+ }
-+}
-+
-+/*
-+ * We define our own sorting function instead of using alphasort which
-+ * uses strcoll and changes ordering based on locale information.
-+ */
-+static int cramsort (const void *a, const void *b)
-+{
-+ return strcmp ((*(const struct dirent **) a)->d_name,
-+ (*(const struct dirent **) b)->d_name);
-+}
-+
-+static unsigned int parse_directory(struct entry *root_entry, const char *name, struct entry **prev, loff_t *fslen_ub)
-+{
-+ struct dirent **dirlist;
-+ int totalsize = 0, dircount, dirindex;
-+ char *path, *endpath;
-+ size_t len = strlen(name);
-+
-+ /* Set up the path. */
-+ /* TODO: Reuse the parent's buffer to save memcpy'ing and duplication. */
-+ path = malloc(len + 1 + MAX_INPUT_NAMELEN + 1);
-+ if (!path) {
-+ perror(NULL);
-+ exit(8);
-+ }
-+ memcpy(path, name, len);
-+ endpath = path + len;
-+ *endpath = '/';
-+ endpath++;
-+
-+ /* read in the directory and sort */
-+ dircount = scandir(name, &dirlist, 0, cramsort);
-+
-+ if (dircount < 0) {
-+ perror(name);
-+ exit(8);
-+ }
-+
-+ /* process directory */
-+ for (dirindex = 0; dirindex < dircount; dirindex++) {
-+ struct dirent *dirent;
-+ struct entry *entry;
-+ struct stat st;
-+ int size;
-+ size_t namelen;
-+
-+ dirent = dirlist[dirindex];
-+
-+ /* Ignore "." and ".." - we won't be adding them to the archive */
-+ if (dirent->d_name[0] == '.') {
-+ if (dirent->d_name[1] == '\0')
-+ continue;
-+ if (dirent->d_name[1] == '.') {
-+ if (dirent->d_name[2] == '\0')
-+ continue;
-+ }
-+ }
-+ namelen = strlen(dirent->d_name);
-+ if (namelen > MAX_INPUT_NAMELEN) {
-+ fprintf(stderr,
-+ "Very long (%u bytes) filename `%s' found.\n"
-+ " Please increase MAX_INPUT_NAMELEN in mkcramfs.c and recompile. Exiting.\n",
-+ namelen, dirent->d_name);
-+ exit(8);
-+ }
-+ memcpy(endpath, dirent->d_name, namelen + 1);
-+
-+ if (lstat(path, &st) < 0) {
-+ perror(endpath);
-+ warn_skip = 1;
-+ continue;
-+ }
-+ entry = calloc(1, sizeof(struct entry));
-+ if (!entry) {
-+ perror(NULL);
-+ exit(8);
-+ }
-+ entry->name = strdup(dirent->d_name);
-+ if (!entry->name) {
-+ perror(NULL);
-+ exit(8);
-+ }
-+ if (namelen > 255) {
-+ /* Can't happen when reading from ext2fs. */
-+
-+ /* TODO: we ought to avoid chopping in half
-+ multi-byte UTF8 characters. */
-+ entry->name[namelen = 255] = '\0';
-+ warn_namelen = 1;
-+ }
-+ entry->mode = st.st_mode;
-+ entry->size = st.st_size;
-+ entry->uid = st.st_uid;
-+ if (entry->uid >= 1 << CRAMFS_UID_WIDTH)
-+ warn_uid = 1;
-+ entry->gid = st.st_gid;
-+ if (entry->gid >= 1 << CRAMFS_GID_WIDTH)
-+ /* TODO: We ought to replace with a default
-+ gid instead of truncating; otherwise there
-+ are security problems. Maybe mode should
-+ be &= ~070. Same goes for uid once Linux
-+ supports >16-bit uids. */
-+ warn_gid = 1;
-+ size = sizeof(struct cramfs_inode) + ((namelen + 3) & ~3);
-+ *fslen_ub += size;
-+ if (S_ISDIR(st.st_mode)) {
-+ entry->size = parse_directory(root_entry, path, &entry->child, fslen_ub);
-+ } else if (S_ISREG(st.st_mode)) {
-+ /* TODO: We ought to open files in do_compress, one
-+ at a time, instead of amassing all these memory
-+ maps during parse_directory (which don't get used
-+ until do_compress anyway). As it is, we tend to
-+ get EMFILE errors (especially if mkcramfs is run
-+ by non-root).
-+
-+ While we're at it, do analagously for symlinks
-+ (which would just save a little memory). */
-+ int fd = open(path, O_RDONLY);
-+ if (fd < 0) {
-+ perror(path);
-+ warn_skip = 1;
-+ continue;
-+ }
-+ if (entry->size) {
-+ if ((entry->size >= 1 << CRAMFS_SIZE_WIDTH)) {
-+ warn_size = 1;
-+ entry->size = (1 << CRAMFS_SIZE_WIDTH) - 1;
-+ }
-+
-+ entry->uncompressed = mmap(NULL, entry->size, PROT_READ, MAP_PRIVATE, fd, 0);
-+ if (-1 == (int) (long) entry->uncompressed) {
-+ perror("mmap");
-+ exit(8);
-+ }
-+ }
-+ close(fd);
-+ } else if (S_ISLNK(st.st_mode)) {
-+ entry->uncompressed = malloc(entry->size);
-+ if (!entry->uncompressed) {
-+ perror(NULL);
-+ exit(8);
-+ }
-+ if (readlink(path, entry->uncompressed, entry->size) < 0) {
-+ perror(path);
-+ warn_skip = 1;
-+ continue;
-+ }
-+ } else if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) {
-+ /* maybe we should skip sockets */
-+ entry->size = 0;
-+ } else {
-+ entry->size = st.st_rdev;
-+ if (entry->size & -(1<<CRAMFS_SIZE_WIDTH))
-+ warn_dev = 1;
-+ }
-+
-+ if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
-+ int blocks = ((entry->size - 1) / blksize + 1);
-+
-+ /* block pointers & data expansion allowance + data */
-+ if(entry->size)
-+ *fslen_ub += (4+26)*blocks + entry->size + 3;
-+ }
-+
-+ if (opt_xip && entry->mode & S_ISVTX) {
-+ /* worse case, depending on where the offsets falls,
-+ * a single XIP entry could expand the sizeof the
-+ * file system by 8k, since we're aligning the start
-+ * and end on page boundary.
-+ */
-+ *fslen_ub += 2*PAGE_CACHE_SIZE;
-+ }
-+
-+ /* Link it into the list */
-+ *prev = entry;
-+ prev = &entry->next;
-+ totalsize += size;
-+ }
-+ free(path);
-+ free(dirlist); /* allocated by scandir() with malloc() */
-+ return totalsize;
-+}
-+
-+/* Returns sizeof(struct cramfs_super), which includes the root inode. */
-+static unsigned int write_superblock(struct entry *root, char *base, int size)
-+{
-+ struct cramfs_super *super = (struct cramfs_super *) base;
-+ unsigned int offset = sizeof(struct cramfs_super) + image_length;
-+
-+ if (opt_pad) {
-+ offset += opt_pad;
-+ }
-+
-+ super->magic = CRAMFS_MAGIC;
-+ super->flags = CRAMFS_FLAG_FSID_VERSION_2 | CRAMFS_FLAG_SORTED_DIRS;
-+ if (opt_holes)
-+ super->flags |= CRAMFS_FLAG_HOLES;
-+ if (image_length > 0)
-+ super->flags |= CRAMFS_FLAG_SHIFTED_ROOT_OFFSET;
-+ super->size = size;
-+ memcpy(super->signature, CRAMFS_SIGNATURE, sizeof(super->signature));
-+
-+ super->fsid.crc = crc32(0L, Z_NULL, 0);
-+ super->fsid.edition = opt_edition;
-+ super->fsid.blocks = total_blocks;
-+ super->fsid.files = total_nodes;
-+
-+ memset(super->name, 0x00, sizeof(super->name));
-+ if (opt_name)
-+ strncpy(super->name, opt_name, sizeof(super->name));
-+ else
-+ strncpy(super->name, "Compressed", sizeof(super->name));
-+
-+ super->root.mode = root->mode;
-+ super->root.uid = root->uid;
-+ super->root.gid = root->gid;
-+ super->root.size = root->size;
-+ super->root.offset = offset >> 2;
-+
-+ return offset;
-+}
-+
-+static void set_data_offset(struct entry *entry, char *base, unsigned long offset)
-+{
-+ struct cramfs_inode *inode = (struct cramfs_inode *) (base + entry->dir_offset);
-+#ifdef DEBUG
-+ assert ((offset & 3) == 0);
-+#endif /* DEBUG */
-+ if (offset >= (1 << (2 + CRAMFS_OFFSET_WIDTH))) {
-+ fprintf(stderr, "filesystem too big. Exiting.\n");
-+ exit(8);
-+ }
-+ inode->offset = (offset >> 2);
-+}
-+
-+
-+/*
-+ * We do a width-first printout of the directory
-+ * entries, using a stack to remember the directories
-+ * we've seen.
-+ */
-+#define MAXENTRIES (100)
-+static unsigned int write_directory_structure(struct entry *entry, char *base, unsigned int offset)
-+{
-+ int stack_entries = 0;
-+ struct entry *entry_stack[MAXENTRIES];
-+
-+ for (;;) {
-+ int dir_start = stack_entries;
-+ while (entry) {
-+ struct cramfs_inode *inode = (struct cramfs_inode *) (base + offset);
-+ size_t len = strlen(entry->name);
-+
-+ entry->dir_offset = offset;
-+
-+ inode->mode = entry->mode;
-+ inode->uid = entry->uid;
-+ inode->gid = entry->gid;
-+ inode->size = entry->size;
-+ inode->offset = 0;
-+ /* Non-empty directories, regfiles and symlinks will
-+ write over inode->offset later. */
-+
-+ offset += sizeof(struct cramfs_inode);
-+ total_nodes++; /* another node */
-+ memcpy(base + offset, entry->name, len);
-+ /* Pad up the name to a 4-byte boundary */
-+ while (len & 3) {
-+ *(base + offset + len) = '\0';
-+ len++;
-+ }
-+ inode->namelen = len >> 2;
-+ offset += len;
-+
-+ /* TODO: this may get it wrong for chars >= 0x80.
-+ Most filesystems use UTF8 encoding for filenames,
-+ whereas the console is a single-byte character
-+ set like iso-latin-1. */
-+ printf(" %s\n", entry->name);
-+ if (entry->child) {
-+ if (stack_entries >= MAXENTRIES) {
-+ fprintf(stderr, "Exceeded MAXENTRIES. Raise this value in mkcramfs.c and recompile. Exiting.\n");
-+ exit(8);
-+ }
-+ entry_stack[stack_entries] = entry;
-+ stack_entries++;
-+ }
-+ entry = entry->next;
-+ }
-+
-+ /*
-+ * Reverse the order the stack entries pushed during
-+ * this directory, for a small optimization of disk
-+ * access in the created fs. This change makes things
-+ * `ls -UR' order.
-+ */
-+ {
-+ struct entry **lo = entry_stack + dir_start;
-+ struct entry **hi = entry_stack + stack_entries;
-+ struct entry *tmp;
-+
-+ while (lo < --hi) {
-+ tmp = *lo;
-+ *lo++ = *hi;
-+ *hi = tmp;
-+ }
-+ }
-+
-+ /* Pop a subdirectory entry from the stack, and recurse. */
-+ if (!stack_entries)
-+ break;
-+ stack_entries--;
-+ entry = entry_stack[stack_entries];
-+
-+ set_data_offset(entry, base, offset);
-+ printf("'%s':\n", entry->name);
-+ entry = entry->child;
-+ }
-+ return offset;
-+}
-+
-+static int is_zero(char const *begin, unsigned len)
-+{
-+ if (opt_holes)
-+ /* Returns non-zero iff the first LEN bytes from BEGIN are
-+ all NULs. */
-+ return (len-- == 0 ||
-+ (begin[0] == '\0' &&
-+ (len-- == 0 ||
-+ (begin[1] == '\0' &&
-+ (len-- == 0 ||
-+ (begin[2] == '\0' &&
-+ (len-- == 0 ||
-+ (begin[3] == '\0' &&
-+ memcmp(begin, begin + 4, len) == 0))))))));
-+ else
-+ /* Never create holes. */
-+ return 0;
-+}
-+
-+static unsigned int do_xip(char *base, unsigned int offset,
-+ char const *name, char *uncompressed,
-+ unsigned int size)
-+{
-+ unsigned int start, end;
-+
-+ /* align to page boundary */
-+
-+ start = ROM_ALIGN(offset);
-+ memset(base + offset, 0, start - offset);
-+
-+ memcpy(base + start, uncompressed, size);
-+
-+ /* pad to page boundary */
-+
-+ end = ROM_ALIGN(start + size);
-+ memset(base + start + size, 0, end - (start + size));
-+
-+ printf("XIP (%u+%u bytes)\toffset %u\t%s\n",
-+ size, (end - offset) - size, offset, name);
-+
-+ return end;
-+}
-+
-+/*
-+ * One 4-byte pointer per block and then the actual blocked
-+ * output. The first block does not need an offset pointer,
-+ * as it will start immediately after the pointer block;
-+ * so the i'th pointer points to the end of the i'th block
-+ * (i.e. the start of the (i+1)'th block or past EOF).
-+ *
-+ * Note that size > 0, as a zero-sized file wouldn't ever
-+ * have gotten here in the first place.
-+ */
-+static unsigned int do_compress(char *base, unsigned int offset, char const *name, char *uncompressed, unsigned int size)
-+{
-+ unsigned long original_size = size;
-+ unsigned long original_offset = offset;
-+ unsigned long new_size;
-+ unsigned long blocks = (size - 1) / blksize + 1;
-+ unsigned long curr = offset + 4 * blocks;
-+ int change;
-+
-+ total_blocks += blocks;
-+
-+ do {
-+ unsigned long len = 2 * blksize;
-+ unsigned int input = size;
-+ if (input > blksize)
-+ input = blksize;
-+ size -= input;
-+ if (!is_zero (uncompressed, input)) {
-+ compress(base + curr, &len, uncompressed, input);
-+ curr += len;
-+ }
-+ uncompressed += input;
-+
-+ if (len > blksize*2) {
-+ /* (I don't think this can happen with zlib.) */
-+ printf("AIEEE: block \"compressed\" to > 2*blocklength (%ld)\n", len);
-+ exit(8);
-+ }
-+
-+ *(u32 *) (base + offset) = curr;
-+ offset += 4;
-+ } while (size);
-+
-+ curr = (curr + 3) & ~3;
-+ new_size = curr - original_offset;
-+ /* TODO: Arguably, original_size in these 2 lines should be
-+ st_blocks * 512. But if you say that then perhaps
-+ administrative data should also be included in both. */
-+ change = new_size - original_size;
-+ printf("%6.2f%% (%+d bytes)\toffset %lu\t%s\n",
-+ (change * 100) / (double) original_size, change, original_offset, name);
-+
-+ return curr;
-+}
-+
-+
-+/*
-+ * Traverse the entry tree, writing data for every item that has
-+ * non-null entry->compressed (i.e. every symlink and non-empty
-+ * regfile).
-+ */
-+static unsigned int write_data(struct entry *entry, char *base, unsigned int offset)
-+{
-+ do {
-+ if (entry->uncompressed) {
-+ if(entry->same) {
-+ set_data_offset(entry, base, entry->same->offset);
-+ entry->offset=entry->same->offset;
-+ } else {
-+ set_data_offset(entry, base, offset);
-+ entry->offset=offset;
-+ if (opt_xip && entry->mode & S_ISVTX)
-+ offset = do_xip(base, offset, entry->name, entry->uncompressed, entry->size);
-+ else
-+ offset = do_compress(base, offset, entry->name, entry->uncompressed, entry->size);
-+ }
-+ }
-+ else if (entry->child)
-+ offset = write_data(entry->child, base, offset);
-+ entry=entry->next;
-+ } while (entry);
-+ return offset;
-+}
-+
-+static unsigned int write_file(char *file, char *base, unsigned int offset)
-+{
-+ int fd;
-+ char *buf;
-+
-+ fd = open(file, O_RDONLY);
-+ if (fd < 0) {
-+ perror(file);
-+ exit(8);
-+ }
-+ buf = mmap(NULL, image_length, PROT_READ, MAP_PRIVATE, fd, 0);
-+ memcpy(base + offset, buf, image_length);
-+ munmap(buf, image_length);
-+ close (fd);
-+ /* Pad up the image_length to a 4-byte boundary */
-+ while (image_length & 3) {
-+ *(base + offset + image_length) = '\0';
-+ image_length++;
-+ }
-+ return (offset + image_length);
-+}
-+
-+/*
-+ * Maximum size fs you can create is roughly 256MB. (The last file's
-+ * data must begin within 256MB boundary but can extend beyond that.)
-+ *
-+ * Note that if you want it to fit in a ROM then you're limited to what the
-+ * hardware and kernel can support (64MB?).
-+ */
-+#define MAXFSLEN ((((1 << CRAMFS_OFFSET_WIDTH) - 1) << 2) /* offset */ \
-+ + (1 << CRAMFS_SIZE_WIDTH) - 1 /* filesize */ \
-+ + (1 << CRAMFS_SIZE_WIDTH) * 4 / PAGE_CACHE_SIZE /* block pointers */ )
-+
-+
-+/*
-+ * Usage:
-+ *
-+ * mkcramfs directory-name outfile
-+ *
-+ * where "directory-name" is simply the root of the directory
-+ * tree that we want to generate a compressed filesystem out
-+ * of.
-+ */
-+int main(int argc, char **argv)
-+{
-+ struct stat st; /* used twice... */
-+ struct entry *root_entry;
-+ char *rom_image;
-+ ssize_t offset, written;
-+ int fd;
-+ /* initial guess (upper-bound) of required filesystem size */
-+ loff_t fslen_ub = sizeof(struct cramfs_super);
-+ char const *dirname, *outfile;
-+ u32 crc = crc32(0L, Z_NULL, 0);
-+ int c; /* for getopt */
-+
-+ total_blocks = 0;
-+
-+ if (argc)
-+ progname = argv[0];
-+
-+ /* command line options */
-+ while ((c = getopt(argc, argv, "hEe:i:n:psxz")) != EOF) {
-+ switch (c) {
-+ case 'h':
-+ usage(0);
-+ case 'E':
-+ opt_errors = 1;
-+ break;
-+ case 'e':
-+ opt_edition = atoi(optarg);
-+ break;
-+ case 'i':
-+ opt_image = optarg;
-+ if (lstat(opt_image, &st) < 0) {
-+ perror(opt_image);
-+ exit(16);
-+ }
-+ image_length = st.st_size; /* may be padded later */
-+ fslen_ub += (image_length + 3); /* 3 is for padding */
-+ break;
-+ case 'n':
-+ opt_name = optarg;
-+ break;
-+ case 'p':
-+ opt_pad = PAD_SIZE;
-+ fslen_ub += PAD_SIZE;
-+ break;
-+ case 's':
-+ /* old option, ignored */
-+ break;
-+ case 'x':
-+ opt_xip = 1;
-+ break;
-+ case 'z':
-+ opt_holes = 1;
-+ break;
-+ }
-+ }
-+
-+ if ((argc - optind) != 2)
-+ usage(16);
-+ dirname = argv[optind];
-+ outfile = argv[optind + 1];
-+
-+ if (stat(dirname, &st) < 0) {
-+ perror(dirname);
-+ exit(16);
-+ }
-+ fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666);
-+
-+ root_entry = calloc(1, sizeof(struct entry));
-+ if (!root_entry) {
-+ perror(NULL);
-+ exit(8);
-+ }
-+ root_entry->mode = st.st_mode;
-+ root_entry->uid = st.st_uid;
-+ root_entry->gid = st.st_gid;
-+
-+ root_entry->size = parse_directory(root_entry, dirname, &root_entry->child, &fslen_ub);
-+
-+ /* always allocate a multiple of blksize bytes because that's
-+ what we're going to write later on */
-+ fslen_ub = ((fslen_ub - 1) | (blksize - 1)) + 1;
-+
-+ if (fslen_ub > MAXFSLEN) {
-+ fprintf(stderr,
-+ "warning: guestimate of required size (upper bound) is %LdMB, but maximum image size is %uMB. We might die prematurely.\n",
-+ fslen_ub >> 20,
-+ MAXFSLEN >> 20);
-+ fslen_ub = MAXFSLEN;
-+ }
-+
-+ /* find duplicate files. TODO: uses the most inefficient algorithm
-+ possible. */
-+ eliminate_doubles(root_entry,root_entry);
-+
-+ /* TODO: Why do we use a private/anonymous mapping here
-+ followed by a write below, instead of just a shared mapping
-+ and a couple of ftruncate calls? Is it just to save us
-+ having to deal with removing the file afterwards? If we
-+ really need this huge anonymous mapping, we ought to mmap
-+ in smaller chunks, so that the user doesn't need nn MB of
-+ RAM free. If the reason is to be able to write to
-+ un-mmappable block devices, then we could try shared mmap
-+ and revert to anonymous mmap if the shared mmap fails. */
-+ rom_image = mmap(NULL, fslen_ub?fslen_ub:1, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-+
-+ if (-1 == (int) (long) rom_image) {
-+ perror("ROM image map");
-+ exit(8);
-+ }
-+
-+ /* Skip the first opt_pad bytes for boot loader code */
-+ offset = opt_pad;
-+ memset(rom_image, 0x00, opt_pad);
-+
-+ /* Skip the superblock and come back to write it later. */
-+ offset += sizeof(struct cramfs_super);
-+
-+ /* Insert a file image. */
-+ if (opt_image) {
-+ printf("Including: %s\n", opt_image);
-+ offset = write_file(opt_image, rom_image, offset);
-+ }
-+
-+ offset = write_directory_structure(root_entry->child, rom_image, offset);
-+ printf("Directory data: %d bytes\n", offset);
-+
-+ offset = write_data(root_entry, rom_image, offset);
-+
-+ /* We always write a multiple of blksize bytes, so that
-+ losetup works. */
-+ offset = ((offset - 1) | (blksize - 1)) + 1;
-+ printf("Everything: %d kilobytes\n", offset >> 10);
-+
-+ /* Write the superblock now that we can fill in all of the fields. */
-+ write_superblock(root_entry, rom_image+opt_pad, offset);
-+ printf("Super block: %d bytes\n", sizeof(struct cramfs_super));
-+
-+ /* Put the checksum in. */
-+ crc = crc32(crc, (rom_image+opt_pad), (offset-opt_pad));
-+ ((struct cramfs_super *) (rom_image+opt_pad))->fsid.crc = crc;
-+ printf("CRC: %x\n", crc);
-+
-+ /* Check to make sure we allocated enough space. */
-+ if (fslen_ub < offset) {
-+ fprintf(stderr, "not enough space allocated for ROM image (%Ld allocated, %d used)\n",
-+ fslen_ub, offset);
-+ exit(8);
-+ }
-+
-+ written = write(fd, rom_image, offset);
-+ if (written < 0) {
-+ perror("ROM image");
-+ exit(8);
-+ }
-+ if (offset != written) {
-+ fprintf(stderr, "ROM image write failed (%d %d)\n", written, offset);
-+ exit(8);
-+ }
-+
-+ /* (These warnings used to come at the start, but they scroll off the
-+ screen too quickly.) */
-+ if (warn_namelen) /* (can't happen when reading from ext2fs) */
-+ fprintf(stderr, /* bytes, not chars: think UTF8. */
-+ "warning: filenames truncated to 255 bytes.\n");
-+ if (warn_skip)
-+ fprintf(stderr, "warning: files were skipped due to errors.\n");
-+ if (warn_size)
-+ fprintf(stderr,
-+ "warning: file sizes truncated to %luMB (minus 1 byte).\n",
-+ 1L << (CRAMFS_SIZE_WIDTH - 20));
-+ if (warn_uid) /* (not possible with current Linux versions) */
-+ fprintf(stderr,
-+ "warning: uids truncated to %u bits. (This may be a security concern.)\n",
-+ CRAMFS_UID_WIDTH);
-+ if (warn_gid)
-+ fprintf(stderr,
-+ "warning: gids truncated to %u bits. (This may be a security concern.)\n",
-+ CRAMFS_GID_WIDTH);
-+ if (warn_dev)
-+ fprintf(stderr,
-+ "WARNING: device numbers truncated to %u bits. This almost certainly means\n"
-+ "that some device files will be wrong.\n",
-+ CRAMFS_OFFSET_WIDTH);
-+ if (opt_errors &&
-+ (warn_namelen||warn_skip||warn_size||warn_uid||warn_gid||warn_dev))
-+ exit(8);
-+ return 0;
-+}
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/bitfield.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,113 @@
-+/*
-+ * FILE bitfield.h
-+ *
-+ * Version 1.1
-+ * Author Copyright (c) Marc A. Viredaz, 1998
-+ * DEC Western Research Laboratory, Palo Alto, CA
-+ * Date April 1998 (April 1997)
-+ * System Advanced RISC Machine (ARM)
-+ * Language C or ARM Assembly
-+ * Purpose Definition of macros to operate on bit fields.
-+ */
-+
-+
-+
-+#ifndef __BITFIELD_H
-+#define __BITFIELD_H
-+
-+#ifndef __ASSEMBLY__
-+#define UData(Data) ((unsigned long) (Data))
-+#else
-+#define UData(Data) (Data)
-+#endif
-+
-+
-+/*
-+ * MACRO: Fld
-+ *
-+ * Purpose
-+ * The macro "Fld" encodes a bit field, given its size and its shift value
-+ * with respect to bit 0.
-+ *
-+ * Note
-+ * A more intuitive way to encode bit fields would have been to use their
-+ * mask. However, extracting size and shift value information from a bit
-+ * field's mask is cumbersome and might break the assembler (255-character
-+ * line-size limit).
-+ *
-+ * Input
-+ * Size Size of the bit field, in number of bits.
-+ * Shft Shift value of the bit field with respect to bit 0.
-+ *
-+ * Output
-+ * Fld Encoded bit field.
-+ */
-+
-+#define Fld(Size, Shft) (((Size) << 16) + (Shft))
-+
-+
-+/*
-+ * MACROS: FSize, FShft, FMsk, FAlnMsk, F1stBit
-+ *
-+ * Purpose
-+ * The macros "FSize", "FShft", "FMsk", "FAlnMsk", and "F1stBit" return
-+ * the size, shift value, mask, aligned mask, and first bit of a
-+ * bit field.
-+ *
-+ * Input
-+ * Field Encoded bit field (using the macro "Fld").
-+ *
-+ * Output
-+ * FSize Size of the bit field, in number of bits.
-+ * FShft Shift value of the bit field with respect to bit 0.
-+ * FMsk Mask for the bit field.
-+ * FAlnMsk Mask for the bit field, aligned on bit 0.
-+ * F1stBit First bit of the bit field.
-+ */
-+
-+#define FSize(Field) ((Field) >> 16)
-+#define FShft(Field) ((Field) & 0x0000FFFF)
-+#define FMsk(Field) (((UData (1) << FSize (Field)) - 1) << FShft (Field))
-+#define FAlnMsk(Field) ((UData (1) << FSize (Field)) - 1)
-+#define F1stBit(Field) (UData (1) << FShft (Field))
-+
-+
-+/*
-+ * MACRO: FInsrt
-+ *
-+ * Purpose
-+ * The macro "FInsrt" inserts a value into a bit field by shifting the
-+ * former appropriately.
-+ *
-+ * Input
-+ * Value Bit-field value.
-+ * Field Encoded bit field (using the macro "Fld").
-+ *
-+ * Output
-+ * FInsrt Bit-field value positioned appropriately.
-+ */
-+
-+#define FInsrt(Value, Field) \
-+ (UData (Value) << FShft (Field))
-+
-+
-+/*
-+ * MACRO: FExtr
-+ *
-+ * Purpose
-+ * The macro "FExtr" extracts the value of a bit field by masking and
-+ * shifting it appropriately.
-+ *
-+ * Input
-+ * Data Data containing the bit-field to be extracted.
-+ * Field Encoded bit field (using the macro "Fld").
-+ *
-+ * Output
-+ * FExtr Bit-field value.
-+ */
-+
-+#define FExtr(Data, Field) \
-+ ((UData (Data) >> FShft (Field)) & FAlnMsk (Field))
-+
-+
-+#endif /* __BITFIELD_H */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/cerf.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,177 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/cerf.h
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+/*
-+ * Add CerfBoard Specifics here...
-+ */
-+
-+/*
-+ * Memory sizes
-+ */
-+
-+#define CERF_RAM_BASE 0xa0000000
-+
-+#ifdef CONFIG_PXA_CERF_RAM_128MB
-+#define CERF_RAM_SIZE 128*1024*1024
-+
-+#elif defined (CONFIG_PXA_CERF_RAM_64MB)
-+#define CERF_RAM_SIZE 64*1024*1024
-+
-+#elif defined (CONFIG_PXA_CERF_RAM_32MB)
-+#define CERF_RAM_SIZE 32*1024*1024
-+
-+#elif defined (CONFIG_PXA_CERF_RAM_16MB)
-+#define CERF_RAM_SIZE 16*1024*1024
-+#endif
-+
-+/*
-+ * CS memory timing via Static Memory Control Register (MSC0-2)
-+ */
-+
-+#define MSC_CS(cs,val) ((val)<<((cs&1)<<4))
-+
-+#define MSC_RBUFF_SHIFT 15
-+#define MSC_RBUFF_SLOW (0)
-+#define MSC_RBUFF_FAST (1)
-+#define MSC_RBUFF(x) ((x)<<MSC_RBUFF_SHIFT)
-+
-+#define MSC_RRR_SHIFT 12
-+#define MSC_RRR(x) ((x)<<MSC_RRR_SHIFT)
-+
-+#define MSC_RDN_SHIFT 8
-+#define MSC_RDN(x) ((x)<<MSC_RDN_SHIFT)
-+
-+#define MSC_RDF_SHIFT 4
-+#define MSC_RDF(x) ((x)<<MSC_RDF_SHIFT)
-+
-+#define MSC_RBW_SHIFT 3
-+#define MSC_RBW(x) ((x)<<MSC_RBW_SHIFT)
-+
-+#define MSC_RT_SHIFT 0
-+#define MSC_RT(x) ((x)<<MSC_RT_SHIFT)
-+
-+/*
-+ * IO Pins for devices
-+ */
-+
-+#define CERF_FLASH_BASE 0xe8000000
-+#define CERF_FLASH_SIZE 0x02000000
-+#define CERF_FLASH_PHYS PXA_CS0_PHYS
-+
-+#define CERF_ETH_BASE 0xf0000000
-+#define CERF_ETH_SIZE 0x00100000
-+#define CERF_ETH_PHYS PXA_CS1_PHYS
-+
-+#define CERF_BT_BASE 0xf2000000
-+#define CERF_BT_SIZE 0x00100000
-+#define CERF_BT_PHYS PXA_CS2_PHYS
-+
-+#define CERF_SERIAL_BASE 0xf3000000
-+#define CERF_SERIAL_SIZE 0x00100000
-+#define CERF_SERIAL_PHYS PXA_CS3_PHYS
-+
-+#define CERF_CPLD_BASE 0xf1000000
-+#define CERF_CPLD_SIZE 0x00100000
-+#define CERF_CPLD_PHYS PXA_CS4_PHYS
-+
-+#define CERF_PDA_CPLD_WRCLRINT (0x0)
-+#define CERF_PDA_CPLD_BRIGHTNESS (0x2)
-+#define CERF_PDA_CPLD_KEYPAD_A (0x6)
-+#define CERF_PDA_CPLD_BATTFAULT (0x8)
-+#define CERF_PDA_CPLD_KEYPAD_B (0xa)
-+#define CERF_PDA_CPLD_SOUND_ENA (0xc)
-+
-+#define CERF_PDA_SOUND_ENABLE 0x1
-+#define CERF_PDA_DEFAULT_BRIGHTNESS 0x9
-+
-+/*
-+ * Access functions (registers are 4-bit wide)
-+ */
-+
-+#define CERF_PDA_CPLD CERF_CPLD_BASE
-+
-+#define CERF_PDA_CPLD_Get(x, y) (*((char*)(CERF_PDA_CPLD + (x))) & (y))
-+#define CERF_PDA_CPLD_Set(x, y, z) (*((char*)(CERF_PDA_CPLD + (x))) = (*((char*)(CERF_PDA_CPLD + (x))) & ~(z)) | (y))
-+#define CERF_PDA_CPLD_UnSet(x, y, z) (*((char*)(CERF_PDA_CPLD + (x))) = (*((char*)(CERF_PDA_CPLD + (x))) & ~(z)) & ~(y))
-+
-+/*
-+ * IO and IRQ settings for cs8900 ethernet chip
-+ */
-+#define CERF_ETH_IO CERF_ETH_BASE
-+#define CERF_ETH_IRQ GPIO_2_80_TO_IRQ(21)
-+
-+/*
-+ * We only have one LED on the XScale CerfPDA so only the
-+ * time or idle should ever be selected.
-+ */
-+#define CERF_HEARTBEAT_LED 0x1
-+#define CERF_SYS_BUSY_LED 0x2
-+
-+#define CERF_HEARTBEAT_LED_GPIO 16 // GPIO 4
-+#define CERF_SYS_BUSY_LED_GPIO 16 // GPIO 4
-+
-+#define CERF_HEARTBEAT_LED_ON (GPSR0 = CERF_HEARTBEAT_LED_GPIO)
-+#define CERF_HEARTBEAT_LED_OFF (GPCR0 = CERF_HEARTBEAT_LED_GPIO)
-+#define CERF_SYS_BUSY_LED_ON (GPSR0 = CERF_SYS_BUSY_LED_GPIO)
-+#define CERF_SYS_BUSY_LED_OFF (GPCR0 = CERF_SYS_BUSY_LED_GPIO)
-+
-+/*
-+ * UCB 1400 gpio
-+ */
-+
-+#define CERF_GPIO_UCB1400_IRQ 32
-+
-+#define UCB_IO_0 (1 << 0)
-+#define UCB_IO_1 (1 << 1)
-+#define UCB_IO_2 (1 << 2)
-+#define UCB_IO_3 (1 << 3)
-+#define UCB_IO_4 (1 << 4)
-+#define UCB_IO_5 (1 << 5)
-+#define UCB_IO_6 (1 << 6)
-+#define UCB_IO_7 (1 << 7)
-+#define UCB_IO_8 (1 << 8)
-+#define UCB_IO_9 (1 << 9)
-+
-+#define UCB1400_GPIO_CONT_CS UCB_IO_0
-+#define UCB1400_GPIO_CONT_DOWN UCB_IO_1
-+#define UCB1400_GPIO_CONT_INC UCB_IO_2
-+#define UCB1400_GPIO_CONT_ENA UCB_IO_3
-+#define UCB1400_GPIO_LCD_RESET UCB_IO_4
-+#define UCB1400_GPIO_IRDA_ENABLE UCB_IO_5
-+#define UCB1400_GPIO_BT_ENABLE UCB_IO_6
-+#define UCB1400_GPIO_TEST_P1 UCB_IO_7
-+#define UCB1400_GPIO_TEST_P2 UCB_IO_8
-+#define UCB1400_GPIO_TEST_P3 UCB_IO_9
-+
-+/*
-+ * IRQ for devices
-+ */
-+#define UCB1400_IRQ(x) (NR_IRQS + 1 + (x))
-+
-+#define IRQ_UCB1400_IO0 UCB1400_IRQ(0)
-+#define IRQ_UCB1400_IO1 UCB1400_IRQ(1)
-+#define IRQ_UCB1400_IO2 UCB1400_IRQ(2)
-+#define IRQ_UCB1400_IO3 UCB1400_IRQ(3)
-+#define IRQ_UCB1400_IO4 UCB1400_IRQ(4)
-+#define IRQ_UCB1400_IO5 UCB1400_IRQ(5)
-+#define IRQ_UCB1400_IO6 UCB1400_IRQ(6)
-+#define IRQ_UCB1400_IO7 UCB1400_IRQ(7)
-+#define IRQ_UCB1400_IO8 UCB1400_IRQ(8)
-+#define IRQ_UCB1400_IO9 UCB1400_IRQ(9)
-+
-+#define IRQ_UCB1400_CONT_CS IRQ_UCB1400_IO0
-+#define IRQ_UCB1400_CONT_DOWN IRQ_UCB1400_IO1
-+#define IRQ_UCB1400_CONT_INC IRQ_UCB1400_IO2
-+#define IRQ_UCB1400_CONT_ENA IRQ_UCB1400_IO3
-+#define IRQ_UCB1400_LCD_RESET IRQ_UCB1400_IO4
-+#define IRQ_UCB1400_IRDA_ENABLE IRQ_UCB1400_IO5
-+#define IRQ_UCB1400_BT_ENABLE IRQ_UCB1400_IO6
-+#define IRQ_UCB1400_TEST_P1 IRQ_UCB1400_IO7
-+#define IRQ_UCB1400_TEST_P2 IRQ_UCB1400_IO8
-+#define IRQ_UCB1400_TEST_P3 IRQ_UCB1400_IO9
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/cerf_ucb1400gpio.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,30 @@
-+/*
-+ * cerf_ucb1400gpio.h
-+ *
-+ * UCB1400 GPIO control stuff for the cerf.
-+ *
-+ * Copyright (C) 2002 Intrinsyc Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * History:
-+ * Mar 2002: Initial version [FB]
-+ *
-+ */
-+/* -- lcd -- */
-+extern void cerf_ucb1400gpio_lcd_enable( void);
-+extern void cerf_ucb1400gpio_lcd_disable( void);
-+extern void cerf_ucb1400gpio_lcd_contrast_step( int direction);
-+
-+/* -- irda -- */
-+extern void cerf_ucb1400gpio_irda_enable( void);
-+extern void cerf_ucb1400gpio_irda_disable( void);
-+
-+/* -- bt -- */
-+extern void cerf_ucb1400gpio_bt_enable( void);
-+extern void cerf_ucb1400gpio_bt_disable( void);
-+
-+/* -- init -- */
-+extern int cerf_ucb1400gpio_init(void);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/csb226.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,99 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/csb226.h
-+ *
-+ * Author: Robert Schwebel (stolen from lubbock.h)
-+ * Created: Oct 30, 2002
-+ * Copyright: Pengutronix
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#define CSB226_FPGA_PHYS PXA_CS2_PHYS
-+
-+#define CSB226_FPGA_VIRT (0xf0000000) /* phys 0x08000000 */
-+#define CSB226_ETH_BASE (0xf1000000) /* phys 0x0c000000 */
-+
-+#define CSB226_P2V(x) ((x) - CSB226_FPGA_PHYS + CSB226_FPGA_VIRT)
-+#define CSB226_V2P(x) ((x) - CSB226_FPGA_VIRT + CSB226_FPGA_PHYS)
-+
-+#ifndef __ASSEMBLY__
-+# define __CSB226_REG(x) (*((volatile unsigned long *)CSB226_P2V(x)))
-+#else
-+# define __CSB226_REG(x) CSB226_P2V(x)
-+#endif
-+
-+
-+/* register physical addresses */
-+#define _CSB226_MISC_WR (CSB226_FPGA_PHYS + 0x080)
-+#define _CSB226_MISC_RD (CSB226_FPGA_PHYS + 0x090)
-+#define _CSB226_IRQ_MASK_EN (CSB226_FPGA_PHYS + 0x0C0)
-+#define _CSB226_IRQ_SET_CLR (CSB226_FPGA_PHYS + 0x0D0)
-+#define _CSB226_GP (CSB226_FPGA_PHYS + 0x100)
-+
-+
-+
-+/* register virtual addresses */
-+
-+#define CSB226_MISC_WR __CSB226_REG(_CSB226_MISC_WR)
-+#define CSB226_MISC_RD __CSB226_REG(_CSB226_MISC_RD)
-+#define CSB226_IRQ_MASK_EN __CSB226_REG(_CSB226_IRQ_MASK_EN)
-+#define CSB226_IRQ_SET_CLR __CSB226_REG(_CSB226_IRQ_SET_CLR)
-+#define CSB226_GP __CSB226_REG(_CSB226_GP)
-+
-+
-+/* GPIOs */
-+
-+#define GPIO_CSB226_IRQ 0
-+#define IRQ_GPIO_CSB226_IRQ IRQ_GPIO0
-+
-+
-+/*
-+ * LED macros
-+ */
-+
-+// #define LEDS_BASE LUB_DISC_BLNK_LED
-+
-+// 8 discrete leds available for general use:
-+
-+/*
-+#define D28 0x1
-+#define D27 0x2
-+#define D26 0x4
-+#define D25 0x8
-+#define D24 0x10
-+#define D23 0x20
-+#define D22 0x40
-+#define D21 0x80
-+*/
-+
-+/* Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays so
-+* be sure to not monkey with them here.
-+*/
-+
-+/*
-+#define HEARTBEAT_LED D28
-+#define SYS_BUSY_LED D27
-+#define HEXLEDS_BASE LUB_HEXLED
-+
-+#define HEARTBEAT_LED_ON (LEDS_BASE &= ~HEARTBEAT_LED)
-+#define HEARTBEAT_LED_OFF (LEDS_BASE |= HEARTBEAT_LED)
-+#define SYS_BUSY_LED_OFF (LEDS_BASE |= SYS_BUSY_LED)
-+#define SYS_BUSY_LED_ON (LEDS_BASE &= ~SYS_BUSY_LED)
-+
-+// use x = D26-D21 for these, please...
-+#define DISCRETE_LED_ON(x) (LEDS_BASE &= ~(x))
-+#define DISCRETE_LED_OFF(x) (LEDS_BASE |= (x))
-+*/
-+
-+#ifndef __ASSEMBLY__
-+
-+//extern int hexled_val = 0;
-+
-+#endif
-+
-+/*
-+#define BUMP_COUNTER (HEXLEDS_BASE = hexled_val++)
-+#define DEC_COUNTER (HEXLEDS_BASE = hexled_val--)
-+*/
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/dma.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,49 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/dma.h
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Jun 15, 2001
-+ * Copyright: MontaVista Software, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#ifndef __ASM_ARCH_DMA_H
-+#define __ASM_ARCH_DMA_H
-+
-+#define MAX_DMA_ADDRESS 0xffffffff
-+
-+/* No DMA as the rest of the world see it */
-+#define MAX_DMA_CHANNELS 0
-+
-+/*
-+ * Descriptor structure for PXA's DMA engine
-+ * Note: this structure must always be aligned to a 16-byte boundary.
-+ */
-+
-+typedef struct {
-+ volatile u32 ddadr; /* Points to the next descriptor + flags */
-+ volatile u32 dsadr; /* DSADR value for the current transfer */
-+ volatile u32 dtadr; /* DTADR value for the current transfer */
-+ volatile u32 dcmd; /* DCMD value for the current transfer */
-+} pxa_dma_desc;
-+
-+/*
-+ * DMA registration
-+ */
-+
-+typedef enum {
-+ DMA_PRIO_HIGH = 0,
-+ DMA_PRIO_MEDIUM = 4,
-+ DMA_PRIO_LOW = 8
-+} pxa_dma_prio;
-+
-+int pxa_request_dma (char *name,
-+ pxa_dma_prio prio,
-+ void (*irq_handler)(int, void *, struct pt_regs *),
-+ void *data);
-+
-+void pxa_free_dma (int dma_ch);
-+
-+#endif /* _ASM_ARCH_DMA_H */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/hardware.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,142 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/hardware.h
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Jun 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#ifndef __ASM_ARCH_HARDWARE_H
-+#define __ASM_ARCH_HARDWARE_H
-+
-+#include <linux/config.h>
-+#include <asm/mach-types.h>
-+
-+
-+/*
-+ * These are statically mapped PCMCIA IO space for designs using it as a
-+ * generic IO bus, typically with ISA parts, hardwired IDE interfaces, etc.
-+ * The actual PCMCIA code is mapping required IO region at run time.
-+ */
-+#define PCMCIA_IO_0_BASE 0xf6000000
-+#define PCMCIA_IO_1_BASE 0xf7000000
-+
-+
-+/*
-+ * XIP kernel text mapping.
-+ * Note: the exact virtual address is also specified in arch/arm/Makefile.
-+ */
-+#ifdef CONFIG_XIP_KERNEL
-+#define KERNEL_XIP_BASE_PHYS (CONFIG_XIP_PHYS_ADDR & 0xffe00000)
-+#define KERNEL_XIP_BASE_VIRT 0xe8000000
-+#endif
-+
-+
-+/*
-+ * We requires absolute addresses.
-+ */
-+#define PCIO_BASE 0
-+
-+/*
-+ * Workarounds for at least 2 errata so far require this.
-+ * The mapping is set in mach-pxa/generic.c.
-+ */
-+#define UNCACHED_PHYS_0 0xff000000
-+#define UNCACHED_ADDR UNCACHED_PHYS_0
-+
-+/*
-+ * Intel PXA internal I/O mappings:
-+ *
-+ * 0x40000000 - 0x41ffffff <--> 0xf8000000 - 0xf9ffffff
-+ * 0x44000000 - 0x45ffffff <--> 0xfa000000 - 0xfbffffff
-+ * 0x48000000 - 0x49ffffff <--> 0xfc000000 - 0xfdffffff
-+ */
-+
-+#define io_p2v(x) ( ((x) | 0xbe000000) ^ (~((x) >> 1) & 0x06000000) )
-+#define io_v2p( x ) ( ((x) & 0x41ffffff) ^ ( ((x) & 0x06000000) << 1) )
-+
-+#ifndef __ASSEMBLY__
-+
-+#if 0
-+# define __REG(x) (*((volatile u32 *)io_p2v(x)))
-+#else
-+/*
-+ * This __REG() version gives the same results as the one above, except
-+ * that we are fooling gcc somehow so it generates far better and smaller
-+ * assembly code for access to contigous registers. It's a shame that gcc
-+ * doesn't guess this by itself.
-+ */
-+#include <asm/types.h>
-+typedef struct { volatile u32 offset[4096]; } __regbase;
-+# define __REGP(x) ((__regbase *)((x)&~4095))->offset[((x)&4095)>>2]
-+# define __REG(x) __REGP(io_p2v(x))
-+#endif
-+
-+/* Let's kick gcc's ass again... */
-+# define __REG2(x,y) \
-+ ( __builtin_constant_p(y) ? (__REG((x) + (y))) \
-+ : (*(volatile u32 *)((u32)&__REG(x) + (y))) )
-+
-+# define __PREG(x) (io_v2p((u32)&(x)))
-+
-+#else
-+
-+# define __REG(x) io_p2v(x)
-+# define __PREG(x) io_v2p(x)
-+
-+#endif
-+
-+#include "pxa-regs.h"
-+
-+#ifndef __ASSEMBLY__
-+
-+/*
-+ * GPIO edge detection for IRQs:
-+ * IRQs are generated on Falling-Edge, Rising-Edge, or both.
-+ * This must be called *before* the corresponding IRQ is registered.
-+ * Use this instead of directly setting GRER/GFER.
-+ */
-+#define GPIO_FALLING_EDGE 1
-+#define GPIO_RISING_EDGE 2
-+#define GPIO_BOTH_EDGES 3
-+extern void set_GPIO_IRQ_edge( int gpio_nr, int edge_mask );
-+
-+/*
-+ * Handy routine to set GPIO alternate functions
-+ */
-+extern void set_GPIO_mode( int gpio_mode );
-+
-+/*
-+ * return current lclk frequency in units of 10kHz
-+ */
-+extern unsigned int get_lclk_frequency_10khz(void);
-+
-+/*
-+ * return current clk frequency in units of 1kHz
-+ */
-+extern unsigned int get_clk_frequency_khz( int info);
-+
-+#endif
-+
-+
-+/*
-+ * Implementation specifics
-+ */
-+
-+//#ifdef CONFIG_ARCH_LUBBOCK
-+#include "lubbock.h"
-+//#endif
-+
-+//#ifdef CONFIG_ARCH_PXA_IDP
-+#include "idp.h"
-+//#endif
-+
-+//#ifdef CONFIG_ARCH_PXA_CERF
-+#include "cerf.h"
-+//#endif
-+
-+#endif /* _ASM_ARCH_HARDWARE_H */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/ide.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,59 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/ide.h
-+ *
-+ * Author: George Davis
-+ * Created: Jan 10, 2002
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ *
-+ * Originally based upon linux/include/asm-arm/arch-sa1100/ide.h
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <asm/irq.h>
-+#include <asm/hardware.h>
-+#include <asm/mach-types.h>
-+
-+
-+/*
-+ * Set up a hw structure for a specified data port, control port and IRQ.
-+ * This should follow whatever the default interface uses.
-+ */
-+static __inline__ void
-+ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port, int *irq)
-+{
-+ ide_ioreg_t reg;
-+
-+ memset(hw, 0, sizeof(*hw));
-+
-+ reg = (ide_ioreg_t)data_port;
-+
-+ hw->io_ports[IDE_DATA_OFFSET] = reg + 0;
-+ hw->io_ports[IDE_ERROR_OFFSET] = reg + 1;
-+ hw->io_ports[IDE_NSECTOR_OFFSET] = reg + 2;
-+ hw->io_ports[IDE_SECTOR_OFFSET] = reg + 3;
-+ hw->io_ports[IDE_LCYL_OFFSET] = reg + 4;
-+ hw->io_ports[IDE_HCYL_OFFSET] = reg + 5;
-+ hw->io_ports[IDE_SELECT_OFFSET] = reg + 6;
-+ hw->io_ports[IDE_STATUS_OFFSET] = reg + 7;
-+
-+ hw->io_ports[IDE_CONTROL_OFFSET] = (ide_ioreg_t) ctrl_port;
-+
-+ if (irq)
-+ *irq = 0;
-+}
-+
-+
-+/*
-+ * Register the standard ports for this architecture with the IDE driver.
-+ */
-+static __inline__ void
-+ide_init_default_hwifs(void)
-+{
-+ /* Nothing to declare... */
-+}
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/idp.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,468 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/idp.h
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Copyright (c) 2001 Cliff Brake, Accelent Systems Inc.
-+ *
-+ * 2001-09-13: Cliff Brake <cbrake@accelent.com>
-+ * Initial code
-+ *
-+ */
-+
-+
-+/*
-+ * Note: this file must be safe to include in assembly files
-+ */
-+
-+/* comment out following if you have a rev01 board */
-+#define PXA_IDP_REV02 1
-+//#undef PXA_IDP_REV02
-+
-+#ifdef PXA_IDP_REV02
-+
-+//Use this as well for 0017-x004 and greater pcb's:
-+#define PXA_IDP_REV04 1
-+
-+#define IDP_FLASH_PHYS (PXA_CS0_PHYS)
-+#define IDP_ALT_FLASH_PHYS (PXA_CS1_PHYS)
-+#define IDP_MEDIAQ_PHYS (PXA_CS3_PHYS)
-+#define IDP_IDE_PHYS (PXA_CS5_PHYS + 0x03000000)
-+#define IDP_ETH_PHYS (PXA_CS5_PHYS + 0x03400000)
-+#define IDP_COREVOLT_PHYS (PXA_CS5_PHYS + 0x03800000)
-+#define IDP_CPLD_PHYS (PXA_CS5_PHYS + 0x03C00000)
-+
-+
-+/*
-+ * virtual memory map
-+ */
-+
-+#define IDP_IDE_BASE (0xf0000000)
-+#define IDP_IDE_SIZE (1*1024*1024)
-+
-+#define IDP_ETH_BASE (IDP_IDE_BASE + IDP_IDE_SIZE)
-+#define IDP_ETH_SIZE (1*1024*1024)
-+#define ETH_BASE IDP_ETH_BASE //smc9194 driver compatibility issue
-+
-+#define IDP_COREVOLT_BASE (IDP_ETH_BASE + IDP_ETH_SIZE)
-+#define IDP_COREVOLT_SIZE (1*1024*1024)
-+
-+#define IDP_CPLD_BASE (IDP_COREVOLT_BASE + IDP_COREVOLT_SIZE)
-+#define IDP_CPLD_SIZE (1*1024*1024)
-+
-+#if (IDP_CPLD_BASE + IDP_CPLD_SIZE) > 0xfc000000
-+#error Your custom IO space is getting a bit large !!
-+#endif
-+
-+#define CPLD_P2V(x) ((x) - IDP_CPLD_PHYS + IDP_CPLD_BASE)
-+#define CPLD_V2P(x) ((x) - IDP_CPLD_BASE + IDP_CPLD_PHYS)
-+
-+#ifndef __ASSEMBLY__
-+# define __CPLD_REG(x) (*((volatile unsigned long *)CPLD_P2V(x)))
-+#else
-+# define __CPLD_REG(x) CPLD_P2V(x)
-+#endif
-+
-+/* board level registers in the CPLD: (offsets from CPLD_BASE) */
-+
-+#define _IDP_CPLD_REV (IDP_CPLD_PHYS + 0x00)
-+#define _IDP_CPLD_PERIPH_PWR (IDP_CPLD_PHYS + 0x04)
-+#define _IDP_CPLD_LED_CONTROL (IDP_CPLD_PHYS + 0x08)
-+#define _IDP_CPLD_KB_COL_HIGH (IDP_CPLD_PHYS + 0x0C)
-+#define _IDP_CPLD_KB_COL_LOW (IDP_CPLD_PHYS + 0x10)
-+#define _IDP_CPLD_PCCARD_EN (IDP_CPLD_PHYS + 0x14)
-+#define _IDP_CPLD_GPIOH_DIR (IDP_CPLD_PHYS + 0x18)
-+#define _IDP_CPLD_GPIOH_VALUE (IDP_CPLD_PHYS + 0x1C)
-+#define _IDP_CPLD_GPIOL_DIR (IDP_CPLD_PHYS + 0x20)
-+#define _IDP_CPLD_GPIOL_VALUE (IDP_CPLD_PHYS + 0x24)
-+#define _IDP_CPLD_PCCARD_PWR (IDP_CPLD_PHYS + 0x28)
-+#define _IDP_CPLD_MISC_CTRL (IDP_CPLD_PHYS + 0x2C)
-+#define _IDP_CPLD_LCD (IDP_CPLD_PHYS + 0x30)
-+#define _IDP_CPLD_FLASH_WE (IDP_CPLD_PHYS + 0x34)
-+
-+#define _IDP_CPLD_KB_ROW (IDP_CPLD_PHYS + 0x50)
-+#define _IDP_CPLD_PCCARD0_STATUS (IDP_CPLD_PHYS + 0x54)
-+#define _IDP_CPLD_PCCARD1_STATUS (IDP_CPLD_PHYS + 0x58)
-+#define _IDP_CPLD_MISC_STATUS (IDP_CPLD_PHYS + 0x5C)
-+
-+/* FPGA register virtual addresses */
-+
-+#define IDP_CPLD_REV __CPLD_REG(_IDP_CPLD_REV)
-+#define IDP_CPLD_PERIPH_PWR __CPLD_REG(_IDP_CPLD_PERIPH_PWR)
-+#define IDP_CPLD_LED_CONTROL __CPLD_REG(_IDP_CPLD_LED_CONTROL)
-+#define IDP_CPLD_KB_COL_HIGH __CPLD_REG(_IDP_CPLD_KB_COL_HIGH)
-+#define IDP_CPLD_KB_COL_LOW __CPLD_REG(_IDP_CPLD_KB_COL_LOW)
-+#define IDP_CPLD_PCCARD_EN __CPLD_REG(_IDP_CPLD_PCCARD_EN)
-+#define IDP_CPLD_GPIOH_DIR __CPLD_REG(_IDP_CPLD_GPIOH_DIR)
-+#define IDP_CPLD_GPIOH_VALUE __CPLD_REG(_IDP_CPLD_GPIOH_VALUE)
-+#define IDP_CPLD_GPIOL_DIR __CPLD_REG(_IDP_CPLD_GPIOL_DIR)
-+#define IDP_CPLD_GPIOL_VALUE __CPLD_REG(_IDP_CPLD_GPIOL_VALUE)
-+#define IDP_CPLD_PCCARD_PWR __CPLD_REG(_IDP_CPLD_PCCARD_PWR)
-+#define IDP_CPLD_MISC_CTRL __CPLD_REG(_IDP_CPLD_MISC_CTRL)
-+#define IDP_CPLD_LCD __CPLD_REG(_IDP_CPLD_LCD)
-+#define IDP_CPLD_FLASH_WE __CPLD_REG(_IDP_CPLD_FLASH_WE)
-+
-+#define IDP_CPLD_KB_ROW __CPLD_REG(_IDP_CPLD_KB_ROW)
-+#define IDP_CPLD_PCCARD0_STATUS __CPLD_REG(_IDP_CPLD_PCCARD0_STATUS)
-+#define IDP_CPLD_PCCARD1_STATUS __CPLD_REG(_IDP_CPLD_PCCARD1_STATUS)
-+#define IDP_CPLD_MISC_STATUS __CPLD_REG(_IDP_CPLD_MISC_STATUS)
-+
-+
-+/*
-+ * Bit masks for various registers
-+ */
-+// IDP_CPLD_PCCARD_PWR
-+#define PCC0_PWR0 (1 << 0)
-+#define PCC0_PWR1 (1 << 1)
-+#define PCC0_PWR2 (1 << 2)
-+#define PCC0_PWR3 (1 << 3)
-+#define PCC1_PWR0 (1 << 4)
-+#define PCC1_PWR1 (1 << 5)
-+#define PCC1_PWR2 (1 << 6)
-+#define PCC1_PWR3 (1 << 7)
-+
-+// IDP_CPLD_PCCARD_EN
-+#define PCC0_RESET (1 << 6)
-+#define PCC1_RESET (1 << 7)
-+#define PCC0_ENABLE (1 << 0)
-+#define PCC1_ENABLE (1 << 1)
-+
-+// IDP_CPLD_PCCARDx_STATUS
-+#define _PCC_WRPROT (1 << 7) // 7-4 read as low true
-+#define _PCC_RESET (1 << 6)
-+#define _PCC_IRQ (1 << 5)
-+#define _PCC_INPACK (1 << 4)
-+#define PCC_BVD2 (1 << 3)
-+#define PCC_BVD1 (1 << 2)
-+#define PCC_VS2 (1 << 1)
-+#define PCC_VS1 (1 << 0)
-+
-+#define PCC_DETECT(x) (GPLR(7 + (x)) & GPIO_bit(7 + (x)))
-+
-+/*
-+ * Macros for LCD Driver
-+ */
-+
-+#ifdef CONFIG_FB_PXA
-+
-+#define FB_BACKLIGHT_ON() (IDP_CPLD_LCD |= (1<<1))
-+#define FB_BACKLIGHT_OFF() (IDP_CPLD_LCD &= ~(1<<1))
-+
-+#define FB_PWR_ON() (IDP_CPLD_LCD |= (1<< 0))
-+#define FB_PWR_OFF() (IDP_CPLD_LCD &= ~(1<<0))
-+
-+#define FB_VLCD_ON() (IDP_CPLD_LCD |= (1<<2))
-+#define FB_VLCD_OFF() (IDP_CPLD_LCD &= ~(1<<2))
-+
-+#endif
-+
-+/* A listing of interrupts used by external hardware devices */
-+
-+#ifdef PXA_IDP_REV04
-+#define TOUCH_PANEL_IRQ IRQ_GPIO(5)
-+#define IDE_IRQ IRQ_GPIO(21)
-+#else
-+#define TOUCH_PANEL_IRQ IRQ_GPIO(21)
-+#define IDE_IRQ IRQ_GPIO(5)
-+#endif
-+
-+#define TOUCH_PANEL_IRQ_EDGE GPIO_FALLING_EDGE
-+
-+#define IDE_IRQ_EDGE GPIO_RISING_EDGE
-+
-+#define ETHERNET_IRQ IRQ_GPIO(4)
-+#define ETHERNET_IRQ_EDGE GPIO_RISING_EDGE
-+
-+#define IDE_IRQ_EDGE GPIO_RISING_EDGE
-+
-+#define PCMCIA_S0_CD_VALID IRQ_GPIO(7)
-+#define PCMCIA_S0_CD_VALID_EDGE GPIO_BOTH_EDGES
-+
-+#define PCMCIA_S1_CD_VALID IRQ_GPIO(8)
-+#define PCMCIA_S1_CD_VALID_EDGE GPIO_BOTH_EDGES
-+
-+#define PCMCIA_S0_RDYINT IRQ_GPIO(19)
-+#define PCMCIA_S1_RDYINT IRQ_GPIO(22)
-+
-+/*
-+ * Macros for LED Driver
-+ */
-+
-+/* leds 0 = ON */
-+#define IDP_HB_LED (1<<5)
-+#define IDP_BUSY_LED (1<<6)
-+
-+#define IDP_LEDS_MASK (IDP_HB_LED | IDP_BUSY_LED)
-+
-+#define IDP_WRITE_LEDS(value) (IDP_CPLD_LED_CONTROL = (IDP_CPLD_LED_CONTROL & (~(IDP_LEDS_MASK)) | value))
-+
-+/*
-+ * macros for MTD driver
-+ */
-+
-+#define FLASH_WRITE_PROTECT_DISABLE() ((IDP_CPLD_FLASH_WE) &= ~(0x1))
-+#define FLASH_WRITE_PROTECT_ENABLE() ((IDP_CPLD_FLASH_WE) |= (0x1))
-+
-+/*
-+ * macros for matrix keyboard driver
-+ */
-+
-+#define KEYBD_MATRIX_NUMBER_INPUTS 7
-+#define KEYBD_MATRIX_NUMBER_OUTPUTS 14
-+
-+#define KEYBD_MATRIX_INVERT_OUTPUT_LOGIC FALSE
-+#define KEYBD_MATRIX_INVERT_INPUT_LOGIC FALSE
-+
-+#define KEYBD_MATRIX_SETTLING_TIME_US 100
-+#define KEYBD_MATRIX_KEYSTATE_DEBOUNCE_CONSTANT 2
-+
-+#define KEYBD_MATRIX_SET_OUTPUTS(outputs) \
-+{\
-+ IDP_CPLD_KB_COL_LOW = outputs;\
-+ IDP_CPLD_KB_COL_HIGH = outputs >> 7;\
-+}
-+
-+#define KEYBD_MATRIX_GET_INPUTS(inputs) \
-+{\
-+ inputs = (IDP_CPLD_KB_ROW & 0x7f);\
-+}
-+
-+//------------------------------------------------------------------------------
-+
-+#else // must be rev 01
-+
-+/* -----------------------------------------------------------------------------
-+ * following is for rev01 boards only
-+ */
-+
-+#define IDP_FLASH_PHYS (PXA_CS0_PHYS)
-+#define IDP_ALT_FLASH_PHYS (PXA_CS1_PHYS)
-+#define IDP_MEDIAQ_PHYS (PXA_CS3_PHYS)
-+#define IDP_CTRL_PORT_PHYS (PXA_CS5_PHYS + 0x02C00000)
-+#define IDP_IDE_PHYS (PXA_CS5_PHYS + 0x03000000)
-+#define IDP_ETH_PHYS (PXA_CS5_PHYS + 0x03400000)
-+#define IDP_COREVOLT_PHYS (PXA_CS5_PHYS + 0x03800000)
-+#define IDP_CPLD_PHYS (PXA_CS5_PHYS + 0x03C00000)
-+
-+
-+/*
-+ * virtual memory map
-+ */
-+
-+#define IDP_CTRL_PORT_BASE (0xf0000000)
-+#define IDP_CTRL_PORT_SIZE (1*1024*1024)
-+
-+#define IDP_IDE_BASE (IDP_CTRL_PORT_BASE + IDP_CTRL_PORT_SIZE)
-+#define IDP_IDE_SIZE (1*1024*1024)
-+
-+#define IDP_ETH_BASE (IDP_IDE_BASE + IDP_IDE_SIZE)
-+#define IDP_ETH_SIZE (1*1024*1024)
-+
-+#define IDP_COREVOLT_BASE (IDP_ETH_BASE + IDP_ETH_SIZE)
-+#define IDP_COREVOLT_SIZE (1*1024*1024)
-+
-+#define IDP_CPLD_BASE (IDP_COREVOLT_BASE + IDP_COREVOLT_SIZE)
-+#define IDP_CPLD_SIZE (1*1024*1024)
-+
-+#if (IDP_CPLD_BASE + IDP_CPLD_SIZE) > 0xfc000000
-+#error Your custom IO space is getting a bit large !!
-+#endif
-+
-+#define CPLD_P2V(x) ((x) - IDP_CPLD_PHYS + IDP_CPLD_BASE)
-+#define CPLD_V2P(x) ((x) - IDP_CPLD_BASE + IDP_CPLD_PHYS)
-+
-+#ifndef __ASSEMBLY__
-+# define __CPLD_REG(x) (*((volatile unsigned long *)CPLD_P2V(x)))
-+#else
-+# define __CPLD_REG(x) CPLD_P2V(x)
-+#endif
-+
-+/* board level registers in the CPLD: (offsets from CPLD_BASE) */
-+
-+#define _IDP_CPLD_LED_CONTROL (IDP_CPLD_PHYS + 0x00)
-+#define _IDP_CPLD_PERIPH_PWR (IDP_CPLD_PHYS + 0x04)
-+#define _IDP_CPLD_CIR (IDP_CPLD_PHYS + 0x08)
-+#define _IDP_CPLD_KB_COL_HIGH (IDP_CPLD_PHYS + 0x0C)
-+#define _IDP_CPLD_KB_COL_LOW (IDP_CPLD_PHYS + 0x10)
-+#define _IDP_CPLD_PCCARD_EN (IDP_CPLD_PHYS + 0x14)
-+#define _IDP_CPLD_GPIOH_DIR (IDP_CPLD_PHYS + 0x18)
-+#define _IDP_CPLD_GPIOH_VALUE (IDP_CPLD_PHYS + 0x1C)
-+#define _IDP_CPLD_GPIOL_DIR (IDP_CPLD_PHYS + 0x20)
-+#define _IDP_CPLD_GPIOL_VALUE (IDP_CPLD_PHYS + 0x24)
-+#define _IDP_CPLD_MISC (IDP_CPLD_PHYS + 0x28)
-+#define _IDP_CPLD_PCCARD0_STATUS (IDP_CPLD_PHYS + 0x2C)
-+#define _IDP_CPLD_PCCARD1_STATUS (IDP_CPLD_PHYS + 0x30)
-+
-+/* FPGA register virtual addresses */
-+#define IDP_CPLD_LED_CONTROL __CPLD_REG(_IDP_CPLD_LED_CONTROL) /* write only */
-+#define IDP_CPLD_PERIPH_PWR __CPLD_REG(_IDP_CPLD_PERIPH_PWR) /* write only */
-+#define IDP_CPLD_CIR __CPLD_REG(_IDP_CPLD_CIR) /* write only */
-+#define IDP_CPLD_KB_COL_HIGH __CPLD_REG(_IDP_CPLD_KB_COL_HIGH) /* write only */
-+#define IDP_CPLD_KB_COL_LOW __CPLD_REG(_IDP_CPLD_KB_COL_LOW) /* write only */
-+#define IDP_CPLD_PCCARD_EN __CPLD_REG(_IDP_CPLD_PCCARD_EN) /* write only */
-+#define IDP_CPLD_GPIOH_DIR __CPLD_REG(_IDP_CPLD_GPIOH_DIR) /* write only */
-+#define IDP_CPLD_GPIOH_VALUE __CPLD_REG(_IDP_CPLD_GPIOH_VALUE) /* write only */
-+#define IDP_CPLD_GPIOL_DIR __CPLD_REG(_IDP_CPLD_GPIOL_DIR) /* write only */
-+#define IDP_CPLD_GPIOL_VALUE __CPLD_REG(_IDP_CPLD_GPIOL_VALUE) /* write only */
-+#define IDP_CPLD_MISC __CPLD_REG(_IDP_CPLD_MISC) /* read only */
-+#define IDP_CPLD_PCCARD0_STATUS __CPLD_REG(_IDP_CPLD_PCCARD0_STATUS) /* read only */
-+#define IDP_CPLD_PCCARD1_STATUS __CPLD_REG(_IDP_CPLD_PCCARD1_STATUS) /* read only */
-+
-+
-+#ifndef __ASSEMBLY__
-+
-+/* shadow registers for write only registers */
-+extern unsigned int idp_cpld_led_control_shadow;
-+extern unsigned int idp_cpld_periph_pwr_shadow;
-+extern unsigned int idp_cpld_cir_shadow;
-+extern unsigned int idp_cpld_kb_col_high_shadow;
-+extern unsigned int idp_cpld_kb_col_low_shadow;
-+extern unsigned int idp_cpld_pccard_en_shadow;
-+extern unsigned int idp_cpld_gpioh_dir_shadow;
-+extern unsigned int idp_cpld_gpioh_value_shadow;
-+extern unsigned int idp_cpld_gpiol_dir_shadow;
-+extern unsigned int idp_cpld_gpiol_value_shadow;
-+
-+extern unsigned int idp_control_port_shadow;
-+
-+/*
-+ * macros to write to write only register
-+ *
-+ * none of these macros are protected from
-+ * multiple drivers using them in interrupt context.
-+ */
-+
-+#define WRITE_IDP_CPLD_LED_CONTROL(value, mask) \
-+{\
-+ idp_cpld_led_control_shadow = ((value & mask) | (idp_cpld_led_control_shadow & ~mask));\
-+ IDP_CPLD_LED_CONTROL = idp_cpld_led_control_shadow;\
-+}
-+#define WRITE_IDP_CPLD_PERIPH_PWR(value, mask) \
-+{\
-+ idp_cpld_periph_pwr_shadow = ((value & mask) | (idp_cpld_periph_pwr_shadow & ~mask));\
-+ IDP_CPLD_PERIPH_PWR = idp_cpld_periph_pwr_shadow;\
-+}
-+#define WRITE_IDP_CPLD_CIR(value, mask) \
-+{\
-+ idp_cpld_cir_shadow = ((value & mask) | (idp_cpld_cir_shadow & ~mask));\
-+ IDP_CPLD_CIR = idp_cpld_cir_shadow;\
-+}
-+#define WRITE_IDP_CPLD_KB_COL_HIGH(value, mask) \
-+{\
-+ idp_cpld_kb_col_high_shadow = ((value & mask) | (idp_cpld_kb_col_high_shadow & ~mask));\
-+ IDP_CPLD_KB_COL_HIGH = idp_cpld_kb_col_high_shadow;\
-+}
-+#define WRITE_IDP_CPLD_KB_COL_LOW(value, mask) \
-+{\
-+ idp_cpld_kb_col_low_shadow = ((value & mask) | (idp_cpld_kb_col_low_shadow & ~mask));\
-+ IDP_CPLD_KB_COL_LOW = idp_cpld_kb_col_low_shadow;\
-+}
-+#define WRITE_IDP_CPLD_PCCARD_EN(value, mask) \
-+{\
-+ idp_cpld_ = ((value & mask) | (idp_cpld_led_control_shadow & ~mask));\
-+ IDP_CPLD_LED_CONTROL = idp_cpld_led_control_shadow;\
-+}
-+#define WRITE_IDP_CPLD_GPIOH_DIR(value, mask) \
-+{\
-+ idp_cpld_gpioh_dir_shadow = ((value & mask) | (idp_cpld_gpioh_dir_shadow & ~mask));\
-+ IDP_CPLD_GPIOH_DIR = idp_cpld_gpioh_dir_shadow;\
-+}
-+#define WRITE_IDP_CPLD_GPIOH_VALUE(value, mask) \
-+{\
-+ idp_cpld_gpioh_value_shadow = ((value & mask) | (idp_cpld_gpioh_value_shadow & ~mask));\
-+ IDP_CPLD_GPIOH_VALUE = idp_cpld_gpioh_value_shadow;\
-+}
-+#define WRITE_IDP_CPLD_GPIOL_DIR(value, mask) \
-+{\
-+ idp_cpld_gpiol_dir_shadow = ((value & mask) | (idp_cpld_gpiol_dir_shadow & ~mask));\
-+ IDP_CPLD_GPIOL_DIR = idp_cpld_gpiol_dir_shadow;\
-+}
-+#define WRITE_IDP_CPLD_GPIOL_VALUE(value, mask) \
-+{\
-+ idp_cpld_gpiol_value_shadow = ((value & mask) | (idp_cpld_gpiol_value_shadow & ~mask));\
-+ IDP_CPLD_GPIOL_VALUE = idp_cpld_gpiol_value_shadow;\
-+}
-+
-+#define WRITE_IDP_CONTROL_PORT(value, mask) \
-+{\
-+ idp_control_port_shadow = ((value & mask) | (idp_control_port_shadow & ~mask));\
-+ (*((volatile unsigned long *)IDP_CTRL_PORT_BASE)) = idp_control_port_shadow;\
-+}
-+
-+#endif
-+
-+/* A listing of interrupts used by external hardware devices */
-+
-+#define TOUCH_PANEL_IRQ IRQ_GPIO(21)
-+#define TOUCH_PANEL_IRQ_EGDE GPIO_FALLING_EDGE
-+
-+#define ETHERNET_IRQ IRQ_GPIO(4)
-+#define ETHERNET_IRQ_EDGE GPIO_RISING_EDGE
-+
-+/*
-+ * Bit masks for various registers
-+ */
-+
-+
-+/* control port */
-+#define IDP_CONTROL_PORT_PCSLOT0_0 (1 << 0)
-+#define IDP_CONTROL_PORT_PCSLOT0_1 (1 << 1)
-+#define IDP_CONTROL_PORT_PCSLOT0_2 (1 << 2)
-+#define IDP_CONTROL_PORT_PCSLOT0_3 (1 << 3)
-+#define IDP_CONTROL_PORT_PCSLOT1_1 (1 << 4)
-+#define IDP_CONTROL_PORT_PCSLOT1_2 (1 << 5)
-+#define IDP_CONTROL_PORT_PCSLOT1_3 (1 << 6)
-+#define IDP_CONTROL_PORT_PCSLOT1_4 (1 << 7)
-+#define IDP_CONTROL_PORT_SERIAL1_EN (1 << 9)
-+#define IDP_CONTROL_PORT_SERIAL2_EN (1 << 10)
-+#define IDP_CONTROL_PORT_SERIAL3_EN (1 << 11)
-+#define IDP_CONTROL_PORT_IRDA_FIR (1 << 12)
-+#define IDP_CONTROL_PORT_IRDA_M0 (1 << 13)
-+#define IDP_CONTROL_PORT_IRDA_M1 (1 << 14)
-+#define IDP_CONTROL_PORT_I2S_PWR (1 << 15)
-+#define IDP_CONTROL_PORT_FLASH_WP (1 << 19)
-+#define IDP_CONTROL_PORT_MILL_EN (1 << 20)
-+#define IDP_CONTROL_PORT_LCD_PWR (1 << 21)
-+#define IDP_CONTROL_PORT_LCD_BKLEN (1 << 22)
-+#define IDP_CONTROL_PORT_LCD_ENAVLCD (1 << 23)
-+
-+/*
-+ * Macros for LCD Driver
-+ */
-+
-+#ifdef CONFIG_FB_PXA
-+
-+#define FB_BACKLIGHT_ON() WRITE_IDP_CONTROL_PORT(IDP_CONTROL_PORT_LCD_BKLEN, IDP_CONTROL_PORT_LCD_BKLEN)
-+#define FB_BACKLIGHT_OFF() WRITE_IDP_CONTROL_PORT(0, IDP_CONTROL_PORT_LCD_BKLEN)
-+
-+#define FB_PWR_ON() WRITE_IDP_CONTROL_PORT(IDP_CONTROL_PORT_LCD_PWR, IDP_CONTROL_PORT_LCD_PWR)
-+#define FB_PWR_OFF() WRITE_IDP_CONTROL_PORT(0, IDP_CONTROL_PORT_LCD_PWR)
-+
-+#define FB_VLCD_ON() WRITE_IDP_CONTROL_PORT(IDP_CONTROL_PORT_LCD_ENAVLCD, IDP_CONTROL_PORT_LCD_ENAVLCD)
-+#define FB_VLCD_OFF() WRITE_IDP_CONTROL_PORT(0, IDP_CONTROL_PORT_LCD_ENAVLCD)
-+
-+#endif
-+
-+
-+/*
-+ * Macros for LED Driver
-+ */
-+
-+/* leds 0 = ON */
-+#define IDP_HB_LED 0x1
-+#define IDP_BUSY_LED 0x2
-+
-+#define IDP_LEDS_MASK (IDP_HB_LED | IDP_BUSY_LED)
-+
-+#define IDP_WRITE_LEDS(value) WRITE_IDP_CPLD_LED_CONTROL(value, IDP_LEDS_MASK)
-+
-+/*
-+ * macros for MTD driver
-+ */
-+
-+#define FLASH_WRITE_PROTECT_DISABLE() WRITE_IDP_CONTROL_PORT(0, IDP_CONTROL_PORT_FLASH_WP)
-+#define FLASH_WRITE_PROTECT_ENABLE() WRITE_IDP_CONTROL_PORT(IDP_CONTROL_PORT_FLASH_WP, IDP_CONTROL_PORT_FLASH_WP)
-+
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/innokom.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,47 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/innokom.h
-+ *
-+ * (c) 2003 Robert Schwebel <r.schwebel@pengutronix.de>, Pengutronix
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+/*
-+ * GPIOs
-+ */
-+#define GPIO_INNOKOM_RESET 3
-+#define GPIO_INNOKOM_SW_UPDATE 11
-+#define GPIO_INNOKOM_ETH 59
-+
-+/*
-+ * ethernet chip (SMSC91C111)
-+ */
-+#define INNOKOM_ETH_PHYS PXA_CS5_PHYS
-+#define INNOKOM_ETH_BASE (0xf0000000) /* phys 0x14000000 */
-+#define INNOKOM_ETH_SIZE (1*1024*1024)
-+#define INNOKOM_ETH_IRQ IRQ_GPIO(GPIO_INNOKOM_ETH)
-+#define INNOKOM_ETH_IRQ_EDGE GPIO_RISING_EDGE
-+
-+/*
-+ * virtual to physical conversion macros
-+ */
-+#define INNOKOM_P2V(x) ((x) - INNOKOM_FPGA_PHYS + INNOKOM_FPGA_VIRT)
-+#define INNOKOM_V2P(x) ((x) - INNOKOM_FPGA_VIRT + INNOKOM_FPGA_PHYS)
-+
-+#ifndef __ASSEMBLY__
-+# define __INNOKOM_REG(x) (*((volatile unsigned long *)INNOKOM_P2V(x)))
-+#else
-+# define __INNOKOM_REG(x) INNOKOM_P2V(x)
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/io.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,34 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/io.h
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Jun 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#ifndef __ASM_ARM_ARCH_IO_H
-+#define __ASM_ARM_ARCH_IO_H
-+
-+#define IO_SPACE_LIMIT 0xffffffff
-+
-+/*
-+ * We don't actually have real ISA nor PCI buses, but there is so many
-+ * drivers out there that might just work if we fake them...
-+ */
-+#define __io(a) (a)
-+#define __mem_pci(a) ((unsigned long)(a))
-+#define __mem_isa(a) ((unsigned long)(a))
-+
-+/*
-+ * Generic virtual read/write
-+ */
-+#define __arch_getw(a) (*(volatile unsigned short *)(a))
-+#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
-+
-+#define iomem_valid_addr(iomem,sz) (1)
-+#define iomem_to_phys(iomem) (iomem)
-+
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/irq.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,19 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/irq.h
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Jun 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#define fixup_irq(x) (x)
-+
-+/*
-+ * This prototype is required for cascading of multiplexed interrupts.
-+ * Since it doesn't exist elsewhere, we'll put it here for now.
-+ */
-+extern void do_IRQ(int irq, struct pt_regs *regs);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/irqs.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,137 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/irqs.h
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Jun 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#define PXA_IRQ_SKIP 7 /* The first 7 IRQs are not yet used */
-+#define PXA_IRQ(x) ((x) - PXA_IRQ_SKIP)
-+
-+#define IRQ_HWUART PXA_IRQ(7) /* HWUART Transmit/Receive/Error */
-+#define IRQ_GPIO0 PXA_IRQ(8) /* GPIO0 Edge Detect */
-+#define IRQ_GPIO1 PXA_IRQ(9) /* GPIO1 Edge Detect */
-+#define IRQ_GPIO_2_80 PXA_IRQ(10) /* GPIO[2-80] Edge Detect */
-+#define IRQ_USB PXA_IRQ(11) /* USB Service */
-+#define IRQ_PMU PXA_IRQ(12) /* Performance Monitoring Unit */
-+#define IRQ_I2S PXA_IRQ(13) /* I2S Interrupt */
-+#define IRQ_AC97 PXA_IRQ(14) /* AC97 Interrupt */
-+#define IRQ_ASSP PXA_IRQ(15) /* Audio SSP Service Request */
-+#define IRQ_NSSP PXA_IRQ(16) /* Network SSP Service Request */
-+#define IRQ_LCD PXA_IRQ(17) /* LCD Controller Service Request */
-+#define IRQ_I2C PXA_IRQ(18) /* I2C Service Request */
-+#define IRQ_ICP PXA_IRQ(19) /* ICP Transmit/Receive/Error */
-+#define IRQ_STUART PXA_IRQ(20) /* STUART Transmit/Receive/Error */
-+#define IRQ_BTUART PXA_IRQ(21) /* BTUART Transmit/Receive/Error */
-+#define IRQ_FFUART PXA_IRQ(22) /* FFUART Transmit/Receive/Error*/
-+#define IRQ_MMC PXA_IRQ(23) /* MMC Status/Error Detection */
-+#define IRQ_SSP PXA_IRQ(24) /* SSP Service Request */
-+#define IRQ_DMA PXA_IRQ(25) /* DMA Channel Service Request */
-+#define IRQ_OST0 PXA_IRQ(26) /* OS Timer match 0 */
-+#define IRQ_OST1 PXA_IRQ(27) /* OS Timer match 1 */
-+#define IRQ_OST2 PXA_IRQ(28) /* OS Timer match 2 */
-+#define IRQ_OST3 PXA_IRQ(29) /* OS Timer match 3 */
-+#define IRQ_RTC1Hz PXA_IRQ(30) /* RTC HZ Clock Tick */
-+#define IRQ_RTCAlrm PXA_IRQ(31) /* RTC Alarm */
-+
-+#define GPIO_2_80_TO_IRQ(x) \
-+ PXA_IRQ((x) - 2 + 32)
-+#define IRQ_GPIO(x) (((x) < 2) ? (IRQ_GPIO0 + (x)) : GPIO_2_80_TO_IRQ(x))
-+
-+#define IRQ_TO_GPIO_2_80(i) \
-+ ((i) - PXA_IRQ(32) + 2)
-+#define IRQ_TO_GPIO(i) ((i) - (((i) > IRQ_GPIO1) ? IRQ_GPIO(2) - 2 : IRQ_GPIO(0)))
-+
-+#define NR_IRQS (IRQ_GPIO(80) + 1)
-+
-+#if defined(CONFIG_SA1111)
-+
-+#define IRQ_SA1111_START (IRQ_GPIO(80) + 1)
-+#define SA1111_IRQ(x) (IRQ_SA1111_START + (x))
-+
-+#define IRQ_GPAIN0 SA1111_IRQ(0)
-+#define IRQ_GPAIN1 SA1111_IRQ(1)
-+#define IRQ_GPAIN2 SA1111_IRQ(2)
-+#define IRQ_GPAIN3 SA1111_IRQ(3)
-+#define IRQ_GPBIN0 SA1111_IRQ(4)
-+#define IRQ_GPBIN1 SA1111_IRQ(5)
-+#define IRQ_GPBIN2 SA1111_IRQ(6)
-+#define IRQ_GPBIN3 SA1111_IRQ(7)
-+#define IRQ_GPBIN4 SA1111_IRQ(8)
-+#define IRQ_GPBIN5 SA1111_IRQ(9)
-+#define IRQ_GPCIN0 SA1111_IRQ(10)
-+#define IRQ_GPCIN1 SA1111_IRQ(11)
-+#define IRQ_GPCIN2 SA1111_IRQ(12)
-+#define IRQ_GPCIN3 SA1111_IRQ(13)
-+#define IRQ_GPCIN4 SA1111_IRQ(14)
-+#define IRQ_GPCIN5 SA1111_IRQ(15)
-+#define IRQ_GPCIN6 SA1111_IRQ(16)
-+#define IRQ_GPCIN7 SA1111_IRQ(17)
-+#define IRQ_MSTXINT SA1111_IRQ(18)
-+#define IRQ_MSRXINT SA1111_IRQ(19)
-+#define IRQ_MSSTOPERRINT SA1111_IRQ(20)
-+#define IRQ_TPTXINT SA1111_IRQ(21)
-+#define IRQ_TPRXINT SA1111_IRQ(22)
-+#define IRQ_TPSTOPERRINT SA1111_IRQ(23)
-+#define SSPXMTINT SA1111_IRQ(24)
-+#define SSPRCVINT SA1111_IRQ(25)
-+#define SSPROR SA1111_IRQ(26)
-+#define AUDXMTDMADONEA SA1111_IRQ(32)
-+#define AUDRCVDMADONEA SA1111_IRQ(33)
-+#define AUDXMTDMADONEB SA1111_IRQ(34)
-+#define AUDRCVDMADONEB SA1111_IRQ(35)
-+#define AUDTFSR SA1111_IRQ(36)
-+#define AUDRFSR SA1111_IRQ(37)
-+#define AUDTUR SA1111_IRQ(38)
-+#define AUDROR SA1111_IRQ(39)
-+#define AUDDTS SA1111_IRQ(40)
-+#define AUDRDD SA1111_IRQ(41)
-+#define AUDSTO SA1111_IRQ(42)
-+#define USBPWR SA1111_IRQ(43)
-+#define NIRQHCIM SA1111_IRQ(44)
-+#define HCIBUFFACC SA1111_IRQ(45)
-+#define HCIRMTWKP SA1111_IRQ(46)
-+#define NHCIMFCIR SA1111_IRQ(47)
-+#define PORT_RESUME SA1111_IRQ(48)
-+#define S0_READY_NINT SA1111_IRQ(49)
-+#define S1_READY_NINT SA1111_IRQ(50)
-+#define S0_CD_VALID SA1111_IRQ(51)
-+#define S1_CD_VALID SA1111_IRQ(52)
-+#define S0_BVD1_STSCHG SA1111_IRQ(53)
-+#define S1_BVD1_STSCHG SA1111_IRQ(54)
-+
-+#define SA1111_IRQ_MAX SA1111_IRQ(54)
-+
-+#undef NR_IRQS
-+#define NR_IRQS (SA1111_IRQ_MAX + 1)
-+
-+#endif // defined(CONFIG_SA1111)
-+
-+#if defined(CONFIG_ARCH_LUBBOCK) || defined(CONFIG_ARCH_PXA_IDP)
-+#if CONFIG_SA1111
-+#define LUBBOCK_IRQ(x) (SA1111_IRQ_MAX + 1 + (x))
-+#else
-+#define LUBBOCK_IRQ(x) (IRQ_GPIO(80) + 1 + (x))
-+#endif
-+
-+#define LUBBOCK_SD_IRQ LUBBOCK_IRQ(0)
-+#define LUBBOCK_SA1111_IRQ LUBBOCK_IRQ(1)
-+#define LUBBOCK_USB_IRQ LUBBOCK_IRQ(2)
-+#define LUBBOCK_ETH_IRQ LUBBOCK_IRQ(3)
-+#define LUBBOCK_UCB1400_IRQ LUBBOCK_IRQ(4)
-+#define LUBBOCK_BB_IRQ LUBBOCK_IRQ(5)
-+#define LUBBOCK_USB_DISC_IRQ LUBBOCK_IRQ(6) /* usb disconnect */
-+#define LUBBOCK_LAST_IRQ LUBBOCK_IRQ(6)
-+
-+#undef NR_IRQS
-+#define NR_IRQS (LUBBOCK_LAST_IRQ + 1)
-+
-+#endif // CONFIG_ARCH_LUBBOCK
-+
-+
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/keyboard.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,29 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/keyboard.h
-+ *
-+ * This file contains the architecture specific keyboard definitions
-+ */
-+
-+#ifndef _PXA_KEYBOARD_H
-+#define _PXA_KEYBOARD_H
-+
-+#include <linux/config.h>
-+#include <asm/mach-types.h>
-+#include <asm/hardware.h>
-+
-+extern struct kbd_ops_struct *kbd_ops;
-+
-+#define kbd_disable_irq() do { } while(0);
-+#define kbd_enable_irq() do { } while(0);
-+
-+extern int sa1111_kbd_init_hw(void);
-+
-+static inline void kbd_init_hw(void)
-+{
-+ if (machine_is_lubbock())
-+ sa1111_kbd_init_hw();
-+}
-+
-+
-+#endif /* _PXA_KEYBOARD_H */
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/lubbock.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,113 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/lubbock.h
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Jun 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#define LUBBOCK_FPGA_PHYS PXA_CS2_PHYS
-+#define LUBBOCK_FPGA_VIRT (0xf0000000) /* phys 0x08000000 */
-+#define LUBBOCK_ETH_PHYS PXA_CS3_PHYS
-+#define LUBBOCK_ETH_VIRT (0xf1000000)
-+#define LUBBOCK_SA1111_BASE (0xf4000000) /* phys 0x10000000 */
-+
-+#define LUB_P2V(x) ((x) - LUBBOCK_FPGA_PHYS + LUBBOCK_FPGA_VIRT)
-+#define LUB_V2P(x) ((x) - LUBBOCK_FPGA_VIRT + LUBBOCK_FPGA_PHYS)
-+
-+#ifndef __ASSEMBLY__
-+# define __LUB_REG(x) (*((volatile unsigned long *)LUB_P2V(x)))
-+#else
-+# define __LUB_REG(x) LUB_P2V(x)
-+#endif
-+
-+/* board level registers in the CPLD: (offsets from CPLD_BASE) */
-+
-+#define WHOAMI 0 // card ID's (see programmers manual)
-+#define HEX_LED 0x10 // R/W access to 8 7 segment displays
-+#define DISC_BLNK_LED 0x40 // R/W [15-8] enables for hex leds, [7-0] discrete LEDs
-+#define CONF_SWITCHES 0x50 // RO [1] flash wrt prot, [0] 0= boot from rom, 1= flash
-+#define USER_SWITCHES 0x60 // RO [15-8] dip switches, [7-0] 2 hex encoding switches
-+#define MISC_WR 0x80 // R/W various system controls -see manual
-+#define MISC_RD 0x90 // RO various system status bits -see manual
-+//#define LUB_IRQ_MASK_EN 0xC0 // R/W 0= mask, 1= enable of TS, codec, ethernet, USB, SA1111, and card det. irq's
-+//#define LUB_IRQ_SET_CLR 0xD0 // R/W 1= set, 0 = clear IRQ's from TS, codec, etc...
-+//#define LUB_GP 0x100 // R/W [15-0] 16 bits of general purpose I/o for hacking
-+
-+
-+/* FPGA register physical addresses */
-+#define _LUB_WHOAMI (LUBBOCK_FPGA_PHYS + 0x000)
-+#define _LUB_HEXLED (LUBBOCK_FPGA_PHYS + 0x010)
-+#define _LUB_DISC_BLNK_LED (LUBBOCK_FPGA_PHYS + 0x040)
-+#define _LUB_CONF_SWITCHES (LUBBOCK_FPGA_PHYS + 0x050)
-+#define _LUB_USER_SWITCHES (LUBBOCK_FPGA_PHYS + 0x060)
-+#define _LUB_MISC_WR (LUBBOCK_FPGA_PHYS + 0x080)
-+#define _LUB_MISC_RD (LUBBOCK_FPGA_PHYS + 0x090)
-+#define _LUB_IRQ_MASK_EN (LUBBOCK_FPGA_PHYS + 0x0C0)
-+#define _LUB_IRQ_SET_CLR (LUBBOCK_FPGA_PHYS + 0x0D0)
-+#define _LUB_GP (LUBBOCK_FPGA_PHYS + 0x100)
-+
-+/* FPGA register virtual addresses */
-+#define LUB_WHOAMI __LUB_REG(_LUB_WHOAMI)
-+#define LUB_HEXLED __LUB_REG(_LUB_HEXLED)
-+#define LUB_DISC_BLNK_LED __LUB_REG(_LUB_DISC_BLNK_LED)
-+#define LUB_CONF_SWITCHES __LUB_REG(_LUB_CONF_SWITCHES)
-+#define LUB_USER_SWITCHES __LUB_REG(_LUB_USER_SWITCHES)
-+#define LUB_MISC_WR __LUB_REG(_LUB_MISC_WR)
-+#define LUB_MISC_RD __LUB_REG(_LUB_MISC_RD)
-+#define LUB_IRQ_MASK_EN __LUB_REG(_LUB_IRQ_MASK_EN)
-+#define LUB_IRQ_SET_CLR __LUB_REG(_LUB_IRQ_SET_CLR)
-+#define LUB_GP __LUB_REG(_LUB_GP)
-+
-+/* GPIOs */
-+
-+#define GPIO_LUBBOCK_IRQ 0
-+#define IRQ_GPIO_LUBBOCK_IRQ IRQ_GPIO0
-+
-+
-+/*
-+ * LED macros
-+ */
-+
-+#define LEDS_BASE LUB_DISC_BLNK_LED
-+
-+// 8 discrete leds available for general use:
-+
-+#define D28 0x1
-+#define D27 0x2
-+#define D26 0x4
-+#define D25 0x8
-+#define D24 0x10
-+#define D23 0x20
-+#define D22 0x40
-+#define D21 0x80
-+
-+/* Note: bits [15-8] are used to enable/blank the 8 7 segment hex displays so
-+* be sure to not monkey with them here.
-+*/
-+
-+#define HEARTBEAT_LED D28
-+#define SYS_BUSY_LED D27
-+#define HEXLEDS_BASE LUB_HEXLED
-+
-+#define HEARTBEAT_LED_ON (LEDS_BASE &= ~HEARTBEAT_LED)
-+#define HEARTBEAT_LED_OFF (LEDS_BASE |= HEARTBEAT_LED)
-+#define SYS_BUSY_LED_OFF (LEDS_BASE |= SYS_BUSY_LED)
-+#define SYS_BUSY_LED_ON (LEDS_BASE &= ~SYS_BUSY_LED)
-+
-+// use x = D26-D21 for these, please...
-+#define DISCRETE_LED_ON(x) (LEDS_BASE &= ~(x))
-+#define DISCRETE_LED_OFF(x) (LEDS_BASE |= (x))
-+
-+#ifndef __ASSEMBLY__
-+
-+//extern int hexled_val = 0;
-+
-+#endif
-+
-+#define BUMP_COUNTER (HEXLEDS_BASE = hexled_val++)
-+#define DEC_COUNTER (HEXLEDS_BASE = hexled_val--)
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/memory.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,106 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/memory.h
-+ *
-+ * Author: Nicolas Pitre
-+ * Copyright: (C) 2001 MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#ifndef __ASM_ARCH_MEMORY_H
-+#define __ASM_ARCH_MEMORY_H
-+
-+
-+/*
-+ * Task size: 3GB
-+ */
-+#define TASK_SIZE (0xc0000000UL)
-+#define TASK_SIZE_26 (0x04000000UL)
-+
-+/*
-+ * This decides where the kernel will search for a free chunk of vm
-+ * space during mmap's.
-+ */
-+#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
-+
-+/*
-+ * Page offset: 3GB
-+ */
-+#define PAGE_OFFSET (0xc0000000UL)
-+
-+/*
-+ * Physical DRAM offset.
-+ */
-+#define PHYS_OFFSET (0xa0000000UL)
-+
-+/*
-+ * physical vs virtual ram conversion
-+ */
-+#define __virt_to_phys__is_a_macro
-+#define __phys_to_virt__is_a_macro
-+#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET)
-+#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET)
-+
-+/*
-+ * Virtual view <-> DMA view memory address translations
-+ * virt_to_bus: Used to translate the virtual address to an
-+ * address suitable to be passed to set_dma_addr
-+ * bus_to_virt: Used to convert an address for DMA operations
-+ * to an address that the kernel can use.
-+ */
-+#define __virt_to_bus__is_a_macro
-+#define __bus_to_virt__is_a_macro
-+#define __virt_to_bus(x) __virt_to_phys(x)
-+#define __bus_to_virt(x) __phys_to_virt(x)
-+
-+#ifdef CONFIG_DISCONTIGMEM
-+/*
-+ * The nodes are matched with the physical SDRAM banks as follows:
-+ *
-+ * node 0: 0xa0000000-0xa3ffffff --> 0xc0000000-0xc3ffffff
-+ * node 1: 0xa4000000-0xa7ffffff --> 0xc4000000-0xc7ffffff
-+ * node 2: 0xa8000000-0xabffffff --> 0xc8000000-0xcbffffff
-+ * node 3: 0xac000000-0xafffffff --> 0xcc000000-0xcfffffff
-+ */
-+
-+#define NR_NODES 4
-+
-+/*
-+ * Given a kernel address, find the home node of the underlying memory.
-+ */
-+#define KVADDR_TO_NID(addr) (((unsigned long)(addr) - PAGE_OFFSET) >> 26)
-+
-+/*
-+ * Given a page frame number, convert it to a node id.
-+ */
-+#define PFN_TO_NID(pfn) (((pfn) - PHYS_PFN_OFFSET) >> (26 - PAGE_SHIFT))
-+
-+/*
-+ * Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
-+ * and returns the mem_map of that node.
-+ */
-+#define ADDR_TO_MAPBASE(kaddr) NODE_MEM_MAP(KVADDR_TO_NID(kaddr))
-+
-+/*
-+ * Given a page frame number, find the owning node of the memory
-+ * and returns the mem_map of that node.
-+ */
-+#define PFN_TO_MAPBASE(pfn) NODE_MEM_MAP(PFN_TO_NID(pfn))
-+
-+/*
-+ * Given a kaddr, LOCAL_MEM_MAP finds the owning node of the memory
-+ * and returns the index corresponding to the appropriate page in the
-+ * node's mem_map.
-+ */
-+#define LOCAL_MAP_NR(addr) \
-+ (((unsigned long)(addr) & 0x03ffffff) >> PAGE_SHIFT)
-+
-+#else
-+
-+#define PFN_TO_NID(addr) (0)
-+
-+#endif
-+
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/param.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,3 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/param.h
-+ */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/pcmcia.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,65 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/pcmcia.h
-+ *
-+ * Author: George Davis
-+ * Created: Jan 10, 2002
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ *
-+ * Originally based upon linux/include/asm-arm/arch-sa1100/pcmcia.h
-+ *
-+ */
-+
-+#ifndef _ASM_ARCH_PCMCIA
-+#define _ASM_ARCH_PCMCIA
-+
-+
-+/* Ideally, we'd support up to MAX_SOCK sockets, but PXA250 only
-+ * provides support for a maximum of two.
-+ */
-+#define PXA_PCMCIA_MAX_SOCK (2)
-+
-+
-+#ifndef __ASSEMBLY__
-+
-+struct pcmcia_init {
-+ void (*handler)(int irq, void *dev, struct pt_regs *regs);
-+};
-+
-+struct pcmcia_state {
-+ unsigned detect: 1,
-+ ready: 1,
-+ bvd1: 1,
-+ bvd2: 1,
-+ wrprot: 1,
-+ vs_3v: 1,
-+ vs_Xv: 1;
-+};
-+
-+struct pcmcia_state_array {
-+ unsigned int size;
-+ struct pcmcia_state *state;
-+};
-+
-+struct pcmcia_irq_info {
-+ unsigned int sock;
-+ unsigned int irq;
-+};
-+
-+struct pcmcia_low_level {
-+ int (*init)(struct pcmcia_init *);
-+ int (*shutdown)(void);
-+ int (*socket_state)(struct pcmcia_state_array *);
-+ int (*get_irq_info)(struct pcmcia_irq_info *);
-+ int (*configure_socket)(unsigned int, socket_state_t *);
-+};
-+
-+extern struct pcmcia_low_level *pcmcia_low_level;
-+
-+#endif /* __ASSEMBLY__ */
-+
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/pxa-regs.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,1327 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/pxa-regs.h
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Jun 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#ifndef _PXA_REGS_H_
-+#define _PXA_REGS_H_
-+
-+#include "bitfield.h"
-+
-+
-+// FIXME hack so that SA-1111.h will work [cb]
-+
-+#ifndef __ASSEMBLY__
-+typedef unsigned short Word16 ;
-+typedef unsigned int Word32 ;
-+typedef Word32 Word ;
-+typedef Word Quad [4] ;
-+typedef void *Address ;
-+typedef void (*ExcpHndlr) (void) ;
-+#endif
-+
-+/*
-+ * PXA Chip selects
-+ */
-+
-+#define PXA_CS0_PHYS 0x00000000
-+#define PXA_CS1_PHYS 0x04000000
-+#define PXA_CS2_PHYS 0x08000000
-+#define PXA_CS3_PHYS 0x0C000000
-+#define PXA_CS4_PHYS 0x10000000
-+#define PXA_CS5_PHYS 0x14000000
-+
-+
-+/*
-+ * Personal Computer Memory Card International Association (PCMCIA) sockets
-+ */
-+
-+#define PCMCIAPrtSp 0x04000000 /* PCMCIA Partition Space [byte] */
-+#define PCMCIASp (4*PCMCIAPrtSp) /* PCMCIA Space [byte] */
-+#define PCMCIAIOSp PCMCIAPrtSp /* PCMCIA I/O Space [byte] */
-+#define PCMCIAAttrSp PCMCIAPrtSp /* PCMCIA Attribute Space [byte] */
-+#define PCMCIAMemSp PCMCIAPrtSp /* PCMCIA Memory Space [byte] */
-+
-+#define PCMCIA0Sp PCMCIASp /* PCMCIA 0 Space [byte] */
-+#define PCMCIA0IOSp PCMCIAIOSp /* PCMCIA 0 I/O Space [byte] */
-+#define PCMCIA0AttrSp PCMCIAAttrSp /* PCMCIA 0 Attribute Space [byte] */
-+#define PCMCIA0MemSp PCMCIAMemSp /* PCMCIA 0 Memory Space [byte] */
-+
-+#define PCMCIA1Sp PCMCIASp /* PCMCIA 1 Space [byte] */
-+#define PCMCIA1IOSp PCMCIAIOSp /* PCMCIA 1 I/O Space [byte] */
-+#define PCMCIA1AttrSp PCMCIAAttrSp /* PCMCIA 1 Attribute Space [byte] */
-+#define PCMCIA1MemSp PCMCIAMemSp /* PCMCIA 1 Memory Space [byte] */
-+
-+#define _PCMCIA(Nb) /* PCMCIA [0..1] */ \
-+ (0x20000000 + (Nb)*PCMCIASp)
-+#define _PCMCIAIO(Nb) _PCMCIA (Nb) /* PCMCIA I/O [0..1] */
-+#define _PCMCIAAttr(Nb) /* PCMCIA Attribute [0..1] */ \
-+ (_PCMCIA (Nb) + 2*PCMCIAPrtSp)
-+#define _PCMCIAMem(Nb) /* PCMCIA Memory [0..1] */ \
-+ (_PCMCIA (Nb) + 3*PCMCIAPrtSp)
-+
-+#define _PCMCIA0 _PCMCIA (0) /* PCMCIA 0 */
-+#define _PCMCIA0IO _PCMCIAIO (0) /* PCMCIA 0 I/O */
-+#define _PCMCIA0Attr _PCMCIAAttr (0) /* PCMCIA 0 Attribute */
-+#define _PCMCIA0Mem _PCMCIAMem (0) /* PCMCIA 0 Memory */
-+
-+#define _PCMCIA1 _PCMCIA (1) /* PCMCIA 1 */
-+#define _PCMCIA1IO _PCMCIAIO (1) /* PCMCIA 1 I/O */
-+#define _PCMCIA1Attr _PCMCIAAttr (1) /* PCMCIA 1 Attribute */
-+#define _PCMCIA1Mem _PCMCIAMem (1) /* PCMCIA 1 Memory */
-+
-+
-+
-+/*
-+ * DMA Controller
-+ */
-+
-+#define DCSR0 __REG(0x40000000) /* DMA Control / Status Register for Channel 0 */
-+#define DCSR1 __REG(0x40000004) /* DMA Control / Status Register for Channel 1 */
-+#define DCSR2 __REG(0x40000008) /* DMA Control / Status Register for Channel 2 */
-+#define DCSR3 __REG(0x4000000c) /* DMA Control / Status Register for Channel 3 */
-+#define DCSR4 __REG(0x40000010) /* DMA Control / Status Register for Channel 4 */
-+#define DCSR5 __REG(0x40000014) /* DMA Control / Status Register for Channel 5 */
-+#define DCSR6 __REG(0x40000018) /* DMA Control / Status Register for Channel 6 */
-+#define DCSR7 __REG(0x4000001c) /* DMA Control / Status Register for Channel 7 */
-+#define DCSR8 __REG(0x40000020) /* DMA Control / Status Register for Channel 8 */
-+#define DCSR9 __REG(0x40000024) /* DMA Control / Status Register for Channel 9 */
-+#define DCSR10 __REG(0x40000028) /* DMA Control / Status Register for Channel 10 */
-+#define DCSR11 __REG(0x4000002c) /* DMA Control / Status Register for Channel 11 */
-+#define DCSR12 __REG(0x40000030) /* DMA Control / Status Register for Channel 12 */
-+#define DCSR13 __REG(0x40000034) /* DMA Control / Status Register for Channel 13 */
-+#define DCSR14 __REG(0x40000038) /* DMA Control / Status Register for Channel 14 */
-+#define DCSR15 __REG(0x4000003c) /* DMA Control / Status Register for Channel 15 */
-+
-+#define DCSR(x) __REG2(0x40000000, (x) << 2)
-+
-+#define DCSR_RUN (1 << 31) /* Run Bit (read / write) */
-+#define DCSR_NODESC (1 << 30) /* No-Descriptor Fetch (read / write) */
-+#define DCSR_STOPIRQEN (1 << 29) /* Stop Interrupt Enable (read / write) */
-+#define DCSR_REQPEND (1 << 8) /* Request Pending (read-only) */
-+#define DCSR_STOPSTATE (1 << 3) /* Stop State (read-only) */
-+#define DCSR_ENDINTR (1 << 2) /* End Interrupt (read / write) */
-+#define DCSR_STARTINTR (1 << 1) /* Start Interrupt (read / write) */
-+#define DCSR_BUSERR (1 << 0) /* Bus Error Interrupt (read / write) */
-+
-+#define DINT __REG(0x400000f0) /* DMA Interrupt Register */
-+
-+#define DRCMR0 __REG(0x40000100) /* Request to Channel Map Register for DREQ 0 */
-+#define DRCMR1 __REG(0x40000104) /* Request to Channel Map Register for DREQ 1 */
-+#define DRCMR2 __REG(0x40000108) /* Request to Channel Map Register for I2S receive Request */
-+#define DRCMR3 __REG(0x4000010c) /* Request to Channel Map Register for I2S transmit Request */
-+#define DRCMR4 __REG(0x40000110) /* Request to Channel Map Register for BTUART receive Request */
-+#define DRCMR5 __REG(0x40000114) /* Request to Channel Map Register for BTUART transmit Request. */
-+#define DRCMR6 __REG(0x40000118) /* Request to Channel Map Register for FFUART receive Request */
-+#define DRCMR7 __REG(0x4000011c) /* Request to Channel Map Register for FFUART transmit Request */
-+#define DRCMR8 __REG(0x40000120) /* Request to Channel Map Register for AC97 microphone Request */
-+#define DRCMR9 __REG(0x40000124) /* Request to Channel Map Register for AC97 modem receive Request */
-+#define DRCMR10 __REG(0x40000128) /* Request to Channel Map Register for AC97 modem transmit Request */
-+#define DRCMR11 __REG(0x4000012c) /* Request to Channel Map Register for AC97 audio receive Request */
-+#define DRCMR12 __REG(0x40000130) /* Request to Channel Map Register for AC97 audio transmit Request */
-+#define DRCMR13 __REG(0x40000134) /* Request to Channel Map Register for SSP receive Request */
-+#define DRCMR14 __REG(0x40000138) /* Request to Channel Map Register for SSP transmit Request */
-+#define DRCMR15 __REG(0x4000013c) /* Reserved */
-+#define DRCMR16 __REG(0x40000140) /* Reserved */
-+#define DRCMR17 __REG(0x40000144) /* Request to Channel Map Register for ICP receive Request */
-+#define DRCMR18 __REG(0x40000148) /* Request to Channel Map Register for ICP transmit Request */
-+#define DRCMR19 __REG(0x4000014c) /* Request to Channel Map Register for STUART receive Request */
-+#define DRCMR20 __REG(0x40000150) /* Request to Channel Map Register for STUART transmit Request */
-+#define DRCMR21 __REG(0x40000154) /* Request to Channel Map Register for MMC receive Request */
-+#define DRCMR22 __REG(0x40000158) /* Request to Channel Map Register for MMC transmit Request */
-+#define DRCMR23 __REG(0x4000015c) /* Reserved */
-+#define DRCMR24 __REG(0x40000160) /* Reserved */
-+#define DRCMR25 __REG(0x40000164) /* Request to Channel Map Register for USB endpoint 1 Request */
-+#define DRCMR26 __REG(0x40000168) /* Request to Channel Map Register for USB endpoint 2 Request */
-+#define DRCMR27 __REG(0x4000016C) /* Request to Channel Map Register for USB endpoint 3 Request */
-+#define DRCMR28 __REG(0x40000170) /* Request to Channel Map Register for USB endpoint 4 Request */
-+#define DRCMR29 __REG(0x40000174) /* Reserved */
-+#define DRCMR30 __REG(0x40000178) /* Request to Channel Map Register for USB endpoint 6 Request */
-+#define DRCMR31 __REG(0x4000017C) /* Request to Channel Map Register for USB endpoint 7 Request */
-+#define DRCMR32 __REG(0x40000180) /* Request to Channel Map Register for USB endpoint 8 Request */
-+#define DRCMR33 __REG(0x40000184) /* Request to Channel Map Register for USB endpoint 9 Request */
-+#define DRCMR34 __REG(0x40000188) /* Reserved */
-+#define DRCMR35 __REG(0x4000018C) /* Request to Channel Map Register for USB endpoint 11 Request */
-+#define DRCMR36 __REG(0x40000190) /* Request to Channel Map Register for USB endpoint 12 Request */
-+#define DRCMR37 __REG(0x40000194) /* Request to Channel Map Register for USB endpoint 13 Request */
-+#define DRCMR38 __REG(0x40000198) /* Request to Channel Map Register for USB endpoint 14 Request */
-+#define DRCMR39 __REG(0x4000019C) /* Reserved */
-+
-+#define DRCMRRXSADR DRCMR2
-+#define DRCMRTXSADR DRCMR3
-+#define DRCMRRXBTRBR DRCMR4
-+#define DRCMRTXBTTHR DRCMR5
-+#define DRCMRRXFFRBR DRCMR6
-+#define DRCMRTXFFTHR DRCMR7
-+#define DRCMRRXMCDR DRCMR8
-+#define DRCMRRXMODR DRCMR9
-+#define DRCMRTXMODR DRCMR10
-+#define DRCMRRXPCDR DRCMR11
-+#define DRCMRTXPCDR DRCMR12
-+#define DRCMRRXSSDR DRCMR13
-+#define DRCMRTXSSDR DRCMR14
-+#define DRCMRRXICDR DRCMR17
-+#define DRCMRTXICDR DRCMR18
-+#define DRCMRRXSTRBR DRCMR19
-+#define DRCMRTXSTTHR DRCMR20
-+#define DRCMRRXMMC DRCMR21
-+#define DRCMRTXMMC DRCMR22
-+
-+#define DRCMR_MAPVLD (1 << 7) /* Map Valid (read / write) */
-+#define DRCMR_CHLNUM 0x0f /* mask for Channel Number (read / write) */
-+
-+#define DDADR0 __REG(0x40000200) /* DMA Descriptor Address Register Channel 0 */
-+#define DSADR0 __REG(0x40000204) /* DMA Source Address Register Channel 0 */
-+#define DTADR0 __REG(0x40000208) /* DMA Target Address Register Channel 0 */
-+#define DCMD0 __REG(0x4000020c) /* DMA Command Address Register Channel 0 */
-+#define DDADR1 __REG(0x40000210) /* DMA Descriptor Address Register Channel 1 */
-+#define DSADR1 __REG(0x40000214) /* DMA Source Address Register Channel 1 */
-+#define DTADR1 __REG(0x40000218) /* DMA Target Address Register Channel 1 */
-+#define DCMD1 __REG(0x4000021c) /* DMA Command Address Register Channel 1 */
-+#define DDADR2 __REG(0x40000220) /* DMA Descriptor Address Register Channel 2 */
-+#define DSADR2 __REG(0x40000224) /* DMA Source Address Register Channel 2 */
-+#define DTADR2 __REG(0x40000228) /* DMA Target Address Register Channel 2 */
-+#define DCMD2 __REG(0x4000022c) /* DMA Command Address Register Channel 2 */
-+#define DDADR3 __REG(0x40000230) /* DMA Descriptor Address Register Channel 3 */
-+#define DSADR3 __REG(0x40000234) /* DMA Source Address Register Channel 3 */
-+#define DTADR3 __REG(0x40000238) /* DMA Target Address Register Channel 3 */
-+#define DCMD3 __REG(0x4000023c) /* DMA Command Address Register Channel 3 */
-+#define DDADR4 __REG(0x40000240) /* DMA Descriptor Address Register Channel 4 */
-+#define DSADR4 __REG(0x40000244) /* DMA Source Address Register Channel 4 */
-+#define DTADR4 __REG(0x40000248) /* DMA Target Address Register Channel 4 */
-+#define DCMD4 __REG(0x4000024c) /* DMA Command Address Register Channel 4 */
-+#define DDADR5 __REG(0x40000250) /* DMA Descriptor Address Register Channel 5 */
-+#define DSADR5 __REG(0x40000254) /* DMA Source Address Register Channel 5 */
-+#define DTADR5 __REG(0x40000258) /* DMA Target Address Register Channel 5 */
-+#define DCMD5 __REG(0x4000025c) /* DMA Command Address Register Channel 5 */
-+#define DDADR6 __REG(0x40000260) /* DMA Descriptor Address Register Channel 6 */
-+#define DSADR6 __REG(0x40000264) /* DMA Source Address Register Channel 6 */
-+#define DTADR6 __REG(0x40000268) /* DMA Target Address Register Channel 6 */
-+#define DCMD6 __REG(0x4000026c) /* DMA Command Address Register Channel 6 */
-+#define DDADR7 __REG(0x40000270) /* DMA Descriptor Address Register Channel 7 */
-+#define DSADR7 __REG(0x40000274) /* DMA Source Address Register Channel 7 */
-+#define DTADR7 __REG(0x40000278) /* DMA Target Address Register Channel 7 */
-+#define DCMD7 __REG(0x4000027c) /* DMA Command Address Register Channel 7 */
-+#define DDADR8 __REG(0x40000280) /* DMA Descriptor Address Register Channel 8 */
-+#define DSADR8 __REG(0x40000284) /* DMA Source Address Register Channel 8 */
-+#define DTADR8 __REG(0x40000288) /* DMA Target Address Register Channel 8 */
-+#define DCMD8 __REG(0x4000028c) /* DMA Command Address Register Channel 8 */
-+#define DDADR9 __REG(0x40000290) /* DMA Descriptor Address Register Channel 9 */
-+#define DSADR9 __REG(0x40000294) /* DMA Source Address Register Channel 9 */
-+#define DTADR9 __REG(0x40000298) /* DMA Target Address Register Channel 9 */
-+#define DCMD9 __REG(0x4000029c) /* DMA Command Address Register Channel 9 */
-+#define DDADR10 __REG(0x400002a0) /* DMA Descriptor Address Register Channel 10 */
-+#define DSADR10 __REG(0x400002a4) /* DMA Source Address Register Channel 10 */
-+#define DTADR10 __REG(0x400002a8) /* DMA Target Address Register Channel 10 */
-+#define DCMD10 __REG(0x400002ac) /* DMA Command Address Register Channel 10 */
-+#define DDADR11 __REG(0x400002b0) /* DMA Descriptor Address Register Channel 11 */
-+#define DSADR11 __REG(0x400002b4) /* DMA Source Address Register Channel 11 */
-+#define DTADR11 __REG(0x400002b8) /* DMA Target Address Register Channel 11 */
-+#define DCMD11 __REG(0x400002bc) /* DMA Command Address Register Channel 11 */
-+#define DDADR12 __REG(0x400002c0) /* DMA Descriptor Address Register Channel 12 */
-+#define DSADR12 __REG(0x400002c4) /* DMA Source Address Register Channel 12 */
-+#define DTADR12 __REG(0x400002c8) /* DMA Target Address Register Channel 12 */
-+#define DCMD12 __REG(0x400002cc) /* DMA Command Address Register Channel 12 */
-+#define DDADR13 __REG(0x400002d0) /* DMA Descriptor Address Register Channel 13 */
-+#define DSADR13 __REG(0x400002d4) /* DMA Source Address Register Channel 13 */
-+#define DTADR13 __REG(0x400002d8) /* DMA Target Address Register Channel 13 */
-+#define DCMD13 __REG(0x400002dc) /* DMA Command Address Register Channel 13 */
-+#define DDADR14 __REG(0x400002e0) /* DMA Descriptor Address Register Channel 14 */
-+#define DSADR14 __REG(0x400002e4) /* DMA Source Address Register Channel 14 */
-+#define DTADR14 __REG(0x400002e8) /* DMA Target Address Register Channel 14 */
-+#define DCMD14 __REG(0x400002ec) /* DMA Command Address Register Channel 14 */
-+#define DDADR15 __REG(0x400002f0) /* DMA Descriptor Address Register Channel 15 */
-+#define DSADR15 __REG(0x400002f4) /* DMA Source Address Register Channel 15 */
-+#define DTADR15 __REG(0x400002f8) /* DMA Target Address Register Channel 15 */
-+#define DCMD15 __REG(0x400002fc) /* DMA Command Address Register Channel 15 */
-+
-+#define DDADR(x) __REG2(0x40000200, (x) << 4)
-+#define DSADR(x) __REG2(0x40000204, (x) << 4)
-+#define DTADR(x) __REG2(0x40000208, (x) << 4)
-+#define DCMD(x) __REG2(0x4000020c, (x) << 4)
-+
-+#define DDADR_DESCADDR 0xfffffff0 /* Address of next descriptor (mask) */
-+#define DDADR_STOP (1 << 0) /* Stop (read / write) */
-+
-+#define DCMD_INCSRCADDR (1 << 31) /* Source Address Increment Setting. */
-+#define DCMD_INCTRGADDR (1 << 30) /* Target Address Increment Setting. */
-+#define DCMD_FLOWSRC (1 << 29) /* Flow Control by the source. */
-+#define DCMD_FLOWTRG (1 << 28) /* Flow Control by the target. */
-+#define DCMD_STARTIRQEN (1 << 22) /* Start Interrupt Enable */
-+#define DCMD_ENDIRQEN (1 << 21) /* End Interrupt Enable */
-+#define DCMD_ENDIAN (1 << 18) /* Device Endian-ness. */
-+#define DCMD_BURST8 (1 << 16) /* 8 byte burst */
-+#define DCMD_BURST16 (2 << 16) /* 16 byte burst */
-+#define DCMD_BURST32 (3 << 16) /* 32 byte burst */
-+#define DCMD_WIDTH1 (1 << 14) /* 1 byte width */
-+#define DCMD_WIDTH2 (2 << 14) /* 2 byte width (HalfWord) */
-+#define DCMD_WIDTH4 (3 << 14) /* 4 byte width (Word) */
-+#define DCMD_LENGTH 0x01fff /* length mask (max = 8K - 1) */
-+
-+/* default combinations */
-+#define DCMD_RXPCDR (DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4)
-+#define DCMD_RXMCDR (DCMD_INCTRGADDR|DCMD_FLOWSRC|DCMD_BURST32|DCMD_WIDTH4)
-+#define DCMD_TXPCDR (DCMD_INCSRCADDR|DCMD_FLOWTRG|DCMD_BURST32|DCMD_WIDTH4)
-+
-+
-+/*
-+ * UARTs
-+ */
-+
-+/* Full Function UART (FFUART) */
-+#define FFUART FFRBR
-+#define FFRBR __REG(0x40100000) /* Receive Buffer Register (read only) */
-+#define FFTHR __REG(0x40100000) /* Transmit Holding Register (write only) */
-+#define FFIER __REG(0x40100004) /* Interrupt Enable Register (read/write) */
-+#define FFIIR __REG(0x40100008) /* Interrupt ID Register (read only) */
-+#define FFFCR __REG(0x40100008) /* FIFO Control Register (write only) */
-+#define FFLCR __REG(0x4010000C) /* Line Control Register (read/write) */
-+#define FFMCR __REG(0x40100010) /* Modem Control Register (read/write) */
-+#define FFLSR __REG(0x40100014) /* Line Status Register (read only) */
-+#define FFMSR __REG(0x40100018) /* Modem Status Register (read only) */
-+#define FFSPR __REG(0x4010001C) /* Scratch Pad Register (read/write) */
-+#define FFISR __REG(0x40100020) /* Infrared Selection Register (read/write) */
-+#define FFDLL __REG(0x40100000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
-+#define FFDLH __REG(0x40100004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
-+
-+/* Bluetooth UART (BTUART) */
-+#define BTUART BTRBR
-+#define BTRBR __REG(0x40200000) /* Receive Buffer Register (read only) */
-+#define BTTHR __REG(0x40200000) /* Transmit Holding Register (write only) */
-+#define BTIER __REG(0x40200004) /* Interrupt Enable Register (read/write) */
-+#define BTIIR __REG(0x40200008) /* Interrupt ID Register (read only) */
-+#define BTFCR __REG(0x40200008) /* FIFO Control Register (write only) */
-+#define BTLCR __REG(0x4020000C) /* Line Control Register (read/write) */
-+#define BTMCR __REG(0x40200010) /* Modem Control Register (read/write) */
-+#define BTLSR __REG(0x40200014) /* Line Status Register (read only) */
-+#define BTMSR __REG(0x40200018) /* Modem Status Register (read only) */
-+#define BTSPR __REG(0x4020001C) /* Scratch Pad Register (read/write) */
-+#define BTISR __REG(0x40200020) /* Infrared Selection Register (read/write) */
-+#define BTDLL __REG(0x40200000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
-+#define BTDLH __REG(0x40200004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
-+
-+/* Standard UART (STUART) */
-+#define STUART STRBR
-+#define STRBR __REG(0x40700000) /* Receive Buffer Register (read only) */
-+#define STTHR __REG(0x40700000) /* Transmit Holding Register (write only) */
-+#define STIER __REG(0x40700004) /* Interrupt Enable Register (read/write) */
-+#define STIIR __REG(0x40700008) /* Interrupt ID Register (read only) */
-+#define STFCR __REG(0x40700008) /* FIFO Control Register (write only) */
-+#define STLCR __REG(0x4070000C) /* Line Control Register (read/write) */
-+#define STMCR __REG(0x40700010) /* Modem Control Register (read/write) */
-+#define STLSR __REG(0x40700014) /* Line Status Register (read only) */
-+#define STMSR __REG(0x40700018) /* Reserved */
-+#define STSPR __REG(0x4070001C) /* Scratch Pad Register (read/write) */
-+#define STISR __REG(0x40700020) /* Infrared Selection Register (read/write) */
-+#define STDLL __REG(0x40700000) /* Divisor Latch Low Register (DLAB = 1) (read/write) */
-+#define STDLH __REG(0x40700004) /* Divisor Latch High Register (DLAB = 1) (read/write) */
-+
-+#define IER_DMAE (1 << 7) /* DMA Requests Enable */
-+#define IER_UUE (1 << 6) /* UART Unit Enable */
-+#define IER_NRZE (1 << 5) /* NRZ coding Enable */
-+#define IER_RTIOE (1 << 4) /* Receiver Time Out Interrupt Enable */
-+#define IER_MIE (1 << 3) /* Modem Interrupt Enable */
-+#define IER_RLSE (1 << 2) /* Receiver Line Status Interrupt Enable */
-+#define IER_TIE (1 << 1) /* Transmit Data request Interrupt Enable */
-+#define IER_RAVIE (1 << 0) /* Receiver Data Available Interrupt Enable */
-+
-+#define IIR_FIFOES1 (1 << 7) /* FIFO Mode Enable Status */
-+#define IIR_FIFOES0 (1 << 6) /* FIFO Mode Enable Status */
-+#define IIR_TOD (1 << 3) /* Time Out Detected */
-+#define IIR_IID2 (1 << 2) /* Interrupt Source Encoded */
-+#define IIR_IID1 (1 << 1) /* Interrupt Source Encoded */
-+#define IIR_IP (1 << 0) /* Interrupt Pending (active low) */
-+
-+#define FCR_ITL2 (1 << 7) /* Interrupt Trigger Level */
-+#define FCR_ITL1 (1 << 6) /* Interrupt Trigger Level */
-+#define FCR_RESETTF (1 << 2) /* Reset Transmitter FIFO */
-+#define FCR_RESETRF (1 << 1) /* Reset Receiver FIFO */
-+#define FCR_TRFIFOE (1 << 0) /* Transmit and Receive FIFO Enable */
-+#define FCR_ITL_1 (0)
-+#define FCR_ITL_8 (FCR_ITL1)
-+#define FCR_ITL_16 (FCR_ITL2)
-+#define FCR_ITL_32 (FCR_ITL2|FCR_ITL1)
-+
-+#define LCR_DLAB (1 << 7) /* Divisor Latch Access Bit */
-+#define LCR_SB (1 << 6) /* Set Break */
-+#define LCR_STKYP (1 << 5) /* Sticky Parity */
-+#define LCR_EPS (1 << 4) /* Even Parity Select */
-+#define LCR_PEN (1 << 3) /* Parity Enable */
-+#define LCR_STB (1 << 2) /* Stop Bit */
-+#define LCR_WLS1 (1 << 1) /* Word Length Select */
-+#define LCR_WLS0 (1 << 0) /* Word Length Select */
-+
-+#define LSR_FIFOE (1 << 7) /* FIFO Error Status */
-+#define LSR_TEMT (1 << 6) /* Transmitter Empty */
-+#define LSR_TDRQ (1 << 5) /* Transmit Data Request */
-+#define LSR_BI (1 << 4) /* Break Interrupt */
-+#define LSR_FE (1 << 3) /* Framing Error */
-+#define LSR_PE (1 << 2) /* Parity Error */
-+#define LSR_OE (1 << 1) /* Overrun Error */
-+#define LSR_DR (1 << 0) /* Data Ready */
-+
-+#define MCR_LOOP (1 << 4) */
-+#define MCR_OUT2 (1 << 3) /* force MSR_DCD in loopback mode */
-+#define MCR_OUT1 (1 << 2) /* force MSR_RI in loopback mode */
-+#define MCR_RTS (1 << 1) /* Request to Send */
-+#define MCR_DTR (1 << 0) /* Data Terminal Ready */
-+
-+#define MSR_DCD (1 << 7) /* Data Carrier Detect */
-+#define MSR_RI (1 << 6) /* Ring Indicator */
-+#define MSR_DSR (1 << 5) /* Data Set Ready */
-+#define MSR_CTS (1 << 4) /* Clear To Send */
-+#define MSR_DDCD (1 << 3) /* Delta Data Carrier Detect */
-+#define MSR_TERI (1 << 2) /* Trailing Edge Ring Indicator */
-+#define MSR_DDSR (1 << 1) /* Delta Data Set Ready */
-+#define MSR_DCTS (1 << 0) /* Delta Clear To Send */
-+
-+/*
-+ * IrSR (Infrared Selection Register)
-+ */
-+#define STISR_RXPL (1 << 4) /* Receive Data Polarity */
-+#define STISR_TXPL (1 << 3) /* Transmit Data Polarity */
-+#define STISR_XMODE (1 << 2) /* Transmit Pulse Width Select */
-+#define STISR_RCVEIR (1 << 1) /* Receiver SIR Enable */
-+#define STISR_XMITIR (1 << 0) /* Transmitter SIR Enable */
-+
-+
-+/*
-+ * I2C registers
-+ */
-+
-+#define IBMR __REG(0x40301680) /* I2C Bus Monitor Register - IBMR */
-+#define IDBR __REG(0x40301688) /* I2C Data Buffer Register - IDBR */
-+#define ICR __REG(0x40301690) /* I2C Control Register - ICR */
-+#define ISR __REG(0x40301698) /* I2C Status Register - ISR */
-+#define ISAR __REG(0x403016A0) /* I2C Slave Address Register - ISAR */
-+
-+#define ICR_START (1 << 0) /* start bit */
-+#define ICR_STOP (1 << 1) /* stop bit */
-+#define ICR_ACKNAK (1 << 2) /* send ACK(0) or NAK(1) */
-+#define ICR_TB (1 << 3) /* transfer byte bit */
-+#define ICR_MA (1 << 4) /* master abort */
-+#define ICR_SCLE (1 << 5) /* master clock enable */
-+#define ICR_IUE (1 << 6) /* unit enable */
-+#define ICR_GCD (1 << 7) /* general call disable */
-+#define ICR_ITEIE (1 << 8) /* enable tx interrupts */
-+#define ICR_IRFIE (1 << 9) /* enable rx interrupts */
-+#define ICR_BEIE (1 << 10) /* enable bus error ints */
-+#define ICR_SSDIE (1 << 11) /* slave STOP detected int enable */
-+#define ICR_ALDIE (1 << 12) /* enable arbitration interrupt */
-+#define ICR_SADIE (1 << 13) /* slave address detected int enable */
-+#define ICR_UR (1 << 14) /* unit reset */
-+
-+#define ISR_RWM (1 << 0) /* read/write mode */
-+#define ISR_ACKNAK (1 << 1) /* ack/nak status */
-+#define ISR_UB (1 << 2) /* unit busy */
-+#define ISR_IBB (1 << 3) /* bus busy */
-+#define ISR_SSD (1 << 4) /* slave stop detected */
-+#define ISR_ALD (1 << 5) /* arbitration loss detected */
-+#define ISR_ITE (1 << 6) /* tx buffer empty */
-+#define ISR_IRF (1 << 7) /* rx buffer full */
-+#define ISR_GCAD (1 << 8) /* general call address detected */
-+#define ISR_SAD (1 << 9) /* slave address detected */
-+#define ISR_BED (1 << 10) /* bus error no ACK/NAK */
-+
-+
-+/*
-+ * Serial Audio Controller
-+ */
-+
-+/* FIXME: This clash with SA1111 defines */
-+#ifndef CONFIG_SA1111
-+#define SACR0 __REG(0x40400000) /* Global Control Register */
-+#define SACR1 __REG(0x40400004) /* Serial Audio I 2 S/MSB-Justified Control Register */
-+#define SASR0 __REG(0x4040000C) /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */
-+#define SAIMR __REG(0x40400014) /* Serial Audio Interrupt Mask Register */
-+#define SAICR __REG(0x40400018) /* Serial Audio Interrupt Clear Register */
-+#define SADIV __REG(0x40400060) /* Audio Clock Divider Register. */
-+#define SADR __REG(0x40400080) /* Serial Audio Data Register (TX and RX FIFO access Register). */
-+#endif
-+
-+
-+/*
-+ * AC97 Controller registers
-+ */
-+
-+#define POCR __REG(0x40500000) /* PCM Out Control Register */
-+#define POCR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */
-+
-+#define PICR __REG(0x40500004) /* PCM In Control Register */
-+#define PICR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */
-+
-+#define MCCR __REG(0x40500008) /* Mic In Control Register */
-+#define MCCR_FEIE (1 << 3) /* FIFO Error Interrupt Enable */
-+
-+#define GCR __REG(0x4050000C) /* Global Control Register */
-+#define GCR_CDONE_IE (1 << 19) /* Command Done Interrupt Enable */
-+#define GCR_SDONE_IE (1 << 18) /* Status Done Interrupt Enable */
-+#define GCR_SECRDY_IEN (1 << 9) /* Secondary Ready Interrupt Enable */
-+#define GCR_PRIRDY_IEN (1 << 8) /* Primary Ready Interrupt Enable */
-+#define GCR_SECRES_IEN (1 << 5) /* Secondary Resume Interrupt Enable */
-+#define GCR_PRIRES_IEN (1 << 4) /* Primary Resume Interrupt Enable */
-+#define GCR_ACLINK_OFF (1 << 3) /* AC-link Shut Off */
-+#define GCR_WARM_RST (1 << 2) /* AC97 Warm Reset */
-+#define GCR_COLD_RST (1 << 1) /* AC'97 Cold Reset (0 = active) */
-+#define GCR_GIE (1 << 0) /* Codec GPI Interrupt Enable */
-+
-+#define POSR __REG(0x40500010) /* PCM Out Status Register */
-+#define POSR_FIFOE (1 << 4) /* FIFO error */
-+
-+#define PISR __REG(0x40500014) /* PCM In Status Register */
-+#define PISR_FIFOE (1 << 4) /* FIFO error */
-+
-+#define MCSR __REG(0x40500018) /* Mic In Status Register */
-+#define MCSR_FIFOE (1 << 4) /* FIFO error */
-+
-+#define GSR __REG(0x4050001C) /* Global Status Register */
-+#define GSR_CDONE (1 << 19) /* Command Done */
-+#define GSR_SDONE (1 << 18) /* Status Done */
-+#define GSR_RDCS (1 << 15) /* Read Completion Status */
-+#define GSR_BIT3SLT12 (1 << 14) /* Bit 3 of slot 12 */
-+#define GSR_BIT2SLT12 (1 << 13) /* Bit 2 of slot 12 */
-+#define GSR_BIT1SLT12 (1 << 12) /* Bit 1 of slot 12 */
-+#define GSR_SECRES (1 << 11) /* Secondary Resume Interrupt */
-+#define GSR_PRIRES (1 << 10) /* Primary Resume Interrupt */
-+#define GSR_SCR (1 << 9) /* Secondary Codec Ready */
-+#define GSR_PCR (1 << 8) /* Primary Codec Ready */
-+#define GSR_MINT (1 << 7) /* Mic In Interrupt */
-+#define GSR_POINT (1 << 6) /* PCM Out Interrupt */
-+#define GSR_PIINT (1 << 5) /* PCM In Interrupt */
-+#define GSR_MOINT (1 << 2) /* Modem Out Interrupt */
-+#define GSR_MIINT (1 << 1) /* Modem In Interrupt */
-+#define GSR_GSCI (1 << 0) /* Codec GPI Status Change Interrupt */
-+
-+#define CAR __REG(0x40500020) /* CODEC Access Register */
-+#define CAR_CAIP (1 << 0) /* Codec Access In Progress */
-+
-+#define PCDR __REG(0x40500040) /* PCM FIFO Data Register */
-+#define MCDR __REG(0x40500060) /* Mic-in FIFO Data Register */
-+
-+#define MOCR __REG(0x40500100) /* Modem Out Control Register */
-+#define MOCR_FEIE (1 << 3) /* FIFO Error */
-+
-+#define MICR __REG(0x40500108) /* Modem In Control Register */
-+#define MICR_FEIE (1 << 3) /* FIFO Error */
-+
-+#define MOSR __REG(0x40500110) /* Modem Out Status Register */
-+#define MOSR_FIFOE (1 << 4) /* FIFO error */
-+
-+#define MISR __REG(0x40500118) /* Modem In Status Register */
-+#define MISR_FIFOE (1 << 4) /* FIFO error */
-+
-+#define MODR __REG(0x40500140) /* Modem FIFO Data Register */
-+
-+#define PAC_REG_BASE __REG(0x40500200) /* Primary Audio Codec */
-+#define SAC_REG_BASE __REG(0x40500300) /* Secondary Audio Codec */
-+#define PMC_REG_BASE __REG(0x40500400) /* Primary Modem Codec */
-+#define SMC_REG_BASE __REG(0x40500500) /* Secondary Modem Codec */
-+
-+
-+/*
-+ * USB Device Controller
-+ */
-+#define UDC_RES1 __REG(0x40600004) /* UDC Undocumented - Reserved1 */
-+#define UDC_RES2 __REG(0x40600008) /* UDC Undocumented - Reserved2 */
-+#define UDC_RES3 __REG(0x4060000C) /* UDC Undocumented - Reserved3 */
-+
-+#define UDCCR __REG(0x40600000) /* UDC Control Register */
-+#define UDCCR_UDE (1 << 0) /* UDC enable */
-+#define UDCCR_UDA (1 << 1) /* UDC active */
-+#define UDCCR_RSM (1 << 2) /* Device resume */
-+#define UDCCR_RESIR (1 << 3) /* Resume interrupt request */
-+#define UDCCR_SUSIR (1 << 4) /* Suspend interrupt request */
-+#define UDCCR_SRM (1 << 5) /* Suspend/resume interrupt mask */
-+#define UDCCR_RSTIR (1 << 6) /* Reset interrupt request */
-+#define UDCCR_REM (1 << 7) /* Reset interrupt mask */
-+
-+#define UDCCS0 __REG(0x40600010) /* UDC Endpoint 0 Control/Status Register */
-+#define UDCCS0_OPR (1 << 0) /* OUT packet ready */
-+#define UDCCS0_IPR (1 << 1) /* IN packet ready */
-+#define UDCCS0_FTF (1 << 2) /* Flush Tx FIFO */
-+#define UDCCS0_DRWF (1 << 3) /* Device remote wakeup feature */
-+#define UDCCS0_SST (1 << 4) /* Sent stall */
-+#define UDCCS0_FST (1 << 5) /* Force stall */
-+#define UDCCS0_RNE (1 << 6) /* Receive FIFO no empty */
-+#define UDCCS0_SA (1 << 7) /* Setup active */
-+
-+/* Bulk IN - Endpoint 1,6,11 */
-+#define UDCCS1 __REG(0x40600014) /* UDC Endpoint 1 (IN) Control/Status Register */
-+#define UDCCS6 __REG(0x40600028) /* UDC Endpoint 6 (IN) Control/Status Register */
-+#define UDCCS11 __REG(0x4060003C) /* UDC Endpoint 11 (IN) Control/Status Register */
-+
-+#define UDCCS_BI_TFS (1 << 0) /* Transmit FIFO service */
-+#define UDCCS_BI_TPC (1 << 1) /* Transmit packet complete */
-+#define UDCCS_BI_FTF (1 << 2) /* Flush Tx FIFO */
-+#define UDCCS_BI_TUR (1 << 3) /* Transmit FIFO underrun */
-+#define UDCCS_BI_SST (1 << 4) /* Sent stall */
-+#define UDCCS_BI_FST (1 << 5) /* Force stall */
-+#define UDCCS_BI_TSP (1 << 7) /* Transmit short packet */
-+
-+/* Bulk OUT - Endpoint 2,7,12 */
-+#define UDCCS2 __REG(0x40600018) /* UDC Endpoint 2 (OUT) Control/Status Register */
-+#define UDCCS7 __REG(0x4060002C) /* UDC Endpoint 7 (OUT) Control/Status Register */
-+#define UDCCS12 __REG(0x40600040) /* UDC Endpoint 12 (OUT) Control/Status Register */
-+
-+#define UDCCS_BO_RFS (1 << 0) /* Receive FIFO service */
-+#define UDCCS_BO_RPC (1 << 1) /* Receive packet complete */
-+#define UDCCS_BO_DME (1 << 3) /* DMA enable */
-+#define UDCCS_BO_SST (1 << 4) /* Sent stall */
-+#define UDCCS_BO_FST (1 << 5) /* Force stall */
-+#define UDCCS_BO_RNE (1 << 6) /* Receive FIFO not empty */
-+#define UDCCS_BO_RSP (1 << 7) /* Receive short packet */
-+
-+/* Isochronous IN - Endpoint 3,8,13 */
-+#define UDCCS3 __REG(0x4060001C) /* UDC Endpoint 3 (IN) Control/Status Register */
-+#define UDCCS8 __REG(0x40600030) /* UDC Endpoint 8 (IN) Control/Status Register */
-+#define UDCCS13 __REG(0x40600044) /* UDC Endpoint 13 (IN) Control/Status Register */
-+
-+#define UDCCS_II_TFS (1 << 0) /* Transmit FIFO service */
-+#define UDCCS_II_TPC (1 << 1) /* Transmit packet complete */
-+#define UDCCS_II_FTF (1 << 2) /* Flush Tx FIFO */
-+#define UDCCS_II_TUR (1 << 3) /* Transmit FIFO underrun */
-+#define UDCCS_II_TSP (1 << 7) /* Transmit short packet */
-+
-+/* Isochronous OUT - Endpoint 4,9,14 */
-+#define UDCCS4 __REG(0x40600020) /* UDC Endpoint 4 (OUT) Control/Status Register */
-+#define UDCCS9 __REG(0x40600034) /* UDC Endpoint 9 (OUT) Control/Status Register */
-+#define UDCCS14 __REG(0x40600048) /* UDC Endpoint 14 (OUT) Control/Status Register */
-+
-+#define UDCCS_IO_RFS (1 << 0) /* Receive FIFO service */
-+#define UDCCS_IO_RPC (1 << 1) /* Receive packet complete */
-+#define UDCCS_IO_ROF (1 << 3) /* Receive overflow */
-+#define UDCCS_IO_DME (1 << 3) /* DMA enable */
-+#define UDCCS_IO_RNE (1 << 6) /* Receive FIFO not empty */
-+#define UDCCS_IO_RSP (1 << 7) /* Receive short packet */
-+
-+/* Interrupt IN - Endpoint 5,10,15 */
-+#define UDCCS5 __REG(0x40600024) /* UDC Endpoint 5 (Interrupt) Control/Status Register */
-+#define UDCCS10 __REG(0x40600038) /* UDC Endpoint 10 (Interrupt) Control/Status Register */
-+#define UDCCS15 __REG(0x4060004C) /* UDC Endpoint 15 (Interrupt) Control/Status Register */
-+
-+#define UDCCS_INT_TFS (1 << 0) /* Transmit FIFO service */
-+#define UDCCS_INT_TPC (1 << 1) /* Transmit packet complete */
-+#define UDCCS_INT_FTF (1 << 2) /* Flush Tx FIFO */
-+#define UDCCS_INT_TUR (1 << 3) /* Transmit FIFO underrun */
-+#define UDCCS_INT_SST (1 << 4) /* Sent stall */
-+#define UDCCS_INT_FST (1 << 5) /* Force stall */
-+#define UDCCS_INT_TSP (1 << 7) /* Transmit short packet */
-+
-+#define UFNRH __REG(0x40600060) /* UDC Frame Number Register High */
-+#define UFNRL __REG(0x40600064) /* UDC Frame Number Register Low */
-+#define UBCR2 __REG(0x40600068) /* UDC Byte Count Reg 2 */
-+#define UBCR4 __REG(0x4060006c) /* UDC Byte Count Reg 4 */
-+#define UBCR7 __REG(0x40600070) /* UDC Byte Count Reg 7 */
-+#define UBCR9 __REG(0x40600074) /* UDC Byte Count Reg 9 */
-+#define UBCR12 __REG(0x40600078) /* UDC Byte Count Reg 12 */
-+#define UBCR14 __REG(0x4060007c) /* UDC Byte Count Reg 14 */
-+#define UDDR0 __REG(0x40600080) /* UDC Endpoint 0 Data Register */
-+#define UDDR1 __REG(0x40600100) /* UDC Endpoint 1 Data Register */
-+#define UDDR2 __REG(0x40600180) /* UDC Endpoint 2 Data Register */
-+#define UDDR3 __REG(0x40600200) /* UDC Endpoint 3 Data Register */
-+#define UDDR4 __REG(0x40600400) /* UDC Endpoint 4 Data Register */
-+#define UDDR5 __REG(0x406000A0) /* UDC Endpoint 5 Data Register */
-+#define UDDR6 __REG(0x40600600) /* UDC Endpoint 6 Data Register */
-+#define UDDR7 __REG(0x40600680) /* UDC Endpoint 7 Data Register */
-+#define UDDR8 __REG(0x40600700) /* UDC Endpoint 8 Data Register */
-+#define UDDR9 __REG(0x40600900) /* UDC Endpoint 9 Data Register */
-+#define UDDR10 __REG(0x406000C0) /* UDC Endpoint 10 Data Register */
-+#define UDDR11 __REG(0x40600B00) /* UDC Endpoint 11 Data Register */
-+#define UDDR12 __REG(0x40600B80) /* UDC Endpoint 12 Data Register */
-+#define UDDR13 __REG(0x40600C00) /* UDC Endpoint 13 Data Register */
-+#define UDDR14 __REG(0x40600E00) /* UDC Endpoint 14 Data Register */
-+#define UDDR15 __REG(0x406000E0) /* UDC Endpoint 15 Data Register */
-+
-+#define UICR0 __REG(0x40600050) /* UDC Interrupt Control Register 0 */
-+
-+#define UICR0_IM0 (1 << 0) /* Interrupt mask ep 0 */
-+#define UICR0_IM1 (1 << 1) /* Interrupt mask ep 1 */
-+#define UICR0_IM2 (1 << 2) /* Interrupt mask ep 2 */
-+#define UICR0_IM3 (1 << 3) /* Interrupt mask ep 3 */
-+#define UICR0_IM4 (1 << 4) /* Interrupt mask ep 4 */
-+#define UICR0_IM5 (1 << 5) /* Interrupt mask ep 5 */
-+#define UICR0_IM6 (1 << 6) /* Interrupt mask ep 6 */
-+#define UICR0_IM7 (1 << 7) /* Interrupt mask ep 7 */
-+
-+#define UICR1 __REG(0x40600054) /* UDC Interrupt Control Register 1 */
-+
-+#define UICR1_IM8 (1 << 0) /* Interrupt mask ep 8 */
-+#define UICR1_IM9 (1 << 1) /* Interrupt mask ep 9 */
-+#define UICR1_IM10 (1 << 2) /* Interrupt mask ep 10 */
-+#define UICR1_IM11 (1 << 3) /* Interrupt mask ep 11 */
-+#define UICR1_IM12 (1 << 4) /* Interrupt mask ep 12 */
-+#define UICR1_IM13 (1 << 5) /* Interrupt mask ep 13 */
-+#define UICR1_IM14 (1 << 6) /* Interrupt mask ep 14 */
-+#define UICR1_IM15 (1 << 7) /* Interrupt mask ep 15 */
-+
-+#define USIR0 __REG(0x40600058) /* UDC Status Interrupt Register 0 */
-+
-+#define USIR0_IR0 (1 << 0) /* Interrup request ep 0 */
-+#define USIR0_IR1 (1 << 1) /* Interrup request ep 1 */
-+#define USIR0_IR2 (1 << 2) /* Interrup request ep 2 */
-+#define USIR0_IR3 (1 << 3) /* Interrup request ep 3 */
-+#define USIR0_IR4 (1 << 4) /* Interrup request ep 4 */
-+#define USIR0_IR5 (1 << 5) /* Interrup request ep 5 */
-+#define USIR0_IR6 (1 << 6) /* Interrup request ep 6 */
-+#define USIR0_IR7 (1 << 7) /* Interrup request ep 7 */
-+
-+#define USIR1 __REG(0x4060005C) /* UDC Status Interrupt Register 1 */
-+
-+#define USIR1_IR8 (1 << 0) /* Interrup request ep 8 */
-+#define USIR1_IR9 (1 << 1) /* Interrup request ep 9 */
-+#define USIR1_IR10 (1 << 2) /* Interrup request ep 10 */
-+#define USIR1_IR11 (1 << 3) /* Interrup request ep 11 */
-+#define USIR1_IR12 (1 << 4) /* Interrup request ep 12 */
-+#define USIR1_IR13 (1 << 5) /* Interrup request ep 13 */
-+#define USIR1_IR14 (1 << 6) /* Interrup request ep 14 */
-+#define USIR1_IR15 (1 << 7) /* Interrup request ep 15 */
-+
-+
-+/*
-+ * Fast Infrared Communication Port
-+ */
-+
-+#define ICCR0 __REG(0x40800000) /* ICP Control Register 0 */
-+#define ICCR1 __REG(0x40800004) /* ICP Control Register 1 */
-+#define ICCR2 __REG(0x40800008) /* ICP Control Register 2 */
-+#define ICDR __REG(0x4080000c) /* ICP Data Register */
-+#define ICSR0 __REG(0x40800014) /* ICP Status Register 0 */
-+#define ICSR1 __REG(0x40800018) /* ICP Status Register 1 */
-+
-+#define ICCR0_AME (1 << 7) /* Adress match enable */
-+#define ICCR0_TIE (1 << 6) /* Transmit FIFO interrupt enable */
-+#define ICCR0_RIE (1 << 5) /* Recieve FIFO interrupt enable */
-+#define ICCR0_RXE (1 << 4) /* Receive enable */
-+#define ICCR0_TXE (1 << 3) /* Transmit enable */
-+#define ICCR0_TUS (1 << 2) /* Transmit FIFO underrun select */
-+#define ICCR0_LBM (1 << 1) /* Loopback mode */
-+#define ICCR0_ITR (1 << 0) /* IrDA transmission */
-+
-+#define ICSR0_FRE (1 << 5) /* Framing error */
-+#define ICSR0_RFS (1 << 4) /* Receive FIFO service request */
-+#define ICSR0_TFS (1 << 3) /* Transnit FIFO service request */
-+#define ICSR0_RAB (1 << 2) /* Receiver abort */
-+#define ICSR0_TUR (1 << 1) /* Trunsmit FIFO underun */
-+#define ICSR0_EIF (1 << 0) /* End/Error in FIFO */
-+
-+#define ICSR1_ROR (1 << 6) /* Receiver FIFO underrun */
-+#define ICSR1_CRE (1 << 5) /* CRC error */
-+#define ICSR1_EOF (1 << 4) /* End of frame */
-+#define ICSR1_TNF (1 << 3) /* Transmit FIFO not full */
-+#define ICSR1_RNE (1 << 2) /* Receive FIFO not empty */
-+#define ICSR1_TBY (1 << 1) /* Tramsmiter busy flag */
-+#define ICSR1_RSY (1 << 0) /* Recevier synchronized flag */
-+
-+
-+/*
-+ * Real Time Clock
-+ */
-+
-+#define RCNR __REG(0x40900000) /* RTC Count Register */
-+#define RTAR __REG(0x40900004) /* RTC Alarm Register */
-+#define RTSR __REG(0x40900008) /* RTC Status Register */
-+#define RTTR __REG(0x4090000C) /* RTC Timer Trim Register */
-+
-+#define RTSR_HZE (1 << 3) /* HZ interrupt enable */
-+#define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */
-+#define RTSR_HZ (1 << 1) /* HZ rising-edge detected */
-+#define RTSR_AL (1 << 0) /* RTC alarm detected */
-+
-+
-+/*
-+ * OS Timer & Match Registers
-+ */
-+
-+#define OSMR0 __REG(0x40A00000) /* */
-+#define OSMR1 __REG(0x40A00004) /* */
-+#define OSMR2 __REG(0x40A00008) /* */
-+#define OSMR3 __REG(0x40A0000C) /* */
-+#define OSCR __REG(0x40A00010) /* OS Timer Counter Register */
-+#define OSSR __REG(0x40A00014) /* OS Timer Status Register */
-+#define OWER __REG(0x40A00018) /* OS Timer Watchdog Enable Register */
-+#define OIER __REG(0x40A0001C) /* OS Timer Interrupt Enable Register */
-+
-+#define OSSR_M3 (1 << 3) /* Match status channel 3 */
-+#define OSSR_M2 (1 << 2) /* Match status channel 2 */
-+#define OSSR_M1 (1 << 1) /* Match status channel 1 */
-+#define OSSR_M0 (1 << 0) /* Match status channel 0 */
-+
-+#define OWER_WME (1 << 0) /* Watchdog Match Enable */
-+
-+#define OIER_E3 (1 << 3) /* Interrupt enable channel 3 */
-+#define OIER_E2 (1 << 2) /* Interrupt enable channel 2 */
-+#define OIER_E1 (1 << 1) /* Interrupt enable channel 1 */
-+#define OIER_E0 (1 << 0) /* Interrupt enable channel 0 */
-+
-+
-+/*
-+ * Pulse Width Modulator
-+ */
-+
-+#define PWM_CTRL0 __REG(0x40B00000) /* PWM 0 Control Register */
-+#define PWM_PWDUTY0 __REG(0x40B00004) /* PWM 0 Duty Cycle Register */
-+#define PWM_PERVAL0 __REG(0x40B00008) /* PWM 0 Period Control Register */
-+
-+#define PWM_CTRL1 __REG(0x40C00000) /* PWM 1Control Register */
-+#define PWM_PWDUTY1 __REG(0x40C00004) /* PWM 1 Duty Cycle Register */
-+#define PWM_PERVAL1 __REG(0x40C00008) /* PWM 1 Period Control Register */
-+
-+
-+/*
-+ * Interrupt Controller
-+ */
-+
-+#define ICIP __REG(0x40D00000) /* Interrupt Controller IRQ Pending Register */
-+#define ICMR __REG(0x40D00004) /* Interrupt Controller Mask Register */
-+#define ICLR __REG(0x40D00008) /* Interrupt Controller Level Register */
-+#define ICFP __REG(0x40D0000C) /* Interrupt Controller FIQ Pending Register */
-+#define ICPR __REG(0x40D00010) /* Interrupt Controller Pending Register */
-+#define ICCR __REG(0x40D00014) /* Interrupt Controller Control Register */
-+
-+
-+/*
-+ * General Purpose I/O
-+ */
-+
-+#define GPLR0 __REG(0x40E00000) /* GPIO Pin-Level Register GPIO<31:0> */
-+#define GPLR1 __REG(0x40E00004) /* GPIO Pin-Level Register GPIO<63:32> */
-+#define GPLR2 __REG(0x40E00008) /* GPIO Pin-Level Register GPIO<80:64> */
-+
-+#define GPDR0 __REG(0x40E0000C) /* GPIO Pin Direction Register GPIO<31:0> */
-+#define GPDR1 __REG(0x40E00010) /* GPIO Pin Direction Register GPIO<63:32> */
-+#define GPDR2 __REG(0x40E00014) /* GPIO Pin Direction Register GPIO<80:64> */
-+
-+#define GPSR0 __REG(0x40E00018) /* GPIO Pin Output Set Register GPIO<31:0> */
-+#define GPSR1 __REG(0x40E0001C) /* GPIO Pin Output Set Register GPIO<63:32> */
-+#define GPSR2 __REG(0x40E00020) /* GPIO Pin Output Set Register GPIO<80:64> */
-+
-+#define GPCR0 __REG(0x40E00024) /* GPIO Pin Output Clear Register GPIO<31:0> */
-+#define GPCR1 __REG(0x40E00028) /* GPIO Pin Output Clear Register GPIO <63:32> */
-+#define GPCR2 __REG(0x40E0002C) /* GPIO Pin Output Clear Register GPIO <80:64> */
-+
-+#define GRER0 __REG(0x40E00030) /* GPIO Rising-Edge Detect Register GPIO<31:0> */
-+#define GRER1 __REG(0x40E00034) /* GPIO Rising-Edge Detect Register GPIO<63:32> */
-+#define GRER2 __REG(0x40E00038) /* GPIO Rising-Edge Detect Register GPIO<80:64> */
-+
-+#define GFER0 __REG(0x40E0003C) /* GPIO Falling-Edge Detect Register GPIO<31:0> */
-+#define GFER1 __REG(0x40E00040) /* GPIO Falling-Edge Detect Register GPIO<63:32> */
-+#define GFER2 __REG(0x40E00044) /* GPIO Falling-Edge Detect Register GPIO<80:64> */
-+
-+#define GEDR0 __REG(0x40E00048) /* GPIO Edge Detect Status Register GPIO<31:0> */
-+#define GEDR1 __REG(0x40E0004C) /* GPIO Edge Detect Status Register GPIO<63:32> */
-+#define GEDR2 __REG(0x40E00050) /* GPIO Edge Detect Status Register GPIO<80:64> */
-+
-+#define GAFR0_L __REG(0x40E00054) /* GPIO Alternate Function Select Register GPIO<15:0> */
-+#define GAFR0_U __REG(0x40E00058) /* GPIO Alternate Function Select Register GPIO<31:16> */
-+#define GAFR1_L __REG(0x40E0005C) /* GPIO Alternate Function Select Register GPIO<47:32> */
-+#define GAFR1_U __REG(0x40E00060) /* GPIO Alternate Function Select Register GPIO<63:48> */
-+#define GAFR2_L __REG(0x40E00064) /* GPIO Alternate Function Select Register GPIO<79:64> */
-+#define GAFR2_U __REG(0x40E00068) /* GPIO Alternate Function Select Register GPIO 80 */
-+
-+/* More handy macros. The argument is a literal GPIO number. */
-+
-+#define GPIO_bit(x) (1 << ((x) & 0x1f))
-+#define GPLR(x) __REG2(0x40E00000, ((x) & 0x60) >> 3)
-+#define GPDR(x) __REG2(0x40E0000C, ((x) & 0x60) >> 3)
-+#define GPSR(x) __REG2(0x40E00018, ((x) & 0x60) >> 3)
-+#define GPCR(x) __REG2(0x40E00024, ((x) & 0x60) >> 3)
-+#define GRER(x) __REG2(0x40E00030, ((x) & 0x60) >> 3)
-+#define GFER(x) __REG2(0x40E0003C, ((x) & 0x60) >> 3)
-+#define GEDR(x) __REG2(0x40E00048, ((x) & 0x60) >> 3)
-+#define GAFR(x) __REG2(0x40E00054, ((x) & 0x70) >> 2)
-+
-+/* GPIO alternate function assignments */
-+
-+#define GPIO1_RST 1 /* reset */
-+#define GPIO6_MMCCLK 6 /* MMC Clock */
-+#define GPIO8_48MHz 7 /* 48 MHz clock output */
-+#define GPIO8_MMCCS0 8 /* MMC Chip Select 0 */
-+#define GPIO9_MMCCS1 9 /* MMC Chip Select 1 */
-+#define GPIO10_RTCCLK 10 /* real time clock (1 Hz) */
-+#define GPIO11_3_6MHz 11 /* 3.6 MHz oscillator out */
-+#define GPIO12_32KHz 12 /* 32 kHz out */
-+#define GPIO13_MBGNT 13 /* memory controller grant */
-+#define GPIO14_MBREQ 14 /* alternate bus master request */
-+#define GPIO15_nCS_1 15 /* chip select 1 */
-+#define GPIO16_PWM0 16 /* PWM0 output */
-+#define GPIO17_PWM1 17 /* PWM1 output */
-+#define GPIO18_RDY 18 /* Ext. Bus Ready */
-+#define GPIO19_DREQ1 19 /* External DMA Request */
-+#define GPIO20_DREQ0 20 /* External DMA Request */
-+#define GPIO23_SCLK 23 /* SSP clock */
-+#define GPIO24_SFRM 24 /* SSP Frame */
-+#define GPIO25_STXD 25 /* SSP transmit */
-+#define GPIO26_SRXD 26 /* SSP receive */
-+#define GPIO27_SEXTCLK 27 /* SSP ext_clk */
-+#define GPIO28_BITCLK 28 /* AC97/I2S bit_clk */
-+#define GPIO29_SDATA_IN 29 /* AC97 Sdata_in0 / I2S Sdata_in */
-+#define GPIO30_SDATA_OUT 30 /* AC97/I2S Sdata_out */
-+#define GPIO31_SYNC 31 /* AC97/I2S sync */
-+#define GPIO32_SDATA_IN1 32 /* AC97 Sdata_in1 */
-+#define GPIO33_nCS_5 33 /* chip select 5 */
-+#define GPIO34_FFRXD 34 /* FFUART receive */
-+#define GPIO34_MMCCS0 34 /* MMC Chip Select 0 */
-+#define GPIO35_FFCTS 35 /* FFUART Clear to send */
-+#define GPIO36_FFDCD 36 /* FFUART Data carrier detect */
-+#define GPIO37_FFDSR 37 /* FFUART data set ready */
-+#define GPIO38_FFRI 38 /* FFUART Ring Indicator */
-+#define GPIO39_MMCCS1 39 /* MMC Chip Select 1 */
-+#define GPIO39_FFTXD 39 /* FFUART transmit data */
-+#define GPIO40_FFDTR 40 /* FFUART data terminal Ready */
-+#define GPIO41_FFRTS 41 /* FFUART request to send */
-+#define GPIO42_BTRXD 42 /* BTUART receive data */
-+#define GPIO43_BTTXD 43 /* BTUART transmit data */
-+#define GPIO44_BTCTS 44 /* BTUART clear to send */
-+#define GPIO45_BTRTS 45 /* BTUART request to send */
-+#define GPIO46_ICPRXD 46 /* ICP receive data */
-+#define GPIO46_STRXD 46 /* STD_UART receive data */
-+#define GPIO47_ICPTXD 47 /* ICP transmit data */
-+#define GPIO47_STTXD 47 /* STD_UART transmit data */
-+#define GPIO48_nPOE 48 /* Output Enable for Card Space */
-+#define GPIO49_nPWE 49 /* Write Enable for Card Space */
-+#define GPIO50_nPIOR 50 /* I/O Read for Card Space */
-+#define GPIO51_nPIOW 51 /* I/O Write for Card Space */
-+#define GPIO52_nPCE_1 52 /* Card Enable for Card Space */
-+#define GPIO53_nPCE_2 53 /* Card Enable for Card Space */
-+#define GPIO53_MMCCLK 53 /* MMC Clock */
-+#define GPIO54_MMCCLK 54 /* MMC Clock */
-+#define GPIO54_pSKTSEL 54 /* Socket Select for Card Space */
-+#define GPIO55_nPREG 55 /* Card Address bit 26 */
-+#define GPIO56_nPWAIT 56 /* Wait signal for Card Space */
-+#define GPIO57_nIOIS16 57 /* Bus Width select for I/O Card Space */
-+#define GPIO58_LDD_0 58 /* LCD data pin 0 */
-+#define GPIO59_LDD_1 59 /* LCD data pin 1 */
-+#define GPIO60_LDD_2 60 /* LCD data pin 2 */
-+#define GPIO61_LDD_3 61 /* LCD data pin 3 */
-+#define GPIO62_LDD_4 62 /* LCD data pin 4 */
-+#define GPIO63_LDD_5 63 /* LCD data pin 5 */
-+#define GPIO64_LDD_6 64 /* LCD data pin 6 */
-+#define GPIO65_LDD_7 65 /* LCD data pin 7 */
-+#define GPIO66_LDD_8 66 /* LCD data pin 8 */
-+#define GPIO66_MBREQ 66 /* alternate bus master req */
-+#define GPIO67_LDD_9 67 /* LCD data pin 9 */
-+#define GPIO67_MMCCS0 67 /* MMC Chip Select 0 */
-+#define GPIO68_LDD_10 68 /* LCD data pin 10 */
-+#define GPIO68_MMCCS1 68 /* MMC Chip Select 1 */
-+#define GPIO69_LDD_11 69 /* LCD data pin 11 */
-+#define GPIO69_MMCCLK 69 /* MMC_CLK */
-+#define GPIO70_LDD_12 70 /* LCD data pin 12 */
-+#define GPIO70_RTCCLK 70 /* Real Time clock (1 Hz) */
-+#define GPIO71_LDD_13 71 /* LCD data pin 13 */
-+#define GPIO71_3_6MHz 71 /* 3.6 MHz Oscillator clock */
-+#define GPIO72_LDD_14 72 /* LCD data pin 14 */
-+#define GPIO72_32kHz 72 /* 32 kHz clock */
-+#define GPIO73_LDD_15 73 /* LCD data pin 15 */
-+#define GPIO73_MBGNT 73 /* Memory controller grant */
-+#define GPIO74_LCD_FCLK 74 /* LCD Frame clock */
-+#define GPIO75_LCD_LCLK 75 /* LCD line clock */
-+#define GPIO76_LCD_PCLK 76 /* LCD Pixel clock */
-+#define GPIO77_LCD_ACBIAS 77 /* LCD AC Bias */
-+#define GPIO78_nCS_2 78 /* chip select 2 */
-+#define GPIO79_nCS_3 79 /* chip select 3 */
-+#define GPIO80_nCS_4 80 /* chip select 4 */
-+
-+/* GPIO alternate function mode & direction */
-+
-+#define GPIO_IN 0x000
-+#define GPIO_OUT 0x080
-+#define GPIO_ALT_FN_1_IN 0x100
-+#define GPIO_ALT_FN_1_OUT 0x180
-+#define GPIO_ALT_FN_2_IN 0x200
-+#define GPIO_ALT_FN_2_OUT 0x280
-+#define GPIO_ALT_FN_3_IN 0x300
-+#define GPIO_ALT_FN_3_OUT 0x380
-+#define GPIO_MD_MASK_NR 0x07f
-+#define GPIO_MD_MASK_DIR 0x080
-+#define GPIO_MD_MASK_FN 0x300
-+
-+#define GPIO1_RTS_MD ( 1 | GPIO_ALT_FN_1_IN)
-+#define GPIO6_MMCCLK_MD ( 6 | GPIO_ALT_FN_1_OUT)
-+#define GPIO8_48MHz_MD ( 8 | GPIO_ALT_FN_1_OUT)
-+#define GPIO8_MMCCS0_MD ( 8 | GPIO_ALT_FN_1_OUT)
-+#define GPIO9_MMCCS1_MD ( 9 | GPIO_ALT_FN_1_OUT)
-+#define GPIO10_RTCCLK_MD (10 | GPIO_ALT_FN_1_OUT)
-+#define GPIO11_3_6MHz_MD (11 | GPIO_ALT_FN_1_OUT)
-+#define GPIO12_32KHz_MD (12 | GPIO_ALT_FN_1_OUT)
-+#define GPIO13_MBGNT_MD (13 | GPIO_ALT_FN_2_OUT)
-+#define GPIO14_MBREQ_MD (14 | GPIO_ALT_FN_1_IN)
-+#define GPIO15_nCS_1_MD (15 | GPIO_ALT_FN_2_OUT)
-+#define GPIO16_PWM0_MD (16 | GPIO_ALT_FN_2_OUT)
-+#define GPIO17_PWM1_MD (17 | GPIO_ALT_FN_2_OUT)
-+#define GPIO18_RDY_MD (18 | GPIO_ALT_FN_1_IN)
-+#define GPIO19_DREQ1_MD (19 | GPIO_ALT_FN_1_IN)
-+#define GPIO20_DREQ0_MD (20 | GPIO_ALT_FN_1_IN)
-+#define GPIO23_SCLK_md (23 | GPIO_ALT_FN_2_OUT)
-+#define GPIO24_SFRM_MD (24 | GPIO_ALT_FN_2_OUT)
-+#define GPIO25_STXD_MD (25 | GPIO_ALT_FN_2_OUT)
-+#define GPIO26_SRXD_MD (26 | GPIO_ALT_FN_1_IN)
-+#define GPIO27_SEXTCLK_MD (27 | GPIO_ALT_FN_1_IN)
-+#define GPIO28_BITCLK_AC97_MD (28 | GPIO_ALT_FN_1_IN)
-+#define GPIO28_BITCLK_I2S_MD (28 | GPIO_ALT_FN_2_IN)
-+#define GPIO29_SDATA_IN_AC97_MD (29 | GPIO_ALT_FN_1_IN)
-+#define GPIO29_SDATA_IN_I2S_MD (29 | GPIO_ALT_FN_2_IN)
-+#define GPIO30_SDATA_OUT_AC97_MD (30 | GPIO_ALT_FN_2_OUT)
-+#define GPIO30_SDATA_OUT_I2S_MD (30 | GPIO_ALT_FN_1_OUT)
-+#define GPIO31_SYNC_AC97_MD (31 | GPIO_ALT_FN_2_OUT)
-+#define GPIO31_SYNC_I2S_MD (31 | GPIO_ALT_FN_1_OUT)
-+#define GPIO32_SDATA_IN1_AC97_MD (32 | GPIO_ALT_FN_1_IN)
-+#define GPIO33_nCS_5_MD (33 | GPIO_ALT_FN_2_OUT)
-+#define GPIO34_FFRXD_MD (34 | GPIO_ALT_FN_1_IN)
-+#define GPIO34_MMCCS0_MD (34 | GPIO_ALT_FN_2_OUT)
-+#define GPIO35_FFCTS_MD (35 | GPIO_ALT_FN_1_IN)
-+#define GPIO36_FFDCD_MD (36 | GPIO_ALT_FN_1_IN)
-+#define GPIO37_FFDSR_MD (37 | GPIO_ALT_FN_1_IN)
-+#define GPIO38_FFRI_MD (38 | GPIO_ALT_FN_1_IN)
-+#define GPIO39_MMCCS1_MD (39 | GPIO_ALT_FN_1_OUT)
-+#define GPIO39_FFTXD_MD (39 | GPIO_ALT_FN_2_OUT)
-+#define GPIO40_FFDTR_MD (40 | GPIO_ALT_FN_2_OUT)
-+#define GPIO41_FFRTS_MD (41 | GPIO_ALT_FN_2_OUT)
-+#define GPIO42_BTRXD_MD (42 | GPIO_ALT_FN_1_IN)
-+#define GPIO43_BTTXD_MD (43 | GPIO_ALT_FN_2_OUT)
-+#define GPIO44_BTCTS_MD (44 | GPIO_ALT_FN_1_IN)
-+#define GPIO45_BTRTS_MD (45 | GPIO_ALT_FN_2_OUT)
-+#define GPIO46_ICPRXD_MD (46 | GPIO_ALT_FN_1_IN)
-+#define GPIO46_STRXD_MD (46 | GPIO_ALT_FN_2_IN)
-+#define GPIO47_ICPTXD_MD (47 | GPIO_ALT_FN_2_OUT)
-+#define GPIO47_STTXD_MD (47 | GPIO_ALT_FN_1_OUT)
-+#define GPIO48_nPOE_MD (48 | GPIO_ALT_FN_2_OUT)
-+#define GPIO49_nPWE_MD (49 | GPIO_ALT_FN_2_OUT)
-+#define GPIO50_nPIOR_MD (50 | GPIO_ALT_FN_2_OUT)
-+#define GPIO51_nPIOW_MD (51 | GPIO_ALT_FN_2_OUT)
-+#define GPIO52_nPCE_1_MD (52 | GPIO_ALT_FN_2_OUT)
-+#define GPIO53_nPCE_2_MD (53 | GPIO_ALT_FN_2_OUT)
-+#define GPIO53_MMCCLK_MD (53 | GPIO_ALT_FN_1_OUT)
-+#define GPIO54_MMCCLK_MD (54 | GPIO_ALT_FN_1_OUT)
-+#define GPIO54_pSKTSEL_MD (54 | GPIO_ALT_FN_2_OUT)
-+#define GPIO55_nPREG_MD (55 | GPIO_ALT_FN_2_OUT)
-+#define GPIO56_nPWAIT_MD (56 | GPIO_ALT_FN_1_IN)
-+#define GPIO57_nIOIS16_MD (57 | GPIO_ALT_FN_1_IN)
-+#define GPIO58_LDD_0_MD (58 | GPIO_ALT_FN_2_OUT)
-+#define GPIO59_LDD_1_MD (59 | GPIO_ALT_FN_2_OUT)
-+#define GPIO60_LDD_2_MD (60 | GPIO_ALT_FN_2_OUT)
-+#define GPIO61_LDD_3_MD (61 | GPIO_ALT_FN_2_OUT)
-+#define GPIO62_LDD_4_MD (62 | GPIO_ALT_FN_2_OUT)
-+#define GPIO63_LDD_5_MD (63 | GPIO_ALT_FN_2_OUT)
-+#define GPIO64_LDD_6_MD (64 | GPIO_ALT_FN_2_OUT)
-+#define GPIO65_LDD_7_MD (65 | GPIO_ALT_FN_2_OUT)
-+#define GPIO66_LDD_8_MD (66 | GPIO_ALT_FN_2_OUT)
-+#define GPIO66_MBREQ_MD (66 | GPIO_ALT_FN_1_IN)
-+#define GPIO67_LDD_9_MD (67 | GPIO_ALT_FN_2_OUT)
-+#define GPIO67_MMCCS0_MD (67 | GPIO_ALT_FN_1_OUT)
-+#define GPIO68_LDD_10_MD (68 | GPIO_ALT_FN_2_OUT)
-+#define GPIO68_MMCCS1_MD (68 | GPIO_ALT_FN_1_OUT)
-+#define GPIO69_LDD_11_MD (69 | GPIO_ALT_FN_2_OUT)
-+#define GPIO69_MMCCLK_MD (69 | GPIO_ALT_FN_1_OUT)
-+#define GPIO70_LDD_12_MD (70 | GPIO_ALT_FN_2_OUT)
-+#define GPIO70_RTCCLK_MD (70 | GPIO_ALT_FN_1_OUT)
-+#define GPIO71_LDD_13_MD (71 | GPIO_ALT_FN_2_OUT)
-+#define GPIO71_3_6MHz_MD (71 | GPIO_ALT_FN_1_OUT)
-+#define GPIO72_LDD_14_MD (72 | GPIO_ALT_FN_2_OUT)
-+#define GPIO72_32kHz_MD (72 | GPIO_ALT_FN_1_OUT)
-+#define GPIO73_LDD_15_MD (73 | GPIO_ALT_FN_2_OUT)
-+#define GPIO73_MBGNT_MD (73 | GPIO_ALT_FN_1_OUT)
-+#define GPIO74_LCD_FCLK_MD (74 | GPIO_ALT_FN_2_OUT)
-+#define GPIO75_LCD_LCLK_MD (75 | GPIO_ALT_FN_2_OUT)
-+#define GPIO76_LCD_PCLK_MD (76 | GPIO_ALT_FN_2_OUT)
-+#define GPIO77_LCD_ACBIAS_MD (77 | GPIO_ALT_FN_2_OUT)
-+#define GPIO78_nCS_2_MD (78 | GPIO_ALT_FN_2_OUT)
-+#define GPIO79_nCS_3_MD (79 | GPIO_ALT_FN_2_OUT)
-+#define GPIO80_nCS_4_MD (80 | GPIO_ALT_FN_2_OUT)
-+
-+
-+/*
-+ * Power Manager
-+ */
-+
-+#define PMCR __REG(0x40F00000) /* Power Manager Control Register */
-+#define PSSR __REG(0x40F00004) /* Power Manager Sleep Status Register */
-+#define PSPR __REG(0x40F00008) /* Power Manager Scratch Pad Register */
-+#define PWER __REG(0x40F0000C) /* Power Manager Wake-up Enable Register */
-+#define PRER __REG(0x40F00010) /* Power Manager GPIO Rising-Edge Detect Enable Register */
-+#define PFER __REG(0x40F00014) /* Power Manager GPIO Falling-Edge Detect Enable Register */
-+#define PEDR __REG(0x40F00018) /* Power Manager GPIO Edge Detect Status Register */
-+#define PCFR __REG(0x40F0001C) /* Power Manager General Configuration Register */
-+#define PGSR0 __REG(0x40F00020) /* Power Manager GPIO Sleep State Register for GP[31-0] */
-+#define PGSR1 __REG(0x40F00024) /* Power Manager GPIO Sleep State Register for GP[63-32] */
-+#define PGSR2 __REG(0x40F00028) /* Power Manager GPIO Sleep State Register for GP[84-64] */
-+#define RCSR __REG(0x40F00030) /* Reset Controller Status Register */
-+
-+#define PSSR_RDH (1 << 5) /* Read Disable Hold */
-+#define PSSR_PH (1 << 4) /* Peripheral Control Hold */
-+#define PSSR_VFS (1 << 2) /* VDD Fault Status */
-+#define PSSR_BFS (1 << 1) /* Battery Fault Status */
-+#define PSSR_SSS (1 << 0) /* Software Sleep Status */
-+
-+#define PCFR_DS (1 << 3) /* Deep Sleep Mode */
-+#define PCFR_FS (1 << 2) /* Float Static Chip Selects */
-+#define PCFR_FP (1 << 1) /* Float PCMCIA controls */
-+#define PCFR_OPDE (1 << 0) /* 3.6864 MHz oscillator power-down enable */
-+
-+#define RCSR_GPR (1 << 3) /* GPIO Reset */
-+#define RCSR_SMR (1 << 2) /* Sleep Mode */
-+#define RCSR_WDR (1 << 1) /* Watchdog Reset */
-+#define RCSR_HWR (1 << 0) /* Hardware Reset */
-+
-+
-+/*
-+ * SSP Serial Port Registers
-+ */
-+
-+#define SSCR0 __REG(0x41000000) /* SSP Control Register 0 */
-+#define SSCR1 __REG(0x41000004) /* SSP Control Register 1 */
-+#define SSSR __REG(0x41000008) /* SSP Status Register */
-+#define SSITR __REG(0x4100000C) /* SSP Interrupt Test Register */
-+#define SSDR __REG(0x41000010) /* (Write / Read) SSP Data Write Register/SSP Data Read Register */
-+
-+
-+/*
-+ * MultiMediaCard (MMC) controller
-+ */
-+
-+#define MMC_STRPCL __REG(0x41100000) /* Control to start and stop MMC clock */
-+#define MMC_STAT __REG(0x41100004) /* MMC Status Register (read only) */
-+#define MMC_CLKRT __REG(0x41100008) /* MMC clock rate */
-+#define MMC_SPI __REG(0x4110000c) /* SPI mode control bits */
-+#define MMC_CMDAT __REG(0x41100010) /* Command/response/data sequence control */
-+#define MMC_RESTO __REG(0x41100014) /* Expected response time out */
-+#define MMC_RDTO __REG(0x41100018) /* Expected data read time out */
-+#define MMC_BLKLEN __REG(0x4110001c) /* Block length of data transaction */
-+#define MMC_NOB __REG(0x41100020) /* Number of blocks, for block mode */
-+#define MMC_PRTBUF __REG(0x41100024) /* Partial MMC_TXFIFO FIFO written */
-+#define MMC_I_MASK __REG(0x41100028) /* Interrupt Mask */
-+#define MMC_I_REG __REG(0x4110002c) /* Interrupt Register (read only) */
-+#define MMC_CMD __REG(0x41100030) /* Index of current command */
-+#define MMC_ARGH __REG(0x41100034) /* MSW part of the current command argument */
-+#define MMC_ARGL __REG(0x41100038) /* LSW part of the current command argument */
-+#define MMC_RES __REG(0x4110003c) /* Response FIFO (read only) */
-+#define MMC_RXFIFO __REG(0x41100040) /* Receive FIFO (read only) */
-+#define MMC_TXFIFO __REG(0x41100044) /* Transmit FIFO (write only) */
-+
-+
-+/*
-+ * Core Clock
-+ */
-+
-+#define CCCR __REG(0x41300000) /* Core Clock Configuration Register */
-+#define CKEN __REG(0x41300004) /* Clock Enable Register */
-+#define OSCC __REG(0x41300008) /* Oscillator Configuration Register */
-+
-+#define CCCR_N_MASK 0x0380 /* Run Mode Frequency to Turbo Mode Frequency Multiplier */
-+#define CCCR_M_MASK 0x0060 /* Memory Frequency to Run Mode Frequency Multiplier */
-+#define CCCR_L_MASK 0x001f /* Crystal Frequency to Memory Frequency Multiplier */
-+
-+#define CKEN16_LCD (1 << 16) /* LCD Unit Clock Enable */
-+#define CKEN14_I2C (1 << 14) /* I2C Unit Clock Enable */
-+#define CKEN13_FICP (1 << 13) /* FICP Unit Clock Enable */
-+#define CKEN12_MMC (1 << 12) /* MMC Unit Clock Enable */
-+#define CKEN11_USB (1 << 11) /* USB Unit Clock Enable */
-+#define CKEN8_I2S (1 << 8) /* I2S Unit Clock Enable */
-+#define CKEN7_BTUART (1 << 7) /* BTUART Unit Clock Enable */
-+#define CKEN6_FFUART (1 << 6) /* FFUART Unit Clock Enable */
-+#define CKEN5_STUART (1 << 5) /* STUART Unit Clock Enable */
-+#define CKEN3_SSP (1 << 3) /* SSP Unit Clock Enable */
-+#define CKEN2_AC97 (1 << 2) /* AC97 Unit Clock Enable */
-+#define CKEN1_PWM1 (1 << 1) /* PWM1 Clock Enable */
-+#define CKEN0_PWM0 (1 << 0) /* PWM0 Clock Enable */
-+
-+#define OSCC_OON (1 << 1) /* 32.768kHz OON (write-once only bit) */
-+#define OSCC_OOK (1 << 0) /* 32.768kHz OOK (read-only bit) */
-+
-+
-+/*
-+ * LCD
-+ */
-+
-+#define LCCR0 __REG(0x44000000) /* LCD Controller Control Register 0 */
-+#define LCCR1 __REG(0x44000004) /* LCD Controller Control Register 1 */
-+#define LCCR2 __REG(0x44000008) /* LCD Controller Control Register 2 */
-+#define LCCR3 __REG(0x4400000C) /* LCD Controller Control Register 3 */
-+#define DFBR0 __REG(0x44000020) /* DMA Channel 0 Frame Branch Register */
-+#define DFBR1 __REG(0x44000024) /* DMA Channel 1 Frame Branch Register */
-+#define LCSR __REG(0x44000038) /* LCD Controller Status Register */
-+#define LIIDR __REG(0x4400003C) /* LCD Controller Interrupt ID Register */
-+#define TMEDRGBR __REG(0x44000040) /* TMED RGB Seed Register */
-+#define TMEDCR __REG(0x44000044) /* TMED Control Register */
-+
-+#define FDADR0 __REG(0x44000200) /* DMA Channel 0 Frame Descriptor Address Register */
-+#define FSADR0 __REG(0x44000204) /* DMA Channel 0 Frame Source Address Register */
-+#define FIDR0 __REG(0x44000208) /* DMA Channel 0 Frame ID Register */
-+#define LDCMD0 __REG(0x4400020C) /* DMA Channel 0 Command Register */
-+#define FDADR1 __REG(0x44000210) /* DMA Channel 1 Frame Descriptor Address Register */
-+#define FSADR1 __REG(0x44000214) /* DMA Channel 1 Frame Source Address Register */
-+#define FIDR1 __REG(0x44000218) /* DMA Channel 1 Frame ID Register */
-+#define LDCMD1 __REG(0x4400021C) /* DMA Channel 1 Command Register */
-+
-+#define LCCR0_ENB (1 << 0) /* LCD Controller enable */
-+#define LCCR0_CMS (1 << 1) /* Color = 0, Monochrome = 1 */
-+#define LCCR0_SDS (1 << 2) /* Single Panel = 0, Dual Panel = 1 */
-+#define LCCR0_LDM (1 << 3) /* LCD Disable Done Mask */
-+#define LCCR0_SFM (1 << 4) /* Start of frame mask */
-+#define LCCR0_IUM (1 << 5) /* Input FIFO underrun mask */
-+#define LCCR0_EFM (1 << 6) /* End of Frame mask */
-+#define LCCR0_PAS (1 << 7) /* Passive = 0, Active = 1 */
-+#define LCCR0_BLE (1 << 8) /* Little Endian = 0, Big Endian = 1 */
-+#define LCCR0_DPD (1 << 9) /* Double Pixel mode, 4 pixel value = 0, 8 pixle values = 1 */
-+#define LCCR0_DIS (1 << 10) /* LCD Disable */
-+#define LCCR0_QDM (1 << 11) /* LCD Quick Disable mask */
-+#define LCCR0_PDD (0xff << 12) /* Palette DMA request delay */
-+#define LCCR0_PDD_S 12
-+#define LCCR0_BM (1 << 20) /* Branch mask */
-+#define LCCR0_OUM (1 << 21) /* Output FIFO underrun mask */
-+
-+#define LCCR1_PPL Fld (10, 0) /* Pixels Per Line - 1 */
-+#define LCCR1_DisWdth(Pixel) /* Display Width [1..800 pix.] */ \
-+ (((Pixel) - 1) << FShft (LCCR1_PPL))
-+
-+#define LCCR1_HSW Fld (6, 10) /* Horizontal Synchronization */
-+#define LCCR1_HorSnchWdth(Tpix) /* Horizontal Synchronization */ \
-+ /* pulse Width [1..64 Tpix] */ \
-+ (((Tpix) - 1) << FShft (LCCR1_HSW))
-+
-+#define LCCR1_ELW Fld (8, 16) /* End-of-Line pixel clock Wait */
-+ /* count - 1 [Tpix] */
-+#define LCCR1_EndLnDel(Tpix) /* End-of-Line Delay */ \
-+ /* [1..256 Tpix] */ \
-+ (((Tpix) - 1) << FShft (LCCR1_ELW))
-+
-+#define LCCR1_BLW Fld (8, 24) /* Beginning-of-Line pixel clock */
-+ /* Wait count - 1 [Tpix] */
-+#define LCCR1_BegLnDel(Tpix) /* Beginning-of-Line Delay */ \
-+ /* [1..256 Tpix] */ \
-+ (((Tpix) - 1) << FShft (LCCR1_BLW))
-+
-+
-+#define LCCR2_LPP Fld (10, 0) /* Line Per Panel - 1 */
-+#define LCCR2_DisHght(Line) /* Display Height [1..1024 lines] */ \
-+ (((Line) - 1) << FShft (LCCR2_LPP))
-+
-+#define LCCR2_VSW Fld (6, 10) /* Vertical Synchronization pulse */
-+ /* Width - 1 [Tln] (L_FCLK) */
-+#define LCCR2_VrtSnchWdth(Tln) /* Vertical Synchronization pulse */ \
-+ /* Width [1..64 Tln] */ \
-+ (((Tln) - 1) << FShft (LCCR2_VSW))
-+
-+#define LCCR2_EFW Fld (8, 16) /* End-of-Frame line clock Wait */
-+ /* count [Tln] */
-+#define LCCR2_EndFrmDel(Tln) /* End-of-Frame Delay */ \
-+ /* [0..255 Tln] */ \
-+ ((Tln) << FShft (LCCR2_EFW))
-+
-+#define LCCR2_BFW Fld (8, 24) /* Beginning-of-Frame line clock */
-+ /* Wait count [Tln] */
-+#define LCCR2_BegFrmDel(Tln) /* Beginning-of-Frame Delay */ \
-+ /* [0..255 Tln] */ \
-+ ((Tln) << FShft (LCCR2_BFW))
-+
-+#if 0
-+#define LCCR3_PCD (0xff) /* Pixel clock divisor */
-+#define LCCR3_ACB (0xff << 8) /* AC Bias pin frequency */
-+#define LCCR3_ACB_S 8
-+#endif
-+
-+#define LCCR3_API (0xf << 16) /* AC Bias pin trasitions per interrupt */
-+#define LCCR3_API_S 16
-+#define LCCR3_VSP (1 << 20) /* vertical sync polarity */
-+#define LCCR3_HSP (1 << 21) /* horizontal sync polarity */
-+#define LCCR3_PCP (1 << 22) /* pixel clock polarity */
-+#define LCCR3_OEP (1 << 23) /* output enable polarity */
-+#if 0
-+#define LCCR3_BPP (7 << 24) /* bits per pixel */
-+#define LCCR3_BPP_S 24
-+#endif
-+#define LCCR3_DPC (1 << 27) /* double pixel clock mode */
-+
-+
-+#define LCCR3_PCD Fld (8, 0) /* Pixel Clock Divisor */
-+#define LCCR3_PixClkDiv(Div) /* Pixel Clock Divisor */ \
-+ (((Div) << FShft (LCCR3_PCD)))
-+
-+
-+#define LCCR3_BPP Fld (3, 24) /* Bit Per Pixel */
-+#define LCCR3_Bpp(Bpp) /* Bit Per Pixel */ \
-+ (((Bpp) << FShft (LCCR3_BPP)))
-+
-+#define LCCR3_ACB Fld (8, 8) /* AC Bias */
-+#define LCCR3_Acb(Acb) /* BAC Bias */ \
-+ (((Acb) << FShft (LCCR3_ACB)))
-+
-+#define LCCR3_HorSnchH (LCCR3_HSP*0) /* Horizontal Synchronization */
-+ /* pulse active High */
-+#define LCCR3_HorSnchL (LCCR3_HSP*1) /* Horizontal Synchronization */
-+
-+#define LCCR3_VrtSnchH (LCCR3_VSP*0) /* Vertical Synchronization pulse */
-+ /* active High */
-+#define LCCR3_VrtSnchL (LCCR3_VSP*1) /* Vertical Synchronization pulse */
-+ /* active Low */
-+
-+#define LCSR_LDD (1 << 0) /* LCD Disable Done */
-+#define LCSR_SOF (1 << 1) /* Start of frame */
-+#define LCSR_BER (1 << 2) /* Bus error */
-+#define LCSR_ABC (1 << 3) /* AC Bias count */
-+#define LCSR_IUL (1 << 4) /* input FIFO underrun Lower panel */
-+#define LCSR_IUU (1 << 5) /* input FIFO underrun Upper panel */
-+#define LCSR_OU (1 << 6) /* output FIFO underrun */
-+#define LCSR_QD (1 << 7) /* quick disable */
-+#define LCSR_EOF (1 << 8) /* end of frame */
-+#define LCSR_BS (1 << 9) /* branch status */
-+#define LCSR_SINT (1 << 10) /* subsequent interrupt */
-+
-+#define LDCMD_PAL (1 << 26) /* instructs DMA to load palette buffer */
-+
-+#define LCSR_LDD (1 << 0) /* LCD Disable Done */
-+#define LCSR_SOF (1 << 1) /* Start of frame */
-+#define LCSR_BER (1 << 2) /* Bus error */
-+#define LCSR_ABC (1 << 3) /* AC Bias count */
-+#define LCSR_IUL (1 << 4) /* input FIFO underrun Lower panel */
-+#define LCSR_IUU (1 << 5) /* input FIFO underrun Upper panel */
-+#define LCSR_OU (1 << 6) /* output FIFO underrun */
-+#define LCSR_QD (1 << 7) /* quick disable */
-+#define LCSR_EOF (1 << 8) /* end of frame */
-+#define LCSR_BS (1 << 9) /* branch status */
-+#define LCSR_SINT (1 << 10) /* subsequent interrupt */
-+
-+#define LDCMD_PAL (1 << 26) /* instructs DMA to load palette buffer */
-+
-+/*
-+ * Memory controller
-+ */
-+
-+#define MDCNFG __REG(0x48000000) /* SDRAM Configuration Register 0 */
-+#define MDREFR __REG(0x48000004) /* SDRAM Refresh Control Register */
-+#define MSC0 __REG(0x48000008) /* Static Memory Control Register 0 */
-+#define MSC1 __REG(0x4800000C) /* Static Memory Control Register 1 */
-+#define MSC2 __REG(0x48000010) /* Static Memory Control Register 2 */
-+#define MECR __REG(0x48000014) /* Expansion Memory (PCMCIA/Compact Flash) Bus Configuration */
-+#define SXLCR __REG(0x48000018) /* LCR value to be written to SDRAM-Timing Synchronous Flash */
-+#define SXCNFG __REG(0x4800001C) /* Synchronous Static Memory Control Register */
-+#define SXMRS __REG(0x48000024) /* MRS value to be written to Synchronous Flash or SMROM */
-+#define MCMEM0 __REG(0x48000028) /* Card interface Common Memory Space Socket 0 Timing */
-+#define MCMEM1 __REG(0x4800002C) /* Card interface Common Memory Space Socket 1 Timing */
-+#define MCATT0 __REG(0x48000030) /* Card interface Attribute Space Socket 0 Timing Configuration */
-+#define MCATT1 __REG(0x48000034) /* Card interface Attribute Space Socket 1 Timing Configuration */
-+#define MCIO0 __REG(0x48000038) /* Card interface I/O Space Socket 0 Timing Configuration */
-+#define MCIO1 __REG(0x4800003C) /* Card interface I/O Space Socket 1 Timing Configuration */
-+#define MDMRS __REG(0x48000040) /* MRS value to be written to SDRAM */
-+#define BOOT_DEF __REG(0x48000044) /* Read-Only Boot-Time Register. Contains BOOT_SEL and PKG_SEL */
-+
-+#define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */
-+#define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */
-+#define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */
-+#define MDREFR_SLFRSH (1 << 22) /* SDRAM Self-Refresh Control/Status */
-+#define MDREFR_APD (1 << 20) /* SDRAM/SSRAM Auto-Power-Down Enable */
-+#define MDREFR_K2DB2 (1 << 19) /* SDCLK2 Divide by 2 Control/Status */
-+#define MDREFR_K2RUN (1 << 18) /* SDCLK2 Run Control/Status */
-+#define MDREFR_K1DB2 (1 << 17) /* SDCLK1 Divide by 2 Control/Status */
-+#define MDREFR_K1RUN (1 << 16) /* SDCLK1 Run Control/Status */
-+#define MDREFR_E1PIN (1 << 15) /* SDCKE1 Level Control/Status */
-+#define MDREFR_K0DB2 (1 << 14) /* SDCLK0 Divide by 2 Control/Status */
-+#define MDREFR_K0RUN (1 << 13) /* SDCLK0 Run Control/Status */
-+#define MDREFR_E0PIN (1 << 12) /* SDCKE0 Level Control/Status */
-+
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/serial.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,51 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/serial.h
-+ *
-+ * Author: Nicolas Pitre
-+ * Copyright: (C) 2001 MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+
-+#define BAUD_BASE 921600
-+
-+/* Standard COM flags */
-+#define STD_COM_FLAGS (ASYNC_SKIP_TEST)
-+
-+#define STD_SERIAL_PORT_DEFNS \
-+ { \
-+ type: PORT_PXA, \
-+ xmit_fifo_size: 32, \
-+ baud_base: BAUD_BASE, \
-+ iomem_base: (void *)&FFUART,\
-+ iomem_reg_shift: 2, \
-+ io_type: SERIAL_IO_MEM32,\
-+ irq: IRQ_FFUART, \
-+ flags: STD_COM_FLAGS, \
-+ }, { \
-+ type: PORT_PXA, \
-+ xmit_fifo_size: 32, \
-+ baud_base: BAUD_BASE, \
-+ iomem_base: (void *)&BTUART,\
-+ iomem_reg_shift: 2, \
-+ io_type: SERIAL_IO_MEM32,\
-+ irq: IRQ_BTUART, \
-+ flags: STD_COM_FLAGS, \
-+ }, { \
-+ type: PORT_PXA, \
-+ xmit_fifo_size: 32, \
-+ baud_base: BAUD_BASE, \
-+ iomem_base: (void *)&STUART,\
-+ iomem_reg_shift: 2, \
-+ io_type: SERIAL_IO_MEM32,\
-+ irq: IRQ_STUART, \
-+ flags: STD_COM_FLAGS, \
-+ }
-+
-+#define RS_TABLE_SIZE 8
-+
-+#define EXTRA_SERIAL_PORT_DEFNS
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/system.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,32 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/system.h
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Jun 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include "hardware.h"
-+
-+static inline void arch_idle(void)
-+{
-+ cpu_do_idle();
-+}
-+
-+static inline void arch_reset(char mode)
-+{
-+ if (mode == 's') {
-+ /* Jump into ROM at address 0 */
-+ cpu_reset(0);
-+ } else {
-+ /* Initialize the watchdog and let it fire */
-+ OWER = OWER_WME;
-+ OSSR = OSSR_M3;
-+ OSMR3 = OSCR + 368640; /* ... in 100 ms */
-+ }
-+}
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/time.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,86 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/time.h
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Jun 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+
-+static inline unsigned long pxa_get_rtc_time(void)
-+{
-+ return RCNR;
-+}
-+
-+static int pxa_set_rtc(void)
-+{
-+ unsigned long current_time = xtime.tv_sec;
-+
-+ if (RTSR & RTSR_ALE) {
-+ /* make sure not to forward the clock over an alarm */
-+ unsigned long alarm = RTAR;
-+ if (current_time >= alarm && alarm >= RCNR)
-+ return -ERESTARTSYS;
-+ }
-+ RCNR = current_time;
-+ return 0;
-+}
-+
-+/* IRQs are disabled before entering here from do_gettimeofday() */
-+static unsigned long pxa_gettimeoffset (void)
-+{
-+ unsigned long ticks_to_match, elapsed, usec;
-+
-+ /* Get ticks before next timer match */
-+ ticks_to_match = OSMR0 - OSCR;
-+
-+ /* We need elapsed ticks since last match */
-+ elapsed = LATCH - ticks_to_match;
-+
-+ /* Now convert them to usec */
-+ usec = (unsigned long)(elapsed*tick)/LATCH;
-+
-+ return usec;
-+}
-+
-+static void pxa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ long flags;
-+ int next_match;
-+
-+ do_profile(regs);
-+
-+ /* Loop until we get ahead of the free running timer.
-+ * This ensures an exact clock tick count and time acuracy.
-+ * IRQs are disabled inside the loop to ensure coherence between
-+ * lost_ticks (updated in do_timer()) and the match reg value, so we
-+ * can use do_gettimeofday() from interrupt handlers.
-+ */
-+ do {
-+ do_leds();
-+ do_set_rtc();
-+ save_flags_cli( flags );
-+ do_timer(regs);
-+ OSSR = OSSR_M0; /* Clear match on timer 0 */
-+ next_match = (OSMR0 += LATCH);
-+ restore_flags( flags );
-+ } while( (signed long)(next_match - OSCR) <= 0 );
-+}
-+
-+extern inline void setup_timer (void)
-+{
-+ gettimeoffset = pxa_gettimeoffset;
-+ set_rtc = pxa_set_rtc;
-+ xtime.tv_sec = pxa_get_rtc_time();
-+ timer_irq.handler = pxa_timer_interrupt;
-+ OSMR0 = 0; /* set initial match at 0 */
-+ OSSR = 0xf; /* clear status on all timers */
-+ setup_arm_irq(IRQ_OST0, &timer_irq);
-+ OIER |= OIER_E0; /* enable match on timer 0 to cause interrupts */
-+ OSCR = 0; /* initialize free-running timer, force first match */
-+}
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/timex.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,17 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/timex.h
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Jun 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+/*
-+ * PXA250/210 timer
-+ */
-+#define CLOCK_TICK_RATE 3686400
-+#define CLOCK_TICK_FACTOR 80
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/trizeps2.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,206 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/trizeps2.h
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Copyright (c) 2002 Luc De Cock, Teradyne DS, Ltd.
-+ *
-+ * 2002-10-10: Initial code started from idp.h
-+ */
-+
-+
-+/*
-+ * Note: this file must be safe to include in assembly files
-+ */
-+
-+/* comment out following if you have a board with 32MB RAM */
-+//#define PXA_TRIZEPS2_64MB 1
-+#undef PXA_TRIZEPS2_64MB
-+
-+#define TRIZEPS2_FLASH_PHYS (PXA_CS0_PHYS)
-+#define TRIZEPS2_ALT_FLASH_PHYS (PXA_CS1_PHYS)
-+#define TRIZEPS2_MEDIAQ_PHYS (PXA_CS3_PHYS)
-+#define TRIZEPS2_IDE_PHYS (PXA_CS5_PHYS + 0x03000000)
-+#define TRIZEPS2_ETH_PHYS (0x0C800000)
-+#define TRIZEPS2_COREVOLT_PHYS (PXA_CS5_PHYS + 0x03800000)
-+#define TRIZEPS2_BCR_PHYS (0x0E000000)
-+#define TRIZEPS2_CPLD_PHYS (0x0C000000)
-+
-+/*
-+ * virtual memory map
-+ */
-+
-+#define TRIZEPS2_IDE_BASE (0xf0000000)
-+#define TRIZEPS2_IDE_SIZE (1*1024*1024)
-+
-+#define TRIZEPS2_ETH_BASE (0xf1000000)
-+#define TRIZEPS2_ETH_SIZE (1*1024*1024)
-+#define ETH_BASE TRIZEPS2_ETH_BASE //smc9194 driver compatibility issue
-+
-+#define TRIZEPS2_COREVOLT_BASE (TRIZEPS2_ETH_BASE + TRIZEPS2_ETH_SIZE)
-+#define TRIZEPS2_COREVOLT_SIZE (1*1024*1024)
-+
-+#define TRIZEPS2_BCR_BASE (0xf0000000)
-+#define TRIZEPS2_BCR_SIZE (1*1024*1024)
-+
-+#define BCR_P2V(x) ((x) - TRIZEPS2_BCR_PHYS + TRIZEPS2_BCR_BASE)
-+#define BCR_V2P(x) ((x) - TRIZEPS2_BCR_BASE + TRIZEPS2_BCR_PHYS)
-+
-+#ifndef __ASSEMBLY__
-+# define __BCR_REG(x) (*((volatile unsigned short *)BCR_P2V(x)))
-+#else
-+# define __BCR_REG(x) BCR_P2V(x)
-+#endif
-+
-+/* board level registers */
-+#define TRIZEPS2_CPLD_BASE (0xf0100000)
-+#define CPLD_P2V(x) ((x) - TRIZEPS2_CPLD_PHYS + TRIZEPS2_CPLD_BASE)
-+#define CPLD_V2P(x) ((x) - TRIZEPS2_CPLD_BASE + TRIZEPS2_CPLD_PHYS)
-+
-+#ifndef __ASSEMBLY__
-+# define __CPLD_REG(x) (*((volatile unsigned short *)CPLD_P2V(x)))
-+#else
-+# define __CPLD_REG(x) CPLD_P2V(x)
-+#endif
-+
-+#define _TRIZEPS2_PCCARD_STATUS (0x0c000000)
-+#define TRIZEPS2_PCCARD_STATUS __CPLD_REG(_TRIZEPS2_PCCARD_STATUS)
-+
-+/*
-+ * CS memory timing via Static Memory Control Register (MSC0-2)
-+ */
-+
-+#define MSC_CS(cs,val) ((val)<<((cs&1)<<4))
-+
-+#define MSC_RBUFF_SHIFT 15
-+#define MSC_RBUFF(x) ((x)<<MSC_RBUFF_SHIFT)
-+#define MSC_RBUFF_SLOW MSC_RBUFF(0)
-+#define MSC_RBUFF_FAST MSC_RBUFF(1)
-+
-+#define MSC_RRR_SHIFT 12
-+#define MSC_RRR(x) ((x)<<MSC_RRR_SHIFT)
-+
-+#define MSC_RDN_SHIFT 8
-+#define MSC_RDN(x) ((x)<<MSC_RDN_SHIFT)
-+
-+#define MSC_RDF_SHIFT 4
-+#define MSC_RDF(x) ((x)<<MSC_RDF_SHIFT)
-+
-+#define MSC_RBW_SHIFT 3
-+#define MSC_RBW(x) ((x)<<MSC_RBW_SHIFT)
-+#define MSC_RBW_16 MSC_RBW(1)
-+#define MSC_RBW_32 MSC_RBW(0)
-+
-+#define MSC_RT_SHIFT 0
-+#define MSC_RT(x) ((x)<<MSC_RT_SHIFT)
-+
-+
-+/*
-+ * Bit masks for various registers
-+ */
-+// TRIZEPS2_BCR_PCCARD_PWR
-+#define PCC_3V (1 << 0)
-+#define PCC_5V (1 << 1)
-+#define PCC_EN1 (1 << 2)
-+#define PCC_EN0 (1 << 3)
-+
-+// TRIZEPS2_BCR_PCCARD_EN
-+#define PCC_RESET (1 << 6)
-+#define PCC_ENABLE (1 << 0)
-+
-+// TRIZEPS2_BSR_PCCARDx_STATUS
-+#define _PCC_WRPROT (1 << 7) // 7-4 read as low true
-+#define _PCC_RESET (1 << 6)
-+#define _PCC_IRQ (1 << 5)
-+#define _PCC_INPACK (1 << 4)
-+#define PCC_BVD1 (1 << 0)
-+#define PCC_BVD2 (1 << 1)
-+#define PCC_VS1 (1 << 2)
-+#define PCC_VS2 (1 << 3)
-+
-+// TRIZEPS2_BCR_CONTROL bits
-+#define BCR_LCD_ON (1 << 4)
-+#define BCR_LCD_OFF (0)
-+#define BCR_LCD_MASK (1 << 4)
-+#define BCR_PCMCIA_RESET (1 << 7)
-+#define BCR_PCMCIA_NORMAL (0)
-+
-+#define PCC_DETECT (GPLR(24) & GPIO_bit(24))
-+#define PCC_READY (GPLR(1) & GPIO_bit(1))
-+
-+// Board Control Register
-+#define _TRIZEPS2_BCR_CONTROL (TRIZEPS2_BCR_PHYS)
-+#define TRIZEPS2_BCR_CONTROL __BCR_REG(_TRIZEPS2_BCR_CONTROL)
-+
-+// Board TTL-IO register
-+#define TRIZEPS2_TTLIO_PHYS (0x0d800000)
-+#define TRIZEPS2_TTLIO_BASE (0xf2000000)
-+// various ioctl cmds
-+#define TTLIO_RESET 0
-+#define TTLIO_GET 1
-+#define TTLIO_SET 2
-+#define TTLIO_UNSET 3
-+
-+/*
-+ * Macros for LCD Driver
-+ */
-+
-+#ifdef CONFIG_FB_PXA
-+
-+#define FB_BACKLIGHT_ON()
-+#define FB_BACKLIGHT_OFF()
-+
-+#define FB_PWR_ON()
-+#define FB_PWR_OFF()
-+
-+#define FB_VLCD_ON() WRITE_TRIZEPS2_BCR(BCR_LCD_ON,BCR_LCD_MASK);
-+#define FB_VLCD_OFF() WRITE_TRIZEPS2_BCR(BCR_LCD_OFF,BCR_LCD_MASK);
-+
-+#endif
-+
-+/* A listing of interrupts used by external hardware devices */
-+
-+#define GPIO_TOUCH_PANEL_IRQ 2
-+#define TOUCH_PANEL_IRQ IRQ_GPIO(GPIO_TOUCH_PANEL_IRQ)
-+#define GPIO_ETHERNET_IRQ 19
-+#define ETHERNET_IRQ IRQ_GPIO(GPIO_ETHERNET_IRQ)
-+#define GPIO_TTLIO_IRQ 23
-+#define TTLIO_IRQ IRQ_GPIO(GPIO_TTLIO_IRQ)
-+
-+#define TOUCH_PANEL_IRQ_EDGE GPIO_FALLING_EDGE
-+#define IDE_IRQ_EDGE GPIO_RISING_EDGE
-+#define ETHERNET_IRQ_EDGE GPIO_RISING_EDGE
-+
-+#define PCMCIA_S_CD_VALID IRQ_GPIO(24)
-+#define PCMCIA_S_CD_VALID_EDGE GPIO_BOTH_EDGES
-+
-+#define PCMCIA_S_RDYINT IRQ_GPIO(1)
-+#define PCMCIA_S_RDYINT_EDGE GPIO_FALLING_EDGE
-+
-+/*
-+ * macros for MTD driver
-+ */
-+
-+#define FLASH_WRITE_PROTECT_DISABLE() // ((TRIZEPS2_CPLD_FLASH_WE) &= ~(0x1))
-+#define FLASH_WRITE_PROTECT_ENABLE() // ((TRIZEPS2_CPLD_FLASH_WE) |= (0x1))
-+
-+/* shadow registers for write only registers */
-+#ifndef __ASSEMBLY__
-+extern unsigned short trizeps2_bcr_shadow;
-+#endif
-+
-+/*
-+ * macros to write to write only register
-+ *
-+ * none of these macros are protected from
-+ * multiple drivers using them in interrupt context.
-+ */
-+
-+#define WRITE_TRIZEPS2_BCR(value, mask) \
-+{\
-+ trizeps2_bcr_shadow = ((value & mask) | (trizeps2_bcr_shadow & ~mask));\
-+ TRIZEPS2_BCR_CONTROL = trizeps2_bcr_shadow;\
-+}
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/uncompress.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,42 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/uncompress.h
-+ *
-+ * Author: Nicolas Pitre
-+ * Copyright: (C) 2001 MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#define FFUART ((volatile unsigned long *)0x40100000)
-+#define BTUART ((volatile unsigned long *)0x40200000)
-+#define STUART ((volatile unsigned long *)0x40700000)
-+
-+#define UART FFUART
-+
-+
-+static __inline__ void putc(char c)
-+{
-+ while (!(UART[5] & 0x20));
-+ UART[0] = c;
-+}
-+
-+/*
-+ * This does not append a newline
-+ */
-+static void puts(const char *s)
-+{
-+ while (*s) {
-+ putc(*s);
-+ if (*s == '\n')
-+ putc('\r');
-+ s++;
-+ }
-+}
-+
-+/*
-+ * nothing to do
-+ */
-+#define arch_decomp_setup()
-+#define arch_decomp_wdog()
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-pxa/vmalloc.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,23 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/vmalloc.h
-+ *
-+ * Author: Nicolas Pitre
-+ * Copyright: (C) 2001 MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+/*
-+ * Just any arbitrary offset to the start of the vmalloc VM area: the
-+ * current 8MB value just means that there will be a 8MB "hole" after the
-+ * physical memory until the kernel virtual memory starts. That means that
-+ * any out-of-bounds memory accesses will hopefully be caught.
-+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
-+ * area for the same reason. ;)
-+ */
-+#define VMALLOC_OFFSET (8*1024*1024)
-+#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
-+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
-+#define VMALLOC_END (0xe8000000)
---- linux-2.4.25/include/asm-arm/assembler.h~2.4.25-vrs2-pxa1.patch 2000-08-13 18:54:15.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/assembler.h 2004-03-31 17:15:12.000000000 +0200
-@@ -13,3 +13,26 @@
-
- #include <asm/proc/ptrace.h>
- #include <asm/proc/assembler.h>
-+
-+/*
-+ * Endian independent macros for shifting bytes within registers.
-+ */
-+#ifndef __ARMEB__
-+#define pull lsr
-+#define push lsl
-+#define byte(x) (x*8)
-+#else
-+#define pull lsl
-+#define push lsr
-+#define byte(x) ((3-x)*8)
-+#endif
-+
-+/*
-+ * Data preload for architectures that support it
-+ */
-+#if __LINUX_ARM_ARCH__ >= 5
-+#define PLD(code...) code
-+#else
-+#define PLD(code...)
-+#endif
-+
---- linux-2.4.25/include/asm-arm/bitops.h~2.4.25-vrs2-pxa1.patch 2003-08-25 13:44:43.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/bitops.h 2004-03-31 17:15:12.000000000 +0200
-@@ -91,6 +91,8 @@
- return (((unsigned char *) addr)[nr >> 3] >> (nr & 7)) & 1;
- }
-
-+#if __LINUX_ARM_ARCH__ < 5
-+
- /*
- * ffz = Find First Zero in word. Undefined if no zero exists,
- * so code should check against ~0UL first..
-@@ -117,6 +119,23 @@
-
- #define ffs(x) generic_ffs(x)
-
-+#else
-+
-+/*
-+ * On ARMv5 and above those functions can be implemented around
-+ * the clz instruction for much better code efficiency.
-+ */
-+
-+extern __inline__ int generic_fls(int x);
-+#define fls(x) \
-+ ( __builtin_constant_p(x) ? generic_fls(x) : \
-+ ({ int __r; asm("clz%?\t%0, %1" : "=r"(__r) : "r"(x)); 32-__r; }) )
-+#define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })
-+#define __ffs(x) (ffs(x) - 1)
-+#define ffz(x) __ffs( ~(x) )
-+
-+#endif
-+
- /*
- * hweightN: returns the hamming weight (i.e. the number
- * of bits set) of a N-bit word
---- linux-2.4.25/include/asm-arm/io.h~2.4.25-vrs2-pxa1.patch 2003-08-25 13:44:43.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/io.h 2004-03-31 17:15:12.000000000 +0200
-@@ -168,7 +168,7 @@
- * devices. This is the "generic" version. The PCI specific version
- * is in pci.h
- */
--extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle);
-+extern void *consistent_alloc(int gfp, size_t size, dma_addr_t *handle, unsigned long flags);
- extern void consistent_free(void *vaddr, size_t size, dma_addr_t handle);
- extern void consistent_sync(void *vaddr, size_t size, int rw);
-
---- linux-2.4.25/include/asm-arm/memory.h~2.4.25-vrs2-pxa1.patch 2003-08-25 13:44:43.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/memory.h 2004-03-31 17:15:12.000000000 +0200
-@@ -123,6 +123,9 @@
- ((unsigned)((page) - NODE_MEM_MAP(node)) < NODE_DATA(node)->node_size)); \
- })
-
-+/* We want large page mapping possible */
-+#define VMALLOC_ALIGN 0x10000
-+
- #endif
-
- /*
---- linux-2.4.25/include/asm-arm/proc-armv/pgtable.h~2.4.25-vrs2-pxa1.patch 2001-08-12 20:14:00.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/proc-armv/pgtable.h 2004-03-31 17:15:12.000000000 +0200
-@@ -15,9 +15,6 @@
- #ifndef __ASM_PROC_PGTABLE_H
- #define __ASM_PROC_PGTABLE_H
-
--#include <asm/proc/domain.h>
--#include <asm/arch/vmalloc.h>
--
- /*
- * entries per page directory level: they are two-level, so
- * we don't really have any PMD directory.
-@@ -26,27 +23,92 @@
- #define PTRS_PER_PMD 1
- #define PTRS_PER_PGD 4096
-
--/****************
--* PMD functions *
--****************/
--
--/* PMD types (actually level 1 descriptor) */
--#define PMD_TYPE_MASK 0x0003
--#define PMD_TYPE_FAULT 0x0000
--#define PMD_TYPE_TABLE 0x0001
--#define PMD_TYPE_SECT 0x0002
--#define PMD_UPDATABLE 0x0010
--#define PMD_SECT_CACHEABLE 0x0008
--#define PMD_SECT_BUFFERABLE 0x0004
--#define PMD_SECT_AP_WRITE 0x0400
--#define PMD_SECT_AP_READ 0x0800
-+/*
-+ * Hardware page table definitions.
-+ *
-+ * + Level 1 descriptor (PMD)
-+ * - common
-+ */
-+#define PMD_TYPE_MASK (3 << 0)
-+#define PMD_TYPE_FAULT (0 << 0)
-+#define PMD_TYPE_TABLE (1 << 0)
-+#define PMD_TYPE_SECT (2 << 0)
-+#define PMD_UPDATABLE (1 << 4)
- #define PMD_DOMAIN(x) ((x) << 5)
-+#define PMD_PROTECTION (1 << 9) /* v5 */
-+/*
-+ * - section
-+ */
-+#define PMD_SECT_BUFFERABLE (1 << 2)
-+#define PMD_SECT_CACHEABLE (1 << 3)
-+#define PMD_SECT_AP_WRITE (1 << 10)
-+#define PMD_SECT_AP_READ (1 << 11)
-+#define PMD_SECT_TEX(x) ((x) << 12) /* v5 */
-+/*
-+ * - coarse table
-+ */
-+
-+/*
-+ * + Level 2 descriptor (PTE)
-+ * - common
-+ */
-+#define PTE_TYPE_MASK (3 << 0)
-+#define PTE_TYPE_FAULT (0 << 0)
-+#define PTE_TYPE_LARGE (1 << 0)
-+#define PTE_TYPE_SMALL (2 << 0)
-+#define PTE_TYPE_EXT (3 << 0) /* v5 */
-+#define PTE_BUFFERABLE (1 << 2)
-+#define PTE_CACHEABLE (1 << 3)
-+
-+/*
-+ * - extended small page/tiny page
-+ */
-+#define PTE_EXT_AP_UNO_SRO (0 << 4)
-+#define PTE_EXT_AP_UNO_SRW (1 << 4)
-+#define PTE_EXT_AP_URO_SRW (2 << 4)
-+#define PTE_EXT_AP_URW_SRW (3 << 4)
-+#define PTE_EXT_TEX(x) ((x) << 6) /* v5 */
-+
-+/*
-+ * - small page
-+ */
-+#define PTE_SMALL_AP_UNO_SRO (0x00 << 4)
-+#define PTE_SMALL_AP_UNO_SRW (0x55 << 4)
-+#define PTE_SMALL_AP_URO_SRW (0xaa << 4)
-+#define PTE_SMALL_AP_URW_SRW (0xff << 4)
-+#define PTE_AP_READ PTE_SMALL_AP_URO_SRW
-+#define PTE_AP_WRITE PTE_SMALL_AP_UNO_SRW
-+
-+/*
-+ * "Linux" PTE definitions.
-+ *
-+ * We keep two sets of PTEs - the hardware and the linux version.
-+ * This allows greater flexibility in the way we map the Linux bits
-+ * onto the hardware tables, and allows us to have YOUNG and DIRTY
-+ * bits.
-+ *
-+ * The PTE table pointer refers to the hardware entries; the "Linux"
-+ * entries are stored 1024 bytes below.
-+ */
-+#define L_PTE_PRESENT (1 << 0)
-+#define L_PTE_YOUNG (1 << 1)
-+#define L_PTE_BUFFERABLE (1 << 2) /* matches PTE */
-+#define L_PTE_CACHEABLE (1 << 3) /* matches PTE */
-+#define L_PTE_USER (1 << 4)
-+#define L_PTE_WRITE (1 << 5)
-+#define L_PTE_EXEC (1 << 6)
-+#define L_PTE_DIRTY (1 << 7)
-+
-+#ifndef __ASSEMBLY__
-+
-+#include <asm/proc/domain.h>
-+#include <asm/arch/vmalloc.h>
-
- #define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_USER))
- #define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_KERNEL))
-
- #define pmd_bad(pmd) (pmd_val(pmd) & 2)
--#define set_pmd(pmdp,pmd) cpu_set_pmd(pmdp,pmd)
-+#define set_pmd(pmdp,pmd) cpu_set_pmd(pmdp, pmd)
-
- static inline pmd_t __mk_pmd(pte_t *ptep, unsigned long prot)
- {
-@@ -75,49 +137,8 @@
- return __phys_to_virt(ptr);
- }
-
--/****************
--* PTE functions *
--****************/
--
--/* PTE types (actually level 2 descriptor) */
--#define PTE_TYPE_MASK 0x0003
--#define PTE_TYPE_FAULT 0x0000
--#define PTE_TYPE_LARGE 0x0001
--#define PTE_TYPE_SMALL 0x0002
--#define PTE_AP_READ 0x0aa0
--#define PTE_AP_WRITE 0x0550
--#define PTE_CACHEABLE 0x0008
--#define PTE_BUFFERABLE 0x0004
--
- #define set_pte(ptep, pte) cpu_set_pte(ptep,pte)
-
--/* We now keep two sets of ptes - the physical and the linux version.
-- * This gives us many advantages, and allows us greater flexibility.
-- *
-- * The Linux pte's contain:
-- * bit meaning
-- * 0 page present
-- * 1 young
-- * 2 bufferable - matches physical pte
-- * 3 cacheable - matches physical pte
-- * 4 user
-- * 5 write
-- * 6 execute
-- * 7 dirty
-- * 8-11 unused
-- * 12-31 virtual page address
-- *
-- * These are stored at the pte pointer; the physical PTE is at -1024bytes
-- */
--#define L_PTE_PRESENT (1 << 0)
--#define L_PTE_YOUNG (1 << 1)
--#define L_PTE_BUFFERABLE (1 << 2)
--#define L_PTE_CACHEABLE (1 << 3)
--#define L_PTE_USER (1 << 4)
--#define L_PTE_WRITE (1 << 5)
--#define L_PTE_EXEC (1 << 6)
--#define L_PTE_DIRTY (1 << 7)
--
- /*
- * The following macros handle the cache and bufferable bits...
- */
-@@ -162,5 +183,8 @@
- * Mark the prot value as uncacheable and unbufferable.
- */
- #define pgprot_noncached(prot) __pgprot(pgprot_val(prot) & ~(L_PTE_CACHEABLE | L_PTE_BUFFERABLE))
-+#define pgprot_writecombine(prot) __pgprot(pgprot_val(prot) & ~L_PTE_CACHEABLE)
-+
-+#endif /* __ASSEMBLY__ */
-
- #endif /* __ASM_PROC_PGTABLE_H */
---- linux-2.4.25/include/asm-arm/proc-armv/processor.h~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/proc-armv/processor.h 2004-03-31 17:15:12.000000000 +0200
-@@ -23,6 +23,9 @@
- #define KERNEL_STACK_SIZE PAGE_SIZE
-
- struct context_save_struct {
-+#ifdef CONFIG_CPU_XSCALE
-+ long long acc0;
-+#endif
- unsigned long cpsr;
- unsigned long r4;
- unsigned long r5;
-@@ -35,7 +38,11 @@
- unsigned long pc;
- };
-
-+#ifdef CONFIG_CPU_XSCALE
-+#define INIT_CSS (struct context_save_struct){ 0, SVC_MODE, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
-+#else
- #define INIT_CSS (struct context_save_struct){ SVC_MODE, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
-+#endif
-
- #define EXTRA_THREAD_STRUCT \
- unsigned int domain;
---- linux-2.4.25/include/asm-arm/proc-fns.h~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/proc-fns.h 2004-03-31 17:15:12.000000000 +0200
-@@ -124,6 +124,14 @@
- # define CPU_NAME sa1100
- # endif
- # endif
-+# ifdef CONFIG_CPU_XSCALE
-+# ifdef CPU_NAME
-+# undef MULTI_CPU
-+# define MULTI_CPU
-+# else
-+# define CPU_NAME xscale
-+# endif
-+# endif
- #endif
-
- #ifndef MULTI_CPU
---- linux-2.4.25/include/asm-arm/procinfo.h~2.4.25-vrs2-pxa1.patch 2003-08-25 13:44:43.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/procinfo.h 2004-03-31 17:15:12.000000000 +0200
-@@ -55,7 +55,8 @@
- #define HWCAP_FAST_MULT 16
- #define HWCAP_FPA 32
- #define HWCAP_VFP 64
--#define HWCAP_EDSP 128
-+#define HWCAP_EDSP 128 /* El Segundo */
- #define HWCAP_JAVA 256
-+#define HWCAP_XSCALE 512 /* XScale DSP co-processor */
-
- #endif
---- linux-2.4.25/include/asm-arm/uaccess.h~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/uaccess.h 2004-03-31 17:15:12.000000000 +0200
-@@ -86,7 +86,7 @@
- __get_user_x(__r1, __p, __e, 1, "lr"); \
- break; \
- case 2: \
-- __get_user_x(__r1, __p, __e, 2, "r2", "lr"); \
-+ __get_user_x(__r1, __p, __e, 2, "ip", "lr"); \
- break; \
- case 4: \
- __get_user_x(__r1, __p, __e, 4, "lr"); \
---- linux-2.4.25/include/linux/cramfs_fs_sb.h~2.4.25-vrs2-pxa1.patch 2001-07-20 01:14:53.000000000 +0200
-+++ linux-2.4.25/include/linux/cramfs_fs_sb.h 2004-03-31 17:15:12.000000000 +0200
-@@ -10,6 +10,10 @@
- unsigned long blocks;
- unsigned long files;
- unsigned long flags;
-+#ifdef CONFIG_CRAMFS_LINEAR
-+ unsigned long linear_phys_addr;
-+ char * linear_virt_addr;
-+#endif
- };
-
- #endif
---- linux-2.4.25/include/linux/i2c-id.h~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/include/linux/i2c-id.h 2004-03-31 17:15:12.000000000 +0200
-@@ -100,6 +100,10 @@
- #define I2C_DRIVERID_SAA7191 57 /* video decoder */
- #define I2C_DRIVERID_INDYCAM 58 /* SGI IndyCam */
-
-+#define I2C_DRIVERID_DS1307 46 /* real time clock: DS1307 */
-+#define I2C_DRIVERID_24LC64 47 /* EEprom 24LC64 */
-+#define I2C_DRIVERID_FM24CLB4 48 /* EEprom FM24CLB4 */
-+
- #define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */
- #define I2C_DRIVERID_EXP1 0xF1
- #define I2C_DRIVERID_EXP2 0xF2
-@@ -172,6 +176,8 @@
-
- #define I2C_ALGO_OCP 0x120000 /* IBM or otherwise On-chip I2C algorithm */
-
-+#define I2C_ALGO_PXA 0x400000 /* Intel PXA I2C algorithm */
-+
- #define I2C_ALGO_EXP 0x800000 /* experimental */
-
- #define I2C_ALGO_MASK 0xff0000 /* Mask for algorithms */
---- linux-2.4.25/include/linux/serial.h~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/include/linux/serial.h 2004-03-31 17:15:12.000000000 +0200
-@@ -75,11 +75,13 @@
- #define PORT_16654 11
- #define PORT_16850 12
- #define PORT_RSA 13 /* RSA-DV II/S card */
--#define PORT_MAX 13
-+#define PORT_PXA 14
-+#define PORT_MAX 14
-
- #define SERIAL_IO_PORT 0
- #define SERIAL_IO_HUB6 1
- #define SERIAL_IO_MEM 2
-+#define SERIAL_IO_MEM32 3
-
- struct serial_uart_config {
- char *name;
---- linux-2.4.25/include/linux/serial_reg.h~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/include/linux/serial_reg.h 2004-03-31 17:15:12.000000000 +0200
-@@ -119,6 +119,14 @@
- #define UART_IERX_SLEEP 0x10 /* Enable sleep mode */
-
- /*
-+ * The Intel PXA250/210 chip defines those bits
-+ */
-+#define UART_IER_DMAE 0x80 /* DMA Requests Enable */
-+#define UART_IER_UUE 0x40 /* UART Unit Enable */
-+#define UART_IER_NRZE 0x20 /* NRZ coding Enable */
-+#define UART_IER_RTOIE 0x10 /* Receiver Time Out Interrupt Enable */
-+
-+/*
- * These are the definitions for the Modem Control Register
- */
- #define UART_MCR_AFE 0x20 /* Enable auto-RTS/CTS (TI16C750) */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/mmc/ioctl.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,25 @@
-+/*
-+ * linux/include/linux/mmc/ioctl.h
-+ *
-+ * Author: Vladimir Shebordaev
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#ifndef __MMC_IOCTL_H__
-+#define __MMC_IOCTL_H__
-+
-+#include <asm/ioctl.h>
-+
-+/* IOCTL commands provided by MMC subsystem */
-+#define IOCMMCSTRNSMODE _IOW('I',0x0f01,int)
-+#define IOCMMCGTRNSMODE _IOR('I',0x0f02,int)
-+#define IOCMMCGCARDESC _IOR('I',0x0f03,int) /* FIXME */
-+#define IOCMMCGBLKSZMAX _IOR('I',0x0f04,ssize_t)
-+#define IOCMMCGNOBMAX _IOR('I',0x0f05,ssize_t)
-+
-+#endif /* __MMC_IOCTL_H__ */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/mmc/mmc.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,143 @@
-+/*
-+ * linux/include/linux/mmc/mmc.h
-+ *
-+ * Author: Vladimir Shebordaev
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#ifndef __MMC_H__
-+#define __MMC_H__
-+
-+#include <linux/types.h>
-+#include <mmc/types.h>
-+
-+/*
-+ * MMC card type
-+ */
-+enum _mmc_type {
-+ MMC_CARD_TYPE_RO = 1,
-+ MMC_CARD_TYPE_RW,
-+ MMC_CARD_TYPE_IO
-+};
-+
-+/*
-+ * MMC card state
-+ */
-+enum _mmc_state {
-+ MMC_CARD_STATE_IDLE = 1,
-+ MMC_CARD_STATE_READY,
-+ MMC_CARD_STATE_IDENT,
-+ MMC_CARD_STATE_STNBY,
-+ MMC_CARD_STATE_TRAN,
-+ MMC_CARD_STATE_DATA,
-+ MMC_CARD_STATE_RCV,
-+ MMC_CARD_STATE_DIS,
-+ MMC_CARD_STATE_UNPLUGGED=0xff
-+};
-+
-+/*
-+ * Data transfer mode
-+ */
-+enum _mmc_transfer_mode {
-+ MMC_TRANSFER_MODE_STREAM = 1,
-+ MMC_TRANSFER_MODE_BLOCK_SINGLE,
-+ MMC_TRANSFER_MODE_BLOCK_MULTIPLE,
-+ MMC_TRANSFER_MODE_UNDEFINED = -1
-+};
-+
-+struct _mmc_card_csd_rec { /* CSD register contents */
-+/* FIXME: BYTE_ORDER */
-+ u8 ecc:2,
-+ file_format:2,
-+ tmp_write_protect:1,
-+ perm_write_protect:1,
-+ copy:1,
-+ file_format_grp:1;
-+ u64 content_prot_app:1,
-+ rsvd3:4,
-+ write_bl_partial:1,
-+ write_bl_len:4,
-+ r2w_factor:3,
-+ default_ecc:2,
-+ wp_grp_enable:1,
-+ wp_grp_size:5,
-+ erase_grp_mult:5,
-+ erase_grp_size:5,
-+ c_size_mult:3,
-+ vdd_w_curr_max:3,
-+ vdd_w_curr_min:3,
-+ vdd_r_curr_max:3,
-+ vdd_r_curr_min:3,
-+ c_size:12,
-+ rsvd2:2,
-+ dsr_imp:1,
-+ read_blk_misalign:1,
-+ write_blk_misalign:1,
-+ read_bl_partial:1;
-+
-+ u16 read_bl_len:4,
-+ ccc:12;
-+ u8 tran_speed;
-+ u8 nsac;
-+ u8 taac;
-+ u8 rsvd1:2,
-+ spec_vers:4,
-+ csd_structure:2;
-+};
-+
-+struct _mmc_card_cid_rec { /* CID register contents */
-+/* FIXME: BYTE_ORDER */
-+ u8 mdt_year:4,
-+ mdt_mon:4;
-+ u32 psn;
-+ u8 prv_minor:4,
-+ prv_major:4;
-+ u8 pnm[6];
-+ u16 oid;
-+ u8 mid;
-+};
-+
-+/*
-+ * Public card description
-+ */
-+struct _mmc_card_info_rec {
-+ mmc_type_t type;
-+ mmc_transfer_mode_t transfer_mode; /* current data transfer mode */
-+ __u16 rca; /* card's RCA assigned during initialization */
-+ struct _mmc_card_csd_rec csd;
-+ struct _mmc_card_cid_rec cid;
-+ __u32 tran_speed; /* kbits */
-+ __u16 read_bl_len;
-+ __u16 write_bl_len;
-+ size_t capacity; /* card's capacity in bytes */
-+};
-+
-+/*
-+ * Micsellaneous defines
-+ */
-+#ifndef SEEK_SET
-+#define SEEK_SET (0)
-+#endif
-+
-+#ifndef SEEK_CUR
-+#define SEEK_CUR (1)
-+#endif
-+
-+#ifndef SEEK_END
-+#define SEEK_END (2)
-+#endif
-+
-+#ifndef TRUE
-+#define TRUE (1)
-+#endif
-+
-+#ifndef FALSE
-+#define FALSE (0)
-+#endif
-+
-+#endif /* __MMC_H__ */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/mmc/types.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,29 @@
-+/*
-+ * linux/include/linux/mmc/types.h
-+ *
-+ * Author: Vladimir Shebordaev
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#ifndef __MMC_TYPES_H__
-+#define __MMC_TYPES_H__
-+
-+/* MMC card */
-+typedef enum _mmc_type mmc_type_t;
-+typedef enum _mmc_state mmc_state_t;
-+typedef enum _mmc_transfer_mode mmc_transfer_mode_t;
-+
-+typedef struct _mmc_card_csd_rec mmc_card_csd_rec_t;
-+typedef struct _mmc_card_cid_rec mmc_card_cid_rec_t;
-+
-+typedef struct _mmc_card_info_rec mmc_card_info_rec_t;
-+typedef struct _mmc_card_info_rec *mmc_card_info_t;
-+
-+typedef enum _mmc_error mmc_error_t;
-+
-+#endif /* __MMC_TYPES_H__ */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/video/lcdctrl.h 2004-03-31 17:15:12.000000000 +0200
-@@ -0,0 +1,61 @@
-+/*
-+ * lcdctrl.h
-+ *
-+ * Generic LCD control for brightness, contrast, etc.
-+ * Device specific drivers implement a lcdctrl_device and
-+ * provides access to it via lcdctrl_device_get_ops().
-+ *
-+ * Copyright (C) 2002 Intrinsyc Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * History:
-+ * Mar 2002: Initial version [FB]
-+ *
-+ */
-+#ifndef __LCD_CONTROL_H
-+#define __LCD_CONTROL_H
-+
-+#define _LCDCTRL_IOCTL_ON 1
-+#define _LCDCTRL_IOCTL_OFF 2
-+#define _LCDCTRL_IOCTL_INTENSITY 3
-+#define _LCDCTRL_IOCTL_BRIGHTNESS 4
-+#define _LCDCTRL_IOCTL_CONTRAST 5
-+#define _LCDCTRL_IOCTL_GET_BRIGHTNESS 6
-+#define _LCDCTRL_IOCTL_GET_CONTRAST 7
-+#define _LCDCTRL_IOCTL_GET_INTENSITY 8
-+
-+#define _LCD_CONTROL_NAME "lcdctrl"
-+
-+#define LCD_NO_SYNC 0
-+#define LCD_SYNC_NEEDED 1
-+
-+int lcdctrl_enable( void);
-+int lcdctrl_disable( void);
-+
-+/* intensity, contrast, and brightness take values
-+ * between 0..100.
-+ */
-+int lcdctrl_set_intensity( int intensity);
-+int lcdctrl_set_contrast( int contrast, int sync);
-+int lcdctrl_set_brightness( int brightness);
-+
-+int lcdctrl_get_intensity( void);
-+int lcdctrl_get_contrast( void);
-+int lcdctrl_get_brightness( void);
-+
-+struct lcdctrl_device
-+{
-+ int (*init)( int*, int*, int*);
-+ int (*enable)(void);
-+ int (*disable)(void);
-+ int (*set_intensity)( int i);
-+ int (*set_brightness)( int b);
-+ int (*set_contrast)( int c, int sync);
-+};
-+
-+int lcdctrl_init( void);
-+
-+#endif
---- linux-2.4.25/init/do_mounts.c~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/init/do_mounts.c 2004-03-31 17:15:12.000000000 +0200
-@@ -394,6 +394,16 @@
- }
- #endif
-
-+#ifdef CONFIG_ROOT_CRAMFS_LINEAR
-+static int __init mount_linear_cramfs_root(void)
-+{
-+ void *data = root_mount_data;
-+ if (sys_mount("/dev/root","/root","cramfs",root_mountflags,data) == 0)
-+ return 1;
-+ return 0;
-+}
-+#endif
-+
- static int __init create_dev(char *name, kdev_t dev, char *devfs_name)
- {
- void *handle;
-@@ -759,6 +769,16 @@
-
- static void __init mount_root(void)
- {
-+#ifdef CONFIG_ROOT_CRAMFS_LINEAR
-+ if (ROOT_DEV == MKDEV(0, 0)) {
-+ if (mount_linear_cramfs_root()) {
-+ sys_chdir("/root");
-+ ROOT_DEV = current->fs->pwdmnt->mnt_sb->s_dev;
-+ printk("VFS: Mounted root (linear cramfs filesystem).\n");
-+ return;
-+ }
-+ }
-+#endif
- #ifdef CONFIG_ROOT_NFS
- if (MAJOR(ROOT_DEV) == NFS_MAJOR
- && MINOR(ROOT_DEV) == NFS_MINOR) {
---- linux-2.4.25/mm/memory.c~2.4.25-vrs2-pxa1.patch 2004-03-31 17:15:09.000000000 +0200
-+++ linux-2.4.25/mm/memory.c 2004-03-31 17:15:12.000000000 +0200
-@@ -1018,6 +1018,41 @@
- return 1; /* Minor fault */
-
- bad_wp_page:
-+ if (pte_present(pte) && pte_read(pte)) {
-+ /*
-+ * Handle COW of XIP memory.
-+ * Note that the source memory actually isn't a ram page so
-+ * no struct page is associated to the source pte.
-+ */
-+ char *dst;
-+ int ret;
-+
-+ spin_unlock(&mm->page_table_lock);
-+ new_page = alloc_page(GFP_HIGHUSER);
-+ if (!new_page)
-+ return -1;
-+
-+ /* copy XIP data to memory */
-+ dst = kmap_atomic(new_page, KM_USER0);
-+ ret = copy_from_user(dst, (void*)address, PAGE_SIZE);
-+ kunmap_atomic(dst, KM_USER0);
-+
-+ /* make sure pte didn't change while we dropped the lock */
-+ spin_lock(&mm->page_table_lock);
-+ if (!ret && pte_same(*page_table, pte)) {
-+ ++mm->rss;
-+ break_cow(vma, new_page, address, page_table);
-+ lru_cache_add(new_page);
-+ spin_unlock(&mm->page_table_lock);
-+ return 1; /* Minor fault */
-+ }
-+
-+ /* pte changed: back off */
-+ spin_unlock(&mm->page_table_lock);
-+ page_cache_release(new_page);
-+ return ret ? -1 : 1;
-+ }
-+
- spin_unlock(&mm->page_table_lock);
- printk("do_wp_page: bogus page at address %08lx\n", address);
- return -1;
diff --git a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/2.4.25-vrs2.patch b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/2.4.25-vrs2.patch
deleted file mode 100644
index c5f370aee3..0000000000
--- a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/2.4.25-vrs2.patch
+++ /dev/null
@@ -1,86979 +0,0 @@
-
-#
-# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux-2.4.25/Documentation/Configure.help~2.4.25-vrs2.patch 2004-02-18 14:36:30.000000000 +0100
-+++ linux-2.4.25/Documentation/Configure.help 2004-03-31 17:15:08.000000000 +0200
-@@ -4837,6 +4837,13 @@
- Say Y to enable support for Permedia2 AGP frame buffer card from
- 3Dlabs (aka `Graphic Blaster Exxtreme') on the PCI bus.
-
-+Permedia3 support (EXPERIMENTAL)
-+CONFIG_FB_PM3
-+ This is the frame buffer device driver for the 3DLabs Permedia3
-+ chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 &
-+ similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000
-+ and maybe other boards.
-+
- Phase5 CVisionPPC/BVisionPPC support
- CONFIG_FB_PM2_CVPPC
- Say Y to enable support for the Amiga Phase 5 CVisionPPC BVisionPPC
-@@ -13125,6 +13132,17 @@
- The module will be called tmspci.o. If you want to compile it
- as a module, say M here and read <file:Documentation/modules.txt>.
-
-+Altera ether00 support
-+CONFIG_ETHER00
-+ This is the driver for Altera's ether00 ethernet mac IP core. Say
-+ Y here if you want to build support for this into the kernel. It
-+ is also available as a module (say M here) that can be inserted/
-+ removed from the kernel at the same time as the PLD is configured.
-+ If this driver is running on an epxa10 development board then it
-+ will generate a suitable hw address based on the board serial
-+ number (MTD support is required for this). Otherwise you will
-+ need to set a suitable hw address using ifconfig.
-+
- Generic TMS380 ISA support
- CONFIG_TMSISA
- This tms380 module supports generic TMS380-based ISA cards.
-@@ -15069,6 +15087,16 @@
- support" be compiled as a module for this driver to be used
- properly.
-
-+Altera's uart00 serial driver
-+CONFIG_SERIAL_UART00
-+ Say Y here if you want to use the hard logic uart on Excalibur. This
-+ driver also supports soft logic implentations of this uart core.
-+
-+Serial console on uart00
-+CONFIG_SERIAL_UART00_CONSOLE
-+ Say Y here if you want to support a serial console on an Excalibur
-+ hard logic uart or uart00 IP core.
-+
- USB ConnectTech WhiteHEAT Serial Driver
- CONFIG_USB_SERIAL_WHITEHEAT
- Say Y here if you want to use a ConnectTech WhiteHEAT 4 port
-@@ -19085,6 +19113,20 @@
- <file:Documentation/modules.txt>.
- The module will be called i2c-velleman.o.
-
-+Guide GPIO adapter
-+CONFIG_I2C_GUIDE
-+ This supports the Iders GUIDE I2C bit-bashing adapter. If you have
-+ selected the GUIDE A07 as your ARM system type, you cannot deselect
-+ this option, as it is required for proper operation of the GUIDE.
-+
-+ This interface uses /dev/i2c-0 (major 89, minor 0).
-+
-+ Say Y if you own such an adapter.
-+
-+ This driver is also available as a module. If you want to compile
-+ it as a module, say M here and read Documentation/modules.txt. The
-+ module will be called i2c-guide.o.
-+
- I2C PCF 8584 interfaces
- CONFIG_I2C_ALGOPCF
- This allows you to use a range of I2C adapters called PCF adapters.
-@@ -20230,6 +20272,17 @@
- <file:Documentation/modules.txt>. The module will be called
- softdog.o.
-
-+SA1100 Internal Watchdog
-+CONFIG_SA1100_WATCHDOG
-+ Watchdog timer embedded into SA11x0 chips. This will reboot your
-+ system when timeout is reached.
-+ NOTE, that once enabled, this timer cannot be disabled.
-+
-+ This driver is also available as a module ( = code which can be
-+ inserted in and removed from the running kernel whenever you want).
-+ If you want to compile it as a module, say M here and read
-+ Documentation/modules.txt. The module will be called sa1100_wdt.o.
-+
- Berkshire Products PC Watchdog
- CONFIG_PCWATCHDOG
- This is the driver for the Berkshire Products PC Watchdog card.
-@@ -21891,6 +21944,30 @@
- from RME. If you want to acess advanced features of the card, read
- Documentation/sound/rme96xx.
-
-+Assabet audio (UDA1341) support
-+CONFIG_SOUND_ASSABET_UDA1341
-+ Say Y or M if you have an Intel Assabet evaluation board and want to
-+ use the Philips UDA 1341 audio chip (the one that drives the stereo
-+ audio output) on the SA1100 SSP port.
-+
-+Compaq iPAQ audio support
-+CONFIG_SOUND_H3600_UDA1341
-+ Say Y or M if you have a Compaq iPaq handheld computer and want to
-+ use its Philips UDA 1341 audio chip.
-+
-+Audio support for SA1111/UDA1341
-+CONFIG_SOUND_SA1111_UDA1341
-+ Say Y or M if you have an SA11x0 system with a Philips UDA 1341
-+ connected to the SA11x1. An example of such a system is the Intel
-+ Assabet evaluation board connected to a Neponset expansion board.
-+
-+Generic DAC on the SA11x0 SSP port
-+CONFIG_SOUND_SA1100SSP
-+ Say Y or M if you have an SA-11x0 system with a DAC on the SSP port.
-+ The LART has an Burr-Brown PCM 1710 digital to analog convertor on
-+ the SSP port, so you want to say Y or M for the LART. It might work
-+ on other SA-1100 platforms, too, but this is not tested.
-+
- Are you using a crosscompiler
- CONFIG_CROSSCOMPILE
- Say Y here if you are compiling the kernel on a different
-@@ -25594,6 +25671,20 @@
- Say Y if configuring for a Pangolin.
- Say N otherwise.
-
-+Shannon
-+CONFIG_SA1100_SHANNON
-+ The Shannon (also known as a Tuxscreen, and also as a IS2630) was a
-+ limited edition webphone produced by Philips. The Shannon is a SA1100
-+ platform with a 640x480 LCD, touchscreen, CIR keyboard, PCMCIA slots,
-+ and a telco interface.
-+
-+Simputer
-+CONFIG_SA1100_SIMPUTER
-+ Say Y here if you are using an Intel(R) StrongARM(R) SA-1110
-+ based Simputer. See http://www.simputer.org/ for information
-+ on the Simputer. The Simputer software is actively maintained
-+ by PicoPeta Simputers Pvt. Ltd. (http://www.picopeta.com)
-+
- Victor
- CONFIG_SA1100_VICTOR
- Say Y here if you are using a Visu Aide Intel(R) StrongARM(R)
-@@ -25601,6 +25692,14 @@
- <http://www.visuaide.com/pagevictor.en.html> for information on
- this system.
-
-+Radisys Corp. Tulsa
-+CONFIG_SA1100_PFS168
-+ The Radisys Corp. PFS-168 (aka Tulsa) is an Intel® StrongArm® SA-1110 based
-+ computer which includes the SA-1111 Microprocessor Companion Chip and other
-+ custom I/O designed to add connectivity and multimedia features for vending
-+ and business machine applications. Say Y here if you require support for
-+ this target.
-+
- # Choice: cerf_ram
- Cerf on-board RAM size
- CONFIG_SA1100_CERF_8MB
-@@ -25668,37 +25767,65 @@
- Say Y if you want support for the ARM920T processor.
- Otherwise, say N.
-
--Support ARM1020 processor
--CONFIG_CPU_ARM1020
-- The ARM1020 is the cached version of the ARM10 processor,
-- with an addition of a floating-point unit.
-+Support ARM922T processor
-+CONFIG_CPU_ARM922T
-+ The ARM922T is a version of the ARM920T, but with smaller
-+ instruction and data caches. It is used in Altera's
-+ Excalibur XA device family.
-
-- Say Y if you want support for the ARM1020 processor.
-+ Say Y if you want support for the ARM922T processor.
- Otherwise, say N.
-
--Disable I-Cache
-+Disable instruction cache
- CONFIG_CPU_ICACHE_DISABLE
-- Say Y here to disable the processor instruction cache. Unless
-- you have a reason not to or are unsure, say N.
-+ Say Y here to disable the processor instruction cache. Unless
-+ you have a reason to do this, say N.
-
--Disable D-Cache
-+Disable data cache
- CONFIG_CPU_DCACHE_DISABLE
-- Say Y here to disable the processor data cache. Unless
-- you have a reason not to or are unsure, say N.
-+ Say Y here to disable the processor data cache. Unless
-+ you have a reason to do this, say N.
-
--Force write through D-cache
-+Use data cache in writethrough mode
- CONFIG_CPU_DCACHE_WRITETHROUGH
-- Say Y here to use the data cache in write-through mode. Unless you
-- specifically require this or are unsure, say N.
-+ Say Y here to use the data cache in writethough mode. Unless you
-+ specifically require this, say N.
-
--Round robin I and D cache replacement algorithm
-+Support ARM1020 processor
-+CONFIG_CPU_ARM1020
-+ The ARM1020 is the 32K cached version of the ARM10 processor,
-+ with an addition of a floating-point unit.
-+
-+ Say Y if you want support for the ARM1020 processor.
-+ Otherwise, say N.
-+
-+Support ARM1022 processor
-+CONFIG_CPU_ARM1022
-+ The ARM1022E is the 16K cached version of the ARM10 processor,
-+ with an addition of a floating-point unit.
-+
-+ Say Y if you want support for the ARM1022 processor.
-+ Otherwise, say N.
-+
-+Force round-robin cache line replacement
- CONFIG_CPU_CACHE_ROUND_ROBIN
-- Say Y here to use the predictable round-robin cache replacement
-- policy. Unless you specifically require this or are unsure, say N.
-+ Say Y here to force the caches to use a round-robin
-+ algorithm when picking a cache line to evict. Unless you
-+ specifically require this, say N.
-+
-+Disable the write buffer
-+CONFIG_CPU_WB_DISABLE
-+ Say Y here to turn off the write buffer (if possible)
-+ Unless you specifically require this, say N. Note that
-+ not all ARM processors allow the write buffer to be
-+ disabled.
-
- Disable branch prediction
- CONFIG_CPU_BPREDICT_DISABLE
-- Say Y here to disable branch prediction. If unsure, say N.
-+ The ARM10 family of processors support branch prediction,
-+ which can significantly speed up execution of loops.
-+ Say Y here to disable branch prediction. Unless you
-+ specifically require this, say N.
-
- Compressed boot loader in ROM/flash
- CONFIG_ZBOOT_ROM
-@@ -25745,6 +25872,11 @@
- Say Y here if you are using the inhand electronics OmniMeter. See
- <http://www.inhandelectronics.com/html/omni1.html> for details.
-
-+HP Laboratories BadgePAD 4
-+CONFIG_SA1100_BADGE4
-+ Say Y here if you want to build a kernel for the HP Laboratories
-+ BadgePAD 4.
-+
- Load kernel using Angel Debug Monitor
- CONFIG_ANGELBOOT
- Say Y if you plan to load the kernel using Angel, ARM Ltd's target
-@@ -25757,6 +25889,15 @@
- board includes 2 serial ports, Ethernet, IRDA, and expansion headers.
- It comes with 16 MB SDRAM and 8 MB flash ROM.
-
-+GUIDEA07
-+CONFIG_ARCH_GUIDEA07
-+ Say Y if you are using a GUIDE (A07) board.
-+
-+ This board is based on the cs89712 processor and shares much common
-+ hardware with the CDB89712 configuration. When you select this
-+ option and the CDB89712 becomes enabled also, don't worry. It's
-+ supposed to be that way.
-+
- CLPS-711X internal ROM bootstrap
- CONFIG_EP72XX_ROM_BOOT
- If you say Y here, your CLPS711x-based kernel will use the bootstrap
-@@ -25785,19 +25926,27 @@
- You may say N here if you are going to load the Acorn FPEmulator
- early in the bootup.
-
-+Math emulation 80-bit support
-+CONFIG_FPE_NWFPE_XP
-+ Say Y to include 80-bit support in the kernel floating-point
-+ emulator. Otherwise, only 32 and 64-bit support is compiled in.
-+ Note that gcc does not generate 80-bit operations by default,
-+ so in most cases this option only enlarges the size of the
-+ floating point emulator without any good reason.
-+
-+ You almost surely want to say N here.
-+
- FastFPE math emulation
- CONFIG_FPE_FASTFPE
- Say Y here to include the FAST floating point emulator in the kernel.
-- This is an experimental much faster emulator which has only 32 bit
-+ This is an experimental much faster emulator which now also has full
- precision for the mantissa. It does not support any exceptions.
-- This makes it very simple, it is approximately 4-8 times faster than
-- NWFPE.
-+ It is very simple, and approximately 3-6 times faster than NWFPE.
-
-- It should be sufficient for most programs. It is definitely not
-- suitable if you do scientific calculations that need double
-- precision for iteration formulas that sum up lots of very small
-- numbers. If you do not feel you need a faster FP emulation you
-- should better choose NWFPE.
-+ It should be sufficient for most programs. It may be not suitable
-+ for scientific calculations, but you have to check this for yourself.
-+ If you do not feel you need a faster FP emulation you should better
-+ choose NWFPE.
-
- It is also possible to say M to build the emulator as a module
- (fastfpe.o). But keep in mind that you should only load the FP
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/Documentation/arm/Porting 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,135 @@
-+Taken from list archive at http://lists.arm.linux.org.uk/pipermail/linux-arm-kernel/2001-July/004064.html
-+
-+Initial definitions
-+-------------------
-+
-+The following symbol definitions rely on you knowing the translation that
-+__virt_to_phys() does for your machine. This macro converts the passed
-+virtual address to a physical address. Normally, it is simply:
-+
-+ phys = virt - PAGE_OFFSET + PHYS_OFFSET
-+
-+
-+Decompressor Symbols
-+--------------------
-+
-+ZTEXTADDR
-+ Start address of decompressor. There's no point in talking about
-+ virtual or physical addresses here, since the MMU will be off at
-+ the time when you call the decompressor code. You normally call
-+ the kernel at this address to start it booting. This doesn't have
-+ to be located in RAM, it can be in flash or other read-only or
-+ read-write addressable medium.
-+
-+ZBSSADDR
-+ Start address of zero-initialised work area for the decompressor.
-+ This must be pointing at RAM. The decompressor will zero initialise
-+ this for you. Again, the MMU will be off.
-+
-+ZRELADDR
-+ This is the address where the decompressed kernel will be written,
-+ and eventually executed. The following constraint must be valid:
-+
-+ __virt_to_phys(TEXTADDR) == ZRELADDR
-+
-+ The initial part of the kernel is carefully coded to be position
-+ independent.
-+
-+INITRD_PHYS
-+ Physical address to place the initial RAM disk. Only relevant if
-+ you are using the bootpImage stuff (which only works on the old
-+ struct param_struct).
-+
-+INITRD_VIRT
-+ Virtual address of the initial RAM disk. The following constraint
-+ must be valid:
-+
-+ __virt_to_phys(INITRD_VIRT) == INITRD_PHYS
-+
-+PARAMS_PHYS
-+ Physical address of the struct param_struct or tag list, giving the
-+ kernel various parameters about its execution environment.
-+
-+
-+Kernel Symbols
-+--------------
-+
-+PHYS_OFFSET
-+ Physical start address of the first bank of RAM.
-+
-+PAGE_OFFSET
-+ Virtual start address of the first bank of RAM. During the kernel
-+ boot phase, virtual address PAGE_OFFSET will be mapped to physical
-+ address PHYS_OFFSET, along with any other mappings you supply.
-+ This should be the same value as TASK_SIZE.
-+
-+TASK_SIZE
-+ The maximum size of a user process in bytes. Since user space
-+ always starts at zero, this is the maximum address that a user
-+ process can access+1. The user space stack grows down from this
-+ address.
-+
-+ Any virtual address below TASK_SIZE is deemed to be user process
-+ area, and therefore managed dynamically on a process by process
-+ basis by the kernel. I'll call this the user segment.
-+
-+ Anything above TASK_SIZE is common to all processes. I'll call
-+ this the kernel segment.
-+
-+ (In other words, you can't put IO mappings below TASK_SIZE, and
-+ hence PAGE_OFFSET).
-+
-+TEXTADDR
-+ Virtual start address of kernel, normally PAGE_OFFSET + 0x8000.
-+ This is where the kernel image ends up. With the latest kernels,
-+ it must be located at 32768 bytes into a 128MB region. Previous
-+ kernels placed a restriction of 256MB here.
-+
-+DATAADDR
-+ Virtual address for the kernel data segment. Must not be defined
-+ when using the decompressor.
-+
-+VMALLOC_START
-+VMALLOC_END
-+ Virtual addresses bounding the vmalloc() area. There must not be
-+ any static mappings in this area; vmalloc will overwrite them.
-+ The addresses must also be in the kernel segment (see above).
-+ Normally, the vmalloc() area starts VMALLOC_OFFSET bytes above the
-+ last virtual RAM address (found using variable high_memory).
-+
-+VMALLOC_OFFSET
-+ Offset normally incorporated into VMALLOC_START to provide a hole
-+ between virtual RAM and the vmalloc area. We do this to allow
-+ out of bounds memory accesses (eg, something writing off the end
-+ of the mapped memory map) to be caught. Normally set to 8MB.
-+
-+Architecture Specific Macros
-+----------------------------
-+
-+BOOT_MEM(pram,pio,vio)
-+ `pram' specifies the physical start address of RAM. Must always
-+ be present, and should be the same as PHYS_OFFSET.
-+
-+ `pio' is the physical address of an 8MB region containing IO for
-+ use with the debugging macros in arch/arm/kernel/debug-armv.S.
-+
-+ `vio' is the virtual address of the 8MB debugging region.
-+
-+ It is expected that the debugging region will be re-initialised
-+ by the architecture specific code later in the code (via the
-+ MAPIO function).
-+
-+BOOT_PARAMS
-+ Same as, and see PARAMS_PHYS.
-+
-+FIXUP(func)
-+ Machine specific fixups, run before memory subsystems have been
-+ initialised.
-+
-+MAPIO(func)
-+ Machine specific function to map IO areas (including the debug
-+ region above).
-+
-+INITIRQ(func)
-+ Machine specific function to initialise interrupts.
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/Documentation/arm/mem_alignment 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,58 @@
-+Too many problems poped up because of unnoticed misaligned memory access in
-+kernel code lately. Therefore the alignment fixup is now unconditionally
-+configured in for SA11x0 based targets. According to Alan Cox, this is a
-+bad idea to configure it out, but Russell King has some good reasons for
-+doing so on some f***ed up ARM architectures like the EBSA110. However
-+this is not the case on many design I'm aware of, like all SA11x0 based
-+ones.
-+
-+Of course this is a bad idea to rely on the alignment trap to perform
-+unaligned memory access in general. If those access are predictable, you
-+are better to use the macros provided by include/asm/unaligned.h. The
-+alignment trap can fixup misaligned access for the exception cases, but at
-+a high performance cost. It better be rare.
-+
-+Now for user space applications, it is possible to configure the alignment
-+trap to SIGBUS any code performing unaligned access (good for debugging bad
-+code), or even fixup the access by software like for kernel code. The later
-+mode isn't recommended for performance reasons (just think about the
-+floating point emulation that works about the same way). Fix your code
-+instead!
-+
-+Please note that randomly changing the behaviour without good thought is
-+real bad - it changes the behaviour of all unaligned instructions in user
-+space, and might cause programs to fail unexpectedly.
-+
-+To change the alignment trap behavior, simply echo a number into
-+/proc/sys/debug/alignment. The number is made up from various bits:
-+
-+bit behavior when set
-+--- -----------------
-+
-+0 A user process performing an unaligned memory access
-+ will cause the kernel to print a message indicating
-+ process name, pid, pc, instruction, address, and the
-+ fault code.
-+
-+1 The kernel will attempt to fix up the user process
-+ performing the unaligned access. This is of course
-+ slow (think about the floating point emulator) and
-+ not recommended for production use.
-+
-+2 The kernel will send a SIGBUS signal to the user process
-+ performing the unaligned access.
-+
-+Note that not all combinations are supported - only values 0 through 5.
-+(6 and 7 don't make sense).
-+
-+For example, the following will turn on the warnings, but without
-+fixing up or sending SIGBUS signals:
-+
-+ echo 1 > /proc/sys/debug/alignment
-+
-+You can also read the content of the same file to get statistical
-+information on unaligned access occurrences plus the current mode of
-+operation for user space code.
-+
-+
-+Nicolas Pitre, Mar 13, 2001. Modified Russell King, Nov 30, 2001.
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/Documentation/arm/memory.txt 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,74 @@
-+ Kernel Memory Layout on ARM Linux
-+
-+ Russell King <rmk@arm.linux.org.uk>
-+ April 27, 2003 (2.5.68)
-+
-+This document describes the virtual memory layout which the Linux
-+kernel uses for ARM processors. It indicates which regions are
-+free for platforms to use, and which are used by generic code.
-+
-+The ARM CPU is capable of addressing a maximum of 4GB virtual memory
-+space, and this must be shared between user space processes, the
-+kernel, and hardware devices.
-+
-+As the ARM architecture matures, it becomes necessary to reserve
-+certain regions of VM space for use for new facilities; therefore
-+this document may reserve more VM space over time.
-+
-+Start End Use
-+--------------------------------------------------------------------------
-+ffff8000 ffffffff copy_user_page / clear_user_page use.
-+ For SA11xx and Xscale, this is used to
-+ setup a minicache mapping.
-+
-+ffff1000 ffff7fff Reserved.
-+ Platforms must not use this address range.
-+
-+ffff0000 ffff0fff CPU vector page.
-+ The CPU vectors are mapped here if the
-+ CPU supports vector relocation (control
-+ register V bit.)
-+
-+ffe00000 fffeffff Free for platform use, not recommended.
-+
-+ffc00000 ffdfffff 2MB consistent memory mapping.
-+ Memory returned by the consistent_alloc
-+ low level function will be dynamically
-+ mapped here.
-+
-+ff000000 ffbfffff Free for platform use, not recommended.
-+
-+VMALLOC_END ff000000 Free for platform use, recommended.
-+
-+VMALLOC_START VMALLOC_END vmalloc() / ioremap() space.
-+ Memory returned by vmalloc/ioremap will
-+ be dynamically placed in this region.
-+ VMALLOC_START may be based upon the value
-+ of the high_memory variable.
-+
-+PAGE_OFFSET high_memory Kernel direct-mapped RAM region.
-+ This maps the platforms RAM, and typically
-+ maps all platform RAM in a 1:1 relationship.
-+
-+TASK_SIZE PAGE_OFFSET Kernel module space
-+ Kernel modules inserted via insmod are
-+ placed here using dynamic mappings.
-+
-+00001000 TASK_SIZE User space mappings
-+ Per-thread mappings are placed here via
-+ the mmap() system call.
-+
-+00000000 00000fff CPU vector page / null pointer trap
-+ CPUs which do not support vector remapping
-+ place their vector page here. NULL pointer
-+ dereferences by both the kernel and user
-+ space are also caught via this mapping.
-+
-+Please note that mappings which collide with the above areas may result
-+in a non-bootable kernel, or may cause the kernel to (eventually) panic
-+at run time.
-+
-+Since future CPUs may impact the kernel mapping layout, user programs
-+must not access any memory which is not mapped inside their 0x0001000
-+to TASK_SIZE address range. If they wish to access these areas, they
-+must set up their own mappings using open() and mmap().
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/Documentation/cpufreq/core.txt 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,94 @@
-+ CPU frequency and voltage scaling code in the Linux(TM) kernel
-+
-+
-+ L i n u x C P U F r e q
-+
-+ C P U F r e q C o r e
-+
-+
-+ Dominik Brodowski <linux@brodo.de>
-+ David Kimdon <dwhedon@debian.org>
-+
-+
-+
-+ Clock scaling allows you to change the clock speed of the CPUs on the
-+ fly. This is a nice method to save battery power, because the lower
-+ the clock speed, the less power the CPU consumes.
-+
-+
-+Contents:
-+---------
-+1. CPUFreq core and interfaces
-+2. CPUFreq notifiers
-+
-+1. General Information
-+=======================
-+
-+The CPUFreq core code is located in linux/kernel/cpufreq.c. This
-+cpufreq code offers a standardized interface for the CPUFreq
-+architecture drivers (those pieces of code that do actual
-+frequency transitions), as well as to "notifiers". These are device
-+drivers or other part of the kernel that need to be informed of
-+policy changes (ex. thermal modules like ACPI) or of all
-+frequency changes (ex. timing code) or even need to force certain
-+speed limits (like LCD drivers on ARM architecture). Additionally, the
-+kernel "constant" loops_per_jiffy is updated on frequency changes
-+here.
-+
-+Reference counting is done by cpufreq_get_cpu and cpufreq_put_cpu,
-+which make sure that the cpufreq processor driver is correctly
-+registered with the core, and will not be unloaded until
-+cpufreq_put_cpu is called.
-+
-+2. CPUFreq notifiers
-+====================
-+
-+CPUFreq notifiers conform to the standard kernel notifier interface.
-+See linux/include/linux/notifier.h for details on notifiers.
-+
-+There are two different CPUFreq notifiers - policy notifiers and
-+transition notifiers.
-+
-+
-+2.1 CPUFreq policy notifiers
-+----------------------------
-+
-+These are notified when a new policy is intended to be set. Each
-+CPUFreq policy notifier is called three times for a policy transition:
-+
-+1.) During CPUFREQ_ADJUST all CPUFreq notifiers may change the limit if
-+ they see a need for this - may it be thermal considerations or
-+ hardware limitations.
-+
-+2.) During CPUFREQ_INCOMPATIBLE only changes may be done in order to avoid
-+ hardware failure.
-+
-+3.) And during CPUFREQ_NOTIFY all notifiers are informed of the new policy
-+ - if two hardware drivers failed to agree on a new policy before this
-+ stage, the incompatible hardware shall be shut down, and the user
-+ informed of this.
-+
-+The phase is specified in the second argument to the notifier.
-+
-+The third argument, a void *pointer, points to a struct cpufreq_policy
-+consisting of five values: cpu, min, max, policy and max_cpu_freq. min
-+and max are the lower and upper frequencies (in kHz) of the new
-+policy, policy the new policy, cpu the number of the affected CPU or
-+CPUFREQ_ALL_CPUS for all CPUs; and max_cpu_freq the maximum supported
-+CPU frequency. This value is given for informational purposes only.
-+
-+
-+2.2 CPUFreq transition notifiers
-+--------------------------------
-+
-+These are notified twice when the CPUfreq driver switches the CPU core
-+frequency and this change has any external implications.
-+
-+The second argument specifies the phase - CPUFREQ_PRECHANGE or
-+CPUFREQ_POSTCHANGE.
-+
-+The third argument is a struct cpufreq_freqs with the following
-+values:
-+cpu - number of the affected CPU or CPUFREQ_ALL_CPUS
-+old - old frequency
-+new - new frequency
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/Documentation/cpufreq/cpu-drivers.txt 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,210 @@
-+ CPU frequency and voltage scaling code in the Linux(TM) kernel
-+
-+
-+ L i n u x C P U F r e q
-+
-+ C P U D r i v e r s
-+
-+ - information for developers -
-+
-+
-+ Dominik Brodowski <linux@brodo.de>
-+
-+
-+
-+ Clock scaling allows you to change the clock speed of the CPUs on the
-+ fly. This is a nice method to save battery power, because the lower
-+ the clock speed, the less power the CPU consumes.
-+
-+
-+Contents:
-+---------
-+1. What To Do?
-+1.1 Initialization
-+1.2 Per-CPU Initialization
-+1.3 verify
-+1.4 target or setpolicy?
-+1.5 target
-+1.6 setpolicy
-+2. Frequency Table Helpers
-+
-+
-+
-+1. What To Do?
-+==============
-+
-+So, you just got a brand-new CPU / chipset with datasheets and want to
-+add cpufreq support for this CPU / chipset? Great. Here are some hints
-+on what is neccessary:
-+
-+
-+1.1 Initialization
-+------------------
-+
-+First of all, in an __initcall level 7 or later (preferrably
-+module_init() so that your driver is modularized) function check
-+whether this kernel runs on the right CPU and the right chipset. If
-+so, register a struct cpufreq_driver with the CPUfreq core using
-+cpufreq_register_driver()
-+
-+What shall this struct cpufreq_driver contain?
-+
-+cpufreq_driver.name - The name of this driver.
-+
-+cpufreq_driver.init - A pointer to the per-CPU initialization
-+ function.
-+
-+cpufreq_driver.verify - A pointer to a "verfication" funciton.
-+
-+cpufreq_driver.setpolicy _or_
-+cpufreq_driver.target - See below on the differences.
-+
-+And optionally
-+
-+cpufreq_driver.exit - A pointer to a per-CPU cleanup function.
-+
-+cpufreq_driver.attr - A pointer to a NULL-terminated list of
-+ "struct freq_attr" which allow to
-+ export values to sysfs.
-+
-+
-+1.2 Per-CPU Initialization
-+--------------------------
-+
-+Whenever a new CPU is registered with the device model, or after the
-+cpufreq driver registers itself, the per-CPU initialization fucntion
-+cpufreq_driver.init is called. It takes a struct cpufreq_policy
-+*policy as argument. What to do now?
-+
-+If necessary, activate the CPUfreq support on your CPU (unlock that
-+register etc.).
-+
-+Then, the driver must fill in the following values:
-+
-+policy->cpuinfo.min_freq _and_
-+policy->cpuinfo.max_freq - the minimum and maximum frequency
-+ (in kHz) which is supported by
-+ this CPU
-+policy->cpuinfo.transition_latency the time it takes on this CPU to
-+ switch between two frequencies (if
-+ appropriate, else specify
-+ CPUFREQ_ETERNAL)
-+
-+policy->cur The current operating frequency of
-+ this CPU (if appropriate)
-+policy->min,
-+policy->max,
-+policy->policy and, if neccessary,
-+policy->governor must contain the "default policy" for
-+ this CPU. A few moments later,
-+ cpufreq_driver.verify and either
-+ cpufreq_driver.setpolicy or
-+ cpufreq_driver.target is called with
-+ these values.
-+
-+For setting some of these values, the frequency table helpers might be
-+helpful. See the section 2 for more information on them.
-+
-+
-+1.3 verify
-+------------
-+
-+When the user decides a new policy (consisting of
-+"policy,governor,min,max") shall be set, this policy must be validated
-+so that incompatible values can be corrected. For verifying these
-+values, a frequency table helper and/or the
-+cpufreq_verify_within_limits(struct cpufreq_policy *policy, unsigned
-+int min_freq, unsigned int max_freq) function might be helpful. See
-+section 2 for details on frequency table helpers.
-+
-+You need to make sure that at least one valid frequency (or operating
-+range) is within policy->min and policy->max. If necessary, increase
-+policy->max fist, and only if this is no solution, decreas policy->min.
-+
-+
-+1.4 target or setpolicy?
-+----------------------------
-+
-+Most cpufreq drivers or even most cpu frequency scaling algorithms
-+only allow the CPU to be set to one frequency. For these, you use the
-+->target call.
-+
-+Some cpufreq-capable processors switch the frequency between certain
-+limits on their own. These shall use the ->setpolicy call
-+
-+
-+1.4. target
-+-------------
-+
-+The target call has three arguments: struct cpufreq_policy *policy,
-+unsigned int target_frequency, unsigned int relation.
-+
-+The CPUfreq driver must set the new frequency when called here. The
-+actual frequency must be determined using the following rules:
-+
-+- keep close to "target_freq"
-+- policy->min <= new_freq <= policy->max (THIS MUST BE VALID!!!)
-+- if relation==CPUFREQ_REL_L, try to select a new_freq higher than or equal
-+ target_freq. ("L for lowest, but no lower than")
-+- if relation==CPUFREQ_REL_H, try to select a new_freq lower than or equal
-+ target_freq. ("H for highest, but no higher than")
-+
-+Here again the frequency table helper might assist you - see section 3
-+for details.
-+
-+
-+1.5 setpolicy
-+---------------
-+
-+The setpolicy call only takes a struct cpufreq_policy *policy as
-+argument. You need to set the lower limit of the in-processor or
-+in-chipset dynamic frequency switching to policy->min, the upper limit
-+to policy->max, and -if supported- select a performance-oriented
-+setting when policy->policy is CPUFREQ_POLICY_PERFORMANCE, and a
-+powersaving-oriented setting when CPUFREQ_POLICY_POWERSAVE. Also check
-+the reference implementation in arch/i386/kernel/cpu/cpufreq/longrun.c
-+
-+
-+
-+2. Frequency Table Helpers
-+==========================
-+
-+As most cpufreq processors only allow for being set to a few specific
-+frequencies, a "frequency table" with some functions might assist in
-+some work of the processor driver. Such a "frequency table" consists
-+of an array of struct cpufreq_freq_table entries, with any value in
-+"index" you want to use, and the corresponding frequency in
-+"frequency". At the end of the table, you need to add a
-+cpufreq_freq_table entry with frequency set to CPUFREQ_TABLE_END. And
-+if you want to skip one entry in the table, set the frequency to
-+CPUFREQ_ENTRY_INVALID. The entries don't need to be in ascending
-+order.
-+
-+By calling cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
-+ struct cpufreq_frequency_table *table);
-+the cpuinfo.min_freq and cpuinfo.max_freq values are detected, and
-+policy->min and policy->max are set to the same values. This is
-+helpful for the per-CPU initialization stage.
-+
-+int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
-+ struct cpufreq_frequency_table *table);
-+assures that at least one valid frequency is within policy->min and
-+policy->max, and all other criteria are met. This is helpful for the
-+->verify call.
-+
-+int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
-+ struct cpufreq_frequency_table *table,
-+ unsigned int target_freq,
-+ unsigned int relation,
-+ unsigned int *index);
-+
-+is the corresponding frequency table helper for the ->target
-+stage. Just pass the values to this function, and the unsigned int
-+index returns the number of the frequency table entry which contains
-+the frequency the CPU shall be set to. PLEASE NOTE: This is not the
-+"index" which is in this cpufreq_table_entry.index, but instead
-+cpufreq_table[index]. So, the new frequency is
-+cpufreq_table[index].frequency, and the value you stored into the
-+frequency table "index" field is
-+cpufreq_table[index].index.
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/Documentation/cpufreq/governors.txt 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,155 @@
-+ CPU frequency and voltage scaling code in the Linux(TM) kernel
-+
-+
-+ L i n u x C P U F r e q
-+
-+ C P U F r e q G o v e r n o r s
-+
-+ - information for users and developers -
-+
-+
-+ Dominik Brodowski <linux@brodo.de>
-+
-+
-+
-+ Clock scaling allows you to change the clock speed of the CPUs on the
-+ fly. This is a nice method to save battery power, because the lower
-+ the clock speed, the less power the CPU consumes.
-+
-+
-+Contents:
-+---------
-+1. What is a CPUFreq Governor?
-+
-+2. Governors In the Linux Kernel
-+2.1 Performance
-+2.2 Powersave
-+2.3 Userspace
-+
-+3. The Governor Interface in the CPUfreq Core
-+
-+
-+
-+1. What Is A CPUFreq Governor?
-+==============================
-+
-+Most cpufreq drivers (in fact, all except one, longrun) or even most
-+cpu frequency scaling algorithms only offer the CPU to be set to one
-+frequency. In order to offer dynamic frequency scaling, the cpufreq
-+core must be able to tell these drivers of a "target frequency". So
-+these specific drivers will be transformed to offer a "->target"
-+call instead of the existing "->setpolicy" call. For "longrun", all
-+stays the same, though.
-+
-+How to decide what frequency within the CPUfreq policy should be used?
-+That's done using "cpufreq governors". Two are already in this patch
-+-- they're the already existing "powersave" and "performance" which
-+set the frequency statically to the lowest or highest frequency,
-+respectively. At least two more such governors will be ready for
-+addition in the near future, but likely many more as there are various
-+different theories and models about dynamic frequency scaling
-+around. Using such a generic interface as cpufreq offers to scaling
-+governors, these can be tested extensively, and the best one can be
-+selected for each specific use.
-+
-+Basically, it's the following flow graph:
-+
-+CPU can be set to switch independetly | CPU can only be set
-+ within specific "limits" | to specific frequencies
-+
-+ "CPUfreq policy"
-+ consists of frequency limits (policy->{min,max})
-+ and CPUfreq governor to be used
-+ / \
-+ / \
-+ / the cpufreq governor decides
-+ / (dynamically or statically)
-+ / what target_freq to set within
-+ / the limits of policy->{min,max}
-+ / \
-+ / \
-+ Using the ->setpolicy call, Using the ->target call,
-+ the limits and the the frequency closest
-+ "policy" is set. to target_freq is set.
-+ It is assured that it
-+ is within policy->{min,max}
-+
-+
-+2. Governors In the Linux Kernel
-+================================
-+
-+2.1 Performance
-+---------------
-+
-+The CPUfreq governor "performance" sets the CPU statically to the
-+highest frequency within the borders of scaling_min_freq and
-+scaling_max_freq.
-+
-+
-+2.1 Powersave
-+-------------
-+
-+The CPUfreq governor "powersave" sets the CPU statically to the
-+lowest frequency within the borders of scaling_min_freq and
-+scaling_max_freq.
-+
-+
-+2.2 Userspace
-+-------------
-+
-+The CPUfreq governor "userspace" allows the user, or any userspace
-+program running with UID "root", to set the CPU to a specifc frequency
-+by making a sysfs file "scaling_setspeed" available in the CPU-device
-+directory.
-+
-+
-+
-+3. The Governor Interface in the CPUfreq Core
-+=============================================
-+
-+A new governor must register itself with the CPUfreq core using
-+"cpufreq_register_governor". The struct cpufreq_governor, which has to
-+be passed to that function, must contain the following values:
-+
-+governor->name - A unique name for this governor
-+governor->governor - The governor callback function
-+governor->owner - .THIS_MODULE for the governor module (if
-+ appropriate)
-+
-+The governor->governor callback is called with the current (or to-be-set)
-+cpufreq_policy struct for that CPU, and an unsigned int event. The
-+following events are currently defined:
-+
-+CPUFREQ_GOV_START: This governor shall start its duty for the CPU
-+ policy->cpu
-+CPUFREQ_GOV_STOP: This governor shall end its duty for the CPU
-+ policy->cpu
-+CPUFREQ_GOV_LIMITS: The limits for CPU policy->cpu have changed to
-+ policy->min and policy->max.
-+
-+If you need other "events" externally of your driver, _only_ use the
-+cpufreq_governor_l(unsigned int cpu, unsigned int event) call to the
-+CPUfreq core to ensure proper locking.
-+
-+
-+The CPUfreq governor may call the CPU processor driver using one of
-+these two functions:
-+
-+inline int cpufreq_driver_target(struct cpufreq_policy *policy,
-+ unsigned int target_freq,
-+ unsigned int relation);
-+
-+inline int cpufreq_driver_target_l(struct cpufreq_policy *policy,
-+ unsigned int target_freq,
-+ unsigned int relation);
-+
-+target_freq must be within policy->min and policy->max, of course.
-+What's the difference between these two functions? When your governor
-+still is in a direct code path of a call to governor->governor, the
-+cpufreq_driver_sem lock is still held in the cpufreq core, and there's
-+no need to lock it again (in fact, this would cause a deadlock). So
-+use cpufreq_driver_target only in these cases. In all other cases (for
-+example, when there's a "daemonized" function that wakes up every
-+second), use cpufreq_driver_target_l to lock the cpufreq_driver_sem
-+before the command is passed to the cpufreq processor driver.
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/Documentation/cpufreq/index.txt 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,56 @@
-+ CPU frequency and voltage scaling code in the Linux(TM) kernel
-+
-+
-+ L i n u x C P U F r e q
-+
-+
-+
-+
-+ Dominik Brodowski <linux@brodo.de>
-+
-+
-+
-+ Clock scaling allows you to change the clock speed of the CPUs on the
-+ fly. This is a nice method to save battery power, because the lower
-+ the clock speed, the less power the CPU consumes.
-+
-+
-+
-+Documents in this directory:
-+----------------------------
-+core.txt - General description of the CPUFreq core and
-+ of CPUFreq notifiers
-+
-+cpu-drivers.txt - How to implement a new cpufreq processor driver
-+
-+governors.txt - What are cpufreq governors and how to
-+ implement them?
-+
-+index.txt - File index, Mailing list and Links (this document)
-+
-+user-guide.txt - User Guide to CPUFreq
-+
-+
-+Mailing List
-+------------
-+There is a CPU frequency changing CVS commit and general list where
-+you can report bugs, problems or submit patches. To post a message,
-+send an email to cpufreq@www.linux.org.uk, to subscribe go to
-+http://www.linux.org.uk/mailman/listinfo/cpufreq. Previous post to the
-+mailing list are available to subscribers at
-+http://www.linux.org.uk/mailman/private/cpufreq/.
-+
-+
-+Links
-+-----
-+the FTP archives:
-+* ftp://ftp.linux.org.uk/pub/linux/cpufreq/
-+
-+how to access the CVS repository:
-+* http://cvs.arm.linux.org.uk/
-+
-+the CPUFreq Mailing list:
-+* http://www.linux.org.uk/mailman/listinfo/cpufreq
-+
-+Clock and voltage scaling for the SA-1100:
-+* http://www.lart.tudelft.nl/projects/scaling
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/Documentation/cpufreq/user-guide.txt 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,166 @@
-+ CPU frequency and voltage scaling code in the Linux(TM) kernel
-+
-+
-+ L i n u x C P U F r e q
-+
-+ U S E R G U I D E
-+
-+
-+ Dominik Brodowski <linux@brodo.de>
-+
-+
-+
-+ Clock scaling allows you to change the clock speed of the CPUs on the
-+ fly. This is a nice method to save battery power, because the lower
-+ the clock speed, the less power the CPU consumes.
-+
-+
-+Contents:
-+---------
-+1. Supported Architectures and Processors
-+1.1 ARM
-+1.2 x86
-+1.3 sparc64
-+
-+2. "Policy" / "Governor"?
-+2.1 Policy
-+2.2 Governor
-+
-+3. How to change the CPU cpufreq policy and/or speed
-+3.1 Preferred interface: sysfs
-+3.2 Deprecated interfaces
-+
-+
-+
-+1. Supported Architectures and Processors
-+=========================================
-+
-+1.1 ARM
-+-------
-+
-+The following ARM processors are supported by cpufreq:
-+
-+ARM Integrator
-+ARM-SA1100
-+ARM-SA1110
-+
-+
-+1.2 x86
-+-------
-+
-+The following processors for the x86 architecture are supported by cpufreq:
-+
-+AMD Elan - SC400, SC410
-+AMD mobile K6-2+
-+AMD mobile K6-3+
-+Cyrix Media GXm
-+Intel mobile PIII [*] and Intel mobile PIII-M on certain chipsets
-+Intel Pentium 4, Intel Xeon
-+National Semiconductors Geode GX
-+Transmeta Crusoe
-+varios processors on some ACPI 2.0-compatible systems [**]
-+
-+[*] only certain Intel mobile PIII processors are supported. If you
-+know that you own a speedstep-capable processor, pass the option
-+"speedstep_coppermine=1" to the module speedstep.o
-+
-+[**] Only if "ACPI Processor Performance States" are available
-+to the ACPI<->BIOS interface.
-+
-+
-+1.3 sparc64
-+-----------
-+
-+The following processors for the sparc64 architecture are supported by
-+cpufreq:
-+
-+UltraSPARC-III
-+
-+
-+
-+2. "Policy" / "Governor" ?
-+==========================
-+
-+Some CPU frequency scaling-capable processor switch between varios
-+frequencies and operating voltages "on the fly" without any kernel or
-+user involvement. This guarantuees very fast switching to a frequency
-+which is high enough to serve the user's needs, but low enough to save
-+power.
-+
-+
-+2.1 Policy
-+----------
-+
-+On these systems, all you can do is select the lower and upper
-+frequency limit as well as whether you want more aggressive
-+power-saving or more instantly avaialble processing power.
-+
-+
-+2.2 Governor
-+------------
-+
-+On all other cpufreq implementations, these boundaries still need to
-+be set. Then, a "governor" must be selected. Such a "governor" decides
-+what speed the processor shall run within the boundaries. One such
-+"governor" is the "userspace" governor. This one allows the user - or
-+a yet-to-implement userspace program - to decide what specific speed
-+the processor shall run at.
-+
-+
-+3. How to change the CPU cpufreq policy and/or speed
-+====================================================
-+
-+3.1 Preferred Interface: sysfs
-+------------------------------
-+
-+The preferred interface is located in the sysfs filesystem. If you
-+mounted it at /sys, the cpufreq interface is located in a subdirectory
-+"cpufreq" within the cpu-device directory
-+(e.g. /sys/devices/sys/cpu0/cpufreq/ for the first CPU).
-+
-+cpuinfo_min_freq : this file shows the minimum operating
-+ frequency the processor can run at(in kHz)
-+cpuinfo_max_freq : this file shows the maximum operating
-+ frequency the processor can run at(in kHz)
-+scaling_driver : this file shows what cpufreq driver is
-+ used to set the frequency on this CPU
-+
-+scaling_available_governors : this file shows the CPUfreq governors
-+ available in this kernel. You can see the
-+ currently activated governor in
-+
-+scaling_governor, and by "echoing" the name of another
-+ governor you can change it. Please note
-+ that some governors won't load - they only
-+ work on some specific architectures or
-+ processors.
-+scaling_min_freq and
-+scaling_max_freq show the current "policy limits" (in
-+ kHz). By echoing new values into these
-+ files, you can change these limits.
-+
-+
-+If you have selected the "userspace" governor which allows you to
-+set the CPU operating frequency to a specific value, you can read out
-+the current frequency in
-+
-+scaling_setspeed. By "echoing" a new frequency into this
-+ you can change the speed of the CPU,
-+ but only within the limits of
-+ scaling_min_freq and scaling_max_freq.
-+
-+
-+3.2 Deprecated Interfaces
-+-------------------------
-+
-+Depending on your kernel configuration, you might find the following
-+cpufreq-related files:
-+/proc/cpufreq
-+/proc/sys/cpu/*/speed
-+/proc/sys/cpu/*/speed-min
-+/proc/sys/cpu/*/speed-max
-+
-+These are files for deprecated interfaces to cpufreq, which offer far
-+less functionality. Because of this, these interfaces aren't described
-+here.
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/Documentation/cpufreq-old 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,332 @@
-+ CPU frequency and voltage scaling code in the Linux(TM) kernel
-+
-+
-+ L i n u x C P U F r e q
-+
-+
-+
-+
-+ Dominik Brodowski <devel@brodo.de>
-+
-+
-+
-+ Clock scaling allows you to change the clock speed of the CPUs on the
-+ fly. This is a nice method to save battery power, because the lower
-+ the clock speed, the less power the CPU consumes.
-+
-+
-+
-+Contents:
-+---------
-+1. Supported architectures
-+2. User interface
-+2.1 Sample script for command line interface
-+3. CPUFreq core and interfaces
-+3.1 General information
-+3.2 CPUFreq notifiers
-+3.3 CPUFreq architecture drivers
-+4. Mailing list and Links
-+
-+
-+
-+1. Supported architectures
-+==========================
-+
-+Some architectures detect the lowest and highest possible speed
-+settings, while others rely on user information on this. For the
-+latter, a boot parameter is required, for the former, you can specify
-+one to set the limits between speed settings may occur.
-+The boot parameter has the following syntax:
-+
-+ cpufreq=minspeed-maxspeed
-+
-+with both minspeed and maxspeed being given in kHz. To set the lower
-+limit to 59 MHz and the upper limit to 221 MHz, specify:
-+
-+ cpufreq=59000-221000
-+
-+Check the "Speed Limits Detection" information below on whether
-+the driver detects the lowest and highest allowed speed setting
-+automatically.
-+
-+
-+ARM Integrator:
-+ SA 1100, SA1110
-+--------------------------------
-+ Speed Limits Detection: On Integrators, the minimum speed is set
-+ and the maximum speed has to be specified using the boot
-+ parameter. On SA11x0s, the frequencies are fixed (59 - 287 MHz)
-+
-+
-+AMD Elan:
-+ SC400, SC410
-+--------------------------------
-+ Speed Limits Detection: Not implemented. You need to specify the
-+ minimum and maximum frequency in the boot parameter (see above).
-+
-+
-+VIA Cyrix Longhaul:
-+ VIA Samuel/CyrixIII, VIA Cyrix Samuel/C3,
-+ VIA Cyrix Ezra, VIA Cyrix Ezra-T
-+--------------------------------
-+ Speed Limits Detection: working. No need for boot parameters.
-+ NOTE: Support for certain processors is currently disabled,
-+ waiting on updated docs from VIA.
-+
-+
-+Intel SpeedStep:
-+ certain mobile Intel Pentium III (Coppermine), and all mobile
-+ Intel Pentium III-M (Tulatin) and mobile Intel Pentium 4 P4-Ms.
-+--------------------------------
-+ Speed Limits Detection: working. No need for boot parameters.
-+ NOTE:
-+ 1.) mobile Intel Pentium III (Coppermine):
-+ The SpeedStep interface may only be used on SpeedStep
-+ capable processors. Unforunately, due to lack of documentation,
-+ such detection is not yet possible on mobile Intel PIII
-+ (Coppermine) processors. In order to activate SpeedStep on such a
-+ processor, you have to remove one line manually in
-+ linux/drivers/arch/i386/speedstep.c
-+
-+
-+P4 CPU Clock Modulation:
-+ Intel Pentium 4 Xeon processors
-+--------------------------------
-+ Speed Limits Detection: Not implemented. You need to specify the
-+ minimum and maximum frequency in the boot parameter (see above).
-+
-+
-+
-+2. User Interface
-+=================
-+
-+CPUFreq uses a "sysctl" interface which is located in
-+ /proc/sys/cpu/0/ on UP (uniprocessor) kernels, or
-+ /proc/sys/cpu/any/ on SMP (symmetric multiprocessoring) kernels.
-+
-+
-+In this directory, you will find three files of importance for
-+CPUFreq: speed-max, speed-min, and speed:
-+
-+speed shows the current CPU frequency in kHz,
-+speed-min the minimal supported CPU frequency, and
-+speed-max the maximal supported CPU frequency.
-+
-+Please note that you might have to specify these limits as a boot
-+parameter depending on the architecture (see above).
-+
-+
-+To change the CPU frequency, "echo" the desired CPU frequency (in kHz)
-+to speed. For example, to set the CPU speed to the lowest/highest
-+allowed frequency do:
-+
-+root@notebook:# cat /proc/sys/cpu/0/speed-min > /proc/sys/cpu/0/speed
-+root@notebook:# cat /proc/sys/cpu/0/speed-max > /proc/sys/cpu/0/speed
-+
-+
-+2.1 Sample script for command line interface
-+**********************************************
-+
-+
-+Michael Ossmann <mike@ossmann.com> has written a small command line
-+interface for the infinitely lazy.
-+
-+#!/bin/bash
-+#
-+# /usr/local/bin/freq
-+# simple command line interface to cpufreq
-+
-+[ -n "$1" ] && case "$1" in
-+ "min" )
-+ # set frequency to minimum
-+ cat /proc/sys/cpu/0/speed-min >/proc/sys/cpu/0/speed
-+ ;;
-+ "max" )
-+ # set frequency to maximum
-+ cat /proc/sys/cpu/0/speed-max >/proc/sys/cpu/0/speed
-+ ;;
-+ * )
-+ echo "Usage: $0 [min|max]"
-+ echo " min: set frequency to minimum and display new frequency"
-+ echo " max: set frequency to maximum and display new frequency"
-+ echo " no options: display current frequency"
-+ exit 1
-+ ;;
-+esac
-+
-+# display current frequency
-+cat /proc/sys/cpu/0/speed
-+exit 0
-+
-+
-+
-+3. CPUFreq core and interfaces
-+===============================
-+
-+3.1 General information
-+*************************
-+
-+The CPUFreq core code is located in linux/kernel/cpufreq.c. This
-+cpufreq code offers a standardized interface for the CPUFreq
-+architecture drivers (those pieces of code that do the actual
-+frequency transition), as well as to "notifiers". These are device
-+drivers or other part of the kernel that need to be informed of
-+frequency changes (like timing code) or even need to force certain
-+speed limits (like LCD drivers on ARM architecture). Aditionally, the
-+kernel "constant" loops_per_jiffy is updated on frequency changes
-+here.
-+
-+
-+3.2 CPUFreq notifiers
-+***********************
-+
-+CPUFreq notifiers are kernel code that need to be called to either
-+a) define certain minimum or maximum speed settings,
-+b) be informed of frequency changes in advance of the transition, or
-+c) be informed of frequency changes directly after the transition.
-+
-+A standard kernel notifier interface is offered for this. See
-+linux/include/linux/notifier.h for details on notifiers.
-+
-+
-+Data and value passed to CPUFreq notifiers
-+------------------------------------------
-+The second argument passed to any notifier is an unsigned int stating
-+the phase of the transition:
-+CPUFREQ_MINMAX during the process of determing a valid new CPU
-+ frequency,
-+CPUFREQ_PRECHANGE right before the transition, and
-+CPUFREQ_POSTCHANGE right after the transition.
-+
-+The third argument, a void *pointer, points to a struct
-+cpufreq_freqs. This consists of four values: min, max, cur and new.
-+
-+min and max are the current speed limits. Please note: Never update
-+these values directly, use cpufreq_updateminmax(struct cpufreq_freqs
-+*freqs, unsigned int min, unsigned int max) instead. cur is the
-+current/old speed, and new is the new speed, but might only be valid
-+on CPUFREQ_PRECHANGE or CPUFREQ_POSTCHANGE.
-+
-+Each notifier gets called all three times on any transition:
-+
-+CPUFREQ_MINMAX
-+Here the notifier is supposed to update the min and max values to the
-+limits the protected device / kernel code needs. As stated above,
-+always use cpufreq_updateminmax for this.
-+
-+CPUFREQ_PRECHANGE
-+CPUFREQ_POSTCHANGE
-+Here the notifier is supposed to update all internal (e.g. device
-+driver) code which is dependend on the CPU frequency.
-+
-+
-+3.3 CPUFreq architecture drivers
-+**********************************
-+
-+CPUFreq architecture drivers are the pieces of kernel code that
-+actually perform CPU frequency transitions. These need to be
-+initialised seperately (seperate initcalls), and may be
-+modularized. They interact with the CPUFreq core in the following way:
-+
-+
-+cpufreq_register()
-+------------------
-+cpufreq_register registers an arch driver to the CPUFreq core. Please
-+note that only one arch driver may be registered at any time, -EBUSY
-+is returned when an arch driver is already registered. The argument to
-+cpufreq_register, cpufreq_driver_t driver, is described later.
-+
-+
-+cpufreq_unregister()
-+--------------------
-+cpufreq_unregister unregisters an arch driver, e.g. on module
-+unloading. Please note that there is no check done that this is called
-+from the driver which actually registered itself to the core, so
-+please only call this function when you are sure the arch driver got
-+registered correctly before.
-+
-+
-+struct cpufreq_driver
-+----------------
-+On initialisation, the arch driver is supposed to pass the following
-+entries in struct cpufreq_driver cpufreq_driver:
-+
-+cpufreq_verify_t validate: This is a pointer to a function with the
-+following definition:
-+ unsigned int validating_function (unsigned int kHz).
-+It is called right before a transition occurs. The proposed new
-+speed setting is passed as an argument in kHz; the validating code
-+should verify this is a valid speed setting which is currently
-+supported by the CPU. It shall return the closest valid CPU frequency
-+in kHz.
-+
-+cpufreq_setspeed_t setspeed: This is a pointer to a function with the
-+following definition:
-+ void setspeed_function (unsigned int kHz).
-+This function shall perform the transition to the new CPU frequency
-+given as argument in kHz. Note that this argument is exactly the same
-+as the one returned by cpufreq_verify_t validate.
-+
-+
-+unsigned int freq.cur: The current CPU core frequency. Note that this
-+is a requirement while the next two entries are optional.
-+
-+
-+unsigned int freq.min (optional): The minimal CPU core frequency this
-+CPU supports. This value may be limited further by the
-+cpufreq_verify_t validate function, and so this value should be the
-+minimal core frequency allowed "theoretically" on this system in this
-+configuration.
-+
-+
-+unsigned int freq.max (optional): The maximum CPU core frequency this
-+CPU supports. This value may be limited further by the
-+cpufreq_verify_t validate function, and so this value should be the
-+maximum core frequency allowed "theoretically" on this system in this
-+configuration.
-+
-+
-+Some Requirements to CPUFreq architecture drivers
-+-------------------------------------------------
-+* Only call cpufreq_register() when the ability to switch CPU
-+ frequencies is _verified_ or can't be missing
-+* cpufreq_unregister() may only be called if cpufreq_register() has
-+ been successfully(!) called before
-+* All CPUs have to be set to the same speed whenever setspeed() is
-+ called
-+* Be aware that there is currently no error management in the
-+ setspeed() code in the CPUFreq core. So only call yourself a
-+ cpufreq_driver if you are really a working cpufreq_driver!
-+
-+
-+
-+4. Mailing list and Links
-+**************************
-+
-+
-+Mailing List
-+------------
-+There is a CPU frequency changing CVS commit and general list where
-+you can report bugs, problems or submit patches. To post a message,
-+send an email to cpufreq@www.linux.org.uk, to subscribe go to
-+http://www.linux.org.uk/mailman/listinfo/cpufreq. Previous post to the
-+mailing list are available to subscribers at
-+http://www.linux.org.uk/mailman/private/cpufreq/.
-+
-+
-+Links
-+-----
-+the FTP archives:
-+* ftp://ftp.linux.org.uk/pub/linux/cpufreq/
-+
-+how to access the CVS repository:
-+* http://www.arm.linux.org.uk/cvs/
-+
-+the CPUFreq Mailing list:
-+* http://www.linux.org.uk/mailman/listinfo/cpufreq
-+
-+Clock and voltage scaling for the SA-1100:
-+* http://www.lart.tudelft.nl/projects/scaling
-+
-+CPUFreq project homepage
-+* http://www.brodo.de/cpufreq/
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/Documentation/l3/structure 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,36 @@
-+L3 Bus Driver
-+-------------
-+
-+The structure of the driver is as follows:
-+
-+ +----------+ +----------+ +----------+
-+ | client 1 | | client 2 | | client 3 |
-+ +-----^----+ +----^-----+ +----^-----+
-+ | | |
-+ +-----v--------------v---------------v-----+
-+ | |
-+ +-----^-------+ +-------^-----+
-+ | | core | |
-+ +-----v----+ | | +----v-----+
-+ | device | | | | device |
-+ | driver 1 | | | | driver 2 |
-+ +-----^----+ | | +----^-----+
-+ | | services | |
-+ +-----v-------+ +-------v-----+
-+ | |
-+ +-----------------^----^-------------------+
-+ | |
-+ | +-v---------+
-+ | | algorithm |
-+ | | driver |
-+ | +-v---------+
-+ | |
-+ +-v----v-+
-+ | bus |
-+ | driver |
-+ +--------+
-+
-+Clients talk to the core to attach device drivers and bus adapters, and
-+to instruct device drivers to perform actions. Device drivers then talk
-+to the core to perform L3 bus transactions via the algorithm driver and
-+ultimately bus driver.
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/Documentation/serial/driver 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,208 @@
-+
-+ Low Level Serial API
-+ --------------------
-+
-+
-+ $Id$
-+
-+
-+This document is meant as a brief overview of some aspects of the new serial
-+driver. It is not complete, any questions you have should be directed to
-+<rmk@arm.linux.org.uk>
-+
-+The reference implementation is contained within serial_amba.c.
-+
-+
-+
-+Low Level Serial Hardware Driver
-+--------------------------------
-+
-+The low level serial hardware driver is responsible for supplying port
-+information (defined by uart_port) and a set of control methods (defined
-+by uart_ops) to the core serial driver. The low level driver is also
-+responsible for handling interrupts for the port, and providing any
-+console support.
-+
-+
-+Console Support
-+---------------
-+
-+The serial core provides a few helper functions. This includes identifing
-+the correct port structure (via uart_get_console) and decoding command line
-+arguments (uart_parse_options).
-+
-+
-+Locking
-+-------
-+
-+Generally, all locking is done by the core driver, except for the interrupt
-+functions. It is the responsibility of the low level hardware driver to
-+perform the necessary locking there using info->lock. (since it is running
-+in an interrupt, you only need to use spin_lock() and spin_unlock() from
-+the interrupt handler).
-+
-+
-+uart_ops
-+--------
-+
-+The uart_ops structure is the main interface between serial_core and the
-+hardware specific driver. It contains all the methods to control the
-+hardware.
-+
-+ tx_empty(port)
-+ This function tests whether the transmitter fifo and shifter
-+ for the port described by 'port' is empty. If it is empty,
-+ this function should return TIOCSER_TEMT, otherwise return 0.
-+ If the port does not support this operation, then it should
-+ return TIOCSER_TEMT.
-+
-+ set_mctrl(port, mctrl)
-+ This function sets the modem control lines for port described
-+ by 'port' to the state described by mctrl. The relevant bits
-+ of mctrl are:
-+ - TIOCM_RTS RTS signal.
-+ - TIOCM_DTR DTR signal.
-+ - TIOCM_OUT1 OUT1 signal.
-+ - TIOCM_OUT2 OUT2 signal.
-+ If the appropriate bit is set, the signal should be driven
-+ active. If the bit is clear, the signal should be driven
-+ inactive.
-+
-+ get_mctrl(port)
-+ Returns the current state of modem control inputs. The state
-+ of the outputs should not be returned, since the core keeps
-+ track of their state. The state information should include:
-+ - TIOCM_DCD state of DCD signal
-+ - TIOCM_CTS state of CTS signal
-+ - TIOCM_DSR state of DSR signal
-+ - TIOCM_RI state of RI signal
-+ The bit is set if the signal is currently driven active. If
-+ the port does not support CTS, DCD or DSR, the driver should
-+ indicate that the signal is permanently active. If RI is
-+ not available, the signal should not be indicated as active.
-+
-+ stop_tx(port,from_tty)
-+ Stop transmitting characters. This might be due to the CTS
-+ line becoming inactive or the tty layer indicating we want
-+ to stop transmission.
-+
-+ start_tx(port,nonempty,from_tty)
-+ start transmitting characters. (incidentally, nonempty will
-+ always be nonzero, and shouldn't be used - it will be dropped).
-+
-+ stop_rx(port)
-+ Stop receiving characters; the port is in the process of
-+ being closed.
-+
-+ enable_ms(port)
-+ Enable the modem status interrupts.
-+
-+ break_ctl(port,ctl)
-+ Control the transmission of a break signal. If ctl is
-+ nonzero, the break signal should be transmitted. The signal
-+ should be terminated when another call is made with a zero
-+ ctl.
-+
-+ startup(port,info)
-+ Grab any interrupt resources and initialise any low level driver
-+ state. Enable the port for reception. It should not activate
-+ RTS nor DTR; this will be done via a separate call to set_mctrl.
-+
-+ shutdown(port,info)
-+ Disable the port, disable any break condition that may be in
-+ effect, and free any interrupt resources. It should not disable
-+ RTS nor DTR; this will have already been done via a separate
-+ call to set_mctrl.
-+
-+ change_speed(port,cflag,iflag,quot)
-+ Change the port parameters, including word length, parity, stop
-+ bits. Update read_status_mask and ignore_status_mask to indicate
-+ the types of events we are interested in receiving. Relevant
-+ cflag bits are:
-+ CSIZE - word size
-+ CSTOPB - 2 stop bits
-+ PARENB - parity enable
-+ PARODD - odd parity (when PARENB is in force)
-+ CREAD - enable reception of characters (if not set,
-+ still receive characters from the port, but
-+ throw them away.
-+ CRTSCTS - if set, enable CTS status change reporting
-+ CLOCAL - if not set, enable modem status change
-+ reporting.
-+ Relevant iflag bits are:
-+ INPCK - enable frame and parity error events to be
-+ passed to the TTY layer.
-+ BRKINT
-+ PARMRK - both of these enable break events to be
-+ passed to the TTY layer.
-+
-+ IGNPAR - ignore parity and framing errors
-+ IGNBRK - ignore break errors, If IGNPAR is also
-+ set, ignore overrun errors as well.
-+ The interaction of the iflag bits is as follows (parity error
-+ given as an example):
-+ Parity error INPCK IGNPAR
-+ None n/a n/a character received
-+ Yes n/a 0 character discarded
-+ Yes 0 1 character received, marked as
-+ TTY_NORMAL
-+ Yes 1 1 character received, marked as
-+ TTY_PARITY
-+
-+ pm(port,state,oldstate)
-+ perform any power management related activities on the specified
-+ port. state indicates the new state (defined by ACPI D0-D3),
-+ oldstate indicates the previous state. Essentially, D0 means
-+ fully on, D3 means powered down.
-+
-+ This function should not be used to grab any resources.
-+
-+ type(port)
-+ Return a pointer to a string constant describing the specified
-+ port, or return NULL, in which case the string 'unknown' is
-+ substituted.
-+
-+ release_port(port)
-+ Release any memory and IO region resources currently in use by
-+ the port.
-+
-+ request_port(port)
-+ Request any memory and IO region resources required by the port.
-+ If any fail, no resources should be registered when this function
-+ returns, and it should return -EBUSY on failure.
-+
-+ config_port(port,type)
-+ Perform any autoconfiguration steps required for the port. `type`
-+ contains a bit mask of the required configuration. UART_CONFIG_TYPE
-+ indicates that the port requires detection and identification.
-+ port->type should be set to the type found, or PORT_UNKNOWN if
-+ no port was detected.
-+
-+ UART_CONFIG_IRQ indicates autoconfiguration of the interrupt signal,
-+ which should be probed using standard kernel autoprobing techniques.
-+ This is not necessary on platforms where ports have interrupts
-+ internally hard wired (eg, system on a chip implementations).
-+
-+ verify_port(port,serinfo)
-+ Verify the new serial port information contained within serinfo is
-+ suitable for this port type.
-+
-+ ioctl(port,cmd,arg)
-+ Perform any port specific IOCTLs. IOCTL commands must be defined
-+ using the standard numbering system found in <asm/ioctl.h>
-+
-+
-+Other notes
-+-----------
-+
-+It is intended some day to drop the 'unused' entries from uart_port, and
-+allow low level drivers to register their own individual uart_port's with
-+the core. This will allow drivers to use uart_port as a pointer to a
-+structure containing both the uart_port entry with their own extensions,
-+thus:
-+
-+ struct my_port {
-+ struct uart_port port;
-+ int my_stuff;
-+ };
-+
---- linux-2.4.25/Makefile~2.4.25-vrs2.patch 2004-02-18 14:36:32.000000000 +0100
-+++ linux-2.4.25/Makefile 2004-03-31 17:15:08.000000000 +0200
-@@ -1,7 +1,7 @@
- VERSION = 2
- PATCHLEVEL = 4
- SUBLEVEL = 25
--EXTRAVERSION =
-+EXTRAVERSION =-vrs2
-
- KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
-
-@@ -137,7 +137,10 @@
-
- DRIVERS-$(CONFIG_ACPI_BOOT) += drivers/acpi/acpi.o
- DRIVERS-$(CONFIG_PARPORT) += drivers/parport/driver.o
--DRIVERS-y += drivers/char/char.o \
-+DRIVERS-$(CONFIG_I2C) += drivers/i2c/i2c.o
-+DRIVERS-$(CONFIG_L3) += drivers/l3/l3.o
-+DRIVERS-y += drivers/serial/serial.o \
-+ drivers/char/char.o \
- drivers/block/block.o \
- drivers/misc/misc.o \
- drivers/net/net.o
-@@ -161,6 +164,7 @@
- DRIVERS-y += drivers/cdrom/driver.o
- endif
-
-+DRIVERS-$(CONFIG_SSI) += drivers/ssi/ssi.o
- DRIVERS-$(CONFIG_SOUND) += drivers/sound/sounddrivers.o
- DRIVERS-$(CONFIG_PCI) += drivers/pci/driver.o
- DRIVERS-$(CONFIG_MTD) += drivers/mtd/mtdlink.o
-@@ -186,7 +190,6 @@
- DRIVERS-$(CONFIG_HIL) += drivers/hil/hil.o
- DRIVERS-$(CONFIG_I2O) += drivers/message/i2o/i2o.o
- DRIVERS-$(CONFIG_IRDA) += drivers/net/irda/irda.o
--DRIVERS-$(CONFIG_I2C) += drivers/i2c/i2c.o
- DRIVERS-$(CONFIG_PHONE) += drivers/telephony/telephony.o
- DRIVERS-$(CONFIG_MD) += drivers/md/mddev.o
- DRIVERS-$(CONFIG_GSC) += drivers/gsc/gscbus.o
-@@ -194,6 +197,8 @@
- DRIVERS-$(CONFIG_HOTPLUG_PCI) += drivers/hotplug/vmlinux-obj.o
- DRIVERS-$(CONFIG_ISDN_BOOL) += drivers/isdn/vmlinux-obj.o
- DRIVERS-$(CONFIG_CRYPTO) += crypto/crypto.o
-+DRIVERS-$(CONFIG_PLD) += drivers/pld/pld.o
-+DRIVERS-$(CONFIG_ARCH_AT91RM9200) += drivers/at91/at91drv.o
-
- DRIVERS := $(DRIVERS-y)
-
-@@ -273,11 +278,6 @@
-
- export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS
-
--.S.s:
-- $(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -traditional -o $*.s $<
--.S.o:
-- $(CC) $(AFLAGS) $(AFLAGS_KERNEL) -traditional -c -o $*.o $<
--
- Version: dummy
- @rm -f include/linux/compile.h
-
---- linux-2.4.25/Rules.make~2.4.25-vrs2.patch 2004-02-18 14:36:30.000000000 +0100
-+++ linux-2.4.25/Rules.make 2004-03-31 17:15:08.000000000 +0200
-@@ -51,15 +51,15 @@
- #
-
- %.s: %.c
-- $(CC) $(CFLAGS) $(EXTRA_CFLAGS_nostdinc) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_$@) -S $< -o $@
-+ $(CC) $(CFLAGS) $(EXTRA_CFLAGS_nostdinc) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_$(*F)) $(CFLAGS_$@) -S $< -o $@
-
- %.i: %.c
-- $(CPP) $(CFLAGS) $(EXTRA_CFLAGS_nostdinc) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_$@) $< > $@
-+ $(CPP) $(CFLAGS) $(EXTRA_CFLAGS_nostdinc) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_$(*F)) $(CFLAGS_$@) $< > $@
-
- %.o: %.c
-- $(CC) $(CFLAGS) $(EXTRA_CFLAGS_nostdinc) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_$@) -c -o $@ $<
-+ $(CC) $(CFLAGS) $(EXTRA_CFLAGS_nostdinc) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_$(*F)) $(CFLAGS_$@) -c -o $@ $<
- @ ( \
-- echo 'ifeq ($(strip $(subst $(comma),:,$(CFLAGS) $(EXTRA_CFLAGS_nostdinc) $(CFLAGS_$@))),$$(strip $$(subst $$(comma),:,$$(CFLAGS) $$(EXTRA_CFLAGS_nostdinc) $$(CFLAGS_$@))))' ; \
-+ echo 'ifeq ($(strip $(subst $(comma),:,$(CFLAGS) $(EXTRA_CFLAGS_nostdinc) $(CFLAGS_$(*F)) $(CFLAGS_$@))),$$(strip $$(subst $$(comma),:,$$(CFLAGS) $$(EXTRA_CFLAGS_nostdinc) $$(CFLAGS_$(*F)) $$(CFLAGS_$@))))' ; \
- echo 'FILES_FLAGS_UP_TO_DATE += $@' ; \
- echo 'endif' \
- ) > $(dir $@)/.$(notdir $@).flags
-@@ -272,7 +272,8 @@
- endif # CONFIG_MODVERSIONS
-
- ifneq "$(strip $(export-objs))" ""
--$(export-objs): $(export-objs:.o=.c) $(TOPDIR)/include/linux/modversions.h
-+$(export-objs): $(TOPDIR)/include/linux/modversions.h
-+$(export-objs): %.o: %.c
- $(CC) $(CFLAGS) $(EXTRA_CFLAGS_nostdinc) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) $(CFLAGS_$@) -DEXPORT_SYMTAB -c $(@:.o=.c)
- @ ( \
- echo 'ifeq ($(strip $(subst $(comma),:,$(CFLAGS) $(EXTRA_CFLAGS_nostdinc) $(CFLAGS_$@) -DEXPORT_SYMTAB)),$$(strip $$(subst $$(comma),:,$$(CFLAGS) $$(EXTRA_CFLAGS_nostdinc) $$(CFLAGS_$@) -DEXPORT_SYMTAB)))' ; \
---- linux-2.4.25/arch/alpha/config.in~2.4.25-vrs2.patch 2004-02-18 14:36:30.000000000 +0100
-+++ linux-2.4.25/arch/alpha/config.in 2004-03-31 17:15:08.000000000 +0200
-@@ -7,6 +7,7 @@
- define_bool CONFIG_UID16 n
- define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
- define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
-+define_bool CONFIG_GENERIC_ISA_DMA y
-
- mainmenu_name "Kernel configuration of Linux for Alpha machines"
-
---- linux-2.4.25/arch/arm/Makefile~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/Makefile 2004-03-31 17:15:08.000000000 +0200
-@@ -52,7 +52,7 @@
-
- CFLAGS_BOOT :=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Uarm
- CFLAGS +=$(apcs-y) $(arch-y) $(tune-y) -mshort-load-bytes -msoft-float -Uarm
--AFLAGS +=$(apcs-y) $(arch-y) -mno-fpu -msoft-float
-+AFLAGS +=$(apcs-y) $(arch-y) -msoft-float
-
- ifeq ($(CONFIG_CPU_26),y)
- PROCESSOR := armo
---- linux-2.4.25/arch/arm/boot/compressed/head.S~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/boot/compressed/head.S 2004-03-31 17:15:08.000000000 +0200
-@@ -40,6 +40,14 @@
- .macro writeb, rb
- strb \rb, [r3, #0x3f8 << 2]
- .endm
-+#elif defined(CONFIG_ARCH_RISCSTATION)
-+ .macro loadsp, rb
-+ mov \rb, #0x03000000
-+ orr \rb, \rb, #0x00010000
-+ .endm
-+ .macro writeb, rb
-+ strb \rb, [r3, #0x3f8 << 2]
-+ .endm
- #elif defined(CONFIG_ARCH_INTEGRATOR)
- .macro loadsp, rb
- mov \rb, #0x16000000
-@@ -396,6 +404,20 @@
- mcr p15, 0, r0, c1, c0, 0 @ load control register
- mov pc, r12
-
-+__arm7_cache_on:
-+ mov r12, lr
-+ bl __setup_mmu
-+ mov r0, #0
-+ mcr p15, 0, r0, c7, c0, 0 @ invalidate whole cache v3
-+ mcr p15, 0, r0, c5, c0, 0 @ invalidate whole TLB v3
-+ mcr p15, 0, r3, c2, c0, 0 @ load page table pointer
-+ mov r0, #-1
-+ mcr p15, 0, r0, c3, c0, 0 @ load domain access control
-+ mov r0, #0x7d
-+ mcr p15, 0, r0, c1, c0, 0 @ load control register
-+ mov pc, r12
-+
-+
- /*
- * All code following this line is relocatable. It is relocated by
- * the above code to the end of the decompressed kernel image and
-@@ -480,9 +502,9 @@
-
- .word 0x41007000 @ ARM7/710
- .word 0xfff8fe00
-+ b __arm7_cache_on
- b __arm7_cache_off
-- b __arm7_cache_off
-- mov pc, lr
-+ b __armv3_cache_flush
-
- .word 0x41807200 @ ARM720T (writethrough)
- .word 0xffffff00
-@@ -490,14 +512,14 @@
- b __armv4_cache_off
- mov pc, lr
-
-- .word 0x41129200 @ ARM920T
-- .word 0xff00fff0
-+ .word 0x41009200 @ ARM920T, ARM922T, ARM926TEJ-S
-+ .word 0xff00ff90
- b __armv4_cache_on
- b __armv4_cache_off
- b __armv4_cache_flush
-
-- .word 0x41029220 @ ARM922T
-- .word 0xff00fff0
-+ .word 0x4100a200 @ ARM1020T/E, ARM1022E, ARM1026TEJ-S
-+ .word 0xff00ff90
- b __armv4_cache_on
- b __armv4_cache_off
- b __armv4_cache_flush
---- linux-2.4.25/arch/arm/config.in~2.4.25-vrs2.patch 2004-02-18 14:36:30.000000000 +0100
-+++ linux-2.4.25/arch/arm/config.in 2004-03-31 17:15:08.000000000 +0200
-@@ -144,6 +144,7 @@
- mainmenu_option next_comment
- comment 'AT91RM9200 Implementations'
- dep_bool ' Atmel AT91RM9200 Development Board' CONFIG_ARCH_AT91RM9200DK $CONFIG_ARCH_AT91RM9200
-+dep_bool ' Cogent CSB337' CONFIG_MACH_CSB337 $CONFIG_ARCH_AT91RM9200
- endmenu
-
- mainmenu_option next_comment
-@@ -189,6 +190,12 @@
- define_bool CONFIG_ARCH_ACORN n
- fi
-
-+if [ "$CONFIG_ARCH_CAMELOT" = "y" ]; then
-+ define_bool CONFIG_PLD y
-+else
-+ define_bool CONFIG_PLD n
-+fi
-+
- #####################################################################
- # Footbridge support
- if [ "$CONFIG_ARCH_CO285" = "y" -o \
-@@ -315,26 +322,42 @@
- # ARM922T
- if [ "$CONFIG_ARCH_CAMELOT" = "y" ]; then
- define_bool CONFIG_CPU_ARM922T y
-- define_bool CONFIG_PLD y
- else
-- define_bool CONFIG_CPU_ARM922T n
-- define_bool CONFIG_PLD n
-+ if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
-+ bool 'Support ARM922T(Excalibur) processor' CONFIG_ARM922T
-+ else
-+ define_bool CONFIG_CPU_ARM922T n
-+ fi
- fi
-
- # ARM926T
- if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
-- bool 'Support ARM926T processor' CONFIG_CPU_ARM926T
-+ bool 'Support ARM926TEJ-S processor' CONFIG_CPU_ARM926T
- else
- define_bool CONFIG_CPU_ARM926T n
- fi
-
- # ARM1020
- if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
-- bool 'Support ARM1020 processor' CONFIG_CPU_ARM1020
-+ bool 'Support ARM1020T (Rev0) processor' CONFIG_CPU_ARM1020
- else
- define_bool CONFIG_CPU_ARM1020 n
- fi
-
-+# ARM1020E
-+if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
-+ bool 'Support ARM1020E (Rev1) processor' CONFIG_CPU_ARM1020E
-+else
-+ define_bool CONFIG_CPU_ARM1020E n
-+fi
-+
-+# ARM1022
-+if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
-+ bool 'Support ARM1022 processor' CONFIG_CPU_ARM1020E
-+else
-+ define_bool CONFIG_CPU_ARM1022 n
-+fi
-+
- # ARM1026EJ-S
- if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
- bool 'Support ARM1026EJ-S processor' CONFIG_CPU_ARM1026
-@@ -388,25 +411,29 @@
-
- if [ "$CONFIG_CPU_ARM720T" = "y" -o "$CONFIG_CPU_ARM920T" = "y" -o \
- "$CONFIG_CPU_ARM922T" = "y" -o "$CONFIG_CPU_ARM926T" = "y" -o \
-- "$CONFIG_CPU_ARM1020" = "y" -o "$CONFIG_CPU_ARM1026" = "y" ]; then
-+ "$CONFIG_CPU_ARM1020" = "y" -o "$CONFIG_CPU_ARM1020E" = "y" -o \
-+ "$CONFIG_CPU_ARM1022" = "y" -o "$CONFIG_CPU_ARM1026" = "y" ]; then
- dep_bool 'Support Thumb instructions (EXPERIMENTAL)' CONFIG_ARM_THUMB $CONFIG_EXPERIMENTAL
- fi
- if [ "$CONFIG_CPU_ARM920T" = "y" -o "$CONFIG_CPU_ARM922T" = "y" -o \
- "$CONFIG_CPU_ARM926T" = "y" -o "$CONFIG_CPU_ARM1020" = "y" -o \
-+ "$CONFIG_CPU_ARM1020E" = "y" -o "$CONFIG_CPU_ARM1022" = "y" -o \
- "$CONFIG_CPU_ARM1026" = "y" ]; then
- bool 'Disable I-Cache' CONFIG_CPU_ICACHE_DISABLE
- bool 'Disable D-Cache' CONFIG_CPU_DCACHE_DISABLE
-- if [ "$CONFIG_CPU_DISABLE_DCACHE" = "n" ]; then
-+ if [ "$CONFIG_CPU_DCACHE_DISABLE" = "n" ]; then
- bool 'Force write through D-cache' CONFIG_CPU_DCACHE_WRITETHROUGH
- fi
- fi
- if [ "$CONFIG_CPU_ARM926T" = "y" -o "$CONFIG_CPU_ARM1020" = "y" -o \
-+ "$CONFIG_CPU_ARM1020E" = "y" -o "$CONFIG_CPU_ARM1022" = "y" -o \
- "$CONFIG_CPU_ARM1026" = "y" ]; then
- if [ "$CONFIG_CPU_ICACHE_DISABLE" = "n" -o "$CONFIG_CPU_DCACHE_DISABLE" = "n" ]; then
- bool 'Round robin I and D cache replacement algorithm' CONFIG_CPU_CACHE_ROUND_ROBIN
- fi
- fi
--if [ "$CONFIG_CPU_ARM1020" = "y" -o "$CONFIG_CPU_ARM1026" = "y" ]; then
-+if [ "$CONFIG_CPU_ARM1020" = "y" -o "$CONFIG_CPU_ARM1020E" = "y" -o \
-+ "$CONFIG_CPU_ARM1026" = "y" -o "$CONFIG_CPU_ARM1022" = "y" ]; then
- bool 'Disable branch prediction' CONFIG_CPU_BPREDICT_DISABLE
- fi
-
-@@ -729,10 +756,7 @@
- dep_bool ' Kernel low-level debugging functions' CONFIG_DEBUG_LL $CONFIG_DEBUG_KERNEL
- dep_bool ' Kernel low-level debugging messages via footbridge serial port' CONFIG_DEBUG_DC21285_PORT $CONFIG_DEBUG_LL $CONFIG_FOOTBRIDGE
- dep_bool ' Kernel low-level debugging messages via UART2' CONFIG_DEBUG_CLPS711X_UART2 $CONFIG_DEBUG_LL $CONFIG_ARCH_CLPS711X
--
--int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0
--
- endmenu
-
--source crypto/Config.in
- source lib/Config.in
-+
---- linux-2.4.25/arch/arm/def-configs/at91rm9200dk~2.4.25-vrs2.patch 2004-02-18 14:36:30.000000000 +0100
-+++ linux-2.4.25/arch/arm/def-configs/at91rm9200dk 2004-03-31 17:15:08.000000000 +0200
-@@ -111,6 +111,7 @@
- # AT91RM9200 Implementations
- #
- CONFIG_ARCH_AT91RM9200DK=y
-+# CONFIG_MACH_CSB337 is not set
-
- #
- # CLPS711X/EP721X Implementations
-@@ -125,6 +126,7 @@
- # CONFIG_ARCH_EP7211 is not set
- # CONFIG_ARCH_EP7212 is not set
- # CONFIG_ARCH_ACORN is not set
-+# CONFIG_PLD is not set
- # CONFIG_FOOTBRIDGE is not set
- # CONFIG_FOOTBRIDGE_HOST is not set
- # CONFIG_FOOTBRIDGE_ADDIN is not set
-@@ -135,9 +137,10 @@
- # CONFIG_CPU_ARM720T is not set
- CONFIG_CPU_ARM920T=y
- # CONFIG_CPU_ARM922T is not set
--# CONFIG_PLD is not set
- # CONFIG_CPU_ARM926T is not set
- # CONFIG_CPU_ARM1020 is not set
-+# CONFIG_CPU_ARM1020E is not set
-+# CONFIG_CPU_ARM1022 is not set
- # CONFIG_CPU_ARM1026 is not set
- # CONFIG_CPU_SA110 is not set
- # CONFIG_CPU_SA1100 is not set
-@@ -146,6 +149,7 @@
- # CONFIG_ARM_THUMB is not set
- # CONFIG_CPU_ICACHE_DISABLE is not set
- # CONFIG_CPU_DCACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
- # CONFIG_DISCONTIGMEM is not set
-
- #
-@@ -164,6 +168,7 @@
- # CONFIG_BSD_PROCESS_ACCT is not set
- CONFIG_SYSCTL=y
- CONFIG_FPE_NWFPE=y
-+# CONFIG_FPE_NWFPE_XP is not set
- # CONFIG_FPE_FASTFPE is not set
- CONFIG_KCORE_ELF=y
- # CONFIG_KCORE_AOUT is not set
-@@ -173,6 +178,9 @@
- # CONFIG_PM is not set
- # CONFIG_ARTHUR is not set
- CONFIG_CMDLINE="mem=32M console=ttyS0,115200 initrd=0x20210000,3145728 root=/dev/ram rw"
-+CONFIG_LEDS=y
-+CONFIG_LEDS_TIMER=y
-+# CONFIG_LEDS_CPU is not set
- CONFIG_ALIGNMENT_TRAP=y
-
- #
-@@ -204,6 +212,7 @@
- # CONFIG_MTD_CFI_ADV_OPTIONS is not set
- # CONFIG_MTD_CFI_INTELEXT is not set
- CONFIG_MTD_CFI_AMDSTD=y
-+# CONFIG_MTD_CFI_STAA is not set
- # CONFIG_MTD_RAM is not set
- # CONFIG_MTD_ROM is not set
- # CONFIG_MTD_ABSENT is not set
-@@ -230,7 +239,9 @@
- # CONFIG_MTD_AUTCPU12 is not set
- # CONFIG_MTD_EDB7312 is not set
- # CONFIG_MTD_IMPA7 is not set
-+# CONFIG_MTD_CEIVA is not set
- # CONFIG_MTD_PCI is not set
-+# CONFIG_MTD_PCMCIA is not set
-
- #
- # Self-contained MTD device drivers
-@@ -250,9 +261,9 @@
- # NAND Flash Device Drivers
- #
- CONFIG_MTD_NAND=y
--CONFIG_MTD_NAND_ECC=y
- # CONFIG_MTD_NAND_VERIFY_WRITE is not set
--CONFIG_MTD_AT91_SMARTMEDIA=y
-+CONFIG_MTD_NAND_IDS=y
-+# CONFIG_MTD_AT91_SMARTMEDIA is not set
-
- #
- # Plug and Play configuration
-@@ -269,6 +280,7 @@
- # CONFIG_BLK_CPQ_DA is not set
- # CONFIG_BLK_CPQ_CISS_DA is not set
- # CONFIG_CISS_SCSI_TAPE is not set
-+# CONFIG_CISS_MONITOR_THREAD is not set
- # CONFIG_BLK_DEV_DAC960 is not set
- # CONFIG_BLK_DEV_UMEM is not set
- # CONFIG_BLK_DEV_LOOP is not set
-@@ -276,6 +288,7 @@
- CONFIG_BLK_DEV_RAM=y
- CONFIG_BLK_DEV_RAM_SIZE=8192
- CONFIG_BLK_DEV_INITRD=y
-+# CONFIG_BLK_STATS is not set
-
- #
- # Multi-device support (RAID and LVM)
-@@ -312,6 +325,12 @@
- # CONFIG_SYN_COOKIES is not set
- # CONFIG_IPV6 is not set
- # CONFIG_KHTTPD is not set
-+
-+#
-+# SCTP Configuration (EXPERIMENTAL)
-+#
-+CONFIG_IPV6_SCTP__=y
-+# CONFIG_IP_SCTP is not set
- # CONFIG_ATM is not set
- # CONFIG_VLAN_8021Q is not set
- # CONFIG_IPX is not set
-@@ -382,10 +401,12 @@
- #
- # CONFIG_ACENIC is not set
- # CONFIG_DL2K is not set
-+# CONFIG_E1000 is not set
- # CONFIG_MYRI_SBUS is not set
- # CONFIG_NS83820 is not set
- # CONFIG_HAMACHI is not set
- # CONFIG_YELLOWFIN is not set
-+# CONFIG_R8169 is not set
- # CONFIG_SK98LIN is not set
- # CONFIG_TIGON3 is not set
- # CONFIG_FDDI is not set
-@@ -455,6 +476,8 @@
- # CONFIG_INPUT_MOUSEDEV is not set
- # CONFIG_INPUT_JOYDEV is not set
- # CONFIG_INPUT_EVDEV is not set
-+# CONFIG_INPUT_UINPUT is not set
-+# CONFIG_INPUT_MX1TS is not set
-
- #
- # Character devices
-@@ -502,6 +525,7 @@
- #
- CONFIG_I2C=y
- # CONFIG_I2C_ALGOBIT is not set
-+# CONFIG_SCx200_ACB is not set
- # CONFIG_I2C_ALGOPCF is not set
- CONFIG_I2C_AT91=y
- CONFIG_I2C_CHARDEV=y
-@@ -528,6 +552,11 @@
- #
- # CONFIG_INPUT_GAMEPORT is not set
- # CONFIG_QIC02_TAPE is not set
-+# CONFIG_IPMI_HANDLER is not set
-+# CONFIG_IPMI_PANIC_EVENT is not set
-+# CONFIG_IPMI_DEVICE_INTERFACE is not set
-+# CONFIG_IPMI_KCS is not set
-+# CONFIG_IPMI_WATCHDOG is not set
-
- #
- # Watchdog Cards
-@@ -536,12 +565,14 @@
- CONFIG_WATCHDOG_NOWAYOUT=y
- # CONFIG_ACQUIRE_WDT is not set
- # CONFIG_ADVANTECH_WDT is not set
-+# CONFIG_ALIM1535_WDT is not set
- # CONFIG_ALIM7101_WDT is not set
- # CONFIG_SC520_WDT is not set
- # CONFIG_PCWATCHDOG is not set
- # CONFIG_21285_WATCHDOG is not set
- # CONFIG_977_WATCHDOG is not set
- # CONFIG_SA1100_WATCHDOG is not set
-+# CONFIG_EPXA_WATCHDOG is not set
- # CONFIG_OMAHA_WATCHDOG is not set
- CONFIG_AT91_WATCHDOG=y
- # CONFIG_EUROTECH_WDT is not set
-@@ -551,11 +582,16 @@
- # CONFIG_MIXCOMWD is not set
- # CONFIG_60XX_WDT is not set
- # CONFIG_SC1200_WDT is not set
-+# CONFIG_SCx200_WDT is not set
- # CONFIG_SOFT_WATCHDOG is not set
- # CONFIG_W83877F_WDT is not set
- # CONFIG_WDT is not set
- # CONFIG_WDTPCI is not set
- # CONFIG_MACHZ_WDT is not set
-+# CONFIG_AMD7XX_TCO is not set
-+# CONFIG_SCx200 is not set
-+# CONFIG_SCx200_GPIO is not set
-+# CONFIG_AMD_PM768 is not set
- # CONFIG_NVRAM is not set
- # CONFIG_RTC is not set
- CONFIG_AT91_RTC=y
-@@ -568,6 +604,10 @@
- #
- # CONFIG_FTAPE is not set
- # CONFIG_AGP is not set
-+
-+#
-+# Direct Rendering Manager (XFree86 DRI support)
-+#
- # CONFIG_DRM is not set
-
- #
-@@ -579,6 +619,7 @@
- # File systems
- #
- # CONFIG_QUOTA is not set
-+# CONFIG_QFMT_V2 is not set
- # CONFIG_AUTOFS_FS is not set
- # CONFIG_AUTOFS4_FS is not set
- # CONFIG_REISERFS_FS is not set
-@@ -588,6 +629,9 @@
- # CONFIG_ADFS_FS_RW is not set
- # CONFIG_AFFS_FS is not set
- # CONFIG_HFS_FS is not set
-+# CONFIG_HFSPLUS_FS is not set
-+# CONFIG_BEFS_FS is not set
-+# CONFIG_BEFS_DEBUG is not set
- # CONFIG_BFS_FS is not set
- # CONFIG_EXT3_FS is not set
- # CONFIG_JBD is not set
-@@ -605,6 +649,9 @@
- # CONFIG_ISO9660_FS is not set
- # CONFIG_JOLIET is not set
- # CONFIG_ZISOFS is not set
-+# CONFIG_JFS_FS is not set
-+# CONFIG_JFS_DEBUG is not set
-+# CONFIG_JFS_STATISTICS is not set
- # CONFIG_MINIX_FS is not set
- # CONFIG_VXFS_FS is not set
- # CONFIG_NTFS_FS is not set
-@@ -624,6 +671,11 @@
- # CONFIG_UDF_RW is not set
- # CONFIG_UFS_FS is not set
- # CONFIG_UFS_FS_WRITE is not set
-+# CONFIG_XFS_FS is not set
-+# CONFIG_XFS_QUOTA is not set
-+# CONFIG_XFS_RT is not set
-+# CONFIG_XFS_TRACE is not set
-+# CONFIG_XFS_DEBUG is not set
-
- #
- # Network File Systems
-@@ -632,9 +684,11 @@
- # CONFIG_INTERMEZZO_FS is not set
- # CONFIG_NFS_FS is not set
- # CONFIG_NFS_V3 is not set
-+# CONFIG_NFS_DIRECTIO is not set
- # CONFIG_ROOT_NFS is not set
- # CONFIG_NFSD is not set
- # CONFIG_NFSD_V3 is not set
-+# CONFIG_NFSD_TCP is not set
- # CONFIG_SUNRPC is not set
- # CONFIG_LOCKD is not set
- # CONFIG_SMB_FS is not set
-@@ -648,7 +702,6 @@
- # CONFIG_NCPFS_NLS is not set
- # CONFIG_NCPFS_EXTRAS is not set
- # CONFIG_ZISOFS_FS is not set
--# CONFIG_ZLIB_FS_INFLATE is not set
-
- #
- # Partition Types
-@@ -674,16 +727,18 @@
- # CONFIG_USB_DEBUG is not set
- # CONFIG_USB_DEVICEFS is not set
- # CONFIG_USB_BANDWIDTH is not set
--# CONFIG_USB_LONG_TIMEOUT is not set
- # CONFIG_USB_EHCI_HCD is not set
- # CONFIG_USB_UHCI is not set
- # CONFIG_USB_UHCI_ALT is not set
- # CONFIG_USB_OHCI is not set
- # CONFIG_USB_OHCI_SA1111 is not set
-+# CONFIG_USB_SL811HS_ALT is not set
-+# CONFIG_USB_SL811HS is not set
- CONFIG_USB_OHCI_AT91=y
- # CONFIG_USB_AUDIO is not set
- # CONFIG_USB_EMI26 is not set
- # CONFIG_USB_BLUETOOTH is not set
-+# CONFIG_USB_MIDI is not set
- # CONFIG_USB_STORAGE is not set
- # CONFIG_USB_STORAGE_DEBUG is not set
- # CONFIG_USB_STORAGE_DATAFAB is not set
-@@ -692,6 +747,7 @@
- # CONFIG_USB_STORAGE_DPCM is not set
- # CONFIG_USB_STORAGE_HP8200e is not set
- # CONFIG_USB_STORAGE_SDDR09 is not set
-+# CONFIG_USB_STORAGE_SDDR55 is not set
- # CONFIG_USB_STORAGE_JUMPSHOT is not set
- # CONFIG_USB_ACM is not set
- # CONFIG_USB_PRINTER is not set
-@@ -700,7 +756,10 @@
- # CONFIG_USB_HIDDEV is not set
- # CONFIG_USB_KBD is not set
- # CONFIG_USB_MOUSE is not set
-+# CONFIG_USB_AIPTEK is not set
- # CONFIG_USB_WACOM is not set
-+# CONFIG_USB_KBTAB is not set
-+# CONFIG_USB_POWERMATE is not set
- # CONFIG_USB_DC2XX is not set
- # CONFIG_USB_MDC800 is not set
- # CONFIG_USB_SCANNER is not set
-@@ -718,35 +777,16 @@
- # USB Serial Converter support
- #
- # CONFIG_USB_SERIAL is not set
--# CONFIG_USB_SERIAL_GENERIC is not set
--# CONFIG_USB_SERIAL_BELKIN is not set
--# CONFIG_USB_SERIAL_WHITEHEAT is not set
--# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
--# CONFIG_USB_SERIAL_EMPEG is not set
--# CONFIG_USB_SERIAL_FTDI_SIO is not set
--# CONFIG_USB_SERIAL_VISOR is not set
--# CONFIG_USB_SERIAL_IPAQ is not set
--# CONFIG_USB_SERIAL_IR is not set
--# CONFIG_USB_SERIAL_EDGEPORT is not set
--# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
--# CONFIG_USB_SERIAL_KEYSPAN is not set
--# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
--# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
--# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
--# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
--# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
--# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
--# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
--# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
--# CONFIG_USB_SERIAL_MCT_U232 is not set
--# CONFIG_USB_SERIAL_KLSI is not set
--# CONFIG_USB_SERIAL_PL2303 is not set
--# CONFIG_USB_SERIAL_CYBERJACK is not set
--# CONFIG_USB_SERIAL_XIRCOM is not set
--# CONFIG_USB_SERIAL_OMNINET is not set
- # CONFIG_USB_RIO500 is not set
- # CONFIG_USB_AUERSWALD is not set
-+# CONFIG_USB_TIGL is not set
- # CONFIG_USB_BRLVGER is not set
-+# CONFIG_USB_LCD is not set
-+
-+#
-+# Support for USB gadgets
-+#
-+# CONFIG_USB_GADGET is not set
-
- #
- # Bluetooth support
-@@ -770,3 +810,10 @@
- CONFIG_DEBUG_LL=y
- # CONFIG_DEBUG_DC21285_PORT is not set
- # CONFIG_DEBUG_CLPS711X_UART2 is not set
-+
-+#
-+# Library routines
-+#
-+CONFIG_CRC32=y
-+# CONFIG_ZLIB_INFLATE is not set
-+# CONFIG_ZLIB_DEFLATE is not set
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/def-configs/csb337 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,760 @@
-+#
-+# Automatically generated by make menuconfig: don't edit
-+#
-+CONFIG_ARM=y
-+# CONFIG_EISA is not set
-+# CONFIG_SBUS is not set
-+# CONFIG_MCA is not set
-+CONFIG_UID16=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-+# CONFIG_GENERIC_BUST_SPINLOCK is not set
-+# CONFIG_GENERIC_ISA_DMA is not set
-+
-+#
-+# Code maturity level options
-+#
-+CONFIG_EXPERIMENTAL=y
-+# CONFIG_OBSOLETE is not set
-+
-+#
-+# Loadable module support
-+#
-+CONFIG_MODULES=y
-+# CONFIG_MODVERSIONS is not set
-+CONFIG_KMOD=y
-+
-+#
-+# System Type
-+#
-+# CONFIG_ARCH_ANAKIN is not set
-+# CONFIG_ARCH_ARCA5K is not set
-+# CONFIG_ARCH_CLPS7500 is not set
-+# CONFIG_ARCH_CLPS711X is not set
-+# CONFIG_ARCH_CO285 is not set
-+# CONFIG_ARCH_EBSA110 is not set
-+# CONFIG_ARCH_CAMELOT is not set
-+# CONFIG_ARCH_FOOTBRIDGE is not set
-+# CONFIG_ARCH_INTEGRATOR is not set
-+# CONFIG_ARCH_OMAHA is not set
-+# CONFIG_ARCH_L7200 is not set
-+# CONFIG_ARCH_MX1ADS is not set
-+# CONFIG_ARCH_RPC is not set
-+# CONFIG_ARCH_RISCSTATION is not set
-+# CONFIG_ARCH_SA1100 is not set
-+# CONFIG_ARCH_SHARK is not set
-+CONFIG_ARCH_AT91RM9200=y
-+
-+#
-+# Archimedes/A5000 Implementations
-+#
-+# CONFIG_ARCH_ARC is not set
-+# CONFIG_ARCH_A5K is not set
-+
-+#
-+# Footbridge Implementations
-+#
-+# CONFIG_ARCH_CATS is not set
-+# CONFIG_ARCH_PERSONAL_SERVER is not set
-+# CONFIG_ARCH_EBSA285_ADDIN is not set
-+# CONFIG_ARCH_EBSA285_HOST is not set
-+# CONFIG_ARCH_NETWINDER is not set
-+
-+#
-+# SA11x0 Implementations
-+#
-+# CONFIG_SA1100_ACCELENT is not set
-+# CONFIG_SA1100_ASSABET is not set
-+# CONFIG_ASSABET_NEPONSET is not set
-+# CONFIG_SA1100_ADSAGC is not set
-+# CONFIG_SA1100_ADSBITSY is not set
-+# CONFIG_SA1100_ADSBITSYPLUS is not set
-+# CONFIG_SA1100_BRUTUS is not set
-+# CONFIG_SA1100_CEP is not set
-+# CONFIG_SA1100_CERF is not set
-+# CONFIG_SA1100_H3100 is not set
-+# CONFIG_SA1100_H3600 is not set
-+# CONFIG_SA1100_H3800 is not set
-+# CONFIG_SA1100_H3XXX is not set
-+# CONFIG_H3600_SLEEVE is not set
-+# CONFIG_SA1100_EXTENEX1 is not set
-+# CONFIG_SA1100_FLEXANET is not set
-+# CONFIG_SA1100_FREEBIRD is not set
-+# CONFIG_SA1100_FRODO is not set
-+# CONFIG_SA1100_GRAPHICSCLIENT is not set
-+# CONFIG_SA1100_GRAPHICSMASTER is not set
-+# CONFIG_SA1100_HACKKIT is not set
-+# CONFIG_SA1100_BADGE4 is not set
-+# CONFIG_SA1100_JORNADA720 is not set
-+# CONFIG_SA1100_HUW_WEBPANEL is not set
-+# CONFIG_SA1100_ITSY is not set
-+# CONFIG_SA1100_LART is not set
-+# CONFIG_SA1100_NANOENGINE is not set
-+# CONFIG_SA1100_OMNIMETER is not set
-+# CONFIG_SA1100_PANGOLIN is not set
-+# CONFIG_SA1100_PLEB is not set
-+# CONFIG_SA1100_PT_SYSTEM3 is not set
-+# CONFIG_SA1100_SHANNON is not set
-+# CONFIG_SA1100_SHERMAN is not set
-+# CONFIG_SA1100_SIMPAD is not set
-+# CONFIG_SA1100_SIMPUTER is not set
-+# CONFIG_SA1100_PFS168 is not set
-+# CONFIG_SA1100_VICTOR is not set
-+# CONFIG_SA1100_XP860 is not set
-+# CONFIG_SA1100_YOPY is not set
-+# CONFIG_SA1100_USB is not set
-+# CONFIG_SA1100_USB_NETLINK is not set
-+# CONFIG_SA1100_USB_CHAR is not set
-+# CONFIG_SA1100_SSP is not set
-+
-+#
-+# AT91RM9200 Implementations
-+#
-+# CONFIG_ARCH_AT91RM9200DK is not set
-+CONFIG_MACH_CSB337=y
-+
-+#
-+# CLPS711X/EP721X Implementations
-+#
-+# CONFIG_ARCH_AUTCPU12 is not set
-+# CONFIG_ARCH_CDB89712 is not set
-+# CONFIG_ARCH_CLEP7312 is not set
-+# CONFIG_ARCH_EDB7211 is not set
-+# CONFIG_ARCH_FORTUNET is not set
-+# CONFIG_ARCH_GUIDEA07 is not set
-+# CONFIG_ARCH_P720T is not set
-+# CONFIG_ARCH_EP7211 is not set
-+# CONFIG_ARCH_EP7212 is not set
-+# CONFIG_ARCH_ACORN is not set
-+# CONFIG_PLD is not set
-+# CONFIG_FOOTBRIDGE is not set
-+# CONFIG_FOOTBRIDGE_HOST is not set
-+# CONFIG_FOOTBRIDGE_ADDIN is not set
-+CONFIG_CPU_32=y
-+# CONFIG_CPU_26 is not set
-+# CONFIG_CPU_ARM610 is not set
-+# CONFIG_CPU_ARM710 is not set
-+# CONFIG_CPU_ARM720T is not set
-+CONFIG_CPU_ARM920T=y
-+# CONFIG_CPU_ARM922T is not set
-+# CONFIG_CPU_ARM926T is not set
-+# CONFIG_CPU_ARM1020 is not set
-+# CONFIG_CPU_ARM1020E is not set
-+# CONFIG_CPU_ARM1022 is not set
-+# CONFIG_CPU_ARM1026 is not set
-+# CONFIG_CPU_SA110 is not set
-+# CONFIG_CPU_SA1100 is not set
-+# CONFIG_CPU_32v3 is not set
-+CONFIG_CPU_32v4=y
-+# CONFIG_ARM_THUMB is not set
-+# CONFIG_CPU_ICACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_DISABLE is not set
-+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
-+# CONFIG_DISCONTIGMEM is not set
-+
-+#
-+# General setup
-+#
-+# CONFIG_PCI is not set
-+# CONFIG_ISA is not set
-+# CONFIG_ISA_DMA is not set
-+# CONFIG_ZBOOT_ROM is not set
-+CONFIG_ZBOOT_ROM_TEXT=0
-+CONFIG_ZBOOT_ROM_BSS=0
-+# CONFIG_HOTPLUG is not set
-+# CONFIG_PCMCIA is not set
-+CONFIG_NET=y
-+CONFIG_SYSVIPC=y
-+# CONFIG_BSD_PROCESS_ACCT is not set
-+CONFIG_SYSCTL=y
-+CONFIG_FPE_NWFPE=y
-+# CONFIG_FPE_NWFPE_XP is not set
-+# CONFIG_FPE_FASTFPE is not set
-+CONFIG_KCORE_ELF=y
-+# CONFIG_KCORE_AOUT is not set
-+# CONFIG_BINFMT_AOUT is not set
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_MISC is not set
-+# CONFIG_PM is not set
-+# CONFIG_ARTHUR is not set
-+CONFIG_CMDLINE="mem=32M console=ttyS0,38400 initrd=0x20210000,3145728 root=/dev/ram rw"
-+# CONFIG_LEDS is not set
-+CONFIG_ALIGNMENT_TRAP=y
-+
-+#
-+# Parallel port support
-+#
-+# CONFIG_PARPORT is not set
-+
-+#
-+# Memory Technology Devices (MTD)
-+#
-+CONFIG_MTD=y
-+# CONFIG_MTD_DEBUG is not set
-+# CONFIG_MTD_PARTITIONS is not set
-+# CONFIG_MTD_CONCAT is not set
-+# CONFIG_MTD_REDBOOT_PARTS is not set
-+# CONFIG_MTD_CMDLINE_PARTS is not set
-+# CONFIG_MTD_AFS_PARTS is not set
-+CONFIG_MTD_CHAR=y
-+CONFIG_MTD_BLOCK=y
-+# CONFIG_FTL is not set
-+# CONFIG_NFTL is not set
-+
-+#
-+# RAM/ROM/Flash chip drivers
-+#
-+CONFIG_MTD_CFI=y
-+CONFIG_MTD_JEDECPROBE=y
-+CONFIG_MTD_GEN_PROBE=y
-+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-+CONFIG_MTD_CFI_INTELEXT=y
-+# CONFIG_MTD_CFI_AMDSTD is not set
-+# CONFIG_MTD_CFI_STAA is not set
-+# CONFIG_MTD_RAM is not set
-+CONFIG_MTD_ROM=y
-+# CONFIG_MTD_ABSENT is not set
-+# CONFIG_MTD_OBSOLETE_CHIPS is not set
-+# CONFIG_MTD_AMDSTD is not set
-+# CONFIG_MTD_SHARP is not set
-+# CONFIG_MTD_JEDEC is not set
-+
-+#
-+# Mapping drivers for chip access
-+#
-+CONFIG_MTD_PHYSMAP=y
-+CONFIG_MTD_PHYSMAP_START=10000000
-+CONFIG_MTD_PHYSMAP_LEN=200000
-+CONFIG_MTD_PHYSMAP_BUSWIDTH=2
-+# CONFIG_MTD_NORA is not set
-+# CONFIG_MTD_ARM_INTEGRATOR is not set
-+# CONFIG_MTD_CDB89712 is not set
-+# CONFIG_MTD_SA1100 is not set
-+# CONFIG_MTD_DC21285 is not set
-+# CONFIG_MTD_IQ80310 is not set
-+# CONFIG_MTD_FORTUNET is not set
-+# CONFIG_MTD_EPXA is not set
-+# CONFIG_MTD_AUTCPU12 is not set
-+# CONFIG_MTD_EDB7312 is not set
-+# CONFIG_MTD_IMPA7 is not set
-+# CONFIG_MTD_CEIVA is not set
-+# CONFIG_MTD_PCI is not set
-+# CONFIG_MTD_PCMCIA is not set
-+
-+#
-+# Self-contained MTD device drivers
-+#
-+# CONFIG_MTD_PMC551 is not set
-+# CONFIG_MTD_SLRAM is not set
-+CONFIG_MTD_AT91_DATAFLASH=y
-+# CONFIG_MTD_AT91_DATAFLASH_CARD is not set
-+# CONFIG_MTD_MTDRAM is not set
-+# CONFIG_MTD_BLKMTD is not set
-+# CONFIG_MTD_DOC1000 is not set
-+# CONFIG_MTD_DOC2000 is not set
-+# CONFIG_MTD_DOC2001 is not set
-+# CONFIG_MTD_DOCPROBE is not set
-+
-+#
-+# NAND Flash Device Drivers
-+#
-+CONFIG_MTD_NAND=y
-+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
-+CONFIG_MTD_NAND_IDS=y
-+# CONFIG_MTD_AT91_SMARTMEDIA is not set
-+
-+#
-+# Plug and Play configuration
-+#
-+# CONFIG_PNP is not set
-+# CONFIG_ISAPNP is not set
-+
-+#
-+# Block devices
-+#
-+# CONFIG_BLK_DEV_FD is not set
-+# CONFIG_BLK_DEV_XD is not set
-+# CONFIG_PARIDE is not set
-+# CONFIG_BLK_CPQ_DA is not set
-+# CONFIG_BLK_CPQ_CISS_DA is not set
-+# CONFIG_CISS_SCSI_TAPE is not set
-+# CONFIG_CISS_MONITOR_THREAD is not set
-+# CONFIG_BLK_DEV_DAC960 is not set
-+# CONFIG_BLK_DEV_UMEM is not set
-+# CONFIG_BLK_DEV_LOOP is not set
-+# CONFIG_BLK_DEV_NBD is not set
-+CONFIG_BLK_DEV_RAM=y
-+CONFIG_BLK_DEV_RAM_SIZE=8192
-+# CONFIG_BLK_DEV_INITRD is not set
-+# CONFIG_BLK_STATS is not set
-+
-+#
-+# Multi-device support (RAID and LVM)
-+#
-+# CONFIG_MD is not set
-+# CONFIG_BLK_DEV_MD is not set
-+# CONFIG_MD_LINEAR is not set
-+# CONFIG_MD_RAID0 is not set
-+# CONFIG_MD_RAID1 is not set
-+# CONFIG_MD_RAID5 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_BLK_DEV_LVM is not set
-+
-+#
-+# Networking options
-+#
-+CONFIG_PACKET=y
-+# CONFIG_PACKET_MMAP is not set
-+# CONFIG_NETLINK_DEV is not set
-+# CONFIG_NETFILTER is not set
-+# CONFIG_FILTER is not set
-+CONFIG_UNIX=y
-+CONFIG_INET=y
-+# CONFIG_IP_MULTICAST is not set
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+CONFIG_IP_PNP=y
-+CONFIG_IP_PNP_DHCP=y
-+CONFIG_IP_PNP_BOOTP=y
-+# CONFIG_IP_PNP_RARP is not set
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_ARPD is not set
-+# CONFIG_INET_ECN is not set
-+# CONFIG_SYN_COOKIES is not set
-+# CONFIG_IPV6 is not set
-+# CONFIG_KHTTPD is not set
-+
-+#
-+# SCTP Configuration (EXPERIMENTAL)
-+#
-+CONFIG_IPV6_SCTP__=y
-+# CONFIG_IP_SCTP is not set
-+# CONFIG_ATM is not set
-+# CONFIG_VLAN_8021Q is not set
-+# CONFIG_IPX is not set
-+# CONFIG_ATALK is not set
-+
-+#
-+# Appletalk devices
-+#
-+# CONFIG_DEV_APPLETALK is not set
-+# CONFIG_DECNET is not set
-+# CONFIG_BRIDGE is not set
-+# CONFIG_X25 is not set
-+# CONFIG_LAPB is not set
-+# CONFIG_LLC is not set
-+# CONFIG_NET_DIVERT is not set
-+# CONFIG_ECONET is not set
-+# CONFIG_WAN_ROUTER is not set
-+# CONFIG_NET_FASTROUTE is not set
-+# CONFIG_NET_HW_FLOWCONTROL is not set
-+
-+#
-+# QoS and/or fair queueing
-+#
-+# CONFIG_NET_SCHED is not set
-+
-+#
-+# Network testing
-+#
-+# CONFIG_NET_PKTGEN is not set
-+
-+#
-+# Network device support
-+#
-+CONFIG_NETDEVICES=y
-+
-+#
-+# ARCnet devices
-+#
-+# CONFIG_ARCNET is not set
-+# CONFIG_DUMMY is not set
-+# CONFIG_BONDING is not set
-+# CONFIG_EQUALIZER is not set
-+# CONFIG_TUN is not set
-+# CONFIG_ETHERTAP is not set
-+
-+#
-+# Ethernet (10 or 100Mbit)
-+#
-+CONFIG_NET_ETHERNET=y
-+# CONFIG_ARM_AM79C961A is not set
-+# CONFIG_ARM_CIRRUS is not set
-+CONFIG_AT91_ETHER=y
-+# CONFIG_AT91_ETHER_RMII is not set
-+# CONFIG_SUNLANCE is not set
-+# CONFIG_SUNBMAC is not set
-+# CONFIG_SUNQE is not set
-+# CONFIG_SUNGEM is not set
-+# CONFIG_NET_VENDOR_3COM is not set
-+# CONFIG_LANCE is not set
-+# CONFIG_NET_VENDOR_SMC is not set
-+# CONFIG_NET_VENDOR_RACAL is not set
-+# CONFIG_NET_ISA is not set
-+# CONFIG_NET_PCI is not set
-+# CONFIG_NET_POCKET is not set
-+
-+#
-+# Ethernet (1000 Mbit)
-+#
-+# CONFIG_ACENIC is not set
-+# CONFIG_DL2K is not set
-+# CONFIG_E1000 is not set
-+# CONFIG_MYRI_SBUS is not set
-+# CONFIG_NS83820 is not set
-+# CONFIG_HAMACHI is not set
-+# CONFIG_YELLOWFIN is not set
-+# CONFIG_R8169 is not set
-+# CONFIG_SK98LIN is not set
-+# CONFIG_TIGON3 is not set
-+# CONFIG_FDDI is not set
-+# CONFIG_HIPPI is not set
-+# CONFIG_PLIP is not set
-+# CONFIG_PPP is not set
-+# CONFIG_SLIP is not set
-+
-+#
-+# Wireless LAN (non-hamradio)
-+#
-+# CONFIG_NET_RADIO is not set
-+
-+#
-+# Token Ring devices
-+#
-+# CONFIG_TR is not set
-+# CONFIG_NET_FC is not set
-+# CONFIG_RCPCI is not set
-+# CONFIG_SHAPER is not set
-+
-+#
-+# Wan interfaces
-+#
-+# CONFIG_WAN is not set
-+
-+#
-+# Amateur Radio support
-+#
-+# CONFIG_HAMRADIO is not set
-+
-+#
-+# IrDA (infrared) support
-+#
-+# CONFIG_IRDA is not set
-+
-+#
-+# ATA/ATAPI/MFM/RLL support
-+#
-+# CONFIG_IDE is not set
-+# CONFIG_BLK_DEV_HD is not set
-+
-+#
-+# SCSI support
-+#
-+# CONFIG_SCSI is not set
-+
-+#
-+# I2O device support
-+#
-+# CONFIG_I2O is not set
-+# CONFIG_I2O_BLOCK is not set
-+# CONFIG_I2O_LAN is not set
-+# CONFIG_I2O_SCSI is not set
-+# CONFIG_I2O_PROC is not set
-+
-+#
-+# ISDN subsystem
-+#
-+# CONFIG_ISDN is not set
-+
-+#
-+# Input core support
-+#
-+# CONFIG_INPUT is not set
-+# CONFIG_INPUT_KEYBDEV is not set
-+# CONFIG_INPUT_MOUSEDEV is not set
-+# CONFIG_INPUT_JOYDEV is not set
-+# CONFIG_INPUT_EVDEV is not set
-+# CONFIG_INPUT_UINPUT is not set
-+# CONFIG_INPUT_MX1TS is not set
-+
-+#
-+# Character devices
-+#
-+# CONFIG_VT is not set
-+# CONFIG_SERIAL is not set
-+# CONFIG_SERIAL_EXTENDED is not set
-+# CONFIG_SERIAL_NONSTANDARD is not set
-+CONFIG_AT91_SPIDEV=y
-+
-+#
-+# Serial drivers
-+#
-+# CONFIG_SERIAL_ANAKIN is not set
-+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-+# CONFIG_SERIAL_AMBA is not set
-+# CONFIG_SERIAL_AMBA_CONSOLE is not set
-+# CONFIG_SERIAL_CLPS711X is not set
-+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-+# CONFIG_SERIAL_21285 is not set
-+# CONFIG_SERIAL_21285_OLD is not set
-+# CONFIG_SERIAL_21285_CONSOLE is not set
-+# CONFIG_SERIAL_UART00 is not set
-+# CONFIG_SERIAL_UART00_CONSOLE is not set
-+# CONFIG_SERIAL_SA1100 is not set
-+# CONFIG_SERIAL_SA1100_CONSOLE is not set
-+# CONFIG_SERIAL_OMAHA is not set
-+# CONFIG_SERIAL_OMAHA_CONSOLE is not set
-+CONFIG_SERIAL_AT91=y
-+CONFIG_SERIAL_AT91_CONSOLE=y
-+# CONFIG_SERIAL_8250 is not set
-+# CONFIG_SERIAL_8250_CONSOLE is not set
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+# CONFIG_SERIAL_8250_MANY_PORTS is not set
-+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-+# CONFIG_SERIAL_8250_MULTIPORT is not set
-+# CONFIG_SERIAL_8250_HUB6 is not set
-+CONFIG_SERIAL_CORE=y
-+CONFIG_SERIAL_CORE_CONSOLE=y
-+# CONFIG_UNIX98_PTYS is not set
-+
-+#
-+# I2C support
-+#
-+CONFIG_I2C=y
-+# CONFIG_I2C_ALGOBIT is not set
-+# CONFIG_SCx200_ACB is not set
-+# CONFIG_I2C_ALGOPCF is not set
-+CONFIG_I2C_AT91=y
-+CONFIG_I2C_CHARDEV=y
-+CONFIG_I2C_PROC=y
-+CONFIG_I2C_DS1307=y
-+
-+#
-+# L3 serial bus support
-+#
-+# CONFIG_L3 is not set
-+# CONFIG_L3_ALGOBIT is not set
-+# CONFIG_L3_BIT_SA1100_GPIO is not set
-+# CONFIG_L3_SA1111 is not set
-+# CONFIG_BIT_SA1100_GPIO is not set
-+
-+#
-+# Mice
-+#
-+# CONFIG_BUSMOUSE is not set
-+# CONFIG_MOUSE is not set
-+
-+#
-+# Joysticks
-+#
-+# CONFIG_INPUT_GAMEPORT is not set
-+# CONFIG_QIC02_TAPE is not set
-+# CONFIG_IPMI_HANDLER is not set
-+# CONFIG_IPMI_PANIC_EVENT is not set
-+# CONFIG_IPMI_DEVICE_INTERFACE is not set
-+# CONFIG_IPMI_KCS is not set
-+# CONFIG_IPMI_WATCHDOG is not set
-+
-+#
-+# Watchdog Cards
-+#
-+CONFIG_WATCHDOG=y
-+CONFIG_WATCHDOG_NOWAYOUT=y
-+# CONFIG_ACQUIRE_WDT is not set
-+# CONFIG_ADVANTECH_WDT is not set
-+# CONFIG_ALIM1535_WDT is not set
-+# CONFIG_ALIM7101_WDT is not set
-+# CONFIG_SC520_WDT is not set
-+# CONFIG_PCWATCHDOG is not set
-+# CONFIG_21285_WATCHDOG is not set
-+# CONFIG_977_WATCHDOG is not set
-+# CONFIG_SA1100_WATCHDOG is not set
-+# CONFIG_EPXA_WATCHDOG is not set
-+# CONFIG_OMAHA_WATCHDOG is not set
-+CONFIG_AT91_WATCHDOG=y
-+# CONFIG_EUROTECH_WDT is not set
-+# CONFIG_IB700_WDT is not set
-+# CONFIG_WAFER_WDT is not set
-+# CONFIG_I810_TCO is not set
-+# CONFIG_MIXCOMWD is not set
-+# CONFIG_60XX_WDT is not set
-+# CONFIG_SC1200_WDT is not set
-+# CONFIG_SCx200_WDT is not set
-+# CONFIG_SOFT_WATCHDOG is not set
-+# CONFIG_W83877F_WDT is not set
-+# CONFIG_WDT is not set
-+# CONFIG_WDTPCI is not set
-+# CONFIG_MACHZ_WDT is not set
-+# CONFIG_AMD7XX_TCO is not set
-+# CONFIG_SCx200 is not set
-+# CONFIG_SCx200_GPIO is not set
-+# CONFIG_AMD_PM768 is not set
-+# CONFIG_NVRAM is not set
-+# CONFIG_RTC is not set
-+CONFIG_AT91_RTC=y
-+# CONFIG_DTLK is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_APPLICOM is not set
-+
-+#
-+# Ftape, the floppy tape device driver
-+#
-+# CONFIG_FTAPE is not set
-+# CONFIG_AGP is not set
-+
-+#
-+# Direct Rendering Manager (XFree86 DRI support)
-+#
-+# CONFIG_DRM is not set
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+
-+#
-+# File systems
-+#
-+# CONFIG_QUOTA is not set
-+# CONFIG_QFMT_V2 is not set
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+# CONFIG_REISERFS_FS is not set
-+# CONFIG_REISERFS_CHECK is not set
-+# CONFIG_REISERFS_PROC_INFO is not set
-+# CONFIG_ADFS_FS is not set
-+# CONFIG_ADFS_FS_RW is not set
-+# CONFIG_AFFS_FS is not set
-+# CONFIG_HFS_FS is not set
-+# CONFIG_HFSPLUS_FS is not set
-+# CONFIG_BEFS_FS is not set
-+# CONFIG_BEFS_DEBUG is not set
-+# CONFIG_BFS_FS is not set
-+# CONFIG_EXT3_FS is not set
-+# CONFIG_JBD is not set
-+# CONFIG_JBD_DEBUG is not set
-+# CONFIG_FAT_FS is not set
-+# CONFIG_MSDOS_FS is not set
-+# CONFIG_UMSDOS_FS is not set
-+# CONFIG_VFAT_FS is not set
-+# CONFIG_EFS_FS is not set
-+# CONFIG_JFFS_FS is not set
-+# CONFIG_JFFS2_FS is not set
-+# CONFIG_CRAMFS is not set
-+# CONFIG_TMPFS is not set
-+CONFIG_RAMFS=y
-+# CONFIG_ISO9660_FS is not set
-+# CONFIG_JOLIET is not set
-+# CONFIG_ZISOFS is not set
-+# CONFIG_JFS_FS is not set
-+# CONFIG_JFS_DEBUG is not set
-+# CONFIG_JFS_STATISTICS is not set
-+# CONFIG_MINIX_FS is not set
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_NTFS_FS is not set
-+# CONFIG_NTFS_RW is not set
-+# CONFIG_HPFS_FS is not set
-+CONFIG_PROC_FS=y
-+CONFIG_DEVFS_FS=y
-+CONFIG_DEVFS_MOUNT=y
-+# CONFIG_DEVFS_DEBUG is not set
-+# CONFIG_DEVPTS_FS is not set
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_QNX4FS_RW is not set
-+# CONFIG_ROMFS_FS is not set
-+CONFIG_EXT2_FS=y
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UDF_FS is not set
-+# CONFIG_UDF_RW is not set
-+# CONFIG_UFS_FS is not set
-+# CONFIG_UFS_FS_WRITE is not set
-+# CONFIG_XFS_FS is not set
-+# CONFIG_XFS_QUOTA is not set
-+# CONFIG_XFS_RT is not set
-+# CONFIG_XFS_TRACE is not set
-+# CONFIG_XFS_DEBUG is not set
-+
-+#
-+# Network File Systems
-+#
-+# CONFIG_CODA_FS is not set
-+# CONFIG_INTERMEZZO_FS is not set
-+CONFIG_NFS_FS=y
-+CONFIG_NFS_V3=y
-+# CONFIG_NFS_DIRECTIO is not set
-+CONFIG_ROOT_NFS=y
-+# CONFIG_NFSD is not set
-+# CONFIG_NFSD_V3 is not set
-+# CONFIG_NFSD_TCP is not set
-+CONFIG_SUNRPC=y
-+CONFIG_LOCKD=y
-+CONFIG_LOCKD_V4=y
-+# CONFIG_SMB_FS is not set
-+# CONFIG_NCP_FS is not set
-+# CONFIG_NCPFS_PACKET_SIGNING is not set
-+# CONFIG_NCPFS_IOCTL_LOCKING is not set
-+# CONFIG_NCPFS_STRONG is not set
-+# CONFIG_NCPFS_NFS_NS is not set
-+# CONFIG_NCPFS_OS2_NS is not set
-+# CONFIG_NCPFS_SMALLDOS is not set
-+# CONFIG_NCPFS_NLS is not set
-+# CONFIG_NCPFS_EXTRAS is not set
-+# CONFIG_ZISOFS_FS is not set
-+
-+#
-+# Partition Types
-+#
-+# CONFIG_PARTITION_ADVANCED is not set
-+CONFIG_MSDOS_PARTITION=y
-+# CONFIG_SMB_NLS is not set
-+# CONFIG_NLS is not set
-+
-+#
-+# Multimedia Capabilities Port drivers
-+#
-+# CONFIG_MCP is not set
-+# CONFIG_MCP_SA1100 is not set
-+# CONFIG_MCP_UCB1200 is not set
-+# CONFIG_MCP_UCB1200_AUDIO is not set
-+# CONFIG_MCP_UCB1200_TS is not set
-+
-+#
-+# USB support
-+#
-+# CONFIG_USB is not set
-+
-+#
-+# Support for USB gadgets
-+#
-+# CONFIG_USB_GADGET is not set
-+
-+#
-+# Bluetooth support
-+#
-+# CONFIG_BLUEZ is not set
-+
-+#
-+# Kernel hacking
-+#
-+CONFIG_FRAME_POINTER=y
-+CONFIG_DEBUG_USER=y
-+# CONFIG_DEBUG_INFO is not set
-+# CONFIG_NO_PGT_CACHE is not set
-+CONFIG_DEBUG_KERNEL=y
-+# CONFIG_DEBUG_SLAB is not set
-+# CONFIG_MAGIC_SYSRQ is not set
-+# CONFIG_DEBUG_SPINLOCK is not set
-+# CONFIG_DEBUG_WAITQ is not set
-+# CONFIG_DEBUG_BUGVERBOSE is not set
-+# CONFIG_DEBUG_ERRORS is not set
-+CONFIG_DEBUG_LL=y
-+# CONFIG_DEBUG_DC21285_PORT is not set
-+# CONFIG_DEBUG_CLPS711X_UART2 is not set
-+
-+#
-+# Library routines
-+#
-+CONFIG_CRC32=y
-+# CONFIG_ZLIB_INFLATE is not set
-+# CONFIG_ZLIB_DEFLATE is not set
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/fastfpe/CPDO.S 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,682 @@
-+/*
-+The FP structure has 4 words reserved for each register, the first is used just
-+for the sign in bit 31, the second and third are for the mantissa (unsigned
-+integer, high 32 bit first) and the fourth is the exponent (signed integer).
-+The mantissa is always normalized.
-+
-+If the exponent is 0x80000000, that is the most negative value, the number
-+represented is 0 and both mantissa words are also 0.
-+
-+If the exponent is 0x7fffffff, that is the biggest positive value, the number
-+represented is infinity if the high 32 mantissa bit are also 0, otherwise it is
-+a NaN. The low 32 mantissa bit are 0 if the number represented is infinity.
-+
-+Decimal and packed decimal numbers are not supported yet.
-+
-+The parameters to these functions are r0=destination pointer, r1 and r2
-+source pointers. r4 is the instruction. They may use r0-r8 and r14. They return
-+to fastfpe_next, except CPDO_rnf_core which expects the return address in r14.
-+*/
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_adf
-+CPDO_adf:
-+ ldmia r1,{r1,r3,r5,r7}
-+ ldmia r2,{r2,r4,r6,r8}
-+
-+ cmp r7,#0x7fffffff
-+ cmpne r8,#0x7fffffff
-+ beq CPDO_adf_extra
-+
-+ cmp r1,r2
-+ bne CPDO_suf_s
-+
-+CPDO_adf_s:
-+ subs r2,r7,r8
-+ bge CPDO_adf_2nd
-+
-+ mov r7,r8
-+ rsb r2,r2,#0
-+ cmp r2,#32
-+ ble CPDO_adf_1st2
-+
-+ sub r2,r2,#32
-+ cmp r2,#32
-+ movgt r2,#32
-+ mov r5,r3,lsr r2
-+ mov r3,#0
-+ b CPDO_adf_add
-+
-+CPDO_adf_1st2:
-+ rsb r8,r2,#32
-+ mov r5,r5,lsr r2
-+ orr r5,r5,r3,lsl r8
-+ mov r3,r3,lsr r2 @ 1. op normalized
-+ b CPDO_adf_add
-+
-+CPDO_adf_2nd:
-+ cmp r2,#32
-+ ble CPDO_adf_2nd2
-+
-+ sub r2,r2,#32
-+ cmp r2,#32
-+ movgt r2,#32
-+ mov r6,r4,lsr r2
-+ mov r4,#0
-+ b CPDO_adf_add
-+
-+CPDO_adf_2nd2:
-+ rsb r8,r2,#32
-+ mov r6,r6,lsr r2
-+ orr r6,r6,r4,lsl r8
-+ mov r4,r4,lsr r2 @ 2. op normalized
-+
-+CPDO_adf_add:
-+ adds r5,r5,r6
-+ adcs r3,r3,r4 @ do addition
-+ bcc CPDO_adf_end
-+
-+ add r7,r7,#1
-+ movs r3,r3,rrx
-+ mov r5,r5,rrx @ correct for overflow
-+
-+CPDO_adf_end:
-+ cmp r7,#0x20000000
-+ bge CPDO_inf
-+
-+ stmia r0,{r1,r3,r5,r7}
-+ b fastfpe_next
-+
-+CPDO_adf_extra:
-+ cmp r7,#0x7fffffff @ was it the 1st ?
-+ bne CPDO_infnan_2 @ no it was the 2nd
-+ cmp r8,#0x7fffffff @ if 1st, 2nd too ?
-+ bne CPDO_infnan_1 @ no only 1st
-+ cmp r3,#0
-+ cmpeq r4,#0
-+ bne CPDO_nan_12
-+ b CPDO_inf
-+
-+/*---------------------------------------------------------------------------*/
-+
-+CPDO_infnan_1:
-+ stmia r0,{r1,r3,r5,r7}
-+ b fastfpe_next
-+
-+CPDO_infnan_2:
-+ stmia r0,{r2,r4,r6,r8}
-+ b fastfpe_next
-+
-+CPDO_nan_12:
-+ orr r2,r3,r4
-+ b CPDO_inf_1
-+
-+CPDO_nan:
-+ mov r2,#0x40000000 @ create non signalling NaN
-+ b CPDO_inf_1
-+
-+CPDO_inf:
-+ mov r2,#0
-+CPDO_inf_1:
-+ mov r3,#0
-+ mov r4,#0x7fffffff
-+CPDO_store_1234:
-+ stmia r0,{r1,r2,r3,r4}
-+ b fastfpe_next
-+
-+CPDO_zero:
-+ mov r1,#0
-+CPDO_zero_1:
-+ mov r2,#0
-+ mov r3,#0
-+ mov r4,#0x80000000
-+ stmia r0,{r1,r2,r3,r4}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_suf
-+CPDO_suf:
-+ ldmia r1,{r1,r3,r5,r7}
-+ ldmia r2,{r2,r4,r6,r8}
-+
-+CPDO_suf_l:
-+ cmp r7,#0x7fffffff
-+ cmpne r8,#0x7fffffff
-+ beq CPDO_suf_extra
-+
-+ cmp r1,r2
-+ bne CPDO_adf_s
-+
-+CPDO_suf_s:
-+ subs r2,r7,r8 @ determine greater number
-+ bgt CPDO_suf_2nd @ first number is greater
-+ blt CPDO_suf_1st @ second number is greater
-+ cmp r3,r4 @ also mantissa is important
-+ cmpeq r5,r6
-+ bhi CPDO_suf_2nd @ first number is greater
-+ beq CPDO_zero
-+
-+CPDO_suf_1st:
-+ eor r1,r1,#0x80000000 @ second number is greater, invert sign
-+ mov r7,r8
-+ rsb r2,r2,#0
-+ cmp r2,#32
-+ ble CPDO_suf_1st2
-+
-+ sub r2,r2,#32
-+ cmp r2,#32
-+ movgt r2,#32
-+ mov r5,r3,lsr r2
-+ mov r3,#0
-+ b CPDO_suf_1st_sub
-+
-+CPDO_suf_1st2:
-+ rsb r8,r2,#32
-+ mov r5,r5,lsr r2
-+ orr r5,r5,r3,lsl r8
-+ mov r3,r3,lsr r2 @ 1. op normalized
-+
-+CPDO_suf_1st_sub:
-+ subs r5,r6,r5 @ do subtraction
-+ sbc r3,r4,r3
-+ b CPDO_suf_norm
-+
-+CPDO_suf_2nd:
-+ cmp r2,#32
-+ ble CPDO_suf_2nd2
-+
-+ sub r2,r2,#32
-+ cmp r2,#32
-+ movgt r2,#32
-+ mov r6,r4,lsr r2
-+ mov r4,#0
-+ b CPDO_suf_2nd_sub
-+
-+CPDO_suf_2nd2:
-+ rsb r8,r2,#32
-+ mov r6,r6,lsr r2
-+ orr r6,r6,r4,lsl r8
-+ mov r4,r4,lsr r2 @ 2. op normalized
-+
-+CPDO_suf_2nd_sub:
-+ subs r5,r5,r6
-+ sbc r3,r3,r4 @ do subtraction
-+
-+CPDO_suf_norm:
-+ teq r3,#0 @ normalize 32bit
-+ moveq r3,r5
-+ moveq r5,#0
-+ subeq r7,r7,#32
-+
-+ cmp r3,#0x00010000 @ 16bit
-+ movcc r3,r3,lsl#16
-+ orrcc r3,r3,r5,lsr#16
-+ movcc r5,r5,lsl#16
-+ subcc r7,r7,#16
-+
-+ cmp r3,#0x01000000 @ 8bit
-+ movcc r3,r3,lsl#8
-+ orrcc r3,r3,r5,lsr#24
-+ movcc r5,r5,lsl#8
-+ subcc r7,r7,#8
-+
-+ cmp r3,#0x10000000 @ 4bit
-+ movcc r3,r3,lsl#4
-+ orrcc r3,r3,r5,lsr#28
-+ movcc r5,r5,lsl#4
-+ subcc r7,r7,#4
-+
-+ cmp r3,#0x40000000 @ 2bit
-+ movcc r3,r3,lsl#2
-+ orrcc r3,r3,r5,lsr#30
-+ movcc r5,r5,lsl#2
-+ subcc r7,r7,#2
-+
-+ cmp r3,#0x80000000 @ 1bit
-+ movcc r3,r3,lsl#1
-+ orrcc r3,r3,r5,lsr#31
-+ movcc r5,r5,lsl#1
-+ subcc r7,r7,#1
-+
-+ cmp r7,#0xe0000000
-+ ble CPDO_zero_1
-+
-+ stmia r0,{r1,r3,r5,r7}
-+ b fastfpe_next
-+
-+CPDO_suf_extra:
-+ cmp r7,#0x7fffffff @ was it the 1st ?
-+ eorne r2,r2,#0x80000000 @ change sign, might have been INF
-+ bne CPDO_infnan_2 @ no it was the 2nd
-+ cmp r8,#0x7fffffff @ if 1st, 2nd too ?
-+ bne CPDO_infnan_1 @ no only 1st
-+ cmp r3,#0
-+ cmpeq r4,#0
-+ bne CPDO_nan_12
-+ b CPDO_nan @ here is difference with adf !
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_rsf
-+CPDO_rsf:
-+ mov r3,r2
-+ ldmia r1,{r2,r4,r6,r8}
-+ ldmia r3,{r1,r3,r5,r7}
-+ b CPDO_suf_l
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_muf
-+CPDO_muf:
-+ ldmia r1,{r1,r3,r5,r7}
-+ ldmia r2,{r2,r4,r6,r8}
-+
-+ cmp r7,#0x7fffffff
-+ cmpne r8,#0x7fffffff
-+ beq CPDO_muf_extra
-+
-+ eor r1,r1,r2
-+ adds r8,r7,r8
-+ bvs CPDO_zero_1
-+
-+ umull r7,r2,r3,r4
-+ umull r14,r3,r6,r3
-+ adds r7,r7,r3 @ r2|r7|r14 = r2|r7|#0 + #0|r3|r14
-+ adc r2,r2,#0
-+ umull r4,r3,r5,r4
-+ adds r14,r14,r4 @ r2|r7|r14 += #0|r3|r4
-+ adcs r7,r7,r3
-+ adc r2,r2,#0
-+ umull r4,r3,r5,r6
-+ adds r14,r14,r3 @ r2|r7|r14 += #0|#0|r3
-+ adcs r7,r7,#0
-+ adcs r2,r2,#0
-+
-+ bpl CPDO_muf_norm
-+
-+ add r8,r8,#1
-+ b CPDO_muf_end
-+
-+CPDO_muf_norm:
-+ adds r14,r14,r14
-+ adcs r7,r7,r7
-+ adcs r2,r2,r2
-+
-+CPDO_muf_end:
-+ cmp r8,#0x20000000
-+ bge CPDO_inf
-+ cmp r8,#0xe0000000
-+ ble CPDO_zero_1
-+ stmia r0,{r1,r2,r7,r8}
-+ b fastfpe_next
-+
-+CPDO_muf_extra:
-+ cmp r7,#0x7fffffff @ was it the first?
-+ bne CPDO_muf_extra_2nd @ no, so it was the second
-+ cmp r8,#0x7fffffff @ yes, second too?
-+ bne CPDO_muf_extra_1st @ no, only first
-+ orr r3,r3,r4 @ if both inf -> inf, otherwise nan
-+ eor r1,r1,r2 @ sign for the inf case
-+ b CPDO_infnan_1
-+
-+CPDO_muf_extra_1st:
-+ cmp r3,#0 @ is it a nan?
-+ bne CPDO_infnan_1
-+ cmp r8,#0x80000000 @ is the second 0?
-+ beq CPDO_nan
-+ eor r1,r1,r2 @ correct sign for inf
-+ b CPDO_inf
-+
-+CPDO_muf_extra_2nd:
-+ cmp r4,#0 @ is it a nan?
-+ bne CPDO_infnan_2
-+ cmp r7,#0x80000000 @ is the first 0?
-+ beq CPDO_nan
-+ eor r1,r1,r2 @ correct sign for inf
-+ b CPDO_inf
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_dvf
-+CPDO_dvf:
-+ ldmia r1,{r1,r3,r5,r7}
-+ ldmia r2,{r2,r4,r6,r8}
-+
-+CPDO_dvf_l:
-+ cmp r7,#0x7fffffff
-+ cmpne r8,#0x7fffffff
-+ beq CPDO_dvf_extra
-+ cmp r8,#0x80000000
-+ beq CPDO_dvf_by0
-+
-+ eor r1,r1,r2
-+ cmp r7,#0x80000000
-+ beq CPDO_zero_1
-+
-+ sub r8,r7,r8
-+
-+ mov r2,#0
-+ mov r7,#1
-+
-+ cmp r3,r4
-+ cmpeq r5,r6
-+ bcs CPDO_dvf_loop_
-+
-+ sub r8,r8,#1
-+
-+CPDO_dvf_loop:
-+ adds r5,r5,r5
-+ adcs r3,r3,r3
-+ bcs CPDO_dvf_anyway
-+CPDO_dvf_loop_:
-+ subs r5,r5,r6
-+ sbcs r3,r3,r4
-+ bcs CPDO_dvf_okay
-+
-+ adds r5,r5,r6
-+ adc r3,r3,r4
-+ adds r7,r7,r7
-+ adcs r2,r2,r2
-+ bcc CPDO_dvf_loop
-+ b CPDO_dvf_end
-+
-+CPDO_dvf_anyway:
-+ adcs r7,r7,r7
-+ adcs r2,r2,r2
-+ bcs CPDO_dvf_end
-+ subs r5,r5,r6
-+ sbc r3,r3,r4
-+ b CPDO_dvf_loop
-+
-+CPDO_dvf_okay:
-+ adcs r7,r7,r7
-+ adcs r2,r2,r2
-+ bcc CPDO_dvf_loop
-+
-+CPDO_dvf_end:
-+ b CPDO_muf_end
-+
-+CPDO_dvf_by0:
-+ cmp R7,#0x80000000
-+ beq CPDO_nan @ first also 0 -> nan
-+ eor r1,r1,r2 @ otherwise calculatesign for inf
-+ b CPDO_inf
-+
-+CPDO_dvf_extra:
-+ cmp r7,#0x7fffffff @ was it the first?
-+ bne CPDO_dvf_extra_2nd @ no, so it was the second
-+ cmp r8,#0x7fffffff @ yes, second too?
-+ bne CPDO_dvf_extra_1st @ no, only first
-+ orrs r3,r3,r4
-+ beq CPDO_nan @ if both inf -> create nan
-+ b CPDO_nan_12 @ otherwise keep nan
-+
-+CPDO_dvf_extra_1st:
-+ eor r1,r1,r2 @ correct sign for inf
-+ b CPDO_infnan_1
-+
-+CPDO_dvf_extra_2nd:
-+ cmp r4,#0 @ is it a nan?
-+ bne CPDO_infnan_2
-+ eor r1,r1,r2 @ correct sign for zero
-+ b CPDO_zero_1
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_rdf
-+CPDO_rdf:
-+ mov r3,r2
-+ ldmia r1,{r2,r4,r6,r8}
-+ ldmia r3,{r1,r3,r5,r7}
-+ b CPDO_dvf_l
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_rmf
-+CPDO_rmf:
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_mvf
-+CPDO_mvf:
-+ ldmia r2,{r1,r2,r3,r4}
-+ stmia r0,{r1,r2,r3,r4}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_mnf
-+CPDO_mnf:
-+ ldmia r2,{r1,r2,r3,r4}
-+ eor r1,r1,#0x80000000
-+ stmia r0,{r1,r2,r3,r4}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_abs
-+CPDO_abs:
-+ ldmia r2,{r1,r2,r3,r4}
-+ bic r1,r1,#0x80000000
-+ stmia r0,{r1,r2,r3,r4}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_sqt
-+CPDO_sqt:
-+ ldmia r2,{r1,r2,r3,r4}
-+ cmp r1,#0
-+ bne CPDO_nan
-+ cmp r4,#0x7fffffff
-+ beq CPDO_store_1234
-+
-+ tst r4,r4,lsr#1 @carry=exponent bit 0
-+ bcc CPDO_sqt_exponenteven
-+ adds r3,r3,r3
-+ adcs r2,r2,r2 @carry is needed in loop!
-+CPDO_sqt_exponenteven:
-+ mov r4,r4,asr #1
-+ str r4,[r0,#12]
-+
-+ mov r4,#0x80000000
-+ mov r5,#0
-+ sub r2,r2,#0x80000000
-+
-+ mov r8,#0x40000000
-+ mov r14,#0x80000000
-+
-+ mov r1,#1
-+ b CPDO_sqt_loop1_first
-+CPDO_sqt_loop1:
-+ adds r3,r3,r3
-+ adcs r2,r2,r2
-+CPDO_sqt_loop1_first:
-+ add r6,r4,r8,lsr r1 @r7 const = r5
-+ bcs CPDO_sqt_loop1_1
-+ cmp r2,r6
-+ cmpeq r3,r5 @r5 for r7
-+ bcc CPDO_sqt_loop1_0
-+CPDO_sqt_loop1_1:
-+ orr r4,r4,r14,lsr r1
-+ subs r3,r3,r5 @r5 for r7
-+ sbc r2,r2,r6
-+CPDO_sqt_loop1_0:
-+ add r1,r1,#1
-+ cmp r1,#30
-+ ble CPDO_sqt_loop1
-+
-+ adds r3,r3,r3
-+ adcs r2,r2,r2
-+ bcs CPDO_sqt_between_1
-+ adds r7,r5,#0x80000000
-+ adc r6,r4,#0
-+ cmp r2,r6
-+ cmpeq r3,r7
-+ bcc CPDO_sqt_between_0
-+CPDO_sqt_between_1:
-+ orr r4,r4,#0x00000001
-+ subs r3,r3,r5
-+ sbc r2,r2,r4
-+ subs r3,r3,#0x80000000
-+ sbc r2,r2,#0
-+CPDO_sqt_between_0:
-+ mov r1,#0
-+
-+CPDO_sqt_loop2:
-+ adds r3,r3,r3
-+ adcs r2,r2,r2
-+ bcs CPDO_sqt_loop2_1
-+ adds r7,r5,r8,lsr r1
-+ adc r6,r4,#0
-+ cmp r2,r6
-+ cmpeq r3,r7
-+ bcc CPDO_sqt_loop2_0
-+CPDO_sqt_loop2_1:
-+ orr r5,r5,r14,lsr r1
-+ subs r3,r3,r5
-+ sbc r2,r2,r4
-+ subs r3,r3,r8,lsr r1
-+ sbc r2,r2,#0
-+CPDO_sqt_loop2_0:
-+ add r1,r1,#1
-+ cmp r1,#30
-+ ble CPDO_sqt_loop2
-+
-+ adds r3,r3,r3
-+ adcs r2,r2,r2
-+ bcs CPDO_sqt_after_1
-+ cmp r2,r6
-+ cmpeq r3,r7
-+ bcc CPDO_sqt_after_0
-+CPDO_sqt_after_1:
-+ orr r5,r5,#0x00000001
-+CPDO_sqt_after_0:
-+
-+ mov r1,#0
-+ stmia r0,{r1,r4,r5}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_rnd
-+CPDO_rnd:
-+ ldmia r2,{r1,r2,r3,r5}
-+ bl CPDO_rnd_core
-+
-+CPDO_rnd_store:
-+ stmia r0,{r1,r2,r3,r5}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDO_rnd_core
-+CPDO_rnd_core:
-+ and r4,r4,#0x00000060
-+ add pc,pc,r4,lsr#3
-+ mov r0,r0
-+ b CPDO_rnd_N
-+ b CPDO_rnd_P
-+ b CPDO_rnd_M
-+ b CPDO_rnd_Z
-+
-+CPDO_rnd_N:
-+ cmp r5,#-1
-+ blt CPDO_rnd_zero
-+ cmp r5,#63
-+ movge pc,r14
-+ mov r4,#0x40000000
-+ cmp r5,#31
-+ bge CPDO_rnd_N_2
-+
-+ adds r2,r2,r4,lsr r5
-+ bcc CPDO_rnd_end
-+ b CPDO_rnd_end_norm
-+
-+CPDO_rnd_N_2:
-+CPDO_rnd_P_2:
-+ sub r6,r5,#32
-+ adds r3,r3,r4,ror r6 @ror ist needed to handle a -1 correctly
-+ adcs r2,r2,#0
-+ bcc CPDO_rnd_end
-+ b CPDO_rnd_end_norm
-+
-+CPDO_rnd_P:
-+ tst r1,#0x80000000
-+ bne CPDO_rnd_M_entry
-+CPDO_rnd_P_entry:
-+ cmp r5,#0
-+ blt CPDO_rnd_P_small
-+ cmp r5,#63
-+ movge pc,r14
-+ mov r4,#0x7fffffff
-+ cmp r5,#32
-+ bge CPDO_rnd_P_2
-+
-+ adds r3,r3,#0xffffffff
-+ adcs r2,r2,r4,lsr r5
-+ bcc CPDO_rnd_end
-+ b CPDO_rnd_end_norm
-+
-+CPDO_rnd_P_small:
-+ cmp r5,#0x80000000
-+ moveq pc,r14
-+ b CPDO_rnd_one
-+
-+CPDO_rnd_M:
-+ tst r1,#0x80000000
-+ bne CPDO_rnd_P_entry
-+CPDO_rnd_M_entry:
-+ cmp r5,#0
-+ blt CPDO_rnd_zero
-+ cmp r5,#63
-+ movge pc,r14
-+
-+ b CPDO_rnd_end
-+
-+CPDO_rnd_Z:
-+ cmp r5,#0
-+ blt CPDO_rnd_zero
-+ cmp r5,#63
-+ movge pc,r14
-+ b CPDO_rnd_end
-+
-+CPDO_rnd_end_norm:
-+ add r5,r5,#1
-+ movs r2,r2,rrx
-+ mov r3,r3,rrx
-+CPDO_rnd_end:
-+ rsbs r4,r5,#31
-+ bmi CPDO_rnd_end_2
-+ mov r3,#0
-+ mov r2,r2,lsr r4
-+ mov r2,r2,lsl r4
-+ mov pc,r14
-+
-+CPDO_rnd_end_2:
-+ rsb r4,r5,#63
-+ mov r3,r3,lsr r4
-+ mov r3,r3,lsl r4
-+ mov pc,r14
-+
-+CPDO_rnd_one:
-+ mov r2,#0x80000000
-+ mov r3,#0
-+ mov r5,#0
-+ mov pc,r14
-+
-+CPDO_rnd_zero:
-+ mov r1,#0
-+ mov r2,#0
-+ mov r3,#0
-+ mov r5,#0x80000000
-+ mov pc,r14
-+
-+/*---------------------------------------------------------------------------*/
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/fastfpe/CPDT.S 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,430 @@
-+/*
-+The FP structure has 4 words reserved for each register, the first is used just
-+for the sign in bit 31, the second and third are for the mantissa (unsigned
-+integer, high 32 bit first) and the fourth is the exponent (signed integer).
-+The mantissa is always normalized.
-+
-+If the exponent is 0x80000000, that is the most negative value, the number
-+represented is 0 and both mantissa words are also 0.
-+
-+If the exponent is 0x7fffffff, that is the biggest positive value, the number
-+represented is infinity if the high 32 mantissa bit are also 0, otherwise it is
-+a NaN. The low 32 mantissa bit are 0 if the number represented is infinity.
-+
-+Decimal and packed decimal numbers are not supported yet.
-+*/
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_load_single
-+CPDT_load_single:
-+ ldr r1,[r6]
-+
-+ and r2,r1,#0x80000000 @ r2 = sign
-+
-+ mov r5,r1,lsr#23
-+ bics r5,r5,#0x100
-+ beq CPDT_ls_e0 @ exponent = 0; zero/denormalized
-+ teq r5,#255
-+ beq CPDT_ls_e255 @ exponent = 255; infinity/NaN
-+
-+ sub r5,r5,#127 @ r5 = exponent, remove normalized bias
-+
-+ mov r3,r1,lsl#8
-+ orr r3,r3,#0x80000000
-+ mov r4,#0 @ r3,r4 = mantissa
-+
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+CPDT_ls_e0:
-+ movs r3,r1,lsl#9
-+ beq CPDT_load_zero
-+
-+ mov r5,#-127
-+
-+CPDT_ls_e0_norm:
-+ tst r3,#0x80000000
-+ subeq r5,r5,#1
-+ moveq r3,r3,lsl#1
-+ beq CPDT_ls_e0_norm
-+
-+ mov r4,#0
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+CPDT_ls_e255:
-+ mov r3,r1,lsl#9
-+ mov r4,#0
-+ mov r5,#0x7fffffff
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+CPDT_load_zero:
-+ mov r3,#0
-+ mov r4,#0
-+ mov r5,#0x80000000
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_load_double
-+CPDT_load_double:
-+ ldr r1,[r6]
-+ ldr r6,[r6,#4]
-+
-+ and r2,r1,#0x80000000 @ r2 = sign
-+
-+ mov r5,r1,lsr#20
-+ bics r5,r5,#0x800
-+ beq CPDT_ld_e0 @ exponent = 0; zero/denormalized
-+ add r4,r5,#1
-+ teq r4,#2048
-+ beq CPDT_ld_e2047 @ exponent = 2047; infinity/NaN
-+
-+ add r5,r5,#1
-+ sub r5,r5,#1024 @ r5 = exponent, remove normalized bias
-+
-+ mov r3,r1,lsl#11
-+ orr r3,r3,#0x80000000
-+ orr r3,r3,r6,lsr #21
-+ mov r4,r6,lsl#11 @ r3,r4 = mantissa
-+
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+CPDT_ld_e0:
-+ mov r3,r1,lsl#12
-+ orr r3,r3,r6,lsr#20
-+ movs r4,r6,lsl#12
-+ teqeq r3,#0
-+ beq CPDT_load_zero
-+
-+ mov r5,#1
-+ sub r5,r5,#1024
-+
-+CPDT_ld_e0_norm:
-+ tst r3,#0x80000000
-+ subeq r5,r5,#1
-+ moveqs r4,r4,lsl#1
-+ adceq r3,r3,r3
-+ beq CPDT_ld_e0_norm
-+
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+CPDT_ld_e2047:
-+ mov r3,r1,lsl#12
-+ orr r3,r3,r6,lsr#1
-+ bic r6,r6,#0x80000000
-+ orr r3,r3,r6 @ to get all fraction bits !
-+ mov r4,#0
-+ mov r5,#0x7fffffff
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_load_extended
-+CPDT_load_extended:
-+ ldr r1,[r6]
-+ ldr r3,[r6,#4]
-+ ldr r4,[r6,#8]
-+
-+ and r2,r1,#0x80000000
-+ bics r5,r1,#0x80000000
-+ beq CPDT_le_e0
-+ add r1,r5,#1
-+ teq r4,#32768
-+ beq CPDT_le_e32767
-+
-+ add r5,r5,#1
-+ sub r5,r5,#16384
-+
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+CPDT_le_e0:
-+ teq r3,#0
-+ teqeq r4,#0
-+ beq CPDT_load_zero
-+
-+ mov r5,#2
-+ sub r5,r5,#16384
-+ b CPDT_ld_e0_norm
-+
-+CPDT_le_e32767:
-+ mov r3,r3,lsl#1
-+ orr r3,r3,r4,lsr#1
-+ bic r4,r4,#0x80000000
-+ orr r3,r3,r4
-+ mov r5,#0x7fffffff
-+ stmia r0,{r2-r5}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_load_decimal
-+CPDT_load_decimal:
-+
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_store_single
-+CPDT_store_single:
-+ ldmia r0,{r1-r4}
-+
-+ cmp r4,#-127
-+ ble CPDT_ss_e0
-+ cmp r4,#128
-+ bge CPDT_ss_e255
-+
-+ adds r2,r2,#1<<7 @ round to nearest
-+ bcs CPDT_ss_rnd_ovfl @ very very seldom taken
-+
-+CPDT_ss_store:
-+ add r4,r4,#127
-+ orr r1,r1,r4,lsl#23
-+
-+ bic r2,r2,#0x80000000
-+ orr r1,r1,r2,lsr#8
-+
-+ str r1,[r6]
-+ b fastfpe_next
-+
-+CPDT_ss_rnd_ovfl:
-+ add r4,r4,#1
-+ cmp r4,#128
-+ bge CPDT_ss_e255
-+
-+ mov r2,#0x80000000
-+ mov r3,#0
-+ b CPDT_ss_store
-+
-+CPDT_ss_e0:
-+ cmp r4,#-150
-+ ble CPDT_ss_zero
-+
-+ add r4,r4,#126
-+CPDT_ss_unnormalize:
-+ mov r2,r2,lsr#1
-+ adds r4,r4,#1
-+ bne CPDT_ss_unnormalize
-+
-+ orr r1,r1,r2,lsr#8
-+
-+CPDT_ss_zero:
-+ str r1,[r6]
-+ b fastfpe_next
-+
-+CPDT_ss_e255:
-+ cmp r4,#0x7fffffff
-+ bne CPDT_ss_inf
-+ cmp r2,#0
-+ beq CPDT_ss_inf
-+
-+ orr r1,r1,#0x00200000 @ for safety so that it is not INF
-+ orr r1,r1,r2,lsr#9 @ get highest bit of mantissa
-+
-+CPDT_ss_inf:
-+ orr r1,r1,#0x7f000000
-+ orr r1,r1,#0x00800000
-+ str r1,[r6]
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_store_double
-+CPDT_store_double:
-+ ldmia r0,{r1-r4}
-+
-+ cmp r4,#1024 @ this check has to be first, or
-+ bge CPDT_sd_e2047 @ overflow can occur on second !
-+ add r0,r4,#3
-+ cmp r0,#-1023+3 @ cmp with -1023
-+ ble CPDT_sd_e0
-+
-+ adds r3,r3,#1<<10 @ round to nearest
-+ adcs r2,r2,#0
-+ bcs CPDT_sd_rnd_ovfl @ very very seldom taken
-+
-+CPDT_sd_store:
-+ sub r4,r4,#1
-+ add r4,r4,#1024
-+ orr r1,r1,r4,lsl#20
-+
-+ bic r2,r2,#0x80000000
-+ orr r1,r1,r2,lsr#11
-+
-+ mov r2,r2,lsl#21
-+ orr r2,r2,r3,lsr#11
-+
-+ stmia r6,{r1,r2}
-+ b fastfpe_next
-+
-+CPDT_sd_rnd_ovfl:
-+ add r4,r4,#1
-+ cmp r4,#1024
-+ bge CPDT_sd_e2047
-+
-+ mov r2,#0x80000000
-+ mov r3,#0
-+ b CPDT_sd_store
-+
-+CPDT_sd_e0:
-+ add r0,r4,#1075-1024
-+ cmp r0,#-1024
-+ ble CPDT_sd_zero
-+
-+ add r4,r4,#1024
-+ sub r4,r4,#2
-+CPDT_sd_unnormalize:
-+ movs r2,r2,lsr#1
-+ mov r3,r3,rrx
-+ adds r4,r4,#1
-+ bne CPDT_sd_unnormalize
-+
-+ orr r1,r1,r2,lsr#11
-+ mov r2,r2,lsl#21
-+ orr r2,r2,r3,lsr#11
-+
-+ stmia r6,{r1,r2}
-+ b fastfpe_next
-+
-+CPDT_sd_zero:
-+ mov r2,#0
-+ stmia r6,{r1,r2}
-+ b fastfpe_next
-+
-+CPDT_sd_e2047:
-+ cmp r4,#0x7fffffff
-+ bne CPDT_sd_inf
-+ cmp r2,#0
-+ beq CPDT_sd_inf
-+
-+ orr r1,r1,#0x00040000 @ for safety so that it is not INF
-+ orr r1,r1,r2,lsr#12 @ get highest bit of mantissa
-+
-+CPDT_sd_inf:
-+ orr r1,r1,#0x7f000000
-+ orr r1,r1,#0x00f00000
-+ stmia r6,{r1,r2}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_store_extended
-+CPDT_store_extended:
-+ ldmia r0,{r1-r4}
-+
-+ cmp r4,#16384 @ this check has to be first, or
-+ bge CPDT_se_e32767 @ overflow can occur with second !
-+ add r0,r4,#63
-+ cmp r0,#-16383+63
-+ ble CPDT_se_e0
-+
-+ sub r4,r4,#1
-+ add r4,r4,#16384
-+ orr r1,r1,r4
-+
-+ stmia r6,{r1-r3}
-+ b fastfpe_next
-+
-+CPDT_se_e0:
-+ add r0,r4,#16446-16384
-+ cmp r0,#-16384
-+ ble CPDT_se_zero
-+
-+ add r4,r4,#16384
-+ sub r4,r4,#2
-+CPDT_se_unnormalize:
-+ movs r2,r2,lsr#1
-+ mov r3,r3,rrx
-+ adds r4,r4,#1
-+ bne CPDT_se_unnormalize
-+
-+ stmia r6,{r1-r3}
-+ b fastfpe_next
-+
-+CPDT_se_zero:
-+ mov r2,#0
-+ mov r3,#0
-+ stmia r6,{r1-r3}
-+ b fastfpe_next
-+
-+CPDT_se_e32767:
-+ cmp r4,#0x7fffffff
-+ bne CPDT_se_inf
-+ cmp r2,#0
-+ beq CPDT_se_inf
-+
-+ mov r2,r2,lsl#1
-+ orr r2,r2,#0x20000000
-+
-+CPDT_se_inf:
-+ orr r1,r1,#0x00007f00
-+ orr r1,r1,#0x000000ff
-+ stmia r6,{r1-r3}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_store_decimal
-+CPDT_store_decimal:
-+
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_sfm
-+CPDT_sfm:
-+ add r2,r10,r0,lsr#8
-+ ldr r4,[r2,#0]
-+ ldr r3,[r2,#4]
-+ bic r3,r3,#0x80000000
-+ orr r3,r3,r4
-+ str r3,[r6],#4
-+ ldr r3,[r2,#8]
-+ str r3,[r6],#4
-+ ldr r3,[r2,#12]
-+ str r3,[r6],#4
-+
-+ add r0,r0,#1<<12
-+ and r0,r0,#7<<12
-+ subs r1,r1,#1
-+ bne CPDT_sfm
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPDT_lfm
-+CPDT_lfm:
-+ add r2,r10,r0,lsr#8
-+ ldr r4,[r6],#4
-+ and r3,r4,#0x80000000
-+ str r3,[r2,#0]
-+ ldr r3,[r6],#4
-+ str r3,[r2,#8]
-+ ldr r3,[r6],#4
-+ str r3,[r2,#12]
-+
-+ cmp r3,#0x80000000 @ does the exp indicate zero?
-+ biceq r4,r4,#0x80000000 @ if so, indicate 'denormalized'
-+ beq CPDT_lfm_storer4
-+ cmp r3,#0x7fffffff @ does the exp indicate inf or NaN?
-+ biceq r4,r4,#0x80000000 @ if so, indicate 'denormalized'
-+ beq CPDT_lfm_storer4
-+ orrne r4,r4,#0x80000000 @ otherwise, set normalized bit
-+
-+CPDT_lfm_storer4:
-+ str r4,[r2,#4]
-+
-+ add r0,r0,#1<<12
-+ and r0,r0,#7<<12
-+ subs r1,r1,#1
-+ bne CPDT_lfm
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/fastfpe/CPRT.S 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,185 @@
-+/*
-+The FP structure has 4 words reserved for each register, the first is used
-+just
-+for the sign in bit 31, the second and third are for the mantissa (unsigned
-+integer, high 32 bit first) and the fourth is the exponent (signed integer).
-+The mantissa is always normalized.
-+
-+If the exponent is 0x80000000, that is the most negative value, the number
-+represented is 0 and both mantissa words are also 0.
-+
-+If the exponent is 0x7fffffff, that is the biggest positive value, the
-+number
-+represented is infinity if the high 32 mantissa bit are also 0, otherwise it
-+is
-+a NaN. The low 32 mantissa bit are 0 if the number represented is infinity.
-+
-+Decimal and packed decimal numbers are not supported yet.
-+*/
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .text
-+ .globl CPRT_flt
-+CPRT_flt:
-+ add r0,r13,r0,lsr#10
-+ ldr r2,[r0]
-+ mov r3,#0
-+ cmp r2,#0
-+ beq CPRT_flt_zero
-+
-+ ands r0,r2,#0x80000000
-+ rsbne r2,r2,#0
-+ mov r4,#31
-+
-+ cmp r2,#0x00010000
-+ movcc r2,r2,lsl#16
-+ subcc r4,r4,#16
-+
-+ cmp r2,#0x01000000
-+ movcc r2,r2,lsl#8
-+ subcc r4,r4,#8
-+
-+ cmp r2,#0x10000000
-+ movcc r2,r2,lsl#4
-+ subcc r4,r4,#4
-+
-+ cmp r2,#0x40000000
-+ movcc r2,r2,lsl#2
-+ subcc r4,r4,#2
-+
-+ cmp r2,#0x80000000
-+ movcc r2,r2,lsl#1
-+ subcc r4,r4,#1
-+
-+ stmia r1,{r0,r2,r3,r4}
-+ b fastfpe_next
-+
-+CPRT_flt_zero:
-+ mov r0,#0
-+ mov r4,#0x80000000
-+ stmia r1,{r0,r2,r3,r4}
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPRT_fix
-+CPRT_fix:
-+ ldmia r2,{r1,r2,r3,r5}
-+ bl CPDO_rnd_core
-+
-+CPRT_back:
-+ add r0,r13,r0,lsr#10
-+ cmp r5,#0
-+ blt CPRT_int_zero
-+ cmp r5,#30
-+ bgt CPRT_overflow
-+
-+ rsb r5,r5,#31
-+ mov r2,r2,lsr r5
-+ tst r1,#0x80000000
-+ rsbne r2,r2,#0
-+
-+ str r2,[r0]
-+ b fastfpe_next
-+
-+CPRT_int_zero:
-+ mov r2,#0
-+ str r2,[r0]
-+ b fastfpe_next
-+
-+CPRT_overflow:
-+ mov r2,#0x80000000
-+ tst r1,#0x80000000
-+ subeq r2,r2,#1
-+ str r2,[r0]
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPRT_wfs
-+CPRT_wfs:
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPRT_rfs
-+CPRT_rfs:
-+ add r0,r13,r0,lsr#10
-+ mov r1,#0x02000000 @ Software Emulation, not Acorn FPE
-+ str r1,[r0]
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPRT_cmf
-+CPRT_cmf:
-+ ldmia r1,{r1,r3,r5,r7}
-+ ldmia r2,{r2,r4,r6,r8}
-+
-+CPRT_cmf_e:
-+ ldr r0,[r13,#16*4]
-+
-+ cmp r7,#0x7fffffff
-+ bic r0,r0,#0xf0000000
-+
-+ cmpeq r3,#0xffffffff
-+ beq CPRT_cmf_unordered
-+ cmp r8,#0x7fffffff
-+ cmpeq r4,#0xffffffff
-+ beq CPRT_cmf_unordered
-+
-+ cmp r1,r2
-+ beq CPRT_cmf_equalsign
-+ b CPRT_cmf_sign
-+
-+CPRT_cmf_equalsign:
-+ cmp r7,r8
-+ beq CPRT_cmf_equalexponent
-+ bgt CPRT_cmf_sign
-+ b CPRT_cmf_signb
-+
-+CPRT_cmf_equalexponent:
-+ cmp r3,r4
-+ cmpeq r5,r6
-+ beq CPRT_cmf_equal
-+ bhi CPRT_cmf_sign
-+ b CPRT_cmf_signb
-+
-+CPRT_cmf_sign:
-+ cmp r7,#0x80000000 @ (0.0 == -0.0)?
-+ cmpeq r7,r8
-+ beq CPRT_cmf_equal
-+ tst r1,#0x80000000
-+ orreq r0,r0,#0x20000000
-+ orrne r0,r0,#0x80000000
-+ str r0,[r13,#16*4]
-+ b fastfpe_next
-+
-+CPRT_cmf_signb:
-+ tst r1,#0x80000000
-+ orrne r0,r0,#0x20000000
-+ orreq r0,r0,#0x80000000
-+ str r0,[r13,#16*4]
-+ b fastfpe_next
-+
-+CPRT_cmf_equal:
-+ orr r0,r0,#0x60000000
-+ str r0,[r13,#16*4]
-+ b fastfpe_next
-+
-+CPRT_cmf_unordered:
-+ orr r0,r0,#0x10000000
-+ str r0,[r13,#16*4]
-+ b fastfpe_next
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl CPRT_cnf
-+CPRT_cnf:
-+ ldmia r1,{r1,r3,r5,r7}
-+ ldmia r2,{r2,r4,r6,r8}
-+ eor r2,r2,#0x80000000
-+ b CPRT_cmf_e
-+
-+/*---------------------------------------------------------------------------*/
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/fastfpe/Makefile 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,25 @@
-+#
-+# linux/arch/arm/fastfpe/Makefile
-+#
-+# Copyright (C) Peter Teichmann
-+#
-+
-+O_TARGET := fast-math-emu.o
-+
-+obj-y :=
-+obj-m :=
-+obj-n :=
-+obj- :=
-+
-+fastfpe-objs := module.o entry.o CPDO.o CPRT.o CPDT.o
-+
-+list-multi := fastfpe.o
-+
-+obj-$(CONFIG_FPE_FASTFPE) += fastfpe.o
-+
-+USE_STANDARD_AS_RULE := true
-+
-+include $(TOPDIR)/Rules.make
-+
-+fastfpe.o: $(fastfpe-objs)
-+ $(LD) -r -o $@ $(fastfpe-objs)
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/fastfpe/entry.S 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,295 @@
-+/*
-+At entry the registers contain the following information:
-+
-+r14 return address for undefined exception return
-+r9 return address for return from exception
-+r13 user registers on stack, offset 0 up to offset 4*15 contains
-+ registers r0..15, then the psr
-+r10 FP workspace 35 words (init, reg[8][4], fpsr, fpcr)
-+
-+*/
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .data
-+fp_const:
-+ .word 0, 0x00000000, 0, 0x80000000 @ 0
-+ .word 0, 0x80000000, 0, 0 @ 1
-+ .word 0, 0x80000000, 0, 1 @ 2
-+ .word 0, 0xc0000000, 0, 1 @ 3
-+ .word 0, 0x80000000, 0, 2 @ 4
-+ .word 0, 0xa0000000, 0, 2 @ 5
-+ .word 0, 0x80000000, 0, -1 @ 0.5
-+ .word 0, 0xa0000000, 0, 3 @ 10
-+fp_undef:
-+ .word 0
-+fp_cond:
-+ .word 0xf0f0 @ eq
-+ .word 0x0f0f @ ne
-+ .word 0xcccc @ cs
-+ .word 0x3333 @ cc
-+ .word 0xff00 @ mi
-+ .word 0x00ff @ pl
-+ .word 0xaaaa @ vs
-+ .word 0x5555 @ vc
-+ .word 0x0c0c @ hi
-+ .word 0xf3f3 @ ls
-+ .word 0xaa55 @ ge
-+ .word 0x55aa @ lt
-+ .word 0x0a05 @ gt
-+ .word 0xf5fa @ le
-+ .word 0xffff @ al
-+ .word 0x0000 @ nv
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .text
-+ .globl fastfpe_enter
-+fastfpe_enter:
-+ ldr r4,=fp_undef
-+ str r14,[r4] @ to free one register
-+ add r10,r10,#4 @ to make the code simpler
-+ ldr r4,[r13,#60] @ r4=saved PC
-+ ldr r4,[r4,#-4] @ r4=trapped instruction
-+ and r1,r4,#0x00000f00 @ r1=coprocessor << 8
-+next_enter:
-+ cmp r1,#1<<8 @ copro 1 ?
-+ beq copro_1
-+ cmp r1,#2<<8
-+ movne pc,r14
-+
-+copro_2:
-+ and r1,r4,#0x0f000000
-+ cmp r1,#0x0c000000 @ CPDT with post indexing
-+ cmpne r1,#0x0d000000 @ CPDT with pre indexing
-+ beq CPDT_M_enter
-+ mov pc,r14
-+
-+copro_1:
-+ and r1,r4,#0x0f000000
-+ cmp r1,#0x0e000000 @ CPDO
-+ beq CPDO_CPRT_enter
-+ cmp r1,#0x0c000000 @ CPDT with post indexing
-+ cmpne r1,#0x0d000000 @ CPDT with pre indexing
-+ beq CPDT_1_enter
-+ mov pc,r14
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ .globl fastfpe_next
-+fastfpe_next:
-+ ldr r5,[r13,#60]
-+next_after_cond:
-+__x1:
-+ ldrt r4,[r5],#4
-+
-+ ldr r0,=fp_cond @ check condition of next instruction
-+ ldr r1,[r13,#64] @ psr containing flags
-+ mov r2,r4,lsr#28
-+ mov r1,r1,lsr#28
-+ ldr r0,[r0,r2,lsl#2]
-+ mov r0,r0,lsr r1
-+ tst r0,#1
-+ beq next_after_cond @ must not necessarily have been an
-+ @ FP instruction !
-+ and r1,r4,#0x0f000000 @ Test for copro instruction
-+ cmp r1,#0x0c000000
-+ rsbgts r0,r1,#0x0e000000 @ cmpgt #0x0e000000,r1
-+ movlt pc,r9 @ next is no copro instruction, return
-+
-+ ands r1,r4,#0x00000f00 @ r1 = coprocessor << 8
-+ cmpne r1,#3<<8
-+ movge pc,r9 @ copro = 0 or >=3, return
-+
-+ str r5,[r13,#60] @ save updated pc
-+ b next_enter
-+
-+/*---------------------------------------------------------------------------*/
-+
-+undefined:
-+ ldr r4,=fp_undef
-+ ldr pc,[r4]
-+
-+/*---------------------------------------------------------------------------*/
-+
-+CPDT_1_enter:
-+ and r5,r4,#0x000f0000 @ r5=base register number << 16
-+ ldr r6,[r13,r5,lsr#14] @ r6=base address
-+ cmp r5,#0x000f0000 @ base register = pc ?
-+ addeq r6,r6,#4
-+ and r7,r4,#0x000000ff @ r7=offset value
-+
-+ tst r4,#0x00800000 @ up or down?
-+ addne r7,r6,r7,lsl#2
-+ subeq r7,r6,r7,lsl#2 @ r6=base address +/- offset
-+ tst r4,#0x01000000 @ preindexing ?
-+ movne r6,r7
-+ tst r4,#0x00200000 @ write back ?
-+ cmpne r5,#0x000f0000 @ base register = pc ?
-+ strne r7,[r13,r5,lsr#14]
-+
-+ and r0,r4,#0x00007000 @ r0=fp register number << 12
-+ add r0,r10,r0,lsr#8 @ r0=address of fp register
-+ mov r1,#0
-+ tst r4,#0x00008000
-+ orrne r1,r1,#1 @ T0
-+ tst r4,#0x00400000
-+ orrne r1,r1,#2 @ T1
-+ tst r4,#0x00100000
-+ orrne r1,r1,#4 @ L/S
-+
-+ add pc,pc,r1,lsl#2
-+ mov r0,r0
-+ b CPDT_store_single @ these functions get
-+ b CPDT_store_double @ r0=address of fp register
-+ b CPDT_store_extended @ r6=address of data
-+ b undefined @ CPDT_store_decimal
-+ b CPDT_load_single
-+ b CPDT_load_double
-+ b CPDT_load_extended
-+ b undefined @ CPDT_load_decimal
-+
-+/*---------------------------------------------------------------------------*/
-+
-+CPDT_M_enter:
-+ and r5,r4,#0x000f0000 @ r5=base register number << 16
-+ ldr r6,[r13,r5,lsr#14] @ r6=base address
-+ cmp r5,#0x000f0000 @ base register = pc ?
-+ addeq r6,r6,#4
-+ and r7,r4,#0x000000ff @ r7=offset value
-+
-+ tst r4,#0x00800000 @ up or down?
-+ addne r7,r6,r7,lsl#2
-+ subeq r7,r6,r7,lsl#2 @ r7=base address +/- offset
-+ tst r4,#0x01000000 @ preindexing ?
-+ movne r6,r7
-+ tst r4,#0x00200000 @ write back ?
-+ cmpne r5,#0x000f0000 @ base register = pc ?
-+ strne r7,[r13,r5,lsr#14]
-+
-+ and r0,r4,#0x00007000 @ r0=fp register number << 12
-+ and r1,r4,#0x00008000
-+ mov r1,r1,lsr#15 @ N0
-+ and r2,r4,#0x00400000
-+ orrs r1,r1,r2,lsr#21 @ N1
-+ addeq r1,r1,#4 @ r1=register count
-+
-+ tst r4,#0x00100000 @ load/store
-+ beq CPDT_sfm
-+ b CPDT_lfm
-+
-+/*---------------------------------------------------------------------------*/
-+
-+CPDO_CPRT_enter:
-+ tst r4,#0x00000010
-+ bne CPRT_enter
-+
-+ and r0,r4,#0x00007000
-+ add r0,r10,r0,lsr#8 @ r0=address of Fd
-+ and r1,r4,#0x00070000
-+ add r1,r10,r1,lsr#12 @ r1=address of Fn
-+ tst r4,#0x00000008
-+ bne CPDO_const
-+ and r2,r4,#0x00000007
-+ add r2,r10,r2,lsl#4 @ r2=address of Fm
-+
-+CPDO_constback:
-+ and r3,r4,#0x00f00000
-+ tst r4,#0x00008000
-+ orrne r3,r3,#0x01000000
-+
-+ add pc,pc,r3,lsr#18
-+ mov r0,r0
-+ b CPDO_adf
-+ b CPDO_muf
-+ b CPDO_suf
-+ b CPDO_rsf
-+ b CPDO_dvf
-+ b CPDO_rdf
-+ b undefined
-+ b undefined
-+ b undefined @ CPDO_rmf
-+ b CPDO_muf
-+ b CPDO_dvf
-+ b CPDO_rdf
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b CPDO_mvf
-+ b CPDO_mnf
-+ b CPDO_abs
-+ b CPDO_rnd
-+ b CPDO_sqt
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b CPDO_rnd
-+ b fastfpe_next
-+
-+CPDO_const:
-+ ldr r2,=fp_const
-+ and r3,r4,#0x00000007
-+ add r2,r2,r3,lsl#4
-+ b CPDO_constback
-+
-+/*---------------------------------------------------------------------------*/
-+
-+CPRT_enter:
-+ and r0,r4,#0x0000f000 @ r0=Rd<<12
-+ and r1,r4,#0x00070000
-+ add r1,r10,r1,lsr#12 @ r1=address of Fn
-+ tst r4,#0x00000008
-+ bne CPRT_const
-+ and r2,r4,#0x00000007
-+ add r2,r10,r2,lsl#4 @ r2=address of Fm
-+
-+CPRT_constback:
-+ and r3,r4,#0x00f00000
-+
-+ add pc,pc,r3,lsr#18
-+ mov r0,r0
-+ b CPRT_flt
-+ b CPRT_fix
-+ b CPRT_wfs
-+ b CPRT_rfs
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b undefined
-+ b CPRT_cmf
-+ b undefined
-+ b CPRT_cnf
-+ b undefined
-+ b CPRT_cmf
-+ b undefined
-+ b CPRT_cnf
-+
-+CPRT_const:
-+ ldr r2,=fp_const
-+ and r3,r4,#0x00000007
-+ add r2,r2,r3,lsl#4
-+ b CPRT_constback
-+
-+/*---------------------------------------------------------------------------*/
-+
-+ @ The fetch of the next instruction to emulate could fault
-+
-+ .section .fixup,"ax"
-+ .align
-+__f1:
-+ mov pc,r9
-+ .previous
-+ .section __ex_table,"a"
-+ .align 3
-+ .long __x1,__f1
-+ .previous
-+
-+/*---------------------------------------------------------------------------*/
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/fastfpe/module.c 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,78 @@
-+/*
-+ Fast Floating Point Emulator
-+ (c) Peter Teichmann <mail@peter-teichmann.de>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2 of the License, or
-+ (at your option) any later version.
-+
-+ 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/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/init.h>
-+
-+#ifndef MODULE
-+#define kern_fp_enter fp_enter
-+
-+extern char fpe_type[];
-+#endif
-+
-+static void (*orig_fp_enter)(void); /* old kern_fp_enter value */
-+extern void (*kern_fp_enter)(void); /* current FP handler */
-+extern void fastfpe_enter(void); /* forward declarations */
-+
-+#ifdef MODULE
-+/*
-+ * Return 0 if we can be unloaded. This can only happen if
-+ * kern_fp_enter is still pointing at fastfpe_enter
-+ */
-+static int fpe_unload(void)
-+{
-+ return (kern_fp_enter == fastfpe_enter) ? 0 : 1;
-+}
-+#endif
-+
-+static int __init fpe_init(void)
-+{
-+#ifdef MODULE
-+ if (!mod_member_present(&__this_module, can_unload))
-+ return -EINVAL;
-+ __this_module.can_unload = fpe_unload;
-+#else
-+ if (fpe_type[0] && strcmp(fpe_type, "fastfpe"))
-+ return 0;
-+#endif
-+
-+ printk("Fast Floating Point Emulator V0.9 (c) Peter Teichmann.\n");
-+
-+ /* Save pointer to the old FP handler and then patch ourselves in */
-+ orig_fp_enter = kern_fp_enter;
-+ kern_fp_enter = fastfpe_enter;
-+
-+ return 0;
-+}
-+
-+static void __exit fpe_exit(void)
-+{
-+ /* Restore the values we saved earlier. */
-+ kern_fp_enter = orig_fp_enter;
-+}
-+
-+module_init(fpe_init);
-+module_exit(fpe_exit);
-+
-+MODULE_AUTHOR("Peter Teichmann <mail@peter-teichmann.de>");
-+MODULE_DESCRIPTION("Fast floating point emulator with full precision");
---- linux-2.4.25/arch/arm/kernel/calls.S~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/kernel/calls.S 2004-03-31 17:15:08.000000000 +0200
-@@ -115,7 +115,7 @@
- .long SYMBOL_NAME(sys_ni_syscall) /* was sys_profil */
- .long SYMBOL_NAME(sys_statfs)
- /* 100 */ .long SYMBOL_NAME(sys_fstatfs)
-- .long SYMBOL_NAME(sys_ni_syscall)
-+ .long SYMBOL_NAME(sys_ni_syscall) /* 101 was sys_ioperm */
- .long SYMBOL_NAME(sys_socketcall)
- .long SYMBOL_NAME(sys_syslog)
- .long SYMBOL_NAME(sys_setitimer)
-@@ -126,7 +126,7 @@
- .long SYMBOL_NAME(sys_ni_syscall) /* was sys_uname */
- /* 110 */ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_iopl */
- .long SYMBOL_NAME(sys_vhangup)
-- .long SYMBOL_NAME(sys_ni_syscall)
-+ .long SYMBOL_NAME(sys_ni_syscall) /* 112 was sys_idle */
- .long SYMBOL_NAME(sys_syscall) /* call a syscall */
- .long SYMBOL_NAME(sys_wait4)
- /* 115 */ .long SYMBOL_NAME(sys_swapoff)
-@@ -137,7 +137,7 @@
- /* 120 */ .long SYMBOL_NAME(sys_clone_wapper)
- .long SYMBOL_NAME(sys_setdomainname)
- .long SYMBOL_NAME(sys_newuname)
-- .long SYMBOL_NAME(sys_ni_syscall)
-+ .long SYMBOL_NAME(sys_ni_syscall) /* 123 was sys_modify_ldt */
- .long SYMBOL_NAME(sys_adjtimex)
- /* 125 */ .long SYMBOL_NAME(sys_mprotect)
- .long SYMBOL_NAME(sys_sigprocmask)
-@@ -180,7 +180,7 @@
- .long SYMBOL_NAME(sys_arm_mremap)
- .long SYMBOL_NAME(sys_setresuid16)
- /* 165 */ .long SYMBOL_NAME(sys_getresuid16)
-- .long SYMBOL_NAME(sys_ni_syscall)
-+ .long SYMBOL_NAME(sys_ni_syscall) /* 166 was sys_vm86 */
- .long SYMBOL_NAME(sys_query_module)
- .long SYMBOL_NAME(sys_poll)
- .long SYMBOL_NAME(sys_nfsservctl)
---- linux-2.4.25/arch/arm/kernel/dma-rpc.c~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/kernel/dma-rpc.c 2004-03-31 17:15:08.000000000 +0200
-@@ -26,19 +26,6 @@
- #include <asm/mach/dma.h>
- #include <asm/hardware/iomd.h>
-
--#if 0
--typedef enum {
-- dma_size_8 = 1,
-- dma_size_16 = 2,
-- dma_size_32 = 4,
-- dma_size_128 = 16
--} dma_size_t;
--
--typedef struct {
-- dma_size_t transfersize;
--} dma_t;
--#endif
--
- #define TRANSFER_SIZE 2
-
- #define CURA (0)
-@@ -48,10 +35,6 @@
- #define CR (IOMD_IO0CR - IOMD_IO0CURA)
- #define ST (IOMD_IO0ST - IOMD_IO0CURA)
-
--#define state_prog_a 0
--#define state_wait_a 1
--#define state_wait_b 2
--
- static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma)
- {
- unsigned long end, offset, flags = 0;
-@@ -65,7 +48,7 @@
- if (end > PAGE_SIZE)
- end = PAGE_SIZE;
-
-- if (offset + (int) TRANSFER_SIZE > end)
-+ if (offset + TRANSFER_SIZE >= end)
- flags |= DMA_END_L;
-
- sg->length = end - TRANSFER_SIZE;
-@@ -103,27 +86,31 @@
- if (!(status & DMA_ST_INT))
- return;
-
-- if (status & DMA_ST_OFL && !dma->sg)
-- break;
--
-- iomd_get_next_sg(&dma->cur_sg, dma);
-+ if ((dma->state ^ status) & DMA_ST_AB)
-+ iomd_get_next_sg(&dma->cur_sg, dma);
-
- switch (status & (DMA_ST_OFL | DMA_ST_AB)) {
- case DMA_ST_OFL: /* OIA */
- case DMA_ST_AB: /* .IB */
- iomd_writel(dma->cur_sg.dma_address, base + CURA);
- iomd_writel(dma->cur_sg.length, base + ENDA);
-+ dma->state = DMA_ST_AB;
- break;
-
- case DMA_ST_OFL | DMA_ST_AB: /* OIB */
- case 0: /* .IA */
- iomd_writel(dma->cur_sg.dma_address, base + CURB);
- iomd_writel(dma->cur_sg.length, base + ENDB);
-+ dma->state = 0;
- break;
- }
-+
-+ if (status & DMA_ST_OFL &&
-+ dma->cur_sg.length == (DMA_END_S|DMA_END_L))
-+ break;
- } while (1);
-
-- iomd_writeb(0, base + CR);
-+ dma->state = ~DMA_ST_AB;
- disable_irq(irq);
- }
-
-@@ -158,6 +145,7 @@
- }
-
- iomd_writeb(DMA_CR_C, dma_base + CR);
-+ dma->state = DMA_ST_AB;
- }
-
- if (dma->dma_mode == DMA_MODE_READ)
-@@ -171,13 +159,11 @@
- {
- unsigned long dma_base = dma->dma_base;
- unsigned long flags;
-- unsigned int ctrl;
-
- local_irq_save(flags);
-- ctrl = iomd_readb(dma_base + CR);
-- if (ctrl & DMA_CR_E)
-+ if (dma->state != ~DMA_ST_AB)
- disable_irq(dma->dma_irq);
-- iomd_writeb(ctrl & ~DMA_CR_E, dma_base + CR);
-+ iomd_writeb(0, dma_base + CR);
- local_irq_restore(flags);
- }
-
---- linux-2.4.25/arch/arm/kernel/entry-armv.S~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/kernel/entry-armv.S 2004-03-31 17:15:08.000000000 +0200
-@@ -677,12 +677,11 @@
- mrs r9, cpsr @ Enable interrupts if they were
- tst r3, #I_BIT
- biceq r9, r9, #I_BIT @ previously
-- mov r0, r2 @ *** remove once everyones in sync
- /*
- * This routine must not corrupt r9
- */
- #ifdef MULTI_CPU
-- ldr r4, .LCprocfns @ pass r0, r3 to
-+ ldr r4, .LCprocfns @ pass r2, r3 to
- mov lr, pc @ processor code
- ldr pc, [r4] @ call processor specific code
- #else
-@@ -788,9 +787,8 @@
- stmdb r5, {sp, lr}^
- alignment_trap r7, r7, __temp_abt
- zero_fp
-- mov r0, r2 @ remove once everyones in sync
- #ifdef MULTI_CPU
-- ldr r4, .LCprocfns @ pass r0, r3 to
-+ ldr r4, .LCprocfns @ pass r2, r3 to
- mov lr, pc @ processor code
- ldr pc, [r4] @ call processor specific code
- #else
-@@ -840,7 +838,8 @@
- adrsvc al, r9, ret_from_exception @ r9 = normal FP return
- adrsvc al, lr, fpundefinstr @ lr = undefined instr return
-
--call_fpe: get_current_task r10
-+call_fpe: enable_irq r10
-+ get_current_task r10
- mov r8, #1
- strb r8, [r10, #TSK_USED_MATH] @ set current->used_math
- ldr r4, .LCfp
---- linux-2.4.25/arch/arm/kernel/head-armv.S~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/kernel/head-armv.S 2004-03-31 17:15:08.000000000 +0200
-@@ -1,7 +1,7 @@
- /*
- * linux/arch/arm/kernel/head-armv.S
- *
-- * Copyright (C) 1994-1999 Russell King
-+ * Copyright (C) 1994-2003 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
-@@ -163,10 +163,10 @@
- */
- .type __ret, %function
- __ret: ldr lr, __switch_data
-- mcr p15, 0, r0, c1, c0
-- mrc p15, 0, r0, c1, c0, 0 @ read it back.
-- mov r0, r0
-- mov r0, r0
-+ mcr p15, 0, r0, c1, c0, 0
-+ mrc p15, 0, r3, c0, c0, 0
-+ mov r3, r3
-+ mov r3, r3
- mov pc, lr
-
- /*
-@@ -214,6 +214,11 @@
- */
- __create_page_tables:
- pgtbl r4, r5 @ page table address
-+#if defined(CONFIG_CPU_DCACHE_DISABLE)
-+ bic r8, r8, #0x00c @ clear B, C
-+#elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
-+ bic r8, r8, #0x004 @ clear B
-+#endif
-
- /*
- * Clear the 16K level 1 swapper page table
---- linux-2.4.25/arch/arm/kernel/irq.c~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/kernel/irq.c 2004-03-31 17:15:08.000000000 +0200
-@@ -549,7 +549,7 @@
- kfree(action);
- goto out;
- }
-- printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
-+ printk(KERN_ERR "Trying to free IRQ%d\n",irq);
- #ifdef CONFIG_DEBUG_ERRORS
- __backtrace();
- #endif
---- linux-2.4.25/arch/arm/kernel/ptrace.c~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/kernel/ptrace.c 2004-03-31 17:15:08.000000000 +0200
-@@ -725,11 +725,8 @@
- goto out_tsk;
- }
- ret = -ESRCH;
-- if (!(child->ptrace & PT_PTRACED))
-- goto out_tsk;
-- if (child->state != TASK_STOPPED && request != PTRACE_KILL)
-- goto out_tsk;
-- if (child->p_pptr != current)
-+ ret = ptrace_check_attach(child, request == PTRACE_KILL);
-+ if (ret)
- goto out_tsk;
-
- ret = do_ptrace(request, child, addr, data);
---- linux-2.4.25/arch/arm/kernel/semaphore.c~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/kernel/semaphore.c 2004-03-31 17:15:08.000000000 +0200
-@@ -193,7 +193,7 @@
- bl __down_interruptible \n\
- mov ip, r0 \n\
- ldmfd sp!, {r0 - r3, pc}^ \n\
--
-+ \n\
- .align 5 \n\
- .globl __down_trylock_failed \n\
- __down_trylock_failed: \n\
---- linux-2.4.25/arch/arm/kernel/signal.c~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/kernel/signal.c 2004-03-31 17:15:08.000000000 +0200
-@@ -641,10 +641,7 @@
- /* FALLTHRU */
-
- default:
-- sigaddset(&current->pending.signal, signr);
-- recalc_sigpending(current);
-- current->flags |= PF_SIGNALED;
-- do_exit(exit_code);
-+ sig_exit(signr, exit_code, &info);
- /* NOTREACHED */
- }
- }
---- linux-2.4.25/arch/arm/lib/Makefile~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/lib/Makefile 2004-03-31 17:15:08.000000000 +0200
-@@ -15,7 +15,7 @@
- strnlen_user.o strchr.o strrchr.o testchangebit.o \
- testclearbit.o testsetbit.o uaccess.o getuser.o \
- putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
-- ucmpdi2.o udivdi3.o lib1funcs.o
-+ ucmpdi2.o udivdi3.o lib1funcs.o div64.o
- obj-m :=
- obj-n :=
-
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/lib/div64.S 2004-03-31 17:15:08.000000000 +0200
-@@ -0,0 +1,59 @@
-+#include <linux/linkage.h>
-+
-+#ifndef __ARMEB__
-+ql .req r0 @ quotient low
-+qh .req r1 @ quotient high
-+onl .req r0 @ original dividend low
-+onh .req r1 @ original dividend high
-+nl .req r4 @ dividend low
-+nh .req r5 @ dividend high
-+res .req r4 @ result
-+#else
-+ql .req r1
-+qh .req r0
-+onl .req r1
-+onh .req r0
-+nl .req r5
-+nh .req r4
-+res .req r5
-+#endif
-+
-+dl .req r3 @ divisor low
-+dh .req r2 @ divsor high
-+
-+
-+ENTRY(do_div64)
-+ stmfd sp!, {r4, r5, lr}
-+ mov nl, onl
-+ movs nh, onh @ if high bits are zero
-+ movne lr, #33
-+ moveq lr, #1 @ only divide low bits
-+ moveq nh, onl
-+
-+ tst dh, #0x80000000
-+ bne 2f
-+1: cmp nh, dh
-+ bls 2f
-+ add lr, lr, #1
-+ movs dh, dh, lsl #1 @ left justify disor
-+ bpl 1b
-+
-+2: movs nh, onh
-+ moveq dl, dh
-+ moveq dh, #0
-+ movne dl, #0
-+ mov ql, #0
-+ mov qh, #0
-+3: subs ip, nl, dl @ trial subtraction
-+ sbcs ip, nh, dh
-+ movcs nh, ip @ only update if successful
-+ subcs nl, nl, dl @ (repeat the subtraction)
-+ adcs ql, ql, ql @ C=1 if successful, shift into
-+ adc qh, qh, qh @ quotient
-+ movs dh, dh, lsr #1 @ shift base high part right
-+ mov dl, dl, rrx @ shift base low part right
-+ subs lr, lr, #1
-+ bne 3b
-+
-+ mov r2, res
-+ ldmfd sp!, {r4, r5, pc}
---- linux-2.4.25/arch/arm/lib/putuser.S~2.4.25-vrs2.patch 2001-10-11 18:04:57.000000000 +0200
-+++ linux-2.4.25/arch/arm/lib/putuser.S 2004-03-31 17:15:09.000000000 +0200
-@@ -30,11 +30,11 @@
-
- .global __put_user_1
- __put_user_1:
-- bic r2, sp, #0x1f00
-- bic r2, r2, #0x00ff
-- ldr r2, [r2, #TSK_ADDR_LIMIT]
-- sub r2, r2, #1
-- cmp r0, r2
-+ bic ip, sp, #0x1f00
-+ bic ip, ip, #0x00ff
-+ ldr ip, [ip, #TSK_ADDR_LIMIT]
-+ sub ip, ip, #1
-+ cmp r0, ip
- 1: strlsbt r1, [r0]
- movls r0, #0
- movls pc, lr
-@@ -42,11 +42,11 @@
-
- .global __put_user_2
- __put_user_2:
-- bic r2, sp, #0x1f00
-- bic r2, r2, #0x00ff
-- ldr r2, [r2, #TSK_ADDR_LIMIT]
-- sub r2, r2, #2
-- cmp r0, r2
-+ bic ip, sp, #0x1f00
-+ bic ip, ip, #0x00ff
-+ ldr ip, [ip, #TSK_ADDR_LIMIT]
-+ sub ip, ip, #2
-+ cmp r0, ip
- 2: strlsbt r1, [r0], #1
- movls r1, r1, lsr #8
- 3: strlsbt r1, [r0]
-@@ -56,11 +56,11 @@
-
- .global __put_user_4
- __put_user_4:
-- bic r2, sp, #0x1f00
-- bic r2, r2, #0x00ff
-- ldr r2, [r2, #TSK_ADDR_LIMIT]
-- sub r2, r2, #4
-- cmp r0, r2
-+ bic ip, sp, #0x1f00
-+ bic ip, ip, #0x00ff
-+ ldr ip, [ip, #TSK_ADDR_LIMIT]
-+ sub ip, ip, #4
-+ cmp r0, ip
- 4: strlst r1, [r0]
- movls r0, #0
- movls pc, lr
---- linux-2.4.25/arch/arm/mach-integrator/pci_v3.c~2.4.25-vrs2.patch 2003-06-13 16:51:29.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-integrator/pci_v3.c 2004-03-31 17:15:09.000000000 +0200
-@@ -21,7 +21,6 @@
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
- #include <linux/config.h>
--#include <linux/sched.h>
- #include <linux/kernel.h>
- #include <linux/pci.h>
- #include <linux/ptrace.h>
-@@ -32,6 +31,7 @@
- #include <linux/init.h>
-
- #include <asm/hardware.h>
-+#include <asm/io.h>
- #include <asm/irq.h>
- #include <asm/system.h>
- #include <asm/mach/pci.h>
-@@ -447,15 +447,16 @@
- #define SC_LBFADDR (IO_ADDRESS(INTEGRATOR_SC_BASE) + 0x20)
- #define SC_LBFCODE (IO_ADDRESS(INTEGRATOR_SC_BASE) + 0x24)
-
--static int v3_fault(unsigned long addr, struct pt_regs *regs)
-+static int
-+v3_pci_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
- {
- unsigned long pc = instruction_pointer(regs);
- unsigned long instr = *(unsigned long *)pc;
- #if 0
- char buf[128];
-
-- sprintf(buf, "V3 fault: address=0x%08lx, pc=0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n",
-- addr, pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255,
-+ sprintf(buf, "V3 fault: addr 0x%08lx, FSR 0x%03x, PC 0x%08lx [%08lx] LBFADDR=%08x LBFCODE=%02x ISTAT=%02x\n",
-+ addr, fsr, pc, instr, __raw_readl(SC_LBFADDR), __raw_readl(SC_LBFCODE) & 255,
- v3_readb(V3_LB_ISTAT));
- printk(KERN_DEBUG "%s", buf);
- printascii(buf);
-@@ -523,8 +524,6 @@
- #endif
- }
-
--extern int (*external_fault)(unsigned long addr, struct pt_regs *regs);
--
- /*
- * V3_LB_BASE? - local bus address
- * V3_LB_MAP? - pci bus address
-@@ -539,7 +538,10 @@
- /*
- * Hook in our fault handler for PCI errors
- */
-- external_fault = v3_fault;
-+ hook_fault_code(4, v3_pci_fault, SIGBUS, "external abort on linefetch");
-+ hook_fault_code(6, v3_pci_fault, SIGBUS, "external abort on linefetch");
-+ hook_fault_code(8, v3_pci_fault, SIGBUS, "external abort on non-linefetch");
-+ hook_fault_code(10, v3_pci_fault, SIGBUS, "external abort on non-linefetch");
-
- spin_lock_irqsave(&v3_lock, flags);
-
-@@ -629,7 +631,7 @@
- #if 0
- ret = request_irq(IRQ_LBUSTIMEOUT, lb_timeout, 0, "bus timeout", NULL);
- if (ret)
-- printk(KERN_ERR "PCI: unable to grab local bus timeout ".
-+ printk(KERN_ERR "PCI: unable to grab local bus timeout "
- "interrupt: %d\n", ret);
- #endif
- }
---- linux-2.4.25/arch/arm/mach-sa1100/pm.c~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/pm.c 2004-03-31 17:15:09.000000000 +0200
-@@ -21,6 +21,8 @@
- *
- * 2002-05-27: Nicolas Pitre Killed sleep.h and the kmalloced save array.
- * Storage is local on the stack now.
-+ * 2003-06-25: Jeff Corrall <jcorrall@mac.com>
-+ * Saved the GPIO levels for resume after sleep.
- */
- #include <linux/config.h>
- #include <linux/init.h>
-@@ -70,13 +72,20 @@
- int pm_do_suspend(void)
- {
- unsigned long sleep_save[SLEEP_SAVE_SIZE];
-+ unsigned long sleep_save_gpsr;
-+ unsigned long sleep_save_gpcr;
-+ unsigned long delta;
-
- cli();
-
- leds_event(led_stop);
-
- /* preserve current time */
-- RCNR = xtime.tv_sec;
-+ delta = xtime.tv_sec - RCNR;
-+
-+ /* save the current state of the GPIO output pins */
-+ sleep_save_gpsr = GPDR & GPLR;
-+ sleep_save_gpcr = GPDR & ~GPLR;
-
- /* save vital registers */
- SAVE(OSCR);
-@@ -121,6 +130,10 @@
- printk(KERN_DEBUG "*** made it back from resume\n");
- #endif
-
-+ /* restore GPIO output state before enabling the pins */
-+ GPSR = sleep_save_gpsr;
-+ GPCR = sleep_save_gpcr;
-+
- /* restore registers */
- RESTORE(GPDR);
- RESTORE(GRER);
-@@ -151,7 +164,7 @@
- RESTORE(ICMR);
-
- /* restore current time */
-- xtime.tv_sec = RCNR;
-+ xtime.tv_sec = RCNR + delta;
-
- leds_event(led_start);
-
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/sa1100_usb.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,193 @@
-+/*
-+ * sa1100_usb.h
-+ *
-+ * Public interface to the sa1100 USB core. For use by client modules
-+ * like usb-eth and usb-char.
-+ *
-+ */
-+
-+#ifndef _SA1100_USB_H
-+#define _SA1100_USB_H
-+#include <asm/byteorder.h>
-+
-+typedef void (*usb_callback_t)(int flag, int size);
-+
-+/* in usb_ctl.c (see also descriptor methods at bottom of file) */
-+
-+// Open the USB client for client and initialize data structures
-+// to default values, but _do not_ start UDC.
-+int sa1100_usb_open( const char * client_name );
-+
-+// Start UDC running
-+int sa1100_usb_start( void );
-+
-+// Immediately stop udc, fire off completion routines w/-EINTR
-+int sa1100_usb_stop( void ) ;
-+
-+// Disconnect client from usb core
-+int sa1100_usb_close( void ) ;
-+
-+// set notify callback for when core reaches configured state
-+// return previous pointer (if any)
-+typedef void (*usb_notify_t)(void);
-+usb_notify_t sa1100_set_configured_callback( usb_notify_t callback );
-+
-+/* in usb_send.c */
-+int sa1100_usb_xmitter_avail( void );
-+int sa1100_usb_send(char *buf, int len, usb_callback_t callback);
-+void sa1100_usb_send_reset(void);
-+
-+/* in usb_recev.c */
-+int sa1100_usb_recv(char *buf, int len, usb_callback_t callback);
-+void sa1100_usb_recv_reset(void);
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Descriptor Management
-+//////////////////////////////////////////////////////////////////////////////
-+
-+#define DescriptorHeader \
-+ __u8 bLength; \
-+ __u8 bDescriptorType
-+
-+
-+// --- Device Descriptor -------------------
-+
-+typedef struct {
-+ DescriptorHeader;
-+ __u16 bcdUSB; /* USB specification revision number in BCD */
-+ __u8 bDeviceClass; /* USB class for entire device */
-+ __u8 bDeviceSubClass; /* USB subclass information for entire device */
-+ __u8 bDeviceProtocol; /* USB protocol information for entire device */
-+ __u8 bMaxPacketSize0; /* Max packet size for endpoint zero */
-+ __u16 idVendor; /* USB vendor ID */
-+ __u16 idProduct; /* USB product ID */
-+ __u16 bcdDevice; /* vendor assigned device release number */
-+ __u8 iManufacturer; /* index of manufacturer string */
-+ __u8 iProduct; /* index of string that describes product */
-+ __u8 iSerialNumber; /* index of string containing device serial number */
-+ __u8 bNumConfigurations; /* number fo configurations */
-+} __attribute__ ((packed)) device_desc_t;
-+
-+// --- Configuration Descriptor ------------
-+
-+typedef struct {
-+ DescriptorHeader;
-+ __u16 wTotalLength; /* total # of bytes returned in the cfg buf 4 this cfg */
-+ __u8 bNumInterfaces; /* number of interfaces in this cfg */
-+ __u8 bConfigurationValue; /* used to uniquely ID this cfg */
-+ __u8 iConfiguration; /* index of string describing configuration */
-+ __u8 bmAttributes; /* bitmap of attributes for ths cfg */
-+ __u8 MaxPower; /* power draw in 2ma units */
-+} __attribute__ ((packed)) config_desc_t;
-+
-+// bmAttributes:
-+enum { USB_CONFIG_REMOTEWAKE=0x20, USB_CONFIG_SELFPOWERED=0x40,
-+ USB_CONFIG_BUSPOWERED=0x80 };
-+// MaxPower:
-+#define USB_POWER( x) ((x)>>1) /* convert mA to descriptor units of A for MaxPower */
-+
-+// --- Interface Descriptor ---------------
-+
-+typedef struct {
-+ DescriptorHeader;
-+ __u8 bInterfaceNumber; /* Index uniquely identfying this interface */
-+ __u8 bAlternateSetting; /* ids an alternate setting for this interface */
-+ __u8 bNumEndpoints; /* number of endpoints in this interface */
-+ __u8 bInterfaceClass; /* USB class info applying to this interface */
-+ __u8 bInterfaceSubClass; /* USB subclass info applying to this interface */
-+ __u8 bInterfaceProtocol; /* USB protocol info applying to this interface */
-+ __u8 iInterface; /* index of string describing interface */
-+} __attribute__ ((packed)) intf_desc_t;
-+
-+// --- Endpoint Descriptor ---------------
-+
-+typedef struct {
-+ DescriptorHeader;
-+ __u8 bEndpointAddress; /* 0..3 ep num, bit 7: 0 = 0ut 1= in */
-+ __u8 bmAttributes; /* 0..1 = 0: ctrl, 1: isoc, 2: bulk 3: intr */
-+ __u16 wMaxPacketSize; /* data payload size for this ep in this cfg */
-+ __u8 bInterval; /* polling interval for this ep in this cfg */
-+} __attribute__ ((packed)) ep_desc_t;
-+
-+// bEndpointAddress:
-+enum { USB_OUT= 0, USB_IN=1 };
-+#define USB_EP_ADDRESS(a,d) (((a)&0xf) | ((d) << 7))
-+// bmAttributes:
-+enum { USB_EP_CNTRL=0, USB_EP_BULK=2, USB_EP_INT=3 };
-+
-+// --- String Descriptor -------------------
-+
-+typedef struct {
-+ DescriptorHeader;
-+ __u16 bString[1]; /* unicode string .. actaully 'n' __u16s */
-+} __attribute__ ((packed)) string_desc_t;
-+
-+/*=======================================================
-+ * Handy helpers when working with above
-+ *
-+ */
-+// these are x86-style 16 bit "words" ...
-+#define make_word_c( w ) __constant_cpu_to_le16(w)
-+#define make_word( w ) __cpu_to_le16(w)
-+
-+// descriptor types
-+enum { USB_DESC_DEVICE=1, USB_DESC_CONFIG=2, USB_DESC_STRING=3,
-+ USB_DESC_INTERFACE=4, USB_DESC_ENDPOINT=5 };
-+
-+
-+/*=======================================================
-+ * Default descriptor layout for SA-1100 and SA-1110 UDC
-+ */
-+
-+/* "config descriptor buffer" - that is, one config,
-+ ..one interface and 2 endpoints */
-+struct cdb {
-+ config_desc_t cfg;
-+ intf_desc_t intf;
-+ ep_desc_t ep1;
-+ ep_desc_t ep2;
-+} __attribute__ ((packed));
-+
-+
-+/* all SA device descriptors */
-+typedef struct {
-+ device_desc_t dev; /* device descriptor */
-+ struct cdb b; /* bundle of descriptors for this cfg */
-+} __attribute__ ((packed)) desc_t;
-+
-+
-+/*=======================================================
-+ * Descriptor API
-+ */
-+
-+/* Get the address of the statically allocated desc_t structure
-+ in the usb core driver. Clients can modify this between
-+ the time they call sa1100_usb_open() and sa1100_usb_start()
-+*/
-+desc_t *
-+sa1100_usb_get_descriptor_ptr( void );
-+
-+
-+/* Set a pointer to the string descriptor at "index". The driver
-+ ..has room for 8 string indicies internally. Index zero holds
-+ ..a LANGID code and is set to US English by default. Inidices
-+ ..1-7 are available for use in the config descriptors as client's
-+ ..see fit. This pointer is assumed to be good as long as the
-+ ..SA usb core is open (so statically allocate them). Returnes -EINVAL
-+ ..if index out of range */
-+int sa1100_usb_set_string_descriptor( int index, string_desc_t * p );
-+
-+/* reverse of above */
-+string_desc_t *
-+sa1100_usb_get_string_descriptor( int index );
-+
-+/* kmalloc() a string descriptor and convert "p" to unicode in it */
-+string_desc_t *
-+sa1100_usb_kmalloc_string_descriptor( const char * p );
-+
-+
-+
-+
-+
-+
-+#endif /* _SA1100_USB_H */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/sa1111-ohci.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,140 @@
-+#include <linux/config.h>
-+#include <linux/sched.h>
-+#include <linux/pci.h>
-+#include <linux/mm.h>
-+
-+#ifdef CONFIG_USB_OHCI
-+
-+/*
-+ * The SA-1111 errata says that the DMA hardware needs to be exercised
-+ * before the clocks are turned on to work properly. This code does
-+ * a tiny dma transfer to prime to hardware.
-+ *
-+ * What DMA errata? I've checked October 1999 and February 2001, both
-+ * of which do not mention such a bug, let alone any details of this
-+ * work-around.
-+ */
-+static void __init sa1111_dma_setup(void)
-+{
-+ dma_addr_t dma_buf;
-+ void * vbuf;
-+
-+ /* DMA init & setup */
-+
-+ /* WARNING: The SA-1111 L3 function is used as part of this
-+ * SA-1111 DMA errata workaround.
-+ *
-+ * N.B., When the L3 function is enabled, it uses GPIO_B<4:5>
-+ * and takes precedence over the PS/2 mouse and GPIO_B
-+ * functions. Refer to "Intel StrongARM SA-1111 Microprocessor
-+ * Companion Chip, Sect 10.2" for details. So this "fix" may
-+ * "break" support of either PS/2 mouse or GPIO_B if
-+ * precautions are not taken to avoid collisions in
-+ * configuration and use of these pins. AFAIK, no precautions
-+ * are taken at this time. So it is likely that the action
-+ * taken here may cause problems in PS/2 mouse and/or GPIO_B
-+ * pin use elsewhere.
-+ *
-+ * But wait, there's more... What we're doing here is
-+ * obviously altogether a bad idea. We're indiscrimanately bit
-+ * flipping config for a few different functions here which
-+ * are "owned" by other drivers. This needs to be handled
-+ * better than it is being done here at this time. */
-+
-+ /* prime the dma engine with a tiny dma */
-+ SKPCR |= SKPCR_I2SCLKEN;
-+ SKAUD |= SKPCR_L3CLKEN | SKPCR_SCLKEN;
-+
-+ SACR0 |= 0x00003305;
-+ SACR1 = 0x00000000;
-+
-+ /*
-+ * We need memory below 1MB.
-+ * NOTE: consistent_alloc gives you some random virtual
-+ * address as its return value, and the DMA address via
-+ * the dma_addr_t pointer.
-+ */
-+ vbuf = consistent_alloc(GFP_KERNEL | GFP_DMA, 4, &dma_buf);
-+
-+ SADTSA = (unsigned long)dma_buf;
-+ SADTCA = 4;
-+
-+ SADTCS |= 0x00000011;
-+ SKPCR |= SKPCR_DCLKEN;
-+
-+ /* wait */
-+ udelay(100);
-+
-+ /* clear reserved but, then disable SAC */
-+ SACR0 &= ~(0x00000002);
-+ SACR0 &= ~(0x00000001);
-+
-+ /* toggle bit clock direction */
-+ SACR0 |= 0x00000004;
-+ SACR0 &= ~(0x00000004);
-+
-+ SKAUD &= ~(SKPCR_L3CLKEN | SKPCR_SCLKEN);
-+
-+ SKPCR &= ~SKPCR_I2SCLKEN;
-+
-+ consistent_free(vbuf, 4, dma_buf);
-+}
-+
-+/*
-+ * reset the SA-1111 usb controller and turn on it's clocks
-+ */
-+int __init sa1111_ohci_hcd_init(void)
-+{
-+ unsigned int usb_reset = 0;
-+
-+ if (machine_is_xp860() ||
-+ machine_has_neponset() ||
-+ machine_is_pfs168() ||
-+ machine_is_badge4())
-+ usb_reset = USB_RESET_PWRSENSELOW | USB_RESET_PWRCTRLLOW;
-+
-+ /*
-+ * turn on USB clocks
-+ */
-+ SKPCR |= SKPCR_UCLKEN;
-+ udelay(100);
-+
-+ /*
-+ * Force USB reset
-+ */
-+ USB_RESET = USB_RESET_FORCEIFRESET;
-+ USB_RESET |= USB_RESET_FORCEHCRESET;
-+ udelay(100);
-+
-+ /*
-+ * Take out of reset
-+ */
-+ USB_RESET = 0;
-+
-+ /*
-+ * set power sense and control lines (this from the diags code)
-+ */
-+ USB_RESET = usb_reset;
-+
-+ /*
-+ * Huh? This is a _read only_ register --rmk
-+ */
-+ USB_STATUS = 0;
-+
-+ udelay(10);
-+
-+ /*
-+ * compensate for dma bug
-+ */
-+ sa1111_dma_setup();
-+
-+ return 0;
-+}
-+
-+void sa1111_ohci_hcd_cleanup(void)
-+{
-+ /* turn the USB clock off */
-+ SKPCR &= ~SKPCR_UCLKEN;
-+}
-+
-+#endif /* CONFIG_USB_OHCI */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/usb-char.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,723 @@
-+/*
-+ * (C) Copyright 2000-2001 Extenex Corporation
-+ *
-+ * 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.
-+ *
-+ * usb-char.c
-+ *
-+ * Miscellaneous character device interface for SA1100 USB function
-+ * driver.
-+ *
-+ * Background:
-+ * The SA1100 function driver ported from the Compaq Itsy project
-+ * has an interface, usb-eth.c, to feed network packets over the
-+ * usb wire and into the Linux TCP/IP stack.
-+ *
-+ * This file replaces that one with a simple character device
-+ * interface that allows unstructured "byte pipe" style reads and
-+ * writes over the USB bulk endpoints by userspace programs.
-+ *
-+ * A new define, CONFIG_SA1100_USB_NETLINK, has been created that,
-+ * when set, (the default) causes the ethernet interface to be used.
-+ * When not set, this more pedestrian character interface is linked
-+ * in instead.
-+ *
-+ * Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
-+ *
-+ * ward.willats@extenex.com
-+ *
-+ * To do:
-+ * - Can't dma into ring buffer directly with pci_map/unmap usb_recv
-+ * uses and get bytes out at the same time DMA is going on. Investigate:
-+ * a) changing usb_recv to use alloc_consistent() at client request; or
-+ * b) non-ring-buffer based data structures. In the meantime, I am using
-+ * a bounce buffer. Simple, but wasteful.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/config.h>
-+#include <linux/miscdevice.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/cache.h>
-+#include <linux/poll.h>
-+#include <linux/circ_buf.h>
-+#include <linux/timer.h>
-+
-+#include <asm/io.h>
-+#include <asm/semaphore.h>
-+#include <asm/proc/page.h>
-+#include <asm/mach-types.h>
-+
-+#include "usb-char.h"
-+#include "sa1100_usb.h"
-+
-+
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Driver Options
-+//////////////////////////////////////////////////////////////////////////////
-+
-+#define VERSION "0.4"
-+
-+
-+#define VERBOSITY 1
-+
-+#if VERBOSITY
-+# define PRINTK(x, a...) printk (x, ## a)
-+#else
-+# define PRINTK(x, a...) /**/
-+#endif
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Globals - Macros - Enums - Structures
-+//////////////////////////////////////////////////////////////////////////////
-+#ifndef MIN
-+#define MIN( a, b ) ((a)<(b)?(a):(b))
-+#endif
-+
-+typedef int bool; enum { false = 0, true = 1 };
-+
-+static const char pszMe[] = "usbchr: ";
-+
-+static wait_queue_head_t wq_read;
-+static wait_queue_head_t wq_write;
-+static wait_queue_head_t wq_poll;
-+
-+/* Serialze multiple writers onto the transmit hardware
-+.. since we sleep the writer during transmit to stay in
-+.. sync. (Multiple writers don't make much sense, but..) */
-+static DECLARE_MUTEX( xmit_sem );
-+
-+// size of usb DATA0/1 packets. 64 is standard maximum
-+// for bulk transport, though most hosts seem to be able
-+// to handle larger.
-+#define TX_PACKET_SIZE 64
-+#define RX_PACKET_SIZE 64
-+#define RBUF_SIZE (4*PAGE_SIZE)
-+
-+static struct wcirc_buf {
-+ char *buf;
-+ int in;
-+ int out;
-+} rx_ring = { NULL, 0, 0 };
-+
-+static struct {
-+ unsigned long cnt_rx_complete;
-+ unsigned long cnt_rx_errors;
-+ unsigned long bytes_rx;
-+ unsigned long cnt_tx_timeouts;
-+ unsigned long cnt_tx_errors;
-+ unsigned long bytes_tx;
-+} charstats;
-+
-+
-+static char * tx_buf = NULL;
-+static char * packet_buffer = NULL;
-+static int sending = 0;
-+static int usb_ref_count = 0;
-+static int last_tx_result = 0;
-+static int last_rx_result = 0;
-+static int last_tx_size = 0;
-+static struct timer_list tx_timer;
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Prototypes
-+//////////////////////////////////////////////////////////////////////////////
-+static char * what_the_f( int e );
-+static void free_txrx_buffers( void );
-+static void twiddle_descriptors( void );
-+static void free_string_descriptors( void ) ;
-+static int usbc_open( struct inode *pInode, struct file *pFile );
-+static void rx_done_callback_packet_buffer( int flag, int size );
-+
-+static void tx_timeout( unsigned long );
-+static void tx_done_callback( int flag, int size );
-+
-+static ssize_t usbc_read( struct file *, char *, size_t, loff_t * );
-+static ssize_t usbc_write( struct file *, const char *, size_t, loff_t * );
-+static unsigned int usbc_poll( struct file *pFile, poll_table * pWait );
-+static int usbc_ioctl( struct inode *pInode, struct file *pFile,
-+ unsigned int nCmd, unsigned long argument );
-+static int usbc_close( struct inode *pInode, struct file *pFile );
-+
-+#ifdef CONFIG_SA1100_EXTENEX1
-+static void extenex_configured_notify_proc( void );
-+#endif
-+//////////////////////////////////////////////////////////////////////////////
-+// Private Helpers
-+//////////////////////////////////////////////////////////////////////////////
-+
-+static char * what_the_f( int e )
-+{
-+ char * p;
-+ switch( e ) {
-+ case 0:
-+ p = "noErr";
-+ break;
-+ case -ENODEV:
-+ p = "ENODEV - usb not in config state";
-+ break;
-+ case -EBUSY:
-+ p = "EBUSY - another request on the hardware";
-+ break;
-+ case -EAGAIN:
-+ p = "EAGAIN";
-+ break;
-+ case -EINTR:
-+ p = "EINTR - interrupted\n";
-+ break;
-+ case -EPIPE:
-+ p = "EPIPE - zero length xfer\n";
-+ break;
-+ default:
-+ p = "????";
-+ break;
-+ }
-+ return p;
-+}
-+
-+static void free_txrx_buffers( void )
-+{
-+ if ( rx_ring.buf != NULL ) {
-+ kfree( rx_ring.buf );
-+ rx_ring.buf = NULL;
-+ }
-+ if ( packet_buffer != NULL ) {
-+ kfree( packet_buffer );
-+ packet_buffer = NULL;
-+ }
-+ if ( tx_buf != NULL ) {
-+ kfree( tx_buf );
-+ tx_buf = NULL;
-+ }
-+}
-+
-+/* twiddle_descriptors()
-+ * It is between open() and start(). Setup descriptors.
-+ */
-+static void twiddle_descriptors( void )
-+{
-+ desc_t * pDesc = sa1100_usb_get_descriptor_ptr();
-+ string_desc_t * pString;
-+
-+ pDesc->b.ep1.wMaxPacketSize = make_word_c( RX_PACKET_SIZE );
-+ pDesc->b.ep1.bmAttributes = USB_EP_BULK;
-+ pDesc->b.ep2.wMaxPacketSize = make_word_c( TX_PACKET_SIZE );
-+ pDesc->b.ep2.bmAttributes = USB_EP_BULK;
-+
-+ if ( machine_is_extenex1() ) {
-+#ifdef CONFIG_SA1100_EXTENEX1
-+ pDesc->dev.idVendor = make_word_c( 0xC9F );
-+ pDesc->dev.idProduct = 1;
-+ pDesc->dev.bcdDevice = make_word_c( 0x0001 );
-+ pDesc->b.cfg.bmAttributes = USB_CONFIG_SELFPOWERED;
-+ pDesc->b.cfg.MaxPower = 0;
-+
-+ pString = sa1100_usb_kmalloc_string_descriptor( "Extenex" );
-+ if ( pString ) {
-+ sa1100_usb_set_string_descriptor( 1, pString );
-+ pDesc->dev.iManufacturer = 1;
-+ }
-+
-+ pString = sa1100_usb_kmalloc_string_descriptor( "Handheld Theater" );
-+ if ( pString ) {
-+ sa1100_usb_set_string_descriptor( 2, pString );
-+ pDesc->dev.iProduct = 2;
-+ }
-+
-+ pString = sa1100_usb_kmalloc_string_descriptor( "00000000" );
-+ if ( pString ) {
-+ sa1100_usb_set_string_descriptor( 3, pString );
-+ pDesc->dev.iSerialNumber = 3;
-+ }
-+
-+ pString = sa1100_usb_kmalloc_string_descriptor( "HHT Bulk Transfer" );
-+ if ( pString ) {
-+ sa1100_usb_set_string_descriptor( 4, pString );
-+ pDesc->b.intf.iInterface = 4;
-+ }
-+ sa1100_set_configured_callback( extenex_configured_notify_proc );
-+#endif
-+ }
-+}
-+
-+static void free_string_descriptors( void )
-+{
-+ if ( machine_is_extenex1() ) {
-+ string_desc_t * pString;
-+ int i;
-+ for( i = 1 ; i <= 4 ; i++ ) {
-+ pString = sa1100_usb_get_string_descriptor( i );
-+ if ( pString )
-+ kfree( pString );
-+ }
-+ }
-+}
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// ASYNCHRONOUS
-+//////////////////////////////////////////////////////////////////////////////
-+static void kick_start_rx( void )
-+{
-+ if ( usb_ref_count ) {
-+ int total_space = CIRC_SPACE( rx_ring.in, rx_ring.out, RBUF_SIZE );
-+ if ( total_space >= RX_PACKET_SIZE ) {
-+ sa1100_usb_recv( packet_buffer,
-+ RX_PACKET_SIZE,
-+ rx_done_callback_packet_buffer
-+ );
-+ }
-+ }
-+}
-+/*
-+ * rx_done_callback_packet_buffer()
-+ * We have completed a DMA xfer into the temp packet buffer.
-+ * Move to ring.
-+ *
-+ * flag values:
-+ * on init, -EAGAIN
-+ * on reset, -EINTR
-+ * on RPE, -EIO
-+ * on short packet -EPIPE
-+ */
-+static void
-+rx_done_callback_packet_buffer( int flag, int size )
-+{
-+ charstats.cnt_rx_complete++;
-+
-+ if ( flag == 0 || flag == -EPIPE ) {
-+ size_t n;
-+
-+ charstats.bytes_rx += size;
-+
-+ n = CIRC_SPACE_TO_END( rx_ring.in, rx_ring.out, RBUF_SIZE );
-+ n = MIN( n, size );
-+ size -= n;
-+
-+ memcpy( &rx_ring.buf[ rx_ring.in ], packet_buffer, n );
-+ rx_ring.in = (rx_ring.in + n) & (RBUF_SIZE-1);
-+ memcpy( &rx_ring.buf[ rx_ring.in ], packet_buffer + n, size );
-+ rx_ring.in = (rx_ring.in + size) & (RBUF_SIZE-1);
-+
-+ wake_up_interruptible( &wq_read );
-+ wake_up_interruptible( &wq_poll );
-+
-+ last_rx_result = 0;
-+
-+ kick_start_rx();
-+
-+ } else if ( flag != -EAGAIN ) {
-+ charstats.cnt_rx_errors++;
-+ last_rx_result = flag;
-+ wake_up_interruptible( &wq_read );
-+ wake_up_interruptible( &wq_poll );
-+ }
-+ else /* init, start a read */
-+ kick_start_rx();
-+}
-+
-+
-+static void tx_timeout( unsigned long unused )
-+{
-+ printk( "%stx timeout\n", pszMe );
-+ sa1100_usb_send_reset();
-+ charstats.cnt_tx_timeouts++;
-+}
-+
-+
-+// on init, -EAGAIN
-+// on reset, -EINTR
-+// on TPE, -EIO
-+static void tx_done_callback( int flags, int size )
-+{
-+ if ( flags == 0 )
-+ charstats.bytes_tx += size;
-+ else
-+ charstats.cnt_tx_errors++;
-+ last_tx_size = size;
-+ last_tx_result = flags;
-+ sending = 0;
-+ wake_up_interruptible( &wq_write );
-+ wake_up_interruptible( &wq_poll );
-+}
-+
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Workers
-+//////////////////////////////////////////////////////////////////////////////
-+
-+static int usbc_open( struct inode *pInode, struct file *pFile )
-+{
-+ int retval = 0;
-+
-+ PRINTK( KERN_DEBUG "%sopen()\n", pszMe );
-+
-+ /* start usb core */
-+ retval = sa1100_usb_open( "usb-char" );
-+ if ( retval ) return retval;
-+
-+ /* allocate memory */
-+ if ( usb_ref_count == 0 ) {
-+ tx_buf = (char*) kmalloc( TX_PACKET_SIZE, GFP_KERNEL | GFP_DMA );
-+ if ( tx_buf == NULL ) {
-+ printk( "%sARGHH! COULD NOT ALLOCATE TX BUFFER\n", pszMe );
-+ goto malloc_fail;
-+ }
-+ rx_ring.buf =
-+ (char*) kmalloc( RBUF_SIZE, GFP_KERNEL );
-+
-+ if ( rx_ring.buf == NULL ) {
-+ printk( "%sARGHH! COULD NOT ALLOCATE RX BUFFER\n", pszMe );
-+ goto malloc_fail;
-+ }
-+
-+ packet_buffer =
-+ (char*) kmalloc( RX_PACKET_SIZE, GFP_KERNEL | GFP_DMA );
-+
-+ if ( packet_buffer == NULL ) {
-+ printk( "%sARGHH! COULD NOT ALLOCATE RX PACKET BUFFER\n", pszMe );
-+ goto malloc_fail;
-+ }
-+ rx_ring.in = rx_ring.out = 0;
-+ memset( &charstats, 0, sizeof( charstats ) );
-+ sending = 0;
-+ last_tx_result = 0;
-+ last_tx_size = 0;
-+ }
-+
-+ /* modify default descriptors */
-+ twiddle_descriptors();
-+
-+ retval = sa1100_usb_start();
-+ if ( retval ) {
-+ printk( "%sAGHH! Could not USB core\n", pszMe );
-+ free_txrx_buffers();
-+ return retval;
-+ }
-+ usb_ref_count++; /* must do _before_ kick_start() */
-+ MOD_INC_USE_COUNT;
-+ kick_start_rx();
-+ return 0;
-+
-+ malloc_fail:
-+ free_txrx_buffers();
-+ return -ENOMEM;
-+}
-+
-+/*
-+ * Read endpoint. Note that you can issue a read to an
-+ * unconfigured endpoint. Eventually, the host may come along
-+ * and configure underneath this module and data will appear.
-+ */
-+static ssize_t usbc_read( struct file *pFile, char *pUserBuffer,
-+ size_t stCount, loff_t *pPos )
-+{
-+ ssize_t retval;
-+ int flags;
-+ DECLARE_WAITQUEUE( wait, current );
-+
-+ PRINTK( KERN_DEBUG "%sread()\n", pszMe );
-+
-+ local_irq_save( flags );
-+ if ( last_rx_result == 0 ) {
-+ local_irq_restore( flags );
-+ } else { /* an error happended and receiver is paused */
-+ local_irq_restore( flags );
-+ last_rx_result = 0;
-+ kick_start_rx();
-+ }
-+
-+ add_wait_queue( &wq_read, &wait );
-+ while( 1 ) {
-+ ssize_t bytes_avail;
-+ ssize_t bytes_to_end;
-+
-+ set_current_state( TASK_INTERRUPTIBLE );
-+
-+ /* snap ring buf state */
-+ local_irq_save( flags );
-+ bytes_avail = CIRC_CNT( rx_ring.in, rx_ring.out, RBUF_SIZE );
-+ bytes_to_end = CIRC_CNT_TO_END( rx_ring.in, rx_ring.out, RBUF_SIZE );
-+ local_irq_restore( flags );
-+
-+ if ( bytes_avail != 0 ) {
-+ ssize_t bytes_to_move = MIN( stCount, bytes_avail );
-+ retval = 0; // will be bytes transfered
-+ if ( bytes_to_move != 0 ) {
-+ size_t n = MIN( bytes_to_end, bytes_to_move );
-+ if ( copy_to_user( pUserBuffer,
-+ &rx_ring.buf[ rx_ring.out ],
-+ n ) ) {
-+ retval = -EFAULT;
-+ break;
-+ }
-+ bytes_to_move -= n;
-+ retval += n;
-+ // might go 1 char off end, so wrap
-+ rx_ring.out = ( rx_ring.out + n ) & (RBUF_SIZE-1);
-+ if ( copy_to_user( pUserBuffer + n,
-+ &rx_ring.buf[ rx_ring.out ],
-+ bytes_to_move )
-+ ) {
-+ retval = -EFAULT;
-+ break;
-+ }
-+ rx_ring.out += bytes_to_move; // cannot wrap
-+ retval += bytes_to_move;
-+ kick_start_rx();
-+ }
-+ break;
-+ }
-+ else if ( last_rx_result ) {
-+ retval = last_rx_result;
-+ break;
-+ }
-+ else if ( pFile->f_flags & O_NONBLOCK ) { // no data, can't sleep
-+ retval = -EAGAIN;
-+ break;
-+ }
-+ else if ( signal_pending( current ) ) { // no data, can sleep, but signal
-+ retval = -ERESTARTSYS;
-+ break;
-+ }
-+ schedule(); // no data, can sleep
-+ }
-+ set_current_state( TASK_RUNNING );
-+ remove_wait_queue( &wq_read, &wait );
-+
-+ if ( retval < 0 )
-+ printk( "%sread error %d - %s\n", pszMe, retval, what_the_f( retval ) );
-+ return retval;
-+}
-+
-+/*
-+ * Write endpoint. This routine attempts to break the passed in buffer
-+ * into usb DATA0/1 packet size chunks and send them to the host.
-+ * (The lower-level driver tries to do this too, but easier for us
-+ * to manage things here.)
-+ *
-+ * We are at the mercy of the host here, in that it must send an IN
-+ * token to us to pull this data back, so hopefully some higher level
-+ * protocol is expecting traffic to flow in that direction so the host
-+ * is actually polling us. To guard against hangs, a 5 second timeout
-+ * is used.
-+ *
-+ * This routine takes some care to only report bytes sent that have
-+ * actually made it across the wire. Thus we try to stay in lockstep
-+ * with the completion routine and only have one packet on the xmit
-+ * hardware at a time. Multiple simultaneous writers will get
-+ * "undefined" results.
-+ *
-+ */
-+static ssize_t usbc_write( struct file *pFile, const char * pUserBuffer,
-+ size_t stCount, loff_t *pPos )
-+{
-+ ssize_t retval = 0;
-+ ssize_t stSent = 0;
-+
-+ DECLARE_WAITQUEUE( wait, current );
-+
-+ PRINTK( KERN_DEBUG "%swrite() %d bytes\n", pszMe, stCount );
-+
-+ down( &xmit_sem ); // only one thread onto the hardware at a time
-+
-+ while( stCount != 0 && retval == 0 ) {
-+ int nThisTime = MIN( TX_PACKET_SIZE, stCount );
-+ copy_from_user( tx_buf, pUserBuffer, nThisTime );
-+ sending = nThisTime;
-+ retval = sa1100_usb_send( tx_buf, nThisTime, tx_done_callback );
-+ if ( retval < 0 ) {
-+ char * p = what_the_f( retval );
-+ printk( "%sCould not queue xmission. rc=%d - %s\n",
-+ pszMe, retval, p );
-+ sending = 0;
-+ break;
-+ }
-+ /* now have something on the diving board */
-+ add_wait_queue( &wq_write, &wait );
-+ tx_timer.expires = jiffies + ( HZ * 5 );
-+ add_timer( &tx_timer );
-+ while( 1 ) {
-+ set_current_state( TASK_INTERRUPTIBLE );
-+ if ( sending == 0 ) { /* it jumped into the pool */
-+ del_timer( &tx_timer );
-+ retval = last_tx_result;
-+ if ( retval == 0 ) {
-+ stSent += last_tx_size;
-+ pUserBuffer += last_tx_size;
-+ stCount -= last_tx_size;
-+ }
-+ else
-+ printk( "%sxmission error rc=%d - %s\n",
-+ pszMe, retval, what_the_f(retval) );
-+ break;
-+ }
-+ else if ( signal_pending( current ) ) {
-+ del_timer( &tx_timer );
-+ printk( "%ssignal\n", pszMe );
-+ retval = -ERESTARTSYS;
-+ break;
-+ }
-+ schedule();
-+ }
-+ set_current_state( TASK_RUNNING );
-+ remove_wait_queue( &wq_write, &wait );
-+ }
-+
-+ up( &xmit_sem );
-+
-+ if ( 0 == retval )
-+ retval = stSent;
-+ return retval;
-+}
-+
-+static unsigned int usbc_poll( struct file *pFile, poll_table * pWait )
-+{
-+ unsigned int retval = 0;
-+
-+ PRINTK( KERN_DEBUG "%poll()\n", pszMe );
-+
-+ poll_wait( pFile, &wq_poll, pWait );
-+
-+ if ( CIRC_CNT( rx_ring.in, rx_ring.out, RBUF_SIZE ) )
-+ retval |= POLLIN | POLLRDNORM;
-+ if ( sa1100_usb_xmitter_avail() )
-+ retval |= POLLOUT | POLLWRNORM;
-+ return retval;
-+}
-+
-+static int usbc_ioctl( struct inode *pInode, struct file *pFile,
-+ unsigned int nCmd, unsigned long argument )
-+{
-+ int retval = 0;
-+
-+ switch( nCmd ) {
-+
-+ case USBC_IOC_FLUSH_RECEIVER:
-+ sa1100_usb_recv_reset();
-+ rx_ring.in = rx_ring.out = 0;
-+ break;
-+
-+ case USBC_IOC_FLUSH_TRANSMITTER:
-+ sa1100_usb_send_reset();
-+ break;
-+
-+ case USBC_IOC_FLUSH_ALL:
-+ sa1100_usb_recv_reset();
-+ rx_ring.in = rx_ring.out = 0;
-+ sa1100_usb_send_reset();
-+ break;
-+
-+ default:
-+ retval = -ENOIOCTLCMD;
-+ break;
-+
-+ }
-+ return retval;
-+}
-+
-+
-+static int usbc_close( struct inode *pInode, struct file * pFile )
-+{
-+ PRINTK( KERN_DEBUG "%sclose()\n", pszMe );
-+ if ( --usb_ref_count == 0 ) {
-+ down( &xmit_sem );
-+ sa1100_usb_stop();
-+ free_txrx_buffers();
-+ free_string_descriptors();
-+ del_timer( &tx_timer );
-+ sa1100_usb_close();
-+ up( &xmit_sem );
-+ }
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+#ifdef CONFIG_SA1100_EXTENEX1
-+#include "../../../drivers/char/ex_gpio.h"
-+void extenex_configured_notify_proc( void )
-+{
-+ if ( exgpio_play_string( "440,1:698,1" ) == -EAGAIN )
-+ printk( "%sWanted to BEEP but ex_gpio not open\n", pszMe );
-+}
-+#endif
-+//////////////////////////////////////////////////////////////////////////////
-+// Initialization
-+//////////////////////////////////////////////////////////////////////////////
-+
-+static struct file_operations usbc_fops = {
-+ owner: THIS_MODULE,
-+ open: usbc_open,
-+ read: usbc_read,
-+ write: usbc_write,
-+ poll: usbc_poll,
-+ ioctl: usbc_ioctl,
-+ release: usbc_close,
-+};
-+
-+static struct miscdevice usbc_misc_device = {
-+ USBC_MINOR, "usb_char", &usbc_fops
-+};
-+
-+/*
-+ * usbc_init()
-+ */
-+
-+int __init usbc_init( void )
-+{
-+ int rc;
-+
-+#if !defined( CONFIG_ARCH_SA1100 )
-+ return -ENODEV;
-+#endif
-+
-+ if ( (rc = misc_register( &usbc_misc_device )) != 0 ) {
-+ printk( KERN_WARNING "%sCould not register device 10, "
-+ "%d. (%d)\n", pszMe, USBC_MINOR, rc );
-+ return -EBUSY;
-+ }
-+
-+ // initialize wait queues
-+ init_waitqueue_head( &wq_read );
-+ init_waitqueue_head( &wq_write );
-+ init_waitqueue_head( &wq_poll );
-+
-+ // initialize tx timeout timer
-+ init_timer( &tx_timer );
-+ tx_timer.function = tx_timeout;
-+
-+ printk( KERN_INFO "USB Function Character Driver Interface"
-+ " - %s, (C) 2001, Extenex Corp.\n", VERSION
-+ );
-+
-+ return rc;
-+}
-+
-+void __exit usbc_exit( void )
-+{
-+}
-+
-+EXPORT_NO_SYMBOLS;
-+
-+module_init(usbc_init);
-+module_exit(usbc_exit);
-+
-+
-+
-+// end: usb-char.c
-+
-+
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/usb-char.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,34 @@
-+/*
-+ * Copyright (C) 2001 Extenex Corporation
-+ *
-+ * usb-char.h
-+ *
-+ * Character device emulation client for SA-1100 client usb core.
-+ *
-+ *
-+ *
-+ */
-+#ifndef _USB_CHAR_H
-+#define _USB_CHAR_H
-+
-+#define USBC_MAJOR 10 /* miscellaneous character device */
-+#define USBC_MINOR 240 /* in the "reserved for local use" range */
-+
-+#define USBC_MAGIC 0x8E
-+
-+/* zap everything in receive ring buffer */
-+#define USBC_IOC_FLUSH_RECEIVER _IO( USBC_MAGIC, 0x01 )
-+
-+/* reset transmitter */
-+#define USBC_IOC_FLUSH_TRANSMITTER _IO( USBC_MAGIC, 0x02 )
-+
-+/* do both of above */
-+#define USBC_IOC_FLUSH_ALL _IO( USBC_MAGIC, 0x03 )
-+
-+
-+
-+
-+
-+
-+#endif /* _USB_CHAR_H */
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/usb-eth.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,447 @@
-+ /*
-+ * Ethernet driver for the SA1100 USB client function
-+ * Copyright (c) 2001 by Nicolas Pitre
-+ *
-+ * This code was loosely inspired by the original initial ethernet test driver
-+ * Copyright (c) Compaq Computer Corporation, 1999
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This is still work in progress...
-+ *
-+ * 19/02/2001 - Now we are compatible with generic usbnet driver. green@iXcelerator.com
-+ * 09/03/2001 - Dropped 'framing' scheme, as it seems to cause a lot of problems with little benefit.
-+ * Now, since we do not know what size of packet we are receiving
-+ * last usb packet in sequence will always be less than max packet
-+ * receive endpoint can accept.
-+ * Now the only way to check correct start of frame is to compare
-+ * MAC address. Also now we are stalling on each receive error.
-+ *
-+ * 15/03/2001 - Using buffer to get data from UDC. DMA needs to have 8 byte
-+ * aligned buffer, but this breaks IP code (unaligned access).
-+ *
-+ * 01/04/2001 - stall endpoint operations appeared to be very unstable, so
-+ * they are disabled now.
-+ *
-+ * 03/06/2001 - Readded "zerocopy" receive path (tunable).
-+ *
-+ */
-+
-+// Define DMA_NO_COPY if you want data to arrive directly into the
-+// receive network buffers, instead of arriving into bounce buffer
-+// and then get copied to network buffer.
-+// This does not work correctly right now.
-+#undef DMA_NO_COPY
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/timer.h>
-+
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/random.h>
-+
-+#include "sa1100_usb.h"
-+
-+
-+#define ETHERNET_VENDOR_ID 0x49f
-+#define ETHERNET_PRODUCT_ID 0x505A
-+#define MAX_PACKET 32768
-+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-+
-+// Should be global, so that insmod can change these
-+int usb_rsize=64;
-+int usb_wsize=64;
-+
-+static struct usbe_info_t {
-+ struct net_device *dev;
-+ u16 packet_id;
-+ struct net_device_stats stats;
-+} usbe_info;
-+
-+static char usb_eth_name[16] = "usbf";
-+static struct net_device usb_eth_device;
-+static struct sk_buff *cur_tx_skb, *next_tx_skb;
-+static struct sk_buff *cur_rx_skb, *next_rx_skb;
-+static volatile int terminating;
-+#ifndef DMA_NO_COPY
-+static char *dmabuf; // we need that, as dma expect it's buffers to be aligned on 8 bytes boundary
-+#endif
-+
-+static int usb_change_mtu (struct net_device *net, int new_mtu)
-+{
-+ if (new_mtu <= sizeof (struct ethhdr) || new_mtu > MAX_PACKET)
-+ return -EINVAL;
-+ // no second zero-length packet read wanted after mtu-sized packets
-+ if (((new_mtu + sizeof (struct ethhdr)) % usb_rsize) == 0)
-+ return -EDOM;
-+
-+ net->mtu = new_mtu;
-+ return 0;
-+}
-+
-+static struct sk_buff *
-+usb_new_recv_skb(void)
-+{
-+ struct sk_buff *skb = alloc_skb( 2 + sizeof (struct ethhdr) + usb_eth_device.mtu,GFP_ATOMIC);
-+
-+ if (skb) {
-+ skb_reserve(skb, 2);
-+ }
-+ return skb;
-+}
-+
-+static u8 bcast_hwaddr[ETH_ALEN]={0xff,0xff,0xff,0xff,0xff,0xff};
-+static void
-+usb_recv_callback(int flag, int size)
-+{
-+ struct sk_buff *skb;
-+
-+ if (terminating)
-+ return;
-+
-+ skb = cur_rx_skb;
-+
-+ /* flag validation */
-+ if (flag == 0) {
-+ if ( skb_tailroom (skb) < size ) { // hey! we are overloaded!!!
-+ usbe_info.stats.rx_over_errors++;
-+ goto error;
-+ }
-+#ifndef DMA_NO_COPY
-+ memcpy(skb->tail,dmabuf,size);
-+#endif
-+ skb_put(skb, size);
-+ } else {
-+ if (flag == -EIO) {
-+ usbe_info.stats.rx_errors++;
-+ }
-+ goto error;
-+ }
-+
-+ /* validate packet length */
-+ if (size == usb_rsize ) {
-+ /* packet not complete yet */
-+ skb = NULL;
-+ }
-+
-+ /*
-+ * At this point skb is non null if we have a complete packet.
-+ * If so take a fresh skb right away and restart USB receive without
-+ * further delays, then process the packet. Otherwise resume USB
-+ * receive on the current skb and exit.
-+ */
-+
-+ if (skb)
-+ cur_rx_skb = next_rx_skb;
-+#ifndef DMA_NO_COPY
-+ sa1100_usb_recv(dmabuf, usb_rsize,
-+ usb_recv_callback);
-+#else
-+ sa1100_usb_recv(cur_rx_skb->tail, MIN(usb_rsize, skb_tailroom (cur_rx_skb)),
-+ usb_recv_callback);
-+#endif
-+ if (!skb)
-+ return;
-+
-+ next_rx_skb = usb_new_recv_skb();
-+ if (!next_rx_skb) {
-+ /*
-+ * We can't aford loosing buffer space...
-+ * So we drop the current packet and recycle its skb.
-+ */
-+ printk("%s: can't allocate new skb\n", __FUNCTION__);
-+ usbe_info.stats.rx_dropped++;
-+ skb_trim(skb, 0);
-+ next_rx_skb = skb;
-+ return;
-+ }
-+ if ( skb->len >= sizeof(struct ethhdr)) {
-+ if (memcmp(skb->data,usb_eth_device.dev_addr,ETH_ALEN) && memcmp(skb->data,bcast_hwaddr,ETH_ALEN) ) {
-+ // This frame is not for us. nor it is broadcast
-+ usbe_info.stats.rx_frame_errors++;
-+ kfree_skb(skb);
-+ goto error;
-+ }
-+ }
-+
-+ if (skb->len) {
-+ int status;
-+// FIXME: eth_copy_and_csum "small" packets to new SKB (small < ~200 bytes) ?
-+
-+ skb->dev = &usb_eth_device;
-+ skb->protocol = eth_type_trans (skb, &usb_eth_device);
-+ usbe_info.stats.rx_packets++;
-+ usbe_info.stats.rx_bytes += skb->len;
-+ skb->ip_summed = CHECKSUM_NONE;
-+ status = netif_rx (skb);
-+ if (status != NET_RX_SUCCESS)
-+ printk("netif_rx failed with code %d\n",status);
-+ } else {
-+error:
-+ /*
-+ * Error due to HW addr mismatch, or IO error.
-+ * Recycle the current skb and reset USB reception.
-+ */
-+ skb_trim(cur_rx_skb, 0);
-+// if ( flag == -EINTR || flag == -EAGAIN ) // only if we are coming out of stall
-+#ifndef DMA_NO_COPY
-+ sa1100_usb_recv(dmabuf, usb_rsize, usb_recv_callback);
-+#else
-+ sa1100_usb_recv(cur_rx_skb->tail, MIN(usb_rsize, skb_tailroom (cur_rx_skb)), usb_recv_callback);
-+#endif
-+ }
-+}
-+
-+
-+static void
-+usb_send_callback(int flag, int size)
-+{
-+ struct net_device *dev = usbe_info.dev;
-+ struct net_device_stats *stats;
-+ struct sk_buff *skb=cur_tx_skb;
-+ int ret;
-+
-+ if (terminating)
-+ return;
-+
-+ stats = &usbe_info.stats;
-+ switch (flag) {
-+ case 0:
-+ stats->tx_packets++;
-+ stats->tx_bytes += size;
-+ break;
-+ case -EIO:
-+ stats->tx_errors++;
-+ break;
-+ default:
-+ stats->tx_dropped++;
-+ break;
-+ }
-+
-+ cur_tx_skb = next_tx_skb;
-+ next_tx_skb = NULL;
-+ dev_kfree_skb_irq(skb);
-+ if (!cur_tx_skb)
-+ return;
-+
-+ dev->trans_start = jiffies;
-+ ret = sa1100_usb_send(cur_tx_skb->data, cur_tx_skb->len, usb_send_callback);
-+ if (ret) {
-+ /* If the USB core can't accept the packet, we drop it. */
-+ dev_kfree_skb_irq(cur_tx_skb);
-+ cur_tx_skb = NULL;
-+ usbe_info.stats.tx_carrier_errors++;
-+ }
-+ netif_wake_queue(dev);
-+}
-+
-+static int
-+usb_eth_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+ int ret;
-+ unsigned long flags;
-+
-+ if (next_tx_skb) {
-+ printk("%s: called with next_tx_skb != NULL\n", __FUNCTION__);
-+ return 1;
-+ }
-+
-+ if (skb_shared (skb)) {
-+ struct sk_buff *skb2 = skb_unshare(skb, GFP_ATOMIC);
-+ if (!skb2) {
-+ usbe_info.stats.tx_dropped++;
-+ dev_kfree_skb(skb);
-+ return 1;
-+ }
-+ skb = skb2;
-+ }
-+
-+ if ((skb->len % usb_wsize) == 0) {
-+ skb->len++; // other side will ignore this one, anyway.
-+ }
-+
-+ local_irq_save(flags);
-+ if (cur_tx_skb) {
-+ next_tx_skb = skb;
-+ netif_stop_queue(dev);
-+ } else {
-+ cur_tx_skb = skb;
-+ dev->trans_start = jiffies;
-+ ret = sa1100_usb_send(skb->data, skb->len, usb_send_callback);
-+ if (ret) {
-+ /* If the USB core can't accept the packet, we drop it. */
-+ dev_kfree_skb(skb);
-+ cur_tx_skb = NULL;
-+ usbe_info.stats.tx_carrier_errors++;
-+ }
-+ }
-+ local_irq_restore(flags);
-+ return 0;
-+}
-+
-+static void
-+usb_xmit_timeout(struct net_device *dev )
-+{
-+ sa1100_usb_send_reset();
-+ dev->trans_start = jiffies;
-+ netif_wake_queue(dev);
-+}
-+
-+
-+static int
-+usb_eth_open(struct net_device *dev)
-+{
-+ terminating = 0;
-+ cur_tx_skb = next_tx_skb = NULL;
-+ cur_rx_skb = usb_new_recv_skb();
-+ next_rx_skb = usb_new_recv_skb();
-+ if (!cur_rx_skb || !next_rx_skb) {
-+ printk("%s: can't allocate new skb\n", __FUNCTION__);
-+ if (cur_rx_skb)
-+ kfree_skb(cur_rx_skb);
-+ if (next_rx_skb)
-+ kfree_skb(next_rx_skb);
-+ return -ENOMEM;;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+#ifndef DMA_NO_COPY
-+ sa1100_usb_recv(dmabuf, usb_rsize, usb_recv_callback);
-+#else
-+ sa1100_usb_recv(cur_rx_skb->tail, MIN(usb_rsize, skb_tailroom (cur_rx_skb)),
-+ usb_recv_callback);
-+#endif
-+ return 0;
-+}
-+
-+static int
-+usb_eth_release(struct net_device *dev)
-+{
-+ terminating = 1;
-+ sa1100_usb_send_reset();
-+ sa1100_usb_recv_reset();
-+ if (cur_tx_skb)
-+ kfree_skb(cur_tx_skb);
-+ if (next_tx_skb)
-+ kfree_skb(next_tx_skb);
-+ if (cur_rx_skb)
-+ kfree_skb(cur_rx_skb);
-+ if (next_rx_skb)
-+ kfree_skb(next_rx_skb);
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static struct net_device_stats *
-+usb_eth_stats(struct net_device *dev)
-+{
-+ struct usbe_info_t *priv = (struct usbe_info_t*) dev->priv;
-+ struct net_device_stats *stats=NULL;
-+
-+ if (priv)
-+ stats = &priv->stats;
-+ return stats;
-+}
-+
-+static int
-+usb_eth_probe(struct net_device *dev)
-+{
-+ u8 node_id [ETH_ALEN];
-+
-+ get_random_bytes (node_id, sizeof node_id);
-+ node_id [0] &= 0xfe; // clear multicast bit
-+
-+ /*
-+ * Assign the hardware address of the board:
-+ * generate it randomly, as there can be many such
-+ * devices on the bus.
-+ */
-+ memcpy (dev->dev_addr, node_id, sizeof node_id);
-+
-+ dev->open = usb_eth_open;
-+ dev->change_mtu = usb_change_mtu;
-+ dev->stop = usb_eth_release;
-+ dev->hard_start_xmit = usb_eth_xmit;
-+ dev->get_stats = usb_eth_stats;
-+ dev->watchdog_timeo = 1*HZ;
-+ dev->tx_timeout = usb_xmit_timeout;
-+ dev->priv = &usbe_info;
-+
-+ usbe_info.dev = dev;
-+
-+ /* clear the statistics */
-+ memset(&usbe_info.stats, 0, sizeof(struct net_device_stats));
-+
-+ ether_setup(dev);
-+ dev->flags &= ~IFF_MULTICAST;
-+ dev->flags &= ~IFF_BROADCAST;
-+ //dev->flags |= IFF_NOARP;
-+
-+ return 0;
-+}
-+
-+#ifdef MODULE
-+MODULE_PARM(usb_rsize, "1i");
-+MODULE_PARM_DESC(usb_rsize, "number of bytes in packets from host to sa1100");
-+MODULE_PARM(usb_wsize, "1i");
-+MODULE_PARM_DESC(usb_wsize, "number of bytes in packets from sa1100 to host");
-+#endif
-+
-+static int __init
-+usb_eth_init(void)
-+{
-+ int rc;
-+
-+#ifndef DMA_NO_COPY
-+ dmabuf = kmalloc( usb_rsize, GFP_KERNEL | GFP_DMA );
-+ if (!dmabuf)
-+ return -ENOMEM;
-+#endif
-+ strncpy(usb_eth_device.name, usb_eth_name, IFNAMSIZ);
-+ usb_eth_device.init = usb_eth_probe;
-+ if (register_netdev(&usb_eth_device) != 0)
-+ return -EIO;
-+
-+ rc = sa1100_usb_open( "usb-eth" );
-+ if ( rc == 0 ) {
-+ string_desc_t * pstr;
-+ desc_t * pd = sa1100_usb_get_descriptor_ptr();
-+
-+ pd->b.ep1.wMaxPacketSize = make_word( usb_rsize );
-+ pd->b.ep2.wMaxPacketSize = make_word( usb_wsize );
-+ pd->dev.idVendor = ETHERNET_VENDOR_ID;
-+ pd->dev.idProduct = ETHERNET_PRODUCT_ID;
-+ pstr = sa1100_usb_kmalloc_string_descriptor( "SA1100 USB NIC" );
-+ if ( pstr ) {
-+ sa1100_usb_set_string_descriptor( 1, pstr );
-+ pd->dev.iProduct = 1;
-+ }
-+ rc = sa1100_usb_start();
-+ }
-+ return rc;
-+}
-+
-+module_init(usb_eth_init);
-+
-+static void __exit
-+usb_eth_cleanup(void)
-+{
-+ string_desc_t * pstr;
-+ sa1100_usb_stop();
-+ sa1100_usb_close();
-+ if ( (pstr = sa1100_usb_get_string_descriptor(1)) != NULL )
-+ kfree( pstr );
-+#ifndef DMA_NO_COPY
-+ kfree(dmabuf);
-+#endif
-+ unregister_netdev(&usb_eth_device);
-+}
-+
-+module_exit(usb_eth_cleanup);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/usb_ctl.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,774 @@
-+ /*
-+ * Copyright (C) Compaq Computer Corporation, 1998, 1999
-+ * Copyright (C) Extenex Corporation, 2001
-+ *
-+ * usb_ctl.c
-+ *
-+ * SA1100 USB controller core driver.
-+ *
-+ * This file provides interrupt routing and overall coordination
-+ * of the three endpoints in usb_ep0, usb_receive (1), and usb_send (2).
-+ *
-+ * Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/tqueue.h>
-+#include <linux/delay.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <asm/io.h>
-+#include <asm/dma.h>
-+#include <asm/irq.h>
-+#include <asm/mach-types.h>
-+
-+#include "sa1100_usb.h"
-+#include "usb_ctl.h"
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Prototypes
-+//////////////////////////////////////////////////////////////////////////////
-+
-+int usbctl_next_state_on_event( int event );
-+static void udc_int_hndlr(int, void *, struct pt_regs *);
-+static void initialize_descriptors( void );
-+static void soft_connect_hook( int enable );
-+static void udc_disable(void);
-+static void udc_enable(void);
-+
-+#if CONFIG_PROC_FS
-+#define PROC_NODE_NAME "sausb"
-+static int usbctl_read_proc(char *page, char **start, off_t off,
-+ int count, int *eof, void *data);
-+#endif
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Globals
-+//////////////////////////////////////////////////////////////////////////////
-+static const char pszMe[] = "usbctl: ";
-+struct usb_info_t usbd_info; /* global to ep0, usb_recv, usb_send */
-+
-+/* device descriptors */
-+static desc_t desc;
-+
-+#define MAX_STRING_DESC 8
-+static string_desc_t * string_desc_array[ MAX_STRING_DESC ];
-+static string_desc_t sd_zero; /* special sd_zero holds language codes */
-+
-+// called when configured
-+static usb_notify_t configured_callback = NULL;
-+
-+enum { kStateZombie = 0, kStateZombieSuspend = 1,
-+ kStateDefault = 2, kStateDefaultSuspend = 3,
-+ kStateAddr = 4, kStateAddrSuspend = 5,
-+ kStateConfig = 6, kStateConfigSuspend = 7
-+};
-+
-+static int device_state_machine[8][6] = {
-+// suspend reset resume adddr config deconfig
-+/* zombie */ { kStateZombieSuspend, kStateDefault, kError, kError, kError, kError },
-+/* zom sus */ { kError, kStateDefault, kStateZombie, kError, kError, kError },
-+/* default */ { kStateDefaultSuspend, kError, kStateDefault, kStateAddr, kError, kError },
-+/* def sus */ { kError, kStateDefault, kStateDefault, kError, kError, kError },
-+/* addr */ { kStateAddrSuspend, kStateDefault, kError, kError, kStateConfig, kError },
-+/* addr sus */{ kError, kStateDefault, kStateAddr, kError, kError, kError },
-+/* config */ { kStateConfigSuspend, kStateDefault, kError, kError, kError, kStateAddr },
-+/* cfg sus */ { kError, kStateDefault, kStateConfig, kError, kError, kError }
-+};
-+
-+/* "device state" is the usb device framework state, as opposed to the
-+ "state machine state" which is whatever the driver needs and is much
-+ more fine grained
-+*/
-+static int sm_state_to_device_state[8] =
-+// zombie zom suspend default default sus
-+{ USB_STATE_POWERED, USB_STATE_SUSPENDED, USB_STATE_DEFAULT, USB_STATE_SUSPENDED,
-+// addr addr sus config config sus
-+ USB_STATE_ADDRESS, USB_STATE_SUSPENDED, USB_STATE_CONFIGURED, USB_STATE_SUSPENDED
-+};
-+
-+static char * state_names[8] =
-+{ "zombie", "zombie suspended", "default", "default suspended",
-+ "address", "address suspended", "configured", "config suspended"
-+};
-+
-+static char * event_names[6] =
-+{ "suspend", "reset", "resume",
-+ "address assigned", "configure", "de-configure"
-+};
-+
-+static char * device_state_names[] =
-+{ "not attached", "attached", "powered", "default",
-+ "address", "configured", "suspended" };
-+
-+static int sm_state = kStateZombie;
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Async
-+//////////////////////////////////////////////////////////////////////////////
-+static void core_kicker(void);
-+
-+static inline void enable_resume_mask_suspend( void );
-+static inline void enable_suspend_mask_resume(void);
-+
-+static void
-+udc_int_hndlr(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ __u32 status = Ser0UDCSR;
-+
-+ /* ReSeT Interrupt Request - UDC has been reset */
-+ if ( status & UDCSR_RSTIR )
-+ {
-+ if ( usbctl_next_state_on_event( kEvReset ) != kError )
-+ {
-+ /* starting 20ms or so reset sequence now... */
-+ printk("%sResetting\n", pszMe);
-+ ep0_reset(); // just set state to idle
-+ ep1_reset(); // flush dma, clear false stall
-+ ep2_reset(); // flush dma, clear false stall
-+ }
-+ // mask reset ints, they flood during sequence, enable
-+ // suspend and resume
-+ Ser0UDCCR |= UDCCR_REM; // mask reset
-+ Ser0UDCCR &= ~(UDCCR_SUSIM | UDCCR_RESIM); // enable suspend and resume
-+ UDC_flip( Ser0UDCSR, status ); // clear all pending sources
-+ return; // <-- no reason to continue if resetting
-+ }
-+ // else we have done something other than reset, so be sure reset enabled
-+ UDC_clear( Ser0UDCCR, UDCCR_REM );
-+
-+ /* RESume Interrupt Request */
-+ if ( status & UDCSR_RESIR )
-+ {
-+ usbctl_next_state_on_event( kEvResume );
-+ core_kicker();
-+ enable_suspend_mask_resume();
-+ }
-+
-+ /* SUSpend Interrupt Request */
-+ if ( status & UDCSR_SUSIR )
-+ {
-+ usbctl_next_state_on_event( kEvSuspend );
-+ enable_resume_mask_suspend();
-+ }
-+
-+ UDC_flip(Ser0UDCSR, status); // clear all pending sources
-+
-+ if (status & UDCSR_EIR)
-+ ep0_int_hndlr();
-+
-+ if (status & UDCSR_RIR)
-+ ep1_int_hndlr(status);
-+
-+ if (status & UDCSR_TIR)
-+ ep2_int_hndlr(status);
-+}
-+
-+static inline void enable_resume_mask_suspend( void )
-+{
-+ int i = 0;
-+
-+ while( 1 ) {
-+ Ser0UDCCR |= UDCCR_SUSIM; // mask future suspend events
-+ udelay( i );
-+ if ( (Ser0UDCCR & UDCCR_SUSIM) || (Ser0UDCSR & UDCSR_RSTIR) )
-+ break;
-+ if ( ++i == 50 ) {
-+ printk( "%senable_resume(): Could not set SUSIM %8.8X\n",
-+ pszMe, Ser0UDCCR );
-+ break;
-+ }
-+ }
-+
-+ i = 0;
-+ while( 1 ) {
-+ Ser0UDCCR &= ~UDCCR_RESIM;
-+ udelay( i );
-+ if ( ( Ser0UDCCR & UDCCR_RESIM ) == 0
-+ ||
-+ (Ser0UDCSR & UDCSR_RSTIR)
-+ )
-+ break;
-+ if ( ++i == 50 ) {
-+ printk( "%senable_resume(): Could not clear RESIM %8.8X\n",
-+ pszMe, Ser0UDCCR );
-+ break;
-+ }
-+ }
-+}
-+
-+static inline void enable_suspend_mask_resume(void)
-+{
-+ int i = 0;
-+ while( 1 ) {
-+ Ser0UDCCR |= UDCCR_RESIM; // mask future resume events
-+ udelay( i );
-+ if ( Ser0UDCCR & UDCCR_RESIM || (Ser0UDCSR & UDCSR_RSTIR) )
-+ break;
-+ if ( ++i == 50 ) {
-+ printk( "%senable_suspend(): Could not set RESIM %8.8X\n",
-+ pszMe, Ser0UDCCR );
-+ break;
-+ }
-+ }
-+ i = 0;
-+ while( 1 ) {
-+ Ser0UDCCR &= ~UDCCR_SUSIM;
-+ udelay( i );
-+ if ( ( Ser0UDCCR & UDCCR_SUSIM ) == 0
-+ ||
-+ (Ser0UDCSR & UDCSR_RSTIR)
-+ )
-+ break;
-+ if ( ++i == 50 ) {
-+ printk( "%senable_suspend(): Could not clear SUSIM %8.8X\n",
-+ pszMe, Ser0UDCCR );
-+ break;
-+ }
-+ }
-+}
-+
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Public Interface
-+//////////////////////////////////////////////////////////////////////////////
-+
-+/* Open SA usb core on behalf of a client, but don't start running */
-+
-+int
-+sa1100_usb_open( const char * client )
-+{
-+ if ( usbd_info.client_name != NULL )
-+ return -EBUSY;
-+
-+ usbd_info.client_name = (char*) client;
-+ memset(&usbd_info.stats, 0, sizeof(struct usb_stats_t));
-+ memset(string_desc_array, 0, sizeof(string_desc_array));
-+
-+ /* hack to start in zombie suspended state */
-+ sm_state = kStateZombieSuspend;
-+ usbd_info.state = USB_STATE_SUSPENDED;
-+
-+ /* create descriptors for enumeration */
-+ initialize_descriptors();
-+
-+ printk( "%sOpened for %s\n", pszMe, client );
-+ return 0;
-+}
-+
-+/* Start running. Must have called usb_open (above) first */
-+int
-+sa1100_usb_start( void )
-+{
-+ if ( usbd_info.client_name == NULL ) {
-+ printk( "%s%s - no client registered\n",
-+ pszMe, __FUNCTION__ );
-+ return -EPERM;
-+ }
-+
-+ /* start UDC internal machinery running */
-+ udc_enable();
-+ udelay( 100 );
-+
-+ /* clear stall - receiver seems to start stalled? 19Jan01ww */
-+ /* also clear other stuff just to be thurough 22Feb01ww */
-+ UDC_clear(Ser0UDCCS1, UDCCS1_FST | UDCCS1_RPE | UDCCS1_RPC );
-+ UDC_clear(Ser0UDCCS2, UDCCS2_FST | UDCCS2_TPE | UDCCS2_TPC );
-+
-+ /* mask everything */
-+ Ser0UDCCR = 0xFC;
-+
-+ /* flush DMA and fire through some -EAGAINs */
-+ ep1_init( usbd_info.dmach_rx );
-+ ep2_init( usbd_info.dmach_tx );
-+
-+ /* give endpoint notification we are starting */
-+ ep1_state_change_notify( USB_STATE_SUSPENDED );
-+ ep2_state_change_notify( USB_STATE_SUSPENDED );
-+
-+ /* enable any platform specific hardware */
-+ soft_connect_hook( 1 );
-+
-+ /* clear all top-level sources */
-+ Ser0UDCSR = UDCSR_RSTIR | UDCSR_RESIR | UDCSR_EIR |
-+ UDCSR_RIR | UDCSR_TIR | UDCSR_SUSIR ;
-+
-+ /* EXERIMENT - a short line in the spec says toggling this
-+ ..bit diddles the internal state machine in the udc to
-+ ..expect a suspend */
-+ Ser0UDCCR |= UDCCR_RESIM;
-+ /* END EXPERIMENT 10Feb01ww */
-+
-+ /* enable any platform specific hardware */
-+ soft_connect_hook( 1 );
-+
-+ /* enable interrupts. If you are unplugged you will
-+ immediately get a suspend interrupt. If you are plugged
-+ and have a soft connect-circuit, you will get a reset
-+ If you are plugged without a soft-connect, I think you
-+ also get suspend. In short, start with suspend masked
-+ and everything else enabled */
-+ UDC_write( Ser0UDCCR, UDCCR_SUSIM );
-+
-+ printk( "%sStarted for %s\n", pszMe, usbd_info.client_name );
-+ return 0;
-+}
-+
-+/* Stop USB core from running */
-+int
-+sa1100_usb_stop( void )
-+{
-+ if ( usbd_info.client_name == NULL ) {
-+ printk( "%s%s - no client registered\n",
-+ pszMe, __FUNCTION__ );
-+ return -EPERM;
-+ }
-+ /* mask everything */
-+ Ser0UDCCR = 0xFC;
-+ ep1_reset();
-+ ep2_reset();
-+ udc_disable();
-+ printk( "%sStopped\n", pszMe );
-+ return 0;
-+}
-+
-+/* Tell SA core client is through using it */
-+int
-+sa1100_usb_close( void )
-+{
-+ if ( usbd_info.client_name == NULL ) {
-+ printk( "%s%s - no client registered\n",
-+ pszMe, __FUNCTION__ );
-+ return -EPERM;
-+ }
-+ usbd_info.client_name = NULL;
-+ printk( "%sClosed\n", pszMe );
-+ return 0;
-+}
-+
-+/* set a proc to be called when device is configured */
-+usb_notify_t sa1100_set_configured_callback( usb_notify_t func )
-+{
-+ usb_notify_t retval = configured_callback;
-+ configured_callback = func;
-+ return retval;
-+}
-+
-+/*====================================================
-+ * Descriptor Manipulation.
-+ * Use these between open() and start() above to setup
-+ * the descriptors for your device.
-+ *
-+ */
-+
-+/* get pointer to static default descriptor */
-+desc_t *
-+sa1100_usb_get_descriptor_ptr( void ) { return &desc; }
-+
-+/* optional: set a string descriptor */
-+int
-+sa1100_usb_set_string_descriptor( int i, string_desc_t * p )
-+{
-+ int retval;
-+ if ( i < MAX_STRING_DESC ) {
-+ string_desc_array[i] = p;
-+ retval = 0;
-+ } else {
-+ retval = -EINVAL;
-+ }
-+ return retval;
-+}
-+
-+/* optional: get a previously set string descriptor */
-+string_desc_t *
-+sa1100_usb_get_string_descriptor( int i )
-+{
-+ return ( i < MAX_STRING_DESC )
-+ ? string_desc_array[i]
-+ : NULL;
-+}
-+
-+
-+/* optional: kmalloc and unicode up a string descriptor */
-+string_desc_t *
-+sa1100_usb_kmalloc_string_descriptor( const char * p )
-+{
-+ string_desc_t * pResult = NULL;
-+
-+ if ( p ) {
-+ int len = strlen( p );
-+ int uni_len = len * sizeof( __u16 );
-+ pResult = (string_desc_t*) kmalloc( uni_len + 2, GFP_KERNEL ); /* ugh! */
-+ if ( pResult != NULL ) {
-+ int i;
-+ pResult->bLength = uni_len + 2;
-+ pResult->bDescriptorType = USB_DESC_STRING;
-+ for( i = 0; i < len ; i++ ) {
-+ pResult->bString[i] = make_word( (__u16) p[i] );
-+ }
-+ }
-+ }
-+ return pResult;
-+}
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Exports to rest of driver
-+//////////////////////////////////////////////////////////////////////////////
-+
-+/* called by the int handler here and the two endpoint files when interesting
-+ .."events" happen */
-+
-+int
-+usbctl_next_state_on_event( int event )
-+{
-+ int next_state = device_state_machine[ sm_state ][ event ];
-+ if ( next_state != kError )
-+ {
-+ int next_device_state = sm_state_to_device_state[ next_state ];
-+ printk( "%s%s --> [%s] --> %s. Device in %s state.\n",
-+ pszMe, state_names[ sm_state ], event_names[ event ],
-+ state_names[ next_state ], device_state_names[ next_device_state ] );
-+
-+ sm_state = next_state;
-+ if ( usbd_info.state != next_device_state )
-+ {
-+ if ( configured_callback != NULL
-+ &&
-+ next_device_state == USB_STATE_CONFIGURED
-+ &&
-+ usbd_info.state != USB_STATE_SUSPENDED
-+ ) {
-+ configured_callback();
-+ }
-+ usbd_info.state = next_device_state;
-+ ep1_state_change_notify( next_device_state );
-+ ep2_state_change_notify( next_device_state );
-+ }
-+ }
-+#if 0
-+ else
-+ printk( "%s%s --> [%s] --> ??? is an error.\n",
-+ pszMe, state_names[ sm_state ], event_names[ event ] );
-+#endif
-+ return next_state;
-+}
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Private Helpers
-+//////////////////////////////////////////////////////////////////////////////
-+
-+/* setup default descriptors */
-+
-+static void
-+initialize_descriptors(void)
-+{
-+ desc.dev.bLength = sizeof( device_desc_t );
-+ desc.dev.bDescriptorType = USB_DESC_DEVICE;
-+ desc.dev.bcdUSB = 0x100; /* 1.0 */
-+ desc.dev.bDeviceClass = 0xFF; /* vendor specific */
-+ desc.dev.bDeviceSubClass = 0;
-+ desc.dev.bDeviceProtocol = 0;
-+ desc.dev.bMaxPacketSize0 = 8; /* ep0 max fifo size */
-+ desc.dev.idVendor = 0; /* vendor ID undefined */
-+ desc.dev.idProduct = 0; /* product */
-+ desc.dev.bcdDevice = 0; /* vendor assigned device release num */
-+ desc.dev.iManufacturer = 0; /* index of manufacturer string */
-+ desc.dev.iProduct = 0; /* index of product description string */
-+ desc.dev.iSerialNumber = 0; /* index of string holding product s/n */
-+ desc.dev.bNumConfigurations = 1;
-+
-+ desc.b.cfg.bLength = sizeof( config_desc_t );
-+ desc.b.cfg.bDescriptorType = USB_DESC_CONFIG;
-+ desc.b.cfg.wTotalLength = make_word_c( sizeof(struct cdb) );
-+ desc.b.cfg.bNumInterfaces = 1;
-+ desc.b.cfg.bConfigurationValue = 1;
-+ desc.b.cfg.iConfiguration = 0;
-+ desc.b.cfg.bmAttributes = USB_CONFIG_BUSPOWERED;
-+ desc.b.cfg.MaxPower = USB_POWER( 500 );
-+
-+ desc.b.intf.bLength = sizeof( intf_desc_t );
-+ desc.b.intf.bDescriptorType = USB_DESC_INTERFACE;
-+ desc.b.intf.bInterfaceNumber = 0; /* unique intf index*/
-+ desc.b.intf.bAlternateSetting = 0;
-+ desc.b.intf.bNumEndpoints = 2;
-+ desc.b.intf.bInterfaceClass = 0xFF; /* vendor specific */
-+ desc.b.intf.bInterfaceSubClass = 0;
-+ desc.b.intf.bInterfaceProtocol = 0;
-+ desc.b.intf.iInterface = 0;
-+
-+ desc.b.ep1.bLength = sizeof( ep_desc_t );
-+ desc.b.ep1.bDescriptorType = USB_DESC_ENDPOINT;
-+ desc.b.ep1.bEndpointAddress = USB_EP_ADDRESS( 1, USB_OUT );
-+ desc.b.ep1.bmAttributes = USB_EP_BULK;
-+ desc.b.ep1.wMaxPacketSize = make_word_c( 64 );
-+ desc.b.ep1.bInterval = 0;
-+
-+ desc.b.ep2.bLength = sizeof( ep_desc_t );
-+ desc.b.ep2.bDescriptorType = USB_DESC_ENDPOINT;
-+ desc.b.ep2.bEndpointAddress = USB_EP_ADDRESS( 2, USB_IN );
-+ desc.b.ep2.bmAttributes = USB_EP_BULK;
-+ desc.b.ep2.wMaxPacketSize = make_word_c( 64 );
-+ desc.b.ep2.bInterval = 0;
-+
-+ /* set language */
-+ /* See: http://www.usb.org/developers/data/USB_LANGIDs.pdf */
-+ sd_zero.bDescriptorType = USB_DESC_STRING;
-+ sd_zero.bLength = sizeof( string_desc_t );
-+ sd_zero.bString[0] = make_word_c( 0x409 ); /* American English */
-+ sa1100_usb_set_string_descriptor( 0, &sd_zero );
-+}
-+
-+/* soft_connect_hook()
-+ * Some devices have platform-specific circuitry to make USB
-+ * not seem to be plugged in, even when it is. This allows
-+ * software to control when a device 'appears' on the USB bus
-+ * (after Linux has booted and this driver has loaded, for
-+ * example). If you have such a circuit, control it here.
-+ */
-+static void
-+soft_connect_hook( int enable )
-+{
-+#ifdef CONFIG_SA1100_EXTENEX1
-+ if (machine_is_extenex1() ) {
-+ if ( enable ) {
-+ PPDR |= PPC_USB_SOFT_CON;
-+ PPSR |= PPC_USB_SOFT_CON;
-+ } else {
-+ PPSR &= ~PPC_USB_SOFT_CON;
-+ PPDR &= ~PPC_USB_SOFT_CON;
-+ }
-+ }
-+#endif
-+}
-+
-+/* disable the UDC at the source */
-+static void
-+udc_disable(void)
-+{
-+ soft_connect_hook( 0 );
-+ UDC_set( Ser0UDCCR, UDCCR_UDD );
-+}
-+
-+
-+/* enable the udc at the source */
-+static void
-+udc_enable(void)
-+{
-+ UDC_clear(Ser0UDCCR, UDCCR_UDD);
-+}
-+
-+// HACK DEBUG 3Mar01ww
-+// Well, maybe not, it really seems to help! 08Mar01ww
-+static void
-+core_kicker( void )
-+{
-+ __u32 car = Ser0UDCAR;
-+ __u32 imp = Ser0UDCIMP;
-+ __u32 omp = Ser0UDCOMP;
-+
-+ UDC_set( Ser0UDCCR, UDCCR_UDD );
-+ udelay( 300 );
-+ UDC_clear(Ser0UDCCR, UDCCR_UDD);
-+
-+ Ser0UDCAR = car;
-+ Ser0UDCIMP = imp;
-+ Ser0UDCOMP = omp;
-+}
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Proc Filesystem Support
-+//////////////////////////////////////////////////////////////////////////////
-+
-+#if CONFIG_PROC_FS
-+
-+#define SAY( fmt, args... ) p += sprintf(p, fmt, ## args )
-+#define SAYV( num ) p += sprintf(p, num_fmt, "Value", num )
-+#define SAYC( label, yn ) p += sprintf(p, yn_fmt, label, yn )
-+#define SAYS( label, v ) p += sprintf(p, cnt_fmt, label, v )
-+
-+static int usbctl_read_proc(char *page, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ const char * num_fmt = "%25.25s: %8.8lX\n";
-+ const char * cnt_fmt = "%25.25s: %lu\n";
-+ const char * yn_fmt = "%25.25s: %s\n";
-+ const char * yes = "YES";
-+ const char * no = "NO";
-+ unsigned long v;
-+ char * p = page;
-+ int len;
-+
-+ SAY( "SA1100 USB Controller Core\n" );
-+ SAY( "USB state: %s (%s) %d\n",
-+ device_state_names[ sm_state_to_device_state[ sm_state ] ],
-+ state_names[ sm_state ],
-+ sm_state );
-+
-+ SAYS( "ep0 bytes read", usbd_info.stats.ep0_bytes_read );
-+ SAYS( "ep0 bytes written", usbd_info.stats.ep0_bytes_written );
-+ SAYS( "ep0 FIFO read failures", usbd_info.stats.ep0_fifo_write_failures );
-+ SAYS( "ep0 FIFO write failures", usbd_info.stats.ep0_fifo_write_failures );
-+
-+ SAY( "\n" );
-+
-+ v = Ser0UDCAR;
-+ SAY( "%25.25s: 0x%8.8lX - %ld\n", "Address Register", v, v );
-+ v = Ser0UDCIMP;
-+ SAY( "%25.25s: %ld (%8.8lX)\n", "IN max packet size", v+1, v );
-+ v = Ser0UDCOMP;
-+ SAY( "%25.25s: %ld (%8.8lX)\n", "OUT max packet size", v+1, v );
-+
-+ v = Ser0UDCCR;
-+ SAY( "\nUDC Mask Register\n" );
-+ SAYV( v );
-+ SAYC( "UDC Active", ( v & UDCCR_UDA ) ? yes : no );
-+ SAYC( "Suspend interrupts masked", ( v & UDCCR_SUSIM ) ? yes : no );
-+ SAYC( "Resume interrupts masked", ( v & UDCCR_RESIM ) ? yes : no );
-+ SAYC( "Reset interrupts masked", ( v & UDCCR_REM ) ? yes : no );
-+
-+ v = Ser0UDCSR;
-+ SAY( "\nUDC Interrupt Request Register\n" );
-+ SAYV( v );
-+ SAYC( "Reset pending", ( v & UDCSR_RSTIR ) ? yes : no );
-+ SAYC( "Suspend pending", ( v & UDCSR_SUSIR ) ? yes : no );
-+ SAYC( "Resume pending", ( v & UDCSR_RESIR ) ? yes : no );
-+ SAYC( "ep0 pending", ( v & UDCSR_EIR ) ? yes : no );
-+ SAYC( "receiver pending", ( v & UDCSR_RIR ) ? yes : no );
-+ SAYC( "tramsitter pending", ( v & UDCSR_TIR ) ? yes : no );
-+
-+#ifdef CONFIG_SA1100_EXTENEX1
-+ SAYC( "\nSoft connect", (PPSR & PPC_USB_SOFT_CON) ? "Visible" : "Hidden" );
-+#endif
-+
-+#if 0
-+ v = Ser0UDCCS0;
-+ SAY( "\nUDC Endpoint Zero Status Register\n" );
-+ SAYV( v );
-+ SAYC( "Out Packet Ready", ( v & UDCCS0_OPR ) ? yes : no );
-+ SAYC( "In Packet Ready", ( v & UDCCS0_IPR ) ? yes : no );
-+ SAYC( "Sent Stall", ( v & UDCCS0_SST ) ? yes : no );
-+ SAYC( "Force Stall", ( v & UDCCS0_FST ) ? yes : no );
-+ SAYC( "Data End", ( v & UDCCS0_DE ) ? yes : no );
-+ SAYC( "Data Setup End", ( v & UDCCS0_SE ) ? yes : no );
-+ SAYC( "Serviced (SO)", ( v & UDCCS0_SO ) ? yes : no );
-+
-+ v = Ser0UDCCS1;
-+ SAY( "\nUDC Receiver Status Register\n" );
-+ SAYV( v );
-+ SAYC( "Receive Packet Complete", ( v & UDCCS1_RPC ) ? yes : no );
-+ SAYC( "Sent Stall", ( v & UDCCS1_SST ) ? yes : no );
-+ SAYC( "Force Stall", ( v & UDCCS1_FST ) ? yes : no );
-+ SAYC( "Receive Packet Error", ( v & UDCCS1_RPE ) ? yes : no );
-+ SAYC( "Receive FIFO not empty", ( v & UDCCS1_RNE ) ? yes : no );
-+
-+ v = Ser0UDCCS2;
-+ SAY( "\nUDC Transmitter Status Register\n" );
-+ SAYV( v );
-+ SAYC( "FIFO has < 8 of 16 chars", ( v & UDCCS2_TFS ) ? yes : no );
-+ SAYC( "Transmit Packet Complete", ( v & UDCCS2_TPC ) ? yes : no );
-+ SAYC( "Transmit FIFO underrun", ( v & UDCCS2_TUR ) ? yes : no );
-+ SAYC( "Transmit Packet Error", ( v & UDCCS2_TPE ) ? yes : no );
-+ SAYC( "Sent Stall", ( v & UDCCS2_SST ) ? yes : no );
-+ SAYC( "Force Stall", ( v & UDCCS2_FST ) ? yes : no );
-+#endif
-+
-+ len = ( p - page ) - off;
-+ if ( len < 0 )
-+ len = 0;
-+ *eof = ( len <=count ) ? 1 : 0;
-+ *start = page + off;
-+ return len;
-+}
-+
-+#endif /* CONFIG_PROC_FS */
-+
-+//////////////////////////////////////////////////////////////////////////////
-+// Module Initialization and Shutdown
-+//////////////////////////////////////////////////////////////////////////////
-+/*
-+ * usbctl_init()
-+ * Module load time. Allocate dma and interrupt resources. Setup /proc fs
-+ * entry. Leave UDC disabled.
-+ */
-+int __init usbctl_init( void )
-+{
-+ int retval = 0;
-+
-+ udc_disable();
-+
-+ memset( &usbd_info, 0, sizeof( usbd_info ) );
-+
-+#if CONFIG_PROC_FS
-+ create_proc_read_entry ( PROC_NODE_NAME, 0, NULL, usbctl_read_proc, NULL);
-+#endif
-+
-+ /* setup rx dma */
-+ retval = sa1100_request_dma(&usbd_info.dmach_rx, "USB receive", DMA_Ser0UDCRd);
-+ if (retval) {
-+ printk("%sunable to register for rx dma rc=%d\n", pszMe, retval );
-+ goto err_rx_dma;
-+ }
-+
-+ /* setup tx dma */
-+ retval = sa1100_request_dma(&usbd_info.dmach_tx, "USB transmit", DMA_Ser0UDCWr);
-+ if (retval) {
-+ printk("%sunable to register for tx dma rc=%d\n",pszMe,retval);
-+ goto err_tx_dma;
-+ }
-+
-+ /* now allocate the IRQ. */
-+ retval = request_irq(IRQ_Ser0UDC, udc_int_hndlr, SA_INTERRUPT,
-+ "SA USB core", NULL);
-+ if (retval) {
-+ printk("%sCouldn't request USB irq rc=%d\n",pszMe, retval);
-+ goto err_irq;
-+ }
-+
-+ printk( "SA1100 USB Controller Core Initialized\n");
-+ return 0;
-+
-+err_irq:
-+ sa1100_free_dma(usbd_info.dmach_tx);
-+ usbd_info.dmach_tx = 0;
-+err_tx_dma:
-+ sa1100_free_dma(usbd_info.dmach_rx);
-+ usbd_info.dmach_rx = 0;
-+err_rx_dma:
-+ return retval;
-+}
-+/*
-+ * usbctl_exit()
-+ * Release DMA and interrupt resources
-+ */
-+void __exit usbctl_exit( void )
-+{
-+ printk("Unloading SA1100 USB Controller\n");
-+
-+ udc_disable();
-+
-+#if CONFIG_PROC_FS
-+ remove_proc_entry ( PROC_NODE_NAME, NULL);
-+#endif
-+
-+ sa1100_free_dma(usbd_info.dmach_rx);
-+ sa1100_free_dma(usbd_info.dmach_tx);
-+ free_irq(IRQ_Ser0UDC, NULL);
-+}
-+
-+EXPORT_SYMBOL( sa1100_usb_open );
-+EXPORT_SYMBOL( sa1100_usb_start );
-+EXPORT_SYMBOL( sa1100_usb_stop );
-+EXPORT_SYMBOL( sa1100_usb_close );
-+
-+
-+EXPORT_SYMBOL( sa1100_usb_get_descriptor_ptr );
-+EXPORT_SYMBOL( sa1100_usb_set_string_descriptor );
-+EXPORT_SYMBOL( sa1100_usb_get_string_descriptor );
-+EXPORT_SYMBOL( sa1100_usb_kmalloc_string_descriptor );
-+
-+
-+module_init( usbctl_init );
-+module_exit( usbctl_exit );
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/usb_ctl.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,123 @@
-+/*
-+ * Copyright (C) Compaq Computer Corporation, 1998, 1999
-+ * Copyright (C) Extenex Corporation 2001
-+ *
-+ * usb_ctl.h
-+ *
-+ * PRIVATE interface used to share info among components of the SA-1100 USB
-+ * core: usb_ctl, usb_ep0, usb_recv and usb_send. Clients of the USB core
-+ * should use sa1100_usb.h.
-+ *
-+ */
-+
-+#ifndef _USB_CTL_H
-+#define _USB_CTL_H
-+
-+#include <asm/dma.h> /* dmach_t */
-+
-+
-+/*
-+ * These states correspond to those in the USB specification v1.0
-+ * in chapter 8, Device Framework.
-+ */
-+enum { USB_STATE_NOTATTACHED=0, USB_STATE_ATTACHED=1,USB_STATE_POWERED=2,
-+ USB_STATE_DEFAULT=3, USB_STATE_ADDRESS=4, USB_STATE_CONFIGURED=5,
-+ USB_STATE_SUSPENDED=6};
-+
-+struct usb_stats_t {
-+ unsigned long ep0_fifo_write_failures;
-+ unsigned long ep0_bytes_written;
-+ unsigned long ep0_fifo_read_failures;
-+ unsigned long ep0_bytes_read;
-+};
-+
-+struct usb_info_t
-+{
-+ char * client_name;
-+ dmach_t dmach_tx, dmach_rx;
-+ int state;
-+ unsigned char address;
-+ struct usb_stats_t stats;
-+};
-+
-+/* in usb_ctl.c */
-+extern struct usb_info_t usbd_info;
-+
-+/*
-+ * Function Prototypes
-+ */
-+enum { kError=-1, kEvSuspend=0, kEvReset=1,
-+ kEvResume=2, kEvAddress=3, kEvConfig=4, kEvDeConfig=5 };
-+int usbctl_next_state_on_event( int event );
-+
-+/* endpoint zero */
-+void ep0_reset(void);
-+void ep0_int_hndlr(void);
-+
-+/* receiver */
-+void ep1_state_change_notify( int new_state );
-+int ep1_recv(void);
-+int ep1_init(int chn);
-+void ep1_int_hndlr(int status);
-+void ep1_reset(void);
-+void ep1_stall(void);
-+
-+/* xmitter */
-+void ep2_state_change_notify( int new_state );
-+void ep2_reset(void);
-+int ep2_init(int chn);
-+void ep2_int_hndlr(int status);
-+void ep2_stall(void);
-+
-+#define UDC_write(reg, val) { \
-+ int i = 10000; \
-+ do { \
-+ (reg) = (val); \
-+ if (i-- <= 0) { \
-+ printk( "%s [%d]: write %#x to %p (%#x) failed\n", \
-+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
-+ break; \
-+ } \
-+ } while((reg) != (val)); \
-+}
-+
-+#define UDC_set(reg, val) { \
-+ int i = 10000; \
-+ do { \
-+ (reg) |= (val); \
-+ if (i-- <= 0) { \
-+ printk( "%s [%d]: set %#x of %p (%#x) failed\n", \
-+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
-+ break; \
-+ } \
-+ } while(!((reg) & (val))); \
-+}
-+
-+#define UDC_clear(reg, val) { \
-+ int i = 10000; \
-+ do { \
-+ (reg) &= ~(val); \
-+ if (i-- <= 0) { \
-+ printk( "%s [%d]: clear %#x of %p (%#x) failed\n", \
-+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
-+ break; \
-+ } \
-+ } while((reg) & (val)); \
-+}
-+
-+#define UDC_flip(reg, val) { \
-+ int i = 10000; \
-+ (reg) = (val); \
-+ do { \
-+ (reg) = (val); \
-+ if (i-- <= 0) { \
-+ printk( "%s [%d]: flip %#x of %p (%#x) failed\n", \
-+ __FUNCTION__, __LINE__, (val), &(reg), (reg)); \
-+ break; \
-+ } \
-+ } while(((reg) & (val))); \
-+}
-+
-+
-+#define CHECK_ADDRESS { if ( Ser0UDCAR == 1 ) { printk("%s:%d I lost my address!!!\n",__FUNCTION__, __LINE__);}}
-+#endif /* _USB_CTL_H */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/usb_ep0.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,911 @@
-+/*
-+ * Copyright (C) Extenex Corporation 2001
-+ * Much folklore gleaned from original code:
-+ * Copyright (C) Compaq Computer Corporation, 1998, 1999
-+ *
-+ * usb_ep0.c - SA1100 USB controller driver.
-+ * Endpoint zero management
-+ *
-+ * Please see:
-+ * linux/Documentation/arm/SA1100/SA1100_USB
-+ * for details. (Especially since Intel docs are full of
-+ * errors about ep0 operation.) ward.willats@extenex.com.
-+ *
-+ * Intel also has a "Universal Serial Bus Client Device
-+ * Validation for the StrongARM SA-1100 Microprocessor"
-+ * document, which has flow charts and assembler test driver,
-+ * but be careful, since it is just for validation and not
-+ * a "real world" solution.
-+ *
-+ * A summary of three types of data-returning setups:
-+ *
-+ * 1. Setup request <= 8 bytes. That is, requests that can
-+ * be fullfilled in one write to the FIFO. DE is set
-+ * with IPR in queue_and_start_write(). (I don't know
-+ * if there really are any of these!)
-+ *
-+ * 2. Setup requests > 8 bytes (requiring more than one
-+ * IN to get back to the host), and we have at least
-+ * as much or more data than the host requested. In
-+ * this case we pump out everything we've got, and
-+ * when the final interrupt comes in due to the UDC
-+ * clearing the last IPR, we just set DE.
-+ *
-+ * 3. Setup requests > 8 bytes, but we don't have enough
-+ * data to satisfy the request. In this case, we send
-+ * everything we've got, and when the final interrupt
-+ * comes in due to the UDC clearing the last IPR
-+ * we write nothing to the FIFO and set both IPR and DE
-+ * so the UDC sends an empty packet and forces the host
-+ * to perform short packet retirement instead of stalling
-+ * out.
-+ *
-+ */
-+
-+#include <linux/delay.h>
-+#include "sa1100_usb.h" /* public interface */
-+#include "usb_ctl.h" /* private stuff */
-+
-+
-+// 1 == lots of trace noise, 0 = only "important' stuff
-+#define VERBOSITY 0
-+
-+enum { true = 1, false = 0 };
-+typedef int bool;
-+#ifndef MIN
-+#define MIN( a, b ) ((a)<(b)?(a):(b))
-+#endif
-+
-+#if 1 && !defined( ASSERT )
-+# define ASSERT(expr) \
-+ if(!(expr)) { \
-+ printk( "Assertion failed! %s,%s,%s,line=%d\n",\
-+ #expr,__FILE__,__FUNCTION__,__LINE__); \
-+ }
-+#else
-+# define ASSERT(expr)
-+#endif
-+
-+#if VERBOSITY
-+#define PRINTKD(fmt, args...) printk( fmt , ## args)
-+#else
-+#define PRINTKD(fmt, args...)
-+#endif
-+
-+/*================================================
-+ * USB Protocol Stuff
-+ */
-+
-+/* Request Codes */
-+enum { GET_STATUS=0, CLEAR_FEATURE=1, SET_FEATURE=3,
-+ SET_ADDRESS=5, GET_DESCRIPTOR=6, SET_DESCRIPTOR=7,
-+ GET_CONFIGURATION=8, SET_CONFIGURATION=9, GET_INTERFACE=10,
-+ SET_INTERFACE=11 };
-+
-+
-+/* USB Device Requests */
-+typedef struct
-+{
-+ __u8 bmRequestType;
-+ __u8 bRequest;
-+ __u16 wValue;
-+ __u16 wIndex;
-+ __u16 wLength;
-+} usb_dev_request_t __attribute__ ((packed));
-+
-+/***************************************************************************
-+Prototypes
-+***************************************************************************/
-+/* "setup handlers" -- the main functions dispatched to by the
-+ .. isr. These represent the major "modes" of endpoint 0 operaton */
-+static void sh_setup_begin(void); /* setup begin (idle) */
-+static void sh_write( void ); /* writing data */
-+static void sh_write_with_empty_packet( void ); /* empty packet at end of xfer*/
-+/* called before both sh_write routines above */
-+static void common_write_preamble( void );
-+
-+/* other subroutines */
-+static __u32 queue_and_start_write( void * p, int req, int act );
-+static void write_fifo( void );
-+static int read_fifo( usb_dev_request_t * p );
-+static void get_descriptor( usb_dev_request_t * pReq );
-+
-+/* some voodo helpers 01Mar01ww */
-+static void set_cs_bits( __u32 set_bits );
-+static void set_de( void );
-+static void set_ipr( void );
-+static void set_ipr_and_de( void );
-+static bool clear_opr( void );
-+
-+/***************************************************************************
-+Inline Helpers
-+***************************************************************************/
-+
-+/* Data extraction from usb_request_t fields */
-+enum { kTargetDevice=0, kTargetInterface=1, kTargetEndpoint=2 };
-+static inline int request_target( __u8 b ) { return (int) ( b & 0x0F); }
-+
-+static inline int windex_to_ep_num( __u16 w ) { return (int) ( w & 0x000F); }
-+inline int type_code_from_request( __u8 by ) { return (( by >> 4 ) & 3); }
-+
-+/* following is hook for self-powered flag in GET_STATUS. Some devices
-+ .. might like to override and return real info */
-+static inline bool self_powered_hook( void ) { return true; }
-+
-+/* print string descriptor */
-+static inline void psdesc( string_desc_t * p )
-+{
-+ int i;
-+ int nchars = ( p->bLength - 2 ) / sizeof( __u16 );
-+ printk( "'" );
-+ for( i = 0 ; i < nchars ; i++ ) {
-+ printk( "%c", (char) p->bString[i] );
-+ }
-+ printk( "'\n" );
-+}
-+
-+
-+#if VERBOSITY
-+/* "pcs" == "print control status" */
-+static inline void pcs( void )
-+{
-+ __u32 foo = Ser0UDCCS0;
-+ printk( "%8.8X: %s %s %s %s\n",
-+ foo,
-+ foo & UDCCS0_SE ? "SE" : "",
-+ foo & UDCCS0_OPR ? "OPR" : "",
-+ foo & UDCCS0_IPR ? "IPR" : "",
-+ foo & UDCCS0_SST ? "SST" : ""
-+ );
-+}
-+static inline void preq( usb_dev_request_t * pReq )
-+{
-+ static char * tnames[] = { "dev", "intf", "ep", "oth" };
-+ static char * rnames[] = { "std", "class", "vendor", "???" };
-+ char * psz;
-+ switch( pReq->bRequest ) {
-+ case GET_STATUS: psz = "get stat"; break;
-+ case CLEAR_FEATURE: psz = "clr feat"; break;
-+ case SET_FEATURE: psz = "set feat"; break;
-+ case SET_ADDRESS: psz = "set addr"; break;
-+ case GET_DESCRIPTOR: psz = "get desc"; break;
-+ case SET_DESCRIPTOR: psz = "set desc"; break;
-+ case GET_CONFIGURATION: psz = "get cfg"; break;
-+ case SET_CONFIGURATION: psz = "set cfg"; break;
-+ case GET_INTERFACE: psz = "get intf"; break;
-+ case SET_INTERFACE: psz = "set intf"; break;
-+ default: psz = "unknown"; break;
-+ }
-+ printk( "- [%s: %s req to %s. dir=%s]\n", psz,
-+ rnames[ (pReq->bmRequestType >> 5) & 3 ],
-+ tnames[ pReq->bmRequestType & 3 ],
-+ ( pReq->bmRequestType & 0x80 ) ? "in" : "out" );
-+}
-+
-+#else
-+static inline void pcs( void ){}
-+static inline void preq( void ){}
-+#endif
-+
-+/***************************************************************************
-+Globals
-+***************************************************************************/
-+static const char pszMe[] = "usbep0: ";
-+
-+/* pointer to current setup handler */
-+static void (*current_handler)(void) = sh_setup_begin;
-+
-+/* global write struct to keep write
-+ ..state around across interrupts */
-+static struct {
-+ unsigned char *p;
-+ int bytes_left;
-+} wr;
-+
-+/***************************************************************************
-+Public Interface
-+***************************************************************************/
-+
-+/* reset received from HUB (or controller just went nuts and reset by itself!)
-+ so udc core has been reset, track this state here */
-+void
-+ep0_reset(void)
-+{
-+ /* reset state machine */
-+ current_handler = sh_setup_begin;
-+ wr.p = NULL;
-+ wr.bytes_left = 0;
-+ usbd_info.address=0;
-+}
-+
-+/* handle interrupt for endpoint zero */
-+void
-+ep0_int_hndlr( void )
-+{
-+ PRINTKD( "/\\(%d)\n", Ser0UDCAR );
-+ pcs();
-+
-+ /* if not in setup begin, we are returning data.
-+ execute a common preamble to both write handlers
-+ */
-+ if ( current_handler != sh_setup_begin )
-+ common_write_preamble();
-+
-+ (*current_handler)();
-+
-+ PRINTKD( "---\n" );
-+ pcs();
-+ PRINTKD( "\\/\n" );
-+}
-+
-+/***************************************************************************
-+Setup Handlers
-+***************************************************************************/
-+/*
-+ * sh_setup_begin()
-+ * This setup handler is the "idle" state of endpoint zero. It looks for OPR
-+ * (OUT packet ready) to see if a setup request has been been received from the
-+ * host. Requests without a return data phase are immediately handled. Otherwise,
-+ * in the case of GET_XXXX the handler may be set to one of the sh_write_xxxx
-+ * data pumpers if more than 8 bytes need to get back to the host.
-+ *
-+ */
-+static void
-+sh_setup_begin( void )
-+{
-+ unsigned char status_buf[2]; /* returned in GET_STATUS */
-+ usb_dev_request_t req;
-+ int request_type;
-+ int n;
-+ __u32 cs_bits;
-+ __u32 address;
-+ __u32 cs_reg_in = Ser0UDCCS0;
-+
-+ if (cs_reg_in & UDCCS0_SST) {
-+ PRINTKD( "%ssetup begin: sent stall. Continuing\n", pszMe );
-+ set_cs_bits( UDCCS0_SST );
-+ }
-+
-+ if ( cs_reg_in & UDCCS0_SE ) {
-+ PRINTKD( "%ssetup begin: Early term of setup. Continuing\n", pszMe );
-+ set_cs_bits( UDCCS0_SSE ); /* clear setup end */
-+ }
-+
-+ /* Be sure out packet ready, otherwise something is wrong */
-+ if ( (cs_reg_in & UDCCS0_OPR) == 0 ) {
-+ /* we can get here early...if so, we'll int again in a moment */
-+ PRINTKD( "%ssetup begin: no OUT packet available. Exiting\n", pszMe );
-+ goto sh_sb_end;
-+ }
-+
-+ /* read the setup request */
-+ n = read_fifo( &req );
-+ if ( n != sizeof( req ) ) {
-+ printk( "%ssetup begin: fifo READ ERROR wanted %d bytes got %d. "
-+ " Stalling out...\n",
-+ pszMe, sizeof( req ), n );
-+ /* force stall, serviced out */
-+ set_cs_bits( UDCCS0_FST | UDCCS0_SO );
-+ goto sh_sb_end;
-+ }
-+
-+ /* Is it a standard request? (not vendor or class request) */
-+ request_type = type_code_from_request( req.bmRequestType );
-+ if ( request_type != 0 ) {
-+ printk( "%ssetup begin: unsupported bmRequestType: %d ignored\n",
-+ pszMe, request_type );
-+ set_cs_bits( UDCCS0_DE | UDCCS0_SO );
-+ goto sh_sb_end;
-+ }
-+
-+#if VERBOSITY
-+ {
-+ unsigned char * pdb = (unsigned char *) &req;
-+ PRINTKD( "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X ",
-+ pdb[0], pdb[1], pdb[2], pdb[3], pdb[4], pdb[5], pdb[6], pdb[7]
-+ );
-+ preq( &req );
-+ }
-+#endif
-+
-+ /* Handle it */
-+ switch( req.bRequest ) {
-+
-+ /* This first bunch have no data phase */
-+
-+ case SET_ADDRESS:
-+ address = (__u32) (req.wValue & 0x7F);
-+ /* when SO and DE sent, UDC will enter status phase and ack,
-+ ..propagating new address to udc core. Next control transfer
-+ ..will be on the new address. You can't see the change in a
-+ ..read back of CAR until then. (about 250us later, on my box).
-+ ..The original Intel driver sets S0 and DE and code to check
-+ ..that address has propagated here. I tried this, but it
-+ ..would only work sometimes! The rest of the time it would
-+ ..never propagate and we'd spin forever. So now I just set
-+ ..it and pray...
-+ */
-+ Ser0UDCAR = address;
-+ usbd_info.address = address;
-+ usbctl_next_state_on_event( kEvAddress );
-+ set_cs_bits( UDCCS0_SO | UDCCS0_DE ); /* no data phase */
-+ printk( "%sI have been assigned address: %d\n", pszMe, address );
-+ break;
-+
-+
-+ case SET_CONFIGURATION:
-+ if ( req.wValue == 1 ) {
-+ /* configured */
-+ if (usbctl_next_state_on_event( kEvConfig ) != kError){
-+ /* (re)set the out and in max packet sizes */
-+ desc_t * pDesc = sa1100_usb_get_descriptor_ptr();
-+ __u32 out = __le16_to_cpu( pDesc->b.ep1.wMaxPacketSize );
-+ __u32 in = __le16_to_cpu( pDesc->b.ep2.wMaxPacketSize );
-+ Ser0UDCOMP = ( out - 1 );
-+ Ser0UDCIMP = ( in - 1 );
-+ printk( "%sConfigured (OMP=%8.8X IMP=%8.8X)\n", pszMe, out, in );
-+ }
-+ } else if ( req.wValue == 0 ) {
-+ /* de-configured */
-+ if (usbctl_next_state_on_event( kEvDeConfig ) != kError )
-+ printk( "%sDe-Configured\n", pszMe );
-+ } else {
-+ printk( "%ssetup phase: Unknown "
-+ "\"set configuration\" data %d\n",
-+ pszMe, req.wValue );
-+ }
-+ set_cs_bits( UDCCS0_SO | UDCCS0_DE ); /* no data phase */
-+ break;
-+
-+ case CLEAR_FEATURE:
-+ /* could check data length, direction...26Jan01ww */
-+ if ( req.wValue == 0 ) { /* clearing ENDPOINT_HALT/STALL */
-+ int ep = windex_to_ep_num( req.wIndex );
-+ if ( ep == 1 ) {
-+ printk( "%sclear feature \"endpoint halt\" "
-+ " on receiver\n", pszMe );
-+ ep1_reset();
-+ }
-+ else if ( ep == 2 ) {
-+ printk( "%sclear feature \"endpoint halt\" "
-+ "on xmitter\n", pszMe );
-+ ep2_reset();
-+ } else {
-+ printk( "%sclear feature \"endpoint halt\" "
-+ "on unsupported ep # %d\n",
-+ pszMe, ep );
-+ }
-+ } else {
-+ printk( "%sUnsupported feature selector (%d) "
-+ "in clear feature. Ignored.\n" ,
-+ pszMe, req.wValue );
-+ }
-+ set_cs_bits( UDCCS0_SO | UDCCS0_DE ); /* no data phase */
-+ break;
-+
-+ case SET_FEATURE:
-+ if ( req.wValue == 0 ) { /* setting ENDPOINT_HALT/STALL */
-+ int ep = windex_to_ep_num( req.wValue );
-+ if ( ep == 1 ) {
-+ printk( "%set feature \"endpoint halt\" "
-+ "on receiver\n", pszMe );
-+ ep1_stall();
-+ }
-+ else if ( ep == 2 ) {
-+ printk( "%sset feature \"endpoint halt\" "
-+ " on xmitter\n", pszMe );
-+ ep2_stall();
-+ } else {
-+ printk( "%sset feature \"endpoint halt\" "
-+ "on unsupported ep # %d\n",
-+ pszMe, ep );
-+ }
-+ }
-+ else {
-+ printk( "%sUnsupported feature selector "
-+ "(%d) in set feature\n",
-+ pszMe, req.wValue );
-+ }
-+ set_cs_bits( UDCCS0_SO | UDCCS0_DE ); /* no data phase */
-+ break;
-+
-+
-+ /* The rest have a data phase that writes back to the host */
-+ case GET_STATUS:
-+ /* return status bit flags */
-+ status_buf[0] = status_buf[1] = 0;
-+ n = request_target(req.bmRequestType);
-+ switch( n ) {
-+ case kTargetDevice:
-+ if ( self_powered_hook() )
-+ status_buf[0] |= 1;
-+ break;
-+ case kTargetInterface:
-+ break;
-+ case kTargetEndpoint:
-+ /* return stalled bit */
-+ n = windex_to_ep_num( req.wIndex );
-+ if ( n == 1 )
-+ status_buf[0] |= (Ser0UDCCS1 & UDCCS1_FST) >> 4;
-+ else if ( n == 2 )
-+ status_buf[0] |= (Ser0UDCCS2 & UDCCS2_FST) >> 5;
-+ else {
-+ printk( "%sUnknown endpoint (%d) "
-+ "in GET_STATUS\n", pszMe, n );
-+ }
-+ break;
-+ default:
-+ printk( "%sUnknown target (%d) in GET_STATUS\n",
-+ pszMe, n );
-+ /* fall thru */
-+ break;
-+ }
-+ cs_bits = queue_and_start_write( status_buf,
-+ req.wLength,
-+ sizeof( status_buf ) );
-+ set_cs_bits( cs_bits );
-+ break;
-+ case GET_DESCRIPTOR:
-+ get_descriptor( &req );
-+ break;
-+
-+ case GET_CONFIGURATION:
-+ status_buf[0] = (usbd_info.state == USB_STATE_CONFIGURED)
-+ ? 1
-+ : 0;
-+ cs_bits = queue_and_start_write( status_buf, req.wLength, 1 );
-+ set_cs_bits( cs_bits );
-+ break;
-+ case GET_INTERFACE:
-+ printk( "%sfixme: get interface not supported\n", pszMe );
-+ cs_bits = queue_and_start_write( NULL, req.wLength, 0 );
-+ set_cs_bits( cs_bits );
-+ break;
-+ case SET_INTERFACE:
-+ printk( "%sfixme: set interface not supported\n", pszMe );
-+ set_cs_bits( UDCCS0_DE | UDCCS0_SO );
-+ break;
-+ default :
-+ printk("%sunknown request 0x%x\n", pszMe, req.bRequest);
-+ break;
-+ } /* switch( bRequest ) */
-+
-+sh_sb_end:
-+ return;
-+
-+}
-+/*
-+ * common_wrtie_preamble()
-+ * Called before execution of sh_write() or sh_write_with_empty_packet()
-+ * Handles common abort conditions.
-+ *
-+ */
-+static void common_write_preamble( void )
-+{
-+ /* If "setup end" has been set, the usb controller has
-+ ..terminated a setup transaction before we set DE. This
-+ ..happens during enumeration with some hosts. For example,
-+ ..the host will ask for our device descriptor and specify
-+ ..a return of 64 bytes. When we hand back the first 8, the
-+ ..host will know our max packet size and turn around and
-+ ..issue a new setup immediately. This causes the UDC to auto-ack
-+ ..the new setup and set SE. We must then "unload" (process)
-+ ..the new setup, which is what will happen after this preamble
-+ ..is finished executing.
-+ */
-+ __u32 cs_reg_in = Ser0UDCCS0;
-+
-+ if ( cs_reg_in & UDCCS0_SE ) {
-+ PRINTKD( "%swrite_preamble(): Early termination of setup\n", pszMe );
-+ Ser0UDCCS0 = UDCCS0_SSE; /* clear setup end */
-+ current_handler = sh_setup_begin;
-+ }
-+
-+ if ( cs_reg_in & UDCCS0_SST ) {
-+ PRINTKD( "%swrite_preamble(): UDC sent stall\n", pszMe );
-+ Ser0UDCCS0 = UDCCS0_SST; /* clear setup end */
-+ current_handler = sh_setup_begin;
-+ }
-+
-+ if ( cs_reg_in & UDCCS0_OPR ) {
-+ PRINTKD( "%swrite_preamble(): see OPR. Stopping write to "
-+ "handle new SETUP\n", pszMe );
-+ /* very rarely, you can get OPR and leftover IPR. Try to clear */
-+ UDC_clear( Ser0UDCCS0, UDCCS0_IPR );
-+ current_handler = sh_setup_begin;
-+ }
-+}
-+
-+/*
-+ * sh_write()
-+ * This is the setup handler when we are in the data return phase of
-+ * a setup request and have as much (or more) data than the host
-+ * requested. If we enter this routine and bytes left is zero, the
-+ * last data packet has gone (int is because IPR was just cleared)
-+ * so we just set DE and reset. Otheriwse, we write another packet
-+ * and set IPR.
-+ */
-+static void sh_write()
-+{
-+ PRINTKD( "W\n" );
-+
-+ if ( Ser0UDCCS0 & UDCCS0_IPR ) {
-+ PRINTKD( "%ssh_write(): IPR set, exiting\n", pszMe );
-+ return;
-+ }
-+
-+ /* If bytes left is zero, we are coming in on the
-+ ..interrupt after the last packet went out. And
-+ ..we know we don't have to empty packet this transfer
-+ ..so just set DE and we are done */
-+
-+ if ( 0 == wr.bytes_left ) {
-+ /* that's it, so data end */
-+ set_de();
-+ wr.p = NULL; /* be anal */
-+ current_handler = sh_setup_begin;
-+ } else {
-+ /* Otherwise, more data to go */
-+ write_fifo();
-+ set_ipr();
-+ }
-+}
-+/*
-+ * sh_write_with_empty_packet()
-+ * This is the setup handler when we don't have enough data to
-+ * satisfy the host's request. After we send everything we've got
-+ * we must send an empty packet (by setting IPR and DE) so the
-+ * host can perform "short packet retirement" and not stall.
-+ *
-+ */
-+static void sh_write_with_empty_packet( void )
-+{
-+ __u32 cs_reg_out = 0;
-+ PRINTKD( "WE\n" );
-+
-+ if ( Ser0UDCCS0 & UDCCS0_IPR ) {
-+ PRINTKD( "%ssh_write(): IPR set, exiting\n", pszMe );
-+ return;
-+ }
-+
-+ /* If bytes left is zero, we are coming in on the
-+ ..interrupt after the last packet went out.
-+ ..we must do short packet suff, so set DE and IPR
-+ */
-+
-+ if ( 0 == wr.bytes_left ) {
-+ set_ipr_and_de();
-+ wr.p = NULL;
-+ current_handler = sh_setup_begin;
-+ PRINTKD( "%ssh_write empty() Sent empty packet \n", pszMe );
-+ } else {
-+ write_fifo(); /* send data */
-+ set_ipr(); /* flag a packet is ready */
-+ }
-+ Ser0UDCCS0 = cs_reg_out;
-+}
-+
-+/***************************************************************************
-+Other Private Subroutines
-+***************************************************************************/
-+/*
-+ * queue_and_start_write()
-+ * p == data to send
-+ * req == bytes host requested
-+ * act == bytes we actually have
-+ * Returns: bits to be flipped in ep0 control/status register
-+ *
-+ * Called from sh_setup_begin() to begin a data return phase. Sets up the
-+ * global "wr"-ite structure and load the outbound FIFO with data.
-+ * If can't send all the data, set appropriate handler for next interrupt.
-+ *
-+ */
-+static __u32 queue_and_start_write( void * in, int req, int act )
-+{
-+ __u32 cs_reg_bits = UDCCS0_IPR;
-+ unsigned char * p = (unsigned char*) in;
-+
-+ PRINTKD( "Qr=%d a=%d\n",req,act );
-+
-+ /* thou shalt not enter data phase until the serviced OUT is clear */
-+ if ( ! clear_opr() ) {
-+ printk( "%sSO did not clear OPR\n", pszMe );
-+ return ( UDCCS0_DE | UDCCS0_SO ) ;
-+ }
-+ wr.p = p;
-+ wr.bytes_left = MIN( act, req );
-+
-+ write_fifo();
-+
-+ if ( 0 == wr.bytes_left ) {
-+ cs_reg_bits |= UDCCS0_DE; /* out in 1 so data end */
-+ wr.p = NULL; /* be anal */
-+ }
-+ else if ( act < req ) /* we are going to short-change host */
-+ current_handler = sh_write_with_empty_packet; /* so need nul to not stall */
-+ else /* we have as much or more than requested */
-+ current_handler = sh_write;
-+
-+ return cs_reg_bits; /* note: IPR was set uncondtionally at start of routine */
-+}
-+/*
-+ * write_fifo()
-+ * Stick bytes in the 8 bytes endpoint zero FIFO.
-+ * This version uses a variety of tricks to make sure the bytes
-+ * are written correctly. 1. The count register is checked to
-+ * see if the byte went in, and the write is attempted again
-+ * if not. 2. An overall counter is used to break out so we
-+ * don't hang in those (rare) cases where the UDC reverses
-+ * direction of the FIFO underneath us without notification
-+ * (in response to host aborting a setup transaction early).
-+ *
-+ */
-+static void write_fifo( void )
-+{
-+ int bytes_this_time = MIN( wr.bytes_left, 8 );
-+ int bytes_written = 0;
-+ int i=0;
-+
-+ PRINTKD( "WF=%d: ", bytes_this_time );
-+
-+ while( bytes_this_time-- ) {
-+ PRINTKD( "%2.2X ", *wr.p );
-+ i = 0;
-+ do {
-+ Ser0UDCD0 = *wr.p;
-+ udelay( 20 ); /* voodo 28Feb01ww */
-+ i++;
-+ } while( Ser0UDCWC == bytes_written && i < 10 );
-+ if ( i == 50 ) {
-+ printk( "%swrite_fifo: write failure\n", pszMe );
-+ usbd_info.stats.ep0_fifo_write_failures++;
-+ }
-+
-+ wr.p++;
-+ bytes_written++;
-+ }
-+ wr.bytes_left -= bytes_written;
-+
-+ /* following propagation voodo so maybe caller writing IPR in
-+ ..a moment might actually get it to stick 28Feb01ww */
-+ udelay( 300 );
-+
-+ usbd_info.stats.ep0_bytes_written += bytes_written;
-+ PRINTKD( "L=%d WCR=%8.8X\n", wr.bytes_left, Ser0UDCWC );
-+}
-+/*
-+ * read_fifo()
-+ * Read 1-8 bytes out of FIFO and put in request.
-+ * Called to do the initial read of setup requests
-+ * from the host. Return number of bytes read.
-+ *
-+ * Like write fifo above, this driver uses multiple
-+ * reads checked agains the count register with an
-+ * overall timeout.
-+ *
-+ */
-+static int
-+read_fifo( usb_dev_request_t * request )
-+{
-+ int bytes_read = 0;
-+ int fifo_count;
-+ int i;
-+
-+ unsigned char * pOut = (unsigned char*) request;
-+
-+ fifo_count = ( Ser0UDCWC & 0xFF );
-+
-+ ASSERT( fifo_count <= 8 );
-+ PRINTKD( "RF=%d ", fifo_count );
-+
-+ while( fifo_count-- ) {
-+ i = 0;
-+ do {
-+ *pOut = (unsigned char) Ser0UDCD0;
-+ udelay( 10 );
-+ } while( ( Ser0UDCWC & 0xFF ) != fifo_count && i < 10 );
-+ if ( i == 10 ) {
-+ printk( "%sread_fifo(): read failure\n", pszMe );
-+ usbd_info.stats.ep0_fifo_read_failures++;
-+ }
-+ pOut++;
-+ bytes_read++;
-+ }
-+
-+ PRINTKD( "fc=%d\n", bytes_read );
-+ usbd_info.stats.ep0_bytes_read++;
-+ return bytes_read;
-+}
-+
-+/*
-+ * get_descriptor()
-+ * Called from sh_setup_begin to handle data return
-+ * for a GET_DESCRIPTOR setup request.
-+ */
-+static void get_descriptor( usb_dev_request_t * pReq )
-+{
-+ __u32 cs_bits = 0;
-+ string_desc_t * pString;
-+ ep_desc_t * pEndpoint;
-+
-+ desc_t * pDesc = sa1100_usb_get_descriptor_ptr();
-+ int type = pReq->wValue >> 8;
-+ int idx = pReq->wValue & 0xFF;
-+
-+ switch( type ) {
-+ case USB_DESC_DEVICE:
-+ cs_bits =
-+ queue_and_start_write( &pDesc->dev,
-+ pReq->wLength,
-+ pDesc->dev.bLength );
-+ break;
-+
-+ // return config descriptor buffer, cfg, intf, 2 ep
-+ case USB_DESC_CONFIG:
-+ cs_bits =
-+ queue_and_start_write( &pDesc->b,
-+ pReq->wLength,
-+ sizeof( struct cdb ) );
-+ break;
-+
-+ // not quite right, since doesn't do language code checking
-+ case USB_DESC_STRING:
-+ pString = sa1100_usb_get_string_descriptor( idx );
-+ if ( pString ) {
-+ if ( idx != 0 ) { // if not language index
-+ printk( "%sReturn string %d: ", pszMe, idx );
-+ psdesc( pString );
-+ }
-+ cs_bits =
-+ queue_and_start_write( pString,
-+ pReq->wLength,
-+ pString->bLength );
-+ }
-+ else {
-+ printk("%sunkown string index %d Stall.\n", pszMe, idx );
-+ cs_bits = ( UDCCS0_DE | UDCCS0_SO | UDCCS0_FST );
-+ }
-+ break;
-+
-+ case USB_DESC_INTERFACE:
-+ if ( idx == pDesc->b.intf.bInterfaceNumber ) {
-+ cs_bits =
-+ queue_and_start_write( &pDesc->b.intf,
-+ pReq->wLength,
-+ pDesc->b.intf.bLength );
-+ }
-+ break;
-+
-+ case USB_DESC_ENDPOINT: /* correct? 21Feb01ww */
-+ if ( idx == 1 )
-+ pEndpoint = &pDesc->b.ep1;
-+ else if ( idx == 2 )
-+ pEndpoint = &pDesc->b.ep2;
-+ else
-+ pEndpoint = NULL;
-+ if ( pEndpoint ) {
-+ cs_bits =
-+ queue_and_start_write( pEndpoint,
-+ pReq->wLength,
-+ pEndpoint->bLength );
-+ } else {
-+ printk("%sunkown endpoint index %d Stall.\n", pszMe, idx );
-+ cs_bits = ( UDCCS0_DE | UDCCS0_SO | UDCCS0_FST );
-+ }
-+ break;
-+
-+
-+ default :
-+ printk("%sunknown descriptor type %d. Stall.\n", pszMe, type );
-+ cs_bits = ( UDCCS0_DE | UDCCS0_SO | UDCCS0_FST );
-+ break;
-+
-+ }
-+ set_cs_bits( cs_bits );
-+}
-+
-+
-+/* some voodo I am adding, since the vanilla macros just aren't doing it 1Mar01ww */
-+
-+#define ABORT_BITS ( UDCCS0_SST | UDCCS0_SE )
-+#define OK_TO_WRITE (!( Ser0UDCCS0 & ABORT_BITS ))
-+#define BOTH_BITS (UDCCS0_IPR | UDCCS0_DE)
-+
-+static void set_cs_bits( __u32 bits )
-+{
-+ if ( bits & ( UDCCS0_SO | UDCCS0_SSE | UDCCS0_FST ) )
-+ Ser0UDCCS0 = bits;
-+ else if ( (bits & BOTH_BITS) == BOTH_BITS )
-+ set_ipr_and_de();
-+ else if ( bits & UDCCS0_IPR )
-+ set_ipr();
-+ else if ( bits & UDCCS0_DE )
-+ set_de();
-+}
-+
-+static void set_de( void )
-+{
-+ int i = 1;
-+ while( 1 ) {
-+ if ( OK_TO_WRITE ) {
-+ Ser0UDCCS0 |= UDCCS0_DE;
-+ } else {
-+ PRINTKD( "%sQuitting set DE because SST or SE set\n", pszMe );
-+ break;
-+ }
-+ if ( Ser0UDCCS0 & UDCCS0_DE )
-+ break;
-+ udelay( i );
-+ if ( ++i == 50 ) {
-+ printk( "%sDangnabbbit! Cannot set DE! (DE=%8.8X CCS0=%8.8X)\n",
-+ pszMe, UDCCS0_DE, Ser0UDCCS0 );
-+ break;
-+ }
-+ }
-+}
-+
-+static void set_ipr( void )
-+{
-+ int i = 1;
-+ while( 1 ) {
-+ if ( OK_TO_WRITE ) {
-+ Ser0UDCCS0 |= UDCCS0_IPR;
-+ } else {
-+ PRINTKD( "%sQuitting set IPR because SST or SE set\n", pszMe );
-+ break;
-+ }
-+ if ( Ser0UDCCS0 & UDCCS0_IPR )
-+ break;
-+ udelay( i );
-+ if ( ++i == 50 ) {
-+ printk( "%sDangnabbbit! Cannot set IPR! (IPR=%8.8X CCS0=%8.8X)\n",
-+ pszMe, UDCCS0_IPR, Ser0UDCCS0 );
-+ break;
-+ }
-+ }
-+}
-+
-+
-+
-+static void set_ipr_and_de( void )
-+{
-+ int i = 1;
-+ while( 1 ) {
-+ if ( OK_TO_WRITE ) {
-+ Ser0UDCCS0 |= BOTH_BITS;
-+ } else {
-+ PRINTKD( "%sQuitting set IPR/DE because SST or SE set\n", pszMe );
-+ break;
-+ }
-+ if ( (Ser0UDCCS0 & BOTH_BITS) == BOTH_BITS)
-+ break;
-+ udelay( i );
-+ if ( ++i == 50 ) {
-+ printk( "%sDangnabbbit! Cannot set DE/IPR! (DE=%8.8X IPR=%8.8X CCS0=%8.8X)\n",
-+ pszMe, UDCCS0_DE, UDCCS0_IPR, Ser0UDCCS0 );
-+ break;
-+ }
-+ }
-+}
-+
-+static bool clear_opr( void )
-+{
-+ int i = 10000;
-+ bool is_clear;
-+ do {
-+ Ser0UDCCS0 = UDCCS0_SO;
-+ is_clear = ! ( Ser0UDCCS0 & UDCCS0_OPR );
-+ if ( i-- <= 0 ) {
-+ printk( "%sclear_opr(): failed\n", pszMe );
-+ break;
-+ }
-+ } while( ! is_clear );
-+ return is_clear;
-+}
-+
-+
-+
-+
-+
-+/* end usb_ep0.c */
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/usb_recv.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,205 @@
-+/*
-+ * Generic receive layer for the SA1100 USB client function
-+ * Copyright (c) 2001 by Nicolas Pitre
-+ *
-+ * This code was loosely inspired by the original version which was
-+ * Copyright (c) Compaq Computer Corporation, 1998-1999
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This is still work in progress...
-+ *
-+ * Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+#include <linux/errno.h>
-+#include <asm/dma.h>
-+#include <asm/system.h>
-+
-+#include "sa1100_usb.h"
-+#include "usb_ctl.h"
-+
-+
-+static char *ep1_buf;
-+static int ep1_len;
-+static usb_callback_t ep1_callback;
-+static char *ep1_curdmabuf;
-+static dma_addr_t ep1_curdmapos;
-+static int ep1_curdmalen;
-+static int ep1_remain;
-+static int dmachn_rx;
-+static int rx_pktsize;
-+
-+static int naking;
-+
-+static void
-+ep1_start(void)
-+{
-+ sa1100_dma_flush_all(dmachn_rx);
-+ if (!ep1_curdmalen) {
-+ ep1_curdmalen = rx_pktsize;
-+ if (ep1_curdmalen > ep1_remain)
-+ ep1_curdmalen = ep1_remain;
-+ ep1_curdmapos = pci_map_single(NULL, ep1_curdmabuf, ep1_curdmalen,
-+ PCI_DMA_FROMDEVICE);
-+ }
-+ sa1100_dma_queue_buffer(dmachn_rx, NULL, ep1_curdmapos, ep1_curdmalen);
-+ if ( naking ) {
-+ /* turn off NAK of OUT packets, if set */
-+ UDC_flip( Ser0UDCCS1, UDCCS1_RPC );
-+ naking = 0;
-+ }
-+}
-+
-+static void
-+ep1_done(int flag)
-+{
-+ int size = ep1_len - ep1_remain;
-+
-+ if (!ep1_len)
-+ return;
-+ if (ep1_curdmalen)
-+ pci_unmap_single(NULL, ep1_curdmapos, ep1_curdmalen,
-+ PCI_DMA_FROMDEVICE);
-+ ep1_len = ep1_curdmalen = 0;
-+ if (ep1_callback) {
-+ ep1_callback(flag, size);
-+ }
-+}
-+
-+void
-+ep1_state_change_notify( int new_state )
-+{
-+
-+}
-+
-+void
-+ep1_stall( void )
-+{
-+ /* SET_FEATURE force stall at UDC */
-+ UDC_set( Ser0UDCCS1, UDCCS1_FST );
-+}
-+
-+int
-+ep1_init(int chn)
-+{
-+ desc_t * pd = sa1100_usb_get_descriptor_ptr();
-+ rx_pktsize = __le16_to_cpu( pd->b.ep1.wMaxPacketSize );
-+ dmachn_rx = chn;
-+ sa1100_dma_flush_all(dmachn_rx);
-+ ep1_done(-EAGAIN);
-+ return 0;
-+}
-+
-+void
-+ep1_reset(void)
-+{
-+ desc_t * pd = sa1100_usb_get_descriptor_ptr();
-+ rx_pktsize = __le16_to_cpu( pd->b.ep1.wMaxPacketSize );
-+ sa1100_dma_flush_all(dmachn_rx);
-+ UDC_clear(Ser0UDCCS1, UDCCS1_FST);
-+ ep1_done(-EINTR);
-+}
-+
-+void
-+ep1_int_hndlr(int udcsr)
-+{
-+ dma_addr_t dma_addr;
-+ unsigned int len;
-+ int status = Ser0UDCCS1;
-+
-+ if ( naking ) printk( "%sEh? in ISR but naking = %d\n", "usbrx: ", naking );
-+
-+ if (status & UDCCS1_RPC) {
-+
-+ if (!ep1_curdmalen) {
-+ printk("usb_recv: RPC for non-existent buffer\n");
-+ naking=1;
-+ return;
-+ }
-+
-+ sa1100_dma_stop(dmachn_rx);
-+
-+ if (status & UDCCS1_SST) {
-+ printk("usb_recv: stall sent OMP=%d\n",Ser0UDCOMP);
-+ UDC_flip(Ser0UDCCS1, UDCCS1_SST);
-+ ep1_done(-EIO); // UDC aborted current transfer, so we do
-+ return;
-+ }
-+
-+ if (status & UDCCS1_RPE) {
-+ printk("usb_recv: RPError %x\n", status);
-+ UDC_flip(Ser0UDCCS1, UDCCS1_RPC);
-+ ep1_done(-EIO);
-+ return;
-+ }
-+
-+ sa1100_dma_get_current(dmachn_rx, NULL, &dma_addr);
-+ pci_unmap_single(NULL, ep1_curdmapos, ep1_curdmalen,
-+ PCI_DMA_FROMDEVICE);
-+ len = dma_addr - ep1_curdmapos;
-+ if (len < ep1_curdmalen) {
-+ char *buf = ep1_curdmabuf + len;
-+ while (Ser0UDCCS1 & UDCCS1_RNE) {
-+ if (len >= ep1_curdmalen) {
-+ printk("usb_recv: too much data in fifo\n");
-+ break;
-+ }
-+ *buf++ = Ser0UDCDR;
-+ len++;
-+ }
-+ } else if (Ser0UDCCS1 & UDCCS1_RNE) {
-+ printk("usb_recv: fifo screwed, shouldn't contain data\n");
-+ len = 0;
-+ }
-+ ep1_curdmalen = 0; /* dma unmap already done */
-+ ep1_remain -= len;
-+ naking = 1;
-+ ep1_done((len) ? 0 : -EPIPE);
-+ }
-+ /* else, you can get here if we are holding NAK */
-+}
-+
-+int
-+sa1100_usb_recv(char *buf, int len, usb_callback_t callback)
-+{
-+ int flags;
-+
-+ if (ep1_len)
-+ return -EBUSY;
-+
-+ local_irq_save(flags);
-+ ep1_buf = buf;
-+ ep1_len = len;
-+ ep1_callback = callback;
-+ ep1_remain = len;
-+ ep1_curdmabuf = buf;
-+ ep1_curdmalen = 0;
-+ ep1_start();
-+ local_irq_restore(flags);
-+
-+ return 0;
-+}
-+
-+EXPORT_SYMBOL(sa1100_usb_recv);
-+
-+void
-+sa1100_usb_recv_reset(void)
-+{
-+ ep1_reset();
-+}
-+
-+EXPORT_SYMBOL(sa1100_usb_recv_reset);
-+
-+void
-+sa1100_usb_recv_stall(void)
-+{
-+ ep1_stall();
-+}
-+
-+EXPORT_SYMBOL(sa1100_usb_recv_stall);
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mach-sa1100/usb_send.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,205 @@
-+/*
-+ * Generic xmit layer for the SA1100 USB client function
-+ * Copyright (c) 2001 by Nicolas Pitre
-+ *
-+ * This code was loosely inspired by the original version which was
-+ * Copyright (c) Compaq Computer Corporation, 1998-1999
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This is still work in progress...
-+ *
-+ * Please see linux/Documentation/arm/SA1100/SA1100_USB for details.
-+ * 15/03/2001 - ep2_start now sets UDCAR to overcome something that is hardware
-+ * bug, I think. green@iXcelerator.com
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/pci.h>
-+#include <linux/errno.h>
-+#include <linux/delay.h> // for the massive_attack hack 28Feb01ww
-+#include <asm/hardware.h>
-+#include <asm/dma.h>
-+#include <asm/system.h>
-+#include <asm/byteorder.h>
-+
-+#include "sa1100_usb.h"
-+#include "usb_ctl.h"
-+
-+
-+static char *ep2_buf;
-+static int ep2_len;
-+static usb_callback_t ep2_callback;
-+static dma_addr_t ep2_dma;
-+static dma_addr_t ep2_curdmapos;
-+static int ep2_curdmalen;
-+static int ep2_remain;
-+static int dmachn_tx;
-+static int tx_pktsize;
-+
-+/* device state is changing, async */
-+void
-+ep2_state_change_notify( int new_state )
-+{
-+}
-+
-+/* set feature stall executing, async */
-+void
-+ep2_stall( void )
-+{
-+ UDC_set( Ser0UDCCS2, UDCCS2_FST ); /* force stall at UDC */
-+}
-+
-+static void
-+ep2_start(void)
-+{
-+ if (!ep2_len)
-+ return;
-+
-+ ep2_curdmalen = tx_pktsize;
-+ if (ep2_curdmalen > ep2_remain)
-+ ep2_curdmalen = ep2_remain;
-+
-+ /* must do this _before_ queue buffer.. */
-+ UDC_flip( Ser0UDCCS2,UDCCS2_TPC ); /* stop NAKing IN tokens */
-+ UDC_write( Ser0UDCIMP, ep2_curdmalen-1 );
-+
-+ /* Remove if never seen...8Mar01ww */
-+ {
-+ int massive_attack = 20;
-+ while ( Ser0UDCIMP != ep2_curdmalen-1 && massive_attack-- ) {
-+ printk( "usbsnd: Oh no you don't! Let me spin..." );
-+ udelay( 500 );
-+ printk( "and try again...\n" );
-+ UDC_write( Ser0UDCIMP, ep2_curdmalen-1 );
-+ }
-+ if ( massive_attack != 20 ) {
-+ if ( Ser0UDCIMP != ep2_curdmalen-1 )
-+ printk( "usbsnd: Massive attack FAILED :-( %d\n",
-+ 20 - massive_attack );
-+ else
-+ printk( "usbsnd: Massive attack WORKED :-) %d\n",
-+ 20 - massive_attack );
-+ }
-+ }
-+ /* End remove if never seen... 8Mar01ww */
-+
-+ Ser0UDCAR = usbd_info.address; // fighting stupid silicon bug
-+ sa1100_dma_queue_buffer(dmachn_tx, NULL, ep2_curdmapos, ep2_curdmalen);
-+}
-+
-+static void
-+ep2_done(int flag)
-+{
-+ int size = ep2_len - ep2_remain;
-+ if (ep2_len) {
-+ pci_unmap_single(NULL, ep2_dma, ep2_len, PCI_DMA_TODEVICE);
-+ ep2_len = 0;
-+ if (ep2_callback)
-+ ep2_callback(flag, size);
-+ }
-+}
-+
-+int
-+ep2_init(int chn)
-+{
-+ desc_t * pd = sa1100_usb_get_descriptor_ptr();
-+ tx_pktsize = __le16_to_cpu( pd->b.ep2.wMaxPacketSize );
-+ dmachn_tx = chn;
-+ sa1100_dma_flush_all(dmachn_tx);
-+ ep2_done(-EAGAIN);
-+ return 0;
-+}
-+
-+void
-+ep2_reset(void)
-+{
-+ desc_t * pd = sa1100_usb_get_descriptor_ptr();
-+ tx_pktsize = __le16_to_cpu( pd->b.ep2.wMaxPacketSize );
-+ UDC_clear(Ser0UDCCS2, UDCCS2_FST);
-+ sa1100_dma_flush_all(dmachn_tx);
-+ ep2_done(-EINTR);
-+}
-+
-+void
-+ep2_int_hndlr(int udcsr)
-+{
-+ int status = Ser0UDCCS2;
-+
-+ if (Ser0UDCAR != usbd_info.address) // check for stupid silicon bug.
-+ Ser0UDCAR = usbd_info.address;
-+
-+ UDC_flip(Ser0UDCCS2, UDCCS2_SST);
-+
-+ if (status & UDCCS2_TPC) {
-+ sa1100_dma_flush_all(dmachn_tx);
-+
-+ if (status & (UDCCS2_TPE | UDCCS2_TUR)) {
-+ printk("usb_send: transmit error %x\n", status);
-+ ep2_done(-EIO);
-+ } else {
-+#if 1 // 22Feb01ww/Oleg
-+ ep2_curdmapos += ep2_curdmalen;
-+ ep2_remain -= ep2_curdmalen;
-+#else
-+ ep2_curdmapos += Ser0UDCIMP + 1; // this is workaround
-+ ep2_remain -= Ser0UDCIMP + 1; // for case when setting of Ser0UDCIMP was failed
-+#endif
-+
-+ if (ep2_remain != 0) {
-+ ep2_start();
-+ } else {
-+ ep2_done(0);
-+ }
-+ }
-+ } else {
-+ printk("usb_send: Not TPC: UDCCS2 = %x\n", status);
-+ }
-+}
-+
-+int
-+sa1100_usb_send(char *buf, int len, usb_callback_t callback)
-+{
-+ int flags;
-+
-+ if (usbd_info.state != USB_STATE_CONFIGURED)
-+ return -ENODEV;
-+
-+ if (ep2_len)
-+ return -EBUSY;
-+
-+ local_irq_save(flags);
-+ ep2_buf = buf;
-+ ep2_len = len;
-+ ep2_dma = pci_map_single(NULL, buf, len, PCI_DMA_TODEVICE);
-+ ep2_callback = callback;
-+ ep2_remain = len;
-+ ep2_curdmapos = ep2_dma;
-+ ep2_start();
-+ local_irq_restore(flags);
-+
-+ return 0;
-+}
-+
-+
-+void
-+sa1100_usb_send_reset(void)
-+{
-+ ep2_reset();
-+}
-+
-+int sa1100_usb_xmitter_avail( void )
-+{
-+ if (usbd_info.state != USB_STATE_CONFIGURED)
-+ return -ENODEV;
-+ if (ep2_len)
-+ return -EBUSY;
-+ return 0;
-+}
-+
-+
-+EXPORT_SYMBOL(sa1100_usb_xmitter_avail);
-+EXPORT_SYMBOL(sa1100_usb_send);
-+EXPORT_SYMBOL(sa1100_usb_send_reset);
---- linux-2.4.25/arch/arm/mm/Makefile~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -39,6 +39,8 @@
- p-$(CONFIG_CPU_ARM925T) += proc-arm925.o
- p-$(CONFIG_CPU_ARM926T) += proc-arm926.o
- p-$(CONFIG_CPU_ARM1020) += proc-arm1020.o
-+p-$(CONFIG_CPU_ARM1020E) += proc-arm1020E.o
-+p-$(CONFIG_CPU_ARM1022) += proc-arm1022.o
- p-$(CONFIG_CPU_ARM1026) += proc-arm1026.o
- p-$(CONFIG_CPU_SA110) += proc-sa110.o
- p-$(CONFIG_CPU_SA1100) += proc-sa110.o
---- linux-2.4.25/arch/arm/mm/alignment.c~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/alignment.c 2004-03-31 17:15:09.000000000 +0200
-@@ -11,7 +11,6 @@
- #include <linux/config.h>
- #include <linux/compiler.h>
- #include <linux/signal.h>
--#include <linux/sched.h>
- #include <linux/kernel.h>
- #include <linux/errno.h>
- #include <linux/string.h>
-@@ -19,7 +18,6 @@
- #include <linux/ptrace.h>
- #include <linux/mman.h>
- #include <linux/mm.h>
--#include <linux/interrupt.h>
- #include <linux/proc_fs.h>
- #include <linux/bitops.h>
- #include <linux/init.h>
-@@ -30,9 +28,7 @@
- #include <asm/pgtable.h>
- #include <asm/unaligned.h>
-
--extern void
--do_bad_area(struct task_struct *tsk, struct mm_struct *mm, unsigned long addr,
-- int error_code, struct pt_regs *regs);
-+#include "fault.h"
-
- /*
- * 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998
-@@ -130,31 +126,6 @@
- return count;
- }
-
--/*
-- * This needs to be done after sysctl_init, otherwise sys/ will be
-- * overwritten. Actually, this shouldn't be in sys/ at all since
-- * it isn't a sysctl, and it doesn't contain sysctl information.
-- * We now locate it in /proc/cpu/alignment instead.
-- */
--static int __init alignment_init(void)
--{
-- struct proc_dir_entry *res;
--
-- res = proc_mkdir("cpu", NULL);
-- if (!res)
-- return -ENOMEM;
--
-- res = create_proc_entry("alignment", S_IWUSR | S_IRUGO, res);
-- if (!res)
-- return -ENOMEM;
--
-- res->read_proc = proc_alignment_read;
-- res->write_proc = proc_alignment_write;
--
-- return 0;
--}
--
--__initcall(alignment_init);
- #endif /* CONFIG_PROC_FS */
-
- union offset_union {
-@@ -429,7 +400,7 @@
- * For alignment faults on the ARM922T/ARM920T the MMU makes
- * the FSR (and hence addr) equal to the updated base address
- * of the multiple access rather than the restored value.
-- * Switch this messsage off if we've got a ARM92[02], otherwise
-+ * Switch this message off if we've got a ARM92[02], otherwise
- * [ls]dm alignment faults are noisy!
- */
- #if !(defined CONFIG_CPU_ARM922T) && !(defined CONFIG_CPU_ARM920T)
-@@ -486,7 +457,8 @@
- return TYPE_ERROR;
- }
-
--int do_alignment(unsigned long addr, int error_code, struct pt_regs *regs)
-+static int
-+do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
- {
- union offset_union offset;
- unsigned long instr, instrptr;
-@@ -541,7 +513,7 @@
- case SHIFT_RORRRX:
- if (shiftval == 0) {
- offset.un >>= 1;
-- if (regs->ARM_cpsr & CC_C_BIT)
-+ if (regs->ARM_cpsr & PSR_C_BIT)
- offset.un |= 1 << 31;
- } else
- offset.un = offset.un >> shiftval |
-@@ -577,7 +549,7 @@
- /*
- * We got a fault - fix it up, or die.
- */
-- do_bad_area(current, current->mm, addr, error_code, regs);
-+ do_bad_area(current, current->mm, addr, fsr, regs);
- return 0;
-
- bad:
-@@ -594,8 +566,8 @@
-
- if (ai_usermode & 1)
- printk("Alignment trap: %s (%d) PC=0x%08lx Instr=0x%08lx "
-- "Address=0x%08lx Code 0x%02x\n", current->comm,
-- current->pid, instrptr, instr, addr, error_code);
-+ "Address=0x%08lx FSR 0x%03x\n", current->comm,
-+ current->pid, instrptr, instr, addr, fsr);
-
- if (ai_usermode & 2)
- goto fixup;
-@@ -607,3 +579,34 @@
-
- return 0;
- }
-+
-+/*
-+ * This needs to be done after sysctl_init, otherwise sys/ will be
-+ * overwritten. Actually, this shouldn't be in sys/ at all since
-+ * it isn't a sysctl, and it doesn't contain sysctl information.
-+ * We now locate it in /proc/cpu/alignment instead.
-+ */
-+static int __init alignment_init(void)
-+{
-+#ifdef CONFIG_PROC_FS
-+ struct proc_dir_entry *res;
-+
-+ res = proc_mkdir("cpu", NULL);
-+ if (!res)
-+ return -ENOMEM;
-+
-+ res = create_proc_entry("alignment", S_IWUSR | S_IRUGO, res);
-+ if (!res)
-+ return -ENOMEM;
-+
-+ res->read_proc = proc_alignment_read;
-+ res->write_proc = proc_alignment_write;
-+#endif
-+
-+ hook_fault_code(1, do_alignment, SIGILL, "alignment exception");
-+ hook_fault_code(3, do_alignment, SIGILL, "alignment exception");
-+
-+ return 0;
-+}
-+
-+__initcall(alignment_init);
---- linux-2.4.25/arch/arm/mm/fault-armv.c~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/fault-armv.c 2004-03-31 17:15:09.000000000 +0200
-@@ -2,116 +2,90 @@
- * linux/arch/arm/mm/fault-armv.c
- *
- * Copyright (C) 1995 Linus Torvalds
-- * Modifications for ARM processor (c) 1995-2001 Russell King
-+ * Modifications for ARM processor (c) 1995-2003 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
--#include <linux/config.h>
--#include <linux/signal.h>
- #include <linux/sched.h>
- #include <linux/kernel.h>
--#include <linux/errno.h>
--#include <linux/string.h>
- #include <linux/types.h>
- #include <linux/ptrace.h>
--#include <linux/mman.h>
- #include <linux/mm.h>
--#include <linux/interrupt.h>
--#include <linux/proc_fs.h>
- #include <linux/bitops.h>
- #include <linux/init.h>
-
--#include <asm/system.h>
--#include <asm/uaccess.h>
- #include <asm/pgalloc.h>
- #include <asm/pgtable.h>
-+#include <asm/io.h>
-
--extern void show_pte(struct mm_struct *mm, unsigned long addr);
--extern int do_page_fault(unsigned long addr, int error_code,
-- struct pt_regs *regs);
--extern int do_translation_fault(unsigned long addr, int error_code,
-- struct pt_regs *regs);
--extern void do_bad_area(struct task_struct *tsk, struct mm_struct *mm,
-- unsigned long addr, int error_code,
-- struct pt_regs *regs);
--
--#ifdef CONFIG_ALIGNMENT_TRAP
--extern int do_alignment(unsigned long addr, int error_code, struct pt_regs *regs);
--#else
--#define do_alignment do_bad
--#endif
--
-+#include "fault.h"
-
- /*
- * Some section permission faults need to be handled gracefully.
- * They can happen due to a __{get,put}_user during an oops.
- */
- static int
--do_sect_fault(unsigned long addr, int error_code, struct pt_regs *regs)
-+do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
- {
- struct task_struct *tsk = current;
-- do_bad_area(tsk, tsk->active_mm, addr, error_code, regs);
-+ do_bad_area(tsk, tsk->active_mm, addr, fsr, regs);
- return 0;
- }
-
- /*
-- * Hook for things that need to trap external faults. Note that
-- * we don't guarantee that this will be the final version of the
-- * interface.
-- */
--int (*external_fault)(unsigned long addr, struct pt_regs *regs);
--
--static int
--do_external_fault(unsigned long addr, int error_code, struct pt_regs *regs)
--{
-- if (external_fault)
-- return external_fault(addr, regs);
-- return 1;
--}
--
--/*
- * This abort handler always returns "fault".
- */
- static int
--do_bad(unsigned long addr, int error_code, struct pt_regs *regs)
-+do_bad(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
- {
- return 1;
- }
-
--static const struct fsr_info {
-- int (*fn)(unsigned long addr, int error_code, struct pt_regs *regs);
-+static struct fsr_info {
-+ int (*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
- int sig;
- const char *name;
- } fsr_info[] = {
- { do_bad, SIGSEGV, "vector exception" },
-- { do_alignment, SIGILL, "alignment exception" },
-+ { do_bad, SIGILL, "alignment exception" },
- { do_bad, SIGKILL, "terminal exception" },
-- { do_alignment, SIGILL, "alignment exception" },
-- { do_external_fault, SIGBUS, "external abort on linefetch" },
-+ { do_bad, SIGILL, "alignment exception" },
-+ { do_bad, SIGBUS, "external abort on linefetch" },
- { do_translation_fault, SIGSEGV, "section translation fault" },
-- { do_external_fault, SIGBUS, "external abort on linefetch" },
-+ { do_bad, SIGBUS, "external abort on linefetch" },
- { do_page_fault, SIGSEGV, "page translation fault" },
-- { do_external_fault, SIGBUS, "external abort on non-linefetch" },
-+ { do_bad, SIGBUS, "external abort on non-linefetch" },
- { do_bad, SIGSEGV, "section domain fault" },
-- { do_external_fault, SIGBUS, "external abort on non-linefetch" },
-+ { do_bad, SIGBUS, "external abort on non-linefetch" },
- { do_bad, SIGSEGV, "page domain fault" },
- { do_bad, SIGBUS, "external abort on translation" },
- { do_sect_fault, SIGSEGV, "section permission fault" },
- { do_bad, SIGBUS, "external abort on translation" },
-- { do_page_fault, SIGSEGV, "page permission fault" }
-+ { do_page_fault, SIGSEGV, "page permission fault" },
- };
-
-+void __init
-+hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *),
-+ int sig, const char *name)
-+{
-+ if (nr >= 0 && nr < ARRAY_SIZE(fsr_info)) {
-+ fsr_info[nr].fn = fn;
-+ fsr_info[nr].sig = sig;
-+ fsr_info[nr].name = name;
-+ }
-+}
-+
- /*
- * Dispatch a data abort to the relevant handler.
- */
- asmlinkage void
--do_DataAbort(unsigned long addr, int error_code, struct pt_regs *regs, int fsr)
-+do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
- {
- const struct fsr_info *inf = fsr_info + (fsr & 15);
-
-- if (!inf->fn(addr, error_code, regs))
-+ if (!inf->fn(addr, fsr, regs))
- return;
-
- printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n",
-@@ -127,25 +101,28 @@
- do_translation_fault(addr, 0, regs);
- }
-
-+static unsigned long shared_pte_mask = L_PTE_CACHEABLE;
-+
- /*
- * We take the easy way out of this problem - we make the
- * PTE uncacheable. However, we leave the write buffer on.
- */
--static void adjust_pte(struct vm_area_struct *vma, unsigned long address)
-+static int adjust_pte(struct vm_area_struct *vma, unsigned long address)
- {
- pgd_t *pgd;
- pmd_t *pmd;
- pte_t *pte, entry;
-+ int ret = 0;
-
- pgd = pgd_offset(vma->vm_mm, address);
- if (pgd_none(*pgd))
-- return;
-+ goto no_pgd;
- if (pgd_bad(*pgd))
- goto bad_pgd;
-
- pmd = pmd_offset(pgd, address);
- if (pmd_none(*pmd))
-- return;
-+ goto no_pmd;
- if (pmd_bad(*pmd))
- goto bad_pmd;
-
-@@ -156,27 +133,30 @@
- * If this page isn't present, or is already setup to
- * fault (ie, is old), we can safely ignore any issues.
- */
-- if (pte_present(entry) && pte_val(entry) & L_PTE_CACHEABLE) {
-+ if (pte_present(entry) && pte_val(entry) & shared_pte_mask) {
- flush_cache_page(vma, address);
-- pte_val(entry) &= ~L_PTE_CACHEABLE;
-+ pte_val(entry) &= ~shared_pte_mask;
- set_pte(pte, entry);
- flush_tlb_page(vma, address);
-+ ret = 1;
- }
-- return;
-+ return ret;
-
- bad_pgd:
- pgd_ERROR(*pgd);
- pgd_clear(pgd);
-- return;
-+no_pgd:
-+ return 0;
-
- bad_pmd:
- pmd_ERROR(*pmd);
- pmd_clear(pmd);
-- return;
-+no_pmd:
-+ return 0;
- }
-
- static void
--make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page)
-+make_coherent(struct vm_area_struct *vma, unsigned long addr, struct page *page, int dirty)
- {
- struct vm_area_struct *mpnt;
- struct mm_struct *mm = vma->vm_mm;
-@@ -210,14 +190,17 @@
- if (off >= (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT)
- continue;
-
-+ off = mpnt->vm_start + (off << PAGE_SHIFT);
-+
- /*
- * Ok, it is within mpnt. Fix it up.
- */
-- adjust_pte(mpnt, mpnt->vm_start + (off << PAGE_SHIFT));
-- aliases ++;
-+ aliases += adjust_pte(mpnt, off);
- }
- if (aliases)
- adjust_pte(vma, addr);
-+ else if (dirty)
-+ flush_cache_page(vma, addr);
- }
-
- /*
-@@ -242,11 +225,85 @@
- return;
- page = pfn_to_page(pfn);
- if (page->mapping) {
-- if (test_and_clear_bit(PG_dcache_dirty, &page->flags)) {
-+ int dirty = test_and_clear_bit(PG_dcache_dirty, &page->flags);
-+
-+ if (dirty) {
- unsigned long kvirt = (unsigned long)page_address(page);
- cpu_cache_clean_invalidate_range(kvirt, kvirt + PAGE_SIZE, 0);
- }
-
-- make_coherent(vma, addr, page);
-+ make_coherent(vma, addr, page, dirty);
-+ }
-+}
-+
-+/*
-+ * Check whether the write buffer has physical address aliasing
-+ * issues. If it has, we need to avoid them for the case where
-+ * we have several shared mappings of the same object in user
-+ * space.
-+ */
-+static int __init check_writebuffer(unsigned long *p1, unsigned long *p2)
-+{
-+ register unsigned long zero = 0, one = 1, val;
-+
-+ mb();
-+ *p1 = one;
-+ mb();
-+ *p2 = zero;
-+ mb();
-+ val = *p1;
-+ mb();
-+ return val != zero;
-+}
-+
-+static inline void *map_page(struct page *page)
-+{
-+ void *map;
-+
-+ map = __ioremap(page_to_phys(page), PAGE_SIZE, L_PTE_BUFFERABLE);
-+ if (map)
-+ get_page(page);
-+ return map;
-+}
-+
-+static inline void unmap_page(void *map)
-+{
-+ iounmap(map);
-+}
-+
-+void __init check_writebuffer_bugs(void)
-+{
-+ struct page *page;
-+ const char *reason;
-+ unsigned long v = 1;
-+
-+ printk(KERN_INFO "CPU: Testing write buffer: ");
-+
-+ page = alloc_page(GFP_KERNEL);
-+ if (page) {
-+ unsigned long *p1, *p2;
-+
-+ p1 = map_page(page);
-+ p2 = map_page(page);
-+
-+ if (p1 && p2) {
-+ v = check_writebuffer(p1, p2);
-+ reason = "enabling work-around";
-+ } else {
-+ reason = "unable to map memory\n";
-+ }
-+
-+ unmap_page(p1);
-+ unmap_page(p2);
-+ put_page(page);
-+ } else {
-+ reason = "unable to grab page\n";
-+ }
-+
-+ if (v) {
-+ printk("FAIL - %s\n", reason);
-+ shared_pte_mask |= L_PTE_BUFFERABLE;
-+ } else {
-+ printk("pass\n");
- }
- }
---- linux-2.4.25/arch/arm/mm/fault-common.c~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/fault-common.c 2004-03-31 17:15:09.000000000 +0200
-@@ -11,21 +11,17 @@
- #include <linux/config.h>
- #include <linux/signal.h>
- #include <linux/sched.h>
--#include <linux/kernel.h>
--#include <linux/errno.h>
- #include <linux/string.h>
--#include <linux/types.h>
- #include <linux/ptrace.h>
--#include <linux/mman.h>
- #include <linux/mm.h>
- #include <linux/interrupt.h>
--#include <linux/proc_fs.h>
- #include <linux/init.h>
-
- #include <asm/system.h>
--#include <asm/uaccess.h>
- #include <asm/pgtable.h>
--#include <asm/unaligned.h>
-+#include <asm/uaccess.h>
-+
-+#include "fault.h"
-
- #ifdef CONFIG_CPU_26
- #define FAULT_CODE_WRITE 0x02
-@@ -34,13 +30,11 @@
- #define READ_FAULT(m) (!((m) & FAULT_CODE_WRITE))
- #else
- /*
-- * On 32-bit processors, we define "mode" to be zero when reading,
-- * non-zero when writing. This now ties up nicely with the polarity
-- * of the 26-bit machines, and also means that we avoid the horrible
-- * gcc code for "int val = !other_val;".
-+ * "code" is actually the FSR register. Bit 11 set means the
-+ * instruction was performing a write.
- */
--#define DO_COW(m) (m)
--#define READ_FAULT(m) (!(m))
-+#define DO_COW(code) ((code) & (1 << 11))
-+#define READ_FAULT(code) (!DO_COW(code))
- #endif
-
- /*
-@@ -54,16 +48,17 @@
- if (!mm)
- mm = &init_mm;
-
-- printk(KERN_ALERT "mm = %p pgd = %p\n", mm, mm->pgd);
--
- fs = get_fs();
- set_fs(get_ds());
-+
- do {
-- pgd_t pg, *pgd = pgd_offset(mm, addr);
-+ pgd_t pg, *pgd;
- pmd_t pm, *pmd;
- pte_t pt, *pte;
-
-- printk(KERN_ALERT "*pgd = ");
-+ printk(KERN_ALERT "pgd = %p\n", mm->pgd);
-+ pgd = pgd_offset(mm, addr);
-+ printk(KERN_ALERT "[%08lx] *pgd=", addr);
-
- if (__get_user(pgd_val(pg), (unsigned long *)pgd)) {
- printk("(faulted)");
-@@ -122,7 +117,7 @@
- * Oops. The kernel tried to access some page that wasn't present.
- */
- static void
--__do_kernel_fault(struct mm_struct *mm, unsigned long addr, int error_code,
-+__do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
- struct pt_regs *regs)
- {
- unsigned long fixup;
-@@ -148,7 +143,7 @@
- "paging request", addr);
-
- show_pte(mm, addr);
-- die("Oops", regs, error_code);
-+ die("Oops", regs, fsr);
- do_exit(SIGKILL);
- }
-
-@@ -157,20 +152,20 @@
- * User mode accesses just cause a SIGSEGV
- */
- static void
--__do_user_fault(struct task_struct *tsk, unsigned long addr, int error_code,
-- int code, struct pt_regs *regs)
-+__do_user_fault(struct task_struct *tsk, unsigned long addr,
-+ unsigned int fsr, int code, struct pt_regs *regs)
- {
- struct siginfo si;
-
- #ifdef CONFIG_DEBUG_USER
- printk(KERN_DEBUG "%s: unhandled page fault at pc=0x%08lx, "
- "lr=0x%08lx (bad address=0x%08lx, code %d)\n",
-- tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, error_code);
-+ tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, fsr);
- show_regs(regs);
- #endif
-
- tsk->thread.address = addr;
-- tsk->thread.error_code = error_code;
-+ tsk->thread.error_code = fsr;
- tsk->thread.trap_no = 14;
- si.si_signo = SIGSEGV;
- si.si_errno = 0;
-@@ -181,20 +176,20 @@
-
- void
- do_bad_area(struct task_struct *tsk, struct mm_struct *mm, unsigned long addr,
-- int error_code, struct pt_regs *regs)
-+ unsigned int fsr, struct pt_regs *regs)
- {
- /*
- * If we are in kernel mode at this point, we
- * have no context to handle this fault with.
- */
- if (user_mode(regs))
-- __do_user_fault(tsk, addr, error_code, SEGV_MAPERR, regs);
-+ __do_user_fault(tsk, addr, fsr, SEGV_MAPERR, regs);
- else
-- __do_kernel_fault(mm, addr, error_code, regs);
-+ __do_kernel_fault(mm, addr, fsr, regs);
- }
-
- static int
--__do_page_fault(struct mm_struct *mm, unsigned long addr, int error_code,
-+__do_page_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr,
- struct task_struct *tsk)
- {
- struct vm_area_struct *vma;
-@@ -212,7 +207,7 @@
- * memory access, so we can handle it.
- */
- good_area:
-- if (READ_FAULT(error_code)) /* read? */
-+ if (READ_FAULT(fsr)) /* read? */
- mask = VM_READ|VM_EXEC;
- else
- mask = VM_WRITE;
-@@ -227,7 +222,7 @@
- * than endlessly redo the fault.
- */
- survive:
-- fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(error_code));
-+ fault = handle_mm_fault(mm, vma, addr & PAGE_MASK, DO_COW(fsr));
-
- /*
- * Handle the "normal" cases first - successful and sigbus
-@@ -260,7 +255,7 @@
- return fault;
- }
-
--int do_page_fault(unsigned long addr, int error_code, struct pt_regs *regs)
-+int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
- {
- struct task_struct *tsk;
- struct mm_struct *mm;
-@@ -277,7 +272,7 @@
- goto no_context;
-
- down_read(&mm->mmap_sem);
-- fault = __do_page_fault(mm, addr, error_code, tsk);
-+ fault = __do_page_fault(mm, addr, fsr, tsk);
- up_read(&mm->mmap_sem);
-
- /*
-@@ -308,7 +303,7 @@
- printk("VM: killing process %s\n", tsk->comm);
- do_exit(SIGKILL);
- } else
-- __do_user_fault(tsk, addr, error_code, fault == -1 ?
-+ __do_user_fault(tsk, addr, fsr, fault == -1 ?
- SEGV_ACCERR : SEGV_MAPERR, regs);
- return 0;
-
-@@ -323,7 +318,7 @@
- * or user mode.
- */
- tsk->thread.address = addr;
-- tsk->thread.error_code = error_code;
-+ tsk->thread.error_code = fsr;
- tsk->thread.trap_no = 14;
- force_sig(SIGBUS, tsk);
- #ifdef CONFIG_DEBUG_USER
-@@ -336,7 +331,7 @@
- return 0;
-
- no_context:
-- __do_kernel_fault(mm, addr, error_code, regs);
-+ __do_kernel_fault(mm, addr, fsr, regs);
- return 0;
- }
-
-@@ -357,21 +352,23 @@
- * interrupt or a critical region, and should only copy the information
- * from the master page table, nothing more.
- */
--int do_translation_fault(unsigned long addr, int error_code, struct pt_regs *regs)
-+int do_translation_fault(unsigned long addr, unsigned int fsr,
-+ struct pt_regs *regs)
- {
- struct task_struct *tsk;
-- struct mm_struct *mm;
- int offset;
- pgd_t *pgd, *pgd_k;
- pmd_t *pmd, *pmd_k;
-
- if (addr < TASK_SIZE)
-- return do_page_fault(addr, error_code, regs);
-+ return do_page_fault(addr, fsr, regs);
-
- offset = __pgd_offset(addr);
-
- /*
- * FIXME: CP15 C1 is write only on ARMv3 architectures.
-+ * You really need to read the value in the page table
-+ * register, not a copy.
- */
- pgd = cpu_get_pgd() + offset;
- pgd_k = init_mm.pgd + offset;
-@@ -395,8 +392,7 @@
-
- bad_area:
- tsk = current;
-- mm = tsk->active_mm;
-
-- do_bad_area(tsk, mm, addr, error_code, regs);
-+ do_bad_area(tsk, tsk->active_mm, addr, fsr, regs);
- return 0;
- }
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/fault.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,9 @@
-+void do_bad_area(struct task_struct *tsk, struct mm_struct *mm,
-+ unsigned long addr, unsigned int fsr, struct pt_regs *regs);
-+
-+void show_pte(struct mm_struct *mm, unsigned long addr);
-+
-+int do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
-+
-+int do_translation_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
-+
---- linux-2.4.25/arch/arm/mm/init.c~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/init.c 2004-03-31 17:15:09.000000000 +0200
-@@ -9,7 +9,6 @@
- */
- #include <linux/config.h>
- #include <linux/signal.h>
--#include <linux/sched.h>
- #include <linux/kernel.h>
- #include <linux/errno.h>
- #include <linux/string.h>
-@@ -18,7 +17,6 @@
- #include <linux/mman.h>
- #include <linux/mm.h>
- #include <linux/swap.h>
--#include <linux/swapctl.h>
- #include <linux/smp.h>
- #include <linux/init.h>
- #include <linux/bootmem.h>
---- linux-2.4.25/arch/arm/mm/ioremap.c~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/ioremap.c 2004-03-31 17:15:09.000000000 +0200
-@@ -144,7 +144,7 @@
- */
- offset = phys_addr & ~PAGE_MASK;
- phys_addr &= PAGE_MASK;
-- size = PAGE_ALIGN(last_addr) - phys_addr;
-+ size = PAGE_ALIGN(last_addr + 1) - phys_addr;
-
- /*
- * Ok, go for it..
---- linux-2.4.25/arch/arm/mm/mm-armv.c~2.4.25-vrs2.patch 2003-11-28 19:26:19.000000000 +0100
-+++ linux-2.4.25/arch/arm/mm/mm-armv.c 2004-03-31 17:15:09.000000000 +0200
-@@ -9,7 +9,6 @@
- *
- * Page table sludge for ARM v3 and v4 processor architectures.
- */
--#include <linux/sched.h>
- #include <linux/mm.h>
- #include <linux/init.h>
- #include <linux/bootmem.h>
-@@ -390,6 +389,9 @@
- init_maps->bufferable = 0;
-
- create_mapping(init_maps);
-+
-+ flush_cache_all();
-+ flush_tlb_all();
- }
-
- /*
---- linux-2.4.25/arch/arm/mm/proc-arm1020.S~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/proc-arm1020.S 2004-03-31 17:15:09.000000000 +0200
-@@ -65,18 +65,21 @@
- *
- * Returns:
- * r0 = address of abort
-- * r1 != 0 if writing
-- * r3 = FSR
-+ * r1 = FSR
-+ * r3 = corrupted
- * r4 = corrupted
- */
- .align 5
- ENTRY(cpu_arm1020_data_abort)
-- mrc p15, 0, r3, c5, c0, 0 @ get FSR
-+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
- mrc p15, 0, r0, c6, c0, 0 @ get FAR
-- ldr r1, [r2] @ read aborted instruction
-- and r3, r3, #255
-- tst r1, r1, lsr #21 @ C = bit 20
-- sbc r1, r1, r1 @ r1 = C - 1
-+ tst r3, #PSR_T_BIT
-+ ldrneh r3, [r2] @ read aborted thumb instruction
-+ ldreq r3, [r2] @ read aborted ARM instruction
-+ bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
-+ movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20
-+ tst r3, #1 << 20 @ check write
-+ orreq r1, r1, #1 << 11
- mov pc, lr
-
- /*
-@@ -170,10 +173,10 @@
- #endif
- subs r3, r3, #1
- cmp r3, #0
-- bge 2b @ entries 3F to 0
-+ bhs 2b @ entries 3F to 0
- subs r1, r1, #1
- cmp r1, #0
-- bge 1b @ segments 7 to 0
-+ bhs 1b @ segments 7 to 0
- #endif
-
- #ifndef CONFIG_CPU_ICACHE_DISABLE
-@@ -201,7 +204,7 @@
- bic r0, r0, #DCACHELINESIZE - 1
- sub r3, r1, r0
- cmp r3, #MAX_AREA_SIZE
-- bgt cpu_arm1020_cache_clean_invalidate_all_r2
-+ bhi cpu_arm1020_cache_clean_invalidate_all_r2
- mcr p15, 0, r3, c7, c10, 4
- #ifndef CONFIG_CPU_DCACHE_DISABLE
- 1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
-@@ -214,7 +217,7 @@
- #endif
- add r0, r0, #DCACHELINESIZE
- cmp r0, r1
-- blt 1b
-+ blo 1b
- #endif
-
- #ifndef CONFIG_CPU_ICACHE_DISABLE
-@@ -302,7 +305,7 @@
- #endif
- add r0, r0, #DCACHELINESIZE
- cmp r0, r1
-- blt 1b
-+ blo 1b
- #else
- /* D cache off, but still drain the write buffer */
- mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer
-@@ -328,7 +331,7 @@
- bic r0, r0, #DCACHELINESIZE - 1
- sub r3, r1, r0
- cmp r3, #MAX_AREA_SIZE
-- bgt cpu_arm1020_cache_clean_invalidate_all_r2
-+ bhi cpu_arm1020_cache_clean_invalidate_all_r2
- mcr p15, 0, r3, c7, c10, 4
- #ifndef CONFIG_CPU_DCACHE_DISABLE
- 1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
-@@ -341,7 +344,7 @@
- #endif
- add r0, r0, #DCACHELINESIZE
- cmp r0, r1
-- blt 1b
-+ blo 1b
- #endif
-
- #ifndef CONFIG_CPU_BPREDICT_DISABLE
-@@ -488,7 +491,7 @@
- mov r0, r0
- #endif
- cmp r0, r1
-- blt 1b
-+ blo 1b
- mov pc, lr
-
- /*
-@@ -541,10 +544,10 @@
- #endif
- subs r3, r3, #1
- cmp r3, #0
-- bge 2b @ entries 3F to 0
-+ bhs 2b @ entries 3F to 0
- subs r1, r1, #1
- cmp r1, #0
-- bge 1b @ segments 15 to 0
-+ bhs 1b @ segments 15 to 0
-
- #endif
- mov r1, #0
-@@ -603,7 +606,7 @@
- bic r2, r2, #3
- orr r2, r2, #HPTE_TYPE_SMALL
-
-- tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
-+ tst r1, #LPTE_USER @ User?
- orrne r2, r2, #HPTE_AP_READ
-
- tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
-@@ -740,12 +743,12 @@
-
- .type cpu_arch_name, #object
- cpu_arch_name:
-- .asciz "armv4"
-+ .asciz "armv5t"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
- cpu_elf_name:
-- .asciz "v4"
-+ .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
- .align
-
-@@ -753,9 +756,9 @@
-
- .type __arm1020_proc_info,#object
- __arm1020_proc_info:
-- .long 0x4100a200
-- .long 0xff00fff0
-- .long 0x00000c02 @ mmuflags
-+ .long 0x4104a200 @ ARM 1020T (Architecture v5T)
-+ .long 0xff0ffff0
-+ .long 0x00000c0e @ mmuflags
- b __arm1020_setup
- .long cpu_arch_name
- .long cpu_elf_name
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/proc-arm1020E.S 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,718 @@
-+/*
-+ * linux/arch/arm/mm/proc-arm1020E.S: MMU functions for ARM1020E
-+ *
-+ * Copyright (C) 2000 ARM Limited
-+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ *
-+ * These are the low level assembler for performing cache and TLB
-+ * functions on the arm1020E.
-+ */
-+#include <linux/linkage.h>
-+#include <linux/config.h>
-+#include <asm/assembler.h>
-+#include <asm/constants.h>
-+#include <asm/procinfo.h>
-+#include <asm/hardware.h>
-+
-+/*
-+ * This is the maximum size of an area which will be invalidated
-+ * using the single invalidate entry instructions. Anything larger
-+ * than this, and we go for the whole cache.
-+ *
-+ * This value should be chosen such that we choose the cheapest
-+ * alternative.
-+ */
-+#define MAX_AREA_SIZE 32768
-+
-+/*
-+ * the cache line size of the I and D cache
-+ */
-+#define DCACHELINESIZE 32
-+#define ICACHELINESIZE 32
-+
-+/*
-+ * and the page size
-+ */
-+#define LOG2PAGESIZE 12 /* == 4096 Bytes */
-+#define PAGESIZE (1 << LOG2PAGESIZE)
-+
-+/*
-+ * create some useful conditional macro definitions
-+ * we often need to know if we are ((not dcache disable) and writethrough) or ((not dcache disable) and writeback)
-+ */
-+#ifdef CONFIG_CPU_DCACHE_DISABLE
-+ #undef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ #undef CONFIG_CPU_DCACHE_WRITEBACK
-+ #undef CONFIG_CPU_DCACHE_ENABLE
-+#else
-+ #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ #undef CONFIG_CPU_DCACHE_WRITEBACK
-+ #else
-+ #define CONFIG_CPU_DCACHE_WRITEBACK
-+ #endif
-+ #define CONFIG_CPU_DCACHE_ENABLE
-+#endif
-+
-+#ifdef CONFIG_CPU_ICACHE_DISABLE
-+ #undef CONFIG_CPU_ICACHE_ENABLE
-+#else
-+ #define CONFIG_CPU_ICACHE_ENABLE
-+#endif
-+
-+ .text
-+
-+/*
-+ * cpu_arm1020E_data_abort()
-+ *
-+ * obtain information about current aborted instruction
-+ * Note: we read user space. This means we might cause a data
-+ * abort here if the I-TLB and D-TLB aren't seeing the same
-+ * picture. Unfortunately, this does happen. We live with it.
-+ *
-+ * r2 = address of aborted instruction
-+ * r3 = cpsr
-+ *
-+ * Returns:
-+ * r0 = address of abort
-+ * r1 = FSR
-+ * r3 = corrupted
-+ * r4 = corrupted
-+ */
-+ .align 5
-+ENTRY(cpu_arm1020E_data_abort)
-+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
-+ mrc p15, 0, r0, c6, c0, 0 @ get FAR
-+ tst r3, #PSR_T_BIT
-+ ldrneh r3, [r2] @ read aborted thumb instruction
-+ ldreq r3, [r2] @ read aborted ARM instruction
-+ bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
-+ movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20
-+ tst r3, #1 << 20 @ check write
-+ orreq r1, r1, #1 << 11
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1020E_check_bugs()
-+ */
-+ENTRY(cpu_arm1020E_check_bugs)
-+ mrs ip, cpsr
-+ bic ip, ip, #F_BIT
-+ msr cpsr, ip
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1020E_proc_init()
-+ */
-+ENTRY(cpu_arm1020E_proc_init)
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1020E_proc_fin()
-+ */
-+ENTRY(cpu_arm1020E_proc_fin)
-+ stmfd sp!, {lr}
-+ mov ip, #F_BIT | I_BIT | SVC_MODE
-+ msr cpsr_c, ip
-+ bl cpu_arm1020E_cache_clean_invalidate_all
-+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
-+ bic r0, r0, #0x1000 @ ...i............
-+ bic r0, r0, #0x000e @ ............wca.
-+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
-+ ldmfd sp!, {pc}
-+
-+/*
-+ * cpu_arm1020E_reset(loc)
-+ *
-+ * Perform a soft reset of the system. Put the CPU into the
-+ * same state as it would be if it had been reset, and branch
-+ * to what would be the reset vector.
-+ *
-+ * loc: location to jump to for soft reset
-+ */
-+ .align 5
-+ENTRY(cpu_arm1020E_reset)
-+ mov ip, #0
-+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
-+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
-+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
-+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
-+ bic ip, ip, #0x000f @ ............wcam
-+ bic ip, ip, #0x1100 @ ...i...s........
-+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
-+ mov pc, r0
-+
-+/*
-+ * cpu_arm1020E_do_idle()
-+ */
-+ .align 5
-+ENTRY(cpu_arm1020E_do_idle)
-+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
-+ mov pc, lr
-+
-+/* ================================= CACHE ================================ */
-+
-+
-+/*
-+ * cpu_arm1020E_cache_clean_invalidate_all()
-+ *
-+ * clean and invalidate all cache lines
-+ *
-+ * Note:
-+ * 1. we should preserve r0 and ip at all times
-+ */
-+ .align 5
-+ENTRY(cpu_arm1020E_cache_clean_invalidate_all)
-+ mov r2, #1
-+cpu_arm1020E_cache_clean_invalidate_all_r2:
-+
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ mov r1, #0x0F << 5 @ 16 segments
-+1: orr r3, r1, #63 << 26 @ 64 entries
-+2: mcr p15, 0, r3, c7, c14, 2 @ clean and invalidate D index
-+ subs r3, r3, #1 << 26
-+ bcs 2b
-+ subs r1, r1, #1 << 5
-+ bcs 1b @ segments 15 to 0
-+#endif
-+
-+ mov r1, #0
-+
-+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ mcr p15, 0, r1, c7, c6, 0 @ invalidate D cache
-+#endif
-+
-+#ifdef CONFIG_CPU_ICACHE_ENABLE
-+ teq r2, #0
-+ mcrne p15, 0, r1, c7, c5, 0 @ invalidate I cache
-+#endif
-+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1020E_cache_clean_invalidate_range(start, end, flags)
-+ *
-+ * clean and invalidate all cache lines associated with this area of memory
-+ *
-+ * start: Area start address
-+ * end: Area end address
-+ * flags: nonzero for I cache as well
-+ */
-+ .align 5
-+ENTRY(cpu_arm1020E_cache_clean_invalidate_range)
-+ bic r0, r0, #DCACHELINESIZE - 1
-+ sub r3, r1, r0
-+ cmp r3, #MAX_AREA_SIZE
-+ bhs cpu_arm1020E_cache_clean_invalidate_all_r2
-+1:
-+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
-+#endif
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
-+#endif
-+#ifdef CONFIG_CPU_ICACHE_ENABLE
-+ teq r2, #0
-+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
-+#endif
-+ add r0, r0, #DCACHELINESIZE
-+ cmp r0, r1
-+ bls 1b @ unsigned lower or same - must include end point (r1)!
-+
-+ mov r1, #0
-+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1020E_flush_ram_page(page)
-+ *
-+ * clean and invalidate all cache lines associated with this area of memory
-+ *
-+ * page: page to clean and invalidate
-+ */
-+ .align 5
-+ENTRY(cpu_arm1020E_flush_ram_page)
-+ mov r1, #PAGESIZE
-+ mov r0, r0, LSR #LOG2PAGESIZE @ round down to nearest page
-+ mov r0, r0, LSL #LOG2PAGESIZE
-+1:
-+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
-+#endif
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
-+#endif
-+#ifdef CONFIG_CPU_ICACHE_ENABLE
-+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
-+#endif
-+ add r0, r0, #DCACHELINESIZE
-+ subs r1, r1, #DCACHELINESIZE
-+ bne 1b
-+
-+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+/* ================================ D-CACHE =============================== */
-+
-+/*
-+ * cpu_arm1020E_dcache_invalidate_range(start, end)
-+ *
-+ * throw away all D-cached data in specified region without an obligation
-+ * to write them back. Note however that we must clean the D-cached entries
-+ * around the boundaries if the start and/or end address are not cache
-+ * aligned.
-+ *
-+ * start: virtual start address
-+ * end: virtual end address
-+ */
-+ .align 5
-+ENTRY(cpu_arm1020E_dcache_invalidate_range)
-+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ bic r0, r0, #DCACHELINESIZE - 1
-+#endif
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ tst r0, #DCACHELINESIZE - 1
-+ bic r0, r0, #DCACHELINESIZE - 1
-+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry at start
-+ tst r1, #DCACHELINESIZE - 1
-+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry at end
-+#endif
-+
-+1:
-+#ifdef CONFIG_CPU_DCACHE_ENABLE
-+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
-+#endif
-+#ifdef CONFIG_CPU_ICACHE_ENABLE
-+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
-+#endif
-+ add r0, r0, #DCACHELINESIZE
-+ cmp r0, r1
-+ bls 1b
-+
-+ /* Even if the D cache is off still drain the write buffer */
-+ mov r0, #0
-+ mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1020E_dcache_clean_range(start, end)
-+ *
-+ * For the specified virtual address range, ensure that all caches contain
-+ * clean data, such that peripheral accesses to the physical RAM fetch
-+ * correct data.
-+ *
-+ * start: virtual start address
-+ * end: virtual end address
-+ */
-+ .align 5
-+ENTRY(cpu_arm1020E_dcache_clean_range)
-+
-+ mov r2, #0
-+
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ bic r0, r0, #DCACHELINESIZE - 1
-+ sub r3, r1, r0
-+ cmp r3, #MAX_AREA_SIZE
-+ bhs cpu_arm1020E_cache_clean_invalidate_all_r2
-+
-+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
-+ add r0, r0, #DCACHELINESIZE
-+ cmp r0, r1
-+ bls 1b
-+#endif
-+
-+ mcr p15, 0, r2, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1020E_dcache_clean_page(page)
-+ *
-+ * Cleans a single page of dcache so that if we have any future aliased
-+ * mappings, they will be consistent at the time that they are created.
-+ *
-+ * page: virtual address of page to clean from dcache
-+ *
-+ * Note:
-+ * we don't invalidate the entries since when we write the page
-+ * out to disk, the entries may get reloaded into the cache.
-+ */
-+ .align 5
-+ENTRY(cpu_arm1020E_dcache_clean_page)
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ mov r0, r0, LSR #LOG2PAGESIZE @ round down to nearest page
-+ mov r0, r0, LSL #LOG2PAGESIZE
-+ mov r1, #PAGESIZE
-+1:
-+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
-+ add r0, r0, #DCACHELINESIZE
-+ subs r1, r1, #DCACHELINESIZE
-+ bne 1b
-+#endif
-+ mov r1, #0
-+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1020E_dcache_clean_entry(addr)
-+ *
-+ * Clean the specified entry of any caches such that the MMU
-+ * translation fetches will obtain correct data.
-+ *
-+ * addr: cache-unaligned virtual address
-+ */
-+ .align 5
-+ENTRY(cpu_arm1020E_dcache_clean_entry)
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ bic r0, r0, #DCACHELINESIZE - 1
-+ mcr p15, 0, r0, c7, c10, 1 @ clean single D entry
-+#endif
-+ mov r1, #0
-+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+/* ================================ I-CACHE =============================== */
-+
-+/*
-+ * cpu_arm1020E_icache_invalidate_range(start, end)
-+ *
-+ * invalidate a range of virtual addresses from the Icache
-+ *
-+ * This is a little misleading, it is not intended to clean out
-+ * the i-cache but to make sure that any data written to the
-+ * range is made consistent. This means that when we execute code
-+ * in that region, everything works as we expect.
-+ *
-+ * This generally means writing back data in the Dcache and
-+ * write buffer and invalidating the Icache over that region
-+ *
-+ * start: virtual start address
-+ * end: virtual end address
-+ *
-+ * NOTE: ICACHELINESIZE == DCACHELINESIZE (so we don't need to
-+ * loop twice, once for i-cache, once for d-cache)
-+ */
-+ .align 5
-+ENTRY(cpu_arm1020E_icache_invalidate_range)
-+ bic r0, r0, #ICACHELINESIZE - 1
-+ sub r3, r1, r0
-+ cmp r3, #MAX_AREA_SIZE
-+ movhs r2, #1
-+ bhs cpu_arm1020E_cache_clean_invalidate_all_r2
-+
-+1:
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ mcr p15, 0, r0, c7, c10, 1 @ Clean D entry
-+#endif
-+#ifdef CONFIG_CPU_ICACHE_ENABLE
-+ mcr p15, 0, r0, c7, c5, 1 @ Invalidate I entry
-+#endif
-+ add r0, r0, #DCACHELINESIZE
-+ cmp r0, r1
-+ bls 1b @ unsigned lower or same - includes r1 entry
-+
-+ mov r0, #0
-+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+ENTRY(cpu_arm1020E_icache_invalidate_page)
-+ mov r0, r0, LSR #LOG2PAGESIZE @ round down to nearest page
-+ mov r0, r0, LSL #LOG2PAGESIZE
-+ add r1, r0, #PAGESIZE
-+ b cpu_arm1020E_icache_invalidate_range
-+
-+/* ================================== TLB ================================= */
-+
-+/*
-+ * cpu_arm1020E_tlb_invalidate_all()
-+ *
-+ * Invalidate all TLB entries
-+ */
-+ .align 5
-+ENTRY(cpu_arm1020E_tlb_invalidate_all)
-+ mov r0, #0
-+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
-+ mcr p15, 0, r0, c8, c7, 0 @ invalidate I & D tlbs
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1020E_tlb_invalidate_range(start, end)
-+ *
-+ * invalidate TLB entries covering the specified range
-+ *
-+ * start: range start address
-+ * end: range end address
-+ */
-+ .align 5
-+ENTRY(cpu_arm1020E_tlb_invalidate_range)
-+ sub r3, r1, r0
-+ cmp r3, #256 * PAGESIZE
-+ bhs cpu_arm1020E_tlb_invalidate_all
-+ mov r3, #0
-+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
-+ mov r3, #PAGESIZE
-+ sub r3, r3, #1
-+ bic r0, r0, r3
-+1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
-+ mcr p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
-+ add r0, r0, #PAGESIZE
-+ cmp r0, r1
-+ bls 1b
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1020E_tlb_invalidate_page(page, flags)
-+ *
-+ * invalidate the TLB entries for the specified page.
-+ *
-+ * page: page to invalidate
-+ * flags: non-zero if we include the I TLB
-+ */
-+ .align 5
-+ENTRY(cpu_arm1020E_tlb_invalidate_page)
-+ mov r3, #0
-+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
-+ mov r0, r0, LSR #LOG2PAGESIZE @ round down to nearest page
-+ mov r0, r0, LSL #LOG2PAGESIZE
-+ teq r1, #0
-+ mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
-+ mcrne p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
-+ mov pc, lr
-+
-+/* =============================== PageTable ============================== */
-+
-+/*
-+ * cpu_arm1020E_set_pgd(pgd)
-+ *
-+ * Set the translation base pointer to be as described by pgd.
-+ *
-+ * pgd: new page tables
-+ */
-+ .align 5
-+ENTRY(cpu_arm1020E_set_pgd)
-+ stmfd sp!, {lr}
-+ bl cpu_arm1020E_cache_clean_invalidate_all @ preserves r0
-+ mov r1, #0
-+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
-+ mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
-+ ldmfd sp!, {pc}
-+
-+/*
-+ * cpu_arm1020E_set_pmd(pmdp, pmd)
-+ *
-+ * Set a level 1 translation table entry, and clean it out of
-+ * any caches such that the MMUs can load it correctly.
-+ *
-+ * pmdp: pointer to PMD entry
-+ * pmd: PMD value to store
-+ */
-+ .align 5
-+ENTRY(cpu_arm1020E_set_pmd)
-+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ eor r2, r1, #0x0a @ C & Section
-+ tst r2, #0x0b
-+ biceq r1, r1, #4 @ clear bufferable bit
-+#endif
-+ str r1, [r0]
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
-+#endif
-+ mov r0, #0
-+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1020E_set_pte(ptep, pte)
-+ *
-+ * Set a PTE and flush it out
-+ */
-+ .align 5
-+ENTRY(cpu_arm1020E_set_pte)
-+ str r1, [r0], #-1024 @ linux version
-+
-+ eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
-+
-+ bic r2, r1, #0xff0
-+ bic r2, r2, #3
-+ orr r2, r2, #HPTE_TYPE_SMALL
-+
-+ tst r1, #LPTE_USER @ User?
-+ orrne r2, r2, #HPTE_AP_READ
-+
-+ tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
-+ orreq r2, r2, #HPTE_AP_WRITE
-+
-+ tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young?
-+ movne r2, #0
-+
-+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ eor r3, r2, #0x0a @ C and Small Page?
-+ tst r3, #0x0b @ if so..
-+ biceq r2, r2, #0x04 @ clear the bufferable bit
-+#endif
-+ str r2, [r0] @ hardware version
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
-+#endif
-+ mov r1, #0
-+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+
-+cpu_manu_name:
-+ .asciz "ARM"
-+ENTRY(cpu_arm1020E_name)
-+ .ascii "Arm1020E"
-+#ifdef CONFIG_CPU_ICACHE_ENABLE
-+ .ascii "i"
-+#endif
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ .ascii "d"
-+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ .ascii "(wt)"
-+#endif
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ .ascii "(wb)"
-+#endif
-+#endif
-+#ifndef CONFIG_CPU_BPREDICT_DISABLE
-+ .ascii "B"
-+#endif
-+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
-+ .ascii "RR"
-+#endif
-+ .ascii "\0"
-+ .align
-+
-+ .section ".text.init", #alloc, #execinstr
-+
-+__arm1020E_setup:
-+ mov r0, #0
-+ mcr p15, 0, r0, c7, c7, 0 @ invalidate I,D caches on v4
-+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
-+ mcr p15, 0, r0, c8, c7, 0 @ invalidate I,D TLBs on v4
-+ mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
-+ mov r0, #0x1f @ Domains 0, 1 = client
-+ mcr p15, 0, r0, c3, c0, 0 @ load domain access register
-+
-+ mrc p15, 0, r0, c1, c0, 0 @ Read current control register
-+/*
-+ * The only thing worth keeping from the initial control register is the endian bit
-+ */
-+
-+ and r0, r0, #0x0080 @ ........B....... Preserve endian bit, zero all others.
-+ orr r0, r0, #0x0070 @ .........111.... Set the SBO (Should Be One) bits
-+/*
-+ * Turn on what we want.
-+ */
-+ orr r0, r0, #0x0001 @ ...............M Enable MMU (Alignment is special cased elsewhere)
-+ orr r0, r0, #0x0100 @ .......S........ Enable system MMU protection
-+ orr r0, r0, #0x2000 @ ..V............. Enable high vectors
-+
-+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
-+ orr r0, r0, #0x4000 @ .R.............. Force round-robin replacement
-+#endif
-+
-+#ifndef CONFIG_CPU_BPREDICT_DISABLE
-+ orr r0, r0, #0x0800 @ ....Z........... Enable branch prediction
-+#endif
-+
-+#ifdef CONFIG_CPU_DCACHE_ENABLE
-+ orr r0, r0, #0x0004 @ .............C.. Enable D cache
-+#endif
-+#ifndef CONFIG_CPU_WB_DISABLE
-+ orr r0, r0, #0x0008 @ ............W... Write Buffer enabled
-+#endif
-+
-+#ifdef CONFIG_CPU_ICACHE_ENABLE
-+ orr r0, r0, #0x1000 @ ...I............ Enable I Cache
-+#endif
-+
-+ mov pc, lr
-+
-+ .text
-+
-+/*
-+ * Purpose : Function pointers used to access above functions - all calls
-+ * come through these
-+ */
-+ .type arm1020E_processor_functions, #object
-+arm1020E_processor_functions:
-+ .word cpu_arm1020E_data_abort
-+ .word cpu_arm1020E_check_bugs
-+ .word cpu_arm1020E_proc_init
-+ .word cpu_arm1020E_proc_fin
-+ .word cpu_arm1020E_reset
-+ .word cpu_arm1020E_do_idle
-+
-+ /* cache */
-+ .word cpu_arm1020E_cache_clean_invalidate_all
-+ .word cpu_arm1020E_cache_clean_invalidate_range
-+ .word cpu_arm1020E_flush_ram_page
-+
-+ /* dcache */
-+ .word cpu_arm1020E_dcache_invalidate_range
-+ .word cpu_arm1020E_dcache_clean_range
-+ .word cpu_arm1020E_dcache_clean_page
-+ .word cpu_arm1020E_dcache_clean_entry
-+
-+ /* icache */
-+ .word cpu_arm1020E_icache_invalidate_range
-+ .word cpu_arm1020E_icache_invalidate_page
-+
-+ /* tlb */
-+ .word cpu_arm1020E_tlb_invalidate_all
-+ .word cpu_arm1020E_tlb_invalidate_range
-+ .word cpu_arm1020E_tlb_invalidate_page
-+
-+ /* pgtable */
-+ .word cpu_arm1020E_set_pgd
-+ .word cpu_arm1020E_set_pmd
-+ .word cpu_arm1020E_set_pte
-+ .size arm1020E_processor_functions, . - arm1020E_processor_functions
-+
-+ .type cpu_arm1020E_info, #object
-+cpu_arm1020E_info:
-+ .long cpu_manu_name
-+ .long cpu_arm1020E_name
-+ .size cpu_arm1020E_info, . - cpu_arm1020E_info
-+
-+ .type cpu_arch_name, #object
-+cpu_arch_name:
-+ .asciz "armv5te"
-+ .size cpu_arch_name, . - cpu_arch_name
-+
-+ .type cpu_elf_name, #object
-+cpu_elf_name:
-+ .asciz "v5"
-+ .size cpu_elf_name, . - cpu_elf_name
-+ .align
-+
-+ .section ".proc.info", #alloc, #execinstr
-+
-+ .type __arm1020E_proc_info,#object
-+__arm1020E_proc_info:
-+ .long 0x4105a200 @ ARM 1020E (Architecture v5TE)
-+ .long 0xff0ffff0
-+ .long 0x00000c1e @ mmuflags
-+ b __arm1020E_setup
-+ .long cpu_arch_name
-+ .long cpu_elf_name
-+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
-+ .long cpu_arm1020E_info
-+ .long arm1020E_processor_functions
-+ .size __arm1020E_proc_info, . - __arm1020E_proc_info
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/proc-arm1022.S 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,716 @@
-+/*
-+ * linux/arch/arm/mm/proc-arm1022.S: MMU functions for ARM1022E
-+ *
-+ * Copyright (C) 2000 ARM Limited
-+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ *
-+ * These are the low level assembler for performing cache and TLB
-+ * functions on the arm1022E.
-+ */
-+#include <linux/linkage.h>
-+#include <linux/config.h>
-+#include <asm/assembler.h>
-+#include <asm/constants.h>
-+#include <asm/procinfo.h>
-+#include <asm/hardware.h>
-+
-+/*
-+ * This is the maximum size of an area which will be invalidated
-+ * using the single invalidate entry instructions. Anything larger
-+ * than this, and we go for the whole cache.
-+ *
-+ * This value should be chosen such that we choose the cheapest
-+ * alternative.
-+ */
-+#define MAX_AREA_SIZE 16384
-+
-+/*
-+ * the cache line size of the I and D cache
-+ */
-+#define DCACHELINESIZE 32
-+#define ICACHELINESIZE 32
-+
-+/*
-+ * and the page size
-+ */
-+#define LOG2PAGESIZE 12 /* == 4096 Bytes */
-+#define PAGESIZE (1 << LOG2PAGESIZE)
-+
-+/*
-+ * create some useful conditional macro definitions
-+ * we often need to know if we are ((not dcache disable) and writethrough) or ((not dcache disable) and writeback)
-+ */
-+#ifdef CONFIG_CPU_DCACHE_DISABLE
-+ #undef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ #undef CONFIG_CPU_DCACHE_WRITEBACK
-+ #undef CONFIG_CPU_DCACHE_ENABLE
-+#else
-+ #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ #undef CONFIG_CPU_DCACHE_WRITEBACK
-+ #else
-+ #define CONFIG_CPU_DCACHE_WRITEBACK
-+ #endif
-+ #define CONFIG_CPU_DCACHE_ENABLE
-+#endif
-+
-+#ifdef CONFIG_CPU_ICACHE_DISABLE
-+ #undef CONFIG_CPU_ICACHE_ENABLE
-+#else
-+ #define CONFIG_CPU_ICACHE_ENABLE
-+#endif
-+
-+ .text
-+
-+/*
-+ * cpu_arm1022_data_abort()
-+ *
-+ * obtain information about current aborted instruction
-+ * Note: we read user space. This means we might cause a data
-+ * abort here if the I-TLB and D-TLB aren't seeing the same
-+ * picture. Unfortunately, this does happen. We live with it.
-+ *
-+ * r2 = address of aborted instruction
-+ * r3 = cpsr
-+ *
-+ * Returns:
-+ * r0 = address of abort
-+ * r1 = FSR
-+ * r3 = corrupted
-+ * r4 = corrupted
-+ */
-+ .align 5
-+ENTRY(cpu_arm1022_data_abort)
-+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
-+ mrc p15, 0, r0, c6, c0, 0 @ get FAR
-+ tst r3, #PSR_T_BIT
-+ ldrneh r3, [r2] @ read aborted thumb instruction
-+ ldreq r3, [r2] @ read aborted ARM instruction
-+ bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
-+ movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20
-+ tst r3, #1 << 20 @ check write
-+ orreq r1, r1, #1 << 11
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1022_check_bugs()
-+ */
-+ENTRY(cpu_arm1022_check_bugs)
-+ mrs ip, cpsr
-+ bic ip, ip, #F_BIT
-+ msr cpsr, ip
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1022_proc_init()
-+ */
-+ENTRY(cpu_arm1022_proc_init)
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1022_proc_fin()
-+ */
-+ENTRY(cpu_arm1022_proc_fin)
-+ stmfd sp!, {lr}
-+ mov ip, #F_BIT | I_BIT | SVC_MODE
-+ msr cpsr_c, ip
-+ bl cpu_arm1022_cache_clean_invalidate_all
-+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
-+ bic r0, r0, #0x1000 @ ...i............
-+ bic r0, r0, #0x000e @ ............wca.
-+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
-+ ldmfd sp!, {pc}
-+
-+/*
-+ * cpu_arm1022_reset(loc)
-+ *
-+ * Perform a soft reset of the system. Put the CPU into the
-+ * same state as it would be if it had been reset, and branch
-+ * to what would be the reset vector.
-+ *
-+ * loc: location to jump to for soft reset
-+ */
-+ .align 5
-+ENTRY(cpu_arm1022_reset)
-+ mov ip, #0
-+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
-+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
-+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
-+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
-+ bic ip, ip, #0x000f @ ............wcam
-+ bic ip, ip, #0x1100 @ ...i...s........
-+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
-+ mov pc, r0
-+
-+/*
-+ * cpu_arm1022_do_idle()
-+ */
-+ .align 5
-+ENTRY(cpu_arm1022_do_idle)
-+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
-+ mov pc, lr
-+
-+/* ================================= CACHE ================================ */
-+
-+
-+/*
-+ * cpu_arm1022_cache_clean_invalidate_all()
-+ *
-+ * clean and invalidate all cache lines
-+ *
-+ * Note:
-+ * 1. we should preserve r0 and ip at all times
-+ */
-+ .align 5
-+ENTRY(cpu_arm1022_cache_clean_invalidate_all)
-+ mov r2, #1
-+cpu_arm1022_cache_clean_invalidate_all_r2:
-+
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ mov r1, #7 << 5 @ 8 segments
-+1: orr r3, r1, #63 << 26 @ 64 entries
-+2: mcr p15, 0, r3, c7, c14, 2 @ clean and invalidate D index
-+ subs r3, r3, #1 << 26
-+ bcs 2b
-+ subs r1, r1, #1 << 5
-+ bcs 1b @ segments 7 to 0
-+#endif
-+
-+ mov r1, #0
-+
-+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ mcr p15, 0, r1, c7, c6, 0 @ invalidate D cache
-+#endif
-+
-+#ifdef CONFIG_CPU_ICACHE_ENABLE
-+ teq r2, #0
-+ mcrne p15, 0, r1, c7, c5, 0 @ invalidate I cache
-+#endif
-+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1022_cache_clean_invalidate_range(start, end, flags)
-+ *
-+ * clean and invalidate all cache lines associated with this area of memory
-+ *
-+ * start: Area start address
-+ * end: Area end address
-+ * flags: nonzero for I cache as well
-+ */
-+ .align 5
-+ENTRY(cpu_arm1022_cache_clean_invalidate_range)
-+ bic r0, r0, #DCACHELINESIZE - 1
-+ sub r3, r1, r0
-+ cmp r3, #MAX_AREA_SIZE
-+ bhs cpu_arm1022_cache_clean_invalidate_all_r2
-+1:
-+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
-+#endif
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
-+#endif
-+#ifdef CONFIG_CPU_ICACHE_ENABLE
-+ teq r2, #0
-+ mcrne p15, 0, r0, c7, c5, 1 @ invalidate I entry
-+#endif
-+ add r0, r0, #DCACHELINESIZE
-+ cmp r0, r1
-+ bls 1b @ unsigned lower or same - must include end point (r1)!
-+
-+ mov r1, #0
-+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1022_flush_ram_page(page)
-+ *
-+ * clean and invalidate all cache lines associated with this area of memory
-+ *
-+ * page: page to clean and invalidate
-+ */
-+ .align 5
-+ENTRY(cpu_arm1022_flush_ram_page)
-+ mov r1, #PAGESIZE
-+ mov r0, r0, LSR #LOG2PAGESIZE @ round down to nearest page
-+ mov r0, r0, LSL #LOG2PAGESIZE
-+1:
-+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
-+#endif
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
-+#endif
-+#ifdef CONFIG_CPU_ICACHE_ENABLE
-+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
-+#endif
-+ add r0, r0, #DCACHELINESIZE
-+ subs r1, r1, #DCACHELINESIZE
-+ bne 1b
-+
-+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+/* ================================ D-CACHE =============================== */
-+
-+/*
-+ * cpu_arm1022_dcache_invalidate_range(start, end)
-+ *
-+ * throw away all D-cached data in specified region without an obligation
-+ * to write them back. Note however that we must clean the D-cached entries
-+ * around the boundaries if the start and/or end address are not cache
-+ * aligned.
-+ *
-+ * start: virtual start address
-+ * end: virtual end address
-+ */
-+ .align 5
-+ENTRY(cpu_arm1022_dcache_invalidate_range)
-+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ bic r0, r0, #DCACHELINESIZE - 1
-+#endif
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ tst r0, #DCACHELINESIZE - 1
-+ bic r0, r0, #DCACHELINESIZE - 1
-+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry at start
-+ tst r1, #DCACHELINESIZE - 1
-+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry at end
-+#endif
-+
-+1:
-+#ifdef CONFIG_CPU_DCACHE_ENABLE
-+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
-+#endif
-+#ifdef CONFIG_CPU_ICACHE_ENABLE
-+ mcr p15, 0, r0, c7, c5, 1 @ invalidate I entry
-+#endif
-+ add r0, r0, #DCACHELINESIZE
-+ cmp r0, r1
-+ bls 1b
-+
-+ /* Even if the D cache is off still drain the write buffer */
-+ mov r0, #0
-+ mcr p15, 0, r0, c7, c10, 4 @ Drain write buffer
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1022_dcache_clean_range(start, end)
-+ *
-+ * For the specified virtual address range, ensure that all caches contain
-+ * clean data, such that peripheral accesses to the physical RAM fetch
-+ * correct data.
-+ *
-+ * start: virtual start address
-+ * end: virtual end address
-+ */
-+ .align 5
-+ENTRY(cpu_arm1022_dcache_clean_range)
-+
-+ mov r2, #0
-+
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ bic r0, r0, #DCACHELINESIZE - 1
-+ sub r3, r1, r0
-+ cmp r3, #MAX_AREA_SIZE
-+ bhs cpu_arm1022_cache_clean_invalidate_all_r2
-+
-+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
-+ add r0, r0, #DCACHELINESIZE
-+ cmp r0, r1
-+ bls 1b
-+#endif
-+
-+ mcr p15, 0, r2, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1022_dcache_clean_page(page)
-+ *
-+ * Cleans a single page of dcache so that if we have any future aliased
-+ * mappings, they will be consistent at the time that they are created.
-+ *
-+ * page: virtual address of page to clean from dcache
-+ *
-+ * Note:
-+ * we don't invalidate the entries since when we write the page
-+ * out to disk, the entries may get reloaded into the cache.
-+ */
-+ .align 5
-+ENTRY(cpu_arm1022_dcache_clean_page)
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ mov r0, r0, LSR #LOG2PAGESIZE @ round down to nearest page
-+ mov r0, r0, LSL #LOG2PAGESIZE
-+ mov r1, #PAGESIZE
-+1:
-+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
-+ add r0, r0, #DCACHELINESIZE
-+ subs r1, r1, #DCACHELINESIZE
-+ bne 1b
-+#endif
-+ mov r1, #0
-+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1022_dcache_clean_entry(addr)
-+ *
-+ * Clean the specified entry of any caches such that the MMU
-+ * translation fetches will obtain correct data.
-+ *
-+ * addr: cache-unaligned virtual address
-+ */
-+ .align 5
-+ENTRY(cpu_arm1022_dcache_clean_entry)
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ bic r0, r0, #DCACHELINESIZE - 1
-+ mcr p15, 0, r0, c7, c10, 1 @ clean single D entry
-+#endif
-+ mov r1, #0
-+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+/* ================================ I-CACHE =============================== */
-+
-+/*
-+ * cpu_arm1022_icache_invalidate_range(start, end)
-+ *
-+ * invalidate a range of virtual addresses from the Icache
-+ *
-+ * This is a little misleading, it is not intended to clean out
-+ * the i-cache but to make sure that any data written to the
-+ * range is made consistent. This means that when we execute code
-+ * in that region, everything works as we expect.
-+ *
-+ * This generally means writing back data in the Dcache and
-+ * write buffer and invalidating the Icache over that region
-+ *
-+ * start: virtual start address
-+ * end: virtual end address
-+ *
-+ * NOTE: ICACHELINESIZE == DCACHELINESIZE (so we don't need to
-+ * loop twice, once for i-cache, once for d-cache)
-+ */
-+ .align 5
-+ENTRY(cpu_arm1022_icache_invalidate_range)
-+ bic r0, r0, #ICACHELINESIZE - 1
-+ sub r3, r1, r0
-+ cmp r3, #MAX_AREA_SIZE
-+ movhs r2, #1
-+ bhs cpu_arm1022_cache_clean_invalidate_all_r2
-+1:
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ mcr p15, 0, r0, c7, c10, 1 @ Clean D entry
-+#endif
-+#ifdef CONFIG_CPU_ICACHE_ENABLE
-+ mcr p15, 0, r0, c7, c5, 1 @ Invalidate I entry
-+#endif
-+ add r0, r0, #DCACHELINESIZE
-+ cmp r0, r1
-+ bls 1b @ unsigned lower or same - includes r1 entry
-+
-+ mov r0, #0
-+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+ENTRY(cpu_arm1022_icache_invalidate_page)
-+ mov r0, r0, LSR #LOG2PAGESIZE @ round down to nearest page
-+ mov r0, r0, LSL #LOG2PAGESIZE
-+ add r1, r0, #PAGESIZE
-+ b cpu_arm1022_icache_invalidate_range
-+
-+/* ================================== TLB ================================= */
-+
-+/*
-+ * cpu_arm1022_tlb_invalidate_all()
-+ *
-+ * Invalidate all TLB entries
-+ */
-+ .align 5
-+ENTRY(cpu_arm1022_tlb_invalidate_all)
-+ mov r0, #0
-+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
-+ mcr p15, 0, r0, c8, c7, 0 @ invalidate I & D tlbs
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1022_tlb_invalidate_range(start, end)
-+ *
-+ * invalidate TLB entries covering the specified range
-+ *
-+ * start: range start address
-+ * end: range end address
-+ */
-+ .align 5
-+ENTRY(cpu_arm1022_tlb_invalidate_range)
-+ sub r3, r1, r0
-+ cmp r3, #256 * PAGESIZE
-+ bhs cpu_arm1022_tlb_invalidate_all
-+ mov r3, #0
-+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
-+ mov r3, #PAGESIZE
-+ sub r3, r3, #1
-+ bic r0, r0, r3
-+1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
-+ mcr p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
-+ add r0, r0, #PAGESIZE
-+ cmp r0, r1
-+ bls 1b
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1022_tlb_invalidate_page(page, flags)
-+ *
-+ * invalidate the TLB entries for the specified page.
-+ *
-+ * page: page to invalidate
-+ * flags: non-zero if we include the I TLB
-+ */
-+ .align 5
-+ENTRY(cpu_arm1022_tlb_invalidate_page)
-+ mov r3, #0
-+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
-+ mov r0, r0, LSR #LOG2PAGESIZE @ round down to nearest page
-+ mov r0, r0, LSL #LOG2PAGESIZE
-+ teq r1, #0
-+ mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
-+ mcrne p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
-+ mov pc, lr
-+
-+/* =============================== PageTable ============================== */
-+
-+/*
-+ * cpu_arm1022_set_pgd(pgd)
-+ *
-+ * Set the translation base pointer to be as described by pgd.
-+ *
-+ * pgd: new page tables
-+ */
-+ .align 5
-+ENTRY(cpu_arm1022_set_pgd)
-+ stmfd sp!, {lr}
-+ bl cpu_arm1022_cache_clean_invalidate_all @ preserves r0
-+ mov r1, #0
-+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
-+ mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
-+ ldmfd sp!, {pc}
-+
-+/*
-+ * cpu_arm1022_set_pmd(pmdp, pmd)
-+ *
-+ * Set a level 1 translation table entry, and clean it out of
-+ * any caches such that the MMUs can load it correctly.
-+ *
-+ * pmdp: pointer to PMD entry
-+ * pmd: PMD value to store
-+ */
-+ .align 5
-+ENTRY(cpu_arm1022_set_pmd)
-+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ eor r2, r1, #0x0a @ C & Section
-+ tst r2, #0x0b
-+ biceq r1, r1, #4 @ clear bufferable bit
-+#endif
-+ str r1, [r0]
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
-+#endif
-+ mov r0, #0
-+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+/*
-+ * cpu_arm1022_set_pte(ptep, pte)
-+ *
-+ * Set a PTE and flush it out
-+ */
-+ .align 5
-+ENTRY(cpu_arm1022_set_pte)
-+ str r1, [r0], #-1024 @ linux version
-+
-+ eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
-+
-+ bic r2, r1, #0xff0
-+ bic r2, r2, #3
-+ orr r2, r2, #HPTE_TYPE_SMALL
-+
-+ tst r1, #LPTE_USER @ User?
-+ orrne r2, r2, #HPTE_AP_READ
-+
-+ tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
-+ orreq r2, r2, #HPTE_AP_WRITE
-+
-+ tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young?
-+ movne r2, #0
-+
-+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ eor r3, r2, #0x0a @ C and Small Page?
-+ tst r3, #0x0b @ if so..
-+ biceq r2, r2, #0x04 @ clear the bufferable bit
-+#endif
-+ str r2, [r0] @ hardware version
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
-+#endif
-+ mov r1, #0
-+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
-+ mov pc, lr
-+
-+
-+cpu_manu_name:
-+ .asciz "ARM"
-+ENTRY(cpu_arm1022_name)
-+ .ascii "Arm1022E"
-+#ifdef CONFIG_CPU_ICACHE_ENABLE
-+ .ascii "i"
-+#endif
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ .ascii "d"
-+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-+ .ascii "(wt)"
-+#endif
-+#ifdef CONFIG_CPU_DCACHE_WRITEBACK
-+ .ascii "(wb)"
-+#endif
-+#endif
-+#ifndef CONFIG_CPU_BPREDICT_DISABLE
-+ .ascii "B"
-+#endif
-+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
-+ .ascii "RR"
-+#endif
-+ .ascii "\0"
-+ .align
-+
-+ .section ".text.init", #alloc, #execinstr
-+
-+__arm1022_setup:
-+ mov r0, #0
-+ mcr p15, 0, r0, c7, c7, 0 @ invalidate I,D caches on v4
-+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
-+ mcr p15, 0, r0, c8, c7, 0 @ invalidate I,D TLBs on v4
-+ mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
-+ mov r0, #0x1f @ Domains 0, 1 = client
-+ mcr p15, 0, r0, c3, c0, 0 @ load domain access register
-+
-+ mrc p15, 0, r0, c1, c0, 0 @ Read current control register
-+/*
-+ * The only thing worth keeping from the initial control register is the endian bit
-+ */
-+
-+ and r0, r0, #0x0080 @ ........B....... Preserve endian bit, zero all others.
-+ orr r0, r0, #0x0070 @ .........111.... Set the SBO (Should Be One) bits
-+/*
-+ * Turn on what we want.
-+ */
-+ orr r0, r0, #0x0001 @ ...............M Enable MMU (Alignment is special cased elsewhere)
-+ orr r0, r0, #0x0100 @ .......S........ Enable system MMU protection
-+ orr r0, r0, #0x2000 @ ..V............. Enable high vectors
-+
-+#ifdef CONFIG_CPU_CACHE_ROUND_ROBIN
-+ orr r0, r0, #0x4000 @ .R.............. Force round-robin replacement
-+#endif
-+
-+#ifndef CONFIG_CPU_BPREDICT_DISABLE
-+ orr r0, r0, #0x0800 @ ....Z........... Enable branch prediction
-+#endif
-+
-+#ifdef CONFIG_CPU_DCACHE_ENABLE
-+ orr r0, r0, #0x0004 @ .............C.. Enable D cache
-+#endif
-+#ifndef CONFIG_CPU_WB_DISABLE
-+ orr r0, r0, #0x0008 @ ............W... Write Buffer enabled
-+#endif
-+
-+#ifdef CONFIG_CPU_ICACHE_ENABLE
-+ orr r0, r0, #0x1000 @ ...I............ Enable I Cache
-+#endif
-+
-+ mov pc, lr
-+
-+ .text
-+
-+/*
-+ * Purpose : Function pointers used to access above functions - all calls
-+ * come through these
-+ */
-+ .type arm1022_processor_functions, #object
-+arm1022_processor_functions:
-+ .word cpu_arm1022_data_abort
-+ .word cpu_arm1022_check_bugs
-+ .word cpu_arm1022_proc_init
-+ .word cpu_arm1022_proc_fin
-+ .word cpu_arm1022_reset
-+ .word cpu_arm1022_do_idle
-+
-+ /* cache */
-+ .word cpu_arm1022_cache_clean_invalidate_all
-+ .word cpu_arm1022_cache_clean_invalidate_range
-+ .word cpu_arm1022_flush_ram_page
-+
-+ /* dcache */
-+ .word cpu_arm1022_dcache_invalidate_range
-+ .word cpu_arm1022_dcache_clean_range
-+ .word cpu_arm1022_dcache_clean_page
-+ .word cpu_arm1022_dcache_clean_entry
-+
-+ /* icache */
-+ .word cpu_arm1022_icache_invalidate_range
-+ .word cpu_arm1022_icache_invalidate_page
-+
-+ /* tlb */
-+ .word cpu_arm1022_tlb_invalidate_all
-+ .word cpu_arm1022_tlb_invalidate_range
-+ .word cpu_arm1022_tlb_invalidate_page
-+
-+ /* pgtable */
-+ .word cpu_arm1022_set_pgd
-+ .word cpu_arm1022_set_pmd
-+ .word cpu_arm1022_set_pte
-+ .size arm1022_processor_functions, . - arm1022_processor_functions
-+
-+ .type cpu_arm1022_info, #object
-+cpu_arm1022_info:
-+ .long cpu_manu_name
-+ .long cpu_arm1022_name
-+ .size cpu_arm1022_info, . - cpu_arm1022_info
-+
-+ .type cpu_arch_name, #object
-+cpu_arch_name:
-+ .asciz "armv5t"
-+ .size cpu_arch_name, . - cpu_arch_name
-+
-+ .type cpu_elf_name, #object
-+cpu_elf_name:
-+ .asciz "v5"
-+ .size cpu_elf_name, . - cpu_elf_name
-+ .align
-+
-+ .section ".proc.info", #alloc, #execinstr
-+
-+ .type __arm1022_proc_info,#object
-+__arm1022_proc_info:
-+ .long 0x4100a220 @ ARM 1022
-+ .long 0xff00fff0
-+ .long 0x00000c1e @ mmuflags
-+ b __arm1022_setup
-+ .long cpu_arch_name
-+ .long cpu_elf_name
-+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_THUMB
-+ .long cpu_arm1022_info
-+ .long arm1022_processor_functions
-+ .size __arm1022_proc_info, . - __arm1022_proc_info
---- linux-2.4.25/arch/arm/mm/proc-arm1026.S~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/proc-arm1026.S 2004-03-31 17:15:09.000000000 +0200
-@@ -66,19 +66,24 @@
- *
- * Returns:
- * r0 = address of abort
-- * r1 != 0 if writing
-- * r3 = FSR
-+ * r1 = FSR, bit 11 set if writing
-+ * r3 = corrupted
- * r4 = corrupted
- */
- .align 5
- ENTRY(cpu_arm1026_data_abort)
-- mrc p15, 0, r3, c5, c0, 0 @ get FSR
-- and r2, r3, #0b1101 @ Check for translation error
-- sub r1, r2, #0b0101
--
-- and r3, r3, #255
-+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
- mrc p15, 0, r0, c6, c0, 0 @ get FAR
--
-+ bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
-+ tst r3, #PSR_J_BIT @ Java?
-+ orrne r1, r1, #1 << 11 @ always assume write
-+ movne pc, lr
-+ tst r3, #PSR_T_BIT
-+ ldrneh r3, [r2] @ read aborted thumb instruction
-+ ldreq r3, [r2] @ read aborted ARM instruction
-+ movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20
-+ tst r3, #1 << 20 @ check write
-+ orreq r1, r1, #1 << 11
- mov pc, lr
-
- /*
-@@ -254,7 +259,7 @@
- */
- .align 5
- ENTRY(cpu_arm1026_dcache_invalidate_range)
--#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- tst r0, #DCACHELINESIZE - 1
- mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
- tst r1, #DCACHELINESIZE - 1
-@@ -279,7 +284,7 @@
- */
- .align 5
- ENTRY(cpu_arm1026_dcache_clean_range)
--#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- bic r0, r0, #DCACHELINESIZE - 1
- sub r3, r1, r0
- cmp r3, #MAX_AREA_SIZE
-@@ -309,7 +314,7 @@
- */
- .align 5
- ENTRY(cpu_arm1026_dcache_clean_page)
--#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- mov r1, #PAGESIZE
- 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- add r0, r0, #DCACHELINESIZE
-@@ -330,7 +335,7 @@
- */
- .align 5
- ENTRY(cpu_arm1026_dcache_clean_entry)
--#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- #endif
- mcr p15, 0, r0, c7, c10, 4 @ drain WB
-@@ -473,7 +478,7 @@
- biceq r1, r1, #4 @ clear bufferable bit
- #endif
- str r1, [r0]
--#ifndef CONFIG_CPU_ARM1026_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- #endif
- mcr p15, 0, r0, c7, c10, 4 @ drain WB
-@@ -494,7 +499,7 @@
- bic r2, r2, #3
- orr r2, r2, #HPTE_TYPE_SMALL
-
-- tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
-+ tst r1, #LPTE_USER @ User?
- orrne r2, r2, #HPTE_AP_READ
-
- tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
-@@ -634,12 +639,12 @@
-
- .type cpu_arch_name, #object
- cpu_arch_name:
-- .asciz "armv5EJ"
-+ .asciz "armv5tej"
- .size cpu_arch_name, . - cpu_arch_name
-
- .type cpu_elf_name, #object
- cpu_elf_name:
-- .asciz "v5EJ"
-+ .asciz "v5"
- .size cpu_elf_name, . - cpu_elf_name
- .align
-
---- linux-2.4.25/arch/arm/mm/proc-arm6,7.S~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/proc-arm6,7.S 2004-03-31 17:15:09.000000000 +0200
-@@ -72,7 +72,7 @@
- 1: mcr p15, 0, r0, c6, c0, 0 @ purge TLB
- add r0, r0, #4096
- cmp r0, r1
-- blt 1b
-+ blo 1b
- mov pc, lr
-
- ENTRY(cpu_arm7_tlb_invalidate_range)
-@@ -85,7 +85,7 @@
- 1: mcr p15, 0, r0, c6, c0, 0 @ purge TLB
- add r0, r0, #0x4000
- cmp r0, r1
-- blt 1b
-+ blo 1b
- mov pc, lr
- #endif
-
-@@ -110,15 +110,13 @@
- * Purpose : obtain information about current aborted instruction
- *
- * Returns : r0 = address of abort
-- * : r1 != 0 if writing
-- * : r3 = FSR
-+ * : r1 = FSR, bit 11 set if writing
-+ * : r3 = corrupted
- * : sp = pointer to registers
- */
-
- ENTRY(cpu_arm6_data_abort)
- ldr r4, [r0] @ read instruction causing problem
-- tst r4, r4, lsr #21 @ C = bit 20
-- sbc r1, r1, r1 @ r1 = C - 1
- and r2, r4, #14 << 24
- teq r2, #8 << 24 @ was it ldm/stm
- bne Ldata_simple
-@@ -144,14 +142,14 @@
- addeq r7, r0, r7, lsl #2 @ Do correction (signed)
- Ldata_saver7: str r7, [sp, r5, lsr #14] @ Put register
- Ldata_simple: mrc p15, 0, r0, c6, c0, 0 @ get FAR
-- mrc p15, 0, r3, c5, c0, 0 @ get FSR
-- and r3, r3, #255
-+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
-+ bic r1, r1, #1 << 11 | 1 << 10
-+ tst r4, #1 << 20
-+ orreq r1, r1, #1 << 11
- mov pc, lr
-
- ENTRY(cpu_arm7_data_abort)
- ldr r4, [r0] @ read instruction causing problem
-- tst r4, r4, lsr #21 @ C = bit 20
-- sbc r1, r1, r1 @ r1 = C - 1
- and r2, r4, #15 << 24
- add pc, pc, r2, lsr #22 @ Now branch to the relevent processing routine
- movs pc, lr
-@@ -336,7 +334,7 @@
- bic r2, r2, #3
- orr r2, r2, #HPTE_TYPE_SMALL
-
-- tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
-+ tst r1, #LPTE_USER @ User?
- orrne r2, r2, #HPTE_AP_READ
-
- tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
---- linux-2.4.25/arch/arm/mm/proc-arm720.S~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/proc-arm720.S 2004-03-31 17:15:09.000000000 +0200
-@@ -97,7 +97,7 @@
- 1: mcr p15, 0, r0, c8, c7, 1 @ flush TLB (v4)
- add r0, r0, #PAGESIZE
- cmp r0, r1
-- blt 1b
-+ blo 1b
- mov pc, lr
-
- /*
-@@ -124,8 +124,8 @@
- * picture. Unfortunately, this does happen. We live with it.
- *
- * Returns : r0 = address of abort
-- * : r1 != 0 if writing
-- * : r3 = FSR
-+ * : r1 = FSR, bit 11 set if writing
-+ * : r3 = corrupted
- * : sp = pointer to registers
- */
-
-@@ -150,16 +150,16 @@
- addeq r7, r0, r7, lsl #2 @ Do correction (signed)
- Ldata_saver7: str r7, [sp, r5, lsr #14] @ Put register
- Ldata_simple: mrc p15, 0, r0, c6, c0, 0 @ get FAR
-- mrc p15, 0, r3, c5, c0, 0 @ get FSR
-- and r3, r3, #255
-+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
-+ bic r1, r1, #1 << 11 | 1 << 10
-+ tst r4, #1 << 20
-+ orreq r1, r1, #1 << 11
- mov pc, lr
-
- ENTRY(cpu_arm720_data_abort)
-- tst r3, #T_BIT
-+ tst r3, #PSR_T_BIT
- bne .data_thumb_abort
-- ldr r4, [r0] @ read instruction causing problem
-- tst r4, r4, lsr #21 @ C = bit 20
-- sbc r1, r1, r1 @ r1 = C - 1
-+ ldr r4, [r2] @ read instruction causing problem
- and r2, r4, #15 << 24
- add pc, pc, r2, lsr #22 @ Now branch to the relevent processing routine
- movs pc, lr
-@@ -270,9 +270,9 @@
- b Ldata_saver7
-
- .data_thumb_abort:
-- ldrh r4, [r0] @ read instruction
-- tst r4, r4, lsr #12 @ C = bit 11
-- sbc r1, r1, r1 @ r1 = C - 1
-+ ldrh r4, [r2] @ read instruction
-+ tst r4, #1 << 11
-+ orrne r4, r4, #1 << 20
- and r2, r4, #15 << 12
- add pc, pc, r2, lsr #10 @ lookup in table
- nop
-@@ -318,8 +318,8 @@
- and r0, r0, #15 @ number of regs to transfer
- ldr r7, [sp, #13 << 2]
- tst r4, #1 << 11
-- addne r7, r7, r0, lsl #2 @ increment SP if PUSH
-- subeq r7, r7, r0, lsr #2 @ decrement SP if POP
-+ addeq r7, r7, r0, lsl #2 @ increment SP if PUSH
-+ subne r7, r7, r0, lsl #2 @ decrement SP if POP
- str r7, [sp, #13 << 2]
- b Ldata_simple
-
-@@ -336,7 +336,7 @@
- and r0, r0, #15 @ number of regs to transfer
- and r5, r4, #7 << 8
- ldr r7, [sp, r5, lsr #6]
-- sub r7, r7, r0, lsr #2 @ always decrement
-+ sub r7, r7, r0, lsl #2 @ always decrement
- str r7, [sp, r5, lsr #6]
- b Ldata_simple
-
-@@ -418,7 +418,7 @@
- bic r2, r2, #3
- orr r2, r2, #HPTE_TYPE_SMALL
-
-- tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
-+ tst r1, #LPTE_USER @ User?
- orrne r2, r2, #HPTE_AP_READ
-
- tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
---- linux-2.4.25/arch/arm/mm/proc-arm920.S~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/proc-arm920.S 2004-03-31 17:15:09.000000000 +0200
-@@ -71,12 +71,16 @@
- */
- .align 5
- ENTRY(cpu_arm920_data_abort)
-- mrc p15, 0, r3, c5, c0, 0 @ get FSR
-+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
- mrc p15, 0, r0, c6, c0, 0 @ get FAR
-- ldr r1, [r2] @ read aborted instruction
-- and r3, r3, #255
-- tst r1, r1, lsr #21 @ C = bit 20
-- sbc r1, r1, r1 @ r1 = C - 1
-+
-+ tst r3, #PSR_T_BIT
-+ ldrneh r3, [r2] @ read aborted thumb instruction
-+ ldreq r3, [r2] @ read aborted ARM instruction
-+ bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
-+ movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20
-+ tst r3, #1 << 20 @ check write
-+ orreq r1, r1, #1 << 11
- mov pc, lr
-
- /*
-@@ -186,10 +190,9 @@
- .align 5
- ENTRY(cpu_arm920_cache_clean_invalidate_range)
- bic r0, r0, #DCACHELINESIZE - 1 @ && added by PGM
-- bic r1, r1, #DCACHELINESIZE - 1 @ && added by DHM
- sub r3, r1, r0
- cmp r3, #MAX_AREA_SIZE
-- bgt cpu_arm920_cache_clean_invalidate_all_r2
-+ bhi cpu_arm920_cache_clean_invalidate_all_r2
- 1: teq r2, #0
- #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
- mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
-@@ -207,7 +210,7 @@
- add r0, r0, #DCACHELINESIZE
- #endif
- cmp r0, r1
-- blt 1b
-+ blo 1b
-
- mcr p15, 0, r1, c7, c10, 4 @ drain WB
- mov pc, lr
-@@ -253,18 +256,17 @@
- */
- .align 5
- ENTRY(cpu_arm920_dcache_invalidate_range)
--#ifndef CONFIG_CPU_ARM920_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- tst r0, #DCACHELINESIZE - 1
- mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
- tst r1, #DCACHELINESIZE - 1
- mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
- #endif @ clean D entry
- bic r0, r0, #DCACHELINESIZE - 1
-- bic r1, r1, #DCACHELINESIZE - 1
- 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
- add r0, r0, #DCACHELINESIZE
- cmp r0, r1
-- blt 1b
-+ blo 1b
- mov pc, lr
-
- /*
-@@ -279,20 +281,17 @@
- */
- .align 5
- ENTRY(cpu_arm920_dcache_clean_range)
--#ifndef CONFIG_CPU_ARM920_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- bic r0, r0, #DCACHELINESIZE - 1
- sub r1, r1, r0
- cmp r1, #MAX_AREA_SIZE
- mov r2, #0
-- bgt cpu_arm920_cache_clean_invalidate_all_r2
--
-- bic r1, r1, #DCACHELINESIZE -1
-- add r1, r1, #DCACHELINESIZE
-+ bhi cpu_arm920_cache_clean_invalidate_all_r2
-
- 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- add r0, r0, #DCACHELINESIZE
- subs r1, r1, #DCACHELINESIZE
-- bpl 1b
-+ bcs 1b
- #endif
- mcr p15, 0, r2, c7, c10, 4 @ drain WB
- mov pc, lr
-@@ -312,7 +311,7 @@
- */
- .align 5
- ENTRY(cpu_arm920_dcache_clean_page)
--#ifndef CONFIG_CPU_ARM920_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- mov r1, #PAGESIZE
- 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- add r0, r0, #DCACHELINESIZE
-@@ -333,7 +332,7 @@
- */
- .align 5
- ENTRY(cpu_arm920_dcache_clean_entry)
--#ifndef CONFIG_CPU_ARM920_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- #endif
- mcr p15, 0, r0, c7, c10, 4 @ drain WB
-@@ -365,16 +364,13 @@
- bic r0, r0, #ICACHELINESIZE - 1 @ Safety check
- sub r1, r1, r0
- cmp r1, #MAX_AREA_SIZE
-- bgt cpu_arm920_cache_clean_invalidate_all_r2
--
-- bic r1, r1, #ICACHELINESIZE - 1
-- add r1, r1, #ICACHELINESIZE
-+ bhi cpu_arm920_cache_clean_invalidate_all_r2
-
- 1: mcr p15, 0, r0, c7, c5, 1 @ Clean I entry
- mcr p15, 0, r0, c7, c10, 1 @ Clean D entry
- add r0, r0, #ICACHELINESIZE
- subs r1, r1, #ICACHELINESIZE
-- bne 1b
-+ bcs 1b
-
- mov r0, #0
- mcr p15, 0, r0, c7, c10, 4 @ drain WB
-@@ -418,13 +414,12 @@
- mov r3, #PAGESIZE
- sub r3, r3, #1
- bic r0, r0, r3
-- bic r1, r1, r3
-
- 1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
- mcr p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
- add r0, r0, #PAGESIZE
- cmp r0, r1
-- blt 1b
-+ blo 1b
- mov pc, lr
-
- /*
-@@ -457,7 +452,6 @@
- ENTRY(cpu_arm920_set_pgd)
- mov ip, #0
- #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
-- /* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */
- mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
- #else
- @ && 'Clean & Invalidate whole DCache'
-@@ -514,7 +508,7 @@
- bic r2, r2, #3
- orr r2, r2, #HPTE_TYPE_SMALL
-
-- tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
-+ tst r1, #LPTE_USER @ User?
- orrne r2, r2, #HPTE_AP_READ
-
- tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
---- linux-2.4.25/arch/arm/mm/proc-arm922.S~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/proc-arm922.S 2004-03-31 17:15:09.000000000 +0200
-@@ -62,17 +62,20 @@
- *
- * Returns:
- * r0 = address of abort
-- * r1 != 0 if writing
-- * r3 = FSR
-+ * r1 = FSR, bit 11 set if writing
-+ * r3 = corrupted
- */
- .align 5
- ENTRY(cpu_arm922_data_abort)
-- ldr r1, [r0] @ read aborted instruction
-+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
- mrc p15, 0, r0, c6, c0, 0 @ get FAR
-- tst r1, r1, lsr #21 @ C = bit 20
-- mrc p15, 0, r3, c5, c0, 0 @ get FSR
-- sbc r1, r1, r1 @ r1 = C - 1
-- and r3, r3, #255
-+ tst r3, #PSR_T_BIT
-+ ldrneh r3, [r2] @ read aborted thumb instruction
-+ ldreq r3, [r2] @ read aborted ARM instruction
-+ bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
-+ movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20
-+ tst r3, #1 << 20 @ check write
-+ orreq r1, r1, #1 << 11
- mov pc, lr
-
- /*
-@@ -185,7 +188,7 @@
- bic r1, r1, #DCACHELINESIZE - 1 @ && added by DHM
- sub r3, r1, r0
- cmp r3, #MAX_AREA_SIZE
-- bgt cpu_arm922_cache_clean_invalidate_all_r2
-+ bhi cpu_arm922_cache_clean_invalidate_all_r2
- 1: teq r2, #0
- #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
- mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
-@@ -203,7 +206,7 @@
- add r0, r0, #DCACHELINESIZE
- #endif
- cmp r0, r1
-- blt 1b
-+ blo 1b
-
- mcr p15, 0, r1, c7, c10, 4 @ drain WB
- mov pc, lr
-@@ -249,7 +252,7 @@
- */
- .align 5
- ENTRY(cpu_arm922_dcache_invalidate_range)
--#ifndef CONFIG_CPU_ARM922_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- tst r0, #DCACHELINESIZE - 1
- mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
- tst r1, #DCACHELINESIZE - 1
-@@ -260,7 +263,7 @@
- 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
- add r0, r0, #DCACHELINESIZE
- cmp r0, r1
-- blt 1b
-+ blo 1b
- mov pc, lr
-
- /*
-@@ -275,12 +278,12 @@
- */
- .align 5
- ENTRY(cpu_arm922_dcache_clean_range)
--#ifndef CONFIG_CPU_ARM922_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- bic r0, r0, #DCACHELINESIZE - 1
- sub r1, r1, r0
- cmp r1, #MAX_AREA_SIZE
- mov r2, #0
-- bgt cpu_arm922_cache_clean_invalidate_all_r2
-+ bhi cpu_arm922_cache_clean_invalidate_all_r2
-
- bic r1, r1, #DCACHELINESIZE -1
- add r1, r1, #DCACHELINESIZE
-@@ -308,7 +311,7 @@
- */
- .align 5
- ENTRY(cpu_arm922_dcache_clean_page)
--#ifndef CONFIG_CPU_ARM922_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- mov r1, #PAGESIZE
- 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- add r0, r0, #DCACHELINESIZE
-@@ -329,7 +332,7 @@
- */
- .align 5
- ENTRY(cpu_arm922_dcache_clean_entry)
--#ifndef CONFIG_CPU_ARM922_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- #endif
- mcr p15, 0, r0, c7, c10, 4 @ drain WB
-@@ -361,7 +364,7 @@
- bic r0, r0, #ICACHELINESIZE - 1 @ Safety check
- sub r1, r1, r0
- cmp r1, #MAX_AREA_SIZE
-- bgt cpu_arm922_cache_clean_invalidate_all_r2
-+ bhi cpu_arm922_cache_clean_invalidate_all_r2
-
- bic r1, r1, #ICACHELINESIZE - 1
- add r1, r1, #ICACHELINESIZE
-@@ -420,7 +423,7 @@
- mcr p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
- add r0, r0, #PAGESIZE
- cmp r0, r1
-- blt 1b
-+ blo 1b
- mov pc, lr
-
- /*
-@@ -510,7 +513,7 @@
- bic r2, r2, #3
- orr r2, r2, #HPTE_TYPE_SMALL
-
-- tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
-+ tst r1, #LPTE_USER @ User?
- orrne r2, r2, #HPTE_AP_READ
-
- tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
---- linux-2.4.25/arch/arm/mm/proc-arm925.S~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/proc-arm925.S 2004-03-31 17:15:09.000000000 +0200
-@@ -69,24 +69,24 @@
- *
- * Returns:
- * r0 = address of abort
-- * r1 != 0 if writing
-- * r3 = FSR
-+ * r1 = FSR, bit 11 set if writing
-+ * r3 = corrupted
- * r4 = corrupted
- */
- .align 5
- ENTRY(cpu_arm925_data_abort)
-+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
- mrc p15, 0, r0, c6, c0, 0 @ get FAR
-- mrc p15, 0, r4, c5, c0, 0 @ get FSR
--
-- tst r3, #1<<5 @ Check for Thumb-bit (NE -> found)
-- ldrneh r1, [r2] @ Read aborted Thumb instruction
-- tstne r1, r1, lsr #12 @ C = bit 11
--
-- ldreq r1, [r2] @ Read aborted ARM instruction
-- tsteq r1, r1, lsr #21 @ C = bit 20
--
-- sbc r1, r1, r1 @ r1 = C - 1
-- and r3, r4, #255
-+ bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
-+ tst r3, #PSR_J_BIT @ Java?
-+ orrne r1, r1, #1 << 11 @ always assume write
-+ movne pc, lr
-+ tst r3, #PSR_T_BIT @ Thumb?
-+ ldrneh r3, [r2] @ read aborted thumb instruction
-+ ldreq r3, [r2] @ read aborted ARM instruction
-+ movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20
-+ tst r3, #1 << 20 @ L = 0 -> write
-+ orreq r1, r1, #1 << 11 @ yes.
- mov pc, lr
-
- /*
-@@ -207,7 +207,7 @@
- bic r1, r1, #DCACHELINESIZE - 1 @ && added by DHM
- sub r3, r1, r0
- cmp r3, #MAX_AREA_SIZE
-- bgt cpu_arm925_cache_clean_invalidate_all_r2
-+ bhi cpu_arm925_cache_clean_invalidate_all_r2
- 1: teq r2, #0
- #ifdef CONFIG_CPU_ARM925_WRITETHROUGH
- mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
-@@ -225,7 +225,7 @@
- add r0, r0, #DCACHELINESIZE
- #endif
- cmp r0, r1
-- blt 1b
-+ blo 1b
-
- mcr p15, 0, r1, c7, c10, 4 @ drain WB
- mov pc, lr
-@@ -282,7 +282,7 @@
- 1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
- add r0, r0, #DCACHELINESIZE
- cmp r0, r1
-- blt 1b
-+ blo 1b
- mov pc, lr
-
- /*
-@@ -302,7 +302,7 @@
- sub r1, r1, r0
- cmp r1, #MAX_AREA_SIZE
- mov r2, #0
-- bgt cpu_arm925_cache_clean_invalidate_all_r2
-+ bhi cpu_arm925_cache_clean_invalidate_all_r2
-
- bic r1, r1, #DCACHELINESIZE -1
- add r1, r1, #DCACHELINESIZE
-@@ -383,7 +383,7 @@
- bic r0, r0, #ICACHELINESIZE - 1 @ Safety check
- sub r1, r1, r0
- cmp r1, #MAX_AREA_SIZE
-- bgt cpu_arm925_cache_clean_invalidate_all_r2
-+ bhi cpu_arm925_cache_clean_invalidate_all_r2
-
- bic r1, r1, #ICACHELINESIZE - 1
- add r1, r1, #ICACHELINESIZE
-@@ -443,7 +443,7 @@
- mcr p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
- add r0, r0, #PAGESIZE
- cmp r0, r1
-- blt 1b
-+ blo 1b
- mov pc, lr
-
- /*
-@@ -532,7 +532,7 @@
- bic r2, r2, #3
- orr r2, r2, #HPTE_TYPE_SMALL
-
-- tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
-+ tst r1, #LPTE_USER @ User?
- orrne r2, r2, #HPTE_AP_READ
-
- tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
---- linux-2.4.25/arch/arm/mm/proc-arm926.S~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/proc-arm926.S 2004-03-31 17:15:09.000000000 +0200
-@@ -66,28 +66,24 @@
- *
- * Returns:
- * r0 = address of abort
-- * r1 != 0 if writing
-- * r3 = FSR
-+ * r1 = FSR, bit 11 set if writing
-+ * r3 = corrupted
- * r4 = corrupted
- */
- .align 5
- ENTRY(cpu_arm926_data_abort)
-+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
- mrc p15, 0, r0, c6, c0, 0 @ get FAR
-- mrc p15, 0, r4, c5, c0, 0 @ get FSR
--
-- tst r3, #1<<24 @ Check for Jbit (NE -> found)
-- movne r3, #-1 @ Mark as writing
-- bne 2f
--
-- tst r3, #1<<5 @ Check for Thumb-bit (NE -> found)
-- ldrneh r1, [r2] @ Read aborted Thumb instruction
-- ldreq r1, [r2] @ Read aborted ARM instruction
-- movne r1, r1, lsl #(20-12) @ shift thumb bit 10 to ARM bit 20
-- tsteq r1, r1, lsr #21 @ C = bit 20
--
-- sbc r1, r1, r1 @ r1 = C - 1
--2:
-- and r3, r4, #255
-+ bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
-+ tst r3, #PSR_J_BIT @ Java?
-+ orrne r1, r1, #1 << 11 @ always assume write
-+ movne pc, lr
-+ tst r3, #PSR_T_BIT @ Thumb?
-+ ldrneh r3, [r2] @ read aborted thumb instruction
-+ ldreq r3, [r2] @ read aborted ARM instruction
-+ movne r3, r3, lsl #(21 - 12) @ move thumb bit 11 to ARM bit 20
-+ tst r3, #1 << 20 @ L = 0 -> write
-+ orreq r1, r1, #1 << 11 @ yes.
- mov pc, lr
-
- /*
-@@ -263,7 +259,7 @@
- */
- .align 5
- ENTRY(cpu_arm926_dcache_invalidate_range)
--#ifndef CONFIG_CPU_ARM926_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- tst r0, #DCACHELINESIZE - 1
- mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
- tst r1, #DCACHELINESIZE - 1
-@@ -288,7 +284,7 @@
- */
- .align 5
- ENTRY(cpu_arm926_dcache_clean_range)
--#ifndef CONFIG_CPU_ARM926_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- bic r0, r0, #DCACHELINESIZE - 1
- sub r3, r1, r0
- cmp r3, #MAX_AREA_SIZE
-@@ -318,7 +314,7 @@
- */
- .align 5
- ENTRY(cpu_arm926_dcache_clean_page)
--#ifndef CONFIG_CPU_ARM926_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- mov r1, #PAGESIZE
- 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- add r0, r0, #DCACHELINESIZE
-@@ -339,7 +335,7 @@
- */
- .align 5
- ENTRY(cpu_arm926_dcache_clean_entry)
--#ifndef CONFIG_CPU_ARM926_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- #endif
- mcr p15, 0, r0, c7, c10, 4 @ drain WB
-@@ -482,7 +478,7 @@
- biceq r1, r1, #4 @ clear bufferable bit
- #endif
- str r1, [r0]
--#ifndef CONFIG_CPU_ARM926_WRITETHROUGH
-+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH
- mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- #endif
- mcr p15, 0, r0, c7, c10, 4 @ drain WB
-@@ -503,7 +499,7 @@
- bic r2, r2, #3
- orr r2, r2, #HPTE_TYPE_SMALL
-
-- tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
-+ tst r1, #LPTE_USER @ User?
- orrne r2, r2, #HPTE_AP_READ
-
- tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
---- linux-2.4.25/arch/arm/mm/proc-sa110.S~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/mm/proc-sa110.S 2004-03-31 17:15:09.000000000 +0200
-@@ -86,12 +86,12 @@
- .align 5
- ENTRY(cpu_sa110_data_abort)
- ENTRY(cpu_sa1100_data_abort)
-- mrc p15, 0, r3, c5, c0, 0 @ get FSR
-+ mrc p15, 0, r1, c5, c0, 0 @ get FSR
- mrc p15, 0, r0, c6, c0, 0 @ get FAR
-- ldr r1, [r2] @ read aborted instruction
-- and r3, r3, #255
-- tst r1, r1, lsr #21 @ C = bit 20
-- sbc r1, r1, r1 @ r1 = C - 1
-+ ldr r3, [r2] @ read aborted instruction
-+ bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR
-+ tst r3, #1 << 20 @ check write
-+ orreq r1, r1, #1 << 11
- mov pc, lr
-
- /*
-@@ -551,7 +551,7 @@
- bic r2, r2, #3
- orr r2, r2, #HPTE_TYPE_SMALL
-
-- tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
-+ tst r1, #LPTE_USER @ User?
- orrne r2, r2, #HPTE_AP_READ
-
- tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
---- linux-2.4.25/arch/arm/tools/mach-types~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/arm/tools/mach-types 2004-03-31 17:15:09.000000000 +0200
-@@ -6,7 +6,7 @@
- # To add an entry into this database, please see Documentation/arm/README,
- # or contact rmk@arm.linux.org.uk
- #
--# Last update: Sat Jun 28 12:10:54 2003
-+# Last update: Tue Feb 10 17:10:34 2004
- #
- # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
- #
-@@ -202,7 +202,7 @@
- fester SA1100_FESTER FESTER 191
- gpi ARCH_GPI GPI 192
- smdk2410 ARCH_SMDK2410 SMDK2410 193
--premium ARCH_PREMIUM PREMIUM 194
-+i519 ARCH_I519 I519 194
- nexio SA1100_NEXIO NEXIO 195
- bitbox SA1100_BITBOX BITBOX 196
- g200 SA1100_G200 G200 197
-@@ -228,7 +228,7 @@
- arnold SA1100_ARNOLD ARNOLD 217
- psiboard SA1100_PSIBOARD PSIBOARD 218
- jz8028 ARCH_JZ8028 JZ8028 219
--h5400 ARCH_IPAQ3 IPAQ3 220
-+h5400 ARCH_H5400 H5400 220
- forte SA1100_FORTE FORTE 221
- acam SA1100_ACAM ACAM 222
- abox SA1100_ABOX ABOX 223
-@@ -259,7 +259,7 @@
- stork_egg ARCH_STORK_EGG STORK_EGG 248
- wismo SA1100_WISMO WISMO 249
- ezlinx ARCH_EZLINX EZLINX 250
--at91rm9200 ARCH_AT91 AT91 251
-+at91rm9200 ARCH_AT91RM9200 AT91RM9200 251
- orion ARCH_ORION ORION 252
- neptune ARCH_NEPTUNE NEPTUNE 253
- hackkit SA1100_HACKKIT HACKKIT 254
-@@ -300,7 +300,7 @@
- inhandelf3 ARCH_INHANDELF3 INHANDELF3 289
- adi_coyote ARCH_ADI_COYOTE ADI_COYOTE 290
- iyonix ARCH_IYONIX IYONIX 291
--damicam_sa1110 ARCH_DAMICAM_SA1110 DAMICAM_SA1110 292
-+damicam1 ARCH_DAMICAM_SA1110 DAMICAM_SA1110 292
- meg03 ARCH_MEG03 MEG03 293
- pxa_whitechapel ARCH_PXA_WHITECHAPEL PXA_WHITECHAPEL 294
- nwsc ARCH_NWSC NWSC 295
-@@ -356,3 +356,111 @@
- seedpxa_c2 ARCH_SEEDPXA_C2 SEEDPXA_C2 345
- ixp4xx_mguardpci ARCH_IXP4XX_MGUARD_PCI IXP4XX_MGUARD_PCI 346
- h1940 ARCH_H1940 H1940 347
-+scorpio ARCH_SCORPIO SCORPIO 348
-+viva ARCH_VIVA VIVA 349
-+pxa_xcard ARCH_PXA_XCARD PXA_XCARD 350
-+csb335 ARCH_CSB335 CSB335 351
-+ixrd425 ARCH_IXRD425 IXRD425 352
-+iq80315 ARCH_IQ80315 IQ80315 353
-+nmp7312 ARCH_NMP7312 NMP7312 354
-+cx861xx ARCH_CX861XX CX861XX 355
-+enp2611 ARCH_ENP2611 ENP2611 356
-+xda SA1100_XDA XDA 357
-+csir_ims ARCH_CSIR_IMS CSIR_IMS 358
-+ixp421_dnaeeth ARCH_IXP421_DNAEETH IXP421_DNAEETH 359
-+pocketserv9200 ARCH_POCKETSERV9200 POCKETSERV9200 360
-+toto ARCH_TOTO TOTO 361
-+s3c2440 ARCH_S3C2440 S3C2440 362
-+ks8695p ARCH_KS8695P KS8695P 363
-+se4000 ARCH_SE4000 SE4000 364
-+quadriceps ARCH_QUADRICEPS QUADRICEPS 365
-+bronco ARCH_BRONCO BRONCO 366
-+esl_wireless_tab ARCH_ESL_WIRELESS_TABLETESL_WIRELESS_TABLET 367
-+esl_sofcomp ARCH_ESL_SOFCOMP ESL_SOFCOMP 368
-+s5c7375 ARCH_S5C7375 S5C7375 369
-+spearhead ARCH_SPEARHEAD SPEARHEAD 370
-+pantera ARCH_PANTERA PANTERA 371
-+prayoglite ARCH_PRAYOGLITE PRAYOGLITE 372
-+gumstik ARCH_GUMSTIK GUMSTIK 373
-+rcube ARCH_RCUBE RCUBE 374
-+rea_olv ARCH_REA_OLV REA_OLV 375
-+pxa_iphone ARCH_PXA_IPHONE PXA_IPHONE 376
-+s3c3410 ARCH_S3C3410 S3C3410 377
-+espd_4510b ARCH_ESPD_4510B ESPD_4510B 378
-+mp1x ARCH_MP1X MP1X 379
-+at91rm9200tb ARCH_AT91RM9200TB AT91RM9200TB 380
-+adsvgx ARCH_ADSVGX ADSVGX 381
-+omap1610 ARCH_OMAP1610 OMAP1610 382
-+pelee ARCH_PELEE PELEE 383
-+e7xx ARCH_E7XX E7XX 384
-+iq80331 ARCH_IQ80331 IQ80331 385
-+versatile_pb ARCH_VERSATILE_PB VERSATILE_PB 387
-+kev7a400 MACH_KEV7A400 KEV7A400 388
-+lpd7a400 MACH_LPD7A400 LPD7A400 389
-+lpd7a404 MACH_LPD7A404 LPD7A404 390
-+fujitsu_camelot ARCH_FUJITSU_CAMELOT FUJITSU_CAMELOT 391
-+janus2m ARCH_JANUS2M JANUS2M 392
-+embtf MACH_EMBTF EMBTF 393
-+hpm MACH_HPM HPM 394
-+smdk2410tk MACH_SMDK2410TK SMDK2410TK 395
-+smdk2410aj MACH_SMDK2410AJ SMDK2410AJ 396
-+streetracer MACH_STREETRACER STREETRACER 397
-+eframe MACH_EFRAME EFRAME 398
-+csb337 MACH_CSB337 CSB337 399
-+pxa_lark MACH_PXA_LARK PXA_LARK 400
-+pxa_pnp2110 MACH_PNP2110 PNP2110 401
-+tcc72x MACH_TCC72X TCC72X 402
-+altair MACH_ALTAIR ALTAIR 403
-+kc3 MACH_KC3 KC3 404
-+sinteftd MACH_SINTEFTD SINTEFTD 405
-+mainstone MACH_MAINSTONE MAINSTONE 406
-+aday4x MACH_ADAY4X ADAY4X 407
-+lite300 MACH_LITE300 LITE300 408
-+s5c7376 MACH_S5C7376 S5C7376 409
-+mt02 MACH_MT02 MT02 410
-+mport3s MACH_MPORT3S MPORT3S 411
-+ra_alpha MACH_RA_ALPHA RA_ALPHA 412
-+xcep MACH_XCEP XCEP 413
-+arcom_mercury MACH_ARCOM_MERCURY ARCOM_MERCURY 414
-+stargate MACH_STARGATE STARGATE 415
-+armadilloj MACH_ARMADILLOJ ARMADILLOJ 416
-+elroy_jack MACH_ELROY_JACK ELROY_JACK 417
-+backend MACH_BACKEND BACKEND 418
-+s5linbox MACH_S5LINBOX S5LINBOX 419
-+nomadik MACH_NOMADIK NOMADIK 420
-+ia_cpu_9200 MACH_IA_CPU_9200 IA_CPU_9200 421
-+at91_bja1 MACH_AT91_BJA1 AT91_BJA1 422
-+corgi MACH_CORGI CORGI 423
-+poodle MACH_POODLE POODLE 424
-+ten MACH_TEN TEN 425
-+roverp5p MACH_ROVERP5P ROVERP5P 426
-+sc2700 MACH_SC2700 SC2700 427
-+ex_eagle MACH_EX_EAGLE EX_EAGLE 428
-+nx_pxa12 MACH_NX_PXA12 NX_PXA12 429
-+nx_pxa5 MACH_NX_PXA5 NX_PXA5 430
-+blackboard2 MACH_BLACKBOARD2 BLACKBOARD2 431
-+i819 MACH_I819 I819 432
-+ixmb995e MACH_IXMB995E IXMB995E 433
-+skyrider MACH_SKYRIDER SKYRIDER 434
-+skyhawk MACH_SKYHAWK SKYHAWK 435
-+enterprise MACH_ENTERPRISE ENTERPRISE 436
-+dep2410 MACH_DEP2410 DEP2410 437
-+armcore MACH_ARMCORE ARMCORE 438
-+hobbit MACH_HOBBIT HOBBIT 439
-+h7210 MACH_H7210 H7210 440
-+pxa_netdcu5 MACH_PXA_NETDCU5 PXA_NETDCU5 441
-+acc MACH_ACC ACC 442
-+esl_sarva MACH_ESL_SARVA ESL_SARVA 443
-+xm250 MACH_XM250 XM250 444
-+t6tc1xb MACH_T6TC1XB T6TC1XB 445
-+ess710 MACH_ESS710 ESS710 446
-+mx3ads MACH_MX3ADS MX3ADS 447
-+himalaya MACH_HIMALAYA HIMALAYA 448
-+bolfenk MACH_BOLFENK BOLFENK 449
-+at91rm9200kr MACH_AT91RM9200KR AT91RM9200KR 450
-+edb9312 MACH_EDB9312 EDB9312 451
-+omap_generic MACH_OMAP_GENERIC OMAP_GENERIC 452
-+aximx3 MACH_AXIMX3 AXIMX3 453
-+eb67xdip MACH_EB67XDIP EB67XDIP 454
-+webtxs MACH_WEBTXS WEBTXS 455
-+hawk MACH_HAWK HAWK 456
---- linux-2.4.25/arch/i386/config.in~2.4.25-vrs2.patch 2004-02-18 14:36:30.000000000 +0100
-+++ linux-2.4.25/arch/i386/config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -9,6 +9,7 @@
-
- define_bool CONFIG_UID16 y
-
-+define_bool CONFIG_GENERIC_ISA_DMA y
- mainmenu_option next_comment
- comment 'Code maturity level options'
- bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
---- linux-2.4.25/arch/i386/kernel/Makefile~2.4.25-vrs2.patch 2003-11-28 19:26:19.000000000 +0100
-+++ linux-2.4.25/arch/i386/kernel/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -7,8 +7,8 @@
- #
- # Note 2! The CFLAGS definitions are now in the main makefile...
-
--.S.o:
-- $(CC) $(AFLAGS) -traditional -c $< -o $*.o
-+USE_STANDARD_AS_RULE := true
-+EXTRA_AFLAGS := -traditional
-
- all: kernel.o head.o init_task.o
-
---- linux-2.4.25/arch/i386/kernel/apm.c~2.4.25-vrs2.patch 2003-08-25 13:44:39.000000000 +0200
-+++ linux-2.4.25/arch/i386/kernel/apm.c 2004-03-31 17:15:09.000000000 +0200
-@@ -1267,6 +1267,7 @@
- as->suspend_wait = 0;
- as->suspend_result = err;
- }
-+ ignore_normal_resume = 1;
- wake_up_interruptible(&apm_suspend_waitqueue);
- return err;
- }
-@@ -1319,6 +1320,8 @@
- if (ignore_bounce
- && ((jiffies - last_resume) > bounce_interval))
- ignore_bounce = 0;
-+ if (ignore_normal_resume && (event != APM_NORMAL_RESUME))
-+ ignore_normal_resume = 0;
-
- switch (event) {
- case APM_SYS_STANDBY:
---- linux-2.4.25/arch/i386/lib/Makefile~2.4.25-vrs2.patch 2001-09-10 16:31:30.000000000 +0200
-+++ linux-2.4.25/arch/i386/lib/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -2,8 +2,7 @@
- # Makefile for i386-specific library files..
- #
-
--.S.o:
-- $(CC) $(AFLAGS) -c $< -o $*.o
-+USE_STANDARD_AS_RULE := true
-
- L_TARGET = lib.a
-
---- linux-2.4.25/arch/i386/math-emu/Makefile~2.4.25-vrs2.patch 2000-12-29 23:07:20.000000000 +0100
-+++ linux-2.4.25/arch/i386/math-emu/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -2,15 +2,15 @@
- # Makefile for wm-FPU-emu
- #
-
-+USE_STANDARD_AS_RULE := true
-+
- O_TARGET := math.o
-
- #DEBUG = -DDEBUGGING
- DEBUG =
- PARANOID = -DPARANOID
- CFLAGS := $(CFLAGS) $(PARANOID) $(DEBUG) -fno-builtin $(MATH_EMULATION)
--
--.S.o:
-- $(CC) $(AFLAGS) $(PARANOID) -c $<
-+EXTRA_AFLAGS := $(PARANOID)
-
- # From 'C' language sources:
- C_OBJS =fpu_entry.o errors.o \
---- linux-2.4.25/arch/ia64/config.in~2.4.25-vrs2.patch 2004-02-18 14:36:30.000000000 +0100
-+++ linux-2.4.25/arch/ia64/config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -25,6 +25,7 @@
- define_bool CONFIG_SBUS n
- define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
- define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
-+define_bool CONFIG_GENERIC_ISA_DMA y
-
- choice 'IA-64 processor type' \
- "Itanium CONFIG_ITANIUM \
---- linux-2.4.25/arch/m68k/config.in~2.4.25-vrs2.patch 2004-02-18 14:36:30.000000000 +0100
-+++ linux-2.4.25/arch/m68k/config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -6,6 +6,7 @@
- define_bool CONFIG_UID16 y
- define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
- define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
-+define_bool CONFIG_GENERIC_ISA_DMA y
-
- mainmenu_name "Linux/68k Kernel Configuration"
-
---- linux-2.4.25/arch/mips/config.in~2.4.25-vrs2.patch 2002-11-29 00:53:09.000000000 +0100
-+++ linux-2.4.25/arch/mips/config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -5,5 +5,6 @@
- define_bool CONFIG_MIPS y
- define_bool CONFIG_MIPS32 y
- define_bool CONFIG_MIPS64 n
-+define_bool CONFIG_GENERIC_ISA_DMA y
-
- source arch/mips/config-shared.in
---- linux-2.4.25/arch/parisc/config.in~2.4.25-vrs2.patch 2004-02-18 14:36:30.000000000 +0100
-+++ linux-2.4.25/arch/parisc/config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -9,6 +9,7 @@
- define_bool CONFIG_UID16 n
- define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
- define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
-+define_bool CONFIG_GENERIC_ISA_DMA y
-
- mainmenu_option next_comment
- comment 'Code maturity level options'
---- linux-2.4.25/arch/ppc/config.in~2.4.25-vrs2.patch 2004-02-18 14:36:30.000000000 +0100
-+++ linux-2.4.25/arch/ppc/config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -6,6 +6,7 @@
- define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
- define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
- define_bool CONFIG_HAVE_DEC_LOCK y
-+define_bool CONFIG_GENERIC_ISA_DMA y
-
- mainmenu_name "Linux/PowerPC Kernel Configuration"
-
---- linux-2.4.25/arch/sh/config.in~2.4.25-vrs2.patch 2004-02-18 14:36:30.000000000 +0100
-+++ linux-2.4.25/arch/sh/config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -9,6 +9,7 @@
- define_bool CONFIG_UID16 y
- define_bool CONFIG_RWSEM_GENERIC_SPINLOCK y
- define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n
-+define_bool CONFIG_GENERIC_ISA_DMA y
-
- mainmenu_option next_comment
- comment 'Code maturity level options'
---- linux-2.4.25/arch/sparc/config.in~2.4.25-vrs2.patch 2004-02-18 14:36:30.000000000 +0100
-+++ linux-2.4.25/arch/sparc/config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -6,6 +6,7 @@
-
- define_bool CONFIG_UID16 y
- define_bool CONFIG_HIGHMEM y
-+define_bool CONFIG_GENERIC_ISA_DMA y
-
- mainmenu_option next_comment
- comment 'Code maturity level options'
---- linux-2.4.25/arch/sparc64/config.in~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/arch/sparc64/config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -41,6 +41,7 @@
- define_bool CONFIG_HAVE_DEC_LOCK y
- define_bool CONFIG_RWSEM_GENERIC_SPINLOCK n
- define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y
-+define_bool CONFIG_GENERIC_ISA_DMA y
- define_bool CONFIG_ISA n
- define_bool CONFIG_ISAPNP n
- define_bool CONFIG_EISA n
---- linux-2.4.25/drivers/Makefile~2.4.25-vrs2.patch 2003-11-28 19:26:19.000000000 +0100
-+++ linux-2.4.25/drivers/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -8,9 +8,9 @@
-
- mod-subdirs := dio hil mtd sbus video macintosh usb input telephony ide \
- message/i2o message/fusion scsi md ieee1394 pnp isdn atm \
-- fc4 net/hamradio i2c acpi bluetooth usb/gadget
-+ fc4 net/hamradio i2c l3 acpi bluetooth serial usb/gadget
-
--subdir-y := parport char block net sound misc media cdrom hotplug
-+subdir-y := parport serial char block net sound misc media cdrom hotplug pld
- subdir-m := $(subdir-y)
-
-
-@@ -45,8 +45,12 @@
- # CONFIG_HAMRADIO can be set without CONFIG_NETDEVICE being set -- ch
- subdir-$(CONFIG_HAMRADIO) += net/hamradio
- subdir-$(CONFIG_I2C) += i2c
-+subdir-$(CONFIG_L3) += l3
- subdir-$(CONFIG_ACPI_BOOT) += acpi
-
- subdir-$(CONFIG_BLUEZ) += bluetooth
-+subdir-$(CONFIG_SSI) += ssi
-+
-+subdir-$(CONFIG_ARCH_AT91RM9200)+= at91
-
- include $(TOPDIR)/Rules.make
---- linux-2.4.25/drivers/acorn/char/i2c.c~2.4.25-vrs2.patch 2004-01-05 14:53:56.000000000 +0100
-+++ linux-2.4.25/drivers/acorn/char/i2c.c 2004-03-31 17:15:09.000000000 +0200
-@@ -166,7 +166,6 @@
- break;
-
- case RTC_RD_TIME:
-- memset(&rtctm, 0, sizeof(struct rtc_time));
- get_rtc_time(&rtc_raw, &year);
- rtctm.tm_sec = rtc_raw.secs;
- rtctm.tm_min = rtc_raw.mins;
---- linux-2.4.25/drivers/acorn/net/ether1.c~2.4.25-vrs2.patch 2003-08-25 13:44:40.000000000 +0200
-+++ linux-2.4.25/drivers/acorn/net/ether1.c 2004-03-31 17:15:09.000000000 +0200
-@@ -80,7 +80,7 @@
- #define BUS_16 16
- #define BUS_8 8
-
--static const card_ids __init ether1_cids[] = {
-+static card_ids __initdata ether1_cids[] = {
- { MANU_ACORN, PROD_ACORN_ETHER1 },
- { 0xffff, 0xffff }
- };
---- linux-2.4.25/drivers/acorn/net/ether3.c~2.4.25-vrs2.patch 2003-08-25 13:44:40.000000000 +0200
-+++ linux-2.4.25/drivers/acorn/net/ether3.c 2004-03-31 17:15:09.000000000 +0200
-@@ -75,7 +75,7 @@
- #include "ether3.h"
-
- static unsigned int net_debug = NET_DEBUG;
--static const card_ids __init ether3_cids[] = {
-+static card_ids __initdata ether3_cids[] = {
- { MANU_ANT2, PROD_ANT_ETHER3 },
- { MANU_ANT, PROD_ANT_ETHER3 },
- { MANU_ANT, PROD_ANT_ETHERB },
---- linux-2.4.25/drivers/acorn/net/etherh.c~2.4.25-vrs2.patch 2003-08-25 13:44:40.000000000 +0200
-+++ linux-2.4.25/drivers/acorn/net/etherh.c 2004-03-31 17:15:09.000000000 +0200
-@@ -57,7 +57,7 @@
-
- static unsigned int net_debug = NET_DEBUG;
-
--static const card_ids __init etherh_cids[] = {
-+static card_ids __initdata etherh_cids[] = {
- { MANU_ANT, PROD_ANT_ETHERM },
- { MANU_I3, PROD_I3_ETHERLAN500 },
- { MANU_I3, PROD_I3_ETHERLAN600 },
---- linux-2.4.25/drivers/acorn/scsi/cumana_1.c~2.4.25-vrs2.patch 2001-09-14 00:21:32.000000000 +0200
-+++ linux-2.4.25/drivers/acorn/scsi/cumana_1.c 2004-03-31 17:15:09.000000000 +0200
-@@ -153,20 +153,20 @@
- ((struct NCR5380_hostdata *)instance->hostdata)->ctrl = 0;
- outb(0x00, instance->io_port - 577);
-
-- if (instance->irq != IRQ_NONE)
-+ if (instance->irq != SCSI_IRQ_NONE)
- if (request_irq(instance->irq, do_cumanascsi_intr, SA_INTERRUPT, "CumanaSCSI-1", NULL)) {
- printk("scsi%d: IRQ%d not free, interrupts disabled\n",
- instance->host_no, instance->irq);
-- instance->irq = IRQ_NONE;
-+ instance->irq = SCSI_IRQ_NONE;
- }
-
-- if (instance->irq == IRQ_NONE) {
-+ if (instance->irq == SCSI_IRQ_NONE) {
- printk("scsi%d: interrupts not enabled. for better interactive performance,\n", instance->host_no);
- printk("scsi%d: please jumper the board for a free IRQ.\n", instance->host_no);
- }
-
- printk("scsi%d: at port %lX irq", instance->host_no, instance->io_port);
-- if (instance->irq == IRQ_NONE)
-+ if (instance->irq == SCSI_IRQ_NONE)
- printk ("s disabled");
- else
- printk (" %d", instance->irq);
-@@ -185,7 +185,7 @@
- {
- int i;
-
-- if (shpnt->irq != IRQ_NONE)
-+ if (shpnt->irq != SCSI_IRQ_NONE)
- free_irq (shpnt->irq, NULL);
- if (shpnt->io_port)
- release_region (shpnt->io_port, shpnt->n_io_port);
---- linux-2.4.25/drivers/acorn/scsi/ecoscsi.c~2.4.25-vrs2.patch 2002-08-03 02:39:43.000000000 +0200
-+++ linux-2.4.25/drivers/acorn/scsi/ecoscsi.c 2004-03-31 17:15:09.000000000 +0200
-@@ -106,7 +106,7 @@
- instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
- instance->io_port = 0x80ce8000;
- instance->n_io_port = 144;
-- instance->irq = IRQ_NONE;
-+ instance->irq = SCSI_IRQ_NONE;
-
- if (check_region (instance->io_port, instance->n_io_port)) {
- scsi_unregister (instance);
-@@ -130,20 +130,20 @@
- return 0;
- }
-
-- if (instance->irq != IRQ_NONE)
-+ if (instance->irq != SCSI_IRQ_NONE)
- if (request_irq(instance->irq, do_ecoscsi_intr, SA_INTERRUPT, "ecoscsi", NULL)) {
- printk("scsi%d: IRQ%d not free, interrupts disabled\n",
- instance->host_no, instance->irq);
-- instance->irq = IRQ_NONE;
-+ instance->irq = SCSI_IRQ_NONE;
- }
-
-- if (instance->irq != IRQ_NONE) {
-+ if (instance->irq != SCSI_IRQ_NONE) {
- printk("scsi%d: eek! Interrupts enabled, but I don't think\n", instance->host_no);
- printk("scsi%d: that the board had an interrupt!\n", instance->host_no);
- }
-
- printk("scsi%d: at port %X irq", instance->host_no, instance->io_port);
-- if (instance->irq == IRQ_NONE)
-+ if (instance->irq == SCSI_IRQ_NONE)
- printk ("s disabled");
- else
- printk (" %d", instance->irq);
-@@ -157,7 +157,7 @@
-
- int ecoscsi_release (struct Scsi_Host *shpnt)
- {
-- if (shpnt->irq != IRQ_NONE)
-+ if (shpnt->irq != SCSI_IRQ_NONE)
- free_irq (shpnt->irq, NULL);
- if (shpnt->io_port)
- release_region (shpnt->io_port, shpnt->n_io_port);
---- linux-2.4.25/drivers/acorn/scsi/oak.c~2.4.25-vrs2.patch 2001-10-11 18:04:57.000000000 +0200
-+++ linux-2.4.25/drivers/acorn/scsi/oak.c 2004-03-31 17:15:09.000000000 +0200
-@@ -97,7 +97,7 @@
- };
-
- #define OAK_ADDRESS(card) (ecard_address((card), ECARD_MEMC, 0))
--#define OAK_IRQ(card) (IRQ_NONE)
-+#define OAK_IRQ(card) (SCSI_IRQ_NONE)
- /*
- * Function : int oakscsi_detect(Scsi_Host_Template * tpnt)
- *
-@@ -136,20 +136,20 @@
- instance->n_io_port = 255;
- request_region (instance->io_port, instance->n_io_port, "Oak SCSI");
-
-- if (instance->irq != IRQ_NONE)
-+ if (instance->irq != SCSI_IRQ_NONE)
- if (request_irq(instance->irq, do_oakscsi_intr, SA_INTERRUPT, "Oak SCSI", NULL)) {
- printk("scsi%d: IRQ%d not free, interrupts disabled\n",
- instance->host_no, instance->irq);
-- instance->irq = IRQ_NONE;
-+ instance->irq = SCSI_IRQ_NONE;
- }
-
-- if (instance->irq != IRQ_NONE) {
-+ if (instance->irq != SCSI_IRQ_NONE) {
- printk("scsi%d: eek! Interrupts enabled, but I don't think\n", instance->host_no);
- printk("scsi%d: that the board had an interrupt!\n", instance->host_no);
- }
-
- printk("scsi%d: at port %lX irq", instance->host_no, instance->io_port);
-- if (instance->irq == IRQ_NONE)
-+ if (instance->irq == SCSI_IRQ_NONE)
- printk ("s disabled");
- else
- printk (" %d", instance->irq);
-@@ -172,7 +172,7 @@
- {
- int i;
-
-- if (shpnt->irq != IRQ_NONE)
-+ if (shpnt->irq != SCSI_IRQ_NONE)
- free_irq (shpnt->irq, NULL);
- if (shpnt->io_port)
- release_region (shpnt->io_port, shpnt->n_io_port);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,23 @@
-+#
-+# Makefile for the AT91RM9200-specific Linux kernel device drivers.
-+#
-+# Note! Dependencies are done automagically by 'make dep', which also
-+# removes any old dependencies. DON'T put your own dependencies here
-+# unless it's something special (not a .c file).
-+
-+O_TARGET := at91drv.o
-+
-+subdir-y := serial net watchdog rtc usb i2c spi mtd
-+subdir-m := $(subdir-y)
-+
-+obj-$(CONFIG_SERIAL_AT91) += serial/at91serial.o
-+obj-$(CONFIG_AT91_ETHER) += net/at91net.o
-+obj-$(CONFIG_AT91_WATCHDOG) += watchdog/at91wdt.o
-+obj-$(CONFIG_AT91_RTC) += rtc/at91rtc.o
-+obj-$(CONFIG_USB) += usb/at91usb.o
-+obj-$(CONFIG_I2C_AT91) += i2c/at91i2c.o
-+obj-$(CONFIG_AT91_SPIDEV) += spi/at91spi.o
-+obj-$(CONFIG_MTD_AT91_DATAFLASH) += spi/at91spi.o mtd/at91mtd.o
-+obj-$(CONFIG_MTD_AT91_SMARTMEDIA) += mtd/at91mtd.o
-+
-+include $(TOPDIR)/Rules.make
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/i2c/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,15 @@
-+# File: drivers/at91/i2c/Makefile
-+#
-+# Makefile for the Atmel AT91RM9200 I2C (TWI) device drivers
-+#
-+
-+O_TARGET := at91i2c.o
-+
-+obj-y :=
-+obj-m :=
-+obj-n :=
-+obj- :=
-+
-+obj-$(CONFIG_I2C_AT91) += at91_i2c.o
-+
-+include $(TOPDIR)/Rules.make
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/i2c/at91_i2c.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,257 @@
-+/*
-+ i2c Support for Atmel's AT91RM9200 Two-Wire Interface
-+
-+ (c) Rick Bronson
-+
-+ Borrowed heavily from original work by:
-+ Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
-+
-+ 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/module.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/pci.h>
-+#include <linux/types.h>
-+#include <linux/delay.h>
-+#include <linux/i2c.h>
-+#include <linux/init.h>
-+
-+#include <asm/arch/AT91RM9200_TWI.h>
-+#include <asm/arch/pio.h>
-+#include "at91_i2c.h"
-+
-+#define DBG(x...) do {\
-+ if (debug > 0) \
-+ printk(KERN_DEBUG "i2c:" x); \
-+ } while(0)
-+
-+int debug = 0;
-+
-+static struct at91_i2c_local *at91_i2c_device;
-+
-+/*
-+ * Poll the i2c status register until the specified bit is set.
-+ * Returns 0 if timed out (100 msec)
-+ */
-+static short at91_poll_status(AT91PS_TWI twi, unsigned long bit) {
-+ int loop_cntr = 10000;
-+ do {
-+ udelay(10);
-+ } while (!(twi->TWI_SR & bit) && (--loop_cntr > 0));
-+
-+ return (loop_cntr > 0);
-+}
-+
-+/*
-+ * Generic i2c master transfer entrypoint
-+ */
-+static int at91_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
-+{
-+ struct at91_i2c_local *device = (struct at91_i2c_local *) adap->data;
-+ AT91PS_TWI twi = (AT91PS_TWI) device->base_addr;
-+
-+ struct i2c_msg *pmsg;
-+ int length;
-+ unsigned char *buf;
-+
-+ /*
-+ * i2c_smbus_xfer_emulated() in drivers/i2c/i2c-core.c states:
-+ * "... In the case of writing, we need to use only one message;
-+ * when reading, we need two..."
-+ */
-+
-+ pmsg = msgs; /* look at 1st message, it contains the address/command */
-+ if (num >= 1 && num <= 2) {
-+ DBG("xfer: doing %s %d bytes to 0x%02x - %d messages\n",
-+ pmsg->flags & I2C_M_RD ? "read" : "write",
-+ pmsg->len, pmsg->buf[0], num);
-+
-+ /* Set the TWI Master Mode Register */
-+ twi->TWI_MMR = (pmsg->addr << 16) | (pmsg->len << 8)
-+ | ((pmsg + 1)->flags & I2C_M_RD ? AT91C_TWI_MREAD : 0);
-+
-+ /* Set TWI Internal Address Register with first messages data field */
-+ if (pmsg->len == 1)
-+ twi->TWI_IADR = pmsg->buf[0];
-+ else if (pmsg->len == 2)
-+ twi->TWI_IADR = pmsg->buf[0] << 8 | pmsg->buf[1];
-+ else /* must be 3 */
-+ twi->TWI_IADR = pmsg->buf[0] << 16 | pmsg->buf[1] << 8 | pmsg->buf[2];
-+
-+ /* 1st message contains the address/command */
-+ if (num > 1)
-+ pmsg++; /* go to real message */
-+
-+ length = pmsg->len;
-+ buf = pmsg->buf;
-+ if (length && buf) { /* sanity check */
-+ if (pmsg->flags & I2C_M_RD) {
-+ twi->TWI_CR = AT91C_TWI_START;
-+ while (length--) {
-+ if (!length)
-+ twi->TWI_CR = AT91C_TWI_STOP;
-+ /* Wait until transfer is finished */
-+ if (!at91_poll_status(twi, AT91C_TWI_RXRDY)) {
-+ printk(KERN_ERR "at91_i2c: timeout 1\n");
-+ return 0;
-+ }
-+ *buf++ = twi->TWI_RHR;
-+ }
-+ if (!at91_poll_status(twi, AT91C_TWI_TXCOMP)) {
-+ printk(KERN_ERR "at91_i2c: timeout 2\n");
-+ return 0;
-+ }
-+ } else {
-+ twi->TWI_CR = AT91C_TWI_START;
-+ while (length--) {
-+ twi->TWI_THR = *buf++;
-+ if (!length)
-+ twi->TWI_CR = AT91C_TWI_STOP;
-+ if (!at91_poll_status(twi, AT91C_TWI_TXRDY)) {
-+ printk(KERN_ERR "at91_i2c: timeout 3\n");
-+ return 0;
-+ }
-+ }
-+ /* Wait until transfer is finished */
-+ if (!at91_poll_status(twi, AT91C_TWI_TXCOMP)) {
-+ printk(KERN_ERR "at91_i2c: timeout 4\n");
-+ return 0;
-+ }
-+ }
-+ }
-+ DBG("transfer complete\n");
-+ return num;
-+ }
-+ else {
-+ printk(KERN_ERR "at91_i2c: unexpected number of messages: %d\n", num);
-+ return 0;
-+ }
-+}
-+
-+/*
-+ * Return list of supported functionality
-+ */
-+static u32 at91_func(struct i2c_adapter *adapter)
-+{
-+ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE
-+ | I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA
-+ | I2C_FUNC_SMBUS_BLOCK_DATA;
-+}
-+
-+/*
-+ * Open
-+ */
-+static void at91_inc(struct i2c_adapter *adapter)
-+{
-+ MOD_INC_USE_COUNT;
-+}
-+
-+/*
-+ * Close
-+ */
-+static void at91_dec(struct i2c_adapter *adapter)
-+{
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+/* For now, we only handle combined mode (smbus) */
-+static struct i2c_algorithm at91_algorithm = {
-+ name:"at91 i2c",
-+ id:I2C_ALGO_SMBUS,
-+ master_xfer:at91_xfer,
-+ functionality:at91_func,
-+};
-+
-+/*
-+ * Main initialization routine
-+ */
-+static int __init i2c_at91_init(void)
-+{
-+ AT91PS_TWI twi = (AT91PS_TWI) AT91C_VA_BASE_TWI;
-+ struct at91_i2c_local *device;
-+ int rc;
-+
-+ AT91_CfgPIO_TWI();
-+ AT91_SYS->PMC_PCER = 1 << AT91C_ID_TWI; /* enable peripheral clock */
-+
-+ twi->TWI_IDR = 0x3ff; /* Disable all interrupts */
-+ twi->TWI_CR = AT91C_TWI_SWRST; /* Reset peripheral */
-+ twi->TWI_CR = AT91C_TWI_MSEN | AT91C_TWI_SVDIS; /* Set Master mode */
-+
-+ /* Here, CKDIV = 1 and CHDIV=CLDIV ==> CLDIV = CHDIV = 1/4*((Fmclk/FTWI) -6) */
-+ twi->TWI_CWGR = AT91C_TWI_CKDIV1 | AT91C_TWI_CLDIV3 | (AT91C_TWI_CLDIV3 << 8);
-+
-+ device = (struct at91_i2c_local *) kmalloc(sizeof(struct at91_i2c_local), GFP_KERNEL);
-+ if (device == NULL) {
-+ printk(KERN_ERR "at91_i2c: can't allocate inteface!\n");
-+ return -ENOMEM;
-+ }
-+ memset(device, 0, sizeof(struct at91_i2c_local));
-+ at91_i2c_device = device;
-+
-+ sprintf(device->adapter.name, "AT91RM9200");
-+ device->adapter.data = (void *) device;
-+ device->adapter.id = I2C_ALGO_SMBUS;
-+ device->adapter.algo = &at91_algorithm;
-+ device->adapter.algo_data = NULL;
-+ device->adapter.inc_use = at91_inc;
-+ device->adapter.dec_use = at91_dec;
-+ device->adapter.client_register = NULL;
-+ device->adapter.client_unregister = NULL;
-+ device->base_addr = AT91C_VA_BASE_TWI;
-+
-+ rc = i2c_add_adapter(&device->adapter);
-+ if (rc) {
-+ printk(KERN_ERR "at91_i2c: Adapter %s registration failed\n", device->adapter.name);
-+ device->adapter.data = NULL;
-+ kfree(device);
-+ }
-+ else
-+ printk(KERN_INFO "Found AT91 i2c\n");
-+ return rc;
-+}
-+
-+/*
-+ * Clean up routine
-+ */
-+static void __exit i2c_at91_cleanup(void)
-+{
-+ struct at91_i2c_local *device = at91_i2c_device;
-+ int rc;
-+
-+ rc = i2c_del_adapter(&device->adapter);
-+ device->adapter.data = NULL;
-+ kfree(device);
-+
-+ AT91_SYS->PMC_PCDR = 1 << AT91C_ID_TWI; /* disable peripheral clock */
-+
-+ /* We aren't that prepared to deal with this... */
-+ if (rc)
-+ printk(KERN_ERR "at91_i2c: i2c_del_adapter failed (%i), that's bad!\n", rc);
-+}
-+
-+module_init(i2c_at91_init);
-+module_exit(i2c_at91_cleanup);
-+
-+MODULE_AUTHOR("Rick Bronson");
-+MODULE_DESCRIPTION("I2C driver for Atmel AT91RM9200");
-+MODULE_LICENSE("GPL");
-+MODULE_PARM(debug, "i");
-+
-+EXPORT_NO_SYMBOLS;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/i2c/at91_i2c.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,43 @@
-+/*
-+ i2c Support for Atmel's AT91RM9200 Two-Wire Interface
-+
-+ (c) Rick Bronson
-+
-+ 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 AT91_I2C_H
-+#define AT91_I2C_H
-+
-+#define AT91C_TWI_CLOCK 100000
-+#define AT91C_TWI_SCLOCK (10 * AT91C_MASTER_CLOCK / AT91C_TWI_CLOCK)
-+#define AT91C_TWI_CKDIV1 (2 << 16) /* TWI clock divider. NOTE: see Errata #22 */
-+
-+#if (AT91C_TWI_SCLOCK % 10) >= 5
-+#define AT91C_TWI_CLDIV2 ((AT91C_TWI_SCLOCK / 10) - 5)
-+#else
-+#define AT91C_TWI_CLDIV2 ((AT91C_TWI_SCLOCK / 10) - 6)
-+#endif
-+#define AT91C_TWI_CLDIV3 ((AT91C_TWI_CLDIV2 + (4 - AT91C_TWI_CLDIV2 % 4)) >> 2)
-+
-+#define AT91C_EEPROM_I2C_ADDRESS (0x50 << 16)
-+
-+/* Physical interface */
-+struct at91_i2c_local {
-+ struct i2c_adapter adapter;
-+ unsigned long base_addr;
-+};
-+
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/mtd/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,19 @@
-+# File: drivers/at91/mtd/Makefile
-+#
-+# Makefile for the Atmel AT91RM9200 MTD devices.
-+# Includes: NAND flash (SmartMedia) & DataFlash
-+#
-+
-+O_TARGET := at91mtd.o
-+
-+export-objs :=
-+
-+obj-y :=
-+obj-m :=
-+obj-n :=
-+obj- :=
-+
-+obj-$(CONFIG_MTD_AT91_DATAFLASH) += at91_dataflash.o
-+obj-$(CONFIG_MTD_AT91_SMARTMEDIA) += at91_nand.o
-+
-+include $(TOPDIR)/Rules.make
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/mtd/at91_dataflash.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,495 @@
-+/*
-+ * Atmel DataFlash driver for Atmel AT91RM9200 (Thunder)
-+ *
-+ * (c) SAN People (Pty) Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/pci.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
-+
-+#include <asm/arch/AT91RM9200_SPI.h>
-+#include <asm/arch/pio.h>
-+#include "at91_dataflash.h"
-+#include "../spi/at91_spi.h"
-+
-+#undef DEBUG_DATAFLASH
-+
-+/* Detected DataFlash devices */
-+static struct mtd_info* mtd_devices[DATAFLASH_MAX_DEVICES];
-+static int nr_devices = 0;
-+
-+/* ......................................................................... */
-+
-+#ifdef CONFIG_MTD_PARTITIONS
-+
-+static struct mtd_partition *mtd_parts = 0;
-+static int mtd_parts_nr = 0;
-+
-+#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
-+
-+static struct mtd_partition static_partitions[] =
-+{
-+ {
-+ name: "bootloader",
-+ offset: 0,
-+ size: 64 * 1024, /* 64 Kb */
-+ mask_flags: MTD_WRITEABLE /* read-only */
-+ },
-+ {
-+ name: "kernel",
-+ offset: MTDPART_OFS_NXTBLK,
-+ size: 768 *1024, /* 768 Kb */
-+ },
-+ {
-+ name: "filesystem",
-+ offset: MTDPART_OFS_NXTBLK,
-+ size: MTDPART_SIZ_FULL,
-+ }
-+};
-+
-+int parse_cmdline_partitions(struct mtd_info *master,
-+ struct mtd_partition **pparts, const char *mtd_id);
-+
-+#endif
-+
-+/* ......................................................................... */
-+
-+/* Allocate a single SPI transfer descriptor. We're assuming that if multiple
-+ SPI transfers occur at the same time, spi_access_bus() will serialize them.
-+ If this is not valid, then either (i) each dataflash 'priv' structure
-+ needs it's own transfer descriptor, (ii) we lock this one, or (iii) use
-+ another mechanism. */
-+struct spi_transfer_list* spi_transfer_desc;
-+
-+/*
-+ * Perform a SPI transfer to access the DataFlash device.
-+ */
-+int do_spi_transfer(int nr, char* tx, int tx_len, char* rx, int rx_len,
-+ char* txnext, int txnext_len, char* rxnext, int rxnext_len)
-+{
-+ struct spi_transfer_list* list = spi_transfer_desc;
-+
-+ list->tx[0] = tx; list->txlen[0] = tx_len;
-+ list->rx[0] = rx; list->rxlen[0] = rx_len;
-+
-+ list->tx[1] = txnext; list->txlen[1] = txnext_len;
-+ list->rx[1] = rxnext; list->rxlen[1] = rxnext_len;
-+
-+ list->nr_transfers = nr;
-+
-+ return spi_transfer(list);
-+}
-+
-+/* ......................................................................... */
-+
-+/*
-+ * Poll the DataFlash device until it is READY.
-+ */
-+void at91_dataflash_waitready(void)
-+{
-+ char* command = kmalloc(2, GFP_KERNEL);
-+
-+ if (!command)
-+ return;
-+
-+ do {
-+ command[0] = OP_READ_STATUS;
-+ command[1] = 0;
-+
-+ do_spi_transfer(1, command, 2, command, 2, NULL, 0, NULL, 0);
-+ } while ((command[1] & 0x80) == 0);
-+
-+ kfree(command);
-+}
-+
-+/*
-+ * Return the status of the DataFlash device.
-+ */
-+unsigned short at91_dataflash_status(void)
-+{
-+ unsigned short status;
-+ char* command = kmalloc(2, GFP_KERNEL);
-+
-+ if (!command)
-+ return 0;
-+
-+ command[0] = OP_READ_STATUS;
-+ command[1] = 0;
-+
-+ do_spi_transfer(1, command, 2, command, 2, NULL, 0, NULL, 0);
-+ status = command[1];
-+
-+ kfree(command);
-+ return status;
-+}
-+
-+/* ......................................................................... */
-+
-+/*
-+ * Erase a block of flash.
-+ */
-+int at91_dataflash_erase(struct mtd_info *mtd, struct erase_info *instr)
-+{
-+ struct dataflash_local *priv = (struct dataflash_local *) mtd->priv;
-+ unsigned int pageaddr;
-+ char* command;
-+
-+#ifdef DEBUG_DATAFLASH
-+ printk("dataflash_erase: addr=%i len=%i\n", instr->addr, instr->len);
-+#endif
-+
-+ /* Sanity checks */
-+ if (instr->addr + instr->len > mtd->size)
-+ return -EINVAL;
-+ if ((instr->len != mtd->erasesize) || (instr->len != priv->page_size))
-+ return -EINVAL;
-+ if ((instr->addr % priv->page_size) != 0)
-+ return -EINVAL;
-+
-+ command = kmalloc(4, GFP_KERNEL);
-+ if (!command)
-+ return -ENOMEM;
-+
-+ /* Calculate flash page address */
-+ pageaddr = (instr->addr / priv->page_size) << priv->page_offset;
-+
-+ command[0] = OP_ERASE_PAGE;
-+ command[1] = (pageaddr & 0x00FF0000) >> 16;
-+ command[2] = (pageaddr & 0x0000FF00) >> 8;
-+ command[3] = 0;
-+#ifdef DEBUG_DATAFLASH
-+ printk("ERASE: (%x) %x %x %x [%i]\n", command[0], command[1], command[2], command[3], pageaddr);
-+#endif
-+
-+ /* Send command to SPI device */
-+ spi_access_bus(priv->spi);
-+ do_spi_transfer(1, command, 4, command, 4, NULL, 0, NULL, 0);
-+
-+ at91_dataflash_waitready(); /* poll status until ready */
-+ spi_release_bus(priv->spi);
-+
-+ kfree(command);
-+
-+ /* Inform MTD subsystem that erase is complete */
-+ instr->state = MTD_ERASE_DONE;
-+ if (instr->callback)
-+ instr->callback(instr);
-+
-+ return 0;
-+}
-+
-+/*
-+ * Read from the DataFlash device.
-+ * from : Start offset in flash device
-+ * len : Amount to read
-+ * retlen : About of data actually read
-+ * buf : Buffer containing the data
-+ */
-+int at91_dataflash_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
-+{
-+ struct dataflash_local *priv = (struct dataflash_local *) mtd->priv;
-+ unsigned int addr;
-+ char* command;
-+
-+#ifdef DEBUG_DATAFLASH
-+ printk("dataflash_read: %lli .. %lli\n", from, from+len);
-+#endif
-+
-+ *retlen = 0;
-+
-+ /* Sanity checks */
-+ if (!len)
-+ return 0;
-+ if (from + len > mtd->size)
-+ return -EINVAL;
-+
-+ /* Calculate flash page/byte address */
-+ addr = (((unsigned)from / priv->page_size) << priv->page_offset) + ((unsigned)from % priv->page_size);
-+
-+ command = kmalloc(8, GFP_KERNEL);
-+ if (!command)
-+ return -ENOMEM;
-+
-+ command[0] = OP_READ_CONTINUOUS;
-+ command[1] = (addr & 0x00FF0000) >> 16;
-+ command[2] = (addr & 0x0000FF00) >> 8;
-+ command[3] = (addr & 0x000000FF);
-+#ifdef DEBUG_DATAFLASH
-+ printk("READ: (%x) %x %x %x\n", command[0], command[1], command[2], command[3]);
-+#endif
-+
-+ /* Send command to SPI device */
-+ spi_access_bus(priv->spi);
-+ do_spi_transfer(2, command, 8, command, 8, buf, len, buf, len);
-+ spi_release_bus(priv->spi);
-+
-+ *retlen = len;
-+ kfree(command);
-+ return 0;
-+}
-+
-+/*
-+ * Write to the DataFlash device.
-+ * to : Start offset in flash device
-+ * len : Amount to write
-+ * retlen : Amount of data actually written
-+ * buf : Buffer containing the data
-+ */
-+int at91_dataflash_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf)
-+{
-+ struct dataflash_local *priv = (struct dataflash_local *) mtd->priv;
-+ unsigned int pageaddr, addr, offset, writelen;
-+ size_t remaining;
-+ char *writebuf;
-+ unsigned short status;
-+ int res = 0;
-+ char* command;
-+
-+#ifdef DEBUG_DATAFLASH
-+ printk("dataflash_write: %lli .. %lli\n", to, to+len);
-+#endif
-+
-+ *retlen = 0;
-+
-+ /* Sanity checks */
-+ if (!len)
-+ return 0;
-+ if (to + len > mtd->size)
-+ return -EINVAL;
-+
-+ command = kmalloc(4, GFP_KERNEL);
-+ if (!command)
-+ return -ENOMEM;
-+
-+ pageaddr = ((unsigned)to / priv->page_size);
-+ offset = ((unsigned)to % priv->page_size);
-+ if (offset + len > priv->page_size)
-+ writelen = priv->page_size - offset;
-+ else
-+ writelen = len;
-+ writebuf = buf;
-+ remaining = len;
-+
-+ /* Gain access to the SPI bus */
-+ spi_access_bus(priv->spi);
-+
-+ while (remaining > 0) {
-+#ifdef DEBUG_DATAFLASH
-+ printk("write @ %i:%i len=%i\n", pageaddr, offset, writelen);
-+#endif
-+
-+ /* (1) Transfer to Buffer1 */
-+ if (writelen != priv->page_size) {
-+ addr = pageaddr << priv->page_offset;
-+ command[0] = OP_TRANSFER_BUF1;
-+ command[1] = (addr & 0x00FF0000) >> 16;
-+ command[2] = (addr & 0x0000FF00) >> 8;
-+ command[3] = 0;
-+#ifdef DEBUG_DATAFLASH
-+ printk("TRANSFER: (%x) %x %x %x\n", command[0], command[1], command[2], command[3]);
-+#endif
-+ do_spi_transfer(1, command, 4, command, 4, NULL, 0, NULL, 0);
-+ at91_dataflash_waitready();
-+ }
-+
-+ /* (2) Program via Buffer1 */
-+ addr = (pageaddr << priv->page_offset) + offset;
-+ command[0] = OP_PROGRAM_VIA_BUF1;
-+ command[1] = (addr & 0x00FF0000) >> 16;
-+ command[2] = (addr & 0x0000FF00) >> 8;
-+ command[3] = (addr & 0x000000FF);
-+#ifdef DEBUG_DATAFLASH
-+ printk("PROGRAM: (%x) %x %x %x\n", command[0], command[1], command[2], command[3]);
-+#endif
-+ do_spi_transfer(2, command, 4, command, 4, writebuf, writelen, writebuf, writelen);
-+ at91_dataflash_waitready();
-+
-+ /* (3) Compare to Buffer1 */
-+ addr = pageaddr << priv->page_offset;
-+ command[0] = OP_COMPARE_BUF1;
-+ command[1] = (addr & 0x00FF0000) >> 16;
-+ command[2] = (addr & 0x0000FF00) >> 8;
-+ command[3] = 0;
-+#ifdef DEBUG_DATAFLASH
-+ printk("COMPARE: (%x) %x %x %x\n", command[0], command[1], command[2], command[3]);
-+#endif
-+ do_spi_transfer(1, command, 4, command, 4, NULL, 0, NULL, 0);
-+ at91_dataflash_waitready();
-+
-+ /* Get result of the compare operation */
-+ status = at91_dataflash_status();
-+ if ((status & 0x40) == 1) {
-+ printk("at91_dataflash: Write error on page %i\n", pageaddr);
-+ remaining = 0;
-+ res = -EIO;
-+ }
-+
-+ remaining = remaining - writelen;
-+ pageaddr++;
-+ offset = 0;
-+ writebuf += writelen;
-+ *retlen += writelen;
-+
-+ if (remaining > priv->page_size)
-+ writelen = priv->page_size;
-+ else
-+ writelen = remaining;
-+ }
-+
-+ /* Release SPI bus */
-+ spi_release_bus(priv->spi);
-+
-+ kfree(command);
-+ return res;
-+}
-+
-+/* ......................................................................... */
-+
-+/*
-+ * Initialize and register DataFlash device with MTD subsystem.
-+ */
-+int add_dataflash(int channel, char *name, int size, int pagesize, int pageoffset)
-+{
-+ struct mtd_info *device;
-+ struct dataflash_local *priv;
-+#ifdef CONFIG_MTD_CMDLINE_PARTS
-+ char mtdID[14];
-+#endif
-+
-+ if (nr_devices >= DATAFLASH_MAX_DEVICES) {
-+ printk(KERN_ERR "at91_dataflash: Too many devices detected\n");
-+ return 0;
-+ }
-+
-+ device = (struct mtd_info *) kmalloc(sizeof(struct mtd_info), GFP_KERNEL);
-+ if (!device)
-+ return -ENOMEM;
-+ memset(device, 0, sizeof(struct mtd_info));
-+
-+ device->name = name;
-+ device->size = size;
-+ device->erasesize = pagesize;
-+ device->module = THIS_MODULE;
-+ device->type = MTD_NORFLASH;
-+ device->flags = MTD_CAP_NORFLASH;
-+ device->erase = at91_dataflash_erase;
-+ device->read = at91_dataflash_read;
-+ device->write = at91_dataflash_write;
-+
-+ priv = (struct dataflash_local *) kmalloc(sizeof(struct dataflash_local), GFP_KERNEL);
-+ if (!priv) {
-+ kfree(device);
-+ return -ENOMEM;
-+ }
-+ memset(priv, 0, sizeof(struct dataflash_local));
-+
-+ priv->spi = channel;
-+ priv->page_size = pagesize;
-+ priv->page_offset = pageoffset;
-+ device->priv = priv;
-+
-+ mtd_devices[nr_devices] = device;
-+ nr_devices++;
-+ printk("at91_dataflash: %s detected [spi%i] (%i bytes)\n", name, channel, size);
-+
-+#ifdef CONFIG_MTD_PARTITIONS
-+#ifdef CONFIG_MTD_CMDLINE_PARTS
-+ sprintf(mtdID, "dataflash%i", nr_devices-1);
-+ mtd_parts_nr = parse_cmdline_partitions(device, &mtd_parts, mtdID);
-+#endif
-+ if (mtd_parts_nr <= 0) {
-+ mtd_parts = static_partitions;
-+ mtd_parts_nr = NB_OF(static_partitions);
-+ }
-+
-+ return add_mtd_partitions(device, mtd_parts, mtd_parts_nr);
-+#else
-+ return add_mtd_device(device);
-+#endif
-+}
-+
-+/*
-+ * Detect and initialize DataFlash device connected to specified SPI channel.
-+ */
-+int at91_dataflash_detect(int channel)
-+{
-+ int res = 0;
-+ unsigned short status;
-+
-+ spi_access_bus(channel);
-+ status = at91_dataflash_status();
-+ if (status != 0xff) { /* no dataflash device there */
-+ switch (status & 0x3c) {
-+ case 0x2c: /* 1 0 1 1 */
-+ res = add_dataflash(channel, "Atmel AT45DB161B", 4096*528, 528, 10);
-+ break;
-+ case 0x34: /* 1 1 0 1 */
-+ res = add_dataflash(channel, "Atmel AT45DB321B", 8192*528, 528, 10);
-+ break;
-+ case 0x3c: /* 1 1 1 1 */
-+ res = add_dataflash(channel, "Atmel AT45DB642", 8192*1056, 1056, 11);
-+ break;
-+ default:
-+ printk(KERN_ERR "at91_dataflash: Unknown device (%x)\n", status & 0x3c);
-+ }
-+ }
-+ spi_release_bus(channel);
-+
-+ return res;
-+}
-+
-+int __init at91_dataflash_init(void)
-+{
-+ spi_transfer_desc = kmalloc(sizeof(struct spi_transfer_list), GFP_KERNEL);
-+ if (!spi_transfer_desc)
-+ return -ENOMEM;
-+
-+ /* DataFlash (SPI chip select 0) */
-+ at91_dataflash_detect(0);
-+
-+#ifdef CONFIG_MTD_AT91_DATAFLASH_CARD
-+ /* DataFlash card (SPI chip select 3) */
-+ AT91_CfgPIO_DataFlashCard();
-+ at91_dataflash_detect(3);
-+#endif
-+
-+ return 0;
-+}
-+
-+void __exit at91_dataflash_exit(void)
-+{
-+ int i;
-+
-+ for (i = 0; i < DATAFLASH_MAX_DEVICES; i++) {
-+ if (mtd_devices[i]) {
-+#ifdef CONFIG_MTD_PARTITIONS
-+ del_mtd_partitions(mtd_devices[i]);
-+#else
-+ del_mtd_device(mtd_devices[i]);
-+#endif
-+ kfree(mtd_devices[i]->priv);
-+ kfree(mtd_devices[i]);
-+ }
-+ }
-+ nr_devices = 0;
-+ kfree(spi_transfer_desc);
-+}
-+
-+
-+EXPORT_NO_SYMBOLS;
-+
-+module_init(at91_dataflash_init);
-+module_exit(at91_dataflash_exit);
-+
-+MODULE_LICENSE("GPL")
-+MODULE_AUTHOR("Andrew Victor")
-+MODULE_DESCRIPTION("DataFlash driver for Atmel AT91RM9200")
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/mtd/at91_dataflash.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,42 @@
-+/*
-+ * Atmel DataFlash driver for the Atmel AT91RM9200 (Thunder)
-+ *
-+ * (c) SAN People (Pty) Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef AT91_DATAFLASH_H
-+#define AT91_DATAFLASH_H
-+
-+#define DATAFLASH_MAX_DEVICES 4 /* max number of dataflash devices */
-+
-+#define OP_READ_CONTINUOUS 0xE8
-+#define OP_READ_PAGE 0xD2
-+#define OP_READ_BUFFER1 0xD4
-+#define OP_READ_BUFFER2 0xD6
-+#define OP_READ_STATUS 0xD7
-+
-+#define OP_ERASE_PAGE 0x81
-+#define OP_ERASE_BLOCK 0x50
-+
-+#define OP_TRANSFER_BUF1 0x53
-+#define OP_TRANSFER_BUF2 0x55
-+#define OP_COMPARE_BUF1 0x60
-+#define OP_COMPARE_BUF2 0x61
-+
-+#define OP_PROGRAM_VIA_BUF1 0x82
-+#define OP_PROGRAM_VIA_BUF2 0x85
-+
-+struct dataflash_local
-+{
-+ int spi; /* SPI chip-select number */
-+
-+ unsigned int page_size; /* number of bytes per page */
-+ unsigned short page_offset; /* page offset in flash address */
-+};
-+
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/mtd/at91_nand.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,328 @@
-+/*
-+ * drivers/at91/mtd/at91_nand.c
-+ *
-+ * Copyright (c) 2003 Rick Bronson
-+ *
-+ * Derived from drivers/mtd/nand/autcpu12.c
-+ * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
-+ *
-+ * Derived from drivers/mtd/spia.c
-+ * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ */
-+
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/partitions.h>
-+#include <asm/io.h>
-+#include <asm/arch/hardware.h>
-+#include <asm/sizes.h>
-+
-+#include <asm/arch/pio.h>
-+#include "at91_nand.h"
-+
-+/*
-+ * MTD structure for AT91 board
-+ */
-+static struct mtd_info *at91_mtd = NULL;
-+static struct nand_chip *my_nand_chip = NULL;
-+
-+static int at91_fio_base;
-+
-+#ifdef CONFIG_MTD_PARTITIONS
-+
-+/*
-+ * Define partitions for flash devices
-+ */
-+
-+static struct mtd_partition partition_info32k[] = {
-+ { name: "AT91 NAND partition 1, kernel",
-+ offset: 0,
-+ size: 1 * SZ_1M },
-+ { name: "AT91 NAND partition 2, filesystem",
-+ offset: 1 * SZ_1M,
-+ size: 16 * SZ_1M },
-+ { name: "AT91 NAND partition 3a, storage",
-+ offset: (1 * SZ_1M) + (16 * SZ_1M),
-+ size: 1 * SZ_1M },
-+ { name: "AT91 NAND partition 3b, storage",
-+ offset: (2 * SZ_1M) + (16 * SZ_1M),
-+ size: 1 * SZ_1M },
-+ { name: "AT91 NAND partition 3c, storage",
-+ offset: (3 * SZ_1M) + (16 * SZ_1M),
-+ size: 1 * SZ_1M },
-+ { name: "AT91 NAND partition 3d, storage",
-+ offset: (4 * SZ_1M) + (16 * SZ_1M),
-+ size: 1 * SZ_1M },
-+};
-+
-+static struct mtd_partition partition_info64k[] = {
-+ { name: "AT91 NAND partition 1, kernel",
-+ offset: 0,
-+ size: 1 * SZ_1M },
-+ { name: "AT91 NAND partition 2, filesystem",
-+ offset: 1 * SZ_1M,
-+ size: 16 * SZ_1M },
-+ { name: "AT91 NAND partition 3, storage",
-+ offset: (1 * SZ_1M) + (16 * SZ_1M),
-+ size: 47 * SZ_1M },
-+};
-+
-+#endif
-+
-+/*
-+ * Hardware specific access to control-lines
-+ */
-+static void at91_hwcontrol(int cmd)
-+{
-+ struct nand_chip *my_nand = my_nand_chip;
-+ switch(cmd)
-+ {
-+ case NAND_CTL_SETCLE:
-+ my_nand->IO_ADDR_W = at91_fio_base + AT91_SMART_MEDIA_CLE;
-+ break;
-+ case NAND_CTL_CLRCLE:
-+ my_nand->IO_ADDR_W = at91_fio_base;
-+ break;
-+ case NAND_CTL_SETALE:
-+ my_nand->IO_ADDR_W = at91_fio_base + AT91_SMART_MEDIA_ALE;
-+ break;
-+ case NAND_CTL_CLRALE:
-+ my_nand->IO_ADDR_W = at91_fio_base;
-+ break;
-+ case NAND_CTL_SETNCE:
-+ break;
-+ case NAND_CTL_CLRNCE:
-+ break;
-+ }
-+}
-+
-+/*
-+ * Send command to NAND device
-+ */
-+static void at91_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr)
-+{
-+ register struct nand_chip *my_nand = mtd->priv;
-+
-+ /* Begin command latch cycle */
-+ register unsigned long NAND_IO_ADDR = my_nand->IO_ADDR_W + AT91_SMART_MEDIA_CLE;
-+
-+ /*
-+ * Write out the command to the device.
-+ */
-+ if (command != NAND_CMD_SEQIN)
-+ writeb (command, NAND_IO_ADDR);
-+ else {
-+ if (mtd->oobblock == 256 && column >= 256) {
-+ column -= 256;
-+ writeb (NAND_CMD_RESET, NAND_IO_ADDR);
-+ writeb (NAND_CMD_READOOB, NAND_IO_ADDR);
-+ writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
-+ }
-+ else
-+ if (mtd->oobblock == 512 && column >= 256) {
-+ if (column < 512) {
-+ column -= 256;
-+ writeb (NAND_CMD_READ1, NAND_IO_ADDR);
-+ writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
-+ } else {
-+ column -= 512;
-+ writeb (NAND_CMD_READOOB, NAND_IO_ADDR);
-+ writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
-+ }
-+ } else {
-+ writeb (NAND_CMD_READ0, NAND_IO_ADDR);
-+ writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
-+ }
-+ }
-+
-+ /* Set ALE and clear CLE to start address cycle */
-+ NAND_IO_ADDR = at91_fio_base;
-+
-+ if (column != -1 || page_addr != -1)
-+ NAND_IO_ADDR += AT91_SMART_MEDIA_ALE;
-+
-+ /* Serially input address */
-+ if (column != -1)
-+ writeb (column, NAND_IO_ADDR);
-+ if (page_addr != -1) {
-+ writeb ((unsigned char) (page_addr & 0xff), NAND_IO_ADDR);
-+ writeb ((unsigned char) ((page_addr >> 8) & 0xff), NAND_IO_ADDR);
-+ /* One more address cycle for higher density devices */
-+ if (mtd->size & 0x0c000000) {
-+ writeb ((unsigned char) ((page_addr >> 16) & 0x0f), NAND_IO_ADDR);
-+ }
-+ }
-+
-+ /* wait until command is processed */
-+ while (!my_nand->dev_ready())
-+ ;
-+}
-+
-+/*
-+ * Read the Device Ready pin.
-+ */
-+static int at91_device_ready(void)
-+{
-+ return AT91_PIO_SmartMedia_RDY();
-+}
-+/*
-+ * Main initialization routine
-+ */
-+static int __init at91_init (void)
-+{
-+ struct nand_chip *my_nand;
-+ int err = 0;
-+
-+ /* Allocate memory for MTD device structure and private data */
-+ at91_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip), GFP_KERNEL);
-+ if (!at91_mtd) {
-+ printk ("Unable to allocate AT91 NAND MTD device structure.\n");
-+ err = -ENOMEM;
-+ goto out;
-+ }
-+
-+ /* map physical adress */
-+ at91_fio_base = (unsigned long) ioremap(AT91_SMARTMEDIA_BASE, SZ_8M);
-+ if(!at91_fio_base) {
-+ printk("ioremap AT91 NAND failed\n");
-+ err = -EIO;
-+ goto out_mtd;
-+ }
-+
-+ /* Get pointer to private data */
-+ my_nand_chip = my_nand = (struct nand_chip *) (&at91_mtd[1]);
-+
-+ /* Initialize structures */
-+ memset((char *) at91_mtd, 0, sizeof(struct mtd_info));
-+ memset((char *) my_nand, 0, sizeof(struct nand_chip));
-+
-+ /* Link the private data with the MTD structure */
-+ at91_mtd->priv = my_nand;
-+
-+ /* Set address of NAND IO lines */
-+ my_nand->IO_ADDR_R = at91_fio_base;
-+ my_nand->IO_ADDR_W = at91_fio_base;
-+ my_nand->hwcontrol = at91_hwcontrol;
-+ my_nand->dev_ready = at91_device_ready;
-+ my_nand->cmdfunc = at91_nand_command; /* we need our own */
-+ my_nand->eccmode = NAND_ECC_SOFT; /* enable ECC */
-+ /* 20 us command delay time */
-+ my_nand->chip_delay = 20;
-+
-+ /* Setup Smart Media, first enable the address range of CS3 */
-+ AT91_SYS->EBI_CSA |= AT91C_EBI_CS3A_SMC_SmartMedia;
-+ /* set the bus interface characteristics based on
-+ tDS Data Set up Time 30 - ns
-+ tDH Data Hold Time 20 - ns
-+ tALS ALE Set up Time 20 - ns
-+ 16ns at 60 MHz ~= 3 */
-+#define AT91C_SM_ID_RWH (5 << 28) /* orig = 5 */
-+#define AT91C_SM_RWH (1 << 28) /* orig = 1 */
-+#define AT91C_SM_RWS (0 << 24) /* orig = 0 */
-+#define AT91C_SM_TDF (1 << 8) /* orig = 1 */
-+#define AT91C_SM_NWS (5) /* orig = 3 */
-+ AT91_SYS->EBI_SMC2_CSR[3] = ( AT91C_SM_RWH | AT91C_SM_RWS |
-+ AT91C_SMC2_ACSS_STANDARD |
-+ AT91C_SMC2_DBW_8 | AT91C_SM_TDF |
-+ AT91C_SMC2_WSEN | AT91C_SM_NWS);
-+
-+ AT91_CfgPIO_SmartMedia();
-+
-+ if (AT91_PIO_SmartMedia_CardDetect())
-+ printk ("No ");
-+ printk ("SmartMedia card inserted.\n");
-+
-+ /* Scan to find existance of the device */
-+ if (nand_scan (at91_mtd)) {
-+ err = -ENXIO;
-+ goto out_ior;
-+ }
-+
-+ /* Allocate memory for internal data buffer */
-+ my_nand->data_buf = kmalloc (sizeof(u_char) * (at91_mtd->oobblock + at91_mtd->oobsize), GFP_KERNEL);
-+ if (!my_nand->data_buf) {
-+ printk ("Unable to allocate AT91 NAND data buffer.\n");
-+ err = -ENOMEM;
-+ goto out_ior;
-+ }
-+
-+ /* Allocate memory for internal data buffer */
-+ my_nand->data_cache = kmalloc (sizeof(u_char) * (at91_mtd->oobblock + at91_mtd->oobsize), GFP_KERNEL);
-+ if (!my_nand->data_cache) {
-+ printk ("Unable to allocate AT91 NAND data cache.\n");
-+ err = -ENOMEM;
-+ goto out_buf;
-+ }
-+ my_nand->cache_page = -1;
-+
-+#ifdef CONFIG_MTD_PARTITIONS
-+ /* Register the partitions */
-+ switch(at91_mtd->size)
-+ {
-+ case SZ_32M:
-+ err = add_mtd_partitions(at91_mtd, partition_info32k,
-+ ARRAY_SIZE (partition_info32k));
-+ break;
-+ case SZ_64M:
-+ err = add_mtd_partitions(at91_mtd, partition_info64k,
-+ ARRAY_SIZE (partition_info64k));
-+ break;
-+ default:
-+ printk ("Unsupported SmartMedia device\n");
-+ err = -ENXIO;
-+ goto out_cac;
-+ }
-+#else
-+ err = add_mtd_device(at91_mtd);
-+#endif
-+ goto out;
-+
-+ out_cac:
-+ kfree (my_nand->data_cache);
-+ out_buf:
-+ kfree (my_nand->data_buf);
-+ out_ior:
-+ iounmap((void *)at91_fio_base);
-+ out_mtd:
-+ kfree (at91_mtd);
-+ out:
-+ return err;
-+}
-+
-+/*
-+ * Clean up routine
-+ */
-+static void __exit at91_cleanup (void)
-+{
-+ struct nand_chip *my_nand = (struct nand_chip *) &at91_mtd[1];
-+
-+ /* Unregister partitions */
-+ del_mtd_partitions(at91_mtd);
-+
-+ /* Unregister the device */
-+ del_mtd_device (at91_mtd);
-+
-+ /* Free internal data buffers */
-+ kfree (my_nand->data_buf);
-+ kfree (my_nand->data_cache);
-+
-+ /* unmap physical adress */
-+ iounmap((void *)at91_fio_base);
-+
-+ /* Free the MTD device structure */
-+ kfree (at91_mtd);
-+}
-+
-+module_init(at91_init);
-+module_exit(at91_cleanup);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Rick Bronson");
-+MODULE_DESCRIPTION("Glue layer for SmartMediaCard on ATMEL AT91RM9200");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/mtd/at91_nand.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,27 @@
-+/*
-+ * AT91RM9200 specific NAND (SmartMedia) defines
-+ *
-+ * (c) 2003 Rick Bronson
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+#ifndef __AT91_NAND_H
-+#define __AT91_NAND_H
-+
-+#define AT91_SMART_MEDIA_ALE (1 << 22) /* our ALE is AD22 */
-+#define AT91_SMART_MEDIA_CLE (1 << 21) /* our CLE is AD21 */
-+
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/net/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,15 @@
-+# File: drivers/at91/net/Makefile
-+#
-+# Makefile for the Atmel AT91RM9200 ethernet device drivers
-+#
-+
-+O_TARGET := at91net.o
-+
-+obj-y :=
-+obj-m :=
-+obj-n :=
-+obj- :=
-+
-+obj-$(CONFIG_AT91_ETHER) += at91_ether.o
-+
-+include $(TOPDIR)/Rules.make
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/net/at91_ether.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,877 @@
-+/*
-+ * Ethernet driver for the Atmel AT91RM9200 (Thunder)
-+ *
-+ * (c) SAN People (Pty) Ltd
-+ *
-+ * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc.
-+ * Initial version by Rick Bronson 01/11/2003
-+ *
-+ * Intel LXT971A PHY support by Christopher Bahns & David Knickerbocker
-+ * (Polaroid Corporation)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/config.h>
-+#include <linux/mii.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+#include <asm/io.h>
-+#include <linux/pci.h>
-+#include <linux/crc32.h>
-+#include <asm/uaccess.h>
-+#include <linux/ethtool.h>
-+
-+#include <asm/arch/AT91RM9200_EMAC.h>
-+#include <asm/arch/pio.h>
-+#include "at91_ether.h"
-+
-+static struct net_device at91_dev;
-+
-+/* ........................... PHY INTERFACE ........................... */
-+
-+/*
-+ * Enable the MDIO bit in MAC control register
-+ * When not called from an interrupt-handler, access to the PHY must be
-+ * protected by a spinlock.
-+ */
-+static void enable_mdi(AT91PS_EMAC regs)
-+{
-+ regs->EMAC_CTL |= AT91C_EMAC_MPE; /* enable management port */
-+}
-+
-+/*
-+ * Disable the MDIO bit in the MAC control register
-+ */
-+static void disable_mdi(AT91PS_EMAC regs)
-+{
-+ regs->EMAC_CTL &= ~AT91C_EMAC_MPE; /* disable management port */
-+}
-+
-+/*
-+ * Write value to the a PHY register
-+ * Note: MDI interface is assumed to already have been enabled.
-+ */
-+static void write_phy(AT91PS_EMAC regs, unsigned char phy_addr, unsigned char address, unsigned int value)
-+{
-+ regs->EMAC_MAN = (AT91C_EMAC_HIGH | AT91C_EMAC_CODE_802_3 | AT91C_EMAC_RW_W
-+ | ((phy_addr & 0x1f) << 23) | (address << 18)) + (value & 0xffff);
-+
-+ /* Wait until IDLE bit in Network Status register is cleared */
-+ // TODO: Enforce some maximum loop-count?
-+ while (!(regs->EMAC_SR & AT91C_EMAC_IDLE)) { barrier(); }
-+}
-+
-+/*
-+ * Read value stored in a PHY register.
-+ * Note: MDI interface is assumed to already have been enabled.
-+ */
-+static void read_phy(AT91PS_EMAC regs, unsigned char phy_addr, unsigned char address, unsigned int *value)
-+{
-+ regs->EMAC_MAN = AT91C_EMAC_HIGH | AT91C_EMAC_CODE_802_3 | AT91C_EMAC_RW_R
-+ | ((phy_addr & 0x1f) << 23) | (address << 18);
-+
-+ /* Wait until IDLE bit in Network Status register is cleared */
-+ // TODO: Enforce some maximum loop-count?
-+ while (!(regs->EMAC_SR & AT91C_EMAC_IDLE)) { barrier(); }
-+
-+ *value = (regs->EMAC_MAN & 0x0000ffff);
-+}
-+
-+/* ........................... PHY MANAGEMENT .......................... */
-+
-+/*
-+ * Access the PHY to determine the current Link speed and Mode, and update the
-+ * MAC accordingly.
-+ * If no link or auto-negotiation is busy, then no changes are made.
-+ * Returns: 0 : OK
-+ * -1 : No link
-+ * -2 : AutoNegotiation still in progress
-+ */
-+static int update_linkspeed(struct net_device *dev, AT91PS_EMAC regs) {
-+ unsigned int bmsr, bmcr, lpa, mac_cfg;
-+ unsigned int speed, duplex;
-+
-+ /* Link status is latched, so read twice to get current value */
-+ read_phy(regs, 0, MII_BMSR, &bmsr);
-+ read_phy(regs, 0, MII_BMSR, &bmsr);
-+ if (!(bmsr & BMSR_LSTATUS)) return -1; /* no link */
-+
-+ read_phy(regs, 0, MII_BMCR, &bmcr);
-+ if (bmcr & BMCR_ANENABLE) { /* AutoNegotiation is enabled */
-+ if (!(bmsr & BMSR_ANEGCOMPLETE)) return -2; /* auto-negotitation in progress */
-+
-+ read_phy(regs, 0, MII_LPA, &lpa);
-+ if ((lpa & LPA_100FULL) || (lpa & LPA_100HALF)) speed = SPEED_100;
-+ else speed = SPEED_10;
-+ if ((lpa & LPA_100FULL) || (lpa & LPA_10FULL)) duplex = DUPLEX_FULL;
-+ else duplex = DUPLEX_HALF;
-+ } else {
-+ speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10;
-+ duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
-+ }
-+
-+ /* Update the MAC */
-+ mac_cfg = regs->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
-+ if (speed == SPEED_100) {
-+ if (duplex == DUPLEX_FULL) /* 100 Full Duplex */
-+ regs->EMAC_CFG = mac_cfg | AT91C_EMAC_SPD | AT91C_EMAC_FD;
-+ else /* 100 Half Duplex */
-+ regs->EMAC_CFG = mac_cfg | AT91C_EMAC_SPD;
-+ } else {
-+ if (duplex == DUPLEX_FULL) /* 10 Full Duplex */
-+ regs->EMAC_CFG = mac_cfg | AT91C_EMAC_FD;
-+ else /* 10 Half Duplex */
-+ regs->EMAC_CFG = mac_cfg;
-+ }
-+
-+ printk(KERN_INFO "%s: Link now %i-%s\n", dev->name, speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex");
-+ return 0;
-+}
-+
-+/*
-+ * Handle interrupts from the PHY
-+ */
-+static void at91ether_phy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct net_device *dev = (struct net_device *) dev_id;
-+ struct at91_private *lp = (struct at91_private *) dev->priv;
-+ AT91PS_EMAC emac = (AT91PS_EMAC) dev->base_addr;
-+ int status;
-+ unsigned int phy;
-+
-+ enable_mdi(emac);
-+ if (lp->phy_type == MII_DM9161_ID)
-+ read_phy(emac, 0, MII_DSINTR_REG, &phy); /* ack interrupt in Davicom PHY */
-+ else if (lp->phy_type == MII_LXT971A_ID)
-+ read_phy(emac, 0, MII_ISINTS_REG, &phy); /* ack interrupt in Intel PHY */
-+
-+ status = AT91_SYS->PIOC_ISR; /* acknowledge interrupt in PIO */
-+
-+ status = update_linkspeed(dev, emac);
-+ if (status == -1) { /* link is down */
-+ netif_carrier_off(dev);
-+ printk(KERN_INFO "%s: Link down.\n", dev->name);
-+ } else if (status == -2) { /* auto-negotiation in progress */
-+ /* Do nothing - another interrupt generated when negotiation complete */
-+ } else { /* link is operational */
-+ netif_carrier_on(dev);
-+ }
-+ disable_mdi(emac);
-+}
-+
-+/*
-+ * Initialize and enable the PHY interrupt when link-state changes
-+ */
-+static void enable_phyirq(struct net_device *dev, AT91PS_EMAC regs)
-+{
-+ struct at91_private *lp = (struct at91_private *) dev->priv;
-+ unsigned int dsintr, status;
-+
-+ // TODO: Check error code. Really need a generic PIO (interrupt)
-+ // layer since we're really only interested in the PC4 (DK) or PC2 (CSB337) line.
-+ (void) request_irq(AT91C_ID_PIOC, at91ether_phy_interrupt, 0, dev->name, dev);
-+
-+ status = AT91_SYS->PIOC_ISR; /* clear any pending PIO interrupts */
-+#ifdef CONFIG_MACH_CSB337
-+ AT91_SYS->PIOC_IER = AT91C_PIO_PC2; /* Enable interrupt */
-+#else
-+ AT91_SYS->PIOC_IER = AT91C_PIO_PC4; /* Enable interrupt */
-+#endif
-+
-+ spin_lock_irq(&lp->lock);
-+ enable_mdi(regs);
-+
-+ if (lp->phy_type == MII_DM9161_ID) { /* for Davicom PHY */
-+ read_phy(regs, 0, MII_DSINTR_REG, &dsintr);
-+ dsintr = dsintr & ~0xf00; /* clear bits 8..11 */
-+ write_phy(regs, 0, MII_DSINTR_REG, dsintr);
-+ }
-+ else if (lp->phy_type == MII_LXT971A_ID) { /* for Intel PHY */
-+ read_phy(regs, 0, MII_ISINTE_REG, &dsintr);
-+ dsintr = dsintr | 0xf2; /* set bits 1, 4..7 */
-+ write_phy(regs, 0, MII_ISINTE_REG, dsintr);
-+ }
-+
-+ disable_mdi(regs);
-+ spin_unlock_irq(&lp->lock);
-+}
-+
-+/*
-+ * Disable the PHY interrupt
-+ */
-+static void disable_phyirq(struct net_device *dev, AT91PS_EMAC regs)
-+{
-+ struct at91_private *lp = (struct at91_private *) dev->priv;
-+ unsigned int dsintr;
-+
-+ spin_lock_irq(&lp->lock);
-+ enable_mdi(regs);
-+
-+ if (lp->phy_type == MII_DM9161_ID) { /* for Davicom PHY */
-+ read_phy(regs, 0, MII_DSINTR_REG, &dsintr);
-+ dsintr = dsintr | 0xf00; /* set bits 8..11 */
-+ write_phy(regs, 0, MII_DSINTR_REG, dsintr);
-+ }
-+ else if (lp->phy_type == MII_LXT971A_ID) { /* for Intel PHY */
-+ read_phy(regs, 0, MII_ISINTE_REG, &dsintr);
-+ dsintr = dsintr & ~0xf2; /* clear bits 1, 4..7 */
-+ write_phy(regs, 0, MII_ISINTE_REG, dsintr);
-+ }
-+
-+ disable_mdi(regs);
-+ spin_unlock_irq(&lp->lock);
-+
-+#ifdef CONFIG_MACH_CSB337
-+ AT91_SYS->PIOC_IDR = AT91C_PIO_PC2; /* Disable interrupt */
-+#else
-+ AT91_SYS->PIOC_IDR = AT91C_PIO_PC4; /* Disable interrupt */
-+#endif
-+ free_irq(AT91C_ID_PIOC, dev); /* Free interrupt handler */
-+}
-+
-+/*
-+ * Perform a software reset of the PHY.
-+ */
-+static void reset_phy(struct net_device *dev, AT91PS_EMAC regs)
-+{
-+ struct at91_private *lp = (struct at91_private *) dev->priv;
-+ unsigned int bmcr;
-+
-+ spin_lock_irq(&lp->lock);
-+ enable_mdi(regs);
-+
-+ /* Perform PHY reset */
-+ write_phy(regs, 0, MII_BMCR, BMCR_RESET);
-+
-+ /* Wait until PHY reset is complete */
-+ do {
-+ read_phy(regs, 0, MII_BMCR, &bmcr);
-+ } while (!(bmcr && BMCR_RESET));
-+
-+ disable_mdi(regs);
-+ spin_unlock_irq(&lp->lock);
-+}
-+
-+
-+/* ......................... ADDRESS MANAGEMENT ........................ */
-+
-+/*
-+ * Set the ethernet MAC address in dev->dev_addr
-+ */
-+static void get_mac_address(struct net_device *dev) {
-+ AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
-+ char addr[6];
-+ unsigned int hi, lo;
-+
-+ /* Check if bootloader set address in Specific-Address 1 */
-+ hi = regs->EMAC_SA1H;
-+ lo = regs->EMAC_SA1L;
-+ addr[0] = (lo & 0xff);
-+ addr[1] = (lo & 0xff00) >> 8;
-+ addr[2] = (lo & 0xff0000) >> 16;
-+ addr[3] = (lo & 0xff000000) >> 24;
-+ addr[4] = (hi & 0xff);
-+ addr[5] = (hi & 0xff00) >> 8;
-+
-+ if (is_valid_ether_addr(addr)) {
-+ memcpy(dev->dev_addr, &addr, 6);
-+ return;
-+ }
-+
-+ /* Check if bootloader set address in Specific-Address 2 */
-+ hi = regs->EMAC_SA2H;
-+ lo = regs->EMAC_SA2L;
-+ addr[0] = (lo & 0xff);
-+ addr[1] = (lo & 0xff00) >> 8;
-+ addr[2] = (lo & 0xff0000) >> 16;
-+ addr[3] = (lo & 0xff000000) >> 24;
-+ addr[4] = (hi & 0xff);
-+ addr[5] = (hi & 0xff00) >> 8;
-+
-+ if (is_valid_ether_addr(addr)) {
-+ memcpy(dev->dev_addr, &addr, 6);
-+ return;
-+ }
-+}
-+
-+/*
-+ * Program the hardware MAC address from dev->dev_addr.
-+ */
-+static void update_mac_address(struct net_device *dev)
-+{
-+ AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
-+
-+ regs->EMAC_SA1L = (dev->dev_addr[3] << 24) | (dev->dev_addr[2] << 16) | (dev->dev_addr[1] << 8) | (dev->dev_addr[0]);
-+ regs->EMAC_SA1H = (dev->dev_addr[5] << 8) | (dev->dev_addr[4]);
-+}
-+
-+#ifdef AT91_ETHER_ADDR_CONFIGURABLE
-+/*
-+ * Store the new hardware address in dev->dev_addr, and update the MAC.
-+ */
-+static int set_mac_address(struct net_device *dev, void* addr)
-+{
-+ struct sockaddr *address = addr;
-+
-+ if (!is_valid_ether_addr(address->sa_data))
-+ return -EADDRNOTAVAIL;
-+
-+ memcpy(dev->dev_addr, address->sa_data, dev->addr_len);
-+ update_mac_address(dev);
-+
-+ printk("%s: Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
-+ dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
-+ dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
-+
-+ return 0;
-+}
-+#endif
-+
-+/*
-+ * Add multicast addresses to the internal multicast-hash table.
-+ */
-+static void at91ether_sethashtable(struct net_device *dev, AT91PS_EMAC regs)
-+{
-+ struct dev_mc_list *curr;
-+ unsigned char mc_filter[2];
-+ unsigned int i, bitnr;
-+
-+ mc_filter[0] = mc_filter[1] = 0;
-+
-+ curr = dev->mc_list;
-+ for (i = 0; i < dev->mc_count; i++, curr = curr->next) {
-+ if (!curr) break; /* unexpected end of list */
-+
-+ bitnr = ether_crc(ETH_ALEN, curr->dmi_addr) >> 26;
-+ mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
-+ }
-+
-+ regs->EMAC_HSH = mc_filter[1];
-+ regs->EMAC_HSL = mc_filter[0];
-+}
-+
-+/*
-+ * Enable/Disable promiscuous and multicast modes.
-+ */
-+static void at91ether_set_rx_mode(struct net_device *dev)
-+{
-+ AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
-+
-+ if (dev->flags & IFF_PROMISC) { /* Enable promiscuous mode */
-+ regs->EMAC_CFG |= AT91C_EMAC_CAF;
-+ } else if (dev->flags & (~IFF_PROMISC)) { /* Disable promiscuous mode */
-+ regs->EMAC_CFG &= ~AT91C_EMAC_CAF;
-+ }
-+
-+ if (dev->flags & IFF_ALLMULTI) { /* Enable all multicast mode */
-+ regs->EMAC_HSH = -1;
-+ regs->EMAC_HSL = -1;
-+ regs->EMAC_CFG |= AT91C_EMAC_MTI;
-+ } else if (dev->mc_count > 0) { /* Enable specific multicasts */
-+ at91ether_sethashtable(dev, regs);
-+ regs->EMAC_CFG |= AT91C_EMAC_MTI;
-+ } else if (dev->flags & (~IFF_ALLMULTI)) { /* Disable all multicast mode */
-+ regs->EMAC_HSH = 0;
-+ regs->EMAC_HSL = 0;
-+ regs->EMAC_CFG &= ~AT91C_EMAC_MTI;
-+ }
-+}
-+
-+/* ............................... IOCTL ............................... */
-+
-+static int mdio_read(struct net_device *dev, int phy_id, int location)
-+{
-+ AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
-+ unsigned int value;
-+
-+ read_phy(regs, phy_id, location, &value);
-+ return value;
-+}
-+
-+static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
-+{
-+ AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
-+
-+ write_phy(regs, phy_id, location, value);
-+}
-+
-+/*
-+ * ethtool support.
-+ */
-+static int at91ether_ethtool_ioctl (struct net_device *dev, void *useraddr)
-+{
-+ struct at91_private *lp = (struct at91_private *) dev->priv;
-+ AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
-+ u32 ethcmd;
-+ int res = 0;
-+
-+ if (copy_from_user (&ethcmd, useraddr, sizeof (ethcmd)))
-+ return -EFAULT;
-+
-+ spin_lock_irq(&lp->lock);
-+ enable_mdi(regs);
-+
-+ switch (ethcmd) {
-+ case ETHTOOL_GSET: {
-+ struct ethtool_cmd ecmd = { ETHTOOL_GSET };
-+ res = mii_ethtool_gset(&lp->mii, &ecmd);
-+ if (lp->phy_media == PORT_FIBRE) { /* override media type since mii.c doesn't know */
-+ ecmd.supported = SUPPORTED_FIBRE;
-+ ecmd.port = PORT_FIBRE;
-+ }
-+ if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
-+ res = -EFAULT;
-+ break;
-+ }
-+ case ETHTOOL_SSET: {
-+ struct ethtool_cmd ecmd;
-+ if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
-+ res = -EFAULT;
-+ else
-+ res = mii_ethtool_sset(&lp->mii, &ecmd);
-+ break;
-+ }
-+ case ETHTOOL_NWAY_RST: {
-+ res = mii_nway_restart(&lp->mii);
-+ break;
-+ }
-+ case ETHTOOL_GLINK: {
-+ struct ethtool_value edata = { ETHTOOL_GLINK };
-+ edata.data = mii_link_ok(&lp->mii);
-+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
-+ res = -EFAULT;
-+ break;
-+ }
-+ default:
-+ res = -EOPNOTSUPP;
-+ }
-+
-+ disable_mdi(regs);
-+ spin_unlock_irq(&lp->lock);
-+
-+ return res;
-+}
-+
-+/*
-+ * User-space ioctl interface.
-+ */
-+static int at91ether_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-+{
-+ switch(cmd) {
-+ case SIOCETHTOOL:
-+ return at91ether_ethtool_ioctl(dev, (void *) rq->ifr_data);
-+ default:
-+ return -EOPNOTSUPP;
-+ }
-+}
-+
-+/* ................................ MAC ................................ */
-+
-+/*
-+ * Initialize and start the Receiver and Transmit subsystems
-+ */
-+static void at91ether_start(struct net_device *dev)
-+{
-+ AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
-+ struct at91_private *lp = (struct at91_private *) dev->priv;
-+ int i;
-+ struct recv_desc_bufs *dlist, *dlist_phys;
-+
-+ dlist = lp->dlist;
-+ dlist_phys = lp->dlist_phys;
-+
-+ for (i = 0; i < MAX_RX_DESCR; i++) {
-+ dlist->descriptors[i].addr = (unsigned int) &dlist_phys->recv_buf[i][0];
-+ dlist->descriptors[i].size = 0;
-+ }
-+
-+ /* Set the Wrap bit on the last descriptor */
-+ dlist->descriptors[i-1].addr |= EMAC_DESC_WRAP;
-+
-+ /* Reset buffer index */
-+ lp->rxBuffIndex = 0;
-+
-+ /* Program address of descriptor list in Rx Buffer Queue register */
-+ regs->EMAC_RBQP = (AT91_REG) dlist_phys;
-+
-+ /* Enable Receive and Transmit */
-+ regs->EMAC_CTL |= (AT91C_EMAC_RE | AT91C_EMAC_TE);
-+}
-+
-+/*
-+ * Open the ethernet interface
-+ */
-+static int at91ether_open(struct net_device *dev)
-+{
-+ struct at91_private *lp = (struct at91_private *) dev->priv;
-+ AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
-+
-+ if (!is_valid_ether_addr(dev->dev_addr))
-+ return -EADDRNOTAVAIL;
-+
-+ AT91_SYS->PMC_PCER = 1 << AT91C_ID_EMAC; /* Re-enable Peripheral clock */
-+ regs->EMAC_CTL |= AT91C_EMAC_CSR; /* Clear internal statistics */
-+
-+ /* Enable PHY interrupt */
-+ enable_phyirq(dev, regs);
-+
-+ /* Enable MAC interrupts */
-+ regs->EMAC_IER = AT91C_EMAC_RCOM | AT91C_EMAC_RBNA
-+ | AT91C_EMAC_TUND | AT91C_EMAC_RTRY | AT91C_EMAC_TCOM
-+ | AT91C_EMAC_ROVR | AT91C_EMAC_HRESP;
-+
-+ /* Determine current link speed */
-+ spin_lock_irq(&lp->lock);
-+ enable_mdi(regs);
-+ (void) update_linkspeed(dev, regs);
-+ disable_mdi(regs);
-+ spin_unlock_irq(&lp->lock);
-+
-+ at91ether_start(dev);
-+ netif_start_queue(dev);
-+ return 0;
-+}
-+
-+/*
-+ * Close the interface
-+ */
-+static int at91ether_close(struct net_device *dev)
-+{
-+ AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
-+
-+ /* Disable Receiver and Transmitter */
-+ regs->EMAC_CTL &= ~(AT91C_EMAC_TE | AT91C_EMAC_RE);
-+
-+ /* Disable PHY interrupt */
-+ disable_phyirq(dev, regs);
-+
-+ /* Disable MAC interrupts */
-+ regs->EMAC_IDR = AT91C_EMAC_RCOM | AT91C_EMAC_RBNA
-+ | AT91C_EMAC_TUND | AT91C_EMAC_RTRY | AT91C_EMAC_TCOM
-+ | AT91C_EMAC_ROVR | AT91C_EMAC_HRESP;
-+
-+ netif_stop_queue(dev);
-+
-+ AT91_SYS->PMC_PCDR = 1 << AT91C_ID_EMAC; /* Disable Peripheral clock */
-+
-+ return 0;
-+}
-+
-+/*
-+ * Transmit packet.
-+ */
-+static int at91ether_tx(struct sk_buff *skb, struct net_device *dev)
-+{
-+ AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
-+ struct at91_private *lp = (struct at91_private *) dev->priv;
-+
-+ if (regs->EMAC_TSR & AT91C_EMAC_BNQ) {
-+ netif_stop_queue(dev);
-+
-+ /* Store packet information (to free when Tx completed) */
-+ lp->skb = skb;
-+ lp->skb_length = skb->len;
-+ lp->skb_physaddr = pci_map_single(NULL, skb->data, skb->len, PCI_DMA_TODEVICE);
-+ lp->stats.tx_bytes += skb->len;
-+
-+ /* Set address of the data in the Transmit Address register */
-+ regs->EMAC_TAR = lp->skb_physaddr;
-+ /* Set length of the packet in the Transmit Control register */
-+ regs->EMAC_TCR = skb->len;
-+
-+ dev->trans_start = jiffies;
-+ } else {
-+ printk(KERN_ERR "at91_ether.c: at91ether_tx() called, but device is busy!\n");
-+ return 1; /* if we return anything but zero, dev.c:1055 calls kfree_skb(skb)
-+ on this skb, he also reports -ENETDOWN and printk's, so either
-+ we free and return(0) or don't free and return 1 */
-+ }
-+
-+ return 0;
-+}
-+
-+/*
-+ * Update the current statistics from the internal statistics registers.
-+ */
-+static struct net_device_stats *at91ether_stats(struct net_device *dev)
-+{
-+ struct at91_private *lp = (struct at91_private *) dev->priv;
-+ AT91PS_EMAC regs = (AT91PS_EMAC) dev->base_addr;
-+ int ale, lenerr, seqe, lcol, ecol;
-+
-+ if (netif_running(dev)) {
-+ lp->stats.rx_packets += regs->EMAC_OK; /* Good frames received */
-+ ale = regs->EMAC_ALE;
-+ lp->stats.rx_frame_errors += ale; /* Alignment errors */
-+ lenerr = regs->EMAC_ELR + regs->EMAC_USF;
-+ lp->stats.rx_length_errors += lenerr; /* Excessive Length or Undersize Frame error */
-+ seqe = regs->EMAC_SEQE;
-+ lp->stats.rx_crc_errors += seqe; /* CRC error */
-+ lp->stats.rx_fifo_errors += regs->EMAC_DRFC; /* Receive buffer not available */
-+ lp->stats.rx_errors += (ale + lenerr + seqe + regs->EMAC_CDE + regs->EMAC_RJB);
-+
-+ lp->stats.tx_packets += regs->EMAC_FRA; /* Frames successfully transmitted */
-+ lp->stats.tx_fifo_errors += regs->EMAC_TUE; /* Transmit FIFO underruns */
-+ lp->stats.tx_carrier_errors += regs->EMAC_CSE; /* Carrier Sense errors */
-+ lp->stats.tx_heartbeat_errors += regs->EMAC_SQEE; /* Heartbeat error */
-+
-+ lcol = regs->EMAC_LCOL;
-+ ecol = regs->EMAC_ECOL;
-+ lp->stats.tx_window_errors += lcol; /* Late collisions */
-+ lp->stats.tx_aborted_errors += ecol; /* 16 collisions */
-+
-+ lp->stats.collisions += (regs->EMAC_SCOL + regs->EMAC_MCOL + lcol + ecol);
-+ }
-+ return &lp->stats;
-+}
-+
-+/*
-+ * Extract received frame from buffer descriptors and sent to upper layers.
-+ * (Called from interrupt context)
-+ */
-+static void at91ether_rx(struct net_device *dev)
-+{
-+ struct at91_private *lp = (struct at91_private *) dev->priv;
-+ struct recv_desc_bufs *dlist;
-+ unsigned char *p_recv;
-+ struct sk_buff *skb;
-+ unsigned int pktlen;
-+
-+ dlist = lp->dlist;
-+ while (dlist->descriptors[lp->rxBuffIndex].addr & EMAC_DESC_DONE) {
-+ p_recv = dlist->recv_buf[lp->rxBuffIndex];
-+ pktlen = dlist->descriptors[lp->rxBuffIndex].size & 0x7ff; /* Length of frame including FCS */
-+ skb = alloc_skb(pktlen + 2, GFP_ATOMIC);
-+ if (skb != NULL) {
-+ skb_reserve(skb, 2);
-+ memcpy(skb_put(skb, pktlen), p_recv, pktlen);
-+
-+ skb->dev = dev;
-+ skb->protocol = eth_type_trans(skb, dev);
-+ skb->len = pktlen;
-+ dev->last_rx = jiffies;
-+ lp->stats.rx_bytes += pktlen;
-+ netif_rx(skb);
-+ }
-+ else {
-+ lp->stats.rx_dropped += 1;
-+ printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
-+ }
-+
-+ if (dlist->descriptors[lp->rxBuffIndex].size & EMAC_MULTICAST)
-+ lp->stats.multicast++;
-+
-+ dlist->descriptors[lp->rxBuffIndex].addr &= ~EMAC_DESC_DONE; /* reset ownership bit */
-+ if (lp->rxBuffIndex == MAX_RX_DESCR-1) /* wrap after last buffer */
-+ lp->rxBuffIndex = 0;
-+ else
-+ lp->rxBuffIndex++;
-+ }
-+}
-+
-+/*
-+ * MAC interrupt handler
-+ */
-+static void at91ether_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct net_device *dev = (struct net_device *) dev_id;
-+ struct at91_private *lp = (struct at91_private *) dev->priv;
-+ AT91PS_EMAC emac = (AT91PS_EMAC) dev->base_addr;
-+ unsigned long intstatus;
-+
-+ /* MAC Interrupt Status register indicates what interrupts are pending.
-+ It is automatically cleared once read. */
-+ intstatus = emac->EMAC_ISR;
-+
-+ if (intstatus & AT91C_EMAC_RCOM) /* Receive complete */
-+ at91ether_rx(dev);
-+
-+ if (intstatus & AT91C_EMAC_TCOM) { /* Transmit complete */
-+ /* The TCOM bit is set even if the transmission failed. */
-+ if (intstatus & (AT91C_EMAC_TUND | AT91C_EMAC_RTRY))
-+ lp->stats.tx_errors += 1;
-+
-+ dev_kfree_skb_irq(lp->skb);
-+ pci_unmap_single(NULL, lp->skb_physaddr, lp->skb_length, PCI_DMA_TODEVICE);
-+ netif_wake_queue(dev);
-+ }
-+
-+ if (intstatus & AT91C_EMAC_RBNA)
-+ printk("%s: RBNA error\n", dev->name);
-+ if (intstatus & AT91C_EMAC_ROVR)
-+ printk("%s: ROVR error\n", dev->name);
-+}
-+
-+/*
-+ * Initialize the ethernet interface
-+ */
-+static int at91ether_setup(struct net_device *dev, unsigned long phy_type)
-+{
-+ struct at91_private *lp;
-+ AT91PS_EMAC regs;
-+ static int already_initialized = 0;
-+ unsigned int val;
-+
-+ if (already_initialized)
-+ return 0;
-+
-+ dev = init_etherdev(dev, sizeof(struct at91_private));
-+ dev->base_addr = AT91C_VA_BASE_EMAC;
-+ dev->irq = AT91C_ID_EMAC;
-+ SET_MODULE_OWNER(dev);
-+
-+ /* Install the interrupt handler */
-+ if (request_irq(dev->irq, at91ether_interrupt, 0, dev->name, dev))
-+ return -EBUSY;
-+
-+ /* Allocate memory for private data structure */
-+ lp = (struct at91_private *) kmalloc(sizeof(struct at91_private), GFP_KERNEL);
-+ if (lp == NULL) {
-+ free_irq(dev->irq, dev);
-+ return -ENOMEM;
-+ }
-+ memset(lp, 0, sizeof(struct at91_private));
-+ dev->priv = lp;
-+
-+ /* Allocate memory for DMA Receive descriptors */
-+ lp->dlist = (struct recv_desc_bufs *) consistent_alloc(GFP_DMA | GFP_KERNEL, sizeof(struct recv_desc_bufs), (dma_addr_t *) &lp->dlist_phys);
-+ if (lp->dlist == NULL) {
-+ kfree(dev->priv);
-+ free_irq(dev->irq, dev);
-+ return -ENOMEM;
-+ }
-+
-+ spin_lock_init(&lp->lock);
-+
-+ ether_setup(dev);
-+ dev->open = at91ether_open;
-+ dev->stop = at91ether_close;
-+ dev->hard_start_xmit = at91ether_tx;
-+ dev->get_stats = at91ether_stats;
-+ dev->set_multicast_list = at91ether_set_rx_mode;
-+ dev->do_ioctl = at91ether_ioctl;
-+
-+#ifdef AT91_ETHER_ADDR_CONFIGURABLE
-+ dev->set_mac_address = set_mac_address;
-+#endif
-+
-+ get_mac_address(dev); /* Get ethernet address and store it in dev->dev_addr */
-+ update_mac_address(dev); /* Program ethernet address into MAC */
-+
-+ regs = (AT91PS_EMAC) dev->base_addr;
-+ regs->EMAC_CTL = 0;
-+
-+#ifdef CONFIG_AT91_ETHER_RMII
-+ regs->EMAC_CFG = AT91C_EMAC_BIG | AT91C_EMAC_RMII;
-+#else
-+ regs->EMAC_CFG = AT91C_EMAC_BIG;
-+#endif
-+ if (phy_type == MII_LXT971A_ID)
-+ regs->EMAC_CFG |= AT91C_EMAC_CLK_HCLK_64; /* MDIO clock = system clock/64 */
-+
-+ if (phy_type == MII_DM9161_ID) {
-+ spin_lock_irq(&lp->lock);
-+ enable_mdi(regs);
-+
-+ read_phy(regs, 0, MII_DSCR_REG, &val);
-+ if ((val & (1 << 10)) == 0) /* DSCR bit 10 is 0 -- fiber mode */
-+ lp->phy_media = PORT_FIBRE;
-+
-+ disable_mdi(regs);
-+ spin_unlock_irq(&lp->lock);
-+ }
-+
-+ lp->mii.dev = dev; /* Support for ethtool */
-+ lp->mii.mdio_read = mdio_read;
-+ lp->mii.mdio_write = mdio_write;
-+
-+ lp->phy_type = phy_type; /* Type of PHY connected */
-+
-+ /* Determine current link speed */
-+ spin_lock_irq(&lp->lock);
-+ enable_mdi(regs);
-+ (void) update_linkspeed(dev, regs);
-+ disable_mdi(regs);
-+ spin_unlock_irq(&lp->lock);
-+
-+ /* Display ethernet banner */
-+ printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%02x:%02x:%02x:%02x:%02x:%02x)\n",
-+ dev->name, (uint) dev->base_addr, dev->irq,
-+ regs->EMAC_CFG & AT91C_EMAC_SPD ? "100-" : "10-",
-+ regs->EMAC_CFG & AT91C_EMAC_FD ? "FullDuplex" : "HalfDuplex",
-+ dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
-+ dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
-+ if (phy_type == MII_DM9161_ID)
-+ printk(KERN_INFO "%s: Davicom 9196 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)");
-+ else if (phy_type == MII_LXT971A_ID)
-+ printk(KERN_INFO "%s: Intel LXT971A PHY\n", dev->name);
-+
-+ already_initialized = 1;
-+ return 0;
-+}
-+
-+/*
-+ * Detect MAC and PHY and perform initialization
-+ */
-+static int at91ether_probe(struct net_device *dev)
-+{
-+ AT91PS_EMAC regs = (AT91PS_EMAC) AT91C_VA_BASE_EMAC;
-+ unsigned int phyid1, phyid2;
-+ int detected = -1;
-+
-+ /* Configure the hardware - RMII vs MII mode */
-+#ifdef CONFIG_AT91_ETHER_RMII
-+ AT91_CfgPIO_EMAC_RMII();
-+#else
-+ AT91_CfgPIO_EMAC_MII();
-+#endif
-+
-+ AT91_CfgPIO_EMAC_PHY(); /* Configure PHY interrupt */
-+ AT91_SYS->PMC_PCER = 1 << AT91C_ID_EMAC; /* Enable Peripheral clock */
-+
-+ /* Read the PHY ID registers */
-+ enable_mdi(regs);
-+ read_phy(regs, 0, MII_PHYSID1, &phyid1);
-+ read_phy(regs, 0, MII_PHYSID2, &phyid2);
-+ disable_mdi(regs);
-+
-+ /* Davicom 9161: PHY_ID1 = 0x181 PHY_ID2 = B881 */
-+ if (((phyid1 << 16) | (phyid2 & 0xfff0)) == MII_DM9161_ID) {
-+ detected = at91ether_setup(dev, MII_DM9161_ID);
-+ }
-+ /* Intel LXT971A: PHY_ID1 = 0x13 PHY_ID2 = 78E0 */
-+ else if (((phyid1 << 16) | (phyid2 & 0xfff0)) == MII_LXT971A_ID) {
-+ detected = at91ether_setup(dev, MII_LXT971A_ID);
-+ }
-+
-+ AT91_SYS->PMC_PCDR = 1 << AT91C_ID_EMAC; /* Disable Peripheral clock */
-+
-+ return detected;
-+}
-+
-+static int __init at91ether_init(void)
-+{
-+ if (!at91ether_probe(&at91_dev))
-+ return register_netdev(&at91_dev);
-+
-+ return -1;
-+}
-+
-+static void __exit at91ether_exit(void)
-+{
-+ unregister_netdev(&at91_dev);
-+}
-+
-+module_init(at91ether_init)
-+module_exit(at91ether_exit)
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("AT91RM9200 EMAC Ethernet driver");
-+MODULE_AUTHOR("Andrew Victor");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/net/at91_ether.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,81 @@
-+/*
-+ * Ethernet driver for the Atmel AT91RM9200 (Thunder)
-+ *
-+ * (c) SAN People (Pty) Ltd
-+ *
-+ * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc.
-+ * Initial version by Rick Bronson.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef AT91_ETHERNET
-+#define AT91_ETHERNET
-+
-+#undef AT91_ETHER_ADDR_CONFIGURABLE /* MAC address can be changed? */
-+
-+
-+/* Davicom 9161 PHY */
-+#define MII_DM9161_ID 0x0181b880
-+
-+/* Davicom specific registers */
-+#define MII_DSCR_REG 16
-+#define MII_DSCSR_REG 17
-+#define MII_DSINTR_REG 21
-+
-+/* Intel LXT971A PHY */
-+#define MII_LXT971A_ID 0x001378E0
-+
-+/* Intel specific registers */
-+#define MII_ISINTE_REG 18
-+#define MII_ISINTS_REG 19
-+
-+/* ........................................................................ */
-+
-+#define MAX_RBUFF_SZ 0x600 /* 1518 rounded up */
-+#define MAX_RX_DESCR 9 /* max number of receive buffers */
-+
-+#define EMAC_DESC_DONE 0x00000001 /* bit for if DMA is done */
-+#define EMAC_DESC_WRAP 0x00000002 /* bit for wrap */
-+
-+#define EMAC_BROADCAST 0x80000000 /* broadcast address */
-+#define EMAC_MULTICAST 0x40000000 /* multicast address */
-+#define EMAC_UNICAST 0x20000000 /* unicast address */
-+
-+struct rbf_t
-+{
-+ unsigned int addr;
-+ unsigned long size;
-+};
-+
-+struct recv_desc_bufs
-+{
-+ struct rbf_t descriptors[MAX_RX_DESCR]; /* must be on sizeof (rbf_t) boundary */
-+ char recv_buf[MAX_RX_DESCR][MAX_RBUFF_SZ]; /* must be on long boundary */
-+};
-+
-+struct at91_private
-+{
-+ struct net_device_stats stats;
-+ struct mii_if_info mii; /* ethtool support */
-+
-+ /* PHY */
-+ unsigned long phy_type; /* type of PHY (PHY_ID) */
-+ spinlock_t lock; /* lock for MDI interface */
-+ short phy_media; /* media interface type */
-+
-+ /* Transmit */
-+ struct sk_buff *skb; /* holds skb until xmit interrupt completes */
-+ dma_addr_t skb_physaddr; /* phys addr from pci_map_single */
-+ int skb_length; /* saved skb length for pci_unmap_single */
-+
-+ /* Receive */
-+ int rxBuffIndex; /* index into receive descriptor list */
-+ struct recv_desc_bufs *dlist; /* descriptor list address */
-+ struct recv_desc_bufs *dlist_phys; /* descriptor list physical address */
-+};
-+
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/rtc/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,15 @@
-+# File: drivers/at91/rtc/Makefile
-+#
-+# Makefile for the Atmel AT91RM9200 real time clock device drivers
-+#
-+
-+O_TARGET := at91rtc.o
-+
-+obj-y :=
-+obj-m :=
-+obj-n :=
-+obj- :=
-+
-+obj-$(CONFIG_AT91_RTC) += at91_rtc.o
-+
-+include $(TOPDIR)/Rules.make
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/rtc/at91_rtc.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,441 @@
-+/*
-+ * Real Time Clock interface for Linux on Atmel AT91RM9200
-+ *
-+ * Copyright (c) 2002 Rick Bronson
-+ *
-+ * Based on sa1100-rtc.c by Nils Faerber
-+ * Based on rtc.c by Paul Gortmaker
-+ * Date/time conversion routines taken from arch/arm/kernel/time.c
-+ * by Linus Torvalds and Russell King
-+ * and the GNU C Library
-+ * ( ... I love the GPL ... just take what you need! ;)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/fs.h>
-+#include <linux/miscdevice.h>
-+#include <linux/string.h>
-+#include <linux/init.h>
-+#include <linux/poll.h>
-+#include <linux/proc_fs.h>
-+#include <asm/bitops.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <linux/rtc.h>
-+
-+#define AT91_RTC_FREQ 1
-+#define EPOCH 1970
-+
-+/* Those are the bits from a classic RTC we want to mimic */
-+#define AT91_RTC_IRQF 0x80 /* any of the following 3 is active */
-+#define AT91_RTC_PF 0x40
-+#define AT91_RTC_AF 0x20
-+#define AT91_RTC_UF 0x10
-+
-+#define BCD2BIN(val) (((val)&15) + ((val)>>4)*10)
-+#define BIN2BCD(val) ((((val)/10)<<4) + (val)%10)
-+
-+static unsigned long rtc_status = 0;
-+static unsigned long rtc_irq_data;
-+static unsigned int at91_alarm_year = EPOCH;
-+
-+static struct fasync_struct *at91_rtc_async_queue;
-+static DECLARE_WAIT_QUEUE_HEAD(at91_rtc_wait);
-+static DECLARE_WAIT_QUEUE_HEAD(at91_rtc_update);
-+static spinlock_t at91_rtc_updlock; /* some spinlocks for saving/restoring interrupt levels */
-+extern spinlock_t at91_rtc_lock;
-+
-+static const unsigned char days_in_mo[] =
-+ { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-+
-+#define is_leap(year) \
-+ ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
-+
-+static const unsigned short int __mon_yday[2][13] =
-+{
-+ /* Normal years. */
-+ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
-+ /* Leap years. */
-+ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
-+};
-+
-+/*
-+ * Returns day since start of the year [0-365]
-+ * (from drivers/char/efirtc.c)
-+ */
-+static inline int compute_yday(int year, int month, int day)
-+{
-+ return __mon_yday[is_leap(year)][month] + day-1;
-+}
-+
-+/*
-+ * Set current time and date in RTC
-+ */
-+static void at91_rtc_settime(struct rtc_time *tval)
-+{
-+ unsigned long flags;
-+
-+ /* Stop Time/Calendar from counting */
-+ AT91_SYS->RTC_CR |= (AT91C_RTC_UPDCAL | AT91C_RTC_UPDTIM);
-+
-+ spin_lock_irqsave(&at91_rtc_updlock, flags); /* stop int's else we wakeup b4 we sleep */
-+ AT91_SYS->RTC_IER = AT91C_RTC_ACKUPD;
-+ interruptible_sleep_on(&at91_rtc_update); /* wait for ACKUPD interrupt to hit */
-+ spin_unlock_irqrestore(&at91_rtc_updlock, flags);
-+ AT91_SYS->RTC_IDR = AT91C_RTC_ACKUPD;
-+
-+ AT91_SYS->RTC_TIMR = BIN2BCD(tval->tm_sec) << 0
-+ | BIN2BCD(tval->tm_min) << 8
-+ | BIN2BCD(tval->tm_hour) << 16;
-+
-+ AT91_SYS->RTC_CALR = BIN2BCD((tval->tm_year + 1900) / 100) /* century */
-+ | BIN2BCD(tval->tm_year % 100) << 8 /* year */
-+ | BIN2BCD(tval->tm_mon + 1) << 16 /* tm_mon starts at zero */
-+ | BIN2BCD(tval->tm_wday + 1) << 21 /* day of the week [0-6], Sunday=0 */
-+ | BIN2BCD(tval->tm_mday) << 24;
-+
-+ /* Restart Time/Calendar */
-+ AT91_SYS->RTC_CR &= ~(AT91C_RTC_UPDCAL | AT91C_RTC_UPDTIM);
-+}
-+
-+/*
-+ * Decode time/date into rtc_time structure
-+ */
-+static void at91_rtc_decodetime(AT91_REG *timereg, AT91_REG *calreg, struct rtc_time *tval)
-+{
-+ unsigned int time, date;
-+
-+ do { /* must read twice in case it changes */
-+ time = *timereg;
-+ date = *calreg;
-+ } while ((time != *timereg) || (date != *calreg));
-+
-+ tval->tm_sec = BCD2BIN((time & AT91C_RTC_SEC) >> 0);
-+ tval->tm_min = BCD2BIN((time & AT91C_RTC_MIN) >> 8);
-+ tval->tm_hour = BCD2BIN((time & AT91C_RTC_HOUR) >> 16);
-+
-+ /* The Calendar Alarm register does not have a field for
-+ the year - so these will return an invalid value. When an
-+ alarm is set, at91_alarm_year wille store the current year. */
-+ tval->tm_year = BCD2BIN(date & AT91C_RTC_CENT) * 100; /* century */
-+ tval->tm_year += BCD2BIN((date & AT91C_RTC_YEAR) >> 8); /* year */
-+
-+ tval->tm_wday = BCD2BIN((date & AT91C_RTC_DAY) >> 21) - 1; /* day of the week [0-6], Sunday=0 */
-+ tval->tm_mon = BCD2BIN(((date & AT91C_RTC_MONTH) >> 16) - 1);
-+ tval->tm_mday = BCD2BIN((date & AT91C_RTC_DATE) >> 24);
-+}
-+
-+/*
-+ * IRQ handler for the RTC
-+ */
-+static void at91_rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ unsigned int rtsr = AT91_SYS->RTC_SR & AT91_SYS->RTC_IMR;
-+
-+ /* update irq data & counter */
-+ if (rtsr) { /* this interrupt is shared! Is it ours? */
-+ if (rtsr & AT91C_RTC_ALARM)
-+ rtc_irq_data |= (AT91_RTC_AF | AT91_RTC_IRQF);
-+ if (rtsr & AT91C_RTC_SECEV)
-+ rtc_irq_data |= (AT91_RTC_UF | AT91_RTC_IRQF);
-+ if (rtsr & AT91C_RTC_ACKUPD)
-+ wake_up_interruptible(&at91_rtc_update);
-+ rtc_irq_data += 0x100;
-+ AT91_SYS->RTC_SCCR = rtsr; /* clear status reg */
-+
-+ /* wake up waiting process */
-+ wake_up_interruptible(&at91_rtc_wait);
-+ kill_fasync(&at91_rtc_async_queue, SIGIO, POLL_IN);
-+ }
-+}
-+
-+static int at91_rtc_open(struct inode *inode, struct file *file)
-+{
-+ if (test_and_set_bit(1, &rtc_status))
-+ return -EBUSY;
-+ rtc_irq_data = 0;
-+ return 0;
-+}
-+
-+static int at91_rtc_release(struct inode *inode, struct file *file)
-+{
-+ rtc_status = 0;
-+ return 0;
-+}
-+
-+static int at91_rtc_fasync(int fd, struct file *filp, int on)
-+{
-+ return fasync_helper(fd, filp, on, &at91_rtc_async_queue);
-+}
-+
-+static unsigned int at91_rtc_poll(struct file *file, poll_table * wait)
-+{
-+ poll_wait(file, &at91_rtc_wait, wait);
-+ return (rtc_irq_data) ? 0 : POLLIN | POLLRDNORM;
-+}
-+
-+static ssize_t at91_rtc_read(struct file * file, char *buf, size_t count, loff_t * ppos)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ unsigned long data;
-+ ssize_t retval;
-+
-+ if (count < sizeof(unsigned long))
-+ return -EINVAL;
-+
-+ add_wait_queue(&at91_rtc_wait, &wait);
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ for (;;) {
-+ spin_lock_irq(&at91_rtc_lock);
-+ data = rtc_irq_data;
-+ if (data != 0) {
-+ rtc_irq_data = 0;
-+ break;
-+ }
-+ spin_unlock_irq(&at91_rtc_lock);
-+
-+ if (file->f_flags & O_NONBLOCK) {
-+ retval = -EAGAIN;
-+ goto out;
-+ }
-+
-+ if (signal_pending(current)) {
-+ retval = -ERESTARTSYS;
-+ goto out;
-+ }
-+
-+ schedule();
-+ }
-+ spin_unlock_irq(&at91_rtc_lock);
-+
-+ data -= 0x100; /* the first IRQ wasn't actually missed */
-+ retval = put_user(data, (unsigned long *) buf);
-+ if (!retval)
-+ retval = sizeof(unsigned long);
-+
-+out:
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&at91_rtc_wait, &wait);
-+ return retval;
-+}
-+
-+/*
-+ * Handle commands from user-space
-+ */
-+static int at91_rtc_ioctl(struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ struct rtc_time tm, tm2;
-+ int ret = 0;
-+
-+ spin_lock_irq(&at91_rtc_lock);
-+ switch (cmd) {
-+ case RTC_AIE_OFF: /* alarm off */
-+ AT91_SYS->RTC_IDR = AT91C_RTC_ALARM;
-+ rtc_irq_data = 0;
-+ break;
-+ case RTC_AIE_ON: /* alarm on */
-+ AT91_SYS->RTC_IER = AT91C_RTC_ALARM;
-+ rtc_irq_data = 0;
-+ break;
-+ case RTC_UIE_OFF: /* update off */
-+ AT91_SYS->RTC_IDR = AT91C_RTC_SECEV;
-+ rtc_irq_data = 0;
-+ break;
-+ case RTC_UIE_ON: /* update on */
-+ AT91_SYS->RTC_IER = AT91C_RTC_SECEV;
-+ rtc_irq_data = 0;
-+ break;
-+ case RTC_PIE_OFF: /* periodic off */
-+ AT91_SYS->RTC_IDR = AT91C_RTC_SECEV;
-+ rtc_irq_data = 0;
-+ break;
-+ case RTC_PIE_ON: /* periodic on */
-+ AT91_SYS->RTC_IER = AT91C_RTC_SECEV;
-+ rtc_irq_data = 0;
-+ break;
-+ case RTC_ALM_READ: /* read alarm */
-+ memset(&tm, 0, sizeof(struct rtc_time));
-+ at91_rtc_decodetime(&(AT91_SYS->RTC_TIMALR), &(AT91_SYS->RTC_CALALR), &tm);
-+ tm.tm_yday = compute_yday(tm.tm_year, tm.tm_mon, tm.tm_mday);
-+ tm.tm_year = at91_alarm_year - 1900;
-+ ret = copy_to_user((void *) arg, &tm, sizeof(tm)) ? -EFAULT : 0;
-+ break;
-+ case RTC_ALM_SET: /* set alarm */
-+ if (copy_from_user(&tm2, (struct rtc_time *) arg, sizeof(tm2)))
-+ ret = -EFAULT;
-+ else {
-+ at91_rtc_decodetime(&(AT91_SYS->RTC_TIMR), &(AT91_SYS->RTC_CALR), &tm);
-+ at91_alarm_year = tm.tm_year;
-+ if ((unsigned) tm2.tm_hour < 24) /* do some range checking */
-+ tm.tm_hour = tm2.tm_hour;
-+ if ((unsigned) tm2.tm_min < 60)
-+ tm.tm_min = tm2.tm_min;
-+ if ((unsigned) tm2.tm_sec < 60)
-+ tm.tm_sec = tm2.tm_sec;
-+ AT91_SYS->RTC_TIMALR = BIN2BCD(tm.tm_sec) << 0
-+ | BIN2BCD(tm.tm_min) << 8
-+ | BIN2BCD(tm.tm_hour) << 16
-+ | AT91C_RTC_HOUREN | AT91C_RTC_MINEN
-+ | AT91C_RTC_SECEN;
-+ AT91_SYS->RTC_CALALR = BIN2BCD(tm.tm_mon + 1) << 16 /* tm_mon starts at zero */
-+ | BIN2BCD(tm.tm_mday) << 24
-+ | AT91C_RTC_DATEEN | AT91C_RTC_MONTHEN;
-+ }
-+ break;
-+ case RTC_RD_TIME: /* read time */
-+ memset(&tm, 0, sizeof(struct rtc_time));
-+ at91_rtc_decodetime(&(AT91_SYS->RTC_TIMR), &(AT91_SYS->RTC_CALR), &tm);
-+ tm.tm_yday = compute_yday(tm.tm_year, tm.tm_mon, tm.tm_mday);
-+ tm.tm_year = tm.tm_year - 1900;
-+ ret = copy_to_user((void *) arg, &tm, sizeof(tm)) ? -EFAULT : 0;
-+ break;
-+ case RTC_SET_TIME: /* set time */
-+ if (!capable(CAP_SYS_TIME))
-+ ret = -EACCES;
-+ else {
-+ if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(tm)))
-+ ret = -EFAULT;
-+ else {
-+ int tm_year = tm.tm_year + 1900;
-+ if (tm_year < EPOCH
-+ || (unsigned) tm.tm_mon >= 12
-+ || tm.tm_mday < 1
-+ || tm.tm_mday > (days_in_mo[tm.tm_mon] + (tm.tm_mon == 1 && is_leap(tm_year)))
-+ || (unsigned) tm.tm_hour >= 24
-+ || (unsigned) tm.tm_min >= 60
-+ || (unsigned) tm.tm_sec >= 60)
-+ ret = -EINVAL;
-+ else
-+ at91_rtc_settime(&tm);
-+ }
-+ }
-+ break;
-+ case RTC_IRQP_READ: /* read periodic alarm frequency */
-+ ret = put_user(AT91_RTC_FREQ, (unsigned long *) arg);
-+ break;
-+ case RTC_IRQP_SET: /* set periodic alarm frequency */
-+ if (arg != AT91_RTC_FREQ)
-+ ret = -EINVAL;
-+ break;
-+ case RTC_EPOCH_READ: /* read epoch */
-+ ret = put_user(EPOCH, (unsigned long *) arg);
-+ break;
-+ default:
-+ ret = -EINVAL;
-+ break;
-+ }
-+ spin_unlock_irq(&at91_rtc_lock);
-+ return ret;
-+}
-+
-+/*
-+ * Provide RTC information in /proc/driver/rtc
-+ */
-+static int at91_rtc_read_proc(char *page, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ char *p = page;
-+ int len;
-+ struct rtc_time tm;
-+
-+ at91_rtc_decodetime(&(AT91_SYS->RTC_TIMR), &(AT91_SYS->RTC_CALR), &tm);
-+ p += sprintf(p, "rtc_time\t: %02d:%02d:%02d\n"
-+ "rtc_date\t: %04d-%02d-%02d\n"
-+ "rtc_epoch\t: %04d\n",
-+ tm.tm_hour, tm.tm_min, tm.tm_sec,
-+ tm.tm_year, tm.tm_mon + 1, tm.tm_mday, EPOCH);
-+ at91_rtc_decodetime(&(AT91_SYS->RTC_TIMALR), &(AT91_SYS->RTC_CALALR), &tm);
-+ p += sprintf(p, "alrm_time\t: %02d:%02d:%02d\n"
-+ "alrm_date\t: %04d-%02d-%02d\n",
-+ tm.tm_hour, tm.tm_min, tm.tm_sec,
-+ at91_alarm_year, tm.tm_mon + 1, tm.tm_mday);
-+ p += sprintf(p, "alarm_IRQ\t: %s\n", (AT91_SYS->RTC_IMR & AT91C_RTC_ALARM) ? "yes" : "no");
-+ p += sprintf(p, "update_IRQ\t: %s\n", (AT91_SYS->RTC_IMR & AT91C_RTC_ACKUPD) ? "yes" : "no");
-+ p += sprintf(p, "periodic_IRQ\t: %s\n", (AT91_SYS->RTC_IMR & AT91C_RTC_SECEV) ? "yes" : "no");
-+ p += sprintf(p, "periodic_freq\t: %ld\n", (unsigned long) AT91_RTC_FREQ);
-+
-+ len = (p - page) - off;
-+ if (len < 0)
-+ len = 0;
-+
-+ *eof = (len <= count) ? 1 : 0;
-+ *start = page + off;
-+
-+ return len;
-+}
-+
-+static struct file_operations at91_rtc_fops = {
-+ owner:THIS_MODULE,
-+ llseek:no_llseek,
-+ read:at91_rtc_read,
-+ poll:at91_rtc_poll,
-+ ioctl:at91_rtc_ioctl,
-+ open:at91_rtc_open,
-+ release:at91_rtc_release,
-+ fasync:at91_rtc_fasync,
-+};
-+
-+static struct miscdevice at91_rtc_miscdev = {
-+ minor:RTC_MINOR,
-+ name:"rtc",
-+ fops:&at91_rtc_fops,
-+};
-+
-+/*
-+ * Initialize and install RTC driver
-+ */
-+static int __init at91_rtc_init(void)
-+{
-+ int ret;
-+
-+ AT91_SYS->RTC_CR = 0;
-+ AT91_SYS->RTC_MR = 0; /* put in 24 hour format */
-+ /* Disable all interrupts */
-+ AT91_SYS->RTC_IDR = AT91C_RTC_ACKUPD | AT91C_RTC_ALARM | AT91C_RTC_SECEV | AT91C_RTC_TIMEV | AT91C_RTC_CALEV;
-+
-+ spin_lock_init(&at91_rtc_updlock);
-+ spin_lock_init(&at91_rtc_lock);
-+
-+ misc_register(&at91_rtc_miscdev);
-+ create_proc_read_entry("driver/rtc", 0, 0, at91_rtc_read_proc, NULL);
-+ ret = request_irq(AT91C_ID_SYS, at91_rtc_interrupt, SA_SHIRQ,
-+ "at91_rtc", &rtc_status);
-+ if (ret) {
-+ printk(KERN_ERR "at91_rtc: IRQ %d already in use.\n", AT91C_ID_SYS);
-+ remove_proc_entry("driver/rtc", NULL);
-+ misc_deregister(&at91_rtc_miscdev);
-+ return ret;
-+ }
-+
-+ printk(KERN_INFO "AT91 Real Time Clock driver\n");
-+ return 0;
-+}
-+
-+/*
-+ * Disable and remove the RTC driver
-+ */
-+static void __exit at91_rtc_exit(void)
-+{
-+ /* Disable all interrupts */
-+ AT91_SYS->RTC_IDR = AT91C_RTC_ACKUPD | AT91C_RTC_ALARM | AT91C_RTC_SECEV | AT91C_RTC_TIMEV | AT91C_RTC_CALEV;
-+ free_irq(AT91C_ID_SYS, &rtc_status);
-+
-+ rtc_status = 0;
-+ remove_proc_entry("driver/rtc", NULL);
-+ misc_deregister(&at91_rtc_miscdev);
-+}
-+
-+module_init(at91_rtc_init);
-+module_exit(at91_rtc_exit);
-+
-+MODULE_AUTHOR("Rick Bronson");
-+MODULE_DESCRIPTION("AT91 Realtime Clock Driver (AT91_RTC)");
-+MODULE_LICENSE("GPL");
-+EXPORT_NO_SYMBOLS;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/serial/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,15 @@
-+# File: drivers/at91/serial/Makefile
-+#
-+# Makefile for the Atmel AT91RM9200 serial and console device drivers
-+#
-+
-+O_TARGET := at91serial.o
-+
-+obj-y :=
-+obj-m :=
-+obj-n :=
-+obj- :=
-+
-+obj-$(CONFIG_SERIAL_AT91) += at91_serial.o
-+
-+include $(TOPDIR)/Rules.make
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/serial/at91_serial.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,870 @@
-+/*
-+ * linux/drivers/char/at91_serial.c
-+ *
-+ * Driver for Atmel AT91RM9200 Serial ports
-+ *
-+ * Copyright (c) Rick Bronson
-+ *
-+ * Based on drivers/char/serial_sa1100.c, by Deep Blue Solutions Ltd.
-+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/tty.h>
-+#include <linux/ioport.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/serial.h>
-+#include <linux/console.h>
-+#include <linux/sysrq.h>
-+
-+#include <asm/arch/AT91RM9200_USART.h>
-+#include <asm/mach/serial_at91rm9200.h>
-+#include <asm/arch/pio.h>
-+
-+
-+#if defined(CONFIG_SERIAL_AT91_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-+#define SUPPORT_SYSRQ
-+#endif
-+
-+#include <linux/serial_core.h>
-+
-+#define SERIAL_AT91_MAJOR TTY_MAJOR
-+#define CALLOUT_AT91_MAJOR TTYAUX_MAJOR
-+#define MINOR_START 64
-+
-+#define AT91C_VA_BASE_DBGU ((unsigned long) &(AT91_SYS->DBGU_CR))
-+#define AT91_ISR_PASS_LIMIT 256
-+
-+#define UART_PUT_CR(port,v) ((AT91PS_USART)(port)->membase)->US_CR = v
-+#define UART_GET_MR(port) ((AT91PS_USART)(port)->membase)->US_MR
-+#define UART_PUT_MR(port,v) ((AT91PS_USART)(port)->membase)->US_MR = v
-+#define UART_PUT_IER(port,v) ((AT91PS_USART)(port)->membase)->US_IER = v
-+#define UART_PUT_IDR(port,v) ((AT91PS_USART)(port)->membase)->US_IDR = v
-+#define UART_GET_IMR(port) ((AT91PS_USART)(port)->membase)->US_IMR
-+#define UART_GET_CSR(port) ((AT91PS_USART)(port)->membase)->US_CSR
-+#define UART_GET_CHAR(port) ((AT91PS_USART)(port)->membase)->US_RHR
-+#define UART_PUT_CHAR(port,v) ((AT91PS_USART)(port)->membase)->US_THR = v
-+#define UART_GET_BRGR(port) ((AT91PS_USART)(port)->membase)->US_BRGR
-+#define UART_PUT_BRGR(port,v) ((AT91PS_USART)(port)->membase)->US_BRGR = v
-+#define UART_PUT_RTOR(port,v) ((AT91PS_USART)(port)->membase)->US_RTOR = v
-+
-+// #define UART_GET_CR(port) ((AT91PS_USART)(port)->membase)->US_CR // is write-only
-+
-+ /* PDC registers */
-+#define UART_PUT_PTCR(port,v) ((AT91PS_USART)(port)->membase)->US_PTCR = v
-+#define UART_PUT_RPR(port,v) ((AT91PS_USART)(port)->membase)->US_RPR = v
-+#define UART_PUT_RCR(port,v) ((AT91PS_USART)(port)->membase)->US_RCR = v
-+#define UART_GET_RCR(port) ((AT91PS_USART)(port)->membase)->US_RCR
-+#define UART_PUT_RNPR(port,v) ((AT91PS_USART)(port)->membase)->US_RNPR = v
-+#define UART_PUT_RNCR(port,v) ((AT91PS_USART)(port)->membase)->US_RNCR = v
-+
-+static struct tty_driver normal, callout;
-+static struct tty_struct *at91_table[AT91C_NR_UART];
-+static struct termios *at91_termios[AT91C_NR_UART], *at91_termios_locked[AT91C_NR_UART];
-+
-+const int at91_serialmap[AT91C_NR_UART] = AT91C_UART_MAP;
-+
-+static int (*at91_open)(struct uart_port *);
-+static void (*at91_close)(struct uart_port *);
-+
-+#ifdef SUPPORT_SYSRQ
-+static struct console at91_console;
-+#endif
-+
-+/*
-+ * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty.
-+ */
-+static u_int at91_tx_empty(struct uart_port *port)
-+{
-+ return UART_GET_CSR(port) & AT91C_US_TXEMPTY ? TIOCSER_TEMT : 0;
-+}
-+
-+/*
-+ * Set state of the modem control output lines
-+ */
-+static void at91_set_mctrl(struct uart_port *port, u_int mctrl)
-+{
-+ unsigned int control = 0;
-+
-+ if (mctrl & TIOCM_RTS)
-+ control |= AT91C_US_RTSEN;
-+ else
-+ control |= AT91C_US_RTSDIS;
-+
-+ if (mctrl & TIOCM_DTR)
-+ control |= AT91C_US_DTREN;
-+ else
-+ control |= AT91C_US_DTRDIS;
-+
-+ UART_PUT_CR(port,control);
-+}
-+
-+/*
-+ * Get state of the modem control input lines
-+ */
-+static u_int at91_get_mctrl(struct uart_port *port)
-+{
-+ unsigned int status, ret = 0;
-+
-+ status = UART_GET_CSR(port);
-+ if (status & AT91C_US_DCD)
-+ ret |= TIOCM_CD;
-+ if (status & AT91C_US_CTS)
-+ ret |= TIOCM_CTS;
-+ if (status & AT91C_US_DSR)
-+ ret |= TIOCM_DSR;
-+ if (status & AT91C_US_RI)
-+ ret |= TIOCM_RI;
-+
-+ return ret;
-+}
-+
-+/*
-+ * Stop transmitting.
-+ */
-+static void at91_stop_tx(struct uart_port *port, u_int from_tty)
-+{
-+ UART_PUT_IDR(port, AT91C_US_TXRDY);
-+ port->read_status_mask &= ~AT91C_US_TXRDY;
-+}
-+
-+/*
-+ * Start transmitting.
-+ */
-+static void at91_start_tx(struct uart_port *port, u_int from_tty)
-+{
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+ port->read_status_mask |= AT91C_US_TXRDY;
-+ UART_PUT_IER(port, AT91C_US_TXRDY);
-+ local_irq_restore(flags);
-+}
-+
-+/*
-+ * Stop receiving - port is in process of being closed.
-+ */
-+static void at91_stop_rx(struct uart_port *port)
-+{
-+ UART_PUT_IDR(port, AT91C_US_RXRDY);
-+}
-+
-+/*
-+ * Enable modem status interrupts
-+ */
-+static void at91_enable_ms(struct uart_port *port)
-+{
-+ UART_PUT_IER(port, AT91C_US_RIIC | AT91C_US_DSRIC | AT91C_US_DCDIC | AT91C_US_CTSIC);
-+}
-+
-+/*
-+ * Control the transmission of a break signal
-+ */
-+static void at91_break_ctl(struct uart_port *port, int break_state)
-+{
-+ if (break_state != 0)
-+ UART_PUT_CR(port, AT91C_US_STTBRK); /* start break */
-+ else
-+ UART_PUT_CR(port, AT91C_US_STPBRK); /* stop break */
-+}
-+
-+/*
-+ * Characters received (called from interrupt handler)
-+ */
-+static void at91_rx_chars(struct uart_port *port, struct pt_regs *regs)
-+{
-+ struct uart_info *info = port->info;
-+ struct tty_struct *tty = info->tty;
-+ unsigned int status, ch, flg, ignored = 0;
-+
-+ status = UART_GET_CSR(port);
-+ while (status & (AT91C_US_RXRDY)) {
-+ ch = UART_GET_CHAR(port);
-+
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+ goto ignore_char;
-+ port->icount.rx++;
-+
-+ flg = TTY_NORMAL;
-+
-+ /*
-+ * note that the error handling code is
-+ * out of the main execution path
-+ */
-+ if (status & (AT91C_US_PARE | AT91C_US_FRAME | AT91C_US_OVRE))
-+ goto handle_error;
-+
-+ if (uart_handle_sysrq_char(port, ch, regs))
-+ goto ignore_char;
-+
-+ error_return:
-+ *tty->flip.flag_buf_ptr++ = flg;
-+ *tty->flip.char_buf_ptr++ = ch;
-+ tty->flip.count++;
-+ ignore_char:
-+ status = UART_GET_CSR(port);
-+ }
-+out:
-+ tty_flip_buffer_push(tty);
-+ return;
-+
-+handle_error:
-+ if (status & (AT91C_US_PARE | AT91C_US_FRAME | AT91C_US_OVRE))
-+ UART_PUT_CR(port, AT91C_US_RSTSTA); /* clear error */
-+ if (status & (AT91C_US_PARE))
-+ port->icount.parity++;
-+ else if (status & (AT91C_US_FRAME))
-+ port->icount.frame++;
-+ if (status & (AT91C_US_OVRE))
-+ port->icount.overrun++;
-+
-+ if (status & port->ignore_status_mask) {
-+ if (++ignored > 100)
-+ goto out;
-+ goto ignore_char;
-+ }
-+
-+ status &= port->read_status_mask;
-+
-+ UART_PUT_CR(port, AT91C_US_RSTSTA); /* clear error */
-+ if (status & AT91C_US_PARE)
-+ flg = TTY_PARITY;
-+ else if (status & AT91C_US_FRAME)
-+ flg = TTY_FRAME;
-+
-+ if (status & AT91C_US_OVRE) {
-+ /*
-+ * overrun does *not* affect the character
-+ * we read from the FIFO
-+ */
-+ *tty->flip.flag_buf_ptr++ = flg;
-+ *tty->flip.char_buf_ptr++ = ch;
-+ tty->flip.count++;
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+ goto ignore_char;
-+ ch = 0;
-+ flg = TTY_OVERRUN;
-+ }
-+#ifdef SUPPORT_SYSRQ
-+ port->sysrq = 0;
-+#endif
-+ goto error_return;
-+}
-+
-+/*
-+ * Transmit characters (called from interrupt handler)
-+ */
-+static void at91_tx_chars(struct uart_port *port)
-+{
-+ struct circ_buf *xmit = &port->info->xmit;
-+
-+ if (port->x_char) {
-+ UART_PUT_CHAR(port, port->x_char);
-+ port->icount.tx++;
-+ port->x_char = 0;
-+ return;
-+ }
-+ if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
-+ at91_stop_tx(port, 0);
-+ return;
-+ }
-+
-+ while (UART_GET_CSR(port) & AT91C_US_TXRDY) {
-+ UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
-+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-+ port->icount.tx++;
-+ if (uart_circ_empty(xmit))
-+ break;
-+ }
-+
-+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-+ uart_write_wakeup(port);
-+
-+ if (uart_circ_empty(xmit))
-+ at91_stop_tx(port, 0);
-+}
-+
-+/*
-+ * Interrupt handler
-+ */
-+static void at91_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct uart_port *port = dev_id;
-+ unsigned int status, pending, pass_counter = 0;
-+
-+ status = UART_GET_CSR(port);
-+ pending = status & port->read_status_mask;
-+ if (pending) {
-+ do {
-+ if (pending & AT91C_US_RXRDY)
-+ at91_rx_chars(port, regs);
-+
-+ /* Clear the relevent break bits */
-+ if (pending & AT91C_US_RXBRK) {
-+ UART_PUT_CR(port, AT91C_US_RSTSTA);
-+ port->icount.brk++;
-+#ifdef SUPPORT_SYSRQ
-+ if (port->line == at91_console.index && !port->sysrq) {
-+ port->sysrq = jiffies + HZ*5;
-+ }
-+#endif
-+ }
-+
-+ // TODO: All reads to CSR will clear these interrupts!
-+ if (pending & AT91C_US_RIIC) port->icount.rng++;
-+ if (pending & AT91C_US_DSRIC) port->icount.dsr++;
-+ if (pending & AT91C_US_DCDIC) {
-+ port->icount.dcd++;
-+ uart_handle_dcd_change(port, status & AT91C_US_DCD);
-+ }
-+ if (pending & AT91C_US_CTSIC) {
-+ port->icount.cts++;
-+ uart_handle_cts_change(port, status & AT91C_US_CTS);
-+ }
-+ if (pending & (AT91C_US_RIIC | AT91C_US_DSRIC | AT91C_US_DCDIC | AT91C_US_CTSIC))
-+ wake_up_interruptible(&port->info->delta_msr_wait);
-+
-+ if (pending & AT91C_US_TXRDY)
-+ at91_tx_chars(port);
-+ if (pass_counter++ > AT91_ISR_PASS_LIMIT)
-+ break;
-+
-+ status = UART_GET_CSR(port);
-+ pending = status & port->read_status_mask;
-+ } while (pending);
-+ }
-+}
-+
-+/*
-+ * Perform initialization and enable port for reception
-+ */
-+static int at91_startup(struct uart_port *port)
-+{
-+ int retval;
-+
-+ /*
-+ * Allocate the IRQ
-+ */
-+ retval = request_irq(port->irq, at91_interrupt, SA_SHIRQ, "at91_serial", port);
-+ if (retval) {
-+ printk("at91_serial: at91_startup - Can't get irq\n");
-+ return retval;
-+ }
-+ /*
-+ * If there is a specific "open" function (to register
-+ * control line interrupts)
-+ */
-+ if (at91_open) {
-+ retval = at91_open(port);
-+ if (retval) {
-+ free_irq(port->irq, port);
-+ return retval;
-+ }
-+ }
-+
-+ /* Enable peripheral clock if required */
-+ if (port->irq != AT91C_ID_SYS)
-+ AT91_SYS->PMC_PCER = 1 << port->irq;
-+
-+ port->read_status_mask = AT91C_US_RXRDY | AT91C_US_TXRDY | AT91C_US_OVRE
-+ | AT91C_US_FRAME | AT91C_US_PARE | AT91C_US_RXBRK;
-+ /*
-+ * Finally, clear and enable interrupts
-+ */
-+ UART_PUT_IDR(port, -1);
-+ UART_PUT_CR(port, AT91C_US_TXEN | AT91C_US_RXEN); /* enable xmit & rcvr */
-+ UART_PUT_IER(port, AT91C_US_RXRDY); /* do receive only */
-+ return 0;
-+}
-+
-+/*
-+ * Disable the port
-+ */
-+static void at91_shutdown(struct uart_port *port)
-+{
-+ /*
-+ * Free the interrupt
-+ */
-+ free_irq(port->irq, port);
-+
-+ /*
-+ * If there is a specific "close" function (to unregister
-+ * control line interrupts)
-+ */
-+ if (at91_close)
-+ at91_close(port);
-+
-+ /*
-+ * Disable all interrupts, port and break condition.
-+ */
-+ UART_PUT_CR(port, AT91C_US_RSTSTA);
-+ UART_PUT_IDR(port, -1);
-+
-+ /* Disable peripheral clock if required */
-+ if (port->irq != AT91C_ID_SYS)
-+ AT91_SYS->PMC_PCDR = 1 << port->irq;
-+}
-+
-+static struct uart_ops at91_pops; /* forward declaration */
-+
-+/*
-+ * Change the port parameters
-+ */
-+static void at91_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot)
-+{
-+ unsigned long flags;
-+ unsigned int mode, imr;
-+
-+ /* Get current mode register */
-+ mode = UART_GET_MR(port) & ~(AT91C_US_CHRL | AT91C_US_NBSTOP | AT91C_US_PAR);
-+
-+ /* byte size */
-+ switch (cflag & CSIZE) {
-+ case CS5:
-+ mode |= AT91C_US_CHRL_5_BITS;
-+ break;
-+ case CS6:
-+ mode |= AT91C_US_CHRL_6_BITS;
-+ break;
-+ case CS7:
-+ mode |= AT91C_US_CHRL_7_BITS;
-+ break;
-+ default:
-+ mode |= AT91C_US_CHRL_8_BITS;
-+ break;
-+ }
-+
-+ /* stop bits */
-+ if (cflag & CSTOPB)
-+ mode |= AT91C_US_NBSTOP_2_BIT;
-+
-+ /* parity */
-+ if (cflag & PARENB) {
-+ if (cflag & CMSPAR) { /* Mark or Space parity */
-+ if (cflag & PARODD)
-+ mode |= AT91C_US_PAR_MARK;
-+ else
-+ mode |= AT91C_US_PAR_SPACE;
-+ }
-+ else if (cflag & PARODD)
-+ mode |= AT91C_US_PAR_ODD;
-+ else
-+ mode |= AT91C_US_PAR_EVEN;
-+ }
-+ else
-+ mode |= AT91C_US_PAR_NONE;
-+
-+ port->read_status_mask |= AT91C_US_OVRE;
-+ if (iflag & INPCK)
-+ port->read_status_mask |= AT91C_US_FRAME | AT91C_US_PARE;
-+ if (iflag & (BRKINT | PARMRK))
-+ port->read_status_mask |= AT91C_US_RXBRK;
-+
-+ /*
-+ * Characters to ignore
-+ */
-+ port->ignore_status_mask = 0;
-+ if (iflag & IGNPAR)
-+ port->ignore_status_mask |= (AT91C_US_FRAME | AT91C_US_PARE);
-+ if (iflag & IGNBRK) {
-+ port->ignore_status_mask |= AT91C_US_RXBRK;
-+ /*
-+ * If we're ignoring parity and break indicators,
-+ * ignore overruns too (for real raw support).
-+ */
-+ if (iflag & IGNPAR)
-+ port->ignore_status_mask |= AT91C_US_OVRE;
-+ }
-+
-+ // TODO: Ignore all characters if CREAD is set.
-+
-+ /* first, disable interrupts and drain transmitter */
-+ local_irq_save(flags);
-+ imr = UART_GET_IMR(port); /* get interrupt mask */
-+ UART_PUT_IDR(port, -1); /* disable all interrupts */
-+ local_irq_restore(flags);
-+ while (!(UART_GET_CSR(port) & AT91C_US_TXEMPTY)) { barrier(); }
-+
-+ /* disable receiver and transmitter */
-+ UART_PUT_CR(port, AT91C_US_TXDIS | AT91C_US_RXDIS);
-+
-+ /* set the parity, stop bits and data size */
-+ UART_PUT_MR(port, mode);
-+
-+ /* set the baud rate */
-+ UART_PUT_BRGR(port, quot);
-+ UART_PUT_CR(port, AT91C_US_TXEN | AT91C_US_RXEN);
-+
-+ /* restore interrupts */
-+ UART_PUT_IER(port, imr);
-+
-+ /* CTS flow-control and modem-status interrupts */
-+ if (UART_ENABLE_MS(uart, cflag))
-+ at91_pops.enable_ms(uart);
-+}
-+
-+/*
-+ * Return string describing the specified port
-+ */
-+static const char *at91_type(struct uart_port *port)
-+{
-+ return port->type == PORT_AT91RM9200 ? "AT91_SERIAL" : NULL;
-+}
-+
-+/*
-+ * Release the memory region(s) being used by 'port'.
-+ */
-+static void at91_release_port(struct uart_port *port)
-+{
-+ release_mem_region(port->mapbase,
-+ port->mapbase == AT91C_VA_BASE_DBGU ? 512 : SZ_16K);
-+}
-+
-+/*
-+ * Request the memory region(s) being used by 'port'.
-+ */
-+static int at91_request_port(struct uart_port *port)
-+{
-+ return request_mem_region(port->mapbase,
-+ port->mapbase == AT91C_VA_BASE_DBGU ? 512 : SZ_16K,
-+ "at91_serial") != NULL ? 0 : -EBUSY;
-+
-+}
-+
-+/*
-+ * Configure/autoconfigure the port.
-+ */
-+static void at91_config_port(struct uart_port *port, int flags)
-+{
-+ if (flags & UART_CONFIG_TYPE) {
-+ port->type = PORT_AT91RM9200;
-+ at91_request_port(port);
-+ }
-+}
-+
-+/*
-+ * Verify the new serial_struct (for TIOCSSERIAL).
-+ */
-+static int at91_verify_port(struct uart_port *port, struct serial_struct *ser)
-+{
-+ int ret = 0;
-+ if (ser->type != PORT_UNKNOWN && ser->type != PORT_AT91RM9200)
-+ ret = -EINVAL;
-+ if (port->irq != ser->irq)
-+ ret = -EINVAL;
-+ if (ser->io_type != SERIAL_IO_MEM)
-+ ret = -EINVAL;
-+ if (port->uartclk / 16 != ser->baud_base)
-+ ret = -EINVAL;
-+ if ((void *)port->mapbase != ser->iomem_base)
-+ ret = -EINVAL;
-+ if (port->iobase != ser->port)
-+ ret = -EINVAL;
-+ if (ser->hub6 != 0)
-+ ret = -EINVAL;
-+ return ret;
-+}
-+
-+static struct uart_ops at91_pops = {
-+ tx_empty: at91_tx_empty,
-+ set_mctrl: at91_set_mctrl,
-+ get_mctrl: at91_get_mctrl,
-+ stop_tx: at91_stop_tx,
-+ start_tx: at91_start_tx,
-+ stop_rx: at91_stop_rx,
-+ enable_ms: at91_enable_ms,
-+ break_ctl: at91_break_ctl,
-+ startup: at91_startup,
-+ shutdown: at91_shutdown,
-+ change_speed: at91_change_speed,
-+ type: at91_type,
-+ release_port: at91_release_port,
-+ request_port: at91_request_port,
-+ config_port: at91_config_port,
-+ verify_port: at91_verify_port,
-+};
-+
-+static struct uart_port at91_ports[AT91C_NR_UART];
-+
-+void __init at91_init_ports(void)
-+{
-+ static int first = 1;
-+ int i;
-+
-+ if (!first)
-+ return;
-+ first = 0;
-+
-+ for (i = 0; i < AT91C_NR_UART; i++) {
-+ at91_ports[i].iotype = SERIAL_IO_MEM;
-+ at91_ports[i].flags = ASYNC_BOOT_AUTOCONF;
-+ at91_ports[i].uartclk = AT91C_MASTER_CLOCK;
-+ at91_ports[i].ops = &at91_pops;
-+ at91_ports[i].fifosize = 1;
-+ at91_ports[i].line = i;
-+ }
-+}
-+
-+void __init at91_register_uart_fns(struct at91rm9200_port_fns *fns)
-+{
-+ if (fns->enable_ms)
-+ at91_pops.enable_ms = fns->enable_ms;
-+ if (fns->get_mctrl)
-+ at91_pops.get_mctrl = fns->get_mctrl;
-+ if (fns->set_mctrl)
-+ at91_pops.set_mctrl = fns->set_mctrl;
-+ at91_open = fns->open;
-+ at91_close = fns->close;
-+ at91_pops.pm = fns->pm;
-+ at91_pops.set_wake = fns->set_wake;
-+}
-+
-+/*
-+ * Setup ports.
-+ */
-+void __init at91_register_uart(int idx, int port)
-+{
-+ if ((idx < 0) || (idx >= AT91C_NR_UART)) {
-+ printk(KERN_ERR __FUNCTION__ ": bad index number %d\n", idx);
-+ return;
-+ }
-+
-+ switch (port) {
-+ case 0:
-+ at91_ports[idx].membase = (void *) AT91C_VA_BASE_US0;
-+ at91_ports[idx].mapbase = AT91C_VA_BASE_US0;
-+ at91_ports[idx].irq = AT91C_ID_US0;
-+ AT91_CfgPIO_USART0();
-+ break;
-+ case 1:
-+ at91_ports[idx].membase = (void *) AT91C_VA_BASE_US1;
-+ at91_ports[idx].mapbase = AT91C_VA_BASE_US1;
-+ at91_ports[idx].irq = AT91C_ID_US1;
-+ AT91_CfgPIO_USART1();
-+ break;
-+ case 2:
-+ at91_ports[idx].membase = (void *) AT91C_VA_BASE_US2;
-+ at91_ports[idx].mapbase = AT91C_VA_BASE_US2;
-+ at91_ports[idx].irq = AT91C_ID_US2;
-+ AT91_CfgPIO_USART2();
-+ break;
-+ case 3:
-+ at91_ports[idx].membase = (void *) AT91C_VA_BASE_US3;
-+ at91_ports[idx].mapbase = AT91C_VA_BASE_US3;
-+ at91_ports[idx].irq = AT91C_ID_US3;
-+ AT91_CfgPIO_USART3();
-+ break;
-+ case 4:
-+ at91_ports[idx].membase = (void *) AT91C_VA_BASE_DBGU;
-+ at91_ports[idx].mapbase = AT91C_VA_BASE_DBGU;
-+ at91_ports[idx].irq = AT91C_ID_SYS;
-+ AT91_CfgPIO_DBGU();
-+ break;
-+ default:
-+ printk(KERN_ERR __FUNCTION__ ": bad port number %d\n", port);
-+ }
-+}
-+
-+#ifdef CONFIG_SERIAL_AT91_CONSOLE
-+
-+/*
-+ * Interrupts are disabled on entering
-+ */
-+static void at91_console_write(struct console *co, const char *s, u_int count)
-+{
-+ struct uart_port *port = at91_ports + co->index;
-+ unsigned int status, i, imr;
-+
-+ /*
-+ * First, save IMR and then disable interrupts
-+ */
-+ imr = UART_GET_IMR(port); /* get interrupt mask */
-+ UART_PUT_IDR(port, AT91C_US_RXRDY | AT91C_US_TXRDY);
-+
-+ /*
-+ * Now, do each character
-+ */
-+ for (i = 0; i < count; i++) {
-+ do {
-+ status = UART_GET_CSR(port);
-+ } while (!(status & AT91C_US_TXRDY));
-+ UART_PUT_CHAR(port, s[i]);
-+ if (s[i] == '\n') {
-+ do {
-+ status = UART_GET_CSR(port);
-+ } while (!(status & AT91C_US_TXRDY));
-+ UART_PUT_CHAR(port, '\r');
-+ }
-+ }
-+
-+ /*
-+ * Finally, wait for transmitter to become empty
-+ * and restore IMR
-+ */
-+ do {
-+ status = UART_GET_CSR(port);
-+ } while (status & AT91C_US_TXRDY);
-+ UART_PUT_IER(port, imr); /* set interrupts back the way they were */
-+}
-+
-+static kdev_t at91_console_device(struct console *co)
-+{
-+ return MKDEV(SERIAL_AT91_MAJOR, MINOR_START + co->index);
-+}
-+
-+/*
-+ * If the port was already initialised (eg, by a boot loader), try to determine
-+ * the current setup.
-+ */
-+static void __init at91_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
-+{
-+ unsigned int mr, quot;
-+
-+// TODO: CR is a write-only register
-+// unsigned int cr;
-+//
-+// cr = UART_GET_CR(port) & (AT91C_US_RXEN | AT91C_US_TXEN);
-+// if (cr == (AT91C_US_RXEN | AT91C_US_TXEN)) {
-+// /* ok, the port was enabled */
-+//
-+// mr = UART_GET_MR(port) & AT91C_US_PAR;
-+//
-+// *parity = 'n';
-+// if (mr == AT91C_US_PAR_EVEN)
-+// *parity = 'e';
-+// else if (mr == AT91C_US_PAR_ODD)
-+// *parity = 'o';
-+// }
-+
-+ mr = UART_GET_MR(port) & AT91C_US_CHRL;
-+ if (mr == AT91C_US_CHRL_8_BITS)
-+ *bits = 8;
-+ else
-+ *bits = 7;
-+
-+ quot = UART_GET_BRGR(port);
-+ *baud = port->uartclk / (16 * (quot));
-+}
-+
-+static int __init at91_console_setup(struct console *co, char *options)
-+{
-+ struct uart_port *port;
-+ int baud = AT91C_CONSOLE_DEFAULT_BAUDRATE;
-+ int bits = 8;
-+ int parity = 'n';
-+ int flow = 'n';
-+
-+ /*
-+ * Check whether an invalid uart number has been specified, and
-+ * if so, search for the first available port that does have
-+ * console support.
-+ */
-+ port = uart_get_console(at91_ports, AT91C_NR_UART, co);
-+
-+ // TODO: The console port should be initialized, and clock enabled if
-+ // we're not relying on the bootloader to do it.
-+
-+ if (options)
-+ uart_parse_options(options, &baud, &parity, &bits, &flow);
-+ else
-+ at91_console_get_options(port, &baud, &parity, &bits);
-+
-+ return uart_set_options(port, co, baud, parity, bits, flow);
-+}
-+
-+static struct console at91_console = {
-+ name: "ttyS",
-+ write: at91_console_write,
-+ device: at91_console_device,
-+ setup: at91_console_setup,
-+ flags: CON_PRINTBUFFER,
-+ index: AT91C_CONSOLE,
-+};
-+
-+#define AT91_CONSOLE_DEVICE &at91_console
-+
-+void __init at91_console_init(void)
-+{
-+ at91_init_ports();
-+ register_console(&at91_console);
-+}
-+
-+#else
-+#define AT91_CONSOLE_DEVICE NULL
-+#endif
-+
-+static struct uart_driver at91_reg = {
-+ owner: THIS_MODULE,
-+ normal_major: SERIAL_AT91_MAJOR,
-+#ifdef CONFIG_DEVFS_FS
-+ normal_name: "ttyS%d",
-+ callout_name: "cua%d",
-+#else
-+ normal_name: "ttyS",
-+ callout_name: "cua",
-+#endif
-+ normal_driver: &normal,
-+ callout_major: CALLOUT_AT91_MAJOR,
-+ callout_driver: &callout,
-+ table: at91_table,
-+ termios: at91_termios,
-+ termios_locked: at91_termios_locked,
-+ minor: MINOR_START,
-+ nr: AT91C_NR_UART,
-+ cons: AT91_CONSOLE_DEVICE,
-+};
-+
-+static int __init at91_serial_init(void)
-+{
-+ int ret, i;
-+
-+ at91_init_ports();
-+
-+ ret = uart_register_driver(&at91_reg);
-+ if (ret)
-+ return ret;
-+
-+ for (i = 0; i < AT91C_NR_UART; i++) {
-+ if (at91_serialmap[i] >= 0)
-+ uart_add_one_port(&at91_reg, &at91_ports[i]);
-+ }
-+
-+ return 0;
-+}
-+
-+static void __exit at91_serial_exit(void)
-+{
-+ int i;
-+
-+ for (i = 0; i < AT91C_NR_UART; i++) {
-+ if (at91_serialmap[i] >= 0)
-+ uart_remove_one_port(&at91_reg, &at91_ports[i]);
-+ }
-+
-+ uart_unregister_driver(&at91_reg);
-+}
-+
-+module_init(at91_serial_init);
-+module_exit(at91_serial_exit);
-+
-+EXPORT_NO_SYMBOLS;
-+
-+MODULE_AUTHOR("Rick Bronson");
-+MODULE_DESCRIPTION("AT91 generic serial port driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/spi/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,17 @@
-+# File: drivers/at91/spi/Makefile
-+#
-+# Makefile for the Atmel AT91RM9200 SPI device drivers
-+#
-+
-+O_TARGET := at91spi.o
-+
-+export-objs := at91_spi.o
-+
-+obj-y := at91_spi.o
-+obj-m :=
-+obj-n :=
-+obj- :=
-+
-+obj-$(CONFIG_AT91_SPIDEV) += at91_spidev.o
-+
-+include $(TOPDIR)/Rules.make
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/spi/at91_spi.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,275 @@
-+/*
-+ * Serial Peripheral Interface (SPI) driver for the Atmel AT91RM9200 (Thunder)
-+ *
-+ * (c) SAN People (Pty) Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <asm/semaphore.h>
-+#include <linux/pci.h>
-+#include <linux/sched.h>
-+#include <linux/completion.h>
-+
-+#include <asm/arch/AT91RM9200_SPI.h>
-+#include <asm/arch/pio.h>
-+#include "at91_spi.h"
-+
-+#undef DEBUG_SPI
-+
-+static struct spi_local spi_dev[NR_SPI_DEVICES]; /* state of the SPI devices */
-+static int spi_enabled = 0;
-+static struct semaphore spi_lock; /* protect access to SPI bus */
-+static int current_device = -1; /* currently selected SPI device */
-+
-+DECLARE_COMPLETION(transfer_complete);
-+
-+/* SPI controller device */
-+AT91PS_SPI controller = (AT91PS_SPI) AT91C_VA_BASE_SPI;
-+
-+/* ......................................................................... */
-+
-+/*
-+ * Access and enable the SPI bus.
-+ * This MUST be called before any transfers are performed.
-+ */
-+void spi_access_bus(short device)
-+{
-+ /* Ensure that requested device is valid */
-+ if ((device < 0) || (device >= NR_SPI_DEVICES))
-+ panic("at91_spi: spi_access_bus called with invalid device");
-+
-+ if (spi_enabled == 0) {
-+ AT91_SYS->PMC_PCER = 1 << AT91C_ID_SPI; /* Enable Peripheral clock */
-+ controller->SPI_CR = AT91C_SPI_SPIEN; /* Enable SPI */
-+#ifdef DEBUG_SPI
-+ printk("SPI on\n");
-+#endif
-+ }
-+ MOD_INC_USE_COUNT;
-+ spi_enabled++;
-+
-+ /* Lock the SPI bus */
-+ down(&spi_lock);
-+ current_device = device;
-+
-+ /* Enable PIO */
-+ if (!spi_dev[device].pio_enabled) {
-+ switch (device) {
-+ case 0: AT91_CfgPIO_SPI_CS0();
-+ case 1: AT91_CfgPIO_SPI_CS1();
-+ case 2: AT91_CfgPIO_SPI_CS2();
-+ case 3: AT91_CfgPIO_SPI_CS3();
-+ }
-+ spi_dev[device].pio_enabled = 1;
-+#ifdef DEBUG_SPI
-+ printk("SPI CS%i enabled\n", device);
-+#endif
-+ }
-+
-+ /* Configure SPI bus for device */
-+ controller->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | (spi_dev[device].pcs << 16);
-+}
-+
-+/*
-+ * Relinquish control of the SPI bus.
-+ */
-+void spi_release_bus(short device)
-+{
-+ if (device != current_device)
-+ panic("at91_spi: spi_release called with invalid device");
-+
-+ /* Release the SPI bus */
-+ current_device = -1;
-+ up(&spi_lock);
-+
-+ spi_enabled--;
-+ MOD_DEC_USE_COUNT;
-+ if (spi_enabled == 0) {
-+ controller->SPI_CR = AT91C_SPI_SPIDIS; /* Disable SPI */
-+ AT91_SYS->PMC_PCER = 1 << AT91C_ID_SPI; /* Disable Peripheral clock */
-+#ifdef DEBUG_SPI
-+ printk("SPI off\n");
-+#endif
-+ }
-+}
-+
-+/*
-+ * Perform a data transfer over the SPI bus
-+ */
-+int spi_transfer(struct spi_transfer_list* list)
-+{
-+ struct spi_local *device = (struct spi_local *) &spi_dev[current_device];
-+
-+ if (!list)
-+ panic("at91_spi: spi_transfer called with NULL transfer list");
-+ if (current_device == -1)
-+ panic("at91_spi: spi_transfer called without acquiring bus");
-+
-+#ifdef DEBUG_SPI
-+ printk("SPI transfer start [%i]\n", list->nr_transfers);
-+#endif
-+
-+ /* Store transfer list */
-+ device->xfers = list;
-+ list->curr = 0;
-+
-+ /* Assume there must be at least one transfer */
-+ device->tx = pci_map_single(NULL, list->tx[0], list->txlen[0], PCI_DMA_TODEVICE);
-+ device->rx = pci_map_single(NULL, list->rx[0], list->rxlen[0], PCI_DMA_FROMDEVICE);
-+
-+ /* Program PDC registers */
-+ controller->SPI_TPR = device->tx;
-+ controller->SPI_RPR = device->rx;
-+ controller->SPI_TCR = list->txlen[0];
-+ controller->SPI_RCR = list->rxlen[0];
-+
-+ /* Is there a second transfer? */
-+ if (list->nr_transfers > 1) {
-+ device->txnext = pci_map_single(NULL, list->tx[1], list->txlen[1], PCI_DMA_TODEVICE);
-+ device->rxnext = pci_map_single(NULL, list->rx[1], list->rxlen[1], PCI_DMA_FROMDEVICE);
-+
-+ /* Program Next PDC registers */
-+ controller->SPI_TNPR = device->txnext;
-+ controller->SPI_RNPR = device->rxnext;
-+ controller->SPI_TNCR = list->txlen[1];
-+ controller->SPI_RNCR = list->rxlen[1];
-+ }
-+ else {
-+ device->txnext = 0;
-+ device->rxnext = 0;
-+ controller->SPI_TNCR = 0;
-+ controller->SPI_RNCR = 0;
-+ }
-+
-+ // TODO: If we are doing consecutive transfers (at high speed, or
-+ // small buffers), then it might be worth modifying the 'Delay between
-+ // Consecutive Transfers' in the CSR registers.
-+ // This is an issue if we cannot chain the next buffer fast enough
-+ // in the interrupt handler.
-+
-+ /* Enable transmitter and receiver */
-+ controller->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
-+
-+ controller->SPI_IER = AT91C_SPI_SPENDRX; /* enable buffer complete interrupt */
-+ wait_for_completion(&transfer_complete);
-+
-+#ifdef DEBUG_SPI
-+ printk("SPI transfer end\n");
-+#endif
-+
-+ return 0;
-+}
-+
-+/* ......................................................................... */
-+
-+/*
-+ * Handle interrupts from the SPI controller.
-+ */
-+void spi_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ unsigned int status;
-+ struct spi_local *device = (struct spi_local *) &spi_dev[current_device];
-+ struct spi_transfer_list *list = device->xfers;
-+
-+#ifdef DEBUG_SPI
-+ printk("SPI interrupt %i\n", current_device);
-+#endif
-+
-+ if (!list)
-+ panic("at91_spi: spi_interrupt with a NULL transfer list");
-+
-+ status = controller->SPI_SR & controller->SPI_IMR; /* read status */
-+
-+ pci_unmap_single(NULL, device->tx, list->txlen[list->curr], PCI_DMA_TODEVICE);
-+ pci_unmap_single(NULL, device->rx, list->rxlen[list->curr], PCI_DMA_FROMDEVICE);
-+
-+ device->tx = device->txnext; /* move next transfer to current transfer */
-+ device->rx = device->rxnext;
-+
-+ list->curr = list->curr + 1;
-+ if (list->curr == list->nr_transfers) { /* all transfers complete */
-+ controller->SPI_IDR = AT91C_SPI_SPENDRX; /* disable interrupt */
-+
-+ /* Disable transmitter and receiver */
-+ controller->SPI_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;
-+
-+ device->xfers = NULL;
-+ complete(&transfer_complete);
-+ }
-+ else if (list->curr+1 == list->nr_transfers) { /* no more next transfers */
-+ device->txnext = 0;
-+ device->rxnext = 0;
-+ controller->SPI_TNCR = 0;
-+ controller->SPI_RNCR = 0;
-+ }
-+ else {
-+ int i = (list->curr)+1;
-+
-+ device->txnext = pci_map_single(NULL, list->tx[i], list->txlen[i], PCI_DMA_TODEVICE);
-+ device->rxnext = pci_map_single(NULL, list->rx[i], list->rxlen[i], PCI_DMA_FROMDEVICE);
-+ controller->SPI_TNPR = device->txnext;
-+ controller->SPI_RNPR = device->rxnext;
-+ controller->SPI_TNCR = list->txlen[i];
-+ controller->SPI_RNCR = list->rxlen[i];
-+ }
-+}
-+
-+/* ......................................................................... */
-+
-+/*
-+ * Initialize the SPI controller
-+ */
-+static int __init at91_spi_init(void)
-+{
-+ init_MUTEX(&spi_lock);
-+
-+ AT91_CfgPIO_SPI();
-+
-+ controller->SPI_CR = AT91C_SPI_SWRST; /* software reset of SPI controller */
-+
-+ /* Set Chip Select registers to good defaults */
-+ controller->SPI_CSR0 = AT91C_SPI_CPOL | AT91C_SPI_BITS_8 | (16 << 16) | (DEFAULT_SPI_BAUD << 8);
-+ controller->SPI_CSR1 = AT91C_SPI_CPOL | AT91C_SPI_BITS_8 | (16 << 16) | (DEFAULT_SPI_BAUD << 8);
-+ controller->SPI_CSR2 = AT91C_SPI_CPOL | AT91C_SPI_BITS_8 | (16 << 16) | (DEFAULT_SPI_BAUD << 8);
-+ controller->SPI_CSR3 = AT91C_SPI_CPOL | AT91C_SPI_BITS_8 | (16 << 16) | (DEFAULT_SPI_BAUD << 8);
-+
-+ controller->SPI_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS;
-+
-+ memset(&spi_dev, 0, sizeof(spi_dev));
-+ spi_dev[0].pcs = 0xE;
-+ spi_dev[1].pcs = 0xD;
-+ spi_dev[2].pcs = 0xB;
-+ spi_dev[3].pcs = 0x7;
-+
-+ if (request_irq(AT91C_ID_SPI, spi_interrupt, 0, "spi", NULL))
-+ return -EBUSY;
-+
-+ controller->SPI_CR = AT91C_SPI_SPIEN; /* Enable SPI */
-+
-+ return 0;
-+}
-+
-+static void at91_spi_exit(void)
-+{
-+ controller->SPI_CR = AT91C_SPI_SPIDIS; /* Disable SPI */
-+
-+ free_irq(AT91C_ID_SPI, 0);
-+}
-+
-+
-+EXPORT_SYMBOL(spi_access_bus);
-+EXPORT_SYMBOL(spi_release_bus);
-+EXPORT_SYMBOL(spi_transfer);
-+
-+module_init(at91_spi_init);
-+module_exit(at91_spi_exit);
-+
-+MODULE_LICENSE("GPL")
-+MODULE_AUTHOR("Andrew Victor")
-+MODULE_DESCRIPTION("SPI driver for Atmel AT91RM9200")
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/spi/at91_spi.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,56 @@
-+/*
-+ * Serial Peripheral Interface (SPI) driver for the Atmel AT91RM9200
-+ *
-+ * (c) SAN People (Pty) Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#ifndef AT91_SPI_H
-+#define AT91_SPI_H
-+
-+/* Maximum number of buffers in a single SPI transfer.
-+ * DataFlash uses maximum of 2
-+ * spidev interface supports up to 8.
-+ */
-+#define MAX_SPI_TRANSFERS 8
-+
-+#define NR_SPI_DEVICES 4 /* number of devices on SPI bus */
-+
-+#define DATAFLASH_CLK 6000000
-+#define DEFAULT_SPI_BAUD AT91C_MASTER_CLOCK / (2 * DATAFLASH_CLK)
-+
-+#define SPI_MAJOR 153 /* registered device number */
-+
-+/*
-+ * Describes the buffers for a SPI transfer.
-+ * A transmit & receive buffer must be specified for each transfer
-+ */
-+struct spi_transfer_list {
-+ void* tx[MAX_SPI_TRANSFERS]; /* transmit */
-+ int txlen[MAX_SPI_TRANSFERS];
-+ void* rx[MAX_SPI_TRANSFERS]; /* receive */
-+ int rxlen[MAX_SPI_TRANSFERS];
-+ int nr_transfers; /* number of transfers */
-+ int curr; /* current transfer */
-+};
-+
-+struct spi_local {
-+ unsigned int pcs; /* Peripheral Chip Select value */
-+ short pio_enabled; /* has PIO been enabled? */
-+
-+ struct spi_transfer_list *xfers; /* current transfer list */
-+ dma_addr_t tx, rx; /* DMA address for current transfer */
-+ dma_addr_t txnext, rxnext; /* DMA address for next transfer */
-+};
-+
-+
-+/* Exported functions */
-+extern void spi_access_bus(short device);
-+extern void spi_release_bus(short device);
-+extern int spi_transfer(struct spi_transfer_list* list);
-+
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/spi/at91_spidev.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,226 @@
-+/*
-+ * User-space interface to the SPI bus on Atmel AT91RM9200
-+ *
-+ * (c) SAN People (Pty) Ltd
-+ *
-+ * Based on SPI driver by Rick Bronson
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/iobuf.h>
-+#include <linux/highmem.h>
-+
-+#ifdef CONFIG_DEVFS_FS
-+#include <linux/devfs_fs_kernel.h>
-+#endif
-+
-+#include "at91_spi.h"
-+
-+#undef DEBUG_SPIDEV
-+
-+#ifdef CONFIG_DEVFS_FS
-+static devfs_handle_t devfs_handle = NULL;
-+static devfs_handle_t devfs_spi[NR_SPI_DEVICES];
-+#endif
-+
-+/* ......................................................................... */
-+
-+/*
-+ * Read or Write to SPI bus.
-+ */
-+static ssize_t spidev_rd_wr(struct file *file, char *buf, size_t count, loff_t *offset)
-+{
-+ unsigned int spi_device = (unsigned int) file->private_data;
-+ struct kiobuf *iobuf;
-+ unsigned int ofs, pagelen;
-+ int res, i;
-+
-+ struct spi_transfer_list* list = kmalloc(sizeof(struct spi_transfer_list), GFP_KERNEL);
-+ if (!list)
-+ return -ENOMEM;
-+
-+ res = alloc_kiovec(1, &iobuf);
-+ if (res) {
-+ kfree(list);
-+ return res;
-+ }
-+
-+ res = map_user_kiobuf(READ, iobuf, (unsigned long) buf, count);
-+ if (res) {
-+ free_kiovec(1, &iobuf);
-+ kfree(list);
-+ return res;
-+ }
-+
-+ /* More pages than transfer slots in spi_transfer_list */
-+ if (iobuf->nr_pages >= MAX_SPI_TRANSFERS) {
-+ unmap_kiobuf(iobuf);
-+ free_kiovec(1, &iobuf);
-+ kfree(list);
-+ return -EFBIG;
-+ }
-+
-+#ifdef DEBUG_SPIDEV
-+ printk("spidev_rd_rw: %i %i\n", count, iobuf->nr_pages);
-+#endif
-+
-+ /* Set default return value = transfer length */
-+ res = count;
-+
-+ /*
-+ * At this point, the virtual area buf[0] .. buf[count-1] will have
-+ * corresponding pages mapped in the physical memory and locked until
-+ * we unmap the kiobuf. The pages cannot be swapped out or moved
-+ * around.
-+ */
-+ ofs = iobuf->offset;
-+ pagelen = PAGE_SIZE - iobuf->offset;
-+ if (count < pagelen)
-+ pagelen = count;
-+
-+ for (i = 0; i < iobuf->nr_pages; i++) {
-+ list->tx[i] = list->rx[i] = page_address(iobuf->maplist[i]) + ofs;
-+ list->txlen[i] = list->rxlen[i] = pagelen;
-+
-+#ifdef DEBUG_SPIDEV
-+ printk(" %i: %x (%i)\n", i, list->tx[i], list->txlen[i]);
-+#endif
-+
-+ ofs = 0; /* all subsequent transfers start at beginning of a page */
-+ count = count - pagelen;
-+ pagelen = (count < PAGE_SIZE) ? count : PAGE_SIZE;
-+ }
-+ list->nr_transfers = iobuf->nr_pages;
-+
-+ /* Perform transfer on SPI bus */
-+ spi_access_bus(spi_device);
-+ spi_transfer(list);
-+ spi_release_bus(spi_device);
-+
-+ unmap_kiobuf(iobuf);
-+ free_kiovec(1, &iobuf);
-+ kfree(list);
-+
-+ return res;
-+}
-+
-+int spidev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-+{
-+ int spi_device = MINOR(inode->i_rdev);
-+
-+ if (spi_device >= NR_SPI_DEVICES)
-+ return -ENODEV;
-+
-+ // TODO: This interface can be used to configure the SPI bus.
-+ // Configurable options could include: Speed, Clock Polarity, Clock Phase
-+
-+ switch(cmd) {
-+ default:
-+ return -ENOIOCTLCMD;
-+ }
-+}
-+
-+/*
-+ * Open the SPI device
-+ */
-+int spidev_open(struct inode *inode, struct file *file)
-+{
-+ unsigned int spi_device = MINOR(inode->i_rdev);
-+
-+ if (spi_device >= NR_SPI_DEVICES)
-+ return -ENODEV;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ /*
-+ * 'private_data' is actually a pointer, but we overload it with the
-+ * value we want to store.
-+ */
-+ (unsigned int) file->private_data = spi_device;
-+
-+ return 0;
-+}
-+
-+/*
-+ * Close the SPI device
-+ */
-+static int spidev_close(struct inode *inode, struct file *file)
-+{
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+/* ......................................................................... */
-+
-+static struct file_operations spidev_fops = {
-+ owner: THIS_MODULE,
-+ llseek: no_llseek,
-+ read: spidev_rd_wr,
-+ write: spidev_rd_wr,
-+ ioctl: spidev_ioctl,
-+ open: spidev_open,
-+ release: spidev_close,
-+};
-+
-+/*
-+ * Install the SPI /dev interface driver
-+ */
-+static int __init at91_spidev_init(void)
-+{
-+ int i;
-+ char name[3];
-+
-+#ifdef CONFIG_DEVFS_FS
-+ if (devfs_register_chrdev(SPI_MAJOR, "spi", &spidev_fops)) {
-+#else
-+ if (register_chrdev(SPI_MAJOR, "spi", &spidev_fops)) {
-+#endif
-+ printk(KERN_ERR "at91_spidev: Unable to get major %d for SPI bus\n", SPI_MAJOR);
-+ return -EIO;
-+ }
-+
-+#ifdef CONFIG_DEVFS_FS
-+ devfs_handle = devfs_mk_dir(NULL, "spi", NULL);
-+
-+ for (i = 0; i < NR_SPI_DEVICES; i++) {
-+ sprintf (name, "%d", i);
-+ devfs_spi[i] = devfs_register (devfs_handle, name,
-+ DEVFS_FL_DEFAULT, SPI_MAJOR, i, S_IFCHR | S_IRUSR | S_IWUSR,
-+ &spidev_fops, NULL);
-+ }
-+#endif
-+ printk(KERN_INFO "AT91 SPI driver loaded\n");
-+
-+ return 0;
-+}
-+
-+/*
-+ * Remove the SPI /dev interface driver
-+ */
-+static void at91_spidev_exit(void)
-+{
-+#ifdef CONFIG_DEVFS_FS
-+ devfs_unregister(devfs_handle);
-+ if (devfs_unregister_chrdev(SPI_MAJOR, "spi")) {
-+#else
-+ if (unregister_chrdev(SPI_MAJOR,"spi")) {
-+#endif
-+ printk(KERN_ERR "at91_spidev: Unable to release major %d for SPI bus\n", SPI_MAJOR);
-+ return;
-+ }
-+}
-+
-+module_init(at91_spidev_init);
-+module_exit(at91_spidev_exit);
-+
-+MODULE_LICENSE("GPL")
-+MODULE_AUTHOR("Andrew Victor")
-+MODULE_DESCRIPTION("SPI /dev interface for Atmel AT91RM9200")
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/usb/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,17 @@
-+# File: drivers/at91/usb/Makefile
-+#
-+# Makefile for the Atmel AT91RM9200 USB device drivers
-+#
-+
-+O_TARGET := at91usb.o
-+
-+export-objs :=
-+
-+obj-y :=
-+obj-m :=
-+obj-n :=
-+obj- :=
-+
-+obj-$(CONFIG_USB_OHCI_AT91) += at91_usb-ohci.o
-+
-+include $(TOPDIR)/Rules.make
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/usb/at91_usb-ohci.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,81 @@
-+/*
-+ * linux/drivers/at91/usb/at91_usb_ohci-at91.c
-+ *
-+ * (c) Rick Bronson
-+ *
-+ * The outline of this code was taken from Brad Parkers <brad@heeltoe.com>
-+ * original OHCI driver modifications, and reworked into a cleaner form
-+ * by Russell King <rmk@arm.linux.org.uk>.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/ioport.h>
-+#include <linux/interrupt.h>
-+#include <linux/slab.h>
-+#include <linux/usb.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/io.h>
-+
-+#include <asm/arch/AT91RM9200_UHP.h>
-+
-+/*
-+ NOTE:
-+ The following is so that we don't have to include usb-ohci.h or pci.h as the
-+ usb-ohci.c driver needs these routines even when the architecture
-+ has no PCI bus...
-+*/
-+
-+extern int __devinit hc_add_ohci(struct pci_dev *dev, int irq, void *membase,
-+ unsigned long flags, void *ohci, const char *name,
-+ const char *slot_name);
-+extern void hc_remove_ohci(void *ohci);
-+
-+static void *at91_ohci;
-+AT91PS_UHP ohci_regs;
-+
-+static int __init at91_ohci_init(void)
-+{
-+ int ret;
-+
-+ ohci_regs = ioremap(AT91_UHP_BASE, SZ_4K);
-+ if (!ohci_regs) {
-+ printk(KERN_ERR "at91_usb-ohci: ioremap failed\n");
-+ return -EIO;
-+ }
-+
-+ /* Now, enable the USB clock */
-+ AT91_SYS->PMC_SCER = AT91C_PMC_UHP; /* enable system clock */
-+ AT91_SYS->PMC_PCER = 1 << AT91C_ID_UHP; /* enable peripheral clock */
-+
-+ /* Take Hc out of reset */
-+ ohci_regs->UHP_HcControl = 2 << 6;
-+
-+ /* Initialise the generic OHCI driver. */
-+ ret = hc_add_ohci((struct pci_dev *) 1, AT91C_ID_UHP,
-+ (void *)ohci_regs, 0, &at91_ohci,
-+ "usb-ohci", "at91");
-+ if (ret)
-+ iounmap(ohci_regs);
-+
-+ return ret;
-+}
-+
-+static void __exit at91_ohci_exit(void)
-+{
-+ hc_remove_ohci(at91_ohci);
-+
-+ /* Force UHP_Hc to reset */
-+ ohci_regs->UHP_HcControl = 0;
-+
-+ /* Stop the USB clock. */
-+ AT91_SYS->PMC_SCDR = AT91C_PMC_UHP; /* disable system clock */
-+ AT91_SYS->PMC_PCDR = 1 << AT91C_ID_UHP; /* disable peripheral clock */
-+
-+ iounmap(ohci_regs);
-+}
-+
-+module_init(at91_ohci_init);
-+module_exit(at91_ohci_exit);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/watchdog/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,15 @@
-+# File: drivers/at91/watchdog/Makefile
-+#
-+# Makefile for the Atmel AT91RM9200 watchdog device driver
-+#
-+
-+O_TARGET := at91wdt.o
-+
-+obj-y :=
-+obj-m :=
-+obj-n :=
-+obj- :=
-+
-+obj-$(CONFIG_AT91_WATCHDOG) += at91_wdt.o
-+
-+include $(TOPDIR)/Rules.make
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/at91/watchdog/at91_wdt.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,193 @@
-+/*
-+ * Watchdog driver for Atmel AT91RM9200 (Thunder)
-+ *
-+ * (c) SAN People (Pty) Ltd
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * as published by the Free Software Foundation; either version
-+ * 2 of the License, or (at your option) any later version.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/config.h>
-+#include <linux/miscdevice.h>
-+#include <linux/watchdog.h>
-+#include <asm/uaccess.h>
-+#include <linux/init.h>
-+
-+#define WDT_DEFAULT_TIME 5 /* 5 seconds */
-+#define WDT_MAX_TIME 256 /* 256 seconds */
-+
-+static int at91wdt_time = WDT_DEFAULT_TIME;
-+static int at91wdt_busy;
-+
-+/* ......................................................................... */
-+
-+/*
-+ * Disable the watchdog.
-+ */
-+void at91_wdt_stop(void)
-+{
-+ AT91_SYS->ST_WDMR = AT91C_ST_EXTEN;
-+}
-+
-+/*
-+ * Enable and reset the watchdog.
-+ */
-+void at91_wdt_start(void)
-+{
-+ AT91_SYS->ST_WDMR = AT91C_ST_EXTEN | AT91C_ST_RSTEN | (((65536 * at91wdt_time) >> 8) & AT91C_ST_WDV);
-+ AT91_SYS->ST_CR = AT91C_ST_WDRST;
-+}
-+
-+/* ......................................................................... */
-+
-+/*
-+ * Watchdog device is opened, and watchdog starts running.
-+ */
-+static int at91_wdt_open(struct inode *inode, struct file *file)
-+{
-+ if (test_and_set_bit(1, &at91wdt_busy))
-+ return -EBUSY;
-+ MOD_INC_USE_COUNT;
-+
-+ /*
-+ * All counting occurs at SLOW_CLOCK / 128 = 0.256 Hz
-+ *
-+ * Since WDV is a 16-bit counter, the maximum period is
-+ * 65536 / 0.256 = 256 seconds.
-+ */
-+
-+ at91_wdt_start();
-+ return 0;
-+}
-+
-+/*
-+ * Close the watchdog device.
-+ * If CONFIG_WATCHDOG_NOWAYOUT is NOT defined then the watchdog is also
-+ * disabled.
-+ */
-+static int at91_wdt_close(struct inode *inode, struct file *file)
-+{
-+#ifndef CONFIG_WATCHDOG_NOWAYOUT
-+ /* Disable the watchdog when file is closed */
-+ at91_wdt_stop();
-+#endif
-+
-+ at91wdt_busy = 0;
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+/*
-+ * Handle commands from user-space.
-+ */
-+static int at91_wdt_ioctl(struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ unsigned int new_value;
-+ static struct watchdog_info info = {
-+ identity: "at91 watchdog",
-+ options: WDIOF_SETTIMEOUT,
-+ };
-+
-+ switch(cmd) {
-+ case WDIOC_KEEPALIVE:
-+ AT91_SYS->ST_CR = AT91C_ST_WDRST; /* Pat the watchdog */
-+ return 0;
-+
-+ case WDIOC_GETSUPPORT:
-+ return copy_to_user((struct watchdog_info *)arg, &info, sizeof(info));
-+
-+ case WDIOC_SETTIMEOUT:
-+ if (get_user(new_value, (int *)arg))
-+ return -EFAULT;
-+ if ((new_value <= 0) || (new_value > WDT_MAX_TIME))
-+ return -EINVAL;
-+
-+ /* Restart watchdog with new time */
-+ at91wdt_time = new_value;
-+ at91_wdt_start();
-+
-+ /* Return current value */
-+ return put_user(at91wdt_time, (int *)arg);
-+
-+ case WDIOC_GETTIMEOUT:
-+ return put_user(at91wdt_time, (int *)arg);
-+
-+ case WDIOC_GETSTATUS:
-+ return put_user(0, (int *)arg);
-+
-+ case WDIOC_SETOPTIONS:
-+ if (get_user(new_value, (int *)arg))
-+ return -EFAULT;
-+ if (new_value & WDIOS_DISABLECARD)
-+ at91_wdt_stop();
-+ if (new_value & WDIOS_ENABLECARD)
-+ at91_wdt_start();
-+ return 0;
-+
-+ default:
-+ return -ENOIOCTLCMD;
-+ }
-+}
-+
-+/*
-+ * Pat the watchdog whenever device is written to.
-+ */
-+static ssize_t at91_wdt_write(struct file *file, const char *data, size_t len, loff_t *ppos)
-+{
-+ /* Can't seek (pwrite) on this device */
-+ if (ppos != &file->f_pos)
-+ return -ESPIPE;
-+
-+ if (len) {
-+ AT91_SYS->ST_CR = AT91C_ST_WDRST; /* Pat the watchdog */
-+ return len;
-+ }
-+
-+ return 0;
-+}
-+
-+/* ......................................................................... */
-+
-+static struct file_operations at91wdt_fops =
-+{
-+ .owner = THIS_MODULE,
-+ .ioctl = at91_wdt_ioctl,
-+ .open = at91_wdt_open,
-+ .release = at91_wdt_close,
-+ .write = at91_wdt_write,
-+};
-+
-+static struct miscdevice at91wdt_miscdev =
-+{
-+ .minor = WATCHDOG_MINOR,
-+ .name = "watchdog",
-+ .fops = &at91wdt_fops,
-+};
-+
-+static int __init at91_wdt_init(void)
-+{
-+ int res;
-+
-+ res = misc_register(&at91wdt_miscdev);
-+ if (res)
-+ return res;
-+
-+ printk("AT91 Watchdog Timer enabled (%d seconds)\n", WDT_DEFAULT_TIME);
-+ return 0;
-+}
-+
-+static void __exit at91_wdt_exit(void)
-+{
-+ misc_deregister(&at91wdt_miscdev);
-+}
-+
-+module_init(at91_wdt_init);
-+module_exit(at91_wdt_exit);
-+
-+MODULE_LICENSE("GPL")
-+MODULE_AUTHOR("Andrew Victor")
-+MODULE_DESCRIPTION("Watchdog driver for Atmel AT91RM9200")
---- linux-2.4.25/drivers/block/Makefile~2.4.25-vrs2.patch 2003-06-13 16:51:32.000000000 +0200
-+++ linux-2.4.25/drivers/block/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -27,11 +27,17 @@
- obj-$(CONFIG_BLK_DEV_PS2) += ps2esdi.o
- obj-$(CONFIG_BLK_DEV_XD) += xd.o
- obj-$(CONFIG_BLK_CPQ_DA) += cpqarray.o
--obj-$(CONFIG_BLK_CPQ_CISS_DA) += cciss.o
-+obj-$(CONFIG_BLK_CPQ_CISS_DA) += cciss.o
- obj-$(CONFIG_BLK_DEV_DAC960) += DAC960.o
- obj-$(CONFIG_BLK_DEV_UMEM) += umem.o
- obj-$(CONFIG_BLK_DEV_NBD) += nbd.o
-
- subdir-$(CONFIG_PARIDE) += paride
-
-+ifeq ($(CONFIG_ARCH_ACORN),y)
-+mod-subdirs += ../acorn/block
-+subdir-y += ../acorn/block
-+obj-y += ../acorn/block/acorn-block.o
-+endif
-+
- include $(TOPDIR)/Rules.make
---- linux-2.4.25/drivers/block/ll_rw_blk.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/block/ll_rw_blk.c 2004-03-31 17:15:09.000000000 +0200
-@@ -32,6 +32,19 @@
- #include <linux/slab.h>
- #include <linux/module.h>
-
-+/* Maybe something to cleanup in 2.3?
-+ * We shouldn't touch 0x3f2 on machines which don't have a PC floppy controller
-+ * - it may contain something else which could cause a system hang. This is
-+ * now selected by a configuration option, but maybe it ought to be in the
-+ * floppy code itself? - rmk
-+ */
-+#if defined(__i386__) || (defined(__arm__) && defined(CONFIG_ARCH_ACORN))
-+#define FLOPPY_BOOT_DISABLE
-+#endif
-+#ifdef CONFIG_BLK_DEV_FD
-+#undef FLOPPY_BOOT_DISABLE
-+#endif
-+
- /*
- * MAC Floppy IWM hooks
- */
-@@ -524,7 +537,7 @@
- elevator_init(&q->elevator, ELEVATOR_LINUS);
- blk_init_free_list(q);
- q->request_fn = rfn;
-- q->back_merge_fn = ll_back_merge_fn;
-+ q->back_merge_fn = ll_back_merge_fn;
- q->front_merge_fn = ll_front_merge_fn;
- q->merge_requests_fn = ll_merge_requests_fn;
- q->make_request_fn = __make_request;
-@@ -1540,7 +1553,7 @@
- mfm_init();
- #endif
- #ifdef CONFIG_PARIDE
-- { extern void paride_init(void); paride_init(); };
-+ { extern void paride_init(void); paride_init(); }
- #endif
- #ifdef CONFIG_MAC_FLOPPY
- swim3_init();
-@@ -1554,12 +1567,14 @@
- #ifdef CONFIG_ATARI_FLOPPY
- atari_floppy_init();
- #endif
-+#ifdef CONFIG_BLK_DEV_FD1772
-+ fd1772_init();
-+#endif
- #ifdef CONFIG_BLK_DEV_FD
- floppy_init();
--#else
--#if defined(__i386__) /* Do we even need this? */
-- outb_p(0xc, 0x3f2);
- #endif
-+#ifdef FLOPPY_BOOT_DISABLE
-+ outb_p(0xc, 0x3f2);
- #endif
- #ifdef CONFIG_CDU31A
- cdu31a_init();
-@@ -1617,7 +1632,7 @@
- jsfd_init();
- #endif
- return 0;
--};
-+}
-
- EXPORT_SYMBOL(io_request_lock);
- EXPORT_SYMBOL(end_that_request_first);
---- linux-2.4.25/drivers/cdrom/cdrom.c~2.4.25-vrs2.patch 2003-11-28 19:26:20.000000000 +0100
-+++ linux-2.4.25/drivers/cdrom/cdrom.c 2004-03-31 17:15:09.000000000 +0200
-@@ -246,8 +246,8 @@
- #define CD_DVD 0x80
-
- /* Define this to remove _all_ the debugging messages */
--/* #define ERRLOGMASK CD_NOTHING */
--#define ERRLOGMASK (CD_WARNING)
-+#define ERRLOGMASK CD_NOTHING
-+/* #define ERRLOGMASK (CD_WARNING) */
- /* #define ERRLOGMASK (CD_WARNING|CD_OPEN|CD_COUNT_TRACKS|CD_CLOSE) */
- /* #define ERRLOGMASK (CD_WARNING|CD_REG_UNREG|CD_DO_IOCTL|CD_OPEN|CD_CLOSE|CD_COUNT_TRACKS) */
-
---- linux-2.4.25/drivers/char/Config.in~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/char/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -20,10 +20,10 @@
- if [ "$CONFIG_IA64" = "y" ]; then
- bool ' Support for serial port described by EFI HCDP table' CONFIG_SERIAL_HCDP
- fi
-- if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
-- tristate ' Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL
-- tristate ' Dual serial port support' CONFIG_DUALSP_SERIAL
-- fi
-+fi
-+if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
-+ dep_tristate ' Atomwide serial port support' CONFIG_ATOMWIDE_SERIAL $CONFIG_SERIAL
-+ dep_tristate ' Dual serial port support' CONFIG_DUALSP_SERIAL $CONFIG_SERIAL
- fi
- dep_mbool 'Extended dumb serial driver options' CONFIG_SERIAL_EXTENDED $CONFIG_SERIAL
- if [ "$CONFIG_SERIAL_EXTENDED" = "y" ]; then
-@@ -132,18 +132,6 @@
- bool ' SGI SN2 IOC4 serial port support' CONFIG_SGI_IOC4_SERIAL
- fi
- fi
--fi
--if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_ZORRO" = "y" ]; then
-- tristate 'Commodore A2232 serial support (EXPERIMENTAL)' CONFIG_A2232
--fi
--if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then
-- bool 'DC21285 serial port support' CONFIG_SERIAL_21285
-- if [ "$CONFIG_SERIAL_21285" = "y" ]; then
-- if [ "$CONFIG_OBSOLETE" = "y" ]; then
-- bool ' Use /dev/ttyS0 device (OBSOLETE)' CONFIG_SERIAL_21285_OLD
-- fi
-- bool ' Console on DC21285 serial port' CONFIG_SERIAL_21285_CONSOLE
-- fi
- if [ "$CONFIG_PARISC" = "y" ]; then
- bool ' PDC software console support' CONFIG_PDC_CONSOLE
- fi
-@@ -168,6 +156,16 @@
- if [ "$CONFIG_CPU_VR41XX" = "y" ]; then
- bool 'NEC VR4100 series Keyboard Interface Unit Support ' CONFIG_VR41XX_KIU
- fi
-+if [ "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
-+ tristate 'AT91RM9200 SPI device interface' CONFIG_AT91_SPIDEV
-+fi
-+
-+source drivers/serial/Config.in
-+
-+if [ "$CONFIG_ARCH_ANAKIN" = "y" ]; then
-+ tristate 'Anakin touchscreen support' CONFIG_TOUCHSCREEN_ANAKIN
-+fi
-+
- bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
- if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
- int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
-@@ -190,6 +188,12 @@
-
- source drivers/i2c/Config.in
-
-+if [ "$CONFIG_I2C" != "n" ]; then
-+ dep_tristate ' DS1307 RTC' CONFIG_I2C_DS1307 $CONFIG_I2C
-+fi
-+
-+source drivers/l3/Config.in
-+
- mainmenu_option next_comment
- comment 'Mice'
- tristate 'Bus Mouse Support' CONFIG_BUSMOUSE
-@@ -245,11 +249,13 @@
- tristate ' ALi M7101 PMU Watchdog Timer' CONFIG_ALIM7101_WDT
- tristate ' AMD "Elan" SC520 Watchdog Timer' CONFIG_SC520_WDT
- tristate ' Berkshire Products PC Watchdog' CONFIG_PCWATCHDOG
-- if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then
-- tristate ' DC21285 watchdog' CONFIG_21285_WATCHDOG
-- if [ "$CONFIG_ARCH_NETWINDER" = "y" ]; then
-- tristate ' NetWinder WB83C977 watchdog' CONFIG_977_WATCHDOG
-- fi
-+ if [ "$CONFIG_ARM" = "y" ]; then
-+ dep_tristate ' DC21285 watchdog' CONFIG_21285_WATCHDOG $CONFIG_FOOTBRIDGE
-+ dep_tristate ' NetWinder WB83C977 watchdog' CONFIG_977_WATCHDOG $CONFIG_ARCH_NETWINDER
-+ dep_tristate ' SA1100 watchdog' CONFIG_SA1100_WATCHDOG $CONFIG_ARCH_SA1100
-+ dep_tristate ' EPXA watchdog' CONFIG_EPXA_WATCHDOG $CONFIG_ARCH_CAMELOT
-+ dep_tristate ' Omaha watchdog' CONFIG_OMAHA_WATCHDOG $CONFIG_ARCH_OMAHA
-+ dep_tristate ' AT91RM9200 watchdog' CONFIG_AT91_WATCHDOG $CONFIG_ARCH_AT91RM9200
- fi
- tristate ' Eurotech CPU-1220/1410 Watchdog Timer' CONFIG_EUROTECH_WDT
- tristate ' IB700 SBC Watchdog Timer' CONFIG_IB700_WDT
-@@ -326,6 +332,15 @@
- if [ "$CONFIG_TOSHIBA_RBTX4927" = "y" -o "$CONFIG_TOSHIBA_JMR3927" = "y" ]; then
- tristate 'Dallas DS1742 RTC support' CONFIG_DS1742
- fi
-+if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
-+ tristate 'SA1100 Real Time Clock' CONFIG_SA1100_RTC
-+fi
-+if [ "$CONFIG_ARCH_OMAHA" = "y" ]; then
-+ tristate 'Omaha Real Time Clock' CONFIG_OMAHA_RTC
-+fi
-+if [ "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
-+ tristate 'AT91RM9200 Real Time Clock' CONFIG_AT91_RTC
-+fi
-
- tristate 'Double Talk PC internal speech card support' CONFIG_DTLK
- tristate 'Siemens R3964 line discipline' CONFIG_R3964
---- linux-2.4.25/drivers/char/Makefile~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/char/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -29,7 +29,7 @@
-
- mod-subdirs := joystick ftape drm drm-4.0 pcmcia
-
--list-multi :=
-+list-multi :=
-
- KEYMAP =defkeymap.o
- KEYBD =pc_keyb.o
-@@ -106,11 +106,39 @@
- endif
-
- ifeq ($(ARCH),arm)
-- ifneq ($(CONFIG_PC_KEYMAP),y)
-- KEYMAP =
-+ KEYMAP :=
-+ KEYBD :=
-+ ifeq ($(CONFIG_PC_KEYMAP),y)
-+ KEYMAP := defkeymap.o
- endif
-- ifneq ($(CONFIG_PC_KEYB),y)
-- KEYBD =
-+ ifeq ($(CONFIG_PC_KEYB),y)
-+ KEYBD += pc_keyb.o
-+ endif
-+ ifeq ($(CONFIG_KMI_KEYB),y)
-+ KEYBD += amba_kmi_keyb.o
-+ endif
-+ ifeq ($(CONFIG_SA1111),y)
-+ KEYBD += sa1111_keyb.o
-+ endif
-+ ifeq ($(CONFIG_ARCH_EDB7211),y)
-+ KEYBD += edb7211_keyb.o
-+ endif
-+ ifeq ($(CONFIG_ARCH_AUTCPU12),y)
-+ KEYMAP := defkeymap.o
-+ KEYBD += clps711x_keyb.o
-+ endif
-+ ifeq ($(CONFIG_SA1100_GRAPHICSCLIENT),y)
-+ KEYMAP = gckeymap.o
-+ KEYBD += gc_keyb.o
-+ endif
-+ ifeq ($(CONFIG_SA1100_CERF_CPLD),y)
-+ KEYBD += cerf_keyb.o
-+ endif
-+ ifeq ($(CONFIG_ARCH_FORTUNET),y)
-+ KEYMAP := defkeymap.o
-+ endif
-+ ifeq ($(CONFIG_ARCH_GUIDEA07),y)
-+ KEYMAP := defkeymap.o
- endif
- endif
-
-@@ -172,11 +200,9 @@
- obj-$(CONFIG_VT) += vt.o vc_screen.o consolemap.o consolemap_deftbl.o $(CONSOLE) selection.o
- obj-$(CONFIG_SERIAL) += $(SERIAL)
- obj-$(CONFIG_SERIAL_HCDP) += hcdp_serial.o
--obj-$(CONFIG_SERIAL_21285) += serial_21285.o
--obj-$(CONFIG_SERIAL_SA1100) += serial_sa1100.o
--obj-$(CONFIG_SERIAL_AMBA) += serial_amba.o
- obj-$(CONFIG_TS_AU1X00_ADS7846) += au1000_ts.o
- obj-$(CONFIG_SERIAL_DEC) += decserial.o
-+obj-$(CONFIG_TOUCHSCREEN_ANAKIN) += anakin_ts.o
-
- ifndef CONFIG_SUN_KEYBOARD
- obj-$(CONFIG_VT) += keyboard.o $(KEYMAP) $(KEYBD)
-@@ -253,6 +279,8 @@
- obj-$(CONFIG_SGI_DS1286) += ds1286.o
- obj-$(CONFIG_MIPS_RTC) += mips_rtc.o
- obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o
-+obj-$(CONFIG_SA1100_RTC) += sa1100-rtc.o
-+obj-$(CONFIG_OMAHA_RTC) += omaha-rtc.o
- ifeq ($(CONFIG_PPC),)
- obj-$(CONFIG_NVRAM) += nvram.o
- endif
-@@ -291,6 +319,7 @@
- obj-$(CONFIG_NWFLASH) += nwflash.o
- obj-$(CONFIG_SCx200) += scx200.o
- obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o
-+obj-$(CONFIG_SA1100_CONSUS) += consusbutton.o
-
- # Only one watchdog can succeed. We probe the hardware watchdog
- # drivers first, then the softdog driver. This means if your hardware
-@@ -319,16 +348,28 @@
- obj-$(CONFIG_SC1200_WDT) += sc1200wdt.o
- obj-$(CONFIG_SCx200_WDT) += scx200_wdt.o
- obj-$(CONFIG_WAFER_WDT) += wafer5823wdt.o
-+obj-$(CONFIG_SA1100_WATCHDOG) += sa1100_wdt.o
-+obj-$(CONFIG_EPXA_WATCHDOG) += epxa_wdt.o
-+obj-$(CONFIG_OMAHA_WATCHDOG) += omaha_wdt.o
- obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o
- obj-$(CONFIG_AMD7XX_TCO) += amd7xx_tco.o
- obj-$(CONFIG_INDYDOG) += indydog.o
- obj-$(CONFIG_8xx_WDT) += mpc8xx_wdt.o
-
-+# I2C char devices
-+obj-$(CONFIG_I2C_DS1307) += ds1307.o
-+
- subdir-$(CONFIG_MWAVE) += mwave
- ifeq ($(CONFIG_MWAVE),y)
- obj-y += mwave/mwave.o
- endif
-
-+ifeq ($(CONFIG_ARCH_ACORN),y)
-+mod-subdirs += ../acorn/char
-+subdir-y += ../acorn/char
-+obj-y += ../acorn/char/acorn-char.o
-+endif
-+
- subdir-$(CONFIG_IPMI_HANDLER) += ipmi
- ifeq ($(CONFIG_IPMI_HANDLER),y)
- obj-y += ipmi/ipmi.o
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/amba_kmi_keyb.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,999 @@
-+/*
-+ * linux/drivers/char/amba_kmi_keyb.c
-+ *
-+ * AMBA Keyboard and Mouse Interface Driver
-+ *
-+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * This keyboard driver drives a PS/2 keyboard and mouse connected
-+ * to the KMI interfaces. The KMI interfaces are nothing more than
-+ * a uart; there is no inteligence in them to do keycode translation.
-+ * We leave all that up to the keyboard itself.
-+ *
-+ * FIXES:
-+ * dirk.uffmann@nokia.com: enabled PS/2 reconnection
-+ */
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h> /* for in_interrupt */
-+#include <linux/timer.h>
-+#include <linux/init.h>
-+#include <linux/delay.h> /* for udelay */
-+#include <linux/kbd_kern.h> /* for keyboard_tasklet */
-+#include <linux/kbd_ll.h>
-+
-+#include <asm/io.h>
-+#include <asm/hardware/amba_kmi.h>
-+#include <asm/mach/amba_kmi.h>
-+#include <asm/keyboard.h>
-+
-+//#define DEBUG(s) printk s
-+#define DEBUG(s) do { } while (0)
-+
-+#define CONFIG_AMBA_PS2_RECONNECT
-+
-+#define KMI_BASE (kmi->base)
-+
-+#define KMI_RESET 0x00
-+#define KMI_RESET_POR 0x01
-+#define KMI_RESET_DONE 0x02
-+
-+#define KMI_NO_ACK 0xffff
-+
-+#define PS2_O_RESET 0xff
-+#define PS2_O_RESEND 0xfe
-+#define PS2_O_DISABLE 0xf5
-+#define PS2_O_ENABLE 0xf4
-+#define PS2_O_ECHO 0xee
-+
-+/*
-+ * Keyboard
-+ */
-+#define PS2_O_SET_DEFAULT 0xf6
-+#define PS2_O_SET_RATE_DELAY 0xf3
-+#define PS2_O_SET_SCANSET 0xf0
-+#define PS2_O_INDICATORS 0xed
-+
-+/*
-+ * Mouse
-+ */
-+#define PS2_O_SET_SAMPLE 0xf3
-+#define PS2_O_SET_STREAM 0xea
-+#define PS2_O_SET_RES 0xe8
-+#define PS2_O_SET_SCALE21 0xe7
-+#define PS2_O_SET_SCALE11 0xe6
-+#define PS2_O_REQ_STATUS 0xe9
-+
-+/*
-+ * Responses
-+ */
-+#define PS2_I_RESEND 0xfe
-+#define PS2_I_DIAGFAIL 0xfc
-+#define PS2_I_ACK 0xfa
-+#define PS2_I_BREAK 0xf0
-+#define PS2_I_ECHO 0xee
-+#define PS2_I_BAT_OK 0xaa
-+
-+static char *kmi_type[] = { "Keyboard", "Mouse" };
-+
-+static struct kmi_info *kmi_keyb;
-+static struct kmi_info *kmi_mouse;
-+
-+static inline void __kmi_send(struct kmi_info *kmi, u_int val)
-+{
-+ u_int status;
-+
-+ do {
-+ status = __raw_readb(KMISTAT);
-+ } while (!(status & KMISTAT_TXEMPTY));
-+
-+ kmi->resend_count += 1;
-+ __raw_writeb(val, KMIDATA);
-+}
-+
-+static void kmi_send(struct kmi_info *kmi, u_int val)
-+{
-+ kmi->last_tx = val;
-+ kmi->resend_count = -1;
-+ __kmi_send(kmi, val);
-+}
-+
-+static u_int kmi_send_and_wait(struct kmi_info *kmi, u_int val, u_int timeo)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+ if (kmi->present == 0)
-+ return KMI_NO_ACK;
-+
-+ kmi->res = KMI_NO_ACK;
-+ kmi->last_tx = val;
-+ kmi->resend_count = -1;
-+
-+ if (current->pid != 0 && !in_interrupt()) {
-+ add_wait_queue(&kmi->wait_q, &wait);
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ __kmi_send(kmi, val);
-+ schedule_timeout(timeo);
-+ current->state = TASK_RUNNING;
-+ remove_wait_queue(&kmi->wait_q, &wait);
-+ } else {
-+ int i;
-+
-+ __kmi_send(kmi, val);
-+ for (i = 0; i < 1000; i++) {
-+ if (kmi->res != KMI_NO_ACK)
-+ break;
-+ udelay(100);
-+ }
-+ }
-+
-+ return kmi->res;
-+}
-+
-+/*
-+ * This lot should probably be separated into a separate file...
-+ */
-+#ifdef CONFIG_KMI_MOUSE
-+
-+#include <linux/fs.h> /* for struct file_ops */
-+#include <linux/poll.h> /* for poll_table */
-+#include <linux/miscdevice.h> /* for struct miscdev */
-+#include <linux/random.h> /* for add_mouse_randomness */
-+#include <linux/slab.h> /* for kmalloc */
-+#include <linux/smp_lock.h> /* for {un,}lock_kernel */
-+#include <linux/spinlock.h>
-+
-+#include <asm/uaccess.h>
-+
-+#define BUF_SZ 2048
-+
-+static spinlock_t kmi_mouse_lock;
-+static int kmi_mouse_count;
-+static struct queue {
-+ u_int head;
-+ u_int tail;
-+ struct fasync_struct *fasync;
-+ unsigned char buf[BUF_SZ];
-+} *queue;
-+
-+#define queue_empty() (queue->head == queue->tail)
-+
-+static u_char get_from_queue(void)
-+{
-+ unsigned long flags;
-+ u_char res;
-+
-+ spin_lock_irqsave(&kmi_mouse_lock, flags);
-+ res = queue->buf[queue->tail];
-+ queue->tail = (queue->tail + 1) & (BUF_SZ-1);
-+ spin_unlock_irqrestore(&kmi_mouse_lock, flags);
-+
-+ return res;
-+}
-+
-+static ssize_t
-+kmi_mouse_read(struct file *file, char *buf, size_t count, loff_t *ppos)
-+{
-+ ssize_t i = count;
-+
-+ if (queue_empty()) {
-+ int ret;
-+
-+ if (file->f_flags & O_NONBLOCK)
-+ return -EAGAIN;
-+ ret = wait_event_interruptible(kmi_mouse->wait_q, !queue_empty());
-+ if (ret)
-+ return ret;
-+ }
-+ while (i > 0 && !queue_empty()) {
-+ u_char c;
-+ c = get_from_queue();
-+ put_user(c, buf++);
-+ i--;
-+ }
-+ if (count - i)
-+ file->f_dentry->d_inode->i_atime = CURRENT_TIME;
-+ return count - i;
-+}
-+
-+static ssize_t
-+kmi_mouse_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
-+{
-+ ssize_t retval = 0;
-+
-+ if (count > 32)
-+ count = 32;
-+
-+ do {
-+ char c;
-+ get_user(c, buf++);
-+ kmi_send_and_wait(kmi_mouse, c, HZ);
-+ retval++;
-+ } while (--count);
-+
-+ if (retval)
-+ file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
-+
-+ return retval;
-+}
-+
-+static unsigned int
-+kmi_mouse_poll(struct file *file, poll_table *wait)
-+{
-+ poll_wait(file, &kmi_mouse->wait_q, wait);
-+ return (!queue_empty()) ? POLLIN | POLLRDNORM : 0;
-+}
-+
-+static int
-+kmi_mouse_release(struct inode *inode, struct file *file)
-+{
-+ lock_kernel();
-+ fasync_helper(-1, file, 0, &queue->fasync);
-+ if (--kmi_mouse_count == 0)
-+ kmi_send_and_wait(kmi_mouse, PS2_O_DISABLE, HZ);
-+ unlock_kernel();
-+ return 0;
-+}
-+
-+static int
-+kmi_mouse_open(struct inode *inode, struct file *file)
-+{
-+ if (kmi_mouse_count++)
-+ return 0;
-+ queue->head = queue->tail = 0;
-+ kmi_send_and_wait(kmi_mouse, PS2_O_ENABLE, HZ);
-+ return 0;
-+}
-+
-+static int
-+kmi_mouse_fasync(int fd, struct file *filp, int on)
-+{
-+ int retval = fasync_helper(fd, filp, on, &queue->fasync);
-+ if (retval > 0)
-+ retval = 0;
-+ return retval;
-+}
-+
-+static struct file_operations ps_fops = {
-+ read: kmi_mouse_read,
-+ write: kmi_mouse_write,
-+ poll: kmi_mouse_poll,
-+ open: kmi_mouse_open,
-+ release: kmi_mouse_release,
-+ fasync: kmi_mouse_fasync,
-+};
-+
-+static struct miscdevice ps_mouse = {
-+ minor: PSMOUSE_MINOR,
-+ name: "psaux",
-+ fops: &ps_fops,
-+};
-+
-+static u_char kmi_mse_init_string[] = {
-+ PS2_O_DISABLE,
-+ PS2_O_SET_SAMPLE, 100,
-+ PS2_O_SET_RES, 3,
-+ PS2_O_SET_SCALE21
-+};
-+
-+/*
-+ * The "normal" mouse scancode processing
-+ */
-+static void kmi_mse_intr(struct kmi_info *kmi, u_int val, struct pt_regs *regs)
-+{
-+ u_int head;
-+
-+ add_mouse_randomness(val);
-+
-+#ifdef CONFIG_AMBA_PS2_RECONNECT
-+ /* Try to detect a hot-plug event on the PS/2 mouse port */
-+ switch (kmi->hotplug_state) {
-+ case 0:
-+ /* Maybe we lost contact... */
-+ if (val == PS2_I_BAT_OK) {
-+ kmi->hotplug_state++;
-+ DEBUG(("%s: Saw 0xAA. Going to hotplug state %d\n", kmi->name, kmi->hotplug_state));
-+ }
-+ break;
-+
-+ case 1:
-+ /* Again, maybe (but only maybe) we lost contact... */
-+ if (val == 0) {
-+ kmi->hotplug_state++;
-+ kmi_send(kmi, PS2_O_REQ_STATUS);
-+ DEBUG(("%s: Got 0xAA 0x00. Sent Status Request\n", kmi->name));
-+ } else {
-+ kmi->hotplug_state = 0;
-+ DEBUG(("%s: No 0x00 followed 0xAA. No reconnect.\n", kmi->name));
-+ }
-+ break;
-+
-+ case 2:
-+ /* Eat up acknowledge */
-+ if (val == PS2_I_ACK)
-+ kmi->hotplug_state++;
-+ else {
-+ kmi->hotplug_state = 0;
-+ DEBUG(("%s: didn't get ack (0x%2.2x)\n", kmi->name, val));
-+ }
-+ break;
-+
-+ case 3:
-+ /* check if data reporting is still enabled, then no POR has happend */
-+ kmi->reconnect = !(val & 1<<5);
-+ DEBUG(("%s: Data reporting disabled?: (%d)\n", kmi->name, kmi->reconnect));
-+ kmi->hotplug_state++;
-+ DEBUG(("%s: Going to hotplug state %d\n", kmi->name, kmi->hotplug_state));
-+ break;
-+
-+ case 4:
-+ /* Eat up one status byte */
-+ kmi->hotplug_state++;
-+ DEBUG(("%s: Going to hotplug state %d\n", kmi->name, kmi->hotplug_state));
-+ break;
-+
-+ case 5:
-+ /* Eat up another status byte */
-+ if (kmi->reconnect) {
-+ kmi->config_num = 0;
-+ kmi_send(kmi, kmi_mse_init_string[kmi->config_num]);
-+ kmi->config_num++;
-+ kmi->hotplug_state++;
-+ DEBUG(("%s: Sending byte %d of PS/2 init string.\n", kmi->name, kmi->config_num));
-+ } else {
-+ kmi->hotplug_state = 0;
-+ DEBUG(("%s: False Alarm...\n", kmi->name));
-+ }
-+ break;
-+
-+ case 6:
-+ if (val == PS2_I_ACK && kmi->config_num < sizeof(kmi_mse_init_string)) {
-+ kmi_send(kmi, kmi_mse_init_string[kmi->config_num]);
-+ kmi->config_num++;
-+ DEBUG(("%s: Sending byte %d of PS/2 init string.\n", kmi->name, kmi->config_num));
-+ } else {
-+ if (val == PS2_I_ACK) {
-+ DEBUG(("%s: Now enable the mouse again...\n", kmi->name));
-+ queue->head = queue->tail = 0;
-+ kmi_send(kmi, PS2_O_ENABLE);
-+ kmi->hotplug_state++;
-+ } else {
-+ kmi->hotplug_state = 0;
-+ DEBUG(("%s: didn't get ack (0x%2.2x)\n", kmi->name, val));
-+ }
-+ }
-+ break;
-+
-+ case 7:
-+ /* Eat up last acknowledge from enable */
-+ if (val == PS2_I_ACK)
-+ printk(KERN_ERR "%s: reconnected\n", kmi->name);
-+ else
-+ DEBUG(("%s: didn't get ack (0x%2.2x)\n", kmi->name, val));
-+
-+ kmi->hotplug_state = 0;
-+ break;
-+
-+ } /* switch (kmi->hotplug_state) */
-+
-+ /* while inside hotplug mechanism, don't misinterpret values */
-+ if (kmi->hotplug_state > 2)
-+ return;
-+#endif
-+
-+ /* We are waiting for the mouse to respond to a kmi_send_and_wait() */
-+ if (kmi->res == KMI_NO_ACK) {
-+ if (val == PS2_I_RESEND) {
-+ if (kmi->resend_count < 5)
-+ __kmi_send(kmi, kmi->last_tx);
-+ else {
-+ printk(KERN_ERR "%s: too many resends\n", kmi->name);
-+ return;
-+ }
-+ }
-+
-+ if (val == PS2_I_ACK) {
-+ kmi->res = val;
-+ wake_up(&kmi->wait_q);
-+ }
-+ return;
-+ }
-+
-+ /* The mouse autonomously send new data, so wake up mouse_read() */
-+ if (queue) {
-+ head = queue->head;
-+ queue->buf[head] = val;
-+ head = (head + 1) & (BUF_SZ - 1);
-+ if (head != queue->tail) {
-+ queue->head = head;
-+ kill_fasync(&queue->fasync, SIGIO, POLL_IN);
-+ wake_up_interruptible(&kmi->wait_q);
-+ }
-+ }
-+}
-+
-+static int kmi_init_mouse(struct kmi_info *kmi)
-+{
-+ u_int ret, i;
-+
-+ if (kmi->present) {
-+ kmi->rx = kmi_mse_intr;
-+
-+ for (i = 0; i < sizeof(kmi_mse_init_string); i++) {
-+ ret = kmi_send_and_wait(kmi, kmi_mse_init_string[i], HZ);
-+ if (ret != PS2_I_ACK)
-+ printk("%s: didn't get ack (0x%2.2x)\n",
-+ kmi->name, ret);
-+ }
-+ }
-+
-+ queue = kmalloc(sizeof(*queue), GFP_KERNEL);
-+ if (queue) {
-+ memset(queue, 0, sizeof(*queue));
-+ misc_register(&ps_mouse);
-+ ret = 0;
-+ } else
-+ ret = -ENOMEM;
-+
-+ return ret;
-+}
-+#endif /* CONFIG_KMI_MOUSE */
-+
-+/*
-+ * The "program" we send to the keyboard to set it up how we want it:
-+ * - default typematic delays
-+ * - scancode set 1
-+ */
-+static u_char kmi_kbd_init_string[] = {
-+ PS2_O_DISABLE,
-+ PS2_O_SET_DEFAULT,
-+ PS2_O_SET_SCANSET, 0x01,
-+ PS2_O_ENABLE
-+};
-+
-+static void kmi_kbd_intr(struct kmi_info *kmi, u_int val, struct pt_regs *regs);
-+
-+static int __kmi_init_keyboard(struct kmi_info *kmi)
-+{
-+ u_int ret, i;
-+
-+ if (!kmi->present)
-+ return 0;
-+
-+ kmi->rx = kmi_kbd_intr;
-+
-+ for (i = 0; i < sizeof(kmi_kbd_init_string); i++) {
-+ ret = kmi_send_and_wait(kmi, kmi_kbd_init_string[i], HZ);
-+ if (ret != PS2_I_ACK)
-+ printk("%s: didn't ack (0x%2.2x)\n",
-+ kmi->name, ret);
-+ }
-+
-+ return 0;
-+}
-+
-+static void kmi_kbd_init_tasklet(unsigned long k)
-+{
-+ struct kmi_info *kmi = (struct kmi_info *)k;
-+ __kmi_init_keyboard(kmi);
-+}
-+
-+static DECLARE_TASKLET_DISABLED(kmikbd_init_tasklet, kmi_kbd_init_tasklet, 0);
-+
-+/*
-+ * The "normal" keyboard scancode processing
-+ */
-+static void kmi_kbd_intr(struct kmi_info *kmi, u_int val, struct pt_regs *regs)
-+{
-+#ifdef CONFIG_AMBA_PS2_RECONNECT
-+ /* Try to detect a hot-plug event on the PS/2 keyboard port */
-+ switch (kmi->hotplug_state) {
-+ case 0:
-+ /* Maybe we lost contact... */
-+ if (val == PS2_I_BAT_OK) {
-+ kmi_send(kmi, PS2_O_SET_SCANSET);
-+ kmi->hotplug_state++;
-+ DEBUG(("%s: Saw 0xAA. Going to hotplug state %d\n", kmi->name, kmi->hotplug_state));
-+ }
-+ break;
-+
-+ case 1:
-+ /* Eat up acknowledge */
-+ if (val == PS2_I_ACK) {
-+ /* Request scan code set: '2' if POR has happend, '1' is false alarm */
-+ kmi_send(kmi, 0);
-+ kmi->hotplug_state++;
-+ }
-+ else {
-+ kmi->hotplug_state = 0;
-+ DEBUG(("%s: didn't get ack (0x%2.2x)\n", kmi->name, val));
-+ }
-+ break;
-+
-+ case 2:
-+ /* Eat up acknowledge */
-+ if (val == PS2_I_ACK)
-+ kmi->hotplug_state++;
-+ else {
-+ kmi->hotplug_state = 0;
-+ DEBUG(("%s: didn't get ack (0x%2.2x)\n", kmi->name, val));
-+ }
-+ break;
-+
-+ case 3:
-+ kmi->hotplug_state = 0;
-+ if (val == 2) {
-+ DEBUG(("%s: POR detected. Scan code is: (%d)\n", kmi->name, val));
-+ kmi->present = 1;
-+ tasklet_schedule(&kmikbd_init_tasklet);
-+ printk(KERN_ERR "%s: reconnected\n", kmi->name);
-+ return;
-+ }
-+ else
-+ DEBUG(("%s: False Alarm...\n", kmi->name));
-+ break;
-+
-+ } /* switch (kmi->hotplug_state) */
-+#endif
-+
-+ if (val == PS2_I_DIAGFAIL) {
-+ printk(KERN_ERR "%s: diagnostic failed\n", kmi->name);
-+ return;
-+ }
-+
-+ /* We are waiting for the keyboard to respond to a kmi_send_and_wait() */
-+ if (kmi->res == KMI_NO_ACK) {
-+ if (val == PS2_I_RESEND) {
-+ if (kmi->resend_count < 5)
-+ __kmi_send(kmi, kmi->last_tx);
-+ else {
-+ printk(KERN_ERR "%s: too many resends\n", kmi->name);
-+ return;
-+ }
-+ }
-+
-+ if (val >= 0xee) {
-+ kmi->res = val;
-+ wake_up(&kmi->wait_q);
-+ }
-+ return;
-+ }
-+
-+#ifdef CONFIG_VT
-+ kbd_pt_regs = regs;
-+ handle_scancode(val, !(val & 0x80));
-+ tasklet_schedule(&keyboard_tasklet);
-+#endif
-+}
-+
-+static void kmi_intr(int nr, void *devid, struct pt_regs *regs)
-+{
-+ struct kmi_info *kmi = devid;
-+ u_int status = __raw_readb(KMIIR);
-+
-+ if (status & KMIIR_RXINTR) {
-+ u_int val = __raw_readb(KMIDATA);
-+
-+ if (kmi->rx)
-+ kmi->rx(kmi, val, regs);
-+ }
-+}
-+
-+static int kmi_init_keyboard(struct kmi_info *kmi)
-+{
-+ kmikbd_init_tasklet.data = (unsigned long)kmi;
-+ tasklet_enable(&kmikbd_init_tasklet);
-+
-+ return __kmi_init_keyboard(kmi);
-+}
-+
-+/*
-+ * Reset interrupt handler
-+ */
-+static void __init
-+kmi_reset_intr(struct kmi_info *kmi, u_int val, struct pt_regs *regs)
-+{
-+ if (kmi->state == KMI_RESET) {
-+ if (val == PS2_I_ACK)
-+ kmi->state = KMI_RESET_POR;
-+ else {
-+ val = KMI_NO_ACK;
-+ goto finished;
-+ }
-+ } else if (kmi->state == KMI_RESET_POR) {
-+finished:
-+ kmi->res = val;
-+ kmi->state = KMI_RESET_DONE;
-+ kmi->rx = NULL;
-+ wake_up(&kmi->wait_q);
-+ }
-+}
-+
-+/*
-+ * Reset the device plugged into this interface
-+ */
-+static int __init kmi_reset(struct kmi_info *kmi)
-+{
-+ u_int res;
-+ int ret = 0;
-+
-+ kmi->state = KMI_RESET;
-+ kmi->rx = kmi_reset_intr;
-+ res = kmi_send_and_wait(kmi, PS2_O_RESET, HZ);
-+ kmi->rx = NULL;
-+
-+ if (res != PS2_I_BAT_OK) {
-+ printk(KERN_ERR "%s: reset failed; ", kmi->name);
-+ if (kmi->res != KMI_NO_ACK)
-+ printk("code 0x%2.2x\n", kmi->res);
-+ else
-+ printk("no ack\n");
-+ ret = -EINVAL;
-+ }
-+ return ret;
-+}
-+
-+static int __init kmi_init_one_interface(struct kmi_info *kmi)
-+{
-+ u_int stat;
-+ int ret = -ENODEV;
-+
-+ init_waitqueue_head(&kmi->wait_q);
-+
-+ printk(KERN_INFO "%s at 0x%8.8x on irq %d (%s)\n", kmi->name,
-+ kmi->base, kmi->irq, kmi_type[kmi->type]);
-+
-+ /*
-+ * Initialise the KMI interface
-+ */
-+ __raw_writeb(kmi->divisor, KMICLKDIV);
-+ __raw_writeb(KMICR_EN, KMICR);
-+
-+ /*
-+ * Check that the data and clock lines are OK.
-+ */
-+ stat = __raw_readb(KMISTAT);
-+ if ((stat & (KMISTAT_IC|KMISTAT_ID)) != (KMISTAT_IC|KMISTAT_ID)) {
-+ printk(KERN_ERR "%s: %s%s%sline%s stuck low\n", kmi->name,
-+ (stat & KMISTAT_IC) ? "" : "clock ",
-+ (stat & (KMISTAT_IC | KMISTAT_ID)) ? "" : "and ",
-+ (stat & KMISTAT_ID) ? "" : "data ",
-+ (stat & (KMISTAT_IC | KMISTAT_ID)) ? "" : "s");
-+ goto bad;
-+ }
-+
-+ /*
-+ * Claim the appropriate interrupts
-+ */
-+ ret = request_irq(kmi->irq, kmi_intr, 0, kmi->name, kmi);
-+ if (ret)
-+ goto bad;
-+
-+ /*
-+ * Enable the receive interrupt, and reset the device.
-+ */
-+ __raw_writeb(KMICR_EN | KMICR_RXINTREN, KMICR);
-+ kmi->present = 1;
-+ kmi->present = kmi_reset(kmi) == 0;
-+
-+ switch (kmi->type) {
-+ case KMI_KEYBOARD:
-+ ret = kmi_init_keyboard(kmi);
-+ break;
-+
-+#ifdef CONFIG_KMI_MOUSE
-+ case KMI_MOUSE:
-+ ret = kmi_init_mouse(kmi);
-+ break;
-+#endif
-+ }
-+
-+ return ret;
-+
-+bad:
-+ /*
-+ * Oh dear, the interface was bad, disable it.
-+ */
-+ __raw_writeb(0, KMICR);
-+ return ret;
-+}
-+
-+#ifdef CONFIG_VT
-+/*
-+ * The fragment between #ifdef above and #endif * CONFIG_VT *
-+ * is from the pc_keyb.c driver. It is not copyrighted under the
-+ * above notice. This code is by various authors; please see
-+ * drivers/char/pc_keyb.c for further information.
-+ */
-+
-+/*
-+ * Translation of escaped scancodes to keycodes.
-+ * This is now user-settable.
-+ * The keycodes 1-88,96-111,119 are fairly standard, and
-+ * should probably not be changed - changing might confuse X.
-+ * X also interprets scancode 0x5d (KEY_Begin).
-+ *
-+ * For 1-88 keycode equals scancode.
-+ */
-+
-+#define E0_KPENTER 96
-+#define E0_RCTRL 97
-+#define E0_KPSLASH 98
-+#define E0_PRSCR 99
-+#define E0_RALT 100
-+#define E0_BREAK 101 /* (control-pause) */
-+#define E0_HOME 102
-+#define E0_UP 103
-+#define E0_PGUP 104
-+#define E0_LEFT 105
-+#define E0_RIGHT 106
-+#define E0_END 107
-+#define E0_DOWN 108
-+#define E0_PGDN 109
-+#define E0_INS 110
-+#define E0_DEL 111
-+
-+#define E1_PAUSE 119
-+
-+/* BTC */
-+#define E0_MACRO 112
-+/* LK450 */
-+#define E0_F13 113
-+#define E0_F14 114
-+#define E0_HELP 115
-+#define E0_DO 116
-+#define E0_F17 117
-+#define E0_KPMINPLUS 118
-+/*
-+ * My OmniKey generates e0 4c for the "OMNI" key and the
-+ * right alt key does nada. [kkoller@nyx10.cs.du.edu]
-+ */
-+#define E0_OK 124
-+/*
-+ * New microsoft keyboard is rumoured to have
-+ * e0 5b (left window button), e0 5c (right window button),
-+ * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
-+ * [or: Windows_L, Windows_R, TaskMan]
-+ */
-+#define E0_MSLW 125
-+#define E0_MSRW 126
-+#define E0_MSTM 127
-+
-+static u_char e0_keys[128] = {
-+ 0, 0, 0, 0,
-+ 0, 0, 0, 0,
-+ 0, 0, 0, 0,
-+ 0, 0, 0, 0,
-+ 0, 0, 0, 0,
-+ 0, 0, 0, 0,
-+ 0, 0, 0, 0,
-+ E0_KPENTER, E0_RCTRL, 0, 0,
-+ 0, 0, 0, 0,
-+ 0, 0, 0, 0,
-+ 0, 0, 0, 0,
-+ 0, 0, 0, 0,
-+ 0, 0, 0, 0,
-+ 0, E0_KPSLASH, 0, E0_PRSCR,
-+ E0_RALT, 0, 0, 0,
-+ 0, E0_F13, E0_F14, E0_HELP,
-+ E0_DO, E0_F17, 0, 0,
-+ 0, 0, E0_BREAK, E0_HOME,
-+ E0_UP, E0_PGUP, 0, E0_LEFT,
-+ E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,
-+ E0_DOWN, E0_PGDN, E0_INS, E0_DEL,
-+ 0, 0, 0, 0,
-+ 0, 0, 0, E0_MSLW,
-+ E0_MSRW, E0_MSTM, 0, 0,
-+ 0, 0, 0, 0,
-+ 0, 0, 0, 0,
-+ 0, 0, 0, 0,
-+ 0, 0, 0, E0_MACRO,
-+ 0, 0, 0, 0,
-+ 0, 0, 0, 0,
-+ 0, 0, 0, 0,
-+ 0, 0, 0, 0
-+};
-+
-+#ifdef CONFIG_MAGIC_SYSRQ
-+u_char kmi_kbd_sysrq_xlate[128] =
-+ "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
-+ "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
-+ "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
-+ "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
-+ "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
-+ "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
-+ "\r\000/"; /* 0x60 - 0x6f */
-+#endif
-+
-+int kmi_kbd_setkeycode(u_int scancode, u_int keycode)
-+{
-+ if (scancode < 128 || scancode > 255 || keycode > 127)
-+ return -EINVAL;
-+ e0_keys[scancode - 128] = keycode;
-+ return 0;
-+}
-+
-+int kmi_kbd_getkeycode(u_int scancode)
-+{
-+ if (scancode < 128 || scancode > 255)
-+ return -EINVAL;
-+ return e0_keys[scancode - 128];
-+}
-+
-+int kmi_kbd_translate(u_char scancode, u_char *keycode, char raw_mode)
-+{
-+ static int prev_scancode = 0;
-+
-+ /* special prefix scancodes.. */
-+ if (scancode == 0xe0 || scancode == 0xe1) {
-+ prev_scancode = scancode;
-+ return 0;
-+ }
-+
-+ /* 0xff is sent by a few keyboards, ignore it. 0x00 is error */
-+ if (scancode == 0x00 || scancode == 0xff) {
-+ prev_scancode = 0;
-+ return 0;
-+ }
-+
-+ scancode &= 0x7f;
-+
-+ if (prev_scancode) {
-+ int old_scancode = prev_scancode;
-+
-+ prev_scancode = 0;
-+ switch (old_scancode) {
-+ case 0xe0:
-+ /*
-+ * The keyboard maintains its own internal caps lock
-+ * and num lock status. In caps lock mode, E0 AA
-+ * precedes make code and E0 2A follows break code.
-+ * In numlock mode, E0 2A precedes make code, and
-+ * E0 AA follows break code. We do our own book-
-+ * keeping, so we will just ignore these.
-+ *
-+ * For my keyboard there is no caps lock mode, but
-+ * there are both Shift-L and Shift-R modes. The
-+ * former mode generates E0 2A / E0 AA pairs, the
-+ * latter E0 B6 / E0 36 pairs. So, we should also
-+ * ignore the latter. - aeb@cwi.nl
-+ */
-+ if (scancode == 0x2a || scancode == 0x36)
-+ return 0;
-+ if (e0_keys[scancode])
-+ *keycode = e0_keys[scancode];
-+ else {
-+ if (!raw_mode)
-+ printk(KERN_INFO "kbd: unknown "
-+ "scancode e0 %02x\n",
-+ scancode);
-+ return 0;
-+ }
-+ break;
-+
-+ case 0xe1:
-+ if (scancode == 0x1d)
-+ prev_scancode = 0x100;
-+ else {
-+ if (!raw_mode)
-+ printk(KERN_INFO "kbd: unknown "
-+ "scancode e1 %02x\n",
-+ scancode);
-+ return 0;
-+ }
-+ break;
-+
-+ case 0x100:
-+ if (scancode == 0x45)
-+ *keycode = E1_PAUSE;
-+ else {
-+ if (!raw_mode)
-+ printk(KERN_INFO "kbd: unknown "
-+ "scan code e1 1d %02x\n",
-+ scancode);
-+ return 0;
-+ }
-+ break;
-+ }
-+ } else
-+ *keycode = scancode;
-+ return 1;
-+}
-+
-+char kmi_kbd_unexpected_up(u_char keycode)
-+{
-+ return 0x80;
-+}
-+
-+void kmi_kbd_leds(u_char leds)
-+{
-+ struct kmi_info *kmi = kmi_keyb;
-+ u_int ret;
-+
-+ if (kmi) {
-+ ret = kmi_send_and_wait(kmi, PS2_O_INDICATORS, HZ);
-+ if (ret != KMI_NO_ACK)
-+ ret = kmi_send_and_wait(kmi, leds, HZ);
-+ if (ret == KMI_NO_ACK)
-+ kmi->present = 0;
-+ }
-+}
-+
-+int __init kmi_kbd_init(void)
-+{
-+ int ret = -ENODEV;
-+
-+ if (kmi_keyb) {
-+ strcpy(kmi_keyb->name, "kmikbd");
-+ ret = kmi_init_one_interface(kmi_keyb);
-+ }
-+
-+ if (ret == 0) {
-+ k_setkeycode = kmi_kbd_setkeycode;
-+ k_getkeycode = kmi_kbd_getkeycode;
-+ k_translate = kmi_kbd_translate;
-+ k_unexpected_up = kmi_kbd_unexpected_up;
-+ k_leds = kmi_kbd_leds;
-+#ifdef CONFIG_MAGIC_SYSRQ
-+ k_sysrq_xlate = kmi_kbd_sysrq_xlate;
-+ k_sysrq_key = 0x54;
-+#endif
-+ }
-+
-+ return ret;
-+}
-+
-+#endif /* CONFIG_VT */
-+
-+int register_kmi(struct kmi_info *kmi)
-+{
-+ struct kmi_info **kmip = NULL;
-+ int ret;
-+
-+ if (kmi->type == KMI_KEYBOARD)
-+ kmip = &kmi_keyb;
-+ else if (kmi->type == KMI_MOUSE)
-+ kmip = &kmi_mouse;
-+
-+ ret = -EINVAL;
-+ if (kmip) {
-+ ret = -EBUSY;
-+ if (!*kmip) {
-+ *kmip = kmi;
-+ ret = 0;
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+#ifdef CONFIG_KMI_MOUSE
-+static int __init kmi_init(void)
-+{
-+ int ret = -ENODEV;
-+
-+ if (kmi_mouse) {
-+ strcpy(kmi_mouse->name, "kmimouse");
-+ ret = kmi_init_one_interface(kmi_mouse);
-+ }
-+
-+ return ret;
-+}
-+
-+__initcall(kmi_init);
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/anakin_ts.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,208 @@
-+/*
-+ * linux/drivers/char/anakin_ts.c
-+ *
-+ * Copyright (C) 2001 Aleph One Ltd. for Acunia N.V.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Changelog:
-+ * 18-Apr-2001 TTC Created
-+ * 23-Oct-2001 dwmw2 Cleanup
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/wait.h>
-+#include <linux/fs.h>
-+#include <linux/sched.h>
-+#include <linux/poll.h>
-+#include <linux/miscdevice.h>
-+#include <linux/init.h>
-+#include <linux/compiler.h>
-+#include <linux/interrupt.h>
-+
-+#include <asm/io.h>
-+#include <asm/uaccess.h>
-+#include <asm/irq.h>
-+
-+/*
-+ * TSBUF_SIZE must be a power of two
-+ */
-+#define ANAKIN_TS_MINOR 16
-+#define TSBUF_SIZE 256
-+#define NEXT(index) (((index) + 1) & (TSBUF_SIZE - 1))
-+
-+static unsigned short buffer[TSBUF_SIZE][4];
-+static int head, tail;
-+static DECLARE_WAIT_QUEUE_HEAD(queue);
-+static DECLARE_MUTEX(open_sem);
-+static spinlock_t tailptr_lock = SPIN_LOCK_UNLOCKED;
-+static struct fasync_struct *fasync;
-+
-+/*
-+ * Interrupt handler and standard file operations
-+ */
-+static void
-+anakin_ts_handler(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ unsigned int status = __raw_readl(IO_BASE + IO_CONTROLLER + 0x24);
-+
-+ /*
-+ * iPAQ format (u16 pressure, x, y, millisecs)
-+ */
-+ switch (status >> 20 & 3) {
-+ case 0:
-+ return;
-+ case 2:
-+ buffer[head][0] = 0;
-+ break;
-+ default:
-+ buffer[head][0] = 0x7f;
-+ }
-+
-+ if (unlikely((volatile int)tail == NEXT(head))) {
-+ /* Run out of space in the buffer. Move the tail pointer */
-+ spin_lock(&tailptr_lock);
-+
-+ if ((volatile int)tail == NEXT(head)) {
-+ tail = NEXT(NEXT(head));
-+ }
-+ spin_unlock(&tailptr_lock);
-+ }
-+
-+ buffer[head][1] = status >> 2 & 0xff;
-+ buffer[head][2] = status >> 12 & 0xff;
-+ buffer[head][3] = jiffies;
-+ mb();
-+ head = NEXT(head);
-+
-+ wake_up_interruptible(&queue);
-+ kill_fasync(&fasync, SIGIO, POLL_IN);
-+
-+}
-+
-+static ssize_t
-+anakin_ts_read(struct file *filp, char *buf, size_t count, loff_t *l)
-+{
-+ unsigned short data[4];
-+ ssize_t written = 0;
-+
-+ if (head == tail) {
-+ if (filp->f_flags & O_NONBLOCK)
-+ return -EAGAIN;
-+ if (wait_event_interruptible(queue, (volatile int)head != (volatile int)tail))
-+ return -ERESTARTSYS;
-+ }
-+
-+ while ((volatile int)head != (volatile int)tail && count >= sizeof data) {
-+ /* Copy the data out with the spinlock held, so the
-+ interrupt can't fill the buffer and move the tail
-+ pointer while we're doing it */
-+ spin_lock_irq(&tailptr_lock);
-+
-+ memcpy(data, buffer[tail], sizeof data);
-+ tail = NEXT(tail);
-+
-+ spin_unlock_irq(&tailptr_lock);
-+
-+ if (copy_to_user(buf, data, sizeof data))
-+ return -EFAULT;
-+ count -= sizeof data;
-+ buf += sizeof data;
-+ written += sizeof data;
-+ }
-+ return written ? written : -EINVAL;
-+}
-+
-+static unsigned int
-+anakin_ts_poll(struct file *filp, poll_table *wait)
-+{
-+ poll_wait(filp, &queue, wait);
-+ return head != tail ? POLLIN | POLLRDNORM : 0;
-+}
-+
-+static int
-+anakin_ts_ioctl(struct inode *inode, struct file *filp,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ /*
-+ * Future ioctl goes here
-+ */
-+ return 0;
-+}
-+
-+static int
-+anakin_ts_open(struct inode *inode, struct file *filp)
-+{
-+ if (down_trylock(&open_sem))
-+ return -EBUSY;
-+ return 0;
-+}
-+
-+static int
-+anakin_ts_fasync(int fd, struct file *filp, int on)
-+{
-+ return fasync_helper(fd, filp, on, &fasync);
-+}
-+
-+static int
-+anakin_ts_release(struct inode *inode, struct file *filp)
-+{
-+ anakin_ts_fasync(-1, filp, 0);
-+ up(&open_sem);
-+ return 0;
-+}
-+
-+static struct file_operations anakin_ts_fops = {
-+ owner: THIS_MODULE,
-+ read: anakin_ts_read,
-+ poll: anakin_ts_poll,
-+ ioctl: anakin_ts_ioctl,
-+ open: anakin_ts_open,
-+ release: anakin_ts_release,
-+ fasync: anakin_ts_fasync,
-+};
-+
-+static struct miscdevice anakin_ts_miscdev = {
-+ ANAKIN_TS_MINOR,
-+ "anakin_ts",
-+ &anakin_ts_fops
-+};
-+
-+/*
-+ * Initialization and exit routines
-+ */
-+int __init
-+anakin_ts_init(void)
-+{
-+ int retval;
-+
-+ if ((retval = request_irq(IRQ_TOUCHSCREEN, anakin_ts_handler,
-+ SA_INTERRUPT, "anakin_ts", 0))) {
-+ printk(KERN_WARNING "anakin_ts: failed to get IRQ\n");
-+ return retval;
-+ }
-+ __raw_writel(1, IO_BASE + IO_CONTROLLER + 8);
-+ misc_register(&anakin_ts_miscdev);
-+
-+ printk(KERN_NOTICE "Anakin touchscreen driver initialised\n");
-+
-+ return 0;
-+}
-+
-+void __exit
-+anakin_ts_exit(void)
-+{
-+ __raw_writel(0, IO_BASE + IO_CONTROLLER + 8);
-+ free_irq(IRQ_TOUCHSCREEN, 0);
-+ misc_deregister(&anakin_ts_miscdev);
-+}
-+
-+module_init(anakin_ts_init);
-+module_exit(anakin_ts_exit);
-+
-+MODULE_AUTHOR("Tak-Shing Chan <chan@aleph1.co.uk>");
-+MODULE_DESCRIPTION("Anakin touchscreen driver");
-+MODULE_SUPPORTED_DEVICE("touchscreen/anakin");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/cerf_keyb.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,380 @@
-+/*
-+ cerf_keyb.c: This is the end. Daniel is writing a device driver!!!
-+*/
-+#include <linux/config.h>
-+
-+#include <linux/spinlock.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/tty.h>
-+#include <linux/mm.h>
-+#include <linux/signal.h>
-+#include <linux/init.h>
-+#include <linux/kbd_ll.h>
-+#include <linux/delay.h>
-+#include <linux/random.h>
-+#include <linux/poll.h>
-+#include <linux/miscdevice.h>
-+#include <linux/slab.h>
-+#include <linux/kbd_kern.h>
-+#include <linux/smp_lock.h>
-+#include <linux/timer.h>
-+
-+#include <asm/keyboard.h>
-+#include <asm/bitops.h>
-+#include <asm/uaccess.h>
-+#include <asm/irq.h>
-+#include <asm/system.h>
-+
-+#include <asm/io.h>
-+
-+#define KBD_REPORT_UNKN
-+
-+#define KBD_REPORT_ERR /* Report keyboard errors */
-+#define KBD_REPORT_UNKN /* Report unknown scan codes */
-+#define KBD_REPORT_TIMEOUTS /* Report keyboard timeouts */
-+#define KBD_NO_DATA (-1) /* No data */
-+#define KBD_REPEAT_START (0x20)
-+#define KBD_REPEAT_CONTINUE (0x05)
-+#define KBD_KEY_DOWN_MAX (0x10)
-+#define UINT_LEN (20)
-+#define SC_LIM (69)
-+#define KBD_ROWS (5)
-+#define KBD_COLUMNS (8)
-+
-+#define KBD_KEYUP (0x80)
-+#define KBD_MODESCAN (0x7f)
-+#define KBD_CAPSSCAN (0x3a)
-+#define KBD_SHIFTSCAN (0x2a)
-+#define KBD_NUMCURSCAN (0x7c)
-+#define KBD_CTRLSCAN (0x1d)
-+#define KBD_ALTSCAN (0x38)
-+
-+#define KBD_UP_OFF (0)
-+#define KBD_UP_ON (1)
-+#define KBD_DOWN (2)
-+#define KBD_DOWN_HOLD (3)
-+
-+
-+
-+static unsigned char handle_kbd_event(void);
-+static unsigned char kbd_read_input(void);
-+static void column_set(unsigned int column);
-+static int scancodes(unsigned char codeval[KBD_ROWS][KBD_COLUMNS]);
-+
-+static spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
-+static struct timer_list kbd_timer;
-+
-+static short mode_ena = 0;
-+static short numcur_ena = 0;
-+static short shift_ena = 0;
-+
-+#define E0_KPENTER 96
-+#define E0_RCTRL 97
-+#define E0_KPSLASH 98
-+#define E0_PRSCR 99
-+#define E0_RALT 100
-+#define E0_BREAK 101 /* (control-pause) */
-+#define E0_HOME 102
-+#define E0_UP 103
-+#define E0_PGUP 104
-+#define E0_LEFT 105
-+#define E0_RIGHT 106
-+#define E0_END 107
-+#define E0_DOWN 108
-+#define E0_PGDN 109
-+#define E0_INS 110
-+#define E0_DEL 111
-+#define E1_PAUSE 119
-+#define E0_MACRO 112
-+#define E0_F13 113
-+#define E0_F14 114
-+#define E0_HELP 115
-+#define E0_DO 116
-+#define E0_F17 117
-+#define E0_KPMINPLUS 118
-+#define E0_OK 124
-+#define E0_MSLW 125
-+#define E0_MSRW 126
-+#define E0_MSTM 127
-+
-+static unsigned char e0_keys[128] = {
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */
-+ 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0, /* 0x18-0x1f */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */
-+ 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR, /* 0x30-0x37 */
-+ E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP, /* 0x38-0x3f */
-+ E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */
-+ E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
-+ E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0, /* 0x50-0x57 */
-+ 0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0, /* 0x58-0x5f */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
-+ 0, 0, 0, 0, 0, 0, 0, E0_MACRO, /* 0x68-0x6f */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */
-+ 0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */
-+};
-+
-+static unsigned char cerf_normal_map[KBD_ROWS][KBD_COLUMNS] = {
-+ {KBD_ALTSCAN, KBD_MODESCAN, 0x1e, 0x30, 0x2e, 0x20, 0x00, 0x00},
-+ {0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x00},
-+ {0x26, 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x00},
-+ {0x1f, 0x14, 0x16, 0x2f, 0x11, 0x2d, 0x15, 0x00},
-+ {0x2c, KBD_SHIFTSCAN, KBD_CTRLSCAN, 0x39, KBD_NUMCURSCAN, 0x2b, 0x1c, 0x00}
-+};
-+
-+static unsigned char cerf_mode_map[KBD_ROWS][KBD_COLUMNS] = {
-+ {0x00, 0x00, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00},
-+ {0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x00, 0x00}, //
-+ {0x0d, 0x0c, 0x37, 0x35, 0x0d, 0x48, 0x28, 0x00},
-+ {0x01, 0x33, 0x34, 0x00, 0x4b, 0x27, 0x4d, 0x00}, //
-+ {0x0f, 0x00, KBD_CAPSSCAN, 0x0e, 0x00, 0x50, 0x00, 0x00}
-+};
-+
-+static unsigned char cerf_numcur_map[KBD_ROWS][KBD_COLUMNS] = {
-+ {0x00, 0x00, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00},
-+ {0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x00, 0x00},
-+ {0x0d, 0x0c, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00},
-+ {0x00, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x4d, 0x00},
-+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00}
-+};
-+
-+static void column_set(unsigned int column)
-+{
-+ if (column < 0)
-+ {
-+ CERF_PDA_CPLD_UnSet(CERF_PDA_CPLD_KEYPAD_A, 0xFF, 0xFF);
-+ CERF_PDA_CPLD_UnSet(CERF_PDA_CPLD_KEYPAD_B, 0xFF, 0xFF);
-+ }
-+ else
-+ {
-+ if(column < 4)
-+ {
-+ CERF_PDA_CPLD_Set(CERF_PDA_CPLD_KEYPAD_A, 1 << (column % 4), 0xFF);
-+ CERF_PDA_CPLD_UnSet(CERF_PDA_CPLD_KEYPAD_B, 0xFF, 0xFF);
-+ }
-+ else
-+ {
-+ CERF_PDA_CPLD_UnSet(CERF_PDA_CPLD_KEYPAD_A, 0xFF, 0xFF);
-+ CERF_PDA_CPLD_Set(CERF_PDA_CPLD_KEYPAD_B, 1 << (column % 4), 0xFF);
-+ }
-+ }
-+}
-+
-+static int scancodes(unsigned char codeval[KBD_ROWS][KBD_COLUMNS])
-+{
-+ int i, j;
-+
-+ for(i = 0; i < KBD_COLUMNS; i++)
-+ {
-+ column_set(i);
-+ udelay(50);
-+ for(j = 0; j < KBD_ROWS; j++)
-+ {
-+ if(mode_ena)
-+ codeval[j][i] = (GPLR & (1 << (20 + j)))?(cerf_mode_map[j][i]?cerf_mode_map[j][i]:cerf_normal_map[j][i]):0;
-+ else if(numcur_ena)
-+ codeval[j][i] = (GPLR & (1 << (20 + j)))?(cerf_numcur_map[j][i]?cerf_numcur_map[j][i]:cerf_normal_map[j][i]):0;
-+ else
-+ codeval[j][i] = (GPLR & (1 << (20 + j)))?cerf_normal_map[j][i]:0;
-+ }
-+ }
-+ column_set(-1);
-+
-+ return 0;
-+}
-+
-+static unsigned char kbd_read_input(void)
-+{
-+ int i, j, k, l;
-+ unsigned char prev;
-+ static unsigned char count = 0;
-+
-+ static unsigned char oldcodes[KBD_ROWS][KBD_COLUMNS]={{0,0,0,0,0,0,0,0},
-+ {0,0,0,0,0,0,0,0},
-+ {0,0,0,0,0,0,0,0},
-+ {0,0,0,0,0,0,0,0},
-+ {0,0,0,0,0,0,0,0}};
-+ unsigned char inputcode[KBD_ROWS][KBD_COLUMNS];
-+
-+ memset(inputcode, 0, sizeof(unsigned char) * (KBD_ROWS * KBD_COLUMNS));
-+ scancodes(inputcode);
-+
-+ for(i = 0; i < KBD_COLUMNS; i++)
-+ {
-+ for(j = 0; j < KBD_ROWS; j++)
-+ {
-+// if(oldcodes[j][i] == 0xe0)
-+// oldcodes[j][i] =
-+ if(oldcodes[j][i] != inputcode[j][i])
-+ {
-+ // Value of the key before entering this function
-+ prev = oldcodes[j][i];
-+
-+ // KEYUP
-+ if(inputcode[j][i] == 0 && oldcodes[j][i] != 0 && !(oldcodes[j][i] & KBD_KEYUP))
-+ {
-+ oldcodes[j][i] |= KBD_KEYUP;
-+
-+ if(mode_ena == KBD_UP_ON)
-+ mode_ena = KBD_UP_OFF;
-+ if(prev == KBD_MODESCAN)
-+ if(mode_ena == KBD_DOWN_HOLD)
-+ mode_ena = KBD_UP_OFF;
-+ else if(mode_ena == KBD_DOWN)
-+ mode_ena = KBD_UP_ON;
-+ if(mode_ena == KBD_DOWN)
-+ mode_ena = KBD_DOWN_HOLD;
-+ }
-+ // RESET KEYUP
-+ else if(oldcodes[j][i] & KBD_KEYUP)
-+ oldcodes[j][i] = 0;
-+ // KEY DOWN
-+ else
-+ {
-+ oldcodes[j][i] = inputcode[j][i];
-+
-+ // Parse out mode modifiers before the keyboard interpreter can touch them
-+ if(inputcode[j][i] == KBD_MODESCAN)
-+ {
-+ if(!mode_ena)
-+ mode_ena = KBD_DOWN;
-+ continue;
-+ }
-+ if(inputcode[j][i] == KBD_NUMCURSCAN)
-+ {
-+ numcur_ena = numcur_ena?0:1;
-+ continue;
-+ }
-+ }
-+ //printk("Modified: (%#x,%#x), ipv:%#x, To: (%#.2x), From: (%#.2x), Flags:%d,%d,%d\r\n", j, i, inputcode[j][i], oldcodes[j][i], prev, mode_ena, shift_ena, numcur_ena);
-+ return oldcodes[j][i];
-+ }
-+ }
-+ }
-+
-+ return (unsigned char)(KBD_NO_DATA);
-+}
-+
-+int cerf_kbd_translate(unsigned char scancode, unsigned char *keycode,
-+ char raw_mode)
-+{
-+ static int prev_scancode;
-+
-+ if (scancode == 0xe0 || scancode == 0xe1) {
-+ prev_scancode = scancode;
-+ return 0;
-+ }
-+
-+ if (scancode == 0x00 || scancode == 0xff) {
-+ prev_scancode = 0;
-+ return 0;
-+ }
-+
-+ scancode &= 0x7f;
-+
-+ if (prev_scancode) {
-+ if (prev_scancode != 0xe0) {
-+ if (prev_scancode == 0xe1 && scancode == 0x1d) {
-+ prev_scancode = 0x100;
-+ return 0;
-+ } else if (prev_scancode == 0x100 && scancode == 0x45) {
-+ prev_scancode = 0;
-+ } else {
-+#ifdef KBD_REPORT_UNKN
-+ if (!raw_mode)
-+ printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
-+#endif
-+ prev_scancode = 0;
-+ return 0;
-+ }
-+ } else {
-+ prev_scancode = 0;
-+ if (scancode == 0x2a || scancode == 0x36)
-+ return 0;
-+ else {
-+#ifdef KBD_REPORT_UNKN
-+ if (!raw_mode)
-+ printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
-+ scancode);
-+#endif
-+ return 0;
-+ }
-+ }
-+ } else
-+ *keycode = scancode;
-+ return 1;
-+}
-+
-+static inline void handle_keyboard_event(unsigned char scancode)
-+{
-+ if(scancode != (unsigned char)(KBD_NO_DATA))
-+ {
-+#ifdef CONFIG_VT
-+ handle_scancode(scancode, !(scancode & KBD_KEYUP));
-+#endif
-+ tasklet_schedule(&keyboard_tasklet);
-+ }
-+}
-+
-+static unsigned char handle_kbd_event(void)
-+{
-+ unsigned char scancode;
-+
-+ scancode = kbd_read_input();
-+ handle_keyboard_event(scancode);
-+
-+ return 0;
-+}
-+
-+/* Handle the automatic interrupts handled by the timer */
-+static void keyboard_interrupt(unsigned long foo)
-+{
-+ spin_lock_irq(&kbd_controller_lock);
-+ handle_kbd_event();
-+ spin_unlock_irq(&kbd_controller_lock);
-+
-+ kbd_timer.expires = 8 + jiffies;
-+ kbd_timer.data = 0x00000000;
-+ kbd_timer.function = (void(*)(unsigned long))&keyboard_interrupt;
-+
-+ add_timer(&kbd_timer);
-+}
-+
-+void cerf_leds(unsigned char leds)
-+{
-+}
-+char cerf_unexpected_up(unsigned char keycode)
-+{
-+return 0;
-+}
-+int cerf_getkeycode(unsigned int scancode)
-+{
-+return 0;
-+}
-+int cerf_setkeycode(unsigned int scancode, unsigned int keycode)
-+{
-+return 0;
-+}
-+
-+void cerf_kbd_init_hw(void)
-+{
-+ printk("Starting Cerf PDA Keyboard Driver... ");
-+
-+ k_setkeycode = cerf_setkeycode;
-+ k_getkeycode = cerf_getkeycode;
-+ k_translate = cerf_kbd_translate;
-+ k_unexpected_up = cerf_unexpected_up;
-+ k_leds = cerf_leds;
-+
-+ GPDR &= ~(GPIO_GPIO(20) | GPIO_GPIO(21) | GPIO_GPIO(22) | GPIO_GPIO(23) | GPIO_GPIO(24));
-+ kbd_timer.expires = 40 + jiffies;
-+ kbd_timer.data = 0x00000000;
-+ kbd_timer.function = (void(*)(unsigned long))&keyboard_interrupt;
-+
-+ add_timer(&kbd_timer);
-+
-+ printk("Done\r\n");
-+}
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/clps711x_keyb.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,547 @@
-+/*
-+ * drivers/char/clps711x_keyb.c
-+ *
-+ * Copyright (C) 2001 Thomas Gleixner <gleixner@autronix.de>
-+ *
-+ * based on drivers/edb7211_keyb.c, which is copyright (C) 2000 Bluemug Inc.
-+ *
-+ * Keyboard driver for ARM Linux on EP7xxx and CS89712 processors
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation. See the file COPYING
-+ * in the main directory of this archive for more details.
-+ *
-+ *
-+ * Hardware:
-+ *
-+ * matrix scan keyboards based on EP7209,7211,7212,7312 and CS89712
-+ * on chip keyboard scanner.
-+ * Adaption for different machines is done in init function.
-+ *
-+ * Basic Function:
-+ *
-+ * Basicly the driver is interrupt driven. It sets all column drivers
-+ * high. If any key is pressed, a interrupt occures. Now a seperate scan of
-+ * each column is done. This scan is timer based, because we use a keyboard
-+ * interface with decoupling capacitors (neccecary if you want to survive
-+ * EMC compliance tests). Always one line is set high. When next timer event
-+ * occures the scan data on port A are valid. This makes also sure, that no
-+ * spurious keys are scanned. The kbd int on these CPU's is not deglitched!
-+ * After scanning all columns, we switch back to int mode, if no key is
-+ * pressed. If any is pressed we reschedule the scan within a programmable
-+ * delay. If we would switch back to interrupt mode as long as a key is pressed,
-+ * we come right back to the interrupt, because the int. is level triggered !
-+ * The timer based scan of the seperate columns can also be done in one
-+ * timer event (set fastscan to 1).
-+ *
-+ * Summary:
-+ * The design of this keyboard controller chip is stupid at all !
-+ *
-+ * Matrix translation:
-+ * The matrix translation table is based on standard XT scancodes. Maybe
-+ * you have to adjust the KEYISPRINTABLE macro if you set other codes.
-+ *
-+ * HandyKey:
-+ *
-+ * On small matrix keyboards you don't have enough keys for operation.
-+ * The intention was to implement a operation mode as it's used on handys.
-+ * You can rotate trough four scancode levels and produce e.g. with a 4x3
-+ * matrix 4*3*4 = 48 different keycodes. That's basicly enough for editing
-+ * filenames or things like that. The HandyKey function takes care about
-+ * nonprintable keys like cursors, backspace, del ...
-+ * If a key is pressed and is a printable keycode, the code is put to the
-+ * main keyboard handler and a cursor left is applied. If you press the same
-+ * key again, the current character is deleted and the next level character
-+ * is applied. (e.g. 1, a, b, c, 1 ....). If you press a different key, the
-+ * driver applies cursor right, before processing the new key.
-+ * The autocomplete feature moves the cursor right, if you do not press a
-+ * key within a programmable time.
-+ * If HandyKey is off, the keyboard behaviour is that of a standard keyboard
-+ * HandyKey can be en/disabled from userspace with the proc/keyboard entry
-+ *
-+ * proc/keyboard:
-+ *
-+ * Read access gives back the actual state of the HandyKey function
-+ * h:0 Disabled
-+ * h:1 Enabled
-+ * Write access has two functions. Changing the HandyKey mode and applying
-+ * a different scancode translation table.
-+ * Syntax is: h:0 disable Handykey
-+ * h:1 enabled Handykey
-+ * t:array[256] of bytes Transfer translation table
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/tty.h>
-+#include <linux/tty_flip.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/ptrace.h>
-+#include <linux/signal.h>
-+#include <linux/timer.h>
-+#include <linux/tqueue.h>
-+#include <linux/random.h>
-+#include <linux/ctype.h>
-+#include <linux/init.h>
-+#include <linux/kbd_ll.h>
-+#include <linux/kbd_kern.h>
-+#include <linux/delay.h>
-+#include <linux/proc_fs.h>
-+
-+#include <asm/bitops.h>
-+#include <asm/keyboard.h>
-+#include <asm/irq.h>
-+#include <asm/hardware.h>
-+#include <asm/uaccess.h>
-+
-+#include <asm/io.h>
-+#include <asm/system.h>
-+
-+void clps711x_kbd_init_hw(void);
-+
-+/*
-+ * Values for the keyboard column scan control register.
-+ */
-+#define KBSC_HI 0x0 /* All driven high */
-+#define KBSC_LO 0x1 /* All driven low */
-+#define KBSC_X 0x2 /* All high impedance */
-+#define KBSC_COL0 0x8 /* Column 0 high, others high impedance */
-+#define KBSC_COL1 0x9 /* Column 1 high, others high impedance */
-+#define KBSC_COL2 0xa /* Column 2 high, others high impedance */
-+#define KBSC_COL3 0xb /* Column 3 high, others high impedance */
-+#define KBSC_COL4 0xc /* Column 4 high, others high impedance */
-+#define KBSC_COL5 0xd /* Column 5 high, others high impedance */
-+#define KBSC_COL6 0xe /* Column 6 high, others high impedance */
-+#define KBSC_COL7 0xf /* Column 7 high, others high impedance */
-+
-+/*
-+* Keycodes for cursor left/right and delete (used by HandyKey)
-+*/
-+#define KEYCODE_CLEFT 0x4b
-+#define KEYCODE_CRIGHT 0x4d
-+#define KEYCODE_DEL 0x53
-+#define KEYISPRINTABLE(code) ( (code > 0x01 && code < 0x37 && code != 0x1c \
-+ && code != 0x0e) || code == 0x39)
-+
-+/* Simple translation table for the SysRq keys */
-+#ifdef CONFIG_MAGIC_SYSRQ
-+unsigned char clps711x_kbd_sysrq_xlate[128] =
-+ "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
-+ "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
-+ "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
-+ "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
-+ "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
-+ "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
-+ "\r\000/"; /* 0x60 - 0x6f */
-+#endif
-+
-+/*
-+ * This table maps row/column keyboard matrix positions to XT scancodes.
-+ * It's a default table, which can be overriden by writing to proc/keyboard
-+ */
-+#ifdef CONFIG_ARCH_AUTCPU12
-+static unsigned char autcpu12_scancode[256] =
-+{
-+/* Column:
-+ Row 0 1 2 3 4 5 6 7 */
-+/* A0 */ 0x08, 0x09, 0x0a, 0x0e, 0x05, 0x06, 0x00, 0x00,
-+/* A1 */ 0x07, 0x53, 0x02, 0x03, 0x04, 0x0f, 0x00, 0x00,
-+/* A2 */ 0x0c, 0x0b, 0x33, 0x1c, 0xff, 0x4b, 0x00, 0x00,
-+/* A3 */ 0x48, 0x50, 0x4d, 0x3b, 0x3c, 0x3d, 0x00, 0x00,
-+/* A4 */ 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* A5 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* A6 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* A7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+
-+/* A0 */ 0x1e, 0x20, 0x22, 0x0e, 0x24, 0x32, 0x00, 0x00,
-+/* A1 */ 0x19, 0x53, 0x1f, 0x2f, 0x15, 0x0f, 0x00, 0x00,
-+/* A2 */ 0x0c, 0x39, 0x34, 0x1c, 0xff, 0x4b, 0x00, 0x00,
-+/* A3 */ 0x48, 0x50, 0x4d, 0x3b, 0x3c, 0x3d, 0x00, 0x00,
-+/* A4 */ 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* A5 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* A6 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* A7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+
-+/* A0 */ 0x30, 0x12, 0x23, 0x0e, 0x25, 0x31, 0x00, 0x00,
-+/* A1 */ 0x10, 0x53, 0x14, 0x11, 0x2c, 0x0f, 0x00, 0x00,
-+/* A2 */ 0x0c, 0x0b, 0x27, 0x1c, 0xff, 0x4b, 0x00, 0x00,
-+/* A3 */ 0x48, 0x50, 0x4d, 0x3b, 0x3c, 0x3d, 0x00, 0x00,
-+/* A4 */ 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* A5 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* A6 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* A7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+
-+/* A0 */ 0x2e, 0x21, 0x17, 0x0e, 0x26, 0x18, 0x00, 0x00,
-+/* A1 */ 0x13, 0x53, 0x16, 0x2D, 0x04, 0x0f, 0x00, 0x00,
-+/* A2 */ 0x0c, 0x39, 0x35, 0x1c, 0xff, 0x4b, 0x00, 0x00,
-+/* A3 */ 0x48, 0x50, 0x4d, 0x3b, 0x3c, 0x3d, 0x00, 0x00,
-+/* A4 */ 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* A5 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* A6 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* A7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+};
-+#endif
-+
-+static int keys[8];
-+static int new_keys[8];
-+static int previous_keys[8];
-+
-+static int fastscan;
-+static int scan_interval;
-+static int scan_delay;
-+static int last_column;
-+static int key_is_pressed;
-+
-+static unsigned char *act_scancode;
-+
-+static struct kbd_handy_key {
-+ int ena;
-+ int code;
-+ int shift;
-+ int autocomplete;
-+ unsigned long expires;
-+ unsigned long delay;
-+ unsigned char left;
-+ unsigned char right;
-+ unsigned char del;
-+} khandy;
-+
-+static struct tq_struct kbd_process_task;
-+static struct timer_list clps711x_kbd_timer;
-+static struct timer_list clps711x_kbdhandy_timer;
-+static struct proc_dir_entry *clps711x_keyboard_proc_entry = NULL;
-+
-+/*
-+ * Translate a raw keycode to an XT keyboard scancode.
-+ */
-+static int clps711x_translate(unsigned char scancode, unsigned char *keycode,
-+ char raw_mode)
-+{
-+ *keycode = act_scancode[scancode];
-+ return 1;
-+}
-+
-+/*
-+* Initialize handykey structure
-+* clear code, clear shift
-+* scan scancode for cursor right/left and delete
-+*/
-+static void clps711x_handykey_init(void) {
-+
-+ int i;
-+
-+ khandy.ena = 0;
-+ khandy.code = 0;
-+ khandy.shift = 0;
-+ khandy.autocomplete = 0;
-+ for(i = 0; i < 64; i++) {
-+ switch(act_scancode[i]) {
-+ case KEYCODE_CLEFT: khandy.left = i; break;
-+ case KEYCODE_CRIGHT: khandy.right = i; break;
-+ case KEYCODE_DEL: khandy.del = i; break;
-+ }
-+ }
-+}
-+
-+/*
-+* Check for handy key and process it
-+*/
-+void inline clps711x_checkhandy(int col, int row) {
-+
-+ int scode, down;
-+ unsigned char kcode;
-+
-+ scode = (row<<3) + col;
-+ down = keys[col]>>row & 0x01;
-+ kcode = act_scancode[scode];
-+
-+ if (!khandy.ena) {
-+ if (khandy.code) {
-+ handle_scancode(khandy.right,1);
-+ handle_scancode(khandy.right,0);
-+ }
-+ khandy.code = 0;
-+ khandy.shift = 0;
-+ khandy.autocomplete = 0;
-+ }
-+
-+ if(!kcode)
-+ return;
-+
-+ if (!down || !khandy.ena) {
-+ if (khandy.ena && KEYISPRINTABLE(act_scancode[scode]))
-+ khandy.autocomplete = 1;
-+ else
-+ handle_scancode(scode + khandy.shift, down);
-+ return;
-+ }
-+
-+ khandy.autocomplete = 0;
-+ if (KEYISPRINTABLE(kcode)) {
-+ if (khandy.code) {
-+ if(khandy.code == (scode|0x100)) {
-+ handle_scancode(khandy.del,1);
-+ handle_scancode(khandy.del,0);
-+ khandy.shift = khandy.shift < 3*64 ? khandy.shift + 64 : 0 ;
-+ } else {
-+ handle_scancode(khandy.right,1);
-+ handle_scancode(khandy.right,0);
-+ khandy.shift = 0;
-+ }
-+ }
-+ handle_scancode(scode + khandy.shift, 1);
-+ handle_scancode(scode + khandy.shift, 0);
-+ khandy.code = scode | 0x100;
-+ handle_scancode(khandy.left,1);
-+ handle_scancode(khandy.left,0);
-+ } else {
-+ if (khandy.code) {
-+ khandy.code = 0;
-+ handle_scancode(khandy.right,1);
-+ handle_scancode(khandy.right,0);
-+ }
-+ khandy.shift = 0;
-+ handle_scancode(scode, down);
-+ }
-+}
-+
-+
-+/*
-+ * Process the new key data
-+ */
-+static void clps711x_kbd_process(void* data)
-+{
-+ int col,row,res;
-+
-+ for (col = 0; col < 8; col++) {
-+ if (( res = previous_keys[col] ^ keys[col]) == 0)
-+ continue;
-+ for(row = 0; row < 8; row++) {
-+ if ( ((res >> row) & 0x01) != 0)
-+ clps711x_checkhandy(col,row);
-+ }
-+ }
-+ /* Update the state variables. */
-+ memcpy(previous_keys, keys, 8 * sizeof(int));
-+
-+ /* reschedule, if autocomplete pending */
-+ if (khandy.autocomplete) {
-+ khandy.expires = jiffies + khandy.delay;
-+ mod_timer(&clps711x_kbdhandy_timer,khandy.expires);
-+ }
-+
-+}
-+
-+static char clps711x_unexpected_up(unsigned char scancode)
-+{
-+ return 0200;
-+}
-+
-+/*
-+* Handle timer event, for autocomplete function
-+* Reschedule keyboard process task
-+*/
-+static void clps711x_kbdhandy_timeout(unsigned long data)
-+{
-+ if(khandy.autocomplete) {
-+ khandy.code = 0;
-+ khandy.shift = 0;
-+ khandy.autocomplete = 0;
-+ handle_scancode(khandy.right,1);
-+ handle_scancode(khandy.right,0);
-+ }
-+}
-+
-+/*
-+* Handle timer event, while in pollmode
-+*/
-+static void clps711x_kbd_timeout(unsigned long data)
-+{
-+ int i;
-+ unsigned long flags;
-+ /*
-+ * read bits of actual column or all columns in fastscan-mode
-+ */
-+ for (i = 0; i < 8; i++) {
-+ new_keys[last_column - KBSC_COL0] = clps_readb(PADR) & 0xff;
-+ key_is_pressed |= new_keys[last_column - KBSC_COL0];
-+ last_column = last_column < KBSC_COL7 ? last_column + 1 : KBSC_COL0;
-+ local_irq_save(flags);
-+ clps_writel( (clps_readl(SYSCON1) & ~SYSCON1_KBDSCANMASK)
-+ | last_column, SYSCON1);
-+ local_irq_restore(flags);
-+ /*
-+ * For fastscan, apply a short delay to settle scanlines
-+ * else break and wait for next timeout
-+ */
-+ if (fastscan)
-+ udelay(5);
-+ else
-+ break;
-+ }
-+
-+ if (key_is_pressed)
-+ khandy.autocomplete = 0;
-+
-+ /*
-+ * switch to interupt mode, if all columns scanned and no key pressed
-+ * else reschedule scan
-+ */
-+ if (last_column == KBSC_COL0) {
-+ if (!key_is_pressed) {
-+ local_irq_save(flags);
-+ clps_writel( (clps_readl(SYSCON1) & ~SYSCON1_KBDSCANMASK)
-+ | KBSC_HI, SYSCON1);
-+ local_irq_restore(flags);
-+ clps_writel(0,KBDEOI);
-+ enable_irq(IRQ_KBDINT);
-+ } else {
-+ clps711x_kbd_timer.expires = jiffies + scan_interval;
-+ add_timer(&clps711x_kbd_timer);
-+ }
-+ key_is_pressed = 0;
-+ memcpy(keys, new_keys, 8 * sizeof(int));
-+ for (i = 0; i < 8; i++) {
-+ if (previous_keys[i] != keys[i]) {
-+ queue_task(&kbd_process_task, &tq_timer);
-+ return;
-+ }
-+ }
-+ } else {
-+ clps711x_kbd_timer.expires = jiffies + scan_delay;
-+ add_timer(&clps711x_kbd_timer);
-+ }
-+}
-+
-+/*
-+* Keyboard interrupt, change to scheduling mode
-+*/
-+static void clps711x_kbd_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+
-+#ifdef CONFIG_VT
-+ kbd_pt_regs = regs;
-+#endif
-+ disable_irq(IRQ_KBDINT);
-+ khandy.autocomplete = 0;
-+ clps_writel( (clps_readl(SYSCON1) & ~SYSCON1_KBDSCANMASK)
-+ | KBSC_COL0, SYSCON1);
-+ clps711x_kbd_timer.expires = jiffies + scan_delay;
-+ add_timer(&clps711x_kbd_timer);
-+}
-+
-+
-+static int clps711x_kbd_proc_keyboard_read(char *page, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ if (count < 2)
-+ return -EINVAL;
-+
-+ return sprintf(page,"h:%d\n",khandy.ena);
-+}
-+
-+static int clps711x_kbd_proc_keyboard_write(struct file *file, const char *buffer,
-+ unsigned long count, void *data)
-+{
-+ unsigned char buf[260];
-+
-+ if (count < 3|| count > 258)
-+ return -EINVAL;
-+ if (copy_from_user(buf, buffer, count))
-+ return -EFAULT;
-+ if (buf[1] != ':')
-+ return -EINVAL;
-+
-+ if (buf[0] == 'h') {
-+ switch (buf[2]) {
-+ case '0':
-+ case '1':
-+ case '2': khandy.ena = buf[2]-'0'; return count;
-+ }
-+ }
-+
-+ if (buf[0] == 't' && count == 258) {
-+ memcpy(act_scancode,buf+2,256);
-+ /* rescan cursor left/right and del */
-+ clps711x_handykey_init();
-+ return count;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+
-+/*
-+ * Initialize the keyboard hardware.
-+ * Set all columns high
-+ * Install interrupt handler
-+ *
-+ * Machine dependent parameters:
-+ *
-+ * fastscan: 0 = timer based scan for each column
-+ * 1 = full scan is done in one timer event
-+ * scan_delay: time between column scans
-+ * setup even if you use fastscan (leeds to timer mode)
-+ * scan_interval: time between full scans
-+ * handy.delay: timeout before last entry get's automatically valid
-+ *
-+ */
-+void __init clps711x_kbd_init_hw(void)
-+{
-+
-+ /*
-+ * put here machine dependent init stuff
-+ */
-+ if (machine_is_autcpu12()) {
-+ fastscan = 0;
-+ scan_interval = 50*HZ/1000;
-+ scan_delay = 20*HZ/1000;
-+ khandy.delay = 750*HZ/1000;
-+ act_scancode = autcpu12_scancode;
-+ } else {
-+ printk("No initialization, keyboard killed\n");
-+ return;
-+ }
-+
-+ last_column = KBSC_COL0;
-+ key_is_pressed = 0;
-+
-+ clps711x_handykey_init();
-+
-+ /* Register the /proc entry */
-+ clps711x_keyboard_proc_entry = create_proc_entry("keyboard", 0444,
-+ &proc_root);
-+ if (clps711x_keyboard_proc_entry == NULL)
-+ printk("Couldn't create the /proc entry for the keyboard\n");
-+ else {
-+ clps711x_keyboard_proc_entry->read_proc =
-+ &clps711x_kbd_proc_keyboard_read;
-+ clps711x_keyboard_proc_entry->write_proc =
-+ &clps711x_kbd_proc_keyboard_write;
-+ }
-+
-+ /* Initialize the matrix processing task. */
-+ k_translate = clps711x_translate;
-+ k_unexpected_up = clps711x_unexpected_up;
-+ kbd_process_task.routine = clps711x_kbd_process;
-+ kbd_process_task.data = 0;
-+
-+ /* Setup the timer for keyboard polling, after kbd int */
-+ init_timer(&clps711x_kbd_timer);
-+ clps711x_kbd_timer.function = clps711x_kbd_timeout;
-+ clps711x_kbd_timer.data = 0;
-+ init_timer(&clps711x_kbdhandy_timer);
-+ clps711x_kbdhandy_timer.function = clps711x_kbdhandy_timeout;
-+ clps711x_kbdhandy_timer.data = 1;
-+
-+ /* Initialise scan hardware, request int */
-+ clps_writel( (clps_readl(SYSCON1) & ~SYSCON1_KBDSCANMASK)
-+ | KBSC_HI, SYSCON1);
-+ request_irq(IRQ_KBDINT, clps711x_kbd_int, 0,"keyboard", NULL);
-+
-+ printk("clps711x keyboard init done\n");
-+
-+}
---- linux-2.4.25/drivers/char/console.c~2.4.25-vrs2.patch 2003-11-28 19:26:20.000000000 +0100
-+++ linux-2.4.25/drivers/char/console.c 2004-03-31 17:15:09.000000000 +0200
-@@ -72,8 +72,14 @@
- *
- * Removed console_lock, enabled interrupts across all console operations
- * 13 March 2001, Andrew Morton
-+ *
-+ * Split out con_write_ctrl_* functions from do_con_write & changed
-+ * vc_state to function pointer
-+ * by Russell King <rmk@arm.linux.org.uk>, July 1998
- */
-
-+#define CONSOLE_WIP
-+
- #include <linux/module.h>
- #include <linux/sched.h>
- #include <linux/tty.h>
-@@ -228,7 +234,7 @@
- static inline unsigned short *screenpos(int currcons, int offset, int viewed)
- {
- unsigned short *p;
--
-+
- if (!viewed)
- p = (unsigned short *)(origin + offset);
- else if (!sw->con_screen_pos)
-@@ -729,7 +735,7 @@
- else {
- unsigned short *p = (unsigned short *) kmalloc(ss, GFP_USER);
- if (!p) {
-- for (i = first; i < currcons; i++)
-+ for (i = first; i< currcons; i++)
- if (newscreens[i])
- kfree(newscreens[i]);
- return -ENOMEM;
-@@ -847,7 +853,7 @@
- /* the default colour table, for VGA+ colour systems */
- int default_red[] = {0x00,0xaa,0x00,0xaa,0x00,0xaa,0x00,0xaa,
- 0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};
--int default_grn[] = {0x00,0x00,0xaa,0x55,0x00,0x00,0xaa,0xaa,
-+int default_grn[] = {0x00,0x00,0xaa,0xaa,0x00,0x00,0xaa,0xaa,
- 0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};
- int default_blu[] = {0x00,0x00,0x00,0x00,0xaa,0xaa,0xaa,0xaa,
- 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
-@@ -1393,6 +1399,19 @@
- need_wrap = 0;
- }
-
-+static int con_write_ctrl_ESnormal(int, struct tty_struct *, unsigned int);
-+static int con_write_ctrl_ESesc(int, struct tty_struct *, unsigned int);
-+static int con_write_ctrl_ESnonstd(int, struct tty_struct *, unsigned int);
-+static int con_write_ctrl_ESpalette(int, struct tty_struct *, unsigned int);
-+static int con_write_ctrl_ESsquare(int, struct tty_struct *, unsigned int);
-+static int con_write_ctrl_ESgetpars(int, struct tty_struct *, unsigned int);
-+static int con_write_ctrl_ESgotpars(int, struct tty_struct *, unsigned int);
-+static int con_write_ctrl_ESpercent(int, struct tty_struct *, unsigned int);
-+static int con_write_ctrl_ESfunckey(int, struct tty_struct *, unsigned int);
-+static int con_write_ctrl_EShash(int, struct tty_struct *, unsigned int);
-+static int con_write_ctrl_ESsetG0(int, struct tty_struct *, unsigned int);
-+static int con_write_ctrl_ESsetG1(int, struct tty_struct *, unsigned int);
-+
- enum { ESnormal, ESesc, ESsquare, ESgetpars, ESgotpars, ESfunckey,
- EShash, ESsetG0, ESsetG1, ESpercent, ESignore, ESnonstd,
- ESpalette };
-@@ -1402,7 +1421,7 @@
- {
- top = 0;
- bottom = video_num_lines;
-- vc_state = ESnormal;
-+ vc_state = con_write_ctrl_ESnormal;
- ques = 0;
- translate = set_translate(LAT1_MAP,currcons);
- G0_charset = LAT1_MAP;
-@@ -1500,328 +1519,426 @@
- disp_ctrl = 0;
- return;
- case 24: case 26:
-- vc_state = ESnormal;
-+ vc_state = con_write_ctrl_ESnormal;
- return;
- case 27:
-- vc_state = ESesc;
-+ vc_state = con_write_ctrl_ESesc;
- return;
- case 127:
- del(currcons);
- return;
- case 128+27:
-- vc_state = ESsquare;
-+ vc_state = con_write_ctrl_ESsquare;
- return;
- }
-- switch(vc_state) {
-- case ESesc:
-- vc_state = ESnormal;
-- switch (c) {
-- case '[':
-- vc_state = ESsquare;
-- return;
-- case ']':
-- vc_state = ESnonstd;
-- return;
-- case '%':
-- vc_state = ESpercent;
-- return;
-- case 'E':
-- cr(currcons);
-- lf(currcons);
-- return;
-- case 'M':
-- ri(currcons);
-- return;
-- case 'D':
-- lf(currcons);
-- return;
-- case 'H':
-- tab_stop[x >> 5] |= (1 << (x & 31));
-- return;
-- case 'Z':
-- respond_ID(tty);
-- return;
-- case '7':
-- save_cur(currcons);
-- return;
-- case '8':
-- restore_cur(currcons);
-- return;
-- case '(':
-- vc_state = ESsetG0;
-- return;
-- case ')':
-- vc_state = ESsetG1;
-- return;
-- case '#':
-- vc_state = EShash;
-- return;
-- case 'c':
-- reset_terminal(currcons,1);
-- return;
-- case '>': /* Numeric keypad */
-- clr_kbd(kbdapplic);
-- return;
-- case '=': /* Appl. keypad */
-- set_kbd(kbdapplic);
-- return;
-+ vc_state(currcons, tty, c);
-+}
-+
-+static int con_write_utf(int currcons, int c)
-+{
-+ unsigned int chr;
-+
-+ /* Combine UTF-8 into Unicode */
-+ /* Incomplete characters silently ignored */
-+ if (c < 0x80) {
-+ utf_count = 0;
-+ return c;
-+ }
-+
-+ if (utf_count > 0 && (c & 0xc0) == 0x80) {
-+ chr = (utf_char << 6) | (c & 0x3f);
-+ utf_count--;
-+ if (utf_count == 0)
-+ return chr;
-+ } else {
-+ unsigned int count;
-+ if ((c & 0xe0) == 0xc0) {
-+ count = 1;
-+ chr = (c & 0x1f);
-+ } else if ((c & 0xf0) == 0xe0) {
-+ count = 2;
-+ chr = (c & 0x0f);
-+ } else if ((c & 0xf8) == 0xf0) {
-+ count = 3;
-+ chr = (c & 0x07);
-+ } else if ((c & 0xfc) == 0xf8) {
-+ count = 4;
-+ chr = (c & 0x03);
-+ } else if ((c & 0xfe) == 0xfc) {
-+ count = 5;
-+ chr = (c & 0x01);
-+ } else {
-+ count = 0;
-+ chr = 0;
- }
-- return;
-- case ESnonstd:
-- if (c=='P') { /* palette escape sequence */
-- for (npar=0; npar<NPAR; npar++)
-- par[npar] = 0 ;
-- npar = 0 ;
-- vc_state = ESpalette;
-- return;
-- } else if (c=='R') { /* reset palette */
-- reset_palette(currcons);
-- vc_state = ESnormal;
-- } else
-- vc_state = ESnormal;
-- return;
-- case ESpalette:
-- if ( (c>='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f') ) {
-- par[npar++] = (c>'9' ? (c&0xDF)-'A'+10 : c-'0') ;
-- if (npar==7) {
-- int i = par[0]*3, j = 1;
-- palette[i] = 16*par[j++];
-- palette[i++] += par[j++];
-- palette[i] = 16*par[j++];
-- palette[i++] += par[j++];
-- palette[i] = 16*par[j++];
-- palette[i] += par[j];
-- set_palette(currcons);
-- vc_state = ESnormal;
-- }
-- } else
-- vc_state = ESnormal;
-- return;
-- case ESsquare:
-- for(npar = 0 ; npar < NPAR ; npar++)
-- par[npar] = 0;
-- npar = 0;
-- vc_state = ESgetpars;
-- if (c == '[') { /* Function key */
-- vc_state=ESfunckey;
-- return;
-+ utf_count = count;
-+ }
-+
-+ utf_char = chr;
-+ return -1;
-+}
-+
-+static int con_write_ctrl_ESnormal(int currcons, struct tty_struct *tty, unsigned int c)
-+{
-+ return 0;
-+}
-+
-+static int con_write_ctrl_ESesc(int currcons, struct tty_struct *tty, unsigned int c)
-+{
-+ vc_state = con_write_ctrl_ESnormal;
-+ switch (c) {
-+ case '[':
-+ vc_state = con_write_ctrl_ESsquare;
-+ break;
-+ case ']':
-+ vc_state = con_write_ctrl_ESnonstd;
-+ break;
-+ case '%':
-+ vc_state = con_write_ctrl_ESpercent;
-+ break;
-+ case 'E':
-+ cr(currcons);
-+ lf(currcons);
-+ break;
-+ case 'M':
-+ ri(currcons);
-+ break;
-+ case 'D':
-+ lf(currcons);
-+ break;
-+ case 'H':
-+ tab_stop[x >> 5] |= (1 << (x & 31));
-+ break;
-+ case 'Z':
-+ respond_ID(tty);
-+ break;
-+ case '7':
-+ save_cur(currcons);
-+ break;
-+ case '8':
-+ restore_cur(currcons);
-+ return 1;
-+ case '(':
-+ vc_state = con_write_ctrl_ESsetG0;
-+ break;
-+ case ')':
-+ vc_state = con_write_ctrl_ESsetG1;
-+ break;
-+ case '#':
-+ vc_state = con_write_ctrl_EShash;
-+ break;
-+ case 'c':
-+ reset_terminal(currcons,1);
-+ return 1;
-+ case '>': /* Numeric keypad */
-+ clr_kbd(kbdapplic);
-+ break;
-+ case '=': /* Appl. keypad */
-+ set_kbd(kbdapplic);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static int con_write_ctrl_ESnonstd(int currcons, struct tty_struct *tty, unsigned int c)
-+{
-+ switch (c) {
-+ case 'P': /* palette escape sequence */
-+ for (npar=0; npar<NPAR; npar++)
-+ par[npar] = 0 ;
-+ npar = 0 ;
-+ vc_state = con_write_ctrl_ESpalette;
-+ break;
-+ case 'R': /* reset palette */
-+ reset_palette (currcons);
-+ default:
-+ vc_state = con_write_ctrl_ESnormal;
-+ }
-+ return 0;
-+}
-+
-+static int con_write_ctrl_ESpalette(int currcons, struct tty_struct *tty, unsigned int c)
-+{
-+ if ( (c>='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f') ) {
-+ par[npar++] = (c>'9' ? (c&0xDF)-'A'+10 : c-'0') ;
-+ if (npar==7) {
-+ int i = par[0]*3, j = 1;
-+ palette[i] = 16*par[j++];
-+ palette[i++] += par[j++];
-+ palette[i] = 16*par[j++];
-+ palette[i++] += par[j++];
-+ palette[i] = 16*par[j++];
-+ palette[i] += par[j];
-+ set_palette(currcons);
-+ vc_state = con_write_ctrl_ESnormal;
- }
-- ques = (c=='?');
-- if (ques)
-- return;
-- case ESgetpars:
-- if (c==';' && npar<NPAR-1) {
-- npar++;
-- return;
-- } else if (c>='0' && c<='9') {
-- par[npar] *= 10;
-- par[npar] += c-'0';
-- return;
-- } else vc_state=ESgotpars;
-- case ESgotpars:
-- vc_state = ESnormal;
-- switch(c) {
-- case 'h':
-- set_mode(currcons,1);
-- return;
-- case 'l':
-- set_mode(currcons,0);
-- return;
-- case 'c':
-- if (ques) {
-- if (par[0])
-- cursor_type = par[0] | (par[1]<<8) | (par[2]<<16);
-- else
-- cursor_type = CUR_DEFAULT;
-- return;
-- }
-- break;
-- case 'm':
-- if (ques) {
-- clear_selection();
-- if (par[0])
-- complement_mask = par[0]<<8 | par[1];
-- else
-- complement_mask = s_complement_mask;
-- return;
-- }
-- break;
-- case 'n':
-- if (!ques) {
-- if (par[0] == 5)
-- status_report(tty);
-- else if (par[0] == 6)
-- cursor_report(currcons,tty);
-- }
-- return;
-+ } else
-+ vc_state = con_write_ctrl_ESnormal;
-+ return 0;
-+}
-+
-+static int con_write_ctrl_ESsquare(int currcons, struct tty_struct *tty, unsigned int c)
-+{
-+ for(npar = 0 ; npar < NPAR ; npar++)
-+ par[npar] = 0;
-+ npar = 0;
-+ vc_state = con_write_ctrl_ESgetpars;
-+ if (c == '[') { /* Function key */
-+ vc_state = con_write_ctrl_ESfunckey;
-+ return 0;
-+ }
-+ ques = (c=='?');
-+ if (ques)
-+ return 0;
-+ return con_write_ctrl_ESgetpars(currcons, tty, c);
-+}
-+
-+static int con_write_ctrl_ESgetpars(int currcons, struct tty_struct *tty, unsigned int c)
-+{
-+ if (c==';' && npar<NPAR-1) {
-+ npar++;
-+ return 0;
-+ } else if (c>='0' && c<='9') {
-+ par[npar] *= 10;
-+ par[npar] += c-'0';
-+ return 0;
-+ } else vc_state = con_write_ctrl_ESgotpars;
-+ return con_write_ctrl_ESgotpars(currcons, tty, c);
-+}
-+
-+static int con_write_ctrl_ESgotpars(int currcons, struct tty_struct *tty, unsigned int c)
-+{
-+ vc_state = con_write_ctrl_ESnormal;
-+ switch(c) {
-+ case 'h':
-+ set_mode(currcons,1);
-+ return 0;
-+ case 'l':
-+ set_mode(currcons,0);
-+ return 0;
-+ case 'c':
-+ if (ques) {
-+ if (par[0])
-+ cursor_type = par[0] | (par[1]<<8) | (par[2]<<16);
-+ else
-+ cursor_type = CUR_DEFAULT;
-+ return 0;
- }
-+ break;
-+ case 'm':
- if (ques) {
-- ques = 0;
-- return;
-+ clear_selection();
-+ if (par[0])
-+ complement_mask = par[0]<<8 | par[1];
-+ else
-+ complement_mask = s_complement_mask;
-+ return 0;
- }
-- switch(c) {
-- case 'G': case '`':
-- if (par[0]) par[0]--;
-- gotoxy(currcons,par[0],y);
-- return;
-- case 'A':
-- if (!par[0]) par[0]++;
-- gotoxy(currcons,x,y-par[0]);
-- return;
-- case 'B': case 'e':
-- if (!par[0]) par[0]++;
-- gotoxy(currcons,x,y+par[0]);
-- return;
-- case 'C': case 'a':
-- if (!par[0]) par[0]++;
-- gotoxy(currcons,x+par[0],y);
-- return;
-- case 'D':
-- if (!par[0]) par[0]++;
-- gotoxy(currcons,x-par[0],y);
-- return;
-- case 'E':
-- if (!par[0]) par[0]++;
-- gotoxy(currcons,0,y+par[0]);
-- return;
-- case 'F':
-- if (!par[0]) par[0]++;
-- gotoxy(currcons,0,y-par[0]);
-- return;
-- case 'd':
-- if (par[0]) par[0]--;
-- gotoxay(currcons,x,par[0]);
-- return;
-- case 'H': case 'f':
-- if (par[0]) par[0]--;
-- if (par[1]) par[1]--;
-- gotoxay(currcons,par[1],par[0]);
-- return;
-- case 'J':
-- csi_J(currcons,par[0]);
-- return;
-- case 'K':
-- csi_K(currcons,par[0]);
-- return;
-- case 'L':
-- csi_L(currcons,par[0]);
-- return;
-- case 'M':
-- csi_M(currcons,par[0]);
-- return;
-- case 'P':
-- csi_P(currcons,par[0]);
-- return;
-- case 'c':
-- if (!par[0])
-- respond_ID(tty);
-- return;
-- case 'g':
-- if (!par[0])
-- tab_stop[x >> 5] &= ~(1 << (x & 31));
-- else if (par[0] == 3) {
-- tab_stop[0] =
-- tab_stop[1] =
-- tab_stop[2] =
-- tab_stop[3] =
-- tab_stop[4] = 0;
-- }
-- return;
-- case 'm':
-- csi_m(currcons);
-- return;
-- case 'q': /* DECLL - but only 3 leds */
-- /* map 0,1,2,3 to 0,1,2,4 */
-- if (par[0] < 4)
-- setledstate(kbd_table + currcons,
-- (par[0] < 3) ? par[0] : 4);
-- return;
-- case 'r':
-- if (!par[0])
-- par[0]++;
-- if (!par[1])
-- par[1] = video_num_lines;
-- /* Minimum allowed region is 2 lines */
-- if (par[0] < par[1] &&
-- par[1] <= video_num_lines) {
-- top=par[0]-1;
-- bottom=par[1];
-- gotoxay(currcons,0,0);
-- }
-- return;
-- case 's':
-- save_cur(currcons);
-- return;
-- case 'u':
-- restore_cur(currcons);
-- return;
-- case 'X':
-- csi_X(currcons, par[0]);
-- return;
-- case '@':
-- csi_at(currcons,par[0]);
-- return;
-- case ']': /* setterm functions */
-- setterm_command(currcons);
-- return;
-+ break;
-+ case 'n':
-+ if (!ques) {
-+ if (par[0] == 5)
-+ status_report(tty);
-+ else if (par[0] == 6)
-+ cursor_report(currcons,tty);
- }
-- return;
-- case ESpercent:
-- vc_state = ESnormal;
-- switch (c) {
-- case '@': /* defined in ISO 2022 */
-- utf = 0;
-- return;
-- case 'G': /* prelim official escape code */
-- case '8': /* retained for compatibility */
-- utf = 1;
-- return;
-+ return 0;
-+ }
-+ if (ques) {
-+ ques = 0;
-+ return 0;
-+ }
-+ switch(c) {
-+ case 'G': case '`':
-+ if (par[0]) par[0]--;
-+ gotoxy(currcons,par[0],y);
-+ break;
-+ case 'A':
-+ if (!par[0]) par[0]++;
-+ gotoxy(currcons,x,y-par[0]);
-+ break;
-+ case 'B': case 'e':
-+ if (!par[0]) par[0]++;
-+ gotoxy(currcons,x,y+par[0]);
-+ break;
-+ case 'C': case 'a':
-+ if (!par[0]) par[0]++;
-+ gotoxy(currcons,x+par[0],y);
-+ break;
-+ case 'D':
-+ if (!par[0]) par[0]++;
-+ gotoxy(currcons,x-par[0],y);
-+ break;
-+ case 'E':
-+ if (!par[0]) par[0]++;
-+ gotoxy(currcons,0,y+par[0]);
-+ break;
-+ case 'F':
-+ if (!par[0]) par[0]++;
-+ gotoxy(currcons,0,y-par[0]);
-+ break;
-+ case 'd':
-+ if (par[0]) par[0]--;
-+ gotoxay(currcons,x,par[0]);
-+ break;
-+ case 'H': case 'f':
-+ if (par[0]) par[0]--;
-+ if (par[1]) par[1]--;
-+ gotoxay(currcons,par[1],par[0]);
-+ break;
-+ case 'J':
-+ csi_J(currcons,par[0]);
-+ break;
-+ case 'K':
-+ csi_K(currcons,par[0]);
-+ break;
-+ case 'L':
-+ csi_L(currcons,par[0]);
-+ break;
-+ case 'M':
-+ csi_M(currcons,par[0]);
-+ break;
-+ case 'P':
-+ csi_P(currcons,par[0]);
-+ break;
-+ case 'c':
-+ if (!par[0])
-+ respond_ID(tty);
-+ break;
-+ case 'g':
-+ if (!par[0])
-+ tab_stop[x >> 5] &= ~(1 << (x & 31));
-+ else if (par[0] == 3) {
-+ tab_stop[0] =
-+ tab_stop[1] =
-+ tab_stop[2] =
-+ tab_stop[3] =
-+ tab_stop[4] = 0;
- }
-- return;
-- case ESfunckey:
-- vc_state = ESnormal;
-- return;
-- case EShash:
-- vc_state = ESnormal;
-- if (c == '8') {
-- /* DEC screen alignment test. kludge :-) */
-- video_erase_char =
-- (video_erase_char & 0xff00) | 'E';
-- csi_J(currcons, 2);
-- video_erase_char =
-- (video_erase_char & 0xff00) | ' ';
-- do_update_region(currcons, origin, screenbuf_size/2);
-+ break;
-+ case 'm':
-+ csi_m(currcons);
-+ return 1;
-+ case 'q': /* DECLL - but only 3 leds */
-+ /* map 0,1,2,3 to 0,1,2,4 */
-+ if (par[0] < 4)
-+ setledstate(kbd_table + currcons,
-+ (par[0] < 3) ? par[0] : 4);
-+ break;
-+ case 'r':
-+ if (!par[0])
-+ par[0]++;
-+ if (!par[1])
-+ par[1] = video_num_lines;
-+ /* Minimum allowed region is 2 lines */
-+ if (par[0] < par[1] &&
-+ par[1] <= video_num_lines) {
-+ top=par[0]-1;
-+ bottom=par[1];
-+ gotoxay(currcons,0,0);
- }
-- return;
-- case ESsetG0:
-- if (c == '0')
-- G0_charset = GRAF_MAP;
-- else if (c == 'B')
-- G0_charset = LAT1_MAP;
-- else if (c == 'U')
-- G0_charset = IBMPC_MAP;
-- else if (c == 'K')
-- G0_charset = USER_MAP;
-- if (charset == 0)
-- translate = set_translate(G0_charset,currcons);
-- vc_state = ESnormal;
-- return;
-- case ESsetG1:
-- if (c == '0')
-- G1_charset = GRAF_MAP;
-- else if (c == 'B')
-- G1_charset = LAT1_MAP;
-- else if (c == 'U')
-- G1_charset = IBMPC_MAP;
-- else if (c == 'K')
-- G1_charset = USER_MAP;
-- if (charset == 1)
-- translate = set_translate(G1_charset,currcons);
-- vc_state = ESnormal;
-- return;
-- default:
-- vc_state = ESnormal;
-+ break;
-+ case 's':
-+ save_cur(currcons);
-+ break;
-+ case 'u':
-+ restore_cur(currcons);
-+ return 1;
-+ case 'X':
-+ csi_X(currcons, par[0]);
-+ break;
-+ case '@':
-+ csi_at(currcons,par[0]);
-+ break;
-+ case ']': /* setterm functions */
-+ setterm_command(currcons);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static int con_write_ctrl_ESpercent(int currcons, struct tty_struct *tty, unsigned int c)
-+{
-+ vc_state = con_write_ctrl_ESnormal;
-+ switch (c) {
-+ case '@': /* defined in ISO 2022 */
-+ utf = 0;
-+ break;
-+ case 'G': /* prelim official escape code */
-+ case '8': /* retained for compatibility */
-+ utf = 1;
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static int con_write_ctrl_ESfunckey(int currcons, struct tty_struct *tty, unsigned int c)
-+{
-+ vc_state = con_write_ctrl_ESnormal;
-+ return 0;
-+}
-+
-+static int con_write_ctrl_EShash(int currcons, struct tty_struct *tty, unsigned int c)
-+{
-+ vc_state = con_write_ctrl_ESnormal;
-+ if (c == '8') {
-+ /* DEC screen alignment test. kludge :-) */
-+ video_erase_char =
-+ (video_erase_char & 0xff00) | 'E';
-+ csi_J(currcons, 2);
-+ video_erase_char =
-+ (video_erase_char & 0xff00) | ' ';
-+ do_update_region(currcons, origin, screenbuf_size/2);
-+ }
-+ return 0;
-+}
-+
-+static int con_write_ctrl_ESsetG0(int currcons, struct tty_struct *tty, unsigned int c)
-+{
-+ switch (c) {
-+ case '0':
-+ G0_charset = GRAF_MAP;
-+ break;
-+ case 'B':
-+ G0_charset = LAT1_MAP;
-+ break;
-+ case 'U':
-+ G0_charset = IBMPC_MAP;
-+ break;
-+ case 'K':
-+ G0_charset = USER_MAP;
-+ break;
-+ }
-+ if (charset == 0) {
-+ translate = set_translate(G0_charset,currcons);
-+ return 1;
-+ }
-+ vc_state = con_write_ctrl_ESnormal;
-+ return 0;
-+}
-+
-+static int con_write_ctrl_ESsetG1(int currcons, struct tty_struct *tty, unsigned int c)
-+{
-+ switch (c) {
-+ case '0':
-+ G1_charset = GRAF_MAP;
-+ break;
-+ case 'B':
-+ G1_charset = LAT1_MAP;
-+ break;
-+ case 'U':
-+ G1_charset = IBMPC_MAP;
-+ break;
-+ case 'K':
-+ G1_charset = USER_MAP;
-+ break;
-+ }
-+ if (charset == 1) {
-+ translate = set_translate(G1_charset,currcons);
-+ return 1;
- }
-+ vc_state = con_write_ctrl_ESnormal;
-+ return 0;
- }
-
- /* This is a temporary buffer used to prepare a tty console write
-@@ -1855,7 +1972,7 @@
- unsigned long draw_from = 0, draw_to = 0;
- struct vt_struct *vt = (struct vt_struct *)tty->driver_data;
- u16 himask, charmask;
-- const unsigned char *orig_buf = NULL;
-+ const unsigned char *orig_buf;
- int orig_count;
-
- if (in_interrupt())
-@@ -1913,42 +2030,12 @@
- count--;
-
- if (utf) {
-- /* Combine UTF-8 into Unicode */
-- /* Incomplete characters silently ignored */
-- if(c > 0x7f) {
-- if (utf_count > 0 && (c & 0xc0) == 0x80) {
-- utf_char = (utf_char << 6) | (c & 0x3f);
-- utf_count--;
-- if (utf_count == 0)
-- tc = c = utf_char;
-- else continue;
-- } else {
-- if ((c & 0xe0) == 0xc0) {
-- utf_count = 1;
-- utf_char = (c & 0x1f);
-- } else if ((c & 0xf0) == 0xe0) {
-- utf_count = 2;
-- utf_char = (c & 0x0f);
-- } else if ((c & 0xf8) == 0xf0) {
-- utf_count = 3;
-- utf_char = (c & 0x07);
-- } else if ((c & 0xfc) == 0xf8) {
-- utf_count = 4;
-- utf_char = (c & 0x03);
-- } else if ((c & 0xfe) == 0xfc) {
-- utf_count = 5;
-- utf_char = (c & 0x01);
-- } else
-- utf_count = 0;
-+ tc = con_write_utf(currcons, c);
-+ if (tc < 0)
- continue;
-- }
-- } else {
-- tc = c;
-- utf_count = 0;
-- }
-- } else { /* no utf */
-- tc = translate[toggle_meta ? (c|0x80) : c];
-- }
-+ c = tc;
-+ } else /* no utf */
-+ tc = translate[toggle_meta ? (c|0x80) : c];
-
- /* If the original code was a control character we
- * only allow a glyph to be displayed if the code is
-@@ -1966,7 +2053,7 @@
- && (c != 127 || disp_ctrl)
- && (c != 128+27);
-
-- if (vc_state == ESnormal && ok) {
-+ if (vc_state == con_write_ctrl_ESnormal && ok) {
- /* Now try to find out how to display it */
- tc = conv_uni_to_pc(vc_cons[currcons].d, tc);
- if ( tc == -4 ) {
-@@ -2112,7 +2199,7 @@
- if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1))
- currcons = kmsg_redirect - 1;
-
-- /* read `x' only after setting currecons properly (otherwise
-+ /* read `x' only after setting currcons properly (otherwise
- the `x' macro will read the x of the foreground console). */
- myx = x;
-
-@@ -2475,8 +2562,8 @@
- console_driver.init_termios = tty_std_termios;
- console_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
- /* Tell tty_register_driver() to skip consoles because they are
-- * registered before kmalloc() is ready. We'll patch them in later.
-- * See comments at console_init(); see also con_init_devfs().
-+ * registered before kmalloc() is ready. We'll patch them in later.
-+ * See comments at console_init(); see also con_init_devfs().
- */
- console_driver.flags |= TTY_DRIVER_NO_DEVFS;
- console_driver.refcount = &console_refcount;
-@@ -2719,7 +2806,7 @@
-
- if (console_blank_hook && console_blank_hook(1))
- return;
-- if (vesa_blank_mode)
-+ if (vesa_blank_mode)
- sw->con_blank(vc_cons[currcons].d, vesa_blank_mode + 1);
- }
-
-@@ -2893,7 +2980,7 @@
- if (!op->height) { /* Need to guess font height [compat] */
- int h, i;
- u8 *charmap = op->data, tmp;
--
-+
- /* If from KDFONTOP ioctl, don't allow things which can be done in userland,
- so that we can get rid of this soon */
- if (!(op->flags & KD_FONT_FLAG_OLD))
-@@ -2940,18 +3027,18 @@
- op->data = old_op.data;
- if (!rc && !set) {
- int c = (op->width+7)/8 * 32 * op->charcount;
--
-+
- if (op->data && op->charcount > old_op.charcount)
- rc = -ENOSPC;
- if (!(op->flags & KD_FONT_FLAG_OLD)) {
-- if (op->width > old_op.width ||
-+ if (op->width > old_op.width ||
- op->height > old_op.height)
- rc = -ENOSPC;
- } else {
- if (op->width != 8)
- rc = -EIO;
- else if ((old_op.height && op->height > old_op.height) ||
-- op->height > 32)
-+ op->height > 32)
- rc = -ENOSPC;
- }
- if (!rc && op->data && copy_to_user(op->data, temp, c))
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/ds1307.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,604 @@
-+/*
-+ * ds1307.c
-+ *
-+ * Device driver for Dallas Semiconductor's Real Time Controller DS1307.
-+ *
-+ * Copyright (C) 2002 Intrinsyc Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/version.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/poll.h>
-+#include <linux/i2c.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/rtc.h>
-+#include <linux/string.h>
-+#include <linux/miscdevice.h>
-+#include <linux/proc_fs.h>
-+
-+#include "ds1307.h"
-+
-+#define DEBUG 0
-+
-+#if DEBUG
-+static unsigned int rtc_debug = DEBUG;
-+#else
-+#define rtc_debug 0 /* gcc will remove all the debug code for us */
-+#endif
-+
-+static unsigned short slave_address = DS1307_I2C_SLAVE_ADDR;
-+
-+struct i2c_driver ds1307_driver;
-+struct i2c_client *ds1307_i2c_client = 0;
-+
-+static unsigned short ignore[] = { I2C_CLIENT_END };
-+static unsigned short normal_addr[] = { DS1307_I2C_SLAVE_ADDR, I2C_CLIENT_END };
-+
-+static struct i2c_client_address_data addr_data = {
-+ normal_i2c: normal_addr,
-+ normal_i2c_range: ignore,
-+ probe: ignore,
-+ probe_range: ignore,
-+ ignore: ignore,
-+ ignore_range: ignore,
-+ force: ignore,
-+};
-+
-+static int ds1307_rtc_ioctl( struct inode *, struct file *, unsigned int, unsigned long);
-+static int ds1307_rtc_open(struct inode *inode, struct file *file);
-+static int ds1307_rtc_release(struct inode *inode, struct file *file);
-+
-+static struct file_operations rtc_fops = {
-+ owner: THIS_MODULE,
-+ ioctl: ds1307_rtc_ioctl,
-+ open: ds1307_rtc_open,
-+ release: ds1307_rtc_release,
-+};
-+
-+static struct miscdevice ds1307_rtc_miscdev = {
-+ RTC_MINOR,
-+ "rtc",
-+ &rtc_fops
-+};
-+
-+static int ds1307_probe(struct i2c_adapter *adap);
-+static int ds1307_detach(struct i2c_client *client);
-+static int ds1307_command(struct i2c_client *client, unsigned int cmd, void *arg);
-+
-+struct i2c_driver ds1307_driver = {
-+ name: "DS1307",
-+ id: I2C_DRIVERID_DS1307,
-+ flags: I2C_DF_NOTIFY,
-+ attach_adapter: ds1307_probe,
-+ detach_client: ds1307_detach,
-+ command: ds1307_command
-+};
-+
-+static spinlock_t ds1307_rtc_lock = SPIN_LOCK_UNLOCKED;
-+
-+#define DAT(x) ((unsigned int)((x)->data)) /* keep the control register info */
-+
-+static int
-+ds1307_readram( char *buf, int len)
-+{
-+ unsigned long flags;
-+ unsigned char ad[1] = { 0 };
-+ int ret;
-+ struct i2c_msg msgs[2] = {
-+ { ds1307_i2c_client->addr , 0, 1, ad },
-+ { ds1307_i2c_client->addr , I2C_M_RD, len, buf } };
-+
-+ spin_lock_irqsave(&ds1307_rtc_lock, flags);
-+ ret = i2c_transfer(ds1307_i2c_client->adapter, msgs, 2);
-+ spin_unlock_irqrestore(&ds1307_rtc_lock,flags);
-+
-+ return ret;
-+}
-+
-+static void
-+ds1307_dumpram( void)
-+{
-+ unsigned char buf[DS1307_RAM_SIZE];
-+ int ret;
-+
-+ ret = ds1307_readram( buf, DS1307_RAM_SIZE);
-+
-+ if( ret > 0)
-+ {
-+ int i;
-+ for( i=0; i<DS1307_RAM_SIZE; i++)
-+ {
-+ printk ("%02X ", buf[i]);
-+ if( (i%8) == 7) printk ("\n");
-+ }
-+ printk ("\n");
-+ }
-+}
-+
-+static void
-+ds1307_enable_clock( int enable)
-+{
-+ unsigned char buf[2], ad[1] = { 0 };
-+ struct i2c_msg msgs[2] = {
-+ { ds1307_i2c_client->addr , 0, 1, ad },
-+ { ds1307_i2c_client->addr , I2C_M_RD, 1, buf }
-+ };
-+ unsigned char ctrl_info;
-+ int ret;
-+
-+ if( enable)
-+ ctrl_info = SQW_ENABLE | RATE_32768HZ;
-+ else
-+ ctrl_info = SQW_DISABLE;
-+ ds1307_command(ds1307_i2c_client, DS1307_SETCTRL, &ctrl_info);
-+
-+ /* read addr 0 (Clock-Halt bit and second counter */
-+ ret = i2c_transfer(ds1307_i2c_client->adapter, msgs, 2);
-+
-+ if( enable)
-+ buf[1] = buf[0] & ~CLOCK_HALT; /* clear Clock-Halt bit */
-+ else
-+ buf[1] = buf[0] | CLOCK_HALT; /* set Clock-Halt bit */
-+ buf[0] = 0; /* control register address on DS1307 */
-+
-+ ret = i2c_master_send(ds1307_i2c_client, (char *)buf, 2);
-+}
-+
-+static int
-+ds1307_attach(struct i2c_adapter *adap, int addr, unsigned short flags,int kind)
-+{
-+ struct i2c_client *c;
-+ unsigned char buf[1], ad[1] = { 7 };
-+ struct i2c_msg msgs[2] = {
-+ { addr , 0, 1, ad },
-+ { addr , I2C_M_RD, 1, buf }
-+ };
-+ int ret;
-+
-+ c = (struct i2c_client *)kmalloc(sizeof(*c), GFP_KERNEL);
-+ if (!c)
-+ return -ENOMEM;
-+
-+ strcpy(c->name, "DS1307");
-+ c->id = ds1307_driver.id;
-+ c->flags = 0;
-+ c->addr = addr;
-+ c->adapter = adap;
-+ c->driver = &ds1307_driver;
-+ c->data = NULL;
-+
-+ ret = i2c_transfer(c->adapter, msgs, 2);
-+
-+ if ( ret == 2 )
-+ {
-+ DAT(c) = buf[0];
-+ }
-+ else
-+ printk ("ds1307_attach(): i2c_transfer() returned %d.\n",ret);
-+
-+ ds1307_i2c_client = c;
-+ ds1307_enable_clock( 1);
-+
-+ return i2c_attach_client(c);
-+}
-+
-+static int
-+ds1307_probe(struct i2c_adapter *adap)
-+{
-+ return i2c_probe(adap, &addr_data, ds1307_attach);
-+}
-+
-+static int
-+ds1307_detach(struct i2c_client *client)
-+{
-+ i2c_detach_client(client);
-+ ds1307_enable_clock( 0);
-+
-+ return 0;
-+}
-+
-+static void
-+ds1307_convert_to_time( struct rtc_time *dt, char *buf)
-+{
-+ dt->tm_sec = BCD_TO_BIN(buf[0]);
-+ dt->tm_min = BCD_TO_BIN(buf[1]);
-+
-+ if ( TWELVE_HOUR_MODE(buf[2]) )
-+ {
-+ dt->tm_hour = HOURS_12(buf[2]);
-+ if (HOURS_AP(buf[2])) /* PM */
-+ {
-+ dt->tm_hour += 12;
-+ }
-+ }
-+ else /* 24-hour-mode */
-+ {
-+ dt->tm_hour = HOURS_24(buf[2]);
-+ }
-+
-+ dt->tm_mday = BCD_TO_BIN(buf[4]);
-+ /* dt->tm_mon is zero-based */
-+ dt->tm_mon = BCD_TO_BIN(buf[5]) - 1;
-+ /* year is 1900 + dt->tm_year */
-+ dt->tm_year = BCD_TO_BIN(buf[6]) + 100;
-+
-+ if( rtc_debug > 2)
-+ {
-+ printk("ds1307_get_datetime: year = %d\n", dt->tm_year);
-+ printk("ds1307_get_datetime: mon = %d\n", dt->tm_mon);
-+ printk("ds1307_get_datetime: mday = %d\n", dt->tm_mday);
-+ printk("ds1307_get_datetime: hour = %d\n", dt->tm_hour);
-+ printk("ds1307_get_datetime: min = %d\n", dt->tm_min);
-+ printk("ds1307_get_datetime: sec = %d\n", dt->tm_sec);
-+ }
-+}
-+
-+static int
-+ds1307_get_datetime(struct i2c_client *client, struct rtc_time *dt)
-+{
-+ unsigned char buf[7], addr[1] = { 0 };
-+ struct i2c_msg msgs[2] = {
-+ { client->addr, 0, 1, addr },
-+ { client->addr, I2C_M_RD, 7, buf }
-+ };
-+ int ret = -EIO;
-+
-+ memset(buf, 0, sizeof(buf));
-+
-+ ret = i2c_transfer(client->adapter, msgs, 2);
-+
-+ if (ret == 2) {
-+ ds1307_convert_to_time( dt, buf);
-+ ret = 0;
-+ }
-+ else
-+ printk("ds1307_get_datetime(), i2c_transfer() returned %d\n",ret);
-+
-+ return ret;
-+}
-+
-+static int
-+ds1307_set_datetime(struct i2c_client *client, struct rtc_time *dt, int datetoo)
-+{
-+ unsigned char buf[8];
-+ int ret, len = 4;
-+
-+ if( rtc_debug > 2)
-+ {
-+ printk("ds1307_set_datetime: tm_year = %d\n", dt->tm_year);
-+ printk("ds1307_set_datetime: tm_mon = %d\n", dt->tm_mon);
-+ printk("ds1307_set_datetime: tm_mday = %d\n", dt->tm_mday);
-+ printk("ds1307_set_datetime: tm_hour = %d\n", dt->tm_hour);
-+ printk("ds1307_set_datetime: tm_min = %d\n", dt->tm_min);
-+ printk("ds1307_set_datetime: tm_sec = %d\n", dt->tm_sec);
-+ }
-+
-+ buf[0] = 0; /* register address on DS1307 */
-+ buf[1] = (BIN_TO_BCD(dt->tm_sec));
-+ buf[2] = (BIN_TO_BCD(dt->tm_min));
-+ buf[3] = (BIN_TO_BCD(dt->tm_hour));
-+
-+ if (datetoo) {
-+ len = 8;
-+ /* we skip buf[4] as we don't use day-of-week. */
-+ buf[5] = (BIN_TO_BCD(dt->tm_mday));
-+ buf[6] = (BIN_TO_BCD(dt->tm_mon + 1));
-+ /* The year only ranges from 0-99, we are being passed an offset from 1900,
-+ * and the chip calulates leap years based on 2000, thus we adjust by 100.
-+ */
-+ buf[7] = (BIN_TO_BCD(dt->tm_year - 100));
-+ }
-+ ret = i2c_master_send(client, (char *)buf, len);
-+ if (ret == len)
-+ ret = 0;
-+ else
-+ printk("ds1307_set_datetime(), i2c_master_send() returned %d\n",ret);
-+
-+
-+ return ret;
-+}
-+
-+static int
-+ds1307_get_ctrl(struct i2c_client *client, unsigned char *ctrl)
-+{
-+ *ctrl = DAT(client);
-+
-+ return 0;
-+}
-+
-+static int
-+ds1307_set_ctrl(struct i2c_client *client, unsigned char *cinfo)
-+{
-+ unsigned char buf[2];
-+ int ret;
-+
-+
-+ buf[0] = 7; /* control register address on DS1307 */
-+ buf[1] = *cinfo;
-+ /* save the control reg info in the client data field so that get_ctrl
-+ * function doesn't have to do an I2C transfer to get it.
-+ */
-+ DAT(client) = buf[1];
-+
-+ ret = i2c_master_send(client, (char *)buf, 2);
-+
-+ return ret;
-+}
-+
-+static int
-+ds1307_read_mem(struct i2c_client *client, struct rtc_mem *mem)
-+{
-+ unsigned char addr[1];
-+ struct i2c_msg msgs[2] = {
-+ { client->addr, 0, 1, addr },
-+ { client->addr, I2C_M_RD, mem->nr, mem->data }
-+ };
-+
-+ if ( (mem->loc < DS1307_RAM_ADDR_START) ||
-+ ((mem->loc + mem->nr -1) > DS1307_RAM_ADDR_END) )
-+ return -EINVAL;
-+
-+ addr[0] = mem->loc;
-+
-+ return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
-+}
-+
-+static int
-+ds1307_write_mem(struct i2c_client *client, struct rtc_mem *mem)
-+{
-+ unsigned char addr[1];
-+ struct i2c_msg msgs[2] = {
-+ { client->addr, 0, 1, addr },
-+ { client->addr, 0, mem->nr, mem->data }
-+ };
-+
-+ if ( (mem->loc < DS1307_RAM_ADDR_START) ||
-+ ((mem->loc + mem->nr -1) > DS1307_RAM_ADDR_END) )
-+ return -EINVAL;
-+
-+ addr[0] = mem->loc;
-+
-+ return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO;
-+}
-+
-+static int
-+ds1307_command(struct i2c_client *client, unsigned int cmd, void *arg)
-+{
-+ switch (cmd) {
-+ case DS1307_GETDATETIME:
-+ return ds1307_get_datetime(client, arg);
-+
-+ case DS1307_SETTIME:
-+ return ds1307_set_datetime(client, arg, 0);
-+
-+ case DS1307_SETDATETIME:
-+ return ds1307_set_datetime(client, arg, 1);
-+
-+ case DS1307_GETCTRL:
-+ return ds1307_get_ctrl(client, arg);
-+
-+ case DS1307_SETCTRL:
-+ return ds1307_set_ctrl(client, arg);
-+
-+ case DS1307_MEM_READ:
-+ return ds1307_read_mem(client, arg);
-+
-+ case DS1307_MEM_WRITE:
-+ return ds1307_write_mem(client, arg);
-+
-+ default:
-+ return -EINVAL;
-+ }
-+}
-+
-+static int
-+ds1307_rtc_open(struct inode *inode, struct file *file)
-+{
-+ return 0;
-+}
-+
-+static int
-+ds1307_rtc_release(struct inode *inode, struct file *file)
-+{
-+ return 0;
-+}
-+
-+static int
-+ds1307_rtc_ioctl( struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ unsigned long flags;
-+ struct rtc_time wtime;
-+ int status = 0;
-+
-+ switch (cmd) {
-+ default:
-+ case RTC_UIE_ON:
-+ case RTC_UIE_OFF:
-+ case RTC_PIE_ON:
-+ case RTC_PIE_OFF:
-+ case RTC_AIE_ON:
-+ case RTC_AIE_OFF:
-+ case RTC_ALM_SET:
-+ case RTC_ALM_READ:
-+ case RTC_IRQP_READ:
-+ case RTC_IRQP_SET:
-+ case RTC_EPOCH_READ:
-+ case RTC_EPOCH_SET:
-+ case RTC_WKALM_SET:
-+ case RTC_WKALM_RD:
-+ status = -EINVAL;
-+ break;
-+
-+ case RTC_RD_TIME:
-+ spin_lock_irqsave(&ds1307_rtc_lock, flags);
-+ ds1307_command( ds1307_i2c_client, DS1307_GETDATETIME, &wtime);
-+ spin_unlock_irqrestore(&ds1307_rtc_lock,flags);
-+
-+ if( copy_to_user((void *)arg, &wtime, sizeof (struct rtc_time)))
-+ status = -EFAULT;
-+ break;
-+
-+ case RTC_SET_TIME:
-+ if (!capable(CAP_SYS_TIME))
-+ {
-+ status = -EACCES;
-+ break;
-+ }
-+
-+ if (copy_from_user(&wtime, (struct rtc_time *)arg, sizeof(struct rtc_time)) )
-+ {
-+ status = -EFAULT;
-+ break;
-+ }
-+
-+ spin_lock_irqsave(&ds1307_rtc_lock, flags);
-+ ds1307_command( ds1307_i2c_client, DS1307_SETDATETIME, &wtime);
-+ spin_unlock_irqrestore(&ds1307_rtc_lock,flags);
-+ break;
-+ }
-+
-+ return status;
-+}
-+
-+static char *
-+ds1307_mon2str( unsigned int mon)
-+{
-+ char *mon2str[12] = {
-+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
-+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
-+ };
-+ if( mon > 11) return "error";
-+ else return mon2str[ mon];
-+}
-+
-+static int ds1307_rtc_proc_output( char *buf)
-+{
-+#define CHECK(ctrl,bit) ((ctrl & bit) ? "yes" : "no")
-+ unsigned char ram[DS1307_RAM_SIZE];
-+ int ret;
-+
-+ char *p = buf;
-+
-+ ret = ds1307_readram( ram, DS1307_RAM_SIZE);
-+ if( ret > 0)
-+ {
-+ int i;
-+ struct rtc_time dt;
-+ char text[9];
-+
-+ p += sprintf(p, "DS1307 (64x8 Serial Real Time Clock)\n");
-+
-+ ds1307_convert_to_time( &dt, ram);
-+ p += sprintf(p, "Date/Time : %02d-%s-%04d %02d:%02d:%02d\n",
-+ dt.tm_mday, ds1307_mon2str(dt.tm_mon), dt.tm_year + 1900,
-+ dt.tm_hour, dt.tm_min, dt.tm_sec);
-+
-+ p += sprintf(p, "Clock halted : %s\n", CHECK(ram[0],0x80));
-+ p += sprintf(p, "24h mode : %s\n", CHECK(ram[2],0x40));
-+ p += sprintf(p, "Square wave enabled : %s\n", CHECK(ram[7],0x10));
-+ p += sprintf(p, "Freq : ");
-+
-+ switch( ram[7] & 0x03)
-+ {
-+ case RATE_1HZ:
-+ p += sprintf(p, "1Hz\n");
-+ break;
-+ case RATE_4096HZ:
-+ p += sprintf(p, "4.096kHz\n");
-+ break;
-+ case RATE_8192HZ:
-+ p += sprintf(p, "8.192kHz\n");
-+ break;
-+ case RATE_32768HZ:
-+ default:
-+ p += sprintf(p, "32.768kHz\n");
-+ break;
-+
-+ }
-+
-+ p += sprintf(p, "RAM dump:\n");
-+ text[8]='\0';
-+ for( i=0; i<DS1307_RAM_SIZE; i++)
-+ {
-+ p += sprintf(p, "%02X ", ram[i]);
-+
-+ if( (ram[i] < 32) || (ram[i]>126)) ram[i]='.';
-+ text[i%8] = ram[i];
-+ if( (i%8) == 7) p += sprintf(p, "%s\n",text);
-+ }
-+ p += sprintf(p, "\n");
-+ }
-+ else
-+ {
-+ p += sprintf(p, "Failed to read RTC memory!\n");
-+ }
-+
-+ return p - buf;
-+}
-+
-+static int ds1307_rtc_read_proc(char *page, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ int len = ds1307_rtc_proc_output (page);
-+ if (len <= off+count) *eof = 1;
-+ *start = page + off;
-+ len -= off;
-+ if (len>count) len = count;
-+ if (len<0) len = 0;
-+ return len;
-+}
-+
-+static __init int ds1307_init(void)
-+{
-+ int retval=0;
-+
-+ if( slave_address != 0xffff)
-+ {
-+ normal_addr[0] = slave_address;
-+ }
-+
-+ if( normal_addr[0] == 0xffff)
-+ {
-+ printk(KERN_ERR"I2C: Invalid slave address for DS1307 RTC (%#x)\n",
-+ normal_addr[0]);
-+ return -EINVAL;
-+ }
-+
-+ retval = i2c_add_driver(&ds1307_driver);
-+
-+ if (retval==0)
-+ {
-+ misc_register (&ds1307_rtc_miscdev);
-+ create_proc_read_entry (PROC_DS1307_NAME, 0, 0, ds1307_rtc_read_proc, NULL);
-+ printk("I2C: DS1307 RTC driver successfully loaded\n");
-+
-+ if( rtc_debug) ds1307_dumpram();
-+ }
-+ return retval;
-+}
-+
-+static __exit void ds1307_exit(void)
-+{
-+ remove_proc_entry (PROC_DS1307_NAME, NULL);
-+ misc_deregister(&ds1307_rtc_miscdev);
-+ i2c_del_driver(&ds1307_driver);
-+}
-+
-+module_init(ds1307_init);
-+module_exit(ds1307_exit);
-+
-+MODULE_PARM (slave_address, "i");
-+MODULE_PARM_DESC (slave_address, "I2C slave address for DS1307 RTC.");
-+
-+MODULE_AUTHOR ("Intrinsyc Software Inc.");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/ds1307.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,58 @@
-+/*
-+ * ds1307.h
-+ *
-+ * Copyright (C) 2002 Intrinsyc Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ */
-+#ifndef DS1307_H
-+#define DS1307_H
-+
-+#if defined(CONFIG_PXA_EMERSON_SBC) || defined(CONFIG_PXA_CERF_BOARD) || defined(CONFIG_MACH_CSB337)
-+ #define DS1307_I2C_SLAVE_ADDR 0x68
-+#else
-+ #define DS1307_I2C_SLAVE_ADDR 0xffff
-+#endif
-+
-+#define DS1307_RAM_ADDR_START 0x08
-+#define DS1307_RAM_ADDR_END 0x3F
-+#define DS1307_RAM_SIZE 0x40
-+
-+#define PROC_DS1307_NAME "driver/ds1307"
-+
-+struct rtc_mem {
-+ unsigned int loc;
-+ unsigned int nr;
-+ unsigned char *data;
-+};
-+
-+#define DS1307_GETDATETIME 0
-+#define DS1307_SETTIME 1
-+#define DS1307_SETDATETIME 2
-+#define DS1307_GETCTRL 3
-+#define DS1307_SETCTRL 4
-+#define DS1307_MEM_READ 5
-+#define DS1307_MEM_WRITE 6
-+
-+#define SQW_ENABLE 0x10 /* Square Wave Enable */
-+#define SQW_DISABLE 0x00 /* Square Wave disable */
-+
-+#define RATE_32768HZ 0x03 /* Rate Select 32.768KHz */
-+#define RATE_8192HZ 0x02 /* Rate Select 8.192KHz */
-+#define RATE_4096HZ 0x01 /* Rate Select 4.096KHz */
-+#define RATE_1HZ 0x00 /* Rate Select 1Hz */
-+
-+#define CLOCK_HALT 0x80 /* Clock Halt */
-+
-+#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
-+#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
-+
-+#define TWELVE_HOUR_MODE(n) (((n)>>6)&1)
-+#define HOURS_AP(n) (((n)>>5)&1)
-+#define HOURS_12(n) BCD_TO_BIN((n)&0x1F)
-+#define HOURS_24(n) BCD_TO_BIN((n)&0x3F)
-+
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/edb7211_keyb.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,335 @@
-+/*
-+ * drivers/char/edb7211_keyb.c
-+ *
-+ * Copyright (C) 2000 Blue Mug, Inc. All Rights Reserved.
-+ *
-+ * EDB7211 Keyboard driver for ARM Linux.
-+ *
-+ * The EP7211 keyboard hardware only supports generating interrupts for 64 keys.
-+ * The EBD7211's keyboard has 84 keys. Therefore we need to poll for keys,
-+ * instead of waiting for interrupts.
-+ *
-+ * In a real-world hardware situation, this would be a bad thing. It would
-+ * kill power management.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/tty.h>
-+#include <linux/tty_flip.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/ptrace.h>
-+#include <linux/signal.h>
-+#include <linux/timer.h>
-+#include <linux/tqueue.h>
-+#include <linux/random.h>
-+#include <linux/ctype.h>
-+#include <linux/init.h>
-+#include <linux/kbd_ll.h>
-+#include <linux/kbd_kern.h>
-+#include <linux/delay.h>
-+
-+#include <asm/bitops.h>
-+#include <asm/keyboard.h>
-+#include <asm/irq.h>
-+#include <asm/hardware.h>
-+
-+#include <asm/io.h>
-+#include <asm/system.h>
-+
-+
-+/*
-+ * The number of jiffies between keyboard scans.
-+ */
-+#define KEYBOARD_SCAN_INTERVAL 5
-+
-+/*
-+ * Values for the keyboard column scan control register.
-+ */
-+#define KBSC_HI 0x0 /* All driven high */
-+#define KBSC_LO 0x1 /* All driven low */
-+#define KBSC_X 0x2 /* All high impedance */
-+#define KBSC_COL0 0x8 /* Column 0 high, others high impedance */
-+#define KBSC_COL1 0x9 /* Column 1 high, others high impedance */
-+#define KBSC_COL2 0xa /* Column 2 high, others high impedance */
-+#define KBSC_COL3 0xb /* Column 3 high, others high impedance */
-+#define KBSC_COL4 0xc /* Column 4 high, others high impedance */
-+#define KBSC_COL5 0xd /* Column 5 high, others high impedance */
-+#define KBSC_COL6 0xe /* Column 6 high, others high impedance */
-+#define KBSC_COL7 0xf /* Column 7 high, others high impedance */
-+
-+
-+/* XXX: Figure out what these values should be... */
-+/* Simple translation table for the SysRq keys */
-+#ifdef CONFIG_MAGIC_SYSRQ
-+unsigned char edb7211_kbd_sysrq_xlate[128] =
-+ "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
-+ "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
-+ "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
-+ "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
-+ "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
-+ "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
-+ "\r\000/"; /* 0x60 - 0x6f */
-+#endif
-+
-+/*
-+ * Row/column to scancode mappings.
-+ *
-+ * This table maps row/column keyboard matrix positions to XT scancodes.
-+ *
-+ * The port A rows come first, followed by the extended rows.
-+ */
-+static unsigned char colrow_2_scancode[128] =
-+{
-+/* Column:
-+ Row 0 1 2 3 4 5 6 7 */
-+/* A0 */ 0x01, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x40, 0x41,
-+/* A1 */ 0x02, 0x07, 0x06, 0x05, 0x04, 0x03, 0x08, 0x09,
-+/* A2 */ 0x0f, 0x14, 0x13, 0x12, 0x11, 0x10, 0x15, 0x16,
-+/* A3 */ 0x3a, 0x22, 0x21, 0x20, 0x1f, 0x1e, 0x23, 0x24,
-+/* A4 */ 0x29, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x31, 0x32,
-+/* A5 */ 0x39, 0x35, 0x6F, 0x52, 0x00, 0x6B, 0x34, 0x33,
-+/* A6 */ 0x6A, 0x27, 0x28, 0x00, 0x1c, 0x6D, 0x26, 0x25,
-+/* A7 */ 0x67, 0x19, 0x1a, 0x1b, 0x2b, 0x68, 0x18, 0x17,
-+/* E0 */ 0x6C, 0x0c, 0x0d, 0x0e, 0x00, 0x66, 0x0b, 0x0a,
-+/* E1 */ 0x69, 0x44, 0x45, 0x37, 0x46, 0x77, 0x43, 0x42,
-+/* E2 */ 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* E3 */ 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* E4 */ 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* E5 */ 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* E6 */ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* E7 */ 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-+};
-+
-+/*
-+ * A bitfield array which contains the state of the keyboard after the last
-+ * scan. A bit set in this array corresponds to a key down. Only the lower
-+ * 16 bits of each array element are used.
-+ */
-+static unsigned long previous_keys[8];
-+static unsigned long keys[8];
-+
-+
-+/* This will be set to a non-zero value if a key was found to be pressed
-+ * in the last scan. */
-+static int key_is_pressed;
-+
-+static struct tq_struct kbd_process_task;
-+static struct timer_list edb7211_kbd_timer;
-+
-+/*
-+ * External methods.
-+ */
-+void edb7211_kbd_init_hw(void);
-+
-+/*
-+ * Internal methods.
-+ */
-+static int edb7211_kbd_scan_matrix(u_long* keys);
-+static void edb7211_kbd_timeout(unsigned long data);
-+static void edb7211_kbd_process(void* data);
-+
-+/*
-+ * Translate a raw keycode to an XT keyboard scancode.
-+ */
-+static int
-+edb7211_translate(unsigned char scancode, unsigned char *keycode,
-+ char raw_mode)
-+{
-+ *keycode = colrow_2_scancode[scancode & 0x7f];
-+ return 1;
-+}
-+
-+/*
-+ * Scan the keyboard matrix; for each key that is pressed, set the
-+ * corresponding bit in the bitfield array.
-+ *
-+ * The parameter is expected to be an array of 8 32-bit values. Only the lower
-+ * 16 bits of each value is used. Each value contains the row bits for the
-+ * corresponding column.
-+ */
-+static int
-+edb7211_kbd_scan_matrix(u_long* keys)
-+{
-+ int column, row, key_pressed;
-+ unsigned char port_a_data, ext_port_data;
-+
-+ key_pressed = 0;
-+
-+ /* Drive all the columns low. */
-+ clps_writel((clps_readl(SYSCON1) & ~SYSCON1_KBDSCANMASK) | KBSC_LO,
-+ SYSCON1);
-+
-+ for (column = 0; column < 8; column++) {
-+
-+ /* Drive the column high. */
-+ clps_writel((clps_readl(SYSCON1) & ~SYSCON1_KBDSCANMASK) |
-+ (KBSC_COL0 + column), SYSCON1);
-+
-+ /* Read port A and the extended port. */
-+ port_a_data = clps_readb(PADR) & 0xff;
-+ ext_port_data = __raw_readb(EP7211_VIRT_EXTKBD) & 0xff;
-+
-+ /* Drive all columns tri-state. */
-+ clps_writel((clps_readl(SYSCON1) & ~SYSCON1_KBDSCANMASK) | KBSC_X,
-+ SYSCON1);
-+
-+ /* Look at each column in port A. */
-+ for (row=0; row < 8; row++) {
-+ /* If the row's bit is set, set the bit in the bitfield.
-+ * Otherwise, clear it.
-+ */
-+ if (port_a_data & (1 << row)) {
-+ keys[column] |= (1 << row);
-+ key_pressed = 1;
-+ } else {
-+ keys[column] &= ~(1 << row);
-+ }
-+ }
-+
-+ /* Look at each column in the extended port. */
-+ for (row=0; row < 8; row++) {
-+ /* If the row's bit is set, set the bit in the bitfield.
-+ * Otherwise, clear it.
-+ */
-+ if (ext_port_data & (1 << row)) {
-+ keys[column] |= (1 << (row + 8));
-+ key_pressed = 1;
-+ } else {
-+ keys[column] &= ~(1 << (row + 8));
-+ }
-+ }
-+
-+ /*
-+ * Short delay: The example code for the EDB7211 runs an empty
-+ * loop 256 times. At this rate, there were some spurious keys
-+ * generated. I doubled the delay to let the column drives
-+ * settle some.
-+ */
-+ for (row=0; row < 512; row++) { }
-+ }
-+
-+ /* If we could use interrupts, we would drive all columns high so
-+ * that interrupts will be generated on key presses. But we can't,
-+ * so we leave all columns floating.
-+ */
-+ clps_writel((clps_readl(SYSCON1) & ~SYSCON1_KBDSCANMASK) | KBSC_X,
-+ SYSCON1);
-+
-+ return key_pressed;
-+}
-+
-+/*
-+ * XXX: This is really ugly; this needs to be reworked to have less levels of
-+ * indentation.
-+ */
-+static void
-+edb7211_kbd_timeout(unsigned long data)
-+{
-+ /* Schedule the next timer event. */
-+ edb7211_kbd_timer.expires = jiffies + KEYBOARD_SCAN_INTERVAL;
-+ add_timer(&edb7211_kbd_timer);
-+
-+ if (edb7211_kbd_scan_matrix(keys) || key_is_pressed) {
-+ queue_task(&kbd_process_task, &tq_timer);
-+ } else {
-+ key_is_pressed = 0;
-+ }
-+}
-+
-+/*
-+ * Process the keys that have been pressed.
-+ */
-+static void
-+edb7211_kbd_process(void* data)
-+{
-+ int i;
-+
-+ /* First check if any keys have been released. */
-+ if (key_is_pressed) {
-+ for (i=0; i < 8; i++) {
-+ if (previous_keys[i]) {
-+ int row;
-+
-+ for (row=0; row < 16; row++) {
-+ if ((previous_keys[i] & (1 << row)) &&
-+ !(keys[i] & (1 << row))) {
-+ /* Generate the up event. */
-+ handle_scancode(
-+ (row<<3)+i, 0);
-+ }
-+ }
-+ }
-+ }
-+ }
-+
-+ key_is_pressed = 0;
-+
-+ /* Now scan the keys and send press events. */
-+ for (i=0; i < 8; i++) {
-+ if (keys[i]) {
-+ int row;
-+
-+ for (row=0; row < 16; row++) {
-+ if (keys[i] & (1 << row)) {
-+ if (previous_keys[i] & (1 << row)) {
-+ /* Generate the hold event. */
-+ handle_scancode((row<<3)+i, 1);
-+ } else {
-+ /* Generate the down event. */
-+ handle_scancode((row<<3)+i, 1);
-+ }
-+
-+ key_is_pressed = 1;
-+ }
-+ }
-+ }
-+ }
-+
-+ /* Update the state variables. */
-+ memcpy(previous_keys, keys, 8 * sizeof(unsigned long));
-+}
-+
-+static char edb7211_unexpected_up(unsigned char scancode)
-+{
-+ return 0200;
-+}
-+
-+static void edb7211_leds(unsigned char leds)
-+{
-+}
-+
-+/*
-+ * Initialize the keyboard hardware. Set the column drives low and
-+ * start the timer.
-+ */
-+void __init
-+edb7211_kbd_init_hw(void)
-+{
-+ k_translate = edb7211_translate;
-+ k_unexpected_up = edb7211_unexpected_up;
-+ k_leds = edb7211_leds;
-+
-+ /*
-+ * If we had the ability to use interrupts, we would want to drive all
-+ * columns high. But we have more keys than can generate interrupts, so
-+ * we leave them floating.
-+ */
-+ clps_writel((clps_readl(SYSCON1) & ~SYSCON1_KBDSCANMASK) | KBSC_X,
-+ SYSCON1);
-+
-+ /* Initialize the matrix processing task. */
-+ kbd_process_task.routine = edb7211_kbd_process;
-+ kbd_process_task.data = NULL;
-+
-+ /* Setup the timer to poll the keyboard. */
-+ init_timer(&edb7211_kbd_timer);
-+ edb7211_kbd_timer.function = edb7211_kbd_timeout;
-+ edb7211_kbd_timer.data = (unsigned long)NULL;
-+ edb7211_kbd_timer.expires = jiffies + KEYBOARD_SCAN_INTERVAL;
-+ add_timer(&edb7211_kbd_timer);
-+}
-+
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/epxa_wdt.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,178 @@
-+/*
-+ * Watchdog driver for the Altera Excalibur EPXA1DB
-+ *
-+ * (c) Copyright 2003 Krzysztof Marianski <kmarian@konin.lm.pl>
-+ * Based on SA11x0 Watchdog driver by Oleg Drokin <green@crimea.edu>
-+ *
-+ * 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 material is provided "AS-IS" and at no charge
-+ *
-+ * (c) Copyright 2003 Krzysztof Marianski <kmarian@konin.lm.pl>
-+ *
-+ * 1/08/2003 Initial release
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/config.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/fs.h>
-+#include <linux/mm.h>
-+#include <linux/miscdevice.h>
-+#include <linux/watchdog.h>
-+#include <linux/reboot.h>
-+#include <linux/smp_lock.h>
-+#include <linux/init.h>
-+#include <asm/uaccess.h>
-+#include <asm/hardware.h>
-+
-+#define WATCHDOG00_TYPE (volatile unsigned int*)
-+#include <asm/arch/watchdog00.h>
-+#include <asm/bitops.h>
-+
-+#define TIMER_MARGIN 30 /* (secs) Default is 30 seconds */
-+
-+static int margin = TIMER_MARGIN; /* in seconds */
-+static int epxa1wdt_users;
-+static unsigned char last_written_byte;
-+
-+#ifdef CONFIG_WATCHDOG_NOWAYOUT
-+static int nowayout=1;
-+#else
-+static int nowayout=0;
-+#endif
-+
-+#ifdef MODULE
-+MODULE_PARM(margin,"i");
-+MODULE_PARM(nowayout, "i");
-+#endif
-+
-+/*
-+ * Allow only one person to hold it open
-+ */
-+
-+static int epxa1dog_open(struct inode *inode, struct file *file)
-+{
-+ if(test_and_set_bit(1,&epxa1wdt_users))
-+ return -EBUSY;
-+
-+ /* Reset the Watchdog, just to be sure we don't set
-+ a value close to actual value of WDOG_COUNT register */
-+ *WDOG_RELOAD(IO_ADDRESS(EXC_WATCHDOG00_BASE))=WDOG_RELOAD_MAGIC_1;
-+ *WDOG_RELOAD(IO_ADDRESS(EXC_WATCHDOG00_BASE))=WDOG_RELOAD_MAGIC_2;
-+
-+ /* Activate EPXA1DB Watchdog timer */
-+ *WDOG_CR(IO_ADDRESS(EXC_WATCHDOG00_BASE))= (EXC_INPUT_CLK_FREQUENCY * margin) & WDOG_CR_TRIGGER_MSK;
-+
-+ last_written_byte = 'V'; //in case user opens it only to ioctl
-+ return 0;
-+}
-+
-+static int epxa1dog_release(struct inode *inode, struct file *file)
-+{
-+ /*
-+ * Shut off the timer and set lock bit when no special
-+ * character 'V' was last written
-+ */
-+
-+ if ((last_written_byte != 'V') && (nowayout)) {
-+ *WDOG_CR(IO_ADDRESS(EXC_WATCHDOG00_BASE)) |= WDOG_CR_LK_MSK;
-+ printk("No special character 'V' was written to Watchdog just before closing it\n");
-+ printk("WATCHDOG LOCKED - Reboot expected!!!\n");
-+ } else
-+ *WDOG_CR(IO_ADDRESS(EXC_WATCHDOG00_BASE))=0;
-+
-+ epxa1wdt_users = 0;
-+
-+ return 0;
-+}
-+
-+static ssize_t epxa1dog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
-+{
-+ /* Can't seek (pwrite) on this device */
-+ if (ppos != &file->f_pos)
-+ return -ESPIPE;
-+
-+ /* Reset Watchdog timer. */
-+ if(len) {
-+ *WDOG_RELOAD(IO_ADDRESS(EXC_WATCHDOG00_BASE))=WDOG_RELOAD_MAGIC_1;
-+ *WDOG_RELOAD(IO_ADDRESS(EXC_WATCHDOG00_BASE))=WDOG_RELOAD_MAGIC_2;
-+ last_written_byte = *data;
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+static int epxa1dog_ioctl(struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ static struct watchdog_info ident = {
-+ identity: "EPXA Watchdog",
-+ };
-+
-+ switch(cmd){
-+ default:
-+ return -ENOIOCTLCMD;
-+ case WDIOC_GETSUPPORT:
-+ return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident));
-+// case WDIOC_GETSTATUS: //TODO
-+// return put_user(0,(int *)arg);
-+// case WDIOC_GETBOOTSTATUS: //TODO
-+// return 0;
-+ case WDIOC_KEEPALIVE:
-+ *WDOG_RELOAD(IO_ADDRESS(EXC_WATCHDOG00_BASE))=WDOG_RELOAD_MAGIC_1;
-+ *WDOG_RELOAD(IO_ADDRESS(EXC_WATCHDOG00_BASE))=WDOG_RELOAD_MAGIC_2;
-+ return 0;
-+ case WDIOC_SETTIMEOUT:
-+ *WDOG_CR(IO_ADDRESS(EXC_WATCHDOG00_BASE))= (EXC_INPUT_CLK_FREQUENCY * margin) & WDOG_CR_TRIGGER_MSK;
-+ return 0;
-+ case WDIOC_GETTIMEOUT:
-+ return put_user( ((*WDOG_CR(IO_ADDRESS(EXC_WATCHDOG00_BASE)))/EXC_INPUT_CLK_FREQUENCY), (int*)arg);
-+ }
-+}
-+
-+static struct file_operations epxa1dog_fops = {
-+ .owner = THIS_MODULE,
-+ .write = epxa1dog_write,
-+ .ioctl = epxa1dog_ioctl,
-+ .open = epxa1dog_open,
-+ .release = epxa1dog_release,
-+};
-+
-+static struct miscdevice epxa1dog_miscdev=
-+{
-+ .minor = WATCHDOG_MINOR,
-+ .name = "EPXA watchdog",
-+ .fops = &epxa1dog_fops
-+};
-+
-+static int __init epxa1dog_init(void)
-+{
-+ int ret;
-+
-+ ret = misc_register(&epxa1dog_miscdev);
-+
-+ if (ret)
-+ return ret;
-+
-+ printk("EPXA Watchdog Timer: timer margin %d sec\n", margin);
-+ printk("EPXA Watchdog Timer: no way out is %s\n", nowayout ? "enabled" : "disabled");
-+
-+ return 0;
-+}
-+
-+static void __exit epxa1dog_exit(void)
-+{
-+ misc_deregister(&epxa1dog_miscdev);
-+}
-+
-+module_init(epxa1dog_init);
-+module_exit(epxa1dog_exit);
-+
-+MODULE_AUTHOR("Krzysztof Marianski <kmarian@konin.lm.pl>");
-+MODULE_DESCRIPTION("EPXA Watchdog Timer");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/gc_kbmap.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,162 @@
-+
-+
-+#define KK_NONE 0x7f
-+#define KK_ESC 0x00
-+#define KK_F1 0x01
-+#define KK_F2 0x02
-+#define KK_F3 0x03
-+#define KK_F4 0x04
-+#define KK_F5 0x05
-+#define KK_F6 0x06
-+#define KK_F7 0x07
-+#define KK_F8 0x08
-+#define KK_F9 0x09
-+#define KK_F10 0x0a
-+#define KK_F11 0x0b
-+#define KK_F12 0x0c
-+#define KK_PRNT 0x0d
-+#define KK_SCRL 0x0e
-+#define KK_BRK 0x0f
-+#define KK_AGR 0x10
-+#define KK_1 0x11
-+#define KK_2 0x12
-+#define KK_3 0x13
-+#define KK_4 0x14
-+#define KK_5 0x15
-+#define KK_6 0x16
-+#define KK_7 0x17
-+#define KK_8 0x18
-+#define KK_9 0x19
-+#define KK_0 0x1a
-+#define KK_MINS 0x1b
-+#define KK_EQLS 0x1c
-+#define KK_BKSP 0x1e
-+#define KK_INS 0x1f
-+#define KK_HOME 0x20
-+#define KK_PGUP 0x21
-+#define KK_NUML 0x22
-+#define KP_SLH 0x23
-+#define KP_STR 0x24
-+#define KP_MNS 0x3a
-+#define KK_TAB 0x26
-+#define KK_Q 0x27
-+#define KK_W 0x28
-+#define KK_E 0x29
-+#define KK_R 0x2a
-+#define KK_T 0x2b
-+#define KK_Y 0x2c
-+#define KK_U 0x2d
-+#define KK_I 0x2e
-+#define KK_O 0x2f
-+#define KK_P 0x30
-+#define KK_LSBK 0x31
-+#define KK_RSBK 0x32
-+#define KK_ENTR 0x47
-+#define KK_DEL 0x34
-+#define KK_END 0x35
-+#define KK_PGDN 0x36
-+#define KP_7 0x37
-+#define KP_8 0x38
-+#define KP_9 0x39
-+#define KP_PLS 0x4b
-+#define KK_CAPS 0x5d
-+#define KK_A 0x3c
-+#define KK_S 0x3d
-+#define KK_D 0x3e
-+#define KK_F 0x3f
-+#define KK_G 0x40
-+#define KK_H 0x41
-+#define KK_J 0x42
-+#define KK_K 0x43
-+#define KK_L 0x44
-+#define KK_SEMI 0x45
-+#define KK_SQOT 0x46
-+#define KK_HASH 0x1d
-+#define KP_4 0x48
-+#define KP_5 0x49
-+#define KP_6 0x4a
-+#define KK_LSFT 0x4c
-+#define KK_BSLH 0x33
-+#define KK_Z 0x4e
-+#define KK_X 0x4f
-+#define KK_C 0x50
-+#define KK_V 0x51
-+#define KK_B 0x52
-+#define KK_N 0x53
-+#define KK_M 0x54
-+#define KK_COMA 0x55
-+#define KK_DOT 0x56
-+#define KK_FSLH 0x57
-+#define KK_RSFT 0x58
-+#define KK_UP 0x59
-+#define KP_1 0x5a
-+#define KP_2 0x5b
-+#define KP_3 0x5c
-+#define KP_ENT 0x67
-+#define KK_LCTL 0x3b
-+#define KK_LALT 0x5e
-+#define KK_SPCE 0x5f
-+#define KK_RALT 0x60
-+#define KK_RCTL 0x61
-+#define KK_LEFT 0x62
-+#define KK_DOWN 0x63
-+#define KK_RGHT 0x64
-+#define KP_0 0x65
-+#define KP_DOT 0x66
-+
-+static char kbmap[128] = {
-+KK_NONE, KK_LALT, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_AGR, KK_BSLH, KK_TAB, KK_Z, KK_A, KK_X, KK_NONE,
-+KK_NONE, KK_NONE, KK_LSFT, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_LCTL, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, 0x21, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_ESC, KK_DEL, KK_Q, KK_CAPS, KK_S, KK_C, KK_3,
-+KK_NONE, KK_1, KK_NONE, KK_W, KK_NONE, KK_D, KK_V, KK_4,
-+KK_NONE, KK_2, KK_T, KK_E, KK_NONE, KK_F, KK_B, KK_5,
-+KK_NONE, KK_9, KK_Y, KK_R, KK_K, KK_G, KK_N, KK_6,
-+KK_NONE, KK_0, KK_U, KK_O, KK_L, KK_H, KK_M, KK_7,
-+KK_NONE, KK_MINS, KK_I, KK_P, KK_SEMI, KK_J, KK_COMA, KK_8,
-+KK_NONE, KK_EQLS, KK_ENTR, KK_LSBK, KK_BSLH, KK_FSLH, KK_DOT, KK_NONE,
-+KK_NONE, KK_NONE, KK_RSFT, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_BKSP, KK_DOWN, KK_RSBK, KK_UP, KK_LEFT, KK_SPCE, KK_RGHT,
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE};
-+
-+static char kbmapFN[128] = {
-+KK_NONE, KK_LALT, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_NONE, KK_LSFT, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_LCTL, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, 0x21, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_F3,
-+KK_NONE, KK_F1, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_F4,
-+KK_NONE, KK_F2, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_F5,
-+KK_NONE, KK_F9, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_F6,
-+KK_NONE, KK_F10, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_F7,
-+KK_NONE, KK_NUML, KK_NONE, KK_INS, KK_PRNT, KK_NONE, KK_NONE, KK_F8,
-+KK_NONE, KK_BRK, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_NONE, KK_RSFT, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_NONE, KK_PGDN, KK_SCRL, KK_PGUP, KK_HOME, KK_NONE, KK_END,
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE};
-+
-+static char kbmapNL[128] = {
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KP_9, KK_NONE, KK_NONE, KP_2, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KP_STR, KP_4, KP_6, KP_3, KK_NONE, KP_0, KP_7,
-+KK_NONE, KK_NONE, KP_5, KP_MNS, KP_PLS, KP_1, KK_NONE, KP_8,
-+KK_NONE, KK_NONE, KP_ENT, KK_NONE, KK_NONE, KP_SLH, KP_DOT, KK_NONE,
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE,
-+KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE, KK_NONE};
-+
-+
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/gc_keyb.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,1145 @@
-+/*
-+ * linux/arch/arm/drivers/char/gc_keyb.c
-+ *
-+ * Copyright 2000 Applied Data Systems
-+ *
-+ * Keyboard & Smartio driver for GraphicsClient ARM Linux.
-+ * Graphics Client is SA1110 based single board computer by
-+ * Applied Data Systems (http://www.applieddata.net)
-+ *
-+ * Change log:
-+ * 7-10/6/01 Thomas Thaele <tthaele@papenmeier.de>
-+ * - Added Keyboard Sniffer on /dev/sio12 <minor = 12>
-+ * - First implementation of PC- compatible Scancodes (thanks to pc_keyb.c)
-+ * 3/23/01 Woojung Huh
-+ * Power Management added
-+ * 12/01/00 Woojung Huh
-+ * Bug fixed
-+ * 11/16/00 Woojung Huh [whuh@applieddata.net]
-+ * Added smartio device driver on it
-+ */
-+
-+/*
-+ * Introduced setkeycode, ketkeycode for the GC+ by Thomas Thaele
-+ * <tthaele@papenmeier.de> GC+ now performs like a real PC on the keyboard.
-+ * Warning: this code is still beta! PrntScrn and Pause keys are not
-+ * completely tested and implemented!!! Keyboard driver can be confused
-+ * by hacking like crazy on the keyboard. (hardware problem on serial line?)
-+ */
-+
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/kbd_ll.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/kbd_kern.h>
-+
-+#include <asm/irq.h>
-+#include <asm/hardware.h>
-+#include <asm/keyboard.h>
-+#include <linux/tqueue.h>
-+#include <linux/proc_fs.h>
-+#include <linux/pm.h>
-+
-+#define ADS_AVR_IRQ 63
-+
-+#define SMARTIO_IOCTL_BASES 's'
-+#define SMARTIO_KPD_TIMEOUT _IOW(SMARTIO_IOCTL_BASES, 0, int)
-+#define SMARTIO_KPD_SETUP _IOW(SMARTIO_IOCTL_BASES, 1, short)
-+#define SMARTIO_BL_CONTROL _IOW(SMARTIO_IOCTL_BASES, 2, char)
-+#define SMARTIO_BL_CONTRAST _IOW(SMARTIO_IOCTL_BASES, 3, char)
-+#define SMARTIO_PORT_CONFIG _IOW(SMARTIO_IOCTL_BASES, 4, char)
-+#define SMARTIO_SNIFFER_TIMEOUT _IOW(SMARTIO_IOCTL_BASES, 5, long)
-+
-+
-+/* Simple translation table for the SysRq keys */
-+
-+#ifdef CONFIG_MAGIC_SYSRQ
-+unsigned char pckbd_sysrq_xlate[128] =
-+ "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
-+ "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
-+ "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
-+ "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
-+ "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
-+ "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
-+ "\r\000/"; /* 0x60 - 0x6f */
-+#endif
-+
-+/*
-+ * Translation of escaped scancodes to keycodes.
-+ * This is now user-settable.
-+ * The keycodes 1-88,96-111,119 are fairly standard, and
-+ * should probably not be changed - changing might confuse X.
-+ * X also interprets scancode 0x5d (KEY_Begin).
-+ *
-+ * For 1-88 keycode equals scancode.
-+ */
-+
-+#define E0_KPENTER 96
-+#define E0_RCTRL 97
-+#define E0_KPSLASH 98
-+#define E0_PRSCR 99
-+#define E0_RALT 100
-+#define E0_BREAK 101 /* (control-pause) */
-+#define E0_HOME 102
-+#define E0_UP 103
-+#define E0_PGUP 104
-+#define E0_LEFT 105
-+#define E0_RIGHT 106
-+#define E0_END 107
-+#define E0_DOWN 108
-+#define E0_PGDN 109
-+#define E0_INS 110
-+#define E0_DEL 111
-+
-+#define E1_PAUSE 119
-+
-+/*
-+ * The keycodes below are randomly located in 89-95,112-118,120-127.
-+ * They could be thrown away (and all occurrences below replaced by 0),
-+ * but that would force many users to use the `setkeycodes' utility, where
-+ * they needed not before. It does not matter that there are duplicates, as
-+ * long as no duplication occurs for any single keyboard.
-+ */
-+#define SC_LIM 89
-+
-+#define FOCUS_PF1 85 /* actual code! */
-+#define FOCUS_PF2 89
-+#define FOCUS_PF3 90
-+#define FOCUS_PF4 91
-+#define FOCUS_PF5 92
-+#define FOCUS_PF6 93
-+#define FOCUS_PF7 94
-+#define FOCUS_PF8 95
-+#define FOCUS_PF9 120
-+#define FOCUS_PF10 121
-+#define FOCUS_PF11 122
-+#define FOCUS_PF12 123
-+
-+#define JAP_86 124
-+/* tfj@olivia.ping.dk:
-+ * The four keys are located over the numeric keypad, and are
-+ * labelled A1-A4. It's an rc930 keyboard, from
-+ * Regnecentralen/RC International, Now ICL.
-+ * Scancodes: 59, 5a, 5b, 5c.
-+ */
-+#define RGN1 124
-+#define RGN2 125
-+#define RGN3 126
-+#define RGN4 127
-+
-+static unsigned char high_keys[128 - SC_LIM] = {
-+ RGN1, RGN2, RGN3, RGN4, 0, 0, 0, /* 0x59-0x5f */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
-+ 0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12, /* 0x68-0x6f */
-+ 0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3, /* 0x70-0x77 */
-+ FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7, /* 0x78-0x7b */
-+ FOCUS_PF8, JAP_86, FOCUS_PF10, 0 /* 0x7c-0x7f */
-+};
-+
-+/* BTC */
-+#define E0_MACRO 112
-+/* LK450 */
-+#define E0_F13 113
-+#define E0_F14 114
-+#define E0_HELP 115
-+#define E0_DO 116
-+#define E0_F17 117
-+#define E0_KPMINPLUS 118
-+/*
-+ * My OmniKey generates e0 4c for the "OMNI" key and the
-+ * right alt key does nada. [kkoller@nyx10.cs.du.edu]
-+ */
-+#define E0_OK 124
-+/*
-+ * New microsoft keyboard is rumoured to have
-+ * e0 5b (left window button), e0 5c (right window button),
-+ * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
-+ * [or: Windows_L, Windows_R, TaskMan]
-+ */
-+#define E0_MSLW 125
-+#define E0_MSRW 126
-+#define E0_MSTM 127
-+
-+static unsigned char e0_keys[128] = {
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */
-+ 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0, /* 0x18-0x1f */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */
-+ 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR, /* 0x30-0x37 */
-+ E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP, /* 0x38-0x3f */
-+ E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */
-+ E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END,/* 0x48-0x4f */
-+ E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0, /* 0x50-0x57 */
-+ 0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0, /* 0x58-0x5f */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
-+ 0, 0, 0, 0, 0, 0, 0, E0_MACRO, /* 0x68-0x6f */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */
-+ 0, 0, 0, 0, 0, 0, 0, 0 /* 0x78-0x7f */
-+};
-+
-+int gc_kbd_setkeycode(unsigned int scancode, unsigned int keycode)
-+{
-+ if (scancode < SC_LIM || scancode > 255 || keycode > 127)
-+ return -EINVAL;
-+ if (scancode < 128)
-+ high_keys[scancode - SC_LIM] = keycode;
-+ else
-+ e0_keys[scancode - 128] = keycode;
-+ return 0;
-+}
-+
-+int gc_kbd_getkeycode(unsigned int scancode)
-+{
-+ return
-+ (scancode < SC_LIM || scancode > 255) ? -EINVAL :
-+ (scancode < 128) ? high_keys[scancode - SC_LIM] :
-+ e0_keys[scancode - 128];
-+}
-+
-+int gc_kbd_translate(unsigned char scancode, unsigned char *keycode,
-+ char raw_mode)
-+{
-+ static int prev_scancode;
-+
-+ /* special prefix scancodes.. */
-+ if (scancode == 0xe0 || scancode == 0xe1) {
-+ prev_scancode = scancode;
-+ return 0;
-+ }
-+
-+ /* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
-+ if (scancode == 0x00 || scancode == 0xff) {
-+ prev_scancode = 0;
-+ return 0;
-+ }
-+
-+ scancode &= 0x7f;
-+
-+ if (prev_scancode) {
-+ /*
-+ * usually it will be 0xe0, but a Pause key generates
-+ * e1 1d 45 e1 9d c5 when pressed, and nothing when released
-+ */
-+ if (prev_scancode != 0xe0) {
-+ if (prev_scancode == 0xe1 && scancode == 0x1d) {
-+ prev_scancode = 0x100;
-+ return 0;
-+ } else if (prev_scancode == 0x100 && scancode == 0x45) {
-+ *keycode = E1_PAUSE;
-+ prev_scancode = 0;
-+ } else {
-+#ifdef KBD_REPORT_UNKN
-+ if (!raw_mode)
-+ printk(KERN_INFO "keyboard: unknown e1 escape sequence\n");
-+#endif
-+ prev_scancode = 0;
-+ return 0;
-+ }
-+ } else {
-+ prev_scancode = 0;
-+ /*
-+ * The keyboard maintains its own internal caps lock and
-+ * num lock statuses. In caps lock mode E0 AA precedes make
-+ * code and E0 2A follows break code. In num lock mode,
-+ * E0 2A precedes make code and E0 AA follows break code.
-+ * We do our own book-keeping, so we will just ignore these.
-+ */
-+ /*
-+ * For my keyboard there is no caps lock mode, but there are
-+ * both Shift-L and Shift-R modes. The former mode generates
-+ * E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
-+ * So, we should also ignore the latter. - aeb@cwi.nl
-+ */
-+ if (scancode == 0x2a || scancode == 0x36)
-+ return 0;
-+
-+ if (e0_keys[scancode])
-+ *keycode = e0_keys[scancode];
-+ else {
-+#ifdef KBD_REPORT_UNKN
-+ if (!raw_mode)
-+ printk(KERN_INFO "keyboard: unknown scancode e0 %02x\n",
-+ scancode);
-+#endif
-+ return 0;
-+ }
-+ }
-+ } else if (scancode >= SC_LIM) {
-+ /* This happens with the FOCUS 9000 keyboard
-+ Its keys PF1..PF12 are reported to generate
-+ 55 73 77 78 79 7a 7b 7c 74 7e 6d 6f
-+ Moreover, unless repeated, they do not generate
-+ key-down events, so we have to zero up_flag below */
-+ /* Also, Japanese 86/106 keyboards are reported to
-+ generate 0x73 and 0x7d for \ - and \ | respectively. */
-+ /* Also, some Brazilian keyboard is reported to produce
-+ 0x73 and 0x7e for \ ? and KP-dot, respectively. */
-+
-+ *keycode = high_keys[scancode - SC_LIM];
-+
-+ if (!*keycode) {
-+ if (!raw_mode) {
-+#ifdef KBD_REPORT_UNKN
-+ printk(KERN_INFO "keyboard: unrecognized scancode (%02x)"
-+ " - ignored\n", scancode);
-+#endif
-+ }
-+ return 0;
-+ }
-+ } else
-+ *keycode = scancode;
-+ return 1;
-+}
-+
-+// this table converts the hardware dependent codes of a MF-2 Keyboard to
-+// the codes normally comming out of a i8042. This table is 128 Bytes too
-+// big, but for stability reasons it should be kept like it is!
-+// There is no range checking in the code!
-+static int mf_two_kbdmap[256] = {
-+ 00, 67, 65, 63, 61, 59, 60, 88, 00, 68, 66, 64, 62, 15, 41, 00,
-+ 00, 56, 42, 00, 29, 16, 02, 00, 00, 00, 44, 31, 30, 17, 03, 00,
-+ 00, 46, 45, 32, 18, 05, 04, 00, 00, 57, 47, 33, 20, 19, 06, 00,
-+ 00, 49, 48, 35, 34, 21, 7, 00, 00, 00, 50, 36, 22, 8, 9, 00,
-+ 00, 51, 37, 23, 24, 11, 10, 00, 00, 52, 53, 38, 39, 25, 12, 00,
-+ 00, 00, 40, 00, 26, 13, 00, 00, 58, 54, 28, 27, 00, 43, 00, 00,
-+ 00, 86, 00, 00, 00, 00, 14, 00, 00, 79, 00, 75, 71, 00, 00, 00,
-+ 82, 83, 80, 76, 77, 72, 01, 69, 87, 78, 81, 74, 55, 73, 70, 00,
-+ 00, 00, 00, 65, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
-+ 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
-+ 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
-+ 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
-+ 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
-+ 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
-+ 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
-+ 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 };
-+
-+
-+// some texts displayed by the proc_file_system
-+static char *kbd_sniff[2] = { "off", "on" };
-+static char *kbd_sniff_mode[2] = { "passive", "active" };
-+
-+#define PASSIVE 0
-+#define ACTIVE 1
-+
-+// is the sniffer active (1) or inactive (0)
-+static int SNIFFER = 0;
-+// do we get a copy (SNIFFMODE = PASSIVE) or do we get the original data (SNIFFMODE = ACTIVE)
-+// and have to reinsert the data
-+static int SNIFFMODE = PASSIVE;
-+
-+// we allow only one process to sniff
-+static int sniffer_in_use = 0;
-+
-+// timeout for the keyboard sniffer -1 = blocking, otherwise timeout in msecs
-+static long sniffer_timeout = -1;
-+
-+// the value we sniffed from the keyboard
-+static int sniffed_value;
-+
-+static char *smartio_version = "1.02 MF-II compatibility patch <tthaele@papenmeier.de>";
-+static char *smartio_date = "Aug-27-2001";
-+
-+static int sio_reset_flag;
-+static int kbd_press_flag;
-+
-+static void send_SSP_msg(unchar *pBuf, int num)
-+{
-+ ushort tmp;
-+ int i;
-+
-+ for (i=0;i<num;i++) {
-+ while ((Ser4SSSR & SSSR_TNF) == 0);
-+ tmp = pBuf[i];
-+ Ser4SSDR = (tmp << 8);
-+ }
-+
-+ // Throw away Echo
-+ for (i=0;i<num;i++) {
-+ while ((Ser4SSSR & SSSR_RNE) == 0);
-+ tmp = Ser4SSDR;
-+ }
-+}
-+
-+static unchar ReadSSPByte(void)
-+{
-+ if (Ser4SSSR & SSSR_ROR) {
-+ printk("%s() : Overrun\n", __FUNCTION__);
-+ return 0;
-+ }
-+
-+ Ser4SSDR = 0x00;
-+
-+ while ((Ser4SSSR & SSSR_RNE) == 0);
-+
-+ return ((unchar) Ser4SSDR);
-+}
-+
-+static ulong read_SSP_response(int num)
-+{
-+ int i;
-+ ulong ret;
-+
-+ // discard leading 0x00 and command echo 0 (command group value)
-+ while (ReadSSPByte() == 0);
-+ // discard command echo 1 (command code value)
-+ ReadSSPByte();
-+
-+ // data from SMARTIO
-+ // It assumes LSB first.
-+ // NOTE:Some command uses MSB first order
-+ ret = 0;
-+ for (i=0;i<num;i++) {
-+ ret |= ReadSSPByte() << (8*i);
-+ }
-+
-+ return ret;
-+}
-+
-+typedef struct t_SMARTIO_CMD {
-+ unchar Group;
-+ unchar Code;
-+ unchar Opt[2];
-+} SMARTIO_CMD;
-+
-+static SMARTIO_CMD RD_INT_CMD = { 0x83, 0x01, { 0x00, 0x00 } };
-+static SMARTIO_CMD RD_KBD_CMD = { 0x83, 0x02, { 0x00, 0x00 } };
-+static SMARTIO_CMD RD_ADC_CMD = { 0x83, 0x28, { 0x00, 0x00 } };
-+static SMARTIO_CMD RD_KPD_CMD = { 0x83, 0x04, { 0x00, 0x00 } };
-+
-+static volatile ushort adc_value;
-+static volatile unchar kpd_value;
-+static unsigned int kpd_timeout = 10000; // 10000 msec
-+
-+static ulong kbd_int, kpd_int, adc_int;
-+
-+static void smartio_interrupt_task(void *data);
-+
-+static struct tq_struct tq_smartio = {
-+ { NULL, NULL }, // struct list_head
-+ 0, // unsigned long sync
-+ smartio_interrupt_task, // void (*routine)(void *)
-+ NULL, // void *data
-+};
-+
-+DECLARE_WAIT_QUEUE_HEAD(smartio_queue);
-+DECLARE_WAIT_QUEUE_HEAD(smartio_adc_queue);
-+DECLARE_WAIT_QUEUE_HEAD(smartio_kpd_queue);
-+DECLARE_WAIT_QUEUE_HEAD(keyboard_done_queue);
-+DECLARE_WAIT_QUEUE_HEAD(sniffer_queue);
-+
-+static spinlock_t smartio_busy_lock = SPIN_LOCK_UNLOCKED;
-+static atomic_t smartio_busy = ATOMIC_INIT(0);
-+
-+static int f_five_pressed = 0;
-+static int f_seven_pressed = 0;
-+//static int e_null_counter = 0;
-+//static int f_null_counter = 0;
-+//static int keydown = 0;
-+static unchar previous_code = 0;
-+//static int e0 = 0;
-+
-+static void smartio_interrupt_task(void *arg)
-+{
-+ unchar code;
-+ unsigned long flags;
-+ unchar dummy;
-+
-+ spin_lock_irqsave(&smartio_busy_lock, flags);
-+ if (atomic_read(&smartio_busy) == 1) {
-+ spin_unlock_irqrestore(&smartio_busy_lock, flags);
-+ queue_task(&tq_smartio, &tq_timer);
-+ }
-+ else {
-+ atomic_set(&smartio_busy, 1);
-+ spin_unlock_irqrestore(&smartio_busy_lock, flags);
-+ }
-+
-+ /* Read SMARTIO Interrupt Status to check which Interrupt is occurred
-+ * and Clear SMARTIO Interrupt */
-+ send_SSP_msg((unchar *) &RD_INT_CMD, 2);
-+ code = (unchar) (read_SSP_response(1) & 0xFF);
-+
-+#ifdef CONFIG_VT
-+ if (code & 0x04) { // Keyboard Interrupt
-+ kbd_int++;
-+ /* Read Scan code */
-+ send_SSP_msg((unchar *) &RD_KBD_CMD, 2);
-+ code = (unchar) (read_SSP_response(1) & 0xFF);
-+ dummy = code & 0x80;
-+ if ((code == 0xE0) || (code == 0xE1) || (code == 0xF0)) { // combined code
-+ if (code == 0xF0) {
-+ if (!previous_code) {
-+ code = 0xE0;
-+ previous_code = 0xF0;
-+ } else {
-+ code = mf_two_kbdmap[code & 0x7F] | dummy;
-+ previous_code = 0;
-+ }
-+ } else if (code == 0xE0) {
-+ if (previous_code != 0) {
-+ code = mf_two_kbdmap[code & 0x7F] | dummy;
-+ previous_code = 0;
-+ } else previous_code = code;
-+ } else { // 0xE1
-+ if (!previous_code) {
-+ code = mf_two_kbdmap[code &0x7F] | dummy;
-+ previous_code = 0;
-+ } else {
-+ previous_code = code;
-+ }
-+ }
-+ } else {
-+ if (code == 0x03) {
-+ f_five_pressed = 1;
-+ } else if (code == 0x83) {
-+ if (f_five_pressed != 0) {
-+ f_five_pressed = 0;
-+ code = 0x03;
-+ } else if (f_seven_pressed == 0) {
-+ f_seven_pressed = 1;
-+ code = 2;
-+ dummy = 0;
-+ } else {
-+ f_seven_pressed = 0;
-+ code = 2;
-+ }
-+ }
-+ previous_code = 0;
-+ code &= 0x7F;
-+ code = mf_two_kbdmap[code] | dummy;
-+ }
-+ sniffed_value = (ushort)code;
-+ if (SNIFFER) wake_up_interruptible(&sniffer_queue);
-+ if (SNIFFMODE == PASSIVE) {
-+ handle_scancode( code, (code & 0x80) ? 0 : 1 );
-+ if (code & 0x80) {
-+ wake_up_interruptible(&keyboard_done_queue);
-+ mdelay(10); // this makes the whole thing a bit more stable
-+ // keyboard handling can be corrupted when hitting
-+ // thousands of keys like crazy. kbd_translate might catch up
-+ // with irq routine? or there is simply a buffer overflow on
-+ // the serial device? somehow it looses some key sequences.
-+ // if a break code is lost or coruppted the keyboard starts
-+ // to autorepeat like crazy and appears to hang.
-+ // this needs further investigations! Thomas
-+ kbd_press_flag = 0;
-+ }
-+ else
-+ kbd_press_flag = 1;
-+ }
-+ code = 0; // prevent furthermore if ... then to react!
-+ }
-+#endif
-+ // ADC resolution is 10bit (0x000 ~ 0x3FF)
-+ if (code & 0x02) { // ADC Complete Interrupt
-+ adc_int++;
-+ send_SSP_msg((unchar *) &RD_ADC_CMD, 2);
-+ adc_value = (ushort) (read_SSP_response(2) & 0x3FF);
-+ wake_up_interruptible(&smartio_adc_queue);
-+ }
-+
-+ if (code & 0x08) { // Keypad interrupt
-+ kpd_int++;
-+ send_SSP_msg((unchar *) &RD_KPD_CMD, 2);
-+ kpd_value = (unchar) (read_SSP_response(1) & 0xFF);
-+ wake_up_interruptible(&smartio_kpd_queue);
-+ }
-+
-+ spin_lock_irqsave(&smartio_busy_lock, flags);
-+ atomic_set(&smartio_busy, 0);
-+ spin_unlock_irqrestore(&smartio_busy_lock, flags);
-+
-+ enable_irq(ADS_AVR_IRQ);
-+
-+ wake_up_interruptible(&smartio_queue);
-+}
-+
-+static void gc_sio_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+#ifdef CONFIG_VT
-+ kbd_pt_regs = regs;
-+#endif
-+
-+ // *NOTE*
-+ // ADS SMARTIO interrupt is cleared after reading interrupt status
-+ // from smartio.
-+ // disable SMARTIO IRQ here and re-enable at samrtio_bh.
-+ // 11/13/00 Woojung
-+ disable_irq(ADS_AVR_IRQ);
-+
-+ queue_task(&tq_smartio, &tq_immediate);
-+ mark_bh(IMMEDIATE_BH);
-+}
-+
-+char gc_kbd_unexpected_up(unsigned char keycode)
-+{
-+ return 0;
-+}
-+
-+static inline void gc_sio_init(void)
-+{
-+ GPDR |= (GPIO_GPIO10 | GPIO_GPIO12 | GPIO_GPIO13); // Output
-+ GPDR &= ~GPIO_GPIO11;
-+
-+ // Alternative Function
-+ GAFR |= (GPIO_GPIO10 | GPIO_GPIO11 | GPIO_GPIO12 | GPIO_GPIO13);
-+
-+ Ser4SSCR0 = 0xA707;
-+ Ser4SSSR = SSSR_ROR;
-+ Ser4SSCR1 = 0x0010;
-+ Ser4SSCR0 = 0xA787;
-+
-+ // Reset SMARTIO
-+ ADS_AVR_REG &= 0xFE;
-+ mdelay(300); // 10 mSec
-+ ADS_AVR_REG |= 0x01;
-+ mdelay(10); // 10 mSec
-+
-+}
-+
-+void __init gc_kbd_init_hw(void)
-+{
-+ printk (KERN_INFO "Graphics Client keyboard driver v1.0\n");
-+
-+ k_setkeycode = gc_kbd_setkeycode;
-+ k_getkeycode = gc_kbd_getkeycode;
-+ k_translate = gc_kbd_translate;
-+ k_unexpected_up = gc_kbd_unexpected_up;
-+#ifdef CONFIG_MAGIC_SYSRQ
-+ k_sysrq_key = 0x54;
-+ /* sysrq table??? --rmk */
-+#endif
-+
-+ gc_sio_init();
-+
-+ if (request_irq(ADS_AVR_IRQ,gc_sio_interrupt,0,"smartio", NULL) != 0)
-+ printk("Could not allocate SMARTIO IRQ!\n");
-+
-+ sio_reset_flag = 1;
-+}
-+
-+/* SMARTIO ADC Interface */
-+#define SMARTIO_VERSION 0
-+#define SMARTIO_PORT_A 1
-+#define SMARTIO_PORT_B 2
-+#define SMARTIO_PORT_C 3
-+#define SMARTIO_PORT_D 4
-+#define SMARTIO_SELECT_OPTION 5
-+#define SMARTIO_BACKLITE 6
-+#define SMARTIO_KEYPAD 7
-+#define SMARTIO_ADC 8
-+#define SMARTIO_VEE_PWM 9
-+#define SMARTIO_SLEEP 11
-+#define SMARTIO_KBD_SNIFFER 12
-+
-+static SMARTIO_CMD CONV_ADC_CMD = { 0x80, 0x28, { 0x00, 0x00 } };
-+static SMARTIO_CMD READ_PORT_CMD = { 0x82, 0x00, { 0x00, 0x00 } };
-+
-+static SMARTIO_CMD READ_DEVVER_CMD = { 0x82, 0x05, { 0x00, 0x00 } };
-+static SMARTIO_CMD READ_DEVTYPE_CMD = { 0x82, 0x06, { 0x00, 0x00 } };
-+static SMARTIO_CMD READ_FWLEVEL_CMD = { 0x82, 0x07, { 0x00, 0x00 } };
-+
-+static int lock_smartio(unsigned long *flags)
-+{
-+ spin_lock_irqsave(&smartio_busy_lock, *flags);
-+ if (atomic_read(&smartio_busy) == 1) {
-+ spin_unlock_irqrestore(&smartio_busy_lock, *flags);
-+ interruptible_sleep_on(&smartio_queue);
-+ }
-+ else {
-+ atomic_set(&smartio_busy, 1);
-+ spin_unlock_irqrestore(&smartio_busy_lock, *flags);
-+ }
-+
-+ return 1;
-+}
-+
-+static int unlock_smartio(unsigned long *flags)
-+{
-+ spin_lock_irqsave(&smartio_busy_lock, *flags);
-+ atomic_set(&smartio_busy, 0);
-+ spin_unlock_irqrestore(&smartio_busy_lock, *flags);
-+
-+ return 1;
-+}
-+
-+static ushort read_sio_adc(int channel)
-+{
-+ unsigned long flags;
-+
-+ if ((channel < 0) || (channel > 7))
-+ return 0xFFFF;
-+
-+ CONV_ADC_CMD.Opt[0] = (unchar) channel;
-+
-+ lock_smartio(&flags);
-+ send_SSP_msg((unchar *) &CONV_ADC_CMD, 3);
-+ unlock_smartio(&flags);
-+
-+ interruptible_sleep_on(&smartio_adc_queue);
-+
-+ return adc_value & 0x3FF;
-+}
-+
-+static ushort read_sio_port(int port)
-+{
-+ unsigned long flags;
-+ ushort ret;
-+
-+ if ((port < SMARTIO_PORT_B) || (port > SMARTIO_PORT_D))
-+ return 0xFFFF;
-+
-+ READ_PORT_CMD.Code = (unchar) port;
-+
-+ lock_smartio(&flags);
-+ send_SSP_msg((unchar *) &READ_PORT_CMD, 2);
-+ ret = read_SSP_response(1);
-+ unlock_smartio(&flags);
-+
-+ return ret;
-+}
-+
-+static ushort read_sio_kpd(void)
-+{
-+ long timeout;
-+
-+ // kpd_timeout is mSec order
-+ // interrupt_sleep_on_timeout is based on 10msec timer tick
-+ if (kpd_timeout == -1) {
-+ interruptible_sleep_on(&smartio_kpd_queue);
-+ }
-+ else {
-+ timeout = interruptible_sleep_on_timeout(&smartio_kpd_queue,
-+ kpd_timeout/10);
-+ if (timeout == 0) {
-+ // timeout without keypad input
-+ return 0xFFFF;
-+ }
-+ }
-+ return kpd_value;
-+}
-+
-+static ushort read_sio_sniff(void)
-+{
-+ long timeout;
-+
-+ // kpd_timeout is mSec order
-+ // interrupt_sleep_on_timeout is based on 10msec timer tick
-+ if (sniffer_timeout == -1) {
-+ interruptible_sleep_on(&sniffer_queue);
-+ }
-+ else {
-+ timeout = interruptible_sleep_on_timeout(&sniffer_queue,
-+ sniffer_timeout/10);
-+ if (timeout == 0) {
-+ // timeout without keypad input
-+ return -1;
-+ }
-+ }
-+ return (ushort)sniffed_value;
-+}
-+
-+static struct sio_ver {
-+ uint DevVer;
-+ uint DevType;
-+ uint FwLevel;
-+};
-+
-+static ushort read_sio_version(struct sio_ver *ptr)
-+{
-+ unsigned long flags;
-+ ushort ret;
-+
-+ // Read Device Version
-+ lock_smartio(&flags);
-+ send_SSP_msg((unchar *) &READ_DEVVER_CMD, 2);
-+ ret = read_SSP_response(1);
-+ unlock_smartio(&flags);
-+ ptr->DevVer = (uint)ret;
-+ // Read Device Type
-+ lock_smartio(&flags);
-+ send_SSP_msg((unchar *) &READ_DEVTYPE_CMD, 2);
-+ ret = read_SSP_response(2);
-+ unlock_smartio(&flags);
-+ // swap MSB & LSB
-+ ret = ((ret & 0xFF) << 8) | ((ret & 0xFF00) >> 8);
-+ ptr->DevType = (uint)ret;
-+ // Read Firmware Level
-+ lock_smartio(&flags);
-+ send_SSP_msg((unchar *) &READ_FWLEVEL_CMD, 2);
-+ ret = read_SSP_response(2);
-+ unlock_smartio(&flags);
-+ // swap MSB & LSB
-+ ret = ((ret & 0xFF) << 8) | ((ret & 0xFF00) >> 8);
-+ ptr->FwLevel = (uint)ret;
-+
-+ return 0;
-+}
-+
-+static ssize_t sio_read(struct file *file, char *buf, size_t count, loff_t *ppos)
-+{
-+ struct inode *inode = file->f_dentry->d_inode;
-+ unsigned int minor = MINOR(inode->i_rdev);
-+ ushort *ret = (ushort *)buf;
-+
-+ switch (minor) {
-+ case SMARTIO_ADC:
-+ if ((*ret = read_sio_adc(buf[0])) != 0xFFFF)
-+ return sizeof(ushort); // 2 bytes
-+ case SMARTIO_PORT_B:
-+ case SMARTIO_PORT_C:
-+ case SMARTIO_PORT_D:
-+ if ((*ret = read_sio_port(minor)) != 0xFFFF)
-+ return sizeof(ushort);
-+ case SMARTIO_VERSION:
-+ if ((read_sio_version((struct sio_ver *)buf)) != 0xFFFF)
-+ return sizeof(struct sio_ver);
-+ case SMARTIO_KEYPAD:
-+ if ((*ret = read_sio_kpd()) != 0xFFFF)
-+ return sizeof(ushort);
-+ case SMARTIO_KBD_SNIFFER:
-+ if ((*ret = read_sio_sniff()) != (ushort)-1)
-+ return 1;
-+ default :
-+ return -ENXIO;
-+ }
-+}
-+
-+static SMARTIO_CMD WRITE_PORT_CMD = { 0x81, 0x00, { 0x00, 0x00 } };
-+static SMARTIO_CMD SELECT_OPT_CMD = { 0x80, 0x00, { 0x00, 0x00 } };
-+static SMARTIO_CMD CONTROL_BL_CMD = { 0x80, 0x00, { 0x00, 0x00 } };
-+static SMARTIO_CMD CONTRAST_BL_CMD = { 0x80, 0x21, { 0x00, 0x00 } };
-+static SMARTIO_CMD CONTROL_KPD_CMD = { 0x80, 0x27, { 0x00, 0x00 } };
-+static SMARTIO_CMD CONTROL_VEE_CMD = { 0x80, 0x22, { 0x00, 0x00 } };
-+
-+static ushort write_sio_port(int port, unchar value)
-+{
-+ unsigned long flags;
-+
-+ if ((port < SMARTIO_PORT_B) || (port > SMARTIO_PORT_D))
-+ return 0xFFFF;
-+
-+ WRITE_PORT_CMD.Code = (unchar) port;
-+ WRITE_PORT_CMD.Opt[0] = (unchar) value;
-+
-+ lock_smartio(&flags);
-+ send_SSP_msg((unchar *) &WRITE_PORT_CMD, 3);
-+ unlock_smartio(&flags);
-+
-+ return 0;
-+}
-+
-+static ushort write_sio_select(unchar select)
-+{
-+ unsigned long flags;
-+
-+ if ((select < 1) || (select > 2))
-+ return 0xFFFF;
-+
-+ SELECT_OPT_CMD.Code = (unchar) (select + 0x28);
-+
-+ lock_smartio(&flags);
-+ send_SSP_msg((unchar *) &SELECT_OPT_CMD, 2);
-+ unlock_smartio(&flags);
-+
-+ return 0;
-+}
-+
-+static ushort control_sio_backlite(int cmd, int value)
-+{
-+ unsigned long flags;
-+
-+ if (cmd == SMARTIO_BL_CONTRAST) {
-+ value &= 0xFF;
-+ CONTRAST_BL_CMD.Opt[0] = (unchar) value;
-+
-+ lock_smartio(&flags);
-+ send_SSP_msg((unchar *) &CONTRAST_BL_CMD, 3);
-+ unlock_smartio(&flags);
-+ }
-+ else if (cmd == SMARTIO_BL_CONTROL) {
-+ if (value == 0x00) {
-+ // Backlite OFF
-+ CONTROL_BL_CMD.Code = 0x24;
-+ }
-+ else {
-+ // Backlite ON
-+ CONTROL_BL_CMD.Code = 0x23;
-+ }
-+ lock_smartio(&flags);
-+ send_SSP_msg((unchar *) &CONTROL_BL_CMD, 2);
-+ unlock_smartio(&flags);
-+ }
-+ else
-+ return 0xFFFF;
-+
-+ return 0;
-+}
-+
-+static ushort control_sio_keypad(int x, int y)
-+{
-+ unsigned long flags;
-+
-+ if ( (x<1) || (x>8) || (y<1) || (y>8)) {
-+ return 0xFFFF;
-+ }
-+
-+ CONTROL_KPD_CMD.Opt[0] = (unchar) x;
-+ CONTROL_KPD_CMD.Opt[1] = (unchar) y;
-+
-+ lock_smartio(&flags);
-+ send_SSP_msg((unchar *) &CONTROL_KPD_CMD, 4);
-+ unlock_smartio(&flags);
-+
-+ return 0;
-+}
-+
-+static ushort control_sio_vee(int value)
-+{
-+ unsigned long flags;
-+
-+ value &= 0xFF;
-+ CONTROL_VEE_CMD.Opt[0] = (unchar) value;
-+
-+ lock_smartio(&flags);
-+ send_SSP_msg((unchar *) &CONTROL_VEE_CMD, 3);
-+ unlock_smartio(&flags);
-+
-+ return 0;
-+}
-+
-+static ssize_t sio_write(struct file *file, const char *buf, size_t cont, loff_t *ppos)
-+{
-+ struct inode *inode = file->f_dentry->d_inode;
-+ unsigned int minor = MINOR(inode->i_rdev);
-+
-+ switch (minor) {
-+ case SMARTIO_PORT_B:
-+ case SMARTIO_PORT_C:
-+ case SMARTIO_PORT_D:
-+ if (write_sio_port(minor, buf[0]) != 0xFFFF)
-+ return 1;
-+ case SMARTIO_SELECT_OPTION:
-+ if (write_sio_select(buf[0]) != 0xFFFF)
-+ return 1;
-+ case SMARTIO_BACKLITE:
-+ if (control_sio_backlite(SMARTIO_BL_CONTROL, buf[0]) != 0xFFFF)
-+ return 1;
-+ case SMARTIO_KEYPAD:
-+ if (control_sio_keypad(buf[0], buf[1]) != 0xFFFF)
-+ return 2;
-+ case SMARTIO_VEE_PWM:
-+ if (control_sio_vee(buf[0]) != 0xFFFF)
-+ return 1;
-+ case SMARTIO_KBD_SNIFFER:
-+ // here are the scancodes injected
-+ handle_scancode((unchar)buf[0], (buf[0] & 0x80) ? 0 : 1);
-+ wake_up_interruptible(&keyboard_done_queue);
-+ // give some time to process! File IO is a bit faster than manual typing ;-)
-+ udelay(10000);
-+ return 1;
-+ default:
-+ return -ENXIO;
-+ }
-+}
-+
-+static unsigned int sio_poll(struct file *file, struct poll_table_struct *wait)
-+{
-+ return 0;
-+}
-+
-+static SMARTIO_CMD IOCTL_PORT_CMD = { 0x81, 0x00, { 0x00, 0x00 } };
-+
-+static ushort ioctl_sio_port(int port, unchar value)
-+{
-+ unsigned long flags;
-+
-+ if ((port < SMARTIO_PORT_B) || (port > SMARTIO_PORT_D))
-+ return 0xFFFF;
-+
-+ IOCTL_PORT_CMD.Code = (unchar) port + 0x04; // 0x05 ~ 0x08
-+ if (port == SMARTIO_PORT_B) {
-+ // Port B has 4 bits only
-+ IOCTL_PORT_CMD.Opt[0] = (unchar) value & 0x0F;
-+ }
-+ else
-+ IOCTL_PORT_CMD.Opt[0] = (unchar) value;
-+
-+ lock_smartio(&flags);
-+ send_SSP_msg((unchar *) &IOCTL_PORT_CMD, 3);
-+ unlock_smartio(&flags);
-+
-+ return 0;
-+}
-+
-+static int sio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-+{
-+ unsigned int minor = MINOR(inode->i_rdev);
-+ unchar *buf = (unchar *)arg;
-+
-+ switch (minor) {
-+ case SMARTIO_PORT_B:
-+ case SMARTIO_PORT_C:
-+ case SMARTIO_PORT_D:
-+ if (cmd == SMARTIO_PORT_CONFIG) {
-+ if (ioctl_sio_port(minor, buf[0]) != 0xFFFF)
-+ return 0;
-+ }
-+ return -EINVAL;
-+ case SMARTIO_SELECT_OPTION:
-+ if (write_sio_select(buf[0]) != 0xFFFF) return 0;
-+ return -EINVAL;
-+ case SMARTIO_BACKLITE:
-+ if (cmd == SMARTIO_BL_CONTROL) {
-+ if (control_sio_backlite(SMARTIO_BL_CONTROL, buf[0]) != 0xFFFF) return 0;
-+ }
-+ else if (cmd == SMARTIO_BL_CONTRAST) {
-+ if (control_sio_backlite(SMARTIO_BL_CONTRAST, buf[0]) != 0xFFFF) return 0;
-+ }
-+ else return -EINVAL;
-+ case SMARTIO_KEYPAD:
-+ if (cmd == SMARTIO_KPD_TIMEOUT) {
-+ kpd_timeout = *(long*)buf;
-+ return 0;
-+ }
-+ else if (cmd == SMARTIO_KPD_SETUP) {
-+ if (control_sio_keypad(buf[0], buf[1]) != 0xFFFF) return 0;
-+ }
-+ return -EINVAL;
-+ case SMARTIO_VEE_PWM:
-+ if (control_sio_vee(buf[0]) != 0xFFFF) return 0;
-+ return -EINVAL;
-+ case SMARTIO_KBD_SNIFFER:
-+ if (cmd == SMARTIO_SNIFFER_TIMEOUT) {
-+ sniffer_timeout = *(long*)buf;
-+ if (sniffer_timeout < 0) sniffer_timeout = -1;
-+ // the value will be devided by 10 later on
-+ if (!sniffer_timeout) sniffer_timeout = 10;
-+ return 0;
-+ }
-+ return -EINVAL;
-+ default:
-+ return -ENXIO;
-+ }
-+}
-+
-+static int sio_open(struct inode *inode, struct file *file)
-+{
-+ unsigned int minor = MINOR(inode->i_rdev);
-+
-+ // we open all by default. we only have a special handler for the kbd sniffer
-+ switch (minor) {
-+ case SMARTIO_KBD_SNIFFER:
-+ if (sniffer_in_use) return -EBUSY;
-+ sniffer_in_use = 1;
-+ SNIFFER = 1;
-+ // sniff in active or passive mode
-+ if ((file->f_flags & O_RDWR) == O_RDWR) SNIFFMODE = 1; else SNIFFMODE = 0;
-+ // do we have a blocking or non blocking sniffer?
-+ if ((file->f_flags & O_NONBLOCK) == O_NONBLOCK) sniffer_timeout = 100; else sniffer_timeout = -1;
-+ break;
-+ default:
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static int sio_close(struct inode *inode, struct file *file)
-+{
-+ unsigned int minor = MINOR(inode->i_rdev);
-+
-+ switch (minor) {
-+ case SMARTIO_KBD_SNIFFER:
-+ SNIFFER = 0;
-+ SNIFFMODE = 0;
-+ sniffer_in_use = 0;
-+ break;
-+ default:
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static struct file_operations sio_fops = {
-+ read: sio_read,
-+ write: sio_write,
-+ poll: sio_poll,
-+ ioctl: sio_ioctl,
-+ open: sio_open,
-+ release: sio_close,
-+};
-+
-+static struct proc_dir_entry *sio_dir, *parent_dir = NULL;
-+
-+#define SMARTIO_MAJOR 58
-+#define MAJOR_NR SMARTIO_MAJOR
-+
-+#define PROC_NAME "sio"
-+
-+static int sio_read_proc(char *buf, char **start, off_t pos, int count, int *eof, void *data)
-+{
-+ char *p = buf;
-+
-+ p += sprintf(p, "ADS SMARTIO Status: \n");
-+ p += sprintf(p, "\t Keyboard Interrupt : %lu\n", kbd_int);
-+ p += sprintf(p, "\t Keypad Interrupt : %lu\n", kpd_int);
-+ p += sprintf(p, "\t ADC Interrupt : %lu\n", adc_int);
-+ p += sprintf(p, "\t Keyboard Sniffer : %s mode : %s\n", kbd_sniff[ SNIFFER ], kbd_sniff_mode [ SNIFFMODE ]);
-+
-+ return (p-buf);
-+}
-+
-+#ifdef CONFIG_PM
-+static int pm_smartio_callback(struct pm_dev *dev, pm_request_t rqst, void *data)
-+{
-+ switch (rqst) {
-+ case PM_RESUME:
-+ gc_sio_init();
-+ break;
-+ case PM_SUSPEND:
-+ // 4/5/01 Woojung
-+ // It checks Keybard received pair of press/release code.
-+ // System can sleep before receiving release code
-+ if (kbd_press_flag) {
-+ interruptible_sleep_on(&keyboard_done_queue);
-+ }
-+ break;
-+ }
-+
-+ return 0;
-+}
-+#endif
-+
-+void __init sio_init(void)
-+{
-+ if (register_chrdev(MAJOR_NR, "sio", &sio_fops)) {
-+ printk("smartio : unable to get major %d\n", MAJOR_NR);
-+ return;
-+ }
-+ else {
-+ printk("smartio driver initialized. version %s, date:%s\n",
-+ smartio_version, smartio_date);
-+
-+ if (sio_reset_flag != 1) {
-+ gc_sio_init();
-+ if (request_irq(ADS_AVR_IRQ, gc_sio_interrupt,0,"sio",NULL) != 0){
-+ printk("smartio : Could not allocate IRQ!\n");
-+ return;
-+ }
-+ }
-+
-+ if ((sio_dir = create_proc_entry(PROC_NAME, 0, parent_dir)) == NULL) {
-+ printk("smartio : Unable to create /proc entry\n");
-+ return;
-+ }
-+ else {
-+ sio_dir->read_proc = sio_read_proc;
-+#ifdef CONFIG_PM
-+ pm_register(PM_SYS_DEV, PM_SYS_KBC, pm_smartio_callback);
-+#endif
-+ }
-+ }
-+}
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/gckeymap.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,262 @@
-+/* Do not edit this file! It was automatically generated by */
-+/* loadkeys --mktable defkeymap.map > defkeymap.c */
-+
-+#include <linux/types.h>
-+#include <linux/keyboard.h>
-+#include <linux/kd.h>
-+
-+u_short plain_map[NR_KEYS] = {
-+ 0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
-+ 0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009,
-+ 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
-+ 0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
-+ 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
-+ 0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
-+ 0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c,
-+ 0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
-+ 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307,
-+ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
-+ 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a,
-+ 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
-+ 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
-+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+};
-+
-+u_short shift_map[NR_KEYS] = {
-+ 0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e,
-+ 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009,
-+ 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49,
-+ 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53,
-+ 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a,
-+ 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56,
-+ 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c,
-+ 0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e,
-+ 0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307,
-+ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
-+ 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a,
-+ 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
-+ 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116,
-+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+};
-+
-+u_short altgr_map[NR_KEYS] = {
-+ 0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
-+ 0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200,
-+ 0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
-+ 0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf914, 0xfb73,
-+ 0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200,
-+ 0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76,
-+ 0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
-+ 0xf703, 0xf200, 0xf207, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510,
-+ 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911,
-+ 0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b,
-+ 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516,
-+ 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
-+ 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
-+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+};
-+
-+u_short ctrl_map[NR_KEYS] = {
-+ 0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e,
-+ 0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200,
-+ 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
-+ 0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013,
-+ 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
-+ 0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016,
-+ 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c,
-+ 0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
-+ 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307,
-+ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
-+ 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a,
-+ 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
-+ 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
-+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+};
-+
-+u_short shift_ctrl_map[NR_KEYS] = {
-+ 0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200,
-+ 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
-+ 0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013,
-+ 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
-+ 0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016,
-+ 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
-+ 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307,
-+ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
-+ 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
-+ 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
-+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+};
-+
-+u_short alt_map[NR_KEYS] = {
-+ 0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836,
-+ 0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809,
-+ 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869,
-+ 0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873,
-+ 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b,
-+ 0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876,
-+ 0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c,
-+ 0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
-+ 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907,
-+ 0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901,
-+ 0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a,
-+ 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
-+ 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
-+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+};
-+
-+u_short ctrl_alt_map[NR_KEYS] = {
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809,
-+ 0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813,
-+ 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200,
-+ 0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816,
-+ 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
-+ 0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
-+ 0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307,
-+ 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
-+ 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a,
-+ 0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
-+ 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c,
-+ 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+};
-+
-+ushort *key_maps[MAX_NR_KEYMAPS] = {
-+ plain_map, shift_map, altgr_map, 0,
-+ ctrl_map, shift_ctrl_map, 0, 0,
-+ alt_map, 0, 0, 0,
-+ ctrl_alt_map, 0
-+};
-+
-+unsigned int keymap_count = 7;
-+
-+/*
-+ * Philosophy: most people do not define more strings, but they who do
-+ * often want quite a lot of string space. So, we statically allocate
-+ * the default and allocate dynamically in chunks of 512 bytes.
-+ */
-+
-+char func_buf[] = {
-+ '\033', '[', '[', 'A', 0,
-+ '\033', '[', '[', 'B', 0,
-+ '\033', '[', '[', 'C', 0,
-+ '\033', '[', '[', 'D', 0,
-+ '\033', '[', '[', 'E', 0,
-+ '\033', '[', '1', '7', '~', 0,
-+ '\033', '[', '1', '8', '~', 0,
-+ '\033', '[', '1', '9', '~', 0,
-+ '\033', '[', '2', '0', '~', 0,
-+ '\033', '[', '2', '1', '~', 0,
-+ '\033', '[', '2', '3', '~', 0,
-+ '\033', '[', '2', '4', '~', 0,
-+ '\033', '[', '2', '5', '~', 0,
-+ '\033', '[', '2', '6', '~', 0,
-+ '\033', '[', '2', '8', '~', 0,
-+ '\033', '[', '2', '9', '~', 0,
-+ '\033', '[', '3', '1', '~', 0,
-+ '\033', '[', '3', '2', '~', 0,
-+ '\033', '[', '3', '3', '~', 0,
-+ '\033', '[', '3', '4', '~', 0,
-+ '\033', '[', '1', '~', 0,
-+ '\033', '[', '2', '~', 0,
-+ '\033', '[', '3', '~', 0,
-+ '\033', '[', '4', '~', 0,
-+ '\033', '[', '5', '~', 0,
-+ '\033', '[', '6', '~', 0,
-+ '\033', '[', 'M', 0,
-+ '\033', '[', 'P', 0,
-+};
-+
-+char *funcbufptr = func_buf;
-+int funcbufsize = sizeof(func_buf);
-+int funcbufleft = 0; /* space left */
-+
-+char *func_table[MAX_NR_FUNC] = {
-+ func_buf + 0,
-+ func_buf + 5,
-+ func_buf + 10,
-+ func_buf + 15,
-+ func_buf + 20,
-+ func_buf + 25,
-+ func_buf + 31,
-+ func_buf + 37,
-+ func_buf + 43,
-+ func_buf + 49,
-+ func_buf + 55,
-+ func_buf + 61,
-+ func_buf + 67,
-+ func_buf + 73,
-+ func_buf + 79,
-+ func_buf + 85,
-+ func_buf + 91,
-+ func_buf + 97,
-+ func_buf + 103,
-+ func_buf + 109,
-+ func_buf + 115,
-+ func_buf + 120,
-+ func_buf + 125,
-+ func_buf + 130,
-+ func_buf + 135,
-+ func_buf + 140,
-+ func_buf + 145,
-+ 0,
-+ 0,
-+ func_buf + 149,
-+ 0,
-+};
-+
-+struct kbdiacr accent_table[MAX_DIACR] = {
-+ {'`', 'A', '\300'}, {'`', 'a', '\340'},
-+ {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
-+ {'^', 'A', '\302'}, {'^', 'a', '\342'},
-+ {'~', 'A', '\303'}, {'~', 'a', '\343'},
-+ {'"', 'A', '\304'}, {'"', 'a', '\344'},
-+ {'O', 'A', '\305'}, {'o', 'a', '\345'},
-+ {'0', 'A', '\305'}, {'0', 'a', '\345'},
-+ {'A', 'A', '\305'}, {'a', 'a', '\345'},
-+ {'A', 'E', '\306'}, {'a', 'e', '\346'},
-+ {',', 'C', '\307'}, {',', 'c', '\347'},
-+ {'`', 'E', '\310'}, {'`', 'e', '\350'},
-+ {'\'', 'E', '\311'}, {'\'', 'e', '\351'},
-+ {'^', 'E', '\312'}, {'^', 'e', '\352'},
-+ {'"', 'E', '\313'}, {'"', 'e', '\353'},
-+ {'`', 'I', '\314'}, {'`', 'i', '\354'},
-+ {'\'', 'I', '\315'}, {'\'', 'i', '\355'},
-+ {'^', 'I', '\316'}, {'^', 'i', '\356'},
-+ {'"', 'I', '\317'}, {'"', 'i', '\357'},
-+ {'-', 'D', '\320'}, {'-', 'd', '\360'},
-+ {'~', 'N', '\321'}, {'~', 'n', '\361'},
-+ {'`', 'O', '\322'}, {'`', 'o', '\362'},
-+ {'\'', 'O', '\323'}, {'\'', 'o', '\363'},
-+ {'^', 'O', '\324'}, {'^', 'o', '\364'},
-+ {'~', 'O', '\325'}, {'~', 'o', '\365'},
-+ {'"', 'O', '\326'}, {'"', 'o', '\366'},
-+ {'/', 'O', '\330'}, {'/', 'o', '\370'},
-+ {'`', 'U', '\331'}, {'`', 'u', '\371'},
-+ {'\'', 'U', '\332'}, {'\'', 'u', '\372'},
-+ {'^', 'U', '\333'}, {'^', 'u', '\373'},
-+ {'"', 'U', '\334'}, {'"', 'u', '\374'},
-+ {'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
-+ {'T', 'H', '\336'}, {'t', 'h', '\376'},
-+ {'s', 's', '\337'}, {'"', 'y', '\377'},
-+ {'s', 'z', '\337'}, {'i', 'j', '\377'},
-+};
-+
-+unsigned int accent_table_size = 68;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/gckeymap.map 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,357 @@
-+# Default kernel keymap. This uses 7 modifier combinations.
-+keymaps 0-2,4-5,8,12
-+# Change the above line into
-+# keymaps 0-2,4-6,8,12
-+# in case you want the entries
-+# altgr control keycode 83 = Boot
-+# altgr control keycode 111 = Boot
-+# below.
-+#
-+# In fact AltGr is used very little, and one more keymap can
-+# be saved by mapping AltGr to Alt (and adapting a few entries):
-+# keycode 100 = Alt
-+#
-+keycode 1 = Escape Escape
-+ alt keycode 1 = Meta_Escape
-+keycode 2 = one exclam
-+ alt keycode 2 = Meta_one
-+keycode 3 = two at at
-+ control keycode 3 = nul
-+ shift control keycode 3 = nul
-+ alt keycode 3 = Meta_two
-+keycode 4 = three numbersign
-+ control keycode 4 = Escape
-+ alt keycode 4 = Meta_three
-+keycode 5 = four dollar dollar
-+ control keycode 5 = Control_backslash
-+ alt keycode 5 = Meta_four
-+keycode 6 = five percent
-+ control keycode 6 = Control_bracketright
-+ alt keycode 6 = Meta_five
-+keycode 7 = six asciicircum
-+ control keycode 7 = Control_asciicircum
-+ alt keycode 7 = Meta_six
-+keycode 8 = seven ampersand braceleft
-+ control keycode 8 = Control_underscore
-+ alt keycode 8 = Meta_seven
-+keycode 9 = eight asterisk bracketleft
-+ control keycode 9 = Delete
-+ alt keycode 9 = Meta_eight
-+keycode 10 = nine parenleft bracketright
-+ alt keycode 10 = Meta_nine
-+keycode 11 = zero parenright braceright
-+ alt keycode 11 = Meta_zero
-+keycode 12 = minus underscore backslash
-+ control keycode 12 = Control_underscore
-+ shift control keycode 12 = Control_underscore
-+ alt keycode 12 = Meta_minus
-+keycode 13 = equal plus
-+ alt keycode 13 = Meta_equal
-+keycode 14 = Delete Delete
-+ control keycode 14 = BackSpace
-+ alt keycode 14 = Meta_Delete
-+keycode 15 = Tab Tab
-+ alt keycode 15 = Meta_Tab
-+keycode 16 = q
-+keycode 17 = w
-+keycode 18 = e
-+ altgr keycode 18 = Hex_E
-+keycode 19 = r
-+keycode 20 = t
-+keycode 21 = y
-+keycode 22 = u
-+keycode 23 = i
-+keycode 24 = o
-+keycode 25 = p
-+keycode 26 = bracketleft braceleft
-+ control keycode 26 = Escape
-+ alt keycode 26 = Meta_bracketleft
-+keycode 27 = bracketright braceright asciitilde
-+ control keycode 27 = Control_bracketright
-+ alt keycode 27 = Meta_bracketright
-+keycode 28 = Return
-+ alt keycode 28 = Meta_Control_m
-+keycode 29 = Control
-+keycode 30 = a
-+ altgr keycode 30 = Hex_A
-+keycode 31 = s
-+keycode 32 = d
-+ altgr keycode 32 = Hex_D
-+keycode 33 = f
-+ altgr keycode 33 = Hex_F
-+keycode 34 = g
-+keycode 35 = h
-+keycode 36 = j
-+keycode 37 = k
-+keycode 38 = l
-+keycode 39 = semicolon colon
-+ alt keycode 39 = Meta_semicolon
-+keycode 40 = apostrophe quotedbl
-+ control keycode 40 = Control_g
-+ alt keycode 40 = Meta_apostrophe
-+keycode 41 = grave asciitilde
-+ control keycode 41 = nul
-+ alt keycode 41 = Meta_grave
-+keycode 42 = Shift
-+keycode 43 = backslash bar
-+ control keycode 43 = Control_backslash
-+ alt keycode 43 = Meta_backslash
-+keycode 44 = z
-+keycode 45 = x
-+keycode 46 = c
-+ altgr keycode 46 = Hex_C
-+keycode 47 = v
-+keycode 48 = b
-+ altgr keycode 48 = Hex_B
-+keycode 49 = n
-+keycode 50 = m
-+keycode 51 = comma less
-+ alt keycode 51 = Meta_comma
-+keycode 52 = period greater
-+ control keycode 52 = Compose
-+ alt keycode 52 = Meta_period
-+keycode 53 = slash question
-+ control keycode 53 = Delete
-+ alt keycode 53 = Meta_slash
-+keycode 54 = Shift
-+keycode 55 = KP_Multiply
-+keycode 56 = Alt
-+keycode 57 = space space
-+ control keycode 57 = nul
-+ alt keycode 57 = Meta_space
-+keycode 58 = Caps_Lock
-+keycode 59 = F1 F11 Console_13
-+ control keycode 59 = F1
-+ alt keycode 59 = Console_1
-+ control alt keycode 59 = Console_1
-+keycode 60 = F2 F12 Console_14
-+ control keycode 60 = F2
-+ alt keycode 60 = Console_2
-+ control alt keycode 60 = Console_2
-+keycode 61 = F3 F13 Console_15
-+ control keycode 61 = F3
-+ alt keycode 61 = Console_3
-+ control alt keycode 61 = Console_3
-+keycode 62 = F4 F14 Console_16
-+ control keycode 62 = F4
-+ alt keycode 62 = Console_4
-+ control alt keycode 62 = Console_4
-+keycode 63 = F5 F15 Console_17
-+ control keycode 63 = F5
-+ alt keycode 63 = Console_5
-+ control alt keycode 63 = Console_5
-+keycode 64 = F6 F16 Console_18
-+ control keycode 64 = F6
-+ alt keycode 64 = Console_6
-+ control alt keycode 64 = Console_6
-+keycode 65 = F7 F17 Console_19
-+ control keycode 65 = F7
-+ alt keycode 65 = Console_7
-+ control alt keycode 65 = Console_7
-+keycode 66 = F8 F18 Console_20
-+ control keycode 66 = F8
-+ alt keycode 66 = Console_8
-+ control alt keycode 66 = Console_8
-+keycode 67 = F9 F19 Console_21
-+ control keycode 67 = F9
-+ alt keycode 67 = Console_9
-+ control alt keycode 67 = Console_9
-+keycode 68 = F10 F20 Console_22
-+ control keycode 68 = F10
-+ alt keycode 68 = Console_10
-+ control alt keycode 68 = Console_10
-+keycode 69 = Num_Lock
-+ shift keycode 69 = Bare_Num_Lock
-+keycode 70 = Scroll_Lock Show_Memory Show_Registers
-+ control keycode 70 = Show_State
-+ alt keycode 70 = Scroll_Lock
-+keycode 71 = KP_7
-+ alt keycode 71 = Ascii_7
-+ altgr keycode 71 = Hex_7
-+keycode 72 = KP_8
-+ alt keycode 72 = Ascii_8
-+ altgr keycode 72 = Hex_8
-+keycode 73 = KP_9
-+ alt keycode 73 = Ascii_9
-+ altgr keycode 73 = Hex_9
-+keycode 74 = KP_Subtract
-+keycode 75 = KP_4
-+ alt keycode 75 = Ascii_4
-+ altgr keycode 75 = Hex_4
-+keycode 76 = KP_5
-+ alt keycode 76 = Ascii_5
-+ altgr keycode 76 = Hex_5
-+keycode 77 = KP_6
-+ alt keycode 77 = Ascii_6
-+ altgr keycode 77 = Hex_6
-+keycode 78 = KP_Add
-+keycode 79 = KP_1
-+ alt keycode 79 = Ascii_1
-+ altgr keycode 79 = Hex_1
-+keycode 80 = KP_2
-+ alt keycode 80 = Ascii_2
-+ altgr keycode 80 = Hex_2
-+keycode 81 = KP_3
-+ alt keycode 81 = Ascii_3
-+ altgr keycode 81 = Hex_3
-+keycode 82 = KP_0
-+ alt keycode 82 = Ascii_0
-+ altgr keycode 82 = Hex_0
-+keycode 83 = KP_Period
-+# altgr control keycode 83 = Boot
-+ control alt keycode 83 = Boot
-+keycode 84 = Last_Console
-+keycode 85 =
-+keycode 86 = less greater bar
-+ alt keycode 86 = Meta_less
-+keycode 87 = F11 F11 Console_23
-+ control keycode 87 = F11
-+ alt keycode 87 = Console_11
-+ control alt keycode 87 = Console_11
-+keycode 88 = F12 F12 Console_24
-+ control keycode 88 = F12
-+ alt keycode 88 = Console_12
-+ control alt keycode 88 = Console_12
-+keycode 89 =
-+keycode 90 =
-+keycode 91 =
-+keycode 92 =
-+keycode 93 =
-+keycode 94 =
-+keycode 95 =
-+keycode 96 = KP_Enter
-+keycode 97 = Control
-+keycode 98 = KP_Divide
-+keycode 99 = Control_backslash
-+ control keycode 99 = Control_backslash
-+ alt keycode 99 = Control_backslash
-+keycode 100 = AltGr
-+keycode 101 = Break
-+keycode 102 = Find
-+keycode 103 = Up
-+keycode 104 = Prior
-+ shift keycode 104 = Scroll_Backward
-+keycode 105 = Left
-+ alt keycode 105 = Decr_Console
-+keycode 106 = Right
-+ alt keycode 106 = Incr_Console
-+keycode 107 = Select
-+keycode 108 = Down
-+keycode 109 = Next
-+ shift keycode 109 = Scroll_Forward
-+keycode 110 = Insert
-+keycode 111 = Remove
-+# altgr control keycode 111 = Boot
-+ control alt keycode 111 = Boot
-+keycode 112 = Macro
-+keycode 113 = F13
-+keycode 114 = F14
-+keycode 115 = Help
-+keycode 116 = Do
-+keycode 117 = F17
-+keycode 118 = KP_MinPlus
-+keycode 119 = Pause
-+keycode 120 =
-+keycode 121 =
-+keycode 122 =
-+keycode 123 =
-+keycode 124 =
-+keycode 125 =
-+keycode 126 =
-+keycode 127 =
-+string F1 = "\033[[A"
-+string F2 = "\033[[B"
-+string F3 = "\033[[C"
-+string F4 = "\033[[D"
-+string F5 = "\033[[E"
-+string F6 = "\033[17~"
-+string F7 = "\033[18~"
-+string F8 = "\033[19~"
-+string F9 = "\033[20~"
-+string F10 = "\033[21~"
-+string F11 = "\033[23~"
-+string F12 = "\033[24~"
-+string F13 = "\033[25~"
-+string F14 = "\033[26~"
-+string F15 = "\033[28~"
-+string F16 = "\033[29~"
-+string F17 = "\033[31~"
-+string F18 = "\033[32~"
-+string F19 = "\033[33~"
-+string F20 = "\033[34~"
-+string Find = "\033[1~"
-+string Insert = "\033[2~"
-+string Remove = "\033[3~"
-+string Select = "\033[4~"
-+string Prior = "\033[5~"
-+string Next = "\033[6~"
-+string Macro = "\033[M"
-+string Pause = "\033[P"
-+compose '`' 'A' to 'À'
-+compose '`' 'a' to 'à'
-+compose '\'' 'A' to 'Á'
-+compose '\'' 'a' to 'á'
-+compose '^' 'A' to 'Â'
-+compose '^' 'a' to 'â'
-+compose '~' 'A' to 'Ã'
-+compose '~' 'a' to 'ã'
-+compose '"' 'A' to 'Ä'
-+compose '"' 'a' to 'ä'
-+compose 'O' 'A' to 'Å'
-+compose 'o' 'a' to 'å'
-+compose '0' 'A' to 'Å'
-+compose '0' 'a' to 'å'
-+compose 'A' 'A' to 'Å'
-+compose 'a' 'a' to 'å'
-+compose 'A' 'E' to 'Æ'
-+compose 'a' 'e' to 'æ'
-+compose ',' 'C' to 'Ç'
-+compose ',' 'c' to 'ç'
-+compose '`' 'E' to 'È'
-+compose '`' 'e' to 'è'
-+compose '\'' 'E' to 'É'
-+compose '\'' 'e' to 'é'
-+compose '^' 'E' to 'Ê'
-+compose '^' 'e' to 'ê'
-+compose '"' 'E' to 'Ë'
-+compose '"' 'e' to 'ë'
-+compose '`' 'I' to 'Ì'
-+compose '`' 'i' to 'ì'
-+compose '\'' 'I' to 'Í'
-+compose '\'' 'i' to 'í'
-+compose '^' 'I' to 'Î'
-+compose '^' 'i' to 'î'
-+compose '"' 'I' to 'Ï'
-+compose '"' 'i' to 'ï'
-+compose '-' 'D' to 'Ð'
-+compose '-' 'd' to 'ð'
-+compose '~' 'N' to 'Ñ'
-+compose '~' 'n' to 'ñ'
-+compose '`' 'O' to 'Ò'
-+compose '`' 'o' to 'ò'
-+compose '\'' 'O' to 'Ó'
-+compose '\'' 'o' to 'ó'
-+compose '^' 'O' to 'Ô'
-+compose '^' 'o' to 'ô'
-+compose '~' 'O' to 'Õ'
-+compose '~' 'o' to 'õ'
-+compose '"' 'O' to 'Ö'
-+compose '"' 'o' to 'ö'
-+compose '/' 'O' to 'Ø'
-+compose '/' 'o' to 'ø'
-+compose '`' 'U' to 'Ù'
-+compose '`' 'u' to 'ù'
-+compose '\'' 'U' to 'Ú'
-+compose '\'' 'u' to 'ú'
-+compose '^' 'U' to 'Û'
-+compose '^' 'u' to 'û'
-+compose '"' 'U' to 'Ü'
-+compose '"' 'u' to 'ü'
-+compose '\'' 'Y' to 'Ý'
-+compose '\'' 'y' to 'ý'
-+compose 'T' 'H' to 'Þ'
-+compose 't' 'h' to 'þ'
-+compose 's' 's' to 'ß'
-+compose '"' 'y' to 'ÿ'
-+compose 's' 'z' to 'ß'
-+compose 'i' 'j' to 'ÿ'
---- linux-2.4.25/drivers/char/generic_serial.c~2.4.25-vrs2.patch 2002-11-29 00:53:12.000000000 +0100
-+++ linux-2.4.25/drivers/char/generic_serial.c 2004-03-31 17:15:09.000000000 +0200
-@@ -883,6 +883,9 @@
- if(!memcmp(tiosp->c_cc, old_termios->c_cc, NCC)) printk("c_cc changed\n");
- }
-
-+ /*
-+ * should be using tty_get_baud_rate() here -- rmk
-+ */
- baudrate = tiosp->c_cflag & CBAUD;
- if (baudrate & CBAUDEX) {
- baudrate &= ~CBAUDEX;
-@@ -957,6 +960,11 @@
- unsigned long flags;
- unsigned long page;
-
-+ /*
-+ * Do we expect to allocate tmp_buf from an interrupt routine?
-+ * If not, then save_flags() cli() and restore_flags() are
-+ * redundant here and should be replaced by a semaphore. -- rmk
-+ */
- save_flags (flags);
- if (!tmp_buf) {
- page = get_free_page(GFP_KERNEL);
-@@ -976,6 +984,11 @@
- if (port->flags & ASYNC_INITIALIZED)
- return 0;
-
-+ /*
-+ * Do we expect to allocate xmit_buf from an interrupt routine?
-+ * If not, then save_flags() cli() and restore_flags() are
-+ * redundant here and should be replaced by a semaphore. -- rmk
-+ */
- if (!port->xmit_buf) {
- /* We may sleep in get_free_page() */
- unsigned long tmp;
-@@ -1016,7 +1029,7 @@
- struct serial_struct sio;
-
- if (copy_from_user(&sio, sp, sizeof(struct serial_struct)))
-- return(-EFAULT);
-+ return -EFAULT;
-
- if (!capable(CAP_SYS_ADMIN)) {
- if ((sio.baud_base != port->baud_base) ||
---- linux-2.4.25/drivers/char/keyboard.c~2.4.25-vrs2.patch 2003-11-28 19:26:20.000000000 +0100
-+++ linux-2.4.25/drivers/char/keyboard.c 2004-03-31 17:15:09.000000000 +0200
-@@ -14,13 +14,17 @@
- * `Sticky' modifier keys, 951006.
- *
- * 11-11-96: SAK should now work in the raw mode (Martin Mares)
-- *
-+ *
- * Modified to provide 'generic' keyboard support by Hamish Macdonald
- * Merge with the m68k keyboard driver and split-off of the PC low-level
- * parts by Geert Uytterhoeven, May 1997
- *
- * 27-05-97: Added support for the Magic SysRq Key (Martin Mares)
- * 30-07-98: Dead keys redone, aeb@cwi.nl.
-+ *
-+ * 04-04-1998: Added keyboard autorepeat support (some keyboards don't
-+ * autorepeat, and some keyboard changers interfere with keyboard
-+ * autorepeat settings). - Russell King (rmk@arm.linux.org.uk)
- */
-
- #include <linux/config.h>
-@@ -30,6 +34,7 @@
- #include <linux/tty_flip.h>
- #include <linux/mm.h>
- #include <linux/string.h>
-+#include <linux/timer.h>
- #include <linux/random.h>
- #include <linux/init.h>
-
-@@ -61,6 +66,14 @@
- #define KBD_DEFLOCK 0
- #endif
-
-+/*
-+ * Default autorepeat settings.
-+ * DEFAULT_REPEAT_TIMEOUT is the timeout from the keypress to the first repeat
-+ * DEFAULT_REPEAT_INTERVAL is the timeout between successive repeats
-+ */
-+#define DEFAULT_REPEAT_TIMEOUT HZ*300/1000
-+#define DEFAULT_REPEAT_INTERVAL HZ*30/1000
-+
- void (*kbd_ledfunc)(unsigned int led);
- EXPORT_SYMBOL(handle_scancode);
- EXPORT_SYMBOL(kbd_ledfunc);
-@@ -82,21 +95,25 @@
- static unsigned long key_down[256/BITS_PER_LONG];
-
- static int dead_key_next;
--/*
-+/*
- * In order to retrieve the shift_state (for the mouse server), either
-- * the variable must be global, or a new procedure must be created to
-+ * the variable must be global, or a new procedure must be created to
- * return the value. I chose the former way.
- */
- int shift_state;
- static int npadch = -1; /* -1 or number assembled on pad */
- static unsigned char diacr;
- static char rep; /* flag telling character repeat */
-+static int kbd_repeatkeycode= -1;
-+static int kbd_repeattimeout = DEFAULT_REPEAT_TIMEOUT;
-+static int kbd_repeatinterval= DEFAULT_REPEAT_INTERVAL;
- struct kbd_struct kbd_table[MAX_NR_CONSOLES];
- static struct tty_struct **ttytab;
- static struct kbd_struct * kbd = kbd_table;
- static struct tty_struct * tty;
- static unsigned char prev_scancode;
-
-+static void kbd_processkeycode(unsigned char scancode, char up_flag, int autorepeat);
- void compute_shiftstate(void);
-
- typedef void (*k_hand)(unsigned char value, char up_flag);
-@@ -163,7 +180,8 @@
- * string, and in both cases we might assume that it is
- * in utf-8 already.
- */
--void to_utf8(ushort c) {
-+void to_utf8(ushort c)
-+{
- if (c < 0x80)
- put_queue(c); /* 0******* */
- else if (c < 0x800) {
-@@ -182,17 +200,23 @@
- * Translation of escaped scancodes to keycodes.
- * This is now user-settable (for machines were it makes sense).
- */
--
- int setkeycode(unsigned int scancode, unsigned int keycode)
- {
-- return kbd_setkeycode(scancode, keycode);
-+ return kbd_setkeycode(scancode, keycode);
- }
-
- int getkeycode(unsigned int scancode)
- {
-- return kbd_getkeycode(scancode);
-+ return kbd_getkeycode(scancode);
- }
-
-+static void key_callback(unsigned long nr);
-+
-+static struct timer_list key_autorepeat_timer =
-+{
-+ function: key_callback
-+};
-+
- void handle_scancode(unsigned char scancode, int down)
- {
- unsigned char keycode;
-@@ -201,6 +225,7 @@
- char have_keycode;
-
- pm_access(pm_kbd);
-+
- add_keyboard_randomness(scancode | up_flag);
-
- tty = ttytab? ttytab[fg_console]: NULL;
-@@ -223,15 +248,15 @@
- if (raw_mode) {
- /*
- * The following is a workaround for hardware
-- * which sometimes send the key release event twice
-+ * which sometimes send the key release event twice
- */
- unsigned char next_scancode = scancode|up_flag;
- if (have_keycode && up_flag && next_scancode==prev_scancode) {
- /* unexpected 2nd release event */
- } else {
-- /*
-+ /*
- * Only save previous scancode if it was a key-up
-- * and had a single-byte scancode.
-+ * and had a single-byte scancode.
- */
- if (!have_keycode)
- prev_scancode = 1;
-@@ -256,12 +281,35 @@
- * return the keycode if in MEDIUMRAW mode.
- */
-
-+ kbd_processkeycode(keycode, up_flag, 0);
-+
-+out:
-+ do_poke_blanked_console = 1;
-+ schedule_console_callback();
-+}
-+
-+static void
-+kbd_processkeycode(unsigned char keycode, char up_flag, int autorepeat)
-+{
-+ char raw_mode = (kbd->kbdmode == VC_RAW);
-+
- if (up_flag) {
- rep = 0;
- if(!test_and_clear_bit(keycode, key_down))
- up_flag = kbd_unexpected_up(keycode);
-- } else
-+ } else {
- rep = test_and_set_bit(keycode, key_down);
-+ /* If the keyboard autorepeated for us, ignore it.
-+ * We do our own autorepeat processing.
-+ */
-+ if (rep && !autorepeat)
-+ return;
-+ }
-+
-+ if (kbd_repeatkeycode == keycode || !up_flag || raw_mode) {
-+ kbd_repeatkeycode = -1;
-+ del_timer(&key_autorepeat_timer);
-+ }
-
- #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
- if (keycode == SYSRQ_KEY) {
-@@ -275,6 +323,23 @@
- }
- #endif
-
-+ /*
-+ * Calculate the next time when we have to do some autorepeat
-+ * processing. Note that we do not do autorepeat processing
-+ * while in raw mode but we do do autorepeat processing in
-+ * medium raw mode.
-+ */
-+ if (!up_flag && !raw_mode) {
-+ kbd_repeatkeycode = keycode;
-+ if (vc_kbd_mode(kbd, VC_REPEAT)) {
-+ if (rep)
-+ key_autorepeat_timer.expires = jiffies + kbd_repeatinterval;
-+ else
-+ key_autorepeat_timer.expires = jiffies + kbd_repeattimeout;
-+ add_timer(&key_autorepeat_timer);
-+ }
-+ }
-+
- if (kbd->kbdmode == VC_MEDIUMRAW) {
- /* soon keycodes will require more than one byte */
- put_queue(keycode + up_flag);
-@@ -343,9 +408,24 @@
- #endif
- }
- }
-+ rep = 0;
- out:
-- do_poke_blanked_console = 1;
-- schedule_console_callback();
-+}
-+
-+/*
-+ * This clears the key down arrays when the keyboard is reset. On
-+ * keyboard reset, this must be called before any keycodes are
-+ * received.
-+ */
-+void kbd_reset_kdown(void)
-+{
-+ int i;
-+
-+ for (i = 0; i < NR_SHIFT; i++)
-+ k_down[i] = 0;
-+ for (i = 0; i < SIZE(key_down); i++)
-+ key_down[i] = 0;
-+ shift_state = 0;
- }
-
- void put_queue(int ch)
-@@ -453,7 +533,7 @@
- static void decr_console(void)
- {
- int i;
--
-+
- for (i = fg_console-1; i != fg_console; i--) {
- if (i == -1)
- i = MAX_NR_CONSOLES-1;
-@@ -531,7 +611,7 @@
- {
- }
-
--static void do_null()
-+static void do_null(void)
- {
- compute_shiftstate();
- }
-@@ -646,8 +726,8 @@
-
- static void do_pad(unsigned char value, char up_flag)
- {
-- static const char *pad_chars = "0123456789+-*/\015,.?()";
-- static const char *app_map = "pqrstuvwxylSRQMnnmPQ";
-+ static const char *pad_chars = "0123456789+-*/\015,.?()#";
-+ static const char *app_map = "pqrstuvwxylSRQMnnmPQS";
-
- if (up_flag)
- return; /* no action, if this is a key release */
-@@ -748,9 +828,10 @@
- }
- }
-
--/* called after returning from RAW mode or when changing consoles -
-- recompute k_down[] and shift_state from key_down[] */
--/* maybe called when keymap is undefined, so that shiftkey release is seen */
-+/* Called after returning from RAW mode or when changing consoles -
-+ * recompute k_down[] and shift_state from key_down[]
-+ * Maybe called when keymap is undefined so that shift key release is seen
-+ */
- void compute_shiftstate(void)
- {
- int i, j, k, sym, val;
-@@ -829,19 +910,22 @@
- }
-
- /*
-- * The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
-- * or (ii) whatever pattern of lights people want to show using KDSETLED,
-- * or (iii) specified bits of specified words in kernel memory.
-+ * The leds display either
-+ * (i) the status of NumLock, CapsLock, ScrollLock, or
-+ * (ii) whatever pattern of lights people want to show using KDSETLED, or
-+ * (iii) specified bits of specified words in kernel memory.
- */
-
- static unsigned char ledstate = 0xff; /* undefined */
- static unsigned char ledioctl;
-
--unsigned char getledstate(void) {
-+unsigned char getledstate(void)
-+{
- return ledstate;
- }
-
--void setledstate(struct kbd_struct *kbd, unsigned int led) {
-+void setledstate(struct kbd_struct *kbd, unsigned int led)
-+{
- if (!(led & ~7)) {
- ledioctl = led;
- kbd->ledmode = LED_SHOW_IOCTL;
-@@ -857,7 +941,8 @@
- } ledptrs[3];
-
- void register_leds(int console, unsigned int led,
-- unsigned int *addr, unsigned int mask) {
-+ unsigned int *addr, unsigned int mask)
-+{
- struct kbd_struct *kbd = kbd_table + console;
- if (led < 3) {
- ledptrs[led].addr = addr;
-@@ -868,7 +953,8 @@
- kbd->ledmode = LED_SHOW_FLAGS;
- }
-
--static inline unsigned char getleds(void){
-+static inline unsigned char getleds(void)
-+{
- struct kbd_struct *kbd = kbd_table + fg_console;
- unsigned char leds;
-
-@@ -915,6 +1001,19 @@
- {
- unsigned char leds = getleds();
-
-+ if (rep && kbd_repeatkeycode != -1) {
-+ tty = ttytab? ttytab[fg_console]: NULL;
-+ kbd = kbd_table + fg_console;
-+
-+ /* This prevents the kbd_key routine from being called
-+ * twice, once by this BH, and once by the interrupt
-+ * routine.
-+ */
-+ kbd_disable_irq();
-+ kbd_processkeycode(kbd_repeatkeycode, 0, 1);
-+ kbd_enable_irq();
-+ }
-+
- if (leds != ledstate) {
- ledstate = leds;
- kbd_leds(leds);
-@@ -937,6 +1036,12 @@
- tasklet_enable(&keyboard_tasklet);
- }
-
-+static void key_callback(unsigned long nr)
-+{
-+ rep = 1;
-+ tasklet_schedule(&keyboard_tasklet);
-+}
-+
- typedef void (pm_kbd_func) (void);
-
- pm_callback pm_kbd_request_override = NULL;
-@@ -953,7 +1058,7 @@
- kbd0.slockstate = 0;
- kbd0.modeflags = KBD_DEFMODE;
- kbd0.kbdmode = VC_XLATE;
--
-+
- for (i = 0 ; i < MAX_NR_CONSOLES ; i++)
- kbd_table[i] = kbd0;
-
-@@ -963,7 +1068,7 @@
-
- tasklet_enable(&keyboard_tasklet);
- tasklet_schedule(&keyboard_tasklet);
--
-+
- pm_kbd = pm_register(PM_SYS_DEV, PM_SYS_KBC, pm_kbd_request_override);
-
- return 0;
---- linux-2.4.25/drivers/char/mem.c~2.4.25-vrs2.patch 2003-11-28 19:26:20.000000000 +0100
-+++ linux-2.4.25/drivers/char/mem.c 2004-03-31 17:15:09.000000000 +0200
-@@ -27,9 +27,6 @@
- #include <asm/io.h>
- #include <asm/pgalloc.h>
-
--#ifdef CONFIG_I2C
--extern int i2c_init_all(void);
--#endif
- #ifdef CONFIG_FB
- extern void fbmem_init(void);
- #endif
-@@ -740,9 +737,6 @@
- printk("unable to get major %d for memory devs\n", MEM_MAJOR);
- memory_devfs_register();
- rand_initialize();
--#ifdef CONFIG_I2C
-- i2c_init_all();
--#endif
- #if defined (CONFIG_FB)
- fbmem_init();
- #endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/omaha-rtc.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,566 @@
-+/*
-+ * (C) ARM Limited 2002.
-+ *
-+ * Real Time Clock interface for Linux on Omaha
-+ *
-+ * Based on sa1100-rtc.c
-+ *
-+ * Copyright (c) 2000 Nils Faerber
-+ *
-+ * Based on rtc.c by Paul Gortmaker
-+ * Date/time conversion routines taken from arch/arm/kernel/time.c
-+ * by Linus Torvalds and Russell King
-+ * and the GNU C Library
-+ * ( ... I love the GPL ... just take what you need! ;)
-+ *
-+ * 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.
-+ *
-+ * 1.00 2001-06-08 Nicolas Pitre <nico@cam.org>
-+ * - added periodic timer capability using OSMR1
-+ * - flag compatibility with other RTC chips
-+ * - permission checks for ioctls
-+ * - major cleanup, partial rewrite
-+ *
-+ * 0.03 2001-03-07 CIH <cih@coventive.com>
-+ * - Modify the bug setups RTC clock.
-+ *
-+ * 0.02 2001-02-27 Nils Faerber <nils@@kernelconcepts.de>
-+ * - removed mktime(), added alarm irq clear
-+ *
-+ * 0.01 2000-10-01 Nils Faerber <nils@@kernelconcepts.de>
-+ * - initial release
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/fs.h>
-+#include <linux/miscdevice.h>
-+#include <linux/string.h>
-+#include <linux/init.h>
-+#include <linux/poll.h>
-+#include <linux/proc_fs.h>
-+#include <asm/bitops.h>
-+#include <asm/io.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <linux/rtc.h>
-+#include <linux/mc146818rtc.h>
-+
-+#define DRIVER_VERSION "1.00"
-+
-+#define epoch 1970
-+
-+#define TIMER_FREQ 3686400
-+
-+#define RTC_DEF_DIVIDER 32768 - 1
-+#define RTC_DEF_TRIM 0
-+
-+/* Those are the bits from a classic RTC we want to mimic */
-+#define RTC_IRQF 0x80 /* any of the following 3 is active */
-+#define RTC_PF 0x40
-+#define RTC_AF 0x20
-+#define RTC_UF 0x10
-+
-+// bitdefs for rtc registers
-+#define TICNT_ENABLE 0x80 // Enable tick interrupt
-+#define TICNT_PERIOD 0x7F // Divisor required for 1Hz tick
-+#define RTC_ENABLE 0x1 // Enable bit for RTC
-+
-+static unsigned long rtc_status;
-+static unsigned long rtc_irq_data;
-+static unsigned long rtc_freq = 1024;
-+
-+static struct fasync_struct *rtc_async_queue;
-+static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
-+
-+extern spinlock_t rtc_lock;
-+
-+static const unsigned char days_in_mo[] =
-+ {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-+
-+#define is_leap(year) \
-+ ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
-+
-+// all the alarm and rtc registers
-+static volatile unsigned int almsec = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_ALMSEC);
-+static volatile unsigned int almmin = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_ALMMIN);
-+static volatile unsigned int almhour = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_ALMHOUR);
-+static volatile unsigned int almday = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_ALMDAY);
-+static volatile unsigned int almmon = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_ALMMON);
-+static volatile unsigned int almyear = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_ALMYEAR);
-+
-+static volatile unsigned int bcdsec = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_BCDSEC);
-+static volatile unsigned int bcdmin = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_BCDMIN);
-+static volatile unsigned int bcdhour = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_BCDHOUR);
-+static volatile unsigned int bcdday = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_BCDDAY);
-+static volatile unsigned int bcddate = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_BCDDATE);
-+static volatile unsigned int bcdmon = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_BCDMON);
-+static volatile unsigned int bcdyear = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_BCDYEAR);
-+
-+/*
-+ * Converts seconds since 1970-01-01 00:00:00 to Gregorian date.
-+ */
-+
-+static void decodetime (unsigned long t, struct rtc_time *tval)
-+{
-+ long days, month, year, rem;
-+
-+ days = t / 86400;
-+ rem = t % 86400;
-+ tval->tm_hour = rem / 3600;
-+ rem %= 3600;
-+ tval->tm_min = rem / 60;
-+ tval->tm_sec = rem % 60;
-+ tval->tm_wday = (4 + days) % 7;
-+
-+#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
-+
-+ year = epoch;
-+ while (days >= (365 + is_leap(year))) {
-+ unsigned long yg = year + days / 365;
-+ days -= ((yg - year) * 365
-+ + LEAPS_THRU_END_OF (yg - 1)
-+ - LEAPS_THRU_END_OF (year - 1));
-+ year = yg;
-+ }
-+ tval->tm_year = year - 1900;
-+ tval->tm_yday = days + 1;
-+
-+ month = 0;
-+ if (days >= 31) {
-+ days -= 31;
-+ month++;
-+ if (days >= (28 + is_leap(year))) {
-+ days -= (28 + is_leap(year));
-+ month++;
-+ while (days >= days_in_mo[month]) {
-+ days -= days_in_mo[month];
-+ month++;
-+ }
-+ }
-+ }
-+ tval->tm_mon = month;
-+ tval->tm_mday = days + 1;
-+}
-+
-+// Get alarm time in seconds
-+static unsigned long get_alarm_time(void)
-+{
-+ int sec, min,hour,date,mon,year;
-+
-+ // Read data from h/w
-+ year = __raw_readb(almyear);
-+ mon = __raw_readb(almmon);
-+ date = __raw_readb(almday);
-+ hour = __raw_readb(almhour);
-+ min = __raw_readb(almmin);
-+ sec = __raw_readb(almsec);
-+
-+ // convert all the data into binary
-+ year = BCD_TO_BIN(year);
-+ mon = BCD_TO_BIN(mon);
-+ date = BCD_TO_BIN(date);
-+ hour = BCD_TO_BIN(hour);
-+ min = BCD_TO_BIN(min);
-+ sec = BCD_TO_BIN(sec);
-+
-+ // convert year to 19xx or 20xx as appropriate
-+ if (year > 69)
-+ year += 1900;
-+ else
-+ year += 2000;
-+
-+ // Now calculate number of seconds since time began...
-+ return mktime(year,mon,date,hour,min,sec);
-+}
-+
-+// Get rtc time in seconds
-+static unsigned long get_rtc_time(void)
-+{
-+ int sec,min,hour,day,date,mon,year;
-+
-+ // Read data from h/w
-+ year = __raw_readb(bcdyear);
-+ mon = __raw_readb(bcdmon);
-+ date = __raw_readb(bcdday);
-+ day = __raw_readb(bcddate);
-+ hour = __raw_readb(bcdhour);
-+ min = __raw_readb(bcdmin);
-+ sec = __raw_readb(bcdsec);
-+
-+ // convert all the data into binary
-+ year = BCD_TO_BIN(year);
-+ mon = BCD_TO_BIN(mon);
-+ date = BCD_TO_BIN(date);
-+ day = BCD_TO_BIN(day);
-+ hour = BCD_TO_BIN(hour);
-+ min = BCD_TO_BIN(min);
-+ sec = BCD_TO_BIN(sec);
-+
-+ // convert year to 19xx or 20xx as appropriate
-+ if (year > 69)
-+ year += 1900;
-+ else
-+ year += 2000;
-+
-+ // Now calculate number of seconds since time began...
-+ return mktime(year,mon,date,hour,min,sec);
-+}
-+
-+/* Sets time of alarm */
-+static void set_alarm_time(struct rtc_time *tval)
-+{
-+
-+ int sec,min,hour,day,mon,year;
-+
-+ // Convert data from binary to 8-bit bcd
-+ sec = BIN_TO_BCD(tval->tm_sec);
-+ min = BIN_TO_BCD(tval->tm_min);
-+ hour = BIN_TO_BCD(tval->tm_hour);
-+ day = BIN_TO_BCD(tval->tm_mday);
-+ mon = BIN_TO_BCD(tval->tm_mon);
-+
-+ // Year is special
-+ year = tval->tm_year;
-+ if(year > 1999)
-+ year -=2000;
-+ else
-+ year -=1900;
-+
-+ year = BIN_TO_BCD(year);
-+
-+ // Write all the registers
-+ __raw_writeb(year,almyear);
-+ __raw_writeb(mon,almmon);
-+ __raw_writeb(day,almday);
-+ __raw_writeb(hour,almhour);
-+ __raw_writeb(min,almmin);
-+ __raw_writeb(sec,almsec);
-+}
-+
-+/* Sets time of alarm */
-+static void set_rtc_time(struct rtc_time *tval)
-+{
-+
-+ int sec,min,hour,day,date,mon,year;
-+
-+ // Convert data from binary to 8-bit bcd
-+ sec = BIN_TO_BCD(tval->tm_sec);
-+ min = BIN_TO_BCD(tval->tm_min);
-+ hour = BIN_TO_BCD(tval->tm_hour);
-+ day = BIN_TO_BCD(tval->tm_mday);
-+ date = BIN_TO_BCD(tval->tm_wday);
-+ mon = BIN_TO_BCD(tval->tm_mon);
-+
-+ // Year is special
-+ year = tval->tm_year;
-+ if(year > 1999)
-+ year -=2000;
-+ else
-+ year -=1900;
-+
-+ year = BIN_TO_BCD(year);
-+
-+ // Write all the registers
-+ __raw_writeb(year,bcdyear);
-+ __raw_writeb(mon,bcdmon);
-+ __raw_writeb(date,bcddate);
-+ __raw_writeb(day,bcdday);
-+ __raw_writeb(hour,bcdhour);
-+ __raw_writeb(min,bcdmin);
-+ __raw_writeb(sec,bcdsec);
-+}
-+
-+static void rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ /* update irq data & counter */
-+ rtc_irq_data += 0x100;
-+
-+ /* wake up waiting process */
-+ wake_up_interruptible(&rtc_wait);
-+ kill_fasync (&rtc_async_queue, SIGIO, POLL_IN);
-+}
-+
-+static int rtc_open(struct inode *inode, struct file *file)
-+{
-+ if (test_and_set_bit (1, &rtc_status))
-+ return -EBUSY;
-+ MOD_INC_USE_COUNT;
-+ rtc_irq_data = 0;
-+ return 0;
-+}
-+
-+static int rtc_release(struct inode *inode, struct file *file)
-+{
-+ rtc_status = 0;
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static int rtc_fasync (int fd, struct file *filp, int on)
-+{
-+ return fasync_helper (fd, filp, on, &rtc_async_queue);
-+}
-+
-+static unsigned int rtc_poll(struct file *file, poll_table *wait)
-+{
-+ poll_wait (file, &rtc_wait, wait);
-+ return (rtc_irq_data) ? 0 : POLLIN | POLLRDNORM;
-+}
-+
-+static loff_t rtc_llseek(struct file *file, loff_t offset, int origin)
-+{
-+ return -ESPIPE;
-+}
-+
-+ssize_t rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ unsigned long data;
-+ ssize_t retval;
-+
-+ if (count < sizeof(unsigned long))
-+ return -EINVAL;
-+
-+ add_wait_queue(&rtc_wait, &wait);
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ for (;;) {
-+ spin_lock_irq (&rtc_lock);
-+ data = rtc_irq_data;
-+ if (data != 0) {
-+ rtc_irq_data = 0;
-+ break;
-+ }
-+ spin_unlock_irq (&rtc_lock);
-+
-+ if (file->f_flags & O_NONBLOCK) {
-+ retval = -EAGAIN;
-+ goto out;
-+ }
-+
-+ if (signal_pending(current)) {
-+ retval = -ERESTARTSYS;
-+ goto out;
-+ }
-+
-+ schedule();
-+ }
-+
-+ spin_unlock_irq (&rtc_lock);
-+
-+ data -= 0x100; /* the first IRQ wasn't actually missed */
-+
-+ retval = put_user(data, (unsigned long *)buf);
-+ if (!retval)
-+ retval = sizeof(unsigned long);
-+
-+out:
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&rtc_wait, &wait);
-+ return retval;
-+}
-+
-+static int rtc_ioctl(struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ volatile unsigned int rtcalm = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_RTCALM);
-+ volatile unsigned int ticnt = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_TICINT);
-+
-+ struct rtc_time tm, tm2;
-+ switch (cmd) {
-+ case RTC_AIE_OFF:
-+ spin_lock_irq(&rtc_lock);
-+ __raw_writel(0,rtcalm);
-+ rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+ case RTC_AIE_ON:
-+ spin_lock_irq(&rtc_lock);
-+ __raw_writel(0x7F,rtcalm);
-+ rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+ case RTC_UIE_OFF:
-+ spin_lock_irq(&rtc_lock);
-+ __raw_writel(~TICNT_ENABLE,ticnt);
-+ rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+ case RTC_UIE_ON:
-+ spin_lock_irq(&rtc_lock);
-+ __raw_writel(TICNT_ENABLE|TICNT_PERIOD,ticnt);
-+ rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+ case RTC_PIE_OFF:
-+ spin_lock_irq(&rtc_lock);
-+ // Periodic int not available
-+ rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+ case RTC_PIE_ON:
-+ spin_lock_irq(&rtc_lock);
-+ // Periodic int not available
-+ rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+ case RTC_ALM_READ:
-+ decodetime(get_alarm_time(),&tm);
-+ break;
-+ case RTC_ALM_SET:
-+ if (copy_from_user (&tm2, (struct rtc_time*)arg, sizeof (tm2)))
-+ return -EFAULT;
-+ decodetime(get_rtc_time(),&tm);
-+ if ((unsigned)tm2.tm_hour < 24)
-+ tm.tm_hour = tm2.tm_hour;
-+ if ((unsigned)tm2.tm_min < 60)
-+ tm.tm_min = tm2.tm_min;
-+ if ((unsigned)tm2.tm_sec < 60)
-+ tm.tm_sec = tm2.tm_sec;
-+
-+ // Munge (as per sa1100)
-+ tm.tm_year+=1900;
-+ tm.tm_mon+=1;
-+
-+ // Set the alarm
-+ set_alarm_time(&tm);
-+ return 0;
-+ case RTC_RD_TIME:
-+ decodetime (get_rtc_time(), &tm);
-+ break;
-+ case RTC_SET_TIME:
-+ if (!capable(CAP_SYS_TIME))
-+ return -EACCES;
-+ if (copy_from_user (&tm, (struct rtc_time*)arg, sizeof (tm)))
-+ return -EFAULT;
-+ tm.tm_year += 1900;
-+ if (tm.tm_year < epoch || (unsigned)tm.tm_mon >= 12 ||
-+ tm.tm_mday < 1 || tm.tm_mday > (days_in_mo[tm.tm_mon] +
-+ (tm.tm_mon == 1 && is_leap(tm.tm_year))) ||
-+ (unsigned)tm.tm_hour >= 24 ||
-+ (unsigned)tm.tm_min >= 60 ||
-+ (unsigned)tm.tm_sec >= 60)
-+ return -EINVAL;
-+ tm.tm_mon +=1; // wierd: same as sa1100 though (gets month wrong otherwise!)
-+ set_rtc_time(&tm);
-+ return 0;
-+ case RTC_IRQP_READ:
-+ return put_user(rtc_freq, (unsigned long *)arg);
-+ case RTC_IRQP_SET:
-+ if (arg < 1 || arg > TIMER_FREQ)
-+ return -EINVAL;
-+ if ((arg > 64) && (!capable(CAP_SYS_RESOURCE)))
-+ return -EACCES;
-+ rtc_freq = arg;
-+ return 0;
-+ case RTC_EPOCH_READ:
-+ return put_user (epoch, (unsigned long *)arg);
-+ default:
-+ return -EINVAL;
-+ }
-+ return copy_to_user ((void *)arg, &tm, sizeof (tm)) ? -EFAULT : 0;
-+}
-+
-+static struct file_operations rtc_fops = {
-+ .owner = THIS_MODULE,
-+ .llseek = rtc_llseek,
-+ .read = rtc_read,
-+ .poll = rtc_poll,
-+ .ioctl = rtc_ioctl,
-+ .open = rtc_open,
-+ .release = rtc_release,
-+ .fasync = rtc_fasync,
-+};
-+
-+static struct miscdevice omahartc_miscdev = {
-+ .minor = RTC_MINOR,
-+ .name = "rtc",
-+ .fops = &rtc_fops,
-+};
-+
-+static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
-+{
-+ char *p = page;
-+ int len;
-+ struct rtc_time tm;
-+
-+ decodetime (get_rtc_time(), &tm);
-+ p += sprintf(p, "rtc_time\t: %02d:%02d:%02d\n"
-+ "rtc_date\t: %04d-%02d-%02d\n"
-+ "rtc_epoch\t: %04d\n",
-+ tm.tm_hour, tm.tm_min, tm.tm_sec,
-+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
-+ decodetime (get_alarm_time(), &tm);
-+ p += sprintf(p, "alrm_time\t: %02d:%02d:%02d\n"
-+ "alrm_date\t: %04d-%02d-%02d\n",
-+ tm.tm_hour, tm.tm_min, tm.tm_sec,
-+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
-+ p += sprintf(p, "periodic_freq\t: %ld\n", rtc_freq);
-+
-+ len = (p - page) - off;
-+ if (len < 0)
-+ len = 0;
-+
-+ *eof = (len <= count) ? 1 : 0;
-+ *start = page + off;
-+
-+ return len;
-+}
-+
-+static int __init rtc_init(void)
-+{
-+ volatile unsigned int ticnt = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_TICINT);
-+ volatile unsigned int rtccon = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_RTCCON);
-+ int ret;
-+
-+ misc_register (&omahartc_miscdev);
-+ create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL);
-+
-+ // Enable RTC
-+ __raw_writel(RTC_ENABLE,rtccon);
-+
-+ // Acquire 1Hz timer
-+ ret = request_irq (OMAHA_INT_TICK, rtc_interrupt, SA_INTERRUPT, "rtc 1Hz", NULL);
-+ if (ret) {
-+ printk (KERN_ERR "rtc: IRQ %d already in use.\n", OMAHA_INT_TICK);
-+ goto IRQ_TICK_failed;
-+ }
-+
-+ // Acquire RTC (Alarm interrupt)
-+ ret = request_irq (OMAHA_INT_RTC, rtc_interrupt, SA_INTERRUPT, "rtc Alrm", NULL);
-+ if (ret) {
-+ printk (KERN_ERR "rtc: IRQ %d already in use.\n", OMAHA_INT_RTC);
-+ goto IRQ_RTC_failed;
-+ }
-+
-+ printk (KERN_INFO "Omaha Real Time Clock driver v" DRIVER_VERSION "\n");
-+
-+ // Program tick interrupt divisor to generate real 1Hz clock and enable the interrupt
-+ __raw_writeb(TICNT_ENABLE|TICNT_PERIOD,ticnt);
-+
-+ return 0;
-+
-+IRQ_TICK_failed:
-+ free_irq (OMAHA_INT_TICK, NULL);
-+IRQ_RTC_failed:
-+ free_irq(OMAHA_INT_RTC, NULL);
-+ remove_proc_entry ("driver/rtc", NULL);
-+ misc_deregister (&omahartc_miscdev);
-+ return ret;
-+}
-+
-+static void __exit rtc_exit(void)
-+{
-+ free_irq (OMAHA_INT_TICK, NULL);
-+ remove_proc_entry ("driver/rtc", NULL);
-+ misc_deregister (&omahartc_miscdev);
-+}
-+
-+module_init(rtc_init);
-+module_exit(rtc_exit);
-+
-+MODULE_AUTHOR("ARM Limited <support@arm.com>");
-+MODULE_DESCRIPTION("Omaha Realtime Clock Driver (RTC)");
-+EXPORT_NO_SYMBOLS;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/omaha_wdt.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,193 @@
-+/*
-+ * Watchdog driver for the Omaha
-+ * (C) ARM Limited 2002.
-+ *
-+ * Based on sa1100_wdt.c
-+ *
-+ * (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
-+ * Based on SoftDog driver by Alan Cox <alan@redhat.com>
-+ *
-+ * 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.
-+ *
-+ * Neither Oleg Drokin nor iXcelerator.com admit liability nor provide
-+ * warranty for any of this software. This material is provided
-+ * "AS-IS" and at no charge.
-+ *
-+ * (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
-+ *
-+ * 27/11/2000 Initial release
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/config.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/fs.h>
-+#include <linux/mm.h>
-+#include <linux/miscdevice.h>
-+#include <linux/watchdog.h>
-+#include <linux/reboot.h>
-+#include <linux/smp_lock.h>
-+#include <linux/init.h>
-+#include <asm/uaccess.h>
-+#include <asm/io.h>
-+#include <asm/hardware.h>
-+#include <asm/bitops.h>
-+
-+#define TIMER_MARGIN 8 /* (secs) Default is 1 minute */
-+#define WT_TPS 7812 /* Watchdog ticks per second. */
-+#define WT_ENABLE 0x21 // Enable bits for watchdog
-+#define WT_CLKSEL_128 0x18 // Select 1/128 divider
-+
-+static int omaha_margin = TIMER_MARGIN; /* in seconds */
-+static int omahawdt_users;
-+static int pre_margin;
-+#ifdef MODULE
-+MODULE_PARM(omaha_margin,"i");
-+#endif
-+
-+/*
-+ * Allow only one person to hold it open
-+ */
-+
-+static int omahadog_open(struct inode *inode, struct file *file)
-+{
-+ volatile unsigned int wtcon = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_WTCON);
-+ volatile unsigned int wtdat = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_WTDAT);
-+ volatile unsigned int wtcnt = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_WTCNT);
-+ unsigned int tmp;
-+
-+ if(test_and_set_bit(1,&omahawdt_users))
-+ return -EBUSY;
-+ MOD_INC_USE_COUNT;
-+ /* Activate omaha Watchdog timer */
-+
-+ /* Assume that uhal has set up pre-scaler according
-+ * to the system clock frequency (don't change it!)
-+ *
-+ * Ie. all counting occurs at 1MHz / 128 = 7812.5Hz
-+ *
-+ * Since we have 16-bit counter, maximum period is
-+ * 65536/7812.5 = 8.338608 seconds!
-+ */
-+
-+ pre_margin = WT_TPS * omaha_margin;
-+
-+ // Set count to the maximum
-+ __raw_writel(pre_margin,wtcnt);
-+
-+ // Set the clock division factor
-+ tmp = __raw_readl(wtcon);
-+ tmp |= WT_CLKSEL_128;
-+ __raw_writel(tmp,wtcon);
-+
-+ // Program an initial count into WTDAT
-+ __raw_writel(0x8000,wtdat);
-+
-+ // enable the watchdog
-+ tmp = __raw_readl(wtcon);
-+ tmp |= WT_ENABLE;
-+
-+ __raw_writel(tmp,wtcon);
-+
-+ return 0;
-+}
-+
-+static int omahadog_release(struct inode *inode, struct file *file)
-+{
-+ volatile unsigned int wtcon = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_WTCON);
-+ unsigned int tmp;
-+
-+ /*
-+ * Shut off the timer.
-+ * Lock it in if it's a module and we defined ...NOWAYOUT
-+ */
-+#ifndef CONFIG_WATCHDOG_NOWAYOUT
-+ tmp = __raw_readl(wtcon);
-+ tmp &= ~WT_ENABLE;
-+ __raw_writel(tmp,wtcon);
-+#endif
-+ omahawdt_users = 0;
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static ssize_t omahadog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
-+{
-+ volatile unsigned int wtcnt = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_WTCNT);
-+
-+ /* Can't seek (pwrite) on this device */
-+ if (ppos != &file->f_pos)
-+ return -ESPIPE;
-+
-+ /* Refresh timer. */
-+ if(len) {
-+ __raw_writel(pre_margin,wtcnt);
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+static int omahadog_ioctl(struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ volatile unsigned int wtdat = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_WTDAT);
-+ static struct watchdog_info ident = {
-+ identity: "omaha Watchdog",
-+ };
-+
-+ switch(cmd){
-+ default:
-+ return -ENOIOCTLCMD;
-+ case WDIOC_GETSUPPORT:
-+ return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident));
-+ case WDIOC_GETSTATUS:
-+ return put_user(0,(int *)arg);
-+ case WDIOC_GETBOOTSTATUS:
-+ return 0;
-+ case WDIOC_KEEPALIVE:
-+ __raw_writel(pre_margin,wtdat);
-+ return 0;
-+ }
-+}
-+
-+static struct file_operations omahadog_fops=
-+{
-+ .owner = THIS_MODULE,
-+ .write = omahadog_write,
-+ .ioctl = omahadog_ioctl,
-+ .open = omahadog_open,
-+ .release = omahadog_release,
-+};
-+
-+static struct miscdevice omahadog_miscdev=
-+{
-+ .minor = WATCHDOG_MINOR,
-+ .name = "omaha watchdog",
-+ .fops = &omahadog_fops
-+};
-+
-+static int __init omahadog_init(void)
-+{
-+ int ret;
-+
-+ ret = misc_register(&omahadog_miscdev);
-+
-+ if (ret)
-+ return ret;
-+
-+ printk("Omaha Watchdog Timer: timer margin %d sec\n", omaha_margin);
-+
-+ return 0;
-+}
-+
-+static void __exit omahadog_exit(void)
-+{
-+ misc_deregister(&omahadog_miscdev);
-+}
-+
-+module_init(omahadog_init);
-+module_exit(omahadog_exit);
---- linux-2.4.25/drivers/char/pcmcia/Config.in~2.4.25-vrs2.patch 2002-11-29 00:53:12.000000000 +0100
-+++ linux-2.4.25/drivers/char/pcmcia/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -5,7 +5,13 @@
- mainmenu_option next_comment
- comment 'PCMCIA character devices'
-
--dep_tristate 'PCMCIA serial device support' CONFIG_PCMCIA_SERIAL_CS $CONFIG_SERIAL
-+if [ "$CONFIG_SERIAL" = "y" -o "$CONFIG_SERIAL_8250" = "y" ]; then
-+ dep_tristate 'PCMCIA serial device support' CONFIG_PCMCIA_SERIAL_CS y
-+else
-+ if [ "$CONFIG_SERIAL" = "m" -o "$CONFIG_SERIAL_8250" = "m" ]; then
-+ dep_tristate 'PCMCIA serial device support' CONFIG_PCMCIA_SERIAL_CS m
-+ fi
-+fi
- if [ "$CONFIG_PCMCIA_SERIAL_CS" = "y" ]; then
- define_bool CONFIG_PCMCIA_CHRDEV y
- fi
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/pcmcia/memory_cs.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,214 @@
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/mtd.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/mtd.h>
-+
-+static dev_info_t dev_info = "memory_cs";
-+static dev_link_t *dev_list;
-+
-+struct memcs_dev {
-+ dev_link_t link;
-+ struct map_info map;
-+};
-+
-+static __u8 mem_cs_read8(struct map_info *map, unsigned long ofs)
-+{
-+ return readb(map->map_priv_1 + ofs);
-+}
-+
-+static __u16 mem_cs_read16(struct map_info *map, unsigned long ofs)
-+{
-+ return readw(map->map_priv_1 + ofs);
-+}
-+
-+static __u32 mem_cs_read32(struct map_info *map, unsigned long ofs)
-+{
-+ return readl(map->map_priv_1 + ofs);
-+}
-+
-+static void mem_cs_copy_from(struct map_info *map, void *to, unsigned long ofs, ssize_t size)
-+{
-+ memcpy_fromio(to, map->map_priv_1 + ofs, size);
-+}
-+
-+static void mem_cs_write8(struct map_info *map, __u8 val, unsigned long ofs)
-+{
-+ writeb(val, map->map_priv_1 + ofs);
-+}
-+
-+static void mem_cs_write16(struct map_info *map, __u16 val, unsigned long ofs)
-+{
-+ writew(val, map->map_priv_1 + ofs);
-+}
-+
-+static void mem_cs_write32(struct map_info *map, __u32 val, unsigned long ofs)
-+{
-+ writel(val, map->map_priv_1 + ofs);
-+}
-+
-+static void mem_cs_copy_to(struct map_info *map, unsigned long ofs, const void *to, ssize_t size)
-+{
-+ memcpy_toio(map->map_priv_1 + ofs, from, size);
-+}
-+
-+static void mem_cs_release(u_long arg);
-+
-+static void mem_cs_detach(dev_link_t *link)
-+{
-+ del_timer(&link->release);
-+ if (link->state & DEV_CONFIG) {
-+ mem_cs_release((u_long)link);
-+ if (link->state & DEV_STALE_CONFIG) {
-+ link->state |= DEV_STALE_LINK;
-+ return;
-+ }
-+ }
-+
-+ if (link->handle)
-+ CardServices(DeregisterClient, link->handle);
-+
-+ kfree(link);
-+}
-+
-+static void mem_cs_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *)arg;
-+
-+ link->dev = NULL;
-+ if (link->win) {
-+ CardServices(ReleaseWindow, link->win);
-+ }
-+ link->state &= ~DEV_CONFIG;
-+
-+ if (link->state & DEV_STALE_LINK)
-+ mem_cs_detach(link);
-+}
-+
-+static void mem_cs_config(dev_link_t *link)
-+{
-+ struct memcs_dev *dev = link->priv;
-+ cs_status_t status;
-+ win_req_t req;
-+
-+ link->state |= DEV_CONFIG;
-+
-+ req.Attributes = word_width ? WIN_DATA_WIDTH_16 : WIN_DATA_WIDTH_8;
-+ req.Base = 0;
-+ req.Size = 0;
-+ req.AccessSpeed = mem_speed;
-+
-+ link->win = (window_handle_t)link->handle;
-+
-+ CS_CHECK(RequestWindow, &link->win, &req);
-+
-+ CS_CHECK(GetStatus, link->handle, &status);
-+
-+ dev->map.buswidth = word_width ? 2 : 1;
-+ dev->map.size = req.Size;
-+ dev->map.map_priv_1 = ioremap(req.Base, req.Size);
-+}
-+
-+static int
-+mem_cs_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG)
-+ mod_timer(&link->release, jiffies + HZ/20);
-+ break;
-+
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ mem_cs_config(link);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static dev_link_t *mem_cs_attach(void)
-+{
-+ struct memcs_dev *dev;
-+ client_reg_t clnt;
-+
-+ dev = kmalloc(sizeof(*dev), GFP_KERNEL);
-+ if (dev) {
-+ memset(dev, 0, sizeof(*dev));
-+
-+ dev->map.read8 = mem_cs_read8;
-+ dev->map.read16 = mem_cs_read16;
-+ dev->map.read32 = mem_cs_read32;
-+ dev->map.copy_from = mem_cs_copy_from;
-+ dev->map.write8 = mem_cs_write8;
-+ dev->map.write16 = mem_cs_write16;
-+ dev->map.write32 = mem_cs_write32;
-+ dev->map.copy_to = mem_cs_copy_to;
-+
-+ dev->link.release.function = &mem_cs_release;
-+ dev->link.release.data = (u_long)link;
-+ dev->link.priv = dev;
-+
-+ dev->link.next = dev_list;
-+ dev_list = &dev->link;
-+
-+ clnt.dev_info = &dev_info;
-+ clnt.Attributes = INOF_IO_CLIENT | INFO_CARD_SHARE;
-+ clnt.EventMask =
-+ CS_EVENT_WRITE_PROTECT | CS_EVENT_CARD_INSERTION |
-+ CS_EVENT_CARD_REMOVAL | CS_EVENT_BATTERY_DEAD |
-+ CS_EVENT_BATTERY_LOW;
-+
-+ clnt.event_handler = &mem_cs_event;
-+ clnt.Version = 0x0210;
-+ clnt.event_callback_args.client_data = &dev->link;
-+
-+ ret = CardServices(RegisterClient, &dev->link.handle, &clnt);
-+ if (ret != CS_SUCCESS) {
-+ error_info_t err = { RegisterClient, ret };
-+ CardServices(ReportError, dev->link.handle, &err);
-+ mem_cs_detach(&dev->link);
-+ dev = NULL;
-+ }
-+ }
-+
-+ return &dev->link;
-+}
-+
-+static int __init mem_cs_init(void)
-+{
-+ servinfo_t serv;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "memory_cs: Card services release "
-+ "does not match\n");
-+ return -ENXIO;
-+ }
-+ register_pccard_driver(&dev_info, mem_cs_attach, mem_cs_detach);
-+ return 0;
-+}
-+
-+static void __exit mem_cs_exit(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+ while (dev_list != NULL)
-+ memory_detach(dev_list);
-+}
-+
-+module_init(mem_cs_init);
-+module_exit(mem_cs_exit);
-+
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/sa1100-rtc.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,474 @@
-+/*
-+ * Real Time Clock interface for Linux on StrongARM SA1100
-+ *
-+ * Copyright (c) 2000 Nils Faerber
-+ *
-+ * Based on rtc.c by Paul Gortmaker
-+ * Date/time conversion routines taken from arch/arm/kernel/time.c
-+ * by Linus Torvalds and Russel King
-+ * and the GNU C Library
-+ * ( ... I love the GPL ... just take what you need! ;)
-+ *
-+ * 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.
-+ *
-+ * 1.00 2001-06-08 Nicolas Pitre <nico@cam.org>
-+ * - added periodic timer capability using OSMR1
-+ * - flag compatibility with other RTC chips
-+ * - permission checks for ioctls
-+ * - major cleanup, partial rewrite
-+ *
-+ * 0.03 2001-03-07 CIH <cih@coventive.com>
-+ * - Modify the bug setups RTC clock.
-+ *
-+ * 0.02 2001-02-27 Nils Faerber <nils@@kernelconcepts.de>
-+ * - removed mktime(), added alarm irq clear
-+ *
-+ * 0.01 2000-10-01 Nils Faerber <nils@@kernelconcepts.de>
-+ * - initial release
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/fs.h>
-+#include <linux/miscdevice.h>
-+#include <linux/string.h>
-+#include <linux/init.h>
-+#include <linux/poll.h>
-+#include <linux/proc_fs.h>
-+#include <asm/bitops.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <linux/rtc.h>
-+
-+#define DRIVER_VERSION "1.00"
-+
-+#define TIMER_FREQ 3686400
-+
-+#define RTC_DEF_DIVIDER 32768 - 1
-+#define RTC_DEF_TRIM 0
-+
-+/* Those are the bits from a classic RTC we want to mimic */
-+#define RTC_IRQF 0x80 /* any of the following 3 is active */
-+#define RTC_PF 0x40
-+#define RTC_AF 0x20
-+#define RTC_UF 0x10
-+
-+static unsigned long rtc_status;
-+static unsigned long rtc_irq_data;
-+static unsigned long rtc_freq = 1024;
-+
-+static struct fasync_struct *rtc_async_queue;
-+static DECLARE_WAIT_QUEUE_HEAD(rtc_wait);
-+
-+extern spinlock_t rtc_lock;
-+
-+static const unsigned char days_in_mo[] =
-+ {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-+
-+#define is_leap(year) \
-+ ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
-+
-+/*
-+ * Converts seconds since 1970-01-01 00:00:00 to Gregorian date.
-+ */
-+
-+static void decodetime (unsigned long t, struct rtc_time *tval)
-+{
-+ long days, month, year, rem;
-+
-+ days = t / 86400;
-+ rem = t % 86400;
-+ tval->tm_hour = rem / 3600;
-+ rem %= 3600;
-+ tval->tm_min = rem / 60;
-+ tval->tm_sec = rem % 60;
-+ tval->tm_wday = (4 + days) % 7;
-+
-+#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
-+
-+ year = 1970 + days / 365;
-+ days -= ((year - 1970) * 365
-+ + LEAPS_THRU_END_OF (year - 1)
-+ - LEAPS_THRU_END_OF (1970 - 1));
-+ if (days < 0) {
-+ year -= 1;
-+ days += 365 + is_leap(year);
-+ }
-+ tval->tm_year = year - 1900;
-+ tval->tm_yday = days + 1;
-+
-+ month = 0;
-+ if (days >= 31) {
-+ days -= 31;
-+ month++;
-+ if (days >= (28 + is_leap(year))) {
-+ days -= (28 + is_leap(year));
-+ month++;
-+ while (days >= days_in_mo[month]) {
-+ days -= days_in_mo[month];
-+ month++;
-+ }
-+ }
-+ }
-+ tval->tm_mon = month;
-+ tval->tm_mday = days + 1;
-+}
-+
-+static void rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ unsigned int rtsr = RTSR;
-+
-+ /* clear interrupt sources */
-+ RTSR = 0;
-+ RTSR = (RTSR_AL|RTSR_HZ);
-+
-+ /* clear alarm interrupt if it has occurred */
-+ if (rtsr & RTSR_AL)
-+ rtsr &= ~RTSR_ALE;
-+ RTSR = rtsr & (RTSR_ALE|RTSR_HZE);
-+
-+ /* update irq data & counter */
-+ if (rtsr & RTSR_AL)
-+ rtc_irq_data |= (RTC_AF|RTC_IRQF);
-+ if (rtsr & RTSR_HZ)
-+ rtc_irq_data |= (RTC_UF|RTC_IRQF);
-+ rtc_irq_data += 0x100;
-+
-+ /* wake up waiting process */
-+ wake_up_interruptible(&rtc_wait);
-+ kill_fasync (&rtc_async_queue, SIGIO, POLL_IN);
-+}
-+
-+static void timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ /*
-+ * If we match for the first time, the periodic interrupt flag won't
-+ * be set. If it is, then we did wrap around (very unlikely but
-+ * still possible) and compute the amount of missed periods.
-+ * The match reg is updated only when the data is actually retrieved
-+ * to avoid unnecessary interrupts.
-+ */
-+ OSSR = OSSR_M1; /* clear match on timer1 */
-+ if (rtc_irq_data & RTC_PF) {
-+ rtc_irq_data += (rtc_freq * ((1<<30)/(TIMER_FREQ>>2))) << 8;
-+ } else {
-+ rtc_irq_data += (0x100|RTC_PF|RTC_IRQF);
-+ }
-+
-+ wake_up_interruptible(&rtc_wait);
-+ kill_fasync (&rtc_async_queue, SIGIO, POLL_IN);
-+}
-+
-+static int rtc_open(struct inode *inode, struct file *file)
-+{
-+ if (test_and_set_bit (1, &rtc_status))
-+ return -EBUSY;
-+ rtc_irq_data = 0;
-+ return 0;
-+}
-+
-+static int rtc_release(struct inode *inode, struct file *file)
-+{
-+ spin_lock_irq (&rtc_lock);
-+ RTSR = 0;
-+ RTSR = (RTSR_AL|RTSR_HZ);
-+ OIER &= ~OIER_E1;
-+ OSSR = OSSR_M1;
-+ spin_unlock_irq (&rtc_lock);
-+ rtc_status = 0;
-+ return 0;
-+}
-+
-+static int rtc_fasync (int fd, struct file *filp, int on)
-+{
-+ return fasync_helper (fd, filp, on, &rtc_async_queue);
-+}
-+
-+static unsigned int rtc_poll(struct file *file, poll_table *wait)
-+{
-+ poll_wait (file, &rtc_wait, wait);
-+ return (rtc_irq_data) ? 0 : POLLIN | POLLRDNORM;
-+}
-+
-+static loff_t rtc_llseek(struct file *file, loff_t offset, int origin)
-+{
-+ return -ESPIPE;
-+}
-+
-+ssize_t rtc_read(struct file *file, char *buf, size_t count, loff_t *ppos)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ unsigned long data;
-+ ssize_t retval;
-+
-+ if (count < sizeof(unsigned long))
-+ return -EINVAL;
-+
-+ add_wait_queue(&rtc_wait, &wait);
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ for (;;) {
-+ spin_lock_irq (&rtc_lock);
-+ data = rtc_irq_data;
-+ if (data != 0) {
-+ rtc_irq_data = 0;
-+ break;
-+ }
-+ spin_unlock_irq (&rtc_lock);
-+
-+ if (file->f_flags & O_NONBLOCK) {
-+ retval = -EAGAIN;
-+ goto out;
-+ }
-+
-+ if (signal_pending(current)) {
-+ retval = -ERESTARTSYS;
-+ goto out;
-+ }
-+
-+ schedule();
-+ }
-+
-+ if (data & RTC_PF) {
-+ /* interpolate missed periods and set match for the next one */
-+ unsigned long period = TIMER_FREQ/rtc_freq;
-+ unsigned long oscr = OSCR;
-+ unsigned long osmr1 = OSMR1;
-+ unsigned long missed = (oscr - osmr1)/period;
-+ data += missed << 8;
-+ OSSR = OSSR_M1; /* clear match on timer 1 */
-+ OSMR1 = osmr1 + (missed + 1)*period;
-+ /* ensure we didn't miss another match in the mean time */
-+ while( (signed long)((osmr1 = OSMR1) - OSCR) <= 0 ) {
-+ data += 0x100;
-+ OSSR = OSSR_M1; /* clear match on timer 1 */
-+ OSMR1 = osmr1 + period;
-+ }
-+ }
-+ spin_unlock_irq (&rtc_lock);
-+
-+ data -= 0x100; /* the first IRQ wasn't actually missed */
-+
-+ retval = put_user(data, (unsigned long *)buf);
-+ if (!retval)
-+ retval = sizeof(unsigned long);
-+
-+out:
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&rtc_wait, &wait);
-+ return retval;
-+}
-+
-+static int rtc_ioctl(struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ struct rtc_time tm, tm2;
-+
-+ switch (cmd) {
-+ case RTC_AIE_OFF:
-+ spin_lock_irq(&rtc_lock);
-+ RTSR &= ~RTSR_ALE;
-+ rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+ case RTC_AIE_ON:
-+ spin_lock_irq(&rtc_lock);
-+ RTSR |= RTSR_ALE;
-+ rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+ case RTC_UIE_OFF:
-+ spin_lock_irq(&rtc_lock);
-+ RTSR &= ~RTSR_HZE;
-+ rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+ case RTC_UIE_ON:
-+ spin_lock_irq(&rtc_lock);
-+ RTSR |= RTSR_HZE;
-+ rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+ case RTC_PIE_OFF:
-+ spin_lock_irq(&rtc_lock);
-+ OIER &= ~OIER_E1;
-+ rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+ case RTC_PIE_ON:
-+ if ((rtc_freq > 64) && !capable(CAP_SYS_RESOURCE))
-+ return -EACCES;
-+ spin_lock_irq(&rtc_lock);
-+ OSMR1 = TIMER_FREQ/rtc_freq + OSCR;
-+ OIER |= OIER_E1;
-+ rtc_irq_data = 0;
-+ spin_unlock_irq(&rtc_lock);
-+ return 0;
-+ case RTC_ALM_READ:
-+ decodetime (RTAR, &tm);
-+ break;
-+ case RTC_ALM_SET:
-+ if (copy_from_user (&tm2, (struct rtc_time*)arg, sizeof (tm2)))
-+ return -EFAULT;
-+ decodetime (RCNR, &tm);
-+ if ((unsigned)tm2.tm_hour < 24)
-+ tm.tm_hour = tm2.tm_hour;
-+ if ((unsigned)tm2.tm_min < 60)
-+ tm.tm_min = tm2.tm_min;
-+ if ((unsigned)tm2.tm_sec < 60)
-+ tm.tm_sec = tm2.tm_sec;
-+ RTAR = mktime ( tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
-+ tm.tm_hour, tm.tm_min, tm.tm_sec);
-+ return 0;
-+ case RTC_RD_TIME:
-+ decodetime (RCNR, &tm);
-+ break;
-+ case RTC_SET_TIME:
-+ if (!capable(CAP_SYS_TIME))
-+ return -EACCES;
-+ if (copy_from_user (&tm, (struct rtc_time*)arg, sizeof (tm)))
-+ return -EFAULT;
-+ tm.tm_year += 1900;
-+ if (tm.tm_year < 1970 || (unsigned)tm.tm_mon >= 12 ||
-+ tm.tm_mday < 1 || tm.tm_mday > (days_in_mo[tm.tm_mon] +
-+ (tm.tm_mon == 1 && is_leap(tm.tm_year))) ||
-+ (unsigned)tm.tm_hour >= 24 ||
-+ (unsigned)tm.tm_min >= 60 ||
-+ (unsigned)tm.tm_sec >= 60)
-+ return -EINVAL;
-+ RCNR = mktime ( tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
-+ tm.tm_hour, tm.tm_min, tm.tm_sec);
-+ return 0;
-+ case RTC_IRQP_READ:
-+ return put_user(rtc_freq, (unsigned long *)arg);
-+ case RTC_IRQP_SET:
-+ if (arg < 1 || arg > TIMER_FREQ)
-+ return -EINVAL;
-+ if ((arg > 64) && (!capable(CAP_SYS_RESOURCE)))
-+ return -EACCES;
-+ rtc_freq = arg;
-+ return 0;
-+ case RTC_EPOCH_READ:
-+ return put_user (1970, (unsigned long *)arg);
-+ default:
-+ return -EINVAL;
-+ }
-+ return copy_to_user ((void *)arg, &tm, sizeof (tm)) ? -EFAULT : 0;
-+}
-+
-+static struct file_operations rtc_fops = {
-+ owner: THIS_MODULE,
-+ llseek: rtc_llseek,
-+ read: rtc_read,
-+ poll: rtc_poll,
-+ ioctl: rtc_ioctl,
-+ open: rtc_open,
-+ release: rtc_release,
-+ fasync: rtc_fasync,
-+};
-+
-+static struct miscdevice sa1100rtc_miscdev = {
-+ RTC_MINOR,
-+ "rtc",
-+ &rtc_fops
-+};
-+
-+static int rtc_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
-+{
-+ char *p = page;
-+ int len;
-+ struct rtc_time tm;
-+
-+ decodetime (RCNR, &tm);
-+ p += sprintf(p, "rtc_time\t: %02d:%02d:%02d\n"
-+ "rtc_date\t: %04d-%02d-%02d\n"
-+ "rtc_epoch\t: %04d\n",
-+ tm.tm_hour, tm.tm_min, tm.tm_sec,
-+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, 1970);
-+ decodetime (RTAR, &tm);
-+ p += sprintf(p, "alrm_time\t: %02d:%02d:%02d\n"
-+ "alrm_date\t: %04d-%02d-%02d\n",
-+ tm.tm_hour, tm.tm_min, tm.tm_sec,
-+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
-+ p += sprintf(p, "trim/divider\t: 0x%08x\n", RTTR);
-+ p += sprintf(p, "alarm_IRQ\t: %s\n", (RTSR & RTSR_ALE) ? "yes" : "no" );
-+ p += sprintf(p, "update_IRQ\t: %s\n", (RTSR & RTSR_HZE) ? "yes" : "no");
-+ p += sprintf(p, "periodic_IRQ\t: %s\n", (OIER & OIER_E1) ? "yes" : "no");
-+ p += sprintf(p, "periodic_freq\t: %ld\n", rtc_freq);
-+
-+ len = (p - page) - off;
-+ if (len < 0)
-+ len = 0;
-+
-+ *eof = (len <= count) ? 1 : 0;
-+ *start = page + off;
-+
-+ return len;
-+}
-+
-+static int __init rtc_init(void)
-+{
-+ int ret;
-+
-+ misc_register (&sa1100rtc_miscdev);
-+ create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL);
-+ ret = request_irq (IRQ_RTC1Hz, rtc_interrupt, SA_INTERRUPT, "rtc 1Hz", NULL);
-+ if (ret) {
-+ printk (KERN_ERR "rtc: IRQ %d already in use.\n", IRQ_RTC1Hz);
-+ goto IRQ_RTC1Hz_failed;
-+ }
-+ ret = request_irq (IRQ_RTCAlrm, rtc_interrupt, SA_INTERRUPT, "rtc Alrm", NULL);
-+ if (ret) {
-+ printk(KERN_ERR "rtc: IRQ %d already in use.\n", IRQ_RTCAlrm);
-+ goto IRQ_RTCAlrm_failed;
-+ }
-+ ret = request_irq (IRQ_OST1, timer1_interrupt, SA_INTERRUPT, "rtc timer", NULL);
-+ if (ret) {
-+ printk(KERN_ERR "rtc: IRQ %d already in use.\n", IRQ_OST1);
-+ goto IRQ_OST1_failed;
-+ }
-+
-+ printk (KERN_INFO "SA1100 Real Time Clock driver v" DRIVER_VERSION "\n");
-+
-+ /*
-+ * According to the manual we should be able to let RTTR be zero
-+ * and then a default diviser for a 32.768KHz clock is used.
-+ * Apparently this doesn't work, at least for my SA1110 rev 5.
-+ * If the clock divider is uninitialized then reset it to the
-+ * default value to get the 1Hz clock.
-+ */
-+ if (RTTR == 0) {
-+ RTTR = RTC_DEF_DIVIDER + (RTC_DEF_TRIM << 16);
-+ printk (KERN_WARNING "rtc: warning: initializing default clock divider/trim value\n");
-+ /* The current RTC value probably doesn't make sense either */
-+ RCNR = 0;
-+ }
-+
-+ return 0;
-+
-+IRQ_OST1_failed:
-+ free_irq (IRQ_RTCAlrm, NULL);
-+IRQ_RTCAlrm_failed:
-+ free_irq (IRQ_RTC1Hz, NULL);
-+IRQ_RTC1Hz_failed:
-+ remove_proc_entry ("driver/rtc", NULL);
-+ misc_deregister (&sa1100rtc_miscdev);
-+ return ret;
-+}
-+
-+static void __exit rtc_exit(void)
-+{
-+ free_irq (IRQ_OST1, NULL);
-+ free_irq (IRQ_RTCAlrm, NULL);
-+ free_irq (IRQ_RTC1Hz, NULL);
-+ remove_proc_entry ("driver/rtc", NULL);
-+ misc_deregister (&sa1100rtc_miscdev);
-+}
-+
-+module_init(rtc_init);
-+module_exit(rtc_exit);
-+
-+MODULE_AUTHOR("Nils Faerber <nils@@kernelconcepts.de>");
-+MODULE_DESCRIPTION("SA1100 Realtime Clock Driver (RTC)");
-+EXPORT_NO_SYMBOLS;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/sa1100_wdt.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,150 @@
-+/*
-+ * Watchdog driver for the SA11x0
-+ *
-+ * (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
-+ * Based on SoftDog driver by Alan Cox <alan@redhat.com>
-+ *
-+ * 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.
-+ *
-+ * Neither Oleg Drokin nor iXcelerator.com admit liability nor provide
-+ * warranty for any of this software. This material is provided
-+ * "AS-IS" and at no charge.
-+ *
-+ * (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
-+ *
-+ * 27/11/2000 Initial release
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/config.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/fs.h>
-+#include <linux/mm.h>
-+#include <linux/miscdevice.h>
-+#include <linux/watchdog.h>
-+#include <linux/reboot.h>
-+#include <linux/smp_lock.h>
-+#include <linux/init.h>
-+#include <asm/uaccess.h>
-+#include <asm/hardware.h>
-+#include <asm/bitops.h>
-+
-+#define TIMER_MARGIN 60 /* (secs) Default is 1 minute */
-+
-+static int sa1100_margin = TIMER_MARGIN; /* in seconds */
-+static int sa1100wdt_users;
-+static int pre_margin;
-+#ifdef MODULE
-+MODULE_PARM(sa1100_margin,"i");
-+#endif
-+
-+/*
-+ * Allow only one person to hold it open
-+ */
-+
-+static int sa1100dog_open(struct inode *inode, struct file *file)
-+{
-+ if(test_and_set_bit(1,&sa1100wdt_users))
-+ return -EBUSY;
-+ MOD_INC_USE_COUNT;
-+ /* Activate SA1100 Watchdog timer */
-+ pre_margin=3686400 * sa1100_margin;
-+ OSMR3 = OSCR + pre_margin;
-+ OSSR = OSSR_M3;
-+ OWER = OWER_WME;
-+ OIER |= OIER_E3;
-+ return 0;
-+}
-+
-+static int sa1100dog_release(struct inode *inode, struct file *file)
-+{
-+ /*
-+ * Shut off the timer.
-+ * Lock it in if it's a module and we defined ...NOWAYOUT
-+ */
-+ OSMR3 = OSCR + pre_margin;
-+#ifndef CONFIG_WATCHDOG_NOWAYOUT
-+ OIER &= ~OIER_E3;
-+#endif
-+ sa1100wdt_users = 0;
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static ssize_t sa1100dog_write(struct file *file, const char *data, size_t len, loff_t *ppos)
-+{
-+ /* Can't seek (pwrite) on this device */
-+ if (ppos != &file->f_pos)
-+ return -ESPIPE;
-+
-+ /* Refresh OSMR3 timer. */
-+ if(len) {
-+ OSMR3 = OSCR + pre_margin;
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+static int sa1100dog_ioctl(struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ static struct watchdog_info ident = {
-+ identity: "SA1100 Watchdog",
-+ };
-+
-+ switch(cmd){
-+ default:
-+ return -ENOIOCTLCMD;
-+ case WDIOC_GETSUPPORT:
-+ return copy_to_user((struct watchdog_info *)arg, &ident, sizeof(ident));
-+ case WDIOC_GETSTATUS:
-+ return put_user(0,(int *)arg);
-+ case WDIOC_GETBOOTSTATUS:
-+ return put_user((RCSR & RCSR_WDR) ? WDIOF_CARDRESET : 0, (int *)arg);
-+ case WDIOC_KEEPALIVE:
-+ OSMR3 = OSCR + pre_margin;
-+ return 0;
-+ }
-+}
-+
-+static struct file_operations sa1100dog_fops=
-+{
-+ owner: THIS_MODULE,
-+ write: sa1100dog_write,
-+ ioctl: sa1100dog_ioctl,
-+ open: sa1100dog_open,
-+ release: sa1100dog_release,
-+};
-+
-+static struct miscdevice sa1100dog_miscdev=
-+{
-+ WATCHDOG_MINOR,
-+ "SA1100 watchdog",
-+ &sa1100dog_fops
-+};
-+
-+static int __init sa1100dog_init(void)
-+{
-+ int ret;
-+
-+ ret = misc_register(&sa1100dog_miscdev);
-+
-+ if (ret)
-+ return ret;
-+
-+ printk("SA1100 Watchdog Timer: timer margin %d sec\n", sa1100_margin);
-+
-+ return 0;
-+}
-+
-+static void __exit sa1100dog_exit(void)
-+{
-+ misc_deregister(&sa1100dog_miscdev);
-+}
-+
-+module_init(sa1100dog_init);
-+module_exit(sa1100dog_exit);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/char/sa1111_keyb.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,1153 @@
-+/*
-+ * SA1111 PS/2 keyboard/mouse driver
-+ *
-+ * 2000 by VASARA RESEARCH INC.
-+ *
-+ * Changelog:
-+ * Jun.xx,2000: Kunihiko IMAI <imai@vasara.co.jp>
-+ * Port to 2.4.0test1-ac19-rmk1-np1
-+ * Apr.17,2000: Takafumi Kawana <kawana@pro.or.jp>
-+ * Internal Release for XP860
-+ *
-+ *
-+ * This driver is based on linux/drivers/char/pc_keyb.c
-+ * Original declaration follows:
-+
-+ *
-+ * linux/drivers/char/pc_keyb.c
-+ *
-+ * Separation of the PC low-level part by Geert Uytterhoeven, May 1997
-+ * See keyboard.c for the whole history.
-+ *
-+ * Major cleanup by Martin Mares, May 1997
-+ *
-+ * Combined the keyboard and PS/2 mouse handling into one file,
-+ * because they share the same hardware.
-+ * Johan Myreen <jem@iki.fi> 1998-10-08.
-+ *
-+ * Code fixes to handle mouse ACKs properly.
-+ * C. Scott Ananian <cananian@alumni.princeton.edu> 1999-01-29.
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/spinlock.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/tty.h>
-+#include <linux/mm.h>
-+#include <linux/signal.h>
-+#include <linux/init.h>
-+#include <linux/kbd_ll.h>
-+#include <linux/delay.h>
-+#include <linux/random.h>
-+#include <linux/poll.h>
-+#include <linux/miscdevice.h>
-+#include <linux/slab.h>
-+#include <linux/kbd_kern.h>
-+#include <linux/ioport.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/bitops.h>
-+#include <asm/uaccess.h>
-+#include <asm/irq.h>
-+#include <asm/system.h>
-+
-+#include <asm/io.h>
-+
-+/* Some configuration switches are present in the include file... */
-+
-+#include <linux/pc_keyb.h>
-+#include <asm/keyboard.h>
-+#include <asm/hardware/sa1111.h>
-+
-+#define KBD_STAT_RXB (1<<4)
-+#define KBD_STAT_RXF (1<<5)
-+#define KBD_STAT_TXB (1<<6)
-+#define KBD_STAT_TXE (1<<7)
-+#define KBD_STAT_STP (1<<8)
-+
-+#define MSE_STAT_RXB (1<<4)
-+#define MSE_STAT_RXF (1<<5)
-+#define MSE_STAT_TXB (1<<6)
-+#define MSE_STAT_TXE (1<<7)
-+#define MSE_STAT_STP (1<<8)
-+
-+/* Simple translation table for the SysRq keys */
-+
-+#ifdef CONFIG_MAGIC_SYSRQ
-+unsigned char sa1111_sysrq_xlate[128] = "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
-+ "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
-+ "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
-+ "bnm,./\000*\000 \000\201\202\203\204\205" /* 0x30 - 0x3f */
-+ "\206\207\210\211\212\000\000789-456+1" /* 0x40 - 0x4f */
-+ "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
-+ "\r\000/"; /* 0x60 - 0x6f */
-+#endif
-+
-+// static void kbd_write_command_w(int data);
-+static void kbd_write_output_w(int data);
-+
-+spinlock_t kbd_controller_lock = SPIN_LOCK_UNLOCKED;
-+static void handle_kbd_event(void);
-+
-+/* used only by send_data - set by keyboard_interrupt */
-+static volatile unsigned char reply_expected = 0;
-+static volatile unsigned char acknowledge = 0;
-+static volatile unsigned char resend = 0;
-+
-+
-+#if defined CONFIG_PSMOUSE
-+/*
-+ * PS/2 Auxiliary Device
-+ */
-+
-+static int __init psaux_init(void);
-+
-+static struct aux_queue *queue; /* Mouse data buffer. */
-+static int aux_count = 0;
-+/* used when we send commands to the mouse that expect an ACK. */
-+static unsigned char mouse_reply_expected = 0;
-+
-+#define AUX_INTS_OFF (KBD_MODE_KCC | KBD_MODE_DISABLE_MOUSE | KBD_MODE_SYS | KBD_MODE_KBD_INT)
-+#define AUX_INTS_ON (KBD_MODE_KCC | KBD_MODE_SYS | KBD_MODE_MOUSE_INT | KBD_MODE_KBD_INT)
-+
-+#define MAX_RETRIES 60 /* some aux operations take long time */
-+#endif /* CONFIG_PSMOUSE */
-+
-+/*
-+ * Wait for keyboard controller input buffer to drain.
-+ *
-+ * Don't use 'jiffies' so that we don't depend on
-+ * interrupts..
-+ *
-+ * Quote from PS/2 System Reference Manual:
-+ *
-+ * "Address hex 0060 and address hex 0064 should be written only when
-+ * the input-buffer-full bit and output-buffer-full bit in the
-+ * Controller Status register are set 0."
-+ */
-+
-+static void kb_wait(void)
-+{
-+ unsigned long timeout = KBC_TIMEOUT;
-+
-+ do {
-+ /*
-+ * "handle_kbd_event()" will handle any incoming events
-+ * while we wait - keypresses or mouse movement.
-+ */
-+ handle_kbd_event();
-+ if (KBDSTAT & KBD_STAT_TXE)
-+ return;
-+ mdelay(1);
-+ timeout--;
-+ }
-+ while (timeout);
-+#ifdef KBD_REPORT_TIMEOUTS
-+ printk(KERN_WARNING "Keyboard timed out[1]\n");
-+#endif
-+}
-+
-+/*
-+ * Translation of escaped scancodes to keycodes.
-+ * This is now user-settable.
-+ * The keycodes 1-88,96-111,119 are fairly standard, and
-+ * should probably not be changed - changing might confuse X.
-+ * X also interprets scancode 0x5d (KEY_Begin).
-+ *
-+ * For 1-88 keycode equals scancode.
-+ */
-+
-+#define E0_KPENTER 96
-+#define E0_RCTRL 97
-+#define E0_KPSLASH 98
-+#define E0_PRSCR 99
-+#define E0_RALT 100
-+#define E0_BREAK 101 /* (control-pause) */
-+#define E0_HOME 102
-+#define E0_UP 103
-+#define E0_PGUP 104
-+#define E0_LEFT 105
-+#define E0_RIGHT 106
-+#define E0_END 107
-+#define E0_DOWN 108
-+#define E0_PGDN 109
-+#define E0_INS 110
-+#define E0_DEL 111
-+
-+/* for USB 106 keyboard */
-+#define E0_YEN 124
-+#define E0_BACKSLASH 89
-+
-+
-+#define E1_PAUSE 119
-+
-+/*
-+ * The keycodes below are randomly located in 89-95,112-118,120-127.
-+ * They could be thrown away (and all occurrences below replaced by 0),
-+ * but that would force many users to use the `setkeycodes' utility, where
-+ * they needed not before. It does not matter that there are duplicates, as
-+ * long as no duplication occurs for any single keyboard.
-+ */
-+#define SC_LIM 89
-+
-+#define FOCUS_PF1 85 /* actual code! */
-+#define FOCUS_PF2 89
-+#define FOCUS_PF3 90
-+#define FOCUS_PF4 91
-+#define FOCUS_PF5 92
-+#define FOCUS_PF6 93
-+#define FOCUS_PF7 94
-+#define FOCUS_PF8 95
-+#define FOCUS_PF9 120
-+#define FOCUS_PF10 121
-+#define FOCUS_PF11 122
-+#define FOCUS_PF12 123
-+
-+#define JAP_86 124
-+/* tfj@olivia.ping.dk:
-+ * The four keys are located over the numeric keypad, and are
-+ * labelled A1-A4. It's an rc930 keyboard, from
-+ * Regnecentralen/RC International, Now ICL.
-+ * Scancodes: 59, 5a, 5b, 5c.
-+ */
-+#define RGN1 124
-+#define RGN2 125
-+#define RGN3 126
-+#define RGN4 127
-+
-+static unsigned char high_keys[128 - SC_LIM] = {
-+ RGN1, RGN2, RGN3, RGN4, 0, 0, 0, /* 0x59-0x5f */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
-+ 0, 0, 0, 0, 0, FOCUS_PF11, 0, FOCUS_PF12, /* 0x68-0x6f */
-+ 0, 0, 0, FOCUS_PF2, FOCUS_PF9, 0, 0, FOCUS_PF3, /* 0x70-0x77 */
-+ FOCUS_PF4, FOCUS_PF5, FOCUS_PF6, FOCUS_PF7, /* 0x78-0x7b */
-+ FOCUS_PF8, JAP_86, FOCUS_PF10, 0 /* 0x7c-0x7f */
-+};
-+
-+/* BTC */
-+#define E0_MACRO 112
-+/* LK450 */
-+#define E0_F13 113
-+#define E0_F14 114
-+#define E0_HELP 115
-+#define E0_DO 116
-+#define E0_F17 117
-+#define E0_KPMINPLUS 118
-+/*
-+ * My OmniKey generates e0 4c for the "OMNI" key and the
-+ * right alt key does nada. [kkoller@nyx10.cs.du.edu]
-+ */
-+#define E0_OK 124
-+/*
-+ * New microsoft keyboard is rumoured to have
-+ * e0 5b (left window button), e0 5c (right window button),
-+ * e0 5d (menu button). [or: LBANNER, RBANNER, RMENU]
-+ * [or: Windows_L, Windows_R, TaskMan]
-+ */
-+#define E0_MSLW 125
-+#define E0_MSRW 126
-+#define E0_MSTM 127
-+
-+static unsigned char e0_keys[128] = {
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00-0x07 */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08-0x0f */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10-0x17 */
-+ 0, 0, 0, 0, E0_KPENTER, E0_RCTRL, 0, 0, /* 0x18-0x1f */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20-0x27 */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28-0x2f */
-+ 0, 0, 0, 0, 0, E0_KPSLASH, 0, E0_PRSCR, /* 0x30-0x37 */
-+ E0_RALT, 0, 0, 0, 0, E0_F13, E0_F14, E0_HELP, /* 0x38-0x3f */
-+ E0_DO, E0_F17, 0, 0, 0, 0, E0_BREAK, E0_HOME, /* 0x40-0x47 */
-+ E0_UP, E0_PGUP, 0, E0_LEFT, E0_OK, E0_RIGHT, E0_KPMINPLUS, E0_END, /* 0x48-0x4f */
-+ E0_DOWN, E0_PGDN, E0_INS, E0_DEL, 0, 0, 0, 0, /* 0x50-0x57 */
-+ 0, 0, 0, E0_MSLW, E0_MSRW, E0_MSTM, 0, 0, /* 0x58-0x5f */
-+ 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60-0x67 */
-+ 0, 0, 0, 0, 0, 0, 0, E0_MACRO, /* 0x68-0x6f */
-+ //0, 0, 0, 0, 0, 0, 0, 0, /* 0x70-0x77 */
-+ 0, 0, 0, 0, 0, E0_BACKSLASH, 0, 0, /* 0x70-0x77 */
-+ 0, 0, 0, E0_YEN, 0, 0, 0, 0 /* 0x78-0x7f */
-+};
-+
-+int sa1111_setkeycode(unsigned int scancode, unsigned int keycode)
-+{
-+ if (scancode < SC_LIM || scancode > 255 || keycode > 127)
-+ return -EINVAL;
-+ if (scancode < 128)
-+ high_keys[scancode - SC_LIM] = keycode;
-+ else
-+ e0_keys[scancode - 128] = keycode;
-+ return 0;
-+}
-+
-+int sa1111_getkeycode(unsigned int scancode)
-+{
-+ return
-+ (scancode < SC_LIM || scancode > 255) ? -EINVAL :
-+ (scancode <
-+ 128) ? high_keys[scancode - SC_LIM] : e0_keys[scancode - 128];
-+}
-+
-+static int do_acknowledge(unsigned char scancode)
-+{
-+ if (reply_expected) {
-+ /* Unfortunately, we must recognise these codes only if we know they
-+ * are known to be valid (i.e., after sending a command), because there
-+ * are some brain-damaged keyboards (yes, FOCUS 9000 again) which have
-+ * keys with such codes :(
-+ */
-+ if (scancode == KBD_REPLY_ACK) {
-+ acknowledge = 1;
-+ reply_expected = 0;
-+ return 0;
-+ } else if (scancode == KBD_REPLY_RESEND) {
-+ resend = 1;
-+ reply_expected = 0;
-+ return 0;
-+ }
-+ /* Should not happen... */
-+#if 0
-+ printk(KERN_DEBUG "keyboard reply expected - got %02x\n",
-+ scancode);
-+#endif
-+ }
-+ return 1;
-+}
-+
-+int
-+sa1111_translate(unsigned char scancode, unsigned char *keycode,
-+ char raw_mode)
-+{
-+ static int prev_scancode = 0;
-+
-+ /* special prefix scancodes.. */
-+ if (scancode == 0xe0 || scancode == 0xe1) {
-+ prev_scancode = scancode;
-+ return 0;
-+ }
-+
-+ /* 0xFF is sent by a few keyboards, ignore it. 0x00 is error */
-+ if (scancode == 0x00 || scancode == 0xff) {
-+ prev_scancode = 0;
-+ return 0;
-+ }
-+
-+ scancode &= 0x7f;
-+
-+ if (prev_scancode) {
-+ /*
-+ * usually it will be 0xe0, but a Pause key generates
-+ * e1 1d 45 e1 9d c5 when pressed, and nothing when released
-+ */
-+ if (prev_scancode != 0xe0) {
-+ if (prev_scancode == 0xe1 && scancode == 0x1d) {
-+ prev_scancode = 0x100;
-+ return 0;
-+ }
-+ else if (prev_scancode == 0x100
-+ && scancode == 0x45) {
-+ *keycode = E1_PAUSE;
-+ prev_scancode = 0;
-+ } else {
-+#ifdef KBD_REPORT_UNKN
-+ if (!raw_mode)
-+ printk(KERN_INFO
-+ "keyboard: unknown e1 escape sequence\n");
-+#endif
-+ prev_scancode = 0;
-+ return 0;
-+ }
-+ } else {
-+ prev_scancode = 0;
-+ /*
-+ * The keyboard maintains its own internal caps lock and
-+ * num lock statuses. In caps lock mode E0 AA precedes make
-+ * code and E0 2A follows break code. In num lock mode,
-+ * E0 2A precedes make code and E0 AA follows break code.
-+ * We do our own book-keeping, so we will just ignore these.
-+ */
-+ /*
-+ * For my keyboard there is no caps lock mode, but there are
-+ * both Shift-L and Shift-R modes. The former mode generates
-+ * E0 2A / E0 AA pairs, the latter E0 B6 / E0 36 pairs.
-+ * So, we should also ignore the latter. - aeb@cwi.nl
-+ */
-+ if (scancode == 0x2a || scancode == 0x36)
-+ return 0;
-+
-+ if (e0_keys[scancode])
-+ *keycode = e0_keys[scancode];
-+ else {
-+#ifdef KBD_REPORT_UNKN
-+ if (!raw_mode)
-+ printk(KERN_INFO
-+ "keyboard: unknown scancode e0 %02x\n",
-+ scancode);
-+#endif
-+ return 0;
-+ }
-+ }
-+ } else if (scancode >= SC_LIM) {
-+ /* This happens with the FOCUS 9000 keyboard
-+ Its keys PF1..PF12 are reported to generate
-+ 55 73 77 78 79 7a 7b 7c 74 7e 6d 6f
-+ Moreover, unless repeated, they do not generate
-+ key-down events, so we have to zero up_flag below */
-+ /* Also, Japanese 86/106 keyboards are reported to
-+ generate 0x73 and 0x7d for \ - and \ | respectively. */
-+ /* Also, some Brazilian keyboard is reported to produce
-+ 0x73 and 0x7e for \ ? and KP-dot, respectively. */
-+
-+ *keycode = high_keys[scancode - SC_LIM];
-+
-+ if (!*keycode) {
-+ if (!raw_mode) {
-+#ifdef KBD_REPORT_UNKN
-+ printk(KERN_INFO
-+ "keyboard: unrecognized scancode (%02x)"
-+ " - ignored\n", scancode);
-+#endif
-+ }
-+ return 0;
-+ }
-+ } else
-+ *keycode = scancode;
-+ return 1;
-+}
-+
-+char sa1111_unexpected_up(unsigned char keycode)
-+{
-+ /* unexpected, but this can happen: maybe this was a key release for a
-+ FOCUS 9000 PF key; if we want to see it, we have to clear up_flag */
-+ if (keycode >= SC_LIM || keycode == 85)
-+ return 0;
-+ else
-+ return 0200;
-+}
-+
-+static unsigned char kbd_exists = 1;
-+
-+static inline void handle_keyboard_event(unsigned char scancode)
-+{
-+#ifdef CONFIG_VT
-+ kbd_exists = 1;
-+ if (do_acknowledge(scancode))
-+ handle_scancode(scancode, !(scancode & 0x80));
-+#endif
-+ tasklet_schedule(&keyboard_tasklet);
-+}
-+
-+/*
-+ * This reads the keyboard status port, and does the
-+ * appropriate action.
-+ *
-+ * It requires that we hold the keyboard controller
-+ * spinlock.
-+ */
-+static void handle_kbd_event(void)
-+{
-+ unsigned int status = KBDSTAT;
-+ unsigned int work = 10000;
-+ unsigned char scancode;
-+
-+ while (status & KBD_STAT_RXF) {
-+ while (status & KBD_STAT_RXF) {
-+ scancode = KBDDATA & 0xff;
-+ if (!(status & KBD_STAT_STP))
-+ handle_keyboard_event(scancode);
-+ if (!--work) {
-+ printk(KERN_ERR
-+ "pc_keyb: keyboard controller jammed (0x%02X).\n",
-+ status);
-+ return;
-+ }
-+ status = KBDSTAT;
-+ }
-+ work = 10000;
-+ }
-+
-+ if (status & KBD_STAT_STP)
-+ KBDSTAT = KBD_STAT_STP;
-+}
-+
-+static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ unsigned long flags;
-+
-+#ifdef CONFIG_VT
-+ kbd_pt_regs = regs;
-+#endif
-+ spin_lock_irqsave(&kbd_controller_lock, flags);
-+ handle_kbd_event();
-+ spin_unlock_irqrestore(&kbd_controller_lock, flags);
-+}
-+
-+/*
-+ * send_data sends a character to the keyboard and waits
-+ * for an acknowledge, possibly retrying if asked to. Returns
-+ * the success status.
-+ *
-+ * Don't use 'jiffies', so that we don't depend on interrupts
-+ */
-+static int send_data(unsigned char data)
-+{
-+ int retries = 3;
-+
-+ do {
-+ unsigned long timeout = KBD_TIMEOUT;
-+
-+ acknowledge = 0; /* Set by interrupt routine on receipt of ACK. */
-+ resend = 0;
-+ reply_expected = 1;
-+ kbd_write_output_w(data);
-+ for (;;) {
-+ if (acknowledge)
-+ return 1;
-+ if (resend)
-+ break;
-+ mdelay(1);
-+ if (!--timeout) {
-+#ifdef KBD_REPORT_TIMEOUTS
-+ printk(KERN_WARNING
-+ "keyboard: Timeout - AT keyboard not present?\n");
-+#endif
-+ return 0;
-+ }
-+ }
-+ }
-+ while (retries-- > 0);
-+#ifdef KBD_REPORT_TIMEOUTS
-+ printk(KERN_WARNING
-+ "keyboard: Too many NACKs -- noisy kbd cable?\n");
-+#endif
-+ return 0;
-+}
-+
-+void sa1111_leds(unsigned char leds)
-+{
-+ if (kbd_exists
-+ && (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds))) {
-+ send_data(KBD_CMD_ENABLE); /* re-enable kbd if any errors */
-+ kbd_exists = 0;
-+ }
-+}
-+
-+#define KBD_NO_DATA (-1) /* No data */
-+#define KBD_BAD_DATA (-2) /* Parity or other error */
-+
-+static int __init kbd_read_data(void)
-+{
-+ int retval = KBD_NO_DATA;
-+ unsigned int status;
-+
-+ status = KBDSTAT;
-+ if (status & KBD_STAT_RXF) {
-+ unsigned char data = KBDDATA;
-+
-+ retval = data;
-+ if (status & KBD_STAT_STP)
-+ retval = KBD_BAD_DATA;
-+ }
-+ return retval;
-+}
-+
-+static void __init kbd_clear_input(void)
-+{
-+ int maxread = 100; /* Random number */
-+
-+ do {
-+ if (kbd_read_data() == KBD_NO_DATA)
-+ break;
-+ }
-+ while (--maxread);
-+}
-+
-+static int __init kbd_wait_for_input(void)
-+{
-+ long timeout = KBD_INIT_TIMEOUT;
-+
-+ do {
-+ int retval = kbd_read_data();
-+ if (retval >= 0)
-+ return retval;
-+ mdelay(1);
-+ }
-+ while (--timeout);
-+ return -1;
-+}
-+
-+#if 0
-+static void kbd_write_command_w(int data)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&kbd_controller_lock, flags);
-+ kb_wait();
-+ kbd_write_command(data);
-+ spin_unlock_irqrestore(&kbd_controller_lock, flags);
-+}
-+#endif
-+
-+static void kbd_write_output_w(int data)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&kbd_controller_lock, flags);
-+ kb_wait();
-+ KBDDATA = data & 0xff;
-+ spin_unlock_irqrestore(&kbd_controller_lock, flags);
-+}
-+
-+/*
-+ * Test the keyboard interface. We basically check to make sure that
-+ * we can drive each line to the keyboard independently of each other.
-+ */
-+static int kbdif_test(void)
-+{
-+ int ret = 0;
-+
-+ KBDCR = KBDCR_ENA | KBDCR_FKC;
-+ udelay(2);
-+ if ((KBDSTAT & (KBDSTAT_KBC | KBDSTAT_KBD)) != KBDSTAT_KBD) {
-+ printk("Keyboard interface test failed[1]: %02x\n",
-+ KBDSTAT);
-+ ret = -ENODEV;
-+ }
-+
-+ KBDCR = KBDCR_ENA;
-+ udelay(2);
-+ if ((KBDSTAT & (KBDSTAT_KBC | KBDSTAT_KBD)) != (KBDSTAT_KBC | KBDSTAT_KBD)) {
-+ printk("Keyboard interface test failed[2]: %02x\n",
-+ KBDSTAT);
-+ ret = -ENODEV;
-+ }
-+
-+ KBDCR = KBDCR_ENA | KBDCR_FKD;
-+ udelay(2);
-+ if ((KBDSTAT & (KBDSTAT_KBC | KBDSTAT_KBD)) != KBDSTAT_KBC) {
-+ printk("Keyboard interface test failed[3]: %02x\n",
-+ KBDSTAT);
-+ ret = -ENODEV;
-+ }
-+
-+ return ret;
-+}
-+
-+static char *__init initialize_kbd(void)
-+{
-+ int status;
-+
-+ /*
-+ * Test the keyboard interface.
-+ */
-+ kbdif_test();
-+
-+ /*
-+ * Ok, drop the force low bits, and wait a while,
-+ * and clear the stop bit error flag.
-+ */
-+ KBDCR = KBDCR_ENA;
-+ udelay(4);
-+ KBDSTAT = KBD_STAT_STP;
-+
-+ /*
-+ * Ok, we're now ready to talk to the keyboard. Reset
-+ * it, just to make sure we're starting in a sane state.
-+ *
-+ * Set up to try again if the keyboard asks for RESEND.
-+ */
-+ do {
-+ KBDDATA = KBD_CMD_RESET;
-+ status = kbd_wait_for_input();
-+ if (status == KBD_REPLY_ACK)
-+ break;
-+ if (status != KBD_REPLY_RESEND)
-+ return "Keyboard reset failed, no ACK";
-+ } while (1);
-+
-+ if (kbd_wait_for_input() != KBD_REPLY_POR)
-+ return "Keyboard reset failed, no POR";
-+
-+ /*
-+ * Set keyboard controller mode. During this, the keyboard should be
-+ * in the disabled state.
-+ *
-+ * Set up to try again if the keyboard asks for RESEND.
-+ */
-+ do {
-+ kbd_write_output_w(KBD_CMD_DISABLE);
-+ status = kbd_wait_for_input();
-+ if (status == KBD_REPLY_ACK)
-+ break;
-+ if (status != KBD_REPLY_RESEND)
-+ return "Disable keyboard: no ACK";
-+ } while (1);
-+
-+#if 0 /*@@@ */
-+ kbd_write_command_w(KBD_CCMD_WRITE_MODE);
-+ kbd_write_output_w(KBD_MODE_KBD_INT
-+ | KBD_MODE_SYS | KBD_MODE_DISABLE_MOUSE |
-+ KBD_MODE_KCC);
-+
-+ /* ibm powerpc portables need this to use scan-code set 1 -- Cort */
-+ kbd_write_command_w(KBD_CCMD_READ_MODE);
-+ if (!(kbd_wait_for_input() & KBD_MODE_KCC)) {
-+ /*
-+ * If the controller does not support conversion,
-+ * Set the keyboard to scan-code set 1.
-+ */
-+ kbd_write_output_w(0xF0);
-+ kbd_wait_for_input();
-+ kbd_write_output_w(0x01);
-+ kbd_wait_for_input();
-+ }
-+#else
-+ kbd_write_output_w(0xf0);
-+ kbd_wait_for_input();
-+ kbd_write_output_w(0x01);
-+ kbd_wait_for_input();
-+#endif
-+
-+
-+ kbd_write_output_w(KBD_CMD_ENABLE);
-+ if (kbd_wait_for_input() != KBD_REPLY_ACK)
-+ return "Enable keyboard: no ACK";
-+
-+ /*
-+ * Finally, set the typematic rate to maximum.
-+ */
-+ kbd_write_output_w(KBD_CMD_SET_RATE);
-+ if (kbd_wait_for_input() != KBD_REPLY_ACK)
-+ return "Set rate: no ACK";
-+ kbd_write_output_w(0x00);
-+ if (kbd_wait_for_input() != KBD_REPLY_ACK)
-+ return "Set rate: no ACK";
-+
-+ return NULL;
-+}
-+
-+int __init sa1111_kbd_init_hw(void)
-+{
-+ char *msg;
-+ int ret;
-+
-+ if (!request_mem_region(_KBDCR, 512, "keyboard"))
-+ return -EBUSY;
-+
-+ SKPCR |= SKPCR_PTCLKEN;
-+ KBDCLKDIV = 0;
-+ KBDPRECNT = 127;
-+
-+ /* Flush any pending input. */
-+ kbd_clear_input();
-+
-+ msg = initialize_kbd();
-+ if (msg)
-+ printk(KERN_WARNING "initialize_kbd: %s\n", msg);
-+
-+#if defined CONFIG_PSMOUSE
-+ psaux_init();
-+#endif
-+
-+ k_setkeycode = sa1111_setkeycode;
-+ k_getkeycode = sa1111_getkeycode;
-+ k_translate = sa1111_translate;
-+ k_unexpected_up = sa1111_unexpected_up;
-+ k_leds = sa1111_leds;
-+#ifdef CONFIG_MAGIC_SYSRQ
-+ k_sysrq_xlate = sa1111_sysrq_xlate;
-+ k_sysrq_key = 0x54;
-+#endif
-+
-+ /* Ok, finally allocate the IRQ, and off we go.. */
-+ ret = request_irq(IRQ_TPRXINT, keyboard_interrupt, 0, "keyboard", NULL);
-+ if (ret)
-+ release_mem_region(_KBDCR, 512);
-+
-+ return ret;
-+}
-+
-+#if defined CONFIG_PSMOUSE
-+
-+static inline void handle_mouse_event(unsigned char scancode)
-+{
-+ if (mouse_reply_expected) {
-+ if (scancode == AUX_ACK) {
-+ mouse_reply_expected--;
-+ return;
-+ }
-+ mouse_reply_expected = 0;
-+ }
-+
-+ add_mouse_randomness(scancode);
-+ if (aux_count) {
-+ int head = queue->head;
-+
-+ queue->buf[head] = scancode;
-+ head = (head + 1) & (AUX_BUF_SIZE - 1);
-+ if (head != queue->tail) {
-+ queue->head = head;
-+ if (queue->fasync)
-+ kill_fasync(&queue->fasync, SIGIO,
-+ POLL_IN);
-+ wake_up_interruptible(&queue->proc_list);
-+ }
-+ }
-+}
-+
-+static void handle_mse_event(void)
-+{
-+ unsigned int msests = MSESTAT;
-+ unsigned int work = 10000;
-+ unsigned char scancode;
-+
-+ while (msests & MSE_STAT_RXF) {
-+ while (msests & MSE_STAT_RXF) {
-+ scancode = MSEDATA & 0xff;
-+ if (!(msests & MSE_STAT_STP))
-+ handle_mouse_event(scancode);
-+ if (!--work) {
-+ printk(KERN_ERR
-+ "pc_keyb: mouse controller jammed (0x%02X).\n",
-+ msests);
-+ return;
-+ /*XXX*/}
-+ msests = MSESTAT;
-+ }
-+ work = 10000;
-+ }
-+}
-+
-+static void ms_wait(void)
-+{
-+ unsigned long timeout = KBC_TIMEOUT;
-+
-+ do {
-+ /*
-+ * "handle_kbd_event()" will handle any incoming events
-+ * while we wait - keypresses or mouse movement.
-+ */
-+ handle_mse_event();
-+ if (MSESTAT & MSE_STAT_TXE)
-+ return;
-+ mdelay(1);
-+ timeout--;
-+ }
-+ while (timeout);
-+#ifdef KBD_REPORT_TIMEOUTS
-+ printk(KERN_WARNING "Mouse timed out[1]\n");
-+#endif
-+}
-+
-+static void mouse_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&kbd_controller_lock, flags);
-+ handle_mse_event();
-+ spin_unlock_irqrestore(&kbd_controller_lock, flags);
-+}
-+
-+/*
-+ * Check if this is a dual port controller.
-+ */
-+static int __init detect_auxiliary_port(void)
-+{
-+ unsigned long flags;
-+ int loops = 10;
-+ int retval = 0;
-+
-+ /* Check if the BIOS detected a device on the auxiliary port. */
-+ if (aux_device_present == 0xaa)
-+ return 1;
-+
-+ spin_lock_irqsave(&kbd_controller_lock, flags);
-+
-+ /* Put the value 0x5A in the output buffer using the "Write
-+ * Auxiliary Device Output Buffer" command (0xD3). Poll the
-+ * Status Register for a while to see if the value really
-+ * turns up in the Data Register. If the KBD_STAT_MOUSE_OBF
-+ * bit is also set to 1 in the Status Register, we assume this
-+ * controller has an Auxiliary Port (a.k.a. Mouse Port).
-+ */
-+ // kb_wait();
-+ // kbd_write_command(KBD_CCMD_WRITE_AUX_OBUF);
-+
-+ SKPCR |= SKPCR_PMCLKEN;
-+
-+ MSECLKDIV = 0;
-+ MSEPRECNT = 127;
-+ MSECR = MSECR_ENA;
-+ mdelay(50);
-+ MSEDATA = 0xf4;
-+ mdelay(50);
-+
-+ do {
-+ unsigned int msests = MSESTAT;
-+
-+ if (msests & MSE_STAT_RXF) {
-+ do {
-+ msests = MSEDATA; /* dummy read */
-+ mdelay(50);
-+ msests = MSESTAT;
-+ }
-+ while (msests & MSE_STAT_RXF);
-+ printk(KERN_INFO "Detected PS/2 Mouse Port.\n");
-+ retval = 1;
-+ break;
-+ }
-+ mdelay(1);
-+ }
-+ while (--loops);
-+ spin_unlock_irqrestore(&kbd_controller_lock, flags);
-+
-+ return retval;
-+}
-+
-+/*
-+ * Send a byte to the mouse.
-+ */
-+static void aux_write_dev(int val)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&kbd_controller_lock, flags);
-+ // kb_wait();
-+ // kbd_write_command(KBD_CCMD_WRITE_MOUSE);
-+ ms_wait();
-+ MSEDATA = val;
-+ spin_unlock_irqrestore(&kbd_controller_lock, flags);
-+}
-+
-+/*
-+ * Send a byte to the mouse & handle returned ack
-+ */
-+static void aux_write_ack(int val)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&kbd_controller_lock, flags);
-+ // kb_wait();
-+ // kbd_write_command(KBD_CCMD_WRITE_MOUSE);
-+ ms_wait();
-+ MSEDATA = val;
-+ /* we expect an ACK in response. */
-+ mouse_reply_expected++;
-+ ms_wait();
-+ spin_unlock_irqrestore(&kbd_controller_lock, flags);
-+}
-+
-+static unsigned char get_from_queue(void)
-+{
-+ unsigned char result;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&kbd_controller_lock, flags);
-+ result = queue->buf[queue->tail];
-+ queue->tail = (queue->tail + 1) & (AUX_BUF_SIZE - 1);
-+ spin_unlock_irqrestore(&kbd_controller_lock, flags);
-+ return result;
-+}
-+
-+
-+static inline int queue_empty(void)
-+{
-+ return queue->head == queue->tail;
-+}
-+
-+static int fasync_aux(int fd, struct file *filp, int on)
-+{
-+ int retval;
-+
-+ retval = fasync_helper(fd, filp, on, &queue->fasync);
-+ if (retval < 0)
-+ return retval;
-+ return 0;
-+}
-+
-+
-+/*
-+ * Random magic cookie for the aux device
-+ */
-+#define AUX_DEV ((void *)queue)
-+
-+static int release_aux(struct inode *inode, struct file *file)
-+{
-+ fasync_aux(-1, file, 0);
-+ if (--aux_count)
-+ return 0;
-+ // kbd_write_cmd(AUX_INTS_OFF); /* Disable controller ints */
-+ // kbd_write_command_w(KBD_CCMD_MOUSE_DISABLE);
-+ aux_write_ack(AUX_DISABLE_DEV); /* Disable aux device */
-+ MSECR &= ~MSECR_ENA;
-+ free_irq(IRQ_MSRXINT, AUX_DEV);
-+ return 0;
-+}
-+
-+/*
-+ * Install interrupt handler.
-+ * Enable auxiliary device.
-+ */
-+
-+static int open_aux(struct inode *inode, struct file *file)
-+{
-+ if (aux_count++) {
-+ return 0;
-+ }
-+ queue->head = queue->tail = 0; /* Flush input queue */
-+ /* Don't enable the mouse controller until we've registered IRQ handler */
-+ if (request_irq(IRQ_MSRXINT, mouse_interrupt, SA_SHIRQ, "PS/2 Mouse", AUX_DEV)) {
-+ aux_count--;
-+ return -EBUSY;
-+ }
-+ MSECLKDIV = 0;
-+ MSEPRECNT = 127;
-+ MSECR &= ~MSECR_ENA;
-+ mdelay(50);
-+ MSECR = MSECR_ENA;
-+ mdelay(50);
-+ MSEDATA = 0xf4;
-+ mdelay(50);
-+ if (MSESTAT & 0x0100) {
-+ MSESTAT = 0x0100; /* clear IRQ status */
-+ }
-+/* kbd_write_command_w(KBD_CCMD_MOUSE_ENABLE); *//* Enable the
-+ auxiliary port on
-+ controller. */
-+ aux_write_ack(AUX_ENABLE_DEV); /* Enable aux device */
-+ // kbd_write_cmd(AUX_INTS_ON); /* Enable controller ints */
-+
-+ // send_data(KBD_CMD_ENABLE); /* try to workaround toshiba4030cdt problem */
-+
-+ return 0;
-+}
-+
-+/*
-+ * Put bytes from input queue to buffer.
-+ */
-+
-+static ssize_t
-+read_aux(struct file *file, char *buffer, size_t count, loff_t * ppos)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ ssize_t i = count;
-+ unsigned char c;
-+
-+ if (queue_empty()) {
-+ if (file->f_flags & O_NONBLOCK)
-+ return -EAGAIN;
-+ add_wait_queue(&queue->proc_list, &wait);
-+ repeat:
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (queue_empty() && !signal_pending(current)) {
-+ schedule();
-+ goto repeat;
-+ }
-+ current->state = TASK_RUNNING;
-+ remove_wait_queue(&queue->proc_list, &wait);
-+ }
-+ while (i > 0 && !queue_empty()) {
-+ c = get_from_queue();
-+ put_user(c, buffer++);
-+ i--;
-+ }
-+ if (count - i) {
-+ file->f_dentry->d_inode->i_atime = CURRENT_TIME;
-+ return count - i;
-+ }
-+ if (signal_pending(current))
-+ return -ERESTARTSYS;
-+ return 0;
-+}
-+
-+/*
-+ * Write to the aux device.
-+ */
-+
-+static ssize_t
-+write_aux(struct file *file, const char *buffer, size_t count,
-+ loff_t * ppos)
-+{
-+ ssize_t retval = 0;
-+
-+ if (count) {
-+ ssize_t written = 0;
-+
-+ if (count > 32)
-+ count = 32; /* Limit to 32 bytes. */
-+ do {
-+ char c;
-+ get_user(c, buffer++);
-+ aux_write_dev(c);
-+ written++;
-+ }
-+ while (--count);
-+ retval = -EIO;
-+ if (written) {
-+ retval = written;
-+ file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
-+ }
-+ }
-+
-+ return retval;
-+}
-+
-+static unsigned int aux_poll(struct file *file, poll_table * wait)
-+{
-+ poll_wait(file, &queue->proc_list, wait);
-+ if (!queue_empty())
-+ return POLLIN | POLLRDNORM;
-+ return 0;
-+}
-+
-+struct file_operations psaux_fops = {
-+ read: read_aux,
-+ write: write_aux,
-+ poll: aux_poll,
-+ open: open_aux,
-+ release: release_aux,
-+ fasync: fasync_aux,
-+};
-+
-+/*
-+ * Initialize driver.
-+ */
-+static struct miscdevice psaux_mouse = {
-+ PSMOUSE_MINOR, "psaux", &psaux_fops
-+};
-+
-+
-+static int __init psaux_init(void)
-+{
-+ int ret;
-+
-+ if (!request_mem_region(_MSECR, 512, "psaux"))
-+ return -EBUSY;
-+
-+ if (!detect_auxiliary_port()) {
-+ ret = -EIO;
-+ goto out;
-+ }
-+
-+ misc_register(&psaux_mouse);
-+ queue = (struct aux_queue *) kmalloc(sizeof(*queue), GFP_KERNEL);
-+ memset(queue, 0, sizeof(*queue));
-+ queue->head = queue->tail = 0;
-+ init_waitqueue_head(&queue->proc_list);
-+
-+#ifdef CONFIG_PSMOUSE
-+ aux_write_ack(AUX_SET_SAMPLE);
-+ aux_write_ack(100); /* 100 samples/sec */
-+ aux_write_ack(AUX_SET_RES);
-+ aux_write_ack(3); /* 8 counts per mm */
-+ aux_write_ack(AUX_SET_SCALE21); /* 2:1 scaling */
-+#endif
-+ ret = 0;
-+
-+ out:
-+ if (ret)
-+ release_mem_region(_MSECR, 512);
-+ return ret;
-+}
-+
-+#endif /* CONFIG_PSMOUSE */
---- linux-2.4.25/drivers/char/serial.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/char/serial.c 2004-03-31 17:15:09.000000000 +0200
-@@ -4527,6 +4527,14 @@
- }
-
- /*
-+ * If there is exactly one port of 8 bytes, use it.
-+ */
-+ if (num_port == 1 && pci_resource_len(dev, first_port) == 8) {
-+ board->flags = first_port;
-+ return 0;
-+ }
-+
-+ /*
- * If there is 1 or 0 iomem regions, and exactly one port, use
- * it.
- */
---- linux-2.4.25/drivers/char/serial_21285.c~2.4.25-vrs2.patch
-+++ linux-2.4.25/drivers/char/serial_21285.c
--/*
-- * linux/drivers/char/serial_21285.c
-- *
-- * Driver for the serial port on the 21285 StrongArm-110 core logic chip.
-- *
-- * Based on drivers/char/serial.c
-- */
--
--#include <linux/config.h>
--#include <linux/module.h>
--#include <linux/errno.h>
--#include <linux/signal.h>
--#include <linux/sched.h>
--#include <linux/interrupt.h>
--#include <linux/tty.h>
--#include <linux/tty_flip.h>
--#include <linux/serial.h>
--#include <linux/major.h>
--#include <linux/ptrace.h>
--#include <linux/ioport.h>
--#include <linux/mm.h>
--#include <linux/slab.h>
--#include <linux/init.h>
--#include <linux/console.h>
--
--#include <asm/io.h>
--#include <asm/irq.h>
--#include <asm/uaccess.h>
--#include <asm/dec21285.h>
--#include <asm/hardware.h>
--
--#define BAUD_BASE (mem_fclk_21285/64)
--
--#define SERIAL_21285_NAME "ttyFB"
--#define SERIAL_21285_MAJOR 204
--#define SERIAL_21285_MINOR 4
--
--#define SERIAL_21285_AUXNAME "cuafb"
--#define SERIAL_21285_AUXMAJOR 205
--#define SERIAL_21285_AUXMINOR 4
--
--static struct tty_driver rs285_driver, callout_driver;
--static int rs285_refcount;
--static struct tty_struct *rs285_table[1];
--
--static struct termios *rs285_termios[1];
--static struct termios *rs285_termios_locked[1];
--
--static char wbuf[1000], *putp = wbuf, *getp = wbuf, x_char;
--static struct tty_struct *rs285_tty;
--static int rs285_use_count;
--
--static int rs285_write_room(struct tty_struct *tty)
--{
-- return putp >= getp ? (sizeof(wbuf) - (long) putp + (long) getp) : ((long) getp - (long) putp - 1);
--}
--
--static void rs285_rx_int(int irq, void *dev_id, struct pt_regs *regs)
--{
-- if (!rs285_tty) {
-- disable_irq(IRQ_CONRX);
-- return;
-- }
-- while (!(*CSR_UARTFLG & 0x10)) {
-- int ch, flag;
-- ch = *CSR_UARTDR;
-- flag = *CSR_RXSTAT;
-- if (flag & 4)
-- tty_insert_flip_char(rs285_tty, 0, TTY_OVERRUN);
-- if (flag & 2)
-- flag = TTY_PARITY;
-- else if (flag & 1)
-- flag = TTY_FRAME;
-- tty_insert_flip_char(rs285_tty, ch, flag);
-- }
-- tty_flip_buffer_push(rs285_tty);
--}
--
--static void rs285_send_xchar(struct tty_struct *tty, char ch)
--{
-- x_char = ch;
-- enable_irq(IRQ_CONTX);
--}
--
--static void rs285_throttle(struct tty_struct *tty)
--{
-- if (I_IXOFF(tty))
-- rs285_send_xchar(tty, STOP_CHAR(tty));
--}
--
--static void rs285_unthrottle(struct tty_struct *tty)
--{
-- if (I_IXOFF(tty)) {
-- if (x_char)
-- x_char = 0;
-- else
-- rs285_send_xchar(tty, START_CHAR(tty));
-- }
--}
--
--static void rs285_tx_int(int irq, void *dev_id, struct pt_regs *regs)
--{
-- while (!(*CSR_UARTFLG & 0x20)) {
-- if (x_char) {
-- *CSR_UARTDR = x_char;
-- x_char = 0;
-- continue;
-- }
-- if (putp == getp) {
-- disable_irq(IRQ_CONTX);
-- break;
-- }
-- *CSR_UARTDR = *getp;
-- if (++getp >= wbuf + sizeof(wbuf))
-- getp = wbuf;
-- }
-- if (rs285_tty)
-- wake_up_interruptible(&rs285_tty->write_wait);
--}
--
--static inline int rs285_xmit(int ch)
--{
-- if (putp + 1 == getp || (putp + 1 == wbuf + sizeof(wbuf) && getp == wbuf))
-- return 0;
-- *putp = ch;
-- if (++putp >= wbuf + sizeof(wbuf))
-- putp = wbuf;
-- enable_irq(IRQ_CONTX);
-- return 1;
--}
--
--static int rs285_write(struct tty_struct *tty, int from_user,
-- const u_char * buf, int count)
--{
-- int i;
--
-- if (from_user && verify_area(VERIFY_READ, buf, count))
-- return -EINVAL;
--
-- for (i = 0; i < count; i++) {
-- char ch;
-- if (from_user)
-- __get_user(ch, buf + i);
-- else
-- ch = buf[i];
-- if (!rs285_xmit(ch))
-- break;
-- }
-- return i;
--}
--
--static void rs285_put_char(struct tty_struct *tty, u_char ch)
--{
-- rs285_xmit(ch);
--}
--
--static int rs285_chars_in_buffer(struct tty_struct *tty)
--{
-- return sizeof(wbuf) - rs285_write_room(tty);
--}
--
--static void rs285_flush_buffer(struct tty_struct *tty)
--{
-- disable_irq(IRQ_CONTX);
-- putp = getp = wbuf;
-- if (x_char)
-- enable_irq(IRQ_CONTX);
--}
--
--static inline void rs285_set_cflag(int cflag)
--{
-- int h_lcr, baud, quot;
--
-- switch (cflag & CSIZE) {
-- case CS5:
-- h_lcr = 0x10;
-- break;
-- case CS6:
-- h_lcr = 0x30;
-- break;
-- case CS7:
-- h_lcr = 0x50;
-- break;
-- default: /* CS8 */
-- h_lcr = 0x70;
-- break;
--
-- }
-- if (cflag & CSTOPB)
-- h_lcr |= 0x08;
-- if (cflag & PARENB)
-- h_lcr |= 0x02;
-- if (!(cflag & PARODD))
-- h_lcr |= 0x04;
--
-- switch (cflag & CBAUD) {
-- case B200: baud = 200; break;
-- case B300: baud = 300; break;
-- case B1200: baud = 1200; break;
-- case B1800: baud = 1800; break;
-- case B2400: baud = 2400; break;
-- case B4800: baud = 4800; break;
-- default:
-- case B9600: baud = 9600; break;
-- case B19200: baud = 19200; break;
-- case B38400: baud = 38400; break;
-- case B57600: baud = 57600; break;
-- case B115200: baud = 115200; break;
-- }
--
-- /*
-- * The documented expression for selecting the divisor is:
-- * BAUD_BASE / baud - 1
-- * However, typically BAUD_BASE is not divisible by baud, so
-- * we want to select the divisor that gives us the minimum
-- * error. Therefore, we want:
-- * int(BAUD_BASE / baud - 0.5) ->
-- * int(BAUD_BASE / baud - (baud >> 1) / baud) ->
-- * int((BAUD_BASE - (baud >> 1)) / baud)
-- */
-- quot = (BAUD_BASE - (baud >> 1)) / baud;
--
-- *CSR_UARTCON = 0;
-- *CSR_L_UBRLCR = quot & 0xff;
-- *CSR_M_UBRLCR = (quot >> 8) & 0x0f;
-- *CSR_H_UBRLCR = h_lcr;
-- *CSR_UARTCON = 1;
--}
--
--static void rs285_set_termios(struct tty_struct *tty, struct termios *old)
--{
-- if (old && tty->termios->c_cflag == old->c_cflag)
-- return;
-- rs285_set_cflag(tty->termios->c_cflag);
--}
--
--
--static void rs285_stop(struct tty_struct *tty)
--{
-- disable_irq(IRQ_CONTX);
--}
--
--static void rs285_start(struct tty_struct *tty)
--{
-- enable_irq(IRQ_CONTX);
--}
--
--static void rs285_wait_until_sent(struct tty_struct *tty, int timeout)
--{
-- int orig_jiffies = jiffies;
-- while (*CSR_UARTFLG & 8) {
-- current->state = TASK_INTERRUPTIBLE;
-- schedule_timeout(1);
-- if (signal_pending(current))
-- break;
-- if (timeout && time_after(jiffies, orig_jiffies + timeout))
-- break;
-- }
-- current->state = TASK_RUNNING;
--}
--
--static int rs285_open(struct tty_struct *tty, struct file *filp)
--{
-- int line;
--
-- MOD_INC_USE_COUNT;
-- line = MINOR(tty->device) - tty->driver.minor_start;
-- if (line) {
-- MOD_DEC_USE_COUNT;
-- return -ENODEV;
-- }
--
-- tty->driver_data = NULL;
-- if (!rs285_tty)
-- rs285_tty = tty;
--
-- enable_irq(IRQ_CONRX);
-- rs285_use_count++;
-- return 0;
--}
--
--static void rs285_close(struct tty_struct *tty, struct file *filp)
--{
-- if (!--rs285_use_count) {
-- rs285_wait_until_sent(tty, 0);
-- disable_irq(IRQ_CONRX);
-- disable_irq(IRQ_CONTX);
-- rs285_tty = NULL;
-- }
-- MOD_DEC_USE_COUNT;
--}
--
--static int __init rs285_init(void)
--{
-- int baud = B9600;
--
-- if (machine_is_personal_server())
-- baud = B57600;
--
-- rs285_driver.magic = TTY_DRIVER_MAGIC;
-- rs285_driver.driver_name = "serial_21285";
-- rs285_driver.name = SERIAL_21285_NAME;
-- rs285_driver.major = SERIAL_21285_MAJOR;
-- rs285_driver.minor_start = SERIAL_21285_MINOR;
-- rs285_driver.num = 1;
-- rs285_driver.type = TTY_DRIVER_TYPE_SERIAL;
-- rs285_driver.subtype = SERIAL_TYPE_NORMAL;
-- rs285_driver.init_termios = tty_std_termios;
-- rs285_driver.init_termios.c_cflag = baud | CS8 | CREAD | HUPCL | CLOCAL;
-- rs285_driver.flags = TTY_DRIVER_REAL_RAW;
-- rs285_driver.refcount = &rs285_refcount;
-- rs285_driver.table = rs285_table;
-- rs285_driver.termios = rs285_termios;
-- rs285_driver.termios_locked = rs285_termios_locked;
--
-- rs285_driver.open = rs285_open;
-- rs285_driver.close = rs285_close;
-- rs285_driver.write = rs285_write;
-- rs285_driver.put_char = rs285_put_char;
-- rs285_driver.write_room = rs285_write_room;
-- rs285_driver.chars_in_buffer = rs285_chars_in_buffer;
-- rs285_driver.flush_buffer = rs285_flush_buffer;
-- rs285_driver.throttle = rs285_throttle;
-- rs285_driver.unthrottle = rs285_unthrottle;
-- rs285_driver.send_xchar = rs285_send_xchar;
-- rs285_driver.set_termios = rs285_set_termios;
-- rs285_driver.stop = rs285_stop;
-- rs285_driver.start = rs285_start;
-- rs285_driver.wait_until_sent = rs285_wait_until_sent;
--
-- callout_driver = rs285_driver;
-- callout_driver.name = SERIAL_21285_AUXNAME;
-- callout_driver.major = SERIAL_21285_AUXMAJOR;
-- callout_driver.subtype = SERIAL_TYPE_CALLOUT;
--
-- if (request_irq(IRQ_CONRX, rs285_rx_int, 0, "rs285", NULL))
-- panic("Couldn't get rx irq for rs285");
--
-- if (request_irq(IRQ_CONTX, rs285_tx_int, 0, "rs285", NULL))
-- panic("Couldn't get tx irq for rs285");
--
-- if (tty_register_driver(&rs285_driver))
-- printk(KERN_ERR "Couldn't register 21285 serial driver\n");
-- if (tty_register_driver(&callout_driver))
-- printk(KERN_ERR "Couldn't register 21285 callout driver\n");
--
-- return 0;
--}
--
--static void __exit rs285_fini(void)
--{
-- unsigned long flags;
-- int ret;
--
-- save_flags(flags);
-- cli();
-- ret = tty_unregister_driver(&callout_driver);
-- if (ret)
-- printk(KERN_ERR "Unable to unregister 21285 callout driver "
-- "(%d)\n", ret);
-- ret = tty_unregister_driver(&rs285_driver);
-- if (ret)
-- printk(KERN_ERR "Unable to unregister 21285 driver (%d)\n",
-- ret);
-- free_irq(IRQ_CONTX, NULL);
-- free_irq(IRQ_CONRX, NULL);
-- restore_flags(flags);
--}
--
--module_init(rs285_init);
--module_exit(rs285_fini);
--
--#ifdef CONFIG_SERIAL_21285_CONSOLE
--/************** console driver *****************/
--
--static void rs285_console_write(struct console *co, const char *s, u_int count)
--{
-- int i;
--
-- disable_irq(IRQ_CONTX);
-- for (i = 0; i < count; i++) {
-- while (*CSR_UARTFLG & 0x20);
-- *CSR_UARTDR = s[i];
-- if (s[i] == '\n') {
-- while (*CSR_UARTFLG & 0x20);
-- *CSR_UARTDR = '\r';
-- }
-- }
-- enable_irq(IRQ_CONTX);
--}
--
--static kdev_t rs285_console_device(struct console *c)
--{
-- return MKDEV(SERIAL_21285_MAJOR, SERIAL_21285_MINOR);
--}
--
--static int __init rs285_console_setup(struct console *co, char *options)
--{
-- int baud = 9600;
-- int bits = 8;
-- int parity = 'n';
-- int cflag = CREAD | HUPCL | CLOCAL;
--
-- if (machine_is_personal_server())
-- baud = 57600;
--
-- if (options) {
-- char *s = options;
-- baud = simple_strtoul(options, NULL, 10);
-- while (*s >= '0' && *s <= '9')
-- s++;
-- if (*s)
-- parity = *s++;
-- if (*s)
-- bits = *s - '0';
-- }
--
-- /*
-- * Now construct a cflag setting.
-- */
-- switch (baud) {
-- case 1200:
-- cflag |= B1200;
-- break;
-- case 2400:
-- cflag |= B2400;
-- break;
-- case 4800:
-- cflag |= B4800;
-- break;
-- case 9600:
-- cflag |= B9600;
-- break;
-- case 19200:
-- cflag |= B19200;
-- break;
-- case 38400:
-- cflag |= B38400;
-- break;
-- case 57600:
-- cflag |= B57600;
-- break;
-- case 115200:
-- cflag |= B115200;
-- break;
-- default:
-- cflag |= B9600;
-- break;
-- }
-- switch (bits) {
-- case 7:
-- cflag |= CS7;
-- break;
-- default:
-- cflag |= CS8;
-- break;
-- }
-- switch (parity) {
-- case 'o':
-- case 'O':
-- cflag |= PARODD;
-- break;
-- case 'e':
-- case 'E':
-- cflag |= PARENB;
-- break;
-- }
-- co->cflag = cflag;
-- rs285_set_cflag(cflag);
-- rs285_console_write(NULL, "\e[2J\e[Hboot ", 12);
-- if (options)
-- rs285_console_write(NULL, options, strlen(options));
-- else
-- rs285_console_write(NULL, "no options", 10);
-- rs285_console_write(NULL, "\n", 1);
--
-- return 0;
--}
--
--static struct console rs285_cons =
--{
-- name: SERIAL_21285_NAME,
-- write: rs285_console_write,
-- device: rs285_console_device,
-- setup: rs285_console_setup,
-- flags: CON_PRINTBUFFER,
-- index: -1,
--};
--
--void __init rs285_console_init(void)
--{
-- register_console(&rs285_cons);
--}
--
--#endif /* CONFIG_SERIAL_21285_CONSOLE */
--
--MODULE_LICENSE("GPL");
--EXPORT_NO_SYMBOLS;
---- linux-2.4.25/drivers/char/serial_amba.c~2.4.25-vrs2.patch
-+++ linux-2.4.25/drivers/char/serial_amba.c
--/*
-- * linux/drivers/char/serial_amba.c
-- *
-- * Driver for AMBA serial ports
-- *
-- * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
-- *
-- * Copyright 1999 ARM Limited
-- * Copyright (C) 2000 Deep Blue Solutions Ltd.
-- *
-- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-- *
-- *
-- * This is a generic driver for ARM AMBA-type serial ports. They
-- * have a lot of 16550-like features, but are not register compatable.
-- * Note that although they do have CTS, DCD and DSR inputs, they do
-- * not have an RI input, nor do they have DTR or RTS outputs. If
-- * required, these have to be supplied via some other means (eg, GPIO)
-- * and hooked into this driver.
-- *
-- * This could very easily become a generic serial driver for dumb UARTs
-- * (eg, {82,16x}50, 21285, SA1100).
-- */
--
--#include <linux/config.h>
--#include <linux/module.h>
--#include <linux/errno.h>
--#include <linux/signal.h>
--#include <linux/sched.h>
--#include <linux/interrupt.h>
--#include <linux/tty.h>
--#include <linux/tty_flip.h>
--#include <linux/major.h>
--#include <linux/string.h>
--#include <linux/fcntl.h>
--#include <linux/ptrace.h>
--#include <linux/ioport.h>
--#include <linux/mm.h>
--#include <linux/slab.h>
--#include <linux/init.h>
--#include <linux/circ_buf.h>
--#include <linux/serial.h>
--#include <linux/console.h>
--#include <linux/sysrq.h>
--
--#include <asm/system.h>
--#include <asm/io.h>
--#include <asm/irq.h>
--#include <asm/uaccess.h>
--#include <asm/bitops.h>
--
--#include <asm/hardware/serial_amba.h>
--
--#define SERIAL_AMBA_NAME "ttyAM"
--#define SERIAL_AMBA_MAJOR 204
--#define SERIAL_AMBA_MINOR 16
--#define SERIAL_AMBA_NR 2
--
--#define CALLOUT_AMBA_NAME "cuaam"
--#define CALLOUT_AMBA_MAJOR 205
--#define CALLOUT_AMBA_MINOR 16
--#define CALLOUT_AMBA_NR SERIAL_AMBA_NR
--
--#ifndef TRUE
--#define TRUE 1
--#endif
--#ifndef FALSE
--#define FALSE 0
--#endif
--
--#define DEBUG 0
--#define DEBUG_LEDS 0
--
--#if DEBUG_LEDS
--extern int get_leds(void);
--extern int set_leds(int);
--#endif
--
--/*
-- * Access routines for the AMBA UARTs
-- */
--#define UART_GET_INT_STATUS(p) IO_READ((p)->uart_base + AMBA_UARTIIR)
--#define UART_GET_FR(p) IO_READ((p)->uart_base + AMBA_UARTFR)
--#define UART_GET_CHAR(p) IO_READ((p)->uart_base + AMBA_UARTDR)
--#define UART_PUT_CHAR(p, c) IO_WRITE((p)->uart_base + AMBA_UARTDR, (c))
--#define UART_GET_RSR(p) IO_READ((p)->uart_base + AMBA_UARTRSR)
--#define UART_GET_CR(p) IO_READ((p)->uart_base + AMBA_UARTCR)
--#define UART_PUT_CR(p,c) IO_WRITE((p)->uart_base + AMBA_UARTCR, (c))
--#define UART_GET_LCRL(p) IO_READ((p)->uart_base + AMBA_UARTLCR_L)
--#define UART_PUT_LCRL(p,c) IO_WRITE((p)->uart_base + AMBA_UARTLCR_L, (c))
--#define UART_GET_LCRM(p) IO_READ((p)->uart_base + AMBA_UARTLCR_M)
--#define UART_PUT_LCRM(p,c) IO_WRITE((p)->uart_base + AMBA_UARTLCR_M, (c))
--#define UART_GET_LCRH(p) IO_READ((p)->uart_base + AMBA_UARTLCR_H)
--#define UART_PUT_LCRH(p,c) IO_WRITE((p)->uart_base + AMBA_UARTLCR_H, (c))
--#define UART_RX_DATA(s) (((s) & AMBA_UARTFR_RXFE) == 0)
--#define UART_TX_READY(s) (((s) & AMBA_UARTFR_TXFF) == 0)
--#define UART_TX_EMPTY(p) ((UART_GET_FR(p) & AMBA_UARTFR_TMSK) == 0)
--
--#define AMBA_UARTRSR_ANY (AMBA_UARTRSR_OE|AMBA_UARTRSR_BE|AMBA_UARTRSR_PE|AMBA_UARTRSR_FE)
--#define AMBA_UARTFR_MODEM_ANY (AMBA_UARTFR_DCD|AMBA_UARTFR_DSR|AMBA_UARTFR_CTS)
--
--/*
-- * Things needed by tty driver
-- */
--static struct tty_driver ambanormal_driver, ambacallout_driver;
--static int ambauart_refcount;
--static struct tty_struct *ambauart_table[SERIAL_AMBA_NR];
--static struct termios *ambauart_termios[SERIAL_AMBA_NR];
--static struct termios *ambauart_termios_locked[SERIAL_AMBA_NR];
--
--#if defined(CONFIG_SERIAL_AMBA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
--#define SUPPORT_SYSRQ
--#endif
--
--/*
-- * Things needed internally to this driver
-- */
--
--/*
-- * tmp_buf is used as a temporary buffer by serial_write. We need to
-- * lock it in case the copy_from_user blocks while swapping in a page,
-- * and some other program tries to do a serial write at the same time.
-- * Since the lock will only come under contention when the system is
-- * swapping and available memory is low, it makes sense to share one
-- * buffer across all the serial ports, since it significantly saves
-- * memory if large numbers of serial ports are open.
-- */
--static u_char *tmp_buf;
--static DECLARE_MUTEX(tmp_buf_sem);
--
--#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
--
--/* number of characters left in xmit buffer before we ask for more */
--#define WAKEUP_CHARS 256
--#define AMBA_ISR_PASS_LIMIT 256
--
--#define EVT_WRITE_WAKEUP 0
--
--struct amba_icount {
-- __u32 cts;
-- __u32 dsr;
-- __u32 rng;
-- __u32 dcd;
-- __u32 rx;
-- __u32 tx;
-- __u32 frame;
-- __u32 overrun;
-- __u32 parity;
-- __u32 brk;
-- __u32 buf_overrun;
--};
--
--/*
-- * Static information about the port
-- */
--struct amba_port {
-- unsigned int uart_base;
-- unsigned int irq;
-- unsigned int uartclk;
-- unsigned int fifosize;
-- unsigned int tiocm_support;
-- void (*set_mctrl)(struct amba_port *, u_int mctrl);
--};
--
--/*
-- * This is the state information which is persistent across opens
-- */
--struct amba_state {
-- struct amba_icount icount;
-- unsigned int line;
-- unsigned int close_delay;
-- unsigned int closing_wait;
-- unsigned int custom_divisor;
-- unsigned int flags;
-- struct termios normal_termios;
-- struct termios callout_termios;
--
-- int count;
-- struct amba_info *info;
--};
--
--#define AMBA_XMIT_SIZE 1024
--/*
-- * This is the state information which is only valid when the port is open.
-- */
--struct amba_info {
-- struct amba_port *port;
-- struct amba_state *state;
-- struct tty_struct *tty;
-- unsigned char x_char;
-- unsigned char old_status;
-- unsigned char read_status_mask;
-- unsigned char ignore_status_mask;
-- struct circ_buf xmit;
-- unsigned int flags;
--#ifdef SUPPORT_SYSRQ
-- unsigned long sysrq;
--#endif
--
-- unsigned int event;
-- unsigned int timeout;
-- unsigned int lcr_h;
-- unsigned int mctrl;
-- int blocked_open;
-- pid_t session;
-- pid_t pgrp;
--
-- struct tasklet_struct tlet;
--
-- wait_queue_head_t open_wait;
-- wait_queue_head_t close_wait;
-- wait_queue_head_t delta_msr_wait;
--};
--
--#ifdef CONFIG_SERIAL_AMBA_CONSOLE
--static struct console ambauart_cons;
--#endif
--static void ambauart_change_speed(struct amba_info *info, struct termios *old_termios);
--static void ambauart_wait_until_sent(struct tty_struct *tty, int timeout);
--
--#if 1 //def CONFIG_SERIAL_INTEGRATOR
--static void amba_set_mctrl_null(struct amba_port *port, u_int mctrl)
--{
--}
--
--static struct amba_port amba_ports[SERIAL_AMBA_NR] = {
-- {
-- uart_base: IO_ADDRESS(INTEGRATOR_UART0_BASE),
-- irq: IRQ_UARTINT0,
-- uartclk: 14745600,
-- fifosize: 8,
-- set_mctrl: amba_set_mctrl_null,
-- },
-- {
-- uart_base: IO_ADDRESS(INTEGRATOR_UART1_BASE),
-- irq: IRQ_UARTINT1,
-- uartclk: 14745600,
-- fifosize: 8,
-- set_mctrl: amba_set_mctrl_null,
-- }
--};
--#endif
--
--static struct amba_state amba_state[SERIAL_AMBA_NR];
--
--static void ambauart_enable_rx_interrupt(struct amba_info *info)
--{
-- unsigned int cr;
--
-- cr = UART_GET_CR(info->port);
-- cr |= AMBA_UARTCR_RIE | AMBA_UARTCR_RTIE;
-- UART_PUT_CR(info->port, cr);
--}
--
--static void ambauart_disable_rx_interrupt(struct amba_info *info)
--{
-- unsigned int cr;
--
-- cr = UART_GET_CR(info->port);
-- cr &= ~(AMBA_UARTCR_RIE | AMBA_UARTCR_RTIE);
-- UART_PUT_CR(info->port, cr);
--}
--
--static void ambauart_enable_tx_interrupt(struct amba_info *info)
--{
-- unsigned int cr;
--
-- cr = UART_GET_CR(info->port);
-- cr |= AMBA_UARTCR_TIE;
-- UART_PUT_CR(info->port, cr);
--}
--
--static void ambauart_disable_tx_interrupt(struct amba_info *info)
--{
-- unsigned int cr;
--
-- cr = UART_GET_CR(info->port);
-- cr &= ~AMBA_UARTCR_TIE;
-- UART_PUT_CR(info->port, cr);
--}
--
--static void ambauart_stop(struct tty_struct *tty)
--{
-- struct amba_info *info = tty->driver_data;
-- unsigned long flags;
--
-- save_flags(flags); cli();
-- ambauart_disable_tx_interrupt(info);
-- restore_flags(flags);
--}
--
--static void ambauart_start(struct tty_struct *tty)
--{
-- struct amba_info *info = tty->driver_data;
-- unsigned long flags;
--
-- save_flags(flags); cli();
-- if (info->xmit.head != info->xmit.tail
-- && info->xmit.buf)
-- ambauart_enable_tx_interrupt(info);
-- restore_flags(flags);
--}
--
--
--/*
-- * This routine is used by the interrupt handler to schedule
-- * processing in the software interrupt portion of the driver.
-- */
--static void ambauart_event(struct amba_info *info, int event)
--{
-- info->event |= 1 << event;
-- tasklet_schedule(&info->tlet);
--}
--
--static void
--#ifdef SUPPORT_SYSRQ
--ambauart_rx_chars(struct amba_info *info, struct pt_regs *regs)
--#else
--ambauart_rx_chars(struct amba_info *info)
--#endif
--{
-- struct tty_struct *tty = info->tty;
-- unsigned int status, ch, rsr, flg, ignored = 0;
-- struct amba_icount *icount = &info->state->icount;
-- struct amba_port *port = info->port;
--
-- status = UART_GET_FR(port);
-- while (UART_RX_DATA(status)) {
-- ch = UART_GET_CHAR(port);
--
-- if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-- goto ignore_char;
-- icount->rx++;
--
-- flg = TTY_NORMAL;
--
-- /*
-- * Note that the error handling code is
-- * out of the main execution path
-- */
-- rsr = UART_GET_RSR(port);
-- if (rsr & AMBA_UARTRSR_ANY)
-- goto handle_error;
--#ifdef SUPPORT_SYSRQ
-- if (info->sysrq) {
-- if (ch && time_before(jiffies, info->sysrq)) {
-- handle_sysrq(ch, regs, NULL, NULL);
-- info->sysrq = 0;
-- goto ignore_char;
-- }
-- info->sysrq = 0;
-- }
--#endif
-- error_return:
-- *tty->flip.flag_buf_ptr++ = flg;
-- *tty->flip.char_buf_ptr++ = ch;
-- tty->flip.count++;
-- ignore_char:
-- status = UART_GET_FR(port);
-- }
--out:
-- tty_flip_buffer_push(tty);
-- return;
--
--handle_error:
-- if (rsr & AMBA_UARTRSR_BE) {
-- rsr &= ~(AMBA_UARTRSR_FE | AMBA_UARTRSR_PE);
-- icount->brk++;
--
--#ifdef SUPPORT_SYSRQ
-- if (info->state->line == ambauart_cons.index) {
-- if (!info->sysrq) {
-- info->sysrq = jiffies + HZ*5;
-- goto ignore_char;
-- }
-- }
--#endif
-- } else if (rsr & AMBA_UARTRSR_PE)
-- icount->parity++;
-- else if (rsr & AMBA_UARTRSR_FE)
-- icount->frame++;
-- if (rsr & AMBA_UARTRSR_OE)
-- icount->overrun++;
--
-- if (rsr & info->ignore_status_mask) {
-- if (++ignored > 100)
-- goto out;
-- goto ignore_char;
-- }
-- rsr &= info->read_status_mask;
--
-- if (rsr & AMBA_UARTRSR_BE)
-- flg = TTY_BREAK;
-- else if (rsr & AMBA_UARTRSR_PE)
-- flg = TTY_PARITY;
-- else if (rsr & AMBA_UARTRSR_FE)
-- flg = TTY_FRAME;
--
-- if (rsr & AMBA_UARTRSR_OE) {
-- /*
-- * CHECK: does overrun affect the current character?
-- * ASSUMPTION: it does not.
-- */
-- *tty->flip.flag_buf_ptr++ = flg;
-- *tty->flip.char_buf_ptr++ = ch;
-- tty->flip.count++;
-- if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-- goto ignore_char;
-- ch = 0;
-- flg = TTY_OVERRUN;
-- }
--#ifdef SUPPORT_SYSRQ
-- info->sysrq = 0;
--#endif
-- goto error_return;
--}
--
--static void ambauart_tx_chars(struct amba_info *info)
--{
-- struct amba_port *port = info->port;
-- int count;
--
-- if (info->x_char) {
-- UART_PUT_CHAR(port, info->x_char);
-- info->state->icount.tx++;
-- info->x_char = 0;
-- return;
-- }
-- if (info->xmit.head == info->xmit.tail
-- || info->tty->stopped
-- || info->tty->hw_stopped) {
-- ambauart_disable_tx_interrupt(info);
-- return;
-- }
--
-- count = port->fifosize;
-- do {
-- UART_PUT_CHAR(port, info->xmit.buf[info->xmit.tail]);
-- info->xmit.tail = (info->xmit.tail + 1) & (AMBA_XMIT_SIZE - 1);
-- info->state->icount.tx++;
-- if (info->xmit.head == info->xmit.tail)
-- break;
-- } while (--count > 0);
--
-- if (CIRC_CNT(info->xmit.head,
-- info->xmit.tail,
-- AMBA_XMIT_SIZE) < WAKEUP_CHARS)
-- ambauart_event(info, EVT_WRITE_WAKEUP);
--
-- if (info->xmit.head == info->xmit.tail) {
-- ambauart_disable_tx_interrupt(info);
-- }
--}
--
--static void ambauart_modem_status(struct amba_info *info)
--{
-- unsigned int status, delta;
-- struct amba_icount *icount = &info->state->icount;
--
-- status = UART_GET_FR(info->port) & AMBA_UARTFR_MODEM_ANY;
--
-- delta = status ^ info->old_status;
-- info->old_status = status;
--
-- if (!delta)
-- return;
--
-- if (delta & AMBA_UARTFR_DCD) {
-- icount->dcd++;
--#ifdef CONFIG_HARD_PPS
-- if ((info->flags & ASYNC_HARDPPS_CD) &&
-- (status & AMBA_UARTFR_DCD)
-- hardpps();
--#endif
-- if (info->flags & ASYNC_CHECK_CD) {
-- if (status & AMBA_UARTFR_DCD)
-- wake_up_interruptible(&info->open_wait);
-- else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-- (info->flags & ASYNC_CALLOUT_NOHUP))) {
-- if (info->tty)
-- tty_hangup(info->tty);
-- }
-- }
-- }
--
-- if (delta & AMBA_UARTFR_DSR)
-- icount->dsr++;
--
-- if (delta & AMBA_UARTFR_CTS) {
-- icount->cts++;
--
-- if (info->flags & ASYNC_CTS_FLOW) {
-- status &= AMBA_UARTFR_CTS;
--
-- if (info->tty->hw_stopped) {
-- if (status) {
-- info->tty->hw_stopped = 0;
-- ambauart_enable_tx_interrupt(info);
-- ambauart_event(info, EVT_WRITE_WAKEUP);
-- }
-- } else {
-- if (!status) {
-- info->tty->hw_stopped = 1;
-- ambauart_disable_tx_interrupt(info);
-- }
-- }
-- }
-- }
-- wake_up_interruptible(&info->delta_msr_wait);
--
--}
--
--static void ambauart_int(int irq, void *dev_id, struct pt_regs *regs)
--{
-- struct amba_info *info = dev_id;
-- unsigned int status, pass_counter = 0;
--
--#if DEBUG_LEDS
-- // tell the world
-- set_leds(get_leds() | RED_LED);
--#endif
--
-- status = UART_GET_INT_STATUS(info->port);
-- do {
-- /*
-- * FIXME: what about clearing the interrupts?
-- */
--
-- if (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS))
--#ifdef SUPPORT_SYSRQ
-- ambauart_rx_chars(info, regs);
--#else
-- ambauart_rx_chars(info);
--#endif
-- if (status & AMBA_UARTIIR_TIS)
-- ambauart_tx_chars(info);
-- if (status & AMBA_UARTIIR_MIS)
-- ambauart_modem_status(info);
-- if (pass_counter++ > AMBA_ISR_PASS_LIMIT)
-- break;
--
-- status = UART_GET_INT_STATUS(info->port);
-- } while (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS | AMBA_UARTIIR_TIS));
--
--#if DEBUG_LEDS
-- // tell the world
-- set_leds(get_leds() & ~RED_LED);
--#endif
--}
--
--static void ambauart_tasklet_action(unsigned long data)
--{
-- struct amba_info *info = (struct amba_info *)data;
-- struct tty_struct *tty;
--
-- tty = info->tty;
-- if (!tty || !test_and_clear_bit(EVT_WRITE_WAKEUP, &info->event))
-- return;
--
-- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-- tty->ldisc.write_wakeup)
-- (tty->ldisc.write_wakeup)(tty);
-- wake_up_interruptible(&tty->write_wait);
--}
--
--static int ambauart_startup(struct amba_info *info)
--{
-- unsigned long flags;
-- unsigned long page;
-- int retval = 0;
--
-- page = get_zeroed_page(GFP_KERNEL);
-- if (!page)
-- return -ENOMEM;
--
-- save_flags(flags); cli();
--
-- if (info->flags & ASYNC_INITIALIZED) {
-- free_page(page);
-- goto errout;
-- }
--
-- if (info->xmit.buf)
-- free_page(page);
-- else
-- info->xmit.buf = (unsigned char *) page;
--
-- /*
-- * Allocate the IRQ
-- */
-- retval = request_irq(info->port->irq, ambauart_int, 0, "amba", info);
-- if (retval) {
-- if (capable(CAP_SYS_ADMIN)) {
-- if (info->tty)
-- set_bit(TTY_IO_ERROR, &info->tty->flags);
-- retval = 0;
-- }
-- goto errout;
-- }
--
-- info->mctrl = 0;
-- if (info->tty->termios->c_cflag & CBAUD)
-- info->mctrl = TIOCM_RTS | TIOCM_DTR;
-- info->port->set_mctrl(info->port, info->mctrl);
--
-- /*
-- * initialise the old status of the modem signals
-- */
-- info->old_status = UART_GET_FR(info->port) & AMBA_UARTFR_MODEM_ANY;
--
-- /*
-- * Finally, enable interrupts
-- */
-- ambauart_enable_rx_interrupt(info);
--
-- if (info->tty)
-- clear_bit(TTY_IO_ERROR, &info->tty->flags);
-- info->xmit.head = info->xmit.tail = 0;
--
-- /*
-- * Set up the tty->alt_speed kludge
-- */
-- if (info->tty) {
-- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-- info->tty->alt_speed = 57600;
-- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-- info->tty->alt_speed = 115200;
-- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
-- info->tty->alt_speed = 230400;
-- if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
-- info->tty->alt_speed = 460800;
-- }
--
-- /*
-- * and set the speed of the serial port
-- */
-- ambauart_change_speed(info, 0);
--
-- info->flags |= ASYNC_INITIALIZED;
-- restore_flags(flags);
-- return 0;
--
--errout:
-- restore_flags(flags);
-- return retval;
--}
--
--/*
-- * This routine will shutdown a serial port; interrupts are disabled, and
-- * DTR is dropped if the hangup on close termio flag is on.
-- */
--static void ambauart_shutdown(struct amba_info *info)
--{
-- unsigned long flags;
--
-- if (!(info->flags & ASYNC_INITIALIZED))
-- return;
--
-- save_flags(flags); cli(); /* Disable interrupts */
--
-- /*
-- * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
-- * here so the queue might never be woken up
-- */
-- wake_up_interruptible(&info->delta_msr_wait);
--
-- /*
-- * Free the IRQ
-- */
-- free_irq(info->port->irq, info);
--
-- if (info->xmit.buf) {
-- unsigned long pg = (unsigned long) info->xmit.buf;
-- info->xmit.buf = NULL;
-- free_page(pg);
-- }
--
-- /*
-- * disable all interrupts, disable the port
-- */
-- UART_PUT_CR(info->port, 0);
--
-- /* disable break condition and fifos */
-- UART_PUT_LCRH(info->port, UART_GET_LCRH(info->port) &
-- ~(AMBA_UARTLCR_H_BRK | AMBA_UARTLCR_H_FEN));
--
-- if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
-- info->mctrl &= ~(TIOCM_DTR|TIOCM_RTS);
-- info->port->set_mctrl(info->port, info->mctrl);
--
-- /* kill off our tasklet */
-- tasklet_kill(&info->tlet);
-- if (info->tty)
-- set_bit(TTY_IO_ERROR, &info->tty->flags);
--
-- info->flags &= ~ASYNC_INITIALIZED;
-- restore_flags(flags);
--}
--
--static void ambauart_change_speed(struct amba_info *info, struct termios *old_termios)
--{
-- unsigned int lcr_h, baud, quot, cflag, old_cr, bits;
-- unsigned long flags;
--
-- if (!info->tty || !info->tty->termios)
-- return;
--
-- cflag = info->tty->termios->c_cflag;
--
--#if DEBUG
-- printk("ambauart_set_cflag(0x%x) called\n", cflag);
--#endif
-- /* byte size and parity */
-- switch (cflag & CSIZE) {
-- case CS5: lcr_h = AMBA_UARTLCR_H_WLEN_5; bits = 7; break;
-- case CS6: lcr_h = AMBA_UARTLCR_H_WLEN_6; bits = 8; break;
-- case CS7: lcr_h = AMBA_UARTLCR_H_WLEN_7; bits = 9; break;
-- default: lcr_h = AMBA_UARTLCR_H_WLEN_8; bits = 10; break; // CS8
-- }
-- if (cflag & CSTOPB) {
-- lcr_h |= AMBA_UARTLCR_H_STP2;
-- bits ++;
-- }
-- if (cflag & PARENB) {
-- lcr_h |= AMBA_UARTLCR_H_PEN;
-- bits++;
-- if (!(cflag & PARODD))
-- lcr_h |= AMBA_UARTLCR_H_EPS;
-- }
-- if (info->port->fifosize > 1)
-- lcr_h |= AMBA_UARTLCR_H_FEN;
--
-- do {
-- /* Determine divisor based on baud rate */
-- baud = tty_get_baud_rate(info->tty);
-- if (!baud)
-- baud = 9600;
--
-- if (baud == 38400 &&
-- ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
-- quot = info->state->custom_divisor;
-- else
-- quot = (info->port->uartclk / (16 * baud)) - 1;
--
-- if (!quot && old_termios) {
-- info->tty->termios->c_cflag &= ~CBAUD;
-- info->tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD);
-- old_termios = NULL;
-- }
-- } while (quot == 0 && old_termios);
--
-- /* As a last resort, if the quotient is zero, default to 9600 bps */
-- if (!quot)
-- quot = (info->port->uartclk / (16 * 9600)) - 1;
--
-- info->timeout = (info->port->fifosize * HZ * bits * quot) /
-- (info->port->uartclk / 16);
-- info->timeout += HZ/50; /* Add .02 seconds of slop */
--
-- if (cflag & CRTSCTS)
-- info->flags |= ASYNC_CTS_FLOW;
-- else
-- info->flags &= ~ASYNC_CTS_FLOW;
-- if (cflag & CLOCAL)
-- info->flags &= ~ASYNC_CHECK_CD;
-- else
-- info->flags |= ASYNC_CHECK_CD;
--
-- /*
-- * Set up parity check flag
-- */
--#define RELEVENT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
--
-- info->read_status_mask = AMBA_UARTRSR_OE;
-- if (I_INPCK(info->tty))
-- info->read_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;
-- if (I_BRKINT(info->tty) || I_PARMRK(info->tty))
-- info->read_status_mask |= AMBA_UARTRSR_BE;
--
-- /*
-- * Characters to ignore
-- */
-- info->ignore_status_mask = 0;
-- if (I_IGNPAR(info->tty))
-- info->ignore_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;
-- if (I_IGNBRK(info->tty)) {
-- info->ignore_status_mask |= AMBA_UARTRSR_BE;
-- /*
-- * If we're ignoring parity and break indicators,
-- * ignore overruns to (for real raw support).
-- */
-- if (I_IGNPAR(info->tty))
-- info->ignore_status_mask |= AMBA_UARTRSR_OE;
-- }
--
-- /* first, disable everything */
-- save_flags(flags); cli();
-- old_cr = UART_GET_CR(info->port) &= ~AMBA_UARTCR_MSIE;
--
-- if ((info->flags & ASYNC_HARDPPS_CD) ||
-- (cflag & CRTSCTS) ||
-- !(cflag & CLOCAL))
-- old_cr |= AMBA_UARTCR_MSIE;
--
-- UART_PUT_CR(info->port, 0);
-- restore_flags(flags);
--
-- /* Set baud rate */
-- UART_PUT_LCRM(info->port, ((quot & 0xf00) >> 8));
-- UART_PUT_LCRL(info->port, (quot & 0xff));
--
-- /*
-- * ----------v----------v----------v----------v-----
-- * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
-- * ----------^----------^----------^----------^-----
-- */
-- UART_PUT_LCRH(info->port, lcr_h);
-- UART_PUT_CR(info->port, old_cr);
--}
--
--static void ambauart_put_char(struct tty_struct *tty, u_char ch)
--{
-- struct amba_info *info = tty->driver_data;
-- unsigned long flags;
--
-- if (!tty || !info->xmit.buf)
-- return;
--
-- save_flags(flags); cli();
-- if (CIRC_SPACE(info->xmit.head, info->xmit.tail, AMBA_XMIT_SIZE) != 0) {
-- info->xmit.buf[info->xmit.head] = ch;
-- info->xmit.head = (info->xmit.head + 1) & (AMBA_XMIT_SIZE - 1);
-- }
-- restore_flags(flags);
--}
--
--static void ambauart_flush_chars(struct tty_struct *tty)
--{
-- struct amba_info *info = tty->driver_data;
-- unsigned long flags;
--
-- if (info->xmit.head == info->xmit.tail
-- || tty->stopped
-- || tty->hw_stopped
-- || !info->xmit.buf)
-- return;
--
-- save_flags(flags); cli();
-- ambauart_enable_tx_interrupt(info);
-- restore_flags(flags);
--}
--
--static int ambauart_write(struct tty_struct *tty, int from_user,
-- const u_char * buf, int count)
--{
-- struct amba_info *info = tty->driver_data;
-- unsigned long flags;
-- int c, ret = 0;
--
-- if (!tty || !info->xmit.buf || !tmp_buf)
-- return 0;
--
-- save_flags(flags);
-- if (from_user) {
-- down(&tmp_buf_sem);
-- while (1) {
-- int c1;
-- c = CIRC_SPACE_TO_END(info->xmit.head,
-- info->xmit.tail,
-- AMBA_XMIT_SIZE);
-- if (count < c)
-- c = count;
-- if (c <= 0)
-- break;
--
-- c -= copy_from_user(tmp_buf, buf, c);
-- if (!c) {
-- if (!ret)
-- ret = -EFAULT;
-- break;
-- }
-- cli();
-- c1 = CIRC_SPACE_TO_END(info->xmit.head,
-- info->xmit.tail,
-- AMBA_XMIT_SIZE);
-- if (c1 < c)
-- c = c1;
-- memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
-- info->xmit.head = (info->xmit.head + c) &
-- (AMBA_XMIT_SIZE - 1);
-- restore_flags(flags);
-- buf += c;
-- count -= c;
-- ret += c;
-- }
-- up(&tmp_buf_sem);
-- } else {
-- cli();
-- while (1) {
-- c = CIRC_SPACE_TO_END(info->xmit.head,
-- info->xmit.tail,
-- AMBA_XMIT_SIZE);
-- if (count < c)
-- c = count;
-- if (c <= 0)
-- break;
-- memcpy(info->xmit.buf + info->xmit.head, buf, c);
-- info->xmit.head = (info->xmit.head + c) &
-- (AMBA_XMIT_SIZE - 1);
-- buf += c;
-- count -= c;
-- ret += c;
-- }
-- restore_flags(flags);
-- }
-- if (info->xmit.head != info->xmit.tail
-- && !tty->stopped
-- && !tty->hw_stopped)
-- ambauart_enable_tx_interrupt(info);
-- return ret;
--}
--
--static int ambauart_write_room(struct tty_struct *tty)
--{
-- struct amba_info *info = tty->driver_data;
--
-- return CIRC_SPACE(info->xmit.head, info->xmit.tail, AMBA_XMIT_SIZE);
--}
--
--static int ambauart_chars_in_buffer(struct tty_struct *tty)
--{
-- struct amba_info *info = tty->driver_data;
--
-- return CIRC_CNT(info->xmit.head, info->xmit.tail, AMBA_XMIT_SIZE);
--}
--
--static void ambauart_flush_buffer(struct tty_struct *tty)
--{
-- struct amba_info *info = tty->driver_data;
-- unsigned long flags;
--
--#if DEBUG
-- printk("ambauart_flush_buffer(%d) called\n",
-- MINOR(tty->device) - tty->driver.minor_start);
--#endif
-- save_flags(flags); cli();
-- info->xmit.head = info->xmit.tail = 0;
-- restore_flags(flags);
-- wake_up_interruptible(&tty->write_wait);
-- if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-- tty->ldisc.write_wakeup)
-- (tty->ldisc.write_wakeup)(tty);
--}
--
--/*
-- * This function is used to send a high-priority XON/XOFF character to
-- * the device
-- */
--static void ambauart_send_xchar(struct tty_struct *tty, char ch)
--{
-- struct amba_info *info = tty->driver_data;
--
-- info->x_char = ch;
-- if (ch)
-- ambauart_enable_tx_interrupt(info);
--}
--
--static void ambauart_throttle(struct tty_struct *tty)
--{
-- struct amba_info *info = tty->driver_data;
-- unsigned long flags;
--
-- if (I_IXOFF(tty))
-- ambauart_send_xchar(tty, STOP_CHAR(tty));
--
-- if (tty->termios->c_cflag & CRTSCTS) {
-- save_flags(flags); cli();
-- info->mctrl &= ~TIOCM_RTS;
-- info->port->set_mctrl(info->port, info->mctrl);
-- restore_flags(flags);
-- }
--}
--
--static void ambauart_unthrottle(struct tty_struct *tty)
--{
-- struct amba_info *info = (struct amba_info *) tty->driver_data;
-- unsigned long flags;
--
-- if (I_IXOFF(tty)) {
-- if (info->x_char)
-- info->x_char = 0;
-- else
-- ambauart_send_xchar(tty, START_CHAR(tty));
-- }
--
-- if (tty->termios->c_cflag & CRTSCTS) {
-- save_flags(flags); cli();
-- info->mctrl |= TIOCM_RTS;
-- info->port->set_mctrl(info->port, info->mctrl);
-- restore_flags(flags);
-- }
--}
--
--static int get_serial_info(struct amba_info *info, struct serial_struct *retinfo)
--{
-- struct amba_state *state = info->state;
-- struct amba_port *port = info->port;
-- struct serial_struct tmp;
--
-- memset(&tmp, 0, sizeof(tmp));
-- tmp.type = 0;
-- tmp.line = state->line;
-- tmp.port = port->uart_base;
-- if (HIGH_BITS_OFFSET)
-- tmp.port_high = port->uart_base >> HIGH_BITS_OFFSET;
-- tmp.irq = port->irq;
-- tmp.flags = 0;
-- tmp.xmit_fifo_size = port->fifosize;
-- tmp.baud_base = port->uartclk / 16;
-- tmp.close_delay = state->close_delay;
-- tmp.closing_wait = state->closing_wait;
-- tmp.custom_divisor = state->custom_divisor;
--
-- if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
-- return -EFAULT;
-- return 0;
--}
--
--static int set_serial_info(struct amba_info *info,
-- struct serial_struct *newinfo)
--{
-- struct serial_struct new_serial;
-- struct amba_state *state, old_state;
-- struct amba_port *port;
-- unsigned long new_port;
-- unsigned int i, change_irq, change_port;
-- int retval = 0;
--
-- if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
-- return -EFAULT;
--
-- state = info->state;
-- old_state = *state;
-- port = info->port;
--
-- new_port = new_serial.port;
-- if (HIGH_BITS_OFFSET)
-- new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET;
--
-- change_irq = new_serial.irq != port->irq;
-- change_port = new_port != port->uart_base;
--
-- if (!capable(CAP_SYS_ADMIN)) {
-- if (change_irq || change_port ||
-- (new_serial.baud_base != port->uartclk / 16) ||
-- (new_serial.close_delay != state->close_delay) ||
-- (new_serial.xmit_fifo_size != port->fifosize) ||
-- ((new_serial.flags & ~ASYNC_USR_MASK) !=
-- (state->flags & ~ASYNC_USR_MASK)))
-- return -EPERM;
-- state->flags = ((state->flags & ~ASYNC_USR_MASK) |
-- (new_serial.flags & ASYNC_USR_MASK));
-- info->flags = ((info->flags & ~ASYNC_USR_MASK) |
-- (new_serial.flags & ASYNC_USR_MASK));
-- state->custom_divisor = new_serial.custom_divisor;
-- goto check_and_exit;
-- }
--
-- if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) ||
-- (new_serial.baud_base < 9600))
-- return -EINVAL;
--
-- if (new_serial.type && change_port) {
-- for (i = 0; i < SERIAL_AMBA_NR; i++)
-- if ((port != amba_ports + i) &&
-- amba_ports[i].uart_base != new_port)
-- return -EADDRINUSE;
-- }
--
-- if ((change_port || change_irq) && (state->count > 1))
-- return -EBUSY;
--
-- /*
-- * OK, past this point, all the error checking has been done.
-- * At this point, we start making changes.....
-- */
-- port->uartclk = new_serial.baud_base * 16;
-- state->flags = ((state->flags & ~ASYNC_FLAGS) |
-- (new_serial.flags & ASYNC_FLAGS));
-- info->flags = ((state->flags & ~ASYNC_INTERNAL_FLAGS) |
-- (info->flags & ASYNC_INTERNAL_FLAGS));
-- state->custom_divisor = new_serial.custom_divisor;
-- state->close_delay = new_serial.close_delay * HZ / 100;
-- state->closing_wait = new_serial.closing_wait * HZ / 100;
-- info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
-- port->fifosize = new_serial.xmit_fifo_size;
--
-- if (change_port || change_irq) {
-- /*
-- * We need to shutdown the serial port at the old
-- * port/irq combination.
-- */
-- ambauart_shutdown(info);
-- port->irq = new_serial.irq;
-- port->uart_base = new_port;
-- }
--
--check_and_exit:
-- if (!port->uart_base)
-- return 0;
-- if (info->flags & ASYNC_INITIALIZED) {
-- if ((old_state.flags & ASYNC_SPD_MASK) !=
-- (state->flags & ASYNC_SPD_MASK) ||
-- (old_state.custom_divisor != state->custom_divisor)) {
-- if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
-- info->tty->alt_speed = 57600;
-- if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
-- info->tty->alt_speed = 115200;
-- if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
-- info->tty->alt_speed = 230400;
-- if ((state->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
-- info->tty->alt_speed = 460800;
-- ambauart_change_speed(info, NULL);
-- }
-- } else
-- retval = ambauart_startup(info);
-- return retval;
--}
--
--
--/*
-- * get_lsr_info - get line status register info
-- */
--static int get_lsr_info(struct amba_info *info, unsigned int *value)
--{
-- unsigned int result, status;
-- unsigned long flags;
--
-- save_flags(flags); cli();
-- status = UART_GET_FR(info->port);
-- restore_flags(flags);
-- result = status & AMBA_UARTFR_BUSY ? TIOCSER_TEMT : 0;
--
-- /*
-- * If we're about to load something into the transmit
-- * register, we'll pretend the transmitter isn't empty to
-- * avoid a race condition (depending on when the transmit
-- * interrupt happens).
-- */
-- if (info->x_char ||
-- ((CIRC_CNT(info->xmit.head, info->xmit.tail,
-- AMBA_XMIT_SIZE) > 0) &&
-- !info->tty->stopped && !info->tty->hw_stopped))
-- result &= TIOCSER_TEMT;
--
-- return put_user(result, value);
--}
--
--static int get_modem_info(struct amba_info *info, unsigned int *value)
--{
-- unsigned int result = info->mctrl;
-- unsigned int status;
--
-- status = UART_GET_FR(info->port);
-- if (status & AMBA_UARTFR_DCD)
-- result |= TIOCM_CAR;
-- if (status & AMBA_UARTFR_DSR)
-- result |= TIOCM_DSR;
-- if (status & AMBA_UARTFR_CTS)
-- result |= TIOCM_CTS;
--
-- return put_user(result, value);
--}
--
--static int set_modem_info(struct amba_info *info, unsigned int cmd,
-- unsigned int *value)
--{
-- unsigned int arg, old;
-- unsigned long flags;
--
-- if (get_user(arg, value))
-- return -EFAULT;
--
-- old = info->mctrl;
-- switch (cmd) {
-- case TIOCMBIS:
-- info->mctrl |= arg;
-- break;
--
-- case TIOCMBIC:
-- info->mctrl &= ~arg;
-- break;
--
-- case TIOCMSET:
-- info->mctrl = arg;
-- break;
--
-- default:
-- return -EINVAL;
-- }
-- save_flags(flags); cli();
-- if (old != info->mctrl)
-- info->port->set_mctrl(info->port, info->mctrl);
-- restore_flags(flags);
-- return 0;
--}
--
--static void ambauart_break_ctl(struct tty_struct *tty, int break_state)
--{
-- struct amba_info *info = tty->driver_data;
-- unsigned long flags;
-- unsigned int lcr_h;
--
-- save_flags(flags); cli();
-- lcr_h = UART_GET_LCRH(info->port);
-- if (break_state == -1)
-- lcr_h |= AMBA_UARTLCR_H_BRK;
-- else
-- lcr_h &= ~AMBA_UARTLCR_H_BRK;
-- UART_PUT_LCRH(info->port, lcr_h);
-- restore_flags(flags);
--}
--
--static int ambauart_ioctl(struct tty_struct *tty, struct file *file,
-- unsigned int cmd, unsigned long arg)
--{
-- struct amba_info *info = tty->driver_data;
-- struct amba_icount cprev, cnow;
-- struct serial_icounter_struct icount;
-- unsigned long flags;
--
-- if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
-- (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
-- (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
-- if (tty->flags & (1 << TTY_IO_ERROR))
-- return -EIO;
-- }
--
-- switch (cmd) {
-- case TIOCMGET:
-- return get_modem_info(info, (unsigned int *)arg);
-- case TIOCMBIS:
-- case TIOCMBIC:
-- case TIOCMSET:
-- return set_modem_info(info, cmd, (unsigned int *)arg);
-- case TIOCGSERIAL:
-- return get_serial_info(info,
-- (struct serial_struct *)arg);
-- case TIOCSSERIAL:
-- return set_serial_info(info,
-- (struct serial_struct *)arg);
-- case TIOCSERGETLSR: /* Get line status register */
-- return get_lsr_info(info, (unsigned int *)arg);
-- /*
-- * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
-- * - mask passed in arg for lines of interest
-- * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
-- * Caller should use TIOCGICOUNT to see which one it was
-- */
-- case TIOCMIWAIT:
-- save_flags(flags); cli();
-- /* note the counters on entry */
-- cprev = info->state->icount;
-- /* Force modem status interrupts on */
-- UART_PUT_CR(info->port, UART_GET_CR(info->port) | AMBA_UARTCR_MSIE);
-- restore_flags(flags);
-- while (1) {
-- interruptible_sleep_on(&info->delta_msr_wait);
-- /* see if a signal did it */
-- if (signal_pending(current))
-- return -ERESTARTSYS;
-- save_flags(flags); cli();
-- cnow = info->state->icount; /* atomic copy */
-- restore_flags(flags);
-- if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
-- cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
-- return -EIO; /* no change => error */
-- if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
-- ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
-- ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
-- ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
-- return 0;
-- }
-- cprev = cnow;
-- }
-- /* NOTREACHED */
--
-- /*
-- * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
-- * Return: write counters to the user passed counter struct
-- * NB: both 1->0 and 0->1 transitions are counted except for
-- * RI where only 0->1 is counted.
-- */
-- case TIOCGICOUNT:
-- save_flags(flags); cli();
-- cnow = info->state->icount;
-- restore_flags(flags);
-- icount.cts = cnow.cts;
-- icount.dsr = cnow.dsr;
-- icount.rng = cnow.rng;
-- icount.dcd = cnow.dcd;
-- icount.rx = cnow.rx;
-- icount.tx = cnow.tx;
-- icount.frame = cnow.frame;
-- icount.overrun = cnow.overrun;
-- icount.parity = cnow.parity;
-- icount.brk = cnow.brk;
-- icount.buf_overrun = cnow.buf_overrun;
--
-- return copy_to_user((void *)arg, &icount, sizeof(icount))
-- ? -EFAULT : 0;
--
-- default:
-- return -ENOIOCTLCMD;
-- }
-- return 0;
--}
--
--static void ambauart_set_termios(struct tty_struct *tty, struct termios *old_termios)
--{
-- struct amba_info *info = tty->driver_data;
-- unsigned long flags;
-- unsigned int cflag = tty->termios->c_cflag;
--
-- if ((cflag ^ old_termios->c_cflag) == 0 &&
-- RELEVENT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)
-- return;
--
-- ambauart_change_speed(info, old_termios);
--
-- /* Handle transition to B0 status */
-- if ((old_termios->c_cflag & CBAUD) &&
-- !(cflag & CBAUD)) {
-- save_flags(flags); cli();
-- info->mctrl &= ~(TIOCM_RTS | TIOCM_DTR);
-- info->port->set_mctrl(info->port, info->mctrl);
-- restore_flags(flags);
-- }
--
-- /* Handle transition away from B0 status */
-- if (!(old_termios->c_cflag & CBAUD) &&
-- (cflag & CBAUD)) {
-- save_flags(flags); cli();
-- info->mctrl |= TIOCM_DTR;
-- if (!(cflag & CRTSCTS) ||
-- !test_bit(TTY_THROTTLED, &tty->flags))
-- info->mctrl |= TIOCM_RTS;
-- info->port->set_mctrl(info->port, info->mctrl);
-- restore_flags(flags);
-- }
--
-- /* Handle turning off CRTSCTS */
-- if ((old_termios->c_cflag & CRTSCTS) &&
-- !(cflag & CRTSCTS)) {
-- tty->hw_stopped = 0;
-- ambauart_start(tty);
-- }
--
--#if 0
-- /*
-- * No need to wake up processes in open wait, since they
-- * sample the CLOCAL flag once, and don't recheck it.
-- * XXX It's not clear whether the current behavior is correct
-- * or not. Hence, this may change.....
-- */
-- if (!(old_termios->c_cflag & CLOCAL) &&
-- (tty->termios->c_cflag & CLOCAL))
-- wake_up_interruptible(&info->open_wait);
--#endif
--}
--
--static void ambauart_close(struct tty_struct *tty, struct file *filp)
--{
-- struct amba_info *info = tty->driver_data;
-- struct amba_state *state;
-- unsigned long flags;
--
-- if (!info)
-- return;
--
-- state = info->state;
--
--#if DEBUG
-- printk("ambauart_close() called\n");
--#endif
--
-- save_flags(flags); cli();
--
-- if (tty_hung_up_p(filp)) {
-- MOD_DEC_USE_COUNT;
-- restore_flags(flags);
-- return;
-- }
--
-- if ((tty->count == 1) && (state->count != 1)) {
-- /*
-- * Uh, oh. tty->count is 1, which means that the tty
-- * structure will be freed. state->count should always
-- * be one in these conditions. If it's greater than
-- * one, we've got real problems, since it means the
-- * serial port won't be shutdown.
-- */
-- printk("ambauart_close: bad serial port count; tty->count is 1, "
-- "state->count is %d\n", state->count);
-- state->count = 1;
-- }
-- if (--state->count < 0) {
-- printk("rs_close: bad serial port count for %s%d: %d\n",
-- tty->driver.name, info->state->line, state->count);
-- state->count = 0;
-- }
-- if (state->count) {
-- MOD_DEC_USE_COUNT;
-- restore_flags(flags);
-- return;
-- }
-- info->flags |= ASYNC_CLOSING;
-- restore_flags(flags);
-- /*
-- * Save the termios structure, since this port may have
-- * separate termios for callout and dialin.
-- */
-- if (info->flags & ASYNC_NORMAL_ACTIVE)
-- info->state->normal_termios = *tty->termios;
-- if (info->flags & ASYNC_CALLOUT_ACTIVE)
-- info->state->callout_termios = *tty->termios;
-- /*
-- * Now we wait for the transmit buffer to clear; and we notify
-- * the line discipline to only process XON/XOFF characters.
-- */
-- tty->closing = 1;
-- if (info->state->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-- tty_wait_until_sent(tty, info->state->closing_wait);
-- /*
-- * At this point, we stop accepting input. To do this, we
-- * disable the receive line status interrupts.
-- */
-- if (info->flags & ASYNC_INITIALIZED) {
-- ambauart_disable_rx_interrupt(info);
-- /*
-- * Before we drop DTR, make sure the UART transmitter
-- * has completely drained; this is especially
-- * important if there is a transmit FIFO!
-- */
-- ambauart_wait_until_sent(tty, info->timeout);
-- }
-- ambauart_shutdown(info);
-- if (tty->driver.flush_buffer)
-- tty->driver.flush_buffer(tty);
-- if (tty->ldisc.flush_buffer)
-- tty->ldisc.flush_buffer(tty);
-- tty->closing = 0;
-- info->event = 0;
-- info->tty = NULL;
-- if (info->blocked_open) {
-- if (info->state->close_delay) {
-- set_current_state(TASK_INTERRUPTIBLE);
-- schedule_timeout(info->state->close_delay);
-- }
-- wake_up_interruptible(&info->open_wait);
-- }
-- info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|
-- ASYNC_CLOSING);
-- wake_up_interruptible(&info->close_wait);
-- MOD_DEC_USE_COUNT;
--}
--
--static void ambauart_wait_until_sent(struct tty_struct *tty, int timeout)
--{
-- struct amba_info *info = (struct amba_info *) tty->driver_data;
-- unsigned long char_time, expire;
-- unsigned int status;
--
-- if (info->port->fifosize == 0)
-- return;
--
-- /*
-- * Set the check interval to be 1/5 of the estimated time to
-- * send a single character, and make it at least 1. The check
-- * interval should also be less than the timeout.
-- *
-- * Note: we have to use pretty tight timings here to satisfy
-- * the NIST-PCTS.
-- */
-- char_time = (info->timeout - HZ/50) / info->port->fifosize;
-- char_time = char_time / 5;
-- if (char_time == 0)
-- char_time = 1;
-- if (timeout && timeout < char_time)
-- char_time = timeout;
-- /*
-- * If the transmitter hasn't cleared in twice the approximate
-- * amount of time to send the entire FIFO, it probably won't
-- * ever clear. This assumes the UART isn't doing flow
-- * control, which is currently the case. Hence, if it ever
-- * takes longer than info->timeout, this is probably due to a
-- * UART bug of some kind. So, we clamp the timeout parameter at
-- * 2*info->timeout.
-- */
-- if (!timeout || timeout > 2 * info->timeout)
-- timeout = 2 * info->timeout;
--
-- expire = jiffies + timeout;
--#if DEBUG
-- printk("ambauart_wait_until_sent(%d), jiff=%lu, expire=%lu...\n",
-- MINOR(tty->device) - tty->driver.minor_start, jiffies,
-- expire);
--#endif
-- while (UART_GET_FR(info->port) & AMBA_UARTFR_BUSY) {
-- set_current_state(TASK_INTERRUPTIBLE);
-- schedule_timeout(char_time);
-- if (signal_pending(current))
-- break;
-- if (timeout && time_after(jiffies, expire))
-- break;
-- status = UART_GET_FR(info->port);
-- }
-- set_current_state(TASK_RUNNING);
--}
--
--static void ambauart_hangup(struct tty_struct *tty)
--{
-- struct amba_info *info = tty->driver_data;
-- struct amba_state *state = info->state;
--
-- ambauart_flush_buffer(tty);
-- if (info->flags & ASYNC_CLOSING)
-- return;
-- ambauart_shutdown(info);
-- info->event = 0;
-- state->count = 0;
-- info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
-- info->tty = NULL;
-- wake_up_interruptible(&info->open_wait);
--}
--
--static int block_til_ready(struct tty_struct *tty, struct file *filp,
-- struct amba_info *info)
--{
-- DECLARE_WAITQUEUE(wait, current);
-- struct amba_state *state = info->state;
-- unsigned long flags;
-- int do_clocal = 0, extra_count = 0, retval;
--
-- /*
-- * If the device is in the middle of being closed, then block
-- * until it's done, and then try again.
-- */
-- if (tty_hung_up_p(filp) ||
-- (info->flags & ASYNC_CLOSING)) {
-- if (info->flags & ASYNC_CLOSING)
-- interruptible_sleep_on(&info->close_wait);
-- return (info->flags & ASYNC_HUP_NOTIFY) ?
-- -EAGAIN : -ERESTARTSYS;
-- }
--
-- /*
-- * If this is a callout device, then just make sure the normal
-- * device isn't being used.
-- */
-- if (tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
-- if (info->flags & ASYNC_NORMAL_ACTIVE)
-- return -EBUSY;
-- if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-- (info->flags & ASYNC_SESSION_LOCKOUT) &&
-- (info->session != current->session))
-- return -EBUSY;
-- if ((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-- (info->flags & ASYNC_PGRP_LOCKOUT) &&
-- (info->pgrp != current->pgrp))
-- return -EBUSY;
-- info->flags |= ASYNC_CALLOUT_ACTIVE;
-- return 0;
-- }
--
-- /*
-- * If non-blocking mode is set, or the port is not enabled,
-- * then make the check up front and then exit.
-- */
-- if ((filp->f_flags & O_NONBLOCK) ||
-- (tty->flags & (1 << TTY_IO_ERROR))) {
-- if (info->flags & ASYNC_CALLOUT_ACTIVE)
-- return -EBUSY;
-- info->flags |= ASYNC_NORMAL_ACTIVE;
-- return 0;
-- }
--
-- if (info->flags & ASYNC_CALLOUT_ACTIVE) {
-- if (state->normal_termios.c_cflag & CLOCAL)
-- do_clocal = 1;
-- } else {
-- if (tty->termios->c_cflag & CLOCAL)
-- do_clocal = 1;
-- }
--
-- /*
-- * Block waiting for the carrier detect and the line to become
-- * free (i.e., not in use by the callout). While we are in
-- * this loop, state->count is dropped by one, so that
-- * rs_close() knows when to free things. We restore it upon
-- * exit, either normal or abnormal.
-- */
-- retval = 0;
-- add_wait_queue(&info->open_wait, &wait);
-- save_flags(flags); cli();
-- if (!tty_hung_up_p(filp)) {
-- extra_count = 1;
-- state->count--;
-- }
-- restore_flags(flags);
-- info->blocked_open++;
-- while (1) {
-- save_flags(flags); cli();
-- if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-- (tty->termios->c_cflag & CBAUD)) {
-- info->mctrl = TIOCM_DTR | TIOCM_RTS;
-- info->port->set_mctrl(info->port, info->mctrl);
-- }
-- restore_flags(flags);
-- set_current_state(TASK_INTERRUPTIBLE);
-- if (tty_hung_up_p(filp) ||
-- !(info->flags & ASYNC_INITIALIZED)) {
-- if (info->flags & ASYNC_HUP_NOTIFY)
-- retval = -EAGAIN;
-- else
-- retval = -ERESTARTSYS;
-- break;
-- }
-- if (!(info->flags & ASYNC_CALLOUT_ACTIVE) &&
-- !(info->flags & ASYNC_CLOSING) &&
-- (do_clocal || (UART_GET_FR(info->port) & AMBA_UARTFR_DCD)))
-- break;
-- if (signal_pending(current)) {
-- retval = -ERESTARTSYS;
-- break;
-- }
-- schedule();
-- }
-- set_current_state(TASK_RUNNING);
-- remove_wait_queue(&info->open_wait, &wait);
-- if (extra_count)
-- state->count++;
-- info->blocked_open--;
-- if (retval)
-- return retval;
-- info->flags |= ASYNC_NORMAL_ACTIVE;
-- return 0;
--}
--
--static struct amba_info *ambauart_get(int line)
--{
-- struct amba_info *info;
-- struct amba_state *state = amba_state + line;
--
-- state->count++;
-- if (state->info)
-- return state->info;
-- info = kmalloc(sizeof(struct amba_info), GFP_KERNEL);
-- if (info) {
-- memset(info, 0, sizeof(struct amba_info));
-- init_waitqueue_head(&info->open_wait);
-- init_waitqueue_head(&info->close_wait);
-- init_waitqueue_head(&info->delta_msr_wait);
-- info->flags = state->flags;
-- info->state = state;
-- info->port = amba_ports + line;
-- tasklet_init(&info->tlet, ambauart_tasklet_action,
-- (unsigned long)info);
-- }
-- if (state->info) {
-- kfree(info);
-- return state->info;
-- }
-- state->info = info;
-- return info;
--}
--
--static int ambauart_open(struct tty_struct *tty, struct file *filp)
--{
-- struct amba_info *info;
-- int retval, line = MINOR(tty->device) - tty->driver.minor_start;
--
--#if DEBUG
-- printk("ambauart_open(%d) called\n", line);
--#endif
--
-- // is this a line that we've got?
-- MOD_INC_USE_COUNT;
-- if (line >= SERIAL_AMBA_NR) {
-- MOD_DEC_USE_COUNT;
-- return -ENODEV;
-- }
--
-- info = ambauart_get(line);
-- if (!info)
-- return -ENOMEM;
--
-- tty->driver_data = info;
-- info->tty = tty;
-- info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
--
-- /*
-- * Make sure we have the temporary buffer allocated
-- */
-- if (!tmp_buf) {
-- unsigned long page = get_zeroed_page(GFP_KERNEL);
-- if (tmp_buf)
-- free_page(page);
-- else if (!page) {
-- MOD_DEC_USE_COUNT;
-- return -ENOMEM;
-- }
-- tmp_buf = (u_char *)page;
-- }
--
-- /*
-- * If the port is in the middle of closing, bail out now.
-- */
-- if (tty_hung_up_p(filp) ||
-- (info->flags & ASYNC_CLOSING)) {
-- if (info->flags & ASYNC_CLOSING)
-- interruptible_sleep_on(&info->close_wait);
-- MOD_DEC_USE_COUNT;
-- return -EAGAIN;
-- }
--
-- /*
-- * Start up the serial port
-- */
-- retval = ambauart_startup(info);
-- if (retval) {
-- MOD_DEC_USE_COUNT;
-- return retval;
-- }
--
-- retval = block_til_ready(tty, filp, info);
-- if (retval) {
-- MOD_DEC_USE_COUNT;
-- return retval;
-- }
--
-- if ((info->state->count == 1) &&
-- (info->flags & ASYNC_SPLIT_TERMIOS)) {
-- if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
-- *tty->termios = info->state->normal_termios;
-- else
-- *tty->termios = info->state->callout_termios;
-- }
--#ifdef CONFIG_SERIAL_AMBA_CONSOLE
-- if (ambauart_cons.cflag && ambauart_cons.index == line) {
-- tty->termios->c_cflag = ambauart_cons.cflag;
-- ambauart_cons.cflag = 0;
-- }
--#endif
-- ambauart_change_speed(info, NULL);
-- info->session = current->session;
-- info->pgrp = current->pgrp;
-- return 0;
--}
--
--int __init ambauart_init(void)
--{
-- int i;
--
-- ambanormal_driver.magic = TTY_DRIVER_MAGIC;
-- ambanormal_driver.driver_name = "serial_amba";
-- ambanormal_driver.name = SERIAL_AMBA_NAME;
-- ambanormal_driver.major = SERIAL_AMBA_MAJOR;
-- ambanormal_driver.minor_start = SERIAL_AMBA_MINOR;
-- ambanormal_driver.num = SERIAL_AMBA_NR;
-- ambanormal_driver.type = TTY_DRIVER_TYPE_SERIAL;
-- ambanormal_driver.subtype = SERIAL_TYPE_NORMAL;
-- ambanormal_driver.init_termios = tty_std_termios;
-- ambanormal_driver.init_termios.c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
-- ambanormal_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
-- ambanormal_driver.refcount = &ambauart_refcount;
-- ambanormal_driver.table = ambauart_table;
-- ambanormal_driver.termios = ambauart_termios;
-- ambanormal_driver.termios_locked = ambauart_termios_locked;
--
-- ambanormal_driver.open = ambauart_open;
-- ambanormal_driver.close = ambauart_close;
-- ambanormal_driver.write = ambauart_write;
-- ambanormal_driver.put_char = ambauart_put_char;
-- ambanormal_driver.flush_chars = ambauart_flush_chars;
-- ambanormal_driver.write_room = ambauart_write_room;
-- ambanormal_driver.chars_in_buffer = ambauart_chars_in_buffer;
-- ambanormal_driver.flush_buffer = ambauart_flush_buffer;
-- ambanormal_driver.ioctl = ambauart_ioctl;
-- ambanormal_driver.throttle = ambauart_throttle;
-- ambanormal_driver.unthrottle = ambauart_unthrottle;
-- ambanormal_driver.send_xchar = ambauart_send_xchar;
-- ambanormal_driver.set_termios = ambauart_set_termios;
-- ambanormal_driver.stop = ambauart_stop;
-- ambanormal_driver.start = ambauart_start;
-- ambanormal_driver.hangup = ambauart_hangup;
-- ambanormal_driver.break_ctl = ambauart_break_ctl;
-- ambanormal_driver.wait_until_sent = ambauart_wait_until_sent;
-- ambanormal_driver.read_proc = NULL;
--
-- /*
-- * The callout device is just like the normal device except for
-- * the major number and the subtype code.
-- */
-- ambacallout_driver = ambanormal_driver;
-- ambacallout_driver.name = CALLOUT_AMBA_NAME;
-- ambacallout_driver.major = CALLOUT_AMBA_MAJOR;
-- ambacallout_driver.subtype = SERIAL_TYPE_CALLOUT;
-- ambacallout_driver.read_proc = NULL;
-- ambacallout_driver.proc_entry = NULL;
--
-- if (tty_register_driver(&ambanormal_driver))
-- panic("Couldn't register AMBA serial driver\n");
-- if (tty_register_driver(&ambacallout_driver))
-- panic("Couldn't register AMBA callout driver\n");
--
-- for (i = 0; i < SERIAL_AMBA_NR; i++) {
-- struct amba_state *state = amba_state + i;
-- state->line = i;
-- state->close_delay = 5 * HZ / 10;
-- state->closing_wait = 30 * HZ;
-- state->callout_termios = ambacallout_driver.init_termios;
-- state->normal_termios = ambanormal_driver.init_termios;
-- }
--
-- return 0;
--}
--
--__initcall(ambauart_init);
--
--#ifdef CONFIG_SERIAL_AMBA_CONSOLE
--/************** console driver *****************/
--
--/*
-- * This code is currently never used; console->read is never called.
-- * Therefore, although we have an implementation, we don't use it.
-- * FIXME: the "const char *s" should be fixed to "char *s" some day.
-- * (when the definition in include/linux/console.h is also fixed)
-- */
--#ifdef used_and_not_const_char_pointer
--static int ambauart_console_read(struct console *co, const char *s, u_int count)
--{
-- struct amba_port *port = &amba_ports[co->index];
-- unsigned int status;
-- char *w;
-- int c;
--#if DEBUG
-- printk("ambauart_console_read() called\n");
--#endif
--
-- c = 0;
-- w = s;
-- while (c < count) {
-- status = UART_GET_FR(port);
-- if (UART_RX_DATA(status)) {
-- *w++ = UART_GET_CHAR(port);
-- c++;
-- } else {
-- // nothing more to get, return
-- return c;
-- }
-- }
-- // return the count
-- return c;
--}
--#endif
--
--/*
-- * Print a string to the serial port trying not to disturb
-- * any possible real use of the port...
-- *
-- * The console must be locked when we get here.
-- */
--static void ambauart_console_write(struct console *co, const char *s, u_int count)
--{
-- struct amba_port *port = &amba_ports[co->index];
-- unsigned int status, old_cr;
-- int i;
--
-- /*
-- * First save the CR then disable the interrupts
-- */
-- old_cr = UART_GET_CR(port);
-- UART_PUT_CR(port, AMBA_UARTCR_UARTEN);
--
-- /*
-- * Now, do each character
-- */
-- for (i = 0; i < count; i++) {
-- do {
-- status = UART_GET_FR(port);
-- } while (!UART_TX_READY(status));
-- UART_PUT_CHAR(port, s[i]);
-- if (s[i] == '\n') {
-- do {
-- status = UART_GET_FR(port);
-- } while (!UART_TX_READY(status));
-- UART_PUT_CHAR(port, '\r');
-- }
-- }
--
-- /*
-- * Finally, wait for transmitter to become empty
-- * and restore the TCR
-- */
-- do {
-- status = UART_GET_FR(port);
-- } while (status & AMBA_UARTFR_BUSY);
-- UART_PUT_CR(port, old_cr);
--}
--
--static kdev_t ambauart_console_device(struct console *c)
--{
-- return MKDEV(SERIAL_AMBA_MAJOR, SERIAL_AMBA_MINOR + c->index);
--}
--
--static int __init ambauart_console_setup(struct console *co, char *options)
--{
-- struct amba_port *port;
-- int baud = 38400;
-- int bits = 8;
-- int parity = 'n';
-- u_int cflag = CREAD | HUPCL | CLOCAL;
-- u_int lcr_h, quot;
--
-- if (co->index >= SERIAL_AMBA_NR)
-- co->index = 0;
--
-- port = &amba_ports[co->index];
--
-- if (options) {
-- char *s = options;
-- baud = simple_strtoul(s, NULL, 10);
-- while (*s >= '0' && *s <= '9')
-- s++;
-- if (*s) parity = *s++;
-- if (*s) bits = *s - '0';
-- }
--
-- /*
-- * Now construct a cflag setting.
-- */
-- switch (baud) {
-- case 1200: cflag |= B1200; break;
-- case 2400: cflag |= B2400; break;
-- case 4800: cflag |= B4800; break;
-- default: cflag |= B9600; baud = 9600; break;
-- case 19200: cflag |= B19200; break;
-- case 38400: cflag |= B38400; break;
-- case 57600: cflag |= B57600; break;
-- case 115200: cflag |= B115200; break;
-- }
-- switch (bits) {
-- case 7: cflag |= CS7; lcr_h = AMBA_UARTLCR_H_WLEN_7; break;
-- default: cflag |= CS8; lcr_h = AMBA_UARTLCR_H_WLEN_8; break;
-- }
-- switch (parity) {
-- case 'o':
-- case 'O': cflag |= PARODD; lcr_h |= AMBA_UARTLCR_H_PEN; break;
-- case 'e':
-- case 'E': cflag |= PARENB; lcr_h |= AMBA_UARTLCR_H_PEN |
-- AMBA_UARTLCR_H_EPS; break;
-- }
--
-- co->cflag = cflag;
--
-- if (port->fifosize > 1)
-- lcr_h |= AMBA_UARTLCR_H_FEN;
--
-- quot = (port->uartclk / (16 * baud)) - 1;
--
-- UART_PUT_LCRL(port, (quot & 0xff));
-- UART_PUT_LCRM(port, (quot >> 8));
-- UART_PUT_LCRH(port, lcr_h);
--
-- /* we will enable the port as we need it */
-- UART_PUT_CR(port, 0);
--
-- return 0;
--}
--
--static struct console ambauart_cons =
--{
-- name: SERIAL_AMBA_NAME,
-- write: ambauart_console_write,
--#ifdef used_and_not_const_char_pointer
-- read: ambauart_console_read,
--#endif
-- device: ambauart_console_device,
-- setup: ambauart_console_setup,
-- flags: CON_PRINTBUFFER,
-- index: -1,
--};
--
--void __init ambauart_console_init(void)
--{
-- register_console(&ambauart_cons);
--}
--
--#endif /* CONFIG_SERIAL_AMBA_CONSOLE */
--
--MODULE_LICENSE("GPL");
--EXPORT_NO_SYMBOLS;
---- linux-2.4.25/drivers/char/tty_io.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/char/tty_io.c 2004-03-31 17:15:09.000000000 +0200
-@@ -19,7 +19,7 @@
- * Also restructured routines so that there is more of a separation
- * between the high-level tty routines (tty_io.c and tty_ioctl.c) and
- * the low-level tty routines (serial.c, pty.c, console.c). This
-- * makes for cleaner and more compact code. -TYT, 9/17/92
-+ * makes for cleaner and more compact code. -TYT, 9/17/92
- *
- * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines
- * which can be dynamically activated and de-activated by the line
-@@ -41,7 +41,7 @@
- *
- * New TIOCLINUX variants added.
- * -- mj@k332.feld.cvut.cz, 19-Nov-95
-- *
-+ *
- * Restrict vt switching via ioctl()
- * -- grif@cs.ucr.edu, 5-Dec-95
- *
-@@ -151,8 +151,7 @@
- extern void tty3215_init(void);
- extern void tub3270_con_init(void);
- extern void tub3270_init(void);
--extern void rs285_console_init(void);
--extern void sa1100_rs_console_init(void);
-+extern void uart_console_init(void);
- extern void sgi_serial_console_init(void);
- extern void sn_sal_serial_console_init(void);
- extern void sci_console_init(void);
-@@ -164,6 +163,7 @@
- extern void txx9_serial_console_init(void);
- extern void sb1250_serial_console_init(void);
- extern void arc_console_init(void);
-+extern void rs285_console_init(void);
- extern int hvc_console_init(void);
-
- #ifndef MIN
-@@ -201,7 +201,7 @@
- else
- sprintf(buf, name,
- idx + tty->driver.name_base);
--
-+
- return buf;
- }
-
-@@ -239,7 +239,7 @@
- #ifdef CHECK_TTY_COUNT
- struct list_head *p;
- int count = 0;
--
-+
- file_list_lock();
- for(p = tty->tty_files.next; p != &tty->tty_files; p = p->next) {
- if(list_entry(p, struct file, f_list)->private_data == tty)
-@@ -255,7 +255,7 @@
- "!= #fd's(%d) in %s\n",
- kdevname(tty->device), tty->count, count, routine);
- return count;
-- }
-+ }
- #endif
- return 0;
- }
-@@ -264,14 +264,14 @@
- {
- if (disc < N_TTY || disc >= NR_LDISCS)
- return -EINVAL;
--
-+
- if (new_ldisc) {
- ldiscs[disc] = *new_ldisc;
- ldiscs[disc].flags |= LDISC_FLAG_DEFINED;
- ldiscs[disc].num = disc;
- } else
- memset(&ldiscs[disc], 0, sizeof(struct tty_ldisc));
--
-+
- return 0;
- }
-
-@@ -301,7 +301,7 @@
- o_ldisc = tty->ldisc;
-
- tty_wait_until_sent(tty, 0);
--
-+
- /* Shutdown the current discipline. */
- if (tty->ldisc.close)
- (tty->ldisc.close)(tty);
-@@ -339,7 +339,7 @@
- {
- int major, minor;
- struct tty_driver *p;
--
-+
- minor = MINOR(device);
- major = MAJOR(device);
-
-@@ -456,7 +456,7 @@
- redirect = NULL;
- }
- spin_unlock(&redirect_lock);
--
-+
- check_tty_count(tty, "do_tty_hangup");
- file_list_lock();
- for (l = tty->tty_files.next; l != &tty->tty_files; l = l->next) {
-@@ -473,7 +473,7 @@
- filp->f_op = &hung_up_tty_fops;
- }
- file_list_unlock();
--
-+
- /* FIXME! What are the locking issues here? This may me overdoing things.. */
- {
- unsigned long flags;
-@@ -510,7 +510,7 @@
- "error %d\n", -i);
- }
- }
--
-+
- read_lock(&tasklist_lock);
- for_each_task(p) {
- if ((tty->session > 0) && (p->session == tty->session) &&
-@@ -550,7 +550,7 @@
- {
- #ifdef TTY_DEBUG_HANGUP
- char buf[64];
--
-+
- printk(KERN_DEBUG "%s hangup...\n", tty_name(tty, buf));
- #endif
- schedule_task(&tty->tq_hangup);
-@@ -650,7 +650,7 @@
- wake_up_interruptible(&tty->write_wait);
- }
-
--static ssize_t tty_read(struct file * file, char * buf, size_t count,
-+static ssize_t tty_read(struct file * file, char * buf, size_t count,
- loff_t *ppos)
- {
- int i;
-@@ -707,7 +707,7 @@
- size_t count)
- {
- ssize_t ret = 0, written = 0;
--
-+
- if (file->f_flags & O_NONBLOCK) {
- if (down_trylock(&tty->atomic_write))
- return -EAGAIN;
-@@ -835,7 +835,7 @@
- struct tty_struct *tty, *o_tty;
- struct termios *tp, **tp_loc, *o_tp, **o_tp_loc;
- struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
-- struct tty_driver *driver;
-+ struct tty_driver *driver;
- int retval=0;
- int idx;
-
-@@ -845,7 +845,7 @@
-
- idx = MINOR(device) - driver->minor_start;
-
-- /*
-+ /*
- * Check whether we need to acquire the tty semaphore to avoid
- * race conditions. For now, play it safe.
- */
-@@ -859,7 +859,7 @@
- * First time open is complex, especially for PTY devices.
- * This code guarantees that either everything succeeds and the
- * TTY is ready for operation, or else the table slots are vacated
-- * and the allocated memory released. (Except that the termios
-+ * and the allocated memory released. (Except that the termios
- * and locked termios may be retained.)
- */
-
-@@ -938,13 +938,13 @@
- o_tty->link = tty;
- }
-
-- /*
-+ /*
- * All structures have been allocated, so now we install them.
-- * Failures after this point use release_mem to clean up, so
-+ * Failures after this point use release_mem to clean up, so
- * there's no need to null out the local pointers.
- */
- driver->table[idx] = tty;
--
-+
- if (!*tp_loc)
- *tp_loc = tp;
- if (!*ltp_loc)
-@@ -954,7 +954,7 @@
- (*driver->refcount)++;
- tty->count++;
-
-- /*
-+ /*
- * Structures all installed ... call the ldisc open routines.
- * If we fail here just call release_mem to clean up. No need
- * to decrement the use counts, as release_mem doesn't care.
-@@ -988,7 +988,7 @@
- if (driver->type == TTY_DRIVER_TYPE_PTY &&
- driver->subtype == PTY_TYPE_MASTER) {
- /*
-- * special case for PTY masters: only one open permitted,
-+ * special case for PTY masters: only one open permitted,
- * and the slave side open count is incremented as well.
- */
- if (tty->count) {
-@@ -1002,7 +1002,7 @@
-
- success:
- *ret_tty = tty;
--
-+
- /* All paths come through here to release the semaphore */
- end_init:
- up_tty_sem(idx);
-@@ -1080,7 +1080,7 @@
- int pty_master, tty_closing, o_tty_closing, do_sleep;
- int idx;
- char buf[64];
--
-+
- tty = (struct tty_struct *)filp->private_data;
- if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "release_dev"))
- return;
-@@ -1138,7 +1138,7 @@
- idx, kdevname(tty->device));
- return;
- }
-- if (o_tty->termios_locked !=
-+ if (o_tty->termios_locked !=
- tty->driver.other->termios_locked[idx]) {
- printk(KERN_DEBUG "release_dev: other->termios_locked["
- "%d] not o_termios_locked for (%s)\n",
-@@ -1204,11 +1204,11 @@
- printk(KERN_WARNING "release_dev: %s: read/write wait queue "
- "active!\n", tty_name(tty, buf));
- schedule();
-- }
-+ }
-
- /*
-- * The closing flags are now consistent with the open counts on
-- * both sides, and we've completed the last operation that could
-+ * The closing flags are now consistent with the open counts on
-+ * both sides, and we've completed the last operation that could
- * block, so it's safe to proceed with closing.
- */
- if (pty_master) {
-@@ -1266,7 +1266,7 @@
- /* check whether both sides are closing ... */
- if (!tty_closing || (o_tty && !o_tty_closing))
- return;
--
-+
- #ifdef TTY_DEBUG_HANGUP
- printk(KERN_DEBUG "freeing tty structure...");
- #endif
-@@ -1284,14 +1284,14 @@
- (o_tty->ldisc.close)(o_tty);
- o_tty->ldisc = ldiscs[N_TTY];
- }
--
-+
- /*
-- * Make sure that the tty's task queue isn't activated.
-+ * Make sure that the tty's task queue isn't activated.
- */
- run_task_queue(&tq_timer);
- flush_scheduled_tasks();
-
-- /*
-+ /*
- * The release_mem function takes care of the details of clearing
- * the slots and preserving the termios structure.
- */
-@@ -1482,7 +1482,7 @@
- tty = (struct tty_struct *)filp->private_data;
- if (tty_paranoia_check(tty, filp->f_dentry->d_inode->i_rdev, "tty_fasync"))
- return 0;
--
-+
- retval = fasync_helper(fd, filp, on, &tty->fasync);
- if (retval <= 0)
- return retval;
-@@ -1697,7 +1697,7 @@
-
- static int tty_generic_brk(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg)
- {
-- if (cmd == TCSBRK && arg)
-+ if (cmd == TCSBRK && arg)
- {
- /* tcdrain case */
- int retval = tty_check_change(tty);
-@@ -1718,7 +1718,7 @@
- {
- struct tty_struct *tty, *real_tty;
- int retval;
--
-+
- tty = (struct tty_struct *)file->private_data;
- if (tty_paranoia_check(tty, inode->i_rdev, "tty_ioctl"))
- return -EINVAL;
-@@ -1738,7 +1738,7 @@
- if (tty->driver.ioctl)
- return tty->driver.ioctl(tty, file, cmd, arg);
- return -EINVAL;
--
-+
- /* These two ioctl's always return success; even if */
- /* the driver doesn't support them. */
- case TCSBRK:
-@@ -1761,7 +1761,7 @@
- case TIOCSBRK:
- case TIOCCBRK:
- case TCSBRK:
-- case TCSBRKP:
-+ case TCSBRKP:
- retval = tty_check_change(tty);
- if (retval)
- return retval;
-@@ -1824,7 +1824,7 @@
- case TIOCSBRK: /* Turn break on, unconditionally */
- tty->driver.break_ctl(tty, -1);
- return 0;
--
-+
- case TIOCCBRK: /* Turn break off, unconditionally */
- tty->driver.break_ctl(tty, 0);
- return 0;
-@@ -1837,7 +1837,7 @@
- if (!arg)
- return send_break(tty, HZ/4);
- return 0;
-- case TCSBRKP: /* support for POSIX tcsendbreak() */
-+ case TCSBRKP: /* support for POSIX tcsendbreak() */
- return send_break(tty, arg ? arg*(HZ/10) : HZ/4);
- }
- if (tty->driver.ioctl) {
-@@ -1859,7 +1859,7 @@
- * prevent trojan horses by killing all processes associated with this
- * tty when the user hits the "Secure Attention Key". Required for
- * super-paranoid applications --- see the Orange Book for more details.
-- *
-+ *
- * This code could be nicer; ideally it should send a HUP, wait a few
- * seconds, then send a INT, and then a KILL signal. But you then
- * have to coordinate with the init process, since all processes associated
-@@ -1883,7 +1883,7 @@
- int session;
- int i;
- struct file *filp;
--
-+
- if (!tty)
- return;
- session = tty->session;
-@@ -1968,7 +1968,7 @@
- count = tty->flip.count;
- tty->flip.count = 0;
- restore_flags(flags);
--
-+
- tty->ldisc.receive_buf(tty, cp, fp, count);
- }
-
-@@ -2000,7 +2000,7 @@
- i = cflag & CBAUD;
- if (i & CBAUDEX) {
- i &= ~CBAUDEX;
-- if (i < 1 || i+15 >= n_baud_table)
-+ if (i < 1 || i+15 >= n_baud_table)
- tty->termios->c_cflag &= ~CBAUDEX;
- else
- i += 15;
-@@ -2013,7 +2013,7 @@
- }
- return(tty->alt_speed);
- }
--
-+
- return baud_table[i];
- }
-
-@@ -2079,7 +2079,7 @@
- mode |= S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
- break;
- }
-- if ( (minor < driver->minor_start) ||
-+ if ( (minor < driver->minor_start) ||
- (minor >= driver->minor_start + driver->num) ) {
- printk(KERN_ERR "Attempt to register invalid minor number "
- "with devfs (%d:%d).\n", (int)driver->major,(int)minor);
-@@ -2132,12 +2132,12 @@
-
- if (!driver->put_char)
- driver->put_char = tty_default_put_char;
--
-+
- driver->prev = 0;
- driver->next = tty_drivers;
- if (tty_drivers) tty_drivers->prev = driver;
- tty_drivers = driver;
--
-+
- if ( !(driver->flags & TTY_DRIVER_NO_DEVFS) ) {
- for(i = 0; i < driver->num; i++)
- tty_register_devfs(driver, 0, driver->minor_start + i);
-@@ -2156,7 +2156,7 @@
- int i, found = 0;
- struct termios *tp;
- const char *othername = NULL;
--
-+
- if (*driver->refcount)
- return -EBUSY;
-
-@@ -2166,7 +2166,7 @@
- else if (p->major == driver->major)
- othername = p->name;
- }
--
-+
- if (!found)
- return -ENOENT;
-
-@@ -2181,7 +2181,7 @@
- driver->prev->next = driver->next;
- else
- tty_drivers = driver->next;
--
-+
- if (driver->next)
- driver->next->prev = driver->prev;
-
-@@ -2221,7 +2221,7 @@
- (void) tty_register_ldisc(N_TTY, &tty_ldisc_N_TTY);
-
- /*
-- * Set up the standard termios. Individual tty drivers may
-+ * Set up the standard termios. Individual tty drivers may
- * deviate from this; this is used as a template.
- */
- memset(&tty_std_termios, 0, sizeof(struct termios));
-@@ -2233,11 +2233,11 @@
- ECHOCTL | ECHOKE | IEXTEN;
-
- /*
-- * set up the console device so that later boot sequences can
-+ * set up the console device so that later boot sequences can
- * inform about problems etc..
- */
- #ifdef CONFIG_EARLY_PRINTK
-- disable_early_printk();
-+ disable_early_printk();
- #endif
- #ifdef CONFIG_HVC_CONSOLE
- hvc_console_init();
-@@ -2288,18 +2288,12 @@
- #ifdef CONFIG_STDIO_CONSOLE
- stdio_console_init();
- #endif
--#ifdef CONFIG_SERIAL_21285_CONSOLE
-- rs285_console_init();
--#endif
--#ifdef CONFIG_SERIAL_SA1100_CONSOLE
-- sa1100_rs_console_init();
-+#ifdef CONFIG_SERIAL_CORE_CONSOLE
-+ uart_console_init();
- #endif
- #ifdef CONFIG_ARC_CONSOLE
- arc_console_init();
- #endif
--#ifdef CONFIG_SERIAL_AMBA_CONSOLE
-- ambauart_console_init();
--#endif
- #ifdef CONFIG_SERIAL_TX3912_CONSOLE
- tx3912_console_init();
- #endif
-@@ -2315,6 +2309,9 @@
- #ifdef CONFIG_IP22_SERIAL
- sgi_serial_console_init();
- #endif
-+#ifdef CONFIG_SERIAL_21285_CONSOLE
-+ rs285_console_init();
-+#endif
- }
-
- static struct tty_driver dev_tty_driver, dev_syscons_driver;
-@@ -2347,7 +2344,7 @@
- dev_tty_driver.num = 1;
- dev_tty_driver.type = TTY_DRIVER_TYPE_SYSTEM;
- dev_tty_driver.subtype = SYSTEM_TYPE_TTY;
--
-+
- if (tty_register_driver(&dev_tty_driver))
- panic("Couldn't register /dev/tty driver\n");
-
-@@ -2363,7 +2360,7 @@
- panic("Couldn't register /dev/console driver\n");
-
- /* console calls tty_register_driver() before kmalloc() works.
-- * Thus, we can't devfs_register() then. Do so now, instead.
-+ * Thus, we can't devfs_register() then. Do so now, instead.
- */
- #ifdef CONFIG_VT
- con_init_devfs();
-@@ -2381,7 +2378,7 @@
- if (tty_register_driver(&dev_ptmx_driver))
- panic("Couldn't register /dev/ptmx driver\n");
- #endif
--
-+
- #ifdef CONFIG_VT
- dev_console_driver = dev_tty_driver;
- dev_console_driver.driver_name = "/dev/vc/0";
-@@ -2441,10 +2438,10 @@
- pty_init();
- #ifdef CONFIG_MOXA_SMARTIO
- mxser_init();
--#endif
-+#endif
- #ifdef CONFIG_MOXA_INTELLIO
- moxa_init();
--#endif
-+#endif
- #ifdef CONFIG_VT
- vcs_init();
- #endif
---- linux-2.4.25/drivers/char/wdt285.c~2.4.25-vrs2.patch 2003-06-13 16:51:33.000000000 +0200
-+++ linux-2.4.25/drivers/char/wdt285.c 2004-03-31 17:15:09.000000000 +0200
-@@ -151,7 +151,7 @@
- if (get_user(new_margin, (int *)arg))
- return -EFAULT;
- /* Arbitrary, can't find the card's limits */
-- if ((new_marg < 0) || (new_margin > 60))
-+ if ((new_margin < 0) || (new_margin > 60))
- return -EINVAL;
- soft_margin = new_margin;
- watchdog_ping();
---- linux-2.4.25/drivers/char/wdt977.c~2.4.25-vrs2.patch 2002-11-29 00:53:12.000000000 +0100
-+++ linux-2.4.25/drivers/char/wdt977.c 2004-03-31 17:15:09.000000000 +0200
-@@ -27,6 +27,7 @@
- #include <asm/io.h>
- #include <asm/system.h>
- #include <asm/mach-types.h>
-+#include <asm/uaccess.h>
-
- #define WATCHDOG_MINOR 130
-
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/cpufreq/Kconfig 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,38 @@
-+config CPU_FREQ_PROC_INTF
-+ tristate "/proc/cpufreq interface (deprecated)"
-+ depends on CPU_FREQ && PROC_FS
-+ help
-+ This enables the /proc/cpufreq interface for controlling
-+ CPUFreq. Please note that it is recommended to use the sysfs
-+ interface instead (which is built automatically).
-+
-+ For details, take a look at linux/Documentation/cpufreq.
-+
-+ If in doubt, say N.
-+
-+config CPU_FREQ_GOV_USERSPACE
-+ tristate "'userspace' governor for userspace frequency scaling"
-+ depends on CPU_FREQ
-+ help
-+ Enable this cpufreq governor when you either want to set the
-+ CPU frequency manually or when an userspace programm shall
-+ be able to set the CPU dynamically, like on LART
-+ ( http://www.lart.tudelft.nl/ )
-+
-+ For details, take a look at linux/Documentation/cpufreq.
-+
-+ If in doubt, say Y.
-+
-+config CPU_FREQ_24_API
-+ bool "/proc/sys/cpu/ interface (2.4. / OLD)"
-+ depends on CPU_FREQ && SYSCTL && CPU_FREQ_GOV_USERSPACE
-+ help
-+ This enables the /proc/sys/cpu/ sysctl interface for controlling
-+ the CPUFreq,"userspace" governor. This is the same interface
-+ as known from the.4.-kernel patches for CPUFreq, and offers
-+ the same functionality as long as "userspace" is the
-+ selected governor for the specified CPU.
-+
-+ For details, take a look at linux/Documentation/cpufreq.
-+
-+ If in doubt, say N.
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/cpufreq/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,4 @@
-+#CPUfreq governors and cross-arch helpers
-+obj-$(CONFIG_CPU_FREQ_TABLE) += freq_table.o
-+obj-$(CONFIG_CPU_FREQ_PROC_INTF) += proc_intf.o
-+obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE) += userspace.o
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/cpufreq/cpufreq.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,720 @@
-+/*
-+ * linux/kernel/cpufreq.c
-+ *
-+ * Copyright (C) 2001 Russell King
-+ * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/notifier.h>
-+#include <linux/cpufreq.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h>
-+#include <linux/spinlock.h>
-+#include <linux/slab.h>
-+
-+#include <asm/semaphore.h>
-+/**
-+ * The "cpufreq driver" - the arch- or hardware-dependend low
-+ * level driver of CPUFreq support, and its spinlock. This lock
-+ * also protects the cpufreq_cpu_data array.
-+ */
-+static struct cpufreq_driver *cpufreq_driver;
-+static struct cpufreq_policy *cpufreq_cpu_data[NR_CPUS];
-+static spinlock_t cpufreq_driver_lock = SPIN_LOCK_UNLOCKED;
-+
-+/* internal prototype */
-+static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event);
-+
-+
-+/**
-+ * Two notifier lists: the "policy" list is involved in the
-+ * validation process for a new CPU frequency policy; the
-+ * "transition" list for kernel code that needs to handle
-+ * changes to devices when the CPU clock speed changes.
-+ * The mutex locks both lists.
-+ */
-+static struct notifier_block *cpufreq_policy_notifier_list;
-+static struct notifier_block *cpufreq_transition_notifier_list;
-+static DECLARE_RWSEM (cpufreq_notifier_rwsem);
-+
-+
-+static LIST_HEAD(cpufreq_governor_list);
-+static DECLARE_MUTEX (cpufreq_governor_sem);
-+
-+/*
-+ * backport info:
-+ * we don't have a kobj we can use for ref-counting, so use a
-+ * "unsigned int policy->use_count" and an "unload_sem" [idea from
-+ * Pat Mochel's struct driver unload_sem] for proper reference counting.
-+ */
-+
-+static struct cpufreq_policy * cpufreq_cpu_get(unsigned int cpu)
-+{
-+ struct cpufreq_policy *data;
-+ unsigned long flags;
-+
-+ if (cpu >= NR_CPUS)
-+ goto err_out;
-+
-+ /* get the cpufreq driver */
-+ spin_lock_irqsave(&cpufreq_driver_lock, flags);
-+
-+ if (!cpufreq_driver)
-+ goto err_out_unlock;
-+
-+ /* get the CPU */
-+ data = cpufreq_cpu_data[cpu];
-+
-+ if (!data)
-+ goto err_out_unlock;
-+
-+ if (!data->use_count)
-+ goto err_out_unlock;
-+
-+ data->use_count += 1;
-+
-+ spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-+
-+ return data;
-+
-+ err_out_unlock:
-+ spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-+ err_out:
-+ return NULL;
-+}
-+
-+static void cpufreq_cpu_put(struct cpufreq_policy *data)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&cpufreq_driver_lock, flags);
-+ data->use_count -= 1;
-+ if (!data->use_count) {
-+ spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-+ up(&data->unload_sem);
-+ return;
-+ }
-+ spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-+}
-+
-+/*********************************************************************
-+ * SYSFS INTERFACE *
-+ *********************************************************************/
-+
-+/**
-+ * cpufreq_parse_governor - parse a governor string
-+ */
-+int cpufreq_parse_governor (char *str_governor, unsigned int *policy,
-+ struct cpufreq_governor **governor)
-+{
-+ if (!strnicmp(str_governor, "performance", CPUFREQ_NAME_LEN)) {
-+ *policy = CPUFREQ_POLICY_PERFORMANCE;
-+ return 0;
-+ } else if (!strnicmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) {
-+ *policy = CPUFREQ_POLICY_POWERSAVE;
-+ return 0;
-+ } else {
-+ struct cpufreq_governor *t;
-+ down(&cpufreq_governor_sem);
-+ if (!cpufreq_driver || !cpufreq_driver->target)
-+ goto out;
-+ list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
-+ if (!strnicmp(str_governor,t->name,CPUFREQ_NAME_LEN)) {
-+ *governor = t;
-+ *policy = CPUFREQ_POLICY_GOVERNOR;
-+ up(&cpufreq_governor_sem);
-+ return 0;
-+ }
-+ }
-+ out:
-+ up(&cpufreq_governor_sem);
-+ }
-+ return -EINVAL;
-+}
-+EXPORT_SYMBOL_GPL(cpufreq_parse_governor);
-+
-+
-+/* backport info:
-+ * all the sysfs stuff is missing -- of course
-+ */
-+
-+/**
-+ * cpufreq_add_dev - add a CPU device
-+ *
-+ * Adds the cpufreq interface for a CPU device.
-+ */
-+static int cpufreq_add_dev (unsigned int cpu)
-+{
-+ int ret = 0;
-+ struct cpufreq_policy new_policy;
-+ struct cpufreq_policy *policy;
-+ unsigned long flags;
-+
-+ policy = kmalloc(sizeof(struct cpufreq_policy), GFP_KERNEL);
-+ if (!policy)
-+ return -ENOMEM;
-+ memset(policy, 0, sizeof(struct cpufreq_policy));
-+
-+ policy->cpu = cpu;
-+ policy->use_count = 1;
-+ init_MUTEX_LOCKED(&policy->lock);
-+ init_MUTEX_LOCKED(&policy->unload_sem);
-+
-+ /* call driver. From then on the cpufreq must be able
-+ * to accept all calls to ->verify and ->setpolicy for this CPU
-+ */
-+ ret = cpufreq_driver->init(policy);
-+ if (ret)
-+ goto err_out;
-+
-+ memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
-+
-+ spin_lock_irqsave(&cpufreq_driver_lock, flags);
-+ cpufreq_cpu_data[cpu] = policy;
-+ spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-+
-+ up(&policy->lock);
-+
-+ /* set default policy */
-+ ret = cpufreq_set_policy(&new_policy);
-+ if (ret)
-+ goto err_out_unregister;
-+
-+ return 0;
-+
-+
-+ err_out_unregister:
-+ spin_lock_irqsave(&cpufreq_driver_lock, flags);
-+ cpufreq_cpu_data[cpu] = NULL;
-+ spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-+
-+ err_out:
-+ kfree(policy);
-+ return ret;
-+}
-+
-+
-+/**
-+ * cpufreq_remove_dev - remove a CPU device
-+ *
-+ * Removes the cpufreq interface for a CPU device.
-+ */
-+static int cpufreq_remove_dev (unsigned int cpu)
-+{
-+ unsigned long flags;
-+ struct cpufreq_policy *data;
-+
-+ spin_lock_irqsave(&cpufreq_driver_lock, flags);
-+ data = cpufreq_cpu_data[cpu];
-+ if (!data) {
-+ spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-+ return -EINVAL;
-+ }
-+ cpufreq_cpu_data[cpu] = NULL;
-+
-+ data->use_count -= 1;
-+ if (!data->use_count) {
-+ spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-+ up(&data->unload_sem);
-+ } else {
-+ spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-+ /* this will sleep until data->use_count gets to zero */
-+ down(&data->unload_sem);
-+ up(&data->unload_sem);
-+ }
-+
-+ if (cpufreq_driver->target)
-+ __cpufreq_governor(data, CPUFREQ_GOV_STOP);
-+
-+ if (cpufreq_driver->exit)
-+ cpufreq_driver->exit(data);
-+
-+ kfree(data);
-+
-+ return 0;
-+}
-+
-+
-+/*********************************************************************
-+ * NOTIFIER LISTS INTERFACE *
-+ *********************************************************************/
-+
-+/**
-+ * cpufreq_register_notifier - register a driver with cpufreq
-+ * @nb: notifier function to register
-+ * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
-+ *
-+ * Add a driver to one of two lists: either a list of drivers that
-+ * are notified about clock rate changes (once before and once after
-+ * the transition), or a list of drivers that are notified about
-+ * changes in cpufreq policy.
-+ *
-+ * This function may sleep, and has the same return conditions as
-+ * notifier_chain_register.
-+ */
-+int cpufreq_register_notifier(struct notifier_block *nb, unsigned int list)
-+{
-+ int ret;
-+
-+ down_write(&cpufreq_notifier_rwsem);
-+ switch (list) {
-+ case CPUFREQ_TRANSITION_NOTIFIER:
-+ ret = notifier_chain_register(&cpufreq_transition_notifier_list, nb);
-+ break;
-+ case CPUFREQ_POLICY_NOTIFIER:
-+ ret = notifier_chain_register(&cpufreq_policy_notifier_list, nb);
-+ break;
-+ default:
-+ ret = -EINVAL;
-+ }
-+ up_write(&cpufreq_notifier_rwsem);
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL(cpufreq_register_notifier);
-+
-+
-+/**
-+ * cpufreq_unregister_notifier - unregister a driver with cpufreq
-+ * @nb: notifier block to be unregistered
-+ * @list: CPUFREQ_TRANSITION_NOTIFIER or CPUFREQ_POLICY_NOTIFIER
-+ *
-+ * Remove a driver from the CPU frequency notifier list.
-+ *
-+ * This function may sleep, and has the same return conditions as
-+ * notifier_chain_unregister.
-+ */
-+int cpufreq_unregister_notifier(struct notifier_block *nb, unsigned int list)
-+{
-+ int ret;
-+
-+ down_write(&cpufreq_notifier_rwsem);
-+ switch (list) {
-+ case CPUFREQ_TRANSITION_NOTIFIER:
-+ ret = notifier_chain_unregister(&cpufreq_transition_notifier_list, nb);
-+ break;
-+ case CPUFREQ_POLICY_NOTIFIER:
-+ ret = notifier_chain_unregister(&cpufreq_policy_notifier_list, nb);
-+ break;
-+ default:
-+ ret = -EINVAL;
-+ }
-+ up_write(&cpufreq_notifier_rwsem);
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL(cpufreq_unregister_notifier);
-+
-+
-+/*********************************************************************
-+ * GOVERNORS *
-+ *********************************************************************/
-+
-+
-+int __cpufreq_driver_target(struct cpufreq_policy *policy,
-+ unsigned int target_freq,
-+ unsigned int relation)
-+{
-+ return cpufreq_driver->target(policy, target_freq, relation);
-+}
-+EXPORT_SYMBOL_GPL(__cpufreq_driver_target);
-+
-+
-+int cpufreq_driver_target(struct cpufreq_policy *policy,
-+ unsigned int target_freq,
-+ unsigned int relation)
-+{
-+ unsigned int ret;
-+
-+ policy = cpufreq_cpu_get(policy->cpu);
-+ if (!policy)
-+ return -EINVAL;
-+
-+ down(&policy->lock);
-+
-+ ret = __cpufreq_driver_target(policy, target_freq, relation);
-+
-+ up(&policy->lock);
-+
-+ cpufreq_cpu_put(policy);
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(cpufreq_driver_target);
-+
-+
-+static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event)
-+{
-+ int ret = 0;
-+
-+ switch (policy->policy) {
-+ case CPUFREQ_POLICY_POWERSAVE:
-+ if ((event == CPUFREQ_GOV_LIMITS) || (event == CPUFREQ_GOV_START)) {
-+ ret = __cpufreq_driver_target(policy, policy->min, CPUFREQ_RELATION_L);
-+ }
-+ break;
-+ case CPUFREQ_POLICY_PERFORMANCE:
-+ if ((event == CPUFREQ_GOV_LIMITS) || (event == CPUFREQ_GOV_START)) {
-+ ret = __cpufreq_driver_target(policy, policy->max, CPUFREQ_RELATION_H);
-+ }
-+ break;
-+ case CPUFREQ_POLICY_GOVERNOR:
-+ ret = policy->governor->governor(policy, event);
-+ break;
-+ default:
-+ ret = -EINVAL;
-+ }
-+
-+ return ret;
-+}
-+
-+
-+int cpufreq_governor(unsigned int cpu, unsigned int event)
-+{
-+ int ret = 0;
-+ struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
-+
-+ if (!policy)
-+ return -EINVAL;
-+
-+ down(&policy->lock);
-+ ret = __cpufreq_governor(policy, event);
-+ up(&policy->lock);
-+
-+ cpufreq_cpu_put(policy);
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(cpufreq_governor);
-+
-+
-+int cpufreq_register_governor(struct cpufreq_governor *governor)
-+{
-+ struct cpufreq_governor *t;
-+
-+ if (!governor)
-+ return -EINVAL;
-+
-+ if (!strnicmp(governor->name,"powersave",CPUFREQ_NAME_LEN))
-+ return -EBUSY;
-+ if (!strnicmp(governor->name,"performance",CPUFREQ_NAME_LEN))
-+ return -EBUSY;
-+
-+ down(&cpufreq_governor_sem);
-+
-+ list_for_each_entry(t, &cpufreq_governor_list, governor_list) {
-+ if (!strnicmp(governor->name,t->name,CPUFREQ_NAME_LEN)) {
-+ up(&cpufreq_governor_sem);
-+ return -EBUSY;
-+ }
-+ }
-+ list_add(&governor->governor_list, &cpufreq_governor_list);
-+
-+ up(&cpufreq_governor_sem);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(cpufreq_register_governor);
-+
-+
-+void cpufreq_unregister_governor(struct cpufreq_governor *governor)
-+{
-+ /* backport info:
-+ * As the module usage count isn't assured in 2.4., check for removal
-+ * of running cpufreq governor
-+ */
-+ unsigned int i;
-+
-+ if (!governor)
-+ return;
-+
-+ down(&cpufreq_governor_sem);
-+
-+ for (i=0; i<NR_CPUS; i++) {
-+ struct cpufreq_policy *policy = cpufreq_cpu_get(i);
-+ if (!policy)
-+ goto done;
-+ down(&policy->lock);
-+
-+ if (policy->policy != CPUFREQ_POLICY_GOVERNOR)
-+ goto unlock_done;
-+ if (policy->governor != governor)
-+ goto unlock_done;
-+
-+ /* stop old one, start performance [always present] */
-+ __cpufreq_governor(policy, CPUFREQ_GOV_STOP);
-+ policy->policy = CPUFREQ_POLICY_PERFORMANCE;
-+ __cpufreq_governor(policy, CPUFREQ_GOV_START);
-+
-+ unlock_done:
-+ up(&policy->lock);
-+ done:
-+ cpufreq_cpu_put(policy);
-+ }
-+ list_del(&governor->governor_list);
-+ up(&cpufreq_governor_sem);
-+ return;
-+}
-+EXPORT_SYMBOL_GPL(cpufreq_unregister_governor);
-+
-+
-+
-+/*********************************************************************
-+ * POLICY INTERFACE *
-+ *********************************************************************/
-+
-+/**
-+ * cpufreq_get_policy - get the current cpufreq_policy
-+ * @policy: struct cpufreq_policy into which the current cpufreq_policy is written
-+ *
-+ * Reads the current cpufreq policy.
-+ */
-+int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu)
-+{
-+ struct cpufreq_policy *cpu_policy;
-+ if (!policy)
-+ return -EINVAL;
-+
-+ cpu_policy = cpufreq_cpu_get(cpu);
-+ if (!cpu_policy)
-+ return -EINVAL;
-+
-+ down(&cpu_policy->lock);
-+ memcpy(policy, cpu_policy, sizeof(struct cpufreq_policy));
-+ up(&cpu_policy->lock);
-+
-+ cpufreq_cpu_put(cpu_policy);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(cpufreq_get_policy);
-+
-+
-+/**
-+ * cpufreq_set_policy - set a new CPUFreq policy
-+ * @policy: policy to be set.
-+ *
-+ * Sets a new CPU frequency and voltage scaling policy.
-+ */
-+int cpufreq_set_policy(struct cpufreq_policy *policy)
-+{
-+ int ret = 0;
-+ struct cpufreq_policy *data;
-+
-+ if (!policy)
-+ return -EINVAL;
-+
-+ data = cpufreq_cpu_get(policy->cpu);
-+ if (!data)
-+ return -EINVAL;
-+
-+ /* lock this CPU */
-+ down(&data->lock);
-+
-+ memcpy(&policy->cpuinfo,
-+ &data->cpuinfo,
-+ sizeof(struct cpufreq_cpuinfo));
-+
-+ /* verify the cpu speed can be set within this limit */
-+ ret = cpufreq_driver->verify(policy);
-+ if (ret)
-+ goto error_out;
-+
-+ down_read(&cpufreq_notifier_rwsem);
-+
-+ /* adjust if necessary - all reasons */
-+ notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_ADJUST,
-+ policy);
-+
-+ /* adjust if necessary - hardware incompatibility*/
-+ notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_INCOMPATIBLE,
-+ policy);
-+
-+ /* verify the cpu speed can be set within this limit,
-+ which might be different to the first one */
-+ ret = cpufreq_driver->verify(policy);
-+ if (ret) {
-+ up_read(&cpufreq_notifier_rwsem);
-+ goto error_out;
-+ }
-+
-+ /* notification of the new policy */
-+ notifier_call_chain(&cpufreq_policy_notifier_list, CPUFREQ_NOTIFY,
-+ policy);
-+
-+ up_read(&cpufreq_notifier_rwsem);
-+
-+ data->min = policy->min;
-+ data->max = policy->max;
-+
-+ if (cpufreq_driver->setpolicy) {
-+ data->policy = policy->policy;
-+ ret = cpufreq_driver->setpolicy(policy);
-+ } else {
-+ if ((policy->policy != data->policy) ||
-+ ((policy->policy == CPUFREQ_POLICY_GOVERNOR) && (policy->governor != data->governor))) {
-+ /* save old, working values */
-+ unsigned int old_pol = data->policy;
-+ struct cpufreq_governor *old_gov = data->governor;
-+
-+ /* end old governor */
-+ __cpufreq_governor(data, CPUFREQ_GOV_STOP);
-+
-+ /* start new governor */
-+ data->policy = policy->policy;
-+ data->governor = policy->governor;
-+ if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
-+ /* new governor failed, so re-start old one */
-+ data->policy = old_pol;
-+ data->governor = old_gov;
-+ __cpufreq_governor(data, CPUFREQ_GOV_START);
-+ }
-+ /* might be a policy change, too, so fall through */
-+ }
-+ __cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
-+ }
-+
-+ error_out:
-+ up(&data->lock);
-+ cpufreq_cpu_put(data);
-+
-+ return ret;
-+}
-+EXPORT_SYMBOL(cpufreq_set_policy);
-+
-+
-+
-+/*********************************************************************
-+ * EXTERNALLY AFFECTING FREQUENCY CHANGES *
-+ *********************************************************************/
-+
-+/**
-+ * adjust_jiffies - adjust the system "loops_per_jiffy"
-+ *
-+ * This function alters the system "loops_per_jiffy" for the clock
-+ * speed change. Note that loops_per_jiffy cannot be updated on SMP
-+ * systems as each CPU might be scaled differently. So, use the arch
-+ * per-CPU loops_per_jiffy value wherever possible.
-+ */
-+#ifndef CONFIG_SMP
-+static unsigned long l_p_j_ref = 0;
-+static unsigned int l_p_j_ref_freq = 0;
-+
-+static inline void adjust_jiffies(unsigned long val, struct cpufreq_freqs *ci)
-+{
-+ if (!l_p_j_ref_freq) {
-+ l_p_j_ref = loops_per_jiffy;
-+ l_p_j_ref_freq = ci->old;
-+ }
-+ if ((val == CPUFREQ_PRECHANGE && ci->old < ci->new) ||
-+ (val == CPUFREQ_POSTCHANGE && ci->old > ci->new))
-+ loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq, ci->new);
-+}
-+#else
-+#define adjust_jiffies(x...) do {} while (0)
-+#endif
-+
-+
-+/**
-+ * cpufreq_notify_transition - call notifier chain and adjust_jiffies on frequency transition
-+ *
-+ * This function calls the transition notifiers and the "adjust_jiffies" function. It is called
-+ * twice on all CPU frequency changes that have external effects.
-+ */
-+void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
-+{
-+ down_read(&cpufreq_notifier_rwsem);
-+ switch (state) {
-+ case CPUFREQ_PRECHANGE:
-+ notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_PRECHANGE, freqs);
-+ adjust_jiffies(CPUFREQ_PRECHANGE, freqs);
-+ break;
-+ case CPUFREQ_POSTCHANGE:
-+ adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
-+ notifier_call_chain(&cpufreq_transition_notifier_list, CPUFREQ_POSTCHANGE, freqs);
-+ cpufreq_cpu_data[freqs->cpu]->cur = freqs->new;
-+ break;
-+ }
-+ up_read(&cpufreq_notifier_rwsem);
-+}
-+EXPORT_SYMBOL_GPL(cpufreq_notify_transition);
-+
-+
-+
-+/*********************************************************************
-+ * REGISTER / UNREGISTER CPUFREQ DRIVER *
-+ *********************************************************************/
-+
-+/**
-+ * cpufreq_register_driver - register a CPU Frequency driver
-+ * @driver_data: A struct cpufreq_driver containing the values#
-+ * submitted by the CPU Frequency driver.
-+ *
-+ * Registers a CPU Frequency driver to this core code. This code
-+ * returns zero on success, -EBUSY when another driver got here first
-+ * (and isn't unregistered in the meantime).
-+ *
-+ */
-+int cpufreq_register_driver(struct cpufreq_driver *driver_data)
-+{
-+ unsigned long flags;
-+ unsigned int i;
-+
-+ if (!driver_data || !driver_data->verify || !driver_data->init ||
-+ ((!driver_data->setpolicy) && (!driver_data->target)))
-+ return -EINVAL;
-+
-+ spin_lock_irqsave(&cpufreq_driver_lock, flags);
-+ if (cpufreq_driver) {
-+ spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-+ return -EBUSY;
-+ }
-+ cpufreq_driver = driver_data;
-+ spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-+
-+ for (i=0; i<NR_CPUS; i++) {
-+ if (cpu_online(i))
-+ cpufreq_add_dev(i);
-+ }
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(cpufreq_register_driver);
-+
-+
-+/**
-+ * cpufreq_unregister_driver - unregister the current CPUFreq driver
-+ *
-+ * Unregister the current CPUFreq driver. Only call this if you have
-+ * the right to do so, i.e. if you have succeeded in initialising before!
-+ * Returns zero if successful, and -EINVAL if the cpufreq_driver is
-+ * currently not initialised.
-+ */
-+int cpufreq_unregister_driver(struct cpufreq_driver *driver)
-+{
-+ unsigned long flags;
-+ unsigned int i;
-+
-+ if (!cpufreq_driver || (driver != cpufreq_driver))
-+ return -EINVAL;
-+
-+ for (i=0; i<NR_CPUS; i++) {
-+ if (cpu_online(i))
-+ cpufreq_remove_dev(i);
-+ }
-+
-+ spin_lock_irqsave(&cpufreq_driver_lock, flags);
-+ cpufreq_driver = NULL;
-+ spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(cpufreq_unregister_driver);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/cpufreq/freq_table.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,203 @@
-+/*
-+ * linux/drivers/cpufreq/freq_table.c
-+ *
-+ * Copyright (C) 2002 - 2003 Dominik Brodowski
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/cpufreq.h>
-+
-+/*********************************************************************
-+ * FREQUENCY TABLE HELPERS *
-+ *********************************************************************/
-+
-+int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
-+ struct cpufreq_frequency_table *table)
-+{
-+ unsigned int min_freq = ~0;
-+ unsigned int max_freq = 0;
-+ unsigned int i = 0;
-+
-+ for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
-+ unsigned int freq = table[i].frequency;
-+ if (freq == CPUFREQ_ENTRY_INVALID)
-+ continue;
-+ if (freq < min_freq)
-+ min_freq = freq;
-+ if (freq > max_freq)
-+ max_freq = freq;
-+ }
-+
-+ policy->min = policy->cpuinfo.min_freq = min_freq;
-+ policy->max = policy->cpuinfo.max_freq = max_freq;
-+
-+ if (policy->min == ~0)
-+ return -EINVAL;
-+ else
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(cpufreq_frequency_table_cpuinfo);
-+
-+
-+int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
-+ struct cpufreq_frequency_table *table)
-+{
-+ unsigned int next_larger = ~0;
-+ unsigned int i = 0;
-+ unsigned int count = 0;
-+
-+ if (!cpu_online(policy->cpu))
-+ return -EINVAL;
-+
-+ cpufreq_verify_within_limits(policy,
-+ policy->cpuinfo.min_freq,
-+ policy->cpuinfo.max_freq);
-+
-+ for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
-+ unsigned int freq = table[i].frequency;
-+ if (freq == CPUFREQ_ENTRY_INVALID)
-+ continue;
-+ if ((freq >= policy->min) && (freq <= policy->max))
-+ count++;
-+ else if ((next_larger > freq) && (freq > policy->max))
-+ next_larger = freq;
-+ }
-+
-+ if (!count)
-+ policy->max = next_larger;
-+
-+ cpufreq_verify_within_limits(policy,
-+ policy->cpuinfo.min_freq,
-+ policy->cpuinfo.max_freq);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(cpufreq_frequency_table_verify);
-+
-+
-+int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
-+ struct cpufreq_frequency_table *table,
-+ unsigned int target_freq,
-+ unsigned int relation,
-+ unsigned int *index)
-+{
-+ struct cpufreq_frequency_table optimal = { .index = ~0, };
-+ struct cpufreq_frequency_table suboptimal = { .index = ~0, };
-+ unsigned int i;
-+
-+ switch (relation) {
-+ case CPUFREQ_RELATION_H:
-+ optimal.frequency = 0;
-+ suboptimal.frequency = ~0;
-+ break;
-+ case CPUFREQ_RELATION_L:
-+ optimal.frequency = ~0;
-+ suboptimal.frequency = 0;
-+ break;
-+ }
-+
-+ if (!cpu_online(policy->cpu))
-+ return -EINVAL;
-+
-+ for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
-+ unsigned int freq = table[i].frequency;
-+ if (freq == CPUFREQ_ENTRY_INVALID)
-+ continue;
-+ if ((freq < policy->min) || (freq > policy->max))
-+ continue;
-+ switch(relation) {
-+ case CPUFREQ_RELATION_H:
-+ if (freq <= target_freq) {
-+ if (freq >= optimal.frequency) {
-+ optimal.frequency = freq;
-+ optimal.index = i;
-+ }
-+ } else {
-+ if (freq <= suboptimal.frequency) {
-+ suboptimal.frequency = freq;
-+ suboptimal.index = i;
-+ }
-+ }
-+ break;
-+ case CPUFREQ_RELATION_L:
-+ if (freq >= target_freq) {
-+ if (freq <= optimal.frequency) {
-+ optimal.frequency = freq;
-+ optimal.index = i;
-+ }
-+ } else {
-+ if (freq >= suboptimal.frequency) {
-+ suboptimal.frequency = freq;
-+ suboptimal.index = i;
-+ }
-+ }
-+ break;
-+ }
-+ }
-+ if (optimal.index > i) {
-+ if (suboptimal.index > i)
-+ return -EINVAL;
-+ *index = suboptimal.index;
-+ } else
-+ *index = optimal.index;
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
-+
-+static struct cpufreq_frequency_table *show_table[NR_CPUS];
-+/**
-+ * show_scaling_governor - show the current policy for the specified CPU
-+ */
-+static ssize_t show_available_freqs (struct cpufreq_policy *policy, char *buf)
-+{
-+ unsigned int i = 0;
-+ unsigned int cpu = policy->cpu;
-+ ssize_t count = 0;
-+ struct cpufreq_frequency_table *table;
-+
-+ if (!show_table[cpu])
-+ return -ENODEV;
-+
-+ table = show_table[cpu];
-+
-+ for (i=0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
-+ if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
-+ continue;
-+ count += sprintf(&buf[count], "%d ", table[i].frequency);
-+ }
-+ count += sprintf(&buf[count], "\n");
-+
-+ return count;
-+
-+}
-+
-+struct freq_attr cpufreq_freq_attr_scaling_available_freqs = {
-+ .attr = { .name = "scaling_available_frequencies", .mode = 0444 },
-+ .show = show_available_freqs,
-+};
-+EXPORT_SYMBOL_GPL(cpufreq_freq_attr_scaling_available_freqs);
-+
-+/*
-+ * if you use these, you must assure that the frequency table is valid
-+ * all the time between get_attr and put_attr!
-+ */
-+void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
-+ unsigned int cpu)
-+{
-+ show_table[cpu] = table;
-+}
-+EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_attr);
-+
-+void cpufreq_frequency_table_put_attr(unsigned int cpu)
-+{
-+ show_table[cpu] = NULL;
-+}
-+EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr);
-+
-+
-+MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
-+MODULE_DESCRIPTION ("CPUfreq frequency table helpers");
-+MODULE_LICENSE ("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/cpufreq/proc_intf.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,244 @@
-+/*
-+ * linux/drivers/cpufreq/proc_intf.c
-+ *
-+ * Copyright (C) 2002 - 2003 Dominik Brodowski
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/cpufreq.h>
-+#include <linux/ctype.h>
-+#include <linux/proc_fs.h>
-+#include <asm/uaccess.h>
-+
-+
-+/**
-+ * cpufreq_parse_policy - parse a policy string
-+ * @input_string: the string to parse.
-+ * @policy: the policy written inside input_string
-+ *
-+ * This function parses a "policy string" - something the user echo'es into
-+ * /proc/cpufreq or gives as boot parameter - into a struct cpufreq_policy.
-+ * If there are invalid/missing entries, they are replaced with current
-+ * cpufreq policy.
-+ */
-+static int cpufreq_parse_policy(char input_string[42], struct cpufreq_policy *policy)
-+{
-+ unsigned int min = 0;
-+ unsigned int max = 0;
-+ unsigned int cpu = 0;
-+ char str_governor[16];
-+ struct cpufreq_policy current_policy;
-+ unsigned int result = -EFAULT;
-+
-+ if (!policy)
-+ return -EINVAL;
-+
-+ policy->min = 0;
-+ policy->max = 0;
-+ policy->policy = 0;
-+ policy->cpu = CPUFREQ_ALL_CPUS;
-+
-+ if (sscanf(input_string, "%d:%d:%d:%15s", &cpu, &min, &max, str_governor) == 4)
-+ {
-+ policy->min = min;
-+ policy->max = max;
-+ policy->cpu = cpu;
-+ result = 0;
-+ goto scan_policy;
-+ }
-+ if (sscanf(input_string, "%d%%%d%%%d%%%15s", &cpu, &min, &max, str_governor) == 4)
-+ {
-+ if (!cpufreq_get_policy(&current_policy, cpu)) {
-+ policy->min = (min * current_policy.cpuinfo.max_freq) / 100;
-+ policy->max = (max * current_policy.cpuinfo.max_freq) / 100;
-+ policy->cpu = cpu;
-+ result = 0;
-+ goto scan_policy;
-+ }
-+ }
-+
-+ if (sscanf(input_string, "%d:%d:%15s", &min, &max, str_governor) == 3)
-+ {
-+ policy->min = min;
-+ policy->max = max;
-+ result = 0;
-+ goto scan_policy;
-+ }
-+
-+ if (sscanf(input_string, "%d%%%d%%%15s", &min, &max, str_governor) == 3)
-+ {
-+ if (!cpufreq_get_policy(&current_policy, cpu)) {
-+ policy->min = (min * current_policy.cpuinfo.max_freq) / 100;
-+ policy->max = (max * current_policy.cpuinfo.max_freq) / 100;
-+ result = 0;
-+ goto scan_policy;
-+ }
-+ }
-+
-+ return -EINVAL;
-+
-+scan_policy:
-+ result = cpufreq_parse_governor(str_governor, &policy->policy, &policy->governor);
-+
-+ return result;
-+}
-+
-+/**
-+ * cpufreq_proc_read - read /proc/cpufreq
-+ *
-+ * This function prints out the current cpufreq policy.
-+ */
-+static int cpufreq_proc_read (
-+ char *page,
-+ char **start,
-+ off_t off,
-+ int count,
-+ int *eof,
-+ void *data)
-+{
-+ char *p = page;
-+ int len = 0;
-+ struct cpufreq_policy policy;
-+ unsigned int min_pctg = 0;
-+ unsigned int max_pctg = 0;
-+ unsigned int i = 0;
-+
-+ if (off != 0)
-+ goto end;
-+
-+ p += sprintf(p, " minimum CPU frequency - maximum CPU frequency - policy\n");
-+ for (i=0;i<NR_CPUS;i++) {
-+ if (!cpu_online(i))
-+ continue;
-+
-+ if (cpufreq_get_policy(&policy, i))
-+ continue;
-+
-+ if (!policy.cpuinfo.max_freq)
-+ continue;
-+
-+ min_pctg = (policy.min * 100) / policy.cpuinfo.max_freq;
-+ max_pctg = (policy.max * 100) / policy.cpuinfo.max_freq;
-+
-+ p += sprintf(p, "CPU%3d %9d kHz (%3d %%) - %9d kHz (%3d %%) - ",
-+ i , policy.min, min_pctg, policy.max, max_pctg);
-+ switch (policy.policy) {
-+ case CPUFREQ_POLICY_POWERSAVE:
-+ p += sprintf(p, "powersave\n");
-+ break;
-+ case CPUFREQ_POLICY_PERFORMANCE:
-+ p += sprintf(p, "performance\n");
-+ break;
-+ case CPUFREQ_POLICY_GOVERNOR:
-+ p += snprintf(p, CPUFREQ_NAME_LEN, "%s\n", policy.governor->name);
-+ break;
-+ default:
-+ p += sprintf(p, "INVALID\n");
-+ break;
-+ }
-+ }
-+end:
-+ len = (p - page);
-+ if (len <= off+count)
-+ *eof = 1;
-+ *start = page + off;
-+ len -= off;
-+ if (len>count)
-+ len = count;
-+ if (len<0)
-+ len = 0;
-+
-+ return len;
-+}
-+
-+
-+/**
-+ * cpufreq_proc_write - handles writing into /proc/cpufreq
-+ *
-+ * This function calls the parsing script and then sets the policy
-+ * accordingly.
-+ */
-+static int cpufreq_proc_write (
-+ struct file *file,
-+ const char *buffer,
-+ unsigned long count,
-+ void *data)
-+{
-+ int result = 0;
-+ char proc_string[42] = {'\0'};
-+ struct cpufreq_policy policy;
-+ unsigned int i = 0;
-+
-+
-+ if ((count > sizeof(proc_string) - 1))
-+ return -EINVAL;
-+
-+ if (copy_from_user(proc_string, buffer, count))
-+ return -EFAULT;
-+
-+ proc_string[count] = '\0';
-+
-+ result = cpufreq_parse_policy(proc_string, &policy);
-+ if (result)
-+ return -EFAULT;
-+
-+ if (policy.cpu == CPUFREQ_ALL_CPUS)
-+ {
-+ for (i=0; i<NR_CPUS; i++)
-+ {
-+ policy.cpu = i;
-+ if (cpu_online(i))
-+ cpufreq_set_policy(&policy);
-+ }
-+ }
-+ else
-+ cpufreq_set_policy(&policy);
-+
-+ return count;
-+}
-+
-+
-+/**
-+ * cpufreq_proc_init - add "cpufreq" to the /proc root directory
-+ *
-+ * This function adds "cpufreq" to the /proc root directory.
-+ */
-+static int __init cpufreq_proc_init (void)
-+{
-+ struct proc_dir_entry *entry = NULL;
-+
-+ /* are these acceptable values? */
-+ entry = create_proc_entry("cpufreq", S_IFREG|S_IRUGO|S_IWUSR,
-+ &proc_root);
-+
-+ if (!entry) {
-+ printk(KERN_ERR "unable to create /proc/cpufreq entry\n");
-+ return -EIO;
-+ } else {
-+ entry->read_proc = cpufreq_proc_read;
-+ entry->write_proc = cpufreq_proc_write;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+/**
-+ * cpufreq_proc_exit - removes "cpufreq" from the /proc root directory.
-+ *
-+ * This function removes "cpufreq" from the /proc root directory.
-+ */
-+static void __exit cpufreq_proc_exit (void)
-+{
-+ remove_proc_entry("cpufreq", &proc_root);
-+ return;
-+}
-+
-+MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>");
-+MODULE_DESCRIPTION ("CPUfreq /proc/cpufreq interface");
-+MODULE_LICENSE ("GPL");
-+
-+module_init(cpufreq_proc_init);
-+module_exit(cpufreq_proc_exit);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/cpufreq/userspace.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,591 @@
-+/*
-+ * drivers/cpufreq/userspace.c
-+ *
-+ * Copyright (C) 2001 Russell King
-+ * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/smp.h>
-+#include <linux/init.h>
-+#include <linux/spinlock.h>
-+#include <linux/interrupt.h>
-+#include <linux/ctype.h>
-+#include <linux/cpufreq.h>
-+#include <linux/sysctl.h>
-+#include <linux/types.h>
-+#include <linux/fs.h>
-+#include <linux/sysfs.h>
-+
-+#include <asm/uaccess.h>
-+
-+#define CTL_CPU_VARS_SPEED_MAX(cpunr) { \
-+ .ctl_name = CPU_NR_FREQ_MAX, \
-+ .data = &cpu_max_freq[cpunr], \
-+ .procname = "speed-max", \
-+ .maxlen = sizeof(cpu_max_freq[cpunr]),\
-+ .mode = 0444, \
-+ .proc_handler = proc_dointvec, }
-+
-+#define CTL_CPU_VARS_SPEED_MIN(cpunr) { \
-+ .ctl_name = CPU_NR_FREQ_MIN, \
-+ .data = &cpu_min_freq[cpunr], \
-+ .procname = "speed-min", \
-+ .maxlen = sizeof(cpu_min_freq[cpunr]),\
-+ .mode = 0444, \
-+ .proc_handler = proc_dointvec, }
-+
-+#define CTL_CPU_VARS_SPEED(cpunr) { \
-+ .ctl_name = CPU_NR_FREQ, \
-+ .procname = "speed", \
-+ .mode = 0644, \
-+ .proc_handler = cpufreq_procctl, \
-+ .strategy = cpufreq_sysctl, \
-+ .extra1 = (void*) (cpunr), }
-+
-+#define CTL_TABLE_CPU_VARS(cpunr) static ctl_table ctl_cpu_vars_##cpunr[] = {\
-+ CTL_CPU_VARS_SPEED_MAX(cpunr), \
-+ CTL_CPU_VARS_SPEED_MIN(cpunr), \
-+ CTL_CPU_VARS_SPEED(cpunr), \
-+ { .ctl_name = 0, }, }
-+
-+/* the ctl_table entry for each CPU */
-+#define CPU_ENUM(s) { \
-+ .ctl_name = (CPU_NR + s), \
-+ .procname = #s, \
-+ .mode = 0555, \
-+ .child = ctl_cpu_vars_##s }
-+
-+/**
-+ * A few values needed by the userspace governor
-+ */
-+static unsigned int cpu_max_freq[NR_CPUS];
-+static unsigned int cpu_min_freq[NR_CPUS];
-+static unsigned int cpu_cur_freq[NR_CPUS];
-+static unsigned int cpu_is_managed[NR_CPUS];
-+static struct cpufreq_policy current_policy[NR_CPUS];
-+
-+static DECLARE_MUTEX (userspace_sem);
-+
-+
-+/* keep track of frequency transitions */
-+static int
-+userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
-+ void *data)
-+{
-+ struct cpufreq_freqs *freq = data;
-+
-+ cpu_cur_freq[freq->cpu] = freq->new;
-+
-+ return 0;
-+}
-+
-+static struct notifier_block userspace_cpufreq_notifier_block = {
-+ .notifier_call = userspace_cpufreq_notifier
-+};
-+
-+
-+/**
-+ * cpufreq_set - set the CPU frequency
-+ * @freq: target frequency in kHz
-+ * @cpu: CPU for which the frequency is to be set
-+ *
-+ * Sets the CPU frequency to freq.
-+ */
-+int cpufreq_set(unsigned int freq, unsigned int cpu)
-+{
-+ int ret = -EINVAL;
-+
-+ down(&userspace_sem);
-+ if (!cpu_is_managed[cpu])
-+ goto err;
-+
-+ if (freq < cpu_min_freq[cpu])
-+ freq = cpu_min_freq[cpu];
-+ if (freq > cpu_max_freq[cpu])
-+ freq = cpu_max_freq[cpu];
-+
-+ ret = cpufreq_driver_target(&current_policy[cpu], freq,
-+ CPUFREQ_RELATION_L);
-+
-+ err:
-+ up(&userspace_sem);
-+ return ret;
-+}
-+EXPORT_SYMBOL_GPL(cpufreq_set);
-+
-+
-+/**
-+ * cpufreq_setmax - set the CPU to the maximum frequency
-+ * @cpu - affected cpu;
-+ *
-+ * Sets the CPU frequency to the maximum frequency supported by
-+ * this CPU.
-+ */
-+int cpufreq_setmax(unsigned int cpu)
-+{
-+ if (!cpu_is_managed[cpu] || !cpu_online(cpu))
-+ return -EINVAL;
-+ return cpufreq_set(cpu_max_freq[cpu], cpu);
-+}
-+EXPORT_SYMBOL_GPL(cpufreq_setmax);
-+
-+
-+/**
-+ * cpufreq_get - get the current CPU frequency (in kHz)
-+ * @cpu: CPU number
-+ *
-+ * Get the CPU current (static) CPU frequency
-+ */
-+unsigned int cpufreq_get(unsigned int cpu)
-+{
-+ return cpu_cur_freq[cpu];
-+}
-+EXPORT_SYMBOL(cpufreq_get);
-+
-+
-+#ifdef CONFIG_CPU_FREQ_24_API
-+
-+
-+/*********************** cpufreq_sysctl interface ********************/
-+static int
-+cpufreq_procctl(ctl_table *ctl, int write, struct file *filp,
-+ void *buffer, size_t *lenp)
-+{
-+ char buf[16], *p;
-+ int cpu = (int) ctl->extra1;
-+ int len, left = *lenp;
-+
-+ if (!left || (filp->f_pos && !write) || !cpu_online(cpu)) {
-+ *lenp = 0;
-+ return 0;
-+ }
-+
-+ if (write) {
-+ unsigned int freq;
-+
-+ len = left;
-+ if (left > sizeof(buf))
-+ left = sizeof(buf);
-+ if (copy_from_user(buf, buffer, left))
-+ return -EFAULT;
-+ buf[sizeof(buf) - 1] = '\0';
-+
-+ freq = simple_strtoul(buf, &p, 0);
-+ cpufreq_set(freq, cpu);
-+ } else {
-+ len = sprintf(buf, "%d\n", cpufreq_get(cpu));
-+ if (len > left)
-+ len = left;
-+ if (copy_to_user(buffer, buf, len))
-+ return -EFAULT;
-+ }
-+
-+ *lenp = len;
-+ filp->f_pos += len;
-+ return 0;
-+}
-+
-+static int
-+cpufreq_sysctl(ctl_table *table, int *name, int nlen,
-+ void *oldval, size_t *oldlenp,
-+ void *newval, size_t newlen, void **context)
-+{
-+ int cpu = (int) table->extra1;
-+
-+ if (!cpu_online(cpu))
-+ return -EINVAL;
-+
-+ if (oldval && oldlenp) {
-+ size_t oldlen;
-+
-+ if (get_user(oldlen, oldlenp))
-+ return -EFAULT;
-+
-+ if (oldlen != sizeof(unsigned int))
-+ return -EINVAL;
-+
-+ if (put_user(cpufreq_get(cpu), (unsigned int *)oldval) ||
-+ put_user(sizeof(unsigned int), oldlenp))
-+ return -EFAULT;
-+ }
-+ if (newval && newlen) {
-+ unsigned int freq;
-+
-+ if (newlen != sizeof(unsigned int))
-+ return -EINVAL;
-+
-+ if (get_user(freq, (unsigned int *)newval))
-+ return -EFAULT;
-+
-+ cpufreq_set(freq, cpu);
-+ }
-+ return 1;
-+}
-+
-+/* ctl_table ctl_cpu_vars_{0,1,...,(NR_CPUS-1)} */
-+/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
-+ CTL_TABLE_CPU_VARS(0);
-+#if NR_CPUS > 1
-+ CTL_TABLE_CPU_VARS(1);
-+#endif
-+#if NR_CPUS > 2
-+ CTL_TABLE_CPU_VARS(2);
-+#endif
-+#if NR_CPUS > 3
-+ CTL_TABLE_CPU_VARS(3);
-+#endif
-+#if NR_CPUS > 4
-+ CTL_TABLE_CPU_VARS(4);
-+#endif
-+#if NR_CPUS > 5
-+ CTL_TABLE_CPU_VARS(5);
-+#endif
-+#if NR_CPUS > 6
-+ CTL_TABLE_CPU_VARS(6);
-+#endif
-+#if NR_CPUS > 7
-+ CTL_TABLE_CPU_VARS(7);
-+#endif
-+#if NR_CPUS > 8
-+ CTL_TABLE_CPU_VARS(8);
-+#endif
-+#if NR_CPUS > 9
-+ CTL_TABLE_CPU_VARS(9);
-+#endif
-+#if NR_CPUS > 10
-+ CTL_TABLE_CPU_VARS(10);
-+#endif
-+#if NR_CPUS > 11
-+ CTL_TABLE_CPU_VARS(11);
-+#endif
-+#if NR_CPUS > 12
-+ CTL_TABLE_CPU_VARS(12);
-+#endif
-+#if NR_CPUS > 13
-+ CTL_TABLE_CPU_VARS(13);
-+#endif
-+#if NR_CPUS > 14
-+ CTL_TABLE_CPU_VARS(14);
-+#endif
-+#if NR_CPUS > 15
-+ CTL_TABLE_CPU_VARS(15);
-+#endif
-+#if NR_CPUS > 16
-+ CTL_TABLE_CPU_VARS(16);
-+#endif
-+#if NR_CPUS > 17
-+ CTL_TABLE_CPU_VARS(17);
-+#endif
-+#if NR_CPUS > 18
-+ CTL_TABLE_CPU_VARS(18);
-+#endif
-+#if NR_CPUS > 19
-+ CTL_TABLE_CPU_VARS(19);
-+#endif
-+#if NR_CPUS > 20
-+ CTL_TABLE_CPU_VARS(20);
-+#endif
-+#if NR_CPUS > 21
-+ CTL_TABLE_CPU_VARS(21);
-+#endif
-+#if NR_CPUS > 22
-+ CTL_TABLE_CPU_VARS(22);
-+#endif
-+#if NR_CPUS > 23
-+ CTL_TABLE_CPU_VARS(23);
-+#endif
-+#if NR_CPUS > 24
-+ CTL_TABLE_CPU_VARS(24);
-+#endif
-+#if NR_CPUS > 25
-+ CTL_TABLE_CPU_VARS(25);
-+#endif
-+#if NR_CPUS > 26
-+ CTL_TABLE_CPU_VARS(26);
-+#endif
-+#if NR_CPUS > 27
-+ CTL_TABLE_CPU_VARS(27);
-+#endif
-+#if NR_CPUS > 28
-+ CTL_TABLE_CPU_VARS(28);
-+#endif
-+#if NR_CPUS > 29
-+ CTL_TABLE_CPU_VARS(29);
-+#endif
-+#if NR_CPUS > 30
-+ CTL_TABLE_CPU_VARS(30);
-+#endif
-+#if NR_CPUS > 31
-+ CTL_TABLE_CPU_VARS(31);
-+#endif
-+#if NR_CPUS > 32
-+#error please extend CPU enumeration
-+#endif
-+
-+/* due to NR_CPUS tweaking, a lot of if/endifs are required, sorry */
-+static ctl_table ctl_cpu_table[NR_CPUS + 1] = {
-+ CPU_ENUM(0),
-+#if NR_CPUS > 1
-+ CPU_ENUM(1),
-+#endif
-+#if NR_CPUS > 2
-+ CPU_ENUM(2),
-+#endif
-+#if NR_CPUS > 3
-+ CPU_ENUM(3),
-+#endif
-+#if NR_CPUS > 4
-+ CPU_ENUM(4),
-+#endif
-+#if NR_CPUS > 5
-+ CPU_ENUM(5),
-+#endif
-+#if NR_CPUS > 6
-+ CPU_ENUM(6),
-+#endif
-+#if NR_CPUS > 7
-+ CPU_ENUM(7),
-+#endif
-+#if NR_CPUS > 8
-+ CPU_ENUM(8),
-+#endif
-+#if NR_CPUS > 9
-+ CPU_ENUM(9),
-+#endif
-+#if NR_CPUS > 10
-+ CPU_ENUM(10),
-+#endif
-+#if NR_CPUS > 11
-+ CPU_ENUM(11),
-+#endif
-+#if NR_CPUS > 12
-+ CPU_ENUM(12),
-+#endif
-+#if NR_CPUS > 13
-+ CPU_ENUM(13),
-+#endif
-+#if NR_CPUS > 14
-+ CPU_ENUM(14),
-+#endif
-+#if NR_CPUS > 15
-+ CPU_ENUM(15),
-+#endif
-+#if NR_CPUS > 16
-+ CPU_ENUM(16),
-+#endif
-+#if NR_CPUS > 17
-+ CPU_ENUM(17),
-+#endif
-+#if NR_CPUS > 18
-+ CPU_ENUM(18),
-+#endif
-+#if NR_CPUS > 19
-+ CPU_ENUM(19),
-+#endif
-+#if NR_CPUS > 20
-+ CPU_ENUM(20),
-+#endif
-+#if NR_CPUS > 21
-+ CPU_ENUM(21),
-+#endif
-+#if NR_CPUS > 22
-+ CPU_ENUM(22),
-+#endif
-+#if NR_CPUS > 23
-+ CPU_ENUM(23),
-+#endif
-+#if NR_CPUS > 24
-+ CPU_ENUM(24),
-+#endif
-+#if NR_CPUS > 25
-+ CPU_ENUM(25),
-+#endif
-+#if NR_CPUS > 26
-+ CPU_ENUM(26),
-+#endif
-+#if NR_CPUS > 27
-+ CPU_ENUM(27),
-+#endif
-+#if NR_CPUS > 28
-+ CPU_ENUM(28),
-+#endif
-+#if NR_CPUS > 29
-+ CPU_ENUM(29),
-+#endif
-+#if NR_CPUS > 30
-+ CPU_ENUM(30),
-+#endif
-+#if NR_CPUS > 31
-+ CPU_ENUM(31),
-+#endif
-+#if NR_CPUS > 32
-+#error please extend CPU enumeration
-+#endif
-+ {
-+ .ctl_name = 0,
-+ }
-+};
-+
-+static ctl_table ctl_cpu[2] = {
-+ {
-+ .ctl_name = CTL_CPU,
-+ .procname = "cpu",
-+ .mode = 0555,
-+ .child = ctl_cpu_table,
-+ },
-+ {
-+ .ctl_name = 0,
-+ }
-+};
-+
-+struct ctl_table_header *cpufreq_sysctl_table;
-+
-+static inline void cpufreq_sysctl_init(void)
-+{
-+ cpufreq_sysctl_table = register_sysctl_table(ctl_cpu, 0);
-+}
-+
-+static inline void cpufreq_sysctl_exit(void)
-+{
-+ unregister_sysctl_table(cpufreq_sysctl_table);
-+}
-+
-+#else
-+#define cpufreq_sysctl_init() do {} while(0)
-+#define cpufreq_sysctl_exit() do {} while(0)
-+#endif /* CONFIG_CPU_FREQ_24API */
-+
-+
-+/************************** sysfs interface ************************/
-+static ssize_t show_speed (struct cpufreq_policy *policy, char *buf)
-+{
-+ return sprintf (buf, "%u\n", cpu_cur_freq[policy->cpu]);
-+}
-+
-+static ssize_t
-+store_speed (struct cpufreq_policy *policy, const char *buf, size_t count)
-+{
-+ unsigned int freq = 0;
-+ unsigned int ret;
-+
-+ ret = sscanf (buf, "%u", &freq);
-+ if (ret != 1)
-+ return -EINVAL;
-+
-+ cpufreq_set(freq, policy->cpu);
-+
-+ return count;
-+}
-+
-+static struct freq_attr freq_attr_scaling_setspeed = {
-+ .attr = { .name = "scaling_setspeed", .mode = 0644 },
-+ .show = show_speed,
-+ .store = store_speed,
-+};
-+
-+static int cpufreq_governor_userspace(struct cpufreq_policy *policy,
-+ unsigned int event)
-+{
-+ unsigned int cpu = policy->cpu;
-+ switch (event) {
-+ case CPUFREQ_GOV_START:
-+ if ((!cpu_online(cpu)) || (!try_module_get(THIS_MODULE)) ||
-+ !policy->cur)
-+ return -EINVAL;
-+ down(&userspace_sem);
-+ cpu_is_managed[cpu] = 1;
-+ cpu_min_freq[cpu] = policy->min;
-+ cpu_max_freq[cpu] = policy->max;
-+ cpu_cur_freq[cpu] = policy->cur;
-+ sysfs_create_file (&policy->kobj, &freq_attr_scaling_setspeed.attr);
-+ memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
-+ up(&userspace_sem);
-+ break;
-+ case CPUFREQ_GOV_STOP:
-+ down(&userspace_sem);
-+ cpu_is_managed[cpu] = 0;
-+ cpu_min_freq[cpu] = 0;
-+ cpu_max_freq[cpu] = 0;
-+ sysfs_remove_file (&policy->kobj, &freq_attr_scaling_setspeed.attr);
-+ up(&userspace_sem);
-+ module_put(THIS_MODULE);
-+ break;
-+ case CPUFREQ_GOV_LIMITS:
-+ down(&userspace_sem);
-+ cpu_min_freq[cpu] = policy->min;
-+ cpu_max_freq[cpu] = policy->max;
-+ if (policy->max < cpu_cur_freq[cpu])
-+ cpufreq_driver_target(&current_policy[cpu], policy->max,
-+ CPUFREQ_RELATION_H);
-+ else if (policy->min > cpu_cur_freq[cpu])
-+ cpufreq_driver_target(&current_policy[cpu], policy->min,
-+ CPUFREQ_RELATION_L);
-+ memcpy (&current_policy[cpu], policy, sizeof(struct cpufreq_policy));
-+ up(&userspace_sem);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+/* on ARM SA1100 we need to rely on the values of cpufreq_get() - because
-+ * of this, cpu_cur_freq[] needs to be set early.
-+ */
-+#if defined(CONFIG_ARM) && defined(CONFIG_ARCH_SA1100)
-+extern unsigned int sa11x0_getspeed(void);
-+
-+static void cpufreq_sa11x0_compat(void)
-+{
-+ cpu_cur_freq[0] = sa11x0_getspeed();
-+}
-+#else
-+#define cpufreq_sa11x0_compat() do {} while(0)
-+#endif
-+
-+
-+static struct cpufreq_governor cpufreq_gov_userspace = {
-+ .name = "userspace",
-+ .governor = cpufreq_governor_userspace,
-+ .owner = THIS_MODULE,
-+};
-+EXPORT_SYMBOL(cpufreq_gov_userspace);
-+
-+static int already_init = 0;
-+
-+int cpufreq_gov_userspace_init(void)
-+{
-+ if (!already_init) {
-+ down(&userspace_sem);
-+ cpufreq_sa11x0_compat();
-+ cpufreq_sysctl_init();
-+ cpufreq_register_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
-+ already_init = 1;
-+ up(&userspace_sem);
-+ }
-+ return cpufreq_register_governor(&cpufreq_gov_userspace);
-+}
-+EXPORT_SYMBOL(cpufreq_gov_userspace_init);
-+
-+
-+static void __exit cpufreq_gov_userspace_exit(void)
-+{
-+ cpufreq_unregister_governor(&cpufreq_gov_userspace);
-+ cpufreq_unregister_notifier(&userspace_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
-+ cpufreq_sysctl_exit();
-+}
-+
-+
-+MODULE_AUTHOR ("Dominik Brodowski <linux@brodo.de>, Russell King <rmk@arm.linux.org.uk>");
-+MODULE_DESCRIPTION ("CPUfreq policy governor 'userspace'");
-+MODULE_LICENSE ("GPL");
-+
-+module_init(cpufreq_gov_userspace_init);
-+module_exit(cpufreq_gov_userspace_exit);
---- linux-2.4.25/drivers/i2c/Config.in~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/i2c/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -17,6 +17,15 @@
- int ' GPIO pin used for SCL' CONFIG_SCx200_I2C_SCL 12
- int ' GPIO pin used for SDA' CONFIG_SCx200_I2C_SDA 13
- fi
-+
-+ dep_tristate ' Guide GPIO adapter' CONFIG_I2C_GUIDE $CONFIG_I2C_ALGOBIT
-+ if [ "$CONFIG_ARCH_OMAHA" = "y" ]; then
-+ dep_tristate ' Omaha I2C interface' CONFIG_I2C_OMAHA $CONFIG_I2C
-+ fi
-+ if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
-+ dep_tristate ' Frodo I2C adapter' CONFIG_I2C_FRODO $CONFIG_I2C_ALGOBIT
-+ dep_tristate ' SA1100 I2C GPIO adapter' CONFIG_I2C_BIT_SA1100_GPIO $CONFIG_I2C_ALGOBIT
-+ fi
- fi
-
- dep_tristate 'NatSemi SCx200 ACCESS.bus' CONFIG_SCx200_ACB $CONFIG_I2C
-@@ -49,6 +58,10 @@
- dep_tristate 'Keywest I2C interface in Apple Core99 machines' CONFIG_I2C_KEYWEST $CONFIG_I2C
- fi
-
-+ if [ "$CONFIG_ARCH_AT91RM9200" = "y" ] ; then
-+ dep_tristate 'Atmel AT91RM9200 I2C Two-Wire interface (TWI)' CONFIG_I2C_AT91 $CONFIG_I2C
-+ fi
-+
- if [ "$CONFIG_SIBYTE_SB1xxx_SOC" = "y" ]; then
- dep_tristate 'SiByte SMBus interface' CONFIG_I2C_ALGO_SIBYTE $CONFIG_I2C
- dep_tristate ' MAX1617 Temperature Sensor' CONFIG_I2C_MAX1617 $CONFIG_I2C_ALGO_SIBYTE
---- linux-2.4.25/drivers/i2c/Makefile~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/i2c/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -8,12 +8,21 @@
- i2c-algo-ite.o i2c-algo-sibyte.o i2c-algo-sgi.o \
- i2c-proc.o
-
-+# Init order: core, chardev, bit adapters, pcf adapters
-+
- obj-$(CONFIG_I2C) += i2c-core.o
- obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o
-+
-+# Bit adapters
- obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o
- obj-$(CONFIG_I2C_PHILIPSPAR) += i2c-philips-par.o
- obj-$(CONFIG_I2C_ELV) += i2c-elv.o
- obj-$(CONFIG_I2C_VELLEMAN) += i2c-velleman.o
-+obj-$(CONFIG_I2C_GUIDE) += i2c-guide.o
-+obj-$(CONFIG_I2C_FRODO) += i2c-frodo.o
-+obj-$(CONFIG_I2C_OMAHA) += i2c-omaha.o
-+
-+# PCF adapters
- obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o
- obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o
- obj-$(CONFIG_ITE_I2C_ALGO) += i2c-algo-ite.o
-@@ -30,4 +39,3 @@
- # This is needed for automatic patch generation: sensors code ends here
-
- include $(TOPDIR)/Rules.make
--
---- linux-2.4.25/drivers/i2c/i2c-algo-bit.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/i2c/i2c-algo-bit.c 2004-03-31 17:15:09.000000000 +0200
-@@ -169,7 +169,14 @@
- * 1 if the device acknowledged
- * 0 if the device did not ack
- * -ETIMEDOUT if an error occurred (while raising the scl line)
-- */
-+
-+ * tsong@iders.ca: an instruction to disable any timeconsuming interrupt
-+ here except the heart beat of timer2 should be added before setsda(adap, sb).
-+ because when interrupt occurs during
-+ scl is set high, the interrupt service routine is served and may take long,
-+ after the interrupt returns, sda could be sampled by the device(slave)
-+ more than once, and this cause error problem.
-+*/
- static int i2c_outb(struct i2c_adapter *i2c_adap, char c)
- {
- int i;
-@@ -582,9 +589,7 @@
- printk("\n");
- }
-
--#ifdef MODULE
- MOD_INC_USE_COUNT;
--#endif
- i2c_add_adapter(adap);
-
- return 0;
-@@ -600,15 +605,13 @@
-
- DEB2(printk("i2c-algo-bit.o: adapter unregistered: %s\n",adap->name));
-
--#ifdef MODULE
- MOD_DEC_USE_COUNT;
--#endif
- return 0;
- }
-
--int __init i2c_algo_bit_init (void)
-+static int __init i2c_algo_bit_init (void)
- {
-- printk(KERN_INFO "i2c-algo-bit.o: i2c bit algorithm module\n");
-+ printk(KERN_DEBUG "i2c-algo-bit.o: i2c bit algorithm module\n");
- return 0;
- }
-
-@@ -617,7 +620,6 @@
- EXPORT_SYMBOL(i2c_bit_add_bus);
- EXPORT_SYMBOL(i2c_bit_del_bus);
-
--#ifdef MODULE
- MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
- MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm");
- MODULE_LICENSE("GPL");
-@@ -631,12 +633,4 @@
- MODULE_PARM_DESC(i2c_debug,
- "debug level - 0 off; 1 normal; 2,3 more verbose; 9 bit-protocol");
-
--int init_module(void)
--{
-- return i2c_algo_bit_init();
--}
--
--void cleanup_module(void)
--{
--}
--#endif
-+module_init(i2c_algo_bit_init);
---- linux-2.4.25/drivers/i2c/i2c-algo-pcf.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/i2c/i2c-algo-pcf.c 2004-03-31 17:15:09.000000000 +0200
-@@ -475,9 +475,7 @@
- return i;
- }
-
--#ifdef MODULE
- MOD_INC_USE_COUNT;
--#endif
-
- i2c_add_adapter(adap);
-
-@@ -515,13 +513,11 @@
- return res;
- DEB2(printk("i2c-algo-pcf.o: adapter unregistered: %s\n",adap->name));
-
--#ifdef MODULE
- MOD_DEC_USE_COUNT;
--#endif
- return 0;
- }
-
--int __init i2c_algo_pcf_init (void)
-+static int __init i2c_algo_pcf_init (void)
- {
- printk("i2c-algo-pcf.o: i2c pcf8584 algorithm module\n");
- return 0;
-@@ -531,7 +527,6 @@
- EXPORT_SYMBOL(i2c_pcf_add_bus);
- EXPORT_SYMBOL(i2c_pcf_del_bus);
-
--#ifdef MODULE
- MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
- MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm");
- MODULE_LICENSE("GPL");
-@@ -543,13 +538,4 @@
- MODULE_PARM_DESC(i2c_debug,
- "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");
-
--
--int init_module(void)
--{
-- return i2c_algo_pcf_init();
--}
--
--void cleanup_module(void)
--{
--}
--#endif
-+module_init(i2c_algo_pcf_init);
---- linux-2.4.25/drivers/i2c/i2c-core.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/i2c/i2c-core.c 2004-03-31 17:15:09.000000000 +0200
-@@ -41,7 +41,7 @@
-
- /* exclusive access to the bus */
- #define I2C_LOCK(adap) down(&adap->lock)
--#define I2C_UNLOCK(adap) up(&adap->lock)
-+#define I2C_UNLOCK(adap) up(&adap->lock)
-
- #define ADAP_LOCK() down(&adap_lock)
- #define ADAP_UNLOCK() up(&adap_lock)
-@@ -67,7 +67,7 @@
- static int driver_count;
-
- /**** debug level */
--static int i2c_debug=1;
-+static int i2c_debug = 0;
-
- /* ---------------------------------------------------
- * /proc entry declarations
-@@ -77,14 +77,14 @@
- #ifdef CONFIG_PROC_FS
-
- static int i2cproc_init(void);
--static int i2cproc_cleanup(void);
-+static void i2cproc_cleanup(void);
-
--static ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count,
-+static ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count,
- loff_t *ppos);
- static int read_bus_i2c(char *buf, char **start, off_t offset, int len,
- int *eof , void *private);
-
--/* To implement the dynamic /proc/bus/i2c-? files, we need our own
-+/* To implement the dynamic /proc/bus/i2c-? files, we need our own
- implementation of the read hook */
- static struct file_operations i2cproc_operations = {
- read: i2cproc_bus_read,
-@@ -101,8 +101,8 @@
-
-
- /* ---------------------------------------------------
-- * registering functions
-- * ---------------------------------------------------
-+ * registering functions
-+ * ---------------------------------------------------
- */
-
- /* -----
-@@ -119,7 +119,7 @@
- if (NULL == adapters[i])
- break;
- if (I2C_ADAP_MAX == i) {
-- printk(KERN_WARNING
-+ printk(KERN_WARNING
- " i2c-core.o: register_adapter(%s) - enlarge I2C_ADAP_MAX.\n",
- adap->name);
- res = -ENOMEM;
-@@ -129,7 +129,7 @@
- adapters[i] = adap;
- adap_count++;
- ADAP_UNLOCK();
--
-+
- /* init data types */
- init_MUTEX(&adap->lock);
-
-@@ -157,18 +157,18 @@
- #endif /* def CONFIG_PROC_FS */
-
- /* inform drivers of new adapters */
-- DRV_LOCK();
-+ DRV_LOCK();
- for (j=0;j<I2C_DRIVER_MAX;j++)
-- if (drivers[j]!=NULL &&
-+ if (drivers[j]!=NULL &&
- (drivers[j]->flags&(I2C_DF_NOTIFY|I2C_DF_DUMMY)))
- /* We ignore the return code; if it fails, too bad */
- drivers[j]->attach_adapter(adap);
- DRV_UNLOCK();
--
-+
- DEB(printk(KERN_DEBUG "i2c-core.o: adapter %s registered as adapter %d.\n",
- adap->name,i));
-
-- return 0;
-+ return 0;
-
-
- ERROR1:
-@@ -203,13 +203,13 @@
- * this or hell will break loose...
- */
- DRV_LOCK();
-- for (j = 0; j < I2C_DRIVER_MAX; j++)
-+ for (j = 0; j < I2C_DRIVER_MAX; j++)
- if (drivers[j] && (drivers[j]->flags & I2C_DF_DUMMY))
- if ((res = drivers[j]->attach_adapter(adap))) {
- printk(KERN_WARNING "i2c-core.o: can't detach adapter %s "
- "while detaching driver %s: driver not "
- "detached!",adap->name,drivers[j]->name);
-- goto ERROR1;
-+ goto ERROR1;
- }
- DRV_UNLOCK();
-
-@@ -241,8 +241,8 @@
-
- adapters[i] = NULL;
- adap_count--;
--
-- ADAP_UNLOCK();
-+
-+ ADAP_UNLOCK();
- DEB(printk(KERN_DEBUG "i2c-core.o: adapter unregistered: %s\n",adap->name));
- return 0;
-
-@@ -269,7 +269,7 @@
- if (NULL == drivers[i])
- break;
- if (I2C_DRIVER_MAX == i) {
-- printk(KERN_WARNING
-+ printk(KERN_WARNING
- " i2c-core.o: register_driver(%s) "
- "- enlarge I2C_DRIVER_MAX.\n",
- driver->name);
-@@ -279,11 +279,11 @@
-
- drivers[i] = driver;
- driver_count++;
--
-+
- DRV_UNLOCK(); /* driver was successfully added */
--
-+
- DEB(printk(KERN_DEBUG "i2c-core.o: driver %s registered.\n",driver->name));
--
-+
- ADAP_LOCK();
-
- /* now look for instances of driver on our adapters
-@@ -314,11 +314,11 @@
- return -ENODEV;
- }
- /* Have a look at each adapter, if clients of this driver are still
-- * attached. If so, detach them to be able to kill the driver
-+ * attached. If so, detach them to be able to kill the driver
- * afterwards.
- */
- DEB2(printk(KERN_DEBUG "i2c-core.o: unregister_driver - looking for clients.\n"));
-- /* removing clients does not depend on the notify flag, else
-+ /* removing clients does not depend on the notify flag, else
- * invalid operation might (will!) result, when using stale client
- * pointers.
- */
-@@ -333,7 +333,7 @@
- /* DUMMY drivers do not register their clients, so we have to
- * use a trick here: we call driver->attach_adapter to
- * *detach* it! Of course, each dummy driver should know about
-- * this or hell will break loose...
-+ * this or hell will break loose...
- */
- if ((res = driver->attach_adapter(adap))) {
- printk(KERN_WARNING "i2c-core.o: while unregistering "
-@@ -345,9 +345,9 @@
- return res;
- }
- } else {
-- for (j=0;j<I2C_CLIENT_MAX;j++) {
-+ for (j=0;j<I2C_CLIENT_MAX;j++) {
- struct i2c_client *client = adap->clients[j];
-- if (client != NULL &&
-+ if (client != NULL &&
- client->driver == driver) {
- DEB2(printk(KERN_DEBUG "i2c-core.o: "
- "detaching client %s:\n",
-@@ -376,7 +376,7 @@
- drivers[i] = NULL;
- driver_count--;
- DRV_UNLOCK();
--
-+
- DEB(printk(KERN_DEBUG "i2c-core.o: driver unregistered: %s\n",driver->name));
- return 0;
- }
-@@ -384,7 +384,7 @@
- int i2c_check_addr (struct i2c_adapter *adapter, int addr)
- {
- int i;
-- for (i = 0; i < I2C_CLIENT_MAX ; i++)
-+ for (i = 0; i < I2C_CLIENT_MAX ; i++)
- if (adapter->clients[i] && (adapter->clients[i]->addr == addr))
- return -EBUSY;
- return 0;
-@@ -402,7 +402,7 @@
- if (NULL == adapter->clients[i])
- break;
- if (I2C_CLIENT_MAX == i) {
-- printk(KERN_WARNING
-+ printk(KERN_WARNING
- " i2c-core.o: attach_client(%s) - enlarge I2C_CLIENT_MAX.\n",
- client->name);
- return -ENOMEM;
-@@ -410,9 +410,9 @@
-
- adapter->clients[i] = client;
- adapter->client_count++;
--
-- if (adapter->client_register)
-- if (adapter->client_register(client))
-+
-+ if (adapter->client_register)
-+ if (adapter->client_register(client))
- printk(KERN_DEBUG "i2c-core.o: warning: client_register seems "
- "to have failed for client %02x at adapter %s\n",
- client->addr,adapter->name);
-@@ -421,7 +421,7 @@
-
- if(client->flags & I2C_CLIENT_ALLOW_USE)
- client->usage_count = 0;
--
-+
- return 0;
- }
-
-@@ -440,12 +440,12 @@
- client->name);
- return -ENODEV;
- }
--
-- if( (client->flags & I2C_CLIENT_ALLOW_USE) &&
-+
-+ if( (client->flags & I2C_CLIENT_ALLOW_USE) &&
- (client->usage_count>0))
- return -EBUSY;
--
-- if (adapter->client_unregister != NULL)
-+
-+ if (adapter->client_unregister != NULL)
- if ((res = adapter->client_unregister(client))) {
- printk(KERN_ERR "i2c-core.o: client_unregister [%s] failed, "
- "client not detached",client->name);
-@@ -471,7 +471,7 @@
-
- void i2c_dec_use_client(struct i2c_client *client)
- {
--
-+
- if (client->driver->dec_use != NULL)
- client->driver->dec_use(client);
-
-@@ -479,65 +479,65 @@
- client->adapter->dec_use(client->adapter);
- }
-
--struct i2c_client *i2c_get_client(int driver_id, int adapter_id,
-+struct i2c_client *i2c_get_client(int driver_id, int adapter_id,
- struct i2c_client *prev)
- {
- int i,j;
--
-+
- /* Will iterate through the list of clients in each adapter of adapters-list
-- in search for a client that matches the search criteria. driver_id or
-- adapter_id are ignored if set to 0. If both are ignored this returns
-+ in search for a client that matches the search criteria. driver_id or
-+ adapter_id are ignored if set to 0. If both are ignored this returns
- first client found. */
--
-- i = j = 0;
--
-- /* set starting point */
-+
-+ i = j = 0;
-+
-+ /* set starting point */
- if(prev)
- {
- if(!(prev->adapter))
- return (struct i2c_client *) -EINVAL;
--
-+
- for(j=0; j < I2C_ADAP_MAX; j++)
- if(prev->adapter == adapters[j])
- break;
--
-+
- /* invalid starting point? */
- if (I2C_ADAP_MAX == j) {
- printk(KERN_WARNING " i2c-core.o: get_client adapter for client:[%s] not found\n",
- prev->name);
- return (struct i2c_client *) -ENODEV;
-- }
--
-+ }
-+
- for(i=0; i < I2C_CLIENT_MAX; i++)
- if(prev == adapters[j]->clients[i])
- break;
--
-+
- /* invalid starting point? */
- if (I2C_CLIENT_MAX == i) {
- printk(KERN_WARNING " i2c-core.o: get_client client:[%s] not found\n",
- prev->name);
- return (struct i2c_client *) -ENODEV;
-- }
--
-+ }
-+
- i++; /* start from one after prev */
- }
--
-+
- for(; j < I2C_ADAP_MAX; j++)
- {
- if(!adapters[j])
- continue;
--
-+
- if(adapter_id && (adapters[j]->id != adapter_id))
- continue;
--
-+
- for(; i < I2C_CLIENT_MAX; i++)
- {
- if(!adapters[j]->clients[i])
- continue;
--
-+
- if(driver_id && (adapters[j]->clients[i]->driver->id != driver_id))
- continue;
-- if(adapters[j]->clients[i]->flags & I2C_CLIENT_ALLOW_USE)
-+ if(adapters[j]->clients[i]->flags & I2C_CLIENT_ALLOW_USE)
- return adapters[j]->clients[i];
- }
- i = 0;
-@@ -549,12 +549,12 @@
- int i2c_use_client(struct i2c_client *client)
- {
- if(client->flags & I2C_CLIENT_ALLOW_USE) {
-- if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE)
-+ if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE)
- client->usage_count++;
- else {
-- if(client->usage_count > 0)
-+ if(client->usage_count > 0)
- return -EBUSY;
-- else
-+ else
- client->usage_count++;
- }
- }
-@@ -575,9 +575,9 @@
- return -EPERM;
- }
- }
--
-+
- i2c_dec_use_client(client);
--
-+
- return 0;
- }
-
-@@ -589,7 +589,7 @@
- #ifdef CONFIG_PROC_FS
-
- /* This function generates the output for /proc/bus/i2c */
--int read_bus_i2c(char *buf, char **start, off_t offset, int len, int *eof,
-+int read_bus_i2c(char *buf, char **start, off_t offset, int len, int *eof,
- void *private)
- {
- int i;
-@@ -615,7 +615,7 @@
- }
-
- /* This function generates the output for /proc/bus/i2c-? */
--ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count,
-+ssize_t i2cproc_bus_read(struct file * file, char * buf,size_t count,
- loff_t *ppos)
- {
- struct inode * inode = file->f_dentry->d_inode;
-@@ -626,7 +626,7 @@
- int order[I2C_CLIENT_MAX];
-
- if (count > 4000)
-- return -EINVAL;
-+ return -EINVAL;
- len_total = file->f_pos + count;
- /* Too bad if this gets longer (unlikely) */
- if (len_total > 4000)
-@@ -641,12 +641,12 @@
- sorted by address */
- order_nr=0;
- for (j = 0; j < I2C_CLIENT_MAX; j++) {
-- if ((client = adapters[i]->clients[j]) &&
-+ if ((client = adapters[i]->clients[j]) &&
- (client->driver->id != I2C_DRIVERID_I2CDEV)) {
-- for(k = order_nr;
-- (k > 0) &&
-+ for(k = order_nr;
-+ (k > 0) &&
- adapters[i]->clients[order[k-1]]->
-- addr > client->addr;
-+ addr > client->addr;
- k--)
- order[k] = order[k-1];
- order[k] = j;
-@@ -665,7 +665,7 @@
- len = len - file->f_pos;
- if (len > count)
- len = count;
-- if (len < 0)
-+ if (len < 0)
- len = 0;
- if (copy_to_user (buf,kbuf+file->f_pos, len)) {
- kfree(kbuf);
-@@ -689,7 +689,7 @@
- printk("i2c-core.o: /proc/bus/ does not exist");
- i2cproc_cleanup();
- return -ENOENT;
-- }
-+ }
- proc_bus_i2c = create_proc_entry("i2c",0,proc_bus);
- if (!proc_bus_i2c) {
- printk(KERN_ERR "i2c-core.o: Could not create /proc/bus/i2c");
-@@ -702,14 +702,13 @@
- return 0;
- }
-
--int i2cproc_cleanup(void)
-+static void i2cproc_cleanup(void)
- {
-
- if (i2cproc_initialized >= 1) {
- remove_proc_entry("i2c",proc_bus);
- i2cproc_initialized -= 2;
- }
-- return 0;
- }
-
-
-@@ -751,10 +750,10 @@
- msg.flags = client->flags & I2C_M_TEN;
- msg.len = count;
- (const char *)msg.buf = buf;
--
-+
- DEB2(printk(KERN_DEBUG "i2c-core.o: master_send: writing %d bytes on %s.\n",
- count,client->adapter->name));
--
-+
- I2C_LOCK(adap);
- ret = adap->algo->master_xfer(adap,&msg,1);
- I2C_UNLOCK(adap);
-@@ -784,14 +783,14 @@
-
- DEB2(printk(KERN_DEBUG "i2c-core.o: master_recv: reading %d bytes on %s.\n",
- count,client->adapter->name));
--
-+
- I2C_LOCK(adap);
- ret = adap->algo->master_xfer(adap,&msg,1);
- I2C_UNLOCK(adap);
--
-+
- DEB2(printk(KERN_DEBUG "i2c-core.o: master_recv: return:%d (count:%d, addr:0x%02x)\n",
- ret, count, client->addr));
--
-+
- /* if everything went ok (i.e. 1 msg transmitted), return #bytes
- * transmitted, else error code.
- */
-@@ -852,7 +851,7 @@
- found = 0;
-
- for (i = 0; !found && (address_data->force[i] != I2C_CLIENT_END); i += 3) {
-- if (((adap_id == address_data->force[i]) ||
-+ if (((adap_id == address_data->force[i]) ||
- (address_data->force[i] == ANY_I2C_BUS)) &&
- (addr == address_data->force[i+1])) {
- DEB2(printk(KERN_DEBUG "i2c-core.o: found force parameter for adapter %d, addr %04x\n",
-@@ -862,7 +861,7 @@
- found = 1;
- }
- }
-- if (found)
-+ if (found)
- continue;
-
- /* If this address is in one of the ignores, we can forget about
-@@ -870,7 +869,7 @@
- for (i = 0;
- !found && (address_data->ignore[i] != I2C_CLIENT_END);
- i += 2) {
-- if (((adap_id == address_data->ignore[i]) ||
-+ if (((adap_id == address_data->ignore[i]) ||
- ((address_data->ignore[i] == ANY_I2C_BUS))) &&
- (addr == address_data->ignore[i+1])) {
- DEB2(printk(KERN_DEBUG "i2c-core.o: found ignore parameter for adapter %d, "
-@@ -890,11 +889,11 @@
- found = 1;
- }
- }
-- if (found)
-+ if (found)
- continue;
-
-- /* Now, we will do a detection, but only if it is in the normal or
-- probe entries */
-+ /* Now, we will do a detection, but only if it is in the normal or
-+ probe entries */
- for (i = 0;
- !found && (address_data->normal_i2c[i] != I2C_CLIENT_END);
- i += 1) {
-@@ -939,7 +938,7 @@
- "addr %04x\n", adap_id,addr));
- }
- }
-- if (!found)
-+ if (!found)
- continue;
-
- /* OK, so we really should examine this address. First check
-@@ -1087,11 +1086,11 @@
- I2C_SMBUS_I2C_BLOCK_DATA,&data);
- }
-
--/* Simulate a SMBus command using the i2c protocol
-+/* Simulate a SMBus command using the i2c protocol
- No checking of parameters is done! */
--static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
-+static s32 i2c_smbus_xfer_emulated(struct i2c_adapter * adapter, u16 addr,
- unsigned short flags,
-- char read_write, u8 command, int size,
-+ char read_write, u8 command, int size,
- union i2c_smbus_data * data)
- {
- /* So we need to generate a series of msgs. In the case of writing, we
-@@ -1101,7 +1100,7 @@
- unsigned char msgbuf0[34];
- unsigned char msgbuf1[34];
- int num = read_write == I2C_SMBUS_READ?2:1;
-- struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 },
-+ struct i2c_msg msg[2] = { { addr, flags, 1, msgbuf0 },
- { addr, flags | I2C_M_RD, 0, msgbuf1 }
- };
- int i;
-@@ -1179,7 +1178,7 @@
- case I2C_SMBUS_BYTE_DATA:
- data->byte = msgbuf1[0];
- break;
-- case I2C_SMBUS_WORD_DATA:
-+ case I2C_SMBUS_WORD_DATA:
- case I2C_SMBUS_PROC_CALL:
- data->word = msgbuf1[0] | (msgbuf1[1] << 8);
- break;
-@@ -1189,7 +1188,7 @@
-
-
- s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags,
-- char read_write, u8 command, int size,
-+ char read_write, u8 command, int size,
- union i2c_smbus_data * data)
- {
- s32 res;
-@@ -1207,7 +1206,7 @@
-
-
- /* You should always define `functionality'; the 'else' is just for
-- backward compatibility. */
-+ backward compatibility. */
- u32 i2c_get_functionality (struct i2c_adapter *adap)
- {
- if (adap->algo->functionality)
-@@ -1233,122 +1232,12 @@
-
- init_MUTEX(&adap_lock);
- init_MUTEX(&driver_lock);
--
-- i2cproc_init();
--
-- return 0;
--}
--
--#ifndef MODULE
--#ifdef CONFIG_I2C_CHARDEV
-- extern int i2c_dev_init(void);
--#endif
--#ifdef CONFIG_I2C_ALGOBIT
-- extern int i2c_algo_bit_init(void);
--#endif
--#ifdef CONFIG_I2C_PHILIPSPAR
-- extern int i2c_bitlp_init(void);
--#endif
--#ifdef CONFIG_I2C_ELV
-- extern int i2c_bitelv_init(void);
--#endif
--#ifdef CONFIG_I2C_VELLEMAN
-- extern int i2c_bitvelle_init(void);
--#endif
--#ifdef CONFIG_I2C_BITVIA
-- extern int i2c_bitvia_init(void);
--#endif
-
--#ifdef CONFIG_I2C_ALGOPCF
-- extern int i2c_algo_pcf_init(void);
--#endif
--#ifdef CONFIG_I2C_ELEKTOR
-- extern int i2c_pcfisa_init(void);
--#endif
--
--#ifdef CONFIG_I2C_ALGO8XX
-- extern int i2c_algo_8xx_init(void);
--#endif
--#ifdef CONFIG_I2C_RPXLITE
-- extern int i2c_rpx_init(void);
--#endif
--
--#ifdef CONFIG_I2C_ALGO_SIBYTE
-- extern int i2c_algo_sibyte_init(void);
-- extern int i2c_sibyte_init(void);
--#endif
--#ifdef CONFIG_I2C_MAX1617
-- extern int i2c_max1617_init(void);
--#endif
--
--#ifdef CONFIG_I2C_PROC
-- extern int sensors_init(void);
--#endif
--
--/* This is needed for automatic patch generation: sensors code starts here */
--/* This is needed for automatic patch generation: sensors code ends here */
--
--int __init i2c_init_all(void)
--{
-- /* --------------------- global ----- */
-- i2c_init();
--
--#ifdef CONFIG_I2C_CHARDEV
-- i2c_dev_init();
--#endif
-- /* --------------------- bit -------- */
--#ifdef CONFIG_I2C_ALGOBIT
-- i2c_algo_bit_init();
--#endif
--#ifdef CONFIG_I2C_PHILIPSPAR
-- i2c_bitlp_init();
--#endif
--#ifdef CONFIG_I2C_ELV
-- i2c_bitelv_init();
--#endif
--#ifdef CONFIG_I2C_VELLEMAN
-- i2c_bitvelle_init();
--#endif
--
-- /* --------------------- pcf -------- */
--#ifdef CONFIG_I2C_ALGOPCF
-- i2c_algo_pcf_init();
--#endif
--#ifdef CONFIG_I2C_ELEKTOR
-- i2c_pcfisa_init();
--#endif
--
-- /* --------------------- 8xx -------- */
--#ifdef CONFIG_I2C_ALGO8XX
-- i2c_algo_8xx_init();
--#endif
--#ifdef CONFIG_I2C_RPXLITE
-- i2c_rpx_init();
--#endif
--
-- /* --------------------- SiByte -------- */
--#ifdef CONFIG_I2C_ALGO_SIBYTE
-- i2c_algo_sibyte_init();
-- i2c_sibyte_init();
--#endif
--#ifdef CONFIG_I2C_MAX1617
-- i2c_max1617_init();
--#endif
--
-- /* -------------- proc interface ---- */
--#ifdef CONFIG_I2C_PROC
-- sensors_init();
--#endif
--/* This is needed for automatic patch generation: sensors code starts here */
--/* This is needed for automatic patch generation: sensors code ends here */
-+ i2cproc_init();
-
- return 0;
- }
-
--#endif
--
--
--
- EXPORT_SYMBOL(i2c_add_adapter);
- EXPORT_SYMBOL(i2c_del_adapter);
- EXPORT_SYMBOL(i2c_add_driver);
-@@ -1385,7 +1274,6 @@
- EXPORT_SYMBOL(i2c_get_functionality);
- EXPORT_SYMBOL(i2c_check_functionality);
-
--#ifdef MODULE
- MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
- MODULE_DESCRIPTION("I2C-Bus main module");
- MODULE_LICENSE("GPL");
-@@ -1393,13 +1281,5 @@
- MODULE_PARM(i2c_debug, "i");
- MODULE_PARM_DESC(i2c_debug,"debug level");
-
--int init_module(void)
--{
-- return i2c_init();
--}
--
--void cleanup_module(void)
--{
-- i2cproc_cleanup();
--}
--#endif
-+module_init(i2c_init);
-+module_exit(i2cproc_cleanup);
---- linux-2.4.25/drivers/i2c/i2c-dev.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/i2c/i2c-dev.c 2004-03-31 17:15:09.000000000 +0200
-@@ -1,5 +1,5 @@
- /*
-- i2c-dev.c - i2c-bus driver, char device interface
-+ i2c-dev.c - i2c-bus driver, char device interface
-
- Copyright (C) 1995-97 Simon G. Vogl
- Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
-@@ -25,7 +25,7 @@
-
- /* The I2C_RDWR ioctl code is written by Kolja Waschk <waschk@telos.de> */
-
--/* The devfs code is contributed by Philipp Matthias Hahn
-+/* The devfs code is contributed by Philipp Matthias Hahn
- <pmhahn@titan.lahn.de> */
-
- /* $Id$ */
-@@ -50,19 +50,14 @@
- #include <linux/i2c.h>
- #include <linux/i2c-dev.h>
-
--#ifdef MODULE
--extern int init_module(void);
--extern int cleanup_module(void);
--#endif /* def MODULE */
--
- /* struct file_operations changed too often in the 2.1 series for nice code */
-
--static ssize_t i2cdev_read (struct file *file, char *buf, size_t count,
-+static ssize_t i2cdev_read (struct file *file, char *buf, size_t count,
- loff_t *offset);
--static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count,
-+static ssize_t i2cdev_write (struct file *file, const char *buf, size_t count,
- loff_t *offset);
-
--static int i2cdev_ioctl (struct inode *inode, struct file *file,
-+static int i2cdev_ioctl (struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg);
- static int i2cdev_open (struct inode *inode, struct file *file);
-
-@@ -73,13 +68,8 @@
- static int i2cdev_command(struct i2c_client *client, unsigned int cmd,
- void *arg);
-
--#ifdef MODULE
--static
--#else
--extern
--#endif
-- int __init i2c_dev_init(void);
--static int i2cdev_cleanup(void);
-+static int __init i2c_dev_init(void);
-+static void i2cdev_cleanup(void);
-
- static struct file_operations i2cdev_fops = {
- owner: THIS_MODULE,
-@@ -185,7 +175,7 @@
- return ret;
- }
-
--int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
-+int i2cdev_ioctl (struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg)
- {
- struct i2c_client *client = (struct i2c_client *)file->private_data;
-@@ -198,14 +188,14 @@
- unsigned long funcs;
-
- #ifdef DEBUG
-- printk(KERN_DEBUG "i2c-dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n",
-+ printk(KERN_DEBUG "i2c-dev.o: i2c-%d ioctl, cmd: 0x%x, arg: %lx.\n",
- MINOR(inode->i_rdev),cmd, arg);
- #endif /* DEBUG */
-
- switch ( cmd ) {
- case I2C_SLAVE:
- case I2C_SLAVE_FORCE:
-- if ((arg > 0x3ff) ||
-+ if ((arg > 0x3ff) ||
- (((client->flags & I2C_M_TEN) == 0) && arg > 0x7f))
- return -EINVAL;
- if ((cmd == I2C_SLAVE) && i2c_check_addr(client->adapter,arg))
-@@ -224,8 +214,8 @@
- sizeof(unsigned long)))?-EFAULT:0;
-
- case I2C_RDWR:
-- if (copy_from_user(&rdwr_arg,
-- (struct i2c_rdwr_ioctl_data *)arg,
-+ if (copy_from_user(&rdwr_arg,
-+ (struct i2c_rdwr_ioctl_data *)arg,
- sizeof(rdwr_arg)))
- return -EFAULT;
-
-@@ -233,9 +223,9 @@
- * be sent at once */
- if (rdwr_arg.nmsgs > 42)
- return -EINVAL;
--
-+
- rdwr_pa = (struct i2c_msg *)
-- kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
-+ kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
- GFP_KERNEL);
-
- if (rdwr_pa == NULL) return -ENOMEM;
-@@ -312,9 +302,9 @@
- (struct i2c_smbus_ioctl_data *) arg,
- sizeof(struct i2c_smbus_ioctl_data)))
- return -EFAULT;
-- if ((data_arg.size != I2C_SMBUS_BYTE) &&
-+ if ((data_arg.size != I2C_SMBUS_BYTE) &&
- (data_arg.size != I2C_SMBUS_QUICK) &&
-- (data_arg.size != I2C_SMBUS_BYTE_DATA) &&
-+ (data_arg.size != I2C_SMBUS_BYTE_DATA) &&
- (data_arg.size != I2C_SMBUS_WORD_DATA) &&
- (data_arg.size != I2C_SMBUS_PROC_CALL) &&
- (data_arg.size != I2C_SMBUS_BLOCK_DATA) &&
-@@ -325,9 +315,9 @@
- #endif
- return -EINVAL;
- }
-- /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1,
-+ /* Note that I2C_SMBUS_READ and I2C_SMBUS_WRITE are 0 and 1,
- so the check is valid if size==I2C_SMBUS_QUICK too. */
-- if ((data_arg.read_write != I2C_SMBUS_READ) &&
-+ if ((data_arg.read_write != I2C_SMBUS_READ) &&
- (data_arg.read_write != I2C_SMBUS_WRITE)) {
- #ifdef DEBUG
- printk(KERN_DEBUG "i2c-dev.o: read_write out of range (%x) in ioctl I2C_SMBUS.\n",
-@@ -339,7 +329,7 @@
- /* Note that command values are always valid! */
-
- if ((data_arg.size == I2C_SMBUS_QUICK) ||
-- ((data_arg.size == I2C_SMBUS_BYTE) &&
-+ ((data_arg.size == I2C_SMBUS_BYTE) &&
- (data_arg.read_write == I2C_SMBUS_WRITE)))
- /* These are special: we do not use data */
- return i2c_smbus_xfer(client->adapter, client->addr,
-@@ -358,13 +348,13 @@
- if ((data_arg.size == I2C_SMBUS_BYTE_DATA) ||
- (data_arg.size == I2C_SMBUS_BYTE))
- datasize = sizeof(data_arg.data->byte);
-- else if ((data_arg.size == I2C_SMBUS_WORD_DATA) ||
-+ else if ((data_arg.size == I2C_SMBUS_WORD_DATA) ||
- (data_arg.size == I2C_SMBUS_PROC_CALL))
- datasize = sizeof(data_arg.data->word);
- else /* size == I2C_SMBUS_BLOCK_DATA */
- datasize = sizeof(data_arg.data->block);
-
-- if ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
-+ if ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
- (data_arg.read_write == I2C_SMBUS_WRITE)) {
- if (copy_from_user(&temp, data_arg.data, datasize))
- return -EFAULT;
-@@ -372,7 +362,7 @@
- res = i2c_smbus_xfer(client->adapter,client->addr,client->flags,
- data_arg.read_write,
- data_arg.command,data_arg.size,&temp);
-- if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
-+ if (! res && ((data_arg.size == I2C_SMBUS_PROC_CALL) ||
- (data_arg.read_write == I2C_SMBUS_READ))) {
- if (copy_to_user(data_arg.data, &temp, datasize))
- return -EFAULT;
-@@ -479,7 +469,7 @@
- return -1;
- }
-
--int __init i2c_dev_init(void)
-+static int __init i2c_dev_init(void)
- {
- int res;
-
-@@ -509,7 +499,7 @@
- return 0;
- }
-
--int i2cdev_cleanup(void)
-+static void i2cdev_cleanup(void)
- {
- int res;
-
-@@ -517,9 +507,9 @@
- if ((res = i2c_del_driver(&i2cdev_driver))) {
- printk("i2c-dev.o: Driver deregistration failed, "
- "module not removed.\n");
-- return res;
-+ return;
- }
-- i2cdev_initialized --;
-+ i2cdev_initialized --;
- }
-
- if (i2cdev_initialized >= 1) {
-@@ -531,30 +521,17 @@
- #endif
- printk("i2c-dev.o: unable to release major %d for i2c bus\n",
- I2C_MAJOR);
-- return res;
-+ return;
- }
- i2cdev_initialized --;
- }
-- return 0;
- }
-
- EXPORT_NO_SYMBOLS;
-
--#ifdef MODULE
--
- MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl> and Simon G. Vogl <simon@tk.uni-linz.ac.at>");
- MODULE_DESCRIPTION("I2C /dev entries driver");
- MODULE_LICENSE("GPL");
-
--int init_module(void)
--{
-- return i2c_dev_init();
--}
--
--int cleanup_module(void)
--{
-- return i2cdev_cleanup();
--}
--
--#endif /* def MODULE */
--
-+module_init(i2c_dev_init);
-+module_exit(i2cdev_cleanup);
---- linux-2.4.25/drivers/i2c/i2c-elektor.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/i2c/i2c-elektor.c 2004-03-31 17:15:09.000000000 +0200
-@@ -181,16 +181,12 @@
-
- static void pcf_isa_inc_use(struct i2c_adapter *adap)
- {
--#ifdef MODULE
- MOD_INC_USE_COUNT;
--#endif
- }
-
- static void pcf_isa_dec_use(struct i2c_adapter *adap)
- {
--#ifdef MODULE
- MOD_DEC_USE_COUNT;
--#endif
- }
-
-
-@@ -219,7 +215,7 @@
- pcf_isa_unreg,
- };
-
--int __init i2c_pcfisa_init(void)
-+static int __init i2c_pcfisa_init(void)
- {
- #ifdef __alpha__
- /* check to see we have memory mapped PCF8584 connected to the
-@@ -289,10 +285,14 @@
- return 0;
- }
-
-+static void i2c_pcfisa_exit(void)
-+{
-+ i2c_pcf_del_bus(&pcf_isa_ops);
-+ pcf_isa_exit();
-+}
-
- EXPORT_NO_SYMBOLS;
-
--#ifdef MODULE
- MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
- MODULE_DESCRIPTION("I2C-Bus adapter routines for PCF8584 ISA bus adapter");
- MODULE_LICENSE("GPL");
-@@ -304,15 +304,5 @@
- MODULE_PARM(mmapped, "i");
- MODULE_PARM(i2c_debug, "i");
-
--int init_module(void)
--{
-- return i2c_pcfisa_init();
--}
--
--void cleanup_module(void)
--{
-- i2c_pcf_del_bus(&pcf_isa_ops);
-- pcf_isa_exit();
--}
--
--#endif
-+module_init(i2c_pcfisa_init);
-+module_exit(i2c_pcfisa_exit);
---- linux-2.4.25/drivers/i2c/i2c-elv.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/i2c/i2c-elv.c 2004-03-31 17:15:09.000000000 +0200
-@@ -75,7 +75,7 @@
- PortData |=2;
- }
- outb(PortData, DATA);
--}
-+}
-
- static int bit_elv_getscl(void *data)
- {
-@@ -90,7 +90,7 @@
- static int bit_elv_init(void)
- {
- if (check_region(base,(base == 0x3bc)? 3 : 8) < 0 ) {
-- return -ENODEV;
-+ return -ENODEV;
- } else {
- /* test for ELV adap. */
- if (inb(base+1) & 0x80) { /* BUSY should be high */
-@@ -131,16 +131,12 @@
-
- static void bit_elv_inc_use(struct i2c_adapter *adap)
- {
--#ifdef MODULE
- MOD_INC_USE_COUNT;
--#endif
- }
-
- static void bit_elv_dec_use(struct i2c_adapter *adap)
- {
--#ifdef MODULE
- MOD_DEC_USE_COUNT;
--#endif
- }
-
- /* ------------------------------------------------------------------------
-@@ -164,10 +160,10 @@
- bit_elv_inc_use,
- bit_elv_dec_use,
- bit_elv_reg,
-- bit_elv_unreg,
-+ bit_elv_unreg,
- };
-
--int __init i2c_bitelv_init(void)
-+static int __init i2c_bitelv_init(void)
- {
- printk(KERN_INFO "i2c-elv.o: i2c ELV parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
- if (base==0) {
-@@ -194,24 +190,19 @@
- }
-
-
-+static void __exit i2c_bitelv_exit(void)
-+{
-+ i2c_bit_del_bus(&bit_elv_ops);
-+ bit_elv_exit();
-+}
-+
- EXPORT_NO_SYMBOLS;
-
--#ifdef MODULE
- MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
- MODULE_DESCRIPTION("I2C-Bus adapter routines for ELV parallel port adapter");
- MODULE_LICENSE("GPL");
-
- MODULE_PARM(base, "i");
-
--int init_module(void)
--{
-- return i2c_bitelv_init();
--}
--
--void cleanup_module(void)
--{
-- i2c_bit_del_bus(&bit_elv_ops);
-- bit_elv_exit();
--}
--
--#endif
-+module_init(i2c_bitelv_init);
-+module_exit(i2c_bitelv_exit);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/i2c/i2c-frodo.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,114 @@
-+
-+/*
-+ * linux/drivers/i2c/i2c-frodo.c
-+ *
-+ * Author: Abraham van der Merwe <abraham@2d3d.co.za>
-+ *
-+ * An I2C adapter driver for the 2d3D, Inc. StrongARM SA-1110
-+ * Development board (Frodo).
-+ *
-+ * This source code is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * version 2 as published by the Free Software Foundation.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/version.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+
-+#include <asm/hardware.h>
-+
-+#include <linux/i2c.h>
-+#include <linux/i2c-algo-bit.h>
-+
-+static void frodo_setsda (void *data,int state)
-+{
-+ if (state)
-+ frodo_cpld_set (FRODO_CPLD_I2C,FRODO_I2C_SDA_OUT);
-+ else
-+ frodo_cpld_clear (FRODO_CPLD_I2C,FRODO_I2C_SDA_OUT);
-+}
-+
-+static void frodo_setscl (void *data,int state)
-+{
-+ if (state)
-+ frodo_cpld_set (FRODO_CPLD_I2C,FRODO_I2C_SCL_OUT);
-+ else
-+ frodo_cpld_clear (FRODO_CPLD_I2C,FRODO_I2C_SCL_OUT);
-+}
-+
-+static int frodo_getsda (void *data)
-+{
-+ return ((frodo_cpld_read (FRODO_CPLD_I2C) & FRODO_I2C_SDA_IN) != 0);
-+}
-+
-+static int frodo_getscl (void *data)
-+{
-+ return ((frodo_cpld_read (FRODO_CPLD_I2C) & FRODO_I2C_SCL_IN) != 0);
-+}
-+
-+static struct i2c_algo_bit_data bit_frodo_data = {
-+ setsda: frodo_setsda,
-+ setscl: frodo_setscl,
-+ getsda: frodo_getsda,
-+ getscl: frodo_getscl,
-+ udelay: 80,
-+ mdelay: 80,
-+ timeout: 100
-+};
-+
-+static int frodo_client_register (struct i2c_client *client)
-+{
-+ return (0);
-+}
-+
-+static int frodo_client_unregister (struct i2c_client *client)
-+{
-+ return (0);
-+}
-+
-+static void frodo_inc_use (struct i2c_adapter *adapter)
-+{
-+ MOD_INC_USE_COUNT;
-+}
-+
-+static void frodo_dec_use (struct i2c_adapter *adapter)
-+{
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static struct i2c_adapter frodo_ops = {
-+ name: "Frodo adapter driver",
-+ id: I2C_HW_B_FRODO,
-+ algo: NULL,
-+ algo_data: &bit_frodo_data,
-+ inc_use: frodo_inc_use,
-+ dec_use: frodo_dec_use,
-+ client_register: frodo_client_register,
-+ client_unregister: frodo_client_unregister
-+};
-+
-+static int __init i2c_frodo_init (void)
-+{
-+ return (i2c_bit_add_bus (&frodo_ops));
-+}
-+
-+EXPORT_NO_SYMBOLS;
-+
-+static void __exit i2c_frodo_exit (void)
-+{
-+ i2c_bit_del_bus (&frodo_ops);
-+}
-+
-+MODULE_AUTHOR ("Abraham van der Merwe <abraham@2d3d.co.za>");
-+MODULE_DESCRIPTION ("I2C-Bus adapter routines for Frodo");
-+MODULE_LICENSE ("GPL");
-+EXPORT_NO_SYMBOLS;
-+
-+module_init (i2c_frodo_init);
-+module_exit (i2c_frodo_exit);
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/i2c/i2c-guide.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,199 @@
-+/************************************************************************************\
-+Copyright : Copyright (C) 1995-2000 Simon G. Vogl
-+ Copyright 2002 IDERs Incorporated
-+File Name : i2c-guide.c
-+Description : this i2c driver uses the GPIO port B pin 0 and pin 1 on the cs89712.
-+Notes : To change the bit rate, change the structure i2c_algo_bit_data
-+ : to 10 10 100
-+Contact : tsong@iders.ca
-+License : This source code is free software; you can redistribute it and/or
-+ modify it under the terms of the GNU General Public License
-+ version 2 as published by the Free Software Foundation.
-+\************************************************************************************/
-+
-+#include <linux/kernel.h>
-+#include <linux/ioport.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/string.h> /* for 2.0 kernels to get NULL */
-+#include <asm/errno.h> /* for 2.0 kernels to get ENODEV */
-+#include <asm/io.h>
-+
-+#include <asm/hardware/cs89712.h> // io operation ep_writel()
-+#include <asm/hardware/clps7111.h> // io operation clps_writel()
-+#include <asm/arch-clps711x/hardware.h> // io operation clps_writel()
-+
-+#include <linux/i2c.h>
-+#include <linux/i2c-algo-bit.h>
-+
-+/* ----- global defines ----------------------------------------------- */
-+
-+#define DEB(x) /* should be reasonable open, close &c. */
-+#define DEB2(x) /* low level debugging - very slow */
-+#define DEBE(x) x /* error messages */
-+ /* Pin Port Inverted name */
-+#define I2C_SDA 0x08 /* port B ctrl pin 3 (inv) */
-+#define I2C_SCL 0x04 /* port B ctrl pin 2 (inv) */
-+
-+#define I2C_SDAIN 0x08 /* use the same pin with output */
-+#define I2C_SCLIN 0x04 /* use the same pin with output */
-+
-+#define I2C_DMASK 0xf7 /* inverse of I2C_SDA */
-+#define I2C_CMASK 0xfb /* inverse of I2c_SCL */
-+
-+#define PORTB_PIN0_SDA_OUTPUT 0x08 /* pin 3 direction of port B output */
-+#define PORTB_PIN0_SDA_INPUT 0xf7 /* pin 3 direction of port B input */
-+
-+#define PORTB_PIN1_SCL_OUTPUT 0x04 /* pin 2 direction of port B output */
-+#define PORTB_PIN1_SCL_INPUT 0xfb /* pin 2 direction of port B input */
-+
-+int base = 0;
-+#define DEFAULT_BASE PBDR
-+
-+/* ----- local functions --------------------------------------------------- */
-+
-+static void bit_guide_setscl(void* data, int state)
-+{
-+ if (state) {
-+ // set port B pin2 input
-+ clps_writeb((clps_readb(PBDDR)) & PORTB_PIN1_SCL_INPUT, PBDDR);
-+ }
-+ else {
-+ // clear
-+ clps_writeb((clps_readb(PBDR)) & I2C_CMASK, PBDR);
-+ // set port B pin2 output
-+ clps_writeb((clps_readb(PBDDR)) | PORTB_PIN1_SCL_OUTPUT, PBDDR);
-+ }
-+}
-+
-+static void bit_guide_setsda(void* data, int state)
-+{
-+ if (state) {
-+ clps_writeb((clps_readb(PBDDR)) & PORTB_PIN0_SDA_INPUT, PBDDR);
-+ // float pin 0 (actually drive high by pull up resistor)
-+ // clps_writeb((clps_readb(PBDR)) | I2C_SDA, PBDR); // set Jan4 ori: eff
-+ // printk("set sda high, state=%i\n",state);
-+ }
-+ else {
-+ // clear
-+ clps_writeb((clps_readb(PBDR)) & I2C_DMASK, PBDR);
-+ // set port B pin 0 output
-+ clps_writeb((clps_readb(PBDDR)) | PORTB_PIN0_SDA_OUTPUT, PBDDR);
-+ }
-+}
-+
-+static int bit_guide_getscl(void *data)
-+{
-+ return ( 0 != ( (clps_readb(PBDR)) & I2C_SCLIN ) );
-+}
-+
-+static int bit_guide_getsda(void *data)
-+{
-+ // set port B pin 0 input Jan4 ori eff
-+ clps_writeb((clps_readb(PBDDR)) & PORTB_PIN0_SDA_INPUT, PBDDR);
-+ return ( 0 != ( (clps_readb(PBDR) ) & I2C_SDAIN ) );
-+}
-+
-+static int bit_guide_init(void)
-+{
-+ bit_guide_setsda((void*)base,1);
-+ bit_guide_setscl((void*)base,1);
-+ return 0;
-+}
-+
-+static int bit_guide_reg(struct i2c_client *client)
-+{
-+ return 0;
-+}
-+
-+static int bit_guide_unreg(struct i2c_client *client)
-+{
-+ return 0;
-+}
-+
-+static void bit_guide_inc_use(struct i2c_adapter *adap)
-+{
-+#ifdef MODULE
-+ MOD_INC_USE_COUNT;
-+#endif
-+}
-+
-+static void bit_guide_dec_use(struct i2c_adapter *adap)
-+{
-+#ifdef MODULE
-+ MOD_DEC_USE_COUNT;
-+#endif
-+}
-+
-+/* ------------------------------------------------------------------------
-+ * Encapsulate the above functions in the correct operations structure.
-+ * This is only done when more than one hardware adapter is supported.
-+ */
-+
-+/* last line (us, ms, timout)
-+ * us dominates the bit rate: 10us means: 100Kbit/sec(25 means 40kbps)
-+ * 10ms not known
-+ * 100ms timeout
-+ */
-+static struct i2c_algo_bit_data bit_guide_data = {
-+ NULL,
-+ bit_guide_setsda,
-+ bit_guide_setscl,
-+ bit_guide_getsda,
-+ bit_guide_getscl,
-+ 50, 10, 100, /* orginal (non-guide) value 10, 10, 100 */
-+};
-+
-+static struct i2c_adapter bit_guide_ops = {
-+ "Guide Port B: PIN2-SCL/PIN3-SDA",
-+ I2C_HW_B_GUIDE,
-+ NULL,
-+ &bit_guide_data,
-+ bit_guide_inc_use,
-+ bit_guide_dec_use,
-+ bit_guide_reg,
-+ bit_guide_unreg,
-+};
-+
-+static int __init i2c_bitguide_init(void)
-+{
-+ printk("i2c-guide.o: Guide i2c port B adapter module.\n");
-+ clps_writeb((clps_readb(PBDDR)) & 0xfd, PBDDR); // set service reuest pb1 as input
-+ if (base==0) {
-+ /* probe some values */
-+ base=DEFAULT_BASE;
-+ bit_guide_data.data=(void*)DEFAULT_BASE;
-+ if (bit_guide_init()==0) {
-+ if(i2c_bit_add_bus(&bit_guide_ops) < 0)
-+ return -ENODEV;
-+ } else {
-+ return -ENODEV;
-+ }
-+ } else {
-+ bit_guide_data.data=(void*)base;
-+ if (bit_guide_init()==0) {
-+ if(i2c_bit_add_bus(&bit_guide_ops) < 0)
-+ return -ENODEV;
-+ } else {
-+ return -ENODEV;
-+ }
-+ }
-+ printk("i2c-guide.o: found device at %#x.\n",base);
-+ return 0;
-+}
-+
-+EXPORT_NO_SYMBOLS;
-+
-+MODULE_AUTHOR("T. C. Song <tsong@iders.ca>");
-+MODULE_DESCRIPTION("I2C-Bus adapter routines for Guide (cs89712) GPIO port B");
-+MODULE_LICENSE("GPL");
-+
-+MODULE_PARM(base, "i");
-+
-+module_init(i2c_bitguide_init);
-+/* for completeness, we should have a module_exit() function, but the
-+ GUIDE requires this to always be loaded. If it is unloaded, the
-+ operation of the GUIDE is undefined.
-+ Nobody has written the i2c_bitguide_exit() routine yet, so it is not included.
-+module_exit(i2c_bitguide_exit);
-+*/
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/i2c/i2c-omaha.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,276 @@
-+/* ------------------------------------------------------------------------- *
-+ Copyright ARM Limited 2002. All rights reserved.
-+
-+ i2c driver for Omaha
-+
-+ Notes:Based on i2c-elv.c
-+
-+ The S3C2400X01 has better support for I2C, but bit oriented operations
-+ are directly supported by the other I2C layers, so we use that method
-+ of performing I2C operations.
-+
-+ Copyright (C) 1995-2000 Simon G. Vogl
-+
-+ 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/module.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/version.h>
-+#include <linux/init.h>
-+#include <asm/irq.h>
-+#include <asm/io.h>
-+#include <asm/uaccess.h>
-+#include <linux/ioport.h>
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+
-+#include <linux/i2c.h>
-+#include <linux/i2c-algo-bit.h>
-+
-+#include <asm/io.h>
-+#include <asm/hardware.h>
-+
-+/* ----- global defines ----------------------------------------------- */
-+#define DEB(x) if (i2c_debug>=1) x;
-+#define DEB2(x) if (i2c_debug>=2) x;
-+#define DEB3(x) if (i2c_debug>=3) x
-+#define DEBE(x) x // error messages
-+#define DEBSTAT(x) if (i2c_debug>=3) x; /* print several statistical values*/
-+#define DEBPROTO(x) if (i2c_debug>=9) { x; }
-+ /* debug the protocol by showing transferred bits */
-+
-+/* Register and bitdefs for Omaha */
-+
-+// Port G control registers
-+static volatile unsigned int pgcon = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_PGCON);
-+static volatile unsigned int pgdat = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_PGDAT);
-+
-+static volatile unsigned int opencr = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_OPENCR);
-+
-+static int base = IO_ADDRESS(PLAT_PERIPHERAL_BASE+OMAHA_PGCON);
-+
-+// Open drain control registers
-+#define OPC_CMD BIT2
-+#define OPC_DAT BIT3
-+
-+// data bits in GPIO Port G data register
-+#define OMAHA_SDA BIT5
-+#define OMAHA_SCL BIT6
-+#define IIC_WP BIT3 // Write Protect for EEPROM
-+
-+// input/out select bits in GPIO G control register
-+#define IIC_BITS (BIT12|BIT10|BIT6);
-+
-+
-+/* ----- local functions ---------------------------------------------- */
-+
-+
-+static void bit_omaha_setscl(void *data, int state)
-+{
-+ unsigned int tmp;
-+
-+ if (state)
-+ {
-+ tmp = __raw_readl(pgdat);
-+ tmp |= OMAHA_SCL;
-+ __raw_writel(tmp,pgdat);
-+ }
-+ else
-+ {
-+ tmp = __raw_readl(pgdat);
-+ tmp &= ~OMAHA_SCL;
-+ __raw_writel(tmp,pgdat);
-+ }
-+}
-+
-+static void bit_omaha_setsda(void *data, int state)
-+{
-+ unsigned int tmp;
-+
-+ // ensure that sda is an output at the moment
-+ tmp = __raw_readl(pgcon);
-+ tmp = tmp | BIT10;
-+ __raw_writel(tmp,pgcon);
-+
-+ if (state)
-+ {
-+ tmp = __raw_readl(pgdat);
-+ tmp |= OMAHA_SDA;
-+ __raw_writel(tmp,pgdat);
-+ }
-+ else
-+ {
-+ tmp = __raw_readl(pgdat);
-+ tmp &= ~OMAHA_SDA;
-+ __raw_writel(tmp,pgdat);
-+ }
-+}
-+
-+static int bit_omaha_getscl(void *data)
-+{
-+ if (__raw_readl(pgdat) & OMAHA_SCL)
-+ return 1;
-+ else
-+ return 0;
-+}
-+
-+static int bit_omaha_getsda(void *data)
-+{
-+ unsigned int tmp;
-+
-+ // ensure that sda is an output at the moment
-+ tmp = __raw_readl(pgcon);
-+ tmp = tmp & ~BIT10;
-+ __raw_writel(tmp,pgcon);
-+
-+ if (__raw_readl(pgdat) & OMAHA_SDA)
-+ return 1;
-+ else
-+ return 0;
-+}
-+
-+static int bit_omaha_init(void)
-+{
-+ // Have we got some mmapped space?
-+ if (request_region(base, 0x100, "i2c (omaha bus adapter)") < 0 )
-+ {
-+ printk("i2c-omaha.o: requested I/O region (0x%08x) is in use.\n", base);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static int bit_omaha_reg(struct i2c_client *client)
-+{
-+ return 0;
-+}
-+
-+
-+static int bit_omaha_unreg(struct i2c_client *client)
-+{
-+ return 0;
-+}
-+
-+static void bit_omaha_inc_use(struct i2c_adapter *adap)
-+{
-+ MOD_INC_USE_COUNT;
-+}
-+
-+static void bit_omaha_dec_use(struct i2c_adapter *adap)
-+{
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+
-+
-+/* ------------------------------------------------------------------------
-+ * Encapsulate the above functions in the correct operations structure.
-+ * This is only done when more than one hardware adapter is supported.
-+ */
-+static struct i2c_algo_bit_data bit_omaha_data = {
-+ NULL,
-+ bit_omaha_setsda,
-+ bit_omaha_setscl,
-+ bit_omaha_getsda,
-+ bit_omaha_getscl,
-+ 10, 10, 20, /* waits, timeout */
-+};
-+
-+static struct i2c_adapter bit_omaha_ops = {
-+ "BIT-Type Omaha I2C adapter",
-+ I2C_HW_B_OMAHA,
-+ NULL,
-+ &bit_omaha_data,
-+ bit_omaha_inc_use,
-+ bit_omaha_dec_use,
-+ bit_omaha_reg,
-+ bit_omaha_unreg,
-+};
-+
-+static int __init i2c_omaha_init (void)
-+{
-+ unsigned int tmp;
-+
-+ printk("i2c-omaha.o: i2c omaha adapter module\n");
-+
-+ if (bit_omaha_init() == 0) {
-+ if(i2c_bit_add_bus(&bit_omaha_ops) < 0)
-+ {
-+ printk("Could not add bus!\n");
-+ return -ENODEV;
-+ }
-+ } else {
-+ printk("Could not pcf_omaha_init\n");
-+ return -ENODEV;
-+ }
-+
-+ // Program Port G bits to output function
-+ tmp = __raw_readl(pgcon);
-+ tmp |= IIC_BITS;
-+ __raw_writel(tmp,pgcon);
-+
-+ // Ensure SDA and SCL are open-drain
-+ tmp = __raw_readl(opencr);
-+ tmp = tmp | OPC_CMD | OPC_DAT;
-+ __raw_writel(tmp,opencr);
-+
-+ bit_omaha_setsda((void*)base,1);
-+ bit_omaha_setscl((void*)base,1);
-+
-+ // Disable WP
-+ tmp = __raw_readl(pgdat);
-+ tmp = tmp & ~IIC_WP;
-+ __raw_writel(tmp,pgdat);
-+
-+ return 0;
-+}
-+
-+static void bit_omaha_exit(void)
-+{
-+ release_region(base , 2);
-+}
-+
-+static void i2c_omaha_exit(void)
-+{
-+
-+ i2c_bit_del_bus(&bit_omaha_ops);
-+
-+ bit_omaha_exit();
-+
-+}
-+
-+EXPORT_NO_SYMBOLS;
-+
-+MODULE_AUTHOR("ARM Limited <support@arm.com>");
-+MODULE_DESCRIPTION("I2C-Bus adapter routines for Omaha");
-+MODULE_LICENSE("GPL");
-+
-+MODULE_PARM(base, "i");
-+MODULE_PARM(irq, "i");
-+MODULE_PARM(clock, "i");
-+MODULE_PARM(own, "i");
-+MODULE_PARM(mmapped, "i");
-+MODULE_PARM(i2c_debug, "i");
-+
-+
-+module_init(i2c_omaha_init);
-+module_exit(i2c_omaha_exit);
-+
-+
---- linux-2.4.25/drivers/i2c/i2c-philips-par.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/i2c/i2c-philips-par.c 2004-03-31 17:15:09.000000000 +0200
-@@ -16,7 +16,7 @@
- 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. */
--/* ------------------------------------------------------------------------- */
-+/* ------------------------------------------------------------------------- */
-
- /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
- Frodo Looijaard <frodol@dds.nl> */
-@@ -72,7 +72,7 @@
-
- static void bit_lp_setscl(void *data, int state)
- {
-- /*be cautious about state of the control register -
-+ /*be cautious about state of the control register -
- touch only the one bit needed*/
- if (state) {
- parport_write_control((struct parport *) data,
-@@ -126,7 +126,7 @@
-
- static int bit_lp_getsda2(void *data)
- {
-- return (parport_read_status((struct parport *) data) &
-+ return (parport_read_status((struct parport *) data) &
- PARPORT_STATUS_BUSY) ? 0 : 1;
- }
-
-@@ -154,7 +154,7 @@
- * Encapsulate the above functions in the correct operations structure.
- * This is only done when more than one hardware adapter is supported.
- */
--
-+
- static struct i2c_algo_bit_data bit_lp_data = {
- NULL,
- bit_lp_setsda,
-@@ -162,7 +162,7 @@
- bit_lp_getsda,
- bit_lp_getscl,
- 80, 80, 100, /* waits, timeout */
--};
-+};
-
- static struct i2c_algo_bit_data bit_lp_data2 = {
- NULL,
-@@ -171,7 +171,7 @@
- bit_lp_getsda2,
- NULL,
- 80, 80, 100, /* waits, timeout */
--};
-+};
-
- static struct i2c_adapter bit_lp_ops = {
- "Philips Parallel port adapter",
-@@ -197,7 +197,7 @@
- printk(KERN_DEBUG "i2c-philips-par.o: attaching to %s\n", port->name);
-
- adapter->pdev = parport_register_device(port, "i2c-philips-par",
-- NULL, NULL, NULL,
-+ NULL, NULL, NULL,
- PARPORT_FLAG_EXCL,
- NULL);
- if (!adapter->pdev) {
-@@ -257,16 +257,16 @@
- NULL
- };
-
--int __init i2c_bitlp_init(void)
-+static int __init i2c_bitlp_init(void)
- {
- printk(KERN_INFO "i2c-philips-par.o: i2c Philips parallel port adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
-
- parport_register_driver(&i2c_driver);
--
-+
- return 0;
- }
-
--void __exit i2c_bitlp_exit(void)
-+static void __exit i2c_bitlp_exit(void)
- {
- parport_unregister_driver(&i2c_driver);
- }
-@@ -279,14 +279,5 @@
-
- MODULE_PARM(type, "i");
-
--#ifdef MODULE
--int init_module(void)
--{
-- return i2c_bitlp_init();
--}
--
--void cleanup_module(void)
--{
-- i2c_bitlp_exit();
--}
--#endif
-+module_init(i2c_bitlp_init);
-+module_exit(i2c_bitlp_exit);
---- linux-2.4.25/drivers/i2c/i2c-velleman.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/i2c/i2c-velleman.c 2004-03-31 17:15:09.000000000 +0200
-@@ -65,7 +65,7 @@
- } else {
- outb(inb(CTRL) | I2C_SCL, CTRL);
- }
--
-+
- }
-
- static void bit_velle_setsda(void *data, int state)
-@@ -75,8 +75,8 @@
- } else {
- outb(inb(CTRL) | I2C_SDA, CTRL);
- }
--
--}
-+
-+}
-
- static int bit_velle_getscl(void *data)
- {
-@@ -95,7 +95,7 @@
- base));
- return -ENODEV;
- } else {
-- request_region(base, (base == 0x3bc)? 3 : 8,
-+ request_region(base, (base == 0x3bc)? 3 : 8,
- "i2c (Vellemann adapter)");
- bit_velle_setsda((void*)base,1);
- bit_velle_setscl((void*)base,1);
-@@ -104,7 +104,7 @@
- }
-
- static void __exit bit_velle_exit(void)
--{
-+{
- release_region( base , (base == 0x3bc)? 3 : 8 );
- }
-
-@@ -121,16 +121,12 @@
-
- static void bit_velle_inc_use(struct i2c_adapter *adap)
- {
--#ifdef MODULE
- MOD_INC_USE_COUNT;
--#endif
- }
-
- static void bit_velle_dec_use(struct i2c_adapter *adap)
- {
--#ifdef MODULE
- MOD_DEC_USE_COUNT;
--#endif
- }
-
- /* ------------------------------------------------------------------------
-@@ -158,7 +154,7 @@
- bit_velle_unreg,
- };
-
--int __init i2c_bitvelle_init(void)
-+static int __init i2c_bitvelle_init(void)
- {
- printk(KERN_INFO "i2c-velleman.o: i2c Velleman K8000 adapter module version %s (%s)\n", I2C_VERSION, I2C_DATE);
- if (base==0) {
-@@ -184,24 +180,19 @@
- return 0;
- }
-
-+static void __exit i2c_bitvelle_exit(void)
-+{
-+ i2c_bit_del_bus(&bit_velle_ops);
-+ bit_velle_exit();
-+}
-+
- EXPORT_NO_SYMBOLS;
-
--#ifdef MODULE
- MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
- MODULE_DESCRIPTION("I2C-Bus adapter routines for Velleman K8000 adapter");
- MODULE_LICENSE("GPL");
-
- MODULE_PARM(base, "i");
-
--int init_module(void)
--{
-- return i2c_bitvelle_init();
--}
--
--void cleanup_module(void)
--{
-- i2c_bit_del_bus(&bit_velle_ops);
-- bit_velle_exit();
--}
--
--#endif
-+module_init(i2c_bitvelle_init);
-+module_exit(i2c_bitvelle_exit);
---- linux-2.4.25/drivers/ide/Config.in~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/ide/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -106,6 +106,9 @@
- define_bool CONFIG_BLK_DEV_IDEDMA $CONFIG_BLK_DEV_IDEDMA_ICS
- dep_bool ' RapIDE interface support' CONFIG_BLK_DEV_IDE_RAPIDE $CONFIG_ARCH_ACORN
- fi
-+ if [ "$CONFIG_ARCH_RISCSTATION" = "y" ]; then
-+ dep_bool ' RiscStation IDE' CONFIG_BLK_DEV_IDE_RISCSTATION $CONFIG_ARCH_RISCSTATION
-+ fi
- if [ "$CONFIG_AMIGA" = "y" ]; then
- dep_bool ' Amiga Gayle IDE interface support' CONFIG_BLK_DEV_GAYLE $CONFIG_AMIGA
- dep_mbool ' Amiga IDE Doubler support (EXPERIMENTAL)' CONFIG_BLK_DEV_IDEDOUBLER $CONFIG_BLK_DEV_GAYLE $CONFIG_EXPERIMENTAL
---- linux-2.4.25/drivers/ide/arm/Makefile~2.4.25-vrs2.patch 2003-06-13 16:51:33.000000000 +0200
-+++ linux-2.4.25/drivers/ide/arm/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -6,6 +6,7 @@
-
- obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o
- obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o
-+obj-$(CONFIG_BLK_DEV_IDE_RISCSTATION) += rstation-ide.o
-
- EXTRA_CFLAGS := -I../
-
---- linux-2.4.25/drivers/ide/arm/icside.c~2.4.25-vrs2.patch 2003-06-13 16:51:33.000000000 +0200
-+++ linux-2.4.25/drivers/ide/arm/icside.c 2004-03-31 17:15:09.000000000 +0200
-@@ -1,7 +1,7 @@
- /*
- * linux/drivers/ide/arm/icside.c
- *
-- * Copyright (c) 1996,1997 Russell King.
-+ * Copyright (c) 1996-2003 Russell King.
- *
- * Changelog:
- * 08-Jun-1996 RMK Created
-@@ -26,24 +26,6 @@
- #include <asm/ecard.h>
- #include <asm/io.h>
-
--#include "ide-noise.h"
--
--/*
-- * FIXME: We want to drop the the MACRO CRAP!
-- *
-- * ec->iops->in{b/w/l}
-- * ec->iops->in{b/w/l}_p
-- * ec->iops->out{b/w/l}
-- * ec->iops->out{b/w/l}_p
-- *
-- * the new core supports clean MMIO calls and other goodies
-- */
--
--/*
-- * Maximum number of interfaces per card
-- */
--#define MAX_IFS 2
--
- #define ICS_IDENT_OFFSET 0x8a0
-
- #define ICS_ARCIN_V5_INTRSTAT 0x000
-@@ -86,17 +68,20 @@
- ICS_ARCIN_V6_IDESTEPPING
- };
-
--static const card_ids icside_cids[] = {
-- { MANU_ICS, PROD_ICS_IDE },
-- { MANU_ICS2, PROD_ICS2_IDE },
-- { 0xffff, 0xffff }
-+struct icside_state {
-+ unsigned int channel;
-+ unsigned int enabled;
-+ unsigned long irq_port;
-+ unsigned long slot_port;
-+ unsigned int type;
-+ ide_hwif_t *hwif[2];
- };
-
--typedef enum {
-- ics_if_unknown,
-- ics_if_arcin_v5,
-- ics_if_arcin_v6
--} iftype_t;
-+#define ICS_TYPE_A3IN 0
-+#define ICS_TYPE_A3USER 1
-+#define ICS_TYPE_V6 3
-+#define ICS_TYPE_V5 15
-+#define ICS_TYPE_NOTYPE ((unsigned int)-1)
-
- /* ---------------- Version 5 PCB Support Functions --------------------- */
- /* Prototype: icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
-@@ -104,8 +89,10 @@
- */
- static void icside_irqenable_arcin_v5 (struct expansion_card *ec, int irqnr)
- {
-- unsigned int memc_port = (unsigned int)ec->irq_data;
-- outb(0, memc_port + ICS_ARCIN_V5_INTROFFSET);
-+ struct icside_state *state = ec->irq_data;
-+ unsigned int base = state->irq_port;
-+
-+ outb(0, base + ICS_ARCIN_V5_INTROFFSET);
- }
-
- /* Prototype: icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
-@@ -113,17 +100,15 @@
- */
- static void icside_irqdisable_arcin_v5 (struct expansion_card *ec, int irqnr)
- {
-- unsigned int memc_port = (unsigned int)ec->irq_data;
-- inb(memc_port + ICS_ARCIN_V5_INTROFFSET);
-+ struct icside_state *state = ec->irq_data;
-+ unsigned int base = state->irq_port;
-+
-+ inb(base + ICS_ARCIN_V5_INTROFFSET);
- }
-
- static const expansioncard_ops_t icside_ops_arcin_v5 = {
-- icside_irqenable_arcin_v5,
-- icside_irqdisable_arcin_v5,
-- NULL,
-- NULL,
-- NULL,
-- NULL
-+ .irqenable = icside_irqenable_arcin_v5,
-+ .irqdisable = icside_irqdisable_arcin_v5,
- };
-
-
-@@ -133,10 +118,21 @@
- */
- static void icside_irqenable_arcin_v6 (struct expansion_card *ec, int irqnr)
- {
-- unsigned int ide_base_port = (unsigned int)ec->irq_data;
-+ struct icside_state *state = ec->irq_data;
-+ unsigned int base = state->irq_port;
-
-- outb(0, ide_base_port + ICS_ARCIN_V6_INTROFFSET_1);
-- outb(0, ide_base_port + ICS_ARCIN_V6_INTROFFSET_2);
-+ state->enabled = 1;
-+
-+ switch (state->channel) {
-+ case 0:
-+ outb(0, base + ICS_ARCIN_V6_INTROFFSET_1);
-+ inb(base + ICS_ARCIN_V6_INTROFFSET_2);
-+ break;
-+ case 1:
-+ outb(0, base + ICS_ARCIN_V6_INTROFFSET_2);
-+ inb(base + ICS_ARCIN_V6_INTROFFSET_1);
-+ break;
-+ }
- }
-
- /* Prototype: icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
-@@ -144,10 +140,12 @@
- */
- static void icside_irqdisable_arcin_v6 (struct expansion_card *ec, int irqnr)
- {
-- unsigned int ide_base_port = (unsigned int)ec->irq_data;
-+ struct icside_state *state = ec->irq_data;
-
-- inb(ide_base_port + ICS_ARCIN_V6_INTROFFSET_1);
-- inb(ide_base_port + ICS_ARCIN_V6_INTROFFSET_2);
-+ state->enabled = 0;
-+
-+ inb (state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
-+ inb (state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
- }
-
- /* Prototype: icside_irqprobe(struct expansion_card *ec)
-@@ -155,70 +153,49 @@
- */
- static int icside_irqpending_arcin_v6(struct expansion_card *ec)
- {
-- unsigned int ide_base_port = (unsigned int)ec->irq_data;
-+ struct icside_state *state = ec->irq_data;
-
-- return inb(ide_base_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 ||
-- inb(ide_base_port + ICS_ARCIN_V6_INTRSTAT_2) & 1;
-+ return inb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_1) & 1 ||
-+ inb(state->irq_port + ICS_ARCIN_V6_INTRSTAT_2) & 1;
- }
-
- static const expansioncard_ops_t icside_ops_arcin_v6 = {
-- icside_irqenable_arcin_v6,
-- icside_irqdisable_arcin_v6,
-- icside_irqpending_arcin_v6,
-- NULL,
-- NULL,
-- NULL
-+ .irqenable = icside_irqenable_arcin_v6,
-+ .irqdisable = icside_irqdisable_arcin_v6,
-+ .irqpending = icside_irqpending_arcin_v6,
- };
-
--/* Prototype: icside_identifyif (struct expansion_card *ec)
-- * Purpose : identify IDE interface type
-- * Notes : checks the description string
-+/*
-+ * Handle routing of interrupts. This is called before
-+ * we write the command to the drive.
- */
--static iftype_t __init icside_identifyif (struct expansion_card *ec)
-+static void icside_maskproc(ide_drive_t *drive, int mask)
- {
-- unsigned int addr;
-- iftype_t iftype;
-- int id = 0;
--
-- iftype = ics_if_unknown;
--
-- addr = ecard_address (ec, ECARD_IOC, ECARD_FAST) + ICS_IDENT_OFFSET;
--
-- id = inb(addr) & 1;
-- id |= (inb(addr + 1) & 1) << 1;
-- id |= (inb(addr + 2) & 1) << 2;
-- id |= (inb(addr + 3) & 1) << 3;
--
-- switch (id) {
-- case 0: /* A3IN */
-- printk("icside: A3IN unsupported\n");
-- break;
--
-- case 1: /* A3USER */
-- printk("icside: A3USER unsupported\n");
-- break;
-+ ide_hwif_t *hwif = HWIF(drive);
-+ struct icside_state *state = hwif->hwif_data;
-+ unsigned long flags;
-
-- case 3: /* ARCIN V6 */
-- printk(KERN_DEBUG "icside: detected ARCIN V6 in slot %d\n", ec->slot_no);
-- iftype = ics_if_arcin_v6;
-- break;
-+ local_irq_save(flags);
-
-- case 15:/* ARCIN V5 (no id) */
-- printk(KERN_DEBUG "icside: detected ARCIN V5 in slot %d\n", ec->slot_no);
-- iftype = ics_if_arcin_v5;
-- break;
-+ state->channel = hwif->channel;
-
-- default:/* we don't know - complain very loudly */
-- printk("icside: ***********************************\n");
-- printk("icside: *** UNKNOWN ICS INTERFACE id=%d ***\n", id);
-- printk("icside: ***********************************\n");
-- printk("icside: please report this to linux@arm.linux.org.uk\n");
-- printk("icside: defaulting to ARCIN V5\n");
-- iftype = ics_if_arcin_v5;
-- break;
-+ if (state->enabled && !mask) {
-+ switch (hwif->channel) {
-+ case 0:
-+ outb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
-+ inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
-+ break;
-+ case 1:
-+ outb(0, state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
-+ inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
-+ break;
-+ }
-+ } else {
-+ inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
-+ inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
- }
-
-- return iftype;
-+ local_irq_restore(flags);
- }
-
- #ifdef CONFIG_BLK_DEV_IDEDMA_ICS
-@@ -234,125 +211,138 @@
- #define NR_ENTRIES 256
- #define TABLE_SIZE (NR_ENTRIES * 8)
-
--static int ide_build_sglist(ide_hwif_t *hwif, struct request *rq)
-+static void ide_build_sglist(ide_drive_t *drive, struct request *rq)
- {
-- struct buffer_head *bh;
-+ ide_hwif_t *hwif = HWIF(drive);
- struct scatterlist *sg = hwif->sg_table;
-+ struct buffer_head *bh;
- int nents = 0;
-
-- if (rq->cmd == READ)
-- hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
-- else
-- hwif->sg_dma_direction = PCI_DMA_TODEVICE;
-- bh = rq->bh;
-- do {
-- unsigned char *virt_addr = bh->b_data;
-- unsigned int size = bh->b_size;
-+ BUG_ON(hwif->sg_dma_active);
-
-- while ((bh = bh->b_reqnext) != NULL) {
-- if ((virt_addr + size) != (unsigned char *)bh->b_data)
-- break;
-- size += bh->b_size;
-- }
-- memset(&sg[nents], 0, sizeof(*sg));
-- sg[nents].address = virt_addr;
-- sg[nents].length = size;
-- nents++;
-- } while (bh != NULL);
-+ if (rq->cmd == IDE_DRIVE_TASKFILE) {
-+ ide_task_t *args = rq->special;
-
-- return pci_map_sg(NULL, sg, nents, hwif->sg_dma_direction);
--}
-+ if (args->command_type == IDE_DRIVE_TASK_RAW_WRITE)
-+ hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
-+ else
-+ hwif->sg_dma_direction = PCI_DMA_TODEVICE;
-
--static int
--icside_build_dmatable(ide_drive_t *drive, int ddir)
--{
-- return HWIF(drive)->sg_nents = ide_build_sglist(HWIF(drive), HWGROUP(drive)->rq, ddir);
--}
-+ memset(sg, 0, sizeof(*sg));
-+ sg->address = rq->buffer;
-+ sg->length = rq->nr_sectors * SECTOR_SIZE;
-+ nents = 1;
-+ } else {
-+ if (rq->cmd == READ)
-+ hwif->sg_dma_direction = PCI_DMA_FROMDEVICE;
-+ else
-+ hwif->sg_dma_direction = PCI_DMA_TODEVICE;
-
--/* Teardown mappings after DMA has completed. */
--static void icside_destroy_dmatable(ide_drive_t *drive)
--{
-- struct scatterlist *sg = HWIF(drive)->sg_table;
-- int nents = HWIF(drive)->sg_nents;
-+ bh = rq->bh;
-+ do {
-+ unsigned long lastend;
-
-- pci_unmap_sg(NULL, sg, nents, HWIF(drive)->sg_dma_direction);
-+ memset(sg, 0, sizeof(*sg));
-+ sg->page = bh->b_page;
-+ lastend = bh_phys(bh);
-+
-+ do {
-+ lastend += bh->b_size;
-+ sg->length += bh->b_size;
-+
-+ bh = bh->b_reqnext;
-+ if (bh == NULL)
-+ break;
-+ } while (lastend == bh_phys(bh));
-+
-+ sg++;
-+ nents++;
-+ } while (bh != NULL);
-+ }
-+
-+ nents = pci_map_sg(NULL, sg, nents, hwif->sg_dma_direction);
-+
-+ hwif->sg_nents = nents;
- }
-
--static int
--icside_config_if(ide_drive_t *drive, int xfer_mode)
-+
-+/*
-+ * Configure the IOMD to give the appropriate timings for the transfer
-+ * mode being requested. We take the advice of the ATA standards, and
-+ * calculate the cycle time based on the transfer mode, and the EIDE
-+ * MW DMA specs that the drive provides in the IDENTIFY command.
-+ *
-+ * We have the following IOMD DMA modes to choose from:
-+ *
-+ * Type Active Recovery Cycle
-+ * A 250 (250) 312 (550) 562 (800)
-+ * B 187 250 437
-+ * C 125 (125) 125 (375) 250 (500)
-+ * D 62 125 187
-+ *
-+ * (figures in brackets are actual measured timings)
-+ *
-+ * However, we also need to take care of the read/write active and
-+ * recovery timings:
-+ *
-+ * Read Write
-+ * Mode Active -- Recovery -- Cycle IOMD type
-+ * MW0 215 50 215 480 A
-+ * MW1 80 50 50 150 C
-+ * MW2 70 25 25 120 C
-+ */
-+static int icside_set_speed(ide_drive_t *drive, u8 xfer_mode)
- {
-- int func = ide_dma_off;
-+ int on = 0, cycle_time = 0, use_dma_info = 0;
-+
-+ /*
-+ * Limit the transfer speed to MW_DMA_2.
-+ */
-+ if (xfer_mode > XFER_MW_DMA_2)
-+ xfer_mode = XFER_MW_DMA_2;
-
- switch (xfer_mode) {
- case XFER_MW_DMA_2:
-- /*
-- * The cycle time is limited to 250ns by the r/w
-- * pulse width (90ns), however we should still
-- * have a maximum burst transfer rate of 8MB/s.
-- */
-- drive->drive_data = 250;
-+ cycle_time = 250;
-+ use_dma_info = 1;
- break;
-
- case XFER_MW_DMA_1:
-- drive->drive_data = 250;
-+ cycle_time = 250;
-+ use_dma_info = 1;
- break;
-
- case XFER_MW_DMA_0:
-- drive->drive_data = 480;
-+ cycle_time = 480;
- break;
-
-- default:
-- drive->drive_data = 0;
-+ case XFER_SW_DMA_2:
-+ case XFER_SW_DMA_1:
-+ case XFER_SW_DMA_0:
-+ cycle_time = 480;
- break;
- }
-
-- if (!drive->init_speed)
-- drive->init_speed = (u8) xfer_mode;
-+ /*
-+ * If we're going to be doing MW_DMA_1 or MW_DMA_2, we should
-+ * take care to note the values in the ID...
-+ */
-+ if (use_dma_info && drive->id->eide_dma_time > cycle_time)
-+ cycle_time = drive->id->eide_dma_time;
-
-- if (drive->drive_data &&
-- ide_config_drive_speed(drive, (u8) xfer_mode) == 0)
-- func = ide_dma_on;
-+ drive->drive_data = cycle_time;
-+
-+ if (cycle_time && ide_config_drive_speed(drive, xfer_mode) == 0)
-+ on = 1;
- else
- drive->drive_data = 480;
-
- printk("%s: %s selected (peak %dMB/s)\n", drive->name,
- ide_xfer_verbose(xfer_mode), 2000 / drive->drive_data);
-
-- drive->current_speed = (u8) xfer_mode;
--
-- return func;
--}
--
--static int
--icside_set_speed(ide_drive_t *drive, u8 speed)
--{
-- return icside_config_if(drive, speed);
--}
--
--/*
-- * dma_intr() is the handler for disk read/write DMA interrupts
-- */
--static ide_startstop_t icside_dmaintr(ide_drive_t *drive)
--{
-- u8 dma_stat = HWIF(drive)->ide_dma_end(drive);
-- /* get drive status */
-- u8 stat = HWIF(drive)->INB(IDE_STATUS_REG);
-- int i;
-+ drive->current_speed = xfer_mode;
-
-- if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) {
-- if (!dma_stat) {
-- struct request *rq = HWGROUP(drive)->rq;
-- rq = HWGROUP(drive)->rq;
-- for (i = rq->nr_sectors; i > 0;) {
-- i -= rq->current_nr_sectors;
-- DRIVER(drive)->end_request(drive, 1);
-- }
-- return ide_stopped;
-- }
-- printk("%s: dma_intr: bad DMA status (dma_stat=%x)\n",
-- drive->name, dma_stat);
-- }
-- return DRIVER(drive)->error(drive, "dma_intr", stat);
-+ return on;
- }
-
- /*
-@@ -361,19 +351,19 @@
- * This should be defined in one place only.
- */
- struct drive_list_entry {
-- char * id_model;
-- char * id_firmware;
-+ const char * id_model;
-+ const char * id_firmware;
- };
-
--static struct drive_list_entry drive_whitelist [] = {
-+static const struct drive_list_entry drive_whitelist [] = {
- { "Micropolis 2112A", "ALL" },
- { "CONNER CTMA 4000", "ALL" },
- { "CONNER CTT8000-A", "ALL" },
- { "ST34342A", "ALL" },
-- { NULL, 0 }
-+ { NULL, NULL }
- };
-
--static struct drive_list_entry drive_blacklist [] = {
-+static const struct drive_list_entry drive_blacklist [] = {
- { "WDC AC11000H", "ALL" },
- { "WDC AC22100H", "ALL" },
- { "WDC AC32500H", "ALL" },
-@@ -407,10 +397,11 @@
- { "PLEXTOR CD-R PX-W8432T", "ALL" },
- { "ATAPI CD-ROM DRIVE 40X MAXIMUM", "ALL" },
- { "_NEC DV5800A", "ALL" },
-- { NULL, 0 }
-+ { NULL, NULL }
- };
-
--static int in_drive_list(struct hd_driveid *id, struct drive_list_entry * drive_table)
-+static int
-+in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table)
- {
- for ( ; drive_table->id_model ; drive_table++)
- if ((!strcmp(drive_table->id_model, id->model)) &&
-@@ -420,41 +411,52 @@
- return 0;
- }
-
--/*
-- * For both Blacklisted and Whitelisted drives.
-- * This is setup to be called as an extern for future support
-- * to other special driver code.
-- */
--int check_drive_good_lists (ide_drive_t *drive)
-+static int icside_dma_host_off(ide_drive_t *drive)
- {
-- struct hd_driveid *id = drive->id;
-- return in_drive_list(id, drive_whitelist);
-+ return 0;
- }
-
--int check_drive_bad_lists (ide_drive_t *drive)
-+static int icside_dma_off_quietly(ide_drive_t *drive)
- {
-- struct hd_driveid *id = drive->id;
-- int blacklist = in_drive_list(id, drive_blacklist);
-- if (blacklist)
-- printk("%s: Disabling DMA for %s\n", drive->name, id->model);
-- return(blacklist);
-+ drive->using_dma = 0;
-+ return icside_dma_host_off(drive);
- }
-
--int icside_dma_check(ide_drive_t *drive)
-+static int icside_dma_off(ide_drive_t *drive)
-+{
-+ printk("%s: DMA disabled\n", drive->name);
-+ return icside_dma_off_quietly(drive);
-+}
-+
-+static int icside_dma_host_on(ide_drive_t *drive)
-+{
-+ return 0;
-+}
-+
-+static int icside_dma_on(ide_drive_t *drive)
-+{
-+ drive->using_dma = 1;
-+ return icside_dma_host_on(drive);
-+}
-+
-+static int icside_dma_check(ide_drive_t *drive)
- {
- struct hd_driveid *id = drive->id;
- ide_hwif_t *hwif = HWIF(drive);
-- int autodma = hwif->autodma;
- int xfer_mode = XFER_PIO_2;
-+ int on;
-
-- if (!id || !(id->capability & 1) || !autodma)
-- return hwif->ide_dma_off_quietly(drive);
-+ if (!id || !(id->capability & 1) || !hwif->autodma)
-+ goto out;
-
- /*
- * Consult the list of known "bad" drives
- */
-- if (check_drive_bad_lists(drive))
-- return hwif->ide_dma_off(drive);
-+ if (in_drive_list(id, drive_blacklist)) {
-+ printk("%s: Disabling DMA for %s (blacklisted)\n",
-+ drive->name, id->model);
-+ goto out;
-+ }
-
- /*
- * Enable DMA on any drive that has multiword DMA
-@@ -473,192 +475,241 @@
- /*
- * Consult the list of known "good" drives
- */
-- if (check_drive_good_lists(drive)) {
-+ if (in_drive_list(id, drive_whitelist)) {
- if (id->eide_dma_time > 150)
- goto out;
- xfer_mode = XFER_MW_DMA_1;
- }
-
- out:
-- if (icside_config_if(drive, xfer_mode))
-- return hwif->ide_dma_on(drive);
-- return hwif->ide_dma_off(drive);
--}
-+ on = icside_set_speed(drive, xfer_mode);
-
--int icside_dma_verbose(ide_drive_t *drive)
--{
-- printk(", DMA");
-- return 1;
-+ if (on)
-+ return icside_dma_on(drive);
-+ else
-+ return icside_dma_off(drive);
- }
-
--int icside_dma_test_irq(ide_drive_t *drive)
-+static int icside_dma_end(ide_drive_t *drive)
- {
- ide_hwif_t *hwif = HWIF(drive);
-- return inb((unsigned long)hwif->hw.priv) & 1;
--}
-
--int icside_dma_host_off(ide_drive_t *drive)
--{
-- return 0;
--}
-+ drive->waiting_for_dma = 0;
-
--int icside_dma_off_quietly(ide_drive_t *drive)
--{
-- drive->using_dma = 0;
-- return icside_dma_host_off(drive);
--}
-+ disable_dma(hwif->hw.dma);
-
--int icside_dma_off(ide_drive_t *drive)
--{
-- printk("%s: DMA disabled\n", drive->name);
-- return icside_dma_off_quietly(drive);
--}
-+ /* Teardown mappings after DMA has completed. */
-+ pci_unmap_sg(NULL, hwif->sg_table, hwif->sg_nents,
-+ hwif->sg_dma_direction);
-
--int icside_dma_host_on(ide_drive_t *drive)
--{
-- return 0;
--}
-+ hwif->sg_dma_active = 0;
-
--int icside_dma_on(ide_drive_t *drive)
--{
-- drive->using_dma = 1;
-- return icside_dma_host_on(drive);
-+ return get_dma_residue(hwif->hw.dma) != 0;
- }
-
--int icside_dma_begin(ide_drive_t *drive)
-+static int icside_dma_begin(ide_drive_t *drive)
- {
- ide_hwif_t *hwif = HWIF(drive);
-
-+ /* We can not enable DMA on both channels simultaneously. */
-+ BUG_ON(dma_channel_active(hwif->hw.dma));
- enable_dma(hwif->hw.dma);
- return 0;
- }
-
--int icside_dma_end(ide_drive_t *drive)
-+static int icside_dma_count(ide_drive_t *drive)
- {
-- ide_hwif_t *hwif = HWIF(drive);
--
-- drive->waiting_for_dma = 0;
-- disable_dma(hwif->hw.dma);
-- icside_destroy_dmatable(drive);
-- return get_dma_residue(hwif->hw.dma) != 0;
-+ return icside_dma_begin(drive);
- }
-
--int icside_dma_count (ide_drive_t *drive)
-+/*
-+ * dma_intr() is the handler for disk read/write DMA interrupts
-+ */
-+static ide_startstop_t icside_dmaintr(ide_drive_t *drive)
- {
-- return icside_dma_begin(drive);
-+ unsigned int stat;
-+ int dma_stat;
-+
-+ dma_stat = icside_dma_end(drive);
-+ stat = HWIF(drive)->INB(IDE_STATUS_REG);
-+ if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | DRQ_STAT)) {
-+ if (!dma_stat) {
-+ struct request *rq = HWGROUP(drive)->rq;
-+ int i;
-+
-+ for (i = rq->nr_sectors; i > 0; ) {
-+ i -= rq->current_nr_sectors;
-+ DRIVER(drive)->end_request(drive, 1);
-+ }
-+
-+ return ide_stopped;
-+ }
-+ printk(KERN_ERR "%s: bad DMA status (dma_stat=%x)\n",
-+ drive->name, dma_stat);
-+ }
-+
-+ return DRIVER(drive)->error(drive, __FUNCTION__, stat);
- }
-
--int icside_dma_read(ide_drive_t *drive)
-+static int
-+icside_dma_common(ide_drive_t *drive, struct request *rq,
-+ unsigned int dma_mode)
- {
-- ide_hwif_t *hwif = HWIF(drive);
--// ide_task_t *args = HWGROUP(drive)->rq->special;
-- int count = 0;
-- u8 lba48 = (drive->addressing == 1) ? 1 : 0;
-- task_ioreg_t command = WIN_NOP;
-+ ide_hwif_t *hwif = HWIF(drive);
-
-- count = icside_build_dmatable(drive, PCI_DMA_FROMDEVICE);
-- if (!count)
-- return 1;
-- disable_dma(hwif->hw.dma);
-+ /*
-+ * We can not enable DMA on both channels.
-+ */
-+ BUG_ON(hwif->sg_dma_active);
-+ BUG_ON(dma_channel_active(hwif->hw.dma));
-
-- /* Route the DMA signals to
-- * to the correct interface.
-+ ide_build_sglist(drive, rq);
-+
-+ /*
-+ * Ensure that we have the right interrupt routed.
- */
-- HWIF(drive)->OUTB(hwif->select_data, hwif->config_data);
-+ icside_maskproc(drive, 0);
-
-- /* Select the correct timing
-- * for this drive
-+ /*
-+ * Route the DMA signals to the correct interface.
-+ */
-+ outb(hwif->select_data, hwif->config_data);
-+
-+ /*
-+ * Select the correct timing for this drive.
- */
- set_dma_speed(hwif->hw.dma, drive->drive_data);
-
-- set_dma_sg(hwif->hw.dma, HWIF(drive)->sg_table, count);
-- set_dma_mode(hwif->hw.dma, DMA_MODE_READ);
-+ /*
-+ * Tell the DMA engine about the SG table and
-+ * data direction.
-+ */
-+ set_dma_sg(hwif->hw.dma, hwif->sg_table, hwif->sg_nents);
-+ set_dma_mode(hwif->hw.dma, dma_mode);
-+
-+ return 0;
-+}
-+
-+static int icside_dma_read(ide_drive_t *drive)
-+{
-+ struct request *rq = HWGROUP(drive)->rq;
-+ task_ioreg_t cmd;
-+
-+ if (icside_dma_common(drive, rq, DMA_MODE_READ))
-+ return 1;
-
- drive->waiting_for_dma = 1;
-+
- if (drive->media != ide_disk)
- return 0;
-
-- if (HWGROUP(drive)->handler != NULL) /* paranoia check */
-- BUG();
-- ide_set_handler(drive, &icside_dmaintr, WAIT_CMD, NULL);
- /*
- * FIX ME to use only ACB ide_task_t args Struct
- */
- #if 0
- {
-- ide_task_t *args = HWGROUP(drive)->rq->special;
-- command = args->tfRegister[IDE_COMMAND_OFFSET];
-+ ide_task_t *args = rq->special;
-+ cmd = args->tfRegister[IDE_COMMAND_OFFSET];
- }
- #else
-- command = (lba48) ? WIN_READDMA_EXT : WIN_READDMA;
-- if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) {
-- ide_task_t *args = HWGROUP(drive)->rq->special;
-- command = args->tfRegister[IDE_COMMAND_OFFSET];
-+ if (rq->cmd == IDE_DRIVE_TASKFILE) {
-+ ide_task_t *args = rq->special;
-+ cmd = args->tfRegister[IDE_COMMAND_OFFSET];
-+ } else if (drive->addressing == 1) {
-+ cmd = WIN_READDMA_EXT;
-+ } else {
-+ cmd = WIN_READDMA;
- }
- #endif
-- /* issue cmd to drive */
-- HWIF(drive)->OUTB(command, IDE_COMMAND_REG);
-
-- return icside_dma_count(drive);
-+ ide_execute_command(drive, cmd, icside_dmaintr, 2*WAIT_CMD, NULL);
-+
-+ return icside_dma_begin(drive);
- }
-
--int icside_dma_write(ide_drive_t *drive)
-+static int icside_dma_write(ide_drive_t *drive)
- {
-- ide_hwif_t *hwif = HWIF(drive);
--// ide_task_t *args = HWGROUP(drive)->rq->special;
-- int count = 0;
-- u8 lba48 = (drive->addressing == 1) ? 1 : 0;
-- task_ioreg_t command = WIN_NOP;
-+ struct request *rq = HWGROUP(drive)->rq;
-+ task_ioreg_t cmd;
-
-- count = icside_build_dmatable(drive, PCI_DMA_TODEVICE);
-- if (!count)
-+ if (icside_dma_common(drive, rq, DMA_MODE_WRITE))
- return 1;
-- disable_dma(hwif->hw.dma);
--
-- /* Route the DMA signals to
-- * to the correct interface.
-- */
-- HWIF(drive)->OUTB(hwif->select_data, hwif->config_data);
--
-- /* Select the correct timing
-- * for this drive
-- */
-- set_dma_speed(hwif->hw.dma, drive->drive_data);
--
-- set_dma_sg(hwif->hw.dma, HWIF(drive)->sg_table, count);
-- set_dma_mode(hwif->hw.dma, DMA_MODE_WRITE);
-
- drive->waiting_for_dma = 1;
-+
- if (drive->media != ide_disk)
- return 0;
-
-- if (HWGROUP(drive)->handler != NULL)
-- BUG();
-- ide_set_handler(drive, &icside_dmaintr, WAIT_CMD, NULL);
- /*
- * FIX ME to use only ACB ide_task_t args Struct
- */
- #if 0
- {
-- ide_task_t *args = HWGROUP(drive)->rq->special;
-- command = args->tfRegister[IDE_COMMAND_OFFSET];
-+ ide_task_t *args = rq->special;
-+ cmd = args->tfRegister[IDE_COMMAND_OFFSET];
- }
- #else
-- command = (lba48) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA;
-- if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) {
-- ide_task_t *args = HWGROUP(drive)->rq->special;
-- command = args->tfRegister[IDE_COMMAND_OFFSET];
-+ if (rq->cmd == IDE_DRIVE_TASKFILE) {
-+ ide_task_t *args = rq->special;
-+ cmd = args->tfRegister[IDE_COMMAND_OFFSET];
-+ } else if (drive->addressing == 1) {
-+ cmd = WIN_WRITEDMA_EXT;
-+ } else {
-+ cmd = WIN_WRITEDMA;
- }
- #endif
-- /* issue cmd to drive */
-- HWIF(drive)->OUTB(command, IDE_COMMAND_REG);
-
-- return icside_dma_count(drive);
-+ ide_execute_command(drive, cmd, icside_dmaintr, 2*WAIT_CMD, NULL);
-+
-+ return icside_dma_begin(drive);
- }
-
--static int
--icside_setup_dma(ide_hwif_t *hwif, int autodma)
-+static int icside_dma_test_irq(ide_drive_t *drive)
-+{
-+ ide_hwif_t *hwif = HWIF(drive);
-+ struct icside_state *state = hwif->hwif_data;
-+
-+ return inb(state->irq_port +
-+ (hwif->channel ?
-+ ICS_ARCIN_V6_INTRSTAT_2 :
-+ ICS_ARCIN_V6_INTRSTAT_1)) & 1;
-+}
-+
-+static int icside_dma_verbose(ide_drive_t *drive)
-+{
-+ printk(", %s (peak %dMB/s)",
-+ ide_xfer_verbose(drive->current_speed),
-+ 2000 / drive->drive_data);
-+ return 1;
-+}
-+
-+static int icside_dma_timeout(ide_drive_t *drive)
- {
-+ printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name);
-+
-+ if (icside_dma_test_irq(drive))
-+ return 0;
-+
-+ ide_dump_status(drive, "DMA timeout",
-+ HWIF(drive)->INB(IDE_STATUS_REG));
-+
-+ return icside_dma_end(drive);
-+}
-+
-+static int icside_dma_lostirq(ide_drive_t *drive)
-+{
-+ printk(KERN_ERR "%s: IRQ lost\n", drive->name);
-+ return 1;
-+}
-+
-+static int icside_dma_init(ide_hwif_t *hwif)
-+{
-+ int autodma = 0;
-+
-+#ifdef CONFIG_IDEDMA_ICS_AUTO
-+ autodma = 1;
-+#endif
-+
- printk(" %s: SG-DMA", hwif->name);
-
- hwif->sg_table = kmalloc(sizeof(struct scatterlist) * NR_ENTRIES,
-@@ -666,40 +717,53 @@
- if (!hwif->sg_table)
- goto failed;
-
-- hwif->dmatable_cpu = NULL;
-- hwif->dmatable_dma = 0;
-- hwif->speedproc = icside_set_speed;
-- hwif->autodma = autodma;
-+ hwif->atapi_dma = 1;
-+ hwif->mwdma_mask = 7; /* MW0..2 */
-+ hwif->swdma_mask = 7; /* SW0..2 */
-
-- hwif->ide_dma_check = icside_dma_check;
-- hwif->ide_dma_host_off = icside_dma_host_off;
-+ hwif->dmatable_cpu = NULL;
-+ hwif->dmatable_dma = 0;
-+ hwif->speedproc = icside_set_speed;
-+ hwif->autodma = autodma;
-+
-+ hwif->ide_dma_check = icside_dma_check;
-+ hwif->ide_dma_host_off = icside_dma_host_off;
- hwif->ide_dma_off_quietly = icside_dma_off_quietly;
-- hwif->ide_dma_off = icside_dma_off;
-- hwif->ide_dma_host_on = icside_dma_host_on;
-- hwif->ide_dma_on = icside_dma_on;
-- hwif->ide_dma_read = icside_dma_read;
-- hwif->ide_dma_write = icside_dma_write;
-- hwif->ide_dma_count = icside_dma_count;
-- hwif->ide_dma_begin = icside_dma_begin;
-- hwif->ide_dma_end = icside_dma_end;
-- hwif->ide_dma_verbose = icside_dma_verbose;
-- hwif->ide_dma_bad_drive = check_drive_bad_lists;
-- hwif->ide_dma_good_drive = check_drive_good_lists;
-- hwif->ide_dma_test_irq = icside_dma_test_irq;
-+ hwif->ide_dma_off = icside_dma_off;
-+ hwif->ide_dma_host_on = icside_dma_host_on;
-+ hwif->ide_dma_on = icside_dma_on;
-+ hwif->ide_dma_read = icside_dma_read;
-+ hwif->ide_dma_write = icside_dma_write;
-+ hwif->ide_dma_count = icside_dma_count;
-+ hwif->ide_dma_begin = icside_dma_begin;
-+ hwif->ide_dma_end = icside_dma_end;
-+ hwif->ide_dma_test_irq = icside_dma_test_irq;
-+ hwif->ide_dma_verbose = icside_dma_verbose;
-+ hwif->ide_dma_timeout = icside_dma_timeout;
-+ hwif->ide_dma_lostirq = icside_dma_lostirq;
-
-- printk(" capable%s\n", autodma ?
-- ", auto-enable" : "");
-+ printk(" capable%s\n", hwif->autodma ? ", auto-enable" : "");
-
- return 1;
-
- failed:
-- printk(" -- ERROR, unable to allocate DMA table\n");
-+ printk(" disabled, unable to allocate DMA table\n");
- return 0;
- }
-+
-+static void icside_dma_exit(ide_hwif_t *hwif)
-+{
-+ if (hwif->sg_table) {
-+ kfree(hwif->sg_table);
-+ hwif->sg_table = NULL;
-+ }
-+}
-+#else
-+#define icside_dma_init(hwif) (0)
-+#define icside_dma_exit(hwif) do { } while (0)
- #endif
-
--static ide_hwif_t *
--icside_find_hwif(unsigned long dataport)
-+static ide_hwif_t *icside_find_hwif(unsigned long dataport)
- {
- ide_hwif_t *hwif;
- int index;
-@@ -716,13 +780,13 @@
- goto found;
- }
-
-- return NULL;
-+ hwif = NULL;
- found:
- return hwif;
- }
-
- static ide_hwif_t *
--icside_setup(unsigned long base, struct cardinfo *info, int irq)
-+icside_setup(unsigned long base, struct cardinfo *info, struct expansion_card *ec)
- {
- unsigned long port = base + info->dataoffset;
- ide_hwif_t *hwif;
-@@ -740,8 +804,8 @@
- }
- hwif->hw.io_ports[IDE_CONTROL_OFFSET] = base + info->ctrloffset;
- hwif->io_ports[IDE_CONTROL_OFFSET] = base + info->ctrloffset;
-- hwif->hw.irq = irq;
-- hwif->irq = irq;
-+ hwif->hw.irq = ec->irq;
-+ hwif->irq = ec->irq;
- hwif->hw.dma = NO_DMA;
- hwif->noprobe = 0;
- hwif->chipset = ide_acorn;
-@@ -750,33 +814,39 @@
- return hwif;
- }
-
--static int __init icside_register_v5(struct expansion_card *ec, int autodma)
-+static int __init
-+icside_register_v5(struct icside_state *state, struct expansion_card *ec)
- {
- unsigned long slot_port;
- ide_hwif_t *hwif;
-
- slot_port = ecard_address(ec, ECARD_MEMC, 0);
-
-+ state->irq_port = slot_port;
-+
- ec->irqaddr = (unsigned char *)ioaddr(slot_port + ICS_ARCIN_V5_INTRSTAT);
- ec->irqmask = 1;
-- ec->irq_data = (void *)slot_port;
-- ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v5;
-+ ec->irq_data = state;
-+ ec->ops = &icside_ops_arcin_v5;
-
- /*
- * Be on the safe side - disable interrupts
- */
- inb(slot_port + ICS_ARCIN_V5_INTROFFSET);
-
-- hwif = icside_setup(slot_port, &icside_cardinfo_v5, ec->irq);
-+ hwif = icside_setup(slot_port, &icside_cardinfo_v5, ec);
-
-- return hwif ? 0 : -1;
-+ state->hwif[0] = hwif;
-+
-+ return hwif ? 0 : -ENODEV;
- }
-
--static int __init icside_register_v6(struct expansion_card *ec, int autodma)
-+static int __init
-+icside_register_v6(struct icside_state *state, struct expansion_card *ec)
- {
- unsigned long slot_port, port;
- ide_hwif_t *hwif, *mate;
-- int sel = 0;
-+ unsigned int sel = 0;
-
- slot_port = ecard_address(ec, ECARD_IOC, ECARD_FAST);
- port = ecard_address(ec, ECARD_EASI, ECARD_FAST);
-@@ -788,88 +858,185 @@
-
- outb(sel, slot_port);
-
-- ec->irq_data = (void *)port;
-- ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v6;
--
- /*
- * Be on the safe side - disable interrupts
- */
- inb(port + ICS_ARCIN_V6_INTROFFSET_1);
- inb(port + ICS_ARCIN_V6_INTROFFSET_2);
-
-- hwif = icside_setup(port, &icside_cardinfo_v6_1, ec->irq);
-- mate = icside_setup(port, &icside_cardinfo_v6_2, ec->irq);
-+ /*
-+ * Find and register the interfaces.
-+ */
-+ hwif = icside_setup(port, &icside_cardinfo_v6_1, ec);
-+ mate = icside_setup(port, &icside_cardinfo_v6_2, ec);
-
--#ifdef CONFIG_BLK_DEV_IDEDMA_ICS
-- if (ec->dma != NO_DMA) {
-- if (request_dma(ec->dma, hwif->name))
-- goto no_dma;
-+ if (!hwif || !mate)
-+ return -ENODEV;
-
-- if (hwif) {
-- hwif->config_data = slot_port;
-- hwif->select_data = sel;
-- hwif->hw.dma = ec->dma;
-- hwif->hw.priv = (void *)
-- (port + ICS_ARCIN_V6_INTRSTAT_1);
-- hwif->channel = 0;
-- icside_setup_dma(hwif, autodma);
-- hwif->drives[0].autodma = autodma;
-- hwif->drives[1].autodma = autodma;
-- }
-- if (mate) {
-- mate->config_data = slot_port;
-- mate->select_data = sel | 1;
-- mate->hw.dma = ec->dma;
-- mate->hw.priv = (void *)
-- (port + ICS_ARCIN_V6_INTRSTAT_2);
-- mate->channel = 1;
-- icside_setup_dma(mate, autodma);
-- mate->drives[0].autodma = autodma;
-- mate->drives[1].autodma = autodma;
-- }
-+ state->irq_port = port;
-+ state->slot_port = slot_port;
-+ state->hwif[0] = hwif;
-+ state->hwif[1] = mate;
-+
-+ ec->irq_data = state;
-+ ec->ops = &icside_ops_arcin_v6;
-+
-+ hwif->maskproc = icside_maskproc;
-+ hwif->channel = 0;
-+ hwif->hwif_data = state;
-+ hwif->mate = mate;
-+ hwif->serialized = 1;
-+ hwif->config_data = slot_port;
-+ hwif->select_data = sel;
-+ hwif->hw.dma = ec->dma;
-+
-+ mate->maskproc = icside_maskproc;
-+ mate->channel = 1;
-+ mate->hwif_data = state;
-+ mate->mate = hwif;
-+ mate->serialized = 1;
-+ mate->config_data = slot_port;
-+ mate->select_data = sel | 1;
-+ mate->hw.dma = ec->dma;
-+
-+ if (ec->dma != NO_DMA && !request_dma(ec->dma, hwif->name)) {
-+ icside_dma_init(hwif);
-+ icside_dma_init(mate);
- }
--no_dma:
--#endif
-- return hwif || mate ? 0 : -1;
-+ return 0;
- }
-
--int __init icside_init(void)
-+static int __init icside_probe(struct expansion_card *ec, const struct ecard_id *id)
- {
-- int autodma = 0;
-+ struct icside_state *state;
-+ int ret;
-
--#ifdef CONFIG_IDEDMA_ICS_AUTO
-- autodma = 1;
--#endif
-+ state = kmalloc(sizeof(struct icside_state), GFP_KERNEL);
-+ if (!state) {
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-
-- ecard_startfind ();
-+ memset(state, 0, sizeof(struct icside_state));
-+ state->type = ICS_TYPE_NOTYPE;
-
-- do {
-- struct expansion_card *ec;
-- int result;
-+ {
-+ unsigned int addr = ecard_address (ec, ECARD_IOC, ECARD_FAST) + ICS_IDENT_OFFSET;
-+ unsigned int type;
-
-- ec = ecard_find(0, icside_cids);
-- if (ec == NULL)
-- break;
-+ type = inb(addr) & 1;
-+ type |= (inb(addr + 1) & 1) << 1;
-+ type |= (inb(addr + 2) & 1) << 2;
-+ type |= (inb(addr + 3) & 1) << 3;
-
-- ecard_claim(ec);
-+ state->type = type;
-+ }
-
-- switch (icside_identifyif(ec)) {
-- case ics_if_arcin_v5:
-- result = icside_register_v5(ec, autodma);
-- break;
-+ switch (state->type) {
-+ case ICS_TYPE_A3IN:
-+ printk(KERN_WARNING "icside: A3IN unsupported\n");
-+ ret = -ENODEV;
-+ break;
-
-- case ics_if_arcin_v6:
-- result = icside_register_v6(ec, autodma);
-- break;
-+ case ICS_TYPE_A3USER:
-+ printk(KERN_WARNING "icside: A3USER unsupported\n");
-+ ret = -ENODEV;
-+ break;
-
-- default:
-- result = -1;
-- break;
-- }
-+ case ICS_TYPE_V5:
-+ ret = icside_register_v5(state, ec);
-+ break;
-
-- if (result)
-- ecard_release(ec);
-- } while (1);
-+ case ICS_TYPE_V6:
-+ ret = icside_register_v6(state, ec);
-+ break;
-
-- return 0;
-+ default:
-+ printk(KERN_WARNING "icside: unknown interface type\n");
-+ ret = -ENODEV;
-+ break;
-+ }
-+
-+ if (ret == 0) {
-+ ecard_set_drvdata(ec, state);
-+ } else {
-+ kfree(state);
-+ }
-+ out:
-+ return ret;
-+}
-+
-+static void __devexit icside_remove(struct expansion_card *ec)
-+{
-+ struct icside_state *state = ecard_get_drvdata(ec);
-+
-+ switch (state->type) {
-+ case ICS_TYPE_V5:
-+ /* FIXME: tell IDE to stop using the interface */
-+
-+ /* Disable interrupts */
-+ inb(state->slot_port + ICS_ARCIN_V5_INTROFFSET);
-+ break;
-+
-+ case ICS_TYPE_V6:
-+ /* FIXME: tell IDE to stop using the interface */
-+ icside_dma_exit(state->hwif[1]);
-+ icside_dma_exit(state->hwif[0]);
-+
-+ if (ec->dma != NO_DMA)
-+ free_dma(ec->dma);
-+
-+ /* Disable interrupts */
-+ inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
-+ inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
-+
-+ /* Reset the ROM pointer/EASI selection */
-+ outb(0, state->slot_port);
-+ break;
-+ }
-+
-+ ecard_set_drvdata(ec, NULL);
-+ ec->ops = NULL;
-+ ec->irq_data = NULL;
-+
-+ kfree(state);
-+}
-+
-+static void icside_shutdown(struct expansion_card *ec)
-+{
-+ struct icside_state *state = ecard_get_drvdata(ec);
-+
-+ switch (state->type) {
-+ case ICS_TYPE_V5:
-+ /* Disable interrupts */
-+ inb(state->slot_port + ICS_ARCIN_V5_INTROFFSET);
-+ break;
-+
-+ case ICS_TYPE_V6:
-+ /* Disable interrupts */
-+ inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_1);
-+ inb(state->irq_port + ICS_ARCIN_V6_INTROFFSET_2);
-+
-+ /* Reset the ROM pointer/EASI selection */
-+ outb(0, state->slot_port);
-+ break;
-+ }
-+}
-+
-+static const struct ecard_id icside_ids[] = {
-+ { MANU_ICS, PROD_ICS_IDE },
-+ { MANU_ICS2, PROD_ICS2_IDE },
-+ { 0xffff, 0xffff }
-+};
-+
-+static struct ecard_driver icside_driver = {
-+ .probe = icside_probe,
-+ .remove = __devexit_p(icside_remove),
-+ .shutdown = icside_shutdown,
-+ .id_table = icside_ids,
-+};
-+
-+int __init icside_init(void)
-+{
-+ return ecard_register_driver(&icside_driver);
- }
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/ide/arm/rstation-ide.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,78 @@
-+/*
-+ * linux/drivers/ide/rs-ide.c
-+ *
-+ * Copyright (c) 2002 Ben Dooks
-+ * Copyright (c) 2002 Simtec Electronics
-+ *
-+ * Simple RiscStation IDE support
-+*/
-+
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/blkdev.h>
-+#include <linux/errno.h>
-+#include <linux/ide.h>
-+#include <linux/init.h>
-+
-+#include <asm/hardware/iomd.h>
-+#include <asm/mach-types.h>
-+#include <asm/io.h>
-+
-+#ifndef CONFIG_ARCH_RISCSTATION
-+#error "compiling this code for non-riscstation hardware is dangerous!"
-+#endif
-+
-+#define DRV_PREFIX "ide-rs"
-+
-+#define IRQ_PRI (40+3)
-+#define IRQ_SEC (40+4)
-+
-+#define PORT_BASE ((0x2b800 - 0x10000) >> 2)
-+#define SEC_OFF (0x400 >> 2)
-+
-+int __init rside_reg(unsigned long base, unsigned int irq);
-+
-+int __init rside_init(void)
-+{
-+ int iotcr;
-+
-+ if (!machine_is_riscstation()) {
-+ printk(DRV_PREFIX ": hardware is not a RiscStation!\n");
-+ return 0;
-+ }
-+
-+ /* select correct area cycle time */
-+
-+ iotcr = inb(IOMD_IOTCR);
-+ outb((iotcr & ~3) | 1, IOMD_IOTCR);
-+
-+ /* register h/w */
-+
-+ rside_reg(PORT_BASE, IRQ_PRI);
-+ rside_reg(PORT_BASE + SEC_OFF, IRQ_SEC);
-+
-+ return 0;
-+}
-+
-+
-+int __init rside_reg(unsigned long port, unsigned int irq)
-+{
-+ unsigned long addr, i;
-+ hw_regs_t hw;
-+
-+ hw.irq = irq;
-+
-+ addr = port;
-+
-+ for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-+ hw.io_ports[i] = (ide_ioreg_t)addr;
-+ addr += 0x40 >> 2;
-+ }
-+
-+ hw.io_ports[IDE_CONTROL_OFFSET] = port + ((0xb80 - 0x800) >> 2);
-+
-+ printk(DRV_PREFIX ": registering channel at %08lx, %08lx, irq %d\n",
-+ port, hw.io_ports[IDE_CONTROL_OFFSET], irq);
-+
-+ return ide_register_hw(&hw, NULL);
-+}
---- linux-2.4.25/drivers/ide/ide-probe.c~2.4.25-vrs2.patch 2003-11-28 19:26:20.000000000 +0100
-+++ linux-2.4.25/drivers/ide/ide-probe.c 2004-03-31 17:15:09.000000000 +0200
-@@ -1296,11 +1296,11 @@
- hwif->name, hwif->major);
- return (hwif->present = 0);
- }
--
-+
- if (init_irq(hwif)) {
- int i = hwif->irq;
- /*
-- * It failed to initialise. Find the default IRQ for
-+ * It failed to initialise. Find the default IRQ for
- * this port and try that.
- */
- if (!(hwif->irq = ide_default_irq(hwif->io_ports[IDE_DATA_OFFSET]))) {
-@@ -1318,7 +1318,7 @@
- printk("%s: probed IRQ %d failed, using default.\n",
- hwif->name, hwif->irq);
- }
--
-+
- init_gendisk(hwif);
- blk_dev[hwif->major].data = hwif;
- blk_dev[hwif->major].queue = ide_get_queue;
---- linux-2.4.25/drivers/ide/ide-proc.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/ide/ide-proc.c 2004-03-31 17:15:09.000000000 +0200
-@@ -425,6 +425,7 @@
- case ide_cy82c693: name = "cy82c693"; break;
- case ide_4drives: name = "4drives"; break;
- case ide_pmac: name = "pmac"; break;
-+ case ide_acorn: name = "acorn"; break;
- default: name = "(unknown)"; break;
- }
- len = sprintf(page, "%s\n", name);
---- linux-2.4.25/drivers/ide/ide.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/ide/ide.c 2004-03-31 17:15:09.000000000 +0200
-@@ -218,23 +218,14 @@
- static void init_hwif_data (unsigned int index)
- {
- unsigned int unit;
-- hw_regs_t hw;
- ide_hwif_t *hwif = &ide_hwifs[index];
-
- /* bulk initialize hwif & drive info with zeros */
- memset(hwif, 0, sizeof(ide_hwif_t));
-- memset(&hw, 0, sizeof(hw_regs_t));
-
- /* fill in any non-zero initial values */
- hwif->index = index;
-- ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, &hwif->irq);
-- memcpy(&hwif->hw, &hw, sizeof(hw));
-- memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports));
-- hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
--#ifdef CONFIG_BLK_DEV_HD
-- if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA)
-- hwif->noprobe = 1; /* may be overridden by ide_setup() */
--#endif /* CONFIG_BLK_DEV_HD */
-+ hwif->noprobe = 1;
- hwif->major = ide_hwif_to_major[index];
- hwif->name[0] = 'i';
- hwif->name[1] = 'd';
-@@ -276,6 +267,28 @@
- }
-
- /*
-+ * Old compatability function - initialise ports using ide_default_io_base
-+ */
-+static void ide_old_init_default_hwifs(void)
-+{
-+ unsigned int index;
-+ ide_ioreg_t base;
-+ ide_hwif_t *hwif;
-+
-+ for (index = 0; index < MAX_HWIFS; index++) {
-+ hwif = &ide_hwifs[index];
-+
-+ base = ide_default_io_base(index);
-+
-+ if (base) {
-+ ide_init_hwif_ports(&hwif->hw, base, 0, &hwif->hw.irq);
-+ memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));
-+ hwif->noprobe = 0;
-+ }
-+ }
-+}
-+
-+/*
- * init_ide_data() sets reasonable default values into all fields
- * of all instances of the hwifs and drives, but only on the first call.
- * Subsequent calls have no effect (they don't wipe out anything).
-@@ -307,6 +320,7 @@
- init_hwif_data(index);
-
- /* Add default hw interfaces */
-+ ide_old_init_default_hwifs();
- ide_init_default_hwifs();
-
- idebus_parameter = 0;
-@@ -2530,6 +2544,12 @@
- rapide_init();
- }
- #endif /* CONFIG_BLK_DEV_IDE_RAPIDE */
-+#ifdef CONFIG_BLK_DEV_IDE_RISCSTATION
-+ {
-+ extern void rside_init(void);
-+ rside_init();
-+ }
-+#endif /* CONFIG_BLK_DEV_IDE_RISCSTATION */
- #ifdef CONFIG_BLK_DEV_GAYLE
- {
- extern void gayle_init(void);
---- linux-2.4.25/drivers/ide/pci/Makefile~2.4.25-vrs2.patch 2003-11-28 19:26:20.000000000 +0100
-+++ linux-2.4.25/drivers/ide/pci/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -15,7 +15,6 @@
- obj-$(CONFIG_BLK_DEV_HPT34X) += hpt34x.o
- obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o
- #obj-$(CONFIG_BLK_DEV_HPT37X) += hpt37x.o
--obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o
- obj-$(CONFIG_BLK_DEV_IT8172) += it8172.o
- obj-$(CONFIG_BLK_DEV_NS87415) += ns87415.o
- obj-$(CONFIG_BLK_DEV_OPTI621) += opti621.o
---- linux-2.4.25/drivers/ide/pci/sl82c105.c~2.4.25-vrs2.patch 2003-06-13 16:51:33.000000000 +0200
-+++ linux-2.4.25/drivers/ide/pci/sl82c105.c 2004-03-31 17:15:09.000000000 +0200
-@@ -37,7 +37,7 @@
- #ifdef DEBUG
- #define DBG(arg) printk arg
- #else
--#define DBG(fmt,...)
-+#define DBG(fmt...)
- #endif
- /*
- * SL82C105 PCI config register 0x40 bits.
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/ide/pci/sl82c105.c.2419 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,380 @@
-+/*
-+ * linux/drivers/ide/sl82c105.c
-+ *
-+ * SL82C105/Winbond 553 IDE driver
-+ *
-+ * Maintainer unknown.
-+ *
-+ * Changelog:
-+ *
-+ * 15/11/1998 RMK Drive tuning added from Rebel.com's kernel
-+ * sources
-+ * 30/03/2002 RMK Add fixes specified in W83C553F errata.
-+ * (with special thanks to Todd Inglett)
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/timer.h>
-+#include <linux/mm.h>
-+#include <linux/ioport.h>
-+#include <linux/interrupt.h>
-+#include <linux/blkdev.h>
-+#include <linux/hdreg.h>
-+#include <linux/pci.h>
-+#include <linux/ide.h>
-+
-+#include <asm/io.h>
-+#include <asm/dma.h>
-+
-+#include "ide_modes.h"
-+
-+extern char *ide_xfer_verbose (byte xfer_rate);
-+
-+/*
-+ * SL82C105 PCI config register 0x40 bits.
-+ */
-+#define CTRL_IDE_IRQB (1 << 30)
-+#define CTRL_IDE_IRQA (1 << 28)
-+#define CTRL_LEGIRQ (1 << 11)
-+#define CTRL_P1F16 (1 << 5)
-+#define CTRL_P1EN (1 << 4)
-+#define CTRL_P0F16 (1 << 1)
-+#define CTRL_P0EN (1 << 0)
-+
-+/*
-+ * Convert a PIO mode and cycle time to the required on/off
-+ * times for the interface. This has protection against run-away
-+ * timings.
-+ */
-+static unsigned int get_timing_sl82c105(ide_pio_data_t *p)
-+{
-+ unsigned int cmd_on;
-+ unsigned int cmd_off;
-+
-+ cmd_on = (ide_pio_timings[p->pio_mode].active_time + 29) / 30;
-+ cmd_off = (p->cycle_time - 30 * cmd_on + 29) / 30;
-+
-+ if (cmd_on > 32)
-+ cmd_on = 32;
-+ if (cmd_on == 0)
-+ cmd_on = 1;
-+
-+ if (cmd_off > 32)
-+ cmd_off = 32;
-+ if (cmd_off == 0)
-+ cmd_off = 1;
-+
-+ return (cmd_on - 1) << 8 | (cmd_off - 1) | (p->use_iordy ? 0x40 : 0x00);
-+}
-+
-+/*
-+ * Configure the drive and chipset for PIO
-+ */
-+static void config_for_pio(ide_drive_t *drive, int pio, int report)
-+{
-+ ide_hwif_t *hwif = HWIF(drive);
-+ struct pci_dev *dev = hwif->pci_dev;
-+ ide_pio_data_t p;
-+ unsigned short drv_ctrl = 0x909;
-+ unsigned int xfer_mode, reg;
-+
-+ reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0);
-+
-+ pio = ide_get_best_pio_mode(drive, pio, 5, &p);
-+
-+ switch (pio) {
-+ default:
-+ case 0: xfer_mode = XFER_PIO_0; break;
-+ case 1: xfer_mode = XFER_PIO_1; break;
-+ case 2: xfer_mode = XFER_PIO_2; break;
-+ case 3: xfer_mode = XFER_PIO_3; break;
-+ case 4: xfer_mode = XFER_PIO_4; break;
-+ }
-+
-+ if (ide_config_drive_speed(drive, xfer_mode) == 0)
-+ drv_ctrl = get_timing_sl82c105(&p);
-+
-+ if (drive->using_dma == 0) {
-+ /*
-+ * If we are actually using MW DMA, then we can not
-+ * reprogram the interface drive control register.
-+ */
-+ pci_write_config_word(dev, reg, drv_ctrl);
-+ pci_read_config_word(dev, reg, &drv_ctrl);
-+
-+ if (report) {
-+ printk("%s: selected %s (%dns) (%04X)\n", drive->name,
-+ ide_xfer_verbose(xfer_mode), p.cycle_time, drv_ctrl);
-+ }
-+ }
-+}
-+
-+/*
-+ * Configure the drive and the chipset for DMA
-+ */
-+static int config_for_dma(ide_drive_t *drive)
-+{
-+ ide_hwif_t *hwif = HWIF(drive);
-+ struct pci_dev *dev = hwif->pci_dev;
-+ unsigned short drv_ctrl = 0x909;
-+ unsigned int reg;
-+
-+ reg = (hwif->channel ? 0x4c : 0x44) + (drive->select.b.unit ? 4 : 0);
-+
-+ if (ide_config_drive_speed(drive, XFER_MW_DMA_2) == 0)
-+ drv_ctrl = 0x0240;
-+
-+ pci_write_config_word(dev, reg, drv_ctrl);
-+
-+ return 0;
-+}
-+
-+
-+/*
-+ * Check to see if the drive and
-+ * chipset is capable of DMA mode
-+ */
-+static int sl82c105_check_drive(ide_drive_t *drive)
-+{
-+ ide_dma_action_t dma_func = ide_dma_off_quietly;
-+
-+ do {
-+ struct hd_driveid *id = drive->id;
-+ ide_hwif_t *hwif = HWIF(drive);
-+
-+ if (!hwif->autodma)
-+ break;
-+
-+ if (!id || !(id->capability & 1))
-+ break;
-+
-+ /* Consult the list of known "bad" drives */
-+ if (ide_dmaproc(ide_dma_bad_drive, drive)) {
-+ dma_func = ide_dma_off;
-+ break;
-+ }
-+
-+ if (id->field_valid & 2) {
-+ if (id->dma_mword & 7 || id->dma_1word & 7)
-+ dma_func = ide_dma_on;
-+ break;
-+ }
-+
-+ if (ide_dmaproc(ide_dma_good_drive, drive)) {
-+ dma_func = ide_dma_on;
-+ break;
-+ }
-+ } while (0);
-+
-+ return HWIF(drive)->dmaproc(dma_func, drive);
-+}
-+
-+/*
-+ * The SL82C105 holds off all IDE interrupts while in DMA mode until
-+ * all DMA activity is completed. Sometimes this causes problems (eg,
-+ * when the drive wants to report an error condition).
-+ *
-+ * 0x7e is a "chip testing" register. Bit 2 resets the DMA controller
-+ * state machine. We need to kick this to work around various bugs.
-+ */
-+static inline void sl82c105_reset_host(struct pci_dev *dev)
-+{
-+ u16 val;
-+
-+ pci_read_config_word(dev, 0x7e, &val);
-+ pci_write_config_word(dev, 0x7e, val | (1 << 2));
-+ pci_write_config_word(dev, 0x7e, val & ~(1 << 2));
-+}
-+
-+/*
-+ * If we get an IRQ timeout, it might be that the DMA state machine
-+ * got confused. Fix from Todd Inglett. Details from Winbond.
-+ *
-+ * This function is called when the IDE timer expires, the drive
-+ * indicates that it is READY, and we were waiting for DMA to complete.
-+ */
-+static int sl82c105_lostirq(ide_drive_t *drive)
-+{
-+ ide_hwif_t *hwif = HWIF(drive);
-+ struct pci_dev *dev = hwif->pci_dev;
-+ u32 val, mask = hwif->channel ? CTRL_IDE_IRQB : CTRL_IDE_IRQA;
-+ unsigned long dma_base = hwif->dma_base;
-+
-+ printk("sl82c105: lost IRQ: resetting host\n");
-+
-+ /*
-+ * Check the raw interrupt from the drive.
-+ */
-+ pci_read_config_dword(dev, 0x40, &val);
-+ if (val & mask)
-+ printk("sl82c105: drive was requesting IRQ, but host lost it\n");
-+
-+ /*
-+ * Was DMA enabled? If so, disable it - we're resetting the
-+ * host. The IDE layer will be handling the drive for us.
-+ */
-+ val = inb(dma_base);
-+ if (val & 1) {
-+ outb(val & ~1, dma_base);
-+ printk("sl82c105: DMA was enabled\n");
-+ }
-+
-+ sl82c105_reset_host(dev);
-+
-+ /* ide_dmaproc would return 1, so we do as well */
-+ return 1;
-+}
-+
-+/*
-+ * ATAPI devices can cause the SL82C105 DMA state machine to go gaga.
-+ * Winbond recommend that the DMA state machine is reset prior to
-+ * setting the bus master DMA enable bit.
-+ *
-+ * The generic IDE core will have disabled the BMEN bit before this
-+ * function is called.
-+ */
-+static void sl82c105_before_bm_enable(ide_drive_t *drive)
-+{
-+ ide_hwif_t *hwif = HWIF(drive);
-+ struct pci_dev *dev = hwif->pci_dev;
-+
-+ sl82c105_reset_host(dev);
-+}
-+
-+/*
-+ * Our very own dmaproc. We need to intercept various calls
-+ * to fix up the SL82C105 specific behaviour.
-+ */
-+static int sl82c105_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
-+{
-+ switch (func) {
-+ case ide_dma_check:
-+ return sl82c105_check_drive(drive);
-+
-+ case ide_dma_on:
-+ if (config_for_dma(drive))
-+ func = ide_dma_off;
-+ /* fall through */
-+
-+ case ide_dma_off_quietly:
-+ case ide_dma_off:
-+ config_for_pio(drive, 4, 0);
-+ break;
-+
-+ case ide_dma_read:
-+ case ide_dma_write:
-+ case ide_dma_begin:
-+ case ide_dma_timeout:
-+ sl82c105_before_bm_enable(drive);
-+ break;
-+
-+ case ide_dma_lostirq:
-+ return sl82c105_lostirq(drive);
-+
-+ default:
-+ break;
-+ }
-+ return ide_dmaproc(func, drive);
-+}
-+
-+/*
-+ * We only deal with PIO mode here - DMA mode 'using_dma' is not
-+ * initialised at the point that this function is called.
-+ */
-+static void tune_sl82c105(ide_drive_t *drive, byte pio)
-+{
-+ config_for_pio(drive, pio, 1);
-+
-+ /*
-+ * We support 32-bit I/O on this interface, and it
-+ * doesn't have problems with interrupts.
-+ */
-+ drive->io_32bit = 1;
-+ drive->unmask = 1;
-+}
-+
-+/*
-+ * Return the revision of the Winbond bridge
-+ * which this function is part of.
-+ */
-+static unsigned int sl82c105_bridge_revision(struct pci_dev *dev)
-+{
-+ struct pci_dev *bridge;
-+ unsigned char rev;
-+
-+ /*
-+ * The bridge should be part of the same device, but function 0.
-+ */
-+ bridge = pci_find_slot(dev->bus->number,
-+ PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
-+ if (!bridge)
-+ return -1;
-+
-+ /*
-+ * Make sure it is a Winbond 553 and is an ISA bridge.
-+ */
-+ if (bridge->vendor != PCI_VENDOR_ID_WINBOND ||
-+ bridge->device != PCI_DEVICE_ID_WINBOND_83C553 ||
-+ bridge->class >> 8 != PCI_CLASS_BRIDGE_ISA)
-+ return -1;
-+
-+ /*
-+ * We need to find function 0's revision, not function 1
-+ */
-+ pci_read_config_byte(bridge, PCI_REVISION_ID, &rev);
-+
-+ return rev;
-+}
-+
-+/*
-+ * Enable the PCI device
-+ */
-+unsigned int __init pci_init_sl82c105(struct pci_dev *dev, const char *msg)
-+{
-+ u32 val;
-+
-+ pci_read_config_dword(dev, 0x40, &val);
-+ val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1EN | CTRL_P1F16;
-+ pci_write_config_dword(dev, 0x40, val);
-+
-+ return dev->irq;
-+}
-+
-+void __init dma_init_sl82c105(ide_hwif_t *hwif, unsigned long dma_base)
-+{
-+ unsigned int bridge_rev;
-+ byte dma_state;
-+
-+ dma_state = inb(dma_base + 2);
-+ bridge_rev = sl82c105_bridge_revision(hwif->pci_dev);
-+ if (bridge_rev <= 5) {
-+ hwif->autodma = 0;
-+ hwif->drives[0].autotune = 1;
-+ hwif->drives[1].autotune = 1;
-+ printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n",
-+ hwif->name, bridge_rev);
-+ dma_state &= ~0x60;
-+ } else {
-+ dma_state |= 0x60;
-+ hwif->autodma = 1;
-+ }
-+ outb(dma_state, dma_base + 2);
-+
-+ ide_setup_dma(hwif, dma_base, 8);
-+
-+ if (bridge_rev <= 5)
-+ hwif->dmaproc = NULL;
-+ else
-+ hwif->dmaproc = sl82c105_dmaproc;
-+}
-+
-+/*
-+ * Initialise the chip
-+ */
-+void __init ide_init_sl82c105(ide_hwif_t *hwif)
-+{
-+ hwif->tuneproc = tune_sl82c105;
-+}
-+
---- linux-2.4.25/drivers/input/Config.in~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/input/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -15,5 +15,6 @@
- dep_tristate ' Joystick support' CONFIG_INPUT_JOYDEV $CONFIG_INPUT
- dep_tristate ' Event interface support' CONFIG_INPUT_EVDEV $CONFIG_INPUT
- dep_tristate ' User level driver support' CONFIG_INPUT_UINPUT $CONFIG_INPUT
-+dep_tristate ' MX1 touchscreen support' CONFIG_INPUT_MX1TS $CONFIG_INPUT_MOUSEDEV $CONFIG_ARCH_MX1ADS
-
- endmenu
---- linux-2.4.25/drivers/input/Makefile~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/input/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -24,6 +24,7 @@
- obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
- obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
- obj-$(CONFIG_INPUT_EVDEV) += evdev.o
-+obj-$(CONFIG_INPUT_MX1TS) += mx1ts.o
- obj-$(CONFIG_INPUT_UINPUT) += uinput.o
-
- # The global Rules.make.
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/input/mx1ts.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,508 @@
-+/*
-+ * linux/drivers/misc/mx1ts.c
-+ *
-+ * Copyright (C) 2003 Blue Mug, Inc. for Motorola, Inc.
-+ *
-+ * Cloned from ucb1x00_ts.c
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/smp.h>
-+#include <linux/smp_lock.h>
-+#include <linux/sched.h>
-+#include <linux/completion.h>
-+#include <linux/delay.h>
-+#include <linux/string.h>
-+#include <linux/pm.h>
-+
-+#include <asm/dma.h>
-+
-+#include <linux/input.h>
-+
-+#include "mx1ts.h"
-+
-+#define DEV_IRQ_ID "mx1-ts"
-+
-+struct mx1_ts {
-+ struct input_dev idev;
-+#ifdef CONFIG_PM
-+ struct pm_dev *pmdev;
-+#endif
-+
-+ wait_queue_head_t irq_wait;
-+ struct completion init_exit;
-+ int use_count;
-+ u16 x_res;
-+ u16 y_res;
-+
-+ int restart:1;
-+};
-+
-+static struct mx1_ts mx1ts;
-+static u8 mx1_performing_auto_calibration = 0;
-+static u16 mx1_cal_auto_zero = 0;
-+static u16 mx1_cal_range_x = 0;
-+static u16 mx1_cal_range_y = 0;
-+
-+static int mx1_ts_startup(struct mx1_ts *ts);
-+static void mx1_ts_shutdown(struct mx1_ts *ts);
-+
-+static void mx1_ts_pendata_int(int irq, void *dev_id, struct pt_regs *regs);
-+static void mx1_ts_touch_int(int irq, void *dev_id, struct pt_regs *regs);
-+static void mx1_ts_compare_int(int irq, void *dev_id, struct pt_regs *regs);
-+
-+static void mx1_ts_enable_pen_touch_interrupt(void);
-+static void mx1_ts_disable_pen_touch_interrupt(void);
-+static void mx1_ts_enable_pen_up_interrupt(void);
-+static void mx1_ts_disable_pen_up_interrupt(void);
-+static void mx1_ts_enable_auto_sample(void);
-+static void mx1_ts_disable_auto_sample(void);
-+static void mx1_ts_start_auto_calibration(void);
-+
-+static inline void mx1_reg_write(unsigned int reg, unsigned int val)
-+{
-+ *((volatile unsigned int *)reg) = val;
-+}
-+
-+static inline unsigned int mx1_reg_read(unsigned int reg)
-+{
-+ return *((volatile unsigned int *)reg);
-+}
-+
-+static inline void mx1_reg_clear_bit(unsigned int reg, unsigned int bit)
-+{
-+ *((volatile unsigned int *)reg) &= ~bit;
-+}
-+
-+static inline void mx1_reg_set_bit(unsigned int reg, unsigned int bit)
-+{
-+ *((volatile unsigned int *)reg) |= bit;
-+}
-+
-+static inline void mx1_ts_evt_add(struct mx1_ts *ts, u16 pressure, u16 x, u16 y)
-+{
-+ input_report_abs(&ts->idev, ABS_X, (int)x - 32768);
-+ input_report_abs(&ts->idev, ABS_Y, (int)y - 32768);
-+ input_report_abs(&ts->idev, ABS_PRESSURE, (int)pressure);
-+}
-+
-+static inline void mx1_ts_flush_fifo(void)
-+{
-+ int i;
-+ for (i = 0; i < 12; i++)
-+ if (mx1_reg_read(ASP_ISTATR) & (ASP_PFF | ASP_PDR))
-+ mx1_reg_read(ASP_PADFIFO);
-+}
-+
-+static int mx1_ts_open(struct input_dev *idev)
-+{
-+ struct mx1_ts *ts = (struct mx1_ts *)idev;
-+
-+ mx1_performing_auto_calibration = 0;
-+ return mx1_ts_startup(ts);
-+}
-+
-+static void mx1_ts_close(struct input_dev *idev)
-+{
-+ struct mx1_ts *ts = (struct mx1_ts *)idev;
-+
-+ mx1_ts_shutdown(ts);
-+}
-+
-+static inline int mx1_ts_enable_irqs(void)
-+{
-+ int result;
-+
-+ result = request_irq(ASP_PENDATA_IRQ,
-+ mx1_ts_pendata_int,
-+ SA_INTERRUPT,
-+ DEV_IRQ_ID,
-+ DEV_IRQ_ID);
-+ if (result) {
-+ printk("Couldn't request pen data IRQ.\n");
-+ return result;
-+ }
-+
-+ result = request_irq(ASP_TOUCH_IRQ,
-+ mx1_ts_touch_int,
-+ SA_INTERRUPT,
-+ DEV_IRQ_ID,
-+ DEV_IRQ_ID);
-+ if (result) {
-+ printk("Couldn't request pen touch IRQ.\n");
-+ free_irq(ASP_PENDATA_IRQ, DEV_IRQ_ID);
-+ return result;
-+ }
-+
-+ return result;
-+}
-+
-+static inline int mx1_ts_disable_irqs(void)
-+{
-+ free_irq(ASP_PENDATA_IRQ, DEV_IRQ_ID);
-+ free_irq(ASP_TOUCH_IRQ, DEV_IRQ_ID);
-+
-+ return 0;
-+}
-+
-+static inline int mx1_ts_register(struct mx1_ts *ts)
-+{
-+ ts->idev.name = "Touchscreen panel";
-+ ts->idev.open = mx1_ts_open;
-+ ts->idev.close = mx1_ts_close;
-+
-+ __set_bit(EV_ABS, ts->idev.evbit);
-+ __set_bit(ABS_X, ts->idev.absbit);
-+ __set_bit(ABS_Y, ts->idev.absbit);
-+ __set_bit(ABS_PRESSURE, ts->idev.absbit);
-+
-+ ts->idev.absmin[ABS_X] = 0;
-+ ts->idev.absmax[ABS_X] = (u32)0x0000FFFF;
-+ ts->idev.absfuzz[ABS_X] = 50;
-+ ts->idev.absflat[ABS_X] = 0;
-+
-+ ts->idev.absmin[ABS_Y] = 0;
-+ ts->idev.absmax[ABS_Y] = (u32)0x0000FFFF;
-+ ts->idev.absfuzz[ABS_Y] = 50;
-+ ts->idev.absflat[ABS_Y] = 0;
-+
-+ input_register_device(&ts->idev);
-+
-+ return 0;
-+}
-+
-+static inline void mx1_ts_deregister(struct mx1_ts *ts)
-+{
-+ input_unregister_device(&ts->idev);
-+}
-+
-+/*
-+ * Handle the touch interrupt, generated when the pen is pressed/
-+ * released.
-+ */
-+static void mx1_ts_touch_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ /* Clear the interrupt. */
-+ mx1_reg_set_bit(ASP_ISTATR, ASP_PEN);
-+
-+ mx1_ts_disable_pen_touch_interrupt();
-+ mx1_ts_start_auto_calibration();
-+ mx1_ts_enable_pen_up_interrupt();
-+}
-+
-+/*
-+ * Handle the pen data ready interrupt, generated when pen data is
-+ * in the FIFO.
-+ */
-+static void mx1_ts_pendata_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ static unsigned int auto_zero, pen_x, pen_y, pen_u;
-+
-+ if (mx1_reg_read(ASP_ISTATR) & 0x400) {
-+ mx1_reg_set_bit(ASP_ISTATR, 0x400);
-+
-+ mx1_ts_disable_auto_sample();
-+ mx1_ts_disable_pen_up_interrupt();
-+ mx1_ts_enable_pen_touch_interrupt();
-+
-+ mx1_ts_evt_add(&mx1ts, 0, pen_x, pen_y);
-+
-+ mx1_ts_flush_fifo();
-+
-+ return;
-+ }
-+
-+ if (mx1_performing_auto_calibration) {
-+ unsigned int value;
-+
-+ mx1_cal_auto_zero = mx1_reg_read(ASP_PADFIFO) & 0xFFFF;
-+ mx1_cal_range_x = mx1_reg_read(ASP_PADFIFO) & 0xFFFF;
-+ mx1_cal_range_y = mx1_reg_read(ASP_PADFIFO) & 0xFFFF;
-+
-+ if ((mx1_cal_auto_zero >= mx1_cal_range_x) ||
-+ (mx1_cal_auto_zero >= mx1_cal_range_y)) {
-+ /* Invalid data. */
-+ mx1_ts_start_auto_calibration();
-+ return;
-+ }
-+
-+ mx1_cal_range_x -= mx1_cal_auto_zero;
-+ mx1_cal_range_y -= mx1_cal_auto_zero;
-+
-+ value = mx1_reg_read(ASP_ACNTLCR);
-+ value &= ~0x04000000; /* XXX Undocumented. */
-+ mx1_reg_write(ASP_ACNTLCR, value);
-+
-+ mx1_performing_auto_calibration = 0;
-+
-+ mx1_ts_enable_auto_sample();
-+ } else {
-+ /* There could be more than one sample in the FIFO, but we're
-+ * only going to read one per call. The interrupt will be
-+ * generated as long as there is data in the FIFO. */
-+
-+ if ((mx1_reg_read(ASP_ISTATR) & ASP_PDR) != ASP_PDR) {
-+ return;
-+ }
-+
-+ auto_zero = mx1_reg_read(ASP_PADFIFO);
-+ if (auto_zero > (mx1_cal_auto_zero + 0x200)) {
-+ return;
-+ }
-+
-+ pen_x = mx1_reg_read(ASP_PADFIFO);
-+ pen_y = mx1_reg_read(ASP_PADFIFO);
-+ pen_u = mx1_reg_read(ASP_PADFIFO);
-+
-+ pen_x = (u32)(((pen_x - mx1_cal_auto_zero) << 16) /
-+ mx1_cal_range_x);
-+ pen_y = (u32)(((pen_y - mx1_cal_auto_zero) << 16) /
-+ mx1_cal_range_y);
-+
-+ mx1_ts_evt_add(&mx1ts, pen_u, pen_x, pen_y);
-+ }
-+}
-+
-+static void mx1_ts_reset_asp(void)
-+{
-+ unsigned int value;
-+
-+ mx1_ts_flush_fifo();
-+
-+ /* Soft reset the ASP module */
-+ mx1_reg_write(ASP_ACNTLCR, ASP_SWRST);
-+
-+ /* Read back the reset value of the control register */
-+ value = mx1_reg_read(ASP_ACNTLCR);
-+
-+ /* Enable the clock and wait for a short while */
-+ value |= ASP_CLKEN;
-+ mx1_reg_write(ASP_ACNTLCR, value);
-+ udelay(100);
-+
-+ /* Set the value of the conrtol register. */
-+ value = ASP_CLKEN | ASP_NM | ASP_SW6 | ASP_BGE;
-+ mx1_reg_write(ASP_ACNTLCR, value);
-+
-+ /* Set the clock divide ratio to 2. */
-+ mx1_reg_write(ASP_CLKDIV, 0x01);
-+
-+ /* Set the sample rate control register. These values should yield
-+ * about 150 samples per second, which seems to give good smooth
-+ * lines. */
-+ value = (0x2 << ASP_DMCNT_SCALE) | /* Decimation ratio is 3 */
-+ (0x1 << ASP_IDLECNT_SCALE) | /* Idle count is 1 clock */
-+ (0x2 << ASP_DSCNT_SCALE); /* Data setup is 2 clocks */
-+ mx1_reg_write(ASP_PSMPLRG, value);
-+
-+ /* Disable the compare function. */
-+ mx1_reg_write(ASP_CMPCNTL, 0);
-+}
-+
-+static void mx1_ts_enable_auto_sample(void)
-+{
-+ unsigned int value;
-+
-+ mx1_ts_flush_fifo();
-+
-+ value = mx1_reg_read(ASP_ACNTLCR);
-+
-+ /* Set the mode to X then Y */
-+ value &= ~ASP_MODE_MASK;
-+ value |= ASP_MODE_ONLY_Y;
-+
-+ /* Enable auto zero. */
-+ value |= ASP_AZE;
-+
-+ /* Enable auto sample. */
-+ value |= ASP_AUTO;
-+
-+ /* Enable pen A/D. */
-+ value |= ASP_PADE;
-+ mx1_reg_write(ASP_ACNTLCR, value);
-+
-+ /* Enable pen data ready and full interrupt. */
-+ value = mx1_reg_read(ASP_ICNTLR);
-+ value |= ASP_PFFE | ASP_PDRE;
-+ mx1_reg_write(ASP_ICNTLR, value);
-+}
-+
-+static void mx1_ts_disable_auto_sample(void)
-+{
-+ unsigned int value;
-+
-+ value = mx1_reg_read(ASP_ACNTLCR);
-+
-+ /* Set the mode to none */
-+ value &= ~ASP_MODE_MASK;
-+
-+ /* Disable auto zero. */
-+ value &= ~ASP_AZE;
-+
-+ /* Disable auto sample. */
-+ value &= ~ASP_AUTO;
-+
-+ /* Disable pen A/D. */
-+ value &= ~ASP_PADE;
-+ mx1_reg_write(ASP_ACNTLCR, value);
-+
-+ /* Disable pen data ready and full interrupt. */
-+ value = mx1_reg_read(ASP_ICNTLR);
-+ value &= ~(ASP_PFFE | ASP_PDRE);
-+ mx1_reg_write(ASP_ICNTLR, value);
-+}
-+
-+static void mx1_ts_enable_pen_touch_interrupt(void)
-+{
-+ unsigned int value;
-+
-+ /* Enable pen touch interrupt. */
-+ value = mx1_reg_read(ASP_ICNTLR);
-+ value |= ASP_EDGE | ASP_PIRQE;
-+ mx1_reg_write(ASP_ICNTLR, value);
-+}
-+
-+static void mx1_ts_disable_pen_touch_interrupt(void)
-+{
-+ unsigned int value;
-+
-+ /* Enable pen touch interrupt. */
-+ value = mx1_reg_read(ASP_ICNTLR);
-+ value &= ~ASP_PIRQE;
-+ mx1_reg_write(ASP_ICNTLR, value);
-+}
-+
-+static void mx1_ts_enable_pen_up_interrupt(void)
-+{
-+ unsigned int value;
-+
-+ /* Enable pen up interrupt. XXX: This feature is undocumented. */
-+ value = mx1_reg_read(ASP_ICNTLR);
-+ value |= ASP_PUPE;
-+ mx1_reg_write(ASP_ICNTLR, value);
-+}
-+
-+static void mx1_ts_disable_pen_up_interrupt(void)
-+{
-+ unsigned int value;
-+
-+ /* Enable pen up interrupt. XXX: This feature is undocumented. */
-+ value = mx1_reg_read(ASP_ICNTLR);
-+ value &= ~ASP_PUPE;
-+ mx1_reg_write(ASP_ICNTLR, value);
-+}
-+
-+static void mx1_ts_start_auto_calibration(void)
-+{
-+ unsigned int value;
-+
-+ mx1_performing_auto_calibration = 1;
-+
-+ value = mx1_reg_read(ASP_ACNTLCR);
-+
-+ /* Set the mode to X then Y */
-+ value &= ~ASP_MODE_MASK;
-+ value |= ASP_MODE_ONLY_X;
-+
-+ /* Enable auto zero. */
-+ value |= ASP_AZE;
-+
-+ /* Enable auto calibrate. XXX: Undocumented bitfield. */
-+ value |= 0x04000000;
-+
-+ /* Enable auto sample. */
-+ value |= ASP_AUTO;
-+
-+ /* Enable pen A/D. */
-+ value |= ASP_PADE;
-+ mx1_reg_write(ASP_ACNTLCR, value);
-+
-+ /* Enable pen data ready and full interrupt. */
-+ value = mx1_reg_read(ASP_ICNTLR);
-+ value |= ASP_PFFE | ASP_PDRE | ASP_PUPE;
-+ mx1_reg_write(ASP_ICNTLR, value);
-+}
-+
-+static int mx1_ts_startup(struct mx1_ts *ts)
-+{
-+ int ret = 0;
-+
-+ if (ts->use_count++ != 0)
-+ goto out;
-+
-+ /*
-+ * Reset the ASP.
-+ */
-+ mx1_ts_reset_asp();
-+
-+
-+ /*
-+ * XXX: Figure out if we need this...
-+ * If we do this at all, we should allow the user to
-+ * measure and read the X and Y resistance at any time.
-+ */
-+ //ts->x_res = mx1_ts_read_xres(ts);
-+ //ts->y_res = mx1_ts_read_yres(ts);
-+
-+ mx1_ts_enable_pen_touch_interrupt();
-+
-+ out:
-+ if (ret)
-+ ts->use_count--;
-+ return ret;
-+}
-+
-+/*
-+ * Release touchscreen resources. Disable IRQs.
-+ */
-+static void mx1_ts_shutdown(struct mx1_ts *ts)
-+{
-+ if (--ts->use_count == 0) {
-+ unsigned int value;
-+
-+ /* Turn off the ADC and associated circuitry. */
-+ value = mx1_reg_read(ASP_ACNTLCR);
-+ value &= !(ASP_CLKEN | ASP_PADE | ASP_BGE);
-+ mx1_reg_write(ASP_ACNTLCR, value);
-+ }
-+}
-+
-+/*
-+ * Initialization.
-+ */
-+static int __init mx1_ts_init(void)
-+{
-+ int ret = 0;
-+ struct mx1_ts *ts = &mx1ts;
-+
-+ mx1_ts_reset_asp();
-+
-+ /*
-+ * Enable the IRQ's
-+ */
-+ if ((ret = mx1_ts_enable_irqs()))
-+ return ret;
-+
-+ return mx1_ts_register(ts);
-+}
-+
-+static void __exit mx1_ts_exit(void)
-+{
-+ struct mx1_ts *ts = &mx1ts;
-+
-+ mx1_ts_disable_irqs();
-+ mx1_ts_deregister(ts);
-+}
-+
-+module_init(mx1_ts_init);
-+module_exit(mx1_ts_exit);
-+
-+MODULE_AUTHOR("Jon McClintock <jonm@bluemug.com>");
-+MODULE_DESCRIPTION("MX1 touchscreen driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/input/mx1ts.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,108 @@
-+/*
-+ * linux/drivers/misc/mx1ts.h
-+ *
-+ * Copyright (C) 2003 Blue Mug, Inc. for Motorola, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ */
-+
-+/* Interrupt numbers */
-+#define ASP_COMPARE_IRQ 5
-+#define ASP_PENDATA_IRQ 33
-+#define ASP_TOUCH_IRQ 46
-+
-+/* Analog signal processor (ASP) control registers */
-+#define ASP_ACNTLCR 0xF0215010 /* Control register */
-+#define ASP_PSMPLRG 0xF0215014 /* Pen A/D sampe rate control */
-+#define ASP_CMPCNTL 0xF0215030 /* Compare control register */
-+#define ASP_ICNTLR 0xF0215018 /* Interrupt control register */
-+#define ASP_ISTATR 0xF021501C /* Interrupt status register */
-+#define ASP_PADFIFO 0xF0215000 /* Pen sample FIFO */
-+#define ASP_CLKDIV 0xF021502C /* Clock divide register */
-+
-+/* ASP control register bits */
-+#define ASP_CLKEN (1 << 25) /* Clock enable */
-+#define ASP_SWRST (1 << 23) /* Software reset */
-+#define ASP_U_SEL (1 << 21) /* U-channel resistor select */
-+#define ASP_AZ_SEL (1 << 20) /* Auto-zero position select */
-+#define ASP_LVM (1 << 19) /* Low voltage output */
-+#define ASP_NM (1 << 18) /* Normal voltage output */
-+#define ASP_HPM (1 << 17) /* High voltage output */
-+#define ASP_GLO (1 << 16) /* Low gain enable */
-+#define ASP_AZE (1 << 15) /* Auto-zero enable */
-+#define ASP_AUTO (1 << 14) /* Auto sampling */
-+#define ASP_SW8 (1 << 11) /* Switch control 8 */
-+#define ASP_SW7 (1 << 10)
-+#define ASP_SW6 (1 << 9)
-+#define ASP_SW5 (1 << 8)
-+#define ASP_SW4 (1 << 7)
-+#define ASP_SW3 (1 << 6)
-+#define ASP_SW2 (1 << 5)
-+#define ASP_SW1 (1 << 4) /* Switch control 1 */
-+#define ASP_VDAE (1 << 3) /* Voice D/A enable */
-+#define ASP_VADE (1 << 2) /* Voice A/D enable */
-+#define ASP_PADE (1 << 1) /* Pen A/D enable */
-+#define ASP_BGE (1 << 0) /* Bandgap enable */
-+
-+#define ASP_MODE_MASK 0x00003000
-+#define ASP_MODE_NONE 0x00000000
-+#define ASP_MODE_ONLY_X 0x00001000
-+#define ASP_MODE_ONLY_Y 0x00002000
-+#define ASP_MODE_ONLY_U 0x00003000
-+
-+/* ASP Pen A/D sample rate control register */
-+#define ASP_DMCNT_MASK (0x00007000) /* Decimation ratio count */
-+#define ASP_DMCNT_SCALE (12)
-+#define ASP_BIT_SELECT_MASK (0x00000C00) /* Bit select */
-+#define ASP_BIT_SELECT_SCALE (10)
-+#define ASP_IDLECNT_MASK (0x000003F0) /* Idle count */
-+#define ASP_IDLECNT_SCALE (4)
-+#define ASP_DSCNT_MASK (0x0000000F) /* Data setup count */
-+#define ASP_DSCNT_SCALE (0)
-+
-+/* ASP compare control register */
-+#define ASP_INT (1 << 19) /* Interrupt status */
-+#define ASP_CC (1 << 18) /* Trigger on greater than */
-+#define ASP_INSEL_MASK (0x00030000)
-+#define ASP_INSEL_DISABLE (0x00000000)
-+#define ASP_INSEL_X (0x00010000)
-+#define ASP_INSEL_Y (0x00020000)
-+#define ASP_INSEL_U (0x00030000)
-+#define ASP_COMPARE_VAL_MASK (0x0000FFFF)
-+#define ASP_COMPARE_VAL_SCALE (0)
-+
-+/* ASP interrupt control register bits */
-+#define ASP_PUPE (1 << 10) /* Pen up XXX undocumented */
-+#define ASP_VDDMAE (1 << 8) /* VDAC FIFO empty DMA */
-+#define ASP_VADMAE (1 << 7) /* VADC FIFO full DMA */
-+#define ASP_POL (1 << 6) /* Pen interrupt polarity */
-+#define ASP_EDGE (1 << 5) /* Edge trigger enable */
-+#define ASP_PIRQE (1 << 4) /* Pen interrupt enable */
-+#define ASP_VDAFEE (1 << 3) /* VDAC FIFO empty interrupt */
-+#define ASP_VADFFE (1 << 2) /* VADC FIFO full interrupt */
-+#define ASP_PFFE (1 << 1) /* Pen FIFO full interrupt */
-+#define ASP_PDRE (1 << 0) /* Pen data ready interrupt */
-+
-+/* ASP interrupt/error status register bits */
-+#define ASP_PUP (1 << 10) /* Pen up XXX undocumented */
-+#define ASP_BGR (1 << 9) /* Bandgap ready */
-+#define ASP_VOV (1 << 8) /* Voice sample data overflow */
-+#define ASP_POV (1 << 7) /* Pen sample data overflow */
-+#define ASP_PEN (1 << 6) /* Pen interrupt */
-+#define ASP_VDAFF (1 << 5) /* VDAC FIFO full */
-+#define ASP_VDAFE (1 << 4) /* VDAC FIFO empty */
-+#define ASP_VADFF (1 << 3) /* VADC FIFO full */
-+#define ASP_VADDR (1 << 2) /* VADC data ready */
-+#define ASP_PFF (1 << 1) /* Pen sample FIFO full */
-+#define ASP_PDR (1 << 0) /* Pen data ready */
-+
-+/* ASP Clock divide register */
-+#define ASP_PADC_CLK_MASK (0x0000001F)
-+#define ASP_PADC_CLK_SCALE (0)
-+#define ASP_VADC_CLK_MASK (0x000003E0)
-+#define ASP_VADC_CLK_SCALE (5)
-+#define ASP_VDAC_CLK_MASK (0x00003C00)
-+#define ASP_VDAC_CLK_SCALE (10)
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/l3/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,21 @@
-+#
-+# L3 bus configuration
-+#
-+mainmenu_option next_comment
-+comment 'L3 serial bus support'
-+
-+tristate 'L3 support' CONFIG_L3
-+dep_bool ' L3 bit-banging interfaces' CONFIG_L3_ALGOBIT $CONFIG_L3
-+dep_bool ' SA11x0 GPIO adapter' CONFIG_L3_BIT_SA1100_GPIO $CONFIG_L3_ALGOBIT $CONFIG_ARCH_SA1100
-+
-+comment 'Other L3 adapters'
-+dep_bool ' SA1111 adapter' CONFIG_L3_SA1111 $CONFIG_L3
-+endmenu
-+
-+# i2c must come before this
-+if [ "$CONFIG_L3_BIT_SA1100_GPIO" = "y" -o \
-+ "$CONFIG_I2C_BIT_SA1100_GPIO" = "y" ]; then
-+ define_bool CONFIG_BIT_SA1100_GPIO y
-+else
-+ define_bool CONFIG_BIT_SA1100_GPIO n
-+fi
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/l3/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,23 @@
-+#
-+# Makefile for the L3 bus driver.
-+#
-+
-+O_TARGET := l3.o
-+
-+export-objs := l3-core.o l3-algo-bit.o
-+l3-y :=
-+l3-n :=
-+l3-drv-y :=
-+l3-drv-n :=
-+
-+# Link order:
-+# (core, adapters, algorithms, drivers) then clients
-+
-+l3-$(CONFIG_L3_ALGOBIT) += l3-algo-bit.o
-+l3-$(CONFIG_BIT_SA1100_GPIO) += l3-bit-sa1100.o
-+l3-$(CONFIG_L3_SA1111) += l3-sa1111.o
-+
-+obj-$(CONFIG_L3) += l3-core.o $(l3-y) $(l3-drv-y)
-+
-+include $(TOPDIR)/Rules.make
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/l3/l3-algo-bit.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,175 @@
-+/*
-+ * L3 bus algorithm module.
-+ *
-+ * Copyright (C) 2001 Russell King, 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 version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Note that L3 buses can share the same pins as I2C buses, so we must
-+ * _not_ generate an I2C start condition. An I2C start condition is
-+ * defined as a high-to-low transition of the data line while the clock
-+ * is high. Therefore, we must only change the data line while the
-+ * clock is low.
-+ */
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+#include <linux/l3/l3.h>
-+#include <linux/l3/algo-bit.h>
-+
-+#define setdat(adap,val) adap->setdat(adap->data, val)
-+#define setclk(adap,val) adap->setclk(adap->data, val)
-+#define setmode(adap,val) adap->setmode(adap->data, val)
-+#define setdatin(adap) adap->setdir(adap->data, 1)
-+#define setdatout(adap) adap->setdir(adap->data, 0)
-+#define getdat(adap) adap->getdat(adap->data)
-+
-+/*
-+ * Send one byte of data to the chip. Data is latched into the chip on
-+ * the rising edge of the clock.
-+ */
-+static void sendbyte(struct l3_algo_bit_data *adap, unsigned int byte)
-+{
-+ int i;
-+
-+ for (i = 0; i < 8; i++) {
-+ setclk(adap, 0);
-+ udelay(adap->data_hold);
-+ setdat(adap, byte & 1);
-+ udelay(adap->data_setup);
-+ setclk(adap, 1);
-+ udelay(adap->clock_high);
-+ byte >>= 1;
-+ }
-+}
-+
-+/*
-+ * Send a set of bytes to the chip. We need to pulse the MODE line
-+ * between each byte, but never at the start nor at the end of the
-+ * transfer.
-+ */
-+static void sendbytes(struct l3_algo_bit_data *adap, const char *buf, int len)
-+{
-+ int i;
-+
-+ for (i = 0; i < len; i++) {
-+ if (i) {
-+ udelay(adap->mode_hold);
-+ setmode(adap, 0);
-+ udelay(adap->mode);
-+ }
-+ setmode(adap, 1);
-+ udelay(adap->mode_setup);
-+ sendbyte(adap, buf[i]);
-+ }
-+}
-+
-+/*
-+ * Read one byte of data from the chip. Data is latched into the chip on
-+ * the rising edge of the clock.
-+ */
-+static unsigned int readbyte(struct l3_algo_bit_data *adap)
-+{
-+ unsigned int byte = 0;
-+ int i;
-+
-+ for (i = 0; i < 8; i++) {
-+ setclk(adap, 0);
-+ udelay(adap->data_hold + adap->data_setup);
-+ setclk(adap, 1);
-+ if (getdat(adap))
-+ byte |= 1 << i;
-+ udelay(adap->clock_high);
-+ }
-+
-+ return byte;
-+}
-+
-+/*
-+ * Read a set of bytes from the chip. We need to pulse the MODE line
-+ * between each byte, but never at the start nor at the end of the
-+ * transfer.
-+ */
-+static void readbytes(struct l3_algo_bit_data *adap, char *buf, int len)
-+{
-+ int i;
-+
-+ for (i = 0; i < len; i++) {
-+ if (i) {
-+ udelay(adap->mode_hold);
-+ setmode(adap, 0);
-+ }
-+ setmode(adap, 1);
-+ udelay(adap->mode_setup);
-+ buf[i] = readbyte(adap);
-+ }
-+}
-+
-+static int l3_xfer(struct l3_adapter *l3_adap, struct l3_msg msgs[], int num)
-+{
-+ struct l3_algo_bit_data *adap = l3_adap->algo_data;
-+ int i;
-+
-+ /*
-+ * If we share an I2C bus, ensure that it is in STOP mode
-+ */
-+ setclk(adap, 1);
-+ setdat(adap, 1);
-+ setmode(adap, 1);
-+ setdatout(adap);
-+ udelay(adap->mode);
-+
-+ for (i = 0; i < num; i++) {
-+ struct l3_msg *pmsg = &msgs[i];
-+
-+ if (!(pmsg->flags & L3_M_NOADDR)) {
-+ setmode(adap, 0);
-+ udelay(adap->mode_setup);
-+ sendbyte(adap, pmsg->addr);
-+ udelay(adap->mode_hold);
-+ }
-+
-+ if (pmsg->flags & L3_M_RD) {
-+ setdatin(adap);
-+ readbytes(adap, pmsg->buf, pmsg->len);
-+ } else {
-+ setdatout(adap);
-+ sendbytes(adap, pmsg->buf, pmsg->len);
-+ }
-+ }
-+
-+ /*
-+ * Ensure that we leave the bus in I2C stop mode.
-+ */
-+ setclk(adap, 1);
-+ setdat(adap, 1);
-+ setmode(adap, 0);
-+ setdatin(adap);
-+
-+ return num;
-+}
-+
-+static struct l3_algorithm l3_bit_algo = {
-+ name: "L3 bit-shift algorithm",
-+ xfer: l3_xfer,
-+};
-+
-+int l3_bit_add_bus(struct l3_adapter *adap)
-+{
-+ adap->algo = &l3_bit_algo;
-+ return l3_add_adapter(adap);
-+}
-+
-+int l3_bit_del_bus(struct l3_adapter *adap)
-+{
-+ return l3_del_adapter(adap);
-+}
-+
-+EXPORT_SYMBOL(l3_bit_add_bus);
-+EXPORT_SYMBOL(l3_bit_del_bus);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/l3/l3-bit-sa1100.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,277 @@
-+/*
-+ * linux/drivers/l3/l3-bit-sa1100.c
-+ *
-+ * Copyright (C) 2001 Russell King
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * This is a combined I2C and L3 bus driver.
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/ioport.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/i2c-algo-bit.h>
-+#include <linux/l3/algo-bit.h>
-+
-+#include <asm/system.h>
-+#include <asm/hardware.h>
-+#include <asm/mach-types.h>
-+#include <asm/arch/assabet.h>
-+
-+#define NAME "l3-bit-sa1100-gpio"
-+
-+struct bit_data {
-+ unsigned int sda;
-+ unsigned int scl;
-+ unsigned int l3_mode;
-+};
-+
-+static int getsda(void *data)
-+{
-+ struct bit_data *bits = data;
-+
-+ return GPLR & bits->sda;
-+}
-+
-+#ifdef CONFIG_I2C_BIT_SA1100_GPIO
-+static void i2c_setsda(void *data, int state)
-+{
-+ struct bit_data *bits = data;
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+ if (state)
-+ GPDR &= ~bits->sda;
-+ else {
-+ GPCR = bits->sda;
-+ GPDR |= bits->sda;
-+ }
-+ local_irq_restore(flags);
-+}
-+
-+static void i2c_setscl(void *data, int state)
-+{
-+ struct bit_data *bits = data;
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+ if (state)
-+ GPDR &= ~bits->scl;
-+ else {
-+ GPCR = bits->scl;
-+ GPDR |= bits->scl;
-+ }
-+ local_irq_restore(flags);
-+}
-+
-+static int i2c_getscl(void *data)
-+{
-+ struct bit_data *bits = data;
-+
-+ return GPLR & bits->scl;
-+}
-+
-+static struct i2c_algo_bit_data i2c_bit_data = {
-+ setsda: i2c_setsda,
-+ setscl: i2c_setscl,
-+ getsda: getsda,
-+ getscl: i2c_getscl,
-+ udelay: 10,
-+ mdelay: 10,
-+ timeout: 100,
-+};
-+
-+static struct i2c_adapter i2c_adapter = {
-+ name: NAME,
-+ algo_data: &i2c_bit_data,
-+// inc_use: i2c_inc_use,
-+// dec_use: i2c_dec_use,
-+};
-+
-+#define LOCK &i2c_adapter.lock
-+
-+static int __init i2c_init(struct bit_data *bits)
-+{
-+ i2c_bit_data.data = bits;
-+ return i2c_bit_add_bus(&i2c_adapter);
-+}
-+
-+static void i2c_exit(void)
-+{
-+ i2c_bit_del_bus(&i2c_adapter);
-+}
-+
-+#else
-+static DECLARE_MUTEX(l3_lock);
-+#define LOCK &l3_lock
-+#define i2c_init(bits) (0)
-+#define i2c_exit() do { } while (0)
-+#endif
-+
-+#ifdef CONFIG_L3_BIT_SA1100_GPIO
-+/*
-+ * iPAQs need the clock line driven hard high and low.
-+ */
-+static void l3_setscl(void *data, int state)
-+{
-+ struct bit_data *bits = data;
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+ if (state)
-+ GPSR = bits->scl;
-+ else
-+ GPCR = bits->scl;
-+ GPDR |= bits->scl;
-+ local_irq_restore(flags);
-+}
-+
-+static void l3_setsda(void *data, int state)
-+{
-+ struct bit_data *bits = data;
-+
-+ if (state)
-+ GPSR = bits->sda;
-+ else
-+ GPCR = bits->sda;
-+}
-+
-+static void l3_setdir(void *data, int in)
-+{
-+ struct bit_data *bits = data;
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+ if (in)
-+ GPDR &= ~bits->sda;
-+ else
-+ GPDR |= bits->sda;
-+ local_irq_restore(flags);
-+}
-+
-+static void l3_setmode(void *data, int state)
-+{
-+ struct bit_data *bits = data;
-+
-+ if (state)
-+ GPSR = bits->l3_mode;
-+ else
-+ GPCR = bits->l3_mode;
-+}
-+
-+static struct l3_algo_bit_data l3_bit_data = {
-+ data: NULL,
-+ setdat: l3_setsda,
-+ setclk: l3_setscl,
-+ setmode: l3_setmode,
-+ setdir: l3_setdir,
-+ getdat: getsda,
-+ data_hold: 1,
-+ data_setup: 1,
-+ clock_high: 1,
-+ mode_hold: 1,
-+ mode_setup: 1,
-+};
-+
-+static struct l3_adapter l3_adapter = {
-+ owner: THIS_MODULE,
-+ name: NAME,
-+ algo_data: &l3_bit_data,
-+ lock: LOCK,
-+};
-+
-+static int __init l3_init(struct bit_data *bits)
-+{
-+ l3_bit_data.data = bits;
-+ return l3_bit_add_bus(&l3_adapter);
-+}
-+
-+static void __exit l3_exit(void)
-+{
-+ l3_bit_del_bus(&l3_adapter);
-+}
-+#else
-+#define l3_init(bits) (0)
-+#define l3_exit() do { } while (0)
-+#endif
-+
-+static struct bit_data bit_data;
-+
-+static int __init bus_init(void)
-+{
-+ struct bit_data *bit = &bit_data;
-+ unsigned long flags;
-+ int ret;
-+
-+ if (machine_is_assabet() || machine_is_pangolin()) {
-+ bit->sda = GPIO_GPIO15;
-+ bit->scl = GPIO_GPIO18;
-+ bit->l3_mode = GPIO_GPIO17;
-+ }
-+
-+#if defined(CONFIG_SA1100_H3600) || defined(CONFIG_SA1100_H3100)
-+ if (machine_is_h3600() || machine_is_h3100()) {
-+ bit->sda = GPIO_H3600_L3_DATA;
-+ bit->scl = GPIO_H3600_L3_CLOCK;
-+ bit->l3_mode = GPIO_H3600_L3_MODE;
-+ }
-+#endif
-+
-+#ifdef CONFIG_SA1100_STORK
-+ if (machine_is_stork()) {
-+ bit->sda = GPIO_STORK_L3_I2C_SDA;
-+ bit->scl = GPIO_STORK_L3_I2C_SCL;
-+ bit->l3_mode = GPIO_STORK_L3_MODE;
-+ }
-+#endif
-+
-+ if (!bit->sda)
-+ return -ENODEV;
-+
-+ /*
-+ * Default level for L3 mode is low.
-+ * We set SCL and SDA high (i2c idle state).
-+ */
-+ local_irq_save(flags);
-+ GPDR &= ~(bit->scl | bit->sda);
-+ GPCR = bit->l3_mode | bit->scl | bit->sda;
-+ GPDR |= bit->l3_mode;
-+ local_irq_restore(flags);
-+
-+ if (machine_is_assabet()) {
-+ /*
-+ * Release reset on UCB1300, ADI7171 and UDA1341. We
-+ * need to do this here so that we can communicate on
-+ * the I2C/L3 buses.
-+ */
-+ ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
-+ mdelay(1);
-+ ASSABET_BCR_clear(ASSABET_BCR_CODEC_RST);
-+ mdelay(1);
-+ ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
-+ }
-+
-+ ret = i2c_init(bit);
-+ if (ret == 0 && bit->l3_mode) {
-+ ret = l3_init(bit);
-+ if (ret)
-+ i2c_exit();
-+ }
-+
-+ return ret;
-+}
-+
-+static void __exit bus_exit(void)
-+{
-+ l3_exit();
-+ i2c_exit();
-+}
-+
-+module_init(bus_init);
-+module_exit(bus_exit);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/l3/l3-core.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,377 @@
-+/*
-+ * linux/drivers/l3/l3-core.c
-+ *
-+ * Copyright (C) 2001 Russell King
-+ *
-+ * General structure taken from i2c-core.c by Simon G. Vogl
-+ *
-+ * 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.
-+ *
-+ * See linux/Documentation/l3 for further documentation.
-+ */
-+#include <linux/module.h>
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/errno.h>
-+#include <linux/slab.h>
-+#include <linux/proc_fs.h>
-+#include <linux/kmod.h>
-+#include <linux/init.h>
-+#include <linux/l3/l3.h>
-+
-+static DECLARE_MUTEX(adapter_lock);
-+static LIST_HEAD(adapter_list);
-+
-+static DECLARE_MUTEX(driver_lock);
-+static LIST_HEAD(driver_list);
-+
-+/**
-+ * l3_add_adapter - register a new L3 bus adapter
-+ * @adap: l3_adapter structure for the registering adapter
-+ *
-+ * Make the adapter available for use by clients using name adap->name.
-+ * The adap->adapters list is initialised by this function.
-+ *
-+ * Returns 0;
-+ */
-+int l3_add_adapter(struct l3_adapter *adap)
-+{
-+ INIT_LIST_HEAD(&adap->clients);
-+ down(&adapter_lock);
-+ list_add(&adap->adapters, &adapter_list);
-+ up(&adapter_lock);
-+ return 0;
-+}
-+
-+/**
-+ * l3_del_adapter - unregister a L3 bus adapter
-+ * @adap: l3_adapter structure to unregister
-+ *
-+ * Remove an adapter from the list of available L3 Bus adapters.
-+ *
-+ * Returns 0;
-+ */
-+int l3_del_adapter(struct l3_adapter *adap)
-+{
-+ down(&adapter_lock);
-+ list_del(&adap->adapters);
-+ up(&adapter_lock);
-+ return 0;
-+}
-+
-+static struct l3_adapter *__l3_get_adapter(const char *name)
-+{
-+ struct list_head *l;
-+
-+ list_for_each(l, &adapter_list) {
-+ struct l3_adapter *adap = list_entry(l, struct l3_adapter, adapters);
-+
-+ if (strcmp(adap->name, name) == 0)
-+ return adap;
-+ }
-+
-+ return NULL;
-+}
-+
-+/**
-+ * l3_get_adapter - get a reference to an adapter
-+ * @name: driver name
-+ *
-+ * Obtain a l3_adapter structure for the specified adapter. If the adapter
-+ * is not currently load, then load it. The adapter will be locked in core
-+ * until all references are released via l3_put_adapter.
-+ */
-+struct l3_adapter *l3_get_adapter(const char *name)
-+{
-+ struct l3_adapter *adap;
-+ int try;
-+
-+ for (try = 0; try < 2; try ++) {
-+ down(&adapter_lock);
-+ adap = __l3_get_adapter(name);
-+ if (adap && !try_inc_mod_count(adap->owner))
-+ adap = NULL;
-+ up(&adapter_lock);
-+
-+ if (adap)
-+ break;
-+
-+ if (try == 0)
-+ request_module(name);
-+ }
-+
-+ return adap;
-+}
-+
-+/**
-+ * l3_put_adapter - release a reference to an adapter
-+ * @adap: driver to release reference
-+ *
-+ * Indicate to the L3 core that you no longer require the adapter reference.
-+ * The adapter module may be unloaded when there are no references to its
-+ * data structure.
-+ *
-+ * You must not use the reference after calling this function.
-+ */
-+void l3_put_adapter(struct l3_adapter *adap)
-+{
-+ if (adap && adap->owner)
-+ __MOD_DEC_USE_COUNT(adap->owner);
-+}
-+
-+/**
-+ * l3_add_driver - register a new L3 device driver
-+ * @driver - driver structure to make available
-+ *
-+ * Make the driver available for use by clients using name driver->name.
-+ * The driver->drivers list is initialised by this function.
-+ *
-+ * Returns 0;
-+ */
-+int l3_add_driver(struct l3_driver *driver)
-+{
-+ down(&driver_lock);
-+ list_add(&driver->drivers, &driver_list);
-+ up(&driver_lock);
-+ return 0;
-+}
-+
-+/**
-+ * l3_del_driver - unregister a L3 device driver
-+ * @driver: driver to remove
-+ *
-+ * Remove an driver from the list of available L3 Bus device drivers.
-+ *
-+ * Returns 0;
-+ */
-+int l3_del_driver(struct l3_driver *driver)
-+{
-+ down(&driver_lock);
-+ list_del(&driver->drivers);
-+ up(&driver_lock);
-+ return 0;
-+}
-+
-+static struct l3_driver *__l3_get_driver(const char *name)
-+{
-+ struct list_head *l;
-+
-+ list_for_each(l, &driver_list) {
-+ struct l3_driver *drv = list_entry(l, struct l3_driver, drivers);
-+
-+ if (strcmp(drv->name, name) == 0)
-+ return drv;
-+ }
-+
-+ return NULL;
-+}
-+
-+/**
-+ * l3_get_driver - get a reference to a driver
-+ * @name: driver name
-+ *
-+ * Obtain a l3_driver structure for the specified driver. If the driver is
-+ * not currently load, then load it. The driver will be locked in core
-+ * until all references are released via l3_put_driver.
-+ */
-+struct l3_driver *l3_get_driver(const char *name)
-+{
-+ struct l3_driver *drv;
-+ int try;
-+
-+ for (try = 0; try < 2; try ++) {
-+ down(&adapter_lock);
-+ drv = __l3_get_driver(name);
-+ if (drv && !try_inc_mod_count(drv->owner))
-+ drv = NULL;
-+ up(&adapter_lock);
-+
-+ if (drv)
-+ break;
-+
-+ if (try == 0)
-+ request_module(name);
-+ }
-+
-+ return drv;
-+}
-+
-+/**
-+ * l3_put_driver - release a reference to a driver
-+ * @drv: driver to release reference
-+ *
-+ * Indicate to the L3 core that you no longer require the driver reference.
-+ * The driver module may be unloaded when there are no references to its
-+ * data structure.
-+ *
-+ * You must not use the reference after calling this function.
-+ */
-+void l3_put_driver(struct l3_driver *drv)
-+{
-+ if (drv && drv->owner)
-+ __MOD_DEC_USE_COUNT(drv->owner);
-+}
-+
-+/**
-+ * l3_attach_client - attach a client to an adapter and driver
-+ * @client: client structure to attach
-+ * @adap: adapter (module) name
-+ * @drv: driver (module) name
-+ *
-+ * Attempt to attach a client (a user of a device driver) to a particular
-+ * driver and adapter. If the specified driver or adapter aren't registered,
-+ * request_module is used to load the relevant modules.
-+ *
-+ * Returns 0 on success, or negative error code.
-+ */
-+int l3_attach_client(struct l3_client *client, const char *adap, const char *drv)
-+{
-+ struct l3_adapter *adapter = l3_get_adapter(adap);
-+ struct l3_driver *driver = l3_get_driver(drv);
-+ int ret = -ENOENT;
-+
-+ if (!adapter)
-+ printk(KERN_ERR "%s: unable to get adapter: %s\n",
-+ __FUNCTION__, adap);
-+ if (!driver)
-+ printk(KERN_ERR "%s: unable to get driver: %s\n",
-+ __FUNCTION__, drv);
-+
-+ if (adapter && driver) {
-+ ret = 0;
-+
-+ client->adapter = adapter;
-+ client->driver = driver;
-+
-+ list_add(&client->__adap, &adapter->clients);
-+
-+ if (driver->attach_client)
-+ ret = driver->attach_client(client);
-+ }
-+
-+ if (ret) {
-+ l3_put_driver(driver);
-+ l3_put_adapter(adapter);
-+ }
-+ return ret;
-+}
-+
-+/**
-+ * l3_detach_client - detach a client from an adapter and driver
-+ * @client: client structure to detach
-+ *
-+ * Detach the client from the adapter and driver.
-+ */
-+int l3_detach_client(struct l3_client *client)
-+{
-+ struct l3_adapter *adapter = client->adapter;
-+ struct l3_driver *driver = client->driver;
-+
-+ driver->detach_client(client);
-+
-+ client->adapter = NULL;
-+ client->driver = NULL;
-+
-+ l3_put_driver(driver);
-+ l3_put_adapter(adapter);
-+
-+ list_del(&client->__adap);
-+
-+ return 0;
-+}
-+
-+/**
-+ * l3_transfer - transfer information on an L3 bus
-+ * @adap: adapter structure to perform transfer on
-+ * @msgs: array of l3_msg structures describing transfer
-+ * @num: number of l3_msg structures
-+ *
-+ * Transfer the specified messages to/from a device on the L3 bus.
-+ *
-+ * Returns number of messages successfully transferred, otherwise negative
-+ * error code.
-+ */
-+int l3_transfer(struct l3_adapter *adap, struct l3_msg msgs[], int num)
-+{
-+ int ret = -ENOSYS;
-+
-+ if (adap->algo->xfer) {
-+ down(adap->lock);
-+ ret = adap->algo->xfer(adap, msgs, num);
-+ up(adap->lock);
-+ }
-+ return ret;
-+}
-+
-+/**
-+ * l3_write - send data to a device on an L3 bus
-+ * @client: registered client structure
-+ * @addr: L3 bus address
-+ * @buf: buffer for bytes to send
-+ * @len: number of bytes to send
-+ *
-+ * Send len bytes pointed to by buf to device address addr on the L3 bus
-+ * described by client.
-+ *
-+ * Returns the number of bytes transferred, or negative error code.
-+ */
-+int l3_write(struct l3_client *client, int addr, const char *buf, int len)
-+{
-+ struct l3_adapter *adap = client->adapter;
-+ struct l3_msg msg;
-+ int ret;
-+
-+ msg.addr = addr;
-+ msg.flags = 0;
-+ msg.buf = (char *)buf;
-+ msg.len = len;
-+
-+ ret = l3_transfer(adap, &msg, 1);
-+ return ret == 1 ? len : ret;
-+}
-+
-+/**
-+ * l3_read - receive data from a device on an L3 bus
-+ * @client: registered client structure
-+ * @addr: L3 bus address
-+ * @buf: buffer for bytes to receive
-+ * @len: number of bytes to receive
-+ *
-+ * Receive len bytes from device address addr on the L3 bus described by
-+ * client to a buffer pointed to by buf.
-+ *
-+ * Returns the number of bytes transferred, or negative error code.
-+ */
-+int l3_read(struct l3_client *client, int addr, char *buf, int len)
-+{
-+ struct l3_adapter *adap = client->adapter;
-+ struct l3_msg msg;
-+ int ret;
-+
-+ msg.addr = addr;
-+ msg.flags = L3_M_RD;
-+ msg.buf = buf;
-+ msg.len = len;
-+
-+ ret = l3_transfer(adap, &msg, 1);
-+ return ret == 1 ? len : ret;
-+}
-+
-+EXPORT_SYMBOL(l3_add_adapter);
-+EXPORT_SYMBOL(l3_del_adapter);
-+EXPORT_SYMBOL(l3_get_adapter);
-+EXPORT_SYMBOL(l3_put_adapter);
-+
-+EXPORT_SYMBOL(l3_add_driver);
-+EXPORT_SYMBOL(l3_del_driver);
-+EXPORT_SYMBOL(l3_get_driver);
-+EXPORT_SYMBOL(l3_put_driver);
-+
-+EXPORT_SYMBOL(l3_attach_client);
-+EXPORT_SYMBOL(l3_detach_client);
-+
-+EXPORT_SYMBOL(l3_transfer);
-+EXPORT_SYMBOL(l3_write);
-+EXPORT_SYMBOL(l3_read);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/l3/l3-sa1111.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,118 @@
-+/*
-+ * L3 SA1111 algorithm/adapter module.
-+ *
-+ * By Russell King,
-+ * gratuitously ripped from sa1111-uda1341.c by John Dorsey.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/errno.h>
-+#include <linux/l3/l3.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/semaphore.h>
-+#include <asm/mach-types.h>
-+#include <asm/arch/assabet.h>
-+#include <asm/hardware/sa1111.h>
-+
-+static inline unsigned char l3_sa1111_recv_byte(unsigned char addr)
-+{
-+ unsigned char dat;
-+
-+ L3_CAR = addr;
-+ while ((SASR0 & SASR0_L3RD) == 0)
-+ mdelay(1);
-+ dat = L3_CDR;
-+ SASCR = SASCR_RDD;
-+ return dat;
-+}
-+
-+static void l3_sa1111_recv_msg(struct l3_msg *msg)
-+{
-+ int len = msg->len;
-+ char *p = msg->buf;
-+
-+ if (len > 1) {
-+ SACR1 |= SACR1_L3MB;
-+ while ((len--) > 1)
-+ *p++ = l3_sa1111_recv_byte(msg->addr);
-+ }
-+ SACR1 &= ~SACR1_L3MB;
-+ *p = l3_sa1111_recv_byte(msg->addr);
-+}
-+
-+static inline void l3_sa1111_send_byte(unsigned char addr, unsigned char dat)
-+{
-+ L3_CAR = addr;
-+ L3_CDR = dat;
-+ while ((SASR0 & SASR0_L3WD) == 0)
-+ mdelay(1);
-+ SASCR = SASCR_DTS;
-+}
-+
-+static void l3_sa1111_send_msg(struct l3_msg *msg)
-+{
-+ int len = msg->len;
-+ char *p = msg->buf;
-+
-+ if (len > 1) {
-+ SACR1 |= SACR1_L3MB;
-+ while ((len--) > 1)
-+ l3_sa1111_send_byte(msg->addr, *p++);
-+ }
-+ SACR1 &= ~SACR1_L3MB;
-+ l3_sa1111_send_byte(msg->addr, *p);
-+}
-+
-+static int l3_sa1111_xfer(struct l3_adapter *adap, struct l3_msg msgs[], int num)
-+{
-+ int i;
-+
-+ for (i = 0; i < num; i++) {
-+ struct l3_msg *pmsg = &msgs[i];
-+
-+ if (pmsg->flags & L3_M_RD)
-+ l3_sa1111_recv_msg(pmsg);
-+ else
-+ l3_sa1111_send_msg(pmsg);
-+ }
-+
-+ return num;
-+}
-+
-+static struct l3_algorithm l3_sa1111_algo = {
-+ name: "L3 SA1111 algorithm",
-+ xfer: l3_sa1111_xfer,
-+};
-+
-+static DECLARE_MUTEX(sa1111_lock);
-+
-+static struct l3_adapter l3_sa1111_adapter = {
-+ owner: THIS_MODULE,
-+ name: "l3-sa1111",
-+ algo: &l3_sa1111_algo,
-+ lock: &sa1111_lock,
-+};
-+
-+static int __init l3_sa1111_init(void)
-+{
-+ int ret = -ENODEV;
-+ if ((machine_is_assabet() && machine_has_neponset()) ||
-+ machine_is_jornada720() || machine_is_accelent_sa() ||
-+ machine_is_badge4())
-+ ret = l3_add_adapter(&l3_sa1111_adapter);
-+ return ret;
-+}
-+
-+static void __exit l3_sa1111_exit(void)
-+{
-+ l3_del_adapter(&l3_sa1111_adapter);
-+}
-+
-+module_init(l3_sa1111_init);
-+module_exit(l3_sa1111_exit);
---- linux-2.4.25/drivers/media/video/Config.in~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/media/video/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -52,5 +52,8 @@
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- dep_tristate ' Sony Vaio Picturebook Motion Eye Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_MEYE $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_SONYPI
- fi
-+# unfortunately, this depends on having CONFIG_FB_CYBER2000
-+# set as well - we hook off of the VGA driver
-+dep_tristate ' NetWinder Video for Linux (EXPERIMENTAL)' CONFIG_VIDEO_CYBERPRO $CONFIG_VIDEO_DEV $CONFIG_EXPERIMENTAL $CONFIG_ARCH_NETWINDER
-
- endmenu
---- linux-2.4.25/drivers/media/video/Makefile~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/media/video/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -16,7 +16,7 @@
- obj-n :=
- obj- :=
-
--SUB_DIRS :=
-+SUB_DIRS :=
- MOD_SUB_DIRS := $(SUB_DIRS)
- ALL_SUB_DIRS := $(SUB_DIRS)
-
-@@ -47,7 +47,8 @@
- obj-$(CONFIG_VIDEO_ZORAN) += zr36067.o i2c-old.o
- obj-$(CONFIG_VIDEO_ZORAN_BUZ) += saa7111.o saa7185.o
- obj-$(CONFIG_VIDEO_ZORAN_DC10) += saa7110.o adv7175.o
--obj-$(CONFIG_VIDEO_ZORAN_LML33) += bt819.o bt856.o
-+obj-$(CONFIG_VIDEO_CYBERPRO) += cyberpro.o i2c-old.o saa7111.o
-+obj-$(CONFIG_VIDEO_LML33) += bt856.o bt819.o
- obj-$(CONFIG_VIDEO_PMS) += pms.o
- obj-$(CONFIG_VIDEO_PLANB) += planb.o
- obj-$(CONFIG_VIDEO_VINO) += saa7191.o indycam.o vino.o
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/media/video/cyberpro.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,2091 @@
-+/*
-+ * CyberPro 2000 video capture driver for the Rebel.com NetWinder
-+ *
-+ * (C) 1999-2000 Russell King
-+ *
-+ * Re-written from Rebel.com's vidcap driver.
-+ *
-+ * Architecture
-+ * ------------
-+ * The NetWinder video capture consists of a SAA7111 video decoder chip
-+ * connected to the CyberPro feature bus. The video data is captured to
-+ * the VGA memory, where the CyberPro can overlay (by chromakeying) the
-+ * data onto the VGA display.
-+ *
-+ * The CyberPro also has some nifty features, including a second overlay
-+ * and picture in picture mode. We do not currently use these features.
-+ *
-+ * Power Saving
-+ * ------------
-+ * Please note that rev.5 NetWinders have the ability to hold the SAA7111
-+ * decoder chip into reset, which saves power. The only time at which
-+ * this is done is when the driver is unloaded, which implies that this
-+ * is compiled as a module.
-+ *
-+ * In this case, you will want the kernel to automatically load this
-+ * driver when required. Place the following line in /etc/modules.conf
-+ * to enable this:
-+ *
-+ * alias char-major-81-0 cyberpro
-+ *
-+ * The relevant modules will be automatically loaded by modprobe on a
-+ * as and when needed basis.
-+ *
-+ * Capture resolution
-+ * ------------------
-+ * The maximum useful capture resolution is:
-+ * 625-line UK: 716x576
-+ * 525-line US: ?
-+ *
-+ * Bugs
-+ * ----
-+ * 1. The CyberPro chip seems to be prone to randomly scribbling over VGA
-+ * memory [hopefully fixed with new capture enable/freeze stuff]
-+ * 2. read()ing pauses video capture, and sometimes triggers bug 1.
-+ * 3. mmap() is not supported (requires BM-DMA - see bug 4)
-+ * 4. Really, we want to do scatter BM-DMA. Is the CyberPro capable of this?
-+ * The Cyberpro seems to randomly scribble to various PCI addresses if you
-+ * transfer >16 words.
-+ * 5. We shouldn't ignore O_NONBLOCK when reading a frame.
-+ * 6. The incoming stream on the NetWinder is CCIR656, which is YUV422.
-+ * CyberPro docs also call the format we capture and overlay "YUV422",
-+ * but we actually seem to have Y, U, Y, V bytes (is this YUYV format?)
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/videodev.h>
-+#include <linux/video_decoder.h>
-+#include <linux/mm.h>
-+#include <linux/i2c-old.h>
-+#include <linux/spinlock.h>
-+#include <linux/slab.h>
-+#include <linux/vmalloc.h>
-+#include <linux/delay.h>
-+#include <linux/sched.h>
-+#include <linux/kmod.h>
-+#include <linux/pci.h>
-+#include <linux/init.h>
-+
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/pgtable.h>
-+#include <asm/pgalloc.h>
-+
-+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-+MODULE_DESCRIPTION("CyberPro v4l video grabber");
-+MODULE_LICENSE("GPL");
-+
-+#include "../../video/cyber2000fb.h"
-+
-+/*
-+ * These enable various experimental features. Most of these
-+ * are just plain broken or just don't work at the moment.
-+ */
-+/*
-+ * Enable this if you want mmap() access. (see bug 4)
-+ */
-+#undef USE_MMAP
-+
-+/*
-+ * Enable this if you want mmio access. (slow)
-+ */
-+#define USE_MMIO
-+
-+/*
-+ * The V4L API is unclear whether VIDIOCSCAPTURE call is allowed while
-+ * capture is running. The default is to disallow the call.
-+ *
-+ * Define this if you do want to allow the call while capture is active.
-+ */
-+#undef ALLOW_SCAPTURE_WHILE_CAP
-+
-+/*
-+ * We capture two frames
-+ */
-+#define NR_FRAMES 2
-+
-+/*
-+ * One frame of video is 202 pages, assuming YUV422 format, 716x576
-+ */
-+#define NR_PAGES 202
-+
-+struct src_info {
-+ unsigned int offset; /* offset of source data */
-+ unsigned int x; /* source x */
-+ unsigned int y; /* source y */
-+ unsigned int width; /* source width */
-+ unsigned int height; /* source height */
-+ unsigned int format; /* source format */
-+};
-+
-+struct dst_info {
-+ unsigned int x; /* destination x */
-+ unsigned int y; /* destination y */
-+ unsigned int width; /* destination width */
-+ unsigned int height; /* destination height */
-+ unsigned int chromakey; /* chromakey */
-+ unsigned int flags; /* flags (eg, chromakey enable) */
-+};
-+
-+struct cyberpro_vidinfo;
-+
-+struct win_info {
-+ void (*init)(struct cyberpro_vidinfo *dp, struct win_info *wi);
-+ void (*set_src)(struct cyberpro_vidinfo *dp, struct win_info *wi);
-+ void (*set_win)(struct cyberpro_vidinfo *dp, struct win_info *wi);
-+ void (*ctl)(struct cyberpro_vidinfo *dp, struct win_info *wi, int on_off);
-+
-+ /* public */
-+ struct src_info src;
-+ struct dst_info dst;
-+
-+ /* private */
-+ unsigned short vid_fifo_ctl;
-+ unsigned char vid_fmt;
-+ unsigned char vid_disp_ctl1;
-+ unsigned char vid_fifo_ctl1;
-+ unsigned char vid_misc_ctl1;
-+};
-+
-+struct framebuf {
-+ unsigned int offset; /* mmap offset for this frame */
-+ unsigned int status;
-+#define FRAME_FREE 0
-+#define FRAME_DONE 1
-+#define FRAME_WAITING 2
-+#define FRAME_GRABBING 3
-+
-+ /*
-+ * Bus-Master DMA stuff. Note that we should
-+ * probably use the kiovec stuff instead.
-+ */
-+ unsigned long bus_addr[NR_PAGES]; /* list of pages */
-+ struct page *pages[NR_PAGES];
-+ void *buffer;
-+ int dbg;
-+};
-+
-+struct cyberpro_vidinfo {
-+ struct video_device *dev;
-+ struct i2c_bus *bus;
-+ struct cyberpro_info info; /* host information */
-+ unsigned char *regs;
-+ unsigned int irq; /* PCI interrupt number */
-+
-+ /* hardware configuration */
-+ unsigned int stream_fmt; /* format of stream from decoder*/
-+
-+ /* software settings */
-+ unsigned int decoder:1; /* decoder loaded */
-+ unsigned int interlace:1; /* interlace */
-+ unsigned int buf_set:1; /* VIDIOCSFBUF has been issued */
-+ unsigned int win_set:1; /* VIDIOCSWIN has been issued */
-+ unsigned int cap_active:1; /* capture is active */
-+ unsigned int ovl_active:1; /* overlay is active */
-+ unsigned int mmaped:1; /* buffer is mmap()d */
-+ unsigned int unused:25;
-+
-+ unsigned int users; /* number of users */
-+ unsigned long cap_mem_offset; /* capture framebuffer offset */
-+ void * buffer; /* kernel capture buffer */
-+ unsigned int norm; /* video standard */
-+
-+ struct video_capability cap; /* capabilities */
-+ struct video_picture pic; /* current picture settings */
-+ struct video_buffer buf; /* display parameters */
-+ struct video_capture capt; /* video capture params */
-+
-+ struct win_info *ovl; /* overlay window set */
-+ struct win_info ext; /* "Extended" window info */
-+ struct win_info v2; /* "V2" window info */
-+ struct win_info x2; /* "X2" window info */
-+
-+ unsigned int bm_offset; /* Cap memory bus master offset */
-+ unsigned int bm_index; /* Cap page index */
-+
-+#ifdef USE_MMAP
-+ unsigned int frame_idx; /* currently grabbing frame */
-+ unsigned int frame_size;
-+ struct framebuf frame[NR_FRAMES];
-+ wait_queue_head_t frame_wait;
-+#endif
-+
-+ wait_queue_head_t vbl_wait;
-+
-+ /*
-+ * cyberpro registers
-+ */
-+ unsigned char cap_mode1;
-+ unsigned char cap_mode2;
-+ unsigned char cap_miscctl;
-+ unsigned char vfac1;
-+ unsigned char vfac3;
-+};
-+
-+/*
-+ * Our access methods.
-+ */
-+#define cyberpro_writel(val,reg,dp) writel(val, (dp)->regs + (reg))
-+#define cyberpro_writew(val,reg,dp) writew(val, (dp)->regs + (reg))
-+#define cyberpro_writeb(val,reg,dp) writeb(val, (dp)->regs + (reg))
-+
-+#define cyberpro_readb(reg,dp) readb((dp)->regs + (reg))
-+
-+static inline void
-+cyberpro_grphw(unsigned int reg, unsigned int val, struct cyberpro_vidinfo *dp)
-+{
-+ cyberpro_writew((reg & 255) | val << 8, 0x3ce, dp);
-+}
-+
-+static void cyberpro_grphw8(unsigned int reg, unsigned int val, struct cyberpro_vidinfo *dp)
-+{
-+ cyberpro_grphw(reg, val, dp);
-+}
-+
-+static unsigned char cyberpro_grphr8(int reg, struct cyberpro_vidinfo *dp)
-+{
-+ cyberpro_writeb(reg, 0x3ce, dp);
-+ return cyberpro_readb(0x3cf, dp);
-+}
-+
-+static void cyberpro_grphw16(int reg, unsigned int val, struct cyberpro_vidinfo *dp)
-+{
-+ cyberpro_grphw(reg, val, dp);
-+ cyberpro_grphw(reg + 1, val >> 8, dp);
-+}
-+
-+static void cyberpro_grphw24(int reg, unsigned int val, struct cyberpro_vidinfo *dp)
-+{
-+ cyberpro_grphw(reg, val, dp);
-+ cyberpro_grphw(reg + 1, val >> 8, dp);
-+ cyberpro_grphw(reg + 2, val >> 16, dp);
-+}
-+
-+#if 0
-+static void
-+cyberpro_dbg_dump(void)
-+{
-+ int i;
-+ unsigned char idx[] =
-+ { 0x30, 0x3e, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d,
-+ 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad };
-+ printk(KERN_DEBUG);
-+ for (i = 0; i < sizeof(idx); i++)
-+ printk("%02x ", idx[i]);
-+ printk("\n" KERN_DEBUG);
-+ for (i = 0; i < sizeof(idx); i++)
-+ printk("%02x ", cyberpro_grphr8(idx[i]));
-+ printk("\n");
-+}
-+#endif
-+
-+/*
-+ * On the NetWinder, we can put the SAA7111 to sleep by holding
-+ * it in reset.
-+ *
-+ * Note: once we have initialised the SAA7111, we can't put it back to
-+ * sleep and expect it to keep its settings. Maybe a better solution
-+ * is to register/de-register the i2c bus in open/release?
-+ */
-+static void
-+decoder_sleep(int sleep)
-+{
-+#ifdef CONFIG_ARCH_NETWINDER
-+ extern spinlock_t gpio_lock;
-+
-+ spin_lock_irq(&gpio_lock);
-+ cpld_modify(CPLD_7111_DISABLE, sleep ? CPLD_7111_DISABLE : 0);
-+ spin_unlock_irq(&gpio_lock);
-+
-+ if (!sleep) {
-+ /*
-+ * wait 20ms for device to wake up
-+ */
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ schedule_timeout(HZ / 50);
-+ }
-+#endif
-+}
-+
-+/* -------------------------------- I2C support ---------------------------- */
-+
-+#define I2C_DELAY 100
-+
-+static void
-+cyberpro_i2c_setlines(struct i2c_bus *bus, int ctrl, int data)
-+{
-+ struct cyberpro_vidinfo *dp = bus->data;
-+ int v;
-+
-+ v = (ctrl ? EXT_LATCH2_I2C_CLKEN : 0x00) | (data ? EXT_LATCH2_I2C_DATEN : 0x00);
-+ cyberpro_grphw8(EXT_LATCH2, v, dp);
-+
-+ udelay(I2C_DELAY);
-+}
-+
-+static int
-+cyberpro_i2c_getdataline(struct i2c_bus *bus)
-+{
-+ struct cyberpro_vidinfo *dp = bus->data;
-+ unsigned long flags;
-+ int v;
-+
-+ save_flags(flags);
-+ cli();
-+
-+ v = cyberpro_grphr8(EXT_LATCH2, dp);
-+
-+ restore_flags(flags);
-+
-+ return v & EXT_LATCH2_I2C_DAT ? 1 : 0;
-+}
-+
-+static void
-+cyberpro_i2c_attach(struct i2c_bus *bus, int id)
-+{
-+ struct cyberpro_vidinfo *dp = bus->data;
-+ int zero = 0;
-+
-+ if (id == I2C_DRIVERID_VIDEODECODER) {
-+ __u16 norm = dp->norm;
-+ i2c_control_device(bus, id, DECODER_SET_NORM, &norm);
-+ i2c_control_device(bus, id, DECODER_SET_PICTURE, &dp->pic);
-+ i2c_control_device(bus, id, DECODER_ENABLE_OUTPUT, &zero);
-+
-+ dp->decoder = 1;
-+ }
-+}
-+
-+static void
-+cyberpro_i2c_detach(struct i2c_bus *bus, int id)
-+{
-+ struct cyberpro_vidinfo *dp = bus->data;
-+
-+ if (id == I2C_DRIVERID_VIDEODECODER)
-+ dp->decoder = 0;
-+}
-+
-+static struct i2c_bus cyberpro_i2c_bus = {
-+ name: "",
-+ id: I2C_BUSID_CYBER2000,
-+ bus_lock: SPIN_LOCK_UNLOCKED,
-+ attach_inform: cyberpro_i2c_attach,
-+ detach_inform: cyberpro_i2c_detach,
-+ i2c_setlines: cyberpro_i2c_setlines,
-+ i2c_getdataline: cyberpro_i2c_getdataline,
-+};
-+
-+/*------------------------- Extended Overlay Window -------------------------
-+ * Initialise 1st overlay window (works)
-+ */
-+static void
-+cyberpro_ext_init(struct cyberpro_vidinfo *dp, struct win_info *wi)
-+{
-+ wi->vid_fifo_ctl = 0xf87c;
-+ wi->vid_fmt = EXT_VID_FMT_YUV422;
-+ wi->vid_disp_ctl1 = EXT_VID_DISP_CTL1_VINTERPOL_OFF |
-+ EXT_VID_DISP_CTL1_NOCLIP;
-+ wi->vid_fifo_ctl1 = EXT_VID_FIFO_CTL1_INTERLEAVE |
-+ EXT_VID_FIFO_CTL1_OE_HIGH;
-+ wi->vid_misc_ctl1 = 0;
-+
-+ cyberpro_grphw8 (EXT_VID_DISP_CTL1, wi->vid_disp_ctl1, dp);
-+ cyberpro_grphw16(EXT_DDA_X_INIT, 0x0800, dp);
-+ cyberpro_grphw16(EXT_DDA_Y_INIT, 0x0800, dp);
-+ cyberpro_grphw16(EXT_VID_FIFO_CTL, wi->vid_fifo_ctl, dp);
-+ cyberpro_grphw8 (EXT_VID_FIFO_CTL1, wi->vid_fifo_ctl1, dp);
-+}
-+
-+/*
-+ * Set the source parameters for the extended window
-+ */
-+static void
-+cyberpro_ext_set_src(struct cyberpro_vidinfo *dp, struct win_info *wi)
-+{
-+ unsigned int phase, pitch;
-+
-+ pitch = (wi->src.width >> 2) & 0x0fff;
-+ phase = (wi->src.width + 3) >> 2;
-+
-+ wi->vid_fmt &= ~7;
-+ switch (wi->src.format) {
-+ case VIDEO_PALETTE_RGB565: wi->vid_fmt |= EXT_VID_FMT_RGB565; break;
-+ case VIDEO_PALETTE_RGB24: wi->vid_fmt |= EXT_VID_FMT_RGB888_24; break;
-+ case VIDEO_PALETTE_RGB32: wi->vid_fmt |= EXT_VID_FMT_RGB888_32; break;
-+ case VIDEO_PALETTE_RGB555: wi->vid_fmt |= EXT_VID_FMT_RGB555; break;
-+ case VIDEO_PALETTE_YUV422: wi->vid_fmt |= EXT_VID_FMT_YUV422; break;
-+ }
-+
-+ cyberpro_grphw24(EXT_MEM_START, wi->src.offset, dp);
-+ cyberpro_grphw16(EXT_SRC_WIDTH, pitch | ((phase << 4) & 0xf000), dp);
-+ cyberpro_grphw8 (EXT_SRC_WIN_WIDTH, phase, dp);
-+ cyberpro_grphw8 (EXT_VID_FMT, wi->vid_fmt, dp);
-+}
-+
-+/*
-+ * Set overlay1 window
-+ */
-+static void
-+cyberpro_ext_set_win(struct cyberpro_vidinfo *dp, struct win_info *wi)
-+{
-+ unsigned int xscale, yscale;
-+ unsigned int xoff, yoff;
-+
-+ /*
-+ * Note: the offset does not appear to be influenced by
-+ * hardware scrolling.
-+ */
-+ xoff = yoff = 0;
-+
-+ xoff += wi->dst.x;
-+ yoff += wi->dst.y;
-+
-+ xscale = wi->src.width;
-+
-+ if (wi->dst.width >= wi->src.width * 2) {
-+ wi->vid_fmt |= EXT_VID_FMT_DBL_H_PIX;
-+ xscale *= 2;
-+ } else {
-+ wi->vid_fmt &= ~EXT_VID_FMT_DBL_H_PIX;
-+ }
-+
-+ xscale = ((xscale - /*2*/0) * 4096) / wi->dst.width;
-+ yscale = ((wi->src.height - /*2*/0) * 4096) / wi->dst.height;
-+
-+ cyberpro_grphw16(EXT_X_START, xoff, dp);
-+ cyberpro_grphw16(EXT_X_END, xoff + wi->dst.width, dp);
-+ cyberpro_grphw16(EXT_Y_START, yoff, dp);
-+ cyberpro_grphw16(EXT_Y_END, yoff + wi->dst.height, dp);
-+ cyberpro_grphw24(EXT_COLOUR_COMPARE, wi->dst.chromakey, dp);
-+ cyberpro_grphw16(EXT_DDA_X_INC, xscale, dp);
-+ cyberpro_grphw16(EXT_DDA_Y_INC, yscale, dp);
-+ cyberpro_grphw8(EXT_VID_FMT, wi->vid_fmt, dp);
-+
-+ if (wi->dst.flags & VIDEO_WINDOW_CHROMAKEY)
-+ wi->vid_disp_ctl1 &= ~EXT_VID_DISP_CTL1_IGNORE_CCOMP;
-+ else
-+ wi->vid_disp_ctl1 |= EXT_VID_DISP_CTL1_IGNORE_CCOMP;
-+}
-+
-+/*
-+ * Enable or disable the 1st overlay window. Note that for anything
-+ * useful to be displayed, we must have capture enabled.
-+ */
-+static void
-+cyberpro_ext_ctl(struct cyberpro_vidinfo *dp, struct win_info *wi, int on)
-+{
-+ if (on)
-+ wi->vid_disp_ctl1 |= EXT_VID_DISP_CTL1_ENABLE_WINDOW;
-+ else
-+ wi->vid_disp_ctl1 &= ~EXT_VID_DISP_CTL1_ENABLE_WINDOW;
-+
-+ cyberpro_grphw8(EXT_VID_DISP_CTL1, wi->vid_disp_ctl1, dp);
-+}
-+
-+/*------------------------------- V2 Overlay Window -------------------------
-+ * Initialise 2nd overlay window (guesswork)
-+ */
-+static void
-+cyberpro_v2_init(struct cyberpro_vidinfo *dp, struct win_info *wi)
-+{
-+ wi->vid_fifo_ctl = 0xf87c;
-+ wi->vid_fmt = EXT_VID_FMT_YUV422;
-+ wi->vid_disp_ctl1 = EXT_VID_DISP_CTL1_VINTERPOL_OFF |
-+ EXT_VID_DISP_CTL1_NOCLIP;
-+ wi->vid_fifo_ctl1 = 0x06;
-+ wi->vid_misc_ctl1 = 0;
-+
-+ cyberpro_grphw8(REG_BANK, REG_BANK_Y, dp);
-+ cyberpro_grphw8 (Y_V2_VID_DISP_CTL1, wi->vid_disp_ctl1, dp);
-+ /* No DDA init values */
-+ cyberpro_grphw16(Y_V2_VID_FIFO_CTL, wi->vid_fifo_ctl, dp);
-+ cyberpro_grphw8 (Y_V2_VID_FIFO_CTL1, wi->vid_fifo_ctl1, dp);
-+}
-+
-+/*
-+ * Set the source parameters for the v2 window
-+ */
-+static void
-+cyberpro_v2_set_src(struct cyberpro_vidinfo *dp, struct win_info *wi)
-+{
-+ unsigned int phase, pitch;
-+
-+ pitch = (wi->src.width >> 2) & 0x0fff;
-+ phase = (wi->src.width + 3) >> 2;
-+
-+ wi->vid_fmt &= ~7;
-+ switch (wi->src.format) {
-+ case VIDEO_PALETTE_RGB565: wi->vid_fmt |= EXT_VID_FMT_RGB565; break;
-+ case VIDEO_PALETTE_RGB24: wi->vid_fmt |= EXT_VID_FMT_RGB888_24; break;
-+ case VIDEO_PALETTE_RGB32: wi->vid_fmt |= EXT_VID_FMT_RGB888_32; break;
-+ case VIDEO_PALETTE_RGB555: wi->vid_fmt |= EXT_VID_FMT_RGB555; break;
-+ case VIDEO_PALETTE_YUV422: wi->vid_fmt |= EXT_VID_FMT_YUV422; break;
-+ }
-+
-+ cyberpro_grphw8(REG_BANK, REG_BANK_X, dp);
-+ cyberpro_grphw24(X_V2_VID_MEM_START, wi->src.offset, dp);
-+ cyberpro_grphw16(X_V2_VID_SRC_WIDTH, pitch | ((phase << 4) & 0xf000), dp);
-+ cyberpro_grphw8 (X_V2_VID_SRC_WIN_WIDTH, phase, dp);
-+
-+ cyberpro_grphw8(REG_BANK, REG_BANK_Y, dp);
-+ cyberpro_grphw8(Y_V2_VID_FMT, wi->vid_fmt, dp);
-+}
-+
-+/*
-+ * Set v2 window
-+ */
-+static void
-+cyberpro_v2_set_win(struct cyberpro_vidinfo *dp, struct win_info *wi)
-+{
-+ unsigned int xscale, yscale;
-+ unsigned int xoff, yoff;
-+
-+ /*
-+ * Note: the offset does not appear to be influenced by
-+ * hardware scrolling.
-+ */
-+ xoff = yoff = 0;
-+
-+ xoff += wi->dst.x;
-+ yoff += wi->dst.y;
-+
-+ xscale = (wi->src.width * 4096) / wi->dst.width;
-+ yscale = (wi->src.height * 4096) / wi->dst.height;
-+
-+ cyberpro_grphw8(REG_BANK, REG_BANK_X, dp);
-+ cyberpro_grphw16(X_V2_X_START, xoff, dp);
-+ cyberpro_grphw16(X_V2_X_END, xoff + wi->dst.width, dp);
-+ cyberpro_grphw16(X_V2_Y_START, yoff, dp);
-+ cyberpro_grphw16(X_V2_Y_END, yoff + wi->dst.height, dp);
-+
-+ cyberpro_grphw8(REG_BANK, REG_BANK_Y, dp);
-+ cyberpro_grphw16(Y_V2_DDA_X_INC, xscale, dp);
-+ cyberpro_grphw16(Y_V2_DDA_Y_INC, yscale, dp);
-+}
-+
-+/*
-+ * Enable or disable the 2nd overlay window. Note that for anything
-+ * useful to be displayed, we must have capture enabled.
-+ */
-+static void
-+cyberpro_v2_ctl(struct cyberpro_vidinfo *dp, struct win_info *wi, int on)
-+{
-+ if (on)
-+ wi->vid_disp_ctl1 |= EXT_VID_DISP_CTL1_ENABLE_WINDOW;
-+ else
-+ wi->vid_disp_ctl1 &= ~EXT_VID_DISP_CTL1_ENABLE_WINDOW;
-+
-+ cyberpro_grphw8(REG_BANK, REG_BANK_Y, dp);
-+ cyberpro_grphw8(Y_V2_VID_DISP_CTL1, wi->vid_disp_ctl1, dp);
-+}
-+
-+/*--------------------------- X2 Overlay Window -----------------------------
-+ * Initialise 3rd overlay window (guesswork)
-+ */
-+static void
-+cyberpro_x2_init(struct cyberpro_vidinfo *dp, struct win_info *wi)
-+{
-+ wi->vid_fmt = EXT_VID_FMT_YUV422;
-+ wi->vid_disp_ctl1 = 0x40;
-+ wi->vid_misc_ctl1 = 0;
-+
-+ cyberpro_grphw8(REG_BANK, REG_BANK_K, dp);
-+ cyberpro_grphw8 (K_X2_VID_DISP_CTL1, wi->vid_disp_ctl1, dp);
-+ cyberpro_grphw16(K_X2_DDA_X_INIT, 0x0800, dp);
-+ cyberpro_grphw16(K_X2_DDA_Y_INIT, 0x0800, dp);
-+}
-+
-+/*
-+ * Set the source parameters for the x2 window
-+ */
-+static void
-+cyberpro_x2_set_src(struct cyberpro_vidinfo *dp, struct win_info *wi)
-+{
-+ unsigned int phase, pitch;
-+
-+ pitch = (wi->src.width >> 2) & 0x0fff;
-+ phase = (wi->src.width + 3) >> 2;
-+
-+ wi->vid_fmt &= ~7;
-+ switch (wi->src.format) {
-+ case VIDEO_PALETTE_RGB565: wi->vid_fmt |= EXT_VID_FMT_RGB565; break;
-+ case VIDEO_PALETTE_RGB24: wi->vid_fmt |= EXT_VID_FMT_RGB888_24; break;
-+ case VIDEO_PALETTE_RGB32: wi->vid_fmt |= EXT_VID_FMT_RGB888_32; break;
-+ case VIDEO_PALETTE_RGB555: wi->vid_fmt |= EXT_VID_FMT_RGB555; break;
-+ case VIDEO_PALETTE_YUV422: wi->vid_fmt |= EXT_VID_FMT_YUV422; break;
-+ }
-+
-+ cyberpro_grphw8(REG_BANK, REG_BANK_J, dp);
-+ cyberpro_grphw24(J_X2_VID_MEM_START, wi->src.offset, dp);
-+ cyberpro_grphw16(J_X2_VID_SRC_WIDTH, pitch | ((phase << 4) & 0xf000), dp);
-+ cyberpro_grphw8 (J_X2_VID_SRC_WIN_WIDTH, phase, dp);
-+
-+ cyberpro_grphw8(REG_BANK, REG_BANK_K, dp);
-+ cyberpro_grphw8(K_X2_VID_FMT, wi->vid_fmt, dp);
-+}
-+
-+/*
-+ * Set x2 window
-+ */
-+static void
-+cyberpro_x2_set_win(struct cyberpro_vidinfo *dp, struct win_info *wi)
-+{
-+ unsigned int xscale, yscale;
-+ unsigned int xoff, yoff;
-+
-+ /*
-+ * Note: the offset does not appear to be influenced by
-+ * hardware scrolling.
-+ */
-+ xoff = yoff = 0;
-+
-+ xoff += wi->dst.x;
-+ yoff += wi->dst.y;
-+
-+ xscale = (wi->src.width * 4096) / wi->dst.width;
-+ yscale = (wi->src.height * 4096) / wi->dst.height;
-+
-+ cyberpro_grphw8(REG_BANK, REG_BANK_J, dp);
-+ cyberpro_grphw16(J_X2_X_START, xoff, dp);
-+ cyberpro_grphw16(J_X2_X_END, xoff + wi->dst.width, dp);
-+ cyberpro_grphw16(J_X2_Y_START, yoff, dp);
-+ cyberpro_grphw16(J_X2_Y_END, yoff + wi->dst.height, dp);
-+
-+ cyberpro_grphw8(REG_BANK, REG_BANK_K, dp);
-+ cyberpro_grphw16(K_X2_DDA_X_INC, xscale, dp);
-+ cyberpro_grphw16(K_X2_DDA_Y_INC, yscale, dp);
-+}
-+
-+/*
-+ * Enable or disable the 3rd overlay window. Note that for anything
-+ * useful to be displayed, we must have capture enabled.
-+ */
-+static void
-+cyberpro_x2_ctl(struct cyberpro_vidinfo *dp, struct win_info *wi, int on)
-+{
-+ if (on)
-+ wi->vid_disp_ctl1 |= EXT_VID_DISP_CTL1_ENABLE_WINDOW;
-+ else
-+ wi->vid_disp_ctl1 &= ~EXT_VID_DISP_CTL1_ENABLE_WINDOW;
-+
-+ cyberpro_grphw8(REG_BANK, REG_BANK_K, dp);
-+ cyberpro_grphw8(K_X2_VID_DISP_CTL1, wi->vid_disp_ctl1, dp);
-+}
-+
-+/* ------------------------------------------------------------------------- */
-+
-+#if 0
-+static void reset_seq(struct cyberpro_vidinfo *dp)
-+{
-+ unsigned char ext_mem_ctl = cyberpro_grphr8(0x70, dp);
-+
-+ cyberpro_grphw8(ext_mem_ctl | 0x80, 0x70, dp);
-+ cyberpro_grphw8(ext_mem_ctl, 0x70, dp);
-+}
-+#endif
-+
-+#ifdef USE_MMAP
-+/*
-+ * Buffer support
-+ */
-+static int
-+cyberpro_alloc_frame_buffer(struct cyberpro_vidinfo *dp,
-+ struct framebuf *frame)
-+{
-+ unsigned long addr;
-+ void *buffer;
-+ int pgidx;
-+
-+ if (frame->buffer)
-+ return 0;
-+
-+ /*
-+ * Allocate frame buffer
-+ */
-+ buffer = vmalloc(NR_PAGES * PAGE_SIZE);
-+
-+ if (frame->buffer) {
-+ vfree(buffer);
-+ return 0;
-+ }
-+
-+ if (!buffer)
-+ return -ENOMEM;
-+
-+ printk("Buffer allocated @ %p [", buffer);
-+
-+ frame->buffer = buffer;
-+ frame->dbg = 1;
-+
-+ /*
-+ * Don't leak information from the kernel.
-+ */
-+ memset(buffer, 0x5a, NR_PAGES * PAGE_SIZE);
-+
-+ /*
-+ * Now, reserve all the pages, and calculate
-+ * each pages' bus address.
-+ */
-+ addr = (unsigned long)buffer;
-+ for (pgidx = 0; pgidx < NR_PAGES; pgidx++, addr += PAGE_SIZE) {
-+ struct page *page;
-+ pgd_t *pgd;
-+ pmd_t *pmd;
-+ pte_t *pte;
-+
-+ /*
-+ * The page should be present. If not,
-+ * vmalloc has gone nuts.
-+ */
-+ pgd = pgd_offset_k(addr);
-+ if (pgd_none(*pgd))
-+ BUG();
-+ pmd = pmd_offset(pgd, addr);
-+ if (pmd_none(*pmd))
-+ BUG();
-+ pte = pte_offset(pmd, addr);
-+ if (!pte_present(*pte))
-+ BUG();
-+
-+ page = pte_page(*pte);
-+
-+ frame->bus_addr[pgidx] = virt_to_bus((void *)page_address(page));
-+ frame->pages[pgidx] = page;
-+ SetPageReserved(page);
-+
-+ printk("%08lx (%08lx) ", page_address(page), frame->bus_addr[pgidx]);
-+ }
-+ printk("\n");
-+
-+ return 0;
-+}
-+
-+static void
-+cyberpro_frames_free_one(struct cyberpro_vidinfo *dp, struct framebuf *frame)
-+{
-+ void *buffer;
-+ int pgidx;
-+
-+ frame->status = FRAME_FREE;
-+ buffer = frame->buffer;
-+ frame->buffer = NULL;
-+
-+ if (buffer) {
-+ for (pgidx = 0; pgidx < NR_PAGES; pgidx++) {
-+ frame->bus_addr[pgidx] = 0;
-+ ClearPageReserved(frame->pages[pgidx]);
-+ frame->pages[pgidx] = NULL;
-+ }
-+ vfree(buffer);
-+ }
-+}
-+
-+static void
-+cyberpro_busmaster_frame(struct cyberpro_vidinfo *dp, struct framebuf *frame)
-+{
-+ unsigned long bus_addr;
-+
-+ bus_addr = frame->bus_addr[dp->bm_index];
-+
-+ if (frame->dbg) {
-+ printk("Frame%d: %06x -> %08lx\n",
-+ dp->frame_idx,
-+ dp->bm_offset,
-+ bus_addr);
-+ }
-+
-+ cyber2000_outw(dp->bm_offset, BM_VID_ADDR_LOW);
-+ cyber2000_outw(dp->bm_offset >> 16, BM_VID_ADDR_HIGH);
-+
-+ cyber2000_outw(bus_addr, BM_ADDRESS_LOW);
-+ cyber2000_outw(bus_addr >> 16, BM_ADDRESS_HIGH);
-+
-+ /*
-+ * One page-full only
-+ */
-+ cyber2000_outw(1023, BM_LENGTH);
-+
-+ /*
-+ * Load length
-+ */
-+ cyber2000_outw(BM_CONTROL_INIT, BM_CONTROL);
-+
-+ /*
-+ * Enable transfer
-+ */
-+ cyber2000_outw(BM_CONTROL_ENABLE|BM_CONTROL_IRQEN, BM_CONTROL);
-+
-+ dp->bm_offset += 1024;
-+ dp->bm_index += 1;
-+}
-+
-+static void cyberpro_busmaster_interrupt(struct cyberpro_vidinfo *dp)
-+{
-+ struct framebuf *frame = dp->frame + dp->frame_idx;
-+
-+ /*
-+ * Disable Busmaster operations
-+ */
-+ cyber2000_outw(0, BM_CONTROL);
-+
-+ if (frame->status == FRAME_GRABBING) {
-+ /*
-+ * We are still grabbing this frame to system
-+ * memory. Transfer next page if there are
-+ * more, or else flag this frame as complete.
-+ */
-+ if (dp->bm_index < NR_PAGES)
-+ cyberpro_busmaster_frame(dp);
-+ else {
-+ unsigned int idx;
-+
-+ frame->status = FRAME_DONE;
-+ frame->dbg = 0;
-+
-+ idx = dp->frame_idx + 1;
-+ if (idx >= NR_FRAMES)
-+ idx = 0;
-+
-+ dp->frame_idx = idx;
-+
-+ wake_up(&dp->frame_wait);
-+ }
-+ }
-+}
-+
-+static void cyberpro_frames_vbl(struct cyberpro_vidinfo *dp, unsigned int stat)
-+{
-+ struct framebuf *frame = dp->frame + dp->frame_idx;
-+
-+ /*
-+ * No point capturing frames if the grabber isn't active.
-+ */
-+ if (stat & EXT_ROM_UCB4GH_FREEZE)
-+ return;
-+
-+ /*
-+ * If the next buffer is ready for grabbing,
-+ * set up the bus master registers for the
-+ * transfer.
-+ */
-+ if (frame->status == FRAME_WAITING) {
-+ frame->status = FRAME_GRABBING;
-+
-+ dp->bm_offset = dp->cap_mem_offset;
-+ dp->bm_index = 0;
-+
-+ cyberpro_busmaster_frame(dp, frame);
-+ }
-+}
-+
-+static void __init cyberpro_frames_init(struct cyberpro_vidinfo *dp)
-+{
-+ unsigned int offset, maxsize;
-+ int i;
-+
-+ init_waitqueue_head(&dp->frame_wait);
-+
-+ maxsize = 2 * dp->cap.maxwidth * dp->cap.maxheight;
-+ dp->frame_size = PAGE_ALIGN(maxsize);
-+ dp->frame_idx = 0;
-+
-+ for (i = offset = 0; i < NR_FRAMES; i++) {
-+ dp->frame[i].offset = offset;
-+ dp->frame[i].status = FRAME_FREE;
-+ offset += dp->frame_size;
-+ }
-+}
-+
-+static void cyberpro_frames_free(struct cyberpro_vidinfo *dp)
-+{
-+ int i;
-+
-+ dp->mmaped = 0;
-+
-+ /*
-+ * Free all frame buffers
-+ */
-+ for (i = 0; i < NR_FRAMES; i++)
-+ cyberpro_frames_free_one(dp, dp->frame + i);
-+}
-+
-+#else
-+#define cyberpro_frames_vbl(dp,stat) do { } while (0)
-+#define cyberpro_frames_init(dp) do { } while (0)
-+#define cyberpro_frames_free(dp) do { } while (0)
-+#endif
-+
-+/*
-+ * CyberPro Interrupts
-+ * -------------------
-+ *
-+ * We don't really know how to signal an IRQ clear to the chip. However,
-+ * disabling and re-enabling the capture interrupt enable seems to do what
-+ * we want.
-+ */
-+static void cyberpro_interrupt(int nr, void *dev_id, struct pt_regs *regs)
-+{
-+ struct cyberpro_vidinfo *dp = dev_id;
-+ unsigned char old_grphidx;
-+ unsigned int status;
-+
-+ /*
-+ * Save old graphics index register
-+ */
-+ old_grphidx = cyberpro_readb(0x3ce, dp);
-+
-+ status = cyberpro_grphr8(EXT_ROM_UCB4GH, dp);
-+
-+ /*
-+ * Was it due to the Capture VSYNC?
-+ */
-+ if (status & EXT_ROM_UCB4GH_INTSTAT) {
-+ /*
-+ * Frob the IRQ enable bit to drop the request.
-+ */
-+ cyberpro_grphw8(VFAC_CTL3, dp->vfac3 & ~VFAC_CTL3_CAP_IRQ, dp);
-+ cyberpro_grphw8(VFAC_CTL3, dp->vfac3, dp);
-+
-+ cyberpro_frames_vbl(dp, status);
-+ wake_up(&dp->vbl_wait);
-+ }
-+
-+ /*
-+ * Restore graphics controller index
-+ */
-+ cyberpro_writeb(old_grphidx, 0x3ce, dp);
-+
-+#ifdef USE_MMAP
-+ /*
-+ * Do Bus-Master IRQ stuff
-+ */
-+ if (cyber2000_inb(BM_CONTROL) & (1 << 7))
-+ cyberpro_busmaster_interrupt(dp);
-+#endif
-+}
-+
-+static void cyberpro_capture(struct cyberpro_vidinfo *dp, int on)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ unsigned int status;
-+
-+ status = cyberpro_grphr8(EXT_ROM_UCB4GH, dp);
-+
-+ add_wait_queue(&dp->vbl_wait, &wait);
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+
-+ if (!!on ^ !(status & EXT_ROM_UCB4GH_FREEZE)) {
-+ if (on) {
-+ schedule_timeout(40 * HZ / 1000);
-+ dp->vfac1 &= ~(VFAC_CTL1_FREEZE_CAPTURE|VFAC_CTL1_FREEZE_CAPTURE_SYNC);
-+ cyberpro_grphw8(VFAC_CTL1, dp->vfac1, dp);
-+
-+ status = cyberpro_grphr8(EXT_ROM_UCB4GH, dp);
-+ } else {
-+ dp->vfac1 |= VFAC_CTL1_FREEZE_CAPTURE_SYNC;
-+ cyberpro_grphw8(VFAC_CTL1, dp->vfac1, dp);
-+
-+ status = cyberpro_grphr8(EXT_ROM_UCB4GH, dp);
-+ if (!(status & EXT_ROM_UCB4GH_FREEZE))
-+ schedule_timeout(40 * HZ / 1000);
-+ }
-+ }
-+
-+ current->state = TASK_RUNNING;
-+ remove_wait_queue(&dp->vbl_wait, &wait);
-+}
-+
-+static void cyberpro_capture_one(struct cyberpro_vidinfo *dp)
-+{
-+ struct task_struct *tsk = current;
-+ DECLARE_WAITQUEUE(wait, tsk);
-+ unsigned int status;
-+ unsigned long policy, rt_priority;
-+
-+ policy = tsk->policy;
-+ rt_priority = tsk->rt_priority;
-+
-+ tsk->policy = SCHED_FIFO;
-+ tsk->rt_priority = 1;
-+
-+ status = cyberpro_grphr8(EXT_ROM_UCB4GH, dp);
-+
-+ add_wait_queue(&dp->vbl_wait, &wait);
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+
-+ schedule_timeout(40 * HZ / 1000);
-+ dp->vfac1 &= ~(VFAC_CTL1_FREEZE_CAPTURE|VFAC_CTL1_FREEZE_CAPTURE_SYNC);
-+ cyberpro_grphw8(VFAC_CTL1, dp->vfac1, dp);
-+
-+ status = cyberpro_grphr8(EXT_ROM_UCB4GH, dp);
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ schedule_timeout(40 * HZ / 1000);
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ schedule_timeout(40 * HZ / 1000);
-+
-+ dp->vfac1 |= VFAC_CTL1_FREEZE_CAPTURE_SYNC;
-+ cyberpro_grphw8(VFAC_CTL1, dp->vfac1, dp);
-+
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ status = cyberpro_grphr8(EXT_ROM_UCB4GH, dp);
-+
-+ current->state = TASK_RUNNING;
-+ remove_wait_queue(&dp->vbl_wait, &wait);
-+
-+ tsk->policy = policy;
-+ tsk->rt_priority = rt_priority;
-+}
-+
-+static void cyberpro_capture_set_win(struct cyberpro_vidinfo *dp)
-+{
-+ unsigned int xstart, xend, ystart, yend;
-+
-+ xstart = 4 + dp->capt.x;
-+ xend = xstart + dp->capt.width;
-+
-+ if (dp->cap_mode1 & EXT_CAP_MODE1_8BIT) {
-+ /* 8-bit capture */
-+ xstart *= 2;
-+ xend *= 2;
-+ }
-+
-+ xstart -= 1;
-+ xend -= 1;
-+
-+ ystart = 18 + dp->capt.y;
-+ yend = ystart + dp->capt.height / 2;
-+
-+ cyberpro_grphw16(CAP_X_START, xstart, dp);
-+ cyberpro_grphw16(CAP_X_END, xend + 1, dp);
-+ cyberpro_grphw16(CAP_Y_START, ystart, dp);
-+ cyberpro_grphw16(CAP_Y_END, yend + 2, dp);
-+
-+ /*
-+ * This should take account of capt.decimation
-+ */
-+ cyberpro_grphw16(CAP_DDA_X_INIT, 0x0800, dp);
-+ cyberpro_grphw16(CAP_DDA_X_INC, 0x1000, dp);
-+ cyberpro_grphw16(CAP_DDA_Y_INIT, 0x0800, dp);
-+ cyberpro_grphw16(CAP_DDA_Y_INC, 0x1000, dp);
-+
-+ cyberpro_grphw8(CAP_PITCH, dp->capt.width >> 2, dp);
-+}
-+
-+static void cyberpro_set_interlace(struct cyberpro_vidinfo *dp)
-+{
-+ /*
-+ * set interlace mode
-+ */
-+ if (dp->interlace) {
-+ dp->vfac3 |= VFAC_CTL3_CAP_INTERLACE;
-+ dp->cap_miscctl &= ~CAP_CTL_MISC_ODDEVEN;
-+ dp->ovl->src.height = dp->capt.height;
-+ } else {
-+ dp->vfac3 &= ~VFAC_CTL3_CAP_INTERLACE;
-+ dp->cap_miscctl |= CAP_CTL_MISC_ODDEVEN;
-+ dp->ovl->src.height = dp->capt.height / 2;
-+ }
-+
-+ cyberpro_grphw8(VFAC_CTL3, dp->vfac3, dp);
-+ cyberpro_grphw8(CAP_CTL_MISC, dp->cap_miscctl, dp);
-+
-+ dp->ovl->set_src(dp, dp->ovl);
-+
-+ if (dp->win_set)
-+ dp->ovl->set_win(dp, dp->ovl);
-+}
-+
-+/*
-+ * Calculate and set the address of the capture buffer. Note we
-+ * also update the extended memory buffer for the overlay window.
-+ *
-+ * base: phys base address of display
-+ * width: pixel width of display
-+ * height: height of display
-+ * depth: depth of display (8/16/24)
-+ * bytesperline: number of bytes on a line
-+ *
-+ * We place the capture buffer 16K after the screen.
-+ */
-+static int
-+cyberpro_set_buffer(struct cyberpro_vidinfo *dp, struct video_buffer *b)
-+{
-+ unsigned long screensize, maxbufsz;
-+
-+ if (b->height <= 0 || b->width <= 0 || b->bytesperline <= 0)
-+ return -EINVAL;
-+
-+ maxbufsz = dp->cap.maxwidth * dp->cap.maxheight * 2;
-+ screensize = b->height * b->bytesperline + 16384;
-+
-+ if ((screensize + maxbufsz) >= dp->info.fb_size)
-+ return -EINVAL;
-+
-+ dp->buf.base = b->base;
-+ dp->buf.width = b->width;
-+ dp->buf.height = b->height;
-+ dp->buf.depth = b->depth;
-+ dp->buf.bytesperline = b->bytesperline;
-+ dp->cap_mem_offset = screensize >> 2;
-+
-+ cyberpro_grphw24(CAP_MEM_START, dp->cap_mem_offset, dp);
-+
-+ /*
-+ * Setup the overlay source information.
-+ */
-+ dp->ovl->src.offset = dp->cap_mem_offset;
-+ dp->ovl->set_src(dp, dp->ovl);
-+
-+ return 0;
-+}
-+
-+static void cyberpro_hw_init(struct cyberpro_vidinfo *dp)
-+{
-+ unsigned char old;
-+
-+ /*
-+ * Enable access to bus-master registers
-+ */
-+ dp->info.enable_extregs(dp->info.info);
-+
-+ dp->vfac1 = VFAC_CTL1_PHILIPS |
-+ VFAC_CTL1_FREEZE_CAPTURE |
-+ VFAC_CTL1_FREEZE_CAPTURE_SYNC;
-+ dp->vfac3 = VFAC_CTL3_CAP_IRQ;
-+
-+ dp->cap_miscctl = CAP_CTL_MISC_DISPUSED |
-+ CAP_CTL_MISC_SYNCTZOR |
-+ CAP_CTL_MISC_SYNCTZHIGH;
-+
-+ /*
-+ * Setup bus-master mode
-+ */
-+ cyberpro_grphw8(BM_CTRL1, 0x88, dp);
-+ cyberpro_grphw8(PCI_BM_CTL, PCI_BM_CTL_ENABLE, dp);
-+ cyberpro_grphw8(BM_CTRL0, 0x44, dp);
-+ cyberpro_grphw8(BM_CTRL1, 0x84, dp);
-+
-+ cyberpro_grphw24(CAP_MEM_START, 0, dp);
-+
-+ cyberpro_grphw8(VFAC_CTL1, dp->vfac1, dp);
-+ cyberpro_grphw8(VFAC_CTL3, dp->vfac3, dp);
-+ cyberpro_grphw8(VFAC_CTL2, 0, dp);
-+
-+ cyberpro_grphw8(REG_BANK, REG_BANK_Y, dp);
-+ cyberpro_grphw8(EXT_TV_CTL, 0x80, dp);
-+
-+ cyberpro_grphw8(EXT_CAP_CTL1, 0x3f, dp); /* disable PIP */
-+ cyberpro_grphw8(EXT_CAP_CTL2, 0xc0 | EXT_CAP_CTL2_ODDFRAMEIRQ, dp);
-+
-+ /*
-+ * Configure capture mode to match the
-+ * external video processor format
-+ */
-+ cyberpro_grphw8(EXT_CAP_MODE1, dp->cap_mode1, dp);
-+ cyberpro_grphw8(EXT_CAP_MODE2, dp->cap_mode2, dp);
-+
-+ /* setup overlay */
-+ cyberpro_grphw16(EXT_FIFO_CTL, 0x1010, dp);
-+// cyberpro_grphw16(EXT_FIFO_CTL, 0x1b0f, dp);
-+
-+ /*
-+ * Always reset the capture parameters on each open.
-+ */
-+ dp->capt.x = 0;
-+ dp->capt.y = 0;
-+ dp->capt.width = dp->cap.maxwidth;
-+ dp->capt.height = dp->cap.maxheight;
-+ dp->capt.decimation = 0;
-+ dp->capt.flags = 0;
-+
-+ cyberpro_capture_set_win(dp);
-+
-+ /*
-+ * Enable VAFC
-+ */
-+ old = cyberpro_grphr8(EXT_LATCH1, dp);
-+ cyberpro_grphw8(EXT_LATCH1, old | EXT_LATCH1_VAFC_EN, dp);
-+
-+ /*
-+ * Enable capture (we hope that VSYNC=1)
-+ */
-+ dp->vfac1 |= VFAC_CTL1_CAPTURE;
-+ cyberpro_grphw8(VFAC_CTL1, dp->vfac1, dp);
-+
-+ /*
-+ * The overlay source format is always the
-+ * same as the capture stream format.
-+ */
-+ dp->ovl->src.width = dp->capt.width;
-+ dp->ovl->src.height = dp->capt.height;
-+ dp->ovl->src.format = dp->stream_fmt;
-+
-+ /*
-+ * Initialise the overlay windows
-+ */
-+ dp->ext.init(dp, &dp->ext);
-+ dp->v2.init(dp, &dp->v2);
-+ dp->x2.init(dp, &dp->x2);
-+}
-+
-+static void cyberpro_deinit(struct cyberpro_vidinfo *dp)
-+{
-+ unsigned char old;
-+
-+ /*
-+ * Stop any bus-master activity
-+ */
-+ cyberpro_writew(0, BM_CONTROL, dp);
-+
-+ /*
-+ * Shut down overlay
-+ */
-+ if (dp->ovl_active)
-+ dp->ovl->ctl(dp, dp->ovl, 0);
-+ dp->ovl_active = 0;
-+
-+ /*
-+ * Shut down capture
-+ */
-+ if (dp->cap_active)
-+ cyberpro_capture(dp, 0);
-+ dp->cap_active = 0;
-+
-+ /*
-+ * Disable all capture
-+ */
-+ cyberpro_grphw8(VFAC_CTL1, 0, dp);
-+
-+ /*
-+ * Disable VAFC
-+ */
-+ old = cyberpro_grphr8(EXT_LATCH1, dp);
-+ cyberpro_grphw8(EXT_LATCH1, old & ~EXT_LATCH1_VAFC_EN, dp);
-+
-+ /*
-+ * Disable interrupt (this allows it to float)
-+ */
-+ dp->vfac3 &= ~VFAC_CTL3_CAP_IRQ;
-+ cyberpro_grphw8(VFAC_CTL3, dp->vfac3, dp);
-+
-+ /*
-+ * Switch off bus-master mode
-+ */
-+ cyberpro_grphw8(PCI_BM_CTL, 0, dp);
-+
-+ /*
-+ * Disable access to bus-master registers
-+ */
-+ dp->info.disable_extregs(dp->info.info);
-+}
-+
-+static int cyberpro_grabber_open(struct video_device *dev, int flags)
-+{
-+ struct cyberpro_vidinfo *dp = dev->priv;
-+ int ret, one = 1;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ ret = -EBUSY;
-+ if (flags || dp->users)
-+ goto out;
-+
-+ dp->users += 1;
-+
-+ if (dp->users == 1) {
-+ ret = request_irq(dp->irq, cyberpro_interrupt, SA_SHIRQ,
-+ dp->info.dev_name, dp);
-+
-+ if (ret) {
-+ dp->users -= 1;
-+ goto out;
-+ }
-+
-+ /*
-+ * Initialise the VGA chip
-+ */
-+ cyberpro_hw_init(dp);
-+
-+ /*
-+ * Enable the IRQ. This allows the IRQ to work as expected
-+ * even if the IRQ line is missing the pull-up resistor.
-+ */
-+ enable_irq(dp->irq);
-+
-+ i2c_control_device(dp->bus, I2C_DRIVERID_VIDEODECODER,
-+ DECODER_ENABLE_OUTPUT, &one);
-+ }
-+
-+ ret = 0;
-+out:
-+ if (ret)
-+ MOD_DEC_USE_COUNT;
-+ return ret;
-+}
-+
-+static void cyberpro_grabber_close(struct video_device *dev)
-+{
-+ struct cyberpro_vidinfo *dp = dev->priv;
-+
-+ if (dp->users == 1) {
-+ int zero = 0;
-+
-+ /*
-+ * Disable the IRQ. This prevents problems with missing
-+ * pull-up resistors on the PCI interrupt line.
-+ */
-+ disable_irq(dp->irq);
-+
-+ cyberpro_frames_free(dp);
-+
-+ /*
-+ * Turn off the SAA7111 decoder
-+ */
-+ i2c_control_device(dp->bus, I2C_DRIVERID_VIDEODECODER,
-+ DECODER_ENABLE_OUTPUT, &zero);
-+
-+ /*
-+ * Disable grabber
-+ */
-+ cyberpro_deinit(dp);
-+
-+ free_irq(dp->irq, dp);
-+ }
-+
-+ dp->users -= 1;
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+/*
-+ * Our general plan here is:
-+ * 1. Set the CyberPro to perform a BM-DMA of one frame to this memory
-+ * 2. Copy the frame to the userspace
-+ *
-+ * However, BM-DMA seems to be unreliable at the moment, especially on
-+ * rev. 4 NetWinders.
-+ */
-+static long
-+cyberpro_grabber_read(struct video_device *dev, char *buf,
-+ unsigned long count, int noblock)
-+{
-+ struct cyberpro_vidinfo *dp = dev->priv;
-+ int ret = -EINVAL;
-+
-+#ifdef USE_MMIO
-+ unsigned long maxbufsz = dp->capt.width * dp->capt.height * 2;
-+ char *disp = dp->info.fb + (dp->cap_mem_offset << 2);
-+
-+ /*
-+ * If the buffer is mmap()'d, we shouldn't be using read()
-+ */
-+ if (dp->mmaped)
-+ return -EINVAL;
-+
-+ if (count > maxbufsz)
-+ count = maxbufsz;
-+
-+ if (dp->cap_active)
-+ cyberpro_capture(dp, 0);
-+ else
-+ cyberpro_capture_one(dp);
-+
-+ ret = (int)count;
-+ if (copy_to_user(buf, disp, count))
-+ ret = -EFAULT;
-+
-+ /*
-+ * unfreeze capture
-+ */
-+ if (dp->cap_active)
-+ cyberpro_capture(dp, 1);
-+#endif
-+
-+ return ret;
-+}
-+
-+/*
-+ * We don't support writing to the grabber
-+ * (In theory, we could allow writing to a separate region of VGA memory,
-+ * and display this using the second overlay window. This would allow us
-+ * to do video conferencing for example).
-+ */
-+static long
-+cyberpro_grabber_write(struct video_device *dev, const char *buf,
-+ unsigned long count, int noblock)
-+{
-+ return -EINVAL;
-+}
-+
-+static int
-+cyberpro_grabber_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
-+{
-+ struct cyberpro_vidinfo *dp = dev->priv;
-+
-+ switch (cmd) {
-+ case VIDIOCGCAP:
-+ return copy_to_user(arg, &dp->cap, sizeof(dp->cap))
-+ ? -EFAULT : 0;
-+
-+ case VIDIOCGCHAN:
-+ {
-+ struct video_channel chan;
-+
-+ chan.channel = 0;
-+ strcpy(chan.name, "Composite");
-+ chan.tuners = 0;
-+ chan.flags = 0;
-+ chan.type = VIDEO_TYPE_CAMERA;
-+ chan.norm = dp->norm;
-+
-+ return copy_to_user(arg, &chan, sizeof(chan)) ? -EFAULT : 0;
-+ }
-+
-+ case VIDIOCGPICT:
-+ return copy_to_user(arg, &dp->pic, sizeof(dp->pic))
-+ ? -EINVAL : 0;
-+
-+ case VIDIOCGWIN:
-+ {
-+ struct video_window win;
-+
-+ win.x = dp->ovl->dst.x;
-+ win.y = dp->ovl->dst.y;
-+ win.width = dp->ovl->dst.width;
-+ win.height = dp->ovl->dst.height;
-+ win.chromakey = dp->ovl->dst.chromakey;
-+ win.flags = VIDEO_WINDOW_CHROMAKEY |
-+ (dp->interlace ? VIDEO_WINDOW_INTERLACE : 0);
-+ win.clips = NULL;
-+ win.clipcount = 0;
-+
-+ return copy_to_user(arg, &win, sizeof(win))
-+ ? -EINVAL : 0;
-+ }
-+
-+ case VIDIOCGFBUF:
-+ return copy_to_user(arg, &dp->buf, sizeof(dp->buf))
-+ ? -EINVAL : 0;
-+
-+ case VIDIOCGUNIT:
-+ {
-+ struct video_unit unit;
-+
-+ unit.video = dev->minor;
-+ unit.vbi = VIDEO_NO_UNIT;
-+ unit.radio = VIDEO_NO_UNIT;
-+ unit.audio = VIDEO_NO_UNIT;
-+ unit.teletext = VIDEO_NO_UNIT;
-+
-+ return copy_to_user(arg, &unit, sizeof(unit))
-+ ? -EINVAL : 0;
-+ }
-+
-+ case VIDIOCGCAPTURE:
-+ return copy_to_user(arg, &dp->capt, sizeof(dp->capt))
-+ ? -EFAULT : 0;
-+
-+ case VIDIOCSCHAN:
-+ {
-+ struct video_decoder_capability vdc;
-+ struct video_channel v;
-+ int ok;
-+
-+ if (copy_from_user(&v, arg, sizeof(v)))
-+ return -EFAULT;
-+
-+ if (v.channel != 0)
-+ return -EINVAL;
-+
-+ i2c_control_device(dp->bus, I2C_DRIVERID_VIDEODECODER,
-+ DECODER_GET_CAPABILITIES, &vdc);
-+
-+ switch (v.norm) {
-+ case VIDEO_MODE_PAL:
-+ ok = vdc.flags & VIDEO_DECODER_PAL;
-+ break;
-+ case VIDEO_MODE_NTSC:
-+ ok = vdc.flags & VIDEO_DECODER_NTSC;
-+ break;
-+ case VIDEO_MODE_AUTO:
-+ ok = vdc.flags & VIDEO_DECODER_AUTO;
-+ break;
-+ default:
-+ ok = 0;
-+ }
-+ if (!ok)
-+ return -EINVAL;
-+
-+ dp->norm = v.norm;
-+
-+ i2c_control_device(dp->bus, I2C_DRIVERID_VIDEODECODER,
-+ DECODER_SET_NORM, &v.norm);
-+
-+ return 0;
-+ }
-+
-+ case VIDIOCSPICT:
-+ {
-+ struct video_picture p;
-+
-+ if (copy_from_user(&p, arg, sizeof(p)))
-+ return -EFAULT;
-+
-+ if (p.palette != dp->stream_fmt ||
-+ p.depth != 8)
-+ return -EINVAL;
-+
-+ dp->pic = p;
-+
-+ /* p.depth sets the capture depth */
-+ /* p.palette sets the capture palette */
-+
-+ i2c_control_device(dp->bus, I2C_DRIVERID_VIDEODECODER,
-+ DECODER_SET_PICTURE, &p);
-+
-+ return 0;
-+ }
-+
-+ case VIDIOCSWIN: /* set the size & position of the overlay window */
-+ {
-+ struct video_window w;
-+ int diff;
-+
-+ if (!dp->buf_set)
-+ return -EINVAL;
-+
-+ if (copy_from_user(&w, arg, sizeof(w)))
-+ return -EFAULT;
-+
-+ if (w.clipcount)
-+ return -EINVAL;
-+
-+ /*
-+ * Bound the overlay window by the size of the screen
-+ */
-+ if (w.x < 0)
-+ w.x = 0;
-+ if (w.y < 0)
-+ w.y = 0;
-+
-+ if (w.x > dp->buf.width)
-+ w.x = dp->buf.width;
-+ if (w.y > dp->buf.height)
-+ w.y = dp->buf.height;
-+
-+ if (w.width < dp->capt.width)
-+ w.width = dp->capt.width;
-+ if (w.height < dp->capt.height)
-+ w.height = dp->capt.height;
-+
-+ if (w.x + w.width > dp->buf.width)
-+ w.width = dp->buf.width - w.x;
-+ if (w.y + w.height > dp->buf.height)
-+ w.height = dp->buf.height - w.y;
-+
-+ /*
-+ * We've tried to make the values fit, but
-+ * they just won't.
-+ */
-+ if (w.width < dp->capt.width || w.height < dp->capt.height)
-+ return -EINVAL;
-+
-+ diff = dp->ovl->dst.x != w.x ||
-+ dp->ovl->dst.y != w.y ||
-+ dp->ovl->dst.width != w.width ||
-+ dp->ovl->dst.height != w.height ||
-+ dp->ovl->dst.chromakey != w.chromakey ||
-+ dp->ovl->dst.flags != w.flags;
-+
-+ if (!dp->win_set || diff) {
-+ dp->ovl->dst.x = w.x;
-+ dp->ovl->dst.y = w.y;
-+ dp->ovl->dst.width = w.width;
-+ dp->ovl->dst.height = w.height;
-+ dp->ovl->dst.chromakey = w.chromakey;
-+ dp->ovl->dst.flags = w.flags;
-+
-+ if (dp->ovl_active)
-+ dp->ovl->ctl(dp, dp->ovl, 0);
-+
-+ dp->ovl->set_win(dp, dp->ovl);
-+
-+ if (dp->ovl_active)
-+ dp->ovl->ctl(dp, dp->ovl, 1);
-+
-+ diff = w.flags & VIDEO_WINDOW_INTERLACE ? 1 : 0;
-+ if (!dp->win_set || dp->interlace != diff) {
-+ dp->interlace = diff;
-+ cyberpro_set_interlace(dp);
-+ }
-+ }
-+
-+ dp->win_set = 1;
-+
-+ return 0;
-+ }
-+
-+ case VIDIOCSFBUF: /* set frame buffer info */
-+ {
-+ struct video_buffer b;
-+ int ret;
-+
-+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
-+ return -EPERM;
-+
-+ if (dp->cap_active)
-+ return -EINVAL;
-+
-+ if (copy_from_user(&b, arg, sizeof(b)))
-+ return -EFAULT;
-+
-+ ret = cyberpro_set_buffer(dp, &b);
-+ if (ret == 0) {
-+ dp->buf_set = 1;
-+ dp->win_set = 0;
-+ }
-+
-+ return ret;
-+ }
-+
-+ case VIDIOCCAPTURE:
-+ {
-+ int on;
-+
-+ if (get_user(on, (int *)arg))
-+ return -EFAULT;
-+
-+ if (( on && dp->ovl_active) ||
-+ (!on && !dp->ovl_active))
-+ return 0;
-+
-+ if (on && (!dp->buf_set || !dp->win_set))
-+ return -EINVAL;
-+
-+ cyberpro_capture(dp, on);
-+ dp->cap_active = on;
-+ dp->ovl->ctl(dp, dp->ovl, on);
-+ dp->ovl_active = on;
-+
-+ return 0;
-+ }
-+
-+#ifdef USE_MMAP
-+ case VIDIOCSYNC:
-+ {
-+ DECLARE_WAITQUEUE(wait, current);
-+ int buf;
-+
-+ /*
-+ * The buffer must have been mmaped
-+ * for this call to work.
-+ */
-+ if (!dp->mmaped)
-+ return -EINVAL;
-+
-+ if (get_user(buf, (int *)arg))
-+ return -EFAULT;
-+
-+ if (buf < 0 || buf >= NR_FRAMES)
-+ return -EINVAL;
-+
-+ switch (dp->frame[buf].status) {
-+ case FRAME_FREE:
-+ return -EINVAL;
-+
-+ case FRAME_WAITING:
-+ case FRAME_GRABBING:
-+ add_wait_queue(&dp->frame_wait, &wait);
-+ while (1) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (signal_pending(current))
-+ break;
-+ if (dp->frame[buf].status == FRAME_DONE)
-+ break;
-+ schedule();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&dp->frame_wait, &wait);
-+ if (signal_pending(current))
-+ return -EINTR;
-+ /*FALLTHROUGH*/
-+ case FRAME_DONE:
-+ dp->frame[buf].status = FRAME_FREE;
-+ break;
-+ }
-+ return 0;
-+ }
-+
-+ case VIDIOCMCAPTURE:
-+ {
-+ struct video_mmap vmap;
-+
-+ /*
-+ * The buffer must have been mmaped
-+ * for this call to work.
-+ */
-+ if (!dp->mmaped)
-+ return -EINVAL;
-+
-+ if (copy_from_user(&vmap, arg, sizeof(vmap)))
-+ return -EFAULT;
-+
-+ /*
-+ * We can only capture in our source format/size.
-+ */
-+ if (vmap.frame >= NR_FRAMES ||
-+ vmap.format != dp->stream_fmt ||
-+ vmap.width != dp->capt.width ||
-+ vmap.height != dp->capt.height)
-+ return -EINVAL;
-+
-+ if (dp->frame[vmap.frame].status == FRAME_WAITING ||
-+ dp->frame[vmap.frame].status == FRAME_GRABBING)
-+ return -EBUSY;
-+
-+ dp->frame[vmap.frame].status = FRAME_WAITING;
-+ return 0;
-+ }
-+
-+ case VIDIOCGMBUF:
-+ {
-+ struct video_mbuf vmb;
-+ unsigned int i;
-+
-+ vmb.frames = NR_FRAMES;
-+ vmb.size = dp->frame_size * NR_FRAMES;
-+
-+ for (i = 0; i < NR_FRAMES; i++)
-+ vmb.offsets[i] = dp->frame[i].offset;
-+
-+ return copy_to_user(arg, &vmb, sizeof(vmb)) ? -EFAULT : 0;
-+ }
-+#endif
-+
-+ case VIDIOCSCAPTURE:
-+ {
-+ struct video_capture capt;
-+
-+#ifndef ALLOW_SCAPTURE_WHILE_CAP
-+ if (dp->cap_active)
-+ return -EINVAL;
-+#endif
-+
-+ if (copy_from_user(&capt, arg, sizeof(capt)))
-+ return -EFAULT;
-+
-+ if (capt.x < 0 || capt.width < 0 ||
-+ capt.y < 0 || capt.height < 0 ||
-+ capt.x + capt.width > dp->cap.maxwidth ||
-+ capt.y + capt.height > dp->cap.maxheight)
-+ return -EINVAL;
-+
-+ /*
-+ * The capture width must be a multiple of 4
-+ */
-+ if (dp->capt.width & 3)
-+ return -EINVAL;
-+
-+ dp->capt.x = capt.x;
-+ dp->capt.y = capt.y;
-+ dp->capt.width = capt.width;
-+ dp->capt.height = capt.height;
-+#ifdef ALLOW_SCAPTURE_WHILE_CAP
-+ if (dp->ovl_active)
-+ dp->ovl->ctl(dp, dp->ovl, 0);
-+ if (dp->cap_active)
-+ cyberpro_capture(dp, 0);
-+#endif
-+ cyberpro_capture_set_win(dp);
-+
-+ /*
-+ * Update the overlay window information
-+ */
-+ dp->ovl->src.width = capt.width;
-+ dp->ovl->src.height = capt.height;
-+
-+ dp->ovl->set_src(dp, dp->ovl);
-+ if (dp->win_set)
-+ dp->ovl->set_win(dp, dp->ovl);
-+
-+#ifdef ALLOW_SCAPTURE_WHILE_CAP
-+ if (dp->cap_active)
-+ cyberpro_capture(dp, 1);
-+ if (dp->ovl_active)
-+ dp->ovl->ctl(dp, dp->ovl, 1);
-+#endif
-+ return 0;
-+ }
-+
-+ case VIDIOCGTUNER: /* no tuner */
-+ case VIDIOCSTUNER:
-+ return -EINVAL;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+#ifdef USE_MMAP
-+static int
-+cyberpro_grabber_mmap(struct video_device *dev, const char *addr, unsigned long size)
-+{
-+ struct cyberpro_vidinfo *dp = dev->priv;
-+ unsigned long vaddr = (unsigned long)addr;
-+ pgprot_t prot;
-+ int frame_idx, ret = -EINVAL;
-+
-+#if defined(__arm__)
-+ prot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_USER | L_PTE_WRITE | L_PTE_DIRTY);
-+#elif defined(__i386__)
-+ prot = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED);
-+ if (boot_cpu_data.x86 > 3)
-+ pgprot_val(prot) |= _PAGE_PCD;
-+#else
-+#error "Unsupported architecture"
-+#endif
-+
-+ /*
-+ * The mmap() request must have the correct size.
-+ */
-+ if (size != NR_FRAMES * dp->frame_size)
-+ goto out;
-+
-+ /*
-+ * If it's already mapped, don't re-do
-+ */
-+ if (dp->mmaped)
-+ goto out;
-+ dp->mmaped = 1;
-+
-+ /*
-+ * Map in each frame
-+ */
-+ for (frame_idx = 0; frame_idx < NR_FRAMES; frame_idx++) {
-+ struct framebuf *frame;
-+ int pgidx;
-+
-+ frame = dp->frame + frame_idx;
-+
-+ ret = cyberpro_alloc_frame_buffer(dp, frame);
-+
-+ /*
-+ * If an error occurs, we can be lazy and leave what we've
-+ * been able to do. Our release function will free any
-+ * allocated buffers, and do_mmap_pgoff() will zap any
-+ * inserted mappings.
-+ */
-+ if (ret)
-+ goto out2;
-+
-+ /*
-+ * Map in each page on a page by page basis. This is just
-+ * a little on the inefficient side, but it's only run once.
-+ */
-+ for (pgidx = 0; pgidx < NR_PAGES; pgidx++) {
-+ unsigned long virt;
-+
-+ virt = page_address(frame->pages[pgidx]);
-+
-+ ret = remap_page_range(vaddr, virt_to_phys((void *)virt),
-+ PAGE_SIZE, prot);
-+
-+ if (ret)
-+ goto out2;
-+
-+ vaddr += PAGE_SIZE;
-+ }
-+ }
-+
-+ out2:
-+ if (ret)
-+ dp->mmaped = 0;
-+ out:
-+ return ret;
-+}
-+#endif
-+
-+static int __init cyberpro_grabber_init_done(struct video_device *dev)
-+{
-+ struct cyberpro_vidinfo *dp;
-+ struct cyberpro_info *info = dev->priv;
-+ int ret;
-+
-+ dp = kmalloc(sizeof(*dp), GFP_KERNEL);
-+ if (!dp)
-+ return -ENOMEM;
-+
-+ memset(dp, 0, sizeof(*dp));
-+
-+ dev->priv = dp;
-+ dp->info = *info;
-+ dp->dev = dev;
-+ dp->bus = &cyberpro_i2c_bus;
-+ dp->regs = info->regs;
-+ dp->irq = info->dev->irq;
-+
-+ strcpy(dp->cap.name, dev->name);
-+ dp->cap.type = dev->type;
-+ dp->cap.channels = 1;
-+ dp->cap.audios = 0;
-+ dp->cap.minwidth = 32;
-+ dp->cap.maxwidth = 716;
-+ dp->cap.minheight = 32;
-+ dp->cap.maxheight = 576;
-+
-+ dp->pic.brightness = 32768;
-+ dp->pic.hue = 32768;
-+ dp->pic.colour = 32768;
-+ dp->pic.contrast = 32768;
-+ dp->pic.whiteness = 0;
-+ dp->pic.depth = 8;
-+ dp->pic.palette = VIDEO_PALETTE_YUV422;
-+
-+ /* dp->buf is setup by the user */
-+ /* dp->cap_mem_offset setup by dp->buf */
-+
-+ dp->norm = VIDEO_MODE_AUTO;
-+
-+ /*
-+ * The extended overlay window
-+ */
-+ dp->ext.init = cyberpro_ext_init;
-+ dp->ext.set_src = cyberpro_ext_set_src;
-+ dp->ext.set_win = cyberpro_ext_set_win;
-+ dp->ext.ctl = cyberpro_ext_ctl;
-+
-+ /*
-+ * The V2 overlay window
-+ */
-+ dp->v2.init = cyberpro_v2_init;
-+ dp->v2.set_src = cyberpro_v2_set_src;
-+ dp->v2.set_win = cyberpro_v2_set_win;
-+ dp->v2.ctl = cyberpro_v2_ctl;
-+
-+ /*
-+ * The X2 overlay window
-+ */
-+ dp->x2.init = cyberpro_x2_init;
-+ dp->x2.set_src = cyberpro_x2_set_src;
-+ dp->x2.set_win = cyberpro_x2_set_win;
-+ dp->x2.ctl = cyberpro_x2_ctl;
-+
-+ /*
-+ * Set the overlay window which we shall be using
-+ */
-+ dp->ovl = &dp->ext;
-+
-+ dp->cap_mode1 = EXT_CAP_MODE1_ALTFIFO;
-+
-+ /*
-+ * Initialise hardware specific values.
-+ * - CCIR656 8bit mode (YUV422 data)
-+ * - Ignore Hgood signal
-+ * - Invert Odd/Even field signal
-+ */
-+ dp->cap_mode1 |= EXT_CAP_MODE1_CCIR656 | EXT_CAP_MODE1_8BIT;
-+ dp->cap_mode2 = EXT_CAP_MODE2_FIXSONY | EXT_CAP_MODE2_DATEND |
-+ EXT_CAP_MODE2_CCIRINVOE;
-+ dp->stream_fmt = VIDEO_PALETTE_YUV422;
-+
-+
-+ init_waitqueue_head(&dp->vbl_wait);
-+ cyberpro_frames_init(dp);
-+
-+ /*
-+ * wake up the decoder
-+ */
-+ decoder_sleep(0);
-+
-+ dp->bus->data = dp;
-+ strncpy(dp->bus->name, dev->name, sizeof(dp->bus->name));
-+
-+ pci_set_master(dp->info.dev);
-+
-+ ret = i2c_register_bus(dp->bus);
-+
-+ /*
-+ * If we successfully registered the bus, but didn't initialise
-+ * the decoder (because its driver is not present), request
-+ * that it is loaded.
-+ */
-+ if (ret == 0 && !dp->decoder)
-+ request_module("saa7111");
-+
-+ /*
-+ * If that didn't work, then we're out of luck.
-+ */
-+ if (ret == 0 && !dp->decoder) {
-+ i2c_unregister_bus(dp->bus);
-+ ret = -ENXIO;
-+ }
-+
-+ if (ret) {
-+ kfree(dp);
-+
-+ /*
-+ * put the decoder back to sleep
-+ */
-+ decoder_sleep(1);
-+ }
-+
-+ return ret;
-+}
-+
-+static struct video_device cyberpro_grabber = {
-+ name: "",
-+ type: VID_TYPE_CAPTURE | VID_TYPE_OVERLAY |
-+ VID_TYPE_CHROMAKEY | VID_TYPE_SCALES |
-+ VID_TYPE_SUBCAPTURE,
-+ hardware: 0,
-+ open: cyberpro_grabber_open,
-+ close: cyberpro_grabber_close,
-+ read: cyberpro_grabber_read,
-+ write: cyberpro_grabber_write,
-+ ioctl: cyberpro_grabber_ioctl,
-+#ifdef USE_MMAP
-+ mmap: cyberpro_grabber_mmap,
-+#endif
-+ initialize: cyberpro_grabber_init_done,
-+};
-+
-+int init_cyber2000fb_viddev(void)
-+{
-+ struct cyberpro_info info;
-+
-+ if (!cyber2000fb_attach(&info, 0))
-+ return -ENXIO;
-+
-+ strncpy(cyberpro_grabber.name, info.dev_name, sizeof(cyberpro_grabber.name));
-+
-+ cyberpro_grabber.priv = &info;
-+
-+ return video_register_device(&cyberpro_grabber, VFL_TYPE_GRABBER, -1);
-+}
-+
-+/*
-+ * This can be cleaned up when the SAA7111 code is fixed.
-+ */
-+#ifdef MODULE
-+static int __init cyberpro_init(void)
-+{
-+ disable_irq(35);
-+ return init_cyber2000fb_viddev();
-+}
-+
-+static void __exit cyberpro_exit(void)
-+{
-+ video_unregister_device(&cyberpro_grabber);
-+ kfree(cyberpro_grabber.priv);
-+ i2c_unregister_bus(&cyberpro_i2c_bus);
-+
-+ /*
-+ * put the decoder back to sleep
-+ */
-+ decoder_sleep(1);
-+
-+ cyber2000fb_detach(0);
-+}
-+
-+module_init(cyberpro_init);
-+module_exit(cyberpro_exit);
-+#endif
---- linux-2.4.25/drivers/media/video/i2c-old.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/media/video/i2c-old.c 2004-03-31 17:15:09.000000000 +0200
-@@ -36,11 +36,20 @@
- static struct i2c_driver *drivers[I2C_DRIVER_MAX];
- static int bus_count = 0, driver_count = 0;
-
-+extern int saa7111_init(void);
-+extern int saa7185_init(void);
-+extern int bt819_init(void);
-+extern int bt856_init(void);
-+
- int i2c_init(void)
- {
- printk(KERN_INFO "i2c: initialized%s\n",
- scan ? " (i2c bus scan enabled)" : "");
-
-+#if defined(CONFIG_VIDEO_CYBERPRO)
-+ saa7111_init();
-+#endif
-+
- return 0;
- }
-
-@@ -52,10 +61,10 @@
- int i,j,ack=1;
- unsigned char addr;
- LOCK_FLAGS;
--
-+
- /* probe for device */
- LOCK_I2C_BUS(bus);
-- for (addr = driver->addr_l; addr <= driver->addr_h; addr += 2)
-+ for (addr = driver->addr_l; addr <= driver->addr_h; addr += 2)
- {
- i2c_start(bus);
- ack = i2c_sendbyte(bus,addr,0);
-@@ -87,8 +96,8 @@
- device->addr = addr;
-
- /* Attach */
--
-- if (driver->attach(device)!=0)
-+
-+ if (driver->attach(device)!=0)
- {
- kfree(device);
- return;
-@@ -114,7 +123,7 @@
- for (i = 0; i < I2C_DEVICE_MAX; i++)
- if (device == device->driver->devices[i])
- break;
-- if (I2C_DEVICE_MAX == i)
-+ if (I2C_DEVICE_MAX == i)
- {
- printk(KERN_WARNING "i2c: detach_device #1: device not found: %s\n",
- device->name);
-@@ -126,7 +135,7 @@
- for (i = 0; i < I2C_DEVICE_MAX; i++)
- if (device == device->bus->devices[i])
- break;
-- if (I2C_DEVICE_MAX == i)
-+ if (I2C_DEVICE_MAX == i)
- {
- printk(KERN_WARNING "i2c: detach_device #2: device not found: %s\n",
- device->name);
-@@ -158,19 +167,19 @@
- busses[i] = bus;
- bus_count++;
- REGPRINT(printk("i2c: bus registered: %s\n",bus->name));
--
-+
- MOD_INC_USE_COUNT;
-
-- if (scan)
-+ if (scan)
- {
- /* scan whole i2c bus */
- LOCK_I2C_BUS(bus);
-- for (i = 0; i < 256; i+=2)
-+ for (i = 0; i < 256; i+=2)
- {
- i2c_start(bus);
- ack = i2c_sendbyte(bus,i,0);
- i2c_stop(bus);
-- if (!ack)
-+ if (!ack)
- {
- printk(KERN_INFO "i2c: scanning bus %s: found device at addr=0x%02x\n",
- bus->name,i);
-@@ -198,20 +207,20 @@
- for (i = 0; i < I2C_BUS_MAX; i++)
- if (bus == busses[i])
- break;
-- if (I2C_BUS_MAX == i)
-+ if (I2C_BUS_MAX == i)
- {
- printk(KERN_WARNING "i2c: unregister_bus #1: bus not found: %s\n",
- bus->name);
- return -ENODEV;
- }
--
-+
- MOD_DEC_USE_COUNT;
--
-+
- busses[i] = NULL;
- bus_count--;
- REGPRINT(printk("i2c: bus unregistered: %s\n",bus->name));
-
-- return 0;
-+ return 0;
- }
-
- /* ----------------------------------------------------------------------- */
-@@ -231,9 +240,9 @@
-
- drivers[i] = driver;
- driver_count++;
--
-+
- MOD_INC_USE_COUNT;
--
-+
- REGPRINT(printk("i2c: driver registered: %s\n",driver->name));
-
- /* Probe available busses */
-@@ -256,7 +265,7 @@
- for (i = 0; i < I2C_DRIVER_MAX; i++)
- if (driver == drivers[i])
- break;
-- if (I2C_DRIVER_MAX == i)
-+ if (I2C_DRIVER_MAX == i)
- {
- printk(KERN_WARNING "i2c: unregister_driver: driver not found: %s\n",
- driver->name);
-@@ -264,7 +273,7 @@
- }
-
- MOD_DEC_USE_COUNT;
--
-+
- drivers[i] = NULL;
- driver_count--;
- REGPRINT(printk("i2c: driver unregistered: %s\n",driver->name));
-@@ -328,7 +337,7 @@
- int i2c_ack(struct i2c_bus *bus)
- {
- int ack;
--
-+
- I2C_SET(bus,0,1);
- I2C_SET(bus,1,1);
- ack = I2C_GET(bus);
-@@ -339,7 +348,7 @@
- int i2c_sendbyte(struct i2c_bus *bus,unsigned char data,int wait_for_ack)
- {
- int i, ack;
--
-+
- I2C_SET(bus,0,0);
- for (i=7; i>=0; i--)
- (data&(1<<i)) ? i2c_one(bus) : i2c_zero(bus);
-@@ -354,9 +363,9 @@
- {
- int i;
- unsigned char data=0;
--
-+
- I2C_SET(bus,0,1);
-- for (i=7; i>=0; i--)
-+ for (i=7; i>=0; i--)
- {
- I2C_SET(bus,1,1);
- if (I2C_GET(bus))
-@@ -373,7 +382,7 @@
- int i2c_read(struct i2c_bus *bus, unsigned char addr)
- {
- int ret;
--
-+
- if (bus->i2c_read)
- return bus->i2c_read(bus, addr);
-
---- linux-2.4.25/drivers/media/video/saa7111.c~2.4.25-vrs2.patch 2001-09-30 21:26:06.000000000 +0200
-+++ linux-2.4.25/drivers/media/video/saa7111.c 2004-03-31 17:15:09.000000000 +0200
-@@ -20,9 +20,9 @@
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
--
--#include <linux/module.h>
-+#include <linux/config.h>
- #include <linux/init.h>
-+#include <linux/module.h>
- #include <linux/delay.h>
- #include <linux/errno.h>
- #include <linux/fs.h>
-@@ -149,7 +149,11 @@
- 0x0d, 0x00, /* 0d - HUE=0 */
- 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
- 0x0f, 0x00, /* 0f - reserved */
-+#ifndef CONFIG_ARCH_NETWINDER
- 0x10, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
-+#else
-+ 0x10, 0xc8, /* 10 - OFTS=YUV-CCIR656, HDEL=0, VLRN=1, YDEL=0 */
-+#endif
- 0x11, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
- 0x12, 0x00, /* 12 - output control 2 */
- 0x13, 0x00, /* 13 - output control 3 */
---- linux-2.4.25/drivers/message/i2o/i2o_core.c~2.4.25-vrs2.patch 2003-06-13 16:51:34.000000000 +0200
-+++ linux-2.4.25/drivers/message/i2o/i2o_core.c 2004-03-31 17:15:09.000000000 +0200
-@@ -1665,14 +1665,14 @@
- }
- memset(status, 0, 4);
-
-- msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0;
-- msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID;
-- msg[2]=core_context;
-- msg[3]=0;
-- msg[4]=0;
-- msg[5]=0;
-- msg[6]=virt_to_bus(status);
-- msg[7]=0; /* 64bit host FIXME */
-+ writel(EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0, msg + 0);
-+ writel(I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID, msg + 1);
-+ writel(core_context, msg + 2);
-+ writel(0, msg + 3);
-+ writel(0, msg + 4);
-+ writel(0, msg + 5);
-+ writel(virt_to_bus(status), msg + 6);
-+ writel(0, msg + 7); /* 64bit host FIXME */
-
- i2o_post_message(c,m);
-
-@@ -1781,15 +1781,15 @@
- return -ETIMEDOUT;
- msg=(u32 *)(c->mem_offset+m);
-
-- msg[0]=NINE_WORD_MSG_SIZE|SGL_OFFSET_0;
-- msg[1]=I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID;
-- msg[2]=core_context;
-- msg[3]=0;
-- msg[4]=0;
-- msg[5]=0;
-- msg[6]=virt_to_bus(c->status_block);
-- msg[7]=0; /* 64bit host FIXME */
-- msg[8]=sizeof(i2o_status_block); /* always 88 bytes */
-+ writel(NINE_WORD_MSG_SIZE|SGL_OFFSET_0, msg + 0);
-+ writel(I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID, msg + 1);
-+ writel(core_context, msg + 2);
-+ writel(0, msg + 3);
-+ writel(0, msg + 4);
-+ writel(0, msg + 5);
-+ writel(virt_to_bus(c->status_block), msg + 6);
-+ writel(0, msg + 7); /* 64bit host FIXME */
-+ writel(sizeof(i2o_status_block), msg + 8); /* always 88 bytes */
-
- i2o_post_message(c,m);
-
-@@ -2193,15 +2193,15 @@
- }
- memset(status, 0, 4);
-
-- msg[0]= EIGHT_WORD_MSG_SIZE| TRL_OFFSET_6;
-- msg[1]= I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID;
-- msg[2]= core_context;
-- msg[3]= 0x0106; /* Transaction context */
-- msg[4]= 4096; /* Host page frame size */
-+ writel(EIGHT_WORD_MSG_SIZE| TRL_OFFSET_6, msg + 0);
-+ writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, msg + 1);
-+ writel(core_context, msg + 2);
-+ writel(0x0106, msg + 3); /* Transaction context */
-+ writel(PAGE_SIZE, msg + 4); /* Host page frame size */
- /* Frame size is in words. 256 bytes a frame for now */
-- msg[5]= MSG_FRAME_SIZE<<16|0x80; /* Outbound msg frame size in words and Initcode */
-- msg[6]= 0xD0000004; /* Simple SG LE, EOB */
-- msg[7]= virt_to_bus(status);
-+ writel(MSG_FRAME_SIZE<<16|0x80, msg + 5);/* Outbound msg frame size in words and Initcode */
-+ writel(0xD0000004, msg + 6); /* Simple SG LE, EOB */
-+ writel(virt_to_bus(status), msg + 7);
-
- i2o_post_message(c,m);
-
---- linux-2.4.25/drivers/message/i2o/i2o_pci.c~2.4.25-vrs2.patch 2002-11-29 00:53:13.000000000 +0100
-+++ linux-2.4.25/drivers/message/i2o/i2o_pci.c 2004-03-31 17:15:09.000000000 +0200
-@@ -390,4 +390,4 @@
- MODULE_PARM_DESC(dpt, "Set this if you want to drive DPT cards normally handled by dpt_i2o");
- module_init(i2o_pci_core_attach);
- module_exit(i2o_pci_core_detach);
--
-\ No newline at end of file
-+
---- linux-2.4.25/drivers/misc/Config.in~2.4.25-vrs2.patch 1999-12-26 00:04:56.000000000 +0100
-+++ linux-2.4.25/drivers/misc/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -1,7 +1,17 @@
- #
--# Misc strange devices
-+# MCP drivers
- #
- mainmenu_option next_comment
--comment 'Misc devices'
-+comment 'Multimedia Capabilities Port drivers'
-+
-+bool 'Multimedia drivers' CONFIG_MCP
-+
-+# Interface drivers
-+dep_bool 'Support SA1100 MCP interface' CONFIG_MCP_SA1100 $CONFIG_MCP $CONFIG_ARCH_SA1100
-+
-+# Chip drivers
-+dep_tristate 'Support for UCB1200 / UCB1300' CONFIG_MCP_UCB1200 $CONFIG_MCP
-+dep_tristate ' Audio / Telephony interface support' CONFIG_MCP_UCB1200_AUDIO $CONFIG_MCP_UCB1200 $CONFIG_SOUND
-+dep_tristate ' Touchscreen interface support' CONFIG_MCP_UCB1200_TS $CONFIG_MCP_UCB1200
-
- endmenu
---- linux-2.4.25/drivers/misc/Makefile~2.4.25-vrs2.patch 2000-12-29 23:07:22.000000000 +0100
-+++ linux-2.4.25/drivers/misc/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -11,6 +11,14 @@
-
- O_TARGET := misc.o
-
-+export-objs := mcp-core.o mcp-sa1100.o ucb1x00-core.o
-+
-+obj-$(CONFIG_MCP) += mcp-core.o
-+obj-$(CONFIG_MCP_SA1100) += mcp-sa1100.o
-+obj-$(CONFIG_MCP_UCB1200) += ucb1x00-core.o
-+obj-$(CONFIG_MCP_UCB1200_AUDIO) += ucb1x00-audio.o
-+obj-$(CONFIG_MCP_UCB1200_TS) += ucb1x00-ts.o
-+
- include $(TOPDIR)/Rules.make
-
- fastdep:
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/misc/mcp-core.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,155 @@
-+/*
-+ * linux/drivers/misc/mcp-core.c
-+ *
-+ * Copyright (C) 2001 Russell King
-+ *
-+ * 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.
-+ *
-+ * Generic MCP (Multimedia Communications Port) layer. All MCP locking
-+ * is solely held within this file.
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/smp.h>
-+
-+#include <asm/dma.h>
-+#include <asm/system.h>
-+
-+#include "mcp.h"
-+
-+/**
-+ * mcp_set_telecom_divisor - set the telecom divisor
-+ * @mcp: MCP interface structure
-+ * @div: SIB clock divisor
-+ *
-+ * Set the telecom divisor on the MCP interface. The resulting
-+ * sample rate is SIBCLOCK/div.
-+ */
-+void mcp_set_telecom_divisor(struct mcp *mcp, unsigned int div)
-+{
-+ spin_lock_irq(&mcp->lock);
-+ mcp->set_telecom_divisor(mcp, div);
-+ spin_unlock_irq(&mcp->lock);
-+}
-+
-+/**
-+ * mcp_set_audio_divisor - set the audio divisor
-+ * @mcp: MCP interface structure
-+ * @div: SIB clock divisor
-+ *
-+ * Set the audio divisor on the MCP interface.
-+ */
-+void mcp_set_audio_divisor(struct mcp *mcp, unsigned int div)
-+{
-+ spin_lock_irq(&mcp->lock);
-+ mcp->set_audio_divisor(mcp, div);
-+ spin_unlock_irq(&mcp->lock);
-+}
-+
-+/**
-+ * mcp_reg_write - write a device register
-+ * @mcp: MCP interface structure
-+ * @reg: 4-bit register index
-+ * @val: 16-bit data value
-+ *
-+ * Write a device register. The MCP interface must be enabled
-+ * to prevent this function hanging.
-+ */
-+void mcp_reg_write(struct mcp *mcp, unsigned int reg, unsigned int val)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&mcp->lock, flags);
-+ mcp->reg_write(mcp, reg, val);
-+ spin_unlock_irqrestore(&mcp->lock, flags);
-+}
-+
-+/**
-+ * mcp_reg_read - read a device register
-+ * @mcp: MCP interface structure
-+ * @reg: 4-bit register index
-+ *
-+ * Read a device register and return its value. The MCP interface
-+ * must be enabled to prevent this function hanging.
-+ */
-+unsigned int mcp_reg_read(struct mcp *mcp, unsigned int reg)
-+{
-+ unsigned long flags;
-+ unsigned int val;
-+
-+ spin_lock_irqsave(&mcp->lock, flags);
-+ val = mcp->reg_read(mcp, reg);
-+ spin_unlock_irqrestore(&mcp->lock, flags);
-+
-+ return val;
-+}
-+
-+/**
-+ * mcp_enable - enable the MCP interface
-+ * @mcp: MCP interface to enable
-+ *
-+ * Enable the MCP interface. Each call to mcp_enable will need
-+ * a corresponding call to mcp_disable to disable the interface.
-+ */
-+void mcp_enable(struct mcp *mcp)
-+{
-+ spin_lock_irq(&mcp->lock);
-+ if (mcp->use_count++ == 0)
-+ mcp->enable(mcp);
-+ spin_unlock_irq(&mcp->lock);
-+}
-+
-+/**
-+ * mcp_disable - disable the MCP interface
-+ * @mcp: MCP interface to disable
-+ *
-+ * Disable the MCP interface. The MCP interface will only be
-+ * disabled once the number of calls to mcp_enable matches the
-+ * number of calls to mcp_disable.
-+ */
-+void mcp_disable(struct mcp *mcp)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&mcp->lock, flags);
-+ if (--mcp->use_count == 0)
-+ mcp->disable(mcp);
-+ spin_unlock_irqrestore(&mcp->lock, flags);
-+}
-+
-+
-+/*
-+ * This needs re-working
-+ */
-+static struct mcp *mcp_if;
-+
-+struct mcp *mcp_get(void)
-+{
-+ return mcp_if;
-+}
-+
-+int mcp_register(struct mcp *mcp)
-+{
-+ if (mcp_if)
-+ return -EBUSY;
-+ if (mcp->owner)
-+ __MOD_INC_USE_COUNT(mcp->owner);
-+ mcp_if = mcp;
-+ return 0;
-+}
-+
-+EXPORT_SYMBOL(mcp_set_telecom_divisor);
-+EXPORT_SYMBOL(mcp_set_audio_divisor);
-+EXPORT_SYMBOL(mcp_reg_write);
-+EXPORT_SYMBOL(mcp_reg_read);
-+EXPORT_SYMBOL(mcp_enable);
-+EXPORT_SYMBOL(mcp_disable);
-+EXPORT_SYMBOL(mcp_get);
-+EXPORT_SYMBOL(mcp_register);
-+
-+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-+MODULE_DESCRIPTION("Core multimedia communications port driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/misc/mcp-sa1100.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,180 @@
-+/*
-+ * linux/drivers/misc/mcp-sa1100.c
-+ *
-+ * Copyright (C) 2001 Russell King
-+ *
-+ * 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.
-+ *
-+ * SA1100 MCP (Multimedia Communications Port) driver.
-+ *
-+ * MCP read/write timeouts from Jordi Colomer, rehacked by rmk.
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/spinlock.h>
-+
-+#include <asm/dma.h>
-+#include <asm/hardware.h>
-+#include <asm/system.h>
-+
-+#include "mcp.h"
-+
-+static void
-+mcp_sa1100_set_telecom_divisor(struct mcp *mcp, unsigned int divisor)
-+{
-+ unsigned int mccr0;
-+
-+ divisor /= 32;
-+
-+ mccr0 = Ser4MCCR0 & ~0x00007f00;
-+ mccr0 |= divisor << 8;
-+ Ser4MCCR0 = mccr0;
-+}
-+
-+static void
-+mcp_sa1100_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
-+{
-+ unsigned int mccr0;
-+
-+ divisor /= 32;
-+
-+ mccr0 = Ser4MCCR0 & ~0x0000007f;
-+ mccr0 |= divisor;
-+ Ser4MCCR0 = mccr0;
-+}
-+
-+/*
-+ * Write data to the device. The bit should be set after 3 subframe
-+ * times (each frame is 64 clocks). We wait a maximum of 6 subframes.
-+ * We really should try doing something more productive while we
-+ * wait.
-+ */
-+static void
-+mcp_sa1100_write(struct mcp *mcp, unsigned int reg, unsigned int val)
-+{
-+ int ret = -ETIME;
-+ int i;
-+
-+ Ser4MCDR2 = reg << 17 | MCDR2_Wr | (val & 0xffff);
-+
-+ for (i = 0; i < 2; i++) {
-+ udelay(mcp->rw_timeout);
-+ if (Ser4MCSR & MCSR_CWC) {
-+ ret = 0;
-+ break;
-+ }
-+ }
-+
-+ if (ret < 0)
-+ printk(KERN_WARNING "mcp: write timed out\n");
-+}
-+
-+/*
-+ * Read data from the device. The bit should be set after 3 subframe
-+ * times (each frame is 64 clocks). We wait a maximum of 6 subframes.
-+ * We really should try doing something more productive while we
-+ * wait.
-+ */
-+static unsigned int
-+mcp_sa1100_read(struct mcp *mcp, unsigned int reg)
-+{
-+ int ret = -ETIME;
-+ int i;
-+
-+ Ser4MCDR2 = reg << 17 | MCDR2_Rd;
-+
-+ for (i = 0; i < 2; i++) {
-+ udelay(mcp->rw_timeout);
-+ if (Ser4MCSR & MCSR_CRC) {
-+ ret = Ser4MCDR2 & 0xffff;
-+ break;
-+ }
-+ }
-+
-+ if (ret < 0)
-+ printk(KERN_WARNING "mcp: read timed out\n");
-+
-+ return ret;
-+}
-+
-+static void mcp_sa1100_enable(struct mcp *mcp)
-+{
-+ Ser4MCSR = -1;
-+ Ser4MCCR0 |= MCCR0_MCE;
-+}
-+
-+static void mcp_sa1100_disable(struct mcp *mcp)
-+{
-+ Ser4MCCR0 &= ~MCCR0_MCE;
-+}
-+
-+struct mcp mcp_sa1100 = {
-+ owner: THIS_MODULE,
-+ lock: SPIN_LOCK_UNLOCKED,
-+ sclk_rate: 11981000,
-+ dma_audio_rd: DMA_Ser4MCP0Rd,
-+ dma_audio_wr: DMA_Ser4MCP0Wr,
-+ dma_telco_rd: DMA_Ser4MCP1Rd,
-+ dma_telco_wr: DMA_Ser4MCP1Wr,
-+ set_telecom_divisor: mcp_sa1100_set_telecom_divisor,
-+ set_audio_divisor: mcp_sa1100_set_audio_divisor,
-+ reg_write: mcp_sa1100_write,
-+ reg_read: mcp_sa1100_read,
-+ enable: mcp_sa1100_enable,
-+ disable: mcp_sa1100_disable,
-+};
-+
-+/*
-+ * This needs re-working
-+ */
-+static int mcp_sa1100_init(void)
-+{
-+ struct mcp *mcp = &mcp_sa1100;
-+ int ret = -ENODEV;
-+
-+ if (machine_is_accelent_sa() ||
-+ machine_is_adsbitsy() || machine_is_assabet() ||
-+ machine_is_cerf() || machine_is_flexanet() ||
-+ machine_is_freebird() || machine_is_graphicsclient() ||
-+ machine_is_graphicsmaster() || machine_is_lart() ||
-+ machine_is_omnimeter() || machine_is_pfs168() ||
-+ machine_is_shannon() || machine_is_simpad() ||
-+ machine_is_simputer() || machine_is_yopy()) {
-+ /*
-+ * Setup the PPC unit correctly.
-+ */
-+ PPDR &= ~PPC_RXD4;
-+ PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
-+ PSDR |= PPC_RXD4;
-+ PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-+ PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-+
-+ Ser4MCSR = -1;
-+ Ser4MCCR1 = 0;
-+ Ser4MCCR0 = 0x00007f7f | MCCR0_ADM;
-+
-+ /*
-+ * Calculate the read/write timeout (us) from the bit clock
-+ * rate. This is the period for 3 64-bit frames. Always
-+ * round this time up.
-+ */
-+ mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) /
-+ mcp->sclk_rate;
-+
-+ ret = mcp_register(mcp);
-+ }
-+
-+ return ret;
-+}
-+
-+module_init(mcp_sa1100_init);
-+EXPORT_SYMBOL(mcp_sa1100_init);
-+
-+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-+MODULE_DESCRIPTION("SA11x0 multimedia communications port driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/misc/mcp.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,44 @@
-+/*
-+ * linux/drivers/misc/mcp.h
-+ *
-+ * Copyright (C) 2001 Russell King, 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.
-+ */
-+#ifndef MCP_H
-+#define MCP_H
-+
-+struct mcp {
-+ struct module *owner;
-+ spinlock_t lock;
-+ int use_count;
-+ unsigned int sclk_rate;
-+ unsigned int rw_timeout;
-+ dma_device_t dma_audio_rd;
-+ dma_device_t dma_audio_wr;
-+ dma_device_t dma_telco_rd;
-+ dma_device_t dma_telco_wr;
-+ void (*set_telecom_divisor)(struct mcp *, unsigned int);
-+ void (*set_audio_divisor)(struct mcp *, unsigned int);
-+ void (*reg_write)(struct mcp *, unsigned int, unsigned int);
-+ unsigned int (*reg_read)(struct mcp *, unsigned int);
-+ void (*enable)(struct mcp *);
-+ void (*disable)(struct mcp *);
-+};
-+
-+void mcp_set_telecom_divisor(struct mcp *, unsigned int);
-+void mcp_set_audio_divisor(struct mcp *, unsigned int);
-+void mcp_reg_write(struct mcp *, unsigned int, unsigned int);
-+unsigned int mcp_reg_read(struct mcp *, unsigned int);
-+void mcp_enable(struct mcp *);
-+void mcp_disable(struct mcp *);
-+
-+/* noddy implementation alert! */
-+struct mcp *mcp_get(void);
-+int mcp_register(struct mcp *);
-+
-+#define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate)
-+
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/misc/ucb1x00-audio.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,378 @@
-+/*
-+ * linux/drivers/misc/ucb1x00-audio.c
-+ *
-+ * Copyright (C) 2001 Russell King, 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 version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/fs.h>
-+#include <linux/errno.h>
-+#include <linux/slab.h>
-+#include <linux/sound.h>
-+#include <linux/soundcard.h>
-+#include <linux/list.h>
-+
-+#include <asm/dma.h>
-+#include <asm/hardware.h>
-+#include <asm/semaphore.h>
-+#include <asm/uaccess.h>
-+
-+#include "ucb1x00.h"
-+
-+#include "../drivers/sound/sa1100-audio.h"
-+
-+#define MAGIC 0x41544154
-+
-+struct ucb1x00_audio {
-+ struct file_operations fops;
-+ struct file_operations mops;
-+ struct ucb1x00 *ucb;
-+ audio_stream_t output_stream;
-+ audio_stream_t input_stream;
-+ audio_state_t state;
-+ unsigned int rate;
-+ int dev_id;
-+ int mix_id;
-+ unsigned int daa_oh_bit;
-+ unsigned int telecom;
-+ unsigned int magic;
-+ unsigned int ctrl_a;
-+ unsigned int ctrl_b;
-+
-+ /* mixer info */
-+ unsigned int mod_cnt;
-+ unsigned short output_level;
-+ unsigned short input_level;
-+};
-+
-+#define REC_MASK (SOUND_MASK_VOLUME | SOUND_MASK_MIC)
-+#define DEV_MASK REC_MASK
-+
-+static int
-+ucb1x00_mixer_ioctl(struct inode *ino, struct file *filp, uint cmd, ulong arg)
-+{
-+ struct ucb1x00_audio *ucba;
-+ unsigned int val, gain;
-+ int ret = 0;
-+
-+ ucba = list_entry(filp->f_op, struct ucb1x00_audio, mops);
-+
-+ if (_IOC_TYPE(cmd) != 'M')
-+ return -EINVAL;
-+
-+ if (cmd == SOUND_MIXER_INFO) {
-+ struct mixer_info mi;
-+
-+ strncpy(mi.id, "UCB1x00", sizeof(mi.id));
-+ strncpy(mi.name, "Philips UCB1x00", sizeof(mi.name));
-+ mi.modify_counter = ucba->mod_cnt;
-+ return copy_to_user((void *)arg, &mi, sizeof(mi)) ? -EFAULT : 0;
-+ }
-+
-+ if (_IOC_DIR(cmd) & _IOC_WRITE) {
-+ unsigned int left, right;
-+
-+ ret = get_user(val, (unsigned int *)arg);
-+ if (ret)
-+ goto out;
-+
-+ left = val & 255;
-+ right = val >> 8;
-+
-+ if (left > 100)
-+ left = 100;
-+ if (right > 100)
-+ right = 100;
-+
-+ gain = (left + right) / 2;
-+
-+ ret = -EINVAL;
-+ if (!ucba->telecom) {
-+ switch(_IOC_NR(cmd)) {
-+ case SOUND_MIXER_VOLUME:
-+ ucba->output_level = gain | gain << 8;
-+ ucba->mod_cnt++;
-+ ucba->ctrl_b = (ucba->ctrl_b & 0xff00) |
-+ ((gain * 31) / 100);
-+ ucb1x00_reg_write(ucba->ucb, UCB_AC_B,
-+ ucba->ctrl_b);
-+ ret = 0;
-+ break;
-+
-+ case SOUND_MIXER_MIC:
-+ ucba->input_level = gain | gain << 8;
-+ ucba->mod_cnt++;
-+ ucba->ctrl_a = (ucba->ctrl_a & 0x7f) |
-+ (((gain * 31) / 100) << 7);
-+ ucb1x00_reg_write(ucba->ucb, UCB_AC_A,
-+ ucba->ctrl_a);
-+ ret = 0;
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) {
-+ switch (_IOC_NR(cmd)) {
-+ case SOUND_MIXER_VOLUME:
-+ val = ucba->output_level;
-+ break;
-+
-+ case SOUND_MIXER_MIC:
-+ val = ucba->input_level;
-+ break;
-+
-+ case SOUND_MIXER_RECSRC:
-+ case SOUND_MIXER_RECMASK:
-+ val = ucba->telecom ? 0 : REC_MASK;
-+ break;
-+
-+ case SOUND_MIXER_DEVMASK:
-+ val = ucba->telecom ? 0 : DEV_MASK;
-+ break;
-+
-+ case SOUND_MIXER_CAPS:
-+ case SOUND_MIXER_STEREODEVS:
-+ val = 0;
-+ break;
-+
-+ default:
-+ val = 0;
-+ ret = -EINVAL;
-+ break;
-+ }
-+
-+ if (ret == 0)
-+ ret = put_user(val, (int *)arg);
-+ }
-+ out:
-+ return ret;
-+}
-+
-+static int ucb1x00_audio_setrate(struct ucb1x00_audio *ucba, int rate)
-+{
-+ unsigned int div_rate = ucb1x00_clkrate(ucba->ucb) / 32;
-+ unsigned int div;
-+
-+ div = (div_rate + (rate / 2)) / rate;
-+ if (div < 6)
-+ div = 6;
-+ if (div > 127)
-+ div = 127;
-+
-+ ucba->ctrl_a = (ucba->ctrl_a & ~0x7f) | div;
-+
-+ if (ucba->telecom) {
-+ ucb1x00_reg_write(ucba->ucb, UCB_TC_B, 0);
-+ ucb1x00_set_telecom_divisor(ucba->ucb, div * 32);
-+ ucb1x00_reg_write(ucba->ucb, UCB_TC_A, ucba->ctrl_a);
-+ ucb1x00_reg_write(ucba->ucb, UCB_TC_B, ucba->ctrl_b);
-+ } else {
-+ ucb1x00_reg_write(ucba->ucb, UCB_AC_B, 0);
-+ ucb1x00_set_audio_divisor(ucba->ucb, div * 32);
-+ ucb1x00_reg_write(ucba->ucb, UCB_AC_A, ucba->ctrl_a);
-+ ucb1x00_reg_write(ucba->ucb, UCB_AC_B, ucba->ctrl_b);
-+ }
-+
-+ ucba->rate = div_rate / div;
-+
-+ return ucba->rate;
-+}
-+
-+static int ucb1x00_audio_getrate(struct ucb1x00_audio *ucba)
-+{
-+ return ucba->rate;
-+}
-+
-+static void ucb1x00_audio_startup(void *data)
-+{
-+ struct ucb1x00_audio *ucba = data;
-+
-+ ucb1x00_enable(ucba->ucb);
-+ ucb1x00_audio_setrate(ucba, ucba->rate);
-+
-+ ucb1x00_reg_write(ucba->ucb, UCB_MODE, UCB_MODE_DYN_VFLAG_ENA);
-+
-+ /*
-+ * Take off-hook
-+ */
-+ if (ucba->daa_oh_bit)
-+ ucb1x00_io_write(ucba->ucb, 0, ucba->daa_oh_bit);
-+}
-+
-+static void ucb1x00_audio_shutdown(void *data)
-+{
-+ struct ucb1x00_audio *ucba = data;
-+
-+ /*
-+ * Place on-hook
-+ */
-+ if (ucba->daa_oh_bit)
-+ ucb1x00_io_write(ucba->ucb, ucba->daa_oh_bit, 0);
-+
-+ ucb1x00_reg_write(ucba->ucb, ucba->telecom ? UCB_TC_B : UCB_AC_B, 0);
-+ ucb1x00_disable(ucba->ucb);
-+}
-+
-+static int
-+ucb1x00_audio_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
-+{
-+ struct ucb1x00_audio *ucba;
-+ int val, ret = 0;
-+
-+ ucba = list_entry(file->f_op, struct ucb1x00_audio, fops);
-+
-+ /*
-+ * Make sure we have our magic number
-+ */
-+ if (ucba->magic != MAGIC)
-+ return -ENODEV;
-+
-+ switch (cmd) {
-+ case SNDCTL_DSP_STEREO:
-+ ret = get_user(val, (int *)arg);
-+ if (ret)
-+ return ret;
-+ if (val != 0)
-+ return -EINVAL;
-+ val = 0;
-+ break;
-+
-+ case SNDCTL_DSP_CHANNELS:
-+ case SOUND_PCM_READ_CHANNELS:
-+ val = 1;
-+ break;
-+
-+ case SNDCTL_DSP_SPEED:
-+ ret = get_user(val, (int *)arg);
-+ if (ret)
-+ return ret;
-+ val = ucb1x00_audio_setrate(ucba, val);
-+ break;
-+
-+ case SOUND_PCM_READ_RATE:
-+ val = ucb1x00_audio_getrate(ucba);
-+ break;
-+
-+ case SNDCTL_DSP_SETFMT:
-+ case SNDCTL_DSP_GETFMTS:
-+ val = AFMT_S16_LE;
-+ break;
-+
-+ default:
-+ return ucb1x00_mixer_ioctl(inode, file, cmd, arg);
-+ }
-+
-+ return put_user(val, (int *)arg);
-+}
-+
-+static int ucb1x00_audio_open(struct inode *inode, struct file *file)
-+{
-+ struct ucb1x00_audio *ucba;
-+
-+ ucba = list_entry(file->f_op, struct ucb1x00_audio, fops);
-+
-+ return sa1100_audio_attach(inode, file, &ucba->state);
-+}
-+
-+static struct ucb1x00_audio *ucb1x00_audio_alloc(struct ucb1x00 *ucb)
-+{
-+ struct ucb1x00_audio *ucba;
-+
-+ ucba = kmalloc(sizeof(*ucba), GFP_KERNEL);
-+ if (ucba) {
-+ memset(ucba, 0, sizeof(*ucba));
-+
-+ ucba->magic = MAGIC;
-+ ucba->ucb = ucb;
-+ ucba->fops.owner = THIS_MODULE;
-+ ucba->fops.open = ucb1x00_audio_open;
-+ ucba->mops.owner = THIS_MODULE;
-+ ucba->mops.ioctl = ucb1x00_mixer_ioctl;
-+ ucba->state.output_stream = &ucba->output_stream;
-+ ucba->state.input_stream = &ucba->input_stream;
-+ ucba->state.data = ucba;
-+ ucba->state.hw_init = ucb1x00_audio_startup;
-+ ucba->state.hw_shutdown = ucb1x00_audio_shutdown;
-+ ucba->state.client_ioctl = ucb1x00_audio_ioctl;
-+
-+ /* There is a bug in the StrongARM causes corrupt MCP data to be sent to
-+ * the codec when the FIFOs are empty and writes are made to the OS timer
-+ * match register 0. To avoid this we must make sure that data is always
-+ * sent to the codec.
-+ */
-+ ucba->state.need_tx_for_rx = 1;
-+
-+ init_MUTEX(&ucba->state.sem);
-+ ucba->rate = 8000;
-+ }
-+ return ucba;
-+}
-+
-+static struct ucb1x00_audio *audio, *telecom;
-+
-+static int __init ucb1x00_audio_init(void)
-+{
-+ struct ucb1x00 *ucb = ucb1x00_get();
-+ struct ucb1x00_audio *a;
-+
-+ if (!ucb)
-+ return -ENODEV;
-+
-+ a = ucb1x00_audio_alloc(ucb);
-+ if (a) {
-+ a->state.input_dma = ucb->mcp->dma_audio_rd;
-+ a->state.input_id = "UCB1x00 audio in";
-+ a->state.output_dma = ucb->mcp->dma_audio_wr;
-+ a->state.output_id = "UCB1x00 audio out";
-+ a->dev_id = register_sound_dsp(&a->fops, -1);
-+ a->mix_id = register_sound_mixer(&a->mops, -1);
-+ a->ctrl_a = 0;
-+ a->ctrl_b = UCB_AC_B_IN_ENA|UCB_AC_B_OUT_ENA;
-+ audio = a;
-+ }
-+
-+ a = ucb1x00_audio_alloc(ucb);
-+ if (a) {
-+#if 0
-+ a->daa_oh_bit = UCB_IO_8;
-+
-+ ucb1x00_enable(ucb);
-+ ucb1x00_io_write(ucb, a->daa_oh_bit, 0);
-+ ucb1x00_io_set_dir(ucb, UCB_IO_7 | UCB_IO_6, a->daa_oh_bit);
-+ ucb1x00_disable(ucb);
-+#endif
-+
-+ a->telecom = 1;
-+ a->state.input_dma = ucb->mcp->dma_telco_rd;
-+ a->state.input_id = "UCB1x00 telco in";
-+ a->state.output_dma = ucb->mcp->dma_telco_wr;
-+ a->state.output_id = "UCB1x00 telco out";
-+ a->dev_id = register_sound_dsp(&a->fops, -1);
-+ a->mix_id = register_sound_mixer(&a->mops, -1);
-+ a->ctrl_a = 0;
-+ a->ctrl_b = UCB_TC_B_IN_ENA|UCB_TC_B_OUT_ENA;
-+ telecom = a;
-+ }
-+
-+ return 0;
-+}
-+
-+static void __exit ucb1x00_audio_exit(void)
-+{
-+ unregister_sound_dsp(telecom->dev_id);
-+ unregister_sound_dsp(audio->dev_id);
-+ unregister_sound_mixer(telecom->mix_id);
-+ unregister_sound_mixer(audio->mix_id);
-+}
-+
-+module_init(ucb1x00_audio_init);
-+module_exit(ucb1x00_audio_exit);
-+
-+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-+MODULE_DESCRIPTION("UCB1x00 telecom/audio driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/misc/ucb1x00-core.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,651 @@
-+/*
-+ * linux/drivers/misc/ucb1x00-core.c
-+ *
-+ * Copyright (C) 2001 Russell King, 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.
-+ *
-+ * The UCB1x00 core driver provides basic services for handling IO,
-+ * the ADC, interrupts, and accessing registers. It is designed
-+ * such that everything goes through this layer, thereby providing
-+ * a consistent locking methodology, as well as allowing the drivers
-+ * to be used on other non-MCP-enabled hardware platforms.
-+ *
-+ * Note that all locks are private to this file. Nothing else may
-+ * touch them.
-+ */
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/interrupt.h>
-+#include <linux/pm.h>
-+
-+#include <asm/dma.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/mach-types.h>
-+#include <asm/arch/shannon.h>
-+
-+#include "ucb1x00.h"
-+
-+/**
-+ * ucb1x00_io_set_dir - set IO direction
-+ * @ucb: UCB1x00 structure describing chip
-+ * @in: bitfield of IO pins to be set as inputs
-+ * @out: bitfield of IO pins to be set as outputs
-+ *
-+ * Set the IO direction of the ten general purpose IO pins on
-+ * the UCB1x00 chip. The @in bitfield has priority over the
-+ * @out bitfield, in that if you specify a pin as both input
-+ * and output, it will end up as an input.
-+ *
-+ * ucb1x00_enable must have been called to enable the comms
-+ * before using this function.
-+ *
-+ * This function takes a spinlock, disabling interrupts.
-+ */
-+void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int in, unsigned int out)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&ucb->io_lock, flags);
-+ ucb->io_dir |= out;
-+ ucb->io_dir &= ~in;
-+
-+ ucb1x00_reg_write(ucb, UCB_IO_DIR, ucb->io_dir);
-+ spin_unlock_irqrestore(&ucb->io_lock, flags);
-+}
-+
-+/**
-+ * ucb1x00_io_write - set or clear IO outputs
-+ * @ucb: UCB1x00 structure describing chip
-+ * @set: bitfield of IO pins to set to logic '1'
-+ * @clear: bitfield of IO pins to set to logic '0'
-+ *
-+ * Set the IO output state of the specified IO pins. The value
-+ * is retained if the pins are subsequently configured as inputs.
-+ * The @clear bitfield has priority over the @set bitfield -
-+ * outputs will be cleared.
-+ *
-+ * ucb1x00_enable must have been called to enable the comms
-+ * before using this function.
-+ *
-+ * This function takes a spinlock, disabling interrupts.
-+ */
-+void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int set, unsigned int clear)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&ucb->io_lock, flags);
-+ ucb->io_out |= set;
-+ ucb->io_out &= ~clear;
-+
-+ ucb1x00_reg_write(ucb, UCB_IO_DATA, ucb->io_out);
-+ spin_unlock_irqrestore(&ucb->io_lock, flags);
-+}
-+
-+/**
-+ * ucb1x00_io_read - read the current state of the IO pins
-+ * @ucb: UCB1x00 structure describing chip
-+ *
-+ * Return a bitfield describing the logic state of the ten
-+ * general purpose IO pins.
-+ *
-+ * ucb1x00_enable must have been called to enable the comms
-+ * before using this function.
-+ *
-+ * This function does not take any semaphores or spinlocks.
-+ */
-+unsigned int ucb1x00_io_read(struct ucb1x00 *ucb)
-+{
-+ return ucb1x00_reg_read(ucb, UCB_IO_DATA);
-+}
-+
-+/*
-+ * UCB1300 data sheet says we must:
-+ * 1. enable ADC => 5us (including reference startup time)
-+ * 2. select input => 51*tsibclk => 4.3us
-+ * 3. start conversion => 102*tsibclk => 8.5us
-+ * (tsibclk = 1/11981000)
-+ * Period between SIB 128-bit frames = 10.7us
-+ */
-+
-+/**
-+ * ucb1x00_adc_enable - enable the ADC converter
-+ * @ucb: UCB1x00 structure describing chip
-+ *
-+ * Enable the ucb1x00 and ADC converter on the UCB1x00 for use.
-+ * Any code wishing to use the ADC converter must call this
-+ * function prior to using it.
-+ *
-+ * This function takes the ADC semaphore to prevent two or more
-+ * concurrent uses, and therefore may sleep. As a result, it
-+ * can only be called from process context, not interrupt
-+ * context.
-+ *
-+ * You should release the ADC as soon as possible using
-+ * ucb1x00_adc_disable.
-+ */
-+void ucb1x00_adc_enable(struct ucb1x00 *ucb)
-+{
-+ down(&ucb->adc_sem);
-+
-+ ucb->adc_cr |= UCB_ADC_ENA;
-+
-+ ucb1x00_enable(ucb);
-+ ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr);
-+}
-+
-+/**
-+ * ucb1x00_adc_read - read the specified ADC channel
-+ * @ucb: UCB1x00 structure describing chip
-+ * @adc_channel: ADC channel mask
-+ * @sync: wait for syncronisation pulse.
-+ *
-+ * Start an ADC conversion and wait for the result. Note that
-+ * synchronised ADC conversions (via the ADCSYNC pin) must wait
-+ * until the trigger is asserted and the conversion is finished.
-+ *
-+ * This function currently spins waiting for the conversion to
-+ * complete (2 frames max without sync).
-+ *
-+ * If called for a synchronised ADC conversion, it may sleep
-+ * with the ADC semaphore held.
-+ */
-+unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync)
-+{
-+ unsigned int val;
-+
-+ if (sync)
-+ adc_channel |= UCB_ADC_SYNC_ENA;
-+
-+ ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr | adc_channel);
-+ ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr | adc_channel | UCB_ADC_START);
-+
-+ for (;;) {
-+ val = ucb1x00_reg_read(ucb, UCB_ADC_DATA);
-+ if (val & UCB_ADC_DAT_VAL)
-+ break;
-+ /* yield to other processes */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(1);
-+ }
-+
-+ return UCB_ADC_DAT(val);
-+}
-+
-+/**
-+ * ucb1x00_adc_disable - disable the ADC converter
-+ * @ucb: UCB1x00 structure describing chip
-+ *
-+ * Disable the ADC converter and release the ADC semaphore.
-+ */
-+void ucb1x00_adc_disable(struct ucb1x00 *ucb)
-+{
-+ ucb->adc_cr &= ~UCB_ADC_ENA;
-+ ucb1x00_reg_write(ucb, UCB_ADC_CR, ucb->adc_cr);
-+ ucb1x00_disable(ucb);
-+
-+ up(&ucb->adc_sem);
-+}
-+
-+#ifdef CONFIG_PM
-+static int ucb1x00_pm (struct pm_dev *dev, pm_request_t rqst, void *data)
-+{
-+ struct ucb1x00 *ucb = (struct ucb1x00 *)dev->data;
-+ unsigned int isr;
-+
-+ if (rqst == PM_RESUME) {
-+ ucb1x00_enable(ucb);
-+ isr = ucb1x00_reg_read(ucb, UCB_IE_STATUS);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
-+ ucb1x00_disable(ucb);
-+ }
-+
-+ return 0;
-+}
-+#endif
-+
-+/*
-+ * UCB1x00 Interrupt handling.
-+ *
-+ * The UCB1x00 can generate interrupts when the SIBCLK is stopped.
-+ * Since we need to read an internal register, we must re-enable
-+ * SIBCLK to talk to the chip. We leave the clock running until
-+ * we have finished processing all interrupts from the chip.
-+ */
-+static void ucb1x00_irq(int irqnr, void *devid, struct pt_regs *regs)
-+{
-+ struct ucb1x00 *ucb = devid;
-+ struct ucb1x00_irq *irq;
-+ unsigned int isr, i;
-+
-+ ucb1x00_enable(ucb);
-+ isr = ucb1x00_reg_read(ucb, UCB_IE_STATUS);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, isr);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
-+
-+ for (i = 0, irq = ucb->irq_handler; i < 16 && isr; i++, isr >>= 1, irq++)
-+ if (isr & 1 && irq->fn)
-+ irq->fn(i, irq->devid);
-+ ucb1x00_disable(ucb);
-+}
-+
-+/**
-+ * ucb1x00_hook_irq - hook a UCB1x00 interrupt
-+ * @ucb: UCB1x00 structure describing chip
-+ * @idx: interrupt index
-+ * @fn: function to call when interrupt is triggered
-+ * @devid: device id to pass to interrupt handler
-+ *
-+ * Hook the specified interrupt. You can only register one handler
-+ * for each interrupt source. The interrupt source is not enabled
-+ * by this function; use ucb1x00_enable_irq instead.
-+ *
-+ * Interrupt handlers will be called with other interrupts enabled.
-+ *
-+ * Returns zero on success, or one of the following errors:
-+ * -EINVAL if the interrupt index is invalid
-+ * -EBUSY if the interrupt has already been hooked
-+ */
-+int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid)
-+{
-+ struct ucb1x00_irq *irq;
-+ int ret = -EINVAL;
-+
-+ if (idx < 16) {
-+ irq = ucb->irq_handler + idx;
-+ ret = -EBUSY;
-+
-+ spin_lock_irq(&ucb->lock);
-+ if (irq->fn == NULL) {
-+ irq->devid = devid;
-+ irq->fn = fn;
-+ ret = 0;
-+ }
-+ spin_unlock_irq(&ucb->lock);
-+ }
-+ return ret;
-+}
-+
-+/**
-+ * ucb1x00_enable_irq - enable an UCB1x00 interrupt source
-+ * @ucb: UCB1x00 structure describing chip
-+ * @idx: interrupt index
-+ * @edges: interrupt edges to enable
-+ *
-+ * Enable the specified interrupt to trigger on %UCB_RISING,
-+ * %UCB_FALLING or both edges. The interrupt should have been
-+ * hooked by ucb1x00_hook_irq.
-+ */
-+void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges)
-+{
-+ unsigned long flags;
-+
-+ if (idx < 16) {
-+ spin_lock_irqsave(&ucb->lock, flags);
-+
-+ ucb1x00_enable(ucb);
-+ if (edges & UCB_RISING) {
-+ ucb->irq_ris_enbl |= 1 << idx;
-+ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
-+ }
-+ if (edges & UCB_FALLING) {
-+ ucb->irq_fal_enbl |= 1 << idx;
-+ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
-+ }
-+ ucb1x00_disable(ucb);
-+ spin_unlock_irqrestore(&ucb->lock, flags);
-+ }
-+}
-+
-+/**
-+ * ucb1x00_disable_irq - disable an UCB1x00 interrupt source
-+ * @ucb: UCB1x00 structure describing chip
-+ * @edges: interrupt edges to disable
-+ *
-+ * Disable the specified interrupt triggering on the specified
-+ * (%UCB_RISING, %UCB_FALLING or both) edges.
-+ */
-+void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges)
-+{
-+ unsigned long flags;
-+
-+ if (idx < 16) {
-+ spin_lock_irqsave(&ucb->lock, flags);
-+
-+ ucb1x00_enable(ucb);
-+ if (edges & UCB_RISING) {
-+ ucb->irq_ris_enbl &= ~(1 << idx);
-+ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
-+ }
-+ if (edges & UCB_FALLING) {
-+ ucb->irq_fal_enbl &= ~(1 << idx);
-+ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
-+ }
-+ ucb1x00_disable(ucb);
-+ spin_unlock_irqrestore(&ucb->lock, flags);
-+ }
-+}
-+
-+/**
-+ * ucb1x00_free_irq - disable and free the specified UCB1x00 interrupt
-+ * @ucb: UCB1x00 structure describing chip
-+ * @idx: interrupt index
-+ * @devid: device id.
-+ *
-+ * Disable the interrupt source and remove the handler. devid must
-+ * match the devid passed when hooking the interrupt.
-+ *
-+ * Returns zero on success, or one of the following errors:
-+ * -EINVAL if the interrupt index is invalid
-+ * -ENOENT if devid does not match
-+ */
-+int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid)
-+{
-+ struct ucb1x00_irq *irq;
-+ int ret;
-+
-+ if (idx >= 16)
-+ goto bad;
-+
-+ irq = ucb->irq_handler + idx;
-+ ret = -ENOENT;
-+
-+ spin_lock_irq(&ucb->lock);
-+ if (irq->devid == devid) {
-+ ucb->irq_ris_enbl &= ~(1 << idx);
-+ ucb->irq_fal_enbl &= ~(1 << idx);
-+
-+ ucb1x00_enable(ucb);
-+ ucb1x00_reg_write(ucb, UCB_IE_RIS, ucb->irq_ris_enbl);
-+ ucb1x00_reg_write(ucb, UCB_IE_FAL, ucb->irq_fal_enbl);
-+ ucb1x00_disable(ucb);
-+
-+ irq->fn = NULL;
-+ irq->devid = NULL;
-+ ret = 0;
-+ }
-+ spin_unlock_irq(&ucb->lock);
-+ return ret;
-+
-+bad:
-+ printk(KERN_ERR "%s: freeing bad irq %d\n", __FUNCTION__, idx);
-+ return -EINVAL;
-+}
-+
-+/*
-+ * Try to probe our interrupt, rather than relying on lots of
-+ * hard-coded machine dependencies. For reference, the expected
-+ * IRQ mappings are:
-+ *
-+ * Machine Default IRQ
-+ * adsbitsy IRQ_GPCIN4
-+ * cerf IRQ_GPIO_UCB1200_IRQ
-+ * flexanet IRQ_GPIO_GUI
-+ * freebird IRQ_GPIO_FREEBIRD_UCB1300_IRQ
-+ * graphicsclient IRQ_GRAPHICSCLIENT_UCB1200
-+ * graphicsmaster IRQ_GRAPHICSMASTER_UCB1200
-+ * lart LART_IRQ_UCB1200
-+ * omnimeter IRQ_GPIO23
-+ * pfs168 IRQ_GPIO_UCB1300_IRQ
-+ * simpad IRQ_GPIO_UCB1300_IRQ
-+ * shannon SHANNON_IRQ_GPIO_IRQ_CODEC
-+ * yopy IRQ_GPIO_UCB1200_IRQ
-+ */
-+static int __init ucb1x00_detect_irq(struct ucb1x00 *ucb)
-+{
-+ unsigned long mask;
-+
-+ mask = probe_irq_on();
-+ if (!mask)
-+ return NO_IRQ;
-+
-+ /*
-+ * Enable the ADC interrupt.
-+ */
-+ ucb1x00_reg_write(ucb, UCB_IE_RIS, UCB_IE_ADC);
-+ ucb1x00_reg_write(ucb, UCB_IE_FAL, UCB_IE_ADC);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0xffff);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
-+
-+ /*
-+ * Cause an ADC interrupt.
-+ */
-+ ucb1x00_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA);
-+ ucb1x00_reg_write(ucb, UCB_ADC_CR, UCB_ADC_ENA | UCB_ADC_START);
-+
-+ /*
-+ * Wait for the conversion to complete.
-+ */
-+ while ((ucb1x00_reg_read(ucb, UCB_ADC_DATA) & UCB_ADC_DAT_VAL) == 0);
-+ ucb1x00_reg_write(ucb, UCB_ADC_CR, 0);
-+
-+ /*
-+ * Disable and clear interrupt.
-+ */
-+ ucb1x00_reg_write(ucb, UCB_IE_RIS, 0);
-+ ucb1x00_reg_write(ucb, UCB_IE_FAL, 0);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0xffff);
-+ ucb1x00_reg_write(ucb, UCB_IE_CLEAR, 0);
-+
-+ /*
-+ * Read triggered interrupt.
-+ */
-+ return probe_irq_off(mask);
-+}
-+
-+/*
-+ * This configures the UCB1x00 layer depending on the machine type
-+ * we're running on. The UCB1x00 drivers should not contain any
-+ * machine dependencies.
-+ *
-+ * We can get rid of some of these dependencies by using existing
-+ * facilities provided by the kernel - namely IRQ probing. The
-+ * machine specific files are expected to setup the IRQ levels on
-+ * initialisation. With any luck, we'll get rid of all the
-+ * machine dependencies here.
-+ */
-+static int __init ucb1x00_configure(struct ucb1x00 *ucb)
-+{
-+ unsigned int irq_gpio_pin = 0;
-+ int irq, default_irq = NO_IRQ;
-+
-+ if (machine_is_adsbitsy())
-+ default_irq = IRQ_GPCIN4;
-+
-+// if (machine_is_assabet())
-+// default_irq = IRQ_GPIO23;
-+
-+#ifdef CONFIG_SA1100_CERF
-+ if (machine_is_cerf())
-+ default_irq = IRQ_GPIO_UCB1200_IRQ;
-+#endif
-+#ifdef CONFIG_SA1100_FREEBIRD
-+ if (machine_is_freebird())
-+ default_irq = IRQ_GPIO_FREEBIRD_UCB1300_IRQ;
-+#endif
-+#if defined(CONFIG_SA1100_GRAPHICSCLIENT)
-+// if (machine_is_graphicsclient())
-+// default_irq = IRQ_GRAPHICSCLIENT_UCB1200;
-+#endif
-+#if defined(CONFIG_SA1100_GRAPICSMASTER)
-+ if (machine_is_graphicsmaster())
-+ default_irq = IRQ_GRAPHICSMASTER_UCB1200;
-+#endif
-+#ifdef CONFIG_SA1100_LART
-+ if (machine_is_lart()) {
-+ default_irq = LART_IRQ_UCB1200;
-+ irq_gpio_pin = LART_GPIO_UCB1200;
-+ }
-+#endif
-+ if (machine_is_omnimeter())
-+ default_irq = IRQ_GPIO23;
-+
-+#ifdef CONFIG_SA1100_PFS168
-+ if (machine_is_pfs168())
-+ default_irq = IRQ_GPIO_UCB1300_IRQ;
-+#endif
-+#ifdef CONFIG_SA1100_SIMPAD
-+ if (machine_is_simpad())
-+ default_irq = IRQ_GPIO_UCB1300_IRQ;
-+#endif
-+#ifdef CONFIG_SA1100_SIMPUTER
-+ if (machine_is_simputer()) {
-+ default_irq = IRQ_GPIO_UCB1300_IRQ;
-+ irq_gpio_pin = GPIO_UCB1300_IRQ;
-+ }
-+#endif
-+ if (machine_is_shannon())
-+ default_irq = SHANNON_IRQ_GPIO_IRQ_CODEC;
-+#ifdef CONFIG_SA1100_YOPY
-+ if (machine_is_yopy())
-+ default_irq = IRQ_GPIO_UCB1200_IRQ;
-+#endif
-+#ifdef CONFIG_SA1100_ACCELENT
-+ if (machine_is_accelent_sa()) {
-+ ucb->irq = IRQ_GPIO_UCB1200_IRQ;
-+ irq_gpio_pin = GPIO_UCB1200_IRQ;
-+ }
-+#endif
-+
-+ /*
-+ * Eventually, this will disappear.
-+ */
-+ if (irq_gpio_pin)
-+ set_GPIO_IRQ_edge(irq_gpio_pin, GPIO_RISING_EDGE);
-+
-+ irq = ucb1x00_detect_irq(ucb);
-+ if (irq != NO_IRQ) {
-+ if (default_irq != NO_IRQ && irq != default_irq)
-+ printk(KERN_ERR "UCB1x00: probed IRQ%d != default IRQ%d\n",
-+ irq, default_irq);
-+ if (irq == default_irq)
-+ printk(KERN_ERR "UCB1x00: probed IRQ%d correctly. "
-+ "Please remove machine dependencies from "
-+ "ucb1x00-core.c\n", irq);
-+ ucb->irq = irq;
-+ } else {
-+ printk(KERN_ERR "UCB1x00: IRQ probe failed, using IRQ%d\n",
-+ default_irq);
-+ ucb->irq = default_irq;
-+ }
-+
-+ return ucb->irq == NO_IRQ ? -ENODEV : 0;
-+}
-+
-+struct ucb1x00 *my_ucb;
-+
-+/**
-+ * ucb1x00_get - get the UCB1x00 structure describing a chip
-+ * @ucb: UCB1x00 structure describing chip
-+ *
-+ * Return the UCB1x00 structure describing a chip.
-+ *
-+ * FIXME: Currently very noddy indeed, which currently doesn't
-+ * matter since we only support one chip.
-+ */
-+struct ucb1x00 *ucb1x00_get(void)
-+{
-+ return my_ucb;
-+}
-+
-+static int __init ucb1x00_init(void)
-+{
-+ struct mcp *mcp;
-+ unsigned int id;
-+ int ret = -ENODEV;
-+
-+ mcp = mcp_get();
-+ if (!mcp)
-+ goto no_mcp;
-+
-+ mcp_enable(mcp);
-+ id = mcp_reg_read(mcp, UCB_ID);
-+
-+ if (id != UCB_ID_1200 && id != UCB_ID_1300) {
-+ printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id);
-+ goto out;
-+ }
-+
-+ my_ucb = kmalloc(sizeof(struct ucb1x00), GFP_KERNEL);
-+ ret = -ENOMEM;
-+ if (!my_ucb)
-+ goto out;
-+
-+ if (machine_is_shannon()) {
-+ /* reset the codec */
-+ GPDR |= SHANNON_GPIO_CODEC_RESET;
-+ GPCR = SHANNON_GPIO_CODEC_RESET;
-+ GPSR = SHANNON_GPIO_CODEC_RESET;
-+
-+ }
-+
-+ memset(my_ucb, 0, sizeof(struct ucb1x00));
-+
-+ spin_lock_init(&my_ucb->lock);
-+ spin_lock_init(&my_ucb->io_lock);
-+ sema_init(&my_ucb->adc_sem, 1);
-+
-+ my_ucb->id = id;
-+ my_ucb->mcp = mcp;
-+
-+ ret = ucb1x00_configure(my_ucb);
-+ if (ret)
-+ goto out;
-+
-+ ret = request_irq(my_ucb->irq, ucb1x00_irq, 0, "UCB1x00", my_ucb);
-+ if (ret) {
-+ printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
-+ my_ucb->irq, ret);
-+ kfree(my_ucb);
-+ my_ucb = NULL;
-+ goto out;
-+ }
-+
-+#ifdef CONFIG_PM
-+ my_ucb->pmdev = pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, ucb1x00_pm);
-+ if (my_ucb->pmdev == NULL)
-+ printk("ucb1x00: unable to register in PM.\n");
-+ else
-+ my_ucb->pmdev->data = my_ucb;
-+#endif
-+
-+out:
-+ mcp_disable(mcp);
-+no_mcp:
-+ return ret;
-+}
-+
-+static void __exit ucb1x00_exit(void)
-+{
-+ free_irq(my_ucb->irq, my_ucb);
-+ kfree(my_ucb);
-+}
-+
-+module_init(ucb1x00_init);
-+module_exit(ucb1x00_exit);
-+
-+EXPORT_SYMBOL(ucb1x00_get);
-+
-+EXPORT_SYMBOL(ucb1x00_io_set_dir);
-+EXPORT_SYMBOL(ucb1x00_io_write);
-+EXPORT_SYMBOL(ucb1x00_io_read);
-+
-+EXPORT_SYMBOL(ucb1x00_adc_enable);
-+EXPORT_SYMBOL(ucb1x00_adc_read);
-+EXPORT_SYMBOL(ucb1x00_adc_disable);
-+
-+EXPORT_SYMBOL(ucb1x00_hook_irq);
-+EXPORT_SYMBOL(ucb1x00_free_irq);
-+EXPORT_SYMBOL(ucb1x00_enable_irq);
-+EXPORT_SYMBOL(ucb1x00_disable_irq);
-+
-+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-+MODULE_DESCRIPTION("UCB1x00 core driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/misc/ucb1x00-ts.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,664 @@
-+/*
-+ * linux/drivers/misc/ucb1x00-ts.c
-+ *
-+ * Copyright (C) 2001 Russell King, 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 version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * 21-Jan-2002 <jco@ict.es> :
-+ *
-+ * Added support for synchronous A/D mode. This mode is useful to
-+ * avoid noise induced in the touchpanel by the LCD, provided that
-+ * the UCB1x00 has a valid LCD sync signal routed to its ADCSYNC pin.
-+ * It is important to note that the signal connected to the ADCSYNC
-+ * pin should provide pulses even when the LCD is blanked, otherwise
-+ * a pen touch needed to unblank the LCD will never be read.
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/smp.h>
-+#include <linux/smp_lock.h>
-+#include <linux/sched.h>
-+#include <linux/completion.h>
-+#include <linux/delay.h>
-+#include <linux/string.h>
-+#include <linux/pm.h>
-+
-+#include <asm/dma.h>
-+#include <asm/semaphore.h>
-+
-+#include "ucb1x00.h"
-+
-+/*
-+ * Define this if you want the UCB1x00 stuff to talk to the input layer
-+ */
-+#undef USE_INPUT
-+
-+#ifndef USE_INPUT
-+
-+#include <linux/fs.h>
-+#include <linux/miscdevice.h>
-+#include <linux/poll.h>
-+
-+/*
-+ * This structure is nonsense - millisecs is not very useful
-+ * since the field size is too small. Also, we SHOULD NOT
-+ * be exposing jiffies to user space directly.
-+ */
-+struct ts_event {
-+ u16 pressure;
-+ u16 x;
-+ u16 y;
-+ u16 pad;
-+ struct timeval stamp;
-+};
-+
-+#define NR_EVENTS 16
-+
-+#else
-+
-+#include <linux/input.h>
-+
-+#endif
-+
-+struct ucb1x00_ts {
-+#ifdef USE_INPUT
-+ struct input_dev idev;
-+#endif
-+ struct ucb1x00 *ucb;
-+#ifdef CONFIG_PM
-+ struct pm_dev *pmdev;
-+#endif
-+
-+ wait_queue_head_t irq_wait;
-+ struct semaphore sem;
-+ struct completion init_exit;
-+ struct task_struct *rtask;
-+ int use_count;
-+ u16 x_res;
-+ u16 y_res;
-+
-+#ifndef USE_INPUT
-+ struct fasync_struct *fasync;
-+ wait_queue_head_t read_wait;
-+ u8 evt_head;
-+ u8 evt_tail;
-+ struct ts_event events[NR_EVENTS];
-+#endif
-+ int restart:1;
-+ int adcsync:1;
-+};
-+
-+static struct ucb1x00_ts ucbts;
-+static int adcsync = UCB_NOSYNC;
-+
-+static int ucb1x00_ts_startup(struct ucb1x00_ts *ts);
-+static void ucb1x00_ts_shutdown(struct ucb1x00_ts *ts);
-+
-+#ifndef USE_INPUT
-+
-+#define ucb1x00_ts_evt_pending(ts) ((volatile u8)(ts)->evt_head != (ts)->evt_tail)
-+#define ucb1x00_ts_evt_get(ts) ((ts)->events + (ts)->evt_tail)
-+#define ucb1x00_ts_evt_pull(ts) ((ts)->evt_tail = ((ts)->evt_tail + 1) & (NR_EVENTS - 1))
-+#define ucb1x00_ts_evt_clear(ts) ((ts)->evt_head = (ts)->evt_tail = 0)
-+
-+static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
-+{
-+ int next_head;
-+
-+ next_head = (ts->evt_head + 1) & (NR_EVENTS - 1);
-+ if (next_head != ts->evt_tail) {
-+ ts->events[ts->evt_head].pressure = pressure;
-+ ts->events[ts->evt_head].x = x;
-+ ts->events[ts->evt_head].y = y;
-+ do_gettimeofday(&ts->events[ts->evt_head].stamp);
-+ ts->evt_head = next_head;
-+
-+ if (ts->fasync)
-+ kill_fasync(&ts->fasync, SIGIO, POLL_IN);
-+ wake_up_interruptible(&ts->read_wait);
-+ }
-+}
-+
-+static inline void ucb1x00_ts_event_release(struct ucb1x00_ts *ts)
-+{
-+ ucb1x00_ts_evt_add(ts, 0, 0, 0);
-+}
-+
-+/*
-+ * User space driver interface.
-+ */
-+static ssize_t
-+ucb1x00_ts_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct ucb1x00_ts *ts = filp->private_data;
-+ char *ptr = buffer;
-+ int err = 0;
-+
-+ add_wait_queue(&ts->read_wait, &wait);
-+ while (count >= sizeof(struct ts_event)) {
-+ err = -ERESTARTSYS;
-+ if (signal_pending(current))
-+ break;
-+
-+ if (ucb1x00_ts_evt_pending(ts)) {
-+ struct ts_event *evt = ucb1x00_ts_evt_get(ts);
-+
-+ err = copy_to_user(ptr, evt, sizeof(struct ts_event));
-+ ucb1x00_ts_evt_pull(ts);
-+
-+ if (err)
-+ break;
-+
-+ ptr += sizeof(struct ts_event);
-+ count -= sizeof(struct ts_event);
-+ continue;
-+ }
-+
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ err = -EAGAIN;
-+ if (filp->f_flags & O_NONBLOCK)
-+ break;
-+ schedule();
-+ }
-+ current->state = TASK_RUNNING;
-+ remove_wait_queue(&ts->read_wait, &wait);
-+
-+ return ptr == buffer ? err : ptr - buffer;
-+}
-+
-+static unsigned int ucb1x00_ts_poll(struct file *filp, poll_table *wait)
-+{
-+ struct ucb1x00_ts *ts = filp->private_data;
-+ int ret = 0;
-+
-+ poll_wait(filp, &ts->read_wait, wait);
-+ if (ucb1x00_ts_evt_pending(ts))
-+ ret = POLLIN | POLLRDNORM;
-+
-+ return ret;
-+}
-+
-+static int ucb1x00_ts_fasync(int fd, struct file *filp, int on)
-+{
-+ struct ucb1x00_ts *ts = filp->private_data;
-+
-+ return fasync_helper(fd, filp, on, &ts->fasync);
-+}
-+
-+static int ucb1x00_ts_open(struct inode *inode, struct file *filp)
-+{
-+ struct ucb1x00_ts *ts = &ucbts;
-+ int ret = 0;
-+
-+ ret = ucb1x00_ts_startup(ts);
-+ if (ret == 0)
-+ filp->private_data = ts;
-+
-+ return ret;
-+}
-+
-+/*
-+ * Release touchscreen resources. Disable IRQs.
-+ */
-+static int ucb1x00_ts_release(struct inode *inode, struct file *filp)
-+{
-+ struct ucb1x00_ts *ts = filp->private_data;
-+
-+ down(&ts->sem);
-+ ucb1x00_ts_fasync(-1, filp, 0);
-+ ucb1x00_ts_shutdown(ts);
-+ up(&ts->sem);
-+
-+ return 0;
-+}
-+
-+static struct file_operations ucb1x00_fops = {
-+ owner: THIS_MODULE,
-+ read: ucb1x00_ts_read,
-+ poll: ucb1x00_ts_poll,
-+ open: ucb1x00_ts_open,
-+ release: ucb1x00_ts_release,
-+ fasync: ucb1x00_ts_fasync,
-+};
-+
-+/*
-+ * The official UCB1x00 touchscreen is a miscdevice:
-+ * 10 char Non-serial mice, misc features
-+ * 14 = /dev/touchscreen/ucb1x00 UCB 1x00 touchscreen
-+ */
-+static struct miscdevice ucb1x00_ts_dev = {
-+ minor: 14,
-+ name: "touchscreen/ucb1x00",
-+ fops: &ucb1x00_fops,
-+};
-+
-+static inline int ucb1x00_ts_register(struct ucb1x00_ts *ts)
-+{
-+ init_waitqueue_head(&ts->read_wait);
-+ return misc_register(&ucb1x00_ts_dev);
-+}
-+
-+static inline void ucb1x00_ts_deregister(struct ucb1x00_ts *ts)
-+{
-+ misc_deregister(&ucb1x00_ts_dev);
-+}
-+
-+#else
-+
-+#define ucb1x00_ts_evt_clear(ts) do { } while (0)
-+
-+static inline void ucb1x00_ts_evt_add(struct ucb1x00_ts *ts, u16 pressure, u16 x, u16 y)
-+{
-+ input_report_abs(&ts->idev, ABS_X, x);
-+ input_report_abs(&ts->idev, ABS_Y, y);
-+ input_report_abs(&ts->idev, ABS_PRESSURE, pressure);
-+}
-+
-+static int ucb1x00_ts_open(struct input_dev *idev)
-+{
-+ struct ucb1x00_ts *ts = (struct ucb1x00_ts *)idev;
-+
-+ return ucb1x00_ts_startup(ts);
-+}
-+
-+static void ucb1x00_ts_close(struct input_dev *idev)
-+{
-+ struct ucb1x00_ts *ts = (struct ucb1x00_ts *)idev;
-+
-+ down(&ts->sem);
-+ ucb1x00_ts_shutdown(ts);
-+ up(&ts->sem);
-+}
-+
-+static inline int ucb1x00_ts_register(struct ucb1x00_ts *ts)
-+{
-+ ts->idev.name = "Touchscreen panel";
-+ ts->idev.idproduct = ts->ucb->id;
-+ ts->idev.open = ucb1x00_ts_open;
-+ ts->idev.close = ucb1x00_ts_close;
-+
-+ __set_bit(EV_ABS, ts->idev.evbit);
-+ __set_bit(ABS_X, ts->idev.absbit);
-+ __set_bit(ABS_Y, ts->idev.absbit);
-+ __set_bit(ABS_PRESSURE, ts->idev.absbit);
-+
-+ input_register_device(&ts->idev);
-+
-+ return 0;
-+}
-+
-+static inline void ucb1x00_ts_deregister(struct ucb1x00_ts *ts)
-+{
-+ input_unregister_device(&ts->idev);
-+}
-+
-+#endif
-+
-+/*
-+ * Switch to interrupt mode.
-+ */
-+static inline void ucb1x00_ts_mode_int(struct ucb1x00_ts *ts)
-+{
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
-+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
-+ UCB_TS_CR_MODE_INT);
-+}
-+
-+/*
-+ * Switch to pressure mode, and read pressure. We don't need to wait
-+ * here, since both plates are being driven.
-+ */
-+static inline unsigned int ucb1x00_ts_read_pressure(struct ucb1x00_ts *ts)
-+{
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMX_POW | UCB_TS_CR_TSPX_POW |
-+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_GND |
-+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-+
-+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
-+}
-+
-+/*
-+ * Switch to X position mode and measure Y plate. We switch the plate
-+ * configuration in pressure mode, then switch to position mode. This
-+ * gives a faster response time. Even so, we need to wait about 55us
-+ * for things to stabilise.
-+ */
-+static inline unsigned int ucb1x00_ts_read_xpos(struct ucb1x00_ts *ts)
-+{
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
-+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
-+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
-+ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
-+
-+ udelay(55);
-+
-+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPY, ts->adcsync);
-+}
-+
-+/*
-+ * Switch to Y position mode and measure X plate. We switch the plate
-+ * configuration in pressure mode, then switch to position mode. This
-+ * gives a faster response time. Even so, we need to wait about 55us
-+ * for things to stabilise.
-+ */
-+static inline unsigned int ucb1x00_ts_read_ypos(struct ucb1x00_ts *ts)
-+{
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
-+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
-+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
-+ UCB_TS_CR_MODE_POS | UCB_TS_CR_BIAS_ENA);
-+
-+ udelay(55);
-+
-+ return ucb1x00_adc_read(ts->ucb, UCB_ADC_INP_TSPX, ts->adcsync);
-+}
-+
-+/*
-+ * Switch to X plate resistance mode. Set MX to ground, PX to
-+ * supply. Measure current.
-+ */
-+static inline unsigned int ucb1x00_ts_read_xres(struct ucb1x00_ts *ts)
-+{
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMX_GND | UCB_TS_CR_TSPX_POW |
-+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-+ return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
-+}
-+
-+/*
-+ * Switch to Y plate resistance mode. Set MY to ground, PY to
-+ * supply. Measure current.
-+ */
-+static inline unsigned int ucb1x00_ts_read_yres(struct ucb1x00_ts *ts)
-+{
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR,
-+ UCB_TS_CR_TSMY_GND | UCB_TS_CR_TSPY_POW |
-+ UCB_TS_CR_MODE_PRES | UCB_TS_CR_BIAS_ENA);
-+ return ucb1x00_adc_read(ts->ucb, 0, ts->adcsync);
-+}
-+
-+/*
-+ * This is a RT kernel thread that handles the ADC accesses
-+ * (mainly so we can use semaphores in the UCB1200 core code
-+ * to serialise accesses to the ADC).
-+ */
-+static int ucb1x00_thread(void *_ts)
-+{
-+ struct ucb1x00_ts *ts = _ts;
-+ struct task_struct *tsk = current;
-+ DECLARE_WAITQUEUE(wait, tsk);
-+ int valid;
-+
-+ ts->rtask = tsk;
-+
-+ daemonize();
-+ reparent_to_init();
-+ strcpy(tsk->comm, "ktsd");
-+ tsk->tty = NULL;
-+ /*
-+ * We could run as a real-time thread. However, thus far
-+ * this doesn't seem to be necessary.
-+ */
-+// tsk->policy = SCHED_FIFO;
-+// tsk->rt_priority = 1;
-+
-+ /* only want to receive SIGKILL */
-+ spin_lock_irq(&tsk->sigmask_lock);
-+ siginitsetinv(&tsk->blocked, sigmask(SIGKILL));
-+ recalc_sigpending(tsk);
-+ spin_unlock_irq(&tsk->sigmask_lock);
-+
-+ complete(&ts->init_exit);
-+
-+ valid = 0;
-+
-+ add_wait_queue(&ts->irq_wait, &wait);
-+ for (;;) {
-+ unsigned int x, y, p, val;
-+ signed long timeout;
-+
-+ ts->restart = 0;
-+
-+ ucb1x00_adc_enable(ts->ucb);
-+
-+ x = ucb1x00_ts_read_xpos(ts);
-+ y = ucb1x00_ts_read_ypos(ts);
-+ p = ucb1x00_ts_read_pressure(ts);
-+
-+ /*
-+ * Switch back to interrupt mode.
-+ */
-+ ucb1x00_ts_mode_int(ts);
-+ ucb1x00_adc_disable(ts->ucb);
-+
-+ set_task_state(tsk, TASK_UNINTERRUPTIBLE);
-+ schedule_timeout(HZ / 100);
-+ if (signal_pending(tsk))
-+ break;
-+
-+ ucb1x00_enable(ts->ucb);
-+ val = ucb1x00_reg_read(ts->ucb, UCB_TS_CR);
-+
-+ if (val & (UCB_TS_CR_TSPX_LOW | UCB_TS_CR_TSMX_LOW)) {
-+ set_task_state(tsk, TASK_INTERRUPTIBLE);
-+
-+ ucb1x00_enable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
-+ ucb1x00_disable(ts->ucb);
-+
-+ /*
-+ * If we spat out a valid sample set last time,
-+ * spit out a "pen off" sample here.
-+ */
-+ if (valid) {
-+ ucb1x00_ts_event_release(ts);
-+ valid = 0;
-+ }
-+
-+ timeout = MAX_SCHEDULE_TIMEOUT;
-+ } else {
-+ ucb1x00_disable(ts->ucb);
-+
-+ /*
-+ * Filtering is policy. Policy belongs in user
-+ * space. We therefore leave it to user space
-+ * to do any filtering they please.
-+ */
-+ if (!ts->restart) {
-+ ucb1x00_ts_evt_add(ts, p, x, y);
-+ valid = 1;
-+ }
-+
-+ set_task_state(tsk, TASK_INTERRUPTIBLE);
-+ timeout = HZ / 100;
-+ }
-+
-+ schedule_timeout(timeout);
-+ if (signal_pending(tsk))
-+ break;
-+ }
-+
-+ remove_wait_queue(&ts->irq_wait, &wait);
-+
-+ ts->rtask = NULL;
-+ ucb1x00_ts_evt_clear(ts);
-+ complete_and_exit(&ts->init_exit, 0);
-+}
-+
-+/*
-+ * We only detect touch screen _touches_ with this interrupt
-+ * handler, and even then we just schedule our task.
-+ */
-+static void ucb1x00_ts_irq(int idx, void *id)
-+{
-+ struct ucb1x00_ts *ts = id;
-+ ucb1x00_disable_irq(ts->ucb, UCB_IRQ_TSPX, UCB_FALLING);
-+ wake_up(&ts->irq_wait);
-+}
-+
-+static int ucb1x00_ts_startup(struct ucb1x00_ts *ts)
-+{
-+ int ret = 0;
-+
-+ if (down_interruptible(&ts->sem))
-+ return -EINTR;
-+
-+ if (ts->use_count++ != 0)
-+ goto out;
-+
-+ if (ts->rtask)
-+ panic("ucb1x00: rtask running?");
-+
-+ init_waitqueue_head(&ts->irq_wait);
-+ ret = ucb1x00_hook_irq(ts->ucb, UCB_IRQ_TSPX, ucb1x00_ts_irq, ts);
-+ if (ret < 0)
-+ goto out;
-+
-+ /*
-+ * If we do this at all, we should allow the user to
-+ * measure and read the X and Y resistance at any time.
-+ */
-+ ucb1x00_adc_enable(ts->ucb);
-+ ts->x_res = ucb1x00_ts_read_xres(ts);
-+ ts->y_res = ucb1x00_ts_read_yres(ts);
-+ ucb1x00_adc_disable(ts->ucb);
-+
-+ init_completion(&ts->init_exit);
-+ ret = kernel_thread(ucb1x00_thread, ts, 0);
-+ if (ret >= 0) {
-+ wait_for_completion(&ts->init_exit);
-+ ret = 0;
-+ } else {
-+ ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
-+ }
-+
-+ out:
-+ if (ret)
-+ ts->use_count--;
-+ up(&ts->sem);
-+ return ret;
-+}
-+
-+/*
-+ * Release touchscreen resources. Disable IRQs.
-+ */
-+static void ucb1x00_ts_shutdown(struct ucb1x00_ts *ts)
-+{
-+ if (--ts->use_count == 0) {
-+ if (ts->rtask) {
-+ send_sig(SIGKILL, ts->rtask, 1);
-+ wait_for_completion(&ts->init_exit);
-+ }
-+
-+ ucb1x00_enable(ts->ucb);
-+ ucb1x00_free_irq(ts->ucb, UCB_IRQ_TSPX, ts);
-+ ucb1x00_reg_write(ts->ucb, UCB_TS_CR, 0);
-+ ucb1x00_disable(ts->ucb);
-+ }
-+}
-+
-+#ifdef CONFIG_PM
-+static int ucb1x00_ts_pm (struct pm_dev *dev, pm_request_t rqst, void *data)
-+{
-+ struct ucb1x00_ts *ts = (struct ucb1x00_ts *) (dev->data);
-+
-+ if (rqst == PM_RESUME && ts->rtask != NULL) {
-+ /*
-+ * Restart the TS thread to ensure the
-+ * TS interrupt mode is set up again
-+ * after sleep.
-+ */
-+ ts->restart = 1;
-+ wake_up(&ts->irq_wait);
-+ }
-+ return 0;
-+}
-+#endif
-+
-+
-+/*
-+ * Initialisation.
-+ */
-+static int __init ucb1x00_ts_init(void)
-+{
-+ struct ucb1x00_ts *ts = &ucbts;
-+
-+ ts->ucb = ucb1x00_get();
-+ if (!ts->ucb)
-+ return -ENODEV;
-+
-+ ts->adcsync = adcsync;
-+ init_MUTEX(&ts->sem);
-+
-+#ifdef CONFIG_PM
-+ ts->pmdev = pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, ucb1x00_ts_pm);
-+ if (ts->pmdev == NULL)
-+ printk("ucb1x00_ts: unable to register in PM.\n");
-+ else
-+ ts->pmdev->data = ts;
-+#endif
-+ return ucb1x00_ts_register(ts);
-+}
-+
-+static void __exit ucb1x00_ts_exit(void)
-+{
-+ struct ucb1x00_ts *ts = &ucbts;
-+
-+ ucb1x00_ts_deregister(ts);
-+
-+#ifdef CONFIG_PM
-+ if (ts->pmdev)
-+ pm_unregister(ts->pmdev);
-+#endif
-+}
-+
-+#ifndef MODULE
-+
-+/*
-+ * Parse kernel command-line options.
-+ *
-+ * syntax : ucbts=[sync|nosync],...
-+ */
-+static int __init ucb1x00_ts_setup(char *str)
-+{
-+ char *p;
-+
-+ while ((p = strsep(&str, ",")) != NULL) {
-+ if (strcmp(p, "sync") == 0)
-+ adcsync = UCB_SYNC;
-+ }
-+
-+ return 1;
-+}
-+
-+__setup("ucbts=", ucb1x00_ts_setup);
-+
-+#else
-+
-+MODULE_PARM(adcsync, "i");
-+MODULE_PARM_DESC(adcsync, "Enable use of ADCSYNC signal");
-+
-+#endif
-+
-+module_init(ucb1x00_ts_init);
-+module_exit(ucb1x00_ts_exit);
-+
-+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-+MODULE_DESCRIPTION("UCB1x00 touchscreen driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/misc/ucb1x00.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,232 @@
-+/*
-+ * linux/drivers/misc/ucb1x00.h
-+ *
-+ * Copyright (C) 2001 Russell King, 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.
-+ */
-+#ifndef UCB1200_H
-+#define UCB1200_H
-+
-+#define UCB_IO_DATA 0x00
-+#define UCB_IO_DIR 0x01
-+
-+#define UCB_IO_0 (1 << 0)
-+#define UCB_IO_1 (1 << 1)
-+#define UCB_IO_2 (1 << 2)
-+#define UCB_IO_3 (1 << 3)
-+#define UCB_IO_4 (1 << 4)
-+#define UCB_IO_5 (1 << 5)
-+#define UCB_IO_6 (1 << 6)
-+#define UCB_IO_7 (1 << 7)
-+#define UCB_IO_8 (1 << 8)
-+#define UCB_IO_9 (1 << 9)
-+
-+#define UCB_IE_RIS 0x02
-+#define UCB_IE_FAL 0x03
-+#define UCB_IE_STATUS 0x04
-+#define UCB_IE_CLEAR 0x04
-+#define UCB_IE_ADC (1 << 11)
-+#define UCB_IE_TSPX (1 << 12)
-+#define UCB_IE_TSMX (1 << 13)
-+#define UCB_IE_TCLIP (1 << 14)
-+#define UCB_IE_ACLIP (1 << 15)
-+
-+#define UCB_IRQ_TSPX 12
-+
-+#define UCB_TC_A 0x05
-+#define UCB_TC_A_LOOP (1 << 7) /* UCB1200 */
-+#define UCB_TC_A_AMPL (1 << 7) /* UCB1300 */
-+
-+#define UCB_TC_B 0x06
-+#define UCB_TC_B_VOICE_ENA (1 << 3)
-+#define UCB_TC_B_CLIP (1 << 4)
-+#define UCB_TC_B_ATT (1 << 6)
-+#define UCB_TC_B_SIDE_ENA (1 << 11)
-+#define UCB_TC_B_MUTE (1 << 13)
-+#define UCB_TC_B_IN_ENA (1 << 14)
-+#define UCB_TC_B_OUT_ENA (1 << 15)
-+
-+#define UCB_AC_A 0x07
-+#define UCB_AC_B 0x08
-+#define UCB_AC_B_LOOP (1 << 8)
-+#define UCB_AC_B_MUTE (1 << 13)
-+#define UCB_AC_B_IN_ENA (1 << 14)
-+#define UCB_AC_B_OUT_ENA (1 << 15)
-+
-+#define UCB_TS_CR 0x09
-+#define UCB_TS_CR_TSMX_POW (1 << 0)
-+#define UCB_TS_CR_TSPX_POW (1 << 1)
-+#define UCB_TS_CR_TSMY_POW (1 << 2)
-+#define UCB_TS_CR_TSPY_POW (1 << 3)
-+#define UCB_TS_CR_TSMX_GND (1 << 4)
-+#define UCB_TS_CR_TSPX_GND (1 << 5)
-+#define UCB_TS_CR_TSMY_GND (1 << 6)
-+#define UCB_TS_CR_TSPY_GND (1 << 7)
-+#define UCB_TS_CR_MODE_INT (0 << 8)
-+#define UCB_TS_CR_MODE_PRES (1 << 8)
-+#define UCB_TS_CR_MODE_POS (2 << 8)
-+#define UCB_TS_CR_BIAS_ENA (1 << 11)
-+#define UCB_TS_CR_TSPX_LOW (1 << 12)
-+#define UCB_TS_CR_TSMX_LOW (1 << 13)
-+
-+#define UCB_ADC_CR 0x0a
-+#define UCB_ADC_SYNC_ENA (1 << 0)
-+#define UCB_ADC_VREFBYP_CON (1 << 1)
-+#define UCB_ADC_INP_TSPX (0 << 2)
-+#define UCB_ADC_INP_TSMX (1 << 2)
-+#define UCB_ADC_INP_TSPY (2 << 2)
-+#define UCB_ADC_INP_TSMY (3 << 2)
-+#define UCB_ADC_INP_AD0 (4 << 2)
-+#define UCB_ADC_INP_AD1 (5 << 2)
-+#define UCB_ADC_INP_AD2 (6 << 2)
-+#define UCB_ADC_INP_AD3 (7 << 2)
-+#define UCB_ADC_EXT_REF (1 << 5)
-+#define UCB_ADC_START (1 << 7)
-+#define UCB_ADC_ENA (1 << 15)
-+
-+#define UCB_ADC_DATA 0x0b
-+#define UCB_ADC_DAT_VAL (1 << 15)
-+#define UCB_ADC_DAT(x) (((x) & 0x7fe0) >> 5)
-+
-+#define UCB_ID 0x0c
-+#define UCB_ID_1200 0x1004
-+#define UCB_ID_1300 0x1005
-+
-+#define UCB_MODE 0x0d
-+#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
-+#define UCB_MODE_AUD_OFF_CAN (1 << 13)
-+
-+#include "mcp.h"
-+
-+struct ucb1x00;
-+
-+struct ucb1x00_irq {
-+ void *devid;
-+ void (*fn)(int, void *);
-+};
-+
-+struct ucb1x00 {
-+ spinlock_t lock;
-+ struct mcp *mcp;
-+ struct pm_dev *pmdev;
-+ unsigned int irq;
-+ struct semaphore adc_sem;
-+ spinlock_t io_lock;
-+ u16 id;
-+ u16 io_dir;
-+ u16 io_out;
-+ u16 adc_cr;
-+ u16 irq_fal_enbl;
-+ u16 irq_ris_enbl;
-+ struct ucb1x00_irq irq_handler[16];
-+};
-+
-+/**
-+ * ucb1x00_clkrate - return the UCB1x00 SIB clock rate
-+ * @ucb: UCB1x00 structure describing chip
-+ *
-+ * Return the SIB clock rate in Hz.
-+ */
-+static inline unsigned int ucb1x00_clkrate(struct ucb1x00 *ucb)
-+{
-+ return mcp_get_sclk_rate(ucb->mcp);
-+}
-+
-+/**
-+ * ucb1x00_enable - enable the UCB1x00 SIB clock
-+ * @ucb: UCB1x00 structure describing chip
-+ *
-+ * Enable the SIB clock. This can be called multiple times.
-+ */
-+static inline void ucb1x00_enable(struct ucb1x00 *ucb)
-+{
-+ mcp_enable(ucb->mcp);
-+}
-+
-+/**
-+ * ucb1x00_disable - disable the UCB1x00 SIB clock
-+ * @ucb: UCB1x00 structure describing chip
-+ *
-+ * Disable the SIB clock. The SIB clock will only be disabled
-+ * when the number of ucb1x00_enable calls match the number of
-+ * ucb1x00_disable calls.
-+ */
-+static inline void ucb1x00_disable(struct ucb1x00 *ucb)
-+{
-+ mcp_disable(ucb->mcp);
-+}
-+
-+/**
-+ * ucb1x00_reg_write - write a UCB1x00 register
-+ * @ucb: UCB1x00 structure describing chip
-+ * @reg: UCB1x00 4-bit register index to write
-+ * @val: UCB1x00 16-bit value to write
-+ *
-+ * Write the UCB1x00 register @reg with value @val. The SIB
-+ * clock must be running for this function to return.
-+ */
-+static inline void ucb1x00_reg_write(struct ucb1x00 *ucb, unsigned int reg, unsigned int val)
-+{
-+ mcp_reg_write(ucb->mcp, reg, val);
-+}
-+
-+/**
-+ * ucb1x00_reg_read - read a UCB1x00 register
-+ * @ucb: UCB1x00 structure describing chip
-+ * @reg: UCB1x00 4-bit register index to write
-+ *
-+ * Read the UCB1x00 register @reg and return its value. The SIB
-+ * clock must be running for this function to return.
-+ */
-+static inline unsigned int ucb1x00_reg_read(struct ucb1x00 *ucb, unsigned int reg)
-+{
-+ return mcp_reg_read(ucb->mcp, reg);
-+}
-+/**
-+ * ucb1x00_set_audio_divisor -
-+ * @ucb: UCB1x00 structure describing chip
-+ * @div: SIB clock divisor
-+ */
-+static inline void ucb1x00_set_audio_divisor(struct ucb1x00 *ucb, unsigned int div)
-+{
-+ mcp_set_audio_divisor(ucb->mcp, div);
-+}
-+
-+/**
-+ * ucb1x00_set_telecom_divisor -
-+ * @ucb: UCB1x00 structure describing chip
-+ * @div: SIB clock divisor
-+ */
-+static inline void ucb1x00_set_telecom_divisor(struct ucb1x00 *ucb, unsigned int div)
-+{
-+ mcp_set_telecom_divisor(ucb->mcp, div);
-+}
-+
-+struct ucb1x00 *ucb1x00_get(void);
-+
-+void ucb1x00_io_set_dir(struct ucb1x00 *ucb, unsigned int, unsigned int);
-+void ucb1x00_io_write(struct ucb1x00 *ucb, unsigned int, unsigned int);
-+unsigned int ucb1x00_io_read(struct ucb1x00 *ucb);
-+
-+#define UCB_NOSYNC (0)
-+#define UCB_SYNC (1)
-+
-+unsigned int ucb1x00_adc_read(struct ucb1x00 *ucb, int adc_channel, int sync);
-+void ucb1x00_adc_enable(struct ucb1x00 *ucb);
-+void ucb1x00_adc_disable(struct ucb1x00 *ucb);
-+
-+/*
-+ * Which edges of the IRQ do you want to control today?
-+ */
-+#define UCB_RISING (1 << 0)
-+#define UCB_FALLING (1 << 1)
-+
-+int ucb1x00_hook_irq(struct ucb1x00 *ucb, unsigned int idx, void (*fn)(int, void *), void *devid);
-+void ucb1x00_enable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
-+void ucb1x00_disable_irq(struct ucb1x00 *ucb, unsigned int idx, int edges);
-+int ucb1x00_free_irq(struct ucb1x00 *ucb, unsigned int idx, void *devid);
-+
-+#endif
---- linux-2.4.25/drivers/mtd/chips/cfi_probe.c~2.4.25-vrs2.patch 2003-06-13 16:51:34.000000000 +0200
-+++ linux-2.4.25/drivers/mtd/chips/cfi_probe.c 2004-03-31 17:15:09.000000000 +0200
-@@ -65,6 +65,10 @@
- return 0;
- }
- cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
-+
-+ /* some devices don't respond to 0xF0, so send 0xFF to be sure */
-+ cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
-+
- cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL);
-
- if (!qry_present(map,base,cfi))
-@@ -84,6 +88,8 @@
- /* Eep. This chip also had the QRY marker.
- * Is it an alias for the new one? */
- cfi_send_gen_cmd(0xF0, 0, chips[i].start, map, cfi, cfi->device_type, NULL);
-+ /* some devices don't respond to 0xF0, so send 0xFF to be sure */
-+ cfi_send_gen_cmd(0xFF, 0, chips[i].start, map, cfi, cfi->device_type, NULL);
-
- /* If the QRY marker goes away, it's an alias */
- if (!qry_present(map, chips[i].start, cfi)) {
-@@ -96,7 +102,8 @@
- * too and if it's the same, assume it's an alias. */
- /* FIXME: Use other modes to do a proper check */
- cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
--
-+ /* some devices don't respond to 0xF0, so send 0xFF to be sure */
-+ cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
- if (qry_present(map, base, cfi)) {
- printk(KERN_DEBUG "%s: Found an alias at 0x%x for the chip at 0x%lx\n",
- map->name, base, chips[i].start);
-@@ -119,6 +126,10 @@
- /* Put it back into Read Mode */
- cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
-
-+ /* some devices don't respond to 0xF0, so send 0xFF to be sure */
-+ cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
-+
-+
- printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit mode\n",
- map->name, cfi->interleave, cfi->device_type*8, base,
- map->buswidth*8);
-@@ -165,6 +176,20 @@
- cfi->cfiq->InterfaceDesc = le16_to_cpu(cfi->cfiq->InterfaceDesc);
- cfi->cfiq->MaxBufWriteSize = le16_to_cpu(cfi->cfiq->MaxBufWriteSize);
-
-+ /*
-+ * ST screwed up the CFI interface for buffer writes on their parts,
-+ * so this needs to be fixed up by hand here.
-+ *
-+ * A possible enhancment is that instead of just reverting back
-+ * to word write (as this does), we could use the ST specific double
-+ * word write instead.
-+ */
-+
-+ if (cfi_read_query(map,base) == 0x20){
-+ cfi->cfiq->BufWriteTimeoutTyp = 0;
-+ cfi->cfiq->BufWriteTimeoutMax = 0;
-+ }
-+
- #ifdef DEBUG_CFI
- /* Dump the information therein */
- print_cfi_ident(cfi->cfiq);
-@@ -182,6 +207,9 @@
- /* Put it back into Read Mode */
- cfi_send_gen_cmd(0xF0, 0, base, map, cfi, cfi->device_type, NULL);
-
-+ /* some devices don't respond to 0xF0, so send 0xFF to be sure */
-+ cfi_send_gen_cmd(0xFF, 0, base, map, cfi, cfi->device_type, NULL);
-+
- return 1;
- }
-
---- linux-2.4.25/drivers/mtd/devices/Config.in~2.4.25-vrs2.patch 2003-06-13 16:51:34.000000000 +0200
-+++ linux-2.4.25/drivers/mtd/devices/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -17,6 +17,15 @@
- if [ "$CONFIG_SA1100_LART" = "y" ]; then
- dep_tristate ' 28F160xx flash driver for LART' CONFIG_MTD_LART $CONFIG_MTD
- fi
-+if [ "$CONFIG_ARCH_MX1ADS" = "y" ]; then
-+ dep_tristate ' SyncFlash driver for MX1ADS' CONFIG_MTD_SYNCFLASH $CONFIG_MTD
-+fi
-+if [ "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
-+ dep_tristate ' AT91RM9200 DataFlash support' CONFIG_MTD_AT91_DATAFLASH $CONFIG_MTD
-+ if [ "$CONFIG_MTD_AT91_DATAFLASH" = "y" -o "$CONFIG_MTD_AT91_DATAFLASH" = "m" ]; then
-+ bool ' Enable DataFlash card? ' CONFIG_MTD_AT91_DATAFLASH_CARD
-+ fi
-+fi
- dep_tristate ' Test driver using RAM' CONFIG_MTD_MTDRAM $CONFIG_MTD
- if [ "$CONFIG_MTD_MTDRAM" = "y" -o "$CONFIG_MTD_MTDRAM" = "m" ]; then
- int 'MTDRAM device size in KiB' CONFIG_MTDRAM_TOTAL_SIZE 4096
---- linux-2.4.25/drivers/mtd/devices/Makefile~2.4.25-vrs2.patch 2002-11-29 00:53:13.000000000 +0100
-+++ linux-2.4.25/drivers/mtd/devices/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -21,6 +21,7 @@
- obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o
- obj-$(CONFIG_MTD_MTDRAM) += mtdram.o
- obj-$(CONFIG_MTD_LART) += lart.o
-+obj-$(CONFIG_MTD_SYNCFLASH) += syncflash.o
- obj-$(CONFIG_MTD_BLKMTD) += blkmtd.o
-
- include $(TOPDIR)/Rules.make
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/mtd/devices/syncflash.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,615 @@
-+/*
-+ * MTD driver for Micron SyncFlash flash memory.
-+ *
-+ * Author: Jon McClintock <jonm@bluemug.com>
-+ *
-+ * Based loosely upon the LART flash driver, authored by Abraham vd Merwe
-+ * <abraham@2d3d.co.za>.
-+ *
-+ * Copyright 2003, Blue Mug, Inc. for Motorola, Inc.
-+ *
-+ * This code is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * References:
-+ *
-+ * [1] Micron SyncFlash homepage
-+ * - http://www.syncflash.com/
-+ *
-+ * [2] MT28S4M16LC -- 4Mx16 SyncFlash memory datasheet
-+ * - http://syncflash.com/pdfs/datasheets/mt28s4m16lc_6.pdf
-+ *
-+ * [3] MTD internal API documentation
-+ * - http://www.linux-mtd.infradead.org/tech/
-+ *
-+ * Limitations:
-+ *
-+ * Even though this driver is written for Micron SyncFlash, it is quite
-+ * specific to the Motorola MX1 ADS development board.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/version.h>
-+#include <linux/errno.h>
-+#include <linux/mtd/mtd.h>
-+#include <asm/io.h>
-+
-+/* partition support */
-+#define HAVE_PARTITIONS
-+#ifdef HAVE_PARTITIONS
-+#include <linux/mtd/partitions.h>
-+#endif
-+
-+#ifndef CONFIG_ARCH_MX1ADS
-+#error The SyncFlash driver currently only supports the MX1 ADS platform.
-+#endif
-+
-+/*
-+ * General flash configuration parameters.
-+ */
-+#define BUSWIDTH 4
-+#define FLASH_BLOCKSIZE (256 * 1024 * BUSWIDTH)
-+#define FLASH_NUMBLOCKS 16
-+
-+#define BUSWIDTH 4
-+#define FLASH_ADDRESS IO_ADDRESS(MX1ADS_FLASH_BASE)
-+
-+#define FLASH_MANUFACTURER 0x002C002C
-+#define FLASH_DEVICE_ID 0x00D300D3
-+
-+/*
-+ * The size and extent of the bootloader in flash.
-+ */
-+#define NUM_BOOTLOADER_BLOCKS 1
-+#define BOOTLOADER_START 0x00000000
-+#define BOOTLOADER_LEN (NUM_BOOTLOADER_BLOCKS * FLASH_BLOCKSIZE)
-+
-+/*
-+ * The size and extent of the kernel in flash.
-+ */
-+#define NUM_KERNEL_BLOCKS 1
-+#define KERNEL_START (BOOTLOADER_START + BOOTLOADER_LEN)
-+#define KERNEL_LEN (NUM_KERNEL_BLOCKS * FLASH_BLOCKSIZE)
-+
-+/* File system */
-+#define NUM_FILESYSTEM_BLOCKS 14
-+#define FILESYSTEM_START (KERNEL_START + KERNEL_LEN)
-+#define FILESYSTEM_LEN (NUM_FILESYSTEM_BLOCKS * FLASH_BLOCKSIZE)
-+
-+
-+/*
-+ * SDRAM controller register location and values. These are very specific
-+ * to the MX1.
-+ */
-+#define SDRAMC_REGISTER IO_ADDRESS(0x00221004)
-+
-+/*
-+ * This the mask we use to get the start of a block from a given address.
-+ */
-+#define BLOCK_MASK (0xFFF00000)
-+
-+/*
-+ * This is the A10 address line of the SyncFlash; it's used to initiate
-+ * a precharge command.
-+ */
-+#define SYNCFLASH_A10 (0x00100000)
-+
-+/*
-+ * SDRAM controller MODE settings.
-+ */
-+#define CMD_NORMAL (0x81020300) /* Normal Mode */
-+#define CMD_PREC (CMD_NORMAL + 0x10000000) /* Precharge command */
-+#define CMD_AUTO (CMD_NORMAL + 0x20000000) /* Auto refresh */
-+#define CMD_LMR (CMD_NORMAL + 0x30000000) /* Load Mode Register */
-+#define CMD_LCR (CMD_NORMAL + 0x60000000) /* LCR Command */
-+#define CMD_PROGRAM (CMD_NORMAL + 0x70000000) /* SyncFlash Program */
-+
-+/*
-+ * SyncFlash LCR Commands adjusted for the DBMX1 AHB internal address bus .
-+ */
-+#define LCR_READ_STATUS (0x0001C000) /* 0x70 */
-+#define LCR_READ_CONFIG (0x00024000) /* 0x90 */
-+#define LCR_ERASE_CONFIRM (0x00008000) /* 0x20 */
-+#define LCR_ERASE_NVMODE (0x0000C000) /* 0x30 */
-+#define LCR_PROG_NVMODE (0x00028000) /* 0xA0 */
-+#define LCR_SR_CLEAR (0x00014000) /* 0x50 */
-+
-+/*
-+ * Status register bits
-+ */
-+#define SR_VPS_ERROR (1 << 8) /* Power-Up status error */
-+#define SR_ISM_READY (1 << 7) /* State machine isn't busy */
-+#define SR_ERASE_ERROR (1 << 5) /* Erase/Unprotect error */
-+#define SR_PROGRAM_ERROR (1 << 4) /* Program/Protect error */
-+#define SR_DEVICE_PROTECTED (1 << 3) /* Device is protected */
-+#define SR_ISM_STATUS_H (1 << 2) /* Bank ISM status, high bit */
-+#define SR_ISM_STATUS_L (1 << 1) /* Bank ISM status, low bit */
-+#define SR_DEVICE_ISM_STATUS (1 << 0) /* ISM is device-level */
-+
-+#define SR_ERROR (SR_VPS_ERROR|SR_ERASE_ERROR|SR_PROGRAM_ERROR|SR_DEVICE_PROTECTED)
-+
-+#define STATUS_VALUE(a) ((a) | ((a) << 16))
-+
-+/*
-+ * Device configuration register offsets
-+ */
-+#define DC_MANUFACTURER (0 * BUSWIDTH)
-+#define DC_DEVICE_ID (1 * BUSWIDTH)
-+#define DC_BLOCK_PROTECT (2 * BUSWIDTH)
-+#define DC_DEVICE_PROTECT (3 * BUSWIDTH)
-+
-+#define FL_WORD(addr) (*(volatile unsigned long*)(addr))
-+
-+static char module_name[] = "syncflash";
-+
-+inline __u8 read8 (__u32 offset)
-+{
-+ return *(volatile __u8 *) (FLASH_ADDRESS + offset);
-+}
-+
-+inline __u32 read32 (__u32 offset)
-+{
-+ return *(volatile __u32 *) (FLASH_ADDRESS + offset);
-+}
-+
-+inline void write32 (__u32 x,__u32 offset)
-+{
-+ *(volatile __u32 *) (FLASH_ADDRESS + offset) = x;
-+}
-+
-+static __u32 read_device_configuration_register(__u32 reg_number)
-+{
-+ __u32 tmp;
-+
-+ /* Setup the SDRAM controller to issue an LCR command. */
-+ FL_WORD(SDRAMC_REGISTER) = CMD_LCR;
-+
-+ /* Perform a read to issue the Read Device Configuration Command. */
-+ tmp = read32(LCR_READ_CONFIG);
-+
-+ /* Return the SDRAM controller to normal mode. */
-+ FL_WORD(SDRAMC_REGISTER) = CMD_NORMAL;
-+
-+ /* Return the value of the specified register. */
-+ tmp = read32(reg_number);
-+
-+ return tmp;
-+}
-+
-+/*
-+ * Get the status of the flash devices.
-+ */
-+static __u32 flash_read_status()
-+{
-+ __u32 status, tmp;
-+
-+ /* Enter the SyncFlash Program READ/WRITE mode. */
-+ FL_WORD(SDRAMC_REGISTER) = CMD_PROGRAM;
-+
-+ /* Read the status register. */
-+ status = read32(LCR_READ_STATUS);
-+
-+ /* Clear the status register. */
-+ FL_WORD(SDRAMC_REGISTER) = CMD_LCR;
-+ tmp = read32(LCR_SR_CLEAR);
-+
-+ /* Return to Normal mode. */
-+ FL_WORD(SDRAMC_REGISTER) = CMD_NORMAL;
-+
-+ return status;
-+}
-+
-+/*
-+ * Loop until both write state machines are ready.
-+ */
-+static __u32 flash_status_wait()
-+{
-+ __u32 status;
-+ do {
-+ status = flash_read_status();
-+ } while ((status & STATUS_VALUE(SR_ISM_READY)) !=
-+ STATUS_VALUE(SR_ISM_READY));
-+ return status;
-+}
-+
-+/*
-+ * Loop until the Write State machine is ready, then do a full error
-+ * check. Clear status and leave the flash in Read Array mode; return
-+ * 0 for no error, -1 for error.
-+ */
-+static int flash_status_full_check()
-+{
-+ __u32 status;
-+
-+ status = flash_status_wait() & STATUS_VALUE(SR_ERROR);
-+ return status ? -EIO : 0;
-+}
-+
-+/*
-+ * Return the flash to the normal mode.
-+ */
-+static void flash_normal_mode()
-+{
-+ __u32 tmp;
-+
-+ /* First issue a precharge all command. */
-+ FL_WORD(SDRAMC_REGISTER) = CMD_PREC;
-+ tmp = read32(SYNCFLASH_A10);
-+
-+ /* Now place the SDRAM controller in Normal mode. */
-+ FL_WORD(SDRAMC_REGISTER) = CMD_NORMAL;
-+}
-+
-+/*
-+ * Probe for SyncFlash memory on MX1ADS board.
-+ *
-+ * Returns 1 if we found SyncFlash memory, 0 otherwise.
-+ */
-+static int flash_probe (void)
-+{
-+ __u32 manufacturer, device_id;
-+
-+ /* For some reason, the first read doesn't work, so we do it
-+ * twice. */
-+ manufacturer = read_device_configuration_register(DC_MANUFACTURER);
-+ manufacturer = read_device_configuration_register(DC_MANUFACTURER);
-+ device_id = read_device_configuration_register(DC_DEVICE_ID);
-+
-+ printk("SyncFlash probe: manufacturer 0x%08lx, device_id 0x%08lx\n",
-+ manufacturer, device_id);
-+ return (manufacturer == FLASH_MANUFACTURER &&
-+ device_id == FLASH_DEVICE_ID);
-+}
-+
-+/*
-+ * Erase one block of flash memory at offset ``offset'' which is any
-+ * address within the block which should be erased.
-+ *
-+ * Returns 0 if successful, -1 otherwise.
-+ */
-+static inline int erase_block (__u32 offset)
-+{
-+ __u32 tmp;
-+
-+ /* Mask off the lower bits of the address to get the first address
-+ * in the flash block. */
-+ offset &= (__u32)BLOCK_MASK;
-+
-+ /* Perform a read and precharge of the bank before the LCR|ACT|WRIT
-+ * sequence to avoid the inadvertent precharge command occurring
-+ * during the LCR_ACT_WRIT sequence. */
-+ FL_WORD(SDRAMC_REGISTER) = CMD_NORMAL;
-+ tmp = read32(offset);
-+ FL_WORD(SDRAMC_REGISTER) = CMD_PREC;
-+ tmp = read32(offset);
-+
-+ /* Now start the actual erase. */
-+
-+ /* LCR|ACT|WRIT sequence */
-+ FL_WORD(SDRAMC_REGISTER) = CMD_LCR;
-+ write32(0, offset + LCR_ERASE_CONFIRM);
-+
-+ /* Return to normal mode to issue the erase confirm. */
-+ FL_WORD(SDRAMC_REGISTER) = CMD_NORMAL;
-+ write32(0xD0D0D0D0, offset);
-+
-+ if (flash_status_full_check()) {
-+ printk (KERN_WARNING "%s: erase error at address 0x%.8x.\n",
-+ module_name, offset);
-+ return (-1);
-+ }
-+
-+ flash_normal_mode();
-+
-+ return 0;
-+}
-+
-+static int flash_erase (struct mtd_info *mtd,struct erase_info *instr)
-+{
-+ __u32 addr,len;
-+ int i,first;
-+
-+ /* sanity checks */
-+ if (instr->addr + instr->len > mtd->size) return (-EINVAL);
-+
-+ /*
-+ * check that both start and end of the requested erase are
-+ * aligned with the erasesize at the appropriate addresses.
-+ *
-+ * skip all erase regions which are ended before the start of
-+ * the requested erase. Actually, to save on the calculations,
-+ * we skip to the first erase region which starts after the
-+ * start of the requested erase, and then go back one.
-+ */
-+ for (i = 0; (i < mtd->numeraseregions) &&
-+ (instr->addr >= mtd->eraseregions[i].offset); i++) ;
-+ i--;
-+
-+ /*
-+ * ok, now i is pointing at the erase region in which this
-+ * erase request starts. Check the start of the requested
-+ * erase range is aligned with the erase size which is in
-+ * effect here.
-+ */
-+ if (instr->addr & (mtd->eraseregions[i].erasesize - 1))
-+ return (-EINVAL);
-+
-+ /* Remember the erase region we start on */
-+ first = i;
-+
-+ /*
-+ * next, check that the end of the requested erase is aligned
-+ * with the erase region at that address.
-+ *
-+ * as before, drop back one to point at the region in which
-+ * the address actually falls
-+ */
-+ for (;
-+ (i < mtd->numeraseregions) &&
-+ ((instr->addr + instr->len) >= mtd->eraseregions[i].offset) ;
-+ i++) ;
-+ i--;
-+
-+ /* is the end aligned on a block boundary? */
-+ if ((instr->addr + instr->len) & (mtd->eraseregions[i].erasesize - 1))
-+ return (-EINVAL);
-+
-+ addr = instr->addr;
-+ len = instr->len;
-+
-+ i = first;
-+
-+ /* now erase those blocks */
-+ while (len)
-+ {
-+ if (erase_block (addr))
-+ {
-+ instr->state = MTD_ERASE_FAILED;
-+ return (-EIO);
-+ }
-+
-+ addr += mtd->eraseregions[i].erasesize;
-+ len -= mtd->eraseregions[i].erasesize;
-+
-+ if (addr == (mtd->eraseregions[i].offset +
-+ (mtd->eraseregions[i].erasesize *
-+ mtd->eraseregions[i].numblocks)))
-+ i++;
-+ }
-+
-+ instr->state = MTD_ERASE_DONE;
-+ if (instr->callback) instr->callback (instr);
-+
-+ return (0);
-+}
-+
-+static int flash_read (struct mtd_info *mtd, loff_t from,
-+ size_t len, size_t *retlen, u_char *buf)
-+{
-+ /* Sanity checks. */
-+ if (!len) return (0);
-+ if (from + len > mtd->size) return (-EINVAL);
-+
-+ /* Ensure that we are in normal mode. */
-+ flash_normal_mode();
-+
-+ /* We always read len bytes. */
-+ *retlen = len;
-+
-+ /* first, we read bytes until we reach a dword boundary */
-+ if (from & (BUSWIDTH - 1))
-+ {
-+ int gap = BUSWIDTH - (from & (BUSWIDTH - 1));
-+ while (len && gap--) *buf++ = read8(from++), len--;
-+ }
-+
-+ /* now we read dwords until we reach a non-dword boundary */
-+ while (len >= BUSWIDTH)
-+ {
-+ *((__u32 *) buf) = read32(from);
-+
-+ buf += BUSWIDTH;
-+ from += BUSWIDTH;
-+ len -= BUSWIDTH;
-+ }
-+
-+ /* top up the last unaligned bytes */
-+ if (len & (BUSWIDTH - 1))
-+ while (len--) *buf++ = read8(from++);
-+
-+ return (0);
-+}
-+
-+/*
-+ * Write one dword ``x'' to flash memory at offset ``offset''. ``offset''
-+ * must be 32 bits, i.e. it must be on a dword boundary.
-+ *
-+ * Returns 0 if successful, -1 otherwise.
-+ */
-+static int flash_write_dword(__u32 offset, __u32 x)
-+{
-+ __u32 tmp;
-+
-+ /* First issue a precharge all command. */
-+ FL_WORD(SDRAMC_REGISTER) = CMD_PREC;
-+ tmp = read32(SYNCFLASH_A10);
-+
-+ /* Enter the SyncFlash programming mode. */
-+ FL_WORD(SDRAMC_REGISTER) = CMD_PROGRAM;
-+ write32(x, offset);
-+
-+ /* Wait for the write to complete. */
-+ flash_status_wait();
-+
-+ /* Return to normal mode. */
-+ flash_normal_mode();
-+
-+ return 0;
-+}
-+
-+static int flash_write (struct mtd_info *mtd,loff_t to,size_t len,size_t *retlen,const u_char *buf)
-+{
-+ __u8 tmp[4];
-+ int i,n;
-+
-+ *retlen = 0;
-+
-+ /* Sanity checks */
-+ if (!len) return (0);
-+ if (to + len > mtd->size) return (-EINVAL);
-+
-+ /* First, we write a 0xFF.... padded byte until we reach a
-+ * dword boundary. */
-+ if (to & (BUSWIDTH - 1))
-+ {
-+ __u32 aligned = to & ~(BUSWIDTH - 1);
-+ int gap = to - aligned;
-+
-+ i = n = 0;
-+
-+ while (gap--) tmp[i++] = 0xFF;
-+ while (len && i < BUSWIDTH) tmp[i++] = buf[n++], len--;
-+ while (i < BUSWIDTH) tmp[i++] = 0xFF;
-+
-+ if (flash_write_dword(aligned, *((__u32 *) tmp)))
-+ return (-EIO);
-+
-+ to += n;
-+ buf += n;
-+ *retlen += n;
-+ }
-+
-+ /* Now we write dwords until we reach a non-dword boundary. */
-+ while (len >= BUSWIDTH)
-+ {
-+ if (flash_write_dword (to,*((__u32 *) buf))) return (-EIO);
-+
-+ to += BUSWIDTH;
-+ buf += BUSWIDTH;
-+ *retlen += BUSWIDTH;
-+ len -= BUSWIDTH;
-+ }
-+
-+ /* Top up the last unaligned bytes, padded with 0xFF.... */
-+ if (len & (BUSWIDTH - 1))
-+ {
-+ i = n = 0;
-+
-+ while (len--) tmp[i++] = buf[n++];
-+ while (i < BUSWIDTH) tmp[i++] = 0xFF;
-+
-+ if (flash_write_dword (to,*((__u32 *) tmp))) return (-EIO);
-+
-+ *retlen += n;
-+ }
-+
-+ return flash_status_full_check();
-+}
-+
-+
-+
-+#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
-+
-+static struct mtd_info mtd;
-+
-+static struct mtd_erase_region_info erase_regions[] =
-+{
-+ /* flash blocks */
-+ {
-+ offset: 0x00000000,
-+ erasesize: FLASH_BLOCKSIZE,
-+ numblocks: FLASH_NUMBLOCKS
-+ },
-+};
-+
-+#ifdef HAVE_PARTITIONS
-+static struct mtd_partition syncflash_partitions[] =
-+{
-+ /* bootloader */
-+ {
-+ name: "bootloader",
-+ offset: BOOTLOADER_START,
-+ size: BOOTLOADER_LEN,
-+ mask_flags: 0
-+ },
-+ /* Kernel */
-+ {
-+ name: "kernel",
-+ offset: KERNEL_START, /* MTDPART_OFS_APPEND */
-+ size: KERNEL_LEN,
-+ mask_flags: 0
-+ },
-+ /* file system */
-+ {
-+ name: "file system",
-+ offset: FILESYSTEM_START, /* MTDPART_OFS_APPEND */
-+ size: FILESYSTEM_LEN, /* MTDPART_SIZ_FULL */
-+ mask_flags: 0
-+ }
-+};
-+#endif
-+
-+int __init syncflash_init (void)
-+{
-+ int result;
-+
-+ memset (&mtd,0,sizeof (mtd));
-+
-+ printk ("MTD driver for Micron SyncFlash.\n");
-+ printk ("%s: Probing for SyncFlash on MX1ADS...\n",module_name);
-+
-+ if (!flash_probe ())
-+ {
-+ printk (KERN_WARNING "%s: Found no SyncFlash devices\n",
-+ module_name);
-+ return (-ENXIO);
-+ }
-+
-+ printk ("%s: Found a SyncFlash device.\n",module_name);
-+
-+ mtd.name = module_name;
-+ mtd.type = MTD_NORFLASH;
-+ mtd.flags = MTD_CAP_NORFLASH;
-+ mtd.size = FLASH_BLOCKSIZE * FLASH_NUMBLOCKS;
-+
-+ mtd.erasesize = FLASH_BLOCKSIZE;
-+ mtd.numeraseregions = NB_OF(erase_regions);
-+ mtd.eraseregions = erase_regions;
-+
-+ mtd.module = THIS_MODULE;
-+
-+ mtd.erase = flash_erase;
-+ mtd.read = flash_read;
-+ mtd.write = flash_write;
-+
-+#ifndef HAVE_PARTITIONS
-+ result = add_mtd_device(&mtd);
-+#else
-+ result = add_mtd_partitions(&mtd,
-+ syncflash_partitions,
-+ NB_OF(syncflash_partitions));
-+#endif
-+
-+ return (result);
-+}
-+
-+void __exit syncflash_exit (void)
-+{
-+#ifndef HAVE_PARTITIONS
-+ del_mtd_device (&mtd);
-+#else
-+ del_mtd_partitions (&mtd);
-+#endif
-+}
-+
-+module_init (syncflash_init);
-+module_exit (syncflash_exit);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Jon McClintock <jonm@bluemug.com>");
-+MODULE_DESCRIPTION("MTD driver for Micron MT28S4M16LC SyncFlash on MX1ADS board");
-+
-+
---- linux-2.4.25/drivers/mtd/maps/Config.in~2.4.25-vrs2.patch 2003-06-13 16:51:34.000000000 +0200
-+++ linux-2.4.25/drivers/mtd/maps/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -81,10 +81,10 @@
- dep_tristate ' CFI Flash device mapped on StrongARM SA11x0' CONFIG_MTD_SA1100 $CONFIG_MTD_CFI $CONFIG_ARCH_SA1100 $CONFIG_MTD_PARTITIONS
- dep_tristate ' CFI Flash device mapped on DC21285 Footbridge' CONFIG_MTD_DC21285 $CONFIG_MTD_CFI $CONFIG_ARCH_FOOTBRIDGE
- dep_tristate ' CFI Flash device mapped on the XScale IQ80310 board' CONFIG_MTD_IQ80310 $CONFIG_MTD_CFI $CONFIG_ARCH_IQ80310
-- dep_tristate ' CFI Flash device mapped on Epxa10db' CONFIG_MTD_EPXA10DB $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS $CONFIG_ARCH_CAMELOT
-- dep_tristate ' CFI Flash device mapped on the FortuNet board' CONFIG_MTD_FORTUNET $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS $CONFIG_SA1100_FORTUNET
-+ dep_tristate ' CFI Flash device mapped on the FortuNet board' CONFIG_MTD_FORTUNET $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS $CONFIG_ARCH_FORTUNET
-+ dep_tristate ' CFI Flash device mapped on Epxa' CONFIG_MTD_EPXA $CONFIG_MTD_CFI $CONFIG_MTD_PARTITIONS $CONFIG_ARCH_CAMELOT
- dep_tristate ' NV-RAM mapping AUTCPU12 board' CONFIG_MTD_AUTCPU12 $CONFIG_ARCH_AUTCPU12
-- dep_tristate ' CFI Flash device mapped on EDB7312' CONFIG_MTD_EDB7312 $CONFIG_MTD_CFI
-+ dep_tristate ' CFI Flash device mapped on EDB7312' CONFIG_MTD_EDB7312 $CONFIG_ARCH_EDB7212 $CONFIG_MTD_CFI
- dep_tristate ' JEDEC Flash device mapped on impA7' CONFIG_MTD_IMPA7 $CONFIG_MTD_JEDECPROBE
- dep_tristate ' JEDEC Flash device mapped on Ceiva/Polaroid PhotoMax Digital Picture Frame' CONFIG_MTD_CEIVA $CONFIG_MTD_JEDECPROBE $CONFIG_ARCH_CEIVA
- fi
---- linux-2.4.25/drivers/mtd/maps/Makefile~2.4.25-vrs2.patch 2003-06-13 16:51:34.000000000 +0200
-+++ linux-2.4.25/drivers/mtd/maps/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -3,11 +3,7 @@
- #
- # $Id$
-
--BELOW25 := $(shell echo $(PATCHLEVEL) | sed s/[1234]/y/)
--
--ifeq ($(BELOW25),y)
- O_TARGET := mapslink.o
--endif
-
- # Chip mappings
- obj-$(CONFIG_MTD_CDB89712) += cdb89712.o
-@@ -17,7 +13,7 @@
- obj-$(CONFIG_MTD_DC21285) += dc21285.o
- obj-$(CONFIG_MTD_DILNETPC) += dilnetpc.o
- obj-$(CONFIG_MTD_ELAN_104NC) += elan-104nc.o
--obj-$(CONFIG_MTD_EPXA10DB) += epxa10db-flash.o
-+obj-$(CONFIG_MTD_EPXA) += epxa-flash.o
- obj-$(CONFIG_MTD_IQ80310) += iq80310.o
- obj-$(CONFIG_MTD_L440GX) += l440gx.o
- obj-$(CONFIG_MTD_AMD76XROM) += amd76xrom.o
-@@ -29,9 +25,9 @@
- obj-$(CONFIG_MTD_OCTAGON) += octagon-5066.o
- ifneq ($(CONFIG_MTD_PHYSMAP),n)
- ifeq ($(CONFIG_MTD_PHYSMAP_BUSWIDTH),8)
-- obj-$(CONFIG_MTD_PHYSMAP) += physmap64.o
-+ obj-$(CONFIG_MTD_PHYSMAP) += physmap64.o
- else
-- obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
-+ obj-$(CONFIG_MTD_PHYSMAP) += physmap.o
- endif
- endif
- obj-$(CONFIG_MTD_PNC2000) += pnc2000.o
-@@ -39,6 +35,9 @@
- obj-$(CONFIG_MTD_RPXLITE) += rpxlite.o
- obj-$(CONFIG_MTD_TQM8XXL) += tqm8xxl.o
- obj-$(CONFIG_MTD_SA1100) += sa1100-flash.o
-+ifeq ($(CONFIG_ASSABET_NEPONSET),y)
-+ obj-$(CONFIG_MTD_SA1100) += neponset-flash.o
-+endif
- obj-$(CONFIG_MTD_SBC_GXX) += sbc_gxx.o
- obj-$(CONFIG_MTD_SC520CDP) += sc520cdp.o
- obj-$(CONFIG_MTD_NETSC520) += netsc520.o
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/mtd/maps/epxa-flash.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,234 @@
-+/*
-+ * Flash memory access on EPXA based devices
-+ *
-+ * (C) 2000 Nicolas Pitre <nico@cam.org>
-+ * Copyright (C) 2001 Altera Corporation
-+ * Copyright (C) 2001 Red Hat, Inc.
-+ *
-+ * $Id$
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <asm/io.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+
-+#include <asm/hardware.h>
-+#ifdef CONFIG_EPXA10DB
-+#define BOARD_NAME "EPXA10DB"
-+#else
-+#define BOARD_NAME "EPXA1DB"
-+#endif
-+
-+static int nr_parts = 0;
-+static struct mtd_partition *parts;
-+
-+static struct mtd_info *mymtd;
-+
-+extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **);
-+static int epxa_default_partitions(struct mtd_info *master, struct mtd_partition **pparts);
-+
-+static __u8 epxa_read8(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readb(map->map_priv_1 + ofs);
-+}
-+
-+static __u16 epxa_read16(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readw(map->map_priv_1 + ofs);
-+}
-+
-+static __u32 epxa_read32(struct map_info *map, unsigned long ofs)
-+{
-+ return __raw_readl(map->map_priv_1 + ofs);
-+}
-+
-+static void epxa_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-+{
-+ memcpy_fromio(to, map->map_priv_1 + from, len);
-+}
-+
-+static void epxa_write8(struct map_info *map, __u8 d, unsigned long adr)
-+{
-+ __raw_writeb(d, map->map_priv_1 + adr);
-+ mb();
-+}
-+
-+static void epxa_write16(struct map_info *map, __u16 d, unsigned long adr)
-+{
-+ __raw_writew(d, map->map_priv_1 + adr);
-+ mb();
-+}
-+
-+static void epxa_write32(struct map_info *map, __u32 d, unsigned long adr)
-+{
-+ __raw_writel(d, map->map_priv_1 + adr);
-+ mb();
-+}
-+
-+static void epxa_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-+{
-+ memcpy_toio(map->map_priv_1 + to, from, len);
-+}
-+
-+static struct map_info epxa_map = {
-+ .name = "EPXA flash",
-+ .size = FLASH_SIZE,
-+ .buswidth = 2,
-+ .read8 = epxa_read8,
-+ .read16 = epxa_read16,
-+ .read32 = epxa_read32,
-+ .copy_from = epxa_copy_from,
-+ .write8 = epxa_write8,
-+ .write16 = epxa_write16,
-+ .write32 = epxa_write32,
-+ .copy_to = epxa_copy_to
-+};
-+
-+static int __init epxa_mtd_init(void)
-+{
-+ int i;
-+
-+ printk(KERN_NOTICE "%s flash device: %x at %x\n", BOARD_NAME, FLASH_SIZE, FLASH_START);
-+ epxa_map.map_priv_1 = (unsigned long)ioremap_nocache(FLASH_START, FLASH_SIZE);
-+ if (!epxa_map.map_priv_1) {
-+ printk("Failed to ioremap %s flash\n",BOARD_NAME);
-+ return -EIO;
-+ }
-+
-+ mymtd = do_map_probe("cfi_probe", &epxa_map);
-+ if (!mymtd) {
-+ iounmap((void *)epxa_map.map_priv_1);
-+ return -ENXIO;
-+ }
-+
-+ mymtd->module = THIS_MODULE;
-+
-+ /* Unlock the flash device. */
-+ if(mymtd->unlock){
-+ for (i=0; i<mymtd->numeraseregions;i++){
-+ int j;
-+ for(j=0;j<mymtd->eraseregions[i].numblocks;j++){
-+ mymtd->unlock(mymtd,mymtd->eraseregions[i].offset + j * mymtd->eraseregions[i].erasesize,mymtd->eraseregions[i].erasesize);
-+ }
-+ }
-+ }
-+
-+#ifdef CONFIG_MTD_REDBOOT_PARTS
-+ nr_parts = parse_redboot_partitions(mymtd, &parts);
-+
-+ if (nr_parts > 0) {
-+ add_mtd_partitions(mymtd, parts, nr_parts);
-+ return 0;
-+ }
-+#endif
-+#ifdef CONFIG_MTD_AFS_PARTS
-+ nr_parts = parse_afs_partitions(mymtd, &parts);
-+
-+ if (nr_parts > 0) {
-+ add_mtd_partitions(mymtd, parts, nr_parts);
-+ return 0;
-+ }
-+#endif
-+
-+ /* No recognised partitioning schemes found - use defaults */
-+ nr_parts = epxa_default_partitions(mymtd, &parts);
-+ if (nr_parts > 0) {
-+ add_mtd_partitions(mymtd, parts, nr_parts);
-+ return 0;
-+ }
-+
-+ /* If all else fails... */
-+ add_mtd_device(mymtd);
-+ return 0;
-+}
-+
-+static void __exit epxa_mtd_cleanup(void)
-+{
-+ if (mymtd) {
-+ if (nr_parts)
-+ del_mtd_partitions(mymtd);
-+ else
-+ del_mtd_device(mymtd);
-+ map_destroy(mymtd);
-+ }
-+ if (epxa_map.map_priv_1) {
-+ iounmap((void *)epxa_map.map_priv_1);
-+ epxa_map.map_priv_1 = 0;
-+ }
-+}
-+
-+
-+/*
-+ * This will do for now, once we decide which bootldr we're finally
-+ * going to use then we'll remove this function and do it properly
-+ *
-+ * Partions are currently (as offsets from base of flash):
-+ * 0x00000000 - 0x003FFFFF - bootloader (!)
-+ * 0x00400000 - 0x00FFFFFF - Flashdisk
-+ */
-+
-+static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_partition **pparts)
-+{
-+ struct mtd_partition *parts;
-+ int ret;
-+ int npartitions = 0;
-+ char *names;
-+ const char *name = "jffs";
-+
-+ printk("Using default partitions for %s\n",BOARD_NAME);
-+ npartitions=1;
-+ parts = kmalloc(npartitions*sizeof(*parts)+strlen(name)+1, GFP_KERNEL);
-+ if (!parts) {
-+ ret = -ENOMEM;
-+ goto out;
-+ }
-+ memzero(parts,npartitions*sizeof(*parts)+strlen(name));
-+
-+ names = (char *)&parts[npartitions];
-+ parts[0].name = names;
-+ names += strlen(name) + 1;
-+ strcpy(parts[0].name, name);
-+
-+#ifdef CONFIG_EPXA10DB_R2
-+ parts[0].size = FLASH_SIZE-0x00400000;
-+ parts[0].offset = 0x00400000;
-+#elif defined CONFIG_EPXA10DB_R3
-+ parts[0].size = 0x00800000;
-+ parts[0].offset = 0x00800000;
-+#else
-+ parts[0].size = FLASH_SIZE-0x00180000;
-+ parts[0].offset = 0x00180000;
-+#endif
-+ ret = npartitions;
-+
-+ out:
-+ *pparts = parts;
-+ return ret;
-+}
-+
-+
-+module_init(epxa_mtd_init);
-+module_exit(epxa_mtd_cleanup);
-+
-+MODULE_AUTHOR("Clive Davies");
-+MODULE_DESCRIPTION("Altera epxa mtd flash map");
-+MODULE_LICENSE("GPL");
---- linux-2.4.25/drivers/mtd/maps/epxa10db-flash.c~2.4.25-vrs2.patch
-+++ linux-2.4.25/drivers/mtd/maps/epxa10db-flash.c
--/*
-- * Flash memory access on EPXA based devices
-- *
-- * (C) 2000 Nicolas Pitre <nico@cam.org>
-- * Copyright (C) 2001 Altera Corporation
-- * Copyright (C) 2001 Red Hat, Inc.
-- *
-- * $Id$
-- *
-- * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-- */
--
--#include <linux/config.h>
--#include <linux/module.h>
--#include <linux/types.h>
--#include <linux/kernel.h>
--#include <asm/io.h>
--#include <linux/mtd/mtd.h>
--#include <linux/mtd/map.h>
--#include <linux/mtd/partitions.h>
--
--#include <asm/hardware.h>
--#ifdef CONFIG_EPXA10DB
--#define BOARD_NAME "EPXA10DB"
--#else
--#define BOARD_NAME "EPXA1DB"
--#endif
--
--static int nr_parts = 0;
--static struct mtd_partition *parts;
--
--static struct mtd_info *mymtd;
--
--extern int parse_redboot_partitions(struct mtd_info *, struct mtd_partition **);
--static int epxa_default_partitions(struct mtd_info *master, struct mtd_partition **pparts);
--
--static __u8 epxa_read8(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readb(map->map_priv_1 + ofs);
--}
--
--static __u16 epxa_read16(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readw(map->map_priv_1 + ofs);
--}
--
--static __u32 epxa_read32(struct map_info *map, unsigned long ofs)
--{
-- return __raw_readl(map->map_priv_1 + ofs);
--}
--
--static void epxa_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
--{
-- memcpy_fromio(to, (void *)(map->map_priv_1 + from), len);
--}
--
--static void epxa_write8(struct map_info *map, __u8 d, unsigned long adr)
--{
-- __raw_writeb(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void epxa_write16(struct map_info *map, __u16 d, unsigned long adr)
--{
-- __raw_writew(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void epxa_write32(struct map_info *map, __u32 d, unsigned long adr)
--{
-- __raw_writel(d, map->map_priv_1 + adr);
-- mb();
--}
--
--static void epxa_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
--{
-- memcpy_toio((void *)(map->map_priv_1 + to), from, len);
--}
--
--
--
--static struct map_info epxa_map = {
-- name: "EPXA flash",
-- size: FLASH_SIZE,
-- buswidth: 2,
-- read8: epxa_read8,
-- read16: epxa_read16,
-- read32: epxa_read32,
-- copy_from: epxa_copy_from,
-- write8: epxa_write8,
-- write16: epxa_write16,
-- write32: epxa_write32,
-- copy_to: epxa_copy_to
--};
--
--
--static int __init epxa_mtd_init(void)
--{
-- int i;
--
-- printk(KERN_NOTICE "%s flash device: %x at %x\n", BOARD_NAME, FLASH_SIZE, FLASH_START);
-- epxa_map.map_priv_1 = (unsigned long)ioremap(FLASH_START, FLASH_SIZE);
-- if (!epxa_map.map_priv_1) {
-- printk("Failed to ioremap %s flash\n",BOARD_NAME);
-- return -EIO;
-- }
--
-- mymtd = do_map_probe("cfi_probe", &epxa_map);
-- if (!mymtd) {
-- iounmap((void *)epxa_map.map_priv_1);
-- return -ENXIO;
-- }
--
-- mymtd->module = THIS_MODULE;
--
-- /* Unlock the flash device. */
-- if(mymtd->unlock){
-- for (i=0; i<mymtd->numeraseregions;i++){
-- int j;
-- for(j=0;j<mymtd->eraseregions[i].numblocks;j++){
-- mymtd->unlock(mymtd,mymtd->eraseregions[i].offset + j * mymtd->eraseregions[i].erasesize,mymtd->eraseregions[i].erasesize);
-- }
-- }
-- }
--
--#ifdef CONFIG_MTD_REDBOOT_PARTS
-- nr_parts = parse_redboot_partitions(mymtd, &parts);
--
-- if (nr_parts > 0) {
-- add_mtd_partitions(mymtd, parts, nr_parts);
-- return 0;
-- }
--#endif
--#ifdef CONFIG_MTD_AFS_PARTS
-- nr_parts = parse_afs_partitions(mymtd, &parts);
--
-- if (nr_parts > 0) {
-- add_mtd_partitions(mymtd, parts, nr_parts);
-- return 0;
-- }
--#endif
--
-- /* No recognised partitioning schemes found - use defaults */
-- nr_parts = epxa_default_partitions(mymtd, &parts);
-- if (nr_parts > 0) {
-- add_mtd_partitions(mymtd, parts, nr_parts);
-- return 0;
-- }
--
-- /* If all else fails... */
-- add_mtd_device(mymtd);
-- return 0;
--}
--
--static void __exit epxa_mtd_cleanup(void)
--{
-- if (mymtd) {
-- if (nr_parts)
-- del_mtd_partitions(mymtd);
-- else
-- del_mtd_device(mymtd);
-- map_destroy(mymtd);
-- }
-- if (epxa_map.map_priv_1) {
-- iounmap((void *)epxa_map.map_priv_1);
-- epxa_map.map_priv_1 = 0;
-- }
--}
--
--
--/*
-- * This will do for now, once we decide which bootldr we're finally
-- * going to use then we'll remove this function and do it properly
-- *
-- * Partions are currently (as offsets from base of flash):
-- * 0x00000000 - 0x003FFFFF - bootloader (!)
-- * 0x00400000 - 0x00FFFFFF - Flashdisk
-- */
--
--static int __init epxa_default_partitions(struct mtd_info *master, struct mtd_partition **pparts)
--{
-- struct mtd_partition *parts;
-- int ret, i;
-- int npartitions = 0;
-- char *names;
-- const char *name = "jffs";
--
-- printk("Using default partitions for %s\n",BOARD_NAME);
-- npartitions=1;
-- parts = kmalloc(npartitions*sizeof(*parts)+strlen(name), GFP_KERNEL);
-- memzero(parts,npartitions*sizeof(*parts)+strlen(name));
-- if (!parts) {
-- ret = -ENOMEM;
-- goto out;
-- }
-- i=0;
-- names = (char *)&parts[npartitions];
-- parts[i].name = names;
-- names += strlen(name) + 1;
-- strcpy(parts[i].name, name);
--
--#ifdef CONFIG_EPXA10DB
-- parts[i].size = FLASH_SIZE-0x00400000;
-- parts[i].offset = 0x00400000;
--#else
-- parts[i].size = FLASH_SIZE-0x00180000;
-- parts[i].offset = 0x00180000;
--#endif
--
-- out:
-- *pparts = parts;
-- return npartitions;
--}
--
--
--module_init(epxa_mtd_init);
--module_exit(epxa_mtd_cleanup);
--
--MODULE_AUTHOR("Clive Davies");
--MODULE_DESCRIPTION("Altera epxa mtd flash map");
--MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/mtd/maps/neponset-flash.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,109 @@
-+/*
-+ * Flash memory access on SA11x0 based devices
-+ *
-+ * (C) 2000 Nicolas Pitre <nico@cam.org>
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/map.h>
-+#include <linux/mtd/partitions.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/arch/assabet.h>
-+
-+static __u8 read8(struct map_info *map, unsigned long ofs)
-+{
-+ return readb(map->map_priv_1 + ofs);
-+}
-+
-+static __u16 read16(struct map_info *map, unsigned long ofs)
-+{
-+ return readw(map->map_priv_1 + ofs);
-+}
-+
-+static __u32 read32(struct map_info *map, unsigned long ofs)
-+{
-+ return readl(map->map_priv_1 + ofs);
-+}
-+
-+static void copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
-+{
-+ memcpy_fromio(to, map->map_priv_1 + from, len);
-+}
-+
-+static void write8(struct map_info *map, __u8 d, unsigned long adr)
-+{
-+ writeb(d, map->map_priv_1 + adr);
-+}
-+
-+static void write16(struct map_info *map, __u16 d, unsigned long adr)
-+{
-+ writew(d, map->map_priv_1 + adr);
-+}
-+
-+static void write32(struct map_info *map, __u32 d, unsigned long adr)
-+{
-+ writel(d, map->map_priv_1 + adr);
-+}
-+
-+static void copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
-+{
-+ memcpy_toio(map->map_priv_1 + to, from, len);
-+}
-+
-+#define MAX_SZ (32 * 1024 * 1024)
-+
-+static struct map_info neponset_map = {
-+ name: "Neponset",
-+ size: MAX_SZ,
-+ buswidth: 4,
-+ read8: read8,
-+ read16: read16,
-+ read32: read32,
-+ copy_from: copy_from,
-+ write8: write8,
-+ write16: write16,
-+ write32: write32,
-+ copy_to: copy_to,
-+};
-+
-+extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
-+extern int parse_bootldr_partitions(struct mtd_info *master, struct mtd_partition **pparts);
-+
-+static struct mtd_info *neponset_mtd;
-+
-+int __init neponset_mtd_init(void)
-+{
-+ if (!machine_is_assabet() || !machine_has_neponset())
-+ return -ENODEV;
-+
-+ neponset_map.map_priv_1 = (unsigned int)ioremap(0x08000000, MAX_SZ);
-+ if (!neponset_map.map_priv_1)
-+ return -ENOMEM;
-+
-+ neponset_mtd = do_map_probe("cfi_probe", &neponset_map);
-+ if (!neponset_mtd)
-+ return -ENXIO;
-+ neponset_mtd->module = THIS_MODULE;
-+ add_mtd_device(neponset_mtd);
-+ return 0;
-+}
-+
-+static void __exit neponset_mtd_cleanup(void)
-+{
-+ if (neponset_mtd)
-+ map_destroy(neponset_mtd);
-+ if (neponset_map.map_priv_1)
-+ iounmap((void *)neponset_map.map_priv_1);
-+}
-+
-+module_init(neponset_mtd_init);
-+module_exit(neponset_mtd_cleanup);
---- linux-2.4.25/drivers/mtd/maps/sa1100-flash.c~2.4.25-vrs2.patch 2003-06-13 16:51:34.000000000 +0200
-+++ linux-2.4.25/drivers/mtd/maps/sa1100-flash.c 2004-03-31 17:15:09.000000000 +0200
-@@ -97,6 +97,32 @@
- * entries. Thanks.
- */
-
-+#ifdef CONFIG_SA1100_ADSAGC
-+#define ADSAGC_FLASH_SIZE 0x02000000
-+static struct mtd_partition adsagc_partitions[] = {
-+ {
-+ name: "bootROM",
-+ size: 0x80000,
-+ offset: 0,
-+ mask_flags: MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ name: "zImage",
-+ size: 0x100000,
-+ offset: MTDPART_OFS_APPEND,
-+ mask_flags: MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ name: "ramdisk.gz",
-+ size: 0x300000,
-+ offset: MTDPART_OFS_APPEND,
-+ mask_flags: MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ name: "User FS",
-+ size: MTDPART_SIZ_FULL,
-+ offset: MTDPART_OFS_APPEND,
-+ }
-+};
-+#endif
-+
- #ifdef CONFIG_SA1100_ADSBITSY
- #define ADSBITSY_FLASH_SIZE 0x02000000
- static struct mtd_partition adsbitsy_partitions[] = {
-@@ -123,6 +149,32 @@
- };
- #endif
-
-+#ifdef CONFIG_SA1100_ADSBITSYPLUS
-+#define ADSBITSYPLUS_FLASH_SIZE 0x02000000
-+static struct mtd_partition adsbitsyplus_partitions[] = {
-+ {
-+ name: "bootROM",
-+ size: 0x80000,
-+ offset: 0,
-+ mask_flags: MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ name: "zImage",
-+ size: 0x100000,
-+ offset: MTDPART_OFS_APPEND,
-+ mask_flags: MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ name: "ramdisk.gz",
-+ size: 0x300000,
-+ offset: MTDPART_OFS_APPEND,
-+ mask_flags: MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ name: "User FS",
-+ size: MTDPART_SIZ_FULL,
-+ offset: MTDPART_OFS_APPEND,
-+ }
-+};
-+#endif
-+
- #ifdef CONFIG_SA1100_ASSABET
- /* Phase 4 Assabet has two 28F160B3 flash parts in bank 0: */
- #define ASSABET4_FLASH_SIZE 0x00400000
-@@ -438,7 +490,7 @@
- #endif
-
- #ifdef CONFIG_SA1100_GRAPHICSMASTER
--#define GRAPHICSMASTER_FLASH_SIZE 0x01000000
-+#define GRAPHICSMASTER_FLASH_SIZE 0x02000000
- static struct mtd_partition graphicsmaster_partitions[] = {
- {
- name: "zImage",
-@@ -507,6 +559,38 @@
- }
- #endif
-
-+#ifdef CONFIG_SA1100_HACKKIT
-+#define HACKKIT_FLASH_SIZE 0x01000000
-+static struct mtd_partition hackkit_partitions[] = {
-+ {
-+ name: "BLOB",
-+ size: 0x00040000,
-+ offset: 0x00000000,
-+ mask_flags: MTD_WRITEABLE, /* force read-only */
-+ }, {
-+ name: "config",
-+ size: 0x00040000,
-+ offset: MTDPART_OFS_APPEND,
-+ }, {
-+ name: "kernel",
-+ size: 0x00100000,
-+ offset: MTDPART_OFS_APPEND,
-+ }, {
-+ name: "initrd",
-+ size: 0x00180000,
-+ offset: MTDPART_OFS_APPEND,
-+ }, {
-+ name: "rootfs",
-+ size: 0x700000,
-+ offset: MTDPART_OFS_APPEND,
-+ }, {
-+ name: "data",
-+ size: MTDPART_SIZ_FULL,
-+ offset: MTDPART_OFS_APPEND,
-+ }
-+};
-+#endif
-+
- #ifdef CONFIG_SA1100_HUW_WEBPANEL
- #define HUW_WEBPANEL_FLASH_SIZE 0x01000000
- static struct mtd_partition huw_webpanel_partitions[] = {
-@@ -555,12 +639,12 @@
- offset: 0x00540000,
- }, {
- name: "JORNADA720 usr local",
-- size: 0 /* will expand to the end of the flash */
-+ size: 0, /* will expand to the end of the flash */
- offset: 0x00d00000,
- }
- };
-
--static void jornada720_set_vpp(int vpp)
-+static void jornada720_set_vpp(struct map_info *map, int vpp)
- {
- if (vpp)
- PPSR |= 0x80;
-@@ -571,6 +655,27 @@
-
- #endif
-
-+#ifdef CONFIG_SA1100_NANOENGINE
-+/* nanoEngine has one 28F320B3B Flash part in bank 0: */
-+#define NANOENGINE_FLASH_SIZE 0x00400000
-+static struct mtd_partition nanoengine_partitions[] = {
-+ {
-+ name: "nanoEngine boot firmware and parameter table",
-+ size: 0x00010000, /* 32K */
-+ offset: 0x00000000,
-+ mask_flags: MTD_WRITEABLE, /* force read-only */
-+ },{
-+ name: "kernel/initrd reserved",
-+ size: 0x002f0000,
-+ offset: 0x00010000,
-+ },{
-+ name: "experimental filesystem allocation",
-+ size: 0x00100000,
-+ offset: 0x00300000,
-+ }
-+};
-+#endif
-+
- #ifdef CONFIG_SA1100_PANGOLIN
- #define PANGOLIN_FLASH_SIZE 0x04000000
- static struct mtd_partition pangolin_partitions[] = {
-@@ -699,6 +804,32 @@
- };
- #endif /* CONFIG_SA1100_SIMPAD */
-
-+#ifdef CONFIG_SA1100_SIMPUTER
-+#define SIMPUTER_FLASH_SIZE 0x02000000
-+static struct mtd_partition simputer_partitions[] = {
-+ {
-+ name: "blob+logo",
-+ offset: 0,
-+ size: 0x00040000
-+ },
-+ {
-+ name: "kernel",
-+ offset: MTDPART_OFS_APPEND,
-+ size: 0x000C0000
-+ },
-+ {
-+ name: "/(cramfs)",
-+ offset: MTDPART_OFS_APPEND,
-+ size: 0x00200000
-+ },
-+ {
-+ name: "/usr/local(jffs2)",
-+ offset: MTDPART_OFS_APPEND,
-+ size: MTDPART_SIZ_FULL /* expand till the end */
-+ }
-+};
-+#endif
-+
- #ifdef CONFIG_SA1100_STORK
- #define STORK_FLASH_SIZE 0x02000000
- static struct mtd_partition stork_partitions[] = {
-@@ -766,7 +897,7 @@
- #endif
-
- extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts);
--extern int parse_bootldr_partitions(struct mtd_info *master, struct mtd_partition **pparts);
-+extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, char *);
-
- static struct mtd_partition *parsed_parts;
- static struct mtd_info *mymtd;
-@@ -787,6 +918,14 @@
- */
- part_type = "static";
-
-+#ifdef CONFIG_SA1100_ADSAGC
-+ if (machine_is_adsagc()) {
-+ parts = adsagc_partitions;
-+ nb_parts = ARRAY_SIZE(adsagc_partitions);
-+ sa1100_map.size = ADSAGC_FLASH_SIZE;
-+ sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2 : 4;
-+ }
-+#endif
- #ifdef CONFIG_SA1100_ADSBITSY
- if (machine_is_adsbitsy()) {
- parts = adsbitsy_partitions;
-@@ -795,6 +934,14 @@
- sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2 : 4;
- }
- #endif
-+#ifdef CONFIG_SA1100_ADSBITSYPLUS
-+ if (machine_is_adsbitsyplus()) {
-+ parts = adsbitsyplus_partitions;
-+ nb_parts = ARRAY_SIZE(adsbitsyplus_partitions);
-+ sa1100_map.size = ADSBITSYPLUS_FLASH_SIZE;
-+ sa1100_map.buswidth = (MSC1 & MSC_RBW) ? 2 : 4;
-+ }
-+#endif
- #ifdef CONFIG_SA1100_ASSABET
- if (machine_is_assabet()) {
- parts = assabet_partitions;
-@@ -869,6 +1016,13 @@
- sa1100_map.set_vpp = h3600_set_vpp;
- }
- #endif
-+#ifdef CONFIG_SA1100_HACKKIT
-+ if (machine_is_hackkit()) {
-+ parts = hackkit_partitions;
-+ nb_parts = ARRAY_SIZE(hackkit_partitions);
-+ sa1100_map.size = HACKKIT_FLASH_SIZE;
-+ }
-+#endif
- #ifdef CONFIG_SA1100_HUW_WEBPANEL
- if (machine_is_huw_webpanel()) {
- parts = huw_webpanel_partitions;
-@@ -884,6 +1038,13 @@
- sa1100_map.set_vpp = jornada720_set_vpp;
- }
- #endif
-+#ifdef CONFIG_SA1100_NANOENGINE
-+ if (machine_is_nanoengine()) {
-+ parts = nanoengine_partitions;
-+ nb_parts = ARRAY_SIZE(nanoengine_partitions);
-+ sa1100_map.size = NANOENGINE_FLASH_SIZE;
-+ }
-+#endif
- #ifdef CONFIG_SA1100_PANGOLIN
- if (machine_is_pangolin()) {
- parts = pangolin_partitions;
-@@ -919,6 +1080,13 @@
- sa1100_map.size = SIMPAD_FLASH_SIZE;
- }
- #endif
-+#ifdef CONFIG_SA1100_SIMPUTER
-+ if (machine_is_simputer()) {
-+ parts = simputer_partitions;
-+ nb_parts = ARRAY_SIZE(simputer_partitions);
-+ sa1100_map.size = SIMPUTER_FLASH_SIZE;
-+ }
-+#endif
- #ifdef CONFIG_SA1100_STORK
- if (machine_is_stork()) {
- parts = stork_partitions;
-@@ -953,7 +1121,9 @@
- * specific machine settings might have been set above.
- */
- printk(KERN_NOTICE "SA1100 flash: probing %d-bit flash bus\n", sa1100_map.buswidth*8);
-- mymtd = do_map_probe("cfi_probe", &sa1100_map);
-+ mymtd = do_map_probe("jedec_probe", &sa1100_map);
-+ if (!mymtd)
-+ mymtd = do_map_probe("cfi_probe", &sa1100_map);
- ret = -ENXIO;
- if (!mymtd)
- goto out_err;
---- linux-2.4.25/drivers/net/Config.in~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/net/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -30,9 +30,15 @@
- if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
- source drivers/acorn/net/Config.in
- fi
-+ if [ "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
-+ tristate ' AT91RM9200 Ethernet support' CONFIG_AT91_ETHER
-+ if [ "$CONFIG_AT91_ETHER" = "y" -o "$CONFIG_AT91_ETHER" = "m" ]; then
-+ bool ' RMII interface? ' CONFIG_AT91_ETHER_RMII
-+ fi
-+ fi
- fi
- if [ "$CONFIG_ARCH_CAMELOT" = "y" ]; then
-- tristate ' Altera Ether00 support' CONFIG_ETHER00
-+ tristate ' Altera Ether00 support' CONFIG_ETHER00
- fi
- if [ "$CONFIG_PPC" = "y" ]; then
- dep_tristate ' MACE (Power Mac ethernet) support' CONFIG_MACE $CONFIG_ALL_PPC
---- linux-2.4.25/drivers/net/Makefile~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/net/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -243,6 +243,7 @@
- # non-drivers/net drivers who want mii lib
- obj-$(CONFIG_PCMCIA_SMC91C92) += mii.o
- obj-$(CONFIG_USB_USBNET) += mii.o
-+obj-$(CONFIG_AT91_ETHER) += mii.o
-
- ifeq ($(CONFIG_ARCH_ACORN),y)
- mod-subdirs += ../acorn/net
-@@ -267,4 +268,3 @@
-
- rcpci.o: $(rcpci-objs)
- $(LD) -r -o $@ $(rcpci-objs)
--
---- linux-2.4.25/drivers/net/am79c961a.c~2.4.25-vrs2.patch 2003-06-13 16:51:34.000000000 +0200
-+++ linux-2.4.25/drivers/net/am79c961a.c 2004-03-31 17:15:09.000000000 +0200
-@@ -54,25 +54,36 @@
- #ifdef __arm__
- static void write_rreg(u_long base, u_int reg, u_int val)
- {
-- __asm__("str%?h %1, [%2] @ NET_RAP
-- str%?h %0, [%2, #-4] @ NET_RDP
-- " : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
-+ __asm__("str%?h %1, [%2] @ NET_RAP\n\t"
-+ "str%?h %0, [%2, #-4] @ NET_RDP"
-+ : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
- }
-
- static inline unsigned short read_rreg(u_long base_addr, u_int reg)
- {
- unsigned short v;
-- __asm__("str%?h %1, [%2] @ NET_RAP
-- ldr%?h %0, [%2, #-4] @ NET_RDP
-- " : "=r" (v): "r" (reg), "r" (ISAIO_BASE + 0x0464));
-+ __asm__("str%?h %1, [%2] @ NET_RAP\n\t"
-+ "ldr%?h %0, [%2, #-4] @ NET_RDP"
-+ : "=r" (v): "r" (reg), "r" (ISAIO_BASE + 0x0464));
- return v;
- }
-
- static inline void write_ireg(u_long base, u_int reg, u_int val)
- {
-- __asm__("str%?h %1, [%2] @ NET_RAP
-- str%?h %0, [%2, #8] @ NET_IDP
-- " : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
-+ __asm__("str%?h %1, [%2] @ NET_RAP\n\t"
-+ "str%?h %0, [%2, #8] @ NET_IDP"
-+ : : "r" (val), "r" (reg), "r" (ISAIO_BASE + 0x0464));
-+}
-+
-+static inline unsigned short read_ireg(u_long base_addr, u_int reg)
-+{
-+ u_short v;
-+ __asm__(
-+ "str%?h %1, [%2] @ NAT_RAP\n\t"
-+ "str%?h %0, [%2, #8] @ NET_IDP\n\t"
-+ : "=r" (v)
-+ : "r" (reg), "r" (ISAIO_BASE + 0x0464));
-+ return v;
- }
-
- #define am_writeword(dev,off,val) __raw_writew(val, ISAMEM_BASE + ((off) << 1))
-@@ -91,16 +102,16 @@
- }
- while (length > 8) {
- unsigned int tmp, tmp2;
-- __asm__ __volatile__("
-- ldm%?ia %1!, {%2, %3}
-- str%?h %2, [%0], #4
-- mov%? %2, %2, lsr #16
-- str%?h %2, [%0], #4
-- str%?h %3, [%0], #4
-- mov%? %3, %3, lsr #16
-- str%?h %3, [%0], #4
-- " : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2)
-- : "0" (offset), "1" (buf));
-+ __asm__ __volatile__(
-+ "ldm%?ia %1!, {%2, %3}\n\t"
-+ "str%?h %2, [%0], #4\n\t"
-+ "mov%? %2, %2, lsr #16\n\t"
-+ "str%?h %2, [%0], #4\n\t"
-+ "str%?h %3, [%0], #4\n\t"
-+ "mov%? %3, %3, lsr #16\n\t"
-+ "str%?h %3, [%0], #4"
-+ : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2)
-+ : "0" (offset), "1" (buf));
- length -= 8;
- }
- while (length > 0) {
-@@ -118,36 +129,36 @@
- length = (length + 1) & ~1;
- if ((int)buf & 2) {
- unsigned int tmp;
-- __asm__ __volatile__("
-- ldr%?h %2, [%0], #4
-- str%?b %2, [%1], #1
-- mov%? %2, %2, lsr #8
-- str%?b %2, [%1], #1
-- " : "=&r" (offset), "=&r" (buf), "=r" (tmp): "0" (offset), "1" (buf));
-+ __asm__ __volatile__(
-+ "ldr%?h %2, [%0], #4\n\t"
-+ "str%?b %2, [%1], #1\n\t"
-+ "mov%? %2, %2, lsr #8\n\t"
-+ "str%?b %2, [%1], #1"
-+ : "=&r" (offset), "=&r" (buf), "=r" (tmp): "0" (offset), "1" (buf));
- length -= 2;
- }
- while (length > 8) {
- unsigned int tmp, tmp2, tmp3;
-- __asm__ __volatile__("
-- ldr%?h %2, [%0], #4
-- ldr%?h %3, [%0], #4
-- orr%? %2, %2, %3, lsl #16
-- ldr%?h %3, [%0], #4
-- ldr%?h %4, [%0], #4
-- orr%? %3, %3, %4, lsl #16
-- stm%?ia %1!, {%2, %3}
-- " : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2), "=r" (tmp3)
-- : "0" (offset), "1" (buf));
-+ __asm__ __volatile__(
-+ "ldr%?h %2, [%0], #4\n\t"
-+ "ldr%?h %3, [%0], #4\n\t"
-+ "orr%? %2, %2, %3, lsl #16\n\t"
-+ "ldr%?h %3, [%0], #4\n\t"
-+ "ldr%?h %4, [%0], #4\n\t"
-+ "orr%? %3, %3, %4, lsl #16\n\t"
-+ "stm%?ia %1!, {%2, %3}"
-+ : "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2), "=r" (tmp3)
-+ : "0" (offset), "1" (buf));
- length -= 8;
- }
- while (length > 0) {
- unsigned int tmp;
-- __asm__ __volatile__("
-- ldr%?h %2, [%0], #4
-- str%?b %2, [%1], #1
-- mov%? %2, %2, lsr #8
-- str%?b %2, [%1], #1
-- " : "=&r" (offset), "=&r" (buf), "=r" (tmp) : "0" (offset), "1" (buf));
-+ __asm__ __volatile__(
-+ "ldr%?h %2, [%0], #4\n\t"
-+ "str%?b %2, [%1], #1\n\t"
-+ "mov%? %2, %2, lsr #8\n\t"
-+ "str%?b %2, [%1], #1"
-+ : "=&r" (offset), "=&r" (buf), "=r" (tmp) : "0" (offset), "1" (buf));
- length -= 2;
- }
- }
-@@ -254,9 +265,27 @@
- write_rreg (dev->base_addr, BASERXH, 0);
- write_rreg (dev->base_addr, CSR0, CSR0_STOP);
- write_rreg (dev->base_addr, CSR3, CSR3_IDONM|CSR3_BABLM|CSR3_DXSUFLO);
-+ write_rreg (dev->base_addr, CSR4, CSR4_APAD_XMIT|CSR4_MFCOM|CSR4_RCVCCOM|CSR4_TXSTRTM|CSR4_JABM);
- write_rreg (dev->base_addr, CSR0, CSR0_IENA|CSR0_STRT);
- }
-
-+static void am79c961_timer(unsigned long data)
-+{
-+ struct net_device *dev = (struct net_device *)data;
-+ struct dev_priv *priv = (struct dev_priv *)dev->priv;
-+ unsigned int lnkstat, carrier;
-+
-+ lnkstat = read_ireg(dev->base_addr, ISALED0) & ISALED0_LNKST;
-+ carrier = netif_carrier_ok(dev);
-+
-+ if (lnkstat && !carrier)
-+ netif_carrier_on(dev);
-+ else if (!lnkstat && carrier)
-+ netif_carrier_off(dev);
-+
-+ mod_timer(&priv->timer, jiffies + 5*HZ);
-+}
-+
- /*
- * Open/initialize the board.
- */
-@@ -274,6 +303,11 @@
-
- am79c961_init_for_open(dev);
-
-+ netif_carrier_off(dev);
-+
-+ priv->timer.expires = jiffies;
-+ add_timer(&priv->timer);
-+
- netif_start_queue(dev);
-
- return 0;
-@@ -288,7 +322,10 @@
- struct dev_priv *priv = (struct dev_priv *)dev->priv;
- unsigned long flags;
-
-+ del_timer_sync(&priv->timer);
-+
- netif_stop_queue(dev);
-+ netif_carrier_off(dev);
-
- spin_lock_irqsave(priv->chip_lock, flags);
- write_rreg (dev->base_addr, CSR0, CSR0_STOP);
-@@ -413,15 +450,6 @@
- unsigned int hdraddr, bufaddr;
- unsigned int head;
- unsigned long flags;
--
-- /* FIXME: I thought the 79c961 could do padding - RMK ??? */
-- if(length < ETH_ZLEN)
-- {
-- skb = skb_padto(skb, ETH_ZLEN);
-- if(skb == NULL)
-- return 0;
-- length = ETH_ZLEN;
-- }
-
- head = priv->txhead;
- hdraddr = priv->txhdr + (head << 3);
-@@ -431,7 +459,7 @@
- head = 0;
-
- am_writebuffer (dev, bufaddr, skb->data, length);
-- am_writeword (dev, hdraddr + 4, -length);
-+ am_writeword (dev, hdraddr + 4, -skb->len);
- am_writeword (dev, hdraddr + 2, TMD_OWN|TMD_STP|TMD_ENP);
- priv->txhead = head;
-
-@@ -448,6 +476,8 @@
- if (am_readword(dev, priv->txhdr + (priv->txhead << 3) + 2) & TMD_OWN)
- netif_stop_queue(dev);
-
-+ priv->stats.tx_bytes += skb->len;
-+
- dev_kfree_skb(skb);
-
- return 0;
-@@ -520,6 +550,7 @@
- am79c961_tx(struct net_device *dev, struct dev_priv *priv)
- {
- do {
-+ signed short len;
- u_int hdraddr;
- u_int status;
-
-@@ -555,6 +586,8 @@
- continue;
- }
- priv->stats.tx_packets ++;
-+ len = am_readword (dev, hdraddr + 4);
-+ priv->stats.tx_bytes += -len;
- } while (priv->txtail != priv->txhead);
-
- netif_wake_queue(dev);
-@@ -565,17 +598,23 @@
- {
- struct net_device *dev = (struct net_device *)dev_id;
- struct dev_priv *priv = (struct dev_priv *)dev->priv;
-- u_int status;
-+ u_int status, n = 100;
-
-- status = read_rreg(dev->base_addr, CSR0);
-- write_rreg(dev->base_addr, CSR0, status & (CSR0_TINT|CSR0_RINT|CSR0_MISS|CSR0_IENA));
-+ do {
-+ status = read_rreg(dev->base_addr, CSR0);
-+ write_rreg(dev->base_addr, CSR0, status &
-+ (CSR0_IENA|CSR0_TINT|CSR0_RINT|
-+ CSR0_MERR|CSR0_MISS|CSR0_CERR|CSR0_BABL));
-
-- if (status & CSR0_RINT)
-- am79c961_rx(dev, priv);
-- if (status & CSR0_TINT)
-- am79c961_tx(dev, priv);
-- if (status & CSR0_MISS)
-- priv->stats.rx_dropped ++;
-+ if (status & CSR0_RINT)
-+ am79c961_rx(dev, priv);
-+ if (status & CSR0_TINT)
-+ am79c961_tx(dev, priv);
-+ if (status & CSR0_MISS)
-+ priv->stats.rx_dropped ++;
-+ if (status & CSR0_CERR)
-+ mod_timer(&priv->timer, jiffies);
-+ } while (--n && status & (CSR0_RINT | CSR0_TINT));
- }
-
- /*
-@@ -587,10 +626,10 @@
- {
- struct dev_priv *priv = (struct dev_priv *)dev->priv;
-
-- spin_lock_irq(priv->chip_lock);
-+ spin_lock_irq(&priv->chip_lock);
- write_rreg (dev->base_addr, CSR0, CSR0_STOP);
- write_rreg (dev->base_addr, CSR3, CSR3_MASKALL);
-- spin_unlock_irq(priv->chip_lock);
-+ spin_unlock_irq(&priv->chip_lock);
-
- am79c961_ramtest(dev, 0x66);
- am79c961_ramtest(dev, 0x99);
-@@ -655,6 +694,11 @@
- printk (i == 5 ? "%02x\n" : "%02x:", dev->dev_addr[i]);
- }
-
-+ spin_lock_init(&priv->chip_lock);
-+ init_timer(&priv->timer);
-+ priv->timer.data = (unsigned long)dev;
-+ priv->timer.function = am79c961_timer;
-+
- if (am79c961_hw_init(dev))
- goto release;
-
---- linux-2.4.25/drivers/net/am79c961a.h~2.4.25-vrs2.patch 2000-09-19 00:15:22.000000000 +0200
-+++ linux-2.4.25/drivers/net/am79c961a.h 2004-03-31 17:15:09.000000000 +0200
-@@ -58,6 +58,18 @@
- #define CSR3_BABLM 0x4000
- #define CSR3_MASKALL 0x5F00
-
-+#define CSR4 4
-+#define CSR4_JABM 0x0001
-+#define CSR4_JAB 0x0002
-+#define CSR4_TXSTRTM 0x0004
-+#define CSR4_TXSTRT 0x0008
-+#define CSR4_RCVCCOM 0x0010
-+#define CSR4_RCVCCO 0x0020
-+#define CSR4_MFCOM 0x0100
-+#define CSR4_MFCO 0x0200
-+#define CSR4_ASTRP_RCV 0x0400
-+#define CSR4_APAD_XMIT 0x0800
-+
- #define CTRL1 5
- #define CTRL1_SPND 0x0001
-
-@@ -93,6 +105,8 @@
- #define SIZERXR 76
- #define SIZETXR 78
-
-+#define CSR_MFC 112
-+
- #define RMD_ENP 0x0100
- #define RMD_STP 0x0200
- #define RMD_CRC 0x0800
-@@ -112,6 +126,9 @@
- #define TST_UFLO 0x4000
- #define TST_BUFF 0x8000
-
-+#define ISALED0 0x0004
-+#define ISALED0_LNKST 0x8000
-+
- struct dev_priv {
- struct net_device_stats stats;
- unsigned long rxbuffer[RX_BUFFERS];
-@@ -123,6 +140,7 @@
- unsigned long rxhdr;
- unsigned long txhdr;
- spinlock_t chip_lock;
-+ struct timer_list timer;
- };
-
- extern int am79c961_probe (struct net_device *dev);
---- linux-2.4.25/drivers/net/cirrus.c~2.4.25-vrs2.patch 2003-06-13 16:51:34.000000000 +0200
-+++ linux-2.4.25/drivers/net/cirrus.c 2004-03-31 17:15:09.000000000 +0200
-@@ -75,6 +75,7 @@
- typedef struct {
- struct net_device_stats stats;
- u16 txlen;
-+ u16 txafter; /* Default is After5 (0) */
- } cirrus_t;
-
- typedef struct {
-@@ -230,13 +231,19 @@
- cirrus_t *priv = (cirrus_t *) dev->priv;
- u16 status;
-
-+ /* Tx start must be done with irq disabled
-+ * else status can be wrong */
-+ disable_irq (dev->irq);
-+
- netif_stop_queue (dev);
-
-- cirrus_write (dev,PP_TxCMD,TxStart (After5));
-+ cirrus_write (dev,PP_TxCMD,TxStart (priv->txafter));
- cirrus_write (dev,PP_TxLength,skb->len);
-
- status = cirrus_read (dev,PP_BusST);
-
-+ enable_irq (dev->irq);
-+
- if ((status & TxBidErr)) {
- printk (KERN_WARNING "%s: Invalid frame size %d!\n",dev->name,skb->len);
- priv->stats.tx_errors++;
-@@ -249,7 +256,6 @@
- printk (KERN_WARNING "%s: Transmit buffer not free!\n",dev->name);
- priv->stats.tx_errors++;
- priv->txlen = 0;
-- /* FIXME: store skb and send it in interrupt handler */
- return (1);
- }
-
-@@ -310,11 +316,18 @@
- }
- if ((RegContent (status) & TxUnderrun)) {
- priv->stats.tx_errors++;
-- priv->stats.tx_fifo_errors++;
-+ /* Shift start tx, if underruns come too often */
-+ switch (priv->stats.tx_fifo_errors++) {
-+ case 3: priv->txafter = After381; break;
-+ case 6: priv->txafter = After1021; break;
-+ case 9: priv->txafter = AfterAll; break;
-+ }
-+ }
-+ /* Wakeup only for tx events ! */
-+ if ((RegContent (status) & (TxUnderrun | Rdy4Tx))) {
-+ priv->txlen = 0;
-+ netif_wake_queue (dev);
- }
-- /* FIXME: if Rdy4Tx, transmit last sent packet (if any) */
-- priv->txlen = 0;
-- netif_wake_queue (dev);
- break;
-
- case TxCOL:
-@@ -428,7 +441,7 @@
- else
- cirrus_clear (dev,PP_RxCTL,PromiscuousA);
-
-- if ((dev->flags & IFF_ALLMULTI) && dev->mc_list)
-+ if ((dev->flags & IFF_ALLMULTI) || dev->mc_list)
- cirrus_set (dev,PP_RxCTL,MulticastA);
- else
- cirrus_clear (dev,PP_RxCTL,MulticastA);
---- linux-2.4.25/drivers/net/cs89x0.c~2.4.25-vrs2.patch 2003-08-25 13:44:42.000000000 +0200
-+++ linux-2.4.25/drivers/net/cs89x0.c 2004-03-31 17:15:09.000000000 +0200
-@@ -115,6 +115,7 @@
-
- */
-
-+#include <linux/config.h>
- #include <linux/kernel.h>
- #include <linux/sched.h>
- #include <linux/types.h>
-@@ -427,18 +428,18 @@
- /* if they give us an odd I/O address, then do ONE write to
- the address port, to get it back to address zero, where we
- expect to find the EISA signature word. An IO with a base of 0x3
-- will skip the test for the ADD_PORT. */
-+ will skip the test for the ADD_PORT. */
- if (ioaddr & 1) {
- if (net_debug > 1)
- printk(KERN_INFO "%s: odd ioaddr 0x%x\n", dev->name, ioaddr);
-- if ((ioaddr & 2) != 2)
-+ if ((ioaddr & 2) != 2)
- if ((inw((ioaddr & ~3)+ ADD_PORT) & ADD_MASK) != ADD_SIG) {
- printk(KERN_ERR "%s: bad signature 0x%x\n",
- dev->name, inw((ioaddr & ~3)+ ADD_PORT));
- retval = -ENODEV;
- goto out2;
- }
-- ioaddr &= ~3;
-+ ioaddr &= ~3;
- outw(PP_ChipID, ioaddr + ADD_PORT);
- }
- printk("PP_addr=0x%x\n", inw(ioaddr + ADD_PORT));
-@@ -446,7 +447,7 @@
- if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG) {
- printk(KERN_ERR "%s: incorrect signature 0x%x\n",
- dev->name, inw(ioaddr + DATA_PORT));
-- retval = -ENODEV;
-+ retval = -ENODEV;
- goto out2;
- }
-
-@@ -477,7 +478,7 @@
- dev->base_addr);
-
- reset_chip(dev);
--
-+
- /* Here we read the current configuration of the chip. If there
- is no Extended EEPROM then the idea is to not disturb the chip
- configuration, it should have been correctly setup by automatic
---- linux-2.4.25/drivers/net/ether00.c~2.4.25-vrs2.patch 2003-06-13 16:51:34.000000000 +0200
-+++ linux-2.4.25/drivers/net/ether00.c 2004-03-31 17:15:09.000000000 +0200
-@@ -38,6 +38,7 @@
- #include <asm/arch/ether00.h>
- #include <asm/arch/tdkphy.h>
-
-+static int ether00_get_ethernet_address(struct net_device* dev);
-
- MODULE_AUTHOR("Clive Davies");
- MODULE_DESCRIPTION("Altera Ether00 IP core driver");
-@@ -734,8 +735,11 @@
- int result,tmp;
- struct net_priv* priv;
-
-- if (!is_valid_ether_addr(dev->dev_addr))
-- return -EINVAL;
-+ if (!ether00_get_ethernet_address(dev)){
-+ printk("%s: Invalid ethernet MAC address. Please set using "
-+ "ifconfig\n", dev->name);
-+ return -EINVAL;
-+ }
-
- dev->base_addr=(unsigned int)ioremap_nocache(base,SZ_4K);
-
-@@ -906,10 +910,9 @@
- }
-
-
--static void ether00_get_ethernet_address(struct net_device* dev)
-+static int ether00_get_ethernet_address(struct net_device* dev)
- {
- struct mtd_info *mymtd=NULL;
-- int i;
- size_t retlen;
-
- /*
-@@ -926,11 +929,7 @@
- #ifdef CONFIG_ARCH_CAMELOT
- #ifdef CONFIG_MTD
- /* get the mtd_info structure for the first mtd device*/
-- for(i=0;i<MAX_MTD_DEVICES;i++){
-- mymtd=get_mtd_device(NULL,i);
-- if(!mymtd||!strcmp(mymtd->name,"EPXA10DB flash"))
-- break;
-- }
-+ mymtd=get_mtd_device(NULL,0);
-
- if(!mymtd || !mymtd->read_user_prot_reg){
- printk(KERN_WARNING "%s: Failed to read MAC address from flash\n",dev->name);
-@@ -947,9 +946,7 @@
- #endif
- #endif
-
-- if (!is_valid_ether_addr(dev->dev_addr))
-- printk("%s: Invalid ethernet MAC address. Please set using "
-- "ifconfig\n", dev->name);
-+ return (is_valid_ether_addr(dev->dev_addr));
-
- }
-
-@@ -966,8 +963,6 @@
- dev->tx_timeout=ether00_tx_timeout;
- dev->watchdog_timeo=TX_TIMEOUT;
-
-- ether00_get_ethernet_address(dev);
--
- SET_MODULE_OWNER(dev);
- return 0;
- }
---- linux-2.4.25/drivers/net/irda/Config.in~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/net/irda/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -40,7 +40,7 @@
- dep_tristate 'VIA IrCC (Experimental)' CONFIG_VIA_IRCC_FIR $CONFIG_IRDA
- fi
- if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
-- dep_tristate 'SA1100 Internal IR' CONFIG_SA1100_FIR $CONFIG_IRDA
-+ dep_tristate 'SA1100 Internal IR' CONFIG_SA1100_FIR $CONFIG_IRDA $CONFIG_EXPERIMENTAL
- fi
-
- endmenu
---- linux-2.4.25/drivers/net/irda/sa1100_ir.c~2.4.25-vrs2.patch 2002-08-03 02:39:44.000000000 +0200
-+++ linux-2.4.25/drivers/net/irda/sa1100_ir.c 2004-03-31 17:15:09.000000000 +0200
-@@ -38,11 +38,7 @@
-
- #include <asm/arch/assabet.h>
-
--#ifndef CONFIG_SA1100_H3600
--#define clr_h3600_egpio(x) do { } while (0)
--#define set_h3600_egpio(x) do { } while (0)
--#endif
--
-+/* Yopy wants fixing */
- #ifndef GPIO_IRDA_FIR
- #define GPIO_IRDA_FIR (0)
- #endif
-@@ -174,8 +170,8 @@
-
- if (machine_is_assabet())
- ASSABET_BCR_clear(ASSABET_BCR_IRDA_FSEL);
-- if (machine_is_h3600())
-- clr_h3600_egpio(EGPIO_H3600_IR_FSEL);
-+ if (machine_is_h3xxx())
-+ clr_h3600_egpio(IPAQ_EGPIO_IR_FSEL);
- if (machine_is_yopy())
- PPSR &= ~GPIO_IRDA_FIR;
-
-@@ -199,8 +195,8 @@
-
- if (machine_is_assabet())
- ASSABET_BCR_set(ASSABET_BCR_IRDA_FSEL);
-- if (machine_is_h3600())
-- set_h3600_egpio(EGPIO_H3600_IR_FSEL);
-+ if (machine_is_h3xxx())
-+ set_h3600_egpio(IPAQ_EGPIO_IR_FSEL);
- if (machine_is_yopy())
- PPSR |= GPIO_IRDA_FIR;
-
-@@ -246,10 +242,7 @@
- static inline int
- sa1100_irda_set_power_h3600(struct sa1100_irda *si, unsigned int state)
- {
-- if (state)
-- set_h3600_egpio(EGPIO_H3600_IR_ON);
-- else
-- clr_h3600_egpio(EGPIO_H3600_IR_ON);
-+ assign_h3600_egpio( IPAQ_EGPIO_IR_ON, state );
- return 0;
- }
-
-@@ -283,7 +276,7 @@
-
- if (machine_is_assabet())
- ret = sa1100_irda_set_power_assabet(si, state);
-- if (machine_is_h3600())
-+ if (machine_is_h3xxx())
- ret = sa1100_irda_set_power_h3600(si, state);
- if (machine_is_yopy())
- ret = sa1100_irda_set_power_yopy(si, state);
-@@ -727,11 +720,6 @@
- netif_wake_queue(dev);
- }
-
--/*
-- * Note that we will never build up a backlog of frames; the protocol is a
-- * half duplex protocol which basically means we transmit a frame, we
-- * receive a frame, we transmit the next frame etc.
-- */
- static int sa1100_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
- {
- struct sa1100_irda *si = dev->priv;
-@@ -758,6 +746,8 @@
- }
-
- if (!IS_FIR(si)) {
-+ netif_stop_queue(dev);
-+
- si->tx_buff.data = si->tx_buff.head;
- si->tx_buff.len = async_wrap_skb(skb, si->tx_buff.data,
- si->tx_buff.truesize);
---- linux-2.4.25/drivers/net/irda/w83977af_ir.c~2.4.25-vrs2.patch 2002-11-29 00:53:13.000000000 +0100
-+++ linux-2.4.25/drivers/net/irda/w83977af_ir.c 2004-03-31 17:15:09.000000000 +0200
-@@ -205,7 +205,7 @@
-
- /* FIXME: The HP HDLS-1100 does not support 1152000! */
- self->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
-- IR_115200|IR_576000|IR_1152000|(IR_4000000 << 8);
-+ IR_115200/*|IR_576000|IR_1152000|(IR_4000000 << 8)*/;
-
- /* The HP HDLS-1100 needs 1 ms according to the specs */
- self->qos.min_turn_time.bits = qos_mtt_bits;
-@@ -1341,7 +1341,7 @@
- case SIOCSBANDWIDTH: /* Set bandwidth */
- if (!capable(CAP_NET_ADMIN)) {
- ret = -EPERM;
-- goto out;
-+ break;
- }
- w83977af_change_speed(self, irq->ifr_baudrate);
- break;
---- linux-2.4.25/drivers/net/smc9194.c~2.4.25-vrs2.patch 2003-06-13 16:51:35.000000000 +0200
-+++ linux-2.4.25/drivers/net/smc9194.c 2004-03-31 17:15:09.000000000 +0200
-@@ -12,8 +12,8 @@
- . AUI/TP selection ( mine has 10Base2/10BaseT select )
- .
- . Arguments:
-- . io = for the base address
-- . irq = for the IRQ
-+ . io = for the base address
-+ . irq = for the IRQ
- . ifport = 0 for autodetect, 1 for TP, 2 for AUI ( or 10base2 )
- .
- . author:
-@@ -51,12 +51,21 @@
- . allocation
- . 08/20/00 Arnaldo Melo fix kfree(skb) in smc_hardware_send_packet
- . 12/15/00 Christian Jullien fix "Warning: kfree_skb on hard IRQ"
-+ . 06/23/01 Russell King Separate out IO functions for different bus
-+ . types.
-+ . Use dev->name instead of CARDNAME for printk
-+ . Add ethtool support, full duplex support
-+ . Add LAN91C96 support.
- . 11/08/01 Matt Domsch Use common crc32 function
- ----------------------------------------------------------------------------*/
-
-+#define DRV_NAME "smc9194"
-+#define DRV_VERSION "0.15"
-+
- static const char version[] =
-- "smc9194.c:v0.14 12/15/00 by Erik Stahlman (erik@vt.edu)\n";
-+ DRV_NAME ".c:v" DRV_VERSION " 12/15/00 by Erik Stahlman (erik@vt.edu)\n";
-
-+#include <linux/config.h>
- #include <linux/module.h>
- #include <linux/version.h>
- #include <linux/kernel.h>
-@@ -69,16 +78,26 @@
- #include <linux/in.h>
- #include <linux/slab.h>
- #include <linux/string.h>
-+#include <linux/delay.h>
- #include <linux/init.h>
- #include <linux/crc32.h>
--#include <asm/bitops.h>
--#include <asm/io.h>
- #include <linux/errno.h>
-+#include <linux/ethtool.h>
-
- #include <linux/netdevice.h>
- #include <linux/etherdevice.h>
- #include <linux/skbuff.h>
-
-+#include <asm/bitops.h>
-+#include <asm/irq.h>
-+#include <asm/io.h>
-+#include <asm/uaccess.h>
-+
-+#ifdef CONFIG_ARCH_SA1100
-+#include <asm/hardware.h>
-+#include <asm/arch/assabet.h>
-+#endif
-+
- #include "smc9194.h"
- /*------------------------------------------------------------------------
- .
-@@ -152,29 +171,27 @@
- -------------------------------------------------------------------------*/
- #define CARDNAME "SMC9194"
-
-+static const char *chip_ids[15] = {
-+ NULL,
-+ NULL,
-+ NULL,
-+ "SMC91C90/91C92", /* 3 */
-+ "SMC91C94/91C96", /* 4 */
-+ "SMC91C95", /* 5 */
-+ NULL,
-+ "SMC91C100", /* 7 */
-+ "SMC91C100FD", /* 8 */
-+ NULL,
-+ NULL,
-+ NULL,
-+ NULL,
-+ NULL,
-+ NULL
-+};
-
--/* store this information for the driver.. */
--struct smc_local {
-- /*
-- these are things that the kernel wants me to keep, so users
-- can find out semi-useless statistics of how well the card is
-- performing
-- */
-- struct net_device_stats stats;
--
-- /*
-- If I have to wait until memory is available to send
-- a packet, I will store the skbuff here, until I get the
-- desired memory. Then, I'll send it out and free it.
-- */
-- struct sk_buff * saved_skb;
--
-- /*
-- . This keeps track of how many packets that I have
-- . sent out. When an TX_EMPTY interrupt comes, I know
-- . that all of these have been sent.
-- */
-- int packets_waiting;
-+static const char * interfaces[2] = {
-+ "TP",
-+ "AUI"
- };
-
-
-@@ -202,6 +219,11 @@
- static int smc_open(struct net_device *dev);
-
- /*
-+ . This handles the ethtool interface
-+*/
-+static int smc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-+
-+/*
- . Our watchdog timed out. Called by the networking layer
- */
- static void smc_timeout(struct net_device *dev);
-@@ -217,11 +239,11 @@
- . This routine allows the proc file system to query the driver's
- . statistics.
- */
--static struct net_device_stats * smc_query_statistics( struct net_device *dev);
-+static struct net_device_stats * smc_query_statistics(struct net_device *dev);
-
- /*
-- . Finally, a call to set promiscuous mode ( for TCPDUMP and related
-- . programs ) and multicast modes.
-+ . Finally, a call to set promiscuous mode (for TCPDUMP and related
-+ . programs) and multicast modes.
- */
- static void smc_set_multicast_list(struct net_device *dev);
-
-@@ -240,12 +262,12 @@
- . This is a separate procedure to handle the receipt of a packet, to
- . leave the interrupt code looking slightly cleaner
- */
--static inline void smc_rcv( struct net_device *dev );
-+static inline void smc_rcv(struct net_device *dev);
- /*
- . This handles a TX interrupt, which is only called when an error
- . relating to a packet is sent.
- */
--static inline void smc_tx( struct net_device * dev );
-+static inline void smc_tx(struct net_device * dev);
-
- /*
- ------------------------------------------------------------
-@@ -261,39 +283,287 @@
- */
- static int smc_probe(struct net_device *dev, int ioaddr);
-
--/*
-- . A rather simple routine to print out a packet for debugging purposes.
--*/
--#if SMC_DEBUG > 2
--static void print_packet( byte *, int );
--#endif
--
--#define tx_done(dev) 1
--
- /* this is called to actually send the packet to the chip */
--static void smc_hardware_send_packet( struct net_device * dev );
-+static void smc_hardware_send_packet(struct net_device * dev);
-
- /* Since I am not sure if I will have enough room in the chip's ram
- . to store the packet, I call this routine, which either sends it
- . now, or generates an interrupt when the card is ready for the
- . packet */
--static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device *dev );
-+static int smc_wait_to_send_packet(struct sk_buff * skb, struct net_device *dev);
-
- /* this does a soft reset on the device */
--static void smc_reset( int ioaddr );
-+static void smc_reset(struct net_device *dev);
-
- /* Enable Interrupts, Receive, and Transmit */
--static void smc_enable( int ioaddr );
-+static void smc_enable(struct net_device *dev);
-
- /* this puts the device in an inactive state */
--static void smc_shutdown( int ioaddr );
-+static void smc_shutdown(struct net_device *dev);
-
- /* This routine will find the IRQ of the driver if one is not
- . specified in the input to the device. */
--static int smc_findirq( int ioaddr );
-+static int smc_findirq(struct net_device *dev);
-
-+#ifndef CONFIG_ASSABET_NEPONSET
- /*
-- . Function: smc_reset( int ioaddr )
-+ * These functions allow us to handle IO addressing as we wish - this
-+ * ethernet controller can be connected to a variety of busses. Some
-+ * busses do not support 16 bit or 32 bit transfers. --rmk
-+ */
-+static inline u8 smc_inb(u_int base, u_int reg)
-+{
-+ return inb(base + reg);
-+}
-+
-+static inline u16 smc_inw(u_int base, u_int reg)
-+{
-+ return inw(base + reg);
-+}
-+
-+static inline void smc_ins(u_int base, u_int reg, u8 *data, u_int len)
-+{
-+ u_int port = base + reg;
-+#ifdef USE_32_BIT
-+ /* QUESTION: Like in the TX routine, do I want
-+ to send the DWORDs or the bytes first, or some
-+ mixture. A mixture might improve already slow PIO
-+ performance */
-+ PRINTK3((" Reading %d dwords (and %d bytes) \n",
-+ len >> 2, len & 3));
-+ insl(port, data, len >> 2);
-+ /* read the left over bytes */
-+ insb(port, data + (len & ~3), len & 3);
-+#else
-+ PRINTK3((" Reading %d words and %d byte(s) \n",
-+ len >> 1, len & 1));
-+ insw(port, data, len >> 1);
-+ if (len & 1) {
-+ data += len & ~1;
-+ *data = inb(port);
-+ }
-+#endif
-+}
-+
-+static inline void smc_outb(u8 val, u_int base, u_int reg)
-+{
-+ outb(val, base + reg);
-+}
-+
-+static inline void smc_outw(u16 val, u_int base, u_int reg)
-+{
-+ outw(val, base + reg);
-+}
-+
-+static inline void smc_outl(u32 val, u_int base, u_int reg)
-+{
-+ u_int port = base + reg;
-+#ifdef USE_32_BIT
-+ outl(val, port);
-+#else
-+ outw(val, port);
-+ outw(val >> 16, port);
-+#endif
-+}
-+
-+static inline void smc_outs(u_int base, u_int reg, u8 *data, u_int len)
-+{
-+ u_int port = base + reg;
-+#ifdef USE_32_BIT
-+ if (len & 2) {
-+ outsl(port, data, len >> 2);
-+ outw(*((word *)(data + (len & ~3))), port);
-+ }
-+ else
-+ outsl(port, data, len >> 2);
-+#else
-+ outsw(port, data, len >> 1);
-+#endif
-+}
-+
-+
-+/*-------------------------------------------------------------------------
-+ . I define some macros to make it easier to do somewhat common
-+ . or slightly complicated, repeated tasks.
-+ --------------------------------------------------------------------------*/
-+
-+/* select a register bank, 0 to 3 */
-+
-+#define SMC_SELECT_BANK(x) \
-+ { \
-+ smc_outw(x, ioaddr, BANK_SELECT); \
-+ }
-+
-+/* define a small delay for the reset */
-+#define SMC_DELAY() \
-+ { \
-+ smc_inw(ioaddr, RCR); \
-+ smc_inw(ioaddr, RCR); \
-+ smc_inw(ioaddr, RCR); \
-+ }
-+
-+/* this enables an interrupt in the interrupt mask register */
-+#define SMC_ENABLE_INT(x) \
-+ { \
-+ byte mask; \
-+ mask = smc_inb(ioaddr, INT_MASK); \
-+ mask |= (x); \
-+ smc_outb(mask, ioaddr, INT_MASK); \
-+ }
-+
-+/* this sets the absolutel interrupt mask */
-+#define SMC_SET_INT(x) \
-+ { \
-+ smc_outw((x), INT_MASK); \
-+ }
-+
-+#else
-+
-+#undef SMC_IO_EXTENT
-+#define SMC_IO_EXTENT (16 << 2)
-+
-+/*
-+ * These functions allow us to handle IO addressing as we wish - this
-+ * ethernet controller can be connected to a variety of busses. Some
-+ * busses do not support 16 bit or 32 bit transfers. --rmk
-+ */
-+static inline u8 smc_inb(u_int base, u_int reg)
-+{
-+ u_int port = base + reg * 4;
-+
-+ return readb(port);
-+}
-+
-+static inline u16 smc_inw(u_int base, u_int reg)
-+{
-+ u_int port = base + reg * 4;
-+
-+ return readb(port) | readb(port + 4) << 8;
-+}
-+
-+static inline void smc_ins(u_int base, u_int reg, u8 *data, u_int len)
-+{
-+ u_int port = base + reg * 4;
-+
-+ insb(port, data, len);
-+}
-+
-+static inline void smc_outb(u8 val, u_int base, u_int reg)
-+{
-+ u_int port = base + reg * 4;
-+
-+ writeb(val, port);
-+}
-+
-+static inline void smc_outw(u16 val, u_int base, u_int reg)
-+{
-+ u_int port = base + reg * 4;
-+
-+ writeb(val, port);
-+ writeb(val >> 8, port + 4);
-+}
-+
-+static inline void smc_outl(u32 val, u_int base, u_int reg)
-+{
-+ u_int port = base + reg * 4;
-+
-+ writeb(val, port);
-+ writeb(val >> 8, port + 4);
-+ writeb(val >> 16, port + 8);
-+ writeb(val >> 24, port + 12);
-+}
-+
-+static inline void smc_outs(u_int base, u_int reg, u8 *data, u_int len)
-+{
-+ u_int port = base + reg * 4;
-+
-+ outsb(port, data, len & ~1);
-+}
-+
-+/*-------------------------------------------------------------------------
-+ . I define some macros to make it easier to do somewhat common
-+ . or slightly complicated, repeated tasks.
-+ --------------------------------------------------------------------------*/
-+
-+/* select a register bank, 0 to 3 */
-+
-+#define SMC_SELECT_BANK(x) \
-+ { \
-+ smc_outb(x, ioaddr, BANK_SELECT); \
-+ }
-+
-+/* define a small delay for the reset */
-+#define SMC_DELAY() \
-+ { \
-+ smc_inb(ioaddr, RCR); \
-+ smc_inb(ioaddr, RCR); \
-+ smc_inb(ioaddr, RCR); \
-+ }
-+
-+/* this enables an interrupt in the interrupt mask register */
-+#define SMC_ENABLE_INT(x) \
-+ { \
-+ byte mask; \
-+ mask = smc_inb(ioaddr, INT_MASK); \
-+ mask |= (x); \
-+ smc_outb(mask, ioaddr, INT_MASK); \
-+ }
-+
-+/* this sets the absolutel interrupt mask */
-+#define SMC_SET_INT(x) \
-+ { \
-+ smc_outb((x), ioaddr, INT_MASK); \
-+ }
-+
-+#endif
-+
-+/*
-+ . A rather simple routine to print out a packet for debugging purposes.
-+*/
-+#if SMC_DEBUG > 2
-+static void print_packet(byte * buf, int length)
-+{
-+ int i;
-+ int remainder;
-+ int lines;
-+
-+ printk("Packet of length %d \n", length);
-+ lines = length / 16;
-+ remainder = length % 16;
-+
-+ for (i = 0; i < lines ; i ++) {
-+ int cur;
-+
-+ for (cur = 0; cur < 8; cur ++) {
-+ byte a, b;
-+
-+ a = *(buf ++);
-+ b = *(buf ++);
-+ printk("%02x%02x ", a, b);
-+ }
-+ printk("\n");
-+ }
-+ for (i = 0; i < remainder/2 ; i++) {
-+ byte a, b;
-+
-+ a = *(buf ++);
-+ b = *(buf ++);
-+ printk("%02x%02x ", a, b);
-+ }
-+ if (remainder & 1) {
-+ byte a;
-+
-+ a = *buf++;
-+ printk("%02x", a);
-+ }
-+ printk("\n");
-+}
-+#else
-+#define print_packet(buf,len) do { } while (0)
-+#endif
-+
-+/*
-+ . Function: smc_reset(struct net_device *dev)
- . Purpose:
- . This sets the SMC91xx chip to its normal state, hopefully from whatever
- . mess that any other DOS driver has put it in.
-@@ -309,36 +579,37 @@
- . 5. clear all interrupts
- .
- */
--static void smc_reset( int ioaddr )
-+static void smc_reset(struct net_device *dev)
- {
-+ u_int ioaddr = dev->base_addr;
-+
- /* This resets the registers mostly to defaults, but doesn't
- affect EEPROM. That seems unnecessary */
-- SMC_SELECT_BANK( 0 );
-- outw( RCR_SOFTRESET, ioaddr + RCR );
-+ SMC_SELECT_BANK(0);
-+ smc_outw(RCR_SOFTRESET, ioaddr, RCR);
-
- /* this should pause enough for the chip to be happy */
-- SMC_DELAY( );
-+ SMC_DELAY();
-
- /* Set the transmit and receive configuration registers to
- default values */
-- outw( RCR_CLEAR, ioaddr + RCR );
-- outw( TCR_CLEAR, ioaddr + TCR );
-+ smc_outw(RCR_CLEAR, ioaddr, RCR);
-+ smc_outw(TCR_CLEAR, ioaddr, TCR);
-
- /* set the control register to automatically
- release successfully transmitted packets, to make the best
- use out of our limited memory */
-- SMC_SELECT_BANK( 1 );
-- outw( inw( ioaddr + CONTROL ) | CTL_AUTO_RELEASE , ioaddr + CONTROL );
-+ SMC_SELECT_BANK(1);
-+ smc_outw(smc_inw(ioaddr, CONTROL) | CTL_AUTO_RELEASE, ioaddr, CONTROL);
-
- /* Reset the MMU */
-- SMC_SELECT_BANK( 2 );
-- outw( MC_RESET, ioaddr + MMU_CMD );
-+ SMC_SELECT_BANK(2);
-+ smc_outw(MC_RESET, ioaddr, MMU_CMD);
-
- /* Note: It doesn't seem that waiting for the MMU busy is needed here,
- but this is a place where future chipsets _COULD_ break. Be wary
- of issuing another MMU command right after this */
--
-- outb( 0, ioaddr + INT_MASK );
-+ SMC_SET_INT(0);
- }
-
- /*
-@@ -349,20 +620,21 @@
- . 2. Enable the receiver
- . 3. Enable interrupts
- */
--static void smc_enable( int ioaddr )
-+static void smc_enable(struct net_device *dev)
- {
-- SMC_SELECT_BANK( 0 );
-+ u_int ioaddr = dev->base_addr;
-+ SMC_SELECT_BANK(0);
- /* see the header file for options in TCR/RCR NORMAL*/
-- outw( TCR_NORMAL, ioaddr + TCR );
-- outw( RCR_NORMAL, ioaddr + RCR );
-+ smc_outw(TCR_NORMAL, ioaddr, TCR);
-+ smc_outw(RCR_NORMAL, ioaddr, RCR);
-
- /* now, enable interrupts */
-- SMC_SELECT_BANK( 2 );
-- outb( SMC_INTERRUPT_MASK, ioaddr + INT_MASK );
-+ SMC_SELECT_BANK(2);
-+ SMC_SET_INT(SMC_INTERRUPT_MASK);
- }
-
- /*
-- . Function: smc_shutdown
-+ . Function: smc_shutdown(struct net_device *dev)
- . Purpose: closes down the SMC91xxx chip.
- . Method:
- . 1. zero the interrupt mask
-@@ -375,26 +647,28 @@
- . the manual says that it will wake up in response to any I/O requests
- . in the register space. Empirical results do not show this working.
- */
--static void smc_shutdown( int ioaddr )
-+static void smc_shutdown(struct net_device *dev)
- {
-+ u_int ioaddr = dev->base_addr;
-+
- /* no more interrupts for me */
-- SMC_SELECT_BANK( 2 );
-- outb( 0, ioaddr + INT_MASK );
-+ SMC_SELECT_BANK(2);
-+ SMC_SET_INT(0);
-
- /* and tell the card to stay away from that nasty outside world */
-- SMC_SELECT_BANK( 0 );
-- outb( RCR_CLEAR, ioaddr + RCR );
-- outb( TCR_CLEAR, ioaddr + TCR );
-+ SMC_SELECT_BANK(0);
-+ smc_outb(RCR_CLEAR, ioaddr, RCR);
-+ smc_outb(TCR_CLEAR, ioaddr, TCR);
- #if 0
- /* finally, shut the chip down */
-- SMC_SELECT_BANK( 1 );
-- outw( inw( ioaddr + CONTROL ), CTL_POWERDOWN, ioaddr + CONTROL );
-+ SMC_SELECT_BANK(1);
-+ smc_outw(smc_inw(ioaddr, CONTROL), CTL_POWERDOWN, ioaddr, CONTROL);
- #endif
- }
-
-
- /*
-- . Function: smc_setmulticast( int ioaddr, int count, dev_mc_list * adds )
-+ . Function: smc_setmulticast(int ioaddr, int count, dev_mc_list * adds)
- . Purpose:
- . This sets the internal hardware table to filter out unwanted multicast
- . packets before they take up memory.
-@@ -411,26 +685,28 @@
- */
-
-
--static void smc_setmulticast( int ioaddr, int count, struct dev_mc_list * addrs ) {
-+static void smc_setmulticast(struct net_device *dev, int count, struct dev_mc_list * addrs)
-+{
-+ u_int ioaddr = dev->base_addr;
- int i;
-- unsigned char multicast_table[ 8 ];
-+ unsigned char multicast_table[8];
- struct dev_mc_list * cur_addr;
- /* table for flipping the order of 3 bits */
- unsigned char invert3[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
-
- /* start with a table of all zeros: reject all */
-- memset( multicast_table, 0, sizeof( multicast_table ) );
-+ memset(multicast_table, 0, sizeof(multicast_table));
-
- cur_addr = addrs;
-- for ( i = 0; i < count ; i ++, cur_addr = cur_addr->next ) {
-+ for (i = 0; i < count ; i ++, cur_addr = cur_addr->next) {
- int position;
-
- /* do we have a pointer here? */
-- if ( !cur_addr )
-+ if (!cur_addr)
- break;
- /* make sure this is a multicast address - shouldn't this
- be a given if we have it here ? */
-- if ( !( *cur_addr->dmi_addr & 1 ) )
-+ if (!(*cur_addr->dmi_addr & 1))
- continue;
-
- /* only use the low order bits */
-@@ -442,15 +718,15 @@
-
- }
- /* now, the table can be loaded into the chipset */
-- SMC_SELECT_BANK( 3 );
-+ SMC_SELECT_BANK(3);
-
-- for ( i = 0; i < 8 ; i++ ) {
-- outb( multicast_table[i], ioaddr + MULTICAST1 + i );
-+ for (i = 0; i < 8 ; i++) {
-+ smc_outb(multicast_table[i], ioaddr, MULTICAST1 + i);
- }
- }
-
- /*
-- . Function: smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * )
-+ . Function: smc_wait_to_send_packet(struct sk_buff * skb, struct net_device *)
- . Purpose:
- . Attempt to allocate memory for a packet, if chip-memory is not
- . available, then tell the card to generate an interrupt when it
-@@ -465,10 +741,10 @@
- . o (NO): Enable interrupts and let the interrupt handler deal with it.
- . o (YES):Send it now.
- */
--static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * dev )
-+static int smc_wait_to_send_packet(struct sk_buff * skb, struct net_device * dev)
- {
- struct smc_local *lp = (struct smc_local *)dev->priv;
-- unsigned short ioaddr = dev->base_addr;
-+ u_int ioaddr = dev->base_addr;
- word length;
- unsigned short numPages;
- word time_out;
-@@ -477,15 +753,16 @@
- /* Well, I want to send the packet.. but I don't know
- if I can send it right now... */
-
-- if ( lp->saved_skb) {
-+ if (lp->saved_skb) {
- /* THIS SHOULD NEVER HAPPEN. */
- lp->stats.tx_aborted_errors++;
-- printk(CARDNAME": Bad Craziness - sent packet while busy.\n" );
-+ printk("%s: Bad Craziness - sent packet while busy.\n",
-+ dev->name);
- return 1;
- }
-
- length = skb->len;
--
-+
- if(length < ETH_ZLEN)
- {
- skb = skb_padto(skb, ETH_ZLEN);
-@@ -497,18 +774,18 @@
- length = ETH_ZLEN;
- }
- lp->saved_skb = skb;
--
-+
- /*
- ** The MMU wants the number of pages to be the number of 256 bytes
-- ** 'pages', minus 1 ( since a packet can't ever have 0 pages :) )
-+ ** 'pages', minus 1 (since a packet can't ever have 0 pages :))
- **
- ** Pkt size for allocating is data length +6 (for additional status words,
- ** length and ctl!) If odd size last byte is included in this header.
- */
-- numPages = ((length & 0xfffe) + 6) / 256;
-+ numPages = ((length & 0xfffe) + 6) / 256;
-
-- if (numPages > 7 ) {
-- printk(CARDNAME": Far too big packet error. \n");
-+ if (numPages > 7) {
-+ printk("%s: Far too big packet error.\n", dev->name);
- /* freeing the packet is a good thing here... but should
- . any packets of this size get down here? */
- dev_kfree_skb (skb);
-@@ -517,12 +794,13 @@
- netif_wake_queue(dev);
- return 0;
- }
-+
- /* either way, a packet is waiting now */
- lp->packets_waiting++;
-
- /* now, try to allocate the memory */
-- SMC_SELECT_BANK( 2 );
-- outw( MC_ALLOC | numPages, ioaddr + MMU_CMD );
-+ SMC_SELECT_BANK(2);
-+ smc_outw(MC_ALLOC | numPages, ioaddr, MMU_CMD);
- /*
- . Performance Hack
- .
-@@ -539,21 +817,21 @@
- do {
- word status;
-
-- status = inb( ioaddr + INTERRUPT );
-- if ( status & IM_ALLOC_INT ) {
-+ status = smc_inb(ioaddr, INTERRUPT);
-+ if (status & IM_ALLOC_INT) {
- /* acknowledge the interrupt */
-- outb( IM_ALLOC_INT, ioaddr + INTERRUPT );
-- break;
-+ smc_outb(IM_ALLOC_INT, ioaddr, INTERRUPT);
-+ break;
- }
-- } while ( -- time_out );
-+ } while (-- time_out);
-
-- if ( !time_out ) {
-+ if (!time_out) {
- /* oh well, wait until the chip finds memory later */
-- SMC_ENABLE_INT( IM_ALLOC_INT );
-- PRINTK2((CARDNAME": memory allocation deferred. \n"));
-+ SMC_ENABLE_INT(IM_ALLOC_INT);
-+ PRINTK2(("%s: memory allocation deferred.\n", dev->name));
- /* it's deferred, but I'll handle it later */
-- return 0;
-- }
-+ return 0;
-+ }
- /* or YES! I can send the packet now.. */
- smc_hardware_send_packet(dev);
- netif_wake_queue(dev);
-@@ -561,46 +839,46 @@
- }
-
- /*
-- . Function: smc_hardware_send_packet(struct net_device * )
-+ . Function: smc_hardware_send_packet(struct net_device *)
- . Purpose:
- . This sends the actual packet to the SMC9xxx chip.
- .
- . Algorithm:
- . First, see if a saved_skb is available.
-- . ( this should NOT be called if there is no 'saved_skb'
-+ . (this should NOT be called if there is no 'saved_skb'
- . Now, find the packet number that the chip allocated
- . Point the data pointers at it in memory
- . Set the length word in the chip's memory
- . Dump the packet to chip memory
-- . Check if a last byte is needed ( odd length packet )
-+ . Check if a last byte is needed (odd length packet)
- . if so, set the control flag right
- . Tell the card to send it
- . Enable the transmit interrupt, so I know if it failed
- . Free the kernel data if I actually sent it.
- */
--static void smc_hardware_send_packet( struct net_device * dev )
-+static void smc_hardware_send_packet(struct net_device *dev)
- {
- struct smc_local *lp = (struct smc_local *)dev->priv;
-- byte packet_no;
-- struct sk_buff * skb = lp->saved_skb;
-- word length;
-- unsigned short ioaddr;
-- byte * buf;
--
-- ioaddr = dev->base_addr;
-+ struct sk_buff *skb = lp->saved_skb;
-+ word length, lastword;
-+ u_int ioaddr = dev->base_addr;
-+ byte packet_no;
-+ byte *buf;
-
-- if ( !skb ) {
-- PRINTK((CARDNAME": In XMIT with no packet to send \n"));
-+ if (!skb) {
-+ PRINTK(("%s: In XMIT with no packet to send\n", dev->name));
- return;
- }
-+
- length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
- buf = skb->data;
-
- /* If I get here, I _know_ there is a packet slot waiting for me */
-- packet_no = inb( ioaddr + PNR_ARR + 1 );
-- if ( packet_no & 0x80 ) {
-+ packet_no = smc_inb(ioaddr, PNR_ARR + 1);
-+ if (packet_no & 0x80) {
- /* or isn't there? BAD CHIP! */
-- printk(KERN_DEBUG CARDNAME": Memory allocation failed. \n");
-+ printk(KERN_DEBUG "%s: Memory allocation failed.\n",
-+ dev->name);
- dev_kfree_skb_any(skb);
- lp->saved_skb = NULL;
- netif_wake_queue(dev);
-@@ -608,26 +886,19 @@
- }
-
- /* we have a packet address, so tell the card to use it */
-- outb( packet_no, ioaddr + PNR_ARR );
-+ smc_outb(packet_no, ioaddr, PNR_ARR);
-
- /* point to the beginning of the packet */
-- outw( PTR_AUTOINC , ioaddr + POINTER );
-+ smc_outw(PTR_AUTOINC, ioaddr, POINTER);
-
-- PRINTK3((CARDNAME": Trying to xmit packet of length %x\n", length ));
--#if SMC_DEBUG > 2
-- print_packet( buf, length );
--#endif
-+ PRINTK3(("%s: Trying to xmit packet of length %x\n",
-+ dev->name, length));
-
-- /* send the packet length ( +6 for status, length and ctl byte )
-- and the status word ( set to zeros ) */
--#ifdef USE_32_BIT
-- outl( (length +6 ) << 16 , ioaddr + DATA_1 );
--#else
-- outw( 0, ioaddr + DATA_1 );
-- /* send the packet length ( +6 for status words, length, and ctl*/
-- outb( (length+6) & 0xFF,ioaddr + DATA_1 );
-- outb( (length+6) >> 8 , ioaddr + DATA_1 );
--#endif
-+ print_packet(buf, length);
-+
-+ /* send the packet length (+6 for status, length and ctl byte)
-+ and the status word (set to zeros) */
-+ smc_outl((length + 6) << 16, ioaddr, DATA_1);
-
- /* send the actual data
- . I _think_ it's faster to send the longs first, and then
-@@ -636,32 +907,22 @@
- . a good idea to check which is optimal? But that could take
- . almost as much time as is saved?
- */
--#ifdef USE_32_BIT
-- if ( length & 0x2 ) {
-- outsl(ioaddr + DATA_1, buf, length >> 2 );
-- outw( *((word *)(buf + (length & 0xFFFFFFFC))),ioaddr +DATA_1);
-- }
-- else
-- outsl(ioaddr + DATA_1, buf, length >> 2 );
--#else
-- outsw(ioaddr + DATA_1 , buf, (length ) >> 1);
--#endif
-- /* Send the last byte, if there is one. */
-+ smc_outs(ioaddr, DATA_1, buf, length);
-
-- if ( (length & 1) == 0 ) {
-- outw( 0, ioaddr + DATA_1 );
-- } else {
-- outb( buf[length -1 ], ioaddr + DATA_1 );
-- outb( 0x20, ioaddr + DATA_1);
-- }
-+ /* Send the last byte, if there is one. */
-+ if ((length & 1) == 0)
-+ lastword = 0;
-+ else
-+ lastword = 0x2000 | buf[length - 1];
-+ smc_outw(lastword, ioaddr, DATA_1);
-
- /* enable the interrupts */
-- SMC_ENABLE_INT( (IM_TX_INT | IM_TX_EMPTY_INT) );
-+ SMC_ENABLE_INT(IM_TX_INT | IM_TX_EMPTY_INT);
-
- /* and let the chipset deal with it */
-- outw( MC_ENQUEUE , ioaddr + MMU_CMD );
-+ smc_outw(MC_ENQUEUE, ioaddr, MMU_CMD);
-
-- PRINTK2((CARDNAME": Sent packet of length %d \n",length));
-+ PRINTK2(("%s: Sent packet of length %d\n", dev->name, length));
-
- lp->saved_skb = NULL;
- dev_kfree_skb_any (skb);
-@@ -676,7 +937,7 @@
-
- /*-------------------------------------------------------------------------
- |
-- | smc_init( struct net_device * dev )
-+ | smc_init(struct net_device * dev)
- | Input parameters:
- | dev->base_addr == 0, try to find all possible locations
- | dev->base_addr == 1, return failure code
-@@ -691,6 +952,65 @@
- */
- int __init smc_init(struct net_device *dev)
- {
-+ int ret = -ENODEV;
-+#if defined(CONFIG_ASSABET_NEPONSET)
-+ if (machine_is_assabet() && machine_has_neponset()) {
-+ unsigned int *addr;
-+ unsigned char ecor;
-+ unsigned long flags;
-+
-+ NCR_0 |= NCR_ENET_OSC_EN;
-+ dev->irq = IRQ_NEPONSET_SMC9196;
-+
-+ /*
-+ * Map the attribute space. This is overkill, but clean.
-+ */
-+ addr = ioremap(0x18000000 + (1 << 25), 64 * 1024 * 4);
-+ if (!addr)
-+ return -ENOMEM;
-+
-+ /*
-+ * Reset the device. We must disable IRQs around this.
-+ */
-+ local_irq_save(flags);
-+ ecor = readl(addr + ECOR) & ~ECOR_RESET;
-+ writel(ecor | ECOR_RESET, addr + ECOR);
-+ udelay(100);
-+
-+ /*
-+ * The device will ignore all writes to the enable bit while
-+ * reset is asserted, even if the reset bit is cleared in the
-+ * same write. Must clear reset first, then enable the device.
-+ */
-+ writel(ecor, addr + ECOR);
-+ writel(ecor | ECOR_ENABLE, addr + ECOR);
-+
-+ /*
-+ * Force byte mode.
-+ */
-+ writel(readl(addr + ECSR) | ECSR_IOIS8, addr + ECSR);
-+ local_irq_restore(flags);
-+
-+ iounmap(addr);
-+
-+ /*
-+ * Wait for the chip to wake up.
-+ */
-+ mdelay(1);
-+
-+ /*
-+ * Map the real registers.
-+ */
-+ addr = ioremap(0x18000000, 8 * 1024);
-+ if (!addr)
-+ return -ENOMEM;
-+
-+ ret = smc_probe(dev, (int)addr);
-+ if (ret)
-+ iounmap(addr);
-+ }
-+
-+#elif defined(CONFIG_ISA)
- int i;
- int base_addr = dev->base_addr;
-
-@@ -708,7 +1028,8 @@
- return 0;
-
- /* couldn't find anything */
-- return -ENODEV;
-+#endif
-+ return ret;
- }
-
- /*----------------------------------------------------------------------
-@@ -718,10 +1039,11 @@
- . interrupt, so an auto-detect routine can detect it, and find the IRQ,
- ------------------------------------------------------------------------
- */
--int __init smc_findirq( int ioaddr )
-+int __init smc_findirq(struct net_device *dev)
- {
- int timeout = 20;
- unsigned long cookie;
-+ u_int ioaddr = dev->base_addr;
-
-
- /* I have to do a STI() here, because this is called from
-@@ -737,26 +1059,25 @@
- * when done.
- */
-
--
-+ /* enable ALLOCation interrupts ONLY. */
- SMC_SELECT_BANK(2);
-- /* enable ALLOCation interrupts ONLY */
-- outb( IM_ALLOC_INT, ioaddr + INT_MASK );
-+ SMC_SET_INT(IM_ALLOC_INT);
-
- /*
- . Allocate 512 bytes of memory. Note that the chip was just
- . reset so all the memory is available
- */
-- outw( MC_ALLOC | 1, ioaddr + MMU_CMD );
-+ smc_outw(MC_ALLOC | 1, ioaddr, MMU_CMD);
-
- /*
- . Wait until positive that the interrupt has been generated
- */
-- while ( timeout ) {
-+ while (timeout) {
- byte int_status;
-
-- int_status = inb( ioaddr + INTERRUPT );
-+ int_status = smc_inb(ioaddr, INTERRUPT);
-
-- if ( int_status & IM_ALLOC_INT )
-+ if (int_status & IM_ALLOC_INT)
- break; /* got the interrupt */
- timeout--;
- }
-@@ -775,7 +1096,7 @@
- SMC_DELAY();
-
- /* and disable all interrupts again */
-- outb( 0, ioaddr + INT_MASK );
-+ SMC_SET_INT(0);
-
- /* clear hardware interrupts again, because that's how it
- was when I was called... */
-@@ -785,8 +1106,87 @@
- return probe_irq_off(cookie);
- }
-
-+static int __init smc_probe_chip(struct net_device *dev, int ioaddr)
-+{
-+ unsigned int temp;
-+
-+ /* First, see if the high byte is 0x33 */
-+ temp = smc_inw(ioaddr, BANK_SELECT);
-+ if ((temp & 0xFF00) != 0x3300)
-+ return -ENODEV;
-+
-+ /* The above MIGHT indicate a device, but I need to write to further
-+ test this. */
-+ smc_outw(0, ioaddr, BANK_SELECT);
-+ temp = smc_inw(ioaddr, BANK_SELECT);
-+ if ((temp & 0xFF00) != 0x3300)
-+ return -ENODEV;
-+
-+#ifndef CONFIG_ASSABET_NEPONSET
-+ /* well, we've already written once, so hopefully another time won't
-+ hurt. This time, I need to switch the bank register to bank 1,
-+ so I can access the base address register */
-+ SMC_SELECT_BANK(1);
-+ temp = smc_inw(ioaddr, BASE);
-+ if (ioaddr != (temp >> 3 & 0x3E0)) {
-+ printk("%s: IOADDR %x doesn't match configuration (%x)."
-+ "Probably not a SMC chip\n", dev->name,
-+ ioaddr, (base_address_register >> 3) & 0x3E0);
-+ /* well, the base address register didn't match. Must not have
-+ been a SMC chip after all. */
-+ return -ENODEV;
-+ }
-+#endif
-+
-+ return 0;
-+}
-+
-+/*
-+ . If dev->irq is 0, then the device has to be banged on to see
-+ . what the IRQ is.
-+ .
-+ . This banging doesn't always detect the IRQ, for unknown reasons.
-+ . a workaround is to reset the chip and try again.
-+ .
-+ . Interestingly, the DOS packet driver *SETS* the IRQ on the card to
-+ . be what is requested on the command line. I don't do that, mostly
-+ . because the card that I have uses a non-standard method of accessing
-+ . the IRQs, and because this _should_ work in most configurations.
-+ .
-+ . Specifying an IRQ is done with the assumption that the user knows
-+ . what (s)he is doing. No checking is done!!!!
-+ .
-+*/
-+static int __init smc_probe_irq(struct net_device *dev)
-+{
-+ if (dev->irq < 2) {
-+ int trials;
-+
-+ trials = 3;
-+ while (trials--) {
-+ dev->irq = smc_findirq(dev);
-+ if (dev->irq)
-+ break;
-+ /* kick the card and try again */
-+ smc_reset(dev);
-+ }
-+ }
-+ if (dev->irq == 0) {
-+ printk("%s: Couldn't autodetect your IRQ. Use irq=xx.\n",
-+ dev->name);
-+ return -ENODEV;
-+ }
-+
-+ /*
-+ * Some machines (eg, PCs) need to cannonicalize their IRQs.
-+ */
-+ dev->irq = irq_cannonicalize(dev->irq);
-+
-+ return 0;
-+}
-+
- /*----------------------------------------------------------------------
-- . Function: smc_probe( int ioaddr )
-+ . Function: smc_probe(struct net_device *dev, int ioaddr)
- .
- . Purpose:
- . Tests to see if a given ioaddr points to an SMC9xxx chip.
-@@ -816,16 +1216,14 @@
- */
- static int __init smc_probe(struct net_device *dev, int ioaddr)
- {
-+ struct smc_local *smc;
- int i, memory, retval;
- static unsigned version_printed;
-- unsigned int bank;
-
- const char *version_string;
-- const char *if_string;
-
- /* registers */
- word revision_register;
-- word base_address_register;
- word configuration_register;
- word memory_info_register;
- word memory_cfg_register;
-@@ -834,44 +1232,24 @@
- if (!request_region(ioaddr, SMC_IO_EXTENT, dev->name))
- return -EBUSY;
-
-- /* First, see if the high byte is 0x33 */
-- bank = inw( ioaddr + BANK_SELECT );
-- if ( (bank & 0xFF00) != 0x3300 ) {
-- retval = -ENODEV;
-- goto err_out;
-- }
-- /* The above MIGHT indicate a device, but I need to write to further
-- test this. */
-- outw( 0x0, ioaddr + BANK_SELECT );
-- bank = inw( ioaddr + BANK_SELECT );
-- if ( (bank & 0xFF00 ) != 0x3300 ) {
-- retval = -ENODEV;
-- goto err_out;
-- }
-- /* well, we've already written once, so hopefully another time won't
-- hurt. This time, I need to switch the bank register to bank 1,
-- so I can access the base address register */
-- SMC_SELECT_BANK(1);
-- base_address_register = inw( ioaddr + BASE );
-- if ( ioaddr != ( base_address_register >> 3 & 0x3E0 ) ) {
-- printk(CARDNAME ": IOADDR %x doesn't match configuration (%x)."
-- "Probably not a SMC chip\n",
-- ioaddr, base_address_register >> 3 & 0x3E0 );
-- /* well, the base address register didn't match. Must not have
-- been a SMC chip after all. */
-- retval = -ENODEV;
-+ /*
-+ * Do the basic probes.
-+ */
-+ retval = smc_probe_chip(dev, ioaddr);
-+ if (retval)
- goto err_out;
-- }
-
- /* check if the revision register is something that I recognize.
- These might need to be added to later, as future revisions
- could be added. */
- SMC_SELECT_BANK(3);
-- revision_register = inw( ioaddr + REVISION );
-- if ( !chip_ids[ ( revision_register >> 4 ) & 0xF ] ) {
-+ revision_register = smc_inw(ioaddr, REVISION);
-+ version_string = chip_ids[(revision_register >> 4) & 15];
-+ if (!version_string) {
- /* I don't recognize this chip, so... */
-- printk(CARDNAME ": IO %x: Unrecognized revision register:"
-- " %x, Contact author. \n", ioaddr, revision_register );
-+ printk("%s: IO %x: unrecognized revision register: %x, "
-+ "contact author.\n", dev->name, ioaddr,
-+ revision_register);
-
- retval = -ENODEV;
- goto err_out;
-@@ -882,138 +1260,122 @@
- against the hardware address, or do some other tests. */
-
- if (version_printed++ == 0)
-- printk("%s", version);
-+ printk(KERN_INFO "%s", version);
-
- /* fill in some of the fields */
- dev->base_addr = ioaddr;
-
- /*
-- . Get the MAC address ( bank 1, regs 4 - 9 )
-+ . Get the MAC address (bank 1, regs 4 - 9)
- */
-- SMC_SELECT_BANK( 1 );
-- for ( i = 0; i < 6; i += 2 ) {
-+ SMC_SELECT_BANK(1);
-+ for (i = 0; i < 6; i += 2) {
- word address;
-
-- address = inw( ioaddr + ADDR0 + i );
-- dev->dev_addr[ i + 1] = address >> 8;
-- dev->dev_addr[ i ] = address & 0xFF;
-+ address = smc_inw(ioaddr, ADDR0 + i);
-+ dev->dev_addr[i + 1] = address >> 8;
-+ dev->dev_addr[i] = address & 0xFF;
- }
-
-+ if (!is_valid_ether_addr(dev->dev_addr))
-+ printk("%s: Invalid ethernet MAC address. Please set using "
-+ "ifconfig\n", dev->name);
-+
- /* get the memory information */
-
-- SMC_SELECT_BANK( 0 );
-- memory_info_register = inw( ioaddr + MIR );
-- memory_cfg_register = inw( ioaddr + MCR );
-- memory = ( memory_cfg_register >> 9 ) & 0x7; /* multiplier */
-- memory *= 256 * ( memory_info_register & 0xFF );
-+ SMC_SELECT_BANK(0);
-+ memory_info_register = smc_inw(ioaddr, MIR);
-+ memory_cfg_register = smc_inw(ioaddr, MCR);
-+ memory = (memory_cfg_register >> 9) & 0x7; /* multiplier */
-+ memory *= 256 * (memory_info_register & 0xFF);
-+
-+ /* now, reset the chip, and put it into a known state */
-+ smc_reset(dev);
-
- /*
-- Now, I want to find out more about the chip. This is sort of
-- redundant, but it's cleaner to have it in both, rather than having
-- one VERY long probe procedure.
-- */
-- SMC_SELECT_BANK(3);
-- revision_register = inw( ioaddr + REVISION );
-- version_string = chip_ids[ ( revision_register >> 4 ) & 0xF ];
-- if ( !version_string ) {
-- /* I shouldn't get here because this call was done before.... */
-- retval = -ENODEV;
-+ * Ok, now that we have everything in a
-+ * sane state, probe for the interrupt.
-+ */
-+ retval = smc_probe_irq(dev);
-+ if (retval)
- goto err_out;
-- }
-
-- /* is it using AUI or 10BaseT ? */
-- if ( dev->if_port == 0 ) {
-- SMC_SELECT_BANK(1);
-- configuration_register = inw( ioaddr + CONFIG );
-- if ( configuration_register & CFG_AUI_SELECT )
-- dev->if_port = 2;
-- else
-- dev->if_port = 1;
-+ /* Initialize the private structure. */
-+ if (dev->priv == NULL) {
-+ dev->priv = kmalloc(sizeof(struct smc_local), GFP_KERNEL);
-+ if (dev->priv == NULL) {
-+ retval = -ENOMEM;
-+ goto err_out;
-+ }
- }
-- if_string = interfaces[ dev->if_port - 1 ];
-
-- /* now, reset the chip, and put it into a known state */
-- smc_reset( ioaddr );
-+ smc = dev->priv;
-+
-+ /* set the private data to zero by default */
-+ memset(smc, 0, sizeof(struct smc_local));
-
- /*
-- . If dev->irq is 0, then the device has to be banged on to see
-- . what the IRQ is.
-- .
-- . This banging doesn't always detect the IRQ, for unknown reasons.
-- . a workaround is to reset the chip and try again.
-- .
-- . Interestingly, the DOS packet driver *SETS* the IRQ on the card to
-- . be what is requested on the command line. I don't do that, mostly
-- . because the card that I have uses a non-standard method of accessing
-- . the IRQs, and because this _should_ work in most configurations.
-- .
-- . Specifying an IRQ is done with the assumption that the user knows
-- . what (s)he is doing. No checking is done!!!!
-- .
-- */
-- if ( dev->irq < 2 ) {
-- int trials;
-+ * Get the interface characteristics.
-+ * is it using AUI or 10BaseT ?
-+ */
-+ switch (dev->if_port) {
-+ case IF_PORT_10BASET:
-+ smc->port = PORT_TP;
-+ break;
-
-- trials = 3;
-- while ( trials-- ) {
-- dev->irq = smc_findirq( ioaddr );
-- if ( dev->irq )
-- break;
-- /* kick the card and try again */
-- smc_reset( ioaddr );
-+ case IF_PORT_AUI:
-+ smc->port = PORT_AUI;
-+ break;
-+
-+ default:
-+ SMC_SELECT_BANK(1);
-+ configuration_register = smc_inw(ioaddr, CONFIG);
-+ if (configuration_register & CFG_AUI_SELECT) {
-+ dev->if_port = IF_PORT_AUI;
-+ smc->port = PORT_AUI;
-+ } else {
-+ dev->if_port = IF_PORT_10BASET;
-+ smc->port = PORT_TP;
- }
-- }
-- if (dev->irq == 0 ) {
-- printk(CARDNAME": Couldn't autodetect your IRQ. Use irq=xx.\n");
-- retval = -ENODEV;
-- goto err_out;
-+ break;
- }
-
-- /* now, print out the card info, in a short format.. */
-+ /* all interfaces are half-duplex by default */
-+ smc->duplex = DUPLEX_HALF;
-
-- printk("%s: %s(r:%d) at %#3x IRQ:%d INTF:%s MEM:%db ", dev->name,
-- version_string, revision_register & 0xF, ioaddr, dev->irq,
-- if_string, memory );
-+ /* now, print out the card info, in a short format.. */
-+ printk("%s: %s (rev %d) at %#3x IRQ:%d INTF:%s MEM:%db ", dev->name,
-+ version_string, revision_register & 15, ioaddr, dev->irq,
-+ interfaces[smc->port], memory);
- /*
- . Print the Ethernet address
- */
- printk("ADDR: ");
- for (i = 0; i < 5; i++)
-- printk("%2.2x:", dev->dev_addr[i] );
-- printk("%2.2x \n", dev->dev_addr[5] );
--
--
-- /* Initialize the private structure. */
-- if (dev->priv == NULL) {
-- dev->priv = kmalloc(sizeof(struct smc_local), GFP_KERNEL);
-- if (dev->priv == NULL) {
-- retval = -ENOMEM;
-- goto err_out;
-- }
-- }
-- /* set the private data to zero by default */
-- memset(dev->priv, 0, sizeof(struct smc_local));
-+ printk("%2.2x:", dev->dev_addr[i]);
-+ printk("%2.2x\n", dev->dev_addr[5]);
-
- /* Fill in the fields of the device structure with ethernet values. */
- ether_setup(dev);
-
- /* Grab the IRQ */
-- retval = request_irq(dev->irq, &smc_interrupt, 0, dev->name, dev);
-- if (retval) {
-+ retval = request_irq(dev->irq, &smc_interrupt, 0, dev->name, dev);
-+ if (retval) {
- printk("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
- dev->irq, retval);
- kfree(dev->priv);
- dev->priv = NULL;
-- goto err_out;
-- }
-+ goto err_out;
-+ }
-
-- dev->open = smc_open;
-- dev->stop = smc_close;
-- dev->hard_start_xmit = smc_wait_to_send_packet;
-- dev->tx_timeout = smc_timeout;
-- dev->watchdog_timeo = HZ/20;
-- dev->get_stats = smc_query_statistics;
-- dev->set_multicast_list = smc_set_multicast_list;
-+ dev->open = smc_open;
-+ dev->stop = smc_close;
-+ dev->hard_start_xmit = smc_wait_to_send_packet;
-+ dev->tx_timeout = smc_timeout;
-+ dev->watchdog_timeo = HZ/20;
-+ dev->get_stats = smc_query_statistics;
-+ dev->set_multicast_list = smc_set_multicast_list;
-+ dev->do_ioctl = smc_ioctl;
-
- return 0;
-
-@@ -1022,42 +1384,43 @@
- return retval;
- }
-
--#if SMC_DEBUG > 2
--static void print_packet( byte * buf, int length )
-+/*
-+ * This is responsible for setting the chip appropriately
-+ * for the interface type. This should only be called while
-+ * the interface is up and running.
-+ */
-+static void smc_set_port(struct net_device *dev)
- {
--#if 0
-- int i;
-- int remainder;
-- int lines;
--
-- printk("Packet of length %d \n", length );
-- lines = length / 16;
-- remainder = length % 16;
--
-- for ( i = 0; i < lines ; i ++ ) {
-- int cur;
-+ struct smc_local *smc = dev->priv;
-+ u_int ioaddr = dev->base_addr;
-+ u_int val;
-
-- for ( cur = 0; cur < 8; cur ++ ) {
-- byte a, b;
-+ SMC_SELECT_BANK(1);
-+ val = smc_inw(ioaddr, CONFIG);
-+ switch (smc->port) {
-+ case PORT_TP:
-+ val &= ~CFG_AUI_SELECT;
-+ break;
-
-- a = *(buf ++ );
-- b = *(buf ++ );
-- printk("%02x%02x ", a, b );
-- }
-- printk("\n");
-+ case PORT_AUI:
-+ val |= CFG_AUI_SELECT;
-+ break;
- }
-- for ( i = 0; i < remainder/2 ; i++ ) {
-- byte a, b;
-+ smc_outw(val, ioaddr, CONFIG);
-
-- a = *(buf ++ );
-- b = *(buf ++ );
-- printk("%02x%02x ", a, b );
-+ SMC_SELECT_BANK(0);
-+ val = smc_inw(ioaddr, TCR);
-+ switch (smc->duplex) {
-+ case DUPLEX_HALF:
-+ val &= ~TCR_FDSE;
-+ break;
-+
-+ case DUPLEX_FULL:
-+ val |= TCR_FDSE;
-+ break;
- }
-- printk("\n");
--#endif
-+ smc_outw(val, ioaddr, TCR);
- }
--#endif
--
-
- /*
- * Open and Initialize the board
-@@ -1067,48 +1430,141 @@
- */
- static int smc_open(struct net_device *dev)
- {
-- int ioaddr = dev->base_addr;
-+ struct smc_local *smc = dev->priv;
-+ u_int ioaddr = dev->base_addr;
-+ int i;
-
-- int i; /* used to set hw ethernet address */
-+ /*
-+ * Check that the address is valid. If its not, refuse
-+ * to bring the device up. The user must specify an
-+ * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
-+ */
-+ if (!is_valid_ether_addr(dev->dev_addr))
-+ return -EINVAL;
-
- /* clear out all the junk that was put here before... */
-- memset(dev->priv, 0, sizeof(struct smc_local));
-+ smc->saved_skb = NULL;
-+ smc->packets_waiting = 0;
-
- /* reset the hardware */
--
-- smc_reset( ioaddr );
-- smc_enable( ioaddr );
-+ smc_reset(dev);
-+ smc_enable(dev);
-
- /* Select which interface to use */
--
-- SMC_SELECT_BANK( 1 );
-- if ( dev->if_port == 1 ) {
-- outw( inw( ioaddr + CONFIG ) & ~CFG_AUI_SELECT,
-- ioaddr + CONFIG );
-- }
-- else if ( dev->if_port == 2 ) {
-- outw( inw( ioaddr + CONFIG ) | CFG_AUI_SELECT,
-- ioaddr + CONFIG );
-- }
-+ smc_set_port(dev);
-
- /*
-- According to Becker, I have to set the hardware address
-+ According to Becker, I have to set the hardware address
- at this point, because the (l)user can set it with an
- ioctl. Easily done...
- */
-- SMC_SELECT_BANK( 1 );
-- for ( i = 0; i < 6; i += 2 ) {
-+ SMC_SELECT_BANK(1);
-+ for (i = 0; i < 6; i += 2) {
- word address;
-
-- address = dev->dev_addr[ i + 1 ] << 8 ;
-- address |= dev->dev_addr[ i ];
-- outw( address, ioaddr + ADDR0 + i );
-+ address = dev->dev_addr[i + 1] << 8 ;
-+ address |= dev->dev_addr[i];
-+ smc_outw(address, ioaddr, ADDR0 + i);
- }
-
- netif_start_queue(dev);
- return 0;
- }
-
-+/*
-+ * This is our template. Fill the rest in at run-time
-+ */
-+static const struct ethtool_cmd ecmd_template = {
-+ supported: SUPPORTED_10baseT_Half |
-+ SUPPORTED_10baseT_Full |
-+ SUPPORTED_TP |
-+ SUPPORTED_AUI,
-+ speed: SPEED_10,
-+ autoneg: AUTONEG_DISABLE,
-+ maxtxpkt: 1,
-+ maxrxpkt: 1,
-+ transceiver: XCVR_INTERNAL,
-+};
-+
-+static int smc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-+{
-+ struct smc_local *smc = dev->priv;
-+ u32 etcmd;
-+ int ret = -EINVAL;
-+
-+ if (cmd != SIOCETHTOOL)
-+ return -EOPNOTSUPP;
-+
-+ if (get_user(etcmd, (u32 *)rq->ifr_data))
-+ return -EFAULT;
-+
-+ switch (etcmd) {
-+ case ETHTOOL_GSET: {
-+ struct ethtool_cmd ecmd = ecmd_template;
-+
-+ ecmd.cmd = etcmd;
-+ ecmd.port = smc->port;
-+ ecmd.duplex = smc->duplex;
-+
-+ ret = copy_to_user(rq->ifr_data, &ecmd, sizeof(ecmd))
-+ ? -EFAULT : 0;
-+ break;
-+ }
-+
-+ case ETHTOOL_SSET: {
-+ struct ethtool_cmd ecmd;
-+
-+ ret = -EPERM;
-+ if (!capable(CAP_NET_ADMIN))
-+ break;
-+
-+ ret = -EFAULT;
-+ if (copy_from_user(&ecmd, rq->ifr_data, sizeof(ecmd)))
-+ break;
-+
-+ /*
-+ * Sanity-check the arguments.
-+ */
-+ ret = -EINVAL;
-+ if (ecmd.autoneg != AUTONEG_DISABLE)
-+ break;
-+ if (ecmd.speed != SPEED_10)
-+ break;
-+ if (ecmd.duplex != DUPLEX_HALF && ecmd.duplex != DUPLEX_FULL)
-+ break;
-+ if (ecmd.port != PORT_TP && ecmd.port != PORT_AUI)
-+ break;
-+
-+ smc->port = ecmd.port;
-+ smc->duplex = ecmd.duplex;
-+
-+ if (netif_running(dev))
-+ smc_set_port(dev);
-+
-+ ret = 0;
-+ break;
-+ }
-+
-+ case ETHTOOL_GDRVINFO: {
-+ struct ethtool_drvinfo edrv;
-+
-+ memset(&edrv, 0, sizeof(edrv));
-+
-+ edrv.cmd = etcmd;
-+ strcpy(edrv.driver, DRV_NAME);
-+ strcpy(edrv.version, DRV_VERSION);
-+ sprintf(edrv.bus_info, "ISA:%8.8lx:%d",
-+ dev->base_addr, dev->irq);
-+
-+ ret = copy_to_user(rq->ifr_data, &edrv, sizeof(edrv))
-+ ? -EFAULT : 0;
-+ break;
-+ }
-+ }
-+
-+ return ret;
-+}
-+
- /*--------------------------------------------------------
- . Called by the kernel to send a packet out into the void
- . of the net. This routine is largely based on
-@@ -1120,12 +1576,10 @@
- {
- /* If we get here, some higher level has decided we are broken.
- There should really be a "kick me" function call instead. */
-- printk(KERN_WARNING CARDNAME": transmit timed out, %s?\n",
-- tx_done(dev) ? "IRQ conflict" :
-- "network cable problem");
-+ printk(KERN_WARNING "%s: transmit timed out\n", dev->name);
- /* "kick" the adaptor */
-- smc_reset( dev->base_addr );
-- smc_enable( dev->base_addr );
-+ smc_reset(dev);
-+ smc_enable(dev);
- dev->trans_start = jiffies;
- /* clear anything saved */
- ((struct smc_local *)dev->priv)->saved_skb = NULL;
-@@ -1145,10 +1599,10 @@
- .
- ---------------------------------------------------------------------*/
-
--static void smc_interrupt(int irq, void * dev_id, struct pt_regs * regs)
-+static void smc_interrupt(int irq, void * dev_id, struct pt_regs * regs)
- {
- struct net_device *dev = dev_id;
-- int ioaddr = dev->base_addr;
-+ u_int ioaddr = dev->base_addr;
- struct smc_local *lp = (struct smc_local *)dev->priv;
-
- byte status;
-@@ -1161,45 +1615,45 @@
-
-
-
-- PRINTK3((CARDNAME": SMC interrupt started \n"));
-+ PRINTK3(("%s: SMC interrupt started\n", dev->name));
-
-- saved_bank = inw( ioaddr + BANK_SELECT );
-+ saved_bank = smc_inw(ioaddr, BANK_SELECT);
-
- SMC_SELECT_BANK(2);
-- saved_pointer = inw( ioaddr + POINTER );
-+ saved_pointer = smc_inw(ioaddr, POINTER);
-
-- mask = inb( ioaddr + INT_MASK );
-+ mask = smc_inb(ioaddr, INT_MASK);
- /* clear all interrupts */
-- outb( 0, ioaddr + INT_MASK );
-+ SMC_SET_INT(0);
-
-
- /* set a timeout value, so I don't stay here forever */
- timeout = 4;
-
-- PRINTK2((KERN_WARNING CARDNAME ": MASK IS %x \n", mask ));
-+ PRINTK2((KERN_WARNING "%s: MASK IS %x\n", dev->name, mask));
- do {
- /* read the status flag, and mask it */
-- status = inb( ioaddr + INTERRUPT ) & mask;
-- if (!status )
-+ status = smc_inb(ioaddr, INTERRUPT) & mask;
-+ if (!status)
- break;
-
-- PRINTK3((KERN_WARNING CARDNAME
-- ": Handling interrupt status %x \n", status ));
-+ PRINTK3((KERN_WARNING "%s: handling interrupt status %x\n",
-+ dev->name, status));
-
- if (status & IM_RCV_INT) {
- /* Got a packet(s). */
-- PRINTK2((KERN_WARNING CARDNAME
-- ": Receive Interrupt\n"));
-+ PRINTK2((KERN_WARNING "%s: receive interrupt\n",
-+ dev->name));
- smc_rcv(dev);
-- } else if (status & IM_TX_INT ) {
-- PRINTK2((KERN_WARNING CARDNAME
-- ": TX ERROR handled\n"));
-+ } else if (status & IM_TX_INT) {
-+ PRINTK2((KERN_WARNING "%s: TX ERROR handled\n",
-+ dev->name));
- smc_tx(dev);
-- outb(IM_TX_INT, ioaddr + INTERRUPT );
-- } else if (status & IM_TX_EMPTY_INT ) {
-+ smc_outb(IM_TX_INT, ioaddr, INTERRUPT);
-+ } else if (status & IM_TX_EMPTY_INT) {
- /* update stats */
-- SMC_SELECT_BANK( 0 );
-- card_stats = inw( ioaddr + COUNTER );
-+ SMC_SELECT_BANK(0);
-+ card_stats = smc_inw(ioaddr, COUNTER);
- /* single collisions */
- lp->stats.collisions += card_stats & 0xF;
- card_stats >>= 4;
-@@ -1208,60 +1662,63 @@
-
- /* these are for when linux supports these statistics */
-
-- SMC_SELECT_BANK( 2 );
-- PRINTK2((KERN_WARNING CARDNAME
-- ": TX_BUFFER_EMPTY handled\n"));
-- outb( IM_TX_EMPTY_INT, ioaddr + INTERRUPT );
-+ SMC_SELECT_BANK(2);
-+ PRINTK2((KERN_WARNING "%s: TX_BUFFER_EMPTY handled\n",
-+ dev->name));
-+ smc_outb(IM_TX_EMPTY_INT, ioaddr, INTERRUPT);
- mask &= ~IM_TX_EMPTY_INT;
- lp->stats.tx_packets += lp->packets_waiting;
- lp->packets_waiting = 0;
-
-- } else if (status & IM_ALLOC_INT ) {
-- PRINTK2((KERN_DEBUG CARDNAME
-- ": Allocation interrupt \n"));
-+ } else if (status & IM_ALLOC_INT) {
-+ PRINTK2((KERN_DEBUG "%s: Allocation interrupt\n",
-+ dev->name));
- /* clear this interrupt so it doesn't happen again */
- mask &= ~IM_ALLOC_INT;
-
-- smc_hardware_send_packet( dev );
-+ smc_hardware_send_packet(dev);
-
- /* enable xmit interrupts based on this */
-- mask |= ( IM_TX_EMPTY_INT | IM_TX_INT );
-+ mask |= (IM_TX_EMPTY_INT | IM_TX_INT);
-
- /* and let the card send more packets to me */
- netif_wake_queue(dev);
-
-- PRINTK2((CARDNAME": Handoff done successfully.\n"));
-- } else if (status & IM_RX_OVRN_INT ) {
-+ PRINTK2(("%s: Handoff done successfully.\n",
-+ dev->name));
-+ } else if (status & IM_RX_OVRN_INT) {
- lp->stats.rx_errors++;
- lp->stats.rx_fifo_errors++;
-- outb( IM_RX_OVRN_INT, ioaddr + INTERRUPT );
-- } else if (status & IM_EPH_INT ) {
-- PRINTK((CARDNAME ": UNSUPPORTED: EPH INTERRUPT \n"));
-- } else if (status & IM_ERCV_INT ) {
-- PRINTK((CARDNAME ": UNSUPPORTED: ERCV INTERRUPT \n"));
-- outb( IM_ERCV_INT, ioaddr + INTERRUPT );
-+ smc_outb(IM_RX_OVRN_INT, ioaddr, INTERRUPT);
-+ } else if (status & IM_EPH_INT) {
-+ PRINTK(("%s: UNSUPPORTED: EPH INTERRUPT\n",
-+ dev->name));
-+ } else if (status & IM_ERCV_INT) {
-+ PRINTK(("%s: UNSUPPORTED: ERCV INTERRUPT\n",
-+ dev->name));
-+ smc_outb(IM_ERCV_INT, ioaddr, INTERRUPT);
- }
-- } while ( timeout -- );
-+ } while (timeout --);
-
-
- /* restore state register */
-- SMC_SELECT_BANK( 2 );
-- outb( mask, ioaddr + INT_MASK );
-+ SMC_SELECT_BANK(2);
-+ SMC_SET_INT(mask);
-
-- PRINTK3(( KERN_WARNING CARDNAME ": MASK is now %x \n", mask ));
-- outw( saved_pointer, ioaddr + POINTER );
-+ PRINTK3((KERN_WARNING "%s: MASK is now %x\n", dev->name, mask));
-+ smc_outw(saved_pointer, ioaddr, POINTER);
-
-- SMC_SELECT_BANK( saved_bank );
-+ SMC_SELECT_BANK(saved_bank);
-
-- PRINTK3((CARDNAME ": Interrupt done\n"));
-+ PRINTK3(("%s: Interrupt done\n", dev->name));
- return;
- }
-
- /*-------------------------------------------------------------
- .
-- . smc_rcv - receive a packet from the card
-+ . smc_rcv - receive a packet from the card
- .
-- . There is ( at least ) a packet waiting to be read from
-+ . There is (at least) a packet waiting to be read from
- . chip-memory.
- .
- . o Read the status
-@@ -1272,55 +1729,57 @@
- static void smc_rcv(struct net_device *dev)
- {
- struct smc_local *lp = (struct smc_local *)dev->priv;
-- int ioaddr = dev->base_addr;
-+ u_int ioaddr = dev->base_addr;
- int packet_number;
- word status;
- word packet_length;
-
- /* assume bank 2 */
-
-- packet_number = inw( ioaddr + FIFO_PORTS );
-+ packet_number = smc_inw(ioaddr, FIFO_PORTS);
-
-- if ( packet_number & FP_RXEMPTY ) {
-+ if (packet_number & FP_RXEMPTY) {
- /* we got called , but nothing was on the FIFO */
-- PRINTK((CARDNAME ": WARNING: smc_rcv with nothing on FIFO. \n"));
-+ PRINTK(("%s: WARNING: smc_rcv with nothing on FIFO.\n",
-+ dev->name));
- /* don't need to restore anything */
- return;
- }
-
- /* start reading from the start of the packet */
-- outw( PTR_READ | PTR_RCV | PTR_AUTOINC, ioaddr + POINTER );
-+ smc_outw(PTR_READ | PTR_RCV | PTR_AUTOINC, ioaddr, POINTER);
-
- /* First two words are status and packet_length */
-- status = inw( ioaddr + DATA_1 );
-- packet_length = inw( ioaddr + DATA_1 );
-+ status = smc_inw(ioaddr, DATA_1);
-+ packet_length = smc_inw(ioaddr, DATA_1);
-
- packet_length &= 0x07ff; /* mask off top bits */
-
-- PRINTK2(("RCV: STATUS %4x LENGTH %4x\n", status, packet_length ));
-+ PRINTK2(("RCV: STATUS %4x LENGTH %4x\n", status, packet_length));
- /*
- . the packet length contains 3 extra words :
- . status, length, and an extra word with an odd byte .
- */
- packet_length -= 6;
-
-- if ( !(status & RS_ERRORS ) ){
-+ if (!(status & RS_ERRORS)){
- /* do stuff to make a new packet */
- struct sk_buff * skb;
- byte * data;
-
- /* read one extra byte */
-- if ( status & RS_ODDFRAME )
-+ if (status & RS_ODDFRAME)
- packet_length++;
-
- /* set multicast stats */
-- if ( status & RS_MULTICAST )
-+ if (status & RS_MULTICAST)
- lp->stats.multicast++;
-
-- skb = dev_alloc_skb( packet_length + 5);
-+ skb = dev_alloc_skb(packet_length + 5);
-
-- if ( skb == NULL ) {
-- printk(KERN_NOTICE CARDNAME ": Low memory, packet dropped.\n");
-+ if (skb == NULL) {
-+ printk(KERN_NOTICE "%s: Low memory, packet dropped.\n",
-+ dev->name);
- lp->stats.rx_dropped++;
- goto done;
- }
-@@ -1330,36 +1789,15 @@
- ! in the worse case
- */
-
-- skb_reserve( skb, 2 ); /* 16 bit alignment */
-+ skb_reserve(skb, 2); /* 16 bit alignment */
-
- skb->dev = dev;
-- data = skb_put( skb, packet_length);
-+ data = skb_put(skb, packet_length);
-
--#ifdef USE_32_BIT
-- /* QUESTION: Like in the TX routine, do I want
-- to send the DWORDs or the bytes first, or some
-- mixture. A mixture might improve already slow PIO
-- performance */
-- PRINTK3((" Reading %d dwords (and %d bytes) \n",
-- packet_length >> 2, packet_length & 3 ));
-- insl(ioaddr + DATA_1 , data, packet_length >> 2 );
-- /* read the left over bytes */
-- insb( ioaddr + DATA_1, data + (packet_length & 0xFFFFFC),
-- packet_length & 0x3 );
--#else
-- PRINTK3((" Reading %d words and %d byte(s) \n",
-- (packet_length >> 1 ), packet_length & 1 ));
-- insw(ioaddr + DATA_1 , data, packet_length >> 1);
-- if ( packet_length & 1 ) {
-- data += packet_length & ~1;
-- *(data++) = inb( ioaddr + DATA_1 );
-- }
--#endif
--#if SMC_DEBUG > 2
-- print_packet( data, packet_length );
--#endif
-+ smc_ins(ioaddr, DATA_1, data, packet_length);
-+ print_packet(data, packet_length);
-
-- skb->protocol = eth_type_trans(skb, dev );
-+ skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb);
- dev->last_rx = jiffies;
- lp->stats.rx_packets++;
-@@ -1368,15 +1806,17 @@
- /* error ... */
- lp->stats.rx_errors++;
-
-- if ( status & RS_ALGNERR ) lp->stats.rx_frame_errors++;
-- if ( status & (RS_TOOSHORT | RS_TOOLONG ) )
-+ if (status & RS_ALGNERR)
-+ lp->stats.rx_frame_errors++;
-+ if (status & (RS_TOOSHORT | RS_TOOLONG))
- lp->stats.rx_length_errors++;
-- if ( status & RS_BADCRC) lp->stats.rx_crc_errors++;
-+ if (status & RS_BADCRC)
-+ lp->stats.rx_crc_errors++;
- }
-
- done:
- /* error or good, tell the card to get rid of this packet */
-- outw( MC_RELEASE, ioaddr + MMU_CMD );
-+ smc_outw(MC_RELEASE, ioaddr, MMU_CMD);
- }
-
-
-@@ -1389,62 +1829,64 @@
- . Algorithm:
- . Save pointer and packet no
- . Get the packet no from the top of the queue
-- . check if it's valid ( if not, is this an error??? )
-+ . check if it's valid (if not, is this an error???)
- . read the status word
- . record the error
-- . ( resend? Not really, since we don't want old packets around )
-+ . (resend? Not really, since we don't want old packets around)
- . Restore saved values
- ************************************************************************/
--static void smc_tx( struct net_device * dev )
-+static void smc_tx(struct net_device * dev)
- {
-- int ioaddr = dev->base_addr;
-+ u_int ioaddr = dev->base_addr;
- struct smc_local *lp = (struct smc_local *)dev->priv;
- byte saved_packet;
- byte packet_no;
- word tx_status;
-
-
-- /* assume bank 2 */
-+ /* assume bank 2 */
-
-- saved_packet = inb( ioaddr + PNR_ARR );
-- packet_no = inw( ioaddr + FIFO_PORTS );
-+ saved_packet = smc_inb(ioaddr, PNR_ARR);
-+ packet_no = smc_inw(ioaddr, FIFO_PORTS);
- packet_no &= 0x7F;
-
- /* select this as the packet to read from */
-- outb( packet_no, ioaddr + PNR_ARR );
-+ smc_outb(packet_no, ioaddr, PNR_ARR);
-
- /* read the first word from this packet */
-- outw( PTR_AUTOINC | PTR_READ, ioaddr + POINTER );
-+ smc_outw(PTR_AUTOINC | PTR_READ, ioaddr, POINTER);
-
-- tx_status = inw( ioaddr + DATA_1 );
-- PRINTK3((CARDNAME": TX DONE STATUS: %4x \n", tx_status ));
-+ tx_status = smc_inw(ioaddr, DATA_1);
-+ PRINTK3(("%s: TX DONE STATUS: %4x\n", dev->name, tx_status));
-
- lp->stats.tx_errors++;
-- if ( tx_status & TS_LOSTCAR ) lp->stats.tx_carrier_errors++;
-- if ( tx_status & TS_LATCOL ) {
-- printk(KERN_DEBUG CARDNAME
-- ": Late collision occurred on last xmit.\n");
-+ if (tx_status & TS_LOSTCAR)
-+ lp->stats.tx_carrier_errors++;
-+ if (tx_status & TS_LATCOL) {
-+ printk(KERN_DEBUG "%s: Late collision occurred on "
-+ "last xmit.\n", dev->name);
- lp->stats.tx_window_errors++;
- }
- #if 0
-- if ( tx_status & TS_16COL ) { ... }
-+ if (tx_status & TS_16COL) { ... }
- #endif
-
-- if ( tx_status & TS_SUCCESS ) {
-- printk(CARDNAME": Successful packet caused interrupt \n");
-+ if (tx_status & TS_SUCCESS) {
-+ printk("%s: Successful packet caused interrupt\n",
-+ dev->name);
- }
- /* re-enable transmit */
-- SMC_SELECT_BANK( 0 );
-- outw( inw( ioaddr + TCR ) | TCR_ENABLE, ioaddr + TCR );
-+ SMC_SELECT_BANK(0);
-+ smc_outw(smc_inw(ioaddr, TCR) | TCR_ENABLE, ioaddr, TCR);
-
- /* kill the packet */
-- SMC_SELECT_BANK( 2 );
-- outw( MC_FREEPKT, ioaddr + MMU_CMD );
-+ SMC_SELECT_BANK(2);
-+ smc_outw(MC_FREEPKT, ioaddr, MMU_CMD);
-
- /* one less packet waiting for me */
- lp->packets_waiting--;
-
-- outb( saved_packet, ioaddr + PNR_ARR );
-+ smc_outb(saved_packet, ioaddr, PNR_ARR);
- return;
- }
-
-@@ -1460,7 +1902,7 @@
- {
- netif_stop_queue(dev);
- /* clear everything */
-- smc_shutdown( dev->base_addr );
-+ smc_shutdown(dev);
-
- /* Update the statistics here. */
- return 0;
-@@ -1481,16 +1923,16 @@
- .
- . This routine will, depending on the values passed to it,
- . either make it accept multicast packets, go into
-- . promiscuous mode ( for TCPDUMP and cousins ) or accept
-+ . promiscuous mode (for TCPDUMP and cousins) or accept
- . a select set of multicast packets
- */
- static void smc_set_multicast_list(struct net_device *dev)
- {
-- short ioaddr = dev->base_addr;
-+ u_int ioaddr = dev->base_addr;
-
- SMC_SELECT_BANK(0);
-- if ( dev->flags & IFF_PROMISC )
-- outw( inw(ioaddr + RCR ) | RCR_PROMISC, ioaddr + RCR );
-+ if (dev->flags & IFF_PROMISC)
-+ smc_outw(smc_inw(ioaddr, RCR) | RCR_PROMISC, ioaddr, RCR);
-
- /* BUG? I never disable promiscuous mode if multicasting was turned on.
- Now, I turn off promiscuous mode, but I don't do anything to multicasting
-@@ -1502,34 +1944,34 @@
- checked before the table is
- */
- else if (dev->flags & IFF_ALLMULTI)
-- outw( inw(ioaddr + RCR ) | RCR_ALMUL, ioaddr + RCR );
-+ smc_outw(smc_inw(ioaddr, RCR) | RCR_ALMUL, ioaddr, RCR);
-
- /* We just get all multicast packets even if we only want them
- . from one source. This will be changed at some future
- . point. */
-- else if (dev->mc_count ) {
-+ else if (dev->mc_count) {
- /* support hardware multicasting */
-
- /* be sure I get rid of flags I might have set */
-- outw( inw( ioaddr + RCR ) & ~(RCR_PROMISC | RCR_ALMUL),
-- ioaddr + RCR );
-+ smc_outw(smc_inw(ioaddr, RCR) & ~(RCR_PROMISC | RCR_ALMUL),
-+ ioaddr, RCR);
- /* NOTE: this has to set the bank, so make sure it is the
- last thing called. The bank is set to zero at the top */
-- smc_setmulticast( ioaddr, dev->mc_count, dev->mc_list );
-+ smc_setmulticast(dev, dev->mc_count, dev->mc_list);
- }
-- else {
-- outw( inw( ioaddr + RCR ) & ~(RCR_PROMISC | RCR_ALMUL),
-- ioaddr + RCR );
-+ else {
-+ smc_outw(smc_inw(ioaddr, RCR) & ~(RCR_PROMISC | RCR_ALMUL),
-+ ioaddr, RCR);
-
- /*
- since I'm disabling all multicast entirely, I need to
- clear the multicast list
- */
-- SMC_SELECT_BANK( 3 );
-- outw( 0, ioaddr + MULTICAST1 );
-- outw( 0, ioaddr + MULTICAST2 );
-- outw( 0, ioaddr + MULTICAST3 );
-- outw( 0, ioaddr + MULTICAST4 );
-+ SMC_SELECT_BANK(3);
-+ smc_outw(0, ioaddr, MULTICAST1);
-+ smc_outw(0, ioaddr, MULTICAST2);
-+ smc_outw(0, ioaddr, MULTICAST3);
-+ smc_outw(0, ioaddr, MULTICAST4);
- }
- }
-
-@@ -1550,21 +1992,26 @@
-
- int init_module(void)
- {
-- int result;
--
- if (io == 0)
-- printk(KERN_WARNING
-- CARDNAME": You shouldn't use auto-probing with insmod!\n" );
-+ printk(KERN_WARNING CARDNAME
-+ ": You shouldn't use auto-probing with insmod!\n");
-+
-+ /*
-+ * Note: dev->if_port has changed to be 2.4 compliant.
-+ * We keep the ifport insmod parameter the same though.
-+ */
-+ switch (ifport) {
-+ case 1: devSMC9194.if_port = IF_PORT_10BASET; break;
-+ case 2: devSMC9194.if_port = IF_PORT_AUI; break;
-+ default: devSMC9194.if_port = 0; break;
-+ }
-
- /* copy the parameters from insmod into the device structure */
- devSMC9194.base_addr = io;
- devSMC9194.irq = irq;
-- devSMC9194.if_port = ifport;
-- devSMC9194.init = smc_init;
-- if ((result = register_netdev(&devSMC9194)) != 0)
-- return result;
-+ devSMC9194.init = smc_init;
-
-- return 0;
-+ return register_netdev(&devSMC9194);
- }
-
- void cleanup_module(void)
---- linux-2.4.25/drivers/net/smc9194.h~2.4.25-vrs2.patch 2001-09-08 21:13:55.000000000 +0200
-+++ linux-2.4.25/drivers/net/smc9194.h 2004-03-31 17:15:09.000000000 +0200
-@@ -63,10 +63,11 @@
-
- #define TCR 0 /* transmit control register */
- #define TCR_ENABLE 0x0001 /* if this is 1, we can transmit */
-+#define TCR_PAD_ENABLE 0x0080 /* pads short packets to 64 bytes */
-+#define TCR_MON_CNS 0x0400 /* monitors the carrier status */
- #define TCR_FDUPLX 0x0800 /* receive packets sent out */
- #define TCR_STP_SQET 0x1000 /* stop transmitting if Signal quality error */
--#define TCR_MON_CNS 0x0400 /* monitors the carrier status */
--#define TCR_PAD_ENABLE 0x0080 /* pads short packets to 64 bytes */
-+#define TCR_FDSE 0x8000 /* full duplex, switched ethernet */
-
- #define TCR_CLEAR 0 /* do NOTHING */
- /* the normal settings for the TCR register : */
-@@ -107,7 +108,10 @@
- #define CTL_CR_ENABLE 0x40
- #define CTL_TE_ENABLE 0x0020
- #define CTL_AUTO_RELEASE 0x0800
--#define CTL_EPROM_ACCESS 0x0003 /* high if Eprom is being read */
-+#define CTL_EPROM_SELECT 0x0004
-+#define CTL_EPROM_RELOAD 0x0002
-+#define CTL_EPROM_STORE 0x0001
-+#define CTL_EPROM_ACCESS (CTL_EPROM_RELOAD | CTL_EPROM_STORE) /* high if Eprom is being read */
-
- /* BANK 2 */
- #define MMU_CMD 0
-@@ -130,7 +134,6 @@
- #define PTR_READ 0x2000
- #define PTR_RCV 0x8000
- #define PTR_AUTOINC 0x4000
--#define PTR_AUTO_INC 0x0040
-
- #define DATA_1 8
- #define DATA_2 10
-@@ -162,17 +165,6 @@
- #define CHIP_9195 5
- #define CHIP_91100 7
-
--static const char * chip_ids[ 15 ] = {
-- NULL, NULL, NULL,
-- /* 3 */ "SMC91C90/91C92",
-- /* 4 */ "SMC91C94",
-- /* 5 */ "SMC91C95",
-- NULL,
-- /* 7 */ "SMC91C100",
-- /* 8 */ "SMC91C100FD",
-- NULL, NULL, NULL,
-- NULL, NULL, NULL};
--
- /*
- . Transmit status bits
- */
-@@ -192,40 +184,20 @@
- #define RS_MULTICAST 0x0001
- #define RS_ERRORS (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
-
--static const char * interfaces[ 2 ] = { "TP", "AUI" };
--
--/*-------------------------------------------------------------------------
-- . I define some macros to make it easier to do somewhat common
-- . or slightly complicated, repeated tasks.
-- --------------------------------------------------------------------------*/
--
--/* select a register bank, 0 to 3 */
--
--#define SMC_SELECT_BANK(x) { outw( x, ioaddr + BANK_SELECT ); }
--
--/* define a small delay for the reset */
--#define SMC_DELAY() { inw( ioaddr + RCR );\
-- inw( ioaddr + RCR );\
-- inw( ioaddr + RCR ); }
--
--/* this enables an interrupt in the interrupt mask register */
--#define SMC_ENABLE_INT(x) {\
-- unsigned char mask;\
-- SMC_SELECT_BANK(2);\
-- mask = inb( ioaddr + INT_MASK );\
-- mask |= (x);\
-- outb( mask, ioaddr + INT_MASK ); \
--}
--
--/* this disables an interrupt from the interrupt mask register */
-+/*
-+ * SMC91C96 ethernet config and status registers.
-+ * These are in the "attribute" space.
-+ */
-+#define ECOR 0x8000
-+#define ECOR_RESET 0x80
-+#define ECOR_LEVEL_IRQ 0x40
-+#define ECOR_WR_ATTRIB 0x04
-+#define ECOR_ENABLE 0x01
-
--#define SMC_DISABLE_INT(x) {\
-- unsigned char mask;\
-- SMC_SELECT_BANK(2);\
-- mask = inb( ioaddr + INT_MASK );\
-- mask &= ~(x);\
-- outb( mask, ioaddr + INT_MASK ); \
--}
-+#define ECSR 0x8002
-+#define ECSR_IOIS8 0x20
-+#define ECSR_PWRDWN 0x04
-+#define ECSR_INT 0x02
-
- /*----------------------------------------------------------------------
- . Define the interrupts that I want to receive from the card
-@@ -237,5 +209,36 @@
- --------------------------------------------------------------------------*/
- #define SMC_INTERRUPT_MASK (IM_EPH_INT | IM_RX_OVRN_INT | IM_RCV_INT)
-
-+/* store this information for the driver.. */
-+struct smc_local {
-+ /*
-+ these are things that the kernel wants me to keep, so users
-+ can find out semi-useless statistics of how well the card is
-+ performing
-+ */
-+ struct net_device_stats stats;
-+
-+ /*
-+ If I have to wait until memory is available to send
-+ a packet, I will store the skbuff here, until I get the
-+ desired memory. Then, I'll send it out and free it.
-+ */
-+ struct sk_buff * saved_skb;
-+
-+ /*
-+ . This keeps track of how many packets that I have
-+ . sent out. When an TX_EMPTY interrupt comes, I know
-+ . that all of these have been sent.
-+ */
-+ int packets_waiting;
-+
-+ /*
-+ . Interface status. These correspond to the parameters
-+ . in the ethtool_cmd structure.
-+ */
-+ u8 duplex;
-+ u8 port;
-+};
-+
- #endif /* _SMC_9194_H_ */
-
---- linux-2.4.25/drivers/parport/Config.in~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/parport/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -27,7 +27,8 @@
- dep_tristate ' Support for PCMCIA management for PC-style ports' CONFIG_PARPORT_PC_PCMCIA $CONFIG_PCMCIA $CONFIG_PARPORT_PC $CONFIG_HOTPLUG
- fi
- if [ "$CONFIG_ARM" = "y" ]; then
-- dep_tristate ' Archimedes hardware' CONFIG_PARPORT_ARC $CONFIG_PARPORT
-+ dep_tristate ' Archimedes hardware' CONFIG_PARPORT_ARC $CONFIG_PARPORT $CONFIG_ARCH_ARC
-+ dep_tristate ' Accelent SA1110 IDP' CONFIG_PARPORT_IDP $CONFIG_PARPORT $CONFIG_SA1100_ACCELENT
- fi
- if [ "$CONFIG_AMIGA" = "y" ]; then
- dep_tristate ' Amiga builtin port' CONFIG_PARPORT_AMIGA $CONFIG_PARPORT
---- linux-2.4.25/drivers/parport/Makefile~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/parport/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -29,6 +29,7 @@
- obj-$(CONFIG_PARPORT_ATARI) += parport_atari.o
- obj-$(CONFIG_PARPORT_SUNBPP) += parport_sunbpp.o
- obj-$(CONFIG_PARPORT_GSC) += parport_gsc.o
-+obj-$(CONFIG_PARPORT_IDP) += parport_idp.o
- obj-$(CONFIG_PARPORT_IP22) += parport_ip22.o
-
- include $(TOPDIR)/Rules.make
---- linux-2.4.25/drivers/parport/init.c~2.4.25-vrs2.patch 2002-11-29 00:53:14.000000000 +0100
-+++ linux-2.4.25/drivers/parport/init.c 2004-03-31 17:15:09.000000000 +0200
-@@ -164,6 +164,9 @@
- #ifdef CONFIG_PARPORT_SUNBPP
- parport_sunbpp_init();
- #endif
-+#ifdef CONFIG_PARPORT_IDP
-+ parport_idp_init();
-+#endif
- return 0;
- }
-
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/parport/parport_idp.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,247 @@
-+/* Low-level polled-mode parallel port routines for the Accelent IDP
-+ *
-+ * Author: Rich Dulabahn <rich@accelent.com>
-+ *
-+ * Inspiration taken from parport_amiga.c and parport_atari.c.
-+ *
-+ * To use, under menuconfig:
-+ * 1) Turn on <*> Accelent IDP under Parallel port setup
-+ * 2) Turn on <*> Parallel printer support under Character devices
-+ *
-+ * This will give you parport0 configured as /dev/lp0
-+ *
-+ * To make the correct /dev/lp* entries, enter /dev and type this:
-+ *
-+ * mknod lp0 c 6 0
-+ * mknod lp1 c 6 1
-+ * mknod lp2 c 6 2
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/parport.h>
-+#include <asm/hardware.h>
-+
-+/*
-+ * Parallel data port is port H, data
-+ * Parallel data direction is port H, direction
-+ * Control port is port I, data, lowest 4 bits
-+ * Status port is port G, data, upper 5 bits
-+ */
-+
-+#define INPUTPOWERHANDLER 0
-+/* masks */
-+#define CONTROL_MASK 0x0f
-+#define STATUS_MASK 0xf8
-+
-+#undef DEBUG
-+
-+#ifdef DEBUG
-+#define DPRINTK printk
-+#else
-+#define DPRINTK(stuff...)
-+#endif
-+
-+static struct parport *this_port = NULL;
-+
-+static unsigned char
-+parport_idp_read_data(struct parport *p)
-+{
-+ unsigned char c;
-+
-+ c = IDP_FPGA_PORTH_DATA;
-+ DPRINTK("read_data:0x%x\n",c);
-+ return c;
-+}
-+
-+static void
-+parport_idp_write_data(struct parport *p, unsigned char data)
-+{
-+ IDP_FPGA_PORTH_DATA = data;
-+ DPRINTK("write_data:0x%x\n",data);
-+}
-+
-+static unsigned char
-+parport_idp_read_control(struct parport *p)
-+{
-+ unsigned char c;
-+
-+ c = IDP_FPGA_PORTI_DATA & CONTROL_MASK;
-+ DPRINTK("read_control:0x%x\n",c);
-+ return c;
-+}
-+
-+static void
-+parport_idp_write_control(struct parport *p, unsigned char control)
-+{
-+ unsigned int temp;
-+
-+ temp = IDP_FPGA_PORTH_DATA;
-+ temp &= ~CONTROL_MASK;
-+ IDP_FPGA_PORTI_DATA = (temp | (control & CONTROL_MASK));
-+DPRINTK("write_control:0x%x\n",control);
-+}
-+
-+static unsigned char
-+parport_idp_frob_control(struct parport *p, unsigned char mask,
-+ unsigned char val)
-+{
-+ unsigned char c;
-+
-+/* From the parport-lowlevel.txt file...*/
-+/* This is equivalent to reading from the control register, masking out
-+the bits in mask, exclusive-or'ing with the bits in val, and writing
-+the result to the control register. */
-+
-+/* Easy enough, right? */
-+
-+ c = parport_idp_read_control(p);
-+ parport_idp_write_control(p, (c & ~mask) ^ val);
-+ DPRINTK("frob_control:0x%x\n",c);
-+ return c;
-+}
-+
-+static unsigned char
-+parport_idp_read_status(struct parport *p)
-+{
-+ unsigned char c;
-+
-+ c = IDP_FPGA_PORTG_DATA & STATUS_MASK;
-+ c ^= 0x80; /* toggle S7 bit, active low */
-+ DPRINTK("read_status:0x%x\n",c);
-+ return c;
-+}
-+
-+static void
-+parport_idp_init_state(struct pardevice *d, struct parport_state *s)
-+{
-+}
-+
-+static void
-+parport_idp_save_state(struct parport *p, struct parport_state *s)
-+{
-+}
-+
-+static void
-+parport_idp_restore_state(struct parport *p, struct parport_state *s)
-+{
-+}
-+
-+static void
-+parport_idp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+}
-+
-+static void
-+parport_idp_enable_irq(struct parport *p)
-+{
-+}
-+
-+static void
-+parport_idp_disable_irq(struct parport *p)
-+{
-+}
-+
-+static void
-+parport_idp_data_forward(struct parport *p)
-+{
-+ IDP_FPGA_PORTH_DIR = 0x00; /* 0 sets to output */
-+ DPRINTK("data_forward:0x%x\n",0);
-+}
-+
-+static void
-+parport_idp_data_reverse(struct parport *p)
-+{
-+ IDP_FPGA_PORTH_DIR = 0xff; /* and 1 sets to input */
-+ DPRINTK("data_reverse:0x%x\n",0xff);
-+}
-+
-+static void
-+parport_idp_inc_use_count(void)
-+{
-+ MOD_INC_USE_COUNT;
-+}
-+
-+static void
-+parport_idp_dec_use_count(void)
-+{
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static struct parport_operations parport_idp_ops = {
-+ parport_idp_write_data,
-+ parport_idp_read_data,
-+
-+ parport_idp_write_control,
-+ parport_idp_read_control,
-+ parport_idp_frob_control,
-+
-+ parport_idp_read_status,
-+
-+ parport_idp_enable_irq,
-+ parport_idp_disable_irq,
-+
-+ parport_idp_data_forward,
-+ parport_idp_data_reverse,
-+
-+ parport_idp_init_state,
-+ parport_idp_save_state,
-+ parport_idp_restore_state,
-+
-+ parport_idp_inc_use_count,
-+ parport_idp_dec_use_count,
-+
-+ parport_ieee1284_epp_write_data,
-+ parport_ieee1284_epp_read_data,
-+ parport_ieee1284_epp_write_addr,
-+ parport_ieee1284_epp_read_addr,
-+
-+ parport_ieee1284_ecp_write_data,
-+ parport_ieee1284_ecp_read_data,
-+ parport_ieee1284_ecp_write_addr,
-+
-+ parport_ieee1284_write_compat,
-+ parport_ieee1284_read_nibble,
-+ parport_ieee1284_read_byte,
-+};
-+
-+
-+int __init
-+parport_idp_init(void)
-+{
-+ struct parport *p;
-+
-+ p = parport_register_port((unsigned long)0,PARPORT_IRQ_NONE,PARPORT_DMA_NONE,&parport_idp_ops);
-+
-+ if (!p) return 0; /* return 0 on failure */
-+
-+ this_port=p;
-+ printk("%s: Accelent IDP parallel port registered.\n", p->name);
-+ parport_proc_register(p);
-+ parport_announce_port(p);
-+
-+ return 1;
-+}
-+
-+#ifdef MODULE
-+
-+MODULE_AUTHOR("Rich Dulabahn");
-+MODULE_DESCRIPTION("Parport Driver for Accelent IDP");
-+MODULE_SUPPORTED_DEVICE("Accelent IDP builtin Parallel Port");
-+MODULE_LICENSE("GPL");
-+
-+int
-+init_module(void)
-+{
-+ return parport_idp_init() ? 0 : -ENODEV;
-+}
-+
-+void
-+cleanup_module(void)
-+{
-+ parport_proc_unregister(this_port);
-+ parport_unregister_port(this_port);
-+}
-+#endif
-+
---- linux-2.4.25/drivers/pci/Makefile~2.4.25-vrs2.patch 2003-08-25 13:44:42.000000000 +0200
-+++ linux-2.4.25/drivers/pci/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -13,7 +13,7 @@
-
- export-objs := pci.o
-
--obj-$(CONFIG_PCI) += pci.o quirks.o compat.o names.o
-+obj-$(CONFIG_PCI) += pci.o quirks.o compat.o names.o bridge.o
- obj-$(CONFIG_PROC_FS) += proc.o
-
- ifndef CONFIG_SPARC64
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/pci/bridge.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,149 @@
-+
-+/*
-+ * Copyright (c) 2001 Red Hat, Inc. All rights reserved.
-+ *
-+ * This software may be freely redistributed under the terms
-+ * of the GNU public license.
-+ *
-+ * 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.
-+ *
-+ * Author: Arjan van de Ven <arjanv@redhat.com>
-+ *
-+ */
-+
-+
-+/*
-+ * Generic PCI driver for PCI bridges for powermanagement purposes
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/pci.h>
-+#include <linux/init.h>
-+
-+static struct pci_device_id bridge_pci_table[] __devinitdata = {
-+ {/* handle all PCI bridges */
-+ class: ((PCI_CLASS_BRIDGE_PCI << 8) | 0x00),
-+ class_mask: ~0,
-+ vendor: PCI_ANY_ID,
-+ device: PCI_ANY_ID,
-+ subvendor: PCI_ANY_ID,
-+ subdevice: PCI_ANY_ID,
-+ },
-+ {0,},
-+};
-+
-+static int bridge_probe(struct pci_dev *pdev, const struct pci_device_id *id);
-+static int pci_bridge_save_state_bus(struct pci_bus *bus, int force);
-+int pci_generic_resume_compare(struct pci_dev *pdev);
-+
-+int pci_bridge_force_restore = 0;
-+
-+
-+
-+
-+static int __init bridge_setup(char *str)
-+{
-+ if (!strcmp(str,"force"))
-+ pci_bridge_force_restore = 1;
-+ else if (!strcmp(str,"noforce"))
-+ pci_bridge_force_restore = 0;
-+ return 0;
-+}
-+
-+__setup("resume=",bridge_setup);
-+
-+
-+static int pci_bridge_save_state_bus(struct pci_bus *bus, int force)
-+{
-+ struct list_head *list;
-+ int error = 0;
-+
-+ list_for_each(list, &bus->children) {
-+ error = pci_bridge_save_state_bus(pci_bus_b(list),force);
-+ if (error) return error;
-+ }
-+ list_for_each(list, &bus->devices) {
-+ pci_generic_suspend_save(pci_dev_b(list),0);
-+ }
-+ return 0;
-+}
-+
-+
-+static int pci_bridge_restore_state_bus(struct pci_bus *bus, int force)
-+{
-+ struct list_head *list;
-+ int error = 0;
-+ static int printed_warning=0;
-+
-+ list_for_each(list, &bus->children) {
-+ error = pci_bridge_restore_state_bus(pci_bus_b(list),force);
-+ if (error) return error;
-+ }
-+ list_for_each(list, &bus->devices) {
-+ if (force)
-+ pci_generic_resume_restore(pci_dev_b(list));
-+ else {
-+ error = pci_generic_resume_compare(pci_dev_b(list));
-+ if (error && !printed_warning++) {
-+ printk(KERN_WARNING "resume warning: bios doesn't restore PCI state properly\n");
-+ printk(KERN_WARNING "resume warning: if resume failed, try booting with resume=force\n");
-+ }
-+ if (error)
-+ return error;
-+ }
-+ }
-+ return 0;
-+}
-+
-+static int bridge_suspend(struct pci_dev *dev, u32 force)
-+{
-+ pci_generic_suspend_save(dev,force);
-+ if (dev->subordinate)
-+ pci_bridge_save_state_bus(dev->subordinate,force);
-+ return 0;
-+}
-+
-+static int bridge_resume(struct pci_dev *dev)
-+{
-+
-+ pci_generic_resume_restore(dev);
-+ if (dev->subordinate)
-+ pci_bridge_restore_state_bus(dev->subordinate,pci_bridge_force_restore);
-+ return 0;
-+}
-+
-+
-+MODULE_DEVICE_TABLE(pci, bridge_pci_table);
-+static struct pci_driver bridge_ops = {
-+ name: "PCI Bridge",
-+ id_table: bridge_pci_table,
-+ probe: bridge_probe,
-+ suspend: bridge_suspend,
-+ resume: bridge_resume
-+};
-+
-+static int __devinit bridge_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-+{
-+ return 0;
-+}
-+
-+static int __init bridge_init(void)
-+{
-+ pci_register_driver(&bridge_ops);
-+ return 0;
-+}
-+
-+static void __exit bridge_exit(void)
-+{
-+ pci_unregister_driver(&bridge_ops);
-+}
-+
-+
-+module_init(bridge_init)
-+module_exit(bridge_exit)
-+
---- linux-2.4.25/drivers/pci/pci.c~2.4.25-vrs2.patch 2003-11-28 19:26:20.000000000 +0100
-+++ linux-2.4.25/drivers/pci/pci.c 2004-03-31 17:15:09.000000000 +0200
-@@ -359,6 +359,48 @@
- return 0;
- }
-
-+int
-+pci_compare_state(struct pci_dev *dev, u32 *buffer)
-+{
-+ int i;
-+ unsigned int temp;
-+
-+ if (buffer) {
-+ for (i = 0; i < 16; i++) {
-+ pci_read_config_dword(dev,i*4,&temp);
-+ if (temp!=buffer[i])
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
-+int pci_generic_suspend_save(struct pci_dev *pdev, u32 state)
-+{
-+ if (pdev)
-+ pci_save_state(pdev,pdev->saved_state);
-+ return 0;
-+}
-+
-+int pci_generic_resume_restore(struct pci_dev *pdev)
-+{
-+ if (pdev)
-+ pci_restore_state(pdev,pdev->saved_state);
-+ return 0;
-+}
-+
-+int pci_generic_resume_compare(struct pci_dev *pdev)
-+{
-+ int retval=0;
-+ if (pdev)
-+ retval = pci_compare_state(pdev,pdev->saved_state);
-+ return retval;
-+}
-+
-+EXPORT_SYMBOL(pci_generic_suspend_save);
-+EXPORT_SYMBOL(pci_generic_resume_restore);
-+EXPORT_SYMBOL(pci_generic_resume_compare);
-+
- /**
- * pci_enable_device_bars - Initialize some of a device for use
- * @dev: PCI device to be initialized
---- linux-2.4.25/drivers/pci/setup-bus.c~2.4.25-vrs2.patch 2003-06-13 16:51:35.000000000 +0200
-+++ linux-2.4.25/drivers/pci/setup-bus.c 2004-03-31 17:15:09.000000000 +0200
-@@ -12,6 +12,8 @@
- /*
- * Nov 2000, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
- * PCI-PCI bridges cleanup, sorted resource allocation.
-+ * May 2001, Russell King <rmk@arm.linux.org.uk>
-+ * Allocate prefetchable memory regions where available.
- * Feb 2002, Ivan Kokshaysky <ink@jurassic.park.msu.ru>
- * Converted to allocation in 3 passes, which gives
- * tighter packing. Prefetchable range support.
-@@ -160,8 +162,10 @@
- pci_write_config_dword(bridge, PCI_PREF_MEMORY_BASE, l);
-
- /* Check if we have VGA behind the bridge.
-- Enable ISA in either case (FIXME!). */
-- l = (bus->resource[0]->flags & IORESOURCE_BUS_HAS_VGA) ? 0x0c : 0x04;
-+ Enable ISA in either case. */
-+ l = (bus->resource[0]->flags & IORESOURCE_BUS_HAS_VGA) ?
-+ PCI_BRIDGE_CTL_VGA | PCI_BRIDGE_CTL_NO_ISA :
-+ PCI_BRIDGE_CTL_NO_ISA;
- pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, l);
- }
-
---- linux-2.4.25/drivers/pcmcia/Config.in~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/pcmcia/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -14,21 +14,19 @@
-
- tristate 'PCMCIA/CardBus support' CONFIG_PCMCIA
- if [ "$CONFIG_PCMCIA" != "n" ]; then
-+ # yes, I really mean the following...
-+ if [ "$CONFIG_ISA" = "y" -o "$CONFIG_ARCH_SA1100" = "y" ]; then
-+ define_bool CONFIG_PCMCIA_PROBE y
-+ fi
- if [ "$CONFIG_PCI" != "n" ]; then
- bool ' CardBus support' CONFIG_CARDBUS
- fi
-+ dep_bool ' i82092 compatible bridge support' CONFIG_I82092 $CONFIG_PCI
-+ bool ' i82365 compatible bridge support' CONFIG_I82365
- bool ' Databook TCIC host bridge support' CONFIG_TCIC
- if [ "$CONFIG_HD64465" = "y" ]; then
- dep_tristate ' HD64465 host bridge support' CONFIG_HD64465_PCMCIA $CONFIG_PCMCIA
- fi
-- dep_bool ' i82092 compatible bridge support' CONFIG_I82092 $CONFIG_PCI
-- bool ' i82365 compatible bridge support' CONFIG_I82365
-- if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
-- dep_tristate ' SA1100 support' CONFIG_PCMCIA_SA1100 $CONFIG_PCMCIA
-- fi
-- if [ "$CONFIG_8xx" = "y" ]; then
-- dep_tristate ' M8xx support' CONFIG_PCMCIA_M8XX $CONFIG_PCMCIA
-- fi
- if [ "$CONFIG_SOC_AU1X00" = "y" ]; then
- dep_tristate ' Au1x00 PCMCIA support' CONFIG_PCMCIA_AU1X00 $CONFIG_PCMCIA
- if [ "$CONFIG_PCMCIA_AU1X00" != "n" ]; then
-@@ -44,5 +42,9 @@
- dep_tristate ' NEC VRC4173 CARDU support' CONFIG_PCMCIA_VRC4173 $CONFIG_PCMCIA
- fi
- fi
-+if [ "$CONFIG_ARM" = "y" ]; then
-+ dep_tristate ' CLPS6700 support' CONFIG_PCMCIA_CLPS6700 $CONFIG_ARCH_CLPS711X $CONFIG_PCMCIA
-+ dep_tristate ' SA1100 support' CONFIG_PCMCIA_SA1100 $CONFIG_ARCH_SA1100 $CONFIG_PCMCIA
-+fi
-
- endmenu
---- linux-2.4.25/drivers/pcmcia/Makefile~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/pcmcia/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -65,15 +65,18 @@
- au1000_ss-objs-$(CONFIG_PCMCIA_DB1X00) += au1000_db1x00.o
- au1000_ss-objs-$(CONFIG_PCMCIA_XXS1500) += au1000_xxs1500.o
-
-+obj-$(CONFIG_PCMCIA_CLPS6700) += clps6700.o
- obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o
--obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
- obj-$(CONFIG_PCMCIA_SIBYTE) += sibyte_generic.o
-
- sa1100_cs-objs-y := sa1100_generic.o
-+sa1100_cs-objs-$(CONFIG_SA1100_ADSAGC) += sa1100_graphicsmaster.o sa1111_generic.o
- sa1100_cs-objs-$(CONFIG_SA1100_ADSBITSY) += sa1100_adsbitsy.o sa1111_generic.o
-+sa1100_cs-objs-$(CONFIG_SA1100_ADSBITSYPLUS) += sa1100_adsbitsyplus.o sa1111_generic.o
- sa1100_cs-objs-$(CONFIG_SA1100_ASSABET) += sa1100_assabet.o
- sa1100_cs-objs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o sa1111_generic.o
- sa1100_cs-objs-$(CONFIG_SA1100_BADGE4) += sa1100_badge4.o sa1111_generic.o
-+sa1100_cs-objs-$(CONFIG_SA1100_CONSUS) += sa1100_neponset.o sa1111_generic.o
- sa1100_cs-objs-$(CONFIG_SA1100_CERF) += sa1100_cerf.o
- sa1100_cs-objs-$(CONFIG_SA1100_FLEXANET) += sa1100_flexanet.o
- sa1100_cs-objs-$(CONFIG_SA1100_FREEBIRD) += sa1100_freebird.o
---- linux-2.4.25/drivers/pcmcia/cistpl.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/pcmcia/cistpl.c 2004-03-31 17:15:09.000000000 +0200
-@@ -286,7 +286,7 @@
- s->cis_mem.flags &= ~MAP_ACTIVE;
- s->ss_entry->set_mem_map(s->sock, &s->cis_mem);
- if (!(s->cap.features & SS_CAP_STATIC_MAP))
-- release_mem_region(s->cis_mem.sys_start, s->cap.map_size);
-+ release_mem_resource(s->cis_mem.sys_start, s->cap.map_size);
- bus_iounmap(s->cap.bus, s->cis_virt);
- s->cis_mem.sys_start = 0;
- s->cis_virt = NULL;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/clps6700.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,498 @@
-+/*
-+ * linux/drivers/pcmcia/clps6700.c
-+ *
-+ * Copyright (C) 2000 Deep Blue Solutions Ltd
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+#include <linux/proc_fs.h>
-+#include <linux/spinlock.h>
-+#include <linux/init.h>
-+
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/hardware.h>
-+#include <asm/page.h>
-+
-+#include <asm/arch/syspld.h>
-+#include <asm/hardware/clps7111.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/ss.h>
-+
-+#include "clps6700.h"
-+
-+#define DEBUG
-+
-+MODULE_AUTHOR("Russell King");
-+MODULE_DESCRIPTION("CL-PS6700 PCMCIA socket driver");
-+
-+#define NR_CLPS6700 2
-+
-+struct clps6700_skt {
-+ u_int nr;
-+ u_int physbase;
-+ u_int regbase;
-+ u_int pmr;
-+ u_int cpcr;
-+ u_int cpcr_3v3;
-+ u_int cpcr_5v0;
-+ u_int cur_pmr;
-+ u_int cur_cicr;
-+ u_int cur_pcimr;
-+ u_int cur_cpcr;
-+ void (*handler)(void *, u_int);
-+ void *handler_info;
-+
-+ u_int ev_pending;
-+ spinlock_t ev_lock;
-+};
-+
-+static struct clps6700_skt *skts[NR_CLPS6700];
-+
-+static int clps6700_sock_init(u_int sock)
-+{
-+ struct clps6700_skt *skt = skts[sock];
-+
-+ skt->cur_cicr = 0;
-+ skt->cur_pmr = skt->pmr;
-+ skt->cur_pcimr = 0;
-+ skt->cur_cpcr = skt->cpcr;
-+
-+#ifdef DEBUG
-+ printk("skt%d: sock_init()\n", sock);
-+#endif
-+
-+ __raw_writel(skt->cur_pmr, skt->regbase + PMR);
-+ __raw_writel(skt->cur_cpcr, skt->regbase + CPCR);
-+ __raw_writel(0x01f8, skt->regbase + SICR);
-+ __raw_writel(0x0000, skt->regbase + DMACR);
-+ __raw_writel(skt->cur_cicr, skt->regbase + CICR);
-+ __raw_writel(0x1f00, skt->regbase + CITR0A);
-+ __raw_writel(0x0000, skt->regbase + CITR0B);
-+ __raw_writel(0x1f00, skt->regbase + CITR1A);
-+ __raw_writel(0x0000, skt->regbase + CITR1B);
-+ __raw_writel(skt->cur_pcimr, skt->regbase + PCIMR);
-+
-+ /*
-+ * Enable Auto Idle Mode in PM register
-+ */
-+ __raw_writel(-1, skt->regbase + PCIRR1);
-+ __raw_writel(-1, skt->regbase + PCIRR2);
-+ __raw_writel(-1, skt->regbase + PCIRR3);
-+
-+ return 0;
-+}
-+
-+static int clps6700_suspend(u_int sock)
-+{
-+ return 0;
-+}
-+
-+static int clps6700_register_callback(u_int sock, void (*handler)(void *, u_int), void *info)
-+{
-+ struct clps6700_skt *skt = skts[sock];
-+
-+#ifdef DEBUG
-+ printk("skt%d: register_callback: %p (%p)\n", sock, handler, info);
-+#endif
-+
-+ skt->handler_info = info;
-+ skt->handler = handler;
-+
-+ return 0;
-+}
-+
-+static int clps6700_inquire_socket(u_int sock, socket_cap_t *cap)
-+{
-+ cap->features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP | SS_CAP_MEM_ALIGN;
-+ cap->irq_mask = 0; /* available IRQs for this socket */
-+ cap->map_size = PAGE_SIZE; /* minimum mapping size */
-+ cap->pci_irq = 0; /* PCI interrupt number */
-+ cap->cb_dev = NULL;
-+ cap->bus = NULL;
-+ return 0;
-+}
-+
-+static int __clps6700_get_status(struct clps6700_skt *skt)
-+{
-+ unsigned int v, val;
-+
-+ v = __raw_readl(skt->regbase + PCIILR);
-+ val = 0;
-+ if ((v & (PCM_CD1 | PCM_CD2)) == 0)
-+ val |= SS_DETECT;
-+ if ((v & (PCM_BVD2 | PCM_BVD1)) == PCM_BVD1)
-+ val |= SS_BATWARN;
-+ if ((v & PCM_BVD2) == 0)
-+ val |= SS_BATDEAD;
-+
-+ if (v & PCM_RDYL)
-+ val |= SS_READY;
-+ if (v & PCM_VS1)
-+ val |= SS_3VCARD;
-+ if (v & PCM_VS2)
-+ val |= SS_XVCARD;
-+
-+#ifdef DEBUG
-+ printk("skt%d: PCIILR: %08x -> (%s %s %s %s %s %s)\n",
-+ skt->nr, v,
-+ val & SS_READY ? "rdy" : "---",
-+ val & SS_DETECT ? "det" : "---",
-+ val & SS_BATWARN ? "bw" : "--",
-+ val & SS_BATDEAD ? "bd" : "--",
-+ val & SS_3VCARD ? "3v" : "--",
-+ val & SS_XVCARD ? "xv" : "--");
-+#endif
-+ return val;
-+}
-+
-+static int clps6700_get_status(u_int sock, u_int *valp)
-+{
-+ struct clps6700_skt *skt = skts[sock];
-+
-+ *valp = __clps6700_get_status(skt);
-+
-+ return 0; /* not used! */
-+}
-+
-+static int clps6700_get_socket(u_int sock, socket_state_t *state)
-+{
-+ return -EINVAL;
-+}
-+
-+static int clps6700_set_socket(u_int sock, socket_state_t *state)
-+{
-+ struct clps6700_skt *skt = skts[sock];
-+ unsigned long flags;
-+ u_int cpcr = skt->cur_cpcr, pmr = skt->cur_pmr, cicr = skt->cur_cicr;
-+ u_int pcimr = 0;
-+
-+ cicr &= ~(CICR_ENABLE | CICR_RESET | CICR_IOMODE);
-+
-+ if (state->flags & SS_PWR_AUTO)
-+ pmr |= PMR_DCAR | PMR_PDCR;
-+
-+ /*
-+ * Note! We must NOT assert the Card Enable bit until reset has
-+ * been de-asserted. Some cards indicate not ready, which then
-+ * hangs our next access. (Bug in CLPS6700?)
-+ */
-+ if (state->flags & SS_RESET)
-+ cicr |= CICR_RESET | CICR_RESETOE;
-+ else if (state->flags & SS_OUTPUT_ENA)
-+ cicr |= CICR_ENABLE;
-+
-+ if (state->flags & SS_IOCARD) {
-+ cicr |= CICR_IOMODE;
-+
-+/* if (state->csc_mask & SS_STSCHG)*/
-+ } else {
-+ if (state->csc_mask & SS_BATDEAD)
-+ pcimr |= PCM_BVD2;
-+ if (state->csc_mask & SS_BATWARN)
-+ pcimr |= PCM_BVD1;
-+ if (state->csc_mask & SS_READY)
-+ pcimr |= PCM_RDYL;
-+ }
-+
-+ if (state->csc_mask & SS_DETECT)
-+ pcimr |= PCM_CD1 | PCM_CD2;
-+
-+ switch (state->Vcc) {
-+ case 0: break;
-+ case 33: cpcr |= skt->cpcr_3v3; pmr |= PMR_CPE; break;
-+ case 50: cpcr |= skt->cpcr_5v0; pmr |= PMR_CPE; break;
-+ default: return -EINVAL;
-+ }
-+
-+#ifdef DEBUG
-+ printk("skt%d: PMR: %04x, CPCR: %04x, CICR: %04x PCIMR: %04x "
-+ "(Vcc = %d, flags = %c%c%c%c, csc = %c%c%c%c%c)\n",
-+ sock, pmr, cpcr, cicr, pcimr, state->Vcc,
-+ state->flags & SS_RESET ? 'r' : '-',
-+ state->flags & SS_PWR_AUTO ? 'p' : '-',
-+ state->flags & SS_IOCARD ? 'i' : '-',
-+ state->flags & SS_OUTPUT_ENA ? 'o' : '-',
-+ state->csc_mask & SS_STSCHG ? 's' : '-',
-+ state->csc_mask & SS_BATDEAD ? 'd' : '-',
-+ state->csc_mask & SS_BATWARN ? 'w' : '-',
-+ state->csc_mask & SS_READY ? 'r' : '-',
-+ state->csc_mask & SS_DETECT ? 'c' : '-');
-+#endif
-+
-+ save_flags_cli(flags);
-+
-+ if (skt->cur_cpcr != cpcr) {
-+ skt->cur_cpcr = cpcr;
-+ __raw_writel(skt->cur_cpcr, skt->regbase + CPCR);
-+ }
-+
-+ if (skt->cur_pmr != pmr) {
-+ skt->cur_pmr = pmr;
-+ __raw_writel(skt->cur_pmr, skt->regbase + PMR);
-+ }
-+ if (skt->cur_pcimr != pcimr) {
-+ skt->cur_pcimr = pcimr;
-+ __raw_writel(skt->cur_pcimr, skt->regbase + PCIMR);
-+ }
-+ if (skt->cur_cicr != cicr) {
-+ skt->cur_cicr = cicr;
-+ __raw_writel(skt->cur_cicr, skt->regbase + CICR);
-+ }
-+
-+ restore_flags(flags);
-+
-+ return 0;
-+}
-+
-+static int clps6700_get_io_map(u_int sock, struct pccard_io_map *io)
-+{
-+ return -EINVAL;
-+}
-+
-+static int clps6700_set_io_map(u_int sock, struct pccard_io_map *io)
-+{
-+ printk("skt%d: iomap: %d: speed %d, flags %X start %X stop %X\n",
-+ sock, io->map, io->speed, io->flags, io->start, io->stop);
-+ return 0;
-+}
-+
-+static int clps6700_get_mem_map(u_int sock, struct pccard_mem_map *mem)
-+{
-+ return -EINVAL;
-+}
-+
-+/*
-+ * Set the memory map attributes for this socket. (ie, mem->speed)
-+ * Note that since we have SS_CAP_STATIC_MAP set, we don't need to do
-+ * any mapping here at all; we just need to return the address (suitable
-+ * for ioremap) to map the requested space in mem->sys_start.
-+ *
-+ * flags & MAP_ATTRIB indicates whether we want attribute space.
-+ */
-+static int clps6700_set_mem_map(u_int sock, struct pccard_mem_map *mem)
-+{
-+ struct clps6700_skt *skt = skts[sock];
-+ u_int off;
-+
-+ printk("skt%d: memmap: %d: speed %d, flags %X start %lX stop %lX card %X\n",
-+ sock, mem->map, mem->speed, mem->flags, mem->sys_start,
-+ mem->sys_stop, mem->card_start);
-+
-+ if (mem->flags & MAP_ATTRIB)
-+ off = CLPS6700_ATTRIB_BASE;
-+ else
-+ off = CLPS6700_MEM_BASE;
-+
-+ mem->sys_start = skt->physbase + off;
-+ mem->sys_start += mem->card_start;
-+
-+ return 0;
-+}
-+
-+static void clps6700_proc_setup(u_int sock, struct proc_dir_entry *base)
-+{
-+}
-+
-+static struct pccard_operations clps6700_operations = {
-+ init: clps6700_sock_init,
-+ suspend: clps6700_suspend,
-+ register_callback: clps6700_register_callback,
-+ inquire_socket: clps6700_inquire_socket,
-+ get_status: clps6700_get_status,
-+ get_socket: clps6700_get_socket,
-+ set_socket: clps6700_set_socket,
-+ get_io_map: clps6700_get_io_map,
-+ set_io_map: clps6700_set_io_map,
-+ get_mem_map: clps6700_get_mem_map,
-+ set_mem_map: clps6700_set_mem_map,
-+ proc_setup: clps6700_proc_setup
-+};
-+
-+static void clps6700_bh(void *dummy)
-+{
-+ int i;
-+
-+ for (i = 0; i < NR_CLPS6700; i++) {
-+ struct clps6700_skt *skt = skts[i];
-+ unsigned long flags;
-+ u_int events;
-+
-+ if (!skt)
-+ continue;
-+
-+ /*
-+ * Note! We must read the pending event state
-+ * with interrupts disabled, otherwise we race
-+ * with our own interrupt routine!
-+ */
-+ spin_lock_irqsave(&skt->ev_lock, flags);
-+ events = skt->ev_pending;
-+ skt->ev_pending = 0;
-+ spin_unlock_irqrestore(&skt->ev_lock, flags);
-+
-+ if (skt->handler && events)
-+ skt->handler(skt->handler_info, events);
-+ }
-+}
-+
-+static struct tq_struct clps6700_task = {
-+ routine: clps6700_bh
-+};
-+
-+static void clps6700_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct clps6700_skt *skt = dev_id;
-+ u_int val, events;
-+
-+ val = __raw_readl(skt->regbase + PCISR);
-+ if (!val)
-+ return;
-+
-+ __raw_writel(val, skt->regbase + PCICR);
-+
-+ events = 0;
-+ if (val & (PCM_CD1 | PCM_CD2))
-+ events |= SS_DETECT;
-+ if (val & PCM_BVD1)
-+ events |= SS_BATWARN;
-+ if (val & PCM_BVD2)
-+ events |= SS_BATDEAD;
-+ if (val & PCM_RDYL)
-+ events |= SS_READY;
-+
-+ spin_lock(&skt->ev_lock);
-+ skt->ev_pending |= events;
-+ spin_unlock(&skt->ev_lock);
-+ schedule_task(&clps6700_task);
-+}
-+
-+static int __init clps6700_init_skt(int nr)
-+{
-+ struct clps6700_skt *skt;
-+ int ret;
-+
-+ skt = kmalloc(sizeof(struct clps6700_skt), GFP_KERNEL);
-+ if (!skt)
-+ return -ENOMEM;
-+
-+ memset(skt, 0, sizeof(struct clps6700_skt));
-+
-+ spin_lock_init(&skt->ev_lock);
-+
-+ skt->nr = nr;
-+ skt->physbase = nr ? CS5_PHYS_BASE : CS4_PHYS_BASE;
-+ skt->pmr = PMR_AUTOIDLE | PMR_MCPE | PMR_CDWEAK;
-+ skt->cpcr = CPCR_PDIR(PCTL1|PCTL0);
-+ skt->cpcr_3v3 = CPCR_PON(PCTL0);
-+ skt->cpcr_5v0 = CPCR_PON(PCTL0); /* we only do 3v3 */
-+
-+ skt->cur_pmr = skt->pmr;
-+
-+ skt->regbase = (u_int)ioremap(skt->physbase + CLPS6700_REG_BASE,
-+ CLPS6700_REG_SIZE);
-+ ret = -ENOMEM;
-+ if (!skt->regbase)
-+ goto err_free;
-+
-+ skts[nr] = skt;
-+
-+ ret = request_irq(IRQ_EINT3, clps6700_interrupt,
-+ SA_SHIRQ, "pcmcia", skt);
-+
-+ if (ret) {
-+ printk(KERN_ERR "clps6700: unable to grab irq%d (%d)\n",
-+ IRQ_EINT3, ret);
-+ goto err_unmap;
-+ }
-+ return 0;
-+
-+err_unmap:
-+ iounmap((void *)skt->regbase);
-+err_free:
-+ kfree(skt);
-+ skts[nr] = NULL;
-+ return ret;
-+}
-+
-+static void clps6700_free_resources(void)
-+{
-+ int i;
-+
-+ for (i = NR_CLPS6700; i >= 0; i--) {
-+ struct clps6700_skt *skt = skts[i];
-+
-+ skts[i] = NULL;
-+ if (skt == NULL)
-+ continue;
-+
-+ free_irq(IRQ_EINT3, skt);
-+ if (skt->regbase) {
-+ __raw_writel(skt->pmr, skt->regbase + PMR);
-+ __raw_writel(skt->cpcr, skt->regbase + CPCR);
-+ __raw_writel(0, skt->regbase + CICR);
-+ __raw_writel(0, skt->regbase + PCIMR);
-+ }
-+ iounmap((void *)skt->regbase);
-+ kfree(skt);
-+ }
-+}
-+
-+static int __init clps6700_init(void)
-+{
-+ unsigned int v;
-+ int err, nr;
-+
-+ PLD_CF = 0;
-+ v = clps_readl(SYSCON2) | SYSCON2_PCCARD1 | SYSCON2_PCCARD2;
-+ clps_writel(v, SYSCON2);
-+ v = clps_readl(SYSCON1) | SYSCON1_EXCKEN;
-+ clps_writel(v, SYSCON1);
-+
-+ for (nr = 0; nr < NR_CLPS6700; nr++) {
-+ err = clps6700_init_skt(nr);
-+ if (err)
-+ goto free;
-+ }
-+
-+ err = register_ss_entry(nr, &clps6700_operations);
-+ if (err)
-+ goto free;
-+
-+ return 0;
-+
-+free:
-+ clps6700_free_resources();
-+ /*
-+ * An error occurred. Unmap and free all CLPS6700
-+ */
-+ return err;
-+}
-+
-+static void __exit clps6700_exit(void)
-+{
-+ unregister_ss_entry(&clps6700_operations);
-+ clps6700_free_resources();
-+}
-+
-+module_init(clps6700_init);
-+module_exit(clps6700_exit);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/clps6700.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,85 @@
-+#define PCISR 0x0000 /* PC Card Interrupt Status Register */
-+#define PCIMR 0x0400 /* PC Card Interrupt Mask Register */
-+#define PCICR 0x0800 /* PC Card Interrupt Clear Register */
-+#define PCIOSR 0x0c00 /* PC Card Interrupt Output Select Regsiter */
-+#define PCIRR1 0x1000 /* PC Card Interrupt Reserved Register 1 */
-+#define PCIRR2 0x1400 /* PC Card Interrupt Reserved Register 2 */
-+#define PCIRR3 0x1800 /* PC Card Interrupt Reserved Register 3 */
-+#define PCIILR 0x1c00 /* PC Card Interrupt Input Level Register */
-+#define SICR 0x2000 /* System Interface Configuration Register */
-+#define CICR 0x2400 /* Card Interface Configuration Register */
-+#define PMR 0x2800 /* Power Management Register */
-+#define CPCR 0x2c00 /* Card Power Control Register */
-+#define CITR0A 0x3000 /* Card Interface Timing Register 0A */
-+#define CITR0B 0x3400 /* Card Interface Timing Register 0B */
-+#define CITR1A 0x3800 /* Card Interface Timing Register 1A */
-+#define CITR1B 0x3c00 /* Card Interface Timing Register 1B */
-+#define DMACR 0x4000 /* DMA Control Register */
-+#define DIR 0x4400 /* Device Information Register */
-+
-+#define CLPS6700_ATTRIB_BASE 0x00000000
-+#define CLPS6700_IO_BASE 0x04000000
-+#define CLPS6700_MEM_BASE 0x08000000
-+#define CLPS6700_REG_BASE 0x0c000000
-+#define CLPS6700_REG_SIZE 0x00005000
-+
-+
-+#define PMR_AUTOIDLE (1 << 0) /* auto idle mode */
-+#define PMR_FORCEIDLE (1 << 1) /* force idle mode */
-+#define PMR_PDCS (1 << 2) /* Power down card on standby */
-+#define PMR_PDCR (1 << 3) /* Power down card on removal */
-+#define PMR_DCAR (1 << 4) /* Disable card access on removal */
-+#define PMR_CPE (1 << 5) /* Card power enable */
-+#define PMR_MCPE (1 << 6) /* Monitor card power enable */
-+#define PMR_PDREQLSEL (1 << 7) /* If set, PDREQL is a GPIO pin */
-+#define PMR_DISSTBY (1 << 8) /* Disable standby */
-+#define PMR_ACCSTBY (1 << 9) /* Complete card accesses before standby*/
-+#define PMR_CDUNPROT (0 << 10) /* Card detect inputs unprotected */
-+#define PMR_CDPROT (1 << 10) /* Card detect inputs protected */
-+#define PMR_CDWEAK (2 << 10) /* Weak pullup except in standby */
-+#define PMR_CDWEAKAL (3 << 10) /* Weak pullup */
-+
-+#define CPCR_PON(x) ((x)&7) /* PCTL[2:0] value when PMR_CPE = 1 */
-+#define CPCR_POFF(x) (((x)&7)<<3) /* PCTL[2:0] value when PMR_CPE = 0 */
-+#define CPCR_PDIR(x) (((x)&7)<<6) /* PCTL[2:0] direction */
-+#define CPCR_CON(x) (((x)&1)<<9) /* GPIO value when PMR_CPE = 1 */
-+#define CPCR_COFF(x) (((x)&1)<<10) /* GPIO value when PMR_CPE = 0 */
-+#define CPCR_CDIR(x) (((x)&1)<<11) /* GPIO direction (PMR_PDREQLSEL = 1) */
-+#define CPCR_VS(x) (((x)&3)<<12) /* VS[2:1] output value */
-+#define CPCR_VSDIR(x) (((x)&3)<<14) /* VS[2:1] direction */
-+
-+#define PCTL0 (1 << 0)
-+#define PCTL1 (1 << 1)
-+#define PCTL2 (1 << 2)
-+
-+#define CICR_ASRTMR1 (1 << 0) /* Timer 1 select for attribute read */
-+#define CICR_ASWTMR1 (1 << 1) /* Timer 1 select for attribute write */
-+#define CICR_IOSRTMR1 (1 << 2) /* Timer 1 select for IO read */
-+#define CICR_IOSWTMR1 (1 << 3) /* Timer 1 select for IO write */
-+#define CICR_MEMSRTMR1 (1 << 4) /* Timer 1 select for memory read */
-+#define CICR_MEMSWTMR1 (1 << 5) /* Timer 1 select for memory write */
-+#define CICR_AUTOIOSZ (1 << 6) /* Auto size I/O accesses */
-+#define CICR_CAW (1 << 7) /* Card access width */
-+#define CICR_IOMODE (1 << 8) /* IO mode select */
-+#define CICR_ENABLE (1 << 10) /* Card enable */
-+#define CICR_RESETOE (1 << 11) /* Card reset output enable */
-+#define CICR_RESET (1 << 12) /* Card reset */
-+
-+
-+#define RD_FAIL (1 << 14)
-+#define WR_FAIL (1 << 13)
-+#define IDLE (1 << 12)
-+
-+#define FFOTHLD (1 << 11)
-+#define PCM_RDYL (1 << 10)
-+#define PCM_WP (1 << 9)
-+#define PCTL (1 << 8)
-+
-+#define PDREQ_L (1 << 6)
-+#define PCM_VS2 (1 << 5)
-+#define PCM_VS1 (1 << 4)
-+
-+#define PCM_CD2 (1 << 3)
-+#define PCM_CD1 (1 << 2)
-+#define PCM_BVD2 (1 << 1)
-+#define PCM_BVD1 (1 << 0)
---- linux-2.4.25/drivers/pcmcia/cs.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/pcmcia/cs.c 2004-03-31 17:15:09.000000000 +0200
-@@ -3,7 +3,7 @@
- Kernel Card Services -- core services
-
- cs.c 1.271 2000/10/02 20:27:49
--
-+
- The contents of this file are subject to the Mozilla Public
- License Version 1.1 (the "License"); you may not use this file
- except in compliance with the License. You may obtain a copy of
-@@ -28,7 +28,7 @@
- and other provisions required by the GPL. If you do not delete
- the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
--
-+
- ======================================================================*/
-
- #include <linux/module.h>
-@@ -92,7 +92,7 @@
- MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
- MODULE_DESCRIPTION("Linux Kernel Card Services " CS_RELEASE
- "\n options:" OPTIONS);
--MODULE_LICENSE("Dual MPL/GPL");
-+MODULE_LICENSE("Dual MPL/GPL");
-
- #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
-
-@@ -123,7 +123,7 @@
- static const char *version =
- "cs.c 1.279 2001/10/13 00:08:28 (David Hinds)";
- #endif
--
-+
- /*====================================================================*/
-
- socket_state_t dead_socket = {
-@@ -299,7 +299,7 @@
-
- Low-level PC Card interface drivers need to register with Card
- Services using these calls.
--
-+
- ======================================================================*/
-
- static int setup_socket(socket_info_t *);
-@@ -331,7 +331,7 @@
- s->use_bus_pm = use_bus_pm;
- s->erase_busy.next = s->erase_busy.prev = &s->erase_busy;
- spin_lock_init(&s->lock);
--
-+
- for (i = 0; i < sockets; i++)
- if (socket_table[i] == NULL) break;
- socket_table[i] = s;
-@@ -365,7 +365,7 @@
- for (ns = 0; ns < nsock; ns++) {
- pcmcia_register_socket (ns, ss_entry, 0);
- }
--
-+
- return 0;
- } /* register_ss_entry */
-
-@@ -457,7 +457,7 @@
- static void shutdown_socket(socket_info_t *s)
- {
- client_t **c;
--
-+
- DEBUG(1, "cs: shutdown_socket(%p)\n", s);
-
- /* Blank out the socket state */
-@@ -561,7 +561,7 @@
- have several causes: card insertion, a call to reset_socket, or
- recovery from a suspend/resume cycle. Unreset_socket() sends
- a CS event that matches the cause of the reset.
--
-+
- ======================================================================*/
-
- static void reset_socket(socket_info_t *s)
-@@ -616,7 +616,7 @@
- s->state &= ~SOCKET_SETUP_PENDING;
- } else {
- send_event(s, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
-- if (s->reset_handle) {
-+ if (s->reset_handle) {
- s->reset_handle->event_callback_args.info = NULL;
- EVENT(s->reset_handle, CS_EVENT_RESET_COMPLETE,
- CS_EVENT_PRI_LOW);
-@@ -631,7 +631,7 @@
- valid clients. Parse_events() interprets the event bits from
- a card status change report. Do_shutdown() handles the high
- priority stuff associated with a card removal.
--
-+
- ======================================================================*/
-
- static int send_event(socket_info_t *s, event_t event, int priority)
-@@ -641,7 +641,7 @@
- DEBUG(1, "cs: send_event(sock %d, event %d, pri %d)\n",
- s->sock, event, priority);
- ret = 0;
-- for (; client; client = client->next) {
-+ for (; client; client = client->next) {
- if (client->state & (CLIENT_UNBOUND|CLIENT_STALE))
- continue;
- if (client->EventMask & event) {
-@@ -675,10 +675,17 @@
- static void parse_events(void *info, u_int events)
- {
- socket_info_t *s = info;
-+
- if (events & SS_DETECT) {
- int status;
-
- get_socket_status(s, &status);
-+
-+ /*
-+ * If our socket state indicates that a card is present and
-+ * either the socket has not been suspended (for some reason)
-+ * or the card has been removed, shut down the socket first.
-+ */
- if ((s->state & SOCKET_PRESENT) &&
- (!(s->state & SOCKET_SUSPEND) ||
- !(status & SS_DETECT)))
-@@ -716,7 +723,7 @@
-
- This does not comply with the latest PC Card spec for handling
- power management events.
--
-+
- ======================================================================*/
-
- void pcmcia_suspend_socket (socket_info_t *s)
-@@ -773,7 +780,7 @@
- /*======================================================================
-
- Special stuff for managing IO windows, because they are scarce.
--
-+
- ======================================================================*/
-
- static int alloc_io_space(socket_info_t *s, u_int attr, ioaddr_t *base,
-@@ -862,7 +869,7 @@
- Access_configuration_register() reads and writes configuration
- registers in attribute memory. Memory window 0 is reserved for
- this and the tuple reading services.
--
-+
- ======================================================================*/
-
- int pcmcia_access_configuration_register(client_handle_t handle,
-@@ -872,7 +879,7 @@
- config_t *c;
- int addr;
- u_char val;
--
-+
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
-@@ -890,7 +897,7 @@
- return CS_CONFIGURATION_LOCKED;
-
- addr = (c->ConfigBase + reg->Offset) >> 1;
--
-+
- switch (reg->Action) {
- case CS_READ:
- read_cis_mem(s, 1, addr, 1, &val);
-@@ -913,7 +920,7 @@
- It is normally called by Driver Services after it has identified
- a newly inserted card. An instance of that driver will then be
- eligible to register as a client of this socket.
--
-+
- ======================================================================*/
-
- int pcmcia_bind_device(bind_req_t *req)
-@@ -949,23 +956,23 @@
- region. It is normally called by Driver Services after it has
- identified a memory device type. An instance of the corresponding
- driver will then be able to register to control this region.
--
-+
- ======================================================================*/
-
- int pcmcia_bind_mtd(mtd_bind_t *req)
- {
- socket_info_t *s;
- memory_handle_t region;
--
-+
- if (CHECK_SOCKET(req->Socket))
- return CS_BAD_SOCKET;
- s = SOCKET(req);
--
-+
- if (req->Attributes & REGION_TYPE_AM)
- region = s->a_region;
- else
- region = s->c_region;
--
-+
- while (region) {
- if (region->info.CardOffset == req->CardOffset) break;
- region = region->info.next;
-@@ -973,7 +980,7 @@
- if (!region || (region->mtd != NULL))
- return CS_BAD_OFFSET;
- strncpy(region->dev_info, (char *)req->dev_info, DEV_NAME_LEN);
--
-+
- DEBUG(1, "cs: bind_mtd(): attr 0x%x, offset 0x%x, dev %s\n",
- req->Attributes, req->CardOffset, (char *)req->dev_info);
- return CS_SUCCESS;
-@@ -988,7 +995,7 @@
- memory_handle_t region;
- u_long flags;
- int i, sn;
--
-+
- DEBUG(1, "cs: deregister_client(%p)\n", handle);
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
-@@ -1007,7 +1014,7 @@
- for (region = s->c_region; region; region = region->info.next)
- if (region->mtd == handle) region->mtd = NULL;
- }
--
-+
- sn = handle->Socket; s = socket_table[sn];
-
- if ((handle->state & CLIENT_STALE) ||
-@@ -1032,7 +1039,7 @@
-
- if (--s->real_clients == 0)
- register_callback(s, NULL, NULL);
--
-+
- return CS_SUCCESS;
- } /* deregister_client */
-
-@@ -1043,7 +1050,7 @@
- {
- socket_info_t *s;
- config_t *c;
--
-+
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
-@@ -1055,7 +1062,7 @@
- return CS_BAD_ARGS;
- } else
- config->Function = handle->Function;
--
-+
- #ifdef CONFIG_CARDBUS
- if (s->state & SOCKET_CARDBUS) {
- u_char fn = config->Function;
-@@ -1076,16 +1083,16 @@
- return CS_SUCCESS;
- }
- #endif
--
-+
- c = (s->config != NULL) ? &s->config[config->Function] : NULL;
--
-+
- if ((c == NULL) || !(c->state & CONFIG_LOCKED)) {
- config->Attributes = 0;
- config->Vcc = s->socket.Vcc;
- config->Vpp1 = config->Vpp2 = s->socket.Vpp;
- return CS_SUCCESS;
- }
--
-+
- /* !!! This is a hack !!! */
- memcpy(&config->Attributes, &c->Attributes, sizeof(config_t));
- config->Attributes |= CONF_VALID_CLIENT;
-@@ -1099,14 +1106,14 @@
- config->NumPorts2 = c->io.NumPorts2;
- config->Attributes2 = c->io.Attributes2;
- config->IOAddrLines = c->io.IOAddrLines;
--
-+
- return CS_SUCCESS;
- } /* get_configuration_info */
-
- /*======================================================================
-
- Return information about this version of Card Services.
--
-+
- ======================================================================*/
-
- int pcmcia_get_card_services_info(servinfo_t *info)
-@@ -1124,7 +1131,7 @@
-
- Note that get_first_client() *does* recognize the Socket field
- in the request structure.
--
-+
- ======================================================================*/
-
- int pcmcia_get_first_client(client_handle_t *handle, client_req_t *req)
-@@ -1239,7 +1246,7 @@
-
- Get the current socket state bits. We don't support the latched
- SocketState yet: I haven't seen any point for it.
--
-+
- ======================================================================*/
-
- int pcmcia_get_status(client_handle_t handle, cs_status_t *status)
-@@ -1247,7 +1254,7 @@
- socket_info_t *s;
- config_t *c;
- int val;
--
-+
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
-@@ -1263,7 +1270,7 @@
- return CS_NO_CARD;
- if (s->state & SOCKET_SETUP_PENDING)
- status->CardState |= CS_EVENT_CARD_INSERTION;
--
-+
- /* Get info from the PRR, if necessary */
- if (handle->Function == BIND_FN_ALL) {
- if (status->Function && (status->Function >= s->functions))
-@@ -1309,7 +1316,7 @@
- /*======================================================================
-
- Change the card address of an already open memory window.
--
-+
- ======================================================================*/
-
- int pcmcia_get_mem_page(window_handle_t win, memreq_t *req)
-@@ -1338,7 +1345,7 @@
- /*======================================================================
-
- Modify a locked socket configuration
--
-+
- ======================================================================*/
-
- int pcmcia_modify_configuration(client_handle_t handle,
-@@ -1346,7 +1353,7 @@
- {
- socket_info_t *s;
- config_t *c;
--
-+
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle); c = CONFIG(handle);
-@@ -1354,7 +1361,7 @@
- return CS_NO_CARD;
- if (!(c->state & CONFIG_LOCKED))
- return CS_CONFIGURATION_LOCKED;
--
-+
- if (mod->Attributes & CONF_IRQ_CHANGE_VALID) {
- if (mod->Attributes & CONF_ENABLE_IRQ) {
- c->Attributes |= CONF_ENABLE_IRQ;
-@@ -1406,7 +1413,7 @@
- win->ctl.flags |= MAP_USE_WAIT;
- win->ctl.speed = req->AccessSpeed;
- set_mem_map(win->sock, &win->ctl);
--
-+
- return CS_SUCCESS;
- } /* modify_window */
-
-@@ -1416,7 +1423,7 @@
- caller with a socket. The driver must have already been bound
- to a socket with bind_device() -- in fact, bind_device()
- allocates the client structure that will be used.
--
-+
- ======================================================================*/
-
- int pcmcia_register_client(client_handle_t *handle, client_reg_t *req)
-@@ -1424,7 +1431,7 @@
- client_t *client;
- socket_info_t *s;
- socket_t ns;
--
-+
- /* Look for unbound client with matching dev_info */
- client = NULL;
- for (ns = 0; ns < sockets; ns++) {
-@@ -1464,7 +1471,7 @@
-
- if (s->state & SOCKET_CARDBUS)
- client->state |= CLIENT_CARDBUS;
--
-+
- if ((!(s->state & SOCKET_CARDBUS)) && (s->functions == 0) &&
- (client->Function != BIND_FN_ALL)) {
- cistpl_longlink_mfc_t mfc;
-@@ -1479,7 +1486,7 @@
- return CS_OUT_OF_RESOURCE;
- memset(s->config, 0, sizeof(config_t) * s->functions);
- }
--
-+
- DEBUG(1, "cs: register_client(): client 0x%p, sock %d, dev %s\n",
- client, client->Socket, client->dev_info);
- if (client->EventMask & CS_EVENT_REGISTRATION_COMPLETE)
-@@ -1501,13 +1508,13 @@
- pccard_io_map io = { 0, 0, 0, 0, 1 };
- socket_info_t *s;
- int i;
--
-+
- if (CHECK_HANDLE(handle) ||
- !(handle->state & CLIENT_CONFIG_LOCKED))
- return CS_BAD_HANDLE;
- handle->state &= ~CLIENT_CONFIG_LOCKED;
- s = SOCKET(handle);
--
-+
- #ifdef CONFIG_CARDBUS
- if (handle->state & CLIENT_CARDBUS) {
- cb_disable(s);
-@@ -1515,7 +1522,7 @@
- return CS_SUCCESS;
- }
- #endif
--
-+
- if (!(handle->state & CLIENT_STALE)) {
- config_t *c = CONFIG(handle);
- if (--(s->lock_count) == 0) {
-@@ -1536,7 +1543,7 @@
- }
- c->state &= ~CONFIG_LOCKED;
- }
--
-+
- return CS_SUCCESS;
- } /* release_configuration */
-
-@@ -1547,25 +1554,25 @@
- the actual socket configuration, so if the client is "stale", we
- don't bother checking the port ranges against the current socket
- values.
--
-+
- ======================================================================*/
-
- int pcmcia_release_io(client_handle_t handle, io_req_t *req)
- {
- socket_info_t *s;
--
-+
- if (CHECK_HANDLE(handle) || !(handle->state & CLIENT_IO_REQ))
- return CS_BAD_HANDLE;
- handle->state &= ~CLIENT_IO_REQ;
- s = SOCKET(handle);
--
-+
- #ifdef CONFIG_CARDBUS
- if (handle->state & CLIENT_CARDBUS) {
- cb_release(s);
- return CS_SUCCESS;
- }
- #endif
--
-+
- if (!(handle->state & CLIENT_STALE)) {
- config_t *c = CONFIG(handle);
- if (c->state & CONFIG_LOCKED)
-@@ -1581,7 +1588,7 @@
- release_io_space(s, req->BasePort1, req->NumPorts1);
- if (req->NumPorts2)
- release_io_space(s, req->BasePort2, req->NumPorts2);
--
-+
- return CS_SUCCESS;
- } /* release_io */
-
-@@ -1594,7 +1601,7 @@
- return CS_BAD_HANDLE;
- handle->state &= ~CLIENT_IRQ_REQ;
- s = SOCKET(handle);
--
-+
- if (!(handle->state & CLIENT_STALE)) {
- config_t *c = CONFIG(handle);
- if (c->state & CONFIG_LOCKED)
-@@ -1608,16 +1615,16 @@
- s->irq.AssignedIRQ = 0;
- }
- }
--
-+
- if (req->Attributes & IRQ_HANDLE_PRESENT) {
- bus_free_irq(s->cap.bus, req->AssignedIRQ, req->Instance);
- }
-
--#ifdef CONFIG_ISA
-+#ifdef CONFIG_PCMCIA_PROBE
- if (req->AssignedIRQ != s->cap.pci_irq)
- undo_irq(req->Attributes, req->AssignedIRQ);
- #endif
--
-+
- return CS_SUCCESS;
- } /* cs_release_irq */
-
-@@ -1626,7 +1633,7 @@
- int pcmcia_release_window(window_handle_t win)
- {
- socket_info_t *s;
--
-+
- if ((win == NULL) || (win->magic != WINDOW_MAGIC))
- return CS_BAD_HANDLE;
- s = win->sock;
-@@ -1640,11 +1647,11 @@
-
- /* Release system memory */
- if(!(s->cap.features & SS_CAP_STATIC_MAP))
-- release_mem_region(win->base, win->size);
-+ release_mem_resource(win->base, win->size);
- win->handle->state &= ~CLIENT_WIN_REQ(win->index);
-
- win->magic = 0;
--
-+
- return CS_SUCCESS;
- } /* release_window */
-
-@@ -1658,13 +1665,13 @@
- socket_info_t *s;
- config_t *c;
- pccard_io_map iomap;
--
-+
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- i = handle->Socket; s = socket_table[i];
- if (!(s->state & SOCKET_PRESENT))
- return CS_NO_CARD;
--
-+
- #ifdef CONFIG_CARDBUS
- if (handle->state & CLIENT_CARDBUS) {
- if (!(req->IntType & INT_CARDBUS))
-@@ -1677,7 +1684,7 @@
- return CS_SUCCESS;
- }
- #endif
--
-+
- if (req->IntType & INT_CARDBUS)
- return CS_UNSUPPORTED_MODE;
- c = CONFIG(handle);
-@@ -1692,9 +1699,9 @@
- s->socket.Vpp = req->Vpp1;
- if (set_socket(s, &s->socket))
- return CS_BAD_VPP;
--
-+
- c->Vcc = req->Vcc; c->Vpp1 = c->Vpp2 = req->Vpp1;
--
-+
- /* Pick memory or I/O card, DMA mode, interrupt */
- c->IntType = req->IntType;
- c->Attributes = req->Attributes;
-@@ -1712,7 +1719,7 @@
- s->socket.io_irq = 0;
- set_socket(s, &s->socket);
- s->lock_count++;
--
-+
- /* Set up CIS configuration registers */
- base = c->ConfigBase = req->ConfigBase;
- c->Present = c->CardValues = req->Present;
-@@ -1757,7 +1764,7 @@
- u_char b = c->io.NumPorts1 + c->io.NumPorts2 - 1;
- write_cis_mem(s, 1, (base + CISREG_IOSIZE)>>1, 1, &b);
- }
--
-+
- /* Configure I/O windows */
- if (c->state & CONFIG_IO_REQ) {
- iomap.speed = io_speed;
-@@ -1779,24 +1786,24 @@
- s->io[i].Config++;
- }
- }
--
-+
- c->state |= CONFIG_LOCKED;
- handle->state |= CLIENT_CONFIG_LOCKED;
- return CS_SUCCESS;
- } /* request_configuration */
-
- /*======================================================================
--
-+
- Request_io() reserves ranges of port addresses for a socket.
- I have not implemented range sharing or alias addressing.
--
-+
- ======================================================================*/
-
- int pcmcia_request_io(client_handle_t handle, io_req_t *req)
- {
- socket_info_t *s;
- config_t *c;
--
-+
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
-@@ -1855,7 +1862,7 @@
- hooked, we don't guarantee that an irq will still be available
- when the configuration is locked. Now that I think about it,
- there might be a way to fix this using a dummy handler.
--
-+
- ======================================================================*/
-
- int pcmcia_request_irq(client_handle_t handle, irq_req_t *req)
-@@ -1863,7 +1870,7 @@
- socket_info_t *s;
- config_t *c;
- int ret = CS_IN_USE, irq = 0;
--
-+
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- s = SOCKET(handle);
-@@ -1875,7 +1882,7 @@
- if (c->state & CONFIG_IRQ_REQ)
- return CS_IN_USE;
-
--#ifdef CONFIG_ISA
-+#ifdef CONFIG_PCMCIA_PROBE
- if (s->irq.AssignedIRQ != 0) {
- /* If the interrupt is already assigned, it must match */
- irq = s->irq.AssignedIRQ;
-@@ -1909,7 +1916,7 @@
-
- if (req->Attributes & IRQ_HANDLE_PRESENT) {
- if (bus_request_irq(s->cap.bus, irq, req->Handler,
-- ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||
-+ ((req->Attributes & IRQ_TYPE_DYNAMIC_SHARING) ||
- (s->functions > 1) ||
- (irq == s->cap.pci_irq)) ? SA_SHIRQ : 0,
- handle->dev_info, req->Instance))
-@@ -1919,7 +1926,7 @@
- c->irq.Attributes = req->Attributes;
- s->irq.AssignedIRQ = req->AssignedIRQ = irq;
- s->irq.Config++;
--
-+
- c->state |= CONFIG_IRQ_REQ;
- handle->state |= CLIENT_IRQ_REQ;
- return CS_SUCCESS;
-@@ -1938,7 +1945,7 @@
- window_t *win;
- u_long align;
- int w;
--
-+
- if (CHECK_HANDLE(*handle))
- return CS_BAD_HANDLE;
- s = SOCKET(*handle);
-@@ -2005,7 +2012,7 @@
- /* Return window handle */
- req->Base = win->ctl.sys_start;
- *wh = win;
--
-+
- return CS_SUCCESS;
- } /* request_window */
-
-@@ -2014,14 +2021,14 @@
- I'm not sure which "reset" function this is supposed to use,
- but for now, it uses the low-level interface's reset, not the
- CIS register.
--
-+
- ======================================================================*/
-
- int pcmcia_reset_card(client_handle_t handle, client_req_t *req)
- {
- int i, ret;
- socket_info_t *s;
--
-+
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- i = handle->Socket; s = socket_table[i];
-@@ -2049,14 +2056,14 @@
-
- These shut down or wake up a socket. They are sort of user
- initiated versions of the APM suspend and resume actions.
--
-+
- ======================================================================*/
-
- int pcmcia_suspend_card(client_handle_t handle, client_req_t *req)
- {
- int i;
- socket_info_t *s;
--
-+
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- i = handle->Socket; s = socket_table[i];
-@@ -2077,7 +2084,7 @@
- {
- int i;
- socket_info_t *s;
--
-+
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- i = handle->Socket; s = socket_table[i];
-@@ -2095,7 +2102,7 @@
- /*======================================================================
-
- These handle user requests to eject or insert a card.
--
-+
- ======================================================================*/
-
- int pcmcia_eject_card(client_handle_t handle, client_req_t *req)
-@@ -2103,7 +2110,7 @@
- int i, ret;
- socket_info_t *s;
- u_long flags;
--
-+
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- i = handle->Socket; s = socket_table[i];
-@@ -2119,9 +2126,9 @@
- spin_lock_irqsave(&s->lock, flags);
- do_shutdown(s);
- spin_unlock_irqrestore(&s->lock, flags);
--
-+
- return CS_SUCCESS;
--
-+
- } /* eject_card */
-
- int pcmcia_insert_card(client_handle_t handle, client_req_t *req)
-@@ -2129,7 +2136,7 @@
- int i, status;
- socket_info_t *s;
- u_long flags;
--
-+
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
- i = handle->Socket; s = socket_table[i];
-@@ -2157,7 +2164,7 @@
-
- Maybe this should send a CS_EVENT_CARD_INSERTION event if we
- haven't sent one to this client yet?
--
-+
- ======================================================================*/
-
- int pcmcia_set_event_mask(client_handle_t handle, eventmask_t *mask)
-@@ -2189,7 +2196,7 @@
- printk(KERN_NOTICE);
- else
- printk(KERN_NOTICE "%s: ", handle->dev_info);
--
-+
- for (i = 0; i < SERVICE_COUNT; i++)
- if (service_table[i].key == err->func) break;
- if (i < SERVICE_COUNT)
-@@ -2347,13 +2354,13 @@
- default:
- return CS_UNSUPPORTED_FUNCTION; break;
- }
--
-+
- } /* CardServices */
-
- /*======================================================================
-
- OS-specific module glue goes here
--
-+
- ======================================================================*/
- /* in alpha order */
- EXPORT_SYMBOL(pcmcia_access_configuration_register);
-@@ -2450,4 +2457,3 @@
- module_exit(exit_pcmcia_cs);
-
- /*====================================================================*/
--
---- linux-2.4.25/drivers/pcmcia/ds.c~2.4.25-vrs2.patch 2001-11-12 18:39:01.000000000 +0100
-+++ linux-2.4.25/drivers/pcmcia/ds.c 2004-03-31 17:15:09.000000000 +0200
-@@ -55,6 +55,7 @@
- #include <pcmcia/bulkmem.h>
- #include <pcmcia/cistpl.h>
- #include <pcmcia/ds.h>
-+#include <linux/devfs_fs_kernel.h>
-
- /*====================================================================*/
-
-@@ -880,6 +881,8 @@
- EXPORT_SYMBOL(register_pccard_driver);
- EXPORT_SYMBOL(unregister_pccard_driver);
-
-+static devfs_handle_t devfs_handle;
-+
- /*====================================================================*/
-
- int __init init_pcmcia_ds(void)
-@@ -957,8 +960,13 @@
- if (i == -EBUSY)
- printk(KERN_NOTICE "unable to find a free device # for "
- "Driver Services\n");
-- else
-+ else {
- major_dev = i;
-+ devfs_handle = devfs_register(NULL, "pcmcia", DEVFS_FL_DEFAULT,
-+ major_dev, 0,
-+ S_IFCHR | S_IRUSR | S_IWUSR,
-+ &ds_fops, NULL);
-+ }
-
- #ifdef CONFIG_PROC_FS
- if (proc_pccard)
-@@ -983,7 +991,9 @@
- remove_proc_entry("drivers", proc_pccard);
- #endif
- if (major_dev != -1)
-- unregister_chrdev(major_dev, "pcmcia");
-+ devfs_unregister_chrdev(major_dev, "pcmcia");
-+ devfs_unregister(devfs_handle);
-+
- for (i = 0; i < sockets; i++)
- pcmcia_deregister_client(socket_table[i].handle);
- sockets = 0;
---- linux-2.4.25/drivers/pcmcia/i82365.c~2.4.25-vrs2.patch 2003-11-28 19:26:20.000000000 +0100
-+++ linux-2.4.25/drivers/pcmcia/i82365.c 2004-03-31 17:15:09.000000000 +0200
-@@ -28,7 +28,7 @@
- and other provisions required by the GPL. If you do not delete
- the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
--
-+
- ======================================================================*/
-
- #include <linux/module.h>
-@@ -65,6 +65,15 @@
- #include "ricoh.h"
- #include "o2micro.h"
-
-+#ifdef CONFIG_ARCH_EBSA110
-+#define I365_MASK (1 << 6)
-+#define SOCKIRQ2REG(sock,irq) ((irq) ? ((sock) ? 3 : 4) : 0)
-+#define REG2SOCKIRQ(sock,reg) (6)
-+#else
-+#define SOCKIRQ2REG(sock,irq) (irq)
-+#define REG2SOCKIRQ(sock,reg) (reg)
-+#endif
-+
- #ifdef PCMCIA_DEBUG
- static int pc_debug = PCMCIA_DEBUG;
- MODULE_PARM(pc_debug, "i");
-@@ -173,13 +182,15 @@
- } socket_info_t;
-
- /* Where we keep track of our sockets... */
--static int sockets = 0;
--static socket_info_t socket[8] = {
-- { 0, }, /* ... */
--};
-+static int sockets /* = 0 */;
-+static socket_info_t socket[8] /* = {
-+ { 0, },
-+} */;
-
- /* Default ISA interrupt mask */
-+#ifndef I365_MASK
- #define I365_MASK 0xdeb8 /* irq 15,14,12,11,10,9,7,5,4,3 */
-+#endif
-
- static int grab_irq;
- static spinlock_t isa_lock = SPIN_LOCK_UNLOCKED;
-@@ -303,7 +314,7 @@
-
- The VIA controllers also use these routines, as they are mostly
- Cirrus lookalikes, without the timing registers.
--
-+
- ======================================================================*/
-
- #define flip(v,b,f) (v = ((f)<0) ? v : ((f) ? ((v)|(b)) : ((v)&(~b))))
-@@ -389,7 +400,7 @@
- Code to save and restore global state information for Vadem VG468
- and VG469 controllers, and to set and report global configuration
- options.
--
-+
- ======================================================================*/
-
- static void vg46x_get_state(u_short s)
-@@ -411,7 +422,7 @@
- static u_int __init vg46x_set_opts(u_short s, char *buf)
- {
- vg46x_state_t *p = &socket[s].state.vg46x;
--
-+
- flip(p->ctl, VG468_CTL_ASYNC, async_clock);
- flip(p->ema, VG469_MODE_CABLE, cable_mode);
- if (p->ctl & VG468_CTL_ASYNC)
-@@ -436,7 +447,7 @@
- /*======================================================================
-
- Generic routines to get and set controller options
--
-+
- ======================================================================*/
-
- static void get_bridge_state(u_short s)
-@@ -489,7 +500,7 @@
- /*======================================================================
-
- Interrupt testing code, for ISA and PCI interrupts
--
-+
- ======================================================================*/
-
- static volatile u_int irq_hits;
-@@ -517,7 +528,7 @@
- }
-
- /* Generate one interrupt */
-- i365_set(sock, I365_CSCINT, I365_CSC_DETECT | (irq << 4));
-+ i365_set(sock, I365_CSCINT, I365_CSC_DETECT | (SOCKIRQ2REG(sock, irq) << 4));
- i365_bset(sock, I365_GENCTL, I365_CTL_SW_IRQ);
- udelay(1000);
-
-@@ -526,7 +537,7 @@
- /* mask all interrupts */
- i365_set(sock, I365_CSCINT, 0);
- DEBUG(2, " hits = %d\n", irq_hits);
--
-+
- return (irq_hits != 1);
- }
-
-@@ -540,7 +551,7 @@
- /* Don't probe level-triggered interrupts -- reserved for PCI */
- mask0 &= ~(inb(PIC) | (inb(PIC+1) << 8));
- #endif
--
-+
- if (do_scan) {
- set_bridge_state(sock);
- i365_set(sock, I365_CSCINT, 0);
-@@ -551,7 +562,7 @@
- if ((mask1 & (1 << i)) && (test_irq(sock, i) != 0))
- mask1 ^= (1 << i);
- }
--
-+
- printk(KERN_INFO " ISA irqs (");
- if (mask1) {
- printk("scanned");
-@@ -565,12 +576,12 @@
- if (!cs_irq && (poll_interval == 0)) poll_interval = HZ;
- }
- printk(") = ");
--
-+
- for (i = 0; i < 16; i++)
- if (mask1 & (1<<i))
- printk("%s%d", ((mask1 & ((1<<i)-1)) ? "," : ""), i);
- if (mask1 == 0) printk("none!");
--
-+
- return mask1;
- }
-
-@@ -598,14 +609,14 @@
- /* Use the next free entry in the socket table */
- socket[sockets].ioaddr = port;
- socket[sockets].psock = sock;
--
-+
- /* Wake up a sleepy Cirrus controller */
- if (wakeup) {
- i365_bclr(sockets, PD67_MISC_CTL_2, PD67_MC2_SUSPEND);
- /* Pause at least 50 ms */
- mdelay(50);
- }
--
-+
- if ((val = i365_get(sockets, I365_IDENT)) & 0x70)
- return -1;
- switch (val) {
-@@ -618,7 +629,7 @@
- case 0x88: case 0x89: case 0x8a:
- type = IS_IBM; break;
- }
--
-+
- /* Check for Vadem VG-468 chips */
- outb(0x0e, port);
- outb(0x37, port);
-@@ -633,7 +644,7 @@
- val = i365_get(sockets, RF5C_CHIP_ID);
- if ((val == RF5C_CHIP_RF5C296) || (val == RF5C_CHIP_RF5C396))
- type = IS_RF5Cx96;
--
-+
- /* Check for Cirrus CL-PD67xx chips */
- i365_set(sockets, PD67_CHIP_INFO, 0);
- val = i365_get(sockets, PD67_CHIP_INFO);
-@@ -655,14 +666,14 @@
- bound to a (non PC Card) Linux driver. We leave these alone.
-
- We make an exception for cards that seem to be serial devices.
--
-+
- ======================================================================*/
-
- static int __init is_alive(u_short sock)
- {
- u_char stat;
- u_short start, stop;
--
-+
- stat = i365_get(sock, I365_STATUS);
- start = i365_get_pair(sock, I365_IO(0)+I365_W_START);
- stop = i365_get_pair(sock, I365_IO(0)+I365_W_STOP);
-@@ -697,7 +708,7 @@
-
- base = sockets-ns;
- if (t->ioaddr > 0) request_region(t->ioaddr, 2, "i82365");
--
-+
- if (base == 0) printk("\n");
- printk(KERN_INFO " %s", pcic[type].name);
- printk(" ISA-to-PCMCIA at port %#x ofs 0x%02x",
-@@ -713,7 +724,7 @@
- mask &= I365_MASK & set_bridge_opts(base, ns);
- /* Scan for ISA interrupts */
- mask = isa_scan(base, mask);
--
-+
- /* Poll if only two interrupts available */
- if (!poll_interval) {
- u_int tmp = (mask & 0xff20);
-@@ -735,15 +746,15 @@
- printk(" status change on irq %d\n", cs_irq);
- }
- }
--
-+
- if (!isa_irq) {
- if (poll_interval == 0)
- poll_interval = HZ;
- printk(" polling interval = %d ms\n",
- poll_interval * 1000 / HZ);
--
-+
- }
--
-+
- /* Update socket interrupt information, capabilities */
- for (i = 0; i < ns; i++) {
- t[i].cap.features |= SS_CAP_PCCARD;
-@@ -866,12 +877,12 @@
- events = pending_events[i];
- pending_events[i] = 0;
- spin_unlock_irq(&pending_event_lock);
-- /*
-- SS_DETECT events need a small delay here. The reason for this is that
-+ /*
-+ SS_DETECT events need a small delay here. The reason for this is that
- the "is there a card" electronics need time to see the card after the
-- "we have a card coming in" electronics have seen it.
-+ "we have a card coming in" electronics have seen it.
- */
-- if (events & SS_DETECT)
-+ if (events & SS_DETECT)
- mdelay(4);
- if (socket[i].handler)
- socket[i].handler(socket[i].info, events);
-@@ -890,7 +901,7 @@
- int i, j, csc;
- u_int events, active;
- u_long flags = 0;
--
-+
- DEBUG(4, "i82365: pcic_interrupt(%d)\n", irq);
-
- for (j = 0; j < 20; j++) {
-@@ -906,20 +917,20 @@
- continue;
- }
- events = (csc & I365_CSC_DETECT) ? SS_DETECT : 0;
--
--
-+
-+
- /* Several sockets will send multiple "new card detected"
-- events in rapid succession. However, the rest of the pcmcia expects
-+ events in rapid succession. However, the rest of the pcmcia expects
- only one such event. We just ignore these events by having a
- timeout */
-
- if (events) {
-- if ((jiffies - last_detect_jiffies)<(HZ/20))
-+ if ((jiffies - last_detect_jiffies)<(HZ/20))
- events = 0;
- last_detect_jiffies = jiffies;
--
-+
- }
--
-+
- if (i365_get(i, I365_INTCTL) & I365_PC_IOCARD)
- events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0;
- else {
-@@ -980,11 +991,11 @@
- static int i365_get_status(u_short sock, u_int *value)
- {
- u_int status;
--
-+
- status = i365_get(sock, I365_STATUS);
- *value = ((status & I365_CS_DETECT) == I365_CS_DETECT)
- ? SS_DETECT : 0;
--
-+
- if (i365_get(sock, I365_INTCTL) & I365_PC_IOCARD)
- *value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
- else {
-@@ -1005,7 +1016,7 @@
- *value |= (status & VG469_VSENSE_A_VS2) ? 0 : SS_XVCARD;
- }
- }
--
-+
- DEBUG(1, "i82365: GetStatus(%d) = %#4.4x\n", sock, *value);
- return 0;
- } /* i365_get_status */
-@@ -1016,7 +1027,7 @@
- {
- socket_info_t *t = &socket[sock];
- u_char reg, vcc, vpp;
--
-+
- reg = i365_get(sock, I365_POWER);
- state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
- state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
-@@ -1057,14 +1068,14 @@
- reg = i365_get(sock, I365_INTCTL);
- state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;
- if (reg & I365_PC_IOCARD) state->flags |= SS_IOCARD;
-- state->io_irq = reg & I365_IRQ_MASK;
--
-+ state->io_irq = REG2SOCKIRQ(sock, reg & I365_IRQ_MASK);
-+
- /* speaker control */
- if (t->flags & IS_CIRRUS) {
- if (i365_get(sock, PD67_MISC_CTL_1) & PD67_MC1_SPKR_ENA)
- state->flags |= SS_SPKR_ENA;
- }
--
-+
- /* Card status change mask */
- reg = i365_get(sock, I365_CSCINT);
- state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0;
-@@ -1075,7 +1086,7 @@
- state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0;
- state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0;
- }
--
-+
- DEBUG(1, "i82365: GetSocket(%d) = flags %#3.3x, Vcc %d, Vpp %d, "
- "io_irq %d, csc_mask %#2.2x\n", sock, state->flags,
- state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
-@@ -1088,21 +1099,21 @@
- {
- socket_info_t *t = &socket[sock];
- u_char reg;
--
-+
- DEBUG(1, "i82365: SetSocket(%d, flags %#3.3x, Vcc %d, Vpp %d, "
- "io_irq %d, csc_mask %#2.2x)\n", sock, state->flags,
- state->Vcc, state->Vpp, state->io_irq, state->csc_mask);
--
-+
- /* First set global controller options */
- set_bridge_state(sock);
--
-+
- /* IO card, RESET flag, IO interrupt */
- reg = t->intr;
-- reg |= state->io_irq;
-+ reg |= SOCKIRQ2REG(sock, state->io_irq);
- reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
- reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
- i365_set(sock, I365_INTCTL, reg);
--
-+
- reg = I365_PWR_NORESET;
- if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO;
- if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT;
-@@ -1165,7 +1176,7 @@
- default: return -EINVAL;
- }
- }
--
-+
- if (reg != i365_get(sock, I365_POWER))
- i365_set(sock, I365_POWER, reg);
-
-@@ -1175,9 +1186,9 @@
- i365_bflip(sock, PD67_MISC_CTL_1, PD67_MC1_SPKR_ENA,
- state->flags & SS_SPKR_ENA);
- }
--
-+
- /* Card status change interrupt mask */
-- reg = t->cs_irq << 4;
-+ reg = SOCKIRQ2REG(sock, t->cs_irq) << 4;
- if (state->csc_mask & SS_DETECT) reg |= I365_CSC_DETECT;
- if (state->flags & SS_IOCARD) {
- if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;
-@@ -1188,7 +1199,7 @@
- }
- i365_set(sock, I365_CSCINT, reg);
- i365_get(sock, I365_CSC);
--
-+
- return 0;
- } /* i365_set_socket */
-
-@@ -1197,7 +1208,7 @@
- static int i365_get_io_map(u_short sock, struct pccard_io_map *io)
- {
- u_char map, ioctl, addr;
--
-+
- map = io->map;
- if (map > 1) return -EINVAL;
- io->start = i365_get_pair(sock, I365_IO(map)+I365_W_START);
-@@ -1220,7 +1231,7 @@
- static int i365_set_io_map(u_short sock, struct pccard_io_map *io)
- {
- u_char map, ioctl;
--
-+
- DEBUG(1, "i82365: SetIOMap(%d, %d, %#2.2x, %d ns, "
- "%#4.4x-%#4.4x)\n", sock, io->map, io->flags,
- io->speed, io->start, io->stop);
-@@ -1250,30 +1261,30 @@
- {
- u_short base, i;
- u_char map, addr;
--
-+
- map = mem->map;
- if (map > 4) return -EINVAL;
- addr = i365_get(sock, I365_ADDRWIN);
- mem->flags = (addr & I365_ENA_MEM(map)) ? MAP_ACTIVE : 0;
- base = I365_MEM(map);
--
-+
- i = i365_get_pair(sock, base+I365_W_START);
- mem->flags |= (i & I365_MEM_16BIT) ? MAP_16BIT : 0;
- mem->flags |= (i & I365_MEM_0WS) ? MAP_0WS : 0;
- mem->sys_start = ((u_long)(i & 0x0fff) << 12);
--
-+
- i = i365_get_pair(sock, base+I365_W_STOP);
- mem->speed = (i & I365_MEM_WS0) ? 1 : 0;
- mem->speed += (i & I365_MEM_WS1) ? 2 : 0;
- mem->speed = to_ns(mem->speed);
- mem->sys_stop = ((u_long)(i & 0x0fff) << 12) + 0x0fff;
--
-+
- i = i365_get_pair(sock, base+I365_W_OFF);
- mem->flags |= (i & I365_MEM_WRPROT) ? MAP_WRPROT : 0;
- mem->flags |= (i & I365_MEM_REG) ? MAP_ATTRIB : 0;
- mem->card_start = ((u_int)(i & 0x3fff) << 12) + mem->sys_start;
- mem->card_start &= 0x3ffffff;
--
-+
- DEBUG(1, "i82365: GetMemMap(%d, %d) = %#2.2x, %d ns, %#5.5lx-%#5."
- "5lx, %#5.5x\n", sock, mem->map, mem->flags, mem->speed,
- mem->sys_start, mem->sys_stop, mem->card_start);
-@@ -1281,12 +1292,12 @@
- } /* i365_get_mem_map */
-
- /*====================================================================*/
--
-+
- static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem)
- {
- u_short base, i;
- u_char map;
--
-+
- DEBUG(1, "i82365: SetMemMap(%d, %d, %#2.2x, %d ns, %#5.5lx-%#5.5"
- "lx, %#5.5x)\n", sock, mem->map, mem->flags, mem->speed,
- mem->sys_start, mem->sys_stop, mem->card_start);
-@@ -1297,17 +1308,17 @@
- return -EINVAL;
- if ((mem->sys_start > 0xffffff) || (mem->sys_stop > 0xffffff))
- return -EINVAL;
--
-+
- /* Turn off the window before changing anything */
- if (i365_get(sock, I365_ADDRWIN) & I365_ENA_MEM(map))
- i365_bclr(sock, I365_ADDRWIN, I365_ENA_MEM(map));
--
-+
- base = I365_MEM(map);
- i = (mem->sys_start >> 12) & 0x0fff;
- if (mem->flags & MAP_16BIT) i |= I365_MEM_16BIT;
- if (mem->flags & MAP_0WS) i |= I365_MEM_0WS;
- i365_set_pair(sock, base+I365_W_START, i);
--
-+
- i = (mem->sys_stop >> 12) & 0x0fff;
- switch (to_cycles(mem->speed)) {
- case 0: break;
-@@ -1316,12 +1327,12 @@
- default: i |= I365_MEM_WS1 | I365_MEM_WS0; break;
- }
- i365_set_pair(sock, base+I365_W_STOP, i);
--
-+
- i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff;
- if (mem->flags & MAP_WRPROT) i |= I365_MEM_WRPROT;
- if (mem->flags & MAP_ATTRIB) i |= I365_MEM_REG;
- i365_set_pair(sock, base+I365_W_OFF, i);
--
-+
- /* Turn on the window if necessary */
- if (mem->flags & MAP_ACTIVE)
- i365_bset(sock, I365_ADDRWIN, I365_ENA_MEM(map));
-@@ -1332,7 +1343,7 @@
-
- Routines for accessing socket information and register dumps via
- /proc/bus/pccard/...
--
-+
- ======================================================================*/
-
- #ifdef CONFIG_PROC_FS
-@@ -1353,7 +1364,7 @@
- u_short sock = (socket_info_t *)data - socket;
- char *p = buf;
- int i, top;
--
-+
- u_long flags = 0;
- ISA_LOCK(sock, flags);
- top = 0x40;
-@@ -1399,7 +1410,7 @@
-
- /*====================================================================*/
-
--/* this is horribly ugly... proper locking needs to be done here at
-+/* this is horribly ugly... proper locking needs to be done here at
- * some time... */
- #define LOCKED(x) do { \
- int retval; \
-@@ -1532,7 +1543,7 @@
- /* Set up interrupt handler(s) */
- if (grab_irq != 0)
- request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt);
--
-+
- if (register_ss_entry(sockets, &pcic_operations) != 0)
- printk(KERN_NOTICE "i82365: register_ss_entry() failed\n");
-
-@@ -1544,9 +1555,9 @@
- poll_timer.expires = jiffies + poll_interval;
- add_timer(&poll_timer);
- }
--
-+
- return 0;
--
-+
- } /* init_i82365 */
-
- static void __exit exit_i82365(void)
---- linux-2.4.25/drivers/pcmcia/rsrc_mgr.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/pcmcia/rsrc_mgr.c 2004-03-31 17:15:09.000000000 +0200
-@@ -28,7 +28,7 @@
- and other provisions required by the GPL. If you do not delete
- the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
--
-+
- ======================================================================*/
-
- #define __NO_VERSION__
-@@ -55,6 +55,10 @@
- #include <pcmcia/cistpl.h>
- #include "cs_internal.h"
-
-+#ifndef ISAMEM_PHYS
-+#define ISAMEM_PHYS 0
-+#endif
-+
- /*====================================================================*/
-
- /* Parameters that can be set with 'insmod' */
-@@ -62,7 +66,7 @@
- #define INT_MODULE_PARM(n, v) static int n = v; MODULE_PARM(n, "i")
-
- INT_MODULE_PARM(probe_mem, 1); /* memory probe? */
--#ifdef CONFIG_ISA
-+#ifdef CONFIG_PCMCIA_PROBE
- INT_MODULE_PARM(probe_io, 1); /* IO port probe? */
- INT_MODULE_PARM(mem_limit, 0x10000);
- #endif
-@@ -85,7 +89,7 @@
- /* IO port resource database */
- static resource_map_t io_db = { 0, 0, &io_db };
-
--#ifdef CONFIG_ISA
-+#ifdef CONFIG_PCMCIA_PROBE
-
- typedef struct irq_info_t {
- u_int Attributes;
-@@ -133,6 +137,7 @@
- static inline int check_mem_resource(unsigned long b, unsigned long n,
- struct pci_dev *dev)
- {
-+ b += ISAMEM_PHYS;
- return check_resource(resource_parent(b, n, IORESOURCE_MEM, dev), b, n);
- }
-
-@@ -169,10 +174,15 @@
- static int request_mem_resource(unsigned long b, unsigned long n,
- char *name, struct pci_dev *dev)
- {
-- struct resource *res = make_resource(b, n, IORESOURCE_MEM, name);
-- struct resource *pr = resource_parent(b, n, IORESOURCE_MEM, dev);
-+ struct resource *res;
-+ struct resource *pr;
- int err = -ENOMEM;
-
-+ b += ISAMEM_PHYS;
-+
-+ res = make_resource(b, n, IORESOURCE_MEM, name);
-+ pr = resource_parent(b, n, IORESOURCE_MEM, dev);
-+
- if (res) {
- err = request_resource(pr, res);
- if (err)
-@@ -181,10 +191,16 @@
- return err;
- }
-
-+void release_mem_resource(unsigned long b, unsigned long n)
-+{
-+ b += ISAMEM_PHYS;
-+ release_mem_region(b, n);
-+}
-+
- /*======================================================================
-
- These manage the internal databases of available resources.
--
-+
- ======================================================================*/
-
- static int add_interval(resource_map_t *map, u_long base, u_long num)
-@@ -248,25 +264,25 @@
-
- These routines examine a region of IO or memory addresses to
- determine what ranges might be genuinely available.
--
-+
- ======================================================================*/
-
--#ifdef CONFIG_ISA
-+#ifdef CONFIG_PCMCIA_PROBE
- static void do_io_probe(ioaddr_t base, ioaddr_t num)
- {
--
-+
- ioaddr_t i, j, bad, any;
- u_char *b, hole, most;
--
-+
- printk(KERN_INFO "cs: IO port probe 0x%04x-0x%04x:",
- base, base+num-1);
--
-+
- /* First, what does a floating port look like? */
- b = kmalloc(256, GFP_KERNEL);
- if (!b) {
- printk(KERN_ERR "do_io_probe: unable to kmalloc 256 bytes");
- return;
-- }
-+ }
- memset(b, 0, 256);
- for (i = base, most = 0; i < base+num; i += 8) {
- if (check_io_resource(i, 8, NULL))
-@@ -308,7 +324,7 @@
- printk(" %#04x-%#04x", bad, i-1);
- }
- }
--
-+
- printk(any ? "\n" : " clean.\n");
- }
- #endif
-@@ -318,7 +334,7 @@
- The memory probe. If the memory list includes a 64K-aligned block
- below 1MB, we probe in 64K chunks, and as soon as we accumulate at
- least mem_limit free space, we quit.
--
-+
- ======================================================================*/
-
- static int do_mem_probe(u_long base, u_long num,
-@@ -332,7 +348,7 @@
- bad = fail = 0;
- step = (num < 0x20000) ? 0x2000 : ((num>>4) & ~0x1fff);
- for (i = j = base; i < base+num; i = j + step) {
-- if (!fail) {
-+ if (!fail) {
- for (j = i; j < base+num; j += step)
- if ((check_mem_resource(j, step, s->cap.cb_dev) == 0) &&
- is_valid(j))
-@@ -356,7 +372,7 @@
- return (num - bad);
- }
-
--#ifdef CONFIG_ISA
-+#ifdef CONFIG_PCMCIA_PROBE
-
- static u_long inv_probe(int (*is_valid)(u_long),
- int (*do_cksum)(u_long),
-@@ -383,7 +399,7 @@
- static u_char order[] = { 0xd0, 0xe0, 0xc0, 0xf0 };
- static int hi = 0, lo = 0;
- u_long b, i, ok = 0;
--
-+
- if (!probe_mem) return;
- /* We do up to four passes through the list */
- if (!force_low) {
-@@ -414,14 +430,14 @@
- }
- }
-
--#else /* CONFIG_ISA */
-+#else /* CONFIG_PCMCIA_PROBE */
-
- void validate_mem(int (*is_valid)(u_long), int (*do_cksum)(u_long),
- int force_low, socket_info_t *s)
- {
- resource_map_t *m, *n;
- static int done = 0;
--
-+
- if (!probe_mem || done++)
- return;
-
-@@ -432,7 +448,7 @@
- }
- }
-
--#endif /* CONFIG_ISA */
-+#endif /* CONFIG_PCMCIA_PROBE */
-
- /*======================================================================
-
-@@ -444,7 +460,7 @@
- should be a power of two, greater than or equal to 'num'. A value
- of 0 means that all bits of *base are significant. *base should
- also be strictly less than 'align'.
--
-+
- ======================================================================*/
-
- int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
-@@ -452,7 +468,7 @@
- {
- ioaddr_t try;
- resource_map_t *m;
--
-+
- for (m = io_db.next; m != &io_db; m = m->next) {
- try = (m->base & ~(align-1)) + *base;
- for (try = (try >= m->base) ? try : try+align;
-@@ -500,10 +516,10 @@
- This checks to see if an interrupt is available, with support
- for interrupt sharing. We don't support reserving interrupts
- yet. If the interrupt is available, we allocate it.
--
-+
- ======================================================================*/
-
--#ifdef CONFIG_ISA
-+#ifdef CONFIG_PCMCIA_PROBE
-
- static void fake_irq(int i, void *d, struct pt_regs *r) { }
- static inline int check_irq(int irq)
-@@ -570,7 +586,7 @@
-
- /*====================================================================*/
-
--#ifdef CONFIG_ISA
-+#ifdef CONFIG_PCMCIA_PROBE
-
- void undo_irq(u_int Attributes, int irq)
- {
-@@ -600,7 +616,7 @@
-
- The various adjust_* calls form the external interface to the
- resource database.
--
-+
- ======================================================================*/
-
- static int adjust_memory(adjust_t *adj)
-@@ -632,7 +648,7 @@
- default:
- ret = CS_UNSUPPORTED_FUNCTION;
- }
--
-+
- return ret;
- }
-
-@@ -641,7 +657,7 @@
- static int adjust_io(adjust_t *adj)
- {
- int base, num;
--
-+
- base = adj->resource.io.BasePort;
- num = adj->resource.io.NumPorts;
- if ((base < 0) || (base > 0xffff))
-@@ -653,7 +669,7 @@
- case ADD_MANAGED_RESOURCE:
- if (add_interval(&io_db, base, num) != 0)
- return CS_IN_USE;
--#ifdef CONFIG_ISA
-+#ifdef CONFIG_PCMCIA_PROBE
- if (probe_io)
- do_io_probe(base, num);
- #endif
-@@ -673,15 +689,15 @@
-
- static int adjust_irq(adjust_t *adj)
- {
--#ifdef CONFIG_ISA
-+#ifdef CONFIG_PCMCIA_PROBE
- int irq;
- irq_info_t *info;
--
-+
- irq = adj->resource.irq.IRQ;
- if ((irq < 0) || (irq > 15))
- return CS_BAD_IRQ;
- info = &irq_table[irq];
--
-+
- switch (adj->Action) {
- case ADD_MANAGED_RESOURCE:
- if (info->Attributes & RES_REMOVED)
-@@ -716,7 +732,7 @@
- {
- if (CHECK_HANDLE(handle))
- return CS_BAD_HANDLE;
--
-+
- switch (adj->Resource) {
- case RES_MEMORY_RANGE:
- return adjust_memory(adj);
-@@ -736,7 +752,7 @@
- void release_resource_db(void)
- {
- resource_map_t *p, *q;
--
-+
- for (p = mem_db.next; p != &mem_db; p = q) {
- q = p->next;
- kfree(p);
---- linux-2.4.25/drivers/pcmcia/sa1100.h~2.4.25-vrs2.patch 2002-08-03 02:39:44.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/sa1100.h 2004-03-31 17:15:09.000000000 +0200
-@@ -204,7 +204,9 @@
- extern struct pcmcia_low_level flexanet_pcmcia_ops;
- extern struct pcmcia_low_level simpad_pcmcia_ops;
- extern struct pcmcia_low_level graphicsmaster_pcmcia_ops;
-+extern struct pcmcia_low_level adsagc_pcmcia_ops;
- extern struct pcmcia_low_level adsbitsy_pcmcia_ops;
-+extern struct pcmcia_low_level adsbitsyplus_pcmcia_ops;
- extern struct pcmcia_low_level stork_pcmcia_ops;
- extern struct pcmcia_low_level badge4_pcmcia_ops;
-
---- linux-2.4.25/drivers/pcmcia/sa1100_adsbitsy.c~2.4.25-vrs2.patch 2002-08-03 02:39:44.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/sa1100_adsbitsy.c 2004-03-31 17:15:09.000000000 +0200
-@@ -11,28 +11,156 @@
- */
- #include <linux/kernel.h>
- #include <linux/sched.h>
-+#include <linux/ioport.h>
-
- #include <asm/hardware.h>
-+#include <asm/hardware/sa1111.h>
-+#include <asm/irq.h>
-
- #include "sa1100_generic.h"
- #include "sa1111_generic.h"
-
-+int adsbitsy_smc91111_present(void);
-+
-+#ifndef CONFIG_SMC91111
-+#define adsbitsy_smc91111_present() 0
-+#endif
-+
-+static struct irqs {
-+ int irq;
-+ const char *str;
-+} irqs[] = {
-+ { S0_CD_VALID, "SA1111 PCMCIA card detect" },
-+ { S0_BVD1_STSCHG, "SA1111 PCMCIA BVD1" },
-+ { S1_CD_VALID, "SA1111 CF card detect" },
-+ { S1_BVD1_STSCHG, "SA1111 CF BVD1" },
-+};
-+
- static int adsbitsy_pcmcia_init(struct pcmcia_init *init)
- {
-- /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
-- PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
-+ int ret=0;
-+ int nirq = 0;
-+ int slots = 0;
-+ int i;
-
-- /* Disable Power 3.3V/5V for PCMCIA/CF */
-- PA_DWR |= GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3;
-+ /* Set GPIO_A<1:0> to be outputs for PCMCIA power controller: */
-+ PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1);
-
-- /* Why? */
-- MECR = 0x09430943;
-+ /* Disable Power 3.3V/5V for PCMCIA */
-+ PA_DWR |= GPIO_GPIO0 | GPIO_GPIO1;
-
-- return sa1111_pcmcia_init(init);
-+ if (!request_mem_region(_PCCR, 512, "PCMCIA"))
-+ return -1;
-+
-+
-+ INTPOL1 |= SA1111_IRQMASK_HI(S0_READY_NINT) |
-+ SA1111_IRQMASK_HI(S0_CD_VALID) |
-+ SA1111_IRQMASK_HI(S0_BVD1_STSCHG);
-+
-+ nirq = 2;
-+ slots = 1;
-+
-+ if (!adsbitsy_smc91111_present()) {
-+ /* If the SMC91111 is used CF cannot be used */
-+ /* Set GPIO_A<3:2> to be outputs for CF power controller: */
-+ PA_DDR &= ~(GPIO_GPIO2 | GPIO_GPIO3);
-+
-+ /* Disable Power 3.3V/5V for CF */
-+ PA_DWR |= GPIO_GPIO2 | GPIO_GPIO3;
-+
-+ INTPOL1 |= SA1111_IRQMASK_HI(S1_READY_NINT) |
-+ SA1111_IRQMASK_HI(S1_CD_VALID) |
-+ SA1111_IRQMASK_HI(S1_BVD1_STSCHG);
-+
-+ nirq = 4;
-+ slots = 2;
-+ }
-+
-+ for (i = ret = 0; i < nirq; i++) {
-+ ret = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
-+ irqs[i].str, NULL);
-+ if (ret)
-+ break;
-+ }
-+
-+ if (i < nirq) {
-+ printk(KERN_ERR "sa1111_pcmcia: unable to grab IRQ%d (%d)\n",
-+ irqs[i].irq, ret);
-+ while (i--)
-+ free_irq(irqs[i].irq, NULL);
-+
-+ release_mem_region(_PCCR, 16);
-+ }
-+
-+ return ret ? -1 : slots;
- }
-
--static int
--adsbitsy_pcmcia_configure_socket(const struct pcmcia_configure *conf)
-+static int adsbitsy_pcmcia_shutdown(void)
-+{
-+
-+ free_irq(S0_CD_VALID, NULL);
-+ free_irq(S0_BVD1_STSCHG, NULL);
-+ INTPOL1 &= ~(SA1111_IRQMASK_HI(S0_CD_VALID) | SA1111_IRQMASK_HI(S0_BVD1_STSCHG));
-+
-+ if (!adsbitsy_smc91111_present()) {
-+ free_irq(S1_CD_VALID, NULL);
-+ free_irq(S1_BVD1_STSCHG, NULL);
-+ INTPOL1 &= ~(SA1111_IRQMASK_HI(S1_CD_VALID) | SA1111_IRQMASK_HI(S1_BVD1_STSCHG));
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static int adsbitsy_pcmcia_socket_state(struct pcmcia_state_array *state)
-+{
-+ unsigned long status;
-+
-+ if (adsbitsy_smc91111_present()) {
-+ if(state->size<1) return -1;
-+ }
-+ else
-+ if(state->size<2) return -1;
-+
-+ memset(state->state, 0,
-+ (state->size)*sizeof(struct pcmcia_state));
-+
-+ status = PCSR;
-+
-+ state->state[0].detect = status & PCSR_S0_DETECT ? 0 : 1;
-+ state->state[0].ready = status & PCSR_S0_READY ? 1 : 0;
-+ state->state[0].bvd1 = status & PCSR_S0_BVD1 ? 1 : 0;
-+ state->state[0].bvd2 = status & PCSR_S0_BVD2 ? 1 : 0;
-+ state->state[0].wrprot = status & PCSR_S0_WP ? 1 : 0;
-+ state->state[0].vs_3v = status & PCSR_S0_VS1 ? 0 : 1;
-+ state->state[0].vs_Xv = status & PCSR_S0_VS2 ? 0 : 1;
-+
-+ if (state->size > 1) {
-+ if (adsbitsy_smc91111_present()) {
-+ // If there is SMC91111 on ADS Bitsy connector board
-+ // it returns not detect/ready/...
-+ state->state[1].detect = 0;
-+ state->state[1].ready = 0;
-+ state->state[1].bvd1 = 0;
-+ state->state[1].bvd2 = 0;
-+ state->state[1].wrprot = 0;
-+ state->state[1].vs_3v = 0;
-+ state->state[1].vs_Xv = 0;
-+ }
-+ else {
-+ state->state[1].detect = status & PCSR_S1_DETECT ? 0 : 1;
-+ state->state[1].ready = status & PCSR_S1_READY ? 1 : 0;
-+ state->state[1].bvd1 = status & PCSR_S1_BVD1 ? 1 : 0;
-+ state->state[1].bvd2 = status & PCSR_S1_BVD2 ? 1 : 0;
-+ state->state[1].wrprot = status & PCSR_S1_WP ? 1 : 0;
-+ state->state[1].vs_3v = status & PCSR_S1_VS1 ? 0 : 1;
-+ state->state[1].vs_Xv = status & PCSR_S1_VS2 ? 0 : 1;
-+ }
-+ }
-+ return 1;
-+}
-+
-+static int adsbitsy_pcmcia_configure_socket(const struct pcmcia_configure *conf)
- {
- unsigned int pa_dwr_mask, pa_dwr_set;
- int ret;
-@@ -54,10 +182,11 @@
-
- switch (conf->vcc) {
- default:
-- case 0: pa_dwr_set = 0; break;
-+ case 0: pa_dwr_set = GPIO_GPIO2 | GPIO_GPIO3; break;
- case 33: pa_dwr_set = GPIO_GPIO2; break;
- case 50: pa_dwr_set = GPIO_GPIO3; break;
- }
-+ break;
-
- default:
- return -1;
-@@ -83,8 +212,8 @@
-
- struct pcmcia_low_level adsbitsy_pcmcia_ops = {
- init: adsbitsy_pcmcia_init,
-- shutdown: sa1111_pcmcia_shutdown,
-- socket_state: sa1111_pcmcia_socket_state,
-+ shutdown: adsbitsy_pcmcia_shutdown,
-+ socket_state: adsbitsy_pcmcia_socket_state,
- get_irq_info: sa1111_pcmcia_get_irq_info,
- configure_socket: adsbitsy_pcmcia_configure_socket,
-
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/sa1100_adsbitsyplus.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,236 @@
-+/*
-+ * drivers/pcmcia/sa1100_adsbitsyplus.c
-+ *
-+ * PCMCIA implementation routines for ADS Bitsy Plus
-+ *
-+ * Created Feb 7, 2003 by Robert Whaley <rwhaley@applieddata.net>
-+ *
-+ * This file comes from sa1100_adsbitsy.c of Woojung Huh <whuh@applieddata.net>
-+ *
-+ */
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/ioport.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/hardware/sa1111.h>
-+#include <asm/irq.h>
-+
-+#include "sa1100_generic.h"
-+#include "sa1111_generic.h"
-+
-+int adsbitsy_smc91111_present(void);
-+
-+#ifndef CONFIG_SMC91111
-+#define adsbitsy_smc91111_present() 0
-+#endif
-+
-+static struct irqs {
-+ int irq;
-+ const char *str;
-+} irqs[] = {
-+ { S0_CD_VALID, "SA1111 PCMCIA card detect" },
-+ { S0_BVD1_STSCHG, "SA1111 PCMCIA BVD1" },
-+ { S1_CD_VALID, "SA1111 CF card detect" },
-+ { S1_BVD1_STSCHG, "SA1111 CF BVD1" },
-+};
-+
-+#define sock0_3_3_reverse_logic() ((ADS_CPLD_IO2 & ADS_IO2_CPLD_REV_MASK) >= ADS_IO2_CPLD_REV_5_MAGIC)
-+
-+static int adsbitsyplus_pcmcia_init(struct pcmcia_init *init)
-+{
-+ int ret=0;
-+ int nirq = 0;
-+ int slots = 0;
-+ int i;
-+
-+ /* Set GPIO_A<1:0> to be outputs for PCMCIA power controller: */
-+ PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1);
-+
-+ /* Disable Power 3.3V/5V for PCMCIA */
-+ if (sock0_3_3_reverse_logic())
-+ PA_DWR = (PA_DWR & ~GPIO_GPIO0) | GPIO_GPIO1;
-+ else
-+ PA_DWR |= GPIO_GPIO0 | GPIO_GPIO1;
-+
-+ if (!request_mem_region(_PCCR, 512, "PCMCIA"))
-+ return -1;
-+
-+
-+ INTPOL1 |= SA1111_IRQMASK_HI(S0_READY_NINT) |
-+ SA1111_IRQMASK_HI(S0_CD_VALID) |
-+ SA1111_IRQMASK_HI(S0_BVD1_STSCHG);
-+
-+ nirq = 2;
-+ slots = 1;
-+
-+ if (!adsbitsy_smc91111_present()) {
-+ /* If the SMC91111 is used CF cannot be used */
-+ /* Set GPIO_A<3:2> to be outputs for CF power controller: */
-+ PA_DDR &= ~(GPIO_GPIO2 | GPIO_GPIO3);
-+
-+ /* Disable Power 3.3V/5V for CF */
-+ PA_DWR |= GPIO_GPIO2 | GPIO_GPIO3;
-+
-+ INTPOL1 |= SA1111_IRQMASK_HI(S1_READY_NINT) |
-+ SA1111_IRQMASK_HI(S1_CD_VALID) |
-+ SA1111_IRQMASK_HI(S1_BVD1_STSCHG);
-+
-+ nirq = 4;
-+ slots = 2;
-+ }
-+
-+ for (i = ret = 0; i < nirq; i++) {
-+ ret = request_irq(irqs[i].irq, init->handler, SA_INTERRUPT,
-+ irqs[i].str, NULL);
-+ if (ret)
-+ break;
-+ }
-+
-+ if (i < nirq) {
-+ printk(KERN_ERR "sa1111_pcmcia: unable to grab IRQ%d (%d)\n",
-+ irqs[i].irq, ret);
-+ while (i--)
-+ free_irq(irqs[i].irq, NULL);
-+
-+ release_mem_region(_PCCR, 16);
-+ }
-+
-+ return ret ? -1 : slots;
-+}
-+
-+static int adsbitsyplus_pcmcia_shutdown(void)
-+{
-+
-+ free_irq(S0_CD_VALID, NULL);
-+ free_irq(S0_BVD1_STSCHG, NULL);
-+ INTPOL1 &= ~(SA1111_IRQMASK_HI(S0_CD_VALID) | SA1111_IRQMASK_HI(S0_BVD1_STSCHG));
-+
-+ if (!adsbitsy_smc91111_present()) {
-+ free_irq(S1_CD_VALID, NULL);
-+ free_irq(S1_BVD1_STSCHG, NULL);
-+ INTPOL1 &= ~(SA1111_IRQMASK_HI(S1_CD_VALID) | SA1111_IRQMASK_HI(S1_BVD1_STSCHG));
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static int adsbitsyplus_pcmcia_socket_state(struct pcmcia_state_array *state)
-+{
-+ unsigned long status;
-+
-+ if (adsbitsy_smc91111_present()) {
-+ if(state->size<1) return -1;
-+ }
-+ else
-+ if(state->size<2) return -1;
-+
-+ memset(state->state, 0,
-+ (state->size)*sizeof(struct pcmcia_state));
-+
-+ status = PCSR;
-+
-+ state->state[0].detect = status & PCSR_S0_DETECT ? 0 : 1;
-+ state->state[0].ready = status & PCSR_S0_READY ? 1 : 0;
-+ state->state[0].bvd1 = status & PCSR_S0_BVD1 ? 1 : 0;
-+ state->state[0].bvd2 = status & PCSR_S0_BVD2 ? 1 : 0;
-+ state->state[0].wrprot = status & PCSR_S0_WP ? 1 : 0;
-+ state->state[0].vs_3v = status & PCSR_S0_VS1 ? 0 : 1;
-+ state->state[0].vs_Xv = status & PCSR_S0_VS2 ? 0 : 1;
-+
-+ if (state->size > 1) {
-+ if (adsbitsy_smc91111_present()) {
-+ // If there is SMC91111 on ADS Bitsy connector board
-+ // it returns not detect/ready/...
-+ state->state[1].detect = 0;
-+ state->state[1].ready = 0;
-+ state->state[1].bvd1 = 0;
-+ state->state[1].bvd2 = 0;
-+ state->state[1].wrprot = 0;
-+ state->state[1].vs_3v = 0;
-+ state->state[1].vs_Xv = 0;
-+ }
-+ else {
-+ state->state[1].detect = status & PCSR_S1_DETECT ? 0 : 1;
-+ state->state[1].ready = status & PCSR_S1_READY ? 1 : 0;
-+ state->state[1].bvd1 = status & PCSR_S1_BVD1 ? 1 : 0;
-+ state->state[1].bvd2 = status & PCSR_S1_BVD2 ? 1 : 0;
-+ state->state[1].wrprot = status & PCSR_S1_WP ? 1 : 0;
-+ state->state[1].vs_3v = status & PCSR_S1_VS1 ? 0 : 1;
-+ state->state[1].vs_Xv = status & PCSR_S1_VS2 ? 0 : 1;
-+ }
-+ }
-+ return 1;
-+}
-+
-+static int adsbitsyplus_pcmcia_configure_socket(const struct pcmcia_configure *conf)
-+{
-+ unsigned int pa_dwr_mask, pa_dwr_set;
-+ int ret;
-+
-+ switch (conf->sock) {
-+ case 0:
-+ pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1;
-+
-+ if (sock0_3_3_reverse_logic()) {
-+ switch (conf->vcc) {
-+ default:
-+ case 0: pa_dwr_set = GPIO_GPIO1; break;
-+ case 33: pa_dwr_set = GPIO_GPIO0 | GPIO_GPIO1; break;
-+ case 50: pa_dwr_set = 0; break;
-+ }
-+ } else {
-+ switch (conf->vcc) {
-+ default:
-+ case 0: pa_dwr_set = GPIO_GPIO0 | GPIO_GPIO1; break;
-+ case 33: pa_dwr_set = GPIO_GPIO1; break;
-+ case 50: pa_dwr_set = GPIO_GPIO0; break;
-+ }
-+ }
-+ break;
-+
-+ case 1:
-+ pa_dwr_mask = GPIO_GPIO2 | GPIO_GPIO3;
-+
-+ switch (conf->vcc) {
-+ default:
-+ case 0: pa_dwr_set = GPIO_GPIO2 | GPIO_GPIO3; break;
-+ case 33: pa_dwr_set = GPIO_GPIO2; break;
-+ case 50: pa_dwr_set = GPIO_GPIO3; break;
-+ }
-+ break;
-+
-+ default:
-+ return -1;
-+ }
-+
-+ if (conf->vpp != conf->vcc && conf->vpp != 0) {
-+ printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n",
-+ __FUNCTION__, conf->vpp);
-+ return -1;
-+ }
-+
-+ ret = sa1111_pcmcia_configure_socket(conf);
-+ if (ret == 0) {
-+ unsigned long flags;
-+
-+ local_irq_save(flags);
-+ PA_DWR = (PA_DWR & ~pa_dwr_mask) | pa_dwr_set;
-+ local_irq_restore(flags);
-+ }
-+
-+ return ret;
-+}
-+
-+struct pcmcia_low_level adsbitsyplus_pcmcia_ops = {
-+ init: adsbitsyplus_pcmcia_init,
-+ shutdown: adsbitsyplus_pcmcia_shutdown,
-+ socket_state: adsbitsyplus_pcmcia_socket_state,
-+ get_irq_info: sa1111_pcmcia_get_irq_info,
-+ configure_socket: adsbitsyplus_pcmcia_configure_socket,
-+
-+ socket_init: sa1111_pcmcia_socket_init,
-+ socket_suspend: sa1111_pcmcia_socket_suspend,
-+};
-+
---- linux-2.4.25/drivers/pcmcia/sa1100_freebird.c~2.4.25-vrs2.patch 2002-08-03 02:39:44.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/sa1100_freebird.c 2004-03-31 17:15:09.000000000 +0200
-@@ -67,9 +67,6 @@
-
- if(state_array->size<2) return -1;
-
-- memset(state_array->state, 0,
-- (state_array->size)*sizeof(struct pcmcia_state));
--
- levels = LINKUP_PRS;
- //printk("LINKUP_PRS=%x \n",levels);
-
---- linux-2.4.25/drivers/pcmcia/sa1100_generic.c~2.4.25-vrs2.patch 2003-06-13 16:51:35.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/sa1100_generic.c 2004-03-31 17:15:09.000000000 +0200
-@@ -992,10 +992,18 @@
- if(machine_is_graphicsmaster())
- pcmcia_low_level = &graphicsmaster_pcmcia_ops;
- #endif
-+#ifdef CONFIG_SA1100_ADSAGC
-+ if(machine_is_adsagc())
-+ pcmcia_low_level = &graphicsmaster_pcmcia_ops;
-+#endif
- #ifdef CONFIG_SA1100_ADSBITSY
- if(machine_is_adsbitsy())
- pcmcia_low_level = &adsbitsy_pcmcia_ops;
- #endif
-+#ifdef CONFIG_SA1100_ADSBITSYPLUS
-+ if(machine_is_adsbitsyplus())
-+ pcmcia_low_level = &adsbitsyplus_pcmcia_ops;
-+#endif
- #ifdef CONFIG_SA1100_STORK
- if(machine_is_stork())
- pcmcia_low_level = &stork_pcmcia_ops;
-@@ -1067,7 +1075,7 @@
- * We initialize the MECR to default values here, because we are
- * not guaranteed to see a SetIOMap operation at runtime.
- */
-- mecr = 0;
-+ mecr = MECR;
-
- clock = cpufreq_get(0);
-
---- linux-2.4.25/drivers/pcmcia/sa1100_graphicsclient.c~2.4.25-vrs2.patch 2002-08-03 02:39:44.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/sa1100_graphicsclient.c 2004-03-31 17:15:09.000000000 +0200
-@@ -3,6 +3,8 @@
- *
- * PCMCIA implementation routines for Graphics Client Plus
- *
-+ * Nov/14/01 Woojung
-+ * Set MECR at initializing time
- * 9/12/01 Woojung
- * Turn power OFF at startup
- * 1/31/2001 Woojung Huh
-@@ -19,11 +21,6 @@
- #include <asm/irq.h>
- #include "sa1100_generic.h"
-
--#error This is broken!
--
--#define S0_CD_IRQ 60 // Socket 0 Card Detect IRQ
--#define S0_STS_IRQ 55 // Socket 0 PCMCIA IRQ
--
- static volatile unsigned long *PCMCIA_Status =
- ((volatile unsigned long *) ADS_p2v(_ADS_CS_STATUS));
-
-@@ -46,20 +43,23 @@
- *PCMCIA_Power &= ~0x03;
-
- /* Register interrupts */
-- irq = S0_CD_IRQ;
-+ irq = IRQ_GRAPHICSCLIENT_S0_CD;
- res = request_irq(irq, init->handler, SA_INTERRUPT, "PCMCIA 0 CD", NULL);
- if (res < 0) {
-- printk(KERN_ERR "%s: Request for IRQ %lu failed\n", __FUNCTION__, irq);
-+ printk(KERN_ERR "%s: Request for IRQ %u failed\n", __FUNCTION__, irq);
- return -1;
- }
-
-+ // Nov/14/01 WH
-+ MECR = 0x00000943;
-+
- return 1; // 1 PCMCIA Slot
- }
-
- static int gcplus_pcmcia_shutdown(void)
- {
- /* disable IRQs */
-- free_irq( S0_CD_IRQ, NULL);
-+ free_irq( IRQ_GRAPHICSCLIENT_S0_CD, NULL);
-
- /* Shutdown PCMCIA power */
- mdelay(2); // 2msec
-@@ -74,9 +74,6 @@
-
- if(state_array->size<1) return -1;
-
-- memset(state_array->state, 0,
-- (state_array->size)*sizeof(struct pcmcia_state));
--
- levels=*PCMCIA_Status;
-
- state_array->state[0].detect=(levels & ADS_CS_ST_A_CD)?1:0;
-@@ -96,7 +93,7 @@
- return -1;
-
- if (info->sock == 0)
-- info->irq = S0_STS_IRQ;
-+ info->irq = IRQ_GRAPHICSCLIENT_S0_STS;
-
- return 0;
- }
-@@ -143,6 +140,11 @@
-
- restore_flags(flags);
-
-+ if (configure->irq)
-+ enable_irq(IRQ_GRAPHICSCLIENT_S0_STS);
-+ else
-+ disable_irq(IRQ_GRAPHICSCLIENT_S0_STS);
-+
- return 0;
- }
-
---- linux-2.4.25/drivers/pcmcia/sa1100_graphicsmaster.c~2.4.25-vrs2.patch 2002-08-03 02:39:44.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/sa1100_graphicsmaster.c 2004-03-31 17:15:09.000000000 +0200
-@@ -12,13 +12,13 @@
- #include <linux/sched.h>
-
- #include <asm/hardware.h>
-+#include <asm/hardware/sa1111.h>
-
- #include "sa1100_generic.h"
- #include "sa1111_generic.h"
-
- static int graphicsmaster_pcmcia_init(struct pcmcia_init *init)
- {
-- int return_val=0;
-
- /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
- PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
-@@ -26,9 +26,6 @@
- /* Disable Power 3.3V/5V for PCMCIA/CF */
- PA_DWR |= GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3;
-
-- /* why? */
-- MECR = 0x09430943;
--
- return sa1111_pcmcia_init(init);
- }
-
-@@ -59,6 +56,10 @@
- case 33: pa_dwr_set = GPIO_GPIO3; break;
- case 50: pa_dwr_set = GPIO_GPIO2; break;
- }
-+ break;
-+
-+ default:
-+ return -1;
- }
-
- if (conf->vpp != conf->vcc && conf->vpp != 0) {
---- linux-2.4.25/drivers/pcmcia/sa1100_h3600.c~2.4.25-vrs2.patch 2002-08-03 02:39:44.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/sa1100_h3600.c 2004-03-31 17:15:09.000000000 +0200
-@@ -29,6 +29,9 @@
- set_GPIO_IRQ_edge(GPIO_H3600_PCMCIA_IRQ0 | GPIO_H3600_PCMCIA_IRQ1,
- GPIO_FALLING_EDGE);
-
-+ set_GPIO_IRQ_edge(GPIO_H3600_PCMCIA_CD0 | GPIO_H3600_PCMCIA_CD1,
-+ GPIO_NO_EDGES);
-+
- /*
- * Register interrupts
- */
---- linux-2.4.25/drivers/pcmcia/sa1100_jornada720.c~2.4.25-vrs2.patch 2002-08-03 02:39:44.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/sa1100_jornada720.c 2004-03-31 17:15:09.000000000 +0200
-@@ -8,6 +8,7 @@
- #include <linux/sched.h>
-
- #include <asm/hardware.h>
-+#include <asm/hardware/sa1111.h>
-
- #include "sa1100_generic.h"
- #include "sa1111_generic.h"
-@@ -88,7 +89,7 @@
-
- local_irq_save(flags);
- PA_DWR = (PA_DWR & ~pa_dwr_mask) | pa_dwr_set;
-- locla_irq_restore(flags);
-+ local_irq_restore(flags);
- }
-
- return ret;
---- linux-2.4.25/drivers/pcmcia/sa1100_pangolin.c~2.4.25-vrs2.patch 2002-08-03 02:39:44.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/sa1100_pangolin.c 2004-03-31 17:15:09.000000000 +0200
-@@ -53,9 +53,6 @@
-
- if(state_array->size<2) return -1;
-
-- memset(state_array->state, 0,
-- (state_array->size)*sizeof(struct pcmcia_state));
--
- levels=GPLR;
- #ifndef CONFIG_SA1100_PANGOLIN_PCMCIA_IDE
- state_array->state[1].detect=((levels & GPIO_PCMCIA_CD)==0)?1:0;
---- linux-2.4.25/drivers/pcmcia/sa1100_shannon.c~2.4.25-vrs2.patch 2002-08-03 02:39:44.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/sa1100_shannon.c 2004-03-31 17:15:09.000000000 +0200
-@@ -53,9 +53,6 @@
- {
- unsigned long levels;
-
-- memset(state_array->state, 0,
-- state_array->size * sizeof(struct pcmcia_state));
--
- levels = GPLR;
-
- state_array->state[0].detect = (levels & SHANNON_GPIO_EJECT_0) ? 0 : 1;
---- linux-2.4.25/drivers/pcmcia/sa1100_simpad.c~2.4.25-vrs2.patch 2002-08-03 02:39:44.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/sa1100_simpad.c 2004-03-31 17:15:09.000000000 +0200
-@@ -63,9 +63,6 @@
-
- if(state_array->size<2) return -1;
-
-- memset(state_array->state, 0,
-- (state_array->size)*sizeof(struct pcmcia_state));
--
- levels=GPLR;
-
- state_array->state[1].detect=((levels & GPIO_CF_CD)==0)?1:0;
---- linux-2.4.25/drivers/pcmcia/sa1100_stork.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/pcmcia/sa1100_stork.c 2004-03-31 17:15:09.000000000 +0200
-@@ -79,9 +79,6 @@
-
- if(state_array->size<2) return -1;
-
-- memset(state_array->state, 0,
-- (state_array->size)*sizeof(struct pcmcia_state));
--
- levels=GPLR;
-
- if (debug > 1)
---- linux-2.4.25/drivers/pcmcia/sa1100_yopy.c~2.4.25-vrs2.patch 2002-08-03 02:39:44.000000000 +0200
-+++ linux-2.4.25/drivers/pcmcia/sa1100_yopy.c 2004-03-31 17:15:09.000000000 +0200
-@@ -73,9 +73,6 @@
- if (state_array->size != 1)
- return -1;
-
-- memset(state_array->state, 0,
-- state_array->size * sizeof(struct pcmcia_state));
--
- levels = GPLR;
-
- state_array->state[0].detect = (levels & GPIO_CF_CD) ? 0 : 1;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/pld/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,28 @@
-+#
-+# Makefile for the kernel pld device drivers.
-+#
-+# Note! Dependencies are done automagically by 'make dep', which also
-+# removes any old dependencies. DON'T put your own dependencies here
-+# unless it's something special (ie not a .c file).
-+#
-+# Note 2! The CFLAGS definitions are now inherited from the
-+# parent makes..
-+#
-+# $Id$
-+#
-+
-+O_TARGET := pld.o
-+
-+export-objs := pld_hotswap.o
-+obj-y :=
-+obj-m :=
-+obj-n :=
-+obj- :=
-+
-+obj-$(CONFIG_PLD) += pld_epxa.o
-+obj-$(CONFIG_PLD_HOTSWAP) += pld_hotswap.o
-+
-+include $(TOPDIR)/Rules.make
-+
-+fastdep:
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/pld/pld_epxa.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,375 @@
-+
-+/*
-+ * drivers/char/epxapld.c
-+ *
-+ * Copyright (C) 2001 Altera Corporation
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/errno.h>
-+#include <linux/fs.h>
-+#include <linux/slab.h>
-+#include <linux/ioport.h>
-+#include <linux/init.h>
-+#include <linux/errno.h>
-+#include <linux/module.h>
-+#include <asm/io.h>
-+#include <asm/uaccess.h>
-+#include <asm/arch/excalibur.h>
-+#include <asm/arch/hardware.h>
-+#define PLD_CONF00_TYPE (volatile unsigned int *)
-+#define MODE_CTRL00_TYPE (volatile unsigned int *)
-+//#define DEBUG(x) x
-+#define DEBUG(x)
-+
-+#include <asm/arch/mode_ctrl00.h>
-+#include <asm/arch/pld_conf00.h>
-+#ifdef CONFIG_PLD_HOTSWAP
-+#include <linux/pld/pld_hotswap.h>
-+#endif
-+#include <linux/pld/pld_epxa.h>
-+
-+/*
-+ * Macros
-+ */
-+
-+
-+#define PLD_BASE (IO_ADDRESS(EXC_PLD_CONFIG00_BASE))
-+#define CLOCK_DIV_RATIO ((1 + EXC_AHB2_CLK_FREQUENCY/32000000) & CONFIG_CONTROL_CLOCK_RATIO_MSK)
-+/*
-+ * STRUCTURES
-+ */
-+
-+
-+struct pld_sbihdr{
-+ unsigned int fpos;
-+ unsigned int temp;
-+};
-+
-+static DECLARE_MUTEX(pld_sem);
-+
-+
-+static void lock_pld (void)
-+{
-+ /* Lock the pld i/f */
-+ unsigned int tmp;
-+
-+ tmp = readl(CONFIG_CONTROL(PLD_BASE));
-+ tmp |= CONFIG_CONTROL_LK_MSK;
-+
-+ writel(tmp,CONFIG_CONTROL(PLD_BASE));
-+}
-+
-+static void unlock_excalibur_pld (void)
-+{
-+ /* Unlock the pld i/f */
-+
-+ if (readl(CONFIG_CONTROL(PLD_BASE)) & CONFIG_CONTROL_LK_MSK ){
-+ writel(CONFIG_UNLOCK_MAGIC, CONFIG_UNLOCK(PLD_BASE));
-+ while (readl(CONFIG_CONTROL(PLD_BASE)) & CONFIG_CONTROL_LK_MSK);
-+ }
-+}
-+
-+
-+static int place_pld_into_configure_mode (void)
-+{
-+ unsigned int tmp;
-+
-+
-+ if( readl(CONFIG_CONTROL(PLD_BASE)) & CONFIG_CONTROL_CO_MSK ){
-+ /*
-+ * Already being configured!!!
-+ */
-+ printk(KERN_WARNING "pld0: Device already being configured!\n");
-+ return -EBUSY;
-+ }
-+
-+ /* Set up the config clock */
-+
-+ writel(CLOCK_DIV_RATIO,CONFIG_CONTROL_CLOCK(PLD_BASE));
-+ while(readl(CONFIG_CONTROL_CLOCK(PLD_BASE))
-+ !=CLOCK_DIV_RATIO);
-+ /* Tell the device we wish to configure it */
-+ tmp = readl(CONFIG_CONTROL(PLD_BASE));
-+ tmp |= CONFIG_CONTROL_CO_MSK;
-+ writel(tmp,CONFIG_CONTROL(PLD_BASE));
-+
-+
-+ /*
-+ * Wait for the busy bit to clear then check for errors.
-+ */
-+
-+ while((tmp=readl(CONFIG_CONTROL(PLD_BASE))&CONFIG_CONTROL_B_MSK ));
-+
-+ if ( tmp & CONFIG_CONTROL_E_MSK ){
-+ if ( tmp & CONFIG_CONTROL_ES_0_MSK ){
-+ /* Already being programmed via JTAG */
-+ printk(KERN_WARNING "pld0:JTAG configuration alreay in progress\n");
-+ return -EBUSY;
-+
-+ }
-+ if ( tmp & CONFIG_CONTROL_ES_1_MSK ){
-+ /* No config clock configured */
-+ printk(KERN_ERR "pld0:No config clock!\n");
-+ BUG();
-+ return -EBUSY;
-+ }
-+ if ( tmp & CONFIG_CONTROL_ES_2_MSK ){
-+ /* Already being programmed via External device */
-+ printk(KERN_WARNING "pld0:JTAG configuration alreay in progress\n");
-+ return -EBUSY;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static int write_pld_data_word(unsigned int config_data)
-+{
-+ unsigned int tmp;
-+
-+ do{
-+ tmp = readl(CONFIG_CONTROL(PLD_BASE));
-+ }
-+ while ( ( tmp & CONFIG_CONTROL_B_MSK ) &&
-+ !( tmp & CONFIG_CONTROL_E_MSK ));
-+
-+ if ( tmp & CONFIG_CONTROL_E_MSK ){
-+ printk("pld0: Error writing pld data, CONFIG_CONTROL=%#x\n",tmp);
-+
-+ return -EILSEQ;
-+ }
-+
-+ writel(config_data,CONFIG_CONTROL_DATA(PLD_BASE));
-+ return 0;
-+
-+}
-+
-+
-+static int wait_for_device_to_configure (void)
-+{
-+ int i=0x10000;
-+
-+ while(readl(CONFIG_CONTROL(PLD_BASE)) & CONFIG_CONTROL_B_MSK);
-+
-+ /*
-+ * Wait for the config bit (CO) to go low, indicating that everything
-+ * is Ok. If it doesn't, assume that is screwed up somehow and
-+ * clear the CO bit to abort the configuration.
-+ */
-+
-+ while(readl(CONFIG_CONTROL(PLD_BASE)) & CONFIG_CONTROL_B_MSK);
-+
-+ while (i&&(readl(CONFIG_CONTROL(PLD_BASE)) & CONFIG_CONTROL_CO_MSK)){
-+ i--;
-+ }
-+
-+ if (!i){
-+ writel(0,CONFIG_CONTROL(PLD_BASE));
-+ printk(KERN_WARNING "pld0: Invalid PLD config data\n");
-+ return -EILSEQ;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+static int pld_open(struct inode* inode, struct file *filep)
-+{
-+
-+ struct pld_sbihdr* sbihdr;
-+
-+ /* Check the device minor number */
-+ if(minor(inode->i_rdev)){
-+ DEBUG(printk("pld0: minor=%d",minor(inode->i_rdev));)
-+ return -ENODEV;
-+ }
-+
-+ /* Create our private data and link it to the file structure */
-+ sbihdr=kmalloc(sizeof(struct pld_sbihdr),GFP_KERNEL);
-+
-+ if(!sbihdr)
-+ return -ENOMEM;
-+
-+ filep->private_data=sbihdr;
-+
-+ sbihdr->fpos=0;
-+ sbihdr->temp=0;
-+ return 0;
-+}
-+
-+static int pld_release(struct inode* inode, struct file *filep){
-+ int ret_code;
-+
-+ kfree(filep->private_data);
-+ ret_code=wait_for_device_to_configure();
-+ lock_pld();
-+ return ret_code;
-+}
-+
-+static ssize_t pld_write(struct file* filep, const char* data, size_t count, loff_t* ppos){
-+
-+ struct pld_sbihdr* sbihdr=filep->private_data;
-+ int bytes_left=count;
-+ int result;
-+ DEBUG(int i=0);
-+
-+
-+ /* Can't seek (pwrite) on pld. */
-+ if (ppos != &filep->f_pos)
-+ return -ESPIPE;
-+
-+
-+ /* Check access to the whole are in one go */
-+ if(!access_ok(VERIFY_READ,(const void*)data, count)){
-+ return -EFAULT;
-+ }
-+
-+ /*
-+ * We now lock against writes.
-+ */
-+ if (down_interruptible(&pld_sem))
-+ return -ERESTARTSYS;
-+
-+ if(!sbihdr->fpos){
-+ /*
-+ * unlock the pld and place in configure mode
-+ */
-+ unlock_excalibur_pld();
-+ result=place_pld_into_configure_mode();
-+ if(result)
-+ return result;
-+ }
-+ DEBUG(printk("data= %#x count=%#x 0ffset=%#x\n",*data, count, *ppos));
-+
-+ while(bytes_left){
-+ char tmp;
-+ __get_user(tmp,data);
-+ /* read our header ! */
-+ sbihdr->temp|=tmp << (8*(sbihdr->fpos&3));
-+ if((sbihdr->fpos&3)==3){
-+ if(write_pld_data_word(sbihdr->temp))
-+ {
-+ DEBUG(printk("pos=%d\n",sbihdr->fpos);)
-+ return -EILSEQ;
-+ }
-+ DEBUG(if(i<10){)
-+ DEBUG(printk("fpos2 :%#x data=%#x\n",sbihdr->fpos,sbihdr->temp));
-+ DEBUG(i++);
-+ DEBUG(});
-+ sbihdr->temp=0;
-+ DEBUG(words_written++);
-+ }
-+ sbihdr->fpos++;
-+ data++;
-+ bytes_left--;
-+ }
-+
-+ up(&pld_sem);
-+ return (count);
-+}
-+
-+int pld_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg)
-+{
-+
-+ switch(cmd){
-+
-+#ifdef CONFIG_PLD_HOTSWAP
-+ case PLD_IOC_ADD_PLD_DEV:
-+ {
-+ struct pldhs_dev_desc desc;
-+ struct pldhs_dev_info info;
-+ char *name;
-+ void *data;
-+ int result=0;
-+
-+ result=copy_from_user(&desc,(const void*)arg,sizeof(struct pldhs_dev_desc));
-+ if(result)
-+ return -EFAULT;
-+ result=copy_from_user(&info,(const void*)desc.info,sizeof(struct pldhs_dev_info));
-+ if(result)
-+ return -EFAULT;
-+ name=kmalloc(info.nsize,GFP_KERNEL);
-+ if(!name)
-+ return -ENOMEM;
-+
-+ result=copy_from_user(name,(const void*)desc.name,info.nsize);
-+ if(result){
-+ result=-EFAULT;
-+ goto ioctl_out;
-+ }
-+
-+ data=kmalloc(info.pssize,GFP_KERNEL);
-+ if(!data){
-+ result=-ENOMEM;
-+ goto ioctl_out;
-+ }
-+
-+ result=copy_from_user(data,(const void*)desc.data,info.pssize);
-+ if(result){
-+ result=-EFAULT;
-+ goto ioctl_out1;
-+ }
-+ result=pldhs_add_device(&info,name,data);
-+
-+ ioctl_out1:
-+ kfree(data);
-+ ioctl_out:
-+ kfree(name);
-+ return result;
-+
-+ }
-+
-+ case PLD_IOC_REMOVE_PLD_DEVS:
-+ pldhs_remove_devices();
-+ return 0;
-+
-+ case PLD_IOC_SET_INT_MODE:
-+ if(cmd==3){
-+ printk(KERN_INFO "Interrupt mode set to 3 (Six individual interrupts)\n");
-+ return 0;
-+ }else{
-+ printk(KERN_INFO "There is no interrupt handler available for this mode (%d). You will need to add one\n to implement whatever scheme you require\n");
-+ return -EACCES;
-+ }
-+#endif
-+ default:
-+ return -ENOTTY;
-+ }
-+}
-+
-+
-+static struct file_operations pld_fops={
-+ write: pld_write,
-+ ioctl: pld_ioctl,
-+ open: pld_open,
-+ release: pld_release
-+};
-+
-+static int __init pld_init(void){
-+ int major;
-+ major=register_chrdev(0,"pld",&pld_fops);
-+ printk(KERN_INFO "Using PLD major num=%d\n",major);
-+ if (major<0){
-+ return major;
-+ }
-+ return 0;
-+}
-+
-+__initcall(pld_init);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/pld/pld_hotswap.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,188 @@
-+/*
-+ * linux/drivers/pld/pld_hotswap.c
-+ *
-+ * Pld driver for Altera EPXA Excalibur devices
-+ *
-+ *
-+ * Copyright 2001 Altera Corporation (cdavies@altera.com)
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+/*
-+ * pld_hotswap ops contains the basic operation required for adding
-+ * and removing devices from the system.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/types.h>
-+#include <linux/pagemap.h>
-+#include <linux/slab.h>
-+#include <linux/smp_lock.h>
-+#include <linux/init.h>
-+#include <linux/kmod.h>
-+#include <linux/proc_fs.h>
-+#include <linux/list.h>
-+#include <asm/uaccess.h>
-+#include <linux/pld/pld_hotswap.h>
-+
-+
-+static struct pld_hotswap_ops pldhs_driver_list={
-+ list: LIST_HEAD_INIT(pldhs_driver_list.list),
-+ name: "",
-+};
-+
-+static spinlock_t list_lock=SPIN_LOCK_UNLOCKED;
-+
-+
-+
-+static struct pld_hotswap_ops * pldhs_find_driver(char* name)
-+{
-+ struct pld_hotswap_ops * ptr;
-+ struct list_head *list_pos;
-+
-+ spin_lock(&list_lock);
-+ list_for_each(list_pos,&pldhs_driver_list.list){
-+ ptr=(struct pld_hotswap_ops *)list_pos;
-+ if(!strcmp(name, ptr->name)){
-+ spin_unlock(&list_lock);
-+ return ptr;
-+
-+ }
-+ }
-+ spin_unlock(&list_lock);
-+ return 0;
-+}
-+
-+
-+
-+int pldhs_register_driver(struct pld_hotswap_ops *drv)
-+{
-+
-+ /* Check that the device is not already on the list
-+ * if so, do nothing */
-+ if(pldhs_find_driver(drv->name)){
-+ return 0;
-+ }
-+
-+ printk(KERN_INFO "PLD: Registering hotswap driver %s\n",drv->name);
-+ /* Add this at the start of the list */
-+ spin_lock(&list_lock);
-+ list_add((struct list_head*)drv,&pldhs_driver_list.list);
-+ spin_unlock(&list_lock);
-+
-+ return 0;
-+}
-+
-+int pldhs_unregister_driver(char *name)
-+{
-+ struct pld_hotswap_ops *ptr;
-+
-+ ptr=pldhs_find_driver(name);
-+ if(!ptr){
-+ return -ENODEV;
-+ }
-+
-+ printk(KERN_INFO "PLD: Unregistering hotswap driver%s\n",name);
-+ spin_lock(&list_lock);
-+ list_del((struct list_head*)ptr);
-+ spin_unlock(&list_lock);
-+
-+ return 0;
-+}
-+
-+int pldhs_add_device(struct pldhs_dev_info* dev_info,char *drv_name, void* dev_ps_data)
-+{
-+ struct pld_hotswap_ops * ptr;
-+
-+ ptr=pldhs_find_driver(drv_name);
-+
-+ if(!ptr){
-+ /* try requesting this module*/
-+ request_module(drv_name);
-+ /* is the driver there now? */
-+ ptr=pldhs_find_driver(drv_name);
-+ if(!ptr){
-+ printk("pld hotswap: Failed to load a driver for %s\n",drv_name);
-+ return -ENODEV;
-+ }
-+ }
-+
-+ if(!ptr->add_device){
-+ printk(KERN_WARNING "pldhs: no add_device() function for driver %s\n",drv_name);
-+ return 0;
-+ }
-+
-+ return ptr->add_device(dev_info,dev_ps_data);
-+}
-+
-+int pldhs_remove_devices(void)
-+{
-+ struct list_head *list_pos;
-+ struct pld_hotswap_ops * ptr;
-+
-+
-+ spin_lock(&list_lock);
-+ list_for_each(list_pos,&pldhs_driver_list.list){
-+ ptr=(struct pld_hotswap_ops *)list_pos;
-+ if(ptr->remove_devices)
-+ ptr->remove_devices();
-+
-+ }
-+ spin_unlock(&list_lock);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PROC_FS
-+int pldhs_read_proc(char* buf,char** start,off_t offset,int count,int *eof,void *data){
-+
-+
-+ struct list_head *list_pos;
-+ struct pld_hotswap_ops * ptr;
-+ int i,len=0;
-+
-+ *start=buf;
-+ spin_lock(&list_lock);
-+ list_for_each(list_pos,&pldhs_driver_list.list){
-+ ptr=(struct pld_hotswap_ops *)list_pos;
-+ if(ptr->proc_read){
-+ i=ptr->proc_read(buf,start,offset,count,eof,data);
-+ count-=i;
-+ len+=i;
-+ *start+=i;
-+ }
-+ }
-+ spin_unlock(&list_lock);
-+
-+ *start=NULL;
-+ *eof=1;
-+ return len;
-+}
-+
-+void __init pldhs_init(void){
-+ create_proc_read_entry("pld",0,NULL,pldhs_read_proc,NULL);
-+}
-+
-+__initcall(pldhs_init);
-+#endif
-+
-+EXPORT_SYMBOL(pldhs_register_driver);
-+EXPORT_SYMBOL(pldhs_unregister_driver);
---- linux-2.4.25/drivers/scsi/Makefile~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/scsi/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -21,7 +21,7 @@
-
- O_TARGET := scsidrv.o
-
--export-objs := scsi_syms.o 53c700.o
-+export-objs := scsi_syms.o 53c700.o scsi_error.o
- mod-subdirs := pcmcia ../acorn/scsi
-
-
---- linux-2.4.25/drivers/scsi/scsi.c~2.4.25-vrs2.patch 2003-08-25 13:44:42.000000000 +0200
-+++ linux-2.4.25/drivers/scsi/scsi.c 2004-03-31 17:15:09.000000000 +0200
-@@ -1334,14 +1334,10 @@
- */
- int scsi_retry_command(Scsi_Cmnd * SCpnt)
- {
-- memcpy((void *) SCpnt->cmnd, (void *) SCpnt->data_cmnd,
-- sizeof(SCpnt->data_cmnd));
-- SCpnt->request_buffer = SCpnt->buffer;
-- SCpnt->request_bufflen = SCpnt->bufflen;
-- SCpnt->use_sg = SCpnt->old_use_sg;
-- SCpnt->cmd_len = SCpnt->old_cmd_len;
-- SCpnt->sc_data_direction = SCpnt->sc_old_data_direction;
-- SCpnt->underflow = SCpnt->old_underflow;
-+ /*
-+ * Restore the SCSI command state.
-+ */
-+ scsi_setup_cmd_retry(SCpnt);
-
- /*
- * Zero the sense information from the last time we tried
---- linux-2.4.25/drivers/scsi/scsi.h~2.4.25-vrs2.patch 2003-08-25 13:44:42.000000000 +0200
-+++ linux-2.4.25/drivers/scsi/scsi.h 2004-03-31 17:15:09.000000000 +0200
-@@ -465,6 +465,7 @@
- int sectors);
- extern struct Scsi_Device_Template *scsi_get_request_dev(struct request *);
- extern int scsi_init_cmd_errh(Scsi_Cmnd * SCpnt);
-+extern void scsi_setup_cmd_retry(Scsi_Cmnd *SCpnt);
- extern int scsi_insert_special_cmd(Scsi_Cmnd * SCpnt, int);
- extern void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
- int block_sectors);
-@@ -588,6 +589,7 @@
- unsigned changed:1; /* Data invalid due to media change */
- unsigned busy:1; /* Used to prevent races */
- unsigned lockable:1; /* Able to prevent media removal */
-+ unsigned locked:1; /* Media removal disabled */
- unsigned borken:1; /* Tell the Seagate driver to be
- * painfully slow on this device */
- unsigned tagged_supported:1; /* Supports SCSI-II tagged queuing */
---- linux-2.4.25/drivers/scsi/scsi_dma.c~2.4.25-vrs2.patch 2002-02-25 20:38:04.000000000 +0100
-+++ linux-2.4.25/drivers/scsi/scsi_dma.c 2004-03-31 17:15:09.000000000 +0200
-@@ -30,6 +30,15 @@
- typedef unsigned char FreeSectorBitmap;
- #elif SECTORS_PER_PAGE <= 32
- typedef unsigned int FreeSectorBitmap;
-+#elif SECTORS_PER_PAGE <= 64
-+#if 0
-+typedef unsigned long long FreeSectorBitmap;
-+#else
-+typedef struct {
-+ unsigned long l,h;
-+} FreeSectorBitmap;
-+#define LARGE_MALLOC
-+#endif
- #else
- #error You lose.
- #endif
-@@ -69,6 +78,7 @@
- * to allocate more memory in order to be able to write the
- * data to disk, you would wedge the system.
- */
-+#ifndef LARGE_MALLOC
- void *scsi_malloc(unsigned int len)
- {
- unsigned int nbits, mask;
-@@ -167,6 +177,97 @@
- panic("scsi_free:Bad offset");
- }
-
-+#else
-+
-+void *scsi_malloc(unsigned int len)
-+{
-+ unsigned int nbits;
-+ unsigned long maskl, maskh, flags;
-+ FreeSectorBitmap *fsb;
-+ int i;
-+
-+ if (len % SECTOR_SIZE != 0 || len > PAGE_SIZE)
-+ return NULL;
-+
-+ save_flags_cli (flags);
-+ nbits = len >> 9;
-+ if (nbits < 32) {
-+ maskl = (1 << nbits) - 1;
-+ maskh = 0;
-+ } else {
-+ maskl = (unsigned long)-1;
-+ maskh = (1 << (nbits - 32)) - 1;
-+ }
-+
-+ fsb = dma_malloc_freelist;
-+
-+ for (i = 0; i < dma_sectors / SECTORS_PER_PAGE; i++) {
-+ unsigned long mml, mmh;
-+ int j;
-+ mml = maskl;
-+ mmh = maskh;
-+ j = 0;
-+ do {
-+ if ((fsb->l & mml) == 0 && (fsb->h & mmh) == 0) {
-+ fsb->h |= mmh;
-+ fsb->l |= mml;
-+ restore_flags (flags);
-+ scsi_dma_free_sectors -= nbits;
-+#ifdef DEBUG
-+ printk("SMalloc: %d %p\n",len, dma_malloc_pages[i] + (j << 9));
-+#endif
-+ return (void *) ((unsigned long) dma_malloc_pages[i] + (j << 9));
-+ }
-+ mmh = (mmh << 1) | (mml >> 31);
-+ mml <<= 1;
-+ j++;
-+ } while (!(mmh & (1 << 31)));
-+ fsb ++;
-+ }
-+ return NULL; /* Nope. No more */
-+}
-+
-+int scsi_free(void *obj, unsigned int len)
-+{
-+ unsigned int page, sector, nbits;
-+ unsigned long maskl, maskh, flags;
-+
-+#ifdef DEBUG
-+ printk("scsi_free %p %d\n",obj, len);
-+#endif
-+
-+ for (page = 0; page < dma_sectors / SECTORS_PER_PAGE; page++) {
-+ unsigned long page_addr = (unsigned long) dma_malloc_pages[page];
-+ if ((unsigned long) obj >= page_addr &&
-+ (unsigned long) obj < page_addr + PAGE_SIZE) {
-+ sector = (((unsigned long) obj) - page_addr) >> 9;
-+ nbits = len >> 9;
-+ if (nbits < 32) {
-+ maskl = (1 << nbits) - 1;
-+ maskh = 0;
-+ } else {
-+ maskl = (unsigned long)-1;
-+ maskh = (1 << (nbits - 32)) - 1;
-+ }
-+ if ((sector + nbits) > SECTORS_PER_PAGE)
-+ panic ("scsi_free:Bad memory alignment");
-+ maskh = (maskh << sector) | (maskl >> (32 - sector));
-+ maskl = maskl << sector;
-+ save_flags_cli(flags);
-+ if (((dma_malloc_freelist[page].l & maskl) != maskl) ||
-+ ((dma_malloc_freelist[page].h & maskh) != maskh))
-+ panic("scsi_free:Trying to free unused memory");
-+ scsi_dma_free_sectors += nbits;
-+ dma_malloc_freelist[page].l &= ~maskl;
-+ dma_malloc_freelist[page].h &= ~maskh;
-+ restore_flags(flags);
-+ return 0;
-+ }
-+ }
-+ panic("scsi_free:Bad offset");
-+}
-+#endif
-+
-
- /*
- * Function: scsi_resize_dma_pool
---- linux-2.4.25/drivers/scsi/scsi_error.c~2.4.25-vrs2.patch 2002-11-29 00:53:14.000000000 +0100
-+++ linux-2.4.25/drivers/scsi/scsi_error.c 2004-03-31 17:15:09.000000000 +0200
-@@ -35,6 +35,8 @@
- #include "hosts.h"
- #include "constants.h"
-
-+#include <scsi/scsi_ioctl.h> /* grr */
-+
- /*
- * We must always allow SHUTDOWN_SIGS. Even if we are not a module,
- * the host drivers that we are using may be loaded as modules, and
-@@ -49,6 +51,13 @@
- */
- #define SHUTDOWN_SIGS (sigmask(SIGHUP))
-
-+/*
-+ * The number of times we retry a REQUEST SENSE and TEST UNIT READY
-+ * respectively. This is arbitary.
-+ */
-+#define SENSE_RETRIES 5
-+#define TUR_RETRIES 5
-+
- #ifdef DEBUG
- #define SENSE_TIMEOUT SCSI_TIMEOUT
- #define ABORT_TIMEOUT SCSI_TIMEOUT
-@@ -385,16 +394,12 @@
- */
- STATIC int scsi_eh_retry_command(Scsi_Cmnd * SCpnt)
- {
-- memcpy((void *) SCpnt->cmnd, (void *) SCpnt->data_cmnd,
-- sizeof(SCpnt->data_cmnd));
-- SCpnt->request_buffer = SCpnt->buffer;
-- SCpnt->request_bufflen = SCpnt->bufflen;
-- SCpnt->use_sg = SCpnt->old_use_sg;
-- SCpnt->cmd_len = SCpnt->old_cmd_len;
-- SCpnt->sc_data_direction = SCpnt->sc_old_data_direction;
-- SCpnt->underflow = SCpnt->old_underflow;
-+ int tries = 0;
-
-- scsi_send_eh_cmnd(SCpnt, SCpnt->timeout_per_command);
-+ do {
-+ scsi_setup_cmd_retry(SCpnt);
-+ scsi_send_eh_cmnd(SCpnt, SCpnt->timeout_per_command);
-+ } while (SCpnt->eh_state == NEEDS_RETRY && tries++ < SCpnt->allowed);
-
- /*
- * Hey, we are done. Let's look to see what happened.
-@@ -421,16 +426,10 @@
- static unsigned char generic_sense[6] =
- {REQUEST_SENSE, 0, 0, 0, 255, 0};
- unsigned char scsi_result0[256], *scsi_result = NULL;
-- int saved_result;
-+ int saved_result, tries;
-
- ASSERT_LOCK(&io_request_lock, 0);
-
-- memcpy((void *) SCpnt->cmnd, (void *) generic_sense,
-- sizeof(generic_sense));
--
-- if (SCpnt->device->scsi_level <= SCSI_2)
-- SCpnt->cmnd[1] = SCpnt->lun << 5;
--
- scsi_result = (!SCpnt->host->hostt->unchecked_isa_dma)
- ? &scsi_result0[0] : kmalloc(512, GFP_ATOMIC | GFP_DMA);
-
-@@ -438,24 +437,41 @@
- printk("cannot allocate scsi_result in scsi_request_sense.\n");
- return FAILED;
- }
-- /*
-- * Zero the sense buffer. Some host adapters automatically always request
-- * sense, so it is not a good idea that SCpnt->request_buffer and
-- * SCpnt->sense_buffer point to the same address (DB).
-- * 0 is not a valid sense code.
-- */
-- memset((void *) SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
-- memset((void *) scsi_result, 0, 256);
-
- saved_result = SCpnt->result;
-- SCpnt->request_buffer = scsi_result;
-- SCpnt->request_bufflen = 256;
-- SCpnt->use_sg = 0;
-- SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]);
-- SCpnt->sc_data_direction = SCSI_DATA_READ;
-- SCpnt->underflow = 0;
-
-- scsi_send_eh_cmnd(SCpnt, SENSE_TIMEOUT);
-+ tries = 0;
-+ do {
-+ memcpy((void *) SCpnt->cmnd, (void *) generic_sense,
-+ sizeof(generic_sense));
-+
-+ if (SCpnt->device->scsi_level <= SCSI_2)
-+ SCpnt->cmnd[1] = SCpnt->lun << 5;
-+
-+ /*
-+ * Zero the sense buffer. Some host adapters automatically
-+ * always request sense, so it is not a good idea that
-+ * SCpnt->request_buffer and SCpnt->sense_buffer point to
-+ * the same address (DB). 0 is not a valid sense code.
-+ */
-+ memset((void *) SCpnt->sense_buffer, 0,
-+ sizeof(SCpnt->sense_buffer));
-+ memset((void *) scsi_result, 0, 256);
-+
-+ SCpnt->request_buffer = scsi_result;
-+ SCpnt->request_bufflen = 256;
-+ SCpnt->use_sg = 0;
-+ SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]);
-+ SCpnt->sc_data_direction = SCSI_DATA_READ;
-+ SCpnt->underflow = 0;
-+
-+ scsi_send_eh_cmnd(SCpnt, SENSE_TIMEOUT);
-+ /*
-+ * If the SCSI device responded with "logical unit
-+ * is in process of becoming ready", we need to
-+ * retry this command.
-+ */
-+ } while (SCpnt->eh_state == NEEDS_RETRY && tries++ < SENSE_RETRIES);
-
- /* Last chance to have valid sense data */
- if (!scsi_sense_valid(SCpnt))
-@@ -470,15 +486,8 @@
- * When we eventually call scsi_finish, we really wish to complete
- * the original request, so let's restore the original data. (DB)
- */
-- memcpy((void *) SCpnt->cmnd, (void *) SCpnt->data_cmnd,
-- sizeof(SCpnt->data_cmnd));
- SCpnt->result = saved_result;
-- SCpnt->request_buffer = SCpnt->buffer;
-- SCpnt->request_bufflen = SCpnt->bufflen;
-- SCpnt->use_sg = SCpnt->old_use_sg;
-- SCpnt->cmd_len = SCpnt->old_cmd_len;
-- SCpnt->sc_data_direction = SCpnt->sc_old_data_direction;
-- SCpnt->underflow = SCpnt->old_underflow;
-+ scsi_setup_cmd_retry(SCpnt);
-
- /*
- * Hey, we are done. Let's look to see what happened.
-@@ -496,40 +505,42 @@
- {
- static unsigned char tur_command[6] =
- {TEST_UNIT_READY, 0, 0, 0, 0, 0};
-+ int tries = 0;
-
-- memcpy((void *) SCpnt->cmnd, (void *) tur_command,
-- sizeof(tur_command));
-+ do {
-+ memcpy((void *) SCpnt->cmnd, (void *) tur_command,
-+ sizeof(tur_command));
-
-- if (SCpnt->device->scsi_level <= SCSI_2)
-- SCpnt->cmnd[1] = SCpnt->lun << 5;
-+ if (SCpnt->device->scsi_level <= SCSI_2)
-+ SCpnt->cmnd[1] = SCpnt->lun << 5;
-
-- /*
-- * Zero the sense buffer. The SCSI spec mandates that any
-- * untransferred sense data should be interpreted as being zero.
-- */
-- memset((void *) SCpnt->sense_buffer, 0, sizeof(SCpnt->sense_buffer));
-+ /*
-+ * Zero the sense buffer. The SCSI spec mandates that any
-+ * untransferred sense data should be interpreted as being zero.
-+ */
-+ memset((void *) SCpnt->sense_buffer, 0,
-+ sizeof(SCpnt->sense_buffer));
-
-- SCpnt->request_buffer = NULL;
-- SCpnt->request_bufflen = 0;
-- SCpnt->use_sg = 0;
-- SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]);
-- SCpnt->underflow = 0;
-- SCpnt->sc_data_direction = SCSI_DATA_NONE;
-+ SCpnt->request_buffer = NULL;
-+ SCpnt->request_bufflen = 0;
-+ SCpnt->use_sg = 0;
-+ SCpnt->cmd_len = COMMAND_SIZE(SCpnt->cmnd[0]);
-+ SCpnt->underflow = 0;
-+ SCpnt->sc_data_direction = SCSI_DATA_NONE;
-
-- scsi_send_eh_cmnd(SCpnt, SENSE_TIMEOUT);
-+ scsi_send_eh_cmnd(SCpnt, SENSE_TIMEOUT);
-+ /*
-+ * If the SCSI device responded with "logical unit
-+ * is in process of becoming ready", we need to
-+ * retry this command.
-+ */
-+ } while (SCpnt->eh_state == NEEDS_RETRY && tries++ < TUR_RETRIES);
-
- /*
- * When we eventually call scsi_finish, we really wish to complete
- * the original request, so let's restore the original data. (DB)
- */
-- memcpy((void *) SCpnt->cmnd, (void *) SCpnt->data_cmnd,
-- sizeof(SCpnt->data_cmnd));
-- SCpnt->request_buffer = SCpnt->buffer;
-- SCpnt->request_bufflen = SCpnt->bufflen;
-- SCpnt->use_sg = SCpnt->old_use_sg;
-- SCpnt->cmd_len = SCpnt->old_cmd_len;
-- SCpnt->sc_data_direction = SCpnt->sc_old_data_direction;
-- SCpnt->underflow = SCpnt->old_underflow;
-+ scsi_setup_cmd_retry(SCpnt);
-
- /*
- * Hey, we are done. Let's look to see what happened.
-@@ -589,7 +600,6 @@
-
- host = SCpnt->host;
-
-- retry:
- /*
- * We will use a queued command if possible, otherwise we will emulate the
- * queuing and calling of completion function ourselves.
-@@ -672,14 +682,13 @@
- SCSI_LOG_ERROR_RECOVERY(3,
- printk("scsi_send_eh_cmnd: scsi_eh_completed_normally %x\n", ret));
- switch (ret) {
-- case SUCCESS:
-- SCpnt->eh_state = SUCCESS;
-- break;
-- case NEEDS_RETRY:
-- goto retry;
-- case FAILED:
- default:
-- SCpnt->eh_state = FAILED;
-+ ret = FAILED;
-+ /*FALLTHROUGH*/
-+ case FAILED:
-+ case NEEDS_RETRY:
-+ case SUCCESS:
-+ SCpnt->eh_state = ret;
- break;
- }
- } else {
-@@ -1220,6 +1229,82 @@
-
-
- /*
-+ * Function: scsi_eh_lock_done
-+ *
-+ * Purpose: free the command and request structures associated
-+ * with the error handlers door lock request
-+ *
-+ * Arguments: SCpnt - the SCSI command block for the door lock request.
-+ *
-+ * Returns: Nothing
-+ *
-+ * Notes: We completed the asynchronous door lock request, and
-+ * it has either locked the door or failed. We must free
-+ * the command structures associated with this request.
-+ */
-+static void scsi_eh_lock_done(struct scsi_cmnd *SCpnt)
-+{
-+ struct scsi_request *SRpnt = SCpnt->sc_request;
-+
-+ SCpnt->sc_request = NULL;
-+ SRpnt->sr_command = NULL;
-+
-+ scsi_release_command(SCpnt);
-+ scsi_release_request(SRpnt);
-+}
-+
-+
-+/*
-+ * Function: scsi_eh_lock_door
-+ *
-+ * Purpose: Prevent medium removal for the specified device
-+ *
-+ * Arguments: dev - SCSI device to prevent medium removal
-+ *
-+ * Locking: We must be called from process context;
-+ * scsi_allocate_request() may sleep.
-+ *
-+ * Returns: Nothing
-+ *
-+ * Notes: We queue up an asynchronous "ALLOW MEDIUM REMOVAL" request
-+ * on the head of the devices request queue, and continue.
-+ *
-+ * Bugs: scsi_allocate_request() may sleep waiting for existing
-+ * requests to be processed. However, since we haven't
-+ * kicked off any request processing for this host, this
-+ * may deadlock.
-+ *
-+ * If scsi_allocate_request() fails for what ever reason,
-+ * we completely forget to lock the door.
-+ */
-+STATIC void scsi_eh_lock_door(struct scsi_device *dev)
-+{
-+ struct scsi_request *SRpnt = scsi_allocate_request(dev);
-+
-+ if (SRpnt == NULL) {
-+ /* what now? */
-+ return;
-+ }
-+
-+ SRpnt->sr_cmnd[0] = ALLOW_MEDIUM_REMOVAL;
-+ SRpnt->sr_cmnd[1] = (dev->scsi_level <= SCSI_2) ? (dev->lun << 5) : 0;
-+ SRpnt->sr_cmnd[2] = 0;
-+ SRpnt->sr_cmnd[3] = 0;
-+ SRpnt->sr_cmnd[4] = SCSI_REMOVAL_PREVENT;
-+ SRpnt->sr_cmnd[5] = 0;
-+ SRpnt->sr_data_direction = SCSI_DATA_NONE;
-+ SRpnt->sr_bufflen = 0;
-+ SRpnt->sr_buffer = NULL;
-+ SRpnt->sr_allowed = 5;
-+ SRpnt->sr_done = scsi_eh_lock_done;
-+ SRpnt->sr_timeout_per_command = 10 * HZ;
-+ SRpnt->sr_cmd_len = COMMAND_SIZE(SRpnt->sr_cmnd[0]);
-+
-+ scsi_insert_special_req(SRpnt, 1);
-+}
-+
-+
-+/*
- * Function: scsi_restart_operations
- *
- * Purpose: Restart IO operations to the specified host.
-@@ -1241,6 +1326,15 @@
- ASSERT_LOCK(&io_request_lock, 0);
-
- /*
-+ * If the door was locked, we need to insert a door lock request
-+ * onto the head of the SCSI request queue for the device. There
-+ * is no point trying to lock the door of an off-line device.
-+ */
-+ for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next)
-+ if (SDpnt->online && SDpnt->locked)
-+ scsi_eh_lock_door(SDpnt);
-+
-+ /*
- * Next free up anything directly waiting upon the host. This will be
- * requests for character device operations, and also for ioctls to queued
- * block devices.
-@@ -1260,8 +1354,7 @@
- request_queue_t *q;
- if ((host->can_queue > 0 && (host->host_busy >= host->can_queue))
- || (host->host_blocked)
-- || (host->host_self_blocked)
-- || (SDpnt->device_blocked)) {
-+ || (host->host_self_blocked)) {
- break;
- }
- q = &SDpnt->request_queue;
-@@ -1271,136 +1364,202 @@
- }
-
- /*
-- * Function: scsi_unjam_host
-+ * Function: scsi_eh_find_failed_command
- *
-- * Purpose: Attempt to fix a host which has a command that failed for
-- * some reason.
-+ * Purpose: Find a failed Scsi_Cmnd structure on a device.
- *
-- * Arguments: host - host that needs unjamming.
-- *
-- * Returns: Nothing
-+ * Arguments: SDpnt - Scsi_Device structure
- *
-- * Notes: When we come in here, we *know* that all commands on the
-- * bus have either completed, failed or timed out. We also
-- * know that no further commands are being sent to the host,
-- * so things are relatively quiet and we have freedom to
-- * fiddle with things as we wish.
-+ * Returns: Pointer to Scsi_Cmnd structure, or NULL on failure
-+ */
-+STATIC Scsi_Cmnd *scsi_eh_find_failed_command(Scsi_Device *SDpnt)
-+{
-+ Scsi_Cmnd *SCpnt;
-+
-+ for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next)
-+ if (SCpnt->state == SCSI_STATE_FAILED ||
-+ SCpnt->state == SCSI_STATE_TIMEOUT)
-+ return SCpnt;
-+
-+ return NULL;
-+}
-+
-+
-+/*
-+ * Function: scsi_eh_test_and_retry
- *
-- * Additional note: This is only the *default* implementation. It is possible
-- * for individual drivers to supply their own version of this
-- * function, and if the maintainer wishes to do this, it is
-- * strongly suggested that this function be taken as a template
-- * and modified. This function was designed to correctly handle
-- * problems for about 95% of the different cases out there, and
-- * it should always provide at least a reasonable amount of error
-- * recovery.
-+ * Purpose: Try to retry a failed command.
- *
-- * Note3: Any command marked 'FAILED' or 'TIMEOUT' must eventually
-- * have scsi_finish_command() called for it. We do all of
-- * the retry stuff here, so when we restart the host after we
-- * return it should have an empty queue.
-+ * Arguments: SCpnt - scsi command structure
-+ * done - list of commands that have been successfully
-+ * completed.
-+ *
-+ * Returns: SUCCESS or FAILED
-+ *
-+ * Note: If the TEST UNIT READY command successfully executes,
-+ * but returns some form of "device not ready", we wait
-+ * a while, and retry 3 times. The device could be still
-+ * re-initialising.
- */
--STATIC int scsi_unjam_host(struct Scsi_Host *host)
-+STATIC int scsi_eh_test_and_retry(Scsi_Cmnd *SCpnt, Scsi_Cmnd **done)
- {
-- int devices_failed;
-- int numfailed;
-- int ourrtn;
-- int rtn = FALSE;
-- int result;
-- Scsi_Cmnd *SCloop;
-- Scsi_Cmnd *SCpnt;
-- Scsi_Device *SDpnt;
-- Scsi_Device *SDloop;
-- Scsi_Cmnd *SCdone;
-- int timed_out;
-+ int rtn, tries = 3;
-
-- ASSERT_LOCK(&io_request_lock, 0);
-+ do {
-+ rtn = scsi_test_unit_ready(SCpnt);
-+ if (rtn != SUCCESS)
-+ return rtn;
-
-- SCdone = NULL;
-+ if (scsi_unit_is_ready(SCpnt))
-+ break;
-+
-+ if (tries-- == 0)
-+ return FAILED;
-+
-+ scsi_sleep(5 * HZ);
-+ } while (1);
-+
-+ rtn = scsi_eh_retry_command(SCpnt);
-+ if (rtn == SUCCESS) {
-+ SCpnt->host->host_failed--;
-+ scsi_eh_finish_command(done, SCpnt);
-+ }
-+
-+ return rtn;
-+}
-
-- /*
-- * First, protect against any sort of race condition. If any of the outstanding
-- * commands are in states that indicate that we are not yet blocked (i.e. we are
-- * not in a quiet state) then we got woken up in error. If we ever end up here,
-- * we need to re-examine some of the assumptions.
-- */
-- for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
-- for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next) {
-- if (SCpnt->state == SCSI_STATE_FAILED
-- || SCpnt->state == SCSI_STATE_TIMEOUT
-- || SCpnt->state == SCSI_STATE_INITIALIZING
-- || SCpnt->state == SCSI_STATE_UNUSED) {
-- continue;
-- }
-- /*
-- * Rats. Something is still floating around out there. This could
-- * be the result of the fact that the upper level drivers are still frobbing
-- * commands that might have succeeded. There are two outcomes. One is that
-- * the command block will eventually be freed, and the other one is that
-- * the command will be queued and will be finished along the way.
-- */
-- SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler prematurely woken - commands still active (%p %x %d)\n", SCpnt, SCpnt->state, SCpnt->target));
-
- /*
-- * panic("SCSI Error handler woken too early\n");
-+ * Function: scsi_eh_restart_device
- *
-- * This is no longer a problem, since now the code cares only about
-- * SCSI_STATE_TIMEOUT and SCSI_STATE_FAILED.
-- * Other states are useful only to release active commands when devices are
-- * set offline. If (host->host_active == host->host_busy) we can safely assume
-- * that there are no commands in state other then TIMEOUT od FAILED. (DB)
-+ * Purpose: Retry all failed or timed out commands for a device
- *
-- * FIXME:
-- * It is not easy to release correctly commands according to their state when
-- * devices are set offline, when the state is neither TIMEOUT nor FAILED.
-- * When a device is set offline, we can have some command with
-- * rq_status=RQ_SCSY_BUSY, owner=SCSI_STATE_HIGHLEVEL,
-- * state=SCSI_STATE_INITIALIZING and the driver module cannot be released.
-- * (DB, 17 May 1998)
-+ * Arguments: SDpnt - SCSI device to retry
-+ * done - list of commands that have been successfully
-+ * completed.
-+ *
-+ * Returns: SUCCESS or failure code
- */
-+STATIC int scsi_eh_restart_device(Scsi_Device *SDpnt, Scsi_Cmnd **done)
-+{
-+ Scsi_Cmnd *SCpnt, *SCnext;
-+ int rtn = SUCCESS;
-+
-+ for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCnext) {
-+ SCnext = SCpnt->next;
-+
-+ if (SCpnt->state == SCSI_STATE_FAILED ||
-+ SCpnt->state == SCSI_STATE_TIMEOUT) {
-+ rtn = scsi_eh_test_and_retry(SCpnt, done);
-+ if (rtn != SUCCESS)
-+ break;
-+ }
-+ }
-+
-+ return rtn;
-+}
-+
-+/*
-+ * Function: scsi_eh_set_device_offline
-+ *
-+ * Purpose: set a device off line
-+ *
-+ * Arguments: SDpnt - SCSI device to take off line
-+ * done - list of commands that have been successfully
-+ * completed.
-+ * reason - text string describing why the device is off-line
-+ *
-+ * Returns: Nothing
-+ *
-+ * Notes: In addition, we complete each failed or timed out command
-+ * attached to this device.
-+ */
-+STATIC void scsi_eh_set_device_offline(Scsi_Device *SDpnt, Scsi_Cmnd **done,
-+ const char *reason)
-+{
-+ Scsi_Cmnd *SCpnt, *SCnext;
-+
-+ printk(KERN_ERR "scsi: device set offline - %s: "
-+ "host %d channel %d id %d lun %d\n",
-+ reason, SDpnt->host->host_no, SDpnt->channel,
-+ SDpnt->id, SDpnt->lun);
-+
-+ SDpnt->online = FALSE;
-+
-+ for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCnext) {
-+ SCnext = SCpnt->next;
-+
-+ switch (SCpnt->state) {
-+ case SCSI_STATE_TIMEOUT:
-+ SCpnt->result |= DRIVER_TIMEOUT;
-+ /*FALLTHROUGH*/
-+
-+ case SCSI_STATE_FAILED:
-+ SCSI_LOG_ERROR_RECOVERY(3,
-+ printk("Finishing command for device %d %x\n",
-+ SDpnt->id, SCpnt->result));
-+
-+ SDpnt->host->host_failed--;
-+ scsi_eh_finish_command(done, SCpnt);
-+ break;
-+
-+ default:
-+ break;
- }
- }
-+}
-+
-+static void scsi_unjam_request_sense(struct Scsi_Host *host, Scsi_Cmnd **done)
-+{
-+ int rtn;
-+ int result;
-+ Scsi_Cmnd *SCpnt;
-+ Scsi_Device *SDpnt;
-
- /*
- * Next, see if we need to request sense information. if so,
- * then get it now, so we have a better idea of what to do.
-- * FIXME(eric) this has the unfortunate side effect that if a host
-- * adapter does not automatically request sense information, that we end
-- * up shutting it down before we request it. All hosts should be doing this
-- * anyways, so for now all I have to say is tough noogies if you end up in here.
-- * On second thought, this is probably a good idea. We *really* want to give
-- * authors an incentive to automatically request this.
-+ * FIXME(eric) this has the unfortunate side effect that if a
-+ * host adapter does not automatically request sense information,
-+ * that we end up shutting it down before we request it. All
-+ * hosts should be doing this anyways, so for now all I have
-+ * to say is tough noogies if you end up in here. On second
-+ * thought, this is probably a good idea. We *really* want
-+ * to give authors an incentive to automatically request this.
- */
-- SCSI_LOG_ERROR_RECOVERY(3, printk("scsi_unjam_host: Checking to see if we need to request sense\n"));
-+ SCSI_LOG_ERROR_RECOVERY(3,
-+ printk("scsi_unjam_host: Checking to see if we need to request sense\n"));
-
- for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
- for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next) {
-- if (SCpnt->state != SCSI_STATE_FAILED || scsi_sense_valid(SCpnt)) {
-+ if (SCpnt->state != SCSI_STATE_FAILED || scsi_sense_valid(SCpnt))
- continue;
-- }
-- SCSI_LOG_ERROR_RECOVERY(2, printk("scsi_unjam_host: Requesting sense for %d\n",
-- SCpnt->target));
-+
-+ SCSI_LOG_ERROR_RECOVERY(2,
-+ printk("scsi_unjam_host: Requesting sense for %d\n",
-+ SCpnt->target));
- rtn = scsi_request_sense(SCpnt);
-- if (rtn != SUCCESS) {
-+ if (rtn != SUCCESS)
- continue;
-- }
-- SCSI_LOG_ERROR_RECOVERY(3, printk("Sense requested for %p - result %x\n",
-- SCpnt, SCpnt->result));
-+
-+ SCSI_LOG_ERROR_RECOVERY(3,
-+ printk("Sense requested for %p - result %x\n",
-+ SCpnt, SCpnt->result));
- SCSI_LOG_ERROR_RECOVERY(3, print_sense("bh", SCpnt));
-
- result = scsi_decide_disposition(SCpnt);
-
- /*
-- * If the result was normal, then just pass it along to the
-- * upper level.
-+ * If the result was normal, then just pass
-+ * it along to the upper level.
- */
- if (result == SUCCESS) {
- SCpnt->host->host_failed--;
-- scsi_eh_finish_command(&SCdone, SCpnt);
-+ scsi_eh_finish_command(done, SCpnt);
- }
-- if (result != NEEDS_RETRY) {
-+ if (result != NEEDS_RETRY)
- continue;
-- }
-+
- /*
- * We only come in here if we want to retry a
- * command. The test to see whether the command
-@@ -1410,20 +1569,29 @@
- */
- SCpnt->state = NEEDS_RETRY;
- rtn = scsi_eh_retry_command(SCpnt);
-- if (rtn != SUCCESS) {
-+ if (rtn != SUCCESS)
- continue;
-- }
-+
- /*
- * We eventually hand this one back to the top level.
- */
- SCpnt->host->host_failed--;
-- scsi_eh_finish_command(&SCdone, SCpnt);
-+ scsi_eh_finish_command(done, SCpnt);
- }
- }
-+}
-+
-+static void scsi_unjam_count(struct Scsi_Host *host, Scsi_Cmnd **done)
-+{
-+ Scsi_Device *SDpnt;
-+ Scsi_Cmnd *SCpnt;
-+ int devices_failed;
-+ int numfailed;
-+ int timed_out;
-
- /*
-- * Go through the list of commands and figure out where we stand and how bad things
-- * really are.
-+ * Go through the list of commands and figure out where we
-+ * stand and how bad things really are.
- */
- numfailed = 0;
- timed_out = 0;
-@@ -1433,359 +1601,478 @@
-
- for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next) {
- if (SCpnt->state == SCSI_STATE_FAILED) {
-- SCSI_LOG_ERROR_RECOVERY(5, printk("Command to ID %d failed\n",
-- SCpnt->target));
-+ SCSI_LOG_ERROR_RECOVERY(5,
-+ printk("Command to ID %d failed\n",
-+ SCpnt->target));
- numfailed++;
- device_error++;
- }
- if (SCpnt->state == SCSI_STATE_TIMEOUT) {
-- SCSI_LOG_ERROR_RECOVERY(5, printk("Command to ID %d timedout\n",
-- SCpnt->target));
-+ SCSI_LOG_ERROR_RECOVERY(5,
-+ printk("Command to ID %d timedout\n",
-+ SCpnt->target));
- timed_out++;
- device_error++;
- }
- }
-- if (device_error > 0) {
-+ if (device_error > 0)
- devices_failed++;
-- }
- }
-
-- SCSI_LOG_ERROR_RECOVERY(2, printk("Total of %d+%d commands on %d devices require eh work\n",
-- numfailed, timed_out, devices_failed));
-+ SCSI_LOG_ERROR_RECOVERY(2,
-+ printk("Total of %d+%d commands on %d devices require eh work\n",
-+ numfailed, timed_out, devices_failed));
-+}
-+
-+static void scsi_unjam_abort(struct Scsi_Host *host, Scsi_Cmnd **done)
-+{
-+ Scsi_Device *SDpnt;
-+ Scsi_Cmnd *SCpnt;
-+ int rtn;
-
-- if (host->host_failed == 0) {
-- ourrtn = TRUE;
-- goto leave;
-- }
- /*
-- * Next, try and see whether or not it makes sense to try and abort
-- * the running command. This only works out to be the case if we have
-- * one command that has timed out. If the command simply failed, it
-- * makes no sense to try and abort the command, since as far as the
-- * host adapter is concerned, it isn't running.
-+ * Next, try and see whether or not it makes sense to try and
-+ * abort the running command. This only works out to be the
-+ * case if we have one command that has timed out. If the
-+ * command simply failed, it makes no sense to try and abort
-+ * the command, since as far as the host adapter is concerned,
-+ * it isn't running.
- */
-
-- SCSI_LOG_ERROR_RECOVERY(3, printk("scsi_unjam_host: Checking to see if we want to try abort\n"));
-+ SCSI_LOG_ERROR_RECOVERY(3,
-+ printk("scsi_unjam_host: Checking to see if we want to try abort\n"));
-
- for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
-- for (SCloop = SDpnt->device_queue; SCloop; SCloop = SCloop->next) {
-- if (SCloop->state != SCSI_STATE_TIMEOUT) {
-+ for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next) {
-+ if (SCpnt->state != SCSI_STATE_TIMEOUT)
- continue;
-- }
-- rtn = scsi_try_to_abort_command(SCloop, ABORT_TIMEOUT);
-- if (rtn == SUCCESS) {
-- rtn = scsi_test_unit_ready(SCloop);
-
-- if (rtn == SUCCESS && scsi_unit_is_ready(SCloop)) {
-- rtn = scsi_eh_retry_command(SCloop);
--
-- if (rtn == SUCCESS) {
-- SCloop->host->host_failed--;
-- scsi_eh_finish_command(&SCdone, SCloop);
-- }
-- }
-- }
-+ rtn = scsi_try_to_abort_command(SCpnt, ABORT_TIMEOUT);
-+ if (rtn == SUCCESS)
-+ scsi_eh_test_and_retry(SCpnt, done);
- }
- }
-+}
-+
-+static void scsi_unjam_device_reset(struct Scsi_Host *host, Scsi_Cmnd **done)
-+{
-+ Scsi_Device *SDpnt;
-+ Scsi_Cmnd *SCpnt;
-+ int rtn;
-
-- /*
-- * If we have corrected all of the problems, then we are done.
-- */
-- if (host->host_failed == 0) {
-- ourrtn = TRUE;
-- goto leave;
-- }
- /*
- * Either the abort wasn't appropriate, or it didn't succeed.
-- * Now try a bus device reset. Still, look to see whether we have
-- * multiple devices that are jammed or not - if we have multiple devices,
-- * it makes no sense to try BUS_DEVICE_RESET - we really would need
-- * to try a BUS_RESET instead.
-+ * Now try a bus device reset. Still, look to see whether we
-+ * have multiple devices that are jammed or not - if we have
-+ * multiple devices, it makes no sense to try BUS_DEVICE_RESET
-+ * - we really would need to try a BUS_RESET instead.
- *
-- * Does this make sense - should we try BDR on each device individually?
-- * Yes, definitely.
-+ * Does this make sense - should we try BDR on each device
-+ * individually? Yes, definitely.
- */
-- SCSI_LOG_ERROR_RECOVERY(3, printk("scsi_unjam_host: Checking to see if we want to try BDR\n"));
-+ SCSI_LOG_ERROR_RECOVERY(3,
-+ printk("scsi_unjam_host: Checking to see if we want to try BDR\n"));
-
- for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
-- for (SCloop = SDpnt->device_queue; SCloop; SCloop = SCloop->next) {
-- if (SCloop->state == SCSI_STATE_FAILED
-- || SCloop->state == SCSI_STATE_TIMEOUT) {
-- break;
-- }
-- }
--
-- if (SCloop == NULL) {
-+ SCpnt = scsi_eh_find_failed_command(SDpnt);
-+ if (SCpnt == NULL)
- continue;
-- }
-+
- /*
-- * OK, we have a device that is having problems. Try and send
-- * a bus device reset to it.
-- *
-- * FIXME(eric) - make sure we handle the case where multiple
-- * commands to the same device have failed. They all must
-- * get properly restarted.
-+ * OK, we have a device that is having problems.
-+ * Try and send a bus device reset to it.
- */
-- rtn = scsi_try_bus_device_reset(SCloop, RESET_TIMEOUT);
-+ rtn = scsi_try_bus_device_reset(SCpnt, RESET_TIMEOUT);
-
-- if (rtn == SUCCESS) {
-- rtn = scsi_test_unit_ready(SCloop);
-+ /*
-+ * A successful bus device reset causes all commands
-+ * currently executing on the device to terminate.
-+ * We expect the HBA driver to "forget" all commands
-+ * associated with this device.
-+ *
-+ * Retry each failed or timed out command currently
-+ * outstanding for this device.
-+ *
-+ * If any command fails, bail out. We will try a
-+ * bus reset instead.
-+ */
-+ if (rtn == SUCCESS)
-+ scsi_eh_restart_device(SDpnt, done);
-+ }
-+}
-
-- if (rtn == SUCCESS && scsi_unit_is_ready(SCloop)) {
-- rtn = scsi_eh_retry_command(SCloop);
-+static void scsi_unjam_bus_reset(struct Scsi_Host *host, Scsi_Cmnd **done)
-+{
-+ Scsi_Device *SDpnt;
-+ Scsi_Cmnd *SCpnt;
-+ int rtn, channel, max_channel = 0;
-
-- if (rtn == SUCCESS) {
-- SCloop->host->host_failed--;
-- scsi_eh_finish_command(&SCdone, SCloop);
-- }
-- }
-- }
-- }
-+ /*
-+ * If we ended up here, we have serious problems. The only thing
-+ * left to try is a full bus reset. If someone has grabbed the
-+ * bus and isn't letting go, then perhaps this will help.
-+ */
-+ SCSI_LOG_ERROR_RECOVERY(3,
-+ printk("scsi_unjam_host: Try hard bus reset\n"));
-
-- if (host->host_failed == 0) {
-- ourrtn = TRUE;
-- goto leave;
-- }
- /*
-- * If we ended up here, we have serious problems. The only thing left
-- * to try is a full bus reset. If someone has grabbed the bus and isn't
-- * letting go, then perhaps this will help.
-+ * Find the maximum channel number for this host.
- */
-- SCSI_LOG_ERROR_RECOVERY(3, printk("scsi_unjam_host: Try hard bus reset\n"));
-+ for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next)
-+ if (SDpnt->channel > max_channel)
-+ max_channel = SDpnt->channel;
-
-- /*
-- * We really want to loop over the various channels, and do this on
-- * a channel by channel basis. We should also check to see if any
-- * of the failed commands are on soft_reset devices, and if so, skip
-- * the reset.
-+ /*
-+ * Loop over each channel, and see if it any device on
-+ * each channel has failed.
- */
-- for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
-- next_device:
-- for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next) {
-- if (SCpnt->state != SCSI_STATE_FAILED
-- && SCpnt->state != SCSI_STATE_TIMEOUT) {
-+ for (channel = 0; channel <= max_channel; channel++) {
-+ Scsi_Cmnd *failed_command;
-+ int soft_reset;
-+
-+ try_again:
-+ failed_command = NULL;
-+ soft_reset = 0;
-+
-+ /*
-+ * Loop over each device on this channel locating any
-+ * failed command. We need a Scsi_Cmnd structure to
-+ * call the bus reset function.
-+ *
-+ * We also need to check if any of the failed commands
-+ * are on soft_reset devices, and if so, skip the reset.
-+ */
-+ for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
-+ if (SDpnt->channel != channel)
- continue;
-- }
-- /*
-- * We have a failed command. Make sure there are no other failed
-- * commands on the same channel that are timed out and implement a
-- * soft reset.
-- */
-- for (SDloop = host->host_queue; SDloop; SDloop = SDloop->next) {
-- for (SCloop = SDloop->device_queue; SCloop; SCloop = SCloop->next) {
-- if (SCloop->channel != SCpnt->channel) {
-- continue;
-- }
-- if (SCloop->state != SCSI_STATE_FAILED
-- && SCloop->state != SCSI_STATE_TIMEOUT) {
-- continue;
-- }
-- if (SDloop->soft_reset && SCloop->state == SCSI_STATE_TIMEOUT) {
-- /*
-- * If this device uses the soft reset option, and this
-- * is one of the devices acting up, then our only
-- * option is to wait a bit, since the command is
-- * supposedly still running.
-- *
-- * FIXME(eric) - right now we will just end up falling
-- * through to the 'take device offline' case.
-- *
-- * FIXME(eric) - It is possible that the command completed
-- * *after* the error recovery procedure started, and if this
-- * is the case, we are worrying about nothing here.
-- */
-
-- scsi_sleep(1 * HZ);
-- goto next_device;
-- }
-- }
-- }
-+ SCpnt = scsi_eh_find_failed_command(SDpnt);
-+ if (SCpnt)
-+ failed_command = SCpnt;
-
- /*
-- * We now know that we are able to perform a reset for the
-- * bus that SCpnt points to. There are no soft-reset devices
-- * with outstanding timed out commands.
-+ * If this device has timed out or failed commands,
-+ * and uses the soft_reset option.
- */
-- rtn = scsi_try_bus_reset(SCpnt);
-- if (rtn == SUCCESS) {
-- for (SDloop = host->host_queue; SDloop; SDloop = SDloop->next) {
-- for (SCloop = SDloop->device_queue; SCloop; SCloop = SCloop->next) {
-- if (SCloop->channel != SCpnt->channel) {
-- continue;
-- }
-- if (SCloop->state != SCSI_STATE_FAILED
-- && SCloop->state != SCSI_STATE_TIMEOUT) {
-- continue;
-- }
-- rtn = scsi_test_unit_ready(SCloop);
-+ if (SCpnt && SDpnt->soft_reset)
-+ soft_reset = 1;
-+ }
-
-- if (rtn == SUCCESS && scsi_unit_is_ready(SCloop)) {
-- rtn = scsi_eh_retry_command(SCloop);
-+ /*
-+ * If this channel hasn't failed, we
-+ * don't need to reset it.
-+ */
-+ if (!failed_command)
-+ continue;
-
-- if (rtn == SUCCESS) {
-- SCpnt->host->host_failed--;
-- scsi_eh_finish_command(&SCdone, SCloop);
-- }
-- }
-- /*
-- * If the bus reset worked, but we are still unable to
-- * talk to the device, take it offline.
-- * FIXME(eric) - is this really the correct thing to do?
-- */
-- if (rtn != SUCCESS) {
-- printk(KERN_INFO "scsi: device set offline - not ready or command retry failed after bus reset: host %d channel %d id %d lun %d\n", SDloop->host->host_no, SDloop->channel, SDloop->id, SDloop->lun);
-+ /*
-+ * If this device uses the soft reset option, and this
-+ * is one of the devices acting up, then our only
-+ * option is to wait a bit, since the command is
-+ * supposedly still running.
-+ *
-+ * FIXME(eric) - right now we will just end up falling
-+ * through to the 'take device offline' case.
-+ *
-+ * FIXME(eric) - It is possible that the command completed
-+ * *after* the error recovery procedure started, and if
-+ * this is the case, we are worrying about nothing here.
-+ *
-+ * FIXME(rmk) - This should be bounded; we shouldn't wait
-+ * for an infinite amount of time for any device.
-+ */
-+ if (soft_reset) {
-+ SCSI_LOG_ERROR_RECOVERY(3,
-+ printk("scsi_unjam_host: unable to try bus "
-+ "reset for host %d channel %d\n",
-+ host->host_no, channel));
-+ scsi_sleep(1 * HZ);
-+ goto try_again;
-+ }
-
-- SDloop->online = FALSE;
-- SDloop->host->host_failed--;
-- scsi_eh_finish_command(&SCdone, SCloop);
-- }
-- }
-- }
-+ /*
-+ * We now know that we are able to perform a reset for the
-+ * bus that SCpnt points to. There are no soft-reset devices
-+ * with outstanding timed out commands.
-+ */
-+ rtn = scsi_try_bus_reset(failed_command);
-+
-+ /*
-+ * If we failed to reset the bus, move on to the next bus.
-+ */
-+ if (rtn != SUCCESS)
-+ continue;
-+
-+ /*
-+ * We succeeded. Retry each failed command.
-+ */
-+ for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
-+ if (SDpnt->channel != channel)
-+ continue;
-+
-+ rtn = scsi_eh_restart_device(SDpnt, done);
-+
-+ if (rtn != SUCCESS) {
-+ SCpnt = scsi_eh_find_failed_command(SDpnt);
-+
-+ /*
-+ * This device failed again. Since a bus
-+ * reset freed it up, chances are we've
-+ * hit the same problem, so try the same
-+ * solution. We also need to ensure that
-+ * the SCSI bus is in the BUS FREE state
-+ * so we can try to talk to other devices.
-+ */
-+ scsi_try_bus_reset(SCpnt);
-+ scsi_eh_set_device_offline(SDpnt, done,
-+ "not ready or command retry "
-+ "failed after bus reset");
- }
- }
- }
-+}
-+
-+static void scsi_unjam_host_reset(struct Scsi_Host *host, Scsi_Cmnd **done)
-+{
-+ Scsi_Device *SDpnt;
-+ Scsi_Cmnd *SCpnt;
-+ Scsi_Cmnd *failed_command = NULL;
-+ int rtn, soft_reset;
-
-- if (host->host_failed == 0) {
-- ourrtn = TRUE;
-- goto leave;
-- }
- /*
-- * If we ended up here, we have serious problems. The only thing left
-- * to try is a full host reset - perhaps the firmware on the device
-- * crashed, or something like that.
-+ * If we ended up here, we have serious problems. The only thing
-+ * left to try is a full host reset - perhaps the firmware on the
-+ * device crashed, or something like that.
- *
-- * It is assumed that a succesful host reset will cause *all* information
-- * about the command to be flushed from both the host adapter *and* the
-- * device.
-+ * It is assumed that a succesful host reset will cause *all*
-+ * information about the command to be flushed from both the host
-+ * adapter *and* the device.
- *
-- * FIXME(eric) - it isn't clear that devices that implement the soft reset
-- * option can ever be cleared except via cycling the power. The problem is
-- * that sending the host reset command will cause the host to forget
-- * about the pending command, but the device won't forget. For now, we
-- * skip the host reset option if any of the failed devices are configured
-- * to use the soft reset option.
-+ * FIXME(eric) - it isn't clear that devices that implement the
-+ * soft reset option can ever be cleared except via cycling the
-+ * power. The problem is that sending the host reset command will
-+ * cause the host to forget about the pending command, but the
-+ * device won't forget. For now, we skip the host reset option
-+ * if any of the failed devices are configured to use the soft
-+ * reset option.
- */
-+ SCSI_LOG_ERROR_RECOVERY(3,
-+ printk("scsi_unjam_host: Try host reset\n"));
-+
-+ try_again:
-+ failed_command = NULL;
-+ soft_reset = 0;
-+
- for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
-- next_device2:
-- for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next) {
-- if (SCpnt->state != SCSI_STATE_FAILED
-- && SCpnt->state != SCSI_STATE_TIMEOUT) {
-- continue;
-- }
-- if (SDpnt->soft_reset && SCpnt->state == SCSI_STATE_TIMEOUT) {
-- /*
-- * If this device uses the soft reset option, and this
-- * is one of the devices acting up, then our only
-- * option is to wait a bit, since the command is
-- * supposedly still running.
-- *
-- * FIXME(eric) - right now we will just end up falling
-- * through to the 'take device offline' case.
-- */
-- SCSI_LOG_ERROR_RECOVERY(3,
-- printk("scsi_unjam_host: Unable to try hard host reset\n"));
-+ /*
-+ * Locate any failed commands for this device.
-+ */
-+ SCpnt = scsi_eh_find_failed_command(SDpnt);
-+ if (SCpnt)
-+ failed_command = SCpnt;
-
-- /*
-- * Due to the spinlock, we will never get out of this
-- * loop without a proper wait. (DB)
-- */
-- scsi_sleep(1 * HZ);
-+ /*
-+ * If this device has timed out or failed commands,
-+ * and uses the soft_reset option.
-+ */
-+ if (SCpnt && SDpnt->soft_reset)
-+ soft_reset = 1;
-+ }
-
-- goto next_device2;
-- }
-- SCSI_LOG_ERROR_RECOVERY(3, printk("scsi_unjam_host: Try hard host reset\n"));
-+ /*
-+ * If this device uses the soft reset option, and this
-+ * is one of the devices acting up, then our only
-+ * option is to wait a bit, since the command is
-+ * supposedly still running.
-+ *
-+ * FIXME(eric) - right now we will just end up falling
-+ * through to the 'take device offline' case.
-+ *
-+ * FIXME(rmk) - This should be bounded; we shouldn't wait
-+ * for an infinite amount of time for any device.
-+ */
-+ if (soft_reset) {
-+ SCSI_LOG_ERROR_RECOVERY(3,
-+ printk("scsi_unjam_host: unable to try "
-+ "hard host reset\n"));
-
- /*
-- * FIXME(eric) - we need to obtain a valid SCpnt to perform this call.
-+ * Due to the spinlock, we will never get out of this
-+ * loop without a proper wait. (DB)
- */
-- rtn = scsi_try_host_reset(SCpnt);
-- if (rtn == SUCCESS) {
-- /*
-- * FIXME(eric) we assume that all commands are flushed from the
-- * controller. We should get a DID_RESET for all of the commands
-- * that were pending. We should ignore these so that we can
-- * guarantee that we are in a consistent state.
-- *
-- * I believe this to be the case right now, but this needs to be
-- * tested.
-- */
-- for (SDloop = host->host_queue; SDloop; SDloop = SDloop->next) {
-- for (SCloop = SDloop->device_queue; SCloop; SCloop = SCloop->next) {
-- if (SCloop->state != SCSI_STATE_FAILED
-- && SCloop->state != SCSI_STATE_TIMEOUT) {
-- continue;
-- }
-- rtn = scsi_test_unit_ready(SCloop);
--
-- if (rtn == SUCCESS && scsi_unit_is_ready(SCloop)) {
-- rtn = scsi_eh_retry_command(SCloop);
-+ scsi_sleep(1 * HZ);
-
-- if (rtn == SUCCESS) {
-- SCpnt->host->host_failed--;
-- scsi_eh_finish_command(&SCdone, SCloop);
-- }
-- }
-- if (rtn != SUCCESS) {
-- printk(KERN_INFO "scsi: device set offline - not ready or command retry failed after host reset: host %d channel %d id %d lun %d\n", SDloop->host->host_no, SDloop->channel, SDloop->id, SDloop->lun);
-- SDloop->online = FALSE;
-- SDloop->host->host_failed--;
-- scsi_eh_finish_command(&SCdone, SCloop);
-- }
-- }
-- }
-- }
-- }
-+ goto try_again;
- }
-
-+ SCSI_LOG_ERROR_RECOVERY(3,
-+ printk("scsi_unjam_host: Try hard host reset\n"));
-+
- /*
-- * If we solved all of the problems, then let's rev up the engines again.
-- */
-- if (host->host_failed == 0) {
-- ourrtn = TRUE;
-- goto leave;
-- }
-- /*
-- * If the HOST RESET failed, then for now we assume that the entire host
-- * adapter is too hosed to be of any use. For our purposes, however, it is
-- * easier to simply take the devices offline that correspond to commands
-- * that failed.
-+ * FIXME(eric) - we need to obtain a valid SCpnt to perform this call.
- */
-- SCSI_LOG_ERROR_RECOVERY(1, printk("scsi_unjam_host: Take device offline\n"));
-+ rtn = scsi_try_host_reset(failed_command);
-+ if (rtn == SUCCESS) {
-+ /*
-+ * FIXME(eric) we assume that all commands are flushed from
-+ * the controller. We should get a DID_RESET for all of the
-+ * commands that were pending. We should ignore these so
-+ * that we can guarantee that we are in a consistent state.
-+ *
-+ * I believe this to be the case right now, but this needs
-+ * to be tested.
-+ */
-+ for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
-+ rtn = scsi_eh_restart_device(SDpnt, done);
-
-- for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
-- for (SCloop = SDpnt->device_queue; SCloop; SCloop = SCloop->next) {
-- if (SCloop->state == SCSI_STATE_FAILED || SCloop->state == SCSI_STATE_TIMEOUT) {
-- SDloop = SCloop->device;
-- if (SDloop->online == TRUE) {
-- printk(KERN_INFO "scsi: device set offline - command error recover failed: host %d channel %d id %d lun %d\n", SDloop->host->host_no, SDloop->channel, SDloop->id, SDloop->lun);
-- SDloop->online = FALSE;
-- }
-+ if (rtn != SUCCESS) {
-+ SCpnt = scsi_eh_find_failed_command(SDpnt);
-
- /*
-- * This should pass the failure up to the top level driver, and
-- * it will have to try and do something intelligent with it.
-+ * This device failed again. Since a host
-+ * reset freed it up, chances are we've
-+ * hit the same problem, so try the same
-+ * solution. We also need to ensure that
-+ * the SCSI bus is in the BUS FREE state
-+ * so we can try to talk to other devices.
- */
-- SCloop->host->host_failed--;
--
-- if (SCloop->state == SCSI_STATE_TIMEOUT) {
-- SCloop->result |= (DRIVER_TIMEOUT << 24);
-- }
-- SCSI_LOG_ERROR_RECOVERY(3, printk("Finishing command for device %d %x\n",
-- SDloop->id, SCloop->result));
--
-- scsi_eh_finish_command(&SCdone, SCloop);
-+ scsi_try_host_reset(SCpnt);
-+ scsi_eh_set_device_offline(SDpnt, done,
-+ "not ready or command retry "
-+ "failed after host reset");
- }
- }
- }
-+}
-
-- if (host->host_failed != 0) {
-+static void scsi_unjam_failure(struct Scsi_Host *host, Scsi_Cmnd **done)
-+{
-+ Scsi_Device *SDpnt;
-+
-+ /*
-+ * If the HOST RESET failed, then for now we assume that the
-+ * entire host adapter is too hosed to be of any use. For our
-+ * purposes, however, it is easier to simply take the devices
-+ * offline that correspond to commands that failed.
-+ */
-+ SCSI_LOG_ERROR_RECOVERY(1,
-+ printk("scsi_unjam_host: Take device offline\n"));
-+
-+ for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next)
-+ scsi_eh_set_device_offline(SDpnt, done,
-+ "command error recover failed");
-+
-+ if (host->host_failed != 0)
- panic("scsi_unjam_host: Miscount of number of failed commands.\n");
-- }
-+
- SCSI_LOG_ERROR_RECOVERY(3, printk("scsi_unjam_host: Returning\n"));
-+}
-
-- ourrtn = FALSE;
-+static void (*unjam_method[])(struct Scsi_Host *, Scsi_Cmnd **) = {
-+ scsi_unjam_request_sense,
-+ scsi_unjam_count,
-+ scsi_unjam_abort,
-+ scsi_unjam_device_reset,
-+ scsi_unjam_bus_reset,
-+ scsi_unjam_host_reset,
-+ scsi_unjam_failure,
-+};
-
-- leave:
-+/*
-+ * Function: scsi_unjam_host
-+ *
-+ * Purpose: Attempt to fix a host which has a command that failed for
-+ * some reason.
-+ *
-+ * Arguments: host - host that needs unjamming.
-+ *
-+ * Returns: Nothing
-+ *
-+ * Notes: When we come in here, we *know* that all commands on the
-+ * bus have either completed, failed or timed out. We also
-+ * know that no further commands are being sent to the host,
-+ * so things are relatively quiet and we have freedom to
-+ * fiddle with things as we wish.
-+ *
-+ * Additional note: This is only the *default* implementation. It is possible
-+ * for individual drivers to supply their own version of this
-+ * function, and if the maintainer wishes to do this, it is
-+ * strongly suggested that this function be taken as a template
-+ * and modified. This function was designed to correctly handle
-+ * problems for about 95% of the different cases out there, and
-+ * it should always provide at least a reasonable amount of error
-+ * recovery.
-+ *
-+ * Note3: Any command marked 'FAILED' or 'TIMEOUT' must eventually
-+ * have scsi_finish_command() called for it. We do all of
-+ * the retry stuff here, so when we restart the host after we
-+ * return it should have an empty queue.
-+ */
-+STATIC int scsi_unjam_host(struct Scsi_Host *host)
-+{
-+ Scsi_Cmnd *SCdone = NULL;
-+ Scsi_Cmnd *SCpnt;
-+ Scsi_Device *SDpnt;
-+ int ourrtn = FALSE;
-+ int i;
-+
-+ ASSERT_LOCK(&io_request_lock, 0);
-+
-+ /*
-+ * First, protect against any sort of race condition. If any of the outstanding
-+ * commands are in states that indicate that we are not yet blocked (i.e. we are
-+ * not in a quiet state) then we got woken up in error. If we ever end up here,
-+ * we need to re-examine some of the assumptions.
-+ */
-+ for (SDpnt = host->host_queue; SDpnt; SDpnt = SDpnt->next) {
-+ for (SCpnt = SDpnt->device_queue; SCpnt; SCpnt = SCpnt->next) {
-+ if (SCpnt->state == SCSI_STATE_FAILED
-+ || SCpnt->state == SCSI_STATE_TIMEOUT
-+ || SCpnt->state == SCSI_STATE_INITIALIZING
-+ || SCpnt->state == SCSI_STATE_UNUSED) {
-+ continue;
-+ }
-+ /*
-+ * Rats. Something is still floating around out there. This could
-+ * be the result of the fact that the upper level drivers are still frobbing
-+ * commands that might have succeeded. There are two outcomes. One is that
-+ * the command block will eventually be freed, and the other one is that
-+ * the command will be queued and will be finished along the way.
-+ */
-+ SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler prematurely woken - commands still active (%p %x %d)\n", SCpnt, SCpnt->state, SCpnt->target));
-+
-+/*
-+ * panic("SCSI Error handler woken too early\n");
-+ *
-+ * This is no longer a problem, since now the code cares only about
-+ * SCSI_STATE_TIMEOUT and SCSI_STATE_FAILED.
-+ * Other states are useful only to release active commands when devices are
-+ * set offline. If (host->host_active == host->host_busy) we can safely assume
-+ * that there are no commands in state other then TIMEOUT od FAILED. (DB)
-+ *
-+ * FIXME:
-+ * It is not easy to release correctly commands according to their state when
-+ * devices are set offline, when the state is neither TIMEOUT nor FAILED.
-+ * When a device is set offline, we can have some command with
-+ * rq_status=RQ_SCSY_BUSY, owner=SCSI_STATE_HIGHLEVEL,
-+ * state=SCSI_STATE_INITIALIZING and the driver module cannot be released.
-+ * (DB, 17 May 1998)
-+ */
-+ }
-+ }
-+
-+ for (i = 0; i < ARRAY_SIZE(unjam_method); i++) {
-+ unjam_method[i](host, &SCdone);
-+
-+ /*
-+ * If we solved all of the problems, then
-+ * let's rev up the engines again.
-+ */
-+ if (host->host_failed == 0) {
-+ ourrtn = TRUE;
-+ break;
-+ }
-+ }
-
- /*
- * We should have a list of commands that we 'finished' during the course of
-@@ -2025,3 +2312,17 @@
- * tab-width: 8
- * End:
- */
-+
-+EXPORT_SYMBOL(scsi_eh_times_out);
-+EXPORT_SYMBOL(scsi_eh_retry_command);
-+EXPORT_SYMBOL(scsi_request_sense);
-+EXPORT_SYMBOL(scsi_test_unit_ready);
-+EXPORT_SYMBOL(scsi_unit_is_ready);
-+EXPORT_SYMBOL(scsi_eh_finish_command);
-+EXPORT_SYMBOL(scsi_try_to_abort_command);
-+EXPORT_SYMBOL(scsi_try_bus_device_reset);
-+EXPORT_SYMBOL(scsi_try_bus_reset);
-+EXPORT_SYMBOL(scsi_try_host_reset);
-+EXPORT_SYMBOL(scsi_sense_valid);
-+EXPORT_SYMBOL(scsi_done);
-+EXPORT_SYMBOL(scsi_decide_disposition);
---- linux-2.4.25/drivers/scsi/scsi_ioctl.c~2.4.25-vrs2.patch 2003-08-25 13:44:42.000000000 +0200
-+++ linux-2.4.25/drivers/scsi/scsi_ioctl.c 2004-03-31 17:15:09.000000000 +0200
-@@ -153,6 +153,29 @@
- return result;
- }
-
-+int scsi_set_medium_removal(Scsi_Device *dev, char state)
-+{
-+ char scsi_cmd[MAX_COMMAND_SIZE];
-+ int ret;
-+
-+ if (!dev->removable || !dev->lockable)
-+ return 0;
-+
-+ scsi_cmd[0] = ALLOW_MEDIUM_REMOVAL;
-+ scsi_cmd[1] = (dev->scsi_level <= SCSI_2) ? (dev->lun << 5) : 0;
-+ scsi_cmd[2] = 0;
-+ scsi_cmd[3] = 0;
-+ scsi_cmd[4] = state;
-+ scsi_cmd[5] = 0;
-+
-+ ret = ioctl_internal_command(dev, scsi_cmd, IOCTL_NORMAL_TIMEOUT, NORMAL_RETRIES);
-+
-+ if (ret == 0)
-+ dev->locked = state == SCSI_REMOVAL_PREVENT;
-+
-+ return ret;
-+}
-+
- /*
- * This interface is depreciated - users should use the scsi generic (sg)
- * interface instead, as this is a more flexible approach to performing
-@@ -450,24 +473,9 @@
- return scsi_ioctl_send_command((Scsi_Device *) dev,
- (Scsi_Ioctl_Command *) arg);
- case SCSI_IOCTL_DOORLOCK:
-- if (!dev->removable || !dev->lockable)
-- return 0;
-- scsi_cmd[0] = ALLOW_MEDIUM_REMOVAL;
-- scsi_cmd[1] = cmd_byte1;
-- scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
-- scsi_cmd[4] = SCSI_REMOVAL_PREVENT;
-- return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
-- IOCTL_NORMAL_TIMEOUT, NORMAL_RETRIES);
-- break;
-+ return scsi_set_medium_removal(dev, SCSI_REMOVAL_PREVENT);
- case SCSI_IOCTL_DOORUNLOCK:
-- if (!dev->removable || !dev->lockable)
-- return 0;
-- scsi_cmd[0] = ALLOW_MEDIUM_REMOVAL;
-- scsi_cmd[1] = cmd_byte1;
-- scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
-- scsi_cmd[4] = SCSI_REMOVAL_ALLOW;
-- return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
-- IOCTL_NORMAL_TIMEOUT, NORMAL_RETRIES);
-+ return scsi_set_medium_removal(dev, SCSI_REMOVAL_ALLOW);
- case SCSI_IOCTL_TEST_UNIT_READY:
- scsi_cmd[0] = TEST_UNIT_READY;
- scsi_cmd[1] = cmd_byte1;
---- linux-2.4.25/drivers/scsi/scsi_lib.c~2.4.25-vrs2.patch 2003-08-25 13:44:42.000000000 +0200
-+++ linux-2.4.25/drivers/scsi/scsi_lib.c 2004-03-31 17:15:09.000000000 +0200
-@@ -208,6 +208,30 @@
- }
-
- /*
-+ * Function: scsi_setup_cmd_retry()
-+ *
-+ * Purpose: Restore the command state for a retry
-+ *
-+ * Arguments: SCpnt - command to be restored
-+ *
-+ * Returns: Nothing
-+ *
-+ * Notes: Immediately prior to retrying a command, we need
-+ * to restore certain fields that we saved above.
-+ */
-+void scsi_setup_cmd_retry(Scsi_Cmnd *SCpnt)
-+{
-+ memcpy((void *) SCpnt->cmnd, (void *) SCpnt->data_cmnd,
-+ sizeof(SCpnt->data_cmnd));
-+ SCpnt->request_buffer = SCpnt->buffer;
-+ SCpnt->request_bufflen = SCpnt->bufflen;
-+ SCpnt->use_sg = SCpnt->old_use_sg;
-+ SCpnt->cmd_len = SCpnt->old_cmd_len;
-+ SCpnt->sc_data_direction = SCpnt->sc_old_data_direction;
-+ SCpnt->underflow = SCpnt->old_underflow;
-+}
-+
-+/*
- * Function: scsi_queue_next_request()
- *
- * Purpose: Handle post-processing of completed commands.
-@@ -723,7 +747,7 @@
- printk("scsi%d: ERROR on channel %d, id %d, lun %d, CDB: ",
- SCpnt->host->host_no, (int) SCpnt->channel,
- (int) SCpnt->target, (int) SCpnt->lun);
-- print_command(SCpnt->cmnd);
-+ print_command(SCpnt->data_cmnd);
- print_sense("sd", SCpnt);
- SCpnt = scsi_end_request(SCpnt, 0, block_sectors);
- return;
-@@ -898,8 +922,17 @@
- * space. Technically the error handling thread should be
- * doing this crap, but the error handler isn't used by
- * most hosts.
-+ *
-+ * (rmk)
-+ * Trying to lock the door can cause deadlocks. We therefore
-+ * only use this for old hosts; our door locking is now done
-+ * by the error handler in scsi_restart_operations for new
-+ * eh hosts.
-+ *
-+ * Note that we don't clear was_reset here; this is used by
-+ * st.c, and either one or other has to die.
- */
-- if (SDpnt->was_reset) {
-+ if (SHpnt->hostt->use_new_eh_code == 0 && SDpnt->was_reset) {
- /*
- * We need to relock the door, but we might
- * be in an interrupt handler. Only do this
-@@ -910,7 +943,7 @@
- * this work.
- */
- SDpnt->was_reset = 0;
-- if (SDpnt->removable && !in_interrupt()) {
-+ if (SDpnt->removable && SDpnt->locked && !in_interrupt()) {
- spin_unlock_irq(&io_request_lock);
- scsi_ioctl(SDpnt, SCSI_IOCTL_DOORLOCK, 0);
- spin_lock_irq(&io_request_lock);
---- linux-2.4.25/drivers/scsi/scsi_syms.c~2.4.25-vrs2.patch 2002-08-03 02:39:44.000000000 +0200
-+++ linux-2.4.25/drivers/scsi/scsi_syms.c 2004-03-31 17:15:09.000000000 +0200
-@@ -103,3 +103,6 @@
- extern int scsi_delete_timer(Scsi_Cmnd *);
- EXPORT_SYMBOL(scsi_add_timer);
- EXPORT_SYMBOL(scsi_delete_timer);
-+
-+extern int scsi_set_medium_removal(Scsi_Device *dev, char state);
-+EXPORT_SYMBOL(scsi_set_medium_removal);
---- linux-2.4.25/drivers/scsi/sd.c~2.4.25-vrs2.patch 2003-08-25 13:44:42.000000000 +0200
-+++ linux-2.4.25/drivers/scsi/sd.c 2004-03-31 17:15:09.000000000 +0200
-@@ -399,6 +399,7 @@
- this_count = 0xffff;
-
- SCpnt->cmnd[0] += READ_10 - READ_6;
-+ SCpnt->cmnd[1] |= 1 << 3; /* Set FUA --rmk */
- SCpnt->cmnd[2] = (unsigned char) (block >> 24) & 0xff;
- SCpnt->cmnd[3] = (unsigned char) (block >> 16) & 0xff;
- SCpnt->cmnd[4] = (unsigned char) (block >> 8) & 0xff;
-@@ -524,7 +525,7 @@
- if (SDev->removable)
- if (SDev->access_count==1)
- if (scsi_block_when_processing_errors(SDev))
-- scsi_ioctl(SDev, SCSI_IOCTL_DOORLOCK, NULL);
-+ scsi_set_medium_removal(SDev, SCSI_REMOVAL_PREVENT);
-
-
- return 0;
-@@ -553,7 +554,7 @@
- if (SDev->removable) {
- if (!SDev->access_count)
- if (scsi_block_when_processing_errors(SDev))
-- scsi_ioctl(SDev, SCSI_IOCTL_DOORUNLOCK, NULL);
-+ scsi_set_medium_removal(SDev, SCSI_REMOVAL_ALLOW);
- }
- if (SDev->host->hostt->module)
- __MOD_DEC_USE_COUNT(SDev->host->hostt->module);
---- linux-2.4.25/drivers/scsi/sr_ioctl.c~2.4.25-vrs2.patch 2002-11-29 00:53:14.000000000 +0100
-+++ linux-2.4.25/drivers/scsi/sr_ioctl.c 2004-03-31 17:15:09.000000000 +0200
-@@ -214,9 +214,8 @@
-
- int sr_lock_door(struct cdrom_device_info *cdi, int lock)
- {
-- return scsi_ioctl(scsi_CDs[MINOR(cdi->dev)].device,
-- lock ? SCSI_IOCTL_DOORLOCK : SCSI_IOCTL_DOORUNLOCK,
-- 0);
-+ return scsi_set_medium_removal(scsi_CDs[MINOR(cdi->dev)].device,
-+ lock ? SCSI_REMOVAL_PREVENT : SCSI_REMOVAL_ALLOW);
- }
-
- int sr_drive_status(struct cdrom_device_info *cdi, int slot)
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/serial/21285.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,600 @@
-+/*
-+ * linux/drivers/char/serial_21285.c
-+ *
-+ * Driver for the serial port on the 21285 StrongArm-110 core logic chip.
-+ *
-+ * Based on drivers/char/serial.c
-+ *
-+ * $Id$
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/tty.h>
-+#include <linux/tty_flip.h>
-+#include <linux/serial.h>
-+#include <linux/major.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/console.h>
-+
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+#include <asm/hardware/dec21285.h>
-+#include <asm/hardware.h>
-+
-+#define BAUD_BASE (mem_fclk_21285/64)
-+
-+#define SERIAL_21285_NAME "ttyFB"
-+#define SERIAL_21285_MAJOR 204
-+#define SERIAL_21285_MINOR 4
-+
-+#define SERIAL_21285_AUXNAME "cuafb"
-+#define SERIAL_21285_AUXMAJOR 205
-+#define SERIAL_21285_AUXMINOR 4
-+
-+#ifdef CONFIG_SERIAL_21285_OLD
-+#include <asm/mach-types.h>
-+/*
-+ * Compatability with a mistake made a long time ago.
-+ * Note - the use of "ttyI", "/dev/ttyS0" and major/minor 5,64
-+ * is HIGHLY DEPRECIATED, and will be removed in the 2.5
-+ * kernel series.
-+ * -- rmk 15/04/2000
-+ */
-+#define SERIAL_21285_OLD_NAME "ttyI"
-+#define SERIAL_21285_OLD_MAJOR TTY_MAJOR
-+#define SERIAL_21285_OLD_MINOR 64
-+
-+static struct tty_driver rs285_old_driver;
-+#endif
-+
-+static struct tty_driver rs285_driver, callout_driver;
-+static int rs285_refcount;
-+static struct tty_struct *rs285_table[1];
-+
-+static struct termios *rs285_termios[1];
-+static struct termios *rs285_termios_locked[1];
-+
-+static char wbuf[1000], *putp = wbuf, *getp = wbuf, x_char;
-+static struct tty_struct *rs285_tty;
-+static DECLARE_MUTEX(rs285_sem);
-+static int rs285_use_count;
-+static unsigned long rs285_irq_enabled;
-+
-+#define TX_IRQ_BIT (0)
-+#define RX_IRQ_BIT (1)
-+
-+static void rs285_stop_tx(void)
-+{
-+ if (test_and_clear_bit(TX_IRQ_BIT, &rs285_irq_enabled))
-+ disable_irq(IRQ_CONTX);
-+}
-+
-+static void rs285_start_tx(void)
-+{
-+ if (!test_and_set_bit(TX_IRQ_BIT, &rs285_irq_enabled))
-+ enable_irq(IRQ_CONTX);
-+}
-+
-+static void rs285_stop_rx(void)
-+{
-+ if (test_and_clear_bit(RX_IRQ_BIT, &rs285_irq_enabled))
-+ disable_irq(IRQ_CONRX);
-+}
-+
-+static void rs285_start_rx(void)
-+{
-+ if (!test_and_set_bit(RX_IRQ_BIT, &rs285_irq_enabled))
-+ enable_irq(IRQ_CONRX);
-+}
-+
-+static int rs285_write_room(struct tty_struct *tty)
-+{
-+ return putp >= getp ? (sizeof(wbuf) - (long) putp + (long) getp) : ((long) getp - (long) putp - 1);
-+}
-+
-+static void rs285_rx_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ if (!rs285_tty) {
-+ rs285_stop_rx();
-+ return;
-+ }
-+ while (!(*CSR_UARTFLG & 0x10)) {
-+ int ch, flag;
-+ ch = *CSR_UARTDR;
-+ flag = *CSR_RXSTAT;
-+ if (flag & 4)
-+ tty_insert_flip_char(rs285_tty, 0, TTY_OVERRUN);
-+ if (flag & 2)
-+ flag = TTY_PARITY;
-+ else if (flag & 1)
-+ flag = TTY_FRAME;
-+ tty_insert_flip_char(rs285_tty, ch, flag);
-+ }
-+ tty_flip_buffer_push(rs285_tty);
-+}
-+
-+static void rs285_send_xchar(struct tty_struct *tty, char ch)
-+{
-+ x_char = ch;
-+ rs285_start_tx();
-+}
-+
-+static void rs285_throttle(struct tty_struct *tty)
-+{
-+ if (I_IXOFF(tty))
-+ rs285_send_xchar(tty, STOP_CHAR(tty));
-+}
-+
-+static void rs285_unthrottle(struct tty_struct *tty)
-+{
-+ if (I_IXOFF(tty)) {
-+ if (x_char)
-+ x_char = 0;
-+ else
-+ rs285_send_xchar(tty, START_CHAR(tty));
-+ }
-+}
-+
-+static void rs285_tx_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ while (!(*CSR_UARTFLG & 0x20)) {
-+ if (x_char) {
-+ *CSR_UARTDR = x_char;
-+ x_char = 0;
-+ continue;
-+ }
-+ if (putp == getp) {
-+ rs285_stop_tx();
-+ break;
-+ }
-+ *CSR_UARTDR = *getp;
-+ if (++getp >= wbuf + sizeof(wbuf))
-+ getp = wbuf;
-+ }
-+ if (rs285_tty)
-+ wake_up_interruptible(&rs285_tty->write_wait);
-+}
-+
-+static inline int rs285_xmit(int ch)
-+{
-+ if (putp + 1 == getp || (putp + 1 == wbuf + sizeof(wbuf) && getp == wbuf))
-+ return 0;
-+ *putp = ch;
-+ if (++putp >= wbuf + sizeof(wbuf))
-+ putp = wbuf;
-+ rs285_start_tx();
-+ return 1;
-+}
-+
-+static int rs285_write(struct tty_struct *tty, int from_user,
-+ const u_char * buf, int count)
-+{
-+ int i;
-+
-+ if (from_user && verify_area(VERIFY_READ, buf, count))
-+ return -EINVAL;
-+
-+ for (i = 0; i < count; i++) {
-+ char ch;
-+ if (from_user)
-+ __get_user(ch, buf + i);
-+ else
-+ ch = buf[i];
-+ if (!rs285_xmit(ch))
-+ break;
-+ }
-+ return i;
-+}
-+
-+static void rs285_put_char(struct tty_struct *tty, u_char ch)
-+{
-+ rs285_xmit(ch);
-+}
-+
-+static int rs285_chars_in_buffer(struct tty_struct *tty)
-+{
-+ return sizeof(wbuf) - rs285_write_room(tty);
-+}
-+
-+static void rs285_flush_buffer(struct tty_struct *tty)
-+{
-+ rs285_stop_tx();
-+ putp = getp = wbuf;
-+ if (x_char)
-+ rs285_start_tx();
-+}
-+
-+static inline void rs285_set_cflag(int cflag)
-+{
-+ int h_lcr, baud, quot;
-+
-+ switch (cflag & CSIZE) {
-+ case CS5:
-+ h_lcr = 0x10;
-+ break;
-+ case CS6:
-+ h_lcr = 0x30;
-+ break;
-+ case CS7:
-+ h_lcr = 0x50;
-+ break;
-+ default: /* CS8 */
-+ h_lcr = 0x70;
-+ break;
-+
-+ }
-+ if (cflag & CSTOPB)
-+ h_lcr |= 0x08;
-+ if (cflag & PARENB)
-+ h_lcr |= 0x02;
-+ if (!(cflag & PARODD))
-+ h_lcr |= 0x04;
-+
-+ switch (cflag & CBAUD) {
-+ case B200: baud = 200; break;
-+ case B300: baud = 300; break;
-+ case B1200: baud = 1200; break;
-+ case B1800: baud = 1800; break;
-+ case B2400: baud = 2400; break;
-+ case B4800: baud = 4800; break;
-+ default:
-+ case B9600: baud = 9600; break;
-+ case B19200: baud = 19200; break;
-+ case B38400: baud = 38400; break;
-+ case B57600: baud = 57600; break;
-+ case B115200: baud = 115200; break;
-+ }
-+
-+ /*
-+ * The documented expression for selecting the divisor is:
-+ * BAUD_BASE / baud - 1
-+ * However, typically BAUD_BASE is not divisible by baud, so
-+ * we want to select the divisor that gives us the minimum
-+ * error. Therefore, we want:
-+ * int(BAUD_BASE / baud - 0.5) ->
-+ * int(BAUD_BASE / baud - (baud >> 1) / baud) ->
-+ * int((BAUD_BASE - (baud >> 1)) / baud)
-+ */
-+ quot = (BAUD_BASE - (baud >> 1)) / baud;
-+
-+ *CSR_UARTCON = 0;
-+ *CSR_L_UBRLCR = quot & 0xff;
-+ *CSR_M_UBRLCR = (quot >> 8) & 0x0f;
-+ *CSR_H_UBRLCR = h_lcr;
-+ *CSR_UARTCON = 1;
-+}
-+
-+static void rs285_set_termios(struct tty_struct *tty, struct termios *old)
-+{
-+ if (old && tty->termios->c_cflag == old->c_cflag)
-+ return;
-+ rs285_set_cflag(tty->termios->c_cflag);
-+}
-+
-+
-+static void rs285_stop(struct tty_struct *tty)
-+{
-+ rs285_stop_tx();
-+}
-+
-+static void rs285_start(struct tty_struct *tty)
-+{
-+ rs285_start_tx();
-+}
-+
-+static void rs285_wait_until_sent(struct tty_struct *tty, int timeout)
-+{
-+ int orig_jiffies = jiffies;
-+ while (*CSR_UARTFLG & 8) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(1);
-+ if (signal_pending(current))
-+ break;
-+ if (timeout && time_after(jiffies, orig_jiffies + timeout))
-+ break;
-+ }
-+ set_current_state(TASK_RUNNING);
-+}
-+
-+static int rs285_open(struct tty_struct *tty, struct file *filp)
-+{
-+ int line, ret;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ line = MINOR(tty->device) - tty->driver.minor_start;
-+ if (line)
-+ return -ENODEV;
-+
-+ ret = down_interruptible(&rs285_sem);
-+ if (ret)
-+ return ret;
-+
-+ tty->driver_data = NULL;
-+ rs285_tty = tty;
-+
-+ if (rs285_use_count == 0) {
-+ rs285_irq_enabled = 3;
-+ ret = request_irq(IRQ_CONRX, rs285_rx_int, 0, "rs285", NULL);
-+ if (ret == 0) {
-+ ret = request_irq(IRQ_CONTX, rs285_tx_int, 0, "rs285",
-+ NULL);
-+ if (ret)
-+ free_irq(IRQ_CONRX, NULL);
-+ }
-+ }
-+
-+ if (ret == 0)
-+ rs285_use_count++;
-+
-+ up(&rs285_sem);
-+
-+ return ret;
-+}
-+
-+static void rs285_close(struct tty_struct *tty, struct file *filp)
-+{
-+ down(&rs285_sem);
-+ if (!--rs285_use_count) {
-+ rs285_wait_until_sent(tty, 0);
-+ rs285_stop_rx();
-+ rs285_stop_tx();
-+ rs285_tty = NULL;
-+ free_irq(IRQ_CONTX, NULL);
-+ free_irq(IRQ_CONRX, NULL);
-+ }
-+ up(&rs285_sem);
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static int __init rs285_init(void)
-+{
-+ int baud = B9600;
-+
-+ if (machine_is_personal_server())
-+ baud = B57600;
-+
-+ rs285_driver.magic = TTY_DRIVER_MAGIC;
-+ rs285_driver.driver_name = "serial_21285";
-+ rs285_driver.name = SERIAL_21285_NAME;
-+ rs285_driver.major = SERIAL_21285_MAJOR;
-+ rs285_driver.minor_start = SERIAL_21285_MINOR;
-+ rs285_driver.num = 1;
-+ rs285_driver.type = TTY_DRIVER_TYPE_SERIAL;
-+ rs285_driver.subtype = SERIAL_TYPE_NORMAL;
-+ rs285_driver.init_termios = tty_std_termios;
-+ rs285_driver.init_termios.c_cflag = baud | CS8 | CREAD | HUPCL | CLOCAL;
-+ rs285_driver.flags = TTY_DRIVER_REAL_RAW;
-+ rs285_driver.refcount = &rs285_refcount;
-+ rs285_driver.table = rs285_table;
-+ rs285_driver.termios = rs285_termios;
-+ rs285_driver.termios_locked = rs285_termios_locked;
-+
-+ rs285_driver.open = rs285_open;
-+ rs285_driver.close = rs285_close;
-+ rs285_driver.write = rs285_write;
-+ rs285_driver.put_char = rs285_put_char;
-+ rs285_driver.write_room = rs285_write_room;
-+ rs285_driver.chars_in_buffer = rs285_chars_in_buffer;
-+ rs285_driver.flush_buffer = rs285_flush_buffer;
-+ rs285_driver.throttle = rs285_throttle;
-+ rs285_driver.unthrottle = rs285_unthrottle;
-+ rs285_driver.send_xchar = rs285_send_xchar;
-+ rs285_driver.set_termios = rs285_set_termios;
-+ rs285_driver.stop = rs285_stop;
-+ rs285_driver.start = rs285_start;
-+ rs285_driver.wait_until_sent = rs285_wait_until_sent;
-+
-+ callout_driver = rs285_driver;
-+ callout_driver.name = SERIAL_21285_AUXNAME;
-+ callout_driver.major = SERIAL_21285_AUXMAJOR;
-+ callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-+
-+#ifdef CONFIG_SERIAL_21285_OLD
-+ if (!machine_is_ebsa285() && !machine_is_netwinder()) {
-+ rs285_old_driver = rs285_driver;
-+ rs285_old_driver.name = SERIAL_21285_OLD_NAME;
-+ rs285_old_driver.major = SERIAL_21285_OLD_MAJOR;
-+ rs285_old_driver.minor_start = SERIAL_21285_OLD_MINOR;
-+
-+ if (tty_register_driver(&rs285_old_driver))
-+ printk(KERN_ERR "Couldn't register old 21285 serial driver\n");
-+ }
-+#endif
-+
-+ if (tty_register_driver(&rs285_driver))
-+ printk(KERN_ERR "Couldn't register 21285 serial driver\n");
-+ if (tty_register_driver(&callout_driver))
-+ printk(KERN_ERR "Couldn't register 21285 callout driver\n");
-+
-+ return 0;
-+}
-+
-+static void __exit rs285_fini(void)
-+{
-+ unsigned long flags;
-+ int ret;
-+
-+ save_flags(flags);
-+ cli();
-+ ret = tty_unregister_driver(&callout_driver);
-+ if (ret)
-+ printk(KERN_ERR "Unable to unregister 21285 callout driver "
-+ "(%d)\n", ret);
-+ ret = tty_unregister_driver(&rs285_driver);
-+ if (ret)
-+ printk(KERN_ERR "Unable to unregister 21285 driver (%d)\n",
-+ ret);
-+#ifdef CONFIG_SERIAL_21285_OLD
-+ if (!machine_is_ebsa285() && !machine_is_netwinder()) {
-+ ret = tty_unregister_driver(&rs285_old_driver);
-+ if (ret)
-+ printk(KERN_ERR "Unable to unregister old 21285 "
-+ "driver (%d)\n", ret);
-+ }
-+#endif
-+ free_irq(IRQ_CONTX, NULL);
-+ free_irq(IRQ_CONRX, NULL);
-+ restore_flags(flags);
-+}
-+
-+module_init(rs285_init);
-+module_exit(rs285_fini);
-+
-+#ifdef CONFIG_SERIAL_21285_CONSOLE
-+/************** console driver *****************/
-+
-+static void rs285_console_write(struct console *co, const char *s, u_int count)
-+{
-+ int i;
-+
-+ rs285_stop_tx();
-+ for (i = 0; i < count; i++) {
-+ while (*CSR_UARTFLG & 0x20);
-+ *CSR_UARTDR = s[i];
-+ if (s[i] == '\n') {
-+ while (*CSR_UARTFLG & 0x20);
-+ *CSR_UARTDR = '\r';
-+ }
-+ }
-+ rs285_start_tx();
-+}
-+
-+static kdev_t rs285_console_device(struct console *c)
-+{
-+ return MKDEV(SERIAL_21285_MAJOR, SERIAL_21285_MINOR);
-+}
-+
-+static int __init rs285_console_setup(struct console *co, char *options)
-+{
-+ int baud = 9600;
-+ int bits = 8;
-+ int parity = 'n';
-+ int cflag = CREAD | HUPCL | CLOCAL;
-+
-+ if (machine_is_personal_server())
-+ baud = 57600;
-+
-+ if (options) {
-+ char *s = options;
-+ baud = simple_strtoul(options, NULL, 10);
-+ while (*s >= '0' && *s <= '9')
-+ s++;
-+ if (*s)
-+ parity = *s++;
-+ if (*s)
-+ bits = *s - '0';
-+ }
-+
-+ /*
-+ * Now construct a cflag setting.
-+ */
-+ switch (baud) {
-+ case 1200:
-+ cflag |= B1200;
-+ break;
-+ case 2400:
-+ cflag |= B2400;
-+ break;
-+ case 4800:
-+ cflag |= B4800;
-+ break;
-+ case 9600:
-+ cflag |= B9600;
-+ break;
-+ case 19200:
-+ cflag |= B19200;
-+ break;
-+ case 38400:
-+ cflag |= B38400;
-+ break;
-+ case 57600:
-+ cflag |= B57600;
-+ break;
-+ case 115200:
-+ cflag |= B115200;
-+ break;
-+ default:
-+ cflag |= B9600;
-+ break;
-+ }
-+ switch (bits) {
-+ case 7:
-+ cflag |= CS7;
-+ break;
-+ default:
-+ cflag |= CS8;
-+ break;
-+ }
-+ switch (parity) {
-+ case 'o':
-+ case 'O':
-+ cflag |= PARODD;
-+ break;
-+ case 'e':
-+ case 'E':
-+ cflag |= PARENB;
-+ break;
-+ }
-+ co->cflag = cflag;
-+ rs285_set_cflag(cflag);
-+ rs285_console_write(NULL, "\e[2J\e[Hboot ", 12);
-+ if (options)
-+ rs285_console_write(NULL, options, strlen(options));
-+ else
-+ rs285_console_write(NULL, "no options", 10);
-+ rs285_console_write(NULL, "\n", 1);
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_SERIAL_21285_OLD
-+static struct console rs285_old_cons =
-+{
-+ SERIAL_21285_OLD_NAME,
-+ rs285_console_write,
-+ NULL,
-+ rs285_console_device,
-+ NULL,
-+ rs285_console_setup,
-+ CON_PRINTBUFFER,
-+ -1,
-+ 0,
-+ NULL
-+};
-+#endif
-+
-+static struct console rs285_cons =
-+{
-+ name: SERIAL_21285_NAME,
-+ write: rs285_console_write,
-+ device: rs285_console_device,
-+ setup: rs285_console_setup,
-+ flags: CON_PRINTBUFFER,
-+ index: -1,
-+};
-+
-+void __init rs285_console_init(void)
-+{
-+#ifdef CONFIG_SERIAL_21285_OLD
-+ if (!machine_is_ebsa285() && !machine_is_netwinder())
-+ register_console(&rs285_old_cons);
-+#endif
-+ register_console(&rs285_cons);
-+}
-+
-+#endif /* CONFIG_SERIAL_21285_CONSOLE */
-+
-+EXPORT_NO_SYMBOLS;
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("Intel Footbridge (21285) serial driver");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/serial/8250.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,2170 @@
-+/*
-+ * linux/drivers/serial/8250.c
-+ *
-+ * Driver for 8250/16550-type serial ports
-+ *
-+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
-+ *
-+ * Copyright (C) 2001 Russell King.
-+ *
-+ * 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.
-+ *
-+ * $Id$
-+ *
-+ * A note about mapbase / membase
-+ *
-+ * mapbase is the physical address of the IO port. Currently, we don't
-+ * support this very well, and it may well be dropped from this driver
-+ * in future. As such, mapbase should be NULL.
-+ *
-+ * membase is an 'ioremapped' cookie. This is compatible with the old
-+ * serial.c driver, and is currently the preferred form.
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/sched.h>
-+#include <linux/tty.h>
-+#include <linux/tty_flip.h>
-+#include <linux/major.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/init.h>
-+#include <linux/serial.h>
-+#include <linux/console.h>
-+#include <linux/sysrq.h>
-+#include <linux/serial_reg.h>
-+#include <linux/serialP.h>
-+#include <linux/delay.h>
-+#include <linux/serial_core.h>
-+#include <linux/kmod.h>
-+
-+#include <asm/system.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+#include <asm/bitops.h>
-+
-+#include "8250.h"
-+
-+/*
-+ * Configuration:
-+ * share_irqs - whether we pass SA_SHIRQ to request_irq(). This option
-+ * is unsafe when used on edge-triggered interrupts.
-+ */
-+unsigned int share_irqs = SERIAL8250_SHARE_IRQS;
-+
-+/*
-+ * Debugging.
-+ */
-+#if 0
-+#define DEBUG_AUTOCONF(fmt...) printk(fmt)
-+#else
-+#define DEBUG_AUTOCONF(fmt...) do { } while (0)
-+#endif
-+
-+#if 0
-+#define DEBUG_INTR(fmt...) printk(fmt)
-+#else
-+#define DEBUG_INTR(fmt...) do { } while (0)
-+#endif
-+
-+#define PASS_LIMIT 256
-+
-+/*
-+ * We default to IRQ0 for the "no irq" hack. Some
-+ * machine types want others as well - they're free
-+ * to redefine this in their header file.
-+ */
-+#define is_real_interrupt(irq) ((irq) != 0)
-+
-+/*
-+ * This converts from our new CONFIG_ symbols to the symbols
-+ * that asm/serial.h expects. You _NEED_ to comment out the
-+ * linux/config.h include contained inside asm/serial.h for
-+ * this to work.
-+ */
-+#undef CONFIG_SERIAL_MANY_PORTS
-+#undef CONFIG_SERIAL_DETECT_IRQ
-+#undef CONFIG_SERIAL_MULTIPORT
-+#undef CONFIG_HUB6
-+
-+#ifdef CONFIG_SERIAL_8250_DETECT_IRQ
-+#define CONFIG_SERIAL_DETECT_IRQ 1
-+#endif
-+#ifdef CONFIG_SERIAL_8250_MULTIPORT
-+#define CONFIG_SERIAL_MULTIPORT 1
-+#endif
-+#ifdef CONFIG_SERIAL_8250_HUB6
-+#define CONFIG_HUB6 1
-+#endif
-+#ifdef CONFIG_SERIAL_8250_MANY_PORTS
-+#define CONFIG_SERIAL_MANY_PORTS 1
-+#endif
-+
-+#include <asm/serial.h>
-+
-+static struct old_serial_port old_serial_port[] = {
-+ SERIAL_PORT_DFNS /* defined in asm/serial.h */
-+};
-+
-+#define UART_NR ARRAY_SIZE(old_serial_port)
-+
-+static struct tty_driver normal, callout;
-+static struct tty_struct *serial8250_table[UART_NR];
-+static struct termios *serial8250_termios[UART_NR], *serial8250_termios_locked[UART_NR];
-+
-+#if defined(CONFIG_SERIAL_8250_RSA) && defined(MODULE)
-+
-+#define PORT_RSA_MAX 4
-+static int probe_rsa[PORT_RSA_MAX];
-+static int force_rsa[PORT_RSA_MAX];
-+#endif /* CONFIG_SERIAL_8250_RSA */
-+
-+struct uart_8250_port {
-+ struct uart_port port;
-+ struct timer_list timer; /* "no irq" timer */
-+ struct list_head list; /* ports on this IRQ */
-+ unsigned int capabilities; /* port capabilities */
-+ unsigned char acr;
-+ unsigned char ier;
-+ unsigned short rev;
-+ unsigned char lcr;
-+ unsigned char mcr;
-+ unsigned char mcr_mask; /* mask of user bits */
-+ unsigned char mcr_force; /* mask of forced bits */
-+ unsigned char efr;
-+ unsigned int lsr_break_flag;
-+
-+ /*
-+ * We provide a per-port pm hook.
-+ */
-+ void (*pm)(struct uart_port *port,
-+ unsigned int state, unsigned int old);
-+};
-+
-+struct irq_info {
-+ spinlock_t lock;
-+ struct list_head *head;
-+};
-+
-+static struct irq_info irq_lists[NR_IRQS];
-+
-+/*
-+ * Here we define the default xmit fifo size used for each type of UART.
-+ */
-+static const struct serial_uart_config uart_config[PORT_MAX_8250+1] = {
-+ { "unknown", 1, 0 },
-+ { "8250", 1, 0 },
-+ { "16450", 1, 0 },
-+ { "16550", 1, 0 },
-+ { "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO },
-+ { "Cirrus", 1, 0 },
-+ { "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH },
-+ { "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH },
-+ { "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO },
-+ { "Startech", 1, 0 },
-+ { "16C950/954", 128, UART_CLEAR_FIFO | UART_USE_FIFO },
-+ { "ST16654", 64, UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH },
-+ { "XR16850", 128, UART_CLEAR_FIFO | UART_USE_FIFO | UART_STARTECH },
-+ { "RSA", 2048, UART_CLEAR_FIFO | UART_USE_FIFO }
-+};
-+
-+static _INLINE_ unsigned int serial_in(struct uart_8250_port *up, int offset)
-+{
-+ offset <<= up->port.regshift;
-+
-+ switch (up->port.iotype) {
-+#ifdef CONFIG_SERIAL_8250_HUB6
-+ case SERIAL_IO_HUB6:
-+ outb(up->port.hub6 - 1 + offset, up->port.iobase);
-+ return inb(up->port.iobase + 1);
-+#endif
-+
-+ case SERIAL_IO_MEM:
-+ return readb(up->port.membase + offset);
-+
-+ default:
-+ return inb(up->port.iobase + offset);
-+ }
-+}
-+
-+static _INLINE_ void
-+serial_out(struct uart_8250_port *up, int offset, int value)
-+{
-+ offset <<= up->port.regshift;
-+
-+ switch (up->port.iotype) {
-+#ifdef CONFIG_SERIAL_8250_HUB6
-+ case SERIAL_IO_HUB6:
-+ outb(up->port.hub6 - 1 + offset, up->port.iobase);
-+ outb(value, up->port.iobase + 1);
-+ break;
-+#endif
-+
-+ case SERIAL_IO_MEM:
-+ writeb(value, up->port.membase + offset);
-+ break;
-+
-+ default:
-+ outb(value, up->port.iobase + offset);
-+ }
-+}
-+
-+/*
-+ * We used to support using pause I/O for certain machines. We
-+ * haven't supported this for a while, but just in case it's badly
-+ * needed for certain old 386 machines, I've left these #define's
-+ * in....
-+ */
-+#define serial_inp(up, offset) serial_in(up, offset)
-+#define serial_outp(up, offset, value) serial_out(up, offset, value)
-+
-+
-+/*
-+ * For the 16C950
-+ */
-+static void serial_icr_write(struct uart_8250_port *up, int offset, int value)
-+{
-+ serial_out(up, UART_SCR, offset);
-+ serial_out(up, UART_ICR, value);
-+}
-+
-+static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
-+{
-+ unsigned int value;
-+
-+ serial_icr_write(up, UART_ACR, up->acr | UART_ACR_ICRRD);
-+ serial_out(up, UART_SCR, offset);
-+ value = serial_in(up, UART_ICR);
-+ serial_icr_write(up, UART_ACR, up->acr);
-+
-+ return value;
-+}
-+
-+#ifdef CONFIG_SERIAL_8250_RSA
-+/*
-+ * Attempts to turn on the RSA FIFO. Returns zero on failure.
-+ * We set the port uart clock rate if we succeed.
-+ */
-+static int __enable_rsa(struct uart_8250_port *up)
-+{
-+ unsigned char mode;
-+ int result;
-+
-+ mode = serial_inp(up, UART_RSA_MSR);
-+ result = mode & UART_RSA_MSR_FIFO;
-+
-+ if (!result) {
-+ serial_outp(up, UART_RSA_MSR, mode | UART_RSA_MSR_FIFO);
-+ mode = serial_inp(up, UART_RSA_MSR);
-+ result = mode & UART_RSA_MSR_FIFO;
-+ }
-+
-+ if (result)
-+ up->port.uartclk = SERIAL_RSA_BAUD_BASE * 16;
-+
-+ return result;
-+}
-+
-+static void enable_rsa(struct uart_8250_port *up)
-+{
-+ if (up->port.type == PORT_RSA) {
-+ if (up->port.uartclk != SERIAL_RSA_BAUD_BASE * 16) {
-+ spin_lock_irq(&up->port.lock);
-+ __enable_rsa(up);
-+ spin_unlock_irq(&up->port.lock);
-+ }
-+ if (up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16)
-+ serial_outp(up, UART_RSA_FRR, 0);
-+ }
-+}
-+
-+/*
-+ * Attempts to turn off the RSA FIFO. Returns zero on failure.
-+ * It is unknown why interrupts were disabled in here. However,
-+ * the caller is expected to preserve this behaviour by grabbing
-+ * the spinlock before calling this function.
-+ */
-+static void disable_rsa(struct uart_8250_port *up)
-+{
-+ unsigned char mode;
-+ int result;
-+
-+ if (up->port.type == PORT_RSA &&
-+ up->port.uartclk == SERIAL_RSA_BAUD_BASE * 16) {
-+ spin_lock_irq(&up->port.lock);
-+
-+ mode = serial_inp(up, UART_RSA_MSR);
-+ result = !(mode & UART_RSA_MSR_FIFO);
-+
-+ if (!result) {
-+ serial_outp(up, UART_RSA_MSR, mode & ~UART_RSA_MSR_FIFO);
-+ mode = serial_inp(up, UART_RSA_MSR);
-+ result = !(mode & UART_RSA_MSR_FIFO);
-+ }
-+
-+ if (result)
-+ up->port.uartclk = SERIAL_RSA_BAUD_BASE_LO * 16;
-+ spin_unlock_irq(&up->port.lock);
-+ }
-+}
-+#endif /* CONFIG_SERIAL_8250_RSA */
-+
-+/*
-+ * This is a quickie test to see how big the FIFO is.
-+ * It doesn't work at all the time, more's the pity.
-+ */
-+static int size_fifo(struct uart_8250_port *up)
-+{
-+ unsigned char old_fcr, old_mcr, old_dll, old_dlm;
-+ int count;
-+
-+ old_fcr = serial_inp(up, UART_FCR);
-+ old_mcr = serial_inp(up, UART_MCR);
-+ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
-+ UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
-+ serial_outp(up, UART_MCR, UART_MCR_LOOP);
-+ serial_outp(up, UART_LCR, UART_LCR_DLAB);
-+ old_dll = serial_inp(up, UART_DLL);
-+ old_dlm = serial_inp(up, UART_DLM);
-+ serial_outp(up, UART_DLL, 0x01);
-+ serial_outp(up, UART_DLM, 0x00);
-+ serial_outp(up, UART_LCR, 0x03);
-+ for (count = 0; count < 256; count++)
-+ serial_outp(up, UART_TX, count);
-+ mdelay(20);/* FIXME - schedule_timeout */
-+ for (count = 0; (serial_inp(up, UART_LSR) & UART_LSR_DR) &&
-+ (count < 256); count++)
-+ serial_inp(up, UART_RX);
-+ serial_outp(up, UART_FCR, old_fcr);
-+ serial_outp(up, UART_MCR, old_mcr);
-+ serial_outp(up, UART_LCR, UART_LCR_DLAB);
-+ serial_outp(up, UART_DLL, old_dll);
-+ serial_outp(up, UART_DLM, old_dlm);
-+
-+ return count;
-+}
-+
-+/*
-+ * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's.
-+ * When this function is called we know it is at least a StarTech
-+ * 16650 V2, but it might be one of several StarTech UARTs, or one of
-+ * its clones. (We treat the broken original StarTech 16650 V1 as a
-+ * 16550, and why not? Startech doesn't seem to even acknowledge its
-+ * existence.)
-+ *
-+ * What evil have men's minds wrought...
-+ */
-+static void autoconfig_has_efr(struct uart_8250_port *up)
-+{
-+ unsigned char id1, id2, id3, rev, saved_dll, saved_dlm;
-+
-+ /*
-+ * First we check to see if it's an Oxford Semiconductor UART.
-+ *
-+ * If we have to do this here because some non-National
-+ * Semiconductor clone chips lock up if you try writing to the
-+ * LSR register (which serial_icr_read does)
-+ */
-+
-+ /*
-+ * Check for Oxford Semiconductor 16C950.
-+ *
-+ * EFR [4] must be set else this test fails.
-+ *
-+ * This shouldn't be necessary, but Mike Hudson (Exoray@isys.ca)
-+ * claims that it's needed for 952 dual UART's (which are not
-+ * recommended for new designs).
-+ */
-+ up->acr = 0;
-+ serial_out(up, UART_LCR, 0xBF);
-+ serial_out(up, UART_EFR, 0x10);
-+ serial_out(up, UART_LCR, 0x00);
-+ id1 = serial_icr_read(up, UART_ID1);
-+ id2 = serial_icr_read(up, UART_ID2);
-+ id3 = serial_icr_read(up, UART_ID3);
-+ rev = serial_icr_read(up, UART_REV);
-+
-+ DEBUG_AUTOCONF("950id=%02x:%02x:%02x:%02x ", id1, id2, id3, rev);
-+
-+ if (id1 == 0x16 && id2 == 0xC9 &&
-+ (id3 == 0x50 || id3 == 0x52 || id3 == 0x54)) {
-+ up->port.type = PORT_16C950;
-+ up->rev = rev | (id3 << 8);
-+ return;
-+ }
-+
-+ /*
-+ * We check for a XR16C850 by setting DLL and DLM to 0, and then
-+ * reading back DLL and DLM. The chip type depends on the DLM
-+ * value read back:
-+ * 0x10 - XR16C850 and the DLL contains the chip revision.
-+ * 0x12 - XR16C2850.
-+ * 0x14 - XR16C854.
-+ */
-+ serial_outp(up, UART_LCR, UART_LCR_DLAB);
-+ saved_dll = serial_inp(up, UART_DLL);
-+ saved_dlm = serial_inp(up, UART_DLM);
-+ serial_outp(up, UART_DLL, 0);
-+ serial_outp(up, UART_DLM, 0);
-+ id2 = serial_inp(up, UART_DLL);
-+ id1 = serial_inp(up, UART_DLM);
-+ serial_outp(up, UART_DLL, saved_dll);
-+ serial_outp(up, UART_DLM, saved_dlm);
-+
-+ DEBUG_AUTOCONF("850id=%02x:%02x ", id1, id2);
-+
-+ if (id1 == 0x10 || id1 == 0x12 || id1 == 0x14) {
-+ if (id1 == 0x10)
-+ up->rev = id2;
-+ up->port.type = PORT_16850;
-+ return;
-+ }
-+
-+ /*
-+ * It wasn't an XR16C850.
-+ *
-+ * We distinguish between the '654 and the '650 by counting
-+ * how many bytes are in the FIFO. I'm using this for now,
-+ * since that's the technique that was sent to me in the
-+ * serial driver update, but I'm not convinced this works.
-+ * I've had problems doing this in the past. -TYT
-+ */
-+ if (size_fifo(up) == 64)
-+ up->port.type = PORT_16654;
-+ else
-+ up->port.type = PORT_16650V2;
-+}
-+
-+/*
-+ * We detected a chip without a FIFO. Only two fall into
-+ * this category - the original 8250 and the 16450. The
-+ * 16450 has a scratch register (accessible with LCR=0)
-+ */
-+static void autoconfig_8250(struct uart_8250_port *up)
-+{
-+ unsigned char scratch, status1, status2;
-+
-+ up->port.type = PORT_8250;
-+
-+ scratch = serial_in(up, UART_SCR);
-+ serial_outp(up, UART_SCR, 0xa5);
-+ status1 = serial_in(up, UART_SCR);
-+ serial_outp(up, UART_SCR, 0x5a);
-+ status2 = serial_in(up, UART_SCR);
-+ serial_outp(up, UART_SCR, scratch);
-+
-+ if (status1 == 0xa5 && status2 == 0x5a)
-+ up->port.type = PORT_16450;
-+}
-+
-+/*
-+ * We know that the chip has FIFOs. Does it have an EFR? The
-+ * EFR is located in the same register position as the IIR and
-+ * we know the top two bits of the IIR are currently set. The
-+ * EFR should contain zero. Try to read the EFR.
-+ */
-+static void autoconfig_16550a(struct uart_8250_port *up)
-+{
-+ unsigned char status1, status2;
-+
-+ up->port.type = PORT_16550A;
-+
-+ /*
-+ * Check for presence of the EFR when DLAB is set.
-+ * Only ST16C650V1 UARTs pass this test.
-+ */
-+ serial_outp(up, UART_LCR, UART_LCR_DLAB);
-+ if (serial_in(up, UART_EFR) == 0) {
-+ DEBUG_AUTOCONF("EFRv1 ");
-+ up->port.type = PORT_16650;
-+ return;
-+ }
-+
-+ /*
-+ * Maybe it requires 0xbf to be written to the LCR.
-+ * (other ST16C650V2 UARTs, TI16C752A, etc)
-+ */
-+ serial_outp(up, UART_LCR, 0xBF);
-+ if (serial_in(up, UART_EFR) == 0) {
-+ DEBUG_AUTOCONF("EFRv2 ");
-+ autoconfig_has_efr(up);
-+ return;
-+ }
-+
-+ /*
-+ * Check for a National Semiconductor SuperIO chip.
-+ * Attempt to switch to bank 2, read the value of the LOOP bit
-+ * from EXCR1. Switch back to bank 0, change it in MCR. Then
-+ * switch back to bank 2, read it from EXCR1 again and check
-+ * it's changed. If so, set baud_base in EXCR2 to 921600.
-+ */
-+ serial_outp(up, UART_LCR, 0);
-+ status1 = serial_in(up, UART_MCR);
-+ serial_outp(up, UART_LCR, 0xE0);
-+ status2 = serial_in(up, 0x02); /* EXCR1 */
-+
-+ if (!((status2 ^ status1) & UART_MCR_LOOP)) {
-+ serial_outp(up, UART_LCR, 0);
-+ serial_outp(up, UART_MCR, status1 ^ UART_MCR_LOOP);
-+ serial_outp(up, UART_LCR, 0xE0);
-+ status2 = serial_in(up, 0x02); /* EXCR1 */
-+ serial_outp(up, UART_LCR, 0);
-+ serial_outp(up, UART_MCR, status1);
-+
-+ if ((status2 ^ status1) & UART_MCR_LOOP) {
-+ serial_outp(up, UART_LCR, 0xE0);
-+ status1 = serial_in(up, 0x04); /* EXCR1 */
-+ status1 &= ~0xB0; /* Disable LOCK, mask out PRESL[01] */
-+ status1 |= 0x10; /* 1.625 divisor for baud_base --> 921600 */
-+ serial_outp(up, 0x04, status1);
-+ serial_outp(up, UART_LCR, 0);
-+
-+ up->port.type = PORT_NS16550A;
-+ up->port.uartclk = 921600*16;
-+ return;
-+ }
-+ }
-+
-+ /*
-+ * No EFR. Try to detect a TI16750, which only sets bit 5 of
-+ * the IIR when 64 byte FIFO mode is enabled when DLAB is set.
-+ * Try setting it with and without DLAB set. Cheap clones
-+ * set bit 5 without DLAB set.
-+ */
-+ serial_outp(up, UART_LCR, 0);
-+ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
-+ status1 = serial_in(up, UART_IIR) >> 5;
-+ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
-+ serial_outp(up, UART_LCR, UART_LCR_DLAB);
-+ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
-+ status2 = serial_in(up, UART_IIR) >> 5;
-+ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
-+
-+ DEBUG_AUTOCONF("iir1=%d iir2=%d ", status1, status2);
-+
-+ if (status1 == 6 && status2 == 7) {
-+ up->port.type = PORT_16750;
-+ return;
-+ }
-+}
-+
-+/*
-+ * This routine is called by rs_init() to initialize a specific serial
-+ * port. It determines what type of UART chip this serial port is
-+ * using: 8250, 16450, 16550, 16550A. The important question is
-+ * whether or not this UART is a 16550A or not, since this will
-+ * determine whether or not we can use its FIFO features or not.
-+ */
-+static void autoconfig(struct uart_8250_port *up, unsigned int probeflags)
-+{
-+ unsigned char status1, scratch, scratch2, scratch3;
-+ unsigned char save_lcr, save_mcr;
-+ unsigned long flags;
-+
-+ if (!up->port.iobase && !up->port.mapbase && !up->port.membase)
-+ return;
-+
-+ DEBUG_AUTOCONF("ttyS%d: autoconf (0x%04x, 0x%p): ",
-+ up->port.line, up->port.iobase, up->port.membase);
-+
-+ /*
-+ * We really do need global IRQs disabled here - we're going to
-+ * be frobbing the chips IRQ enable register to see if it exists.
-+ */
-+ spin_lock_irqsave(&up->port.lock, flags);
-+
-+ if (!(up->port.flags & UPF_BUGGY_UART)) {
-+ /*
-+ * Do a simple existence test first; if we fail this,
-+ * there's no point trying anything else.
-+ *
-+ * 0x80 is used as a nonsense port to prevent against
-+ * false positives due to ISA bus float. The
-+ * assumption is that 0x80 is a non-existent port;
-+ * which should be safe since include/asm/io.h also
-+ * makes this assumption.
-+ *
-+ * Note: this is safe as long as MCR bit 4 is clear
-+ * and the device is in "PC" mode.
-+ */
-+ scratch = serial_inp(up, UART_IER);
-+ serial_outp(up, UART_IER, 0);
-+#ifdef __i386__
-+ outb(0xff, 0x080);
-+#endif
-+ scratch2 = serial_inp(up, UART_IER);
-+ serial_outp(up, UART_IER, 0x0F);
-+#ifdef __i386__
-+ outb(0, 0x080);
-+#endif
-+ scratch3 = serial_inp(up, UART_IER);
-+ serial_outp(up, UART_IER, scratch);
-+ if (scratch2 != 0 || scratch3 != 0x0F) {
-+ /*
-+ * We failed; there's nothing here
-+ */
-+ DEBUG_AUTOCONF("IER test failed (%02x, %02x) ",
-+ scratch2, scratch3);
-+ goto out;
-+ }
-+ }
-+
-+ save_mcr = serial_in(up, UART_MCR);
-+ save_lcr = serial_in(up, UART_LCR);
-+
-+ /*
-+ * Check to see if a UART is really there. Certain broken
-+ * internal modems based on the Rockwell chipset fail this
-+ * test, because they apparently don't implement the loopback
-+ * test mode. So this test is skipped on the COM 1 through
-+ * COM 4 ports. This *should* be safe, since no board
-+ * manufacturer would be stupid enough to design a board
-+ * that conflicts with COM 1-4 --- we hope!
-+ */
-+ if (!(up->port.flags & UPF_SKIP_TEST)) {
-+ serial_outp(up, UART_MCR, UART_MCR_LOOP | 0x0A);
-+ status1 = serial_inp(up, UART_MSR) & 0xF0;
-+ serial_outp(up, UART_MCR, save_mcr);
-+ if (status1 != 0x90) {
-+ DEBUG_AUTOCONF("LOOP test failed (%02x) ",
-+ status1);
-+ goto out;
-+ }
-+ }
-+
-+ /*
-+ * We're pretty sure there's a port here. Lets find out what
-+ * type of port it is. The IIR top two bits allows us to find
-+ * out if its 8250 or 16450, 16550, 16550A or later. This
-+ * determines what we test for next.
-+ *
-+ * We also initialise the EFR (if any) to zero for later. The
-+ * EFR occupies the same register location as the FCR and IIR.
-+ */
-+ serial_outp(up, UART_LCR, 0xBF);
-+ serial_outp(up, UART_EFR, 0);
-+ serial_outp(up, UART_LCR, 0);
-+
-+ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
-+ scratch = serial_in(up, UART_IIR) >> 6;
-+
-+ DEBUG_AUTOCONF("iir=%d ", scratch);
-+
-+ switch (scratch) {
-+ case 0:
-+ autoconfig_8250(up);
-+ break;
-+ case 1:
-+ up->port.type = PORT_UNKNOWN;
-+ break;
-+ case 2:
-+ up->port.type = PORT_16550;
-+ break;
-+ case 3:
-+ autoconfig_16550a(up);
-+ break;
-+ }
-+
-+#if defined(CONFIG_SERIAL_8250_RSA) && defined(MODULE)
-+ /*
-+ * Only probe for RSA ports if we got the region.
-+ */
-+ if (up->port.type == PORT_16550A && probeflags & PROBE_RSA) {
-+ int i;
-+
-+ for (i = 0 ; i < PORT_RSA_MAX ; ++i) {
-+ if (!probe_rsa[i] && !force_rsa[i])
-+ break;
-+ if (((probe_rsa[i] != up->port.iobase) ||
-+ check_region(up->port.iobase + UART_RSA_BASE, 16)) &&
-+ (force_rsa[i] != up->port.iobase))
-+ continue;
-+ if (__enable_rsa(up)) {
-+ up->port.type = PORT_RSA;
-+ break;
-+ }
-+ }
-+ }
-+#endif
-+ serial_outp(up, UART_LCR, save_lcr);
-+
-+ up->port.fifosize = uart_config[up->port.type].dfl_xmit_fifo_size;
-+ up->capabilities = uart_config[up->port.type].flags;
-+
-+ if (up->port.type == PORT_UNKNOWN)
-+ goto out;
-+
-+ /*
-+ * Reset the UART.
-+ */
-+#ifdef CONFIG_SERIAL_8250_RSA
-+ if (up->port.type == PORT_RSA)
-+ serial_outp(up, UART_RSA_FRR, 0);
-+#endif
-+ serial_outp(up, UART_MCR, save_mcr);
-+ serial_outp(up, UART_FCR, (UART_FCR_ENABLE_FIFO |
-+ UART_FCR_CLEAR_RCVR |
-+ UART_FCR_CLEAR_XMIT));
-+ serial_outp(up, UART_FCR, 0);
-+ (void)serial_in(up, UART_RX);
-+ serial_outp(up, UART_IER, 0);
-+
-+ out:
-+ spin_unlock_irqrestore(&up->port.lock, flags);
-+
-+#ifdef CONFIG_SERIAL_8250_RSA
-+ if (up->port.iobase && up->port.type == PORT_RSA) {
-+ release_region(up->port.iobase, 8);
-+ request_region(up->port.iobase + UART_RSA_BASE, 16,
-+ "serial_rsa");
-+ }
-+#endif
-+ DEBUG_AUTOCONF("type=%s\n", uart_config[up->port.type].name);
-+}
-+
-+static void autoconfig_irq(struct uart_8250_port *up)
-+{
-+ unsigned char save_mcr, save_ier;
-+ unsigned char save_ICP = 0;
-+ unsigned int ICP = 0;
-+ unsigned long irqs;
-+ int irq;
-+
-+ if (up->port.flags & UPF_FOURPORT) {
-+ ICP = (up->port.iobase & 0xfe0) | 0x1f;
-+ save_ICP = inb_p(ICP);
-+ outb_p(0x80, ICP);
-+ (void) inb_p(ICP);
-+ }
-+
-+ /* forget possible initially masked and pending IRQ */
-+ probe_irq_off(probe_irq_on());
-+ save_mcr = serial_inp(up, UART_MCR);
-+ save_ier = serial_inp(up, UART_IER);
-+ serial_outp(up, UART_MCR, UART_MCR_OUT1 | UART_MCR_OUT2);
-+
-+ irqs = probe_irq_on();
-+ serial_outp(up, UART_MCR, 0);
-+ udelay (10);
-+ if (up->port.flags & UPF_FOURPORT) {
-+ serial_outp(up, UART_MCR,
-+ UART_MCR_DTR | UART_MCR_RTS);
-+ } else {
-+ serial_outp(up, UART_MCR,
-+ UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2);
-+ }
-+ serial_outp(up, UART_IER, 0x0f); /* enable all intrs */
-+ (void)serial_inp(up, UART_LSR);
-+ (void)serial_inp(up, UART_RX);
-+ (void)serial_inp(up, UART_IIR);
-+ (void)serial_inp(up, UART_MSR);
-+ serial_outp(up, UART_TX, 0xFF);
-+ udelay (20);
-+ irq = probe_irq_off(irqs);
-+
-+ serial_outp(up, UART_MCR, save_mcr);
-+ serial_outp(up, UART_IER, save_ier);
-+
-+ if (up->port.flags & UPF_FOURPORT)
-+ outb_p(save_ICP, ICP);
-+
-+ up->port.irq = (irq > 0) ? irq : 0;
-+}
-+
-+static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop)
-+{
-+ struct uart_8250_port *up = (struct uart_8250_port *)port;
-+
-+ if (up->ier & UART_IER_THRI) {
-+ up->ier &= ~UART_IER_THRI;
-+ serial_out(up, UART_IER, up->ier);
-+ }
-+ if (up->port.type == PORT_16C950 && tty_stop) {
-+ up->acr |= UART_ACR_TXDIS;
-+ serial_icr_write(up, UART_ACR, up->acr);
-+ }
-+}
-+
-+static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start)
-+{
-+ struct uart_8250_port *up = (struct uart_8250_port *)port;
-+
-+ if (!(up->ier & UART_IER_THRI)) {
-+ up->ier |= UART_IER_THRI;
-+ serial_out(up, UART_IER, up->ier);
-+ }
-+ /*
-+ * We only do this from uart_start
-+ */
-+ if (tty_start && up->port.type == PORT_16C950) {
-+ up->acr &= ~UART_ACR_TXDIS;
-+ serial_icr_write(up, UART_ACR, up->acr);
-+ }
-+}
-+
-+static void serial8250_stop_rx(struct uart_port *port)
-+{
-+ struct uart_8250_port *up = (struct uart_8250_port *)port;
-+
-+ up->ier &= ~UART_IER_RLSI;
-+ up->port.read_status_mask &= ~UART_LSR_DR;
-+ serial_out(up, UART_IER, up->ier);
-+}
-+
-+static void serial8250_enable_ms(struct uart_port *port)
-+{
-+ struct uart_8250_port *up = (struct uart_8250_port *)port;
-+
-+ up->ier |= UART_IER_MSI;
-+ serial_out(up, UART_IER, up->ier);
-+}
-+
-+static _INLINE_ void
-+receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs)
-+{
-+ struct tty_struct *tty = up->port.info->tty;
-+ unsigned char ch;
-+ int max_count = 256;
-+
-+ do {
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-+ /*
-+ * FIXME: Deadlock can happen here if we're a
-+ * low-latency port. We're holding the per-port
-+ * spinlock, and we call flush_to_ldisc->
-+ * n_tty_receive_buf->n_tty_receive_char->
-+ * opost->uart_put_char.
-+ */
-+ tty->flip.tqueue.routine((void *)tty);
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+ return; // if TTY_DONT_FLIP is set
-+ }
-+ ch = serial_inp(up, UART_RX);
-+ *tty->flip.char_buf_ptr = ch;
-+ *tty->flip.flag_buf_ptr = TTY_NORMAL;
-+ up->port.icount.rx++;
-+
-+ if (*status & (UART_LSR_BI | UART_LSR_PE |
-+ UART_LSR_FE | UART_LSR_OE)) {
-+ /*
-+ * For statistics only
-+ */
-+ if (*status & UART_LSR_BI) {
-+ *status &= ~(UART_LSR_FE | UART_LSR_PE);
-+ up->port.icount.brk++;
-+ /*
-+ * We do the SysRQ and SAK checking
-+ * here because otherwise the break
-+ * may get masked by ignore_status_mask
-+ * or read_status_mask.
-+ */
-+ if (uart_handle_break(&up->port))
-+ goto ignore_char;
-+ } else if (*status & UART_LSR_PE)
-+ up->port.icount.parity++;
-+ else if (*status & UART_LSR_FE)
-+ up->port.icount.frame++;
-+ if (*status & UART_LSR_OE)
-+ up->port.icount.overrun++;
-+
-+ /*
-+ * Mask off conditions which should be ingored.
-+ */
-+ *status &= up->port.read_status_mask;
-+
-+#ifdef CONFIG_SERIAL_8250_CONSOLE
-+ if (up->port.line == up->port.cons->index) {
-+ /* Recover the break flag from console xmit */
-+ *status |= up->lsr_break_flag;
-+ up->lsr_break_flag = 0;
-+ }
-+#endif
-+ if (*status & UART_LSR_BI) {
-+ DEBUG_INTR("handling break....");
-+ *tty->flip.flag_buf_ptr = TTY_BREAK;
-+ } else if (*status & UART_LSR_PE)
-+ *tty->flip.flag_buf_ptr = TTY_PARITY;
-+ else if (*status & UART_LSR_FE)
-+ *tty->flip.flag_buf_ptr = TTY_FRAME;
-+ }
-+ if (uart_handle_sysrq_char(&up->port, ch, regs))
-+ goto ignore_char;
-+ if ((*status & up->port.ignore_status_mask) == 0) {
-+ tty->flip.flag_buf_ptr++;
-+ tty->flip.char_buf_ptr++;
-+ tty->flip.count++;
-+ }
-+ if ((*status & UART_LSR_OE) &&
-+ tty->flip.count < TTY_FLIPBUF_SIZE) {
-+ /*
-+ * Overrun is special, since it's reported
-+ * immediately, and doesn't affect the current
-+ * character.
-+ */
-+ *tty->flip.flag_buf_ptr = TTY_OVERRUN;
-+ tty->flip.flag_buf_ptr++;
-+ tty->flip.char_buf_ptr++;
-+ tty->flip.count++;
-+ }
-+ ignore_char:
-+ *status = serial_inp(up, UART_LSR);
-+ } while ((*status & UART_LSR_DR) && (max_count-- > 0));
-+ tty_flip_buffer_push(tty);
-+}
-+
-+static _INLINE_ void transmit_chars(struct uart_8250_port *up)
-+{
-+ struct circ_buf *xmit = &up->port.info->xmit;
-+ int count;
-+
-+ if (up->port.x_char) {
-+ serial_outp(up, UART_TX, up->port.x_char);
-+ up->port.icount.tx++;
-+ up->port.x_char = 0;
-+ return;
-+ }
-+ if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
-+ serial8250_stop_tx(&up->port, 0);
-+ return;
-+ }
-+
-+ count = up->port.fifosize;
-+ do {
-+ serial_out(up, UART_TX, xmit->buf[xmit->tail]);
-+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-+ up->port.icount.tx++;
-+ if (uart_circ_empty(xmit))
-+ break;
-+ } while (--count > 0);
-+
-+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-+ uart_write_wakeup(&up->port);
-+
-+ DEBUG_INTR("THRE...");
-+
-+ if (uart_circ_empty(xmit))
-+ serial8250_stop_tx(&up->port, 0);
-+}
-+
-+static _INLINE_ void check_modem_status(struct uart_8250_port *up)
-+{
-+ int status;
-+
-+ status = serial_in(up, UART_MSR);
-+
-+ if ((status & UART_MSR_ANY_DELTA) == 0)
-+ return;
-+
-+ if (status & UART_MSR_TERI)
-+ up->port.icount.rng++;
-+ if (status & UART_MSR_DDSR)
-+ up->port.icount.dsr++;
-+ if (status & UART_MSR_DDCD)
-+ uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
-+ if (status & UART_MSR_DCTS)
-+ uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
-+
-+ wake_up_interruptible(&up->port.info->delta_msr_wait);
-+}
-+
-+/*
-+ * This handles the interrupt from one port.
-+ */
-+static inline void
-+serial8250_handle_port(struct uart_8250_port *up, struct pt_regs *regs)
-+{
-+ unsigned int status = serial_inp(up, UART_LSR);
-+
-+ DEBUG_INTR("status = %x...", status);
-+
-+ if (status & UART_LSR_DR)
-+ receive_chars(up, &status, regs);
-+ check_modem_status(up);
-+ if (status & UART_LSR_THRE)
-+ transmit_chars(up);
-+}
-+
-+/*
-+ * This is the serial driver's interrupt routine.
-+ *
-+ * Arjan thinks the old way was overly complex, so it got simplified.
-+ * Alan disagrees, saying that need the complexity to handle the weird
-+ * nature of ISA shared interrupts. (This is a special exception.)
-+ *
-+ * In order to handle ISA shared interrupts properly, we need to check
-+ * that all ports have been serviced, and therefore the ISA interrupt
-+ * line has been de-asserted.
-+ *
-+ * This means we need to loop through all ports. checking that they
-+ * don't have an interrupt pending.
-+ */
-+static void serial8250_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct irq_info *i = dev_id;
-+ struct list_head *l, *end = NULL;
-+ int pass_counter = 0;
-+
-+ DEBUG_INTR("serial8250_interrupt(%d)...", irq);
-+
-+ spin_lock(&i->lock);
-+
-+ l = i->head;
-+ do {
-+ struct uart_8250_port *up;
-+ unsigned int iir;
-+
-+ up = list_entry(l, struct uart_8250_port, list);
-+
-+ iir = serial_in(up, UART_IIR);
-+ if (!(iir & UART_IIR_NO_INT)) {
-+ spin_lock(&up->port.lock);
-+ serial8250_handle_port(up, regs);
-+ spin_unlock(&up->port.lock);
-+
-+ end = NULL;
-+ } else if (end == NULL)
-+ end = l;
-+
-+ l = l->next;
-+
-+ if (l == i->head && pass_counter++ > PASS_LIMIT) {
-+ /* If we hit this, we're dead. */
-+ printk(KERN_ERR "serial8250: too much work for "
-+ "irq%d\n", irq);
-+ break;
-+ }
-+ } while (l != end);
-+
-+ spin_unlock(&i->lock);
-+
-+ DEBUG_INTR("end.\n");
-+}
-+
-+/*
-+ * To support ISA shared interrupts, we need to have one interrupt
-+ * handler that ensures that the IRQ line has been deasserted
-+ * before returning. Failing to do this will result in the IRQ
-+ * line being stuck active, and, since ISA irqs are edge triggered,
-+ * no more IRQs will be seen.
-+ */
-+static void serial_do_unlink(struct irq_info *i, struct uart_8250_port *up)
-+{
-+ spin_lock_irq(&i->lock);
-+
-+ if (!list_empty(i->head)) {
-+ if (i->head == &up->list)
-+ i->head = i->head->next;
-+ list_del(&up->list);
-+ } else {
-+ BUG_ON(i->head != &up->list);
-+ i->head = NULL;
-+ }
-+
-+ spin_unlock_irq(&i->lock);
-+}
-+
-+static int serial_link_irq_chain(struct uart_8250_port *up)
-+{
-+ struct irq_info *i = irq_lists + up->port.irq;
-+ int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? SA_SHIRQ : 0;
-+
-+ spin_lock_irq(&i->lock);
-+
-+ if (i->head) {
-+ list_add(&up->list, i->head);
-+ spin_unlock_irq(&i->lock);
-+
-+ ret = 0;
-+ } else {
-+ INIT_LIST_HEAD(&up->list);
-+ i->head = &up->list;
-+ spin_unlock_irq(&i->lock);
-+
-+ ret = request_irq(up->port.irq, serial8250_interrupt,
-+ irq_flags, "serial", i);
-+ if (ret < 0)
-+ serial_do_unlink(i, up);
-+ }
-+
-+ return ret;
-+}
-+
-+static void serial_unlink_irq_chain(struct uart_8250_port *up)
-+{
-+ struct irq_info *i = irq_lists + up->port.irq;
-+
-+ BUG_ON(i->head == NULL);
-+
-+ if (list_empty(i->head))
-+ free_irq(up->port.irq, i);
-+
-+ serial_do_unlink(i, up);
-+}
-+
-+/*
-+ * This function is used to handle ports that do not have an
-+ * interrupt. This doesn't work very well for 16450's, but gives
-+ * barely passable results for a 16550A. (Although at the expense
-+ * of much CPU overhead).
-+ */
-+static void serial8250_timeout(unsigned long data)
-+{
-+ struct uart_8250_port *up = (struct uart_8250_port *)data;
-+ unsigned int timeout;
-+ unsigned int iir;
-+
-+ iir = serial_in(up, UART_IIR);
-+ if (!(iir & UART_IIR_NO_INT)) {
-+ spin_lock(&up->port.lock);
-+ serial8250_handle_port(up, NULL);
-+ spin_unlock(&up->port.lock);
-+ }
-+
-+ timeout = up->port.timeout;
-+ timeout = timeout > 6 ? (timeout / 2 - 2) : 1;
-+ mod_timer(&up->timer, jiffies + timeout);
-+}
-+
-+static unsigned int serial8250_tx_empty(struct uart_port *port)
-+{
-+ struct uart_8250_port *up = (struct uart_8250_port *)port;
-+ unsigned long flags;
-+ unsigned int ret;
-+
-+ spin_lock_irqsave(&up->port.lock, flags);
-+ ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0;
-+ spin_unlock_irqrestore(&up->port.lock, flags);
-+
-+ return ret;
-+}
-+
-+static unsigned int serial8250_get_mctrl(struct uart_port *port)
-+{
-+ struct uart_8250_port *up = (struct uart_8250_port *)port;
-+ unsigned long flags;
-+ unsigned char status;
-+ unsigned int ret;
-+
-+ spin_lock_irqsave(&up->port.lock, flags);
-+ status = serial_in(up, UART_MSR);
-+ spin_unlock_irqrestore(&up->port.lock, flags);
-+
-+ ret = 0;
-+ if (status & UART_MSR_DCD)
-+ ret |= TIOCM_CAR;
-+ if (status & UART_MSR_RI)
-+ ret |= TIOCM_RNG;
-+ if (status & UART_MSR_DSR)
-+ ret |= TIOCM_DSR;
-+ if (status & UART_MSR_CTS)
-+ ret |= TIOCM_CTS;
-+ return ret;
-+}
-+
-+static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
-+{
-+ struct uart_8250_port *up = (struct uart_8250_port *)port;
-+ unsigned char mcr = 0;
-+
-+ if (mctrl & TIOCM_RTS)
-+ mcr |= UART_MCR_RTS;
-+ if (mctrl & TIOCM_DTR)
-+ mcr |= UART_MCR_DTR;
-+ if (mctrl & TIOCM_OUT1)
-+ mcr |= UART_MCR_OUT1;
-+ if (mctrl & TIOCM_OUT2)
-+ mcr |= UART_MCR_OUT2;
-+ if (mctrl & TIOCM_LOOP)
-+ mcr |= UART_MCR_LOOP;
-+
-+ mcr = (mcr & up->mcr_mask) | up->mcr_force | up->mcr;
-+
-+ serial_out(up, UART_MCR, mcr);
-+}
-+
-+static void serial8250_break_ctl(struct uart_port *port, int break_state)
-+{
-+ struct uart_8250_port *up = (struct uart_8250_port *)port;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&up->port.lock, flags);
-+ if (break_state == -1)
-+ up->lcr |= UART_LCR_SBC;
-+ else
-+ up->lcr &= ~UART_LCR_SBC;
-+ serial_out(up, UART_LCR, up->lcr);
-+ spin_unlock_irqrestore(&up->port.lock, flags);
-+}
-+
-+static int serial8250_startup(struct uart_port *port)
-+{
-+ struct uart_8250_port *up = (struct uart_8250_port *)port;
-+ unsigned long flags;
-+ unsigned char lsr, iir;
-+ int retval;
-+
-+ up->capabilities = uart_config[up->port.type].flags;
-+ up->mcr = 0;
-+ up->efr = 0;
-+ up->ier = 0;
-+
-+ if (up->port.type == PORT_16C950) {
-+ /* Wake up and initialize UART */
-+ up->acr = 0;
-+ serial_outp(up, UART_LCR, 0xBF);
-+ serial_outp(up, UART_EFR, UART_EFR_ECB);
-+ serial_outp(up, UART_IER, 0);
-+ serial_outp(up, UART_LCR, 0);
-+ serial_icr_write(up, UART_CSR, 0); /* Reset the UART */
-+ serial_outp(up, UART_LCR, 0xBF);
-+ serial_outp(up, UART_EFR, UART_EFR_ECB);
-+ serial_outp(up, UART_LCR, 0);
-+ }
-+
-+#ifdef CONFIG_SERIAL_8250_RSA
-+ /*
-+ * If this is an RSA port, see if we can kick it up to the
-+ * higher speed clock.
-+ */
-+ enable_rsa(up);
-+#endif
-+
-+ /*
-+ * Clear the FIFO buffers and disable them.
-+ * (they will be reeanbled in change_speed())
-+ */
-+ if (up->capabilities & UART_CLEAR_FIFO) {
-+ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
-+ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
-+ UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
-+ serial_outp(up, UART_FCR, 0);
-+ }
-+
-+ /*
-+ * Clear the interrupt registers.
-+ */
-+ (void) serial_inp(up, UART_LSR);
-+ (void) serial_inp(up, UART_RX);
-+ (void) serial_inp(up, UART_IIR);
-+ (void) serial_inp(up, UART_MSR);
-+
-+ /*
-+ * At this point, there's no way the LSR could still be 0xff;
-+ * if it is, then bail out, because there's likely no UART
-+ * here.
-+ */
-+ if (!(up->port.flags & UPF_BUGGY_UART) &&
-+ (serial_inp(up, UART_LSR) == 0xff)) {
-+ printk("ttyS%d: LSR safety check engaged!\n", up->port.line);
-+ return -ENODEV;
-+ }
-+
-+ /*
-+ * If the "interrupt" for this port doesn't correspond with any
-+ * hardware interrupt, we use a timer-based system. The original
-+ * driver used to do this with IRQ0.
-+ */
-+ if (!is_real_interrupt(up->port.irq)) {
-+ unsigned int timeout = up->port.timeout;
-+
-+ timeout = timeout > 6 ? (timeout / 2 - 2) : 1;
-+
-+ up->timer.data = (unsigned long)up;
-+ mod_timer(&up->timer, jiffies + timeout);
-+ } else {
-+ retval = serial_link_irq_chain(up);
-+ if (retval)
-+ return retval;
-+ }
-+
-+ /*
-+ * Now, initialize the UART
-+ */
-+ serial_outp(up, UART_LCR, UART_LCR_WLEN8);
-+
-+ spin_lock_irqsave(&up->port.lock, flags);
-+ if (up->port.flags & UPF_FOURPORT) {
-+ if (!is_real_interrupt(up->port.irq))
-+ up->port.mctrl |= TIOCM_OUT1;
-+ } else
-+ /*
-+ * Most PC uarts need OUT2 raised to enable interrupts.
-+ */
-+ if (is_real_interrupt(up->port.irq))
-+ up->port.mctrl |= TIOCM_OUT2;
-+
-+ serial8250_set_mctrl(&up->port, up->port.mctrl);
-+
-+ /*
-+ * Do a quick test to see if we receive an
-+ * interrupt when we enable the TX irq.
-+ */
-+ serial_outp(up, UART_IER, UART_IER_THRI);
-+ lsr = serial_in(up, UART_LSR);
-+ iir = serial_in(up, UART_IIR);
-+ serial_outp(up, UART_IER, 0);
-+
-+ if (lsr & UART_LSR_TEMT && iir & UART_IIR_NO_INT) {
-+ up->capabilities |= UART_BAD_TX_ENABLE;
-+ printk("ttyS%d - enabling bad tx status workarounds\n",
-+ port->line);
-+ }
-+
-+ spin_unlock_irqrestore(&up->port.lock, flags);
-+
-+ /*
-+ * Finally, enable interrupts. Note: Modem status interrupts
-+ * are set via change_speed(), which will be occuring imminently
-+ * anyway, so we don't enable them here.
-+ */
-+ up->ier = UART_IER_RLSI | UART_IER_RDI;
-+ serial_outp(up, UART_IER, up->ier);
-+
-+ if (up->port.flags & UPF_FOURPORT) {
-+ unsigned int icp;
-+ /*
-+ * Enable interrupts on the AST Fourport board
-+ */
-+ icp = (up->port.iobase & 0xfe0) | 0x01f;
-+ outb_p(0x80, icp);
-+ (void) inb_p(icp);
-+ }
-+
-+ /*
-+ * And clear the interrupt registers again for luck.
-+ */
-+ (void) serial_inp(up, UART_LSR);
-+ (void) serial_inp(up, UART_RX);
-+ (void) serial_inp(up, UART_IIR);
-+ (void) serial_inp(up, UART_MSR);
-+
-+ return 0;
-+}
-+
-+static void serial8250_shutdown(struct uart_port *port)
-+{
-+ struct uart_8250_port *up = (struct uart_8250_port *)port;
-+ unsigned long flags;
-+
-+ /*
-+ * Disable interrupts from this port
-+ */
-+ up->ier = 0;
-+ serial_outp(up, UART_IER, 0);
-+
-+ spin_lock_irqsave(&up->port.lock, flags);
-+ if (up->port.flags & UPF_FOURPORT) {
-+ /* reset interrupts on the AST Fourport board */
-+ inb((up->port.iobase & 0xfe0) | 0x1f);
-+ up->port.mctrl |= TIOCM_OUT1;
-+ } else
-+ up->port.mctrl &= ~TIOCM_OUT2;
-+
-+ serial8250_set_mctrl(&up->port, up->port.mctrl);
-+ spin_unlock_irqrestore(&up->port.lock, flags);
-+
-+ /*
-+ * Disable break condition and FIFOs
-+ */
-+ serial_out(up, UART_LCR, serial_inp(up, UART_LCR) & ~UART_LCR_SBC);
-+ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
-+ UART_FCR_CLEAR_RCVR |
-+ UART_FCR_CLEAR_XMIT);
-+ serial_outp(up, UART_FCR, 0);
-+
-+#ifdef CONFIG_SERIAL_8250_RSA
-+ /*
-+ * Reset the RSA board back to 115kbps compat mode.
-+ */
-+ disable_rsa(up);
-+#endif
-+
-+ /*
-+ * Read data port to reset things, and then unlink from
-+ * the IRQ chain.
-+ */
-+ (void) serial_in(up, UART_RX);
-+
-+ if (!is_real_interrupt(up->port.irq))
-+ del_timer_sync(&up->timer);
-+ else
-+ serial_unlink_irq_chain(up);
-+}
-+
-+static void serial8250_change_speed(struct uart_port *port, unsigned int cflag, unsigned int iflag, unsigned int quot)
-+{
-+ struct uart_8250_port *up = (struct uart_8250_port *)port;
-+ unsigned char cval, fcr = 0;
-+ unsigned long flags;
-+
-+ switch (cflag & CSIZE) {
-+ case CS5:
-+ cval = 0x00;
-+ break;
-+ case CS6:
-+ cval = 0x01;
-+ break;
-+ case CS7:
-+ cval = 0x02;
-+ break;
-+ default:
-+ case CS8:
-+ cval = 0x03;
-+ break;
-+ }
-+
-+ if (cflag & CSTOPB)
-+ cval |= 0x04;
-+ if (cflag & PARENB)
-+ cval |= UART_LCR_PARITY;
-+ if (!(cflag & PARODD))
-+ cval |= UART_LCR_EPAR;
-+#ifdef CMSPAR
-+ if (cflag & CMSPAR)
-+ cval |= UART_LCR_SPAR;
-+#endif
-+
-+ /*
-+ * Work around a bug in the Oxford Semiconductor 952 rev B
-+ * chip which causes it to seriously miscalculate baud rates
-+ * when DLL is 0.
-+ */
-+ if ((quot & 0xff) == 0 && up->port.type == PORT_16C950 &&
-+ up->rev == 0x5201)
-+ quot ++;
-+
-+ if (up->capabilities & UART_USE_FIFO) {
-+ if ((up->port.uartclk / quot) < (2400 * 16))
-+ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
-+#ifdef CONFIG_SERIAL_8250_RSA
-+ else if (up->port.type == PORT_RSA)
-+ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_14;
-+#endif
-+ else
-+ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
-+ }
-+ if (up->port.type == PORT_16750)
-+ fcr |= UART_FCR7_64BYTE;
-+
-+ /*
-+ * Ok, we're now changing the port state. Do it with
-+ * interrupts disabled.
-+ */
-+ spin_lock_irqsave(&up->port.lock, flags);
-+
-+ up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
-+ if (iflag & IGNPAR)
-+ up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE;
-+ if (iflag & (BRKINT | PARMRK))
-+ up->port.read_status_mask |= UART_LSR_BI;
-+
-+ /*
-+ * Characteres to ignore
-+ */
-+ up->port.ignore_status_mask = 0;
-+ if (iflag & IGNPAR)
-+ up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
-+ if (iflag & IGNBRK) {
-+ up->port.ignore_status_mask |= UART_LSR_BI;
-+ /*
-+ * If we're ignoring parity and break indicators,
-+ * ignore overruns too (for real raw support).
-+ */
-+ if (iflag & IGNPAR)
-+ up->port.ignore_status_mask |= UART_LSR_OE;
-+ }
-+
-+ /*
-+ * ignore all characters if CREAD is not set
-+ */
-+ if ((cflag & CREAD) == 0)
-+ up->port.ignore_status_mask |= UART_LSR_DR;
-+
-+ /*
-+ * CTS flow control flag and modem status interrupts
-+ */
-+ up->ier &= ~UART_IER_MSI;
-+ if (UART_ENABLE_MS(&up->port, cflag))
-+ up->ier |= UART_IER_MSI;
-+
-+ serial_out(up, UART_IER, up->ier);
-+
-+ if (up->capabilities & UART_MCRAFE) {
-+ /*
-+ * TI16C750 hardware flow control
-+ */
-+ up->mcr &= ~UART_MCR_AFE;
-+ if (cflag & CRTSCTS)
-+ up->mcr |= UART_MCR_AFE;
-+ }
-+ if (up->capabilities & UART_EFRAFE) {
-+ /*
-+ * TI16C752/Startech hardware flow control
-+ * FIXME:
-+ * - TI16C752 requires control thresholds
-+ * to be set for auto-RTS.
-+ * - We only enable auto-CTS here.
-+ * Note: ST16C654 does not allow MCR bit 1
-+ * to override RTS when UART_EFR_RTS is set.
-+ */
-+ up->efr &= ~UART_EFR_CTS;
-+ if (cflag & CRTSCTS)
-+ up->efr |= UART_EFR_CTS;
-+ serial_outp(up, UART_LCR, 0xBF);
-+ serial_outp(up, UART_EFR, up->efr);
-+ }
-+
-+ if (up->capabilities & UART_NATSEMI) {
-+ /* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */
-+ serial_outp(up, UART_LCR, 0xe0);
-+ } else {
-+ serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
-+ }
-+ serial_outp(up, UART_DLL, quot & 0xff); /* LS of divisor */
-+ serial_outp(up, UART_DLM, quot >> 8); /* MS of divisor */
-+ if (up->port.type == PORT_16750)
-+ serial_outp(up, UART_FCR, fcr); /* set fcr */
-+ serial_outp(up, UART_LCR, cval); /* reset DLAB */
-+ up->lcr = cval; /* Save LCR */
-+ if (up->port.type != PORT_16750) {
-+ if (fcr & UART_FCR_ENABLE_FIFO) {
-+ /* emulated UARTs (Lucent Venus 167x) need two steps */
-+ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
-+ }
-+ serial_outp(up, UART_FCR, fcr); /* set fcr */
-+ }
-+ serial8250_set_mctrl(&up->port, up->port.mctrl);
-+ spin_unlock_irqrestore(&up->port.lock, flags);
-+}
-+
-+static void
-+serial8250_pm(struct uart_port *port, unsigned int state,
-+ unsigned int oldstate)
-+{
-+ struct uart_8250_port *up = (struct uart_8250_port *)port;
-+ if (state) {
-+ /* sleep */
-+ if (up->capabilities & UART_STARTECH) {
-+ /* Arrange to enter sleep mode */
-+ serial_outp(up, UART_LCR, 0xBF);
-+ serial_outp(up, UART_EFR, UART_EFR_ECB);
-+ serial_outp(up, UART_LCR, 0);
-+ serial_outp(up, UART_IER, UART_IERX_SLEEP);
-+ serial_outp(up, UART_LCR, 0xBF);
-+ serial_outp(up, UART_EFR, 0);
-+ serial_outp(up, UART_LCR, 0);
-+ }
-+ if (up->port.type == PORT_16750) {
-+ /* Arrange to enter sleep mode */
-+ serial_outp(up, UART_IER, UART_IERX_SLEEP);
-+ }
-+ } else {
-+ /* wake */
-+ if (up->capabilities & UART_STARTECH) {
-+ /* Wake up UART */
-+ serial_outp(up, UART_LCR, 0xBF);
-+ serial_outp(up, UART_EFR, UART_EFR_ECB);
-+ /*
-+ * Turn off LCR == 0xBF so we actually set the IER
-+ * register on the XR16C850
-+ */
-+ serial_outp(up, UART_LCR, 0);
-+ serial_outp(up, UART_IER, 0);
-+ /*
-+ * Now reset LCR so we can turn off the ECB bit
-+ */
-+ serial_outp(up, UART_LCR, 0xBF);
-+ serial_outp(up, UART_EFR, 0);
-+ /*
-+ * For a XR16C850, we need to set the trigger levels
-+ */
-+ if (up->port.type == PORT_16850) {
-+ unsigned char fctr;
-+
-+ fctr = serial_inp(up, UART_FCTR) &
-+ ~(UART_FCTR_RX | UART_FCTR_TX);
-+ serial_outp(up, UART_FCTR, fctr |
-+ UART_FCTR_TRGD |
-+ UART_FCTR_RX);
-+ serial_outp(up, UART_TRG, UART_TRG_96);
-+ serial_outp(up, UART_FCTR, fctr |
-+ UART_FCTR_TRGD |
-+ UART_FCTR_TX);
-+ serial_outp(up, UART_TRG, UART_TRG_96);
-+ }
-+ serial_outp(up, UART_LCR, 0);
-+ }
-+
-+ if (up->port.type == PORT_16750) {
-+ /* Wake up UART */
-+ serial_outp(up, UART_IER, 0);
-+ }
-+ }
-+}
-+
-+/*
-+ * Resource handling. This is complicated by the fact that resources
-+ * depend on the port type. Maybe we should be claiming the standard
-+ * 8250 ports, and then trying to get other resources as necessary?
-+ */
-+static int
-+serial8250_request_std_resource(struct uart_8250_port *up, struct resource **res)
-+{
-+ unsigned int size = 8 << up->port.regshift;
-+ int ret = 0;
-+
-+ switch (up->port.iotype) {
-+ case SERIAL_IO_MEM:
-+ if (up->port.mapbase) {
-+ *res = request_mem_region(up->port.mapbase, size, "serial");
-+ if (!*res)
-+ ret = -EBUSY;
-+ }
-+ break;
-+
-+ case SERIAL_IO_HUB6:
-+ case SERIAL_IO_PORT:
-+ *res = request_region(up->port.iobase, size, "serial");
-+ if (!*res)
-+ ret = -EBUSY;
-+ break;
-+ }
-+ return ret;
-+}
-+
-+static int
-+serial8250_request_rsa_resource(struct uart_8250_port *up, struct resource **res)
-+{
-+ unsigned int size = 8 << up->port.regshift;
-+ unsigned long start;
-+ int ret = 0;
-+
-+ switch (up->port.iotype) {
-+ case SERIAL_IO_MEM:
-+ if (up->port.mapbase) {
-+ start = up->port.mapbase;
-+ start += UART_RSA_BASE << up->port.regshift;
-+ *res = request_mem_region(start, size, "serial-rsa");
-+ if (!*res)
-+ ret = -EBUSY;
-+ }
-+ break;
-+
-+ case SERIAL_IO_HUB6:
-+ case SERIAL_IO_PORT:
-+ start = up->port.iobase;
-+ start += UART_RSA_BASE << up->port.regshift;
-+ *res = request_region(start, size, "serial-rsa");
-+ if (!*res)
-+ ret = -EBUSY;
-+ break;
-+ }
-+
-+ return ret;
-+}
-+
-+static void serial8250_release_port(struct uart_port *port)
-+{
-+ struct uart_8250_port *up = (struct uart_8250_port *)port;
-+ unsigned long start, offset = 0, size = 0;
-+
-+ if (up->port.type == PORT_RSA) {
-+ offset = UART_RSA_BASE << up->port.regshift;
-+ size = 8;
-+ }
-+
-+ size <<= up->port.regshift;
-+
-+ switch (up->port.iotype) {
-+ case SERIAL_IO_MEM:
-+ if (up->port.mapbase) {
-+ /*
-+ * Unmap the area.
-+ */
-+ if (up->port.flags & UPF_IOREMAP) {
-+ iounmap(up->port.membase);
-+ up->port.membase = NULL;
-+ }
-+
-+ start = up->port.mapbase;
-+
-+ if (size)
-+ release_mem_region(start + offset, size);
-+ release_mem_region(start, 8 << up->port.regshift);
-+ }
-+ break;
-+
-+ case SERIAL_IO_HUB6:
-+ case SERIAL_IO_PORT:
-+ start = up->port.iobase;
-+
-+ if (size)
-+ release_region(start + offset, size);
-+ release_region(start + offset, 8 << up->port.regshift);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+}
-+
-+static int serial8250_request_port(struct uart_port *port)
-+{
-+ struct uart_8250_port *up = (struct uart_8250_port *)port;
-+ struct resource *res = NULL, *res_rsa = NULL;
-+ int ret = 0;
-+
-+ if (up->port.flags & UPF_RESOURCES) {
-+ if (up->port.type == PORT_RSA) {
-+ ret = serial8250_request_rsa_resource(up, &res_rsa);
-+ if (ret < 0)
-+ return ret;
-+ }
-+
-+ ret = serial8250_request_std_resource(up, &res);
-+ }
-+
-+ /*
-+ * If we have a mapbase, then request that as well.
-+ */
-+ if (ret == 0 && up->port.flags & UPF_IOREMAP) {
-+ int size = res->end - res->start + 1;
-+
-+ up->port.membase = ioremap(up->port.mapbase, size);
-+ if (!up->port.membase)
-+ ret = -ENOMEM;
-+ }
-+
-+ if (ret < 0) {
-+ if (res_rsa)
-+ release_resource(res_rsa);
-+ if (res)
-+ release_resource(res);
-+ }
-+ return ret;
-+}
-+
-+static void serial8250_config_port(struct uart_port *port, int flags)
-+{
-+ struct uart_8250_port *up = (struct uart_8250_port *)port;
-+ struct resource *res_std = NULL, *res_rsa = NULL;
-+ int probeflags = PROBE_ANY;
-+ int ret;
-+
-+#ifdef CONFIG_MCA
-+ /*
-+ * Don't probe for MCA ports on non-MCA machines.
-+ */
-+ if (up->port.flags & UPF_BOOT_ONLYMCA && !MCA_bus)
-+ return;
-+#endif
-+
-+ /*
-+ * Find the region that we can probe for. This in turn
-+ * tells us whether we can probe for the type of port.
-+ */
-+ if (up->port.flags & UPF_RESOURCES) {
-+ ret = serial8250_request_std_resource(up, &res_std);
-+ if (ret < 0)
-+ return;
-+
-+ ret = serial8250_request_rsa_resource(up, &res_rsa);
-+ if (ret < 0)
-+ probeflags &= ~PROBE_RSA;
-+ } else {
-+ probeflags &= ~PROBE_RSA;
-+ }
-+
-+ if (flags & UART_CONFIG_TYPE)
-+ autoconfig(up, probeflags);
-+ if (up->port.type != PORT_UNKNOWN && flags & UART_CONFIG_IRQ)
-+ autoconfig_irq(up);
-+
-+ /*
-+ * If the port wasn't an RSA port, release the resource.
-+ */
-+ if (up->port.type != PORT_RSA && res_rsa)
-+ release_resource(res_rsa);
-+
-+ if (up->port.type == PORT_UNKNOWN && res_std)
-+ release_resource(res_std);
-+}
-+
-+static int
-+serial8250_verify_port(struct uart_port *port, struct serial_struct *ser)
-+{
-+ if (ser->irq >= NR_IRQS || ser->irq < 0 ||
-+ ser->baud_base < 9600 || ser->type < PORT_UNKNOWN ||
-+ ser->type > PORT_MAX_8250 || ser->type == PORT_CIRRUS ||
-+ ser->type == PORT_STARTECH)
-+ return -EINVAL;
-+ return 0;
-+}
-+
-+static const char *
-+serial8250_type(struct uart_port *port)
-+{
-+ int type = port->type;
-+
-+ if (type >= ARRAY_SIZE(uart_config))
-+ type = 0;
-+ return uart_config[type].name;
-+}
-+
-+static struct uart_ops serial8250_pops = {
-+ .tx_empty = serial8250_tx_empty,
-+ .set_mctrl = serial8250_set_mctrl,
-+ .get_mctrl = serial8250_get_mctrl,
-+ .stop_tx = serial8250_stop_tx,
-+ .start_tx = serial8250_start_tx,
-+ .stop_rx = serial8250_stop_rx,
-+ .enable_ms = serial8250_enable_ms,
-+ .break_ctl = serial8250_break_ctl,
-+ .startup = serial8250_startup,
-+ .shutdown = serial8250_shutdown,
-+ .change_speed = serial8250_change_speed,
-+ .pm = serial8250_pm,
-+ .type = serial8250_type,
-+ .release_port = serial8250_release_port,
-+ .request_port = serial8250_request_port,
-+ .config_port = serial8250_config_port,
-+ .verify_port = serial8250_verify_port,
-+};
-+
-+static struct uart_8250_port serial8250_ports[UART_NR];
-+
-+static void __init serial8250_isa_init_ports(void)
-+{
-+ struct uart_8250_port *up;
-+ static int first = 1;
-+ int i;
-+
-+ if (!first)
-+ return;
-+ first = 0;
-+
-+ for (i = 0, up = serial8250_ports; i < ARRAY_SIZE(old_serial_port);
-+ i++, up++) {
-+ up->port.iobase = old_serial_port[i].port;
-+ up->port.irq = irq_cannonicalize(old_serial_port[i].irq);
-+ up->port.uartclk = old_serial_port[i].baud_base * 16;
-+ up->port.flags = old_serial_port[i].flags |
-+ UPF_RESOURCES;
-+ up->port.hub6 = old_serial_port[i].hub6;
-+ up->port.membase = old_serial_port[i].iomem_base;
-+ up->port.iotype = old_serial_port[i].io_type;
-+ up->port.regshift = old_serial_port[i].iomem_reg_shift;
-+ up->port.ops = &serial8250_pops;
-+
-+ if (up->port.iotype == UPIO_MEM && up->port.mapbase)
-+ up->port.flags |= UPF_IOREMAP;
-+
-+ if (share_irqs)
-+ up->port.flags |= UPF_SHARE_IRQ;
-+ }
-+}
-+
-+static void __init serial8250_register_ports(struct uart_driver *drv)
-+{
-+ int i;
-+
-+ serial8250_isa_init_ports();
-+
-+ for (i = 0; i < UART_NR; i++) {
-+ struct uart_8250_port *up = &serial8250_ports[i];
-+
-+ up->port.line = i;
-+ up->port.ops = &serial8250_pops;
-+ init_timer(&up->timer);
-+ up->timer.function = serial8250_timeout;
-+
-+ /*
-+ * ALPHA_KLUDGE_MCR needs to be killed.
-+ */
-+ up->mcr_mask = ~ALPHA_KLUDGE_MCR;
-+ up->mcr_force = ALPHA_KLUDGE_MCR;
-+
-+ uart_add_one_port(drv, &up->port);
-+ }
-+}
-+
-+#ifdef CONFIG_SERIAL_8250_CONSOLE
-+
-+#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
-+
-+/*
-+ * Wait for transmitter & holding register to empty
-+ */
-+static inline void wait_for_xmitr(struct uart_8250_port *up)
-+{
-+ unsigned int status, tmout = 10000;
-+
-+ /* Wait up to 10ms for the character(s) to be sent. */
-+ do {
-+ status = serial_in(up, UART_LSR);
-+
-+ if (status & UART_LSR_BI)
-+ up->lsr_break_flag = UART_LSR_BI;
-+
-+ if (--tmout == 0)
-+ break;
-+ udelay(1);
-+ } while ((status & BOTH_EMPTY) != BOTH_EMPTY);
-+
-+ /* Wait up to 1s for flow control if necessary */
-+ if (up->port.flags & UPF_CONS_FLOW) {
-+ tmout = 1000000;
-+ while (--tmout &&
-+ ((serial_in(up, UART_MSR) & UART_MSR_CTS) == 0))
-+ udelay(1);
-+ }
-+}
-+
-+/*
-+ * Print a string to the serial port trying not to disturb
-+ * any possible real use of the port...
-+ *
-+ * The console_lock must be held when we get here.
-+ */
-+static void
-+serial8250_console_write(struct console *co, const char *s, unsigned int count)
-+{
-+ struct uart_8250_port *up = &serial8250_ports[co->index];
-+ unsigned int ier;
-+ int i;
-+
-+ /*
-+ * First save the UER then disable the interrupts
-+ */
-+ ier = serial_in(up, UART_IER);
-+ serial_out(up, UART_IER, 0);
-+
-+ /*
-+ * Now, do each character
-+ */
-+ for (i = 0; i < count; i++, s++) {
-+ wait_for_xmitr(up);
-+
-+ /*
-+ * Send the character out.
-+ * If a LF, also do CR...
-+ */
-+ serial_out(up, UART_TX, *s);
-+ if (*s == 10) {
-+ wait_for_xmitr(up);
-+ serial_out(up, UART_TX, 13);
-+ }
-+ }
-+
-+ /*
-+ * Finally, wait for transmitter to become empty
-+ * and restore the IER
-+ */
-+ wait_for_xmitr(up);
-+ serial_out(up, UART_IER, ier);
-+}
-+
-+static kdev_t serial8250_console_device(struct console *co)
-+{
-+ return MKDEV(TTY_MAJOR, 64 + co->index);
-+}
-+
-+static int __init serial8250_console_setup(struct console *co, char *options)
-+{
-+ struct uart_port *port;
-+ int baud = 9600;
-+ int bits = 8;
-+ int parity = 'n';
-+ int flow = 'n';
-+
-+ /*
-+ * Check whether an invalid uart number has been specified, and
-+ * if so, search for the first available port that does have
-+ * console support.
-+ */
-+ if (co->index >= UART_NR)
-+ co->index = 0;
-+ port = &serial8250_ports[co->index].port;
-+
-+ /*
-+ * Temporary fix.
-+ */
-+ spin_lock_init(&port->lock);
-+
-+ if (options)
-+ uart_parse_options(options, &baud, &parity, &bits, &flow);
-+
-+ return uart_set_options(port, co, baud, parity, bits, flow);
-+}
-+
-+static struct console serial8250_console = {
-+ .name = "ttyS",
-+ .write = serial8250_console_write,
-+ .device = serial8250_console_device,
-+ .setup = serial8250_console_setup,
-+ .flags = CON_PRINTBUFFER,
-+ .index = -1,
-+};
-+
-+void __init serial8250_console_init(void)
-+{
-+ serial8250_isa_init_ports();
-+ register_console(&serial8250_console);
-+}
-+
-+#define SERIAL8250_CONSOLE &serial8250_console
-+#else
-+#define SERIAL8250_CONSOLE NULL
-+#endif
-+
-+static struct uart_driver serial8250_reg = {
-+ .owner = THIS_MODULE,
-+#ifdef CONFIG_DEVFS_FS
-+ .normal_name = "tts/%d",
-+ .callout_name = "cua/%d",
-+#else
-+ .normal_name = "ttyS",
-+ .callout_name = "cua",
-+#endif
-+ .normal_major = TTY_MAJOR,
-+ .callout_major = TTYAUX_MAJOR,
-+ .normal_driver = &normal,
-+ .callout_driver = &callout,
-+ .table = serial8250_table,
-+ .termios = serial8250_termios,
-+ .termios_locked = serial8250_termios_locked,
-+ .minor = 64,
-+ .nr = UART_NR,
-+ .cons = SERIAL8250_CONSOLE,
-+};
-+
-+/*
-+ * register_serial and unregister_serial allows for 16x50 serial ports to be
-+ * configured at run-time, to support PCMCIA modems.
-+ */
-+
-+static int __register_serial(struct serial_struct *req, int line)
-+{
-+ struct uart_port port;
-+
-+ port.iobase = req->port;
-+ port.membase = req->iomem_base;
-+ port.irq = req->irq;
-+ port.uartclk = req->baud_base * 16;
-+ port.fifosize = req->xmit_fifo_size;
-+ port.regshift = req->iomem_reg_shift;
-+ port.iotype = req->io_type;
-+ port.flags = req->flags | UPF_BOOT_AUTOCONF;
-+ port.mapbase = req->iomap_base;
-+ port.line = line;
-+
-+ if (share_irqs)
-+ port.flags |= UPF_SHARE_IRQ;
-+
-+ if (HIGH_BITS_OFFSET)
-+ port.iobase |= (long) req->port_high << HIGH_BITS_OFFSET;
-+
-+ /*
-+ * If a clock rate wasn't specified by the low level
-+ * driver, then default to the standard clock rate.
-+ */
-+ if (port.uartclk == 0)
-+ port.uartclk = BASE_BAUD * 16;
-+
-+ return uart_register_port(&serial8250_reg, &port);
-+}
-+
-+/**
-+ * register_serial - configure a 16x50 serial port at runtime
-+ * @req: request structure
-+ *
-+ * Configure the serial port specified by the request. If the
-+ * port exists and is in use an error is returned. If the port
-+ * is not currently in the table it is added.
-+ *
-+ * The port is then probed and if necessary the IRQ is autodetected
-+ * If this fails an error is returned.
-+ *
-+ * On success the port is ready to use and the line number is returned.
-+ */
-+int register_serial(struct serial_struct *req)
-+{
-+ return __register_serial(req, -1);
-+}
-+
-+/**
-+ * unregister_serial - remove a 16x50 serial port at runtime
-+ * @line: serial line number
-+ *
-+ * Remove one serial port. This may be called from interrupt
-+ * context.
-+ */
-+void unregister_serial(int line)
-+{
-+ uart_unregister_port(&serial8250_reg, line);
-+}
-+
-+/*
-+ * This is for ISAPNP only.
-+ */
-+void serial8250_get_irq_map(unsigned int *map)
-+{
-+ int i;
-+
-+ for (i = 0; i < UART_NR; i++) {
-+ if (serial8250_ports[i].port.type != PORT_UNKNOWN &&
-+ serial8250_ports[i].port.irq < 16)
-+ *map |= 1 << serial8250_ports[i].port.irq;
-+ }
-+}
-+
-+static int __init serial8250_init(void)
-+{
-+ int ret, i;
-+
-+ for (i = 0; i < NR_IRQS; i++)
-+ spin_lock_init(&irq_lists[i].lock);
-+
-+ ret = uart_register_driver(&serial8250_reg);
-+ if (ret >= 0)
-+ serial8250_register_ports(&serial8250_reg);
-+
-+ return ret;
-+}
-+
-+static void __exit serial8250_exit(void)
-+{
-+ int i;
-+
-+ for (i = 0; i < UART_NR; i++)
-+ uart_remove_one_port(&serial8250_reg, &serial8250_ports[i].port);
-+
-+ uart_unregister_driver(&serial8250_reg);
-+}
-+
-+module_init(serial8250_init);
-+module_exit(serial8250_exit);
-+
-+EXPORT_SYMBOL(register_serial);
-+EXPORT_SYMBOL(unregister_serial);
-+EXPORT_SYMBOL(serial8250_get_irq_map);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("Generic 8250/16x50 serial driver");
-+
-+MODULE_PARM(share_irqs, "i");
-+MODULE_PARM_DESC(share_irqs, "Share IRQs with other non-8250/16x50 devices"
-+ " (unsafe)");
-+
-+#if defined(CONFIG_SERIAL_8250_RSA) && defined(MODULE)
-+MODULE_PARM(probe_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i");
-+MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA");
-+MODULE_PARM(force_rsa, "1-" __MODULE_STRING(PORT_RSA_MAX) "i");
-+MODULE_PARM_DESC(force_rsa, "Force I/O ports for RSA");
-+#endif /* CONFIG_SERIAL_8250_RSA */
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/serial/8250.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,88 @@
-+/*
-+ * linux/drivers/serial/8250.h
-+ *
-+ * Driver for 8250/16550-type serial ports
-+ *
-+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
-+ *
-+ * Copyright (C) 2001 Russell King.
-+ *
-+ * 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.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+
-+struct serial8250_probe {
-+ struct module *owner;
-+ int (*pci_init_one)(struct pci_dev *dev);
-+ void (*pci_remove_one)(struct pci_dev *dev);
-+ void (*pnp_init)(void);
-+};
-+
-+int serial8250_register_probe(struct serial8250_probe *probe);
-+void serial8250_unregister_probe(struct serial8250_probe *probe);
-+void serial8250_get_irq_map(unsigned int *map);
-+
-+struct old_serial_port {
-+ unsigned int uart;
-+ unsigned int baud_base;
-+ unsigned int port;
-+ unsigned int irq;
-+ unsigned int flags;
-+ unsigned char hub6;
-+ unsigned char io_type;
-+ unsigned char *iomem_base;
-+ unsigned short iomem_reg_shift;
-+};
-+
-+struct serial8250_config {
-+ const char *name;
-+ unsigned int dfl_xmit_fifo_size;
-+ unsigned int flags;
-+};
-+
-+#define UART_CLEAR_FIFO 0x01
-+#define UART_USE_FIFO 0x02
-+#define UART_STARTECH 0x04
-+#define UART_NATSEMI 0x08
-+#define UART_MCRAFE 0x10 /* TI16C750-style auto-flow */
-+#define UART_EFRAFE 0x20 /* TI16C752/startech auto-flow */
-+
-+#define UART_BAD_TX_ENABLE 0x80000000
-+
-+#if defined(__i386__) && (defined(CONFIG_M386) || defined(CONFIG_M486))
-+#define SERIAL_INLINE
-+#endif
-+
-+#ifdef SERIAL_INLINE
-+#define _INLINE_ inline
-+#else
-+#define _INLINE_
-+#endif
-+
-+#define PROBE_RSA (1 << 0)
-+#define PROBE_ANY (~0)
-+
-+#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
-+
-+#ifdef CONFIG_SERIAL_8250_SHARE_IRQ
-+#define SERIAL8250_SHARE_IRQS 1
-+#else
-+#define SERIAL8250_SHARE_IRQS 0
-+#endif
-+
-+#if defined(__alpha__) && !defined(CONFIG_PCI)
-+/*
-+ * Digital did something really horribly wrong with the OUT1 and OUT2
-+ * lines on at least some ALPHA's. The failure mode is that if either
-+ * is cleared, the machine locks up with endless interrupts.
-+ */
-+#define ALPHA_KLUDGE_MCR (UART_MCR_OUT2 | UART_MCR_OUT1)
-+#else
-+#define ALPHA_KLUDGE_MCR 0
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/serial/8250_pci.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,1080 @@
-+/*
-+ * linux/drivers/char/serial_8250_pci.c
-+ *
-+ * Probe module for 8250/16550-type PCI serial ports.
-+ *
-+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
-+ *
-+ * Copyright (C) 2001 Russell King, 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.
-+ *
-+ * $Id$
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/pci.h>
-+#include <linux/sched.h>
-+#include <linux/string.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/serial.h>
-+
-+/* 2.4.6 compatibility cruft ;( */
-+#define pci_board __pci_board
-+#include <linux/serialP.h>
-+#undef pci_board
-+
-+#include <asm/bitops.h>
-+#include <asm/byteorder.h>
-+#include <asm/serial.h>
-+
-+#include "8250.h"
-+
-+#ifndef IS_PCI_REGION_IOPORT
-+#define IS_PCI_REGION_IOPORT(dev, r) (pci_resource_flags((dev), (r)) & \
-+ IORESOURCE_IO)
-+#endif
-+#ifndef IS_PCI_REGION_IOMEM
-+#define IS_PCI_REGION_IOMEM(dev, r) (pci_resource_flags((dev), (r)) & \
-+ IORESOURCE_MEM)
-+#endif
-+#ifndef PCI_IRQ_RESOURCE
-+#define PCI_IRQ_RESOURCE(dev, r) ((dev)->irq_resource[r].start)
-+#endif
-+
-+#ifndef pci_get_subvendor
-+#define pci_get_subvendor(dev) ((dev)->subsystem_vendor)
-+#define pci_get_subdevice(dev) ((dev)->subsystem_device)
-+#endif
-+
-+struct serial_private {
-+ unsigned int nr;
-+ struct pci_board *board;
-+ int line[0];
-+};
-+
-+struct pci_board {
-+ int flags;
-+ int num_ports;
-+ int base_baud;
-+ int uart_offset;
-+ int reg_shift;
-+ int (*init_fn)(struct pci_dev *dev, struct pci_board *board,
-+ int enable);
-+ int first_uart_offset;
-+};
-+
-+static int
-+get_pci_port(struct pci_dev *dev, struct pci_board *board,
-+ struct serial_struct *req, int idx)
-+{
-+ unsigned long port;
-+ int base_idx;
-+ int max_port;
-+ int offset;
-+
-+ base_idx = SPCI_FL_GET_BASE(board->flags);
-+ if (board->flags & SPCI_FL_BASE_TABLE)
-+ base_idx += idx;
-+
-+ if (board->flags & SPCI_FL_REGION_SZ_CAP) {
-+ max_port = pci_resource_len(dev, base_idx) / 8;
-+ if (idx >= max_port)
-+ return 1;
-+ }
-+
-+ offset = board->first_uart_offset;
-+
-+ /* Timedia/SUNIX uses a mixture of BARs and offsets */
-+ /* Ugh, this is ugly as all hell --- TYT */
-+ if(dev->vendor == PCI_VENDOR_ID_TIMEDIA ) /* 0x1409 */
-+ switch(idx) {
-+ case 0: base_idx=0;
-+ break;
-+ case 1: base_idx=0; offset=8;
-+ break;
-+ case 2: base_idx=1;
-+ break;
-+ case 3: base_idx=1; offset=8;
-+ break;
-+ case 4: /* BAR 2*/
-+ case 5: /* BAR 3 */
-+ case 6: /* BAR 4*/
-+ case 7: base_idx=idx-2; /* BAR 5*/
-+ }
-+
-+ /* Some Titan cards are also a little weird */
-+ if (dev->vendor == PCI_VENDOR_ID_TITAN &&
-+ (dev->device == PCI_DEVICE_ID_TITAN_400L ||
-+ dev->device == PCI_DEVICE_ID_TITAN_800L)) {
-+ switch (idx) {
-+ case 0: base_idx = 1;
-+ break;
-+ case 1: base_idx = 2;
-+ break;
-+ default:
-+ base_idx = 4;
-+ offset = 8 * (idx - 2);
-+ }
-+ }
-+
-+ port = pci_resource_start(dev, base_idx) + offset;
-+
-+ if ((board->flags & SPCI_FL_BASE_TABLE) == 0)
-+ port += idx * (board->uart_offset ? board->uart_offset : 8);
-+
-+ if (IS_PCI_REGION_IOPORT(dev, base_idx)) {
-+ req->port = port;
-+ if (HIGH_BITS_OFFSET)
-+ req->port_high = port >> HIGH_BITS_OFFSET;
-+ else
-+ req->port_high = 0;
-+ return 0;
-+ }
-+ req->io_type = SERIAL_IO_MEM;
-+ req->iomem_base = ioremap(port, board->uart_offset);
-+ req->iomem_reg_shift = board->reg_shift;
-+ req->port = 0;
-+ return 0;
-+}
-+
-+static _INLINE_ int get_pci_irq(struct pci_dev *dev,
-+ struct pci_board *board,
-+ int idx)
-+{
-+ int base_idx;
-+
-+ if ((board->flags & SPCI_FL_IRQRESOURCE) == 0)
-+ return dev->irq;
-+
-+ base_idx = SPCI_FL_GET_IRQBASE(board->flags);
-+ if (board->flags & SPCI_FL_IRQ_TABLE)
-+ base_idx += idx;
-+
-+ return PCI_IRQ_RESOURCE(dev, base_idx);
-+}
-+
-+/*
-+ * Some PCI serial cards using the PLX 9050 PCI interface chip require
-+ * that the card interrupt be explicitly enabled or disabled. This
-+ * seems to be mainly needed on card using the PLX which also use I/O
-+ * mapped memory.
-+ */
-+static int __devinit
-+pci_plx9050_fn(struct pci_dev *dev, struct pci_board *board, int enable)
-+{
-+ u8 data, *p, irq_config;
-+ int pci_config;
-+
-+ irq_config = 0x41;
-+ pci_config = PCI_COMMAND_MEMORY;
-+ if (dev->vendor == PCI_VENDOR_ID_PANACOM)
-+ irq_config = 0x43;
-+ if ((dev->vendor == PCI_VENDOR_ID_PLX) &&
-+ (dev->device == PCI_DEVICE_ID_PLX_ROMULUS)) {
-+ /*
-+ * As the megawolf cards have the int pins active
-+ * high, and have 2 UART chips, both ints must be
-+ * enabled on the 9050. Also, the UARTS are set in
-+ * 16450 mode by default, so we have to enable the
-+ * 16C950 'enhanced' mode so that we can use the deep
-+ * FIFOs
-+ */
-+ irq_config = 0x5b;
-+ pci_config = PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
-+ }
-+
-+ pci_read_config_byte(dev, PCI_COMMAND, &data);
-+
-+ if (enable)
-+ pci_write_config_byte(dev, PCI_COMMAND,
-+ data | pci_config);
-+
-+ /* enable/disable interrupts */
-+ p = ioremap(pci_resource_start(dev, 0), 0x80);
-+ writel(enable ? irq_config : 0x00, (unsigned long)p + 0x4c);
-+ iounmap(p);
-+
-+ if (!enable)
-+ pci_write_config_byte(dev, PCI_COMMAND,
-+ data & ~pci_config);
-+ return 0;
-+}
-+
-+
-+/*
-+ * SIIG serial cards have an PCI interface chip which also controls
-+ * the UART clocking frequency. Each UART can be clocked independently
-+ * (except cards equiped with 4 UARTs) and initial clocking settings
-+ * are stored in the EEPROM chip. It can cause problems because this
-+ * version of serial driver doesn't support differently clocked UART's
-+ * on single PCI card. To prevent this, initialization functions set
-+ * high frequency clocking for all UART's on given card. It is safe (I
-+ * hope) because it doesn't touch EEPROM settings to prevent conflicts
-+ * with other OSes (like M$ DOS).
-+ *
-+ * SIIG support added by Andrey Panin <pazke@mail.tp.ru>, 10/1999
-+ *
-+ * There is two family of SIIG serial cards with different PCI
-+ * interface chip and different configuration methods:
-+ * - 10x cards have control registers in IO and/or memory space;
-+ * - 20x cards have control registers in standard PCI configuration space.
-+ */
-+
-+#define PCI_DEVICE_ID_SIIG_1S_10x (PCI_DEVICE_ID_SIIG_1S_10x_550 & 0xfffc)
-+#define PCI_DEVICE_ID_SIIG_2S_10x (PCI_DEVICE_ID_SIIG_2S_10x_550 & 0xfff8)
-+
-+static int __devinit
-+pci_siig10x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
-+{
-+ u16 data, *p;
-+
-+ if (!enable) return 0;
-+
-+ p = ioremap(pci_resource_start(dev, 0), 0x80);
-+
-+ switch (dev->device & 0xfff8) {
-+ case PCI_DEVICE_ID_SIIG_1S_10x: /* 1S */
-+ data = 0xffdf;
-+ break;
-+ case PCI_DEVICE_ID_SIIG_2S_10x: /* 2S, 2S1P */
-+ data = 0xf7ff;
-+ break;
-+ default: /* 1S1P, 4S */
-+ data = 0xfffb;
-+ break;
-+ }
-+
-+ writew(readw((unsigned long) p + 0x28) & data, (unsigned long) p + 0x28);
-+ iounmap(p);
-+ return 0;
-+}
-+
-+#define PCI_DEVICE_ID_SIIG_2S_20x (PCI_DEVICE_ID_SIIG_2S_20x_550 & 0xfffc)
-+#define PCI_DEVICE_ID_SIIG_2S1P_20x (PCI_DEVICE_ID_SIIG_2S1P_20x_550 & 0xfffc)
-+
-+static int __devinit
-+pci_siig20x_fn(struct pci_dev *dev, struct pci_board *board, int enable)
-+{
-+ u8 data;
-+
-+ if (!enable) return 0;
-+
-+ /* Change clock frequency for the first UART. */
-+ pci_read_config_byte(dev, 0x6f, &data);
-+ pci_write_config_byte(dev, 0x6f, data & 0xef);
-+
-+ /* If this card has 2 UART, we have to do the same with second UART. */
-+ if (((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S_20x) ||
-+ ((dev->device & 0xfffc) == PCI_DEVICE_ID_SIIG_2S1P_20x)) {
-+ pci_read_config_byte(dev, 0x73, &data);
-+ pci_write_config_byte(dev, 0x73, data & 0xef);
-+ }
-+ return 0;
-+}
-+
-+/* Added for EKF Intel i960 serial boards */
-+static int __devinit
-+pci_inteli960ni_fn(struct pci_dev *dev,
-+ struct pci_board *board,
-+ int enable)
-+{
-+ unsigned long oldval;
-+
-+ if (!(pci_get_subdevice(dev) & 0x1000))
-+ return(-1);
-+
-+ if (!enable) /* is there something to deinit? */
-+ return(0);
-+
-+ /* is firmware started? */
-+ pci_read_config_dword(dev, 0x44, (void*) &oldval);
-+ if (oldval == 0x00001000L) { /* RESET value */
-+ printk(KERN_DEBUG "Local i960 firmware missing");
-+ return(-1);
-+ }
-+ return(0);
-+}
-+
-+/*
-+ * Timedia has an explosion of boards, and to avoid the PCI table from
-+ * growing *huge*, we use this function to collapse some 70 entries
-+ * in the PCI table into one, for sanity's and compactness's sake.
-+ */
-+static unsigned short timedia_single_port[] = {
-+ 0x4025, 0x4027, 0x4028, 0x5025, 0x5027, 0 };
-+static unsigned short timedia_dual_port[] = {
-+ 0x0002, 0x4036, 0x4037, 0x4038, 0x4078, 0x4079, 0x4085,
-+ 0x4088, 0x4089, 0x5037, 0x5078, 0x5079, 0x5085, 0x6079,
-+ 0x7079, 0x8079, 0x8137, 0x8138, 0x8237, 0x8238, 0x9079,
-+ 0x9137, 0x9138, 0x9237, 0x9238, 0xA079, 0xB079, 0xC079,
-+ 0xD079, 0 };
-+static unsigned short timedia_quad_port[] = {
-+ 0x4055, 0x4056, 0x4095, 0x4096, 0x5056, 0x8156, 0x8157,
-+ 0x8256, 0x8257, 0x9056, 0x9156, 0x9157, 0x9158, 0x9159,
-+ 0x9256, 0x9257, 0xA056, 0xA157, 0xA158, 0xA159, 0xB056,
-+ 0xB157, 0 };
-+static unsigned short timedia_eight_port[] = {
-+ 0x4065, 0x4066, 0x5065, 0x5066, 0x8166, 0x9066, 0x9166,
-+ 0x9167, 0x9168, 0xA066, 0xA167, 0xA168, 0 };
-+static struct timedia_struct {
-+ int num;
-+ unsigned short *ids;
-+} timedia_data[] = {
-+ { 1, timedia_single_port },
-+ { 2, timedia_dual_port },
-+ { 4, timedia_quad_port },
-+ { 8, timedia_eight_port },
-+ { 0, 0 }
-+};
-+
-+static int __devinit
-+pci_timedia_fn(struct pci_dev *dev, struct pci_board *board, int enable)
-+{
-+ int i, j;
-+ unsigned short *ids;
-+
-+ if (!enable)
-+ return 0;
-+
-+ for (i=0; timedia_data[i].num; i++) {
-+ ids = timedia_data[i].ids;
-+ for (j=0; ids[j]; j++) {
-+ if (pci_get_subdevice(dev) == ids[j]) {
-+ board->num_ports = timedia_data[i].num;
-+ return 0;
-+ }
-+ }
-+ }
-+ return 0;
-+}
-+
-+static int __devinit
-+pci_xircom_fn(struct pci_dev *dev, struct pci_board *board, int enable)
-+{
-+ __set_current_state(TASK_UNINTERRUPTIBLE);
-+ schedule_timeout(HZ/10);
-+ return 0;
-+}
-+
-+/*
-+ * This is the configuration table for all of the PCI serial boards
-+ * which we support. It is directly indexed by the pci_board_num_t enum
-+ * value, which is encoded in the pci_device_id PCI probe table's
-+ * driver_data member.
-+ */
-+enum pci_board_num_t {
-+ pbn_b0_1_115200,
-+ pbn_default = 0,
-+
-+ pbn_b0_2_115200,
-+ pbn_b0_4_115200,
-+
-+ pbn_b0_1_921600,
-+ pbn_b0_2_921600,
-+ pbn_b0_4_921600,
-+
-+ pbn_b0_bt_1_115200,
-+ pbn_b0_bt_2_115200,
-+ pbn_b0_bt_1_460800,
-+ pbn_b0_bt_2_460800,
-+
-+ pbn_b1_1_115200,
-+ pbn_b1_2_115200,
-+ pbn_b1_4_115200,
-+ pbn_b1_8_115200,
-+
-+ pbn_b1_2_921600,
-+ pbn_b1_4_921600,
-+ pbn_b1_8_921600,
-+
-+ pbn_b1_2_1382400,
-+ pbn_b1_4_1382400,
-+ pbn_b1_8_1382400,
-+
-+ pbn_b2_8_115200,
-+ pbn_b2_4_460800,
-+ pbn_b2_8_460800,
-+ pbn_b2_16_460800,
-+ pbn_b2_4_921600,
-+ pbn_b2_8_921600,
-+
-+ pbn_b2_bt_1_115200,
-+ pbn_b2_bt_2_115200,
-+ pbn_b2_bt_4_115200,
-+ pbn_b2_bt_2_921600,
-+
-+ pbn_panacom,
-+ pbn_panacom2,
-+ pbn_panacom4,
-+ pbn_plx_romulus,
-+ pbn_oxsemi,
-+ pbn_timedia,
-+ pbn_intel_i960,
-+ pbn_sgi_ioc3,
-+#ifdef CONFIG_DDB5074
-+ pbn_nec_nile4,
-+#endif
-+#if 0
-+ pbn_dci_pccom8,
-+#endif
-+ pbn_xircom_combo,
-+
-+ pbn_siig10x_0,
-+ pbn_siig10x_1,
-+ pbn_siig10x_2,
-+ pbn_siig10x_4,
-+ pbn_siig20x_0,
-+ pbn_siig20x_2,
-+ pbn_siig20x_4,
-+
-+ pbn_computone_4,
-+ pbn_computone_6,
-+ pbn_computone_8,
-+};
-+
-+static struct pci_board pci_boards[] __devinitdata = {
-+ /*
-+ * PCI Flags, Number of Ports, Base (Maximum) Baud Rate,
-+ * Offset to get to next UART's registers,
-+ * Register shift to use for memory-mapped I/O,
-+ * Initialization function, first UART offset
-+ */
-+
-+ /* Generic serial board, pbn_b0_1_115200, pbn_default */
-+ { SPCI_FL_BASE0, 1, 115200 }, /* pbn_b0_1_115200,
-+ pbn_default */
-+
-+ { SPCI_FL_BASE0, 2, 115200 }, /* pbn_b0_2_115200 */
-+ { SPCI_FL_BASE0, 4, 115200 }, /* pbn_b0_4_115200 */
-+
-+ { SPCI_FL_BASE0, 1, 921600 }, /* pbn_b0_1_921600 */
-+ { SPCI_FL_BASE0, 2, 921600 }, /* pbn_b0_2_921600 */
-+ { SPCI_FL_BASE0, 4, 921600 }, /* pbn_b0_4_921600 */
-+
-+ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* pbn_b0_bt_1_115200 */
-+ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* pbn_b0_bt_2_115200 */
-+ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 1, 460800 }, /* pbn_b0_bt_1_460800 */
-+ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 460800 }, /* pbn_b0_bt_2_460800 */
-+
-+ { SPCI_FL_BASE1, 1, 115200 }, /* pbn_b1_1_115200 */
-+ { SPCI_FL_BASE1, 2, 115200 }, /* pbn_b1_2_115200 */
-+ { SPCI_FL_BASE1, 4, 115200 }, /* pbn_b1_4_115200 */
-+ { SPCI_FL_BASE1, 8, 115200 }, /* pbn_b1_8_115200 */
-+
-+ { SPCI_FL_BASE1, 2, 921600 }, /* pbn_b1_2_921600 */
-+ { SPCI_FL_BASE1, 4, 921600 }, /* pbn_b1_4_921600 */
-+ { SPCI_FL_BASE1, 8, 921600 }, /* pbn_b1_8_921600 */
-+
-+ { SPCI_FL_BASE1, 2, 1382400 }, /* pbn_b1_2_1382400 */
-+ { SPCI_FL_BASE1, 4, 1382400 }, /* pbn_b1_4_1382400 */
-+ { SPCI_FL_BASE1, 8, 1382400 }, /* pbn_b1_8_1382400 */
-+
-+ { SPCI_FL_BASE2, 8, 115200 }, /* pbn_b2_8_115200 */
-+ { SPCI_FL_BASE2, 4, 460800 }, /* pbn_b2_4_460800 */
-+ { SPCI_FL_BASE2, 8, 460800 }, /* pbn_b2_8_460800 */
-+ { SPCI_FL_BASE2, 16, 460800 }, /* pbn_b2_16_460800 */
-+ { SPCI_FL_BASE2, 4, 921600 }, /* pbn_b2_4_921600 */
-+ { SPCI_FL_BASE2, 8, 921600 }, /* pbn_b2_8_921600 */
-+
-+ { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 1, 115200 }, /* pbn_b2_bt_1_115200 */
-+ { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 115200 }, /* pbn_b2_bt_2_115200 */
-+ { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 115200 }, /* pbn_b2_bt_4_115200 */
-+ { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600 }, /* pbn_b2_bt_2_921600 */
-+
-+ { SPCI_FL_BASE2, 2, 921600, /* IOMEM */ /* pbn_panacom */
-+ 0x400, 7, pci_plx9050_fn },
-+ { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600, /* pbn_panacom2 */
-+ 0x400, 7, pci_plx9050_fn },
-+ { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 921600, /* pbn_panacom4 */
-+ 0x400, 7, pci_plx9050_fn },
-+ { SPCI_FL_BASE2, 4, 921600, /* pbn_plx_romulus */
-+ 0x20, 2, pci_plx9050_fn, 0x03 },
-+ /* This board uses the size of PCI Base region 0 to
-+ * signal now many ports are available */
-+ { SPCI_FL_BASE0 | SPCI_FL_REGION_SZ_CAP, 32, 115200 }, /* pbn_oxsemi */
-+ { SPCI_FL_BASE_TABLE, 1, 921600, /* pbn_timedia */
-+ 0, 0, pci_timedia_fn },
-+ /* EKF addition for i960 Boards form EKF with serial port */
-+ { SPCI_FL_BASE0, 32, 921600, /* max 256 ports */ /* pbn_intel_i960 */
-+ 8<<2, 2, pci_inteli960ni_fn, 0x10000},
-+ { SPCI_FL_BASE0 | SPCI_FL_IRQRESOURCE, /* pbn_sgi_ioc3 */
-+ 1, 458333, 0, 0, 0, 0x20178 },
-+#ifdef CONFIG_DDB5074
-+ /*
-+ * NEC Vrc-5074 (Nile 4) builtin UART.
-+ * Conditionally compiled in since this is a motherboard device.
-+ */
-+ { SPCI_FL_BASE0, 1, 520833, /* pbn_nec_nile4 */
-+ 64, 3, NULL, 0x300 },
-+#endif
-+#if 0 /* PCI_DEVICE_ID_DCI_PCCOM8 ? */ /* pbn_dci_pccom8 */
-+ { SPCI_FL_BASE3, 8, 115200, 8 },
-+#endif
-+ { SPCI_FL_BASE0, 1, 115200, /* pbn_xircom_combo */
-+ 0, 0, pci_xircom_fn },
-+
-+ { SPCI_FL_BASE2, 1, 460800, /* pbn_siig10x_0 */
-+ 0, 0, pci_siig10x_fn },
-+ { SPCI_FL_BASE2, 1, 921600, /* pbn_siig10x_1 */
-+ 0, 0, pci_siig10x_fn },
-+ { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 2, 921600, /* pbn_siig10x_2 */
-+ 0, 0, pci_siig10x_fn },
-+ { SPCI_FL_BASE2 | SPCI_FL_BASE_TABLE, 4, 921600, /* pbn_siig10x_4 */
-+ 0, 0, pci_siig10x_fn },
-+ { SPCI_FL_BASE0, 1, 921600, /* pbn_siix20x_0 */
-+ 0, 0, pci_siig20x_fn },
-+ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 2, 921600, /* pbn_siix20x_2 */
-+ 0, 0, pci_siig20x_fn },
-+ { SPCI_FL_BASE0 | SPCI_FL_BASE_TABLE, 4, 921600, /* pbn_siix20x_4 */
-+ 0, 0, pci_siig20x_fn },
-+
-+ { SPCI_FL_BASE0, 4, 921600, /* IOMEM */ /* pbn_computone_4 */
-+ 0x40, 2, NULL, 0x200 },
-+ { SPCI_FL_BASE0, 6, 921600, /* IOMEM */ /* pbn_computone_6 */
-+ 0x40, 2, NULL, 0x200 },
-+ { SPCI_FL_BASE0, 8, 921600, /* IOMEM */ /* pbn_computone_8 */
-+ 0x40, 2, NULL, 0x200 },
-+};
-+
-+/*
-+ * Given a complete unknown PCI device, try to use some heuristics to
-+ * guess what the configuration might be, based on the pitiful PCI
-+ * serial specs. Returns 0 on success, 1 on failure.
-+ */
-+static int __devinit serial_pci_guess_board(struct pci_dev *dev,
-+ struct pci_board *board)
-+{
-+ int num_iomem = 0, num_port = 0, first_port = -1;
-+ int i;
-+
-+ /*
-+ * If it is not a communications device or the programming
-+ * interface is greater than 6, give up.
-+ *
-+ * (Should we try to make guesses for multiport serial devices
-+ * later?)
-+ */
-+ if ((((dev->class >> 8) != PCI_CLASS_COMMUNICATION_SERIAL) &&
-+ ((dev->class >> 8) != PCI_CLASS_COMMUNICATION_MODEM)) ||
-+ (dev->class & 0xff) > 6)
-+ return 1;
-+
-+ for (i=0; i < 6; i++) {
-+ if (IS_PCI_REGION_IOPORT(dev, i)) {
-+ num_port++;
-+ if (first_port == -1)
-+ first_port = i;
-+ }
-+ if (IS_PCI_REGION_IOMEM(dev, i))
-+ num_iomem++;
-+ }
-+
-+ /*
-+ * If there is 1 or 0 iomem regions, and exactly one port, use
-+ * it.
-+ */
-+ if (num_iomem <= 1 && num_port == 1) {
-+ board->flags = first_port;
-+ return 0;
-+ }
-+ return 1;
-+}
-+
-+/*
-+ * return -1 to refuse
-+ */
-+static int pci_init_one(struct pci_dev *dev, const struct pci_device_id *ent)
-+{
-+ struct serial_private *priv;
-+ struct pci_board *board, tmp;
-+ struct serial_struct serial_req;
-+ int base_baud, rc, k;
-+
-+ board = &pci_boards[ent->driver_data];
-+
-+ rc = pci_enable_device(dev);
-+ if (rc)
-+ return rc;
-+
-+ if (ent->driver_data == pbn_default &&
-+ serial_pci_guess_board(dev, board))
-+ return -ENODEV;
-+ else if (serial_pci_guess_board(dev, &tmp) == 0) {
-+ printk(KERN_INFO "Redundant entry in serial pci_table. "
-+ "Please send the output of\n"
-+ "lspci -vv, this message (%d,%d,%d,%d)\n"
-+ "and the manufacturer and name of "
-+ "serial board or modem board\n"
-+ "to serial-pci-info@lists.sourceforge.net.\n",
-+ dev->vendor, dev->device,
-+ pci_get_subvendor(dev), pci_get_subdevice(dev));
-+ }
-+
-+
-+ priv = kmalloc(sizeof(struct serial_private) +
-+ sizeof(unsigned int) * board->num_ports,
-+ GFP_KERNEL);
-+ if (!priv)
-+ return -ENOMEM;
-+
-+ /*
-+ * Run the initialization function, if any
-+ */
-+ if (board->init_fn && ((board->init_fn)(dev, board, 1) != 0)) {
-+ kfree(priv);
-+ return -ENODEV;
-+ }
-+
-+ base_baud = board->base_baud;
-+ if (!base_baud)
-+ base_baud = BASE_BAUD;
-+ memset(&serial_req, 0, sizeof(serial_req));
-+ for (k=0; k < board->num_ports; k++) {
-+ serial_req.irq = get_pci_irq(dev, board, k);
-+ if (get_pci_port(dev, board, &serial_req, k))
-+ break;
-+#ifdef SERIAL_DEBUG_PCI
-+ printk("Setup PCI/PNP port: port %x, irq %d, type %d\n",
-+ serial_req.port, serial_req.irq, serial_req.io_type);
-+#endif
-+ serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE;
-+ serial_req.baud_base = base_baud;
-+ priv->line[k] = register_serial(&serial_req);
-+ if (priv->line[k] < 0)
-+ break;
-+ }
-+
-+ priv->board = board;
-+ priv->nr = k;
-+
-+ pci_set_drvdata(dev, priv);
-+
-+ return 0;
-+}
-+
-+static void pci_remove_one(struct pci_dev *dev)
-+{
-+ struct serial_private *priv = pci_get_drvdata(dev);
-+ int i;
-+
-+ pci_set_drvdata(dev, NULL);
-+
-+ for (i = 0; i < priv->nr; i++)
-+ unregister_serial(priv->line[i]);
-+
-+ priv->board->init_fn(dev, priv->board, 0);
-+
-+ kfree(priv);
-+}
-+
-+static struct pci_device_id serial_pci_tbl[] __devinitdata = {
-+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
-+ PCI_SUBVENDOR_ID_CONNECT_TECH,
-+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
-+ pbn_b1_8_1382400 },
-+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
-+ PCI_SUBVENDOR_ID_CONNECT_TECH,
-+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
-+ pbn_b1_4_1382400 },
-+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V960,
-+ PCI_SUBVENDOR_ID_CONNECT_TECH,
-+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0,
-+ pbn_b1_2_1382400 },
-+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-+ PCI_SUBVENDOR_ID_CONNECT_TECH,
-+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232, 0, 0,
-+ pbn_b1_8_1382400 },
-+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-+ PCI_SUBVENDOR_ID_CONNECT_TECH,
-+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232, 0, 0,
-+ pbn_b1_4_1382400 },
-+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-+ PCI_SUBVENDOR_ID_CONNECT_TECH,
-+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232, 0, 0,
-+ pbn_b1_2_1382400 },
-+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-+ PCI_SUBVENDOR_ID_CONNECT_TECH,
-+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485, 0, 0,
-+ pbn_b1_8_921600 },
-+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-+ PCI_SUBVENDOR_ID_CONNECT_TECH,
-+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4, 0, 0,
-+ pbn_b1_8_921600 },
-+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-+ PCI_SUBVENDOR_ID_CONNECT_TECH,
-+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485, 0, 0,
-+ pbn_b1_4_921600 },
-+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-+ PCI_SUBVENDOR_ID_CONNECT_TECH,
-+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2, 0, 0,
-+ pbn_b1_4_921600 },
-+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-+ PCI_SUBVENDOR_ID_CONNECT_TECH,
-+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485, 0, 0,
-+ pbn_b1_2_921600 },
-+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-+ PCI_SUBVENDOR_ID_CONNECT_TECH,
-+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6, 0, 0,
-+ pbn_b1_8_921600 },
-+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-+ PCI_SUBVENDOR_ID_CONNECT_TECH,
-+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1, 0, 0,
-+ pbn_b1_8_921600 },
-+ { PCI_VENDOR_ID_V3, PCI_DEVICE_ID_V3_V351,
-+ PCI_SUBVENDOR_ID_CONNECT_TECH,
-+ PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1, 0, 0,
-+ pbn_b1_4_921600 },
-+
-+ { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_U530,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b2_bt_1_115200 },
-+ { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM2,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b2_bt_2_115200 },
-+ { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM422,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b2_bt_4_115200 },
-+ { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_UCOMM232,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b2_bt_2_115200 },
-+ { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM4,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b2_bt_4_115200 },
-+ { PCI_VENDOR_ID_SEALEVEL, PCI_DEVICE_ID_SEALEVEL_COMM8,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b2_8_115200 },
-+
-+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_GTEK_SERIAL2,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b2_bt_2_115200 },
-+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM200,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b2_bt_2_921600 },
-+ /* VScom SPCOM800, from sl@s.pl */
-+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_SPCOM800,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b2_8_921600 },
-+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_1077,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b2_4_921600 },
-+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-+ PCI_SUBVENDOR_ID_KEYSPAN,
-+ PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0,
-+ pbn_panacom },
-+ { PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_QUADMODEM,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_panacom4 },
-+ { PCI_VENDOR_ID_PANACOM, PCI_DEVICE_ID_PANACOM_DUALMODEM,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_panacom2 },
-+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-+ PCI_SUBVENDOR_ID_CHASE_PCIFAST,
-+ PCI_SUBDEVICE_ID_CHASE_PCIFAST4, 0, 0,
-+ pbn_b2_4_460800 },
-+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-+ PCI_SUBVENDOR_ID_CHASE_PCIFAST,
-+ PCI_SUBDEVICE_ID_CHASE_PCIFAST8, 0, 0,
-+ pbn_b2_8_460800 },
-+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-+ PCI_SUBVENDOR_ID_CHASE_PCIFAST,
-+ PCI_SUBDEVICE_ID_CHASE_PCIFAST16, 0, 0,
-+ pbn_b2_16_460800 },
-+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-+ PCI_SUBVENDOR_ID_CHASE_PCIFAST,
-+ PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC, 0, 0,
-+ pbn_b2_16_460800 },
-+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-+ PCI_SUBVENDOR_ID_CHASE_PCIRAS,
-+ PCI_SUBDEVICE_ID_CHASE_PCIRAS4, 0, 0,
-+ pbn_b2_4_460800 },
-+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
-+ PCI_SUBVENDOR_ID_CHASE_PCIRAS,
-+ PCI_SUBDEVICE_ID_CHASE_PCIRAS8, 0, 0,
-+ pbn_b2_8_460800 },
-+ /* Megawolf Romulus PCI Serial Card, from Mike Hudson */
-+ /* (Exoray@isys.ca) */
-+ { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS,
-+ 0x10b5, 0x106a, 0, 0,
-+ pbn_plx_romulus },
-+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b1_4_115200 },
-+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b1_2_115200 },
-+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b1_8_115200 },
-+ { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b1_8_115200 },
-+ { PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954,
-+ PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4, 0, 0,
-+ pbn_b0_4_921600 },
-+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI954,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b0_4_115200 },
-+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI952,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b0_2_115200 },
-+
-+ /* Digitan DS560-558, from jimd@esoft.com */
-+ { PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_ATT_VENUS_MODEM,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b1_1_115200 },
-+
-+ /* 3Com US Robotics 56k Voice Internal PCI model 5610 */
-+ { PCI_VENDOR_ID_USR, 0x1008,
-+ PCI_ANY_ID, PCI_ANY_ID, },
-+
-+ /* Titan Electronic cards */
-+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b0_1_921600 },
-+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b0_2_921600 },
-+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b0_4_921600 },
-+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800B,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b0_4_921600 },
-+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_100L,
-+ PCI_ANY_ID, PCI_ANY_ID,
-+ SPCI_FL_BASE1, 1, 921600 },
-+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_200L,
-+ PCI_ANY_ID, PCI_ANY_ID,
-+ SPCI_FL_BASE1 | SPCI_FL_BASE_TABLE, 2, 921600 },
-+ /* The 400L and 800L have a custom hack in get_pci_port */
-+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_400L,
-+ PCI_ANY_ID, PCI_ANY_ID,
-+ SPCI_FL_BASE_TABLE, 4, 921600 },
-+ { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_800L,
-+ PCI_ANY_ID, PCI_ANY_ID,
-+ SPCI_FL_BASE_TABLE, 8, 921600 },
-+
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_550,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig10x_0 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_650,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig10x_0 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_10x_850,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig10x_0 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig10x_1 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig10x_1 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig10x_1 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_550,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig10x_2 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_650,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig10x_2 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_10x_850,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig10x_2 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig10x_2 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig10x_2 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig10x_2 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_550,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig10x_4 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_650,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig10x_4 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_10x_850,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig10x_4 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_550,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_0 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_650,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_0 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S_20x_850,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_0 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_0 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_0 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_0 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_0 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_0 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_0 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_550,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_2 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_650,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_2 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S_20x_850,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_2 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_2 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_2 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_2 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_550,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_4 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_650,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_4 },
-+ { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_4S_20x_850,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_siig20x_4 },
-+
-+ /* Computone devices submitted by Doug McNash dmcnash@computone.com */
-+ { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
-+ PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG4,
-+ 0, 0, pbn_computone_4 },
-+ { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
-+ PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG8,
-+ 0, 0, pbn_computone_8 },
-+ { PCI_VENDOR_ID_COMPUTONE, PCI_DEVICE_ID_COMPUTONE_PG,
-+ PCI_SUBVENDOR_ID_COMPUTONE, PCI_SUBDEVICE_ID_COMPUTONE_PG6,
-+ 0, 0, pbn_computone_6 },
-+
-+ { PCI_VENDOR_ID_OXSEMI, PCI_DEVICE_ID_OXSEMI_16PCI95N,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_oxsemi },
-+ { PCI_VENDOR_ID_TIMEDIA, PCI_DEVICE_ID_TIMEDIA_1889,
-+ PCI_VENDOR_ID_TIMEDIA, PCI_ANY_ID, 0, 0, pbn_timedia },
-+
-+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_DSERIAL,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b0_bt_2_115200 },
-+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_A,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b0_bt_2_115200 },
-+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUATRO_B,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b0_bt_2_115200 },
-+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_PLUS,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b0_bt_2_460800 },
-+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_A,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b0_bt_2_460800 },
-+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_QUAD_B,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b0_bt_2_460800 },
-+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_SSERIAL,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b0_bt_1_115200 },
-+ { PCI_VENDOR_ID_LAVA, PCI_DEVICE_ID_LAVA_PORT_650,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b0_bt_1_460800 },
-+
-+ /* RAStel 2 port modem, gerg@moreton.com.au */
-+ { PCI_VENDOR_ID_MORETON, PCI_DEVICE_ID_RASTEL_2PORT,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_b2_bt_2_115200 },
-+
-+ /* EKF addition for i960 Boards form EKF with serial port */
-+ { PCI_VENDOR_ID_INTEL, 0x1960,
-+ 0xE4BF, PCI_ANY_ID, 0, 0,
-+ pbn_intel_i960 },
-+
-+ /* Xircom Cardbus/Ethernet combos */
-+ { PCI_VENDOR_ID_XIRCOM, PCI_DEVICE_ID_XIRCOM_X3201_MDM,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_xircom_combo },
-+
-+ /*
-+ * Untested PCI modems, sent in from various folks...
-+ */
-+
-+ /* Elsa Model 56K PCI Modem, from Andreas Rath <arh@01019freenet.de> */
-+ { PCI_VENDOR_ID_ROCKWELL, 0x1004,
-+ 0x1048, 0x1500, 0, 0,
-+ pbn_b1_1_115200 },
-+
-+ { PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
-+ 0xFF00, 0, 0, 0,
-+ pbn_sgi_ioc3 },
-+
-+#ifdef CONFIG_DDB5074
-+ /*
-+ * NEC Vrc-5074 (Nile 4) builtin UART.
-+ * Conditionally compiled in since this is a motherboard device.
-+ */
-+ { PCI_VENDOR_ID_NEC, PCI_DEVICE_ID_NEC_NILE4,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_nec_nile4 },
-+#endif
-+
-+#if 0 /* PCI_DEVICE_ID_DCI_PCCOM8 ? */
-+ { PCI_VENDOR_ID_DCI, PCI_DEVICE_ID_DCI_PCCOM8,
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
-+ pbn_dci_pccom8 },
-+#endif
-+
-+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
-+ PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xffff00, },
-+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
-+ PCI_CLASS_COMMUNICATION_MODEM << 8, 0xffff00, },
-+ { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
-+ PCI_CLASS_COMMUNICATION_MULTISERIAL << 8, 0xffff00, },
-+ { 0, }
-+};
-+
-+static struct pci_driver serial_pci_driver = {
-+ name: "serial",
-+ probe: pci_init_one,
-+ remove: pci_remove_one,
-+ id_table: serial_pci_tbl,
-+};
-+
-+static int __init serial8250_pci_init(void)
-+{
-+ return pci_module_init(&serial_pci_driver);
-+}
-+
-+static void __exit serial8250_pci_exit(void)
-+{
-+ pci_unregister_driver(&serial_pci_driver);
-+}
-+
-+module_init(serial8250_pci_init);
-+module_exit(serial8250_pci_exit);
-+
-+EXPORT_NO_SYMBOLS;
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("Generic 8250/16x50 PCI serial probe module");
-+MODULE_GENERIC_TABLE(pci, serial_pci_tbl);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/serial/8250_pnp.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,553 @@
-+/*
-+ * linux/drivers/char/serial_8250_pnp.c
-+ *
-+ * Probe module for 8250/16550-type ISAPNP serial ports.
-+ *
-+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
-+ *
-+ * Copyright (C) 2001 Russell King, 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.
-+ *
-+ * $Id$
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/pci.h>
-+#include <linux/isapnp.h>
-+#include <linux/string.h>
-+#include <linux/kernel.h>
-+#include <linux/serial.h>
-+#include <linux/serialP.h>
-+
-+#include <asm/bitops.h>
-+#include <asm/byteorder.h>
-+#include <asm/serial.h>
-+
-+#include "8250.h"
-+
-+static struct serial_state rs_table[] = { };
-+#define NR_PORTS 0
-+
-+struct pnpbios_device_id
-+{
-+ char id[8];
-+ unsigned long driver_data;
-+};
-+
-+static const struct pnpbios_device_id pnp_dev_table[] = {
-+ /* Archtek America Corp. */
-+ /* Archtek SmartLink Modem 3334BT Plug & Play */
-+ { "AAC000F", 0 },
-+ /* Anchor Datacomm BV */
-+ /* SXPro 144 External Data Fax Modem Plug & Play */
-+ { "ADC0001", 0 },
-+ /* SXPro 288 External Data Fax Modem Plug & Play */
-+ { "ADC0002", 0 },
-+ /* Rockwell 56K ACF II Fax+Data+Voice Modem */
-+ { "AKY1021", SPCI_FL_NO_SHIRQ },
-+ /* AZT3005 PnP SOUND DEVICE */
-+ { "AZT4001", 0 },
-+ /* Best Data Products Inc. Smart One 336F PnP Modem */
-+ { "BDP3336", 0 },
-+ /* Boca Research */
-+ /* Boca Complete Ofc Communicator 14.4 Data-FAX */
-+ { "BRI0A49", 0 },
-+ /* Boca Research 33,600 ACF Modem */
-+ { "BRI1400", 0 },
-+ /* Boca 33.6 Kbps Internal FD34FSVD */
-+ { "BRI3400", 0 },
-+ /* Boca 33.6 Kbps Internal FD34FSVD */
-+ { "BRI0A49", 0 },
-+ /* Best Data Products Inc. Smart One 336F PnP Modem */
-+ { "BDP3336", 0 },
-+ /* Computer Peripherals Inc */
-+ /* EuroViVa CommCenter-33.6 SP PnP */
-+ { "CPI4050", 0 },
-+ /* Creative Labs */
-+ /* Creative Labs Phone Blaster 28.8 DSVD PnP Voice */
-+ { "CTL3001", 0 },
-+ /* Creative Labs Modem Blaster 28.8 DSVD PnP Voice */
-+ { "CTL3011", 0 },
-+ /* Creative */
-+ /* Creative Modem Blaster Flash56 DI5601-1 */
-+ { "DMB1032", 0 },
-+ /* Creative Modem Blaster V.90 DI5660 */
-+ { "DMB2001", 0 },
-+ /* FUJITSU */
-+ /* Fujitsu 33600 PnP-I2 R Plug & Play */
-+ { "FUJ0202", 0 },
-+ /* Fujitsu FMV-FX431 Plug & Play */
-+ { "FUJ0205", 0 },
-+ /* Fujitsu 33600 PnP-I4 R Plug & Play */
-+ { "FUJ0206", 0 },
-+ /* Fujitsu Fax Voice 33600 PNP-I5 R Plug & Play */
-+ { "FUJ0209", 0 },
-+ /* Archtek America Corp. */
-+ /* Archtek SmartLink Modem 3334BT Plug & Play */
-+ { "GVC000F", 0 },
-+ /* Hayes */
-+ /* Hayes Optima 288 V.34-V.FC + FAX + Voice Plug & Play */
-+ { "HAY0001", 0 },
-+ /* Hayes Optima 336 V.34 + FAX + Voice PnP */
-+ { "HAY000C", 0 },
-+ /* Hayes Optima 336B V.34 + FAX + Voice PnP */
-+ { "HAY000D", 0 },
-+ /* Hayes Accura 56K Ext Fax Modem PnP */
-+ { "HAY5670", 0 },
-+ /* Hayes Accura 56K Ext Fax Modem PnP */
-+ { "HAY5674", 0 },
-+ /* Hayes Accura 56K Fax Modem PnP */
-+ { "HAY5675", 0 },
-+ /* Hayes 288, V.34 + FAX */
-+ { "HAYF000", 0 },
-+ /* Hayes Optima 288 V.34 + FAX + Voice, Plug & Play */
-+ { "HAYF001", 0 },
-+ /* IBM */
-+ /* IBM Thinkpad 701 Internal Modem Voice */
-+ { "IBM0033", 0 },
-+ /* Intertex */
-+ /* Intertex 28k8 33k6 Voice EXT PnP */
-+ { "IXDC801", 0 },
-+ /* Intertex 33k6 56k Voice EXT PnP */
-+ { "IXDC901", 0 },
-+ /* Intertex 28k8 33k6 Voice SP EXT PnP */
-+ { "IXDD801", 0 },
-+ /* Intertex 33k6 56k Voice SP EXT PnP */
-+ { "IXDD901", 0 },
-+ /* Intertex 28k8 33k6 Voice SP INT PnP */
-+ { "IXDF401", 0 },
-+ /* Intertex 28k8 33k6 Voice SP EXT PnP */
-+ { "IXDF801", 0 },
-+ /* Intertex 33k6 56k Voice SP EXT PnP */
-+ { "IXDF901", 0 },
-+ /* Kortex International */
-+ /* KORTEX 28800 Externe PnP */
-+ { "KOR4522", 0 },
-+ /* KXPro 33.6 Vocal ASVD PnP */
-+ { "KORF661", 0 },
-+ /* Lasat */
-+ /* LASAT Internet 33600 PnP */
-+ { "LAS4040", 0 },
-+ /* Lasat Safire 560 PnP */
-+ { "LAS4540", 0 },
-+ /* Lasat Safire 336 PnP */
-+ { "LAS5440", 0 },
-+ /* Microcom, Inc. */
-+ /* Microcom TravelPorte FAST V.34 Plug & Play */
-+ { "MNP0281", 0 },
-+ /* Microcom DeskPorte V.34 FAST or FAST+ Plug & Play */
-+ { "MNP0336", 0 },
-+ /* Microcom DeskPorte FAST EP 28.8 Plug & Play */
-+ { "MNP0339", 0 },
-+ /* Microcom DeskPorte 28.8P Plug & Play */
-+ { "MNP0342", 0 },
-+ /* Microcom DeskPorte FAST ES 28.8 Plug & Play */
-+ { "MNP0500", 0 },
-+ /* Microcom DeskPorte FAST ES 28.8 Plug & Play */
-+ { "MNP0501", 0 },
-+ /* Microcom DeskPorte 28.8S Internal Plug & Play */
-+ { "MNP0502", 0 },
-+ /* Motorola */
-+ /* Motorola BitSURFR Plug & Play */
-+ { "MOT1105", 0 },
-+ /* Motorola TA210 Plug & Play */
-+ { "MOT1111", 0 },
-+ /* Motorola HMTA 200 (ISDN) Plug & Play */
-+ { "MOT1114", 0 },
-+ /* Motorola BitSURFR Plug & Play */
-+ { "MOT1115", 0 },
-+ /* Motorola Lifestyle 28.8 Internal */
-+ { "MOT1190", 0 },
-+ /* Motorola V.3400 Plug & Play */
-+ { "MOT1501", 0 },
-+ /* Motorola Lifestyle 28.8 V.34 Plug & Play */
-+ { "MOT1502", 0 },
-+ /* Motorola Power 28.8 V.34 Plug & Play */
-+ { "MOT1505", 0 },
-+ /* Motorola ModemSURFR External 28.8 Plug & Play */
-+ { "MOT1509", 0 },
-+ /* Motorola Premier 33.6 Desktop Plug & Play */
-+ { "MOT150A", 0 },
-+ /* Motorola VoiceSURFR 56K External PnP */
-+ { "MOT150F", 0 },
-+ /* Motorola ModemSURFR 56K External PnP */
-+ { "MOT1510", 0 },
-+ /* Motorola ModemSURFR 56K Internal PnP */
-+ { "MOT1550", 0 },
-+ /* Motorola ModemSURFR Internal 28.8 Plug & Play */
-+ { "MOT1560", 0 },
-+ /* Motorola Premier 33.6 Internal Plug & Play */
-+ { "MOT1580", 0 },
-+ /* Motorola OnlineSURFR 28.8 Internal Plug & Play */
-+ { "MOT15B0", 0 },
-+ /* Motorola VoiceSURFR 56K Internal PnP */
-+ { "MOT15F0", 0 },
-+ /* Com 1 */
-+ /* Deskline K56 Phone System PnP */
-+ { "MVX00A1", 0 },
-+ /* PC Rider K56 Phone System PnP */
-+ { "MVX00F2", 0 },
-+ /* Pace 56 Voice Internal Plug & Play Modem */
-+ { "PMC2430", 0 },
-+ /* Generic */
-+ /* Generic standard PC COM port */
-+ { "PNP0500", 0 },
-+ /* Generic 16550A-compatible COM port */
-+ { "PNP0501", 0 },
-+ /* Compaq 14400 Modem */
-+ { "PNPC000", 0 },
-+ /* Compaq 2400/9600 Modem */
-+ { "PNPC001", 0 },
-+ /* Dial-Up Networking Serial Cable between 2 PCs */
-+ { "PNPC031", 0 },
-+ /* Dial-Up Networking Parallel Cable between 2 PCs */
-+ { "PNPC032", 0 },
-+ /* Standard 9600 bps Modem */
-+ { "PNPC100", 0 },
-+ /* Standard 14400 bps Modem */
-+ { "PNPC101", 0 },
-+ /* Standard 28800 bps Modem*/
-+ { "PNPC102", 0 },
-+ /* Standard Modem*/
-+ { "PNPC103", 0 },
-+ /* Standard 9600 bps Modem*/
-+ { "PNPC104", 0 },
-+ /* Standard 14400 bps Modem*/
-+ { "PNPC105", 0 },
-+ /* Standard 28800 bps Modem*/
-+ { "PNPC106", 0 },
-+ /* Standard Modem */
-+ { "PNPC107", 0 },
-+ /* Standard 9600 bps Modem */
-+ { "PNPC108", 0 },
-+ /* Standard 14400 bps Modem */
-+ { "PNPC109", 0 },
-+ /* Standard 28800 bps Modem */
-+ { "PNPC10A", 0 },
-+ /* Standard Modem */
-+ { "PNPC10B", 0 },
-+ /* Standard 9600 bps Modem */
-+ { "PNPC10C", 0 },
-+ /* Standard 14400 bps Modem */
-+ { "PNPC10D", 0 },
-+ /* Standard 28800 bps Modem */
-+ { "PNPC10E", 0 },
-+ /* Standard Modem */
-+ { "PNPC10F", 0 },
-+ /* Standard PCMCIA Card Modem */
-+ { "PNP2000", 0 },
-+ /* Rockwell */
-+ /* Modular Technology */
-+ /* Rockwell 33.6 DPF Internal PnP */
-+ /* Modular Technology 33.6 Internal PnP */
-+ { "ROK0030", 0 },
-+ /* Kortex International */
-+ /* KORTEX 14400 Externe PnP */
-+ { "ROK0100", 0 },
-+ /* Viking Components, Inc */
-+ /* Viking 28.8 INTERNAL Fax+Data+Voice PnP */
-+ { "ROK4920", 0 },
-+ /* Rockwell */
-+ /* British Telecom */
-+ /* Modular Technology */
-+ /* Rockwell 33.6 DPF External PnP */
-+ /* BT Prologue 33.6 External PnP */
-+ /* Modular Technology 33.6 External PnP */
-+ { "RSS00A0", 0 },
-+ /* Viking 56K FAX INT */
-+ { "RSS0262", 0 },
-+ /* SupraExpress 28.8 Data/Fax PnP modem */
-+ { "SUP1310", 0 },
-+ /* SupraExpress 33.6 Data/Fax PnP modem */
-+ { "SUP1421", 0 },
-+ /* SupraExpress 33.6 Data/Fax PnP modem */
-+ { "SUP1590", 0 },
-+ /* SupraExpress 33.6 Data/Fax PnP modem */
-+ { "SUP1760", 0 },
-+ /* Phoebe Micro */
-+ /* Phoebe Micro 33.6 Data Fax 1433VQH Plug & Play */
-+ { "TEX0011", 0 },
-+ /* Archtek America Corp. */
-+ /* Archtek SmartLink Modem 3334BT Plug & Play */
-+ { "UAC000F", 0 },
-+ /* 3Com Corp. */
-+ /* Gateway Telepath IIvi 33.6 */
-+ { "USR0000", 0 },
-+ /* Sportster Vi 14.4 PnP FAX Voicemail */
-+ { "USR0004", 0 },
-+ /* U.S. Robotics 33.6K Voice INT PnP */
-+ { "USR0006", 0 },
-+ /* U.S. Robotics 33.6K Voice EXT PnP */
-+ { "USR0007", 0 },
-+ /* U.S. Robotics 33.6K Voice INT PnP */
-+ { "USR2002", 0 },
-+ /* U.S. Robotics 56K Voice INT PnP */
-+ { "USR2070", 0 },
-+ /* U.S. Robotics 56K Voice EXT PnP */
-+ { "USR2080", 0 },
-+ /* U.S. Robotics 56K FAX INT */
-+ { "USR3031", 0 },
-+ /* U.S. Robotics 56K Voice INT PnP */
-+ { "USR3070", 0 },
-+ /* U.S. Robotics 56K Voice EXT PnP */
-+ { "USR3080", 0 },
-+ /* U.S. Robotics 56K Voice INT PnP */
-+ { "USR3090", 0 },
-+ /* U.S. Robotics 56K Message */
-+ { "USR9100", 0 },
-+ /* U.S. Robotics 56K FAX EXT PnP*/
-+ { "USR9160", 0 },
-+ /* U.S. Robotics 56K FAX INT PnP*/
-+ { "USR9170", 0 },
-+ /* U.S. Robotics 56K Voice EXT PnP*/
-+ { "USR9180", 0 },
-+ /* U.S. Robotics 56K Voice INT PnP*/
-+ { "USR9190", 0 },
-+ { "", 0 }
-+};
-+
-+static void inline avoid_irq_share(struct pci_dev *dev)
-+{
-+ int i, map = 0x1FF8;
-+ struct serial_state *state = rs_table;
-+ struct isapnp_irq *irq;
-+ struct isapnp_resources *res = dev->sysdata;
-+
-+ for (i = 0; i < NR_PORTS; i++) {
-+ if (state->type != PORT_UNKNOWN)
-+ clear_bit(state->irq, &map);
-+ state++;
-+ }
-+
-+ for ( ; res; res = res->alt)
-+ for(irq = res->irq; irq; irq = irq->next)
-+ irq->map = map;
-+}
-+
-+static char *modem_names[] __devinitdata = {
-+ "MODEM", "Modem", "modem", "FAX", "Fax", "fax",
-+ "56K", "56k", "K56", "33.6", "28.8", "14.4",
-+ "33,600", "28,800", "14,400", "33.600", "28.800", "14.400",
-+ "33600", "28800", "14400", "V.90", "V.34", "V.32", 0
-+};
-+
-+static int __devinit check_name(char *name)
-+{
-+ char **tmp;
-+
-+ for (tmp = modem_names; *tmp; tmp++)
-+ if (strstr(name, *tmp))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+static int inline check_compatible_id(struct pci_dev *dev)
-+{
-+ int i;
-+ for (i = 0; i < DEVICE_COUNT_COMPATIBLE; i++)
-+ if ((dev->vendor_compatible[i] ==
-+ ISAPNP_VENDOR('P', 'N', 'P')) &&
-+ (swab16(dev->device_compatible[i]) >= 0xc000) &&
-+ (swab16(dev->device_compatible[i]) <= 0xdfff))
-+ return 0;
-+ return 1;
-+}
-+
-+/*
-+ * Given a complete unknown ISA PnP device, try to use some heuristics to
-+ * detect modems. Currently use such heuristic set:
-+ * - dev->name or dev->bus->name must contain "modem" substring;
-+ * - device must have only one IO region (8 byte long) with base adress
-+ * 0x2e8, 0x3e8, 0x2f8 or 0x3f8.
-+ *
-+ * Such detection looks very ugly, but can detect at least some of numerous
-+ * ISA PnP modems, alternatively we must hardcode all modems in pnp_devices[]
-+ * table.
-+ */
-+static int serial_pnp_guess_board(struct pci_dev *dev, int *flags)
-+{
-+ struct isapnp_resources *res = (struct isapnp_resources *)dev->sysdata;
-+ struct isapnp_resources *resa;
-+
-+ if (!(check_name(dev->name) || check_name(dev->bus->name)) &&
-+ !(check_compatible_id(dev)))
-+ return -ENODEV;
-+
-+ if (!res || res->next)
-+ return -ENODEV;
-+
-+ for (resa = res->alt; resa; resa = resa->alt) {
-+ struct isapnp_port *port;
-+ for (port = res->port; port; port = port->next)
-+ if ((port->size == 8) &&
-+ ((port->min == 0x2f8) ||
-+ (port->min == 0x3f8) ||
-+ (port->min == 0x2e8) ||
-+ (port->min == 0x3e8)))
-+ return 0;
-+ }
-+
-+ return -ENODEV;
-+}
-+
-+static int
-+pnp_init_one(struct pci_dev *dev, const struct pnpbios_device_id *ent,
-+ char *slot_name)
-+{
-+ struct serial_struct serial_req;
-+ int ret, line, flags = ent ? ent->driver_data : 0;
-+
-+ if (!ent) {
-+ ret = serial_pnp_guess_board(dev, &flags);
-+ if (ret)
-+ return ret;
-+ }
-+
-+ if (dev->prepare(dev) < 0) {
-+ printk("serial: PNP device '%s' prepare failed\n",
-+ slot_name);
-+ return -ENODEV;
-+ }
-+
-+ if (dev->active)
-+ return -ENODEV;
-+
-+ if (flags & SPCI_FL_NO_SHIRQ)
-+ avoid_irq_share(dev);
-+
-+ if (dev->activate(dev) < 0) {
-+ printk("serial: PNP device '%s' activate failed\n",
-+ slot_name);
-+ return -ENODEV;
-+ }
-+
-+ memset(&serial_req, 0, sizeof(serial_req));
-+ serial_req.irq = dev->irq_resource[0].start;
-+ serial_req.port = pci_resource_start(dev, 0);
-+ if (HIGH_BITS_OFFSET)
-+ serial_req.port = pci_resource_start(dev, 0) >> HIGH_BITS_OFFSET;
-+
-+#ifdef SERIAL_DEBUG_PCI
-+ printk("Setup PCI/PNP port: port %x, irq %d, type %d\n",
-+ serial_req.port, serial_req.irq, serial_req.io_type);
-+#endif
-+
-+ serial_req.flags = ASYNC_SKIP_TEST | ASYNC_AUTOPROBE;
-+ serial_req.baud_base = 115200;
-+ line = register_serial(&serial_req);
-+
-+ if (line >= 0) {
-+ pci_set_drvdata(dev, (void *)(line + 1));
-+
-+ /*
-+ * Public health warning: remove this once the 2.5
-+ * pnpbios_module_init() stuff is incorporated.
-+ */
-+ dev->driver = (void *)pnp_dev_table;
-+ } else
-+ dev->deactivate(dev);
-+
-+ return line >= 0 ? 0 : -ENODEV;
-+}
-+
-+static void pnp_remove_one(struct pci_dev *dev)
-+{
-+ int line = (int)pci_get_drvdata(dev);
-+
-+ if (line) {
-+ pci_set_drvdata(dev, NULL);
-+
-+ unregister_serial(line - 1);
-+
-+ dev->deactivate(dev);
-+ }
-+}
-+
-+static char hex[] = "0123456789ABCDEF";
-+
-+/*
-+ * This function should vanish when 2.5 comes around and
-+ * we have pnpbios_module_init()
-+ */
-+static void pnp_init(void)
-+{
-+ const struct pnpbios_device_id *id;
-+ struct pci_dev *dev = NULL;
-+
-+#ifdef SERIAL_DEBUG_PNP
-+ printk("Entered probe_serial_pnp()\n");
-+#endif
-+
-+ isapnp_for_each_dev(dev) {
-+ char slot_name[8];
-+ u32 pnpid;
-+
-+ if (dev->active)
-+ continue;
-+
-+ pnpid = dev->vendor << 16 | dev->device;
-+ pnpid = cpu_to_le32(pnpid);
-+
-+#define HEX(id,a) hex[((id)>>a) & 15]
-+#define CHAR(id,a) (0x40 + (((id)>>a) & 31))
-+ slot_name[0] = CHAR(pnpid, 26);
-+ slot_name[1] = CHAR(pnpid, 21);
-+ slot_name[2] = CHAR(pnpid, 16);
-+ slot_name[3] = HEX(pnpid, 12);
-+ slot_name[4] = HEX(pnpid, 8);
-+ slot_name[5] = HEX(pnpid, 4);
-+ slot_name[6] = HEX(pnpid, 0);
-+ slot_name[7] = '\0';
-+
-+ for (id = pnp_dev_table; id->id[0]; id++)
-+ if (memcmp(id->id, slot_name, 7) == 0)
-+ break;
-+
-+ if (id->id[0])
-+ pnp_init_one(dev, id, slot_name);
-+ else
-+ pnp_init_one(dev, NULL, slot_name);
-+ }
-+
-+#ifdef SERIAL_DEBUG_PNP
-+ printk("Leaving probe_serial_pnp() (probe finished)\n");
-+#endif
-+}
-+
-+static int __init serial8250_pnp_init(void)
-+{
-+ if (!isapnp_present()) {
-+#ifdef SERIAL_DEBUG_PNP
-+ printk("Leaving probe_serial_pnp() (no isapnp)\n");
-+#endif
-+ return -ENODEV;
-+ }
-+ pnp_init();
-+ return 0;
-+}
-+
-+static void __exit serial8250_pnp_exit(void)
-+{
-+ struct pci_dev *dev = NULL;
-+
-+ isapnp_for_each_dev(dev) {
-+ if (dev->driver != (void *)pnp_dev_table)
-+ continue;
-+ pnp_remove_one(dev);
-+ }
-+}
-+
-+module_init(serial8250_pnp_init);
-+module_exit(serial8250_pnp_exit);
-+
-+EXPORT_NO_SYMBOLS;
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("Generic 8250/16x50 PNPBIOS serial probe module");
-+MODULE_GENERIC_TABLE(pnp, pnp_dev_table);
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/serial/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,91 @@
-+#
-+# Serial device configuration
-+#
-+# $Id$
-+#
-+mainmenu_option next_comment
-+comment 'Serial drivers'
-+
-+if [ "$CONFIG_ARM" = "y" ]; then
-+ # I don't have this in my tree yet.
-+ dep_bool 'Anakin serial port support' CONFIG_SERIAL_ANAKIN $CONFIG_ARCH_ANAKIN
-+ dep_bool ' Console on Anakin serial port' CONFIG_SERIAL_ANAKIN_CONSOLE $CONFIG_SERIAL_ANAKIN
-+ if [ "$CONFIG_SERIAL_ANAKIN" = "y" ]; then
-+ int ' Default Anakin serial baudrate' CONFIG_ANAKIN_DEFAULT_BAUDRATE 9600
-+ fi
-+
-+ dep_tristate 'ARM AMBA serial port support' CONFIG_SERIAL_AMBA $CONFIG_ARCH_INTEGRATOR
-+ dep_bool ' Support for console on AMBA serial port' CONFIG_SERIAL_AMBA_CONSOLE $CONFIG_SERIAL_AMBA
-+ if [ "$CONFIG_SERIAL_AMBA" = "y" ]; then
-+ define_bool CONFIG_SERIAL_INTEGRATOR y
-+ fi
-+
-+ dep_tristate 'CLPS711X serial port support' CONFIG_SERIAL_CLPS711X $CONFIG_ARCH_CLPS711X
-+ dep_bool ' Support for console on CLPS711X serial port' CONFIG_SERIAL_CLPS711X_CONSOLE $CONFIG_SERIAL_CLPS711X
-+
-+ dep_bool 'DC21285 serial port support' CONFIG_SERIAL_21285 $CONFIG_FOOTBRIDGE
-+ dep_bool ' Use /dev/ttyS0 device (OBSOLETE)' CONFIG_SERIAL_21285_OLD $CONFIG_SERIAL_21285 $CONFIG_OBSOLETE
-+ dep_bool ' Console on DC21285 serial port' CONFIG_SERIAL_21285_CONSOLE $CONFIG_SERIAL_21285
-+
-+ dep_bool 'Excalibur serial port (uart00) support' CONFIG_SERIAL_UART00 $CONFIG_ARCH_CAMELOT
-+ dep_bool ' Support for console on Excalibur serial port' CONFIG_SERIAL_UART00_CONSOLE $CONFIG_SERIAL_UART00
-+
-+
-+ dep_bool 'SA1100 serial port support' CONFIG_SERIAL_SA1100 $CONFIG_ARCH_SA1100
-+ dep_bool ' Console on SA1100 serial port' CONFIG_SERIAL_SA1100_CONSOLE $CONFIG_SERIAL_SA1100
-+ if [ "$CONFIG_SERIAL_SA1100" = "y" ]; then
-+ int ' Default SA1100 serial baudrate' CONFIG_SA1100_DEFAULT_BAUDRATE 9600
-+ fi
-+
-+ dep_tristate 'ARM Omaha serial port support' CONFIG_SERIAL_OMAHA $CONFIG_ARCH_OMAHA
-+ dep_bool ' Support for console on Omaha serial port' CONFIG_SERIAL_OMAHA_CONSOLE $CONFIG_SERIAL_OMAHA
-+
-+ dep_tristate 'AT91RM9200 serial port support' CONFIG_SERIAL_AT91 $CONFIG_ARCH_AT91RM9200
-+ dep_bool ' Console on AT91RM9200 serial port' CONFIG_SERIAL_AT91_CONSOLE $CONFIG_SERIAL_AT91
-+
-+fi
-+#
-+# The new 8250/16550 serial drivers
-+dep_tristate '8250/16550 and compatible serial support (EXPERIMENTAL)' CONFIG_SERIAL_8250 $CONFIG_EXPERIMENTAL
-+dep_bool ' Console on 8250/16550 and compatible serial port (EXPERIMENTAL)' CONFIG_SERIAL_8250_CONSOLE $CONFIG_SERIAL_8250 $CONFIG_EXPERIMENTAL
-+
-+dep_mbool 'Extended 8250/16550 serial driver options' CONFIG_SERIAL_8250_EXTENDED $CONFIG_SERIAL_8250
-+dep_bool ' Support more than 4 serial ports' CONFIG_SERIAL_8250_MANY_PORTS $CONFIG_SERIAL_8250_EXTENDED
-+dep_bool ' Support for sharing serial interrupts' CONFIG_SERIAL_8250_SHARE_IRQ $CONFIG_SERIAL_8250_EXTENDED
-+dep_bool ' Autodetect IRQ on standard ports (unsafe)' CONFIG_SERIAL_8250_DETECT_IRQ $CONFIG_SERIAL_8250_EXTENDED
-+dep_bool ' Support special multiport boards' CONFIG_SERIAL_8250_MULTIPORT $CONFIG_SERIAL_8250_EXTENDED
-+dep_bool ' Support Bell Technologies HUB6 card' CONFIG_SERIAL_8250_HUB6 $CONFIG_SERIAL_8250_EXTENDED
-+
-+if [ "$CONFIG_SERIAL_AMBA" = "y" -o \
-+ "$CONFIG_SERIAL_CLPS711X" = "y" -o \
-+ "$CONFIG_SERIAL_SA1100" = "y" -o \
-+ "$CONFIG_SERIAL_ANAKIN" = "y" -o \
-+ "$CONFIG_SERIAL_UART00" = "y" -o \
-+ "$CONFIG_SERIAL_8250" = "y" -o \
-+ "$CONFIG_SERIAL_OMAHA" = "y" -o \
-+ "$CONFIG_SERIAL_AT91" = "y" ]; then
-+ define_bool CONFIG_SERIAL_CORE y
-+else
-+ if [ "$CONFIG_SERIAL_AMBA" = "m" -o \
-+ "$CONFIG_SERIAL_CLPS711X" = "m" -o \
-+ "$CONFIG_SERIAL_SA1100" = "m" -o \
-+ "$CONFIG_SERIAL_ANAKIN" = "m" -o \
-+ "$CONFIG_SERIAL_UART00" = "m" -o \
-+ "$CONFIG_SERIAL_8250" = "m" -o \
-+ "$CONFIG_SERIAL_OMAHA" = "m" -o \
-+ "$CONFIG_SERIAL_AT91" = "m" ]; then
-+ define_bool CONFIG_SERIAL_CORE m
-+ fi
-+fi
-+if [ "$CONFIG_SERIAL_AMBA_CONSOLE" = "y" -o \
-+ "$CONFIG_SERIAL_CLPS711X_CONSOLE" = "y" -o \
-+ "$CONFIG_SERIAL_SA1100_CONSOLE" = "y" -o \
-+ "$CONFIG_SERIAL_ANAKIN_CONSOLE" = "y" -o \
-+ "$CONFIG_SERIAL_UART00_CONSOLE" = "y" -o \
-+ "$CONFIG_SERIAL_8250_CONSOLE" = "y" -o \
-+ "$CONFIG_SERIAL_OMAHA" = "y" -o \
-+ "$CONFIG_SERIAL_AT91_CONSOLE" = "y" ]; then
-+ define_bool CONFIG_SERIAL_CORE_CONSOLE y
-+fi
-+
-+endmenu
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/serial/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,39 @@
-+#
-+# Makefile for the kernel serial device drivers.
-+#
-+# Note! Dependencies are done automagically by 'make dep', which also
-+# removes any old dependencies. DON'T put your own dependencies here
-+# unless it's something special (ie not a .c file).
-+#
-+# Note 2! The CFLAGS definitions are now inherited from the
-+# parent makes..
-+#
-+# $Id$
-+#
-+
-+O_TARGET := serial.o
-+
-+export-objs := core.o 8250.o
-+obj-y :=
-+obj-m :=
-+obj-n :=
-+obj- :=
-+
-+serial-8250-y :=
-+serial-8250-$(CONFIG_PCI) += 8250_pci.o
-+serial-8250-$(CONFIG_ISAPNP) += 8250_pnp.o
-+obj-$(CONFIG_SERIAL_CORE) += core.o
-+obj-$(CONFIG_SERIAL_21285) += 21285.o
-+obj-$(CONFIG_SERIAL_8250) += 8250.o $(serial-8250-y)
-+obj-$(CONFIG_SERIAL_ANAKIN) += anakin.o
-+obj-$(CONFIG_SERIAL_AMBA) += amba.o
-+obj-$(CONFIG_SERIAL_CLPS711X) += clps711x.o
-+obj-$(CONFIG_SERIAL_SA1100) += sa1100.o
-+obj-$(CONFIG_SERIAL_UART00) += uart00.o
-+obj-$(CONFIG_SERIAL_OMAHA) += omaha.o
-+obj-$(CONFIG_SERIAL_AT91US3) += at91us3.o
-+
-+include $(TOPDIR)/Rules.make
-+
-+fastdep:
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/serial/amba.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,770 @@
-+/*
-+ * linux/drivers/char/serial_amba.c
-+ *
-+ * Driver for AMBA serial ports
-+ *
-+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
-+ *
-+ * Copyright 1999 ARM Limited
-+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * $Id$
-+ *
-+ * This is a generic driver for ARM AMBA-type serial ports. They
-+ * have a lot of 16550-like features, but are not register compatable.
-+ * Note that although they do have CTS, DCD and DSR inputs, they do
-+ * not have an RI input, nor do they have DTR or RTS outputs. If
-+ * required, these have to be supplied via some other means (eg, GPIO)
-+ * and hooked into this driver.
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/tty.h>
-+#include <linux/ioport.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/serial.h>
-+#include <linux/console.h>
-+#include <linux/sysrq.h>
-+
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+
-+#if defined(CONFIG_SERIAL_AMBA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-+#define SUPPORT_SYSRQ
-+#endif
-+
-+#include <linux/serial_core.h>
-+
-+#include <asm/hardware/serial_amba.h>
-+
-+#define UART_NR 2
-+
-+#define SERIAL_AMBA_MAJOR 204
-+#define SERIAL_AMBA_MINOR 16
-+#define SERIAL_AMBA_NR UART_NR
-+
-+#define CALLOUT_AMBA_NAME "cuaam"
-+#define CALLOUT_AMBA_MAJOR 205
-+#define CALLOUT_AMBA_MINOR 16
-+#define CALLOUT_AMBA_NR UART_NR
-+
-+static struct tty_driver normal, callout;
-+static struct tty_struct *amba_table[UART_NR];
-+static struct termios *amba_termios[UART_NR], *amba_termios_locked[UART_NR];
-+#ifdef SUPPORT_SYSRQ
-+static struct console amba_console;
-+#endif
-+
-+#define AMBA_ISR_PASS_LIMIT 256
-+
-+/*
-+ * Access macros for the AMBA UARTs
-+ */
-+#define UART_GET_INT_STATUS(p) readb((p)->membase + AMBA_UARTIIR)
-+#define UART_PUT_ICR(p, c) writel((c), (p)->membase + AMBA_UARTICR)
-+#define UART_GET_FR(p) readb((p)->membase + AMBA_UARTFR)
-+#define UART_GET_CHAR(p) readb((p)->membase + AMBA_UARTDR)
-+#define UART_PUT_CHAR(p, c) writel((c), (p)->membase + AMBA_UARTDR)
-+#define UART_GET_RSR(p) readb((p)->membase + AMBA_UARTRSR)
-+#define UART_GET_CR(p) readb((p)->membase + AMBA_UARTCR)
-+#define UART_PUT_CR(p,c) writel((c), (p)->membase + AMBA_UARTCR)
-+#define UART_GET_LCRL(p) readb((p)->membase + AMBA_UARTLCR_L)
-+#define UART_PUT_LCRL(p,c) writel((c), (p)->membase + AMBA_UARTLCR_L)
-+#define UART_GET_LCRM(p) readb((p)->membase + AMBA_UARTLCR_M)
-+#define UART_PUT_LCRM(p,c) writel((c), (p)->membase + AMBA_UARTLCR_M)
-+#define UART_GET_LCRH(p) readb((p)->membase + AMBA_UARTLCR_H)
-+#define UART_PUT_LCRH(p,c) writel((c), (p)->membase + AMBA_UARTLCR_H)
-+#define UART_RX_DATA(s) (((s) & AMBA_UARTFR_RXFE) == 0)
-+#define UART_TX_READY(s) (((s) & AMBA_UARTFR_TXFF) == 0)
-+#define UART_TX_EMPTY(p) ((UART_GET_FR(p) & AMBA_UARTFR_TMSK) == 0)
-+
-+#define UART_DUMMY_RSR_RX 256
-+#define UART_PORT_SIZE 64
-+
-+/*
-+ * On the Integrator platform, the port RTS and DTR are provided by
-+ * bits in the following SC_CTRLS register bits:
-+ * RTS DTR
-+ * UART0 7 6
-+ * UART1 5 4
-+ */
-+#define SC_CTRLC (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
-+#define SC_CTRLS (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
-+
-+/*
-+ * We wrap our port structure around the generic uart_port.
-+ */
-+struct uart_amba_port {
-+ struct uart_port port;
-+ unsigned int dtr_mask;
-+ unsigned int rts_mask;
-+ unsigned int old_status;
-+};
-+
-+static void ambauart_stop_tx(struct uart_port *port, unsigned int tty_stop)
-+{
-+ unsigned int cr;
-+
-+ cr = UART_GET_CR(port);
-+ cr &= ~AMBA_UARTCR_TIE;
-+ UART_PUT_CR(port, cr);
-+}
-+
-+static void ambauart_start_tx(struct uart_port *port, unsigned int tty_start)
-+{
-+ unsigned int cr;
-+
-+ cr = UART_GET_CR(port);
-+ cr |= AMBA_UARTCR_TIE;
-+ UART_PUT_CR(port, cr);
-+}
-+
-+static void ambauart_stop_rx(struct uart_port *port)
-+{
-+ unsigned int cr;
-+
-+ cr = UART_GET_CR(port);
-+ cr &= ~(AMBA_UARTCR_RIE | AMBA_UARTCR_RTIE);
-+ UART_PUT_CR(port, cr);
-+}
-+
-+static void ambauart_enable_ms(struct uart_port *port)
-+{
-+ unsigned int cr;
-+
-+ cr = UART_GET_CR(port);
-+ cr |= AMBA_UARTCR_MSIE;
-+ UART_PUT_CR(port, cr);
-+}
-+
-+static void
-+#ifdef SUPPORT_SYSRQ
-+ambauart_rx_chars(struct uart_port *port, struct pt_regs *regs)
-+#else
-+ambauart_rx_chars(struct uart_port *port)
-+#endif
-+{
-+ struct tty_struct *tty = port->info->tty;
-+ unsigned int status, ch, rsr, max_count = 256;
-+
-+ status = UART_GET_FR(port);
-+ while (UART_RX_DATA(status) && max_count--) {
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-+ tty->flip.tqueue.routine((void *)tty);
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-+ printk(KERN_WARNING "TTY_DONT_FLIP set\n");
-+ return;
-+ }
-+ }
-+
-+ ch = UART_GET_CHAR(port);
-+
-+ *tty->flip.char_buf_ptr = ch;
-+ *tty->flip.flag_buf_ptr = TTY_NORMAL;
-+ port->icount.rx++;
-+
-+ /*
-+ * Note that the error handling code is
-+ * out of the main execution path
-+ */
-+ rsr = UART_GET_RSR(port) | UART_DUMMY_RSR_RX;
-+ if (rsr & AMBA_UARTRSR_ANY) {
-+ if (rsr & AMBA_UARTRSR_BE) {
-+ rsr &= ~(AMBA_UARTRSR_FE | AMBA_UARTRSR_PE);
-+ port->icount.brk++;
-+ if (uart_handle_break(port))
-+ goto ignore_char;
-+ } else if (rsr & AMBA_UARTRSR_PE)
-+ port->icount.parity++;
-+ else if (rsr & AMBA_UARTRSR_FE)
-+ port->icount.frame++;
-+ if (rsr & AMBA_UARTRSR_OE)
-+ port->icount.overrun++;
-+
-+ rsr &= port->read_status_mask;
-+
-+ if (rsr & AMBA_UARTRSR_BE)
-+ *tty->flip.flag_buf_ptr = TTY_BREAK;
-+ else if (rsr & AMBA_UARTRSR_PE)
-+ *tty->flip.flag_buf_ptr = TTY_PARITY;
-+ else if (rsr & AMBA_UARTRSR_FE)
-+ *tty->flip.flag_buf_ptr = TTY_FRAME;
-+ }
-+
-+ if (uart_handle_sysrq_char(port, ch, regs))
-+ goto ignore_char;
-+
-+ if ((rsr & port->ignore_status_mask) == 0) {
-+ tty->flip.flag_buf_ptr++;
-+ tty->flip.char_buf_ptr++;
-+ tty->flip.count++;
-+ }
-+ if ((rsr & AMBA_UARTRSR_OE) &&
-+ tty->flip.count < TTY_FLIPBUF_SIZE) {
-+ /*
-+ * Overrun is special, since it's reported
-+ * immediately, and doesn't affect the current
-+ * character
-+ */
-+ *tty->flip.char_buf_ptr++ = 0;
-+ *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
-+ tty->flip.count++;
-+ }
-+ ignore_char:
-+ status = UART_GET_FR(port);
-+ }
-+ tty_flip_buffer_push(tty);
-+ return;
-+}
-+
-+static void ambauart_tx_chars(struct uart_port *port)
-+{
-+ struct circ_buf *xmit = &port->info->xmit;
-+ int count;
-+
-+ if (port->x_char) {
-+ UART_PUT_CHAR(port, port->x_char);
-+ port->icount.tx++;
-+ port->x_char = 0;
-+ return;
-+ }
-+ if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
-+ ambauart_stop_tx(port, 0);
-+ return;
-+ }
-+
-+ count = port->fifosize >> 1;
-+ do {
-+ UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
-+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-+ port->icount.tx++;
-+ if (uart_circ_empty(xmit))
-+ break;
-+ } while (--count > 0);
-+
-+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-+ uart_write_wakeup(port);
-+
-+ if (uart_circ_empty(xmit))
-+ ambauart_stop_tx(port, 0);
-+}
-+
-+static void ambauart_modem_status(struct uart_port *port)
-+{
-+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
-+ unsigned int status, delta;
-+
-+ UART_PUT_ICR(&uap->port, 0);
-+
-+ status = UART_GET_FR(&uap->port) & AMBA_UARTFR_MODEM_ANY;
-+
-+ delta = status ^ uap->old_status;
-+ uap->old_status = status;
-+
-+ if (!delta)
-+ return;
-+
-+ if (delta & AMBA_UARTFR_DCD)
-+ uart_handle_dcd_change(&uap->port, status & AMBA_UARTFR_DCD);
-+
-+ if (delta & AMBA_UARTFR_DSR)
-+ uap->port.icount.dsr++;
-+
-+ if (delta & AMBA_UARTFR_CTS)
-+ uart_handle_cts_change(&uap->port, status & AMBA_UARTFR_CTS);
-+
-+ wake_up_interruptible(&uap->port.info->delta_msr_wait);
-+}
-+
-+static void ambauart_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct uart_port *port = dev_id;
-+ unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
-+
-+ status = UART_GET_INT_STATUS(port);
-+ do {
-+ if (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS))
-+#ifdef SUPPORT_SYSRQ
-+ ambauart_rx_chars(port, regs);
-+#else
-+ ambauart_rx_chars(port);
-+#endif
-+ if (status & AMBA_UARTIIR_TIS)
-+ ambauart_tx_chars(port);
-+ if (status & AMBA_UARTIIR_MIS)
-+ ambauart_modem_status(port);
-+
-+ if (pass_counter-- == 0)
-+ break;
-+
-+ status = UART_GET_INT_STATUS(port);
-+ } while (status & (AMBA_UARTIIR_RTIS | AMBA_UARTIIR_RIS |
-+ AMBA_UARTIIR_TIS));
-+}
-+
-+static unsigned int ambauart_tx_empty(struct uart_port *port)
-+{
-+ return UART_GET_FR(port) & AMBA_UARTFR_BUSY ? 0 : TIOCSER_TEMT;
-+}
-+
-+static unsigned int ambauart_get_mctrl(struct uart_port *port)
-+{
-+ unsigned int result = 0;
-+ unsigned int status;
-+
-+ status = UART_GET_FR(port);
-+ if (status & AMBA_UARTFR_DCD)
-+ result |= TIOCM_CAR;
-+ if (status & AMBA_UARTFR_DSR)
-+ result |= TIOCM_DSR;
-+ if (status & AMBA_UARTFR_CTS)
-+ result |= TIOCM_CTS;
-+
-+ return result;
-+}
-+
-+static void ambauart_set_mctrl(struct uart_port *port, unsigned int mctrl)
-+{
-+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
-+ unsigned int ctrls = 0, ctrlc = 0;
-+
-+ if (mctrl & TIOCM_RTS)
-+ ctrlc |= uap->rts_mask;
-+ else
-+ ctrls |= uap->rts_mask;
-+
-+ if (mctrl & TIOCM_DTR)
-+ ctrlc |= uap->dtr_mask;
-+ else
-+ ctrls |= uap->dtr_mask;
-+
-+ __raw_writel(ctrls, SC_CTRLS);
-+ __raw_writel(ctrlc, SC_CTRLC);
-+}
-+
-+static void ambauart_break_ctl(struct uart_port *port, int break_state)
-+{
-+ unsigned long flags;
-+ unsigned int lcr_h;
-+
-+ spin_lock_irqsave(&port->lock, flags);
-+ lcr_h = UART_GET_LCRH(port);
-+ if (break_state == -1)
-+ lcr_h |= AMBA_UARTLCR_H_BRK;
-+ else
-+ lcr_h &= ~AMBA_UARTLCR_H_BRK;
-+ UART_PUT_LCRH(port, lcr_h);
-+ spin_unlock_irqrestore(&port->lock, flags);
-+}
-+
-+static int ambauart_startup(struct uart_port *port)
-+{
-+ struct uart_amba_port *uap = (struct uart_amba_port *)port;
-+ int retval;
-+
-+ /*
-+ * Allocate the IRQ
-+ */
-+ retval = request_irq(port->irq, ambauart_int, 0, "amba", port);
-+ if (retval)
-+ return retval;
-+
-+ /*
-+ * initialise the old status of the modem signals
-+ */
-+ uap->old_status = UART_GET_FR(port) & AMBA_UARTFR_MODEM_ANY;
-+
-+ /*
-+ * Finally, enable interrupts
-+ */
-+ UART_PUT_CR(port, AMBA_UARTCR_UARTEN | AMBA_UARTCR_RIE |
-+ AMBA_UARTCR_RTIE);
-+
-+ return 0;
-+}
-+
-+static void ambauart_shutdown(struct uart_port *port)
-+{
-+ /*
-+ * Free the interrupt
-+ */
-+ free_irq(port->irq, port);
-+
-+ /*
-+ * disable all interrupts, disable the port
-+ */
-+ UART_PUT_CR(port, 0);
-+
-+ /* disable break condition and fifos */
-+ UART_PUT_LCRH(port, UART_GET_LCRH(port) &
-+ ~(AMBA_UARTLCR_H_BRK | AMBA_UARTLCR_H_FEN));
-+}
-+
-+static void ambauart_change_speed(struct uart_port *port, unsigned int cflag, unsigned int iflag, unsigned int quot)
-+{
-+ unsigned int lcr_h, old_cr;
-+ unsigned long flags;
-+
-+#if DEBUG
-+ printk("ambauart_set_cflag(0x%x) called\n", cflag);
-+#endif
-+ /* byte size and parity */
-+ switch (cflag & CSIZE) {
-+ case CS5:
-+ lcr_h = AMBA_UARTLCR_H_WLEN_5;
-+ break;
-+ case CS6:
-+ lcr_h = AMBA_UARTLCR_H_WLEN_6;
-+ break;
-+ case CS7:
-+ lcr_h = AMBA_UARTLCR_H_WLEN_7;
-+ break;
-+ default: // CS8
-+ lcr_h = AMBA_UARTLCR_H_WLEN_8;
-+ break;
-+ }
-+ if (cflag & CSTOPB)
-+ lcr_h |= AMBA_UARTLCR_H_STP2;
-+ if (cflag & PARENB) {
-+ lcr_h |= AMBA_UARTLCR_H_PEN;
-+ if (!(cflag & PARODD))
-+ lcr_h |= AMBA_UARTLCR_H_EPS;
-+ }
-+ if (port->fifosize > 1)
-+ lcr_h |= AMBA_UARTLCR_H_FEN;
-+
-+ spin_lock_irqsave(&port->lock, flags);
-+
-+ port->read_status_mask = AMBA_UARTRSR_OE;
-+ if (iflag & INPCK)
-+ port->read_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;
-+ if (iflag & (BRKINT | PARMRK))
-+ port->read_status_mask |= AMBA_UARTRSR_BE;
-+
-+ /*
-+ * Characters to ignore
-+ */
-+ port->ignore_status_mask = 0;
-+ if (iflag & IGNPAR)
-+ port->ignore_status_mask |= AMBA_UARTRSR_FE | AMBA_UARTRSR_PE;
-+ if (iflag & IGNBRK) {
-+ port->ignore_status_mask |= AMBA_UARTRSR_BE;
-+ /*
-+ * If we're ignoring parity and break indicators,
-+ * ignore overruns too (for real raw support).
-+ */
-+ if (iflag & IGNPAR)
-+ port->ignore_status_mask |= AMBA_UARTRSR_OE;
-+ }
-+
-+ /*
-+ * Ignore all characters if CREAD is not set.
-+ */
-+ if ((cflag & CREAD) == 0)
-+ port->ignore_status_mask |= UART_DUMMY_RSR_RX;
-+
-+ old_cr = UART_GET_CR(port) & ~AMBA_UARTCR_MSIE;
-+
-+ if (UART_ENABLE_MS(port, cflag))
-+ old_cr |= AMBA_UARTCR_MSIE;
-+
-+ UART_PUT_CR(port, 0);
-+
-+ /* Set baud rate */
-+ quot -= 1;
-+ UART_PUT_LCRM(port, ((quot & 0xf00) >> 8));
-+ UART_PUT_LCRL(port, (quot & 0xff));
-+
-+ /*
-+ * ----------v----------v----------v----------v-----
-+ * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
-+ * ----------^----------^----------^----------^-----
-+ */
-+ UART_PUT_LCRH(port, lcr_h);
-+ UART_PUT_CR(port, old_cr);
-+
-+ spin_unlock_irqrestore(&port->lock, flags);
-+}
-+
-+static const char *ambauart_type(struct uart_port *port)
-+{
-+ return port->type == PORT_AMBA ? "AMBA" : NULL;
-+}
-+
-+/*
-+ * Release the memory region(s) being used by 'port'
-+ */
-+static void ambauart_release_port(struct uart_port *port)
-+{
-+ release_mem_region(port->mapbase, UART_PORT_SIZE);
-+}
-+
-+/*
-+ * Request the memory region(s) being used by 'port'
-+ */
-+static int ambauart_request_port(struct uart_port *port)
-+{
-+ return request_mem_region(port->mapbase, UART_PORT_SIZE, "serial_amba")
-+ != NULL ? 0 : -EBUSY;
-+}
-+
-+/*
-+ * Configure/autoconfigure the port.
-+ */
-+static void ambauart_config_port(struct uart_port *port, int flags)
-+{
-+ if (flags & UART_CONFIG_TYPE) {
-+ port->type = PORT_AMBA;
-+ ambauart_request_port(port);
-+ }
-+}
-+
-+/*
-+ * verify the new serial_struct (for TIOCSSERIAL).
-+ */
-+static int ambauart_verify_port(struct uart_port *port, struct serial_struct *ser)
-+{
-+ int ret = 0;
-+ if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)
-+ ret = -EINVAL;
-+ if (ser->irq < 0 || ser->irq >= NR_IRQS)
-+ ret = -EINVAL;
-+ if (ser->baud_base < 9600)
-+ ret = -EINVAL;
-+ return ret;
-+}
-+
-+static struct uart_ops amba_pops = {
-+ .tx_empty = ambauart_tx_empty,
-+ .set_mctrl = ambauart_set_mctrl,
-+ .get_mctrl = ambauart_get_mctrl,
-+ .stop_tx = ambauart_stop_tx,
-+ .start_tx = ambauart_start_tx,
-+ .stop_rx = ambauart_stop_rx,
-+ .enable_ms = ambauart_enable_ms,
-+ .break_ctl = ambauart_break_ctl,
-+ .startup = ambauart_startup,
-+ .shutdown = ambauart_shutdown,
-+ .change_speed = ambauart_change_speed,
-+ .type = ambauart_type,
-+ .release_port = ambauart_release_port,
-+ .request_port = ambauart_request_port,
-+ .config_port = ambauart_config_port,
-+ .verify_port = ambauart_verify_port,
-+};
-+
-+static struct uart_amba_port amba_ports[UART_NR] = {
-+ {
-+ .port = {
-+ .membase = (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE),
-+ .mapbase = INTEGRATOR_UART0_BASE,
-+ .iotype = SERIAL_IO_MEM,
-+ .irq = IRQ_UARTINT0,
-+ .uartclk = 14745600,
-+ .fifosize = 16,
-+ .ops = &amba_pops,
-+ .flags = ASYNC_BOOT_AUTOCONF,
-+ .line = 0,
-+ },
-+ .dtr_mask = 1 << 5,
-+ .rts_mask = 1 << 4,
-+ },
-+ {
-+ .port = {
-+ .membase = (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE),
-+ .mapbase = INTEGRATOR_UART1_BASE,
-+ .iotype = SERIAL_IO_MEM,
-+ .irq = IRQ_UARTINT1,
-+ .uartclk = 14745600,
-+ .fifosize = 16,
-+ .ops = &amba_pops,
-+ .flags = ASYNC_BOOT_AUTOCONF,
-+ .line = 1,
-+ },
-+ .dtr_mask = 1 << 7,
-+ .rts_mask = 1 << 6,
-+ }
-+};
-+
-+#ifdef CONFIG_SERIAL_AMBA_CONSOLE
-+
-+static void ambauart_console_write(struct console *co, const char *s, unsigned int count)
-+{
-+ struct uart_port *port = &amba_ports[co->index].port;
-+ unsigned int status, old_cr;
-+ int i;
-+
-+ /*
-+ * First save the CR then disable the interrupts
-+ */
-+ old_cr = UART_GET_CR(port);
-+ UART_PUT_CR(port, AMBA_UARTCR_UARTEN);
-+
-+ /*
-+ * Now, do each character
-+ */
-+ for (i = 0; i < count; i++) {
-+ do {
-+ status = UART_GET_FR(port);
-+ } while (!UART_TX_READY(status));
-+ UART_PUT_CHAR(port, s[i]);
-+ if (s[i] == '\n') {
-+ do {
-+ status = UART_GET_FR(port);
-+ } while (!UART_TX_READY(status));
-+ UART_PUT_CHAR(port, '\r');
-+ }
-+ }
-+
-+ /*
-+ * Finally, wait for transmitter to become empty
-+ * and restore the TCR
-+ */
-+ do {
-+ status = UART_GET_FR(port);
-+ } while (status & AMBA_UARTFR_BUSY);
-+ UART_PUT_CR(port, old_cr);
-+}
-+
-+static kdev_t ambauart_console_device(struct console *co)
-+{
-+ return MKDEV(SERIAL_AMBA_MAJOR, SERIAL_AMBA_MINOR + co->index);
-+}
-+
-+static void __init
-+ambauart_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
-+{
-+ if (UART_GET_CR(port) & AMBA_UARTCR_UARTEN) {
-+ unsigned int lcr_h, quot;
-+ lcr_h = UART_GET_LCRH(port);
-+
-+ *parity = 'n';
-+ if (lcr_h & AMBA_UARTLCR_H_PEN) {
-+ if (lcr_h & AMBA_UARTLCR_H_EPS)
-+ *parity = 'e';
-+ else
-+ *parity = 'o';
-+ }
-+
-+ if ((lcr_h & 0x60) == AMBA_UARTLCR_H_WLEN_7)
-+ *bits = 7;
-+ else
-+ *bits = 8;
-+
-+ quot = UART_GET_LCRL(port) | UART_GET_LCRM(port) << 8;
-+ *baud = port->uartclk / (16 * (quot + 1));
-+ }
-+}
-+
-+static int __init ambauart_console_setup(struct console *co, char *options)
-+{
-+ struct uart_port *port;
-+ int baud = 38400;
-+ int bits = 8;
-+ int parity = 'n';
-+ int flow = 'n';
-+
-+ /*
-+ * Check whether an invalid uart number has been specified, and
-+ * if so, search for the first available port that does have
-+ * console support.
-+ */
-+ if (co->index >= UART_NR)
-+ co->index = 0;
-+ port = &amba_ports[co->index].port;
-+
-+ if (options)
-+ uart_parse_options(options, &baud, &parity, &bits, &flow);
-+ else
-+ ambauart_console_get_options(port, &baud, &parity, &bits);
-+
-+ return uart_set_options(port, co, baud, parity, bits, flow);
-+}
-+
-+static struct console amba_console = {
-+ .name = "ttyAM",
-+ .write = ambauart_console_write,
-+ .device = ambauart_console_device,
-+ .setup = ambauart_console_setup,
-+ .flags = CON_PRINTBUFFER,
-+ .index = -1,
-+};
-+
-+void __init ambauart_console_init(void)
-+{
-+ register_console(&amba_console);
-+}
-+
-+#define AMBA_CONSOLE &amba_console
-+#else
-+#define AMBA_CONSOLE NULL
-+#endif
-+
-+static struct uart_driver amba_reg = {
-+ .owner = THIS_MODULE,
-+ .normal_major = SERIAL_AMBA_MAJOR,
-+#ifdef CONFIG_DEVFS_FS
-+ .normal_name = "ttyAM%d",
-+ .callout_name = "cuaam%d",
-+#else
-+ .normal_name = "ttyAM",
-+ .callout_name = "cuaam",
-+#endif
-+ .normal_driver = &normal,
-+ .callout_major = CALLOUT_AMBA_MAJOR,
-+ .callout_driver = &callout,
-+ .table = amba_table,
-+ .termios = amba_termios,
-+ .termios_locked = amba_termios_locked,
-+ .minor = SERIAL_AMBA_MINOR,
-+ .nr = UART_NR,
-+ .cons = AMBA_CONSOLE,
-+};
-+
-+static int __init ambauart_init(void)
-+{
-+ int ret;
-+
-+ ret = uart_register_driver(&amba_reg);
-+ if (ret == 0) {
-+ int i;
-+
-+ for (i = 0; i < UART_NR; i++)
-+ uart_add_one_port(&amba_reg, &amba_ports[i].port);
-+ }
-+ return ret;
-+}
-+
-+static void __exit ambauart_exit(void)
-+{
-+ int i;
-+
-+ for (i = 0; i < UART_NR; i++)
-+ uart_remove_one_port(&amba_reg, &amba_ports[i].port);
-+
-+ uart_unregister_driver(&amba_reg);
-+}
-+
-+module_init(ambauart_init);
-+module_exit(ambauart_exit);
-+
-+EXPORT_NO_SYMBOLS;
-+
-+MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd");
-+MODULE_DESCRIPTION("ARM AMBA serial port driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/serial/anakin.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,545 @@
-+/*
-+ * linux/drivers/char/serial_anakin.c
-+ *
-+ * Based on driver for AMBA serial ports, by ARM Limited,
-+ * Deep Blue Solutions Ltd., Linus Torvalds and Theodore Ts'o.
-+ *
-+ * Copyright (C) 2001 Aleph One Ltd. for Acunia N.V.
-+ *
-+ * Copyright (C) 2001 Blue Mug, Inc. for Acunia N.V.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Changelog:
-+ * 20-Apr-2001 TTC Created
-+ * 05-May-2001 W/TTC Updated for serial_core.c
-+ * 27-Jun-2001 jonm Minor changes; add mctrl support, switch to
-+ * SA_INTERRUPT. Works reliably now. No longer requires
-+ * changes to the serial_core API.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/tty.h>
-+#include <linux/tty_flip.h>
-+#include <linux/major.h>
-+#include <linux/string.h>
-+#include <linux/fcntl.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/circ_buf.h>
-+#include <linux/serial.h>
-+#include <linux/console.h>
-+#include <linux/sysrq.h>
-+
-+#include <asm/system.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+#include <asm/bitops.h>
-+
-+#include <linux/serial_core.h>
-+
-+#include <asm/arch/serial_reg.h>
-+
-+#define UART_NR 5
-+
-+#define SERIAL_ANAKIN_NAME "ttyAN"
-+#define SERIAL_ANAKIN_MAJOR 204
-+#define SERIAL_ANAKIN_MINOR 32
-+
-+#define CALLOUT_ANAKIN_NAME "cuaan"
-+#define CALLOUT_ANAKIN_MAJOR 205
-+#define CALLOUT_ANAKIN_MINOR 32
-+
-+static struct tty_driver normal, callout;
-+static struct tty_struct *anakin_table[UART_NR];
-+static struct termios *anakin_termios[UART_NR], *anakin_termios_locked[UART_NR];
-+static struct uart_state anakin_state[UART_NR];
-+static u_int txenable[NR_IRQS]; /* Software interrupt register */
-+
-+static inline unsigned int
-+anakin_in(struct uart_port *port, u_int offset)
-+{
-+ return __raw_readl(port->base + offset);
-+}
-+
-+static inline void
-+anakin_out(struct uart_port *port, u_int offset, unsigned int value)
-+{
-+ __raw_writel(value, port->base + offset);
-+}
-+
-+static void
-+anakin_stop_tx(struct uart_port *port, u_int from_tty)
-+{
-+ txenable[port->irq] = 0;
-+}
-+
-+static inline void
-+anakin_transmit_buffer(struct uart_info *info)
-+{
-+ struct uart_port *port = info->port;
-+
-+ while (!(anakin_in(port, 0x10) & TXEMPTY));
-+ anakin_out(port, 0x14, info->xmit.buf[info->xmit.tail]);
-+ anakin_out(port, 0x18, anakin_in(port, 0x18) | SENDREQUEST);
-+ info->xmit.tail = (info->xmit.tail + 1) & (UART_XMIT_SIZE-1);
-+ info->state->icount.tx++;
-+
-+ if (info->xmit.head == info->xmit.tail)
-+ anakin_stop_tx(port, 0);
-+}
-+
-+static inline void
-+anakin_transmit_x_char(struct uart_info *info)
-+{
-+ struct uart_port *port = info->port;
-+
-+ anakin_out(port, 0x14, info->x_char);
-+ anakin_out(port, 0x18, anakin_in(port, 0x18) | SENDREQUEST);
-+ info->state->icount.tx++;
-+ info->x_char = 0;
-+}
-+
-+static void
-+anakin_start_tx(struct uart_port *port, u_int nonempty, u_int from_tty)
-+{
-+ unsigned int flags;
-+
-+ save_flags_cli(flags);
-+
-+ // is it this... or below: if (nonempty
-+ if (!txenable[port->irq]) {
-+ txenable[port->irq] = TXENABLE;
-+
-+ if ((anakin_in(port, 0x10) & TXEMPTY) && nonempty) {
-+ anakin_transmit_buffer((struct uart_info*)port->unused);
-+ }
-+ }
-+
-+ restore_flags(flags);
-+}
-+
-+static void
-+anakin_stop_rx(struct uart_port *port)
-+{
-+ unsigned long flags;
-+
-+ save_flags_cli(flags);
-+ while (anakin_in(port, 0x10) & RXRELEASE)
-+ anakin_in(port, 0x14);
-+ anakin_out(port, 0x18, anakin_in(port, 0x18) | BLOCKRX);
-+ restore_flags(flags);
-+}
-+
-+static void
-+anakin_enable_ms(struct uart_port *port)
-+{
-+}
-+
-+static inline void
-+anakin_rx_chars(struct uart_info *info)
-+{
-+ unsigned int ch;
-+ struct tty_struct *tty = info->tty;
-+
-+ if (!(anakin_in(info->port, 0x10) & RXRELEASE))
-+ return;
-+
-+ ch = anakin_in(info->port, 0x14) & 0xff;
-+
-+ if (tty->flip.count < TTY_FLIPBUF_SIZE) {
-+ *tty->flip.char_buf_ptr++ = ch;
-+ *tty->flip.flag_buf_ptr++ = TTY_NORMAL;
-+ info->state->icount.rx++;
-+ tty->flip.count++;
-+ }
-+ tty_flip_buffer_push(tty);
-+}
-+
-+static inline void
-+anakin_overrun_chars(struct uart_info *info)
-+{
-+ unsigned int ch;
-+
-+ ch = anakin_in(info->port, 0x14);
-+ info->state->icount.overrun++;
-+}
-+
-+static inline void
-+anakin_tx_chars(struct uart_info *info)
-+{
-+ if (info->x_char) {
-+ anakin_transmit_x_char(info);
-+ return;
-+ }
-+
-+ if (info->xmit.head == info->xmit.tail
-+ || info->tty->stopped
-+ || info->tty->hw_stopped) {
-+ anakin_stop_tx(info->port, 0);
-+ return;
-+ }
-+
-+ anakin_transmit_buffer(info);
-+
-+ if (CIRC_CNT(info->xmit.head,
-+ info->xmit.tail,
-+ UART_XMIT_SIZE) < WAKEUP_CHARS)
-+ uart_event(info, EVT_WRITE_WAKEUP);
-+}
-+
-+static void
-+anakin_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ unsigned int status;
-+ struct uart_info *info = dev_id;
-+
-+ status = anakin_in(info->port, 0x1c);
-+
-+ if (status & RX)
-+ anakin_rx_chars(info);
-+
-+ if (status & OVERRUN)
-+ anakin_overrun_chars(info);
-+
-+ if (txenable[info->port->irq] && (status & TX))
-+ anakin_tx_chars(info);
-+}
-+
-+static u_int
-+anakin_tx_empty(struct uart_port *port)
-+{
-+ return anakin_in(port, 0x10) & TXEMPTY ? TIOCSER_TEMT : 0;
-+}
-+
-+static u_int
-+anakin_get_mctrl(struct uart_port *port)
-+{
-+ unsigned int status = 0;
-+
-+ status |= (anakin_in(port, 0x10) & CTS ? TIOCM_CTS : 0);
-+ status |= (anakin_in(port, 0x18) & DCD ? TIOCM_CAR : 0);
-+ status |= (anakin_in(port, 0x18) & DTR ? TIOCM_DTR : 0);
-+ status |= (anakin_in(port, 0x18) & RTS ? TIOCM_RTS : 0);
-+
-+ return status;
-+}
-+
-+static void
-+anakin_set_mctrl(struct uart_port *port, u_int mctrl)
-+{
-+ unsigned int status;
-+
-+ status = anakin_in(port, 0x18);
-+
-+ if (mctrl & TIOCM_RTS)
-+ status |= RTS;
-+ else
-+ status &= ~RTS;
-+
-+ if (mctrl & TIOCM_CAR)
-+ status |= DCD;
-+ else
-+ status &= ~DCD;
-+
-+ anakin_out(port, 0x18, status);
-+}
-+
-+static void
-+anakin_break_ctl(struct uart_port *port, int break_state)
-+{
-+ unsigned int status;
-+
-+ status = anakin_in(port, 0x20);
-+
-+ if (break_state == -1)
-+ status |= SETBREAK;
-+ else
-+ status &= ~SETBREAK;
-+
-+ anakin_out(port, 0x20, status);
-+}
-+
-+static int
-+anakin_startup(struct uart_port *port, struct uart_info *info)
-+{
-+ int retval;
-+ unsigned int read,write;
-+
-+ /*
-+ * Allocate the IRQ
-+ */
-+ retval = request_irq(port->irq, anakin_int, SA_INTERRUPT, "serial_anakin", info);
-+ if (retval)
-+ return retval;
-+
-+ port->ops->set_mctrl(port, info->mctrl);
-+
-+ /*
-+ * initialise the old status of the modem signals
-+ */
-+ port->old_status = 0;
-+
-+ /*
-+ * Finally, disable IRQ and softIRQs for first byte)
-+ */
-+ txenable[port->irq] = 0;
-+ read = anakin_in(port, 0x18);
-+ write = (read & ~(RTS | DTR | BLOCKRX)) | IRQENABLE;
-+ anakin_out(port, 0x18, write);
-+
-+ /* Store the uart_info pointer so we can reference it in
-+ * anakin_start_tx() */
-+ port->unused = (u_int)info;
-+
-+ return 0;
-+}
-+
-+static void
-+anakin_shutdown(struct uart_port *port, struct uart_info *info)
-+{
-+ /*
-+ * Free the interrupt
-+ */
-+ free_irq(port->irq, info);
-+
-+ /*
-+ * disable all interrupts, disable the port
-+ */
-+ anakin_out(port, 0x18, anakin_in(port, 0x18) & ~IRQENABLE);
-+}
-+
-+static void
-+anakin_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot)
-+{
-+ unsigned int flags;
-+
-+ save_flags_cli(flags);
-+ while (!(anakin_in(port, 0x10) & TXEMPTY));
-+ anakin_out(port, 0x10, (anakin_in(port, 0x10) & ~PRESCALER)
-+ | (quot << 3));
-+
-+ //parity always set to none
-+ anakin_out(port, 0x18, anakin_in(port, 0x18) & ~PARITY);
-+ restore_flags(flags);
-+}
-+
-+static const char *anakin_type(struct port *port)
-+{
-+ return port->type == PORT_ANAKIN ? "ANAKIN" : NULL;
-+}
-+
-+static struct uart_ops anakin_pops = {
-+ tx_empty: anakin_tx_empty,
-+ set_mctrl: anakin_set_mctrl,
-+ get_mctrl: anakin_get_mctrl,
-+ stop_tx: anakin_stop_tx,
-+ start_tx: anakin_start_tx,
-+ stop_rx: anakin_stop_rx,
-+ enable_ms: anakin_enable_ms,
-+ break_ctl: anakin_break_ctl,
-+ startup: anakin_startup,
-+ shutdown: anakin_shutdown,
-+ change_speed: anakin_change_speed,
-+ type: anakin_type,
-+};
-+
-+static struct uart_port anakin_ports[UART_NR] = {
-+ {
-+ base: IO_BASE + UART0,
-+ irq: IRQ_UART0,
-+ uartclk: 3686400,
-+ fifosize: 0,
-+ ops: &anakin_pops,
-+ },
-+ {
-+ base: IO_BASE + UART1,
-+ irq: IRQ_UART1,
-+ uartclk: 3686400,
-+ fifosize: 0,
-+ ops: &anakin_pops,
-+ },
-+ {
-+ base: IO_BASE + UART2,
-+ irq: IRQ_UART2,
-+ uartclk: 3686400,
-+ fifosize: 0,
-+ ops: &anakin_pops,
-+ },
-+ {
-+ base: IO_BASE + UART3,
-+ irq: IRQ_UART3,
-+ uartclk: 3686400,
-+ fifosize: 0,
-+ ops: &anakin_pops,
-+ },
-+ {
-+ base: IO_BASE + UART4,
-+ irq: IRQ_UART4,
-+ uartclk: 3686400,
-+ fifosize: 0,
-+ ops: &anakin_pops,
-+ },
-+};
-+
-+
-+#ifdef CONFIG_SERIAL_ANAKIN_CONSOLE
-+
-+static void
-+anakin_console_write(struct console *co, const char *s, u_int count)
-+{
-+ struct uart_port *port = anakin_ports + co->index;
-+ unsigned int flags, status, i;
-+
-+ /*
-+ * First save the status then disable the interrupts
-+ */
-+ save_flags_cli(flags);
-+ status = anakin_in(port, 0x18);
-+ anakin_out(port, 0x18, status & ~IRQENABLE);
-+ restore_flags(flags);
-+
-+ /*
-+ * Now, do each character
-+ */
-+ for (i = 0; i < count; i++, s++) {
-+ while (!(anakin_in(port, 0x10) & TXEMPTY));
-+
-+ /*
-+ * Send the character out.
-+ * If a LF, also do CR...
-+ */
-+ anakin_out(port, 0x14, *s);
-+ anakin_out(port, 0x18, anakin_in(port, 0x18) | SENDREQUEST);
-+
-+ if (*s == 10) {
-+ while (!(anakin_in(port, 0x10) & TXEMPTY));
-+ anakin_out(port, 0x14, 13);
-+ anakin_out(port, 0x18, anakin_in(port, 0x18)
-+ | SENDREQUEST);
-+ }
-+ }
-+
-+ /*
-+ * Finally, wait for transmitter to become empty
-+ * and restore the interrupts
-+ */
-+ while (!(anakin_in(port, 0x10) & TXEMPTY));
-+
-+ if (status & IRQENABLE)
-+ save_flags_cli(flags);
-+ anakin_out(port, 0x18, anakin_in(port, 0x18) | IRQENABLE);
-+ restore_flags(flags);
-+}
-+
-+static kdev_t
-+anakin_console_device(struct console *co)
-+{
-+ return MKDEV(SERIAL_ANAKIN_MAJOR, SERIAL_ANAKIN_MINOR + co->index);
-+}
-+
-+/*
-+ * Read the current UART setup.
-+ */
-+static void __init
-+anakin_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
-+{
-+ int paritycode;
-+
-+ *baud = GETBAUD (anakin_in(port, 0x10) & PRESCALER);
-+ paritycode = GETPARITY(anakin_in(port, 0x18) & PARITY);
-+ switch (paritycode) {
-+ case NONEPARITY: *parity = 'n'; break;
-+ case ODDPARITY: *parity = 'o'; break;
-+ case EVENPARITY: *parity = 'e'; break;
-+ }
-+ *bits = 8;
-+}
-+
-+static int __init
-+anakin_console_setup(struct console *co, char *options)
-+{
-+ struct uart_port *port;
-+ int baud = CONFIG_ANAKIN_DEFAULT_BAUDRATE;
-+ int bits = 8;
-+ int parity = 'n';
-+
-+ /*
-+ * Check whether an invalid uart number has been specified, and
-+ * if so, search for the first available port that does have
-+ * console support.
-+ */
-+ port = uart_get_console(anakin_ports, UART_NR, co);
-+
-+ if (options)
-+ uart_parse_options(options, &baud, &parity, &bits);
-+ else
-+ anakin_console_get_options(port, &baud, &parity, &bits);
-+
-+ return uart_set_options(port, co, baud, parity, bits);
-+}
-+
-+static struct console anakin_console = {
-+ name: SERIAL_ANAKIN_NAME,
-+ write: anakin_console_write,
-+ device: anakin_console_device,
-+ setup: anakin_console_setup,
-+ flags: CON_PRINTBUFFER,
-+ index: -1,
-+};
-+
-+void __init
-+anakin_console_init(void)
-+{
-+ register_console(&anakin_console);
-+}
-+
-+#define ANAKIN_CONSOLE &anakin_console
-+#else
-+#define ANAKIN_CONSOLE NULL
-+#endif
-+
-+static struct uart_register anakin_reg = {
-+ normal_major: SERIAL_ANAKIN_MAJOR,
-+ normal_name: SERIAL_ANAKIN_NAME,
-+ normal_driver: &normal,
-+ callout_major: CALLOUT_ANAKIN_MAJOR,
-+ callout_name: CALLOUT_ANAKIN_NAME,
-+ callout_driver: &callout,
-+ table: anakin_table,
-+ termios: anakin_termios,
-+ termios_locked: anakin_termios_locked,
-+ minor: SERIAL_ANAKIN_MINOR,
-+ nr: UART_NR,
-+ state: anakin_state,
-+ port: anakin_ports,
-+ cons: ANAKIN_CONSOLE,
-+};
-+
-+static int __init
-+anakin_init(void)
-+{
-+ return uart_register_port(&anakin_reg);
-+}
-+
-+__initcall(anakin_init);
-+
-+MODULE_DESCRIPTION("Anakin serial driver");
-+MODULE_AUTHOR("Tak-Shing Chan <chan@aleph1.co.uk>");
-+MODULE_SUPPORTED_DEVICE("ttyAN");
-+MODULE_LICENSE("GPL");
-+
-+EXPORT_NO_SYMBOLS;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/serial/clps711x.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,635 @@
-+/*
-+ * linux/drivers/char/serial_clps711x.c
-+ *
-+ * Driver for CLPS711x serial ports
-+ *
-+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
-+ *
-+ * Copyright 1999 ARM Limited
-+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * $Id$
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/tty.h>
-+#include <linux/tty_flip.h>
-+#include <linux/major.h>
-+#include <linux/string.h>
-+#include <linux/fcntl.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/circ_buf.h>
-+#include <linux/serial.h>
-+#include <linux/console.h>
-+#include <linux/sysrq.h>
-+
-+#include <asm/bitops.h>
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include <linux/serial_core.h>
-+
-+#include <asm/hardware/clps7111.h>
-+
-+#define UART_NR 2
-+
-+#define SERIAL_CLPS711X_NAME "ttyAM"
-+#define SERIAL_CLPS711X_MAJOR 204
-+#define SERIAL_CLPS711X_MINOR 16
-+#define SERIAL_CLPS711X_NR UART_NR
-+
-+#define CALLOUT_CLPS711X_NAME "cuaam"
-+#define CALLOUT_CLPS711X_MAJOR 205
-+#define CALLOUT_CLPS711X_MINOR 16
-+#define CALLOUT_CLPS711X_NR UART_NR
-+
-+static struct tty_driver normal, callout;
-+static struct tty_struct *clps711x_table[UART_NR];
-+static struct termios *clps711x_termios[UART_NR], *clps711x_termios_locked[UART_NR];
-+
-+/*
-+ * We use the relevant SYSCON register as a base address for these ports.
-+ */
-+#define UBRLCR(port) ((port)->iobase + UBRLCR1 - SYSCON1)
-+#define UARTDR(port) ((port)->iobase + UARTDR1 - SYSCON1)
-+#define SYSFLG(port) ((port)->iobase + SYSFLG1 - SYSCON1)
-+#define SYSCON(port) ((port)->iobase + SYSCON1 - SYSCON1)
-+
-+#define TX_IRQ(port) ((port)->irq)
-+#define RX_IRQ(port) ((port)->irq + 1)
-+
-+#define UART_ANY_ERR (UARTDR_FRMERR | UARTDR_PARERR | UARTDR_OVERR)
-+
-+#define tx_enabled(port) ((port)->unused[0])
-+
-+static void
-+clps711xuart_stop_tx(struct uart_port *port, unsigned int tty_stop)
-+{
-+ if (tx_enabled(port)) {
-+ disable_irq(TX_IRQ(port));
-+ tx_enabled(port) = 0;
-+ }
-+}
-+
-+static void
-+clps711xuart_start_tx(struct uart_port *port, unsigned int tty_start)
-+{
-+ if (!tx_enabled(port)) {
-+ enable_irq(TX_IRQ(port));
-+ tx_enabled(port) = 1;
-+ }
-+}
-+
-+static void clps711xuart_stop_rx(struct uart_port *port)
-+{
-+ disable_irq(RX_IRQ(port));
-+}
-+
-+static void clps711xuart_enable_ms(struct uart_port *port)
-+{
-+}
-+
-+static void clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct uart_port *port = dev_id;
-+ struct tty_struct *tty = port->info->tty;
-+ unsigned int status, ch, flg, ignored = 0;
-+
-+ status = clps_readl(SYSFLG(port));
-+ while (!(status & SYSFLG_URXFE)) {
-+ ch = clps_readl(UARTDR(port));
-+
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+ goto ignore_char;
-+ port->icount.rx++;
-+
-+ flg = TTY_NORMAL;
-+
-+ /*
-+ * Note that the error handling code is
-+ * out of the main execution path
-+ */
-+ if (ch & UART_ANY_ERR)
-+ goto handle_error;
-+
-+ if (uart_handle_sysrq_char(port, ch, regs))
-+ goto ignore_char;
-+
-+ error_return:
-+ *tty->flip.flag_buf_ptr++ = flg;
-+ *tty->flip.char_buf_ptr++ = ch;
-+ tty->flip.count++;
-+ ignore_char:
-+ status = clps_readl(SYSFLG(port));
-+ }
-+ out:
-+ tty_flip_buffer_push(tty);
-+ return;
-+
-+ handle_error:
-+ if (ch & UARTDR_PARERR)
-+ port->icount.parity++;
-+ else if (ch & UARTDR_FRMERR)
-+ port->icount.frame++;
-+ if (ch & UARTDR_OVERR)
-+ port->icount.overrun++;
-+
-+ if (ch & port->ignore_status_mask) {
-+ if (++ignored > 100)
-+ goto out;
-+ goto ignore_char;
-+ }
-+ ch &= port->read_status_mask;
-+
-+ if (ch & UARTDR_PARERR)
-+ flg = TTY_PARITY;
-+ else if (ch & UARTDR_FRMERR)
-+ flg = TTY_FRAME;
-+
-+ if (ch & UARTDR_OVERR) {
-+ /*
-+ * CHECK: does overrun affect the current character?
-+ * ASSUMPTION: it does not.
-+ */
-+ *tty->flip.flag_buf_ptr++ = flg;
-+ *tty->flip.char_buf_ptr++ = ch;
-+ tty->flip.count++;
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+ goto ignore_char;
-+ ch = 0;
-+ flg = TTY_OVERRUN;
-+ }
-+#ifdef SUPPORT_SYSRQ
-+ port->sysrq = 0;
-+#endif
-+ goto error_return;
-+}
-+
-+static void clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct uart_port *port = dev_id;
-+ struct circ_buf *xmit = &port->info->xmit;
-+ int count;
-+
-+ if (port->x_char) {
-+ clps_writel(port->x_char, UARTDR(port));
-+ port->icount.tx++;
-+ port->x_char = 0;
-+ return;
-+ }
-+ if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
-+ clps711xuart_stop_tx(port, 0);
-+ return;
-+ }
-+
-+ count = port->fifosize >> 1;
-+ do {
-+ clps_writel(xmit->buf[xmit->tail], UARTDR(port));
-+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-+ port->icount.tx++;
-+ if (uart_circ_empty(xmit))
-+ break;
-+ } while (--count > 0);
-+
-+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-+ uart_write_wakeup(port);
-+
-+ if (uart_circ_empty(xmit))
-+ clps711xuart_stop_tx(port, 0);
-+}
-+
-+static unsigned int clps711xuart_tx_empty(struct uart_port *port)
-+{
-+ unsigned int status = clps_readl(SYSFLG(port));
-+ return status & SYSFLG_UBUSY ? 0 : TIOCSER_TEMT;
-+}
-+
-+static unsigned int clps711xuart_get_mctrl(struct uart_port *port)
-+{
-+ unsigned int port_addr;
-+ unsigned int result = 0;
-+ unsigned int status;
-+
-+ port_addr = SYSFLG(port);
-+ if (port_addr == SYSFLG1) {
-+ status = clps_readl(SYSFLG1);
-+ if (status & SYSFLG1_DCD)
-+ result |= TIOCM_CAR;
-+ if (status & SYSFLG1_DSR)
-+ result |= TIOCM_DSR;
-+ if (status & SYSFLG1_CTS)
-+ result |= TIOCM_CTS;
-+ }
-+
-+ return result;
-+}
-+
-+static void
-+clps711xuart_set_mctrl_null(struct uart_port *port, unsigned int mctrl)
-+{
-+}
-+
-+static void clps711xuart_break_ctl(struct uart_port *port, int break_state)
-+{
-+ unsigned long flags;
-+ unsigned int ubrlcr;
-+
-+ spin_lock_irqsave(&port->lock, flags);
-+ ubrlcr = clps_readl(UBRLCR(port));
-+ if (break_state == -1)
-+ ubrlcr |= UBRLCR_BREAK;
-+ else
-+ ubrlcr &= ~UBRLCR_BREAK;
-+ clps_writel(ubrlcr, UBRLCR(port));
-+ spin_unlock_irqrestore(&port->lock, flags);
-+}
-+
-+static int clps711xuart_startup(struct uart_port *port)
-+{
-+ unsigned int syscon;
-+ int retval;
-+
-+ tx_enabled(port) = 1;
-+
-+ /*
-+ * Allocate the IRQs
-+ */
-+ retval = request_irq(TX_IRQ(port), clps711xuart_int_tx, 0,
-+ "clps711xuart_tx", port);
-+ if (retval)
-+ return retval;
-+
-+ retval = request_irq(RX_IRQ(port), clps711xuart_int_rx, 0,
-+ "clps711xuart_rx", port);
-+ if (retval) {
-+ free_irq(TX_IRQ(port), port);
-+ return retval;
-+ }
-+
-+ /*
-+ * enable the port
-+ */
-+ syscon = clps_readl(SYSCON(port));
-+ syscon |= SYSCON_UARTEN;
-+ clps_writel(syscon, SYSCON(port));
-+
-+ return 0;
-+}
-+
-+static void clps711xuart_shutdown(struct uart_port *port)
-+{
-+ unsigned int ubrlcr, syscon;
-+
-+ /*
-+ * Free the interrupt
-+ */
-+ free_irq(TX_IRQ(port), port); /* TX interrupt */
-+ free_irq(RX_IRQ(port), port); /* RX interrupt */
-+
-+ /*
-+ * disable the port
-+ */
-+ syscon = clps_readl(SYSCON(port));
-+ syscon &= ~SYSCON_UARTEN;
-+ clps_writel(syscon, SYSCON(port));
-+
-+ /*
-+ * disable break condition and fifos
-+ */
-+ ubrlcr = clps_readl(UBRLCR(port));
-+ ubrlcr &= ~(UBRLCR_FIFOEN | UBRLCR_BREAK);
-+ clps_writel(ubrlcr, UBRLCR(port));
-+}
-+
-+static void clps711xuart_change_speed(struct uart_port *port, unsigned int cflag, unsigned int iflag, unsigned int quot)
-+{
-+ unsigned int ubrlcr;
-+ unsigned long flags;
-+
-+#if DEBUG
-+ printk("clps711xuart_change_speed(cflag=0x%x, iflag=0x%x, quot=%d) called\n",
-+ cflag, iflag, quot);
-+#endif
-+ /* byte size and parity */
-+ switch (cflag & CSIZE) {
-+ case CS5:
-+ ubrlcr = UBRLCR_WRDLEN5;
-+ break;
-+ case CS6:
-+ ubrlcr = UBRLCR_WRDLEN6;
-+ break;
-+ case CS7:
-+ ubrlcr = UBRLCR_WRDLEN7;
-+ break;
-+ default: // CS8
-+ ubrlcr = UBRLCR_WRDLEN8;
-+ break;
-+ }
-+ if (cflag & CSTOPB)
-+ ubrlcr |= UBRLCR_XSTOP;
-+ if (cflag & PARENB) {
-+ ubrlcr |= UBRLCR_PRTEN;
-+ if (!(cflag & PARODD))
-+ ubrlcr |= UBRLCR_EVENPRT;
-+ }
-+ if (port->fifosize > 1)
-+ ubrlcr |= UBRLCR_FIFOEN;
-+
-+ spin_lock_irqsave(&port->lock, flags);
-+
-+ port->read_status_mask = UARTDR_OVERR;
-+ if (iflag & INPCK)
-+ port->read_status_mask |= UARTDR_PARERR | UARTDR_FRMERR;
-+
-+ /*
-+ * Characters to ignore
-+ */
-+ port->ignore_status_mask = 0;
-+ if (iflag & IGNPAR)
-+ port->ignore_status_mask |= UARTDR_FRMERR | UARTDR_PARERR;
-+ if (iflag & IGNBRK) {
-+ /*
-+ * If we're ignoring parity and break indicators,
-+ * ignore overruns to (for real raw support).
-+ */
-+ if (iflag & IGNPAR)
-+ port->ignore_status_mask |= UARTDR_OVERR;
-+ }
-+
-+ quot -= 1;
-+
-+ clps_writel(ubrlcr | quot, UBRLCR(port));
-+
-+ spin_unlock_irqrestore(&port->lock, flags);
-+}
-+
-+static const char *clps711xuart_type(struct uart_port *port)
-+{
-+ return port->type == PORT_CLPS711X ? "CLPS711x" : NULL;
-+}
-+
-+/*
-+ * Configure/autoconfigure the port.
-+ */
-+static void clps711xuart_config_port(struct uart_port *port, int flags)
-+{
-+ if (flags & UART_CONFIG_TYPE)
-+ port->type = PORT_CLPS711X;
-+}
-+
-+static void clps711xuart_release_port(struct uart_port *port)
-+{
-+}
-+
-+static int clps711xuart_request_port(struct uart_port *port)
-+{
-+ return 0;
-+}
-+
-+static struct uart_ops clps711x_pops = {
-+ .tx_empty = clps711xuart_tx_empty,
-+ .set_mctrl = clps711xuart_set_mctrl_null,
-+ .get_mctrl = clps711xuart_get_mctrl,
-+ .stop_tx = clps711xuart_stop_tx,
-+ .start_tx = clps711xuart_start_tx,
-+ .stop_rx = clps711xuart_stop_rx,
-+ .enable_ms = clps711xuart_enable_ms,
-+ .break_ctl = clps711xuart_break_ctl,
-+ .startup = clps711xuart_startup,
-+ .shutdown = clps711xuart_shutdown,
-+ .change_speed = clps711xuart_change_speed,
-+ .type = clps711xuart_type,
-+ .config_port = clps711xuart_config_port,
-+ .release_port = clps711xuart_release_port,
-+ .request_port = clps711xuart_request_port,
-+};
-+
-+static struct uart_port clps711x_ports[UART_NR] = {
-+ {
-+ .iobase = SYSCON1,
-+ .irq = IRQ_UTXINT1, /* IRQ_URXINT1, IRQ_UMSINT */
-+ .uartclk = 3686400,
-+ .fifosize = 16,
-+ .ops = &clps711x_pops,
-+ .line = 0,
-+ .flags = ASYNC_BOOT_AUTOCONF,
-+ },
-+ {
-+ .iobase = SYSCON2,
-+ .irq = IRQ_UTXINT2, /* IRQ_URXINT2 */
-+ .uartclk = 3686400,
-+ .fifosize = 16,
-+ .ops = &clps711x_pops,
-+ .line = 1,
-+ .flags = ASYNC_BOOT_AUTOCONF,
-+ }
-+};
-+
-+#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE
-+/*
-+ * Print a string to the serial port trying not to disturb
-+ * any possible real use of the port...
-+ *
-+ * The console_lock must be held when we get here.
-+ *
-+ * Note that this is called with interrupts already disabled
-+ */
-+static void
-+clps711xuart_console_write(struct console *co, const char *s,
-+ unsigned int count)
-+{
-+ struct uart_port *port = clps711x_ports + co->index;
-+ unsigned int status, syscon;
-+ int i;
-+
-+ /*
-+ * Ensure that the port is enabled.
-+ */
-+ syscon = clps_readl(SYSCON(port));
-+ clps_writel(syscon | SYSCON_UARTEN, SYSCON(port));
-+
-+ /*
-+ * Now, do each character
-+ */
-+ for (i = 0; i < count; i++) {
-+ do {
-+ status = clps_readl(SYSFLG(port));
-+ } while (status & SYSFLG_UTXFF);
-+ clps_writel(s[i], UARTDR(port));
-+ if (s[i] == '\n') {
-+ do {
-+ status = clps_readl(SYSFLG(port));
-+ } while (status & SYSFLG_UTXFF);
-+ clps_writel('\r', UARTDR(port));
-+ }
-+ }
-+
-+ /*
-+ * Finally, wait for transmitter to become empty
-+ * and restore the uart state.
-+ */
-+ do {
-+ status = clps_readl(SYSFLG(port));
-+ } while (status & SYSFLG_UBUSY);
-+
-+ clps_writel(syscon, SYSCON(port));
-+}
-+
-+static kdev_t clps711xuart_console_device(struct console *co)
-+{
-+ return MKDEV(SERIAL_CLPS711X_MAJOR, SERIAL_CLPS711X_MINOR + co->index);
-+}
-+
-+static void __init
-+clps711xuart_console_get_options(struct uart_port *port, int *baud,
-+ int *parity, int *bits)
-+{
-+ if (clps_readl(SYSCON(port)) & SYSCON_UARTEN) {
-+ unsigned int ubrlcr, quot;
-+
-+ ubrlcr = clps_readl(UBRLCR(port));
-+
-+ *parity = 'n';
-+ if (ubrlcr & UBRLCR_PRTEN) {
-+ if (ubrlcr & UBRLCR_EVENPRT)
-+ *parity = 'e';
-+ else
-+ *parity = 'o';
-+ }
-+
-+ if ((ubrlcr & UBRLCR_WRDLEN_MASK) == UBRLCR_WRDLEN7)
-+ *bits = 7;
-+ else
-+ *bits = 8;
-+
-+ quot = ubrlcr & UBRLCR_BAUD_MASK;
-+ *baud = port->uartclk / (16 * (quot + 1));
-+ }
-+}
-+
-+static int __init clps711xuart_console_setup(struct console *co, char *options)
-+{
-+ struct uart_port *port;
-+ int baud = 38400;
-+ int bits = 8;
-+ int parity = 'n';
-+ int flow = 'n';
-+
-+ /*
-+ * Check whether an invalid uart number has been specified, and
-+ * if so, search for the first available port that does have
-+ * console support.
-+ */
-+ port = uart_get_console(clps711x_ports, UART_NR, co);
-+
-+ if (options)
-+ uart_parse_options(options, &baud, &parity, &bits, &flow);
-+ else
-+ clps711xuart_console_get_options(port, &baud, &parity, &bits);
-+
-+ return uart_set_options(port, co, baud, parity, bits, flow);
-+}
-+
-+static struct console clps711x_console = {
-+ .name = SERIAL_CLPS711X_NAME,
-+ .write = clps711xuart_console_write,
-+ .device = clps711xuart_console_device,
-+ .setup = clps711xuart_console_setup,
-+ .flags = CON_PRINTBUFFER,
-+ .index = -1,
-+};
-+
-+void __init clps711xuart_console_init(void)
-+{
-+ register_console(&clps711x_console);
-+}
-+
-+#define CLPS711X_CONSOLE &clps711x_console
-+#else
-+#define CLPS711X_CONSOLE NULL
-+#endif
-+
-+static struct uart_driver clps711x_reg = {
-+#ifdef CONFIG_DEVFS_FS
-+ .normal_name = SERIAL_CLPS711X_NAME,
-+ .callout_name = CALLOUT_CLPS711X_NAME,
-+#else
-+ .normal_name = SERIAL_CLPS711X_NAME,
-+ .callout_name = CALLOUT_CLPS711X_NAME,
-+#endif
-+
-+ .normal_major = SERIAL_CLPS711X_MAJOR,
-+ .normal_driver = &normal,
-+ .callout_major = CALLOUT_CLPS711X_MAJOR,
-+ .callout_driver = &callout,
-+
-+ .table = clps711x_table,
-+ .termios = clps711x_termios,
-+ .termios_locked = clps711x_termios_locked,
-+
-+ .minor = SERIAL_CLPS711X_MINOR,
-+ .nr = UART_NR,
-+
-+ .cons = CLPS711X_CONSOLE,
-+};
-+
-+static int __init clps711xuart_init(void)
-+{
-+ int ret, i;
-+
-+ printk(KERN_INFO "Serial: CLPS711x driver\n");
-+
-+ ret = uart_register_driver(&clps711x_reg);
-+ if (ret)
-+ return ret;
-+
-+ for (i = 0; i < UART_NR; i++)
-+ uart_add_one_port(&clps711x_reg, &clps711x_ports[i]);
-+
-+ return 0;
-+}
-+
-+static void __exit clps711xuart_exit(void)
-+{
-+ int i;
-+
-+ for (i = 0; i < UART_NR; i++)
-+ uart_remove_one_port(&clps711x_reg, &clps711x_ports[i]);
-+
-+ uart_unregister_driver(&clps711x_reg);
-+}
-+
-+module_init(clps711xuart_init);
-+module_exit(clps711xuart_exit);
-+
-+EXPORT_NO_SYMBOLS;
-+
-+MODULE_AUTHOR("Deep Blue Solutions Ltd");
-+MODULE_DESCRIPTION("CLPS-711x generic serial driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/serial/core.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,2584 @@
-+/*
-+ * linux/drivers/serial/core.c
-+ *
-+ * Driver core for serial ports
-+ *
-+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
-+ *
-+ * Copyright 1999 ARM Limited
-+ * Copyright (C) 2000-2001 Deep Blue Solutions Ltd.
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * $Id$
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/tty.h>
-+#include <linux/string.h>
-+#include <linux/fcntl.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/console.h>
-+#include <linux/sysrq.h>
-+#include <linux/pm.h>
-+#include <linux/serial_core.h>
-+#include <linux/smp_lock.h>
-+
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+
-+#undef DEBUG
-+#ifdef DEBUG
-+#define DPRINTK(x...) printk(x)
-+#else
-+#define DPRINTK(x...) do { } while (0)
-+#endif
-+
-+#ifndef CONFIG_PM
-+#define pm_access(pm) do { } while (0)
-+#define pm_unregister(pm) do { } while (0)
-+#endif
-+
-+/*
-+ * This is used to lock changes in serial line configuration.
-+ */
-+static DECLARE_MUTEX(port_sem);
-+
-+#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
-+
-+#define uart_users(state) ((state)->count + ((state)->info ? (state)->info->blocked_open : 0))
-+
-+#ifdef CONFIG_SERIAL_CORE_CONSOLE
-+#define uart_console(port) ((port)->cons && (port)->cons->index == (port)->line)
-+#else
-+#define uart_console(port) (0)
-+#endif
-+
-+static void uart_change_speed(struct uart_state *state, struct termios *old_termios);
-+static void uart_wait_until_sent(struct tty_struct *tty, int timeout);
-+static void uart_change_pm(struct uart_state *state, int pm_state);
-+
-+/*
-+ * This routine is used by the interrupt handler to schedule processing in
-+ * the software interrupt portion of the driver.
-+ */
-+void uart_write_wakeup(struct uart_port *port)
-+{
-+ struct uart_info *info = port->info;
-+ tasklet_schedule(&info->tlet);
-+}
-+
-+static void uart_stop(struct tty_struct *tty)
-+{
-+ struct uart_state *state = tty->driver_data;
-+ struct uart_port *port = state->port;
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&port->lock, flags);
-+ port->ops->stop_tx(port, 1);
-+ spin_unlock_irqrestore(&port->lock, flags);
-+}
-+
-+static void __uart_start(struct tty_struct *tty)
-+{
-+ struct uart_state *state = tty->driver_data;
-+ struct uart_port *port = state->port;
-+
-+ if (!uart_circ_empty(&state->info->xmit) && state->info->xmit.buf &&
-+ !tty->stopped && !tty->hw_stopped)
-+ port->ops->start_tx(port, 1);
-+}
-+
-+static void uart_start(struct tty_struct *tty)
-+{
-+ struct uart_state *state = tty->driver_data;
-+ struct uart_port *port = state->port;
-+ unsigned long flags;
-+
-+ pm_access(state->pm);
-+
-+ spin_lock_irqsave(&port->lock, flags);
-+ __uart_start(tty);
-+ spin_unlock_irqrestore(&port->lock, flags);
-+}
-+
-+static void uart_tasklet_action(unsigned long data)
-+{
-+ struct uart_state *state = (struct uart_state *)data;
-+ struct tty_struct *tty;
-+
-+ tty = state->info->tty;
-+ if (tty) {
-+ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-+ tty->ldisc.write_wakeup)
-+ tty->ldisc.write_wakeup(tty);
-+ wake_up_interruptible(&tty->write_wait);
-+ }
-+}
-+
-+static inline void
-+uart_update_mctrl(struct uart_port *port, unsigned int set, unsigned int clear)
-+{
-+ unsigned long flags;
-+ unsigned int old;
-+
-+ spin_lock_irqsave(&port->lock, flags);
-+ old = port->mctrl;
-+ port->mctrl = (old & ~clear) | set;
-+ if (old != port->mctrl)
-+ port->ops->set_mctrl(port, port->mctrl);
-+ spin_unlock_irqrestore(&port->lock, flags);
-+}
-+
-+#define uart_set_mctrl(port,set) uart_update_mctrl(port,set,0)
-+#define uart_clear_mctrl(port,clear) uart_update_mctrl(port,0,clear)
-+
-+static inline unsigned int uart_get_altspeed(struct uart_port *port)
-+{
-+ unsigned int flags = port->flags & UPF_SPD_MASK;
-+ unsigned int altbaud = 0;
-+
-+ if (flags == ASYNC_SPD_HI)
-+ altbaud = 57600;
-+ if (flags == ASYNC_SPD_VHI)
-+ altbaud = 115200;
-+ if (flags == ASYNC_SPD_SHI)
-+ altbaud = 230400;
-+ if (flags == ASYNC_SPD_WARP)
-+ altbaud = 460800;
-+
-+ return altbaud;
-+}
-+
-+/*
-+ * Startup the port. This will be called once per open. All calls
-+ * will be serialised by the per-port semaphore.
-+ */
-+static int uart_startup(struct uart_state *state, int init_hw)
-+{
-+ struct uart_info *info = state->info;
-+ struct uart_port *port = state->port;
-+ unsigned long page;
-+ int retval = 0;
-+
-+ if (info->flags & UIF_INITIALIZED)
-+ return 0;
-+
-+ /*
-+ * Set the TTY IO error marker - we will only clear this
-+ * once we have successfully opened the port. Also set
-+ * up the tty->alt_speed kludge
-+ */
-+ if (info->tty)
-+ set_bit(TTY_IO_ERROR, &info->tty->flags);
-+
-+ if (port->type == PORT_UNKNOWN)
-+ return 0;
-+
-+ /*
-+ * Initialise and allocate the transmit and temporary
-+ * buffer.
-+ */
-+ if (!info->xmit.buf) {
-+ page = get_zeroed_page(GFP_KERNEL);
-+ if (!page)
-+ return -ENOMEM;
-+
-+ info->xmit.buf = (unsigned char *) page;
-+ info->tmpbuf = info->xmit.buf + UART_XMIT_SIZE;
-+ init_MUTEX(&info->tmpbuf_sem);
-+ uart_circ_clear(&info->xmit);
-+ }
-+
-+ port->mctrl = 0;
-+
-+ retval = port->ops->startup(port);
-+ if (retval == 0) {
-+ if (init_hw) {
-+ /*
-+ * Initialise the hardware port settings.
-+ */
-+ uart_change_speed(state, NULL);
-+
-+ /*
-+ * Setup the RTS and DTR signals once the
-+ * port is open and ready to respond.
-+ */
-+ if (info->tty->termios->c_cflag & CBAUD)
-+ uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
-+ }
-+
-+ info->flags |= UIF_INITIALIZED;
-+
-+ clear_bit(TTY_IO_ERROR, &info->tty->flags);
-+ }
-+
-+ if (retval && capable(CAP_SYS_ADMIN))
-+ retval = 0;
-+
-+ return retval;
-+}
-+
-+/*
-+ * This routine will shutdown a serial port; interrupts are disabled, and
-+ * DTR is dropped if the hangup on close termio flag is on. Calls to
-+ * uart_shutdown are serialised by the per-port semaphore.
-+ */
-+static void uart_shutdown(struct uart_state *state)
-+{
-+ struct uart_info *info = state->info;
-+ struct uart_port *port = state->port;
-+
-+ if (!(info->flags & UIF_INITIALIZED))
-+ return;
-+
-+ /*
-+ * Turn off DTR and RTS early.
-+ */
-+ if (!info->tty || (info->tty->termios->c_cflag & HUPCL))
-+ uart_clear_mctrl(port, TIOCM_DTR | TIOCM_RTS);
-+
-+ /*
-+ * clear delta_msr_wait queue to avoid mem leaks: we may free
-+ * the irq here so the queue might never be woken up. Note
-+ * that we won't end up waiting on delta_msr_wait again since
-+ * any outstanding file descriptors should be pointing at
-+ * hung_up_tty_fops now.
-+ */
-+ wake_up_interruptible(&info->delta_msr_wait);
-+
-+ /*
-+ * Free the IRQ and disable the port.
-+ */
-+ port->ops->shutdown(port);
-+
-+ /*
-+ * Free the transmit buffer page.
-+ */
-+ if (info->xmit.buf) {
-+ free_page((unsigned long)info->xmit.buf);
-+ info->xmit.buf = NULL;
-+ info->tmpbuf = NULL;
-+ }
-+
-+ /*
-+ * kill off our tasklet
-+ */
-+ tasklet_kill(&info->tlet);
-+ if (info->tty)
-+ set_bit(TTY_IO_ERROR, &info->tty->flags);
-+
-+ info->flags &= ~UIF_INITIALIZED;
-+}
-+
-+/**
-+ * uart_update_timeout - update per-port FIFO timeout.
-+ * @port: uart_port structure describing the port.
-+ * @cflag: termios cflag value
-+ * @quot: uart clock divisor quotient
-+ *
-+ * Set the port FIFO timeout value. The @cflag value should
-+ * reflect the actual hardware settings.
-+ */
-+void
-+uart_update_timeout(struct uart_port *port, unsigned int cflag,
-+ unsigned int baud)
-+{
-+ unsigned int bits;
-+
-+ /* byte size and parity */
-+ switch (cflag & CSIZE) {
-+ case CS5:
-+ bits = 7;
-+ break;
-+ case CS6:
-+ bits = 8;
-+ break;
-+ case CS7:
-+ bits = 9;
-+ break;
-+ default:
-+ bits = 10;
-+ break; // CS8
-+ }
-+
-+ if (cflag & CSTOPB)
-+ bits++;
-+ if (cflag & PARENB)
-+ bits++;
-+
-+ /*
-+ * The total number of bits to be transmitted in the fifo.
-+ */
-+ bits = bits * port->fifosize;
-+
-+ /*
-+ * Figure the timeout to send the above number of bits.
-+ * Add .02 seconds of slop
-+ */
-+ port->timeout = (HZ * bits) / baud + HZ/50;
-+}
-+
-+EXPORT_SYMBOL(uart_update_timeout);
-+
-+static inline u_int uart_calculate_quot(struct uart_port *port, u_int baud)
-+{
-+ u_int quot;
-+
-+ /* Special case: B0 rate */
-+ if (!baud)
-+ baud = 9600;
-+
-+ /* Old HI/VHI/custom speed handling */
-+ if (baud == 38400 &&
-+ ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
-+ quot = port->custom_divisor;
-+ else
-+ quot = port->uartclk / (16 * baud);
-+
-+ return quot;
-+}
-+
-+static void
-+uart_change_speed(struct uart_state *state, struct termios *old_termios)
-+{
-+ struct tty_struct *tty = state->info->tty;
-+ struct uart_port *port = state->port;
-+ struct termios *termios;
-+ unsigned int quot, baud, cflag, try;
-+
-+ /*
-+ * If we have no tty, termios, or the port does not exist,
-+ * then we can't set the parameters for this port.
-+ */
-+ if (!tty || !tty->termios || port->type == PORT_UNKNOWN)
-+ return;
-+
-+ termios = tty->termios;
-+
-+ cflag = termios->c_cflag;
-+
-+ for (try = 0; try < 2; try ++) {
-+ /* Determine divisor based on baud rate */
-+ baud = tty_get_baud_rate(tty);
-+ quot = uart_calculate_quot(port, baud);
-+ if (quot)
-+ break;
-+
-+ /*
-+ * Oops, the quotient was zero. Try again with
-+ * the old baud rate if possible.
-+ */
-+ termios->c_cflag &= ~CBAUD;
-+ if (old_termios) {
-+ termios->c_cflag |=
-+ (old_termios->c_cflag & CBAUD);
-+ old_termios = NULL;
-+ continue;
-+ }
-+
-+ /*
-+ * As a last resort, if the quotient is zero,
-+ * default to 9600 bps
-+ */
-+ termios->c_cflag |= B9600;
-+ }
-+
-+ uart_update_timeout(port, cflag, port->uartclk / (16 * quot));
-+
-+ if (termios->c_cflag & CRTSCTS)
-+ state->info->flags |= UIF_CTS_FLOW;
-+ else
-+ state->info->flags &= ~UIF_CTS_FLOW;
-+ if (termios->c_cflag & CLOCAL)
-+ state->info->flags &= ~UIF_CHECK_CD;
-+ else
-+ state->info->flags |= UIF_CHECK_CD;
-+
-+ /*
-+ * Set up parity check flag
-+ */
-+ pm_access(state->pm);
-+
-+ port->ops->change_speed(port, cflag, termios->c_iflag, quot);
-+}
-+
-+static inline void
-+__uart_put_char(struct uart_port *port, struct circ_buf *circ, unsigned char c)
-+{
-+ unsigned long flags;
-+
-+ if (!circ->buf)
-+ return;
-+
-+ spin_lock_irqsave(&port->lock, flags);
-+ if (uart_circ_chars_free(circ) != 0) {
-+ circ->buf[circ->head] = c;
-+ circ->head = (circ->head + 1) & (UART_XMIT_SIZE - 1);
-+ }
-+ spin_unlock_irqrestore(&port->lock, flags);
-+}
-+
-+static inline int
-+__uart_user_write(struct uart_port *port, struct circ_buf *circ,
-+ const unsigned char *buf, int count)
-+{
-+ unsigned long flags;
-+ int c, ret = 0;
-+
-+ if (down_interruptible(&port->info->tmpbuf_sem))
-+ return -EINTR;
-+
-+ while (1) {
-+ int c1;
-+ c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
-+ if (count < c)
-+ c = count;
-+ if (c <= 0)
-+ break;
-+
-+ c -= copy_from_user(port->info->tmpbuf, buf, c);
-+ if (!c) {
-+ if (!ret)
-+ ret = -EFAULT;
-+ break;
-+ }
-+ spin_lock_irqsave(&port->lock, flags);
-+ c1 = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
-+ if (c1 < c)
-+ c = c1;
-+ memcpy(circ->buf + circ->head, port->info->tmpbuf, c);
-+ circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
-+ spin_unlock_irqrestore(&port->lock, flags);
-+ buf += c;
-+ count -= c;
-+ ret += c;
-+ }
-+ up(&port->info->tmpbuf_sem);
-+
-+ return ret;
-+}
-+
-+static inline int
-+__uart_kern_write(struct uart_port *port, struct circ_buf *circ,
-+ const unsigned char *buf, int count)
-+{
-+ unsigned long flags;
-+ int c, ret = 0;
-+
-+ spin_lock_irqsave(&port->lock, flags);
-+ while (1) {
-+ c = CIRC_SPACE_TO_END(circ->head, circ->tail, UART_XMIT_SIZE);
-+ if (count < c)
-+ c = count;
-+ if (c <= 0)
-+ break;
-+ memcpy(circ->buf + circ->head, buf, c);
-+ circ->head = (circ->head + c) & (UART_XMIT_SIZE - 1);
-+ buf += c;
-+ count -= c;
-+ ret += c;
-+ }
-+ spin_unlock_irqrestore(&port->lock, flags);
-+
-+ return ret;
-+}
-+
-+static void uart_put_char(struct tty_struct *tty, unsigned char ch)
-+{
-+ struct uart_state *state = tty->driver_data;
-+
-+ __uart_put_char(state->port, &state->info->xmit, ch);
-+}
-+
-+static void uart_flush_chars(struct tty_struct *tty)
-+{
-+ uart_start(tty);
-+}
-+
-+static int
-+uart_write(struct tty_struct *tty, int from_user, const unsigned char * buf,
-+ int count)
-+{
-+ struct uart_state *state = tty->driver_data;
-+ int ret;
-+
-+ if (!state->info->xmit.buf)
-+ return 0;
-+
-+ if (from_user)
-+ ret = __uart_user_write(state->port, &state->info->xmit, buf, count);
-+ else
-+ ret = __uart_kern_write(state->port, &state->info->xmit, buf, count);
-+
-+ uart_start(tty);
-+ return ret;
-+}
-+
-+static int uart_write_room(struct tty_struct *tty)
-+{
-+ struct uart_state *state = tty->driver_data;
-+
-+ return uart_circ_chars_free(&state->info->xmit);
-+}
-+
-+static int uart_chars_in_buffer(struct tty_struct *tty)
-+{
-+ struct uart_state *state = tty->driver_data;
-+
-+ return uart_circ_chars_pending(&state->info->xmit);
-+}
-+
-+static void uart_flush_buffer(struct tty_struct *tty)
-+{
-+ struct uart_state *state = tty->driver_data;
-+ struct uart_port *port = state->port;
-+ unsigned long flags;
-+
-+ DPRINTK("uart_flush_buffer(%d) called\n",
-+ MINOR(tty->device) - tty->driver.minor_start);
-+
-+ spin_lock_irqsave(&port->lock, flags);
-+ uart_circ_clear(&state->info->xmit);
-+ spin_unlock_irqrestore(&port->lock, flags);
-+ wake_up_interruptible(&tty->write_wait);
-+ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-+ tty->ldisc.write_wakeup)
-+ (tty->ldisc.write_wakeup)(tty);
-+}
-+
-+/*
-+ * This function is used to send a high-priority XON/XOFF character to
-+ * the device
-+ */
-+static void uart_send_xchar(struct tty_struct *tty, char ch)
-+{
-+ struct uart_state *state = tty->driver_data;
-+ struct uart_port *port = state->port;
-+ unsigned long flags;
-+
-+ if (port->ops->send_xchar)
-+ port->ops->send_xchar(port, ch);
-+ else {
-+ port->x_char = ch;
-+ if (ch) {
-+ spin_lock_irqsave(&port->lock, flags);
-+ port->ops->start_tx(port, 0);
-+ spin_unlock_irqrestore(&port->lock, flags);
-+ }
-+ }
-+}
-+
-+static void uart_throttle(struct tty_struct *tty)
-+{
-+ struct uart_state *state = tty->driver_data;
-+
-+ if (I_IXOFF(tty))
-+ uart_send_xchar(tty, STOP_CHAR(tty));
-+
-+ if (tty->termios->c_cflag & CRTSCTS)
-+ uart_clear_mctrl(state->port, TIOCM_RTS);
-+}
-+
-+static void uart_unthrottle(struct tty_struct *tty)
-+{
-+ struct uart_state *state = tty->driver_data;
-+ struct uart_port *port = state->port;
-+
-+ if (I_IXOFF(tty)) {
-+ if (port->x_char)
-+ port->x_char = 0;
-+ else
-+ uart_send_xchar(tty, START_CHAR(tty));
-+ }
-+
-+ if (tty->termios->c_cflag & CRTSCTS)
-+ uart_set_mctrl(port, TIOCM_RTS);
-+}
-+
-+static int uart_get_info(struct uart_state *state, struct serial_struct *retinfo)
-+{
-+ struct uart_port *port = state->port;
-+ struct serial_struct tmp;
-+
-+ memset(&tmp, 0, sizeof(tmp));
-+ tmp.type = port->type;
-+ tmp.line = port->line;
-+ tmp.port = port->iobase;
-+ if (HIGH_BITS_OFFSET)
-+ tmp.port_high = (long) port->iobase >> HIGH_BITS_OFFSET;
-+ tmp.irq = port->irq;
-+ tmp.flags = port->flags;
-+ tmp.xmit_fifo_size = port->fifosize;
-+ tmp.baud_base = port->uartclk / 16;
-+ tmp.close_delay = state->close_delay;
-+ tmp.closing_wait = state->closing_wait;
-+ tmp.custom_divisor = port->custom_divisor;
-+ tmp.hub6 = port->hub6;
-+ tmp.io_type = port->iotype;
-+ tmp.iomem_reg_shift = port->regshift;
-+ tmp.iomem_base = (void *)port->mapbase;
-+
-+ if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
-+ return -EFAULT;
-+ return 0;
-+}
-+
-+static int
-+uart_set_info(struct uart_state *state, struct serial_struct *newinfo)
-+{
-+ struct serial_struct new_serial;
-+ struct uart_port *port = state->port;
-+ unsigned long new_port;
-+ unsigned int change_irq, change_port, old_flags;
-+ unsigned int old_custom_divisor;
-+ int retval = 0;
-+
-+ if (copy_from_user(&new_serial, newinfo, sizeof(new_serial)))
-+ return -EFAULT;
-+
-+ new_port = new_serial.port;
-+ if (HIGH_BITS_OFFSET)
-+ new_port += (unsigned long) new_serial.port_high << HIGH_BITS_OFFSET;
-+
-+ new_serial.irq = irq_cannonicalize(new_serial.irq);
-+
-+ /*
-+ * This semaphore protects state->count. It is also
-+ * very useful to prevent opens. Also, take the
-+ * port configuration semaphore to make sure that a
-+ * module insertion/removal doesn't change anything
-+ * under us.
-+ */
-+ down(&state->sem);
-+
-+ change_irq = new_serial.irq != port->irq;
-+
-+ /*
-+ * Since changing the 'type' of the port changes its resource
-+ * allocations, we should treat type changes the same as
-+ * IO port changes.
-+ */
-+ change_port = new_port != port->iobase ||
-+ (unsigned long)new_serial.iomem_base != port->mapbase ||
-+ new_serial.hub6 != port->hub6 ||
-+ new_serial.io_type != port->iotype ||
-+ new_serial.iomem_reg_shift != port->regshift ||
-+ new_serial.type != port->type;
-+
-+ old_flags = port->flags;
-+ old_custom_divisor = port->custom_divisor;
-+
-+ if (!capable(CAP_SYS_ADMIN)) {
-+ retval = -EPERM;
-+ if (change_irq || change_port ||
-+ (new_serial.baud_base != port->uartclk / 16) ||
-+ (new_serial.close_delay != state->close_delay) ||
-+ (new_serial.closing_wait != state->closing_wait) ||
-+ (new_serial.xmit_fifo_size != port->fifosize) ||
-+ (((new_serial.flags ^ old_flags) & ~UPF_USR_MASK) != 0))
-+ goto exit;
-+ port->flags = ((port->flags & ~UPF_USR_MASK) |
-+ (new_serial.flags & UPF_USR_MASK));
-+ port->custom_divisor = new_serial.custom_divisor;
-+ goto check_and_exit;
-+ }
-+
-+ /*
-+ * Ask the low level driver to verify the settings.
-+ */
-+ if (port->ops->verify_port)
-+ retval = port->ops->verify_port(port, &new_serial);
-+
-+ if ((new_serial.irq >= NR_IRQS) || (new_serial.irq < 0) ||
-+ (new_serial.baud_base < 9600))
-+ retval = -EINVAL;
-+
-+ if (retval)
-+ goto exit;
-+
-+ if (change_port || change_irq) {
-+ retval = -EBUSY;
-+
-+ /*
-+ * Make sure that we are the sole user of this port.
-+ */
-+ if (uart_users(state) > 1)
-+ goto exit;
-+
-+ /*
-+ * We need to shutdown the serial port at the old
-+ * port/type/irq combination.
-+ */
-+ uart_shutdown(state);
-+ }
-+
-+ if (change_port) {
-+ unsigned long old_iobase, old_mapbase;
-+ unsigned int old_type, old_iotype, old_hub6, old_shift;
-+
-+ old_iobase = port->iobase;
-+ old_mapbase = port->mapbase;
-+ old_type = port->type;
-+ old_hub6 = port->hub6;
-+ old_iotype = port->iotype;
-+ old_shift = port->regshift;
-+
-+ /*
-+ * Free and release old regions
-+ */
-+ if (old_type != PORT_UNKNOWN)
-+ port->ops->release_port(port);
-+
-+ port->iobase = new_port;
-+ port->type = new_serial.type;
-+ port->hub6 = new_serial.hub6;
-+ port->iotype = new_serial.io_type;
-+ port->regshift = new_serial.iomem_reg_shift;
-+ port->mapbase = (unsigned long)new_serial.iomem_base;
-+
-+ /*
-+ * Claim and map the new regions
-+ */
-+ if (port->type != PORT_UNKNOWN) {
-+ retval = port->ops->request_port(port);
-+ } else {
-+ /* Always success - Jean II */
-+ retval = 0;
-+ }
-+
-+ /*
-+ * If we fail to request resources for the
-+ * new port, try to restore the old settings.
-+ */
-+ if (retval && old_type != PORT_UNKNOWN) {
-+ port->iobase = old_iobase;
-+ port->type = old_type;
-+ port->hub6 = old_hub6;
-+ port->iotype = old_iotype;
-+ port->regshift = old_shift;
-+ port->mapbase = old_mapbase;
-+ retval = port->ops->request_port(port);
-+ /*
-+ * If we failed to restore the old settings,
-+ * we fail like this.
-+ */
-+ if (retval)
-+ port->type = PORT_UNKNOWN;
-+
-+ /*
-+ * We failed anyway.
-+ */
-+ retval = -EBUSY;
-+ }
-+ }
-+
-+ port->irq = new_serial.irq;
-+ port->uartclk = new_serial.baud_base * 16;
-+ port->flags = (port->flags & ~UPF_CHANGE_MASK) |
-+ (new_serial.flags & UPF_CHANGE_MASK);
-+ port->custom_divisor = new_serial.custom_divisor;
-+ state->close_delay = new_serial.close_delay * HZ / 100;
-+ state->closing_wait = new_serial.closing_wait * HZ / 100;
-+ port->fifosize = new_serial.xmit_fifo_size;
-+ if (state->info->tty)
-+ state->info->tty->low_latency =
-+ (port->flags & UPF_LOW_LATENCY) ? 1 : 0;
-+
-+ check_and_exit:
-+ retval = 0;
-+ if (port->type == PORT_UNKNOWN)
-+ goto exit;
-+ if (state->info->flags & UIF_INITIALIZED) {
-+ if (((old_flags ^ port->flags) & UPF_SPD_MASK) ||
-+ old_custom_divisor != port->custom_divisor) {
-+ state->info->tty->alt_speed = uart_get_altspeed(port);
-+ uart_change_speed(state, NULL);
-+ }
-+ } else
-+ retval = uart_startup(state, 1);
-+ exit:
-+ up(&state->sem);
-+ return retval;
-+}
-+
-+
-+/*
-+ * uart_get_lsr_info - get line status register info.
-+ * Note: uart_ioctl protects us against hangups.
-+ */
-+static int uart_get_lsr_info(struct uart_state *state, unsigned int *value)
-+{
-+ struct uart_port *port = state->port;
-+ unsigned int result;
-+
-+ result = port->ops->tx_empty(port);
-+
-+ /*
-+ * If we're about to load something into the transmit
-+ * register, we'll pretend the transmitter isn't empty to
-+ * avoid a race condition (depending on when the transmit
-+ * interrupt happens).
-+ */
-+ if (port->x_char ||
-+ ((uart_circ_chars_pending(&state->info->xmit) > 0) &&
-+ !state->info->tty->stopped && !state->info->tty->hw_stopped))
-+ result &= ~TIOCSER_TEMT;
-+
-+ return put_user(result, value);
-+}
-+
-+static int uart_tiocmget(struct tty_struct *tty, struct file *file)
-+{
-+ struct uart_state *state = tty->driver_data;
-+ struct uart_port *port = state->port;
-+ int result = -EIO;
-+
-+ down(&state->sem);
-+ if ((!file || !tty_hung_up_p(file)) &&
-+ !(tty->flags & (1 << TTY_IO_ERROR))) {
-+ result = port->mctrl;
-+ result |= port->ops->get_mctrl(port);
-+ }
-+ up(&state->sem);
-+
-+ return result;
-+}
-+
-+static int
-+uart_tiocmset(struct tty_struct *tty, struct file *file,
-+ unsigned int set, unsigned int clear)
-+{
-+ struct uart_state *state = tty->driver_data;
-+ struct uart_port *port = state->port;
-+ int ret = -EIO;
-+
-+ down(&state->sem);
-+ if ((!file || !tty_hung_up_p(file)) &&
-+ !(tty->flags & (1 << TTY_IO_ERROR))) {
-+ uart_update_mctrl(port, set, clear);
-+ ret = 0;
-+ }
-+ up(&state->sem);
-+ return ret;
-+}
-+
-+static void uart_break_ctl(struct tty_struct *tty, int break_state)
-+{
-+ struct uart_state *state = tty->driver_data;
-+ struct uart_port *port = state->port;
-+
-+ BUG_ON(!kernel_locked());
-+
-+ down(&state->sem);
-+
-+ if (port->type != PORT_UNKNOWN)
-+ port->ops->break_ctl(port, break_state);
-+
-+ up(&state->sem);
-+}
-+
-+static int uart_do_autoconfig(struct uart_state *state)
-+{
-+ struct uart_port *port = state->port;
-+ int flags, ret;
-+
-+ if (!capable(CAP_SYS_ADMIN))
-+ return -EPERM;
-+
-+ /*
-+ * Take the per-port semaphore. This prevents count from
-+ * changing, and hence any extra opens of the port while
-+ * we're auto-configuring.
-+ */
-+ if (down_interruptible(&state->sem))
-+ return -ERESTARTSYS;
-+
-+ ret = -EBUSY;
-+ if (uart_users(state) == 1) {
-+ uart_shutdown(state);
-+
-+ /*
-+ * If we already have a port type configured,
-+ * we must release its resources.
-+ */
-+ if (port->type != PORT_UNKNOWN)
-+ port->ops->release_port(port);
-+
-+ flags = UART_CONFIG_TYPE;
-+ if (port->flags & UPF_AUTO_IRQ)
-+ flags |= UART_CONFIG_IRQ;
-+
-+ /*
-+ * This will claim the ports resources if
-+ * a port is found.
-+ */
-+ port->ops->config_port(port, flags);
-+
-+ ret = uart_startup(state, 1);
-+ }
-+ up(&state->sem);
-+ return ret;
-+}
-+
-+/*
-+ * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
-+ * - mask passed in arg for lines of interest
-+ * (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
-+ * Caller should use TIOCGICOUNT to see which one it was
-+ */
-+static int
-+uart_wait_modem_status(struct uart_state *state, unsigned long arg)
-+{
-+ struct uart_port *port = state->port;
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct uart_icount cprev, cnow;
-+ int ret;
-+
-+ /*
-+ * note the counters on entry
-+ */
-+ spin_lock_irq(&port->lock);
-+ memcpy(&cprev, &port->icount, sizeof(struct uart_icount));
-+
-+ /*
-+ * Force modem status interrupts on
-+ */
-+ port->ops->enable_ms(port);
-+ spin_unlock_irq(&port->lock);
-+
-+ add_wait_queue(&state->info->delta_msr_wait, &wait);
-+ for (;;) {
-+ spin_lock_irq(&port->lock);
-+ memcpy(&cnow, &port->icount, sizeof(struct uart_icount));
-+ spin_unlock_irq(&port->lock);
-+
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
-+ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
-+ ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
-+ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
-+ ret = 0;
-+ break;
-+ }
-+
-+ schedule();
-+
-+ /* see if a signal did it */
-+ if (signal_pending(current)) {
-+ ret = -ERESTARTSYS;
-+ break;
-+ }
-+
-+ cprev = cnow;
-+ }
-+
-+ current->state = TASK_RUNNING;
-+ remove_wait_queue(&state->info->delta_msr_wait, &wait);
-+
-+ return ret;
-+}
-+
-+/*
-+ * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
-+ * Return: write counters to the user passed counter struct
-+ * NB: both 1->0 and 0->1 transitions are counted except for
-+ * RI where only 0->1 is counted.
-+ */
-+static int
-+uart_get_count(struct uart_state *state, struct serial_icounter_struct *icnt)
-+{
-+ struct serial_icounter_struct icount;
-+ struct uart_icount cnow;
-+ struct uart_port *port = state->port;
-+
-+ spin_lock_irq(&port->lock);
-+ memcpy(&cnow, &port->icount, sizeof(struct uart_icount));
-+ spin_unlock_irq(&port->lock);
-+
-+ icount.cts = cnow.cts;
-+ icount.dsr = cnow.dsr;
-+ icount.rng = cnow.rng;
-+ icount.dcd = cnow.dcd;
-+ icount.rx = cnow.rx;
-+ icount.tx = cnow.tx;
-+ icount.frame = cnow.frame;
-+ icount.overrun = cnow.overrun;
-+ icount.parity = cnow.parity;
-+ icount.brk = cnow.brk;
-+ icount.buf_overrun = cnow.buf_overrun;
-+
-+ return copy_to_user(icnt, &icount, sizeof(icount)) ? -EFAULT : 0;
-+}
-+
-+/*
-+ * Called via sys_ioctl under the BKL. We can use spin_lock_irq() here.
-+ */
-+static int
-+uart_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd,
-+ unsigned long arg)
-+{
-+ struct uart_state *state = tty->driver_data;
-+ int ret = -ENOIOCTLCMD;
-+
-+ BUG_ON(!kernel_locked());
-+
-+ /*
-+ * These ioctls don't rely on the hardware to be present.
-+ */
-+ switch (cmd) {
-+ case TIOCGSERIAL:
-+ ret = uart_get_info(state, (struct serial_struct *)arg);
-+ break;
-+
-+ case TIOCSSERIAL:
-+ ret = uart_set_info(state, (struct serial_struct *)arg);
-+ break;
-+
-+ case TIOCSERCONFIG:
-+ ret = uart_do_autoconfig(state);
-+ break;
-+
-+ case TIOCSERGWILD: /* obsolete */
-+ case TIOCSERSWILD: /* obsolete */
-+ ret = 0;
-+ break;
-+ }
-+
-+ if (ret != -ENOIOCTLCMD)
-+ goto out;
-+
-+ if (tty->flags & (1 << TTY_IO_ERROR)) {
-+ ret = -EIO;
-+ goto out;
-+ }
-+
-+ /*
-+ * The following should only be used when hardware is present.
-+ */
-+ switch (cmd) {
-+ case TIOCMIWAIT:
-+ ret = uart_wait_modem_status(state, arg);
-+ break;
-+
-+ case TIOCGICOUNT:
-+ ret = uart_get_count(state, (struct serial_icounter_struct *)arg);
-+ break;
-+
-+ case TIOCMGET:
-+ {
-+ int val;
-+ val = uart_tiocmget(tty, filp);
-+ if (val >= 0) {
-+ ret = put_user(val, (int *)arg);
-+ } else {
-+ ret = val;
-+ }
-+ }
-+ break;
-+
-+ case TIOCMBIS:
-+ case TIOCMBIC:
-+ case TIOCMSET:
-+ {
-+ int val, set = 0, clear = 0;
-+ ret = get_user(val, (int *)arg);
-+ if (ret)
-+ break;
-+
-+ switch (cmd) {
-+ case TIOCMBIS:
-+ set = val;
-+ break;
-+ case TIOCMBIC:
-+ clear = val;
-+ break;
-+ case TIOCMSET:
-+ set = val;
-+ clear = ~val;
-+ break;
-+ }
-+
-+ set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
-+ clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
-+
-+ ret = uart_tiocmset(tty, filp, set, clear);
-+ }
-+ break;
-+ }
-+
-+ if (ret != -ENOIOCTLCMD)
-+ goto out;
-+
-+ down(&state->sem);
-+
-+ if (tty_hung_up_p(filp)) {
-+ ret = -EIO;
-+ goto out_up;
-+ }
-+
-+ /*
-+ * All these rely on hardware being present and need to be
-+ * protected against the tty being hung up.
-+ */
-+ switch (cmd) {
-+ case TIOCSERGETLSR: /* Get line status register */
-+ ret = uart_get_lsr_info(state, (unsigned int *)arg);
-+ break;
-+
-+ default: {
-+ struct uart_port *port = state->port;
-+ if (port->ops->ioctl)
-+ ret = port->ops->ioctl(port, cmd, arg);
-+ break;
-+ }
-+ }
-+ out_up:
-+ up(&state->sem);
-+ out:
-+ return ret;
-+}
-+
-+static void uart_set_termios(struct tty_struct *tty, struct termios *old_termios)
-+{
-+ struct uart_state *state = tty->driver_data;
-+ unsigned long flags;
-+ unsigned int cflag = tty->termios->c_cflag;
-+
-+ BUG_ON(!kernel_locked());
-+
-+ /*
-+ * These are the bits that are used to setup various
-+ * flags in the low level driver.
-+ */
-+#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-+
-+ if ((cflag ^ old_termios->c_cflag) == 0 &&
-+ RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0)
-+ return;
-+
-+ uart_change_speed(state, old_termios);
-+
-+ /* Handle transition to B0 status */
-+ if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
-+ uart_clear_mctrl(state->port, TIOCM_RTS | TIOCM_DTR);
-+
-+ /* Handle transition away from B0 status */
-+ if (!(old_termios->c_cflag & CBAUD) && (cflag & CBAUD)) {
-+ unsigned int mask = TIOCM_DTR;
-+ if (!(cflag & CRTSCTS) ||
-+ !test_bit(TTY_THROTTLED, &tty->flags))
-+ mask |= TIOCM_RTS;
-+ uart_set_mctrl(state->port, mask);
-+ }
-+
-+ /* Handle turning off CRTSCTS */
-+ if ((old_termios->c_cflag & CRTSCTS) && !(cflag & CRTSCTS)) {
-+ spin_lock_irqsave(&state->port->lock, flags);
-+ tty->hw_stopped = 0;
-+ __uart_start(tty);
-+ spin_unlock_irqrestore(&state->port->lock, flags);
-+ }
-+
-+#if 0
-+ /*
-+ * No need to wake up processes in open wait, since they
-+ * sample the CLOCAL flag once, and don't recheck it.
-+ * XXX It's not clear whether the current behavior is correct
-+ * or not. Hence, this may change.....
-+ */
-+ if (!(old_termios->c_cflag & CLOCAL) &&
-+ (tty->termios->c_cflag & CLOCAL))
-+ wake_up_interruptible(&state->info->open_wait);
-+#endif
-+}
-+
-+/*
-+ * In 2.4.5, calls to this will be serialized via the BKL in
-+ * linux/drivers/char/tty_io.c:tty_release()
-+ * linux/drivers/char/tty_io.c:do_tty_handup()
-+ */
-+static void uart_close(struct tty_struct *tty, struct file *filp)
-+{
-+ struct uart_driver *drv = (struct uart_driver *)tty->driver.driver_state;
-+ struct uart_state *state = tty->driver_data;
-+ struct uart_port *port;
-+
-+ BUG_ON(!kernel_locked());
-+
-+ if (!state || !state->port)
-+ return;
-+
-+ port = state->port;
-+
-+ DPRINTK("uart_close(%d) called\n", port->line);
-+
-+ down(&state->sem);
-+
-+ if (tty_hung_up_p(filp))
-+ goto done;
-+
-+ if ((tty->count == 1) && (state->count != 1)) {
-+ /*
-+ * Uh, oh. tty->count is 1, which means that the tty
-+ * structure will be freed. state->count should always
-+ * be one in these conditions. If it's greater than
-+ * one, we've got real problems, since it means the
-+ * serial port won't be shutdown.
-+ */
-+ printk("uart_close: bad serial port count; tty->count is 1, "
-+ "state->count is %d\n", state->count);
-+ state->count = 1;
-+ }
-+ if (--state->count < 0) {
-+ printk("rs_close: bad serial port count for %s%d: %d\n",
-+ tty->driver.name, port->line, state->count);
-+ state->count = 0;
-+ }
-+ if (state->count)
-+ goto done;
-+
-+ /*
-+ * Save the termios structure, since this port may have
-+ * separate termios for callout and dialin.
-+ */
-+ if (state->info->flags & UIF_NORMAL_ACTIVE)
-+ state->normal_termios = *tty->termios;
-+ if (state->info->flags & UIF_CALLOUT_ACTIVE)
-+ state->callout_termios = *tty->termios;
-+
-+ /*
-+ * Now we wait for the transmit buffer to clear; and we notify
-+ * the line discipline to only process XON/XOFF characters by
-+ * setting tty->closing.
-+ */
-+ tty->closing = 1;
-+
-+ if (state->closing_wait != USF_CLOSING_WAIT_NONE)
-+ tty_wait_until_sent(tty, state->closing_wait);
-+
-+ /*
-+ * At this point, we stop accepting input. To do this, we
-+ * disable the receive line status interrupts.
-+ */
-+ if (state->info->flags & UIF_INITIALIZED) {
-+ unsigned long flags;
-+ spin_lock_irqsave(&port->lock, flags);
-+ port->ops->stop_rx(port);
-+ spin_unlock_irqrestore(&port->lock, flags);
-+ /*
-+ * Before we drop DTR, make sure the UART transmitter
-+ * has completely drained; this is especially
-+ * important if there is a transmit FIFO!
-+ */
-+ uart_wait_until_sent(tty, port->timeout);
-+ }
-+
-+ uart_shutdown(state);
-+ uart_flush_buffer(tty);
-+ if (tty->ldisc.flush_buffer)
-+ tty->ldisc.flush_buffer(tty);
-+ tty->closing = 0;
-+ state->info->tty = NULL;
-+
-+ if (state->info->blocked_open) {
-+ if (state->close_delay) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(state->close_delay);
-+ set_current_state(TASK_RUNNING);
-+ }
-+ } else if (!uart_console(port)) {
-+ uart_change_pm(state, 3);
-+ }
-+
-+ /*
-+ * Wake up anyone trying to open this port.
-+ */
-+ state->info->flags &= ~(UIF_NORMAL_ACTIVE|UIF_CALLOUT_ACTIVE);
-+ wake_up_interruptible(&state->info->open_wait);
-+
-+ done:
-+ up(&state->sem);
-+ if (drv->owner)
-+ __MOD_DEC_USE_COUNT(drv->owner);
-+}
-+
-+static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
-+{
-+ struct uart_state *state = tty->driver_data;
-+ struct uart_port *port = state->port;
-+ unsigned long char_time, expire;
-+
-+ BUG_ON(!kernel_locked());
-+
-+ if (port->type == PORT_UNKNOWN || port->fifosize == 0)
-+ return;
-+
-+ /*
-+ * Set the check interval to be 1/5 of the estimated time to
-+ * send a single character, and make it at least 1. The check
-+ * interval should also be less than the timeout.
-+ *
-+ * Note: we have to use pretty tight timings here to satisfy
-+ * the NIST-PCTS.
-+ */
-+ char_time = (port->timeout - HZ/50) / port->fifosize;
-+ char_time = char_time / 5;
-+ if (char_time == 0)
-+ char_time = 1;
-+ if (timeout && timeout < char_time)
-+ char_time = timeout;
-+
-+ /*
-+ * If the transmitter hasn't cleared in twice the approximate
-+ * amount of time to send the entire FIFO, it probably won't
-+ * ever clear. This assumes the UART isn't doing flow
-+ * control, which is currently the case. Hence, if it ever
-+ * takes longer than port->timeout, this is probably due to a
-+ * UART bug of some kind. So, we clamp the timeout parameter at
-+ * 2*port->timeout.
-+ */
-+ if (timeout == 0 || timeout > 2 * port->timeout)
-+ timeout = 2 * port->timeout;
-+
-+ expire = jiffies + timeout;
-+
-+ DPRINTK("uart_wait_until_sent(%d), jiffies=%lu, expire=%lu...\n",
-+ port->line, jiffies, expire);
-+
-+ /*
-+ * Check whether the transmitter is empty every 'char_time'.
-+ * 'timeout' / 'expire' give us the maximum amount of time
-+ * we wait.
-+ */
-+ while (!port->ops->tx_empty(port)) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(char_time);
-+ if (signal_pending(current))
-+ break;
-+ if (time_after(jiffies, expire))
-+ break;
-+ }
-+ set_current_state(TASK_RUNNING); /* might not be needed */
-+}
-+
-+/*
-+ * This is called with the BKL held in
-+ * linux/drivers/char/tty_io.c:do_tty_hangup()
-+ * We're called from the eventd thread, so we can sleep for
-+ * a _short_ time only.
-+ */
-+static void uart_hangup(struct tty_struct *tty)
-+{
-+ struct uart_state *state = tty->driver_data;
-+
-+ BUG_ON(!kernel_locked());
-+ DPRINTK("uart_hangup(%d)\n", state->port->line);
-+
-+ down(&state->sem);
-+ if (state->info && state->info->flags & (UIF_NORMAL_ACTIVE|UIF_CALLOUT_ACTIVE)) {
-+ uart_flush_buffer(tty);
-+ uart_shutdown(state);
-+ state->count = 0;
-+ state->info->flags &= ~(UIF_NORMAL_ACTIVE|UIF_CALLOUT_ACTIVE);
-+ state->info->tty = NULL;
-+ wake_up_interruptible(&state->info->open_wait);
-+ wake_up_interruptible(&state->info->delta_msr_wait);
-+ }
-+ up(&state->sem);
-+}
-+
-+/*
-+ * Copy across the serial console cflag setting into the termios settings
-+ * for the initial open of the port. This allows continuity between the
-+ * kernel settings, and the settings init adopts when it opens the port
-+ * for the first time.
-+ */
-+static void uart_update_termios(struct uart_state *state)
-+{
-+ struct tty_struct *tty = state->info->tty;
-+ struct uart_port *port = state->port;
-+
-+ if (uart_console(port) && port->cons->cflag) {
-+ tty->termios->c_cflag = port->cons->cflag;
-+ port->cons->cflag = 0;
-+ }
-+
-+ /*
-+ * If the device failed to grab its irq resources,
-+ * or some other error occurred, don't try to talk
-+ * to the port hardware.
-+ */
-+ if (!(tty->flags & (1 << TTY_IO_ERROR))) {
-+ /*
-+ * Make termios settings take effect.
-+ */
-+ uart_change_speed(state, NULL);
-+
-+ /*
-+ * And finally enable the RTS and DTR signals.
-+ */
-+ if (tty->termios->c_cflag & CBAUD)
-+ uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
-+ }
-+}
-+
-+/*
-+ * Block the open until the port is ready. We must be called with
-+ * the per-port semaphore held.
-+ */
-+static int
-+uart_block_til_ready(struct file *filp, struct uart_state *state)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct uart_info *info = state->info;
-+ struct uart_port *port = state->port;
-+ struct termios *termios;
-+
-+ /*
-+ * If this is a callout device, then just make sure the normal
-+ * device isn't being used.
-+ */
-+ if (info->tty->driver.subtype == SERIAL_TYPE_CALLOUT) {
-+ if (info->flags & UIF_NORMAL_ACTIVE)
-+ return -EBUSY;
-+ if ((info->flags & UIF_CALLOUT_ACTIVE) &&
-+ (info->flags & ASYNC_SESSION_LOCKOUT) &&
-+ (info->session != current->session))
-+ return -EBUSY;
-+ if ((info->flags & UIF_CALLOUT_ACTIVE) &&
-+ (info->flags & ASYNC_PGRP_LOCKOUT) &&
-+ (info->pgrp != current->pgrp))
-+ return -EBUSY;
-+ info->flags |= UIF_CALLOUT_ACTIVE;
-+ return 0;
-+ }
-+
-+ if (info->flags & UIF_CALLOUT_ACTIVE) {
-+ termios = &state->normal_termios;
-+ } else {
-+ termios = state->info->tty->termios;
-+ }
-+
-+ info->blocked_open++;
-+ state->count--;
-+
-+ add_wait_queue(&info->open_wait, &wait);
-+ while (1) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ /*
-+ * If we have been hung up, tell userspace/restart open.
-+ */
-+ if (tty_hung_up_p(filp) || info->tty == NULL)
-+ break;
-+
-+ /*
-+ * If the port has been closed, tell userspace/restart open.
-+ */
-+ if (!(info->flags & UIF_INITIALIZED))
-+ break;
-+
-+ /*
-+ * If non-blocking mode is set, or CLOCAL mode is set,
-+ * we don't want to wait for the modem status lines to
-+ * indicate that the port is ready.
-+ *
-+ * Also, if the port is not enabled/configured, we want
-+ * to allow the open to succeed here. Note that we will
-+ * have set TTY_IO_ERROR for a non-existant port.
-+ */
-+ if ((filp->f_flags & O_NONBLOCK) ||
-+ (termios->c_cflag & CLOCAL) ||
-+ (info->tty->flags & (1 << TTY_IO_ERROR))) {
-+ break;
-+ }
-+
-+ if (!(info->flags & UIF_CALLOUT_ACTIVE)) {
-+ /*
-+ * Set DTR to allow modem to know we're waiting. Do
-+ * not set RTS here - we want to make sure we catch
-+ * the data from the modem.
-+ */
-+ if (info->tty->termios->c_cflag & CBAUD)
-+ uart_set_mctrl(port, TIOCM_DTR);
-+
-+ /*
-+ * and wait for the carrier to indicate that the
-+ * modem is ready for us.
-+ */
-+ if (port->ops->get_mctrl(port) & TIOCM_CAR)
-+ break;
-+ }
-+
-+ up(&state->sem);
-+ schedule();
-+ down(&state->sem);
-+
-+ if (signal_pending(current))
-+ break;
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&info->open_wait, &wait);
-+
-+ state->count++;
-+ info->blocked_open--;
-+
-+ info->flags |= UIF_NORMAL_ACTIVE;
-+
-+ if (signal_pending(current))
-+ return -ERESTARTSYS;
-+
-+ if (!info->tty || tty_hung_up_p(filp))
-+ return -EAGAIN;
-+
-+ return 0;
-+}
-+
-+static struct uart_state *uart_get(struct uart_driver *drv, int line)
-+{
-+ struct uart_state *state;
-+
-+ down(&port_sem);
-+ state = drv->state + line;
-+ if (down_interruptible(&state->sem)) {
-+ state = ERR_PTR(-ERESTARTSYS);
-+ goto out;
-+ }
-+
-+ state->count++;
-+ if (!state->port) {
-+ state->count--;
-+ up(&state->sem);
-+ state = ERR_PTR(-ENXIO);
-+ goto out;
-+ }
-+
-+ if (!state->info) {
-+ state->info = kmalloc(sizeof(struct uart_info), GFP_KERNEL);
-+ if (state->info) {
-+ memset(state->info, 0, sizeof(struct uart_info));
-+ init_waitqueue_head(&state->info->open_wait);
-+ init_waitqueue_head(&state->info->delta_msr_wait);
-+
-+ /*
-+ * Link the info into the other structures.
-+ */
-+ state->port->info = state->info;
-+
-+ tasklet_init(&state->info->tlet, uart_tasklet_action,
-+ (unsigned long)state);
-+ } else {
-+ state->count--;
-+ up(&state->sem);
-+ state = ERR_PTR(-ENOMEM);
-+ }
-+ }
-+
-+ out:
-+ up(&port_sem);
-+ return state;
-+}
-+
-+/*
-+ * In 2.4.5, calls to uart_open are serialised by the BKL in
-+ * linux/fs/devices.c:chrdev_open()
-+ * Note that if this fails, then uart_close() _will_ be called.
-+ */
-+static int uart_open(struct tty_struct *tty, struct file *filp)
-+{
-+ struct uart_driver *drv = (struct uart_driver *)tty->driver.driver_state;
-+ struct uart_state *state;
-+ int retval, line = MINOR(tty->device) - tty->driver.minor_start;
-+
-+ BUG_ON(!kernel_locked());
-+ DPRINTK("uart_open(%d) called\n", line);
-+
-+ /*
-+ * tty->driver->num won't change, so we won't fail here with
-+ * tty->driver_data set to something non-NULL (and therefore
-+ * we won't get caught by uart_close()).
-+ */
-+ retval = -ENODEV;
-+ if (line >= tty->driver.num)
-+ goto fail;
-+
-+ if (!try_inc_mod_count(drv->owner))
-+ goto fail;
-+
-+ /*
-+ * We take the semaphore inside uart_get to guarantee that we won't
-+ * be re-entered while allocating the info structure, or while we
-+ * request any IRQs that the driver may need. This also has the nice
-+ * side-effect that it delays the action of uart_hangup, so we can
-+ * guarantee that info->tty will always contain something reasonable.
-+ */
-+ state = uart_get(drv, line);
-+ if (IS_ERR(state)) {
-+ retval = PTR_ERR(state);
-+ if (!tty->driver_data)
-+ goto out;
-+ else
-+ goto fail;
-+ }
-+
-+ /*
-+ * Once we set tty->driver_data here, we are guaranteed that
-+ * uart_close() will decrement the driver module use count.
-+ * Any failures from here onwards should not touch the count.
-+ */
-+ tty->driver_data = state;
-+ tty->low_latency = (state->port->flags & UPF_LOW_LATENCY) ? 1 : 0;
-+ tty->alt_speed = uart_get_altspeed(state->port);
-+ state->info->tty = tty;
-+
-+ /*
-+ * If the port is in the middle of closing, bail out now.
-+ */
-+ if (tty_hung_up_p(filp)) {
-+ retval = -EAGAIN;
-+ state->count--;
-+ up(&state->sem);
-+ goto fail;
-+ }
-+
-+ /*
-+ * Make sure the device is in D0 state.
-+ */
-+ if (state->count == 1)
-+ uart_change_pm(state, 0);
-+
-+ /*
-+ * Start up the serial port.
-+ */
-+ retval = uart_startup(state, 0);
-+
-+ /*
-+ * If we succeeded, wait until the port is ready.
-+ */
-+ if (retval == 0)
-+ retval = uart_block_til_ready(filp, state);
-+
-+ /*
-+ * If this is the first open to succeed, adjust things to suit.
-+ */
-+ if (retval == 0 && state->count == 1) {
-+ if (state->port->flags & UPF_SPLIT_TERMIOS) {
-+ if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
-+ *tty->termios = state->normal_termios;
-+ else
-+ *tty->termios = state->callout_termios;
-+ }
-+
-+ uart_update_termios(state);
-+
-+ state->info->session = current->session;
-+ state->info->pgrp = current->pgrp;
-+ }
-+ up(&state->sem);
-+
-+ return 0;
-+
-+ out:
-+ if (drv->owner)
-+ __MOD_DEC_USE_COUNT(drv->owner);
-+ fail:
-+ return retval;
-+}
-+
-+static const char *uart_type(struct uart_port *port)
-+{
-+ const char *str = NULL;
-+
-+ if (port->ops->type)
-+ str = port->ops->type(port);
-+
-+ if (!str)
-+ str = "unknown";
-+
-+ return str;
-+}
-+
-+#ifdef CONFIG_PROC_FS
-+
-+static int uart_line_info(char *buf, struct uart_driver *drv, int i)
-+{
-+ struct uart_state *state = drv->state + i;
-+ struct uart_port *port = state->port;
-+ char stat_buf[32];
-+ unsigned int status;
-+ int ret;
-+
-+ if (!port)
-+ return 0;
-+
-+ ret = sprintf(buf, "%d: uart:%s port:%08X irq:%d",
-+ port->line, uart_type(port),
-+ port->iobase, port->irq);
-+
-+ if (port->type == PORT_UNKNOWN) {
-+ strcat(buf, "\n");
-+ return ret + 1;
-+ }
-+
-+ status = port->ops->get_mctrl(port);
-+
-+ ret += sprintf(buf + ret, " tx:%d rx:%d",
-+ port->icount.tx, port->icount.rx);
-+ if (port->icount.frame)
-+ ret += sprintf(buf + ret, " fe:%d",
-+ port->icount.frame);
-+ if (port->icount.parity)
-+ ret += sprintf(buf + ret, " pe:%d",
-+ port->icount.parity);
-+ if (port->icount.brk)
-+ ret += sprintf(buf + ret, " brk:%d",
-+ port->icount.brk);
-+ if (port->icount.overrun)
-+ ret += sprintf(buf + ret, " oe:%d",
-+ port->icount.overrun);
-+
-+#define INFOBIT(bit,str) \
-+ if (port->mctrl & (bit)) \
-+ strcat(stat_buf, (str))
-+#define STATBIT(bit,str) \
-+ if (status & (bit)) \
-+ strcat(stat_buf, (str))
-+
-+ stat_buf[0] = '\0';
-+ stat_buf[1] = '\0';
-+ INFOBIT(TIOCM_RTS, "|RTS");
-+ STATBIT(TIOCM_CTS, "|CTS");
-+ INFOBIT(TIOCM_DTR, "|DTR");
-+ STATBIT(TIOCM_DSR, "|DSR");
-+ STATBIT(TIOCM_CAR, "|CD");
-+ STATBIT(TIOCM_RNG, "|RI");
-+ if (stat_buf[0])
-+ stat_buf[0] = ' ';
-+ strcat(stat_buf, "\n");
-+
-+ ret += sprintf(buf + ret, stat_buf);
-+ return ret;
-+}
-+
-+static int uart_read_proc(char *page, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ struct tty_driver *ttydrv = data;
-+ struct uart_driver *drv = ttydrv->driver_state;
-+ int i, len = 0, l;
-+ off_t begin = 0;
-+
-+ len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n",
-+ "", "", "");
-+ for (i = 0; i < drv->nr && len < PAGE_SIZE - 96; i++) {
-+ l = uart_line_info(page + len, drv, i);
-+ len += l;
-+ if (len + begin > off + count)
-+ goto done;
-+ if (len + begin < off) {
-+ begin += len;
-+ len = 0;
-+ }
-+ }
-+ *eof = 1;
-+ done:
-+ if (off >= len + begin)
-+ return 0;
-+ *start = page + (off - begin);
-+ return (count < begin + len - off) ? count : (begin + len - off);
-+}
-+#endif
-+
-+#ifdef CONFIG_SERIAL_CORE_CONSOLE
-+/*
-+ * Check whether an invalid uart number has been specified, and
-+ * if so, search for the first available port that does have
-+ * console support.
-+ */
-+struct uart_port * __init
-+uart_get_console(struct uart_port *ports, int nr, struct console *co)
-+{
-+ int idx = co->index;
-+
-+ if (idx < 0 || idx >= nr || (ports[idx].iobase == 0 &&
-+ ports[idx].membase == NULL))
-+ for (idx = 0; idx < nr; idx++)
-+ if (ports[idx].iobase != 0 ||
-+ ports[idx].membase != NULL)
-+ break;
-+
-+ co->index = idx;
-+
-+ return ports + idx;
-+}
-+
-+/**
-+ * uart_parse_options - Parse serial port baud/parity/bits/flow contro.
-+ * @options: pointer to option string
-+ * @baud: pointer to an 'int' variable for the baud rate.
-+ * @parity: pointer to an 'int' variable for the parity.
-+ * @bits: pointer to an 'int' variable for the number of data bits.
-+ * @flow: pointer to an 'int' variable for the flow control character.
-+ *
-+ * uart_parse_options decodes a string containing the serial console
-+ * options. The format of the string is <baud><parity><bits><flow>,
-+ * eg: 115200n8r
-+ */
-+void __init
-+uart_parse_options(char *options, int *baud, int *parity, int *bits, int *flow)
-+{
-+ char *s = options;
-+
-+ *baud = simple_strtoul(s, NULL, 10);
-+ while (*s >= '0' && *s <= '9')
-+ s++;
-+ if (*s)
-+ *parity = *s++;
-+ if (*s)
-+ *bits = *s++ - '0';
-+ if (*s)
-+ *flow = *s;
-+}
-+
-+struct baud_rates {
-+ unsigned int rate;
-+ unsigned int cflag;
-+};
-+
-+static struct baud_rates baud_rates[] = {
-+ { 921600, B921600 },
-+ { 460800, B460800 },
-+ { 230400, B230400 },
-+ { 115200, B115200 },
-+ { 57600, B57600 },
-+ { 38400, B38400 },
-+ { 19200, B19200 },
-+ { 9600, B9600 },
-+ { 4800, B4800 },
-+ { 2400, B2400 },
-+ { 1200, B1200 },
-+ { 0, B38400 }
-+};
-+
-+/**
-+ * uart_set_options - setup the serial console parameters
-+ * @port: pointer to the serial ports uart_port structure
-+ * @co: console pointer
-+ * @baud: baud rate
-+ * @parity: parity character - 'n' (none), 'o' (odd), 'e' (even)
-+ * @bits: number of data bits
-+ * @flow: flow control character - 'r' (rts)
-+ */
-+int __init
-+uart_set_options(struct uart_port *port, struct console *co,
-+ int baud, int parity, int bits, int flow)
-+{
-+ struct termios termios;
-+ unsigned int quot;
-+ int i;
-+
-+ memset(&termios, 0, sizeof(struct termios));
-+
-+ termios.c_cflag = CREAD | HUPCL | CLOCAL;
-+
-+ /*
-+ * Construct a cflag setting.
-+ */
-+ for (i = 0; baud_rates[i].rate; i++)
-+ if (baud_rates[i].rate <= baud)
-+ break;
-+
-+ termios.c_cflag |= baud_rates[i].cflag;
-+ baud = baud_rates[i].rate;
-+ if (baud == 0)
-+ baud = 38400;
-+
-+ if (bits == 7)
-+ termios.c_cflag |= CS7;
-+ else
-+ termios.c_cflag |= CS8;
-+
-+ switch (parity) {
-+ case 'o': case 'O':
-+ termios.c_cflag |= PARODD;
-+ /*fall through*/
-+ case 'e': case 'E':
-+ termios.c_cflag |= PARENB;
-+ break;
-+ }
-+
-+ if (flow == 'r')
-+ termios.c_cflag |= CRTSCTS;
-+
-+ quot = (port->uartclk / (16 * baud));
-+ port->ops->change_speed(port, termios.c_cflag, 0, quot);
-+ co->cflag = termios.c_cflag;
-+
-+ return 0;
-+}
-+
-+extern void ambauart_console_init(void);
-+extern void anakin_console_init(void);
-+extern void clps711xuart_console_init(void);
-+extern void sa1100_rs_console_init(void);
-+extern void serial8250_console_init(void);
-+extern void at91_console_init(void);
-+
-+/*
-+ * Central "initialise all serial consoles" container. Needs to be killed.
-+ */
-+void __init uart_console_init(void)
-+{
-+#ifdef CONFIG_SERIAL_AMBA_CONSOLE
-+ ambauart_console_init();
-+#endif
-+#ifdef CONFIG_SERIAL_ANAKIN_CONSOLE
-+ anakin_console_init();
-+#endif
-+#ifdef CONFIG_SERIAL_CLPS711X_CONSOLE
-+ clps711xuart_console_init();
-+#endif
-+#ifdef CONFIG_SERIAL_SA1100_CONSOLE
-+ sa1100_rs_console_init();
-+#endif
-+#ifdef CONFIG_SERIAL_AT91_CONSOLE
-+ at91_console_init();
-+#endif
-+#ifdef CONFIG_SERIAL_8250_CONSOLE
-+ serial8250_console_init();
-+#endif
-+#ifdef CONFIG_SERIAL_UART00_CONSOLE
-+ uart00_console_init();
-+#endif
-+}
-+#endif /* CONFIG_SERIAL_CORE_CONSOLE */
-+
-+static void uart_change_pm(struct uart_state *state, int pm_state)
-+{
-+ struct uart_port *port = state->port;
-+ if (port->ops->pm)
-+ port->ops->pm(port, pm_state, 0);
-+}
-+
-+#ifdef CONFIG_PM
-+int uart_suspend_port(struct uart_state *state)
-+{
-+ struct uart_port *port = state->port;
-+
-+ down(&state->sem);
-+ if (port) {
-+ /*
-+ * Disable the console device before suspending.
-+ */
-+ if (uart_console(port))
-+ port->cons->flags &= ~CON_ENABLED;
-+
-+ if (state->info && state->info->flags & UIF_INITIALIZED) {
-+ struct uart_ops *ops = port->ops;
-+
-+ spin_lock_irq(&port->lock);
-+ ops->stop_tx(port, 0);
-+ ops->set_mctrl(port, 0);
-+ ops->stop_rx(port);
-+ spin_unlock_irq(&port->lock);
-+
-+ /*
-+ * Wait for the transmitter to empty.
-+ */
-+ while (!ops->tx_empty(port)) {
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ schedule_timeout(10*HZ/1000);
-+ }
-+ set_current_state(TASK_RUNNING);
-+
-+ ops->shutdown(port);
-+ }
-+
-+ uart_change_pm(state, 3);
-+ }
-+
-+ up(&state->sem);
-+
-+ return 0;
-+}
-+
-+int uart_resume_port(struct uart_state *state)
-+{
-+ struct uart_port *port = state->port;
-+
-+ down(&state->sem);
-+ if (port) {
-+ uart_change_pm(state, 0);
-+
-+ /*
-+ * Re-enable the console device after suspending.
-+ */
-+ if (uart_console(port)) {
-+ uart_change_speed(state, NULL);
-+ port->cons->flags |= CON_ENABLED;
-+ }
-+
-+ if (state->info && state->info->flags & UIF_INITIALIZED) {
-+ struct uart_ops *ops = port->ops;
-+
-+ ops->set_mctrl(port, 0);
-+ ops->startup(port);
-+ uart_change_speed(state, NULL);
-+ spin_lock_irq(&port->lock);
-+ ops->set_mctrl(port, port->mctrl);
-+ ops->start_tx(port, 0);
-+ spin_unlock_irq(&port->lock);
-+ }
-+ }
-+
-+ up(&state->sem);
-+
-+ return 0;
-+}
-+
-+/*
-+ * Wakeup support.
-+ */
-+static int uart_pm_set_wakeup(struct uart_state *state, int data)
-+{
-+ int err = 0;
-+
-+ if (state->port->ops->set_wake)
-+ err = state->port->ops->set_wake(state->port, data);
-+
-+ return err;
-+}
-+
-+static int uart_pm(struct pm_dev *dev, pm_request_t rqst, void *data)
-+{
-+ struct uart_state *state = dev->data;
-+ int err = 0;
-+
-+ if (state->port && state->port->type == PORT_UNKNOWN)
-+ return 0;
-+
-+ switch (rqst) {
-+ case PM_SUSPEND:
-+ err = uart_suspend_port(state);
-+ break;
-+
-+ case PM_RESUME:
-+ err = uart_resume_port(state);
-+ break;
-+
-+ case PM_SET_WAKEUP:
-+ err = uart_pm_set_wakeup(state, (int)data);
-+ break;
-+ }
-+ return err;
-+}
-+#endif
-+
-+static inline void
-+uart_report_port(struct uart_driver *drv, struct uart_port *port)
-+{
-+ printk("%s%d at ", drv->normal_name, port->line);
-+ switch (port->iotype) {
-+ case UPIO_PORT:
-+ printk("I/O 0x%x", port->iobase);
-+ break;
-+ case UPIO_HUB6:
-+ printk("I/O 0x%x offset 0x%x", port->iobase, port->hub6);
-+ break;
-+ case UPIO_MEM:
-+ printk("MMIO 0x%lx", port->mapbase);
-+ break;
-+ }
-+ printk(" (irq = %d) is a %s\n", port->irq, uart_type(port));
-+}
-+
-+static void
-+uart_configure_port(struct uart_driver *drv, struct uart_state *state,
-+ struct uart_port *port)
-+{
-+ unsigned int flags;
-+
-+ /*
-+ * If there isn't a port here, don't do anything further.
-+ */
-+ if (!port->iobase && !port->mapbase && !port->membase)
-+ return;
-+
-+ /*
-+ * Now do the auto configuration stuff. Note that config_port
-+ * is expected to claim the resources and map the port for us.
-+ */
-+ flags = UART_CONFIG_TYPE;
-+ if (port->flags & UPF_AUTO_IRQ)
-+ flags |= UART_CONFIG_IRQ;
-+ if (port->flags & UPF_BOOT_AUTOCONF) {
-+ port->type = PORT_UNKNOWN;
-+ port->ops->config_port(port, flags);
-+ }
-+
-+ if (port->type != PORT_UNKNOWN) {
-+ unsigned long flags;
-+
-+ uart_report_port(drv, port);
-+
-+ /*
-+ * Ensure that the modem control lines are de-activated.
-+ * We probably don't need a spinlock around this, but
-+ */
-+ spin_lock_irqsave(&port->lock, flags);
-+ port->ops->set_mctrl(port, 0);
-+ spin_unlock_irqrestore(&port->lock, flags);
-+
-+ /*
-+ * Power down all ports by default, except the
-+ * console if we have one.
-+ */
-+ if (!uart_console(port))
-+ uart_change_pm(state, 3);
-+ }
-+}
-+
-+/*
-+ * This reverses the effects of uart_configure_port, hanging up the
-+ * port before removal.
-+ */
-+static void
-+uart_unconfigure_port(struct uart_driver *drv, struct uart_state *state)
-+{
-+ struct uart_port *port = state->port;
-+ struct uart_info *info = state->info;
-+
-+ if (info && info->tty)
-+ tty_vhangup(info->tty);
-+
-+ down(&state->sem);
-+
-+ state->info = NULL;
-+
-+ /*
-+ * Free the port IO and memory resources, if any.
-+ */
-+ if (port->type != PORT_UNKNOWN)
-+ port->ops->release_port(port);
-+
-+ /*
-+ * Indicate that there isn't a port here anymore.
-+ */
-+ port->type = PORT_UNKNOWN;
-+
-+ /*
-+ * Kill the tasklet, and free resources.
-+ */
-+ if (info) {
-+ tasklet_kill(&info->tlet);
-+ kfree(info);
-+ }
-+
-+ up(&state->sem);
-+}
-+
-+/**
-+ * uart_register_driver - register a driver with the uart core layer
-+ * @drv: low level driver structure
-+ *
-+ * Register a uart driver with the core driver. We in turn register
-+ * with the tty layer, and initialise the core driver per-port state.
-+ *
-+ * We have a proc file in /proc/tty/driver which is named after the
-+ * normal driver.
-+ *
-+ * drv->port should be NULL, and the per-port structures should be
-+ * registered using uart_add_one_port after this call has succeeded.
-+ */
-+int uart_register_driver(struct uart_driver *drv)
-+{
-+ struct tty_driver *normal, *callout;
-+ int i, retval;
-+
-+ BUG_ON(drv->state);
-+
-+ /*
-+ * Maybe we should be using a slab cache for this, especially if
-+ * we have a large number of ports to handle. Note that we also
-+ * allocate space for an integer for reference counting.
-+ */
-+ drv->state = kmalloc(sizeof(struct uart_state) * drv->nr +
-+ sizeof(int), GFP_KERNEL);
-+ retval = -ENOMEM;
-+ if (!drv->state)
-+ goto out;
-+
-+ memset(drv->state, 0, sizeof(struct uart_state) * drv->nr +
-+ sizeof(int));
-+
-+ normal = drv->normal_driver;
-+ callout = drv->callout_driver;
-+
-+ normal->magic = TTY_DRIVER_MAGIC;
-+ normal->driver_name = drv->normal_name;
-+ normal->name = drv->normal_name;
-+ normal->major = drv->normal_major;
-+ normal->minor_start = drv->minor;
-+ normal->num = drv->nr;
-+ normal->type = TTY_DRIVER_TYPE_SERIAL;
-+ normal->subtype = SERIAL_TYPE_NORMAL;
-+ normal->init_termios = tty_std_termios;
-+ normal->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-+ normal->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
-+ normal->refcount = (int *)(drv->state + drv->nr);
-+ normal->table = drv->table;
-+ normal->termios = drv->termios;
-+ normal->termios_locked = drv->termios_locked;
-+ normal->driver_state = drv;
-+
-+ normal->open = uart_open;
-+ normal->close = uart_close;
-+ normal->write = uart_write;
-+ normal->put_char = uart_put_char;
-+ normal->flush_chars = uart_flush_chars;
-+ normal->write_room = uart_write_room;
-+ normal->chars_in_buffer = uart_chars_in_buffer;
-+ normal->flush_buffer = uart_flush_buffer;
-+ normal->ioctl = uart_ioctl;
-+ normal->throttle = uart_throttle;
-+ normal->unthrottle = uart_unthrottle;
-+ normal->send_xchar = uart_send_xchar;
-+ normal->set_termios = uart_set_termios;
-+ normal->stop = uart_stop;
-+ normal->start = uart_start;
-+ normal->hangup = uart_hangup;
-+ normal->break_ctl = uart_break_ctl;
-+ normal->wait_until_sent = uart_wait_until_sent;
-+#ifdef CONFIG_PROC_FS
-+ normal->read_proc = uart_read_proc;
-+#endif
-+
-+ /*
-+ * The callout device is just like the normal device except for
-+ * the major number and the subtype code.
-+ */
-+ *callout = *normal;
-+ callout->name = drv->callout_name;
-+ callout->major = drv->callout_major;
-+ callout->subtype = SERIAL_TYPE_CALLOUT;
-+ callout->read_proc = NULL;
-+ callout->proc_entry = NULL;
-+
-+ /*
-+ * Initialise the UART state(s).
-+ */
-+ for (i = 0; i < drv->nr; i++) {
-+ struct uart_state *state = drv->state + i;
-+
-+ state->callout_termios = callout->init_termios;
-+ state->normal_termios = normal->init_termios;
-+ state->close_delay = 5 * HZ / 10;
-+ state->closing_wait = 30 * HZ;
-+
-+ init_MUTEX(&state->sem);
-+ }
-+
-+ retval = tty_register_driver(normal);
-+ if (retval)
-+ goto out;
-+
-+ retval = tty_register_driver(callout);
-+ if (retval)
-+ tty_unregister_driver(normal);
-+
-+ out:
-+ if (retval < 0) {
-+ kfree(drv->state);
-+ }
-+ return retval;
-+}
-+
-+/**
-+ * uart_unregister_driver - remove a driver from the uart core layer
-+ * @drv: low level driver structure
-+ *
-+ * Remove all references to a driver from the core driver. The low
-+ * level driver must have removed all its ports via the
-+ * uart_remove_one_port() if it registered them with uart_add_one_port().
-+ * (ie, drv->port == NULL)
-+ */
-+void uart_unregister_driver(struct uart_driver *drv)
-+{
-+ tty_unregister_driver(drv->normal_driver);
-+ tty_unregister_driver(drv->callout_driver);
-+
-+ kfree(drv->state);
-+ drv->state = NULL;
-+}
-+
-+/**
-+ * uart_add_one_port - attach a driver-defined port structure
-+ * @drv: pointer to the uart low level driver structure for this port
-+ * @port: uart port structure to use for this port.
-+ *
-+ * This allows the driver to register its own uart_port structure
-+ * with the core driver. The main purpose is to allow the low
-+ * level uart drivers to expand uart_port, rather than having yet
-+ * more levels of structures.
-+ */
-+int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
-+{
-+ struct uart_state *state;
-+ int ret = 0;
-+
-+ BUG_ON(in_interrupt());
-+
-+ if (port->line >= drv->nr)
-+ return -EINVAL;
-+
-+ state = drv->state + port->line;
-+
-+ down(&port_sem);
-+ if (state->port) {
-+ ret = -EINVAL;
-+ goto out;
-+ }
-+
-+ state->port = port;
-+
-+ spin_lock_init(&port->lock);
-+ port->cons = drv->cons;
-+ port->info = state->info;
-+
-+ uart_configure_port(drv, state, port);
-+
-+ /*
-+ * Register the port whether it's detected or not. This allows
-+ * setserial to be used to alter this ports parameters.
-+ */
-+ tty_register_devfs(drv->normal_driver, 0, drv->minor + port->line);
-+ tty_register_devfs(drv->callout_driver, 0, drv->minor + port->line);
-+
-+#ifdef CONFIG_PM
-+ port->cons = drv->cons;
-+ state->pm = pm_register(PM_SYS_DEV, PM_SYS_COM, uart_pm);
-+ if (state->pm)
-+ state->pm->data = state;
-+#endif
-+
-+ out:
-+ up(&port_sem);
-+
-+ return ret;
-+}
-+
-+/**
-+ * uart_remove_one_port - detach a driver defined port structure
-+ * @drv: pointer to the uart low level driver structure for this port
-+ * @port: uart port structure for this port
-+ *
-+ * This unhooks (and hangs up) the specified port structure from the
-+ * core driver. No further calls will be made to the low-level code
-+ * for this port.
-+ */
-+int uart_remove_one_port(struct uart_driver *drv, struct uart_port *port)
-+{
-+ struct uart_state *state = drv->state + port->line;
-+
-+ BUG_ON(in_interrupt());
-+
-+ if (state->port != port)
-+ printk(KERN_ALERT "Removing wrong port: %p != %p\n",
-+ state->port, port);
-+
-+ down(&port_sem);
-+
-+ pm_unregister(state->pm);
-+
-+ /*
-+ * Remove the devices from devfs
-+ */
-+ tty_unregister_devfs(drv->normal_driver, drv->minor + port->line);
-+ tty_unregister_devfs(drv->callout_driver, drv->minor + port->line);
-+
-+ uart_unconfigure_port(drv, state);
-+ state->port = NULL;
-+ up(&port_sem);
-+
-+ return 0;
-+}
-+
-+/*
-+ * Are the two ports equivalent?
-+ */
-+static int uart_match_port(struct uart_port *port1, struct uart_port *port2)
-+{
-+ if (port1->iotype != port2->iotype)
-+ return 0;
-+
-+ switch (port1->iotype) {
-+ case UPIO_PORT:
-+ return (port1->iobase == port2->iobase);
-+ case UPIO_HUB6:
-+ return (port1->iobase == port2->iobase) &&
-+ (port1->hub6 == port2->hub6);
-+ case UPIO_MEM:
-+ return (port1->membase == port2->membase);
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * Try to find an unused uart_state slot for a port.
-+ */
-+static struct uart_state *
-+uart_find_match_or_unused(struct uart_driver *drv, struct uart_port *port)
-+{
-+ int i;
-+
-+ /*
-+ * First, find a port entry which matches. Note: if we do
-+ * find a matching entry, and it has a non-zero use count,
-+ * then we can't register the port.
-+ */
-+ for (i = 0; i < drv->nr; i++)
-+ if (uart_match_port(drv->state[i].port, port))
-+ return &drv->state[i];
-+
-+ /*
-+ * We didn't find a matching entry, so look for the first
-+ * free entry. We look for one which hasn't been previously
-+ * used (indicated by zero iobase).
-+ */
-+ for (i = 0; i < drv->nr; i++)
-+ if (drv->state[i].port->type == PORT_UNKNOWN &&
-+ drv->state[i].port->iobase == 0 &&
-+ drv->state[i].count == 0)
-+ return &drv->state[i];
-+
-+ /*
-+ * That also failed. Last resort is to find any currently
-+ * entry which doesn't have a real port associated with it.
-+ */
-+ for (i = 0; i < drv->nr; i++)
-+ if (drv->state[i].port->type == PORT_UNKNOWN &&
-+ drv->state[i].count == 0)
-+ return &drv->state[i];
-+
-+ return NULL;
-+}
-+
-+/**
-+ * uart_register_port: register uart settings with a port
-+ * @drv: pointer to the uart low level driver structure for this port
-+ * @port: uart port structure describing the port
-+ *
-+ * Register UART settings with the specified low level driver. Detect
-+ * the type of the port if UPF_BOOT_AUTOCONF is set, and detect the
-+ * IRQ if UPF_AUTO_IRQ is set.
-+ *
-+ * We try to pick the same port for the same IO base address, so that
-+ * when a modem is plugged in, unplugged and plugged back in, it gets
-+ * allocated the same port.
-+ *
-+ * Returns negative error, or positive line number.
-+ */
-+int uart_register_port(struct uart_driver *drv, struct uart_port *port)
-+{
-+ struct uart_state *state;
-+ int ret;
-+
-+ down(&port_sem);
-+
-+ state = uart_find_match_or_unused(drv, port);
-+
-+ if (state) {
-+ /*
-+ * Ok, we've found a line that we can use.
-+ *
-+ * If we find a port that matches this one, and it appears
-+ * to be in-use (even if it doesn't have a type) we shouldn't
-+ * alter it underneath itself - the port may be open and
-+ * trying to do useful work.
-+ */
-+ if (uart_users(state) != 0) {
-+ ret = -EBUSY;
-+ goto out;
-+ }
-+
-+ /*
-+ * If the port is already initialised, don't touch it.
-+ */
-+ if (state->port->type == PORT_UNKNOWN) {
-+ state->port->iobase = port->iobase;
-+ state->port->membase = port->membase;
-+ state->port->irq = port->irq;
-+ state->port->uartclk = port->uartclk;
-+ state->port->fifosize = port->fifosize;
-+ state->port->regshift = port->regshift;
-+ state->port->iotype = port->iotype;
-+ state->port->flags = port->flags;
-+ state->port->line = state - drv->state;
-+ state->port->mapbase = port->mapbase;
-+
-+ uart_configure_port(drv, state, state->port);
-+ }
-+
-+ ret = state->port->line;
-+ } else
-+ ret = -ENOSPC;
-+ out:
-+ up(&port_sem);
-+ return ret;
-+}
-+
-+/**
-+ * uart_unregister_port - de-allocate a port
-+ * @drv: pointer to the uart low level driver structure for this port
-+ * @line: line index previously returned from uart_register_port()
-+ *
-+ * Hang up the specified line associated with the low level driver,
-+ * and mark the port as unused.
-+ */
-+void uart_unregister_port(struct uart_driver *drv, int line)
-+{
-+ struct uart_state *state;
-+
-+ if (line < 0 || line >= drv->nr) {
-+ printk(KERN_ERR "Attempt to unregister %s%d\n",
-+ drv->normal_name, line);
-+ return;
-+ }
-+
-+ state = drv->state + line;
-+
-+ down(&port_sem);
-+ uart_unconfigure_port(drv, state);
-+ up(&port_sem);
-+}
-+
-+EXPORT_SYMBOL(uart_write_wakeup);
-+EXPORT_SYMBOL(uart_register_driver);
-+EXPORT_SYMBOL(uart_unregister_driver);
-+EXPORT_SYMBOL(uart_register_port);
-+EXPORT_SYMBOL(uart_unregister_port);
-+EXPORT_SYMBOL(uart_add_one_port);
-+EXPORT_SYMBOL(uart_remove_one_port);
-+
-+MODULE_DESCRIPTION("Serial driver core");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/serial/omaha.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,584 @@
-+/*
-+ * linux/drivers/char/omaha.c
-+ *
-+ * Driver for Omaha serial port
-+ *
-+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
-+ *
-+ * Copyright 1999-2002 ARM Limited
-+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * $Id$
-+ *
-+ * This is a generic driver for ARM AMBA-type serial ports. They
-+ * have a lot of 16550-like features, but are not register compatable.
-+ * Note that although they do have CTS, DCD and DSR inputs, they do
-+ * not have an RI input, nor do they have DTR or RTS outputs. If
-+ * required, these have to be supplied via some other means (eg, GPIO)
-+ * and hooked into this driver.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/tty.h>
-+#include <linux/tty_flip.h>
-+#include <linux/major.h>
-+#include <linux/string.h>
-+#include <linux/fcntl.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/circ_buf.h>
-+#include <linux/serial.h>
-+#include <linux/console.h>
-+#include <linux/sysrq.h>
-+
-+#include <asm/system.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+#include <asm/bitops.h>
-+
-+#if defined(CONFIG_SERIAL_OMAHA_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-+#define SUPPORT_SYSRQ
-+#endif
-+
-+#include <linux/serial_core.h>
-+
-+#include <asm/hardware/serial_omaha.h>
-+
-+#define UART_NR 1
-+
-+#define SERIAL_OMAHA_MAJOR 204
-+#define SERIAL_OMAHA_MINOR 32
-+#define SERIAL_OMAHA_NR UART_NR
-+
-+#define CALLOUT_OMAHA_NAME "cuaom"
-+#define CALLOUT_OMAHA_MAJOR 205
-+#define CALLOUT_OMAHA_MINOR 32
-+#define CALLOUT_OMAHA_NR UART_NR
-+
-+static struct tty_driver normal, callout;
-+static struct tty_struct *omaha_table[UART_NR];
-+static struct termios *omaha_termios[UART_NR], *omaha_termios_locked[UART_NR];
-+#ifdef SUPPORT_SYSRQ
-+static struct console omaha_console;
-+#endif
-+
-+#define OMAHA_ISR_PASS_LIMIT 256
-+
-+/*
-+ * Access macros for the Omaha UARTs
-+ */
-+
-+#define UART_GET_FR(p) readb((p)->membase + OMAHA_UTRSTAT)
-+#define UART_GET_CHAR(p) readb((p)->membase + OMAHA_URXH)
-+#define UART_PUT_CHAR(p, c) writel((c), (p)->membase + OMAHA_UTXH)
-+#define UART_GET_RSR(p) readb((p)->membase + OMAHA_UERSTAT)
-+#define UART_FIFO_STATUS(p) (readl((p)->membase + OMAHA_UFSTAT))
-+#define UART_RX_DATA(s) (((s) & OMAHA_RXFF_CNT) != 0)
-+#define UART_TX_DATA(s) (!((s) & OMAHA_TXFF))
-+#define UART_TX_READY(s) (((s) & OMAHA_UTX_EMPTY))
-+#define UART_TX_EMPTY(p) ((UART_GET_FR(p) & OMAHA_UTXEMPTY) != 0)
-+
-+#define UART_DUMMY_RSR_RX 256
-+#define UART_PORT_SIZE 64
-+
-+#define RX_IRQ(port) ((port)->irq)
-+#define TX_IRQ(port) ((port)->irq + 5)
-+
-+/*
-+ * Our private driver data mappings.
-+ */
-+#define drv_old_status driver_priv
-+
-+static void omahauart_stop_tx(struct uart_port *port, u_int from_tty)
-+{
-+ disable_irq(TX_IRQ(port));
-+}
-+
-+static void omahauart_start_tx(struct uart_port *port, u_int nonempty, u_int from_tty)
-+{
-+ if (nonempty)
-+ enable_irq(TX_IRQ(port));
-+}
-+
-+static void omahauart_stop_rx(struct uart_port *port)
-+{
-+ disable_irq(RX_IRQ(port));
-+}
-+
-+static void omahauart_enable_ms(struct uart_port *port)
-+{
-+ // Do nothing...
-+}
-+
-+static void
-+#ifdef SUPPORT_SYSRQ
-+omahauart_rx_chars(struct uart_info *info, struct pt_regs *regs)
-+#else
-+omahauart_rx_chars(struct uart_info *info)
-+#endif
-+{
-+ struct tty_struct *tty = info->tty;
-+ volatile unsigned int status, data, ch, rsr, max_count = 256;
-+ struct uart_port *port = info->port;
-+
-+ status = UART_FIFO_STATUS(port);
-+ while (UART_RX_DATA(status) && max_count--) {
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-+ tty->flip.tqueue.routine((void *)tty);
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
-+ printk(KERN_WARNING "TTY_DONT_FLIP set\n");
-+ return;
-+ }
-+ }
-+
-+ ch = UART_GET_CHAR(port);
-+
-+ *tty->flip.char_buf_ptr = ch;
-+ *tty->flip.flag_buf_ptr = TTY_NORMAL;
-+ port->icount.rx++;
-+
-+ /*
-+ * Note that the error handling code is
-+ * out of the main execution path
-+ */
-+ rsr = UART_GET_RSR(port) | UART_DUMMY_RSR_RX;
-+ if (rsr & 0xf) {
-+ if (rsr & OMAHA_UART_BREAK) {
-+ rsr &= ~(OMAHA_UART_FRAME | OMAHA_UART_PARITY);
-+ port->icount.brk++;
-+ if (uart_handle_break(info, &omaha_console))
-+ goto ignore_char;
-+ } else if (rsr & OMAHA_UART_PARITY)
-+ port->icount.parity++;
-+ else if (rsr & OMAHA_UART_FRAME)
-+ port->icount.frame++;
-+ if (rsr & OMAHA_UART_OVERRUN)
-+ port->icount.overrun++;
-+
-+ rsr &= port->read_status_mask;
-+
-+ if (rsr & OMAHA_UART_BREAK)
-+ *tty->flip.flag_buf_ptr = TTY_BREAK;
-+ else if (rsr & OMAHA_UART_PARITY)
-+ *tty->flip.flag_buf_ptr = TTY_PARITY;
-+ else if (rsr & OMAHA_UART_FRAME)
-+ *tty->flip.flag_buf_ptr = TTY_FRAME;
-+ }
-+
-+ if (uart_handle_sysrq_char(info, ch, regs))
-+ goto ignore_char;
-+
-+ if ((rsr & port->ignore_status_mask) == 0) {
-+ tty->flip.flag_buf_ptr++;
-+ tty->flip.char_buf_ptr++;
-+ tty->flip.count++;
-+ }
-+ if ((rsr & OMAHA_UART_OVERRUN) &&
-+ tty->flip.count < TTY_FLIPBUF_SIZE) {
-+ /*
-+ * Overrun is special, since it's reported
-+ * immediately, and doesn't affect the current
-+ * character
-+ */
-+ *tty->flip.char_buf_ptr++ = 0;
-+ *tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
-+ tty->flip.count++;
-+ }
-+ ignore_char:
-+ status = UART_FIFO_STATUS(port);
-+ }
-+ tty_flip_buffer_push(tty);
-+ return;
-+}
-+
-+static void omahauart_tx_chars(struct uart_info *info)
-+{
-+ struct uart_port *port = info->port;
-+ volatile unsigned int status;
-+
-+ if (port->x_char) {
-+ UART_PUT_CHAR(port, port->x_char);
-+ port->icount.tx++;
-+ port->x_char = 0;
-+ return;
-+ }
-+ if (info->xmit.head == info->xmit.tail
-+ || info->tty->stopped
-+ || info->tty->hw_stopped) {
-+ omahauart_stop_tx(port, 0);
-+ return;
-+ }
-+
-+ status = UART_FIFO_STATUS(info->port);
-+
-+ // FIll FIFO as far as possible
-+ while(UART_TX_DATA(UART_FIFO_STATUS(info->port)))
-+ {
-+ UART_PUT_CHAR(port, info->xmit.buf[info->xmit.tail]);
-+ info->xmit.tail = (info->xmit.tail + 1) & (UART_XMIT_SIZE - 1);
-+ port->icount.tx++;
-+ if (info->xmit.head == info->xmit.tail)
-+ break;
-+ }
-+
-+ if (CIRC_CNT(info->xmit.head, info->xmit.tail, UART_XMIT_SIZE) <
-+ WAKEUP_CHARS)
-+ uart_event(info, EVT_WRITE_WAKEUP);
-+
-+ if (info->xmit.head == info->xmit.tail)
-+ omahauart_stop_tx(info->port, 0);
-+}
-+
-+static void omahauart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct uart_info *info = dev_id;
-+ volatile unsigned int status, pass_counter = OMAHA_ISR_PASS_LIMIT;
-+
-+ status = UART_FIFO_STATUS(info->port);
-+ do {
-+ // TX if FIFO not full
-+ if (UART_TX_DATA(status))
-+ omahauart_tx_chars(info);
-+
-+ if (pass_counter-- == 0)
-+ break;
-+
-+ status = UART_FIFO_STATUS(info->port);
-+ } while (UART_TX_DATA(status));
-+}
-+
-+static void omahauart_int_rx(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct uart_info *info = dev_id;
-+ volatile unsigned int status, pass_counter = OMAHA_ISR_PASS_LIMIT;
-+
-+ status = UART_FIFO_STATUS(info->port);
-+ do {
-+ if (UART_RX_DATA(status))
-+#ifdef SUPPORT_SYSRQ
-+ omahauart_rx_chars(info, regs);
-+#else
-+ omahauart_rx_chars(info);
-+#endif
-+
-+ if (pass_counter-- == 0)
-+ break;
-+
-+ status = UART_FIFO_STATUS(info->port);
-+ } while (UART_RX_DATA(status));
-+}
-+
-+static u_int omahauart_tx_empty(struct uart_port *port)
-+{
-+ return UART_FIFO_STATUS(port) ? 0 : TIOCSER_TEMT;
-+}
-+
-+static int omahauart_get_mctrl(struct uart_port *port)
-+{
-+ // Report no errors.
-+
-+ return 0;
-+}
-+
-+static void omahauart_set_mctrl(struct uart_port *port, u_int mctrl)
-+{
-+ // Do nothing.
-+}
-+
-+static void omahauart_break_ctl(struct uart_port *port, int break_state)
-+{
-+ // Do nothing.
-+}
-+
-+static int omahauart_startup(struct uart_port *port, struct uart_info *info)
-+{
-+ unsigned int tmp;
-+ int retval;
-+
-+ /*
-+ * Allocate the IRQs
-+ */
-+ retval = request_irq(TX_IRQ(port), omahauart_int_tx, 0, "omaha_uart_tx", info);
-+ if (retval)
-+ return retval;
-+
-+ retval = request_irq(RX_IRQ(port), omahauart_int_rx, 0, "omaha_uart_rx", info);
-+
-+ if (retval)
-+ {
-+ free_irq(TX_IRQ(port), info);
-+ return retval;
-+ }
-+
-+ /*
-+ * initialise the old status of the modem signals
-+ */
-+ info->drv_old_status = 0;
-+
-+ // Clear all errors
-+ writel(0, port->membase + OMAHA_UERSTAT);
-+
-+ // Enable FIFO, 16-byte watermark, also do reset (auto-clearing)
-+ writel(0xF7, port->membase + OMAHA_UFCON);
-+
-+ // Level driven TX/RX ints, with rx timeout enabled
-+ tmp = readl(port->membase + OMAHA_UCON);
-+ tmp |= 0x280; // rx is pulse driven...
-+ writel(tmp, port->membase + OMAHA_UCON);
-+
-+ return 0;
-+}
-+
-+static void omahauart_shutdown(struct uart_port *port, struct uart_info *info)
-+{
-+ /*
-+ * Free the interrupt
-+ */
-+ free_irq(TX_IRQ(port), info); /* TX interrupt */
-+ free_irq(RX_IRQ(port), info); /* RX interrupt */
-+
-+}
-+
-+static void omahauart_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot)
-+{
-+ // Do nothing.
-+}
-+
-+static const char *omahauart_type(struct uart_port *port)
-+{
-+ return port->type == PORT_OMAHA ? "OMAHA" : NULL;
-+}
-+
-+/*
-+ * Release the memory region(s) being used by 'port'
-+ */
-+static void omahauart_release_port(struct uart_port *port)
-+{
-+ release_mem_region(port->mapbase, UART_PORT_SIZE);
-+}
-+
-+/*
-+ * Request the memory region(s) being used by 'port'
-+ */
-+static int omahauart_request_port(struct uart_port *port)
-+{
-+ return request_mem_region(port->mapbase, UART_PORT_SIZE, "serial_omaha")
-+ != NULL ? 0 : -EBUSY;
-+}
-+
-+/*
-+ * Configure/autoconfigure the port.
-+ */
-+static void omahauart_config_port(struct uart_port *port, int flags)
-+{
-+ if (flags & UART_CONFIG_TYPE) {
-+ port->type = PORT_OMAHA;
-+ omahauart_request_port(port);
-+ }
-+}
-+
-+/*
-+ * verify the new serial_struct (for TIOCSSERIAL).
-+ */
-+static int omahauart_verify_port(struct uart_port *port, struct serial_struct *ser)
-+{
-+ int ret = 0;
-+ if (ser->type != PORT_UNKNOWN && ser->type != PORT_OMAHA)
-+ ret = -EINVAL;
-+ if (ser->irq < 0 || ser->irq >= NR_IRQS)
-+ ret = -EINVAL;
-+ if (ser->baud_base < 9600)
-+ ret = -EINVAL;
-+ return ret;
-+}
-+
-+static struct uart_ops omaha_pops = {
-+ .tx_empty = omahauart_tx_empty,
-+ .set_mctrl = omahauart_set_mctrl,
-+ .get_mctrl = omahauart_get_mctrl,
-+ .stop_tx = omahauart_stop_tx,
-+ .start_tx = omahauart_start_tx,
-+ .stop_rx = omahauart_stop_rx,
-+ .enable_ms = omahauart_enable_ms,
-+ .break_ctl = omahauart_break_ctl,
-+ .startup = omahauart_startup,
-+ .shutdown = omahauart_shutdown,
-+ .change_speed = omahauart_change_speed,
-+ .type = omahauart_type,
-+ .release_port = omahauart_release_port,
-+ .request_port = omahauart_request_port,
-+ .config_port = omahauart_config_port,
-+ .verify_port = omahauart_verify_port,
-+};
-+
-+static struct uart_port omaha_ports[UART_NR] = {
-+ {
-+ .membase = (void *)IO_ADDRESS(OMAHA_UART0_BASE),
-+ .mapbase = OMAHA_UART0_BASE,
-+ .iotype = SERIAL_IO_MEM,
-+ .irq = OMAHA_INT_URXD0,
-+ .uartclk = 10000000,
-+ .fifosize = 8,
-+ .unused = { 4, 5 }, /*Udriver_priv: PORT_CTRLS(5, 4), */
-+ .ops = &omaha_pops,
-+ .flags = ASYNC_BOOT_AUTOCONF,
-+ }
-+};
-+
-+#ifdef CONFIG_SERIAL_OMAHA_CONSOLE
-+static void omahauart_console_write(struct console *co, const char *s, u_int count)
-+{
-+ struct uart_port *port = omaha_ports + co->index;
-+ unsigned int status;
-+ int i;
-+
-+ /*
-+ * First save the CR then disable the interrupts
-+ */
-+
-+ /*
-+ * Now, do each character
-+ */
-+ for (i = 0; i < count; i++) {
-+ do {
-+ status = UART_GET_FR(port);
-+ } while ((status & OMAHA_UTX_EMPTY) == 0);
-+ UART_PUT_CHAR(port, s[i]);
-+ if (s[i] == '\n') {
-+ do {
-+ status = UART_GET_FR(port);
-+ } while ((status & OMAHA_UTX_EMPTY) == 0);
-+ UART_PUT_CHAR(port, '\r');
-+ }
-+ }
-+
-+ /*
-+ * Finally, wait for transmitter to become empty
-+ * and restore the TCR
-+ */
-+ do {
-+ status = UART_GET_FR(port);
-+ } while ((status & OMAHA_UTX_EMPTY) == 0);
-+}
-+
-+static kdev_t omahauart_console_device(struct console *co)
-+{
-+ return MKDEV(SERIAL_OMAHA_MAJOR, SERIAL_OMAHA_MINOR + co->index);
-+}
-+
-+static int omahauart_console_wait_key(struct console *co)
-+{
-+ struct uart_port *port = omaha_ports + co->index;
-+ unsigned int status;
-+
-+ do {
-+ status = UART_FIFO_STATUS(port);
-+ } while (!UART_RX_DATA(status));
-+ return UART_GET_CHAR(port);
-+}
-+
-+static void __init
-+omahauart_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
-+{
-+ // Do nothing.
-+}
-+
-+static int __init omahauart_console_setup(struct console *co, char *options)
-+{
-+ struct uart_port *port;
-+ int baud = 38400;
-+ int bits = 8;
-+ int parity = 'n';
-+ int flow = 'n';
-+
-+ /*
-+ * Check whether an invalid uart number has been specified, and
-+ * if so, search for the first available port that does have
-+ * console support.
-+ */
-+ port = uart_get_console(omaha_ports, UART_NR, co);
-+
-+ if (options)
-+ uart_parse_options(options, &baud, &parity, &bits, &flow);
-+ else
-+ omahauart_console_get_options(port, &baud, &parity, &bits);
-+
-+ return uart_set_options(port, co, baud, parity, bits, flow);
-+}
-+
-+static struct console omaha_console = {
-+ .write = omahauart_console_write,
-+ .device = omahauart_console_device,
-+ .wait_key = omahauart_console_wait_key,
-+ .setup = omahauart_console_setup,
-+ .flags = CON_PRINTBUFFER,
-+ .index = -1,
-+};
-+
-+void __init omahauart_console_init(void)
-+{
-+ register_console(&omaha_console);
-+}
-+
-+#define OMAHA_CONSOLE &omaha_console
-+#else
-+#define OMAHA_CONSOLE NULL
-+#endif
-+
-+static struct uart_driver omaha_reg = {
-+ .owner = THIS_MODULE,
-+ .normal_major = SERIAL_OMAHA_MAJOR,
-+#ifdef CONFIG_DEVFS_FS
-+ .normal_name = "ttyOM%d",
-+ .callout_name = "cuaom%d",
-+#else
-+ .normal_name = "ttyOM",
-+ .callout_name = "cuaom",
-+#endif
-+ .normal_driver = &normal,
-+ .callout_major = CALLOUT_OMAHA_MAJOR,
-+ .callout_driver = &callout,
-+ .table = omaha_table,
-+ .termios = omaha_termios,
-+ .termios_locked = omaha_termios_locked,
-+ .minor = SERIAL_OMAHA_MINOR,
-+ .nr = UART_NR,
-+ .port = omaha_ports,
-+ .cons = OMAHA_CONSOLE,
-+};
-+
-+static int __init omahauart_init(void)
-+{
-+ return uart_register_driver(&omaha_reg);
-+}
-+
-+static void __exit omahauart_exit(void)
-+{
-+ uart_unregister_driver(&omaha_reg);
-+}
-+
-+module_init(omahauart_init);
-+module_exit(omahauart_exit);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/serial/sa1100.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,904 @@
-+/*
-+ * linux/drivers/char/serial_sa1100.c
-+ *
-+ * Driver for SA11x0 serial ports
-+ *
-+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
-+ *
-+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * $Id$
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/tty.h>
-+#include <linux/ioport.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/serial.h>
-+#include <linux/console.h>
-+#include <linux/sysrq.h>
-+
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/hardware.h>
-+#include <asm/mach/serial_sa1100.h>
-+
-+#if defined(CONFIG_SERIAL_SA1100_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-+#define SUPPORT_SYSRQ
-+#endif
-+
-+#include <linux/serial_core.h>
-+
-+/* We've been assigned a range on the "Low-density serial ports" major */
-+#define SERIAL_SA1100_MAJOR 204
-+#define CALLOUT_SA1100_MAJOR 205
-+#define MINOR_START 5
-+
-+#define NR_PORTS 3
-+
-+#define SA1100_ISR_PASS_LIMIT 256
-+
-+/*
-+ * Convert from ignore_status_mask or read_status_mask to UTSR[01]
-+ */
-+#define SM_TO_UTSR0(x) ((x) & 0xff)
-+#define SM_TO_UTSR1(x) ((x) >> 8)
-+#define UTSR0_TO_SM(x) ((x))
-+#define UTSR1_TO_SM(x) ((x) << 8)
-+
-+#define UART_GET_UTCR0(sport) __raw_readl((sport)->port.membase + UTCR0)
-+#define UART_GET_UTCR1(sport) __raw_readl((sport)->port.membase + UTCR1)
-+#define UART_GET_UTCR2(sport) __raw_readl((sport)->port.membase + UTCR2)
-+#define UART_GET_UTCR3(sport) __raw_readl((sport)->port.membase + UTCR3)
-+#define UART_GET_UTSR0(sport) __raw_readl((sport)->port.membase + UTSR0)
-+#define UART_GET_UTSR1(sport) __raw_readl((sport)->port.membase + UTSR1)
-+#define UART_GET_CHAR(sport) __raw_readl((sport)->port.membase + UTDR)
-+
-+#define UART_PUT_UTCR0(sport,v) __raw_writel((v),(sport)->port.membase + UTCR0)
-+#define UART_PUT_UTCR1(sport,v) __raw_writel((v),(sport)->port.membase + UTCR1)
-+#define UART_PUT_UTCR2(sport,v) __raw_writel((v),(sport)->port.membase + UTCR2)
-+#define UART_PUT_UTCR3(sport,v) __raw_writel((v),(sport)->port.membase + UTCR3)
-+#define UART_PUT_UTSR0(sport,v) __raw_writel((v),(sport)->port.membase + UTSR0)
-+#define UART_PUT_UTSR1(sport,v) __raw_writel((v),(sport)->port.membase + UTSR1)
-+#define UART_PUT_CHAR(sport,v) __raw_writel((v),(sport)->port.membase + UTDR)
-+
-+/*
-+ * This is the size of our serial port register set.
-+ */
-+#define UART_PORT_SIZE 0x24
-+
-+static struct tty_driver normal, callout;
-+static struct tty_struct *sa1100_table[NR_PORTS];
-+static struct termios *sa1100_termios[NR_PORTS], *sa1100_termios_locked[NR_PORTS];
-+static int (*sa1100_open)(struct uart_port *);
-+static void (*sa1100_close)(struct uart_port *);
-+#ifdef SUPPORT_SYSRQ
-+static struct console sa1100_console;
-+#endif
-+
-+/*
-+ * This determines how often we check the modem status signals
-+ * for any change. They generally aren't connected to an IRQ
-+ * so we have to poll them. We also check immediately before
-+ * filling the TX fifo incase CTS has been dropped.
-+ */
-+#define MCTRL_TIMEOUT (250*HZ/1000)
-+
-+struct sa1100_port {
-+ struct uart_port port;
-+ struct timer_list timer;
-+ unsigned int old_status;
-+};
-+
-+/*
-+ * Handle any change of modem status signal since we were last called.
-+ */
-+static void sa1100_mctrl_check(struct sa1100_port *sport)
-+{
-+ unsigned int status, changed;
-+
-+ status = sport->port.ops->get_mctrl(&sport->port);
-+ changed = status ^ sport->old_status;
-+
-+ if (changed == 0)
-+ return;
-+
-+ sport->old_status = status;
-+
-+ if (changed & TIOCM_RI)
-+ sport->port.icount.rng++;
-+ if (changed & TIOCM_DSR)
-+ sport->port.icount.dsr++;
-+ if (changed & TIOCM_CAR)
-+ uart_handle_dcd_change(&sport->port, status & TIOCM_CAR);
-+ if (changed & TIOCM_CTS)
-+ uart_handle_cts_change(&sport->port, status & TIOCM_CTS);
-+
-+ wake_up_interruptible(&sport->port.info->delta_msr_wait);
-+}
-+
-+/*
-+ * This is our per-port timeout handler, for checking the
-+ * modem status signals.
-+ */
-+static void sa1100_timeout(unsigned long data)
-+{
-+ struct sa1100_port *sport = (struct sa1100_port *)data;
-+ unsigned long flags;
-+
-+ if (sport->port.info) {
-+ spin_lock_irqsave(&sport->port.lock, flags);
-+ sa1100_mctrl_check(sport);
-+ spin_unlock_irqrestore(&sport->port.lock, flags);
-+
-+ mod_timer(&sport->timer, jiffies + MCTRL_TIMEOUT);
-+ }
-+}
-+
-+/*
-+ * interrupts disabled on entry
-+ */
-+static void sa1100_stop_tx(struct uart_port *port, unsigned int tty_stop)
-+{
-+ struct sa1100_port *sport = (struct sa1100_port *)port;
-+ u32 utcr3;
-+
-+ utcr3 = UART_GET_UTCR3(sport);
-+ UART_PUT_UTCR3(sport, utcr3 & ~UTCR3_TIE);
-+ sport->port.read_status_mask &= ~UTSR0_TO_SM(UTSR0_TFS);
-+}
-+
-+/*
-+ * interrupts may not be disabled on entry
-+ */
-+static void sa1100_start_tx(struct uart_port *port, unsigned int tty_start)
-+{
-+ struct sa1100_port *sport = (struct sa1100_port *)port;
-+ unsigned long flags;
-+ u32 utcr3;
-+
-+ spin_lock_irqsave(&sport->port.lock, flags);
-+ utcr3 = UART_GET_UTCR3(sport);
-+ sport->port.read_status_mask |= UTSR0_TO_SM(UTSR0_TFS);
-+ UART_PUT_UTCR3(sport, utcr3 | UTCR3_TIE);
-+ spin_unlock_irqrestore(&sport->port.lock, flags);
-+}
-+
-+/*
-+ * Interrupts enabled
-+ */
-+static void sa1100_stop_rx(struct uart_port *port)
-+{
-+ struct sa1100_port *sport = (struct sa1100_port *)port;
-+ u32 utcr3;
-+
-+ utcr3 = UART_GET_UTCR3(sport);
-+ UART_PUT_UTCR3(sport, utcr3 & ~UTCR3_RIE);
-+}
-+
-+/*
-+ * Set the modem control timer to fire immediately.
-+ */
-+static void sa1100_enable_ms(struct uart_port *port)
-+{
-+ struct sa1100_port *sport = (struct sa1100_port *)port;
-+
-+ mod_timer(&sport->timer, jiffies);
-+}
-+
-+static void
-+sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs)
-+{
-+ struct tty_struct *tty = sport->port.info->tty;
-+ unsigned int status, ch, flg, ignored = 0;
-+
-+ status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
-+ UTSR0_TO_SM(UART_GET_UTSR0(sport));
-+ while (status & UTSR1_TO_SM(UTSR1_RNE)) {
-+ ch = UART_GET_CHAR(sport);
-+
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+ goto ignore_char;
-+ sport->port.icount.rx++;
-+
-+ flg = TTY_NORMAL;
-+
-+ /*
-+ * note that the error handling code is
-+ * out of the main execution path
-+ */
-+ if (status & UTSR1_TO_SM(UTSR1_PRE | UTSR1_FRE | UTSR1_ROR))
-+ goto handle_error;
-+
-+ if (uart_handle_sysrq_char(&sport->port, ch, regs))
-+ goto ignore_char;
-+
-+ error_return:
-+ *tty->flip.flag_buf_ptr++ = flg;
-+ *tty->flip.char_buf_ptr++ = ch;
-+ tty->flip.count++;
-+ ignore_char:
-+ status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
-+ UTSR0_TO_SM(UART_GET_UTSR0(sport));
-+ }
-+ out:
-+ tty_flip_buffer_push(tty);
-+ return;
-+
-+ handle_error:
-+ if (status & UTSR1_TO_SM(UTSR1_PRE))
-+ sport->port.icount.parity++;
-+ else if (status & UTSR1_TO_SM(UTSR1_FRE))
-+ sport->port.icount.frame++;
-+ if (status & UTSR1_TO_SM(UTSR1_ROR))
-+ sport->port.icount.overrun++;
-+
-+ if (status & sport->port.ignore_status_mask) {
-+ if (++ignored > 100)
-+ goto out;
-+ goto ignore_char;
-+ }
-+
-+ status &= sport->port.read_status_mask;
-+
-+ if (status & UTSR1_TO_SM(UTSR1_PRE))
-+ flg = TTY_PARITY;
-+ else if (status & UTSR1_TO_SM(UTSR1_FRE))
-+ flg = TTY_FRAME;
-+
-+ if (status & UTSR1_TO_SM(UTSR1_ROR)) {
-+ /*
-+ * overrun does *not* affect the character
-+ * we read from the FIFO
-+ */
-+ *tty->flip.flag_buf_ptr++ = flg;
-+ *tty->flip.char_buf_ptr++ = ch;
-+ tty->flip.count++;
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+ goto ignore_char;
-+ ch = 0;
-+ flg = TTY_OVERRUN;
-+ }
-+#ifdef SUPPORT_SYSRQ
-+ sport->port.sysrq = 0;
-+#endif
-+ goto error_return;
-+}
-+
-+static void sa1100_tx_chars(struct sa1100_port *sport)
-+{
-+ struct circ_buf *xmit = &sport->port.info->xmit;
-+
-+ if (sport->port.x_char) {
-+ UART_PUT_CHAR(sport, sport->port.x_char);
-+ sport->port.icount.tx++;
-+ sport->port.x_char = 0;
-+ return;
-+ }
-+
-+ /*
-+ * Check the modem control lines before
-+ * transmitting anything.
-+ */
-+ sa1100_mctrl_check(sport);
-+
-+ if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
-+ sa1100_stop_tx(&sport->port, 0);
-+ return;
-+ }
-+
-+ /*
-+ * Tried using FIFO (not checking TNF) for fifo fill:
-+ * still had the '4 bytes repeated' problem.
-+ */
-+ while (UART_GET_UTSR1(sport) & UTSR1_TNF) {
-+ UART_PUT_CHAR(sport, xmit->buf[xmit->tail]);
-+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
-+ sport->port.icount.tx++;
-+ if (uart_circ_empty(xmit))
-+ break;
-+ }
-+
-+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
-+ uart_write_wakeup(&sport->port);
-+
-+ if (uart_circ_empty(xmit))
-+ sa1100_stop_tx(&sport->port, 0);
-+}
-+
-+static void sa1100_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct sa1100_port *sport = dev_id;
-+ unsigned int status, pass_counter = 0;
-+
-+ spin_lock(&sport->port.lock);
-+ status = UART_GET_UTSR0(sport);
-+ status &= SM_TO_UTSR0(sport->port.read_status_mask) | ~UTSR0_TFS;
-+ do {
-+ if (status & (UTSR0_RFS | UTSR0_RID)) {
-+ /* Clear the receiver idle bit, if set */
-+ if (status & UTSR0_RID)
-+ UART_PUT_UTSR0(sport, UTSR0_RID);
-+ sa1100_rx_chars(sport, regs);
-+ }
-+
-+ /* Clear the relevant break bits */
-+ if (status & (UTSR0_RBB | UTSR0_REB))
-+ UART_PUT_UTSR0(sport, status & (UTSR0_RBB | UTSR0_REB));
-+
-+ if (status & UTSR0_RBB)
-+ sport->port.icount.brk++;
-+
-+ if (status & UTSR0_REB)
-+ uart_handle_break(&sport->port);
-+
-+ if (status & UTSR0_TFS)
-+ sa1100_tx_chars(sport);
-+ if (pass_counter++ > SA1100_ISR_PASS_LIMIT)
-+ break;
-+ status = UART_GET_UTSR0(sport);
-+ status &= SM_TO_UTSR0(sport->port.read_status_mask) |
-+ ~UTSR0_TFS;
-+ } while (status & (UTSR0_TFS | UTSR0_RFS | UTSR0_RID));
-+ spin_unlock(&sport->port.lock);
-+}
-+
-+/*
-+ * Return TIOCSER_TEMT when transmitter is not busy.
-+ */
-+static unsigned int sa1100_tx_empty(struct uart_port *port)
-+{
-+ struct sa1100_port *sport = (struct sa1100_port *)port;
-+
-+ return UART_GET_UTSR1(sport) & UTSR1_TBY ? 0 : TIOCSER_TEMT;
-+}
-+
-+static unsigned int sa1100_get_mctrl(struct uart_port *port)
-+{
-+ return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
-+}
-+
-+static void sa1100_set_mctrl(struct uart_port *port, unsigned int mctrl)
-+{
-+}
-+
-+/*
-+ * Interrupts always disabled.
-+ */
-+static void sa1100_break_ctl(struct uart_port *port, int break_state)
-+{
-+ struct sa1100_port *sport = (struct sa1100_port *)port;
-+ unsigned long flags;
-+ unsigned int utcr3;
-+
-+ spin_lock_irqsave(&sport->port.lock, flags);
-+ utcr3 = UART_GET_UTCR3(sport);
-+ if (break_state == -1)
-+ utcr3 |= UTCR3_BRK;
-+ else
-+ utcr3 &= ~UTCR3_BRK;
-+ UART_PUT_UTCR3(sport, utcr3);
-+ spin_unlock_irqrestore(&sport->port.lock, flags);
-+}
-+
-+static int sa1100_startup(struct uart_port *port)
-+{
-+ struct sa1100_port *sport = (struct sa1100_port *)port;
-+ int retval;
-+
-+ /*
-+ * Allocate the IRQ
-+ */
-+ retval = request_irq(sport->port.irq, sa1100_int, 0,
-+ "sa11x0-uart", sport);
-+ if (retval)
-+ return retval;
-+
-+ /*
-+ * If there is a specific "open" function
-+ * (to register control line interrupts)
-+ */
-+ if (sa1100_open) {
-+ retval = sa1100_open(port);
-+ if (retval) {
-+ free_irq(sport->port.irq, sport);
-+ return retval;
-+ }
-+ }
-+
-+ /*
-+ * Finally, clear and enable interrupts
-+ */
-+ UART_PUT_UTSR0(sport, -1);
-+ UART_PUT_UTCR3(sport, UTCR3_RXE | UTCR3_TXE | UTCR3_RIE);
-+
-+ return 0;
-+}
-+
-+static void sa1100_shutdown(struct uart_port *port)
-+{
-+ struct sa1100_port *sport = (struct sa1100_port *)port;
-+
-+ /*
-+ * Stop our timer.
-+ */
-+ del_timer_sync(&sport->timer);
-+
-+ /*
-+ * Free the interrupt
-+ */
-+ free_irq(sport->port.irq, sport);
-+
-+ /*
-+ * If there is a specific "close" function (to unregister
-+ * control line interrupts)
-+ */
-+ if (sa1100_close)
-+ sa1100_close(port);
-+
-+ /*
-+ * Disable all interrupts, port and break condition.
-+ */
-+ UART_PUT_UTCR3(sport, 0);
-+}
-+
-+static void sa1100_change_speed(struct uart_port *port, unsigned int cflag, unsigned int iflag, unsigned int quot)
-+{
-+ struct sa1100_port *sport = (struct sa1100_port *)port;
-+ unsigned long flags;
-+ unsigned int utcr0, old_utcr3;
-+
-+ if ((cflag & CSIZE) == CS8)
-+ utcr0 = UTCR0_DSS;
-+ else
-+ utcr0 = 0;
-+
-+ if (cflag & CSTOPB)
-+ utcr0 |= UTCR0_SBS;
-+ if (cflag & PARENB) {
-+ utcr0 |= UTCR0_PE;
-+ if (!(cflag & PARODD))
-+ utcr0 |= UTCR0_OES;
-+ }
-+
-+ spin_lock_irqsave(&sport->port.lock, flags);
-+
-+ sport->port.read_status_mask &= UTSR0_TO_SM(UTSR0_TFS);
-+ sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_ROR);
-+ if (iflag & INPCK)
-+ sport->port.read_status_mask |=
-+ UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE);
-+ if (iflag & (BRKINT | PARMRK))
-+ sport->port.read_status_mask |=
-+ UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB);
-+
-+ /*
-+ * Characters to ignore
-+ */
-+ sport->port.ignore_status_mask = 0;
-+ if (iflag & IGNPAR)
-+ sport->port.ignore_status_mask |=
-+ UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE);
-+ if (iflag & IGNBRK) {
-+ sport->port.ignore_status_mask |=
-+ UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB);
-+ /*
-+ * If we're ignoring parity and break indicators,
-+ * ignore overruns too (for real raw support).
-+ */
-+ if (iflag & IGNPAR)
-+ sport->port.ignore_status_mask |=
-+ UTSR1_TO_SM(UTSR1_ROR);
-+ }
-+
-+ del_timer_sync(&sport->timer);
-+
-+ /*
-+ * disable interrupts and drain transmitter
-+ */
-+ old_utcr3 = UART_GET_UTCR3(sport);
-+ UART_PUT_UTCR3(sport, old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE));
-+
-+ while (UART_GET_UTSR1(sport) & UTSR1_TBY)
-+ barrier();
-+
-+ /* then, disable everything */
-+ UART_PUT_UTCR3(sport, 0);
-+
-+ /* set the parity, stop bits and data size */
-+ UART_PUT_UTCR0(sport, utcr0);
-+
-+ /* set the baud rate */
-+ quot -= 1;
-+ UART_PUT_UTCR1(sport, ((quot & 0xf00) >> 8));
-+ UART_PUT_UTCR2(sport, (quot & 0xff));
-+
-+ UART_PUT_UTSR0(sport, -1);
-+
-+ UART_PUT_UTCR3(sport, old_utcr3);
-+
-+ if (UART_ENABLE_MS(&sport->port, cflag))
-+ sa1100_enable_ms(&sport->port);
-+
-+ spin_unlock_irqrestore(&sport->port.lock, flags);
-+}
-+
-+static const char *sa1100_type(struct uart_port *port)
-+{
-+ struct sa1100_port *sport = (struct sa1100_port *)port;
-+
-+ return sport->port.type == PORT_SA1100 ? "SA1100" : NULL;
-+}
-+
-+/*
-+ * Release the memory region(s) being used by 'port'.
-+ */
-+static void sa1100_release_port(struct uart_port *port)
-+{
-+ struct sa1100_port *sport = (struct sa1100_port *)port;
-+
-+ release_mem_region(sport->port.mapbase, UART_PORT_SIZE);
-+}
-+
-+/*
-+ * Request the memory region(s) being used by 'port'.
-+ */
-+static int sa1100_request_port(struct uart_port *port)
-+{
-+ struct sa1100_port *sport = (struct sa1100_port *)port;
-+
-+ return request_mem_region(sport->port.mapbase, UART_PORT_SIZE,
-+ "sa11x0-uart") != NULL ? 0 : -EBUSY;
-+}
-+
-+/*
-+ * Configure/autoconfigure the port.
-+ */
-+static void sa1100_config_port(struct uart_port *port, int flags)
-+{
-+ struct sa1100_port *sport = (struct sa1100_port *)port;
-+
-+ if (flags & UART_CONFIG_TYPE &&
-+ sa1100_request_port(&sport->port) == 0)
-+ sport->port.type = PORT_SA1100;
-+}
-+
-+/*
-+ * Verify the new serial_struct (for TIOCSSERIAL).
-+ * The only change we allow are to the flags and type, and
-+ * even then only between PORT_SA1100 and PORT_UNKNOWN
-+ */
-+static int sa1100_verify_port(struct uart_port *port, struct serial_struct *ser)
-+{
-+ struct sa1100_port *sport = (struct sa1100_port *)port;
-+ int ret = 0;
-+
-+ if (ser->type != PORT_UNKNOWN && ser->type != PORT_SA1100)
-+ ret = -EINVAL;
-+ if (sport->port.irq != ser->irq)
-+ ret = -EINVAL;
-+ if (ser->io_type != SERIAL_IO_MEM)
-+ ret = -EINVAL;
-+ if (sport->port.uartclk / 16 != ser->baud_base)
-+ ret = -EINVAL;
-+ if ((void *)sport->port.mapbase != ser->iomem_base)
-+ ret = -EINVAL;
-+ if (sport->port.iobase != ser->port)
-+ ret = -EINVAL;
-+ if (ser->hub6 != 0)
-+ ret = -EINVAL;
-+ return ret;
-+}
-+
-+static struct uart_ops sa1100_pops = {
-+ .tx_empty = sa1100_tx_empty,
-+ .set_mctrl = sa1100_set_mctrl,
-+ .get_mctrl = sa1100_get_mctrl,
-+ .stop_tx = sa1100_stop_tx,
-+ .start_tx = sa1100_start_tx,
-+ .stop_rx = sa1100_stop_rx,
-+ .enable_ms = sa1100_enable_ms,
-+ .break_ctl = sa1100_break_ctl,
-+ .startup = sa1100_startup,
-+ .shutdown = sa1100_shutdown,
-+ .change_speed = sa1100_change_speed,
-+ .type = sa1100_type,
-+ .release_port = sa1100_release_port,
-+ .request_port = sa1100_request_port,
-+ .config_port = sa1100_config_port,
-+ .verify_port = sa1100_verify_port,
-+};
-+
-+static struct sa1100_port sa1100_ports[NR_PORTS];
-+
-+/*
-+ * Setup the SA1100 serial ports. Note that we don't include the IrDA
-+ * port here since we have our own SIR/FIR driver (see drivers/net/irda)
-+ *
-+ * Note also that we support "console=ttySAx" where "x" is either 0 or 1.
-+ * Which serial port this ends up being depends on the machine you're
-+ * running this kernel on. I'm not convinced that this is a good idea,
-+ * but that's the way it traditionally works.
-+ *
-+ * Note that NanoEngine UART3 becomes UART2, and UART2 is no longer
-+ * used here.
-+ */
-+static void __init sa1100_init_ports(void)
-+{
-+ static int first = 1;
-+ int i;
-+
-+ if (!first)
-+ return;
-+ first = 0;
-+
-+ for (i = 0; i < NR_PORTS; i++) {
-+ sa1100_ports[i].port.uartclk = 3686400;
-+ sa1100_ports[i].port.ops = &sa1100_pops;
-+ sa1100_ports[i].port.fifosize = 8;
-+ sa1100_ports[i].port.line = i;
-+ sa1100_ports[i].port.iotype = SERIAL_IO_MEM;
-+ init_timer(&sa1100_ports[i].timer);
-+ sa1100_ports[i].timer.function = sa1100_timeout;
-+ sa1100_ports[i].timer.data = (unsigned long)&sa1100_ports[i];
-+ }
-+
-+ /*
-+ * make transmit lines outputs, so that when the port
-+ * is closed, the output is in the MARK state.
-+ */
-+ PPDR |= PPC_TXD1 | PPC_TXD3;
-+ PPSR |= PPC_TXD1 | PPC_TXD3;
-+}
-+
-+void __init sa1100_register_uart_fns(struct sa1100_port_fns *fns)
-+{
-+ if (fns->enable_ms)
-+ sa1100_pops.enable_ms = fns->enable_ms;
-+ if (fns->get_mctrl)
-+ sa1100_pops.get_mctrl = fns->get_mctrl;
-+ if (fns->set_mctrl)
-+ sa1100_pops.set_mctrl = fns->set_mctrl;
-+ sa1100_open = fns->open;
-+ sa1100_close = fns->close;
-+ sa1100_pops.pm = fns->pm;
-+ sa1100_pops.set_wake = fns->set_wake;
-+}
-+
-+void __init sa1100_register_uart(int idx, int port)
-+{
-+ if (idx >= NR_PORTS) {
-+ printk(KERN_ERR "%s: bad index number %d\n", __FUNCTION__, idx);
-+ return;
-+ }
-+
-+ switch (port) {
-+ case 1:
-+ sa1100_ports[idx].port.membase = (void *)&Ser1UTCR0;
-+ sa1100_ports[idx].port.mapbase = _Ser1UTCR0;
-+ sa1100_ports[idx].port.irq = IRQ_Ser1UART;
-+ sa1100_ports[idx].port.flags = ASYNC_BOOT_AUTOCONF;
-+ break;
-+
-+ case 2:
-+ sa1100_ports[idx].port.membase = (void *)&Ser2UTCR0;
-+ sa1100_ports[idx].port.mapbase = _Ser2UTCR0;
-+ sa1100_ports[idx].port.irq = IRQ_Ser2ICP;
-+ sa1100_ports[idx].port.flags = ASYNC_BOOT_AUTOCONF;
-+ break;
-+
-+ case 3:
-+ sa1100_ports[idx].port.membase = (void *)&Ser3UTCR0;
-+ sa1100_ports[idx].port.mapbase = _Ser3UTCR0;
-+ sa1100_ports[idx].port.irq = IRQ_Ser3UART;
-+ sa1100_ports[idx].port.flags = ASYNC_BOOT_AUTOCONF;
-+ break;
-+
-+ default:
-+ printk(KERN_ERR "%s: bad port number %d\n", __FUNCTION__, port);
-+ }
-+}
-+
-+
-+#ifdef CONFIG_SERIAL_SA1100_CONSOLE
-+
-+/*
-+ * Interrupts are disabled on entering
-+ */
-+static void
-+sa1100_console_write(struct console *co, const char *s, unsigned int count)
-+{
-+ struct sa1100_port *sport = &sa1100_ports[co->index];
-+ unsigned int old_utcr3, status, i;
-+
-+ /*
-+ * First, save UTCR3 and then disable interrupts
-+ */
-+ old_utcr3 = UART_GET_UTCR3(sport);
-+ UART_PUT_UTCR3(sport, (old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE)) |
-+ UTCR3_TXE);
-+
-+ /*
-+ * Now, do each character
-+ */
-+ for (i = 0; i < count; i++) {
-+ do {
-+ status = UART_GET_UTSR1(sport);
-+ } while (!(status & UTSR1_TNF));
-+ UART_PUT_CHAR(sport, s[i]);
-+ if (s[i] == '\n') {
-+ do {
-+ status = UART_GET_UTSR1(sport);
-+ } while (!(status & UTSR1_TNF));
-+ UART_PUT_CHAR(sport, '\r');
-+ }
-+ }
-+
-+ /*
-+ * Finally, wait for transmitter to become empty
-+ * and restore UTCR3
-+ */
-+ do {
-+ status = UART_GET_UTSR1(sport);
-+ } while (status & UTSR1_TBY);
-+ UART_PUT_UTCR3(sport, old_utcr3);
-+}
-+
-+static kdev_t sa1100_console_device(struct console *co)
-+{
-+ return MKDEV(SERIAL_SA1100_MAJOR, MINOR_START + co->index);
-+}
-+
-+/*
-+ * If the port was already initialised (eg, by a boot loader), try to determine
-+ * the current setup.
-+ */
-+static void __init
-+sa1100_console_get_options(struct sa1100_port *sport, int *baud,
-+ int *parity, int *bits)
-+{
-+ unsigned int utcr3;
-+
-+ utcr3 = UART_GET_UTCR3(sport) & (UTCR3_RXE | UTCR3_TXE);
-+ if (utcr3 == (UTCR3_RXE | UTCR3_TXE)) {
-+ /* ok, the port was enabled */
-+ unsigned int utcr0, quot;
-+
-+ utcr0 = UART_GET_UTCR0(sport);
-+
-+ *parity = 'n';
-+ if (utcr0 & UTCR0_PE) {
-+ if (utcr0 & UTCR0_OES)
-+ *parity = 'e';
-+ else
-+ *parity = 'o';
-+ }
-+
-+ if (utcr0 & UTCR0_DSS)
-+ *bits = 8;
-+ else
-+ *bits = 7;
-+
-+ quot = UART_GET_UTCR2(sport) | UART_GET_UTCR1(sport) << 8;
-+ quot &= 0xfff;
-+ *baud = sport->port.uartclk / (16 * (quot + 1));
-+ }
-+}
-+
-+static int __init
-+sa1100_console_setup(struct console *co, char *options)
-+{
-+ struct sa1100_port *sport;
-+ int baud = CONFIG_SA1100_DEFAULT_BAUDRATE;
-+ int bits = 8;
-+ int parity = 'n';
-+ int flow = 'n';
-+
-+ /*
-+ * Check whether an invalid uart number has been specified, and
-+ * if so, search for the first available port that does have
-+ * console support.
-+ */
-+ if (co->index == -1 || co->index >= NR_PORTS)
-+ co->index = 0;
-+ sport = &sa1100_ports[co->index];
-+
-+ if (options)
-+ uart_parse_options(options, &baud, &parity, &bits, &flow);
-+ else
-+ sa1100_console_get_options(sport, &baud, &parity, &bits);
-+
-+ return uart_set_options(&sport->port, co, baud, parity, bits, flow);
-+}
-+
-+static struct console sa1100_console = {
-+ .name = "ttySA",
-+ .write = sa1100_console_write,
-+ .device = sa1100_console_device,
-+ .setup = sa1100_console_setup,
-+ .flags = CON_PRINTBUFFER,
-+ .index = -1,
-+};
-+
-+void __init sa1100_rs_console_init(void)
-+{
-+ sa1100_init_ports();
-+ register_console(&sa1100_console);
-+}
-+
-+#define SA1100_CONSOLE &sa1100_console
-+#else
-+#define SA1100_CONSOLE NULL
-+#endif
-+
-+static struct uart_driver sa1100_reg = {
-+ .owner = THIS_MODULE,
-+ .normal_major = SERIAL_SA1100_MAJOR,
-+#ifdef CONFIG_DEVFS_FS
-+ .normal_name = "ttySA%d",
-+ .callout_name = "cusa%d",
-+#else
-+ .normal_name = "ttySA",
-+ .callout_name = "cusa",
-+#endif
-+ .normal_driver = &normal,
-+ .callout_major = CALLOUT_SA1100_MAJOR,
-+ .callout_driver = &callout,
-+ .table = sa1100_table,
-+ .termios = sa1100_termios,
-+ .termios_locked = sa1100_termios_locked,
-+ .minor = MINOR_START,
-+ .nr = NR_PORTS,
-+ .cons = SA1100_CONSOLE,
-+};
-+
-+static int __init sa1100_serial_init(void)
-+{
-+ int i, ret;
-+
-+ sa1100_init_ports();
-+
-+ ret = uart_register_driver(&sa1100_reg);
-+ if (ret)
-+ return ret;
-+
-+ for (i = 0; i < NR_PORTS; i++)
-+ uart_add_one_port(&sa1100_reg, &sa1100_ports[i].port);
-+
-+ return 0;
-+}
-+
-+static void __exit sa1100_serial_exit(void)
-+{
-+ int i;
-+
-+ for (i = 0; i < NR_PORTS; i++)
-+ uart_remove_one_port(&sa1100_reg, &sa1100_ports[i].port);
-+
-+ uart_unregister_driver(&sa1100_reg);
-+}
-+
-+module_init(sa1100_serial_init);
-+module_exit(sa1100_serial_exit);
-+
-+EXPORT_NO_SYMBOLS;
-+
-+MODULE_AUTHOR("Deep Blue Solutions Ltd");
-+MODULE_DESCRIPTION("SA1100 generic serial port driver");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/serial/uart00.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,903 @@
-+/*
-+ * linux/drivers/serial/uart00.c
-+ *
-+ * Driver for UART00 serial ports
-+ *
-+ * Based on drivers/char/serial_amba.c, by ARM Limited &
-+ * Deep Blue Solutions Ltd.
-+ * Copyright 2001 Altera Corporation
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * $Id$
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/errno.h>
-+#include <linux/signal.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/tty.h>
-+#include <linux/tty_flip.h>
-+#include <linux/major.h>
-+#include <linux/string.h>
-+#include <linux/fcntl.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/circ_buf.h>
-+#include <linux/serial.h>
-+#include <linux/console.h>
-+#include <linux/sysrq.h>
-+#include <linux/pld/pld_hotswap.h>
-+#include <linux/proc_fs.h>
-+
-+#include <asm/system.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+#include <asm/bitops.h>
-+#include <asm/sizes.h>
-+
-+#if defined(CONFIG_SERIAL_UART00_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
-+#define SUPPORT_SYSRQ
-+#endif
-+
-+#include <linux/serial_core.h>
-+#include <asm/arch/excalibur.h>
-+#define UART00_TYPE (volatile unsigned int*)
-+#include <asm/arch/uart00.h>
-+#include <asm/arch/int_ctrl00.h>
-+
-+#undef DEBUG
-+#define UART_NR 2
-+
-+#define SERIAL_UART00_NAME "ttyUA"
-+#define SERIAL_UART00_MAJOR 204
-+#define SERIAL_UART00_MINOR 16 /* Temporary - will change in future */
-+#define SERIAL_UART00_NR UART_NR
-+#define UART_PORT_SIZE 0x50
-+
-+#define CALLOUT_UART00_NAME "cuaua"
-+#define CALLOUT_UART00_MAJOR 205
-+#define CALLOUT_UART00_MINOR 16 /* Temporary - will change in future */
-+#define CALLOUT_UART00_NR UART_NR
-+
-+static struct tty_driver normal, callout;
-+static struct tty_struct *uart00_table[UART_NR];
-+static struct termios *uart00_termios[UART_NR], *uart00_termios_locked[UART_NR];
-+static struct console uart00_console;
-+static struct uart_driver uart00_reg;
-+
-+
-+#define UART00_ISR_PASS_LIMIT 256
-+
-+/*
-+ * Access macros for the UART00 UARTs
-+ */
-+#define UART_GET_INT_STATUS(p) inl(UART_ISR((p)->membase))
-+#define UART_PUT_IES(p, c) outl(c,UART_IES((p)->membase))
-+#define UART_GET_IES(p) inl(UART_IES((p)->membase))
-+#define UART_PUT_IEC(p, c) outl(c,UART_IEC((p)->membase))
-+#define UART_GET_IEC(p) inl(UART_IEC((p)->membase))
-+#define UART_PUT_CHAR(p, c) outl(c,UART_TD((p)->membase))
-+#define UART_GET_CHAR(p) inl(UART_RD((p)->membase))
-+#define UART_GET_RSR(p) inl(UART_RSR((p)->membase))
-+#define UART_GET_RDS(p) inl(UART_RDS((p)->membase))
-+#define UART_GET_MSR(p) inl(UART_MSR((p)->membase))
-+#define UART_GET_MCR(p) inl(UART_MCR((p)->membase))
-+#define UART_PUT_MCR(p, c) outl(c,UART_MCR((p)->membase))
-+#define UART_GET_MC(p) inl(UART_MC((p)->membase))
-+#define UART_PUT_MC(p, c) outl(c,UART_MC((p)->membase))
-+#define UART_GET_TSR(p) inl(UART_TSR((p)->membase))
-+#define UART_GET_DIV_HI(p) inl(UART_DIV_HI((p)->membase))
-+#define UART_PUT_DIV_HI(p,c) outl(c,UART_DIV_HI((p)->membase))
-+#define UART_GET_DIV_LO(p) inl(UART_DIV_LO((p)->membase))
-+#define UART_PUT_DIV_LO(p,c) outl(c,UART_DIV_LO((p)->membase))
-+#define UART_RX_DATA(s) ((s) & UART_RSR_RX_LEVEL_MSK)
-+#define UART_TX_READY(s) (((s) & UART_TSR_TX_LEVEL_MSK) < 15)
-+//#define UART_TX_EMPTY(p) ((UART_GET_FR(p) & UART00_UARTFR_TMSK) == 0)
-+
-+static void uart00_stop_tx(struct uart_port *port, u_int from_tty)
-+{
-+
-+ UART_PUT_IEC(port, UART_IEC_TIE_MSK);
-+}
-+
-+static void uart00_stop_rx(struct uart_port *port)
-+{
-+
-+ UART_PUT_IEC(port, UART_IEC_RE_MSK);
-+}
-+
-+static void uart00_enable_ms(struct uart_port *port)
-+{
-+
-+ UART_PUT_IES(port, UART_IES_ME_MSK);
-+}
-+
-+static void
-+uart00_rx_chars(struct uart_port *port, struct pt_regs *regs)
-+{
-+ struct uart_info *info = port->info;
-+ struct tty_struct *tty = info->tty;
-+ unsigned int status, ch, rds, flg, ignored = 0;
-+
-+
-+ status = UART_GET_RSR(port);
-+ while (UART_RX_DATA(status)) {
-+
-+ /*
-+ * We need to read rds before reading the
-+ * character from the fifo
-+ */
-+ rds = UART_GET_RDS(port);
-+ ch = UART_GET_CHAR(port);
-+ port->icount.rx++;
-+
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+ goto ignore_char;
-+
-+ flg = TTY_NORMAL;
-+
-+ /*
-+ * Note that the error handling code is
-+ * out of the main execution path
-+ */
-+ if (rds & (UART_RDS_BI_MSK |UART_RDS_FE_MSK|UART_RDS_PE_MSK))
-+ goto handle_error;
-+ if (uart_handle_sysrq_char(port, ch, regs))
-+ goto ignore_char;
-+
-+ error_return:
-+ *tty->flip.flag_buf_ptr++ = flg;
-+ *tty->flip.char_buf_ptr++ = ch;
-+ tty->flip.count++;
-+ ignore_char:
-+ status = UART_GET_RSR(port);
-+ }
-+out:
-+ tty_flip_buffer_push(tty);
-+ return;
-+
-+handle_error:
-+ if (rds & UART_RDS_BI_MSK) {
-+ status &= ~(UART_RDS_FE_MSK | UART_RDS_PE_MSK);
-+ port->icount.brk++;
-+
-+#ifdef SUPPORT_SYSRQ
-+ if (uart_handle_break(port))
-+ goto ignore_char;
-+#endif
-+ } else if (rds & UART_RDS_PE_MSK)
-+ port->icount.parity++;
-+ else if (rds & UART_RDS_FE_MSK)
-+ port->icount.frame++;
-+ if (rds & UART_RDS_OE_MSK)
-+ port->icount.overrun++;
-+
-+ if (rds & port->ignore_status_mask) {
-+ if (++ignored > 100)
-+ goto out;
-+ goto ignore_char;
-+ }
-+ rds &= port->read_status_mask;
-+
-+ if (rds & UART_RDS_BI_MSK)
-+ flg = TTY_BREAK;
-+ else if (rds & UART_RDS_PE_MSK)
-+ flg = TTY_PARITY;
-+ else if (rds & UART_RDS_FE_MSK)
-+ flg = TTY_FRAME;
-+
-+ if (rds & UART_RDS_OE_MSK) {
-+ /*
-+ * CHECK: does overrun affect the current character?
-+ * ASSUMPTION: it does not.
-+ */
-+ *tty->flip.flag_buf_ptr++ = flg;
-+ *tty->flip.char_buf_ptr++ = ch;
-+ tty->flip.count++;
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+ goto ignore_char;
-+ ch = 0;
-+ flg = TTY_OVERRUN;
-+ }
-+#ifdef SUPPORT_SYSRQ
-+ port->sysrq = 0;
-+#endif
-+ goto error_return;
-+}
-+
-+static void uart00_tx_chars(struct uart_port *port)
-+{
-+ int count;
-+ struct uart_info *info = port->info;
-+
-+ if (port->x_char) {
-+ while((UART_GET_TSR(port)& UART_TSR_TX_LEVEL_MSK)==15);
-+ UART_PUT_CHAR(port, port->x_char);
-+ port->icount.tx++;
-+ port->x_char = 0;
-+
-+ return;
-+ }
-+ if (info->xmit.head == info->xmit.tail
-+ || info->tty->stopped
-+ || info->tty->hw_stopped) {
-+ uart00_stop_tx(port, 0);
-+ return;
-+ }
-+
-+ count = port->fifosize >> 1;
-+ do {
-+ while((UART_GET_TSR(port)& UART_TSR_TX_LEVEL_MSK)==15);
-+ UART_PUT_CHAR(port, info->xmit.buf[info->xmit.tail]);
-+ info->xmit.tail = (info->xmit.tail + 1) & (UART_XMIT_SIZE - 1);
-+ port->icount.tx++;
-+ if (info->xmit.head == info->xmit.tail)
-+ break;
-+ } while (--count > 0);
-+
-+ if (CIRC_CNT(info->xmit.head,
-+ info->xmit.tail,
-+ UART_XMIT_SIZE) < WAKEUP_CHARS)
-+ uart_write_wakeup(port);
-+
-+ if (info->xmit.head == info->xmit.tail)
-+ uart00_stop_tx(port, 0);
-+}
-+
-+static void uart00_start_tx(struct uart_port *port, u_int from_tty)
-+{
-+ UART_PUT_IES(port,UART_IES_TIE_MSK );
-+ uart00_tx_chars(port);
-+}
-+
-+static void uart00_modem_status(struct uart_port *port)
-+{
-+ unsigned int status;
-+ struct uart_icount *icount = &port->icount;
-+ struct uart_info *info = port->info;
-+
-+ status = UART_GET_MSR(port);
-+
-+ if (!status & (UART_MSR_DCTS_MSK | UART_MSR_DDSR_MSK |
-+ UART_MSR_TERI_MSK | UART_MSR_DDCD_MSK))
-+ return;
-+
-+ if (status & UART_MSR_DDCD_MSK) {
-+ icount->dcd++;
-+#ifdef CONFIG_HARD_PPS
-+ if ((port->flags & ASYNC_HARDPPS_CD) &&
-+ (status & UART_MSR_DCD_MSK))
-+ hardpps();
-+#endif
-+ if (info->flags & ASYNC_CHECK_CD) {
-+ if (status & UART_MSR_DCD_MSK)
-+ wake_up_interruptible(&info->open_wait);
-+ else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
-+ (port->flags & ASYNC_CALLOUT_NOHUP))) {
-+ if (info->tty)
-+ tty_hangup(info->tty);
-+ }
-+ }
-+ }
-+
-+ if (status & UART_MSR_DDSR_MSK)
-+ icount->dsr++;
-+
-+ if (status & UART_MSR_DCTS_MSK) {
-+ icount->cts++;
-+
-+ if (info->flags & ASYNC_CTS_FLOW) {
-+ status &= UART_MSR_CTS_MSK;
-+
-+ if (info->tty->hw_stopped) {
-+ if (status) {
-+ info->tty->hw_stopped = 0;
-+ port->ops->start_tx(port, 0);
-+ uart_write_wakeup(port);
-+ }
-+ } else {
-+ if (!status) {
-+ info->tty->hw_stopped = 1;
-+ port->ops->stop_tx(port, 0);
-+ }
-+ }
-+ }
-+ }
-+ wake_up_interruptible(&info->delta_msr_wait);
-+
-+}
-+
-+static void uart00_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct uart_port *port = dev_id;
-+ unsigned int status, pass_counter = 0;
-+
-+ status = UART_GET_INT_STATUS(port);
-+ do {
-+
-+ if (status & UART_ISR_RI_MSK)
-+ uart00_rx_chars(port, regs);
-+ if (status & (UART_ISR_TI_MSK | UART_ISR_TII_MSK))
-+ uart00_tx_chars(port);
-+ if (status & UART_ISR_MI_MSK)
-+ uart00_modem_status(port);
-+ if (pass_counter++ > UART00_ISR_PASS_LIMIT)
-+ break;
-+
-+ status = UART_GET_INT_STATUS(port);
-+ } while (status);
-+}
-+
-+static u_int uart00_tx_empty(struct uart_port *port)
-+{
-+ return UART_GET_TSR(port) & UART_TSR_TX_LEVEL_MSK? 0 : TIOCSER_TEMT;
-+}
-+
-+static u_int uart00_get_mctrl(struct uart_port *port)
-+{
-+ unsigned int result = 0;
-+ unsigned int status;
-+
-+ status = UART_GET_MSR(port);
-+ if (status & UART_MSR_DCD_MSK)
-+ result |= TIOCM_CAR;
-+ if (status & UART_MSR_DSR_MSK)
-+ result |= TIOCM_DSR;
-+ if (status & UART_MSR_CTS_MSK)
-+ result |= TIOCM_CTS;
-+ if (status & UART_MCR_RI_MSK)
-+ result |= TIOCM_RNG;
-+
-+ return result;
-+}
-+
-+static void uart00_set_mctrl(struct uart_port *port, u_int mctrl)
-+{
-+ unsigned char mcr = 0;
-+
-+ if (mctrl & TIOCM_RTS)
-+ mcr |= UART_MCR_RTS_MSK;
-+ if (mctrl & TIOCM_DTR)
-+ mcr |= UART_MCR_DTR_MSK;
-+ if (mctrl & TIOCM_LOOP)
-+ mcr |= UART_MCR_LB_MSK;
-+
-+ UART_PUT_MCR(port, mcr);
-+}
-+
-+static void uart00_break_ctl(struct uart_port *port, int break_state)
-+{
-+ unsigned int mcr;
-+
-+ mcr = UART_GET_MCR(port);
-+ if (break_state == -1)
-+ mcr |= UART_MCR_BR_MSK;
-+ else
-+ mcr &= ~UART_MCR_BR_MSK;
-+ UART_PUT_MCR(port, mcr);
-+}
-+
-+static inline u_int uart_calculate_quot(struct uart_port *port, u_int baud)
-+{
-+ u_int quot;
-+
-+ /* Special case: B0 rate */
-+ if (!baud)
-+ baud = 9600;
-+
-+ quot = (port->uartclk / (16 * baud)-1) ;
-+
-+ return quot;
-+}
-+static void uart00_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot)
-+{
-+ u_int uart_mc=0, old_ies;
-+ unsigned long flags;
-+
-+#ifdef DEBUG
-+ printk("uart00_set_cflag(0x%x) called\n", cflag);
-+#endif
-+ /* byte size and parity */
-+ switch (cflag & CSIZE) {
-+ case CS5: uart_mc = UART_MC_CLS_CHARLEN_5; break;
-+ case CS6: uart_mc = UART_MC_CLS_CHARLEN_6; break;
-+ case CS7: uart_mc = UART_MC_CLS_CHARLEN_7; break;
-+ default: uart_mc = UART_MC_CLS_CHARLEN_8; break; // CS8
-+ }
-+ if (cflag & CSTOPB)
-+ uart_mc|= UART_MC_ST_TWO;
-+ if (cflag & PARENB) {
-+ uart_mc |= UART_MC_PE_MSK;
-+ if (!(cflag & PARODD))
-+ uart_mc |= UART_MC_EP_MSK;
-+ }
-+
-+ port->read_status_mask = UART_RDS_OE_MSK;
-+ if (iflag & INPCK)
-+ port->read_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;
-+ if (iflag & (BRKINT | PARMRK))
-+ port->read_status_mask |= UART_RDS_BI_MSK;
-+
-+ /*
-+ * Characters to ignore
-+ */
-+ port->ignore_status_mask = 0;
-+ if (iflag & IGNPAR)
-+ port->ignore_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;
-+ if (iflag & IGNBRK) {
-+ port->ignore_status_mask |= UART_RDS_BI_MSK;
-+ /*
-+ * If we're ignoring parity and break indicators,
-+ * ignore overruns to (for real raw support).
-+ */
-+ if (iflag & IGNPAR)
-+ port->ignore_status_mask |= UART_RDS_OE_MSK;
-+ }
-+
-+ /* first, disable everything */
-+ save_flags(flags); cli();
-+ old_ies = UART_GET_IES(port);
-+
-+ if ((port->flags & ASYNC_HARDPPS_CD) ||
-+ (cflag & CRTSCTS) || !(cflag & CLOCAL))
-+ old_ies |= UART_IES_ME_MSK;
-+
-+
-+ /* Set baud rate */
-+ UART_PUT_DIV_LO(port, (quot & 0xff));
-+ UART_PUT_DIV_HI(port, ((quot & 0xf00) >> 8));
-+
-+
-+ UART_PUT_MC(port, uart_mc);
-+ UART_PUT_IES(port, old_ies);
-+
-+ restore_flags(flags);
-+}
-+
-+static int uart00_startup(struct uart_port *port)
-+{
-+ int retval;
-+
-+ /*
-+ * Allocate the IRQ
-+ */
-+ retval = request_irq(port->irq, uart00_int, 0, "uart00", port);
-+ if (retval)
-+ return retval;
-+
-+ /*
-+ * Finally, enable interrupts. Use the TII interrupt to minimise
-+ * the number of interrupts generated. If higher performance is
-+ * needed, consider using the TI interrupt with a suitable FIFO
-+ * threshold
-+ */
-+ UART_PUT_IES(port, UART_IES_RE_MSK | UART_IES_TIE_MSK);
-+
-+ return 0;
-+}
-+
-+static void uart00_shutdown(struct uart_port *port)
-+{
-+ /*
-+ * disable all interrupts, disable the port
-+ */
-+ UART_PUT_IEC(port, 0xff);
-+
-+ /* disable break condition and fifos */
-+ UART_PUT_MCR(port, UART_GET_MCR(port) &~UART_MCR_BR_MSK);
-+
-+ /*
-+ * Free the interrupt
-+ */
-+ free_irq(port->irq, port);
-+}
-+
-+static const char *uart00_type(struct uart_port *port)
-+{
-+ return port->type == PORT_UART00 ? "Altera UART00" : NULL;
-+}
-+
-+/*
-+ * Release the memory region(s) being used by 'port'
-+ */
-+static void uart00_release_port(struct uart_port *port)
-+{
-+ release_mem_region(port->mapbase, UART_PORT_SIZE);
-+
-+#ifdef CONFIG_ARCH_CAMELOT
-+ if(port->membase!=(void*)IO_ADDRESS(EXC_UART00_BASE)){
-+ iounmap(port->membase);
-+ }
-+#endif
-+}
-+
-+/*
-+ * Request the memory region(s) being used by 'port'
-+ */
-+static int uart00_request_port(struct uart_port *port)
-+{
-+ int result;
-+
-+ result = request_mem_region(port->mapbase, UART_PORT_SIZE,
-+ "serial_uart00") != NULL ? 0 : -EBUSY;
-+ if (result)
-+ return result;
-+
-+ port->membase = ioremap(port->mapbase, SZ_4K);
-+ if (!port->membase) {
-+ printk(KERN_ERR "serial00: cannot map io memory\n");
-+ release_mem_region(port->mapbase, UART_PORT_SIZE);
-+ }
-+
-+ return port->membase ? 0 : -ENOMEM;
-+}
-+
-+/*
-+ * Configure/autoconfigure the port.
-+ */
-+static void uart00_config_port(struct uart_port *port, int flags)
-+{
-+ if (flags & UART_CONFIG_TYPE) {
-+ if (uart00_request_port(port) == 0)
-+ port->type = PORT_UART00;
-+ }
-+}
-+
-+/*
-+ * verify the new serial_struct (for TIOCSSERIAL).
-+ */
-+static int uart00_verify_port(struct uart_port *port, struct serial_struct *ser)
-+{
-+ int ret = 0;
-+ if (ser->type != PORT_UNKNOWN && ser->type != PORT_UART00)
-+ ret = -EINVAL;
-+ if (ser->irq < 0 || ser->irq >= NR_IRQS)
-+ ret = -EINVAL;
-+ if (ser->baud_base < 9600)
-+ ret = -EINVAL;
-+ return ret;
-+}
-+
-+static struct uart_ops uart00_pops = {
-+ tx_empty: uart00_tx_empty,
-+ set_mctrl: uart00_set_mctrl,
-+ get_mctrl: uart00_get_mctrl,
-+ stop_tx: uart00_stop_tx,
-+ start_tx: uart00_start_tx,
-+ stop_rx: uart00_stop_rx,
-+ enable_ms: uart00_enable_ms,
-+ break_ctl: uart00_break_ctl,
-+ startup: uart00_startup,
-+ shutdown: uart00_shutdown,
-+ change_speed: uart00_change_speed,
-+ type: uart00_type,
-+ release_port: uart00_release_port,
-+ request_port: uart00_request_port,
-+ config_port: uart00_config_port,
-+ verify_port: uart00_verify_port,
-+};
-+
-+static struct uart_port uart00_ports[UART_NR] = {
-+
-+#ifdef CONFIG_ARCH_CAMELOT
-+{
-+ .membase = (void*)IO_ADDRESS(EXC_UART00_BASE),
-+ .mapbase = EXC_UART00_BASE,
-+ .iotype = SERIAL_IO_MEM,
-+ .irq = IRQ_UART,
-+ .uartclk = EXC_AHB2_CLK_FREQUENCY,
-+ .fifosize = 16,
-+ .ops = &uart00_pops,
-+ .flags = ASYNC_BOOT_AUTOCONF,
-+}
-+#endif
-+};
-+
-+#ifdef CONFIG_SERIAL_UART00_CONSOLE
-+static void uart00_console_write(struct console *co, const char *s, unsigned count)
-+{
-+#ifdef CONFIG_ARCH_CAMELOT
-+ struct uart_port *port = &uart00_ports[0];
-+ unsigned int status, old_ies;
-+ int i;
-+
-+ /*
-+ * First save the CR then disable the interrupts
-+ */
-+ old_ies = UART_GET_IES(port);
-+ UART_PUT_IEC(port,0xff);
-+
-+ /*
-+ * Now, do each character
-+ */
-+ for (i = 0; i < count; i++) {
-+ do {
-+ status = UART_GET_TSR(port);
-+ } while (!UART_TX_READY(status));
-+ UART_PUT_CHAR(port, s[i]);
-+ if (s[i] == '\n') {
-+ do {
-+ status = UART_GET_TSR(port);
-+ } while (!UART_TX_READY(status));
-+ UART_PUT_CHAR(port, '\r');
-+ }
-+ }
-+
-+ /*
-+ * Finally, wait for transmitter to become empty
-+ * and restore the IES
-+ */
-+ do {
-+ status = UART_GET_TSR(port);
-+ } while (status & UART_TSR_TX_LEVEL_MSK);
-+ UART_PUT_IES(port, old_ies);
-+#endif
-+}
-+
-+static kdev_t uart00_console_device(struct console *co)
-+{
-+ return MKDEV(SERIAL_UART00_MAJOR, SERIAL_UART00_MINOR + co->index);
-+}
-+
-+static void /*__init*/ uart00_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
-+{
-+ u_int uart_mc, quot;
-+ uart_mc= UART_GET_MC(port);
-+
-+ *parity = 'n';
-+ if (uart_mc & UART_MC_PE_MSK) {
-+ if (uart_mc & UART_MC_EP_MSK)
-+ *parity = 'e';
-+ else
-+ *parity = 'o';
-+ }
-+
-+ switch (uart_mc & UART_MC_CLS_MSK){
-+
-+ case UART_MC_CLS_CHARLEN_5:
-+ *bits = 5;
-+ break;
-+ case UART_MC_CLS_CHARLEN_6:
-+ *bits = 6;
-+ break;
-+ case UART_MC_CLS_CHARLEN_7:
-+ *bits = 7;
-+ break;
-+ case UART_MC_CLS_CHARLEN_8:
-+ *bits = 8;
-+ break;
-+ }
-+ quot = UART_GET_DIV_LO(port) | (UART_GET_DIV_HI(port) << 8);
-+ *baud = port->uartclk / (16 *quot );
-+}
-+
-+static int __init uart00_console_setup(struct console *co, char *options)
-+{
-+ struct uart_port *port;
-+ int baud = 38400;
-+ int bits = 8;
-+ int parity = 'n';
-+ int flow= 'n';
-+
-+#ifdef CONFIG_ARCH_CAMELOT
-+ /*
-+ * Check whether an invalid uart number has been specified, and
-+ * if so, search for the first available port that does have
-+ * console support.
-+ */
-+ port = &uart00_ports[0];
-+ co->index = 0;
-+#else
-+ return -ENODEV;
-+#endif
-+
-+ if (options)
-+ uart_parse_options(options, &baud, &parity, &bits, &flow);
-+ else
-+ uart00_console_get_options(port, &baud, &parity, &bits);
-+
-+ return uart_set_options(port, co, baud, parity, bits, flow);
-+}
-+
-+static struct console uart00_console = {
-+ .name = SERIAL_UART00_NAME,
-+ .write = uart00_console_write,
-+ .device = uart00_console_device,
-+ .setup = uart00_console_setup,
-+ .flags = CON_PRINTBUFFER,
-+ .index = 0,
-+};
-+
-+void __init uart00_console_init(void)
-+{
-+ register_console(&uart00_console);
-+}
-+
-+#define UART00_CONSOLE &uart00_console
-+#else
-+#define UART00_CONSOLE NULL
-+#endif
-+
-+static struct uart_driver uart00_reg = {
-+ .owner = NULL,
-+ .normal_major = SERIAL_UART00_MAJOR,
-+ .normal_name = SERIAL_UART00_NAME,
-+ .normal_driver = &normal,
-+ .callout_major = CALLOUT_UART00_MAJOR,
-+ .callout_name = CALLOUT_UART00_NAME,
-+ .callout_driver = &callout,
-+ .table = uart00_table,
-+ .termios = uart00_termios,
-+ .termios_locked = uart00_termios_locked,
-+ .minor = SERIAL_UART00_MINOR,
-+ .nr = UART_NR,
-+ .state = NULL,
-+ .cons = UART00_CONSOLE,
-+};
-+
-+struct dev_port_entry{
-+ struct uart_port *port;
-+};
-+
-+static struct dev_port_entry dev_port_map[UART_NR];
-+
-+#ifdef CONFIG_PLD_HOTSWAP
-+/*
-+ * Keep a mapping of dev_info addresses -> port lines to use when
-+ * removing ports dev==NULL indicates unused entry
-+ */
-+
-+struct uart00_ps_data{
-+ unsigned int clk;
-+ unsigned int fifosize;
-+};
-+
-+int uart00_add_device(struct pldhs_dev_info* dev_info, void* dev_ps_data)
-+{
-+ struct uart00_ps_data* dev_ps=dev_ps_data;
-+ struct uart_port * port;
-+ int i,result;
-+
-+ i=0;
-+ while(dev_port_map[i].port)
-+ i++;
-+
-+ if(i==UART_NR){
-+ printk(KERN_WARNING "uart00: Maximum number of ports reached\n");
-+ return 0;
-+ }
-+
-+ port=&uart00_ports[i];
-+
-+ printk("clk=%d fifo=%d\n",dev_ps->clk,dev_ps->fifosize);
-+ port->membase=0;
-+ port->mapbase=dev_info->base_addr;
-+ port->iotype=SERIAL_IO_MEM;
-+ port->irq=dev_info->irq;
-+ port->uartclk=dev_ps->clk;
-+ port->fifosize=dev_ps->fifosize;
-+ port->ops=&uart00_pops;
-+ port->line=i;
-+ port->flags=ASYNC_BOOT_AUTOCONF;
-+
-+ result=uart_register_port(&uart00_reg, port);
-+ if(result<0){
-+ printk("uart_register_port returned %d\n",result);
-+ return result;
-+ }
-+ dev_port_map[i].port=port;
-+ printk("uart00: added device at %lx as ttyUA%d\n",dev_port_map[i].port->mapbase,i);
-+ return 0;
-+
-+}
-+
-+int uart00_remove_devices(void)
-+{
-+ int i,result;
-+
-+
-+ result=0;
-+ for(i=1;i<UART_NR;i++){
-+ if(dev_port_map[i].port){
-+ uart_unregister_port(&uart00_reg,i);
-+ dev_port_map[i].port=NULL;
-+ }
-+ }
-+ return 0;
-+
-+}
-+
-+#ifdef CONFIG_PROC_FS
-+
-+
-+int uart00_proc_read(char* buf,char** start,off_t offset,int count,int *eof,void *data){
-+
-+ int i,len=0;
-+ struct uart_port *port;
-+ int limit = count - 80;
-+ char ps_data[80];
-+ if(*start)
-+ buf=*start;
-+ for(i=0;(i<UART_NR)&&(len<limit);i++){
-+ if(dev_port_map[i].port){
-+ port=dev_port_map[i].port;
-+ sprintf(ps_data,"clk, %dHz, fifo size, %dbytes",
-+ port->uartclk,port->fifosize);
-+ len+=PLDHS_READ_PROC_DATA(buf+len,"uart00",i,
-+ port->mapbase,port->irq,ps_data);
-+
-+ }
-+ }
-+ *eof=1;
-+ return len;
-+}
-+
-+
-+
-+#endif
-+struct pld_hotswap_ops uart00_pldhs_ops={
-+ .name = "uart00",
-+ .add_device = uart00_add_device,
-+ .remove_devices = uart00_remove_devices,
-+ .proc_read = uart00_proc_read
-+};
-+
-+#endif
-+
-+static int __init uart00_init(void)
-+{
-+ int ret;
-+ int i;
-+
-+ ret = uart_register_driver(&uart00_reg);
-+ if (ret) {
-+ printk(KERN_ERR "uart00: Couldn't register driver\n");
-+ return ret;
-+ }
-+
-+ unregister_console(&uart00_console);
-+
-+ for(i=0;i<UART_NR;i++){
-+ uart00_ports[i].ops=&uart00_pops;
-+ }
-+
-+ printk(KERN_WARNING "uart00:Using temporary major/minor pairs - these WILL change in the future\n");
-+
-+#ifdef CONFIG_PLD_HOTSWAP
-+ pldhs_register_driver(&uart00_pldhs_ops);
-+#endif
-+ for (i=0; i<UART_NR; i++)
-+ uart_add_one_port(&uart00_reg,&uart00_ports[i]);
-+
-+ uart00_console.flags = 0;
-+ register_console(&uart00_console);
-+#ifdef CONFIG_ARCH_CAMELOT
-+ dev_port_map[0].port=uart00_ports;
-+#endif
-+ return ret;
-+}
-+
-+
-+__initcall(uart00_init);
-+
-+
---- linux-2.4.25/drivers/sound/.version~2.4.25-vrs2.patch
-+++ linux-2.4.25/drivers/sound/.version
--3.8s
--0x030804
---- linux-2.4.25/drivers/sound/Config.in~2.4.25-vrs2.patch 2003-11-28 19:26:20.000000000 +0100
-+++ linux-2.4.25/drivers/sound/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -131,6 +131,17 @@
- dep_tristate ' VIA 82C686 Audio Codec' CONFIG_SOUND_VIA82CXXX $CONFIG_PCI
- dep_mbool ' VIA 82C686 MIDI' CONFIG_MIDI_VIA82CXXX $CONFIG_SOUND_VIA82CXXX
-
-+if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
-+ dep_tristate ' StrongARM-11x0 Sound Drivers' CONFIG_SOUND_SA1100 $CONFIG_ARCH_SA1100 $CONFIG_SOUND
-+ dep_tristate ' UDA1341 Stereo Codec' CONFIG_SOUND_UDA1341 $CONFIG_L3 $CONFIG_SOUND_SA1100 $CONFIG_SOUND
-+ dep_tristate ' Assabet audio support' CONFIG_SOUND_ASSABET_UDA1341 $CONFIG_SA1100_ASSABET $CONFIG_SOUND_UDA1341
-+ dep_tristate ' Compaq iPAQ audio support' CONFIG_SOUND_H3600_UDA1341 $CONFIG_SA1100_H3600 $CONFIG_SOUND_UDA1341
-+ dep_tristate ' Pangolin audio support' CONFIG_SOUND_PANGOLIN_UDA1341 $CONFIG_SA1100_PANGOLIN $CONFIG_SOUND_UDA1341
-+ dep_tristate ' SA1111 audio support' CONFIG_SOUND_SA1111_UDA1341 $CONFIG_SA1111 $CONFIG_SOUND_UDA1341
-+ dep_tristate ' SA1111 AC97 Sound' CONFIG_SOUND_SA1111_AC97 $CONFIG_SA1111 $CONFIG_SOUND_SA1100
-+ dep_tristate ' Generic DAC on the SA11x0 SSP port' CONFIG_SOUND_SA1100SSP $CONFIG_SOUND_SA1100
-+fi
-+
- dep_tristate ' OSS sound modules' CONFIG_SOUND_OSS $CONFIG_SOUND
-
- if [ "$CONFIG_SOUND_OSS" = "y" -o "$CONFIG_SOUND_OSS" = "m" ]; then
-@@ -220,14 +231,14 @@
- bool ' Audio Excel DSP 16 (MPU401 emulation)' CONFIG_AEDSP16_MPU401
- fi
- fi
-+
-+fi
-
-- if [ "$CONFIG_ARM" = "y" ]; then
-- if [ "$CONFIG_ARCH_ACORN" = "y" -o "$CONFIG_ARCH_CLPS7500" = "y" ]; then
-- dep_tristate ' VIDC 16-bit sound' CONFIG_SOUND_VIDC $CONFIG_SOUND_OSS
-- fi
-- dep_tristate ' Netwinder WaveArtist' CONFIG_SOUND_WAVEARTIST $CONFIG_SOUND_OSS $CONFIG_ARCH_NETWINDER
-+if [ "$CONFIG_ARM" = "y" ]; then
-+ if [ "$CONFIG_ARCH_ACORN" = "y" -o "$CONFIG_ARCH_CLPS7500" = "y" -o "$CONFIG_ARCH_RISCSTATION" ]; then
-+ dep_tristate ' VIDC 16-bit sound' CONFIG_SOUND_VIDC $CONFIG_SOUND_OSS
- fi
--
-+ dep_tristate ' Netwinder WaveArtist' CONFIG_SOUND_WAVEARTIST $CONFIG_SOUND_OSS $CONFIG_ARCH_NETWINDER
- fi
-
- dep_tristate ' TV card (bt848) mixer support' CONFIG_SOUND_TVMIXER $CONFIG_SOUND $CONFIG_I2C
---- linux-2.4.25/drivers/sound/Makefile~2.4.25-vrs2.patch 2003-11-28 19:26:20.000000000 +0100
-+++ linux-2.4.25/drivers/sound/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -10,7 +10,8 @@
- export-objs := ad1848.o audio_syms.o midi_syms.o mpu401.o \
- msnd.o opl3.o sb_common.o sequencer_syms.o \
- sound_core.o sound_syms.o uart401.o \
-- nm256_audio.o ac97.o ac97_codec.o aci.o
-+ nm256_audio.o ac97.o ac97_codec.o aci.o \
-+ sa1100-audio.o
-
- # Each configuration option enables a list of files.
-
-@@ -76,6 +77,14 @@
- obj-$(CONFIG_SOUND_FORTE) += forte.o ac97_codec.o
- obj-$(CONFIG_SOUND_TRIDENT) += trident.o ac97_codec.o
- obj-$(CONFIG_SOUND_HARMONY) += harmony.o
-+obj-$(CONFIG_SOUND_SA1100) += sa1100-audio.o
-+obj-$(CONFIG_SOUND_UDA1341) += uda1341.o
-+obj-$(CONFIG_SOUND_ASSABET_UDA1341) += assabet-uda1341.o
-+obj-$(CONFIG_SOUND_PANGOLIN_UDA1341) += pangolin-uda1341.o
-+obj-$(CONFIG_SOUND_H3600_UDA1341) += h3600-uda1341.o
-+obj-$(CONFIG_SOUND_SA1111_UDA1341) += sa1111-uda1341.o
-+obj-$(CONFIG_SOUND_SA1111_AC97) += sa1111-ac97.o ac97_codec.o
-+obj-$(CONFIG_SOUND_SA1100SSP) += sa1100ssp.o
- obj-$(CONFIG_SOUND_EMU10K1) += ac97_codec.o
- obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o
- obj-$(CONFIG_SOUND_RME96XX) += rme96xx.o
-@@ -105,7 +114,6 @@
- obj-y += dmasound/dmasound.o
- endif
-
--
- # Declare multi-part drivers.
-
- list-multi := sound.o gus.o pas2.o sb.o sb_lib.o vidc_mod.o \
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/sound/assabet-uda1341.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,404 @@
-+/*
-+ * Glue audio driver for the SA1110 Assabet board & Philips UDA1341 codec.
-+ *
-+ * Copyright (c) 2000 Nicolas Pitre <nico@cam.org>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License.
-+ *
-+ * This is the machine specific part of the Assabet/UDA1341 support.
-+ * This driver makes use of the UDA1341 and the sa1100-audio modules.
-+ *
-+ * History:
-+ *
-+ * 2000-05-21 Nicolas Pitre Initial release.
-+ *
-+ * 2001-06-03 Nicolas Pitre Made this file a separate module, based on
-+ * the former sa1100-uda1341.c driver.
-+ *
-+ * 2001-07-17 Nicolas Pitre Supports 44100Hz and 22050Hz samplerate now.
-+ *
-+ * 2001-08-03 Russell King Fix left/right channel swap.
-+ * Attempt to reduce power consumption when idle.
-+ *
-+ * 2001-09-23 Russell King Remove old L3 bus driver.
-+ *
-+ * Please note that fiddling too much with MDREFR results in oopses, so we don't
-+ * touch MDREFR unnecessarily, which means we don't touch it on close.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/fs.h>
-+#include <linux/delay.h>
-+#include <linux/pm.h>
-+#include <linux/errno.h>
-+#include <linux/sound.h>
-+#include <linux/soundcard.h>
-+#include <linux/cpufreq.h>
-+#include <linux/l3/l3.h>
-+#include <linux/l3/uda1341.h>
-+
-+#include <asm/semaphore.h>
-+#include <asm/uaccess.h>
-+#include <asm/hardware.h>
-+#include <asm/dma.h>
-+#include <asm/arch/assabet.h>
-+
-+#include "sa1100-audio.h"
-+
-+/*
-+ * Define this to fix the power drain on early Assabets
-+ */
-+#define FIX_POWER_DRAIN
-+
-+/*
-+ * Debugging?
-+ */
-+#undef DEBUG
-+
-+
-+#ifdef DEBUG
-+#define DPRINTK( x... ) printk( ##x )
-+#else
-+#define DPRINTK( x... )
-+#endif
-+
-+
-+#define AUDIO_RATE_DEFAULT 44100
-+
-+/*
-+ * Mixer (UDA1341) interface
-+ */
-+
-+static struct l3_client uda1341;
-+
-+static int
-+mixer_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
-+{
-+ /*
-+ * We only accept mixer (type 'M') ioctls.
-+ */
-+ if (_IOC_TYPE(cmd) != 'M')
-+ return -EINVAL;
-+
-+ return l3_command(&uda1341, cmd, (void *)arg);
-+}
-+
-+static struct file_operations assabet_mixer_fops = {
-+ ioctl: mixer_ioctl,
-+ owner: THIS_MODULE
-+};
-+
-+
-+/*
-+ * Audio interface
-+ */
-+static long audio_samplerate = AUDIO_RATE_DEFAULT;
-+
-+/*
-+ * FIXME: what about SFRM going high when SSP is disabled?
-+ */
-+static void assabet_set_samplerate(long val)
-+{
-+ struct uda1341_cfg cfg;
-+ u_int clk_ref, clk_div;
-+
-+ /* We don't want to mess with clocks when frames are in flight */
-+ Ser4SSCR0 &= ~SSCR0_SSE;
-+ /* wait for any frame to complete */
-+ udelay(125);
-+
-+ /*
-+ * Our clock source is derived from the CPLD on which we don't have
-+ * much control unfortunately. This was intended for a fixed 48000 Hz
-+ * samplerate assuming a core clock of 221.2 MHz. The CPLD appears
-+ * to divide the memory clock so there is a ratio of 4608 between
-+ * the core clock and the resulting samplerate (obtained by
-+ * measurements, the CPLD equations should confirm that).
-+ *
-+ * Still we can play with the SA1110's clock divisor for the SSP port
-+ * to get half the samplerate as well.
-+ *
-+ * Apparently the clock sent to the SA1110 for the SSP port is further
-+ * more divided from the clock sent to the UDA1341 (some people tried
-+ * to be too clever in their design, or simply failed to read the
-+ * SA1110 manual). If it was the same clock we would have been able
-+ * to support a third samplerate with the UDA1341's 384FS mode.
-+ *
-+ * At least it would have been a minimum acceptable solution to be
-+ * able to set the CPLD divisor by software. The iPAQ design is
-+ * certainly a better example to follow for a new design.
-+ */
-+ clk_ref = cpufreq_get(0) * 1000 / 4608;
-+ if (val > clk_ref*4/7) {
-+ audio_samplerate = clk_ref;
-+ cfg.fs = 256;
-+ clk_div = SSCR0_SerClkDiv(2);
-+ } else {
-+ audio_samplerate = clk_ref/2;
-+ cfg.fs = 512;
-+ clk_div = SSCR0_SerClkDiv(4);
-+ }
-+
-+ cfg.format = FMT_LSB16;
-+ l3_command(&uda1341, L3_UDA1341_CONFIGURE, &cfg);
-+
-+ Ser4SSCR0 = (Ser4SSCR0 & ~0xff00) + clk_div + SSCR0_SSE;
-+}
-+
-+/*
-+ * Initialise the Assabet audio driver.
-+ *
-+ * Note that we have to be careful with the order that we do things here;
-+ * there is a D-type flip flop which is clocked from the SFRM line which
-+ * indicates whether the same is for the left or right channel to the
-+ * UDA1341.
-+ *
-+ * When you disable the SSP (by clearing SSCR0_SSE) it appears that the
-+ * SFRM signal can float high. When you re-enable the SSP, you clock the
-+ * flip flop once, and end up swapping the left and right channels.
-+ *
-+ * The ASSABET_BCR_CODEC_RST line will force this flip flop into a known
-+ * state, but this line resets other devices as well!
-+ *
-+ * In addition to the above, it appears that powering down the UDA1341 on
-+ * early Assabets leaves the UDA_WS actively driving a logic '1' into the
-+ * chip, wasting power! (you can tell this by D11 being half-on). We
-+ * attempt to correct this by kicking the flip flop on init/open/close.
-+ * We should probably do this on PM resume as well.
-+ *
-+ * (Note the ordering of ASSABET_BCR_AUDIO_ON, SFRM and ASSABET_BCR_CODEC_RST
-+ * is important).
-+ */
-+static void assabet_audio_init(void *dummy)
-+{
-+ unsigned long flags;
-+ unsigned int mdrefr;
-+
-+ local_irq_save(flags);
-+
-+ /*
-+ * Enable the power for the UDA1341 before driving any signals.
-+ * We leave the audio amp (LM4880) disabled for now.
-+ */
-+ ASSABET_BCR_set(ASSABET_BCR_AUDIO_ON);
-+
-+#ifdef FIX_POWER_DRAIN
-+ GPSR = GPIO_SSP_SFRM;
-+ GPCR = GPIO_SSP_SFRM;
-+#endif
-+
-+ ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
-+ ASSABET_BCR_clear(ASSABET_BCR_STEREO_LB);
-+
-+ /*
-+ * Setup the SSP uart.
-+ */
-+ PPAR |= PPAR_SPR;
-+ Ser4SSCR0 = SSCR0_DataSize(16) + SSCR0_TI + SSCR0_SerClkDiv(2);
-+ Ser4SSCR1 = SSCR1_SClkIactL + SSCR1_SClk1P + SSCR1_ExtClk;
-+ GAFR |= GPIO_SSP_TXD | GPIO_SSP_RXD | GPIO_SSP_SCLK | GPIO_SSP_CLK;
-+ GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
-+ GPDR &= ~(GPIO_SSP_RXD | GPIO_SSP_CLK);
-+ Ser4SSCR0 |= SSCR0_SSE;
-+
-+ /*
-+ * Only give SFRM to the SSP after it has been enabled.
-+ */
-+ GAFR |= GPIO_SSP_SFRM;
-+
-+ /*
-+ * The assabet board uses the SDRAM clock as the source clock for
-+ * audio. This is supplied to the SA11x0 from the CPLD on pin 19.
-+ * At 206MHz we need to run the audio clock (SDRAM bank 2)
-+ * at half speed. This clock will scale with core frequency so
-+ * the audio sample rate will also scale. The CPLD on Assabet
-+ * will need to be programmed to match the core frequency.
-+ */
-+ mdrefr = MDREFR;
-+ if ((mdrefr & (MDREFR_K2DB2 | MDREFR_K2RUN | MDREFR_EAPD |
-+ MDREFR_KAPD)) != (MDREFR_K2DB2 | MDREFR_K2RUN)) {
-+ mdrefr |= MDREFR_K2DB2 | MDREFR_K2RUN;
-+ mdrefr &= ~(MDREFR_EAPD | MDREFR_KAPD);
-+ MDREFR = mdrefr;
-+ (void) MDREFR;
-+ }
-+ local_irq_restore(flags);
-+
-+ /* Wait for the UDA1341 to wake up */
-+ mdelay(1);
-+
-+ l3_open(&uda1341);
-+
-+ assabet_set_samplerate(audio_samplerate);
-+
-+ /* Enable the audio power */
-+ ASSABET_BCR_clear(ASSABET_BCR_QMUTE | ASSABET_BCR_SPK_OFF);
-+}
-+
-+/*
-+ * Shutdown the Assabet audio driver.
-+ *
-+ * We have to be careful about the SFRM line here for the same reasons
-+ * described in the initialisation comments above. This basically means
-+ * that we must hand the SSP pins back to the GPIO module before disabling
-+ * the SSP.
-+ *
-+ * In addition, to reduce power drain, we toggle the SFRM line once so
-+ * that the UDA_WS line is at logic 0.
-+ *
-+ * We can't clear ASSABET_BCR_CODEC_RST without knowing if the UCB1300 or
-+ * ADV7171 driver is still active. If it is, then we still need to play
-+ * games, so we might as well leave ASSABET_BCR_CODEC_RST set.
-+ */
-+static void assabet_audio_shutdown(void *dummy)
-+{
-+ ASSABET_BCR_set(ASSABET_BCR_STEREO_LB | ASSABET_BCR_QMUTE |
-+ ASSABET_BCR_SPK_OFF);
-+
-+ l3_close(&uda1341);
-+
-+ GAFR &= ~(GPIO_SSP_TXD | GPIO_SSP_RXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM);
-+ Ser4SSCR0 = 0;
-+
-+#ifdef FIX_POWER_DRAIN
-+ GPSR = GPIO_SSP_SFRM;
-+ GPCR = GPIO_SSP_SFRM;
-+#endif
-+
-+ /* disable the audio power */
-+ ASSABET_BCR_clear(ASSABET_BCR_AUDIO_ON);
-+}
-+
-+static int assabet_audio_ioctl( struct inode *inode, struct file *file,
-+ uint cmd, ulong arg)
-+{
-+ long val;
-+ int ret = 0;
-+
-+ /*
-+ * These are platform dependent ioctls which are not handled by the
-+ * generic sa1100-audio module.
-+ */
-+ switch (cmd) {
-+ case SNDCTL_DSP_STEREO:
-+ ret = get_user(val, (int *) arg);
-+ if (ret)
-+ return ret;
-+ /* the UDA1341 is stereo only */
-+ ret = (val == 0) ? -EINVAL : 1;
-+ return put_user(ret, (int *) arg);
-+
-+ case SNDCTL_DSP_CHANNELS:
-+ case SOUND_PCM_READ_CHANNELS:
-+ /* the UDA1341 is stereo only */
-+ return put_user(2, (long *) arg);
-+
-+ case SNDCTL_DSP_SPEED:
-+ ret = get_user(val, (long *) arg);
-+ if (ret) break;
-+ assabet_set_samplerate(val);
-+ /* fall through */
-+
-+ case SOUND_PCM_READ_RATE:
-+ return put_user(audio_samplerate, (long *) arg);
-+
-+ case SNDCTL_DSP_SETFMT:
-+ case SNDCTL_DSP_GETFMTS:
-+ /* we can do signed 16-bit only */
-+ return put_user(AFMT_S16_LE, (long *) arg);
-+
-+ default:
-+ /* Maybe this is meant for the mixer (As per OSS Docs) */
-+ return mixer_ioctl(inode, file, cmd, arg);
-+ }
-+
-+ return ret;
-+}
-+
-+static audio_stream_t output_stream, input_stream;
-+
-+static audio_state_t audio_state = {
-+ output_stream: &output_stream,
-+ output_dma: DMA_Ser4SSPWr,
-+ output_id: "Assabet UDA1341 out",
-+ input_stream: &input_stream,
-+ input_dma: DMA_Ser4SSPRd,
-+ input_id: "Assabet UDA1341 in",
-+ need_tx_for_rx: 1,
-+ hw_init: assabet_audio_init,
-+ hw_shutdown: assabet_audio_shutdown,
-+ client_ioctl: assabet_audio_ioctl,
-+ sem: __MUTEX_INITIALIZER(audio_state.sem),
-+};
-+
-+static int assabet_audio_open(struct inode *inode, struct file *file)
-+{
-+ return sa1100_audio_attach(inode, file, &audio_state);
-+}
-+
-+/*
-+ * Missing fields of this structure will be patched with the call
-+ * to sa1100_audio_attach().
-+ */
-+static struct file_operations assabet_audio_fops = {
-+ open: assabet_audio_open,
-+ owner: THIS_MODULE
-+};
-+
-+
-+static int audio_dev_id, mixer_dev_id;
-+
-+static int __init assabet_uda1341_init(void)
-+{
-+ int ret;
-+
-+ if (!machine_is_assabet())
-+ return -ENODEV;
-+
-+ ret = l3_attach_client(&uda1341, "l3-bit-sa1100-gpio", "uda1341");
-+ if (ret)
-+ goto out;
-+
-+ /* register devices */
-+ audio_dev_id = register_sound_dsp(&assabet_audio_fops, -1);
-+ mixer_dev_id = register_sound_mixer(&assabet_mixer_fops, -1);
-+
-+#ifdef FIX_POWER_DRAIN
-+ {
-+ unsigned long flags;
-+ local_irq_save(flags);
-+ ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
-+ GPSR = GPIO_SSP_SFRM;
-+ GPDR |= GPIO_SSP_SFRM;
-+ GPCR = GPIO_SSP_SFRM;
-+ local_irq_restore(flags);
-+ }
-+#endif
-+
-+ printk(KERN_INFO "Sound: Assabet UDA1341: dsp id %d mixer id %d\n",
-+ audio_dev_id, mixer_dev_id);
-+ return 0;
-+
-+release_l3:
-+ l3_detach_client(&uda1341);
-+out:
-+ return ret;
-+}
-+
-+static void __exit assabet_uda1341_exit(void)
-+{
-+ unregister_sound_dsp(audio_dev_id);
-+ unregister_sound_mixer(mixer_dev_id);
-+ l3_detach_client(&uda1341);
-+}
-+
-+module_init(assabet_uda1341_init);
-+module_exit(assabet_uda1341_exit);
-+
-+MODULE_AUTHOR("Nicolas Pitre");
-+MODULE_DESCRIPTION("Glue audio driver for the SA1110 Assabet board & Philips UDA1341 codec.");
-+
-+EXPORT_NO_SYMBOLS;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/sound/h3600-uda1341.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,352 @@
-+/*
-+ * Glue audio driver for the Compaq iPAQ H3600 & Philips UDA1341 codec.
-+ *
-+ * Copyright (c) 2000 Nicolas Pitre <nico@cam.org>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License.
-+ *
-+ * This is the machine specific part of the Compaq iPAQ (aka Bitsy) support.
-+ * This driver makes use of the UDA1341 and the sa1100-audio modules.
-+ *
-+ * History:
-+ *
-+ * 2000-05-21 Nicolas Pitre Initial UDA1341 driver release.
-+ *
-+ * 2000-07-?? George France Bitsy support.
-+ *
-+ * 2000-12-13 Deborah Wallach Fixed power handling for iPAQ/h3600
-+ *
-+ * 2001-06-03 Nicolas Pitre Made this file a separate module, based on
-+ * the former sa1100-uda1341.c driver.
-+ *
-+ * 2001-07-13 Nicolas Pitre Fixes for all supported samplerates.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/fs.h>
-+#include <linux/delay.h>
-+#include <linux/pm.h>
-+#include <linux/errno.h>
-+#include <linux/sound.h>
-+#include <linux/soundcard.h>
-+#include <linux/l3/l3.h>
-+#include <linux/l3/uda1341.h>
-+
-+#include <asm/semaphore.h>
-+#include <asm/uaccess.h>
-+#include <asm/hardware.h>
-+#include <asm/dma.h>
-+//#include <asm/arch/h3600_hal.h>
-+
-+#include "sa1100-audio.h"
-+
-+
-+#undef DEBUG
-+#ifdef DEBUG
-+#define DPRINTK( x... ) printk( ##x )
-+#else
-+#define DPRINTK( x... )
-+#endif
-+
-+
-+#define AUDIO_NAME "Bitsy_UDA1341"
-+
-+#define AUDIO_RATE_DEFAULT 44100
-+
-+
-+static struct l3_client uda1341;
-+
-+static int
-+mixer_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
-+{
-+ /*
-+ * We only accept mixer (type 'M') ioctls.
-+ */
-+ if (_IOC_TYPE(cmd) != 'M')
-+ return -EINVAL;
-+
-+ return l3_command(&uda1341, cmd, (void *)arg);
-+}
-+
-+static struct file_operations h3600_mixer_fops = {
-+ ioctl: mixer_ioctl,
-+ owner: THIS_MODULE
-+};
-+
-+
-+/*
-+ * Audio interface
-+ */
-+
-+static long audio_samplerate = AUDIO_RATE_DEFAULT;
-+
-+/*
-+ * Stop-gap solution until rest of hh.org HAL stuff is merged.
-+ */
-+#define GPIO_H3600_CLK_SET0 GPIO_GPIO (12)
-+#define GPIO_H3600_CLK_SET1 GPIO_GPIO (13)
-+static void h3600_set_audio_clock(long val)
-+{
-+ switch (val) {
-+ case 24000: case 32000: case 48000: /* 00: 12.288 MHz */
-+ GPCR = GPIO_H3600_CLK_SET0 | GPIO_H3600_CLK_SET1;
-+ break;
-+
-+ case 22050: case 29400: case 44100: /* 01: 11.2896 MHz */
-+ GPSR = GPIO_H3600_CLK_SET0;
-+ GPCR = GPIO_H3600_CLK_SET1;
-+ break;
-+
-+ case 8000: case 10666: case 16000: /* 10: 4.096 MHz */
-+ GPCR = GPIO_H3600_CLK_SET0;
-+ GPSR = GPIO_H3600_CLK_SET1;
-+ break;
-+
-+ case 10985: case 14647: case 21970: /* 11: 5.6245 MHz */
-+ GPSR = GPIO_H3600_CLK_SET0 | GPIO_H3600_CLK_SET1;
-+ break;
-+ }
-+}
-+
-+static void h3600_set_samplerate(long val)
-+{
-+ struct uda1341_cfg cfg;
-+ int clk_div = 0;
-+
-+ /* We don't want to mess with clocks when frames are in flight */
-+ Ser4SSCR0 &= ~SSCR0_SSE;
-+ /* wait for any frame to complete */
-+ udelay(125);
-+
-+ /*
-+ * We have the following clock sources:
-+ * 4.096 MHz, 5.6245 MHz, 11.2896 MHz, 12.288 MHz
-+ * Those can be divided either by 256, 384 or 512.
-+ * This makes up 12 combinations for the following samplerates...
-+ */
-+ if (val >= 48000)
-+ val = 48000;
-+ else if (val >= 44100)
-+ val = 44100;
-+ else if (val >= 32000)
-+ val = 32000;
-+ else if (val >= 29400)
-+ val = 29400;
-+ else if (val >= 24000)
-+ val = 24000;
-+ else if (val >= 22050)
-+ val = 22050;
-+ else if (val >= 21970)
-+ val = 21970;
-+ else if (val >= 16000)
-+ val = 16000;
-+ else if (val >= 14647)
-+ val = 14647;
-+ else if (val >= 10985)
-+ val = 10985;
-+ else if (val >= 10666)
-+ val = 10666;
-+ else
-+ val = 8000;
-+
-+ /* Set the external clock generator */
-+ h3600_set_audio_clock(val);
-+
-+ /* Select the clock divisor */
-+ switch (val) {
-+ case 8000:
-+ case 10985:
-+ case 22050:
-+ case 24000:
-+ cfg.fs = 512;
-+ clk_div = SSCR0_SerClkDiv(16);
-+ break;
-+ case 16000:
-+ case 21970:
-+ case 44100:
-+ case 48000:
-+ cfg.fs = 256;
-+ clk_div = SSCR0_SerClkDiv(8);
-+ break;
-+ case 10666:
-+ case 14647:
-+ case 29400:
-+ case 32000:
-+ cfg.fs = 384;
-+ clk_div = SSCR0_SerClkDiv(12);
-+ break;
-+ }
-+
-+ cfg.format = FMT_LSB16;
-+ l3_command(&uda1341, L3_UDA1341_CONFIGURE, &cfg);
-+ Ser4SSCR0 = (Ser4SSCR0 & ~0xff00) + clk_div + SSCR0_SSE;
-+ audio_samplerate = val;
-+}
-+
-+static void h3600_audio_init(void *dummy)
-+{
-+ unsigned long flags;
-+
-+ /* Setup the uarts */
-+ local_irq_save(flags);
-+ GAFR |= (GPIO_SSP_CLK);
-+ GPDR &= ~(GPIO_SSP_CLK);
-+ Ser4SSCR0 = 0;
-+ Ser4SSCR0 = SSCR0_DataSize(16) + SSCR0_TI + SSCR0_SerClkDiv(8);
-+ Ser4SSCR1 = SSCR1_SClkIactL + SSCR1_SClk1P + SSCR1_ExtClk;
-+ Ser4SSCR0 |= SSCR0_SSE;
-+
-+ /* Enable the audio power */
-+
-+ clr_h3600_egpio(IPAQ_EGPIO_CODEC_NRESET);
-+ set_h3600_egpio(IPAQ_EGPIO_AUDIO_ON);
-+ set_h3600_egpio(IPAQ_EGPIO_QMUTE);
-+ local_irq_restore(flags);
-+
-+ /* external clock configuration */
-+ h3600_set_samplerate(audio_samplerate);
-+
-+ /* Wait for the UDA1341 to wake up */
-+ set_h3600_egpio(IPAQ_EGPIO_CODEC_NRESET);
-+ mdelay(1);
-+
-+ /* make the left and right channels unswapped (flip the WS latch ) */
-+ Ser4SSDR = 0;
-+
-+ /* Initialize the UDA1341 internal state */
-+ l3_open(&uda1341);
-+
-+ clr_h3600_egpio(IPAQ_EGPIO_QMUTE);
-+}
-+
-+static void h3600_audio_shutdown(void *dummy)
-+{
-+ /* disable the audio power and all signals leading to the audio chip */
-+ l3_close(&uda1341);
-+ Ser4SSCR0 = 0;
-+ clr_h3600_egpio(IPAQ_EGPIO_CODEC_NRESET);
-+ clr_h3600_egpio(IPAQ_EGPIO_AUDIO_ON);
-+ clr_h3600_egpio(IPAQ_EGPIO_QMUTE);
-+}
-+
-+static int h3600_audio_ioctl(struct inode *inode, struct file *file,
-+ uint cmd, ulong arg)
-+{
-+ long val;
-+ int ret = 0;
-+
-+ /*
-+ * These are platform dependent ioctls which are not handled by the
-+ * generic sa1100-audio module.
-+ */
-+ switch (cmd) {
-+ case SNDCTL_DSP_STEREO:
-+ ret = get_user(val, (int *) arg);
-+ if (ret)
-+ return ret;
-+ /* the UDA1341 is stereo only */
-+ ret = (val == 0) ? -EINVAL : 1;
-+ return put_user(ret, (int *) arg);
-+
-+ case SNDCTL_DSP_CHANNELS:
-+ case SOUND_PCM_READ_CHANNELS:
-+ /* the UDA1341 is stereo only */
-+ return put_user(2, (long *) arg);
-+
-+ case SNDCTL_DSP_SPEED:
-+ ret = get_user(val, (long *) arg);
-+ if (ret) break;
-+ h3600_set_samplerate(val);
-+ /* fall through */
-+
-+ case SOUND_PCM_READ_RATE:
-+ return put_user(audio_samplerate, (long *) arg);
-+
-+ case SNDCTL_DSP_SETFMT:
-+ case SNDCTL_DSP_GETFMTS:
-+ /* we can do 16-bit only */
-+ return put_user(AFMT_S16_LE, (long *) arg);
-+
-+ default:
-+ /* Maybe this is meant for the mixer (As per OSS Docs) */
-+ return mixer_ioctl(inode, file, cmd, arg);
-+ }
-+
-+ return ret;
-+}
-+
-+static audio_stream_t output_stream, input_stream;
-+
-+static audio_state_t audio_state = {
-+ output_stream: &output_stream,
-+ output_dma: DMA_Ser4SSPWr,
-+ output_id: "UDA1341 out",
-+ input_stream: &input_stream,
-+ input_dma: DMA_Ser4SSPRd,
-+ input_id: "UDA1341 in",
-+ need_tx_for_rx: 1,
-+ hw_init: h3600_audio_init,
-+ hw_shutdown: h3600_audio_shutdown,
-+ client_ioctl: h3600_audio_ioctl,
-+ sem: __MUTEX_INITIALIZER(audio_state.sem),
-+};
-+
-+static int h3600_audio_open(struct inode *inode, struct file *file)
-+{
-+ return sa1100_audio_attach(inode, file, &audio_state);
-+}
-+
-+/*
-+ * Missing fields of this structure will be patched with the call
-+ * to sa1100_audio_attach().
-+ */
-+static struct file_operations h3600_audio_fops = {
-+ open: h3600_audio_open,
-+ owner: THIS_MODULE
-+};
-+
-+
-+static int audio_dev_id, mixer_dev_id;
-+
-+static int __init h3600_uda1341_init(void)
-+{
-+ int ret;
-+
-+ if (!machine_is_h3xxx())
-+ return -ENODEV;
-+
-+ ret = l3_attach_client(&uda1341, "l3-bit-sa1100-gpio", "uda1341");
-+ if (ret)
-+ goto out;
-+
-+ /* register devices */
-+ audio_dev_id = register_sound_dsp(&h3600_audio_fops, -1);
-+ mixer_dev_id = register_sound_mixer(&h3600_mixer_fops, -1);
-+
-+ printk( KERN_INFO "iPAQ audio support initialized\n" );
-+ return 0;
-+
-+release_l3:
-+ l3_detach_client(&uda1341);
-+out:
-+ return ret;
-+}
-+
-+static void __exit h3600_uda1341_exit(void)
-+{
-+ unregister_sound_dsp(audio_dev_id);
-+ unregister_sound_mixer(mixer_dev_id);
-+ l3_detach_client(&uda1341);
-+}
-+
-+module_init(h3600_uda1341_init);
-+module_exit(h3600_uda1341_exit);
-+
-+MODULE_AUTHOR("Nicolas Pitre, George France");
-+MODULE_DESCRIPTION("Glue audio driver for the Compaq iPAQ H3600 & Philips UDA1341 codec.");
-+
-+EXPORT_NO_SYMBOLS;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/sound/pangolin-uda1341.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,322 @@
-+/*
-+ * Glue audio driver for the SA1110 Pangolin board & Philips UDA1341 codec.
-+ *
-+ * Copyright (c) 2000 Nicolas Pitre <nico@cam.org>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License.
-+ *
-+ * This is the machine specific part of the Pangolin/UDA1341 support.
-+ * This driver makes use of the UDA1341 and the sa1100-audio modules.
-+ *
-+ * History:
-+ *
-+ * 2000-05-21 Nicolas Pitre Initial release.
-+ *
-+ * 2001-06-03 Nicolas Pitre Made this file a separate module, based on
-+ * the former sa1100-uda1341.c driver.
-+ *
-+ * 2001-07-17 Nicolas Pitre Supports 44100Hz and 22050Hz samplerate now.
-+ *
-+ * 2001-08-06 Richard Fan Pangolin Support
-+ *
-+ * 2001-09-23 Russell King Update inline with Assabet driver
-+ * Remove old L3 bus driver
-+ *
-+ * Note: this should probably be merged with the Assabet audio driver,
-+ * and become the "SDRAM-clock driven" SA1100 audio driver.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/fs.h>
-+#include <linux/delay.h>
-+#include <linux/pm.h>
-+#include <linux/errno.h>
-+#include <linux/sound.h>
-+#include <linux/soundcard.h>
-+#include <linux/l3/l3.h>
-+#include <linux/l3/uda1341.h>
-+
-+#include <asm/semaphore.h>
-+#include <asm/uaccess.h>
-+#include <asm/hardware.h>
-+#include <asm/dma.h>
-+
-+#include "sa1100-audio.h"
-+
-+/*
-+ * Debugging?
-+ */
-+#undef DEBUG
-+
-+
-+#ifdef DEBUG
-+#define DPRINTK( x... ) printk( ##x )
-+#else
-+#define DPRINTK( x... )
-+#endif
-+
-+
-+#define AUDIO_RATE_DEFAULT 44100
-+
-+#define QmutePin GPIO_GPIO(4)
-+#define SpeakerOffPin GPIO_GPIO(5)
-+
-+/*
-+ * Mixer (UDA1341) interface
-+ */
-+
-+static struct l3_client uda1341;
-+
-+static int
-+mixer_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
-+{
-+ /*
-+ * We only accept mixer (type 'M') ioctls.
-+ */
-+ if (_IOC_TYPE(cmd) != 'M')
-+ return -EINVAL;
-+
-+ return l3_command(&uda1341, cmd, (void *)arg);
-+}
-+
-+static struct file_operations pangolin_mixer_fops = {
-+ ioctl: mixer_ioctl,
-+ owner: THIS_MODULE
-+};
-+
-+
-+/*
-+ * Audio interface
-+ */
-+static long audio_samplerate = AUDIO_RATE_DEFAULT;
-+
-+static void pangolin_set_samplerate(long val)
-+{
-+ struct uda1341_cfg cfg;
-+ int clk_div;
-+
-+ /* We don't want to mess with clocks when frames are in flight */
-+ Ser4SSCR0 &= ~SSCR0_SSE;
-+ /* wait for any frame to complete */
-+ udelay(125);
-+
-+ /*
-+ * Our clock source is derived from the CPLD on which we don't have
-+ * much control unfortunately. This was intended for a fixed 44100Hz
-+ * samplerate assuming a core clock of 206 MHz. Still we can play
-+ * with the SA1110's clock divisor for the SSP port to get a 22050Hz
-+ * samplerate.
-+ *
-+ * Apparently the clock sent to the SA1110 for the SSP port is
-+ * divided from the clock sent to the UDA1341 (some people tried to
-+ * be too clever in their design, or simply failed to read the SA1110
-+ * manual). If it was the same source we would have been able to
-+ * support a third samplerate.
-+ *
-+ * At least it would have been a minimum acceptable solution to be
-+ * able to set the CPLD divisor by software. The iPAQ design is
-+ * certainly a better example to follow for a new design.
-+ */
-+ if (val >= 44100) {
-+ audio_samplerate = 44100;
-+ cfg.fs = 256;
-+ clk_div = SSCR0_SerClkDiv(2);
-+ } else {
-+ audio_samplerate = 22050;
-+ cfg.fs = 512;
-+ clk_div = SSCR0_SerClkDiv(4);
-+ }
-+
-+ cfg.format = FMT_LSB16;
-+ l3_command(&uda1341, L3_UDA1341_CONFIGURE, &cfg);
-+
-+ Ser4SSCR0 = (Ser4SSCR0 & ~0xff00) + clk_div + SSCR0_SSE;
-+}
-+
-+static void pangolin_audio_init(void *dummy)
-+{
-+ unsigned long flags;
-+ unsigned int mdrefr;
-+
-+ local_irq_save(flags);
-+
-+ /*
-+ * Setup the SSP uart.
-+ */
-+ PPAR |= PPAR_SPR;
-+ Ser4SSCR0 = SSCR0_DataSize(16) + SSCR0_TI + SSCR0_SerClkDiv(2);
-+ Ser4SSCR1 = SSCR1_SClkIactL + SSCR1_SClk1P + SSCR1_ExtClk;
-+ GAFR |= GPIO_SSP_TXD | GPIO_SSP_RXD | GPIO_SSP_SCLK | GPIO_SSP_CLK |
-+ GPIO_SSP_SFRM;
-+ GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
-+ GPDR &= ~(GPIO_SSP_RXD | GPIO_SSP_CLK);
-+ Ser4SSCR0 |= SSCR0_SSE;
-+
-+ GAFR &= ~(SpeakerOffPin | QmutePin);
-+ GPDR |= (SpeakerOffPin | QmutePin);
-+ GPCR = SpeakerOffPin;
-+
-+ /*
-+ * The assabet board uses the SDRAM clock as the source clock for
-+ * audio. This is supplied to the SA11x0 from the CPLD on pin 19.
-+ * At 206MHz we need to run the audio clock (SDRAM bank 2)
-+ * at half speed. This clock will scale with core frequency so
-+ * the audio sample rate will also scale. The CPLD on Assabet
-+ * will need to be programmed to match the core frequency.
-+ */
-+ mdrefr = MDREFR;
-+ if ((mdrefr & (MDREFR_K2DB2 | MDREFR_K2RUN | MDREFR_EAPD |
-+ MDREFR_KAPD)) != (MDREFR_K2DB2 | MDREFR_K2RUN)) {
-+ mdrefr |= MDREFR_K2DB2 | MDREFR_K2RUN;
-+ mdrefr &= ~(MDREFR_EAPD | MDREFR_KAPD);
-+ MDREFR = mdrefr;
-+ (void) MDREFR;
-+ }
-+ local_irq_restore(flags);
-+
-+ /* Wait for the UDA1341 to wake up */
-+ mdelay(100);
-+
-+ l3_open(&uda1341);
-+
-+ pangolin_set_samplerate(audio_samplerate);
-+
-+ GPCR = QmutePin;
-+}
-+
-+static void pangolin_audio_shutdown(void *dummy)
-+{
-+ GPSR = QmutePin;
-+
-+ l3_close(&uda1341);
-+
-+ Ser4SSCR0 = 0;
-+ MDREFR &= ~(MDREFR_K2DB2 | MDREFR_K2RUN);
-+}
-+
-+static int pangolin_audio_ioctl( struct inode *inode, struct file *file,
-+ uint cmd, ulong arg)
-+{
-+ long val;
-+ int ret = 0;
-+
-+ /*
-+ * These are platform dependent ioctls which are not handled by the
-+ * generic sa1100-audio module.
-+ */
-+ switch (cmd) {
-+ case SNDCTL_DSP_STEREO:
-+ ret = get_user(val, (int *) arg);
-+ if (ret)
-+ return ret;
-+ /* the UDA1341 is stereo only */
-+ ret = (val == 0) ? -EINVAL : 1;
-+ return put_user(ret, (int *) arg);
-+
-+ case SNDCTL_DSP_CHANNELS:
-+ case SOUND_PCM_READ_CHANNELS:
-+ /* the UDA1341 is stereo only */
-+ return put_user(2, (long *) arg);
-+
-+ case SNDCTL_DSP_SPEED:
-+ ret = get_user(val, (long *) arg);
-+ if (ret) break;
-+ pangolin_set_samplerate(val);
-+ /* fall through */
-+
-+ case SOUND_PCM_READ_RATE:
-+ return put_user(audio_samplerate, (long *) arg);
-+
-+ case SNDCTL_DSP_SETFMT:
-+ case SNDCTL_DSP_GETFMTS:
-+ /* we can do signed 16-bit only */
-+ return put_user(AFMT_S16_LE, (long *) arg);
-+
-+ default:
-+ /* Maybe this is meant for the mixer (As per OSS Docs) */
-+ return mixer_ioctl(inode, file, cmd, arg);
-+ }
-+
-+ return ret;
-+}
-+
-+static audio_stream_t output_stream, input_stream;
-+
-+static audio_state_t audio_state = {
-+ output_stream: &output_stream,
-+ output_dma: DMA_Ser4SSPWr,
-+ output_id: "Pangolin UDA1341 out",
-+ input_stream: &input_stream,
-+ input_dma: DMA_Ser4SSPRd,
-+ input_id: "Pangolin UDA1341 in",
-+ need_tx_for_rx: 1,
-+ hw_init: pangolin_audio_init,
-+ hw_shutdown: pangolin_audio_shutdown,
-+ client_ioctl: pangolin_audio_ioctl,
-+ sem: __MUTEX_INITIALIZER(audio_state.sem),
-+};
-+
-+static int pangolin_audio_open(struct inode *inode, struct file *file)
-+{
-+ return sa1100_audio_attach(inode, file, &audio_state);
-+}
-+
-+/*
-+ * Missing fields of this structure will be patched with the call
-+ * to sa1100_audio_attach().
-+ */
-+static struct file_operations pangolin_audio_fops = {
-+ open: pangolin_audio_open,
-+ owner: THIS_MODULE
-+};
-+
-+
-+static int audio_dev_id, mixer_dev_id;
-+
-+static int __init pangolin_uda1341_init(void)
-+{
-+ unsigned long flags;
-+ int ret;
-+
-+ if (!machine_is_pangolin())
-+ return -ENODEV;
-+
-+ ret = l3_attach_client(&uda1341, "l3-bit-sa1100-gpio", "uda1341");
-+ if (ret)
-+ goto out;
-+
-+ /* register devices */
-+ audio_dev_id = register_sound_dsp(&pangolin_audio_fops, -1);
-+ mixer_dev_id = register_sound_mixer(&pangolin_mixer_fops, -1);
-+
-+ local_irq_save(flags);
-+ GAFR &= ~(SpeakerOffPin | QmutePin);
-+ GPDR |= (SpeakerOffPin | QmutePin);
-+ local_irq_restore(flags);
-+
-+ printk(KERN_INFO "Pangolin UDA1341 audio driver initialized\n");
-+ return 0;
-+
-+release_l3:
-+ l3_detach_client(&uda1341);
-+out:
-+ return ret;
-+}
-+
-+static void __exit pangolin_uda1341_exit(void)
-+{
-+ unregister_sound_dsp(audio_dev_id);
-+ unregister_sound_mixer(mixer_dev_id);
-+ l3_detach_client(&uda1341);
-+}
-+
-+module_init(pangolin_uda1341_init);
-+module_exit(pangolin_uda1341_exit);
-+
-+MODULE_AUTHOR("Nicolas Pitre");
-+MODULE_DESCRIPTION("Glue audio driver for the SA1110 Pangolin board & Philips UDA1341 codec.");
-+
-+EXPORT_NO_SYMBOLS;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/sound/sa1100-audio.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,976 @@
-+/*
-+ * Common audio handling for the SA11x0 processor
-+ *
-+ * Copyright (C) 2000, 2001 Nicolas Pitre <nico@cam.org>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License.
-+ *
-+ *
-+ * This module handles the generic buffering/DMA/mmap audio interface for
-+ * codecs connected to the SA1100 chip. All features depending on specific
-+ * hardware implementations like supported audio formats or samplerates are
-+ * relegated to separate specific modules.
-+ *
-+ *
-+ * History:
-+ *
-+ * 2000-05-21 Nicolas Pitre Initial release.
-+ *
-+ * 2000-06-10 Erik Bunce Add initial poll support.
-+ *
-+ * 2000-08-22 Nicolas Pitre Removed all DMA stuff. Now using the
-+ * generic SA1100 DMA interface.
-+ *
-+ * 2000-11-30 Nicolas Pitre - Validation of opened instances;
-+ * - Power handling at open/release time instead
-+ * of driver load/unload;
-+ *
-+ * 2001-06-03 Nicolas Pitre Made this file a separate module, based on
-+ * the former sa1100-uda1341.c driver.
-+ *
-+ * 2001-07-22 Nicolas Pitre - added mmap() and realtime support
-+ * - corrected many details to better comply
-+ * with the OSS API
-+ *
-+ * 2001-10-19 Nicolas Pitre - brought DMA registration processing
-+ * into this module for better ressource
-+ * management. This also fixes a bug
-+ * with the suspend/resume logic.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/fs.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/poll.h>
-+#include <linux/pm.h>
-+#include <linux/errno.h>
-+#include <linux/sound.h>
-+#include <linux/soundcard.h>
-+#include <linux/sysrq.h>
-+
-+#include <asm/uaccess.h>
-+#include <asm/io.h>
-+#include <asm/hardware.h>
-+#include <asm/semaphore.h>
-+#include <asm/dma.h>
-+
-+#include "sa1100-audio.h"
-+
-+
-+#undef DEBUG
-+/* #define DEBUG 1 */
-+#ifdef DEBUG
-+#define DPRINTK( x... ) printk( ##x )
-+#else
-+#define DPRINTK( x... )
-+#endif
-+
-+
-+#define AUDIO_NAME "sa1100-audio"
-+#define AUDIO_NBFRAGS_DEFAULT 8
-+#define AUDIO_FRAGSIZE_DEFAULT 8192
-+
-+#define NEXT_BUF(_s_,_b_) { \
-+ (_s_)->_b_##_idx++; \
-+ (_s_)->_b_##_idx %= (_s_)->nbfrags; \
-+ (_s_)->_b_ = (_s_)->buffers + (_s_)->_b_##_idx; }
-+
-+#define AUDIO_ACTIVE(state) ((state)->rd_ref || (state)->wr_ref)
-+
-+/*
-+ * This function frees all buffers
-+ */
-+
-+static void audio_clear_buf(audio_stream_t * s)
-+{
-+ DPRINTK("audio_clear_buf\n");
-+
-+ /* ensure DMA won't run anymore */
-+ s->active = 0;
-+ s->stopped = 0;
-+ sa1100_dma_flush_all(s->dma_ch);
-+
-+ if (s->buffers) {
-+ int frag;
-+ for (frag = 0; frag < s->nbfrags; frag++) {
-+ if (!s->buffers[frag].master)
-+ continue;
-+ consistent_free(s->buffers[frag].start,
-+ s->buffers[frag].master,
-+ s->buffers[frag].dma_addr);
-+ }
-+ kfree(s->buffers);
-+ s->buffers = NULL;
-+ }
-+
-+ s->buf_idx = 0;
-+ s->buf = NULL;
-+}
-+
-+
-+/*
-+ * This function allocates the buffer structure array and buffer data space
-+ * according to the current number of fragments and fragment size.
-+ */
-+
-+static int audio_setup_buf(audio_stream_t * s)
-+{
-+ int frag;
-+ int dmasize = 0;
-+ char *dmabuf = NULL;
-+ dma_addr_t dmaphys = 0;
-+
-+ if (s->buffers)
-+ return -EBUSY;
-+
-+ s->buffers = (audio_buf_t *)
-+ kmalloc(sizeof(audio_buf_t) * s->nbfrags, GFP_KERNEL);
-+ if (!s->buffers)
-+ goto err;
-+ memset(s->buffers, 0, sizeof(audio_buf_t) * s->nbfrags);
-+
-+ for (frag = 0; frag < s->nbfrags; frag++) {
-+ audio_buf_t *b = &s->buffers[frag];
-+
-+ /*
-+ * Let's allocate non-cached memory for DMA buffers.
-+ * We try to allocate all memory at once.
-+ * If this fails (a common reason is memory fragmentation),
-+ * then we allocate more smaller buffers.
-+ */
-+ if (!dmasize) {
-+ dmasize = (s->nbfrags - frag) * s->fragsize;
-+ do {
-+ dmabuf = consistent_alloc(GFP_KERNEL|GFP_DMA,
-+ dmasize,
-+ &dmaphys);
-+ if (!dmabuf)
-+ dmasize -= s->fragsize;
-+ } while (!dmabuf && dmasize);
-+ if (!dmabuf)
-+ goto err;
-+ b->master = dmasize;
-+ memzero(dmabuf, dmasize);
-+ }
-+
-+ b->start = dmabuf;
-+ b->dma_addr = dmaphys;
-+ b->stream = s;
-+ sema_init(&b->sem, 1);
-+ DPRINTK("buf %d: start %p dma %p\n", frag, b->start,
-+ b->dma_addr);
-+
-+ dmabuf += s->fragsize;
-+ dmaphys += s->fragsize;
-+ dmasize -= s->fragsize;
-+ }
-+
-+ s->buf_idx = 0;
-+ s->buf = &s->buffers[0];
-+ s->bytecount = 0;
-+ s->getptrCount = 0;
-+ s->fragcount = 0;
-+
-+ return 0;
-+
-+err:
-+ printk(AUDIO_NAME ": unable to allocate audio memory\n ");
-+ audio_clear_buf(s);
-+ return -ENOMEM;
-+}
-+
-+
-+/*
-+ * This function yanks all buffers from the DMA code's control and
-+ * resets them ready to be used again.
-+ */
-+
-+static void audio_reset_buf(audio_stream_t * s)
-+{
-+ int frag;
-+
-+ s->active = 0;
-+ s->stopped = 0;
-+ sa1100_dma_flush_all(s->dma_ch);
-+ if (s->buffers) {
-+ for (frag = 0; frag < s->nbfrags; frag++) {
-+ audio_buf_t *b = &s->buffers[frag];
-+ b->size = 0;
-+ sema_init(&b->sem, 1);
-+ }
-+ }
-+ s->bytecount = 0;
-+ s->getptrCount = 0;
-+ s->fragcount = 0;
-+}
-+
-+
-+/*
-+ * DMA callback functions
-+ */
-+
-+static void audio_dmaout_done_callback(void *buf_id, int size)
-+{
-+ audio_buf_t *b = (audio_buf_t *) buf_id;
-+ audio_stream_t *s = b->stream;
-+
-+ /* Accounting */
-+ s->bytecount += size;
-+ s->fragcount++;
-+
-+ /* Recycle buffer */
-+ if (s->mapped)
-+ sa1100_dma_queue_buffer(s->dma_ch, buf_id,
-+ b->dma_addr, s->fragsize);
-+ else
-+ up(&b->sem);
-+
-+ /* And any process polling on write. */
-+ wake_up(&s->wq);
-+}
-+
-+static void audio_dmain_done_callback(void *buf_id, int size)
-+{
-+ audio_buf_t *b = (audio_buf_t *) buf_id;
-+ audio_stream_t *s = b->stream;
-+
-+ /* Accounting */
-+ s->bytecount += size;
-+ s->fragcount++;
-+
-+ /* Recycle buffer */
-+ if (s->mapped) {
-+ sa1100_dma_queue_buffer(s->dma_ch, buf_id,
-+ b->dma_addr, s->fragsize);
-+ } else {
-+ b->size = size;
-+ up(&b->sem);
-+ }
-+
-+ /* And any process polling on write. */
-+ wake_up(&s->wq);
-+}
-+
-+static int audio_sync(struct file *file)
-+{
-+ audio_state_t *state = (audio_state_t *)file->private_data;
-+ audio_stream_t *s = state->output_stream;
-+ audio_buf_t *b;
-+
-+ DPRINTK("audio_sync\n");
-+
-+ if (!(file->f_mode & FMODE_WRITE) || !s->buffers || s->mapped)
-+ return 0;
-+
-+ /*
-+ * Send current buffer if it contains data. Be sure to send
-+ * a full sample count.
-+ */
-+ b = s->buf;
-+ if (b->size &= ~3) {
-+ down(&b->sem);
-+ sa1100_dma_queue_buffer(s->dma_ch, (void *) b,
-+ b->dma_addr, b->size);
-+ b->size = 0;
-+ NEXT_BUF(s, buf);
-+ }
-+
-+ /*
-+ * Let's wait for the last buffer we sent i.e. the one before the
-+ * current buf_idx. When we acquire the semaphore, this means either:
-+ * - DMA on the buffer completed or
-+ * - the buffer was already free thus nothing else to sync.
-+ */
-+ b = s->buffers + ((s->nbfrags + s->buf_idx - 1) % s->nbfrags);
-+ if (down_interruptible(&b->sem))
-+ return -EINTR;
-+ up(&b->sem);
-+ return 0;
-+}
-+
-+
-+static int audio_write(struct file *file, const char *buffer,
-+ size_t count, loff_t * ppos)
-+{
-+ const char *buffer0 = buffer;
-+ audio_state_t *state = (audio_state_t *)file->private_data;
-+ audio_stream_t *s = state->output_stream;
-+ int chunksize, ret = 0;
-+
-+ DPRINTK("audio_write: count=%d\n", count);
-+
-+ if (ppos != &file->f_pos)
-+ return -ESPIPE;
-+ if (s->mapped)
-+ return -ENXIO;
-+ if (!s->buffers && audio_setup_buf(s))
-+ return -ENOMEM;
-+
-+ while (count > 0) {
-+ audio_buf_t *b = s->buf;
-+
-+ /* Wait for a buffer to become free */
-+ if (file->f_flags & O_NONBLOCK) {
-+ ret = -EAGAIN;
-+ if (down_trylock(&b->sem))
-+ break;
-+ } else {
-+ ret = -ERESTARTSYS;
-+ if (down_interruptible(&b->sem))
-+ break;
-+ }
-+
-+ /* Feed the current buffer */
-+ chunksize = s->fragsize - b->size;
-+ if (chunksize > count)
-+ chunksize = count;
-+ DPRINTK("write %d to %d\n", chunksize, s->buf_idx);
-+ if (copy_from_user(b->start + b->size, buffer, chunksize)) {
-+ up(&b->sem);
-+ return -EFAULT;
-+ }
-+ b->size += chunksize;
-+ buffer += chunksize;
-+ count -= chunksize;
-+ if (b->size < s->fragsize) {
-+ up(&b->sem);
-+ break;
-+ }
-+
-+ /* Send current buffer to dma */
-+ s->active = 1;
-+ sa1100_dma_queue_buffer(s->dma_ch, (void *) b,
-+ b->dma_addr, b->size);
-+ b->size = 0; /* indicate that the buffer has been sent */
-+ NEXT_BUF(s, buf);
-+ }
-+
-+ if ((buffer - buffer0))
-+ ret = buffer - buffer0;
-+ DPRINTK("audio_write: return=%d\n", ret);
-+ return ret;
-+}
-+
-+
-+static inline void audio_check_tx_spin(audio_state_t *state)
-+{
-+ /*
-+ * With some codecs like the Philips UDA1341 we must ensure
-+ * there is an output stream at any time while recording since
-+ * this is how the UDA1341 gets its clock from the SA1100.
-+ * So while there is no playback data to send, the output DMA
-+ * will spin with all zeroes. We use the cache flush special
-+ * area for that.
-+ */
-+ if (state->need_tx_for_rx && !state->tx_spinning) {
-+ sa1100_dma_set_spin(state->output_stream->dma_ch,
-+ (dma_addr_t)FLUSH_BASE_PHYS, 2048);
-+ state->tx_spinning = 1;
-+ }
-+}
-+
-+
-+static void audio_prime_dma(audio_stream_t *s)
-+{
-+ int i;
-+
-+ s->active = 1;
-+ for (i = 0; i < s->nbfrags; i++) {
-+ audio_buf_t *b = s->buf;
-+ down(&b->sem);
-+ sa1100_dma_queue_buffer(s->dma_ch, (void *) b,
-+ b->dma_addr, s->fragsize);
-+ NEXT_BUF(s, buf);
-+ }
-+}
-+
-+
-+static int audio_read(struct file *file, char *buffer,
-+ size_t count, loff_t * ppos)
-+{
-+ char *buffer0 = buffer;
-+ audio_state_t *state = (audio_state_t *)file->private_data;
-+ audio_stream_t *s = state->input_stream;
-+ int chunksize, ret = 0;
-+
-+ DPRINTK("audio_read: count=%d\n", count);
-+
-+ if (ppos != &file->f_pos)
-+ return -ESPIPE;
-+ if (s->mapped)
-+ return -ENXIO;
-+
-+ if (!s->active) {
-+ if (!s->buffers && audio_setup_buf(s))
-+ return -ENOMEM;
-+ audio_check_tx_spin(state);
-+ audio_prime_dma(s);
-+ }
-+
-+ while (count > 0) {
-+ audio_buf_t *b = s->buf;
-+
-+ /* Wait for a buffer to become full */
-+ if (file->f_flags & O_NONBLOCK) {
-+ ret = -EAGAIN;
-+ if (down_trylock(&b->sem))
-+ break;
-+ } else {
-+ ret = -ERESTARTSYS;
-+ if (down_interruptible(&b->sem))
-+ break;
-+ }
-+
-+ /* Grab data from the current buffer */
-+ chunksize = b->size;
-+ if (chunksize > count)
-+ chunksize = count;
-+ DPRINTK("read %d from %d\n", chunksize, s->buf_idx);
-+ if (copy_to_user(buffer,
-+ b->start + s->fragsize - b->size,
-+ chunksize)) {
-+ up(&b->sem);
-+ return -EFAULT;
-+ }
-+ b->size -= chunksize;
-+ buffer += chunksize;
-+ count -= chunksize;
-+ if (b->size > 0) {
-+ up(&b->sem);
-+ break;
-+ }
-+
-+ /* Make current buffer available for DMA again */
-+ sa1100_dma_queue_buffer(s->dma_ch, (void *) b,
-+ b->dma_addr, s->fragsize);
-+ NEXT_BUF(s, buf);
-+ }
-+
-+ if ((buffer - buffer0))
-+ ret = buffer - buffer0;
-+ DPRINTK("audio_read: return=%d\n", ret);
-+ return ret;
-+}
-+
-+
-+static int audio_mmap(struct file *file, struct vm_area_struct *vma)
-+{
-+ audio_state_t *state = (audio_state_t *)file->private_data;
-+ audio_stream_t *s;
-+ unsigned long size, vma_addr;
-+ int i, ret;
-+
-+ if (vma->vm_pgoff != 0)
-+ return -EINVAL;
-+
-+ if (vma->vm_flags & VM_WRITE) {
-+ if (!state->wr_ref)
-+ return -EINVAL;;
-+ s = state->output_stream;
-+ } else if (vma->vm_flags & VM_READ) {
-+ if (!state->rd_ref)
-+ return -EINVAL;
-+ s = state->input_stream;
-+ } else return -EINVAL;
-+
-+ if (s->mapped)
-+ return -EINVAL;
-+ size = vma->vm_end - vma->vm_start;
-+ if (size != s->fragsize * s->nbfrags)
-+ return -EINVAL;
-+ if (!s->buffers && audio_setup_buf(s))
-+ return -ENOMEM;
-+ vma_addr = vma->vm_start;
-+ for (i = 0; i < s->nbfrags; i++) {
-+ audio_buf_t *buf = &s->buffers[i];
-+ if (!buf->master)
-+ continue;
-+ ret = remap_page_range(vma_addr, buf->dma_addr, buf->master, vma->vm_page_prot);
-+ if (ret)
-+ return ret;
-+ vma_addr += buf->master;
-+ }
-+ s->mapped = 1;
-+
-+ return 0;
-+}
-+
-+
-+static unsigned int audio_poll(struct file *file,
-+ struct poll_table_struct *wait)
-+{
-+ audio_state_t *state = (audio_state_t *)file->private_data;
-+ audio_stream_t *is = state->input_stream;
-+ audio_stream_t *os = state->output_stream;
-+ unsigned int mask = 0;
-+ int i;
-+
-+ DPRINTK("audio_poll(): mode=%s%s\n",
-+ (file->f_mode & FMODE_READ) ? "r" : "",
-+ (file->f_mode & FMODE_WRITE) ? "w" : "");
-+
-+ if (file->f_mode & FMODE_READ) {
-+ /* Start audio input if not already active */
-+ if (!is->active) {
-+ if (!is->buffers && audio_setup_buf(is))
-+ return -ENOMEM;
-+ audio_check_tx_spin(state);
-+ audio_prime_dma(is);
-+ }
-+ poll_wait(file, &is->wq, wait);
-+ }
-+
-+ if (file->f_mode & FMODE_WRITE) {
-+ if (!os->buffers && audio_setup_buf(os))
-+ return -ENOMEM;
-+ poll_wait(file, &os->wq, wait);
-+ }
-+
-+ if (file->f_mode & FMODE_READ) {
-+ if (is->mapped) {
-+/* if the buffer is mapped assume we care that there are more bytes available than
-+ when we last asked using SNDCTL_DSP_GETxPTR */
-+ if (is->bytecount != is->getptrCount)
-+ mask |= POLLIN | POLLRDNORM;
-+ } else {
-+ for (i = 0; i < is->nbfrags; i++) {
-+ if (atomic_read(&is->buffers[i].sem.count) > 0) {
-+ mask |= POLLIN | POLLRDNORM;
-+ break;
-+ }
-+ }
-+ }
-+ }
-+ if (file->f_mode & FMODE_WRITE) {
-+ if (os->mapped) {
-+ if (os->bytecount != os->getptrCount)
-+ mask |= POLLOUT | POLLWRNORM;
-+ } else {
-+ for (i = 0; i < os->nbfrags; i++) {
-+ if (atomic_read(&os->buffers[i].sem.count) > 0) {
-+ mask |= POLLOUT | POLLWRNORM;
-+ break;
-+ }
-+ }
-+ }
-+ }
-+
-+ DPRINTK("audio_poll() returned mask of %s%s\n",
-+ (mask & POLLIN) ? "r" : "",
-+ (mask & POLLOUT) ? "w" : "");
-+
-+ return mask;
-+}
-+
-+
-+static loff_t audio_llseek(struct file *file, loff_t offset, int origin)
-+{
-+ return -ESPIPE;
-+}
-+
-+
-+static int audio_set_fragments(audio_stream_t *s, int val)
-+{
-+ if (s->active)
-+ return -EBUSY;
-+ if (s->buffers)
-+ audio_clear_buf(s);
-+ s->nbfrags = (val >> 16) & 0x7FFF;
-+ val &= 0xffff;
-+ if (val < 4)
-+ val = 4;
-+ if (val > 15)
-+ val = 15;
-+ s->fragsize = 1 << val;
-+ if (s->nbfrags < 2)
-+ s->nbfrags = 2;
-+ if (s->nbfrags * s->fragsize > 128 * 1024)
-+ s->nbfrags = 128 * 1024 / s->fragsize;
-+ if (audio_setup_buf(s))
-+ return -ENOMEM;
-+ return val|(s->nbfrags << 16);
-+}
-+
-+static int audio_ioctl(struct inode *inode, struct file *file,
-+ uint cmd, ulong arg)
-+{
-+ audio_state_t *state = (audio_state_t *)file->private_data;
-+ audio_stream_t *os = state->output_stream;
-+ audio_stream_t *is = state->input_stream;
-+ long val;
-+
-+ /* dispatch based on command */
-+ switch (cmd) {
-+ case OSS_GETVERSION:
-+ return put_user(SOUND_VERSION, (int *)arg);
-+
-+ case SNDCTL_DSP_GETBLKSIZE:
-+ if (file->f_mode & FMODE_WRITE)
-+ return put_user(os->fragsize, (int *)arg);
-+ else
-+ return put_user(is->fragsize, (int *)arg);
-+
-+ case SNDCTL_DSP_GETCAPS:
-+ val = DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP;
-+ if (is && os)
-+ val |= DSP_CAP_DUPLEX;
-+ return put_user(val, (int *)arg);
-+
-+ case SNDCTL_DSP_SETFRAGMENT:
-+ if (get_user(val, (long *) arg))
-+ return -EFAULT;
-+ if (file->f_mode & FMODE_READ) {
-+ int ret = audio_set_fragments(is, val);
-+ if (ret < 0)
-+ return ret;
-+ ret = put_user(ret, (int *)arg);
-+ if (ret)
-+ return ret;
-+ }
-+ if (file->f_mode & FMODE_WRITE) {
-+ int ret = audio_set_fragments(os, val);
-+ if (ret < 0)
-+ return ret;
-+ ret = put_user(ret, (int *)arg);
-+ if (ret)
-+ return ret;
-+ }
-+ return 0;
-+
-+ case SNDCTL_DSP_SYNC:
-+ return audio_sync(file);
-+
-+ case SNDCTL_DSP_SETDUPLEX:
-+ return 0;
-+
-+ case SNDCTL_DSP_POST:
-+ return 0;
-+
-+ case SNDCTL_DSP_GETTRIGGER:
-+ val = 0;
-+ if (file->f_mode & FMODE_READ && is->active && !is->stopped)
-+ val |= PCM_ENABLE_INPUT;
-+ if (file->f_mode & FMODE_WRITE && os->active && !os->stopped)
-+ val |= PCM_ENABLE_OUTPUT;
-+ return put_user(val, (int *)arg);
-+
-+ case SNDCTL_DSP_SETTRIGGER:
-+ if (get_user(val, (int *)arg))
-+ return -EFAULT;
-+ if (file->f_mode & FMODE_READ) {
-+ if (val & PCM_ENABLE_INPUT) {
-+ if (!is->active) {
-+ if (!is->buffers && audio_setup_buf(is))
-+ return -ENOMEM;
-+ audio_prime_dma(is);
-+ }
-+ audio_check_tx_spin(state);
-+ if (is->stopped) {
-+ is->stopped = 0;
-+ sa1100_dma_resume(is->dma_ch);
-+ }
-+ } else {
-+ sa1100_dma_stop(is->dma_ch);
-+ is->stopped = 1;
-+ }
-+ }
-+ if (file->f_mode & FMODE_WRITE) {
-+ if (val & PCM_ENABLE_OUTPUT) {
-+ if (!os->active) {
-+ if (!os->buffers && audio_setup_buf(os))
-+ return -ENOMEM;
-+ if (os->mapped)
-+ audio_prime_dma(os);
-+ }
-+ if (os->stopped) {
-+ os->stopped = 0;
-+ sa1100_dma_resume(os->dma_ch);
-+ }
-+ } else {
-+ sa1100_dma_stop(os->dma_ch);
-+ os->stopped = 1;
-+ }
-+ }
-+ return 0;
-+
-+ case SNDCTL_DSP_GETOPTR:
-+ case SNDCTL_DSP_GETIPTR:
-+ {
-+ count_info inf = { 0, };
-+ audio_stream_t *s = (cmd == SNDCTL_DSP_GETOPTR) ? os : is;
-+ audio_buf_t *b;
-+ dma_addr_t ptr;
-+ int bytecount, offset, flags;
-+
-+ if ((s == is && !(file->f_mode & FMODE_READ)) ||
-+ (s == os && !(file->f_mode & FMODE_WRITE)))
-+ return -EINVAL;
-+ if (s->active) {
-+ save_flags_cli(flags);
-+ if (sa1100_dma_get_current(s->dma_ch, (void *)&b, &ptr) == 0) {
-+ offset = ptr - b->dma_addr;
-+ inf.ptr = (b - s->buffers) * s->fragsize + offset;
-+ } else offset = 0;
-+ bytecount = s->bytecount + offset;
-+ s->getptrCount = s->bytecount; /* so poll can tell if it changes */
-+ inf.blocks = s->fragcount;
-+ s->fragcount = 0;
-+ restore_flags(flags);
-+ if (bytecount < 0)
-+ bytecount = 0;
-+ inf.bytes = bytecount;
-+ }
-+ return copy_to_user((void *)arg, &inf, sizeof(inf));
-+ }
-+
-+ case SNDCTL_DSP_GETOSPACE:
-+ {
-+ audio_buf_info inf = { 0, };
-+ int i;
-+
-+ if (!(file->f_mode & FMODE_WRITE))
-+ return -EINVAL;
-+ if (!os->buffers && audio_setup_buf(os))
-+ return -ENOMEM;
-+ for (i = 0; i < os->nbfrags; i++) {
-+ if (atomic_read(&os->buffers[i].sem.count) > 0) {
-+ if (os->buffers[i].size == 0)
-+ inf.fragments++;
-+ inf.bytes += os->fragsize - os->buffers[i].size;
-+ }
-+ }
-+ inf.fragstotal = os->nbfrags;
-+ inf.fragsize = os->fragsize;
-+ return copy_to_user((void *)arg, &inf, sizeof(inf));
-+ }
-+
-+ case SNDCTL_DSP_GETISPACE:
-+ {
-+ audio_buf_info inf = { 0, };
-+ int i;
-+
-+ if (!(file->f_mode & FMODE_READ))
-+ return -EINVAL;
-+ if (!is->buffers && audio_setup_buf(is))
-+ return -ENOMEM;
-+ for (i = 0; i < is->nbfrags; i++) {
-+ if (atomic_read(&is->buffers[i].sem.count) > 0) {
-+ if (is->buffers[i].size == is->fragsize)
-+ inf.fragments++;
-+ inf.bytes += is->buffers[i].size;
-+ }
-+ }
-+ inf.fragstotal = is->nbfrags;
-+ inf.fragsize = is->fragsize;
-+ return copy_to_user((void *)arg, &inf, sizeof(inf));
-+ }
-+
-+ case SNDCTL_DSP_NONBLOCK:
-+ file->f_flags |= O_NONBLOCK;
-+ return 0;
-+
-+ case SNDCTL_DSP_RESET:
-+ if (file->f_mode & FMODE_READ) {
-+ if (state->tx_spinning) {
-+ sa1100_dma_set_spin(os->dma_ch, 0, 0);
-+ state->tx_spinning = 0;
-+ }
-+ audio_reset_buf(is);
-+ }
-+ if (file->f_mode & FMODE_WRITE) {
-+ audio_reset_buf(os);
-+ }
-+ return 0;
-+
-+ default:
-+ /*
-+ * Let the client of this module handle the
-+ * non generic ioctls
-+ */
-+ return state->client_ioctl(inode, file, cmd, arg);
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static int audio_release(struct inode *inode, struct file *file)
-+{
-+ audio_state_t *state = (audio_state_t *)file->private_data;
-+ DPRINTK("audio_release\n");
-+
-+ down(&state->sem);
-+
-+ if (file->f_mode & FMODE_READ) {
-+ if (state->tx_spinning) {
-+ sa1100_dma_set_spin(state->output_stream->dma_ch, 0, 0);
-+ state->tx_spinning = 0;
-+ }
-+ audio_clear_buf(state->input_stream);
-+ if (!state->skip_dma_init) {
-+ sa1100_free_dma(state->input_stream->dma_ch);
-+ if (state->need_tx_for_rx && !state->wr_ref)
-+ sa1100_free_dma(state->output_stream->dma_ch);
-+ }
-+ state->rd_ref = 0;
-+ }
-+
-+ if (file->f_mode & FMODE_WRITE) {
-+ audio_sync(file);
-+ audio_clear_buf(state->output_stream);
-+ if (!state->skip_dma_init)
-+ if (!state->need_tx_for_rx || !state->rd_ref)
-+ sa1100_free_dma(state->output_stream->dma_ch);
-+ state->wr_ref = 0;
-+ }
-+
-+ if (!AUDIO_ACTIVE(state)) {
-+ if (state->hw_shutdown)
-+ state->hw_shutdown(state->data);
-+#ifdef CONFIG_PM
-+ pm_unregister(state->pm_dev);
-+#endif
-+ }
-+
-+ up(&state->sem);
-+ return 0;
-+}
-+
-+
-+#ifdef CONFIG_PM
-+
-+static int audio_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data)
-+{
-+ audio_state_t *state = (audio_state_t *)pm_dev->data;
-+
-+ switch (req) {
-+ case PM_SUSPEND: /* enter D1-D3 */
-+ if (state->output_stream)
-+ sa1100_dma_sleep(state->output_stream->dma_ch);
-+ if (state->input_stream)
-+ sa1100_dma_sleep(state->input_stream->dma_ch);
-+ if (AUDIO_ACTIVE(state) && state->hw_shutdown)
-+ state->hw_shutdown(state->data);
-+ break;
-+ case PM_RESUME: /* enter D0 */
-+ if (AUDIO_ACTIVE(state) && state->hw_init)
-+ state->hw_init(state->data);
-+ if (state->input_stream)
-+ sa1100_dma_wakeup(state->input_stream->dma_ch);
-+ if (state->output_stream)
-+ sa1100_dma_wakeup(state->output_stream->dma_ch);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+#endif
-+
-+
-+int sa1100_audio_attach(struct inode *inode, struct file *file,
-+ audio_state_t *state)
-+{
-+ int err, need_tx_dma;
-+
-+ DPRINTK("audio_open\n");
-+
-+ down(&state->sem);
-+
-+ /* access control */
-+ err = -ENODEV;
-+ if ((file->f_mode & FMODE_WRITE) && !state->output_stream)
-+ goto out;
-+ if ((file->f_mode & FMODE_READ) && !state->input_stream)
-+ goto out;
-+ err = -EBUSY;
-+ if ((file->f_mode & FMODE_WRITE) && state->wr_ref)
-+ goto out;
-+ if ((file->f_mode & FMODE_READ) && state->rd_ref)
-+ goto out;
-+ err = -EINVAL;
-+ if ((file->f_mode & FMODE_READ) && state->need_tx_for_rx && !state->output_stream)
-+ goto out;
-+
-+ /* request DMA channels */
-+ if (state->skip_dma_init)
-+ goto skip_dma;
-+ need_tx_dma = ((file->f_mode & FMODE_WRITE) ||
-+ ((file->f_mode & FMODE_READ) && state->need_tx_for_rx));
-+ if (state->wr_ref || (state->rd_ref && state->need_tx_for_rx))
-+ need_tx_dma = 0;
-+ if (need_tx_dma) {
-+ err = sa1100_request_dma(&state->output_stream->dma_ch,
-+ state->output_id,
-+ state->output_dma);
-+ if (err)
-+ goto out;
-+ }
-+ if (file->f_mode & FMODE_READ) {
-+ err = sa1100_request_dma(&state->input_stream->dma_ch,
-+ state->input_id,
-+ state->input_dma);
-+ if (err) {
-+ if (need_tx_dma)
-+ sa1100_free_dma(state->output_stream->dma_ch);
-+ goto out;
-+ }
-+ }
-+skip_dma:
-+
-+ /* now complete initialisation */
-+ if (!AUDIO_ACTIVE(state)) {
-+ if (state->hw_init)
-+ state->hw_init(state->data);
-+#ifdef CONFIG_PM
-+ state->pm_dev = pm_register(PM_SYS_DEV, 0, audio_pm_callback);
-+ if (state->pm_dev)
-+ state->pm_dev->data = state;
-+#endif
-+ }
-+
-+ if ((file->f_mode & FMODE_WRITE)) {
-+ state->wr_ref = 1;
-+ audio_clear_buf(state->output_stream);
-+ state->output_stream->fragsize = AUDIO_FRAGSIZE_DEFAULT;
-+ state->output_stream->nbfrags = AUDIO_NBFRAGS_DEFAULT;
-+ state->output_stream->mapped = 0;
-+ sa1100_dma_set_callback(state->output_stream->dma_ch,
-+ audio_dmaout_done_callback);
-+ init_waitqueue_head(&state->output_stream->wq);
-+ }
-+ if (file->f_mode & FMODE_READ) {
-+ state->rd_ref = 1;
-+ audio_clear_buf(state->input_stream);
-+ state->input_stream->fragsize = AUDIO_FRAGSIZE_DEFAULT;
-+ state->input_stream->nbfrags = AUDIO_NBFRAGS_DEFAULT;
-+ state->input_stream->mapped = 0;
-+ sa1100_dma_set_callback(state->input_stream->dma_ch,
-+ audio_dmain_done_callback);
-+ init_waitqueue_head(&state->input_stream->wq);
-+ }
-+
-+ file->private_data = state;
-+ file->f_op->release = audio_release;
-+ file->f_op->write = audio_write;
-+ file->f_op->read = audio_read;
-+ file->f_op->mmap = audio_mmap;
-+ file->f_op->poll = audio_poll;
-+ file->f_op->ioctl = audio_ioctl;
-+ file->f_op->llseek = audio_llseek;
-+ err = 0;
-+
-+out:
-+ up(&state->sem);
-+ return err;
-+}
-+
-+EXPORT_SYMBOL(sa1100_audio_attach);
-+
-+MODULE_AUTHOR("Nicolas Pitre");
-+MODULE_DESCRIPTION("Common audio handling for the SA11x0 processor");
-+MODULE_LICENSE("GPL");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/sound/sa1100-audio.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,68 @@
-+/*
-+ * Common audio handling for the SA11x0
-+ *
-+ * Copyright (c) 2000 Nicolas Pitre <nico@cam.org>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License.
-+ */
-+
-+
-+/*
-+ * Buffer Management
-+ */
-+
-+typedef struct {
-+ int size; /* buffer size */
-+ char *start; /* points to actual buffer */
-+ dma_addr_t dma_addr; /* physical buffer address */
-+ struct semaphore sem; /* down before touching the buffer */
-+ int master; /* owner for buffer allocation, contain size when true */
-+ struct audio_stream_s *stream; /* owning stream */
-+} audio_buf_t;
-+
-+typedef struct audio_stream_s {
-+ audio_buf_t *buffers; /* pointer to audio buffer structures */
-+ audio_buf_t *buf; /* current buffer used by read/write */
-+ u_int buf_idx; /* index for the pointer above... */
-+ u_int fragsize; /* fragment i.e. buffer size */
-+ u_int nbfrags; /* nbr of fragments i.e. buffers */
-+ int bytecount; /* nbr of processed bytes */
-+ int getptrCount; /* value of bytecount last time anyone asked via GETxPTR */
-+ int fragcount; /* nbr of fragment transitions */
-+ dmach_t dma_ch; /* DMA channel ID */
-+ wait_queue_head_t wq; /* for poll */
-+ int mapped:1; /* mmap()'ed buffers */
-+ int active:1; /* actually in progress */
-+ int stopped:1; /* might be active but stopped */
-+} audio_stream_t;
-+
-+/*
-+ * State structure for one instance
-+ */
-+
-+typedef struct {
-+ audio_stream_t *output_stream;
-+ audio_stream_t *input_stream;
-+ dma_device_t output_dma;
-+ dma_device_t input_dma;
-+ char *output_id;
-+ char *input_id;
-+ int rd_ref:1; /* open reference for recording */
-+ int wr_ref:1; /* open reference for playback */
-+ int need_tx_for_rx:1; /* if data must be sent while receiving */
-+ int tx_spinning:1; /* tx spinning active */
-+ int skip_dma_init:1; /* hack for the SA1111 */
-+ void *data;
-+ void (*hw_init)(void *);
-+ void (*hw_shutdown)(void *);
-+ int (*client_ioctl)(struct inode *, struct file *, uint, ulong);
-+ struct pm_dev *pm_dev;
-+ struct semaphore sem; /* to protect against races in attach() */
-+} audio_state_t;
-+
-+/*
-+ * Functions exported by this module
-+ */
-+extern int sa1100_audio_attach( struct inode *inode, struct file *file,
-+ audio_state_t *state);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/sound/sa1100ssp.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,182 @@
-+/*
-+ * Glue audio driver for a simple DAC on the SA1100's SSP port
-+ *
-+ * Copyright (c) 2001 Nicolas Pitre <nico@cam.org>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License.
-+ *
-+ * History:
-+ *
-+ * 2001-06-04 Nicolas Pitre Initial release.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/fs.h>
-+#include <linux/delay.h>
-+#include <linux/pm.h>
-+#include <linux/errno.h>
-+#include <linux/sound.h>
-+#include <linux/soundcard.h>
-+
-+#include <asm/semaphore.h>
-+#include <asm/uaccess.h>
-+#include <asm/hardware.h>
-+#include <asm/dma.h>
-+
-+#include "sa1100-audio.h"
-+
-+
-+#undef DEBUG
-+#ifdef DEBUG
-+#define DPRINTK( x... ) printk( ##x )
-+#else
-+#define DPRINTK( x... )
-+#endif
-+
-+
-+#define AUDIO_NAME "SA1100 SSP audio"
-+
-+#define AUDIO_FMT AFMT_S16_LE
-+#define AUDIO_CHANNELS 2
-+
-+static int sample_rate = 44100;
-+
-+
-+static void ssp_audio_init(void)
-+{
-+ if (machine_is_lart()) {
-+ unsigned long flags;
-+ local_irq_save(flags);
-+
-+ /* LART has the SSP port rewired to GPIO 10-13, 19 */
-+ /* alternate functions for the GPIOs */
-+ GAFR |= ( GPIO_SSP_TXD | GPIO_SSP_RXD | GPIO_SSP_SCLK |
-+ GPIO_SSP_SFRM | GPIO_SSP_CLK );
-+
-+ /* Set the direction: 10, 12, 13 output; 11, 19 input */
-+ GPDR |= ( GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM );
-+ GPDR &= ~( GPIO_SSP_RXD | GPIO_SSP_CLK );
-+
-+ /* enable SSP pin swap */
-+ PPAR |= PPAR_SPR;
-+
-+ local_irq_restore(flags);
-+ }
-+
-+ /* turn on the SSP */
-+ Ser4SSCR0 = 0;
-+ Ser4SSCR0 = (SSCR0_DataSize(16) | SSCR0_TI | SSCR0_SerClkDiv(2) |
-+ SSCR0_SSE);
-+ Ser4SSCR1 = (SSCR1_SClkIactL | SSCR1_SClk1P | SSCR1_ExtClk);
-+}
-+
-+static void ssp_audio_shutdown(void)
-+{
-+ Ser4SSCR0 = 0;
-+}
-+
-+static int ssp_audio_ioctl( struct inode *inode, struct file *file,
-+ uint cmd, ulong arg)
-+{
-+ long val;
-+ int ret = 0;
-+
-+ /*
-+ * These are platform dependent ioctls which are not handled by the
-+ * generic sa1100-audio module.
-+ */
-+ switch (cmd) {
-+ case SNDCTL_DSP_STEREO:
-+ ret = get_user(val, (int *) arg);
-+ if (ret)
-+ return ret;
-+ /* Simple standard DACs are stereo only */
-+ ret = (val == 0) ? -EINVAL : 1;
-+ return put_user(ret, (int *) arg);
-+
-+ case SNDCTL_DSP_CHANNELS:
-+ case SOUND_PCM_READ_CHANNELS:
-+ /* Simple standard DACs are stereo only */
-+ return put_user(AUDIO_CHANNELS, (long *) arg);
-+
-+ case SNDCTL_DSP_SPEED:
-+ case SOUND_PCM_READ_RATE:
-+ /* We assume the clock doesn't change */
-+ return put_user(sample_rate, (long *) arg);
-+
-+ case SNDCTL_DSP_SETFMT:
-+ case SNDCTL_DSP_GETFMTS:
-+ /* Simple standard DACs are 16-bit only */
-+ return put_user(AUDIO_FMT, (long *) arg);
-+
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return ret;
-+}
-+
-+static audio_stream_t output_stream;
-+
-+static audio_state_t audio_state = {
-+ output_stream: &output_stream,
-+ output_dma: DMA_Ser4SSPWr,
-+ output_id: "Generic SSP sound",
-+ hw_init: ssp_audio_init,
-+ hw_shutdown: ssp_audio_shutdown,
-+ client_ioctl: ssp_audio_ioctl,
-+ sem: __MUTEX_INITIALIZER(audio_state.sem),
-+};
-+
-+static int ssp_audio_open(struct inode *inode, struct file *file)
-+{
-+ return sa1100_audio_attach(inode, file, &audio_state);
-+}
-+
-+/*
-+ * Missing fields of this structure will be patched with the call
-+ * to sa1100_audio_attach().
-+ */
-+static struct file_operations ssp_audio_fops = {
-+ open: ssp_audio_open,
-+ owner: THIS_MODULE
-+};
-+
-+static int audio_dev_id;
-+
-+static int __init sa1100ssp_audio_init(void)
-+{
-+ int ret;
-+
-+ if (!machine_is_lart()) {
-+ printk(KERN_ERR AUDIO_NAME ": no support for this SA-1100 design!\n");
-+ /* look at ssp_audio_init() for specific initialisations */
-+ return -ENODEV;
-+ }
-+
-+ /* register devices */
-+ audio_dev_id = register_sound_dsp(&ssp_audio_fops, -1);
-+
-+ printk( KERN_INFO AUDIO_NAME " initialized\n" );
-+ return 0;
-+}
-+
-+static void __exit sa1100ssp_audio_exit(void)
-+{
-+ unregister_sound_dsp(audio_dev_id);
-+}
-+
-+module_init(sa1100ssp_audio_init);
-+module_exit(sa1100ssp_audio_exit);
-+
-+MODULE_AUTHOR("Nicolas Pitre");
-+MODULE_DESCRIPTION("Glue audio driver for a simple DAC on the SA1100's SSP port");
-+
-+MODULE_PARM(sample_rate, "i");
-+MODULE_PARM_DESC(sample_rate, "Sample rate of the audio DAC, default is 44100");
-+
-+EXPORT_NO_SYMBOLS;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/sound/sa1111-ac97.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,518 @@
-+/*
-+ * Glue audio driver for the CS4205 and CS4201 AC'97 codecs.
-+ * largely based on the framework provided by sa1111-uda1341.c.
-+ *
-+ * Copyright (c) 2002 Bertrik Sikken (bertrik.sikken@technolution.nl)
-+ * Copyright (c) 2002 Robert Whaley (rwhaley@applieddata.net)
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License.
-+ *
-+ * This driver makes use of the ac97_codec module (for mixer registers)
-+ * and the sa1100-audio module (for DMA).
-+ *
-+ * History:
-+ *
-+ * 2002-04-04 Initial version.
-+ * 2002-04-10 Updated mtd_audio_init to improve choppy sound
-+ * and hanging sound issue.
-+ * 2002-05-16 Updated for ADS Bitsy+ Robert Whaley
-+ * 2002-06-28 Cleanup and added retry for read register timeouts
-+ * 2002-08-14 Updated for ADS AGC Robert Whaley
-+ * 2002-12-26 Cleanup, remove CONFIG_PM (it's handled by sa1100-audio.c)
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/fs.h>
-+#include <linux/delay.h>
-+#include <linux/pm.h>
-+#include <linux/errno.h>
-+#include <linux/proc_fs.h>
-+#include <linux/sound.h>
-+#include <linux/soundcard.h>
-+#include <linux/ac97_codec.h>
-+
-+#include <asm/semaphore.h>
-+#include <asm/uaccess.h>
-+#include <asm/dma.h>
-+#include <asm/hardware/sa1111.h>
-+
-+#include "sa1100-audio.h"
-+
-+/* SAC FIFO depth, low nibble is transmit fifo, high nibble is receive FIFO */
-+#define SAC_FIFO_DEPTH 0x77
-+
-+// #define DEBUG
-+
-+#ifdef DEBUG
-+#define DPRINTK( x... ) printk( ##x )
-+#else
-+#define DPRINTK( x... )
-+#endif
-+
-+/*
-+ Our codec data
-+*/
-+static struct ac97_codec ac97codec;
-+static int audio_dev_id, mixer_dev_id;
-+static audio_stream_t output_stream, input_stream;
-+
-+/* proc info */
-+
-+struct proc_dir_entry *ac97_ps;
-+
-+static int sa1111_ac97_set_adc_rate(long rate);
-+static void sa1111_ac97_write_reg(struct ac97_codec *dev, u8 reg, u16 val);
-+static u16 sa1111_ac97_read_reg(struct ac97_codec *dev, u8 reg);
-+
-+static int
-+mixer_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
-+{
-+ /*
-+ * We only accept mixer (type 'M') ioctls.
-+ */
-+ if (_IOC_TYPE(cmd) != 'M') {
-+ return -EINVAL;
-+ }
-+
-+ /* pass the ioctl to the ac97 mixer */
-+ return ac97codec.mixer_ioctl(&ac97codec, cmd, arg);
-+}
-+
-+
-+static struct file_operations sa1111_ac97_mixer_fops = {
-+ ioctl: mixer_ioctl,
-+ owner: THIS_MODULE
-+};
-+
-+static void sa1111_ac97_power_off(void *dummy)
-+{
-+#ifdef CONFIG_SA1100_ADSBITSYPLUS
-+ /* turn off audio and audio amp */
-+ ADS_CPLD_PCON |= (ADS_PCON_AUDIO_ON | ADS_PCON_AUDIOPA_ON);
-+
-+ /* make GPIO11 high impeadence */
-+ GPDR &= ~GPIO_GPIO11;
-+
-+ /* disable SACR0 so we can make these pins high impeadence */
-+ SACR0 &= ~SACR0_ENB;
-+
-+ /* make BIT_CLK, SDATA_OUT, and SYNC high impeadence */
-+ PC_DDR |= (GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
-+
-+#endif
-+
-+#ifdef CONFIG_SA1100_ADSAGC
-+ /* turn off audio and audio amp */
-+ ADS_CR1 &= ~(ADS_CR1_CODEC | ADS_CR1_AMP);
-+
-+ /* disable SACR0 so we can make these pins high impeadence */
-+ SACR0 &= ~SACR0_ENB;
-+
-+ /* make BIT_CLK, SDATA_OUT, and SYNC high impeadence */
-+ PC_DDR |= (GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
-+
-+#endif
-+}
-+
-+
-+static void sa1111_ac97_power_on(void *dummy)
-+{
-+ int ret, i;
-+
-+ /* disable L3 */
-+ SACR1 = 0;
-+
-+ SKPCR |= (SKPCR_ACCLKEN); /* enable ac97 clock */
-+ udelay(50);
-+
-+ /* BIT_CLK is input to SA1111, DMA thresholds 9 (both dirs) */
-+ SACR0 |= SACR0_BCKD | (SAC_FIFO_DEPTH << 8);
-+
-+ /* reset SAC registers */
-+ SACR0 &= ~SACR0_RST;
-+ udelay(50);
-+ SACR0 |= SACR0_RST;
-+ udelay(50);
-+ SACR0 &= ~SACR0_RST;
-+
-+ /* setup SA1111 to use AC'97 */
-+ SBI_SKCR |= SKCR_SELAC; /* select ac97 */
-+ udelay(50);
-+
-+ /* issue a cold AC97 reset */
-+#ifdef CONFIG_SA1100_ADSBITSYPLUS
-+
-+ /* initialize reset line */
-+ GAFR &= ~GPIO_GPIO11;
-+ GPDR |= GPIO_GPIO11;
-+ GPSR = GPIO_GPIO11;
-+
-+ /* turn on audio and audio amp */
-+ ADS_CPLD_PCON &= ~(ADS_PCON_AUDIO_ON | ADS_PCON_AUDIOPA_ON);
-+ mdelay(5);
-+
-+ /* reset by lowering the reset pin momentarily */
-+ DPRINTK("reseting codec via GPIO11\n");
-+ GPCR = GPIO_GPIO11;
-+ udelay(5);
-+ GPSR = GPIO_GPIO11;
-+ udelay(10);
-+
-+#endif
-+#ifdef CONFIG_SA1100_ADSAGC
-+
-+ /* turn on audio and audio amp */
-+ DPRINTK("before turning on power. ADS_CR1: %x\n", ADS_CR1);
-+ ADS_CR1 |= (ADS_CR1_AMP | ADS_CR1_CODEC);
-+ DPRINTK("after turnning on power. ADS_CR1: %x\n", ADS_CR1);
-+ mdelay(5);
-+
-+ /* reset by lowering the reset pin momentarily */
-+ DPRINTK("reseting codec via CPLD\n");
-+ ADS_CR1 |= ADS_CR1_AUDIO_RST;
-+ DPRINTK("after reset1. ADS_CR1: %x\n", ADS_CR1);
-+ udelay(5);
-+ ADS_CR1 &= ~ADS_CR1_AUDIO_RST;
-+ DPRINTK("after reset2. ADS_CR1: %x\n", ADS_CR1);
-+ udelay(10);
-+
-+#endif
-+ SACR2 = 0;
-+ udelay(50);
-+
-+ DPRINTK("before SW reset: SACR2: %x\n", SACR2);
-+ SACR2 = SACR2_RESET;
-+ DPRINTK("after SW reset: SACR2: %x\n", SACR2);
-+ udelay(50);
-+
-+ /* set AC97 slot 3 and 4 (PCM out) to valid */
-+ SACR2 = (SACR2_RESET | SACR2_TS3V | SACR2_TS4V);
-+
-+ /* enable SAC */
-+ SACR0 |= SACR0_ENB;
-+
-+ i = 100;
-+ while (!(SASR1 & SASR1_CRDY)) {
-+ if (!i--) {
-+ printk("Didn't get CRDY. SASR1=%x SKID=%x\n", SASR1, SBI_SKID);
-+ break;
-+ }
-+ udelay(50);
-+ }
-+
-+ if (!(ret = ac97_probe_codec(&ac97codec))) {
-+ printk("ac97_probe_codec failed (%d)\n", ret);
-+ return;
-+ }
-+
-+ /* mic ADC on, disable VRA, disable VRM */
-+ sa1111_ac97_write_reg(&ac97codec, AC97_EXTENDED_STATUS, 0x0200);
-+}
-+
-+
-+/*
-+ * Audio interface
-+ */
-+
-+
-+static int sa1111_ac97_audio_ioctl(struct inode *inode, struct file *file,
-+ uint cmd, ulong arg)
-+{
-+ long val;
-+ int ret = 0;
-+
-+ DPRINTK("sa1111_ac97_audio_ioctl\n");
-+
-+ /*
-+ * These are platform dependent ioctls which are not handled by the
-+ * generic sa1100-audio module.
-+ */
-+ switch (cmd) {
-+ case SNDCTL_DSP_STEREO:
-+ ret = get_user(val, (int *) arg);
-+ if (ret) {
-+ return ret;
-+ }
-+ /* the cs42xx is stereo only */
-+ ret = (val == 0) ? -EINVAL : 1;
-+ return put_user(ret, (int *) arg);
-+
-+ case SNDCTL_DSP_CHANNELS:
-+ case SOUND_PCM_READ_CHANNELS:
-+ /* the cs42xx is stereo only */
-+ return put_user(2, (long *) arg);
-+
-+#define SA1100_AC97_IOCTL_EXTRAS
-+
-+#ifdef SA1100_AC97_IOCTL_EXTRAS
-+
-+#define SNDCTL_DSP_AC97_CMD _SIOWR('P', 99, int)
-+#define SNDCTL_DSP_INPUT_SPEED _SIOWR('P', 98, int)
-+#define SOUND_PCM_READ_INPUT_RATE _SIOWR('P', 97, int)
-+
-+ case SNDCTL_DSP_AC97_CMD:
-+
-+ ret = get_user(val, (long *) arg);
-+ if (ret) {
-+ break;
-+ }
-+ sa1111_ac97_write_reg(&ac97codec, (u8) ((val & 0xff000000) >> 24), (u16) (val & 0xffff));
-+ return 0;
-+
-+
-+ case SNDCTL_DSP_INPUT_SPEED:
-+ ret = get_user(val, (long *) arg);
-+ // acc code here to set the speed
-+ if (ret) {
-+ break;
-+ }
-+ // note that this only changes the ADC rate, not the
-+ // rate of the DAC.
-+ ret = sa1111_ac97_set_adc_rate(val);
-+ if (ret)
-+ break;
-+ return put_user(val, (long *) arg);
-+
-+ case SOUND_PCM_READ_INPUT_RATE:
-+
-+ return put_user((long) sa1111_ac97_read_reg(&ac97codec, 0x32), (long *) arg);
-+
-+
-+#endif
-+
-+ case SNDCTL_DSP_SPEED:
-+ ret = get_user(val, (long *) arg);
-+ if (ret) {
-+ break;
-+ }
-+
-+ case SOUND_PCM_READ_RATE:
-+ /* only 48 kHz playback is supported by the SA1111 */
-+ return put_user(48000L, (long *) arg);
-+
-+ case SNDCTL_DSP_SETFMT:
-+ case SNDCTL_DSP_GETFMTS:
-+ /* we can do 16-bit only */
-+ return put_user(AFMT_S16_LE, (long *) arg);
-+
-+ default:
-+ /* Maybe this is meant for the mixer (As per OSS Docs) */
-+ return mixer_ioctl(inode, file, cmd, arg);
-+ }
-+
-+ return ret;
-+}
-+
-+
-+static audio_state_t audio_state = {
-+ output_stream: &output_stream,
-+ input_stream: &input_stream,
-+ skip_dma_init: 1, /* done locally */
-+ hw_init: sa1111_ac97_power_on,
-+ hw_shutdown: sa1111_ac97_power_off,
-+ client_ioctl: sa1111_ac97_audio_ioctl,
-+ sem: __MUTEX_INITIALIZER(audio_state.sem),
-+};
-+
-+
-+static int sa1111_ac97_audio_open(struct inode *inode, struct file *file)
-+{
-+ return sa1100_audio_attach(inode, file, &audio_state);
-+}
-+
-+
-+/*
-+ * Missing fields of this structure will be patched with the call
-+ * to sa1100_audio_attach().
-+ */
-+static struct file_operations sa1111_ac97_audio_fops = {
-+ open: sa1111_ac97_audio_open,
-+ owner: THIS_MODULE
-+};
-+
-+
-+static void sa1111_ac97_write_reg(struct ac97_codec *dev, u8 reg, u16 val)
-+{
-+ int i;
-+
-+ /* reset status bits */
-+ SASCR = SASCR_DTS;
-+
-+ /* write command and data registers */
-+ ACCAR = reg << 12;
-+ ACCDR = val << 4;
-+
-+ /* wait for data to be transmitted */
-+ i = 0;
-+ while ((SASR1 & SASR1_CADT) == 0) {
-+ udelay(50);
-+ if (++i > 10) {
-+ DPRINTK("sa1111_ac97_write_reg failed (data not transmitted. SASR1: %x)\n", SASR1);
-+ break;
-+ }
-+ }
-+
-+ DPRINTK("<%03d> sa1111_ac97_write_reg, [%02X]=%04X\n", i, reg, val);
-+}
-+
-+
-+static u16 sa1111_ac97_read_reg(struct ac97_codec *dev, u8 reg)
-+{
-+ u16 val;
-+ int i;
-+ int retry = 10;
-+
-+ do {
-+ /* reset status bits */
-+ SASCR = SASCR_RDD | SASCR_STO;
-+
-+ /* write command register */
-+ ACCAR = (reg | 0x80) << 12;
-+ ACCDR = 0;
-+
-+ /* wait for SADR bit in SASR1 */
-+ i = 0;
-+ while ((SASR1 & SASR1_SADR) == 0) {
-+ udelay(50);
-+ if (++i > 10) {
-+ DPRINTK("<---> sa1111_ac97_read_reg failed\n");
-+ retry--;
-+ break;
-+ }
-+ if ((SASR1 & SASR1_RSTO) != 0) {
-+ DPRINTK("sa1111_ac97_read_reg *timeout*\n");
-+ retry--;
-+ break;
-+ }
-+ }
-+
-+ } while ((SASR1 & SASR1_SADR) == 0 && retry > 0);
-+
-+ val = ACSDR >> 4;
-+
-+ DPRINTK("<%03d> sa1111_ac97_read_reg, [%02X]=%04X\n", i, reg, val);
-+ return val;
-+}
-+
-+
-+/* wait for codec ready */
-+static void sa1111_ac97_ready(struct ac97_codec *dev)
-+{
-+ int i;
-+ u16 val;
-+
-+ i = 0;
-+ while ((SASR1 & SASR1_CRDY) == 0) {
-+ udelay(50);
-+ if (++i > 10) {
-+ DPRINTK("sa1111_ac97_ready failed\n");
-+ return;
-+ }
-+ }
-+ DPRINTK("codec_ready bit took %d cycles\n", i);
-+
-+ /* Wait for analog parts of codec to initialise */
-+ i = 0;
-+ do {
-+ val = sa1111_ac97_read_reg(&ac97codec, AC97_POWER_CONTROL);
-+ if (++i > 100) {
-+ break;
-+ }
-+ mdelay(10);
-+ } while ((val & 0xF) != 0xF || val == 0xFFFF);
-+
-+ /* the cs42xx typically takes 150 ms to initialise */
-+
-+ DPRINTK("analog init took %d cycles\n", i);
-+}
-+
-+
-+static int __init sa1111_ac97_init(void)
-+{
-+ int ret;
-+
-+ // SBI_SKCR |= SKCR_RCLKEN;
-+
-+ DPRINTK("sa1111_ac97_init\n");
-+
-+ /* install the ac97 mixer module */
-+ ac97codec.codec_read = sa1111_ac97_read_reg;
-+ ac97codec.codec_write = sa1111_ac97_write_reg;
-+ ac97codec.codec_wait = sa1111_ac97_ready;
-+
-+ /* Acquire and initialize DMA */
-+ ret = sa1111_sac_request_dma(&output_stream.dma_ch, "SA1111 audio out",
-+ SA1111_SAC_XMT_CHANNEL);
-+ if (ret < 0) {
-+ printk("DMA request for SAC output failed\n");
-+ return ret;
-+ }
-+
-+ ret = sa1111_sac_request_dma(&input_stream.dma_ch, "SA1111 audio in",
-+ SA1111_SAC_RCV_CHANNEL);
-+ if (ret < 0) {
-+ printk("DMA request for SAC input failed\n");
-+ sa1100_free_dma(output_stream.dma_ch);
-+ return ret;
-+ }
-+ /* register devices */
-+ audio_dev_id = register_sound_dsp(&sa1111_ac97_audio_fops, -1);
-+ mixer_dev_id = register_sound_mixer(&sa1111_ac97_mixer_fops, -1);
-+
-+
-+ /* setup proc entry */
-+ ac97_ps = create_proc_read_entry ("driver/sa1111-ac97", 0, NULL,
-+ ac97_read_proc, &ac97codec);
-+
-+ return 0;
-+}
-+
-+
-+static void __exit sa1111_ac97_exit(void)
-+{
-+ SKPCR &= ~SKPCR_ACCLKEN; /* disable ac97 clock */
-+ SBI_SKCR &= ~SKCR_SELAC; /* deselect ac97 */
-+
-+ unregister_sound_dsp(audio_dev_id);
-+ unregister_sound_mixer(mixer_dev_id);
-+ sa1100_free_dma(output_stream.dma_ch);
-+ sa1100_free_dma(input_stream.dma_ch);
-+}
-+
-+static int sa1111_ac97_set_adc_rate(long rate)
-+{
-+
-+ // note this only changes the rate of the ADC, the DAC is fixed at 48K.
-+ // this is due to limitations of the SA1111 chip
-+
-+ u16 code = rate;
-+
-+ switch (rate) {
-+ case 8000:
-+ case 11025:
-+ case 16000:
-+ case 22050:
-+ case 32000:
-+ case 44100:
-+ case 48000:
-+ break;
-+ default:
-+ return -1;
-+ }
-+ sa1111_ac97_write_reg(&ac97codec, 0x2A, 0x0001);
-+ sa1111_ac97_write_reg(&ac97codec, 0x32, code);
-+ return 0;
-+}
-+
-+module_init(sa1111_ac97_init);
-+module_exit(sa1111_ac97_exit);
-+
-+MODULE_AUTHOR("Bertrik Sikken, Technolution B.V., Netherlands");
-+MODULE_DESCRIPTION("Glue audio driver for AC'97 codec");
-+MODULE_LICENSE("GPL");
-+
-+EXPORT_NO_SYMBOLS;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/sound/sa1111-uda1341.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,282 @@
-+/*
-+ * Glue audio driver for the SA1111 compagnon chip & Philips UDA1341 codec.
-+ *
-+ * Copyright (c) 2000 John Dorsey
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License.
-+ *
-+ * History:
-+ *
-+ * 2000-09-04 John Dorsey SA-1111 Serial Audio Controller support
-+ * was initially added to the sa1100-uda1341.c
-+ * driver.
-+ *
-+ * 2001-06-03 Nicolas Pitre Made this file a separate module, based on
-+ * the former sa1100-uda1341.c driver.
-+ *
-+ * 2001-09-23 Russell King Remove old L3 bus driver.
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/fs.h>
-+#include <linux/delay.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/sound.h>
-+#include <linux/soundcard.h>
-+#include <linux/ioport.h>
-+#include <linux/pm.h>
-+#include <linux/l3/l3.h>
-+#include <linux/l3/uda1341.h>
-+
-+#include <asm/semaphore.h>
-+#include <asm/mach-types.h>
-+#include <asm/uaccess.h>
-+#include <asm/hardware.h>
-+#include <asm/dma.h>
-+#include <asm/arch/assabet.h>
-+#include <asm/hardware/sa1111.h>
-+
-+#include "sa1100-audio.h"
-+
-+#undef DEBUG
-+#ifdef DEBUG
-+#define DPRINTK( x... ) printk( ##x )
-+#else
-+#define DPRINTK( x... )
-+#endif
-+
-+
-+/*
-+ * Definitions
-+ */
-+
-+#define AUDIO_RATE_DEFAULT 22050
-+
-+#define AUDIO_CLK_BASE 561600
-+
-+
-+
-+/*
-+ * Mixer interface
-+ */
-+
-+static struct l3_client uda1341;
-+
-+static int
-+mixer_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
-+{
-+ /*
-+ * We only accept mixer (type 'M') ioctls.
-+ */
-+ if (_IOC_TYPE(cmd) != 'M')
-+ return -EINVAL;
-+
-+ return l3_command(&uda1341, cmd, (void *)arg);
-+}
-+
-+static struct file_operations uda1341_mixer_fops = {
-+ ioctl: mixer_ioctl,
-+ owner: THIS_MODULE
-+};
-+
-+
-+/*
-+ * Audio interface
-+ */
-+
-+static int audio_clk_div = (AUDIO_CLK_BASE + AUDIO_RATE_DEFAULT/2)/AUDIO_RATE_DEFAULT;
-+
-+static void sa1111_audio_init(void *dummy)
-+{
-+#ifdef CONFIG_ASSABET_NEPONSET
-+ if (machine_is_assabet()) {
-+ /* Select I2S audio (instead of AC-Link) */
-+ AUD_CTL = AUD_SEL_1341;
-+ }
-+#endif
-+#ifdef CONFIG_SA1100_JORNADA720
-+ if (machine_is_jornada720()) {
-+ /* LDD4 is speaker, LDD3 is microphone */
-+ PPSR &= ~(PPC_LDD3 | PPC_LDD4);
-+ PPDR |= PPC_LDD3 | PPC_LDD4;
-+ PPSR |= PPC_LDD4; /* enable speaker */
-+ PPSR |= PPC_LDD3; /* enable microphone */
-+ }
-+#endif
-+
-+ SBI_SKCR &= ~SKCR_SELAC;
-+
-+ /* Enable the I2S clock and L3 bus clock: */
-+ SKPCR |= (SKPCR_I2SCLKEN | SKPCR_L3CLKEN);
-+
-+ /* Activate and reset the Serial Audio Controller */
-+ SACR0 |= (SACR0_ENB | SACR0_RST);
-+ mdelay(5);
-+ SACR0 &= ~SACR0_RST;
-+
-+ /* For I2S, BIT_CLK is supplied internally. The "SA-1111
-+ * Specification Update" mentions that the BCKD bit should
-+ * be interpreted as "0 = output". Default clock divider
-+ * is 22.05kHz.
-+ *
-+ * Select I2S, L3 bus. "Recording" and "Replaying"
-+ * (receive and transmit) are enabled.
-+ */
-+ SACR1 = SACR1_L3EN;
-+ SKAUD = audio_clk_div - 1;
-+
-+ /* Initialize the UDA1341 internal state */
-+ l3_open(&uda1341);
-+}
-+
-+static void sa1111_audio_shutdown(void *dummy)
-+{
-+ l3_close(&uda1341);
-+ SACR0 &= ~SACR0_ENB;
-+}
-+
-+static int sa1111_audio_ioctl( struct inode *inode, struct file *file,
-+ uint cmd, ulong arg)
-+{
-+ long val;
-+ int ret = 0;
-+
-+ switch (cmd) {
-+ case SNDCTL_DSP_STEREO:
-+ ret = get_user(val, (int *) arg);
-+ if (ret)
-+ return ret;
-+ /* the UDA1341 is stereo only */
-+ ret = (val == 0) ? -EINVAL : 1;
-+ return put_user(ret, (int *) arg);
-+
-+ case SNDCTL_DSP_CHANNELS:
-+ case SOUND_PCM_READ_CHANNELS:
-+ /* the UDA1341 is stereo only */
-+ return put_user(2, (long *) arg);
-+
-+ case SNDCTL_DSP_SPEED:
-+ ret = get_user(val, (long *) arg);
-+ if (ret) break;
-+ if (val < 8000) val = 8000;
-+ if (val > 48000) val = 48000;
-+ audio_clk_div = (AUDIO_CLK_BASE + val/2)/val;
-+ SKAUD = audio_clk_div - 1;
-+ /* fall through */
-+
-+ case SOUND_PCM_READ_RATE:
-+ return put_user(AUDIO_CLK_BASE/audio_clk_div, (long *) arg);
-+
-+ case SNDCTL_DSP_SETFMT:
-+ case SNDCTL_DSP_GETFMTS:
-+ /* we can do 16-bit only */
-+ return put_user(AFMT_S16_LE, (long *) arg);
-+
-+ default:
-+ /* Maybe this is meant for the mixer (as per OSS Docs) */
-+ return mixer_ioctl(inode, file, cmd, arg);
-+ }
-+
-+ return ret;
-+}
-+
-+static audio_stream_t output_stream, input_stream;
-+
-+static audio_state_t audio_state = {
-+ output_stream: &output_stream,
-+ input_stream: &input_stream,
-+ skip_dma_init: 1, /* done locally */
-+ hw_init: sa1111_audio_init,
-+ hw_shutdown: sa1111_audio_shutdown,
-+ client_ioctl: sa1111_audio_ioctl,
-+ sem: __MUTEX_INITIALIZER(audio_state.sem),
-+};
-+
-+static int sa1111_audio_open(struct inode *inode, struct file *file)
-+{
-+ return sa1100_audio_attach(inode, file, &audio_state);
-+}
-+
-+/*
-+ * Missing fields of this structure will be patched with the call
-+ * to sa1100_audio_attach().
-+ */
-+static struct file_operations sa1111_audio_fops = {
-+ open: sa1111_audio_open,
-+ owner: THIS_MODULE
-+};
-+
-+static int audio_dev_id, mixer_dev_id;
-+
-+static int __init sa1111_uda1341_init(void)
-+{
-+ struct uda1341_cfg cfg;
-+ int ret;
-+
-+ if ( !( (machine_is_assabet() && machine_has_neponset()) ||
-+ machine_is_jornada720() ||
-+ machine_is_badge4() ))
-+ return -ENODEV;
-+
-+ if (!request_mem_region(_SACR0, 512, "sound"))
-+ return -EBUSY;
-+
-+ ret = l3_attach_client(&uda1341, "l3-sa1111", "uda1341");
-+ if (ret)
-+ goto out;
-+
-+ /* Acquire and initialize DMA */
-+ ret = sa1111_sac_request_dma(&output_stream.dma_ch, "SA1111 audio out",
-+ SA1111_SAC_XMT_CHANNEL);
-+ if (ret < 0)
-+ goto release_l3;
-+
-+ ret = sa1111_sac_request_dma(&input_stream.dma_ch, "SA1111 audio in",
-+ SA1111_SAC_RCV_CHANNEL);
-+ if (ret < 0)
-+ goto release_dma;
-+
-+ cfg.fs = 256;
-+ cfg.format = FMT_I2S;
-+ l3_command(&uda1341, L3_UDA1341_CONFIGURE, &cfg);
-+
-+ /* register devices */
-+ audio_dev_id = register_sound_dsp(&sa1111_audio_fops, -1);
-+ mixer_dev_id = register_sound_mixer(&uda1341_mixer_fops, -1);
-+
-+ printk(KERN_INFO "Sound: SA1111 UDA1341: dsp id %d mixer id %d\n",
-+ audio_dev_id, mixer_dev_id);
-+ return 0;
-+
-+release_dma:
-+ sa1100_free_dma(output_stream.dma_ch);
-+release_l3:
-+ l3_detach_client(&uda1341);
-+out:
-+ release_mem_region(_SACR0, 512);
-+ return ret;
-+}
-+
-+static void __exit sa1111_uda1341_exit(void)
-+{
-+ unregister_sound_dsp(audio_dev_id);
-+ unregister_sound_mixer(mixer_dev_id);
-+ sa1100_free_dma(output_stream.dma_ch);
-+ sa1100_free_dma(input_stream.dma_ch);
-+ l3_detach_client(&uda1341);
-+
-+ release_mem_region(_SACR0, 512);
-+}
-+
-+module_init(sa1111_uda1341_init);
-+module_exit(sa1111_uda1341_exit);
-+
-+MODULE_AUTHOR("John Dorsey, Nicolas Pitre");
-+MODULE_DESCRIPTION("Glue audio driver for the SA1111 compagnon chip & Philips UDA1341 codec.");
-+
-+EXPORT_NO_SYMBOLS;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/sound/uda1341.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,511 @@
-+/*
-+ * Philips UDA1341 mixer device driver
-+ *
-+ * Copyright (c) 2000 Nicolas Pitre <nico@cam.org>
-+ *
-+ * Portions are Copyright (C) 2000 Lernout & Hauspie Speech Products, N.V.
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License.
-+ *
-+ * History:
-+ *
-+ * 2000-05-21 Nicolas Pitre Initial release.
-+ *
-+ * 2000-08-19 Erik Bunce More inline w/ OSS API and UDA1341 docs
-+ * including fixed AGC and audio source handling
-+ *
-+ * 2000-11-30 Nicolas Pitre - More mixer functionalities.
-+ *
-+ * 2001-06-03 Nicolas Pitre Made this file a separate module, based on
-+ * the former sa1100-uda1341.c driver.
-+ *
-+ * 2001-08-13 Russell King Re-written as part of the L3 interface
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/slab.h>
-+#include <linux/errno.h>
-+#include <linux/ioctl.h>
-+#include <linux/soundcard.h>
-+#include <linux/l3/l3.h>
-+#include <linux/l3/uda1341.h>
-+
-+#include <asm/uaccess.h>
-+
-+#define DEF_VOLUME 65
-+
-+/*
-+ * UDA1341 L3 address and command types
-+ */
-+#define UDA1341_L3ADDR 5
-+#define UDA1341_DATA0 (UDA1341_L3ADDR << 2 | 0)
-+#define UDA1341_DATA1 (UDA1341_L3ADDR << 2 | 1)
-+#define UDA1341_STATUS (UDA1341_L3ADDR << 2 | 2)
-+
-+struct uda1341_regs {
-+ unsigned char stat0;
-+#define STAT0 0x00
-+#define STAT0_RST (1 << 6)
-+#define STAT0_SC_MASK (3 << 4)
-+#define STAT0_SC_512FS (0 << 4)
-+#define STAT0_SC_384FS (1 << 4)
-+#define STAT0_SC_256FS (2 << 4)
-+#define STAT0_IF_MASK (7 << 1)
-+#define STAT0_IF_I2S (0 << 1)
-+#define STAT0_IF_LSB16 (1 << 1)
-+#define STAT0_IF_LSB18 (2 << 1)
-+#define STAT0_IF_LSB20 (3 << 1)
-+#define STAT0_IF_MSB (4 << 1)
-+#define STAT0_IF_LSB16MSB (5 << 1)
-+#define STAT0_IF_LSB18MSB (6 << 1)
-+#define STAT0_IF_LSB20MSB (7 << 1)
-+#define STAT0_DC_FILTER (1 << 0)
-+
-+ unsigned char stat1;
-+#define STAT1 0x80
-+#define STAT1_DAC_GAIN (1 << 6) /* gain of DAC */
-+#define STAT1_ADC_GAIN (1 << 5) /* gain of ADC */
-+#define STAT1_ADC_POL (1 << 4) /* polarity of ADC */
-+#define STAT1_DAC_POL (1 << 3) /* polarity of DAC */
-+#define STAT1_DBL_SPD (1 << 2) /* double speed playback */
-+#define STAT1_ADC_ON (1 << 1) /* ADC powered */
-+#define STAT1_DAC_ON (1 << 0) /* DAC powered */
-+
-+ unsigned char data0_0;
-+#define DATA0 0x00
-+#define DATA0_VOLUME_MASK 0x3f
-+#define DATA0_VOLUME(x) (x)
-+
-+ unsigned char data0_1;
-+#define DATA1 0x40
-+#define DATA1_BASS(x) ((x) << 2)
-+#define DATA1_BASS_MASK (15 << 2)
-+#define DATA1_TREBLE(x) ((x))
-+#define DATA1_TREBLE_MASK (3)
-+
-+ unsigned char data0_2;
-+#define DATA2 0x80
-+#define DATA2_PEAKAFTER (1 << 5)
-+#define DATA2_DEEMP_NONE (0 << 3)
-+#define DATA2_DEEMP_32KHz (1 << 3)
-+#define DATA2_DEEMP_44KHz (2 << 3)
-+#define DATA2_DEEMP_48KHz (3 << 3)
-+#define DATA2_MUTE (1 << 2)
-+#define DATA2_FILTER_FLAT (0 << 0)
-+#define DATA2_FILTER_MIN (1 << 0)
-+#define DATA2_FILTER_MAX (3 << 0)
-+
-+#define EXTADDR(n) (0xc0 | (n))
-+#define EXTDATA(d) (0xe0 | (d))
-+
-+ unsigned char ext0;
-+#define EXT0 0
-+#define EXT0_CH1_GAIN(x) (x)
-+
-+ unsigned char ext1;
-+#define EXT1 1
-+#define EXT1_CH2_GAIN(x) (x)
-+
-+ unsigned char ext2;
-+#define EXT2 2
-+#define EXT2_MIC_GAIN_MASK (7 << 2)
-+#define EXT2_MIC_GAIN(x) ((x) << 2)
-+#define EXT2_MIXMODE_DOUBLEDIFF (0)
-+#define EXT2_MIXMODE_CH1 (1)
-+#define EXT2_MIXMODE_CH2 (2)
-+#define EXT2_MIXMODE_MIX (3)
-+
-+ unsigned char ext4;
-+#define EXT4 4
-+#define EXT4_AGC_ENABLE (1 << 4)
-+#define EXT4_INPUT_GAIN_MASK (3)
-+#define EXT4_INPUT_GAIN(x) ((x) & 3)
-+
-+ unsigned char ext5;
-+#define EXT5 5
-+#define EXT5_INPUT_GAIN(x) ((x) >> 2)
-+
-+ unsigned char ext6;
-+#define EXT6 6
-+#define EXT6_AGC_CONSTANT_MASK (7 << 2)
-+#define EXT6_AGC_CONSTANT(x) ((x) << 2)
-+#define EXT6_AGC_LEVEL_MASK (3)
-+#define EXT6_AGC_LEVEL(x) (x)
-+};
-+
-+#define REC_MASK (SOUND_MASK_LINE | SOUND_MASK_MIC)
-+#define DEV_MASK (REC_MASK | SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE)
-+
-+struct uda1341 {
-+ struct uda1341_regs regs;
-+ int active;
-+ unsigned short volume;
-+ unsigned short bass;
-+ unsigned short treble;
-+ unsigned short line;
-+ unsigned short mic;
-+ int mod_cnt;
-+};
-+
-+#define ADD_FIELD(reg,field) \
-+ *p++ = reg | uda->regs.field
-+
-+#define ADD_EXTFIELD(reg,field) \
-+ *p++ = EXTADDR(reg); \
-+ *p++ = EXTDATA(uda->regs.field);
-+
-+static void uda1341_sync(struct l3_client *clnt)
-+{
-+ struct uda1341 *uda = clnt->driver_data;
-+ char buf[24], *p = buf;
-+
-+ ADD_FIELD(STAT0, stat0);
-+ ADD_FIELD(STAT1, stat1);
-+
-+ if (p != buf)
-+ l3_write(clnt, UDA1341_STATUS, buf, p - buf);
-+
-+ p = buf;
-+ ADD_FIELD(DATA0, data0_0);
-+ ADD_FIELD(DATA1, data0_1);
-+ ADD_FIELD(DATA2, data0_2);
-+ ADD_EXTFIELD(EXT0, ext0);
-+ ADD_EXTFIELD(EXT1, ext1);
-+ ADD_EXTFIELD(EXT2, ext2);
-+ ADD_EXTFIELD(EXT4, ext4);
-+ ADD_EXTFIELD(EXT5, ext5);
-+ ADD_EXTFIELD(EXT6, ext6);
-+
-+ if (p != buf)
-+ l3_write(clnt, UDA1341_DATA0, buf, p - buf);
-+}
-+
-+static void uda1341_cmd_init(struct l3_client *clnt)
-+{
-+ struct uda1341 *uda = clnt->driver_data;
-+ char buf[2];
-+
-+ uda->active = 1;
-+
-+ buf[0] = uda->regs.stat0 | STAT0_RST;
-+ buf[1] = uda->regs.stat0;
-+
-+ l3_write(clnt, UDA1341_STATUS, buf, 2);
-+
-+ /* resend all parameters */
-+ uda1341_sync(clnt);
-+}
-+
-+static int uda1341_configure(struct l3_client *clnt, struct uda1341_cfg *conf)
-+{
-+ struct uda1341 *uda = clnt->driver_data;
-+ int ret = 0;
-+
-+ uda->regs.stat0 &= ~(STAT0_SC_MASK | STAT0_IF_MASK);
-+
-+ switch (conf->fs) {
-+ case 512: uda->regs.stat0 |= STAT0_SC_512FS; break;
-+ case 384: uda->regs.stat0 |= STAT0_SC_384FS; break;
-+ case 256: uda->regs.stat0 |= STAT0_SC_256FS; break;
-+ default: ret = -EINVAL; break;
-+ }
-+
-+ switch (conf->format) {
-+ case FMT_I2S: uda->regs.stat0 |= STAT0_IF_I2S; break;
-+ case FMT_LSB16: uda->regs.stat0 |= STAT0_IF_LSB16; break;
-+ case FMT_LSB18: uda->regs.stat0 |= STAT0_IF_LSB18; break;
-+ case FMT_LSB20: uda->regs.stat0 |= STAT0_IF_LSB20; break;
-+ case FMT_MSB: uda->regs.stat0 |= STAT0_IF_MSB; break;
-+ case FMT_LSB16MSB: uda->regs.stat0 |= STAT0_IF_LSB16MSB; break;
-+ case FMT_LSB18MSB: uda->regs.stat0 |= STAT0_IF_LSB18MSB; break;
-+ case FMT_LSB20MSB: uda->regs.stat0 |= STAT0_IF_LSB20MSB; break;
-+ }
-+
-+ if (ret == 0 && uda->active) {
-+ char buf = uda->regs.stat0 | STAT0;
-+ l3_write(clnt, UDA1341_STATUS, &buf, 1);
-+ }
-+ return ret;
-+}
-+
-+static int uda1341_update_direct(struct l3_client *clnt, int cmd, void *arg)
-+{
-+ struct uda1341 *uda = clnt->driver_data;
-+ struct l3_gain *v = arg;
-+ char newreg;
-+ int val;
-+
-+ switch (cmd) {
-+ case L3_SET_VOLUME: /* set volume. val = 0 to 100 => 62 to 1 */
-+ uda->regs.data0_0 = DATA0_VOLUME(62 - ((v->left * 61) / 100));
-+ newreg = uda->regs.data0_0 | DATA0;
-+ break;
-+
-+ case L3_SET_BASS: /* set bass. val = 50 to 100 => 0 to 12 */
-+ val = v->left - 50;
-+ if (val < 0)
-+ val = 0;
-+ uda->regs.data0_1 &= ~DATA1_BASS_MASK;
-+ uda->regs.data0_1 |= DATA1_BASS((val * 12) / 50);
-+ newreg = uda->regs.data0_1 | DATA1;
-+ break;
-+
-+ case L3_SET_TREBLE: /* set treble. val = 50 to 100 => 0 to 3 */
-+ val = v->left - 50;
-+ if (val < 0)
-+ val = 0;
-+ uda->regs.data0_1 &= ~DATA1_TREBLE_MASK;
-+ uda->regs.data0_1 |= DATA1_TREBLE((val * 3) / 50);
-+ newreg = uda->regs.data0_1 | DATA1;
-+ break;
-+
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ if (uda->active)
-+ l3_write(clnt, UDA1341_DATA0, &newreg, 1);
-+ return 0;
-+}
-+
-+static int uda1341_update_indirect(struct l3_client *clnt, int cmd, void *arg)
-+{
-+ struct uda1341 *uda = clnt->driver_data;
-+ struct l3_gain *gain = arg;
-+ struct l3_agc *agc = arg;
-+ char buf[8], *p = buf;
-+ int val, ret = 0;
-+
-+ switch (cmd) {
-+ case L3_SET_GAIN:
-+ val = 31 - (gain->left * 31 / 100);
-+ switch (gain->channel) {
-+ case 1:
-+ uda->regs.ext0 = EXT0_CH1_GAIN(val);
-+ ADD_EXTFIELD(EXT0, ext0);
-+ break;
-+
-+ case 2:
-+ uda->regs.ext1 = EXT1_CH2_GAIN(val);
-+ ADD_EXTFIELD(EXT1, ext1);
-+ break;
-+
-+ default:
-+ ret = -EINVAL;
-+ }
-+ break;
-+
-+ case L3_INPUT_AGC:
-+ if (agc->channel == 2) {
-+ if (agc->enable)
-+ uda->regs.ext4 |= EXT4_AGC_ENABLE;
-+ else
-+ uda->regs.ext4 &= ~EXT4_AGC_ENABLE;
-+#if 0
-+ agc->level
-+ agc->attack
-+ agc->decay
-+#endif
-+ ADD_EXTFIELD(EXT4, ext4);
-+ } else
-+ ret = -EINVAL;
-+ break;
-+
-+ default:
-+ ret = -EINVAL;
-+ break;
-+ }
-+
-+ if (ret == 0 && uda->active)
-+ l3_write(clnt, UDA1341_DATA0, buf, p - buf);
-+
-+ return ret;
-+}
-+
-+static int uda1341_mixer_ioctl(struct l3_client *clnt, int cmd, void *arg)
-+{
-+ struct uda1341 *uda = clnt->driver_data;
-+ struct l3_gain gain;
-+ int val, nr = _IOC_NR(cmd), ret = 0;
-+
-+ if (cmd == SOUND_MIXER_INFO) {
-+ struct mixer_info mi;
-+
-+ strncpy(mi.id, "UDA1341", sizeof(mi.id));
-+ strncpy(mi.name, "Philips UDA1341", sizeof(mi.name));
-+ mi.modify_counter = uda->mod_cnt;
-+ return copy_to_user(arg, &mi, sizeof(mi));
-+ }
-+
-+ if (_IOC_DIR(cmd) & _IOC_WRITE) {
-+ ret = get_user(val, (int *)arg);
-+ if (ret)
-+ goto out;
-+
-+ gain.left = val & 255;
-+ gain.right = val >> 8;
-+ gain.channel = 0;
-+
-+ switch (nr) {
-+ case SOUND_MIXER_VOLUME:
-+ uda->volume = val;
-+ uda->mod_cnt++;
-+ uda1341_update_direct(clnt, L3_SET_VOLUME, &gain);
-+ break;
-+
-+ case SOUND_MIXER_BASS:
-+ uda->bass = val;
-+ uda->mod_cnt++;
-+ uda1341_update_direct(clnt, L3_SET_BASS, &gain);
-+ break;
-+
-+ case SOUND_MIXER_TREBLE:
-+ uda->treble = val;
-+ uda->mod_cnt++;
-+ uda1341_update_direct(clnt, L3_SET_TREBLE, &gain);
-+ break;
-+
-+ case SOUND_MIXER_LINE:
-+ uda->line = val;
-+ gain.channel = 1;
-+ uda->mod_cnt++;
-+ uda1341_update_indirect(clnt, L3_SET_GAIN, &gain);
-+ break;
-+
-+ case SOUND_MIXER_MIC:
-+ uda->mic = val;
-+ gain.channel = 2;
-+ uda->mod_cnt++;
-+ uda1341_update_indirect(clnt, L3_SET_GAIN, &gain);
-+ break;
-+
-+ case SOUND_MIXER_RECSRC:
-+ break;
-+
-+ default:
-+ ret = -EINVAL;
-+ }
-+ }
-+
-+ if (ret == 0 && _IOC_DIR(cmd) & _IOC_READ) {
-+ int nr = _IOC_NR(cmd);
-+ ret = 0;
-+
-+ switch (nr) {
-+ case SOUND_MIXER_VOLUME: val = uda->volume; break;
-+ case SOUND_MIXER_BASS: val = uda->bass; break;
-+ case SOUND_MIXER_TREBLE: val = uda->treble; break;
-+ case SOUND_MIXER_LINE: val = uda->line; break;
-+ case SOUND_MIXER_MIC: val = uda->mic; break;
-+ case SOUND_MIXER_RECSRC: val = REC_MASK; break;
-+ case SOUND_MIXER_RECMASK: val = REC_MASK; break;
-+ case SOUND_MIXER_DEVMASK: val = DEV_MASK; break;
-+ case SOUND_MIXER_CAPS: val = 0; break;
-+ case SOUND_MIXER_STEREODEVS: val = 0; break;
-+ default: val = 0; ret = -EINVAL; break;
-+ }
-+
-+ if (ret == 0)
-+ ret = put_user(val, (int *)arg);
-+ }
-+out:
-+ return ret;
-+}
-+
-+static int uda1341_attach(struct l3_client *clnt)
-+{
-+ struct uda1341 *uda;
-+
-+ uda = kmalloc(sizeof(*uda), GFP_KERNEL);
-+ if (!uda)
-+ return -ENOMEM;
-+
-+ memset(uda, 0, sizeof(*uda));
-+
-+ uda->volume = DEF_VOLUME | DEF_VOLUME << 8;
-+ uda->bass = 50 | 50 << 8;
-+ uda->treble = 50 | 50 << 8;
-+ uda->line = 88 | 88 << 8;
-+ uda->mic = 88 | 88 << 8;
-+
-+ uda->regs.stat0 = STAT0_SC_256FS | STAT0_IF_LSB16;
-+ uda->regs.stat1 = STAT1_DAC_GAIN | STAT1_ADC_GAIN |
-+ STAT1_ADC_ON | STAT1_DAC_ON;
-+ uda->regs.data0_0 = DATA0_VOLUME(62 - ((DEF_VOLUME * 61) / 100));
-+ uda->regs.data0_1 = DATA1_BASS(0) | DATA1_TREBLE(0);
-+ uda->regs.data0_2 = DATA2_PEAKAFTER | DATA2_DEEMP_NONE |
-+ DATA2_FILTER_MAX;
-+ uda->regs.ext0 = EXT0_CH1_GAIN(4);
-+ uda->regs.ext1 = EXT1_CH2_GAIN(4);
-+ uda->regs.ext2 = EXT2_MIXMODE_MIX | EXT2_MIC_GAIN(4);
-+ uda->regs.ext4 = EXT4_AGC_ENABLE | EXT4_INPUT_GAIN(0);
-+ uda->regs.ext5 = EXT5_INPUT_GAIN(0);
-+ uda->regs.ext6 = EXT6_AGC_CONSTANT(3) | EXT6_AGC_LEVEL(0);
-+
-+ clnt->driver_data = uda;
-+
-+ return 0;
-+}
-+
-+static void uda1341_detach(struct l3_client *clnt)
-+{
-+ kfree(clnt->driver_data);
-+}
-+
-+static int
-+uda1341_command(struct l3_client *clnt, int cmd, void *arg)
-+{
-+ int ret = -EINVAL;
-+
-+ if (_IOC_TYPE(cmd) == 'M')
-+ ret = uda1341_mixer_ioctl(clnt, cmd, arg);
-+ else if (cmd == L3_UDA1341_CONFIGURE)
-+ ret = uda1341_configure(clnt, arg);
-+
-+ return ret;
-+}
-+
-+static int uda1341_open(struct l3_client *clnt)
-+{
-+ uda1341_cmd_init(clnt);
-+ return 0;
-+}
-+
-+static void uda1341_close(struct l3_client *clnt)
-+{
-+ struct uda1341 *uda = clnt->driver_data;
-+ uda->active = 0;
-+}
-+
-+static struct l3_ops uda1341_ops = {
-+ open: uda1341_open,
-+ command: uda1341_command,
-+ close: uda1341_close,
-+};
-+
-+static struct l3_driver uda1341 = {
-+ name: UDA1341_NAME,
-+ attach_client: uda1341_attach,
-+ detach_client: uda1341_detach,
-+ ops: &uda1341_ops,
-+ owner: THIS_MODULE,
-+};
-+
-+static int __init uda1341_init(void)
-+{
-+ return l3_add_driver(&uda1341);
-+}
-+
-+static void __exit uda1341_exit(void)
-+{
-+ l3_del_driver(&uda1341);
-+}
-+
-+module_init(uda1341_init);
-+module_exit(uda1341_exit);
-+
-+MODULE_AUTHOR("Nicolas Pitre");
-+MODULE_DESCRIPTION("Philips UDA1341 CODEC driver");
---- linux-2.4.25/drivers/sound/vidc.c~2.4.25-vrs2.patch 2001-10-11 18:43:30.000000000 +0200
-+++ linux-2.4.25/drivers/sound/vidc.c 2004-03-31 17:15:09.000000000 +0200
-@@ -40,6 +40,7 @@
- #endif
-
- #define VIDC_SOUND_CLOCK (250000)
-+#define VIDC_SOUND_CLOCK_EXT (176400)
-
- /*
- * When using SERIAL SOUND mode (external DAC), the number of physical
-@@ -192,28 +193,43 @@
- return vidc_audio_format;
- }
-
-+#define my_abs(i) ((i)<0 ? -(i) : (i))
-+
- static int vidc_audio_set_speed(int dev, int rate)
- {
- if (rate) {
-- unsigned int hwctrl, hwrate;
-+ unsigned int hwctrl, hwrate, hwrate_ext, rate_int, rate_ext;
- unsigned int newsize, new2size;
-
-- /*
-- * If we have selected 44.1kHz, use the DAC clock.
-- */
-- if (0 && rate == 44100) {
-- hwctrl = 0x00000002;
-+ hwctrl = 0x00000003;
-+
-+ /* Using internal clock */
-+ hwrate = (((VIDC_SOUND_CLOCK * 2) / rate) + 1) >> 1;
-+ if (hwrate < 3)
- hwrate = 3;
-- } else {
-- hwctrl = 0x00000003;
-+ if (hwrate > 255)
-+ hwrate = 255;
-
-- hwrate = (((VIDC_SOUND_CLOCK * 2) / rate) + 1) >> 1;
-- if (hwrate < 3)
-- hwrate = 3;
-- if (hwrate > 255)
-- hwrate = 255;
-+ /* Using exernal clock */
-+ hwrate_ext = (((VIDC_SOUND_CLOCK_EXT * 2) / rate) + 1) >> 1;
-+ if (hwrate_ext < 3)
-+ hwrate_ext = 3;
-+ if (hwrate_ext > 255)
-+ hwrate_ext = 255;
-
-- rate = VIDC_SOUND_CLOCK / hwrate;
-+ rate_int = VIDC_SOUND_CLOCK / hwrate;
-+ rate_ext = VIDC_SOUND_CLOCK_EXT / hwrate_ext;
-+
-+ /* Chose between external and internal clock */
-+ if (my_abs(rate_ext-rate) < my_abs(rate_int-rate)) {
-+ /*printk("VIDC: external %d %d %d\n", rate, rate_ext, hwrate_ext);*/
-+ hwrate=hwrate_ext;
-+ hwctrl=0x00000002;
-+ rate=rate_ext;
-+ } else {
-+ /*printk("VIDC: internal %d %d %d\n", rate, rate_int, hwrate);*/
-+ hwctrl=0x00000003;
-+ rate=rate_int;
- }
-
- vidc_writel(0xb0000000 | (hwrate - 2));
-@@ -225,13 +241,14 @@
- if (newsize > 4096)
- newsize = 4096;
- for (new2size = 128; new2size < newsize; new2size <<= 1);
-- if (new2size - newsize > newsize - (new2size >> 1))
-- new2size >>= 1;
-+ if (new2size - newsize > newsize - (new2size >> 1))
-+ new2size >>= 1;
- if (new2size > 4096) {
- printk(KERN_ERR "VIDC: error: dma buffer (%d) %d > 4K\n",
- newsize, new2size);
- new2size = 4096;
- }
-+ /*printk("VIDC: dma size %d\n", new2size);*/
- dma_bufsize = new2size;
- vidc_audio_rate = rate;
- }
---- linux-2.4.25/drivers/sound/waveartist.c~2.4.25-vrs2.patch 2001-10-25 22:53:52.000000000 +0200
-+++ linux-2.4.25/drivers/sound/waveartist.c 2004-03-31 17:15:09.000000000 +0200
-@@ -247,17 +247,15 @@
- printk("\n");
- }
-
-- if (inb(io_base + STATR) & CMD_RF) {
-- int old_data;
--
-- /* flush the port
-- */
-+ /*
-+ * flush any stale command data from the port.
-+ */
-+ while (inb(io_base + STATR) & CMD_RF) {
-+ unsigned int old_data;
-
- old_data = inw(io_base + CMDR);
--
-- if (debug_flg & DEBUG_CMD)
-- printk("flushed %04X...", old_data);
--
-+ printk("waveartist: flushing stale command data: 0x%04x pc=%p\n",
-+ old_data, __builtin_return_address(0));
- udelay(10);
- }
-
-@@ -287,16 +285,19 @@
- resp[i] = inw(io_base + CMDR);
- }
-
-- if (debug_flg & DEBUG_CMD) {
-- if (!timed_out) {
-- printk("waveartist_cmd: resp=");
-+ if (debug_flg & DEBUG_CMD && !timed_out) {
-+ printk("waveartist_cmd: resp=");
-
-- for (i = 0; i < nr_resp; i++)
-- printk("%04X ", resp[i]);
-+ for (i = 0; i < nr_resp; i++)
-+ printk("%04X ", resp[i]);
-+ printk("\n");
-+ }
-
-- printk("\n");
-- } else
-- printk("waveartist_cmd: timed out\n");
-+ if (timed_out) {
-+ printk(KERN_ERR "waveartist_cmd: command timed out:");
-+ for (i = 0; i < nr_cmd; i++)
-+ printk(" %04x", cmd[i]);
-+ printk("\n");
- }
-
- return timed_out ? 1 : 0;
-@@ -495,7 +496,6 @@
- audio_devs[dev]->flags & DMA_AUTOMODE &&
- intrflag &&
- count == devc->xfer_count) {
-- devc->audio_mode |= PCM_ENABLE_INPUT;
- return; /*
- * Auto DMA mode on. No need to react
- */
-@@ -571,9 +571,6 @@
- wavnc_port_info *portc = (wavnc_port_info *) audio_devs[dev]->portc;
- unsigned int speed, bits;
-
-- if (devc->audio_mode)
-- return 0;
--
- speed = waveartist_get_speed(portc);
- bits = waveartist_get_bits(portc);
-
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/ssi/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,11 @@
-+
-+mainmenu_option next_comment
-+comment 'Synchronous Serial Interface'
-+tristate 'Synchronous Serial Interface Support' CONFIG_SSI
-+
-+comment 'SSI Bus Drivers'
-+dep_tristate ' CLPS711X SSI support' CONFIG_SSI_CLPS711X $CONFIG_SSI $CONFIG_ARCH_CLPS711X
-+
-+comment 'SSI Device Drivers'
-+dep_tristate ' JUNO keyboard support' CONFIG_SSI_JUNO $CONFIG_SSI
-+endmenu
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/ssi/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,50 @@
-+#
-+# Makefile for the SSI drivers
-+#
-+# Note! Dependencies are done automagically by 'make dep', which also
-+# removes any old dependencies. DON'T put your own dependencies here
-+# unless it's something special (ie not a .c file).
-+#
-+# Note 2! The CFLAGS definition is now inherited from the
-+# parent makefile.
-+#
-+
-+O_TARGET := ssi.o
-+
-+obj-y :=
-+obj-m :=
-+obj-n :=
-+obj- :=
-+
-+export-objs :=
-+list-multi :=
-+
-+obj-$(CONFIG_SSI) += ssi_core.o
-+obj-$(CONFIG_SSI_CLPS711X) += clps711x_ssi1.o
-+obj-y += juno.o
-+
-+# Extract lists of the multi-part drivers.
-+# The 'int-*' lists are intermediate files used to build the multi's.
-+
-+multi-y := $(filter $(list-multi), $(obj-y))
-+multi-m := $(filter $(list-multi), $(obj-m))
-+int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs)))
-+int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs)))
-+
-+# Files that are both resident and modular; remove from modular.
-+
-+obj-m := $(filter-out $(obj-y), $(obj-m))
-+int-m := $(filter-out $(int-y), $(int-m))
-+
-+# Take multi-part drivers out of obj-y and put components in.
-+
-+obj-y := $(filter-out $(list-multi), $(obj-y)) $(int-y)
-+
-+# Translate to Rules.make lists.
-+
-+O_OBJS := $(filter-out $(export-objs), $(obj-y))
-+OX_OBJS := $(filter $(export-objs), $(obj-y))
-+M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
-+MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
-+
-+include $(TOPDIR)/Rules.make
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/ssi/README 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,86 @@
-+ Synchronous Serial Interface bus driver
-+ ---------------------------------------
-+
-+ EEEEE X X PPPP EEEEE RRRR IIIII M M EEEEE N N TTTTT AAA L
-+ E X X P P E R R I MM MM E NN N T A A L
-+ EEEE X PPPP EEEE RRRR I M M M EEEE N N N T AAAAA L
-+ E X X P E R R I M M E N NN T A A L
-+ EEEEE X X P EEEEE R R IIIII M M EEEEE N N T A A LLLLL
-+
-+This directory holds the SSI bus drivers. Basically, a SSI bus consists
-+of the following signals:
-+
-+ stxd Transmit data
-+ srxd Receive data
-+ sclk Clock
-+ sfrm Frame
-+ Chip selects (1 - n)
-+
-+There may be more than one device on a SSI bus, and each device can
-+have different timing requirements. There are several frame formats:
-+
-+1. Texas Instruments Synchronous Serial Frame format
-+
-+ sclk ____~_~_~_~_~_~_~_~____
-+ sfrm ____~~_________________
-+ stxd ------bn..........b0---
-+ srxd ------bn..........b0---
-+
-+ - data latched in on the falling edge of the clock
-+ - data shifted out on the rising edge of the clock
-+
-+2. Motorola SPI frame format
-+
-+ sclk ______~_~_~_~_~_~_~____
-+ sfrm ~~~~________________~~~
-+ stxd -----bn..........b0----
-+ srxd ----.bn..........b0----
-+
-+ - data latched in on the rising edge of the clock
-+ - data shifted out on the falling edge of the clock, or falling edge
-+ of sfrm
-+
-+3. National Microwire format
-+
-+ sclk ______~_~_~_~_~_~_~_~_~_~_~_~_~_____
-+ sfrm ~~~~_____________________________~~~
-+ stxd -----bn......b0---------------------
-+ srxd -----------------bn..........b0.----
-+
-+ - data latched in on the rising edge of the clock
-+ - data shifted out on the falling edge of the clock
-+ - half duplex, one clock between transmission and reception
-+
-+Types of devices
-+----------------
-+
-+The following types of devices can be found on a SSP bus:
-+
-+ Sound chips
-+ Keyboard devices
-+ Touch screen devices
-+
-+Keyboard
-+--------
-+
-+TX:
-+0. Format: cfglen = 8, framelen = 8, clkpol = 1, clk < 250kHz
-+1. select device
-+2. keyboard responds asserting key_atn
-+3. wait 0.1ms to 5ms
-+4. transmit data byte
-+5. wait >= 150us
-+6. repeat step 4 until all data sent
-+7. deselect device
-+8. keyboard responds de-asserting key_atn
-+9. wait >= 120us
-+
-+RX:
-+0. Format: cfglen = 8, framelen = 8, clkpol = 1, clk < 250kHz
-+1. keyboard asserts key_atn
-+2. select device after 0.1ms < 5ms
-+3. read data byte
-+4. wait 150us
-+5. if key_atn still asserted, goto 3
-+6. deselect device
-+7. wait >= 120us
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/ssi/clps711x_ssi1.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,237 @@
-+/*
-+ * linux/drivers/ssi/clps711x_ssi1.c
-+ *
-+ * SSI bus driver for the CLPS711x SSI1 bus. We support EP7212
-+ * extensions as well.
-+ *
-+ * Frame sizes can be between 4 and 24 bits.
-+ * Config sizes can be between 4 and 16 bits.
-+ */
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/delay.h>
-+
-+#include <asm/mach-types.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+
-+#include <asm/hardware/ep7212.h>
-+
-+#include "ssi_bus.h"
-+#include "ssi_dev.h"
-+
-+#define EP7212
-+
-+/*
-+ * Port E on the P720T is used for the SPI bus chip selects
-+ * 0 - Keyboard
-+ * 1 - Touch screen
-+ * 2 - CS4224 ADC/DAC
-+ * 7 - idle
-+ */
-+
-+#if 0
-+/*
-+ * we place in the transmit buffer:
-+ * <control>
-+ * received data (binary):
-+ * 0xxxxxxxxxxxx000
-+ * where 'x' is the value
-+ */
-+struct ssi_dev ads7846_dev = {
-+ name: "ADS7846",
-+ id: 1,
-+ proto: SSI_SPI,
-+ cfglen: 8,
-+ framelen: 24,
-+ clkpol: 0,
-+ clkfreq: 2500000,
-+};
-+
-+/*
-+ * we place in the transmit buffer:
-+ * write: <20> <map> <data>...
-+ * received data discarded
-+ */
-+struct ssi_dev cs4224_dev = {
-+ name: "CS4224",
-+ id: 2,
-+ proto: SSI_SPI,
-+ cfglen: 8,
-+ framelen: 8,
-+ clkpol: 0,
-+ clkfreq: 6000000,
-+};
-+#endif
-+
-+/*
-+ * Supplement with whatever method your board requires
-+ */
-+static void ssi1_select_id(int id)
-+{
-+ if (machine_is_p720t()) {
-+ clps_writel(7, PEDDR);
-+ clps_writel(id, PEDR);
-+ }
-+}
-+
-+/*
-+ * Select the specified device. The upper layers will have already
-+ * checked that the bus transmit queue is idle. We need to make sure
-+ * that the interface itself is idle.
-+ */
-+static int ssi1_select(struct ssi_bus *bus, struct ssi_dev *dev)
-+{
-+ u_int id = dev ? dev->id : 7;
-+ u_int val;
-+
-+ /*
-+ * Make sure that the interface is idle
-+ */
-+ do {
-+ val = clps_readl(SYSFLG1);
-+ } while (val & SYSFLG1_SSIBUSY);
-+
-+ ssi1_select_id(7);
-+
-+ if (dev) {
-+ /*
-+ * Select clock frequency. This is very rough,
-+ * and assumes that we're operating in PLL mode.
-+ */
-+ val = clps_readl(SYSCON1) & ~SYSCON1_ADCKSEL_MASK;
-+// if (dev->clkfreq <= 16000) /* <16kHz */
-+// val |= SYSCON1_ADCKSEL(0);
-+// else if (dev->clkfreq < 64000) /* <64kHz */
-+// val |= SYSCON1_ADCKSEL(1);
-+// else if (dev->clkfreq < 128000) /* <128kHz */
-+ val |= SYSCON1_ADCKSEL(2);
-+// else /* >= 128kHz */
-+// val |= SYSCON1_ADCKSEL(3);
-+ clps_writel(val, SYSCON1);
-+
-+ bus->cfglen = dev->cfglen;
-+ bus->framelen = dev->framelen;
-+ bus->clkpol = dev->clkpol;
-+ bus->proto = dev->proto;
-+
-+#ifdef EP7212
-+ /*
-+ * Set the clock edge according to the device.
-+ * (set clkpol if the device reads data on the
-+ * falling edge of the clock signal).
-+ */
-+ val = ep_readl(SYSCON3) & ~SYSCON3_ADCCKNSEN;
-+ if (bus->clkpol && dev->proto != SSI_USAR)
-+ val |= SYSCON3_ADCCKNSEN;
-+ ep_writel(val, SYSCON3);
-+#endif
-+
-+ /*
-+ * Select the device
-+ */
-+ ssi1_select_id(id);
-+
-+#ifdef EP7212
-+ /*
-+ * If we are doing USAR, wait 30us, then set
-+ * the clock line low.
-+ */
-+ if (dev->proto == SSI_USAR) {
-+ udelay(150);
-+
-+ val |= SYSCON3_ADCCKNSEN;
-+ ep_writel(val, SYSCON3);
-+ }
-+#endif
-+ }
-+
-+ return 0;
-+}
-+
-+static void ssi1_int(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct ssi_bus *bus = (struct ssi_bus *)dev_id;
-+
-+ /*
-+ * Read the data word and queue it.
-+ */
-+ ssi_core_rcv(bus, clps_readl(SYNCIO));
-+}
-+
-+/*
-+ * Enable transmission and/or of some bytes
-+ */
-+static int ssi1_trans(struct ssi_bus *bus, u_int data)
-+{
-+ u_int syncio;
-+
-+#ifdef EP7212
-+ data <<= 32 - bus->cfglen;
-+ syncio = bus->cfglen | bus->framelen << 7 | data;
-+#else
-+ syncio = data | bus->framelen << 8;
-+#endif
-+
-+ clps_writel(syncio, SYNCIO);
-+ clps_writel(syncio | SYNCIO_TXFRMEN, SYNCIO);
-+ return 0;
-+}
-+
-+/*
-+ * Initialise the SSI bus.
-+ */
-+static int ssi1_bus_init(struct ssi_bus *bus)
-+{
-+ int retval, val;
-+
-+ retval = request_irq(IRQ_SSEOTI, ssi1_int, 0, "ssi1", bus);
-+ if (retval)
-+ return retval;
-+
-+#ifdef EP7212
-+ /*
-+ * EP7212 only! Set the configuration command length.
-+ * On the CLPS711x chips, it is fixed at 8 bits.
-+ */
-+ val = ep_readl(SYSCON3);
-+ val |= SYSCON3_ADCCON;
-+ ep_writel(val, SYSCON3);
-+#endif
-+
-+ ssi1_select(bus, NULL);
-+
-+ PLD_SPI |= PLD_SPI_EN;
-+
-+ return 0;
-+}
-+
-+static void ssi1_bus_exit(struct ssi_bus *bus)
-+{
-+ ssi1_select(bus, NULL);
-+
-+ PLD_SPI &= ~PLD_SPI_EN;
-+
-+ free_irq(IRQ_SSEOTI, bus);
-+}
-+
-+struct ssi_bus clps711x_ssi1_bus = {
-+ name: "clps711x_ssi1",
-+ init: ssi1_bus_init,
-+ exit: ssi1_bus_exit,
-+ select: ssi1_select,
-+ trans: ssi1_trans,
-+};
-+
-+static int __init clps711x_ssi1_init(void)
-+{
-+ return ssi_register_bus(&clps711x_ssi1_bus);
-+}
-+
-+static void __exit clps711x_ssi1_exit(void)
-+{
-+ ssi_unregister_bus(&clps711x_ssi1_bus);
-+}
-+
-+module_init(clps711x_ssi1_init);
-+module_exit(clps711x_ssi1_exit);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/ssi/juno.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,131 @@
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/delay.h>
-+
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+
-+#include <asm/arch/syspld.h>
-+
-+#include "ssi_bus.h"
-+#include "ssi_dev.h"
-+
-+extern struct ssi_bus clps711x_ssi1_bus;
-+
-+static u_int recvbuf[16];
-+static volatile u_int ptr, rxed;
-+
-+static inline void juno_enable_irq(void)
-+{
-+ enable_irq(IRQ_EINT1);
-+}
-+
-+static inline void juno_disable_irq(void)
-+{
-+ disable_irq(IRQ_EINT1);
-+}
-+
-+static void juno_rcv(struct ssi_dev *dev, u_int data)
-+{
-+ if (ptr < 16) {
-+ recvbuf[ptr] = data;
-+ ptr++;
-+ } else
-+ printk("juno_rcv: %04x\n", data);
-+ rxed = 1;
-+}
-+
-+static void juno_irq(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ struct ssi_dev *dev = dev_id;
-+
-+ printk("juno_irq\n");
-+
-+ ssi_select_device(dev->bus, dev);
-+
-+ ptr = 0;
-+ do {
-+ rxed = 0;
-+ ssi_transmit_data(dev, 0xff);
-+ while (rxed == 0);
-+ udelay(150);
-+ } while (PLD_INT & PLD_INT_KBD_ATN);
-+
-+ ssi_select_device(dev->bus, NULL);
-+
-+ { int i;
-+ printk("juno_rcv: ");
-+ for (i = 0; i < ptr; i++)
-+ printk("%04x ", recvbuf[i]);
-+ printk("\n");
-+ }
-+}
-+
-+static void juno_command(struct ssi_dev *dev, int cmd, int data)
-+{
-+ ssi_transmit_data(dev, cmd);
-+ mdelay(1);
-+ ssi_transmit_data(dev, data);
-+ mdelay(1);
-+ ssi_transmit_data(dev, 0xa0 ^ 0xc0);
-+ mdelay(1);
-+}
-+
-+static int juno_dev_init(struct ssi_dev *dev)
-+{
-+ int retval;
-+
-+ PLD_KBD |= PLD_KBD_EN;
-+ ptr = 16;
-+
-+ mdelay(20);
-+
-+ retval = request_irq(IRQ_EINT1, juno_irq, 0, dev->name, dev);
-+ if (retval)
-+ return retval;
-+
-+ juno_disable_irq();
-+
-+ if (ssi_select_device(dev->bus, dev) != 0) {
-+ printk("juno: ssi_select_dev failed\n");
-+ return -EBUSY;
-+ }
-+
-+ mdelay(1);
-+
-+ juno_command(dev, 0x80, 0x20);
-+
-+ ssi_select_device(dev->bus, NULL);
-+
-+ juno_enable_irq();
-+
-+ return 0;
-+}
-+
-+static struct ssi_dev juno_dev = {
-+ name: "Juno",
-+ id: 0,
-+ proto: SSI_USAR,
-+ cfglen: 8,
-+ framelen: 8,
-+ clkpol: 1,
-+ clkfreq: 250000,
-+ rcv: juno_rcv,
-+ init: juno_dev_init,
-+};
-+
-+static int __init juno_init(void)
-+{
-+ return ssi_register_device(&clps711x_ssi1_bus, &juno_dev);
-+}
-+
-+static void __exit juno_exit(void)
-+{
-+ ssi_unregister_device(&juno_dev);
-+}
-+
-+module_init(juno_init);
-+module_exit(juno_exit);
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/ssi/ssi_bus.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,21 @@
-+#include <linux/circ_buf.h>
-+
-+struct ssi_dev;
-+
-+struct ssi_bus {
-+ u_char cfglen;
-+ u_char framelen;
-+ u_char clkpol;
-+ u_char proto;
-+ struct ssi_dev *dev; /* current device */
-+ int (*select)(struct ssi_bus *, struct ssi_dev *);
-+ int (*trans)(struct ssi_bus *, u_int data);
-+ int (*init)(struct ssi_bus *);
-+ void (*exit)(struct ssi_bus *);
-+ char *name;
-+ u_int devices;
-+};
-+
-+extern int ssi_core_rcv(struct ssi_bus *bus, u_int data);
-+extern int ssi_register_bus(struct ssi_bus *bus);
-+extern int ssi_unregister_bus(struct ssi_bus *bus);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/ssi/ssi_core.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,175 @@
-+/*
-+ * linux/drivers/ssi/ssi_core.c
-+ *
-+ * This file provides a common framework to allow multiple SSI devices
-+ * to work together on a single SSI bus.
-+ *
-+ * You can use this in two ways:
-+ * 1. select the device, queue up data, flush the data to the device,
-+ * (optionally) purge the received data, deselect the device.
-+ * 2. select the device, queue up one data word, flush to the device
-+ * read data word, queue up next data word, flush to the device...
-+ * deselect the device.
-+ */
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/malloc.h>
-+#include <linux/init.h>
-+
-+#include <asm/errno.h>
-+
-+#include "ssi_bus.h"
-+#include "ssi_dev.h"
-+
-+#define DEBUG
-+
-+/**
-+ * ssi_core_rcv - pass received SSI data to the device
-+ * @bus: the bus that the data was received from
-+ * @data: the data word that was received
-+ *
-+ * This function is intended to be called by SSI bus device
-+ * drivers to pass received data to the device driver.
-+ */
-+int ssi_core_rcv(struct ssi_bus *bus, u_int data)
-+{
-+ struct ssi_dev *dev = bus->dev;
-+
-+ if (dev && dev->rcv)
-+ dev->rcv(dev, data);
-+
-+ return 0;
-+}
-+
-+/**
-+ * ssi_transmit_data - queue SSI data for later transmission
-+ * @dev: device requesting data to be transmitted
-+ * @data: data word to be transmitted.
-+ *
-+ * Queue one data word of SSI data for later transmission.
-+ */
-+int ssi_transmit_data(struct ssi_dev *dev, u_int data)
-+{
-+ struct ssi_bus *bus = dev->bus;
-+
-+ /*
-+ * Make sure that we currently own the bus
-+ */
-+ if (bus->dev != dev)
-+ BUG();
-+
-+ bus->trans(bus, data);
-+ return 0;
-+}
-+
-+/**
-+ * ssi_select_device - select a SSI device for later transactions
-+ * @dev: device to be selected
-+ */
-+int ssi_select_device(struct ssi_bus *bus, struct ssi_dev *dev)
-+{
-+ int retval;
-+
-+#ifdef DEBUG
-+ printk("SSI: selecting device %s on bus %s\n",
-+ dev ? dev->name : "<none>", bus->name);
-+#endif
-+
-+ /*
-+ * Select the device if it wasn't already selected.
-+ */
-+ retval = 0;
-+ if (bus->dev != dev) {
-+ retval = bus->select(bus, dev);
-+ bus->dev = dev;
-+ }
-+
-+ return retval;
-+}
-+
-+/**
-+ * ssi_register_device - register a SSI device with a SSI bus
-+ * @bus: bus
-+ * @dev: SSI device
-+ */
-+int ssi_register_device(struct ssi_bus *bus, struct ssi_dev *dev)
-+{
-+ int retval;
-+
-+ dev->bus = bus;
-+ bus->devices++;
-+ retval = dev->init(dev);
-+ if (retval != 0) {
-+ dev->bus = NULL;
-+ bus->devices--;
-+ } else {
-+#ifdef DEBUG
-+ printk("SSI: registered new device %s on bus %s\n", dev->name, bus->name);
-+#endif
-+ }
-+ return retval;
-+}
-+
-+/**
-+ * ssi_unregister_device - unregister a SSI device from a SSI bus
-+ * @dev: SSI device
-+ */
-+int ssi_unregister_device(struct ssi_dev *dev)
-+{
-+ struct ssi_bus *bus = dev->bus;
-+
-+ if (bus->dev == dev)
-+ bus->dev = NULL;
-+
-+ dev->bus = NULL;
-+ bus->devices--;
-+#ifdef DEBUG
-+ printk("SSI: unregistered device %s on bus %s\n", dev->name, bus->name);
-+#endif
-+ return 0;
-+}
-+
-+/**
-+ * ssi_register_bus - register a SSI bus driver
-+ * @bus: bus
-+ */
-+int ssi_register_bus(struct ssi_bus *bus)
-+{
-+ int retval;
-+
-+ retval = bus->init(bus);
-+ if (retval == 0) {
-+ bus->devices = 0;
-+#ifdef DEBUG
-+ printk("SSI: registered new bus %s\n", bus->name);
-+#endif
-+ }
-+
-+ return retval;
-+}
-+
-+/**
-+ * ssi_unregister_bus - unregister a SSI bus driver
-+ * @bus: bus
-+ */
-+int ssi_unregister_bus(struct ssi_bus *bus)
-+{
-+ int retval = -EBUSY;
-+ if (bus->devices == 0) {
-+ retval = 0;
-+ }
-+ return retval;
-+}
-+
-+static int __init ssi_init(void)
-+{
-+ return 0;
-+}
-+
-+static void __exit ssi_exit(void)
-+{
-+}
-+
-+module_init(ssi_init);
-+module_exit(ssi_exit);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/ssi/ssi_dev.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,21 @@
-+struct ssi_bus;
-+
-+#define SSI_SPI 1
-+#define SSI_MICROWIRE 2
-+#define SSI_TISSF 3
-+#define SSI_USAR 4
-+
-+struct ssi_dev {
-+ char *name;
-+ u_int id;
-+ u_int clkfreq;
-+ u_char cfglen;
-+ u_char framelen;
-+ u_char clkpol;
-+ u_char proto;
-+ void (*rcv)(struct ssi_dev *, u_int);
-+ int (*init)(struct ssi_dev *);
-+ struct ssi_bus *bus;
-+};
-+
-+
---- linux-2.4.25/drivers/usb/Config.in~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/usb/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -4,7 +4,13 @@
- mainmenu_option next_comment
- comment 'USB support'
-
--dep_tristate 'Support for USB' CONFIG_USB $CONFIG_PCI
-+# ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
-+if [ "$CONFIG_PCI" = "y" -o "$CONFIG_SA1111" = "y" -o "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
-+ tristate 'Support for USB' CONFIG_USB
-+else
-+ define_bool CONFIG_USB n
-+fi
-+
- if [ "$CONFIG_USB" = "y" -o "$CONFIG_USB" = "m" ]; then
- bool ' USB verbose debug messages' CONFIG_USB_DEBUG
-
---- linux-2.4.25/drivers/usb/Makefile~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/usb/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -74,6 +74,14 @@
-
- subdir-$(CONFIG_USB_OHCI) += host
- ifeq ($(CONFIG_USB_OHCI),y)
-+ obj-y += host/usb-ohci.o host/usb-ohci-pci.o
-+endif
-+subdir-$(CONFIG_USB_OHCI_SA1111)+= host
-+ifeq ($(CONFIG_USB_OHCI),y)
-+ obj-y += host/usb-ohci.o host/usb-ohci-sa1111.o
-+endif
-+subdir-$(CONFIG_USB_OHCI_AT91) += host
-+ifeq ($(CONFIG_USB_OHCI_AT91),y)
- obj-y += host/usb-ohci.o
- endif
-
-@@ -85,8 +93,6 @@
- obj-$(CONFIG_USB_KBD) += usbkbd.o
- obj-$(CONFIG_USB_AIPTEK) += aiptek.o
- obj-$(CONFIG_USB_WACOM) += wacom.o
--obj-$(CONFIG_USB_KBTAB) += kbtab.o
--obj-$(CONFIG_USB_POWERMATE) += powermate.o
-
- obj-$(CONFIG_USB_SCANNER) += scanner.o
- obj-$(CONFIG_USB_ACM) += acm.o
---- linux-2.4.25/drivers/usb/hcd.c~2.4.25-vrs2.patch 2003-06-13 16:51:36.000000000 +0200
-+++ linux-2.4.25/drivers/usb/hcd.c 2004-03-31 17:15:09.000000000 +0200
-@@ -96,7 +96,7 @@
- /* used when updating hcd data */
- static spinlock_t hcd_data_lock = SPIN_LOCK_UNLOCKED;
-
--static struct usb_operations hcd_operations;
-+/*static*/ struct usb_operations hcd_operations;
-
- /*-------------------------------------------------------------------------*/
-
-@@ -1203,13 +1203,21 @@
- // NOTE: 2.5 does this if !URB_NO_DMA_MAP transfer flag
- if (usb_pipecontrol (urb->pipe))
- urb->setup_dma = pci_map_single (
-+#ifdef CONFIG_PCI
- hcd->pdev,
-+#else
-+ NULL,
-+#endif
- urb->setup_packet,
- sizeof (struct usb_ctrlrequest),
- PCI_DMA_TODEVICE);
- if (urb->transfer_buffer_length != 0)
- urb->transfer_dma = pci_map_single (
-+#ifdef CONFIG_PCI
- hcd->pdev,
-+#else
-+ NULL,
-+#endif
- urb->transfer_buffer,
- urb->transfer_buffer_length,
- usb_pipein (urb->pipe)
-@@ -1422,7 +1430,7 @@
- return 0;
- }
-
--static struct usb_operations hcd_operations = {
-+/*static*/ struct usb_operations hcd_operations = {
- allocate: hcd_alloc_dev,
- get_frame_number: hcd_get_frame_number,
- submit_urb: hcd_submit_urb,
-@@ -1432,7 +1440,7 @@
-
- /*-------------------------------------------------------------------------*/
-
--static void hcd_irq (int irq, void *__hcd, struct pt_regs * r)
-+/*static*/ void hcd_irq (int irq, void *__hcd, struct pt_regs * r)
- {
- struct usb_hcd *hcd = __hcd;
- int start = hcd->state;
-@@ -1481,11 +1489,23 @@
-
- // NOTE: 2.5 does this if !URB_NO_DMA_MAP transfer flag
- if (usb_pipecontrol (urb->pipe))
-- pci_unmap_single (hcd->pdev, urb->setup_dma,
-+ pci_unmap_single (
-+#ifdef CONFIG_PCI
-+ hcd->pdev,
-+#else
-+ NULL,
-+#endif
-+ urb->setup_dma,
- sizeof (struct usb_ctrlrequest),
- PCI_DMA_TODEVICE);
- if (urb->transfer_buffer_length != 0)
-- pci_unmap_single (hcd->pdev, urb->transfer_dma,
-+ pci_unmap_single (
-+#ifdef CONFIG_PCI
-+ hcd->pdev,
-+#else
-+ NULL,
-+#endif
-+ urb->transfer_dma,
- urb->transfer_buffer_length,
- usb_pipein (urb->pipe)
- ? PCI_DMA_FROMDEVICE
---- linux-2.4.25/drivers/usb/host/Config.in~2.4.25-vrs2.patch 2003-11-28 19:26:20.000000000 +0100
-+++ linux-2.4.25/drivers/usb/host/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -12,8 +12,13 @@
- define_bool CONFIG_USB_UHCI_ALT n
- fi
- dep_tristate ' OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI $CONFIG_USB
-+dep_tristate ' SA1111 OHCI-compatible host interface support' CONFIG_USB_OHCI_SA1111 $CONFIG_USB
- if [ "$CONFIG_ARM" = "y" -o "$CONFIG_X86" = "y" -a "$CONFIG_X86_64" != "y" ]; then
- # Cypress embedded USB controller on StrongARM or on x86 in PC/104
- dep_tristate ' SL811HS Alternate (x86, StrongARM, isosynchronous mode)' CONFIG_USB_SL811HS_ALT $CONFIG_USB $CONFIG_EXPERIMENTAL
- dep_tristate ' SL811HS (x86, StrongARM) support, old driver' CONFIG_USB_SL811HS $CONFIG_USB $CONFIG_EXPERIMENTAL
- fi
-+if [ "$CONFIG_ARCH_AT91RM9200" = "y" ]; then
-+ dep_tristate ' AT91RM9200 OHCI-compatible host interface support' CONFIG_USB_OHCI_AT91 $CONFIG_USB
-+fi
-+
---- linux-2.4.25/drivers/usb/host/Makefile~2.4.25-vrs2.patch 2003-11-28 19:26:20.000000000 +0100
-+++ linux-2.4.25/drivers/usb/host/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -8,9 +8,11 @@
- obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o
- obj-$(CONFIG_USB_UHCI_ALT) += uhci.o
- obj-$(CONFIG_USB_UHCI) += usb-uhci.o
--obj-$(CONFIG_USB_OHCI) += usb-ohci.o
-+obj-$(CONFIG_USB_OHCI) += usb-ohci.o usb-ohci-pci.o
- obj-$(CONFIG_USB_SL811HS_ALT) += sl811.o
- obj-$(CONFIG_USB_SL811HS) += hc_sl811.o
-+obj-$(CONFIG_USB_OHCI_SA1111) += usb-ohci.o usb-ohci-sa1111.o
-+obj-$(CONFIG_USB_OHCI_AT91) += usb-ohci.o
-
- # Extract lists of the multi-part drivers.
- # The 'int-*' lists are the intermediate files used to build the multi's.
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/usb/host/usb-ohci-pci.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,436 @@
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/pci.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/delay.h>
-+#include <linux/interrupt.h> /* for in_interrupt() */
-+#undef DEBUG
-+#include <linux/usb.h>
-+
-+#include "usb-ohci.h"
-+
-+#ifdef CONFIG_PMAC_PBOOK
-+#include <asm/machdep.h>
-+#include <asm/pmac_feature.h>
-+#include <asm/pci-bridge.h>
-+#ifndef CONFIG_PM
-+#define CONFIG_PM
-+#endif
-+#endif
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* Increment the module usage count, start the control thread and
-+ * return success. */
-+
-+static struct pci_driver ohci_pci_driver;
-+extern spinlock_t usb_ed_lock;
-+int __devinit
-+hc_add_ohci(struct pci_dev *dev, int irq, void *membase, unsigned long flags,
-+ const char *name, const char *slot_name);
-+extern void hc_remove_ohci(ohci_t *ohci);
-+
-+static int __devinit
-+hc_found_ohci (struct pci_dev *dev, int irq,
-+ void *mem_base, const struct pci_device_id *id)
-+{
-+ unsigned long flags = id->driver_data;
-+
-+ printk(KERN_INFO __FILE__ ": usb-%s, %s\n", dev->slot_name, dev->name);
-+
-+ /* Check for NSC87560. We have to look at the bridge (fn1) to identify
-+ the USB (fn2). This quirk might apply to more or even all NSC stuff
-+ I don't know.. */
-+
-+ if(dev->vendor == PCI_VENDOR_ID_NS)
-+ {
-+ struct pci_dev *fn1 = pci_find_slot(dev->bus->number, PCI_DEVFN(PCI_SLOT(dev->devfn), 1));
-+ if(fn1 && fn1->vendor == PCI_VENDOR_ID_NS && fn1->device == PCI_DEVICE_ID_NS_87560_LIO)
-+ flags |= OHCI_QUIRK_SUCKYIO;
-+
-+ }
-+
-+ if (flags & OHCI_QUIRK_SUCKYIO)
-+ printk (KERN_INFO __FILE__ ": Using NSC SuperIO setup\n");
-+ if (flags & OHCI_QUIRK_AMD756)
-+ printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n");
-+
-+ return hc_add_ohci(dev, irq, mem_base, flags,
-+ ohci_pci_driver.name, dev->slot_name);
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+#ifdef CONFIG_PM
-+
-+/* controller died; cleanup debris, then restart */
-+/* must not be called from interrupt context */
-+
-+static void hc_restart (ohci_t *ohci)
-+{
-+ int temp;
-+ int i;
-+
-+ if (ohci->pci_latency)
-+ pci_write_config_byte (ohci->ohci_dev, PCI_LATENCY_TIMER, ohci->pci_latency);
-+
-+ ohci->disabled = 1;
-+ ohci->sleeping = 0;
-+ if (ohci->bus->root_hub)
-+ usb_disconnect (&ohci->bus->root_hub);
-+
-+ /* empty the interrupt branches */
-+ for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0;
-+ for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table[i] = 0;
-+
-+ /* no EDs to remove */
-+ ohci->ed_rm_list [0] = NULL;
-+ ohci->ed_rm_list [1] = NULL;
-+
-+ /* empty control and bulk lists */
-+ ohci->ed_isotail = NULL;
-+ ohci->ed_controltail = NULL;
-+ ohci->ed_bulktail = NULL;
-+
-+ if ((temp = hc_reset (ohci)) < 0 || (temp = hc_start (ohci)) < 0) {
-+ err ("can't restart usb-%s, %d", ohci->ohci_dev->slot_name, temp);
-+ } else
-+ dbg ("restart usb-%s completed", ohci->ohci_dev->slot_name);
-+}
-+
-+#endif /* CONFIG_PM */
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* configured so that an OHCI device is always provided */
-+/* always called with process context; sleeping is OK */
-+
-+static int __devinit
-+ohci_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
-+{
-+ unsigned long mem_resource, mem_len;
-+ void *mem_base;
-+ int status;
-+
-+ if (pci_enable_device(dev) < 0)
-+ return -ENODEV;
-+
-+ if (!dev->irq) {
-+ err("found OHCI device with no IRQ assigned. check BIOS settings!");
-+ pci_disable_device (dev);
-+ return -ENODEV;
-+ }
-+
-+ /* we read its hardware registers as memory */
-+ mem_resource = pci_resource_start(dev, 0);
-+ mem_len = pci_resource_len(dev, 0);
-+ if (!request_mem_region (mem_resource, mem_len, ohci_pci_driver.name)) {
-+ dbg ("controller already in use");
-+ pci_disable_device (dev);
-+ return -EBUSY;
-+ }
-+
-+ mem_base = ioremap_nocache (mem_resource, mem_len);
-+ if (!mem_base) {
-+ err("Error mapping OHCI memory");
-+ release_mem_region (mem_resource, mem_len);
-+ pci_disable_device (dev);
-+ return -EFAULT;
-+ }
-+
-+ /* controller writes into our memory */
-+ pci_set_master (dev);
-+
-+ status = hc_found_ohci (dev, dev->irq, mem_base, id);
-+ if (status < 0) {
-+ iounmap (mem_base);
-+ release_mem_region (mem_resource, mem_len);
-+ pci_disable_device (dev);
-+ }
-+ return status;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+/* may be called from interrupt context [interface spec] */
-+/* may be called without controller present */
-+/* may be called with controller, bus, and devices active */
-+
-+static void __devexit
-+ohci_pci_remove (struct pci_dev *dev)
-+{
-+ ohci_t *ohci = (ohci_t *) pci_get_drvdata(dev);
-+
-+ dbg ("remove %s controller usb-%s%s%s",
-+ hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
-+ dev->slot_name,
-+ ohci->disabled ? " (disabled)" : "",
-+ in_interrupt () ? " in interrupt" : ""
-+ );
-+
-+ hc_remove_ohci(ohci);
-+
-+ release_mem_region (pci_resource_start (dev, 0), pci_resource_len (dev, 0));
-+ pci_disable_device (dev);
-+}
-+
-+
-+#ifdef CONFIG_PM
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int
-+ohci_pci_suspend (struct pci_dev *dev, u32 state)
-+{
-+ ohci_t *ohci = (ohci_t *) pci_get_drvdata(dev);
-+ unsigned long flags;
-+ u16 cmd;
-+
-+ if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) {
-+ dbg ("can't suspend usb-%s (state is %s)", dev->slot_name,
-+ hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS));
-+ return -EIO;
-+ }
-+
-+ /* act as if usb suspend can always be used */
-+ info ("USB suspend: usb-%s", dev->slot_name);
-+ ohci->sleeping = 1;
-+
-+ /* First stop processing */
-+ spin_lock_irqsave (&usb_ed_lock, flags);
-+ ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE);
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
-+ (void) readl (&ohci->regs->intrstatus);
-+ spin_unlock_irqrestore (&usb_ed_lock, flags);
-+
-+ /* Wait a frame or two */
-+ mdelay(1);
-+ if (!readl (&ohci->regs->intrstatus) & OHCI_INTR_SF)
-+ mdelay (1);
-+
-+#ifdef CONFIG_PMAC_PBOOK
-+ if (_machine == _MACH_Pmac)
-+ disable_irq (ohci->irq);
-+ /* else, 2.4 assumes shared irqs -- don't disable */
-+#endif
-+ /* Enable remote wakeup */
-+ writel (readl(&ohci->regs->intrenable) | OHCI_INTR_RD, &ohci->regs->intrenable);
-+
-+ /* Suspend chip and let things settle down a bit */
-+ ohci->hc_control = OHCI_USB_SUSPEND;
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ (void) readl (&ohci->regs->control);
-+ mdelay (500); /* No schedule here ! */
-+ switch (readl (&ohci->regs->control) & OHCI_CTRL_HCFS) {
-+ case OHCI_USB_RESET:
-+ dbg("Bus in reset phase ???");
-+ break;
-+ case OHCI_USB_RESUME:
-+ dbg("Bus in resume phase ???");
-+ break;
-+ case OHCI_USB_OPER:
-+ dbg("Bus in operational phase ???");
-+ break;
-+ case OHCI_USB_SUSPEND:
-+ dbg("Bus suspended");
-+ break;
-+ }
-+ /* In some rare situations, Apple's OHCI have happily trashed
-+ * memory during sleep. We disable it's bus master bit during
-+ * suspend
-+ */
-+ pci_read_config_word (dev, PCI_COMMAND, &cmd);
-+ cmd &= ~PCI_COMMAND_MASTER;
-+ pci_write_config_word (dev, PCI_COMMAND, cmd);
-+#ifdef CONFIG_PMAC_PBOOK
-+ {
-+ struct device_node *of_node;
-+
-+ /* Disable USB PAD & cell clock */
-+ of_node = pci_device_to_OF_node (ohci->ohci_dev);
-+ if (of_node)
-+ pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
-+ }
-+#endif
-+ return 0;
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int
-+ohci_pci_resume (struct pci_dev *dev)
-+{
-+ ohci_t *ohci = (ohci_t *) pci_get_drvdata(dev);
-+ int temp;
-+ unsigned long flags;
-+
-+ /* guard against multiple resumes */
-+ atomic_inc (&ohci->resume_count);
-+ if (atomic_read (&ohci->resume_count) != 1) {
-+ err ("concurrent PCI resumes for usb-%s", dev->slot_name);
-+ atomic_dec (&ohci->resume_count);
-+ return 0;
-+ }
-+
-+#ifdef CONFIG_PMAC_PBOOK
-+ {
-+ struct device_node *of_node;
-+
-+ /* Re-enable USB PAD & cell clock */
-+ of_node = pci_device_to_OF_node (ohci->ohci_dev);
-+ if (of_node)
-+ pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 1);
-+ }
-+#endif
-+
-+ /* did we suspend, or were we powered off? */
-+ ohci->hc_control = readl (&ohci->regs->control);
-+ temp = ohci->hc_control & OHCI_CTRL_HCFS;
-+
-+#ifdef DEBUG
-+ /* the registers may look crazy here */
-+ ohci_dump_status (ohci);
-+#endif
-+
-+ /* Re-enable bus mastering */
-+ pci_set_master(ohci->ohci_dev);
-+
-+ switch (temp) {
-+
-+ case OHCI_USB_RESET: // lost power
-+ info ("USB restart: usb-%s", dev->slot_name);
-+ hc_restart (ohci);
-+ break;
-+
-+ case OHCI_USB_SUSPEND: // host wakeup
-+ case OHCI_USB_RESUME: // remote wakeup
-+ info ("USB continue: usb-%s from %s wakeup", dev->slot_name,
-+ (temp == OHCI_USB_SUSPEND)
-+ ? "host" : "remote");
-+ ohci->hc_control = OHCI_USB_RESUME;
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ (void) readl (&ohci->regs->control);
-+ mdelay (20); /* no schedule here ! */
-+ /* Some controllers (lucent) need a longer delay here */
-+ mdelay (15);
-+ temp = readl (&ohci->regs->control);
-+ temp = ohci->hc_control & OHCI_CTRL_HCFS;
-+ if (temp != OHCI_USB_RESUME) {
-+ err ("controller usb-%s won't resume", dev->slot_name);
-+ ohci->disabled = 1;
-+ return -EIO;
-+ }
-+
-+ /* Some chips likes being resumed first */
-+ writel (OHCI_USB_OPER, &ohci->regs->control);
-+ (void) readl (&ohci->regs->control);
-+ mdelay (3);
-+
-+ /* Then re-enable operations */
-+ spin_lock_irqsave (&usb_ed_lock, flags);
-+ ohci->disabled = 0;
-+ ohci->sleeping = 0;
-+ ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
-+ if (!ohci->ed_rm_list[0] && !ohci->ed_rm_list[1]) {
-+ if (ohci->ed_controltail)
-+ ohci->hc_control |= OHCI_CTRL_CLE;
-+ if (ohci->ed_bulktail)
-+ ohci->hc_control |= OHCI_CTRL_BLE;
-+ }
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
-+ writel (OHCI_INTR_SF, &ohci->regs->intrenable);
-+ /* Check for a pending done list */
-+ writel (OHCI_INTR_WDH, &ohci->regs->intrdisable);
-+ (void) readl (&ohci->regs->intrdisable);
-+ spin_unlock_irqrestore (&usb_ed_lock, flags);
-+#ifdef CONFIG_PMAC_PBOOK
-+ if (_machine == _MACH_Pmac)
-+ enable_irq (ohci->irq);
-+#endif
-+ if (ohci->hcca->done_head)
-+ dl_done_list (ohci, dl_reverse_done_list (ohci));
-+ writel (OHCI_INTR_WDH, &ohci->regs->intrenable);
-+ writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
-+ writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
-+ break;
-+
-+ default:
-+ warn ("odd PCI resume for usb-%s", dev->slot_name);
-+ }
-+
-+ /* controller is operational, extra resumes are harmless */
-+ atomic_dec (&ohci->resume_count);
-+
-+ return 0;
-+}
-+
-+#endif /* CONFIG_PM */
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static const struct pci_device_id __devinitdata ohci_pci_ids [] = { {
-+
-+ /*
-+ * AMD-756 [Viper] USB has a serious erratum when used with
-+ * lowspeed devices like mice.
-+ */
-+ vendor: 0x1022,
-+ device: 0x740c,
-+ subvendor: PCI_ANY_ID,
-+ subdevice: PCI_ANY_ID,
-+
-+ driver_data: OHCI_QUIRK_AMD756,
-+
-+} , {
-+
-+ /* handle any USB OHCI controller */
-+ class: ((PCI_CLASS_SERIAL_USB << 8) | 0x10),
-+ class_mask: ~0,
-+
-+ /* no matter who makes it */
-+ vendor: PCI_ANY_ID,
-+ device: PCI_ANY_ID,
-+ subvendor: PCI_ANY_ID,
-+ subdevice: PCI_ANY_ID,
-+
-+ }, { /* end: all zeroes */ }
-+};
-+
-+MODULE_DEVICE_TABLE (pci, ohci_pci_ids);
-+
-+static struct pci_driver ohci_pci_driver = {
-+ name: "usb-ohci",
-+ id_table: &ohci_pci_ids [0],
-+
-+ probe: ohci_pci_probe,
-+ remove: __devexit_p(ohci_pci_remove),
-+
-+#ifdef CONFIG_PM
-+ suspend: ohci_pci_suspend,
-+ resume: ohci_pci_resume,
-+#endif /* PM */
-+};
-+
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static int __init ohci_hcd_init (void)
-+{
-+ return pci_module_init (&ohci_pci_driver);
-+}
-+
-+/*-------------------------------------------------------------------------*/
-+
-+static void __exit ohci_hcd_cleanup (void)
-+{
-+ pci_unregister_driver (&ohci_pci_driver);
-+}
-+
-+module_init (ohci_hcd_init);
-+module_exit (ohci_hcd_cleanup);
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/usb/host/usb-ohci-sa1111.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,118 @@
-+/*
-+ * linux/drivers/usb/usb-ohci-sa1111.c
-+ *
-+ * The outline of this code was taken from Brad Parkers <brad@heeltoe.com>
-+ * original OHCI driver modifications, and reworked into a cleaner form
-+ * by Russell King <rmk@arm.linux.org.uk>.
-+ */
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/ioport.h>
-+#include <linux/interrupt.h>
-+#include <linux/slab.h>
-+#include <linux/usb.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/io.h>
-+#include <asm/pci.h>
-+#include <asm/arch/assabet.h>
-+#include <asm/arch/badge4.h>
-+#include <asm/hardware/sa1111.h>
-+
-+#include "usb-ohci.h"
-+
-+int __devinit
-+hc_add_ohci(struct pci_dev *dev, int irq, void *membase, unsigned long flags,
-+ const char *name, const char *slot_name);
-+extern void hc_remove_ohci(ohci_t *ohci);
-+
-+static ohci_t *sa1111_ohci;
-+
-+static void __init sa1111_ohci_configure(void)
-+{
-+ unsigned int usb_rst = 0;
-+
-+ if (machine_is_xp860() ||
-+ machine_has_neponset() ||
-+ machine_is_accelent_sa() ||
-+ machine_is_pfs168() ||
-+ machine_is_badge4())
-+ usb_rst = USB_RESET_PWRSENSELOW | USB_RESET_PWRCTRLLOW;
-+
-+ /*
-+ * Configure the power sense and control lines. Place the USB
-+ * host controller in reset.
-+ */
-+ USB_RESET = usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET;
-+
-+ /*
-+ * Now, carefully enable the USB clock, and take
-+ * the USB host controller out of reset.
-+ */
-+ SKPCR |= SKPCR_UCLKEN;
-+ udelay(11);
-+ USB_RESET = usb_rst;
-+}
-+
-+static int __init sa1111_ohci_init(void)
-+{
-+ int ret;
-+
-+ /*
-+ * Request memory resources.
-+ */
-+// if (!request_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT, "usb-ohci"))
-+// return -EBUSY;
-+
-+ sa1111_ohci_configure();
-+
-+ /*
-+ * Initialise the generic OHCI driver.
-+ */
-+ ret = hc_add_ohci(SA1111_FAKE_PCIDEV, NIRQHCIM,
-+ (void *)&USB_OHCI_OP_BASE, 0, &sa1111_ohci,
-+ "usb-ohci", "sa1111");
-+
-+// if (ret)
-+// release_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT);
-+
-+#ifdef CONFIG_SA1100_BADGE4
-+ if (machine_is_badge4() && (!ret)) {
-+ /* found the controller, so now power the bus */
-+ badge4_set_5V(BADGE4_5V_USB, 1);
-+ }
-+#endif
-+
-+ return ret;
-+}
-+
-+static void __exit sa1111_ohci_exit(void)
-+{
-+ hc_remove_ohci(sa1111_ohci);
-+
-+ /*
-+ * Put the USB host controller into reset.
-+ */
-+ USB_RESET |= USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET;
-+
-+ /*
-+ * Stop the USB clock.
-+ */
-+ SKPCR &= ~SKPCR_UCLKEN;
-+
-+ /*
-+ * Release memory resources.
-+ */
-+// release_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT);
-+
-+#ifdef CONFIG_SA1100_BADGE4
-+ if (machine_is_badge4()) {
-+ badge4_set_5V(BADGE4_5V_USB, 0);
-+ }
-+#endif
-+}
-+
-+module_init(sa1111_ohci_init);
-+module_exit(sa1111_ohci_exit);
---- linux-2.4.25/drivers/usb/host/usb-ohci.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/usb/host/usb-ohci.c 2004-03-31 17:15:09.000000000 +0200
-@@ -12,7 +12,6 @@
- *
- * History:
- *
-- * 2002/10/22 OHCI_USB_OPER for ALi lockup in IBM i1200 (ALEX <thchou@ali>)
- * 2002/03/08 interrupt unlink fix (Matt Hughes), better cleanup on
- * load failure (Matthew Frederickson)
- * 2002/01/20 async unlink fixes: return -EINPROGRESS (per spec) and
-@@ -81,16 +80,6 @@
-
- #include "../hcd.h"
-
--#ifdef CONFIG_PMAC_PBOOK
--#include <asm/machdep.h>
--#include <asm/pmac_feature.h>
--#include <asm/pci-bridge.h>
--#ifndef CONFIG_PM
--#define CONFIG_PM
--#endif
--#endif
--
--
- /*
- * Version Information
- */
-@@ -98,14 +87,10 @@
- #define DRIVER_AUTHOR "Roman Weissgaerber <weissg@vienna.at>, David Brownell"
- #define DRIVER_DESC "USB OHCI Host Controller Driver"
-
--/* For initializing controller (mask in an HCFS mode too) */
--#define OHCI_CONTROL_INIT \
-- (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
--
- #define OHCI_UNLINK_TIMEOUT (HZ / 10)
-
- static LIST_HEAD (ohci_hcd_list);
--static spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED;
-+spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED;
-
-
- /*-------------------------------------------------------------------------*/
-@@ -443,7 +428,7 @@
-
- static void ohci_dump (ohci_t *controller, int verbose)
- {
-- dbg ("OHCI controller usb-%s state", controller->ohci_dev->slot_name);
-+ dbg ("OHCI controller usb-%s state", controller->slot_name);
-
- // dumps some of the state we know about
- ohci_dump_status (controller);
-@@ -557,7 +542,7 @@
- int i, size = 0;
- unsigned long flags;
- int bustime = 0;
-- int mem_flags = GFP_ATOMIC;
-+ int mem_flags = ALLOC_FLAGS;
-
- if (!urb->dev || !urb->dev->bus)
- return -ENODEV;
-@@ -702,6 +687,9 @@
- if (urb->timeout) {
- struct list_head *entry;
-
-+ // FIXME: usb-uhci uses relative timeouts (like this),
-+ // while uhci uses absolute ones (probably better).
-+ // Pick one solution and change the affected drivers.
- urb->timeout += jiffies;
-
- list_for_each (entry, &ohci->timeout_list) {
-@@ -715,7 +703,6 @@
-
- /* drive timeouts by SF (messy, but works) */
- writel (OHCI_INTR_SF, &ohci->regs->intrenable);
-- (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */
- }
- #endif
-
-@@ -790,10 +777,8 @@
-
- /* wait until all TDs are deleted */
- set_current_state(TASK_UNINTERRUPTIBLE);
-- while (timeout && (urb->status == USB_ST_URB_PENDING)) {
-+ while (timeout && (urb->status == USB_ST_URB_PENDING))
- timeout = schedule_timeout (timeout);
-- set_current_state(TASK_UNINTERRUPTIBLE);
-- }
- set_current_state(TASK_RUNNING);
- remove_wait_queue (&unlink_wakeup, &wait);
- if (urb->status == USB_ST_URB_PENDING) {
-@@ -864,7 +849,7 @@
- if (ed->state == ED_OPER) {
- /* driver on that interface didn't unlink an urb */
- dbg ("driver usb-%s dev %d ed 0x%x unfreed URB",
-- ohci->ohci_dev->slot_name, usb_dev->devnum, i);
-+ ohci->slot_name, usb_dev->devnum, i);
- ep_unlink (ohci, ed);
- }
- ep_rm_ed (usb_dev, ed);
-@@ -909,7 +894,7 @@
- } else {
- /* likely some interface's driver has a refcount bug */
- err ("bus %s devnum %d deletion in interrupt",
-- ohci->ohci_dev->slot_name, usb_dev->devnum);
-+ ohci->slot_name, usb_dev->devnum);
- BUG ();
- }
- }
-@@ -1294,7 +1279,6 @@
- /* enable SOF interrupt */
- writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
- writel (OHCI_INTR_SF, &ohci->regs->intrenable);
-- (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */
- }
- }
-
-@@ -1316,7 +1300,11 @@
- err("internal OHCI error: TD index > length");
- return;
- }
--
-+#ifdef CONFIG_SA1111
-+ if (data & (1 << 20))
-+ panic("td_fill: A20 = 1: %08x\n", data);
-+#endif
-+
- /* use this td as the next dummy */
- td_pt = urb_priv->td [index];
- td_pt->hwNextTD = 0;
-@@ -1415,7 +1403,6 @@
- if (!ohci->sleeping) {
- wmb();
- writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
-- (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */
- }
- break;
-
-@@ -1444,7 +1431,6 @@
- if (!ohci->sleeping) {
- wmb();
- writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
-- (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */
- }
- break;
-
-@@ -1826,7 +1812,7 @@
- num_ports = roothub_a (ohci) & RH_A_NDP;
- if (num_ports > MAX_ROOT_PORTS) {
- err ("bogus NDP=%d for OHCI usb-%s", num_ports,
-- ohci->ohci_dev->slot_name);
-+ ohci->slot_name);
- err ("rereads as NDP=%d",
- readl (&ohci->regs->roothub.a) & RH_A_NDP);
- /* retry later; "should not happen" */
-@@ -2174,16 +2160,12 @@
- writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
-
- dbg("USB HC reset_hc usb-%s: ctrl = 0x%x ;",
-- ohci->ohci_dev->slot_name,
-+ ohci->slot_name,
- readl (&ohci->regs->control));
-
- /* Reset USB (needed by some controllers) */
- writel (0, &ohci->regs->control);
--
-- /* Force a state change from USBRESET to USBOPERATIONAL for ALi */
-- (void) readl (&ohci->regs->control); /* PCI posting */
-- writel (ohci->hc_control = OHCI_USB_OPER, &ohci->regs->control);
--
-+
- /* HC Reset requires max 10 ms delay */
- writel (OHCI_HCR, &ohci->regs->cmdstatus);
- while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
-@@ -2252,8 +2234,6 @@
- writel (RH_HS_LPSC, &ohci->regs->roothub.status);
- #endif /* OHCI_USE_NPS */
-
-- (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */
--
- // POTPGT delay is bits 24-31, in 2 ms units.
- mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
-
-@@ -2332,14 +2312,14 @@
- /* interrupt for some other device? */
- } else if ((ints &= readl (&regs->intrenable)) == 0) {
- return;
-- }
-+ }
-
- // dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no));
-
- if (ints & OHCI_INTR_UE) {
- ohci->disabled++;
- err ("OHCI Unrecoverable Error, controller usb-%s disabled",
-- ohci->ohci_dev->slot_name);
-+ ohci->slot_name);
- // e.g. due to PCI Master/Target Abort
-
- #ifdef DEBUG
-@@ -2355,30 +2335,24 @@
-
- if (ints & OHCI_INTR_WDH) {
- writel (OHCI_INTR_WDH, &regs->intrdisable);
-- (void)readl (&regs->intrdisable); /* PCI posting flush */
- dl_done_list (ohci, dl_reverse_done_list (ohci));
- writel (OHCI_INTR_WDH, &regs->intrenable);
-- (void)readl (&regs->intrdisable); /* PCI posting flush */
- }
-
- if (ints & OHCI_INTR_SO) {
- dbg("USB Schedule overrun");
- writel (OHCI_INTR_SO, &regs->intrenable);
-- (void)readl (&regs->intrdisable); /* PCI posting flush */
- }
-
- // FIXME: this assumes SOF (1/ms) interrupts don't get lost...
- if (ints & OHCI_INTR_SF) {
- unsigned int frame = le16_to_cpu (ohci->hcca->frame_no) & 1;
- writel (OHCI_INTR_SF, &regs->intrdisable);
-- (void)readl (&regs->intrdisable); /* PCI posting flush */
- if (ohci->ed_rm_list[!frame] != NULL) {
- dl_del_list (ohci, !frame);
- }
-- if (ohci->ed_rm_list[frame] != NULL) {
-+ if (ohci->ed_rm_list[frame] != NULL)
- writel (OHCI_INTR_SF, &regs->intrenable);
-- (void)readl (&regs->intrdisable); /* PCI posting flush */
-- }
- }
-
- if (!list_empty (&ohci->timeout_list)) {
-@@ -2392,7 +2366,6 @@
-
- writel (ints, &regs->intrstatus);
- writel (OHCI_INTR_MIE, &regs->intrenable);
-- (void)readl (&regs->intrdisable); /* PCI posting flush */
- }
-
- /*-------------------------------------------------------------------------*/
-@@ -2423,7 +2396,9 @@
- ohci->regs = mem_base;
-
- ohci->ohci_dev = dev;
-+#ifdef CONFIG_PCI
- pci_set_drvdata(dev, ohci);
-+#endif
-
- INIT_LIST_HEAD (&ohci->ohci_hcd_list);
- list_add (&ohci->ohci_hcd_list, &ohci_hcd_list);
-@@ -2451,7 +2426,7 @@
-
- static void hc_release_ohci (ohci_t * ohci)
- {
-- dbg ("USB HC release ohci usb-%s", ohci->ohci_dev->slot_name);
-+ dbg ("USB HC release ohci usb-%s", ohci->slot_name);
-
- /* disconnect all devices */
- if (ohci->bus->root_hub)
-@@ -2464,7 +2439,9 @@
- free_irq (ohci->irq, ohci);
- ohci->irq = -1;
- }
-- pci_set_drvdata(ohci->ohci_dev, NULL);
-+#ifdef CONFIG_PCI
-+ pci_set_drvdata(ohci->ohci_dev, 0);
-+#endif
- if (ohci->bus) {
- if (ohci->bus->busnum != -1)
- usb_deregister_bus (ohci->bus);
-@@ -2487,17 +2464,15 @@
-
- /*-------------------------------------------------------------------------*/
-
--/* Increment the module usage count, start the control thread and
-- * return success. */
--
--static struct pci_driver ohci_pci_driver;
--
--static int __devinit
--hc_found_ohci (struct pci_dev *dev, int irq,
-- void *mem_base, const struct pci_device_id *id)
-+/*
-+ * Host bus independent add one OHCI host controller.
-+ */
-+int __devinit
-+hc_add_ohci(struct pci_dev *dev, int irq, void *mem_base, unsigned long flags,
-+ const char *name, const char *slot_name)
- {
-- ohci_t * ohci;
- char buf[8], *bufp = buf;
-+ ohci_t * ohci;
- int ret;
-
- #ifndef __sparc__
-@@ -2507,34 +2482,17 @@
- #endif
- printk(KERN_INFO __FILE__ ": USB OHCI at membase 0x%lx, IRQ %s\n",
- (unsigned long) mem_base, bufp);
-- printk(KERN_INFO __FILE__ ": usb-%s, %s\n", dev->slot_name, dev->name);
--
-+
- ohci = hc_alloc_ohci (dev, mem_base);
- if (!ohci) {
- return -ENOMEM;
- }
-+ ohci->slot_name = slot_name;
- if ((ret = ohci_mem_init (ohci)) < 0) {
- hc_release_ohci (ohci);
- return ret;
- }
-- ohci->flags = id->driver_data;
--
-- /* Check for NSC87560. We have to look at the bridge (fn1) to identify
-- the USB (fn2). This quirk might apply to more or even all NSC stuff
-- I don't know.. */
--
-- if(dev->vendor == PCI_VENDOR_ID_NS)
-- {
-- struct pci_dev *fn1 = pci_find_slot(dev->bus->number, PCI_DEVFN(PCI_SLOT(dev->devfn), 1));
-- if(fn1 && fn1->vendor == PCI_VENDOR_ID_NS && fn1->device == PCI_DEVICE_ID_NS_87560_LIO)
-- ohci->flags |= OHCI_QUIRK_SUCKYIO;
--
-- }
--
-- if (ohci->flags & OHCI_QUIRK_SUCKYIO)
-- printk (KERN_INFO __FILE__ ": Using NSC SuperIO setup\n");
-- if (ohci->flags & OHCI_QUIRK_AMD756)
-- printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n");
-+ ohci->flags = flags;
-
- if (hc_reset (ohci) < 0) {
- hc_release_ohci (ohci);
-@@ -2543,13 +2501,11 @@
-
- /* FIXME this is a second HC reset; why?? */
- writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control);
-- (void)readl (&ohci->regs->intrdisable); /* PCI posting flush */
- wait_ms (10);
-
- usb_register_bus (ohci->bus);
-
-- if (request_irq (irq, hc_interrupt, SA_SHIRQ,
-- ohci_pci_driver.name, ohci) != 0) {
-+ if (request_irq (irq, hc_interrupt, SA_SHIRQ, name, ohci) != 0) {
- err ("request interrupt %s failed", bufp);
- hc_release_ohci (ohci);
- return -EBUSY;
-@@ -2557,7 +2513,7 @@
- ohci->irq = irq;
-
- if (hc_start (ohci) < 0) {
-- err ("can't start usb-%s", dev->slot_name);
-+ err ("can't start usb-%s", ohci->slot_name);
- hc_release_ohci (ohci);
- return -EBUSY;
- }
-@@ -2568,114 +2524,11 @@
- return 0;
- }
-
--/*-------------------------------------------------------------------------*/
--
--#ifdef CONFIG_PM
--
--/* controller died; cleanup debris, then restart */
--/* must not be called from interrupt context */
--
--static void hc_restart (ohci_t *ohci)
--{
-- int temp;
-- int i;
--
-- if (ohci->pci_latency)
-- pci_write_config_byte (ohci->ohci_dev, PCI_LATENCY_TIMER, ohci->pci_latency);
--
-- ohci->disabled = 1;
-- ohci->sleeping = 0;
-- if (ohci->bus->root_hub)
-- usb_disconnect (&ohci->bus->root_hub);
--
-- /* empty the interrupt branches */
-- for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0;
-- for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table[i] = 0;
--
-- /* no EDs to remove */
-- ohci->ed_rm_list [0] = NULL;
-- ohci->ed_rm_list [1] = NULL;
--
-- /* empty control and bulk lists */
-- ohci->ed_isotail = NULL;
-- ohci->ed_controltail = NULL;
-- ohci->ed_bulktail = NULL;
--
-- if ((temp = hc_reset (ohci)) < 0 || (temp = hc_start (ohci)) < 0) {
-- err ("can't restart usb-%s, %d", ohci->ohci_dev->slot_name, temp);
-- } else
-- dbg ("restart usb-%s completed", ohci->ohci_dev->slot_name);
--}
--
--#endif /* CONFIG_PM */
--
--/*-------------------------------------------------------------------------*/
--
--/* configured so that an OHCI device is always provided */
--/* always called with process context; sleeping is OK */
--
--static int __devinit
--ohci_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
--{
-- unsigned long mem_resource, mem_len;
-- void *mem_base;
-- int status;
--
-- if (pci_enable_device(dev) < 0)
-- return -ENODEV;
--
-- if (!dev->irq) {
-- err("found OHCI device with no IRQ assigned. check BIOS settings!");
-- pci_disable_device (dev);
-- return -ENODEV;
-- }
--
-- /* we read its hardware registers as memory */
-- mem_resource = pci_resource_start(dev, 0);
-- mem_len = pci_resource_len(dev, 0);
-- if (!request_mem_region (mem_resource, mem_len, ohci_pci_driver.name)) {
-- dbg ("controller already in use");
-- pci_disable_device (dev);
-- return -EBUSY;
-- }
--
-- mem_base = ioremap_nocache (mem_resource, mem_len);
-- if (!mem_base) {
-- err("Error mapping OHCI memory");
-- release_mem_region (mem_resource, mem_len);
-- pci_disable_device (dev);
-- return -EFAULT;
-- }
--
-- /* controller writes into our memory */
-- pci_set_master (dev);
--
-- status = hc_found_ohci (dev, dev->irq, mem_base, id);
-- if (status < 0) {
-- iounmap (mem_base);
-- release_mem_region (mem_resource, mem_len);
-- pci_disable_device (dev);
-- }
-- return status;
--}
--
--/*-------------------------------------------------------------------------*/
--
--/* may be called from interrupt context [interface spec] */
--/* may be called without controller present */
--/* may be called with controller, bus, and devices active */
--
--static void __devexit
--ohci_pci_remove (struct pci_dev *dev)
-+/*
-+ * Host bus independent remove one OHCI host controller.
-+ */
-+void __devexit hc_remove_ohci(ohci_t *ohci)
- {
-- ohci_t *ohci = pci_get_drvdata(dev);
--
-- dbg ("remove %s controller usb-%s%s%s",
-- hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
-- dev->slot_name,
-- ohci->disabled ? " (disabled)" : "",
-- in_interrupt () ? " in interrupt" : ""
-- );
- #ifdef DEBUG
- ohci_dump (ohci, 1);
- #endif
-@@ -2692,270 +2545,8 @@
- &ohci->regs->control);
-
- hc_release_ohci (ohci);
--
-- release_mem_region (pci_resource_start (dev, 0), pci_resource_len (dev, 0));
-- pci_disable_device (dev);
- }
-
--
--#ifdef CONFIG_PM
--
--/*-------------------------------------------------------------------------*/
--
--static int
--ohci_pci_suspend (struct pci_dev *dev, u32 state)
--{
-- ohci_t *ohci = pci_get_drvdata(dev);
-- unsigned long flags;
-- u16 cmd;
--
-- if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) {
-- dbg ("can't suspend usb-%s (state is %s)", dev->slot_name,
-- hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS));
-- return -EIO;
-- }
--
-- /* act as if usb suspend can always be used */
-- info ("USB suspend: usb-%s", dev->slot_name);
-- ohci->sleeping = 1;
--
-- /* First stop processing */
-- spin_lock_irqsave (&usb_ed_lock, flags);
-- ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE);
-- writel (ohci->hc_control, &ohci->regs->control);
-- writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
-- (void) readl (&ohci->regs->intrstatus);
-- spin_unlock_irqrestore (&usb_ed_lock, flags);
--
-- /* Wait a frame or two */
-- mdelay(1);
-- if (!readl (&ohci->regs->intrstatus) & OHCI_INTR_SF)
-- mdelay (1);
--
--#ifdef CONFIG_PMAC_PBOOK
-- if (_machine == _MACH_Pmac)
-- disable_irq (ohci->irq);
-- /* else, 2.4 assumes shared irqs -- don't disable */
--#endif
-- /* Enable remote wakeup */
-- writel (readl(&ohci->regs->intrenable) | OHCI_INTR_RD, &ohci->regs->intrenable);
--
-- /* Suspend chip and let things settle down a bit */
-- ohci->hc_control = OHCI_USB_SUSPEND;
-- writel (ohci->hc_control, &ohci->regs->control);
-- (void) readl (&ohci->regs->control);
-- mdelay (500); /* No schedule here ! */
-- switch (readl (&ohci->regs->control) & OHCI_CTRL_HCFS) {
-- case OHCI_USB_RESET:
-- dbg("Bus in reset phase ???");
-- break;
-- case OHCI_USB_RESUME:
-- dbg("Bus in resume phase ???");
-- break;
-- case OHCI_USB_OPER:
-- dbg("Bus in operational phase ???");
-- break;
-- case OHCI_USB_SUSPEND:
-- dbg("Bus suspended");
-- break;
-- }
-- /* In some rare situations, Apple's OHCI have happily trashed
-- * memory during sleep. We disable it's bus master bit during
-- * suspend
-- */
-- pci_read_config_word (dev, PCI_COMMAND, &cmd);
-- cmd &= ~PCI_COMMAND_MASTER;
-- pci_write_config_word (dev, PCI_COMMAND, cmd);
--#ifdef CONFIG_PMAC_PBOOK
-- {
-- struct device_node *of_node;
--
-- /* Disable USB PAD & cell clock */
-- of_node = pci_device_to_OF_node (ohci->ohci_dev);
-- if (of_node)
-- pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
-- }
--#endif
-- return 0;
--}
--
--/*-------------------------------------------------------------------------*/
--
--static int
--ohci_pci_resume (struct pci_dev *dev)
--{
-- ohci_t *ohci = pci_get_drvdata(dev);
-- int temp;
-- unsigned long flags;
--
-- /* guard against multiple resumes */
-- atomic_inc (&ohci->resume_count);
-- if (atomic_read (&ohci->resume_count) != 1) {
-- err ("concurrent PCI resumes for usb-%s", dev->slot_name);
-- atomic_dec (&ohci->resume_count);
-- return 0;
-- }
--
--#ifdef CONFIG_PMAC_PBOOK
-- {
-- struct device_node *of_node;
--
-- /* Re-enable USB PAD & cell clock */
-- of_node = pci_device_to_OF_node (ohci->ohci_dev);
-- if (of_node)
-- pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 1);
-- }
--#endif
--
-- /* did we suspend, or were we powered off? */
-- ohci->hc_control = readl (&ohci->regs->control);
-- temp = ohci->hc_control & OHCI_CTRL_HCFS;
--
--#ifdef DEBUG
-- /* the registers may look crazy here */
-- ohci_dump_status (ohci);
--#endif
--
-- /* Re-enable bus mastering */
-- pci_set_master(ohci->ohci_dev);
--
-- switch (temp) {
--
-- case OHCI_USB_RESET: // lost power
-- info ("USB restart: usb-%s", dev->slot_name);
-- hc_restart (ohci);
-- break;
--
-- case OHCI_USB_SUSPEND: // host wakeup
-- case OHCI_USB_RESUME: // remote wakeup
-- info ("USB continue: usb-%s from %s wakeup", dev->slot_name,
-- (temp == OHCI_USB_SUSPEND)
-- ? "host" : "remote");
-- ohci->hc_control = OHCI_USB_RESUME;
-- writel (ohci->hc_control, &ohci->regs->control);
-- (void) readl (&ohci->regs->control);
-- mdelay (20); /* no schedule here ! */
-- /* Some controllers (lucent) need a longer delay here */
-- mdelay (15);
-- temp = readl (&ohci->regs->control);
-- temp = ohci->hc_control & OHCI_CTRL_HCFS;
-- if (temp != OHCI_USB_RESUME) {
-- err ("controller usb-%s won't resume", dev->slot_name);
-- ohci->disabled = 1;
-- return -EIO;
-- }
--
-- /* Some chips likes being resumed first */
-- writel (OHCI_USB_OPER, &ohci->regs->control);
-- (void) readl (&ohci->regs->control);
-- mdelay (3);
--
-- /* Then re-enable operations */
-- spin_lock_irqsave (&usb_ed_lock, flags);
-- ohci->disabled = 0;
-- ohci->sleeping = 0;
-- ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
-- if (!ohci->ed_rm_list[0] && !ohci->ed_rm_list[1]) {
-- if (ohci->ed_controltail)
-- ohci->hc_control |= OHCI_CTRL_CLE;
-- if (ohci->ed_bulktail)
-- ohci->hc_control |= OHCI_CTRL_BLE;
-- }
-- writel (ohci->hc_control, &ohci->regs->control);
-- writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
-- writel (OHCI_INTR_SF, &ohci->regs->intrenable);
-- /* Check for a pending done list */
-- writel (OHCI_INTR_WDH, &ohci->regs->intrdisable);
-- (void) readl (&ohci->regs->intrdisable);
-- spin_unlock_irqrestore (&usb_ed_lock, flags);
--#ifdef CONFIG_PMAC_PBOOK
-- if (_machine == _MACH_Pmac)
-- enable_irq (ohci->irq);
--#endif
-- if (ohci->hcca->done_head)
-- dl_done_list (ohci, dl_reverse_done_list (ohci));
-- writel (OHCI_INTR_WDH, &ohci->regs->intrenable);
-- writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
-- writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
-- break;
--
-- default:
-- warn ("odd PCI resume for usb-%s", dev->slot_name);
-- }
--
-- /* controller is operational, extra resumes are harmless */
-- atomic_dec (&ohci->resume_count);
--
-- return 0;
--}
--
--#endif /* CONFIG_PM */
--
--
--/*-------------------------------------------------------------------------*/
--
--static const struct pci_device_id __devinitdata ohci_pci_ids [] = { {
--
-- /*
-- * AMD-756 [Viper] USB has a serious erratum when used with
-- * lowspeed devices like mice.
-- */
-- vendor: 0x1022,
-- device: 0x740c,
-- subvendor: PCI_ANY_ID,
-- subdevice: PCI_ANY_ID,
--
-- driver_data: OHCI_QUIRK_AMD756,
--
--} , {
--
-- /* handle any USB OHCI controller */
-- class: ((PCI_CLASS_SERIAL_USB << 8) | 0x10),
-- class_mask: ~0,
--
-- /* no matter who makes it */
-- vendor: PCI_ANY_ID,
-- device: PCI_ANY_ID,
-- subvendor: PCI_ANY_ID,
-- subdevice: PCI_ANY_ID,
--
-- }, { /* end: all zeroes */ }
--};
--
--MODULE_DEVICE_TABLE (pci, ohci_pci_ids);
--
--static struct pci_driver ohci_pci_driver = {
-- name: "usb-ohci",
-- id_table: &ohci_pci_ids [0],
--
-- probe: ohci_pci_probe,
-- remove: __devexit_p(ohci_pci_remove),
--
--#ifdef CONFIG_PM
-- suspend: ohci_pci_suspend,
-- resume: ohci_pci_resume,
--#endif /* PM */
--};
--
--
--/*-------------------------------------------------------------------------*/
--
--static int __init ohci_hcd_init (void)
--{
-- return pci_module_init (&ohci_pci_driver);
--}
--
--/*-------------------------------------------------------------------------*/
--
--static void __exit ohci_hcd_cleanup (void)
--{
-- pci_unregister_driver (&ohci_pci_driver);
--}
--
--module_init (ohci_hcd_init);
--module_exit (ohci_hcd_cleanup);
--
--
- MODULE_AUTHOR( DRIVER_AUTHOR );
- MODULE_DESCRIPTION( DRIVER_DESC );
- MODULE_LICENSE("GPL");
---- linux-2.4.25/drivers/usb/host/usb-ohci.h~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/usb/host/usb-ohci.h 2004-03-31 17:15:09.000000000 +0200
-@@ -386,6 +386,7 @@
- struct ohci_regs * regs; /* OHCI controller's memory */
- struct list_head ohci_hcd_list; /* list of all ohci_hcd */
-
-+ struct ohci * next; // chain of ohci device contexts
- struct list_head timeout_list;
- // struct list_head urb_list; // list of all pending urbs
- // spinlock_t urb_list_lock; // lock to keep consistency
-@@ -403,6 +404,7 @@
-
- /* PCI device handle, settings, ... */
- struct pci_dev *ohci_dev;
-+ const char *slot_name;
- u8 pci_latency;
- struct pci_pool *td_cache;
- struct pci_pool *dev_cache;
-@@ -448,7 +450,7 @@
- #endif
-
- #ifndef CONFIG_PCI
--# error "usb-ohci currently requires PCI-based controllers"
-+//# error "usb-ohci currently requires PCI-based controllers"
- /* to support non-PCI OHCIs, you need custom bus/mem/... glue */
- #endif
-
-@@ -641,3 +643,6 @@
- pci_pool_free (hc->dev_cache, dev, dev->dma);
- }
-
-+/* For initializing controller (mask in an HCFS mode too) */
-+#define OHCI_CONTROL_INIT \
-+ (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
---- linux-2.4.25/drivers/video/Config.in~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/video/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -30,13 +30,28 @@
- tristate ' Permedia3 support (EXPERIMENTAL)' CONFIG_FB_PM3
- fi
- fi
-- if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
-- bool ' Acorn VIDC support' CONFIG_FB_ACORN
-- fi
-- dep_tristate ' Cyber2000 support' CONFIG_FB_CYBER2000 $CONFIG_PCI
-- if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
-- bool ' SA-1100 LCD support' CONFIG_FB_SA1100
-+ if [ "$CONFIG_ARM" = "y" ]; then
-+ if [ "$CONFIG_ARCH_ACORN" -o "$CONFIG_ARCH_RISCSTATION" ]; then
-+ bool ' Acorn VIDC support' CONFIG_FB_ACORN
-+ else
-+ define_bool CONFIG_FB_ACORN n
-+ fi
-+ dep_bool ' Anakin LCD support' CONFIG_FB_ANAKIN $CONFIG_ARCH_ANAKIN
-+ dep_bool ' CLPS711X LCD support' CONFIG_FB_CLPS711X $CONFIG_ARCH_CLPS711X
-+ dep_bool ' SA-1100 LCD support' CONFIG_FB_SA1100 $CONFIG_ARCH_SA1100
-+ dep_bool ' MX1ADS LCD support' CONFIG_FB_DBMX1 $CONFIG_ARCH_MX1ADS
-+ if [ "$CONFIG_FB_SA1100" = "y" -a "$CONFIG_SA1100_CERF" = "y" ]; then
-+ choice 'CerfBoard LCD Display Size' \
-+ "3.8_Color CONFIG_CERF_LCD_38_A \
-+ 3.8_Mono CONFIG_CERF_LCD_38_B \
-+ 5.7 CONFIG_CERF_LCD_57_A \
-+ 7.2 CONFIG_CERF_LCD_72_A" 5.7
-+ fi
-+ if [ "$CONFIG_FB_SA1100" = "y" -a "$CONFIG_SA1100_CERF_CPLD" = "y" ]; then
-+ bool 'Cerfboard Backlight (CerfPDA)' CONFIG_SA1100_CERF_LCD_BACKLIGHT
-+ fi
- fi
-+ dep_tristate ' CyberPro 2000/2010/5000 support' CONFIG_FB_CYBER2000 $CONFIG_PCI
- if [ "$CONFIG_APOLLO" = "y" ]; then
- define_bool CONFIG_FB_APOLLO y
- fi
-@@ -265,7 +280,7 @@
- "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_RETINAZ3" = "y" -o \
- "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
- "$CONFIG_FB_BWTWO" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
-- "$CONFIG_FB_TX3912" = "y" ]; then
-+ "$CONFIG_FB_TX3912" = "y" -o "$CONFIG_FB_CLPS711X" = "y" ]; then
- define_tristate CONFIG_FBCON_MFB y
- else
- if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_AMIGA" = "m" -o \
-@@ -273,19 +288,20 @@
- "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_RETINAZ3" = "m" -o \
- "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
- "$CONFIG_FB_BWTWO" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
-- "$CONFIG_FB_TX3912" = "m" ]; then
-+ "$CONFIG_FB_TX3912" = "m" -o "$CONFIG_FB_CLPS711X" = "m" ]; then
- define_tristate CONFIG_FBCON_MFB m
- fi
- fi
- if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
- "$CONFIG_FB_SA1100" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
-- "$CONFIG_FB_TX3912" = "y" ]; then
-+ "$CONFIG_FB_TX3912" = "y" -o "$CONFIG_FB_CLPS711X" = "y" -o \
-+ "$CONFIG_FB_DBMX1" = "y" ]; then
- define_tristate CONFIG_FBCON_CFB2 y
- define_tristate CONFIG_FBCON_CFB4 y
- else
- if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_MAC" = "m" -o \
- "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
-- "$CONFIG_FB_TX3912" = "m" ]; then
-+ "$CONFIG_FB_TX3912" = "m" -o "$CONFIG_FB_CLPS711X" = "m" ]; then
- define_tristate CONFIG_FBCON_CFB2 m
- define_tristate CONFIG_FBCON_CFB4 m
- fi
-@@ -312,7 +328,8 @@
- "$CONFIG_FB_TX3912" = "y" -o \
- "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_NEOMAGIC" = "y" -o \
- "$CONFIG_FB_STI" = "y" -o "$CONFIG_FB_HP300" = "y" -o \
-- "$CONFIG_FB_INTEL" = "y" ]; then
-+ "$CONFIG_FB_INTEL" = "y" -o \
-+ "$CONFIG_FB_DBMX1" = "y" ]; then
- define_tristate CONFIG_FBCON_CFB8 y
- else
- if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
-@@ -354,7 +371,9 @@
- "$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_3DFX" = "y" -o \
- "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SA1100" = "y" -o \
- "$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_VOODOO1" = "y" -o \
-- "$CONFIG_FB_NEOMAGIC" = "y" -o "$CONFIG_FB_INTEL" = "y" ]; then
-+ "$CONFIG_FB_NEOMAGIC" = "y" -o "$CONFIG_FB_INTEL" = "y" -o \
-+ "$CONFIG_FB_ANAKIN" = "y" -o \
-+ "$CONFIG_FB_DBMX1" = "y" ]; then
- define_tristate CONFIG_FBCON_CFB16 y
- else
- if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
-@@ -509,6 +528,9 @@
- if [ "$CONFIG_AMIGA" = "y" ]; then
- define_bool CONFIG_FONT_PEARL_8x8 y
- fi
-+ if [ "$CONFIG_ARM" = "y" -a "$CONFIG_ARCH_RISCSTATION" = "y" ]; then
-+ define_bool CONFIG_FONT_ACORN_8x8 y
-+ fi
- if [ "$CONFIG_ARM" = "y" -a "$CONFIG_ARCH_ACORN" = "y" ]; then
- define_bool CONFIG_FONT_ACORN_8x8 y
- fi
---- linux-2.4.25/drivers/video/Makefile~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/video/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -55,6 +55,7 @@
- obj-$(CONFIG_FB_PLATINUM) += platinumfb.o
- obj-$(CONFIG_FB_VALKYRIE) += valkyriefb.o
- obj-$(CONFIG_FB_CT65550) += chipsfb.o
-+obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o
- obj-$(CONFIG_FB_CYBER) += cyberfb.o
- obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o
- obj-$(CONFIG_FB_SGIVW) += sgivwfb.o
-@@ -68,7 +69,7 @@
- obj-$(CONFIG_FB_TRIDENT) += tridentfb.o fbgen.o
- obj-$(CONFIG_FB_S3TRIO) += S3triofb.o
- obj-$(CONFIG_FB_TGA) += tgafb.o fbgen.o
--obj-$(CONFIG_FB_VESA) += vesafb.o
-+obj-$(CONFIG_FB_VESA) += vesafb.o
- obj-$(CONFIG_FB_VGA16) += vga16fb.o fbcon-vga-planes.o
- obj-$(CONFIG_FB_VIRGE) += virgefb.o
- obj-$(CONFIG_FB_G364) += g364fb.o
-@@ -126,14 +127,16 @@
-
- obj-$(CONFIG_FB_SUN3) += sun3fb.o
- obj-$(CONFIG_FB_BWTWO) += bwtwofb.o
--obj-$(CONFIG_FB_HGA) += hgafb.o
-+obj-$(CONFIG_FB_HGA) += hgafb.o
- obj-$(CONFIG_FB_SA1100) += sa1100fb.o
--obj-$(CONFIG_FB_VIRTUAL) += vfb.o
-+obj-$(CONFIG_FB_DBMX1) += dbmx1fb.o
-+obj-$(CONFIG_FB_VIRTUAL) += vfb.o
- obj-$(CONFIG_FB_HIT) += hitfb.o fbgen.o
- obj-$(CONFIG_FB_E1355) += epson1355fb.o fbgen.o
- obj-$(CONFIG_FB_E1356) += epson1356fb.o
- obj-$(CONFIG_FB_PVR2) += pvr2fb.o
- obj-$(CONFIG_FB_VOODOO1) += sstfb.o
-+obj-$(CONFIG_FB_ANAKIN) += anakinfb.o
-
- # Generic Low Level Drivers
-
-@@ -169,4 +172,3 @@
- -e 's/dfont\(_uni.*\]\)/promfont\1 __initdata/' > promcon_tbl.c
-
- promcon_tbl.o: promcon_tbl.c $(TOPDIR)/include/linux/types.h
--
---- linux-2.4.25/drivers/video/acornfb.c~2.4.25-vrs2.patch 2002-08-03 02:39:45.000000000 +0200
-+++ linux-2.4.25/drivers/video/acornfb.c 2004-03-31 17:15:09.000000000 +0200
-@@ -752,11 +752,12 @@
- }
- #endif
- #ifdef FBCON_HAS_CFB16
-- if (bpp == 16 && regno < 16) {
-+ if (bpp == 16) {
- int i;
-
-- current_par.cmap.cfb16[regno] =
-- regno | regno << 5 | regno << 10;
-+ if (regno < 16)
-+ current_par.cmap.cfb16[regno] =
-+ regno | regno << 5 | regno << 10;
-
- pal.p = 0;
- vidc_writel(0x10000000);
-@@ -1215,7 +1216,7 @@
- p.vidc20.green = current_par.palette[(i >> 1) & 31].vidc20.green;
- p.vidc20.blue = current_par.palette[(i >> 2) & 31].vidc20.blue;
- }
-- acornfb_palette_write(i, current_par.palette[i]);
-+ acornfb_palette_write(i, p);
- }
- } else
- #endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/video/anakinfb.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,221 @@
-+/*
-+ * linux/drivers/video/anakinfb.c
-+ *
-+ * Copyright (C) 2001 Aleph One Ltd. for Acunia N.V.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Changelog:
-+ * 23-Apr-2001 TTC Created
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/fb.h>
-+#include <linux/string.h>
-+#include <linux/errno.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+
-+#include <asm/io.h>
-+
-+#include <video/fbcon.h>
-+#include <video/fbcon-cfb16.h>
-+
-+static u16 colreg[16];
-+static int currcon = 0;
-+static struct fb_info fb_info;
-+static struct display display;
-+
-+static int
-+anakinfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-+ u_int *transp, struct fb_info *info)
-+{
-+ if (regno > 15)
-+ return 1;
-+
-+ *red = colreg[regno] & 0xf800;
-+ *green = colreg[regno] & 0x7e0 << 5;
-+ *blue = colreg[regno] & 0x1f << 11;
-+ *transp = 0;
-+ return 0;
-+}
-+
-+static int
-+anakinfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-+ u_int transp, struct fb_info *info)
-+{
-+ if (regno > 15)
-+ return 1;
-+
-+ colreg[regno] = (red & 0xf800) | (green & 0xfc00 >> 5) |
-+ (blue & 0xf800 >> 11);
-+ return 0;
-+}
-+
-+static int
-+anakinfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
-+{
-+ memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-+ strcpy(fix->id, "AnakinFB");
-+ fix->smem_start = VGA_START;
-+ fix->smem_len = VGA_SIZE;
-+ fix->type = FB_TYPE_PACKED_PIXELS;
-+ fix->type_aux = 0;
-+ fix->visual = FB_VISUAL_TRUECOLOR;
-+ fix->xpanstep = 0;
-+ fix->ypanstep = 0;
-+ fix->ywrapstep = 0;
-+ fix->line_length = 400 * 2;
-+ fix->accel = FB_ACCEL_NONE;
-+ return 0;
-+}
-+
-+static int
-+anakinfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-+{
-+ memset(var, 0, sizeof(struct fb_var_screeninfo));
-+ var->xres = 400;
-+ var->yres = 234;
-+ var->xres_virtual = 400;
-+ var->yres_virtual = 234;
-+ var->xoffset = 0;
-+ var->yoffset = 0;
-+ var->bits_per_pixel = 16;
-+ var->grayscale = 0;
-+ var->red.offset = 11;
-+ var->red.length = 5;
-+ var->green.offset = 5;
-+ var->green.length = 6;
-+ var->blue.offset = 0;
-+ var->blue.length = 5;
-+ var->transp.offset = 0;
-+ var->transp.length = 0;
-+ var->nonstd = 0;
-+ var->activate = FB_ACTIVATE_NOW;
-+ var->height = -1;
-+ var->width = -1;
-+ var->pixclock = 0;
-+ var->left_margin = 0;
-+ var->right_margin = 0;
-+ var->upper_margin = 0;
-+ var->lower_margin = 0;
-+ var->hsync_len = 0;
-+ var->vsync_len = 0;
-+ var->sync = 0;
-+ var->vmode = FB_VMODE_NONINTERLACED;
-+ return 0;
-+}
-+
-+static int
-+anakinfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-+{
-+ return -EINVAL;
-+}
-+
-+static int
-+anakinfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-+ struct fb_info *info)
-+{
-+ if (con == currcon)
-+ return fb_get_cmap(cmap, kspc, anakinfb_getcolreg, info);
-+ else if (fb_display[con].cmap.len)
-+ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-+ else
-+ fb_copy_cmap(fb_default_cmap(16), cmap, kspc ? 0 : 2);
-+ return 0;
-+}
-+
-+static int
-+anakinfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-+ struct fb_info *info)
-+{
-+ int err;
-+
-+ if (!fb_display[con].cmap.len) {
-+ if ((err = fb_alloc_cmap(&fb_display[con].cmap, 16, 0)))
-+ return err;
-+ }
-+ if (con == currcon)
-+ return fb_set_cmap(cmap, kspc, anakinfb_setcolreg, info);
-+ else
-+ fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
-+ return 0;
-+}
-+
-+static int
-+anakinfb_switch_con(int con, struct fb_info *info)
-+{
-+ currcon = con;
-+ return 0;
-+
-+}
-+
-+static int
-+anakinfb_updatevar(int con, struct fb_info *info)
-+{
-+ return 0;
-+}
-+
-+static void
-+anakinfb_blank(int blank, struct fb_info *info)
-+{
-+ /*
-+ * TODO: use I2C to blank/unblank the screen
-+ */
-+}
-+
-+static struct fb_ops anakinfb_ops = {
-+ owner: THIS_MODULE,
-+ fb_get_fix: anakinfb_get_fix,
-+ fb_get_var: anakinfb_get_var,
-+ fb_set_var: anakinfb_set_var,
-+ fb_get_cmap: anakinfb_get_cmap,
-+ fb_set_cmap: anakinfb_set_cmap,
-+};
-+
-+int __init
-+anakinfb_init(void)
-+{
-+ memset(&fb_info, 0, sizeof(struct fb_info));
-+ strcpy(fb_info.modename, "AnakinFB");
-+ fb_info.node = -1;
-+ fb_info.flags = FBINFO_FLAG_DEFAULT;
-+ fb_info.fbops = &anakinfb_ops;
-+ fb_info.disp = &display;
-+ strcpy(fb_info.fontname, "VGA8x16");
-+ fb_info.changevar = NULL;
-+ fb_info.switch_con = &anakinfb_switch_con;
-+ fb_info.updatevar = &anakinfb_updatevar;
-+ fb_info.blank = &anakinfb_blank;
-+
-+ memset(&display, 0, sizeof(struct display));
-+ anakinfb_get_var(&display.var, 0, &fb_info);
-+ display.screen_base = ioremap(VGA_START, VGA_SIZE);
-+ display.visual = FB_VISUAL_TRUECOLOR;
-+ display.type = FB_TYPE_PACKED_PIXELS;
-+ display.type_aux = 0;
-+ display.ypanstep = 0;
-+ display.ywrapstep = 0;
-+ display.line_length = 400 * 2;
-+ display.can_soft_blank = 1;
-+ display.inverse = 0;
-+
-+#ifdef FBCON_HAS_CFB16
-+ display.dispsw = &fbcon_cfb16;
-+ display.dispsw_data = colreg;
-+#else
-+ display.dispsw = &fbcon_dummy;
-+#endif
-+
-+ if (register_framebuffer(&fb_info) < 0)
-+ return -EINVAL;
-+
-+ MOD_INC_USE_COUNT;
-+ return 0;
-+}
-+
-+MODULE_AUTHOR("Tak-Shing Chan <chan@aleph1.co.uk>");
-+MODULE_DESCRIPTION("Anakin framebuffer driver");
-+MODULE_SUPPORTED_DEVICE("fb");
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/video/clps711xfb.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,677 @@
-+/*
-+ * linux/drivers/video/clps711xfb.c
-+ *
-+ * Copyright (C) 2000-2001 Deep Blue Solutions Ltd.
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Framebuffer driver for the CLPS7111 and EP7212 processors.
-+ */
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/fb.h>
-+#include <linux/init.h>
-+#include <linux/proc_fs.h>
-+#include <linux/delay.h>
-+
-+#include <video/fbcon.h>
-+#include <video/fbcon-cfb4.h>
-+#include <video/fbcon-cfb2.h>
-+#include <video/fbcon-mfb.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/mach-types.h>
-+#include <asm/uaccess.h>
-+
-+#include <asm/hardware/clps7111.h>
-+#include <asm/arch/syspld.h>
-+
-+static struct clps7111fb_info {
-+ struct fb_info fb;
-+ int currcon;
-+} *cfb;
-+
-+#define CMAP_MAX_SIZE 16
-+
-+/* The /proc entry for the backlight. */
-+static struct proc_dir_entry *clps7111fb_backlight_proc_entry = NULL;
-+
-+static int clps7111fb_proc_backlight_read(char *page, char **start, off_t off,
-+ int count, int *eof, void *data);
-+static int clps7111fb_proc_backlight_write(struct file *file,
-+ const char *buffer, unsigned long count, void *data);
-+
-+/*
-+ * LCD AC Prescale. This comes from the LCD panel manufacturers specifications.
-+ * This determines how many clocks + 1 of CL1 before the M signal toggles.
-+ * The number of lines on the display must not be divisible by this number.
-+ */
-+static unsigned int lcd_ac_prescale = 13;
-+
-+/*
-+ * Set a single color register. Return != 0 for invalid regno.
-+ */
-+static int
-+clps7111fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-+ u_int transp, struct fb_info *info)
-+{
-+ unsigned int level, mask, shift, pal;
-+
-+ if (regno >= (1 << info->var.bits_per_pixel))
-+ return 1;
-+
-+ /* gray = 0.30*R + 0.58*G + 0.11*B */
-+ level = (red * 77 + green * 151 + blue * 28) >> 20;
-+
-+ /*
-+ * On an LCD, a high value is dark, while a low value is light.
-+ * So we invert the level.
-+ *
-+ * This isn't true on all machines, so we only do it on EDB7211.
-+ * --rmk
-+ */
-+ if (machine_is_edb7211() || machine_is_guidea07()) {
-+ level = 15 - level;
-+ }
-+
-+ shift = 4 * (regno & 7);
-+ level <<= shift;
-+ mask = 15 << shift;
-+ level &= mask;
-+
-+ regno = regno < 8 ? PALLSW : PALMSW;
-+
-+ pal = clps_readl(regno);
-+ pal = (pal & ~mask) | level;
-+ clps_writel(pal, regno);
-+
-+ return 0;
-+}
-+
-+/*
-+ * Set the colormap
-+ */
-+static int
-+clps7111fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-+ struct fb_info *info)
-+{
-+ struct clps7111fb_info *cfb = (struct clps7111fb_info *)info;
-+ struct fb_cmap *dcmap = &fb_display[con].cmap;
-+ int err = 0;
-+
-+ /* no colormap allocated? */
-+ if (!dcmap->len)
-+ err = fb_alloc_cmap(dcmap, CMAP_MAX_SIZE, 0);
-+
-+ if (!err && con == cfb->currcon) {
-+ err = fb_set_cmap(cmap, kspc, clps7111fb_setcolreg, &cfb->fb);
-+ dcmap = &cfb->fb.cmap;
-+ }
-+
-+ if (!err)
-+ fb_copy_cmap(cmap, dcmap, kspc ? 0 : 1);
-+
-+ return err;
-+}
-+
-+/*
-+ * Set the User Defined Part of the Display
-+ */
-+static int
-+clps7111fb_set_var(struct fb_var_screeninfo *var, int con,
-+ struct fb_info *info)
-+{
-+ struct display *display;
-+ unsigned int lcdcon, syscon, pixclock;
-+ int chgvar = 0;
-+
-+ if (var->activate & FB_ACTIVATE_TEST)
-+ return 0;
-+
-+ if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
-+ return -EINVAL;
-+
-+ if (cfb->fb.var.xres != var->xres)
-+ chgvar = 1;
-+ if (cfb->fb.var.yres != var->yres)
-+ chgvar = 1;
-+ if (cfb->fb.var.xres_virtual != var->xres_virtual)
-+ chgvar = 1;
-+ if (cfb->fb.var.yres_virtual != var->yres_virtual)
-+ chgvar = 1;
-+ if (cfb->fb.var.bits_per_pixel != var->bits_per_pixel)
-+ chgvar = 1;
-+
-+ if (con < 0) {
-+ display = cfb->fb.disp;
-+ chgvar = 0;
-+ } else {
-+ display = fb_display + con;
-+ }
-+
-+ var->transp.msb_right = 0;
-+ var->transp.offset = 0;
-+ var->transp.length = 0;
-+ var->red.msb_right = 0;
-+ var->red.offset = 0;
-+ var->red.length = var->bits_per_pixel;
-+ var->green = var->red;
-+ var->blue = var->red;
-+
-+ switch (var->bits_per_pixel) {
-+#ifdef FBCON_HAS_MFB
-+ case 1:
-+ cfb->fb.fix.visual = FB_VISUAL_MONO01;
-+ display->dispsw = &fbcon_mfb;
-+ display->dispsw_data = NULL;
-+ break;
-+#endif
-+#ifdef FBCON_HAS_CFB2
-+ case 2:
-+ cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
-+ display->dispsw = &fbcon_cfb2;
-+ display->dispsw_data = NULL;
-+ break;
-+#endif
-+#ifdef FBCON_HAS_CFB4
-+ case 4:
-+ cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
-+ display->dispsw = &fbcon_cfb4;
-+ display->dispsw_data = NULL;
-+ break;
-+#endif
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ display->next_line = var->xres_virtual * var->bits_per_pixel / 8;
-+
-+ cfb->fb.fix.line_length = display->next_line;
-+
-+ display->screen_base = cfb->fb.screen_base;
-+ display->line_length = cfb->fb.fix.line_length;
-+ display->visual = cfb->fb.fix.visual;
-+ display->type = cfb->fb.fix.type;
-+ display->type_aux = cfb->fb.fix.type_aux;
-+ display->ypanstep = cfb->fb.fix.ypanstep;
-+ display->ywrapstep = cfb->fb.fix.ywrapstep;
-+ display->can_soft_blank = 1;
-+ display->inverse = 0;
-+
-+ cfb->fb.var = *var;
-+ cfb->fb.var.activate &= ~FB_ACTIVATE_ALL;
-+
-+ /*
-+ * Update the old var. The fbcon drivers still use this.
-+ * Once they are using cfb->fb.var, this can be dropped.
-+ * --rmk
-+ */
-+ display->var = cfb->fb.var;
-+
-+ /*
-+ * If we are setting all the virtual consoles, also set the
-+ * defaults used to create new consoles.
-+ */
-+ if (var->activate & FB_ACTIVATE_ALL)
-+ cfb->fb.disp->var = cfb->fb.var;
-+
-+ if (chgvar && info && cfb->fb.changevar)
-+ cfb->fb.changevar(con);
-+
-+ lcdcon = (var->xres_virtual * var->yres_virtual * var->bits_per_pixel) / 128 - 1;
-+ lcdcon |= ((var->xres_virtual / 16) - 1) << 13;
-+ lcdcon |= lcd_ac_prescale << 25;
-+
-+ /*
-+ * Calculate pixel prescale value from the pixclock. This is:
-+ * 36.864MHz / pixclock_mhz - 1.
-+ * However, pixclock is in picoseconds, so this ends up being:
-+ * 36864000 * pixclock_ps / 10^12 - 1
-+ * and this will overflow the 32-bit math. We perform this as
-+ * (9 * 4096000 == 36864000):
-+ * pixclock_ps * 9 * (4096000 / 10^12) - 1
-+ */
-+ pixclock = 9 * info->var.pixclock / 244140 - 1;
-+ lcdcon |= pixclock << 19;
-+
-+ if (info->var.bits_per_pixel == 4)
-+ lcdcon |= LCDCON_GSMD;
-+ if (info->var.bits_per_pixel >= 2)
-+ lcdcon |= LCDCON_GSEN;
-+
-+ /*
-+ * LCDCON must only be changed while the LCD is disabled
-+ */
-+ syscon = clps_readl(SYSCON1);
-+ clps_writel(syscon & ~SYSCON1_LCDEN, SYSCON1);
-+ clps_writel(lcdcon, LCDCON);
-+ clps_writel(syscon | SYSCON1_LCDEN, SYSCON1);
-+
-+ fb_set_cmap(&cfb->fb.cmap, 1, clps7111fb_setcolreg, &cfb->fb);
-+
-+ return 0;
-+}
-+
-+/*
-+ * Get the currently displayed virtual consoles colormap.
-+ */
-+static int
-+gen_get_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
-+{
-+ fb_copy_cmap(&info->cmap, cmap, kspc ? 0 : 2);
-+ return 0;
-+}
-+
-+/*
-+ * Get the currently displayed virtual consoles fixed part of the display.
-+ */
-+static int
-+gen_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
-+{
-+ *fix = info->fix;
-+ return 0;
-+}
-+
-+/*
-+ * Get the current user defined part of the display.
-+ */
-+static int
-+gen_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-+{
-+ *var = info->var;
-+ return 0;
-+}
-+
-+static struct fb_ops clps7111fb_ops = {
-+ owner: THIS_MODULE,
-+ fb_set_var: clps7111fb_set_var,
-+ fb_set_cmap: clps7111fb_set_cmap,
-+ fb_get_fix: gen_get_fix,
-+ fb_get_var: gen_get_var,
-+ fb_get_cmap: gen_get_cmap,
-+};
-+
-+static int clps7111fb_switch(int con, struct fb_info *info)
-+{
-+ struct clps7111fb_info *cfb = (struct clps7111fb_info *)info;
-+ struct display *disp;
-+ struct fb_cmap *cmap;
-+
-+ if (cfb->currcon >= 0) {
-+ disp = fb_display + cfb->currcon;
-+
-+ /*
-+ * Save the old colormap and video mode.
-+ */
-+ disp->var = cfb->fb.var;
-+ if (disp->cmap.len)
-+ fb_copy_cmap(&cfb->fb.cmap, &disp->cmap, 0);
-+ }
-+
-+ cfb->currcon = con;
-+ disp = fb_display + con;
-+
-+ /*
-+ * Install the new colormap and change the video mode. By default,
-+ * fbcon sets all the colormaps and video modes to the default
-+ * values at bootup.
-+ */
-+ if (disp->cmap.len)
-+ cmap = &disp->cmap;
-+ else
-+ cmap = fb_default_cmap(CMAP_MAX_SIZE);
-+
-+ fb_copy_cmap(cmap, &cfb->fb.cmap, 0);
-+
-+ cfb->fb.var = disp->var;
-+ cfb->fb.var.activate = FB_ACTIVATE_NOW;
-+
-+ clps7111fb_set_var(&cfb->fb.var, con, &cfb->fb);
-+
-+ return 0;
-+}
-+
-+static int clps7111fb_updatevar(int con, struct fb_info *info)
-+{
-+ return -EINVAL;
-+}
-+
-+static void clps7111fb_blank(int blank, struct fb_info *info)
-+{
-+ if (blank) {
-+ if (machine_is_edb7211()) {
-+ /* Turn off the LCD backlight. */
-+ clps_writeb(clps_readb(PDDR) & ~EDB_PD3_LCDBL, PDDR);
-+
-+ /* Power off the LCD DC-DC converter. */
-+ clps_writeb(clps_readb(PDDR) & ~EDB_PD1_LCD_DC_DC_EN, PDDR);
-+
-+ /* Delay for a little while (half a second). */
-+ udelay(100);
-+
-+ /* Power off the LCD panel. */
-+ clps_writeb(clps_readb(PDDR) & ~EDB_PD2_LCDEN, PDDR);
-+
-+ /* Power off the LCD controller. */
-+ clps_writel(clps_readl(SYSCON1) & ~SYSCON1_LCDEN,
-+ SYSCON1);
-+ }
-+ } else {
-+ if (machine_is_edb7211()) {
-+ /* Power up the LCD controller. */
-+ clps_writel(clps_readl(SYSCON1) | SYSCON1_LCDEN,
-+ SYSCON1);
-+
-+ /* Power up the LCD panel. */
-+ clps_writeb(clps_readb(PDDR) | EDB_PD2_LCDEN, PDDR);
-+
-+ /* Delay for a little while. */
-+ udelay(100);
-+
-+ /* Power up the LCD DC-DC converter. */
-+ clps_writeb(clps_readb(PDDR) | EDB_PD1_LCD_DC_DC_EN,
-+ PDDR);
-+
-+ /* Turn on the LCD backlight. */
-+ clps_writeb(clps_readb(PDDR) | EDB_PD3_LCDBL, PDDR);
-+ }
-+ }
-+}
-+
-+static int
-+clps7111fb_proc_backlight_read(char *page, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ /* We need at least two characters, one for the digit, and one for
-+ * the terminating NULL. */
-+ if (count < 2)
-+ return -EINVAL;
-+
-+ if (machine_is_edb7211()) {
-+ return sprintf(page, "%d\n",
-+ (clps_readb(PDDR) & EDB_PD3_LCDBL) ? 1 : 0);
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+clps7111fb_proc_backlight_write(struct file *file, const char *buffer,
-+ unsigned long count, void *data)
-+{
-+ unsigned char char_value;
-+ int value;
-+
-+ if (count < 1) {
-+ return -EINVAL;
-+ }
-+
-+ if (copy_from_user(&char_value, buffer, 1))
-+ return -EFAULT;
-+
-+ value = char_value - '0';
-+
-+ if (machine_is_edb7211()) {
-+ unsigned char port_d;
-+
-+ port_d = clps_readb(PDDR);
-+
-+ if (value) {
-+ port_d |= EDB_PD3_LCDBL;
-+ } else {
-+ port_d &= ~EDB_PD3_LCDBL;
-+ }
-+
-+ clps_writeb(port_d, PDDR);
-+ }
-+
-+ return count;
-+}
-+
-+static void __init clps711x_guess_lcd_params(struct fb_info *info)
-+{
-+ unsigned int lcdcon, syscon, size;
-+ unsigned long phys_base = PHYS_OFFSET;
-+ void *virt_base = (void *)PAGE_OFFSET;
-+
-+ info->var.xres_virtual = 640;
-+ info->var.yres_virtual = 240;
-+ info->var.bits_per_pixel = 4;
-+ info->var.activate = FB_ACTIVATE_NOW;
-+ info->var.height = -1;
-+ info->var.width = -1;
-+ info->var.pixclock = 93006; /* 10.752MHz pixel clock */
-+
-+ /*
-+ * If the LCD controller is already running, decode the values
-+ * in LCDCON to xres/yres/bpp/pixclock/acprescale
-+ */
-+ syscon = clps_readl(SYSCON1);
-+ if (syscon & SYSCON1_LCDEN) {
-+ lcdcon = clps_readl(LCDCON);
-+
-+ /*
-+ * Decode GSMD and GSEN bits to bits per pixel
-+ * (in cs89712 docs, GSEN is GSMD1, GSMD is GSMD2)
-+ */
-+ switch (lcdcon & (LCDCON_GSMD | LCDCON_GSEN)) {
-+ case LCDCON_GSMD | LCDCON_GSEN:
-+ info->var.bits_per_pixel = 4;
-+ break;
-+
-+ case LCDCON_GSEN:
-+ info->var.bits_per_pixel = 2;
-+ break;
-+
-+ default:
-+ info->var.bits_per_pixel = 1;
-+ break;
-+ }
-+
-+ /*
-+ * Decode xres/yres
-+ */
-+ info->var.xres_virtual = (((lcdcon >> 13) & 0x3f) + 1) * 16;
-+ info->var.yres_virtual = (((lcdcon & 0x1fff) + 1) * 128) /
-+ (info->var.xres_virtual *
-+ info->var.bits_per_pixel);
-+
-+ /*
-+ * Calculate pixclock
-+ */
-+ info->var.pixclock = (((lcdcon >> 19) & 0x3f) + 1) * 244140 / 9;
-+
-+ /*
-+ * Grab AC prescale
-+ */
-+ lcd_ac_prescale = (lcdcon >> 25) & 0x1f;
-+ }
-+
-+ info->var.xres = info->var.xres_virtual;
-+ info->var.yres = info->var.yres_virtual;
-+ info->var.grayscale = info->var.bits_per_pixel > 1;
-+
-+ size = info->var.xres * info->var.yres * info->var.bits_per_pixel / 8;
-+
-+ /*
-+ * Might be worth checking to see if we can use the on-board
-+ * RAM if size here...
-+ * CLPS7110 - no on-board SRAM
-+ * EP7212 - 38400 bytes
-+ */
-+ if (size <= 38400) {
-+ printk(KERN_INFO "CLPS711xFB: could use on-board SRAM?\n");
-+ }
-+
-+ if ((syscon & SYSCON1_LCDEN) == 0) {
-+ /*
-+ * The display isn't running. Ensure that
-+ * the display memory is empty.
-+ */
-+ memset(virt_base, 0, size);
-+ }
-+
-+ info->screen_base = virt_base;
-+ info->fix.smem_start = phys_base;
-+ info->fix.smem_len = PAGE_ALIGN(size);
-+ info->fix.type = FB_TYPE_PACKED_PIXELS;
-+}
-+
-+/* this function initializes the LCD registers as required by the Guide A07
-+*/
-+int __init clps711xfb_guidea07_init(void)
-+{
-+ unsigned long videomem, videosize;
-+ unsigned int lcdcon, syscon;
-+
-+ //LCDCON must only be changed while the LCD is disabled
-+ syscon = clps_readl(SYSCON1);
-+ clps_writel(syscon & ~SYSCON1_LCDEN, SYSCON1);
-+
-+ printk(KERN_INFO "CLPS711xFB: setting up cs89712 SRAM as QVGA video framebuffer\n");
-+ clps_writel(0x6, FBADDR); //internal SRAM location
-+ videomem = (unsigned long)ioremap(SRAM_START, SRAM_SIZE);
-+ if (!videomem) {
-+ printk("ioremap failed!\n");
-+ kfree(cfb);
-+ return -EIO;
-+ }
-+
-+ videosize = (320*240 * 4 / 8); //ie. 38400 or 0x9600
-+ memset((void *)videomem, 0, videosize); //clear the vid memory
-+
-+ cfb->fb.screen_base = (void *)videomem;
-+ cfb->fb.fix.smem_start = SRAM_START; //must be physical address
-+ cfb->fb.fix.smem_len = videosize;
-+
-+ cfb->fb.var.grayscale = 1;
-+ cfb->fb.var.bits_per_pixel = 4;
-+ cfb->fb.var.xres_virtual = 320;
-+ cfb->fb.var.activate = FB_ACTIVATE_NOW;
-+
-+ // change to 4bpp mode
-+ lcdcon = clps_readl(LCDCON);
-+ lcdcon |= LCDCON_GSMD | LCDCON_GSEN; //4bpp
-+ //lcdcon |= 5 << 19; //pixel prescale value (pixclock)
-+ //lcdcon |= 13 << 25; //AC prescale value
-+ clps_writel(lcdcon, LCDCON);
-+
-+ //reenable LCD
-+ clps_writel(syscon | SYSCON1_LCDEN, SYSCON1);
-+
-+ return 0;
-+}
-+
-+int __init clps711xfb_init(void)
-+{
-+ int err = -ENOMEM;
-+
-+ cfb = kmalloc(sizeof(*cfb) + sizeof(struct display), GFP_KERNEL);
-+ if (!cfb)
-+ goto out;
-+
-+ memset(cfb, 0, sizeof(*cfb) + sizeof(struct display));
-+ strcpy(cfb->fb.fix.id, "clps7111");
-+
-+ cfb->currcon = -1;
-+ cfb->fb.screen_base = (void *)PAGE_OFFSET;
-+ cfb->fb.fix.smem_start = PAGE_OFFSET;
-+ cfb->fb.fix.smem_len = 0x14000;
-+ cfb->fb.fix.type = FB_TYPE_PACKED_PIXELS;
-+
-+ cfb->fb.fbops = &clps7111fb_ops;
-+ cfb->fb.changevar = NULL;
-+ cfb->fb.switch_con = clps7111fb_switch;
-+ cfb->fb.updatevar = clps7111fb_updatevar;
-+ cfb->fb.blank = clps7111fb_blank;
-+ cfb->fb.flags = FBINFO_FLAG_DEFAULT;
-+ cfb->fb.disp = (struct display *)(cfb + 1);
-+
-+ clps711x_guess_lcd_params(&cfb->fb);
-+
-+ if (machine_is_guidea07()) {
-+ clps711xfb_guidea07_init();
-+ }
-+
-+ if (machine_is_fortunet()) {
-+ cfb->fb.fix.smem_len = 0x20000;
-+ }
-+
-+ fb_alloc_cmap(&cfb->fb.cmap, CMAP_MAX_SIZE, 0);
-+
-+ /* Register the /proc entries. */
-+ clps7111fb_backlight_proc_entry = create_proc_entry("backlight", 0444,
-+ &proc_root);
-+ if (clps7111fb_backlight_proc_entry == NULL) {
-+ printk("Couldn't create the /proc entry for the backlight.\n");
-+ return -EINVAL;
-+ }
-+
-+ clps7111fb_backlight_proc_entry->read_proc =
-+ &clps7111fb_proc_backlight_read;
-+ clps7111fb_backlight_proc_entry->write_proc =
-+ &clps7111fb_proc_backlight_write;
-+
-+ /*
-+ * Power up the LCD
-+ */
-+ if (machine_is_p720t()) {
-+ PLD_LCDEN = PLD_LCDEN_EN;
-+ PLD_PWR |= (PLD_S4_ON|PLD_S3_ON|PLD_S2_ON|PLD_S1_ON);
-+ }
-+
-+ if (machine_is_edb7211()) {
-+ /* Power up the LCD panel. */
-+ clps_writeb(clps_readb(PDDR) | EDB_PD2_LCDEN, PDDR);
-+
-+ /* Delay for a little while. */
-+ udelay(100);
-+
-+ /* Power up the LCD DC-DC converter. */
-+ clps_writeb(clps_readb(PDDR) | EDB_PD1_LCD_DC_DC_EN, PDDR);
-+
-+ /* Turn on the LCD backlight. */
-+ clps_writeb(clps_readb(PDDR) | EDB_PD3_LCDBL, PDDR);
-+ }
-+
-+ clps7111fb_set_var(&cfb->fb.var, -1, &cfb->fb);
-+ err = register_framebuffer(&cfb->fb);
-+
-+out: return err;
-+}
-+
-+static void __exit clps711xfb_exit(void)
-+{
-+ unregister_framebuffer(&cfb->fb);
-+ kfree(cfb);
-+
-+ /*
-+ * Power down the LCD
-+ */
-+ if (machine_is_p720t()) {
-+ PLD_LCDEN = 0;
-+ PLD_PWR &= ~(PLD_S4_ON|PLD_S3_ON|PLD_S2_ON|PLD_S1_ON);
-+ }
-+}
-+
-+#ifdef MODULE
-+module_init(clps711xfb_init);
-+#endif
-+module_exit(clps711xfb_exit);
-+
-+MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-+MODULE_DESCRIPTION("CLPS711x framebuffer driver");
-+MODULE_LICENSE("GPL");
---- linux-2.4.25/drivers/video/cyber2000fb.c~2.4.25-vrs2.patch 2002-08-03 02:39:45.000000000 +0200
-+++ linux-2.4.25/drivers/video/cyber2000fb.c 2004-03-31 17:15:09.000000000 +0200
-@@ -1,7 +1,7 @@
- /*
- * linux/drivers/video/cyber2000fb.c
- *
-- * Copyright (C) 1998-2000 Russell King
-+ * Copyright (C) 1998-2002 Russell King
- *
- * MIPS and 50xx clock support
- * Copyright (C) 2001 Bradley D. LaRonde <brad@ltc.com>
-@@ -13,22 +13,28 @@
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-- * Intergraphics CyberPro 2000, 2010 and 5000 frame buffer device
-+ * Integraphics CyberPro 2000, 2010 and 5000 frame buffer device
- *
- * Based on cyberfb.c.
- *
-- * Note that we now use the new fbcon fix, var and cmap scheme. We do still
-- * have to check which console is the currently displayed one however, since
-- * especially for the colourmap stuff. Once fbcon has been fully migrated,
-- * we can kill the last 5 references to cfb->currcon.
-+ * Note that we now use the new fbcon fix, var and cmap scheme. We do
-+ * still have to check which console is the currently displayed one
-+ * however, especially for the colourmap stuff.
- *
-- * We also use the new hotplug PCI subsystem. I'm not sure if there are any
-- * such cards, but I'm erring on the side of caution. We don't want to go
-- * pop just because someone does have one.
-+ * We also use the new hotplug PCI subsystem. I'm not sure if there
-+ * are any such cards, but I'm erring on the side of caution. We don't
-+ * want to go pop just because someone does have one.
- *
-- * Note that this doesn't work fully in the case of multiple CyberPro cards
-- * with grabbers. We currently can only attach to the first CyberPro card
-- * found.
-+ * Note that this doesn't work fully in the case of multiple CyberPro
-+ * cards with grabbers. We currently can only attach to the first
-+ * CyberPro card found.
-+ *
-+ * When we're in truecolour mode, we power down the LUT RAM as a power
-+ * saving feature. Also, when we enter any of the powersaving modes
-+ * (except soft blanking) we power down the RAMDACs. This saves about
-+ * 1W, which is roughly 8% of the power consumption of a NetWinder
-+ * (which, incidentally, is about the same saving as a 2.5in hard disk
-+ * entering standby mode.)
- */
- #include <linux/config.h>
- #include <linux/module.h>
-@@ -55,20 +61,16 @@
- #include <video/fbcon-cfb24.h>
- #include <video/fbcon-cfb32.h>
-
--/*
-- * Define this if you don't want RGB565, but RGB555 for 16bpp displays.
-- */
--/*#define CFB16_IS_CFB15*/
--
- #include "cyber2000fb.h"
-
- struct cfb_info {
- struct fb_info fb;
- struct display_switch *dispsw;
-+ struct display *display;
- struct pci_dev *dev;
- unsigned char *region;
- unsigned char *regs;
-- signed int currcon;
-+ u_int id;
- int func_use_count;
- u_long ref_ps;
-
-@@ -81,10 +83,16 @@
- u8 red, green, blue;
- } palette[NR_PALETTE];
-
-+ u_char mem_ctl0;
- u_char mem_ctl1;
- u_char mem_ctl2;
- u_char mclk_mult;
- u_char mclk_div;
-+ /*
-+ * RAMDAC control register is both of these or'ed together
-+ */
-+ u_char ramdac_ctrl;
-+ u_char ramdac_powerdown;
- };
-
- static char default_font_storage[40];
-@@ -144,7 +152,7 @@
- {
- int count = 100000;
-
-- while (cyber2000fb_readb(CO_REG_CONTROL, cfb) & 0x80) {
-+ while (cyber2000fb_readb(CO_REG_CONTROL, cfb) & CO_CTRL_BUSY) {
- if (!count--) {
- debug_printf("accel_wait timed out\n");
- cyber2000fb_writeb(0, CO_REG_CONTROL, cfb);
-@@ -154,24 +162,23 @@
- }
- }
-
--static void cyber2000_accel_setup(struct display *p)
-+static void cyber2000_accel_setup(struct display *display)
- {
-- struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
-+ struct cfb_info *cfb = (struct cfb_info *)display->fb_info;
-
-- cfb->dispsw->setup(p);
-+ cfb->dispsw->setup(display);
- }
-
- static void
--cyber2000_accel_bmove(struct display *p, int sy, int sx, int dy, int dx,
-+cyber2000_accel_bmove(struct display *display, int sy, int sx, int dy, int dx,
- int height, int width)
- {
-- struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
-- struct fb_var_screeninfo *var = &p->fb_info->var;
-+ struct cfb_info *cfb = (struct cfb_info *)display->fb_info;
-+ struct fb_var_screeninfo *var = &display->var;
- u_long src, dst;
-- u_int fh, fw;
-- int cmd = CO_CMD_L_PATTERN_FGCOL;
-+ u_int fh, fw, cmd = CO_CMD_L_PATTERN_FGCOL;
-
-- fw = fontwidth(p);
-+ fw = fontwidth(display);
- sx *= fw;
- dx *= fw;
- width *= fw;
-@@ -183,7 +190,7 @@
- cmd |= CO_CMD_L_INC_LEFT;
- }
-
-- fh = fontheight(p);
-+ fh = fontheight(display);
- sy *= fh;
- dy *= fh;
- height *= fh;
-@@ -199,227 +206,265 @@
- dst = dx + dy * var->xres_virtual;
-
- cyber2000_accel_wait(cfb);
-- cyber2000fb_writeb(0x00, CO_REG_CONTROL, cfb);
-- cyber2000fb_writeb(0x03, CO_REG_FORE_MIX, cfb);
-- cyber2000fb_writew(width, CO_REG_WIDTH, cfb);
-+ cyber2000fb_writeb(0x00, CO_REG_CONTROL, cfb);
-+ cyber2000fb_writew(width, CO_REG_PIXWIDTH, cfb);
-+ cyber2000fb_writew(height, CO_REG_PIXHEIGHT, cfb);
-
-- if (var->bits_per_pixel != 24) {
-- cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
-- cyber2000fb_writel(src, CO_REG_SRC_PTR, cfb);
-- } else {
-- cyber2000fb_writel(dst * 3, CO_REG_DEST_PTR, cfb);
-- cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
-- cyber2000fb_writel(src * 3, CO_REG_SRC_PTR, cfb);
-+ if (var->bits_per_pixel == 24) {
-+ cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
-+ dst *= 3;
-+ src *= 3;
- }
-
-- cyber2000fb_writew(height, CO_REG_HEIGHT, cfb);
-- cyber2000fb_writew(cmd, CO_REG_CMD_L, cfb);
-- cyber2000fb_writew(0x2800, CO_REG_CMD_H, cfb);
-+ cyber2000fb_writel(src, CO_REG_SRC1_PTR, cfb);
-+ cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
-+ cyber2000fb_writeb(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb);
-+ cyber2000fb_writew(cmd, CO_REG_CMD_L, cfb);
-+ cyber2000fb_writew(CO_CMD_H_FGSRCMAP|CO_CMD_H_BLITTER, CO_REG_CMD_H, cfb);
- }
-
- static void
--cyber2000_accel_clear(struct vc_data *conp, struct display *p, int sy, int sx,
-- int height, int width)
-+cyber2000_accel_clear(struct vc_data *conp, struct display *display, int sy,
-+ int sx, int height, int width)
- {
-- struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
-- struct fb_var_screeninfo *var = &p->fb_info->var;
-+ struct cfb_info *cfb = (struct cfb_info *)display->fb_info;
-+ struct fb_var_screeninfo *var = &display->var;
- u_long dst;
- u_int fw, fh;
-- u32 bgx = attr_bgcol_ec(p, conp);
-+ u32 bgx = attr_bgcol_ec(display, conp);
-
-- fw = fontwidth(p);
-- fh = fontheight(p);
-+ fw = fontwidth(display);
-+ fh = fontheight(display);
-
- dst = sx * fw + sy * var->xres_virtual * fh;
- width = width * fw - 1;
- height = height * fh - 1;
-
- cyber2000_accel_wait(cfb);
-- cyber2000fb_writeb(0x00, CO_REG_CONTROL, cfb);
-- cyber2000fb_writeb(0x03, CO_REG_FORE_MIX, cfb);
-- cyber2000fb_writew(width, CO_REG_WIDTH, cfb);
-- cyber2000fb_writew(height, CO_REG_HEIGHT, cfb);
--
-- switch (var->bits_per_pixel) {
-- case 15:
-- case 16:
-- bgx = ((u16 *)p->dispsw_data)[bgx];
-- case 8:
-- cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
-- break;
-+ cyber2000fb_writeb(0x00, CO_REG_CONTROL, cfb);
-+ cyber2000fb_writew(width, CO_REG_PIXWIDTH, cfb);
-+ cyber2000fb_writew(height, CO_REG_PIXHEIGHT, cfb);
-
-- case 24:
-- cyber2000fb_writel(dst * 3, CO_REG_DEST_PTR, cfb);
-+ if (var->bits_per_pixel == 24) {
- cyber2000fb_writeb(dst, CO_REG_X_PHASE, cfb);
-- bgx = ((u32 *)p->dispsw_data)[bgx];
-- break;
--
-- case 32:
-- bgx = ((u32 *)p->dispsw_data)[bgx];
-- cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
-- break;
-+ dst *= 3;
- }
-
-- cyber2000fb_writel(bgx, CO_REG_FOREGROUND, cfb);
-+ if (var->bits_per_pixel == 16)
-+ bgx = ((u16 *)display->dispsw_data)[bgx];
-+ else if (var->bits_per_pixel >= 24)
-+ bgx = ((u32 *)display->dispsw_data)[bgx];
-+
-+ cyber2000fb_writel(bgx, CO_REG_FGCOLOUR, cfb);
-+ cyber2000fb_writel(dst, CO_REG_DEST_PTR, cfb);
-+ cyber2000fb_writeb(CO_FG_MIX_SRC, CO_REG_FGMIX, cfb);
- cyber2000fb_writew(CO_CMD_L_PATTERN_FGCOL, CO_REG_CMD_L, cfb);
-- cyber2000fb_writew(0x0800, CO_REG_CMD_H, cfb);
-+ cyber2000fb_writew(CO_CMD_H_BLITTER, CO_REG_CMD_H, cfb);
- }
-
- static void
--cyber2000_accel_putc(struct vc_data *conp, struct display *p, int c,
-+cyber2000_accel_putc(struct vc_data *conp, struct display *display, int c,
- int yy, int xx)
- {
-- struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
-+ struct cfb_info *cfb = (struct cfb_info *)display->fb_info;
-
- cyber2000_accel_wait(cfb);
-- cfb->dispsw->putc(conp, p, c, yy, xx);
-+ cfb->dispsw->putc(conp, display, c, yy, xx);
- }
-
- static void
--cyber2000_accel_putcs(struct vc_data *conp, struct display *p,
-+cyber2000_accel_putcs(struct vc_data *conp, struct display *display,
- const unsigned short *s, int count, int yy, int xx)
- {
-- struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
-+ struct cfb_info *cfb = (struct cfb_info *)display->fb_info;
-
- cyber2000_accel_wait(cfb);
-- cfb->dispsw->putcs(conp, p, s, count, yy, xx);
-+ cfb->dispsw->putcs(conp, display, s, count, yy, xx);
- }
-
--static void cyber2000_accel_revc(struct display *p, int xx, int yy)
-+static void cyber2000_accel_revc(struct display *display, int xx, int yy)
- {
-- struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
-+ struct cfb_info *cfb = (struct cfb_info *)display->fb_info;
-
- cyber2000_accel_wait(cfb);
-- cfb->dispsw->revc(p, xx, yy);
-+ cfb->dispsw->revc(display, xx, yy);
- }
-
- static void
--cyber2000_accel_clear_margins(struct vc_data *conp, struct display *p,
-+cyber2000_accel_clear_margins(struct vc_data *conp, struct display *display,
- int bottom_only)
- {
-- struct cfb_info *cfb = (struct cfb_info *)p->fb_info;
-+ struct cfb_info *cfb = (struct cfb_info *)display->fb_info;
-
-- cfb->dispsw->clear_margins(conp, p, bottom_only);
-+ cfb->dispsw->clear_margins(conp, display, bottom_only);
- }
-
- static struct display_switch fbcon_cyber_accel = {
-- setup: cyber2000_accel_setup,
-- bmove: cyber2000_accel_bmove,
-- clear: cyber2000_accel_clear,
-- putc: cyber2000_accel_putc,
-- putcs: cyber2000_accel_putcs,
-- revc: cyber2000_accel_revc,
-- clear_margins: cyber2000_accel_clear_margins,
-- fontwidthmask: FONTWIDTH(8)|FONTWIDTH(16)
-+ .setup = cyber2000_accel_setup,
-+ .bmove = cyber2000_accel_bmove,
-+ .clear = cyber2000_accel_clear,
-+ .putc = cyber2000_accel_putc,
-+ .putcs = cyber2000_accel_putcs,
-+ .revc = cyber2000_accel_revc,
-+ .clear_margins = cyber2000_accel_clear_margins,
-+ .fontwidthmask = FONTWIDTH(8)|FONTWIDTH(16)
- };
-
-+static inline u32 convert_bitfield(u_int val, struct fb_bitfield *bf)
-+{
-+ u_int mask = (1 << bf->length) - 1;
-+
-+ return (val >> (16 - bf->length) & mask) << bf->offset;
-+}
-+
- /*
- * Set a single color register. Return != 0 for invalid regno.
- */
- static int
--cyber2000_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-- u_int transp, struct fb_info *info)
-+cyber2000fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-+ u_int transp, struct fb_info *info)
- {
- struct cfb_info *cfb = (struct cfb_info *)info;
-+ struct fb_var_screeninfo *var = &cfb->display->var;
-+ u32 pseudo_val;
-+ int ret = 1;
-
-- u_int alpha = transp ^ 0xFFFF;
--
-- if (regno >= NR_PALETTE)
-+ switch (cfb->fb.fix.visual) {
-+ default:
- return 1;
-
-- red >>= 8;
-- green >>= 8;
-- blue >>= 8;
-- alpha >>= 8;
-+#ifdef FBCON_HAS_CFB8
-+ /*
-+ * Pseudocolour:
-+ * 8 8
-+ * pixel --/--+--/--> red lut --> red dac
-+ * | 8
-+ * +--/--> green lut --> green dac
-+ * | 8
-+ * +--/--> blue lut --> blue dac
-+ */
-+ case FB_VISUAL_PSEUDOCOLOR:
-+ if (regno >= NR_PALETTE)
-+ return 1;
-
-- cfb->palette[regno].red = red;
-- cfb->palette[regno].green = green;
-- cfb->palette[regno].blue = blue;
-+ red >>= 8;
-+ green >>= 8;
-+ blue >>= 8;
-+
-+ cfb->palette[regno].red = red;
-+ cfb->palette[regno].green = green;
-+ cfb->palette[regno].blue = blue;
-
-- switch (cfb->fb.var.bits_per_pixel) {
--#ifdef FBCON_HAS_CFB8
-- case 8:
- cyber2000fb_writeb(regno, 0x3c8, cfb);
-- cyber2000fb_writeb(red, 0x3c9, cfb);
-+ cyber2000fb_writeb(red, 0x3c9, cfb);
- cyber2000fb_writeb(green, 0x3c9, cfb);
-- cyber2000fb_writeb(blue, 0x3c9, cfb);
-- break;
-+ cyber2000fb_writeb(blue, 0x3c9, cfb);
-+ return 0;
- #endif
-
--#ifdef FBCON_HAS_CFB16
-- case 16:
--#ifndef CFB16_IS_CFB15
-- if (regno < 64) {
-- /* write green */
-+ /*
-+ * Direct colour:
-+ * n rl
-+ * pixel --/--+--/--> red lut --> red dac
-+ * | gl
-+ * +--/--> green lut --> green dac
-+ * | bl
-+ * +--/--> blue lut --> blue dac
-+ * n = bpp, rl = red length, gl = green length, bl = blue length
-+ */
-+ case FB_VISUAL_DIRECTCOLOR:
-+ red >>= 8;
-+ green >>= 8;
-+ blue >>= 8;
-+
-+ if (var->green.length == 6 && regno < 64) {
-+ cfb->palette[regno << 2].green = green;
-+
-+ /*
-+ * The 6 bits of the green component are applied
-+ * to the high 6 bits of the LUT.
-+ */
- cyber2000fb_writeb(regno << 2, 0x3c8, cfb);
- cyber2000fb_writeb(cfb->palette[regno >> 1].red, 0x3c9, cfb);
- cyber2000fb_writeb(green, 0x3c9, cfb);
- cyber2000fb_writeb(cfb->palette[regno >> 1].blue, 0x3c9, cfb);
-+
-+ green = cfb->palette[regno << 3].green;
-+
-+ ret = 0;
- }
-
-- if (regno < 32) {
-- /* write red,blue */
-+ if (var->green.length >= 5 && regno < 32) {
-+ cfb->palette[regno << 3].red = red;
-+ cfb->palette[regno << 3].green = green;
-+ cfb->palette[regno << 3].blue = blue;
-+
-+ /*
-+ * The 5 bits of each colour component are
-+ * applied to the high 5 bits of the LUT.
-+ */
- cyber2000fb_writeb(regno << 3, 0x3c8, cfb);
- cyber2000fb_writeb(red, 0x3c9, cfb);
-- cyber2000fb_writeb(cfb->palette[regno << 1].green, 0x3c9, cfb);
-+ cyber2000fb_writeb(green, 0x3c9, cfb);
- cyber2000fb_writeb(blue, 0x3c9, cfb);
-+ ret = 0;
- }
-
-- if (regno < 16)
-- ((u16 *)cfb->fb.pseudo_palette)[regno] =
-- ((red << 8) & 0xf800) |
-- ((green << 3) & 0x07e0) |
-- ((blue >> 3));
-- break;
--#endif
-+ if (var->green.length == 4 && regno < 16) {
-+ cfb->palette[regno << 4].red = red;
-+ cfb->palette[regno << 4].green = green;
-+ cfb->palette[regno << 4].blue = blue;
-
-- case 15:
-- if (regno < 32) {
-- cyber2000fb_writeb(regno << 3, 0x3c8, cfb);
-+ /*
-+ * The 5 bits of each colour component are
-+ * applied to the high 5 bits of the LUT.
-+ */
-+ cyber2000fb_writeb(regno << 4, 0x3c8, cfb);
- cyber2000fb_writeb(red, 0x3c9, cfb);
- cyber2000fb_writeb(green, 0x3c9, cfb);
- cyber2000fb_writeb(blue, 0x3c9, cfb);
-+ ret = 0;
- }
-- if (regno < 16)
-- ((u16 *)cfb->fb.pseudo_palette)[regno] =
-- ((red << 7) & 0x7c00) |
-- ((green << 2) & 0x03e0) |
-- ((blue >> 3));
-- break;
--
--#endif
--
--#ifdef FBCON_HAS_CFB24
-- case 24:
-- cyber2000fb_writeb(regno, 0x3c8, cfb);
-- cyber2000fb_writeb(red, 0x3c9, cfb);
-- cyber2000fb_writeb(green, 0x3c9, cfb);
-- cyber2000fb_writeb(blue, 0x3c9, cfb);
-
-- if (regno < 16)
-- ((u32 *)cfb->fb.pseudo_palette)[regno] =
-- (red << 16) | (green << 8) | blue;
-+ /*
-+ * Since this is only used for the first 16 colours, we
-+ * don't have to care about overflowing for regno >= 32
-+ */
-+ pseudo_val = regno << var->red.offset |
-+ regno << var->green.offset |
-+ regno << var->blue.offset;
- break;
--#endif
-
--#ifdef FBCON_HAS_CFB32
-- case 32:
-- cyber2000fb_writeb(regno, 0x3c8, cfb);
-- cyber2000fb_writeb(red, 0x3c9, cfb);
-- cyber2000fb_writeb(green, 0x3c9, cfb);
-- cyber2000fb_writeb(blue, 0x3c9, cfb);
--
-- if (regno < 16)
-- ((u32 *)cfb->fb.pseudo_palette)[regno] =
-- (alpha << 24) | (red << 16) | (green << 8) | blue;
-+ /*
-+ * True colour:
-+ * n rl
-+ * pixel --/--+--/--> red dac
-+ * | gl
-+ * +--/--> green dac
-+ * | bl
-+ * +--/--> blue dac
-+ * n = bpp, rl = red length, gl = green length, bl = blue length
-+ */
-+ case FB_VISUAL_TRUECOLOR:
-+ pseudo_val = convert_bitfield(transp ^ 0xffff, &var->transp);
-+ pseudo_val |= convert_bitfield(red, &var->red);
-+ pseudo_val |= convert_bitfield(green, &var->green);
-+ pseudo_val |= convert_bitfield(blue, &var->blue);
- break;
--#endif
-+ }
-
-- default:
-- return 1;
-+ /*
-+ * Now set our pseudo palette for the CFB16/24/32 drivers.
-+ */
-+ if (regno < 16) {
-+ if (var->bits_per_pixel == 16)
-+ ((u16 *)cfb->fb.pseudo_palette)[regno] = pseudo_val;
-+ else
-+ ((u32 *)cfb->fb.pseudo_palette)[regno] = pseudo_val;
-+ ret = 0;
- }
-
-- return 0;
-+ return ret;
- }
-
- struct par_info {
-@@ -428,8 +473,8 @@
- */
- u_char clock_mult;
- u_char clock_div;
-- u_char visualid;
-- u_char pixformat;
-+ u_char extseqmisc;
-+ u_char co_pixfmt;
- u_char crtc_ofl;
- u_char crtc[19];
- u_int width;
-@@ -439,8 +484,7 @@
- /*
- * Other
- */
-- u_char palette_ctrl;
-- u_int vmode;
-+ u_char ramdac;
- };
-
- static const u_char crtc_idx[] = {
-@@ -449,6 +493,18 @@
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18
- };
-
-+static void cyber2000fb_write_ramdac_ctrl(struct cfb_info *cfb)
-+{
-+ unsigned int i;
-+ unsigned int val = cfb->ramdac_ctrl | cfb->ramdac_powerdown;
-+
-+ cyber2000fb_writeb(0x56, 0x3ce, cfb);
-+ i = cyber2000fb_readb(0x3cf, cfb);
-+ cyber2000fb_writeb(i | 4, 0x3cf, cfb);
-+ cyber2000fb_writeb(val, 0x3c6, cfb);
-+ cyber2000fb_writeb(i, 0x3cf, cfb);
-+}
-+
- static void cyber2000fb_set_timing(struct cfb_info *cfb, struct par_info *hw)
- {
- u_int i;
-@@ -480,7 +536,7 @@
- for (i = 0x0a; i < 0x10; i++)
- cyber2000_crtcw(i, 0, cfb);
-
-- cyber2000_grphw(0x11, hw->crtc_ofl, cfb);
-+ cyber2000_grphw(EXT_CRT_VRTOFL, hw->crtc_ofl, cfb);
- cyber2000_grphw(0x00, 0x00, cfb);
- cyber2000_grphw(0x01, 0x00, cfb);
- cyber2000_grphw(0x02, 0x00, cfb);
-@@ -501,30 +557,17 @@
- cyber2000_attrw(0x13, 0x00, cfb);
- cyber2000_attrw(0x14, 0x00, cfb);
-
-- /* woody: set the interlaced bit... */
-- /* FIXME: what about doublescan? */
-- cyber2000fb_writeb(0x11, 0x3ce, cfb);
-- i = cyber2000fb_readb(0x3cf, cfb);
-- if (hw->vmode == FB_VMODE_INTERLACED)
-- i |= 0x20;
-- else
-- i &= ~0x20;
-- cyber2000fb_writeb(i, 0x3cf, cfb);
--
- /* PLL registers */
-- cyber2000_grphw(DCLK_MULT, hw->clock_mult, cfb);
-- cyber2000_grphw(DCLK_DIV, hw->clock_div, cfb);
-- cyber2000_grphw(MCLK_MULT, cfb->mclk_mult, cfb);
-- cyber2000_grphw(MCLK_DIV, cfb->mclk_div, cfb);
-+ cyber2000_grphw(EXT_DCLK_MULT, hw->clock_mult, cfb);
-+ cyber2000_grphw(EXT_DCLK_DIV, hw->clock_div, cfb);
-+ cyber2000_grphw(EXT_MCLK_MULT, cfb->mclk_mult, cfb);
-+ cyber2000_grphw(EXT_MCLK_DIV, cfb->mclk_div, cfb);
- cyber2000_grphw(0x90, 0x01, cfb);
- cyber2000_grphw(0xb9, 0x80, cfb);
- cyber2000_grphw(0xb9, 0x00, cfb);
-
-- cyber2000fb_writeb(0x56, 0x3ce, cfb);
-- i = cyber2000fb_readb(0x3cf, cfb);
-- cyber2000fb_writeb(i | 4, 0x3cf, cfb);
-- cyber2000fb_writeb(hw->palette_ctrl, 0x3c6, cfb);
-- cyber2000fb_writeb(i, 0x3cf, cfb);
-+ cfb->ramdac_ctrl = hw->ramdac;
-+ cyber2000fb_write_ramdac_ctrl(cfb);
-
- cyber2000fb_writeb(0x20, 0x3c0, cfb);
- cyber2000fb_writeb(0xff, 0x3c6, cfb);
-@@ -532,31 +575,32 @@
- cyber2000_grphw(0x14, hw->fetch, cfb);
- cyber2000_grphw(0x15, ((hw->fetch >> 8) & 0x03) |
- ((hw->pitch >> 4) & 0x30), cfb);
-- cyber2000_grphw(0x77, hw->visualid, cfb);
-+ cyber2000_grphw(EXT_SEQ_MISC, hw->extseqmisc, cfb);
-
-- /* make sure we stay in linear mode */
-- cyber2000_grphw(0x33, 0x0d, cfb);
-+// cyber2000_grphw(EXT_BIU_MISC, EXT_BIU_MISC_LIN_ENABLE |
-+// EXT_BIU_MISC_COP_ENABLE |
-+// EXT_BIU_MISC_COP_BFC, cfb);
-
- /*
- * Set up accelerator registers
- */
- cyber2000fb_writew(hw->width, CO_REG_SRC_WIDTH, cfb);
- cyber2000fb_writew(hw->width, CO_REG_DEST_WIDTH, cfb);
-- cyber2000fb_writeb(hw->pixformat, CO_REG_PIX_FORMAT, cfb);
-+ cyber2000fb_writeb(hw->co_pixfmt, CO_REG_PIXFMT, cfb);
- }
-
- static inline int
- cyber2000fb_update_start(struct cfb_info *cfb, struct fb_var_screeninfo *var)
- {
-- u_int base;
--
-- base = var->yoffset * var->xres_virtual + var->xoffset;
-+ u_int base = var->yoffset * var->xres_virtual + var->xoffset;
-
-- /* have to be careful, because bits_per_pixel might be 15
-- in this version of the driver -- dok@directfb.org 2002/06/13 */
-- base *= (var->bits_per_pixel + 7) >> 3;
-+ base *= var->bits_per_pixel;
-
-- base >>= 2;
-+ /*
-+ * Convert to bytes and shift two extra bits because DAC
-+ * can only start on 4 byte aligned data.
-+ */
-+ base >>= 5;
-
- if (base >= 1 << 20)
- return -EINVAL;
-@@ -576,27 +620,20 @@
- struct fb_info *info)
- {
- struct cfb_info *cfb = (struct cfb_info *)info;
-- struct fb_cmap *dcmap = &fb_display[con].cmap;
-+ struct display *display = fb_display + con;
-+ struct fb_cmap *dcmap = &display->cmap;
- int err = 0;
-
- /* no colormap allocated? */
-- if (!dcmap->len) {
-- int size;
--
-- if (cfb->fb.var.bits_per_pixel == 16)
-- size = 32;
-- else
-- size = 256;
--
-- err = fb_alloc_cmap(dcmap, size, 0);
-- }
-+ if (!dcmap->len)
-+ err = fb_alloc_cmap(dcmap, 256, 0);
-
- /*
- * we should be able to remove this test once fbcon has been
- * "improved" --rmk
- */
-- if (!err && con == cfb->currcon) {
-- err = fb_set_cmap(cmap, kspc, cyber2000_setcolreg, &cfb->fb);
-+ if (!err && display == cfb->display) {
-+ err = fb_set_cmap(cmap, kspc, cyber2000fb_setcolreg, &cfb->fb);
- dcmap = &cfb->fb.cmap;
- }
-
-@@ -672,8 +709,9 @@
- hw->crtc[16] = Vblankend;
- hw->crtc[18] = 0xff;
-
-- /* overflow - graphics reg 0x11 */
-- /* 0=VTOTAL:10 1=VDEND:10 2=VRSTART:10 3=VBSTART:10
-+ /*
-+ * overflow - graphics reg 0x11
-+ * 0=VTOTAL:10 1=VDEND:10 2=VRSTART:10 3=VBSTART:10
- * 4=LINECOMP:10 5-IVIDEO 6=FIXCNT
- */
- hw->crtc_ofl =
-@@ -681,7 +719,12 @@
- BIT(Vdispend, 10, 0x01, 1) |
- BIT(Vsyncstart, 10, 0x01, 2) |
- BIT(Vblankstart,10, 0x01, 3) |
-- 1 << 4;
-+ EXT_CRT_VRTOFL_LINECOMP10;
-+
-+ /* woody: set the interlaced bit... */
-+ /* FIXME: what about doublescan? */
-+ if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
-+ hw->crtc_ofl |= EXT_CRT_VRTOFL_INTERLACE;
-
- return 0;
- }
-@@ -787,7 +830,7 @@
- vco = ref_ps * best_div1 / best_mult;
- if ((ref_ps == 40690) && (vco < 5556))
- /* Set VFSEL when VCO > 180MHz (5.556 ps). */
-- hw->clock_div |= DCLK_DIV_VFSEL;
-+ hw->clock_div |= EXT_DCLK_DIV_VFSEL;
-
- return 0;
- }
-@@ -801,58 +844,131 @@
- cyber2000fb_decode_var(struct fb_var_screeninfo *var, struct cfb_info *cfb,
- struct par_info *hw)
- {
-+ unsigned int mem;
- int err;
-
- hw->width = var->xres_virtual;
-- hw->palette_ctrl = 0x06;
-- hw->vmode = var->vmode;
-+ hw->ramdac = RAMDAC_VREFEN | RAMDAC_DAC8BIT;
-+
-+ var->transp.msb_right = 0;
-+ var->red.msb_right = 0;
-+ var->green.msb_right = 0;
-+ var->blue.msb_right = 0;
-
- switch (var->bits_per_pixel) {
- #ifdef FBCON_HAS_CFB8
- case 8: /* PSEUDOCOLOUR, 256 */
-- hw->pixformat = PIXFORMAT_8BPP;
-- hw->visualid = VISUALID_256;
-+ hw->co_pixfmt = CO_PIXFMT_8BPP;
- hw->pitch = hw->width >> 3;
-+ hw->extseqmisc = EXT_SEQ_MISC_8;
-+
-+ var->transp.offset = 0;
-+ var->transp.length = 0;
-+ var->red.offset = 0;
-+ var->red.length = 8;
-+ var->green.offset = 0;
-+ var->green.length = 8;
-+ var->blue.offset = 0;
-+ var->blue.length = 8;
- break;
- #endif
- #ifdef FBCON_HAS_CFB16
-- case 16:/* DIRECTCOLOUR, 64k */
--#ifndef CFB16_IS_CFB15
-- hw->pixformat = PIXFORMAT_16BPP;
-- hw->visualid = VISUALID_64K;
-- hw->pitch = hw->width >> 2;
-- hw->palette_ctrl |= 0x10;
-- break;
--#endif
-- case 15:/* DIRECTCOLOUR, 32k */
-- hw->pixformat = PIXFORMAT_16BPP;
-- hw->visualid = VISUALID_32K;
-+ case 16:/* DIRECTCOLOUR, 64k or 32k */
-+ hw->co_pixfmt = CO_PIXFMT_16BPP;
- hw->pitch = hw->width >> 2;
-- hw->palette_ctrl |= 0x10;
-- break;
-
-+ switch (var->green.length) {
-+ case 6: /* RGB565, 64k */
-+ hw->extseqmisc = EXT_SEQ_MISC_16_RGB565;
-+
-+ var->transp.offset = 0;
-+ var->transp.length = 0;
-+ var->red.offset = 11;
-+ var->red.length = 5;
-+ var->green.offset = 5;
-+ var->green.length = 6;
-+ var->blue.offset = 0;
-+ var->blue.length = 5;
-+ break;
-+
-+ default:
-+ case 5: /* RGB555, 32k */
-+ hw->extseqmisc = EXT_SEQ_MISC_16_RGB555;
-+
-+ var->transp.offset = 0;
-+ var->transp.length = 0;
-+ var->red.offset = 10;
-+ var->red.length = 5;
-+ var->green.offset = 5;
-+ var->green.length = 5;
-+ var->blue.offset = 0;
-+ var->blue.length = 5;
-+ break;
-+
-+ case 4: /* RGB444, 4k + transparency? */
-+ hw->extseqmisc = EXT_SEQ_MISC_16_RGB444;
-+
-+ var->transp.offset = 12;
-+ var->transp.length = 4;
-+ var->red.offset = 8;
-+ var->red.length = 4;
-+ var->green.offset = 4;
-+ var->green.length = 4;
-+ var->blue.offset = 0;
-+ var->blue.length = 4;
-+ break;
-+ }
-+ break;
- #endif
- #ifdef FBCON_HAS_CFB24
- case 24:/* TRUECOLOUR, 16m */
-- hw->pixformat = PIXFORMAT_24BPP;
-- hw->visualid = VISUALID_16M;
-+ hw->co_pixfmt = CO_PIXFMT_24BPP;
- hw->width *= 3;
- hw->pitch = hw->width >> 3;
-- hw->palette_ctrl |= 0x10;
-+ hw->ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
-+ hw->extseqmisc = EXT_SEQ_MISC_24_RGB888;
-+
-+ var->transp.offset = 0;
-+ var->transp.length = 0;
-+ var->red.offset = 16;
-+ var->red.length = 8;
-+ var->green.offset = 8;
-+ var->green.length = 8;
-+ var->blue.offset = 0;
-+ var->blue.length = 8;
- break;
- #endif
- #ifdef FBCON_HAS_CFB32
- case 32:/* TRUECOLOUR, 16m */
-- hw->pixformat = PIXFORMAT_32BPP;
-- hw->visualid = VISUALID_16M_32;
-+ hw->co_pixfmt = CO_PIXFMT_32BPP;
- hw->pitch = hw->width >> 1;
-- hw->palette_ctrl |= 0x10;
-+ hw->ramdac |= (RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
-+ hw->extseqmisc = EXT_SEQ_MISC_32;
-+
-+ var->transp.offset = 24;
-+ var->transp.length = 8;
-+ var->red.offset = 16;
-+ var->red.length = 8;
-+ var->green.offset = 8;
-+ var->green.length = 8;
-+ var->blue.offset = 0;
-+ var->blue.length = 8;
- break;
- #endif
- default:
- return -EINVAL;
- }
-
-+ mem = var->xres_virtual * var->yres_virtual * (var->bits_per_pixel / 8);
-+ if (mem > cfb->fb.fix.smem_len)
-+ var->yres_virtual = cfb->fb.fix.smem_len * 8 /
-+ (var->bits_per_pixel * var->xres_virtual);
-+
-+ if (var->yres > var->yres_virtual)
-+ var->yres = var->yres_virtual;
-+ if (var->xres > var->xres_virtual)
-+ var->xres = var->xres_virtual;
-+
- err = cyber2000fb_decode_clock(hw, cfb, var);
- if (err)
- return err;
-@@ -880,7 +996,7 @@
- struct cfb_info *cfb = (struct cfb_info *)info;
- struct display *display;
- struct par_info hw;
-- int err, chgvar = 0;
-+ int err, chgvar;
-
- /*
- * CONUPDATE and SMOOTH_XPAN are equal. However,
-@@ -888,11 +1004,11 @@
- */
- if (var->vmode & FB_VMODE_CONUPDATE) {
- var->vmode |= FB_VMODE_YWRAP;
-- var->xoffset = cfb->fb.var.xoffset;
-- var->yoffset = cfb->fb.var.yoffset;
-+ var->xoffset = cfb->display->var.xoffset;
-+ var->yoffset = cfb->display->var.yoffset;
- }
-
-- err = cyber2000fb_decode_var(var, (struct cfb_info *)info, &hw);
-+ err = cyber2000fb_decode_var(var, cfb, &hw);
- if (err)
- return err;
-
-@@ -902,105 +1018,61 @@
- if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
- return -EINVAL;
-
-- if (cfb->fb.var.xres != var->xres)
-- chgvar = 1;
-- if (cfb->fb.var.yres != var->yres)
-- chgvar = 1;
-- if (cfb->fb.var.xres_virtual != var->xres_virtual)
-- chgvar = 1;
-- if (cfb->fb.var.yres_virtual != var->yres_virtual)
-- chgvar = 1;
-- if (cfb->fb.var.bits_per_pixel != var->bits_per_pixel)
-- chgvar = 1;
--
- if (con < 0) {
- display = cfb->fb.disp;
-- chgvar = 0;
- } else {
- display = fb_display + con;
- }
-
-- var->red.msb_right = 0;
-- var->green.msb_right = 0;
-- var->blue.msb_right = 0;
-+ chgvar = cfb->fb.var.xres != var->xres ||
-+ cfb->fb.var.yres != var->yres ||
-+ cfb->fb.var.xres_virtual != var->xres_virtual ||
-+ cfb->fb.var.yres_virtual != var->yres_virtual ||
-+ cfb->fb.var.bits_per_pixel != var->bits_per_pixel;
-+
-+ if (memcmp(&cfb->fb.var.red, &var->red, sizeof(var->red)) ||
-+ memcmp(&cfb->fb.var.green, &var->green, sizeof(var->green)) ||
-+ memcmp(&cfb->fb.var.blue, &var->blue, sizeof(var->blue)))
-+ chgvar = 1;
-+
-+ if (con < 0)
-+ chgvar = 0;
-+
-+ /*
-+ * If we are setting all the virtual consoles, also set the
-+ * defaults used to create new consoles.
-+ */
-+ err = var->activate;
-+ var->activate = FB_ACTIVATE_NOW;
-+ if (err & FB_ACTIVATE_ALL)
-+ cfb->fb.disp->var = *var;
-+
-+ cfb->fb.var = *var;
-+ cfb->fb.fix.line_length = var->xres_virtual * var->bits_per_pixel / 8;
-
- switch (var->bits_per_pixel) {
- #ifdef FBCON_HAS_CFB8
- case 8: /* PSEUDOCOLOUR, 256 */
-- var->red.offset = 0;
-- var->red.length = 8;
-- var->green.offset = 0;
-- var->green.length = 8;
-- var->blue.offset = 0;
-- var->blue.length = 8;
--
-- cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
- cfb->dispsw = &fbcon_cfb8;
- display->dispsw_data = NULL;
-- display->next_line = var->xres_virtual;
- break;
- #endif
- #ifdef FBCON_HAS_CFB16
-- case 16:/* DIRECTCOLOUR, 64k */
--#ifndef CFB16_IS_CFB15
-- var->red.offset = 11;
-- var->red.length = 5;
-- var->green.offset = 5;
-- var->green.length = 6;
-- var->blue.offset = 0;
-- var->blue.length = 5;
--
-- cfb->fb.fix.visual = FB_VISUAL_DIRECTCOLOR;
-+ case 16:/* DIRECTCOLOUR */
- cfb->dispsw = &fbcon_cfb16;
- display->dispsw_data = cfb->fb.pseudo_palette;
-- display->next_line = var->xres_virtual * 2;
-- break;
--#endif
-- case 15:/* DIRECTCOLOUR, 32k */
-- var->bits_per_pixel = 15;
-- var->red.offset = 10;
-- var->red.length = 5;
-- var->green.offset = 5;
-- var->green.length = 5;
-- var->blue.offset = 0;
-- var->blue.length = 5;
--
-- cfb->fb.fix.visual = FB_VISUAL_DIRECTCOLOR;
-- cfb->dispsw = &fbcon_cfb16;
-- display->dispsw_data = cfb->fb.pseudo_palette;
-- display->next_line = var->xres_virtual * 2;
- break;
- #endif
- #ifdef FBCON_HAS_CFB24
- case 24:/* TRUECOLOUR, 16m */
-- var->red.offset = 16;
-- var->red.length = 8;
-- var->green.offset = 8;
-- var->green.length = 8;
-- var->blue.offset = 0;
-- var->blue.length = 8;
--
-- cfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
- cfb->dispsw = &fbcon_cfb24;
- display->dispsw_data = cfb->fb.pseudo_palette;
-- display->next_line = var->xres_virtual * 3;
- break;
- #endif
- #ifdef FBCON_HAS_CFB32
- case 32:/* TRUECOLOUR, 16m */
-- var->transp.offset = 24;
-- var->transp.length = 8;
-- var->red.offset = 16;
-- var->red.length = 8;
-- var->green.offset = 8;
-- var->green.length = 8;
-- var->blue.offset = 0;
-- var->blue.length = 8;
--
-- cfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
- cfb->dispsw = &fbcon_cfb32;
- display->dispsw_data = cfb->fb.pseudo_palette;
-- display->next_line = var->xres_virtual * 4;
- break;
- #endif
- default:/* in theory this should never happen */
-@@ -1010,15 +1082,27 @@
- break;
- }
-
-+ /*
-+ * 8bpp displays are always pseudo colour.
-+ * 16bpp and above are direct colour or true colour, depending
-+ * on whether the RAMDAC palettes are bypassed. (Direct colour
-+ * has palettes, true colour does not.)
-+ */
-+ if (var->bits_per_pixel == 8)
-+ cfb->fb.fix.visual = FB_VISUAL_PSEUDOCOLOR;
-+ else if (hw.ramdac & RAMDAC_BYPASS)
-+ cfb->fb.fix.visual = FB_VISUAL_TRUECOLOR;
-+ else
-+ cfb->fb.fix.visual = FB_VISUAL_DIRECTCOLOR;
-+
- if (var->accel_flags & FB_ACCELF_TEXT && cfb->dispsw != &fbcon_dummy)
- display->dispsw = &fbcon_cyber_accel;
- else
- display->dispsw = cfb->dispsw;
-
-- cfb->fb.fix.line_length = display->next_line;
--
- display->screen_base = cfb->fb.screen_base;
- display->line_length = cfb->fb.fix.line_length;
-+ display->next_line = cfb->fb.fix.line_length;
- display->visual = cfb->fb.fix.visual;
- display->type = cfb->fb.fix.type;
- display->type_aux = cfb->fb.fix.type_aux;
-@@ -1026,31 +1110,15 @@
- display->ywrapstep = cfb->fb.fix.ywrapstep;
- display->can_soft_blank = 1;
- display->inverse = 0;
-+ display->var = *var;
-
-- cfb->fb.var = *var;
-- cfb->fb.var.activate &= ~FB_ACTIVATE_ALL;
--
-- /*
-- * Update the old var. The fbcon drivers still use this.
-- * Once they are using cfb->fb.var, this can be dropped.
-- * --rmk
-- */
-- display->var = cfb->fb.var;
--
-- /*
-- * If we are setting all the virtual consoles, also set the
-- * defaults used to create new consoles.
-- */
-- if (var->activate & FB_ACTIVATE_ALL)
-- cfb->fb.disp->var = cfb->fb.var;
-+ cyber2000fb_set_timing(cfb, &hw);
-+ cyber2000fb_update_start(cfb, var);
-+ fb_set_cmap(&cfb->fb.cmap, 1, cyber2000fb_setcolreg, &cfb->fb);
-
-- if (chgvar && info && cfb->fb.changevar)
-+ if (chgvar && cfb->fb.changevar)
- cfb->fb.changevar(con);
-
-- cyber2000fb_update_start(cfb, var);
-- cyber2000fb_set_timing(cfb, &hw);
-- fb_set_cmap(&cfb->fb.cmap, 1, cyber2000_setcolreg, &cfb->fb);
--
- return 0;
- }
-
-@@ -1072,18 +1140,18 @@
-
- if (var->xoffset > (var->xres_virtual - var->xres))
- return -EINVAL;
-- if (y_bottom > cfb->fb.var.yres_virtual)
-+ if (y_bottom > cfb->display->var.yres_virtual)
- return -EINVAL;
-
- if (cyber2000fb_update_start(cfb, var))
- return -EINVAL;
-
-- cfb->fb.var.xoffset = var->xoffset;
-- cfb->fb.var.yoffset = var->yoffset;
-+ cfb->display->var.xoffset = var->xoffset;
-+ cfb->display->var.yoffset = var->yoffset;
- if (var->vmode & FB_VMODE_YWRAP) {
-- cfb->fb.var.vmode |= FB_VMODE_YWRAP;
-+ cfb->display->var.vmode |= FB_VMODE_YWRAP;
- } else {
-- cfb->fb.var.vmode &= ~FB_VMODE_YWRAP;
-+ cfb->display->var.vmode &= ~FB_VMODE_YWRAP;
- }
-
- return 0;
-@@ -1106,22 +1174,18 @@
- static int cyber2000fb_switch(int con, struct fb_info *info)
- {
- struct cfb_info *cfb = (struct cfb_info *)info;
-- struct display *disp;
-+ struct display *display = cfb->display;
- struct fb_cmap *cmap;
-
-- if (cfb->currcon >= 0) {
-- disp = fb_display + cfb->currcon;
--
-+ if (display) {
- /*
- * Save the old colormap and video mode.
- */
-- disp->var = cfb->fb.var;
-- if (disp->cmap.len)
-- fb_copy_cmap(&cfb->fb.cmap, &disp->cmap, 0);
-+ if (display->cmap.len)
-+ fb_copy_cmap(&cfb->fb.cmap, &display->cmap, 0);
- }
-
-- cfb->currcon = con;
-- disp = fb_display + con;
-+ cfb->display = display = fb_display + con;
-
- /*
- * Install the new colormap and change the video mode. By default,
-@@ -1132,73 +1196,88 @@
- * depth of the new video mode. For now, we leave it at its
- * default 256 entry.
- */
-- if (disp->cmap.len)
-- cmap = &disp->cmap;
-+ if (display->cmap.len)
-+ cmap = &display->cmap;
- else
-- cmap = fb_default_cmap(1 << disp->var.bits_per_pixel);
-+ cmap = fb_default_cmap(1 << display->var.bits_per_pixel);
-
- fb_copy_cmap(cmap, &cfb->fb.cmap, 0);
-
-- cfb->fb.var = disp->var;
-- cfb->fb.var.activate = FB_ACTIVATE_NOW;
--
-- cyber2000fb_set_var(&cfb->fb.var, con, &cfb->fb);
-+ display->var.activate = FB_ACTIVATE_NOW;
-+ cyber2000fb_set_var(&display->var, con, &cfb->fb);
-
- return 0;
- }
-
- /*
- * (Un)Blank the display.
-+ *
-+ * Blank the screen if blank_mode != 0, else unblank. If
-+ * blank == NULL then the caller blanks by setting the CLUT
-+ * (Color Look Up Table) to all black. Return 0 if blanking
-+ * succeeded, != 0 if un-/blanking failed due to e.g. a
-+ * video mode which doesn't support it. Implements VESA
-+ * suspend and powerdown modes on hardware that supports
-+ * disabling hsync/vsync:
-+ * blank_mode == 2: suspend vsync
-+ * blank_mode == 3: suspend hsync
-+ * blank_mode == 4: powerdown
-+ *
-+ * wms...Enable VESA DMPS compatible powerdown mode
-+ * run "setterm -powersave powerdown" to take advantage
- */
- static void cyber2000fb_blank(int blank, struct fb_info *info)
- {
- struct cfb_info *cfb = (struct cfb_info *)info;
-+ unsigned int sync = 0;
- int i;
-
-- /*
-- * Blank the screen if blank_mode != 0, else unblank. If
-- * blank == NULL then the caller blanks by setting the CLUT
-- * (Color Look Up Table) to all black. Return 0 if blanking
-- * succeeded, != 0 if un-/blanking failed due to e.g. a
-- * video mode which doesn't support it. Implements VESA
-- * suspend and powerdown modes on hardware that supports
-- * disabling hsync/vsync:
-- * blank_mode == 2: suspend vsync
-- * blank_mode == 3: suspend hsync
-- * blank_mode == 4: powerdown
-- *
-- * wms...Enable VESA DMPS compatible powerdown mode
-- * run "setterm -powersave powerdown" to take advantage
-- */
--
- switch (blank) {
- case 4: /* powerdown - both sync lines down */
-- cyber2000_grphw(0x16, 0x05, cfb);
-+ sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_0;
- break;
- case 3: /* hsync off */
-- cyber2000_grphw(0x16, 0x01, cfb);
-+ sync = EXT_SYNC_CTL_VS_NORMAL | EXT_SYNC_CTL_HS_0;
- break;
- case 2: /* vsync off */
-- cyber2000_grphw(0x16, 0x04, cfb);
-- break;
-+ sync = EXT_SYNC_CTL_VS_0 | EXT_SYNC_CTL_HS_NORMAL;
-+ break;
- case 1: /* soft blank */
-- cyber2000_grphw(0x16, 0x00, cfb);
-+ default: /* unblank */
-+ break;
-+ }
-+
-+ cyber2000_grphw(EXT_SYNC_CTL, sync, cfb);
-+
-+ if (blank <= 1) {
-+ /* turn on ramdacs */
-+ cfb->ramdac_powerdown &= ~(RAMDAC_DACPWRDN | RAMDAC_BYPASS | RAMDAC_RAMPWRDN);
-+ cyber2000fb_write_ramdac_ctrl(cfb);
-+ }
-+
-+ /*
-+ * Soft blank/unblank the display.
-+ */
-+ if (blank) { /* soft blank */
- for (i = 0; i < NR_PALETTE; i++) {
- cyber2000fb_writeb(i, 0x3c8, cfb);
- cyber2000fb_writeb(0, 0x3c9, cfb);
- cyber2000fb_writeb(0, 0x3c9, cfb);
- cyber2000fb_writeb(0, 0x3c9, cfb);
- }
-- break;
-- default: /* unblank */
-- cyber2000_grphw(0x16, 0x00, cfb);
-+ } else { /* unblank */
- for (i = 0; i < NR_PALETTE; i++) {
- cyber2000fb_writeb(i, 0x3c8, cfb);
- cyber2000fb_writeb(cfb->palette[i].red, 0x3c9, cfb);
- cyber2000fb_writeb(cfb->palette[i].green, 0x3c9, cfb);
- cyber2000fb_writeb(cfb->palette[i].blue, 0x3c9, cfb);
- }
-- break;
-+ }
-+
-+ if (blank >= 2) {
-+ /* turn off ramdacs */
-+ cfb->ramdac_powerdown |= RAMDAC_DACPWRDN | RAMDAC_BYPASS | RAMDAC_RAMPWRDN;
-+ cyber2000fb_write_ramdac_ctrl(cfb);
- }
- }
-
-@@ -1233,51 +1312,61 @@
- }
-
- static struct fb_ops cyber2000fb_ops = {
-- owner: THIS_MODULE,
-- fb_set_var: cyber2000fb_set_var,
-- fb_set_cmap: cyber2000fb_set_cmap,
-- fb_pan_display: cyber2000fb_pan_display,
-- fb_get_fix: gen_get_fix,
-- fb_get_var: gen_get_var,
-- fb_get_cmap: gen_get_cmap,
-+ .owner = THIS_MODULE,
-+ .fb_set_var = cyber2000fb_set_var,
-+ .fb_set_cmap = cyber2000fb_set_cmap,
-+ .fb_pan_display = cyber2000fb_pan_display,
-+ .fb_get_fix = gen_get_fix,
-+ .fb_get_var = gen_get_var,
-+ .fb_get_cmap = gen_get_cmap,
- };
-
- /*
-+ * This is the only "static" reference to the internal data structures
-+ * of this driver. It is here solely at the moment to support the other
-+ * CyberPro modules external to this driver.
-+ */
-+static struct cfb_info *int_cfb_info;
-+
-+/*
- * Enable access to the extended registers
- */
--static void cyber2000fb_enable_extregs(struct cfb_info *cfb)
-+void cyber2000fb_enable_extregs(struct cfb_info *cfb)
- {
- cfb->func_use_count += 1;
-
- if (cfb->func_use_count == 1) {
- int old;
-
-- old = cyber2000_grphr(FUNC_CTL, cfb);
-- cyber2000_grphw(FUNC_CTL, old | FUNC_CTL_EXTREGENBL, cfb);
-+ old = cyber2000_grphr(EXT_FUNC_CTL, cfb);
-+ old |= EXT_FUNC_CTL_EXTREGENBL;
-+ cyber2000_grphw(EXT_FUNC_CTL, old, cfb);
- }
- }
-
- /*
- * Disable access to the extended registers
- */
--static void cyber2000fb_disable_extregs(struct cfb_info *cfb)
-+void cyber2000fb_disable_extregs(struct cfb_info *cfb)
- {
- if (cfb->func_use_count == 1) {
- int old;
-
-- old = cyber2000_grphr(FUNC_CTL, cfb);
-- cyber2000_grphw(FUNC_CTL, old & ~FUNC_CTL_EXTREGENBL, cfb);
-+ old = cyber2000_grphr(EXT_FUNC_CTL, cfb);
-+ old &= ~EXT_FUNC_CTL_EXTREGENBL;
-+ cyber2000_grphw(EXT_FUNC_CTL, old, cfb);
- }
-
-- cfb->func_use_count -= 1;
-+ if (cfb->func_use_count == 0)
-+ printk(KERN_ERR "disable_extregs: count = 0\n");
-+ else
-+ cfb->func_use_count -= 1;
- }
-
--/*
-- * This is the only "static" reference to the internal data structures
-- * of this driver. It is here solely at the moment to support the other
-- * CyberPro modules external to this driver.
-- */
--static struct cfb_info *int_cfb_info;
-+void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var)
-+{
-+ memcpy(var, &cfb->display->var, sizeof(struct fb_var_screeninfo));
-+}
-
- /*
- * Attach a capture/tv driver to the core CyberX0X0 driver.
-@@ -1311,164 +1400,102 @@
-
- EXPORT_SYMBOL(cyber2000fb_attach);
- EXPORT_SYMBOL(cyber2000fb_detach);
-+EXPORT_SYMBOL(cyber2000fb_enable_extregs);
-+EXPORT_SYMBOL(cyber2000fb_disable_extregs);
-+EXPORT_SYMBOL(cyber2000fb_get_fb_var);
-
- /*
- * These parameters give
- * 640x480, hsync 31.5kHz, vsync 60Hz
- */
- static struct fb_videomode __devinitdata cyber2000fb_default_mode = {
-- refresh: 60,
-- xres: 640,
-- yres: 480,
-- pixclock: 39722,
-- left_margin: 56,
-- right_margin: 16,
-- upper_margin: 34,
-- lower_margin: 9,
-- hsync_len: 88,
-- vsync_len: 2,
-- sync: FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-- vmode: FB_VMODE_NONINTERLACED
-+ .refresh = 60,
-+ .xres = 640,
-+ .yres = 480,
-+ .pixclock = 39722,
-+ .left_margin = 56,
-+ .right_margin = 16,
-+ .upper_margin = 34,
-+ .lower_margin = 9,
-+ .hsync_len = 88,
-+ .vsync_len = 2,
-+ .sync = FB_SYNC_COMP_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-+ .vmode = FB_VMODE_NONINTERLACED
- };
-
-+/* static register programming for all chips */
- static char igs_regs[] __devinitdata = {
-- 0x12, 0x00, 0x13, 0x00,
-- 0x16, 0x00,
-- 0x31, 0x00, 0x32, 0x00,
-- 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00,
-- 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x01,
-- 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00,
-- 0x70, 0x0b, 0x73, 0x30,
-- 0x74, 0x0b, 0x75, 0x17, 0x76, 0x00, 0x7a, 0xc8
-+ EXT_CRT_IRQ, 0,
-+ EXT_CRT_TEST, 0,
-+ EXT_SYNC_CTL, 0,
-+ EXT_SEG_WRITE_PTR, 0,
-+ EXT_SEG_READ_PTR, 0,
-+ EXT_BIU_MISC, EXT_BIU_MISC_LIN_ENABLE |
-+ EXT_BIU_MISC_COP_ENABLE |
-+ EXT_BIU_MISC_COP_BFC,
-+ EXT_FUNC_CTL, 0,
-+ CURS_H_START, 0,
-+ CURS_H_START + 1, 0,
-+ CURS_H_PRESET, 0,
-+ CURS_V_START, 0,
-+ CURS_V_START + 1, 0,
-+ CURS_V_PRESET, 0,
-+ CURS_CTL, 0,
-+ EXT_ATTRIB_CTL, EXT_ATTRIB_CTL_EXT,
-+ EXT_OVERSCAN_RED, 0,
-+ EXT_OVERSCAN_GREEN, 0,
-+ EXT_OVERSCAN_BLUE, 0,
-+};
-+
-+/* specific register setting for the 2000 series */
-+static char igs_2000_regs[] __devinitdata = {
-+ /* some of these are questionable when we have a BIOS */
-+ EXT_MEM_CTL0, EXT_MEM_CTL0_7CLK |
-+ EXT_MEM_CTL0_RAS_1 |
-+ EXT_MEM_CTL0_MULTCAS,
-+ EXT_HIDDEN_CTL1, 0x30,
-+ EXT_FIFO_CTL, 0x0b,
-+ EXT_FIFO_CTL + 1, 0x17,
-+ 0x76, 0x00,
-+ EXT_HIDDEN_CTL4, 0xc8
- };
-
- /*
-- * We need to wake up the CyberPro, and make sure its in linear memory
-- * mode. Unfortunately, this is specific to the platform and card that
-- * we are running on.
-- *
-- * On x86 and ARM, should we be initialising the CyberPro first via the
-- * IO registers, and then the MMIO registers to catch all cases? Can we
-- * end up in the situation where the chip is in MMIO mode, but not awake
-- * on an x86 system?
-- *
-- * Note that on the NetWinder, the firmware automatically detects the
-- * type, width and size, and leaves this in extended registers 0x71 and
-- * 0x72 for us.
-+ * Initialise the CyberPro hardware.
- */
--static inline void cyberpro_init_hw(struct cfb_info *cfb, int at_boot)
-+static void cyberpro_init_hw(struct cfb_info *cfb)
- {
- int i;
-
-- /*
-- * Wake up the CyberPro.
-- */
--#ifdef __sparc__
--#ifdef __sparc_v9__
--#error "You loose, consult DaveM."
--#else
-- /*
-- * SPARC does not have an "outb" instruction, so we generate
-- * I/O cycles storing into a reserved memory space at
-- * physical address 0x3000000
-- */
-- {
-- unsigned char *iop;
--
-- iop = ioremap(0x3000000, 0x5000);
-- if (iop == NULL) {
-- prom_printf("iga5000: cannot map I/O\n");
-- return -ENOMEM;
-- }
--
-- writeb(0x18, iop + 0x46e8);
-- writeb(0x01, iop + 0x102);
-- writeb(0x08, iop + 0x46e8);
-- writeb(0x33, iop + 0x3ce);
-- writeb(0x01, iop + 0x3cf);
--
-- iounmap((void *)iop);
-- }
--#endif
--
-- if (at_boot) {
-- /*
-- * Use mclk from BIOS. Only read this if we're
-- * initialising this card for the first time.
-- * FIXME: what about hotplug?
-- */
-- cfb->mclk_mult = cyber2000_grphr(MCLK_MULT, cfb);
-- cfb->mclk_div = cyber2000_grphr(MCLK_DIV, cfb);
-- }
--#endif
--#if defined(__i386__) || defined(__x86_64__) || defined(__mips__)
-- /*
-- * x86 and MIPS are simple, we just do regular
-- * outb's instead of cyber2000fb_writeb.
-- */
-- outb(0x18, 0x46e8);
-- outb(0x01, 0x102);
-- outb(0x08, 0x46e8);
-- outb(0x33, 0x3ce);
-- outb(0x01, 0x3cf);
--
-- if (at_boot) {
-- /*
-- * Use mclk from BIOS. Only read this if we're
-- * initialising this card for the first time.
-- * FIXME: what about hotplug?
-- */
-- cfb->mclk_mult = cyber2000_grphr(MCLK_MULT, cfb);
-- cfb->mclk_div = cyber2000_grphr(MCLK_DIV, cfb);
-- }
--#endif
--#ifdef __arm__
-- cyber2000fb_writeb(0x18, 0x46e8, cfb);
-- cyber2000fb_writeb(0x01, 0x102, cfb);
-- cyber2000fb_writeb(0x08, 0x46e8, cfb);
-- cyber2000fb_writeb(0x33, 0x3ce, cfb);
-- cyber2000fb_writeb(0x01, 0x3cf, cfb);
--
-- /*
-- * MCLK on the NetWinder and the Shark is fixed at 75MHz
-- */
-- cfb->mclk_mult = 0xdb;
-- cfb->mclk_div = 0x54;
--#endif
--
-- /*
-- * Initialise the CyberPro
-- */
- for (i = 0; i < sizeof(igs_regs); i += 2)
- cyber2000_grphw(igs_regs[i], igs_regs[i+1], cfb);
-
-- if (at_boot) {
-+ if (cfb->id == ID_CYBERPRO_5000) {
- /*
-- * get the video RAM size and width from the VGA register.
-- * This should have been already initialised by the BIOS,
-- * but if it's garbage, claim default 1MB VRAM (woody)
-+ * On the CyberPro5XXXX, ensure that we're using the correct
-+ * PLL (5XXX's may be programmed to use an additional set of
-+ * PLLs.)
- */
-- cfb->mem_ctl1 = cyber2000_grphr(MEM_CTL1, cfb);
-- cfb->mem_ctl2 = cyber2000_grphr(MEM_CTL2, cfb);
-+ unsigned char val;
-+ cyber2000fb_writeb(0xba, 0x3ce, cfb);
-+ val = cyber2000fb_readb(0x3cf, cfb) & 0x80;
-+ cyber2000fb_writeb(val, 0x3cf, cfb);
-+ cyber2000fb_ops.fb_pan_display = NULL; /* FIXME: panning broken */
- } else {
- /*
-- * Reprogram the MEM_CTL1 and MEM_CTL2 registers
-+ * Other supported chips (2000 series) appear to need
-+ * these registers programming
- */
-- cyber2000_grphw(MEM_CTL1, cfb->mem_ctl1, cfb);
-- cyber2000_grphw(MEM_CTL2, cfb->mem_ctl2, cfb);
-+ for (i = 0; i < sizeof(igs_2000_regs); i += 2)
-+ cyber2000_grphw(igs_2000_regs[i],
-+ igs_2000_regs[i+1],
-+ cfb);
- }
-
-- /*
-- * Ensure thatwe are using the correct PLL.
-- * (CyberPro 5000's may be programmed to use
-- * an additional set of PLLs.
-- */
-- cyber2000fb_writeb(0xba, 0x3ce, cfb);
-- cyber2000fb_writeb(cyber2000fb_readb(0x3cf, cfb) & 0x80, 0x3cf, cfb);
- }
-
- static struct cfb_info * __devinit
--cyberpro_alloc_fb_info(struct pci_dev *dev, const struct pci_device_id *id, char *name)
-+cyberpro_alloc_fb_info(unsigned int id, char *name)
- {
- struct cfb_info *cfb;
-
-@@ -1480,10 +1507,9 @@
-
- memset(cfb, 0, sizeof(struct cfb_info) + sizeof(struct display));
-
-- cfb->currcon = -1;
-- cfb->dev = dev;
-+ cfb->id = id;
-
-- if (id->driver_data == FB_ACCEL_IGS_CYBER5000)
-+ if (id == ID_CYBERPRO_5000)
- cfb->ref_ps = 40690; // 24.576 MHz
- else
- cfb->ref_ps = 69842; // 14.31818 MHz (69841?)
-@@ -1492,7 +1518,7 @@
- cfb->divisors[1] = 2;
- cfb->divisors[2] = 4;
-
-- if (id->driver_data == FB_ACCEL_IGS_CYBER2000)
-+ if (id == ID_CYBERPRO_2000)
- cfb->divisors[3] = 8;
- else
- cfb->divisors[3] = 6;
-@@ -1504,7 +1530,24 @@
- cfb->fb.fix.xpanstep = 0;
- cfb->fb.fix.ypanstep = 1;
- cfb->fb.fix.ywrapstep = 0;
-- cfb->fb.fix.accel = id->driver_data;
-+
-+ switch (id) {
-+ case ID_IGA_1682:
-+ cfb->fb.fix.accel = 0;
-+ break;
-+
-+ case ID_CYBERPRO_2000:
-+ cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER2000;
-+ break;
-+
-+ case ID_CYBERPRO_2010:
-+ cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER2010;
-+ break;
-+
-+ case ID_CYBERPRO_5000:
-+ cfb->fb.fix.accel = FB_ACCEL_IGS_CYBER5000;
-+ break;
-+ }
-
- cfb->fb.var.nonstd = 0;
- cfb->fb.var.activate = FB_ACTIVATE_NOW;
-@@ -1569,55 +1612,46 @@
- return 0;
- }
-
--static int __devinit
--cyberpro_probe(struct pci_dev *dev, const struct pci_device_id *id)
-+/*
-+ * The CyberPro chips can be placed on many different bus types.
-+ * This probe function is common to all bus types. The bus-specific
-+ * probe function is expected to have:
-+ * - enabled access to the linear memory region
-+ * - memory mapped access to the registers
-+ * - initialised mem_ctl1 and mem_ctl2 appropriately.
-+ */
-+static int __devinit cyberpro_common_probe(struct cfb_info *cfb)
- {
-- struct cfb_info *cfb;
-- u_int h_sync, v_sync;
- u_long smem_size;
-- char name[16];
-+ u_int h_sync, v_sync;
- int err;
-
-- sprintf(name, "CyberPro%4X", id->device);
--
-- err = pci_enable_device(dev);
-- if (err)
-- return err;
--
-- err = pci_request_regions(dev, name);
-- if (err)
-- return err;
--
-- err = -ENOMEM;
-- cfb = cyberpro_alloc_fb_info(dev, id, name);
-- if (!cfb)
-- goto failed_release;
--
-- cfb->region = ioremap(pci_resource_start(dev, 0),
-- pci_resource_len(dev, 0));
-- if (!cfb->region)
-- goto failed_ioremap;
--
-- cfb->regs = cfb->region + MMIO_OFFSET;
-+ cyberpro_init_hw(cfb);
-
-- cyberpro_init_hw(cfb, 1);
-+ /*
-+ * Get the video RAM size and width from the VGA register.
-+ * This should have been already initialised by the BIOS,
-+ * but if it's garbage, claim default 1MB VRAM (woody)
-+ */
-+ cfb->mem_ctl0 = cyber2000_grphr(EXT_MEM_CTL0, cfb);
-+ cfb->mem_ctl1 = cyber2000_grphr(EXT_MEM_CTL1, cfb);
-+ cfb->mem_ctl2 = cyber2000_grphr(EXT_MEM_CTL2, cfb);
-
-+ /*
-+ * Determine the size of the memory.
-+ */
- switch (cfb->mem_ctl2 & MEM_CTL2_SIZE_MASK) {
- case MEM_CTL2_SIZE_4MB: smem_size = 0x00400000; break;
- case MEM_CTL2_SIZE_2MB: smem_size = 0x00200000; break;
-+ case MEM_CTL2_SIZE_1MB: smem_size = 0x00100000; break;
- default: smem_size = 0x00100000; break;
- }
-
-- /*
-- * Hmm, we _need_ a portable way of finding the address for
-- * the remap stuff, both for mmio and for smem.
-- */
-- cfb->fb.fix.mmio_start = pci_resource_start(dev, 0) + MMIO_OFFSET;
-- cfb->fb.fix.smem_start = pci_resource_start(dev, 0);
-- cfb->fb.fix.mmio_len = MMIO_SIZE;
- cfb->fb.fix.smem_len = smem_size;
-+ cfb->fb.fix.mmio_len = MMIO_SIZE;
- cfb->fb.screen_base = cfb->region;
-
-+ err = -EINVAL;
- if (!fb_find_mode(&cfb->fb.var, &cfb->fb, NULL, NULL, 0,
- &cyber2000fb_default_mode, 8)) {
- printk("%s: no valid mode found\n", cfb->fb.fix.id);
-@@ -1644,13 +1678,181 @@
- v_sync = h_sync / (cfb->fb.var.yres + cfb->fb.var.upper_margin +
- cfb->fb.var.lower_margin + cfb->fb.var.vsync_len);
-
-- printk(KERN_INFO "%s: %dkB VRAM, using %dx%d, %d.%03dkHz, %dHz\n",
-+ printk(KERN_INFO "%s: %dKiB VRAM, using %dx%d, %d.%03dkHz, %dHz\n",
- cfb->fb.fix.id, cfb->fb.fix.smem_len >> 10,
- cfb->fb.var.xres, cfb->fb.var.yres,
- h_sync / 1000, h_sync % 1000, v_sync);
-
- err = register_framebuffer(&cfb->fb);
-- if (err < 0)
-+
-+failed:
-+ return err;
-+}
-+
-+static void cyberpro_common_resume(struct cfb_info *cfb)
-+{
-+ cyberpro_init_hw(cfb);
-+
-+ /*
-+ * Reprogram the MEM_CTL0, 1 and 2 registers
-+ */
-+ cyber2000_grphw(EXT_MEM_CTL0, cfb->mem_ctl0, cfb);
-+ cyber2000_grphw(EXT_MEM_CTL1, cfb->mem_ctl1, cfb);
-+ cyber2000_grphw(EXT_MEM_CTL2, cfb->mem_ctl2, cfb);
-+
-+ /*
-+ * Restore the old video mode and the palette.
-+ * We also need to tell fbcon to redraw the console.
-+ */
-+ cfb->fb.var.activate = FB_ACTIVATE_NOW;
-+ cyber2000fb_set_var(&cfb->fb.var, -1, &cfb->fb);
-+}
-+
-+
-+
-+
-+/*
-+ * PCI specific support.
-+ */
-+
-+/*
-+ * We need to wake up the CyberPro, and make sure its in linear memory
-+ * mode. Unfortunately, this is specific to the platform and card that
-+ * we are running on.
-+ *
-+ * On x86 and ARM, should we be initialising the CyberPro first via the
-+ * IO registers, and then the MMIO registers to catch all cases? Can we
-+ * end up in the situation where the chip is in MMIO mode, but not awake
-+ * on an x86 system?
-+ */
-+static int cyberpro_pci_enable_mmio(struct cfb_info *cfb)
-+{
-+ unsigned char val;
-+
-+#if defined(__sparc_v9__)
-+#error "You loose, consult DaveM."
-+#elif defined(__sparc__)
-+ /*
-+ * SPARC does not have an "outb" instruction, so we generate
-+ * I/O cycles storing into a reserved memory space at
-+ * physical address 0x3000000
-+ */
-+ unsigned char *iop;
-+
-+ iop = ioremap(0x3000000, 0x5000);
-+ if (iop == NULL) {
-+ prom_printf("iga5000: cannot map I/O\n");
-+ return -ENOMEM;
-+ }
-+
-+ writeb(0x18, iop + 0x46e8);
-+ writeb(0x01, iop + 0x102);
-+ writeb(0x08, iop + 0x46e8);
-+ writeb(EXT_BIU_MISC, iop + 0x3ce);
-+ writeb(EXT_BIU_MISC_LIN_ENABLE, iop + 0x3cf);
-+
-+ iounmap((void *)iop);
-+#elif defined(CONFIG_ARCH_SHARK)
-+ /*
-+ * Shark probably needs to do it this way rather than use the
-+ * IO method below. Since the CyberPro on the Shark isn't a
-+ * PCI device, we probably want to move this to a bus-specific
-+ * probe function. Do we even need to do this?
-+ */
-+ cyber2000fb_writeb(0x18, 0x46e8, cfb);
-+ cyber2000fb_writeb(0x01, 0x102, cfb);
-+ cyber2000fb_writeb(0x08, 0x46e8, cfb);
-+ cyber2000fb_writeb(EXT_BIU_MISC, 0x3ce, cfb);
-+ cyber2000fb_writeb(EXT_BIU_MISC_LIN_ENABLE, 0x3cf, cfb);
-+#else
-+ /*
-+ * Most other machine types are "normal", so
-+ * we use the standard IO-based wakeup.
-+ */
-+ outb(0x18, 0x46e8);
-+ outb(0x01, 0x102);
-+ outb(0x08, 0x46e8);
-+ outb(EXT_BIU_MISC, 0x3ce);
-+ outb(EXT_BIU_MISC_LIN_ENABLE, 0x3cf);
-+#endif
-+
-+ /*
-+ * Allow the CyberPro to accept PCI burst accesses
-+ */
-+ val = cyber2000_grphr(EXT_BUS_CTL, cfb);
-+ if (!(val & EXT_BUS_CTL_PCIBURST_WRITE)) {
-+ printk(KERN_INFO "%s: enabling PCI bursts\n", cfb->fb.fix.id);
-+
-+ val |= EXT_BUS_CTL_PCIBURST_WRITE;
-+
-+ if (cfb->id == ID_CYBERPRO_5000)
-+ val |= EXT_BUS_CTL_PCIBURST_READ;
-+
-+ cyber2000_grphw(EXT_BUS_CTL, val, cfb);
-+ }
-+
-+ return 0;
-+}
-+
-+static int __devinit
-+cyberpro_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
-+{
-+ struct cfb_info *cfb;
-+ char name[16];
-+ int err;
-+
-+ sprintf(name, "CyberPro%4X", id->device);
-+
-+ err = pci_enable_device(dev);
-+ if (err)
-+ return err;
-+
-+ err = pci_request_regions(dev, name);
-+ if (err)
-+ return err;
-+
-+ err = -ENOMEM;
-+ cfb = cyberpro_alloc_fb_info(id->driver_data, name);
-+ if (!cfb)
-+ goto failed_release;
-+
-+ cfb->dev = dev;
-+ cfb->region = ioremap(pci_resource_start(dev, 0),
-+ pci_resource_len(dev, 0));
-+ if (!cfb->region)
-+ goto failed_ioremap;
-+
-+ cfb->regs = cfb->region + MMIO_OFFSET;
-+ cfb->fb.fix.mmio_start = pci_resource_start(dev, 0) + MMIO_OFFSET;
-+ cfb->fb.fix.smem_start = pci_resource_start(dev, 0);
-+
-+ /*
-+ * Bring up the hardware. This is expected to enable access
-+ * to the linear memory region, and allow access to the memory
-+ * mapped registers. Also, mem_ctl1 and mem_ctl2 must be
-+ * initialised.
-+ */
-+ err = cyberpro_pci_enable_mmio(cfb);
-+ if (err)
-+ goto failed;
-+
-+ /*
-+ * Use MCLK from BIOS. FIXME: what about hotplug?
-+ */
-+ cfb->mclk_mult = cyber2000_grphr(EXT_MCLK_MULT, cfb);
-+ cfb->mclk_div = cyber2000_grphr(EXT_MCLK_DIV, cfb);
-+#ifdef __arm__
-+ if (machine_is_netwinder() || machine_is_shark()) {
-+ /*
-+ * MCLK on the NetWinder and the Shark is fixed at 75MHz
-+ */
-+ cfb->mclk_mult = 0xdb;
-+ cfb->mclk_div = 0x54;
-+ }
-+#endif
-+
-+ err = cyberpro_common_probe(cfb);
-+ if (err)
- goto failed;
-
- /*
-@@ -1672,7 +1874,7 @@
- return err;
- }
-
--static void __devexit cyberpro_remove(struct pci_dev *dev)
-+static void __devexit cyberpro_pci_remove(struct pci_dev *dev)
- {
- struct cfb_info *cfb = pci_get_drvdata(dev);
-
-@@ -1701,7 +1903,7 @@
- }
- }
-
--static int cyberpro_suspend(struct pci_dev *dev, u32 state)
-+static int cyberpro_pci_suspend(struct pci_dev *dev, u32 state)
- {
- return 0;
- }
-@@ -1709,41 +1911,44 @@
- /*
- * Re-initialise the CyberPro hardware
- */
--static int cyberpro_resume(struct pci_dev *dev)
-+static int cyberpro_pci_resume(struct pci_dev *dev)
- {
- struct cfb_info *cfb = pci_get_drvdata(dev);
-
- if (cfb) {
-- cyberpro_init_hw(cfb, 0);
--
-- /*
-- * Restore the old video mode and the palette.
-- * We also need to tell fbcon to redraw the console.
-- */
-- cfb->fb.var.activate = FB_ACTIVATE_NOW;
-- cyber2000fb_set_var(&cfb->fb.var, -1, &cfb->fb);
-+ cyberpro_pci_enable_mmio(cfb);
-+ cyberpro_common_resume(cfb);
- }
-
- return 0;
- }
-
- static struct pci_device_id cyberpro_pci_table[] __devinitdata = {
-+// Not yet
-+// { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682,
-+// PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_IGA_1682 },
- { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_IGS_CYBER2000 },
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2000 },
- { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_IGS_CYBER2010 },
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2010 },
- { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000,
-- PCI_ANY_ID, PCI_ANY_ID, 0, 0, FB_ACCEL_IGS_CYBER5000 },
-+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_5000 },
- { 0, }
- };
-
-+MODULE_DEVICE_TABLE(pci,cyberpro_pci_table);
-+
-+#ifndef __devexit_p
-+#define __devexit_p(x) (x)
-+#endif
-+
- static struct pci_driver cyberpro_driver = {
-- name: "CyberPro",
-- probe: cyberpro_probe,
-- remove: __devexit_p(cyberpro_remove),
-- suspend: cyberpro_suspend,
-- resume: cyberpro_resume,
-- id_table: cyberpro_pci_table
-+ .name = "CyberPro",
-+ .probe = cyberpro_pci_probe,
-+ .remove = __devexit_p(cyberpro_pci_remove),
-+ .suspend = cyberpro_pci_suspend,
-+ .resume = cyberpro_pci_resume,
-+ .id_table = cyberpro_pci_table
- };
-
- /*
-@@ -1768,5 +1973,4 @@
-
- MODULE_AUTHOR("Russell King");
- MODULE_DESCRIPTION("CyberPro 2000, 2010 and 5000 framebuffer driver");
--MODULE_DEVICE_TABLE(pci,cyberpro_pci_table);
- MODULE_LICENSE("GPL");
---- linux-2.4.25/drivers/video/cyber2000fb.h~2.4.25-vrs2.patch 2002-08-03 02:39:45.000000000 +0200
-+++ linux-2.4.25/drivers/video/cyber2000fb.h 2004-03-31 17:15:09.000000000 +0200
-@@ -36,24 +36,55 @@
- #define debug_printf(x...) do { } while (0)
- #endif
-
--#define PIXFORMAT_8BPP 0
--#define PIXFORMAT_16BPP 1
--#define PIXFORMAT_24BPP 2
--#define PIXFORMAT_32BPP 3
-+#define RAMDAC_RAMPWRDN 0x01
-+#define RAMDAC_DAC8BIT 0x02
-+#define RAMDAC_VREFEN 0x04
-+#define RAMDAC_BYPASS 0x10
-+#define RAMDAC_DACPWRDN 0x40
-
--#define VISUALID_256 1
--#define VISUALID_64K 2
--#define VISUALID_16M_32 3
--#define VISUALID_16M 4
--#define VISUALID_32K 6
-+#define EXT_CRT_VRTOFL 0x11
-+#define EXT_CRT_VRTOFL_LINECOMP10 0x10
-+#define EXT_CRT_VRTOFL_INTERLACE 0x20
-
--#define FUNC_CTL 0x3c
--#define FUNC_CTL_EXTREGENBL 0x80 /* enable access to 0xbcxxx */
-+#define EXT_CRT_IRQ 0x12
-+#define EXT_CRT_IRQ_ENABLE 0x01
-+#define EXT_CRT_IRQ_ACT_HIGH 0x04
-
--#define BIU_BM_CONTROL 0x3e
--#define BIU_BM_CONTROL_ENABLE 0x01 /* enable bus-master */
--#define BIU_BM_CONTROL_BURST 0x02 /* enable burst */
--#define BIU_BM_CONTROL_BACK2BACK 0x04 /* enable back to back */
-+#define EXT_CRT_TEST 0x13
-+
-+#define EXT_SYNC_CTL 0x16
-+#define EXT_SYNC_CTL_HS_NORMAL 0x00
-+#define EXT_SYNC_CTL_HS_0 0x01
-+#define EXT_SYNC_CTL_HS_1 0x02
-+#define EXT_SYNC_CTL_HS_HSVS 0x03
-+#define EXT_SYNC_CTL_VS_NORMAL 0x00
-+#define EXT_SYNC_CTL_VS_0 0x04
-+#define EXT_SYNC_CTL_VS_1 0x08
-+#define EXT_SYNC_CTL_VS_COMP 0x0c
-+
-+#define EXT_BUS_CTL 0x30
-+#define EXT_BUS_CTL_LIN_1MB 0x00
-+#define EXT_BUS_CTL_LIN_2MB 0x01
-+#define EXT_BUS_CTL_LIN_4MB 0x02
-+#define EXT_BUS_CTL_ZEROWAIT 0x04
-+#define EXT_BUS_CTL_PCIBURST_WRITE 0x20
-+#define EXT_BUS_CTL_PCIBURST_READ 0x80 /* CyberPro 5000 only */
-+
-+#define EXT_SEG_WRITE_PTR 0x31
-+#define EXT_SEG_READ_PTR 0x32
-+#define EXT_BIU_MISC 0x33
-+#define EXT_BIU_MISC_LIN_ENABLE 0x01
-+#define EXT_BIU_MISC_COP_ENABLE 0x04
-+#define EXT_BIU_MISC_COP_BFC 0x08
-+
-+#define EXT_FUNC_CTL 0x3c
-+#define EXT_FUNC_CTL_EXTREGENBL 0x80 /* enable access to 0xbcxxx */
-+
-+#define PCI_BM_CTL 0x3e
-+#define PCI_BM_CTL_ENABLE 0x01 /* enable bus-master */
-+#define PCI_BM_CTL_BURST 0x02 /* enable burst */
-+#define PCI_BM_CTL_BACK2BACK 0x04 /* enable back to back */
-+#define PCI_BM_CTL_DUMMY 0x08 /* insert dummy cycle */
-
- #define X_V2_VID_MEM_START 0x40
- #define X_V2_VID_SRC_WIDTH 0x43
-@@ -87,6 +118,19 @@
-
- #define K_CAP_X2_CTL1 0x49
-
-+#define CURS_H_START 0x50
-+#define CURS_H_PRESET 0x52
-+#define CURS_V_START 0x53
-+#define CURS_V_PRESET 0x55
-+#define CURS_CTL 0x56
-+
-+#define EXT_ATTRIB_CTL 0x57
-+#define EXT_ATTRIB_CTL_EXT 0x01
-+
-+#define EXT_OVERSCAN_RED 0x58
-+#define EXT_OVERSCAN_GREEN 0x59
-+#define EXT_OVERSCAN_BLUE 0x5a
-+
- #define CAP_X_START 0x60
- #define CAP_X_END 0x62
- #define CAP_Y_START 0x64
-@@ -96,46 +140,112 @@
- #define CAP_DDA_Y_INIT 0x6c
- #define CAP_DDA_Y_INC 0x6e
-
--#define MEM_CTL1 0x71
-+#define EXT_MEM_CTL0 0x70
-+#define EXT_MEM_CTL0_7CLK 0x01
-+#define EXT_MEM_CTL0_RAS_1 0x02
-+#define EXT_MEM_CTL0_RAS2CAS_1 0x04
-+#define EXT_MEM_CTL0_MULTCAS 0x08
-+#define EXT_MEM_CTL0_ASYM 0x10
-+#define EXT_MEM_CTL0_CAS1ON 0x20
-+#define EXT_MEM_CTL0_FIFOFLUSH 0x40
-+#define EXT_MEM_CTL0_SEQRESET 0x80
-
--#define MEM_CTL2 0x72
-+#define EXT_MEM_CTL1 0x71
-+#define EXT_MEM_CTL1_PAR 0x00
-+#define EXT_MEM_CTL1_SERPAR 0x01
-+#define EXT_MEM_CTL1_SER 0x03
-+#define EXT_MEM_CTL1_SYNC 0x04
-+#define EXT_MEM_CTL1_VRAM 0x08
-+#define EXT_MEM_CTL1_4K_REFRESH 0x10
-+#define EXT_MEM_CTL1_256Kx4 0x00
-+#define EXT_MEM_CTL1_512Kx8 0x40
-+#define EXT_MEM_CTL1_1Mx16 0x60
-+
-+#define EXT_MEM_CTL2 0x72
-+#define MEM_CTL2_SIZE_1MB 0x00
- #define MEM_CTL2_SIZE_2MB 0x01
- #define MEM_CTL2_SIZE_4MB 0x02
- #define MEM_CTL2_SIZE_MASK 0x03
- #define MEM_CTL2_64BIT 0x04
-
-+#define EXT_HIDDEN_CTL1 0x73
-+
- #define EXT_FIFO_CTL 0x74
-
-+#define EXT_SEQ_MISC 0x77
-+#define EXT_SEQ_MISC_8 0x01
-+#define EXT_SEQ_MISC_16_RGB565 0x02
-+#define EXT_SEQ_MISC_32 0x03
-+#define EXT_SEQ_MISC_24_RGB888 0x04
-+#define EXT_SEQ_MISC_16_RGB555 0x06
-+#define EXT_SEQ_MISC_8_RGB332 0x09
-+#define EXT_SEQ_MISC_16_RGB444 0x0a
-+
-+#define EXT_HIDDEN_CTL4 0x7a
-+
-+#define CURS_MEM_START 0x7e /* bits 23..12 */
-+
- #define CAP_PIP_X_START 0x80
- #define CAP_PIP_X_END 0x82
- #define CAP_PIP_Y_START 0x84
- #define CAP_PIP_Y_END 0x86
-
--#define CAP_NEW_CTL1 0x88
-+#define EXT_CAP_CTL1 0x88
-
--#define CAP_NEW_CTL2 0x89
-+#define EXT_CAP_CTL2 0x89
-+#define EXT_CAP_CTL2_ODDFRAMEIRQ 0x01
-+#define EXT_CAP_CTL2_ANYFRAMEIRQ 0x02
-
- #define BM_CTRL0 0x9c
- #define BM_CTRL1 0x9d
-
--#define CAP_MODE1 0xa4
--#define CAP_MODE1_8BIT 0x01 /* enable 8bit capture mode */
--#define CAP_MODE1_CCIR656 0x02 /* CCIR656 mode */
--#define CAP_MODE1_IGNOREVGT 0x04 /* ignore VGT */
--#define CAP_MODE1_ALTFIFO 0x10 /* use alternate FIFO for capture */
--#define CAP_MODE1_SWAPUV 0x20 /* swap UV bytes */
--#define CAP_MODE1_MIRRORY 0x40 /* mirror vertically */
--#define CAP_MODE1_MIRRORX 0x80 /* mirror horizontally */
-+#define EXT_CAP_MODE1 0xa4
-+#define EXT_CAP_MODE1_8BIT 0x01 /* enable 8bit capture mode */
-+#define EXT_CAP_MODE1_CCIR656 0x02 /* CCIR656 mode */
-+#define EXT_CAP_MODE1_IGNOREVGT 0x04 /* ignore VGT */
-+#define EXT_CAP_MODE1_ALTFIFO 0x10 /* use alternate FIFO for capture */
-+#define EXT_CAP_MODE1_SWAPUV 0x20 /* swap UV bytes */
-+#define EXT_CAP_MODE1_MIRRORY 0x40 /* mirror vertically */
-+#define EXT_CAP_MODE1_MIRRORX 0x80 /* mirror horizontally */
-
--#define DCLK_MULT 0xb0
--#define DCLK_DIV 0xb1
--#define DCLK_DIV_VFSEL 0x20
--#define MCLK_MULT 0xb2
--#define MCLK_DIV 0xb3
-+#define EXT_CAP_MODE2 0xa5
-+#define EXT_CAP_MODE2_CCIRINVOE 0x01
-+#define EXT_CAP_MODE2_CCIRINVVGT 0x02
-+#define EXT_CAP_MODE2_CCIRINVHGT 0x04
-+#define EXT_CAP_MODE2_CCIRINVDG 0x08
-+#define EXT_CAP_MODE2_DATEND 0x10
-+#define EXT_CAP_MODE2_CCIRDGH 0x20
-+#define EXT_CAP_MODE2_FIXSONY 0x40
-+#define EXT_CAP_MODE2_SYNCFREEZE 0x80
-
--#define CAP_MODE2 0xa5
-+#define EXT_TV_CTL 0xae
-
--#define Y_TV_CTL 0xae
-+#define EXT_DCLK_MULT 0xb0
-+#define EXT_DCLK_DIV 0xb1
-+#define EXT_DCLK_DIV_VFSEL 0x20
-+#define EXT_MCLK_MULT 0xb2
-+#define EXT_MCLK_DIV 0xb3
-+
-+#define EXT_LATCH1 0xb5
-+#define EXT_LATCH1_VAFC_EN 0x01 /* enable VAFC */
-+
-+#define EXT_FEATURE 0xb7
-+#define EXT_FEATURE_BUS_MASK 0x07 /* host bus mask */
-+#define EXT_FEATURE_BUS_PCI 0x00
-+#define EXT_FEATURE_BUS_VL_STD 0x04
-+#define EXT_FEATURE_BUS_VL_LINEAR 0x05
-+#define EXT_FEATURE_1682 0x20 /* IGS 1682 compatibility */
-+
-+#define EXT_LATCH2 0xb6
-+#define EXT_LATCH2_I2C_CLKEN 0x10
-+#define EXT_LATCH2_I2C_CLK 0x20
-+#define EXT_LATCH2_I2C_DATEN 0x40
-+#define EXT_LATCH2_I2C_DAT 0x80
-+
-+#define EXT_XT_CTL 0xbe
-+#define EXT_XT_CAP16 0x04
-+#define EXT_XT_LINEARFB 0x08
-+#define EXT_XT_PAL 0x10
-
- #define EXT_MEM_START 0xc0 /* ext start address 21 bits */
- #define HOR_PHASE_SHIFT 0xc2 /* high 3 bits */
-@@ -160,25 +270,37 @@
- #define EXT_VID_FMT_RGB565 0x02
- #define EXT_VID_FMT_RGB888_24 0x03
- #define EXT_VID_FMT_RGB888_32 0x04
-+#define EXT_VID_FMT_RGB8 0x05
-+#define EXT_VID_FMT_RGB4444 0x06
-+#define EXT_VID_FMT_RGB8T 0x07
- #define EXT_VID_FMT_DUP_PIX_ZOON 0x08 /* duplicate pixel zoom */
- #define EXT_VID_FMT_MOD_3RD_PIX 0x20 /* modify 3rd duplicated pixel */
- #define EXT_VID_FMT_DBL_H_PIX 0x40 /* double horiz pixels */
--#define EXT_VID_FMT_UV128 0x80 /* UV data offset by 128 */
-+#define EXT_VID_FMT_YUV128 0x80 /* YUV data offset by 128 */
-
- #define EXT_VID_DISP_CTL1 0xdc
- #define EXT_VID_DISP_CTL1_INTRAM 0x01 /* video pixels go to internal RAM */
- #define EXT_VID_DISP_CTL1_IGNORE_CCOMP 0x02 /* ignore colour compare registers */
- #define EXT_VID_DISP_CTL1_NOCLIP 0x04 /* do not clip to 16235,16240 */
- #define EXT_VID_DISP_CTL1_UV_AVG 0x08 /* U/V data is averaged */
--#define EXT_VID_DISP_CTL1_Y128 0x10 /* Y data offset by 128 */
--#define EXT_VID_DISP_CTL1_VINTERPOL_OFF 0x20 /* vertical interpolation off */
-+#define EXT_VID_DISP_CTL1_Y128 0x10 /* Y data offset by 128 (if YUV128 set) */
-+#define EXT_VID_DISP_CTL1_VINTERPOL_OFF 0x20 /* disable vertical interpolation */
- #define EXT_VID_DISP_CTL1_FULL_WIN 0x40 /* video out window full */
- #define EXT_VID_DISP_CTL1_ENABLE_WINDOW 0x80 /* enable video window */
-
- #define EXT_VID_FIFO_CTL1 0xdd
-+#define EXT_VID_FIFO_CTL1_OE_HIGH 0x02
-+#define EXT_VID_FIFO_CTL1_INTERLEAVE 0x04 /* enable interleaved memory read */
-+
-+#define EXT_ROM_UCB4GH 0xe5
-+#define EXT_ROM_UCB4GH_FREEZE 0x02 /* capture frozen */
-+#define EXT_ROM_UCB4GH_ODDFRAME 0x04 /* 1 = odd frame captured */
-+#define EXT_ROM_UCB4GH_1HL 0x08 /* first horizonal line after VGT falling edge */
-+#define EXT_ROM_UCB4GH_ODD 0x10 /* odd frame indicator */
-+#define EXT_ROM_UCB4GH_INTSTAT 0x20 /* video interrupt */
-
- #define VFAC_CTL1 0xe8
--#define VFAC_CTL1_CAPTURE 0x01 /* capture enable */
-+#define VFAC_CTL1_CAPTURE 0x01 /* capture enable (only when VSYNC high)*/
- #define VFAC_CTL1_VFAC_ENABLE 0x02 /* vfac enable */
- #define VFAC_CTL1_FREEZE_CAPTURE 0x04 /* freeze capture */
- #define VFAC_CTL1_FREEZE_CAPTURE_SYNC 0x08 /* sync freeze capture */
-@@ -197,6 +319,13 @@
- #define VFAC_CTL2_INVERT_OVSYNC 0x80 /* invert other vsync input */
-
- #define VFAC_CTL3 0xea
-+#define VFAC_CTL3_CAP_LARGE_FIFO 0x01 /* large capture fifo */
-+#define VFAC_CTL3_CAP_INTERLACE 0x02 /* capture odd and even fields */
-+#define VFAC_CTL3_CAP_HOLD_4NS 0x00 /* hold capture data for 4ns */
-+#define VFAC_CTL3_CAP_HOLD_2NS 0x04 /* hold capture data for 2ns */
-+#define VFAC_CTL3_CAP_HOLD_6NS 0x08 /* hold capture data for 6ns */
-+#define VFAC_CTL3_CAP_HOLD_0NS 0x0c /* hold capture data for 0ns */
-+#define VFAC_CTL3_CHROMAKEY 0x20 /* capture data will be chromakeyed */
- #define VFAC_CTL3_CAP_IRQ 0x40 /* enable capture interrupt */
-
- #define CAP_MEM_START 0xeb /* 18 bits */
-@@ -235,26 +364,98 @@
- #define BM_COUNT 0xbc090 /* read-only */
-
- /*
-- * Graphics Co-processor
-+ * TV registers
- */
--#define CO_CMD_L_PATTERN_FGCOL 0x8000
--#define CO_CMD_L_INC_LEFT 0x0004
--#define CO_CMD_L_INC_UP 0x0002
--
--#define CO_CMD_H_SRC_PIXMAP 0x2000
--#define CO_CMD_H_BLITTER 0x0800
-+#define TV_VBLANK_EVEN_START 0xbe43c
-+#define TV_VBLANK_EVEN_END 0xbe440
-+#define TV_VBLANK_ODD_START 0xbe444
-+#define TV_VBLANK_ODD_END 0xbe448
-+#define TV_SYNC_YGAIN 0xbe44c
-+#define TV_UV_GAIN 0xbe450
-+#define TV_PED_UVDET 0xbe454
-+#define TV_UV_BURST_AMP 0xbe458
-+#define TV_HSYNC_START 0xbe45c
-+#define TV_HSYNC_END 0xbe460
-+#define TV_Y_DELAY1 0xbe464
-+#define TV_Y_DELAY2 0xbe468
-+#define TV_UV_DELAY1 0xbe46c
-+#define TV_BURST_START 0xbe470
-+#define TV_BURST_END 0xbe474
-+#define TV_HBLANK_START 0xbe478
-+#define TV_HBLANK_END 0xbe47c
-+#define TV_PED_EVEN_START 0xbe480
-+#define TV_PED_EVEN_END 0xbe484
-+#define TV_PED_ODD_START 0xbe488
-+#define TV_PED_ODD_END 0xbe48c
-+#define TV_VSYNC_EVEN_START 0xbe490
-+#define TV_VSYNC_EVEN_END 0xbe494
-+#define TV_VSYNC_ODD_START 0xbe498
-+#define TV_VSYNC_ODD_END 0xbe49c
-+#define TV_SCFL 0xbe4a0
-+#define TV_SCFH 0xbe4a4
-+#define TV_SCP 0xbe4a8
-+#define TV_DELAYBYPASS 0xbe4b4
-+#define TV_EQL_END 0xbe4bc
-+#define TV_SERR_START 0xbe4c0
-+#define TV_SERR_END 0xbe4c4
-+#define TV_CTL 0xbe4dc /* reflects a previous register- MVFCLR, MVPCLR etc P241*/
-+#define TV_VSYNC_VGA_HS 0xbe4e8
-+#define TV_FLICK_XMIN 0xbe514
-+#define TV_FLICK_XMAX 0xbe518
-+#define TV_FLICK_YMIN 0xbe51c
-+#define TV_FLICK_YMAX 0xbe520
-
-+/*
-+ * Graphics Co-processor
-+ */
- #define CO_REG_CONTROL 0xbf011
-+#define CO_CTRL_BUSY 0x80
-+#define CO_CTRL_CMDFULL 0x04
-+#define CO_CTRL_FIFOEMPTY 0x02
-+#define CO_CTRL_READY 0x01
-+
- #define CO_REG_SRC_WIDTH 0xbf018
--#define CO_REG_PIX_FORMAT 0xbf01c
--#define CO_REG_FORE_MIX 0xbf048
--#define CO_REG_FOREGROUND 0xbf058
--#define CO_REG_WIDTH 0xbf060
--#define CO_REG_HEIGHT 0xbf062
-+#define CO_REG_PIXFMT 0xbf01c
-+#define CO_PIXFMT_32BPP 0x03
-+#define CO_PIXFMT_24BPP 0x02
-+#define CO_PIXFMT_16BPP 0x01
-+#define CO_PIXFMT_8BPP 0x00
-+
-+#define CO_REG_FGMIX 0xbf048
-+#define CO_FG_MIX_ZERO 0x00
-+#define CO_FG_MIX_SRC_AND_DST 0x01
-+#define CO_FG_MIX_SRC_AND_NDST 0x02
-+#define CO_FG_MIX_SRC 0x03
-+#define CO_FG_MIX_NSRC_AND_DST 0x04
-+#define CO_FG_MIX_DST 0x05
-+#define CO_FG_MIX_SRC_XOR_DST 0x06
-+#define CO_FG_MIX_SRC_OR_DST 0x07
-+#define CO_FG_MIX_NSRC_AND_NDST 0x08
-+#define CO_FG_MIX_SRC_XOR_NDST 0x09
-+#define CO_FG_MIX_NDST 0x0a
-+#define CO_FG_MIX_SRC_OR_NDST 0x0b
-+#define CO_FG_MIX_NSRC 0x0c
-+#define CO_FG_MIX_NSRC_OR_DST 0x0d
-+#define CO_FG_MIX_NSRC_OR_NDST 0x0e
-+#define CO_FG_MIX_ONES 0x0f
-+
-+#define CO_REG_FGCOLOUR 0xbf058
-+#define CO_REG_BGCOLOUR 0xbf05c
-+#define CO_REG_PIXWIDTH 0xbf060
-+#define CO_REG_PIXHEIGHT 0xbf062
- #define CO_REG_X_PHASE 0xbf078
- #define CO_REG_CMD_L 0xbf07c
-+#define CO_CMD_L_PATTERN_FGCOL 0x8000
-+#define CO_CMD_L_INC_LEFT 0x0004
-+#define CO_CMD_L_INC_UP 0x0002
-+
- #define CO_REG_CMD_H 0xbf07e
--#define CO_REG_SRC_PTR 0xbf170
-+#define CO_CMD_H_BGSRCMAP 0x8000 /* otherwise bg colour */
-+#define CO_CMD_H_FGSRCMAP 0x2000 /* otherwise fg colour */
-+#define CO_CMD_H_BLITTER 0x0800
-+
-+#define CO_REG_SRC1_PTR 0xbf170
-+#define CO_REG_SRC2_PTR 0xbf174
- #define CO_REG_DEST_PTR 0xbf178
- #define CO_REG_DEST_WIDTH 0xbf218
-
-@@ -269,6 +470,7 @@
- char *fb;
- char dev_name[32];
- unsigned int fb_size;
-+ unsigned int chip_id;
-
- /*
- * The following is a pointer to be passed into the
-@@ -288,10 +490,19 @@
- void (*disable_extregs)(struct cfb_info *);
- };
-
-+#define ID_IGA_1682 0
-+#define ID_CYBERPRO_2000 1
-+#define ID_CYBERPRO_2010 2
-+#define ID_CYBERPRO_5000 3
-+
-+struct fb_var_screeninfo;
-+
- /*
- * Note! Writing to the Cyber20x0 registers from an interrupt
- * routine is definitely a bad idea atm.
- */
- int cyber2000fb_attach(struct cyberpro_info *info, int idx);
- void cyber2000fb_detach(int idx);
--
-+void cyber2000fb_enable_extregs(struct cfb_info *cfb);
-+void cyber2000fb_disable_extregs(struct cfb_info *cfb);
-+void cyber2000fb_get_fb_var(struct cfb_info *cfb, struct fb_var_screeninfo *var);
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/video/dbmx1fb.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,2002 @@
-+/******************************************************************************
-+ Copyright (C) 2002 Motorola GSG-China
-+
-+ 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+*******************************************************************************/
-+/*****************************************************************************
-+ * File Name: dbmx1fb.c
-+ *
-+ * Progammers: Chen Ning, Zhang Juan
-+ *
-+ * Date of Creations: 10 DEC,2001
-+ *
-+ * Synopsis:
-+ *
-+ * Descirption: DB-MX1 LCD controller Linux frame buffer driver
-+ * This file is subject to the terms and conditions of the
-+ * GNU General Public License. See the file COPYING in the main
-+ * directory of this archive for more details.
-+ *
-+ * Modification History:
-+ * 10 DEC, 2001, initialization version, frame work for frame buffer driver
-+ *
-+*******************************************************************************/
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/ctype.h>
-+#include <linux/mm.h>
-+#include <linux/tty.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/fb.h>
-+#include <linux/delay.h>
-+#include <linux/wrapper.h>
-+#include <linux/selection.h>
-+#include <linux/console.h>
-+#include <linux/kd.h>
-+#include <linux/vt_kern.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/mach-types.h>
-+#include <asm/uaccess.h>
-+#include <asm/proc/pgtable.h>
-+
-+#include <video/fbcon.h>
-+#include <video/fbcon-mfb.h>
-+#include <video/fbcon-cfb4.h>
-+#include <video/fbcon-cfb8.h>
-+#include <video/fbcon-cfb16.h>
-+
-+#include "asm/arch/hardware.h"
-+#include "asm/arch/platform.h"
-+#include "asm/arch/memory.h"
-+
-+#include "dbmx1fb.h"
-+
-+#undef SUP_TTY0
-+
-+#define LCD_PM
-+#ifdef LCD_PM
-+#include <linux/pm.h>
-+struct pm_dev *pm;
-+#endif
-+
-+// PLAM - make sure fbmem.c also has this defined for full screen frame
-+// buffer support in SDRAM
-+#define FULL_SCREEN
-+
-+#undef HARDWARE_CURSOR
-+// #undef HARDWARE_CURSOR
-+#undef DEBUG
-+
-+
-+/********************************************************************************/
-+#ifdef DEBUG
-+# define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
-+#define FUNC_START DPRINTK(KERN_ERR"start\n");
-+#define FUNC_END DPRINTK(KERN_ERR"end\n");
-+#else
-+# define DPRINTK(fmt, args...)
-+#define FUNC_START
-+#define FUNC_END
-+#endif
-+
-+#define _IO_ADDRESS(r) ((r)+0xf0000000)
-+unsigned int READREG(unsigned int r)
-+{
-+ volatile unsigned int * reg;
-+ reg = (volatile unsigned int*) _IO_ADDRESS(r);
-+ return *reg;
-+}
-+void WRITEREG(unsigned int r, unsigned int val)
-+{
-+ volatile unsigned int *reg;
-+ reg = (volatile unsigned int*) _IO_ADDRESS(r);
-+ *reg = val;
-+ return;
-+}
-+
-+#define FONT_DATA ((unsigned char *)font->data)
-+struct fbcon_font_desc *font;
-+
-+/* Local LCD controller parameters */
-+struct dbmx1fb_par{
-+ u_char *screen_start_address; /* Screen Start Address */
-+ u_char *v_screen_start_address;/* Virtul Screen Start Address */
-+ unsigned long screen_memory_size; /* screen memory size */
-+ unsigned int palette_size;
-+ unsigned int max_xres;
-+ unsigned int max_yres;
-+ unsigned int xres;
-+ unsigned int yres;
-+ unsigned int xres_virtual;
-+ unsigned int yres_virtual;
-+ unsigned int max_bpp;
-+ unsigned int bits_per_pixel;
-+ unsigned int currcon;
-+ unsigned int visual;
-+ unsigned int TFT :1;
-+ unsigned int color :1 ;
-+ unsigned int sharp :1 ;
-+
-+ unsigned short cfb16[16];
-+};
-+
-+#ifdef HARDWARE_CURSOR
-+/* hardware cursor parameters */
-+struct dbmx1fb_cursor{
-+ // int enable;
-+ int startx;
-+ int starty;
-+ int blinkenable;
-+ int blink_rate;
-+ int width;
-+ int height;
-+ int color[3];
-+ int state;
-+};
-+
-+/* Frame buffer of LCD information */
-+struct dbmx1fb_info{
-+ struct display_switch dispsw;
-+ struct dbmx1fb_cursor cursor;
-+};
-+#endif // HARDWARE_CURSOR
-+
-+static u_char* p_framebuffer_memory_address;
-+static u_char* v_framebuffer_memory_address;
-+
-+/* Fake monspecs to fill in fbinfo structure */
-+static struct fb_monspecs monspecs __initdata = {
-+ 30000, 70000, 50, 65, 0 /* Generic */
-+};
-+
-+/* color map initial */
-+static unsigned short __attribute__((unused)) color4map[16] = {
-+ 0x0000, 0x000f, 0x00f0, 0x0f2a, 0x0f00, 0x0f0f, 0x0f88, 0x0ccc,
-+ 0x0888, 0x00ff, 0x00f8, 0x0f44, 0x0fa6, 0x0f22, 0x0ff0, 0x0fff
-+};
-+
-+static unsigned short gray4map[16] = {
-+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
-+ 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f
-+};
-+
-+static struct display global_disp; /* Initial (default) Display Settings */
-+static struct fb_info fb_info;
-+static struct fb_var_screeninfo init_var = {};
-+static struct dbmx1fb_par current_par={ };
-+
-+/* Frame buffer device API */
-+static int dbmx1fb_get_fix(struct fb_fix_screeninfo *fix, int con,
-+ struct fb_info *info);
-+static int dbmx1fb_get_var(struct fb_var_screeninfo *var, int con,
-+ struct fb_info *info);
-+static int dbmx1fb_set_var(struct fb_var_screeninfo *var, int con,
-+ struct fb_info *info);
-+static int dbmx1fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-+ struct fb_info *info);
-+static int dbmx1fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-+ struct fb_info *info);
-+
-+/* Interface to the low level driver */
-+static int dbmx1fb_switch(int con, struct fb_info *info);
-+static void dbmx1fb_blank(int blank, struct fb_info *info);
-+static int dbmx1fb_updatevar(int con, struct fb_info *info);
-+
-+/* Internal routines */
-+static int _reserve_fb_memory(void);
-+static void _install_cmap(int con, struct fb_info *info);
-+static void _enable_lcd_controller(void);
-+static void _disable_lcd_controller(void);
-+static int _encode_var(struct fb_var_screeninfo *var,
-+ struct dbmx1fb_par *par);
-+static int _decode_var(struct fb_var_screeninfo *var,
-+ struct dbmx1fb_par *par);
-+
-+/* initialization routines */
-+static void __init _init_lcd_system(void);
-+static int __init _init_lcd(void);
-+static void __init _init_fbinfo(void);
-+static int __init _reserve_fb_memory(void);
-+
-+/* frame buffer ops */
-+static struct fb_ops dbmx1fb_ops = {
-+ owner: THIS_MODULE,
-+ fb_get_fix: dbmx1fb_get_fix,
-+ fb_get_var: dbmx1fb_get_var,
-+ fb_set_var: dbmx1fb_set_var,
-+ fb_get_cmap: dbmx1fb_get_cmap,
-+ fb_set_cmap: dbmx1fb_set_cmap,
-+};
-+
-+#ifdef HARDWARE_CURSOR
-+/* Hardware Cursor */
-+static void dbmx1fb_cursor(struct display *p, int mode, int x, int y);
-+static int dbmx1fb_set_font(struct display *d, int width, int height);
-+static UINT8 cursor_color_map[] = {0xf8};
-+static void dbmx1fb_set_cursor_state(struct dbmx1fb_info *fb,UINT32 state);
-+static void dbmx1fb_set_cursor(struct dbmx1fb_info *fb);
-+static void dbmx1fb_set_cursor_blink(struct dbmx1fb_info *fb,int blink);
-+
-+struct display_switch dbmx1fb_cfb4 = {
-+ setup: fbcon_cfb4_setup,
-+ bmove: fbcon_cfb4_bmove,
-+ clear: fbcon_cfb4_clear,
-+ putc: fbcon_cfb4_putc,
-+ putcs: fbcon_cfb4_putcs,
-+ revc: fbcon_cfb4_revc,
-+ cursor: dbmx1fb_cursor,
-+ set_font: dbmx1fb_set_font,
-+ fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(16)
-+};
-+
-+struct display_switch dbmx1fb_cfb8 = {
-+ setup: fbcon_cfb8_setup,
-+ bmove: fbcon_cfb8_bmove,
-+ clear: fbcon_cfb8_clear,
-+ putc: fbcon_cfb8_putc,
-+ putcs: fbcon_cfb8_putcs,
-+ revc: fbcon_cfb8_revc,
-+ cursor: dbmx1fb_cursor,
-+ set_font: dbmx1fb_set_font,
-+ fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(16)
-+};
-+
-+struct display_switch dbmx1fb_cfb16 = {
-+ setup: fbcon_cfb16_setup,
-+ bmove: fbcon_cfb16_bmove,
-+ clear: fbcon_cfb16_clear,
-+ putc: fbcon_cfb16_putc,
-+ putcs: fbcon_cfb16_putcs,
-+ revc: fbcon_cfb16_revc,
-+ cursor: dbmx1fb_cursor,
-+ set_font: dbmx1fb_set_font,
-+ fontwidthmask: FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(16)
-+};
-+#endif // HARDWARE_CURSOR
-+
-+
-+/*****************************************************************************
-+ * Function Name: dbmx1fb_getcolreg()
-+ *
-+ * Input: regno : Color register ID
-+ * red : Color map red[]
-+ * green : Color map green[]
-+ * blue : Color map blue[]
-+ * transparent : Flag
-+ * info : Fb_info database
-+ *
-+ * Value Returned: int : Return status.If no error, return 0.
-+ *
-+ * Description: Transfer to fb_xxx_cmap handlers as parameters to
-+ * control color registers
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+#define RED 0xf00
-+#define GREEN 0xf0
-+#define BLUE 0x0f
-+static int dbmx1fb_getcolreg(u_int regno, u_int *red, u_int *green,
-+ u_int *blue, u_int *trans, struct fb_info *info)
-+{
-+ unsigned int val;
-+
-+ FUNC_START;
-+
-+ if(regno >= current_par.palette_size)
-+ return 1;
-+
-+ val = READREG(DBMX1_LCD_MAPRAM+regno);
-+
-+ if((current_par.bits_per_pixel == 4)&&(!current_par.color))
-+ {
-+ *red = *green = *blue = (val & BLUE) << 4;//TODO:
-+ *trans = 0;
-+ }
-+ else
-+ {
-+ *red = (val & RED) << 4;
-+ *green = (val & GREEN) << 8;
-+ *blue = (val & BLUE) << 12;
-+ *trans = 0;
-+ }
-+
-+ FUNC_END;
-+ return 0;
-+}
-+
-+/*****************************************************************************
-+ * Function Name: dbmx1fb_setcolreg()
-+ *
-+ * Input: regno : Color register ID
-+ * red : Color map red[]
-+ * green : Color map green[]
-+ * blue : Color map blue[]
-+ * transparent : Flag
-+ * info : Fb_info database
-+ *
-+ * Value Returned: int : Return status.If no error, return 0.
-+ *
-+ * Description: Transfer to fb_xxx_cmap handlers as parameters to
-+ * control color registers
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+ *****************************************************************************/
-+static int
-+dbmx1fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-+ u_int trans, struct fb_info *info)
-+{
-+ unsigned int val=0;
-+ FUNC_START
-+ if(regno >= current_par.palette_size)
-+ return 1;
-+
-+ if((current_par.bits_per_pixel == 4)&&(!current_par.color))
-+ val = (blue & 0x00f) << 12;//TODO:
-+ else
-+ {
-+ val = (blue >> 12 ) & BLUE;
-+ val |= (green >> 8) & GREEN;
-+ val |= (red >> 4) & RED;
-+ }
-+
-+ if (regno < 16) {
-+ current_par.cfb16[regno] =
-+ regno | regno << 5 | regno << 10;
-+}
-+
-+ WRITEREG(DBMX1_LCD_MAPRAM+regno, val);
-+ FUNC_END;
-+ return 0;
-+}
-+
-+/*****************************************************************************
-+ * Function Name: dbmx1fb_get_cmap()
-+ *
-+ * Input: cmap : Ouput data pointer
-+ * kspc : Kernel space flag
-+ * con : Console ID
-+ * info : Frame buffer information
-+ *
-+ * Value Returned: int : Return status.If no error, return 0.
-+ *
-+ * Description: Data is copied from hardware or local or system DISPAY,
-+ * and copied to cmap.
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static int
-+dbmx1fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-+ struct fb_info *info)
-+{
-+ int err = 0;
-+
-+ FUNC_START;
-+ DPRINTK("current_par.visual=%d\n", current_par.visual);
-+ if (con == current_par.currcon)
-+ err = fb_get_cmap(cmap, kspc, dbmx1fb_getcolreg, info);
-+ else if (fb_display[con].cmap.len)
-+ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
-+ else
-+ fb_copy_cmap(fb_default_cmap(current_par.palette_size),
-+ cmap, kspc ? 0 : 2);
-+ FUNC_END;
-+ return err;
-+}
-+
-+/*****************************************************************************
-+ * Function Name: dbmx1fb_set_cmap()
-+ *
-+ * Input: cmap : Ouput data pointer
-+ * kspc : Kernel space flag
-+ * con : Console ID
-+ * info : Frame buffer information
-+ *
-+ * Value Returned: int : Return status.If no error, return 0.
-+ *
-+ * Description: Copy data from cmap and copy to DISPLAY. If DISPLAy has no cmap,
-+ * allocate memory for it. If DISPLAY is current console and visible,
-+ * then hardware color map shall be set.
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static int
-+dbmx1fb_set_cmap(struct fb_cmap *cmap, int kspc, int con, struct fb_info *info)
-+{
-+ int err = 0;
-+
-+ FUNC_START;
-+ DPRINTK("current_par.visual=%d\n", current_par.visual);
-+ if (!fb_display[con].cmap.len)
-+ err = fb_alloc_cmap(&fb_display[con].cmap,
-+ current_par.palette_size, 0);
-+
-+ if (!err) {
-+ if (con == current_par.currcon)
-+ err = fb_set_cmap(cmap, kspc, dbmx1fb_setcolreg,
-+ info);
-+ fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
-+ }
-+ FUNC_END;
-+ return err;
-+}
-+/*****************************************************************************
-+ * Function Name: dbmx1fb_get_var()
-+ *
-+ * Input: var : Iuput data pointer
-+ * con : Console ID
-+ * info : Frame buffer information
-+ *
-+ * Value Returned: int : Return status.If no error, return 0.
-+ *
-+ * Functions Called: _encode_var()
-+ *
-+ * Description: Get color map from current, or global display[console]
-+ * used by ioctl
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static int
-+dbmx1fb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-+{
-+ if (con == -1) {
-+ _encode_var(var, &current_par);
-+ } else
-+ *var = fb_display[con].var;
-+ return 0;
-+}
-+
-+
-+/*****************************************************************************
-+ * Function Name: dbmx1fb_updatevar()
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called: VOID
-+ *
-+ * Description: Fill in display switch with LCD information,
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static int dbmx1fb_updatevar(int con, struct fb_info *info)
-+{
-+ DPRINTK("entered\n");
-+ return 0;
-+}
-+
-+
-+/*****************************************************************************
-+ * Function Name: dbmx1fb_set_dispsw()
-+ *
-+ * Input: display : Iuput data pointer
-+ * dbmx1fb_info : Frame buffer of LCD information
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called: VOID
-+ *
-+ * Description: Fill in display switch with LCD information,
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static void dbmx1fb_set_dispsw(struct display *disp
-+#ifdef HARDWARE_CURSOR
-+ ,struct dbmx1fb_info *info
-+#endif
-+ )
-+{
-+ FUNC_START;
-+ switch (disp->var.bits_per_pixel) {
-+#ifdef HARDWARE_CURSOR
-+#ifdef FBCON_HAS_CFB4
-+ case 4:
-+ fb_info.fix.visual = FB_VISUAL_PSEUDOCOLOR;
-+ info->dispsw = dbmx1fb_cfb4;
-+ disp->dispsw = &info->dispsw;
-+ disp->dispsw_data = NULL;
-+ break;
-+#endif
-+#ifdef FBCON_HAS_CFB8
-+ case 8:
-+ fb_info.fix.visual = FB_VISUAL_PSEUDOCOLOR;
-+ info->dispsw = dbmx1fb_cfb8;
-+ disp->dispsw = &info->dispsw;
-+ disp->dispsw_data = NULL;
-+ break;
-+#endif
-+#ifdef FBCON_HAS_CFB16
-+ case 12:
-+ case 16:
-+ fb_info.fix.visual = FB_VISUAL_DIRECTCOLOR;
-+ info->dispsw = dbmx1fb_cfb16;
-+ disp->dispsw = &info->dispsw;
-+ disp->dispsw_data = current_par.cfb16;
-+ break;
-+#endif
-+#else //!HARDWARE_CURSOR
-+ /* first step disable the hardware cursor */
-+#ifdef FBCON_HAS_CFB4
-+ case 4:
-+ fb_info.fix.visual = FB_VISUAL_PSEUDOCOLOR;
-+ disp->dispsw = &fbcon_cfb4;
-+ disp->dispsw_data = NULL;
-+ break;
-+#endif
-+#ifdef FBCON_HAS_CFB8
-+ case 8:
-+ fb_info.fix.visual = FB_VISUAL_PSEUDOCOLOR;
-+ disp->dispsw = &fbcon_cfb8;
-+ disp->dispsw_data = NULL;
-+ break;
-+#endif
-+#ifdef FBCON_HAS_CFB16
-+ case 12:
-+ case 16:
-+ fb_info.fix.visual = FB_VISUAL_DIRECTCOLOR;
-+ disp->dispsw = &fbcon_cfb16;
-+ disp->dispsw_data = current_par.cfb16;
-+ break;
-+#endif
-+
-+#endif // HARDWARE_CURSOR
-+ default:
-+ disp->dispsw = &fbcon_dummy;
-+ disp->dispsw_data = NULL;
-+ }
-+#ifdef HARDWARE_CURSOR
-+ if (&info->cursor)
-+ {
-+ info->dispsw.cursor = dbmx1fb_cursor;
-+ info->dispsw.set_font = dbmx1fb_set_font;
-+ }
-+#endif // HARDWARE_CURSOR
-+ FUNC_END;
-+}
-+
-+/*****************************************************************************
-+ * Function Name: dbmx1fb_set_var()
-+ *
-+ * Input: var : Iuput data pointer
-+ * con : Console ID
-+ * info : Frame buffer information
-+ *
-+ * Value Returned: int : Return status.If no error, return 0.
-+ *
-+ * Functions Called: dbmx1fb_decode_var()
-+ * dbmx1fb_encode_var()
-+ * dbmx1fb_set_dispsw()
-+ *
-+ * Description: set current_par by var, also set display data, specially the console
-+ * related fileops, then enable the lcd controller, and set cmap to
-+ * hardware.
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static int
-+dbmx1fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
-+{
-+ struct display *display;
-+ int err, chgvar = 0;
-+ struct dbmx1fb_par par;
-+
-+ FUNC_START;
-+ if (con >= 0)
-+ display = &fb_display[con]; /* Display settings for console */
-+ else
-+ display = &global_disp; /* Default display settings */
-+
-+ /* Decode var contents into a par structure, adjusting any */
-+ /* out of range values. */
-+ if ((err = _decode_var(var, &par))){
-+ DPRINTK("decode var error!");
-+ return err;
-+ }
-+
-+ // Store adjusted par values into var structure
-+ _encode_var(var, &par);
-+
-+ if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)
-+ return 0;
-+
-+ else if (((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) &&
-+ ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NXTOPEN))
-+ return -EINVAL;
-+
-+ if (con >= 0) {
-+ if ((display->var.xres != var->xres) ||
-+ (display->var.yres != var->yres) ||
-+ (display->var.xres_virtual != var->xres_virtual) ||
-+ (display->var.yres_virtual != var->yres_virtual) ||
-+ (display->var.sync != var->sync) ||
-+ (display->var.bits_per_pixel != var->bits_per_pixel) ||
-+ (memcmp(&display->var.red, &var->red, sizeof(var->red))) ||
-+ (memcmp(&display->var.green, &var->green, sizeof(var->green)
-+ )) ||
-+ (memcmp(&display->var.blue, &var->blue, sizeof(var->blue))))
-+ chgvar = 1;
-+ }
-+
-+ display->var = *var;
-+ display->screen_base = par.v_screen_start_address;
-+ display->visual = par.visual;
-+ display->type = FB_TYPE_PACKED_PIXELS;
-+ display->type_aux = 0;
-+ display->ypanstep = 0;
-+ display->ywrapstep = 0;
-+ display->line_length =
-+ display->next_line = (var->xres * 16) / 8;
-+
-+ display->can_soft_blank = 1;
-+ display->inverse = 0;
-+
-+ dbmx1fb_set_dispsw(display
-+#ifdef HARDWARE_CURSOR
-+ , (struct dbmx1fb_info *)info
-+#endif // HARDWARE_CURSOR
-+ );
-+
-+ /* If the console has changed and the console has defined */
-+ /* a changevar function, call that function. */
-+ if (chgvar && info && info->changevar)
-+ info->changevar(con); // TODO:
-+
-+ /* If the current console is selected and it's not truecolor,
-+ * update the palette
-+ */
-+ if ((con == current_par.currcon) &&
-+ (current_par.visual != FB_VISUAL_TRUECOLOR)) {
-+ struct fb_cmap *cmap;
-+
-+ current_par = par; // TODO ?
-+ if (display->cmap.len)
-+ cmap = &display->cmap;
-+ else
-+ cmap = fb_default_cmap(current_par.palette_size);
-+
-+ fb_set_cmap(cmap, 1, dbmx1fb_setcolreg, info);
-+ }
-+
-+ /* If the current console is selected, activate the new var. */
-+ if (con == current_par.currcon){
-+ init_var = *var; // TODO:gcc support structure copy?
-+ _enable_lcd_controller();
-+ }
-+
-+ FUNC_END;
-+ return 0;
-+}
-+
-+/*****************************************************************************
-+ * Function Name: dbmx1fb_get_fix()
-+ *
-+ * Input: fix : Ouput data pointer
-+ * con : Console ID
-+ * info : Frame buffer information
-+ *
-+ * Value Returned: int : Return status.If no error, return 0.
-+ *
-+ * Functions Called: VOID
-+ *
-+ * Description: get fix from display data, current_par data
-+ * used by ioctl
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static int
-+dbmx1fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
-+{
-+ struct display *display;
-+
-+ FUNC_START;
-+ memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-+ strcpy(fix->id, DBMX1_NAME);
-+
-+ if (con >= 0)
-+ {
-+ DPRINTK("Using console specific display for con=%d\n",con);
-+ display = &fb_display[con]; /* Display settings for console */
-+ }
-+ else
-+ display = &global_disp; /* Default display settings */
-+
-+ fix->smem_start = (unsigned long)current_par.screen_start_address;
-+ fix->smem_len = current_par.screen_memory_size;
-+//printk("dbmx1fb_get_fix, pointer fix: 0x%08x, smem_len: 0x%08x\n",fix,fix->smem_len);
-+ fix->type = display->type;
-+ fix->type_aux = display->type_aux;
-+ fix->xpanstep = 0;
-+ fix->ypanstep = display->ypanstep;
-+ fix->ywrapstep = display->ywrapstep;
-+ fix->visual = display->visual;
-+ fix->line_length = display->line_length;
-+ fix->accel = FB_ACCEL_NONE;
-+
-+ FUNC_END;
-+ return 0;
-+}
-+
-+/*****************************************************************************
-+ * Function Name: dbmx1fb_inter_handler()
-+ *
-+ * Input:
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called: VOID
-+ *
-+ * Description: Interrupt handler
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static void dbmx1fb_inter_handler(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ unsigned int intsr;
-+ FUNC_START;
-+ intsr = READREG(DBMX1_LCD_INTSR); // read to clear status
-+ printk(KERN_ERR"lcd interrupt!\n");
-+ FUNC_END;
-+ // handle
-+}
-+
-+#ifdef LCD_PM
-+#define PM_OPT " [pm]"
-+#define LCD_PMST_RESUME 0
-+#define LCD_PMST_SUSPEND 1
-+static unsigned int lcd_pm_status = LCD_PMST_RESUME;
-+
-+void lcd_pm_resume(void)
-+{
-+ if(lcd_pm_status == LCD_PMST_RESUME)
-+ return;
-+ WRITEREG(0x21c21c, 0x10000); // light on
-+ WRITEREG(DBMX1_LCD_REFMCR, 0xf000002);
-+ WRITEREG(DBMX1_LCD_PWMR, 0x00a9008a);
-+ lcd_pm_status = LCD_PMST_RESUME;
-+// printk(KERN_ERR"lcd resumed\n");
-+}
-+
-+void lcd_pm_suspend(void)
-+{
-+ unsigned val;
-+ if(lcd_pm_status == LCD_PMST_SUSPEND)
-+ return;
-+ val = READREG(0x20502c);
-+ val |= 0x8000;
-+ WRITEREG(0x20502c, val);
-+ //To produce enough dealy time before trun off the LCDC.
-+ for(val=0;val<=600000;val++);
-+ val = READREG(0x21c21c);
-+ val &= ~0x10000;
-+ WRITEREG(0x21c21c, val); // light off
-+ WRITEREG(DBMX1_LCD_REFMCR, 0x0);
-+ lcd_pm_status = LCD_PMST_SUSPEND;
-+// printk(KERN_ERR"lcd suspended\n");
-+}
-+
-+int lcd_pm_handler(struct pm_dev *dev, pm_request_t rqst, void *data)
-+{
-+ switch(rqst){
-+ case PM_RESUME:
-+ lcd_pm_resume();
-+ break;
-+ case PM_SUSPEND:
-+ lcd_pm_suspend();
-+ break;
-+ default:
-+ break;
-+ }
-+ return 0;
-+}
-+#endif // LCD_PM
-+
-+/*****************************************************************************
-+ * Function Name: dbmx1fb_init()
-+ *
-+ * Input: VOID
-+ *
-+ * Value Returned: int : Return status.If no error, return 0.
-+ *
-+ * Functions Called: _init_fbinfo()
-+ * disable_irq()
-+ * enable_irq()
-+ * _init_lcd()
-+ * dbmx1fb_init_cursor()
-+ *
-+ * Description: initialization module, all of init routine's entry point
-+ * initialize fb_info, init_var, current_par
-+ * and setup interrupt, memory, lcd controller
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+int __init dbmx1fb_init(void)
-+{
-+ int ret;
-+#ifdef HARDWARE_CURSOR
-+ struct dbmx1fb_info *info;
-+#endif // HARDWARE_CURSOR
-+
-+ _init_lcd_system();
-+
-+ _init_fbinfo();
-+
-+ if ((ret = _reserve_fb_memory()) != 0){
-+ printk(KERN_ERR"failed for reserved DBMX frame buffer memory\n");
-+ return ret;
-+ }
-+
-+#if 0
-+ if (request_irq(IRQ_LCD,
-+ dbmx1fb_inter_handler,
-+ SA_INTERRUPT,
-+ DEV_NAME,
-+ NULL) != 0) {
-+ printk(KERN_ERR "dbmx1fb: failed in request_irq\n");
-+ return -EBUSY;
-+ }
-+
-+ disable_irq(IRQ_LCD);
-+#endif
-+ if (dbmx1fb_set_var(&init_var, -1, &fb_info))
-+ ; //current_par.allow_modeset = 0;
-+
-+ _init_lcd();
-+ _enable_lcd_controller();
-+
-+#ifdef HARDWARE_CURSOR
-+ info = kmalloc(sizeof(struct dbmx1fb_info), GFP_KERNEL);
-+ if(info == NULL){
-+ printk(KERN_ERR"can not kmalloc dbmx1fb_info memory\n");
-+ return -1;
-+ }
-+
-+ memset(info,0,sizeof(struct dbmx1fb_info));
-+
-+ info->cursor.blink_rate = DEFAULT_CURSOR_BLINK_RATE;
-+ info->cursor.blinkenable = 0;
-+ info->cursor.state = LCD_CURSOR_OFF;
-+ WRITEREG(DBMX1_LCD_LCXYP,0x90010001);
-+ WRITEREG(DBMX1_LCD_CURBLKCR,0x1F1F0000);
-+ WRITEREG(DBMX1_LCD_LCHCC,0x0000F800);
-+
-+ DPRINTK(KERN_ERR"LCXYP = %x\n",READREG(DBMX1_LCD_LCXYP));
-+ DPRINTK(KERN_ERR"CURBLICR = %x\n",READREG(DBMX1_LCD_CURBLKCR));
-+ DPRINTK(KERN_ERR"LCHCC = %x\n",READREG(DBMX1_LCD_LCHCC));
-+
-+ //dbmx1fb_set_cursor(info);
-+ //info->cursor = dbmx1fb_init_cursor(info);
-+#endif // HARDWARE_CURSOR
-+
-+ register_framebuffer(&fb_info);
-+
-+#ifdef LCD_PM
-+ pm = pm_register(PM_SYS_DEV, PM_SYS_VGA, lcd_pm_handler);
-+ printk("register LCD power management successfully.\n");
-+#endif
-+#if 0
-+ enable_irq(IRQ_LCD); // TODO:
-+#endif
-+ /* This driver cannot be unloaded at the moment */
-+ MOD_INC_USE_COUNT;
-+
-+ return 0;
-+}
-+
-+/*****************************************************************************
-+ * Function Name: dbmx1fb_setup()
-+ *
-+ * Input: info : VOID
-+ *
-+ * Value Returned: int : Return status.If no error, return 0.
-+ *
-+ * Functions Called: VOID
-+ *
-+ * Description: basically, this routine used to parse command line parameters, which
-+ * is initialization parameters for lcd controller, such as freq, xres,
-+ * yres, and so on
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+int __init dbmx1fb_setup(char *options)
-+{
-+ FUNC_START;
-+ FUNC_END;
-+ return 0;
-+}
-+
-+/*****************************************************************************
-+ * Function Name: _init_fbinfo()
-+ *
-+ * Input: VOID
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called: VOID
-+ *
-+ * Description: while 16bpp is used to store a 12 bits pixels packet, but
-+ * it is not a really 16bpp system. maybe in-compatiable with
-+ * other system or GUI.There are some field in var which specify
-+ * the red/green/blue offset in a 16bit word, just little endian is
-+ * concerned
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static void __init _init_fbinfo(void)
-+{
-+// Thomas Wong add this for debugging
-+// *((unsigned char *)0xF5000008) = '&';
-+
-+ FUNC_START;
-+ strcpy(fb_info.modename, DBMX1_NAME);
-+ strcpy(fb_info.fontname, "Acorn8x8");
-+
-+ fb_info.node = -1;
-+ fb_info.flags = FBINFO_FLAG_DEFAULT; // Low-level driver is not a module
-+ fb_info.fbops = &dbmx1fb_ops;
-+ fb_info.monspecs = monspecs;
-+ fb_info.disp = &global_disp;
-+ fb_info.changevar = NULL;
-+ fb_info.switch_con = dbmx1fb_switch;
-+ fb_info.updatevar = dbmx1fb_updatevar;
-+ fb_info.blank = dbmx1fb_blank;
-+
-+/*
-+ * * setup initial parameters
-+ * */
-+ memset(&init_var, 0, sizeof(init_var));
-+
-+ init_var.transp.length = 0;
-+ init_var.nonstd = 0;
-+ init_var.activate = FB_ACTIVATE_NOW;
-+ init_var.xoffset = 0;
-+ init_var.yoffset = 0;
-+ init_var.height = -1;
-+ init_var.width = -1;
-+ init_var.vmode = FB_VMODE_NONINTERLACED;
-+
-+ if (1) {
-+ current_par.max_xres = LCD_MAXX;
-+ current_par.max_yres = LCD_MAXY;
-+ current_par.max_bpp = LCD_MAX_BPP; // 12
-+ init_var.red.length = 5; // 5;
-+ init_var.green.length = 6; // 6;
-+ init_var.blue.length = 5; // 5;
-+#ifdef __LITTLE_ENDIAN
-+ init_var.red.offset = 11;
-+ init_var.green.offset = 5;
-+ init_var.blue.offset = 0;
-+#endif //__LITTLE_ENDIAN
-+ init_var.grayscale = 16; // i suppose, TODO
-+ init_var.sync = 0;
-+ init_var.pixclock = 171521; // TODO
-+ }
-+
-+ current_par.screen_start_address = NULL;
-+ current_par.v_screen_start_address = NULL;
-+ current_par.screen_memory_size = MAX_PIXEL_MEM_SIZE;
-+// Thomas Wong add this for debugging
-+//printk("_init_fbinfo, pointer to current_par: 0x%08x, screen_memory_size: 0x%08x\n", &current_par,current_par.screen_memory_size);
-+ current_par.currcon = -1; // TODO
-+
-+ init_var.xres = current_par.max_xres;
-+ init_var.yres = current_par.max_yres;
-+ init_var.xres_virtual = init_var.xres;
-+ init_var.yres_virtual = init_var.yres;
-+ init_var.bits_per_pixel = current_par.max_bpp;
-+
-+ FUNC_END;
-+}
-+
-+/*****************************************************************************
-+ * Function Name: dbmx1fb_blank()
-+ *
-+ * Input: blank : Blank flag
-+ * info : Frame buffer database
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called: _enable_lcd_controller()
-+ * _disable_lcd_controller()
-+ *
-+ * Description: blank the screen, if blank, disable lcd controller, while if no blank
-+ * set cmap and enable lcd controller
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static void
-+dbmx1fb_blank(int blank, struct fb_info *info)
-+{
-+#ifdef SUP_TTY0
-+ int i;
-+
-+ FUNC_START;
-+ DPRINTK("blank=%d info->modename=%s\n", blank, info->modename);
-+ if (blank) {
-+ if (current_par.visual != FB_VISUAL_TRUECOLOR)
-+ for (i = 0; i < current_par.palette_size; i++)
-+ ; // TODO
-+//printk("Disable LCD\n");
-+ _disable_lcd_controller();
-+ }
-+ else {
-+ if (current_par.visual != FB_VISUAL_TRUECOLOR)
-+ dbmx1fb_set_cmap(&fb_display[current_par.currcon].cmap,
-+ 1,
-+ current_par.currcon, info);
-+//printk("Enable LCD\n");
-+ _enable_lcd_controller();
-+ }
-+ FUNC_END;
-+#endif //SUP_TTY0
-+}
-+
-+/*****************************************************************************
-+ * Function Name: dbmx1fb_switch()
-+ *
-+ * Input: info : Frame buffer database
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called:
-+ *
-+ * Description: Switch to another console
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static int dbmx1fb_switch(int con, struct fb_info *info)
-+{
-+ FUNC_START;
-+ if (current_par.visual != FB_VISUAL_TRUECOLOR) {
-+ struct fb_cmap *cmap;
-+ if (current_par.currcon >= 0) {
-+ // Get the colormap for the selected console
-+ cmap = &fb_display[current_par.currcon].cmap;
-+
-+ if (cmap->len)
-+ fb_get_cmap(cmap, 1, dbmx1fb_getcolreg, info);
-+ }
-+ }
-+
-+ current_par.currcon = con;
-+ fb_display[con].var.activate = FB_ACTIVATE_NOW;
-+ dbmx1fb_set_var(&fb_display[con].var, con, info);
-+ FUNC_END;
-+ return 0;
-+}
-+
-+/*****************************************************************************
-+ * Function Name: _encode_par()
-+ *
-+ * Input: var : Input var data
-+ * par : LCD controller parameters
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called:
-+ *
-+ * Description: use current_par to set a var structure
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static int _encode_var(struct fb_var_screeninfo *var,
-+ struct dbmx1fb_par *par)
-+{
-+ // Don't know if really want to zero var on entry.
-+ // Look at set_var to see. If so, may need to add extra params to par
-+
-+ // memset(var, 0, sizeof(struct fb_var_screeninfo));
-+
-+ var->xres = par->xres;
-+ var->yres = par->yres;
-+ var->xres_virtual = par->xres_virtual;
-+ var->yres_virtual = par->yres_virtual;
-+
-+ var->bits_per_pixel = par->bits_per_pixel;
-+
-+ DPRINTK("var->bits_per_pixel=%d\n", var->bits_per_pixel);
-+ switch(var->bits_per_pixel) {
-+ case 2:
-+ case 4:
-+ case 8:
-+ var->red.length = 4;
-+ var->green = var->red;
-+ var->blue = var->red;
-+ var->transp.length = 0;
-+ break;
-+ case 12: // This case should differ for Active/Passive mode
-+ case 16:
-+ if (1) {
-+ var->red.length = 4;
-+ var->blue.length = 4;
-+ var->green.length = 4;
-+ var->transp.length = 0;
-+#ifdef __LITTLE_ENDIAN
-+ var->red.offset = 8;
-+ var->green.offset = 4;
-+ var->blue.offset = 0;
-+ var->transp.offset = 0;
-+#endif // __LITTLE_ENDIAN
-+ }
-+ else
-+ {
-+ var->red.length = 5;
-+ var->blue.length = 5;
-+ var->green.length = 6;
-+ var->transp.length = 0;
-+ var->red.offset = 11;
-+ var->green.offset = 5;
-+ var->blue.offset = 0;
-+ var->transp.offset = 0;
-+ }
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+/*****************************************************************************
-+ * Function Name: _decode_var
-+ *
-+ * Input: var : Input var data
-+ * par : LCD controller parameters
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called: VOID
-+ *
-+ * Description: Get the video params out of 'var'. If a value doesn't fit,
-+ * round it up,if it's too big, return -EINVAL.
-+ *
-+ * Cautions: Round up in the following order: bits_per_pixel, xres,
-+ * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
-+ * bitfields, horizontal timing, vertical timing.
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static int _decode_var(struct fb_var_screeninfo *var,
-+ struct dbmx1fb_par *par)
-+{
-+ *par = current_par;
-+
-+ if ((par->xres = var->xres) < MIN_XRES)
-+ par->xres = MIN_XRES;
-+ if ((par->yres = var->yres) < MIN_YRES)
-+ par->yres = MIN_YRES;
-+ if (par->xres > current_par.max_xres)
-+ par->xres = current_par.max_xres;
-+ if (par->yres > current_par.max_yres)
-+ par->yres = current_par.max_yres;
-+ par->xres_virtual =
-+ var->xres_virtual < par->xres ? par->xres : var->xres_virtual;
-+ par->yres_virtual =
-+ var->yres_virtual < par->yres ? par->yres : var->yres_virtual;
-+ par->bits_per_pixel = var->bits_per_pixel;
-+
-+ switch (par->bits_per_pixel) {
-+#ifdef FBCON_HAS_CFB4
-+ case 4:
-+ par->visual = FB_VISUAL_PSEUDOCOLOR;
-+ par->palette_size = 16;
-+ break;
-+#endif
-+#ifdef FBCON_HAS_CFB8
-+ case 8:
-+ par->visual = FB_VISUAL_PSEUDOCOLOR;
-+ par->palette_size = 256;
-+ break;
-+#endif
-+#ifdef FBCON_HAS_CFB16
-+ case 12: // RGB 444
-+ case 16: /* RGB 565 */
-+ par->visual = FB_VISUAL_TRUECOLOR;
-+ par->palette_size = 0;
-+ break;
-+#endif
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ par->screen_start_address =(u_char*)(
-+ (u_long)p_framebuffer_memory_address+PAGE_SIZE);
-+ par->v_screen_start_address =(u_char*)(
-+ (u_long)v_framebuffer_memory_address+PAGE_SIZE);
-+
-+// Thomas Wong - try to change start address here (map to SRAM, instead of SDRAM)
-+#ifndef FULL_SCREEN
-+ par->screen_start_address =(u_char*)(0x00300000);
-+ par->v_screen_start_address =(u_char*)(0xF0300000);
-+#endif
-+
-+// par->screen_start_address =(u_char*)(0x0BE00000);
-+// par->v_screen_start_address =(u_char*)(0xFBE00000);
-+
-+// par->screen_start_address =(u_char*)(0x12000000);
-+// par->v_screen_start_address =(u_char*)(0xF2000000);
-+
-+ return 0;
-+}
-+
-+
-+/*****************************************************************************
-+ * Function Name: _reserve_fb_memory()
-+ *
-+ * Input: VOID
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called:
-+ *
-+ * Description: get data out of var structure and set related LCD controller registers
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static int __init _reserve_fb_memory(void)
-+{
-+ u_int required_pages;
-+ u_int extra_pages;
-+ u_int order;
-+ struct page *page;
-+ char *allocated_region;
-+
-+ DPRINTK("frame buffer memory size = %x\n", (unsigned int)ALLOCATED_FB_MEM_SIZE);
-+ if (v_framebuffer_memory_address != NULL)
-+ return -EINVAL;
-+
-+ /* Find order required to allocate enough memory for framebuffer */
-+ required_pages = ALLOCATED_FB_MEM_SIZE >> PAGE_SHIFT;
-+ for (order = 0 ; required_pages >> order ; order++) {;}
-+ extra_pages = (1 << order) - required_pages;
-+
-+ if ((allocated_region =
-+ (char *)__get_free_pages(GFP_KERNEL | GFP_DMA, order)) == NULL){
-+
-+ DPRINTK("can not allocated memory\n");
-+ return -ENOMEM;
-+ }
-+
-+
-+ v_framebuffer_memory_address = (u_char *)allocated_region +
-+ (extra_pages << PAGE_SHIFT);
-+ p_framebuffer_memory_address = (u_char *)__virt_to_phys(
-+ (u_long)v_framebuffer_memory_address);
-+#if 0
-+ printk(KERN_ERR"Frame buffer __get_free_pages vd:= %x, pd= %x",
-+ (unsigned int)v_framebuffer_memory_address,
-+ (unsigned int)p_framebuffer_memory_address);
-+#endif
-+ /* Free all pages that we don't need but were given to us because */
-+ /* __get_free_pages() works on powers of 2. */
-+ for (;extra_pages;extra_pages--)
-+ free_page((u_int)allocated_region + ((extra_pages-1) << PAGE_SHIFT));
-+
-+ /* Set reserved flag for fb memory to allow it to be remapped into */
-+ /* user space by the common fbmem driver using remap_page_range(). */
-+ for(page = virt_to_page(v_framebuffer_memory_address);
-+ page < virt_to_page(v_framebuffer_memory_address
-+ + ALLOCATED_FB_MEM_SIZE);
-+ page++)
-+ mem_map_reserve(page);
-+#if 0
-+ /* Remap the fb memory to a non-buffered, non-cached region */
-+ v_framebuffer_memory_address = (u_char *)__ioremap(
-+ (u_long)p_framebuffer_memory_address,
-+ ALLOCATED_FB_MEM_SIZE,
-+ L_PTE_PRESENT |
-+ L_PTE_YOUNG |
-+ L_PTE_DIRTY |
-+ L_PTE_WRITE);
-+#endif
-+ current_par.screen_start_address =(u_char*)(
-+ (u_long)p_framebuffer_memory_address+PAGE_SIZE);
-+ current_par.v_screen_start_address =(u_char*)(
-+ (u_long)v_framebuffer_memory_address+PAGE_SIZE);
-+
-+ DPRINTK("physical screen start addres: %x\n",
-+ (u_long)p_framebuffer_memory_address+PAGE_SIZE);
-+
-+#ifndef FULL_SCREEN
-+// Thomas Wong - we'll try to change the screen start address here
-+// printk("\n\rMap LCD screen to SDRAM.\n\r");
-+
-+ printk("\n\rMap LCD screen to embedded SRAM.\n\r");
-+ current_par.screen_start_address =(u_char*)(0x00300000);
-+ current_par.v_screen_start_address =(u_char*)(0xF0300000);
-+#endif
-+
-+// printk("\n\rMap LCD screen to SDRAM 0xFBE00000.\n\r");
-+// current_par.screen_start_address =(u_char*)(0x0BE00000);
-+// current_par.v_screen_start_address =(u_char*)(0xFBE00000);
-+
-+// printk("\n\rMap LCD screen to SRAM 0x12000000.\n\r");
-+// current_par.screen_start_address =(u_char*)(0x12000000);
-+// current_par.v_screen_start_address =(u_char*)(0xF2000000);
-+
-+ return (v_framebuffer_memory_address == NULL ? -EINVAL : 0);
-+}
-+
-+/*****************************************************************************
-+ * Function Name: _enable_lcd_controller()
-+ *
-+ * Input: VOID
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called:
-+ *
-+ * Description: enable Lcd controller, setup registers,
-+ * base on current_par value
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static void _enable_lcd_controller(void)
-+{
-+ unsigned int val;
-+#if 0
-+ int i;
-+ val =0;
-+
-+ FUNC_START;
-+ _decode_var(&init_var, &current_par);
-+
-+ val = current_par.xres/16;
-+ val <<= 20;
-+ val += current_par.yres;
-+ WRITEREG(DBMX1_LCD_XYMAX, val);
-+
-+ val=0;
-+ val=current_par.xres_virtual /2;
-+ WRITEREG(DBMX1_LCD_VPW, val);
-+
-+ switch(current_par.bits_per_pixel ){
-+ case 4: // for gray only
-+ for(i=0; i<16; i++){
-+ WRITEREG(DBMX1_LCD_MAPRAM+i, gray4map[i]);
-+ }
-+ WRITEREG(DBMX1_LCD_PANELCFG, PANELCFG_VAL_4);
-+ WRITEREG(DBMX1_LCD_VCFG, VCFG_VAL_4);
-+ WRITEREG(DBMX1_LCD_HCFG, HCFG_VAL_4);
-+ WRITEREG(DBMX1_LCD_INTCR, INTCR_VAL_4); // no interrupt
-+ WRITEREG(DBMX1_LCD_REFMCR, REFMCR_VAL_4);
-+ WRITEREG(DBMX1_LCD_DMACR, DMACR_VAL_4);
-+ WRITEREG(DBMX1_LCD_PWMR, PWMR_VAL);
-+ break;
-+ case 12:
-+ case 16:
-+ WRITEREG(DBMX1_LCD_PANELCFG, PANELCFG_VAL_12);
-+ WRITEREG(DBMX1_LCD_HCFG, HCFG_VAL_12);
-+ WRITEREG(DBMX1_LCD_VCFG, VCFG_VAL_12);
-+ WRITEREG(DBMX1_LCD_REFMCR, 0x0);
-+ WRITEREG(DBMX1_LCD_DMACR, DMACR_VAL_12);
-+ WRITEREG(DBMX1_LCD_PWMR, 0x00008200);
-+ WRITEREG(DBMX1_LCD_REFMCR, 0x0f000002);
-+ WRITEREG(DBMX1_LCD_PWMR, 0x0000008a);
-+
-+ break;
-+ }
-+#else
-+ val = READREG(0x21c21c);
-+ val |= 0x0010000;
-+ WRITEREG(0x21c21c, val);
-+
-+ WRITEREG(DBMX1_LCD_PWMR, 0x8200);
-+ WRITEREG(DBMX1_LCD_REFMCR, 0xf000002);
-+
-+ // Thomas Wong - we want 0x8A not 0x200
-+// WRITEREG(DBMX1_LCD_PWMR, 0x200);
-+// PLAM -- for rev2 (endian bit)
-+// WRITEREG(DBMX1_LCD_PWMR, 0x0000008A);
-+ WRITEREG(DBMX1_LCD_PWMR, 0x00A9008A);
-+// end PLAM
-+#endif
-+
-+ FUNC_END;
-+}
-+
-+/*****************************************************************************
-+ * Function Name: _disable_lcd_controller()
-+ *
-+ * Input: VOID
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called: VOID
-+ *
-+ * Description: just disable the LCD controller
-+ * disable lcd interrupt. others, i have no ideas
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static void _disable_lcd_controller(void)
-+{
-+ unsigned int val;
-+ val = READREG(0x21c21c);
-+ val &= ~0x0010000;
-+ WRITEREG(0x21c21c, val);
-+
-+ WRITEREG(DBMX1_LCD_PWMR, 0x8200);
-+// WRITEREG(DBMX1_LCD_REFMCR, DISABLELCD_VAL);
-+ WRITEREG(0x205034, 0x0);
-+}
-+
-+/*****************************************************************************
-+ * Function Name: _install_cmap
-+ *
-+ * Input: VOID
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called:
-+ *
-+ * Description: set color map to hardware
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static void _install_cmap(int con, struct fb_info *info)
-+{
-+ if (con != current_par.currcon)
-+ return ;
-+ if (fb_display[con].cmap.len)
-+ fb_set_cmap(&fb_display[con].cmap, 1, dbmx1fb_setcolreg, info);
-+ else
-+ fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
-+ 1,
-+ dbmx1fb_setcolreg,
-+ info);
-+ return ;
-+}
-+
-+/*****************************************************************************
-+ * Function Name: _init_lcd_system
-+ *
-+ * Input: VOID
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called:
-+ *
-+ * Description: initialize the gpio port C and port D with DMA enable
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static void __init _init_lcd_system(void)
-+{
-+unsigned int val;
-+
-+/* Thomas Wong - we don't need DMA here
-+ // dma reset & enable
-+ val = READREG(0x209000);
-+ val |= 0x02;
-+ WRITEREG(0x209000, val);
-+ val = READREG(0x209000);
-+ val |= 0x01;
-+ WRITEREG(0x209000, val);
-+*/
-+ // gpio
-+ //clear port D for LCD signal
-+ WRITEREG(0x21c320, 0x0);
-+ WRITEREG(0x21c338, 0x0);
-+
-+ val = READREG(0x21c220);
-+ val |= 0x10000;
-+ WRITEREG(0x21c220, val);
-+ val = READREG(0x21c208);
-+ val |= 0x03;
-+ WRITEREG(0x21c208, val);
-+ val = READREG(0x21c200);
-+ val |= 0x10000;
-+ WRITEREG(0x21c200, val);
-+ val = READREG(0x21c238);
-+ val |= 0x10000;
-+ WRITEREG(0x21c238, val);
-+ val = READREG(0x21c21c);
-+ val |= 0x10000;
-+ WRITEREG(0x21c21c, val);
-+
-+}
-+
-+static void set_pclk(unsigned int fmhz)
-+{
-+ unsigned int div= 96/fmhz;
-+ unsigned int reg;
-+ reg = READREG(0x21b020);
-+ reg &= ~0xf0;
-+ WRITEREG(0x21b020, reg);
-+ reg |= ((div-1)<<4) &0xf0;
-+ WRITEREG(0x21b020, reg);
-+}
-+
-+/*****************************************************************************
-+ * Function Name: _init_lcd
-+ *
-+ * Input: VOID
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called: _decode_var()
-+ *
-+ * Description: initialize the LCD controller, use current_par for 12bpp
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Chen Ning
-+******************************************************************************/
-+static int __init _init_lcd()
-+{
-+
-+ unsigned int val, rate;
-+ int i;
-+ unsigned char * pscr;
-+ //unsigned long pclk,temp,PCLKDIV2;
-+ //unsigned long MFI,MFN,PD,MFD,tempReg,MCUPLLCLK;
-+
-+
-+ _decode_var(&init_var, &current_par);
-+
-+ // gpio begin
-+ val = READREG(0x21c21c);
-+ val &= ~0x00010000;
-+ WRITEREG(0x21c21c, val);
-+ DPRINTK(KERN_ERR"DR=%x\n", READREG(0x21c21c));
-+
-+ // LCD regs
-+ DPRINTK(KERN_ERR"write SSA by %x\n",
-+ (unsigned int)current_par.screen_start_address);
-+ WRITEREG(DBMX1_LCD_SSA, (unsigned int)current_par.screen_start_address);
-+ DPRINTK(KERN_ERR"SSA=%x\n", READREG(DBMX1_LCD_SSA));
-+
-+ val =0;
-+ val = current_par.xres/16;
-+ val = val<<20;
-+ val += current_par.yres;
-+ DPRINTK(KERN_ERR"par.x=%x, y=%x\n",
-+ current_par.xres,
-+ current_par.yres);
-+ WRITEREG(DBMX1_LCD_XYMAX, val);
-+ DPRINTK(KERN_ERR"XYMAX=%x\n", READREG(DBMX1_LCD_XYMAX));
-+
-+ val=0;
-+ val=current_par.xres_virtual/2;
-+ WRITEREG(DBMX1_LCD_VPW, val);
-+ DPRINTK(KERN_ERR"VPW=%x\n", READREG(DBMX1_LCD_VPW));
-+
-+ set_pclk(4);
-+
-+ DPRINTK(KERN_ERR"DBMX1_LCD_PANELCFG=%x\n",
-+ READREG(DBMX1_LCD_PANELCFG));
-+
-+ WRITEREG(DBMX1_LCD_HCFG, 0x04000f06);
-+ DPRINTK(KERN_ERR"DBMX1_LCD_HCFG=%x\n",
-+ READREG(DBMX1_LCD_HCFG));
-+
-+ WRITEREG(DBMX1_LCD_VCFG, 0x04000907);
-+ DPRINTK(KERN_ERR"DBMX1_LCD_VCFG=%x\n",
-+ READREG(DBMX1_LCD_VCFG));
-+
-+ WRITEREG(DBMX1_LCD_REFMCR, 0x0);
-+ DPRINTK(KERN_ERR"DBMX1_LCD_REFMCR=%x\n",
-+ READREG(DBMX1_LCD_REFMCR));
-+
-+ WRITEREG(DBMX1_LCD_DMACR, DMACR_VAL_12);
-+ DPRINTK(KERN_ERR"DBMX1_LCD_DMACR=%x\n",
-+ READREG(DBMX1_LCD_DMACR));
-+
-+ WRITEREG(DBMX1_LCD_PWMR, 0x00008200);
-+ DPRINTK(KERN_ERR"DBMX1_LCD_PWMR=%x\n",
-+ READREG(DBMX1_LCD_PWMR));
-+
-+ // Thomas Wong - we don't want to turn it on here
-+ /*
-+ WRITEREG(DBMX1_LCD_REFMCR, 0x0f000002)
-+ DPRINTK(KERN_ERR"DBMX1_LCD_REFMCR=%x\n",
-+ READREG(DBMX1_LCD_REFMCR));
-+ */
-+
-+ WRITEREG(DBMX1_LCD_PWMR, 0x0000008a);
-+ DPRINTK(KERN_ERR"DBMX1_LCD_PWMR=%x\n",
-+ READREG(DBMX1_LCD_PWMR));
-+
-+ // Thomas Wong
-+ WRITEREG(0x21B020, 0x000B005B);
-+// PLAM -- for rev2 (new register and endian bits)
-+ WRITEREG(DBMX1_LCD_PANELCFG, 0xF8008B42); // little endian
-+// WRITEREG(DBMX1_LCD_PANELCFG, 0xF8048B42); // big endian
-+ WRITEREG(DBMX1_LCD_LGPMR, 0x00090300);
-+// WRITEREG(DBMX1_LCD_PWMR, 0x0000008A);
-+ WRITEREG (DBMX1_LCD_PWMR, 0x009A008A);
-+// end PLAM
-+
-+// PLAM -- for rev2 (new DMACR setting)
-+// WRITEREG(DBMX1_LCD_DMACR, 0x800C0002);
-+ WRITEREG(DBMX1_LCD_DMACR, 0x00040008);
-+//end PLAM
-+
-+
-+#define DMACR_VAL_12 0x800C0002
-+
-+
-+// WRITEREG(DBMX1_LCD_INTCR, INTCR_VAL_12);
-+// DPRINTK(KERN_ERR"DBMX1_LCD_INTCR=%x\n",
-+// READREG(DBMX1_LCD_INTCR));
-+
-+ // warm up LCD
-+ for(i=0;i<10000000;i++) ;
-+
-+ // gpio end
-+ val = READREG(0x21c21c);
-+ val |= 0x00010000;
-+ WRITEREG(0x21c21c, val);
-+ DPRINTK(KERN_ERR"DR=%x\n",
-+ READREG(0x21c21c));
-+#if 0
-+ // clear screen
-+ pscr = current_par.v_screen_start_address;
-+ for(i=0; i< (current_par.screen_memory_size - 2*PAGE_SIZE); i++){
-+ *pscr++ = 0xff;
-+ }
-+#endif
-+ DPRINTK(KERN_ERR"_init_lcd end \n");
-+
-+ return 0;
-+}
-+
-+#ifdef HARDWARE_CURSOR
-+
-+/*
-+ * Hardware cursor support
-+ */
-+ /*****************************************************************************
-+ * Function Name: dbmx1fb_set_cursor_color()
-+ *
-+ * Input: fb : frame buffer database
-+ * red : red component level in the cursor
-+ * green : green component level in the cursor
-+ * blue : blue component level in the cursor
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called: VOID
-+ *
-+ * Description: Set color of hardware cursor
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Zhang Juan
-+******************************************************************************/
-+static void dbmx1fb_set_cursor_color(struct dbmx1fb_info *fb, UINT8 *red, UINT8 *green, UINT8 *blue)
-+{
-+ struct dbmx1fb_cursor *c = &fb->cursor;
-+ UINT32 color;
-+
-+ FUNC_START;
-+ c->color[0] = *red;
-+ c->color[1] = *green;
-+ c->color[2] = *blue;
-+ color = (UINT32)*red;
-+ color |= (UINT32)(*green>>5);
-+ color |= (UINT32)(*blue>>11);
-+
-+ WRITEREG(DBMX1_LCD_LCHCC, color);
-+ FUNC_END;
-+}
-+
-+ /*****************************************************************************
-+ * Function Name: dbmx1fb_set_cursor()
-+ *
-+ * Input: fb : frame buffer database
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called: VOID
-+ *
-+ * Description: Load information of hardware cursor
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Zhang Juan
-+******************************************************************************/
-+static void dbmx1fb_set_cursor(struct dbmx1fb_info *fb)
-+{
-+ struct dbmx1fb_cursor *c = &fb->cursor;
-+ UINT32 temp,tempReg,x,y;
-+
-+ FUNC_START;
-+ //DPRINTK(KERN_ERR"BLINK_RATE=%x\n",c->blink_rate);
-+// DPRINTK(KERN_ERR"width=%x\n",c->width);
-+// DPRINTK(KERN_ERR"height=%x\n",c->height);
-+
-+ x = c->startx << 16;
-+ if (c->state == LCD_CURSOR_ON)
-+ x |= CURSOR_ON_MASK;
-+
-+#ifdef FBCON_HAS_CFB4
-+ else if(c->state == LCD_CURSOR_REVERSED)
-+ x |= CURSOR_REVERSED_MASK;
-+ else if(c->state == LCD_CURSOR_ON_WHITE)
-+ x |= CURSOR_WHITE_MASK;
-+#elif defined(FBCON_HAS_CFB8)||defined(FBCON_HAS_CFB16)
-+ else if(c->state == LCD_CURSOR_INVERT_BGD)
-+ x |= CURSOR_INVERT_MASK;
-+ else if(c->state == LCD_CURSOR_AND_BGD)
-+ x |= CURSOR_AND_BGD_MASK;
-+ else if(c->state == LCD_CURSOR_OR_BGD)
-+ x |= CURSOR_OR_BGD_MASK;
-+ else if(c->state == LCD_CURSOR_XOR_BGD)
-+ x |= CURSOR_XOR_BGD_MASK;
-+#endif
-+ else
-+ x = c->startx;
-+
-+ y = c->starty;
-+
-+ temp = (UINT32)x | (UINT32)y;
-+ WRITEREG(DBMX1_LCD_LCXYP, temp);
-+ //DPRINTK(KERN_ERR"lcxyp=%x\n",READREG(DBMX1_LCD_LCXYP));
-+
-+ temp = (UINT32)((c->width<<8) | (c->height));
-+ tempReg = (UINT32)((temp<<16) | c->blink_rate);
-+
-+ WRITEREG(DBMX1_LCD_CURBLKCR, tempReg);
-+
-+ //c->blink_rate = 10;
-+ if (c->blinkenable)
-+ dbmx1fb_set_cursor_blink(fb,c->blink_rate);
-+ DPRINTK(KERN_ERR"CURBLKCR=%x\n",READREG(DBMX1_LCD_CURBLKCR));
-+ FUNC_END;
-+}
-+
-+ /*****************************************************************************
-+ * Function Name: dbmx1fb_set_cursor_blink()
-+ *
-+ * Input: fb : frame buffer database
-+ * blink : input blink frequency of cursor
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called: VOID
-+ *
-+ * Description: Set blink frequency of hardware cursor
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Zhang Juan
-+******************************************************************************/
-+static void dbmx1fb_set_cursor_blink(struct dbmx1fb_info *fb,int blink)
-+{
-+ struct dbmx1fb_cursor *c = &fb->cursor;
-+
-+ unsigned long temp,tempReg;
-+ unsigned long PCD, XMAX, YMAX, PCLKDIV2;
-+ unsigned long tempMicroPeriod;
-+
-+ FUNC_START;
-+ DPRINTK(KERN_ERR"dbmx1fb_set_cursor_blink\n");
-+
-+ if(!c){
-+ DPRINTK(KERN_ERR"dangerouts, for c == null\n");
-+ }
-+ c->blink_rate = blink;
-+
-+ tempReg = READREG(DBMX1_LCD_XYMAX);
-+ XMAX = (tempReg & XMAX_MASK) >> 20;
-+ YMAX = tempReg & YMAX_MASK;
-+ //XMAX = 240;
-+ //YMAX = 320;
-+ tempReg = READREG(PCDR);
-+ PCLKDIV2 = (tempReg & PCLKDIV2_MASK) >> 4;
-+ tempReg = READREG(DBMX1_LCD_PANELCFG);
-+ PCD = tempReg & PCD_MASK;
-+
-+ temp = (PCLKDIV2 + 1);
-+
-+ if (!blink)
-+ {
-+ /* disable the blinking cursor function when frequency is 0 */
-+ tempReg = READREG(DBMX1_LCD_CURBLKCR);
-+ tempReg &= CURSORBLINK_DIS_MASK;
-+ WRITEREG(DBMX1_LCD_CURBLKCR,tempReg);
-+ }
-+ else
-+ {
-+
-+ tempMicroPeriod = temp * XMAX * YMAX * (PCD + 1);
-+ temp = 96*10000000/(blink * tempMicroPeriod);
-+ tempReg = READREG(DBMX1_LCD_CURBLKCR);
-+ tempReg |= CURSORBLINK_EN_MASK;
-+ tempReg |= temp;
-+ WRITEREG(DBMX1_LCD_CURBLKCR,tempReg);
-+ DPRINTK(KERN_ERR"Inter_CURBLKCR=%x\n",READREG(DBMX1_LCD_CURBLKCR));
-+ }
-+
-+ FUNC_END;
-+}
-+
-+ /*****************************************************************************
-+ * Function Name: dbmx1fb_set_cursor_state()
-+ *
-+ * Input: fb : frame buffer database
-+ * state : The status of the cursor to be set. e.g.
-+ * LCD_CURSOR_OFF
-+ * LCD_CURSOR_ON
-+ * LCD_CURSOR_REVERSED
-+ * LCD_CURSOR_ON_WHITE
-+ * LCD_CURSOR_OR_BGD
-+ * LCD_CURSOR_XOR_BGD
-+ * LCD_CURSOR_AND_BGD
-+ *
-+ * Value Returned: VOID
-+ *
-+ * Functions Called: VOID
-+ *
-+ * Description: Set state of cursor
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Zhang Juan
-+******************************************************************************/
-+static void dbmx1fb_set_cursor_state(struct dbmx1fb_info *fb,UINT32 state)
-+{
-+ struct dbmx1fb_cursor *c = &fb->cursor;
-+ UINT32 temp;
-+
-+ FUNC_START;
-+ c->state = state;
-+ temp = READREG(DBMX1_LCD_LCXYP);
-+ temp &= CURSOR_OFF_MASK;
-+
-+ if (state == LCD_CURSOR_OFF)
-+ temp = temp;
-+ else if (state == LCD_CURSOR_ON)
-+ temp |= CURSOR_ON_MASK;
-+#ifdef FBCON_HAS_CFB4
-+ else if (state == LCD_CURSOR_REVERSED)
-+ temp |= CURSOR_REVERSED_MASK;
-+ else if (state == LCD_CURSOR_ON_WHITE)
-+ temp |= CURSOR_WHITE_MASK;
-+#elif defined(FBCON_HAS_CFB8)||defined(FBCON_HAS_CFB16)
-+ else if(state == LCD_CURSOR_INVERT_BGD)
-+ temp |= CURSOR_INVERT_MASK;
-+ else if (state == LCD_CURSOR_OR_BGD)
-+ temp |= CURSOR_OR_BGD_MASK;
-+ else if (state == LCD_CURSOR_XOR_BGD)
-+ temp |= CURSOR_XOR_BGD_MASK;
-+ else if (state == LCD_CURSOR_AND_BGD)
-+ temp |= CURSOR_AND_BGD_MASK;
-+#endif
-+ WRITEREG(DBMX1_LCD_LCXYP,temp);
-+ DPRINTK(KERN_ERR"LCDXYP=%x\n",READREG(DBMX1_LCD_LCXYP));
-+ FUNC_END;
-+}
-+
-+
-+/*****************************************************************************
-+ * Function Name: dbmx1fb_cursor()
-+ *
-+ * Input: fb : frame buffer database
-+ *
-+ * Value Returned: cursor : The structure of hardware cursor
-+ *
-+ * Functions Called: dbmx1fb_set_cursor()
-+ * dbmx1fb_set_cursor_state()
-+ *
-+ * Description: The entry for display switch to operate hardware cursor
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Zhang Juan
-+******************************************************************************/
-+static void dbmx1fb_cursor(struct display *p, int mode, int x, int y)
-+{
-+ struct dbmx1fb_info *fb = (struct dbmx1fb_info *)p->fb_info;
-+ struct dbmx1fb_cursor *c = &fb->cursor;
-+
-+ FUNC_START;
-+ if (c==0) return;
-+
-+
-+ x *= fontwidth(p);
-+ y *= fontheight(p);
-+
-+ c->startx = x;
-+ c->starty = y;
-+
-+ switch (mode) {
-+ case CM_ERASE:
-+ dbmx1fb_set_cursor_state(fb,LCD_CURSOR_OFF);
-+ break;
-+
-+ case CM_DRAW:
-+ case CM_MOVE:
-+ c->state = LCD_CURSOR_ON;
-+ dbmx1fb_set_cursor(fb);
-+ dbmx1fb_set_cursor_state(fb, c->state);
-+ break;
-+ }
-+ FUNC_END;
-+}
-+
-+/*****************************************************************************
-+ * Function Name: dbmx1fb_set_font()
-+ *
-+ * Input: display : console datebase
-+ * width : The new width of cursor to be set.
-+ * height : The new height of cursor position to be set
-+ *
-+ * Value Returned: int : Return status.If no error, return 0.
-+ *
-+ * Functions Called: dbmx1fb_set_cursor()
-+ * dbmx1fb_set_cursor_color()
-+ *
-+ * Description: Set font for cursor
-+ *
-+ * Modification History:
-+ * 10 DEC,2001, Zhang Juan
-+******************************************************************************/
-+static int dbmx1fb_set_font(struct display *d, int width, int height)
-+{
-+ struct dbmx1fb_info *fb=(struct dbmx1fb_info *)d->fb_info;
-+ struct dbmx1fb_cursor *c = &fb->cursor;
-+
-+ FUNC_START;
-+ if(!d){
-+ printk(KERN_ERR"dbmx1fb_set_font d=null\n");
-+ return -1;
-+ }
-+
-+ if (c) {
-+ if (!width || !height) {
-+ width = 16;
-+ height = 16;
-+ }
-+
-+ c->width = width;
-+ c->height = height;
-+
-+ DPRINTK(KERN_ERR"set cursor\n");
-+ dbmx1fb_set_cursor(fb);
-+ DPRINTK(KERN_ERR"set color cursor\n");
-+ dbmx1fb_set_cursor_color(fb, cursor_color_map,
-+ cursor_color_map, cursor_color_map);
-+ }else{
-+ DPRINTK(KERN_ERR"set cursor failed, cursor == null\n");
-+ }
-+
-+ FUNC_END;
-+ return 1;
-+}
-+#endif // HARDWARE_CURSOR
-+/* end of file */
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/drivers/video/dbmx1fb.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,213 @@
-+/****************************************************************************
-+ *
-+ * Copyright (C) 2001, Chen Ning All Rights Reserved
-+ *
-+ * File Name: dbmx1fb.h
-+ *
-+ * Progammers: Chen Ning, Zhang Juan
-+ *
-+ * Date of Creations: 10 DEC,2001
-+ *
-+ * Synopsis:
-+ *
-+ * Descirption:
-+ *
-+ * Modification History:
-+ * 10 DEC, 2001, initialization version, frame work for frame buffer driver
-+ *
-+*******************************************************************************/
-+
-+#ifndef LCDFB_H
-+#define LCDFB_H
-+#include "asm/arch/hardware.h"
-+#include "asm/arch/platform.h"
-+
-+typedef signed char BOOLEAN;
-+typedef unsigned char UINT8; /* Unsigned 8 bit quantity */
-+typedef signed char SINT8; /* Signed 8 bit quantity */
-+typedef unsigned short UINT16; /* Unsigned 16 bit quantity */
-+typedef signed short SINT16; /* Signed 16 bit quantity */
-+typedef unsigned long UINT32; /* Unsigned 32 bit quantity */
-+typedef signed long SINT32; /* Signed 32 bit quantity */
-+
-+typedef volatile BOOLEAN VBOOLEAN;
-+typedef volatile UINT8 VUINT8; /* Unsigned 8 bit quantity */
-+typedef volatile SINT8 VSINT8; /* Signed 8 bit quantity */
-+typedef volatile UINT16 VUINT16; /* Unsigned 16 bit quantity */
-+typedef volatile SINT16 VSINT16; /* Signed 16 bit quantity */
-+typedef volatile UINT32 VUINT32; /* Unsigned 32 bit quantity */
-+typedef volatile SINT32 VSINT32; /* Signed 32 bit quantity */
-+
-+#define LCDBASE 0x00205000
-+#define LCD_REGIONSIZE 0xc00
-+
-+#define DBMX1_LCD_SSA 0x00205000
-+#define DBMX1_LCD_XYMAX 0x00205004
-+#define DBMX1_LCD_VPW 0x00205008
-+#define DBMX1_LCD_LCXYP 0x0020500c
-+#define DBMX1_LCD_CURBLKCR 0x00205010
-+#define DBMX1_LCD_LCHCC 0x00205014
-+#define DBMX1_LCD_PANELCFG 0x00205018
-+#define DBMX1_LCD_HCFG 0x0020501c
-+#define DBMX1_LCD_VCFG 0x00205020
-+#define DBMX1_LCD_POS 0x00205024
-+#define DBMX1_LCD_LGPMR 0x00205028
-+#define DBMX1_LCD_PWMR 0x0020502c
-+#define DBMX1_LCD_DMACR 0x00205030
-+#define DBMX1_LCD_REFMCR 0x00205034
-+#define DBMX1_LCD_INTCR 0x00205038
-+#define DBMX1_LCD_INTSR 0x00205040
-+#define DBMX1_LCD_MAPRAM 0x00205800
-+
-+#define MPCTL0 0x0021B004
-+#define PCDR 0X0021B020
-+
-+#define SSA DBMX1_LCD_SSA
-+#define XYMAX DBMX1_LCD_XYMAX
-+#define VPW DBMX1_LCD_VPW
-+#define LCXYP DBMX1_LCD_LCXYP
-+#define CURBLKCR DBMX1_LCD_CURBLKCR
-+#define LCHCC DBMX1_LCD_LCHCC
-+#define PANELCFG DBMX1_LCD_PANELCFG
-+#define VCFG DBMX1_LCD_VCFG
-+#define HCFG DBMX1_LCD_HCFG
-+#define POS DBMX1_LCD_POS
-+#define LGPMR DBMX1_LCD_LGPMR
-+#define PWMR DBMX1_LCD_PWMR
-+#define DMACR DBMX1_LCD_DMACR
-+#define REFMCR DBMX1_LCD_REFMCR
-+#define INTCR DBMX1_LCD_INTCR
-+#define INTSR DBMX1_LCD_INTSR
-+#define MAPRAM DBMX1_LCD_MAPRAM
-+// default value
-+#define SHARP_TFT_240x320
-+
-+#ifdef SHARP_TFT_240x320
-+#define PANELCFG_VAL_12 0xf8008b48
-+#define HCFG_VAL_12 0x04000f06
-+#define VCFG_VAL_12 0x04000907
-+#define PWMR_VAL 0x0000008a
-+#define LCD_MAXX 240
-+#define LCD_MAXY 320
-+#else //SHARP_TFT_240x320
-+
-+#define PANELCFG_VAL_12 0xf8088c6b
-+#define HCFG_VAL_12 0x04000f06
-+#define VCFG_VAL_12 0x04010c03
-+#define PWMR_VAL 0x00000200
-+#define LCD_MAXX 320
-+#define LCD_MAXY 240
-+#endif // SHARP_TFT_240x320
-+
-+#define PANELCFG_VAL_4 0x20008c09
-+#define PANELCFG_VAL_4C 0x60008c09
-+
-+#define HCFG_VAL_4 0x04000f07
-+
-+#define VCFG_VAL_4 0x04010c03
-+
-+
-+#define REFMCR_VAL_4 0x00000003
-+#define REFMCR_VAL_12 0x00000003
-+#define DISABLELCD_VAL 0x00000000
-+
-+#define DMACR_VAL_4 0x800c0003 // 12 & 3 TRIGGER
-+#define DMACR_VAL_12 0x00020008
-+
-+#define INTCR_VAL_4 0x00000000
-+#define INTCR_VAL_12 0x00000000
-+
-+#define INTSR_UDRERR 0x00000008
-+#define INTSR_ERRRESP 0x00000004
-+#define INTSR_EOF 0x00000002
-+#define INTSR_BOF 0x00000001
-+
-+#define MIN_XRES 64
-+#define MIN_YRES 64
-+
-+#define LCD_MAX_BPP 16
-+
-+#if 0
-+#define READREG(r) \
-+ inl(IO_ADDRESS(r))
-+
-+#define WRITEREG(r, val) \
-+ outl(val, IO_ADDRESS(r))
-+#else
-+#endif // 0
-+
-+#define MAX_PALETTE_NUM_ENTRIES 256
-+#define MAX_PIXEL_MEM_SIZE \
-+ ((current_par.max_xres * current_par.max_yres * current_par.max_bpp)/8)
-+#define MAX_FRAMEBUFFER_MEM_SIZE \
-+ (MAX_PIXEL_MEM_SIZE + 32)
-+#define ALLOCATED_FB_MEM_SIZE \
-+ (PAGE_ALIGN(MAX_FRAMEBUFFER_MEM_SIZE + PAGE_SIZE * 2))
-+
-+ // TODO:
-+#define FBCON_HAS_CFB4
-+#define FBCON_HAS_CFB8
-+#define FBCON_HAS_CFB16
-+
-+#define IRQ_LCD 12 // TODO: which irq?
-+#define DBMX1_NAME "DBMX1FB"
-+#define DEV_NAME DBMX1_NAME
-+#define MAX_PALETTE_NUM_ENTRIES 256
-+#define DEFAULT_CURSOR_BLINK_RATE (20)
-+#define CURSOR_DRAW_DELAY (2)
-+/*cursor status*/
-+#define LCD_CURSOR_OFF 0
-+#define LCD_CURSOR_ON 1
-+
-+#ifdef FBCON_HAS_CFB4
-+ #define LCD_CURSOR_REVERSED 2
-+ #define LCD_CURSOR_ON_WHITE 3
-+#elif defined(FBCON_HAS_CFB8) || defined(FBCON_HAS_CFB16)
-+ #define LCD_CURSOR_INVERT_BGD 2
-+ #define LCD_CURSOR_AND_BGD 3
-+ #define LCD_CURSOR_OR_BGD 4
-+ #define LCD_CURSOR_XOR_BGD 5
-+#endif //FBCON_HAS_CFB4
-+
-+/* MASK use for caculating MCDUPLLCLK */
-+#define MFI_MASK 0x00003C00
-+#define MFN_MASK 0x000003FF
-+#define PD_MASK 0x3C000000
-+#define MFD_MASK 0x03FF0000
-+#define PCLKDIV2_MASK 0x000000F0
-+#define PCD_MASK 0x0000003F
-+#define XMAX_MASK 0xF3F00000
-+#define YMAX_MASK 0x000001FF
-+#define HWAIT1_MASK 0x0000FF00
-+#define HWAIT2_MASK 0x000000FF
-+#define HWIDTH_MASK 0xFC000000
-+#define PASSDIV_MASK 0x00FF0000
-+#define VWAIT1_MASK 0x0000FF00
-+#define VWAIT2_MASK 0x000000FF
-+#define VWIDTH_MASK 0xFC000000
-+#define CURSORBLINK_DIS_MASK 0x80000000
-+
-+#define DISPLAY_MODE_MASK 0x80000000
-+
-+#define MCU_FREQUENCE 32768
-+#define COLOR_MASK 0x40000000
-+
-+/* MASK use for indicating the cursor status */
-+#define CURSOR_ON_MASK 0x40000000
-+#define CURSOR_OFF_MASK 0x0FFFFFFF
-+#define MAX_CURSOR_WIDTH 31
-+#define MAX_CURSOR_HEIGHT 31
-+#define CURSORBLINK_EN_MASK 0x80000000
-+
-+#ifdef FBCON_HAS_CFB4
-+#define CURSOR_REVERSED_MASK 0x80000000
-+#define CURSOR_WHITE_MASK 0xC0000000
-+#else
-+#define CURSOR_INVERT_MASK 0x80000000
-+#define CURSOR_AND_BGD_MASK 0xC0000000
-+#define CURSOR_OR_BGD_MASK 0x50000000
-+#define CURSOR_XOR_BGD_MASK 0x90000000
-+#endif // FBCON_HAS_CFB4
-+
-+#endif //LCDFB_H
-+
---- linux-2.4.25/drivers/video/fbmem.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/drivers/video/fbmem.c 2004-03-31 17:15:09.000000000 +0200
-@@ -61,7 +61,9 @@
- extern int pm2fb_setup(char*);
- extern int pm3fb_init(void);
- extern int pm3fb_setup(char*);
-+extern int clps711xfb_init(void);
- extern int cyber2000fb_init(void);
-+extern int cyber2000fb_setup(char*);
- extern int retz3fb_init(void);
- extern int retz3fb_setup(char*);
- extern int clgenfb_init(void);
-@@ -145,6 +147,8 @@
- extern int sstfb_setup(char*);
- extern int it8181fb_init(void);
- extern int it8181fb_setup(char*);
-+extern int anakinfb_init(void);
-+extern int dbmx1fb_init(void);
-
- static struct {
- const char *name;
-@@ -170,11 +174,14 @@
- #ifdef CONFIG_FB_AMIGA
- { "amifb", amifb_init, amifb_setup },
- #endif
-+#ifdef CONFIG_FB_CLPS711X
-+ { "clps711xfb", clps711xfb_init, NULL },
-+#endif
- #ifdef CONFIG_FB_CYBER
- { "cyber", cyberfb_init, cyberfb_setup },
- #endif
- #ifdef CONFIG_FB_CYBER2000
-- { "cyber2000", cyber2000fb_init, NULL },
-+ { "cyber2000", cyber2000fb_init, cyber2000fb_setup },
- #endif
- #ifdef CONFIG_FB_PM2
- { "pm2fb", pm2fb_init, pm2fb_setup },
-@@ -226,10 +233,10 @@
- #endif
- #ifdef CONFIG_FB_S3TRIO
- { "s3trio", s3triofb_init, NULL },
--#endif
-+#endif
- #ifdef CONFIG_FB_FM2
- { "fm2fb", fm2fb_init, fm2fb_setup },
--#endif
-+#endif
- #ifdef CONFIG_FB_SIS
- { "sisfb", sisfb_init, sisfb_setup },
- #endif
-@@ -242,7 +249,7 @@
-
- /*
- * Generic drivers that are used as fallbacks
-- *
-+ *
- * These depend on resource management and must be initialized
- * _after_ all other frame buffer devices that use resource
- * management!
-@@ -253,7 +260,7 @@
- #endif
- #ifdef CONFIG_FB_VESA
- { "vesa", vesafb_init, vesafb_setup },
--#endif
-+#endif
-
- /*
- * Chipset specific drivers that don't use resource management (yet)
-@@ -276,7 +283,7 @@
- #endif
- #ifdef CONFIG_FB_HGA
- { "hga", hgafb_init, hgafb_setup },
--#endif
-+#endif
- #ifdef CONFIG_FB_IGA
- { "igafb", igafb_init, igafb_setup },
- #endif
-@@ -291,7 +298,7 @@
- #endif
- #ifdef CONFIG_FB_HP300
- { "hpfb", hpfb_init, NULL },
--#endif
-+#endif
- #ifdef CONFIG_FB_G364
- { "g364", g364fb_init, NULL },
- #endif
-@@ -307,6 +314,9 @@
- #ifdef CONFIG_FB_TX3912
- { "tx3912", tx3912fb_init, NULL },
- #endif
-+#ifdef CONFIG_FB_ANAKIN
-+ { "anakinfb", anakinfb_init, NULL },
-+#endif
- #ifdef CONFIG_FB_E1355
- { "e1355fb", e1355fb_init, e1355fb_setup },
- #endif
-@@ -330,10 +340,13 @@
- #endif
- #ifdef CONFIG_FB_AU1100
- { "au1100fb", au1100fb_init, au1100fb_setup },
--#endif
-+#endif
- #ifdef CONFIG_FB_IT8181
- { "it8181fb", it8181fb_init, it8181fb_setup },
- #endif
-+#ifdef CONFIG_FB_DBMX1
-+ { "dbmx1fb", dbmx1fb_init, NULL },
-+#endif
-
-
- /*
-@@ -342,7 +355,7 @@
-
- #ifdef CONFIG_FB_VGA16
- { "vga16", vga16fb_init, vga16fb_setup },
--#endif
-+#endif
- #ifdef CONFIG_FB_STI
- { "stifb", stifb_init, stifb_setup },
- #endif
-@@ -371,7 +384,7 @@
-
- struct fb_info *registered_fb[FB_MAX];
- int num_registered_fb;
--extern int fbcon_softback_size;
-+extern int fbcon_softback_size;
-
- static int first_fb_vc;
- static int last_fb_vc = MAX_NR_CONSOLES-1;
-@@ -480,7 +493,7 @@
- }
- #endif /* CONFIG_KMOD */
-
--static int
-+static int
- fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg)
- {
-@@ -492,7 +505,7 @@
- struct fb_fix_screeninfo fix;
- struct fb_con2fbmap con2fb;
- int i;
--
-+
- if (! fb)
- return -ENODEV;
- switch (cmd) {
-@@ -576,7 +589,7 @@
- }
- }
-
--static int
-+static int
- fb_mmap(struct file *file, struct vm_area_struct * vma)
- {
- int fbidx = GET_FB_IDX(file->f_dentry->d_inode->i_rdev);
-@@ -667,11 +680,11 @@
- #elif defined(__sh__)
- pgprot_val(vma->vm_page_prot) &= ~_PAGE_CACHABLE;
- #elif defined(__hppa__)
-- pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
-+ pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
- #elif defined(__ia64__)
- vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
- #elif defined(__hppa__)
-- pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
-+ pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
- #else
- #warning What do we have to do here??
- #endif
-@@ -724,7 +737,7 @@
- return res;
- }
-
--static int
-+static int
- fb_release(struct inode *inode, struct file *file)
- {
- int fbidx = GET_FB_IDX(inode->i_rdev);
-@@ -856,7 +869,7 @@
- *
- */
-
--void __init
-+void __init
- fbmem_init(void)
- {
- int i;
-@@ -904,7 +917,7 @@
-
- if (!options || !*options)
- return 0;
--
-+
- if (!strncmp(options, "scrollback:", 11)) {
- options += 11;
- if (*options) {
-@@ -930,7 +943,7 @@
- }
- return 0;
- }
--
-+
- if (!strncmp(options, "vc:", 3)) {
- options += 3;
- if (*options)
---- linux-2.4.25/drivers/video/font_acorn_8x8.c~2.4.25-vrs2.patch 1998-09-30 05:56:33.000000000 +0200
-+++ linux-2.4.25/drivers/video/font_acorn_8x8.c 2004-03-31 17:15:09.000000000 +0200
-@@ -11,33 +11,33 @@
- /* 03 */ 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* ^C */
- /* 04 */ 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* ^D */
- /* 05 */ 0x00, 0x18, 0x3c, 0xe7, 0xe7, 0x3c, 0x18, 0x00, /* ^E */
--/* 06 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 07 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 09 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 0A */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 0B */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 0C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 0D */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 0E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 0F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* 06 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 07 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 08 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 09 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 0A */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 0B */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 0C */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 0D */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 0E */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 0F */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
- /* 10 */ 0x00, 0x60, 0x78, 0x7e, 0x7e, 0x78, 0x60, 0x00, /* |> */
- /* 11 */ 0x00, 0x06, 0x1e, 0x7e, 0x7e, 0x1e, 0x06, 0x00, /* <| */
--/* 12 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 13 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 14 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 15 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 16 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 17 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 19 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 1A */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 1B */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 1C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 1D */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* 12 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 13 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 14 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 15 */ 0x3c, 0x60, 0x3c, 0x66, 0x3c, 0x06, 0x3c, 0x00,
-+/* 16 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 17 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 18 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 19 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 1A */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 1B */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 1C */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 1D */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
- /* 1E */ 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x7e, 0x7e, 0x00, /* /\ */
- /* 1F */ 0x00, 0x7e, 0x7e, 0x3c, 0x3c, 0x18, 0x18, 0x00, /* \/ */
--/* 20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* */
-+/* 20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* */
- /* 21 */ 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00, /* ! */
- /* 22 */ 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, /* " */
- /* 23 */ 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00, /* # */
-@@ -132,55 +132,55 @@
- /* 7C */ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, /* | */
- /* 7D */ 0x30, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x30, 0x00, /* } */
- /* 7E */ 0x31, 0x6B, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, /* ~ */
--/* 7F */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /*  */
--/* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 81 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 82 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 83 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 84 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 85 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 86 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 87 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 88 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 89 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 8A */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 8B */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 8C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 8D */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 8E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 8F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 91 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 92 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 93 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 94 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 95 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 96 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 97 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 98 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 99 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 9A */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 9B */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 9C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 9D */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 9E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* 9F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* A0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* A1 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* A2 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* A3 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* A4 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* A5 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* A6 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* A7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* A8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* A9 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* AA */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* AB */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* AC */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* AD */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* AE */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* AF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* 7F */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /*  */
-+/* 80 */ 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x30, 0x60,
-+/* 81 */ 0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00,
-+/* 82 */ 0x0c, 0x18, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
-+/* 83 */ 0x18, 0x66, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
-+/* 84 */ 0x66, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
-+/* 85 */ 0x30, 0x18, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
-+/* 86 */ 0x3c, 0x66, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
-+/* 87 */ 0x00, 0x00, 0x3c, 0x66, 0x60, 0x66, 0x3c, 0x60,
-+/* 88 */ 0x3c, 0x66, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
-+/* 89 */ 0x66, 0x00, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
-+/* 8A */ 0x30, 0x18, 0x3c, 0x66, 0x7e, 0x60, 0x3c, 0x00,
-+/* 8B */ 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
-+/* 8C */ 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
-+/* 8D */ 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
-+/* 8E */ 0x66, 0x66, 0x00, 0x3c, 0x66, 0x7e, 0x66, 0x00,
-+/* 8F */ 0x18, 0x66, 0x00, 0x3c, 0x66, 0x7e, 0x66, 0x00,
-+/* 90 */ 0x0c, 0x18, 0x7e, 0x60, 0x7c, 0x60, 0x7e, 0x00,
-+/* 91 */ 0x00, 0x00, 0x3f, 0x0d, 0x3f, 0x6c, 0x3f, 0x00,
-+/* 92 */ 0x3f, 0x66, 0x66, 0x7f, 0x66, 0x66, 0x67, 0x00,
-+/* 93 */ 0x3c, 0x66, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00,
-+/* 94 */ 0x66, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00,
-+/* 95 */ 0x30, 0x18, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00,
-+/* 96 */ 0x3c, 0x66, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
-+/* 97 */ 0x30, 0x18, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
-+/* 98 */ 0x66, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x3c,
-+/* 99 */ 0x66, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x00,
-+/* 9A */ 0x66, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
-+/* 9B */ 0x08, 0x3e, 0x6b, 0x68, 0x6b, 0x3e, 0x08, 0x00,
-+/* 9C */ 0x1c, 0x36, 0x30, 0x7c, 0x30, 0x30, 0x7e, 0x00,
-+/* 9D */ 0x66, 0x3c, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00,
-+/* 9E */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* 9F */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* A0 */ 0x0c, 0x18, 0x3c, 0x06, 0x3e, 0x66, 0x3e, 0x00,
-+/* A1 */ 0x0c, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x00,
-+/* A2 */ 0x0c, 0x18, 0x00, 0x3c, 0x66, 0x66, 0x3c, 0x00,
-+/* A3 */ 0x0c, 0x18, 0x00, 0x66, 0x66, 0x66, 0x3e, 0x00,
-+/* A4 */ 0x36, 0x6c, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x00,
-+/* A5 */ 0x36, 0x6c, 0x00, 0x66, 0x76, 0x6e, 0x66, 0x00,
-+/* A6 */ 0x1c, 0x06, 0x1e, 0x36, 0x1e, 0x00, 0x3e, 0x00,
-+/* A7 */ 0x1c, 0x36, 0x36, 0x36, 0x1c, 0x00, 0x3e, 0x00,
-+/* A8 */ 0x18, 0x00, 0x18, 0x18, 0x30, 0x66, 0x3c, 0x00,
-+/* A9 */ 0x7e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* AA */ 0x7e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* AB */ 0x40, 0xc0, 0x40, 0x4f, 0x41, 0x0f, 0x08, 0x0f,
-+/* AC */ 0x40, 0xc0, 0x40, 0x48, 0x48, 0x0a, 0x0f, 0x02,
-+/* AD */ 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00,
-+/* AE */ 0x00, 0x33, 0x66, 0xcc, 0xcc, 0x66, 0x33, 0x00,
-+/* AF */ 0x00, 0xcc, 0x66, 0x33, 0x33, 0x66, 0xcc, 0x00,
- /* B0 */ 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
- /* B1 */ 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
- /* B2 */ 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
-@@ -229,37 +229,37 @@
- /* DD */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
- /* DE */ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- /* DF */ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
--/* E0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* E1 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* E2 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* E3 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* E4 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* E5 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* E6 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* E7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* E8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* E9 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* EA */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* EB */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* EC */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* ED */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* EE */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* EF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* F0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* F1 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* F2 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* F3 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* F4 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* F5 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* F6 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* F7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* F8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* F9 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* FA */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* FB */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* FC */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* FD */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
--/* FE */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* E0 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* E1 */ 0x3c, 0x66, 0x66, 0x6c, 0x66, 0x66, 0x6c, 0xc0,
-+/* E2 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* E3 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* E4 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* E5 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* E6 */ 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x3e, 0x60,
-+/* E7 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* E8 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* E9 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* EA */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* EB */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* EC */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* ED */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* EE */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* EF */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* F0 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* F1 */ 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x7e, 0x00,
-+/* F2 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* F3 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* F4 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* F5 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* F6 */ 0x00, 0x18, 0x00, 0xff, 0x00, 0x18, 0x00, 0x00,
-+/* F7 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* F8 */ 0x3c, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
-+/* F9 */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* FA */ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
-+/* FB */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* FC */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
-+/* FD */ 0x38, 0x04, 0x18, 0x20, 0x3c, 0x00, 0x00, 0x00,
-+/* FE */ 0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
- /* FF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
-
---- linux-2.4.25/drivers/video/pm3fb.c~2.4.25-vrs2.patch 2002-08-03 02:39:45.000000000 +0200
-+++ linux-2.4.25/drivers/video/pm3fb.c 2004-03-31 17:15:09.000000000 +0200
-@@ -5,7 +5,6 @@
- * Based on code written by:
- * Sven Luther, <luther@dpt-info.u-strasbg.fr>
- * Alan Hourihane, <alanh@fairlite.demon.co.uk>
-- * Russel King, <rmk@arm.linux.org.uk>
- * Based on linux/drivers/video/skeletonfb.c:
- * Copyright (C) 1997 Geert Uytterhoeven
- * Based on linux/driver/video/pm2fb.c:
-@@ -16,13 +15,9 @@
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- *
-- * $Header$
-+ * $Header$
- *
- * CHANGELOG:
-- * Mon Feb 11 10:35:48 MET 2002, v 1.4.11B: Cosmetic update.
-- * Wed Jan 23 14:16:59 MET 2002, v 1.4.11: Preliminary 2.5.x support, patch for 2.5.2.
-- * Wed Nov 28 11:08:29 MET 2001, v 1.4.10: potential bug fix for SDRAM-based board, patch for 2.4.16.
-- * Thu Sep 20 10:24:42 MET DST 2001, v 1.4.9: sync bug fix, preliminary flatpanel support, better timings.
- * Tue Aug 28 10:13:01 MET DST 2001, v 1.4.8: memory timings check, minor bug fixes.
- * Wed Jul 18 19:06:14 CEST 2001, v 1.4.7: Mode fix (800x600-100, 1024x768-100 changed), using HW panning + accel bug fix.
- * Mon Jun 25 10:33:56 MET DST 2001, v 1.4.6: Depth 12 fix, chip reset ioctl, moved memory erase ioctl to DEBUG.
-@@ -53,8 +48,8 @@
- */
-
- #include <linux/config.h>
--#include <linux/module.h>
- #include <linux/version.h>
-+#include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/errno.h>
- #include <linux/string.h>
-@@ -80,7 +75,6 @@
-
- #include <asm/io.h>
- #include <asm/uaccess.h>
--
- #ifdef CONFIG_FB_OF
- #include <asm/prom.h>
- #endif
-@@ -128,7 +122,6 @@
- unsigned long refresh;
- unsigned long powerdown;
- };
--typedef enum pm3fb_timing_result { pm3fb_timing_ok, pm3fb_timing_problem, pm3fb_timing_retry } pm3fb_timing_result;
- #define PM3FB_UNKNOWN_TIMING_VALUE ((unsigned long)-1)
- #define PM3FB_UNKNOWN_TIMINGS { PM3FB_UNKNOWN_TIMING_VALUE, PM3FB_UNKNOWN_TIMING_VALUE, PM3FB_UNKNOWN_TIMING_VALUE, PM3FB_UNKNOWN_TIMING_VALUE, PM3FB_UNKNOWN_TIMING_VALUE }
-
-@@ -191,21 +184,13 @@
- PM3VideoControl_VSYNC_ACTIVE_HIGH
- | PM3VideoControl_PIXELSIZE_8BIT}}, {
- "1024x768-74-32", {
-- 78752, 1024, 768, 32, 128, 304, 1328, 1, 4, 38,
-- 806, 1024, 0, 32,
-- PM3VideoControl_ENABLE |
-- PM3VideoControl_HSYNC_ACTIVE_HIGH
-- |
-- PM3VideoControl_VSYNC_ACTIVE_HIGH
-- | PM3VideoControl_PIXELSIZE_32BIT}},
--/* Generated mode : "1600x1024", for the SGI 1600SW flat panel*/
-- {
-- "SGI1600SW", {
-- 108000, 1600, 1024, 16, 56, 104, 1704, 3, 6, 32,
-- 1056, 1600, 0, 8,
-- PM3VideoControl_ENABLE|
-- PM3VideoControl_HSYNC_ACTIVE_LOW|PM3VideoControl_VSYNC_ACTIVE_LOW|
-- PM3VideoControl_PIXELSIZE_32BIT}},
-+ 78752, 1024, 768, 32, 128, 304, 1328, 1, 4, 38,
-+ 806, 1024, 0, 32,
-+ PM3VideoControl_ENABLE |
-+ PM3VideoControl_HSYNC_ACTIVE_HIGH
-+ |
-+ PM3VideoControl_VSYNC_ACTIVE_HIGH
-+ | PM3VideoControl_PIXELSIZE_32BIT}},
- /* ##### auto-generated mode, by fbtimings2pm3 */
- /* Generated mode : "640x480-60" */
- {
-@@ -554,11 +539,9 @@
- short noaccel[PM3_MAX_BOARD];
- char fontn[PM3_MAX_BOARD][PM3_FONTNAME_SIZE];
- short depth[PM3_MAX_BOARD];
--short flatpanel[PM3_MAX_BOARD];
- static struct display disp[PM3_MAX_BOARD];
- static char g_options[PM3_OPTIONS_SIZE] __initdata = "pm3fb,dummy";
- short printtimings = 0;
--short forcesize[PM3_MAX_BOARD];
-
- /* ********************* */
- /* ***** prototype ***** */
-@@ -566,8 +549,7 @@
- /* card-specific */
- static void pm3fb_j2000_setup(struct pm3fb_info *l_fb_info);
- /* permedia3-specific */
--static pm3fb_timing_result pm3fb_preserve_memory_timings(struct pm3fb_info *l_fb_info);
--static pm3fb_timing_result pm3fb_try_memory_timings(struct pm3fb_info *l_fb_info);
-+static int pm3fb_preserve_memory_timings(struct pm3fb_info *l_fb_info);
- static void pm3fb_write_memory_timings(struct pm3fb_info *l_fb_info);
- static unsigned long pm3fb_read_dac_reg(struct pm3fb_info *l_fb_info,
- unsigned long r);
-@@ -683,7 +665,7 @@
- NULL, NULL
- };
- #endif /* KERNEL_2_2 */
--#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
-+#ifdef KERNEL_2_4
- struct fbgen_hwswitch pm3fb_switch = {
- pm3fb_detect, pm3fb_encode_fix, pm3fb_decode_var, pm3fb_encode_var,
- pm3fb_get_par, pm3fb_set_par, pm3fb_getcolreg, pm3fb_setcolreg,
-@@ -696,7 +678,7 @@
- fbgen_get_fix, fbgen_get_var, fbgen_set_var,
- fbgen_get_cmap, fbgen_set_cmap, fbgen_pan_display, pm3fb_ioctl, NULL, NULL
- };
--#endif /* KERNEL_2_4 or KERNEL_2_5 */
-+#endif /* KERNEL_2_4 */
- #ifdef PM3FB_USE_ACCEL
- #ifdef FBCON_HAS_CFB32
- static struct display_switch pm3fb_cfb32 = {
-@@ -727,75 +709,52 @@
- #endif /* FBCON_HAS_CFB8 */
- #endif /* PM3FB_USE_ACCEL */
-
--/* ****************************** */
--/* ***** card-specific data ***** */
--/* ****************************** */
--struct pm3fb_card_timings {
-- unsigned long memsize; /* 0 for last value (i.e. default) */
-- struct pm3fb_timings memt;
--};
--
--static struct pm3fb_card_timings t_FormacProFormance3[] = {
-- { 16, { 0x02e311b8, 0x06100205, 0x08000002, 0x00000079, 0x00000000} },
-- { 0, { 0x02e311b8, 0x06100205, 0x08000002, 0x00000079, 0x00000000} } /* from 16 MB PF3 */
--};
--
--static struct pm3fb_card_timings t_AppianJeronimo2000[] = {
-- { 32, { 0x02e311B8, 0x07424905, 0x0c000003, 0x00000061, 0x00000000} },
-- { 0, { 0x02e311B8, 0x07424905, 0x0c000003, 0x00000061, 0x00000000} } /* from 32MB J2000 */
--};
--
--static struct pm3fb_card_timings t_3DLabsOxygenVX1[] = {
-- { 32, { 0x30e311b8, 0x08501204, 0x08000002, 0x0000006b, 0x00000000} },
-- { 0, { 0x30e311b8, 0x08501204, 0x08000002, 0x0000006b, 0x00000000} } /* from 32MB VX1 */
--};
--
-+/* ********************************** */
-+/* ***** card-specific function ***** */
-+/* ********************************** */
- static struct {
- char cardname[32]; /* recognized card name */
- u16 subvendor; /* subvendor of the card */
- u16 subdevice; /* subdevice of the card */
- u8 func; /* function of the card to which the extra init apply */
- void (*specific_setup)(struct pm3fb_info *l_fb_info); /* card/func specific setup, done before _any_ FB access */
-- struct pm3fb_card_timings *c_memt; /* defauls timings for the boards */
-+ struct pm3fb_timings memt; /* default timing for the board WARNING : might be *card* - specific */
- } cardbase[] = {
-- { "Unknown Permedia3 board", 0xFFFF, 0xFFFF, 0xFF, NULL, NULL },
-- { "Appian Jeronimo 2000 head 1", 0x1097, 0x3d32, 1, NULL,
-- t_AppianJeronimo2000
-- },
-+ { "Unknown Permedia3 board", 0xFFFF, 0xFFFF, 0xFF, NULL, PM3FB_UNKNOWN_TIMINGS },
-+ { "Appian Jeronimo 2000 head 1", 0x1097, 0x3d32, 1, NULL, PM3FB_UNKNOWN_TIMINGS },
- { "Appian Jeronimo 2000 head 2", 0x1097, 0x3d32, 2, pm3fb_j2000_setup,
-- t_AppianJeronimo2000
-+ {0x02e311B8, 0x07424905, 0x0c000003, 0x00000061, 0x00000000} /* also in pm3fb_j2000_setup */
- },
- { "Formac ProFormance 3", PCI_VENDOR_ID_3DLABS, 0x000a, 0, NULL, /* Formac use 3DLabs ID ?!? */
-- t_FormacProFormance3
-+ { 0x02e311b8, 0x06100205, 0x08000002, 0x00000079, 0x00000000} /* from the 16Mb ProFormance 3 */
- },
-- { "3DLabs Permedia3 Create!", PCI_VENDOR_ID_3DLABS, 0x0127, 0, NULL, NULL },
-+ { "3DLabs Permedia3 Create!", PCI_VENDOR_ID_3DLABS, 0x0127, 0, NULL, PM3FB_UNKNOWN_TIMINGS },
- { "3DLabs Oxygen VX1 PCI", PCI_VENDOR_ID_3DLABS, 0x0121, 0, NULL,
-- t_3DLabsOxygenVX1
-+ { 0x30e311b8, 0x08501204, 0x08000002, 0x0000006b, 0x00000000 }
- },
-- { "3DLabs Oxygen VX1 AGP", PCI_VENDOR_ID_3DLABS, 0x0125, 0, NULL, NULL },
-- { "3DLabs Oxygen VX1-16 AGP", PCI_VENDOR_ID_3DLABS, 0x0140, 0, NULL, NULL },
-- { "3DLabs Oxygen VX1-1600SW PCI", PCI_VENDOR_ID_3DLABS, 0x0800, 0, NULL, NULL },
-- { "\0", 0x0, 0x0, 0, NULL, NULL }
-+ { "3DLabs Oxygen VX1 AGP", PCI_VENDOR_ID_3DLABS, 0x0125, 0, NULL, PM3FB_UNKNOWN_TIMINGS },
-+ { "3DLabs Oxygen VX1-16 AGP", PCI_VENDOR_ID_3DLABS, 0x0140, 0, NULL, PM3FB_UNKNOWN_TIMINGS },
-+ { "3DLabs Oxygen VX1-1600SW PCI", PCI_VENDOR_ID_3DLABS, 0x0800, 0, NULL, PM3FB_UNKNOWN_TIMINGS },
-+ { "\0", 0x0, 0x0, 0, NULL, PM3FB_UNKNOWN_TIMINGS }
- };
-
--/* ********************************** */
--/* ***** card-specific function ***** */
--/* ********************************** */
- static void pm3fb_j2000_setup(struct pm3fb_info *l_fb_info)
- { /* the appian j2000 require more initialization of the second head */
- /* l_fb_info must point to the _second_ head of the J2000 */
-
- DTRACE;
--
-- l_fb_info->memt = t_AppianJeronimo2000[0].memt; /* 32 MB, first and only j2000 ? */
-+
-+ /* Memory timings for the Appian J2000 board. also in cardbase */
-+ l_fb_info->memt.caps = 0x02e311B8;
-+ l_fb_info->memt.timings = 0x07424905;
-+ l_fb_info->memt.control = 0x0c000003;
-+ l_fb_info->memt.refresh = 0x00000061;
-+ l_fb_info->memt.powerdown = 0x00000000;
-
- pm3fb_write_memory_timings(l_fb_info);
- }
-
--/* *************************************** */
--/* ***** permedia3-specific function ***** */
--/* *************************************** */
--static pm3fb_timing_result pm3fb_preserve_memory_timings(struct pm3fb_info *l_fb_info)
-+static int pm3fb_preserve_memory_timings(struct pm3fb_info *l_fb_info)
- {
- l_fb_info->memt.caps = PM3_READ_REG(PM3LocalMemCaps);
- l_fb_info->memt.timings = PM3_READ_REG(PM3LocalMemTimings);
-@@ -810,35 +769,20 @@
- (l_fb_info->memt.powerdown == PM3FB_UNKNOWN_TIMING_VALUE))
- {
- printk(KERN_ERR "pm3fb: invalid memory timings in permedia3 board #%ld\n", l_fb_info->board_num);
-- return(pm3fb_try_memory_timings(l_fb_info));
-- }
-- return(pm3fb_timing_ok);
--}
--
--static pm3fb_timing_result pm3fb_try_memory_timings(struct pm3fb_info *l_fb_info)
--{
-- if (cardbase[l_fb_info->board_type].c_memt)
-- {
-- int i = 0, done = 0;
-- while (!done)
-+ if ((cardbase[l_fb_info->board_type].memt.caps != PM3FB_UNKNOWN_TIMING_VALUE) &&
-+ (cardbase[l_fb_info->board_type].memt.timings != PM3FB_UNKNOWN_TIMING_VALUE) &&
-+ (cardbase[l_fb_info->board_type].memt.control != PM3FB_UNKNOWN_TIMING_VALUE) &&
-+ (cardbase[l_fb_info->board_type].memt.refresh != PM3FB_UNKNOWN_TIMING_VALUE) &&
-+ (cardbase[l_fb_info->board_type].memt.powerdown != PM3FB_UNKNOWN_TIMING_VALUE))
- {
-- if ((cardbase[l_fb_info->board_type].c_memt[i].memsize == l_fb_info->fb_size)
-- || !(cardbase[l_fb_info->board_type].c_memt[i].memsize))
-- { /* will use the 0-sized timings by default */
-- done = 1;
-- l_fb_info->memt = cardbase[l_fb_info->board_type].c_memt[i].memt;
-- printk(KERN_WARNING "pm3fb: trying to use predefined memory timings for permedia3 board #%ld (%s, %ld MB)\n",
-- l_fb_info->board_num,
-- cardbase[l_fb_info->board_type].cardname,
-- cardbase[l_fb_info->board_type].c_memt[i].memsize);
-- pm3fb_write_memory_timings(l_fb_info);
-- return(pm3fb_timing_retry);
-- }
-- i++;
-+ l_fb_info->memt = cardbase[l_fb_info->board_type].memt;
-+ printk(KERN_WARNING "pm3fb: trying to use predefined memory timings for permedia3 board #%ld (%s)\n", l_fb_info->board_num, cardbase[l_fb_info->board_type].cardname);
-+ pm3fb_write_memory_timings(l_fb_info);
- }
-- } else
-- return(pm3fb_timing_problem);
-- return(pm3fb_timing_ok);
-+ else
-+ return(1);
-+ }
-+ return(0);
- }
-
- static void pm3fb_write_memory_timings(struct pm3fb_info *l_fb_info)
-@@ -873,6 +817,10 @@
- PM3RD_SClkControl_ENABLE);
- }
-
-+/* *************************************** */
-+/* ***** permedia3-specific function ***** */
-+/* *************************************** */
-+
- static unsigned long pm3fb_read_dac_reg(struct pm3fb_info *l_fb_info,
- unsigned long r)
- {
-@@ -1067,7 +1015,6 @@
- /* write the mode to registers */
- static void pm3fb_write_mode(struct pm3fb_info *l_fb_info)
- {
-- char tempsync = 0x00, tempmisc = 0x00;
- DTRACE;
-
- PM3_SLOW_WRITE_REG(PM3MemBypassWriteMask, 0xffffffff);
-@@ -1197,26 +1144,22 @@
- /*
- PM3_SLOW_WRITE_REG(PM3RD_IndexControl, 0x00);
- */
-- if ((l_fb_info->current_par->video & PM3VideoControl_HSYNC_MASK) ==
-- PM3VideoControl_HSYNC_ACTIVE_HIGH)
-- tempsync |= PM3RD_SyncControl_HSYNC_ACTIVE_HIGH;
-- if ((l_fb_info->current_par->video & PM3VideoControl_VSYNC_MASK) ==
-- PM3VideoControl_VSYNC_ACTIVE_HIGH)
-- tempsync |= PM3RD_SyncControl_VSYNC_ACTIVE_HIGH;
--
-- PM3_WRITE_DAC_REG(PM3RD_SyncControl, tempsync);
-- DPRINTK(2, "PM3RD_SyncControl: %d\n", tempsync);
--
-- if (flatpanel[l_fb_info->board_num])
- {
-- PM3_WRITE_DAC_REG(PM3RD_DACControl, PM3RD_DACControl_BLANK_PEDESTAL_ENABLE);
-- PM3_WAIT(2);
-- PM3_WRITE_REG(PM3VSConfiguration, 0x06);
-- PM3_WRITE_REG(0x5a00, 1 << 14); /* black magic... */
-- tempmisc = PM3RD_MiscControl_VSB_OUTPUT_ENABLE;
-+ char tempsync = 0x00;
-+
-+ if ((l_fb_info->current_par->
-+ video & PM3VideoControl_HSYNC_MASK) ==
-+ PM3VideoControl_HSYNC_ACTIVE_HIGH)
-+ tempsync |= PM3RD_SyncControl_HSYNC_ACTIVE_HIGH;
-+ if ((l_fb_info->current_par->
-+ video & PM3VideoControl_VSYNC_MASK) ==
-+ PM3VideoControl_VSYNC_ACTIVE_HIGH)
-+ tempsync |= PM3RD_SyncControl_VSYNC_ACTIVE_HIGH;
-+
-+ PM3_WRITE_DAC_REG(PM3RD_SyncControl, tempsync);
-+ DPRINTK(2, "PM3RD_SyncControl: %d\n", tempsync);
- }
-- else
-- PM3_WRITE_DAC_REG(PM3RD_DACControl, 0x00);
-+ PM3_WRITE_DAC_REG(PM3RD_DACControl, 0x00);
-
- switch (l_fb_info->current_par->depth) {
- case 8:
-@@ -1225,7 +1168,8 @@
- PM3_WRITE_DAC_REG(PM3RD_ColorFormat,
- PM3RD_ColorFormat_CI8_COLOR |
- PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW);
-- tempmisc |= PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;
-+ PM3_WRITE_DAC_REG(PM3RD_MiscControl,
-+ PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE);
- break;
- case 12:
- PM3_WRITE_DAC_REG(PM3RD_PixelSize,
-@@ -1234,8 +1178,9 @@
- PM3RD_ColorFormat_4444_COLOR |
- PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW |
- PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE);
-- tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE |
-- PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;
-+ PM3_WRITE_DAC_REG(PM3RD_MiscControl,
-+ PM3RD_MiscControl_DIRECTCOLOR_ENABLE |
-+ PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE);
- break;
- case 15:
- PM3_WRITE_DAC_REG(PM3RD_PixelSize,
-@@ -1244,8 +1189,9 @@
- PM3RD_ColorFormat_5551_FRONT_COLOR |
- PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW |
- PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE);
-- tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE |
-- PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;
-+ PM3_WRITE_DAC_REG(PM3RD_MiscControl,
-+ PM3RD_MiscControl_DIRECTCOLOR_ENABLE |
-+ PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE);
- break;
- case 16:
- PM3_WRITE_DAC_REG(PM3RD_PixelSize,
-@@ -1254,8 +1200,9 @@
- PM3RD_ColorFormat_565_FRONT_COLOR |
- PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW |
- PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE);
-- tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE |
-- PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;
-+ PM3_WRITE_DAC_REG(PM3RD_MiscControl,
-+ PM3RD_MiscControl_DIRECTCOLOR_ENABLE |
-+ PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE);
- break;
- case 32:
- PM3_WRITE_DAC_REG(PM3RD_PixelSize,
-@@ -1263,12 +1210,12 @@
- PM3_WRITE_DAC_REG(PM3RD_ColorFormat,
- PM3RD_ColorFormat_8888_COLOR |
- PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW);
-- tempmisc |= PM3RD_MiscControl_DIRECTCOLOR_ENABLE |
-- PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE;
-+ PM3_WRITE_DAC_REG(PM3RD_MiscControl,
-+ PM3RD_MiscControl_DIRECTCOLOR_ENABLE |
-+ PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE);
- break;
- }
-- PM3_WRITE_DAC_REG(PM3RD_MiscControl, tempmisc);
--
-+
- PM3_SHOW_CUR_MODE;
- }
-
-@@ -1390,9 +1337,8 @@
-
- static unsigned long pm3fb_size_memory(struct pm3fb_info *l_fb_info)
- {
-- unsigned long memsize = 0, tempBypass, i, temp1, temp2;
-+ unsigned long memsize, tempBypass, i, temp1, temp2;
- u16 subvendor, subdevice;
-- pm3fb_timing_result ptr;
-
- DTRACE;
-
-@@ -1438,7 +1384,7 @@
-
- /* card-specific setup is done, we preserve the final
- memory timing for future reference */
-- if ((ptr = pm3fb_preserve_memory_timings(l_fb_info)) == pm3fb_timing_problem) { /* memory timings were wrong ! oops.... */
-+ if (pm3fb_preserve_memory_timings(l_fb_info)) { /* memory timings were wrong ! oops.... */
- return(0);
- }
-
-@@ -1464,12 +1410,12 @@
- temp1 = readl((l_fb_info->v_fb + (i * 1048576)));
- #endif
- #endif /* KERNEL_2_2 */
--#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
-+#ifdef KERNEL_2_4
- fb_writel(i * 0x00345678,
- (l_fb_info->v_fb + (i * 1048576)));
- mb();
- temp1 = fb_readl((l_fb_info->v_fb + (i * 1048576)));
--#endif /* KERNEL_2_4 or KERNEL_2_5 */
-+#endif /* KERNEL_2_4 */
- /* Let's check for wrapover, write will fail at 16MB boundary */
- if (temp1 == (i * 0x00345678))
- memsize = i;
-@@ -1512,7 +1458,7 @@
- ((i - 32) * 1048576)));
- #endif
- #endif /* KERNEL_2_2 */
--#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
-+#ifdef KERNEL_2_4
- fb_writel(i * 0x00345678,
- (l_fb_info->v_fb + (i * 1048576)));
- mb();
-@@ -1521,7 +1467,7 @@
- temp2 =
- fb_readl((l_fb_info->v_fb +
- ((i - 32) * 1048576)));
--#endif /* KERNEL_2_4 or KERNEL_2_5 */
-+#endif /* KERNEL_2_4 */
- if ((temp1 == (i * 0x00345678)) && (temp2 == 0)) /* different value, different RAM... */
- memsize = i;
- else
-@@ -1538,21 +1484,8 @@
-
- DPRINTK(2, "Returning 0x%08lx bytes\n", memsize);
-
-- if (forcesize[l_fb_info->board_num] && ((forcesize[l_fb_info->board_num] * 1048576) != memsize))
-- {
-- printk(KERN_WARNING "pm3fb: mismatch between probed (%ld MB) and specified (%hd MB) memory size, using SPECIFIED !\n", memsize, forcesize[l_fb_info->board_num]);
-- memsize = 1048576 * forcesize[l_fb_info->board_num];
-- }
--
- l_fb_info->fb_size = memsize;
--
-- if (ptr == pm3fb_timing_retry)
-- {
-- printk(KERN_WARNING "pm3fb: retrying memory timings check");
-- if (pm3fb_try_memory_timings(l_fb_info) == pm3fb_timing_problem)
-- return(0);
-- }
--
-+
- return (memsize);
- }
-
-@@ -1571,7 +1504,7 @@
- writel(cc, (l_fb_info->v_fb + (i * sizeof(u32))));
- #endif
- #endif
--#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
-+#ifdef KERNEL_2_4
- fb_writel(cc, (l_fb_info->v_fb + (i * sizeof(u32))));
- #endif
- }
-@@ -1600,7 +1533,7 @@
- disp[l_fb_info->board_num].scrollmode = 0; /* SCROLL_YNOMOVE; *//* 0 means "let fbcon choose" */
- l_fb_info->gen.parsize = sizeof(struct pm3fb_par);
- l_fb_info->gen.info.changevar = NULL;
-- l_fb_info->gen.info.node = B_FREE;
-+ l_fb_info->gen.info.node = -1;
- l_fb_info->gen.info.fbops = &pm3fb_ops;
- l_fb_info->gen.info.disp = &(disp[l_fb_info->board_num]);
- if (fontn[l_fb_info->board_num][0])
-@@ -1765,7 +1698,6 @@
- }
-
- PM3_SLOW_WRITE_REG(PM3FBSoftwareWriteMask, 0xffffffff);
-- PM3_SLOW_WRITE_REG(PM3FBHardwareWriteMask, 0xffffffff);
- PM3_SLOW_WRITE_REG(PM3FBWriteMode,
- PM3FBWriteMode_WriteEnable |
- PM3FBWriteMode_OpaqueSpan |
-@@ -1786,7 +1718,9 @@
- PM3_SLOW_WRITE_REG(PM3SizeOfFramebuffer, 4095);
- else
- PM3_SLOW_WRITE_REG(PM3SizeOfFramebuffer, sofb);
--
-+
-+ PM3_SLOW_WRITE_REG(PM3FBHardwareWriteMask, 0xffffffff);
-+
- switch (l_fb_info->current_par->depth) {
- case 8:
- PM3_SLOW_WRITE_REG(PM3DitherMode,
-@@ -1842,10 +1776,7 @@
- height = height * fontheight(p);
- c = ((u32 *) p->dispsw_data)[attr_bgcol_ec(p, conp)];
-
-- /* block fills in 32bpp are hard, but in low res (width <= 1600 :-)
-- we can use 16bpp operations, but not if NoWriteMask is on (SDRAM) */
-- if ((l_fb_info->current_par->width > 1600) ||
-- (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)) {
-+ if (l_fb_info->current_par->width > 1600) {
- PM3_WAIT(4);
-
- PM3_WRITE_REG(PM3Config2D,
-@@ -1867,7 +1798,7 @@
- PM3Render2D_SpanOperation |
- (PM3Render2D_Width(width)) |
- (PM3Render2D_Height(height)));
-- } else {
-+ } else { /* block fills in 32bpp are hard, but in low res (width <= 1600 :-) we can use 16bpp operations */
- PM3_WAIT(8);
-
- PM3_WRITE_REG(PM3FBBlockColor, c);
-@@ -1992,10 +1923,7 @@
-
- PM3_WAIT(4);
-
-- if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
-- PM3_WRITE_REG(PM3ForegroundColor, c);
-- else
-- PM3_WRITE_REG(PM3FBBlockColor, c);
-+ PM3_WRITE_REG(PM3FBBlockColor, c);
-
- PM3_WRITE_REG(PM3Config2D,
- PM3Config2D_UseConstantSource |
-@@ -2006,23 +1934,14 @@
- PM3_WRITE_REG(PM3RectanglePosition,
- (PM3RectanglePosition_XOffset(sx)) |
- (PM3RectanglePosition_YOffset(sy)));
--
-- if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
-- PM3_WRITE_REG(PM3Render2D,
-- PM3Render2D_XPositive |
-- PM3Render2D_YPositive |
-- PM3Render2D_Operation_Normal |
-- PM3Render2D_SpanOperation |
-- (PM3Render2D_Width(width)) |
-- (PM3Render2D_Height(height)));
-- else
-- PM3_WRITE_REG(PM3Render2D,
-- PM3Render2D_XPositive |
-- PM3Render2D_YPositive |
-- PM3Render2D_Operation_Normal |
-- (PM3Render2D_Width(width)) |
-- (PM3Render2D_Height(height)));
--
-+
-+ PM3_WRITE_REG(PM3Render2D,
-+ PM3Render2D_XPositive |
-+ PM3Render2D_YPositive |
-+ PM3Render2D_Operation_Normal |
-+ (PM3Render2D_Width(width)) |
-+ (PM3Render2D_Height(height)));
-+
- pm3fb_wait_pm3(l_fb_info);
- }
-
-@@ -2048,69 +1967,45 @@
- PM3Config2D_ForegroundROPEnable |
- (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */
- PM3Config2D_FBWriteEnable);
--
-- if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
-- PM3_WRITE_REG(PM3ForegroundColor, c);
-- else
-- PM3_WRITE_REG(PM3FBBlockColor, c);
--
-+
-+ PM3_WRITE_REG(PM3FBBlockColor, c);
-+
- PM3_WRITE_REG(PM3RectanglePosition,
- (PM3RectanglePosition_XOffset
- (p->var.xoffset +
- sx)) | (PM3RectanglePosition_YOffset(p->
- var.
- yoffset)));
-- if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
-- PM3_WRITE_REG(PM3Render2D,
-- PM3Render2D_XPositive |
-- PM3Render2D_YPositive |
-- PM3Render2D_Operation_Normal |
-- PM3Render2D_SpanOperation |
-- (PM3Render2D_Width(p->var.xres - sx)) |
-- (PM3Render2D_Height(p->var.yres)));
-- else
-- PM3_WRITE_REG(PM3Render2D,
-- PM3Render2D_XPositive |
-- PM3Render2D_YPositive |
-- PM3Render2D_Operation_Normal |
-- (PM3Render2D_Width(p->var.xres - sx)) |
-- (PM3Render2D_Height(p->var.yres)));
-+
-+ PM3_WRITE_REG(PM3Render2D,
-+ PM3Render2D_XPositive |
-+ PM3Render2D_YPositive |
-+ PM3Render2D_Operation_Normal |
-+ (PM3Render2D_Width(p->var.xres - sx)) |
-+ (PM3Render2D_Height(p->var.yres)));
- }
--
-+
- /* bottom margin left -> right */
- PM3_WAIT(4);
--
-+
- PM3_WRITE_REG(PM3Config2D,
-- PM3Config2D_UseConstantSource |
-- PM3Config2D_ForegroundROPEnable |
-- (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */
-- PM3Config2D_FBWriteEnable);
--
-- if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
-- PM3_WRITE_REG(PM3ForegroundColor, c);
-- else
-- PM3_WRITE_REG(PM3FBBlockColor, c);
--
--
-+ PM3Config2D_UseConstantSource |
-+ PM3Config2D_ForegroundROPEnable |
-+ (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */
-+ PM3Config2D_FBWriteEnable);
-+
-+ PM3_WRITE_REG(PM3FBBlockColor, c);
-+
- PM3_WRITE_REG(PM3RectanglePosition,
- (PM3RectanglePosition_XOffset(p->var.xoffset)) |
- (PM3RectanglePosition_YOffset(p->var.yoffset + sy)));
--
-- if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
-- PM3_WRITE_REG(PM3Render2D,
-- PM3Render2D_XPositive |
-- PM3Render2D_YPositive |
-- PM3Render2D_Operation_Normal |
-- PM3Render2D_SpanOperation |
-- (PM3Render2D_Width(p->var.xres)) |
-- (PM3Render2D_Height(p->var.yres - sy)));
-- else
-- PM3_WRITE_REG(PM3Render2D,
-- PM3Render2D_XPositive |
-- PM3Render2D_YPositive |
-- PM3Render2D_Operation_Normal |
-- (PM3Render2D_Width(p->var.xres)) |
-- (PM3Render2D_Height(p->var.yres - sy)));
-+
-+ PM3_WRITE_REG(PM3Render2D,
-+ PM3Render2D_XPositive |
-+ PM3Render2D_YPositive |
-+ PM3Render2D_Operation_Normal |
-+ (PM3Render2D_Width(p->var.xres)) |
-+ (PM3Render2D_Height(p->var.yres - sy)));
-
- pm3fb_wait_pm3(l_fb_info);
- }
-@@ -2288,7 +2183,7 @@
- int c, int yy, int xx)
- {
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
-- u8 *cdat, asx = 0, asy = 0, o_x = 0, o_y = 0;
-+ u8 *cdat, asx = 0, asy = 0, o_x, o_y;
- u32 fgx, bgx, ldat;
- int sx, sy, i;
-
-@@ -2398,7 +2293,7 @@
- int xx)
- {
- struct pm3fb_info *l_fb_info = (struct pm3fb_info *) p->fb_info;
-- u8 *cdat, asx = 0, asy = 0, o_x = 0, o_y = 0;
-+ u8 *cdat, asx = 0, asy = 0, o_x, o_y;
- u32 fgx, bgx, ldat;
- int sx, sy, i, j;
- u16 sc;
-@@ -2516,12 +2411,7 @@
- yy = yy * fontheight(p);
-
- if (l_fb_info->current_par->depth == 8)
-- {
-- if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
-- PM3_SLOW_WRITE_REG(PM3FBSoftwareWriteMask, 0x0F0F0F0F);
-- else
-- PM3_SLOW_WRITE_REG(PM3FBHardwareWriteMask, 0x0F0F0F0F);
-- }
-+ PM3_SLOW_WRITE_REG(PM3FBHardwareWriteMask, 0x0F0F0F0F);
-
- PM3_WAIT(3);
-
-@@ -2547,12 +2437,7 @@
- pm3fb_wait_pm3(l_fb_info);
-
- if (l_fb_info->current_par->depth == 8)
-- {
-- if (l_fb_info->memt.caps & PM3LocalMemCaps_NoWriteMask)
-- PM3_SLOW_WRITE_REG(PM3FBSoftwareWriteMask, 0xFFFFFFFF);
-- else
-- PM3_SLOW_WRITE_REG(PM3FBHardwareWriteMask, 0xFFFFFFFF);
-- }
-+ PM3_SLOW_WRITE_REG(PM3FBHardwareWriteMask, 0xFFFFFFFF);
- }
-
- #endif /* FBCON_HAS_CFB8 || FBCON_HAS_CFB16 || FBCON_HAS_CFB32 */
-@@ -2640,25 +2525,12 @@
- unsigned long bd = simple_strtoul(bds, (char **) NULL, 10);
-
- if (!(depth_supported(bd))) {
-- printk(KERN_WARNING "pm3fb: ignoring invalid depth %s for board #%ld\n",
-- bds, board_num);
-+ DPRINTK(1, "Invalid depth: %s\n", bds);
- return;
- }
- depth[board_num] = bd;
- }
-
--static void pm3fb_forcesize_setup(char *bds, unsigned long board_num)
--{
-- unsigned long bd = simple_strtoul(bds, (char **) NULL, 10);
--
-- if (bd > 64) {
-- printk(KERN_WARNING "pm3fb: ignoring invalid memory size %s for board #%ld\n",
-- bds, board_num);
-- return;
-- }
-- forcesize[board_num] = bd;
--}
--
- static char *pm3fb_boardnum_setup(char *options, unsigned long *bn)
- {
- char *next;
-@@ -2752,12 +2624,6 @@
- pm3fb_bootdepth_setup(options, bn);
- } else if (!strncmp(options, "printtimings", 12)) {
- printtimings = 1;
-- } else if (!strncmp(options, "flatpanel:", 10)) {
-- options = pm3fb_boardnum_setup(options + 10, &bn);
-- flatpanel[bn] = 1;
-- } else if (!strncmp(options, "forcesize:", 10)) {
-- options = pm3fb_boardnum_setup(options + 10, &bn);
-- pm3fb_forcesize_setup(options, bn);
- }
- options = next;
- }
-@@ -3495,7 +3361,7 @@
- pci_resource_start(l_fb_info->dev, 1);
- l_fb_info->v_fb = (unsigned char *) -1;
-
--#if (defined KERNEL_2_4) || (defined KERNEL_2_5) /* full resource management, new in linux-2.4.x */
-+#ifdef KERNEL_2_4 /* full resource management, new in linux-2.4.x */
- if (!request_mem_region
- ((unsigned long)l_fb_info->p_fb, 64 * 1024 * 1024, /* request full aperture size */
- "pm3fb")) {
-@@ -3512,10 +3378,8 @@
- l_fb_info->board_num);
- continue;
- }
--#endif /* KERNEL_2_4 or KERNEL_2_5 */
-- if (forcesize[l_fb_info->board_num])
-- l_fb_info->fb_size = forcesize[l_fb_info->board_num];
--
-+#endif /* KERNEL_2_4 */
-+
- l_fb_info->fb_size =
- pm3fb_size_memory(l_fb_info);
-
-@@ -3611,7 +3475,7 @@
- /* ***** standard FB API init functions ***** */
- /* ****************************************** */
-
--#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
-+#ifdef KERNEL_2_4
- int __init pm3fb_setup(char *options)
- #endif
- #ifdef KERNEL_2_2
-@@ -3627,12 +3491,12 @@
- PM3_OPTIONS_SIZE) ? PM3_OPTIONS_SIZE : (opsi + 1));
- g_options[PM3_OPTIONS_SIZE - 1] = 0;
-
--#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
-+#ifdef KERNEL_2_4
- return (0);
- #endif
- }
-
--#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
-+#ifdef KERNEL_2_4
- int __init pm3fb_init(void)
- #endif
- #ifdef KERNEL_2_2
-@@ -3641,7 +3505,7 @@
- {
- DTRACE;
-
-- DPRINTK(2, "This is pm3fb.c, CVS version: $Header$");
-+ DPRINTK(2, "This is pm3fb.c, CVS version: $Header$");
-
- pm3fb_real_setup(g_options);
-
-@@ -3650,7 +3514,7 @@
- if (!fb_info[0].dev) { /* not even one board ??? */
- DPRINTK(1, "No PCI Permedia3 board detected\n");
- }
--#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
-+#ifdef KERNEL_2_4
- return (0);
- #endif
- }
-@@ -3753,9 +3617,7 @@
- MODULE_PARM(depth,PM3_MAX_BOARD_MODULE_ARRAY_SHORT);
- MODULE_PARM_DESC(depth,"boot-time depth");
- MODULE_PARM(printtimings, "h");
--MODULE_PARM_DESC(printtimings, "print the memory timings of the card(s)");
--MODULE_PARM(forcesize, PM3_MAX_BOARD_MODULE_ARRAY_SHORT);
--MODULE_PARM_DESC(forcesize, "force specified memory size");
-+MODULE_PARM_DESC(printtimings, "print the memory timngs of the card(s)");
- /*
- MODULE_SUPPORTED_DEVICE("Permedia3 PCI boards")
- MODULE_GENERIC_TABLE(gtype,name)
-@@ -3829,14 +3691,14 @@
- if (l_fb_info->vIOBase !=
- (unsigned char *) -1) {
- pm3fb_unmapIO(l_fb_info);
--#if (defined KERNEL_2_4) || (defined KERNEL_2_5)
-+#ifdef KERNEL_2_4
- release_mem_region(l_fb_info->p_fb,
- l_fb_info->
- fb_size);
- release_mem_region(l_fb_info->
- pIOBase,
- PM3_REGS_SIZE);
--#endif /* KERNEL_2_4 or KERNEL_2_5 */
-+#endif /* KERNEL_2_4 */
- }
- unregister_framebuffer(&l_fb_info->gen.
- info);
---- linux-2.4.25/drivers/video/pm3fb.h~2.4.25-vrs2.patch 2002-11-29 00:53:15.000000000 +0100
-+++ linux-2.4.25/drivers/video/pm3fb.h 2004-03-31 17:15:09.000000000 +0200
-@@ -8,7 +8,7 @@
- * License. See the file COPYING in the main directory of this archive for
- * more details.
- *
-- * $Header$
-+ * $Header$
- *
- */
-
-@@ -92,7 +92,6 @@
- #define PM3MemBypassWriteMask 0x1008
- #define PM3MemScratch 0x1010
- #define PM3LocalMemCaps 0x1018
-- #define PM3LocalMemCaps_NoWriteMask (1 << 28)
- #define PM3LocalMemTimings 0x1020
- #define PM3LocalMemControl 0x1028
- #define PM3LocalMemRefresh 0x1030
-@@ -1121,10 +1120,6 @@
-
- /* kernel -specific definitions */
- /* what kernel is this ? */
--#if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)))
--#define KERNEL_2_5
--#endif
--
- #if ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)))
- #define KERNEL_2_4
- #endif
-@@ -1138,8 +1133,8 @@
- #endif
- #endif
-
--#if (!defined(KERNEL_2_2)) && (!defined(KERNEL_2_4)) && (!defined(KERNEL_2_5))
--#error "Only kernel 2.2.x, kernel 2.4.y and kernel 2.5.z might work"
-+#if (!defined(KERNEL_2_2)) && (!defined(KERNEL_2_4))
-+#error "Only kernel 2.2.x and kernel 2.4.y might work"
- #endif
-
- /* not sure if/why it's needed. doesn't work without on my PowerMac... */
-@@ -1147,11 +1142,6 @@
- #define MUST_BYTESWAP
- #endif
-
--/* for compatibility between 2.5, 2.4 and 2.2 */
--#ifndef B_FREE
--#define B_FREE -1
--#endif
--
- /* permedia3 -specific definitions */
- #define PM3_SCALE_TO_CLOCK(pr, fe, po) ((2 * PM3_REF_CLOCK * fe) / (pr * (1 << (po))))
- #define PICOS2KHZ(a) (1000000000UL/(a))
-@@ -1219,10 +1209,10 @@
- #define PM3_READ_REG(r) readl((l_fb_info->vIOBase + r))
- #endif /* MUST_BYTESWAP */
- #endif /* KERNEL_2_2 */
--#if (defined KERNEL_2_4) || (defined KERNEL_2_5) /* native-endian access */
-+#ifdef KERNEL_2_4 /* native-endian access */
- #define PM3_WRITE_REG(r, v) fb_writel(v, (l_fb_info->vIOBase + r))
- #define PM3_READ_REG(r) fb_readl((l_fb_info->vIOBase + r))
--#endif /* KERNEL_2_4 or KERNEL_2_5 */
-+#endif /* KERNEL_2_4 */
-
-
- #define depth2bpp(d) ((d + 7L) & ~7L)
---- linux-2.4.25/drivers/video/sa1100fb.c~2.4.25-vrs2.patch 2001-11-14 23:52:20.000000000 +0100
-+++ linux-2.4.25/drivers/video/sa1100fb.c 2004-03-31 17:15:09.000000000 +0200
-@@ -23,11 +23,11 @@
- * Thank you.
- *
- * Known problems:
-- * - With the Neponset plugged into an Assabet, LCD powerdown
-- * doesn't work (LCD stays powered up). Therefore we shouldn't
-- * blank the screen.
-- * - We don't limit the CPU clock rate nor the mode selection
-- * according to the available SDRAM bandwidth.
-+ * - With the Neponset plugged into an Assabet, LCD powerdown
-+ * doesn't work (LCD stays powered up). Therefore we shouldn't
-+ * blank the screen.
-+ * - We don't limit the CPU clock rate nor the mode selection
-+ * according to the available SDRAM bandwidth.
- *
- * Other notes:
- * - Linear grayscale palettes and the kernel.
-@@ -41,6 +41,17 @@
- * David Neuer. It's around 8 lines of C code, plus another 4 to
- * detect if we are using grayscale.
- *
-+ * - The following must never be specified in a panel definition:
-+ * LCCR0_LtlEnd, LCCR3_PixClkDiv, LCCR3_VrtSnchL, LCCR3_HorSnchL
-+ *
-+ * - The following should be specified:
-+ * either LCCR0_Color or LCCR0_Mono
-+ * either LCCR0_Sngl or LCCR0_Dual
-+ * either LCCR0_Act or LCCR0_Pas
-+ * either LCCR3_OutEnH or LCCD3_OutEnL
-+ * either LCCR3_PixRsEdg or LCCR3_PixFlEdg
-+ * either LCCR3_ACBsDiv or LCCR3_ACBsCntOff
-+ *
- * Code Status:
- * 1999/04/01:
- * - Driver appears to be working for Brutus 320x200x8bpp mode. Other
-@@ -147,6 +158,10 @@
- *
- * 2001/10/12: <rmk@arm.linux.org.uk>
- * - Add patch 681/1 and clean up stork definitions.
-+ *
-+ * 2002/02/21: <abraham@2d3d.co.za>
-+ * - Added support for ICP LCD-Kit01 on Frodo.
-+ * - Added support for backlight via CPLDs on Frodo.
- */
-
- #include <linux/config.h>
-@@ -169,6 +184,7 @@
- #include <asm/mach-types.h>
- #include <asm/uaccess.h>
- #include <asm/arch/assabet.h>
-+#include <asm/arch/shannon.h>
-
- #include <video/fbcon.h>
- #include <video/fbcon-mfb.h>
-@@ -177,11 +193,6 @@
- #include <video/fbcon-cfb16.h>
-
- /*
-- * enable this if your panel appears to have broken
-- */
--#undef CHECK_COMPAT
--
--/*
- * debugging?
- */
- #define DEBUG 0
-@@ -197,243 +208,6 @@
- void (*sa1100fb_blank_helper)(int blank);
- EXPORT_SYMBOL(sa1100fb_blank_helper);
-
--
--#ifdef CHECK_COMPAT
--static void
--sa1100fb_check_shadow(struct sa1100fb_lcd_reg *new_regs,
-- struct fb_var_screeninfo *var, u_int pcd)
--{
-- struct sa1100fb_lcd_reg shadow;
-- int different = 0;
--
-- /*
-- * These machines are good machines!
-- */
-- if (machine_is_assabet() || machine_is_h3600())
-- return;
--
-- /*
-- * The following ones are bad, bad, bad.
-- * Please make yours good!
-- */
-- if (machine_is_pangolin()) {
-- DPRINTK("Configuring Pangolin LCD\n");
-- shadow.lccr0 =
-- LCCR0_LEN + LCCR0_Color + LCCR0_LDM +
-- LCCR0_BAM + LCCR0_ERM + LCCR0_Act +
-- LCCR0_LtlEnd + LCCR0_DMADel(0);
-- shadow.lccr1 =
-- LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(64) +
-- LCCR1_BegLnDel(160) + LCCR1_EndLnDel(24);
-- shadow.lccr2 =
-- LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(7) +
-- LCCR2_BegFrmDel(7) + LCCR2_EndFrmDel(1);
-- shadow.lccr3 =
-- LCCR3_PixClkDiv(pcd) + LCCR3_HorSnchH +
-- LCCR3_VrtSnchH + LCCR3_PixFlEdg + LCCR3_OutEnH;
--
-- DPRINTK("pcd = %x, PixCldDiv(pcd)=%x\n",
-- pcd, LCCR3_PixClkDiv(pcd));
-- }
-- if (machine_is_freebird()) {
-- DPRINTK("Configuring Freebird LCD\n");
--#if 1
-- shadow.lccr0 = 0x00000038;
-- shadow.lccr1 = 0x010108e0;
-- shadow.lccr2 = 0x0000053f;
-- shadow.lccr3 = 0x00000c20;
--#else
-- shadow.lccr0 =
-- LCCR0_LEN + LCCR0_Color + LCCR0_Sngl +
-- LCCR0_LDM + LCCR0_BAM + LCCR0_ERM + LCCR0_Pas +
-- LCCR0_LtlEnd + LCCR0_DMADel(0);
-- /* Check ,Chester */
-- shadow.lccr1 =
-- LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(5) +
-- LCCR1_BegLnDel(61) + LCCR1_EndLnDel(9);
-- /* Check ,Chester */
-- shadow.lccr2 =
-- LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(1) +
-- LCCR2_BegFrmDel(3) + LCCR2_EndFrmDel(0);
-- /* Check ,Chester */
-- shadow.lccr3 =
-- LCCR3_OutEnH + LCCR3_PixFlEdg + LCCR3_VrtSnchH +
-- LCCR3_HorSnchH + LCCR3_ACBsCntOff +
-- LCCR3_ACBsDiv(2) + LCCR3_PixClkDiv(pcd);
--#endif
-- }
-- if (machine_is_brutus()) {
-- DPRINTK("Configuring Brutus LCD\n");
-- shadow.lccr0 =
-- LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Pas +
-- LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM +
-- LCCR0_DMADel(0);
-- shadow.lccr1 =
-- LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(3) +
-- LCCR1_BegLnDel(41) + LCCR1_EndLnDel(101);
-- shadow.lccr2 =
-- LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(1) +
-- LCCR2_BegFrmDel(0) + LCCR2_EndFrmDel(0);
-- shadow.lccr3 =
-- LCCR3_OutEnH + LCCR3_PixRsEdg + LCCR3_VrtSnchH +
-- LCCR3_HorSnchH + LCCR3_ACBsCntOff +
-- LCCR3_ACBsDiv(2) + LCCR3_PixClkDiv(44);
-- }
-- if (machine_is_huw_webpanel()) {
-- DPRINTK("Configuring HuW LCD\n");
-- shadow.lccr0 = LCCR0_LEN + LCCR0_Dual + LCCR0_LDM;
-- shadow.lccr1 = LCCR1_DisWdth(var->xres) +
-- LCCR1_HorSnchWdth(3) +
-- LCCR1_BegLnDel(41) + LCCR1_EndLnDel(101);
-- shadow.lccr2 = 239 + LCCR2_VrtSnchWdth(1);
-- shadow.lccr3 = 8 + LCCR3_OutEnH +
-- LCCR3_PixRsEdg + LCCR3_VrtSnchH +
-- LCCR3_HorSnchH + LCCR3_ACBsCntOff + LCCR3_ACBsDiv(2);
-- }
-- if (machine_is_lart()) {
-- DPRINTK("Configuring LART LCD\n");
--#if defined LART_GREY_LCD
-- shadow.lccr0 =
-- LCCR0_LEN + LCCR0_Mono + LCCR0_Sngl + LCCR0_Pas +
-- LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM +
-- LCCR0_DMADel(0);
-- shadow.lccr1 =
-- LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(1) +
-- LCCR1_BegLnDel(4) + LCCR1_EndLnDel(2);
-- shadow.lccr2 =
-- LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(1) +
-- LCCR2_BegFrmDel(0) + LCCR2_EndFrmDel(0);
-- shadow.lccr3 =
-- LCCR3_PixClkDiv(34) + LCCR3_ACBsDiv(512) +
-- LCCR3_ACBsCntOff + LCCR3_HorSnchH + LCCR3_VrtSnchH;
--#endif
--#if defined LART_COLOR_LCD
-- shadow.lccr0 =
-- LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act +
-- LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM +
-- LCCR0_DMADel(0);
-- shadow.lccr1 =
-- LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(2) +
-- LCCR1_BegLnDel(69) + LCCR1_EndLnDel(8);
-- shadow.lccr2 =
-- LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(3) +
-- LCCR2_BegFrmDel(14) + LCCR2_EndFrmDel(4);
-- shadow.lccr3 =
-- LCCR3_PixClkDiv(34) + LCCR3_ACBsDiv(512) +
-- LCCR3_ACBsCntOff + LCCR3_HorSnchL + LCCR3_VrtSnchL +
-- LCCR3_PixFlEdg;
--#endif
--#if defined LART_VIDEO_OUT
-- shadow.lccr0 =
-- LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act +
-- LCCR0_LtlEnd + LCCR0_LDM + LCCR0_BAM + LCCR0_ERM +
-- LCCR0_DMADel(0);
-- shadow.lccr1 =
-- LCCR1_DisWdth(640) + LCCR1_HorSnchWdth(95) +
-- LCCR1_BegLnDel(40) + LCCR1_EndLnDel(24);
-- shadow.lccr2 =
-- LCCR2_DisHght(480) + LCCR2_VrtSnchWdth(2) +
-- LCCR2_BegFrmDel(32) + LCCR2_EndFrmDel(11);
-- shadow.lccr3 =
-- LCCR3_PixClkDiv(8) + LCCR3_ACBsDiv(512) +
-- LCCR3_ACBsCntOff + LCCR3_HorSnchH + LCCR3_VrtSnchH +
-- LCCR3_PixFlEdg + LCCR3_OutEnL;
--#endif
-- }
-- if (machine_is_graphicsclient()) {
-- DPRINTK("Configuring GraphicsClient LCD\n");
-- shadow.lccr0 =
-- LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act;
-- shadow.lccr1 =
-- LCCR1_DisWdth(var->xres) + LCCR1_HorSnchWdth(9) +
-- LCCR1_EndLnDel(54) + LCCR1_BegLnDel(54);
-- shadow.lccr2 =
-- LCCR2_DisHght(var->yres) + LCCR2_VrtSnchWdth(9) +
-- LCCR2_EndFrmDel(32) + LCCR2_BegFrmDel(24);
-- shadow.lccr3 =
-- LCCR3_PixClkDiv(10) + LCCR3_ACBsDiv(2) +
-- LCCR3_ACBsCntOff + LCCR3_HorSnchL + LCCR3_VrtSnchL;
-- }
-- if (machine_is_omnimeter()) {
-- DPRINTK("Configuring OMNI LCD\n");
-- shadow.lccr0 = LCCR0_LEN | LCCR0_CMS | LCCR0_DPD;
-- shadow.lccr1 =
-- LCCR1_BegLnDel(10) + LCCR1_EndLnDel(10) +
-- LCCR1_HorSnchWdth(1) + LCCR1_DisWdth(var->xres);
-- shadow.lccr2 = LCCR2_DisHght(var->yres);
-- shadow.lccr3 =
-- LCCR3_ACBsDiv(0xFF) + LCCR3_PixClkDiv(44);
--//jca (GetPCD(25) << LCD3_V_PCD);
-- }
-- if (machine_is_xp860()) {
-- DPRINTK("Configuring XP860 LCD\n");
-- shadow.lccr0 =
-- LCCR0_LEN + LCCR0_Color + LCCR0_Sngl + LCCR0_Act +
-- LCCR0_LtlEnd + LCCR0_LDM + LCCR0_ERM + LCCR0_DMADel(0);
-- shadow.lccr1 =
-- LCCR1_DisWdth(var->xres) +
-- LCCR1_HorSnchWdth(var->hsync_len) +
-- LCCR1_BegLnDel(var->left_margin) +
-- LCCR1_EndLnDel(var->right_margin);
-- shadow.lccr2 =
-- LCCR2_DisHght(var->yres) +
-- LCCR2_VrtSnchWdth(var->vsync_len) +
-- LCCR2_BegFrmDel(var->upper_margin) +
-- LCCR2_EndFrmDel(var->lower_margin);
-- shadow.lccr3 =
-- LCCR3_PixClkDiv(6) + LCCR3_HorSnchL + LCCR3_VrtSnchL;
-- }
--
-- /*
-- * Ok, since we're calculating these values, we want to know
-- * if the calculation is correct. If you see any of these
-- * messages _PLEASE_ report the incident to me for diagnosis,
-- * including details about what was happening when the
-- * messages appeared. --rmk, 30 March 2001
-- */
-- if (shadow.lccr0 != new_regs->lccr0) {
-- printk(KERN_ERR "LCCR1 mismatch: 0x%08x != 0x%08x\n",
-- shadow.lccr1, new_regs->lccr1);
-- different = 1;
-- }
-- if (shadow.lccr1 != new_regs->lccr1) {
-- printk(KERN_ERR "LCCR1 mismatch: 0x%08x != 0x%08x\n",
-- shadow.lccr1, new_regs->lccr1);
-- different = 1;
-- }
-- if (shadow.lccr2 != new_regs->lccr2) {
-- printk(KERN_ERR "LCCR2 mismatch: 0x%08x != 0x%08x\n",
-- shadow.lccr2, new_regs->lccr2);
-- different = 1;
-- }
-- if (shadow.lccr3 != new_regs->lccr3) {
-- printk(KERN_ERR "LCCR3 mismatch: 0x%08x != 0x%08x\n",
-- shadow.lccr3, new_regs->lccr3);
-- different = 1;
-- }
-- if (different) {
-- printk(KERN_ERR "var: xres=%d hslen=%d lm=%d rm=%d\n",
-- var->xres, var->hsync_len,
-- var->left_margin, var->right_margin);
-- printk(KERN_ERR "var: yres=%d vslen=%d um=%d bm=%d\n",
-- var->yres, var->vsync_len,
-- var->upper_margin, var->lower_margin);
--
-- printk(KERN_ERR "Please report this to Russell King "
-- "<rmk@arm.linux.org.uk>\n");
-- }
--
-- DPRINTK("olccr0 = 0x%08x\n", shadow.lccr0);
-- DPRINTK("olccr1 = 0x%08x\n", shadow.lccr1);
-- DPRINTK("olccr2 = 0x%08x\n", shadow.lccr2);
-- DPRINTK("olccr3 = 0x%08x\n", shadow.lccr3);
--}
--#else
--#define sa1100fb_check_shadow(regs,var,pcd)
--#endif
--
--
--
- /*
- * IMHO this looks wrong. In 8BPP, length should be 8.
- */
-@@ -488,42 +262,56 @@
- #endif
- #endif
-
--#ifdef CONFIG_SA1100_H3600
--static struct sa1100fb_mach_info h3600_info __initdata = {
--#ifdef CONFIG_IPAQ_H3100
-- pixclock: 407766, bpp: 4,
-+#ifdef CONFIG_SA1100_H3XXX
-+static struct sa1100fb_mach_info h3800_info __initdata = {
-+ pixclock: 174757, bpp: 16,
- xres: 320, yres: 240,
-
-- hsync_len: 26, vsync_len: 41,
-- left_margin: 4, upper_margin: 0,
-- right_margin: 4, lower_margin: 0,
-+ hsync_len: 3, vsync_len: 3,
-+ left_margin: 12, upper_margin: 10,
-+ right_margin: 17, lower_margin: 1,
-
-- sync: FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-- cmap_greyscale: 1, cmap_static: 1,
-- cmap_inverse: 1,
-+ sync: 0, cmap_static: 1,
-
-- lccr0: LCCR0_Mono | LCCR0_4PixMono | LCCR0_Sngl | LCCR0_Pas,
-- lccr3: LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
--#else
-- pixclock: 174757, bpp: 16,
-+ lccr0: LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-+ lccr3: LCCR3_ACBsCntOff | LCCR3_PixFlEdg | LCCR3_OutEnH,
-+};
-+
-+static struct sa1100fb_mach_info h3600_info __initdata = {
-+ pixclock: 174757, bpp: 16,
- xres: 320, yres: 240,
-
- hsync_len: 3, vsync_len: 3,
- left_margin: 12, upper_margin: 10,
- right_margin: 17, lower_margin: 1,
-
-- sync: 0,
-+ sync: 0, cmap_static: 1,
-
- lccr0: LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-- lccr3: LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
--#endif
-+ lccr3: LCCR3_ACBsCntOff | LCCR3_OutEnH | LCCR3_PixFlEdg,
- };
-
- static struct sa1100fb_rgb h3600_rgb_16 = {
- red: { offset: 12, length: 4, },
- green: { offset: 7, length: 4, },
- blue: { offset: 1, length: 4, },
-- transp: { offset: 0, length: 0, },
-+ transp: { offset: 0, length: 0, },
-+};
-+
-+static struct sa1100fb_mach_info h3100_info __initdata = {
-+ pixclock: 406977, bpp: 4,
-+ xres: 320, yres: 240,
-+
-+ hsync_len: 26, vsync_len: 41,
-+ left_margin: 4, upper_margin: 0,
-+ right_margin: 4, lower_margin: 0,
-+
-+ sync: FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-+ cmap_greyscale: 1,
-+ cmap_inverse: 1,
-+
-+ lccr0: LCCR0_Mono | LCCR0_4PixMono | LCCR0_Sngl | LCCR0_Pas,
-+ lccr3: LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
- };
- #endif
-
-@@ -618,6 +406,58 @@
-
- #ifdef CONFIG_SA1100_GRAPHICSCLIENT
- static struct sa1100fb_mach_info graphicsclient_info __initdata = {
-+// for LQ64D343
-+ pixclock: 53500, bpp: 8,
-+ xres: 640, yres: 480,
-+
-+ hsync_len: 9, vsync_len: 9,
-+ left_margin: 54, upper_margin: 24,
-+ right_margin: 54, lower_margin: 32,
-+
-+ sync: 0,
-+
-+ lccr0: LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-+ lccr3: LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
-+};
-+#endif
-+
-+#ifdef CONFIG_SA1100_GRAPHICSMASTER
-+static struct sa1100fb_mach_info graphicsmaster_info __initdata = {
-+// for LQ64D343
-+ pixclock: 53500, bpp: 8,
-+ xres: 640, yres: 480,
-+
-+ hsync_len: 9, vsync_len: 9,
-+ left_margin: 54, upper_margin: 24,
-+ right_margin: 54, lower_margin: 32,
-+
-+ sync: 0,
-+
-+ lccr0: LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-+ lccr3: LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
-+};
-+#endif
-+
-+#ifdef CONFIG_SA1100_ADSBITSY
-+static struct sa1100fb_mach_info adsbitsy_info __initdata = {
-+// for LQ64D343
-+ pixclock: 53500, bpp: 8,
-+ xres: 640, yres: 480,
-+
-+ hsync_len: 9, vsync_len: 9,
-+ left_margin: 54, upper_margin: 24,
-+ right_margin: 54, lower_margin: 32,
-+
-+ sync: 0,
-+
-+ lccr0: LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-+ lccr3: LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
-+};
-+#endif
-+
-+#ifdef CONFIG_SA1100_ADSBITSYPLUS
-+static struct sa1100fb_mach_info adsbitsyplus_info __initdata = {
-+// for LQ64D343
- pixclock: 53500, bpp: 8,
- xres: 640, yres: 480,
-
-@@ -699,7 +539,6 @@
- lccr3: LCCR3_OutEnL | LCCR3_PixFlEdg | LCCR3_ACBsDiv(512),
- };
- #endif
--
- #ifdef LART_KIT01_LCD
- static struct sa1100fb_mach_info lart_kit01_info __initdata =
- {
-@@ -707,7 +546,7 @@
- xres: 640, yres: 480,
-
- hsync_len: 64, vsync_len: 3,
-- left_margin: 122, upper_margin: 45,
-+ left_margin: 122, upper_margin: 45,
- right_margin: 10, lower_margin: 10,
-
- sync: 0,
-@@ -717,6 +556,40 @@
- };
- #endif
-
-+#ifdef CONFIG_SA1100_FRODO
-+static struct sa1100fb_mach_info frodo_kit01_info __initdata =
-+{
-+ /* best would be 41731 (25.8mhz), but we can only do 14.743mhz at 191.7mhz clock speed */
-+ pixclock: 73030, bpp: 16,
-+ xres: 640, yres: 480,
-+
-+ hsync_len: 32, vsync_len: 19,
-+ left_margin: 120, upper_margin: 33,
-+ right_margin: 17, lower_margin: 12,
-+
-+ sync: 0,
-+
-+ lccr0: LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-+ lccr3: LCCR3_OutEnH | LCCR3_PixFlEdg
-+};
-+#endif
-+
-+#ifdef CONFIG_SA1100_SHANNON
-+static struct sa1100fb_mach_info shannon_info __initdata = {
-+ pixclock: 152500, bpp: 8,
-+ xres: 640, yres: 480,
-+
-+ hsync_len: 4, vsync_len: 3,
-+ left_margin: 2, upper_margin: 0,
-+ right_margin: 1, lower_margin: 0,
-+
-+ sync: FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-+
-+ lccr0: LCCR0_Color | LCCR0_Dual | LCCR0_Pas,
-+ lccr3: LCCR3_ACBsDiv(512),
-+};
-+#endif
-+
- #ifdef CONFIG_SA1100_OMNIMETER
- static struct sa1100fb_mach_info omnimeter_info __initdata = {
- pixclock: 0, bpp: 4,
-@@ -752,7 +625,24 @@
- sync: FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
-
- lccr0: LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
-- lccr3: LCCR3_OutEnH | LCCR3_PixFlEdg,
-+ lccr3: LCCR3_OutEnH | LCCR3_PixFlEdg | LCCR3_ACBsCntOff,
-+};
-+#endif
-+
-+#ifdef CONFIG_SA1100_SIMPUTER
-+static struct sa1100fb_mach_info simputer_info __initdata = {
-+ pixclock: 70000, bpp: 4,
-+ xres: 320, yres: 240,
-+
-+ hsync_len: 9, vsync_len: 2,
-+ left_margin: 9, upper_margin: 0,
-+ right_margin: 2, lower_margin: 0,
-+
-+ cmap_greyscale: 1,
-+ sync: FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT ,
-+
-+ lccr0: LCCR0_Mono | LCCR0_Sngl | LCCR0_Pas | LCCR0_4PixMono,
-+ lccr3: LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(202),
- };
- #endif
-
-@@ -828,7 +718,6 @@
- #endif
-
-
--
- static struct sa1100fb_mach_info * __init
- sa1100fb_get_machine_info(struct sa1100fb_info *fbi)
- {
-@@ -849,11 +738,17 @@
- #endif
- }
- #endif
--#ifdef CONFIG_SA1100_H3600
-+#ifdef CONFIG_SA1100_H3XXX
- if (machine_is_h3600()) {
- inf = &h3600_info;
- fbi->rgb[RGB_16] = &h3600_rgb_16;
- }
-+ if (machine_is_h3100()) {
-+ inf = &h3100_info;
-+ }
-+ if (machine_is_h3800()) {
-+ inf = &h3800_info;
-+ }
- #endif
- #ifdef CONFIG_SA1100_BRUTUS
- if (machine_is_brutus()) {
-@@ -876,6 +771,22 @@
- inf = &graphicsclient_info;
- }
- #endif
-+#ifdef CONFIG_SA1100_GRAPHICSMASTER
-+ if (machine_is_graphicsmaster()) {
-+ inf = &graphicsmaster_info;
-+ }
-+#endif
-+#ifdef CONFIG_SA1100_ADSBITSY
-+ if (machine_is_adsbitsy()) {
-+ inf = &adsbitsy_info;
-+ }
-+#endif
-+#ifdef CONFIG_SA1100_ADSBITSYPLUS
-+ if (machine_is_adsbitsyplus()) {
-+ inf = &adsbitsyplus_info;
-+ }
-+ }
-+#endif
- #ifdef CONFIG_SA1100_HUW_WEBPANEL
- if (machine_is_huw_webpanel()) {
- inf = &huw_webpanel_info;
-@@ -897,6 +808,21 @@
- #endif
- }
- #endif
-+#ifdef CONFIG_SA1100_FRODO
-+ if (machine_is_frodo()) {
-+ inf = &frodo_kit01_info;
-+ }
-+#endif
-+#ifdef CONFIG_SA1100_SHANNON
-+ if (machine_is_shannon()) {
-+ inf = &shannon_info;
-+ }
-+#endif
-+#ifdef CONFIG_SA1100_SIMPUTER
-+ if (machine_is_simputer()) {
-+ inf = &simputer_info;
-+ }
-+#endif
- #ifdef CONFIG_SA1100_OMNIMETER
- if (machine_is_omnimeter()) {
- inf = &omnimeter_info;
-@@ -1556,7 +1482,8 @@
- unsigned int pcd;
-
- if (pixclock) {
-- pcd = get_cclk_frequency() * pixclock;
-+ pcd = cpufreq_get(0) / 100;
-+ pcd *= pixclock;
- pcd /= 10000000;
- pcd += 1; /* make up for integer math truncations */
- } else {
-@@ -1580,6 +1507,7 @@
- return pcd;
- }
-
-+
- /*
- * sa1100fb_activate_var():
- * Configures LCD Controller based on entries in var parameter. Settings are
-@@ -1659,8 +1587,6 @@
- if (pcd)
- new_regs.lccr3 |= LCCR3_PixClkDiv(pcd);
-
-- sa1100fb_check_shadow(&new_regs, var, pcd);
--
- DPRINTK("nlccr0 = 0x%08x\n", new_regs.lccr0);
- DPRINTK("nlccr1 = 0x%08x\n", new_regs.lccr1);
- DPRINTK("nlccr2 = 0x%08x\n", new_regs.lccr2);
-@@ -1733,6 +1659,10 @@
- if (machine_is_omnimeter())
- LEDBacklightOn();
- #endif
-+#ifdef CONFIG_SA1100_FRODO
-+ if (machine_is_frodo())
-+ frodo_cpld_set (FRODO_CPLD_GENERAL,FRODO_LCD_BACKLIGHT);
-+#endif
- }
-
- /*
-@@ -1755,6 +1685,10 @@
- if (machine_is_omnimeter())
- LEDBacklightOff();
- #endif
-+#ifdef CONFIG_SA1100_FRODO
-+ if (machine_is_frodo())
-+ frodo_cpld_clear (FRODO_CPLD_GENERAL,FRODO_LCD_BACKLIGHT);
-+#endif
- }
-
- static void sa1100fb_power_up_lcd(struct sa1100fb_info *fbi)
-@@ -1773,20 +1707,25 @@
- if (machine_is_omnimeter())
- LCDPowerOn();
- #endif
--#ifdef CONFIG_SA1100_H3600
-- if (machine_is_h3600()) {
-- set_h3600_egpio(EGPIO_H3600_LCD_ON |
-- EGPIO_H3600_LCD_PCI |
-- EGPIO_H3600_LCD_5V_ON |
-- EGPIO_H3600_LVDD_ON);
-- }
--#endif
-+ if (machine_is_h3xxx())
-+ set_h3600_egpio( IPAQ_EGPIO_LCD_ON ); /* Turn on power to the LCD */
- #ifdef CONFIG_SA1100_STORK
- if (machine_is_stork()) {
- storkSetLCDCPLD(0, 1);
- storkSetLatchA(STORK_LCD_BACKLIGHT_INVERTER_ON);
- }
- #endif
-+#ifdef CONFIG_SA1100_FRODO
-+ if (machine_is_frodo())
-+ sa1100fb_backlight_on(fbi);
-+#endif
-+#ifdef CONFIG_SA1100_ADSBITSYPLUS
-+ if (machine_is_adsbitsyplus()) {
-+ ADS_CPLD_PCON &= ~ADS_PCON_PANEL_ON;
-+ ADS_CPLD_SUPPC |= ADS_SUPPC_VEE_ON;
-+ }
-+#endif
-+
- }
-
- static void sa1100fb_power_down_lcd(struct sa1100fb_info *fbi)
-@@ -1802,20 +1741,24 @@
- if (machine_is_huw_webpanel())
- BCR_set(BCR_TFT_NPWR);
- #endif
--#ifdef CONFIG_SA1100_H3600
-- if (machine_is_h3600()) {
-- clr_h3600_egpio(EGPIO_H3600_LCD_ON |
-- EGPIO_H3600_LCD_PCI |
-- EGPIO_H3600_LCD_5V_ON |
-- EGPIO_H3600_LVDD_ON);
-- }
--#endif
-+ if (machine_is_h3xxx())
-+ clr_h3600_egpio( IPAQ_EGPIO_LCD_ON );
- #ifdef CONFIG_SA1100_STORK
- if (machine_is_stork()) {
- storkSetLCDCPLD(0, 0);
- storkClearLatchA(STORK_LCD_BACKLIGHT_INVERTER_ON);
- }
- #endif
-+#ifdef CONFIG_SA1100_FRODO
-+ if (machine_is_frodo())
-+ sa1100fb_backlight_off(fbi);
-+#endif
-+#ifdef CONFIG_SA1100_ADSBITSYPLUS
-+ if (machine_is_adsbitsyplus()) {
-+ ADS_CPLD_PCON |= ADS_PCON_PANEL_ON;
-+ ADS_CPLD_SUPPC &= ~ADS_SUPPC_VEE_ON;
-+ }
-+#endif
- }
-
- static void sa1100fb_setup_gpio(struct sa1100fb_info *fbi)
-@@ -1911,15 +1854,29 @@
- LCCR0 |= LCCR0_LEN;
-
- #ifdef CONFIG_SA1100_GRAPHICSCLIENT
--#error Where is GPIO24 set as an output? Can we fit this in somewhere else?
- if (machine_is_graphicsclient()) {
- // From ADS doc again...same as disable
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(20 * HZ / 1000);
-- GPSR |= GPIO_GPIO24;
-+ GPDR |= GPIO_GPIO24;
-+ GPSR = GPIO_GPIO24;
-+ }
-+#endif
-+#ifdef CONFIG_SA1100_GRAPHICSMASTER
-+ if (machine_is_graphicsmaster()) {
-+ // From ADS doc again...same as disable
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ schedule_timeout(20 * HZ / 1000);
-+ GPDR |= GPIO_GPIO24;
-+ GPSR = GPIO_GPIO24;
- }
- #endif
-
-+ if (machine_is_shannon()) {
-+ GPDR |= SHANNON_GPIO_DISP_EN;
-+ GPSR |= SHANNON_GPIO_DISP_EN;
-+ }
-+
- DPRINTK("DBAR1 = %p\n", DBAR1);
- DPRINTK("DBAR2 = %p\n", DBAR2);
- DPRINTK("LCCR0 = 0x%08x\n", LCCR0);
-@@ -1935,7 +1892,6 @@
- DPRINTK("Disabling LCD controller\n");
-
- #ifdef CONFIG_SA1100_GRAPHICSCLIENT
--#error Where is GPIO24 set as an output? Can we fit this in somewhere else?
- if (machine_is_graphicsclient()) {
- /*
- * From ADS internal document:
-@@ -1944,6 +1900,22 @@
- *
- * We'll wait 20msec.
- */
-+ GPDR |= GPIO_GPIO24;
-+ GPCR |= GPIO_GPIO24;
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ schedule_timeout(20 * HZ / 1000);
-+ }
-+#endif
-+#ifdef CONFIG_SA1100_GRAPHICSMASTER
-+ if (machine_is_graphicsmaster()) {
-+ /*
-+ * From ADS internal document:
-+ * GPIO24 should be LOW at least 10msec prior to disabling
-+ * the LCD interface.
-+ *
-+ * We'll wait 20msec.
-+ */
-+ GPDR |= GPIO_GPIO24;
- GPCR |= GPIO_GPIO24;
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(20 * HZ / 1000);
-@@ -1958,12 +1930,15 @@
- }
- #endif
-
-+ if (machine_is_shannon()) {
-+ GPCR |= SHANNON_GPIO_DISP_EN;
-+ }
-+
- add_wait_queue(&fbi->ctrlr_wait, &wait);
- set_current_state(TASK_UNINTERRUPTIBLE);
-
- LCSR = 0xffffffff; /* Clear LCD Status Register */
- LCCR0 &= ~LCCR0_LDM; /* Enable LCD Disable Done Interrupt */
-- enable_irq(IRQ_LCD); /* Enable LCD IRQ */
- LCCR0 &= ~LCCR0_LEN; /* Disable LCD Controller */
-
- schedule_timeout(20 * HZ / 1000);
-@@ -2006,12 +1981,13 @@
- * Disable controller for clock change. If the
- * controller is already disabled, then do nothing.
- */
-- if (old_state != C_DISABLE) {
-+ if (old_state != C_DISABLE && old_state != C_DISABLE_PM) {
- fbi->state = state;
- sa1100fb_disable_controller(fbi);
- }
- break;
-
-+ case C_DISABLE_PM:
- case C_DISABLE:
- /*
- * Disable controller
-@@ -2050,6 +2026,16 @@
- }
- break;
-
-+ case C_ENABLE_PM:
-+ /*
-+ * Re-enable the controller after PM. This is not
-+ * perfect - think about the case where we were doing
-+ * a clock change, and we suspended half-way through.
-+ */
-+ if (old_state != C_DISABLE_PM)
-+ break;
-+ /* fall through */
-+
- case C_ENABLE:
- /*
- * Power up the LCD screen, enable controller, and
-@@ -2162,10 +2148,10 @@
-
- if (state == 0) {
- /* Enter D0. */
-- set_ctrlr_state(fbi, C_ENABLE);
-+ set_ctrlr_state(fbi, C_ENABLE_PM);
- } else {
- /* Enter D1-D3. Disable the LCD controller. */
-- set_ctrlr_state(fbi, C_DISABLE);
-+ set_ctrlr_state(fbi, C_DISABLE_PM);
- }
- }
- DPRINTK("done\n");
-@@ -2304,7 +2290,7 @@
- goto failed;
-
- ret = request_irq(IRQ_LCD, sa1100fb_handle_irq, SA_INTERRUPT,
-- fbi->fb.fix.id, fbi);
-+ "LCD", fbi);
- if (ret) {
- printk(KERN_ERR "sa1100fb: request_irq failed: %d\n", ret);
- goto failed;
---- linux-2.4.25/drivers/video/sa1100fb.h~2.4.25-vrs2.patch 2001-10-25 22:53:52.000000000 +0200
-+++ linux-2.4.25/drivers/video/sa1100fb.h 2004-03-31 17:15:09.000000000 +0200
-@@ -127,6 +127,8 @@
- #define C_DISABLE_CLKCHANGE (2)
- #define C_ENABLE_CLKCHANGE (3)
- #define C_REENABLE (4)
-+#define C_DISABLE_PM (5)
-+#define C_ENABLE_PM (6)
-
- #define SA1100_NAME "SA1100"
-
---- linux-2.4.25/fs/adfs/dir.c~2.4.25-vrs2.patch 2000-09-19 00:14:06.000000000 +0200
-+++ linux-2.4.25/fs/adfs/dir.c 2004-03-31 17:15:09.000000000 +0200
-@@ -23,7 +23,7 @@
- /*
- * For future. This should probably be per-directory.
- */
--static rwlock_t adfs_dir_lock;
-+static rwlock_t adfs_dir_lock = RW_LOCK_UNLOCKED;
-
- static int
- adfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
---- linux-2.4.25/fs/adfs/map.c~2.4.25-vrs2.patch 2001-10-25 22:53:53.000000000 +0200
-+++ linux-2.4.25/fs/adfs/map.c 2004-03-31 17:15:09.000000000 +0200
-@@ -13,24 +13,27 @@
- #include <linux/adfs_fs.h>
- #include <linux/spinlock.h>
-
-+#include <asm/unaligned.h>
-+
- #include "adfs.h"
-
- /*
- * For the future...
- */
--static rwlock_t adfs_map_lock;
-+static rwlock_t adfs_map_lock = RW_LOCK_UNLOCKED;
-
-+/*
-+ * This is fun. We need to load up to 19 bits from the map at an
-+ * arbitary bit alignment. (We're limited to 19 bits by F+ version
-+ * 2).
-+ */
- #define GET_FRAG_ID(_map,_start,_idmask) \
- ({ \
-- unsigned long _v2, _frag; \
-- unsigned int _tmp; \
-- _tmp = _start >> 5; \
-- _frag = le32_to_cpu(_map[_tmp]); \
-- _v2 = le32_to_cpu(_map[_tmp + 1]); \
-- _tmp = start & 31; \
-- _frag = (_frag >> _tmp) | (_v2 << (32 - _tmp)); \
-+ unsigned char *_m = _map + (_start >> 3); \
-+ u32 _frag = get_unaligned((u32 *)_m); \
-+ _frag >>= (_start & 7); \
- _frag & _idmask; \
-- })
-+ })
-
- /*
- * return the map bit offset of the fragment frag_id in
-@@ -44,14 +47,13 @@
- const unsigned int frag_id, unsigned int *offset)
- {
- const unsigned int mapsize = dm->dm_endbit;
-- const unsigned int idmask = (1 << idlen) - 1;
-- unsigned long *map = ((unsigned long *)dm->dm_bh->b_data) + 1;
-+ const u32 idmask = (1 << idlen) - 1;
-+ unsigned char *map = dm->dm_bh->b_data + 4;
- unsigned int start = dm->dm_startbit;
- unsigned int mapptr;
-+ u32 frag;
-
- do {
-- unsigned long frag;
--
- frag = GET_FRAG_ID(map, start, idmask);
- mapptr = start + idlen;
-
-@@ -59,15 +61,17 @@
- * find end of fragment
- */
- {
-- unsigned long v2;
-+ u32 v, *_map = (u32 *)map;
-
-- while ((v2 = map[mapptr >> 5] >> (mapptr & 31)) == 0) {
-+ v = le32_to_cpu(_map[mapptr >> 5]) >> (mapptr & 31);
-+ while (v == 0) {
- mapptr = (mapptr & ~31) + 32;
- if (mapptr >= mapsize)
- goto error;
-+ v = le32_to_cpu(_map[mapptr >> 5]);
- }
-
-- mapptr += 1 + ffz(~v2);
-+ mapptr += 1 + ffz(~v);
- }
-
- if (frag == frag_id)
-@@ -75,8 +79,11 @@
- again:
- start = mapptr;
- } while (mapptr < mapsize);
-+ return -1;
-
- error:
-+ printk(KERN_ERR "adfs: oversized fragment 0x%x at 0x%x-0x%x\n",
-+ frag, start, mapptr);
- return -1;
-
- found:
-@@ -102,10 +109,10 @@
- const unsigned int mapsize = dm->dm_endbit + 32;
- const unsigned int idlen = asb->s_idlen;
- const unsigned int frag_idlen = idlen <= 15 ? idlen : 15;
-- const unsigned int idmask = (1 << frag_idlen) - 1;
-- unsigned long *map = (unsigned long *)dm->dm_bh->b_data;
-+ const u32 idmask = (1 << frag_idlen) - 1;
-+ unsigned char *map = dm->dm_bh->b_data;
- unsigned int start = 8, mapptr;
-- unsigned long frag;
-+ u32 frag;
- unsigned long total = 0;
-
- /*
-@@ -133,15 +140,17 @@
- * find end of fragment
- */
- {
-- unsigned long v2;
-+ u32 v, *_map = (u32 *)map;
-
-- while ((v2 = map[mapptr >> 5] >> (mapptr & 31)) == 0) {
-+ v = le32_to_cpu(_map[mapptr >> 5]) >> (mapptr & 31);
-+ while (v == 0) {
- mapptr = (mapptr & ~31) + 32;
- if (mapptr >= mapsize)
- goto error;
-+ v = le32_to_cpu(_map[mapptr >> 5]);
- }
-
-- mapptr += 1 + ffz(~v2);
-+ mapptr += 1 + ffz(~v);
- }
-
- total += mapptr - start;
---- linux-2.4.25/fs/adfs/super.c~2.4.25-vrs2.patch 2002-02-25 20:38:07.000000000 +0100
-+++ linux-2.4.25/fs/adfs/super.c 2004-03-31 17:15:09.000000000 +0200
-@@ -386,6 +386,14 @@
- sb->u.adfs_sb.s_size = adfs_discsize(dr, sb->s_blocksize_bits);
- sb->u.adfs_sb.s_version = dr->format_version;
- sb->u.adfs_sb.s_log2sharesize = dr->log2sharesize;
-+
-+ printk(KERN_DEBUG "ADFS: idlen %d map bit size %d sector size %d\n",
-+ dr->idlen, 1 << dr->log2bpmb, 1 << dr->log2secsize);
-+ printk(KERN_DEBUG "ADFS: map size %d map2blk %d version %d share size %d\n",
-+ sb->u.adfs_sb.s_map_size,
-+ sb->u.adfs_sb.s_map2blk,
-+ sb->u.adfs_sb.s_version,
-+ 1 << sb->u.adfs_sb.s_log2sharesize);
-
- sb->u.adfs_sb.s_map = adfs_read_map(sb, dr);
- if (!sb->u.adfs_sb.s_map)
-@@ -393,6 +401,8 @@
-
- brelse(bh);
-
-+ printk(KERN_DEBUG "ADFS: ids per zone %d\n", sb->u.adfs_sb.s_ids_per_zone);
-+
- /*
- * set up enough so that we can read an inode
- */
---- linux-2.4.25/fs/binfmt_aout.c~2.4.25-vrs2.patch 2001-11-03 02:39:20.000000000 +0100
-+++ linux-2.4.25/fs/binfmt_aout.c 2004-03-31 17:15:09.000000000 +0200
-@@ -422,7 +422,11 @@
- start_thread(regs, ex.a_entry, current->mm->start_stack);
- if (current->ptrace & PT_PTRACED)
- send_sig(SIGTRAP, current, 0);
-+#ifndef __arm__
- return 0;
-+#else
-+ return regs->ARM_r0;
-+#endif
- }
-
- static int load_aout_library(struct file *file)
-@@ -452,8 +456,11 @@
-
- /* For QMAGIC, the starting address is 0x20 into the page. We mask
- this off to get the starting address for the page */
--
-- start_addr = ex.a_entry & 0xfffff000;
-+#ifndef __arm__
-+ start_addr = ex.a_entry & 0xfffff000;
-+#else
-+ start_addr = ex.a_entry & 0xffff8000;
-+#endif
-
- if ((N_TXTOFF(ex) & ~PAGE_MASK) != 0) {
- static unsigned long error_time;
---- linux-2.4.25/fs/binfmt_elf.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/fs/binfmt_elf.c 2004-03-31 17:15:09.000000000 +0200
-@@ -635,7 +635,6 @@
- }
-
- current->mm->start_stack = bprm->p;
--
- /* Now we do a little grungy work by mmaping the ELF image into
- the correct location in memory. At this point, we assume that
- the image should be loaded at fixed address, not at a variable
---- linux-2.4.25/fs/exec.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/fs/exec.c 2004-03-31 17:15:09.000000000 +0200
-@@ -315,6 +315,7 @@
- spin_unlock(&tsk->mm->page_table_lock);
-
- /* no need for flush_tlb */
-+ memc_update_addr(tsk->mm, *pte, address);
- return;
- out:
- spin_unlock(&tsk->mm->page_table_lock);
---- linux-2.4.25/fs/jffs/inode-v23.c~2.4.25-vrs2.patch 2001-10-05 00:14:35.000000000 +0200
-+++ linux-2.4.25/fs/jffs/inode-v23.c 2004-03-31 17:15:09.000000000 +0200
-@@ -10,7 +10,7 @@
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
-- * $Id$
-+ * $Id$
- *
- * Ported to Linux 2.3.x and MTD:
- * Copyright (C) 2000 Alexander Larsson (alex@cendio.se), Cendio Systems AB
-@@ -48,6 +48,7 @@
- #include <linux/stat.h>
- #include <linux/blkdev.h>
- #include <linux/quotaops.h>
-+#include <linux/compatmac.h>
- #include <asm/semaphore.h>
- #include <asm/byteorder.h>
- #include <asm/uaccess.h>
-@@ -58,6 +59,11 @@
- #include "jffs_proc.h"
- #endif
-
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2)
-+#define minor(x) MINOR(x)
-+#define major(x) MAJOR(x)
-+#endif
-+
- static int jffs_remove(struct inode *dir, struct dentry *dentry, int type);
-
- static struct super_operations jffs_ops;
-@@ -81,7 +87,7 @@
- D1(printk(KERN_NOTICE "JFFS: Trying to mount device %s.\n",
- kdevname(dev)));
-
-- if (MAJOR(dev) != MTD_BLOCK_MAJOR) {
-+ if (major(dev) != MTD_BLOCK_MAJOR) {
- printk(KERN_WARNING "JFFS: Trying to mount a "
- "non-mtd device.\n");
- return 0;
-@@ -358,7 +364,7 @@
- inode->i_nlink = raw_inode->nlink;
- inode->i_uid = raw_inode->uid;
- inode->i_gid = raw_inode->gid;
-- inode->i_rdev = 0;
-+ inode->i_rdev = NODEV;
- inode->i_size = raw_inode->dsize;
- inode->i_atime = raw_inode->atime;
- inode->i_mtime = raw_inode->mtime;
---- linux-2.4.25/fs/jffs/intrep.c~2.4.25-vrs2.patch 2003-06-13 16:51:37.000000000 +0200
-+++ linux-2.4.25/fs/jffs/intrep.c 2004-03-31 17:15:09.000000000 +0200
-@@ -10,7 +10,7 @@
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
-- * $Id$
-+ * $Id$
- *
- * Ported to Linux 2.3.x and MTD:
- * Copyright (C) 2000 Alexander Larsson (alex@cendio.se), Cendio Systems AB
-@@ -772,6 +772,9 @@
- __u32 free_chunk_size1;
- __u32 free_chunk_size2;
-
-+ __u32 largest_hole = 0;
-+ __u32 hole_end_offset = 0;
-+ __u32 head_offset;
-
- #define NUMFREEALLOWED 2 /* 2 chunks of at least erase size space allowed */
- int num_free_space = 0; /* Flag err if more than TWO
-@@ -884,6 +887,21 @@
- (unsigned int) start,
- (unsigned int)(test_start - start)));
-
-+ D1(printk("Reducing start to 0x%x from 0x%x\n",
-+ test_start, start));
-+ if (largest_hole < test_start - start){
-+
-+ D3(printk("was hole = %x end_offset = %x\n",
-+ largest_hole, hole_end_offset));
-+ if (fmc->head) {
-+ largest_hole = test_start - start;
-+ hole_end_offset = test_start;
-+ }
-+ }
-+
-+ D3(printk("now = %x end_offset = %x\n",
-+ largest_hole, hole_end_offset));
-+
- /* below, space from "start" to "pos" will be marked dirty. */
- start = test_start;
-
-@@ -956,6 +974,19 @@
- num_free_space++;
- D1(printk("Free space accepted: Starting 0x%x for 0x%x bytes\n",
- (unsigned int) start, (unsigned int) (pos - start)));
-+
-+ if (largest_hole < pos - start) {
-+
-+ D3(printk("was hole = %x end_offset = %x\n",
-+ largest_hole, hole_end_offset));
-+ if (fmc->head){
-+ largest_hole = pos - start;
-+ hole_end_offset = pos;
-+ }
-+
-+ D3(printk("now = %x end_offset = %x\n",
-+ largest_hole, hole_end_offset));
-+ }
- }else{
- num_free_spc_not_accp++;
- D1(printk("Free space (#%i) found but *Not* accepted: Starting "
-@@ -968,7 +999,7 @@
- (unsigned int) start, (unsigned int) (pos - start)));
- jffs_fmalloced(fmc, (__u32) start,
- (__u32) (pos - start), 0);
-- }
-+ }
-
- }
- if(num_free_space > NUMFREEALLOWED){
-@@ -1002,9 +1033,11 @@
- to scan for the magic pattern. */
- D1(printk("*************** Dirty flash memory or "
- "bad inode: "
-- "hexdump(pos = 0x%lx, len = 128):\n",
-- (long)pos));
-- D1(jffs_hexdump(fmc->mtd, pos, 128));
-+ "hexdump(pos = 0x%lx, len = %d):\n",
-+ (long)pos,
-+ end - pos > 128 ? 128 : end - pos));
-+ D1(jffs_hexdump(fmc->mtd, pos,
-+ end - pos > 128 ? 128 : end - pos));
-
- for (pos += 4; pos < end; pos += 4) {
- switch (flash_read_u32(fmc->mtd, pos)) {
-@@ -1197,12 +1230,6 @@
-
- return -ENOMEM;
- }
-- if ((err = jffs_insert_node(c, 0, &raw_inode,
-- name, node)) < 0) {
-- printk("JFFS: Failed to handle raw inode. "
-- "(err = %d)\n", err);
-- break;
-- }
- if (raw_inode.rename) {
- struct jffs_delete_list *dl
- = (struct jffs_delete_list *)
-@@ -1226,6 +1253,12 @@
- c->delete_list = dl;
- node->data_size = 0;
- }
-+ if ((err = jffs_insert_node(c, 0, &raw_inode,
-+ name, node)) < 0) {
-+ printk("JFFS: Failed to handle raw inode. "
-+ "(err = %d)\n", err);
-+ break;
-+ }
- D3(jffs_print_node(node));
- node = 0; /* Don't free the node! */
- }
-@@ -1242,7 +1275,19 @@
- jffs_free_node(node);
- DJM(no_jffs_node--);
- }
-- jffs_build_end(fmc);
-+ if (fmc->head && fmc->tail_extra &&
-+ fmc->head->offset + fmc->flash_size -
-+ fmc->tail_extra->offset - fmc->tail_extra->size > largest_hole) {
-+ head_offset = fmc->head->offset;
-+ }
-+ else {
-+ head_offset = hole_end_offset;
-+ }
-+
-+ if (jffs_build_end(fmc, head_offset) < 0) {
-+ D(printk("jffs_build_end() failed\n"));
-+ return -ENOMEM;
-+ }
-
- /* Free read buffer */
- kfree (read_buf);
---- linux-2.4.25/fs/jffs/jffs_fm.c~2.4.25-vrs2.patch 2001-10-05 00:13:18.000000000 +0200
-+++ linux-2.4.25/fs/jffs/jffs_fm.c 2004-03-31 17:15:09.000000000 +0200
-@@ -10,7 +10,7 @@
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
-- * $Id$
-+ * $Id$
- *
- * Ported to Linux 2.3.x and MTD:
- * Copyright (C) 2000 Alexander Larsson (alex@cendio.se), Cendio Systems AB
-@@ -20,8 +20,14 @@
- #include <linux/slab.h>
- #include <linux/blkdev.h>
- #include <linux/jffs.h>
-+#include <linux/compatmac.h>
- #include "jffs_fm.h"
-
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2)
-+#define minor(x) MINOR(x)
-+#define major(x) MAJOR(x)
-+#endif
-+
- #if defined(JFFS_MARK_OBSOLETE) && JFFS_MARK_OBSOLETE
- static int jffs_mark_obsolete(struct jffs_fmcontrol *fmc, __u32 fm_offset);
- #endif
-@@ -46,7 +52,7 @@
- }
- DJM(no_jffs_fmcontrol++);
-
-- mtd = get_mtd_device(NULL, MINOR(dev));
-+ mtd = get_mtd_device(NULL, minor(dev));
-
- if (!mtd) {
- kfree(fmc);
-@@ -89,8 +95,8 @@
-
- /* When the flash memory scan has completed, this function should be called
- before use of the control structure. */
--void
--jffs_build_end(struct jffs_fmcontrol *fmc)
-+int
-+jffs_build_end(struct jffs_fmcontrol *fmc, __u32 head_offset)
- {
- D3(printk("jffs_build_end()\n"));
-
-@@ -99,13 +105,100 @@
- fmc->tail = fmc->tail_extra;
- }
- else if (fmc->head_extra) {
-- fmc->tail_extra->next = fmc->head;
-- fmc->head->prev = fmc->tail_extra;
-- fmc->head = fmc->head_extra;
-+ struct jffs_fm *fm, *cur;
-+
-+ if (head_offset == fmc->head->offset){
-+ fmc->tail->next = fmc->head_extra;
-+ fmc->head_extra->prev = fmc->tail;
-+ fmc->tail = fmc->tail_extra;
-+ }
-+ else {
-+ fmc->tail_extra->next = fmc->head;
-+ fmc->head->prev = fmc->tail_extra;
-+ fmc->head = fmc->head_extra;
-+ while (fmc->head->offset != head_offset){
-+ fmc->tail->next = fmc->head;
-+ fmc->head = fmc->head->next;
-+ fmc->head->prev = 0;
-+ fmc->tail->next->prev = fmc->tail;
-+ fmc->tail = fmc->tail->next;
-+ fmc->tail->next = 0;
-+ }
-+ }
-+ /* Make sure the only free space we have is between tail and head.
-+ */
-+ for (cur = fmc->head; cur && cur != fmc->tail;) {
-+ if (cur->offset + cur->size < cur->next->offset) {
-+ if (!(fm = kmalloc(sizeof(struct jffs_fm), GFP_KERNEL))) {
-+ D(printk("jffs_buid_end(): kmalloc failed!\n"));
-+ return -ENOMEM;
-+ }
-+ DJM(no_jffs_fm++);
-+ fm->size = cur->next->offset - cur->offset - cur->size;
-+ fm->offset = cur->offset + cur->size;
-+ fm->nodes = 0;
-+ fm->next = cur->next;
-+ fm->prev = cur;
-+ cur->next->prev = fm;
-+ cur->next = fm;
-+ cur = fm->next;
-+ fmc->free_size -= fm->size;
-+ fmc->dirty_size += fm->size;
-+ }
-+ else if (cur->offset > cur->next->offset) {
-+ if (cur->offset + cur->size < fmc->flash_size){
-+ if (!(fm = kmalloc(sizeof(struct jffs_fm), GFP_KERNEL))){
-+
-+ D(printk("jffs_buid_end(): kmalloc failed!\n"));
-+ return -ENOMEM;
-+ }
-+ DJM(no_jffs_fm++);
-+ fm->size = fmc->flash_size -
-+ cur->offset - cur->size;
-+ fm->nodes = 0;
-+ fm->offset = cur->offset + cur->size;
-+ fm->next = cur->next;
-+ fm->prev = cur;
-+ cur->next->prev = fm;
-+ cur->next = fm;
-+ cur = fm->next;
-+ fmc->free_size -= fm->size;
-+ fmc->dirty_size += fm->size;
-+ }
-+ else {
-+ cur = cur->next;
-+ }
-+ if (cur->offset > 0) {
-+
-+ if (!(fm = kmalloc(sizeof(struct jffs_fm), GFP_KERNEL))) {
-+ D(printk("jffs_buid_end(): kmalloc failed!\n"));
-+ return -ENOMEM;
-+ }
-+ DJM(no_jffs_fm++);
-+ fm->size = cur->offset;
-+ fm->nodes = 0;
-+ fm->offset = 0;
-+ fm->next = cur;
-+ fm->prev = cur->prev;
-+ cur->prev->next = fm;
-+ cur->prev = fm;
-+ fmc->free_size -= fm->size;
-+ fmc->dirty_size += fm->size;
-+ }
-+ }
-+ else if (cur->offset + cur->size != cur->next->offset) {
-+ printk("jffs_build_end(): Internal error.\n");
-+ return -EINVAL;
-+ }
-+ else {
-+ cur = cur->next;
-+ }
-+ }
- }
- fmc->head_extra = 0; /* These two instructions should be omitted. */
- fmc->tail_extra = 0;
- D3(jffs_print_fmcontrol(fmc));
-+ return 0;
- }
-
-
---- linux-2.4.25/fs/jffs/jffs_fm.h~2.4.25-vrs2.patch 2001-10-05 00:13:18.000000000 +0200
-+++ linux-2.4.25/fs/jffs/jffs_fm.h 2004-03-31 17:15:09.000000000 +0200
-@@ -10,7 +10,7 @@
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
-- * $Id$
-+ * $Id$
- *
- * Ported to Linux 2.3.x and MTD:
- * Copyright (C) 2000 Alexander Larsson (alex@cendio.se), Cendio Systems AB
-@@ -123,7 +123,7 @@
-
-
- struct jffs_fmcontrol *jffs_build_begin(struct jffs_control *c, kdev_t dev);
--void jffs_build_end(struct jffs_fmcontrol *fmc);
-+int jffs_build_end(struct jffs_fmcontrol *fmc, __u32 head_offset);
- void jffs_cleanup_fmcontrol(struct jffs_fmcontrol *fmc);
-
- int jffs_fmalloc(struct jffs_fmcontrol *fmc, __u32 size,
---- linux-2.4.25/fs/partitions/Config.in~2.4.25-vrs2.patch 2002-11-29 00:53:15.000000000 +0100
-+++ linux-2.4.25/fs/partitions/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -6,6 +6,7 @@
- bool ' Acorn partition support' CONFIG_ACORN_PARTITION
- if [ "$CONFIG_ACORN_PARTITION" != "n" ]; then
- # bool ' Cumana partition support' CONFIG_ACORN_PARTITION_CUMANA
-+ bool ' EESOX partition support' CONFIG_ACORN_PARTITION_EESOX
- bool ' ICS partition support' CONFIG_ACORN_PARTITION_ICS
- bool ' Native filecore partition support' CONFIG_ACORN_PARTITION_ADFS
- bool ' PowerTec partition support' CONFIG_ACORN_PARTITION_POWERTEC
-@@ -52,6 +53,7 @@
- define_bool CONFIG_ACORN_PARTITION y
- define_bool CONFIG_ACORN_PARTITION_ADFS y
- # define_bool CONFIG_ACORN_PARTITION_CUMANA y
-+ define_bool CONFIG_ACORN_PARTITION_EESOX y
- define_bool CONFIG_ACORN_PARTITION_ICS y
- define_bool CONFIG_ACORN_PARTITION_POWERTEC y
- define_bool CONFIG_ACORN_PARTITION_RISCIX y
---- linux-2.4.25/fs/partitions/acorn.c~2.4.25-vrs2.patch 2002-08-03 02:39:45.000000000 +0200
-+++ linux-2.4.25/fs/partitions/acorn.c 2004-03-31 17:15:09.000000000 +0200
-@@ -7,7 +7,10 @@
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-- * Scan ADFS partitions on hard disk drives.
-+ * Scan ADFS partitions on hard disk drives. Unfortunately, there
-+ * isn't a standard for partitioning drives on Acorn machines, so
-+ * every single manufacturer of SCSI and IDE cards created their own
-+ * method.
- */
- #include <linux/config.h>
- #include <linux/kernel.h>
-@@ -18,10 +21,18 @@
- #include <linux/genhd.h>
- #include <linux/fs.h>
- #include <linux/pagemap.h>
-+#include <linux/adfs_fs.h>
-
- #include "check.h"
- #include "acorn.h"
-
-+/*
-+ * Partition types. (Oh for reusability)
-+ */
-+#define PARTITION_RISCIX_MFM 1
-+#define PARTITION_RISCIX_SCSI 2
-+#define PARTITION_LINUX 9
-+
- static void
- adfspart_setgeometry(kdev_t dev, unsigned int secspertrack, unsigned int heads)
- {
-@@ -61,6 +72,21 @@
- }
-
- #ifdef CONFIG_ACORN_PARTITION_RISCIX
-+
-+struct riscix_part {
-+ __u32 start;
-+ __u32 length;
-+ __u32 one;
-+ char name[16];
-+};
-+
-+struct riscix_record {
-+ __u32 magic;
-+#define RISCIX_MAGIC (0x4a657320)
-+ __u32 date;
-+ struct riscix_part part[8];
-+};
-+
- static int
- riscix_partition(struct gendisk *hd, struct block_device *bdev,
- unsigned long first_sect, int minor, unsigned long nr_sects)
-@@ -102,6 +128,15 @@
- }
- #endif
-
-+#define LINUX_NATIVE_MAGIC 0xdeafa1de
-+#define LINUX_SWAP_MAGIC 0xdeafab1e
-+
-+struct linux_part {
-+ __u32 magic;
-+ __u32 start_sect;
-+ __u32 nr_sects;
-+};
-+
- static int
- linux_partition(struct gendisk *hd, struct block_device *bdev,
- unsigned long first_sect, int minor, unsigned long nr_sects)
-@@ -136,7 +171,7 @@
- }
-
- #ifdef CONFIG_ACORN_PARTITION_CUMANA
--static int
-+int
- adfspart_check_CUMANA(struct gendisk *hd, struct block_device *bdev,
- unsigned long first_sector, int minor)
- {
-@@ -147,7 +182,7 @@
- int first = 1;
-
- /*
-- * Try Cumana style partitions - sector 3 contains ADFS boot block
-+ * Try Cumana style partitions - sector 6 contains ADFS boot block
- * with pointer to next 'drive'.
- *
- * There are unknowns in this code - is the 'cylinder number' of the
-@@ -163,13 +198,13 @@
- struct adfs_discrecord *dr;
- unsigned int nr_sects;
-
-- if (!(minor & mask))
-- break;
--
- data = read_dev_sector(bdev, start_blk * 2 + 6, &sect);
- if (!data)
- return -1;
-
-+ if (!(minor & mask))
-+ break;
-+
- dr = adfs_partition(hd, name, data, first_sector, minor++);
- if (!dr)
- break;
-@@ -229,7 +264,7 @@
- * hda1 = ADFS partition on first drive.
- * hda2 = non-ADFS partition.
- */
--static int
-+int
- adfspart_check_ADFS(struct gendisk *hd, struct block_device *bdev,
- unsigned long first_sector, int minor)
- {
-@@ -282,11 +317,18 @@
- break;
- }
- }
-+ printk("\n");
- return 1;
- }
- #endif
-
- #ifdef CONFIG_ACORN_PARTITION_ICS
-+
-+struct ics_part {
-+ __u32 start;
-+ __s32 size;
-+};
-+
- static int adfspart_check_ICSLinux(struct block_device *bdev, unsigned long block)
- {
- Sector sect;
-@@ -303,6 +345,22 @@
- }
-
- /*
-+ * Check for a valid ICS partition using the checksum.
-+ */
-+static inline int valid_ics_sector(const unsigned char *data)
-+{
-+ unsigned long sum;
-+ int i;
-+
-+ for (i = 0, sum = 0x50617274; i < 508; i++)
-+ sum += data[i];
-+
-+ sum -= le32_to_cpu(*(__u32 *)(&data[508]));
-+
-+ return sum == 0;
-+}
-+
-+/*
- * Purpose: allocate ICS partitions.
- * Params : hd - pointer to gendisk structure to store partition info.
- * dev - device number to access.
-@@ -314,15 +372,14 @@
- * hda2 = ADFS partition 1 on first drive.
- * ..etc..
- */
--static int
-+int
- adfspart_check_ICS(struct gendisk *hd, struct block_device *bdev,
- unsigned long first_sector, int minor)
- {
-+ const unsigned char *data;
-+ const struct ics_part *p;
-+ unsigned int mask = (1 << hd->minor_shift) - 1;
- Sector sect;
-- unsigned char *data;
-- unsigned long sum;
-- unsigned int i, mask = (1 << hd->minor_shift) - 1;
-- struct ics_part *p;
-
- /*
- * Try ICS style partitions - sector 0 contains partition info.
-@@ -331,21 +388,14 @@
- if (!data)
- return -1;
-
-- /*
-- * check for a valid checksum
-- */
-- for (i = 0, sum = 0x50617274; i < 508; i++)
-- sum += data[i];
--
-- sum -= le32_to_cpu(*(__u32 *)(&data[508]));
-- if (sum) {
-- put_dev_sector(sect);
-- return 0; /* not ICS partition table */
-+ if (!valid_ics_sector(data)) {
-+ put_dev_sector(sect);
-+ return 0;
- }
-
- printk(" [ICS]");
-
-- for (p = (struct ics_part *)data; p->size; p++) {
-+ for (p = (const struct ics_part *)data; p->size; p++) {
- unsigned long start;
- long size;
-
-@@ -355,12 +405,19 @@
- start = le32_to_cpu(p->start);
- size = le32_to_cpu(p->size);
-
-+ /*
-+ * Negative sizes tell the RISC OS ICS driver to ignore
-+ * this partition - in effect it says that this does not
-+ * contain an ADFS filesystem.
-+ */
- if (size < 0) {
- size = -size;
-
- /*
-- * We use the first sector to identify what type
-- * this partition is...
-+ * Our own extension - We use the first sector
-+ * of the partition to identify what type this
-+ * partition is. We must not make this visible
-+ * to the filesystem.
- */
- if (size > 1 && adfspart_check_ICSLinux(bdev, start)) {
- start += 1;
-@@ -375,10 +432,32 @@
- }
-
- put_dev_sector(sect);
-+ printk("\n");
- return 1;
- }
- #endif
-
-+#ifdef CONFIG_ACORN_PARTITION_POWERTEC
-+struct ptec_part {
-+ __u32 unused1;
-+ __u32 unused2;
-+ __u32 start;
-+ __u32 size;
-+ __u32 unused5;
-+ char type[8];
-+};
-+
-+static inline int valid_ptec_sector(const unsigned char *data)
-+{
-+ unsigned char checksum = 0x2a;
-+ int i;
-+
-+ for (i = 0; i < 511; i++)
-+ checksum += data[i];
-+
-+ return checksum == data[511];
-+}
-+
- /*
- * Purpose: allocate ICS partitions.
- * Params : hd - pointer to gendisk structure to store partition info.
-@@ -391,32 +470,27 @@
- * hda2 = ADFS partition 1 on first drive.
- * ..etc..
- */
--#ifdef CONFIG_ACORN_PARTITION_POWERTEC
--static int
-+int
- adfspart_check_POWERTEC(struct gendisk *hd, struct block_device *bdev,
- unsigned long first_sector, int minor)
- {
- Sector sect;
-- unsigned char *data;
-- struct ptec_partition *p;
-- unsigned char checksum;
-+ const unsigned char *data;
-+ const struct ptec_part *p;
- int i;
-
- data = read_dev_sector(bdev, 0, &sect);
- if (!data)
- return -1;
-
-- for (checksum = 0x2a, i = 0; i < 511; i++)
-- checksum += data[i];
--
-- if (checksum != data[511]) {
-+ if (!valid_ptec_sector(data)) {
- put_dev_sector(sect);
- return 0;
- }
-
- printk(" [POWERTEC]");
-
-- for (i = 0, p = (struct ptec_partition *)data; i < 12; i++, p++) {
-+ for (i = 0, p = (const struct ptec_part *)data; i < 12; i++, p++) {
- unsigned long start;
- unsigned long size;
-
-@@ -430,49 +504,82 @@
- }
-
- put_dev_sector(sect);
-+ printk("\n");
- return 1;
- }
- #endif
-
--static int (*partfn[])(struct gendisk *, struct block_device *, unsigned long, int) = {
--#ifdef CONFIG_ACORN_PARTITION_ICS
-- adfspart_check_ICS,
--#endif
--#ifdef CONFIG_ACORN_PARTITION_POWERTEC
-- adfspart_check_POWERTEC,
--#endif
--#ifdef CONFIG_ACORN_PARTITION_CUMANA
-- adfspart_check_CUMANA,
--#endif
--#ifdef CONFIG_ACORN_PARTITION_ADFS
-- adfspart_check_ADFS,
--#endif
-- NULL
-+#ifdef CONFIG_ACORN_PARTITION_EESOX
-+struct eesox_part {
-+ char magic[6];
-+ char name[10];
-+ u32 start;
-+ u32 unused6;
-+ u32 unused7;
-+ u32 unused8;
- };
-+
- /*
-- * Purpose: initialise all the partitions on an ADFS drive.
-- * These may be other ADFS partitions or a Linux/RiscBSD/RISCiX
-- * partition.
-+ * Guess who created this format?
-+ */
-+static const char eesox_name[] = {
-+ 'N', 'e', 'i', 'l', ' ',
-+ 'C', 'r', 'i', 't', 'c', 'h', 'e', 'l', 'l', ' ', ' '
-+};
-+
-+/*
-+ * EESOX SCSI partition format.
- *
-- * Params : hd - pointer to gendisk structure
-- * dev - device number to access
-- * first_sect - first available sector on the disk.
-- * first_minor - first available minor on this device.
-+ * This is a goddamned awful partition format. We don't seem to store
-+ * the size of the partition in this table, only the start addresses.
- *
-- * Returns: -1 on error, 0 if not ADFS format, 1 if ok.
-+ * There are two possibilities where the size comes from:
-+ * 1. The individual ADFS boot block entries that are placed on the disk.
-+ * 2. The start address of the next entry.
- */
--int acorn_partition(struct gendisk *hd, struct block_device *bdev,
-- unsigned long first_sect, int first_minor)
-+int
-+adfspart_check_EESOX(struct gendisk *hd, struct block_device *bdev,
-+ unsigned long first_sector, int minor)
- {
-+ Sector sect;
-+ const unsigned char *data;
-+ unsigned char buffer[256];
-+ struct eesox_part *p;
-+ u32 start = first_sector;
- int i;
-
-- for (i = 0; partfn[i]; i++) {
-- int r = partfn[i](hd, bdev, first_sect, first_minor);
-- if (r) {
-- if (r > 0)
-- printk("\n");
-- return r;
-- }
-+ data = read_dev_sector(bdev, 7, &sect);
-+ if (!data)
-+ return -1;
-+
-+ /*
-+ * "Decrypt" the partition table. God knows why...
-+ */
-+ for (i = 0; i < 256; i++)
-+ buffer[i] = data[i] ^ eesox_name[i & 15];
-+
-+ put_dev_sector(sect);
-+
-+ for (i = 0, p = (struct eesox_part *)buffer; i < 8; i++, p++) {
-+ u32 next;
-+
-+ if (memcmp(p->magic, "Eesox", 6))
-+ break;
-+
-+ next = le32_to_cpu(p->start) + first_sector;
-+ if (i)
-+ add_gd_partition(hd, minor++, start, next - start);
-+ start = next;
- }
-- return 0;
-+
-+ if (i != 0) {
-+ unsigned long size;
-+
-+ size = hd->part[MINOR(to_kdev_t(bdev->bd_dev))].nr_sects;
-+ add_gd_partition(hd, minor++, start, size - start);
-+ printk("\n");
-+ }
-+
-+ return i ? 1 : 0;
- }
-+#endif
---- linux-2.4.25/fs/partitions/acorn.h~2.4.25-vrs2.patch 2001-11-22 20:48:07.000000000 +0100
-+++ linux-2.4.25/fs/partitions/acorn.h 2004-03-31 17:15:09.000000000 +0200
-@@ -1,55 +1,28 @@
- /*
-- * fs/partitions/acorn.h
-+ * linux/fs/partitions/acorn.h
- *
-- * Copyright (C) 1996-1998 Russell King
-- */
--#include <linux/adfs_fs.h>
--
--/*
-- * Partition types. (Oh for reusability)
-+ * Copyright (C) 1996-2001 Russell King.
-+ *
-+ * I _hate_ this partitioning mess - why can't we have one defined
-+ * format, and everyone stick to it?
- */
--#define PARTITION_RISCIX_MFM 1
--#define PARTITION_RISCIX_SCSI 2
--#define PARTITION_LINUX 9
--
--struct riscix_part {
-- __u32 start;
-- __u32 length;
-- __u32 one;
-- char name[16];
--};
-
--struct riscix_record {
-- __u32 magic;
--#define RISCIX_MAGIC (0x4a657320)
-- __u32 date;
-- struct riscix_part part[8];
--};
--
--#define LINUX_NATIVE_MAGIC 0xdeafa1de
--#define LINUX_SWAP_MAGIC 0xdeafab1e
--
--struct linux_part {
-- __u32 magic;
-- __u32 start_sect;
-- __u32 nr_sects;
--};
-+int
-+adfspart_check_CUMANA(struct gendisk *hd, struct block_device *bdev,
-+ unsigned long first_sector, int minor);
-
--struct ics_part {
-- __u32 start;
-- __s32 size;
--};
-+int
-+adfspart_check_ADFS(struct gendisk *hd, struct block_device *bdev,
-+ unsigned long first_sector, int minor);
-
--struct ptec_partition {
-- __u32 unused1;
-- __u32 unused2;
-- __u32 start;
-- __u32 size;
-- __u32 unused5;
-- char type[8];
--};
--
-+int
-+adfspart_check_ICS(struct gendisk *hd, struct block_device *bdev,
-+ unsigned long first_sector, int minor);
-
--int acorn_partition(struct gendisk *hd, struct block_device *bdev,
-- unsigned long first_sect, int first_minor);
-+int
-+adfspart_check_POWERTEC(struct gendisk *hd, struct block_device *bdev,
-+ unsigned long first_sector, int minor);
-
-+int
-+adfspart_check_EESOX(struct gendisk *hd, struct block_device *bdev,
-+ unsigned long first_sector, int minor);
---- linux-2.4.25/fs/partitions/check.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/fs/partitions/check.c 2004-03-31 17:15:09.000000000 +0200
-@@ -40,8 +40,30 @@
- int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
-
- static int (*check_part[])(struct gendisk *hd, struct block_device *bdev, unsigned long first_sect, int first_minor) = {
--#ifdef CONFIG_ACORN_PARTITION
-- acorn_partition,
-+ /*
-+ * Probe partition formats with tables at disk address 0
-+ * that also have an ADFS boot block at 0xdc0.
-+ */
-+#ifdef CONFIG_ACORN_PARTITION_ICS
-+ adfspart_check_ICS,
-+#endif
-+#ifdef CONFIG_ACORN_PARTITION_POWERTEC
-+ adfspart_check_POWERTEC,
-+#endif
-+#ifdef CONFIG_ACORN_PARTITION_EESOX
-+ adfspart_check_EESOX,
-+#endif
-+
-+ /*
-+ * Now move on to formats that only have partition info at
-+ * disk address 0xdc0. These should come before MSDOS
-+ * partition tables.
-+ */
-+#ifdef CONFIG_ACORN_PARTITION_CUMANA
-+ adfspart_check_CUMANA,
-+#endif
-+#ifdef CONFIG_ACORN_PARTITION_ADFS
-+ adfspart_check_ADFS,
- #endif
- #ifdef CONFIG_SGI_PARTITION
- sgi_partition,
-@@ -79,13 +101,25 @@
- NULL
- };
-
-+static char *raid_name (struct gendisk *hd, unsigned int unit, unsigned int part,
-+ int major_base, char *buf)
-+{
-+ int ctlr = hd->major - major_base;
-+ if (part == 0)
-+ sprintf(buf, "%s/c%dd%d", hd->major_name, ctlr, unit);
-+ else
-+ sprintf(buf, "%s/c%dd%dp%d", hd->major_name, ctlr, unit,
-+ part);
-+ return buf;
-+}
-+
- /*
- * This is ucking fugly but its probably the best thing for 2.4.x
- * Take it as a clear reminder that: 1) we should put the device name
- * generation in the object kdev_t points to in 2.5.
- * and 2) ioctls better work on half-opened devices.
- */
--
-+
- #ifdef CONFIG_ARCH_S390
- int (*genhd_dasd_name)(char*,int,int,struct gendisk*) = NULL;
- int (*genhd_dasd_ioctl)(struct inode *inp, struct file *filp,
-@@ -104,10 +138,11 @@
- char *disk_name (struct gendisk *hd, int minor, char *buf)
- {
- const char *maj = hd->major_name;
-- unsigned int unit = (minor >> hd->minor_shift);
-- unsigned int part = (minor & ((1 << hd->minor_shift) -1 ));
-+ unsigned int unit = minor >> hd->minor_shift;
-+ unsigned int part = minor & (( 1 << hd->minor_shift) - 1);
-+ char *p;
-
-- if ((unit < hd->nr_real) && hd->part[minor].de) {
-+ if (unit < hd->nr_real && hd->part[minor].de) {
- int pos;
-
- pos = devfs_generate_path (hd->part[minor].de, buf, 64);
-@@ -153,51 +188,32 @@
- }
- if (hd->major >= SCSI_DISK1_MAJOR && hd->major <= SCSI_DISK7_MAJOR) {
- unit = unit + (hd->major - SCSI_DISK1_MAJOR + 1) * 16;
-- if (unit+'a' > 'z') {
-- unit -= 26;
-- sprintf(buf, "sd%c%c", 'a' + unit / 26, 'a' + unit % 26);
-- if (part)
-- sprintf(buf + 4, "%d", part);
-- return buf;
-- }
- }
- if (hd->major >= COMPAQ_SMART2_MAJOR && hd->major <= COMPAQ_SMART2_MAJOR+7) {
-- int ctlr = hd->major - COMPAQ_SMART2_MAJOR;
-- if (part == 0)
-- sprintf(buf, "%s/c%dd%d", maj, ctlr, unit);
-- else
-- sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part);
-- return buf;
-- }
-+ return raid_name(hd, unit, part, COMPAQ_SMART2_MAJOR, buf);
-+ }
- if (hd->major >= COMPAQ_CISS_MAJOR && hd->major <= COMPAQ_CISS_MAJOR+7) {
-- int ctlr = hd->major - COMPAQ_CISS_MAJOR;
-- if (part == 0)
-- sprintf(buf, "%s/c%dd%d", maj, ctlr, unit);
-- else
-- sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part);
-- return buf;
-+ return raid_name(hd, unit, part, COMPAQ_CISS_MAJOR, buf);
- }
- if (hd->major >= DAC960_MAJOR && hd->major <= DAC960_MAJOR+7) {
-- int ctlr = hd->major - DAC960_MAJOR;
-+ return raid_name(hd, unit, part, DAC960_MAJOR, buf);
-+ }
-+ if (hd->major == ATARAID_MAJOR) {
-+ int disk = minor >> hd->minor_shift;
-+ int part = minor & (( 1 << hd->minor_shift) - 1);
- if (part == 0)
-- sprintf(buf, "%s/c%dd%d", maj, ctlr, unit);
-+ sprintf(buf, "%s/d%d", maj, disk);
- else
-- sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part);
-+ sprintf(buf, "%s/d%dp%d", maj, disk, part);
- return buf;
- }
-- if (hd->major == ATARAID_MAJOR) {
-- int disk = minor >> hd->minor_shift;
-- int part = minor & (( 1 << hd->minor_shift) - 1);
-- if (part == 0)
-- sprintf(buf, "%s/d%d", maj, disk);
-- else
-- sprintf(buf, "%s/d%dp%d", maj, disk, part);
-- return buf;
-- }
-- if (part)
-- sprintf(buf, "%s%c%d", maj, unit+'a', part);
-+ p = buf;
-+ if (unit <= 26)
-+ p += sprintf(buf, "%s%c", maj, 'a' + unit);
- else
-- sprintf(buf, "%s%c", maj, unit+'a');
-+ p += sprintf(buf, "%s%c%c", maj, 'a' + unit / 26, 'a' + unit % 26);
-+ if (part)
-+ sprintf(p, "%d", part);
- return buf;
- }
-
-@@ -207,7 +223,7 @@
- void add_gd_partition(struct gendisk *hd, int minor, int start, int size)
- {
- #ifndef CONFIG_DEVFS_FS
-- char buf[40];
-+ char buf[MAX_DISKNAME_LEN];
- #endif
-
- hd->part[minor].start_sect = start;
-@@ -229,7 +245,7 @@
- static int first_time = 1;
- unsigned long first_sector;
- struct block_device *bdev;
-- char buf[64];
-+ char buf[MAX_DISKNAME_LEN];
- int i;
-
- if (first_time)
---- linux-2.4.25/fs/proc/array.c~2.4.25-vrs2.patch 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.25/fs/proc/array.c 2004-03-31 17:15:09.000000000 +0200
-@@ -362,15 +362,15 @@
- task->cmin_flt,
- task->maj_flt,
- task->cmaj_flt,
-- task->times.tms_utime,
-- task->times.tms_stime,
-- task->times.tms_cutime,
-- task->times.tms_cstime,
-+ hz_to_std(task->times.tms_utime),
-+ hz_to_std(task->times.tms_stime),
-+ hz_to_std(task->times.tms_cutime),
-+ hz_to_std(task->times.tms_cstime),
- priority,
- nice,
- 0UL /* removed */,
- task->it_real_value,
-- task->start_time,
-+ hz_to_std(task->start_time),
- vsize,
- mm ? mm->rss : 0, /* you might want to shift this left 3 */
- task->rlim[RLIMIT_RSS].rlim_cur,
-@@ -417,6 +417,7 @@
- end = PMD_SIZE;
- do {
- pte_t page = *pte;
-+ unsigned long pfn;
- struct page *ptpage;
-
- address += PAGE_SIZE;
-@@ -426,8 +427,11 @@
- ++*total;
- if (!pte_present(page))
- continue;
-- ptpage = pte_page(page);
-- if ((!VALID_PAGE(ptpage)) || PageReserved(ptpage))
-+ pfn = pte_pfn(page);
-+ if (!pfn_valid(pfn))
-+ continue;
-+ ptpage = pfn_to_page(pfn);
-+ if (PageReserved(ptpage))
- continue;
- ++*pages;
- if (pte_dirty(page))
-@@ -609,14 +613,14 @@
-
- len = sprintf(buffer,
- "cpu %lu %lu\n",
-- task->times.tms_utime,
-- task->times.tms_stime);
-+ hz_to_std(task->times.tms_utime),
-+ hz_to_std(task->times.tms_stime));
-
- for (i = 0 ; i < smp_num_cpus; i++)
- len += sprintf(buffer + len, "cpu%d %lu %lu\n",
- i,
-- task->per_cpu_utime[cpu_logical_map(i)],
-- task->per_cpu_stime[cpu_logical_map(i)]);
-+ hz_to_std(task->per_cpu_utime[cpu_logical_map(i)]),
-+ hz_to_std(task->per_cpu_stime[cpu_logical_map(i)]));
-
- return len;
- }
---- linux-2.4.25/fs/proc/proc_misc.c~2.4.25-vrs2.patch 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.25/fs/proc/proc_misc.c 2004-03-31 17:15:09.000000000 +0200
-@@ -308,16 +308,16 @@
- {
- int i, len = 0;
- extern unsigned long total_forks;
-- unsigned long jif = jiffies;
-+ unsigned long jif = hz_to_std(jiffies);
- unsigned int sum = 0, user = 0, nice = 0, system = 0;
- int major, disk;
-
- for (i = 0 ; i < smp_num_cpus; i++) {
- int cpu = cpu_logical_map(i), j;
-
-- user += kstat.per_cpu_user[cpu];
-- nice += kstat.per_cpu_nice[cpu];
-- system += kstat.per_cpu_system[cpu];
-+ user += hz_to_std(kstat.per_cpu_user[cpu]);
-+ nice += hz_to_std(kstat.per_cpu_nice[cpu]);
-+ system += hz_to_std(kstat.per_cpu_system[cpu]);
- #if !defined(CONFIG_ARCH_S390)
- for (j = 0 ; j < NR_IRQS ; j++)
- sum += kstat.irqs[cpu][j];
-@@ -331,10 +331,10 @@
- proc_sprintf(page, &off, &len,
- "cpu%d %u %u %u %lu\n",
- i,
-- kstat.per_cpu_user[cpu_logical_map(i)],
-- kstat.per_cpu_nice[cpu_logical_map(i)],
-- kstat.per_cpu_system[cpu_logical_map(i)],
-- jif - ( kstat.per_cpu_user[cpu_logical_map(i)] \
-+ hz_to_std(kstat.per_cpu_user[cpu_logical_map(i)]),
-+ hz_to_std(kstat.per_cpu_nice[cpu_logical_map(i)]),
-+ hz_to_std(kstat.per_cpu_system[cpu_logical_map(i)]),
-+ jif - hz_to_std( kstat.per_cpu_user[cpu_logical_map(i)] \
- + kstat.per_cpu_nice[cpu_logical_map(i)] \
- + kstat.per_cpu_system[cpu_logical_map(i)]));
- proc_sprintf(page, &off, &len,
-@@ -440,12 +440,14 @@
- return proc_calc_metrics(page, start, off, count, eof, len);
- }
-
-+#ifdef CONFIG_GENERIC_ISA_DMA
- static int dma_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
- {
- int len = get_dma_list(page);
- return proc_calc_metrics(page, start, off, count, eof, len);
- }
-+#endif
-
- static int cmdline_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-@@ -613,7 +615,9 @@
- {"interrupts", interrupts_read_proc},
- #endif
- {"filesystems", filesystems_read_proc},
-+#ifdef CONFIG_GENERIC_ISA_DMA
- {"dma", dma_read_proc},
-+#endif
- {"cmdline", cmdline_read_proc},
- #ifdef CONFIG_SGI_DS1286
- {"rtc", ds1286_read_proc},
---- linux-2.4.25/fs/stat.c~2.4.25-vrs2.patch 2004-02-18 14:36:31.000000000 +0100
-+++ linux-2.4.25/fs/stat.c 2004-03-31 17:15:09.000000000 +0200
-@@ -26,7 +26,9 @@
- }
-
-
--#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) && !defined(__mips__)
-+#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && \
-+ !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__arm__) && \
-+ !defined(__x86_64__) && !defined(__mips__)
-
- /*
- * For backward compatibility? Maybe this should be moved
-@@ -38,7 +40,7 @@
- struct __old_kernel_stat tmp;
-
- memset(&tmp, 0, sizeof(struct __old_kernel_stat));
--
-+
- if (warncount > 0) {
- warncount--;
- printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n",
-@@ -58,7 +60,7 @@
- #if BITS_PER_LONG == 32
- if (inode->i_size > MAX_NON_LFS)
- return -EOVERFLOW;
--#endif
-+#endif
- tmp.st_size = inode->i_size;
- tmp.st_atime = inode->i_atime;
- tmp.st_mtime = inode->i_mtime;
-@@ -84,7 +86,7 @@
- #if BITS_PER_LONG == 32
- if (inode->i_size > MAX_NON_LFS)
- return -EOVERFLOW;
--#endif
-+#endif
- tmp.st_size = inode->i_size;
- tmp.st_atime = inode->i_atime;
- tmp.st_mtime = inode->i_mtime;
-@@ -129,7 +131,9 @@
- }
-
-
--#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) && !defined(__mips__)
-+#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && \
-+ !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__arm__) && \
-+ !defined(__x86_64__) && !defined(__mips__)
- /*
- * For backward compatibility? Maybe this should be moved
- * into arch/i386 instead?
-@@ -165,7 +169,9 @@
- return error;
- }
-
--#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) && !defined(__mips__)
-+#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && \
-+ !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__arm__) && \
-+ !defined(__x86_64__) && !defined(__mips__)
-
- /*
- * For backward compatibility? Maybe this should be moved
-@@ -203,7 +209,9 @@
- return error;
- }
-
--#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__x86_64__) && !defined(__mips__)
-+#if !defined(__alpha__) && !defined(__sparc__) && !defined(__ia64__) && \
-+ !defined(CONFIG_ARCH_S390) && !defined(__hppa__) && !defined(__arm__) && \
-+ !defined(__x86_64__) && !defined(__mips__)
-
- /*
- * For backward compatibility? Maybe this should be moved
---- linux-2.4.25/include/asm-alpha/ide.h~2.4.25-vrs2.patch 2003-06-13 16:51:38.000000000 +0200
-+++ linux-2.4.25/include/asm-alpha/ide.h 2004-03-31 17:15:09.000000000 +0200
-@@ -19,35 +19,15 @@
- #define MAX_HWIFS 4
- #endif
-
--static __inline__ int ide_default_irq(ide_ioreg_t base)
--{
-- switch (base) {
-- case 0x1f0: return 14;
-- case 0x170: return 15;
-- case 0x1e8: return 11;
-- case 0x168: return 10;
-- default:
-- return 0;
-- }
--}
--
--static __inline__ ide_ioreg_t ide_default_io_base(int index)
--{
-- switch (index) {
-- case 0: return 0x1f0;
-- case 1: return 0x170;
-- case 2: return 0x1e8;
-- case 3: return 0x168;
-- default:
-- return 0;
-- }
--}
-+#define ide_default_io_base(i) ((ide_ioreg_t)0)
-+#define ide_default_irq(b) (0)
-
- static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
- {
- ide_ioreg_t reg = data_port;
- int i;
-
-+ memset(hw, 0, sizeof(*hw));
- for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
- hw->io_ports[i] = reg;
- reg += 1;
-@@ -55,7 +35,7 @@
- if (ctrl_port) {
- hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
- } else {
-- hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
-+ hw->io_ports[IDE_CONTROL_OFFSET] = data_port + 0x206;
- }
- if (irq != NULL)
- *irq = 0;
-@@ -70,13 +50,19 @@
- {
- #ifndef CONFIG_BLK_DEV_IDEPCI
- hw_regs_t hw;
-- int index;
-
-- for (index = 0; index < MAX_HWIFS; index++) {
-- ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
-- hw.irq = ide_default_irq(ide_default_io_base(index));
-- ide_register_hw(&hw, NULL);
-- }
-+ ide_init_hwif_ports(&hw, 0x1f0, 0x3f6, NULL);
-+ hw.irq = 14;
-+ ide_register_hw(&hw, NULL);
-+ ide_init_hwif_ports(&hw, 0x170, 0x376, NULL);
-+ hw.irq = 15;
-+ ide_register_hw(&hw, NULL);
-+ ide_init_hwif_ports(&hw, 0x1e8, 0x3ee, NULL);
-+ hw.irq = 11;
-+ ide_register_hw(&hw, NULL);
-+ ide_init_hwif_ports(&hw, 0x168, 0x36e, NULL);
-+ hw.irq = 10;
-+ ide_register_hw(&hw, NULL);
- #endif /* CONFIG_BLK_DEV_IDEPCI */
- }
-
---- linux-2.4.25/include/asm-alpha/param.h~2.4.25-vrs2.patch 2000-11-08 08:37:31.000000000 +0100
-+++ linux-2.4.25/include/asm-alpha/param.h 2004-03-31 17:15:09.000000000 +0200
-@@ -13,6 +13,9 @@
- # else
- # define HZ 1200
- # endif
-+#ifdef __KERNEL__
-+# define hz_to_std(a) (a)
-+#endif
- #endif
-
- #define EXEC_PAGESIZE 8192
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-at91rm9200/AT91RM9200_MCI.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,127 @@
-+// ----------------------------------------------------------------------------
-+// ATMEL Microcontroller Software Support - ROUSSET -
-+// ----------------------------------------------------------------------------
-+// The software is delivered "AS IS" without warranty or condition of any
-+// kind, either express, implied or statutory. This includes without
-+// limitation any warranty or condition with respect to merchantability or
-+// fitness for any particular purpose, or against the infringements of
-+// intellectual property rights of others.
-+// ----------------------------------------------------------------------------
-+// File Name : AT91RM9200.h
-+// Object : AT91RM9200 / MCI definitions
-+// Generated : AT91 SW Application Group 12/03/2002 (10:48:02)
-+//
-+// ----------------------------------------------------------------------------
-+
-+#ifndef AT91RM9200_MCI_H
-+#define AT91RM9200_MCI_H
-+
-+// *****************************************************************************
-+// SOFTWARE API DEFINITION FOR Multimedia Card Interface
-+// *****************************************************************************
-+#ifndef __ASSEMBLY__
-+
-+typedef struct _AT91S_MCI {
-+ AT91_REG MCI_CR; // MCI Control Register
-+ AT91_REG MCI_MR; // MCI Mode Register
-+ AT91_REG MCI_DTOR; // MCI Data Timeout Register
-+ AT91_REG MCI_SDCR; // MCI SD Card Register
-+ AT91_REG MCI_ARGR; // MCI Argument Register
-+ AT91_REG MCI_CMDR; // MCI Command Register
-+ AT91_REG Reserved0[2]; //
-+ AT91_REG MCI_RSPR[4]; // MCI Response Register
-+ AT91_REG MCI_RDR; // MCI Receive Data Register
-+ AT91_REG MCI_TDR; // MCI Transmit Data Register
-+ AT91_REG Reserved1[2]; //
-+ AT91_REG MCI_SR; // MCI Status Register
-+ AT91_REG MCI_IER; // MCI Interrupt Enable Register
-+ AT91_REG MCI_IDR; // MCI Interrupt Disable Register
-+ AT91_REG MCI_IMR; // MCI Interrupt Mask Register
-+ AT91_REG Reserved2[44]; //
-+ AT91_REG MCI_RPR; // Receive Pointer Register
-+ AT91_REG MCI_RCR; // Receive Counter Register
-+ AT91_REG MCI_TPR; // Transmit Pointer Register
-+ AT91_REG MCI_TCR; // Transmit Counter Register
-+ AT91_REG MCI_RNPR; // Receive Next Pointer Register
-+ AT91_REG MCI_RNCR; // Receive Next Counter Register
-+ AT91_REG MCI_TNPR; // Transmit Next Pointer Register
-+ AT91_REG MCI_TNCR; // Transmit Next Counter Register
-+ AT91_REG MCI_PTCR; // PDC Transfer Control Register
-+ AT91_REG MCI_PTSR; // PDC Transfer Status Register
-+} AT91S_MCI, *AT91PS_MCI;
-+
-+#endif
-+
-+// -------- MCI_CR : (MCI Offset: 0x0) MCI Control Register --------
-+#define AT91C_MCI_MCIEN ((unsigned int) 0x1 << 0) // (MCI) Multimedia Interface Enable
-+#define AT91C_MCI_MCIDIS ((unsigned int) 0x1 << 1) // (MCI) Multimedia Interface Disable
-+#define AT91C_MCI_PWSEN ((unsigned int) 0x1 << 2) // (MCI) Power Save Mode Enable
-+#define AT91C_MCI_PWSDIS ((unsigned int) 0x1 << 3) // (MCI) Power Save Mode Disable
-+// -------- MCI_MR : (MCI Offset: 0x4) MCI Mode Register --------
-+#define AT91C_MCI_CLKDIV ((unsigned int) 0x1 << 0) // (MCI) Clock Divider
-+#define AT91C_MCI_PWSDIV ((unsigned int) 0x1 << 8) // (MCI) Power Saving Divider
-+#define AT91C_MCI_PDCPADV ((unsigned int) 0x1 << 14) // (MCI) PDC Padding Value
-+#define AT91C_MCI_PDCMODE ((unsigned int) 0x1 << 15) // (MCI) PDC Oriented Mode
-+#define AT91C_MCI_BLKLEN ((unsigned int) 0x1 << 18) // (MCI) Data Block Length
-+// -------- MCI_DTOR : (MCI Offset: 0x8) MCI Data Timeout Register --------
-+#define AT91C_MCI_DTOCYC ((unsigned int) 0x1 << 0) // (MCI) Data Timeout Cycle Number
-+#define AT91C_MCI_DTOMUL ((unsigned int) 0x7 << 4) // (MCI) Data Timeout Multiplier
-+#define AT91C_MCI_DTOMUL_1 ((unsigned int) 0x0 << 4) // (MCI) DTOCYC x 1
-+#define AT91C_MCI_DTOMUL_16 ((unsigned int) 0x1 << 4) // (MCI) DTOCYC x 16
-+#define AT91C_MCI_DTOMUL_128 ((unsigned int) 0x2 << 4) // (MCI) DTOCYC x 128
-+#define AT91C_MCI_DTOMUL_256 ((unsigned int) 0x3 << 4) // (MCI) DTOCYC x 256
-+#define AT91C_MCI_DTOMUL_1024 ((unsigned int) 0x4 << 4) // (MCI) DTOCYC x 1024
-+#define AT91C_MCI_DTOMUL_4096 ((unsigned int) 0x5 << 4) // (MCI) DTOCYC x 4096
-+#define AT91C_MCI_DTOMUL_65536 ((unsigned int) 0x6 << 4) // (MCI) DTOCYC x 65536
-+#define AT91C_MCI_DTOMUL_1048576 ((unsigned int) 0x7 << 4) // (MCI) DTOCYC x 1048576
-+// -------- MCI_SDCR : (MCI Offset: 0xc) MCI SD Card Register --------
-+#define AT91C_MCI_SCDSEL ((unsigned int) 0x1 << 0) // (MCI) SD Card Selector
-+#define AT91C_MCI_SCDBUS ((unsigned int) 0x1 << 7) // (MCI) SD Card Bus Width
-+// -------- MCI_CMDR : (MCI Offset: 0x14) MCI Command Register --------
-+#define AT91C_MCI_CMDNB ((unsigned int) 0x1F << 0) // (MCI) Command Number
-+#define AT91C_MCI_RSPTYP ((unsigned int) 0x3 << 6) // (MCI) Response Type
-+#define AT91C_MCI_RSPTYP_NO ((unsigned int) 0x0 << 6) // (MCI) No response
-+#define AT91C_MCI_RSPTYP_48 ((unsigned int) 0x1 << 6) // (MCI) 48-bit response
-+#define AT91C_MCI_RSPTYP_136 ((unsigned int) 0x2 << 6) // (MCI) 136-bit response
-+#define AT91C_MCI_SPCMD ((unsigned int) 0x7 << 8) // (MCI) Special CMD
-+#define AT91C_MCI_SPCMD_NONE ((unsigned int) 0x0 << 8) // (MCI) Not a special CMD
-+#define AT91C_MCI_SPCMD_INIT ((unsigned int) 0x1 << 8) // (MCI) Initialization CMD
-+#define AT91C_MCI_SPCMD_SYNC ((unsigned int) 0x2 << 8) // (MCI) Synchronized CMD
-+#define AT91C_MCI_SPCMD_IT_CMD ((unsigned int) 0x4 << 8) // (MCI) Interrupt command
-+#define AT91C_MCI_SPCMD_IT_REP ((unsigned int) 0x5 << 8) // (MCI) Interrupt response
-+#define AT91C_MCI_OPDCMD ((unsigned int) 0x1 << 11) // (MCI) Open Drain Command
-+#define AT91C_MCI_MAXLAT ((unsigned int) 0x1 << 12) // (MCI) Maximum Latency for Command to respond
-+#define AT91C_MCI_TRCMD ((unsigned int) 0x3 << 16) // (MCI) Transfer CMD
-+#define AT91C_MCI_TRCMD_NO ((unsigned int) 0x0 << 16) // (MCI) No transfer
-+#define AT91C_MCI_TRCMD_START ((unsigned int) 0x1 << 16) // (MCI) Start transfer
-+#define AT91C_MCI_TRCMD_STOP ((unsigned int) 0x2 << 16) // (MCI) Stop transfer
-+#define AT91C_MCI_TRDIR ((unsigned int) 0x1 << 18) // (MCI) Transfer Direction
-+#define AT91C_MCI_TRTYP ((unsigned int) 0x3 << 19) // (MCI) Transfer Type
-+#define AT91C_MCI_TRTYP_BLOCK ((unsigned int) 0x0 << 19) // (MCI) Block Transfer type
-+#define AT91C_MCI_TRTYP_MULTIPLE ((unsigned int) 0x1 << 19) // (MCI) Multiple Block transfer type
-+#define AT91C_MCI_TRTYP_STREAM ((unsigned int) 0x2 << 19) // (MCI) Stream transfer type
-+// -------- MCI_SR : (MCI Offset: 0x40) MCI Status Register --------
-+#define AT91C_MCI_CMDRDY ((unsigned int) 0x1 << 0) // (MCI) Command Ready flag
-+#define AT91C_MCI_RXRDY ((unsigned int) 0x1 << 1) // (MCI) RX Ready flag
-+#define AT91C_MCI_TXRDY ((unsigned int) 0x1 << 2) // (MCI) TX Ready flag
-+#define AT91C_MCI_BLKE ((unsigned int) 0x1 << 3) // (MCI) Data Block Transfer Ended flag
-+#define AT91C_MCI_DTIP ((unsigned int) 0x1 << 4) // (MCI) Data Transfer in Progress flag
-+#define AT91C_MCI_NOTBUSY ((unsigned int) 0x1 << 5) // (MCI) Data Line Not Busy flag
-+#define AT91C_MCI_ENDRX ((unsigned int) 0x1 << 6) // (MCI) End of RX Buffer flag
-+#define AT91C_MCI_ENDTX ((unsigned int) 0x1 << 7) // (MCI) End of TX Buffer flag
-+#define AT91C_MCI_RXBUFF ((unsigned int) 0x1 << 14) // (MCI) RX Buffer Full flag
-+#define AT91C_MCI_TXBUFE ((unsigned int) 0x1 << 15) // (MCI) TX Buffer Empty flag
-+#define AT91C_MCI_RINDE ((unsigned int) 0x1 << 16) // (MCI) Response Index Error flag
-+#define AT91C_MCI_RDIRE ((unsigned int) 0x1 << 17) // (MCI) Response Direction Error flag
-+#define AT91C_MCI_RCRCE ((unsigned int) 0x1 << 18) // (MCI) Response CRC Error flag
-+#define AT91C_MCI_RENDE ((unsigned int) 0x1 << 19) // (MCI) Response End Bit Error flag
-+#define AT91C_MCI_RTOE ((unsigned int) 0x1 << 20) // (MCI) Response Time-out Error flag
-+#define AT91C_MCI_DCRCE ((unsigned int) 0x1 << 21) // (MCI) data CRC Error flag
-+#define AT91C_MCI_DTOE ((unsigned int) 0x1 << 22) // (MCI) Data timeout Error flag
-+#define AT91C_MCI_OVRE ((unsigned int) 0x1 << 30) // (MCI) Overrun flag
-+#define AT91C_MCI_UNRE ((unsigned int) 0x1 << 31) // (MCI) Underrun flag
-+// -------- MCI_IER : (MCI Offset: 0x44) MCI Interrupt Enable Register --------
-+// -------- MCI_IDR : (MCI Offset: 0x48) MCI Interrupt Disable Register --------
-+// -------- MCI_IMR : (MCI Offset: 0x4c) MCI Interrupt Mask Register --------
-+
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-at91rm9200/AT91RM9200_SSC.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,129 @@
-+// ----------------------------------------------------------------------------
-+// ATMEL Microcontroller Software Support - ROUSSET -
-+// ----------------------------------------------------------------------------
-+// The software is delivered "AS IS" without warranty or condition of any
-+// kind, either express, implied or statutory. This includes without
-+// limitation any warranty or condition with respect to merchantability or
-+// fitness for any particular purpose, or against the infringements of
-+// intellectual property rights of others.
-+// ----------------------------------------------------------------------------
-+// File Name : AT91RM9200.h
-+// Object : AT91RM9200 / SSC definitions
-+// Generated : AT91 SW Application Group 12/03/2002 (10:48:02)
-+//
-+// ----------------------------------------------------------------------------
-+
-+#ifndef AT91RM9200_SSC_H
-+#define AT91RM9200_SSC_H
-+
-+// *****************************************************************************
-+// SOFTWARE API DEFINITION FOR Synchronous Serial Controller Interface
-+// *****************************************************************************
-+#ifndef __ASSEMBLY__
-+
-+typedef struct _AT91S_SSC {
-+ AT91_REG SSC_CR; // Control Register
-+ AT91_REG SSC_CMR; // Clock Mode Register
-+ AT91_REG Reserved0[2]; //
-+ AT91_REG SSC_RCMR; // Receive Clock ModeRegister
-+ AT91_REG SSC_RFMR; // Receive Frame Mode Register
-+ AT91_REG SSC_TCMR; // Transmit Clock Mode Register
-+ AT91_REG SSC_TFMR; // Transmit Frame Mode Register
-+ AT91_REG SSC_RHR; // Receive Holding Register
-+ AT91_REG SSC_THR; // Transmit Holding Register
-+ AT91_REG Reserved1[2]; //
-+ AT91_REG SSC_RSHR; // Receive Sync Holding Register
-+ AT91_REG SSC_TSHR; // Transmit Sync Holding Register
-+ AT91_REG SSC_RC0R; // Receive Compare 0 Register
-+ AT91_REG SSC_RC1R; // Receive Compare 1 Register
-+ AT91_REG SSC_SR; // Status Register
-+ AT91_REG SSC_IER; // Interrupt Enable Register
-+ AT91_REG SSC_IDR; // Interrupt Disable Register
-+ AT91_REG SSC_IMR; // Interrupt Mask Register
-+ AT91_REG Reserved2[44]; //
-+ AT91_REG SSC_RPR; // Receive Pointer Register
-+ AT91_REG SSC_RCR; // Receive Counter Register
-+ AT91_REG SSC_TPR; // Transmit Pointer Register
-+ AT91_REG SSC_TCR; // Transmit Counter Register
-+ AT91_REG SSC_RNPR; // Receive Next Pointer Register
-+ AT91_REG SSC_RNCR; // Receive Next Counter Register
-+ AT91_REG SSC_TNPR; // Transmit Next Pointer Register
-+ AT91_REG SSC_TNCR; // Transmit Next Counter Register
-+ AT91_REG SSC_PTCR; // PDC Transfer Control Register
-+ AT91_REG SSC_PTSR; // PDC Transfer Status Register
-+} AT91S_SSC, *AT91PS_SSC;
-+
-+#endif
-+
-+// -------- SSC_CR : (SSC Offset: 0x0) SSC Control Register --------
-+#define AT91C_SSC_RXEN ( 0x1 << 0) // (SSC) Receive Enable
-+#define AT91C_SSC_RXDIS ( 0x1 << 1) // (SSC) Receive Disable
-+#define AT91C_SSC_TXEN ( 0x1 << 8) // (SSC) Transmit Enable
-+#define AT91C_SSC_TXDIS ( 0x1 << 9) // (SSC) Transmit Disable
-+#define AT91C_SSC_SWRST ( 0x1 << 15) // (SSC) Software Reset
-+// -------- SSC_RCMR : (SSC Offset: 0x10) SSC Receive Clock Mode Register --------
-+#define AT91C_SSC_CKS ( 0x3 << 0) // (SSC) Receive/Transmit Clock Selection
-+#define AT91C_SSC_CKS_DIV ( 0x0) // (SSC) Divided Clock
-+#define AT91C_SSC_CKS_TK ( 0x1) // (SSC) TK Clock signal
-+#define AT91C_SSC_CKS_RK ( 0x2) // (SSC) RK pin
-+#define AT91C_SSC_CKO ( 0x7 << 2) // (SSC) Receive/Transmit Clock Output Mode Selection
-+#define AT91C_SSC_CKO_NONE ( 0x0 << 2) // (SSC) Receive/Transmit Clock Output Mode: None RK pin: Input-only
-+#define AT91C_SSC_CKO_CONTINOUS ( 0x1 << 2) // (SSC) Continuous Receive/Transmit Clock RK pin: Output
-+#define AT91C_SSC_CKO_DATA_TX ( 0x2 << 2) // (SSC) Receive/Transmit Clock only during data transfers RK pin: Output
-+#define AT91C_SSC_CKI ( 0x1 << 5) // (SSC) Receive/Transmit Clock Inversion
-+#define AT91C_SSC_CKG ( 0x3 << 6) // (SSC) Receive/Transmit Clock Gating Selection
-+#define AT91C_SSC_CKG_NONE ( 0x0 << 6) // (SSC) Receive/Transmit Clock Gating: None, continuous clock
-+#define AT91C_SSC_CKG_LOW ( 0x1 << 6) // (SSC) Receive/Transmit Clock enabled only if RF Low
-+#define AT91C_SSC_CKG_HIGH ( 0x2 << 6) // (SSC) Receive/Transmit Clock enabled only if RF High
-+#define AT91C_SSC_START ( 0xF << 8) // (SSC) Receive/Transmit Start Selection
-+#define AT91C_SSC_START_CONTINOUS ( 0x0 << 8) // (SSC) Continuous, as soon as the receiver is enabled, and immediately after the end of transfer of the previous data.
-+#define AT91C_SSC_START_TX ( 0x1 << 8) // (SSC) Transmit/Receive start
-+#define AT91C_SSC_START_LOW_RF ( 0x2 << 8) // (SSC) Detection of a low level on RF input
-+#define AT91C_SSC_START_HIGH_RF ( 0x3 << 8) // (SSC) Detection of a high level on RF input
-+#define AT91C_SSC_START_FALL_RF ( 0x4 << 8) // (SSC) Detection of a falling edge on RF input
-+#define AT91C_SSC_START_RISE_RF ( 0x5 << 8) // (SSC) Detection of a rising edge on RF input
-+#define AT91C_SSC_START_LEVEL_RF ( 0x6 << 8) // (SSC) Detection of any level change on RF input
-+#define AT91C_SSC_START_EDGE_RF ( 0x7 << 8) // (SSC) Detection of any edge on RF input
-+#define AT91C_SSC_START_0 ( 0x8 << 8) // (SSC) Compare 0
-+#define AT91C_SSC_STOP ( 0x1 << 12) // (SSC) Receive Stop Selection
-+#define AT91C_SSC_STTOUT ( 0x1 << 15) // (SSC) Receive/Transmit Start Output Selection
-+#define AT91C_SSC_STTDLY ( 0xFF << 16) // (SSC) Receive/Transmit Start Delay
-+#define AT91C_SSC_PERIOD ( 0xFF << 24) // (SSC) Receive/Transmit Period Divider Selection
-+// -------- SSC_RFMR : (SSC Offset: 0x14) SSC Receive Frame Mode Register --------
-+#define AT91C_SSC_DATLEN ( 0x1F << 0) // (SSC) Data Length
-+#define AT91C_SSC_LOOP ( 0x1 << 5) // (SSC) Loop Mode
-+#define AT91C_SSC_MSBF ( 0x1 << 7) // (SSC) Most Significant Bit First
-+#define AT91C_SSC_DATNB ( 0xF << 8) // (SSC) Data Number per Frame
-+#define AT91C_SSC_FSLEN ( 0xF << 16) // (SSC) Receive/Transmit Frame Sync length
-+#define AT91C_SSC_FSOS ( 0x7 << 20) // (SSC) Receive/Transmit Frame Sync Output Selection
-+#define AT91C_SSC_FSOS_NONE ( 0x0 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: None RK pin Input-only
-+#define AT91C_SSC_FSOS_NEGATIVE ( 0x1 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Negative Pulse
-+#define AT91C_SSC_FSOS_POSITIVE ( 0x2 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Positive Pulse
-+#define AT91C_SSC_FSOS_LOW ( 0x3 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver Low during data transfer
-+#define AT91C_SSC_FSOS_HIGH ( 0x4 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Driver High during data transfer
-+#define AT91C_SSC_FSOS_TOGGLE ( 0x5 << 20) // (SSC) Selected Receive/Transmit Frame Sync Signal: Toggling at each start of data transfer
-+#define AT91C_SSC_FSEDGE ( 0x1 << 24) // (SSC) Frame Sync Edge Detection
-+// -------- SSC_TCMR : (SSC Offset: 0x18) SSC Transmit Clock Mode Register --------
-+// -------- SSC_TFMR : (SSC Offset: 0x1c) SSC Transmit Frame Mode Register --------
-+#define AT91C_SSC_DATDEF ( 0x1 << 5) // (SSC) Data Default Value
-+#define AT91C_SSC_FSDEN ( 0x1 << 23) // (SSC) Frame Sync Data Enable
-+// -------- SSC_SR : (SSC Offset: 0x40) SSC Status Register --------
-+#define AT91C_SSC_TXRDY ( 0x1 << 0) // (SSC) Transmit Ready
-+#define AT91C_SSC_TXEMPTY ( 0x1 << 1) // (SSC) Transmit Empty
-+#define AT91C_SSC_ENDTX ( 0x1 << 2) // (SSC) End Of Transmission
-+#define AT91C_SSC_TXBUFE ( 0x1 << 3) // (SSC) Transmit Buffer Empty
-+#define AT91C_SSC_RXRDY ( 0x1 << 4) // (SSC) Receive Ready
-+#define AT91C_SSC_OVRUN ( 0x1 << 5) // (SSC) Receive Overrun
-+#define AT91C_SSC_ENDRX ( 0x1 << 6) // (SSC) End of Reception
-+#define AT91C_SSC_RXBUFF ( 0x1 << 7) // (SSC) Receive Buffer Full
-+#define AT91C_SSC_CP0 ( 0x1 << 8) // (SSC) Compare 0
-+#define AT91C_SSC_CP1 ( 0x1 << 9) // (SSC) Compare 1
-+#define AT91C_SSC_TXSYN ( 0x1 << 10) // (SSC) Transmit Sync
-+#define AT91C_SSC_RXSYN ( 0x1 << 11) // (SSC) Receive Sync
-+#define AT91C_SSC_TXENA ( 0x1 << 16) // (SSC) Transmit Enable
-+#define AT91C_SSC_RXENA ( 0x1 << 17) // (SSC) Receive Enable
-+// -------- SSC_IER : (SSC Offset: 0x44) SSC Interrupt Enable Register --------
-+// -------- SSC_IDR : (SSC Offset: 0x48) SSC Interrupt Disable Register --------
-+// -------- SSC_IMR : (SSC Offset: 0x4c) SSC Interrupt Mask Register --------
-+
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-at91rm9200/AT91RM9200_TC.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,165 @@
-+// ----------------------------------------------------------------------------
-+// ATMEL Microcontroller Software Support - ROUSSET -
-+// ----------------------------------------------------------------------------
-+// The software is delivered "AS IS" without warranty or condition of any
-+// kind, either express, implied or statutory. This includes without
-+// limitation any warranty or condition with respect to merchantability or
-+// fitness for any particular purpose, or against the infringements of
-+// intellectual property rights of others.
-+// ----------------------------------------------------------------------------
-+// File Name : AT91RM9200.h
-+// Object : AT91RM9200 definitions
-+// Generated : AT91 SW Application Group 12/03/2002 (10:48:02)
-+//
-+// ----------------------------------------------------------------------------
-+
-+#ifndef AT91RM9200_TC_H
-+#define AT91RM9200_TC_H
-+
-+// *****************************************************************************
-+// SOFTWARE API DEFINITION FOR Timer Counter Channel Interface
-+// *****************************************************************************
-+#ifndef __ASSEMBLY__
-+
-+typedef struct _AT91S_TC {
-+ AT91_REG TC_CCR; // Channel Control Register
-+ AT91_REG TC_CMR; // Channel Mode Register
-+ AT91_REG Reserved0[2]; //
-+ AT91_REG TC_CV; // Counter Value
-+ AT91_REG TC_RA; // Register A
-+ AT91_REG TC_RB; // Register B
-+ AT91_REG TC_RC; // Register C
-+ AT91_REG TC_SR; // Status Register
-+ AT91_REG TC_IER; // Interrupt Enable Register
-+ AT91_REG TC_IDR; // Interrupt Disable Register
-+ AT91_REG TC_IMR; // Interrupt Mask Register
-+} AT91S_TC, *AT91PS_TC;
-+
-+typedef struct _AT91S_TCB {
-+ AT91S_TC TCB_TC0; // TC Channel 0
-+ AT91_REG Reserved0[4]; //
-+ AT91S_TC TCB_TC1; // TC Channel 1
-+ AT91_REG Reserved1[4]; //
-+ AT91S_TC TCB_TC2; // TC Channel 2
-+ AT91_REG Reserved2[4]; //
-+ AT91_REG TCB_BCR; // TC Block Control Register
-+ AT91_REG TCB_BMR; // TC Block Mode Register
-+} AT91S_TCB, *AT91PS_TCB;
-+
-+#endif
-+
-+// -------- TC_CCR : (TC Offset: 0x0) TC Channel Control Register --------
-+#define AT91C_TC_CLKEN ( 0x1 << 0) // (TC) Counter Clock Enable Command
-+#define AT91C_TC_CLKDIS ( 0x1 << 1) // (TC) Counter Clock Disable Command
-+#define AT91C_TC_SWTRG ( 0x1 << 2) // (TC) Software Trigger Command
-+// -------- TC_CMR : (TC Offset: 0x4) TC Channel Mode Register: Capture Mode / Waveform Mode --------
-+#define AT91C_TC_TCCLKS ( 0x7 << 0) // (TC) Clock Selection
-+#define AT91C_TC_TIMER_DIV1_CLOCK ( 0x0 << 0) // (TC) MCK/2
-+#define AT91C_TC_TIMER_DIV2_CLOCK ( 0x1 << 0) // (TC) MCK/8
-+#define AT91C_TC_TIMER_DIV3_CLOCK ( 0x2 << 0) // (TC) MCK/32
-+#define AT91C_TC_TIMER_DIV4_CLOCK ( 0x3 << 0) // (TC) MCK/128
-+#define AT91C_TC_TIMER_DIV5_CLOCK ( 0x4 << 0) // (TC) MCK/256 = SLOW CLOCK
-+#define AT91C_TC_TIMER_XC0 ( 0x5 << 0) // (TC) XC0
-+#define AT91C_TC_TIMER_XC1 ( 0x6 << 0) // (TC) XC1
-+#define AT91C_TC_TIMER_XC2 ( 0x7 << 0) // (TC) XC2
-+#define AT91C_TC_CLKI ( 0x1 << 3) // (TC) Clock Invert
-+#define AT91C_TC_BURST ( 0x3 << 4) // (TC) Burst Signal Selection
-+#define AT91C_TC_CPCSTOP ( 0x1 << 6) // (TC) Counter Clock Stopped with RC Compare
-+#define AT91C_TC_CPCDIS ( 0x1 << 7) // (TC) Counter Clock Disable with RC Compare
-+#define AT91C_TC_EEVTEDG ( 0x3 << 8) // (TC) External Event Edge Selection
-+#define AT91C_TC_EEVTEDG_NONE ( 0x0 << 8) // (TC) Edge: None
-+#define AT91C_TC_EEVTEDG_RISING ( 0x1 << 8) // (TC) Edge: rising edge
-+#define AT91C_TC_EEVTEDG_FALLING ( 0x2 << 8) // (TC) Edge: falling edge
-+#define AT91C_TC_EEVTEDG_BOTH ( 0x3 << 8) // (TC) Edge: each edge
-+#define AT91C_TC_EEVT ( 0x3 << 10) // (TC) External Event Selection
-+#define AT91C_TC_EEVT_NONE ( 0x0 << 10) // (TC) Signal selected as external event: TIOB TIOB direction: input
-+#define AT91C_TC_EEVT_RISING ( 0x1 << 10) // (TC) Signal selected as external event: XC0 TIOB direction: output
-+#define AT91C_TC_EEVT_FALLING ( 0x2 << 10) // (TC) Signal selected as external event: XC1 TIOB direction: output
-+#define AT91C_TC_EEVT_BOTH ( 0x3 << 10) // (TC) Signal selected as external event: XC2 TIOB direction: output
-+#define AT91C_TC_ENETRG ( 0x1 << 12) // (TC) External Event Trigger enable
-+#define AT91C_TC_WAVESEL ( 0x3 << 13) // (TC) Waveform Selection
-+#define AT91C_TC_WAVESEL_UP ( 0x0 << 13) // (TC) UP mode without atomatic trigger on RC Compare
-+#define AT91C_TC_WAVESEL_UP_AUTO ( 0x1 << 13) // (TC) UP mode with automatic trigger on RC Compare
-+#define AT91C_TC_WAVESEL_UPDOWN ( 0x2 << 13) // (TC) UPDOWN mode without automatic trigger on RC Compare
-+#define AT91C_TC_WAVESEL_UPDOWN_AUTO ( 0x3 << 13) // (TC) UPDOWN mode with automatic trigger on RC Compare
-+#define AT91C_TC_CPCTRG ( 0x1 << 14) // (TC) RC Compare Trigger Enable
-+#define AT91C_TC_WAVE ( 0x1 << 15) // (TC)
-+#define AT91C_TC_ACPA ( 0x3 << 16) // (TC) RA Compare Effect on TIOA
-+#define AT91C_TC_ACPA_NONE ( 0x0 << 16) // (TC) Effect: none
-+#define AT91C_TC_ACPA_SET ( 0x1 << 16) // (TC) Effect: set
-+#define AT91C_TC_ACPA_CLEAR ( 0x2 << 16) // (TC) Effect: clear
-+#define AT91C_TC_ACPA_TOGGLE ( 0x3 << 16) // (TC) Effect: toggle
-+#define AT91C_TC_ACPC ( 0x3 << 18) // (TC) RC Compare Effect on TIOA
-+#define AT91C_TC_ACPC_NONE ( 0x0 << 18) // (TC) Effect: none
-+#define AT91C_TC_ACPC_SET ( 0x1 << 18) // (TC) Effect: set
-+#define AT91C_TC_ACPC_CLEAR ( 0x2 << 18) // (TC) Effect: clear
-+#define AT91C_TC_ACPC_TOGGLE ( 0x3 << 18) // (TC) Effect: toggle
-+#define AT91C_TC_AEEVT ( 0x3 << 20) // (TC) External Event Effect on TIOA
-+#define AT91C_TC_AEEVT_NONE ( 0x0 << 20) // (TC) Effect: none
-+#define AT91C_TC_AEEVT_SET ( 0x1 << 20) // (TC) Effect: set
-+#define AT91C_TC_AEEVT_CLEAR ( 0x2 << 20) // (TC) Effect: clear
-+#define AT91C_TC_AEEVT_TOGGLE ( 0x3 << 20) // (TC) Effect: toggle
-+#define AT91C_TC_ASWTRG ( 0x3 << 22) // (TC) Software Trigger Effect on TIOA
-+#define AT91C_TC_ASWTRG_NONE ( 0x0 << 22) // (TC) Effect: none
-+#define AT91C_TC_ASWTRG_SET ( 0x1 << 22) // (TC) Effect: set
-+#define AT91C_TC_ASWTRG_CLEAR ( 0x2 << 22) // (TC) Effect: clear
-+#define AT91C_TC_ASWTRG_TOGGLE ( 0x3 << 22) // (TC) Effect: toggle
-+#define AT91C_TC_BCPB ( 0x3 << 24) // (TC) RB Compare Effect on TIOB
-+#define AT91C_TC_BCPB_NONE ( 0x0 << 24) // (TC) Effect: none
-+#define AT91C_TC_BCPB_SET ( 0x1 << 24) // (TC) Effect: set
-+#define AT91C_TC_BCPB_CLEAR ( 0x2 << 24) // (TC) Effect: clear
-+#define AT91C_TC_BCPB_TOGGLE ( 0x3 << 24) // (TC) Effect: toggle
-+#define AT91C_TC_BCPC ( 0x3 << 26) // (TC) RC Compare Effect on TIOB
-+#define AT91C_TC_BCPC_NONE ( 0x0 << 26) // (TC) Effect: none
-+#define AT91C_TC_BCPC_SET ( 0x1 << 26) // (TC) Effect: set
-+#define AT91C_TC_BCPC_CLEAR ( 0x2 << 26) // (TC) Effect: clear
-+#define AT91C_TC_BCPC_TOGGLE ( 0x3 << 26) // (TC) Effect: toggle
-+#define AT91C_TC_BEEVT ( 0x3 << 28) // (TC) External Event Effect on TIOB
-+#define AT91C_TC_BEEVT_NONE ( 0x0 << 28) // (TC) Effect: none
-+#define AT91C_TC_BEEVT_SET ( 0x1 << 28) // (TC) Effect: set
-+#define AT91C_TC_BEEVT_CLEAR ( 0x2 << 28) // (TC) Effect: clear
-+#define AT91C_TC_BEEVT_TOGGLE ( 0x3 << 28) // (TC) Effect: toggle
-+#define AT91C_TC_BSWTRG ( 0x3 << 30) // (TC) Software Trigger Effect on TIOB
-+#define AT91C_TC_BSWTRG_NONE ( 0x0 << 30) // (TC) Effect: none
-+#define AT91C_TC_BSWTRG_SET ( 0x1 << 30) // (TC) Effect: set
-+#define AT91C_TC_BSWTRG_CLEAR ( 0x2 << 30) // (TC) Effect: clear
-+#define AT91C_TC_BSWTRG_TOGGLE ( 0x3 << 30) // (TC) Effect: toggle
-+// -------- TC_SR : (TC Offset: 0x20) TC Channel Status Register --------
-+#define AT91C_TC_COVFS ( 0x1 << 0) // (TC) Counter Overflow
-+#define AT91C_TC_LOVRS ( 0x1 << 1) // (TC) Load Overrun
-+#define AT91C_TC_CPAS ( 0x1 << 2) // (TC) RA Compare
-+#define AT91C_TC_CPBS ( 0x1 << 3) // (TC) RB Compare
-+#define AT91C_TC_CPCS ( 0x1 << 4) // (TC) RC Compare
-+#define AT91C_TC_LDRAS ( 0x1 << 5) // (TC) RA Loading
-+#define AT91C_TC_LDRBS ( 0x1 << 6) // (TC) RB Loading
-+#define AT91C_TC_ETRCS ( 0x1 << 7) // (TC) External Trigger
-+#define AT91C_TC_ETRGS ( 0x1 << 16) // (TC) Clock Enabling
-+#define AT91C_TC_MTIOA ( 0x1 << 17) // (TC) TIOA Mirror
-+#define AT91C_TC_MTIOB ( 0x1 << 18) // (TC) TIOA Mirror
-+// -------- TC_IER : (TC Offset: 0x24) TC Channel Interrupt Enable Register --------
-+// -------- TC_IDR : (TC Offset: 0x28) TC Channel Interrupt Disable Register --------
-+// -------- TC_IMR : (TC Offset: 0x2c) TC Channel Interrupt Mask Register --------
-+
-+// *****************************************************************************
-+// SOFTWARE API DEFINITION FOR Timer Counter Interface
-+// *****************************************************************************
-+// -------- TCB_BCR : (TCB Offset: 0xc0) TC Block Control Register --------
-+#define AT91C_TCB_SYNC ( 0x1 << 0) // (TCB) Synchro Command
-+// -------- TCB_BMR : (TCB Offset: 0xc4) TC Block Mode Register --------
-+#define AT91C_TCB_TC0XC0S ( 0x1 << 0) // (TCB) External Clock Signal 0 Selection
-+#define AT91C_TCB_TC0XC0S_TCLK0 ( 0x0) // (TCB) TCLK0 connected to XC0
-+#define AT91C_TCB_TC0XC0S_NONE ( 0x1) // (TCB) None signal connected to XC0
-+#define AT91C_TCB_TC0XC0S_TIOA1 ( 0x2) // (TCB) TIOA1 connected to XC0
-+#define AT91C_TCB_TC0XC0S_TIOA2 ( 0x3) // (TCB) TIOA2 connected to XC0
-+#define AT91C_TCB_TC1XC1S ( 0x1 << 2) // (TCB) External Clock Signal 1 Selection
-+#define AT91C_TCB_TC1XC1S_TCLK1 ( 0x0 << 2) // (TCB) TCLK1 connected to XC1
-+#define AT91C_TCB_TC1XC1S_NONE ( 0x1 << 2) // (TCB) None signal connected to XC1
-+#define AT91C_TCB_TC1XC1S_TIOA0 ( 0x2 << 2) // (TCB) TIOA0 connected to XC1
-+#define AT91C_TCB_TC1XC1S_TIOA2 ( 0x3 << 2) // (TCB) TIOA2 connected to XC1
-+#define AT91C_TCB_TC2XC2S ( 0x1 << 4) // (TCB) External Clock Signal 2 Selection
-+#define AT91C_TCB_TC2XC2S_TCLK2 ( 0x0 << 4) // (TCB) TCLK2 connected to XC2
-+#define AT91C_TCB_TC2XC2S_NONE ( 0x1 << 4) // (TCB) None signal connected to XC2
-+#define AT91C_TCB_TC2XC2S_TIOA0 ( 0x2 << 4) // (TCB) TIOA0 connected to XC2
-+#define AT91C_TCB_TC2XC2S_TIOA2 ( 0x3 << 4) // (TCB) TIOA2 connected to XC2
-+
-+#endif
---- linux-2.4.25/include/asm-arm/arch-at91rm9200/at91rm9200dk.h~2.4.25-vrs2.patch 2003-08-25 13:44:43.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-at91rm9200/at91rm9200dk.h 2004-03-31 17:15:09.000000000 +0200
-@@ -68,6 +68,7 @@
- #define AT91_SMR_IRQ5 (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Advanced Interrupt Controller (IRQ5)
- #define AT91_SMR_IRQ6 (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Advanced Interrupt Controller (IRQ6)
-
-+#define AT91C_CONSOLE_DEFAULT_BAUDRATE 115200 /* default serial console baud-rate */
-
- /*
- * Serial port configuration.
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-at91rm9200/csb337.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,82 @@
-+/*
-+ * linux/include/asm-arm/arch-at91rm9200/csb337.h
-+ *
-+ * Copyright (c) 2003 Christopher Bahns & David Knickerbocker
-+ * Polaroid Corporation
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ */
-+
-+#ifndef __ASM_ARCH_HARDWARE_CSB337_H
-+#define __ASM_ARCH_HARDWARE_CSB337_H
-+
-+
-+/* AT91RM92000 clocks on CSB337 */
-+#define AT91C_MAIN_CLOCK 184320000
-+#define AT91C_MASTER_CLOCK 46080000 /* peripheral clock (AT91C_MAIN_CLOCK / 4) */
-+#define AT91C_SLOW_CLOCK 32768 /* slow clock */
-+
-+
-+/* FLASH */
-+#define AT91_FLASH_BASE 0x10000000 // NCS0: Flash physical base address
-+
-+/* SDRAM */
-+#define AT91_SDRAM_BASE 0x20000000 // NCS1: SDRAM physical base address
-+
-+/* SmartMedia */
-+#define AT91_SMARTMEDIA_BASE 0x40000000 // NCS3: Smartmedia physical base address
-+
-+/* Multi-Master Memory controller */
-+#define AT91_UHP_BASE 0x00300000 // USB Host controller
-+
-+
-+/* Peripheral interrupt configuration */
-+#define AT91_SMR_FIQ (AT91C_AIC_PRIOR_HIGHEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Advanced Interrupt Controller (FIQ)
-+#define AT91_SMR_SYS (AT91C_AIC_PRIOR_HIGHEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // System Peripheral
-+#define AT91_SMR_PIOA (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Parallel IO Controller A
-+#define AT91_SMR_PIOB (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Parallel IO Controller B
-+#define AT91_SMR_PIOC (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Parallel IO Controller C
-+#define AT91_SMR_PIOD (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Parallel IO Controller D
-+#define AT91_SMR_US0 (AT91C_AIC_PRIOR_6 | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // USART 0
-+#define AT91_SMR_US1 (AT91C_AIC_PRIOR_6 | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // USART 1
-+#define AT91_SMR_US2 (AT91C_AIC_PRIOR_6 | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // USART 2
-+#define AT91_SMR_US3 (AT91C_AIC_PRIOR_6 | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // USART 3
-+#define AT91_SMR_MCI (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Multimedia Card Interface
-+#define AT91_SMR_UDP (AT91C_AIC_PRIOR_4 | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // USB Device Port
-+#define AT91_SMR_TWI (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Two-Wire Interface
-+#define AT91_SMR_SPI (AT91C_AIC_PRIOR_6 | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Serial Peripheral Interface
-+#define AT91_SMR_SSC0 (AT91C_AIC_PRIOR_5 | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Serial Synchronous Controller 0
-+#define AT91_SMR_SSC1 (AT91C_AIC_PRIOR_5 | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Serial Synchronous Controller 1
-+#define AT91_SMR_SSC2 (AT91C_AIC_PRIOR_5 | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Serial Synchronous Controller 2
-+#define AT91_SMR_TC0 (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Timer Counter 0
-+#define AT91_SMR_TC1 (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Timer Counter 1
-+#define AT91_SMR_TC2 (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Timer Counter 2
-+#define AT91_SMR_TC3 (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Timer Counter 3
-+#define AT91_SMR_TC4 (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Timer Counter 4
-+#define AT91_SMR_TC5 (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Timer Counter 5
-+#define AT91_SMR_UHP (AT91C_AIC_PRIOR_3 | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // USB Host port
-+#define AT91_SMR_EMAC (AT91C_AIC_PRIOR_3 | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Ethernet MAC
-+#define AT91_SMR_IRQ0 (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Advanced Interrupt Controller (IRQ0)
-+#define AT91_SMR_IRQ1 (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Advanced Interrupt Controller (IRQ1)
-+#define AT91_SMR_IRQ2 (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Advanced Interrupt Controller (IRQ2)
-+#define AT91_SMR_IRQ3 (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Advanced Interrupt Controller (IRQ3)
-+#define AT91_SMR_IRQ4 (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Advanced Interrupt Controller (IRQ4)
-+#define AT91_SMR_IRQ5 (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Advanced Interrupt Controller (IRQ5)
-+#define AT91_SMR_IRQ6 (AT91C_AIC_PRIOR_LOWEST | AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE) // Advanced Interrupt Controller (IRQ6)
-+
-+
-+#define AT91C_CONSOLE_DEFAULT_BAUDRATE 38400
-+
-+/*
-+ * Serial port configuration.
-+ * 0 .. 3 = USART0 .. USART3
-+ * 4 = DBGU
-+ */
-+#define AT91C_UART_MAP { 4, 1, -1, -1, -1 } /* ttyS0, ..., ttyS4 */
-+#define AT91C_CONSOLE 0 /* ttyS0 */
-+
-+#endif
---- linux-2.4.25/include/asm-arm/arch-at91rm9200/hardware.h~2.4.25-vrs2.patch 2003-08-25 13:44:43.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-at91rm9200/hardware.h 2004-03-31 17:15:09.000000000 +0200
-@@ -82,5 +82,8 @@
- #include <asm/arch/at91rm9200dk.h>
- #endif
-
-+#ifdef CONFIG_MACH_CSB337
-+#include <asm/arch/csb337.h>
-+#endif
-
- #endif
---- linux-2.4.25/include/asm-arm/arch-at91rm9200/pio.h~2.4.25-vrs2.patch 2003-08-25 13:44:43.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-at91rm9200/pio.h 2004-03-31 17:15:09.000000000 +0200
-@@ -66,6 +66,18 @@
- }
-
- /*
-+ * Configure interrupt from Ethernet PHY.
-+ */
-+static inline void AT91_CfgPIO_EMAC_PHY(void) {
-+ AT91_SYS->PMC_PCER = 1 << AT91C_ID_PIOC; /* enable peripheral clock */
-+#ifdef CONFIG_MACH_CSB337
-+ AT91_SYS->PIOC_ODR = AT91C_PIO_PC2;
-+#else
-+ AT91_SYS->PIOC_ODR = AT91C_PIO_PC4;
-+#endif
-+}
-+
-+/*
- * Enable the Two-Wire interface.
- */
- static inline void AT91_CfgPIO_TWI(void) {
---- linux-2.4.25/include/asm-arm/arch-at91rm9200/time.h~2.4.25-vrs2.patch 2003-08-25 13:44:43.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-at91rm9200/time.h 2004-03-31 17:15:09.000000000 +0200
-@@ -27,6 +27,21 @@
- extern unsigned long (*gettimeoffset)(void);
-
- /*
-+ * The ST_CRTR is updated asynchronously to the master clock. It is therefore
-+ * necessary to read it twice (with the same value) to ensure accuracy.
-+ */
-+static inline unsigned long read_CRTR(void) {
-+ unsigned long x1, x2;
-+
-+ do {
-+ x1 = AT91_SYS->ST_CRTR;
-+ x2 = AT91_SYS->ST_CRTR;
-+ } while (x1 != x2);
-+
-+ return x1;
-+}
-+
-+/*
- * Returns number of microseconds since last timer interrupt. Note that interrupts
- * will have been disabled by do_gettimeofday()
- * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy.
-@@ -36,7 +51,7 @@
- {
- unsigned long elapsed;
-
-- elapsed = (AT91_SYS->ST_CRTR - AT91_SYS->ST_RTAR) & AT91C_ST_ALMV;
-+ elapsed = (read_CRTR() - AT91_SYS->ST_RTAR) & AT91C_ST_ALMV;
-
- return (unsigned long)(elapsed * tick) / LATCH;
- }
-@@ -52,7 +67,7 @@
-
- AT91_SYS->ST_RTAR = (AT91_SYS->ST_RTAR + LATCH) & AT91C_ST_ALMV;
-
-- } while (((AT91_SYS->ST_CRTR - AT91_SYS->ST_RTAR) & AT91C_ST_ALMV) >= LATCH);
-+ } while (((read_CRTR() - AT91_SYS->ST_RTAR) & AT91C_ST_ALMV) >= LATCH);
-
- do_profile(regs);
- }
---- linux-2.4.25/include/asm-arm/arch-clps711x/system.h~2.4.25-vrs2.patch 2003-06-13 16:51:38.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-clps711x/system.h 2004-03-31 17:15:09.000000000 +0200
-@@ -28,8 +28,8 @@
- {
- clps_writel(1, HALT);
- __asm__ __volatile__(
-- "mov r0, r0
-- mov r0, r0");
-+ "mov r0, r0\n\t"
-+ "mov r0, r0");
- }
-
- static inline void arch_reset(char mode)
---- linux-2.4.25/include/asm-arm/arch-integrator/uncompress.h~2.4.25-vrs2.patch 2002-08-03 02:39:45.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-integrator/uncompress.h 2004-03-31 17:15:09.000000000 +0200
-@@ -18,6 +18,8 @@
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-+#include <asm/hardware/serial_amba.h>
-+
- #define AMBA_UART_DR (*(volatile unsigned char *)0x16000000)
- #define AMBA_UART_LCRH (*(volatile unsigned char *)0x16000008)
- #define AMBA_UART_LCRM (*(volatile unsigned char *)0x1600000c)
-@@ -30,21 +32,25 @@
- */
- static void puts(const char *s)
- {
-+ /* Do nothing if the UART is not enabled. */
-+ if (!(AMBA_UART_CR & AMBA_UARTCR_UARTEN))
-+ return;
-+
- while (*s) {
-- while (AMBA_UART_FR & (1 << 5))
-+ while (AMBA_UART_FR & AMBA_UARTFR_TXFF)
- barrier();
-
- AMBA_UART_DR = *s;
-
- if (*s == '\n') {
-- while (AMBA_UART_FR & (1 << 5))
-+ while (AMBA_UART_FR & AMBA_UARTFR_TXFF)
- barrier();
-
- AMBA_UART_DR = '\r';
- }
- s++;
- }
-- while (AMBA_UART_FR & (1 << 3));
-+ while (AMBA_UART_FR & AMBA_UARTFR_BUSY);
- }
-
- /*
---- linux-2.4.25/include/asm-arm/arch-riscstation/system.h~2.4.25-vrs2.patch 2003-08-25 13:44:43.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-riscstation/system.h 2004-03-31 17:15:09.000000000 +0200
-@@ -1,5 +1,5 @@
- /*
-- * linux/include/asm-arm/arch-rpc/system.h
-+ * linux/include/asm-arm/arch-riscstation/system.h
- *
- * Copyright (C) 1996-1999 Russell King.
- *
-@@ -18,7 +18,7 @@
-
- static inline void arch_reset(char mode)
- {
-- iomd_writeb(0, IOMD_ROMCR0);
-+ iomd_writeb(0x40, IOMD_ROMCR0);
-
- /*
- * Jump into the ROM
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-s3c2410/S3C2410-clock.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,76 @@
-+/* linux/include/asm-arm/arch-s3c2410/S3C2410-clock.h
-+ *
-+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
-+ * http://www.simtec.co.uk/products/SWLINUX/
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * S3C2410 clock register definitions
-+ *
-+ * Changelog:
-+ * 19-06-2003 BJD Created file
-+ */
-+
-+#ifndef ASMARM_ARCH_S3C2410_CLOCK_H
-+#define ASMARM_ARCH_S3C2410_CLOCK_H
-+
-+#define S3C2410_CLKREG(x) ((x) + S3C2410_VA_CLKPWR)
-+
-+#define S3C2410_PLLVAL(_m,_p,_s) ((_m) << 12 | ((_p) << 4) | ((_s)))
-+
-+#define S3C2410_LOCKTIME S3C2410_CLKREG(0x00)
-+#define S3C2410_MPLLCON S3C2410_CLKREG(0x04)
-+#define S3C2410_UPLLCON S3C2410_CLKREG(0x08)
-+#define S3C2410_CLKCON S3C2410_CLKREG(0x0C)
-+#define S3C2410_CLKSLOW S3C2410_CLKREG(0x10)
-+#define S3C2410_CLKDIVN S3C2410_CLKREG(0x14)
-+
-+#define S3C2410_PLLCON_MDIVSHIFT 12
-+#define S3C2410_PLLCON_PDIVSHIFT 4
-+#define S3C2410_PLLCON_SDIVSHIFT 0
-+#define S3C2410_PLLCON_MDIVMASK ((1<<(1+(19-12)))-1)
-+#define S3C2410_PLLCON_PDIVMASK ((1<<5)-1)
-+#define S3C2410_PLLCON_SDIVMASK 3
-+
-+/* DCLKCON register addresses in gpio.h */
-+
-+#define S3C2410_DCLKCON_DCLK0EN (1<<0)
-+#define S3C2410_DCLKCON_DCLK0_PCLK (0<<1)
-+#define S3C2410_DCLKCON_DCLK0_UCLK (1<<1)
-+#define S3C2410_DCLKCON_DCLK0_DIV(x) (((x) - 1 )<<4)
-+#define S3C2410_DCLKCON_DCLK0_CMP(x) (((x) - 1 )<<8)
-+
-+#define S3C2410_DCLKCON_DCLK1EN (1<<16)
-+#define S3C2410_DCLKCON_DCLK1_PCLK (0<<17)
-+#define S3C2410_DCLKCON_DCLK1_UCLK (1<<17)
-+#define S3C2410_DCLKCON_DCLK1_DIV(x) (((x) - 1) <<20)
-+
-+#define S3C2410_CLKDIVN_PDIVN (1<<0)
-+#define S3C2410_CLKDIVN_HDIVN (1<<1)
-+
-+static inline unsigned int
-+s3c2410_get_pll(int pllval, int baseclk)
-+{
-+ int mdiv, pdiv, sdiv;
-+
-+ mdiv = pllval >> S3C2410_PLLCON_MDIVSHIFT;
-+ pdiv = pllval >> S3C2410_PLLCON_PDIVSHIFT;
-+ sdiv = pllval >> S3C2410_PLLCON_SDIVSHIFT;
-+
-+ mdiv &= S3C2410_PLLCON_MDIVMASK;
-+ pdiv &= S3C2410_PLLCON_PDIVMASK;
-+ sdiv &= S3C2410_PLLCON_SDIVMASK;
-+
-+ return (baseclk * (mdiv + 8)) / ((pdiv + 2) << sdiv);
-+}
-+
-+#endif /* ASMARM_ARCH_S3C2410_CLOCK_H */
-+
-+
-+
-+
-+
-+
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-s3c2410/S3C2410-gpio.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,602 @@
-+/* linux/include/asm-arm/arch-s3c2410/S3C2410-gpio.h
-+ *
-+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
-+ * http://www.simtec.co.uk/products/SWLINUX/
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * S3C2410 GPIO register definitions
-+ *
-+ * Changelog:
-+ * 19-06-2003 BJD Created file
-+ * 23-06-2003 BJD Updated GSTATUS registers
-+ */
-+
-+#ifndef ASMARM_ARCH_S3C2410_GPIO_H
-+#define ASMARM_ARCH_S3C2410_GPIO_H
-+
-+/* configure GPIO ports A..G */
-+
-+#define S3C2410_GPIOREG(x) ((x) + S3C2410_VA_GPIO)
-+
-+/* port A - 22bits, zero in bit X makes pin X output
-+ * 1 makes port special function, this is default
-+*/
-+#define S3C2410_GPACON S3C2410_GPIOREG(0x00)
-+#define S3C2410_GPADAT S3C2410_GPIOREG(0x04)
-+
-+/* 0x08 and 0x0c are reserved */
-+
-+/* GPB is 10 IO pins, each configured by 2 bits each in GPBCON.
-+ * 00 = input, 01 = output, 10=special function, 11=reserved
-+ * bit 0,1 = pin 0, 2,3= pin 1...
-+ *
-+ * CPBUP = pull up resistor control, 1=disabled, 0=enabled
-+*/
-+
-+#define S3C2410_GPBCON S3C2410_GPIOREG(0x10)
-+#define S3C2410_GPBDAT S3C2410_GPIOREG(0x14)
-+#define S3C2410_GPBUP S3C2410_GPIOREG(0x18)
-+
-+/* no i/o pin in port b can have value 3! */
-+
-+#define S3C2410_GPB0_INP (0x00 << 0)
-+#define S3C2410_GPB0_OUTP (0x01 << 0)
-+#define S3C2410_GPB0_TOUT0 (0x02 << 0)
-+
-+#define S3C2410_GPB1_INP (0x00 << 2)
-+#define S3C2410_GPB1_OUTP (0x01 << 2)
-+#define S3C2410_GPB1_TOUT1 (0x02 << 2)
-+
-+#define S3C2410_GPB2_INP (0x00 << 4)
-+#define S3C2410_GPB2_OUTP (0x01 << 4)
-+#define S3C2410_GPB2_TOUT2 (0x02 << 4)
-+
-+#define S3C2410_GPB3_INP (0x00 << 6)
-+#define S3C2410_GPB3_OUTP (0x01 << 6)
-+#define S3C2410_GPB3_TOUT3 (0x02 << 6)
-+
-+#define S3C2410_GPB4_INP (0x00 << 8)
-+#define S3C2410_GPB4_OUTP (0x01 << 8)
-+#define S3C2410_GPB4_TCLK0 (0x02 << 8)
-+#define S3C2410_GPB4_MASK (0x03 << 8)
-+
-+#define S3C2410_GPB5_INP (0x00 << 10)
-+#define S3C2410_GPB5_OUTP (0x01 << 10)
-+#define S3C2410_GPB5_nXBACK (0x02 << 10)
-+
-+#define S3C2410_GPB6_INP (0x00 << 12)
-+#define S3C2410_GPB6_OUTP (0x01 << 12)
-+#define S3C2410_GPB6_nXBREQ (0x02 << 12)
-+
-+#define S3C2410_GPB7_INP (0x00 << 14)
-+#define S3C2410_GPB7_OUTP (0x01 << 14)
-+#define S3C2410_GPB7_nXDACK1 (0x02 << 14)
-+
-+#define S3C2410_GPB8_INP (0x00 << 16)
-+#define S3C2410_GPB8_OUTP (0x01 << 16)
-+#define S3C2410_GPB8_nXDREQ1 (0x02 << 16)
-+
-+#define S3C2410_GPB9_INP (0x00 << 18)
-+#define S3C2410_GPB9_OUTP (0x01 << 18)
-+#define S3C2410_GPB9_nXDACK0 (0x02 << 18)
-+
-+#define S3C2410_GPB10_INP (0x00 << 18)
-+#define S3C2410_GPB10_OUTP (0x01 << 18)
-+#define S3C2410_GPB10_nXDRE0 (0x02 << 18)
-+
-+/* Port C consits of 16 GPIO/Special function
-+ *
-+ * almost identical setup to port b, but the special functions are mostly
-+ * to do with the video system's sync/etc.
-+*/
-+
-+#define S3C2410_GPCCON S3C2410_GPIOREG(0x20)
-+#define S3C2410_GPCDAT S3C2410_GPIOREG(0x24)
-+#define S3C2410_GPCUP S3C2410_GPIOREG(0x28)
-+
-+#define S3C2410_GPC0_INP (0x00 << 0)
-+#define S3C2410_GPC0_OUTP (0x01 << 0)
-+#define S3C2410_GPC0_LEND (0x02 << 0)
-+
-+#define S3C2410_GPC1_INP (0x00 << 2)
-+#define S3C2410_GPC1_OUTP (0x01 << 2)
-+#define S3C2410_GPC1_VCLK (0x02 << 2)
-+
-+#define S3C2410_GPC2_INP (0x00 << 4)
-+#define S3C2410_GPC2_OUTP (0x01 << 4)
-+#define S3C2410_GPC2_VLINE (0x02 << 4)
-+
-+#define S3C2410_GPC3_INP (0x00 << 6)
-+#define S3C2410_GPC3_OUTP (0x01 << 6)
-+#define S3C2410_GPC3_VFRAME (0x02 << 6)
-+
-+#define S3C2410_GPC4_INP (0x00 << 8)
-+#define S3C2410_GPC4_OUTP (0x01 << 8)
-+#define S3C2410_GPC4_VM (0x02 << 8)
-+
-+#define S3C2410_GPC5_INP (0x00 << 10)
-+#define S3C2410_GPC5_OUTP (0x01 << 10)
-+#define S3C2410_GPC5_LCDVF0 (0x02 << 10)
-+
-+#define S3C2410_GPC6_INP (0x00 << 12)
-+#define S3C2410_GPC6_OUTP (0x01 << 12)
-+#define S3C2410_GPC6_LCDVF1 (0x02 << 12)
-+
-+#define S3C2410_GPC7_INP (0x00 << 14)
-+#define S3C2410_GPC7_OUTP (0x01 << 14)
-+#define S3C2410_GPC7_LCDVF2 (0x02 << 14)
-+
-+#define S3C2410_GPC8_INP (0x00 << 16)
-+#define S3C2410_GPC8_OUTP (0x01 << 16)
-+#define S3C2410_GPC8_VD0 (0x02 << 16)
-+
-+#define S3C2410_GPC9_INP (0x00 << 18)
-+#define S3C2410_GPC9_OUTP (0x01 << 18)
-+#define S3C2410_GPC9_VD1 (0x02 << 18)
-+
-+#define S3C2410_GPC10_INP (0x00 << 20)
-+#define S3C2410_GPC10_OUTP (0x01 << 20)
-+#define S3C2410_GPC10_VD2 (0x02 << 20)
-+
-+#define S3C2410_GPC11_INP (0x00 << 22)
-+#define S3C2410_GPC11_OUTP (0x01 << 22)
-+#define S3C2410_GPC11_VD3 (0x02 << 22)
-+
-+#define S3C2410_GPC12_INP (0x00 << 24)
-+#define S3C2410_GPC12_OUTP (0x01 << 24)
-+#define S3C2410_GPC12_VD4 (0x02 << 24)
-+
-+#define S3C2410_GPC13_INP (0x00 << 26)
-+#define S3C2410_GPC13_OUTP (0x01 << 26)
-+#define S3C2410_GPC13_VD5 (0x02 << 26)
-+
-+#define S3C2410_GPC14_INP (0x00 << 28)
-+#define S3C2410_GPC14_OUTP (0x01 << 28)
-+#define S3C2410_GPC14_VD6 (0x02 << 28)
-+
-+#define S3C2410_GPC15_INP (0x00 << 30)
-+#define S3C2410_GPC15_OUTP (0x01 << 30)
-+#define S3C2410_GPC15_VD7 (0x02 << 30)
-+
-+/* Port D consists of 16 GPIO/Special function
-+ *
-+ * almost identical setup to port b, but the special functions are mostly
-+ * to do with the video system's data.
-+*/
-+
-+#define S3C2410_GPDCON S3C2410_GPIOREG(0x30)
-+#define S3C2410_GPDDAT S3C2410_GPIOREG(0x34)
-+#define S3C2410_GPDUP S3C2410_GPIOREG(0x38)
-+
-+#define S3C2410_GPD0_INP (0x00 << 0)
-+#define S3C2410_GPD0_OUTP (0x01 << 0)
-+#define S3C2410_GPD0_VD8 (0x02 << 0)
-+
-+#define S3C2410_GPD1_INP (0x00 << 2)
-+#define S3C2410_GPD1_OUTP (0x01 << 2)
-+#define S3C2410_GPD1_VD9 (0x02 << 2)
-+
-+#define S3C2410_GPD2_INP (0x00 << 4)
-+#define S3C2410_GPD2_OUTP (0x01 << 4)
-+#define S3C2410_GPD2_VD10 (0x02 << 4)
-+
-+#define S3C2410_GPD3_INP (0x00 << 6)
-+#define S3C2410_GPD3_OUTP (0x01 << 6)
-+#define S3C2410_GPD3_VD11 (0x02 << 6)
-+
-+#define S3C2410_GPD4_INP (0x00 << 8)
-+#define S3C2410_GPD4_OUTP (0x01 << 8)
-+#define S3C2410_GPD4_VD12 (0x02 << 8)
-+
-+#define S3C2410_GPD5_INP (0x00 << 10)
-+#define S3C2410_GPD5_OUTP (0x01 << 10)
-+#define S3C2410_GPD5_VD13 (0x02 << 10)
-+
-+#define S3C2410_GPD6_INP (0x00 << 12)
-+#define S3C2410_GPD6_OUTP (0x01 << 12)
-+#define S3C2410_GPD6_VD14 (0x02 << 12)
-+
-+#define S3C2410_GPD7_INP (0x00 << 14)
-+#define S3C2410_GPD7_OUTP (0x01 << 14)
-+#define S3C2410_GPD7_VD15 (0x02 << 14)
-+
-+#define S3C2410_GPD8_INP (0x00 << 16)
-+#define S3C2410_GPD8_OUTP (0x01 << 16)
-+#define S3C2410_GPD8_VD16 (0x02 << 16)
-+
-+#define S3C2410_GPD9_INP (0x00 << 18)
-+#define S3C2410_GPD9_OUTP (0x01 << 18)
-+#define S3C2410_GPD9_VD17 (0x02 << 18)
-+
-+#define S3C2410_GPD10_INP (0x00 << 20)
-+#define S3C2410_GPD10_OUTP (0x01 << 20)
-+#define S3C2410_GPD10_VD18 (0x02 << 20)
-+
-+#define S3C2410_GPD11_INP (0x00 << 22)
-+#define S3C2410_GPD11_OUTP (0x01 << 22)
-+#define S3C2410_GPD11_VD19 (0x02 << 22)
-+
-+#define S3C2410_GPD12_INP (0x00 << 24)
-+#define S3C2410_GPD12_OUTP (0x01 << 24)
-+#define S3C2410_GPD12_VD20 (0x02 << 24)
-+
-+#define S3C2410_GPD13_INP (0x00 << 26)
-+#define S3C2410_GPD13_OUTP (0x01 << 26)
-+#define S3C2410_GPD13_VD21 (0x02 << 26)
-+
-+#define S3C2410_GPD14_INP (0x00 << 28)
-+#define S3C2410_GPD14_OUTP (0x01 << 28)
-+#define S3C2410_GPD14_VD22 (0x02 << 28)
-+
-+#define S3C2410_GPD15_INP (0x00 << 30)
-+#define S3C2410_GPD15_OUTP (0x01 << 30)
-+#define S3C2410_GPD15_VD23 (0x02 << 30)
-+
-+/* Port E consists of 16 GPIO/Special function
-+ *
-+ * again, the same as port B, but dealing with I2S, SDI, and
-+ * more miscellaneous functions
-+*/
-+
-+#define S3C2410_GPECON S3C2410_GPIOREG(0x40)
-+#define S3C2410_GPEDAT S3C2410_GPIOREG(0x44)
-+#define S3C2410_GPEUP S3C2410_GPIOREG(0x48)
-+
-+#define S3C2410_GPE0_INP (0x00 << 0)
-+#define S3C2410_GPE0_OUTP (0x01 << 0)
-+#define S3C2410_GPE0_I2SLRCK (0x02 << 0)
-+#define S3C2410_GPE0_MASK (0x03 << 0)
-+
-+#define S3C2410_GPE1_INP (0x00 << 2)
-+#define S3C2410_GPE1_OUTP (0x01 << 2)
-+#define S3C2410_GPE1_I2SSCLK (0x02 << 2)
-+#define S3C2410_GPE1_MASK (0x03 << 2)
-+
-+#define S3C2410_GPE2_INP (0x00 << 4)
-+#define S3C2410_GPE2_OUTP (0x01 << 4)
-+#define S3C2410_GPE2_CDCLK (0x02 << 4)
-+
-+#define S3C2410_GPE3_INP (0x00 << 6)
-+#define S3C2410_GPE3_OUTP (0x01 << 6)
-+#define S3C2410_GPE3_I2SSDI (0x02 << 6)
-+#define S3C2410_GPE3_MASK (0x03 << 6)
-+
-+#define S3C2410_GPE4_INP (0x00 << 8)
-+#define S3C2410_GPE4_OUTP (0x01 << 8)
-+#define S3C2410_GPE4_I2SSDO (0x02 << 8)
-+#define S3C2410_GPE4_MASK (0x03 << 8)
-+
-+#define S3C2410_GPE5_INP (0x00 << 10)
-+#define S3C2410_GPE5_OUTP (0x01 << 10)
-+#define S3C2410_GPE5_SDCLK (0x02 << 10)
-+
-+#define S3C2410_GPE6_INP (0x00 << 12)
-+#define S3C2410_GPE6_OUTP (0x01 << 12)
-+#define S3C2410_GPE6_SDCLK (0x02 << 12)
-+
-+#define S3C2410_GPE7_INP (0x00 << 14)
-+#define S3C2410_GPE7_OUTP (0x01 << 14)
-+#define S3C2410_GPE7_SDCMD (0x02 << 14)
-+
-+#define S3C2410_GPE8_INP (0x00 << 16)
-+#define S3C2410_GPE8_OUTP (0x01 << 16)
-+#define S3C2410_GPE8_SDDAT1 (0x02 << 16)
-+
-+#define S3C2410_GPE9_INP (0x00 << 18)
-+#define S3C2410_GPE9_OUTP (0x01 << 18)
-+#define S3C2410_GPE9_SDDAT2 (0x02 << 18)
-+
-+#define S3C2410_GPE10_INP (0x00 << 20)
-+#define S3C2410_GPE10_OUTP (0x01 << 20)
-+#define S3C2410_GPE10_SDDAT3 (0x02 << 20)
-+
-+#define S3C2410_GPE11_INP (0x00 << 22)
-+#define S3C2410_GPE11_OUTP (0x01 << 22)
-+#define S3C2410_GPE11_SPIMISO0 (0x02 << 22)
-+
-+#define S3C2410_GPE12_INP (0x00 << 24)
-+#define S3C2410_GPE12_OUTP (0x01 << 24)
-+#define S3C2410_GPE12_SPIMOSI0 (0x02 << 24)
-+
-+#define S3C2410_GPE13_INP (0x00 << 26)
-+#define S3C2410_GPE13_OUTP (0x01 << 26)
-+#define S3C2410_GPE13_SPICLK0 (0x02 << 26)
-+
-+#define S3C2410_GPE14_INP (0x00 << 28)
-+#define S3C2410_GPE14_OUTP (0x01 << 28)
-+#define S3C2410_GPE14_IICSCL (0x02 << 28)
-+#define S3C2410_GPE14_MASK (0x03 << 28)
-+
-+#define S3C2410_GPE15_INP (0x00 << 30)
-+#define S3C2410_GPE15_OUTP (0x01 << 30)
-+#define S3C2410_GPE15_IICSDA (0x02 << 30)
-+#define S3C2410_GPE15_MASK (0x03 << 30)
-+
-+#define S3C2410_GPE_PUPDIS(x) (1<<(x))
-+
-+/* Port F consists of 8 GPIO/Special function
-+ *
-+ * GPIO / interrupt inputs
-+ *
-+ * GPFCON has 2 bits for each of the input pins on port F
-+ * 00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 undefined
-+ *
-+ * pull up works like all other ports.
-+*/
-+
-+#define S3C2410_GPFCON S3C2410_GPIOREG(0x50)
-+#define S3C2410_GPFDAT S3C2410_GPIOREG(0x54)
-+#define S3C2410_GPFUP S3C2410_GPIOREG(0x58)
-+
-+
-+#define S3C2410_GPF0_INP (0x00 << 0)
-+#define S3C2410_GPF0_OUTP (0x01 << 0)
-+#define S3C2410_GPF0_EINT0 (0x02 << 0)
-+
-+#define S3C2410_GPF1_INP (0x00 << 2)
-+#define S3C2410_GPF1_OUTP (0x01 << 2)
-+#define S3C2410_GPF1_EINT1 (0x02 << 2)
-+
-+#define S3C2410_GPF2_INP (0x00 << 4)
-+#define S3C2410_GPF2_OUTP (0x01 << 4)
-+#define S3C2410_GPF2_EINT2 (0x02 << 4)
-+
-+#define S3C2410_GPF3_INP (0x00 << 6)
-+#define S3C2410_GPF3_OUTP (0x01 << 6)
-+#define S3C2410_GPF3_EINT3 (0x02 << 6)
-+
-+#define S3C2410_GPF4_INP (0x00 << 8)
-+#define S3C2410_GPF4_OUTP (0x01 << 8)
-+#define S3C2410_GPF4_EINT4 (0x02 << 8)
-+
-+#define S3C2410_GPF5_INP (0x00 << 10)
-+#define S3C2410_GPF5_OUTP (0x01 << 10)
-+#define S3C2410_GPF5_EINT5 (0x02 << 10)
-+
-+#define S3C2410_GPF6_INP (0x00 << 12)
-+#define S3C2410_GPF6_OUTP (0x01 << 12)
-+#define S3C2410_GPF6_EINT6 (0x02 << 12)
-+
-+#define S3C2410_GPF7_INP (0x00 << 14)
-+#define S3C2410_GPF7_OUTP (0x01 << 14)
-+#define S3C2410_GPF7_EINT7 (0x02 << 14)
-+
-+/* Port G consists of 8 GPIO/IRQ/Special function
-+ *
-+ * GPGCON has 2 bits for each of the input pins on port F
-+ * 00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 special func
-+ *
-+ * pull up works like all other ports.
-+*/
-+
-+#define S3C2410_GPGCON S3C2410_GPIOREG(0x60)
-+#define S3C2410_GPGDAT S3C2410_GPIOREG(0x64)
-+#define S3C2410_GPGUP S3C2410_GPIOREG(0x68)
-+
-+#define S3C2410_GPG0_INP (0x00 << 0)
-+#define S3C2410_GPG0_OUTP (0x01 << 0)
-+#define S3C2410_GPG0_EINT8 (0x02 << 0)
-+
-+#define S3C2410_GPG1_INP (0x00 << 2)
-+#define S3C2410_GPG1_OUTP (0x01 << 2)
-+#define S3C2410_GPG1_EINT9 (0x02 << 2)
-+
-+#define S3C2410_GPG2_INP (0x00 << 4)
-+#define S3C2410_GPG2_OUTP (0x01 << 4)
-+#define S3C2410_GPG2_EINT10 (0x02 << 4)
-+
-+#define S3C2410_GPG3_INP (0x00 << 6)
-+#define S3C2410_GPG3_OUTP (0x01 << 6)
-+#define S3C2410_GPG3_EINT11 (0x02 << 6)
-+
-+#define S3C2410_GPG4_INP (0x00 << 8)
-+#define S3C2410_GPG4_OUTP (0x01 << 8)
-+#define S3C2410_GPG4_EINT12 (0x02 << 8)
-+#define S3C2410_GPG4_LCDPWREN (0x03 << 8)
-+
-+#define S3C2410_GPG5_INP (0x00 << 10)
-+#define S3C2410_GPG5_OUTP (0x01 << 10)
-+#define S3C2410_GPG5_EINT13 (0x02 << 10)
-+#define S3C2410_GPG5_SPIMISO1 (0x03 << 10)
-+
-+#define S3C2410_GPG6_INP (0x00 << 12)
-+#define S3C2410_GPG6_OUTP (0x01 << 12)
-+#define S3C2410_GPG6_EINT14 (0x02 << 12)
-+#define S3C2410_GPG6_SPIMOSI1 (0x03 << 12)
-+
-+#define S3C2410_GPG7_INP (0x00 << 14)
-+#define S3C2410_GPG7_OUTP (0x01 << 14)
-+#define S3C2410_GPG7_EINT15 (0x02 << 14)
-+#define S3C2410_GPG7_SPICLK1 (0x03 << 14)
-+
-+#define S3C2410_GPG8_INP (0x00 << 16)
-+#define S3C2410_GPG8_OUTP (0x01 << 16)
-+#define S3C2410_GPG8_EINT16 (0x02 << 16)
-+
-+#define S3C2410_GPG9_INP (0x00 << 18)
-+#define S3C2410_GPG9_OUTP (0x01 << 18)
-+#define S3C2410_GPG9_EINT17 (0x02 << 18)
-+
-+#define S3C2410_GPG10_INP (0x00 << 20)
-+#define S3C2410_GPG10_OUTP (0x01 << 20)
-+#define S3C2410_GPG10_EINT18 (0x02 << 20)
-+
-+#define S3C2410_GPG11_INP (0x00 << 22)
-+#define S3C2410_GPG11_OUTP (0x01 << 22)
-+#define S3C2410_GPG11_EINT19 (0x02 << 22)
-+#define S3C2410_GPG11_TCLK1 (0x03 << 22)
-+
-+#define S3C2410_GPG12_INP (0x00 << 24)
-+#define S3C2410_GPG12_OUTP (0x01 << 24)
-+#define S3C2410_GPG12_EINT18 (0x02 << 24)
-+#define S3C2410_GPG12_XMON (0x03 << 24)
-+
-+#define S3C2410_GPG13_INP (0x00 << 26)
-+#define S3C2410_GPG13_OUTP (0x01 << 26)
-+#define S3C2410_GPG13_EINT18 (0x02 << 26)
-+#define S3C2410_GPG13_nXPON (0x03 << 26)
-+
-+#define S3C2410_GPG14_INP (0x00 << 28)
-+#define S3C2410_GPG14_OUTP (0x01 << 28)
-+#define S3C2410_GPG14_EINT18 (0x02 << 28)
-+#define S3C2410_GPG14_YMON (0x03 << 28)
-+
-+#define S3C2410_GPG15_INP (0x00 << 30)
-+#define S3C2410_GPG15_OUTP (0x01 << 30)
-+#define S3C2410_GPG15_EINT18 (0x02 << 30)
-+#define S3C2410_GPG15_nYPON (0x03 << 30)
-+
-+
-+#define S3C2410_GPG_PUPDIS(x) (1<<(x))
-+
-+/* Port H consists of11 GPIO/serial/Misc pins
-+ *
-+ * GPGCON has 2 bits for each of the input pins on port F
-+ * 00 = 0 input, 1 output, 2 interrupt (EINT0..7), 3 special func
-+ *
-+ * pull up works like all other ports.
-+*/
-+
-+#define S3C2410_GPHCON S3C2410_GPIOREG(0x70)
-+#define S3C2410_GPHDAT S3C2410_GPIOREG(0x74)
-+#define S3C2410_GPHUP S3C2410_GPIOREG(0x78)
-+
-+#define S3C2410_GPH0_INP (0x00 << 0)
-+#define S3C2410_GPH0_OUTP (0x01 << 0)
-+#define S3C2410_GPH0_nCTS0 (0x02 << 0)
-+
-+#define S3C2410_GPH1_INP (0x00 << 2)
-+#define S3C2410_GPH1_OUTP (0x01 << 2)
-+#define S3C2410_GPH1_nRTS0 (0x02 << 2)
-+
-+#define S3C2410_GPH2_INP (0x00 << 4)
-+#define S3C2410_GPH2_OUTP (0x01 << 4)
-+#define S3C2410_GPH2_TXD0 (0x02 << 4)
-+
-+#define S3C2410_GPH3_INP (0x00 << 6)
-+#define S3C2410_GPH3_OUTP (0x01 << 6)
-+#define S3C2410_GPH3_RXD0 (0x02 << 6)
-+
-+#define S3C2410_GPH4_INP (0x00 << 8)
-+#define S3C2410_GPH4_OUTP (0x01 << 8)
-+#define S3C2410_GPH4_TXD1 (0x02 << 8)
-+
-+#define S3C2410_GPH5_INP (0x00 << 10)
-+#define S3C2410_GPH5_OUTP (0x01 << 10)
-+#define S3C2410_GPH5_RXD1 (0x02 << 10)
-+
-+#define S3C2410_GPH6_INP (0x00 << 12)
-+#define S3C2410_GPH6_OUTP (0x01 << 12)
-+#define S3C2410_GPH6_TXD2 (0x02 << 12)
-+#define S3C2410_GPH6_nRTS1 (0x03 << 12)
-+
-+#define S3C2410_GPH7_INP (0x00 << 14)
-+#define S3C2410_GPH7_OUTP (0x01 << 14)
-+#define S3C2410_GPH7_RXD2 (0x02 << 14)
-+#define S3C2410_GPH7_nCTS1 (0x03 << 14)
-+
-+#define S3C2410_GPH8_INP (0x00 << 16)
-+#define S3C2410_GPH8_OUTP (0x01 << 16)
-+#define S3C2410_GPH8_UCLK (0x02 << 16)
-+
-+#define S3C2410_GPH9_INP (0x00 << 18)
-+#define S3C2410_GPH9_OUTP (0x01 << 18)
-+#define S3C2410_GPH9_CLKOUT0 (0x02 << 18)
-+
-+#define S3C2410_GPH10_INP (0x00 << 20)
-+#define S3C2410_GPH10_OUTP (0x01 << 20)
-+#define S3C2410_GPH10_CLKOUT1 (0x02 << 20)
-+
-+/* miscellaneous control */
-+
-+#define S3C2410_MISCCR S3C2410_GPIOREG(0x80)
-+#define S3C2410_DCLKCON S3C2410_GPIOREG(0x84)
-+
-+/* see clock.h for dclk definitions */
-+
-+/* pullup control on databus */
-+#define S3C2410_MISCCR_SPUCR_HEN (0)
-+#define S3C2410_MISCCR_SPUCR_HDIS (1<<0)
-+#define S3C2410_MISCCR_SPUCR_LEN (0)
-+#define S3C2410_MISCCR_SPUCR_LDIS (1<<1)
-+
-+#define S3C2410_MISCCR_USBDEV (0)
-+#define S3C2410_MISCCR_USBHOST (1<<3)
-+
-+#define S3C2410_MISCCR_CLK0_MPLL (0<<4)
-+#define S3C2410_MISCCR_CLK0_UPLL (1<<4)
-+#define S3C2410_MISCCR_CLK0_FCLK (2<<4)
-+#define S3C2410_MISCCR_CLK0_HCLK (3<<4)
-+#define S3C2410_MISCCR_CLK0_PCLK (4<<4)
-+#define S3C2410_MISCCR_CLK0_DCLK0 (5<<4)
-+
-+#define S3C2410_MISCCR_CLK1_MPLL (0<<8)
-+#define S3C2410_MISCCR_CLK1_UPLL (1<<8)
-+#define S3C2410_MISCCR_CLK1_FCLK (2<<8)
-+#define S3C2410_MISCCR_CLK1_HCLK (3<<8)
-+#define S3C2410_MISCCR_CLK1_PCLK (4<<8)
-+#define S3C2410_MISCCR_CLK1_DCLK1 (5<<8)
-+
-+#define S3C2410_MISCCR_USBSUSPND0 (1<<12)
-+#define S3C2410_MISCCR_USBSUSPND1 (1<<13)
-+
-+#define S3C2410_MISCCR_nRSTCON (1<<16)
-+
-+/* external interrupt control... */
-+/* S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7
-+ * S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15
-+ * S3C2410_EXTINT2 -> irq sense control for EINT16..EINT23
-+ *
-+ * note S3C2410_EXTINT2 has filtering options for EINT16..EINT23
-+ *
-+ * Samsung datasheet p9-25
-+*/
-+
-+#define S3C2410_EXTINT0 S3C2410_GPIOREG(0x88)
-+#define S3C2410_EXTINT1 S3C2410_GPIOREG(0x8C)
-+#define S3C2410_EXTINT2 S3C2410_GPIOREG(0x90)
-+
-+/* values for S3C2410_EXTINT0/1/2 */
-+#define S3C2410_EXTINT_LOWLEV (0x00)
-+#define S3C2410_EXTINT_HILEV (0x01)
-+#define S3C2410_EXTINT_FALLEDGE (0x02)
-+#define S3C2410_EXTINT_RISEEDGE (0x04)
-+#define S3C2410_EXTINT_BOTHEDGE (0x06)
-+
-+/* interrupt filtering conrrol for EINT16..EINT23 */
-+#define S3C2410_EINFLT0 S3C2410_GPIOREG(0x94)
-+#define S3C2410_EINFLT1 S3C2410_GPIOREG(0x98)
-+#define S3C2410_EINFLT2 S3C2410_GPIOREG(0x9C)
-+#define S3C2410_EINFLT3 S3C2410_GPIOREG(0xA0)
-+
-+/* mask: 0=enable, 1=disable
-+ * 1 bit EINT, 4=EINT4, 23=EINT23
-+ * EINT0,1,2,3 are not handled here.
-+*/
-+#define S3C2410_EINTMASK S3C2410_GPIOREG(0xA4)
-+#define S3C2410_EINTPEND S3C2410_GPIOREG(0xA8)
-+
-+/* GSTATUS have miscellaneous information in them
-+ *
-+ */
-+
-+#define S3C2410_GSTATUS0 S3C2410_GPIOREG(0x0AC)
-+#define S3C2410_GSTATUS1 S3C2410_GPIOREG(0x0B0)
-+#define S3C2410_GSTATUS2 S3C2410_GPIOREG(0x0B4)
-+#define S3C2410_GSTATUS3 S3C2410_GPIOREG(0x0B8)
-+#define S3C2410_GSTATUS4 S3C2410_GPIOREG(0x0BC)
-+
-+#define S3C2410_GSTATUS0_nWAIT (1<<3)
-+#define S3C2410_GSTATUS0_NCON (1<<2)
-+#define S3C2410_GSTATUS0_RnB (1<<1)
-+#define S3C2410_GSTATUS0_nBATTFLT (1<<0)
-+
-+#define S3C2410_GSTATUS2_WTRESET (1<<2)
-+#define S3C2410_GSTATUs2_OFFRESET (1<<1)
-+#define S3C2410_GSTATUS2_PONRESET (1<<0)
-+
-+#endif /* ASMARM_ARCH_S3C2410_GPIO_H */
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-s3c2410/S3C2410-iis.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,61 @@
-+/* linux/include/asm/hardware/s3c2410/iis.h
-+ *
-+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
-+ * http://www.simtec.co.uk/products/SWLINUX/
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * S3C2410 IIS register definition
-+ *
-+ * Changelog:
-+ * 19-06-2003 BJD Created file
-+ * 26-06-2003 BJD Finished off definitions for register addresses
-+ */
-+
-+#ifndef ASMARM_ARCH_S3C2410_IIS_H
-+#define ASMARM_ARCH_S3C2410_IIS_H
-+
-+#define S3C2410_IISCON (S3C2410_VA_IIS + 0x00)
-+
-+#define S3C2410_IISCON_LRINDEX (1<<8)
-+#define S3C2410_IISCON_TXFIFORDY (1<<7)
-+#define S3C2410_IISCON_RXFIFORDY (1<<6)
-+#define S3C2410_IISCON_TXDMAEN (1<<5)
-+#define S3C2410_IISCON_RXDMAEN (1<<4)
-+#define S3C2410_IISCON_TXIDLE (1<<3)
-+#define S3C2410_IISCON_RXIDLE (1<<2)
-+#define S3C2410_IISCON_IISEN (1<<0)
-+
-+#define S3C2410_IISMOD (S3C2410_VA_IIS + 0x04)
-+
-+#define S3C2410_IISMOD_SLAVE (1<<8)
-+#define S3C2410_IISMOD_NOXFER (0<<6)
-+#define S3C2410_IISMOD_RXMODE (1<<6)
-+#define S3C2410_IISMOD_TXMODE (2<<6)
-+#define S3C2410_IISMOD_TXRXMODE (3<<6)
-+#define S3C2410_IISMOD_LR_LLOW (0<<5)
-+#define S3C2410_IISMOD_LR_RLOW (1<<5)
-+#define S3C2410_IISMOD_IIS (0<<4)
-+#define S3C2410_IISMOD_MSB (1<<4)
-+#define S3C2410_IISMOD_8BIT (0<<3)
-+#define S3C2410_IISMOD_16BIT (1<<3)
-+#define S3C2410_IISMOD_256FS (0<<1)
-+#define S3C2410_IISMOD_384FS (1<<1)
-+#define S3C2410_IISMOD_16FS (0<<0)
-+#define S3C2410_IISMOD_32FS (1<<0)
-+#define S3C2410_IISMOD_48FS (2<<0)
-+
-+#define S3C2410_IISPSR (S3C2410_VA_IIS + 0x08)
-+
-+#define S3C2410_IISFCON (S3C2410_VA_IIS + 0x0c)
-+
-+#define S3C2410_IISFCON_TXDMA (1<<15)
-+#define S3C2410_IISFCON_RXDMA (1<<14)
-+#define S3C2410_IISFCON_TXENABLE (1<<13)
-+#define S3C2410_IISFCON_RXENABLE (1<<12)
-+
-+#define S3C2410_IISFIFO (S3C2410_VA_IIS + 0x10)
-+
-+#endif /* ASMARM_ARCH_S3C2410_IIS_H */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-s3c2410/S3C2410-irq.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,34 @@
-+/* linux/include/asm-arm/arch-s3c2410/S3C2410-irq.h
-+ *
-+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
-+ * http://www.simtec.co.uk/products/SWLINUX/
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Changelog:
-+ * 19-06-2003 BJD Created file
-+ */
-+
-+#ifndef ASMARM_ARCH_S3C2410_IRQ_H
-+#define ASMARM_ARCH_S3C2410_IRQ_H
-+
-+/* interrupt controller */
-+
-+#define S3C2410_IRQREG(x) ((x) + S3C2410_VA_IRQ)
-+#define S3C2410_EINTREG(x) ((x) + S3C2410_VA_GPIO)
-+
-+#define S3C2410_SRCPND S3C2410_IRQREG(0x000)
-+#define S3C2410_INTMOD S3C2410_IRQREG(0x004)
-+#define S3C2410_INTMSK S3C2410_IRQREG(0x008)
-+#define S3C2410_PRIORITY S3C2410_IRQREG(0x00C)
-+#define S3C2410_INTPND S3C2410_IRQREG(0x010)
-+#define S3C2410_INTOFFSET S3C2410_IRQREG(0x014)
-+#define S3C2410_SUBSRCPND S3C2410_IRQREG(0x018)
-+#define S3C2410_INTSUBMSK S3C2410_IRQREG(0x01C)
-+
-+#define S3C2410_EINTMASK S3C2410_EINTREG(0x0A4)
-+#define S3C2410_EINTPEND S3C2410_EINTREG(0X0A8)
-+
-+#endif /* ASMARM_ARCH_S3C2410_IRQ_H */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-s3c2410/S3C2410-lcd.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,107 @@
-+/* linux/include/asm-arm/arch-s3c2410/S3C2410-lcd.h
-+ *
-+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
-+ * http://www.simtec.co.uk/products/SWLINUX/
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ *
-+ *
-+ * Changelog:
-+ * 12-06-2003 BJD Created file
-+ * 26-06-2003 BJD Updated LCDCON register definitions
-+*/
-+
-+#ifndef ASMARM_ARCH_S3C2410_LCD_H
-+#define ASMARM_ARCH_S3C2410_LCD_H
-+
-+#define S3C2410_LCDREG(x) ((x) + S3C2410_VA_LCD)
-+
-+/* LCD control registers */
-+#define S3C2410_LCDCON1 S3C2410_LCDREG(0x00)
-+#define S3C2410_LCDCON2 S3C2410_LCDREG(0x04)
-+#define S3C2410_LCDCON3 S3C2410_LCDREG(0x08)
-+#define S3C2410_LCDCON4 S3C2410_LCDREG(0x0C)
-+#define S3C2410_LCDCON5 S3C2410_LCDREG(0x10)
-+
-+#define S3C2410_LCDCON1_CLKVAL(x) ((x) << 8)
-+#define S3C2410_LCDCON1_MMODE (1<<7)
-+#define S3C2410_LCDCON1_DSCAN4 (0<<5)
-+#define S3C2410_LCDCON1_STN4 (1<<5)
-+#define S3C2410_LCDCON1_STN8 (2<<5)
-+#define S3C2410_LCDCON1_TFT (3<<5)
-+
-+#define S3C2410_LCDCON1_STN1BPP (0<<1)
-+#define S3C2410_LCDCON1_STN2GREY (1<<1)
-+#define S3C2410_LCDCON1_STN4GREY (2<<1)
-+#define S3C2410_LCDCON1_STN8BPP (3<<1)
-+#define S3C2410_LCDCON1_STN12BPP (4<<1)
-+
-+#define S3C2410_LCDCON1_TFT1BPP (8<<1)
-+#define S3C2410_LCDCON1_TFT2BPP (9<<1)
-+#define S3C2410_LCDCON1_TFT4BPP (10<<1)
-+#define S3C2410_LCDCON1_TFT8BPP (11<<1)
-+#define S3C2410_LCDCON1_TFT16BPP (12<<1)
-+#define S3C2410_LCDCON1_TFT24BPP (13<<1)
-+
-+#define S3C2410_LCDCON1_ENVDI (1)
-+
-+#define S3C2410_LCDCON2_VBPD(x) ((x) << 24)
-+#define S3C2410_LCDCON2_LINEVAL(x) ((x) << 14)
-+#define S3C2410_LCDCON2_VFPD(x) ((x) << 6)
-+#define S3C2410_LCDCON2_VSPW(x) ((x) << 0)
-+
-+#define S3C2410_LCDCON3_HBPD(x) ((x) << 19)
-+#define S3C2410_LCDCON3_WDLY(x) ((x) << 19)
-+#define S3C2410_LCDCON3_HOZVAL(x) ((x) << 8)
-+#define S3C2410_LCDCON3_HFPD(x) ((x) << 0)
-+#define S3C2410_LCDCON3_LINEBLANK(x)((x) << 0)
-+
-+#define S3C2410_LCDCON4_MVAL(x) ((x) << 8)
-+#define S3C2410_LCDCON4_HSPW(x) ((x) << 0)
-+#define S3C2410_LCDCON4_WLH(x) ((x) << 0)
-+
-+#define S3C2410_LCDCON5_BPP24BL (1<<12)
-+#define S3C2410_LCDCON5_FRM565 (1<<11)
-+#define S3C2410_LCDCON5_INVVCLK (1<<10)
-+#define S3C2410_LCDCON5_INVVLINE (1<<9)
-+#define S3C2410_LCDCON5_INVVFRAME (1<<8)
-+#define S3C2410_LCDCON5_INVVD (1<<7)
-+#define S3C2410_LCDCON5_INVVSYNC (1<<8)
-+#define S3C2410_LCDCON5_INVHSYNC (1<<9)
-+#define S3C2410_LCDCON5_INVVDEN (1<<6)
-+#define S3C2410_LCDCON5_INVPWREN (1<<5)
-+#define S3C2410_LCDCON5_INVLEND (1<<4)
-+#define S3C2410_LCDCON5_PWREN (1<<3)
-+#define S3C2410_LCDCON5_ENLEND (1<<2)
-+#define S3C2410_LCDCON5_BSWP (1<<1)
-+#define S3C2410_LCDCON5_HWSWP (1<<0)
-+
-+/* framebuffer start addressed */
-+#define S3C2410_LCDSADDR1 S3C2410_LCDREG(0x14)
-+#define S3C2410_LCDSADDR2 S3C2410_LCDREG(0x18)
-+#define S3C2410_LCDSADDR3 S3C2410_LCDREG(0x1C)
-+
-+/* colour lookup and miscellaneous controls */
-+
-+#define S3C2410_REDLUT S3C2410_LCDREG(0x20)
-+#define S3C2410_GREENLUT S3C2410_LCDREG(0x24)
-+#define S3C2410_BLUELUT S3C2410_LCDREG(0x28)
-+
-+#define S3C2410_DITHMODE S3C2410_LCDREG(0x4C)
-+#define S3C2410_TPAL S3C2410_LCDREG(0x50)
-+
-+/* interrupt info */
-+#define S3C2410_LCDINTPND S3C2410_LCDREG(0x54)
-+#define S3C2410_LCDSRCPND S3C2410_LCDREG(0x58)
-+#define S3C2410_LCDINTMSK S3C2410_LCDREG(0x5C)
-+#define S3C2410_LPCSEL S3C2410_LCDREG(0x60)
-+
-+#define S3C2410_TFTPAL(x) S3C2410_LCDREG((0x400 + (x)*4))
-+
-+#endif /* ASMARM_ARCH_S3C2410_LCD_H */
-+
-+
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-s3c2410/S3C2410-rtc.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,61 @@
-+/* linux/include/asm-arm/arch-s3c2410/S3C2410-rtc.h
-+ *
-+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
-+ * http://www.simtec.co.uk/products/SWLINUX/
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * S3C2410 Timer configuration
-+ *
-+ * Changelog:
-+ * 05-06-2003 BJD Created file
-+ */
-+
-+#ifndef ASMARM_ARCH_S3C2410_RTC_H
-+#define ASMARM_ARCH_S3C2410_RTC_H
-+
-+#define S3C2410_RTCREG(x) ((x) + S3C2410_VA_RTC)
-+
-+#define S3C2410_RTCCON S3C2410_RTCREG(0x40)
-+#define S3C2410_RTCCON_RTCEN (1<<0)
-+#define S3C2410_RTCCON_CLKRST (1<<3)
-+
-+#define S3C2410_TICNT S3C2410_RTCREG(0x44)
-+#define S3C2410_TICNT_ENABLE (1<<7)
-+
-+#define S3C2410_RTCALM S3C2410_RTCREG(0x50)
-+#define S3C2410_RTCALM_ALMEN (1<<6)
-+#define S3C2410_RTCALM_YEAREN (1<<5)
-+#define S3C2410_RTCALM_MONEN (1<<4)
-+#define S3C2410_RTCALM_DAYEN (1<<3)
-+#define S3C2410_RTCALM_HOUREN (1<<2)
-+#define S3C2410_RTCALM_MINEN (1<<1)
-+#define S3C2410_RTCALM_SECEN (1<<0)
-+
-+#define S3C2410_RTCALM_ALL \
-+ S3C2410_RTCALM_ALMEN | S3C2410_RTCALM_YEAREN | S3C2410_RTCALM_MONEN |\
-+ S3C2410_RTCALM_DAYEN | S3C2410_RTCALM_HOUREN | S3C2410_RTCALM_MINEN |\
-+ S3C2410_RTCALM_SECEN
-+
-+
-+#define S3C2410_ALMSEC S3C2410_RTCREG(0x54)
-+#define S3C2410_ALMMIN S3C2410_RTCREG(0x58)
-+#define S3C2410_ALMHOUR S3C2410_RTCREG(0x5c)
-+
-+#define S3C2410_ALMDATE S3C2410_RTCREG(0x60)
-+#define S3C2410_ALMMON S3C2410_RTCREG(0x64)
-+#define S3C2410_ALMYEAR S3C2410_RTCREG(0x68)
-+
-+#define S3C2410_RTCRST S3C2410_RTCREG(0x6c)
-+
-+#define S3C2410_RTCSEC S3C2410_RTCREG(0x70)
-+#define S3C2410_RTCMIN S3C2410_RTCREG(0x74)
-+#define S3C2410_RTCHOUR S3C2410_RTCREG(0x78)
-+#define S3C2410_RTCDATE S3C2410_RTCREG(0x7c)
-+#define S3C2410_RTCDAY S3C2410_RTCREG(0x80)
-+#define S3C2410_RTCMON S3C2410_RTCREG(0x84)
-+#define S3C2410_RTCYEAR S3C2410_RTCREG(0x88)
-+
-+#endif /* ASMARM_ARCH_S3C2410_RTC_H */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-s3c2410/S3C2410-serial.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,98 @@
-+/*
-+ * linux/include/asm-arm/arch-s3c2410/S3C2410-serial.h
-+ *
-+ * Internal header file for Samsung S3C2410 serial ports (UART0-2)
-+ *
-+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
-+ *
-+ * Additional defines, (c) 2003 Simtec Electronics (linux@simtec.co.uk)
-+ *
-+ * Adapted from:
-+ *
-+ * Internal header file for MX1ADS serial ports (UART1 & 2)
-+ *
-+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ */
-+
-+#ifndef ASMARM_ARCH_S3C2410_SERIAL_H
-+#define ASMARM_ARCH_S3C2410_SERIAL_H
-+
-+#define S3C2410_UARTRXH0_OFF (0x24)
-+#define S3C2410_UARTTXH0_OFF (0x20)
-+#define S3C2410_UARTLCON_OFF (0x00)
-+#define S3C2410_UARTCON_OFF (0x04)
-+#define S3C2410_UARTFCON_OFF (0x08)
-+#define S3C2410_UARTMCON_OFF (0x0C)
-+#define S3C2410_UARTBRDIV_OFF (0x28)
-+#define S3C2410_UARTTRSTAT_OFF (0x10)
-+#define S3C2410_UARTERSTAT_OFF (0x14)
-+#define S3C2410_UARTFSTAT_OFF (0x18)
-+#define S3C2410_UARTMSTAT_OFF (0x1C)
-+
-+
-+#define S3C2410_UART1_OFF (0x4000)
-+#define S3C2410_UART2_OFF (0x8000)
-+
-+#define S3C2410_LCON_CFGMASK ((0xF<<3)|(0x3))
-+
-+#define S3C2410_LCON_CS5 (0x0)
-+#define S3C2410_LCON_CS6 (0x1)
-+#define S3C2410_LCON_CS7 (0x2)
-+#define S3C2410_LCON_CS8 (0x3)
-+
-+#define S3C2410_LCON_PNONE (0x0)
-+#define S3C2410_LCON_PEVEN ((0x5)<<3)
-+#define S3C2410_LCON_PODD ((0x4)<<3)
-+
-+#define S3C2410_UMCON_AFC (0x10)
-+#define S3C2410_UMCON_RTS (0x1)
-+
-+#define S3C2410_UMSTAT_CTS (0x1)
-+
-+#define S3C2410_UCON_SBREAK (1<<4)
-+
-+#define S3C2410_UCON_TXILEVEL (1<<9)
-+#define S3C2410_UCON_RXILEVEL (1<<8)
-+#define S3C2410_UCON_TXIRQMODE (1<<2)
-+#define S3C2410_UCON_RXIRQMODE (1<<0)
-+#define S3C2410_UCON_RXFIFO_TOI (1<<7)
-+
-+#define S3C2410_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL \
-+ | S3C2410_UCON_TXIRQMODE | S3C2410_UCON_RXIRQMODE \
-+ | S3C2410_UCON_RXFIFO_TOI)
-+
-+#define S3C2410_UFCON_FIFOMODE (1<<0)
-+#define S3C2410_UFCON_TXTRIG0 (0<<6)
-+#define S3C2410_UFCON_RXTRIG8 (1<<4)
-+#define S3C2410_UFCON_RXTRIG12 (2<<4)
-+
-+#define S3C2410_UFCON_RESETBOTH (3<<1)
-+
-+#define S3C2410_UFCON_DEFAULT (S3C2410_UFCON_FIFOMODE | S3C2410_UFCON_TXTRIG0 \
-+ | S3C2410_UFCON_RXTRIG8 )
-+
-+#define S3C2410_UFSTAT_TXFULL (1<<9)
-+#define S3C2410_UFSTAT_RXFULL (1<<8)
-+#define S3C2410_UFSTAT_TXMASK (15<<4)
-+#define S3C2410_UFSTAT_TXSHIFT (4)
-+#define S3C2410_UFSTAT_RXMASK (15<<0)
-+#define S3C2410_UFSTAT_RXSHIFT (0)
-+
-+#define S3C2410_UTRSTAT_TXFE (1<<1)
-+#define S3C2410_UTRSTAT_RXDR (1<<0)
-+
-+#endif /* ASMARM_ARCH_S3C2410_SERIAL_H */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-s3c2410/S3C2410-timer.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,81 @@
-+/* linux/include/asm-arm/arch-s3c2410/S3C2410-timer.h
-+ *
-+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
-+ * http://www.simtec.co.uk/products/SWLINUX/
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * S3C2410 Timer configuration
-+ *
-+ * Changelog:
-+ * 05-06-2003 BJD Created file
-+ * 26-06-2003 BJD Added more timer definitions to mux / control
-+ */
-+
-+#ifndef ASMARM_ARCH_S3C2410_TIMER_H
-+#define ASMARM_ARCH_S3C2410_TIMER_H
-+
-+#define S3C2410_TIMERREG(x) (S3C2410_VA_TIMER + (x))
-+#define S3C2410_TIMERREG2(tmr,reg) S3C2410_TIMERREG((reg)+0x0c+((tmr)*0x0c))
-+
-+#define S3C2410_TCFG0 S3C2410_TIMERREG(0x00)
-+#define S3C2410_TCFG1 S3C2410_TIMERREG(0x04)
-+#define S3C2410_TCON S3C2410_TIMERREG(0x08)
-+
-+
-+#define S3C2410_TCFG1_MUX4_TCLK1 (4<<16)
-+#define S3C2410_TCFG1_MUX4_MASK (15<<16)
-+
-+#define S3C2410_TCFG1_MUX3_TCLK1 (4<<12)
-+#define S3C2410_TCFG1_MUX3_MASK (15<<12)
-+
-+#define S3C2410_TCFG1_MUX2_TCLK1 (4<<8)
-+#define S3C2410_TCFG1_MUX2_MASK (15<<8)
-+
-+#define S3C2410_TCFG1_MUX1_TCLK0 (4<<4)
-+#define S3C2410_TCFG1_MUX1_MASK (15<<4)
-+
-+#define S3C2410_TCFG1_MUX0_TCLK0 (4<<0)
-+#define S3C2410_TCFG1_MUX0_MASK (15<<0)
-+
-+/* for each timer, we have an count buffer, an compare buffer and an
-+ * observation buffer
-+ */
-+
-+/* WARNING - timer 4 has no buffer reg, and it's observation is at +4 */
-+
-+#define S3C2410_TCNTB(tmr) S3C2410_TIMERREG2(tmr, 0x00)
-+#define S3C2410_TCMPB(tmr) S3C2410_TIMERREG2(tmr, 0x04)
-+#define S3C2410_TCNTO(tmr) S3C2410_TIMERREG2(tmr, (((tmr) == 4) ? 0x04 : 0x08))
-+
-+#define S3C2410_TCON_T4RELOAD (1<<22)
-+#define S3C2410_TCON_T4MANUALUPD (1<<21)
-+#define S3C2410_TCON_T4START (1<<20)
-+
-+#define S3C2410_TCON_T3RELOAD (1<<19)
-+#define S3C2410_TCON_T3INVERT (1<<18)
-+#define S3C2410_TCON_T3MANUALUPD (1<<17)
-+#define S3C2410_TCON_T3START (1<<16)
-+
-+#define S3C2410_TCON_T2RELOAD (1<<15)
-+#define S3C2410_TCON_T2INVERT (1<<14)
-+#define S3C2410_TCON_T2MANUALUPD (1<<13)
-+#define S3C2410_TCON_T2START (1<<12)
-+
-+#define S3C2410_TCON_T1RELOAD (1<<11)
-+#define S3C2410_TCON_T1INVERT (1<<10)
-+#define S3C2410_TCON_T1MANUALUPD (1<<9)
-+#define S3C2410_TCON_T1START (1<<8)
-+
-+#define S3C2410_TCON_T0DEADZONE (1<<4)
-+#define S3C2410_TCON_T0RELOAD (1<<3)
-+#define S3C2410_TCON_T0INVERT (1<<2)
-+#define S3C2410_TCON_T0MANUALUPD (1<<1)
-+#define S3C2410_TCON_T0START (1<<0)
-+
-+#endif /* ASMARM_ARCH_S3C2410_TIMER_H */
-+
-+
-+
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/arch-s3c2410/S3C2410-watchdog.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,40 @@
-+/* linux/include/asm-arm/arch-s3c2410/S3C2410-watchdog.h
-+ *
-+ * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk>
-+ * http://www.simtec.co.uk/products/SWLINUX/
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * S3C2410 Watchdog timer control
-+ *
-+ * Changelog:
-+ * 21-06-2003 BJD Created file
-+*/
-+
-+#ifndef ASMARM_ARCH_S3C2410_WATCHDOG_H
-+#define ASMARM_ARCH_S3C2410_WATCHDOG_H
-+
-+#define S3C2410_WDOGREG(x) ((x) + S3C2410_VA_WATCHDOG)
-+
-+#define S3C2410_WTCON S3C2410_WDOGREG(0x00)
-+#define S3C2410_WTDAT S3C2410_WDOGREG(0x04)
-+#define S3C2410_WTCNT S3C2410_WDOGREG(0x08)
-+
-+/* the watchdog can either generate a reset pulse, or an interrupt. */
-+
-+#define S3C2410_WTCON_RSTEN (0x01)
-+#define S3C2410_WTCON_INTEN (1<<2)
-+#define S3C2410_WTCON_ENABLE (1<<5)
-+
-+#define S3C2410_WTCON_DIV16 (0<<3)
-+#define S3C2410_WTCON_DIV32 (1<<3)
-+#define S3C2410_WTCON_DIV64 (2<<3)
-+#define S3C2410_WTCON_DIV128 (3<<3)
-+
-+#define S3C2410_WTCON_PRESCALE(x) ((x) << 8)
-+
-+#endif /* ASMARM_ARCH_S3C2410_WATCHDOG_H */
-+
-+
---- linux-2.4.25/include/asm-arm/bugs.h~2.4.25-vrs2.patch 2000-09-19 00:15:23.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/bugs.h 2004-03-31 17:15:09.000000000 +0200
-@@ -10,8 +10,17 @@
- #ifndef __ASM_BUGS_H
- #define __ASM_BUGS_H
-
-+#include <linux/config.h>
- #include <asm/proc-fns.h>
-
--#define check_bugs() cpu_check_bugs()
-+extern void check_writebuffer_bugs(void);
-+
-+static inline void check_bugs(void)
-+{
-+#ifdef CONFIG_CPU_32
-+ check_writebuffer_bugs();
-+#endif
-+ cpu_check_bugs();
-+}
-
- #endif
---- linux-2.4.25/include/asm-arm/div64.h~2.4.25-vrs2.patch 2000-01-13 22:30:31.000000000 +0100
-+++ linux-2.4.25/include/asm-arm/div64.h 2004-03-31 17:15:09.000000000 +0200
-@@ -4,9 +4,13 @@
- /* We're not 64-bit, but... */
- #define do_div(n,base) \
- ({ \
-- int __res; \
-- __res = ((unsigned long)n) % (unsigned int)base; \
-- n = ((unsigned long)n) / (unsigned int)base; \
-+ register int __res asm("r2") = base; \
-+ register unsigned long long __n asm("r0") = n; \
-+ asm("bl do_div64" \
-+ : "=r" (__n), "=r" (__res) \
-+ : "0" (__n), "1" (__res) \
-+ : "r3", "ip", "lr", "cc"); \
-+ n = __n; \
- __res; \
- })
-
---- linux-2.4.25/include/asm-arm/elf.h~2.4.25-vrs2.patch 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.25/include/asm-arm/elf.h 2004-03-31 17:15:09.000000000 +0200
-@@ -45,8 +45,8 @@
-
- #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
-
--/* When the program starts, a1 contains a pointer to a function to be
-- registered with atexit, as per the SVR4 ABI. A value of 0 means we
-+/* When the program starts, a1 contains a pointer to a function to be
-+ registered with atexit, as per the SVR4 ABI. A value of 0 means we
- have no such handler. */
- #define ELF_PLAT_INIT(_r, load_addr) (_r)->ARM_r0 = 0
-
---- linux-2.4.25/include/asm-arm/mach/dma.h~2.4.25-vrs2.patch 2003-08-25 13:44:43.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/mach/dma.h 2004-03-31 17:15:09.000000000 +0200
-@@ -41,6 +41,7 @@
- unsigned int dma_base; /* Controller base address */
- int dma_irq; /* Controller IRQ */
- struct scatterlist cur_sg; /* Current controller buffer */
-+ unsigned int state; /* RiscPC DMA status */
-
- struct dma_ops *d_ops;
- };
---- linux-2.4.25/include/asm-arm/mach/serial_at91rm9200.h~2.4.25-vrs2.patch 2003-08-25 13:44:43.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/mach/serial_at91rm9200.h 2004-03-31 17:15:09.000000000 +0200
-@@ -10,7 +10,6 @@
- #include <linux/config.h>
-
- struct uart_port;
--struct uart_info;
-
- /*
- * This is a temporary structure for registering these
-@@ -22,11 +21,11 @@
- void (*enable_ms)(struct uart_port *);
- void (*pm)(struct uart_port *, u_int, u_int);
- int (*set_wake)(struct uart_port *, u_int);
-- int (*open)(struct uart_port *, struct uart_info *);
-- void (*close)(struct uart_port *, struct uart_info *);
-+ int (*open)(struct uart_port *);
-+ void (*close)(struct uart_port *);
- };
-
--#if defined(CONFIG_SERIAL_AT91RM9200)
-+#if defined(CONFIG_SERIAL_AT91)
- void at91rm9200_register_uart_fns(struct at91rm9200_port_fns *fns);
- void at91rm9200_register_uart(int idx, int port);
- #else
---- linux-2.4.25/include/asm-arm/proc-armv/processor.h~2.4.25-vrs2.patch 2003-08-25 13:44:43.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/proc-armv/processor.h 2004-03-31 17:15:09.000000000 +0200
-@@ -54,7 +54,9 @@
- regs->ARM_cpsr = USR_MODE; \
- else \
- regs->ARM_cpsr = USR26_MODE; \
-- regs->ARM_pc = pc; /* pc */ \
-+ if (elf_hwcap & HWCAP_THUMB && pc & 1) \
-+ regs->ARM_cpsr |= PSR_T_BIT; \
-+ regs->ARM_pc = pc & ~1; /* pc */ \
- regs->ARM_sp = sp; /* sp */ \
- regs->ARM_r2 = stack[2]; /* r2 (envp) */ \
- regs->ARM_r1 = stack[1]; /* r1 (argv) */ \
---- linux-2.4.25/include/asm-arm/proc-armv/ptrace.h~2.4.25-vrs2.patch 2000-11-28 02:07:59.000000000 +0100
-+++ linux-2.4.25/include/asm-arm/proc-armv/ptrace.h 2004-03-31 17:15:09.000000000 +0200
-@@ -33,6 +33,16 @@
- #define CC_N_BIT (1 << 31)
- #define PCMASK 0
-
-+/* 2.5 versions */
-+#define PSR_T_BIT 0x00000020
-+#define PSR_F_BIT 0x00000040
-+#define PSR_I_BIT 0x00000080
-+#define PSR_J_BIT 0x01000000
-+#define PSR_V_BIT 0x10000000
-+#define PSR_C_BIT 0x20000000
-+#define PSR_Z_BIT 0x40000000
-+#define PSR_N_BIT 0x80000000
-+
- #ifndef __ASSEMBLY__
-
- /* this struct defines the way the registers are stored on the
---- linux-2.4.25/include/asm-arm/proc-armv/uaccess.h~2.4.25-vrs2.patch 2001-10-25 22:53:55.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/proc-armv/uaccess.h 2004-03-31 17:15:09.000000000 +0200
-@@ -12,12 +12,11 @@
- * Note that this is actually 0x1,0000,0000
- */
- #define KERNEL_DS 0x00000000
--#define USER_DS PAGE_OFFSET
-+#define USER_DS TASK_SIZE
-
- static inline void set_fs (mm_segment_t fs)
- {
- current->addr_limit = fs;
--
- modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
- }
-
-@@ -38,7 +37,7 @@
- : "cc"); \
- (flag == 0); })
-
--#define __put_user_asm_byte(x,addr,err) \
-+#define __put_user_asm_byte(x,__pu_addr,err) \
- __asm__ __volatile__( \
- "1: strbt %1,[%2],#0\n" \
- "2:\n" \
-@@ -51,18 +50,18 @@
- " .align 3\n" \
- " .long 1b, 3b\n" \
- " .previous" \
-- : "=r" (err) \
-- : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err))
-+ : "+r" (err) \
-+ : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \
-+ : "cc")
-
--#define __put_user_asm_half(x,addr,err) \
-+#define __put_user_asm_half(x,__pu_addr,err) \
- ({ \
- unsigned long __temp = (unsigned long)(x); \
-- unsigned long __ptr = (unsigned long)(addr); \
-- __put_user_asm_byte(__temp, __ptr, err); \
-- __put_user_asm_byte(__temp >> 8, __ptr + 1, err); \
-+ __put_user_asm_byte(__temp, __pu_addr, err); \
-+ __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err); \
- })
-
--#define __put_user_asm_word(x,addr,err) \
-+#define __put_user_asm_word(x,__pu_addr,err) \
- __asm__ __volatile__( \
- "1: strt %1,[%2],#0\n" \
- "2:\n" \
-@@ -75,8 +74,28 @@
- " .align 3\n" \
- " .long 1b, 3b\n" \
- " .previous" \
-- : "=r" (err) \
-- : "r" (x), "r" (addr), "i" (-EFAULT), "0" (err))
-+ : "+r" (err) \
-+ : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \
-+ : "cc")
-+
-+#define __put_user_asm_dword(x,__pu_addr,err) \
-+ __asm__ __volatile__( \
-+ "1: strt %R2, [%1], #4\n" \
-+ "2: strt %Q2, [%1], #0\n" \
-+ "3:\n" \
-+ " .section .fixup,\"ax\"\n" \
-+ " .align 2\n" \
-+ "4: mov %0, %3\n" \
-+ " b 3b\n" \
-+ " .previous\n" \
-+ " .section __ex_table,\"a\"\n" \
-+ " .align 3\n" \
-+ " .long 1b, 4b\n" \
-+ " .long 2b, 4b\n" \
-+ " .previous" \
-+ : "+r" (err), "+r" (__pu_addr) \
-+ : "r" (x), "i" (-EFAULT) \
-+ : "cc")
-
- #define __get_user_asm_byte(x,addr,err) \
- __asm__ __volatile__( \
-@@ -92,18 +111,18 @@
- " .align 3\n" \
- " .long 1b, 3b\n" \
- " .previous" \
-- : "=r" (err), "=&r" (x) \
-- : "r" (addr), "i" (-EFAULT), "0" (err))
-+ : "+r" (err), "=&r" (x) \
-+ : "r" (addr), "i" (-EFAULT) \
-+ : "cc")
-
--#define __get_user_asm_half(x,addr,err) \
-+#define __get_user_asm_half(x,__gu_addr,err) \
- ({ \
-- unsigned long __b1, __b2, __ptr = (unsigned long)addr; \
-- __get_user_asm_byte(__b1, __ptr, err); \
-- __get_user_asm_byte(__b2, __ptr + 1, err); \
-+ unsigned long __b1, __b2; \
-+ __get_user_asm_byte(__b1, __gu_addr, err); \
-+ __get_user_asm_byte(__b2, __gu_addr + 1, err); \
- (x) = __b1 | (__b2 << 8); \
- })
-
--
- #define __get_user_asm_word(x,addr,err) \
- __asm__ __volatile__( \
- "1: ldrt %1,[%2],#0\n" \
-@@ -118,8 +137,9 @@
- " .align 3\n" \
- " .long 1b, 3b\n" \
- " .previous" \
-- : "=r" (err), "=&r" (x) \
-- : "r" (addr), "i" (-EFAULT), "0" (err))
-+ : "+r" (err), "=&r" (x) \
-+ : "r" (addr), "i" (-EFAULT) \
-+ : "cc")
-
- extern unsigned long __arch_copy_from_user(void *to, const void *from, unsigned long n);
- #define __do_copy_from_user(to,from,n) \
---- linux-2.4.25/include/asm-arm/proc-fns.h~2.4.25-vrs2.patch 2003-08-25 13:44:43.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/proc-fns.h 2004-03-31 17:15:09.000000000 +0200
-@@ -76,6 +76,30 @@
- # define CPU_NAME arm926
- # endif
- # endif
-+# ifdef CONFIG_CPU_ARM1020
-+# ifdef CPU_NAME
-+# undef MULTI_CPU
-+# define MULTI_CPU
-+# else
-+# define CPU_NAME arm1020
-+# endif
-+# endif
-+# ifdef CONFIG_CPU_ARM1020E
-+# ifdef CPU_NAME
-+# undef MULTI_CPU
-+# define MULTI_CPU
-+# else
-+# define CPU_NAME arm1020E
-+# endif
-+# endif
-+# ifdef CONFIG_CPU_ARM1022
-+# ifdef CPU_NAME
-+# undef MULTI_CPU
-+# define MULTI_CPU
-+# else
-+# define CPU_NAME arm1022
-+# endif
-+# endif
- # ifdef CONFIG_CPU_ARM1026
- # ifdef CPU_NAME
- # undef MULTI_CPU
---- linux-2.4.25/include/asm-arm/processor.h~2.4.25-vrs2.patch 2003-08-25 13:44:43.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/processor.h 2004-03-31 17:15:09.000000000 +0200
-@@ -43,6 +43,7 @@
- #include <asm/atomic.h>
- #include <asm/ptrace.h>
- #include <asm/arch/memory.h>
-+#include <asm/elf.h>
- #include <asm/proc/processor.h>
- #include <asm/types.h>
-
---- linux-2.4.25/include/asm-arm/system.h~2.4.25-vrs2.patch 2003-08-25 13:44:43.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/system.h 2004-03-31 17:15:09.000000000 +0200
-@@ -29,6 +29,10 @@
-
- void die_if_kernel(const char *str, struct pt_regs *regs, int err);
-
-+void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
-+ struct pt_regs *),
-+ int sig, const char *name);
-+
- #include <asm/proc-fns.h>
-
- #define xchg(ptr,x) \
-@@ -89,6 +93,14 @@
- #define sti() local_irq_enable()
- #define clf() __clf()
- #define stf() __stf()
-+
-+#define irqs_disabled() \
-+({ \
-+ unsigned long flags; \
-+ local_save_flags(flags); \
-+ flags & PSR_I_BIT; \
-+})
-+
- #define save_flags(x) local_save_flags(x)
- #define restore_flags(x) local_irq_restore(x)
- #define save_flags_cli(x) local_irq_save(x)
---- linux-2.4.25/include/asm-arm/termios.h~2.4.25-vrs2.patch 2001-06-12 04:15:27.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/termios.h 2004-03-31 17:15:09.000000000 +0200
-@@ -47,6 +47,8 @@
- #define TIOCM_OUT2 0x4000
- #define TIOCM_LOOP 0x8000
-
-+#define TIOCM_MODEM_BITS TIOCM_OUT2 /* IRDA support */
-+
- /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
-
- /* line disciplines */
---- linux-2.4.25/include/asm-arm/uaccess.h~2.4.25-vrs2.patch 2001-10-25 22:53:55.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/uaccess.h 2004-03-31 17:15:09.000000000 +0200
-@@ -74,14 +74,14 @@
- __asm__ __volatile__ ("bl __get_user_" #__s \
- : "=&r" (__e), "=r" (__r1) \
- : "0" (__p) \
-- : __i)
-+ : __i, "cc")
-
- #define get_user(x,p) \
- ({ \
- const register typeof(*(p)) *__p asm("r0") = (p); \
- register typeof(*(p)) __r1 asm("r1"); \
- register int __e asm("r0"); \
-- switch (sizeof(*(p))) { \
-+ switch (sizeof(*(__p))) { \
- case 1: \
- __get_user_x(__r1, __p, __e, 1, "lr"); \
- break; \
-@@ -100,8 +100,31 @@
- __e; \
- })
-
--#define __get_user(x,p) __get_user_nocheck((x),(p),sizeof(*(p)))
--#define __get_user_error(x,p,e) __get_user_nocheck_error((x),(p),sizeof(*(p)),(e))
-+#define __get_user(x,ptr) \
-+({ \
-+ long __gu_err = 0; \
-+ __get_user_err((x),(ptr),__gu_err); \
-+ __gu_err; \
-+})
-+
-+#define __get_user_error(x,ptr,err) \
-+({ \
-+ __get_user_err((x),(ptr),err); \
-+ (void) 0; \
-+})
-+
-+#define __get_user_err(x,ptr,err) \
-+do { \
-+ unsigned long __gu_addr = (unsigned long)(ptr); \
-+ unsigned long __gu_val; \
-+ switch (sizeof(*(ptr))) { \
-+ case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \
-+ case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \
-+ case 4: __get_user_asm_word(__gu_val,__gu_addr,err); break; \
-+ default: (__gu_val) = __get_user_bad(); \
-+ } \
-+ (x) = (__typeof__(*(ptr)))__gu_val; \
-+} while (0)
-
- extern int __put_user_1(void *, unsigned int);
- extern int __put_user_2(void *, unsigned int);
-@@ -113,22 +136,22 @@
- __asm__ __volatile__ ("bl __put_user_" #__s \
- : "=&r" (__e) \
- : "0" (__p), "r" (__r1) \
-- : __i)
-+ : __i, "cc")
-
- #define put_user(x,p) \
- ({ \
- const register typeof(*(p)) __r1 asm("r1") = (x); \
- const register typeof(*(p)) *__p asm("r0") = (p); \
- register int __e asm("r0"); \
-- switch (sizeof(*(p))) { \
-+ switch (sizeof(*(__p))) { \
- case 1: \
-- __put_user_x(__r1, __p, __e, 1, "r2", "lr"); \
-+ __put_user_x(__r1, __p, __e, 1, "ip", "lr"); \
- break; \
- case 2: \
-- __put_user_x(__r1, __p, __e, 2, "r2", "lr"); \
-+ __put_user_x(__r1, __p, __e, 2, "ip", "lr"); \
- break; \
- case 4: \
-- __put_user_x(__r1, __p, __e, 4, "r2", "lr"); \
-+ __put_user_x(__r1, __p, __e, 4, "ip", "lr"); \
- break; \
- case 8: \
- __put_user_x(__r1, __p, __e, 8, "ip", "lr"); \
-@@ -138,8 +161,31 @@
- __e; \
- })
-
--#define __put_user(x,p) __put_user_nocheck((__typeof(*(p)))(x),(p),sizeof(*(p)))
--#define __put_user_error(x,p,e) __put_user_nocheck_error((x),(p),sizeof(*(p)),(e))
-+#define __put_user(x,ptr) \
-+({ \
-+ long __pu_err = 0; \
-+ __put_user_err((x),(ptr),__pu_err); \
-+ __pu_err; \
-+})
-+
-+#define __put_user_error(x,ptr,err) \
-+({ \
-+ __put_user_err((x),(ptr),err); \
-+ (void) 0; \
-+})
-+
-+#define __put_user_err(x,ptr,err) \
-+do { \
-+ unsigned long __pu_addr = (unsigned long)(ptr); \
-+ __typeof__(*(ptr)) __pu_val = (x); \
-+ switch (sizeof(*(ptr))) { \
-+ case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \
-+ case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \
-+ case 4: __put_user_asm_word(__pu_val,__pu_addr,err); break; \
-+ case 8: __put_user_asm_dword(__pu_val,__pu_addr,err); break; \
-+ default: __put_user_bad(); \
-+ } \
-+} while (0)
-
- static __inline__ unsigned long copy_from_user(void *to, const void *from, unsigned long n)
- {
-@@ -209,82 +255,4 @@
- return res;
- }
-
--/*
-- * These are the work horses of the get/put_user functions
-- */
--#if 0
--#define __get_user_check(x,ptr,size) \
--({ \
-- long __gu_err = -EFAULT, __gu_val = 0; \
-- const __typeof__(*(ptr)) *__gu_addr = (ptr); \
-- if (access_ok(VERIFY_READ,__gu_addr,size)) { \
-- __gu_err = 0; \
-- __get_user_size(__gu_val,__gu_addr,(size),__gu_err); \
-- } \
-- (x) = (__typeof__(*(ptr)))__gu_val; \
-- __gu_err; \
--})
--#endif
--
--#define __get_user_nocheck(x,ptr,size) \
--({ \
-- long __gu_err = 0, __gu_val; \
-- __get_user_size(__gu_val,(ptr),(size),__gu_err); \
-- (x) = (__typeof__(*(ptr)))__gu_val; \
-- __gu_err; \
--})
--
--#define __get_user_nocheck_error(x,ptr,size,err) \
--({ \
-- long __gu_val; \
-- __get_user_size(__gu_val,(ptr),(size),(err)); \
-- (x) = (__typeof__(*(ptr)))__gu_val; \
-- (void) 0; \
--})
--
--#define __put_user_check(x,ptr,size) \
--({ \
-- long __pu_err = -EFAULT; \
-- __typeof__(*(ptr)) *__pu_addr = (ptr); \
-- if (access_ok(VERIFY_WRITE,__pu_addr,size)) { \
-- __pu_err = 0; \
-- __put_user_size((x),__pu_addr,(size),__pu_err); \
-- } \
-- __pu_err; \
--})
--
--#define __put_user_nocheck(x,ptr,size) \
--({ \
-- long __pu_err = 0; \
-- __typeof__(*(ptr)) *__pu_addr = (ptr); \
-- __put_user_size((x),__pu_addr,(size),__pu_err); \
-- __pu_err; \
--})
--
--#define __put_user_nocheck_error(x,ptr,size,err) \
--({ \
-- __put_user_size((x),(ptr),(size),err); \
-- (void) 0; \
--})
--
--#define __get_user_size(x,ptr,size,retval) \
--do { \
-- switch (size) { \
-- case 1: __get_user_asm_byte(x,ptr,retval); break; \
-- case 2: __get_user_asm_half(x,ptr,retval); break; \
-- case 4: __get_user_asm_word(x,ptr,retval); break; \
-- default: (x) = __get_user_bad(); \
-- } \
--} while (0)
--
--#define __put_user_size(x,ptr,size,retval) \
--do { \
-- switch (size) { \
-- case 1: __put_user_asm_byte(x,ptr,retval); break; \
-- case 2: __put_user_asm_half(x,ptr,retval); break; \
-- case 4: __put_user_asm_word(x,ptr,retval); break; \
-- default: __put_user_bad(); \
-- } \
--} while (0)
--
- #endif /* _ASMARM_UACCESS_H */
---- linux-2.4.25/include/asm-arm/unistd.h~2.4.25-vrs2.patch 2003-08-25 13:44:43.000000000 +0200
-+++ linux-2.4.25/include/asm-arm/unistd.h 2004-03-31 17:15:09.000000000 +0200
-@@ -31,7 +31,7 @@
- #define __NR_write (__NR_SYSCALL_BASE+ 4)
- #define __NR_open (__NR_SYSCALL_BASE+ 5)
- #define __NR_close (__NR_SYSCALL_BASE+ 6)
--#define __NR_waitpid (__NR_SYSCALL_BASE+ 7)
-+ /* 7 was sys_waitpid */
- #define __NR_creat (__NR_SYSCALL_BASE+ 8)
- #define __NR_link (__NR_SYSCALL_BASE+ 9)
- #define __NR_unlink (__NR_SYSCALL_BASE+ 10)
-@@ -41,8 +41,8 @@
- #define __NR_mknod (__NR_SYSCALL_BASE+ 14)
- #define __NR_chmod (__NR_SYSCALL_BASE+ 15)
- #define __NR_lchown (__NR_SYSCALL_BASE+ 16)
--#define __NR_break (__NR_SYSCALL_BASE+ 17)
--
-+ /* 17 was sys_break */
-+ /* 18 was sys_stat */
- #define __NR_lseek (__NR_SYSCALL_BASE+ 19)
- #define __NR_getpid (__NR_SYSCALL_BASE+ 20)
- #define __NR_mount (__NR_SYSCALL_BASE+ 21)
-@@ -52,14 +52,14 @@
- #define __NR_stime (__NR_SYSCALL_BASE+ 25)
- #define __NR_ptrace (__NR_SYSCALL_BASE+ 26)
- #define __NR_alarm (__NR_SYSCALL_BASE+ 27)
--
-+ /* 28 was sys_fstat */
- #define __NR_pause (__NR_SYSCALL_BASE+ 29)
- #define __NR_utime (__NR_SYSCALL_BASE+ 30)
--#define __NR_stty (__NR_SYSCALL_BASE+ 31)
--#define __NR_gtty (__NR_SYSCALL_BASE+ 32)
-+ /* 31 was sys_stty */
-+ /* 32 was sys_gtty */
- #define __NR_access (__NR_SYSCALL_BASE+ 33)
- #define __NR_nice (__NR_SYSCALL_BASE+ 34)
--#define __NR_ftime (__NR_SYSCALL_BASE+ 35)
-+ /* 35 was sys_ftime */
- #define __NR_sync (__NR_SYSCALL_BASE+ 36)
- #define __NR_kill (__NR_SYSCALL_BASE+ 37)
- #define __NR_rename (__NR_SYSCALL_BASE+ 38)
-@@ -68,22 +68,23 @@
- #define __NR_dup (__NR_SYSCALL_BASE+ 41)
- #define __NR_pipe (__NR_SYSCALL_BASE+ 42)
- #define __NR_times (__NR_SYSCALL_BASE+ 43)
--#define __NR_prof (__NR_SYSCALL_BASE+ 44)
-+ /* 44 was sys_prof */
- #define __NR_brk (__NR_SYSCALL_BASE+ 45)
- #define __NR_setgid (__NR_SYSCALL_BASE+ 46)
- #define __NR_getgid (__NR_SYSCALL_BASE+ 47)
--#define __NR_signal (__NR_SYSCALL_BASE+ 48)
-+ /* 48 was sys_signal */
- #define __NR_geteuid (__NR_SYSCALL_BASE+ 49)
- #define __NR_getegid (__NR_SYSCALL_BASE+ 50)
- #define __NR_acct (__NR_SYSCALL_BASE+ 51)
- #define __NR_umount2 (__NR_SYSCALL_BASE+ 52)
--#define __NR_lock (__NR_SYSCALL_BASE+ 53)
-+ /* 53 was sys_lock */
- #define __NR_ioctl (__NR_SYSCALL_BASE+ 54)
- #define __NR_fcntl (__NR_SYSCALL_BASE+ 55)
--#define __NR_mpx (__NR_SYSCALL_BASE+ 56)
-+ /* 56 was sys_mpx */
- #define __NR_setpgid (__NR_SYSCALL_BASE+ 57)
- #define __NR_ulimit (__NR_SYSCALL_BASE+ 58)
--
-+ /* 58 was sys_ulimit */
-+ /* 59 was sys_olduname */
- #define __NR_umask (__NR_SYSCALL_BASE+ 60)
- #define __NR_chroot (__NR_SYSCALL_BASE+ 61)
- #define __NR_ustat (__NR_SYSCALL_BASE+ 62)
-@@ -92,8 +93,8 @@
- #define __NR_getpgrp (__NR_SYSCALL_BASE+ 65)
- #define __NR_setsid (__NR_SYSCALL_BASE+ 66)
- #define __NR_sigaction (__NR_SYSCALL_BASE+ 67)
--#define __NR_sgetmask (__NR_SYSCALL_BASE+ 68)
--#define __NR_ssetmask (__NR_SYSCALL_BASE+ 69)
-+ /* 68 was sys_sgetmask */
-+ /* 69 was sys_ssetmask */
- #define __NR_setreuid (__NR_SYSCALL_BASE+ 70)
- #define __NR_setregid (__NR_SYSCALL_BASE+ 71)
- #define __NR_sigsuspend (__NR_SYSCALL_BASE+ 72)
-@@ -108,7 +109,7 @@
- #define __NR_setgroups (__NR_SYSCALL_BASE+ 81)
- #define __NR_select (__NR_SYSCALL_BASE+ 82)
- #define __NR_symlink (__NR_SYSCALL_BASE+ 83)
--
-+ /* 84 was sys_lstat */
- #define __NR_readlink (__NR_SYSCALL_BASE+ 85)
- #define __NR_uselib (__NR_SYSCALL_BASE+ 86)
- #define __NR_swapon (__NR_SYSCALL_BASE+ 87)
-@@ -122,10 +123,10 @@
- #define __NR_fchown (__NR_SYSCALL_BASE+ 95)
- #define __NR_getpriority (__NR_SYSCALL_BASE+ 96)
- #define __NR_setpriority (__NR_SYSCALL_BASE+ 97)
--#define __NR_profil (__NR_SYSCALL_BASE+ 98)
-+ /* 98 was sys_profil */
- #define __NR_statfs (__NR_SYSCALL_BASE+ 99)
- #define __NR_fstatfs (__NR_SYSCALL_BASE+100)
--#define __NR_ioperm (__NR_SYSCALL_BASE+101)
-+ /* 101 was sys_ioperm */
- #define __NR_socketcall (__NR_SYSCALL_BASE+102)
- #define __NR_syslog (__NR_SYSCALL_BASE+103)
- #define __NR_setitimer (__NR_SYSCALL_BASE+104)
-@@ -133,10 +134,10 @@
- #define __NR_stat (__NR_SYSCALL_BASE+106)
- #define __NR_lstat (__NR_SYSCALL_BASE+107)
- #define __NR_fstat (__NR_SYSCALL_BASE+108)
--
--
-+ /* 109 was sys_uname */
-+ /* 110 was sys_iopl */
- #define __NR_vhangup (__NR_SYSCALL_BASE+111)
--#define __NR_idle (__NR_SYSCALL_BASE+112)
-+ /* 112 was sys_idle */
- #define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */
- #define __NR_wait4 (__NR_SYSCALL_BASE+114)
- #define __NR_swapoff (__NR_SYSCALL_BASE+115)
-@@ -147,7 +148,7 @@
- #define __NR_clone (__NR_SYSCALL_BASE+120)
- #define __NR_setdomainname (__NR_SYSCALL_BASE+121)
- #define __NR_uname (__NR_SYSCALL_BASE+122)
--#define __NR_modify_ldt (__NR_SYSCALL_BASE+123)
-+ /* 123 was sys_modify_ldt */
- #define __NR_adjtimex (__NR_SYSCALL_BASE+124)
- #define __NR_mprotect (__NR_SYSCALL_BASE+125)
- #define __NR_sigprocmask (__NR_SYSCALL_BASE+126)
-@@ -161,7 +162,7 @@
- #define __NR_bdflush (__NR_SYSCALL_BASE+134)
- #define __NR_sysfs (__NR_SYSCALL_BASE+135)
- #define __NR_personality (__NR_SYSCALL_BASE+136)
--#define __NR_afs_syscall (__NR_SYSCALL_BASE+137) /* Syscall for Andrew File System */
-+ /* 137 was sys_afs_syscall */
- #define __NR_setfsuid (__NR_SYSCALL_BASE+138)
- #define __NR_setfsgid (__NR_SYSCALL_BASE+139)
- #define __NR__llseek (__NR_SYSCALL_BASE+140)
-@@ -190,7 +191,7 @@
- #define __NR_mremap (__NR_SYSCALL_BASE+163)
- #define __NR_setresuid (__NR_SYSCALL_BASE+164)
- #define __NR_getresuid (__NR_SYSCALL_BASE+165)
--#define __NR_vm86 (__NR_SYSCALL_BASE+166)
-+ /* 166 was sys_vm86 */
- #define __NR_query_module (__NR_SYSCALL_BASE+167)
- #define __NR_poll (__NR_SYSCALL_BASE+168)
- #define __NR_nfsservctl (__NR_SYSCALL_BASE+169)
---- linux-2.4.25/include/asm-i386/ide.h~2.4.25-vrs2.patch 2003-06-13 16:51:38.000000000 +0200
-+++ linux-2.4.25/include/asm-i386/ide.h 2004-03-31 17:15:09.000000000 +0200
-@@ -23,39 +23,15 @@
- # endif
- #endif
-
--static __inline__ int ide_default_irq(ide_ioreg_t base)
--{
-- switch (base) {
-- case 0x1f0: return 14;
-- case 0x170: return 15;
-- case 0x1e8: return 11;
-- case 0x168: return 10;
-- case 0x1e0: return 8;
-- case 0x160: return 12;
-- default:
-- return 0;
-- }
--}
--
--static __inline__ ide_ioreg_t ide_default_io_base(int index)
--{
-- switch (index) {
-- case 0: return 0x1f0;
-- case 1: return 0x170;
-- case 2: return 0x1e8;
-- case 3: return 0x168;
-- case 4: return 0x1e0;
-- case 5: return 0x160;
-- default:
-- return 0;
-- }
--}
-+#define ide_default_io_base(i) ((ide_ioreg_t)0)
-+#define ide_default_irq(b) (0)
-
- static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
- {
- ide_ioreg_t reg = data_port;
- int i;
-
-+ memset(hw, 0, sizeof(*hw));
- for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
- hw->io_ports[i] = reg;
- reg += 1;
-@@ -63,7 +39,7 @@
- if (ctrl_port) {
- hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
- } else {
-- hw->io_ports[IDE_CONTROL_OFFSET] = hw->io_ports[IDE_DATA_OFFSET] + 0x206;
-+ hw->io_ports[IDE_CONTROL_OFFSET] = data_port + 0x206;
- }
- if (irq != NULL)
- *irq = 0;
-@@ -74,14 +50,25 @@
- {
- #ifndef CONFIG_BLK_DEV_IDEPCI
- hw_regs_t hw;
-- int index;
-
-- for(index = 0; index < MAX_HWIFS; index++) {
-- memset(&hw, 0, sizeof hw);
-- ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
-- hw.irq = ide_default_irq(ide_default_io_base(index));
-- ide_register_hw(&hw, NULL);
-- }
-+ ide_init_hwif_ports(&hw, 0x1f0, 0x3f6, NULL);
-+ hw.irq = 14;
-+ ide_register_hw(&hw, NULL);
-+ ide_init_hwif_ports(&hw, 0x170, 0x376, NULL);
-+ hw.irq = 15;
-+ ide_register_hw(&hw, NULL);
-+ ide_init_hwif_ports(&hw, 0x1e8, 0x3ee, NULL);
-+ hw.irq = 11;
-+ ide_register_hw(&hw, NULL);
-+ ide_init_hwif_ports(&hw, 0x168, 0x36e, NULL);
-+ hw.irq = 10;
-+ ide_register_hw(&hw, NULL);
-+ ide_init_hwif_ports(&hw, 0x1e0, 0x3e6, NULL);
-+ hw.irq = 8;
-+ ide_register_hw(&hw, NULL);
-+ ide_init_hwif_ports(&hw, 0x160, 0x366, NULL);
-+ hw.irq = 12;
-+ ide_register_hw(&hw, NULL);
- #endif /* CONFIG_BLK_DEV_IDEPCI */
- }
-
---- linux-2.4.25/include/asm-i386/param.h~2.4.25-vrs2.patch 2000-10-27 20:04:43.000000000 +0200
-+++ linux-2.4.25/include/asm-i386/param.h 2004-03-31 17:15:09.000000000 +0200
-@@ -3,6 +3,16 @@
-
- #ifndef HZ
- #define HZ 100
-+#ifdef __KERNEL__
-+#if HZ == 100
-+/* X86 is defined to provide userspace with a world where HZ=100
-+ We have to do this, (x*const)/const2 isnt optimised out because its not
-+ a null operation as it might overflow.. */
-+#define hz_to_std(a) (a)
-+#else
-+#define hz_to_std(a) ((a)*(100/HZ)+((a)*(100%HZ))/HZ)
-+#endif
-+#endif
- #endif
-
- #define EXEC_PAGESIZE 4096
---- linux-2.4.25/include/asm-i386/pgtable.h~2.4.25-vrs2.patch 2002-11-29 00:53:15.000000000 +0100
-+++ linux-2.4.25/include/asm-i386/pgtable.h 2004-03-31 17:15:09.000000000 +0200
-@@ -361,7 +361,6 @@
- #endif /* !__ASSEMBLY__ */
-
- /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
--#define PageSkip(page) (0)
- #define kern_addr_valid(addr) (1)
-
- #define io_remap_page_range remap_page_range
---- linux-2.4.25/include/asm-ia64/param.h~2.4.25-vrs2.patch 2004-02-18 14:36:32.000000000 +0100
-+++ linux-2.4.25/include/asm-ia64/param.h 2004-03-31 17:15:09.000000000 +0200
-@@ -8,6 +8,10 @@
- * David Mosberger-Tang <davidm@hpl.hp.com>
- */
-
-+#ifdef __KERNEL__
-+#define hz_to_std(a) (a)
-+#endif
-+
- #define EXEC_PAGESIZE 65536
-
- #ifndef NGROUPS
---- linux-2.4.25/include/asm-m68k/param.h~2.4.25-vrs2.patch 2001-01-04 22:00:55.000000000 +0100
-+++ linux-2.4.25/include/asm-m68k/param.h 2004-03-31 17:15:09.000000000 +0200
-@@ -3,6 +3,9 @@
-
- #ifndef HZ
- #define HZ 100
-+#ifdef __KERNEL__
-+#define hz_to_std(a) (a)
-+#endif
- #endif
-
- #define EXEC_PAGESIZE 8192
---- linux-2.4.25/include/asm-mips/ide.h~2.4.25-vrs2.patch 2003-08-25 13:44:43.000000000 +0200
-+++ linux-2.4.25/include/asm-mips/ide.h 2004-03-31 17:15:09.000000000 +0200
-@@ -27,7 +27,7 @@
- int (*ide_default_irq)(ide_ioreg_t base);
- ide_ioreg_t (*ide_default_io_base)(int index);
- void (*ide_init_hwif_ports)(hw_regs_t *hw, ide_ioreg_t data_port,
-- ide_ioreg_t ctrl_port, int *irq);
-+ ide_ioreg_t ctrl_port, int *irq);
- };
-
- extern struct ide_ops *ide_ops;
---- linux-2.4.25/include/asm-ppc/param.h~2.4.25-vrs2.patch 2003-06-13 16:51:38.000000000 +0200
-+++ linux-2.4.25/include/asm-ppc/param.h 2004-03-31 17:15:09.000000000 +0200
-@@ -3,6 +3,9 @@
-
- #ifndef HZ
- #define HZ 100
-+#ifdef __KERNEL__
-+#define hz_to_std(a) (a)
-+#endif
- #endif
-
- #define EXEC_PAGESIZE 4096
---- linux-2.4.25/include/asm-s390/param.h~2.4.25-vrs2.patch 2001-02-13 23:13:44.000000000 +0100
-+++ linux-2.4.25/include/asm-s390/param.h 2004-03-31 17:15:09.000000000 +0200
-@@ -11,6 +11,9 @@
-
- #ifndef HZ
- #define HZ 100
-+#ifdef __KERNEL__
-+#define hz_to_std(a) (a)
-+#endif
- #endif
-
- #define EXEC_PAGESIZE 4096
---- linux-2.4.25/include/asm-sh/param.h~2.4.25-vrs2.patch 2001-01-04 22:19:13.000000000 +0100
-+++ linux-2.4.25/include/asm-sh/param.h 2004-03-31 17:15:09.000000000 +0200
-@@ -3,6 +3,9 @@
-
- #ifndef HZ
- #define HZ 100
-+#ifdef __KERNEL__
-+#define hz_to_std(a) (a)
-+#endif
- #endif
-
- #define EXEC_PAGESIZE 4096
---- linux-2.4.25/include/asm-sparc/param.h~2.4.25-vrs2.patch 2000-10-30 23:34:12.000000000 +0100
-+++ linux-2.4.25/include/asm-sparc/param.h 2004-03-31 17:15:09.000000000 +0200
-@@ -4,6 +4,9 @@
-
- #ifndef HZ
- #define HZ 100
-+#ifdef __KERNEL__
-+#define hz_to_std(a) (a)
-+#endif
- #endif
-
- #define EXEC_PAGESIZE 8192 /* Thanks for sun4's we carry baggage... */
---- linux-2.4.25/include/asm-sparc64/ide.h~2.4.25-vrs2.patch 2003-06-13 16:51:38.000000000 +0200
-+++ linux-2.4.25/include/asm-sparc64/ide.h 2004-03-31 17:15:09.000000000 +0200
-@@ -25,21 +25,12 @@
- # endif
- #endif
-
--static __inline__ int ide_default_irq(ide_ioreg_t base)
--{
-- return 0;
--}
--
--static __inline__ ide_ioreg_t ide_default_io_base(int index)
--{
-- return 0;
--}
--
- static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
- {
-- ide_ioreg_t reg = data_port;
-+ ide_ioreg_t reg = data_port;
- int i;
-
-+ memset(&hw, 0, sizeof(hw));
- for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
- hw->io_ports[i] = reg;
- reg += 1;
-@@ -60,16 +51,6 @@
- */
- static __inline__ void ide_init_default_hwifs(void)
- {
--#ifndef CONFIG_BLK_DEV_IDEPCI
-- hw_regs_t hw;
-- int index;
--
-- for (index = 0; index < MAX_HWIFS; index++) {
-- ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
-- hw.irq = ide_default_irq(ide_default_io_base(index));
-- ide_register_hw(&hw, NULL);
-- }
--#endif /* CONFIG_BLK_DEV_IDEPCI */
- }
-
- #undef SUPPORT_SLOW_DATA_PORTS
---- linux-2.4.25/include/asm-sparc64/param.h~2.4.25-vrs2.patch 2000-10-30 23:34:12.000000000 +0100
-+++ linux-2.4.25/include/asm-sparc64/param.h 2004-03-31 17:15:09.000000000 +0200
-@@ -4,6 +4,9 @@
-
- #ifndef HZ
- #define HZ 100
-+#ifdef __KERNEL__
-+#define hz_to_std(a) (a)
-+#endif
- #endif
-
- #define EXEC_PAGESIZE 8192 /* Thanks for sun4's we carry baggage... */
---- linux-2.4.25/include/linux/console_struct.h~2.4.25-vrs2.patch 2003-06-13 16:51:38.000000000 +0200
-+++ linux-2.4.25/include/linux/console_struct.h 2004-03-31 17:15:09.000000000 +0200
-@@ -7,6 +7,8 @@
- * Fields marked with [#] must be set by the low-level driver.
- * Fields marked with [!] can be changed by the low-level driver
- * to achieve effects such as fast scrolling by changing the origin.
-+ *
-+ * 11/07/1998 RMK Changed vc_state to be a function pointer
- */
-
- #ifndef _LINUX_CONSOLE_STRUCT_H_
-@@ -34,7 +36,11 @@
- unsigned short vc_s_complement_mask; /* Saved mouse pointer mask */
- unsigned int vc_x, vc_y; /* Cursor position */
- unsigned int vc_top, vc_bottom; /* Scrolling region */
-+#ifdef CONSOLE_WIP
-+ int (*vc_state)(int currcons, struct tty_struct *tty, unsigned int c);
-+#else
- unsigned int vc_state; /* Escape sequence parser state */
-+#endif
- unsigned int vc_npar,vc_par[NPAR]; /* Parameters of current escape sequence */
- unsigned long vc_origin; /* [!] Start of real screen */
- unsigned long vc_scr_end; /* [!] End of real screen */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/linux/cpufreq.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,94 @@
-+/*
-+ * linux/include/linux/cpufreq.h
-+ *
-+ * Copyright (C) 2001 Russell King
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#ifndef _LINUX_CPUFREQ_H
-+#define _LINUX_CPUFREQ_H
-+
-+#include <linux/config.h>
-+#include <linux/notifier.h>
-+
-+#ifndef CONFIG_SMP
-+#define cpufreq_current(cpu) ((void)(cpu), __cpufreq_cur)
-+#define cpufreq_max(cpu) ((void)(cpu), __cpufreq_max)
-+#define cpufreq_min(cpu) ((void)(cpu), __cpufreq_min)
-+#else
-+/*
-+ * Should be something like:
-+ *
-+ * typedef struct {
-+ * u_int current;
-+ * u_int max;
-+ * u_int min;
-+ * } __cacheline_aligned cpufreq_info_t;
-+ *
-+ * static cpufreq_info_t cpufreq_info;
-+ *
-+ * #define cpufreq_current(cpu) (cpufreq_info[cpu].current)
-+ * #define cpufreq_max(cpu) (cpufreq_info[cpu].max)
-+ * #define cpufreq_min(cpu) (cpufreq_info[cpu].min)
-+ *
-+ * Maybe we should find some other per-cpu structure to
-+ * bury this in?
-+ */
-+#error fill in SMP version
-+#endif
-+
-+struct cpufreq_info {
-+ unsigned int old_freq;
-+ unsigned int new_freq;
-+};
-+
-+/*
-+ * The max and min frequency rates that the registered device
-+ * can tolerate. Never set any element this structure directly -
-+ * always use cpu_updateminmax.
-+ */
-+struct cpufreq_minmax {
-+ unsigned int min_freq;
-+ unsigned int max_freq;
-+ unsigned int cur_freq;
-+ unsigned int new_freq;
-+};
-+
-+static inline
-+void cpufreq_updateminmax(void *arg, unsigned int min, unsigned int max)
-+{
-+ struct cpufreq_minmax *minmax = arg;
-+
-+ if (minmax->min_freq < min)
-+ minmax->min_freq = min;
-+ if (minmax->max_freq > max)
-+ minmax->max_freq = max;
-+}
-+
-+#define CPUFREQ_MINMAX (0)
-+#define CPUFREQ_PRECHANGE (1)
-+#define CPUFREQ_POSTCHANGE (2)
-+
-+int cpufreq_register_notifier(struct notifier_block *nb);
-+int cpufreq_unregister_notifier(struct notifier_block *nb);
-+
-+int cpufreq_setmax(void);
-+int cpufreq_restore(void);
-+int cpufreq_set(unsigned int khz);
-+unsigned int cpufreq_get(int cpu);
-+
-+/*
-+ * These two functions are only available at init time.
-+ */
-+void cpufreq_init(unsigned int khz,
-+ unsigned int min_freq,
-+ unsigned int max_freq);
-+
-+void cpufreq_setfunctions(unsigned int (*validate)(unsigned int),
-+ void (*setspeed)(unsigned int));
-+
-+#endif
---- linux-2.4.25/include/linux/i2c-id.h~2.4.25-vrs2.patch 2004-02-18 14:36:32.000000000 +0100
-+++ linux-2.4.25/include/linux/i2c-id.h 2004-03-31 17:15:09.000000000 +0200
-@@ -20,16 +20,16 @@
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
- /* ------------------------------------------------------------------------- */
-
--/* $Id$ */
-+/* $Id$ */
-
- #ifndef I2C_ID_H
- #define I2C_ID_H
- /*
- * This file is part of the i2c-bus package and contains the identifier
- * values for drivers, adapters and other folk populating these serial
-- * worlds.
-+ * worlds.
- *
-- * These will change often (i.e. additions) , therefore this has been
-+ * These will change often (i.e. additions) , therefore this has been
- * separated from the functional interface definitions of the i2c api.
- *
- */
-@@ -38,10 +38,10 @@
- * ---- Driver types -----------------------------------------------------
- * device id name + number function description, i2c address(es)
- *
-- * Range 1000-1999 range is defined in sensors/sensors.h
-- * Range 0x100 - 0x1ff is for V4L2 Common Components
-+ * Range 1000-1999 range is defined in sensors/sensors.h
-+ * Range 0x100 - 0x1ff is for V4L2 Common Components
- * Range 0xf000 - 0xffff is reserved for local experimentation, and should
-- * never be used in official drivers
-+ * never be used in official drivers
- */
-
- #define I2C_DRIVERID_MSP3400 1
-@@ -90,7 +90,12 @@
- #define I2C_DRIVERID_DRP3510 43 /* ADR decoder (Astra Radio) */
- #define I2C_DRIVERID_SP5055 44 /* Satellite tuner */
- #define I2C_DRIVERID_STV0030 45 /* Multipurpose switch */
-+#define I2C_DRIVERID_SAA7108 46 /* video decoder, image scaler */
-+#define I2C_DRIVERID_DS1307 47 /* DS1307 real time clock */
- #define I2C_DRIVERID_ADV7175 48 /* ADV 7175/7176 video encoder */
-+#define I2C_DRIVERID_ZR36067 49 /* Zoran 36067 video encoder */
-+#define I2C_DRIVERID_ZR36120 50 /* Zoran 36120 video encoder */
-+#define I2C_DRIVERID_24LC32A 51 /* Microchip 24LC32A 32k EEPROM */
- #define I2C_DRIVERID_MAX1617 56 /* temp sensor */
- #define I2C_DRIVERID_SAA7191 57 /* video decoder */
- #define I2C_DRIVERID_INDYCAM 58 /* SGI IndyCam */
-@@ -102,8 +107,10 @@
-
- #define I2C_DRIVERID_I2CDEV 900
- #define I2C_DRIVERID_I2CPROC 901
-+#define I2C_DRIVERID_ARP 902 /* SMBus ARP Client */
-+#define I2C_DRIVERID_ALERT 903 /* SMBus Alert Responder Client */
-
--/* IDs -- Use DRIVERIDs 1000-1999 for sensors.
-+/* IDs -- Use DRIVERIDs 1000-1999 for sensors.
- These were originally in sensors.h in the lm_sensors package */
- #define I2C_DRIVERID_LM78 1002
- #define I2C_DRIVERID_LM75 1003
-@@ -131,6 +138,12 @@
- #define I2C_DRIVERID_ADM1024 1025
- #define I2C_DRIVERID_IT87 1026
- #define I2C_DRIVERID_CH700X 1027 /* single driver for CH7003-7009 digital pc to tv encoders */
-+#define I2C_DRIVERID_FSCPOS 1028
-+#define I2C_DRIVERID_FSCSCY 1029
-+#define I2C_DRIVERID_PCF8591 1030
-+#define I2C_DRIVERID_SMSC47M1 1031
-+#define I2C_DRIVERID_VT1211 1032
-+#define I2C_DRIVERID_LM92 1033
-
- /*
- * ---- Adapter types ----------------------------------------------------
-@@ -147,7 +160,8 @@
- #define I2C_ALGO_ISA 0x050000 /* lm_sensors ISA pseudo-adapter */
- #define I2C_ALGO_SAA7146 0x060000 /* SAA 7146 video decoder bus */
- #define I2C_ALGO_ACB 0x070000 /* ACCESS.bus algorithm */
--
-+#define I2C_ALGO_IIC 0x080000 /* ITE IIC bus */
-+#define I2C_ALGO_SAA7134 0x090000
- #define I2C_ALGO_EC 0x100000 /* ACPI embedded controller */
-
- #define I2C_ALGO_MPC8XX 0x110000 /* MPC8xx PowerPC I2C algorithm */
-@@ -156,13 +170,15 @@
-
- #define I2C_ALGO_SGI 0x130000 /* SGI algorithm */
-
-+#define I2C_ALGO_OCP 0x120000 /* IBM or otherwise On-chip I2C algorithm */
-+
- #define I2C_ALGO_EXP 0x800000 /* experimental */
-
- #define I2C_ALGO_MASK 0xff0000 /* Mask for algorithms */
- #define I2C_ALGO_SHIFT 0x10 /* right shift to get index values */
-
- #define I2C_HW_ADAPS 0x10000 /* # adapter types */
--#define I2C_HW_MASK 0xffff
-+#define I2C_HW_MASK 0xffff
-
-
- /* hw specific modules that are defined per algorithm layer
-@@ -182,9 +198,13 @@
- #define I2C_HW_B_I810 0x0a /* Intel I810 */
- #define I2C_HW_B_VOO 0x0b /* 3dfx Voodoo 3 / Banshee */
- #define I2C_HW_B_PPORT 0x0c /* Primitive parallel port adapter */
-+#define I2C_HW_B_SAVG 0x0d /* Savage 4 */
- #define I2C_HW_B_RIVA 0x10 /* Riva based graphics cards */
- #define I2C_HW_B_IOC 0x11 /* IOC bit-wiggling */
- #define I2C_HW_B_TSUNA 0x12 /* DEC Tsunami chipset */
-+#define I2C_HW_B_FRODO 0x13 /* 2d3D, Inc. SA-1110 Development Board */
-+#define I2C_HW_B_OMAHA 0x14 /* Omaha I2C interface */
-+#define I2C_HW_B_GUIDE 0x15 /* Guide bit-basher */
-
- /* --- PCF 8584 based algorithms */
- #define I2C_HW_P_LP 0x00 /* Parallel port interface */
-@@ -197,6 +217,12 @@
- /* --- MPC8xx PowerPC adapters */
- #define I2C_HW_MPC8XX_EPON 0x00 /* Eponymous MPC8xx I2C adapter */
-
-+/* --- ITE based algorithms */
-+#define I2C_HW_I_IIC 0x00 /* controller on the ITE */
-+
-+/* --- PowerPC on-chip adapters */
-+#define I2C_HW_OCP 0x00 /* IBM on-chip I2C adapter */
-+
- /* --- Broadcom SiByte adapters */
- #define I2C_HW_SIBYTE 0x00
-
---- linux-2.4.25/include/linux/ide.h~2.4.25-vrs2.patch 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.25/include/linux/ide.h 2004-03-31 17:15:09.000000000 +0200
-@@ -287,7 +287,9 @@
- * Check for an interrupt and acknowledge the interrupt status
- */
- struct hwif_s;
-+struct ide_drive_s;
- typedef int (ide_ack_intr_t)(struct hwif_s *);
-+typedef void (ide_xfer_data_t)(struct ide_drive_s *, void *, unsigned int);
-
- #ifndef NO_DMA
- #define NO_DMA 255
-@@ -311,10 +313,14 @@
- typedef struct hw_regs_s {
- ide_ioreg_t io_ports[IDE_NR_PORTS]; /* task file registers */
- int irq; /* our irq number */
-- int dma; /* our dma entry */
-+ int dma; /* our dma number */
- ide_ack_intr_t *ack_intr; /* acknowledge interrupt */
-+ ide_xfer_data_t *ide_output_data; /* write data to i/face */
-+ ide_xfer_data_t *ide_input_data; /* read data from i/face */
-+ ide_xfer_data_t *atapi_output_bytes; /* write bytes to i/face */
-+ ide_xfer_data_t *atapi_input_bytes; /* read bytes from i/face */
- void *priv; /* interface specific data */
-- hwif_chipset_t chipset;
-+ hwif_chipset_t chipset;
- sata_ioreg_t sata_scr[SATA_NR_PORTS];
- sata_ioreg_t sata_misc[SATA_NR_PORTS];
- } hw_regs_t;
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/linux/l3/algo-bit.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,39 @@
-+/*
-+ * linux/include/linux/l3/algo-bit.h
-+ *
-+ * Copyright (C) 2001 Russell King, 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.
-+ *
-+ * L3 Bus bit-banging algorithm. Derived from i2c-algo-bit.h by
-+ * Simon G. Vogl.
-+ */
-+#ifndef L3_ALGO_BIT_H
-+#define L3_ALGO_BIT_H 1
-+
-+#include <linux/l3/l3.h>
-+
-+struct l3_algo_bit_data {
-+ void (*setdat) (void *data, int state);
-+ void (*setclk) (void *data, int state);
-+ void (*setmode)(void *data, int state);
-+ void (*setdir) (void *data, int in); /* set data direction */
-+ int (*getdat) (void *data);
-+
-+ void *data;
-+
-+ /* bus timings (us) */
-+ int data_hold;
-+ int data_setup;
-+ int clock_high;
-+ int mode_hold;
-+ int mode_setup;
-+ int mode;
-+};
-+
-+int l3_bit_add_bus(struct l3_adapter *);
-+int l3_bit_del_bus(struct l3_adapter *);
-+
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/linux/l3/l3.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,208 @@
-+/*
-+ * linux/include/linux/l3/l3.h
-+ *
-+ * Copyright (C) 2001 Russell King, 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.
-+ *
-+ * Derived from i2c.h by Simon G. Vogl
-+ */
-+#ifndef L3_H
-+#define L3_H
-+
-+struct l3_msg {
-+ unsigned char addr; /* slave address */
-+ unsigned char flags;
-+#define L3_M_RD 0x01
-+#define L3_M_NOADDR 0x02
-+ unsigned short len; /* msg length */
-+ unsigned char *buf; /* pointer to msg data */
-+};
-+
-+#ifdef __KERNEL__
-+
-+#include <linux/types.h>
-+#include <linux/list.h>
-+
-+struct l3_client;
-+
-+struct l3_ops {
-+ int (*open)(struct l3_client *);
-+ int (*command)(struct l3_client *, int cmd, void *arg);
-+ void (*close)(struct l3_client *);
-+};
-+
-+/*
-+ * A driver is capable of handling one or more physical devices present on
-+ * L3 adapters. This information is used to inform the driver of adapter
-+ * events.
-+ */
-+struct l3_driver {
-+ /*
-+ * This name is used to uniquely identify the driver.
-+ * It should be the same as the module name.
-+ */
-+ char name[32];
-+
-+ /*
-+ * Notifies the driver that a new client wishes to use its
-+ * services. Note that the module use count will be increased
-+ * prior to this function being called. In addition, the
-+ * clients driver and adapter fields will have been setup.
-+ */
-+ int (*attach_client)(struct l3_client *);
-+
-+ /*
-+ * Notifies the driver that the client has finished with its
-+ * services, and any memory that it allocated for this client
-+ * should be cleaned up. In addition the chip should be
-+ * shut down.
-+ */
-+ void (*detach_client)(struct l3_client *);
-+
-+ /*
-+ * Possible operations on the driver.
-+ */
-+ struct l3_ops *ops;
-+
-+ /*
-+ * Module structure, if any.
-+ */
-+ struct module *owner;
-+
-+ /*
-+ * drivers list
-+ */
-+ struct list_head drivers;
-+};
-+
-+struct l3_adapter;
-+
-+struct l3_algorithm {
-+ /* textual description */
-+ char name[32];
-+
-+ /* perform bus transactions */
-+ int (*xfer)(struct l3_adapter *, struct l3_msg msgs[], int num);
-+};
-+
-+struct semaphore;
-+
-+/*
-+ * l3_adapter is the structure used to identify a physical L3 bus along
-+ * with the access algorithms necessary to access it.
-+ */
-+struct l3_adapter {
-+ /*
-+ * This name is used to uniquely identify the adapter.
-+ * It should be the same as the module name.
-+ */
-+ char name[32];
-+
-+ /*
-+ * the algorithm to access the bus
-+ */
-+ struct l3_algorithm *algo;
-+
-+ /*
-+ * Algorithm specific data
-+ */
-+ void *algo_data;
-+
-+ /*
-+ * This may be NULL, or should point to the module struct
-+ */
-+ struct module *owner;
-+
-+ /*
-+ * private data for the adapter
-+ */
-+ void *data;
-+
-+ /*
-+ * Our lock. Unlike the i2c layer, we allow this to be used for
-+ * other stuff, like the i2c layer lock. Some people implement
-+ * i2c stuff using the same signals as the l3 bus.
-+ */
-+ struct semaphore *lock;
-+
-+ /*
-+ * List of attached clients.
-+ */
-+ struct list_head clients;
-+
-+ /*
-+ * List of all adapters.
-+ */
-+ struct list_head adapters;
-+};
-+
-+/*
-+ * l3_client identifies a single device (i.e. chip) that is connected to an
-+ * L3 bus. The behaviour is defined by the routines of the driver. This
-+ * function is mainly used for lookup & other admin. functions.
-+ */
-+struct l3_client {
-+ struct l3_adapter *adapter; /* the adapter we sit on */
-+ struct l3_driver *driver; /* and our access routines */
-+ void *driver_data; /* private driver data */
-+ struct list_head __adap;
-+};
-+
-+
-+extern int l3_add_adapter(struct l3_adapter *);
-+extern int l3_del_adapter(struct l3_adapter *);
-+
-+extern int l3_add_driver(struct l3_driver *);
-+extern int l3_del_driver(struct l3_driver *);
-+
-+extern int l3_attach_client(struct l3_client *, const char *, const char *);
-+extern int l3_detach_client(struct l3_client *);
-+
-+extern int l3_transfer(struct l3_adapter *, struct l3_msg msgs[], int);
-+extern int l3_write(struct l3_client *, int, const char *, int);
-+extern int l3_read(struct l3_client *, int, char *, int);
-+
-+/**
-+ * l3_command - send a command to a L3 device driver
-+ * @client: registered client structure
-+ * @cmd: device driver command
-+ * @arg: device driver arguments
-+ *
-+ * Ask the L3 device driver to perform some function. Further information
-+ * should be sought from the device driver in question.
-+ *
-+ * Returns negative error code on failure.
-+ */
-+static inline int l3_command(struct l3_client *clnt, int cmd, void *arg)
-+{
-+ struct l3_ops *ops = clnt->driver->ops;
-+ int ret = -EINVAL;
-+
-+ if (ops && ops->command)
-+ ret = ops->command(clnt, cmd, arg);
-+
-+ return ret;
-+}
-+
-+static inline int l3_open(struct l3_client *clnt)
-+{
-+ struct l3_ops *ops = clnt->driver->ops;
-+ int ret = 0;
-+
-+ if (ops && ops->open)
-+ ret = ops->open(clnt);
-+ return ret;
-+}
-+
-+static inline void l3_close(struct l3_client *clnt)
-+{
-+ struct l3_ops *ops = clnt->driver->ops;
-+ if (ops && ops->close)
-+ ops->close(clnt);
-+}
-+#endif
-+
-+#endif /* L3_H */
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/linux/l3/uda1341.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,50 @@
-+/*
-+ * linux/include/linux/l3/uda1341.h
-+ *
-+ * Philips UDA1341 mixer device driver
-+ *
-+ * Copyright (c) 2000 Nicolas Pitre <nico@cam.org>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License.
-+ */
-+
-+#define UDA1341_NAME "uda1341"
-+
-+struct uda1341_cfg {
-+ unsigned int fs:16;
-+ unsigned int format:3;
-+};
-+
-+#define FMT_I2S 0
-+#define FMT_LSB16 1
-+#define FMT_LSB18 2
-+#define FMT_LSB20 3
-+#define FMT_MSB 4
-+#define FMT_LSB16MSB 5
-+#define FMT_LSB18MSB 6
-+#define FMT_LSB20MSB 7
-+
-+#define L3_UDA1341_CONFIGURE 0x13410001
-+
-+struct l3_gain {
-+ unsigned int left:8;
-+ unsigned int right:8;
-+ unsigned int unused:8;
-+ unsigned int channel:8;
-+};
-+
-+#define L3_SET_VOLUME 0x13410002
-+#define L3_SET_TREBLE 0x13410003
-+#define L3_SET_BASS 0x13410004
-+#define L3_SET_GAIN 0x13410005
-+
-+struct l3_agc {
-+ unsigned int level:8;
-+ unsigned int enable:1;
-+ unsigned int attack:7;
-+ unsigned int decay:8;
-+ unsigned int channel:8;
-+};
-+
-+#define L3_INPUT_AGC 0x13410006
---- linux-2.4.25/include/linux/mm.h~2.4.25-vrs2.patch 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.25/include/linux/mm.h 2004-03-31 17:15:09.000000000 +0200
-@@ -685,6 +685,12 @@
-
- extern struct page * vmalloc_to_page(void *addr);
-
-+#ifndef __arm__
-+#define memc_update_addr(x,y,z)
-+#define memc_update_mm(x)
-+#define memc_clear(x,y)
-+#endif
-+
- #endif /* __KERNEL__ */
-
- #endif
---- linux-2.4.25/include/linux/pci.h~2.4.25-vrs2.patch 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.25/include/linux/pci.h 2004-03-31 17:15:09.000000000 +0200
-@@ -410,6 +410,7 @@
-
- char name[90]; /* device name */
- char slot_name[8]; /* slot name */
-+ u32 saved_state[16]; /* for saving the config space before suspend */
- int active; /* ISAPnP: device is active */
- int ro; /* ISAPnP: read only */
- unsigned short regs; /* ISAPnP: supported registers */
-@@ -496,6 +497,8 @@
-
- struct pbus_set_ranges_data
- {
-+ int found_vga:1;
-+ int prefetch_valid:1;
- unsigned long io_start, io_end;
- unsigned long mem_start, mem_end;
- unsigned long prefetch_start, prefetch_end;
-@@ -637,6 +640,8 @@
- int pci_restore_state(struct pci_dev *dev, u32 *buffer);
- int pci_set_power_state(struct pci_dev *dev, int state);
- int pci_enable_wake(struct pci_dev *dev, u32 state, int enable);
-+int pci_generic_suspend_save(struct pci_dev *pdev, u32 state);
-+int pci_generic_resume_restore(struct pci_dev *pdev);
-
- /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
-
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/linux/pld/pld_epxa.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,35 @@
-+#ifndef __LINUX_EPXAPLD_H
-+#define __LINUX_EPXAPLD_H
-+
-+/*
-+ * linux/drivers/char/pld/epxapld.h
-+ *
-+ * Pld driver for Altera EPXA Excalibur devices
-+ *
-+ * Copyright 2001 Altera Corporation
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * $Id$
-+ *
-+ */
-+#define PLD_IOC_MAGIC 'p'
-+#if !defined(KERNEL) || defined(CONFIG_PLD_HOTSWAP)
-+#define PLD_IOC_ADD_PLD_DEV _IOW(PLD_IOC_MAGIC, 0xa0, struct pldhs_dev_desc)
-+#define PLD_IOC_REMOVE_PLD_DEVS _IO(PLD_IOC_MAGIC, 0xa1)
-+#define PLD_IOC_SET_INT_MODE _IOW(PLD_IOC_MAGIC, 0xa2, int)
-+#endif
-+
-+#endif
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/linux/pld/pld_hotswap.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,87 @@
-+#ifndef __LINUX_PLD_HOTSWAP_H
-+#define __LINUX_PLD_HOTSWAP_H
-+/*
-+ * linux/drivers/char/pld/pld_hotswap.h
-+ *
-+ * Pld driver for Altera EPXA Excalibur devices
-+ *
-+ * Copyright 2001 Altera Corporation
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * $Id$
-+ *
-+ */
-+
-+/*
-+ * The pld_hotswap ops contain the basic operation required for adding
-+ * and removing devices from the system.
-+ */
-+
-+struct pldhs_dev_info{
-+ unsigned int size;
-+ unsigned short vendor_id;
-+ unsigned short product_id;
-+ unsigned char fsize;
-+ unsigned char nsize;
-+ unsigned short pssize;
-+ unsigned short cmdsize;
-+ unsigned char irq;
-+ unsigned char version;
-+ unsigned int base_addr;
-+ unsigned int reg_size;
-+};
-+
-+struct pldhs_dev_desc{
-+ struct pldhs_dev_info* info;
-+ char* name;
-+ void* data;
-+};
-+
-+#include <linux/pld/pld_epxa.h>
-+
-+
-+#ifdef __KERNEL__
-+struct pld_hotswap_ops{
-+ struct list_head list;
-+ char* name;
-+ int (*add_device)(struct pldhs_dev_info *dev_info, void* dev_ps_data);
-+ int (*remove_devices)(void);
-+ int (*proc_read)(char* buf,char** start,off_t offset,int count,int *eof,void *data);
-+};
-+
-+/*
-+ * These functions are called by the device drivers to register functions
-+ * which should be called when devices are added and removed
-+ */
-+extern int pldhs_register_driver(struct pld_hotswap_ops *drv);
-+extern int pldhs_unregister_driver(char *driver);
-+
-+/*
-+ * These functions are called by the pld loader to add and remove
-+ * device instances from the system. The call the functions regsistered
-+ * the the particular deriver for this purpose
-+ */
-+extern int pldhs_add_device(struct pldhs_dev_info* dev_info,char *drv_name, void* dev_ps_data);
-+extern int pldhs_remove_devices(void);
-+
-+/* Macro for formatting data to appear in the proc/pld file */
-+#define PLDHS_READ_PROC_DATA(buf,name,index,base,irq,ps_string) \
-+ sprintf(buf,":%s:%d Base Address, %#lx, IRQ, %d#\n%s\n",\
-+ name,index,base,irq,ps_string)
-+
-+#endif
-+
-+#endif
---- linux-2.4.25/include/linux/serial.h~2.4.25-vrs2.patch 2002-08-03 02:39:45.000000000 +0200
-+++ linux-2.4.25/include/linux/serial.h 2004-03-31 17:15:09.000000000 +0200
-@@ -48,7 +48,7 @@
- unsigned char *iomem_base;
- unsigned short iomem_reg_shift;
- unsigned int port_high;
-- int reserved[1];
-+ unsigned long iomap_base; /* cookie passed into ioremap */
- };
-
- /*
---- linux-2.4.25/include/linux/serialP.h~2.4.25-vrs2.patch 2002-08-03 02:39:45.000000000 +0200
-+++ linux-2.4.25/include/linux/serialP.h 2004-03-31 17:15:09.000000000 +0200
-@@ -157,8 +157,8 @@
- struct pci_dev *dev;
- };
-
--extern int pci_siig10x_fn(struct pci_dev *dev, struct pci_board *board, int enable);
--extern int pci_siig20x_fn(struct pci_dev *dev, struct pci_board *board, int enable);
-+//extern int pci_siig10x_fn(struct pci_dev *dev, struct pci_board *board, int enable);
-+//extern int pci_siig20x_fn(struct pci_dev *dev, struct pci_board *board, int enable);
-
- #ifndef PCI_ANY_ID
- #define PCI_ANY_ID (~0)
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/include/linux/serial_core.h 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,441 @@
-+/*
-+ * linux/drivers/char/serial_core.h
-+ *
-+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * $Id$
-+ */
-+
-+/*
-+ * The type definitions. These are from Ted Ts'o's serial.h
-+ */
-+#define PORT_UNKNOWN 0
-+#define PORT_8250 1
-+#define PORT_16450 2
-+#define PORT_16550 3
-+#define PORT_16550A 4
-+#define PORT_CIRRUS 5
-+#define PORT_16650 6
-+#define PORT_16650V2 7
-+#define PORT_16750 8
-+#define PORT_STARTECH 9
-+#define PORT_16C950 10
-+#define PORT_16654 11
-+#define PORT_16850 12
-+#define PORT_RSA 13
-+#define PORT_NS16550A 14
-+#define PORT_MAX_8250 14 /* max port ID */
-+
-+/*
-+ * ARM specific type numbers. These are not currently guaranteed
-+ * to be implemented, and will change in the future. These are
-+ * separate so any additions to the old serial.c that occur before
-+ * we are merged can be easily merged here.
-+ */
-+#define PORT_AMBA 32
-+#define PORT_CLPS711X 33
-+#define PORT_SA1100 34
-+#define PORT_UART00 35
-+#define PORT_21285 37
-+
-+/* Sparc type numbers. */
-+#define PORT_SUNZILOG 38
-+#define PORT_SUNSAB 39
-+
-+/* NEC v850. */
-+#define PORT_NB85E_UART 40
-+
-+/* NEC PC-9800 */
-+#define PORT_8251_PC98 41
-+#define PORT_19K_PC98 42
-+#define PORT_FIFO_PC98 43
-+#define PORT_VFAST_PC98 44
-+#define PORT_PC9861 45
-+#define PORT_PC9801_101 46
-+
-+/* DZ */
-+#define PORT_DZ 47
-+
-+#define PORT_OMAHA 48
-+#define PORT_AT91RM9200 49
-+
-+
-+#ifdef __KERNEL__
-+
-+#include <linux/config.h>
-+#include <linux/interrupt.h>
-+#include <linux/circ_buf.h>
-+#include <linux/serial.h>
-+#include <linux/spinlock.h>
-+
-+struct uart_port;
-+struct uart_info;
-+struct serial_struct;
-+
-+/*
-+ * This structure describes all the operations that can be
-+ * done on the physical hardware.
-+ */
-+struct uart_ops {
-+ unsigned int (*tx_empty)(struct uart_port *);
-+ void (*set_mctrl)(struct uart_port *, unsigned int mctrl);
-+ unsigned int (*get_mctrl)(struct uart_port *);
-+ void (*stop_tx)(struct uart_port *, unsigned int tty_stop);
-+ void (*start_tx)(struct uart_port *, unsigned int tty_start);
-+ void (*send_xchar)(struct uart_port *, char ch);
-+ void (*stop_rx)(struct uart_port *);
-+ void (*enable_ms)(struct uart_port *);
-+ void (*break_ctl)(struct uart_port *, int ctl);
-+ int (*startup)(struct uart_port *);
-+ void (*shutdown)(struct uart_port *);
-+ void (*change_speed)(struct uart_port *, unsigned int cflag, unsigned int iflag, unsigned int quot);
-+ void (*pm)(struct uart_port *, unsigned int state, unsigned int oldstate);
-+ int (*set_wake)(struct uart_port *, unsigned int state);
-+
-+ /*
-+ * Return a string describing the type of the port
-+ */
-+ const char *(*type)(struct uart_port *);
-+
-+ /*
-+ * Release IO and memory resources used by the port.
-+ * This includes iounmap if necessary.
-+ */
-+ void (*release_port)(struct uart_port *);
-+
-+ /*
-+ * Request IO and memory resources used by the port.
-+ * This includes iomapping the port if necessary.
-+ */
-+ int (*request_port)(struct uart_port *);
-+ void (*config_port)(struct uart_port *, int);
-+ int (*verify_port)(struct uart_port *, struct serial_struct *);
-+ int (*ioctl)(struct uart_port *, unsigned int, unsigned long);
-+};
-+
-+#define UART_CONFIG_TYPE (1 << 0)
-+#define UART_CONFIG_IRQ (1 << 1)
-+
-+struct uart_icount {
-+ __u32 cts;
-+ __u32 dsr;
-+ __u32 rng;
-+ __u32 dcd;
-+ __u32 rx;
-+ __u32 tx;
-+ __u32 frame;
-+ __u32 overrun;
-+ __u32 parity;
-+ __u32 brk;
-+ __u32 buf_overrun;
-+};
-+
-+struct uart_port {
-+ spinlock_t lock; /* port lock */
-+ unsigned int iobase; /* in/out[bwl] */
-+ char *membase; /* read/write[bwl] */
-+ unsigned char fifosize; /* tx fifo size */
-+ unsigned char x_char; /* xon/xoff char */
-+ unsigned char regshift; /* reg offset shift */
-+ unsigned char iotype; /* io access style */
-+
-+#define UPIO_PORT (0)
-+#define UPIO_HUB6 (1)
-+#define UPIO_MEM (2)
-+
-+ unsigned int read_status_mask; /* driver specific */
-+ unsigned int ignore_status_mask; /* driver specific */
-+
-+ struct uart_info *info; /* pointer to parent info */
-+ struct uart_icount icount; /* statistics */
-+
-+ struct console *cons; /* struct console, if any */
-+ unsigned long sysrq; /* sysrq timeout */
-+
-+ unsigned int flags;
-+
-+#define UPF_HUP_NOTIFY ASYNC_HUP_NOTIFY
-+#define UPF_FOURPORT ASYNC_FOURPORT
-+#define UPF_SAK ASYNC_SAK
-+#define UPF_SPLIT_TERMIOS ASYNC_SPLIT_TERMIOS
-+#define UPF_SPD_MASK (0x1030)
-+#define UPF_SPD_HI (0x0010)
-+#define UPF_SPD_VHI (0x0020)
-+#define UPF_SPD_CUST (0x0030)
-+#define UPF_SPD_SHI (0x1000)
-+#define UPF_SPD_WARP (0x1010)
-+#define UPF_SKIP_TEST ASYNC_SKIP_TEST
-+#define UPF_AUTO_IRQ ASYNC_AUTO_IRQ
-+#define UPF_SESSION_LOCKOUT ASYNC_SESSION_LOCKOUT
-+#define UPF_PGRP_LOCKOUT ASYNCPGRP_LOCKOUT
-+#define UPF_CALLOUT_NOHUP ASYNC_CALLOUT_NOHUP
-+#define UPF_HARDPPS_CD ASYNC_HARDPPS_CD
-+ /* 12 */
-+#define UPF_LOW_LATENCY ASYNC_LOW_LATENCY
-+#define UPF_BUGGY_UART ASYNC_BUGGY_UART
-+#define UPF_AUTOPROBE ASYNC_AUTOPROBE
-+#define UPF_MAGIC_MULTIPLIER (1 << 16)
-+#define UPF_BOOT_ONLYMCA ASYNC_BOOT_ONLYMCA
-+#define UPF_CONS_FLOW ASYNC_CONS_FLOW
-+#define UPF_SHARE_IRQ ASYNC_SHARE_IRQ
-+#define UPF_BOOT_AUTOCONF ASYNC_BOOT_AUTOCONF
-+#define UPF_RESOURCES (1 << 30)
-+#define UPF_IOREMAP (1 << 31)
-+
-+#define UPF_CHANGE_MASK (0x17fff)
-+#define UPF_USR_MASK (UPF_SPD_MASK|UPF_LOW_LATENCY)
-+
-+ unsigned int mctrl; /* current modem ctrl settings */
-+ unsigned int timeout; /* character-based timeout */
-+ unsigned int type; /* port type */
-+ struct uart_ops *ops;
-+ unsigned int uartclk; /* base uart clock */
-+ unsigned int custom_divisor;
-+ unsigned int irq; /* irq number */
-+ unsigned int line; /* port index */
-+ unsigned long mapbase; /* for ioremap */
-+ unsigned char hub6; /* this should be in the 8250 driver */
-+ unsigned char unused[7];
-+};
-+
-+/*
-+ * This is the state information which is persistent across opens.
-+ * The low level driver must not to touch any elements contained
-+ * within.
-+ */
-+struct uart_state {
-+ unsigned int close_delay;
-+ unsigned int closing_wait;
-+
-+#define USF_CLOSING_WAIT_INF (0)
-+#define USF_CLOSING_WAIT_NONE (65535)
-+
-+ struct termios normal_termios;
-+ struct termios callout_termios;
-+
-+ int count;
-+ struct uart_info *info;
-+ struct uart_port *port;
-+
-+ struct semaphore sem;
-+#ifdef CONFIG_PM
-+ struct pm_dev *pm;
-+#endif
-+};
-+
-+#define UART_XMIT_SIZE 1024
-+/*
-+ * This is the state information which is only valid when the port
-+ * is open; it may be freed by the core driver once the device has
-+ * been closed. Either the low level driver or the core can modify
-+ * stuff here.
-+ */
-+struct uart_info {
-+ struct tty_struct *tty;
-+ struct circ_buf xmit;
-+ unsigned int flags;
-+
-+/*
-+ * These are the flags that specific to info->flags, and reflect our
-+ * internal state. They can not be accessed via port->flags. Low
-+ * level drivers must not change these, but may query them instead.
-+ */
-+#define UIF_CHECK_CD ASYNC_CHECK_CD
-+#define UIF_CTS_FLOW ASYNC_CTS_FLOW
-+#define UIF_CALLOUT_ACTIVE ASYNC_CALLOUT_ACTIVE
-+#define UIF_NORMAL_ACTIVE ASYNC_NORMAL_ACTIVE
-+#define UIF_INITIALIZED ASYNC_INITIALIZED
-+
-+ unsigned char *tmpbuf;
-+ struct semaphore tmpbuf_sem;
-+
-+ unsigned int driver_priv;
-+ int blocked_open;
-+ pid_t session;
-+ pid_t pgrp;
-+
-+ struct tasklet_struct tlet;
-+
-+ wait_queue_head_t open_wait;
-+ wait_queue_head_t delta_msr_wait;
-+};
-+
-+/* number of characters left in xmit buffer before we ask for more */
-+#define WAKEUP_CHARS 256
-+
-+struct module;
-+struct tty_driver;
-+
-+struct uart_driver {
-+ struct module *owner;
-+ int normal_major;
-+ const char *normal_name;
-+ struct tty_driver *normal_driver;
-+ int callout_major;
-+ const char *callout_name;
-+ struct tty_driver *callout_driver;
-+ struct tty_struct **table;
-+ struct termios **termios;
-+ struct termios **termios_locked;
-+ int minor;
-+ int nr;
-+ struct console *cons;
-+
-+ /*
-+ * these are private; the low level driver should not
-+ * touch these; they should be initialised to NULL
-+ */
-+ struct uart_state *state;
-+};
-+
-+void uart_write_wakeup(struct uart_port *port);
-+struct uart_port *uart_get_console(struct uart_port *ports, int nr,
-+ struct console *c);
-+void uart_parse_options(char *options, int *baud, int *parity, int *bits,
-+ int *flow);
-+int uart_set_options(struct uart_port *port, struct console *co, int baud,
-+ int parity, int bits, int flow);
-+
-+/*
-+ * Port/driver registration/removal
-+ */
-+int uart_register_driver(struct uart_driver *uart);
-+void uart_unregister_driver(struct uart_driver *uart);
-+void uart_unregister_port(struct uart_driver *reg, int line);
-+int uart_register_port(struct uart_driver *reg, struct uart_port *port);
-+int uart_add_one_port(struct uart_driver *reg, struct uart_port *port);
-+int uart_remove_one_port(struct uart_driver *reg, struct uart_port *port);
-+
-+#define uart_circ_empty(circ) ((circ)->head == (circ)->tail)
-+#define uart_circ_clear(circ) ((circ)->head = (circ)->tail = 0)
-+
-+#define uart_circ_chars_pending(circ) \
-+ (CIRC_CNT((circ)->head, (circ)->tail, UART_XMIT_SIZE))
-+
-+#define uart_circ_chars_free(circ) \
-+ (CIRC_SPACE((circ)->head, (circ)->tail, UART_XMIT_SIZE))
-+
-+#define uart_tx_stopped(port) \
-+ ((port)->info->tty->stopped || (port)->info->tty->hw_stopped)
-+
-+/*
-+ * The following are helper functions for the low level drivers.
-+ */
-+#ifdef SUPPORT_SYSRQ
-+static inline int
-+uart_handle_sysrq_char(struct uart_port *port, unsigned int ch,
-+ struct pt_regs *regs)
-+{
-+ if (port->sysrq) {
-+ if (ch && time_before(jiffies, port->sysrq)) {
-+ handle_sysrq(ch, regs, NULL, NULL);
-+ port->sysrq = 0;
-+ return 1;
-+ }
-+ port->sysrq = 0;
-+ }
-+ return 0;
-+}
-+#else
-+#define uart_handle_sysrq_char(port,ch,regs) (0)
-+#endif
-+
-+/*
-+ * We do the SysRQ and SAK checking like this...
-+ */
-+static inline int uart_handle_break(struct uart_port *port)
-+{
-+ struct uart_info *info = port->info;
-+#ifdef SUPPORT_SYSRQ
-+ if (port->cons && port->cons->index == port->line) {
-+ if (!port->sysrq) {
-+ port->sysrq = jiffies + HZ*5;
-+ return 1;
-+ }
-+ port->sysrq = 0;
-+ }
-+#endif
-+ if (port->flags & UPF_SAK)
-+ do_SAK(info->tty);
-+ return 0;
-+}
-+
-+/**
-+ * uart_handle_dcd_change - handle a change of carrier detect state
-+ * @port: uart_port structure for the open port
-+ * @status: new carrier detect status, nonzero if active
-+ */
-+static inline void
-+uart_handle_dcd_change(struct uart_port *port, unsigned int status)
-+{
-+ struct uart_info *info = port->info;
-+
-+ port->icount.dcd++;
-+
-+#ifdef CONFIG_HARD_PPS
-+ if ((port->flags & UPF_HARDPPS_CD) && status)
-+ hardpps();
-+#endif
-+
-+ if (info->flags & UIF_CHECK_CD) {
-+ if (status)
-+ wake_up_interruptible(&info->open_wait);
-+ else if (!((info->flags & UIF_CALLOUT_ACTIVE) &&
-+ (port->flags & UPF_CALLOUT_NOHUP))) {
-+ if (info->tty)
-+ tty_hangup(info->tty);
-+ }
-+ }
-+}
-+
-+/**
-+ * uart_handle_cts_change - handle a change of clear-to-send state
-+ * @port: uart_port structure for the open port
-+ * @status: new clear to send status, nonzero if active
-+ */
-+static inline void
-+uart_handle_cts_change(struct uart_port *port, unsigned int status)
-+{
-+ struct uart_info *info = port->info;
-+ struct tty_struct *tty = info->tty;
-+
-+ port->icount.cts++;
-+
-+ if (info->flags & UIF_CTS_FLOW) {
-+ if (tty->hw_stopped) {
-+ if (status) {
-+ tty->hw_stopped = 0;
-+ port->ops->start_tx(port, 0);
-+ uart_write_wakeup(port);
-+ }
-+ } else {
-+ if (!status) {
-+ tty->hw_stopped = 1;
-+ port->ops->stop_tx(port, 0);
-+ }
-+ }
-+ }
-+}
-+
-+/*
-+ * UART_ENABLE_MS - determine if port should enable modem status irqs
-+ */
-+#define UART_ENABLE_MS(port,cflag) ((port)->flags & UPF_HARDPPS_CD || \
-+ (cflag) & CRTSCTS || \
-+ !((cflag) & CLOCAL))
-+
-+#endif
---- linux-2.4.25/include/linux/serial_reg.h~2.4.25-vrs2.patch 2001-05-02 01:05:00.000000000 +0200
-+++ linux-2.4.25/include/linux/serial_reg.h 2004-03-31 17:15:09.000000000 +0200
-@@ -121,6 +121,7 @@
- /*
- * These are the definitions for the Modem Control Register
- */
-+#define UART_MCR_AFE 0x20 /* Enable auto-RTS/CTS (TI16C750) */
- #define UART_MCR_LOOP 0x10 /* Enable loopback test mode */
- #define UART_MCR_OUT2 0x08 /* Out2 complement */
- #define UART_MCR_OUT1 0x04 /* Out1 complement */
---- linux-2.4.25/include/linux/zlib.h~2.4.25-vrs2.patch 2002-11-29 00:53:15.000000000 +0100
-+++ linux-2.4.25/include/linux/zlib.h 2004-03-31 17:15:09.000000000 +0200
-@@ -31,7 +31,7 @@
- #ifndef _ZLIB_H
- #define _ZLIB_H
-
--#include <linux/zconf.h>
-+#include "zconf.h"
-
- #ifdef __cplusplus
- extern "C" {
---- linux-2.4.25/init/do_mounts.c~2.4.25-vrs2.patch 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.25/init/do_mounts.c 2004-03-31 17:15:09.000000000 +0200
-@@ -888,7 +888,7 @@
- */
- void prepare_namespace(void)
- {
-- int is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR;
-+ int is_floppy = MAJOR(ROOT_DEV) == FLOPPY_MAJOR || MAJOR(ROOT_DEV) == 31;
- #ifdef CONFIG_ALL_PPC
- extern void arch_discover_root(void);
- arch_discover_root();
-@@ -951,6 +951,7 @@
- static unsigned inptr; /* index of next byte to be processed in inbuf */
- static unsigned outcnt; /* bytes in output buffer */
- static int exit_code;
-+static int unzip_error;
- static long bytes_out;
- static int crd_infd, crd_outfd;
-
-@@ -998,13 +999,17 @@
- /* ===========================================================================
- * Fill the input buffer. This is called only when the buffer is empty
- * and at least one byte is really needed.
-+ * Returning -1 does not guarantee that gunzip() will ever return.
- */
- static int __init fill_inbuf(void)
- {
- if (exit_code) return -1;
-
- insize = read(crd_infd, inbuf, INBUFSIZ);
-- if (insize == 0) return -1;
-+ if (insize == 0) {
-+ error("RAMDISK: ran out of compressed data\n");
-+ return -1;
-+ }
-
- inptr = 1;
-
-@@ -1018,10 +1023,15 @@
- static void __init flush_window(void)
- {
- ulg c = crc; /* temporary variable */
-- unsigned n;
-+ unsigned n, written;
- uch *in, ch;
-
-- write(crd_outfd, window, outcnt);
-+ written = write(crd_outfd, window, outcnt);
-+ if (written != outcnt && unzip_error == 0) {
-+ printk(KERN_ERR "RAMDISK: incomplete write (%d != %d), "
-+ "only wrote %ld\n", written, outcnt, bytes_out);
-+ unzip_error = 1;
-+ }
- in = window;
- for (n = 0; n < outcnt; n++) {
- ch = *in++;
-@@ -1036,6 +1046,7 @@
- {
- printk(KERN_ERR "%s", x);
- exit_code = 1;
-+ unzip_error = 1;
- }
-
- static int __init crd_load(int in_fd, int out_fd)
-@@ -1064,6 +1075,8 @@
- }
- makecrc();
- result = gunzip();
-+ if (unzip_error)
-+ result = 1;
- kfree(inbuf);
- kfree(window);
- return result;
---- linux-2.4.25/kernel/Makefile~2.4.25-vrs2.patch 2001-09-17 06:22:40.000000000 +0200
-+++ linux-2.4.25/kernel/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -9,16 +9,19 @@
-
- O_TARGET := kernel.o
-
--export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o printk.o
-+export-objs = signal.o sys.o kmod.o context.o ksyms.o pm.o exec_domain.o \
-+ printk.o fork.o cpufreq.o
-
--obj-y = sched.o dma.o fork.o exec_domain.o panic.o printk.o \
-+obj-y = sched.o fork.o exec_domain.o panic.o printk.o \
- module.o exit.o itimer.o info.o time.o softirq.o resource.o \
- sysctl.o acct.o capability.o ptrace.o timer.o user.o \
- signal.o sys.o kmod.o context.o
-
-+obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
- obj-$(CONFIG_UID16) += uid16.o
- obj-$(CONFIG_MODULES) += ksyms.o
- obj-$(CONFIG_PM) += pm.o
-+obj-$(CONFIG_CPU_FREQ) += cpufreq.o
-
- ifneq ($(CONFIG_IA64),y)
- # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/kernel/cpufreq.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,536 @@
-+/*
-+ * linux/kernel/cpufreq.c
-+ *
-+ * Copyright (C) 2001 Russell King
-+ *
-+ * $Id$
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * CPU speed changing core functionality. We provide the following
-+ * services to the system:
-+ * - notifier lists to inform other code of the freq change both
-+ * before and after the freq change.
-+ * - the ability to change the freq speed
-+ *
-+ * ** You'll need to add CTL_CPU = 10 to include/linux/sysctl.h if
-+ * it's not already present.
-+ *
-+ * When this appears in the kernel, the sysctl enums will move to
-+ * include/linux/sysctl.h
-+ */
-+#include <linux/config.h>
-+#include <linux/types.h>
-+#include <linux/module.h>
-+#include <linux/notifier.h>
-+#include <linux/cpufreq.h>
-+#include <linux/kernel.h>
-+#include <linux/delay.h>
-+#include <linux/init.h>
-+#include <linux/smp.h>
-+#include <linux/fs.h>
-+#include <linux/sysctl.h>
-+
-+#include <asm/semaphore.h>
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <linux/interrupt.h> /* requires system.h */
-+
-+/*
-+ * This list is for kernel code that needs to handle
-+ * changes to devices when the CPU clock speed changes.
-+ */
-+static struct notifier_block *cpufreq_notifier_list;
-+static DECLARE_MUTEX_LOCKED(cpufreq_sem);
-+static unsigned long cpufreq_ref_loops;
-+static unsigned int cpufreq_ref_freq;
-+static int cpufreq_initialised;
-+static unsigned int (*cpufreq_validatespeed)(unsigned int);
-+static void (*cpufreq_setspeed)(unsigned int);
-+
-+#ifndef CONFIG_SMP
-+static unsigned int __cpufreq_max;
-+static unsigned int __cpufreq_min;
-+static unsigned int __cpufreq_cur;
-+#endif
-+
-+static unsigned long scale(unsigned long ref, u_int div, u_int mult)
-+{
-+ unsigned long new_jiffy_l, new_jiffy_h;
-+
-+ /*
-+ * Recalculate loops_per_jiffy. We do it this way to
-+ * avoid math overflow on 32-bit machines. Maybe we
-+ * should make this architecture dependent? If you have
-+ * a better way of doing this, please replace!
-+ *
-+ * new = old * mult / div
-+ */
-+ new_jiffy_h = ref / div;
-+ new_jiffy_l = (ref % div) / 100;
-+ new_jiffy_h *= mult;
-+ new_jiffy_l = new_jiffy_l * mult / div;
-+
-+ return new_jiffy_h + new_jiffy_l * 100;
-+}
-+
-+/*
-+ * cpufreq_max command line parameter. Use:
-+ * cpufreq=59000-221000
-+ * to set the CPU frequency to 59 to 221MHz.
-+ */
-+static int __init cpufreq_setup(char *str)
-+{
-+ unsigned int min, max;
-+ int i;
-+
-+ min = 0;
-+ max = simple_strtoul(str, &str, 0);
-+ if (*str == '-') {
-+ min = max;
-+ max = simple_strtoul(str + 1, NULL, 0);
-+ }
-+
-+ for (i = 0; i < smp_num_cpus; i++) {
-+ cpufreq_max(i) = max;
-+ cpufreq_min(i) = min;
-+ }
-+
-+ return 1;
-+}
-+
-+__setup("cpufreq=", cpufreq_setup);
-+
-+/**
-+ * cpufreq_register_notifier - register a driver with cpufreq
-+ * @nb: notifier function to register
-+ *
-+ * Add a driver to the list of drivers that which to be notified about
-+ * CPU clock rate changes. The driver will be called three times on
-+ * clock change.
-+ *
-+ * This function may sleep, and has the same return conditions as
-+ * notifier_chain_register.
-+ */
-+int cpufreq_register_notifier(struct notifier_block *nb)
-+{
-+ int ret;
-+
-+ down(&cpufreq_sem);
-+ ret = notifier_chain_register(&cpufreq_notifier_list, nb);
-+ up(&cpufreq_sem);
-+
-+ return ret;
-+}
-+
-+EXPORT_SYMBOL(cpufreq_register_notifier);
-+
-+/**
-+ * cpufreq_unregister_notifier - unregister a driver with cpufreq
-+ * @nb: notifier block to be unregistered
-+ *
-+ * Remove a driver from the CPU frequency notifier lists.
-+ *
-+ * This function may sleep, and has the same return conditions as
-+ * notifier_chain_unregister.
-+ */
-+int cpufreq_unregister_notifier(struct notifier_block *nb)
-+{
-+ int ret;
-+
-+ down(&cpufreq_sem);
-+ ret = notifier_chain_unregister(&cpufreq_notifier_list, nb);
-+ up(&cpufreq_sem);
-+
-+ return ret;
-+}
-+
-+EXPORT_SYMBOL(cpufreq_unregister_notifier);
-+
-+/*
-+ * This notifier alters the system "loops_per_jiffy" for the clock
-+ * speed change. We ignore CPUFREQ_MINMAX here.
-+ */
-+static void adjust_jiffies(unsigned long val, struct cpufreq_info *ci)
-+{
-+ if ((val == CPUFREQ_PRECHANGE && ci->old_freq < ci->new_freq) ||
-+ (val == CPUFREQ_POSTCHANGE && ci->old_freq > ci->new_freq))
-+ loops_per_jiffy = scale(cpufreq_ref_loops, cpufreq_ref_freq,
-+ ci->new_freq);
-+}
-+
-+#ifdef CONFIG_PM
-+/**
-+ * cpufreq_restore - restore the CPU clock frequency after resume
-+ *
-+ * Restore the CPU clock frequency so that our idea of the current
-+ * frequency reflects the actual hardware.
-+ */
-+int cpufreq_restore(void)
-+{
-+ unsigned long old_cpus;
-+ int cpu = smp_processor_id();
-+ int ret;
-+
-+ if (!cpufreq_initialised)
-+ panic("cpufreq_restore() called before initialisation!");
-+ if (in_interrupt())
-+ panic("cpufreq_restore() called from interrupt context!");
-+
-+ /*
-+ * Bind to the current CPU.
-+ */
-+ old_cpus = current->cpus_allowed;
-+ current->cpus_allowed = 1UL << cpu_logical_map(cpu);
-+
-+ down(&cpufreq_sem);
-+
-+ ret = -ENXIO;
-+ if (cpufreq_setspeed) {
-+ cpufreq_setspeed(cpufreq_current(cpu));
-+ ret = 0;
-+ }
-+
-+ up(&cpufreq_sem);
-+
-+ current->cpus_allowed = old_cpus;
-+
-+ return ret;
-+}
-+
-+EXPORT_SYMBOL_GPL(cpufreq_restore);
-+#endif
-+
-+/**
-+ * cpu_setfreq - change the CPU clock frequency.
-+ * @freq: frequency (in kHz) at which we should run.
-+ *
-+ * Set the CPU clock frequency, informing all registered users of
-+ * the change. We bound the frequency according to the cpufreq_max
-+ * command line parameter, and the parameters the registered users
-+ * will allow.
-+ *
-+ * This function must be called from process context, and on the
-+ * cpu that we wish to change the frequency of.
-+ *
-+ * We return 0 if successful. (we are currently always successful).
-+ */
-+int cpufreq_set(unsigned int freq)
-+{
-+ unsigned long old_cpus;
-+ struct cpufreq_info clkinfo;
-+ struct cpufreq_minmax minmax;
-+ int cpu = smp_processor_id();
-+ int ret;
-+
-+ if (!cpufreq_initialised)
-+ panic("cpufreq_set() called before initialisation!");
-+ if (in_interrupt())
-+ panic("cpufreq_set() called from interrupt context!");
-+
-+ /*
-+ * Bind to the current CPU.
-+ */
-+ old_cpus = current->cpus_allowed;
-+ current->cpus_allowed = 1UL << cpu_logical_map(cpu);
-+
-+ down(&cpufreq_sem);
-+ ret = -ENXIO;
-+ if (!cpufreq_setspeed || !cpufreq_validatespeed)
-+ goto out;
-+
-+ /*
-+ * Don't allow the CPU to be clocked over the limit.
-+ */
-+ minmax.min_freq = cpufreq_min(cpu);
-+ minmax.max_freq = cpufreq_max(cpu);
-+ minmax.cur_freq = cpufreq_current(cpu);
-+ minmax.new_freq = freq;
-+
-+ /*
-+ * Find out what the registered devices will currently tolerate,
-+ * and limit the requested clock rate to these values. Drivers
-+ * must not rely on the 'new_freq' value - it is only a guide.
-+ */
-+ notifier_call_chain(&cpufreq_notifier_list, CPUFREQ_MINMAX, &minmax);
-+ if (freq < minmax.min_freq)
-+ freq = minmax.min_freq;
-+ if (freq > minmax.max_freq)
-+ freq = minmax.max_freq;
-+
-+ /*
-+ * Ask the CPU specific code to validate the speed. If the speed
-+ * is not acceptable, make it acceptable. Current policy is to
-+ * round the frequency down to the value the processor actually
-+ * supports.
-+ */
-+ freq = cpufreq_validatespeed(freq);
-+
-+ if (cpufreq_current(cpu) != freq) {
-+ clkinfo.old_freq = cpufreq_current(cpu);
-+ clkinfo.new_freq = freq;
-+
-+ notifier_call_chain(&cpufreq_notifier_list, CPUFREQ_PRECHANGE,
-+ &clkinfo);
-+
-+ adjust_jiffies(CPUFREQ_PRECHANGE, &clkinfo);
-+
-+ /*
-+ * Actually set the CPU frequency.
-+ */
-+ cpufreq_setspeed(freq);
-+ cpufreq_current(cpu) = freq;
-+ adjust_jiffies(CPUFREQ_POSTCHANGE, &clkinfo);
-+
-+ notifier_call_chain(&cpufreq_notifier_list, CPUFREQ_POSTCHANGE,
-+ &clkinfo);
-+ }
-+
-+ ret = 0;
-+
-+ out:
-+ up(&cpufreq_sem);
-+
-+ current->cpus_allowed = old_cpus;
-+
-+ return ret;
-+}
-+
-+EXPORT_SYMBOL_GPL(cpufreq_set);
-+
-+/**
-+ * cpufreq_setmax - set the CPU to maximum frequency
-+ *
-+ * Sets the CPU this function is executed on to maximum frequency.
-+ */
-+int cpufreq_setmax(void)
-+{
-+ return cpufreq_set(cpufreq_max(smp_processor_id()));
-+}
-+
-+EXPORT_SYMBOL_GPL(cpufreq_setmax);
-+
-+/**
-+ * cpufreq_get - return the current CPU clock frequency in 1kHz
-+ * @cpu: cpu number to obtain frequency for
-+ *
-+ * Returns the specified CPUs frequency in kHz.
-+ */
-+unsigned int cpufreq_get(int cpu)
-+{
-+ if (!cpufreq_initialised)
-+ panic("cpufreq_get() called before initialisation!");
-+ return cpufreq_current(cpu);
-+}
-+
-+EXPORT_SYMBOL(cpufreq_get);
-+
-+#ifdef CONFIG_SYSCTL
-+
-+static int
-+cpufreq_procctl(ctl_table *ctl, int write, struct file *filp,
-+ void *buffer, size_t *lenp)
-+{
-+ char buf[16], *p;
-+ int cpu = 0, len, left = *lenp;
-+
-+ if (!left || (filp->f_pos && !write)) {
-+ *lenp = 0;
-+ return 0;
-+ }
-+
-+ if (write) {
-+ unsigned int freq;
-+
-+ len = left;
-+ if (left > sizeof(buf))
-+ left = sizeof(buf);
-+ if (copy_from_user(buf, buffer, left))
-+ return -EFAULT;
-+ buf[sizeof(buf) - 1] = '\0';
-+
-+ freq = simple_strtoul(buf, &p, 0);
-+ cpufreq_set(freq);
-+ } else {
-+ len = sprintf(buf, "%d\n", cpufreq_get(cpu));
-+ if (len > left)
-+ len = left;
-+ if (copy_to_user(buffer, buf, len))
-+ return -EFAULT;
-+ }
-+
-+ *lenp = len;
-+ filp->f_pos += len;
-+ return 0;
-+}
-+
-+static int
-+cpufreq_sysctl(ctl_table *table, int *name, int nlen,
-+ void *oldval, size_t *oldlenp,
-+ void *newval, size_t newlen, void **context)
-+{
-+ int cpu = 0;
-+
-+ if (oldval && oldlenp) {
-+ size_t oldlen;
-+
-+ if (get_user(oldlen, oldlenp))
-+ return -EFAULT;
-+
-+ if (oldlen != sizeof(unsigned int))
-+ return -EINVAL;
-+
-+ if (put_user(cpufreq_get(cpu), (unsigned int *)oldval) ||
-+ put_user(sizeof(unsigned int), oldlenp))
-+ return -EFAULT;
-+ }
-+ if (newval && newlen) {
-+ unsigned int freq;
-+
-+ if (newlen != sizeof(unsigned int))
-+ return -EINVAL;
-+
-+ if (get_user(freq, (unsigned int *)newval))
-+ return -EFAULT;
-+
-+ cpufreq_set(freq);
-+ }
-+ return 1;
-+}
-+
-+enum {
-+ CPU_NR_FREQ_MAX = 1,
-+ CPU_NR_FREQ_MIN = 2,
-+ CPU_NR_FREQ = 3
-+};
-+
-+static ctl_table ctl_cpu_vars[4] = {
-+ {
-+ ctl_name: CPU_NR_FREQ_MAX,
-+ procname: "speed-max",
-+ data: &cpufreq_max(0),
-+ maxlen: sizeof(cpufreq_max(0)),
-+ mode: 0444,
-+ proc_handler: proc_dointvec,
-+ },
-+ {
-+ ctl_name: CPU_NR_FREQ_MIN,
-+ procname: "speed-min",
-+ data: &cpufreq_min(0),
-+ maxlen: sizeof(cpufreq_min(0)),
-+ mode: 0444,
-+ proc_handler: proc_dointvec,
-+ },
-+ {
-+ ctl_name: CPU_NR_FREQ,
-+ procname: "speed",
-+ mode: 0644,
-+ proc_handler: cpufreq_procctl,
-+ strategy: cpufreq_sysctl,
-+ },
-+ {
-+ ctl_name: 0,
-+ }
-+};
-+
-+enum {
-+ CPU_NR = 1,
-+};
-+
-+static ctl_table ctl_cpu_nr[2] = {
-+ {
-+ ctl_name: CPU_NR,
-+ procname: "0",
-+ mode: 0555,
-+ child: ctl_cpu_vars,
-+ },
-+ {
-+ ctl_name: 0,
-+ }
-+};
-+
-+static ctl_table ctl_cpu[2] = {
-+ {
-+ ctl_name: CTL_CPU,
-+ procname: "cpu",
-+ mode: 0555,
-+ child: ctl_cpu_nr,
-+ },
-+ {
-+ ctl_name: 0,
-+ }
-+};
-+
-+static inline void cpufreq_sysctl_init(void)
-+{
-+ register_sysctl_table(ctl_cpu, 0);
-+}
-+
-+#else
-+#define cpufreq_sysctl_init()
-+#endif
-+
-+/**
-+ * cpufreq_setfunctions - Set CPU clock functions
-+ * @validate: pointer to validation function
-+ * @setspeed: pointer to setspeed function
-+ */
-+void
-+cpufreq_setfunctions(unsigned int (*validate)(unsigned int),
-+ void (*setspeed)(unsigned int))
-+{
-+ down(&cpufreq_sem);
-+ cpufreq_validatespeed = validate;
-+ cpufreq_setspeed = setspeed;
-+ up(&cpufreq_sem);
-+}
-+
-+EXPORT_SYMBOL_GPL(cpufreq_setfunctions);
-+
-+/**
-+ * cpufreq_init - Initialise the cpufreq core
-+ * @freq: current CPU clock speed.
-+ * @min_freq: minimum CPU clock speed.
-+ * @max_freq: maximum CPU clock speed.
-+ *
-+ * Initialise the cpufreq core. If the cpufreq_max command line
-+ * parameter has not been specified, we set the maximum clock rate
-+ * to the current CPU clock rate.
-+ */
-+void cpufreq_init(unsigned int freq,
-+ unsigned int min_freq,
-+ unsigned int max_freq)
-+{
-+ /*
-+ * If the user doesn't tell us their maximum frequency,
-+ * or if it is invalid, use the values determined
-+ * by the cpufreq-arch-specific initialization functions.
-+ * The validatespeed code is responsible for limiting
-+ * this further.
-+ */
-+ if (max_freq && ((cpufreq_max(0) == 0) || (cpufreq_max(0) > max_freq)))
-+ cpufreq_max(0) = max_freq;
-+ if (min_freq && ((cpufreq_min(0) == 0) || (cpufreq_min(0) < min_freq)))
-+ cpufreq_min(0) = min_freq;
-+
-+ if (cpufreq_max(0) == 0)
-+ cpufreq_max(0) = freq;
-+
-+ printk(KERN_INFO "CPU clock: %d.%03d MHz (%d.%03d-%d.%03d MHz)\n",
-+ freq / 1000, freq % 1000,
-+ cpufreq_min(0) / 1000, cpufreq_min(0) % 1000,
-+ cpufreq_max(0) / 1000, cpufreq_max(0) % 1000);
-+
-+ cpufreq_ref_loops = loops_per_jiffy;
-+ cpufreq_ref_freq = freq;
-+ cpufreq_current(smp_processor_id()) = freq;
-+
-+ cpufreq_initialised = 1;
-+ up(&cpufreq_sem);
-+
-+ cpufreq_sysctl_init();
-+}
-+
-+EXPORT_SYMBOL_GPL(cpufreq_init);
---- linux-2.4.25/kernel/exit.c~2.4.25-vrs2.patch 2002-11-29 00:53:15.000000000 +0100
-+++ linux-2.4.25/kernel/exit.c 2004-03-31 17:15:09.000000000 +0200
-@@ -587,7 +587,7 @@
- return retval;
- }
-
--#if !defined(__alpha__) && !defined(__ia64__)
-+#if !defined(__alpha__) && !defined(__ia64__) && !defined(__arm__)
-
- /*
- * sys_waitpid() remains for compatibility. waitpid() should be
---- linux-2.4.25/kernel/fork.c~2.4.25-vrs2.patch 2004-02-18 14:36:32.000000000 +0100
-+++ linux-2.4.25/kernel/fork.c 2004-03-31 17:15:09.000000000 +0200
-@@ -75,7 +75,11 @@
- * value: the thread structures can take up at most half
- * of memory.
- */
-+#if THREAD_SIZE > PAGE_SIZE
- max_threads = mempages / (THREAD_SIZE/PAGE_SIZE) / 8;
-+#else
-+ max_threads = (mempages * PAGE_SIZE) / (8 * THREAD_SIZE);
-+#endif
-
- init_task.rlim[RLIMIT_NPROC].rlim_cur = max_threads/2;
- init_task.rlim[RLIMIT_NPROC].rlim_max = max_threads/2;
-@@ -220,6 +224,7 @@
-
- fail_nomem:
- flush_tlb_mm(current->mm);
-+ memc_update_mm(mm);
- return retval;
- }
-
---- linux-2.4.25/kernel/ksyms.c~2.4.25-vrs2.patch 2004-02-18 14:36:32.000000000 +0100
-+++ linux-2.4.25/kernel/ksyms.c 2004-03-31 17:15:09.000000000 +0200
-@@ -345,6 +345,7 @@
-
- /* tty routines */
- EXPORT_SYMBOL(tty_hangup);
-+EXPORT_SYMBOL(tty_vhangup);
- EXPORT_SYMBOL(tty_wait_until_sent);
- EXPORT_SYMBOL(tty_check_change);
- EXPORT_SYMBOL(tty_hung_up_p);
-@@ -439,9 +440,11 @@
- EXPORT_SYMBOL(kiobuf_wait_for_io);
-
- /* dma handling */
-+#ifdef CONFIG_GENERIC_ISA_DMA
- EXPORT_SYMBOL(request_dma);
- EXPORT_SYMBOL(free_dma);
- EXPORT_SYMBOL(dma_spin_lock);
-+#endif
- #ifdef HAVE_DISABLE_HLT
- EXPORT_SYMBOL(disable_hlt);
- EXPORT_SYMBOL(enable_hlt);
---- linux-2.4.25/kernel/signal.c~2.4.25-vrs2.patch 2004-02-18 14:36:32.000000000 +0100
-+++ linux-2.4.25/kernel/signal.c 2004-03-31 17:15:09.000000000 +0200
-@@ -778,8 +778,8 @@
- info.si_uid = tsk->uid;
-
- /* FIXME: find out whether or not this is supposed to be c*time. */
-- info.si_utime = tsk->times.tms_utime;
-- info.si_stime = tsk->times.tms_stime;
-+ info.si_utime = hz_to_std(tsk->times.tms_utime);
-+ info.si_stime = hz_to_std(tsk->times.tms_stime);
-
- status = tsk->exit_code & 0x7f;
- why = SI_KERNEL; /* shouldn't happen */
-@@ -1277,7 +1277,7 @@
- #endif /* __sparc__ */
- #endif
-
--#if !defined(__alpha__) && !defined(__ia64__)
-+#if !defined(__alpha__) && !defined(__ia64__) && !defined(__arm__)
- /*
- * For backwards compatibility. Functionality superseded by sigprocmask.
- */
-@@ -1305,7 +1305,8 @@
- }
- #endif /* !defined(__alpha__) */
-
--#if !defined(__alpha__) && !defined(__ia64__) && !defined(__mips__)
-+#if !defined(__alpha__) && !defined(__ia64__) && !defined(__mips__) && \
-+ !defined(__arm__)
- /*
- * For backwards compatibility. Functionality superseded by sigaction.
- */
-@@ -1322,4 +1323,4 @@
-
- return ret ? ret : (unsigned long)old_sa.sa.sa_handler;
- }
--#endif /* !alpha && !__ia64__ && !defined(__mips__) */
-+#endif /* !alpha && !__ia64__ && !defined(__mips__) && !defined(__arm__) */
---- linux-2.4.25/kernel/sys.c~2.4.25-vrs2.patch 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.25/kernel/sys.c 2004-03-31 17:15:09.000000000 +0200
-@@ -801,16 +801,23 @@
-
- asmlinkage long sys_times(struct tms * tbuf)
- {
-+ struct tms temp;
-+
- /*
- * In the SMP world we might just be unlucky and have one of
- * the times increment as we use it. Since the value is an
- * atomically safe type this is just fine. Conceptually its
- * as if the syscall took an instant longer to occur.
- */
-- if (tbuf)
-- if (copy_to_user(tbuf, &current->times, sizeof(struct tms)))
-+ if (tbuf) {
-+ temp.tms_utime = hz_to_std(current->times.tms_utime);
-+ temp.tms_stime = hz_to_std(current->times.tms_stime);
-+ temp.tms_cutime = hz_to_std(current->times.tms_cutime);
-+ temp.tms_cstime = hz_to_std(current->times.tms_cstime);
-+ if (copy_to_user(tbuf, &temp, sizeof(struct tms)))
- return -EFAULT;
-- return jiffies;
-+ }
-+ return hz_to_std(jiffies);
- }
-
- /*
---- linux-2.4.25/lib/string.c~2.4.25-vrs2.patch 2002-08-03 02:39:46.000000000 +0200
-+++ linux-2.4.25/lib/string.c 2004-03-31 17:15:09.000000000 +0200
-@@ -188,10 +188,10 @@
- */
- char * strchr(const char * s, int c)
- {
-- for(; *s != (char) c; ++s)
-- if (*s == '\0')
-- return NULL;
-- return (char *) s;
-+ for(; *s != '\0'; ++s)
-+ if (*s == (char) c)
-+ return (char *) s;
-+ return NULL;
- }
- #endif
-
---- linux-2.4.25/mm/Makefile~2.4.25-vrs2.patch 2002-08-03 02:39:46.000000000 +0200
-+++ linux-2.4.25/mm/Makefile 2004-03-31 17:15:09.000000000 +0200
-@@ -18,4 +18,5 @@
-
- obj-$(CONFIG_HIGHMEM) += highmem.o
-
-+obj-y += debug.o
- include $(TOPDIR)/Rules.make
---- /dev/null 2003-09-23 19:59:22.000000000 +0200
-+++ linux-2.4.25/mm/debug.c 2004-03-31 17:15:09.000000000 +0200
-@@ -0,0 +1,159 @@
-+/*
-+ * linux/mm/debug.c
-+ *
-+ * Copyright (C) 2001 Russell King.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Dump out page information on SysRQ-G, and provide show_page_info()
-+ *
-+ * You are advised to use a serial console with this patch - it
-+ * saturates a 38400baud link for 1 minute on a 32MB machine.
-+ */
-+#include <linux/kernel.h>
-+#include <linux/mm.h>
-+#include <linux/pagemap.h>
-+#include <linux/sysrq.h>
-+#include <linux/init.h>
-+
-+/*
-+ * We print out the following information for each page in the system:
-+ * address: use count, age, mapping, [RSsr] rD [acd]
-+ *
-+ * The flags are:
-+ * R - reserved
-+ * S - in swapcache
-+ * s - slab page
-+ *
-+ * r - referenced
-+ * D - dirty
-+ *
-+ * a - active page
-+ */
-+static void page_detail(struct page *page)
-+{
-+ if (!page)
-+ return;
-+
-+ printk("%p: %2d %p [%c%c%c] %c%c [%c]\n",
-+ page_address(page),
-+ page_count(page),
-+ page->mapping,
-+
-+ PageReserved(page) ? 'R' : '-',
-+ PageSwapCache(page) ? 'S' : '-',
-+ PageSlab(page) ? 's' : '-',
-+
-+ PageReferenced(page) ? 'r' : '-',
-+ PageDirty(page) ? 'D' : '-',
-+
-+ PageActive(page) ? 'a' : '-');
-+}
-+
-+/*
-+ * This version collects statistics
-+ */
-+static int anon_pages, slab_pages, resvd_pages, unused_pages;
-+
-+static void page_statistics(struct page *page)
-+{
-+ if (page) {
-+ if (PageReserved(page))
-+ resvd_pages++;
-+ else if (PageSlab(page))
-+ slab_pages++;
-+ else if (!page_count(page))
-+ unused_pages ++;
-+ else if (!page->mapping)
-+ anon_pages ++;
-+ return;
-+ }
-+
-+ printk(" anon: %d, slab: %d, reserved: %d, free: %d\n",
-+ anon_pages, slab_pages, resvd_pages, unused_pages);
-+}
-+
-+static void show_zone_info(zone_t *zone, void (*fn)(struct page *))
-+{
-+ int i;
-+
-+ printk(" total %ld, free %ld\n",
-+ zone->size, zone->free_pages);
-+
-+ anon_pages = 0;
-+ slab_pages = 0;
-+ resvd_pages = 0;
-+ unused_pages = 0;
-+
-+ for (i = 0; i < zone->size; i++) {
-+ struct page *page = zone->zone_mem_map + i;
-+
-+ fn(page);
-+ }
-+
-+ fn(NULL);
-+}
-+
-+static void show_node_info(pg_data_t *pg, void (*fn)(struct page *))
-+{
-+ int type;
-+
-+ for (type = 0; type < MAX_NR_ZONES; type++) {
-+ zone_t *zone = pg->node_zones + type;
-+
-+ if (zone->size == 0)
-+ continue;
-+
-+ printk("----- Zone %d ------\n", type);
-+
-+ show_zone_info(zone, fn);
-+ }
-+}
-+
-+static void __show_page_info(void (*fn)(struct page *))
-+{
-+ pg_data_t *pg;
-+ int pgdat = 0;
-+
-+ for (pg = pgdat_list; pg; pg = pg->node_next) {
-+
-+ printk("===== Node %d =====\n", pgdat++);
-+
-+ show_node_info(pg, fn);
-+ }
-+}
-+
-+void show_page_info(void)
-+{
-+ __show_page_info(page_detail);
-+}
-+
-+static void
-+show_pg_info(int key, struct pt_regs *regs, struct kbd_struct *kd,
-+ struct tty_struct *tty)
-+{
-+ void (*fn)(struct page *);
-+ show_mem();
-+ if (key == 'g')
-+ fn = page_detail;
-+ else
-+ fn = page_statistics;
-+ __show_page_info(fn);
-+}
-+
-+static struct sysrq_key_op page_info_op = {
-+ handler: show_pg_info,
-+ help_msg: "paGeinfo",
-+ action_msg: "Page Info",
-+};
-+
-+static int __init debug_mm_init(void)
-+{
-+ register_sysrq_key('g', &page_info_op);
-+ register_sysrq_key('h', &page_info_op);
-+ return 0;
-+}
-+
-+__initcall(debug_mm_init);
---- linux-2.4.25/mm/filemap.c~2.4.25-vrs2.patch 2004-02-18 14:36:32.000000000 +0100
-+++ linux-2.4.25/mm/filemap.c 2004-03-31 17:15:09.000000000 +0200
-@@ -2210,10 +2210,14 @@
- pte_t pte = *ptep;
-
- if (pte_present(pte)) {
-- struct page *page = pte_page(pte);
-- if (VALID_PAGE(page) && !PageReserved(page) && ptep_test_and_clear_dirty(ptep)) {
-- flush_tlb_page(vma, address);
-- set_page_dirty(page);
-+ unsigned long pfn = pte_pfn(pte);
-+
-+ if (pfn_valid(pfn)) {
-+ struct page *page = pfn_to_page(pfn);
-+ if (!PageReserved(page) && ptep_test_and_clear_dirty(ptep)) {
-+ flush_tlb_page(vma, address);
-+ set_page_dirty(page);
-+ }
- }
- }
- return 0;
---- linux-2.4.25/mm/memory.c~2.4.25-vrs2.patch 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.25/mm/memory.c 2004-03-31 17:15:09.000000000 +0200
-@@ -77,8 +77,13 @@
- */
- void __free_pte(pte_t pte)
- {
-- struct page *page = pte_page(pte);
-- if ((!VALID_PAGE(page)) || PageReserved(page))
-+ unsigned long pfn = pte_pfn(pte);
-+ struct page *page;
-+
-+ if (!pfn_valid(pfn))
-+ return;
-+ page = pfn_to_page(pfn);
-+ if (PageReserved(page))
- return;
- if (pte_dirty(pte))
- set_page_dirty(page);
-@@ -232,6 +237,7 @@
- do {
- pte_t pte = *src_pte;
- struct page *ptepage;
-+ unsigned long pfn;
-
- /* copy_one_pte */
-
-@@ -241,9 +247,11 @@
- swap_duplicate(pte_to_swp_entry(pte));
- goto cont_copy_pte_range;
- }
-- ptepage = pte_page(pte);
-- if ((!VALID_PAGE(ptepage)) ||
-- PageReserved(ptepage))
-+ pfn = pte_pfn(pte);
-+ if (!pfn_valid(pfn))
-+ goto cont_copy_pte_range;
-+ ptepage = pfn_to_page(pfn);
-+ if (PageReserved(ptepage))
- goto cont_copy_pte_range;
-
- /* If it's a COW mapping, write protect it both in the parent and the child */
-@@ -314,9 +322,13 @@
- if (pte_none(pte))
- continue;
- if (pte_present(pte)) {
-- struct page *page = pte_page(pte);
-- if (VALID_PAGE(page) && !PageReserved(page))
-- freed ++;
-+ unsigned long pfn = pte_pfn(pte);
-+
-+ if (pfn_valid(pfn)) {
-+ struct page *page = pfn_to_page(pfn);
-+ if (!PageReserved(page))
-+ freed ++;
-+ }
- /* This will eventually call __free_pte on the pte. */
- tlb_remove_page(tlb, ptep, address + offset);
- } else {
-@@ -354,17 +366,37 @@
- return freed;
- }
-
-+void unmap_page_range(mmu_gather_t *tlb, struct mm_struct *mm, unsigned long address, unsigned long end)
-+{
-+ int freed = 0;
-+ pgd_t * dir;
-+
-+ if (address >= end)
-+ BUG();
-+ dir = pgd_offset(mm, address);
-+ do {
-+ freed += zap_pmd_range(tlb, dir, address, end - address);
-+ address = (address + PGDIR_SIZE) & PGDIR_MASK;
-+ dir++;
-+ } while (address && (address < end));
-+
-+ /*
-+ * Update rss for the mm_struct (not necessarily current->mm)
-+ * Notice that rss is an unsigned long.
-+ */
-+ if (mm->rss > freed)
-+ mm->rss -= freed;
-+ else
-+ mm->rss = 0;
-+}
-+
- /*
- * remove user pages in a given range.
- */
- void zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long size)
- {
-- mmu_gather_t *tlb;
-- pgd_t * dir;
- unsigned long start = address, end = address + size;
-- int freed = 0;
--
-- dir = pgd_offset(mm, address);
-+ mmu_gather_t *tlb;
-
- /*
- * This is a long-lived spinlock. That's fine.
-@@ -377,25 +409,10 @@
- BUG();
- spin_lock(&mm->page_table_lock);
- flush_cache_range(mm, address, end);
-- tlb = tlb_gather_mmu(mm);
-
-- do {
-- freed += zap_pmd_range(tlb, dir, address, end - address);
-- address = (address + PGDIR_SIZE) & PGDIR_MASK;
-- dir++;
-- } while (address && (address < end));
--
-- /* this will flush any remaining tlb entries */
-+ tlb = tlb_gather_mmu(mm);
-+ unmap_page_range(tlb, mm, address, end);
- tlb_finish_mmu(tlb, start, end);
--
-- /*
-- * Update rss for the mm_struct (not necessarily current->mm)
-- * Notice that rss is an unsigned long.
-- */
-- if (mm->rss > freed)
-- mm->rss -= freed;
-- else
-- mm->rss = 0;
- spin_unlock(&mm->page_table_lock);
- }
-
-@@ -407,6 +424,7 @@
- pgd_t *pgd;
- pmd_t *pmd;
- pte_t *ptep, pte;
-+ unsigned long pfn;
-
- pgd = pgd_offset(mm, address);
- if (pgd_none(*pgd) || pgd_bad(*pgd))
-@@ -423,8 +441,11 @@
- pte = *ptep;
- if (pte_present(pte)) {
- if (!write ||
-- (pte_write(pte) && pte_dirty(pte)))
-- return pte_page(pte);
-+ (pte_write(pte) && pte_dirty(pte))) {
-+ pfn = pte_pfn(pte);
-+ if (pfn_valid(pfn))
-+ return pfn_to_page(pfn);
-+ }
- }
-
- out:
-@@ -439,7 +460,8 @@
-
- static inline struct page * get_page_map(struct page *page)
- {
-- if (!VALID_PAGE(page))
-+ unsigned long pfn = page_to_pfn(page);
-+ if (!pfn_valid(pfn))
- return 0;
- return page;
- }
-@@ -826,22 +848,22 @@
- unsigned long phys_addr, pgprot_t prot)
- {
- unsigned long end;
-+ unsigned long pfn;
-
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
- end = PMD_SIZE;
-+ pfn = phys_addr >> PAGE_SHIFT;
- do {
-- struct page *page;
- pte_t oldpage;
- oldpage = ptep_get_and_clear(pte);
-
-- page = virt_to_page(__va(phys_addr));
-- if ((!VALID_PAGE(page)) || PageReserved(page))
-- set_pte(pte, mk_pte_phys(phys_addr, prot));
-+ if (!pfn_valid(pfn) || PageReserved(pfn_to_page(pfn)))
-+ set_pte(pte, pfn_pte(pfn, prot));
- forget_pte(oldpage);
- address += PAGE_SIZE;
-- phys_addr += PAGE_SIZE;
-+ pfn++;
- pte++;
- } while (address && (address < end));
- }
-@@ -949,10 +971,11 @@
- unsigned long address, pte_t *page_table, pte_t pte)
- {
- struct page *old_page, *new_page;
-+ unsigned long pfn = pte_pfn(pte);
-
-- old_page = pte_page(pte);
-- if (!VALID_PAGE(old_page))
-+ if (!pfn_valid(pfn))
- goto bad_wp_page;
-+ old_page = pte_page(pte);
-
- if (!TryLockPage(old_page)) {
- int reuse = can_share_swap_page(old_page);
-@@ -996,7 +1019,7 @@
-
- bad_wp_page:
- spin_unlock(&mm->page_table_lock);
-- printk("do_wp_page: bogus page at address %08lx (page 0x%lx)\n",address,(unsigned long)old_page);
-+ printk("do_wp_page: bogus page at address %08lx\n", address);
- return -1;
- no_mem:
- page_cache_release(old_page);
---- linux-2.4.25/mm/mmap.c~2.4.25-vrs2.patch 2004-02-18 14:36:32.000000000 +0100
-+++ linux-2.4.25/mm/mmap.c 2004-03-31 17:15:09.000000000 +0200
-@@ -18,6 +18,9 @@
-
- #include <asm/uaccess.h>
- #include <asm/pgalloc.h>
-+#include <asm/tlb.h>
-+
-+extern void unmap_page_range(mmu_gather_t *tlb, struct mm_struct *mm, unsigned long start, unsigned long end);
-
- /*
- * WARNING: the debugging will use recursive algorithms so never enable this
-@@ -915,6 +918,8 @@
- * old method of shifting the VA >> by PGDIR_SHIFT doesn't work.
- */
- start_index = pgd_index(first);
-+ if (start_index < FIRST_USER_PGD_NR)
-+ start_index = FIRST_USER_PGD_NR;
- end_index = pgd_index(last);
- if (end_index > start_index) {
- clear_page_tables(mm, start_index, end_index - start_index);
-@@ -1046,7 +1051,6 @@
- len = PAGE_ALIGN(len);
- if (!len)
- return addr;
--
- if ((addr + len) > TASK_SIZE || (addr + len) < addr)
- return -EINVAL;
-
-@@ -1135,45 +1139,58 @@
- /* Release all mmaps. */
- void exit_mmap(struct mm_struct * mm)
- {
-+ mmu_gather_t *tlb;
- struct vm_area_struct * mpnt;
-
- release_segments(mm);
- spin_lock(&mm->page_table_lock);
-+
-+ tlb = tlb_gather_mmu(mm);
-+
-+ flush_cache_mm(mm);
-+ mpnt = mm->mmap;
-+ while (mpnt) {
-+ unsigned long start = mpnt->vm_start;
-+ unsigned long end = mpnt->vm_end;
-+
-+ mm->map_count--;
-+ remove_shared_vm_struct(mpnt);
-+ unmap_page_range(tlb, mm, start, end);
-+ mpnt = mpnt->vm_next;
-+ }
-+
-+ /* This is just debugging */
-+ if (mm->map_count)
-+ BUG();
-+
-+ tlb_finish_mmu(tlb, 0, TASK_SIZE);
-+
- mpnt = mm->mmap;
- mm->mmap = mm->mmap_cache = NULL;
- mm->mm_rb = RB_ROOT;
- mm->rss = 0;
-- spin_unlock(&mm->page_table_lock);
- mm->total_vm = 0;
- mm->locked_vm = 0;
-
-- flush_cache_mm(mm);
-+ spin_unlock(&mm->page_table_lock);
-+
-+ clear_page_tables(mm, FIRST_USER_PGD_NR, USER_PTRS_PER_PGD);
-+
-+ /*
-+ * Walk the list again, actually closing and freeing it
-+ * without holding any MM locks.
-+ */
- while (mpnt) {
- struct vm_area_struct * next = mpnt->vm_next;
-- unsigned long start = mpnt->vm_start;
-- unsigned long end = mpnt->vm_end;
-- unsigned long size = end - start;
--
- if (mpnt->vm_ops) {
- if (mpnt->vm_ops->close)
- mpnt->vm_ops->close(mpnt);
- }
-- mm->map_count--;
-- remove_shared_vm_struct(mpnt);
-- zap_page_range(mm, start, size);
- if (mpnt->vm_file)
- fput(mpnt->vm_file);
- kmem_cache_free(vm_area_cachep, mpnt);
- mpnt = next;
- }
--
-- /* This is just debugging */
-- if (mm->map_count)
-- BUG();
--
-- clear_page_tables(mm, FIRST_USER_PGD_NR, USER_PTRS_PER_PGD);
--
-- flush_tlb_mm(mm);
- }
-
- /* Insert vm structure into process list sorted by address
---- linux-2.4.25/mm/slab.c~2.4.25-vrs2.patch 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.25/mm/slab.c 2004-03-31 17:15:09.000000000 +0200
-@@ -1391,7 +1391,7 @@
- #if DEBUG
- # define CHECK_NR(pg) \
- do { \
-- if (!VALID_PAGE(pg)) { \
-+ if (!virt_addr_valid(pg)) { \
- printk(KERN_ERR "kfree: out of range ptr %lxh.\n", \
- (unsigned long)objp); \
- BUG(); \
-@@ -1950,12 +1950,12 @@
- name = cachep->name;
- {
- char tmp;
-- mm_segment_t old_fs;
-+ mm_segment_t old_fs;
- old_fs = get_fs();
- set_fs(KERNEL_DS);
- if (__get_user(tmp, name))
- name = "broken";
-- set_fs(old_fs);
-+ set_fs (old_fs);
- }
-
- seq_printf(m, "%-17s %6lu %6lu %6u %4lu %4lu %4u",
---- linux-2.4.25/mm/vmalloc.c~2.4.25-vrs2.patch 2003-08-25 13:44:44.000000000 +0200
-+++ linux-2.4.25/mm/vmalloc.c 2004-03-31 17:15:09.000000000 +0200
-@@ -44,8 +44,13 @@
- if (pte_none(page))
- continue;
- if (pte_present(page)) {
-- struct page *ptpage = pte_page(page);
-- if (VALID_PAGE(ptpage) && (!PageReserved(ptpage)))
-+ unsigned long pfn = pte_pfn(page);
-+ struct page *ptpage;
-+
-+ if (!pfn_valid(pfn))
-+ continue;
-+ ptpage = pfn_to_page(pfn);
-+ if (!PageReserved(ptpage))
- __free_page(ptpage);
- continue;
- }
---- linux-2.4.25/mm/vmscan.c~2.4.25-vrs2.patch 2004-02-18 14:36:32.000000000 +0100
-+++ linux-2.4.25/mm/vmscan.c 2004-03-31 17:15:09.000000000 +0200
-@@ -121,6 +121,7 @@
- drop_pte:
- mm->rss--;
- UnlockPage(page);
-+ memc_clear(vma->vm_mm, page);
- {
- int freeable = page_count(page) - !!page->buffers <= 2;
- page_cache_release(page);
-@@ -206,13 +207,16 @@
-
- do {
- if (pte_present(*pte)) {
-- struct page *page = pte_page(*pte);
-+ unsigned long pfn = pte_pfn(*pte);
-
-- if (VALID_PAGE(page) && !PageReserved(page)) {
-- count -= try_to_swap_out(mm, vma, address, pte, page, classzone);
-- if (!count) {
-- address += PAGE_SIZE;
-- break;
-+ if (pfn_valid(pfn)) {
-+ struct page *page = pfn_to_page(pfn);
-+ if (!PageReserved(page)) {
-+ count -= try_to_swap_out(mm, vma, address, pte, page, classzone);
-+ if (!count) {
-+ address += PAGE_SIZE;
-+ break;
-+ }
- }
- }
- }
---- linux-2.4.25/net/irda/af_irda.c~2.4.25-vrs2.patch 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.25/net/irda/af_irda.c 2004-03-31 17:15:09.000000000 +0200
-@@ -1176,7 +1176,7 @@
- #endif /* CONFIG_IRDA_ULTRA */
- kfree(self);
- MOD_DEC_USE_COUNT;
--
-+
- return;
- }
-
-@@ -2571,19 +2571,15 @@
- sock_register(&irda_family_ops);
-
- irda_packet_type.type = htons(ETH_P_IRDA);
-- dev_add_pack(&irda_packet_type);
-+ dev_add_pack(&irda_packet_type);
-
- register_netdevice_notifier(&irda_dev_notifier);
--
- irda_init();
- #ifdef MODULE
-- irda_device_init(); /* Called by init/main.c when non-modular */
-+ irda_device_init(); /* Called by init/main.c when non-modular */
- #endif
- return 0;
- }
--#ifdef MODULE
--module_init(irda_proto_init); /* If non-module, called from init/main.c */
--#endif
-
- /*
- * Function irda_proto_cleanup (void)
-@@ -2591,25 +2587,27 @@
- * Remove IrDA protocol layer
- *
- */
--#ifdef MODULE
--void irda_proto_cleanup(void)
-+static void __exit irda_proto_cleanup(void)
- {
- irda_packet_type.type = htons(ETH_P_IRDA);
-- dev_remove_pack(&irda_packet_type);
-+ dev_remove_pack(&irda_packet_type);
-+
-+ unregister_netdevice_notifier(&irda_dev_notifier);
-
-- unregister_netdevice_notifier(&irda_dev_notifier);
--
- sock_unregister(PF_IRDA);
-+
- irda_cleanup();
--
-- return;
- }
-+
-+#ifdef MODULE
-+module_init(irda_proto_init);
- module_exit(irda_proto_cleanup);
--
-+
- MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
--MODULE_DESCRIPTION("The Linux IrDA Protocol Subsystem");
-+MODULE_DESCRIPTION("The Linux IrDA Protocol Subsystem");
- MODULE_LICENSE("GPL");
- #ifdef CONFIG_IRDA_DEBUG
- MODULE_PARM(irda_debug, "1l");
- #endif
--#endif /* MODULE */
-+#endif
-+
---- linux-2.4.25/net/irda/iriap.c~2.4.25-vrs2.patch 2002-11-29 00:53:16.000000000 +0100
-+++ linux-2.4.25/net/irda/iriap.c 2004-03-31 17:15:09.000000000 +0200
-@@ -1004,18 +1004,20 @@
-
- switch (attrib->value->type) {
- case IAS_INTEGER:
-- len += sprintf(buf+len, "%d\n",
-+ len += sprintf(buf+len, "%d",
- attrib->value->t.integer);
- break;
- case IAS_STRING:
-- len += sprintf(buf+len, "\"%s\"\n",
-+ len += sprintf(buf+len, "\"%s\"",
- attrib->value->t.string);
- break;
- case IAS_OCT_SEQ:
-- len += sprintf(buf+len, "octet sequence (%d bytes)\n", attrib->value->len);
-+ len += sprintf(buf+len,
-+ "octet sequence (%d bytes)",
-+ attrib->value->len);
- break;
- case IAS_MISSING:
-- len += sprintf(buf+len, "missing\n");
-+ len += sprintf(buf+len, "missing");
- break;
- default:
- IRDA_DEBUG(0, "%s(), Unknown value type!\n", __FUNCTION__);
-@@ -1027,6 +1029,7 @@
- hashbin_get_next(obj->attribs);
- }
- obj = (struct ias_object *) hashbin_get_next(objects);
-+ len += sprintf(buf+len, "\n");
- }
- restore_flags(flags);
-
---- linux-2.4.25/net/irda/irlan/irlan_common.c~2.4.25-vrs2.patch 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.25/net/irda/irlan/irlan_common.c 2004-03-31 17:15:09.000000000 +0200
-@@ -317,6 +317,9 @@
-
- del_timer(&self->watchdog_timer);
-
-+ /* since irlan_do_*_event gobble the skb, we must get it once -- rmk */
-+ skb_get(skb);
-+
- /* If you want to pass the skb to *both* state machines, you will
- * need to skb_clone() it, so that you don't free it twice.
- * As the state machines don't need it, git rid of it here...
---- linux-2.4.25/net/irda/irlap_event.c~2.4.25-vrs2.patch 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.25/net/irda/irlap_event.c 2004-03-31 17:15:09.000000000 +0200
-@@ -532,7 +532,7 @@
- #endif /* CONFIG_IRDA_ULTRA */
- case RECV_TEST_CMD:
- /* Remove test frame header */
-- skb_pull(skb, sizeof(struct test_frame));
-+ skb_pull(skb, 10 /*sizeof(struct test_frame)*/);
-
- /*
- * Send response. This skb will not be sent out again, and
-@@ -740,7 +740,7 @@
-
- switch (event) {
- case CONNECT_RESPONSE:
-- skb_pull(skb, sizeof(struct snrm_frame));
-+ skb_pull(skb, 11 /*sizeof(struct snrm_frame)*/);
-
- ASSERT(self->netdev != NULL, return -1;);
-
-@@ -870,7 +870,7 @@
-
- ASSERT(self->netdev != NULL, return -1;);
-
-- skb_pull(skb, sizeof(struct snrm_frame));
-+ skb_pull(skb, 11 /*sizeof(struct snrm_frame)*/);
-
- irlap_qos_negotiate(self, skb);
-
-@@ -902,7 +902,7 @@
- /* Negotiate connection parameters */
- ASSERT(skb->len > 10, return -1;);
-
-- skb_pull(skb, sizeof(struct ua_frame));
-+ skb_pull(skb, 10 /*sizeof(struct ua_frame)*/);
-
- ASSERT(self->netdev != NULL, return -1;);
-
---- linux-2.4.25/net/irda/irlap_frame.c~2.4.25-vrs2.patch 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.25/net/irda/irlap_frame.c 2004-03-31 17:15:09.000000000 +0200
-@@ -1,5 +1,5 @@
- /*********************************************************************
-- *
-+ *
- * Filename: irlap_frame.c
- * Version: 1.0
- * Description: Build and transmit IrLAP frames
-@@ -8,18 +8,18 @@
- * Created at: Tue Aug 19 10:27:26 1997
- * Modified at: Wed Jan 5 08:59:04 2000
- * Modified by: Dag Brattli <dagb@cs.uit.no>
-- *
-- * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
-+ *
-+ * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
- * All Rights Reserved.
- * Copyright (c) 2000-2001 Jean Tourrilhes <jt@hpl.hp.com>
-- *
-- * 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
-+ *
-+ * 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.
- *
- * Neither Dag Brattli nor University of Tromsø admit liability nor
-- * provide warranty for any of this software. This material is
-+ * provide warranty for any of this software. This material is
- * provided "AS-IS" and at no charge.
- *
- ********************************************************************/
-@@ -29,11 +29,12 @@
- #include <linux/if_ether.h>
- #include <linux/netdevice.h>
- #include <linux/irda.h>
--
-+
- #include <net/pkt_sched.h>
- #include <net/sock.h>
--
-+
- #include <asm/byteorder.h>
-+#include <asm/unaligned.h>
-
- #include <net/irda/irda.h>
- #include <net/irda/irda_device.h>
-@@ -46,18 +47,18 @@
- /*
- * Function irlap_insert_info (self, skb)
- *
-- * Insert minimum turnaround time and speed information into the skb. We
-+ * Insert minimum turnaround time and speed information into the skb. We
- * need to do this since it's per packet relevant information. Safe to
- * have this function inlined since it's only called from one place
- */
--static inline void irlap_insert_info(struct irlap_cb *self,
-+static inline void irlap_insert_info(struct irlap_cb *self,
- struct sk_buff *skb)
- {
- struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
-
-- /*
-+ /*
- * Insert MTT (min. turn time) and speed into skb, so that the
-- * device driver knows which settings to use
-+ * device driver knows which settings to use
- */
- cb->magic = LAP_MAGIC;
- cb->mtt = self->mtt_required;
-@@ -65,15 +66,15 @@
-
- /* Reset */
- self->mtt_required = 0;
--
-- /*
-- * Delay equals negotiated BOFs count, plus the number of BOFs to
-- * force the negotiated minimum turnaround time
-+
-+ /*
-+ * Delay equals negotiated BOFs count, plus the number of BOFs to
-+ * force the negotiated minimum turnaround time
- */
- cb->xbofs = self->bofs_count;
- cb->next_xbofs = self->next_bofs;
- cb->xbofs_delay = self->xbofs_delay;
--
-+
- /* Reset XBOF's delay (used only for getting min turn time) */
- self->xbofs_delay = 0;
- /* Put the correct xbofs value for the next packet */
-@@ -104,7 +105,7 @@
- *
- * Transmits a connect SNRM command frame
- */
--void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos)
-+void irlap_send_snrm_frame(struct irlap_cb *self, struct qos_info *qos)
- {
- struct sk_buff *skb;
- struct snrm_frame *frame;
-@@ -118,7 +119,7 @@
- if (!skb)
- return;
-
-- frame = (struct snrm_frame *) skb_put(skb, 2);
-+ frame = (struct snrm_frame *) skb_put(skb, 2);
-
- /* Insert connection address field */
- if (qos)
-@@ -128,17 +129,17 @@
-
- /* Insert control field */
- frame->control = SNRM_CMD | PF_BIT;
--
-+
- /*
-- * If we are establishing a connection then insert QoS paramerters
-+ * If we are establishing a connection then insert QoS paramerters
- */
- if (qos) {
- skb_put(skb, 9); /* 21 left */
-- frame->saddr = cpu_to_le32(self->saddr);
-- frame->daddr = cpu_to_le32(self->daddr);
-+ put_unaligned(cpu_to_le32(self->saddr), &frame->saddr);
-+ put_unaligned(cpu_to_le32(self->daddr), &frame->daddr);
-
- frame->ncaddr = self->caddr;
--
-+
- ret = irlap_insert_qos_negotiation_params(self, skb);
- if (ret < 0) {
- dev_kfree_skb(skb);
-@@ -154,13 +155,13 @@
- * Received SNRM (Set Normal Response Mode) command frame
- *
- */
--static void irlap_recv_snrm_cmd(struct irlap_cb *self, struct sk_buff *skb,
-- struct irlap_info *info)
-+static void irlap_recv_snrm_cmd(struct irlap_cb *self, struct sk_buff *skb,
-+ struct irlap_info *info)
- {
- struct snrm_frame *frame;
-
- frame = (struct snrm_frame *) skb->data;
--
-+
- if (skb->len >= sizeof(struct snrm_frame)) {
- /* Copy the new connection address ignoring the C/R bit */
- info->caddr = frame->ncaddr & 0xFE;
-@@ -170,11 +171,11 @@
- IRDA_DEBUG(3, "%s(), invalid connection address!\n", __FUNCTION__);
- return;
- }
--
-+
- /* Copy peer device address */
-- info->daddr = le32_to_cpu(frame->saddr);
-- info->saddr = le32_to_cpu(frame->daddr);
--
-+ info->daddr = le32_to_cpu(get_unaligned(&frame->saddr));
-+ info->saddr = le32_to_cpu(get_unaligned(&frame->daddr));
-+
- /* Only accept if addressed directly to us */
- if (info->saddr != self->saddr) {
- IRDA_DEBUG(2, "%s(), not addressed to us!\n", __FUNCTION__);
-@@ -198,9 +199,9 @@
- struct sk_buff *skb;
- struct ua_frame *frame;
- int ret;
--
-+
- IRDA_DEBUG(2, "%s() <%ld>\n", __FUNCTION__, jiffies);
--
-+
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == LAP_MAGIC, return;);
-
-@@ -212,13 +213,13 @@
- return;
-
- frame = (struct ua_frame *) skb_put(skb, 10);
--
-+
- /* Build UA response */
- frame->caddr = self->caddr;
- frame->control = UA_RSP | PF_BIT;
-
-- frame->saddr = cpu_to_le32(self->saddr);
-- frame->daddr = cpu_to_le32(self->daddr);
-+ put_unaligned(cpu_to_le32(self->saddr), &frame->saddr);
-+ put_unaligned(cpu_to_le32(self->daddr), &frame->daddr);
-
- /* Should we send QoS negotiation parameters? */
- if (qos) {
-@@ -243,7 +244,7 @@
- {
- struct sk_buff *skb = NULL;
- __u8 *frame;
--
-+
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == LAP_MAGIC, return;);
-
-@@ -252,7 +253,7 @@
- return;
-
- frame = skb_put( skb, 2);
--
-+
- if (self->state == LAP_NDM)
- frame[0] = CBROADCAST;
- else
-@@ -260,7 +261,7 @@
-
- frame[1] = DM_RSP | PF_BIT;
-
-- irlap_queue_xmit(self, skb);
-+ irlap_queue_xmit(self, skb);
- }
-
- /*
-@@ -269,11 +270,11 @@
- * Send disconnect (DISC) frame
- *
- */
--void irlap_send_disc_frame(struct irlap_cb *self)
-+void irlap_send_disc_frame(struct irlap_cb *self)
- {
- struct sk_buff *skb = NULL;
- __u8 *frame;
--
-+
- IRDA_DEBUG(3, "%s()\n", __FUNCTION__);
-
- ASSERT(self != NULL, return;);
-@@ -284,7 +285,7 @@
- return;
-
- frame = skb_put(skb, 2);
--
-+
- frame[0] = self->caddr | CMD_FRAME;
- frame[1] = DISC_CMD | PF_BIT;
-
-@@ -295,17 +296,17 @@
- * Function irlap_send_discovery_xid_frame (S, s, command)
- *
- * Build and transmit a XID (eXchange station IDentifier) discovery
-- * frame.
-+ * frame.
- */
--void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s,
-- __u8 command, discovery_t *discovery)
-+void irlap_send_discovery_xid_frame(struct irlap_cb *self, int S, __u8 s,
-+ __u8 command, discovery_t *discovery)
- {
- struct sk_buff *skb = NULL;
- struct xid_frame *frame;
-- __u32 bcast = BROADCAST;
-+ __u32 bcast = BROADCAST, daddr;
- __u8 *info;
-
-- IRDA_DEBUG(4, "%s(), s=%d, S=%d, command=%d\n", __FUNCTION__, s, S,
-+ IRDA_DEBUG(4, "%s(), s=%d, S=%d, command=%d\n", __FUNCTION__, s, S,
- command);
-
- ASSERT(self != NULL, return;);
-@@ -328,13 +329,14 @@
- }
- frame->ident = XID_FORMAT;
-
-- frame->saddr = cpu_to_le32(self->saddr);
--
- if (command)
-- frame->daddr = cpu_to_le32(bcast);
-+ daddr = bcast;
- else
-- frame->daddr = cpu_to_le32(discovery->daddr);
--
-+ daddr = discovery->daddr;
-+
-+ put_unaligned(cpu_to_le32(self->saddr), &frame->saddr);
-+ put_unaligned(cpu_to_le32(daddr), &frame->daddr);
-+
- switch (S) {
- case 1:
- frame->flags = 0x00;
-@@ -353,10 +355,10 @@
- break;
- }
-
-- frame->slotnr = s;
-+ frame->slotnr = s;
- frame->version = 0x00;
-
-- /*
-+ /*
- * Provide info for final slot only in commands, and for all
- * responses. Send the second byte of the hint only if the
- * EXTENSION bit is set in the first byte.
-@@ -365,7 +367,7 @@
- int len;
-
- if (discovery->hints.byte[0] & HINT_EXTENSION) {
-- info = skb_put(skb, 2);
-+ info = skb_put(skb, 2);
- info[0] = discovery->hints.byte[0];
- info[1] = discovery->hints.byte[1];
- } else {
-@@ -378,7 +380,7 @@
- len = IRDA_MIN(discovery->name_len, skb_tailroom(skb));
- info = skb_put(skb, len);
- memcpy(info, discovery->nickname, len);
-- }
-+ }
- irlap_queue_xmit(self, skb);
- }
-
-@@ -388,9 +390,9 @@
- * Received a XID discovery response
- *
- */
--static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self,
-- struct sk_buff *skb,
-- struct irlap_info *info)
-+static void irlap_recv_discovery_xid_rsp(struct irlap_cb *self,
-+ struct sk_buff *skb,
-+ struct irlap_info *info)
- {
- struct xid_frame *xid;
- discovery_t *discovery = NULL;
-@@ -404,8 +406,8 @@
-
- xid = (struct xid_frame *) skb->data;
-
-- info->daddr = le32_to_cpu(xid->saddr);
-- info->saddr = le32_to_cpu(xid->daddr);
-+ info->daddr = le32_to_cpu(get_unaligned(&xid->saddr));
-+ info->saddr = le32_to_cpu(get_unaligned(&xid->daddr));
-
- /* Make sure frame is addressed to us */
- if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
-@@ -439,11 +441,11 @@
- discovery->charset = discovery_info[1];
- text = (char *) &discovery_info[2];
- }
-- /*
-- * Terminate info string, should be safe since this is where the
-+ /*
-+ * Terminate info string, should be safe since this is where the
- * FCS bytes resides.
- */
-- skb->data[skb->len] = '\0';
-+ skb->data[skb->len] = '\0';
- strncpy(discovery->nickname, text, NICKNAME_MAX_LEN);
- discovery->name_len = strlen(discovery->nickname);
-
-@@ -458,9 +460,9 @@
- * Received a XID discovery command
- *
- */
--static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self,
-- struct sk_buff *skb,
-- struct irlap_info *info)
-+static void irlap_recv_discovery_xid_cmd(struct irlap_cb *self,
-+ struct sk_buff *skb,
-+ struct irlap_info *info)
- {
- struct xid_frame *xid;
- discovery_t *discovery = NULL;
-@@ -469,8 +471,8 @@
-
- xid = (struct xid_frame *) skb->data;
-
-- info->daddr = le32_to_cpu(xid->saddr);
-- info->saddr = le32_to_cpu(xid->daddr);
-+ info->daddr = le32_to_cpu(get_unaligned(&xid->saddr));
-+ info->saddr = le32_to_cpu(get_unaligned(&xid->daddr));
-
- /* Make sure frame is addressed to us */
- if ((info->saddr != self->saddr) && (info->saddr != BROADCAST)) {
-@@ -497,11 +499,11 @@
- return;
- }
- info->s = xid->slotnr;
--
-+
- discovery_info = skb_pull(skb, sizeof(struct xid_frame));
-
-- /*
-- * Check if last frame
-+ /*
-+ * Check if last frame
- */
- if (info->s == 0xff) {
- /* Check if things are sane at this point... */
-@@ -518,7 +520,7 @@
- WARNING("%s(), unable to malloc!\n", __FUNCTION__);
- return;
- }
--
-+
- discovery->daddr = info->daddr;
- discovery->saddr = self->saddr;
- discovery->timestamp = jiffies;
-@@ -533,11 +535,11 @@
- discovery->charset = discovery_info[1];
- text = (char *) &discovery_info[2];
- }
-- /*
-- * Terminate string, should be safe since this is where the
-+ /*
-+ * Terminate string, should be safe since this is where the
- * FCS bytes resides.
- */
-- skb->data[skb->len] = '\0';
-+ skb->data[skb->len] = '\0';
- strncpy(discovery->nickname, text, NICKNAME_MAX_LEN);
- discovery->name_len = strlen(discovery->nickname);
-
-@@ -554,7 +556,7 @@
- * Build and transmit RR (Receive Ready) frame. Notice that it is currently
- * only possible to send RR frames with the poll bit set.
- */
--void irlap_send_rr_frame(struct irlap_cb *self, int command)
-+void irlap_send_rr_frame(struct irlap_cb *self, int command)
- {
- struct sk_buff *skb;
- __u8 *frame;
-@@ -562,9 +564,9 @@
- skb = dev_alloc_skb(16);
- if (!skb)
- return;
--
-+
- frame = skb_put(skb, 2);
--
-+
- frame[0] = self->caddr;
- frame[0] |= (command) ? CMD_FRAME : 0;
-
-@@ -576,7 +578,7 @@
- /*
- * Function irlap_send_rd_frame (self)
- *
-- * Request disconnect. Used by a secondary station to request the
-+ * Request disconnect. Used by a secondary station to request the
- * disconnection of the link.
- */
- void irlap_send_rd_frame(struct irlap_cb *self)
-@@ -587,9 +589,9 @@
- skb = dev_alloc_skb(16);
- if (!skb)
- return;
--
-+
- frame = skb_put(skb, 2);
--
-+
- frame[0] = self->caddr;
- frame[1] = RD_RSP | PF_BIT;
-
-@@ -603,8 +605,8 @@
- * making it inline since its called only from one single place
- * (irlap_driver_rcv).
- */
--static inline void irlap_recv_rr_frame(struct irlap_cb *self,
-- struct sk_buff *skb,
-+static inline void irlap_recv_rr_frame(struct irlap_cb *self,
-+ struct sk_buff *skb,
- struct irlap_info *info, int command)
- {
- info->nr = skb->data[1] >> 5;
-@@ -620,7 +622,7 @@
- {
- struct sk_buff *skb = NULL;
- __u8 *frame;
--
-+
- ASSERT( self != NULL, return;);
- ASSERT( self->magic == LAP_MAGIC, return;);
-
-@@ -629,7 +631,7 @@
- return;
-
- frame = skb_put( skb, 2);
--
-+
- frame[0] = self->caddr;
- frame[0] |= (command) ? CMD_FRAME : 0;
-
-@@ -639,7 +641,7 @@
-
- frame[2] = 0;
-
-- IRDA_DEBUG(4, "%s(), vr=%d, %ld\n", __FUNCTION__, self->vr, jiffies);
-+ IRDA_DEBUG(4, "%s(), vr=%d, %ld\n", __FUNCTION__, self->vr, jiffies);
-
- irlap_queue_xmit(self, skb);
- }
-@@ -650,8 +652,8 @@
- * Received RNR (Receive Not Ready) frame from peer station
- *
- */
--static void irlap_recv_rnr_frame(struct irlap_cb *self, struct sk_buff *skb,
-- struct irlap_info *info, int command)
-+static void irlap_recv_rnr_frame(struct irlap_cb *self, struct sk_buff *skb,
-+ struct irlap_info *info, int command)
- {
- info->nr = skb->data[1] >> 5;
-
-@@ -663,13 +665,13 @@
- irlap_do_event(self, RECV_RNR_RSP, skb, info);
- }
-
--static void irlap_recv_rej_frame(struct irlap_cb *self, struct sk_buff *skb,
-+static void irlap_recv_rej_frame(struct irlap_cb *self, struct sk_buff *skb,
- struct irlap_info *info, int command)
- {
- IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
-
- info->nr = skb->data[1] >> 5;
--
-+
- /* Check if this is a command or a response frame */
- if (command)
- irlap_do_event(self, RECV_REJ_CMD, skb, info);
-@@ -677,13 +679,13 @@
- irlap_do_event(self, RECV_REJ_RSP, skb, info);
- }
-
--static void irlap_recv_srej_frame(struct irlap_cb *self, struct sk_buff *skb,
-+static void irlap_recv_srej_frame(struct irlap_cb *self, struct sk_buff *skb,
- struct irlap_info *info, int command)
- {
- IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
-
- info->nr = skb->data[1] >> 5;
--
-+
- /* Check if this is a command or a response frame */
- if (command)
- irlap_do_event(self, RECV_SREJ_CMD, skb, info);
-@@ -691,7 +693,7 @@
- irlap_do_event(self, RECV_SREJ_RSP, skb, info);
- }
-
--static void irlap_recv_disc_frame(struct irlap_cb *self, struct sk_buff *skb,
-+static void irlap_recv_disc_frame(struct irlap_cb *self, struct sk_buff *skb,
- struct irlap_info *info, int command)
- {
- IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
-@@ -709,9 +711,9 @@
- * Received UA (Unnumbered Acknowledgement) frame
- *
- */
--static inline void irlap_recv_ua_frame(struct irlap_cb *self,
-- struct sk_buff *skb,
-- struct irlap_info *info)
-+static inline void irlap_recv_ua_frame(struct irlap_cb *self,
-+ struct sk_buff *skb,
-+ struct irlap_info *info)
- {
- irlap_do_event(self, RECV_UA_RSP, skb, info);
- }
-@@ -728,25 +730,25 @@
-
- if (skb->data[1] == I_FRAME) {
-
-- /*
-+ /*
- * Insert frame sequence number (Vs) in control field before
- * inserting into transmit window queue.
- */
- skb->data[1] = I_FRAME | (self->vs << 1);
--
-+
- /* Copy buffer */
- tx_skb = skb_clone(skb, GFP_ATOMIC);
- if (tx_skb == NULL) {
- return;
- }
--
-- /*
-- * Insert frame in store, in case of retransmissions
-+
-+ /*
-+ * Insert frame in store, in case of retransmissions
- */
- skb_queue_tail(&self->wx_list, skb_get(skb));
--
-+
- self->vs = (self->vs + 1) % 8;
-- self->ack_required = FALSE;
-+ self->ack_required = FALSE;
- self->window -= 1;
-
- irlap_send_i_frame( self, tx_skb, CMD_FRAME);
-@@ -761,40 +763,40 @@
- *
- * Send I(nformation) frame as primary with poll bit set
- */
--void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb)
-+void irlap_send_data_primary_poll(struct irlap_cb *self, struct sk_buff *skb)
- {
- struct sk_buff *tx_skb;
-
- /* Stop P timer */
- del_timer(&self->poll_timer);
--
-+
- /* Is this reliable or unreliable data? */
- if (skb->data[1] == I_FRAME) {
--
-- /*
-+
-+ /*
- * Insert frame sequence number (Vs) in control field before
- * inserting into transmit window queue.
- */
- skb->data[1] = I_FRAME | (self->vs << 1);
--
-+
- /* Copy buffer */
- tx_skb = skb_clone(skb, GFP_ATOMIC);
- if (tx_skb == NULL) {
- return;
- }
--
-- /*
-- * Insert frame in store, in case of retransmissions
-+
-+ /*
-+ * Insert frame in store, in case of retransmissions
- */
- skb_queue_tail(&self->wx_list, skb_get(skb));
--
-- /*
-+
-+ /*
- * Set poll bit if necessary. We do this to the copied
- * skb, since retransmitted need to set or clear the poll
-- * bit depending on when they are sent.
-+ * bit depending on when they are sent.
- */
- tx_skb->data[1] |= PF_BIT;
--
-+
- self->vs = (self->vs + 1) % 8;
- self->ack_required = FALSE;
-
-@@ -827,8 +829,8 @@
- * Send I(nformation) frame as secondary with final bit set
- *
- */
--void irlap_send_data_secondary_final(struct irlap_cb *self,
-- struct sk_buff *skb)
-+void irlap_send_data_secondary_final(struct irlap_cb *self,
-+ struct sk_buff *skb)
- {
- struct sk_buff *tx_skb = NULL;
-
-@@ -839,26 +841,26 @@
- /* Is this reliable or unreliable data? */
- if (skb->data[1] == I_FRAME) {
-
-- /*
-+ /*
- * Insert frame sequence number (Vs) in control field before
- * inserting into transmit window queue.
- */
- skb->data[1] = I_FRAME | (self->vs << 1);
--
-+
- tx_skb = skb_clone(skb, GFP_ATOMIC);
- if (tx_skb == NULL) {
- return;
-- }
-+ }
-
- /* Insert frame in store */
- skb_queue_tail(&self->wx_list, skb_get(skb));
--
-+
- tx_skb->data[1] |= PF_BIT;
--
-- self->vs = (self->vs + 1) % 8;
-+
-+ self->vs = (self->vs + 1) % 8;
- self->ack_required = FALSE;
--
-- irlap_send_i_frame(self, tx_skb, RSP_FRAME);
-+
-+ irlap_send_i_frame(self, tx_skb, RSP_FRAME);
- } else {
- if (self->ack_required) {
- irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME);
-@@ -885,32 +887,32 @@
- * Send I(nformation) frame as secondary without final bit set
- *
- */
--void irlap_send_data_secondary(struct irlap_cb *self, struct sk_buff *skb)
-+void irlap_send_data_secondary(struct irlap_cb *self, struct sk_buff *skb)
- {
- struct sk_buff *tx_skb = NULL;
-
- /* Is this reliable or unreliable data? */
- if (skb->data[1] == I_FRAME) {
--
-- /*
-+
-+ /*
- * Insert frame sequence number (Vs) in control field before
- * inserting into transmit window queue.
- */
- skb->data[1] = I_FRAME | (self->vs << 1);
--
-+
- tx_skb = skb_clone(skb, GFP_ATOMIC);
- if (tx_skb == NULL) {
- return;
-- }
--
-+ }
-+
- /* Insert frame in store */
- skb_queue_tail(&self->wx_list, skb_get(skb));
--
-+
- self->vs = (self->vs + 1) % 8;
-- self->ack_required = FALSE;
-+ self->ack_required = FALSE;
- self->window -= 1;
-
-- irlap_send_i_frame(self, tx_skb, RSP_FRAME);
-+ irlap_send_i_frame(self, tx_skb, RSP_FRAME);
- } else {
- irlap_send_ui_frame(self, skb_get(skb), self->caddr, RSP_FRAME);
- self->window -= 1;
-@@ -920,8 +922,8 @@
- /*
- * Function irlap_resend_rejected_frames (nr)
- *
-- * Resend frames which has not been acknowledged. Should be safe to
-- * traverse the list without locking it since this function will only be
-+ * Resend frames which has not been acknowledged. Should be safe to
-+ * traverse the list without locking it since this function will only be
- * called from interrupt context (BH)
- */
- void irlap_resend_rejected_frames(struct irlap_cb *self, int command)
-@@ -943,8 +945,8 @@
- while (skb != NULL) {
- irlap_wait_min_turn_around(self, &self->qos_tx);
-
-- /* We copy the skb to be retransmitted since we will have to
-- * modify it. Cloning will confuse packet sniffers
-+ /* We copy the skb to be retransmitted since we will have to
-+ * modify it. Cloning will confuse packet sniffers
- */
- /* tx_skb = skb_clone( skb, GFP_ATOMIC); */
- tx_skb = skb_copy(skb, GFP_ATOMIC);
-@@ -959,17 +961,17 @@
- /* Clear old Nr field + poll bit */
- tx_skb->data[1] &= 0x0f;
-
-- /*
-+ /*
- * Set poll bit on the last frame retransmitted
- */
- if (count-- == 1)
- tx_skb->data[1] |= PF_BIT; /* Set p/f bit */
- else
- tx_skb->data[1] &= ~PF_BIT; /* Clear p/f bit */
--
-+
- irlap_send_i_frame(self, tx_skb, command);
-
-- /*
-+ /*
- * If our skb is the last buffer in the list, then
- * we are finished, if not, move to the next sk-buffer
- */
-@@ -979,23 +981,23 @@
- skb = skb->next;
- }
- #if 0 /* Not yet */
-- /*
-+ /*
- * We can now fill the window with additinal data frames
- */
- while (skb_queue_len( &self->txq) > 0) {
--
-+
- IRDA_DEBUG(0, "%s(), sending additional frames!\n", __FUNCTION__);
-- if ((skb_queue_len( &self->txq) > 0) &&
-+ if ((skb_queue_len( &self->txq) > 0) &&
- (self->window > 0)) {
-- skb = skb_dequeue( &self->txq);
-+ skb = skb_dequeue( &self->txq);
- ASSERT(skb != NULL, return;);
-
- /*
-- * If send window > 1 then send frame with pf
-+ * If send window > 1 then send frame with pf
- * bit cleared
-- */
-- if ((self->window > 1) &&
-- skb_queue_len(&self->txq) > 0)
-+ */
-+ if ((self->window > 1) &&
-+ skb_queue_len(&self->txq) > 0)
- {
- irlap_send_data_primary(self, skb);
- } else {
-@@ -1023,14 +1025,14 @@
- if (skb != NULL) {
- irlap_wait_min_turn_around(self, &self->qos_tx);
-
-- /* We copy the skb to be retransmitted since we will have to
-- * modify it. Cloning will confuse packet sniffers
-+ /* We copy the skb to be retransmitted since we will have to
-+ * modify it. Cloning will confuse packet sniffers
- */
- /* tx_skb = skb_clone( skb, GFP_ATOMIC); */
- tx_skb = skb_copy(skb, GFP_ATOMIC);
- if (!tx_skb) {
- IRDA_DEBUG(0, "%s(), unable to copy\n", __FUNCTION__);
-- return;
-+ return;
- }
- /* Unlink tx_skb from list */
- tx_skb->next = tx_skb->prev = NULL;
-@@ -1041,7 +1043,7 @@
-
- /* Set poll/final bit */
- tx_skb->data[1] |= PF_BIT; /* Set p/f bit */
--
-+
- irlap_send_i_frame(self, tx_skb, command);
- }
- }
-@@ -1052,15 +1054,15 @@
- * Contruct and transmit an Unnumbered Information (UI) frame
- *
- */
--void irlap_send_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
-+void irlap_send_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
- __u8 caddr, int command)
- {
- IRDA_DEBUG(4, "%s()\n", __FUNCTION__);
--
-+
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == LAP_MAGIC, return;);
- ASSERT(skb != NULL, return;);
--
-+
- /* Insert connection address */
- skb->data[0] = caddr | ((command) ? CMD_FRAME : 0);
-
-@@ -1072,13 +1074,13 @@
- *
- * Contruct and transmit Information (I) frame
- */
--void irlap_send_i_frame(struct irlap_cb *self, struct sk_buff *skb,
-- int command)
-+void irlap_send_i_frame(struct irlap_cb *self, struct sk_buff *skb,
-+ int command)
- {
- /* Insert connection address */
- skb->data[0] = self->caddr;
- skb->data[0] |= (command) ? CMD_FRAME : 0;
--
-+
- /* Insert next to receive (Vr) */
- skb->data[1] |= (self->vr << 5); /* insert nr */
-
-@@ -1091,9 +1093,9 @@
- * Receive and parse an I (Information) frame, no harm in making it inline
- * since it's called only from one single place (irlap_driver_rcv).
- */
--static inline void irlap_recv_i_frame(struct irlap_cb *self,
-- struct sk_buff *skb,
-- struct irlap_info *info, int command)
-+static inline void irlap_recv_i_frame(struct irlap_cb *self,
-+ struct sk_buff *skb,
-+ struct irlap_info *info, int command)
- {
- info->nr = skb->data[1] >> 5; /* Next to receive */
- info->pf = skb->data[1] & PF_BIT; /* Final bit */
-@@ -1112,7 +1114,7 @@
- * Receive and parse an Unnumbered Information (UI) frame
- *
- */
--static void irlap_recv_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
-+static void irlap_recv_ui_frame(struct irlap_cb *self, struct sk_buff *skb,
- struct irlap_info *info)
- {
- IRDA_DEBUG( 4, "%s()\n", __FUNCTION__);
-@@ -1128,19 +1130,19 @@
- * Received Frame Reject response.
- *
- */
--static void irlap_recv_frmr_frame(struct irlap_cb *self, struct sk_buff *skb,
-- struct irlap_info *info)
-+static void irlap_recv_frmr_frame(struct irlap_cb *self, struct sk_buff *skb,
-+ struct irlap_info *info)
- {
- __u8 *frame;
- int w, x, y, z;
-
- IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
--
-+
- ASSERT(self != NULL, return;);
- ASSERT(self->magic == LAP_MAGIC, return;);
- ASSERT(skb != NULL, return;);
- ASSERT(info != NULL, return;);
--
-+
- frame = skb->data;
-
- info->nr = frame[2] >> 5; /* Next to receive */
-@@ -1151,11 +1153,11 @@
- x = frame[3] & 0x02;
- y = frame[3] & 0x04;
- z = frame[3] & 0x08;
--
-+
- if (w) {
- IRDA_DEBUG(0, "Rejected control field is undefined or not "
- "implemented.\n");
-- }
-+ }
- if (x) {
- IRDA_DEBUG(0, "Rejected control field was invalid because it "
- "contained a non permitted I field.\n");
-@@ -1178,7 +1180,7 @@
- * Send a test frame response
- *
- */
--void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr,
-+void irlap_send_test_frame(struct irlap_cb *self, __u8 caddr, __u32 daddr,
- struct sk_buff *cmd)
- {
- struct sk_buff *skb;
-@@ -1191,7 +1193,7 @@
-
- /* Broadcast frames must include saddr and daddr fields */
- if (caddr == CBROADCAST) {
-- frame = (struct test_frame *)
-+ frame = (struct test_frame *)
- skb_put(skb, sizeof(struct test_frame));
-
- /* Insert the swapped addresses */
-@@ -1218,28 +1220,28 @@
- * Receive a test frame
- *
- */
--static void irlap_recv_test_frame(struct irlap_cb *self, struct sk_buff *skb,
-+static void irlap_recv_test_frame(struct irlap_cb *self, struct sk_buff *skb,
- struct irlap_info *info, int command)
- {
- struct test_frame *frame;
-
- IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
--
-+
- frame = (struct test_frame *) skb->data;
--
-+
- /* Broadcast frames must carry saddr and daddr fields */
- if (info->caddr == CBROADCAST) {
- if (skb->len < sizeof(struct test_frame)) {
- IRDA_DEBUG(0, "%s() test frame to short!\n", __FUNCTION__);
- return;
- }
--
-+
- /* Read and swap addresses */
-- info->daddr = le32_to_cpu(frame->saddr);
-- info->saddr = le32_to_cpu(frame->daddr);
-+ info->daddr = le32_to_cpu(get_unaligned(&frame->saddr));
-+ info->saddr = le32_to_cpu(get_unaligned(&frame->daddr));
-
- /* Make sure frame is addressed to us */
-- if ((info->saddr != self->saddr) &&
-+ if ((info->saddr != self->saddr) &&
- (info->saddr != BROADCAST)) {
- return;
- }
-@@ -1254,18 +1256,18 @@
- /*
- * Function irlap_driver_rcv (skb, netdev, ptype)
- *
-- * Called when a frame is received. Dispatches the right receive function
-+ * Called when a frame is received. Dispatches the right receive function
- * for processing of the frame.
- *
- */
--int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev,
-+int irlap_driver_rcv(struct sk_buff *skb, struct net_device *dev,
- struct packet_type *ptype)
- {
- struct irlap_info info;
- struct irlap_cb *self;
- int command;
- __u8 control;
--
-+
- /* FIXME: should we get our own field? */
- self = (struct irlap_cb *) dev->atalk_ptr;
-
-@@ -1281,10 +1283,10 @@
- dev_kfree_skb(skb);
- return -1;
- }
--
-+
- command = skb->data[0] & CMD_FRAME;
- info.caddr = skb->data[0] & CBROADCAST;
--
-+
- info.pf = skb->data[1] & PF_BIT;
- info.control = skb->data[1] & ~PF_BIT; /* Mask away poll/final bit */
-
-@@ -1295,7 +1297,7 @@
- IRDA_DEBUG(0, "%s(), wrong connection address!\n", __FUNCTION__);
- goto out;
- }
-- /*
-+ /*
- * Optimize for the common case and check if the frame is an
- * I(nformation) frame. Only I-frames have bit 0 set to 0
- */
-@@ -1304,11 +1306,11 @@
- goto out;
- }
- /*
-- * We now check is the frame is an S(upervisory) frame. Only
-+ * We now check is the frame is an S(upervisory) frame. Only
- * S-frames have bit 0 set to 1 and bit 1 set to 0
- */
- if (~control & 0x02) {
-- /*
-+ /*
- * Received S(upervisory) frame, check which frame type it is
- * only the first nibble is of interest
- */
-@@ -1332,8 +1334,8 @@
- }
- goto out;
- }
-- /*
-- * This must be a C(ontrol) frame
-+ /*
-+ * This must be a C(ontrol) frame
- */
- switch (control) {
- case XID_RSP:
-@@ -1369,6 +1371,6 @@
- break;
- }
- out:
-- dev_kfree_skb(skb);
-+ dev_kfree_skb(skb);
- return 0;
- }
---- linux-2.4.25/net/irda/irttp.c~2.4.25-vrs2.patch 2003-11-28 19:26:21.000000000 +0100
-+++ linux-2.4.25/net/irda/irttp.c 2004-03-31 17:15:09.000000000 +0200
-@@ -1665,8 +1665,8 @@
- }
- self->rx_sdu_size = 0;
- }
--
-- /*
-+
-+ /*
- * It's not trivial to keep track of how many credits are available
- * by incrementing at each packet, because delivery may fail
- * (irttp_do_data_indication() may requeue the frame) and because
-@@ -1676,7 +1676,7 @@
- * to send remote_credit.
- * No need to spinlock, write is atomic and self correcting...
- * Jean II
-- */
-+ */
- self->avail_credit = (self->initial_credit -
- (self->remote_credit +
- skb_queue_len(&self->rx_queue) +
---- linux-2.4.25/net/sched/Config.in~2.4.25-vrs2.patch 2004-02-18 14:36:32.000000000 +0100
-+++ linux-2.4.25/net/sched/Config.in 2004-03-31 17:15:09.000000000 +0200
-@@ -3,9 +3,9 @@
- #
- tristate ' CBQ packet scheduler' CONFIG_NET_SCH_CBQ
- tristate ' HTB packet scheduler' CONFIG_NET_SCH_HTB
--tristate ' CSZ packet scheduler' CONFIG_NET_SCH_CSZ
-+dep_tristate ' CSZ packet scheduler (experimental)' CONFIG_NET_SCH_CSZ $CONFIG_EXPERIMENTAL
- #tristate ' H-PFQ packet scheduler' CONFIG_NET_SCH_HPFQ
--tristate ' H-FSC packet scheduler' CONFIG_NET_SCH_HFSC
-+tristate ' H-FSC packet scheduler' CONFIG_NET_SCH_HFCS
- if [ "$CONFIG_ATM" = "y" -o "$CONFIG_ATM" = "m" ]; then
- dep_tristate ' ATM pseudo-scheduler' CONFIG_NET_SCH_ATM $CONFIG_ATM
- fi
diff --git a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/defconfig-simpad b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/defconfig-simpad
deleted file mode 100644
index 90791c65f8..0000000000
--- a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/defconfig-simpad
+++ /dev/null
@@ -1,1285 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_OMAHA is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_MX1ADS is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_RISCSTATION is not set
-CONFIG_ARCH_SA1100=y
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_AT91RM9200 is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-
-#
-# Archimedes/A5000 Implementations (select only ONE)
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ACCELENT is not set
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSAGC is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_ADSBITSYPLUS is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CEP is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_H3XXX is not set
-# CONFIG_H3600_SLEEVE is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_FRODO is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_HACKKIT is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-CONFIG_SA1100_SIMPAD=y
-# CONFIG_SA1100_SIMPAD_SINUSPAD is not set
-# CONFIG_SA1100_SIMPUTER is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-CONFIG_SA1100_USB=m
-CONFIG_SA1100_USB_NETLINK=m
-CONFIG_SA1100_USB_CHAR=m
-# CONFIG_SA1100_SSP is not set
-
-#
-# AT91RM9200 Implementations
-#
-# CONFIG_ARCH_AT91RM9200DK is not set
-# CONFIG_MACH_CSB337 is not set
-
-#
-# Intel PXA250/210 Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_ARCH_PXA_IDP is not set
-# CONFIG_ARCH_PXA_CERF is not set
-# CONFIG_ARCH_TRIZEPS2 is not set
-# CONFIG_PXA_USB is not set
-# CONFIG_PXA_USB_NETLINK is not set
-# CONFIG_PXA_USB_CHAR is not set
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_FORTUNET is not set
-# CONFIG_ARCH_GUIDEA07 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_PLD is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM922T is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_ARM1020E is not set
-# CONFIG_CPU_ARM1022 is not set
-# CONFIG_CPU_ARM1026 is not set
-# CONFIG_CPU_SA110 is not set
-CONFIG_CPU_SA1100=y
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
-
-#
-# Processor Features
-#
-CONFIG_DISCONTIGMEM=y
-
-#
-# General setup
-#
-# CONFIG_PCI is not set
-CONFIG_ISA=y
-# CONFIG_ISA_DMA is not set
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_CPU_FREQ=y
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=y
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_CLPS6700 is not set
-CONFIG_PCMCIA_SA1100=y
-# CONFIG_PCMCIA_PXA is not set
-
-#
-# MMC device drivers
-#
-# CONFIG_MMC is not set
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_PM=y
-CONFIG_APM=y
-CONFIG_SIMPAD_PM=y
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="mtdparts=sa1100:512k(boot),1m(kernel),14848k(root),-(home) console=ttySA root=1f02 noinitrd jffs2_orphaned_inodes=delete rootfstype=jffs2 mem=32M"
-CONFIG_LEDS=y
-# CONFIG_LEDS_TIMER is not set
-# CONFIG_LEDS_CPU is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CONCAT=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_GEN_PROBE=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_GEOMETRY=y
-# CONFIG_MTD_CFI_B1 is not set
-CONFIG_MTD_CFI_B2=y
-# CONFIG_MTD_CFI_B4 is not set
-# CONFIG_MTD_CFI_B8 is not set
-CONFIG_MTD_CFI_I1=y
-# CONFIG_MTD_CFI_I2 is not set
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_NORA is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-CONFIG_MTD_SA1100=y
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_FORTUNET is not set
-# CONFIG_MTD_EPXA is not set
-# CONFIG_MTD_AUTCPU12 is not set
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_CEIVA is not set
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PCMCIA is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-CONFIG_MTD_MTDRAM=y
-CONFIG_MTDRAM_TOTAL_SIZE=32768
-CONFIG_MTDRAM_ERASE_SIZE=1
-CONFIG_MTDRAM_ABS_POS=C2000000
-# CONFIG_MTD_BLKMTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC1000 is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
-# CONFIG_CISS_MONITOR_THREAD is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_NBD=m
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_BLK_STATS is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-# CONFIG_NET_IPGRE_BROADCAST is not set
-# CONFIG_IP_MROUTE is not set
-CONFIG_ARPD=y
-CONFIG_INET_ECN=y
-CONFIG_SYN_COOKIES=y
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_AMANDA=m
-CONFIG_IP_NF_TFTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_PKTTYPE=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_RECENT=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_HELPER=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_CONNTRACK=m
-CONFIG_IP_NF_MATCH_UNCLEAN=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_MIRROR=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_NAT_AMANDA=m
-CONFIG_IP_NF_NAT_LOCAL=y
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_NAT_TFTP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_TARGET_DSCP=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-
-#
-# IP: Virtual Server Configuration
-#
-CONFIG_IP_VS=m
-# CONFIG_IP_VS_DEBUG is not set
-CONFIG_IP_VS_TAB_BITS=12
-
-#
-# IPVS scheduler
-#
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-CONFIG_IP_VS_SED=m
-CONFIG_IP_VS_NQ=m
-
-#
-# IPVS application helper
-#
-CONFIG_IP_VS_FTP=m
-CONFIG_IPV6=m
-CONFIG_IPV6_SUBTREES=y
-CONFIG_IPV6_TUNNEL=m
-CONFIG_IPV6_MOBILITY=m
-CONFIG_IPV6_MOBILITY_MN=m
-CONFIG_IPV6_MOBILITY_HA=m
-CONFIG_IPV6_MOBILITY_DEBUG=y
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_MATCH_OPTS=m
-CONFIG_IP6_NF_MATCH_FRAG=m
-CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
-CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_AHESP=m
-CONFIG_IP6_NF_MATCH_LENGTH=m
-CONFIG_IP6_NF_MATCH_EUI64=m
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
-# CONFIG_KHTTPD is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-CONFIG_IPV6_SCTP__=m
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-CONFIG_VLAN_8021Q=m
-
-#
-#
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_DEV_APPLETALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-CONFIG_IPSEC=y
-
-#
-# IPSec options (Openswan)
-#
-CONFIG_IPSEC_IPIP=y
-CONFIG_IPSEC_AH=y
-CONFIG_IPSEC_AUTH_HMAC_MD5=y
-CONFIG_IPSEC_AUTH_HMAC_SHA1=y
-CONFIG_IPSEC_ESP=y
-CONFIG_IPSEC_ENC_3DES=y
-CONFIG_IPSEC_ENC_AES=y
-CONFIG_IPSEC_ALG=y
-CONFIG_IPSEC_ALG_AES=y
-# CONFIG_IPSEC_ALG_CRYPTOAPI is not set
-CONFIG_IPSEC_IPCOMP=y
-CONFIG_IPSEC_DEBUG=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-CONFIG_DUMMY=m
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_ARM_AM79C961A is not set
-# CONFIG_ARM_CIRRUS is not set
-# CONFIG_SUNLANCE is not set
-# CONFIG_SUNBMAC is not set
-# CONFIG_SUNQE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
-# CONFIG_B44 is not set
-# CONFIG_CS89x0 is not set
-# CONFIG_TULIP is not set
-# CONFIG_DM9102 is not set
-# CONFIG_EEPRO100 is not set
-# CONFIG_EEPRO100_PIO is not set
-# CONFIG_E100 is not set
-# CONFIG_LNE390 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_NE3210 is not set
-# CONFIG_ES3210 is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_8139TOO_PIO is not set
-# CONFIG_8139TOO_TUNE_TWISTER is not set
-# CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_OLD_RX_RESET is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_SUNDANCE_MMIO is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_VIA_RHINE_MMIO is not set
-# CONFIG_WINBOND_840 is not set
-CONFIG_NET_POCKET=y
-# CONFIG_DE600 is not set
-# CONFIG_DE620 is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=m
-CONFIG_PPP_MULTILINK=y
-CONFIG_PPP_FILTER=y
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPPOE=m
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_STRIP is not set
-# CONFIG_WAVELAN is not set
-# CONFIG_ARLAN is not set
-# CONFIG_AIRONET4500 is not set
-# CONFIG_AIRONET4500_NONCS is not set
-# CONFIG_AIRONET4500_PROC is not set
-# CONFIG_AIRO is not set
-# CONFIG_HERMES is not set
-
-#
-# Wireless Pcmcia cards support
-#
-# CONFIG_PCMCIA_HERMES is not set
-# CONFIG_AIRO_CS is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=m
-CONFIG_PCMCIA_AXNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-# CONFIG_ARCNET_COM20020_CS is not set
-# CONFIG_PCMCIA_IBMTR is not set
-CONFIG_NET_PCMCIA_RADIO=y
-# CONFIG_PCMCIA_RAYCS is not set
-# CONFIG_PCMCIA_NETWAVE is not set
-# CONFIG_PCMCIA_WAVELAN is not set
-# CONFIG_AIRONET4500_CS is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
-CONFIG_IRLAN=m
-CONFIG_IRNET=m
-CONFIG_IRCOMM=m
-CONFIG_IRDA_ULTRA=y
-
-#
-# IrDA options
-#
-CONFIG_IRDA_CACHE_LAST_LSAP=y
-CONFIG_IRDA_FAST_RR=y
-# CONFIG_IRDA_DEBUG is not set
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=m
-CONFIG_IRPORT_SIR=m
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_OLD is not set
-# CONFIG_TOSHIBA_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-# CONFIG_VIA_IRCC_FIR is not set
-CONFIG_SA1100_FIR=m
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_IDEDISK_STROKE is not set
-CONFIG_BLK_DEV_IDECS=y
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_DMA_NONPCI is not set
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-# CONFIG_BLK_DEV_ATARAID_SII is not set
-
-#
-# SCSI support
-#
-# CONFIG_SCSI is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-CONFIG_INPUT=y
-CONFIG_INPUT_KEYBDEV=y
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_UINPUT=y
-# CONFIG_INPUT_MX1TS is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=m
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_ANAKIN is not set
-# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_UART00 is not set
-# CONFIG_SERIAL_UART00_CONSOLE is not set
-CONFIG_SERIAL_SA1100=y
-CONFIG_SERIAL_SA1100_CONSOLE=y
-CONFIG_SA1100_DEFAULT_BAUDRATE=115200
-# CONFIG_SERIAL_OMAHA is not set
-# CONFIG_SERIAL_OMAHA_CONSOLE is not set
-# CONFIG_SERIAL_AT91 is not set
-# CONFIG_SERIAL_AT91_CONSOLE is not set
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=32
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# L3 serial bus support
-#
-# CONFIG_L3 is not set
-# CONFIG_L3_ALGOBIT is not set
-# CONFIG_L3_BIT_SA1100_GPIO is not set
-
-#
-# Other L3 adapters
-#
-# CONFIG_L3_SA1111 is not set
-# CONFIG_BIT_SA1100_GPIO is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_INPUT_NS558 is not set
-# CONFIG_INPUT_LIGHTNING is not set
-# CONFIG_INPUT_PCIGAME is not set
-# CONFIG_INPUT_CS461X is not set
-# CONFIG_INPUT_EMU10K1 is not set
-# CONFIG_INPUT_SERIO is not set
-# CONFIG_INPUT_SERPORT is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_ANALOG is not set
-# CONFIG_INPUT_A3D is not set
-# CONFIG_INPUT_ADI is not set
-# CONFIG_INPUT_COBRA is not set
-# CONFIG_INPUT_GF2K is not set
-# CONFIG_INPUT_GRIP is not set
-# CONFIG_INPUT_INTERACT is not set
-# CONFIG_INPUT_TMDC is not set
-# CONFIG_INPUT_SIDEWINDER is not set
-# CONFIG_INPUT_IFORCE_USB is not set
-# CONFIG_INPUT_IFORCE_232 is not set
-# CONFIG_INPUT_WARRIOR is not set
-# CONFIG_INPUT_MAGELLAN is not set
-# CONFIG_INPUT_SPACEORB is not set
-# CONFIG_INPUT_SPACEBALL is not set
-# CONFIG_INPUT_STINGER is not set
-# CONFIG_INPUT_DB9 is not set
-# CONFIG_INPUT_GAMECON is not set
-# CONFIG_INPUT_TURBOGRAFX is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_IPMI_PANIC_EVENT is not set
-# CONFIG_IPMI_DEVICE_INTERFACE is not set
-# CONFIG_IPMI_KCS is not set
-# CONFIG_IPMI_WATCHDOG is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_SCx200 is not set
-# CONFIG_SCx200_GPIO is not set
-# CONFIG_AMD_PM768 is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_SA1100_RTC=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-
-#
-# Direct Rendering Manager (XFree86 DRI support)
-#
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-CONFIG_PCMCIA_SERIAL_CS=m
-# CONFIG_SYNCLINK_CS is not set
-CONFIG_TDA8007=m
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_QFMT_V2 is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BEFS_DEBUG is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=m
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=m
-CONFIG_UMSDOS_FS=m
-CONFIG_VFAT_FS=y
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_CRAMFS=m
-# CONFIG_CRAMFS_LINEAR is not set
-# CONFIG_CRAMFS_LINEAR_XIP is not set
-# CONFIG_ROOT_CRAMFS_LINEAR is not set
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-CONFIG_DEVFS_MOUNT=y
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_TRACE is not set
-# CONFIG_XFS_DEBUG is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_NFS_DIRECTIO is not set
-CONFIG_ROOT_NFS=y
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-CONFIG_SMB_UNIX=y
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-CONFIG_NLS_CODEPAGE_850=y
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-CONFIG_NLS_ISO8859_15=y
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Console drivers
-#
-CONFIG_PC_KEYMAP=y
-# CONFIG_VGA_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_ACORN is not set
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_SA1100 is not set
-# CONFIG_FB_DBMX1 is not set
-# CONFIG_FB_PXA is not set
-# CONFIG_FB_CYBER2000 is not set
-CONFIG_FB_MQ200=y
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-CONFIG_FBCON_CFB4=y
-CONFIG_FBCON_CFB8=y
-CONFIG_FBCON_CFB16=y
-# CONFIG_FBCON_CFB24 is not set
-# CONFIG_FBCON_CFB32 is not set
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA_PLANES is not set
-# CONFIG_FBCON_VGA is not set
-# CONFIG_FBCON_HGA is not set
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-CONFIG_FONT_8x8=y
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_ALI5455 is not set
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_FORTE is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-CONFIG_SOUND_SA1100=y
-# CONFIG_SOUND_UDA1341 is not set
-# CONFIG_SOUND_ASSABET_UDA1341 is not set
-# CONFIG_SOUND_H3600_UDA1341 is not set
-# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
-# CONFIG_SOUND_SA1111_UDA1341 is not set
-# CONFIG_SOUND_SA1111_AC97 is not set
-# CONFIG_SOUND_SA1100SSP is not set
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_VIDC is not set
-# CONFIG_SOUND_WAVEARTIST is not set
-# CONFIG_SOUND_PXA_AC97 is not set
-# CONFIG_SOUND_TVMIXER is not set
-# CONFIG_SOUND_AD1980 is not set
-# CONFIG_SOUND_WM97XX is not set
-
-#
-# Multimedia Capabilities Port drivers
-#
-CONFIG_MCP=y
-CONFIG_MCP_SA1100=y
-CONFIG_MCP_UCB1200=y
-CONFIG_MCP_UCB1200_AUDIO=y
-CONFIG_MCP_UCB1200_TS=y
-# CONFIG_MCP_UCB1400_TS is not set
-
-#
-# Console Switches
-#
-CONFIG_SWITCHES=y
-CONFIG_SWITCHES_SA1100=y
-CONFIG_SWITCHES_UCB1X00=y
-
-#
-# USB support
-#
-# CONFIG_USB is not set
-
-#
-# Support for USB gadgets
-#
-CONFIG_USB_GADGET=m
-CONFIG_USB_GADGET_NET2280=y
-# CONFIG_USB_GADGET_GOKU is not set
-# CONFIG_USB_GADGET_CONTROLLER is not set
-
-#
-# Bluetooth support
-#
-CONFIG_BLUEZ=m
-CONFIG_BLUEZ_L2CAP=m
-CONFIG_BLUEZ_SCO=m
-CONFIG_BLUEZ_RFCOMM=m
-CONFIG_BLUEZ_RFCOMM_TTY=y
-CONFIG_BLUEZ_BNEP=m
-CONFIG_BLUEZ_BNEP_MC_FILTER=y
-CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
-
-#
-# Bluetooth device drivers
-#
-# CONFIG_BLUEZ_HCIUSB is not set
-CONFIG_BLUEZ_HCIUART=m
-CONFIG_BLUEZ_HCIUART_H4=y
-CONFIG_BLUEZ_HCIUART_BCSP=y
-CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y
-# CONFIG_BLUEZ_HCIBFUSB is not set
-CONFIG_BLUEZ_HCIDTL1=m
-CONFIG_BLUEZ_HCIBT3C=m
-CONFIG_BLUEZ_HCIBLUECARD=m
-CONFIG_BLUEZ_HCIBTUART=m
-CONFIG_BLUEZ_HCIVHCI=m
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_NO_PGT_CACHE is not set
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_ERRORS is not set
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
-
-#
-# Library routines
-#
-# CONFIG_CRC32 is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
-# CONFIG_FW_LOADER is not set
diff --git a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/disable-pcmcia-probe.patch b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/disable-pcmcia-probe.patch
deleted file mode 100644
index 79ba036323..0000000000
--- a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/disable-pcmcia-probe.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-
-#
-# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux/drivers/pcmcia/Config.in~disable-pcmcia-probe 2003-05-13 11:18:23.000000000 +0200
-+++ linux/drivers/pcmcia/Config.in 2004-05-27 13:59:50.000000000 +0200
-@@ -15,9 +15,6 @@
- tristate 'PCMCIA/CardBus support' CONFIG_PCMCIA
- if [ "$CONFIG_PCMCIA" != "n" ]; then
- # yes, I really mean the following...
-- if [ "$CONFIG_ISA" = "y" -o "$CONFIG_ARCH_SA1100" = "y" ]; then
-- define_bool CONFIG_PCMCIA_PROBE y
-- fi
- if [ "$CONFIG_PCI" != "n" ]; then
- bool ' CardBus support' CONFIG_CARDBUS
- fi
diff --git a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/keymap.patch b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/keymap.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/keymap.patch
+++ /dev/null
diff --git a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/mkdep.patch b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/mkdep.patch
deleted file mode 100644
index 57218a7d1a..0000000000
--- a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/mkdep.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-
-#
-# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux-2.4.25/Makefile~mkdep 2004-03-31 17:15:12.000000000 +0200
-+++ linux-2.4.25/Makefile 2004-03-31 17:18:50.000000000 +0200
-@@ -502,7 +502,7 @@
- ifdef CONFIG_MODVERSIONS
- $(MAKE) update-modverfile
- endif
-- scripts/mkdep -- `find $(FINDHPATH) \( -name SCCS -o -name .svn \) -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend
-+ $(foreach, dir, $(FINDHPATH), scripts/mkdep -- `find $(dir) -name SCCS -prune -o -follow -name \*.h ! -name modversions.h -print` >> .hdepend)
- scripts/mkdep -- init/*.c > .depend
-
- ifdef CONFIG_MODVERSIONS
diff --git a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/mppe-20040216.patch b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/mppe-20040216.patch
deleted file mode 100644
index 4393e2ea83..0000000000
--- a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/mppe-20040216.patch
+++ /dev/null
@@ -1,1225 +0,0 @@
-
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- linux-2.4.25/drivers/net/Config.in~mppe-20040216
-+++ linux-2.4.25/drivers/net/Config.in
-@@ -327,6 +327,7 @@
- dep_tristate ' PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP
- dep_tristate ' PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP
- dep_tristate ' PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP $CONFIG_PPP
-+ dep_tristate ' PPP MPPE compression (encryption)' CONFIG_PPP_MPPE $CONFIG_PPP
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- dep_tristate ' PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP
- fi
---- /dev/null
-+++ linux-2.4.25/drivers/net/arcfour.c
-@@ -0,0 +1,75 @@
-+/*
-+ * arcfour.c
-+ * by Frank Cusack <frank@google.com>
-+ * 100% public domain
-+ *
-+ * Implemented from the description in _Applied Cryptography_, 2nd ed.
-+ *
-+ * ** Distribution ** of this software is unlimited and unrestricted.
-+ *
-+ * ** Use ** of this software is almost certainly legal; however, refer
-+ * to <http://theory.lcs.mit.edu/~rivest/faq.html>.
-+ */
-+
-+#include "arcfour.h"
-+#if defined(__linux__)
-+#include <linux/string.h>
-+#endif
-+
-+#define swap(a, b) \
-+{ \
-+ unsigned char t = b; \
-+ b = a; \
-+ a = t; \
-+}
-+
-+/*
-+ * Initialize arcfour from a key.
-+ */
-+void
-+arcfour_setkey(arcfour_context *context, const unsigned char *key,
-+ unsigned keylen)
-+{
-+ unsigned i, j;
-+ unsigned char K[256];
-+
-+ context->i = context->j = 0;
-+
-+ for (i = 0; i < 256; i++) {
-+ context->S[i] = i;
-+ K[i] = key[i % keylen];
-+ }
-+
-+ j = 0;
-+ for (i = 0; i < 256; i++) {
-+ j = (j + context->S[i] + K[i]) % 256;
-+ swap(context->S[i], context->S[j]);
-+ }
-+
-+ memset(K, 0, sizeof(K));
-+}
-+
-+/*
-+ * plaintext -> ciphertext (or vice versa)
-+ */
-+void
-+arcfour_encrypt(arcfour_context *context, const unsigned char *in, unsigned len,
-+ unsigned char *out)
-+{
-+ unsigned i = context->i;
-+ unsigned j = context->j;
-+ unsigned char *S = context->S;
-+ unsigned char K;
-+
-+ while (len--) {
-+ i = (i + 1) % 256;
-+ j = (j + S[i]) % 256;
-+ swap(S[i], S[j]);
-+ K = S[(S[i] + S[j]) % 256];
-+ *out++ = *in++ ^ K;
-+ }
-+
-+ context->i = i;
-+ context->j = j;
-+}
-+
---- /dev/null
-+++ linux-2.4.25/drivers/net/arcfour.h
-@@ -0,0 +1,17 @@
-+/* arcfour.h */
-+
-+#ifndef _ARCFOUR_H
-+#define _ARCFOUR_H
-+
-+typedef struct {
-+ unsigned i;
-+ unsigned j;
-+ unsigned char S[256];
-+} arcfour_context;
-+
-+extern void arcfour_setkey(arcfour_context *, const unsigned char *, unsigned);
-+extern void arcfour_encrypt(arcfour_context *, const unsigned char *, unsigned,
-+ unsigned char *);
-+#define arcfour_decrypt arcfour_encrypt
-+
-+#endif /* _ARCFOUR_H */
---- linux-2.4.25/drivers/net/ppp_generic.c~mppe-20040216
-+++ linux-2.4.25/drivers/net/ppp_generic.c
-@@ -102,6 +102,7 @@
- spinlock_t rlock; /* lock for receive side 58 */
- spinlock_t wlock; /* lock for transmit side 5c */
- int mru; /* max receive unit 60 */
-+ int mru_alloc; /* MAX(1500,MRU) for dev_alloc_skb() */
- unsigned int flags; /* control bits 64 */
- unsigned int xstate; /* transmit state bits 68 */
- unsigned int rstate; /* receive state bits 6c */
-@@ -129,6 +130,7 @@
- struct sock_fprog pass_filter; /* filter for packets to pass */
- struct sock_fprog active_filter;/* filter for pkts to reset idle */
- #endif /* CONFIG_PPP_FILTER */
-+ int xpad; /* ECP or CCP (MPPE) transmit padding */
- };
-
- /*
-@@ -552,7 +554,9 @@
- case PPPIOCSMRU:
- if (get_user(val, (int *) arg))
- break;
-- ppp->mru = val;
-+ ppp->mru_alloc = ppp->mru = val;
-+ if (ppp->mru_alloc < PPP_MRU)
-+ ppp->mru_alloc = PPP_MRU; /* increase for broken peers */
- err = 0;
- break;
-
-@@ -1031,8 +1035,8 @@
- /* try to do packet compression */
- if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
- && proto != PPP_LCP && proto != PPP_CCP) {
-- new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len,
-- GFP_ATOMIC);
-+ new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len
-+ + ppp->xpad, GFP_ATOMIC);
- if (new_skb == 0) {
- printk(KERN_ERR "PPP: no memory (comp pkt)\n");
- goto drop;
-@@ -1044,15 +1048,28 @@
- /* compressor still expects A/C bytes in hdr */
- len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
- new_skb->data, skb->len + 2,
-- ppp->dev->mtu + PPP_HDRLEN);
-+ ppp->dev->mtu + ppp->xpad
-+ + PPP_HDRLEN);
- if (len > 0 && (ppp->flags & SC_CCP_UP)) {
- kfree_skb(skb);
- skb = new_skb;
- skb_put(skb, len);
- skb_pull(skb, 2); /* pull off A/C bytes */
-- } else {
-+ } else if (len == 0) {
- /* didn't compress, or CCP not up yet */
- kfree_skb(new_skb);
-+ } else {
-+ /*
-+ * (len < 0)
-+ * MPPE requires that we do not send unencrypted
-+ * frames. The compressor will return -1 if we
-+ * should drop the frame. We cannot simply test
-+ * the compress_proto because MPPE and MPPC share
-+ * the same number.
-+ */
-+ printk(KERN_ERR "ppp: compressor dropped pkt\n");
-+ kfree_skb(new_skb);
-+ goto drop;
- }
- }
-
-@@ -1540,14 +1557,15 @@
- int len;
-
- if (proto == PPP_COMP) {
-- ns = dev_alloc_skb(ppp->mru + PPP_HDRLEN);
-+ ns = dev_alloc_skb(ppp->mru_alloc + PPP_HDRLEN);
- if (ns == 0) {
- printk(KERN_ERR "ppp_decompress_frame: no memory\n");
- goto err;
- }
- /* the decompressor still expects the A/C bytes in the hdr */
- len = ppp->rcomp->decompress(ppp->rc_state, skb->data - 2,
-- skb->len + 2, ns->data, ppp->mru + PPP_HDRLEN);
-+ skb->len + 2, ns->data,
-+ ppp->mru_alloc + PPP_HDRLEN);
- if (len < 0) {
- /* Pass the compressed frame to pppd as an
- error indication. */
-@@ -1982,6 +2000,20 @@
- ocomp->comp_free(ostate);
- err = 0;
- }
-+ if (ccp_option[0] == CI_MPPE)
-+ /*
-+ * pppd (userland) has reduced the MTU by MPPE_PAD,
-+ * to accomodate "compressor" growth. We must
-+ * increase the space allocated for compressor
-+ * output in ppp_send_frame() accordingly. Note
-+ * that from a purist's view, it may be more correct
-+ * to require multilink and fragment large packets,
-+ * but that seems inefficient compared to this
-+ * little trick.
-+ */
-+ ppp->xpad = MPPE_PAD;
-+ else
-+ ppp->xpad = 0;
-
- } else {
- state = cp->decomp_alloc(ccp_option, data.length);
-@@ -2253,6 +2285,7 @@
- /* Initialize the new ppp unit */
- ppp->file.index = unit;
- ppp->mru = PPP_MRU;
-+ ppp->mru_alloc = PPP_MRU;
- init_ppp_file(&ppp->file, INTERFACE);
- ppp->file.hdrlen = PPP_HDRLEN - 2; /* don't count proto bytes */
- for (i = 0; i < NUM_NP; ++i)
---- /dev/null
-+++ linux-2.4.25/drivers/net/ppp_mppe_compress.c
-@@ -0,0 +1,643 @@
-+/*
-+ * ==FILEVERSION 20020521==
-+ *
-+ * ppp_mppe_compress.c - interface MPPE to the PPP code.
-+ * This version is for use with Linux kernel 2.2.19+ and 2.4.x.
-+ *
-+ * By Frank Cusack <frank@google.com>.
-+ * Copyright (c) 2002 Google, Inc.
-+ * All rights reserved.
-+ *
-+ * Permission to use, copy, modify, and distribute this software and its
-+ * documentation is hereby granted, provided that the above copyright
-+ * notice appears in all copies. This software is provided without any
-+ * warranty, express or implied.
-+ *
-+ * Changelog:
-+ * 2/15/04 - TS: added #include <version.h> and testing for Kernel
-+ * version before using
-+ * MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are
-+ * depreciated in 2.6
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/version.h>
-+#include <linux/init.h>
-+#include <linux/types.h>
-+#include <linux/slab.h>
-+#include <linux/string.h>
-+
-+#include <linux/ppp_defs.h>
-+#include <linux/ppp-comp.h>
-+
-+#include "arcfour.h"
-+#include "sha1.h"
-+
-+/*
-+ * State for an MPPE (de)compressor.
-+ */
-+typedef struct ppp_mppe_state {
-+ unsigned char master_key[MPPE_MAX_KEY_LEN];
-+ unsigned char session_key[MPPE_MAX_KEY_LEN];
-+ arcfour_context arcfour_context; /* encryption state */
-+ unsigned keylen; /* key length in bytes */
-+ /* NB: 128-bit == 16, 40-bit == 8! */
-+ /* If we want to support 56-bit, */
-+ /* the unit has to change to bits */
-+ unsigned char bits; /* MPPE control bits */
-+ unsigned ccount; /* 12-bit coherency count (seqno) */
-+ unsigned stateful; /* stateful mode flag */
-+ int discard; /* stateful mode packet loss flag */
-+ int sanity_errors; /* take down LCP if too many */
-+ int unit;
-+ int debug;
-+ struct compstat stats;
-+} ppp_mppe_state;
-+
-+/* ppp_mppe_state.bits definitions */
-+#define MPPE_BIT_A 0x80 /* Encryption table were (re)inititalized */
-+#define MPPE_BIT_B 0x40 /* MPPC only (not implemented) */
-+#define MPPE_BIT_C 0x20 /* MPPC only (not implemented) */
-+#define MPPE_BIT_D 0x10 /* This is an encrypted frame */
-+
-+#define MPPE_BIT_FLUSHED MPPE_BIT_A
-+#define MPPE_BIT_ENCRYPTED MPPE_BIT_D
-+
-+#define MPPE_BITS(p) ((p)[4] & 0xf0)
-+#define MPPE_CCOUNT(p) ((((p)[4] & 0x0f) << 8) + (p)[5])
-+#define MPPE_CCOUNT_SPACE 0x1000 /* The size of the ccount space */
-+
-+#define MPPE_OVHD 2 /* MPPE overhead/packet */
-+#define SANITY_MAX 1600 /* Max bogon factor we will tolerate */
-+
-+static void GetNewKeyFromSHA __P((unsigned char *StartKey,
-+ unsigned char *SessionKey,
-+ unsigned SessionKeyLength,
-+ unsigned char *InterimKey));
-+static void mppe_rekey __P((ppp_mppe_state *state, int));
-+static void *mppe_alloc __P((unsigned char *options, int optlen));
-+static void mppe_free __P((void *state));
-+static int mppe_init __P((void *state, unsigned char *options,
-+ int optlen, int unit, int debug, const char *));
-+static int mppe_comp_init __P((void *state, unsigned char *options,
-+ int optlen,
-+ int unit, int hdrlen, int debug));
-+static int mppe_decomp_init __P((void *state, unsigned char *options,
-+ int optlen, int unit,
-+ int hdrlen, int mru, int debug));
-+static int mppe_compress __P((void *state, unsigned char *ibuf,
-+ unsigned char *obuf,
-+ int isize, int osize));
-+static void mppe_incomp __P((void *state, unsigned char *ibuf, int icnt));
-+static int mppe_decompress __P((void *state, unsigned char *ibuf,
-+ int isize, unsigned char *obuf,int osize));
-+static void mppe_comp_reset __P((void *state));
-+static void mppe_decomp_reset __P((void *state));
-+static void mppe_comp_stats __P((void *state, struct compstat *stats));
-+
-+
-+/*
-+ * Key Derivation, from RFC 3078, RFC 3079.
-+ * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
-+ */
-+static void
-+GetNewKeyFromSHA(unsigned char *MasterKey, unsigned char *SessionKey,
-+ unsigned SessionKeyLength, unsigned char *InterimKey)
-+{
-+ SHA1_CTX Context;
-+ unsigned char Digest[SHA1_SIGNATURE_SIZE];
-+
-+ unsigned char SHApad1[40] =
-+ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-+ unsigned char SHApad2[40] =
-+ { 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
-+ 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
-+ 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
-+ 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 };
-+
-+ /* assert(SessionKeyLength <= SHA1_SIGNATURE_SIZE); */
-+
-+ SHA1_Init(&Context);
-+ SHA1_Update(&Context, MasterKey, SessionKeyLength);
-+ SHA1_Update(&Context, SHApad1, sizeof(SHApad1));
-+ SHA1_Update(&Context, SessionKey, SessionKeyLength);
-+ SHA1_Update(&Context, SHApad2, sizeof(SHApad2));
-+ SHA1_Final(Digest, &Context);
-+
-+ memcpy(InterimKey, Digest, SessionKeyLength);
-+}
-+
-+/*
-+ * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3.
-+ * Well, not what's written there, but rather what they meant.
-+ */
-+static void
-+mppe_rekey(ppp_mppe_state *state, int initial_key)
-+{
-+ unsigned char InterimKey[MPPE_MAX_KEY_LEN];
-+
-+ GetNewKeyFromSHA(state->master_key, state->session_key,
-+ state->keylen, InterimKey);
-+ if (!initial_key) {
-+ arcfour_setkey(&state->arcfour_context, InterimKey, state->keylen);
-+ arcfour_encrypt(&state->arcfour_context, InterimKey, state->keylen,
-+ state->session_key);
-+ } else {
-+ memcpy(state->session_key, InterimKey, state->keylen);
-+ }
-+ if (state->keylen == 8) {
-+ /* See RFC 3078 */
-+ state->session_key[0] = 0xd1;
-+ state->session_key[1] = 0x26;
-+ state->session_key[2] = 0x9e;
-+ }
-+ arcfour_setkey(&state->arcfour_context, state->session_key, state->keylen);
-+}
-+
-+
-+/*
-+ * Allocate space for a (de)compressor.
-+ */
-+static void *
-+mppe_alloc(unsigned char *options, int optlen)
-+{
-+ ppp_mppe_state *state;
-+
-+ if (optlen != CILEN_MPPE + sizeof(state->master_key)
-+ || options[0] != CI_MPPE
-+ || options[1] != CILEN_MPPE)
-+ return NULL;
-+
-+ state = (ppp_mppe_state *) kmalloc(sizeof(*state), GFP_KERNEL);
-+ if (state == NULL)
-+ return NULL;
-+
-+/*
-+ Added to avoid module warnings about MOD_INC
-+ being depreciated in 2.6.x
-+*/
-+#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) )
-+ try_module_get(THIS_MODULE);
-+#else
-+ MOD_INC_USE_COUNT;
-+#endif
-+ memset(state, 0, sizeof(*state));
-+
-+ /* Save keys. */
-+ memcpy(state->master_key, &options[CILEN_MPPE], sizeof(state->master_key));
-+ memcpy(state->session_key, state->master_key, sizeof(state->master_key));
-+ /*
-+ * We defer initial key generation until mppe_init(), as mppe_alloc()
-+ * is called frequently during negotiation.
-+ */
-+
-+ return (void *) state;
-+}
-+
-+/*
-+ * Deallocate space for a (de)compressor.
-+ */
-+static void
-+mppe_free(void *arg)
-+{
-+ ppp_mppe_state *state = (ppp_mppe_state *) arg;
-+
-+ if (state) {
-+ kfree(state);
-+/*
-+ Added to avoid module warnings about MOD_DEC_USE_COUNT
-+ being depreciated in 2.6.x
-+*/
-+#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) )
-+ module_put(THIS_MODULE);
-+#else
-+ MOD_DEC_USE_COUNT;
-+#endif
-+ }
-+}
-+
-+
-+/*
-+ * Initialize (de)compressor state.
-+ */
-+static int
-+mppe_init(void *arg, unsigned char *options, int optlen, int unit, int debug,
-+ const char *debugstr)
-+{
-+ ppp_mppe_state *state = (ppp_mppe_state *) arg;
-+ unsigned char mppe_opts;
-+
-+ if (optlen != CILEN_MPPE
-+ || options[0] != CI_MPPE
-+ || options[1] != CILEN_MPPE)
-+ return 0;
-+
-+ MPPE_CI_TO_OPTS(&options[2], mppe_opts);
-+ if (mppe_opts & MPPE_OPT_128)
-+ state->keylen = 16;
-+ else if (mppe_opts & MPPE_OPT_40)
-+ state->keylen = 8;
-+ else {
-+ printk(KERN_WARNING "%s[%d]: unknown key length\n", debugstr, unit);
-+ return 0;
-+ }
-+ if (mppe_opts & MPPE_OPT_STATEFUL)
-+ state->stateful = 1;
-+
-+ /* Generate the initial session key. */
-+ mppe_rekey(state, 1);
-+
-+ if (debug) {
-+ int i;
-+ char mkey[sizeof(state->master_key) * 2 + 1];
-+ char skey[sizeof(state->session_key) * 2 + 1];
-+
-+ printk(KERN_DEBUG "%s[%d]: initialized with %d-bit %s mode\n", debugstr,
-+ unit, (state->keylen == 16)? 128: 40,
-+ (state->stateful)? "stateful": "stateless");
-+
-+ for (i = 0; i < sizeof(state->master_key); i++)
-+ sprintf(mkey + i * 2, "%.2x", state->master_key[i]);
-+ for (i = 0; i < sizeof(state->session_key); i++)
-+ sprintf(skey + i * 2, "%.2x", state->session_key[i]);
-+ printk(KERN_DEBUG "%s[%d]: keys: master: %s initial session: %s\n",
-+ debugstr, unit, mkey, skey);
-+ }
-+
-+ /*
-+ * Initialize the coherency count. The initial value is not specified
-+ * in RFC 3078, but we can make a reasonable assumption that it will
-+ * start at 0. Setting it to the max here makes the comp/decomp code
-+ * do the right thing (determined through experiment).
-+ */
-+ state->ccount = MPPE_CCOUNT_SPACE - 1;
-+
-+ /*
-+ * Note that even though we have initialized the key table, we don't
-+ * set the FLUSHED bit. This is contrary to RFC 3078, sec. 3.1.
-+ */
-+ state->bits = MPPE_BIT_ENCRYPTED;
-+
-+ state->unit = unit;
-+ state->debug = debug;
-+
-+ return 1;
-+}
-+
-+
-+
-+static int
-+mppe_comp_init(void *arg, unsigned char *options, int optlen, int unit,
-+ int hdrlen, int debug)
-+{
-+ /* ARGSUSED */
-+ return mppe_init(arg, options, optlen, unit, debug, "mppe_comp_init");
-+}
-+
-+/*
-+ * We received a CCP Reset-Request (actually, we are sending a Reset-Ack),
-+ * tell the compressor to rekey. Note that we MUST NOT rekey for
-+ * every CCP Reset-Request; we only rekey on the next xmit packet.
-+ * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost.
-+ * So, rekeying for every CCP Reset-Request is broken as the peer will not
-+ * know how many times we've rekeyed. (If we rekey and THEN get another
-+ * CCP Reset-Request, we must rekey again.)
-+ */
-+static void
-+mppe_comp_reset(void *arg)
-+{
-+ ppp_mppe_state *state = (ppp_mppe_state *) arg;
-+
-+ state->bits |= MPPE_BIT_FLUSHED;
-+}
-+
-+/*
-+ * Compress (encrypt) a packet.
-+ * It's strange to call this a compressor, since the output is always
-+ * MPPE_OVHD + 2 bytes larger than the input.
-+ */
-+int
-+mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
-+ int isize, int osize)
-+{
-+ ppp_mppe_state *state = (ppp_mppe_state *) arg;
-+ int proto;
-+
-+ /*
-+ * Check that the protocol is in the range we handle.
-+ */
-+ proto = PPP_PROTOCOL(ibuf);
-+ if (proto < 0x0021 || proto > 0x00fa)
-+ return 0;
-+
-+ /* Make sure we have enough room to generate an encrypted packet. */
-+ if (osize < isize + MPPE_OVHD + 2) {
-+ /* Drop the packet if we should encrypt it, but can't. */
-+ printk(KERN_DEBUG "mppe_compress[%d]: osize too small! "
-+ "(have: %d need: %d)\n", state->unit,
-+ osize, osize + MPPE_OVHD + 2);
-+ return -1;
-+ }
-+
-+ osize = isize + MPPE_OVHD + 2;
-+
-+ /*
-+ * Copy over the PPP header and set control bits.
-+ */
-+ obuf[0] = PPP_ADDRESS(ibuf);
-+ obuf[1] = PPP_CONTROL(ibuf);
-+ obuf[2] = PPP_COMP >> 8; /* isize + MPPE_OVHD + 1 */
-+ obuf[3] = PPP_COMP; /* isize + MPPE_OVHD + 2 */
-+ obuf += PPP_HDRLEN;
-+
-+ state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
-+ if (state->debug >= 7)
-+ printk(KERN_DEBUG "mppe_compress[%d]: ccount %d\n", state->unit,
-+ state->ccount);
-+ obuf[0] = state->ccount >> 8;
-+ obuf[1] = state->ccount & 0xff;
-+
-+ if (!state->stateful || /* stateless mode */
-+ ((state->ccount & 0xff) == 0xff) || /* "flag" packet */
-+ (state->bits & MPPE_BIT_FLUSHED)) { /* CCP Reset-Request */
-+ /* We must rekey */
-+ if (state->debug && state->stateful)
-+ printk(KERN_DEBUG "mppe_compress[%d]: rekeying\n", state->unit);
-+ mppe_rekey(state, 0);
-+ state->bits |= MPPE_BIT_FLUSHED;
-+ }
-+ obuf[0] |= state->bits;
-+ state->bits &= ~MPPE_BIT_FLUSHED; /* reset for next xmit */
-+
-+ obuf += MPPE_OVHD;
-+ ibuf += 2; /* skip to proto field */
-+ isize -= 2;
-+
-+ /* Encrypt packet */
-+ arcfour_encrypt(&state->arcfour_context, ibuf, isize, obuf);
-+
-+ state->stats.unc_bytes += isize;
-+ state->stats.unc_packets++;
-+ state->stats.comp_bytes += osize;
-+ state->stats.comp_packets++;
-+
-+ return osize;
-+}
-+
-+/*
-+ * Since every frame grows by MPPE_OVHD + 2 bytes, this is always going
-+ * to look bad ... and the longer the link is up the worse it will get.
-+ */
-+static void
-+mppe_comp_stats(void *arg, struct compstat *stats)
-+{
-+ ppp_mppe_state *state = (ppp_mppe_state *) arg;
-+
-+ *stats = state->stats;
-+}
-+
-+
-+static int
-+mppe_decomp_init(void *arg, unsigned char *options, int optlen, int unit,
-+ int hdrlen, int mru, int debug)
-+{
-+ /* ARGSUSED */
-+ return mppe_init(arg, options, optlen, unit, debug, "mppe_decomp_init");
-+}
-+
-+/*
-+ * We received a CCP Reset-Ack. Just ignore it.
-+ */
-+static void
-+mppe_decomp_reset(void *arg)
-+{
-+ /* ARGSUSED */
-+ return;
-+}
-+
-+/*
-+ * Decompress (decrypt) an MPPE packet.
-+ */
-+int
-+mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
-+ int osize)
-+{
-+ ppp_mppe_state *state = (ppp_mppe_state *) arg;
-+ unsigned ccount;
-+ int flushed = MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED;
-+ int sanity = 0;
-+
-+ if (isize <= PPP_HDRLEN + MPPE_OVHD) {
-+ if (state->debug)
-+ printk(KERN_DEBUG "mppe_decompress[%d]: short pkt (%d)\n",
-+ state->unit, isize);
-+ return DECOMP_ERROR;
-+ }
-+
-+ /* Make sure we have enough room to decrypt the packet. */
-+ if (osize < isize - MPPE_OVHD - 2) {
-+ printk(KERN_DEBUG "mppe_decompress[%d]: osize too small! "
-+ "(have: %d need: %d)\n", state->unit,
-+ osize, isize - MPPE_OVHD - 2);
-+ return DECOMP_ERROR;
-+ }
-+ osize = isize - MPPE_OVHD - 2;
-+
-+ ccount = MPPE_CCOUNT(ibuf);
-+ if (state->debug >= 7)
-+ printk(KERN_DEBUG "mppe_decompress[%d]: ccount %d\n", state->unit,
-+ ccount);
-+
-+ /* sanity checks -- terminate with extreme prejudice */
-+ if (!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
-+ printk(KERN_DEBUG "mppe_decompress[%d]: ENCRYPTED bit not set!\n",
-+ state->unit);
-+ state->sanity_errors += 100;
-+ sanity = 1;
-+ }
-+ if (!state->stateful && !flushed) {
-+ printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set in "
-+ "stateless mode!\n", state->unit);
-+ state->sanity_errors += 100;
-+ sanity = 1;
-+ }
-+ if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) {
-+ printk(KERN_DEBUG "mppe_decompress[%d]: FLUSHED bit not set on "
-+ "flag packet!\n", state->unit);
-+ state->sanity_errors += 100;
-+ sanity = 1;
-+ }
-+
-+ if (sanity) {
-+ if (state->sanity_errors < SANITY_MAX)
-+ return DECOMP_ERROR;
-+ else
-+ /*
-+ * Take LCP down if the peer is sending too many bogons.
-+ * We don't want to do this for a single or just a few
-+ * instances since it could just be due to packet corruption.
-+ */
-+ return DECOMP_FATALERROR;
-+ }
-+
-+ /*
-+ * Check the coherency count.
-+ */
-+
-+ if (!state->stateful) {
-+ /* RFC 3078, sec 8.1. Rekey for every packet. */
-+ while (state->ccount != ccount) {
-+ mppe_rekey(state, 0);
-+ state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
-+ }
-+ } else {
-+ /* RFC 3078, sec 8.2. */
-+ if (!state->discard) {
-+ /* normal state */
-+ state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE;
-+ if (ccount != state->ccount) {
-+ /*
-+ * (ccount > state->ccount)
-+ * Packet loss detected, enter the discard state.
-+ * Signal the peer to rekey (by sending a CCP Reset-Request).
-+ */
-+ state->discard = 1;
-+ return DECOMP_ERROR;
-+ }
-+ } else {
-+ /* discard state */
-+ if (!flushed) {
-+ /* ccp.c will be silent (no additional CCP Reset-Requests). */
-+ return DECOMP_ERROR;
-+ } else {
-+ /* Rekey for every missed "flag" packet. */
-+ while ((ccount & ~0xff) != (state->ccount & ~0xff)) {
-+ mppe_rekey(state, 0);
-+ state->ccount = (state->ccount + 256) % MPPE_CCOUNT_SPACE;
-+ }
-+
-+ /* reset */
-+ state->discard = 0;
-+ state->ccount = ccount;
-+ /*
-+ * Another problem with RFC 3078 here. It implies that the
-+ * peer need not send a Reset-Ack packet. But RFC 1962
-+ * requires it. Hopefully, M$ does send a Reset-Ack; even
-+ * though it isn't required for MPPE synchronization, it is
-+ * required to reset CCP state.
-+ */
-+ }
-+ }
-+ if (flushed)
-+ mppe_rekey(state, 0);
-+ }
-+
-+ /*
-+ * Fill in the first part of the PPP header. The protocol field
-+ * comes from the decrypted data.
-+ */
-+ obuf[0] = PPP_ADDRESS(ibuf); /* +1 */
-+ obuf[1] = PPP_CONTROL(ibuf); /* +1 */
-+ obuf += 2;
-+ ibuf += PPP_HDRLEN + MPPE_OVHD;
-+ isize -= PPP_HDRLEN + MPPE_OVHD; /* -6 */
-+ /* net osize: isize-4 */
-+
-+ /* And finally, decrypt the packet. */
-+ arcfour_decrypt(&state->arcfour_context, ibuf, isize, obuf);
-+
-+ state->stats.unc_bytes += osize;
-+ state->stats.unc_packets++;
-+ state->stats.comp_bytes += isize;
-+ state->stats.comp_packets++;
-+
-+ /* good packet credit */
-+ state->sanity_errors >>= 1;
-+
-+ return osize;
-+}
-+
-+/*
-+ * Incompressible data has arrived (this should never happen!).
-+ * We should probably drop the link if the protocol is in the range
-+ * of what should be encrypted. At the least, we should drop this
-+ * packet. (How to do this?)
-+ */
-+static void
-+mppe_incomp(void *arg, unsigned char *ibuf, int icnt)
-+{
-+ ppp_mppe_state *state = (ppp_mppe_state *) arg;
-+
-+ if (state->debug &&
-+ (PPP_PROTOCOL(ibuf) >= 0x0021 && PPP_PROTOCOL(ibuf) <= 0x00fa))
-+ printk(KERN_DEBUG "mppe_incomp[%d]: incompressible (unencrypted) data! "
-+ "(proto %04x)\n", state->unit, PPP_PROTOCOL(ibuf));
-+
-+ state->stats.inc_bytes += icnt;
-+ state->stats.inc_packets++;
-+ state->stats.unc_bytes += icnt;
-+ state->stats.unc_packets++;
-+}
-+
-+/*************************************************************
-+ * Module interface table
-+ *************************************************************/
-+
-+/* These are in ppp.c (2.2.x) or ppp_generic.c (2.4.x) */
-+extern int ppp_register_compressor (struct compressor *cp);
-+extern void ppp_unregister_compressor (struct compressor *cp);
-+
-+/*
-+ * Procedures exported to if_ppp.c.
-+ */
-+struct compressor ppp_mppe = {
-+ CI_MPPE, /* compress_proto */
-+ mppe_alloc, /* comp_alloc */
-+ mppe_free, /* comp_free */
-+ mppe_comp_init, /* comp_init */
-+ mppe_comp_reset, /* comp_reset */
-+ mppe_compress, /* compress */
-+ mppe_comp_stats, /* comp_stat */
-+ mppe_alloc, /* decomp_alloc */
-+ mppe_free, /* decomp_free */
-+ mppe_decomp_init, /* decomp_init */
-+ mppe_decomp_reset, /* decomp_reset */
-+ mppe_decompress, /* decompress */
-+ mppe_incomp, /* incomp */
-+ mppe_comp_stats, /* decomp_stat */
-+};
-+
-+/* 2.2 compatibility defines */
-+#ifndef __init
-+#define __init
-+#endif
-+#ifndef __exit
-+#define __exit
-+#endif
-+#ifndef MODULE_LICENSE
-+#define MODULE_LICENSE(license)
-+#endif
-+
-+int __init
-+ppp_mppe_init(void)
-+{
-+ int answer = ppp_register_compressor(&ppp_mppe);
-+
-+ if (answer == 0)
-+ printk(KERN_INFO "PPP MPPE Compression module registered\n");
-+ return answer;
-+}
-+
-+void __exit
-+ppp_mppe_cleanup(void)
-+{
-+ ppp_unregister_compressor(&ppp_mppe);
-+}
-+
-+module_init(ppp_mppe_init);
-+module_exit(ppp_mppe_cleanup);
-+MODULE_LICENSE("BSD without advertisement clause");
---- /dev/null
-+++ linux-2.4.25/drivers/net/sha1.c
-@@ -0,0 +1,185 @@
-+/*
-+ * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c
-+ *
-+ * SHA-1 in C
-+ * By Steve Reid <steve@edmweb.com>
-+ * 100% Public Domain
-+ *
-+ * Test Vectors (from FIPS PUB 180-1)
-+ * "abc"
-+ * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
-+ * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
-+ * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
-+ * A million repetitions of "a"
-+ * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
-+ */
-+
-+/* #define SHA1HANDSOFF * Copies data before messing with it. */
-+
-+#if defined(__linux__)
-+#include <asm/byteorder.h>
-+#include <linux/string.h>
-+#elif defined(__solaris__)
-+#include <sys/isa_defs.h>
-+#include <sys/ddi.h>
-+#include <sys/sunddi.h>
-+#define memcpy(d, s, c) bcopy(s, d, c)
-+#define memset(d, b, c) bzero(d, c)
-+#endif
-+
-+#include "sha1.h"
-+
-+static void SHA1_Transform(unsigned long[5], const unsigned char[64]);
-+
-+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-+
-+/* blk0() and blk() perform the initial expand. */
-+/* I got the idea of expanding during the round function from SSLeay */
-+#if defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN)
-+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
-+ |(rol(block->l[i],8)&0x00FF00FF))
-+#elif defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)
-+#define blk0(i) block->l[i]
-+#else
-+#error Endianness not defined
-+#endif
-+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
-+ ^block->l[(i+2)&15]^block->l[i&15],1))
-+
-+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
-+#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
-+#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
-+#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
-+#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
-+#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
-+
-+
-+/* Hash a single 512-bit block. This is the core of the algorithm. */
-+
-+static void
-+SHA1_Transform(unsigned long state[5], const unsigned char buffer[64])
-+{
-+ unsigned long a, b, c, d, e;
-+ typedef union {
-+ unsigned char c[64];
-+ unsigned long l[16];
-+ } CHAR64LONG16;
-+ CHAR64LONG16 *block;
-+
-+#ifdef SHA1HANDSOFF
-+ static unsigned char workspace[64];
-+ block = (CHAR64LONG16 *) workspace;
-+ memcpy(block, buffer, 64);
-+#else
-+ block = (CHAR64LONG16 *) buffer;
-+#endif
-+ /* Copy context->state[] to working vars */
-+ a = state[0];
-+ b = state[1];
-+ c = state[2];
-+ d = state[3];
-+ e = state[4];
-+ /* 4 rounds of 20 operations each. Loop unrolled. */
-+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
-+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
-+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
-+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
-+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
-+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
-+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
-+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
-+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
-+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
-+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
-+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
-+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
-+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
-+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
-+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
-+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
-+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
-+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
-+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
-+ /* Add the working vars back into context.state[] */
-+ state[0] += a;
-+ state[1] += b;
-+ state[2] += c;
-+ state[3] += d;
-+ state[4] += e;
-+ /* Wipe variables */
-+ a = b = c = d = e = 0;
-+}
-+
-+
-+/* SHA1Init - Initialize new context */
-+
-+void
-+SHA1_Init(SHA1_CTX *context)
-+{
-+ /* SHA1 initialization constants */
-+ context->state[0] = 0x67452301;
-+ context->state[1] = 0xEFCDAB89;
-+ context->state[2] = 0x98BADCFE;
-+ context->state[3] = 0x10325476;
-+ context->state[4] = 0xC3D2E1F0;
-+ context->count[0] = context->count[1] = 0;
-+}
-+
-+
-+/* Run your data through this. */
-+
-+void
-+SHA1_Update(SHA1_CTX *context, const unsigned char *data, unsigned int len)
-+{
-+ unsigned int i, j;
-+
-+ j = (context->count[0] >> 3) & 63;
-+ if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
-+ context->count[1] += (len >> 29);
-+ if ((j + len) > 63) {
-+ memcpy(&context->buffer[j], data, (i = 64-j));
-+ SHA1_Transform(context->state, context->buffer);
-+ for ( ; i + 63 < len; i += 64) {
-+ SHA1_Transform(context->state, &data[i]);
-+ }
-+ j = 0;
-+ }
-+ else
-+ i = 0;
-+
-+ memcpy(&context->buffer[j], &data[i], len - i);
-+}
-+
-+
-+/* Add padding and return the message digest. */
-+
-+void
-+SHA1_Final(unsigned char digest[20], SHA1_CTX *context)
-+{
-+ unsigned long i, j;
-+ unsigned char finalcount[8];
-+
-+ for (i = 0; i < 8; i++) {
-+ finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
-+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
-+ }
-+ SHA1_Update(context, (unsigned char *) "\200", 1);
-+ while ((context->count[0] & 504) != 448) {
-+ SHA1_Update(context, (unsigned char *) "\0", 1);
-+ }
-+ SHA1_Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
-+ for (i = 0; i < 20; i++) {
-+ digest[i] = (unsigned char)
-+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
-+ }
-+ /* Wipe variables */
-+ i = j = 0;
-+ memset(context->buffer, 0, 64);
-+ memset(context->state, 0, 20);
-+ memset(context->count, 0, 8);
-+ memset(&finalcount, 0, 8);
-+#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
-+ SHA1Transform(context->state, context->buffer);
-+#endif
-+}
-+
---- /dev/null
-+++ linux-2.4.25/drivers/net/sha1.h
-@@ -0,0 +1,18 @@
-+/* sha1.h */
-+
-+#ifndef _SHA1_H
-+#define _SHA1_H
-+
-+typedef struct {
-+ unsigned long state[5];
-+ unsigned long count[2];
-+ unsigned char buffer[64];
-+} SHA1_CTX;
-+
-+#define SHA1_SIGNATURE_SIZE 20
-+
-+extern void SHA1_Init(SHA1_CTX *);
-+extern void SHA1_Update(SHA1_CTX *, const unsigned char *, unsigned int);
-+extern void SHA1_Final(unsigned char[SHA1_SIGNATURE_SIZE], SHA1_CTX *);
-+
-+#endif /* _SHA1_H */
---- linux-2.4.25/include/linux/ppp-comp.h~mppe-20040216
-+++ linux-2.4.25/include/linux/ppp-comp.h
-@@ -187,6 +187,100 @@
- #define DEFLATE_CHK_SEQUENCE 0
-
- /*
-+ * Definitions for MPPE.
-+ */
-+
-+#define CI_MPPE 18 /* config option for MPPE */
-+#define CILEN_MPPE 6 /* length of config option */
-+
-+#define MPPE_PAD 4 /* MPPE growth per frame */
-+#define MPPE_MAX_KEY_LEN 16 /* largest key length (128-bit) */
-+
-+/* option bits for ccp_options.mppe */
-+#define MPPE_OPT_40 0x01 /* 40 bit */
-+#define MPPE_OPT_128 0x02 /* 128 bit */
-+#define MPPE_OPT_STATEFUL 0x04 /* stateful mode */
-+/* unsupported opts */
-+#define MPPE_OPT_56 0x08 /* 56 bit */
-+#define MPPE_OPT_MPPC 0x10 /* MPPC compression */
-+#define MPPE_OPT_D 0x20 /* Unknown */
-+#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D)
-+#define MPPE_OPT_UNKNOWN 0x40 /* Bits !defined in RFC 3078 were set */
-+
-+/*
-+ * This is not nice ... the alternative is a bitfield struct though.
-+ * And unfortunately, we cannot share the same bits for the option
-+ * names above since C and H are the same bit. We could do a u_int32
-+ * but then we have to do a htonl() all the time and/or we still need
-+ * to know which octet is which.
-+ */
-+#define MPPE_C_BIT 0x01 /* MPPC */
-+#define MPPE_D_BIT 0x10 /* Obsolete, usage unknown */
-+#define MPPE_L_BIT 0x20 /* 40-bit */
-+#define MPPE_S_BIT 0x40 /* 128-bit */
-+#define MPPE_M_BIT 0x80 /* 56-bit, not supported */
-+#define MPPE_H_BIT 0x01 /* Stateless (in a different byte) */
-+
-+/* Does not include H bit; used for least significant octet only. */
-+#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT)
-+
-+/* Build a CI from mppe opts (see RFC 3078) */
-+#define MPPE_OPTS_TO_CI(opts, ci) \
-+ do { \
-+ u_char *ptr = ci; /* u_char[4] */ \
-+ \
-+ /* H bit */ \
-+ if (opts & MPPE_OPT_STATEFUL) \
-+ *ptr++ = 0x0; \
-+ else \
-+ *ptr++ = MPPE_H_BIT; \
-+ *ptr++ = 0; \
-+ *ptr++ = 0; \
-+ \
-+ /* S,L bits */ \
-+ *ptr = 0; \
-+ if (opts & MPPE_OPT_128) \
-+ *ptr |= MPPE_S_BIT; \
-+ if (opts & MPPE_OPT_40) \
-+ *ptr |= MPPE_L_BIT; \
-+ /* M,D,C bits not supported */ \
-+ } while (/* CONSTCOND */ 0)
-+
-+/* The reverse of the above */
-+#define MPPE_CI_TO_OPTS(ci, opts) \
-+ do { \
-+ u_char *ptr = ci; /* u_char[4] */ \
-+ \
-+ opts = 0; \
-+ \
-+ /* H bit */ \
-+ if (!(ptr[0] & MPPE_H_BIT)) \
-+ opts |= MPPE_OPT_STATEFUL; \
-+ \
-+ /* S,L bits */ \
-+ if (ptr[3] & MPPE_S_BIT) \
-+ opts |= MPPE_OPT_128; \
-+ if (ptr[3] & MPPE_L_BIT) \
-+ opts |= MPPE_OPT_40; \
-+ \
-+ /* M,D,C bits */ \
-+ if (ptr[3] & MPPE_M_BIT) \
-+ opts |= MPPE_OPT_56; \
-+ if (ptr[3] & MPPE_D_BIT) \
-+ opts |= MPPE_OPT_D; \
-+ if (ptr[3] & MPPE_C_BIT) \
-+ opts |= MPPE_OPT_MPPC; \
-+ \
-+ /* Other bits */ \
-+ if (ptr[0] & ~MPPE_H_BIT) \
-+ opts |= MPPE_OPT_UNKNOWN; \
-+ if (ptr[1] || ptr[2]) \
-+ opts |= MPPE_OPT_UNKNOWN; \
-+ if (ptr[3] & ~MPPE_ALL_BITS) \
-+ opts |= MPPE_OPT_UNKNOWN; \
-+ } while (/* CONSTCOND */ 0)
-+
-+/*
- * Definitions for other, as yet unsupported, compression methods.
- */
-
---- linux-2.4.25/drivers/net/Makefile~mppe-20040216
-+++ linux-2.4.25/drivers/net/Makefile
-@@ -18,8 +18,9 @@
- export-objs := 8390.o arlan.o aironet4500_core.o aironet4500_card.o \
- ppp_async.o ppp_generic.o slhc.o pppox.o auto_irq.o \
- net_init.o mii.o
--list-multi := rcpci.o
-+list-multi := rcpci.o ppp_mppe.o
- rcpci-objs := rcpci45.o rclanmtl.o
-+ppp_mppe-objs := ppp_mppe_compress.o sha1.o arcfour.o
-
- ifeq ($(CONFIG_TULIP),y)
- obj-y += tulip/tulip.o
-@@ -163,6 +164,14 @@
- obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
- obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
-
-+ifeq ($(CONFIG_PPP_MPPE),y)
-+ obj-y += $(ppp_mppe-objs)
-+else
-+ ifeq ($(CONFIG_PPP_MPPE),m)
-+ obj-m += ppp_mppe.o
-+ endif
-+endif
-+
- obj-$(CONFIG_SLIP) += slip.o
- ifeq ($(CONFIG_SLIP_COMPRESSED),y)
- obj-$(CONFIG_SLIP) += slhc.o
-@@ -269,3 +278,7 @@
-
- rcpci.o: $(rcpci-objs)
- $(LD) -r -o $@ $(rcpci-objs)
-+
-+ppp_mppe.o: $(ppp_mppe-objs)
-+ $(LD) -r -o $@ $(ppp_mppe-objs)
-+
diff --git a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/scrolling-area.patch b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/scrolling-area.patch
deleted file mode 100644
index c4f7758b3c..0000000000
--- a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/scrolling-area.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-
-#
-# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux-2.4.25/drivers/video/fbcon.c~scrolling-area.patch 2003-08-25 13:44:42.000000000 +0200
-+++ linux-2.4.25/drivers/video/fbcon.c 2004-03-31 17:15:13.000000000 +0200
-@@ -110,8 +110,8 @@
- # define DPRINTK(fmt, args...)
- #endif
-
--#define LOGO_H 80
--#define LOGO_W 80
-+#define LOGO_H 400
-+#define LOGO_W 800
- #define LOGO_LINE (LOGO_W/8)
-
- struct display fb_display[MAX_NR_CONSOLES];
diff --git a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-apm.diff b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-apm.diff
deleted file mode 100644
index dfdbd99237..0000000000
--- a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-apm.diff
+++ /dev/null
@@ -1,799 +0,0 @@
---- /mnt/bdisk/openembedded/oetmp/base/opensimpad-2.4.25-vrs2-pxa1-jpm1-r5/linux-2.4.25/arch/arm/mach-sa1100/pm-common.c 1970-01-01 01:00:00.000000000 +0100
-+++ arch/arm/mach-sa1100/pm-common.c 2004-07-04 14:56:34.000000000 +0200
-@@ -0,0 +1,268 @@
-+/*
-+ * SA1100 Power Management Routines
-+ *
-+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License.
-+ *
-+ * History:
-+ *
-+ * 2001-02-06: Cliff Brake Initial code
-+ *
-+ * 2001-02-25: Sukjae Cho <sjcho@east.isi.edu> &
-+ * Chester Kuo <chester@linux.org.tw>
-+ * Save more value for the resume function! Support
-+ * Bitsy/Assabet/Freebird board
-+ *
-+ * 2001-08-29: Nicolas Pitre <nico@cam.org>
-+ * Cleaned up, pushed platform dependent stuff
-+ * in the platform specific files.
-+ *
-+ * 2002-05-27: Nicolas Pitre Killed sleep.h and the kmalloced save array.
-+ * Storage is local on the stack now.
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/pm.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/sysctl.h>
-+#include <linux/errno.h>
-+#include <linux/cpufreq.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/memory.h>
-+#include <asm/system.h>
-+#include <asm/leds.h>
-+#include <asm/uaccess.h>
-+
-+
-+#ifdef CONFIG_IPAQ_HANDHELD
-+#include <asm/arch-sa1100/h3600_asic.h>
-+#endif
-+
-+#define __KERNEL_SYSCALLS__
-+#include <linux/unistd.h>
-+
-+/*
-+ * Debug macros
-+ */
-+#undef DEBUG
-+
-+
-+
-+static char pm_helper_path[128] = "/sbin/pm_helper";
-+extern int exec_usermodehelper(char *path, char **argv, char **envp);
-+int debug_pm = 0;
-+static int pm_helper_veto = 0;
-+
-+static int
-+run_sbin_pm_helper( pm_request_t action )
-+{
-+ int i;
-+ char *argv[3], *envp[8];
-+
-+ if (!pm_helper_path[0])
-+ return 2;
-+
-+ if ( action != PM_SUSPEND && action != PM_RESUME )
-+ return 1;
-+
-+ /* Be root */
-+ current->uid = current->gid = 0;
-+
-+ i = 0;
-+ argv[i++] = pm_helper_path;
-+ argv[i++] = (action == PM_RESUME ? "resume" : "suspend");
-+ argv[i] = 0;
-+
-+ i = 0;
-+ /* minimal command environment */
-+ envp[i++] = "HOME=/";
-+ envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-+ envp[i] = 0;
-+
-+ /* other stuff we want to pass to /sbin/pm_helper */
-+ return exec_usermodehelper (argv [0], argv, envp);
-+}
-+
-+/*
-+ * If pm_suggest_suspend_hook is non-NULL, it is called by pm_suggest_suspend.
-+ */
-+int (*pm_suggest_suspend_hook)(int state);
-+EXPORT_SYMBOL(pm_suggest_suspend_hook);
-+
-+/*
-+ * If pm_use_sbin_pm_helper is nonzero, then run_sbin_pm_helper is called before suspend and after resume
-+ */
-+int pm_use_sbin_pm_helper = 1;
-+EXPORT_SYMBOL(pm_use_sbin_pm_helper);
-+
-+/*
-+ * If sysctl_pm_do_suspend_hook is non-NULL, it is called by sysctl_pm_do_suspend.
-+ * If it returns a true value, then pm_suspend is not called.
-+ * Use this to hook in apmd, for now.
-+ */
-+int (*pm_sysctl_suspend_hook)(int state);
-+EXPORT_SYMBOL(pm_sysctl_suspend_hook);
-+
-+int pm_suspend(void);
-+
-+int pm_suggest_suspend(void)
-+{
-+ int retval;
-+
-+ if (pm_suggest_suspend_hook) {
-+ if (pm_suggest_suspend_hook(PM_SUSPEND))
-+ return 0;
-+ }
-+
-+ if (pm_use_sbin_pm_helper) {
-+ pid_t pid;
-+ int res;
-+ int status = 0;
-+ unsigned int old_fs;
-+
-+ pid = kernel_thread ((int (*) (void *)) run_sbin_pm_helper, (void *) PM_SUSPEND, 0 );
-+ if ( pid < 0 )
-+ return pid;
-+
-+ if (debug_pm)
-+ printk(KERN_CRIT "%s:%d got pid=%d\n", __FUNCTION__, __LINE__, pid);
-+
-+ old_fs = get_fs ();
-+ set_fs (get_ds ());
-+ res = waitpid(pid, &status, __WCLONE);
-+ set_fs (old_fs);
-+
-+ if ( pid != res ) {
-+ if (debug_pm)
-+ printk(KERN_CRIT ": waitpid returned %d (exit_code=%d); not suspending\n", res, status );
-+
-+ return -1;
-+ }
-+
-+ /*if ( WIFEXITED(status) && ( WIFEXITSTATUS(status) != 0 )) {*/
-+ if (( status & 0xff7f ) != 0 ) {
-+ if (pm_helper_veto) {
-+ if (debug_pm)
-+ printk(KERN_CRIT "%s: SUSPEND WAS CANCELLED BY pm_helper (exit status %d)\n", __FUNCTION__, status >> 8);
-+ return -1;
-+ } else {
-+ if (debug_pm)
-+ printk(KERN_CRIT "%s: pm_helper returned %d, but going ahead anyway\n", __FUNCTION__, status >> 8);
-+ }
-+ }
-+ }
-+
-+ if (debug_pm)
-+ printk(KERN_CRIT "%s: REALLY SUSPENDING NOW\n", __FUNCTION__ );
-+
-+ if (pm_sysctl_suspend_hook) {
-+ if (pm_sysctl_suspend_hook(PM_SUSPEND))
-+ return 0;
-+ }
-+
-+ retval = pm_suspend();
-+ if (retval) {
-+ if (debug_pm)
-+ printk(KERN_CRIT "pm_suspend returned %d\n", retval);
-+ return retval;
-+ }
-+
-+ if (pm_use_sbin_pm_helper) {
-+ pid_t pid;
-+
-+ if (debug_pm)
-+ printk(KERN_CRIT "%s: running pm_helper for wakeup\n", __FUNCTION__);
-+
-+ pid = kernel_thread ((int (*) (void *)) run_sbin_pm_helper, (void *) PM_RESUME, 0 );
-+ if ( pid < 0 )
-+ return pid;
-+
-+ if ( pid != waitpid ( pid, NULL, __WCLONE ))
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+EXPORT_SYMBOL(pm_suggest_suspend);
-+
-+
-+/*
-+ * Send us to sleep.
-+ */
-+int pm_suspend(void)
-+{
-+ int retval;
-+
-+ retval = pm_send_all(PM_SUSPEND, (void *)3);
-+ if ( retval )
-+ return retval;
-+
-+#ifdef CONFIG_IPAQ_HANDHELD
-+ retval = h3600_power_management(PM_SUSPEND);
-+ if (retval) {
-+ pm_send_all(PM_RESUME, (void *)0);
-+ return retval;
-+ }
-+#endif
-+
-+ retval = pm_do_suspend();
-+
-+#ifdef CONFIG_IPAQ_HANDHELD
-+ /* Allow the power management routines to override resuming */
-+ while ( h3600_power_management(PM_RESUME) )
-+ retval = pm_do_suspend();
-+#endif
-+
-+ pm_send_all(PM_RESUME, (void *)0);
-+
-+ return retval;
-+}
-+EXPORT_SYMBOL(pm_suspend);
-+
-+#ifdef CONFIG_SYSCTL
-+/*
-+ * ARGH! ACPI people defined CTL_ACPI in linux/acpi.h rather than
-+ * linux/sysctl.h.
-+ *
-+ * This means our interface here won't survive long - it needs a new
-+ * interface. Quick hack to get this working - use sysctl id 9999.
-+ */
-+#warning ACPI broke the kernel, this interface needs to be fixed up.
-+#define CTL_ACPI 9999
-+#define ACPI_S1_SLP_TYP 19
-+
-+static struct ctl_table pm_table[] =
-+{
-+/* {ACPI_S1_SLP_TYP, "suspend", NULL, 0, 0600, NULL, (proc_handler *)&sysctl_pm_suspend},*/
-+ {2, "helper", pm_helper_path, sizeof(pm_helper_path), 0644, NULL, (proc_handler *)&proc_dostring},
-+ {3, "debug", &debug_pm, sizeof(debug_pm), 0644, NULL, (proc_handler *)&proc_dointvec},
-+ {4, "helper_veto", &pm_helper_veto, sizeof(pm_helper_veto), 0644, NULL, (proc_handler *)&proc_dointvec},
-+ {0}
-+};
-+
-+static struct ctl_table pm_dir_table[] =
-+{
-+ {CTL_ACPI, "pm", NULL, 0, 0555, pm_table},
-+ {0}
-+};
-+
-+/*
-+ * Initialize power interface
-+ */
-+static int __init pm_init(void)
-+{
-+ register_sysctl_table(pm_dir_table, 1);
-+ return 0;
-+}
-+
-+__initcall(pm_init);
-+
-+#endif
-+
---- /mnt/bdisk/openembedded/oetmp/base/opensimpad-2.4.25-vrs2-pxa1-jpm1-r5/linux-2.4.25/arch/arm/mach-sa1100/apm.c 2004-07-01 21:10:30.000000000 +0200
-+++ arch/arm/mach-sa1100/apm.c 2004-07-04 14:53:38.000000000 +0200
-@@ -32,9 +32,7 @@
-
- #include <asm/system.h>
- #include <asm/hardware.h>
--#if FIXME
- #include <asm/arch-sa1100/pm.h>
--#endif
-
- #ifdef CONFIG_IPAQ_HANDHELD
- #include <asm/arch-sa1100/h3600_hal.h>
-@@ -92,6 +91,8 @@
- int magic;
- struct apm_user * next;
- int suser: 1;
-+ int writer: 1;
-+ int reader: 1;
- int suspend_wait: 1;
- int suspend_result;
- int suspends_pending;
-@@ -111,7 +112,7 @@
- /*
- * Local variables
- */
--//static int suspends_pending;
-+static int suspends_pending;
- //static int standbys_pending;
- //static int ignore_normal_resume;
-
-@@ -129,8 +130,6 @@
- #else
- static int power_off = 1;
- #endif
--static int exit_kapmd;
--static int kapmd_running;
-
- static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
- static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
-@@ -190,6 +189,42 @@
- return as->events[as->event_tail];
- }
-
-+static void queue_event(apm_event_t event, struct apm_user *sender)
-+{
-+ struct apm_user * as;
-+
-+ if (user_list == NULL)
-+ return;
-+ for (as = user_list; as != NULL; as = as->next) {
-+ if ((as == sender) || (!as->reader))
-+ continue;
-+ as->event_head = (as->event_head + 1) % APM_MAX_EVENTS;
-+ if (as->event_head == as->event_tail) {
-+ static int notified;
-+
-+ if (notified++ == 0)
-+ printk(KERN_ERR "apm: an event queue overflowed\n");
-+ as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
-+ }
-+ as->events[as->event_head] = event;
-+ if ((!as->suser) || (!as->writer))
-+ continue;
-+ switch (event) {
-+ case APM_SYS_SUSPEND:
-+ case APM_USER_SUSPEND:
-+ as->suspends_pending++;
-+ suspends_pending++;
-+ break;
-+
-+ case APM_SYS_STANDBY:
-+ case APM_USER_STANDBY:
-+ as->standbys_pending++;
-+ break;
-+ }
-+ }
-+ wake_up_interruptible(&apm_waitqueue);
-+}
-+
- static int check_apm_user(struct apm_user *as, const char *func)
- {
- if ((as == NULL) || (as->magic != APM_BIOS_MAGIC)) {
-@@ -228,7 +263,6 @@
- i = count;
- while ((i >= sizeof(event)) && !queue_empty(as)) {
- event = get_queued_event(as);
-- printk(" do_read: event=%d\n", event);
- if (copy_to_user(buf, &event, sizeof(event))) {
- if (i < count)
- break;
-@@ -280,9 +314,17 @@
- return -EPERM;
- switch (cmd) {
- case APM_IOC_SUSPEND:
--#if FIXME
-- pm_suggest_suspend();
--#endif
-+ if (as->suspends_read > 0) {
-+ as->suspends_read--;
-+ as->suspends_pending--;
-+ suspends_pending--;
-+ } else {
-+ queue_event(APM_USER_SUSPEND, as);
-+ }
-+
-+ if (suspends_pending <= 0)
-+ wake_up(&apm_suspend_waitqueue);
-+
- break;
- default:
- return -EINVAL;
-@@ -299,6 +341,20 @@
- return 0;
- filp->private_data = NULL;
- lock_kernel();
-+ if (user_list == as)
-+ user_list = as->next;
-+ else {
-+ struct apm_user * as1;
-+
-+ for (as1 = user_list;
-+ (as1 != NULL) && (as1->next != as);
-+ as1 = as1->next)
-+ ;
-+ if (as1 == NULL)
-+ printk(KERN_ERR "apm: filp not in user list\n");
-+ else
-+ as1->next = as->next;
-+ }
- unlock_kernel();
- kfree(as);
- return 0;
-@@ -326,6 +382,8 @@
- * privileged operation -- cevans
- */
- as->suser = capable(CAP_SYS_ADMIN);
-+ as->writer = (filp->f_mode & FMODE_WRITE) == FMODE_WRITE;
-+ as->reader = (filp->f_mode & FMODE_READ) == FMODE_READ;
- as->next = user_list;
- user_list = as;
- filp->private_data = as;
-@@ -409,34 +467,6 @@
- return p - buf;
- }
-
--#ifndef MODULE
--static int __init apm_setup(char *str)
--{
-- int invert;
--
-- while ((str != NULL) && (*str != '\0')) {
-- if (strncmp(str, "off", 3) == 0)
-- apm_disabled = 1;
-- if (strncmp(str, "on", 2) == 0)
-- apm_disabled = 0;
-- invert = (strncmp(str, "no-", 3) == 0);
-- if (invert)
-- str += 3;
-- if (strncmp(str, "debug", 5) == 0)
-- debug = !invert;
-- if ((strncmp(str, "power-off", 9) == 0) ||
-- (strncmp(str, "power_off", 9) == 0))
-- power_off = !invert;
-- str = strchr(str, ',');
-- if (str != NULL)
-- str += strspn(str, ", \t");
-- }
-- return 1;
--}
--
--__setup("apm=", apm_setup);
--#endif
--
- static struct file_operations apm_bios_fops = {
- owner: THIS_MODULE,
- read: do_read,
-@@ -454,6 +484,48 @@
-
- #define APM_INIT_ERROR_RETURN return -1
-
-+static pid_t apmd_pid;
-+static DECLARE_COMPLETION(apmd_exited);
-+
-+static int apm(void *unused)
-+{
-+ unsigned short bx;
-+ unsigned short cx;
-+ unsigned short dx;
-+ int error;
-+ char * power_stat;
-+ char * bat_stat;
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct apm_user au, *as;
-+
-+ lock_kernel();
-+
-+ daemonize();
-+
-+ strcpy(current->comm, "kapmd");
-+
-+ as = &au;
-+ as->magic = APM_BIOS_MAGIC;
-+ as->event_tail = as->event_head = 0;
-+ as->suspends_pending = as->standbys_pending = 0;
-+ as->suspends_read = as->standbys_read = 0;
-+ as->suser = 1;
-+ as->writer = 1;
-+ as->reader = 0;
-+
-+ while (!signal_pending (current)) {
-+ interruptible_sleep_on(&apm_suspend_waitqueue);
-+
-+ pm_suggest_suspend();
-+
-+ queue_event(APM_NORMAL_RESUME, as);
-+ }
-+
-+ unlock_kernel();
-+
-+ complete_and_exit(&apmd_exited, 0);
-+}
-+
- /*
- * Just start the APM thread. We do NOT want to do APM BIOS
- * calls from anything but the APM thread, if for no other reason
-@@ -492,6 +564,8 @@
-
- misc_register(&apm_device);
-
-+ apmd_pid = kernel_thread(apm, NULL, 0);
-+
- return 0;
- }
-
-@@ -499,11 +573,10 @@
- {
- misc_deregister(&apm_device);
- remove_proc_entry("apm", NULL);
-+ kill_proc (apmd_pid, SIGTERM, 1);
-+ wait_for_completion(&apmd_exited);
- if (power_off)
- pm_power_off = NULL;
-- exit_kapmd = 1;
-- while (kapmd_running)
-- schedule();
- pm_active = 0;
- }
-
-@@ -512,6 +585,7 @@
-
- MODULE_AUTHOR("Jamey Hicks, pulling bits from original by Stephen Rothwell");
- MODULE_DESCRIPTION("A minimal emulation of APM");
-+MODULE_LICENSE("GPL");
- MODULE_PARM(debug, "i");
- MODULE_PARM_DESC(debug, "Enable debug mode");
- MODULE_PARM(power_off, "i");
-diff -bBaruN /mnt/bdisk/openembedded/oetmp/base/opensimpad-2.4.25-vrs2-pxa1-jpm1-r5/linux-2.4.25/include/asm-arm/arch-sa1100/pm.h include/asm-arm/arch/pm.h
---- /mnt/bdisk/openembedded/oetmp/base/opensimpad-2.4.25-vrs2-pxa1-jpm1-r5/linux-2.4.25/include/asm-arm/arch-sa1100/pm.h 1970-01-01 01:00:00.000000000 +0100
-+++ include/asm-arm/arch-sa1100/pm.h 2004-07-04 16:47:18.000000000 +0200
-@@ -0,0 +1,20 @@
-+/*
-+ *
-+ * Declarations for ARM Linux Power Management
-+ *
-+ * Copyright 2002 Compaq Computer Corporation.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Author: Jamey Hicks.
-+ *
-+ */
-+
-+
-+extern int (*pm_suggest_suspend_hook)(int state);
-+extern int (*pm_sysctl_suspend_hook)(int state);
-+extern int pm_use_sbin_pm_helper;
-+extern int pm_suspend(void);
-+extern int pm_suggest_suspend(void); /* triggers /sbin/pm_helper or queueing event to apmd */
---- /mnt/bdisk/openembedded/oetmp/work/opensimpad-64+0-2.4.25-vrs2-pxa1-jpm1-r6/linux-2.4.25/arch/arm/mach-sa1100/Makefile 2004-07-04 19:39:48.000000000 +0200
-+++ arch/arm/mach-sa1100/Makefile 2004-07-04 17:11:35.000000000 +0200
-@@ -19,7 +19,7 @@
- flexanet.o freebird.o frodo.o generic.o h3600.o \
- huw_webpanel.o irq.o sa1111.o sa1111-pcibuf.o \
- system3.o yopy.o usb_ctl.o usb_recv.o usb_send.o simputer.o ssp.o \
-- simpad.o
-+ simpad.o pm-sa1100.o
-
- # These aren't present yet, and prevents a plain -ac kernel building.
- # hwtimer.o
-@@ -105,7 +105,7 @@
- obj-$(CONFIG_SA1100_USB_CHAR) += usb-char.o
-
- # Miscelaneous functions
--obj-$(CONFIG_PM) += pm.o sleep.o
-+obj-$(CONFIG_PM) += pm-sa1100.o sleep.o
- obj-$(CONFIG_APM) += apm.o
-
- # SIMpad specific
---- /mnt/bdisk/openembedded/oetmp/work/opensimpad-64+0-2.4.25-vrs2-pxa1-jpm1-r6/linux-2.4.25/arch/arm/mach-sa1100/pm-sa1100.c 1970-01-01 01:00:00.000000000 +0100
-+++ arch/arm/mach-sa1100/pm-sa1100.c 2004-07-04 17:11:11.000000000 +0200
-@@ -0,0 +1,225 @@
-+/*
-+ * SA1100 Power Management Routines
-+ *
-+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License.
-+ *
-+ * History:
-+ *
-+ * 2001-02-06: Cliff Brake Initial code
-+ *
-+ * 2001-02-25: Sukjae Cho <sjcho@east.isi.edu> &
-+ * Chester Kuo <chester@linux.org.tw>
-+ * Save more value for the resume function! Support
-+ * Bitsy/Assabet/Freebird board
-+ *
-+ * 2001-08-29: Nicolas Pitre <nico@cam.org>
-+ * Cleaned up, pushed platform dependent stuff
-+ * in the platform specific files.
-+ *
-+ * 2002-05-27: Nicolas Pitre Killed sleep.h and the kmalloced save array.
-+ * Storage is local on the stack now.
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/pm.h>
-+#include <linux/slab.h>
-+#include <linux/sched.h>
-+#include <linux/interrupt.h>
-+#include <linux/sysctl.h>
-+#include <linux/errno.h>
-+#include <linux/cpufreq.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/memory.h>
-+#include <asm/system.h>
-+#include <asm/leds.h>
-+
-+
-+#ifdef CONFIG_IPAQ_HANDHELD
-+#include <asm/arch/h3600_asic.h>
-+#endif
-+
-+#define __KERNEL_SYSCALLS__
-+#include <linux/unistd.h>
-+
-+extern void sa1100_cpu_suspend(void);
-+extern void sa1100_cpu_resume(void);
-+extern int debug_pm;
-+
-+#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
-+#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
-+
-+/*
-+ * List of global SA11x0 peripheral registers to preserve.
-+ * More ones like CP and general purpose register values are preserved
-+ * with the stack location in sleep.S.
-+ */
-+enum { SLEEP_SAVE_START = 0,
-+
-+ SLEEP_SAVE_OSCR, SLEEP_SAVE_OIER,
-+ SLEEP_SAVE_OSMR0, SLEEP_SAVE_OSMR1, SLEEP_SAVE_OSMR2, SLEEP_SAVE_OSMR3,
-+
-+ SLEEP_SAVE_GPDR, SLEEP_SAVE_GRER, SLEEP_SAVE_GFER, SLEEP_SAVE_GAFR,
-+ SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR,
-+
-+ SLEEP_SAVE_ICMR,
-+#ifdef CONFIG_SA1100_SIMPAD
-+ SLEEP_SAVE_MECR, /* needed by SIMpad to get PCMCIA working after resume */
-+#endif
-+ SLEEP_SAVE_Ser1SDCR0,
-+
-+ SLEEP_SAVE_PWER,
-+ SLEEP_SAVE_MSC1, SLEEP_SAVE_MSC2,
-+
-+ SLEEP_SAVE_SIZE
-+};
-+
-+
-+int pm_do_suspend(void)
-+{
-+ unsigned long sleep_save[SLEEP_SAVE_SIZE];
-+
-+ cli();
-+
-+ leds_event(led_stop);
-+
-+ /* preserve current time */
-+ RCNR = xtime.tv_sec;
-+
-+ /* save vital registers */
-+ SAVE(OSCR);
-+ SAVE(OSMR0);
-+ SAVE(OSMR1);
-+ SAVE(OSMR2);
-+ SAVE(OSMR3);
-+ SAVE(OIER);
-+
-+ SAVE(GPDR);
-+ SAVE(GRER);
-+ SAVE(GFER);
-+ SAVE(GAFR);
-+
-+ SAVE(PPDR);
-+ SAVE(PPSR);
-+ SAVE(PPAR);
-+ SAVE(PSDR);
-+
-+ SAVE(Ser1SDCR0);
-+
-+ SAVE(ICMR);
-+#ifdef CONFIG_SA1100_SIMPAD
-+ SAVE(MECR);
-+#endif
-+ SAVE(PWER);
-+ SAVE(MSC1);
-+ SAVE(MSC2);
-+
-+ /* ... maybe a global variable initialized by arch code to set this? */
-+ GRER &= PWER;
-+ GFER &= PWER;
-+ // Ugly, but I need the AC inserted event
-+ // In the future, we're going to care about DCD and USB interrupts as well
-+ if ( machine_is_h3800()) {
-+#ifdef CONFIG_IPAQ_HANDHELD
-+ GFER = GPIO_H3800_AC_IN;
-+#endif
-+ } else {
-+ GFER = 0;
-+ if (machine_is_jornada56x()) {
-+ /* jca */
-+ GFER = PWER;
-+ ICMR |= PWER;
-+ }
-+ }
-+ GEDR = GEDR;
-+
-+ /* Clear previous reset status */
-+ RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR;
-+
-+ /* set resume return address */
-+ PSPR = virt_to_phys(sa1100_cpu_resume);
-+
-+ /* go zzz */
-+ sa1100_cpu_suspend();
-+
-+ /* ensure not to come back here if it wasn't intended */
-+ PSPR = 0;
-+
-+ if (debug_pm)
-+ printk(KERN_CRIT "*** made it back from resume\n");
-+
-+#ifdef CONFIG_IPAQ_HANDHELD
-+ if ( machine_is_ipaq()) {
-+ ipaq_model_ops.gedr = GEDR;
-+ ipaq_model_ops.icpr = ICPR;
-+ }
-+#endif
-+
-+ /* restore registers */
-+ RESTORE(GPDR);
-+ RESTORE(GRER);
-+ RESTORE(GFER);
-+ RESTORE(GAFR);
-+
-+ /* clear any edge detect bit */
-+ GEDR = GEDR;
-+
-+ RESTORE(PPDR);
-+ RESTORE(PPSR);
-+ RESTORE(PPAR);
-+ RESTORE(PSDR);
-+
-+ RESTORE(Ser1SDCR0);
-+
-+ PSSR = PSSR_PH;
-+
-+ RESTORE(OSMR0);
-+ RESTORE(OSMR1);
-+ RESTORE(OSMR2);
-+ RESTORE(OSMR3);
-+ RESTORE(OSCR);
-+ RESTORE(OIER);
-+
-+#ifdef CONFIG_IPAQ_HANDHELD
-+/* OSMR0 may have fired before we went to sleep, but after interrupts
-+ were shut off. Set OSMR0 to something plausible */
-+ OSMR0 = OSCR + LATCH;
-+#endif
-+ ICLR = 0;
-+ ICCR = 1;
-+ RESTORE(ICMR);
-+#ifdef CONFIG_SA1100_SIMPAD
-+ RESTORE(MECR);
-+#endif
-+ RESTORE(PWER);
-+ RESTORE(MSC1);
-+ RESTORE(MSC2);
-+ /* restore current time */
-+ xtime.tv_sec = RCNR;
-+
-+ leds_event(led_start);
-+
-+ sti();
-+
-+ if (debug_pm)
-+ printk("interrupts are enabled\n");
-+
-+ /*
-+ * Restore the CPU frequency settings.
-+ */
-+#ifdef CONFIG_CPU_FREQ
-+ cpufreq_restore();
-+#endif
-+ return 0;
-+}
-+
-+unsigned long sleep_phys_sp(void *sp)
-+{
-+ return virt_to_phys(sp);
-+}
-+
-+#include "pm-common.c"
diff --git a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-backlight-if.diff b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-backlight-if.diff
deleted file mode 100644
index 50a4ff7628..0000000000
--- a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-backlight-if.diff
+++ /dev/null
@@ -1,97 +0,0 @@
---- /mnt/bdisk/openembedded/oetmp/base/opensimpad-2.4.25-vrs2-pxa1-jpm1-r5/linux-2.4.25/drivers/video/mq200fb.c 2004-07-01 21:10:30.000000000 +0200
-+++ drivers/video/mq200fb.c 2004-07-03 20:58:59.000000000 +0200
-@@ -82,6 +82,20 @@
- write: proc_write_reg
- };
-
-+#ifdef CONFIG_SA1100_SIMPAD
-+
-+static ssize_t proc_read_light(struct file * file, char * buf,
-+ size_t nbytes, loff_t *ppos);
-+static ssize_t proc_write_light(struct file * file, const char * buffer,
-+ size_t count, loff_t *ppos);
-+
-+static struct file_operations proc_light_operations = {
-+ read: proc_read_light,
-+ write: proc_write_light
-+};
-+#endif
-+
-+
- typedef struct sa1110_reg_entry {
- u32 phyaddr;
- char* name;
-@@ -622,6 +636,20 @@
- }
- }
-
-+#ifdef CONFIG_SA1100_SIMPAD
-+ entry = create_proc_entry("backlight",
-+ S_IRWXU | S_IRWXG | S_IRWXO,
-+ mq200dir);
-+ if(entry) {
-+ entry->proc_fops = &proc_light_operations;
-+ }
-+ else {
-+ printk( KERN_ERR
-+ "mq200fb: can't create /proc/" MQ200_DIRNAME
-+ "/backlight\n");
-+ return(-ENOMEM);
-+ }
-+ #endif
-
- #ifdef MQ_SA1110
-
-@@ -1879,7 +1907,7 @@
- static void writeBrightness(void *pMQMMIO, int brightness)
- {
- unsigned long dutyCycle, pwmcontrol;
-- int MAX_BRIGHT_REG = 0x000000fc; /* int 254 */
-+ int MAX_BRIGHT_REG = 0x000000fe; /* int 254 */
-
- if(brightness > MAX_BRIGHT_REG)
- return;
-@@ -1961,3 +1989,43 @@
- return (count+endp-buffer);
- }
-
-+#ifdef CONFIG_SA1100_SIMPAD
-+
-+#define SIMPAD_BACKLIGHT_MASK 0x00a10044
-+
-+static int proc_read_light(struct file * file, char * buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ char outputbuf[15];
-+ int count;
-+ u32 pwmctl;
-+ if (*ppos>0) /* Assume reading completed in previous read*/
-+ return 0;
-+
-+ pwmctl = *((volatile *) mq200_p2v(0x4be0e03c));
-+ pwmctl &= ~SIMPAD_BACKLIGHT_MASK;
-+ pwmctl = pwmctl >> 8;
-+ pwmctl = 254 - pwmctl;
-+
-+ count = sprintf(outputbuf, "%d\n",pwmctl);
-+ *ppos+=count;
-+ if (count>nbytes) /* Assume output can be read at one time */
-+ return -EINVAL;
-+ if (copy_to_user(buf, outputbuf, count))
-+ return -EFAULT;
-+ return count;
-+}
-+
-+static ssize_t proc_write_light(struct file * file, const char * buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ void * pMQMMIO = (void *) mqMmioAddr;
-+ char *endp;
-+ unsigned long newvalue = simple_strtoul(buffer,&endp,0);
-+ if (newvalue > 254)
-+ newvalue = 254;
-+ writeBrightness(pMQMMIO,newvalue);
-+ mq200_backlight(pMQMMIO,(int)newvalue);
-+ return (count+endp-buffer);
-+}
-+#endif
diff --git a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-pm-updates.patch b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-pm-updates.patch
deleted file mode 100644
index 938c34c67a..0000000000
--- a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-pm-updates.patch
+++ /dev/null
@@ -1,47 +0,0 @@
---- arch/arm/mach-sa1100/pm-sa1100.c 2004-07-14 01:21:38.000000000 +0200
-+++ /home/fuchs/Projekte/simpad/kernel/linux-2.4.25/arch/arm/mach-sa1100/pm-sa1100.c 2004-07-22 00:41:57.000000000 +0200
-@@ -69,6 +69,7 @@
- SLEEP_SAVE_ICMR,
- #ifdef CONFIG_SA1100_SIMPAD
- SLEEP_SAVE_MECR, /* needed by SIMpad to get PCMCIA working after resume */
-+ SLEEP_SAVE_Ser4MCCR0, SLEEP_SAVE_Ser4MCSR, SLEEP_SAVE_Ser4MCCR1, /* touchscreen */
- #endif
- SLEEP_SAVE_Ser1SDCR0,
-
-@@ -82,7 +83,7 @@
- int pm_do_suspend(void)
- {
- unsigned long sleep_save[SLEEP_SAVE_SIZE];
--
-+
- cli();
-
- leds_event(led_stop);
-@@ -113,10 +114,13 @@
- SAVE(ICMR);
- #ifdef CONFIG_SA1100_SIMPAD
- SAVE(MECR);
--#endif
-- SAVE(PWER);
-- SAVE(MSC1);
-- SAVE(MSC2);
-+ SAVE(Ser4MCCR0);
-+ SAVE(Ser4MCSR);
-+ SAVE(Ser4MCCR1);
-+#endif
-+ SAVE(PWER);
-+ SAVE(MSC1);
-+ SAVE(MSC2);
-
- /* ... maybe a global variable initialized by arch code to set this? */
- GRER &= PWER;
-@@ -194,6 +198,9 @@
- RESTORE(ICMR);
- #ifdef CONFIG_SA1100_SIMPAD
- RESTORE(MECR);
-+ RESTORE(Ser4MCCR0);
-+ RESTORE(Ser4MCSR);
-+ RESTORE(Ser4MCCR1);
- #endif
- RESTORE(PWER);
- RESTORE(MSC1);
diff --git a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-switches-input.diff b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-switches-input.diff
deleted file mode 100644
index c07dafd17a..0000000000
--- a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-switches-input.diff
+++ /dev/null
@@ -1,126 +0,0 @@
---- /mnt/bdisk/openembedded/oetmp/base/opensimpad-2.4.25-vrs2-pxa1-jpm1-r5/linux-2.4.25/drivers/misc/switches.h 2004-07-01 21:10:30.000000000 +0200
-+++ drivers/misc/switches.h 2004-07-03 23:45:46.000000000 +0200
-@@ -25,4 +25,14 @@
- extern int switches_ucb1x00_init(void);
- extern void switches_ucb1x00_exit(void);
-
-+#ifdef CONFIG_SA1100_SIMPAD
-+#define SIMPAD_KEY_SUSPEND 0x0002
-+#define SIMPAD_KEY_WWW 0x0008
-+#define SIMPAD_KEY_ENTER 0x0010
-+#define SIMPAD_KEY_UP 0x0020
-+#define SIMPAD_KEY_DOWN 0x0040
-+#define SIMPAD_KEY_LEFT 0x0080
-+#define SIMPAD_KEY_RIGHT 0x0100
-+#endif
-+
- #endif /* !defined(_SWITCHES_H) */
---- /mnt/bdisk/openembedded/oetmp/base/opensimpad-2.4.25-vrs2-pxa1-jpm1-r5/linux-2.4.25/drivers/misc/switches-core.c 2004-07-01 21:10:30.000000000 +0200
-+++ drivers/misc/switches-core.c 2004-07-04 17:57:37.000000000 +0200
-@@ -16,6 +16,9 @@
- * 11 September 2001 - UCB1200 driver framework support added.
- *
- * 19 December 2001 - separated out SA-1100 and UCB1x00 code.
-+ *
-+ * 3 July 2004 - Added generating of keyboard events.
-+ * Florian Boor <florian@handhelds.org>
- */
-
- #include <linux/config.h>
-@@ -30,7 +33,11 @@
- #include <linux/slab.h>
- #include <linux/wait.h>
-
-+#include <linux/input.h>
-+
- #include <asm/uaccess.h>
-+#include <asm/hardware.h>
-+#include <asm/keyboard.h>
-
- #include "switches.h"
-
-@@ -53,6 +60,19 @@
- DECLARE_WAIT_QUEUE_HEAD(switches_wait);
- LIST_HEAD(switches_event_queue);
-
-+#ifdef CONFIG_INPUT
-+static struct input_dev idev;
-+
-+int
-+dummy_k_translate(unsigned char scancode, unsigned char *keycode, char raw_mode)
-+{
-+ *keycode = scancode;
-+ return 1;
-+}
-+
-+extern int (*k_translate)(unsigned char, unsigned char *, char);
-+
-+#endif
-
- static ssize_t switches_read(struct file *file, char *buffer,
- size_t count, loff_t *pos)
-@@ -148,6 +168,31 @@
- {
- struct switches_action *action;
-
-+#ifdef CONFIG_INPUT
-+ /* create input events, the events to send depends on the platform */
-+#ifdef CONFIG_SA1100_SIMPAD
-+ if (machine_is_simpad()) {
-+ if (SWITCHES_COUNT(mask) > 0)
-+ {
-+ if (mask->events[0] & SIMPAD_KEY_SUSPEND)
-+ input_report_key(&idev, KEY_POWER, (mask->states[0] & SIMPAD_KEY_SUSPEND) ? 1 : 0);
-+ if (mask->events[0] & SIMPAD_KEY_ENTER)
-+ input_report_key(&idev, KEY_ENTER, (mask->states[0] & SIMPAD_KEY_ENTER) ? 1 : 0);
-+ if (mask->events[0] & SIMPAD_KEY_UP)
-+ input_report_key(&idev, KEY_UP, (mask->states[0] & SIMPAD_KEY_UP) ? 1 : 0);
-+ if (mask->events[0] & SIMPAD_KEY_DOWN)
-+ input_report_key(&idev, KEY_DOWN, (mask->states[0] & SIMPAD_KEY_DOWN) ? 1 : 0);
-+ if (mask->events[0] & SIMPAD_KEY_LEFT)
-+ input_report_key(&idev, KEY_LEFT, (mask->states[0] & SIMPAD_KEY_LEFT) ? 1 : 0);
-+ if (mask->events[0] & SIMPAD_KEY_RIGHT)
-+ input_report_key(&idev, KEY_RIGHT, (mask->states[0] & SIMPAD_KEY_RIGHT) ? 1 : 0);
-+ if (mask->events[0] & SIMPAD_KEY_WWW)
-+ input_report_key(&idev, KEY_WWW, (mask->states[0] & SIMPAD_KEY_WWW) ? 1 : 0);
-+ }
-+ }
-+#endif
-+#endif
-+ /* take care of switches device */
- if ((switches_users > 0) && (SWITCHES_COUNT(mask) > 0)) {
-
- if ((action = (struct switches_action *)
-@@ -197,6 +242,21 @@
- return -EIO;
- }
-
-+#ifdef CONFIG_INPUT
-+ /* init input driver stuff */
-+ k_translate = dummy_k_translate;
-+ idev.evbit[0] = BIT(EV_KEY); /* handle key events */
-+
-+ idev.keybit[LONG(KEY_SUSPEND)] |= BIT(KEY_SUSPEND);
-+ idev.keybit[LONG(KEY_UP)] |= BIT(KEY_UP);
-+ idev.keybit[LONG(KEY_DOWN)] |= BIT(KEY_DOWN);
-+ idev.keybit[LONG(KEY_LEFT)] |= BIT(KEY_LEFT);
-+ idev.keybit[LONG(KEY_RIGHT)] |= BIT(KEY_RIGHT);
-+ idev.keybit[LONG(KEY_ENTER)] |= BIT(KEY_ENTER);
-+ idev.keybit[LONG(KEY_WWW)] |= BIT(KEY_WWW);
-+
-+ input_register_device(&idev);
-+#endif
- printk("Console switches initialized\n");
-
- return 0;
-@@ -214,6 +274,10 @@
- switches_ucb1x00_exit();
- #endif
-
-+#ifdef CONFIG_INPUT
-+ input_unregister_device(&idev);
-+#endif
-+
- if (misc_deregister(&switches_misc) < 0)
- printk(KERN_ERR "%s: unable to deregister misc device\n",
- SWITCHES_NAME);
diff --git a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-switches-input2.diff b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-switches-input2.diff
deleted file mode 100644
index 9531cf1b43..0000000000
--- a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-switches-input2.diff
+++ /dev/null
@@ -1,52 +0,0 @@
-
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- drivers/misc/switches-core.c~Fooo
-+++ drivers/misc/switches-core.c
-@@ -66,7 +66,32 @@
- int
- dummy_k_translate(unsigned char scancode, unsigned char *keycode, char raw_mode)
- {
-- *keycode = scancode;
-+ if (scancode == KEY_UP)
-+ *keycode = 144;
-+ else if (scancode == KEY_LEFT)
-+ *keycode = 146;
-+ else if (scancode == KEY_RIGHT)
-+ *keycode = 151;
-+ else if (scancode == KEY_DOWN)
-+ *keycode = 161;
-+ else if (scancode == 144)
-+ *keycode = KEY_UP;
-+ else if (scancode == 146)
-+ *keycode = KEY_LEFT;
-+ else if (scancode == 151)
-+ *keycode = KEY_RIGHT;
-+ else if (scancode == 161)
-+ *keycode = KEY_DOWN;
-+ else if (scancode == KEY_KP8)
-+ *keycode = KEY_UP;
-+ else if (scancode == KEY_KP4)
-+ *keycode = KEY_LEFT;
-+ else if (scancode == KEY_KP6)
-+ *keycode = KEY_RIGHT;
-+ else if (scancode == KEY_KP2)
-+ *keycode = KEY_DOWN;
-+ else
-+ *keycode = scancode;
- return 1;
- }
-
-@@ -174,8 +199,9 @@
- if (machine_is_simpad()) {
- if (SWITCHES_COUNT(mask) > 0)
- {
-+// printk("st %04lx, ev: %04lx\n",mask->states[0],mask->events[0]);
- if (mask->events[0] & SIMPAD_KEY_SUSPEND)
-- input_report_key(&idev, KEY_POWER, (mask->states[0] & SIMPAD_KEY_SUSPEND) ? 1 : 0);
-+ input_report_key(&idev, KEY_POWER, (mask->states[0] & SIMPAD_KEY_SUSPEND) ? 0 : 1);
- if (mask->events[0] & SIMPAD_KEY_ENTER)
- input_report_key(&idev, KEY_ENTER, (mask->states[0] & SIMPAD_KEY_ENTER) ? 1 : 0);
- if (mask->events[0] & SIMPAD_KEY_UP)
diff --git a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-ts-noninput.diff b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-ts-noninput.diff
deleted file mode 100644
index 08fffe5882..0000000000
--- a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/simpad-ts-noninput.diff
+++ /dev/null
@@ -1,11 +0,0 @@
---- /mnt/bdisk/openembedded/oetmp/base/opensimpad-2.4.25-vrs2-pxa1-jpm1-r5/linux-2.4.25/drivers/misc/ucb1x00-ts.c 2004-07-01 21:10:30.000000000 +0200
-+++ drivers/misc/ucb1x00-ts.c 2004-07-04 02:00:56.000000000 +0200
-@@ -35,7 +35,7 @@
- /*
- * Define this if you want the UCB1x00 stuff to talk to the input layer
- */
--#ifdef CONFIG_INPUT
-+#if defined(CONFIG_INPUT) && !defined(CONFIG_SA1100_SIMPAD)
- #define USE_INPUT
- #else
- #undef USE_INPUT
diff --git a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/sound-volume-reversed.patch b/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/sound-volume-reversed.patch
deleted file mode 100644
index 11fa5c7ad5..0000000000
--- a/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/sound-volume-reversed.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-
-#
-# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux-2.4.25/drivers/misc/ucb1x00-audio.c~sound-volume-reversed.patch 2004-03-31 17:15:12.000000000 +0200
-+++ linux-2.4.25/drivers/misc/ucb1x00-audio.c 2004-03-31 17:15:13.000000000 +0200
-@@ -97,7 +97,7 @@
- ucba->output_level = gain | gain << 8;
- ucba->mod_cnt++;
- ucba->ctrl_b = (ucba->ctrl_b & 0xff00) |
-- ((gain * 31) / 100);
-+ (((100-gain) * 31) / 100);
- ucb1x00_reg_write(ucba->ucb, UCB_AC_B,
- ucba->ctrl_b);
- ret = 0;
diff --git a/linux/opensimpad-64+0_2.4.25-vrs2-pxa1-jpm1.bb b/linux/opensimpad-64+0_2.4.25-vrs2-pxa1-jpm1.bb
deleted file mode 100644
index fb12c70b59..0000000000
--- a/linux/opensimpad-64+0_2.4.25-vrs2-pxa1-jpm1.bb
+++ /dev/null
@@ -1,5 +0,0 @@
-SECTION = "kernel"
-include opensimpad_${PV}.bb
-
-SIMPAD_MEM = "64"
-SIMPAD_RD = "0"
diff --git a/linux/opensimpad_2.4.25-vrs2-pxa1-jpm1.bb b/linux/opensimpad_2.4.25-vrs2-pxa1-jpm1.bb
deleted file mode 100644
index dc2250b881..0000000000
--- a/linux/opensimpad_2.4.25-vrs2-pxa1-jpm1.bb
+++ /dev/null
@@ -1,70 +0,0 @@
-DESCRIPTION = "Linux kernel for the SIEMENS SIMpad family of devices."
-MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>"
-SECTION = "kernel"
-LICENSE = "GPL"
-KV = "${@bb.data.getVar('PV',d,True).split('-')[0]}"
-VRSV = "${@bb.data.getVar('PV',d,True).split('-')[1]}"
-PXAV = "${@bb.data.getVar('PV',d,True).split('-')[2]}"
-JPMV = "${@bb.data.getVar('PV',d,True).split('-')[3]}"
-PR = "r17"
-
-FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/opensimpad-${PV}"
-
-SRC_URI = "ftp://ftp.kernel.org/pub/linux/kernel/v2.4/linux-${KV}.tar.bz2 \
- file://${KV}-${VRSV}.patch;patch=1 \
- file://${KV}-${VRSV}-${PXAV}.patch;patch=1 \
- file://${KV}-${VRSV}-${PXAV}-${JPMV}.patch;patch=1 \
- file://sound-volume-reversed.patch;patch=1 \
- file://disable-pcmcia-probe.patch;patch=1 \
- file://mkdep.patch;patch=1 \
- file://defconfig-${MACHINE} \
- http://www.openswan.org/download/openswan-2.2.0-kernel-2.4-klips.patch.gz;patch=1 \
- file://mipv6-1.1-v2.4.25.patch;patch=1 \
- file://simpad-backlight-if.diff;patch=1;pnum=0 \
- file://simpad-switches-input.diff;patch=1;pnum=0 \
- file://simpad-switches-input2.diff;patch=1;pnum=0 \
- file://keymap.patch;patch=1 \
- file://simpad-apm.diff;patch=1;pnum=0 \
- file://simpad-ts-noninput.diff;patch=1;pnum=0 \
- file://simpad-pm-updates.patch;patch=1;pnum=0"
-
-# apply this when we have a patch that allows building with gcc 3.x:
-# SRC_URI_append = file://gcc-3.3.patch;patch=1
-# SRC_URI_append = file://machtune-args.patch;patch=1
-
-S = "${WORKDIR}/linux-${KV}"
-
-inherit kernel
-
-KERNEL_CCSUFFIX = "-3.3.3"
-COMPATIBLE_HOST = "arm.*-linux"
-
-SIMPAD_MEM = ${@bb.data.getVar("SIMPAD_MEMORY_SIZE",d,1) or "32"}
-SIMPAD_RD = ${@bb.data.getVar("SIMPAD_RAMDISK_SIZE",d,1) or "32"}
-export CMDLINE = ${@bb.data.getVar("SIMPAD_CMDLINE",d,1) or "mtdparts=sa1100:512k(boot),1m(kernel),14848k(root),-(home) console=ttySA root=1f02 noinitrd jffs2_orphaned_inodes=delete rootfstype=jffs2 "}
-EXTRA_OEMAKE = ""
-
-module_conf_sa1100_ir = "alias irda0 sa1100_ir"
-
-do_configure() {
- install -m 0644 ${WORKDIR}/defconfig-${MACHINE} ${S}/.config || die "No default configuration for ${MACHINE} available."
-
- mem=${SIMPAD_MEM}
- rd=${SIMPAD_RD}
- mempos=`echo "obase=16; $mem * 1024 * 1024" | bc`
- rdsize=`echo "$rd * 1024" | bc`
- total=`expr $mem + $rd`
- addr=`echo "obase=16; ibase=16; C0000000 + $mempos" | bc`
-
- if [ "$rd" == "0" ]
- then
- echo "# CONFIG_MTD_MTDRAM is not set" >> ${S}/.config
- else
- echo "CONFIG_MTD_MTDRAM=y" >> ${S}/.config
- echo "CONFIG_MTDRAM_TOTAL_SIZE=$rdsize" >> ${S}/.config
- echo "CONFIG_MTDRAM_ERASE_SIZE=1" >> ${S}/.config
- echo "CONFIG_MTDRAM_ABS_POS=$addr" >> ${S}/.config
- fi
- echo "CONFIG_CMDLINE=\"${CMDLINE} mem=${mem}M\"" >> ${S}/.config
- oe_runmake oldconfig
-}
diff --git a/linux/openslug-kernel-2.6.7/arm-Makefile.patch b/linux/openslug-kernel-2.6.7/arm-Makefile.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/openslug-kernel-2.6.7/arm-Makefile.patch
+++ /dev/null
diff --git a/linux/openslug-kernel-2.6.7/arm-timer.patch b/linux/openslug-kernel-2.6.7/arm-timer.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/openslug-kernel-2.6.7/arm-timer.patch
+++ /dev/null
diff --git a/linux/openslug-kernel-2.6.7/defconfig b/linux/openslug-kernel-2.6.7/defconfig
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/openslug-kernel-2.6.7/defconfig
+++ /dev/null
diff --git a/linux/openslug-kernel-2.6.7/ipx4xx-pci.patch b/linux/openslug-kernel-2.6.7/ipx4xx-pci.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/openslug-kernel-2.6.7/ipx4xx-pci.patch
+++ /dev/null
diff --git a/linux/openslug-kernel-2.6.7/x1205-rtc.patch b/linux/openslug-kernel-2.6.7/x1205-rtc.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/openslug-kernel-2.6.7/x1205-rtc.patch
+++ /dev/null
diff --git a/linux/openslug-kernel-2.6.9/defconfig b/linux/openslug-kernel-2.6.9/defconfig
deleted file mode 100644
index d989892ba0..0000000000
--- a/linux/openslug-kernel-2.6.9/defconfig
+++ /dev/null
@@ -1,1112 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_STANDALONE=y
-CONFIG_BROKEN_ON_SMP=y
-
-#
-# General setup
-#
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-CONFIG_CC_OPTIMIZE_FOR_SIZE=y
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_ADIFCC is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-CONFIG_ARCH_IXP4XX=y
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE_PB is not set
-CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y
-
-#
-# Intel IXP4xx Implementation Options
-#
-
-#
-# IXP4xx Platforms
-#
-# CONFIG_ARCH_AVILA is not set
-# CONFIG_ARCH_ADI_COYOTE is not set
-#CONFIG_ARCH_IXDP425=y
-#CONFIG_ARCH_IXCDP1100=y
-# CONFIG_ARCH_PRPMC1100 is not set
-#CONFIG_ARCH_IXDP4XX=y
-CONFIG_ARCH_NSLU2=y
-
-#
-# IXP4xx Options
-#
-CONFIG_IXP4XX_INDIRECT_PCI=y
-CONFIG_DMABOUNCE=y
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_XSCALE=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
-
-#
-# Processor Features
-#
-# CONFIG_ARM_THUMB is not set
-CONFIG_CPU_BIG_ENDIAN=y
-CONFIG_XSCALE_PMU=y
-
-#
-# General setup
-#
-CONFIG_PCI=y
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_PCI_LEGACY_PROC=y
-# CONFIG_PCI_NAMES is not set
-
-#
-# PCMCIA/CardBus support
-#
-# CONFIG_PCMCIA is not set
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_AOUT is not set
-# CONFIG_BINFMT_MISC is not set
-
-#
-# Generic Driver Options
-#
-# CONFIG_FW_LOADER is not set
-# CONFIG_DEBUG_DRIVER is not set
-CONFIG_PM=y
-# CONFIG_PREEMPT is not set
-CONFIG_APM=y
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="root=/dev/ram0 initrd=0x01000000,10M mem=32M@0x00000000 console=ttyS0,115200n8"
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_REDBOOT_PARTS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-
-#
-# Mapping drivers for chip access
-#
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-CONFIG_MTD_IXP4XX=y
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_PCI is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_CARMEL is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=10240
-CONFIG_BLK_DEV_INITRD=y
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=m
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=m
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_FWMARK=y
-CONFIG_IP_ROUTE_NAT=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_TOS=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-CONFIG_NET_IPGRE_BROADCAST=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-
-#
-# IP: Virtual Server Configuration
-#
-CONFIG_IP_VS=m
-CONFIG_IP_VS_DEBUG=y
-CONFIG_IP_VS_TAB_BITS=12
-
-#
-# IPVS transport protocol load balancing support
-#
-# CONFIG_IP_VS_PROTO_TCP is not set
-# CONFIG_IP_VS_PROTO_UDP is not set
-# CONFIG_IP_VS_PROTO_ESP is not set
-# CONFIG_IP_VS_PROTO_AH is not set
-
-#
-# IPVS scheduler
-#
-CONFIG_IP_VS_RR=m
-CONFIG_IP_VS_WRR=m
-CONFIG_IP_VS_LC=m
-CONFIG_IP_VS_WLC=m
-CONFIG_IP_VS_LBLC=m
-CONFIG_IP_VS_LBLCR=m
-CONFIG_IP_VS_DH=m
-CONFIG_IP_VS_SH=m
-# CONFIG_IP_VS_SED is not set
-# CONFIG_IP_VS_NQ is not set
-
-#
-# IPVS application helper
-#
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_BRIDGE_NETFILTER=y
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-
-#
-# Bridge: Netfilter Configuration
-#
-# CONFIG_BRIDGE_NF_EBTABLES is not set
-CONFIG_XFRM=y
-# CONFIG_XFRM_USER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-CONFIG_BRIDGE=m
-CONFIG_VLAN_8021Q=m
-# CONFIG_DECNET is not set
-CONFIG_LLC=m
-# CONFIG_LLC2 is not set
-CONFIG_IPX=m
-# CONFIG_IPX_INTERN is not set
-CONFIG_ATALK=m
-CONFIG_DEV_APPLETALK=y
-CONFIG_IPDDP=m
-CONFIG_IPDDP_ENCAP=y
-CONFIG_IPDDP_DECAP=y
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-CONFIG_NET_SCHED=y
-CONFIG_NET_SCH_CBQ=m
-CONFIG_NET_SCH_HTB=m
-# CONFIG_NET_SCH_HFSC is not set
-CONFIG_NET_SCH_CSZ=m
-CONFIG_NET_SCH_PRIO=m
-CONFIG_NET_SCH_RED=m
-CONFIG_NET_SCH_SFQ=m
-CONFIG_NET_SCH_TEQL=m
-CONFIG_NET_SCH_TBF=m
-CONFIG_NET_SCH_GRED=m
-CONFIG_NET_SCH_DSMARK=m
-# CONFIG_NET_SCH_DELAY is not set
-CONFIG_NET_SCH_INGRESS=m
-CONFIG_NET_QOS=y
-CONFIG_NET_ESTIMATOR=y
-CONFIG_NET_CLS=y
-CONFIG_NET_CLS_TCINDEX=m
-CONFIG_NET_CLS_ROUTE4=m
-CONFIG_NET_CLS_ROUTE=y
-CONFIG_NET_CLS_FW=m
-CONFIG_NET_CLS_U32=m
-CONFIG_NET_CLS_RSVP=m
-CONFIG_NET_CLS_RSVP6=m
-CONFIG_NET_CLS_POLICE=y
-
-#
-# Network testing
-#
-CONFIG_NET_PKTGEN=m
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-
-#
-# Tulip family network device support
-#
-# CONFIG_NET_TULIP is not set
-# CONFIG_HP100 is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_B44 is not set
-# CONFIG_FORCEDETH is not set
-# CONFIG_DGRS is not set
-# CONFIG_EEPRO100 is not set
-# CONFIG_E100 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-
-#
-# Ethernet (10000 Mbit)
-#
-# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-# CONFIG_AIRO is not set
-# CONFIG_HERMES is not set
-# CONFIG_ATMEL is not set
-
-#
-# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
-#
-# CONFIG_PRISM54 is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-# CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-
-#
-# SCSI device support
-#
-CONFIG_SCSI=m
-CONFIG_SCSI_PROC_FS=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=m
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI Transport Attributes
-#
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_SATA is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-CONFIG_SCSI_QLA2XXX=m
-# CONFIG_SCSI_QLA21XX is not set
-# CONFIG_SCSI_QLA22XX is not set
-# CONFIG_SCSI_QLA2300 is not set
-# CONFIG_SCSI_QLA2322 is not set
-# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# Fusion MPT device support
-#
-# CONFIG_FUSION is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=m
-
-#
-# Userland interfaces
-#
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_MOUSEDEV_PSAUX=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_TSDEV is not set
-CONFIG_INPUT_EVDEV=m
-# CONFIG_INPUT_EVBUG is not set
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
-#
-# Input Device Drivers
-#
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Character devices
-#
-# CONFIG_VT is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=2
-# CONFIG_SERIAL_8250_EXTENDED is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
-# CONFIG_QIC02_TAPE is not set
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-
-#
-# Watchdog Device Drivers
-#
-# CONFIG_SOFT_WATCHDOG is not set
-CONFIG_IXP4XX_WATCHDOG=y
-
-#
-# PCI-based Watchdog Cards
-#
-# CONFIG_PCIPCWATCHDOG is not set
-# CONFIG_WDTPCI is not set
-
-#
-# USB-based Watchdog Cards
-#
-# CONFIG_USBPCWATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_GEN_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# I2C support
-#
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-
-#
-# I2C Algorithms
-#
-CONFIG_I2C_ALGOBIT=y
-# CONFIG_I2C_ALGOPCF is not set
-
-#
-# I2C Hardware Bus support
-#
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_I810 is not set
-# CONFIG_I2C_ISA is not set
-CONFIG_I2C_IXP4XX=y
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_PROSAVAGE is not set
-# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_SCx200_ACB is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_VOODOO3 is not set
-
-#
-# Hardware Sensors Chip support
-#
-CONFIG_I2C_SENSOR=y
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-
-#
-# Other I2C Chip support
-#
-CONFIG_SENSORS_EEPROM=y
-CONFIG_SENSORS_X1205=y
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-# CONFIG_EXT2_FS_SECURITY is not set
-CONFIG_EXT3_FS=m
-CONFIG_EXT3_FS_XATTR=y
-CONFIG_EXT3_FS_POSIX_ACL=y
-# CONFIG_EXT3_FS_SECURITY is not set
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-# CONFIG_FAT_FS is not set
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-CONFIG_TMPFS=y
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_CRAMFS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_NFSD is not set
-CONFIG_LOCKD=m
-CONFIG_LOCKD_V4=y
-# CONFIG_EXPORTFS is not set
-CONFIG_SUNRPC=m
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_NEC98_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-
-#
-# Native Language Support
-#
-# CONFIG_NLS is not set
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Graphics support
-#
-# CONFIG_FB is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# Misc devices
-#
-
-#
-# USB support
-#
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-
-#
-# USB Host Controller Drivers
-#
-CONFIG_USB_EHCI_HCD=m
-# CONFIG_USB_EHCI_SPLIT_ISO is not set
-# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
-CONFIG_USB_OHCI_HCD=m
-CONFIG_USB_UHCI_HCD=m
-# CONFIG_USB_SL811HS is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_BLUETOOTH_TTY is not set
-# CONFIG_USB_ACM is not set
-CONFIG_USB_PRINTER=m
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-CONFIG_USB_HID=m
-CONFIG_USB_HIDINPUT=y
-CONFIG_HID_FF=y
-CONFIG_HID_PID=y
-CONFIG_LOGITECH_FF=y
-CONFIG_THRUSTMASTER_FF=y
-CONFIG_USB_HIDDEV=y
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_EGALAX is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-
-#
-# USB HID Boot Protocol drivers
-#
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_EGALAX is not set
-# CONFIG_USB_XPAD is not set
-# CONFIG_USB_ATI_REMOTE is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_CATC is not set
-CONFIG_USB_KAWETH=m
-CONFIG_USB_PEGASUS=m
-# CONFIG_USB_RTL8150 is not set
-CONFIG_USB_USBNET=m
-
-#
-# USB Host-to-Host Cables
-#
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_BELKIN=y
-CONFIG_USB_GENESYS=y
-CONFIG_USB_NET1080=y
-CONFIG_USB_PL2301=y
-
-#
-# Intelligent USB Devices/Gadgets
-#
-CONFIG_USB_ARMLINUX=y
-CONFIG_USB_EPSON2888=y
-CONFIG_USB_ZAURUS=y
-CONFIG_USB_CDCETHER=y
-
-#
-# USB Network Adapters
-#
-CONFIG_USB_AX8817X=y
-
-#
-# USB port drivers
-#
-
-#
-# USB Serial Converter support
-#
-CONFIG_USB_SERIAL=m
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_BELKIN=m
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_KOBIL_SCT is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_SAFE is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_TIGL is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_PHIDGETSERVO is not set
-# CONFIG_USB_TEST is not set
-
-#
-# USB Gadget Support
-#
-# CONFIG_USB_GADGET is not set
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_INFO is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_LL=y
-# CONFIG_DEBUG_ICEDCC is not set
-
-#
-# Security options
-#
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Library routines
-#
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/openslug-kernel-2.6.9/nslu2-io.c b/linux/openslug-kernel-2.6.9/nslu2-io.c
deleted file mode 100644
index 53a3df7638..0000000000
--- a/linux/openslug-kernel-2.6.9/nslu2-io.c
+++ /dev/null
@@ -1,748 +0,0 @@
-//=============================================================================
-//
-// n2-io.c version 0.1.7
-// Author: Karen Spearel <kas11 at tampabay.rr.com>
-// please report problems/bugs directly to the address above
-//
-// Boilerplate to be added "real soon now"...it is and has always been GPL'ed per
-// MODULE_LICENSE but is offered without warrantee of any sort..use at your own risk
-//
-// NOTE: THIS IS INCOMPLETE. INCLUDED ONLY TO KEEP FROM BREAKING THE BUILD,
-// IT BEEPS AND SENDS A MESSAGE TO /proc/poweroff. EVENTUALLY IT
-// WILL TALK TO THE n2_pbd DAEMON. EVENTUALLY THE LED DRIVER
-// WILL TALK TO SOME USERLAND APP BUT ***NOT*** SET_LEDS.
-//
-//=============================================================================
-// GPIO Function State
-// 0 Red LED Status
-// 1 Green LED Ready = 1
-// 2 Disk 2 LED On = 0
-// 3 Disk 1 LED On = 0
-// 4 Buzzer
-// 5 Power Button Pressed = 1
-// 8 Power Down Output = 1 powers down N2
-// 12 Reset Pressed = 0
-//=============================================================================
-// this driver is N2 specific and is purposely designed to do the minimum
-// necessary to provide the necessary services given the limited memory resources
-// of the N2. As OpenN2 develops, addition features will be added as
-// suggested by the community.
-//
-//=============================================================================
-
-#include <linux/config.h>
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/utsname.h>
-#include <linux/kernel.h>
-#include <linux/major.h>
-#include <linux/string.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/miscdevice.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/moduleparam.h>
-#include <linux/timer.h>
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/hardware.h>
-#include <asm-arm/irq.h>
-#include <asm-arm/delay.h>
-#include <asm-arm/signal.h>
-
-
-#define VERSION "0.1.7"
-
-#define N2RB_MAJOR 60
-#define N2PB_MAJOR 61
-#define N2BZ_MAJOR 62
-#define N2LM_MAJOR 126
-
-#define N2PB_IRQ 22 //gpio5
-#define N2RB_IRQ 29 //gpio12
-
-#define N2_BEEP_DUR_LONG 2000
-#define N2_BEEP_DUR_MED 400
-#define N2_BEEP_DUR_SHORT 100
-#define N2_BEEP_PITCH_HIGH 250
-#define N2_BEEP_PITCH_MED 500
-#define N2_BEEP_PITCH_LOW 1000
-#define N2_LONG_DELAY 30000
-
-#define N2_BZ_GPIO 4
-#define N2_PB_GPIO 5
-#define N2_PO_GPIO 8 //power off
-#define N2_RB_GPIO 12
-
-#define GPIO_BZ_BM 0x0010 //b0000 0000 0001 0000
-#define GPIO_PB_BM 0x0020 //b0000 0000 0010 0000
-#define GPIO_PO_BM 0x0100 //b0000 0001 0000 0000
-#define GPIO_RB_BM 0x1000 //b0001 0000 0000 0000
-
-#define NOERR 0
-
-#define RB_DELAY 50
-#define PB_DELAY 20
-
-#define PWR_OFF_STR "poweroff"
-
-
-// ioctls -- 'M" is used for sound cards...we don't got one so it seems safe
-
-#define N2BZ_BEEP_STOP _IO('M',0) //stop multi-beep at end of audible
-#define N2BZ_BEEP _IO('M',1) //one beep at current defaults
-#define N2BZ_BEEPS _IOW('M',3,long) //param beeps at current defaults
-#define N2BZ_TONESET _IOW('M',4,long) //set tone: range is high=250 to low=2000
-#define N2BZ_ONTIME _IOW('M',5,long) //ontime for multi-beeps in jiffies
-#define N2BZ_SILENTTIME _IOW('M',6,long) //offtime for multi-beeps in jiffies
-#define N2BZ_REPEATCNT _IOW('M',7,long) //number of repeats for multi-beeps 0 = forever
-#define N2BZ_COMBINED _IOW('M',8,long) //combine all params in a long
-
-#define N2LM_OFF _IOW('M',32,long)
-#define N2LM_ON _IOW('M',33,long)
-#define N2LM_BLINK _IOW('M',34,long)
-#define N2LM_ALT _IOW('M',35,long)
-#define N2LM_ALL_ON _IO('M',36)
-#define N2LM_ALL_OFF _IO('M',37)
-
-#define PHYS_LEDS 4
-#define BLINK_DELAY 25
-
-// OR Masks to turn these LEDs ON
-
-#define RS_RED_ON 0x00000001 //0b0000 0000 0000 0010
-#define RS_GRN_ON 0x00000002 //0b0000 0000 0000 0001
-#define RS_YEL_ON 0x00000003 //0b0000 0000 0000 0011
-
-// AND Masks to turn these LEDs OFF
-
-#define RS_RED_OFF 0xfffffffe //0b1111 1111 1111 1101
-#define RS_GRN_OFF 0xfffffffd //0b1111 1111 1111 1110
-#define RS_YEL_OFF 0xfffffffc //0b1111 1111 1111 1100
-
-// AND Masks to turn these LEDs ON
-
-#define DISK1_ON 0xfffffff7 //0b1111 1111 1111 0111
-#define DISK2_ON 0xfffffffb //0b1111 1111 1111 1011
-
-// Or Masks to turn these LEDs OFF
-
-#define DISK1_OFF 0x00000008 //0b0000 0000 0000 1000
-#define DISK2_OFF 0x00000004 //0b0000 0000 0000 0100
-
-// EOR masks for toggling LEDs on/off
-
-#define RS_RG_ALT 0x00000003 //eor mask to toggle rs rg bits
-#define RS_GRN_TGL 0x00000002
-#define RS_RED_TGL 0x00000001
-#define DISK1_TGL 0x00000008
-#define DISK2_TGL 0x00000004
-
-// The LED names for switches
-
-#define LED_RS_RED 0
-#define LED_RS_GRN 1
-#define LED_DISK1 2
-#define LED_DISK2 3
-#define LED_ALL 4
-
-static unsigned long init_jiffy = 0; //jiffies at init time
-static unsigned long rb_presses = 0; //number of reset button presses
-static unsigned long ontime = 50;
-static unsigned long offtime = 450;
-static unsigned long bz_repeatcnt = 10;
-static unsigned long tone = 1000;
-
-DECLARE_WAIT_QUEUE_HEAD(n2rb_waitq);
-DECLARE_WAIT_QUEUE_HEAD(n2pb_waitq);
-
-static struct timer_list n2lm_rsg_timer; //rs green
-static struct timer_list n2lm_rsr_timer; //rs red
-static struct timer_list n2lm_d1_timer; //drive 1
-static struct timer_list n2lm_d2_timer; //drive 2
-static struct timer_list n2rb_timer;
-static struct timer_list n2pb_timer;
-static struct timer_list n2bz_timer; //beeper
-
-//==================================================================================================
-//
-// Blinking is handled entirely by the 4 timer handlers. On timeout, the bit in the
-// GPIO output register is xor'd with a mask corresponding to the selected led which simply
-// flips that bit. No record of what any of the other leds is doing is needed.
-//
-//==================================================================================================
-// this blinks rs green or green/yellow if rs red is on
-static void n2lm_rsg_handler(unsigned long data)
-{
- *IXP4XX_GPIO_GPOUTR ^= RS_GRN_TGL; //flip the led
- n2lm_rsg_timer.expires = jiffies + BLINK_DELAY; //next timeout
- add_timer(&n2lm_rsg_timer); //reinit timer
- return;
-}
-
-// this blinks or alternates rs red green... inited wit green on/red off
-static void n2lm_rsr_handler(unsigned long data)
-{
- *IXP4XX_GPIO_GPOUTR ^= n2lm_rsr_timer.data;
- n2lm_rsr_timer.expires = jiffies + BLINK_DELAY;
- add_timer(&n2lm_rsr_timer);
- return;
-}
-// blinks disk 1
-static void n2lm_d1_handler(unsigned long data)
-{
- *IXP4XX_GPIO_GPOUTR ^= DISK1_TGL;
- n2lm_d1_timer.expires = jiffies + BLINK_DELAY;
- add_timer(&n2lm_d1_timer);
- return;
-}
-// blinks disk 2
-static void n2lm_d2_handler(unsigned long data)
-{
- *IXP4XX_GPIO_GPOUTR ^= DISK2_TGL;
- n2lm_d2_timer.expires = jiffies + BLINK_DELAY;
- add_timer(&n2lm_d2_timer);
- return;
-}
-
-//==================================================================================================
-
-static void n2lm_timer_start(unsigned long led)
-{
-
- printk(KERN_DEBUG "timer: %ld\n",led);
-
- switch(led) {
- case LED_RS_RED:
- n2lm_rsr_timer.expires = jiffies + BLINK_DELAY;
- add_timer(&n2lm_rsr_timer);
- break;
-
- case LED_RS_GRN:
- n2lm_rsg_timer.expires = jiffies + BLINK_DELAY;
- add_timer(&n2lm_rsg_timer);
- break;
-
- case LED_DISK1:
- n2lm_d1_timer.expires = jiffies + BLINK_DELAY;
- add_timer(&n2lm_d1_timer);
- break;
-
- case LED_DISK2:
- n2lm_d2_timer.expires = jiffies + BLINK_DELAY;
- add_timer(&n2lm_d2_timer);
- break;
-
- default:
- break;
- }
- return;
-}
-
-//==================================================================================================
-
-static void n2lm_timer_stop(unsigned long led)
-{
- switch (led) {
- case LED_RS_RED:
- del_timer(&n2lm_rsr_timer);
- break;
- case LED_RS_GRN:
- del_timer(&n2lm_rsg_timer);
- break;
- case LED_DISK1:
- del_timer(&n2lm_d1_timer);
- break;
- case LED_DISK2:
- del_timer(&n2lm_d2_timer);
- break;
- default:
- break;
- }
- return;
-}
-
-//--------------------------------------------------------------------------------------------------
-
-static void n2lm_timer_stop_all(void)
-{
- del_timer(&n2lm_rsg_timer);
- del_timer(&n2lm_rsr_timer);
- del_timer(&n2lm_d1_timer);
- del_timer(&n2lm_d2_timer);
- return;
-}
-//--------------------------------------------------------------------------------------------------
-
-static void n2lm_ledon(unsigned long led)
-{
-
- printk(KERN_DEBUG "ledon: %ld\n", led);
-
- switch (led) {
- case LED_RS_RED:
- *IXP4XX_GPIO_GPOUTR |= RS_RED_ON; //1
- return;
- case LED_RS_GRN:
- *IXP4XX_GPIO_GPOUTR |= RS_GRN_ON; //2
- return;
- case LED_DISK1:
- *IXP4XX_GPIO_GPOUTR &= DISK1_ON; //0xfffffffb
- return;
- case LED_DISK2:
- *IXP4XX_GPIO_GPOUTR &= DISK2_ON; //0xfffffff7
- return;
- case LED_ALL: //all green
- *IXP4XX_GPIO_GPOUTR |= RS_GRN_ON;
- *IXP4XX_GPIO_GPOUTR &= (DISK1_ON & DISK2_ON);
- return;
- }
-}
-
-//--------------------------------------------------------------------------------------------------
-
-static void n2lm_ledoff(unsigned long led)
-{
-
- switch (led) {
- case LED_RS_RED:
- *IXP4XX_GPIO_GPOUTR &= RS_RED_OFF; //0xffffffffe
- return;
- case LED_RS_GRN:
- *IXP4XX_GPIO_GPOUTR &= RS_GRN_OFF; //0xfffffffd
- return;
- case LED_DISK1:
- *IXP4XX_GPIO_GPOUTR |= DISK1_OFF; //0x00000004
- return;
- case LED_DISK2:
- *IXP4XX_GPIO_GPOUTR |= DISK2_OFF; //0x00000008
- return;
- case LED_ALL:
- *IXP4XX_GPIO_GPOUTR &= (RS_GRN_OFF & RS_RED_OFF);
- *IXP4XX_GPIO_GPOUTR |= (DISK1_OFF | DISK2_OFF);
- }
-}
-
-//==================================================================================================
-
-static int n2lm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long led)
-{
-
- printk(KERN_DEBUG "cmd=%d, led=%ld\n", cmd, led);
-
- if (led < 0 || led >= PHYS_LEDS)
- return -EINVAL;
-
- switch (cmd ) {
- case N2LM_ON:
- n2lm_timer_stop(led);
- n2lm_ledon(led);
- break;
-
- case N2LM_OFF:
- n2lm_timer_stop(led);
- n2lm_ledoff(led);
- break;
-
- case N2LM_BLINK:
- n2lm_ledon(led);
- if (led == LED_RS_RED)
- n2lm_rsr_timer.data = RS_RED_TGL;
- if (led == LED_RS_GRN)
- n2lm_rsr_timer.data = RS_GRN_TGL;
- n2lm_timer_start(led);
- break;
-
- case N2LM_ALT:
- if (led == LED_RS_RED)
- {
- n2lm_ledon(LED_RS_GRN);
- n2lm_ledoff(LED_RS_RED);
- n2lm_rsr_timer.data = RS_RG_ALT;
- n2lm_timer_start(LED_RS_RED);
- break;
- } else
- return -EINVAL;
-
- case N2LM_ALL_ON:
- n2lm_timer_stop_all();
- n2lm_ledon(LED_ALL);
- break;
-
- case N2LM_ALL_OFF:
- n2lm_timer_stop_all();
- n2lm_ledoff(LED_ALL);
- break;
-
- default:
- return -EINVAL;
- }
-
- return NOERR;
-}
-
-static struct file_operations n2lm_fops = {
- .owner = THIS_MODULE,
- .ioctl = n2lm_ioctl,
-};
-//==================================================================================================
-// We can't do anything fancy here since the system tick rate is far below that required to
-// generate a desirable tone. Therefore we haven't much choice but to use a busy loop until
-// I get up to speed on the timers. The saving grace is that for the normal uses, nothing
-// important should be haprepening.
-//==================================================================================================
-
-static void n2_buzz(int tone_delay, int duration)
-{
- int i;
-
- *IXP4XX_GPIO_GPOER &= ~GPIO_BZ_BM;
-
- for (i = 1; i < duration; i++) {
- *IXP4XX_GPIO_GPOUTR &= ~GPIO_BZ_BM;
- udelay(tone_delay);
- *IXP4XX_GPIO_GPOUTR |= GPIO_BZ_BM;
- udelay(tone_delay);
- }
- *IXP4XX_GPIO_GPOER |= GPIO_BZ_BM;
-
- return;
-}
-//=================================================================================================
-
-// this handles the buzzer duty cycle
-static void n2bz_handler(unsigned long data)
-{
- if (--bz_repeatcnt > 0) { //if just one beep left to do
- n2bz_timer.expires = jiffies + ontime + offtime; //next timeout
- add_timer(&n2bz_timer); //reinit timer
- }
- n2_buzz(tone/2, ontime);
- printk(KERN_DEBUG "Count = %d\tOntime = %d\n", bz_repeatcnt, ontime);
- return;
-}
-
-//==================================================================================================
-
-static int n2bz_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long param)
-{
- switch (cmd) {
- case N2BZ_BEEP:
- n2_buzz(tone/2, ontime);
- break;
-
- case N2BZ_BEEP_STOP:
- del_timer(&n2bz_timer);
- break;
-
- case N2BZ_BEEPS:
- if (param == 0)
- bz_repeatcnt = 0xffffffff;
- else
- bz_repeatcnt = param;
- n2bz_handler(0);
- break;
-
- case N2BZ_TONESET:
- if (param >= 250 && param <= 2000)
- tone = param;
- break;
-
- case N2BZ_ONTIME:
- if (param > 4 && param < 201)
- ontime = param;
- break;
-
- case N2BZ_SILENTTIME:
- if (param > ontime) //enforce a reasonable duty cycle
- offtime = param;
- else
- offtime = ontime;
- break;
-
- case N2BZ_REPEATCNT:
- if (param == 0)
- bz_repeatcnt = 0xffffffff;
- else
- bz_repeatcnt = param;
- break;
-
- case N2BZ_COMBINED:
- bz_repeatcnt = (param & 0xF0000000) >> 28; //repeat 1 - 16
- ontime = (param & 0x0FF00000) >> 20; //ontime 1 - 256 jiffies
- offtime = (param & 0x000FFF00) >> 8; //offtime 1 - 4095 jiffies
- tone = (param & 0x000000FF) << 4; //tone (1 - 255) * 16
- break;
-
- default:
- break;
- }
- return NOERR;
-}
-
-static struct file_operations n2bz_fops = {
- .owner = THIS_MODULE,
- .ioctl = n2bz_ioctl,
-};
-
-//==================================================================================================
-
-static irqreturn_t n2pb_handler (int irq, void *dev_id, struct pt_regs *regs)
-{
- void *ret;
-
- wake_up(&n2pb_waitq);
- remove_proc_entry(PWR_OFF_STR, NULL); //no parent
- n2_buzz(N2_BEEP_PITCH_MED, N2_BEEP_DUR_MED);
- ret = create_proc_entry(PWR_OFF_STR, 0, NULL);
- printk(KERN_DEBUG "cpe ret = %p\n", ret);
-
-// WARNING: This is RUDE...it unconditionally pulls the power plug.
-// Your data will be at risk...since this is just a test system
-// I am leaving it enabled...eventually userland needs to get the
-// message, do an orderly shutdown and use an ioctl or something in
-// /proc/powerdowm to actually have us pull the plug.
-
- *IXP4XX_GPIO_GPOER &= ~GPIO_PO_BM; // enable the pwr cntl gpio
- *IXP4XX_GPIO_GPOUTR |= GPIO_PO_BM; // do the deed
-
- return IRQ_HANDLED;
-}
-
-//==================================================================================================
-//
-//static void do_rb_timeout(unsigned long data)
-//{
-// int i;
-//
-// for (i = 0; i < rb_presses; i++)
-// n2_buzz(N2_BEEP_PITCH_MED,N2_BEEP_DUR_SHORT);
-// return;
-//}
-//
-//==================================================================================================
-// does nothing -- waiting for userland to define
-// This thing is sorta braindead...edge triggered IRQs aren't available in the drivers yet...so
-// we hang in a loop until the button is no longer pressed
-
-struct testr {
- int ctl;
- long param;
-};
-
-static irqreturn_t n2rb_handler (int irq, void *dev_id, struct pt_regs *regs)
-{
-
- static struct testr test[] = {
- N2LM_ALL_OFF,0,
- N2LM_ON,0,
- N2LM_OFF,0,
- N2LM_ON,1,
- N2LM_ALL_OFF,1,
- N2LM_ON,2,
- N2LM_OFF,2,
- N2LM_ON,3,
- N2LM_OFF,3,
- N2LM_BLINK,0,
- N2LM_OFF,0,
- N2LM_BLINK,1,
- N2LM_OFF,1,
- N2LM_BLINK,2,
- N2LM_OFF,2,
- N2LM_BLINK,3,
- N2LM_OFF,3,
- N2LM_ALL_OFF,0,
- N2LM_ALT,1,
- N2LM_OFF,1,
- N2LM_ALL_ON,0
- };
-
- printk("Reset Entry IRQ =%d Presses = %d Jiffies = %08lx\tIO = %x\tIOW = %x\n", irq, rb_presses, jiffies, (int)_IO('M',rb_presses), (int)_IOW('M',rb_presses,long));
-
- wake_up(&n2rb_waitq);
- while ((*IXP4XX_GPIO_GPINR & GPIO_RB_BM) == 0)
- ; //wait for button release
-
- if (rb_presses > 20)
- rb_presses = 0;
- tone = (rb_presses * 50) + 200;
- ontime = (rb_presses*10) + 100;
- offtime = 500 - (rb_presses*20);
- printk("Ontime = %d\tOfftime = %d\tTone = %d\n",ontime,offtime,tone);
- rb_presses++;
-
- n2bz_ioctl(NULL,NULL, N2BZ_BEEPS, rb_presses);
- n2lm_ioctl(NULL,NULL, test[rb_presses].ctl, test[rb_presses].param);
-// if (rb_presses == 0) {
-// init_jiffy = jiffies;
-// init_timer (&n2rb_timer);
-// n2rb_timer.function = do_rb_timeout;
-// };
-//
-// if (rb_presses == 8)
-// rb_presses = 0;
-// if (rb_presses & 1)
-// n2lm_ledon(test[rb_presses]);
-// else
-// n2lm_ledoff(test[rb_presses]);
-//
-// n2rb_timer.expires = (jiffies + RB_DELAY);
-// add_timer (&n2rb_timer);
-// if (rb_presses < 5) {
-// if (rb_presses > 0)
-// n2lm_ledoff(rb_presses);
-// n2lm_ledon(++rb_presses);
-// n2lm_timer_start(rb_presses);
-// };
-
- printk(KERN_DEBUG "Reset Exit IRQ=%d Presses= %d Jiffies= %08lx\n", irq, rb_presses, jiffies);
- return IRQ_HANDLED;
-
-}
-
-//==================================================================================================
-// What to do here is majorly undetermined...
-
-static int n2rb_read (struct file *filp, char __user *buffer, size_t count, loff_t *ppos)
-{
- printk(KERN_DEBUG "Reset Button Wait\n");
- interruptible_sleep_on(&n2rb_waitq);
- return copy_to_user(buffer, "reset", 5) ? -EFAULT : 5;
-
-}
-
-//==================================================================================================
-// What to do here is majorly undetermined...
-
-static int n2pb_read (struct file *filp, char __user *buffer, size_t count, loff_t *ppos)
-{
- printk(KERN_DEBUG "Power Button Wait\n");
- interruptible_sleep_on(&n2pb_waitq);
- return copy_to_user(buffer, "poweroff", 8) ? -EFAULT : 8;
-
-}
-
-//--------------------------------------------------------------------------------------------------
-
-static struct file_operations n2rb_fops = {
- .owner = THIS_MODULE,
- .read = n2rb_read,
-};
-
-//--------------------------------------------------------------------------------------------------
-
-static struct file_operations n2pb_fops = {
- .owner = THIS_MODULE,
- .read = n2pb_read,
-};
-
-//==================================================================================================
-
-static void n2iom_initarch(void)
-{
- printk(KERN_DEBUG "setup_interrupts - jiffies=%ld init_jiffy=%ld\n", jiffies, init_jiffy);
-
- *IXP4XX_GPIO_GPISR = 0x20400000; // read the 2 irqs to clr
- gpio_line_config(N2_RB_GPIO, IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
- gpio_line_isr_clear(N2_RB_GPIO);
- gpio_line_config(N2_PB_GPIO, IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_HIGH);
- gpio_line_isr_clear(N2_PB_GPIO);
-
- init_timer(&n2lm_rsg_timer);
- init_timer(&n2lm_rsr_timer);
- init_timer(&n2lm_d1_timer);
- init_timer(&n2lm_d2_timer);
-// init_timer(&n2rb_timer);
-// init_timer(&n2pb_timer);
- init_timer(&n2bz_timer);
- n2lm_rsr_timer.function = n2lm_rsr_handler;
- n2lm_rsg_timer.function = n2lm_rsg_handler;
- n2lm_d2_timer.function = n2lm_d2_handler;
- n2lm_d1_timer.function = n2lm_d1_handler;
- n2bz_timer.function = n2bz_handler;
- n2lm_rsr_timer.data = n2lm_rsg_timer.data = n2lm_d1_timer.data = n2lm_d2_timer.data = n2bz_timer.data = 0;
-
- *IXP4XX_GPIO_GPOER &= 0xfffffff0; //enable gpio 0-3
- *IXP4XX_GPIO_GPOUTR |= 0x00000003; //turn off the leds
- *IXP4XX_GPIO_GPOUTR &= 0xfffffffc;
- n2lm_ledon(LED_ALL);
- n2_buzz(N2_BEEP_PITCH_MED, N2_BEEP_DUR_SHORT);
- n2lm_ledoff(LED_ALL);
-
- return;
-}
-
-//==================================================================================================
-
-static int __init n2iom_init(void)
-{
- printk(KERN_INFO "OpenN2 Misc I/O Driver Version %s\n", VERSION);
-
- init_jiffy = jiffies;
- printk(KERN_DEBUG "init_jiffy=%ld\n",init_jiffy);
- n2iom_initarch();
-
- if (register_chrdev(N2RB_MAJOR, "n2_rbm", &n2pb_fops) < NOERR) {
- printk(KERN_DEBUG "Reset Button Major %d not available\n", N2RB_MAJOR);
- return -EBUSY;
- }
- if (register_chrdev(N2PB_MAJOR, "n2_pbm", &n2rb_fops) < NOERR) {
- printk(KERN_DEBUG "Power Button Major %d not available\n", N2PB_MAJOR);
- return -EBUSY;
- }
- if (register_chrdev(N2LM_MAJOR, "n2_ledm", &n2lm_fops) < NOERR) {
- printk(KERN_DEBUG "Led Manager Major %d not available\n", N2LM_MAJOR);
- return -EBUSY;
- }
- if (register_chrdev(N2BZ_MAJOR, "n2_bzm", &n2bz_fops) < NOERR) {
- printk(KERN_DEBUG "Buzzer Major %d not available\n", N2BZ_MAJOR);
- return -EBUSY;
- }
-
- if (request_irq(N2RB_IRQ, &n2rb_handler, SA_INTERRUPT, "n2_rb", NULL) < NOERR) {
- printk(KERN_DEBUG "Reset Button IRQ %d not available\n", N2RB_IRQ);
- return -EIO;
- }
- if (request_irq(N2PB_IRQ, &n2pb_handler, SA_INTERRUPT, "n2_pb", NULL) < NOERR) {
- printk(KERN_DEBUG "Power Button IRQ %d not available\n", N2PB_IRQ);
- return -EIO;
- }
-
- enable_irq(N2PB_IRQ);
- enable_irq(N2RB_IRQ);
- return (NOERR);
-}
-
-//==================================================================================================
-
-static void __exit n2iom_exit(void)
-{
- remove_proc_entry(PWR_OFF_STR, NULL);
- del_timer(&n2rb_timer);
- free_irq(N2RB_IRQ,NULL);
- unregister_chrdev(N2PB_MAJOR, "n2pb");
- del_timer(&n2pb_timer);
- free_irq(N2PB_IRQ, NULL);
- unregister_chrdev(N2RB_MAJOR, "n2rb" );
- del_timer(&n2lm_rsg_timer);
- del_timer(&n2lm_rsr_timer);
- del_timer(&n2lm_d1_timer);
- del_timer(&n2lm_d2_timer);
- unregister_chrdev(N2LM_MAJOR, "n2lm" );
-}
-
-module_init (n2iom_init);
-module_exit (n2iom_exit);
-
-MODULE_AUTHOR("Karen Spearel <kas11@tampabay.rr.com>");
-MODULE_DESCRIPTION("OpenN2 Buttons/LEDs IO Driver");
-MODULE_LICENSE("GPL");
-static int debug = 7;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debugging enabled = 8");
-
diff --git a/linux/openslug-kernel-2.6.9/nslu2-part.c b/linux/openslug-kernel-2.6.9/nslu2-part.c
deleted file mode 100644
index 6fbf952e2a..0000000000
--- a/linux/openslug-kernel-2.6.9/nslu2-part.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * nslu2-part.c
- *
- * Maintainers: http://www.nslu2-linux.org/
- * Initial port: Mark Rakes <mrakes AT mac.com>
- *
- * "Parse" the fixed partition table of the Linksys NSLU2 and
- * produce a Linux partition array to match.
- */
-
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/vmalloc.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-
-/* info we know about the NSLU2's flash setup:
- *
- * Num Partition offset size
- * --- --------- ---------- -----------
- * 0 RedBoot 0x00000000 0x00040000
- * 1 System Configuration 0x00040000 0x00020000
- * 2 Kernel 0x00060000 0x00100000
- * 3 Ramdisk 0x00160000 0x006a0000
- */
- #define NSLU2_NUM_FLASH_PARTITIONS 4
- #define NSLU2_FLASH_PART0_NAME "RedBoot"
- #define NSLU2_FLASH_PART0_OFFSET 0x00000000
- #define NSLU2_FLASH_PART0_SIZE 0x00040000
- #define NSLU2_FLASH_PART1_NAME "System Configuration"
- #define NSLU2_FLASH_PART1_OFFSET (NSLU2_FLASH_PART0_OFFSET + NSLU2_FLASH_PART0_SIZE)
- #define NSLU2_FLASH_PART1_SIZE 0x00020000
- #define NSLU2_FLASH_PART2_NAME "Kernel"
- #define NSLU2_FLASH_PART2_OFFSET (NSLU2_FLASH_PART1_OFFSET + NSLU2_FLASH_PART1_SIZE)
- #define NSLU2_FLASH_PART2_SIZE 0x00100000
- #define NSLU2_FLASH_PART3_NAME "Ramdisk"
- #define NSLU2_FLASH_PART3_OFFSET (NSLU2_FLASH_PART2_OFFSET + NSLU2_FLASH_PART2_SIZE)
- #define NSLU2_FLASH_PART3_SIZE 0x006a0000
-
-static int parse_nslu2_partitions(struct mtd_info *master,
- struct mtd_partition **pparts,
- unsigned long flash_start)
-{
- struct mtd_partition *parts;
- int ret = 0, namelen = 0;
- char *names;
-
- namelen = strlen(NSLU2_FLASH_PART0_NAME) +
- strlen(NSLU2_FLASH_PART1_NAME) +
- strlen(NSLU2_FLASH_PART2_NAME) +
- strlen(NSLU2_FLASH_PART3_NAME) +
- NSLU2_NUM_FLASH_PARTITIONS; /*4 strings + each terminator */
-
- parts = kmalloc(sizeof(*parts)*NSLU2_NUM_FLASH_PARTITIONS + namelen, GFP_KERNEL);
- if (!parts) {
- ret = -ENOMEM;
- goto out;
- }
-
- memset(parts, 0, sizeof(*parts)*NSLU2_NUM_FLASH_PARTITIONS + namelen);
- names = (char *)&parts[NSLU2_NUM_FLASH_PARTITIONS];
-
- /* RedBoot partition */
- parts[0].size = NSLU2_FLASH_PART0_SIZE;
- parts[0].offset = NSLU2_FLASH_PART0_OFFSET;
- parts[0].name = NSLU2_FLASH_PART0_NAME;
- parts[0].mask_flags = MTD_WRITEABLE; /* readonly */
- strcpy(names, NSLU2_FLASH_PART0_NAME);
- names += strlen(names)+1;
- /* System Configuration */
- parts[1].size = NSLU2_FLASH_PART1_SIZE;
- parts[1].offset = NSLU2_FLASH_PART1_OFFSET;
- parts[1].name = NSLU2_FLASH_PART1_NAME;
- parts[1].mask_flags = MTD_WRITEABLE; /* readonly */
- strcpy(names, NSLU2_FLASH_PART1_NAME);
- names += strlen(names)+1;
- /* Kernel */
- parts[2].size = NSLU2_FLASH_PART2_SIZE;
- parts[2].offset = NSLU2_FLASH_PART2_OFFSET;
- parts[2].name = NSLU2_FLASH_PART2_NAME;
- parts[2].mask_flags = MTD_WRITEABLE; /* readonly */
- strcpy(names, NSLU2_FLASH_PART2_NAME);
- names += strlen(names)+1;
- /* Ramdisk */
- parts[3].size = NSLU2_FLASH_PART3_SIZE;
- parts[3].offset = NSLU2_FLASH_PART3_OFFSET;
- parts[3].name = NSLU2_FLASH_PART3_NAME;
- parts[3].mask_flags = MTD_WRITEABLE; /* readonly */
- strcpy(names, NSLU2_FLASH_PART3_NAME);
- names += strlen(names)+1;
-
- ret = NSLU2_NUM_FLASH_PARTITIONS;
- *pparts = parts;
- out:
- return ret;
-}
-
-static struct mtd_part_parser nslu2_parser = {
- .owner = THIS_MODULE,
- .parse_fn = parse_nslu2_partitions,
- .name = "NSLU2",
-};
-
-static int __init nslu2_parser_init(void)
-{
- return register_mtd_parser(&nslu2_parser);
-}
-
-static void __exit nslu2_parser_exit(void)
-{
- deregister_mtd_parser(&nslu2_parser);
-}
-
-module_init(nslu2_parser_init);
-module_exit(nslu2_parser_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Mark Rakes");
-MODULE_DESCRIPTION("Parsing code for NSLU2 flash tables");
diff --git a/linux/openslug-kernel-2.6.9/nslu2-pci.c b/linux/openslug-kernel-2.6.9/nslu2-pci.c
deleted file mode 100644
index 7327c65a4f..0000000000
--- a/linux/openslug-kernel-2.6.9/nslu2-pci.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/nslu2-pci.c
- *
- * NSLU2 board-level PCI initialization
- *
- * based on ixdp425-pci.c:
- * Copyright (C) 2002 Intel Corporation.
- * Copyright (C) 2003-2004 MontaVista Software, Inc.
- *
- * Maintainer: http://www.nslu2-linux.org/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-// GPIO 8 is used as the power input so is not free for use as a PCI IRQ
-// However, all the common PCI setup code presumes the standard 4 PCI
-// interrupts are available. So we compromise...we don't enable the
-// IRQ on Pin 8 but we let
-
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-
-#include <asm/mach/pci.h>
-#include <asm/irq.h>
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-
-void __init nslu2_pci_preinit(void)
-{
- gpio_line_config(NSLU2_PCI_INTA_PIN,
- IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
- gpio_line_config(NSLU2_PCI_INTB_PIN,
- IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
- gpio_line_config(NSLU2_PCI_INTC_PIN,
- IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
-// gpio_line_config(NSLU2_PCI_INTD_PIN,
-// IXP4XX_GPIO_IN | IXP4XX_GPIO_ACTIVE_LOW);
-
- gpio_line_isr_clear(NSLU2_PCI_INTA_PIN);
- gpio_line_isr_clear(NSLU2_PCI_INTB_PIN);
- gpio_line_isr_clear(NSLU2_PCI_INTC_PIN);
-// gpio_line_isr_clear(NSLU2_PCI_INTD_PIN);
-
- ixp4xx_pci_preinit();
-}
-
-static int __init nslu2_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
- static int pci_irq_table[NSLU2_PCI_IRQ_LINES] = {
- IRQ_NSLU2_PCI_INTA,
- IRQ_NSLU2_PCI_INTB,
- IRQ_NSLU2_PCI_INTC,
-// IRQ_NSLU2_PCI_INTD
- };
-
- int irq = -1;
-
- if (slot >= 1 && slot <= NSLU2_PCI_MAX_DEV &&
- pin >= 1 && pin <= NSLU2_PCI_IRQ_LINES) {
- irq = pci_irq_table[(slot + pin - 2) % 3]; // ! % 4 kas11
- }
-
- return irq;
-}
-
-struct hw_pci __initdata nslu2_pci = {
- .nr_controllers = 1,
- .preinit = nslu2_pci_preinit,
- .swizzle = pci_std_swizzle,
- .setup = ixp4xx_setup,
- .scan = ixp4xx_scan_bus,
- .map_irq = nslu2_map_irq,
-};
-
-int __init nslu2_pci_init(void) //monkey see, monkey do
-{
- if (machine_is_nslu2())
- pci_common_init(&nslu2_pci);
- return 0;
-}
-
-subsys_initcall(nslu2_pci_init);
-
diff --git a/linux/openslug-kernel-2.6.9/nslu2-setup.c b/linux/openslug-kernel-2.6.9/nslu2-setup.c
deleted file mode 100644
index 5698ea9813..0000000000
--- a/linux/openslug-kernel-2.6.9/nslu2-setup.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/nslu2-setup.c
- *
- * NSLU2 board-setup
- *
- * based ixdp425-setup.c:
- * Copyright (C) 2003-2004 MontaVista Software, Inc.
- *
- * Author: Mark Rakes <mrakes at mac.com>
- * Maintainers: http://www.nslu2-linux.org/
- *
- * Fixed missing init_time in MACHINE_START kas11 10/22/04
- * Changed to conform to new style __init ixdp425 kas11 10/22/04
- */
-
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial.h>
-#include <linux/tty.h>
-#include <linux/serial_core.h>
-
-#include <asm/types.h>
-#include <asm/setup.h>
-#include <asm/memory.h>
-#include <asm/hardware.h>
-#include <asm/mach-types.h>
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
-
-#ifdef __ARMEB__
-#define REG_OFFSET 3
-#else
-#define REG_OFFSET 0
-#endif
-
-/*
- * NSLU2 uses only one serial port
- */
-static struct uart_port nslu2_serial_ports[] = {
- {
- .membase = (char*)(IXP4XX_UART1_BASE_VIRT + REG_OFFSET),
- .mapbase = (IXP4XX_UART1_BASE_PHYS),
- .irq = IRQ_IXP4XX_UART1,
- .flags = UPF_SKIP_TEST,
- .iotype = UPIO_MEM,
- .regshift = 2,
- .uartclk = IXP4XX_UART_XTAL,
- .line = 0,
- .type = PORT_XSCALE,
- .fifosize = 32
- }
-#if 0
- , {
- .membase = (char*)(IXP4XX_UART2_BASE_VIRT + REG_OFFSET),
- .mapbase = (IXP4XX_UART2_BASE_PHYS),
- .irq = IRQ_IXP4XX_UART2,
- .flags = UPF_SKIP_TEST,
- .iotype = UPIO_MEM,
- .regshift = 2,
- .uartclk = IXP4XX_UART_XTAL,
- .line = 1,
- .type = PORT_XSCALE,
- .fifosize = 32
- }
-#endif
-};
-
-void __init nslu2_map_io(void)
-{
- early_serial_setup(&nslu2_serial_ports[0]);
-#if 0
- early_serial_setup(&nslu2_serial_ports[1]);
-#endif
- ixp4xx_map_io();
-}
-
-static struct flash_platform_data nslu2_flash_data = {
- .map_name = "cfi_probe",
- .width = 2,
-};
-
-static struct resource nslu2_flash_resource = {
- .start = NSLU2_FLASH_BASE,
- .end = NSLU2_FLASH_BASE + NSLU2_FLASH_SIZE,
- .flags = IORESOURCE_MEM,
-};
-
-static struct platform_device nslu2_flash = {
- .name = "IXP4XX-Flash",
- .id = 0,
- .dev = {
- .platform_data = &nslu2_flash_data,
- },
- .num_resources = 1,
- .resource = &nslu2_flash_resource,
-};
-
-static struct ixp4xx_i2c_pins nslu2_i2c_gpio_pins = {
- .sda_pin = NSLU2_SDA_PIN,
- .scl_pin = NSLU2_SCL_PIN,
-};
-
-static struct platform_device nslu2_i2c_controller = {
- .name = "IXP4XX-I2C",
- .id = 0,
- .dev = {
- .platform_data = &nslu2_i2c_gpio_pins,
- },
- .num_resources = 0
-};
-
-static struct platform_device *nslu2_devices[] __initdata = {
- &nslu2_i2c_controller,
- &nslu2_flash
-};
-
-static void __init nslu2_init(void)
-{
- platform_add_devices(&nslu2_devices, ARRAY_SIZE(nslu2_devices));
-}
-
-MACHINE_START(NSLU2, "Linksys NSLU2")
- MAINTAINER("www.nslu2-linux.org")
- BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS,
- IXP4XX_PERIPHERAL_BASE_VIRT)
- MAPIO(nslu2_map_io)
- INITIRQ(ixp4xx_init_irq) //FIXME: all irq are off here
- INITTIME(ixp4xx_init_time) //this was missing in 2.6.7 code ...soft reboot needed?
- BOOT_PARAMS(0x0100)
- INIT_MACHINE(nslu2_init)
-MACHINE_END
diff --git a/linux/openslug-kernel-2.6.9/nslu2.h b/linux/openslug-kernel-2.6.9/nslu2.h
deleted file mode 100644
index bb79aaa007..0000000000
--- a/linux/openslug-kernel-2.6.9/nslu2.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * include/asm-arm/arch-ixp4xx/nslu2.h
- *
- * NSLU2 platform specific definitions
- *
- * Author: Mark Rakes <mrakes AT mac.com>
- * Maintainers: http://www.nslu2-linux.org
- *
- * based on ixdp425.h:
- * Copyright 2004 (c) MontaVista, Software, Inc.
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-// GPIO 8 is used as the power input so is not free for use as a PCI IRQ
-// kas11 11-2-04
-
-#ifndef __ASM_ARCH_HARDWARE_H__
-#error "Do not include this directly, instead #include <asm/hardware.h>"
-#endif
-
-#define NSLU2_FLASH_BASE IXP4XX_EXP_BUS_CS0_BASE_PHYS
-#define NSLU2_FLASH_SIZE IXP4XX_EXP_BUS_CSX_REGION_SIZE
-
-#define NSLU2_SDA_PIN 7
-#define NSLU2_SCL_PIN 6
-
-/*
- * NSLU2 PCI IRQs
- */
-#define NSLU2_PCI_MAX_DEV 3
-#define NSLU2_PCI_IRQ_LINES 3
-
-
-/* PCI controller GPIO to IRQ pin mappings */
-#define NSLU2_PCI_INTA_PIN 11
-#define NSLU2_PCI_INTB_PIN 10
-#define NSLU2_PCI_INTC_PIN 9
-//#define NSLU2_PCI_INTD_PIN 8
-
-
diff --git a/linux/openslug-kernel-2.6.9/nslu2_2.6.9.patch b/linux/openslug-kernel-2.6.9/nslu2_2.6.9.patch
deleted file mode 100644
index 9f569baabf..0000000000
--- a/linux/openslug-kernel-2.6.9/nslu2_2.6.9.patch
+++ /dev/null
@@ -1,312 +0,0 @@
-diff -purN linux-2.6.9/arch/arm/mach-ixp4xx/Kconfig linux-2.6.9-new/arch/arm/mach-ixp4xx/Kconfig
---- linux-2.6.9/arch/arm/mach-ixp4xx/Kconfig 2004-06-15 22:19:01.000000000 -0700
-+++ linux-2.6.9-new/arch/arm/mach-ixp4xx/Kconfig 2004-09-14 03:59:28.000000000 -0700
-@@ -29,6 +29,13 @@ config ARCH_IXDP425
- IXDP425 Development Platform (Also known as Richfield).
- For more information on this platform, see Documentation/arm/IXP4xx.
-
-+config ARCH_NSLU2
-+ bool "NSLU2"
-+ help
-+ Say 'Y' here if you want your kernel to support Linksys's
-+ NSLU2 NAS device. For more information on this platform,
-+ see http://www.nslu2-linux.org
-+
- #
- # IXCDP1100 is the exact same HW as IXDP425, but with a different machine
- # number from the bootloader due to marketing monkeys, so we just enable it
---- linux-2.6.9.orig/arch/arm/mach-ixp4xx/Makefile 2004-06-16 01:18:59.000000000 -0400
-+++ linux-2.6.9/arch/arm/mach-ixp4xx/Makefile 2004-09-24 01:35:22.051627330 -0400
-@@ -4,7 +4,6 @@
-
- obj-y += common.o common-pci.o
-
--obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o ixdp425-setup.o
- obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o coyote-setup.o
- obj-$(CONFIG_ARCH_PRPMC1100) += prpmc1100-pci.o prpmc1100-setup.o
--
-+obj-$(CONFIG_ARCH_NSLU2) += nslu2-pci.o nslu2-setup.o nslu2-part.o nslu2-io.o
-diff -purN linux-2.6.9/drivers/mtd/maps/ixp4xx.c linux-2.6.9-new/drivers/mtd/maps/ixp4xx.c
---- linux-2.6.9/drivers/mtd/maps/ixp4xx.c 2004-06-15 22:18:38.000000000 -0700
-+++ linux-2.6.9-new/drivers/mtd/maps/ixp4xx.c 2004-09-14 03:59:28.000000000 -0700
-@@ -82,7 +82,11 @@ struct ixp4xx_flash_info {
- struct resource *res;
- };
-
-+#ifdef CONFIG_ARCH_NSLU2
-+static const char *probes[] = { "cmdlinepart", "RedBoot", "NSLU2", NULL };
-+#else
- static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-+#endif
-
- static int
- ixp4xx_flash_remove(struct device *_dev)
-diff -purN linux-2.6.9/include/asm-arm/arch-ixp4xx/hardware.h linux-2.6.9-new/include/asm-arm/arch-ixp4xx/hardware.h
---- linux-2.6.9/include/asm-arm/arch-ixp4xx/hardware.h 2004-06-15 22:19:02.000000000 -0700
-+++ linux-2.6.9-new/include/asm-arm/arch-ixp4xx/hardware.h 2004-09-14 03:59:28.000000000 -0700
-@@ -37,5 +37,6 @@
- #include "ixdp425.h"
- #include "coyote.h"
- #include "prpmc1100.h"
-+#include "nslu2.h"
-
- #endif /* _ASM_ARCH_HARDWARE_H */
-diff -purN linux-2.6.9/include/asm-arm/arch-ixp4xx/irqs.h linux-2.6.9-new/include/asm-arm/arch-ixp4xx/irqs.h
---- linux-2.6.9/include/asm-arm/arch-ixp4xx/irqs.h 2004-06-15 22:19:37.000000000 -0700
-+++ linux-2.6.9-new/include/asm-arm/arch-ixp4xx/irqs.h 2004-09-14 03:59:28.000000000 -0700
-@@ -75,4 +75,12 @@
- #define IRQ_COYOTE_PCI_SLOT1 IRQ_IXP4XX_GPIO11
- #define IRQ_COYOTE_IDE IRQ_IXP4XX_GPIO5
-
-+/*
-+ * NSLU2 board IRQs
-+ */
-+#define IRQ_NSLU2_PCI_INTA IRQ_IXP4XX_GPIO11
-+#define IRQ_NSLU2_PCI_INTB IRQ_IXP4XX_GPIO10
-+#define IRQ_NSLU2_PCI_INTC IRQ_IXP4XX_GPIO9
-+
-+
- #endif
-diff -Nru linux-2.6.9/arch/arm/mach-ixp4xx/common-pci.c linux-2.6.9/arch/arm/mach-ixp4xx/common-pci.c
---- linux-2.6.9/arch/arm/mach-ixp4xx/common-pci.c 2004-10-08 13:59:23 -07:00
-+++ linux-2.6.9/arch/arm/mach-ixp4xx/common-pci.c 2004-10-08 13:59:23 -07:00
-@@ -239,9 +239,10 @@
- return 0xffffffff;
- }
-
--static int read_config(u8 bus_num, u16 devfn, int where, int size, u32 *value)
-+static int ixp4xx_pci_read_config(struct pci_bus *bus, u16 devfn, int where, int size, u32 *value)
- {
- u32 n, byte_enables, addr, data;
-+ u8 bus_num = bus->number;
-
- pr_debug("read_config from %d size %d dev %d:%d:%d\n", where, size,
- bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
-@@ -261,9 +262,10 @@
- return PCIBIOS_SUCCESSFUL;
- }
-
--static int write_config(u8 bus_num, u16 devfn, int where, int size, u32 value)
-+static int ixp4xx_pci_write_config(struct pci_bus *bus, u16 devfn, int where, int size, u32 value)
- {
- u32 n, byte_enables, addr, data;
-+ u8 bus_num = bus->number;
-
- pr_debug("write_config_byte %#x to %d size %d dev %d:%d:%d\n", value, where,
- size, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn));
-@@ -281,30 +283,10 @@
- return PCIBIOS_SUCCESSFUL;
- }
-
--/*
-- * Generalized PCI config access functions.
-- */
--static int ixp4xx_read_config(struct pci_bus *bus, unsigned int devfn,
-- int where, int size, u32 *value)
--{
-- if (bus->number && !PCI_SLOT(devfn))
-- return local_read_config(where, size, value);
-- return read_config(bus->number, devfn, where, size, value);
--}
--
--static int ixp4xx_write_config(struct pci_bus *bus, unsigned int devfn,
-- int where, int size, u32 value)
--{
-- if (bus->number && !PCI_SLOT(devfn))
-- return local_write_config(where, size, value);
-- return write_config(bus->number, devfn, where, size, value);
--}
--
- struct pci_ops ixp4xx_ops = {
-- .read = ixp4xx_read_config,
-- .write = ixp4xx_write_config,
-+ .read = ixp4xx_pci_read_config,
-+ .write = ixp4xx_pci_write_config,
- };
--
-
- /*
- * PCI abort handler
-diff -Nru linux-2.6.9/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h linux-2.6.9/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h
---- linux-2.6.9/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h 2004-10-08 13:59:23 -07:00
-+++ linux-2.6.9/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h 2004-10-08 13:59:23 -07:00
-@@ -55,7 +55,7 @@
- * PCI Config registers
- */
- #define IXP4XX_PCI_CFG_BASE_PHYS (0xC0000000)
--#define IXP4XX_PCI_CFG_BASE_VIRT (0xFFBFD000)
-+#define IXP4XX_PCI_CFG_BASE_VIRT (0xFFBFE000)
- #define IXP4XX_PCI_CFG_REGION_SIZE (0x00001000)
-
- /*
---- linux-2.6.9/drivers/i2c/chips/Kconfig.orig 2004-06-16 01:19:35.000000000 -0400
-+++ linux-2.6.9/drivers/i2c/chips/Kconfig 2004-09-22 18:09:48.454794342 -0400
-@@ -240,6 +240,16 @@
- This driver can also be built as a module. If so, the module
- will be called pcf8591.
-
-+config SENSORS_X1205
-+ tristate "Xicor X1205 RTC chip"
-+ depends on I2C && EXPERIMENTAL
-+ select I2C_SENSOR
-+ help
-+ If you say yes here you get support for the Xicor x1205 RTC chip.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called x1205-rtc
-+
- config SENSORS_RTC8564
- tristate "Epson 8564 RTC chip"
- depends on I2C && EXPERIMENTA
---- linux-2.6.9/drivers/i2c/chips/Makefile.old 2004-06-16 01:20:26.000000000 -0400
-+++ linux-2.6.9/drivers/i2c/chips/Makefile 2004-09-22 16:48:06.435580334 -0400
-@@ -25,6 +25,7 @@
- obj-$(CONFIG_SENSORS_RTC8564) += rtc8564.o
- obj-$(CONFIG_SENSORS_VIA686A) += via686a.o
- obj-$(CONFIG_SENSORS_W83L785TS) += w83l785ts.o
-+obj-$(CONFIG_SENSORS_X1205) += x1205-rtc.o
- obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o
-
- ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
-
---- linux-2.6.9/arch/arm/mach-ixp4xx/common.c.orig 2004-10-18 17:54:25.000000000 -0400
-+++ linux-2.6.9/arch/arm/mach-ixp4xx/common.c 2004-10-21 14:22:40.766271419 -0400
-@@ -227,10 +227,10 @@
- /*
- * Catch up with the real idea of time
- */
-- do {
-+ while((*IXP4XX_OSTS - last_jiffy_time) > LATCH) {
- timer_tick(regs);
- last_jiffy_time += LATCH;
-- } while((*IXP4XX_OSTS - last_jiffy_time) > LATCH);
-+ };
-
- return IRQ_HANDLED;
- }
---- linux-2.6.9/include/linux/i2c-id.h.orig 2004-10-18 17:53:10.000000000 -0400
-+++ linux-2.6.9/include/linux/i2c-id.h 2004-10-21 14:14:17.115262597 -0400
-@@ -109,7 +109,7 @@
- #define I2C_DRIVERID_OVCAMCHIP 61 /* OmniVision CMOS image sens. */
- #define I2C_DRIVERID_TDA7313 62 /* TDA7313 audio processor */
- #define I2C_DRIVERID_MAX6900 63 /* MAX6900 real-time clock */
--
-+#define I2C_DRIVERID_X1205 0xF0
-
- #define I2C_DRIVERID_EXP0 0xF0 /* experimental use id's */
- #define I2C_DRIVERID_EXP1 0xF1
-diff -Nru a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
---- a/arch/arm/kernel/entry-header.S 2004-10-08 13:59:23 -07:00
-+++ b/arch/arm/kernel/entry-header.S 2004-10-08 13:59:23 -07:00
-@@ -4,8 +4,9 @@
- #include <asm/assembler.h>
- #include <asm/constants.h>
- #include <asm/errno.h>
- #include <asm/hardware.h>
- #include <asm/arch/irqs.h>
-+#include <asm/arch/entry-macro.S>
-
- #ifndef MODE_SVC
- #define MODE_SVC 0x13
-diff -Nru a/include/asm-arm/arch-ixp4xx/entry-macro.S b/include/asm-arm/arch-ixp4xx/entry-macro.S
---- /dev/null Wed Dec 31 16:00:00 1969
-+++ b/include/asm-arm/arch-ixp4xx/entry-macro.S Thu Sep 16 13:15:46 2004
-@@ -0,0 +1,25 @@
-+/*
-+ * include/asm-arm/arch-ixp4xx/entry-macro.S
-+ *
-+ * Low-level IRQ helper macros for IXP4xx-based platforms
-+ *
-+ * This file is licensed under the terms of the GNU General Public
-+ * License version 2. This program is licensed "as is" without any
-+ * warranty of any kind, whether express or implied.
-+ */
-+
-+ .macro disable_fiq
-+ .endm
-+
-+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
-+
-+ ldr \irqstat, =(IXP4XX_INTC_BASE_VIRT+IXP4XX_ICIP_OFFSET)
-+ ldr \irqstat, [\irqstat] @ get interrupts
-+ cmp \irqstat, #0
-+ beq 1001f
-+ clz \irqnr, \irqstat
-+ mov \base, #31
-+ subs \irqnr, \base, \irqnr
-+
-+1001:
-+ .endm
-
-diff -purN linux-2.6.9.orig/arch/arm/boot/compressed/head.S linux-2.6.9/arch/arm/boot/compressed/head.S
---- linux-2.6.9.orig/arch/arm/boot/compressed/head.S 2004-10-18 17:55:07.000000000 -0400
-+++ linux-2.6.9/arch/arm/boot/compressed/head.S 2004-10-31 03:05:25.011878371 -0500
-@@ -79,6 +79,7 @@
- .endm
- .macro writeb, rb
- str \rb, [r3, #0]
-+ .endm
- #elif defined(CONFIG_ARCH_IXP2000)
- .macro loadsp, rb
- mov \rb, #0xc0000000
-diff -purN linux-2.6.9.orig/arch/arm/boot/compressed/head-xscale.S linux-2.6.9/arch/arm/boot/compressed/head-xscale.S
---- linux-2.6.9.orig/arch/arm/boot/compressed/head-xscale.S 2004-10-18 17:53:45.000000000 -0400
-+++ linux-2.6.9/arch/arm/boot/compressed/head-xscale.S 2004-10-31 03:05:25.013878040 -0500
-@@ -56,3 +56,7 @@ __XScale_start:
- mov r7, #MACH_TYPE_COTULLA_IDP
- #endif
-
-+#ifdef CONFIG_ARCH_NSLU2
-+ mov r7, #(MACH_TYPE_NSLU2 & 0xff)
-+ orr r7, r7, #(MACH_TYPE_NSLU2 & 0xff00)
-+#endif
---- linux-2.6.9.orig/arch/arm/tools/mach-types 2004-10-18 17:54:08.000000000 -0400
-+++ linux-2.6.9/arch/arm/tools/mach-types 2004-10-31 03:05:25.006879199 -0500
-@@ -6,7 +6,7 @@
- # To add an entry into this database, please see Documentation/arm/README,
- # or contact rmk@arm.linux.org.uk
- #
--# Last update: Thu Sep 30 15:23:21 2004
-+# Last update: Mon Oct 25 04:14:24 2004
- #
- # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
- #
-@@ -595,8 +595,8 @@ pxa_dnp2110 MACH_PXA_DNP2110 PXA_DNP211
- xaeniax MACH_XAENIAX XAENIAX 585
- somn4250 MACH_SOMN4250 SOMN4250 586
- pleb2 MACH_PLEB2 PLEB2 587
--cwl MACH_CWL CWL 588
--gd MACH_GD GD 589
-+cornwallis MACH_CORNWALLIS CORNWALLIS 588
-+gurney_drv MACH_GURNEY_DRV GURNEY_DRV 589
- chaffee MACH_CHAFFEE CHAFFEE 590
- rms101 MACH_RMS101 RMS101 591
- rx3715 MACH_RX3715 RX3715 592
-@@ -604,7 +604,7 @@ swift MACH_SWIFT SWIFT 593
- roverp7 MACH_ROVERP7 ROVERP7 594
- pr818s MACH_PR818S PR818S 595
- trxpro MACH_TRXPRO TRXPRO 596
--nslu2 MACH_NSLU2 NSLU2 597
-+nslu2 ARCH_NSLU2 NSLU2 597
- e400 MACH_E400 E400 598
- trab MACH_TRAB TRAB 599
- cmc_pu2 MACH_CMC_PU2 CMC_PU2 600
-@@ -615,3 +615,18 @@ ixdpg425 MACH_IXDPG425 IXDPG425 604
- tomtomgo MACH_TOMTOMGO TOMTOMGO 605
- versatile_ab MACH_VERSATILE_AB VERSATILE_AB 606
- edb9307 MACH_EDB9307 EDB9307 607
-+sg565 MACH_SG565 SG565 608
-+lpd79524 MACH_LPD79524 LPD79524 609
-+lpd79525 MACH_LPD79525 LPD79525 610
-+rms100 MACH_RMS100 RMS100 611
-+kb9200 MACH_KB9200 KB9200 612
-+sx1 MACH_SX1 SX1 613
-+hms39c7092 MACH_HMS39C7092 HMS39C7092 614
-+armadillo MACH_ARMADILLO ARMADILLO 615
-+ipcu MACH_IPCU IPCU 616
-+loox720 MACH_LOOX720 LOOX720 617
-+ixdp465 MACH_IXDP465 IXDP465 618
-+ixdp2351 MACH_IXDP2351 IXDP2351 619
-+adsvix MACH_ADSVIX ADSVIX 620
-+dm270 MACH_DM270 DM270 621
-+
diff --git a/linux/openslug-kernel-2.6.9/x1205-rtc.c b/linux/openslug-kernel-2.6.9/x1205-rtc.c
deleted file mode 100644
index c194608ad6..0000000000
--- a/linux/openslug-kernel-2.6.9/x1205-rtc.c
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- x1205 - an 12c driver for the Xicor X1205 RTC
- Copyright 2004 Karen Spearel
-
- please send all reports to:
- kas11 at tampabay dot rr dot com
-
- based on linux/drivers/acron/char/pcf8583.h
- Copyright (C) 2000 Russell King
-
- 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.
-*/
-/*
-
- * i2c_adapter is the structure used to identify a physical i2c bus along
- * with the access algorithms necessary to access it.
-
-struct i2c_adapter {
- struct module *owner;
- unsigned int id; == is algo->id | hwdep.struct->id, for registered values see below
- unsigned int class;
- struct i2c_algorithm *algo; the algorithm to access the bus
- void *algo_data;
-
- --- administration stuff.
- int (*client_register)(struct i2c_client *);
- int (*client_unregister)(struct i2c_client *);
-
- data fields that are valid for all devices
- struct semaphore bus_lock;
- struct semaphore clist_lock;
-
- int timeout;
- int retries;
- struct device dev; the adapter device
- struct class_device class_dev; the class device
-
-#ifdef CONFIG_PROC_FS
- No need to set this when you initialize the adapter
- int inode;
-#endif def CONFIG_PROC_FS
-
- int nr;
- struct list_head clients;
- struct list_head list;
- char name[I2C_NAME_SIZE];
- struct completion dev_released;
- struct completion class_dev_released;
-};
-*/
-
-
-/*========== Driver for the X1205 on the Linksys NSLU2 ==================*/
-
-#include <linux/init.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/bcd.h>
-#include <linux/rtc.h>
-#include <linux/fs.h>
-#include <linux/proc_fs.h>
-#include <linux/miscdevice.h>
-#include <linux/device.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <linux/moduleparam.h>
-
-#define RTC_GETDATETIME 0
-#define RTC_SETTIME 1
-#define RTC_SETDATETIME 2
-
-#define I2C_M_WR 0 // just for consistancy
-
-// offsets into read buf - add 2 for write buf
-#define CCR_SEC 0
-#define CCR_MIN 1
-#define CCR_HOUR 2
-#define CCR_MDAY 3
-#define CCR_MONTH 4
-#define CCR_YEAR 5
-#define CCR_WDAY 6
-#define CCR_Y2K 7
-
-#define X1205_I2C_BUS_ADDR 0x6f // hardwired into x1205
-#define X1205_ALM0_BASE 0x00 // Base address of the ALM0
-#define X1205_CCR_BASE 0x30 // Base address of the CCR
-#define X1205_SR_ADDR 0x3f // Status Register
-#define X1205_SR_WEL 0x02 // Write Enable Latch bit
-#define X1205_SR_RWEL 0x04 // Register Write Enable Bit
-#define X1205_MILBIT 0x80 // this bit set in ccr.hour for 24 hr mode
-#define NOERR 0
-#define RTC_NODATE 0
-#define RTC_DATETOO 1
-
-// comment out next line is your x1205 can't do page writes
-//#define X1205PAGEWRITE 1
-#ifdef X1205PAGEWRITE
-#define DRIVERNAME "Xicor x1205 RTC Driver v0.9.3.3"
-#else
-#define DRIVERNAME "Xicor x1205 RTC Dvr v0.9.3.3NPW"
-#endif
-
-#define DEBUG KERN_DEBUG
-
-
-static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm, u8 reg_base);
-static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, int datetoo, u8 reg_base);
-static int x1205_attach(struct i2c_adapter *adapter);
-static int x1205_detach(struct i2c_client *client);
-static int x1205_validate_tm(struct rtc_time *tm);
-static int x1205_command(struct i2c_client *client, unsigned int cmd, void *arg);
-static int x1205_sync_rtc(void);
-static int x1205_read(struct file *file, char *buf, size_t count, loff_t *ptr);
-static int x1205_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
-static int x1205_read_proc(char *buf, char **start, off_t off, int len, int *eof, void *data);
-
-static struct i2c_driver x1205_driver = {
- .owner = THIS_MODULE,
- .name = DRIVERNAME,
- .id = I2C_DRIVERID_X1205,
- .flags = I2C_DF_NOTIFY,
- .attach_adapter = &x1205_attach, //we don't need to probe...x1205 is hardwired @ 0x6f
- .detach_client = &x1205_detach,
- .command = &x1205_command, //this prolly never gets called...used internally tho
-};
-
-static struct i2c_client x1205_i2c_client = {
- .id = I2C_DRIVERID_X1205,
- .flags = 0,
- .addr = X1205_I2C_BUS_ADDR, // chip address - NOTE: 7bit
- .adapter = NULL, // the adapter we sit on assigned in attach
- .driver = &x1205_driver, // and our access routines
- .usage_count = 0, // How many accesses currently to this client
- .dev = {}, // the device structure
- .list = {},
- .name = DRIVERNAME,
- .released = {},
-};
-
-static struct file_operations rtc_fops = {
- owner: THIS_MODULE,
- ioctl: x1205_ioctl,
- read: x1205_read,
-};
-
-static struct miscdevice x1205_miscdev = {
- .minor = RTC_MINOR,
- .name = "rtc",
- .fops = &rtc_fops,
-};
-extern int (*set_rtc)(void);
-static unsigned epoch = 1900; //coresponds to year 0
-static unsigned rtc_epoch = 2000;
-static const unsigned char days_in_mo[] =
-{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
-
-//===================================CODE======================================
-// in the routines that deal directly with the x1205 hardware, we use
-// rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch
-// Epoch is inited as 2000. Time is set to UT
-//=============================================================================
-static int x1205_get_datetime(struct i2c_client *client, struct rtc_time *tm, u8 reg_base)
-{
- static unsigned char addr[2] = { 0,} ;
- unsigned char buf[8];
- struct i2c_msg msgs[2] = {
- { client->addr, I2C_M_WR, 2, addr }, //msg 1 = send base address
- { client->addr, I2C_M_RD, 8, buf }, //msg 2 = read sequential data
- };
- addr[1] = reg_base;
- if ((i2c_transfer(client->adapter, msgs, 2)) == 2) { //did we read 2 messages?
- printk(KERN_DEBUG "raw x1205 read data - sec-%02x min-%02x hr-%02x mday-%02x mon-%02x year-%02x wday-%02x y2k-%02x\n",
- buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6], buf[7]);
- tm->tm_sec = BCD2BIN(buf[CCR_SEC]);
- tm->tm_min = BCD2BIN(buf[CCR_MIN]);
- buf[CCR_HOUR] &= ~X1205_MILBIT;
- tm->tm_hour = BCD2BIN(buf[CCR_HOUR]); //hr is 0-23
- tm->tm_mday = BCD2BIN(buf[CCR_MDAY]);
- tm->tm_mon = BCD2BIN(buf[CCR_MONTH]);
- rtc_epoch = BCD2BIN(buf[CCR_Y2K]) * 100;
- tm->tm_year = BCD2BIN(buf[CCR_YEAR]) + rtc_epoch - epoch;
- tm->tm_wday = buf[CCR_WDAY];
- printk(KERN_DEBUG "rtc_time output data - sec-%02d min-%02d hr-%02d mday-%02d mon-%02d year-%02d wday-%02d epoch-%d rtc_epoch-%d\n",
- tm->tm_sec,tm->tm_min,tm->tm_hour,tm->tm_mday,tm->tm_mon,tm->tm_year,tm->tm_wday,epoch, rtc_epoch);
- } else {
- printk(KERN_DEBUG "i2c_transfer Read Error\n");
- return -EIO;
- }
-
- return NOERR;
-}
-// x1205pagewrite allows writing a block of registers in msg3 even though the x1205 says
-// nothing about this in its spec.
-// it needs more testing as it is possible some x1205s are actually not-completely-
-// functional x1226s and there is a reason for the multiple write to not be in the spec.
-// anyhow, it is enabled for the time being...and we even push out luck by sending 10 bytes
-
-static int x1205_set_datetime(struct i2c_client *client, struct rtc_time *tm, int datetoo, u8 reg_base)
-{
- static unsigned char wel[3] = { 0, X1205_SR_ADDR, X1205_SR_WEL };
- static unsigned char rwel[3] = { 0, X1205_SR_ADDR, X1205_SR_WEL | X1205_SR_RWEL };
- static unsigned char diswe[3] = { 0, X1205_SR_ADDR, 0 };
-
-#ifdef X1205PAGEWRITE
-
- static unsigned char buf[10] = { 0, X1205_CCR_BASE, };
- struct i2c_msg msgs[4] = {
- { client->addr, I2C_M_WR, 3, wel }, //msg 1 = write WEL to to ccr sr
- { client->addr, I2C_M_WR, 3, rwel }, //msg 2 = write RWEL to ccr sr
- { client->addr, I2C_M_WR, 10, buf }, //msg 3 = write ccr base addr +seq data
- { client->addr, I2C_M_WR, 3, diswe }, //msg 4 = 0 to ccr sr to disable writes
- };
-
- msgs[2].len = 5; // 5 bytes + addr to set time only
- buf [1] = reg_base;
- buf[CCR_SEC+2] = BIN2BCD(tm->tm_sec);
- buf[CCR_MIN+2] = BIN2BCD(tm->tm_min);
- buf[CCR_HOUR+2] = BIN2BCD(tm->tm_hour) | X1205_MILBIT; // set 24 hour format
- if (datetoo == 1) {
- buf[CCR_MDAY+2] = BIN2BCD(tm->tm_mday);
- buf[CCR_MONTH+2] = BIN2BCD(tm->tm_mon); // input is 0-11
- buf[CCR_YEAR+2] = BIN2BCD((tm->tm_year + epoch - rtc_epoch)); // input is yrs since 1900
- buf[CCR_WDAY+2] = tm->tm_wday & 7;
- buf[CCR_Y2K+2] = BIN2BCD((rtc_epoch/100));
- msgs[2].len += 5; //5 more bytes to set date
- }
- printk(KERN_DEBUG "rtc_time input - sec-%02d min-%02d hour-%02d mday-%02d mon-%02d year-%02d wday-%02d epoch-%d rtc_epoch-%d\n",
- tm->tm_sec,tm->tm_min,tm->tm_hour,tm->tm_mday,tm->tm_mon,tm->tm_year,tm->tm_wday, epoch, rtc_epoch);
- printk(KERN_DEBUG "BCD write data - sec-%02x min-%02x hour-%02x mday-%02x mon-%02x year-%02x wday-%02x y2k-%02x\n",
- buf[2],buf[3],buf[4],buf[5],buf[6], buf[7], buf[8], buf[9]);
-
- if ((i2c_transfer(client->adapter, msgs, 4)) != 4)
- return -EIO;
- return NOERR;
-
-#else //do this if page writes aren't working
-
- int i,xfer;
- static unsigned char data[3] = { 0,};
- static unsigned char buf[8];
-
- buf[CCR_SEC] = BIN2BCD(tm->tm_sec);
- buf[CCR_MIN] = BIN2BCD(tm->tm_min);
- buf[CCR_HOUR] = BIN2BCD(tm->tm_hour) | X1205_MILBIT; // set 24 hour format
- if (datetoo == 1) {
- buf[CCR_MDAY] = BIN2BCD(tm->tm_mday);
- buf[CCR_MONTH] = BIN2BCD(tm->tm_mon); // input is 0-11
- buf[CCR_YEAR] = BIN2BCD((tm->tm_year + epoch - rtc_epoch)); // input is yrs since 1900
- buf[CCR_WDAY] = tm->tm_wday & 7;
- buf[CCR_Y2K] = BIN2BCD((rtc_epoch/100));
- }
- printk(KERN_DEBUG "rtc_time input - sec-%02d min-%02d hour-%02d mday-%02d mon-%02d year-%02d wday-%02d epoch-%d rtc_epoch-%d\n",
- tm->tm_sec,tm->tm_min,tm->tm_hour,tm->tm_mday,tm->tm_mon,tm->tm_year,tm->tm_wday, epoch, rtc_epoch);
-
- xfer = i2c_master_send(client, wel, 3);
- printk(KERN_DEBUG "wen - %x\n", xfer);
- if (xfer != 3)
- return -EIO;
-
- xfer = i2c_master_send(client, rwel, 3);
- printk(KERN_DEBUG "wenb - %x\n", xfer);
- if (xfer != 3)
- return -EIO;
-
- for (i = 0; i < 8; i++) {
- data[1] = i + reg_base;
- data[2] = buf[i];
- xfer = i2c_master_send(client, data, 3);
- printk(KERN_DEBUG "xfer - %d addr - %02x data - %02x\n", xfer, data[1], data[2]);
- if (xfer != 3)
- return -EIO;
- };
-
- xfer = i2c_master_send(client, diswe, 3);
- printk(KERN_DEBUG "wdis - %x\n", xfer);
- if (xfer != 3)
- return -EIO;
- return NOERR;
-#endif
-}
-//=============================================================================
-
-static int x1205_attach(struct i2c_adapter *adapter)
-{
- struct rtc_time tm;
- struct timespec tv;
- int errno;
-
- x1205_i2c_client.adapter = adapter;
- x1205_i2c_client.id++;
-
- if ((x1205_get_datetime(&x1205_i2c_client, &tm, X1205_CCR_BASE)) != NOERR) //test for functional driver
- return -EIO;
-
- if ((errno = i2c_attach_client(&x1205_i2c_client)) != NOERR)
- return errno;
-
- tv.tv_nsec = tm.tm_sec * 10000000;
- tv.tv_sec = mktime(tm.tm_year+epoch, tm.tm_mon+1, tm.tm_mday, tm.tm_hour,
- tm.tm_min, tm.tm_sec);
- do_settimeofday(&tv);
- set_rtc = x1205_sync_rtc;
-
- printk(KERN_DEBUG "%s attached on adapter %s\n",x1205_i2c_client.name,
- x1205_i2c_client.adapter->name); //why is this name a null string?
-
- return NOERR;
-}
-
-static int x1205_detach(struct i2c_client *client)
-{
- int errno;
-
- if ((errno = i2c_detach_client(client)) != 0) {
- printk(KERN_DEBUG "i2c_detach failed - errno = %d\n", errno);
- return errno;
- }
-
- return NOERR;
-}
-
-// make sure the rtc_time values are in bounds
-static int x1205_validate_tm(struct rtc_time *tm)
-{
- tm->tm_year += 1900;
-
- if (tm->tm_year < 1970)
- return -EINVAL;
-
- if ((tm->tm_mon > 11) || (tm->tm_mday == 0))
- return -EINVAL;
-
- if (tm->tm_mday > (days_in_mo[tm->tm_mon] + ( (tm->tm_mon == 1) &&
- ((!(tm->tm_year % 4) && (tm->tm_year % 100) ) || !(tm->tm_year % 400)))))
- return -EINVAL;
-
- if ((tm->tm_year -= epoch) > 255)
- return -EINVAL;
-
- if ((tm->tm_hour >= 24) || (tm->tm_min >= 60) || (tm->tm_sec >= 60))
- return -EINVAL;
- return NOERR;
-}
-
-static int x1205_command(struct i2c_client *client, unsigned int cmd, void *tm)
-{
- int errno, dodate = RTC_DATETOO;
-
- if (client == NULL || tm == NULL)
- return -EINVAL;
- if (!capable(CAP_SYS_TIME))
- return -EACCES;
-
- printk(KERN_DEBUG "x1205_command %d\n", cmd);
-
- switch (cmd) {
- case RTC_GETDATETIME:
- return x1205_get_datetime(client, tm, X1205_CCR_BASE);
-
- case RTC_SETTIME: // note fall thru
- dodate = RTC_NODATE;
- case RTC_SETDATETIME:
- if ((errno = x1205_validate_tm(tm)) < NOERR)
- return errno;
- return x1205_set_datetime(client, tm, dodate, X1205_CCR_BASE);
-
- default:
- return -EINVAL;
- }
-}
-
-static int x1205_sync_rtc(void)
-{
- struct rtc_time new_tm, old_tm;
- unsigned long cur_secs = xtime.tv_sec;
-
- printk(KERN_DEBUG "x1205_sync_rtc entry\n");
-
- if (x1205_command(&x1205_i2c_client, RTC_GETDATETIME, &old_tm))
- return 0;
-
-// xtime.tv_nsec = old_tm.tm_sec * 10000000; //FIXME:
- new_tm.tm_sec = cur_secs % 60;
- cur_secs /= 60;
- new_tm.tm_min = cur_secs % 60;
- cur_secs /= 60;
- new_tm.tm_hour = cur_secs % 24;
-
- /*
- * avoid writing when we're going to change the day
- * of the month. We will retry in the next minute.
- * This basically means that if the RTC must not drift
- * by more than 1 minute in 11 minutes.
- */
- if ((old_tm.tm_hour == 23 && old_tm.tm_min == 59) ||
- (new_tm.tm_hour == 23 && new_tm.tm_min == 59))
- return 1;
- printk(KERN_DEBUG "x1205_sync_rtc exit\n");
-
- return x1205_command(&x1205_i2c_client, RTC_SETTIME, &new_tm);
-}
-
-static int x1205_read(struct file *file, char *buf, size_t count, loff_t *ptr)
-{
- struct rtc_time tm;
-
- if ((x1205_get_datetime(&x1205_i2c_client, &tm, X1205_CCR_BASE)) < NOERR)
- return -EIO;
- return copy_to_user(buf, &tm, sizeof(tm)) ? -EFAULT : NOERR;
-}
-
-//==============================================================================
-
-static int x1205_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
- unsigned long arg)
-{
- struct rtc_time tm;
- int errno;
-
- printk(KERN_DEBUG "ioctl = %x\n", cmd);
-
- switch (cmd) {
- case RTC_RD_TIME:
- if ((x1205_get_datetime(&x1205_i2c_client, &tm, X1205_CCR_BASE)) < NOERR)
- return -EIO;
- break;
-
- case RTC_SET_TIME:
- if (!capable(CAP_SYS_TIME))
- return -EACCES;
-
- if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(struct rtc_time)))
- return -EFAULT;
- if ((errno = x1205_validate_tm(&tm)) < NOERR)
- return errno;
- return x1205_set_datetime(&x1205_i2c_client, &tm, RTC_DATETOO, X1205_CCR_BASE);
-
- case RTC_ALM_SET: //FIXME: set Control Regs
- if (copy_from_user(&tm, (struct rtc_time *) arg, sizeof(struct rtc_time)))
- return -EFAULT;
- return x1205_set_datetime(&x1205_i2c_client, &tm, RTC_DATETOO, X1205_ALM0_BASE);
-
- case RTC_ALM_READ:
- if ((x1205_get_datetime(&x1205_i2c_client, &tm, X1205_ALM0_BASE)) < NOERR)
- return -EIO;
- break;
-
- case RTC_EPOCH_READ:
-
- return put_user (epoch, (unsigned long __user *)arg);
-
- case RTC_EPOCH_SET:
- if (arg < 1900)
- return -EINVAL;
-
- if (!capable(CAP_SYS_TIME))
- return -EACCES;
-
- epoch = arg;
- return 0;
-
- default:
- return -ENOTTY;
- }
- return copy_to_user((void __user *)arg, &tm, sizeof tm) ? -EFAULT : 0;
-
-}
-
-static int x1205_read_proc(char *buf, char **start, off_t off, int len, int *eof, void *data)
-{
- struct rtc_time tm;
- int slen, errno;
-
- if ((errno = x1205_get_datetime(&x1205_i2c_client, &tm, X1205_CCR_BASE)) < NOERR)
- return errno;
-
-// here we return the real year and the month as 1-12 since it is human-readable
- slen = sprintf(buf, "rtc_time\t: %02d:%02d:%02d\nrtc_date\t: %04d-%02d-%02d\n",
- tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year + 1900, tm.tm_mon+1, tm.tm_mday);
- printk(KERN_DEBUG "raw rtc_time\t: %02d:%02d:%02d\nraw rtc_date\t: %04d-%02d-%02d\n",
- tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year, tm.tm_mon, tm.tm_mday);
-
- if (slen <= off + len)
- *eof = 1;
- *start = buf + off;
- slen -= off;
- if (slen > len)
- slen = len;
- if ( slen < 0 )
- slen = 0;
-
- return slen;
-}
-
-static int __init x1205_init(void)
-{
- struct rtc_time tm;
- int errno;
- printk(KERN_INFO "LOADED %s\n", DRIVERNAME);
-
- if ((errno = i2c_add_driver(&x1205_driver)) != NOERR) {
- dev_dbg(x1205_i2c_client.dev, "x1205_init failed - errno = %d\n", errno);
- return (errno);
- }
- if ((errno = misc_register(&x1205_miscdev)) != NOERR) {
- dev_dbg(x1205_i2c_client.dev, "Register Misc Driver failed - errno = %d\n", errno);
- i2c_del_driver(&x1205_driver);
- return errno;
- }
- if (create_proc_read_entry("driver/rtc", 0, NULL, x1205_read_proc, NULL) < NOERR)
- return -ENOMEM;
- if ((x1205_get_datetime(&x1205_i2c_client, &tm, X1205_CCR_BASE)) != NOERR) //test for functionality
- return -EIO;
-
- return NOERR;
-}
-
-static void __exit x1205_exit(void)
-{
- remove_proc_entry("driver/rtc", NULL);
- misc_deregister(&x1205_miscdev);
- i2c_del_driver(&x1205_driver);
- set_rtc = NULL;
-}
-
-MODULE_AUTHOR("Karen Spearel <kas11@tampabay.rr.com>");
-MODULE_DESCRIPTION("Xicor X1205-RTC Driver");
-MODULE_LICENSE("GPL");
-static int debug = 7;
-module_param(debug, bool, 0644);
-MODULE_PARM_DESC(debug, "Debugging enabled = 1");
-
-module_init(x1205_init);
-module_exit(x1205_exit);
diff --git a/linux/openslug-kernel_2.6.7.bb b/linux/openslug-kernel_2.6.7.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/openslug-kernel_2.6.7.bb
+++ /dev/null
diff --git a/linux/openslug-kernel_2.6.9.bb b/linux/openslug-kernel_2.6.9.bb
deleted file mode 100644
index 0e48638e5b..0000000000
--- a/linux/openslug-kernel_2.6.9.bb
+++ /dev/null
@@ -1,58 +0,0 @@
-SECTION = "kernel"
-DESCRIPTION = "Linux kernel for the Linksys NSLU2 device"
-LICENSE = "GPL"
-MAINTAINER = "Chris Larson <kergoth@handhelds.org>"
-PR = "r1"
-
-KERNEL_SUFFIX = "openslug"
-
-SRC_URI = "ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.9.tar.bz2 \
- file://nslu2_2.6.9.patch;patch=1 \
- file://defconfig \
- file://x1205-rtc.c \
- file://nslu2-io.c \
- file://nslu2-setup.c \
- file://nslu2-pci.c \
- file://nslu2-part.c \
- file://nslu2.h"
-S = "${WORKDIR}/linux-2.6.9"
-
-COMPATIBLE_HOST = 'arm.*-linux'
-
-inherit kernel
-
-ARCH = "arm"
-KERNEL_IMAGETYPE = "zImage"
-CMDLINE_CONSOLE ?= "ttyS0,115200n8"
-CMDLINE_ROOT = "root=/dev/slug rootfstype=ext2,jffs2 initrd=0x01000000,10M mem=32M@0x00000000"
-CMDLINE = "${CMDLINE_ROOT} ${CMDLINE_CONSOLE}"
-
-do_configure_prepend() {
- install -m 0644 ${WORKDIR}/defconfig ${S}/.config
- install -m 0644 ${WORKDIR}/x1205-rtc.c ${S}/drivers/i2c/chips/x1205-rtc.c
- install -m 0644 ${WORKDIR}/nslu2-io.c ${S}/arch/arm/mach-ixp4xx/nslu2-io.c
- install -m 0644 ${WORKDIR}/nslu2-setup.c ${S}/arch/arm/mach-ixp4xx/nslu2-setup.c
- install -m 0644 ${WORKDIR}/nslu2-pci.c ${S}/arch/arm/mach-ixp4xx/nslu2-pci.c
- install -m 0644 ${WORKDIR}/nslu2-part.c ${S}/arch/arm/mach-ixp4xx/nslu2-part.c
- install -m 0644 ${WORKDIR}/nslu2.h ${S}/include/asm-arm/arch-ixp4xx/nslu2.h
- echo "CONFIG_CMDLINE=\"${CMDLINE}\"" >> ${S}/.config
- rm -rf ${S}/include/asm-arm/arch ${S}/include/asm-arm/proc \
- ${S}/include/asm-arm/.proc ${S}/include/asm-arm/.arch
-}
-
-do_deploy() {
- install -d ${DEPLOY_DIR}/images
- install -m 0644 arch/${ARCH}/boot/${KERNEL_IMAGETYPE} ${DEPLOY_DIR}/images/${KERNEL_IMAGETYPE}-${KERNEL_SUFFIX}
-}
-
-do_deploy[dirs] = "${S}"
-
-addtask deploy before do_build after do_compile
-
-python () {
- # Don't build openslug kernel unless we're targeting an nslu2
- mach = bb.data.getVar("MACHINE", d, 1)
- dist = bb.data.getVar("DISTRO", d, 1)
- if mach != 'nslu2' or dist != 'openslug':
- raise bb.parse.SkipPackage("OpenSlug only builds for the Linksys NSLU2")
-}
diff --git a/linux/openzaurus-2.6.10-rc2/defconfig-collie b/linux/openzaurus-2.6.10-rc2/defconfig-collie
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/openzaurus-2.6.10-rc2/defconfig-collie
+++ /dev/null
diff --git a/linux/openzaurus-2.6.10-rc2/defconfig-husky b/linux/openzaurus-2.6.10-rc2/defconfig-husky
deleted file mode 100644
index 87080ed659..0000000000
--- a/linux/openzaurus-2.6.10-rc2/defconfig-husky
+++ /dev/null
@@ -1,893 +0,0 @@
-#
-# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc2
-# Tue Nov 23 22:25:04 2004
-#
-CONFIG_ARM=y
-CONFIG_MMU=y
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-CONFIG_GENERIC_IOMAP=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
-CONFIG_BROKEN_ON_SMP=y
-CONFIG_LOCK_KERNEL=y
-
-#
-# General setup
-#
-CONFIG_LOCALVERSION=""
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-# CONFIG_POSIX_MQUEUE is not set
-CONFIG_BSD_PROCESS_ACCT=y
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-CONFIG_SYSCTL=y
-# CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_HOTPLUG=y
-CONFIG_KOBJECT_UEVENT=y
-# CONFIG_IKCONFIG is not set
-CONFIG_EMBEDDED=y
-CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-CONFIG_FUTEX=y
-CONFIG_EPOLL=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
-# CONFIG_TINY_SHMEM is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
-CONFIG_MODVERSIONS=y
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_L7200 is not set
-CONFIG_ARCH_PXA=y
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_IMX is not set
-# CONFIG_ARCH_H720X is not set
-
-#
-# Intel PXA2xx Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_MACH_MAINSTONE is not set
-# CONFIG_ARCH_PXA_IDP is not set
-# CONFIG_MACH_POODLE is not set
-# CONFIG_MACH_CORGI is not set
-# CONFIG_MACH_SHEPHERD is not set
-CONFIG_MACH_HUSKY=y
-CONFIG_PXA_SHARPSL=y
-# CONFIG_SHARP_LOCOMO is not set
-CONFIG_PXA25x=y
-
-#
-# Processor Type
-#
-CONFIG_CPU_32=y
-CONFIG_CPU_XSCALE=y
-CONFIG_CPU_32v5=y
-CONFIG_CPU_ABRT_EV5T=y
-CONFIG_CPU_CACHE_VIVT=y
-CONFIG_CPU_TLB_V4WBI=y
-CONFIG_CPU_MINICACHE=y
-
-#
-# Processor Features
-#
-CONFIG_ARM_THUMB=y
-CONFIG_XSCALE_PMU=y
-
-#
-# General setup
-#
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-# CONFIG_XIP_KERNEL is not set
-
-#
-# PCCARD (PCMCIA/CardBus) support
-#
-CONFIG_PCCARD=y
-# CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_OBSOLETE is not set
-CONFIG_PCMCIA=y
-
-#
-# PC-card bridges
-#
-# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_PXA2XX is not set
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_AOUT=m
-CONFIG_BINFMT_MISC=m
-
-#
-# Generic Driver Options
-#
-CONFIG_STANDALONE=y
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_FW_LOADER=m
-# CONFIG_DEBUG_DRIVER is not set
-CONFIG_PM=y
-CONFIG_PREEMPT=y
-CONFIG_APM=y
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="console=ttyS0,115200n8 console=tty0 noinitrd root=/dev/mtdblock2 rootfstype=jffs2 mtdparts=sharpsl-nand:7168k@0k(smf),54272k@7168k(root),-(home) mem=64M"
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-# CONFIG_MTD_CFI is not set
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-# CONFIG_MTD_RAM is not set
-CONFIG_MTD_ROM=y
-# CONFIG_MTD_ABSENT is not set
-
-#
-# Mapping drivers for chip access
-#
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-CONFIG_MTD_SHARP_SL=y
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-
-#
-# NAND Flash Device Drivers
-#
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
-# CONFIG_MTD_NAND_H1900 is not set
-CONFIG_MTD_NAND_IDS=y
-# CONFIG_MTD_NAND_DISKONCHIP is not set
-CONFIG_MTD_NAND_SHARPSL=y
-
-#
-# Plug and Play support
-#
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE=""
-# CONFIG_CDROM_PKTCDVD is not set
-
-#
-# IO Schedulers
-#
-CONFIG_IOSCHED_NOOP=y
-CONFIG_IOSCHED_AS=y
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_CFQ=y
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-
-#
-# Networking support
-#
-CONFIG_NET=y
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-# CONFIG_NETLINK_DEV is not set
-CONFIG_UNIX=y
-# CONFIG_NET_KEY is not set
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_ARPD is not set
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_AH is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_TUNNEL is not set
-CONFIG_IP_TCPDIAG=y
-# CONFIG_IP_TCPDIAG_IPV6 is not set
-# CONFIG_IPV6 is not set
-# CONFIG_NETFILTER is not set
-
-#
-# SCTP Configuration (EXPERIMENTAL)
-#
-# CONFIG_IP_SCTP is not set
-# CONFIG_ATM is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_DECNET is not set
-# CONFIG_LLC2 is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_NET_CLS_ROUTE is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_HAMRADIO is not set
-# CONFIG_IRDA is not set
-# CONFIG_BT is not set
-CONFIG_NETDEVICES=y
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
-# CONFIG_SMC91X is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-
-#
-# Ethernet (10000 Mbit)
-#
-
-#
-# Token Ring devices
-#
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-
-#
-# Obsolete Wireless cards support (pre-802.11)
-#
-# CONFIG_STRIP is not set
-# CONFIG_PCMCIA_WAVELAN is not set
-# CONFIG_PCMCIA_NETWAVE is not set
-
-#
-# Wireless 802.11 Frequency Hopping cards support
-#
-# CONFIG_PCMCIA_RAYCS is not set
-
-#
-# Wireless 802.11b ISA/PCI cards support
-#
-# CONFIG_HERMES is not set
-# CONFIG_ATMEL is not set
-
-#
-# Wireless 802.11b Pcmcia/Cardbus cards support
-#
-# CONFIG_AIRO_CS is not set
-# CONFIG_PCMCIA_WL3501 is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-# CONFIG_PCMCIA_3C589 is not set
-# CONFIG_PCMCIA_3C574 is not set
-# CONFIG_PCMCIA_FMVJ18X is not set
-CONFIG_PCMCIA_PCNET=y
-# CONFIG_PCMCIA_NMCLAN is not set
-# CONFIG_PCMCIA_SMC91C92 is not set
-# CONFIG_PCMCIA_XIRC2PS is not set
-# CONFIG_PCMCIA_AXNET is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-CONFIG_PPP=y
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=y
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-CONFIG_PPP_BSDCOMP=y
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-# CONFIG_SHAPER is not set
-# CONFIG_NETCONSOLE is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-CONFIG_IDE=y
-# CONFIG_BLK_DEV_IDE is not set
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI device support
-#
-# CONFIG_SCSI is not set
-
-#
-# Fusion MPT device support
-#
-
-#
-# IEEE 1394 (FireWire) support
-#
-
-#
-# I2O device support
-#
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input device support
-#
-CONFIG_INPUT=y
-
-#
-# Userland interfaces
-#
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-CONFIG_INPUT_TSDEV=y
-CONFIG_INPUT_TSDEV_SCREEN_X=640
-CONFIG_INPUT_TSDEV_SCREEN_Y=480
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_EVBUG=y
-
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-CONFIG_SERIO=y
-# CONFIG_SERIO_SERPORT is not set
-# CONFIG_SERIO_CT82C710 is not set
-# CONFIG_SERIO_RAW is not set
-
-#
-# Input Device Drivers
-#
-CONFIG_INPUT_KEYBOARD=y
-# CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-CONFIG_KEYBOARD_CORGI=y
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_JOYSTICK is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_INPUT_MISC is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_HW_CONSOLE=y
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_8250 is not set
-
-#
-# Non-8250 serial port support
-#
-CONFIG_SERIAL_PXA=y
-CONFIG_SERIAL_PXA_CONSOLE=y
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS is not set
-
-#
-# IPMI
-#
-# CONFIG_IPMI_HANDLER is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-# CONFIG_SYNCLINK_CS is not set
-# CONFIG_RAW_DRIVER is not set
-
-#
-# I2C support
-#
-CONFIG_I2C=m
-# CONFIG_I2C_CHARDEV is not set
-
-#
-# I2C Algorithms
-#
-CONFIG_I2C_ALGOBIT=m
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALGOPCA is not set
-
-#
-# I2C Hardware Bus support
-#
-CONFIG_I2C_ISA=m
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_PCA_ISA is not set
-
-#
-# Hardware Sensors Chip support
-#
-# CONFIG_I2C_SENSOR is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_FSCHER is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83627HF is not set
-
-#
-# Other I2C Chip support
-#
-# CONFIG_SENSORS_EEPROM is not set
-# CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CHIP is not set
-
-#
-# Multimedia devices
-#
-CONFIG_VIDEO_DEV=m
-
-#
-# Video For Linux
-#
-
-#
-# Video Adapters
-#
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_VIDEO_SAA5246A is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_TUNER_3036 is not set
-# CONFIG_VIDEO_OVCAMCHIP is not set
-
-#
-# Radio Adapters
-#
-# CONFIG_RADIO_MAESTRO is not set
-
-#
-# Digital Video Broadcasting Devices
-#
-# CONFIG_DVB is not set
-
-#
-# File systems
-#
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-CONFIG_FS_MBCACHE=y
-# CONFIG_REISERFS_FS is not set
-# CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
-# CONFIG_XFS_FS is not set
-# CONFIG_MINIX_FS is not set
-CONFIG_ROMFS_FS=y
-# CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-
-#
-# CD-ROM/DVD Filesystems
-#
-# CONFIG_ISO9660_FS is not set
-# CONFIG_UDF_FS is not set
-
-#
-# DOS/FAT/NT Filesystems
-#
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_NTFS_FS is not set
-
-#
-# Pseudo filesystems
-#
-CONFIG_PROC_FS=y
-CONFIG_SYSFS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVPTS_FS_XATTR is not set
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_XATTR is not set
-# CONFIG_HUGETLB_PAGE is not set
-CONFIG_RAMFS=y
-
-#
-# Miscellaneous filesystems
-#
-# CONFIG_ADFS_FS is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_NAND=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_ZLIB=y
-CONFIG_JFFS2_RTIME=y
-CONFIG_JFFS2_RUBIN=y
-# CONFIG_JFFS2_CMODE_NONE is not set
-CONFIG_JFFS2_CMODE_PRIORITY=y
-# CONFIG_JFFS2_CMODE_SIZE is not set
-CONFIG_CRAMFS=y
-# CONFIG_VXFS_FS is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_SYSV_FS is not set
-# CONFIG_UFS_FS is not set
-
-#
-# Network File Systems
-#
-# CONFIG_NFS_FS is not set
-# CONFIG_NFSD is not set
-# CONFIG_EXPORTFS is not set
-CONFIG_SMB_FS=y
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_CIFS is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_AFS_FS is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_EFI_PARTITION is not set
-
-#
-# Native Language Support
-#
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="cp437"
-CONFIG_NLS_CODEPAGE_437=m
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
-CONFIG_NLS_ISO8859_1=m
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-CONFIG_NLS_UTF8=m
-
-#
-# Profiling support
-#
-# CONFIG_PROFILING is not set
-
-#
-# Graphics support
-#
-CONFIG_FB=y
-# CONFIG_FB_MODE_HELPERS is not set
-# CONFIG_FB_TILEBLITTING is not set
-# CONFIG_FB_PXA is not set
-CONFIG_FB_W100=y
-# CONFIG_FB_VIRTUAL is not set
-
-#
-# Console display driver support
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-# CONFIG_FONT_MINI_4x6 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-
-#
-# Logo configuration
-#
-# CONFIG_LOGO is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# Misc devices
-#
-
-#
-# USB support
-#
-# CONFIG_USB is not set
-CONFIG_USB_ARCH_HAS_HCD=y
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-
-#
-# USB Gadget Support
-#
-CONFIG_USB_GADGET=y
-# CONFIG_USB_GADGET_DEBUG_FILES is not set
-# CONFIG_USB_GADGET_NET2280 is not set
-CONFIG_USB_GADGET_PXA2XX=y
-CONFIG_USB_PXA2XX=y
-# CONFIG_USB_GADGET_GOKU is not set
-# CONFIG_USB_GADGET_SA1100 is not set
-# CONFIG_USB_GADGET_LH7A40X is not set
-# CONFIG_USB_GADGET_DUMMY_HCD is not set
-# CONFIG_USB_GADGET_OMAP is not set
-# CONFIG_USB_GADGET_DUALSPEED is not set
-# CONFIG_USB_ZERO is not set
-# CONFIG_USB_ETH is not set
-# CONFIG_USB_GADGETFS is not set
-# CONFIG_USB_FILE_STORAGE is not set
-# CONFIG_USB_G_SERIAL is not set
-
-#
-# MMC/SD Card support
-#
-CONFIG_MMC=y
-# CONFIG_MMC_DEBUG is not set
-CONFIG_MMC_BLOCK=y
-CONFIG_MMC_PXA=y
-
-#
-# Kernel hacking
-#
-CONFIG_DEBUG_KERNEL=y
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_KOBJECT is not set
-CONFIG_DEBUG_BUGVERBOSE=y
-# CONFIG_DEBUG_INFO is not set
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_WAITQ is not set
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_LL=y
-# CONFIG_DEBUG_ICEDCC is not set
-
-#
-# Security options
-#
-# CONFIG_KEYS is not set
-# CONFIG_SECURITY is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Library routines
-#
-CONFIG_CRC_CCITT=y
-CONFIG_CRC32=y
-# CONFIG_LIBCRC32C is not set
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/openzaurus-2.6.10-rc2/defconfig-poodle b/linux/openzaurus-2.6.10-rc2/defconfig-poodle
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/openzaurus-2.6.10-rc2/defconfig-poodle
+++ /dev/null
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/1764-1.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/1764-1.patch
deleted file mode 100644
index 0b660f3521..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/1764-1.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-__arch_strncpy_from_user needs to be exported if you build the framebuffer console driver as a module.
-
-Cheers,
-
-Ian.
-
---- linux-2.6-bkpxa.orig/arch/arm/kernel/armksyms.c 2004-02-27 10:35:29.000000000 +0000
-+++ linux-2.6-bkpxa/arch/arm/kernel/armksyms.c 2004-02-27 14:55:02.000000000 +0000
-@@ -187,6 +187,7 @@
- EXPORT_SYMBOL(__arch_copy_to_user);
- EXPORT_SYMBOL(__arch_clear_user);
- EXPORT_SYMBOL(__arch_strnlen_user);
-+EXPORT_SYMBOL(__arch_strncpy_from_user);
-
- /* consistent area handling */
- EXPORT_SYMBOL(consistent_alloc);
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bluecard_cs.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bluecard_cs.patch
deleted file mode 100644
index eacada33f5..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bluecard_cs.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- linux-orig/drivers/bluetooth/bluecard_cs.c 2004-02-16 10:51:46.000000000 +0300
-+++ linux/drivers/bluetooth/bluecard_cs.c 2004-02-17 03:45:31.000000000 +0300
-@@ -102,7 +102,7 @@
-
-
- /* Default baud rate: 57600, 115200, 230400 or 460800 */
--#define DEFAULT_BAUD_RATE 230400
-+#define DEFAULT_BAUD_RATE 460800
-
-
- /* Hardware states */
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bluetooth-2.4.18-mh11.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bluetooth-2.4.18-mh11.patch
deleted file mode 100644
index f2ea0d699b..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bluetooth-2.4.18-mh11.patch
+++ /dev/null
@@ -1,31393 +0,0 @@
-
-#
-# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux/arch/alpha/config.in~bluetooth-2.4.18-mh11 2004-01-25 23:28:10.000000000 +0100
-+++ linux/arch/alpha/config.in 2004-01-25 23:37:39.000000000 +0100
-@@ -372,9 +372,7 @@
- source drivers/usb/Config.in
- source drivers/input/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Kernel hacking'
---- linux/arch/arm/config.in~bluetooth-2.4.18-mh11 2004-01-25 23:28:31.000000000 +0100
-+++ linux/arch/arm/config.in 2004-01-25 23:37:39.000000000 +0100
-@@ -796,9 +796,7 @@
-
- source drivers/usb/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Kernel hacking'
---- linux/arch/i386/config.in~bluetooth-2.4.18-mh11 2004-01-25 23:28:31.000000000 +0100
-+++ linux/arch/i386/config.in 2004-01-25 23:37:39.000000000 +0100
-@@ -415,9 +415,7 @@
-
- source drivers/usb/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Kernel hacking'
---- linux/arch/ppc/config.in~bluetooth-2.4.18-mh11 2004-01-25 23:28:11.000000000 +0100
-+++ linux/arch/ppc/config.in 2004-01-25 23:37:39.000000000 +0100
-@@ -390,9 +390,7 @@
-
- source drivers/usb/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Kernel hacking'
---- linux/arch/sparc/config.in~bluetooth-2.4.18-mh11 2004-01-25 23:28:11.000000000 +0100
-+++ linux/arch/sparc/config.in 2004-01-25 23:37:39.000000000 +0100
-@@ -252,9 +252,7 @@
-
- source fs/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Watchdog'
---- linux/arch/sparc64/config.in~bluetooth-2.4.18-mh11 2004-01-25 23:28:11.000000000 +0100
-+++ linux/arch/sparc64/config.in 2004-01-25 23:37:39.000000000 +0100
-@@ -284,9 +284,7 @@
-
- source drivers/usb/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Watchdog'
---- linux/arch/sparc64/kernel/ioctl32.c~bluetooth-2.4.18-mh11 2002-02-25 20:37:56.000000000 +0100
-+++ linux/arch/sparc64/kernel/ioctl32.c 2004-01-25 23:37:39.000000000 +0100
-@@ -92,6 +92,7 @@
-
- #include <net/bluetooth/bluetooth.h>
- #include <net/bluetooth/hci.h>
-+#include <net/bluetooth/rfcomm.h>
-
- #include <linux/usb.h>
- #include <linux/usbdevice_fs.h>
-@@ -3822,6 +3823,15 @@
- return err;
- }
-
-+/* Bluetooth ioctls */
-+#define HCIUARTSETPROTO _IOW('U', 200, int)
-+#define HCIUARTGETPROTO _IOR('U', 201, int)
-+
-+#define BNEPCONNADD _IOW('B', 200, int)
-+#define BNEPCONNDEL _IOW('B', 201, int)
-+#define BNEPGETCONNLIST _IOR('B', 210, int)
-+#define BNEPGETCONNINFO _IOR('B', 211, int)
-+
- struct mtd_oob_buf32 {
- u32 start;
- u32 length;
-@@ -3878,6 +3888,11 @@
- return ((0 == ret) ? 0 : -EFAULT);
- }
-
-+#define CMTPCONNADD _IOW('C', 200, int)
-+#define CMTPCONNDEL _IOW('C', 201, int)
-+#define CMTPGETCONNLIST _IOR('C', 210, int)
-+#define CMTPGETCONNINFO _IOR('C', 211, int)
-+
- struct ioctl_trans {
- unsigned int cmd;
- unsigned int handler;
-@@ -4540,6 +4555,21 @@
- COMPATIBLE_IOCTL(HCISETSCAN)
- COMPATIBLE_IOCTL(HCISETAUTH)
- COMPATIBLE_IOCTL(HCIINQUIRY)
-+COMPATIBLE_IOCTL(HCIUARTSETPROTO)
-+COMPATIBLE_IOCTL(HCIUARTGETPROTO)
-+COMPATIBLE_IOCTL(RFCOMMCREATEDEV)
-+COMPATIBLE_IOCTL(RFCOMMRELEASEDEV)
-+COMPATIBLE_IOCTL(RFCOMMGETDEVLIST)
-+COMPATIBLE_IOCTL(RFCOMMGETDEVINFO)
-+COMPATIBLE_IOCTL(RFCOMMSTEALDLC)
-+COMPATIBLE_IOCTL(BNEPCONNADD)
-+COMPATIBLE_IOCTL(BNEPCONNDEL)
-+COMPATIBLE_IOCTL(BNEPGETCONNLIST)
-+COMPATIBLE_IOCTL(BNEPGETCONNINFO)
-+COMPATIBLE_IOCTL(CMTPCONNADD)
-+COMPATIBLE_IOCTL(CMTPCONNDEL)
-+COMPATIBLE_IOCTL(CMTPGETCONNLIST)
-+COMPATIBLE_IOCTL(CMTPGETCONNINFO)
- /* Misc. */
- COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */
- COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */
---- linux/CREDITS~bluetooth-2.4.18-mh11 2004-01-25 23:28:29.000000000 +0100
-+++ linux/CREDITS 2004-01-25 23:37:39.000000000 +0100
-@@ -1317,6 +1317,15 @@
- S: Provo, Utah 84606-5607
- S: USA
-
-+N: Marcel Holtmann
-+E: marcel@holtmann.org
-+W: http://www.holtmann.org
-+D: Maintainer of the Linux Bluetooth Subsystem
-+D: Author and maintainer of the various Bluetooth HCI drivers
-+D: Author and maintainer of the CAPI message transport protocol driver
-+D: Various other Bluetooth related patches, cleanups and fixes
-+S: Germany
-+
- N: Rob W. W. Hooft
- E: hooft@EMBL-Heidelberg.DE
- D: Shared libs for graphics-tools and for the f2c compiler
-@@ -2555,6 +2564,7 @@
- N: Aristeu Sergio Rozanski Filho
- E: aris@conectiva.com.br
- D: Support for EtherExpress 10 ISA (i82595) in eepro driver
-+D: User level driver support for input
- S: Conectiva S.A.
- S: R. Tocantins, 89 - Cristo Rei
- S: 80050-430 - Curitiba - Paraná
---- linux/Documentation/Configure.help~bluetooth-2.4.18-mh11 2004-01-25 23:28:31.000000000 +0100
-+++ linux/Documentation/Configure.help 2004-01-25 23:37:39.000000000 +0100
-@@ -2847,14 +2847,6 @@
-
- If unsure, say N.
-
--HCI EMU (virtual device) driver
--CONFIG_BLUEZ_HCIEMU
-- Bluetooth Virtual HCI device driver.
-- This driver is required if you want to use HCI Emulation software.
--
-- Say Y here to compile support for Virtual HCI devices into the
-- kernel or say M to compile it as module (hci_usb.o).
--
- # Choice: alphatype
- Alpha system type
- CONFIG_ALPHA_GENERIC
-@@ -11067,6 +11059,12 @@
-
- If unsure, say N.
-
-+Hotplug firmware loading support (EXPERIMENTAL)
-+CONFIG_FW_LOADER
-+ This option is provided for the case where no in-kernel-tree modules require
-+ hotplug firmware loading support, but a module built outside the kernel tree
-+ does.
-+
- Use PCI shared memory for NIC registers
- CONFIG_TULIP_MMIO
- Use PCI shared memory for the NIC registers, rather than going through
-@@ -12967,6 +12965,15 @@
- accessible under char device 13:64+ - /dev/input/eventX in a generic
- way. This is the future ...
-
-+CONFIG_INPUT_UINPUT
-+ Say Y here if you want to support user level drivers for input
-+ subsystem accessible under char device 10:223 - /dev/input/uinput.
-+
-+ This driver is also available as a module ( = code which can be
-+ inserted in and removed from the running kernel whenever you want).
-+ The module will be called uinput.o. If you want to compile it as a
-+ module, say M here and read <file:Documentation/modules.txt>.
-+
- USB Scanner support
- CONFIG_USB_SCANNER
- Say Y here if you want to connect a USB scanner to your computer's
-@@ -19986,11 +19993,15 @@
- Bluetooth can be found at <http://www.bluetooth.com/>.
-
- Linux Bluetooth subsystem consist of several layers:
-- HCI Core (device and connection manager, scheduler)
-+ BlueZ Core (HCI device and connection manager, scheduler)
- HCI Device drivers (interface to the hardware)
- L2CAP Module (L2CAP protocol)
-+ SCO Module (SCO links)
-+ RFCOMM Module (RFCOMM protocol)
-+ BNEP Module (BNEP protocol)
-+ CMTP Module (CMTP protocol)
-
-- Say Y here to enable Linux Bluetooth support and to build HCI Core
-+ Say Y here to enable Linux Bluetooth support and to build BlueZ Core
- layer.
-
- To use Linux Bluetooth subsystem, you will need several user-space
-@@ -19998,7 +20009,7 @@
- Bluetooth kernel modules are provided in the BlueZ package.
- For more information, see <http://bluez.sourceforge.net/>.
-
-- If you want to compile HCI Core as module (hci.o) say M here.
-+ If you want to compile BlueZ Core as module (bluez.o) say M here.
-
- L2CAP protocol support
- CONFIG_BLUEZ_L2CAP
-@@ -20009,15 +20020,91 @@
- Say Y here to compile L2CAP support into the kernel or say M to
- compile it as module (l2cap.o).
-
-+SCO links support
-+CONFIG_BLUEZ_SCO
-+ SCO link provides voice transport over Bluetooth. SCO support is
-+ required for voice applications like Headset and Audio.
-+
-+ Say Y here to compile SCO support into the kernel or say M to
-+ compile it as module (sco.o).
-+
-+RFCOMM protocol support
-+CONFIG_BLUEZ_RFCOMM
-+ RFCOMM provides connection oriented stream transport. RFCOMM
-+ support is required for Dialup Networking, OBEX and other Bluetooth
-+ applications.
-+
-+ Say Y here to compile RFCOMM support into the kernel or say M to
-+ compile it as module (rfcomm.o).
-+
-+RFCOMM TTY emulation support
-+CONFIG_BLUEZ_RFCOMM_TTY
-+ This option enables TTY emulation support for RFCOMM channels.
-+
-+BNEP protocol support
-+CONFIG_BLUEZ_BNEP
-+ BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet
-+ emulation layer on top of Bluetooth. BNEP is required for Bluetooth
-+ PAN (Personal Area Network).
-+
-+ To use BNEP, you will need user-space utilities provided in the
-+ BlueZ-PAN package.
-+ For more information, see <http://bluez.sourceforge.net>.
-+
-+ Say Y here to compile BNEP support into the kernel or say M to
-+ compile it as module (bnep.o).
-+
-+CMTP protocol support
-+CONFIG_BLUEZ_CMTP
-+ CMTP (CAPI Message Transport Protocol) is a transport layer
-+ for CAPI messages. CMTP is required for the Bluetooth Common
-+ ISDN Access Profile.
-+
-+ Say Y here to compile CMTP support into the kernel or say M to
-+ compile it as module (cmtp.o).
-+
-+BNEP multicast filter support
-+CONFIG_BLUEZ_BNEP_MC_FILTER
-+ This option enables the multicast filter support for BNEP.
-+
-+BNEP protocol filter support
-+CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+ This option enables the protocol filter support for BNEP.
-+
- HCI UART driver
- CONFIG_BLUEZ_HCIUART
- Bluetooth HCI UART driver.
- This driver is required if you want to use Bluetooth devices with
-- serial port interface.
-+ serial port interface. You will also need this driver if you have
-+ UART based Bluetooth PCMCIA and CF devices like Xircom Credit Card
-+ adapter and BrainBoxes Bluetooth PC Card.
-
- Say Y here to compile support for Bluetooth UART devices into the
- kernel or say M to compile it as module (hci_uart.o).
-
-+HCI UART (H4) protocol support
-+CONFIG_BLUEZ_HCIUART_H4
-+ UART (H4) is serial protocol for communication between Bluetooth
-+ device and host. This protocol is required for most Bluetooth devices
-+ with UART interface, including PCMCIA and CF cards.
-+
-+ Say Y here to compile support for HCI UART (H4) protocol.
-+
-+HCI BCSP protocol support
-+CONFIG_BLUEZ_HCIUART_BCSP
-+ BCSP (BlueCore Serial Protocol) is serial protocol for communication
-+ between Bluetooth device and host. This protocol is required for non
-+ USB Bluetooth devices based on CSR BlueCore chip, including PCMCIA and
-+ CF cards.
-+
-+ Say Y here to compile support for HCI BCSP protocol.
-+
-+HCI BCSP transmit CRC with every BCSP packet
-+CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ If you say Y here, a 16-bit CRC checksum will be transmitted along with
-+ every BCSP (BlueCore Serial Protocol) packet sent to the Bluetooth chip.
-+ This increases reliability, but slightly reduces efficiency.
-+
- HCI USB driver
- CONFIG_BLUEZ_HCIUSB
- Bluetooth HCI USB driver.
-@@ -20027,7 +20114,16 @@
- Say Y here to compile support for Bluetooth USB devices into the
- kernel or say M to compile it as module (hci_usb.o).
-
--HCI VHCI virtual HCI device driver
-+HCI USB SCO (voice) support
-+CONFIG_BLUEZ_HCIUSB_SCO
-+ This option enables the SCO support in the HCI USB driver. You need this
-+ to transmit voice data with your Bluetooth USB device. And your device
-+ must also support sending SCO data over the HCI layer, because some of
-+ them sends the SCO data to an internal PCM adapter.
-+
-+ Say Y here to compile support for HCI SCO data.
-+
-+HCI VHCI Virtual HCI device driver
- CONFIG_BLUEZ_HCIVHCI
- Bluetooth Virtual HCI device driver.
- This driver is required if you want to use HCI Emulation software.
-@@ -20035,6 +20131,66 @@
- Say Y here to compile support for virtual HCI devices into the
- kernel or say M to compile it as module (hci_vhci.o).
-
-+HCI BFUSB device driver
-+CONFIG_BLUEZ_HCIBFUSB
-+ Bluetooth HCI BlueFRITZ! USB driver.
-+ This driver provides support for Bluetooth USB devices with AVM
-+ interface:
-+ AVM BlueFRITZ! USB
-+
-+ Say Y here to compile support for HCI BFUSB devices into the
-+ kernel or say M to compile it as module (bfusb.o).
-+
-+HCI DTL1 (PC Card) device driver
-+CONFIG_BLUEZ_HCIDTL1
-+ Bluetooth HCI DTL1 (PC Card) driver.
-+ This driver provides support for Bluetooth PCMCIA devices with
-+ Nokia DTL1 interface:
-+ Nokia Bluetooth Card
-+ Socket Bluetooth CF Card
-+
-+ Say Y here to compile support for HCI DTL1 devices into the
-+ kernel or say M to compile it as module (dtl1_cs.o).
-+
-+HCI BT3C (PC Card) device driver
-+CONFIG_BLUEZ_HCIBT3C
-+ Bluetooth HCI BT3C (PC Card) driver.
-+ This driver provides support for Bluetooth PCMCIA devices with
-+ 3Com BT3C interface:
-+ 3Com Bluetooth Card (3CRWB6096)
-+ HP Bluetooth Card
-+
-+ The HCI BT3C driver uses external firmware loader program provided in
-+ the BlueFW package. For more information, see <http://bluez.sf.net>.
-+
-+ Say Y here to compile support for HCI BT3C devices into the
-+ kernel or say M to compile it as module (bt3c_cs.o).
-+
-+HCI BlueCard (PC Card) device driver
-+CONFIG_BLUEZ_HCIBLUECARD
-+ Bluetooth HCI BlueCard (PC Card) driver.
-+ This driver provides support for Bluetooth PCMCIA devices with
-+ Anycom BlueCard interface:
-+ Anycom Bluetooth PC Card
-+ Anycom Bluetooth CF Card
-+
-+ Say Y here to compile support for HCI BlueCard devices into the
-+ kernel or say M to compile it as module (bluecard_cs.o).
-+
-+HCI UART (PC Card) device driver
-+CONFIG_BLUEZ_HCIBTUART
-+ Bluetooth HCI UART (PC Card) driver.
-+ This driver provides support for Bluetooth PCMCIA devices with
-+ an UART interface:
-+ Xircom CreditCard Bluetooth Adapter
-+ Xircom RealPort2 Bluetooth Adapter
-+ Sphinx PICO Card
-+ H-Soft blue+Card
-+ Cyber-blue Compact Flash Card
-+
-+ Say Y here to compile support for HCI UART devices into the
-+ kernel or say M to compile it as module (btuart_cs.o).
-+
- # The following options are for Linux when running on the Hitachi
- # SuperH family of RISC microprocessors.
-
---- linux/Documentation/devices.txt~bluetooth-2.4.18-mh11 2001-11-07 23:46:01.000000000 +0100
-+++ linux/Documentation/devices.txt 2004-01-25 23:37:39.000000000 +0100
-@@ -419,6 +419,7 @@
- 220 = /dev/mptctl Message passing technology (MPT) control
- 221 = /dev/mvista/hssdsi Montavista PICMG hot swap system driver
- 222 = /dev/mvista/hasi Montavista PICMG high availability
-+ 223 = /dev/input/uinput User level driver support for input
- 240-255 Reserved for local use
-
- 11 char Raw keyboard device
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/firmware_class/firmware_sample_driver.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,121 @@
-+/*
-+ * firmware_sample_driver.c -
-+ *
-+ * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
-+ *
-+ * Sample code on how to use request_firmware() from drivers.
-+ *
-+ * Note that register_firmware() is currently useless.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/string.h>
-+
-+#include "linux/firmware.h"
-+
-+#define WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
-+#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
-+char __init inkernel_firmware[] = "let's say that this is firmware\n";
-+#endif
-+
-+static char ghost_device[] = "ghost0";
-+
-+static void sample_firmware_load(char *firmware, int size)
-+{
-+ u8 buf[size+1];
-+ memcpy(buf, firmware, size);
-+ buf[size] = '\0';
-+ printk("firmware_sample_driver: firmware: %s\n", buf);
-+}
-+
-+static void sample_probe_default(void)
-+{
-+ /* uses the default method to get the firmware */
-+ const struct firmware *fw_entry;
-+ printk("firmware_sample_driver: a ghost device got inserted :)\n");
-+
-+ if(request_firmware(&fw_entry, "sample_driver_fw", ghost_device)!=0)
-+ {
-+ printk(KERN_ERR
-+ "firmware_sample_driver: Firmware not available\n");
-+ return;
-+ }
-+
-+ sample_firmware_load(fw_entry->data, fw_entry->size);
-+
-+ release_firmware(fw_entry);
-+
-+ /* finish setting up the device */
-+}
-+static void sample_probe_specific(void)
-+{
-+ /* Uses some specific hotplug support to get the firmware from
-+ * userspace directly into the hardware, or via some sysfs file */
-+
-+ /* NOTE: This currently doesn't work */
-+
-+ printk("firmware_sample_driver: a ghost device got inserted :)\n");
-+
-+ if(request_firmware(NULL, "sample_driver_fw", ghost_device)!=0)
-+ {
-+ printk(KERN_ERR
-+ "firmware_sample_driver: Firmware load failed\n");
-+ return;
-+ }
-+
-+ /* request_firmware blocks until userspace finished, so at
-+ * this point the firmware should be already in the device */
-+
-+ /* finish setting up the device */
-+}
-+static void sample_probe_async_cont(const struct firmware *fw, void *context)
-+{
-+ if(!fw){
-+ printk(KERN_ERR
-+ "firmware_sample_driver: firmware load failed\n");
-+ return;
-+ }
-+
-+ printk("firmware_sample_driver: device pointer \"%s\"\n",
-+ (char *)context);
-+ sample_firmware_load(fw->data, fw->size);
-+}
-+static void sample_probe_async(void)
-+{
-+ /* Let's say that I can't sleep */
-+ int error;
-+ error = request_firmware_nowait (THIS_MODULE,
-+ "sample_driver_fw", ghost_device,
-+ "my device pointer",
-+ sample_probe_async_cont);
-+ if(error){
-+ printk(KERN_ERR
-+ "firmware_sample_driver:"
-+ " request_firmware_nowait failed\n");
-+ }
-+}
-+
-+static int sample_init(void)
-+{
-+#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
-+ register_firmware("sample_driver_fw", inkernel_firmware,
-+ sizeof(inkernel_firmware));
-+#endif
-+ /* since there is no real hardware insertion I just call the
-+ * sample probe functions here */
-+ sample_probe_specific();
-+ sample_probe_default();
-+ sample_probe_async();
-+ return 0;
-+}
-+static void __exit sample_exit(void)
-+{
-+}
-+
-+module_init (sample_init);
-+module_exit (sample_exit);
-+
-+MODULE_LICENSE("GPL");
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/firmware_class/hotplug-script 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,16 @@
-+#!/bin/sh
-+
-+# Simple hotplug script sample:
-+#
-+# Both $DEVPATH and $FIRMWARE are already provided in the environment.
-+
-+HOTPLUG_FW_DIR=/usr/lib/hotplug/firmware/
-+
-+echo 1 > /sysfs/$DEVPATH/loading
-+cat $HOTPLUG_FW_DIR/$FIRMWARE > /sysfs/$DEVPATH/data
-+echo 0 > /sysfs/$DEVPATH/loading
-+
-+# To cancel the load in case of error:
-+#
-+# echo -1 > /sysfs/$DEVPATH/loading
-+#
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/Documentation/firmware_class/README 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,58 @@
-+
-+ request_firmware() hotplug interface:
-+ ------------------------------------
-+ Copyright (C) 2003 Manuel Estrada Sainz <ranty@debian.org>
-+
-+ Why:
-+ ---
-+
-+ Today, the most extended way to use firmware in the Linux kernel is linking
-+ it statically in a header file. Which has political and technical issues:
-+
-+ 1) Some firmware is not legal to redistribute.
-+ 2) The firmware occupies memory permanently, even though it often is just
-+ used once.
-+ 3) Some people, like the Debian crowd, don't consider some firmware free
-+ enough and remove entire drivers (e.g.: keyspan).
-+
-+ about in-kernel persistence:
-+ ---------------------------
-+ Under some circumstances, as explained below, it would be interesting to keep
-+ firmware images in non-swappable kernel memory or even in the kernel image
-+ (probably within initramfs).
-+
-+ Note that this functionality has not been implemented.
-+
-+ - Why OPTIONAL in-kernel persistence may be a good idea sometimes:
-+
-+ - If the device that needs the firmware is needed to access the
-+ filesystem. When upon some error the device has to be reset and the
-+ firmware reloaded, it won't be possible to get it from userspace.
-+ e.g.:
-+ - A diskless client with a network card that needs firmware.
-+ - The filesystem is stored in a disk behind an scsi device
-+ that needs firmware.
-+ - Replacing buggy DSDT/SSDT ACPI tables on boot.
-+ Note: this would require the persistent objects to be included
-+ within the kernel image, probably within initramfs.
-+
-+ And the same device can be needed to access the filesystem or not depending
-+ on the setup, so I think that the choice on what firmware to make
-+ persistent should be left to userspace.
-+
-+ - Why register_firmware()+__init can be useful:
-+ - For boot devices needing firmware.
-+ - To make the transition easier:
-+ The firmware can be declared __init and register_firmware()
-+ called on module_init. Then the firmware is warranted to be
-+ there even if "firmware hotplug userspace" is not there yet or
-+ it doesn't yet provide the needed firmware.
-+ Once the firmware is widely available in userspace, it can be
-+ removed from the kernel. Or made optional (CONFIG_.*_FIRMWARE).
-+
-+ In either case, if firmware hotplug support is there, it can move the
-+ firmware out of kernel memory into the real filesystem for later
-+ usage.
-+
-+ Note: If persistence is implemented on top of initramfs,
-+ register_firmware() may not be appropriate.
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/bluetooth/bfusb.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,781 @@
-+/*
-+ *
-+ * AVM BlueFRITZ! USB driver
-+ *
-+ * Copyright (C) 2003 Marcel Holtmann <marcel@holtmann.org>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/skbuff.h>
-+
-+#include <linux/firmware.h>
-+#include <linux/usb.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+#ifndef CONFIG_BLUEZ_HCIBFUSB_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define VERSION "1.1"
-+
-+static struct usb_device_id bfusb_table[] = {
-+ /* AVM BlueFRITZ! USB */
-+ { USB_DEVICE(0x057c, 0x2200) },
-+
-+ { } /* Terminating entry */
-+};
-+
-+MODULE_DEVICE_TABLE(usb, bfusb_table);
-+
-+
-+#define BFUSB_MAX_BLOCK_SIZE 256
-+
-+#define BFUSB_BLOCK_TIMEOUT (HZ * 3)
-+
-+#define BFUSB_TX_PROCESS 1
-+#define BFUSB_TX_WAKEUP 2
-+
-+#define BFUSB_MAX_BULK_TX 1
-+#define BFUSB_MAX_BULK_RX 1
-+
-+struct bfusb {
-+ struct hci_dev hdev;
-+
-+ unsigned long state;
-+
-+ struct usb_device *udev;
-+
-+ unsigned int bulk_in_ep;
-+ unsigned int bulk_out_ep;
-+ unsigned int bulk_pkt_size;
-+
-+ rwlock_t lock;
-+
-+ struct sk_buff_head transmit_q;
-+
-+ struct sk_buff *reassembly;
-+
-+ atomic_t pending_tx;
-+ struct sk_buff_head pending_q;
-+ struct sk_buff_head completed_q;
-+};
-+
-+struct bfusb_scb {
-+ struct urb *urb;
-+};
-+
-+static void bfusb_tx_complete(struct urb *urb);
-+static void bfusb_rx_complete(struct urb *urb);
-+
-+static struct urb *bfusb_get_completed(struct bfusb *bfusb)
-+{
-+ struct sk_buff *skb;
-+ struct urb *urb = NULL;
-+
-+ BT_DBG("bfusb %p", bfusb);
-+
-+ skb = skb_dequeue(&bfusb->completed_q);
-+ if (skb) {
-+ urb = ((struct bfusb_scb *) skb->cb)->urb;
-+ kfree_skb(skb);
-+ }
-+
-+ return urb;
-+}
-+
-+static inline void bfusb_unlink_urbs(struct bfusb *bfusb)
-+{
-+ struct sk_buff *skb;
-+ struct urb *urb;
-+
-+ BT_DBG("bfusb %p", bfusb);
-+
-+ while ((skb = skb_dequeue(&bfusb->pending_q))) {
-+ urb = ((struct bfusb_scb *) skb->cb)->urb;
-+ usb_unlink_urb(urb);
-+ skb_queue_tail(&bfusb->completed_q, skb);
-+ }
-+
-+ while ((urb = bfusb_get_completed(bfusb)))
-+ usb_free_urb(urb);
-+}
-+
-+
-+static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb)
-+{
-+ struct bfusb_scb *scb = (void *) skb->cb;
-+ struct urb *urb = bfusb_get_completed(bfusb);
-+ int err, pipe;
-+
-+ BT_DBG("bfusb %p skb %p len %d", bfusb, skb, skb->len);
-+
-+ if (!urb && !(urb = usb_alloc_urb(0)))
-+ return -ENOMEM;
-+
-+ pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
-+
-+ FILL_BULK_URB(urb, bfusb->udev, pipe, skb->data, skb->len,
-+ bfusb_tx_complete, skb);
-+
-+ urb->transfer_flags = USB_QUEUE_BULK;
-+
-+ scb->urb = urb;
-+
-+ skb_queue_tail(&bfusb->pending_q, skb);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s bulk tx submit failed urb %p err %d",
-+ bfusb->hdev.name, urb, err);
-+ skb_unlink(skb);
-+ usb_free_urb(urb);
-+ } else
-+ atomic_inc(&bfusb->pending_tx);
-+
-+ return err;
-+}
-+
-+static void bfusb_tx_wakeup(struct bfusb *bfusb)
-+{
-+ struct sk_buff *skb;
-+
-+ BT_DBG("bfusb %p", bfusb);
-+
-+ if (test_and_set_bit(BFUSB_TX_PROCESS, &bfusb->state)) {
-+ set_bit(BFUSB_TX_WAKEUP, &bfusb->state);
-+ return;
-+ }
-+
-+ do {
-+ clear_bit(BFUSB_TX_WAKEUP, &bfusb->state);
-+
-+ while ((atomic_read(&bfusb->pending_tx) < BFUSB_MAX_BULK_TX) &&
-+ (skb = skb_dequeue(&bfusb->transmit_q))) {
-+ if (bfusb_send_bulk(bfusb, skb) < 0) {
-+ skb_queue_head(&bfusb->transmit_q, skb);
-+ break;
-+ }
-+ }
-+
-+ } while (test_bit(BFUSB_TX_WAKEUP, &bfusb->state));
-+
-+ clear_bit(BFUSB_TX_PROCESS, &bfusb->state);
-+}
-+
-+static void bfusb_tx_complete(struct urb *urb)
-+{
-+ struct sk_buff *skb = (struct sk_buff *) urb->context;
-+ struct bfusb *bfusb = (struct bfusb *) skb->dev;
-+
-+ BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
-+
-+ atomic_dec(&bfusb->pending_tx);
-+
-+ if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags))
-+ return;
-+
-+ if (!urb->status)
-+ bfusb->hdev.stat.byte_tx += skb->len;
-+ else
-+ bfusb->hdev.stat.err_tx++;
-+
-+ read_lock(&bfusb->lock);
-+
-+ skb_unlink(skb);
-+ skb_queue_tail(&bfusb->completed_q, skb);
-+
-+ bfusb_tx_wakeup(bfusb);
-+
-+ read_unlock(&bfusb->lock);
-+}
-+
-+
-+static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb)
-+{
-+ struct bfusb_scb *scb;
-+ struct sk_buff *skb;
-+ int err, pipe, size = HCI_MAX_FRAME_SIZE + 32;
-+
-+ BT_DBG("bfusb %p urb %p", bfusb, urb);
-+
-+ if (!urb && !(urb = usb_alloc_urb(0)))
-+ return -ENOMEM;
-+
-+ if (!(skb = bluez_skb_alloc(size, GFP_ATOMIC))) {
-+ usb_free_urb(urb);
-+ return -ENOMEM;
-+ }
-+
-+ skb->dev = (void *) bfusb;
-+
-+ scb = (struct bfusb_scb *) skb->cb;
-+ scb->urb = urb;
-+
-+ pipe = usb_rcvbulkpipe(bfusb->udev, bfusb->bulk_in_ep);
-+
-+ FILL_BULK_URB(urb, bfusb->udev, pipe, skb->data, size,
-+ bfusb_rx_complete, skb);
-+
-+ urb->transfer_flags = USB_QUEUE_BULK;
-+
-+ skb_queue_tail(&bfusb->pending_q, skb);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s bulk rx submit failed urb %p err %d",
-+ bfusb->hdev.name, urb, err);
-+ skb_unlink(skb);
-+ kfree_skb(skb);
-+ usb_free_urb(urb);
-+ }
-+
-+ return err;
-+}
-+
-+static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *data, int len)
-+{
-+ BT_DBG("bfusb %p hdr 0x%02x data %p len %d", bfusb, hdr, data, len);
-+
-+ if (hdr & 0x10) {
-+ BT_ERR("%s error in block", bfusb->hdev.name);
-+ if (bfusb->reassembly)
-+ kfree_skb(bfusb->reassembly);
-+ bfusb->reassembly = NULL;
-+ return -EIO;
-+ }
-+
-+ if (hdr & 0x04) {
-+ struct sk_buff *skb;
-+ unsigned char pkt_type;
-+ int pkt_len = 0;
-+
-+ if (bfusb->reassembly) {
-+ BT_ERR("%s unexpected start block", bfusb->hdev.name);
-+ kfree_skb(bfusb->reassembly);
-+ bfusb->reassembly = NULL;
-+ }
-+
-+ if (len < 1) {
-+ BT_ERR("%s no packet type found", bfusb->hdev.name);
-+ return -EPROTO;
-+ }
-+
-+ pkt_type = *data++; len--;
-+
-+ switch (pkt_type) {
-+ case HCI_EVENT_PKT:
-+ if (len >= HCI_EVENT_HDR_SIZE) {
-+ hci_event_hdr *hdr = (hci_event_hdr *) data;
-+ pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;
-+ } else {
-+ BT_ERR("%s event block is too short", bfusb->hdev.name);
-+ return -EILSEQ;
-+ }
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ if (len >= HCI_ACL_HDR_SIZE) {
-+ hci_acl_hdr *hdr = (hci_acl_hdr *) data;
-+ pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen);
-+ } else {
-+ BT_ERR("%s data block is too short", bfusb->hdev.name);
-+ return -EILSEQ;
-+ }
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ if (len >= HCI_SCO_HDR_SIZE) {
-+ hci_sco_hdr *hdr = (hci_sco_hdr *) data;
-+ pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen;
-+ } else {
-+ BT_ERR("%s audio block is too short", bfusb->hdev.name);
-+ return -EILSEQ;
-+ }
-+ break;
-+ }
-+
-+ skb = bluez_skb_alloc(pkt_len, GFP_ATOMIC);
-+ if (!skb) {
-+ BT_ERR("%s no memory for the packet", bfusb->hdev.name);
-+ return -ENOMEM;
-+ }
-+
-+ skb->dev = (void *) &bfusb->hdev;
-+ skb->pkt_type = pkt_type;
-+
-+ bfusb->reassembly = skb;
-+ } else {
-+ if (!bfusb->reassembly) {
-+ BT_ERR("%s unexpected continuation block", bfusb->hdev.name);
-+ return -EIO;
-+ }
-+ }
-+
-+ if (len > 0)
-+ memcpy(skb_put(bfusb->reassembly, len), data, len);
-+
-+ if (hdr & 0x08) {
-+ hci_recv_frame(bfusb->reassembly);
-+ bfusb->reassembly = NULL;
-+ }
-+
-+ return 0;
-+}
-+
-+static void bfusb_rx_complete(struct urb *urb)
-+{
-+ struct sk_buff *skb = (struct sk_buff *) urb->context;
-+ struct bfusb *bfusb = (struct bfusb *) skb->dev;
-+ unsigned char *buf = urb->transfer_buffer;
-+ int count = urb->actual_length;
-+ int err, hdr, len;
-+
-+ BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
-+
-+ if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags))
-+ return;
-+
-+ read_lock(&bfusb->lock);
-+
-+ if (urb->status || !count)
-+ goto resubmit;
-+
-+ bfusb->hdev.stat.byte_rx += count;
-+
-+ skb_put(skb, count);
-+
-+ while (count) {
-+ hdr = buf[0] | (buf[1] << 8);
-+
-+ if (hdr & 0x4000) {
-+ len = 0;
-+ count -= 2;
-+ buf += 2;
-+ } else {
-+ len = (buf[2] == 0) ? 256 : buf[2];
-+ count -= 3;
-+ buf += 3;
-+ }
-+
-+ if (count < len) {
-+ BT_ERR("%s block extends over URB buffer ranges",
-+ bfusb->hdev.name);
-+ }
-+
-+ if ((hdr & 0xe1) == 0xc1)
-+ bfusb_recv_block(bfusb, hdr, buf, len);
-+
-+ count -= len;
-+ buf += len;
-+ }
-+
-+ skb_unlink(skb);
-+ kfree_skb(skb);
-+
-+ bfusb_rx_submit(bfusb, urb);
-+
-+ read_unlock(&bfusb->lock);
-+
-+ return;
-+
-+resubmit:
-+ urb->dev = bfusb->udev;
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s bulk resubmit failed urb %p err %d",
-+ bfusb->hdev.name, urb, err);
-+ }
-+
-+ read_unlock(&bfusb->lock);
-+}
-+
-+
-+static int bfusb_open(struct hci_dev *hdev)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
-+ unsigned long flags;
-+ int i, err;
-+
-+ BT_DBG("hdev %p bfusb %p", hdev, bfusb);
-+
-+ if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ write_lock_irqsave(&bfusb->lock, flags);
-+
-+ err = bfusb_rx_submit(bfusb, NULL);
-+ if (!err) {
-+ for (i = 1; i < BFUSB_MAX_BULK_RX; i++)
-+ bfusb_rx_submit(bfusb, NULL);
-+ } else {
-+ clear_bit(HCI_RUNNING, &hdev->flags);
-+ MOD_DEC_USE_COUNT;
-+ }
-+
-+ write_unlock_irqrestore(&bfusb->lock, flags);
-+
-+ return err;
-+}
-+
-+static int bfusb_flush(struct hci_dev *hdev)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
-+
-+ BT_DBG("hdev %p bfusb %p", hdev, bfusb);
-+
-+ skb_queue_purge(&bfusb->transmit_q);
-+
-+ return 0;
-+}
-+
-+static int bfusb_close(struct hci_dev *hdev)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
-+ unsigned long flags;
-+
-+ BT_DBG("hdev %p bfusb %p", hdev, bfusb);
-+
-+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-+
-+ write_lock_irqsave(&bfusb->lock, flags);
-+
-+ bfusb_unlink_urbs(bfusb);
-+ bfusb_flush(hdev);
-+
-+ write_unlock_irqrestore(&bfusb->lock, flags);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ return 0;
-+}
-+
-+static int bfusb_send_frame(struct sk_buff *skb)
-+{
-+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-+ struct bfusb *bfusb;
-+ struct sk_buff *nskb;
-+ unsigned char buf[3];
-+ int sent = 0, size, count;
-+
-+ BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, skb->pkt_type, skb->len);
-+
-+ if (!hdev) {
-+ BT_ERR("Frame for unknown HCI device (hdev=NULL)");
-+ return -ENODEV;
-+ }
-+
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return -EBUSY;
-+
-+ bfusb = (struct bfusb *) hdev->driver_data;
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+
-+ count = skb->len;
-+
-+ /* Max HCI frame size seems to be 1511 + 1 */
-+ if (!(nskb = bluez_skb_alloc(count + 32, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for new packet");
-+ return -ENOMEM;
-+ }
-+
-+ nskb->dev = (void *) bfusb;
-+
-+ while (count) {
-+ size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE);
-+
-+ buf[0] = 0xc1 | ((sent == 0) ? 0x04 : 0) | ((count == size) ? 0x08 : 0);
-+ buf[1] = 0x00;
-+ buf[2] = (size == BFUSB_MAX_BLOCK_SIZE) ? 0 : size;
-+
-+ memcpy(skb_put(nskb, 3), buf, 3);
-+ memcpy(skb_put(nskb, size), skb->data + sent, size);
-+
-+ sent += size;
-+ count -= size;
-+ }
-+
-+ /* Don't send frame with multiple size of bulk max packet */
-+ if ((nskb->len % bfusb->bulk_pkt_size) == 0) {
-+ buf[0] = 0xdd;
-+ buf[1] = 0x00;
-+ memcpy(skb_put(nskb, 2), buf, 2);
-+ }
-+
-+ read_lock(&bfusb->lock);
-+
-+ skb_queue_tail(&bfusb->transmit_q, nskb);
-+ bfusb_tx_wakeup(bfusb);
-+
-+ read_unlock(&bfusb->lock);
-+
-+ kfree_skb(skb);
-+
-+ return 0;
-+}
-+
-+static void bfusb_destruct(struct hci_dev *hdev)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
-+
-+ BT_DBG("hdev %p bfusb %p", hdev, bfusb);
-+
-+ kfree(bfusb);
-+}
-+
-+static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int count)
-+{
-+ unsigned char *buf;
-+ int err, pipe, len, size, sent = 0;
-+
-+ BT_DBG("bfusb %p udev %p firmware %p count %d", bfusb, bfusb->udev, firmware, count);
-+
-+ BT_INFO("BlueFRITZ! USB loading firmware");
-+
-+ if (usb_set_configuration(bfusb->udev, 1) < 0) {
-+ BT_ERR("Can't change to loading configuration");
-+ return -EBUSY;
-+ }
-+
-+ buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
-+ if (!buf) {
-+ BT_ERR("Can't allocate memory chunk for firmware");
-+ return -ENOMEM;
-+ }
-+
-+ pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
-+
-+ while (count) {
-+ size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3);
-+
-+ memcpy(buf, firmware + sent, size);
-+
-+ err = usb_bulk_msg(bfusb->udev, pipe, buf, size,
-+ &len, BFUSB_BLOCK_TIMEOUT);
-+
-+ if (err || (len != size)) {
-+ BT_ERR("Error in firmware loading");
-+ goto error;
-+ }
-+
-+ sent += size;
-+ count -= size;
-+ }
-+
-+ if ((err = usb_bulk_msg(bfusb->udev, pipe, NULL, 0,
-+ &len, BFUSB_BLOCK_TIMEOUT)) < 0) {
-+ BT_ERR("Error in null packet request");
-+ goto error;
-+ }
-+
-+ if ((err = usb_set_configuration(bfusb->udev, 2)) < 0) {
-+ BT_ERR("Can't change to running configuration");
-+ goto error;
-+ }
-+
-+ BT_INFO("BlueFRITZ! USB device ready");
-+
-+ kfree(buf);
-+ return 0;
-+
-+error:
-+ kfree(buf);
-+
-+ pipe = usb_sndctrlpipe(bfusb->udev, 0);
-+
-+ usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
-+ 0, 0, 0, NULL, 0, BFUSB_BLOCK_TIMEOUT);
-+
-+ return err;
-+}
-+
-+static void *bfusb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
-+{
-+ const struct firmware *firmware;
-+ char device[16];
-+ struct usb_interface *iface;
-+ struct usb_interface_descriptor *iface_desc;
-+ struct usb_endpoint_descriptor *bulk_out_ep;
-+ struct usb_endpoint_descriptor *bulk_in_ep;
-+ struct hci_dev *hdev;
-+ struct bfusb *bfusb;
-+
-+ BT_DBG("udev %p ifnum %d id %p", udev, ifnum, id);
-+
-+ /* Check number of endpoints */
-+ iface = &udev->actconfig->interface[0];
-+ iface_desc = &iface->altsetting[0];
-+
-+ if (iface_desc->bNumEndpoints < 2)
-+ return NULL;
-+
-+ bulk_out_ep = &iface_desc->endpoint[0];
-+ bulk_in_ep = &iface_desc->endpoint[1];
-+
-+ if (!bulk_out_ep || !bulk_in_ep) {
-+ BT_ERR("Bulk endpoints not found");
-+ goto done;
-+ }
-+
-+ /* Initialize control structure and load firmware */
-+ if (!(bfusb = kmalloc(sizeof(struct bfusb), GFP_KERNEL))) {
-+ BT_ERR("Can't allocate memory for control structure");
-+ goto done;
-+ }
-+
-+ memset(bfusb, 0, sizeof(struct bfusb));
-+
-+ bfusb->udev = udev;
-+ bfusb->bulk_in_ep = bulk_in_ep->bEndpointAddress;
-+ bfusb->bulk_out_ep = bulk_out_ep->bEndpointAddress;
-+ bfusb->bulk_pkt_size = bulk_out_ep->wMaxPacketSize;
-+
-+ bfusb->lock = RW_LOCK_UNLOCKED;
-+
-+ bfusb->reassembly = NULL;
-+
-+ skb_queue_head_init(&bfusb->transmit_q);
-+ skb_queue_head_init(&bfusb->pending_q);
-+ skb_queue_head_init(&bfusb->completed_q);
-+
-+ snprintf(device, sizeof(device), "bfusb%3.3d%3.3d", udev->bus->busnum, udev->devnum);
-+
-+ if (request_firmware(&firmware, "bfubase.frm", device) < 0) {
-+ BT_ERR("Firmware request failed");
-+ goto error;
-+ }
-+
-+ if (bfusb_load_firmware(bfusb, firmware->data, firmware->size) < 0) {
-+ BT_ERR("Firmware loading failed");
-+ goto release;
-+ }
-+
-+ release_firmware(firmware);
-+
-+ /* Initialize and register HCI device */
-+ hdev = &bfusb->hdev;
-+
-+ hdev->type = HCI_USB;
-+ hdev->driver_data = bfusb;
-+
-+ hdev->open = bfusb_open;
-+ hdev->close = bfusb_close;
-+ hdev->flush = bfusb_flush;
-+ hdev->send = bfusb_send_frame;
-+ hdev->destruct = bfusb_destruct;
-+ hdev->ioctl = bfusb_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ BT_ERR("Can't register HCI device");
-+ goto error;
-+ }
-+
-+ return bfusb;
-+
-+release:
-+ release_firmware(firmware);
-+
-+error:
-+ kfree(bfusb);
-+
-+done:
-+ return NULL;
-+}
-+
-+static void bfusb_disconnect(struct usb_device *udev, void *ptr)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) ptr;
-+ struct hci_dev *hdev = &bfusb->hdev;
-+
-+ BT_DBG("udev %p ptr %p", udev, ptr);
-+
-+ if (!hdev)
-+ return;
-+
-+ bfusb_close(hdev);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ BT_ERR("Can't unregister HCI device %s", hdev->name);
-+}
-+
-+static struct usb_driver bfusb_driver = {
-+ name: "bfusb",
-+ probe: bfusb_probe,
-+ disconnect: bfusb_disconnect,
-+ id_table: bfusb_table,
-+};
-+
-+static int __init bfusb_init(void)
-+{
-+ int err;
-+
-+ BT_INFO("BlueFRITZ! USB driver ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2003 Marcel Holtmann <marcel@holtmann.org>");
-+
-+ if ((err = usb_register(&bfusb_driver)) < 0)
-+ BT_ERR("Failed to register BlueFRITZ! USB driver");
-+
-+ return err;
-+}
-+
-+static void __exit bfusb_cleanup(void)
-+{
-+ usb_deregister(&bfusb_driver);
-+}
-+
-+module_init(bfusb_init);
-+module_exit(bfusb_cleanup);
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION);
-+MODULE_LICENSE("GPL");
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/bluetooth/bluecard_cs.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,1113 @@
-+/*
-+ *
-+ * Bluetooth driver for the Anycom BlueCard (LSE039/LSE041)
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+#include <linux/skbuff.h>
-+#include <asm/io.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0x86bc;
-+static int irq_list[4] = { -1 };
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ driver for the Anycom BlueCard (LSE039/LSE041)");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct bluecard_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+ struct timer_list timer; /* For LED control */
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+
-+ unsigned char ctrl_reg;
-+ unsigned long hw_state; /* Status of the hardware and LED control */
-+} bluecard_info_t;
-+
-+
-+void bluecard_config(dev_link_t *link);
-+void bluecard_release(u_long arg);
-+int bluecard_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "bluecard_cs";
-+
-+dev_link_t *bluecard_attach(void);
-+void bluecard_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+
-+/* Default baud rate: 57600, 115200, 230400 or 460800 */
-+#define DEFAULT_BAUD_RATE 230400
-+
-+
-+/* Hardware states */
-+#define CARD_READY 1
-+#define CARD_HAS_PCCARD_ID 4
-+#define CARD_HAS_POWER_LED 5
-+#define CARD_HAS_ACTIVITY_LED 6
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_BUFFER_NUMBER 5 /* unset = buffer one, set = buffer two */
-+#define XMIT_BUF_ONE_READY 6
-+#define XMIT_BUF_TWO_READY 7
-+#define XMIT_SENDING_READY 8
-+
-+/* Receiver states */
-+#define RECV_WAIT_PACKET_TYPE 0
-+#define RECV_WAIT_EVENT_HEADER 1
-+#define RECV_WAIT_ACL_HEADER 2
-+#define RECV_WAIT_SCO_HEADER 3
-+#define RECV_WAIT_DATA 4
-+
-+/* Special packet types */
-+#define PKT_BAUD_RATE_57600 0x80
-+#define PKT_BAUD_RATE_115200 0x81
-+#define PKT_BAUD_RATE_230400 0x82
-+#define PKT_BAUD_RATE_460800 0x83
-+
-+
-+/* These are the register offsets */
-+#define REG_COMMAND 0x20
-+#define REG_INTERRUPT 0x21
-+#define REG_CONTROL 0x22
-+#define REG_RX_CONTROL 0x24
-+#define REG_CARD_RESET 0x30
-+#define REG_LED_CTRL 0x30
-+
-+/* REG_COMMAND */
-+#define REG_COMMAND_TX_BUF_ONE 0x01
-+#define REG_COMMAND_TX_BUF_TWO 0x02
-+#define REG_COMMAND_RX_BUF_ONE 0x04
-+#define REG_COMMAND_RX_BUF_TWO 0x08
-+#define REG_COMMAND_RX_WIN_ONE 0x00
-+#define REG_COMMAND_RX_WIN_TWO 0x10
-+
-+/* REG_CONTROL */
-+#define REG_CONTROL_BAUD_RATE_57600 0x00
-+#define REG_CONTROL_BAUD_RATE_115200 0x01
-+#define REG_CONTROL_BAUD_RATE_230400 0x02
-+#define REG_CONTROL_BAUD_RATE_460800 0x03
-+#define REG_CONTROL_RTS 0x04
-+#define REG_CONTROL_BT_ON 0x08
-+#define REG_CONTROL_BT_RESET 0x10
-+#define REG_CONTROL_BT_RES_PU 0x20
-+#define REG_CONTROL_INTERRUPT 0x40
-+#define REG_CONTROL_CARD_RESET 0x80
-+
-+/* REG_RX_CONTROL */
-+#define RTS_LEVEL_SHIFT_BITS 0x02
-+
-+
-+
-+/* ======================== LED handling routines ======================== */
-+
-+
-+void bluecard_activity_led_timeout(u_long arg)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)arg;
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) {
-+ /* Disable activity LED */
-+ outb(0x08 | 0x20, iobase + 0x30);
-+ } else {
-+ /* Disable power LED */
-+ outb(0x00, iobase + 0x30);
-+ }
-+}
-+
-+
-+static void bluecard_enable_activity_led(bluecard_info_t *info)
-+{
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) {
-+ /* Enable activity LED */
-+ outb(0x10 | 0x40, iobase + 0x30);
-+
-+ /* Stop the LED after HZ/4 */
-+ mod_timer(&(info->timer), jiffies + HZ / 4);
-+ } else {
-+ /* Enable power LED */
-+ outb(0x08 | 0x20, iobase + 0x30);
-+
-+ /* Stop the LED after HZ/2 */
-+ mod_timer(&(info->timer), jiffies + HZ / 2);
-+ }
-+}
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int bluecard_write(unsigned int iobase, unsigned int offset, __u8 *buf, int len)
-+{
-+ int i, actual;
-+
-+ actual = (len > 15) ? 15 : len;
-+
-+ outb_p(actual, iobase + offset);
-+
-+ for (i = 0; i < actual; i++)
-+ outb_p(buf[i], iobase + offset + i + 1);
-+
-+ return actual;
-+}
-+
-+
-+static void bluecard_write_wakeup(bluecard_info_t *info)
-+{
-+ if (!info) {
-+ printk(KERN_WARNING "bluecard_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (!test_bit(XMIT_SENDING_READY, &(info->tx_state)))
-+ return;
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register unsigned int offset;
-+ register unsigned char command;
-+ register unsigned long ready_bit;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ clear_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ return;
-+
-+ if (test_bit(XMIT_BUFFER_NUMBER, &(info->tx_state))) {
-+ if (!test_bit(XMIT_BUF_TWO_READY, &(info->tx_state)))
-+ break;
-+ offset = 0x10;
-+ command = REG_COMMAND_TX_BUF_TWO;
-+ ready_bit = XMIT_BUF_TWO_READY;
-+ } else {
-+ if (!test_bit(XMIT_BUF_ONE_READY, &(info->tx_state)))
-+ break;
-+ offset = 0x00;
-+ command = REG_COMMAND_TX_BUF_ONE;
-+ ready_bit = XMIT_BUF_ONE_READY;
-+ }
-+
-+ if (!(skb = skb_dequeue(&(info->txq))))
-+ break;
-+
-+ if (skb->pkt_type & 0x80) {
-+ /* Disable RTS */
-+ info->ctrl_reg |= REG_CONTROL_RTS;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+ }
-+
-+ /* Activate LED */
-+ bluecard_enable_activity_led(info);
-+
-+ /* Send frame */
-+ len = bluecard_write(iobase, offset, skb->data, skb->len);
-+
-+ /* Tell the FPGA to send the data */
-+ outb_p(command, iobase + REG_COMMAND);
-+
-+ /* Mark the buffer as dirty */
-+ clear_bit(ready_bit, &(info->tx_state));
-+
-+ if (skb->pkt_type & 0x80) {
-+
-+ wait_queue_head_t wait;
-+ unsigned char baud_reg;
-+
-+ switch (skb->pkt_type) {
-+ case PKT_BAUD_RATE_460800:
-+ baud_reg = REG_CONTROL_BAUD_RATE_460800;
-+ break;
-+ case PKT_BAUD_RATE_230400:
-+ baud_reg = REG_CONTROL_BAUD_RATE_230400;
-+ break;
-+ case PKT_BAUD_RATE_115200:
-+ baud_reg = REG_CONTROL_BAUD_RATE_115200;
-+ break;
-+ case PKT_BAUD_RATE_57600:
-+ /* Fall through... */
-+ default:
-+ baud_reg = REG_CONTROL_BAUD_RATE_57600;
-+ break;
-+ }
-+
-+ /* Wait until the command reaches the baseband */
-+ init_waitqueue_head(&wait);
-+ interruptible_sleep_on_timeout(&wait, HZ / 10);
-+
-+ /* Set baud on baseband */
-+ info->ctrl_reg &= ~0x03;
-+ info->ctrl_reg |= baud_reg;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Enable RTS */
-+ info->ctrl_reg &= ~REG_CONTROL_RTS;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Wait before the next HCI packet can be send */
-+ interruptible_sleep_on_timeout(&wait, HZ);
-+
-+ }
-+
-+ if (len == skb->len) {
-+ kfree_skb(skb);
-+ } else {
-+ skb_pull(skb, len);
-+ skb_queue_head(&(info->txq), skb);
-+ }
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ /* Change buffer */
-+ change_bit(XMIT_BUFFER_NUMBER, &(info->tx_state));
-+
-+ } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
-+
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+}
-+
-+
-+static int bluecard_read(unsigned int iobase, unsigned int offset, __u8 *buf, int size)
-+{
-+ int i, n, len;
-+
-+ outb(REG_COMMAND_RX_WIN_ONE, iobase + REG_COMMAND);
-+
-+ len = inb(iobase + offset);
-+ n = 0;
-+ i = 1;
-+
-+ while (n < len) {
-+
-+ if (i == 16) {
-+ outb(REG_COMMAND_RX_WIN_TWO, iobase + REG_COMMAND);
-+ i = 0;
-+ }
-+
-+ buf[n] = inb(iobase + offset + i);
-+
-+ n++;
-+ i++;
-+
-+ }
-+
-+ return len;
-+}
-+
-+
-+static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
-+{
-+ unsigned int iobase;
-+ unsigned char buf[31];
-+ int i, len;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bluecard_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ if (test_bit(XMIT_SENDING_READY, &(info->tx_state)))
-+ bluecard_enable_activity_led(info);
-+
-+ len = bluecard_read(iobase, offset, buf, sizeof(buf));
-+
-+ for (i = 0; i < len; i++) {
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL) {
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "bluecard_cs: Can't allocate mem for new packet.\n");
-+ return;
-+ }
-+ }
-+
-+ if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
-+
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type = buf[i];
-+
-+ switch (info->rx_skb->pkt_type) {
-+
-+ case 0x00:
-+ /* init packet */
-+ if (offset != 0x00) {
-+ set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
-+ set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
-+ set_bit(XMIT_SENDING_READY, &(info->tx_state));
-+ bluecard_write_wakeup(info);
-+ }
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ case HCI_EVENT_PKT:
-+ info->rx_state = RECV_WAIT_EVENT_HEADER;
-+ info->rx_count = HCI_EVENT_HDR_SIZE;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ info->rx_state = RECV_WAIT_ACL_HEADER;
-+ info->rx_count = HCI_ACL_HDR_SIZE;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ info->rx_state = RECV_WAIT_SCO_HEADER;
-+ info->rx_count = HCI_SCO_HDR_SIZE;
-+ break;
-+
-+ default:
-+ /* unknown packet */
-+ printk(KERN_WARNING "bluecard_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-+ info->hdev.stat.err_rx++;
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ } else {
-+
-+ *skb_put(info->rx_skb, 1) = buf[i];
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ int dlen;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+
-+ switch (info->rx_state) {
-+
-+ case RECV_WAIT_EVENT_HEADER:
-+ eh = (hci_event_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = eh->plen;
-+ break;
-+
-+ case RECV_WAIT_ACL_HEADER:
-+ ah = (hci_acl_hdr *)(info->rx_skb->data);
-+ dlen = __le16_to_cpu(ah->dlen);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = dlen;
-+ break;
-+
-+ case RECV_WAIT_SCO_HEADER:
-+ sh = (hci_sco_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = sh->dlen;
-+ break;
-+
-+ case RECV_WAIT_DATA:
-+ hci_recv_frame(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+
-+ }
-+
-+ info->hdev.stat.byte_rx += len;
-+}
-+
-+
-+void bluecard_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ bluecard_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ unsigned char reg;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bluecard_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ if (!test_bit(CARD_READY, &(info->hw_state)))
-+ return;
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ /* Disable interrupt */
-+ info->ctrl_reg &= ~REG_CONTROL_INTERRUPT;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ reg = inb(iobase + REG_INTERRUPT);
-+
-+ if ((reg != 0x00) && (reg != 0xff)) {
-+
-+ if (reg & 0x04) {
-+ bluecard_receive(info, 0x00);
-+ outb(0x04, iobase + REG_INTERRUPT);
-+ outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
-+ }
-+
-+ if (reg & 0x08) {
-+ bluecard_receive(info, 0x10);
-+ outb(0x08, iobase + REG_INTERRUPT);
-+ outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);
-+ }
-+
-+ if (reg & 0x01) {
-+ set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
-+ outb(0x01, iobase + REG_INTERRUPT);
-+ bluecard_write_wakeup(info);
-+ }
-+
-+ if (reg & 0x02) {
-+ set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
-+ outb(0x02, iobase + REG_INTERRUPT);
-+ bluecard_write_wakeup(info);
-+ }
-+
-+ }
-+
-+ /* Enable interrupt */
-+ info->ctrl_reg |= REG_CONTROL_INTERRUPT;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+
-+
-+/* ======================== Device specific HCI commands ======================== */
-+
-+
-+static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-+ struct sk_buff *skb;
-+
-+ /* Ericsson baud rate command */
-+ unsigned char cmd[] = { HCI_COMMAND_PKT, 0x09, 0xfc, 0x01, 0x03 };
-+
-+ if (!(skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "bluecard_cs: Can't allocate mem for new packet.\n");
-+ return -1;
-+ }
-+
-+ switch (baud) {
-+ case 460800:
-+ cmd[4] = 0x00;
-+ skb->pkt_type = PKT_BAUD_RATE_460800;
-+ break;
-+ case 230400:
-+ cmd[4] = 0x01;
-+ skb->pkt_type = PKT_BAUD_RATE_230400;
-+ break;
-+ case 115200:
-+ cmd[4] = 0x02;
-+ skb->pkt_type = PKT_BAUD_RATE_115200;
-+ break;
-+ case 57600:
-+ /* Fall through... */
-+ default:
-+ cmd[4] = 0x03;
-+ skb->pkt_type = PKT_BAUD_RATE_57600;
-+ break;
-+ }
-+
-+ memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
-+
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ bluecard_write_wakeup(info);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int bluecard_hci_flush(struct hci_dev *hdev)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int bluecard_hci_open(struct hci_dev *hdev)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
-+
-+ if (test_and_set_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ /* Enable LED */
-+ outb(0x08 | 0x20, iobase + 0x30);
-+
-+ return 0;
-+}
-+
-+
-+static int bluecard_hci_close(struct hci_dev *hdev)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ bluecard_hci_flush(hdev);
-+
-+ /* Disable LED */
-+ outb(0x00, iobase + 0x30);
-+
-+ return 0;
-+}
-+
-+
-+static int bluecard_hci_send_frame(struct sk_buff *skb)
-+{
-+ bluecard_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+
-+ if (!hdev) {
-+ printk(KERN_WARNING "bluecard_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (bluecard_info_t *)(hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ bluecard_write_wakeup(info);
-+
-+ return 0;
-+}
-+
-+
-+static void bluecard_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+int bluecard_open(bluecard_info_t *info)
-+{
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev;
-+ unsigned char id;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ init_timer(&(info->timer));
-+ info->timer.function = &bluecard_activity_led_timeout;
-+ info->timer.data = (u_long)info;
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ info->rx_skb = NULL;
-+
-+ id = inb(iobase + 0x30);
-+
-+ if ((id & 0x0f) == 0x02)
-+ set_bit(CARD_HAS_PCCARD_ID, &(info->hw_state));
-+
-+ if (id & 0x10)
-+ set_bit(CARD_HAS_POWER_LED, &(info->hw_state));
-+
-+ if (id & 0x20)
-+ set_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state));
-+
-+ /* Reset card */
-+ info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Turn FPGA off */
-+ outb(0x80, iobase + 0x30);
-+
-+ /* Wait some time */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ / 100);
-+
-+ /* Turn FPGA on */
-+ outb(0x00, iobase + 0x30);
-+
-+ /* Activate card */
-+ info->ctrl_reg = REG_CONTROL_BT_ON | REG_CONTROL_BT_RES_PU;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Enable interrupt */
-+ outb(0xff, iobase + REG_INTERRUPT);
-+ info->ctrl_reg |= REG_CONTROL_INTERRUPT;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Start the RX buffers */
-+ outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
-+ outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);
-+
-+ /* Signal that the hardware is ready */
-+ set_bit(CARD_READY, &(info->hw_state));
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ /* Control the point at which RTS is enabled */
-+ outb((0x0f << RTS_LEVEL_SHIFT_BITS) | 1, iobase + REG_RX_CONTROL);
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout((HZ * 5) / 4); // or set it to 3/2
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = bluecard_hci_open;
-+ hdev->close = bluecard_hci_close;
-+ hdev->flush = bluecard_hci_flush;
-+ hdev->send = bluecard_hci_send_frame;
-+ hdev->destruct = bluecard_hci_destruct;
-+ hdev->ioctl = bluecard_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_WARNING "bluecard_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int bluecard_close(bluecard_info_t *info)
-+{
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ bluecard_hci_close(hdev);
-+
-+ clear_bit(CARD_READY, &(info->hw_state));
-+
-+ /* Reset card */
-+ info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Turn FPGA off */
-+ outb(0x80, iobase + 0x30);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_WARNING "bluecard_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+dev_link_t *bluecard_attach(void)
-+{
-+ bluecard_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &bluecard_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = bluecard_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.Vcc = 50;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &bluecard_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ bluecard_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+void bluecard_detach(dev_link_t *link)
-+{
-+ bluecard_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+ if (link->state & DEV_CONFIG)
-+ bluecard_release((u_long)link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+void bluecard_config(dev_link_t *link)
-+{
-+ client_handle_t handle = link->handle;
-+ bluecard_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ config_info_t config;
-+ int i, n, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ link->conf.ConfigIndex = 0x20;
-+ link->io.NumPorts1 = 64;
-+ link->io.IOAddrLines = 6;
-+
-+ for (n = 0; n < 0x400; n += 0x40) {
-+ link->io.BasePort1 = n ^ 0x300;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ break;
-+ }
-+
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (bluecard_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ bluecard_release((u_long)link);
-+}
-+
-+
-+void bluecard_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *)arg;
-+ bluecard_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ bluecard_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+int bluecard_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ bluecard_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ bluecard_close(info);
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ bluecard_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG)
-+ CardServices(ReleaseConfiguration, link->handle);
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (DEV_OK(link))
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_bluecard_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "bluecard_cs: Card Services release does not match!\n");
-+ return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &bluecard_attach, &bluecard_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_bluecard_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ bluecard_detach(dev_list);
-+}
-+
-+
-+module_init(init_bluecard_cs);
-+module_exit(exit_bluecard_cs);
-+
-+EXPORT_NO_SYMBOLS;
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/bluetooth/bt3c_cs.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,946 @@
-+/*
-+ *
-+ * Driver for the 3Com Bluetooth PCMCIA card
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ * Jose Orlando Pereira <jop@di.uminho.pt>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#define __KERNEL_SYSCALLS__
-+
-+#include <linux/kernel.h>
-+#include <linux/kmod.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/delay.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/unistd.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+
-+#include <linux/skbuff.h>
-+#include <linux/string.h>
-+#include <linux/serial.h>
-+#include <linux/serial_reg.h>
-+#include <asm/system.h>
-+#include <asm/bitops.h>
-+#include <asm/io.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0xffff;
-+static int irq_list[4] = { -1 };
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>, Jose Orlando Pereira <jop@di.uminho.pt>");
-+MODULE_DESCRIPTION("BlueZ driver for the 3Com Bluetooth PCMCIA card");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct bt3c_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+} bt3c_info_t;
-+
-+
-+void bt3c_config(dev_link_t *link);
-+void bt3c_release(u_long arg);
-+int bt3c_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "bt3c_cs";
-+
-+dev_link_t *bt3c_attach(void);
-+void bt3c_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_WAITING 8
-+
-+/* Receiver states */
-+#define RECV_WAIT_PACKET_TYPE 0
-+#define RECV_WAIT_EVENT_HEADER 1
-+#define RECV_WAIT_ACL_HEADER 2
-+#define RECV_WAIT_SCO_HEADER 3
-+#define RECV_WAIT_DATA 4
-+
-+
-+
-+/* ======================== Special I/O functions ======================== */
-+
-+
-+#define DATA_L 0
-+#define DATA_H 1
-+#define ADDR_L 2
-+#define ADDR_H 3
-+#define CONTROL 4
-+
-+
-+inline void bt3c_address(unsigned int iobase, unsigned short addr)
-+{
-+ outb(addr & 0xff, iobase + ADDR_L);
-+ outb((addr >> 8) & 0xff, iobase + ADDR_H);
-+}
-+
-+
-+inline void bt3c_put(unsigned int iobase, unsigned short value)
-+{
-+ outb(value & 0xff, iobase + DATA_L);
-+ outb((value >> 8) & 0xff, iobase + DATA_H);
-+}
-+
-+
-+inline void bt3c_io_write(unsigned int iobase, unsigned short addr, unsigned short value)
-+{
-+ bt3c_address(iobase, addr);
-+ bt3c_put(iobase, value);
-+}
-+
-+
-+inline unsigned short bt3c_get(unsigned int iobase)
-+{
-+ unsigned short value = inb(iobase + DATA_L);
-+
-+ value |= inb(iobase + DATA_H) << 8;
-+
-+ return value;
-+}
-+
-+
-+inline unsigned short bt3c_read(unsigned int iobase, unsigned short addr)
-+{
-+ bt3c_address(iobase, addr);
-+
-+ return bt3c_get(iobase);
-+}
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int bt3c_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
-+{
-+ int actual = 0;
-+
-+ bt3c_address(iobase, 0x7080);
-+
-+ /* Fill FIFO with current frame */
-+ while (actual < len) {
-+ /* Transmit next byte */
-+ bt3c_put(iobase, buf[actual]);
-+ actual++;
-+ }
-+
-+ bt3c_io_write(iobase, 0x7005, actual);
-+
-+ return actual;
-+}
-+
-+
-+static void bt3c_write_wakeup(bt3c_info_t *info, int from)
-+{
-+ unsigned long flags;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bt3c_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state)))
-+ return;
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ break;
-+
-+
-+ if (!(skb = skb_dequeue(&(info->txq)))) {
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+ break;
-+ }
-+
-+ /* Send frame */
-+ len = bt3c_write(iobase, 256, skb->data, skb->len);
-+
-+ if (len != skb->len) {
-+ printk(KERN_WARNING "bt3c_cs: very strange\n");
-+ }
-+
-+ kfree_skb(skb);
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ } while (0);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+}
-+
-+
-+static void bt3c_receive(bt3c_info_t *info)
-+{
-+ unsigned int iobase;
-+ int size = 0, avail;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bt3c_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ avail = bt3c_read(iobase, 0x7006);
-+ //printk("bt3c_cs: receiving %d bytes\n", avail);
-+
-+ bt3c_address(iobase, 0x7480);
-+ while (size < avail) {
-+ size++;
-+ info->hdev.stat.byte_rx++;
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL) {
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "bt3c_cs: Can't allocate mem for new packet.\n");
-+ return;
-+ }
-+ }
-+
-+
-+ if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
-+
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type = inb(iobase + DATA_L);
-+ inb(iobase + DATA_H);
-+ //printk("bt3c: PACKET_TYPE=%02x\n", info->rx_skb->pkt_type);
-+
-+ switch (info->rx_skb->pkt_type) {
-+
-+ case HCI_EVENT_PKT:
-+ info->rx_state = RECV_WAIT_EVENT_HEADER;
-+ info->rx_count = HCI_EVENT_HDR_SIZE;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ info->rx_state = RECV_WAIT_ACL_HEADER;
-+ info->rx_count = HCI_ACL_HDR_SIZE;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ info->rx_state = RECV_WAIT_SCO_HEADER;
-+ info->rx_count = HCI_SCO_HDR_SIZE;
-+ break;
-+
-+ default:
-+ /* Unknown packet */
-+ printk(KERN_WARNING "bt3c_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-+ info->hdev.stat.err_rx++;
-+ clear_bit(HCI_RUNNING, &(info->hdev.flags));
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ } else {
-+
-+ __u8 x = inb(iobase + DATA_L);
-+
-+ *skb_put(info->rx_skb, 1) = x;
-+ inb(iobase + DATA_H);
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ int dlen;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+
-+ switch (info->rx_state) {
-+
-+ case RECV_WAIT_EVENT_HEADER:
-+ eh = (hci_event_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = eh->plen;
-+ break;
-+
-+ case RECV_WAIT_ACL_HEADER:
-+ ah = (hci_acl_hdr *)(info->rx_skb->data);
-+ dlen = __le16_to_cpu(ah->dlen);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = dlen;
-+ break;
-+
-+ case RECV_WAIT_SCO_HEADER:
-+ sh = (hci_sco_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = sh->dlen;
-+ break;
-+
-+ case RECV_WAIT_DATA:
-+ hci_recv_frame(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+ bt3c_io_write(iobase, 0x7006, 0x0000);
-+}
-+
-+
-+void bt3c_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ bt3c_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ int iir;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bt3c_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ iir = inb(iobase + CONTROL);
-+ if (iir & 0x80) {
-+ int stat = bt3c_read(iobase, 0x7001);
-+
-+ if ((stat & 0xff) == 0x7f) {
-+ printk(KERN_WARNING "bt3c_cs: STRANGE stat=%04x\n", stat);
-+ } else if ((stat & 0xff) != 0xff) {
-+ if (stat & 0x0020) {
-+ int stat = bt3c_read(iobase, 0x7002) & 0x10;
-+ printk(KERN_WARNING "bt3c_cs: antena %s\n", stat ? "OUT" : "IN");
-+ }
-+ if (stat & 0x0001)
-+ bt3c_receive(info);
-+ if (stat & 0x0002) {
-+ //printk("bt3c_cs: ACK %04x\n", stat);
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+ bt3c_write_wakeup(info, 1);
-+ }
-+
-+ bt3c_io_write(iobase, 0x7001, 0x0000);
-+
-+ outb(iir, iobase + CONTROL);
-+ }
-+ }
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int bt3c_hci_flush(struct hci_dev *hdev)
-+{
-+ bt3c_info_t *info = (bt3c_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int bt3c_hci_open(struct hci_dev *hdev)
-+{
-+ set_bit(HCI_RUNNING, &(hdev->flags));
-+
-+ return 0;
-+}
-+
-+
-+static int bt3c_hci_close(struct hci_dev *hdev)
-+{
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ bt3c_hci_flush(hdev);
-+
-+ return 0;
-+}
-+
-+
-+static int bt3c_hci_send_frame(struct sk_buff *skb)
-+{
-+ bt3c_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+
-+ if (!hdev) {
-+ printk(KERN_WARNING "bt3c_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (bt3c_info_t *) (hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ bt3c_write_wakeup(info, 0);
-+
-+ return 0;
-+}
-+
-+
-+static void bt3c_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== User mode firmware loader ======================== */
-+
-+
-+#define FW_LOADER "/sbin/bluefw"
-+static int errno;
-+
-+
-+static int bt3c_fw_loader_exec(void *dev)
-+{
-+ char *argv[] = { FW_LOADER, "pccard", dev, NULL };
-+ char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
-+ int err;
-+
-+ err = exec_usermodehelper(FW_LOADER, argv, envp);
-+ if (err)
-+ printk(KERN_WARNING "bt3c_cs: Failed to exec \"%s pccard %s\".\n", FW_LOADER, (char *)dev);
-+
-+ return err;
-+}
-+
-+
-+static int bt3c_firmware_load(bt3c_info_t *info)
-+{
-+ sigset_t tmpsig;
-+ char dev[16];
-+ pid_t pid;
-+ int result;
-+
-+ /* Check if root fs is mounted */
-+ if (!current->fs->root) {
-+ printk(KERN_WARNING "bt3c_cs: Root filesystem is not mounted.\n");
-+ return -EPERM;
-+ }
-+
-+ sprintf(dev, "%04x", info->link.io.BasePort1);
-+
-+ pid = kernel_thread(bt3c_fw_loader_exec, (void *)dev, 0);
-+ if (pid < 0) {
-+ printk(KERN_WARNING "bt3c_cs: Forking of kernel thread failed (errno=%d).\n", -pid);
-+ return pid;
-+ }
-+
-+ /* Block signals, everything but SIGKILL/SIGSTOP */
-+ spin_lock_irq(&current->sigmask_lock);
-+ tmpsig = current->blocked;
-+ siginitsetinv(&current->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP));
-+ recalc_sigpending(current);
-+ spin_unlock_irq(&current->sigmask_lock);
-+
-+ result = waitpid(pid, NULL, __WCLONE);
-+
-+ /* Allow signals again */
-+ spin_lock_irq(&current->sigmask_lock);
-+ current->blocked = tmpsig;
-+ recalc_sigpending(current);
-+ spin_unlock_irq(&current->sigmask_lock);
-+
-+ if (result != pid) {
-+ printk(KERN_WARNING "bt3c_cs: Waiting for pid %d failed (errno=%d).\n", pid, -result);
-+ return -result;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+int bt3c_open(bt3c_info_t *info)
-+{
-+ struct hci_dev *hdev;
-+ int err;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ info->rx_skb = NULL;
-+
-+ /* Load firmware */
-+
-+ if ((err = bt3c_firmware_load(info)) < 0)
-+ return err;
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ);
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = bt3c_hci_open;
-+ hdev->close = bt3c_hci_close;
-+ hdev->flush = bt3c_hci_flush;
-+ hdev->send = bt3c_hci_send_frame;
-+ hdev->destruct = bt3c_hci_destruct;
-+ hdev->ioctl = bt3c_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_WARNING "bt3c_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int bt3c_close(bt3c_info_t *info)
-+{
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ bt3c_hci_close(hdev);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_WARNING "bt3c_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+dev_link_t *bt3c_attach(void)
-+{
-+ bt3c_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &bt3c_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = bt3c_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.Vcc = 50;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &bt3c_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ bt3c_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+void bt3c_detach(dev_link_t *link)
-+{
-+ bt3c_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+
-+ if (link->state & DEV_CONFIG)
-+ bt3c_release((u_long)link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+void bt3c_config(dev_link_t *link)
-+{
-+ static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
-+ client_handle_t handle = link->handle;
-+ bt3c_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
-+ int i, j, try, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ /* First pass: look for a config entry that looks normal. */
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-+ /* Two tries: without IO aliases, then with aliases */
-+ for (try = 0; try < 2; try++) {
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if (i != CS_SUCCESS)
-+ goto next_entry;
-+ if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
-+ link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-+ if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
-+ link->conf.ConfigIndex = cf->index;
-+ link->io.BasePort1 = cf->io.win[0].base;
-+ link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+next_entry:
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+ }
-+
-+ /* Second pass: try to find an entry that isn't picky about
-+ its base address, then try to grab any standard serial port
-+ address, and finally try to get any free port. */
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
-+ link->conf.ConfigIndex = cf->index;
-+ for (j = 0; j < 5; j++) {
-+ link->io.BasePort1 = base[j];
-+ link->io.IOAddrLines = base[j] ? 16 : 3;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+ }
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+
-+found_port:
-+ if (i != CS_SUCCESS) {
-+ printk(KERN_NOTICE "bt3c_cs: No usable port range found. Giving up.\n");
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (bt3c_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ bt3c_release((u_long)link);
-+}
-+
-+
-+void bt3c_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *)arg;
-+ bt3c_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ bt3c_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+int bt3c_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ bt3c_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ bt3c_close(info);
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ bt3c_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG)
-+ CardServices(ReleaseConfiguration, link->handle);
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (DEV_OK(link))
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_bt3c_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "bt3c_cs: Card Services release does not match!\n");
-+ return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &bt3c_attach, &bt3c_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_bt3c_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ bt3c_detach(dev_list);
-+}
-+
-+
-+module_init(init_bt3c_cs);
-+module_exit(exit_bt3c_cs);
-+
-+EXPORT_NO_SYMBOLS;
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/bluetooth/btuart_cs.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,906 @@
-+/*
-+ *
-+ * Driver for Bluetooth PCMCIA cards with HCI UART interface
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+
-+#include <linux/skbuff.h>
-+#include <linux/string.h>
-+#include <linux/serial.h>
-+#include <linux/serial_reg.h>
-+#include <asm/system.h>
-+#include <asm/bitops.h>
-+#include <asm/io.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0xffff;
-+static int irq_list[4] = { -1 };
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ driver for Bluetooth PCMCIA cards with HCI UART interface");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct btuart_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+} btuart_info_t;
-+
-+
-+void btuart_config(dev_link_t *link);
-+void btuart_release(u_long arg);
-+int btuart_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "btuart_cs";
-+
-+dev_link_t *btuart_attach(void);
-+void btuart_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+
-+/* Maximum baud rate */
-+#define SPEED_MAX 115200
-+
-+/* Default baud rate: 57600, 115200, 230400 or 460800 */
-+#define DEFAULT_BAUD_RATE 115200
-+
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_WAITING 8
-+
-+/* Receiver states */
-+#define RECV_WAIT_PACKET_TYPE 0
-+#define RECV_WAIT_EVENT_HEADER 1
-+#define RECV_WAIT_ACL_HEADER 2
-+#define RECV_WAIT_SCO_HEADER 3
-+#define RECV_WAIT_DATA 4
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int btuart_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
-+{
-+ int actual = 0;
-+
-+ /* Tx FIFO should be empty */
-+ if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
-+ return 0;
-+
-+ /* Fill FIFO with current frame */
-+ while ((fifo_size-- > 0) && (actual < len)) {
-+ /* Transmit next byte */
-+ outb(buf[actual], iobase + UART_TX);
-+ actual++;
-+ }
-+
-+ return actual;
-+}
-+
-+
-+static void btuart_write_wakeup(btuart_info_t *info)
-+{
-+ if (!info) {
-+ printk(KERN_WARNING "btuart_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ clear_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ return;
-+
-+ if (!(skb = skb_dequeue(&(info->txq))))
-+ break;
-+
-+ /* Send frame */
-+ len = btuart_write(iobase, 16, skb->data, skb->len);
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (len == skb->len) {
-+ kfree_skb(skb);
-+ } else {
-+ skb_pull(skb, len);
-+ skb_queue_head(&(info->txq), skb);
-+ }
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
-+
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+}
-+
-+
-+static void btuart_receive(btuart_info_t *info)
-+{
-+ unsigned int iobase;
-+ int boguscount = 0;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "btuart_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ do {
-+ info->hdev.stat.byte_rx++;
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL) {
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "btuart_cs: Can't allocate mem for new packet.\n");
-+ return;
-+ }
-+ }
-+
-+ if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
-+
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type = inb(iobase + UART_RX);
-+
-+ switch (info->rx_skb->pkt_type) {
-+
-+ case HCI_EVENT_PKT:
-+ info->rx_state = RECV_WAIT_EVENT_HEADER;
-+ info->rx_count = HCI_EVENT_HDR_SIZE;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ info->rx_state = RECV_WAIT_ACL_HEADER;
-+ info->rx_count = HCI_ACL_HDR_SIZE;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ info->rx_state = RECV_WAIT_SCO_HEADER;
-+ info->rx_count = HCI_SCO_HDR_SIZE;
-+ break;
-+
-+ default:
-+ /* Unknown packet */
-+ printk(KERN_WARNING "btuart_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-+ info->hdev.stat.err_rx++;
-+ clear_bit(HCI_RUNNING, &(info->hdev.flags));
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ } else {
-+
-+ *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ int dlen;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+
-+
-+ switch (info->rx_state) {
-+
-+ case RECV_WAIT_EVENT_HEADER:
-+ eh = (hci_event_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = eh->plen;
-+ break;
-+
-+ case RECV_WAIT_ACL_HEADER:
-+ ah = (hci_acl_hdr *)(info->rx_skb->data);
-+ dlen = __le16_to_cpu(ah->dlen);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = dlen;
-+ break;
-+
-+ case RECV_WAIT_SCO_HEADER:
-+ sh = (hci_sco_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = sh->dlen;
-+ break;
-+
-+ case RECV_WAIT_DATA:
-+ hci_recv_frame(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+ /* Make sure we don't stay here to long */
-+ if (boguscount++ > 16)
-+ break;
-+
-+ } while (inb(iobase + UART_LSR) & UART_LSR_DR);
-+}
-+
-+
-+void btuart_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ btuart_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ int boguscount = 0;
-+ int iir, lsr;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "btuart_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-+ while (iir) {
-+
-+ /* Clear interrupt */
-+ lsr = inb(iobase + UART_LSR);
-+
-+ switch (iir) {
-+ case UART_IIR_RLSI:
-+ printk(KERN_NOTICE "btuart_cs: RLSI\n");
-+ break;
-+ case UART_IIR_RDI:
-+ /* Receive interrupt */
-+ btuart_receive(info);
-+ break;
-+ case UART_IIR_THRI:
-+ if (lsr & UART_LSR_THRE) {
-+ /* Transmitter ready for data */
-+ btuart_write_wakeup(info);
-+ }
-+ break;
-+ default:
-+ printk(KERN_NOTICE "btuart_cs: Unhandled IIR=%#x\n", iir);
-+ break;
-+ }
-+
-+ /* Make sure we don't stay here to long */
-+ if (boguscount++ > 100)
-+ break;
-+
-+ iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-+
-+ }
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+
-+static void btuart_change_speed(btuart_info_t *info, unsigned int speed)
-+{
-+ unsigned long flags;
-+ unsigned int iobase;
-+ int fcr; /* FIFO control reg */
-+ int lcr; /* Line control reg */
-+ int divisor;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "btuart_cs: Call of change speed for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ divisor = SPEED_MAX / speed;
-+
-+ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT;
-+
-+ /*
-+ * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and
-+ * almost 1,7 ms at 19200 bps. At speeds above that we can just forget
-+ * about this timeout since it will always be fast enough.
-+ */
-+
-+ if (speed < 38400)
-+ fcr |= UART_FCR_TRIGGER_1;
-+ else
-+ fcr |= UART_FCR_TRIGGER_14;
-+
-+ /* Bluetooth cards use 8N1 */
-+ lcr = UART_LCR_WLEN8;
-+
-+ outb(UART_LCR_DLAB | lcr, iobase + UART_LCR); /* Set DLAB */
-+ outb(divisor & 0xff, iobase + UART_DLL); /* Set speed */
-+ outb(divisor >> 8, iobase + UART_DLM);
-+ outb(lcr, iobase + UART_LCR); /* Set 8N1 */
-+ outb(fcr, iobase + UART_FCR); /* Enable FIFO's */
-+
-+ /* Turn on interrups */
-+ outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+}
-+
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int btuart_hci_flush(struct hci_dev *hdev)
-+{
-+ btuart_info_t *info = (btuart_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int btuart_hci_open(struct hci_dev *hdev)
-+{
-+ set_bit(HCI_RUNNING, &(hdev->flags));
-+
-+ return 0;
-+}
-+
-+
-+static int btuart_hci_close(struct hci_dev *hdev)
-+{
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ btuart_hci_flush(hdev);
-+
-+ return 0;
-+}
-+
-+
-+static int btuart_hci_send_frame(struct sk_buff *skb)
-+{
-+ btuart_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+
-+ if (!hdev) {
-+ printk(KERN_WARNING "btuart_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (btuart_info_t *)(hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ btuart_write_wakeup(info);
-+
-+ return 0;
-+}
-+
-+
-+static void btuart_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+int btuart_open(btuart_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ info->rx_skb = NULL;
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Reset UART */
-+ outb(0, iobase + UART_MCR);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ /* Initialize UART */
-+ outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
-+ outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
-+
-+ /* Turn on interrupts */
-+ // outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ btuart_change_speed(info, DEFAULT_BAUD_RATE);
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ);
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = btuart_hci_open;
-+ hdev->close = btuart_hci_close;
-+ hdev->flush = btuart_hci_flush;
-+ hdev->send = btuart_hci_send_frame;
-+ hdev->destruct = btuart_hci_destruct;
-+ hdev->ioctl = btuart_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_WARNING "btuart_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int btuart_close(btuart_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ btuart_hci_close(hdev);
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Reset UART */
-+ outb(0, iobase + UART_MCR);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_WARNING "btuart_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+dev_link_t *btuart_attach(void)
-+{
-+ btuart_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &btuart_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = btuart_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.Vcc = 50;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &btuart_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ btuart_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+void btuart_detach(dev_link_t *link)
-+{
-+ btuart_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+ if (link->state & DEV_CONFIG)
-+ btuart_release((u_long)link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+void btuart_config(dev_link_t *link)
-+{
-+ static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
-+ client_handle_t handle = link->handle;
-+ btuart_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
-+ int i, j, try, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ /* First pass: look for a config entry that looks normal. */
-+ tuple.TupleData = (cisdata_t *) buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-+ /* Two tries: without IO aliases, then with aliases */
-+ for (try = 0; try < 2; try++) {
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if (i != CS_SUCCESS)
-+ goto next_entry;
-+ if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
-+ link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-+ if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
-+ link->conf.ConfigIndex = cf->index;
-+ link->io.BasePort1 = cf->io.win[0].base;
-+ link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+next_entry:
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+ }
-+
-+ /* Second pass: try to find an entry that isn't picky about
-+ its base address, then try to grab any standard serial port
-+ address, and finally try to get any free port. */
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if ((i == CS_SUCCESS) && (cf->io.nwin > 0)
-+ && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
-+ link->conf.ConfigIndex = cf->index;
-+ for (j = 0; j < 5; j++) {
-+ link->io.BasePort1 = base[j];
-+ link->io.IOAddrLines = base[j] ? 16 : 3;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+ }
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+
-+found_port:
-+ if (i != CS_SUCCESS) {
-+ printk(KERN_NOTICE "btuart_cs: No usable port range found. Giving up.\n");
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (btuart_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ btuart_release((u_long) link);
-+}
-+
-+
-+void btuart_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *)arg;
-+ btuart_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ btuart_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+int btuart_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ btuart_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ btuart_close(info);
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ btuart_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG)
-+ CardServices(ReleaseConfiguration, link->handle);
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (DEV_OK(link))
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_btuart_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "btuart_cs: Card Services release does not match!\n");
-+ return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &btuart_attach, &btuart_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_btuart_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ btuart_detach(dev_list);
-+}
-+
-+
-+module_init(init_btuart_cs);
-+module_exit(exit_btuart_cs);
-+
-+EXPORT_NO_SYMBOLS;
---- linux/drivers/bluetooth/Config.in~bluetooth-2.4.18-mh11 2001-09-07 18:28:38.000000000 +0200
-+++ linux/drivers/bluetooth/Config.in 2004-01-25 23:37:39.000000000 +0100
-@@ -1,8 +1,33 @@
-+#
-+# Bluetooth HCI device drivers configuration
-+#
-+
- mainmenu_option next_comment
- comment 'Bluetooth device drivers'
-
- dep_tristate 'HCI USB driver' CONFIG_BLUEZ_HCIUSB $CONFIG_BLUEZ $CONFIG_USB
-+if [ "$CONFIG_BLUEZ_HCIUSB" != "n" ]; then
-+ bool ' SCO (voice) support' CONFIG_BLUEZ_HCIUSB_SCO
-+fi
-+
- dep_tristate 'HCI UART driver' CONFIG_BLUEZ_HCIUART $CONFIG_BLUEZ
--dep_tristate 'HCI VHCI virtual HCI device driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
-+if [ "$CONFIG_BLUEZ_HCIUART" != "n" ]; then
-+ bool ' UART (H4) protocol support' CONFIG_BLUEZ_HCIUART_H4
-+ bool ' BCSP protocol support' CONFIG_BLUEZ_HCIUART_BCSP
-+ dep_bool ' Transmit CRC with every BCSP packet' CONFIG_BLUEZ_HCIUART_BCSP_TXCRC $CONFIG_BLUEZ_HCIUART_BCSP
-+fi
-+
-+dep_tristate 'HCI BlueFRITZ! USB driver' CONFIG_BLUEZ_HCIBFUSB $CONFIG_BLUEZ $CONFIG_USB
-+
-+dep_tristate 'HCI DTL1 (PC Card) driver' CONFIG_BLUEZ_HCIDTL1 $CONFIG_PCMCIA $CONFIG_BLUEZ
-+
-+dep_tristate 'HCI BT3C (PC Card) driver' CONFIG_BLUEZ_HCIBT3C $CONFIG_PCMCIA $CONFIG_BLUEZ
-+
-+dep_tristate 'HCI BlueCard (PC Card) driver' CONFIG_BLUEZ_HCIBLUECARD $CONFIG_PCMCIA $CONFIG_BLUEZ
-+
-+dep_tristate 'HCI UART (PC Card) driver' CONFIG_BLUEZ_HCIBTUART $CONFIG_PCMCIA $CONFIG_BLUEZ
-+
-+dep_tristate 'HCI VHCI (Virtual HCI device) driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
-
- endmenu
-+
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/bluetooth/dtl1_cs.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,858 @@
-+/*
-+ *
-+ * A driver for Nokia Connectivity Card DTL-1 devices
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+
-+#include <linux/skbuff.h>
-+#include <linux/string.h>
-+#include <linux/serial.h>
-+#include <linux/serial_reg.h>
-+#include <asm/system.h>
-+#include <asm/bitops.h>
-+#include <asm/io.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0xffff;
-+static int irq_list[4] = { -1 };
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ driver for Nokia Connectivity Card DTL-1");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct dtl1_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+
-+ unsigned long flowmask; /* HCI flow mask */
-+ int ri_latch;
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+} dtl1_info_t;
-+
-+
-+void dtl1_config(dev_link_t *link);
-+void dtl1_release(u_long arg);
-+int dtl1_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "dtl1_cs";
-+
-+dev_link_t *dtl1_attach(void);
-+void dtl1_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_WAITING 8
-+
-+/* Receiver States */
-+#define RECV_WAIT_NSH 0
-+#define RECV_WAIT_DATA 1
-+
-+
-+typedef struct {
-+ u8 type;
-+ u8 zero;
-+ u16 len;
-+} __attribute__ ((packed)) nsh_t; /* Nokia Specific Header */
-+
-+#define NSHL 4 /* Nokia Specific Header Length */
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int dtl1_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
-+{
-+ int actual = 0;
-+
-+ /* Tx FIFO should be empty */
-+ if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
-+ return 0;
-+
-+ /* Fill FIFO with current frame */
-+ while ((fifo_size-- > 0) && (actual < len)) {
-+ /* Transmit next byte */
-+ outb(buf[actual], iobase + UART_TX);
-+ actual++;
-+ }
-+
-+ return actual;
-+}
-+
-+
-+static void dtl1_write_wakeup(dtl1_info_t *info)
-+{
-+ if (!info) {
-+ printk(KERN_WARNING "dtl1_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (test_bit(XMIT_WAITING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ clear_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ return;
-+
-+ if (!(skb = skb_dequeue(&(info->txq))))
-+ break;
-+
-+ /* Send frame */
-+ len = dtl1_write(iobase, 32, skb->data, skb->len);
-+
-+ if (len == skb->len) {
-+ set_bit(XMIT_WAITING, &(info->tx_state));
-+ kfree_skb(skb);
-+ } else {
-+ skb_pull(skb, len);
-+ skb_queue_head(&(info->txq), skb);
-+ }
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
-+
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+}
-+
-+
-+static void dtl1_control(dtl1_info_t *info, struct sk_buff *skb)
-+{
-+ u8 flowmask = *(u8 *)skb->data;
-+ int i;
-+
-+ printk(KERN_INFO "dtl1_cs: Nokia control data = ");
-+ for (i = 0; i < skb->len; i++) {
-+ printk("%02x ", skb->data[i]);
-+ }
-+ printk("\n");
-+
-+ /* transition to active state */
-+ if (((info->flowmask & 0x07) == 0) && ((flowmask & 0x07) != 0)) {
-+ clear_bit(XMIT_WAITING, &(info->tx_state));
-+ dtl1_write_wakeup(info);
-+ }
-+
-+ info->flowmask = flowmask;
-+
-+ kfree_skb(skb);
-+}
-+
-+
-+static void dtl1_receive(dtl1_info_t *info)
-+{
-+ unsigned int iobase;
-+ nsh_t *nsh;
-+ int boguscount = 0;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "dtl1_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ do {
-+ info->hdev.stat.byte_rx++;
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL)
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "dtl1_cs: Can't allocate mem for new packet.\n");
-+ info->rx_state = RECV_WAIT_NSH;
-+ info->rx_count = NSHL;
-+ return;
-+ }
-+
-+ *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
-+ nsh = (nsh_t *)info->rx_skb->data;
-+
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ switch (info->rx_state) {
-+ case RECV_WAIT_NSH:
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = nsh->len + (nsh->len & 0x0001);
-+ break;
-+ case RECV_WAIT_DATA:
-+ info->rx_skb->pkt_type = nsh->type;
-+
-+ /* remove PAD byte if it exists */
-+ if (nsh->len & 0x0001) {
-+ info->rx_skb->tail--;
-+ info->rx_skb->len--;
-+ }
-+
-+ /* remove NSH */
-+ skb_pull(info->rx_skb, NSHL);
-+
-+ switch (info->rx_skb->pkt_type) {
-+ case 0x80:
-+ /* control data for the Nokia Card */
-+ dtl1_control(info, info->rx_skb);
-+ break;
-+ case 0x82:
-+ case 0x83:
-+ case 0x84:
-+ /* send frame to the HCI layer */
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type &= 0x0f;
-+ hci_recv_frame(info->rx_skb);
-+ break;
-+ default:
-+ /* unknown packet */
-+ printk(KERN_WARNING "dtl1_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-+ kfree_skb(info->rx_skb);
-+ break;
-+ }
-+
-+ info->rx_state = RECV_WAIT_NSH;
-+ info->rx_count = NSHL;
-+ info->rx_skb = NULL;
-+ break;
-+ }
-+
-+ }
-+
-+ /* Make sure we don't stay here to long */
-+ if (boguscount++ > 32)
-+ break;
-+
-+ } while (inb(iobase + UART_LSR) & UART_LSR_DR);
-+}
-+
-+
-+void dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ dtl1_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ unsigned char msr;
-+ int boguscount = 0;
-+ int iir, lsr;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "dtl1_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-+ while (iir) {
-+
-+ /* Clear interrupt */
-+ lsr = inb(iobase + UART_LSR);
-+
-+ switch (iir) {
-+ case UART_IIR_RLSI:
-+ printk(KERN_NOTICE "dtl1_cs: RLSI\n");
-+ break;
-+ case UART_IIR_RDI:
-+ /* Receive interrupt */
-+ dtl1_receive(info);
-+ break;
-+ case UART_IIR_THRI:
-+ if (lsr & UART_LSR_THRE) {
-+ /* Transmitter ready for data */
-+ dtl1_write_wakeup(info);
-+ }
-+ break;
-+ default:
-+ printk(KERN_NOTICE "dtl1_cs: Unhandled IIR=%#x\n", iir);
-+ break;
-+ }
-+
-+ /* Make sure we don't stay here to long */
-+ if (boguscount++ > 100)
-+ break;
-+
-+ iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-+
-+ }
-+
-+ msr = inb(iobase + UART_MSR);
-+
-+ if (info->ri_latch ^ (msr & UART_MSR_RI)) {
-+ info->ri_latch = msr & UART_MSR_RI;
-+ clear_bit(XMIT_WAITING, &(info->tx_state));
-+ dtl1_write_wakeup(info);
-+ }
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int dtl1_hci_open(struct hci_dev *hdev)
-+{
-+ set_bit(HCI_RUNNING, &(hdev->flags));
-+
-+ return 0;
-+}
-+
-+
-+static int dtl1_hci_flush(struct hci_dev *hdev)
-+{
-+ dtl1_info_t *info = (dtl1_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int dtl1_hci_close(struct hci_dev *hdev)
-+{
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ dtl1_hci_flush(hdev);
-+
-+ return 0;
-+}
-+
-+
-+static int dtl1_hci_send_frame(struct sk_buff *skb)
-+{
-+ dtl1_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+ struct sk_buff *s;
-+ nsh_t nsh;
-+
-+ if (!hdev) {
-+ printk(KERN_WARNING "dtl1_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (dtl1_info_t *)(hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ nsh.type = 0x81;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ nsh.type = 0x82;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ nsh.type = 0x83;
-+ break;
-+ };
-+
-+ nsh.zero = 0;
-+ nsh.len = skb->len;
-+
-+ s = bluez_skb_alloc(NSHL + skb->len + 1, GFP_ATOMIC);
-+ skb_reserve(s, NSHL);
-+ memcpy(skb_put(s, skb->len), skb->data, skb->len);
-+ if (skb->len & 0x0001)
-+ *skb_put(s, 1) = 0; /* PAD */
-+
-+ /* Prepend skb with Nokia frame header and queue */
-+ memcpy(skb_push(s, NSHL), &nsh, NSHL);
-+ skb_queue_tail(&(info->txq), s);
-+
-+ dtl1_write_wakeup(info);
-+
-+ kfree_skb(skb);
-+
-+ return 0;
-+}
-+
-+
-+static void dtl1_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+int dtl1_open(dtl1_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_NSH;
-+ info->rx_count = NSHL;
-+ info->rx_skb = NULL;
-+
-+ set_bit(XMIT_WAITING, &(info->tx_state));
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Reset UART */
-+ outb(0, iobase + UART_MCR);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ /* Initialize UART */
-+ outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
-+ outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
-+
-+ info->ri_latch = inb(info->link.io.BasePort1 + UART_MSR) & UART_MSR_RI;
-+
-+ /* Turn on interrupts */
-+ outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ * 2);
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = dtl1_hci_open;
-+ hdev->close = dtl1_hci_close;
-+ hdev->flush = dtl1_hci_flush;
-+ hdev->send = dtl1_hci_send_frame;
-+ hdev->destruct = dtl1_hci_destruct;
-+ hdev->ioctl = dtl1_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_WARNING "dtl1_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int dtl1_close(dtl1_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ dtl1_hci_close(hdev);
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Reset UART */
-+ outb(0, iobase + UART_MCR);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_WARNING "dtl1_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+dev_link_t *dtl1_attach(void)
-+{
-+ dtl1_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &dtl1_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = dtl1_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.Vcc = 50;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &dtl1_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ dtl1_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+void dtl1_detach(dev_link_t *link)
-+{
-+ dtl1_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+ if (link->state & DEV_CONFIG)
-+ dtl1_release((u_long)link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+void dtl1_config(dev_link_t *link)
-+{
-+ client_handle_t handle = link->handle;
-+ dtl1_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
-+ int i, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-+
-+ /* Look for a generic full-sized window */
-+ link->io.NumPorts1 = 8;
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
-+ link->conf.ConfigIndex = cf->index;
-+ link->io.BasePort1 = cf->io.win[0].base;
-+ link->io.NumPorts1 = cf->io.win[0].len; /*yo */
-+ link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ break;
-+ }
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (dtl1_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ dtl1_release((u_long)link);
-+}
-+
-+
-+void dtl1_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *)arg;
-+ dtl1_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ dtl1_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+int dtl1_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ dtl1_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ dtl1_close(info);
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ dtl1_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG)
-+ CardServices(ReleaseConfiguration, link->handle);
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (DEV_OK(link))
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_dtl1_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "dtl1_cs: Card Services release does not match!\n");
-+ return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &dtl1_attach, &dtl1_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_dtl1_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ dtl1_detach(dev_list);
-+}
-+
-+
-+module_init(init_dtl1_cs);
-+module_exit(exit_dtl1_cs);
-+
-+EXPORT_NO_SYMBOLS;
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/bluetooth/hci_bcsp.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,710 @@
-+/*
-+ BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
-+ Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com>
-+
-+ Based on
-+ hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com>
-+ ABCSP by Carl Orsborn <cjo@csr.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#define VERSION "0.1"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/version.h>
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/types.h>
-+#include <linux/fcntl.h>
-+#include <linux/interrupt.h>
-+#include <linux/ptrace.h>
-+#include <linux/poll.h>
-+
-+#include <linux/slab.h>
-+#include <linux/tty.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/signal.h>
-+#include <linux/ioctl.h>
-+#include <linux/skbuff.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include "hci_uart.h"
-+#include "hci_bcsp.h"
-+
-+#ifndef HCI_UART_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#undef BT_DMP
-+#define BT_DMP( A... )
-+#endif
-+
-+/* ---- BCSP CRC calculation ---- */
-+
-+/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
-+initial value 0xffff, bits shifted in reverse order. */
-+
-+static const u16 crc_table[] = {
-+ 0x0000, 0x1081, 0x2102, 0x3183,
-+ 0x4204, 0x5285, 0x6306, 0x7387,
-+ 0x8408, 0x9489, 0xa50a, 0xb58b,
-+ 0xc60c, 0xd68d, 0xe70e, 0xf78f
-+};
-+
-+/* Initialise the crc calculator */
-+#define BCSP_CRC_INIT(x) x = 0xffff
-+
-+/*
-+ Update crc with next data byte
-+
-+ Implementation note
-+ The data byte is treated as two nibbles. The crc is generated
-+ in reverse, i.e., bits are fed into the register from the top.
-+*/
-+static void bcsp_crc_update(u16 *crc, u8 d)
-+{
-+ u16 reg = *crc;
-+
-+ reg = (reg >> 4) ^ crc_table[(reg ^ d) & 0x000f];
-+ reg = (reg >> 4) ^ crc_table[(reg ^ (d >> 4)) & 0x000f];
-+
-+ *crc = reg;
-+}
-+
-+/*
-+ Get reverse of generated crc
-+
-+ Implementation note
-+ The crc generator (bcsp_crc_init() and bcsp_crc_update())
-+ creates a reversed crc, so it needs to be swapped back before
-+ being passed on.
-+*/
-+static u16 bcsp_crc_reverse(u16 crc)
-+{
-+ u16 b, rev;
-+
-+ for (b = 0, rev = 0; b < 16; b++) {
-+ rev = rev << 1;
-+ rev |= (crc & 1);
-+ crc = crc >> 1;
-+ }
-+ return (rev);
-+}
-+
-+/* ---- BCSP core ---- */
-+
-+static void bcsp_slip_msgdelim(struct sk_buff *skb)
-+{
-+ const char pkt_delim = 0xc0;
-+ memcpy(skb_put(skb, 1), &pkt_delim, 1);
-+}
-+
-+static void bcsp_slip_one_byte(struct sk_buff *skb, u8 c)
-+{
-+ const char esc_c0[2] = { 0xdb, 0xdc };
-+ const char esc_db[2] = { 0xdb, 0xdd };
-+
-+ switch (c) {
-+ case 0xc0:
-+ memcpy(skb_put(skb, 2), &esc_c0, 2);
-+ break;
-+ case 0xdb:
-+ memcpy(skb_put(skb, 2), &esc_db, 2);
-+ break;
-+ default:
-+ memcpy(skb_put(skb, 1), &c, 1);
-+ }
-+}
-+
-+static int bcsp_enqueue(struct hci_uart *hu, struct sk_buff *skb)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+
-+ if (skb->len > 0xFFF) {
-+ BT_ERR("Packet too long");
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+
-+ switch (skb->pkt_type) {
-+ case HCI_ACLDATA_PKT:
-+ case HCI_COMMAND_PKT:
-+ skb_queue_tail(&bcsp->rel, skb);
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ skb_queue_tail(&bcsp->unrel, skb);
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown packet type");
-+ kfree_skb(skb);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
-+ int len, int pkt_type)
-+{
-+ struct sk_buff *nskb;
-+ u8 hdr[4], chan;
-+ int rel, i;
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
-+#endif
-+
-+ switch (pkt_type) {
-+ case HCI_ACLDATA_PKT:
-+ chan = 6; /* BCSP ACL channel */
-+ rel = 1; /* reliable channel */
-+ break;
-+ case HCI_COMMAND_PKT:
-+ chan = 5; /* BCSP cmd/evt channel */
-+ rel = 1; /* reliable channel */
-+ break;
-+ case HCI_SCODATA_PKT:
-+ chan = 7; /* BCSP SCO channel */
-+ rel = 0; /* unreliable channel */
-+ break;
-+ case BCSP_LE_PKT:
-+ chan = 1; /* BCSP LE channel */
-+ rel = 0; /* unreliable channel */
-+ break;
-+ case BCSP_ACK_PKT:
-+ chan = 0; /* BCSP internal channel */
-+ rel = 0; /* unreliable channel */
-+ break;
-+ default:
-+ BT_ERR("Unknown packet type");
-+ return NULL;
-+ }
-+
-+ /* Max len of packet: (original len +4(bcsp hdr) +2(crc))*2
-+ (because bytes 0xc0 and 0xdb are escaped, worst case is
-+ when the packet is all made of 0xc0 and 0xdb :) )
-+ + 2 (0xc0 delimiters at start and end). */
-+
-+ nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC);
-+ if (!nskb)
-+ return NULL;
-+
-+ nskb->pkt_type = pkt_type;
-+
-+ bcsp_slip_msgdelim(nskb);
-+
-+ hdr[0] = bcsp->rxseq_txack << 3;
-+ bcsp->txack_req = 0;
-+ BT_DBG("We request packet no %u to card", bcsp->rxseq_txack);
-+
-+ if (rel) {
-+ hdr[0] |= 0x80 + bcsp->msgq_txseq;
-+ BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
-+ bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07;
-+ }
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ hdr[0] |= 0x40;
-+#endif
-+
-+ hdr[1] = (len << 4) & 0xFF;
-+ hdr[1] |= chan;
-+ hdr[2] = len >> 4;
-+ hdr[3] = ~(hdr[0] + hdr[1] + hdr[2]);
-+
-+ /* Put BCSP header */
-+ for (i = 0; i < 4; i++) {
-+ bcsp_slip_one_byte(nskb, hdr[i]);
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
-+#endif
-+ }
-+
-+ /* Put payload */
-+ for (i = 0; i < len; i++) {
-+ bcsp_slip_one_byte(nskb, data[i]);
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
-+#endif
-+ }
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ /* Put CRC */
-+ bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
-+ bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
-+ bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
-+#endif
-+
-+ bcsp_slip_msgdelim(nskb);
-+ return nskb;
-+}
-+
-+/* This is a rewrite of pkt_avail in ABCSP */
-+static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
-+ unsigned long flags;
-+ struct sk_buff *skb;
-+
-+ /* First of all, check for unreliable messages in the queue,
-+ since they have priority */
-+
-+ if ((skb = skb_dequeue(&bcsp->unrel)) != NULL) {
-+ struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
-+ if (nskb) {
-+ kfree_skb(skb);
-+ return nskb;
-+ } else {
-+ skb_queue_head(&bcsp->unrel, skb);
-+ BT_ERR("Could not dequeue pkt because alloc_skb failed");
-+ }
-+ }
-+
-+ /* Now, try to send a reliable pkt. We can only send a
-+ reliable packet if the number of packets sent but not yet ack'ed
-+ is < than the winsize */
-+
-+ spin_lock_irqsave(&bcsp->unack.lock, flags);
-+
-+ if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) {
-+ struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
-+ if (nskb) {
-+ __skb_queue_tail(&bcsp->unack, skb);
-+ mod_timer(&bcsp->tbcsp, jiffies + HZ / 4);
-+ spin_unlock_irqrestore(&bcsp->unack.lock, flags);
-+ return nskb;
-+ } else {
-+ skb_queue_head(&bcsp->rel, skb);
-+ BT_ERR("Could not dequeue pkt because alloc_skb failed");
-+ }
-+ }
-+
-+ spin_unlock_irqrestore(&bcsp->unack.lock, flags);
-+
-+
-+ /* We could not send a reliable packet, either because there are
-+ none or because there are too many unack'ed pkts. Did we receive
-+ any packets we have not acknowledged yet ? */
-+
-+ if (bcsp->txack_req) {
-+ /* if so, craft an empty ACK pkt and send it on BCSP unreliable
-+ channel 0 */
-+ struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, NULL, 0, BCSP_ACK_PKT);
-+ return nskb;
-+ }
-+
-+ /* We have nothing to send */
-+ return NULL;
-+}
-+
-+static int bcsp_flush(struct hci_uart *hu)
-+{
-+ BT_DBG("hu %p", hu);
-+ return 0;
-+}
-+
-+/* Remove ack'ed packets */
-+static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
-+{
-+ unsigned long flags;
-+ struct sk_buff *skb;
-+ int i, pkts_to_be_removed;
-+ u8 seqno;
-+
-+ spin_lock_irqsave(&bcsp->unack.lock, flags);
-+
-+ pkts_to_be_removed = bcsp->unack.qlen;
-+ seqno = bcsp->msgq_txseq;
-+
-+ while (pkts_to_be_removed) {
-+ if (bcsp->rxack == seqno)
-+ break;
-+ pkts_to_be_removed--;
-+ seqno = (seqno - 1) & 0x07;
-+ }
-+
-+ if (bcsp->rxack != seqno)
-+ BT_ERR("Peer acked invalid packet");
-+
-+ BT_DBG("Removing %u pkts out of %u, up to seqno %u",
-+ pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07);
-+
-+ for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed
-+ && skb != (struct sk_buff *) &bcsp->unack; i++) {
-+ struct sk_buff *nskb;
-+
-+ nskb = skb->next;
-+ __skb_unlink(skb, &bcsp->unack);
-+ kfree_skb(skb);
-+ skb = nskb;
-+ }
-+ if (bcsp->unack.qlen == 0)
-+ del_timer(&bcsp->tbcsp);
-+ spin_unlock_irqrestore(&bcsp->unack.lock, flags);
-+
-+ if (i != pkts_to_be_removed)
-+ BT_ERR("Removed only %u out of %u pkts", i, pkts_to_be_removed);
-+}
-+
-+/* Handle BCSP link-establishment packets. When we
-+ detect a "sync" packet, symptom that the BT module has reset,
-+ we do nothing :) (yet) */
-+static void bcsp_handle_le_pkt(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+ u8 conf_pkt[4] = { 0xad, 0xef, 0xac, 0xed };
-+ u8 conf_rsp_pkt[4] = { 0xde, 0xad, 0xd0, 0xd0 };
-+ u8 sync_pkt[4] = { 0xda, 0xdc, 0xed, 0xed };
-+
-+ /* spot "conf" pkts and reply with a "conf rsp" pkt */
-+ if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
-+ !memcmp(&bcsp->rx_skb->data[4], conf_pkt, 4)) {
-+ struct sk_buff *nskb = alloc_skb(4, GFP_ATOMIC);
-+
-+ BT_DBG("Found a LE conf pkt");
-+ if (!nskb)
-+ return;
-+ memcpy(skb_put(nskb, 4), conf_rsp_pkt, 4);
-+ nskb->pkt_type = BCSP_LE_PKT;
-+
-+ skb_queue_head(&bcsp->unrel, nskb);
-+ hci_uart_tx_wakeup(hu);
-+ }
-+ /* Spot "sync" pkts. If we find one...disaster! */
-+ else if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
-+ !memcmp(&bcsp->rx_skb->data[4], sync_pkt, 4)) {
-+ BT_ERR("Found a LE sync pkt, card has reset");
-+ }
-+}
-+
-+static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char byte)
-+{
-+ const u8 c0 = 0xc0, db = 0xdb;
-+
-+ switch (bcsp->rx_esc_state) {
-+ case BCSP_ESCSTATE_NOESC:
-+ switch (byte) {
-+ case 0xdb:
-+ bcsp->rx_esc_state = BCSP_ESCSTATE_ESC;
-+ break;
-+ default:
-+ memcpy(skb_put(bcsp->rx_skb, 1), &byte, 1);
-+ if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
-+ bcsp->rx_state != BCSP_W4_CRC)
-+ bcsp_crc_update(&bcsp->message_crc, byte);
-+ bcsp->rx_count--;
-+ }
-+ break;
-+
-+ case BCSP_ESCSTATE_ESC:
-+ switch (byte) {
-+ case 0xdc:
-+ memcpy(skb_put(bcsp->rx_skb, 1), &c0, 1);
-+ if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
-+ bcsp->rx_state != BCSP_W4_CRC)
-+ bcsp_crc_update(&bcsp-> message_crc, 0xc0);
-+ bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
-+ bcsp->rx_count--;
-+ break;
-+
-+ case 0xdd:
-+ memcpy(skb_put(bcsp->rx_skb, 1), &db, 1);
-+ if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
-+ bcsp->rx_state != BCSP_W4_CRC)
-+ bcsp_crc_update(&bcsp-> message_crc, 0xdb);
-+ bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
-+ bcsp->rx_count--;
-+ break;
-+
-+ default:
-+ BT_ERR ("Invalid byte %02x after esc byte", byte);
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_skb = NULL;
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ }
-+ }
-+}
-+
-+static inline void bcsp_complete_rx_pkt(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+ int pass_up;
-+
-+ if (bcsp->rx_skb->data[0] & 0x80) { /* reliable pkt */
-+ BT_DBG("Received seqno %u from card", bcsp->rxseq_txack);
-+ bcsp->rxseq_txack++;
-+ bcsp->rxseq_txack %= 0x8;
-+ bcsp->txack_req = 1;
-+
-+ /* If needed, transmit an ack pkt */
-+ hci_uart_tx_wakeup(hu);
-+ }
-+
-+ bcsp->rxack = (bcsp->rx_skb->data[0] >> 3) & 0x07;
-+ BT_DBG("Request for pkt %u from card", bcsp->rxack);
-+
-+ bcsp_pkt_cull(bcsp);
-+ if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
-+ bcsp->rx_skb->data[0] & 0x80) {
-+ bcsp->rx_skb->pkt_type = HCI_ACLDATA_PKT;
-+ pass_up = 1;
-+ } else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
-+ bcsp->rx_skb->data[0] & 0x80) {
-+ bcsp->rx_skb->pkt_type = HCI_EVENT_PKT;
-+ pass_up = 1;
-+ } else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
-+ bcsp->rx_skb->pkt_type = HCI_SCODATA_PKT;
-+ pass_up = 1;
-+ } else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 &&
-+ !(bcsp->rx_skb->data[0] & 0x80)) {
-+ bcsp_handle_le_pkt(hu);
-+ pass_up = 0;
-+ } else
-+ pass_up = 0;
-+
-+ if (!pass_up) {
-+ if ((bcsp->rx_skb->data[1] & 0x0f) != 0 &&
-+ (bcsp->rx_skb->data[1] & 0x0f) != 1) {
-+ BT_ERR ("Packet for unknown channel (%u %s)",
-+ bcsp->rx_skb->data[1] & 0x0f,
-+ bcsp->rx_skb->data[0] & 0x80 ?
-+ "reliable" : "unreliable");
-+ }
-+ kfree_skb(bcsp->rx_skb);
-+ } else {
-+ /* Pull out BCSP hdr */
-+ skb_pull(bcsp->rx_skb, 4);
-+
-+ hci_recv_frame(bcsp->rx_skb);
-+ }
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_skb = NULL;
-+}
-+
-+/* Recv data */
-+static int bcsp_recv(struct hci_uart *hu, void *data, int count)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+ register unsigned char *ptr;
-+
-+ BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
-+ hu, count, bcsp->rx_state, bcsp->rx_count);
-+
-+ ptr = data;
-+ while (count) {
-+ if (bcsp->rx_count) {
-+ if (*ptr == 0xc0) {
-+ BT_ERR("Short BCSP packet");
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_state = BCSP_W4_PKT_START;
-+ bcsp->rx_count = 0;
-+ } else
-+ bcsp_unslip_one_byte(bcsp, *ptr);
-+
-+ ptr++; count--;
-+ continue;
-+ }
-+
-+ switch (bcsp->rx_state) {
-+ case BCSP_W4_BCSP_HDR:
-+ if ((0xff & (u8) ~ (bcsp->rx_skb->data[0] + bcsp->rx_skb->data[1] +
-+ bcsp->rx_skb->data[2])) != bcsp->rx_skb->data[3]) {
-+ BT_ERR("Error in BCSP hdr checksum");
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ continue;
-+ }
-+ if (bcsp->rx_skb->data[0] & 0x80 /* reliable pkt */
-+ && (bcsp->rx_skb->data[0] & 0x07) != bcsp->rxseq_txack) {
-+ BT_ERR ("Out-of-order packet arrived, got %u expected %u",
-+ bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);
-+
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ continue;
-+ }
-+ bcsp->rx_state = BCSP_W4_DATA;
-+ bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) +
-+ (bcsp->rx_skb->data[2] << 4); /* May be 0 */
-+ continue;
-+
-+ case BCSP_W4_DATA:
-+ if (bcsp->rx_skb->data[0] & 0x40) { /* pkt with crc */
-+ bcsp->rx_state = BCSP_W4_CRC;
-+ bcsp->rx_count = 2;
-+ } else
-+ bcsp_complete_rx_pkt(hu);
-+ continue;
-+
-+ case BCSP_W4_CRC:
-+ if (bcsp_crc_reverse(bcsp->message_crc) !=
-+ (bcsp->rx_skb->data[bcsp->rx_skb->len - 2] << 8) +
-+ bcsp->rx_skb->data[bcsp->rx_skb->len - 1]) {
-+
-+ BT_ERR ("Checksum failed: computed %04x received %04x",
-+ bcsp_crc_reverse(bcsp->message_crc),
-+ (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) +
-+ bcsp->rx_skb->data[bcsp->rx_skb->len - 1]);
-+
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ continue;
-+ }
-+ skb_trim(bcsp->rx_skb, bcsp->rx_skb->len - 2);
-+ bcsp_complete_rx_pkt(hu);
-+ continue;
-+
-+ case BCSP_W4_PKT_DELIMITER:
-+ switch (*ptr) {
-+ case 0xc0:
-+ bcsp->rx_state = BCSP_W4_PKT_START;
-+ break;
-+ default:
-+ /*BT_ERR("Ignoring byte %02x", *ptr);*/
-+ break;
-+ }
-+ ptr++; count--;
-+ break;
-+
-+ case BCSP_W4_PKT_START:
-+ switch (*ptr) {
-+ case 0xc0:
-+ ptr++; count--;
-+ break;
-+
-+ default:
-+ bcsp->rx_state = BCSP_W4_BCSP_HDR;
-+ bcsp->rx_count = 4;
-+ bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
-+ BCSP_CRC_INIT(bcsp->message_crc);
-+
-+ /* Do not increment ptr or decrement count
-+ * Allocate packet. Max len of a BCSP pkt=
-+ * 0xFFF (payload) +4 (header) +2 (crc) */
-+
-+ bcsp->rx_skb = bluez_skb_alloc(0x1005, GFP_ATOMIC);
-+ if (!bcsp->rx_skb) {
-+ BT_ERR("Can't allocate mem for new packet");
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ return 0;
-+ }
-+ bcsp->rx_skb->dev = (void *) &hu->hdev;
-+ break;
-+ }
-+ break;
-+ }
-+ }
-+ return count;
-+}
-+
-+ /* Arrange to retransmit all messages in the relq. */
-+static void bcsp_timed_event(unsigned long arg)
-+{
-+ struct hci_uart *hu = (struct hci_uart *) arg;
-+ struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
-+ struct sk_buff *skb;
-+ unsigned long flags;
-+
-+ BT_ERR("Timeout, retransmitting %u pkts", bcsp->unack.qlen);
-+ spin_lock_irqsave(&bcsp->unack.lock, flags);
-+
-+ while ((skb = __skb_dequeue_tail(&bcsp->unack)) != NULL) {
-+ bcsp->msgq_txseq = (bcsp->msgq_txseq - 1) & 0x07;
-+ skb_queue_head(&bcsp->rel, skb);
-+ }
-+
-+ spin_unlock_irqrestore(&bcsp->unack.lock, flags);
-+
-+ hci_uart_tx_wakeup(hu);
-+}
-+
-+static int bcsp_open(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp;
-+
-+ BT_DBG("hu %p", hu);
-+
-+ bcsp = kmalloc(sizeof(*bcsp), GFP_ATOMIC);
-+ if (!bcsp)
-+ return -ENOMEM;
-+ memset(bcsp, 0, sizeof(*bcsp));
-+
-+ hu->priv = bcsp;
-+ skb_queue_head_init(&bcsp->unack);
-+ skb_queue_head_init(&bcsp->rel);
-+ skb_queue_head_init(&bcsp->unrel);
-+
-+ init_timer(&bcsp->tbcsp);
-+ bcsp->tbcsp.function = bcsp_timed_event;
-+ bcsp->tbcsp.data = (u_long) hu;
-+
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+
-+ return 0;
-+}
-+
-+static int bcsp_close(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+ hu->priv = NULL;
-+
-+ BT_DBG("hu %p", hu);
-+
-+ skb_queue_purge(&bcsp->unack);
-+ skb_queue_purge(&bcsp->rel);
-+ skb_queue_purge(&bcsp->unrel);
-+ del_timer(&bcsp->tbcsp);
-+
-+ kfree(bcsp);
-+ return 0;
-+}
-+
-+static struct hci_uart_proto bcsp = {
-+ id: HCI_UART_BCSP,
-+ open: bcsp_open,
-+ close: bcsp_close,
-+ enqueue: bcsp_enqueue,
-+ dequeue: bcsp_dequeue,
-+ recv: bcsp_recv,
-+ flush: bcsp_flush
-+};
-+
-+int bcsp_init(void)
-+{
-+ return hci_uart_register_proto(&bcsp);
-+}
-+
-+int bcsp_deinit(void)
-+{
-+ return hci_uart_unregister_proto(&bcsp);
-+}
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/bluetooth/hci_bcsp.h 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,70 @@
-+/*
-+ BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
-+ Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com>
-+
-+ Based on
-+ hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com>
-+ ABCSP by Carl Orsborn <cjo@csr.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef __HCI_BCSP_H__
-+#define __HCI_BCSP_H__
-+
-+#define BCSP_TXWINSIZE 4
-+
-+#define BCSP_ACK_PKT 0x05
-+#define BCSP_LE_PKT 0x06
-+
-+struct bcsp_struct {
-+ struct sk_buff_head unack; /* Unack'ed packets queue */
-+ struct sk_buff_head rel; /* Reliable packets queue */
-+ struct sk_buff_head unrel; /* Unreliable packets queue */
-+
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+ u8 rxseq_txack; /* rxseq == txack. */
-+ u8 rxack; /* Last packet sent by us that the peer ack'ed */
-+ struct timer_list tbcsp;
-+
-+ enum {
-+ BCSP_W4_PKT_DELIMITER,
-+ BCSP_W4_PKT_START,
-+ BCSP_W4_BCSP_HDR,
-+ BCSP_W4_DATA,
-+ BCSP_W4_CRC
-+ } rx_state;
-+
-+ enum {
-+ BCSP_ESCSTATE_NOESC,
-+ BCSP_ESCSTATE_ESC
-+ } rx_esc_state;
-+
-+ u16 message_crc;
-+ u8 txack_req; /* Do we need to send ack's to the peer? */
-+
-+ /* Reliable packet sequence number - used to assign seq to each rel pkt. */
-+ u8 msgq_txseq;
-+};
-+
-+#endif /* __HCI_BCSP_H__ */
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/bluetooth/hci_h4.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,277 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * BlueZ HCI UART(H4) protocol.
-+ *
-+ * $Id$
-+ */
-+#define VERSION "1.2"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/types.h>
-+#include <linux/fcntl.h>
-+#include <linux/interrupt.h>
-+#include <linux/ptrace.h>
-+#include <linux/poll.h>
-+
-+#include <linux/slab.h>
-+#include <linux/tty.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/signal.h>
-+#include <linux/ioctl.h>
-+#include <linux/skbuff.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include "hci_uart.h"
-+#include "hci_h4.h"
-+
-+#ifndef HCI_UART_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#undef BT_DMP
-+#define BT_DMP( A... )
-+#endif
-+
-+/* Initialize protocol */
-+static int h4_open(struct hci_uart *hu)
-+{
-+ struct h4_struct *h4;
-+
-+ BT_DBG("hu %p", hu);
-+
-+ h4 = kmalloc(sizeof(*h4), GFP_ATOMIC);
-+ if (!h4)
-+ return -ENOMEM;
-+ memset(h4, 0, sizeof(*h4));
-+
-+ skb_queue_head_init(&h4->txq);
-+
-+ hu->priv = h4;
-+ return 0;
-+}
-+
-+/* Flush protocol data */
-+static int h4_flush(struct hci_uart *hu)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+
-+ BT_DBG("hu %p", hu);
-+ skb_queue_purge(&h4->txq);
-+ return 0;
-+}
-+
-+/* Close protocol */
-+static int h4_close(struct hci_uart *hu)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+ hu->priv = NULL;
-+
-+ BT_DBG("hu %p", hu);
-+
-+ skb_queue_purge(&h4->txq);
-+ if (h4->rx_skb)
-+ kfree_skb(h4->rx_skb);
-+
-+ hu->priv = NULL;
-+ kfree(h4);
-+ return 0;
-+}
-+
-+/* Enqueue frame for transmittion (padding, crc, etc) */
-+static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+
-+ BT_DBG("hu %p skb %p", hu, skb);
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
-+ skb_queue_tail(&h4->txq, skb);
-+ return 0;
-+}
-+
-+static inline int h4_check_data_len(struct h4_struct *h4, int len)
-+{
-+ register int room = skb_tailroom(h4->rx_skb);
-+
-+ BT_DBG("len %d room %d", len, room);
-+ if (!len) {
-+ BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
-+ hci_recv_frame(h4->rx_skb);
-+ } else if (len > room) {
-+ BT_ERR("Data length is too large");
-+ kfree_skb(h4->rx_skb);
-+ } else {
-+ h4->rx_state = H4_W4_DATA;
-+ h4->rx_count = len;
-+ return len;
-+ }
-+
-+ h4->rx_state = H4_W4_PACKET_TYPE;
-+ h4->rx_skb = NULL;
-+ h4->rx_count = 0;
-+ return 0;
-+}
-+
-+/* Recv data */
-+static int h4_recv(struct hci_uart *hu, void *data, int count)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+ register char *ptr;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+ register int len, type, dlen;
-+
-+ BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
-+ hu, count, h4->rx_state, h4->rx_count);
-+
-+ ptr = data;
-+ while (count) {
-+ if (h4->rx_count) {
-+ len = MIN(h4->rx_count, count);
-+ memcpy(skb_put(h4->rx_skb, len), ptr, len);
-+ h4->rx_count -= len; count -= len; ptr += len;
-+
-+ if (h4->rx_count)
-+ continue;
-+
-+ switch (h4->rx_state) {
-+ case H4_W4_DATA:
-+ BT_DBG("Complete data");
-+
-+ BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
-+
-+ hci_recv_frame(h4->rx_skb);
-+
-+ h4->rx_state = H4_W4_PACKET_TYPE;
-+ h4->rx_skb = NULL;
-+ continue;
-+
-+ case H4_W4_EVENT_HDR:
-+ eh = (hci_event_hdr *) h4->rx_skb->data;
-+
-+ BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
-+
-+ h4_check_data_len(h4, eh->plen);
-+ continue;
-+
-+ case H4_W4_ACL_HDR:
-+ ah = (hci_acl_hdr *) h4->rx_skb->data;
-+ dlen = __le16_to_cpu(ah->dlen);
-+
-+ BT_DBG("ACL header: dlen %d", dlen);
-+
-+ h4_check_data_len(h4, dlen);
-+ continue;
-+
-+ case H4_W4_SCO_HDR:
-+ sh = (hci_sco_hdr *) h4->rx_skb->data;
-+
-+ BT_DBG("SCO header: dlen %d", sh->dlen);
-+
-+ h4_check_data_len(h4, sh->dlen);
-+ continue;
-+ }
-+ }
-+
-+ /* H4_W4_PACKET_TYPE */
-+ switch (*ptr) {
-+ case HCI_EVENT_PKT:
-+ BT_DBG("Event packet");
-+ h4->rx_state = H4_W4_EVENT_HDR;
-+ h4->rx_count = HCI_EVENT_HDR_SIZE;
-+ type = HCI_EVENT_PKT;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ BT_DBG("ACL packet");
-+ h4->rx_state = H4_W4_ACL_HDR;
-+ h4->rx_count = HCI_ACL_HDR_SIZE;
-+ type = HCI_ACLDATA_PKT;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ BT_DBG("SCO packet");
-+ h4->rx_state = H4_W4_SCO_HDR;
-+ h4->rx_count = HCI_SCO_HDR_SIZE;
-+ type = HCI_SCODATA_PKT;
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
-+ hu->hdev.stat.err_rx++;
-+ ptr++; count--;
-+ continue;
-+ };
-+ ptr++; count--;
-+
-+ /* Allocate packet */
-+ h4->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
-+ if (!h4->rx_skb) {
-+ BT_ERR("Can't allocate mem for new packet");
-+ h4->rx_state = H4_W4_PACKET_TYPE;
-+ h4->rx_count = 0;
-+ return 0;
-+ }
-+ h4->rx_skb->dev = (void *) &hu->hdev;
-+ h4->rx_skb->pkt_type = type;
-+ }
-+ return count;
-+}
-+
-+static struct sk_buff *h4_dequeue(struct hci_uart *hu)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+ return skb_dequeue(&h4->txq);
-+}
-+
-+static struct hci_uart_proto h4p = {
-+ id: HCI_UART_H4,
-+ open: h4_open,
-+ close: h4_close,
-+ recv: h4_recv,
-+ enqueue: h4_enqueue,
-+ dequeue: h4_dequeue,
-+ flush: h4_flush,
-+};
-+
-+int h4_init(void)
-+{
-+ return hci_uart_register_proto(&h4p);
-+}
-+
-+int h4_deinit(void)
-+{
-+ return hci_uart_unregister_proto(&h4p);
-+}
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/bluetooth/hci_h4.h 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,44 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifdef __KERNEL__
-+struct h4_struct {
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+ struct sk_buff_head txq;
-+};
-+
-+/* H4 receiver States */
-+#define H4_W4_PACKET_TYPE 0
-+#define H4_W4_EVENT_HDR 1
-+#define H4_W4_ACL_HDR 2
-+#define H4_W4_SCO_HDR 3
-+#define H4_W4_DATA 4
-+
-+#endif /* __KERNEL__ */
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/bluetooth/hci_ldisc.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,580 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * BlueZ HCI UART driver.
-+ *
-+ * $Id$
-+ */
-+#define VERSION "2.1"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/version.h>
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/types.h>
-+#include <linux/fcntl.h>
-+#include <linux/interrupt.h>
-+#include <linux/ptrace.h>
-+#include <linux/poll.h>
-+
-+#include <linux/slab.h>
-+#include <linux/tty.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/signal.h>
-+#include <linux/ioctl.h>
-+#include <linux/skbuff.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include "hci_uart.h"
-+
-+#ifndef HCI_UART_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#undef BT_DMP
-+#define BT_DMP( A... )
-+#endif
-+
-+static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
-+
-+int hci_uart_register_proto(struct hci_uart_proto *p)
-+{
-+ if (p->id >= HCI_UART_MAX_PROTO)
-+ return -EINVAL;
-+
-+ if (hup[p->id])
-+ return -EEXIST;
-+
-+ hup[p->id] = p;
-+ return 0;
-+}
-+
-+int hci_uart_unregister_proto(struct hci_uart_proto *p)
-+{
-+ if (p->id >= HCI_UART_MAX_PROTO)
-+ return -EINVAL;
-+
-+ if (!hup[p->id])
-+ return -EINVAL;
-+
-+ hup[p->id] = NULL;
-+ return 0;
-+}
-+
-+static struct hci_uart_proto *hci_uart_get_proto(unsigned int id)
-+{
-+ if (id >= HCI_UART_MAX_PROTO)
-+ return NULL;
-+ return hup[id];
-+}
-+
-+static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type)
-+{
-+ struct hci_dev *hdev = &hu->hdev;
-+
-+ /* Update HCI stat counters */
-+ switch (pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ }
-+}
-+
-+static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu)
-+{
-+ struct sk_buff *skb = hu->tx_skb;
-+ if (!skb)
-+ skb = hu->proto->dequeue(hu);
-+ else
-+ hu->tx_skb = NULL;
-+ return skb;
-+}
-+
-+int hci_uart_tx_wakeup(struct hci_uart *hu)
-+{
-+ struct tty_struct *tty = hu->tty;
-+ struct hci_dev *hdev = &hu->hdev;
-+ struct sk_buff *skb;
-+
-+ if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
-+ set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
-+ return 0;
-+ }
-+
-+ BT_DBG("");
-+
-+restart:
-+ clear_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
-+
-+ while ((skb = hci_uart_dequeue(hu))) {
-+ int len;
-+
-+ set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-+ len = tty->driver.write(tty, 0, skb->data, skb->len);
-+ hdev->stat.byte_tx += len;
-+
-+ skb_pull(skb, len);
-+ if (skb->len) {
-+ hu->tx_skb = skb;
-+ break;
-+ }
-+
-+ hci_uart_tx_complete(hu, skb->pkt_type);
-+ kfree_skb(skb);
-+ }
-+
-+ if (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state))
-+ goto restart;
-+
-+ clear_bit(HCI_UART_SENDING, &hu->tx_state);
-+ return 0;
-+}
-+
-+/* ------- Interface to HCI layer ------ */
-+/* Initialize device */
-+static int hci_uart_open(struct hci_dev *hdev)
-+{
-+ BT_DBG("%s %p", hdev->name, hdev);
-+
-+ /* Nothing to do for UART driver */
-+
-+ set_bit(HCI_RUNNING, &hdev->flags);
-+ return 0;
-+}
-+
-+/* Reset device */
-+static int hci_uart_flush(struct hci_dev *hdev)
-+{
-+ struct hci_uart *hu = (struct hci_uart *) hdev->driver_data;
-+ struct tty_struct *tty = hu->tty;
-+
-+ BT_DBG("hdev %p tty %p", hdev, tty);
-+
-+ if (hu->tx_skb) {
-+ kfree_skb(hu->tx_skb); hu->tx_skb = NULL;
-+ }
-+
-+ /* Flush any pending characters in the driver and discipline. */
-+ if (tty->ldisc.flush_buffer)
-+ tty->ldisc.flush_buffer(tty);
-+
-+ if (tty->driver.flush_buffer)
-+ tty->driver.flush_buffer(tty);
-+
-+ if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
-+ hu->proto->flush(hu);
-+
-+ return 0;
-+}
-+
-+/* Close device */
-+static int hci_uart_close(struct hci_dev *hdev)
-+{
-+ BT_DBG("hdev %p", hdev);
-+
-+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-+
-+ hci_uart_flush(hdev);
-+ return 0;
-+}
-+
-+/* Send frames from HCI layer */
-+static int hci_uart_send_frame(struct sk_buff *skb)
-+{
-+ struct hci_dev* hdev = (struct hci_dev *) skb->dev;
-+ struct tty_struct *tty;
-+ struct hci_uart *hu;
-+
-+ if (!hdev) {
-+ BT_ERR("Frame for uknown device (hdev=NULL)");
-+ return -ENODEV;
-+ }
-+
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return -EBUSY;
-+
-+ hu = (struct hci_uart *) hdev->driver_data;
-+ tty = hu->tty;
-+
-+ BT_DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
-+
-+ hu->proto->enqueue(hu, skb);
-+
-+ hci_uart_tx_wakeup(hu);
-+ return 0;
-+}
-+
-+static void hci_uart_destruct(struct hci_dev *hdev)
-+{
-+ struct hci_uart *hu;
-+
-+ if (!hdev) return;
-+
-+ BT_DBG("%s", hdev->name);
-+
-+ hu = (struct hci_uart *) hdev->driver_data;
-+ kfree(hu);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+/* ------ LDISC part ------ */
-+/* hci_uart_tty_open
-+ *
-+ * Called when line discipline changed to HCI_UART.
-+ *
-+ * Arguments:
-+ * tty pointer to tty info structure
-+ * Return Value:
-+ * 0 if success, otherwise error code
-+ */
-+static int hci_uart_tty_open(struct tty_struct *tty)
-+{
-+ struct hci_uart *hu = (void *) tty->disc_data;
-+
-+ BT_DBG("tty %p", tty);
-+
-+ if (hu)
-+ return -EEXIST;
-+
-+ if (!(hu = kmalloc(sizeof(struct hci_uart), GFP_KERNEL))) {
-+ BT_ERR("Can't allocate controll structure");
-+ return -ENFILE;
-+ }
-+ memset(hu, 0, sizeof(struct hci_uart));
-+
-+ tty->disc_data = hu;
-+ hu->tty = tty;
-+
-+ spin_lock_init(&hu->rx_lock);
-+
-+ /* Flush any pending characters in the driver and line discipline */
-+ if (tty->ldisc.flush_buffer)
-+ tty->ldisc.flush_buffer(tty);
-+
-+ if (tty->driver.flush_buffer)
-+ tty->driver.flush_buffer(tty);
-+
-+ MOD_INC_USE_COUNT;
-+ return 0;
-+}
-+
-+/* hci_uart_tty_close()
-+ *
-+ * Called when the line discipline is changed to something
-+ * else, the tty is closed, or the tty detects a hangup.
-+ */
-+static void hci_uart_tty_close(struct tty_struct *tty)
-+{
-+ struct hci_uart *hu = (void *)tty->disc_data;
-+
-+ BT_DBG("tty %p", tty);
-+
-+ /* Detach from the tty */
-+ tty->disc_data = NULL;
-+
-+ if (hu) {
-+ struct hci_dev *hdev = &hu->hdev;
-+ hci_uart_close(hdev);
-+
-+ if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
-+ hu->proto->close(hu);
-+ hci_unregister_dev(hdev);
-+ }
-+
-+ MOD_DEC_USE_COUNT;
-+ }
-+}
-+
-+/* hci_uart_tty_wakeup()
-+ *
-+ * Callback for transmit wakeup. Called when low level
-+ * device driver can accept more send data.
-+ *
-+ * Arguments: tty pointer to associated tty instance data
-+ * Return Value: None
-+ */
-+static void hci_uart_tty_wakeup(struct tty_struct *tty)
-+{
-+ struct hci_uart *hu = (void *)tty->disc_data;
-+
-+ BT_DBG("");
-+
-+ if (!hu)
-+ return;
-+
-+ clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-+
-+ if (tty != hu->tty)
-+ return;
-+
-+ if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
-+ hci_uart_tx_wakeup(hu);
-+}
-+
-+/* hci_uart_tty_room()
-+ *
-+ * Callback function from tty driver. Return the amount of
-+ * space left in the receiver's buffer to decide if remote
-+ * transmitter is to be throttled.
-+ *
-+ * Arguments: tty pointer to associated tty instance data
-+ * Return Value: number of bytes left in receive buffer
-+ */
-+static int hci_uart_tty_room (struct tty_struct *tty)
-+{
-+ return 65536;
-+}
-+
-+/* hci_uart_tty_receive()
-+ *
-+ * Called by tty low level driver when receive data is
-+ * available.
-+ *
-+ * Arguments: tty pointer to tty isntance data
-+ * data pointer to received data
-+ * flags pointer to flags for data
-+ * count count of received data in bytes
-+ *
-+ * Return Value: None
-+ */
-+static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char *flags, int count)
-+{
-+ struct hci_uart *hu = (void *)tty->disc_data;
-+
-+ if (!hu || tty != hu->tty)
-+ return;
-+
-+ if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
-+ return;
-+
-+ spin_lock(&hu->rx_lock);
-+ hu->proto->recv(hu, (void *) data, count);
-+ hu->hdev.stat.byte_rx += count;
-+ spin_unlock(&hu->rx_lock);
-+
-+ if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver.unthrottle)
-+ tty->driver.unthrottle(tty);
-+}
-+
-+static int hci_uart_register_dev(struct hci_uart *hu)
-+{
-+ struct hci_dev *hdev;
-+
-+ BT_DBG("");
-+
-+ /* Initialize and register HCI device */
-+ hdev = &hu->hdev;
-+
-+ hdev->type = HCI_UART;
-+ hdev->driver_data = hu;
-+
-+ hdev->open = hci_uart_open;
-+ hdev->close = hci_uart_close;
-+ hdev->flush = hci_uart_flush;
-+ hdev->send = hci_uart_send_frame;
-+ hdev->destruct = hci_uart_destruct;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ BT_ERR("Can't register HCI device %s", hdev->name);
-+ return -ENODEV;
-+ }
-+ MOD_INC_USE_COUNT;
-+ return 0;
-+}
-+
-+static int hci_uart_set_proto(struct hci_uart *hu, int id)
-+{
-+ struct hci_uart_proto *p;
-+ int err;
-+
-+ p = hci_uart_get_proto(id);
-+ if (!p)
-+ return -EPROTONOSUPPORT;
-+
-+ err = p->open(hu);
-+ if (err)
-+ return err;
-+
-+ hu->proto = p;
-+
-+ err = hci_uart_register_dev(hu);
-+ if (err) {
-+ p->close(hu);
-+ return err;
-+ }
-+ return 0;
-+}
-+
-+/* hci_uart_tty_ioctl()
-+ *
-+ * Process IOCTL system call for the tty device.
-+ *
-+ * Arguments:
-+ *
-+ * tty pointer to tty instance data
-+ * file pointer to open file object for device
-+ * cmd IOCTL command code
-+ * arg argument for IOCTL call (cmd dependent)
-+ *
-+ * Return Value: Command dependent
-+ */
-+static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ struct hci_uart *hu = (void *)tty->disc_data;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ /* Verify the status of the device */
-+ if (!hu)
-+ return -EBADF;
-+
-+ switch (cmd) {
-+ case HCIUARTSETPROTO:
-+ if (!test_and_set_bit(HCI_UART_PROTO_SET, &hu->flags)) {
-+ err = hci_uart_set_proto(hu, arg);
-+ if (err) {
-+ clear_bit(HCI_UART_PROTO_SET, &hu->flags);
-+ return err;
-+ }
-+ tty->low_latency = 1;
-+ } else
-+ return -EBUSY;
-+
-+ case HCIUARTGETPROTO:
-+ if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
-+ return hu->proto->id;
-+ return -EUNATCH;
-+
-+ default:
-+ err = n_tty_ioctl(tty, file, cmd, arg);
-+ break;
-+ };
-+
-+ return err;
-+}
-+
-+/*
-+ * We don't provide read/write/poll interface for user space.
-+ */
-+static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr)
-+{
-+ return 0;
-+}
-+static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
-+{
-+ return 0;
-+}
-+static unsigned int hci_uart_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
-+{
-+ return 0;
-+}
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_H4
-+int h4_init(void);
-+int h4_deinit(void);
-+#endif
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP
-+int bcsp_init(void);
-+int bcsp_deinit(void);
-+#endif
-+
-+int __init hci_uart_init(void)
-+{
-+ static struct tty_ldisc hci_uart_ldisc;
-+ int err;
-+
-+ BT_INFO("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-+ VERSION);
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+
-+ /* Register the tty discipline */
-+
-+ memset(&hci_uart_ldisc, 0, sizeof (hci_uart_ldisc));
-+ hci_uart_ldisc.magic = TTY_LDISC_MAGIC;
-+ hci_uart_ldisc.name = "n_hci";
-+ hci_uart_ldisc.open = hci_uart_tty_open;
-+ hci_uart_ldisc.close = hci_uart_tty_close;
-+ hci_uart_ldisc.read = hci_uart_tty_read;
-+ hci_uart_ldisc.write = hci_uart_tty_write;
-+ hci_uart_ldisc.ioctl = hci_uart_tty_ioctl;
-+ hci_uart_ldisc.poll = hci_uart_tty_poll;
-+ hci_uart_ldisc.receive_room= hci_uart_tty_room;
-+ hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
-+ hci_uart_ldisc.write_wakeup= hci_uart_tty_wakeup;
-+
-+ if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) {
-+ BT_ERR("Can't register HCI line discipline (%d)", err);
-+ return err;
-+ }
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_H4
-+ h4_init();
-+#endif
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP
-+ bcsp_init();
-+#endif
-+
-+ return 0;
-+}
-+
-+void hci_uart_cleanup(void)
-+{
-+ int err;
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_H4
-+ h4_deinit();
-+#endif
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP
-+ bcsp_deinit();
-+#endif
-+
-+ /* Release tty registration of line discipline */
-+ if ((err = tty_register_ldisc(N_HCI, NULL)))
-+ BT_ERR("Can't unregister HCI line discipline (%d)", err);
-+}
-+
-+module_init(hci_uart_init);
-+module_exit(hci_uart_cleanup);
-+
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
-+MODULE_DESCRIPTION("BlueZ HCI UART driver ver " VERSION);
-+MODULE_LICENSE("GPL");
---- linux/drivers/bluetooth/hci_uart.c~bluetooth-2.4.18-mh11
-+++ linux/drivers/bluetooth/hci_uart.c
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * BlueZ HCI UART driver.
-- *
-- * $Id$
-- */
--#define VERSION "1.0"
--
--#include <linux/config.h>
--#include <linux/module.h>
--
--#include <linux/version.h>
--#include <linux/config.h>
--#include <linux/kernel.h>
--#include <linux/init.h>
--#include <linux/sched.h>
--#include <linux/types.h>
--#include <linux/fcntl.h>
--#include <linux/interrupt.h>
--#include <linux/ptrace.h>
--#include <linux/poll.h>
--
--#include <linux/slab.h>
--#include <linux/tty.h>
--#include <linux/errno.h>
--#include <linux/string.h>
--#include <linux/signal.h>
--#include <linux/ioctl.h>
--#include <linux/skbuff.h>
--
--#include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
--#include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/hci_uart.h>
--
--#ifndef HCI_UART_DEBUG
--#undef DBG
--#define DBG( A... )
--#undef DMP
--#define DMP( A... )
--#endif
--
--/* ------- Interface to HCI layer ------ */
--/* Initialize device */
--int n_hci_open(struct hci_dev *hdev)
--{
-- DBG("%s %p", hdev->name, hdev);
--
-- /* Nothing to do for UART driver */
--
-- hdev->flags |= HCI_RUNNING;
--
-- return 0;
--}
--
--/* Reset device */
--int n_hci_flush(struct hci_dev *hdev)
--{
-- struct n_hci *n_hci = (struct n_hci *) hdev->driver_data;
-- struct tty_struct *tty = n_hci->tty;
--
-- DBG("hdev %p tty %p", hdev, tty);
--
-- /* Drop TX queue */
-- skb_queue_purge(&n_hci->txq);
--
-- /* Flush any pending characters in the driver and discipline. */
-- if (tty->ldisc.flush_buffer)
-- tty->ldisc.flush_buffer(tty);
--
-- if (tty->driver.flush_buffer)
-- tty->driver.flush_buffer(tty);
--
-- return 0;
--}
--
--/* Close device */
--int n_hci_close(struct hci_dev *hdev)
--{
-- DBG("hdev %p", hdev);
--
-- hdev->flags &= ~HCI_RUNNING;
--
-- n_hci_flush(hdev);
--
-- return 0;
--}
--
--int n_hci_tx_wakeup(struct n_hci *n_hci)
--{
-- register struct tty_struct *tty = n_hci->tty;
--
-- if (test_and_set_bit(TRANS_SENDING, &n_hci->tx_state)) {
-- set_bit(TRANS_WAKEUP, &n_hci->tx_state);
-- return 0;
-- }
--
-- DBG("");
-- do {
-- register struct sk_buff *skb;
-- register int len;
--
-- clear_bit(TRANS_WAKEUP, &n_hci->tx_state);
--
-- if (!(skb = skb_dequeue(&n_hci->txq)))
-- break;
--
-- DMP(skb->data, skb->len);
--
-- /* Send frame to TTY driver */
-- tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
-- len = tty->driver.write(tty, 0, skb->data, skb->len);
--
-- n_hci->hdev.stat.byte_tx += len;
--
-- DBG("sent %d", len);
--
-- if (len == skb->len) {
-- /* Full frame was sent */
-- kfree_skb(skb);
-- } else {
-- /* Subtract sent part and requeue */
-- skb_pull(skb, len);
-- skb_queue_head(&n_hci->txq, skb);
-- }
-- } while (test_bit(TRANS_WAKEUP, &n_hci->tx_state));
-- clear_bit(TRANS_SENDING, &n_hci->tx_state);
--
-- return 0;
--}
--
--/* Send frames from HCI layer */
--int n_hci_send_frame(struct sk_buff *skb)
--{
-- struct hci_dev* hdev = (struct hci_dev *) skb->dev;
-- struct tty_struct *tty;
-- struct n_hci *n_hci;
--
-- if (!hdev) {
-- ERR("Frame for uknown device (hdev=NULL)");
-- return -ENODEV;
-- }
--
-- if (!(hdev->flags & HCI_RUNNING))
-- return -EBUSY;
--
-- n_hci = (struct n_hci *) hdev->driver_data;
-- tty = n_hci2tty(n_hci);
--
-- DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
--
-- switch (skb->pkt_type) {
-- case HCI_COMMAND_PKT:
-- hdev->stat.cmd_tx++;
-- break;
--
-- case HCI_ACLDATA_PKT:
-- hdev->stat.acl_tx++;
-- break;
--
-- case HCI_SCODATA_PKT:
-- hdev->stat.cmd_tx++;
-- break;
-- };
--
-- /* Prepend skb with frame type and queue */
-- memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
-- skb_queue_tail(&n_hci->txq, skb);
--
-- n_hci_tx_wakeup(n_hci);
--
-- return 0;
--}
--
--/* ------ LDISC part ------ */
--
--/* n_hci_tty_open
-- *
-- * Called when line discipline changed to N_HCI.
-- *
-- * Arguments:
-- * tty pointer to tty info structure
-- * Return Value:
-- * 0 if success, otherwise error code
-- */
--static int n_hci_tty_open(struct tty_struct *tty)
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
-- struct hci_dev *hdev;
--
-- DBG("tty %p", tty);
--
-- if (n_hci)
-- return -EEXIST;
--
-- if (!(n_hci = kmalloc(sizeof(struct n_hci), GFP_KERNEL))) {
-- ERR("Can't allocate controll structure");
-- return -ENFILE;
-- }
-- memset(n_hci, 0, sizeof(struct n_hci));
--
-- /* Initialize and register HCI device */
-- hdev = &n_hci->hdev;
--
-- hdev->type = HCI_UART;
-- hdev->driver_data = n_hci;
--
-- hdev->open = n_hci_open;
-- hdev->close = n_hci_close;
-- hdev->flush = n_hci_flush;
-- hdev->send = n_hci_send_frame;
--
-- if (hci_register_dev(hdev) < 0) {
-- ERR("Can't register HCI device %s", hdev->name);
-- kfree(n_hci);
-- return -ENODEV;
-- }
--
-- tty->disc_data = n_hci;
-- n_hci->tty = tty;
--
-- spin_lock_init(&n_hci->rx_lock);
-- n_hci->rx_state = WAIT_PACKET_TYPE;
--
-- skb_queue_head_init(&n_hci->txq);
--
-- MOD_INC_USE_COUNT;
--
-- /* Flush any pending characters in the driver and discipline. */
-- if (tty->ldisc.flush_buffer)
-- tty->ldisc.flush_buffer(tty);
--
-- if (tty->driver.flush_buffer)
-- tty->driver.flush_buffer(tty);
--
-- return 0;
--}
--
--/* n_hci_tty_close()
-- *
-- * Called when the line discipline is changed to something
-- * else, the tty is closed, or the tty detects a hangup.
-- */
--static void n_hci_tty_close(struct tty_struct *tty)
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
-- struct hci_dev *hdev = &n_hci->hdev;
--
-- DBG("tty %p hdev %p", tty, hdev);
--
-- if (n_hci != NULL) {
-- n_hci_close(hdev);
--
-- if (hci_unregister_dev(hdev) < 0) {
-- ERR("Can't unregister HCI device %s",hdev->name);
-- }
--
-- hdev->driver_data = NULL;
-- tty->disc_data = NULL;
-- kfree(n_hci);
--
-- MOD_DEC_USE_COUNT;
-- }
--}
--
--/* n_hci_tty_wakeup()
-- *
-- * Callback for transmit wakeup. Called when low level
-- * device driver can accept more send data.
-- *
-- * Arguments: tty pointer to associated tty instance data
-- * Return Value: None
-- */
--static void n_hci_tty_wakeup( struct tty_struct *tty )
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
--
-- DBG("");
--
-- if (!n_hci)
-- return;
--
-- tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
--
-- if (tty != n_hci->tty)
-- return;
--
-- n_hci_tx_wakeup(n_hci);
--}
--
--/* n_hci_tty_room()
-- *
-- * Callback function from tty driver. Return the amount of
-- * space left in the receiver's buffer to decide if remote
-- * transmitter is to be throttled.
-- *
-- * Arguments: tty pointer to associated tty instance data
-- * Return Value: number of bytes left in receive buffer
-- */
--static int n_hci_tty_room (struct tty_struct *tty)
--{
-- return 65536;
--}
--
--static inline int n_hci_check_data_len(struct n_hci *n_hci, int len)
--{
-- register int room = skb_tailroom(n_hci->rx_skb);
--
-- DBG("len %d room %d", len, room);
-- if (!len) {
-- DMP(n_hci->rx_skb->data, n_hci->rx_skb->len);
-- hci_recv_frame(n_hci->rx_skb);
-- } else if (len > room) {
-- ERR("Data length is to large");
-- kfree_skb(n_hci->rx_skb);
-- n_hci->hdev.stat.err_rx++;
-- } else {
-- n_hci->rx_state = WAIT_DATA;
-- n_hci->rx_count = len;
-- return len;
-- }
--
-- n_hci->rx_state = WAIT_PACKET_TYPE;
-- n_hci->rx_skb = NULL;
-- n_hci->rx_count = 0;
-- return 0;
--}
--
--static inline void n_hci_rx(struct n_hci *n_hci, const __u8 * data, char *flags, int count)
--{
-- register const char *ptr;
-- hci_event_hdr *eh;
-- hci_acl_hdr *ah;
-- hci_sco_hdr *sh;
-- register int len, type, dlen;
--
-- DBG("count %d state %ld rx_count %ld", count, n_hci->rx_state, n_hci->rx_count);
--
-- n_hci->hdev.stat.byte_rx += count;
--
-- ptr = data;
-- while (count) {
-- if (n_hci->rx_count) {
-- len = MIN(n_hci->rx_count, count);
-- memcpy(skb_put(n_hci->rx_skb, len), ptr, len);
-- n_hci->rx_count -= len; count -= len; ptr += len;
--
-- if (n_hci->rx_count)
-- continue;
--
-- switch (n_hci->rx_state) {
-- case WAIT_DATA:
-- DBG("Complete data");
--
-- DMP(n_hci->rx_skb->data, n_hci->rx_skb->len);
--
-- hci_recv_frame(n_hci->rx_skb);
--
-- n_hci->rx_state = WAIT_PACKET_TYPE;
-- n_hci->rx_skb = NULL;
-- continue;
--
-- case WAIT_EVENT_HDR:
-- eh = (hci_event_hdr *) n_hci->rx_skb->data;
--
-- DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
--
-- n_hci_check_data_len(n_hci, eh->plen);
-- continue;
--
-- case WAIT_ACL_HDR:
-- ah = (hci_acl_hdr *) n_hci->rx_skb->data;
-- dlen = __le16_to_cpu(ah->dlen);
--
-- DBG("ACL header: dlen %d", dlen);
--
-- n_hci_check_data_len(n_hci, dlen);
-- continue;
--
-- case WAIT_SCO_HDR:
-- sh = (hci_sco_hdr *) n_hci->rx_skb->data;
--
-- DBG("SCO header: dlen %d", sh->dlen);
--
-- n_hci_check_data_len(n_hci, sh->dlen);
-- continue;
-- };
-- }
--
-- /* WAIT_PACKET_TYPE */
-- switch (*ptr) {
-- case HCI_EVENT_PKT:
-- DBG("Event packet");
-- n_hci->rx_state = WAIT_EVENT_HDR;
-- n_hci->rx_count = HCI_EVENT_HDR_SIZE;
-- type = HCI_EVENT_PKT;
-- break;
--
-- case HCI_ACLDATA_PKT:
-- DBG("ACL packet");
-- n_hci->rx_state = WAIT_ACL_HDR;
-- n_hci->rx_count = HCI_ACL_HDR_SIZE;
-- type = HCI_ACLDATA_PKT;
-- break;
--
-- case HCI_SCODATA_PKT:
-- DBG("SCO packet");
-- n_hci->rx_state = WAIT_SCO_HDR;
-- n_hci->rx_count = HCI_SCO_HDR_SIZE;
-- type = HCI_SCODATA_PKT;
-- break;
--
-- default:
-- ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
-- n_hci->hdev.stat.err_rx++;
-- ptr++; count--;
-- continue;
-- };
-- ptr++; count--;
--
-- /* Allocate packet */
-- if (!(n_hci->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-- ERR("Can't allocate mem for new packet");
--
-- n_hci->rx_state = WAIT_PACKET_TYPE;
-- n_hci->rx_count = 0;
-- return;
-- }
-- n_hci->rx_skb->dev = (void *) &n_hci->hdev;
-- n_hci->rx_skb->pkt_type = type;
-- }
--}
--
--/* n_hci_tty_receive()
-- *
-- * Called by tty low level driver when receive data is
-- * available.
-- *
-- * Arguments: tty pointer to tty isntance data
-- * data pointer to received data
-- * flags pointer to flags for data
-- * count count of received data in bytes
-- *
-- * Return Value: None
-- */
--static void n_hci_tty_receive(struct tty_struct *tty, const __u8 * data, char *flags, int count)
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
--
-- if (!n_hci || tty != n_hci->tty)
-- return;
--
-- spin_lock(&n_hci->rx_lock);
-- n_hci_rx(n_hci, data, flags, count);
-- spin_unlock(&n_hci->rx_lock);
--
-- if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver.unthrottle)
-- tty->driver.unthrottle(tty);
--}
--
--/* n_hci_tty_ioctl()
-- *
-- * Process IOCTL system call for the tty device.
-- *
-- * Arguments:
-- *
-- * tty pointer to tty instance data
-- * file pointer to open file object for device
-- * cmd IOCTL command code
-- * arg argument for IOCTL call (cmd dependent)
-- *
-- * Return Value: Command dependent
-- */
--static int n_hci_tty_ioctl (struct tty_struct *tty, struct file * file,
-- unsigned int cmd, unsigned long arg)
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
-- int error = 0;
--
-- DBG("");
--
-- /* Verify the status of the device */
-- if (!n_hci)
-- return -EBADF;
--
-- switch (cmd) {
-- default:
-- error = n_tty_ioctl(tty, file, cmd, arg);
-- break;
-- };
--
-- return error;
--}
--
--/*
-- * We don't provide read/write/poll interface for user space.
-- */
--static ssize_t n_hci_tty_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr)
--{
-- return 0;
--}
--static ssize_t n_hci_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
--{
-- return 0;
--}
--static unsigned int n_hci_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
--{
-- return 0;
--}
--
--int __init n_hci_init(void)
--{
-- static struct tty_ldisc n_hci_ldisc;
-- int err;
--
-- INF("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
--
-- /* Register the tty discipline */
--
-- memset(&n_hci_ldisc, 0, sizeof (n_hci_ldisc));
-- n_hci_ldisc.magic = TTY_LDISC_MAGIC;
-- n_hci_ldisc.name = "n_hci";
-- n_hci_ldisc.open = n_hci_tty_open;
-- n_hci_ldisc.close = n_hci_tty_close;
-- n_hci_ldisc.read = n_hci_tty_read;
-- n_hci_ldisc.write = n_hci_tty_write;
-- n_hci_ldisc.ioctl = n_hci_tty_ioctl;
-- n_hci_ldisc.poll = n_hci_tty_poll;
-- n_hci_ldisc.receive_room= n_hci_tty_room;
-- n_hci_ldisc.receive_buf = n_hci_tty_receive;
-- n_hci_ldisc.write_wakeup= n_hci_tty_wakeup;
--
-- if ((err = tty_register_ldisc(N_HCI, &n_hci_ldisc))) {
-- ERR("Can't register HCI line discipline (%d)", err);
-- return err;
-- }
--
-- return 0;
--}
--
--void n_hci_cleanup(void)
--{
-- int err;
--
-- /* Release tty registration of line discipline */
-- if ((err = tty_register_ldisc(N_HCI, NULL)))
-- ERR("Can't unregister HCI line discipline (%d)", err);
--}
--
--module_init(n_hci_init);
--module_exit(n_hci_cleanup);
--
--MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
--MODULE_DESCRIPTION("BlueZ HCI UART driver ver " VERSION);
--MODULE_LICENSE("GPL");
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/bluetooth/hci_uart.h 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,81 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef N_HCI
-+#define N_HCI 15
-+#endif
-+
-+/* Ioctls */
-+#define HCIUARTSETPROTO _IOW('U', 200, int)
-+#define HCIUARTGETPROTO _IOR('U', 201, int)
-+
-+/* UART protocols */
-+#define HCI_UART_MAX_PROTO 3
-+
-+#define HCI_UART_H4 0
-+#define HCI_UART_BCSP 1
-+#define HCI_UART_NCSP 2
-+
-+#ifdef __KERNEL__
-+struct hci_uart;
-+
-+struct hci_uart_proto {
-+ unsigned int id;
-+ int (*open)(struct hci_uart *hu);
-+ int (*close)(struct hci_uart *hu);
-+ int (*flush)(struct hci_uart *hu);
-+ int (*recv)(struct hci_uart *hu, void *data, int len);
-+ int (*enqueue)(struct hci_uart *hu, struct sk_buff *skb);
-+ struct sk_buff *(*dequeue)(struct hci_uart *hu);
-+};
-+
-+struct hci_uart {
-+ struct tty_struct *tty;
-+ struct hci_dev hdev;
-+ unsigned long flags;
-+
-+ struct hci_uart_proto *proto;
-+ void *priv;
-+
-+ struct sk_buff *tx_skb;
-+ unsigned long tx_state;
-+ spinlock_t rx_lock;
-+};
-+
-+/* HCI_UART flag bits */
-+#define HCI_UART_PROTO_SET 0
-+
-+/* TX states */
-+#define HCI_UART_SENDING 1
-+#define HCI_UART_TX_WAKEUP 2
-+
-+int hci_uart_register_proto(struct hci_uart_proto *p);
-+int hci_uart_unregister_proto(struct hci_uart_proto *p);
-+int hci_uart_tx_wakeup(struct hci_uart *hu);
-+
-+#endif /* __KERNEL__ */
---- linux/drivers/bluetooth/hci_usb.c~bluetooth-2.4.18-mh11 2001-09-07 18:28:38.000000000 +0200
-+++ linux/drivers/bluetooth/hci_usb.c 2004-01-25 23:37:39.000000000 +0100
-@@ -1,9 +1,10 @@
- /*
-- BlueZ - Bluetooth protocol stack for Linux
-+ HCI USB driver for Linux Bluetooth protocol stack (BlueZ)
- Copyright (C) 2000-2001 Qualcomm Incorporated
--
- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-
-+ Copyright (C) 2003 Maxim Krasnyansky <maxk@qualcomm.com>
-+
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as
- published by the Free Software Foundation;
-@@ -23,598 +24,914 @@
- */
-
- /*
-- * BlueZ HCI USB driver.
- * Based on original USB Bluetooth driver for Linux kernel
- * Copyright (c) 2000 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (c) 2000 Mark Douglas Corner <mcorner@umich.edu>
- *
-- * $Id$
-+ * $Id$
- */
--#define VERSION "1.0"
-+#define VERSION "2.4"
-
- #include <linux/config.h>
- #include <linux/module.h>
-
- #include <linux/version.h>
--#include <linux/config.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/sched.h>
-+#include <linux/unistd.h>
- #include <linux/types.h>
--#include <linux/fcntl.h>
- #include <linux/interrupt.h>
--#include <linux/ptrace.h>
--#include <linux/poll.h>
-
- #include <linux/slab.h>
--#include <linux/tty.h>
- #include <linux/errno.h>
- #include <linux/string.h>
--#include <linux/signal.h>
--#include <linux/ioctl.h>
- #include <linux/skbuff.h>
-
- #include <linux/usb.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/hci_usb.h>
-+
-+#include "hci_usb.h"
-
- #ifndef HCI_USB_DEBUG
--#undef DBG
--#define DBG( A... )
--#undef DMP
--#define DMP( A... )
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#undef BT_DMP
-+#define BT_DMP( A... )
- #endif
-
--static struct usb_device_id usb_bluetooth_ids [] = {
-+#ifndef CONFIG_BLUEZ_HCIUSB_ZERO_PACKET
-+#undef USB_ZERO_PACKET
-+#define USB_ZERO_PACKET 0
-+#endif
-+
-+static struct usb_driver hci_usb_driver;
-+
-+static struct usb_device_id bluetooth_ids[] = {
-+ /* Digianswer device */
-+ { USB_DEVICE(0x08fd, 0x0001), driver_info: HCI_DIGIANSWER },
-+
-+ /* Generic Bluetooth USB device */
- { USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) },
-+
-+ /* Ericsson with non-standard id */
-+ { USB_DEVICE(0x0bdb, 0x1002) },
-+
-+ /* ALPS Module with non-standard id */
-+ { USB_DEVICE(0x044e, 0x3002) },
-+
-+ /* Bluetooth Ultraport Module from IBM */
-+ { USB_DEVICE(0x04bf, 0x030a) },
-+
- { } /* Terminating entry */
- };
-
--MODULE_DEVICE_TABLE (usb, usb_bluetooth_ids);
-+MODULE_DEVICE_TABLE (usb, bluetooth_ids);
-
--static int hci_usb_ctrl_msg(struct hci_usb *husb, struct sk_buff *skb);
--static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb);
-+static struct usb_device_id ignore_ids[] = {
-+ /* Broadcom BCM2033 without firmware */
-+ { USB_DEVICE(0x0a5c, 0x2033) },
-
--static void hci_usb_unlink_urbs(struct hci_usb *husb)
--{
-- usb_unlink_urb(husb->read_urb);
-- usb_unlink_urb(husb->intr_urb);
-- usb_unlink_urb(husb->ctrl_urb);
-- usb_unlink_urb(husb->write_urb);
--}
-+ { } /* Terminating entry */
-+};
-
--static void hci_usb_free_bufs(struct hci_usb *husb)
-+struct _urb *_urb_alloc(int isoc, int gfp)
- {
-- if (husb->read_urb) {
-- if (husb->read_urb->transfer_buffer)
-- kfree(husb->read_urb->transfer_buffer);
-- usb_free_urb(husb->read_urb);
-+ struct _urb *_urb = kmalloc(sizeof(struct _urb) +
-+ sizeof(iso_packet_descriptor_t) * isoc, gfp);
-+ if (_urb) {
-+ memset(_urb, 0, sizeof(*_urb));
-+ spin_lock_init(&_urb->urb.lock);
- }
-+ return _urb;
-+}
-
-- if (husb->intr_urb) {
-- if (husb->intr_urb->transfer_buffer)
-- kfree(husb->intr_urb->transfer_buffer);
-- usb_free_urb(husb->intr_urb);
-+struct _urb *_urb_dequeue(struct _urb_queue *q)
-+{
-+ struct _urb *_urb = NULL;
-+ unsigned long flags;
-+ spin_lock_irqsave(&q->lock, flags);
-+ {
-+ struct list_head *head = &q->head;
-+ struct list_head *next = head->next;
-+ if (next != head) {
-+ _urb = list_entry(next, struct _urb, list);
-+ list_del(next); _urb->queue = NULL;
-+ }
- }
-+ spin_unlock_irqrestore(&q->lock, flags);
-+ return _urb;
-+}
-
-- if (husb->ctrl_urb)
-- usb_free_urb(husb->ctrl_urb);
-+static void hci_usb_rx_complete(struct urb *urb);
-+static void hci_usb_tx_complete(struct urb *urb);
-
-- if (husb->write_urb)
-- usb_free_urb(husb->write_urb);
-+#define __pending_tx(husb, type) (&husb->pending_tx[type-1])
-+#define __pending_q(husb, type) (&husb->pending_q[type-1])
-+#define __completed_q(husb, type) (&husb->completed_q[type-1])
-+#define __transmit_q(husb, type) (&husb->transmit_q[type-1])
-+#define __reassembly(husb, type) (husb->reassembly[type-1])
-
-- if (husb->intr_skb)
-- kfree_skb(husb->intr_skb);
-+static inline struct _urb *__get_completed(struct hci_usb *husb, int type)
-+{
-+ return _urb_dequeue(__completed_q(husb, type));
- }
-
--/* ------- Interface to HCI layer ------ */
--/* Initialize device */
--int hci_usb_open(struct hci_dev *hdev)
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+static void __fill_isoc_desc(struct urb *urb, int len, int mtu)
- {
-- struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-- int status;
--
-- DBG("%s", hdev->name);
--
-- husb->read_urb->dev = husb->udev;
-- if ((status = usb_submit_urb(husb->read_urb)))
-- DBG("read submit failed. %d", status);
--
-- husb->intr_urb->dev = husb->udev;
-- if ((status = usb_submit_urb(husb->intr_urb)))
-- DBG("interrupt submit failed. %d", status);
-+ int offset = 0, i;
-
-- hdev->flags |= HCI_RUNNING;
-+ BT_DBG("len %d mtu %d", len, mtu);
-
-- return 0;
-+ for (i=0; i < HCI_MAX_ISOC_FRAMES && len >= mtu; i++, offset += mtu, len -= mtu) {
-+ urb->iso_frame_desc[i].offset = offset;
-+ urb->iso_frame_desc[i].length = mtu;
-+ BT_DBG("desc %d offset %d len %d", i, offset, mtu);
-+ }
-+ if (len && i < HCI_MAX_ISOC_FRAMES) {
-+ urb->iso_frame_desc[i].offset = offset;
-+ urb->iso_frame_desc[i].length = len;
-+ BT_DBG("desc %d offset %d len %d", i, offset, len);
-+ i++;
-+ }
-+ urb->number_of_packets = i;
- }
-+#endif
-
--/* Reset device */
--int hci_usb_flush(struct hci_dev *hdev)
-+static int hci_usb_intr_rx_submit(struct hci_usb *husb)
- {
-- struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-+ struct _urb *_urb;
-+ struct urb *urb;
-+ int err, pipe, interval, size;
-+ void *buf;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s", husb->hdev.name);
-
-- /* Drop TX queues */
-- skb_queue_purge(&husb->tx_ctrl_q);
-- skb_queue_purge(&husb->tx_write_q);
-+ size = husb->intr_in_ep->wMaxPacketSize;
-
-- return 0;
-+ buf = kmalloc(size, GFP_ATOMIC);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ _urb = _urb_alloc(0, GFP_ATOMIC);
-+ if (!_urb) {
-+ kfree(buf);
-+ return -ENOMEM;
-+ }
-+ _urb->type = HCI_EVENT_PKT;
-+ _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
-+
-+ urb = &_urb->urb;
-+ pipe = usb_rcvintpipe(husb->udev, husb->intr_in_ep->bEndpointAddress);
-+ interval = husb->intr_in_ep->bInterval;
-+ FILL_INT_URB(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb, interval);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s intr rx submit failed urb %p err %d",
-+ husb->hdev.name, urb, err);
-+ _urb_unlink(_urb);
-+ _urb_free(_urb);
-+ kfree(buf);
-+ }
-+ return err;
- }
-
--/* Close device */
--int hci_usb_close(struct hci_dev *hdev)
-+static int hci_usb_bulk_rx_submit(struct hci_usb *husb)
- {
-- struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-+ struct _urb *_urb;
-+ struct urb *urb;
-+ int err, pipe, size = HCI_MAX_FRAME_SIZE;
-+ void *buf;
-
-- DBG("%s", hdev->name);
-+ buf = kmalloc(size, GFP_ATOMIC);
-+ if (!buf)
-+ return -ENOMEM;
-
-- hdev->flags &= ~HCI_RUNNING;
-- hci_usb_unlink_urbs(husb);
-+ _urb = _urb_alloc(0, GFP_ATOMIC);
-+ if (!_urb) {
-+ kfree(buf);
-+ return -ENOMEM;
-+ }
-+ _urb->type = HCI_ACLDATA_PKT;
-+ _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
-
-- hci_usb_flush(hdev);
-+ urb = &_urb->urb;
-+ pipe = usb_rcvbulkpipe(husb->udev, husb->bulk_in_ep->bEndpointAddress);
-+ FILL_BULK_URB(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb);
-+ urb->transfer_flags = USB_QUEUE_BULK;
-
-- return 0;
-+ BT_DBG("%s urb %p", husb->hdev.name, urb);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s bulk rx submit failed urb %p err %d",
-+ husb->hdev.name, urb, err);
-+ _urb_unlink(_urb);
-+ _urb_free(_urb);
-+ kfree(buf);
-+ }
-+ return err;
- }
-
--void hci_usb_ctrl_wakeup(struct hci_usb *husb)
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+static int hci_usb_isoc_rx_submit(struct hci_usb *husb)
- {
-- struct sk_buff *skb;
--
-- if (test_and_set_bit(HCI_TX_CTRL, &husb->tx_state))
-- return;
-+ struct _urb *_urb;
-+ struct urb *urb;
-+ int err, mtu, size;
-+ void *buf;
-
-- DBG("%s", husb->hdev.name);
-+ mtu = husb->isoc_in_ep->wMaxPacketSize;
-+ size = mtu * HCI_MAX_ISOC_FRAMES;
-
-- if (!(skb = skb_dequeue(&husb->tx_ctrl_q)))
-- goto done;
-+ buf = kmalloc(size, GFP_ATOMIC);
-+ if (!buf)
-+ return -ENOMEM;
-
-- if (hci_usb_ctrl_msg(husb, skb)){
-- kfree_skb(skb);
-- goto done;
-+ _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
-+ if (!_urb) {
-+ kfree(buf);
-+ return -ENOMEM;
- }
-+ _urb->type = HCI_SCODATA_PKT;
-+ _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
-
-- DMP(skb->data, skb->len);
-+ urb = &_urb->urb;
-
-- husb->hdev.stat.byte_tx += skb->len;
-- return;
-+ urb->context = husb;
-+ urb->dev = husb->udev;
-+ urb->pipe = usb_rcvisocpipe(husb->udev, husb->isoc_in_ep->bEndpointAddress);
-+ urb->complete = hci_usb_rx_complete;
-
--done:
-- clear_bit(HCI_TX_CTRL, &husb->tx_state);
-- return;
-+ urb->transfer_buffer_length = size;
-+ urb->transfer_buffer = buf;
-+ urb->transfer_flags = USB_ISO_ASAP;
-+
-+ __fill_isoc_desc(urb, size, mtu);
-+
-+ BT_DBG("%s urb %p", husb->hdev.name, urb);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s isoc rx submit failed urb %p err %d",
-+ husb->hdev.name, urb, err);
-+ _urb_unlink(_urb);
-+ _urb_free(_urb);
-+ kfree(buf);
-+ }
-+ return err;
- }
-+#endif
-
--void hci_usb_write_wakeup(struct hci_usb *husb)
-+/* Initialize device */
-+static int hci_usb_open(struct hci_dev *hdev)
- {
-- struct sk_buff *skb;
-+ struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-+ int i, err;
-+ unsigned long flags;
-
-- if (test_and_set_bit(HCI_TX_WRITE, &husb->tx_state))
-- return;
-+ BT_DBG("%s", hdev->name);
-
-- DBG("%s", husb->hdev.name);
-+ if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-
-- if (!(skb = skb_dequeue(&husb->tx_write_q)))
-- goto done;
-+ MOD_INC_USE_COUNT;
-
-- if (hci_usb_write_msg(husb, skb)) {
-- skb_queue_head(&husb->tx_write_q, skb);
-- goto done;
-+ write_lock_irqsave(&husb->completion_lock, flags);
-+
-+ err = hci_usb_intr_rx_submit(husb);
-+ if (!err) {
-+ for (i = 0; i < HCI_MAX_BULK_RX; i++)
-+ hci_usb_bulk_rx_submit(husb);
-+
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ if (husb->isoc_iface)
-+ for (i = 0; i < HCI_MAX_ISOC_RX; i++)
-+ hci_usb_isoc_rx_submit(husb);
-+#endif
-+ } else {
-+ clear_bit(HCI_RUNNING, &hdev->flags);
-+ MOD_DEC_USE_COUNT;
- }
-
-- DMP(skb->data, skb->len);
-+ write_unlock_irqrestore(&husb->completion_lock, flags);
-+ return err;
-+}
-
-- husb->hdev.stat.byte_tx += skb->len;
-- return;
-+/* Reset device */
-+static int hci_usb_flush(struct hci_dev *hdev)
-+{
-+ struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-+ int i;
-
--done:
-- clear_bit(HCI_TX_WRITE, &husb->tx_state);
-- return;
-+ BT_DBG("%s", hdev->name);
-+
-+ for (i=0; i < 4; i++)
-+ skb_queue_purge(&husb->transmit_q[i]);
-+ return 0;
- }
-
--/* Send frames from HCI layer */
--int hci_usb_send_frame(struct sk_buff *skb)
-+static void hci_usb_unlink_urbs(struct hci_usb *husb)
- {
-- struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-- struct hci_usb *husb;
-+ int i;
-
-- if (!hdev) {
-- ERR("frame for uknown device (hdev=NULL)");
-- return -ENODEV;
-- }
-+ BT_DBG("%s", husb->hdev.name);
-
-- if (!(hdev->flags & HCI_RUNNING))
-- return 0;
-+ for (i=0; i < 4; i++) {
-+ struct _urb *_urb;
-+ struct urb *urb;
-
-- husb = (struct hci_usb *) hdev->driver_data;
-+ /* Kill pending requests */
-+ while ((_urb = _urb_dequeue(&husb->pending_q[i]))) {
-+ urb = &_urb->urb;
-+ BT_DBG("%s unlinking _urb %p type %d urb %p",
-+ husb->hdev.name, _urb, _urb->type, urb);
-+ usb_unlink_urb(urb);
-+ _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
-+ }
-
-- DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-+ /* Release completed requests */
-+ while ((_urb = _urb_dequeue(&husb->completed_q[i]))) {
-+ urb = &_urb->urb;
-+ BT_DBG("%s freeing _urb %p type %d urb %p",
-+ husb->hdev.name, _urb, _urb->type, urb);
-+ if (urb->setup_packet)
-+ kfree(urb->setup_packet);
-+ if (urb->transfer_buffer)
-+ kfree(urb->transfer_buffer);
-+ _urb_free(_urb);
-+ }
-
-- switch (skb->pkt_type) {
-- case HCI_COMMAND_PKT:
-- skb_queue_tail(&husb->tx_ctrl_q, skb);
-- hci_usb_ctrl_wakeup(husb);
-- hdev->stat.cmd_tx++;
-- return 0;
-+ /* Release reassembly buffers */
-+ if (husb->reassembly[i]) {
-+ kfree_skb(husb->reassembly[i]);
-+ husb->reassembly[i] = NULL;
-+ }
-+ }
-+}
-
-- case HCI_ACLDATA_PKT:
-- skb_queue_tail(&husb->tx_write_q, skb);
-- hci_usb_write_wakeup(husb);
-- hdev->stat.acl_tx++;
-- return 0;
-+/* Close device */
-+static int hci_usb_close(struct hci_dev *hdev)
-+{
-+ struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-+ unsigned long flags;
-+
-+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-
-- case HCI_SCODATA_PKT:
-- return -EOPNOTSUPP;
-- };
-+ BT_DBG("%s", hdev->name);
-+
-+ write_lock_irqsave(&husb->completion_lock, flags);
-+
-+ hci_usb_unlink_urbs(husb);
-+ hci_usb_flush(hdev);
-+
-+ write_unlock_irqrestore(&husb->completion_lock, flags);
-
-+ MOD_DEC_USE_COUNT;
- return 0;
- }
-
--/* ---------- USB ------------- */
-+static int __tx_submit(struct hci_usb *husb, struct _urb *_urb)
-+{
-+ struct urb *urb = &_urb->urb;
-+ int err;
-
--static void hci_usb_ctrl(struct urb *urb)
-+ BT_DBG("%s urb %p type %d", husb->hdev.name, urb, _urb->type);
-+
-+ _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s tx submit failed urb %p type %d err %d",
-+ husb->hdev.name, urb, _urb->type, err);
-+ _urb_unlink(_urb);
-+ _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
-+ } else
-+ atomic_inc(__pending_tx(husb, _urb->type));
-+
-+ return err;
-+}
-+
-+static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
- {
-- struct sk_buff *skb = (struct sk_buff *) urb->context;
-- struct hci_dev *hdev;
-- struct hci_usb *husb;
-+ struct _urb *_urb = __get_completed(husb, skb->pkt_type);
-+ devrequest *dr;
-+ struct urb *urb;
-
-- if (!skb)
-- return;
-- hdev = (struct hci_dev *) skb->dev;
-- husb = (struct hci_usb *) hdev->driver_data;
-+ if (!_urb) {
-+ _urb = _urb_alloc(0, GFP_ATOMIC);
-+ if (!_urb)
-+ return -ENOMEM;
-+ _urb->type = skb->pkt_type;
-
-- DBG("%s", hdev->name);
-+ dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
-+ if (!dr) {
-+ _urb_free(_urb);
-+ return -ENOMEM;
-+ }
-+ } else
-+ dr = (void *) _urb->urb.setup_packet;
-
-- if (urb->status)
-- DBG("%s ctrl status: %d", hdev->name, urb->status);
-+ dr->requesttype = husb->ctrl_req;
-+ dr->request = 0;
-+ dr->index = 0;
-+ dr->value = 0;
-+ dr->length = __cpu_to_le16(skb->len);
-
-- clear_bit(HCI_TX_CTRL, &husb->tx_state);
-- kfree_skb(skb);
-+ urb = &_urb->urb;
-+ FILL_CONTROL_URB(urb, husb->udev, usb_sndctrlpipe(husb->udev, 0),
-+ (void *) dr, skb->data, skb->len, hci_usb_tx_complete, husb);
-
-- /* Wake up device */
-- hci_usb_ctrl_wakeup(husb);
-+ BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
-+
-+ _urb->priv = skb;
-+ return __tx_submit(husb, _urb);
- }
-
--static void hci_usb_bulk_write(struct urb *urb)
-+static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
- {
-- struct sk_buff *skb = (struct sk_buff *) urb->context;
-- struct hci_dev *hdev;
-- struct hci_usb *husb;
--
-- if (!skb)
-- return;
-- hdev = (struct hci_dev *) skb->dev;
-- husb = (struct hci_usb *) hdev->driver_data;
--
-- DBG("%s", hdev->name);
-+ struct _urb *_urb = __get_completed(husb, skb->pkt_type);
-+ struct urb *urb;
-+ int pipe;
-
-- if (urb->status)
-- DBG("%s bulk write status: %d", hdev->name, urb->status);
-+ if (!_urb) {
-+ _urb = _urb_alloc(0, GFP_ATOMIC);
-+ if (!_urb)
-+ return -ENOMEM;
-+ _urb->type = skb->pkt_type;
-+ }
-
-- clear_bit(HCI_TX_WRITE, &husb->tx_state);
-- kfree_skb(skb);
-+ urb = &_urb->urb;
-+ pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep->bEndpointAddress);
-+ FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,
-+ hci_usb_tx_complete, husb);
-+ urb->transfer_flags = USB_QUEUE_BULK | USB_ZERO_PACKET;
-
-- /* Wake up device */
-- hci_usb_write_wakeup(husb);
-+ BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
-
-- return;
-+ _urb->priv = skb;
-+ return __tx_submit(husb, _urb);
- }
-
--static void hci_usb_intr(struct urb *urb)
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb)
- {
-- struct hci_usb *husb = (struct hci_usb *) urb->context;
-- unsigned char *data = urb->transfer_buffer;
-- register int count = urb->actual_length;
-- register struct sk_buff *skb = husb->intr_skb;
-- hci_event_hdr *eh;
-- register int len;
-+ struct _urb *_urb = __get_completed(husb, skb->pkt_type);
-+ struct urb *urb;
-+
-+ if (!_urb) {
-+ _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
-+ if (!_urb)
-+ return -ENOMEM;
-+ _urb->type = skb->pkt_type;
-+ }
-
-- if (!husb)
-- return;
-+ BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
-
-- DBG("%s count %d", husb->hdev.name, count);
-+ urb = &_urb->urb;
-+
-+ urb->context = husb;
-+ urb->dev = husb->udev;
-+ urb->pipe = usb_sndisocpipe(husb->udev, husb->isoc_out_ep->bEndpointAddress);
-+ urb->complete = hci_usb_tx_complete;
-+ urb->transfer_flags = USB_ISO_ASAP;
-
-- if (urb->status || !count) {
-- DBG("%s intr status %d, count %d", husb->hdev.name, urb->status, count);
-- return;
-- }
-+ urb->transfer_buffer = skb->data;
-+ urb->transfer_buffer_length = skb->len;
-+
-+ __fill_isoc_desc(urb, skb->len, husb->isoc_out_ep->wMaxPacketSize);
-
-- /* Do we really have to handle continuations here ? */
-- if (!skb) {
-- /* New frame */
-- if (count < HCI_EVENT_HDR_SIZE) {
-- DBG("%s bad frame len %d", husb->hdev.name, count);
-- return;
-- }
-+ _urb->priv = skb;
-+ return __tx_submit(husb, _urb);
-+}
-+#endif
-
-- eh = (hci_event_hdr *) data;
-- len = eh->plen + HCI_EVENT_HDR_SIZE;
-+static void hci_usb_tx_process(struct hci_usb *husb)
-+{
-+ struct sk_buff_head *q;
-+ struct sk_buff *skb;
-
-- if (count > len) {
-- DBG("%s corrupted frame, len %d", husb->hdev.name, count);
-- return;
-+ BT_DBG("%s", husb->hdev.name);
-+
-+ do {
-+ clear_bit(HCI_USB_TX_WAKEUP, &husb->state);
-+
-+ /* Process command queue */
-+ q = __transmit_q(husb, HCI_COMMAND_PKT);
-+ if (!atomic_read(__pending_tx(husb, HCI_COMMAND_PKT)) &&
-+ (skb = skb_dequeue(q))) {
-+ if (hci_usb_send_ctrl(husb, skb) < 0)
-+ skb_queue_head(q, skb);
- }
-
-- /* Allocate skb */
-- if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {
-- ERR("Can't allocate mem for new packet");
-- return;
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ /* Process SCO queue */
-+ q = __transmit_q(husb, HCI_SCODATA_PKT);
-+ if (atomic_read(__pending_tx(husb, HCI_SCODATA_PKT)) < HCI_MAX_ISOC_TX &&
-+ (skb = skb_dequeue(q))) {
-+ if (hci_usb_send_isoc(husb, skb) < 0)
-+ skb_queue_head(q, skb);
- }
-- skb->dev = (void *) &husb->hdev;
-- skb->pkt_type = HCI_EVENT_PKT;
-+#endif
-+
-+ /* Process ACL queue */
-+ q = __transmit_q(husb, HCI_ACLDATA_PKT);
-+ while (atomic_read(__pending_tx(husb, HCI_ACLDATA_PKT)) < HCI_MAX_BULK_TX &&
-+ (skb = skb_dequeue(q))) {
-+ if (hci_usb_send_bulk(husb, skb) < 0) {
-+ skb_queue_head(q, skb);
-+ break;
-+ }
-+ }
-+ } while(test_bit(HCI_USB_TX_WAKEUP, &husb->state));
-+}
-
-- husb->intr_skb = skb;
-- husb->intr_count = len;
-- } else {
-- /* Continuation */
-- if (count > husb->intr_count) {
-- ERR("%s bad frame len %d (expected %d)", husb->hdev.name, count, husb->intr_count);
-+static inline void hci_usb_tx_wakeup(struct hci_usb *husb)
-+{
-+ /* Serialize TX queue processing to avoid data reordering */
-+ if (!test_and_set_bit(HCI_USB_TX_PROCESS, &husb->state)) {
-+ hci_usb_tx_process(husb);
-+ clear_bit(HCI_USB_TX_PROCESS, &husb->state);
-+ } else
-+ set_bit(HCI_USB_TX_WAKEUP, &husb->state);
-+}
-
-- kfree_skb(skb);
-- husb->intr_skb = NULL;
-- husb->intr_count = 0;
-- return;
-- }
-+/* Send frames from HCI layer */
-+static int hci_usb_send_frame(struct sk_buff *skb)
-+{
-+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-+ struct hci_usb *husb;
-+
-+ if (!hdev) {
-+ BT_ERR("frame for uknown device (hdev=NULL)");
-+ return -ENODEV;
- }
-
-- memcpy(skb_put(skb, count), data, count);
-- husb->intr_count -= count;
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return -EBUSY;
-
-- DMP(data, count);
-+ BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-
-- if (!husb->intr_count) {
-- /* Got complete frame */
-+ husb = (struct hci_usb *) hdev->driver_data;
-
-- husb->hdev.stat.byte_rx += skb->len;
-- hci_recv_frame(skb);
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-
-- husb->intr_skb = NULL;
-- }
--}
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-
--static void hci_usb_bulk_read(struct urb *urb)
--{
-- struct hci_usb *husb = (struct hci_usb *) urb->context;
-- unsigned char *data = urb->transfer_buffer;
-- int count = urb->actual_length, status;
-- struct sk_buff *skb;
-- hci_acl_hdr *ah;
-- register __u16 dlen;
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+#endif
-
-- if (!husb)
-- return;
-+ default:
-+ kfree_skb(skb);
-+ return 0;
-+ }
-
-- DBG("%s status %d, count %d, flags %x", husb->hdev.name, urb->status, count, urb->transfer_flags);
-+ read_lock(&husb->completion_lock);
-
-- if (urb->status) {
-- /* Do not re-submit URB on critical errors */
-- switch (urb->status) {
-- case -ENOENT:
-- return;
-- default:
-- goto resubmit;
-- };
-- }
-- if (!count)
-- goto resubmit;
-+ skb_queue_tail(__transmit_q(husb, skb->pkt_type), skb);
-+ hci_usb_tx_wakeup(husb);
-
-- DMP(data, count);
-+ read_unlock(&husb->completion_lock);
-+ return 0;
-+}
-
-- ah = (hci_acl_hdr *) data;
-- dlen = le16_to_cpu(ah->dlen);
-+static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int count)
-+{
-+ BT_DBG("%s type %d data %p count %d", husb->hdev.name, type, data, count);
-
-- /* Verify frame len and completeness */
-- if ((count - HCI_ACL_HDR_SIZE) != dlen) {
-- ERR("%s corrupted ACL packet: count %d, plen %d", husb->hdev.name, count, dlen);
-- goto resubmit;
-- }
-+ husb->hdev.stat.byte_rx += count;
-
-- /* Allocate packet */
-- if (!(skb = bluez_skb_alloc(count, GFP_ATOMIC))) {
-- ERR("Can't allocate mem for new packet");
-- goto resubmit;
-- }
-+ while (count) {
-+ struct sk_buff *skb = __reassembly(husb, type);
-+ struct { int expect; } *scb;
-+ int len = 0;
-+
-+ if (!skb) {
-+ /* Start of the frame */
-
-- memcpy(skb_put(skb, count), data, count);
-- skb->dev = (void *) &husb->hdev;
-- skb->pkt_type = HCI_ACLDATA_PKT;
-+ switch (type) {
-+ case HCI_EVENT_PKT:
-+ if (count >= HCI_EVENT_HDR_SIZE) {
-+ hci_event_hdr *h = data;
-+ len = HCI_EVENT_HDR_SIZE + h->plen;
-+ } else
-+ return -EILSEQ;
-+ break;
-
-- husb->hdev.stat.byte_rx += skb->len;
-+ case HCI_ACLDATA_PKT:
-+ if (count >= HCI_ACL_HDR_SIZE) {
-+ hci_acl_hdr *h = data;
-+ len = HCI_ACL_HDR_SIZE + __le16_to_cpu(h->dlen);
-+ } else
-+ return -EILSEQ;
-+ break;
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ case HCI_SCODATA_PKT:
-+ if (count >= HCI_SCO_HDR_SIZE) {
-+ hci_sco_hdr *h = data;
-+ len = HCI_SCO_HDR_SIZE + h->dlen;
-+ } else
-+ return -EILSEQ;
-+ break;
-+#endif
-+ }
-+ BT_DBG("new packet len %d", len);
-+
-+ skb = bluez_skb_alloc(len, GFP_ATOMIC);
-+ if (!skb) {
-+ BT_ERR("%s no memory for the packet", husb->hdev.name);
-+ return -ENOMEM;
-+ }
-+ skb->dev = (void *) &husb->hdev;
-+ skb->pkt_type = type;
-+
-+ __reassembly(husb, type) = skb;
-
-- hci_recv_frame(skb);
-+ scb = (void *) skb->cb;
-+ scb->expect = len;
-+ } else {
-+ /* Continuation */
-+ scb = (void *) skb->cb;
-+ len = scb->expect;
-+ }
-
--resubmit:
-- husb->read_urb->dev = husb->udev;
-- if ((status = usb_submit_urb(husb->read_urb)))
-- DBG("%s read URB submit failed %d", husb->hdev.name, status);
-+ len = min(len, count);
-+
-+ memcpy(skb_put(skb, len), data, len);
-
-- DBG("%s read URB re-submited", husb->hdev.name);
-+ scb->expect -= len;
-+ if (!scb->expect) {
-+ /* Complete frame */
-+ __reassembly(husb, type) = NULL;
-+ hci_recv_frame(skb);
-+ }
-+
-+ count -= len; data += len;
-+ }
-+ return 0;
- }
-
--static int hci_usb_ctrl_msg(struct hci_usb *husb, struct sk_buff *skb)
-+static void hci_usb_rx_complete(struct urb *urb)
- {
-- struct urb *urb = husb->ctrl_urb;
-- devrequest *dr = &husb->dev_req;
-- int pipe, status;
-+ struct _urb *_urb = container_of(urb, struct _urb, urb);
-+ struct hci_usb *husb = (void *) urb->context;
-+ struct hci_dev *hdev = &husb->hdev;
-+ int err, count = urb->actual_length;
-
-- DBG("%s len %d", husb->hdev.name, skb->len);
-+ BT_DBG("%s urb %p type %d status %d count %d flags %x", hdev->name, urb,
-+ _urb->type, urb->status, count, urb->transfer_flags);
-
-- pipe = usb_sndctrlpipe(husb->udev, 0);
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return;
-
-- dr->requesttype = HCI_CTRL_REQ;
-- dr->request = 0;
-- dr->index = 0;
-- dr->value = 0;
-- dr->length = cpu_to_le16(skb->len);
-+ read_lock(&husb->completion_lock);
-
-- FILL_CONTROL_URB(urb, husb->udev, pipe, (void*)dr, skb->data, skb->len,
-- hci_usb_ctrl, skb);
-+ if (urb->status || !count)
-+ goto resubmit;
-
-- if ((status = usb_submit_urb(urb))) {
-- DBG("%s control URB submit failed %d", husb->hdev.name, status);
-- return status;
-+ if (_urb->type == HCI_SCODATA_PKT) {
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ int i;
-+ for (i=0; i < urb->number_of_packets; i++) {
-+ BT_DBG("desc %d status %d offset %d len %d", i,
-+ urb->iso_frame_desc[i].status,
-+ urb->iso_frame_desc[i].offset,
-+ urb->iso_frame_desc[i].actual_length);
-+
-+ if (!urb->iso_frame_desc[i].status)
-+ __recv_frame(husb, _urb->type,
-+ urb->transfer_buffer + urb->iso_frame_desc[i].offset,
-+ urb->iso_frame_desc[i].actual_length);
-+ }
-+#else
-+ ;
-+#endif
-+ } else {
-+ err = __recv_frame(husb, _urb->type, urb->transfer_buffer, count);
-+ if (err < 0) {
-+ BT_ERR("%s corrupted packet: type %d count %d",
-+ husb->hdev.name, _urb->type, count);
-+ hdev->stat.err_rx++;
-+ }
- }
-
-- return 0;
-+resubmit:
-+ if (_urb->type != HCI_EVENT_PKT) {
-+ urb->dev = husb->udev;
-+ err = usb_submit_urb(urb);
-+ BT_DBG("%s urb %p type %d resubmit status %d", hdev->name, urb,
-+ _urb->type, err);
-+ }
-+ read_unlock(&husb->completion_lock);
- }
-
--static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb)
-+static void hci_usb_tx_complete(struct urb *urb)
- {
-- struct urb *urb = husb->write_urb;
-- int pipe, status;
-+ struct _urb *_urb = container_of(urb, struct _urb, urb);
-+ struct hci_usb *husb = (void *) urb->context;
-+ struct hci_dev *hdev = &husb->hdev;
-
-- DBG("%s len %d", husb->hdev.name, skb->len);
-+ BT_DBG("%s urb %p status %d flags %x", hdev->name, urb,
-+ urb->status, urb->transfer_flags);
-
-- pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep_addr);
-+ atomic_dec(__pending_tx(husb, _urb->type));
-
-- FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,
-- hci_usb_bulk_write, skb);
-- urb->transfer_flags |= USB_QUEUE_BULK;
-+ urb->transfer_buffer = NULL;
-+ kfree_skb((struct sk_buff *) _urb->priv);
-
-- if ((status = usb_submit_urb(urb))) {
-- DBG("%s write URB submit failed %d", husb->hdev.name, status);
-- return status;
-- }
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return;
-
-- return 0;
-+ if (!urb->status)
-+ hdev->stat.byte_tx += urb->transfer_buffer_length;
-+ else
-+ hdev->stat.err_tx++;
-+
-+ read_lock(&husb->completion_lock);
-+
-+ _urb_unlink(_urb);
-+ _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
-+
-+ hci_usb_tx_wakeup(husb);
-+
-+ read_unlock(&husb->completion_lock);
- }
-
--static void * hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
-+static void hci_usb_destruct(struct hci_dev *hdev)
- {
-- struct usb_endpoint_descriptor *bulk_out_ep, *intr_in_ep, *bulk_in_ep;
-+ struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-+
-+ BT_DBG("%s", hdev->name);
-+
-+ kfree(husb);
-+}
-+
-+static void *hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
-+{
-+ struct usb_endpoint_descriptor *bulk_out_ep[HCI_MAX_IFACE_NUM];
-+ struct usb_endpoint_descriptor *isoc_out_ep[HCI_MAX_IFACE_NUM];
-+ struct usb_endpoint_descriptor *bulk_in_ep[HCI_MAX_IFACE_NUM];
-+ struct usb_endpoint_descriptor *isoc_in_ep[HCI_MAX_IFACE_NUM];
-+ struct usb_endpoint_descriptor *intr_in_ep[HCI_MAX_IFACE_NUM];
- struct usb_interface_descriptor *uif;
- struct usb_endpoint_descriptor *ep;
-+ struct usb_interface *iface, *isoc_iface;
- struct hci_usb *husb;
- struct hci_dev *hdev;
-- int i, size, pipe;
-- __u8 * buf;
--
-- DBG("udev %p ifnum %d", udev, ifnum);
-+ int i, a, e, size, ifn, isoc_ifnum, isoc_alts;
-
-- /* Check device signature */
-- if ((udev->descriptor.bDeviceClass != HCI_DEV_CLASS) ||
-- (udev->descriptor.bDeviceSubClass != HCI_DEV_SUBCLASS)||
-- (udev->descriptor.bDeviceProtocol != HCI_DEV_PROTOCOL) )
-- return NULL;
-+ BT_DBG("udev %p ifnum %d", udev, ifnum);
-
-- MOD_INC_USE_COUNT;
-+ iface = &udev->actconfig->interface[0];
-
-- uif = &udev->actconfig->interface[ifnum].altsetting[0];
-+ /* Check our black list */
-+ if (usb_match_id(udev, iface, ignore_ids))
-+ return NULL;
-
-- if (uif->bNumEndpoints != 3) {
-- DBG("Wrong number of endpoints %d", uif->bNumEndpoints);
-- MOD_DEC_USE_COUNT;
-+ /* Check number of endpoints */
-+ if (udev->actconfig->interface[ifnum].altsetting[0].bNumEndpoints < 3)
- return NULL;
-- }
-
-- bulk_out_ep = intr_in_ep = bulk_in_ep = NULL;
-+ memset(bulk_out_ep, 0, sizeof(bulk_out_ep));
-+ memset(isoc_out_ep, 0, sizeof(isoc_out_ep));
-+ memset(bulk_in_ep, 0, sizeof(bulk_in_ep));
-+ memset(isoc_in_ep, 0, sizeof(isoc_in_ep));
-+ memset(intr_in_ep, 0, sizeof(intr_in_ep));
-
-+ size = 0;
-+ isoc_iface = NULL;
-+ isoc_alts = isoc_ifnum = 0;
-+
- /* Find endpoints that we need */
-- for ( i = 0; i < uif->bNumEndpoints; ++i) {
-- ep = &uif->endpoint[i];
-
-- switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
-- case USB_ENDPOINT_XFER_BULK:
-- if (ep->bEndpointAddress & USB_DIR_IN)
-- bulk_in_ep = ep;
-- else
-- bulk_out_ep = ep;
-- break;
--
-- case USB_ENDPOINT_XFER_INT:
-- intr_in_ep = ep;
-- break;
-- };
-- }
-+ ifn = MIN(udev->actconfig->bNumInterfaces, HCI_MAX_IFACE_NUM);
-+ for (i = 0; i < ifn; i++) {
-+ iface = &udev->actconfig->interface[i];
-+ for (a = 0; a < iface->num_altsetting; a++) {
-+ uif = &iface->altsetting[a];
-+ for (e = 0; e < uif->bNumEndpoints; e++) {
-+ ep = &uif->endpoint[e];
-
-- if (!bulk_in_ep || !bulk_out_ep || !intr_in_ep) {
-- DBG("Endpoints not found: %p %p %p", bulk_in_ep, bulk_out_ep, intr_in_ep);
-- MOD_DEC_USE_COUNT;
-- return NULL;
-- }
-+ switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
-+ case USB_ENDPOINT_XFER_INT:
-+ if (ep->bEndpointAddress & USB_DIR_IN)
-+ intr_in_ep[i] = ep;
-+ break;
-
-- if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
-- ERR("Can't allocate: control structure");
-- MOD_DEC_USE_COUNT;
-- return NULL;
-- }
-+ case USB_ENDPOINT_XFER_BULK:
-+ if (ep->bEndpointAddress & USB_DIR_IN)
-+ bulk_in_ep[i] = ep;
-+ else
-+ bulk_out_ep[i] = ep;
-+ break;
-
-- memset(husb, 0, sizeof(struct hci_usb));
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ case USB_ENDPOINT_XFER_ISOC:
-+ if (ep->wMaxPacketSize < size || a > 2)
-+ break;
-+ size = ep->wMaxPacketSize;
-
-- husb->udev = udev;
-- husb->bulk_out_ep_addr = bulk_out_ep->bEndpointAddress;
-+ isoc_iface = iface;
-+ isoc_alts = a;
-+ isoc_ifnum = i;
-
-- if (!(husb->ctrl_urb = usb_alloc_urb(0))) {
-- ERR("Can't allocate: control URB");
-- goto probe_error;
-+ if (ep->bEndpointAddress & USB_DIR_IN)
-+ isoc_in_ep[i] = ep;
-+ else
-+ isoc_out_ep[i] = ep;
-+ break;
-+#endif
-+ }
-+ }
-+ }
- }
-
-- if (!(husb->write_urb = usb_alloc_urb(0))) {
-- ERR("Can't allocate: write URB");
-- goto probe_error;
-+ if (!bulk_in_ep[0] || !bulk_out_ep[0] || !intr_in_ep[0]) {
-+ BT_DBG("Bulk endpoints not found");
-+ goto done;
- }
-
-- if (!(husb->read_urb = usb_alloc_urb(0))) {
-- ERR("Can't allocate: read URB");
-- goto probe_error;
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ if (!isoc_in_ep[1] || !isoc_out_ep[1]) {
-+ BT_DBG("Isoc endpoints not found");
-+ isoc_iface = NULL;
- }
-+#endif
-
-- ep = bulk_in_ep;
-- pipe = usb_rcvbulkpipe(udev, ep->bEndpointAddress);
-- size = HCI_MAX_FRAME_SIZE;
--
-- if (!(buf = kmalloc(size, GFP_KERNEL))) {
-- ERR("Can't allocate: read buffer");
-- goto probe_error;
-+ if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
-+ BT_ERR("Can't allocate: control structure");
-+ goto done;
- }
-
-- FILL_BULK_URB(husb->read_urb, udev, pipe, buf, size, hci_usb_bulk_read, husb);
-- husb->read_urb->transfer_flags |= USB_QUEUE_BULK;
-+ memset(husb, 0, sizeof(struct hci_usb));
-
-- ep = intr_in_ep;
-- pipe = usb_rcvintpipe(udev, ep->bEndpointAddress);
-- size = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
-+ husb->udev = udev;
-+ husb->bulk_out_ep = bulk_out_ep[0];
-+ husb->bulk_in_ep = bulk_in_ep[0];
-+ husb->intr_in_ep = intr_in_ep[0];
-
-- if (!(husb->intr_urb = usb_alloc_urb(0))) {
-- ERR("Can't allocate: interrupt URB");
-- goto probe_error;
-- }
-+ if (id->driver_info & HCI_DIGIANSWER)
-+ husb->ctrl_req = HCI_DIGI_REQ;
-+ else
-+ husb->ctrl_req = HCI_CTRL_REQ;
-
-- if (!(buf = kmalloc(size, GFP_KERNEL))) {
-- ERR("Can't allocate: interrupt buffer");
-- goto probe_error;
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ if (isoc_iface) {
-+ BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, isoc_alts);
-+ if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) {
-+ BT_ERR("Can't set isoc interface settings");
-+ isoc_iface = NULL;
-+ }
-+ usb_driver_claim_interface(&hci_usb_driver, isoc_iface, husb);
-+ husb->isoc_iface = isoc_iface;
-+ husb->isoc_in_ep = isoc_in_ep[isoc_ifnum];
-+ husb->isoc_out_ep = isoc_out_ep[isoc_ifnum];
- }
-+#endif
-+
-+ husb->completion_lock = RW_LOCK_UNLOCKED;
-
-- FILL_INT_URB(husb->intr_urb, udev, pipe, buf, size, hci_usb_intr, husb, ep->bInterval);
--
-- skb_queue_head_init(&husb->tx_ctrl_q);
-- skb_queue_head_init(&husb->tx_write_q);
-+ for (i = 0; i < 4; i++) {
-+ skb_queue_head_init(&husb->transmit_q[i]);
-+ _urb_queue_init(&husb->pending_q[i]);
-+ _urb_queue_init(&husb->completed_q[i]);
-+ }
-
- /* Initialize and register HCI device */
- hdev = &husb->hdev;
-
-- hdev->type = HCI_USB;
-+ hdev->type = HCI_USB;
- hdev->driver_data = husb;
-
- hdev->open = hci_usb_open;
- hdev->close = hci_usb_close;
- hdev->flush = hci_usb_flush;
-- hdev->send = hci_usb_send_frame;
-+ hdev->send = hci_usb_send_frame;
-+ hdev->destruct = hci_usb_destruct;
-
- if (hci_register_dev(hdev) < 0) {
-- ERR("Can't register HCI device %s", hdev->name);
-+ BT_ERR("Can't register HCI device");
- goto probe_error;
- }
-
- return husb;
-
- probe_error:
-- hci_usb_free_bufs(husb);
- kfree(husb);
-- MOD_DEC_USE_COUNT;
-+
-+done:
- return NULL;
- }
-
-@@ -626,38 +943,34 @@
- if (!husb)
- return;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s", hdev->name);
-
- hci_usb_close(hdev);
-
-- if (hci_unregister_dev(hdev) < 0) {
-- ERR("Can't unregister HCI device %s", hdev->name);
-- }
--
-- hci_usb_free_bufs(husb);
-- kfree(husb);
-+ if (husb->isoc_iface)
-+ usb_driver_release_interface(&hci_usb_driver, husb->isoc_iface);
-
-- MOD_DEC_USE_COUNT;
-+ if (hci_unregister_dev(hdev) < 0)
-+ BT_ERR("Can't unregister HCI device %s", hdev->name);
- }
-
--static struct usb_driver hci_usb_driver =
--{
-+static struct usb_driver hci_usb_driver = {
- name: "hci_usb",
- probe: hci_usb_probe,
- disconnect: hci_usb_disconnect,
-- id_table: usb_bluetooth_ids,
-+ id_table: bluetooth_ids,
- };
-
- int hci_usb_init(void)
- {
- int err;
-
-- INF("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-+ BT_INFO("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-
- if ((err = usb_register(&hci_usb_driver)) < 0)
-- ERR("Failed to register HCI USB driver");
-+ BT_ERR("Failed to register HCI USB driver");
-
- return err;
- }
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/bluetooth/hci_usb.h 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,144 @@
-+/*
-+ HCI USB driver for Linux Bluetooth protocol stack (BlueZ)
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ Copyright (C) 2003 Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifdef __KERNEL__
-+
-+/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
-+#define HCI_DEV_CLASS 0xe0 /* Wireless class */
-+#define HCI_DEV_SUBCLASS 0x01 /* RF subclass */
-+#define HCI_DEV_PROTOCOL 0x01 /* Bluetooth programming protocol */
-+
-+#define HCI_CTRL_REQ 0x20
-+#define HCI_DIGI_REQ 0x40
-+
-+#define HCI_DIGIANSWER 0x01
-+
-+#define HCI_MAX_IFACE_NUM 3
-+
-+#define HCI_MAX_BULK_TX 4
-+#define HCI_MAX_BULK_RX 1
-+
-+#define HCI_MAX_ISOC_RX 2
-+#define HCI_MAX_ISOC_TX 2
-+
-+#define HCI_MAX_ISOC_FRAMES 10
-+
-+struct _urb_queue {
-+ struct list_head head;
-+ spinlock_t lock;
-+};
-+
-+struct _urb {
-+ struct list_head list;
-+ struct _urb_queue *queue;
-+ int type;
-+ void *priv;
-+ struct urb urb;
-+};
-+
-+struct _urb *_urb_alloc(int isoc, int gfp);
-+
-+static inline void _urb_free(struct _urb *_urb)
-+{
-+ kfree(_urb);
-+}
-+
-+static inline void _urb_queue_init(struct _urb_queue *q)
-+{
-+ INIT_LIST_HEAD(&q->head);
-+ spin_lock_init(&q->lock);
-+}
-+
-+static inline void _urb_queue_head(struct _urb_queue *q, struct _urb *_urb)
-+{
-+ unsigned long flags;
-+ spin_lock_irqsave(&q->lock, flags);
-+ list_add(&_urb->list, &q->head); _urb->queue = q;
-+ spin_unlock_irqrestore(&q->lock, flags);
-+}
-+
-+static inline void _urb_queue_tail(struct _urb_queue *q, struct _urb *_urb)
-+{
-+ unsigned long flags;
-+ spin_lock_irqsave(&q->lock, flags);
-+ list_add_tail(&_urb->list, &q->head); _urb->queue = q;
-+ spin_unlock_irqrestore(&q->lock, flags);
-+}
-+
-+static inline void _urb_unlink(struct _urb *_urb)
-+{
-+ struct _urb_queue *q = _urb->queue;
-+ unsigned long flags;
-+ if (q) {
-+ spin_lock_irqsave(&q->lock, flags);
-+ list_del(&_urb->list); _urb->queue = NULL;
-+ spin_unlock_irqrestore(&q->lock, flags);
-+ }
-+}
-+
-+struct _urb *_urb_dequeue(struct _urb_queue *q);
-+
-+#ifndef container_of
-+#define container_of(ptr, type, member) ({ \
-+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
-+ (type *)( (char *)__mptr - offsetof(type,member) );})
-+#endif
-+
-+struct hci_usb {
-+ struct hci_dev hdev;
-+
-+ unsigned long state;
-+
-+ struct usb_device *udev;
-+
-+ struct usb_endpoint_descriptor *bulk_in_ep;
-+ struct usb_endpoint_descriptor *bulk_out_ep;
-+ struct usb_endpoint_descriptor *intr_in_ep;
-+
-+ struct usb_interface *isoc_iface;
-+ struct usb_endpoint_descriptor *isoc_out_ep;
-+ struct usb_endpoint_descriptor *isoc_in_ep;
-+
-+ __u8 ctrl_req;
-+
-+ struct sk_buff_head transmit_q[4];
-+ struct sk_buff *reassembly[4]; // Reassembly buffers
-+
-+ rwlock_t completion_lock;
-+
-+ atomic_t pending_tx[4]; // Number of pending requests
-+ struct _urb_queue pending_q[4]; // Pending requests
-+ struct _urb_queue completed_q[4]; // Completed requests
-+};
-+
-+/* States */
-+#define HCI_USB_TX_PROCESS 1
-+#define HCI_USB_TX_WAKEUP 2
-+
-+#endif /* __KERNEL__ */
---- linux/drivers/bluetooth/hci_vhci.c~bluetooth-2.4.18-mh11 2001-09-07 18:28:38.000000000 +0200
-+++ linux/drivers/bluetooth/hci_vhci.c 2004-01-25 23:37:39.000000000 +0100
-@@ -25,9 +25,9 @@
- /*
- * BlueZ HCI virtual device driver.
- *
-- * $Id$
-+ * $Id$
- */
--#define VERSION "1.0"
-+#define VERSION "1.1"
-
- #include <linux/config.h>
- #include <linux/module.h>
-@@ -49,43 +49,56 @@
- #include <asm/uaccess.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/hci_vhci.h>
-+#include "hci_vhci.h"
-
- /* HCI device part */
-
--int hci_vhci_open(struct hci_dev *hdev)
-+static int hci_vhci_open(struct hci_dev *hdev)
- {
-- hdev->flags |= HCI_RUNNING;
-+ set_bit(HCI_RUNNING, &hdev->flags);
- return 0;
- }
-
--int hci_vhci_flush(struct hci_dev *hdev)
-+static int hci_vhci_flush(struct hci_dev *hdev)
- {
- struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
- skb_queue_purge(&hci_vhci->readq);
- return 0;
- }
-
--int hci_vhci_close(struct hci_dev *hdev)
-+static int hci_vhci_close(struct hci_dev *hdev)
- {
-- hdev->flags &= ~HCI_RUNNING;
-+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-+
- hci_vhci_flush(hdev);
- return 0;
- }
-
--int hci_vhci_send_frame(struct sk_buff *skb)
-+static void hci_vhci_destruct(struct hci_dev *hdev)
-+{
-+ struct hci_vhci_struct *vhci;
-+
-+ if (!hdev) return;
-+
-+ vhci = (struct hci_vhci_struct *) hdev->driver_data;
-+ kfree(vhci);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static int hci_vhci_send_frame(struct sk_buff *skb)
- {
- struct hci_dev* hdev = (struct hci_dev *) skb->dev;
- struct hci_vhci_struct *hci_vhci;
-
- if (!hdev) {
-- ERR("Frame for uknown device (hdev=NULL)");
-+ BT_ERR("Frame for uknown device (hdev=NULL)");
- return -ENODEV;
- }
-
-- if (!(hdev->flags & HCI_RUNNING))
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
- return -EBUSY;
-
- hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
-@@ -188,7 +201,7 @@
-
- add_wait_queue(&hci_vhci->read_wait, &wait);
- while (count) {
-- current->state = TASK_INTERRUPTIBLE;
-+ set_current_state(TASK_INTERRUPTIBLE);
-
- /* Read frames from device queue */
- if (!(skb = skb_dequeue(&hci_vhci->readq))) {
-@@ -214,8 +227,7 @@
- kfree_skb(skb);
- break;
- }
--
-- current->state = TASK_RUNNING;
-+ set_current_state(TASK_RUNNING);
- remove_wait_queue(&hci_vhci->read_wait, &wait);
-
- return ret;
-@@ -270,11 +282,13 @@
- hdev->close = hci_vhci_close;
- hdev->flush = hci_vhci_flush;
- hdev->send = hci_vhci_send_frame;
-+ hdev->destruct = hci_vhci_destruct;
-
- if (hci_register_dev(hdev) < 0) {
- kfree(hci_vhci);
- return -EBUSY;
- }
-+ MOD_INC_USE_COUNT;
-
- file->private_data = hci_vhci;
- return 0;
-@@ -285,12 +299,10 @@
- struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
-
- if (hci_unregister_dev(&hci_vhci->hdev) < 0) {
-- ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
-+ BT_ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
- }
-
-- kfree(hci_vhci);
- file->private_data = NULL;
--
- return 0;
- }
-
-@@ -315,12 +327,12 @@
-
- int __init hci_vhci_init(void)
- {
-- INF("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-+ BT_INFO("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-
- if (misc_register(&hci_vhci_miscdev)) {
-- ERR("Can't register misc device %d\n", VHCI_MINOR);
-+ BT_ERR("Can't register misc device %d\n", VHCI_MINOR);
- return -EIO;
- }
-
-@@ -337,4 +349,4 @@
-
- MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
- MODULE_DESCRIPTION("BlueZ VHCI driver ver " VERSION);
--MODULE_LICENSE("GPL");
-+MODULE_LICENSE("GPL");
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/bluetooth/hci_vhci.h 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,50 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef __HCI_VHCI_H
-+#define __HCI_VHCI_H
-+
-+#ifdef __KERNEL__
-+
-+struct hci_vhci_struct {
-+ struct hci_dev hdev;
-+ __u32 flags;
-+ wait_queue_head_t read_wait;
-+ struct sk_buff_head readq;
-+ struct fasync_struct *fasync;
-+};
-+
-+/* VHCI device flags */
-+#define VHCI_FASYNC 0x0010
-+
-+#endif /* __KERNEL__ */
-+
-+#define VHCI_DEV "/dev/vhci"
-+#define VHCI_MINOR 250
-+
-+#endif /* __HCI_VHCI_H */
---- linux/drivers/bluetooth/Makefile~bluetooth-2.4.18-mh11 2001-09-07 18:28:38.000000000 +0200
-+++ linux/drivers/bluetooth/Makefile 2004-01-25 23:37:39.000000000 +0100
-@@ -1,11 +1,27 @@
- #
--# Makefile for Bluetooth HCI device drivers.
-+# Makefile for the Linux Bluetooth HCI device drivers
- #
-
- O_TARGET := bluetooth.o
-
-+list-multi := hci_uart.o
-+
- obj-$(CONFIG_BLUEZ_HCIUSB) += hci_usb.o
--obj-$(CONFIG_BLUEZ_HCIUART) += hci_uart.o
- obj-$(CONFIG_BLUEZ_HCIVHCI) += hci_vhci.o
-
-+obj-$(CONFIG_BLUEZ_HCIUART) += hci_uart.o
-+uart-y := hci_ldisc.o
-+uart-$(CONFIG_BLUEZ_HCIUART_H4) += hci_h4.o
-+uart-$(CONFIG_BLUEZ_HCIUART_BCSP) += hci_bcsp.o
-+
-+obj-$(CONFIG_BLUEZ_HCIBFUSB) += bfusb.o
-+
-+obj-$(CONFIG_BLUEZ_HCIDTL1) += dtl1_cs.o
-+obj-$(CONFIG_BLUEZ_HCIBT3C) += bt3c_cs.o
-+obj-$(CONFIG_BLUEZ_HCIBLUECARD) += bluecard_cs.o
-+obj-$(CONFIG_BLUEZ_HCIBTUART) += btuart_cs.o
-+
- include $(TOPDIR)/Rules.make
-+
-+hci_uart.o: $(uart-y)
-+ $(LD) -r -o $@ $(uart-y)
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/bluetooth/Makefile.lib 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1 @@
-+obj-$(CONFIG_BLUEZ_HCIBFUSB) += firmware_class.o
---- linux/drivers/char/pcmcia/serial_cs.c~bluetooth-2.4.18-mh11 2004-01-25 23:28:22.000000000 +0100
-+++ linux/drivers/char/pcmcia/serial_cs.c 2004-01-25 23:37:39.000000000 +0100
-@@ -72,14 +72,14 @@
- static int irq_list[4] = { -1 };
- MODULE_PARM(irq_list, "1-4i");
-
--/* Enable the speaker? */
--INT_MODULE_PARM(do_sound, 1);
-+INT_MODULE_PARM(do_sound, 1); /* Enable the speaker? */
-+INT_MODULE_PARM(buggy_uart, 0); /* Skip strict UART tests? */
-
- #ifdef PCMCIA_DEBUG
- INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
- #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
- static char *version =
--"serial_cs.c 1.128 2001/10/18 12:18:35 (David Hinds)";
-+"serial_cs.c 1.138 2002/10/25 06:24:52 (David Hinds)";
- #else
- #define DEBUG(n, args...)
- #endif
-@@ -98,6 +98,7 @@
- { MANFID_OMEGA, PRODID_OMEGA_QSP_100, 4 },
- { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232, 2 },
- { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 },
-+ { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D2, 2 },
- { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS232, 4 },
- { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS422, 2 },
- { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS422, 4 },
-@@ -151,7 +152,7 @@
- client_reg_t client_reg;
- dev_link_t *link;
- int i, ret;
--
-+
- DEBUG(0, "serial_attach()\n");
-
- /* Create new serial device */
-@@ -163,7 +164,7 @@
- link->release.function = &serial_release;
- link->release.data = (u_long)link;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-- link->io.NumPorts1 = 8;
-+ link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
- link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
- if (irq_list[0] == -1)
-@@ -172,13 +173,12 @@
- for (i = 0; i < 4; i++)
- link->irq.IRQInfo2 |= 1 << irq_list[i];
- link->conf.Attributes = CONF_ENABLE_IRQ;
-- link->conf.Vcc = 50;
- if (do_sound) {
- link->conf.Attributes |= CONF_ENABLE_SPKR;
- link->conf.Status = CCSR_AUDIO_ENA;
- }
- link->conf.IntType = INT_MEMORY_AND_IO;
--
-+
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
-@@ -197,7 +197,7 @@
- serial_detach(link);
- return NULL;
- }
--
-+
- return link;
- } /* serial_attach */
-
-@@ -217,7 +217,7 @@
- int ret;
-
- DEBUG(0, "serial_detach(0x%p)\n", link);
--
-+
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
-@@ -227,17 +227,17 @@
- del_timer(&link->release);
- if (link->state & DEV_CONFIG)
- serial_release((u_long)link);
--
-+
- if (link->handle) {
- ret = CardServices(DeregisterClient, link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
- }
--
-+
- /* Unlink device structure, free bits */
- *linkp = link->next;
- kfree(info);
--
-+
- } /* serial_detach */
-
- /*====================================================================*/
-@@ -246,18 +246,20 @@
- {
- struct serial_struct serial;
- int line;
--
-+
- memset(&serial, 0, sizeof(serial));
- serial.port = port;
- serial.irq = irq;
- serial.flags = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ;
-+ if (buggy_uart)
-+ serial.flags |= ASYNC_BUGGY_UART;
- line = register_serial(&serial);
- if (line < 0) {
- printk(KERN_NOTICE "serial_cs: register_serial() at 0x%04lx,"
- " irq %d failed\n", (u_long)serial.port, serial.irq);
- return -1;
- }
--
-+
- info->line[info->ndev] = line;
- sprintf(info->node[info->ndev].dev_name, "ttyS%d", line);
- info->node[info->ndev].major = TTY_MAJOR;
-@@ -265,7 +267,7 @@
- if (info->ndev > 0)
- info->node[info->ndev-1].next = &info->node[info->ndev];
- info->ndev++;
--
-+
- return 0;
- }
-
-@@ -316,7 +318,10 @@
- return setup_serial(info, port, config.AssignedIRQ);
- }
- link->conf.Vcc = config.Vcc;
--
-+
-+ link->io.NumPorts1 = 8;
-+ link->io.NumPorts2 = 0;
-+
- /* First pass: look for a config entry that looks normal. */
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
-@@ -343,7 +348,7 @@
- i = next_tuple(handle, &tuple, &parse);
- }
- }
--
-+
- /* Second pass: try to find an entry that isn't picky about
- its base address, then try to grab any standard serial port
- address, and finally try to get any free port. */
-@@ -355,8 +360,7 @@
- for (j = 0; j < 5; j++) {
- link->io.BasePort1 = base[j];
- link->io.IOAddrLines = base[j] ? 16 : 3;
-- i = CardServices(RequestIO, link->handle,
-- &link->io);
-+ i = CardServices(RequestIO, link->handle, &link->io);
- if (i == CS_SUCCESS) goto found_port;
- }
- }
-@@ -368,7 +372,7 @@
- cs_error(link->handle, RequestIO, i);
- return -1;
- }
--
-+
- i = CardServices(RequestIRQ, link->handle, &link->irq);
- if (i != CS_SUCCESS) {
- cs_error(link->handle, RequestIRQ, i);
-@@ -393,8 +397,12 @@
- u_char buf[256];
- cisparse_t parse;
- cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
- int i, base2 = 0;
-
-+ CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
-@@ -436,12 +444,12 @@
- i = next_tuple(handle, &tuple, &parse);
- }
- }
--
-+
- if (i != CS_SUCCESS) {
-- cs_error(link->handle, RequestIO, i);
-- return -1;
-+ /* At worst, try to configure as a single port */
-+ return simple_config(link);
- }
--
-+
- i = CardServices(RequestIRQ, link->handle, &link->irq);
- if (i != CS_SUCCESS) {
- cs_error(link->handle, RequestIRQ, i);
-@@ -457,14 +465,27 @@
- cs_error(link->handle, RequestConfiguration, i);
- return -1;
- }
--
-+
-+ /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
-+ 8 registers are for the UART, the others are extra registers */
-+ if (info->manfid == MANFID_OXSEMI) {
-+ if (cf->index == 1 || cf->index == 3) {
-+ setup_serial(info, base2, link->irq.AssignedIRQ);
-+ outb(12,link->io.BasePort1+1);
-+ } else {
-+ setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
-+ outb(12,base2+1);
-+ }
-+ return 0;
-+ }
-+
- setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
- /* The Nokia cards are not really multiport cards */
- if (info->manfid == MANFID_NOKIA)
- return 0;
- for (i = 0; i < info->multi-1; i++)
- setup_serial(info, base2+(8*i), link->irq.AssignedIRQ);
--
-+
- return 0;
- }
-
-@@ -490,7 +511,7 @@
- int i, last_ret, last_fn;
-
- DEBUG(0, "serial_config(0x%p)\n", link);
--
-+
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
-@@ -525,7 +546,7 @@
- }
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
--
-+
- /* Configure card */
- link->state |= DEV_CONFIG;
-
-@@ -533,8 +554,8 @@
- tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
- tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
- info->multi = (first_tuple(handle, &tuple, &parse) == CS_SUCCESS);
--
-- /* Is this a multiport card? */
-+
-+ /* Scan list of known multiport card ID's */
- tuple.DesiredTuple = CISTPL_MANFID;
- if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
- info->manfid = le16_to_cpu(buf[0]);
-@@ -589,15 +610,15 @@
- }
- #endif
- }
--
-+
- if (info->multi > 1)
- multi_config(link);
- else
- simple_config(link);
--
-+
- if (info->ndev == 0)
- goto failed;
--
-+
- if (info->manfid == MANFID_IBM) {
- conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
- CS_CHECK(AccessConfigurationRegister, link->handle, &reg);
-@@ -614,6 +635,7 @@
- cs_error(link->handle, last_fn, last_ret);
- failed:
- serial_release((u_long)link);
-+ link->state &= ~DEV_CONFIG_PENDING;
-
- } /* serial_config */
-
-@@ -621,7 +643,7 @@
-
- After a card is removed, serial_release() will unregister the net
- device, and release the PCMCIA configuration.
--
-+
- ======================================================================*/
-
- void serial_release(u_long arg)
-@@ -629,7 +651,7 @@
- dev_link_t *link = (dev_link_t *)arg;
- serial_info_t *info = link->priv;
- int i;
--
-+
- DEBUG(0, "serial_release(0x%p)\n", link);
-
- for (i = 0; i < info->ndev; i++) {
-@@ -642,7 +664,7 @@
- CardServices(ReleaseIO, link->handle, &link->io);
- CardServices(ReleaseIRQ, link->handle, &link->irq);
- }
--
-+
- link->state &= ~DEV_CONFIG;
-
- } /* serial_release */
-@@ -653,7 +675,7 @@
- stuff to run after an event is received. A CARD_REMOVAL event
- also sets some flags to discourage the serial drivers from
- talking to the ports.
--
-+
- ======================================================================*/
-
- static int serial_event(event_t event, int priority,
-@@ -661,9 +683,9 @@
- {
- dev_link_t *link = args->client_data;
- serial_info_t *info = link->priv;
--
-+
- DEBUG(1, "serial_event(0x%06x)\n", event);
--
-+
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
-@@ -702,7 +724,7 @@
- if (serv.Revision != CS_RELEASE_CODE) {
- printk(KERN_NOTICE "serial_cs: Card Services release "
- "does not match!\n");
-- return -1;
-+ return -EINVAL;
- }
- register_pccard_driver(&dev_info, &serial_attach, &serial_detach);
- return 0;
---- linux/drivers/input/Config.in~bluetooth-2.4.18-mh11 2001-09-13 00:34:06.000000000 +0200
-+++ linux/drivers/input/Config.in 2004-01-25 23:37:39.000000000 +0100
-@@ -14,5 +14,6 @@
- fi
- dep_tristate ' Joystick support' CONFIG_INPUT_JOYDEV $CONFIG_INPUT
- dep_tristate ' Event interface support' CONFIG_INPUT_EVDEV $CONFIG_INPUT
-+dep_tristate ' User level driver support' CONFIG_INPUT_UINPUT $CONFIG_INPUT
-
- endmenu
---- linux/drivers/input/keybdev.c~bluetooth-2.4.18-mh11 2001-10-11 18:14:32.000000000 +0200
-+++ linux/drivers/input/keybdev.c 2004-01-25 23:37:39.000000000 +0100
-@@ -154,16 +154,18 @@
-
- static struct input_handler keybdev_handler;
-
-+static unsigned int ledstate = 0xff;
-+
- void keybdev_ledfunc(unsigned int led)
- {
- struct input_handle *handle;
-
-- for (handle = keybdev_handler.handle; handle; handle = handle->hnext) {
-+ ledstate = led;
-
-+ for (handle = keybdev_handler.handle; handle; handle = handle->hnext) {
- input_event(handle->dev, EV_LED, LED_SCROLLL, !!(led & 0x01));
- input_event(handle->dev, EV_LED, LED_NUML, !!(led & 0x02));
- input_event(handle->dev, EV_LED, LED_CAPSL, !!(led & 0x04));
--
- }
- }
-
-@@ -202,6 +204,12 @@
-
- // printk(KERN_INFO "keybdev.c: Adding keyboard: input%d\n", dev->number);
-
-+ if (ledstate != 0xff) {
-+ input_event(dev, EV_LED, LED_SCROLLL, !!(ledstate & 0x01));
-+ input_event(dev, EV_LED, LED_NUML, !!(ledstate & 0x02));
-+ input_event(dev, EV_LED, LED_CAPSL, !!(ledstate & 0x04));
-+ }
-+
- return handle;
- }
-
---- linux/drivers/input/Makefile~bluetooth-2.4.18-mh11 2000-12-29 23:07:22.000000000 +0100
-+++ linux/drivers/input/Makefile 2004-01-25 23:37:39.000000000 +0100
-@@ -24,6 +24,7 @@
- obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
- obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
- obj-$(CONFIG_INPUT_EVDEV) += evdev.o
-+obj-$(CONFIG_INPUT_UINPUT) += uinput.o
-
- # The global Rules.make.
-
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/drivers/input/uinput.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,428 @@
-+/*
-+ * User level driver support for input subsystem
-+ *
-+ * Heavily based on evdev.c by Vojtech Pavlik
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
-+ *
-+ * Changes/Revisions:
-+ * 0.1 20/06/2002
-+ * - first public version
-+ */
-+
-+#include <linux/poll.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/input.h>
-+#include <linux/smp_lock.h>
-+#include <linux/fs.h>
-+#include <linux/miscdevice.h>
-+#include <linux/uinput.h>
-+
-+static int uinput_dev_open(struct input_dev *dev)
-+{
-+ return 0;
-+}
-+
-+static void uinput_dev_close(struct input_dev *dev)
-+{
-+}
-+
-+static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
-+{
-+ struct uinput_device *udev;
-+
-+ udev = (struct uinput_device *)dev->private;
-+
-+ udev->buff[udev->head].type = type;
-+ udev->buff[udev->head].code = code;
-+ udev->buff[udev->head].value = value;
-+ do_gettimeofday(&udev->buff[udev->head].time);
-+ udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE;
-+
-+ wake_up_interruptible(&udev->waitq);
-+
-+ return 0;
-+}
-+
-+static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect)
-+{
-+ return 0;
-+}
-+
-+static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
-+{
-+ return 0;
-+}
-+
-+static int uinput_create_device(struct uinput_device *udev)
-+{
-+ if (!udev->dev->name) {
-+ printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME);
-+ return -EINVAL;
-+ }
-+
-+ udev->dev->open = uinput_dev_open;
-+ udev->dev->close = uinput_dev_close;
-+ udev->dev->event = uinput_dev_event;
-+ udev->dev->upload_effect = uinput_dev_upload_effect;
-+ udev->dev->erase_effect = uinput_dev_erase_effect;
-+ udev->dev->private = udev;
-+
-+ init_waitqueue_head(&(udev->waitq));
-+
-+ input_register_device(udev->dev);
-+
-+ set_bit(UIST_CREATED, &(udev->state));
-+
-+ return 0;
-+}
-+
-+static int uinput_destroy_device(struct uinput_device *udev)
-+{
-+ if (!test_bit(UIST_CREATED, &(udev->state))) {
-+ printk(KERN_WARNING "%s: create the device first\n", UINPUT_NAME);
-+ return -EINVAL;
-+ }
-+
-+ input_unregister_device(udev->dev);
-+
-+ clear_bit(UIST_CREATED, &(udev->state));
-+
-+ return 0;
-+}
-+
-+static int uinput_open(struct inode *inode, struct file *file)
-+{
-+ struct uinput_device *newdev;
-+ struct input_dev *newinput;
-+
-+ newdev = kmalloc(sizeof(struct uinput_device), GFP_KERNEL);
-+ if (!newdev)
-+ goto error;
-+ memset(newdev, 0, sizeof(struct uinput_device));
-+
-+ newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
-+ if (!newinput)
-+ goto cleanup;
-+ memset(newinput, 0, sizeof(struct input_dev));
-+
-+ newdev->dev = newinput;
-+
-+ file->private_data = newdev;
-+
-+ return 0;
-+cleanup:
-+ kfree(newdev);
-+error:
-+ return -ENOMEM;
-+}
-+
-+static int uinput_validate_absbits(struct input_dev *dev)
-+{
-+ unsigned int cnt;
-+ int retval = 0;
-+
-+ for (cnt = 0; cnt < ABS_MAX; cnt++) {
-+ if (!test_bit(cnt, dev->absbit))
-+ continue;
-+
-+ if (/*!dev->absmin[cnt] || !dev->absmax[cnt] || */
-+ (dev->absmax[cnt] <= dev->absmin[cnt])) {
-+ printk(KERN_DEBUG
-+ "%s: invalid abs[%02x] min:%d max:%d\n",
-+ UINPUT_NAME, cnt,
-+ dev->absmin[cnt], dev->absmax[cnt]);
-+ retval = -EINVAL;
-+ break;
-+ }
-+
-+ if ((dev->absflat[cnt] < dev->absmin[cnt]) ||
-+ (dev->absflat[cnt] > dev->absmax[cnt])) {
-+ printk(KERN_DEBUG
-+ "%s: absflat[%02x] out of range: %d "
-+ "(min:%d/max:%d)\n",
-+ UINPUT_NAME, cnt, dev->absflat[cnt],
-+ dev->absmin[cnt], dev->absmax[cnt]);
-+ retval = -EINVAL;
-+ break;
-+ }
-+ }
-+ return retval;
-+}
-+
-+static int uinput_alloc_device(struct file *file, const char *buffer, size_t count)
-+{
-+ struct uinput_user_dev *user_dev;
-+ struct input_dev *dev;
-+ struct uinput_device *udev;
-+ int size,
-+ retval;
-+
-+ retval = count;
-+
-+ udev = (struct uinput_device *)file->private_data;
-+ dev = udev->dev;
-+
-+ user_dev = kmalloc(sizeof(*user_dev), GFP_KERNEL);
-+ if (!user_dev) {
-+ retval = -ENOMEM;
-+ goto exit;
-+ }
-+
-+ if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) {
-+ retval = -EFAULT;
-+ goto exit;
-+ }
-+
-+ if (NULL != dev->name)
-+ kfree(dev->name);
-+
-+ size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
-+ dev->name = kmalloc(size, GFP_KERNEL);
-+ if (!dev->name) {
-+ retval = -ENOMEM;
-+ goto exit;
-+ }
-+
-+ strncpy(dev->name, user_dev->name, size);
-+ dev->idbus = user_dev->idbus;
-+ dev->idvendor = user_dev->idvendor;
-+ dev->idproduct = user_dev->idproduct;
-+ dev->idversion = user_dev->idversion;
-+ dev->ff_effects_max = user_dev->ff_effects_max;
-+
-+ size = sizeof(int) * (ABS_MAX + 1);
-+ memcpy(dev->absmax, user_dev->absmax, size);
-+ memcpy(dev->absmin, user_dev->absmin, size);
-+ memcpy(dev->absfuzz, user_dev->absfuzz, size);
-+ memcpy(dev->absflat, user_dev->absflat, size);
-+
-+ /* check if absmin/absmax/absfuzz/absflat are filled as
-+ * told in Documentation/input/input-programming.txt */
-+ if (test_bit(EV_ABS, dev->evbit)) {
-+ retval = uinput_validate_absbits(dev);
-+ if (retval < 0)
-+ kfree(dev->name);
-+ }
-+
-+exit:
-+ kfree(user_dev);
-+ return retval;
-+}
-+
-+static ssize_t uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
-+{
-+ struct uinput_device *udev = file->private_data;
-+
-+ if (test_bit(UIST_CREATED, &(udev->state))) {
-+ struct input_event ev;
-+
-+ if (copy_from_user(&ev, buffer, sizeof(struct input_event)))
-+ return -EFAULT;
-+ input_event(udev->dev, ev.type, ev.code, ev.value);
-+ }
-+ else
-+ count = uinput_alloc_device(file, buffer, count);
-+
-+ return count;
-+}
-+
-+static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
-+{
-+ struct uinput_device *udev = file->private_data;
-+ int retval = 0;
-+
-+ if (!test_bit(UIST_CREATED, &(udev->state)))
-+ return -ENODEV;
-+
-+ if ((udev->head == udev->tail) && (file->f_flags & O_NONBLOCK))
-+ return -EAGAIN;
-+
-+ retval = wait_event_interruptible(udev->waitq,
-+ (udev->head != udev->tail) ||
-+ !test_bit(UIST_CREATED, &(udev->state)));
-+
-+ if (retval)
-+ return retval;
-+
-+ if (!test_bit(UIST_CREATED, &(udev->state)))
-+ return -ENODEV;
-+
-+ while ((udev->head != udev->tail) &&
-+ (retval + sizeof(struct input_event) <= count)) {
-+ if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]),
-+ sizeof(struct input_event))) return -EFAULT;
-+ udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE;
-+ retval += sizeof(struct input_event);
-+ }
-+
-+ return retval;
-+}
-+
-+static unsigned int uinput_poll(struct file *file, poll_table *wait)
-+{
-+ struct uinput_device *udev = file->private_data;
-+
-+ poll_wait(file, &udev->waitq, wait);
-+
-+ if (udev->head != udev->tail)
-+ return POLLIN | POLLRDNORM;
-+
-+ return 0;
-+}
-+
-+static int uinput_burn_device(struct uinput_device *udev)
-+{
-+ if (test_bit(UIST_CREATED, &(udev->state)))
-+ uinput_destroy_device(udev);
-+
-+ kfree(udev->dev);
-+ kfree(udev);
-+
-+ return 0;
-+}
-+
-+static int uinput_close(struct inode *inode, struct file *file)
-+{
-+ return uinput_burn_device((struct uinput_device *)file->private_data);
-+}
-+
-+static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-+{
-+ int retval = 0;
-+ struct uinput_device *udev;
-+
-+ udev = (struct uinput_device *)file->private_data;
-+
-+ /* device attributes can not be changed after the device is created */
-+ if (cmd >= UI_SET_EVBIT && test_bit(UIST_CREATED, &(udev->state)))
-+ return -EINVAL;
-+
-+ switch (cmd) {
-+ case UI_DEV_CREATE:
-+ retval = uinput_create_device(udev);
-+ break;
-+
-+ case UI_DEV_DESTROY:
-+ retval = uinput_destroy_device(udev);
-+ break;
-+
-+ case UI_SET_EVBIT:
-+ if (arg > EV_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->evbit);
-+ break;
-+
-+ case UI_SET_KEYBIT:
-+ if (arg > KEY_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->keybit);
-+ break;
-+
-+ case UI_SET_RELBIT:
-+ if (arg > REL_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->relbit);
-+ break;
-+
-+ case UI_SET_ABSBIT:
-+ if (arg > ABS_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->absbit);
-+ break;
-+
-+ case UI_SET_MSCBIT:
-+ if (arg > MSC_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->mscbit);
-+ break;
-+
-+ case UI_SET_LEDBIT:
-+ if (arg > LED_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->ledbit);
-+ break;
-+
-+ case UI_SET_SNDBIT:
-+ if (arg > SND_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->sndbit);
-+ break;
-+
-+ case UI_SET_FFBIT:
-+ if (arg > FF_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->ffbit);
-+ break;
-+
-+ default:
-+ retval = -EFAULT;
-+ }
-+ return retval;
-+}
-+
-+struct file_operations uinput_fops = {
-+ owner: THIS_MODULE,
-+ open: uinput_open,
-+ release: uinput_close,
-+ read: uinput_read,
-+ write: uinput_write,
-+ poll: uinput_poll,
-+ ioctl: uinput_ioctl,
-+};
-+
-+static struct miscdevice uinput_misc = {
-+ fops: &uinput_fops,
-+ minor: UINPUT_MINOR,
-+ name: UINPUT_NAME,
-+};
-+
-+static int __init uinput_init(void)
-+{
-+ return misc_register(&uinput_misc);
-+}
-+
-+static void __exit uinput_exit(void)
-+{
-+ misc_deregister(&uinput_misc);
-+}
-+
-+MODULE_AUTHOR("Aristeu Sergio Rozanski Filho");
-+MODULE_DESCRIPTION("User level driver support for input subsystem");
-+MODULE_LICENSE("GPL");
-+
-+module_init(uinput_init);
-+module_exit(uinput_exit);
-+
---- linux/drivers/isdn/avmb1/capidrv.c~bluetooth-2.4.18-mh11 2001-12-21 18:41:54.000000000 +0100
-+++ linux/drivers/isdn/avmb1/capidrv.c 2004-01-25 23:37:39.000000000 +0100
-@@ -514,13 +514,25 @@
-
- static void send_message(capidrv_contr * card, _cmsg * cmsg)
- {
-- struct sk_buff *skb;
-- size_t len;
-+ struct sk_buff *skb;
-+ size_t len;
-+ u16 err;
-+
- capi_cmsg2message(cmsg, cmsg->buf);
- len = CAPIMSG_LEN(cmsg->buf);
- skb = alloc_skb(len, GFP_ATOMIC);
-+ if(!skb) {
-+ printk(KERN_ERR "no skb len(%d) memory\n", len);
-+ return;
-+ }
- memcpy(skb_put(skb, len), cmsg->buf, len);
-- (*capifuncs->capi_put_message) (global.appid, skb);
-+ err = (*capifuncs->capi_put_message) (global.appid, skb);
-+ if (err) {
-+ printk(KERN_WARNING "%s: capi_put_message error: %04x\n",
-+ __FUNCTION__, err);
-+ kfree_skb(skb);
-+ return;
-+ }
- global.nsentctlpkt++;
- }
-
-@@ -2179,10 +2191,10 @@
- free_ncci(card, card->bchans[card->nbchan-1].nccip);
- if (card->bchans[card->nbchan-1].plcip)
- free_plci(card, card->bchans[card->nbchan-1].plcip);
-- if (card->plci_list)
-- printk(KERN_ERR "capidrv: bug in free_plci()\n");
- card->nbchan--;
- }
-+ if (card->plci_list)
-+ printk(KERN_ERR "capidrv: bug in free_plci()\n");
- kfree(card->bchans);
- card->bchans = 0;
-
---- linux/drivers/isdn/avmb1/kcapi.c~bluetooth-2.4.18-mh11 2001-12-21 18:41:54.000000000 +0100
-+++ linux/drivers/isdn/avmb1/kcapi.c 2004-01-25 23:37:39.000000000 +0100
-@@ -545,7 +545,13 @@
- static void notify_up(__u32 contr)
- {
- struct capi_interface_user *p;
-+ __u16 appl;
-
-+ for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
-+ if (!VALID_APPLID(appl)) continue;
-+ if (APPL(appl)->releasing) continue;
-+ CARD(contr)->driver->register_appl(CARD(contr), appl, &APPL(appl)->rparam);
-+ }
- printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr);
- spin_lock(&capi_users_lock);
- for (p = capi_users; p; p = p->next) {
-@@ -705,12 +711,16 @@
- nextpp = &(*pp)->next;
- }
- }
-- APPL(appl)->releasing--;
-- if (APPL(appl)->releasing <= 0) {
-- APPL(appl)->signal = 0;
-- APPL_MARK_FREE(appl);
-- printk(KERN_INFO "kcapi: appl %d down\n", appl);
-- }
-+ if (APPL(appl)->releasing) { /* only release if the application was marked for release */
-+ printk(KERN_DEBUG "kcapi: appl %d releasing(%d)\n", appl, APPL(appl)->releasing);
-+ APPL(appl)->releasing--;
-+ if (APPL(appl)->releasing <= 0) {
-+ APPL(appl)->signal = 0;
-+ APPL_MARK_FREE(appl);
-+ printk(KERN_INFO "kcapi: appl %d down\n", appl);
-+ }
-+ } else
-+ printk(KERN_WARNING "kcapi: appl %d card%d released without request\n", appl, card->cnr);
- }
- /*
- * ncci management
-@@ -863,16 +873,7 @@
-
- static void controllercb_ready(struct capi_ctr * card)
- {
-- __u16 appl;
--
- card->cardstate = CARD_RUNNING;
--
-- for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
-- if (!VALID_APPLID(appl)) continue;
-- if (APPL(appl)->releasing) continue;
-- card->driver->register_appl(card, appl, &APPL(appl)->rparam);
-- }
--
- printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n",
- CARDNR(card), card->name);
-
---- linux/drivers/usb/Config.in~bluetooth-2.4.18-mh11 2004-01-25 23:28:22.000000000 +0100
-+++ linux/drivers/usb/Config.in 2004-01-25 23:37:39.000000000 +0100
-@@ -39,7 +39,13 @@
-
- comment 'USB Device Class drivers'
- dep_tristate ' USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND
--dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB $CONFIG_EXPERIMENTAL
-+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-+ if [ "$CONFIG_BLUEZ" = "n" ]; then
-+ dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB
-+ else
-+ comment ' USB Bluetooth can only be used with disabled Bluetooth subsystem'
-+ fi
-+fi
- if [ "$CONFIG_SCSI" = "n" ]; then
- comment ' SCSI support is needed for USB Storage'
- fi
---- linux/drivers/usb/hid-core.c~bluetooth-2.4.18-mh11 2001-12-21 18:41:55.000000000 +0100
-+++ linux/drivers/usb/hid-core.c 2004-01-25 23:37:39.000000000 +0100
-@@ -217,6 +217,8 @@
-
- offset = report->size;
- report->size += parser->global.report_size * parser->global.report_count;
-+ if (usages < parser->global.report_count)
-+ usages = parser->global.report_count;
-
- if (usages == 0)
- return 0; /* ignore padding fields */
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/include/linux/firmware.h 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,20 @@
-+#ifndef _LINUX_FIRMWARE_H
-+#define _LINUX_FIRMWARE_H
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#define FIRMWARE_NAME_MAX 30
-+struct firmware {
-+ size_t size;
-+ u8 *data;
-+};
-+int request_firmware (const struct firmware **fw, const char *name,
-+ const char *device);
-+int request_firmware_nowait (
-+ struct module *module,
-+ const char *name, const char *device, void *context,
-+ void (*cont)(const struct firmware *fw, void *context));
-+/* On 2.5 'device' is 'struct device *' */
-+
-+void release_firmware (const struct firmware *fw);
-+void register_firmware (const char *name, const u8 *data, size_t size);
-+#endif
---- linux/include/linux/input.h~bluetooth-2.4.18-mh11 2001-09-13 00:34:06.000000000 +0200
-+++ linux/include/linux/input.h 2004-01-25 23:37:39.000000000 +0100
-@@ -468,6 +468,8 @@
- #define BUS_PCI 0x01
- #define BUS_ISAPNP 0x02
- #define BUS_USB 0x03
-+#define BUS_HIL 0x04
-+#define BUS_BLUETOOTH 0x05
-
- #define BUS_ISA 0x10
- #define BUS_I8042 0x11
---- linux/include/linux/kernel.h~bluetooth-2.4.18-mh11 2002-02-25 20:38:13.000000000 +0100
-+++ linux/include/linux/kernel.h 2004-01-25 23:37:39.000000000 +0100
-@@ -11,6 +11,7 @@
- #include <linux/linkage.h>
- #include <linux/stddef.h>
- #include <linux/types.h>
-+#include <linux/compiler.h>
-
- /* Optimization barrier */
- /* The "volatile" is due to gcc bugs */
-@@ -181,4 +182,6 @@
- char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
- };
-
--#endif
-+#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
-+
-+#endif /* _LINUX_KERNEL_H */
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/include/linux/uinput.h 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,79 @@
-+/*
-+ * User level driver support for input subsystem
-+ *
-+ * Heavily based on evdev.c by Vojtech Pavlik
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
-+ *
-+ * Changes/Revisions:
-+ * 0.1 20/06/2002
-+ * - first public version
-+ */
-+
-+#ifndef __UINPUT_H_
-+#define __UINPUT_H_
-+
-+#ifdef __KERNEL__
-+#define UINPUT_MINOR 223
-+#define UINPUT_NAME "uinput"
-+#define UINPUT_BUFFER_SIZE 16
-+
-+/* state flags => bit index for {set|clear|test}_bit ops */
-+#define UIST_CREATED 0
-+
-+struct uinput_device {
-+ struct input_dev *dev;
-+ unsigned long state;
-+ wait_queue_head_t waitq;
-+ unsigned char ready,
-+ head,
-+ tail;
-+ struct input_event buff[UINPUT_BUFFER_SIZE];
-+};
-+#endif /* __KERNEL__ */
-+
-+/* ioctl */
-+#define UINPUT_IOCTL_BASE 'U'
-+#define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1)
-+#define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2)
-+#define UI_SET_EVBIT _IOW(UINPUT_IOCTL_BASE, 100, int)
-+#define UI_SET_KEYBIT _IOW(UINPUT_IOCTL_BASE, 101, int)
-+#define UI_SET_RELBIT _IOW(UINPUT_IOCTL_BASE, 102, int)
-+#define UI_SET_ABSBIT _IOW(UINPUT_IOCTL_BASE, 103, int)
-+#define UI_SET_MSCBIT _IOW(UINPUT_IOCTL_BASE, 104, int)
-+#define UI_SET_LEDBIT _IOW(UINPUT_IOCTL_BASE, 105, int)
-+#define UI_SET_SNDBIT _IOW(UINPUT_IOCTL_BASE, 106, int)
-+#define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int)
-+
-+#ifndef NBITS
-+#define NBITS(x) ((((x)-1)/(sizeof(long)*8))+1)
-+#endif /* NBITS */
-+
-+#define UINPUT_MAX_NAME_SIZE 80
-+struct uinput_user_dev {
-+ char name[UINPUT_MAX_NAME_SIZE];
-+ unsigned short idbus;
-+ unsigned short idvendor;
-+ unsigned short idproduct;
-+ unsigned short idversion;
-+ int ff_effects_max;
-+ int absmax[ABS_MAX + 1];
-+ int absmin[ABS_MAX + 1];
-+ int absfuzz[ABS_MAX + 1];
-+ int absflat[ABS_MAX + 1];
-+};
-+#endif /* __UINPUT_H_ */
---- linux/include/net/bluetooth/bluetooth.h~bluetooth-2.4.18-mh11 2001-09-07 18:28:38.000000000 +0200
-+++ linux/include/net/bluetooth/bluetooth.h 2004-01-25 23:37:39.000000000 +0100
-@@ -23,7 +23,7 @@
- */
-
- /*
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __BLUETOOTH_H
-@@ -31,17 +31,63 @@
-
- #include <asm/types.h>
- #include <asm/byteorder.h>
-+#include <linux/poll.h>
-+#include <net/sock.h>
-
- #ifndef AF_BLUETOOTH
- #define AF_BLUETOOTH 31
- #define PF_BLUETOOTH AF_BLUETOOTH
- #endif
-
-+/* Reserv for core and drivers use */
-+#define BLUEZ_SKB_RESERVE 8
-+
-+#ifndef MIN
-+#define MIN(a,b) ((a) < (b) ? (a) : (b))
-+#endif
-+
- #define BTPROTO_L2CAP 0
- #define BTPROTO_HCI 1
-+#define BTPROTO_SCO 2
-+#define BTPROTO_RFCOMM 3
-+#define BTPROTO_BNEP 4
-+#define BTPROTO_CMTP 5
-
- #define SOL_HCI 0
- #define SOL_L2CAP 6
-+#define SOL_SCO 17
-+#define SOL_RFCOMM 18
-+
-+/* Debugging */
-+#ifdef CONFIG_BLUEZ_DEBUG
-+
-+#define HCI_CORE_DEBUG 1
-+#define HCI_SOCK_DEBUG 1
-+#define HCI_UART_DEBUG 1
-+#define HCI_USB_DEBUG 1
-+//#define HCI_DATA_DUMP 1
-+
-+#define L2CAP_DEBUG 1
-+#define SCO_DEBUG 1
-+#define AF_BLUETOOTH_DEBUG 1
-+
-+#endif /* CONFIG_BLUEZ_DEBUG */
-+
-+extern void bluez_dump(char *pref, __u8 *buf, int count);
-+
-+#if __GNUC__ <= 2 && __GNUC_MINOR__ < 95
-+#define __func__ __FUNCTION__
-+#endif
-+
-+#define BT_INFO(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
-+#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __func__ , ## arg)
-+#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
-+
-+#ifdef HCI_DATA_DUMP
-+#define BT_DMP(buf, len) bluez_dump(__func__, buf, len)
-+#else
-+#define BT_DMP(D...)
-+#endif
-
- /* Connection and socket states */
- enum {
-@@ -50,6 +96,7 @@
- BT_BOUND,
- BT_LISTEN,
- BT_CONNECT,
-+ BT_CONNECT2,
- BT_CONFIG,
- BT_DISCONN,
- BT_CLOSED
-@@ -66,7 +113,8 @@
- __u8 b[6];
- } __attribute__((packed)) bdaddr_t;
-
--#define BDADDR_ANY ((bdaddr_t *)"\000\000\000\000\000")
-+#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
-+#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
-
- /* Copy, swap, convert BD Address */
- static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2)
-@@ -82,6 +130,91 @@
- char *batostr(bdaddr_t *ba);
- bdaddr_t *strtoba(char *str);
-
-+/* Common socket structures and functions */
-+
-+#define bluez_pi(sk) ((struct bluez_pinfo *) &sk->protinfo)
-+#define bluez_sk(pi) ((struct sock *) \
-+ ((void *)pi - (unsigned long)(&((struct sock *)0)->protinfo)))
-+
-+struct bluez_pinfo {
-+ bdaddr_t src;
-+ bdaddr_t dst;
-+
-+ struct list_head accept_q;
-+ struct sock *parent;
-+};
-+
-+struct bluez_sock_list {
-+ struct sock *head;
-+ rwlock_t lock;
-+};
-+
-+int bluez_sock_register(int proto, struct net_proto_family *ops);
-+int bluez_sock_unregister(int proto);
-+void bluez_sock_init(struct socket *sock, struct sock *sk);
-+void bluez_sock_link(struct bluez_sock_list *l, struct sock *s);
-+void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *s);
-+int bluez_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm);
-+uint bluez_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
-+int bluez_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
-+
-+void bluez_accept_enqueue(struct sock *parent, struct sock *sk);
-+struct sock * bluez_accept_dequeue(struct sock *parent, struct socket *newsock);
-+
-+/* Skb helpers */
-+struct bluez_skb_cb {
-+ int incomming;
-+};
-+#define bluez_cb(skb) ((struct bluez_skb_cb *)(skb->cb))
-+
-+static inline struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
-+{
-+ struct sk_buff *skb;
-+
-+ if ((skb = alloc_skb(len + BLUEZ_SKB_RESERVE, how))) {
-+ skb_reserve(skb, BLUEZ_SKB_RESERVE);
-+ bluez_cb(skb)->incomming = 0;
-+ }
-+ return skb;
-+}
-+
-+static inline struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len,
-+ int nb, int *err)
-+{
-+ struct sk_buff *skb;
-+
-+ if ((skb = sock_alloc_send_skb(sk, len + BLUEZ_SKB_RESERVE, nb, err))) {
-+ skb_reserve(skb, BLUEZ_SKB_RESERVE);
-+ bluez_cb(skb)->incomming = 0;
-+ }
-+
-+ return skb;
-+}
-+
-+static inline int skb_frags_no(struct sk_buff *skb)
-+{
-+ register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
-+ register int n = 1;
-+
-+ for (; frag; frag=frag->next, n++);
-+ return n;
-+}
-+
-+int hci_core_init(void);
-+int hci_core_cleanup(void);
-+int hci_sock_init(void);
-+int hci_sock_cleanup(void);
-+
- int bterr(__u16 code);
-
-+#ifndef MODULE_LICENSE
-+#define MODULE_LICENSE(x)
-+#endif
-+
-+#ifndef list_for_each_safe
-+#define list_for_each_safe(pos, n, head) \
-+ for (pos = (head)->next, n = pos->next; pos != (head); \
-+ pos = n, n = pos->next)
-+#endif
-+
- #endif /* __BLUETOOTH_H */
---- linux/include/net/bluetooth/bluez.h~bluetooth-2.4.18-mh11
-+++ linux/include/net/bluetooth/bluez.h
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifndef __IF_BLUEZ_H
--#define __IF_BLUEZ_H
--
--#include <net/sock.h>
--
--#define BLUEZ_MAX_PROTO 2
--
--/* Reserv for core and drivers use */
--#define BLUEZ_SKB_RESERVE 8
--
--#ifndef MIN
--#define MIN(a,b) ((a) < (b) ? (a) : (b))
--#endif
--
--/* Debugging */
--#ifdef BLUEZ_DEBUG
--
--#define HCI_CORE_DEBUG 1
--#define HCI_SOCK_DEBUG 1
--#define HCI_UART_DEBUG 1
--#define HCI_USB_DEBUG 1
--//#define HCI_DATA_DUMP 1
--
--#define L2CAP_DEBUG 1
--
--#endif /* BLUEZ_DEBUG */
--
--extern void bluez_dump(char *pref, __u8 *buf, int count);
--
--#define INF(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
--#define DBG(fmt, arg...) printk(KERN_INFO __FUNCTION__ ": " fmt "\n" , ## arg)
--#define ERR(fmt, arg...) printk(KERN_ERR __FUNCTION__ ": " fmt "\n" , ## arg)
--
--#ifdef HCI_DATA_DUMP
--#define DMP(buf, len) bluez_dump(__FUNCTION__, buf, len)
--#else
--#define DMP(D...)
--#endif
--
--/* ----- Sockets ------ */
--struct bluez_sock_list {
-- struct sock *head;
-- rwlock_t lock;
--};
--
--extern int bluez_sock_register(int proto, struct net_proto_family *ops);
--extern int bluez_sock_unregister(int proto);
--
--extern void bluez_sock_link(struct bluez_sock_list *l, struct sock *s);
--extern void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *s);
--
--/* ----- SKB helpers ----- */
--struct bluez_skb_cb {
-- int incomming;
--};
--#define bluez_cb(skb) ((struct bluez_skb_cb *)(skb->cb))
--
--static inline struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
--{
-- struct sk_buff *skb;
--
-- if ((skb = alloc_skb(len + BLUEZ_SKB_RESERVE, how))) {
-- skb_reserve(skb, BLUEZ_SKB_RESERVE);
-- bluez_cb(skb)->incomming = 0;
-- }
-- return skb;
--}
--
--static inline struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len,
-- int nb, int *err)
--{
-- struct sk_buff *skb;
--
-- if ((skb = sock_alloc_send_skb(sk, len + BLUEZ_SKB_RESERVE, nb, err))) {
-- skb_reserve(skb, BLUEZ_SKB_RESERVE);
-- bluez_cb(skb)->incomming = 0;
-- }
--
-- return skb;
--}
--
--static inline int skb_frags_no(struct sk_buff *skb)
--{
-- register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
-- register int n = 1;
--
-- for (; frag; frag=frag->next, n++);
-- return n;
--}
--
--extern int hci_core_init(void);
--extern int hci_core_cleanup(void);
--extern int hci_sock_init(void);
--extern int hci_sock_cleanup(void);
--
--#endif /* __IF_BLUEZ_H */
---- linux/include/net/bluetooth/hci_core.h~bluetooth-2.4.18-mh11 2001-09-07 18:28:38.000000000 +0200
-+++ linux/include/net/bluetooth/hci_core.h 2004-01-25 23:37:39.000000000 +0100
-@@ -23,7 +23,7 @@
- */
-
- /*
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __HCI_CORE_H
-@@ -32,14 +32,12 @@
- #include <net/bluetooth/hci.h>
-
- /* HCI upper protocols */
--#define HCI_MAX_PROTO 1
- #define HCI_PROTO_L2CAP 0
-+#define HCI_PROTO_SCO 1
-
- #define HCI_INIT_TIMEOUT (HZ * 10)
-
--/* ----- Inquiry cache ----- */
--#define INQUIRY_CACHE_AGE_MAX (HZ*5) // 5 seconds
--#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds
-+/* HCI Core structures */
-
- struct inquiry_entry {
- struct inquiry_entry *next;
-@@ -53,111 +51,186 @@
- struct inquiry_entry *list;
- };
-
--static inline void inquiry_cache_init(struct inquiry_cache *cache)
--{
-- spin_lock_init(&cache->lock);
-- cache->list = NULL;
--}
-+struct conn_hash {
-+ struct list_head list;
-+ spinlock_t lock;
-+ unsigned int num;
-+};
-
--static inline void inquiry_cache_lock(struct inquiry_cache *cache)
--{
-- spin_lock(&cache->lock);
--}
-+struct hci_dev {
-+ struct list_head list;
-+ spinlock_t lock;
-+ atomic_t refcnt;
-
--static inline void inquiry_cache_unlock(struct inquiry_cache *cache)
--{
-- spin_unlock(&cache->lock);
--}
-+ char name[8];
-+ unsigned long flags;
-+ __u16 id;
-+ __u8 type;
-+ bdaddr_t bdaddr;
-+ __u8 features[8];
-
--static inline void inquiry_cache_lock_bh(struct inquiry_cache *cache)
--{
-- spin_lock_bh(&cache->lock);
--}
-+ __u16 pkt_type;
-+ __u16 link_policy;
-+ __u16 link_mode;
-+
-+ atomic_t cmd_cnt;
-+ unsigned int acl_cnt;
-+ unsigned int sco_cnt;
-
--static inline void inquiry_cache_unlock_bh(struct inquiry_cache *cache)
--{
-- spin_unlock_bh(&cache->lock);
--}
-+ unsigned int acl_mtu;
-+ unsigned int sco_mtu;
-+ unsigned int acl_pkts;
-+ unsigned int sco_pkts;
-
--static inline long inquiry_cache_age(struct inquiry_cache *cache)
--{
-- return jiffies - cache->timestamp;
--}
-+ unsigned long cmd_last_tx;
-+ unsigned long acl_last_tx;
-+ unsigned long sco_last_tx;
-+
-+ struct tasklet_struct cmd_task;
-+ struct tasklet_struct rx_task;
-+ struct tasklet_struct tx_task;
-
--static inline long inquiry_entry_age(struct inquiry_entry *e)
--{
-- return jiffies - e->timestamp;
--}
--extern void inquiry_cache_flush(struct inquiry_cache *cache);
-+ struct sk_buff_head rx_q;
-+ struct sk_buff_head raw_q;
-+ struct sk_buff_head cmd_q;
-
--struct hci_dev;
-+ struct sk_buff *sent_cmd;
-+
-+ struct semaphore req_lock;
-+ wait_queue_head_t req_wait_q;
-+ __u32 req_status;
-+ __u32 req_result;
-+
-+ struct inquiry_cache inq_cache;
-+ struct conn_hash conn_hash;
-+
-+ struct hci_dev_stats stat;
-+
-+ void *driver_data;
-+ void *core_data;
-+
-+ atomic_t promisc;
-+
-+ int (*open)(struct hci_dev *hdev);
-+ int (*close)(struct hci_dev *hdev);
-+ int (*flush)(struct hci_dev *hdev);
-+ int (*send)(struct sk_buff *skb);
-+ void (*destruct)(struct hci_dev *hdev);
-+ int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
-+};
-
--/* ----- HCI Connections ----- */
- struct hci_conn {
- struct list_head list;
-+
-+ atomic_t refcnt;
-+ spinlock_t lock;
-+
- bdaddr_t dst;
- __u16 handle;
-+ __u16 state;
- __u8 type;
-- unsigned int sent;
-+ __u8 out;
-+ __u32 link_mode;
-+ unsigned long pend;
-+
-+ unsigned int sent;
-+
-+ struct sk_buff_head data_q;
-
-+ struct timer_list timer;
-+
- struct hci_dev *hdev;
- void *l2cap_data;
-+ void *sco_data;
- void *priv;
-
-- struct sk_buff_head data_q;
-+ struct hci_conn *link;
- };
-
--struct conn_hash {
-- struct list_head list;
-- spinlock_t lock;
-- unsigned int num;
--};
-+extern struct hci_proto *hci_proto[];
-+extern struct list_head hdev_list;
-+extern rwlock_t hdev_list_lock;
-
--static inline void conn_hash_init(struct conn_hash *h)
-+/* ----- Inquiry cache ----- */
-+#define INQUIRY_CACHE_AGE_MAX (HZ*30) // 30 seconds
-+#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds
-+
-+#define inquiry_cache_lock(c) spin_lock(&c->lock)
-+#define inquiry_cache_unlock(c) spin_unlock(&c->lock)
-+#define inquiry_cache_lock_bh(c) spin_lock_bh(&c->lock)
-+#define inquiry_cache_unlock_bh(c) spin_unlock_bh(&c->lock)
-+
-+static inline void inquiry_cache_init(struct hci_dev *hdev)
- {
-- INIT_LIST_HEAD(&h->list);
-- spin_lock_init(&h->lock);
-- h->num = 0;
-+ struct inquiry_cache *c = &hdev->inq_cache;
-+ spin_lock_init(&c->lock);
-+ c->list = NULL;
- }
-
--static inline void conn_hash_lock(struct conn_hash *h)
-+static inline int inquiry_cache_empty(struct hci_dev *hdev)
- {
-- spin_lock(&h->lock);
-+ struct inquiry_cache *c = &hdev->inq_cache;
-+ return (c->list == NULL);
- }
-
--static inline void conn_hash_unlock(struct conn_hash *h)
-+static inline long inquiry_cache_age(struct hci_dev *hdev)
- {
-- spin_unlock(&h->lock);
-+ struct inquiry_cache *c = &hdev->inq_cache;
-+ return jiffies - c->timestamp;
- }
-
--static inline void __conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
-+static inline long inquiry_entry_age(struct inquiry_entry *e)
- {
-- list_add(&c->list, &h->list);
-- h->num++;
-+ return jiffies - e->timestamp;
- }
-
--static inline void conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
-+struct inquiry_entry *inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
-+void inquiry_cache_update(struct hci_dev *hdev, inquiry_info *info);
-+void inquiry_cache_flush(struct hci_dev *hdev);
-+int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf);
-+
-+/* ----- HCI Connections ----- */
-+enum {
-+ HCI_CONN_AUTH_PEND,
-+ HCI_CONN_ENCRYPT_PEND
-+};
-+
-+#define hci_conn_lock(c) spin_lock(&c->lock)
-+#define hci_conn_unlock(c) spin_unlock(&c->lock)
-+#define hci_conn_lock_bh(c) spin_lock_bh(&c->lock)
-+#define hci_conn_unlock_bh(c) spin_unlock_bh(&c->lock)
-+
-+#define conn_hash_lock(d) spin_lock(&d->conn_hash->lock)
-+#define conn_hash_unlock(d) spin_unlock(&d->conn_hash->lock)
-+#define conn_hash_lock_bh(d) spin_lock_bh(&d->conn_hash->lock)
-+#define conn_hash_unlock_bh(d) spin_unlock_bh(&d->conn_hash->lock)
-+
-+static inline void conn_hash_init(struct hci_dev *hdev)
- {
-- conn_hash_lock(h);
-- __conn_hash_add(h, handle, c);
-- conn_hash_unlock(h);
-+ struct conn_hash *h = &hdev->conn_hash;
-+ INIT_LIST_HEAD(&h->list);
-+ spin_lock_init(&h->lock);
-+ h->num = 0;
- }
-
--static inline void __conn_hash_del(struct conn_hash *h, struct hci_conn *c)
-+static inline void conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
- {
-- list_del(&c->list);
-- h->num--;
-+ struct conn_hash *h = &hdev->conn_hash;
-+ list_add(&c->list, &h->list);
-+ h->num++;
- }
-
--static inline void conn_hash_del(struct conn_hash *h, struct hci_conn *c)
-+static inline void conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
- {
-- conn_hash_lock(h);
-- __conn_hash_del(h, c);
-- conn_hash_unlock(h);
-+ struct conn_hash *h = &hdev->conn_hash;
-+ list_del(&c->list);
-+ h->num--;
- }
-
--static inline struct hci_conn *__conn_hash_lookup(struct conn_hash *h, __u16 handle)
-+static inline struct hci_conn *conn_hash_lookup_handle(struct hci_dev *hdev,
-+ __u16 handle)
- {
-+ register struct conn_hash *h = &hdev->conn_hash;
- register struct list_head *p;
- register struct hci_conn *c;
-
-@@ -169,101 +242,97 @@
- return NULL;
- }
-
--static inline struct hci_conn *conn_hash_lookup(struct conn_hash *h, __u16 handle)
-+static inline struct hci_conn *conn_hash_lookup_ba(struct hci_dev *hdev,
-+ __u8 type, bdaddr_t *ba)
- {
-- struct hci_conn *conn;
-+ register struct conn_hash *h = &hdev->conn_hash;
-+ register struct list_head *p;
-+ register struct hci_conn *c;
-
-- conn_hash_lock(h);
-- conn = __conn_hash_lookup(h, handle);
-- conn_hash_unlock(h);
-- return conn;
-+ list_for_each(p, &h->list) {
-+ c = list_entry(p, struct hci_conn, list);
-+ if (c->type == type && !bacmp(&c->dst, ba))
-+ return c;
-+ }
-+ return NULL;
- }
-
--/* ----- HCI Devices ----- */
--struct hci_dev {
-- atomic_t refcnt;
--
-- char name[8];
-- __u32 flags;
-- __u16 id;
-- __u8 type;
-- bdaddr_t bdaddr;
-- __u8 features[8];
--
-- __u16 pkt_type;
--
-- atomic_t cmd_cnt;
-- unsigned int acl_cnt;
-- unsigned int sco_cnt;
--
-- unsigned int acl_mtu;
-- unsigned int sco_mtu;
-- unsigned int acl_max;
-- unsigned int sco_max;
--
-- void *driver_data;
-- void *l2cap_data;
-- void *priv;
--
-- struct tasklet_struct cmd_task;
-- struct tasklet_struct rx_task;
-- struct tasklet_struct tx_task;
--
-- struct sk_buff_head rx_q;
-- struct sk_buff_head raw_q;
-- struct sk_buff_head cmd_q;
--
-- struct sk_buff *sent_cmd;
--
-- struct semaphore req_lock;
-- wait_queue_head_t req_wait_q;
-- __u32 req_status;
-- __u32 req_result;
-+void hci_acl_connect(struct hci_conn *conn);
-+void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
-+void hci_add_sco(struct hci_conn *conn, __u16 handle);
-
-- struct inquiry_cache inq_cache;
-+struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
-+int hci_conn_del(struct hci_conn *conn);
-+void hci_conn_hash_flush(struct hci_dev *hdev);
-
-- struct conn_hash conn_hash;
-+struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src);
-+int hci_conn_auth(struct hci_conn *conn);
-+int hci_conn_encrypt(struct hci_conn *conn);
-
-- struct hci_dev_stats stat;
-+static inline void hci_conn_set_timer(struct hci_conn *conn, long timeout)
-+{
-+ mod_timer(&conn->timer, jiffies + timeout);
-+}
-
-- int (*open)(struct hci_dev *hdev);
-- int (*close)(struct hci_dev *hdev);
-- int (*flush)(struct hci_dev *hdev);
-- int (*send)(struct sk_buff *skb);
--};
-+static inline void hci_conn_del_timer(struct hci_conn *conn)
-+{
-+ del_timer(&conn->timer);
-+}
-
--static inline void hci_dev_hold(struct hci_dev *hdev)
-+static inline void hci_conn_hold(struct hci_conn *conn)
- {
-- atomic_inc(&hdev->refcnt);
-+ atomic_inc(&conn->refcnt);
-+ hci_conn_del_timer(conn);
- }
-
--static inline void hci_dev_put(struct hci_dev *hdev)
-+static inline void hci_conn_put(struct hci_conn *conn)
- {
-- atomic_dec(&hdev->refcnt);
-+ if (atomic_dec_and_test(&conn->refcnt)) {
-+ if (conn->type == ACL_LINK) {
-+ unsigned long timeo = (conn->out) ?
-+ HCI_DISCONN_TIMEOUT : HCI_DISCONN_TIMEOUT * 2;
-+ hci_conn_set_timer(conn, timeo);
-+ } else
-+ hci_conn_set_timer(conn, HZ / 100);
-+ }
- }
-
--extern struct hci_dev *hci_dev_get(int index);
--extern int hci_register_dev(struct hci_dev *hdev);
--extern int hci_unregister_dev(struct hci_dev *hdev);
--extern int hci_dev_open(__u16 dev);
--extern int hci_dev_close(__u16 dev);
--extern int hci_dev_reset(__u16 dev);
--extern int hci_dev_reset_stat(__u16 dev);
--extern int hci_dev_info(unsigned long arg);
--extern int hci_dev_list(unsigned long arg);
--extern int hci_dev_setscan(unsigned long arg);
--extern int hci_dev_setauth(unsigned long arg);
--extern int hci_dev_setptype(unsigned long arg);
--extern int hci_conn_list(unsigned long arg);
--extern int hci_inquiry(unsigned long arg);
-+/* ----- HCI Devices ----- */
-+static inline void hci_dev_put(struct hci_dev *d)
-+{
-+ if (atomic_dec_and_test(&d->refcnt))
-+ d->destruct(d);
-+}
-+#define hci_dev_hold(d) atomic_inc(&d->refcnt)
-
--extern __u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode);
--extern __u32 hci_dev_getmode(struct hci_dev *hdev);
-+#define hci_dev_lock(d) spin_lock(&d->lock)
-+#define hci_dev_unlock(d) spin_unlock(&d->lock)
-+#define hci_dev_lock_bh(d) spin_lock_bh(&d->lock)
-+#define hci_dev_unlock_bh(d) spin_unlock_bh(&d->lock)
-
--extern int hci_recv_frame(struct sk_buff *skb);
-+struct hci_dev *hci_dev_get(int index);
-+struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst);
-+int hci_register_dev(struct hci_dev *hdev);
-+int hci_unregister_dev(struct hci_dev *hdev);
-+int hci_suspend_dev(struct hci_dev *hdev);
-+int hci_resume_dev(struct hci_dev *hdev);
-+int hci_dev_open(__u16 dev);
-+int hci_dev_close(__u16 dev);
-+int hci_dev_reset(__u16 dev);
-+int hci_dev_reset_stat(__u16 dev);
-+int hci_dev_cmd(unsigned int cmd, unsigned long arg);
-+int hci_get_dev_list(unsigned long arg);
-+int hci_get_dev_info(unsigned long arg);
-+int hci_get_conn_list(unsigned long arg);
-+int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg);
-+int hci_inquiry(unsigned long arg);
-+
-+int hci_recv_frame(struct sk_buff *skb);
-+void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
-
- /* ----- LMP capabilities ----- */
- #define lmp_rswitch_capable(dev) (dev->features[0] & LMP_RSWITCH)
-+#define lmp_encrypt_capable(dev) (dev->features[0] & LMP_ENCRYPT)
-
- /* ----- HCI tasks ----- */
- static inline void hci_sched_cmd(struct hci_dev *hdev)
-@@ -284,43 +353,130 @@
- /* ----- HCI protocols ----- */
- struct hci_proto {
- char *name;
-- __u32 id;
-- __u32 flags;
-+ unsigned int id;
-+ unsigned long flags;
-
- void *priv;
-
-- int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr);
-- int (*connect_cfm) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 status, struct hci_conn *conn);
-+ int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type);
-+ int (*connect_cfm) (struct hci_conn *conn, __u8 status);
- int (*disconn_ind) (struct hci_conn *conn, __u8 reason);
-- int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb , __u16 flags);
-+ int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
- int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb);
-+ int (*auth_cfm) (struct hci_conn *conn, __u8 status);
-+ int (*encrypt_cfm) (struct hci_conn *conn, __u8 status);
- };
-
--extern int hci_register_proto(struct hci_proto *hproto);
--extern int hci_unregister_proto(struct hci_proto *hproto);
--extern int hci_register_notifier(struct notifier_block *nb);
--extern int hci_unregister_notifier(struct notifier_block *nb);
--extern int hci_connect(struct hci_dev * hdev, bdaddr_t * bdaddr);
--extern int hci_disconnect(struct hci_conn *conn, __u8 reason);
--extern int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void * param);
--extern int hci_send_raw(struct sk_buff *skb);
--extern int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
--extern int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
-+static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
-+{
-+ register struct hci_proto *hp;
-+ int mask = 0;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->connect_ind)
-+ mask |= hp->connect_ind(hdev, bdaddr, type);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->connect_ind)
-+ mask |= hp->connect_ind(hdev, bdaddr, type);
-+
-+ return mask;
-+}
-+
-+static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
-+{
-+ register struct hci_proto *hp;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->connect_cfm)
-+ hp->connect_cfm(conn, status);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->connect_cfm)
-+ hp->connect_cfm(conn, status);
-+}
-+
-+static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason)
-+{
-+ register struct hci_proto *hp;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->disconn_ind)
-+ hp->disconn_ind(conn, reason);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->disconn_ind)
-+ hp->disconn_ind(conn, reason);
-+}
-+
-+static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
-+{
-+ register struct hci_proto *hp;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->auth_cfm)
-+ hp->auth_cfm(conn, status);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->auth_cfm)
-+ hp->auth_cfm(conn, status);
-+}
-+
-+static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status)
-+{
-+ register struct hci_proto *hp;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->encrypt_cfm)
-+ hp->encrypt_cfm(conn, status);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->encrypt_cfm)
-+ hp->encrypt_cfm(conn, status);
-+}
-+
-+int hci_register_proto(struct hci_proto *hproto);
-+int hci_unregister_proto(struct hci_proto *hproto);
-+int hci_register_notifier(struct notifier_block *nb);
-+int hci_unregister_notifier(struct notifier_block *nb);
-+
-+int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param);
-+int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
-+int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
-+
-+void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf);
-+
-+void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
-
- /* ----- HCI Sockets ----- */
--extern void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
-+void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
-
- /* HCI info for socket */
--#define hci_pi(sk) ((struct hci_pinfo *) &sk->protinfo)
-+#define hci_pi(sk) ((struct hci_pinfo *) &sk->tp_pinfo)
- struct hci_pinfo {
- struct hci_dev *hdev;
- struct hci_filter filter;
- __u32 cmsg_mask;
- };
-
-+/* HCI security filter */
-+#define HCI_SFLT_MAX_OGF 5
-+
-+struct hci_sec_filter {
-+ __u32 type_mask;
-+ __u32 event_mask[2];
-+ __u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4];
-+};
-+
- /* ----- HCI requests ----- */
- #define HCI_REQ_DONE 0
- #define HCI_REQ_PEND 1
- #define HCI_REQ_CANCELED 2
-
-+#define hci_req_lock(d) down(&d->req_lock)
-+#define hci_req_unlock(d) up(&d->req_lock)
-+
-+void hci_req_complete(struct hci_dev *hdev, int result);
-+void hci_req_cancel(struct hci_dev *hdev, int err);
-+
- #endif /* __HCI_CORE_H */
---- linux/include/net/bluetooth/hci.h~bluetooth-2.4.18-mh11 2001-09-07 18:28:38.000000000 +0200
-+++ linux/include/net/bluetooth/hci.h 2004-01-25 23:37:39.000000000 +0100
-@@ -23,59 +23,75 @@
- */
-
- /*
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __HCI_H
- #define __HCI_H
-
--#include <asm/byteorder.h>
--
--#define HCI_MAX_DEV 8
--#define HCI_MAX_FRAME_SIZE 2048
-+#define HCI_MAX_ACL_SIZE 1024
-+#define HCI_MAX_SCO_SIZE 255
-+#define HCI_MAX_EVENT_SIZE 260
-+#define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4)
-
- /* HCI dev events */
- #define HCI_DEV_REG 1
- #define HCI_DEV_UNREG 2
- #define HCI_DEV_UP 3
- #define HCI_DEV_DOWN 4
-+#define HCI_DEV_SUSPEND 5
-+#define HCI_DEV_RESUME 6
-
- /* HCI device types */
--#define HCI_UART 0
-+#define HCI_VHCI 0
- #define HCI_USB 1
--#define HCI_VHCI 2
-+#define HCI_PCCARD 2
-+#define HCI_UART 3
-+#define HCI_RS232 4
-+#define HCI_PCI 5
-
--/* HCI device modes */
--#define HCI_NORMAL 0x0001
--#define HCI_RAW 0x0002
--#define HCI_MODE_MASK (HCI_NORMAL | HCI_RAW)
--#define HCI_SOCK 0x1000
-+/* HCI device flags */
-+enum {
-+ HCI_UP,
-+ HCI_INIT,
-+ HCI_RUNNING,
-
--/* HCI device states */
--#define HCI_INIT 0x0010
--#define HCI_UP 0x0020
--#define HCI_RUNNING 0x0040
-+ HCI_PSCAN,
-+ HCI_ISCAN,
-+ HCI_AUTH,
-+ HCI_ENCRYPT,
-+ HCI_INQUIRY,
-
--/* HCI device flags */
--#define HCI_PSCAN 0x0100
--#define HCI_ISCAN 0x0200
--#define HCI_AUTH 0x0400
-+ HCI_RAW
-+};
-
--/* HCI Ioctl defines */
-+/* HCI ioctl defines */
- #define HCIDEVUP _IOW('H', 201, int)
- #define HCIDEVDOWN _IOW('H', 202, int)
- #define HCIDEVRESET _IOW('H', 203, int)
--#define HCIRESETSTAT _IOW('H', 204, int)
--#define HCIGETINFO _IOR('H', 205, int)
--#define HCIGETDEVLIST _IOR('H', 206, int)
--#define HCISETRAW _IOW('H', 207, int)
--#define HCISETSCAN _IOW('H', 208, int)
--#define HCISETAUTH _IOW('H', 209, int)
--#define HCIINQUIRY _IOR('H', 210, int)
--#define HCISETPTYPE _IOW('H', 211, int)
-+#define HCIDEVRESTAT _IOW('H', 204, int)
-+
-+#define HCIGETDEVLIST _IOR('H', 210, int)
-+#define HCIGETDEVINFO _IOR('H', 211, int)
- #define HCIGETCONNLIST _IOR('H', 212, int)
-+#define HCIGETCONNINFO _IOR('H', 213, int)
-
--#ifndef __NO_HCI_DEFS
-+#define HCISETRAW _IOW('H', 220, int)
-+#define HCISETSCAN _IOW('H', 221, int)
-+#define HCISETAUTH _IOW('H', 222, int)
-+#define HCISETENCRYPT _IOW('H', 223, int)
-+#define HCISETPTYPE _IOW('H', 224, int)
-+#define HCISETLINKPOL _IOW('H', 225, int)
-+#define HCISETLINKMODE _IOW('H', 226, int)
-+#define HCISETACLMTU _IOW('H', 227, int)
-+#define HCISETSCOMTU _IOW('H', 228, int)
-+
-+#define HCIINQUIRY _IOR('H', 240, int)
-+
-+/* HCI timeouts */
-+#define HCI_CONN_TIMEOUT (HZ * 40)
-+#define HCI_DISCONN_TIMEOUT (HZ * 2)
-+#define HCI_CONN_IDLE_TIMEOUT (HZ * 60)
-
- /* HCI Packet types */
- #define HCI_COMMAND_PKT 0x01
-@@ -92,11 +108,18 @@
- #define HCI_DH3 0x0800
- #define HCI_DH5 0x8000
-
-+#define HCI_HV1 0x0020
-+#define HCI_HV2 0x0040
-+#define HCI_HV3 0x0080
-+
-+#define SCO_PTYPE_MASK (HCI_HV1 | HCI_HV2 | HCI_HV3)
-+#define ACL_PTYPE_MASK (~SCO_PTYPE_MASK)
-+
- /* ACL flags */
--#define ACL_CONT 0x0001
--#define ACL_START 0x0002
--#define ACL_ACTIVE_BCAST 0x0010
--#define ACL_PICO_BCAST 0x0020
-+#define ACL_CONT 0x01
-+#define ACL_START 0x02
-+#define ACL_ACTIVE_BCAST 0x04
-+#define ACL_PICO_BCAST 0x08
-
- /* Baseband links */
- #define SCO_LINK 0x00
-@@ -125,6 +148,20 @@
- #define LMP_PSCHEME 0x02
- #define LMP_PCONTROL 0x04
-
-+/* Link policies */
-+#define HCI_LP_RSWITCH 0x0001
-+#define HCI_LP_HOLD 0x0002
-+#define HCI_LP_SNIFF 0x0004
-+#define HCI_LP_PARK 0x0008
-+
-+/* Link mode */
-+#define HCI_LM_ACCEPT 0x8000
-+#define HCI_LM_MASTER 0x0001
-+#define HCI_LM_AUTH 0x0002
-+#define HCI_LM_ENCRYPT 0x0004
-+#define HCI_LM_TRUSTED 0x0008
-+#define HCI_LM_RELIABLE 0x0010
-+
- /* ----- HCI Commands ----- */
- /* OGF & OCF values */
-
-@@ -137,9 +174,10 @@
- __u8 hci_ver;
- __u16 hci_rev;
- __u8 lmp_ver;
-- __u16 man_name;
-- __u16 lmp_sub;
-+ __u16 manufacturer;
-+ __u16 lmp_subver;
- } __attribute__ ((packed)) read_local_version_rp;
-+#define READ_LOCAL_VERSION_RP_SIZE 9
-
- #define OCF_READ_LOCAL_FEATURES 0x0003
- typedef struct {
-@@ -165,18 +203,24 @@
- /* Host Controller and Baseband */
- #define OGF_HOST_CTL 0x03
- #define OCF_RESET 0x0003
-+#define OCF_READ_AUTH_ENABLE 0x001F
- #define OCF_WRITE_AUTH_ENABLE 0x0020
-- #define AUTH_DISABLED 0x00
-- #define AUTH_ENABLED 0x01
-+ #define AUTH_DISABLED 0x00
-+ #define AUTH_ENABLED 0x01
-+
-+#define OCF_READ_ENCRYPT_MODE 0x0021
-+#define OCF_WRITE_ENCRYPT_MODE 0x0022
-+ #define ENCRYPT_DISABLED 0x00
-+ #define ENCRYPT_P2P 0x01
-+ #define ENCRYPT_BOTH 0x02
-
- #define OCF_WRITE_CA_TIMEOUT 0x0016
- #define OCF_WRITE_PG_TIMEOUT 0x0018
-
- #define OCF_WRITE_SCAN_ENABLE 0x001A
-- #define SCANS_DISABLED 0x00
-- #define IS_ENA_PS_DIS 0x01
-- #define IS_DIS_PS_ENA 0x02
-- #define IS_ENA_PS_ENA 0x03
-+ #define SCAN_DISABLED 0x00
-+ #define SCAN_INQUIRY 0x01
-+ #define SCAN_PAGE 0x02
-
- #define OCF_SET_EVENT_FLT 0x0005
- typedef struct {
-@@ -226,9 +270,18 @@
- } __attribute__ ((packed)) write_class_of_dev_cp;
- #define WRITE_CLASS_OF_DEV_CP_SIZE 3
-
-+#define OCF_HOST_BUFFER_SIZE 0x0033
-+typedef struct {
-+ __u16 acl_mtu;
-+ __u8 sco_mtu;
-+ __u16 acl_max_pkt;
-+ __u16 sco_max_pkt;
-+} __attribute__ ((packed)) host_buffer_size_cp;
-+#define HOST_BUFFER_SIZE_CP_SIZE 7
-+
- /* Link Control */
- #define OGF_LINK_CTL 0x01
--#define OCF_CREATE_CONN 0x0005
-+#define OCF_CREATE_CONN 0x0005
- typedef struct {
- bdaddr_t bdaddr;
- __u16 pkt_type;
-@@ -246,6 +299,13 @@
- } __attribute__ ((packed)) accept_conn_req_cp;
- #define ACCEPT_CONN_REQ_CP_SIZE 7
-
-+#define OCF_REJECT_CONN_REQ 0x000a
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 reason;
-+} __attribute__ ((packed)) reject_conn_req_cp;
-+#define REJECT_CONN_REQ_CP_SIZE 7
-+
- #define OCF_DISCONNECT 0x0006
- typedef struct {
- __u16 handle;
-@@ -253,17 +313,142 @@
- } __attribute__ ((packed)) disconnect_cp;
- #define DISCONNECT_CP_SIZE 3
-
-+#define OCF_ADD_SCO 0x0007
-+typedef struct {
-+ __u16 handle;
-+ __u16 pkt_type;
-+} __attribute__ ((packed)) add_sco_cp;
-+#define ADD_SCO_CP_SIZE 4
-+
- #define OCF_INQUIRY 0x0001
- typedef struct {
- __u8 lap[3];
-- __u8 lenght;
-+ __u8 length;
- __u8 num_rsp;
- } __attribute__ ((packed)) inquiry_cp;
- #define INQUIRY_CP_SIZE 5
-
--#define OGF_LINK_POLICY 0x02 /* Link Policy */
-+typedef struct {
-+ __u8 status;
-+ bdaddr_t bdaddr;
-+} __attribute__ ((packed)) status_bdaddr_rp;
-+#define STATUS_BDADDR_RP_SIZE 7
-
--/* --------- HCI Events --------- */
-+#define OCF_INQUIRY_CANCEL 0x0002
-+
-+#define OCF_LINK_KEY_REPLY 0x000B
-+#define OCF_LINK_KEY_NEG_REPLY 0x000C
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 link_key[16];
-+} __attribute__ ((packed)) link_key_reply_cp;
-+#define LINK_KEY_REPLY_CP_SIZE 22
-+
-+#define OCF_PIN_CODE_REPLY 0x000D
-+#define OCF_PIN_CODE_NEG_REPLY 0x000E
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 pin_len;
-+ __u8 pin_code[16];
-+} __attribute__ ((packed)) pin_code_reply_cp;
-+#define PIN_CODE_REPLY_CP_SIZE 23
-+
-+#define OCF_CHANGE_CONN_PTYPE 0x000F
-+typedef struct {
-+ __u16 handle;
-+ __u16 pkt_type;
-+} __attribute__ ((packed)) change_conn_ptype_cp;
-+#define CHANGE_CONN_PTYPE_CP_SIZE 4
-+
-+#define OCF_AUTH_REQUESTED 0x0011
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) auth_requested_cp;
-+#define AUTH_REQUESTED_CP_SIZE 2
-+
-+#define OCF_SET_CONN_ENCRYPT 0x0013
-+typedef struct {
-+ __u16 handle;
-+ __u8 encrypt;
-+} __attribute__ ((packed)) set_conn_encrypt_cp;
-+#define SET_CONN_ENCRYPT_CP_SIZE 3
-+
-+#define OCF_REMOTE_NAME_REQ 0x0019
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 pscan_rep_mode;
-+ __u8 pscan_mode;
-+ __u16 clock_offset;
-+} __attribute__ ((packed)) remote_name_req_cp;
-+#define REMOTE_NAME_REQ_CP_SIZE 10
-+
-+#define OCF_READ_REMOTE_FEATURES 0x001B
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) read_remote_features_cp;
-+#define READ_REMOTE_FEATURES_CP_SIZE 2
-+
-+#define OCF_READ_REMOTE_VERSION 0x001D
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) read_remote_version_cp;
-+#define READ_REMOTE_VERSION_CP_SIZE 2
-+
-+/* Link Policy */
-+#define OGF_LINK_POLICY 0x02
-+#define OCF_ROLE_DISCOVERY 0x0009
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) role_discovery_cp;
-+#define ROLE_DISCOVERY_CP_SIZE 2
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u8 role;
-+} __attribute__ ((packed)) role_discovery_rp;
-+#define ROLE_DISCOVERY_RP_SIZE 4
-+
-+#define OCF_READ_LINK_POLICY 0x000C
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) read_link_policy_cp;
-+#define READ_LINK_POLICY_CP_SIZE 2
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u16 policy;
-+} __attribute__ ((packed)) read_link_policy_rp;
-+#define READ_LINK_POLICY_RP_SIZE 5
-+
-+#define OCF_SWITCH_ROLE 0x000B
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 role;
-+} __attribute__ ((packed)) switch_role_cp;
-+#define SWITCH_ROLE_CP_SIZE 7
-+
-+#define OCF_WRITE_LINK_POLICY 0x000D
-+typedef struct {
-+ __u16 handle;
-+ __u16 policy;
-+} __attribute__ ((packed)) write_link_policy_cp;
-+#define WRITE_LINK_POLICY_CP_SIZE 4
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+} __attribute__ ((packed)) write_link_policy_rp;
-+#define WRITE_LINK_POLICY_RP_SIZE 3
-+
-+/* Status params */
-+#define OGF_STATUS_PARAM 0x05
-+
-+/* Testing commands */
-+#define OGF_TESTING_CMD 0x3e
-+
-+/* Vendor specific commands */
-+#define OGF_VENDOR_CMD 0x3f
-+
-+/* ---- HCI Events ---- */
- #define EVT_INQUIRY_COMPLETE 0x01
-
- #define EVT_INQUIRY_RESULT 0x02
-@@ -272,11 +457,22 @@
- __u8 pscan_rep_mode;
- __u8 pscan_period_mode;
- __u8 pscan_mode;
-- __u8 class[3];
-+ __u8 dev_class[3];
- __u16 clock_offset;
- } __attribute__ ((packed)) inquiry_info;
- #define INQUIRY_INFO_SIZE 14
-
-+#define EVT_INQUIRY_RESULT_WITH_RSSI 0x22
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 pscan_rep_mode;
-+ __u8 pscan_period_mode;
-+ __u8 dev_class[3];
-+ __u16 clock_offset;
-+ __u8 rssi;
-+} __attribute__ ((packed)) inquiry_info_with_rssi;
-+#define INQUIRY_INFO_WITH_RSSI_SIZE 14
-+
- #define EVT_CONN_COMPLETE 0x03
- typedef struct {
- __u8 status;
-@@ -303,6 +499,44 @@
- } __attribute__ ((packed)) evt_disconn_complete;
- #define EVT_DISCONN_COMPLETE_SIZE 4
-
-+#define EVT_AUTH_COMPLETE 0x06
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+} __attribute__ ((packed)) evt_auth_complete;
-+#define EVT_AUTH_COMPLETE_SIZE 3
-+
-+#define EVT_REMOTE_NAME_REQ_COMPLETE 0x07
-+typedef struct {
-+ __u8 status;
-+ bdaddr_t bdaddr;
-+ __u8 name[248];
-+} __attribute__ ((packed)) evt_remote_name_req_complete;
-+#define EVT_REMOTE_NAME_REQ_COMPLETE_SIZE 255
-+
-+#define EVT_ENCRYPT_CHANGE 0x08
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u8 encrypt;
-+} __attribute__ ((packed)) evt_encrypt_change;
-+#define EVT_ENCRYPT_CHANGE_SIZE 5
-+
-+#define EVT_QOS_SETUP_COMPLETE 0x0D
-+typedef struct {
-+ __u8 service_type;
-+ __u32 token_rate;
-+ __u32 peak_bandwidth;
-+ __u32 latency;
-+ __u32 delay_variation;
-+} __attribute__ ((packed)) hci_qos;
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ hci_qos qos;
-+} __attribute__ ((packed)) evt_qos_setup_complete;
-+#define EVT_QOS_SETUP_COMPLETE_SIZE 20
-+
- #define EVT_CMD_COMPLETE 0x0e
- typedef struct {
- __u8 ncmd;
-@@ -321,16 +555,78 @@
- #define EVT_NUM_COMP_PKTS 0x13
- typedef struct {
- __u8 num_hndl;
-- /* variable lenght part */
-+ /* variable length part */
- } __attribute__ ((packed)) evt_num_comp_pkts;
- #define EVT_NUM_COMP_PKTS_SIZE 1
-
--#define EVT_HCI_DEV_EVENT 0xfd
-+#define EVT_ROLE_CHANGE 0x12
-+typedef struct {
-+ __u8 status;
-+ bdaddr_t bdaddr;
-+ __u8 role;
-+} __attribute__ ((packed)) evt_role_change;
-+#define EVT_ROLE_CHANGE_SIZE 8
-+
-+#define EVT_PIN_CODE_REQ 0x16
-+typedef struct {
-+ bdaddr_t bdaddr;
-+} __attribute__ ((packed)) evt_pin_code_req;
-+#define EVT_PIN_CODE_REQ_SIZE 6
-+
-+#define EVT_LINK_KEY_REQ 0x17
-+typedef struct {
-+ bdaddr_t bdaddr;
-+} __attribute__ ((packed)) evt_link_key_req;
-+#define EVT_LINK_KEY_REQ_SIZE 6
-+
-+#define EVT_LINK_KEY_NOTIFY 0x18
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 link_key[16];
-+ __u8 key_type;
-+} __attribute__ ((packed)) evt_link_key_notify;
-+#define EVT_LINK_KEY_NOTIFY_SIZE 23
-+
-+#define EVT_READ_REMOTE_FEATURES_COMPLETE 0x0B
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u8 features[8];
-+} __attribute__ ((packed)) evt_read_remote_features_complete;
-+#define EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE 11
-+
-+#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u8 lmp_ver;
-+ __u16 manufacturer;
-+ __u16 lmp_subver;
-+} __attribute__ ((packed)) evt_read_remote_version_complete;
-+#define EVT_READ_REMOTE_VERSION_COMPLETE_SIZE 8
-+
-+/* Internal events generated by BlueZ stack */
-+#define EVT_STACK_INTERNAL 0xfd
-+typedef struct {
-+ __u16 type;
-+ __u8 data[0];
-+} __attribute__ ((packed)) evt_stack_internal;
-+#define EVT_STACK_INTERNAL_SIZE 2
-+
-+#define EVT_SI_DEVICE 0x01
-+typedef struct {
-+ __u16 event;
-+ __u16 dev_id;
-+} __attribute__ ((packed)) evt_si_device;
-+#define EVT_SI_DEVICE_SIZE 4
-+
-+#define EVT_SI_SECURITY 0x02
- typedef struct {
- __u16 event;
-- __u16 param;
--} __attribute__ ((packed)) evt_hci_dev_event;
--#define EVT_HCI_DEV_EVENT_SIZE 4
-+ __u16 proto;
-+ __u16 subproto;
-+ __u8 incomming;
-+} __attribute__ ((packed)) evt_si_security;
-
- /* -------- HCI Packet structures -------- */
- #define HCI_TYPE_LEN 1
-@@ -369,14 +665,14 @@
- #define acl_handle(h) (h & 0x0fff)
- #define acl_flags(h) (h >> 12)
-
--#endif /* _NO_HCI_DEFS */
--
- /* HCI Socket options */
--#define HCI_DATA_DIR 0x0001
--#define HCI_FILTER 0x0002
-+#define HCI_DATA_DIR 1
-+#define HCI_FILTER 2
-+#define HCI_TIME_STAMP 3
-
- /* HCI CMSG flags */
- #define HCI_CMSG_DIR 0x0001
-+#define HCI_CMSG_TSTAMP 0x0002
-
- struct sockaddr_hci {
- sa_family_t hci_family;
-@@ -387,27 +683,29 @@
- struct hci_filter {
- __u32 type_mask;
- __u32 event_mask[2];
-+ __u16 opcode;
- };
-
--struct hci_dev_req {
-- __u16 dev_id;
-- __u32 dev_opt;
--};
--
--struct hci_dev_list_req {
-- __u16 dev_num;
-- struct hci_dev_req dev_req[0]; /* hci_dev_req structures */
--};
-+#define HCI_FLT_TYPE_BITS 31
-+#define HCI_FLT_EVENT_BITS 63
-+#define HCI_FLT_OGF_BITS 63
-+#define HCI_FLT_OCF_BITS 127
-
--struct hci_inquiry_req {
-- __u16 dev_id;
-- __u16 flags;
-- __u8 lap[3];
-- __u8 length;
-- __u8 num_rsp;
--};
--#define IREQ_CACHE_FLUSH 0x0001
-+#if BITS_PER_LONG == 64
-+static inline void hci_set_bit(int nr, void *addr)
-+{
-+ *((__u32 *) addr + (nr >> 5)) |= ((__u32) 1 << (nr & 31));
-+}
-+static inline int hci_test_bit(int nr, void *addr)
-+{
-+ return *((__u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
-+}
-+#else
-+#define hci_set_bit set_bit
-+#define hci_test_bit test_bit
-+#endif
-
-+/* Ioctl requests structures */
- struct hci_dev_stats {
- __u32 err_rx;
- __u32 err_tx;
-@@ -433,11 +731,13 @@
- __u8 features[8];
-
- __u32 pkt_type;
-+ __u32 link_policy;
-+ __u32 link_mode;
-
- __u16 acl_mtu;
-- __u16 acl_max;
-+ __u16 acl_pkts;
- __u16 sco_mtu;
-- __u16 sco_max;
-+ __u16 sco_pkts;
-
- struct hci_dev_stats stat;
- };
-@@ -445,6 +745,20 @@
- struct hci_conn_info {
- __u16 handle;
- bdaddr_t bdaddr;
-+ __u8 type;
-+ __u8 out;
-+ __u16 state;
-+ __u32 link_mode;
-+};
-+
-+struct hci_dev_req {
-+ __u16 dev_id;
-+ __u32 dev_opt;
-+};
-+
-+struct hci_dev_list_req {
-+ __u16 dev_num;
-+ struct hci_dev_req dev_req[0]; /* hci_dev_req structures */
- };
-
- struct hci_conn_list_req {
-@@ -453,4 +767,26 @@
- struct hci_conn_info conn_info[0];
- };
-
-+struct hci_conn_info_req {
-+ bdaddr_t bdaddr;
-+ __u8 type;
-+ struct hci_conn_info conn_info[0];
-+};
-+
-+struct hci_inquiry_req {
-+ __u16 dev_id;
-+ __u16 flags;
-+ __u8 lap[3];
-+ __u8 length;
-+ __u8 num_rsp;
-+};
-+#define IREQ_CACHE_FLUSH 0x0001
-+
-+struct hci_remotename_req {
-+ __u16 dev_id;
-+ __u16 flags;
-+ bdaddr_t bdaddr;
-+ __u8 name[248];
-+};
-+
- #endif /* __HCI_H */
---- linux/include/net/bluetooth/hci_uart.h~bluetooth-2.4.18-mh11
-+++ linux/include/net/bluetooth/hci_uart.h
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifndef N_HCI
--#define N_HCI 15
--#endif
--
--#ifdef __KERNEL__
--
--#define tty2n_hci(tty) ((struct n_hci *)((tty)->disc_data))
--#define n_hci2tty(n_hci) ((n_hci)->tty)
--
--struct n_hci {
-- struct tty_struct *tty;
-- struct hci_dev hdev;
--
-- struct sk_buff_head txq;
-- unsigned long tx_state;
--
-- spinlock_t rx_lock;
-- unsigned long rx_state;
-- unsigned long rx_count;
-- struct sk_buff *rx_skb;
--};
--
--/* Transmit states */
--#define TRANS_SENDING 1
--#define TRANS_WAKEUP 2
--
--/* Receiver States */
--#define WAIT_PACKET_TYPE 0
--#define WAIT_EVENT_HDR 1
--#define WAIT_ACL_HDR 2
--#define WAIT_SCO_HDR 3
--#define WAIT_DATA 4
--
--#endif /* __KERNEL__ */
---- linux/include/net/bluetooth/hci_usb.h~bluetooth-2.4.18-mh11
-+++ linux/include/net/bluetooth/hci_usb.h
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifdef __KERNEL__
--
--/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
--#define HCI_DEV_CLASS 0xe0 /* Wireless class */
--#define HCI_DEV_SUBCLASS 0x01 /* RF subclass */
--#define HCI_DEV_PROTOCOL 0x01 /* Bluetooth programming protocol */
--
--#define HCI_CTRL_REQ 0x20
--
--struct hci_usb {
-- struct usb_device *udev;
--
-- devrequest dev_req;
-- struct urb *ctrl_urb;
-- struct urb *intr_urb;
-- struct urb *read_urb;
-- struct urb *write_urb;
--
-- __u8 *read_buf;
-- __u8 *intr_buf;
-- struct sk_buff *intr_skb;
-- int intr_count;
--
-- __u8 bulk_out_ep_addr;
-- __u8 bulk_in_ep_addr;
-- __u8 intr_in_ep_addr;
-- __u8 intr_in_interval;
--
-- struct hci_dev hdev;
--
-- unsigned long tx_state;
-- struct sk_buff_head tx_ctrl_q;
-- struct sk_buff_head tx_write_q;
--};
--
--/* Transmit states */
--#define HCI_TX_CTRL 1
--#define HCI_TX_WRITE 2
--
--#endif /* __KERNEL__ */
---- linux/include/net/bluetooth/hci_vhci.h~bluetooth-2.4.18-mh11
-+++ linux/include/net/bluetooth/hci_vhci.h
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifndef __HCI_VHCI_H
--#define __HCI_VHCI_H
--
--#ifdef __KERNEL__
--
--struct hci_vhci_struct {
-- struct hci_dev hdev;
-- __u32 flags;
-- wait_queue_head_t read_wait;
-- struct sk_buff_head readq;
-- struct fasync_struct *fasync;
--};
--
--/* VHCI device flags */
--#define VHCI_FASYNC 0x0010
--
--#endif /* __KERNEL__ */
--
--#define VHCI_DEV "/dev/vhci"
--#define VHCI_MINOR 250
--
--#endif /* __HCI_VHCI_H */
---- linux/include/net/bluetooth/l2cap_core.h~bluetooth-2.4.18-mh11
-+++ linux/include/net/bluetooth/l2cap_core.h
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifndef __L2CAP_CORE_H
--#define __L2CAP_CORE_H
--
--#ifdef __KERNEL__
--
--/* ----- L2CAP interface ----- */
--struct l2cap_iff {
-- struct list_head list;
-- struct hci_dev *hdev;
-- bdaddr_t *bdaddr;
-- __u16 mtu;
-- spinlock_t lock;
-- struct list_head conn_list;
--};
--
--static inline void l2cap_iff_lock(struct l2cap_iff *iff)
--{
-- spin_lock(&iff->lock);
--}
--
--static inline void l2cap_iff_unlock(struct l2cap_iff *iff)
--{
-- spin_unlock(&iff->lock);
--}
--
--/* ----- L2CAP connections ----- */
--struct l2cap_chan_list {
-- struct sock *head;
-- rwlock_t lock;
-- long num;
--};
--
--struct l2cap_conn {
-- struct l2cap_iff *iff;
-- struct list_head list;
--
-- struct hci_conn *hconn;
--
-- __u16 state;
-- __u8 out;
-- bdaddr_t src;
-- bdaddr_t dst;
--
-- spinlock_t lock;
-- atomic_t refcnt;
--
-- struct sk_buff *rx_skb;
-- __u32 rx_len;
-- __u8 rx_ident;
-- __u8 tx_ident;
--
-- struct l2cap_chan_list chan_list;
--
-- struct timer_list timer;
--};
--
--static inline void __l2cap_conn_link(struct l2cap_iff *iff, struct l2cap_conn *c)
--{
-- list_add(&c->list, &iff->conn_list);
--}
--
--static inline void __l2cap_conn_unlink(struct l2cap_iff *iff, struct l2cap_conn *c)
--{
-- list_del(&c->list);
--}
--
--/* ----- L2CAP channel and socket info ----- */
--#define l2cap_pi(sk) ((struct l2cap_pinfo *) &sk->protinfo)
--
--struct l2cap_accept_q {
-- struct sock *head;
-- struct sock *tail;
--};
--
--struct l2cap_pinfo {
-- bdaddr_t src;
-- bdaddr_t dst;
-- __u16 psm;
-- __u16 dcid;
-- __u16 scid;
-- __u32 flags;
--
-- __u16 imtu;
-- __u16 omtu;
-- __u16 flush_to;
--
-- __u8 conf_state;
-- __u16 conf_mtu;
--
-- __u8 ident;
--
-- struct l2cap_conn *conn;
-- struct sock *next_c;
-- struct sock *prev_c;
--
-- struct sock *parent;
-- struct sock *next_q;
-- struct sock *prev_q;
--
-- struct l2cap_accept_q accept_q;
--};
--
--#define CONF_REQ_SENT 0x01
--#define CONF_INPUT_DONE 0x02
--#define CONF_OUTPUT_DONE 0x04
--
--extern struct bluez_sock_list l2cap_sk_list;
--extern struct list_head l2cap_iff_list;
--extern rwlock_t l2cap_rt_lock;
--
--extern void l2cap_register_proc(void);
--extern void l2cap_unregister_proc(void);
--
--#endif /* __KERNEL__ */
--
--#endif /* __L2CAP_CORE_H */
---- linux/include/net/bluetooth/l2cap.h~bluetooth-2.4.18-mh11 2001-09-07 18:28:38.000000000 +0200
-+++ linux/include/net/bluetooth/l2cap.h 2004-01-25 23:37:39.000000000 +0100
-@@ -23,22 +23,17 @@
- */
-
- /*
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __L2CAP_H
- #define __L2CAP_H
-
--#include <asm/types.h>
--#include <asm/byteorder.h>
--
- /* L2CAP defaults */
- #define L2CAP_DEFAULT_MTU 672
- #define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
-
- #define L2CAP_CONN_TIMEOUT (HZ * 40)
--#define L2CAP_DISCONN_TIMEOUT (HZ * 2)
--#define L2CAP_CONN_IDLE_TIMEOUT (HZ * 60)
-
- /* L2CAP socket address */
- struct sockaddr_l2 {
-@@ -47,17 +42,12 @@
- bdaddr_t l2_bdaddr;
- };
-
--/* set/get sockopt defines */
--#define L2CAP_OPTIONS 0x01
-+/* Socket options */
-+#define L2CAP_OPTIONS 0x01
- struct l2cap_options {
- __u16 omtu;
- __u16 imtu;
- __u16 flush_to;
-- __u32 token_rate;
-- __u32 bucket_size;
-- __u32 pick_band;
-- __u32 latency;
-- __u32 delay_var;
- };
-
- #define L2CAP_CONNINFO 0x02
-@@ -65,6 +55,27 @@
- __u16 hci_handle;
- };
-
-+#define L2CAP_LM 0x03
-+#define L2CAP_LM_MASTER 0x0001
-+#define L2CAP_LM_AUTH 0x0002
-+#define L2CAP_LM_ENCRYPT 0x0004
-+#define L2CAP_LM_TRUSTED 0x0008
-+#define L2CAP_LM_RELIABLE 0x0010
-+
-+#define L2CAP_QOS 0x04
-+struct l2cap_qos {
-+ __u16 service_type;
-+ __u32 token_rate;
-+ __u32 token_bucket_size;
-+ __u32 peak_bandwidth;
-+ __u32 latency;
-+ __u32 delay_variation;
-+};
-+
-+#define L2CAP_SERV_NO_TRAFFIC 0x00
-+#define L2CAP_SERV_BEST_EFFORT 0x01
-+#define L2CAP_SERV_GUARANTEED 0x02
-+
- /* L2CAP command codes */
- #define L2CAP_COMMAND_REJ 0x01
- #define L2CAP_CONN_REQ 0x02
-@@ -79,7 +90,6 @@
- #define L2CAP_INFO_RSP 0x0b
-
- /* L2CAP structures */
--
- typedef struct {
- __u16 len;
- __u16 cid;
-@@ -112,11 +122,17 @@
- } __attribute__ ((packed)) l2cap_conn_rsp;
- #define L2CAP_CONN_RSP_SIZE 8
-
--#define L2CAP_CONN_SUCCESS 0x0000
--#define L2CAP_CONN_PEND 0x0001
--#define L2CAP_CONN_BAD_PSM 0x0002
--#define L2CAP_CONN_SEC_BLOCK 0x0003
--#define L2CAP_CONN_NO_MEM 0x0004
-+/* connect result */
-+#define L2CAP_CR_SUCCESS 0x0000
-+#define L2CAP_CR_PEND 0x0001
-+#define L2CAP_CR_BAD_PSM 0x0002
-+#define L2CAP_CR_SEC_BLOCK 0x0003
-+#define L2CAP_CR_NO_MEM 0x0004
-+
-+/* connect status */
-+#define L2CAP_CS_NO_INFO 0x0000
-+#define L2CAP_CS_AUTHEN_PEND 0x0001
-+#define L2CAP_CS_AUTHOR_PEND 0x0002
-
- typedef struct {
- __u16 dcid;
-@@ -147,6 +163,8 @@
- #define L2CAP_CONF_FLUSH_TO 0x02
- #define L2CAP_CONF_QOS 0x03
-
-+#define L2CAP_CONF_MAX_SIZE 22
-+
- typedef struct {
- __u16 dcid;
- __u16 scid;
-@@ -159,4 +177,74 @@
- } __attribute__ ((packed)) l2cap_disconn_rsp;
- #define L2CAP_DISCONN_RSP_SIZE 4
-
-+typedef struct {
-+ __u16 type;
-+ __u8 data[0];
-+} __attribute__ ((packed)) l2cap_info_req;
-+#define L2CAP_INFO_REQ_SIZE 2
-+
-+typedef struct {
-+ __u16 type;
-+ __u16 result;
-+ __u8 data[0];
-+} __attribute__ ((packed)) l2cap_info_rsp;
-+#define L2CAP_INFO_RSP_SIZE 4
-+
-+/* ----- L2CAP connections ----- */
-+struct l2cap_chan_list {
-+ struct sock *head;
-+ rwlock_t lock;
-+ long num;
-+};
-+
-+struct l2cap_conn {
-+ struct hci_conn *hcon;
-+
-+ bdaddr_t *dst;
-+ bdaddr_t *src;
-+
-+ unsigned int mtu;
-+
-+ spinlock_t lock;
-+
-+ struct sk_buff *rx_skb;
-+ __u32 rx_len;
-+ __u8 rx_ident;
-+ __u8 tx_ident;
-+
-+ struct l2cap_chan_list chan_list;
-+};
-+
-+/* ----- L2CAP channel and socket info ----- */
-+#define l2cap_pi(sk) ((struct l2cap_pinfo *) &sk->tp_pinfo)
-+
-+struct l2cap_pinfo {
-+ __u16 psm;
-+ __u16 dcid;
-+ __u16 scid;
-+
-+ __u16 imtu;
-+ __u16 omtu;
-+ __u16 flush_to;
-+
-+ __u32 link_mode;
-+
-+ __u8 conf_state;
-+ __u8 conf_retry;
-+ __u16 conf_mtu;
-+
-+ __u8 ident;
-+
-+ struct l2cap_conn *conn;
-+ struct sock *next_c;
-+ struct sock *prev_c;
-+};
-+
-+#define L2CAP_CONF_REQ_SENT 0x01
-+#define L2CAP_CONF_INPUT_DONE 0x02
-+#define L2CAP_CONF_OUTPUT_DONE 0x04
-+#define L2CAP_CONF_MAX_RETRIES 2
-+
-+void l2cap_load(void);
-+
- #endif /* __L2CAP_H */
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/include/net/bluetooth/rfcomm.h 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,361 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ RPN support - Dirk Husemann <hud@zurich.ibm.com>
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef __RFCOMM_H
-+#define __RFCOMM_H
-+
-+#define RFCOMM_PSM 3
-+
-+#define RFCOMM_CONN_TIMEOUT (HZ * 30)
-+#define RFCOMM_DISC_TIMEOUT (HZ * 20)
-+
-+#define RFCOMM_DEFAULT_MTU 127
-+#define RFCOMM_DEFAULT_CREDITS 7
-+
-+#define RFCOMM_MAX_L2CAP_MTU 1024
-+#define RFCOMM_MAX_CREDITS 40
-+
-+#define RFCOMM_SKB_HEAD_RESERVE 8
-+#define RFCOMM_SKB_TAIL_RESERVE 2
-+#define RFCOMM_SKB_RESERVE (RFCOMM_SKB_HEAD_RESERVE + RFCOMM_SKB_TAIL_RESERVE)
-+
-+#define RFCOMM_SABM 0x2f
-+#define RFCOMM_DISC 0x43
-+#define RFCOMM_UA 0x63
-+#define RFCOMM_DM 0x0f
-+#define RFCOMM_UIH 0xef
-+
-+#define RFCOMM_TEST 0x08
-+#define RFCOMM_FCON 0x28
-+#define RFCOMM_FCOFF 0x18
-+#define RFCOMM_MSC 0x38
-+#define RFCOMM_RPN 0x24
-+#define RFCOMM_RLS 0x14
-+#define RFCOMM_PN 0x20
-+#define RFCOMM_NSC 0x04
-+
-+#define RFCOMM_V24_FC 0x02
-+#define RFCOMM_V24_RTC 0x04
-+#define RFCOMM_V24_RTR 0x08
-+#define RFCOMM_V24_IC 0x40
-+#define RFCOMM_V24_DV 0x80
-+
-+#define RFCOMM_RPN_BR_2400 0x0
-+#define RFCOMM_RPN_BR_4800 0x1
-+#define RFCOMM_RPN_BR_7200 0x2
-+#define RFCOMM_RPN_BR_9600 0x3
-+#define RFCOMM_RPN_BR_19200 0x4
-+#define RFCOMM_RPN_BR_38400 0x5
-+#define RFCOMM_RPN_BR_57600 0x6
-+#define RFCOMM_RPN_BR_115200 0x7
-+#define RFCOMM_RPN_BR_230400 0x8
-+
-+#define RFCOMM_RPN_DATA_5 0x0
-+#define RFCOMM_RPN_DATA_6 0x1
-+#define RFCOMM_RPN_DATA_7 0x2
-+#define RFCOMM_RPN_DATA_8 0x3
-+
-+#define RFCOMM_RPN_STOP_1 0
-+#define RFCOMM_RPN_STOP_15 1
-+
-+#define RFCOMM_RPN_PARITY_NONE 0x0
-+#define RFCOMM_RPN_PARITY_ODD 0x4
-+#define RFCOMM_RPN_PARITY_EVEN 0x5
-+#define RFCOMM_RPN_PARITY_MARK 0x6
-+#define RFCOMM_RPN_PARITY_SPACE 0x7
-+
-+#define RFCOMM_RPN_FLOW_NONE 0x00
-+
-+#define RFCOMM_RPN_XON_CHAR 0x11
-+#define RFCOMM_RPN_XOFF_CHAR 0x13
-+
-+#define RFCOMM_RPN_PM_BITRATE 0x0001
-+#define RFCOMM_RPN_PM_DATA 0x0002
-+#define RFCOMM_RPN_PM_STOP 0x0004
-+#define RFCOMM_RPN_PM_PARITY 0x0008
-+#define RFCOMM_RPN_PM_PARITY_TYPE 0x0010
-+#define RFCOMM_RPN_PM_XON 0x0020
-+#define RFCOMM_RPN_PM_XOFF 0x0040
-+#define RFCOMM_RPN_PM_FLOW 0x3F00
-+
-+#define RFCOMM_RPN_PM_ALL 0x3F7F
-+
-+struct rfcomm_hdr {
-+ u8 addr;
-+ u8 ctrl;
-+ u8 len; // Actual size can be 2 bytes
-+} __attribute__ ((packed));
-+
-+struct rfcomm_cmd {
-+ u8 addr;
-+ u8 ctrl;
-+ u8 len;
-+ u8 fcs;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_mcc {
-+ u8 type;
-+ u8 len;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_pn {
-+ u8 dlci;
-+ u8 flow_ctrl;
-+ u8 priority;
-+ u8 ack_timer;
-+ u16 mtu;
-+ u8 max_retrans;
-+ u8 credits;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_rpn {
-+ u8 dlci;
-+ u8 bit_rate;
-+ u8 line_settings;
-+ u8 flow_ctrl;
-+ u8 xon_char;
-+ u8 xoff_char;
-+ u16 param_mask;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_rls {
-+ u8 dlci;
-+ u8 status;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_msc {
-+ u8 dlci;
-+ u8 v24_sig;
-+} __attribute__ ((packed));
-+
-+/* ---- Core structures, flags etc ---- */
-+
-+struct rfcomm_session {
-+ struct list_head list;
-+ struct socket *sock;
-+ unsigned long state;
-+ unsigned long flags;
-+ atomic_t refcnt;
-+ int initiator;
-+
-+ /* Default DLC parameters */
-+ int cfc;
-+ uint mtu;
-+
-+ struct list_head dlcs;
-+};
-+
-+struct rfcomm_dlc {
-+ struct list_head list;
-+ struct rfcomm_session *session;
-+ struct sk_buff_head tx_queue;
-+ struct timer_list timer;
-+
-+ spinlock_t lock;
-+ unsigned long state;
-+ unsigned long flags;
-+ atomic_t refcnt;
-+ u8 dlci;
-+ u8 addr;
-+ u8 priority;
-+ u8 v24_sig;
-+ u8 mscex;
-+
-+ uint mtu;
-+ uint cfc;
-+ uint rx_credits;
-+ uint tx_credits;
-+
-+ void *owner;
-+
-+ void (*data_ready)(struct rfcomm_dlc *d, struct sk_buff *skb);
-+ void (*state_change)(struct rfcomm_dlc *d, int err);
-+ void (*modem_status)(struct rfcomm_dlc *d, u8 v24_sig);
-+};
-+
-+/* DLC and session flags */
-+#define RFCOMM_RX_THROTTLED 0
-+#define RFCOMM_TX_THROTTLED 1
-+#define RFCOMM_MSC_PENDING 2
-+#define RFCOMM_TIMED_OUT 3
-+
-+/* Scheduling flags and events */
-+#define RFCOMM_SCHED_STATE 0
-+#define RFCOMM_SCHED_RX 1
-+#define RFCOMM_SCHED_TX 2
-+#define RFCOMM_SCHED_TIMEO 3
-+#define RFCOMM_SCHED_WAKEUP 31
-+
-+/* MSC exchange flags */
-+#define RFCOMM_MSCEX_TX 1
-+#define RFCOMM_MSCEX_RX 2
-+#define RFCOMM_MSCEX_OK (RFCOMM_MSCEX_TX + RFCOMM_MSCEX_RX)
-+
-+/* CFC states */
-+#define RFCOMM_CFC_UNKNOWN -1
-+#define RFCOMM_CFC_DISABLED 0
-+#define RFCOMM_CFC_ENABLED RFCOMM_MAX_CREDITS
-+
-+extern struct task_struct *rfcomm_thread;
-+extern unsigned long rfcomm_event;
-+
-+static inline void rfcomm_schedule(uint event)
-+{
-+ if (!rfcomm_thread)
-+ return;
-+ set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
-+ wake_up_process(rfcomm_thread);
-+}
-+
-+extern struct semaphore rfcomm_sem;
-+#define rfcomm_lock() down(&rfcomm_sem);
-+#define rfcomm_unlock() up(&rfcomm_sem);
-+
-+/* ---- RFCOMM DLCs (channels) ---- */
-+struct rfcomm_dlc *rfcomm_dlc_alloc(int prio);
-+void rfcomm_dlc_free(struct rfcomm_dlc *d);
-+int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel);
-+int rfcomm_dlc_close(struct rfcomm_dlc *d, int reason);
-+int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb);
-+int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig);
-+int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig);
-+
-+#define rfcomm_dlc_lock(d) spin_lock(&d->lock)
-+#define rfcomm_dlc_unlock(d) spin_unlock(&d->lock)
-+
-+static inline void rfcomm_dlc_hold(struct rfcomm_dlc *d)
-+{
-+ atomic_inc(&d->refcnt);
-+}
-+
-+static inline void rfcomm_dlc_put(struct rfcomm_dlc *d)
-+{
-+ if (atomic_dec_and_test(&d->refcnt))
-+ rfcomm_dlc_free(d);
-+}
-+
-+extern void FASTCALL(__rfcomm_dlc_throttle(struct rfcomm_dlc *d));
-+extern void FASTCALL(__rfcomm_dlc_unthrottle(struct rfcomm_dlc *d));
-+
-+static inline void rfcomm_dlc_throttle(struct rfcomm_dlc *d)
-+{
-+ if (!test_and_set_bit(RFCOMM_RX_THROTTLED, &d->flags))
-+ __rfcomm_dlc_throttle(d);
-+}
-+
-+static inline void rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
-+{
-+ if (test_and_clear_bit(RFCOMM_RX_THROTTLED, &d->flags))
-+ __rfcomm_dlc_unthrottle(d);
-+}
-+
-+/* ---- RFCOMM sessions ---- */
-+struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state);
-+struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
-+struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err);
-+void rfcomm_session_del(struct rfcomm_session *s);
-+void rfcomm_session_close(struct rfcomm_session *s, int err);
-+void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst);
-+
-+static inline void rfcomm_session_hold(struct rfcomm_session *s)
-+{
-+ atomic_inc(&s->refcnt);
-+}
-+
-+static inline void rfcomm_session_put(struct rfcomm_session *s)
-+{
-+ if (atomic_dec_and_test(&s->refcnt))
-+ rfcomm_session_del(s);
-+}
-+
-+/* ---- RFCOMM chechsum ---- */
-+extern u8 rfcomm_crc_table[];
-+
-+/* ---- RFCOMM sockets ---- */
-+struct sockaddr_rc {
-+ sa_family_t rc_family;
-+ bdaddr_t rc_bdaddr;
-+ u8 rc_channel;
-+};
-+
-+#define rfcomm_pi(sk) ((struct rfcomm_pinfo *) &sk->tp_pinfo)
-+
-+struct rfcomm_pinfo {
-+ struct rfcomm_dlc *dlc;
-+ u8 channel;
-+};
-+
-+int rfcomm_init_sockets(void);
-+void rfcomm_cleanup_sockets(void);
-+
-+int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d);
-+
-+/* ---- RFCOMM TTY ---- */
-+#define RFCOMM_MAX_DEV 256
-+
-+#define RFCOMMCREATEDEV _IOW('R', 200, int)
-+#define RFCOMMRELEASEDEV _IOW('R', 201, int)
-+#define RFCOMMGETDEVLIST _IOR('R', 210, int)
-+#define RFCOMMGETDEVINFO _IOR('R', 211, int)
-+#define RFCOMMSTEALDLC _IOW('R', 220, int)
-+
-+#define RFCOMM_REUSE_DLC 0
-+#define RFCOMM_RELEASE_ONHUP 1
-+#define RFCOMM_HANGUP_NOW 2
-+#define RFCOMM_TTY_ATTACHED 3
-+
-+struct rfcomm_dev_req {
-+ s16 dev_id;
-+ u32 flags;
-+ bdaddr_t src;
-+ bdaddr_t dst;
-+ u8 channel;
-+};
-+
-+struct rfcomm_dev_info {
-+ s16 id;
-+ u32 flags;
-+ u16 state;
-+ bdaddr_t src;
-+ bdaddr_t dst;
-+ u8 channel;
-+};
-+
-+struct rfcomm_dev_list_req {
-+ u16 dev_num;
-+ struct rfcomm_dev_info dev_info[0];
-+};
-+
-+int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg);
-+int rfcomm_init_ttys(void);
-+void rfcomm_cleanup_ttys(void);
-+
-+#endif /* __RFCOMM_H */
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/include/net/bluetooth/sco.h 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,81 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef __SCO_H
-+#define __SCO_H
-+
-+/* SCO defaults */
-+#define SCO_DEFAULT_MTU 500
-+#define SCO_DEFAULT_FLUSH_TO 0xFFFF
-+
-+#define SCO_CONN_TIMEOUT (HZ * 40)
-+#define SCO_DISCONN_TIMEOUT (HZ * 2)
-+#define SCO_CONN_IDLE_TIMEOUT (HZ * 60)
-+
-+/* SCO socket address */
-+struct sockaddr_sco {
-+ sa_family_t sco_family;
-+ bdaddr_t sco_bdaddr;
-+};
-+
-+/* set/get sockopt defines */
-+#define SCO_OPTIONS 0x01
-+struct sco_options {
-+ __u16 mtu;
-+};
-+
-+#define SCO_CONNINFO 0x02
-+struct sco_conninfo {
-+ __u16 hci_handle;
-+};
-+
-+/* ---- SCO connections ---- */
-+struct sco_conn {
-+ struct hci_conn *hcon;
-+
-+ bdaddr_t *dst;
-+ bdaddr_t *src;
-+
-+ spinlock_t lock;
-+ struct sock *sk;
-+
-+ unsigned int mtu;
-+};
-+
-+#define sco_conn_lock(c) spin_lock(&c->lock);
-+#define sco_conn_unlock(c) spin_unlock(&c->lock);
-+
-+/* ----- SCO socket info ----- */
-+#define sco_pi(sk) ((struct sco_pinfo *) &sk->tp_pinfo)
-+
-+struct sco_pinfo {
-+ __u32 flags;
-+ struct sco_conn *conn;
-+};
-+
-+#endif /* __SCO_H */
---- linux/include/pcmcia/ciscode.h~bluetooth-2.4.18-mh11 2001-12-21 18:42:04.000000000 +0100
-+++ linux/include/pcmcia/ciscode.h 2004-01-25 23:37:39.000000000 +0100
-@@ -1,5 +1,5 @@
- /*
-- * ciscode.h 1.48 2001/08/24 12:16:12
-+ * ciscode.h 1.57 2002/11/03 20:38:14
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
-@@ -60,6 +60,10 @@
- #define PRODID_INTEL_DUAL_RS232 0x0301
- #define PRODID_INTEL_2PLUS 0x8422
-
-+#define MANFID_KME 0x0032
-+#define PRODID_KME_KXLC005_A 0x0704
-+#define PRODID_KME_KXLC005_B 0x2904
-+
- #define MANFID_LINKSYS 0x0143
- #define PRODID_LINKSYS_PCMLM28 0xc0ab
- #define PRODID_LINKSYS_3400 0x3341
-@@ -94,6 +98,8 @@
- #define PRODID_OSITECH_JACK_336 0x0007
- #define PRODID_OSITECH_SEVEN 0x0008
-
-+#define MANFID_OXSEMI 0x0279
-+
- #define MANFID_PIONEER 0x000b
-
- #define MANFID_PSION 0x016c
-@@ -103,6 +109,7 @@
- #define PRODID_QUATECH_SPP100 0x0003
- #define PRODID_QUATECH_DUAL_RS232 0x0012
- #define PRODID_QUATECH_DUAL_RS232_D1 0x0007
-+#define PRODID_QUATECH_DUAL_RS232_D2 0x0052
- #define PRODID_QUATECH_QUAD_RS232 0x001b
- #define PRODID_QUATECH_DUAL_RS422 0x000e
- #define PRODID_QUATECH_QUAD_RS422 0x0045
-@@ -120,9 +127,12 @@
-
- #define MANFID_TDK 0x0105
- #define PRODID_TDK_CF010 0x0900
-+#define PRODID_TDK_GN3410 0x4815
-
- #define MANFID_TOSHIBA 0x0098
-
-+#define MANFID_UNGERMANN 0x02c0
-+
- #define MANFID_XIRCOM 0x0105
-
- #endif /* _LINUX_CISCODE_H */
---- linux/kernel/ksyms.c~bluetooth-2.4.18-mh11 2004-01-25 23:28:30.000000000 +0100
-+++ linux/kernel/ksyms.c 2004-01-25 23:37:39.000000000 +0100
-@@ -47,6 +47,7 @@
- #include <linux/in6.h>
- #include <linux/completion.h>
- #include <linux/seq_file.h>
-+#include <linux/firmware.h>
- #include <asm/checksum.h>
-
- #if defined(CONFIG_PROC_FS)
-@@ -543,6 +544,13 @@
- EXPORT_SYMBOL(strspn);
- EXPORT_SYMBOL(strsep);
-
-+#ifdef CONFIG_FW_LOADER
-+EXPORT_SYMBOL(release_firmware);
-+EXPORT_SYMBOL(request_firmware);
-+EXPORT_SYMBOL(request_firmware_nowait);
-+EXPORT_SYMBOL(register_firmware);
-+#endif
-+
- /* software interrupts */
- EXPORT_SYMBOL(tasklet_hi_vec);
- EXPORT_SYMBOL(tasklet_vec);
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/lib/Config.in 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,12 @@
-+#
-+# Library configuration
-+#
-+mainmenu_option next_comment
-+comment 'Library routines'
-+
-+if [ "$CONFIG_EXPERIMENTAL" = "y" -a \
-+ "$CONFIG_HOTPLUG" = "y" ]; then
-+ tristate 'Hotplug firmware loading support (EXPERIMENTAL)' CONFIG_FW_LOADER
-+fi
-+
-+endmenu
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/lib/firmware_class.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,573 @@
-+/*
-+ * firmware_class.c - Multi purpose firmware loading support
-+ *
-+ * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
-+ *
-+ * Please see Documentation/firmware_class/ for more information.
-+ *
-+ */
-+/*
-+ * Based on kernel/kmod.c and drivers/usb/usb.c
-+ */
-+/*
-+ kernel/kmod.c
-+ Kirk Petersen
-+
-+ Reorganized not to be a daemon by Adam Richter, with guidance
-+ from Greg Zornetzer.
-+
-+ Modified to avoid chroot and file sharing problems.
-+ Mikael Pettersson
-+
-+ Limit the concurrent number of kmod modprobes to catch loops from
-+ "modprobe needs a service that is in a module".
-+ Keith Owens <kaos@ocs.com.au> December 1999
-+
-+ Unblock all signals when we exec a usermode process.
-+ Shuu Yamaguchi <shuu@wondernetworkresources.com> December 2000
-+*/
-+/*
-+ * drivers/usb/usb.c
-+ *
-+ * (C) Copyright Linus Torvalds 1999
-+ * (C) Copyright Johannes Erdfelt 1999-2001
-+ * (C) Copyright Andreas Gal 1999
-+ * (C) Copyright Gregory P. Smith 1999
-+ * (C) Copyright Deti Fliegl 1999 (new USB architecture)
-+ * (C) Copyright Randy Dunlap 2000
-+ * (C) Copyright David Brownell 2000 (kernel hotplug, usb_device_id)
-+ * (C) Copyright Yggdrasil Computing, Inc. 2000
-+ * (usb_device_id matching changes by Adam J. Richter)
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/types.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/kmod.h>
-+#include <linux/proc_fs.h>
-+#include <linux/vmalloc.h>
-+#include <asm/hardirq.h>
-+
-+#include "linux/firmware.h"
-+
-+MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>");
-+MODULE_DESCRIPTION("Multi purpose firmware loading support");
-+MODULE_LICENSE("GPL");
-+
-+#define err(format, arg...) \
-+ printk(KERN_ERR "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
-+#define warn(format, arg...) \
-+ printk(KERN_WARNING "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
-+#define dbg(format, arg...) \
-+ printk(KERN_DEBUG "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
-+
-+static int loading_timeout = 10; /* In seconds */
-+static struct proc_dir_entry *proc_dir_timeout;
-+static struct proc_dir_entry *proc_dir;
-+
-+#ifdef CONFIG_HOTPLUG
-+
-+static int
-+call_helper(char *verb, const char *name, const char *device)
-+{
-+ char *argv[3], **envp, *buf, *scratch;
-+ int i = 0;
-+
-+ int retval = 0;
-+
-+ if (!hotplug_path[0])
-+ return -ENOENT;
-+ if (in_interrupt()) {
-+ err("in_interrupt");
-+ return -EFAULT;
-+ }
-+ if (!current->fs->root) {
-+ warn("call_policy %s -- no FS yet", verb);
-+ return -EPERM;
-+ }
-+
-+ if (!(envp = (char **) kmalloc(20 * sizeof (char *), GFP_KERNEL))) {
-+ err("unable to allocate envp");
-+ return -ENOMEM;
-+ }
-+ if (!(buf = kmalloc(256, GFP_KERNEL))) {
-+ kfree(envp);
-+ err("unable to allocate buf");
-+ return -ENOMEM;
-+ }
-+
-+ /* only one standardized param to hotplug command: type */
-+ argv[0] = hotplug_path;
-+ argv[1] = "firmware";
-+ argv[2] = 0;
-+
-+ /* minimal command environment */
-+ envp[i++] = "HOME=/";
-+ envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-+
-+#ifdef DEBUG
-+ /* hint that policy agent should enter no-stdout debug mode */
-+ envp[i++] = "DEBUG=kernel";
-+#endif
-+ scratch = buf;
-+
-+ if (device) {
-+ envp[i++] = scratch;
-+ scratch += snprintf(scratch, FIRMWARE_NAME_MAX+25,
-+ "DEVPATH=/driver/firmware/%s", device) + 1;
-+ }
-+
-+ envp[i++] = scratch;
-+ scratch += sprintf(scratch, "ACTION=%s", verb) + 1;
-+
-+ envp[i++] = scratch;
-+ scratch += snprintf(scratch, FIRMWARE_NAME_MAX,
-+ "FIRMWARE=%s", name) + 1;
-+
-+ envp[i++] = 0;
-+
-+#ifdef DEBUG
-+ dbg("firmware: %s %s %s", argv[0], argv[1], verb);
-+#endif
-+
-+ retval = call_usermodehelper(argv[0], argv, envp);
-+ if (retval) {
-+ printk("call_usermodehelper return %d\n", retval);
-+ }
-+
-+ kfree(buf);
-+ kfree(envp);
-+ return retval;
-+}
-+#else
-+
-+static inline int
-+call_helper(char *verb, const char *name, const char *device)
-+{
-+ return -ENOENT;
-+}
-+
-+#endif /* CONFIG_HOTPLUG */
-+
-+struct firmware_priv {
-+ struct completion completion;
-+ struct proc_dir_entry *proc_dir;
-+ struct proc_dir_entry *attr_data;
-+ struct proc_dir_entry *attr_loading;
-+ struct firmware *fw;
-+ int loading;
-+ int abort;
-+ int alloc_size;
-+ struct timer_list timeout;
-+};
-+
-+static int
-+firmware_timeout_show(char *buf, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ return sprintf(buf, "%d\n", loading_timeout);
-+}
-+
-+/**
-+ * firmware_timeout_store:
-+ * Description:
-+ * Sets the number of seconds to wait for the firmware. Once
-+ * this expires an error will be return to the driver and no
-+ * firmware will be provided.
-+ *
-+ * Note: zero means 'wait for ever'
-+ *
-+ **/
-+static int
-+firmware_timeout_store(struct file *file, const char *buf,
-+ unsigned long count, void *data)
-+{
-+ loading_timeout = simple_strtol(buf, NULL, 10);
-+ return count;
-+}
-+
-+static int
-+firmware_loading_show(char *buf, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ struct firmware_priv *fw_priv = data;
-+ return sprintf(buf, "%d\n", fw_priv->loading);
-+}
-+
-+/**
-+ * firmware_loading_store: - loading control file
-+ * Description:
-+ * The relevant values are:
-+ *
-+ * 1: Start a load, discarding any previous partial load.
-+ * 0: Conclude the load and handle the data to the driver code.
-+ * -1: Conclude the load with an error and discard any written data.
-+ **/
-+static int
-+firmware_loading_store(struct file *file, const char *buf,
-+ unsigned long count, void *data)
-+{
-+ struct firmware_priv *fw_priv = data;
-+ int prev_loading = fw_priv->loading;
-+
-+ fw_priv->loading = simple_strtol(buf, NULL, 10);
-+
-+ switch (fw_priv->loading) {
-+ case -1:
-+ fw_priv->abort = 1;
-+ wmb();
-+ complete(&fw_priv->completion);
-+ break;
-+ case 1:
-+ kfree(fw_priv->fw->data);
-+ fw_priv->fw->data = NULL;
-+ fw_priv->fw->size = 0;
-+ fw_priv->alloc_size = 0;
-+ break;
-+ case 0:
-+ if (prev_loading == 1)
-+ complete(&fw_priv->completion);
-+ break;
-+ }
-+
-+ return count;
-+}
-+
-+static int
-+firmware_data_read(char *buffer, char **start, off_t offset,
-+ int count, int *eof, void *data)
-+{
-+ struct firmware_priv *fw_priv = data;
-+ struct firmware *fw = fw_priv->fw;
-+
-+ if (offset > fw->size)
-+ return 0;
-+ if (offset + count > fw->size)
-+ count = fw->size - offset;
-+
-+ memcpy(buffer, fw->data + offset, count);
-+ *start = (void *) ((long) count);
-+ return count;
-+}
-+static int
-+fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
-+{
-+ u8 *new_data;
-+ int new_size;
-+
-+ if (min_size <= fw_priv->alloc_size)
-+ return 0;
-+ if((min_size % PAGE_SIZE) == 0)
-+ new_size = min_size;
-+ else
-+ new_size = (min_size + PAGE_SIZE) & PAGE_MASK;
-+ new_data = vmalloc(new_size);
-+ if (!new_data) {
-+ printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__);
-+ /* Make sure that we don't keep incomplete data */
-+ fw_priv->abort = 1;
-+ return -ENOMEM;
-+ }
-+ fw_priv->alloc_size = new_size;
-+ if (fw_priv->fw->data) {
-+ memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size);
-+ vfree(fw_priv->fw->data);
-+ }
-+ fw_priv->fw->data = new_data;
-+ BUG_ON(min_size > fw_priv->alloc_size);
-+ return 0;
-+}
-+
-+/**
-+ * firmware_data_write:
-+ *
-+ * Description:
-+ *
-+ * Data written to the 'data' attribute will be later handled to
-+ * the driver as a firmware image.
-+ **/
-+static int
-+firmware_data_write(struct file *file, const char *buffer,
-+ unsigned long count, void *data)
-+{
-+ struct firmware_priv *fw_priv = data;
-+ struct firmware *fw = fw_priv->fw;
-+ int offset = file->f_pos;
-+ int retval;
-+
-+ retval = fw_realloc_buffer(fw_priv, offset + count);
-+ if (retval) {
-+ printk("%s: retval:%d\n", __FUNCTION__, retval);
-+ return retval;
-+ }
-+
-+ memcpy(fw->data + offset, buffer, count);
-+
-+ fw->size = max_t(size_t, offset + count, fw->size);
-+ file->f_pos += count;
-+ return count;
-+}
-+
-+static void
-+firmware_class_timeout(u_long data)
-+{
-+ struct firmware_priv *fw_priv = (struct firmware_priv *) data;
-+ fw_priv->abort = 1;
-+ wmb();
-+ complete(&fw_priv->completion);
-+}
-+static int
-+fw_setup_class_device(struct firmware_priv **fw_priv_p,
-+ const char *fw_name, const char *device)
-+{
-+ int retval;
-+ struct firmware_priv *fw_priv = kmalloc(sizeof (struct firmware_priv),
-+ GFP_KERNEL);
-+ *fw_priv_p = fw_priv;
-+ if (!fw_priv) {
-+ retval = -ENOMEM;
-+ goto out;
-+ }
-+ memset(fw_priv, 0, sizeof (*fw_priv));
-+
-+ init_completion(&fw_priv->completion);
-+
-+ fw_priv->timeout.function = firmware_class_timeout;
-+ fw_priv->timeout.data = (u_long) fw_priv;
-+ init_timer(&fw_priv->timeout);
-+
-+ retval = -EAGAIN;
-+ fw_priv->proc_dir = create_proc_entry(device, 0644 | S_IFDIR, proc_dir);
-+ if (!fw_priv->proc_dir)
-+ goto err_free_fw_priv;
-+
-+ fw_priv->attr_data = create_proc_entry("data", 0644 | S_IFREG,
-+ fw_priv->proc_dir);
-+ if (!fw_priv->attr_data)
-+ goto err_remove_dir;
-+
-+ fw_priv->attr_data->read_proc = firmware_data_read;
-+ fw_priv->attr_data->write_proc = firmware_data_write;
-+ fw_priv->attr_data->data = fw_priv;
-+
-+ fw_priv->attr_loading = create_proc_entry("loading", 0644 | S_IFREG,
-+ fw_priv->proc_dir);
-+ if (!fw_priv->attr_loading)
-+ goto err_remove_data;
-+
-+ fw_priv->attr_loading->read_proc = firmware_loading_show;
-+ fw_priv->attr_loading->write_proc = firmware_loading_store;
-+ fw_priv->attr_loading->data = fw_priv;
-+
-+ retval = 0;
-+ fw_priv->fw = kmalloc(sizeof (struct firmware), GFP_KERNEL);
-+ if (!fw_priv->fw) {
-+ printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n",
-+ __FUNCTION__);
-+ retval = -ENOMEM;
-+ goto err_remove_loading;
-+ }
-+ memset(fw_priv->fw, 0, sizeof (*fw_priv->fw));
-+
-+ goto out;
-+
-+err_remove_loading:
-+ remove_proc_entry("loading", fw_priv->proc_dir);
-+err_remove_data:
-+ remove_proc_entry("data", fw_priv->proc_dir);
-+err_remove_dir:
-+ remove_proc_entry(device, proc_dir);
-+err_free_fw_priv:
-+ kfree(fw_priv);
-+out:
-+ return retval;
-+}
-+static void
-+fw_remove_class_device(struct firmware_priv *fw_priv)
-+{
-+ remove_proc_entry("loading", fw_priv->proc_dir);
-+ remove_proc_entry("data", fw_priv->proc_dir);
-+ remove_proc_entry(fw_priv->proc_dir->name, proc_dir);
-+}
-+
-+/**
-+ * request_firmware: - request firmware to hotplug and wait for it
-+ * Description:
-+ * @firmware will be used to return a firmware image by the name
-+ * of @name for device @device.
-+ *
-+ * Should be called from user context where sleeping is allowed.
-+ *
-+ * @name will be use as $FIRMWARE in the hotplug environment and
-+ * should be distinctive enough not to be confused with any other
-+ * firmware image for this or any other device.
-+ **/
-+int
-+request_firmware(const struct firmware **firmware, const char *name,
-+ const char *device)
-+{
-+ struct firmware_priv *fw_priv;
-+ int retval;
-+
-+ if (!firmware) {
-+ retval = -EINVAL;
-+ goto out;
-+ }
-+ *firmware = NULL;
-+
-+ retval = fw_setup_class_device(&fw_priv, name, device);
-+ if (retval)
-+ goto out;
-+
-+ retval = call_helper("add", name, device);
-+ if (retval)
-+ goto out;
-+ if (loading_timeout) {
-+ fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
-+ add_timer(&fw_priv->timeout);
-+ }
-+
-+ wait_for_completion(&fw_priv->completion);
-+
-+ del_timer(&fw_priv->timeout);
-+ fw_remove_class_device(fw_priv);
-+
-+ if (fw_priv->fw->size && !fw_priv->abort) {
-+ *firmware = fw_priv->fw;
-+ } else {
-+ retval = -ENOENT;
-+ vfree(fw_priv->fw->data);
-+ kfree(fw_priv->fw);
-+ }
-+out:
-+ kfree(fw_priv);
-+ return retval;
-+}
-+
-+void
-+release_firmware(const struct firmware *fw)
-+{
-+ if (fw) {
-+ vfree(fw->data);
-+ kfree(fw);
-+ }
-+}
-+
-+/**
-+ * register_firmware: - provide a firmware image for later usage
-+ *
-+ * Description:
-+ * Make sure that @data will be available by requesting firmware @name.
-+ *
-+ * Note: This will not be possible until some kind of persistence
-+ * is available.
-+ **/
-+void
-+register_firmware(const char *name, const u8 *data, size_t size)
-+{
-+ /* This is meaningless without firmware caching, so until we
-+ * decide if firmware caching is reasonable just leave it as a
-+ * noop */
-+}
-+
-+/* Async support */
-+struct firmware_work {
-+ struct tq_struct work;
-+ struct module *module;
-+ const char *name;
-+ const char *device;
-+ void *context;
-+ void (*cont)(const struct firmware *fw, void *context);
-+};
-+
-+static void
-+request_firmware_work_func(void *arg)
-+{
-+ struct firmware_work *fw_work = arg;
-+ const struct firmware *fw;
-+ if (!arg)
-+ return;
-+ request_firmware(&fw, fw_work->name, fw_work->device);
-+ fw_work->cont(fw, fw_work->context);
-+ release_firmware(fw);
-+ __MOD_DEC_USE_COUNT(fw_work->module);
-+ kfree(fw_work);
-+}
-+
-+/**
-+ * request_firmware_nowait:
-+ *
-+ * Description:
-+ * Asynchronous variant of request_firmware() for contexts where
-+ * it is not possible to sleep.
-+ *
-+ * @cont will be called asynchronously when the firmware request is over.
-+ *
-+ * @context will be passed over to @cont.
-+ *
-+ * @fw may be %NULL if firmware request fails.
-+ *
-+ **/
-+int
-+request_firmware_nowait(
-+ struct module *module,
-+ const char *name, const char *device, void *context,
-+ void (*cont)(const struct firmware *fw, void *context))
-+{
-+ struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
-+ GFP_ATOMIC);
-+ if (!fw_work)
-+ return -ENOMEM;
-+ if (!try_inc_mod_count(module)) {
-+ kfree(fw_work);
-+ return -EFAULT;
-+ }
-+
-+ *fw_work = (struct firmware_work) {
-+ .module = module,
-+ .name = name,
-+ .device = device,
-+ .context = context,
-+ .cont = cont,
-+ };
-+ INIT_TQUEUE(&fw_work->work, request_firmware_work_func, fw_work);
-+
-+ schedule_task(&fw_work->work);
-+ return 0;
-+}
-+
-+static int __init
-+firmware_class_init(void)
-+{
-+ proc_dir = create_proc_entry("driver/firmware", 0755 | S_IFDIR, NULL);
-+ if (!proc_dir)
-+ return -EAGAIN;
-+ proc_dir_timeout = create_proc_entry("timeout",
-+ 0644 | S_IFREG, proc_dir);
-+ if (!proc_dir_timeout) {
-+ remove_proc_entry("driver/firmware", NULL);
-+ return -EAGAIN;
-+ }
-+ proc_dir_timeout->read_proc = firmware_timeout_show;
-+ proc_dir_timeout->write_proc = firmware_timeout_store;
-+ return 0;
-+}
-+static void __exit
-+firmware_class_exit(void)
-+{
-+ remove_proc_entry("timeout", proc_dir);
-+ remove_proc_entry("driver/firmware", NULL);
-+}
-+
-+module_init(firmware_class_init);
-+module_exit(firmware_class_exit);
-+
-+#ifndef CONFIG_FW_LOADER
-+EXPORT_SYMBOL(release_firmware);
-+EXPORT_SYMBOL(request_firmware);
-+EXPORT_SYMBOL(request_firmware_nowait);
-+EXPORT_SYMBOL(register_firmware);
-+#endif
---- linux/lib/Makefile~bluetooth-2.4.18-mh11 2001-09-18 00:31:15.000000000 +0200
-+++ linux/lib/Makefile 2004-01-25 23:37:39.000000000 +0100
-@@ -8,13 +8,17 @@
-
- L_TARGET := lib.a
-
--export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o
-+export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o \
-+ firmware_class.o
-
- obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o bust_spinlocks.o rbtree.o
-
-+obj-$(CONFIG_FW_LOADER) += firmware_class.o
- obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
- obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
-
-+include $(TOPDIR)/drivers/bluetooth/Makefile.lib
-+
- ifneq ($(CONFIG_HAVE_DEC_LOCK),y)
- obj-y += dec_and_lock.o
- endif
---- linux/MAINTAINERS~bluetooth-2.4.18-mh11 2004-01-25 23:28:29.000000000 +0100
-+++ linux/MAINTAINERS 2004-01-25 23:37:39.000000000 +0100
-@@ -259,7 +259,84 @@
- L: linux-kernel@vger.kernel.org
- S: Maintained
-
--BLUETOOTH SUBSYSTEM (BlueZ)
-+BLUETOOTH SUBSYSTEM
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+L: bluez-devel@lists.sf.net
-+W: http://bluez.sf.net
-+S: Maintained
-+
-+BLUETOOTH RFCOMM LAYER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+W: http://bluez.sf.net
-+S: Maintained
-+
-+BLUETOOTH BNEP LAYER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+W: http://bluez.sf.net
-+S: Maintained
-+
-+BLUETOOTH CMTP LAYER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+W: http://www.holtmann.org/linux/bluetooth/
-+S: Maintained
-+
-+BLUETOOTH HCI USB DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+W: http://bluez.sf.net
-+S: Maintained
-+
-+BLUETOOTH HCI UART DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+W: http://bluez.sf.net
-+S: Maintained
-+
-+BLUETOOTH HCI BFUSB DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+W: http://www.holtmann.org/linux/bluetooth/
-+S: Maintained
-+
-+BLUETOOTH HCI DTL1 DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+W: http://www.holtmann.org/linux/bluetooth/
-+S: Maintained
-+
-+BLUETOOTH HCI BLUECARD DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+W: http://www.holtmann.org/linux/bluetooth/
-+S: Maintained
-+
-+BLUETOOTH HCI BT3C DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+W: http://www.holtmann.org/linux/bluetooth/
-+S: Maintained
-+
-+BLUETOOTH HCI BTUART DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+W: http://www.holtmann.org/linux/bluetooth/
-+S: Maintained
-+
-+BLUETOOTH HCI VHCI DRIVER
- P: Maxim Krasnyansky
- M: maxk@qualcomm.com
- W: http://bluez.sf.net
---- linux/net/bluetooth/af_bluetooth.c~bluetooth-2.4.18-mh11 2001-09-07 18:28:38.000000000 +0200
-+++ linux/net/bluetooth/af_bluetooth.c 2004-01-25 23:37:39.000000000 +0100
-@@ -25,14 +25,15 @@
- /*
- * BlueZ Bluetooth address family and sockets.
- *
-- * $Id$
-+ * $Id$
- */
--#define VERSION "1.1"
-+#define VERSION "2.3"
-
- #include <linux/config.h>
- #include <linux/module.h>
-
- #include <linux/types.h>
-+#include <linux/list.h>
- #include <linux/errno.h>
- #include <linux/kernel.h>
- #include <linux/major.h>
-@@ -40,6 +41,7 @@
- #include <linux/slab.h>
- #include <linux/skbuff.h>
- #include <linux/init.h>
-+#include <linux/poll.h>
- #include <linux/proc_fs.h>
- #include <net/sock.h>
-
-@@ -48,70 +50,79 @@
- #endif
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
-+
-+#ifndef AF_BLUETOOTH_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-
- /* Bluetooth sockets */
--static struct net_proto_family *bluez_sock[BLUEZ_MAX_PROTO];
-+#define BLUEZ_MAX_PROTO 6
-+static struct net_proto_family *bluez_proto[BLUEZ_MAX_PROTO];
-
- int bluez_sock_register(int proto, struct net_proto_family *ops)
- {
-- if (proto > BLUEZ_MAX_PROTO)
-+ if (proto >= BLUEZ_MAX_PROTO)
- return -EINVAL;
-
-- if (bluez_sock[proto])
-+ if (bluez_proto[proto])
- return -EEXIST;
-
-- bluez_sock[proto] = ops;
-+ bluez_proto[proto] = ops;
- return 0;
- }
-
- int bluez_sock_unregister(int proto)
- {
-- if (proto > BLUEZ_MAX_PROTO)
-+ if (proto >= BLUEZ_MAX_PROTO)
- return -EINVAL;
-
-- if (!bluez_sock[proto])
-+ if (!bluez_proto[proto])
- return -ENOENT;
-
-- bluez_sock[proto] = NULL;
-+ bluez_proto[proto] = NULL;
- return 0;
- }
-
- static int bluez_sock_create(struct socket *sock, int proto)
- {
-- if (proto > BLUEZ_MAX_PROTO)
-+ if (proto >= BLUEZ_MAX_PROTO)
- return -EINVAL;
-
- #if defined(CONFIG_KMOD)
-- if (!bluez_sock[proto]) {
-+ if (!bluez_proto[proto]) {
- char module_name[30];
- sprintf(module_name, "bt-proto-%d", proto);
- request_module(module_name);
- }
- #endif
-
-- if (!bluez_sock[proto])
-+ if (!bluez_proto[proto])
- return -ENOENT;
-
-- return bluez_sock[proto]->create(sock, proto);
-+ return bluez_proto[proto]->create(sock, proto);
-+}
-+
-+void bluez_sock_init(struct socket *sock, struct sock *sk)
-+{
-+ sock_init_data(sock, sk);
-+ INIT_LIST_HEAD(&bluez_pi(sk)->accept_q);
- }
-
- void bluez_sock_link(struct bluez_sock_list *l, struct sock *sk)
- {
-- write_lock(&l->lock);
--
-+ write_lock_bh(&l->lock);
- sk->next = l->head;
- l->head = sk;
- sock_hold(sk);
--
-- write_unlock(&l->lock);
-+ write_unlock_bh(&l->lock);
- }
-
- void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *sk)
- {
- struct sock **skp;
-
-- write_lock(&l->lock);
-+ write_lock_bh(&l->lock);
- for (skp = &l->head; *skp; skp = &((*skp)->next)) {
- if (*skp == sk) {
- *skp = sk->next;
-@@ -119,7 +130,162 @@
- break;
- }
- }
-- write_unlock(&l->lock);
-+ write_unlock_bh(&l->lock);
-+}
-+
-+void bluez_accept_enqueue(struct sock *parent, struct sock *sk)
-+{
-+ BT_DBG("parent %p, sk %p", parent, sk);
-+
-+ sock_hold(sk);
-+ list_add_tail(&bluez_pi(sk)->accept_q, &bluez_pi(parent)->accept_q);
-+ bluez_pi(sk)->parent = parent;
-+ parent->ack_backlog++;
-+}
-+
-+static void bluez_accept_unlink(struct sock *sk)
-+{
-+ BT_DBG("sk %p state %d", sk, sk->state);
-+
-+ list_del_init(&bluez_pi(sk)->accept_q);
-+ bluez_pi(sk)->parent->ack_backlog--;
-+ bluez_pi(sk)->parent = NULL;
-+ sock_put(sk);
-+}
-+
-+struct sock *bluez_accept_dequeue(struct sock *parent, struct socket *newsock)
-+{
-+ struct list_head *p, *n;
-+ struct bluez_pinfo *pi;
-+ struct sock *sk;
-+
-+ BT_DBG("parent %p", parent);
-+
-+ list_for_each_safe(p, n, &bluez_pi(parent)->accept_q) {
-+ pi = list_entry(p, struct bluez_pinfo, accept_q);
-+ sk = bluez_sk(pi);
-+
-+ lock_sock(sk);
-+ if (sk->state == BT_CLOSED) {
-+ release_sock(sk);
-+ bluez_accept_unlink(sk);
-+ continue;
-+ }
-+
-+ if (sk->state == BT_CONNECTED || !newsock) {
-+ bluez_accept_unlink(sk);
-+ if (newsock)
-+ sock_graft(sk, newsock);
-+ release_sock(sk);
-+ return sk;
-+ }
-+ release_sock(sk);
-+ }
-+ return NULL;
-+}
-+
-+int bluez_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
-+{
-+ int noblock = flags & MSG_DONTWAIT;
-+ struct sock *sk = sock->sk;
-+ struct sk_buff *skb;
-+ int copied, err;
-+
-+ BT_DBG("sock %p sk %p len %d", sock, sk, len);
-+
-+ if (flags & (MSG_OOB))
-+ return -EOPNOTSUPP;
-+
-+ if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) {
-+ if (sk->shutdown & RCV_SHUTDOWN)
-+ return 0;
-+ return err;
-+ }
-+
-+ msg->msg_namelen = 0;
-+
-+ copied = skb->len;
-+ if (len < copied) {
-+ msg->msg_flags |= MSG_TRUNC;
-+ copied = len;
-+ }
-+
-+ skb->h.raw = skb->data;
-+ err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
-+
-+ skb_free_datagram(sk, skb);
-+
-+ return err ? : copied;
-+}
-+
-+unsigned int bluez_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
-+{
-+ struct sock *sk = sock->sk;
-+ unsigned int mask;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ poll_wait(file, sk->sleep, wait);
-+ mask = 0;
-+
-+ if (sk->err || !skb_queue_empty(&sk->error_queue))
-+ mask |= POLLERR;
-+
-+ if (sk->shutdown == SHUTDOWN_MASK)
-+ mask |= POLLHUP;
-+
-+ if (!skb_queue_empty(&sk->receive_queue) ||
-+ !list_empty(&bluez_pi(sk)->accept_q) ||
-+ (sk->shutdown & RCV_SHUTDOWN))
-+ mask |= POLLIN | POLLRDNORM;
-+
-+ if (sk->state == BT_CLOSED)
-+ mask |= POLLHUP;
-+
-+ if (sk->state == BT_CONNECT || sk->state == BT_CONNECT2)
-+ return mask;
-+
-+ if (sock_writeable(sk))
-+ mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
-+ else
-+ set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
-+
-+ return mask;
-+}
-+
-+int bluez_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ int err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ add_wait_queue(sk->sleep, &wait);
-+ while (sk->state != state) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+
-+ if (sk->err) {
-+ err = sock_error(sk);
-+ break;
-+ }
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+ return err;
- }
-
- struct net_proto_family bluez_sock_family_ops =
-@@ -129,9 +295,9 @@
-
- int bluez_init(void)
- {
-- INF("BlueZ HCI Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-+ BT_INFO("BlueZ Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-
- proc_mkdir("bluetooth", NULL);
-
-@@ -164,5 +330,6 @@
- module_exit(bluez_cleanup);
-
- MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
--MODULE_DESCRIPTION("BlueZ HCI Core ver " VERSION);
-+MODULE_DESCRIPTION("BlueZ Core ver " VERSION);
-+MODULE_LICENSE("GPL");
- #endif
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/bnep/bnep.h 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,185 @@
-+/*
-+ BNEP protocol definition for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License, version 2, as
-+ published by the Free Software Foundation.
-+
-+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef _BNEP_H
-+#define _BNEP_H
-+
-+#include <linux/types.h>
-+#include <net/bluetooth/bluetooth.h>
-+
-+#include "crc32.h"
-+
-+// Limits
-+#define BNEP_MAX_PROTO_FILTERS 5
-+#define BNEP_MAX_MULTICAST_FILTERS 20
-+
-+// UUIDs
-+#define BNEP_BASE_UUID 0x0000000000001000800000805F9B34FB
-+#define BNEP_UUID16 0x02
-+#define BNEP_UUID32 0x04
-+#define BNEP_UUID128 0x16
-+
-+#define BNEP_SVC_PANU 0x1115
-+#define BNEP_SVC_NAP 0x1116
-+#define BNEP_SVC_GN 0x1117
-+
-+// Packet types
-+#define BNEP_GENERAL 0x00
-+#define BNEP_CONTROL 0x01
-+#define BNEP_COMPRESSED 0x02
-+#define BNEP_COMPRESSED_SRC_ONLY 0x03
-+#define BNEP_COMPRESSED_DST_ONLY 0x04
-+
-+// Control types
-+#define BNEP_CMD_NOT_UNDERSTOOD 0x00
-+#define BNEP_SETUP_CONN_REQ 0x01
-+#define BNEP_SETUP_CONN_RSP 0x02
-+#define BNEP_FILTER_NET_TYPE_SET 0x03
-+#define BNEP_FILTER_NET_TYPE_RSP 0x04
-+#define BNEP_FILTER_MULTI_ADDR_SET 0x05
-+#define BNEP_FILTER_MULTI_ADDR_RSP 0x06
-+
-+// Extension types
-+#define BNEP_EXT_CONTROL 0x00
-+
-+// Response messages
-+#define BNEP_SUCCESS 0x00
-+
-+#define BNEP_CONN_INVALID_DST 0x01
-+#define BNEP_CONN_INVALID_SRC 0x02
-+#define BNEP_CONN_INVALID_SVC 0x03
-+#define BNEP_CONN_NOT_ALLOWED 0x04
-+
-+#define BNEP_FILTER_UNSUPPORTED_REQ 0x01
-+#define BNEP_FILTER_INVALID_RANGE 0x02
-+#define BNEP_FILTER_INVALID_MCADDR 0x02
-+#define BNEP_FILTER_LIMIT_REACHED 0x03
-+#define BNEP_FILTER_DENIED_SECURITY 0x04
-+
-+// L2CAP settings
-+#define BNEP_MTU 1691
-+#define BNEP_PSM 0x0f
-+#define BNEP_FLUSH_TO 0xffff
-+#define BNEP_CONNECT_TO 15
-+#define BNEP_FILTER_TO 15
-+
-+// Headers
-+#define BNEP_TYPE_MASK 0x7f
-+#define BNEP_EXT_HEADER 0x80
-+
-+struct bnep_setup_conn_req {
-+ __u8 type;
-+ __u8 ctrl;
-+ __u8 uuid_size;
-+ __u8 service[0];
-+} __attribute__((packed));
-+
-+struct bnep_set_filter_req {
-+ __u8 type;
-+ __u8 ctrl;
-+ __u16 len;
-+ __u8 list[0];
-+} __attribute__((packed));
-+
-+struct bnep_control_rsp {
-+ __u8 type;
-+ __u8 ctrl;
-+ __u16 resp;
-+} __attribute__((packed));
-+
-+struct bnep_ext_hdr {
-+ __u8 type;
-+ __u8 len;
-+ __u8 data[0];
-+} __attribute__((packed));
-+
-+/* BNEP ioctl defines */
-+#define BNEPCONNADD _IOW('B', 200, int)
-+#define BNEPCONNDEL _IOW('B', 201, int)
-+#define BNEPGETCONNLIST _IOR('B', 210, int)
-+#define BNEPGETCONNINFO _IOR('B', 211, int)
-+
-+struct bnep_connadd_req {
-+ int sock; // Connected socket
-+ __u32 flags;
-+ __u16 role;
-+ char device[16]; // Name of the Ethernet device
-+};
-+
-+struct bnep_conndel_req {
-+ __u32 flags;
-+ __u8 dst[ETH_ALEN];
-+};
-+
-+struct bnep_conninfo {
-+ __u32 flags;
-+ __u16 role;
-+ __u16 state;
-+ __u8 dst[ETH_ALEN];
-+ char device[16];
-+};
-+
-+struct bnep_connlist_req {
-+ __u32 cnum;
-+ struct bnep_conninfo *ci;
-+};
-+
-+struct bnep_proto_filter {
-+ __u16 start;
-+ __u16 end;
-+};
-+
-+int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock);
-+int bnep_del_connection(struct bnep_conndel_req *req);
-+int bnep_get_connlist(struct bnep_connlist_req *req);
-+int bnep_get_conninfo(struct bnep_conninfo *ci);
-+
-+// BNEP sessions
-+struct bnep_session {
-+ struct list_head list;
-+
-+ unsigned int role;
-+ unsigned long state;
-+ unsigned long flags;
-+ atomic_t killed;
-+
-+ struct ethhdr eh;
-+ struct msghdr msg;
-+
-+ struct bnep_proto_filter proto_filter[BNEP_MAX_PROTO_FILTERS];
-+ u64 mc_filter;
-+
-+ struct socket *sock;
-+ struct net_device dev;
-+ struct net_device_stats stats;
-+};
-+
-+int bnep_net_init(struct net_device *dev);
-+int bnep_sock_init(void);
-+int bnep_sock_cleanup(void);
-+
-+static inline int bnep_mc_hash(__u8 *addr)
-+{
-+ return (bnep_crc32(~0, addr, ETH_ALEN) >> 26);
-+}
-+
-+#endif
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/bnep/Config.in 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,11 @@
-+#
-+# Bluetooth BNEP layer configuration
-+#
-+
-+dep_tristate 'BNEP protocol support' CONFIG_BLUEZ_BNEP $CONFIG_BLUEZ_L2CAP
-+
-+if [ "$CONFIG_BLUEZ_BNEP" != "n" ]; then
-+ bool ' Multicast filter support' CONFIG_BLUEZ_BNEP_MC_FILTER
-+ bool ' Protocol filter support' CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+fi
-+
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/bnep/core.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,708 @@
-+/*
-+ BNEP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2001-2002 Inventel Systemes
-+ Written 2001-2002 by
-+ Clément Moreau <clement.moreau@inventel.fr>
-+ David Libault <david.libault@inventel.fr>
-+
-+ Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#define __KERNEL_SYSCALLS__
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/signal.h>
-+#include <linux/init.h>
-+#include <linux/wait.h>
-+#include <linux/errno.h>
-+#include <linux/smp_lock.h>
-+#include <linux/net.h>
-+#include <net/sock.h>
-+
-+#include <linux/socket.h>
-+#include <linux/file.h>
-+
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#include "bnep.h"
-+
-+#ifndef CONFIG_BLUEZ_BNEP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define VERSION "1.1"
-+
-+static LIST_HEAD(bnep_session_list);
-+static DECLARE_RWSEM(bnep_session_sem);
-+
-+static struct bnep_session *__bnep_get_session(u8 *dst)
-+{
-+ struct bnep_session *s;
-+ struct list_head *p;
-+
-+ BT_DBG("");
-+
-+ list_for_each(p, &bnep_session_list) {
-+ s = list_entry(p, struct bnep_session, list);
-+ if (!memcmp(dst, s->eh.h_source, ETH_ALEN))
-+ return s;
-+ }
-+ return NULL;
-+}
-+
-+static void __bnep_link_session(struct bnep_session *s)
-+{
-+ MOD_INC_USE_COUNT;
-+ list_add(&s->list, &bnep_session_list);
-+}
-+
-+static void __bnep_unlink_session(struct bnep_session *s)
-+{
-+ list_del(&s->list);
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static int bnep_send(struct bnep_session *s, void *data, size_t len)
-+{
-+ struct socket *sock = s->sock;
-+ struct iovec iv = { data, len };
-+ s->msg.msg_iov = &iv;
-+ s->msg.msg_iovlen = 1;
-+ return sock->ops->sendmsg(sock, &s->msg, len, NULL);
-+}
-+
-+static int bnep_send_rsp(struct bnep_session *s, u8 ctrl, u16 resp)
-+{
-+ struct bnep_control_rsp rsp;
-+ rsp.type = BNEP_CONTROL;
-+ rsp.ctrl = ctrl;
-+ rsp.resp = htons(resp);
-+ return bnep_send(s, &rsp, sizeof(rsp));
-+}
-+
-+static int bnep_ctrl_set_netfilter(struct bnep_session *s, u16 *data, int len)
-+{
-+ int n;
-+
-+ if (len < 2)
-+ return -EILSEQ;
-+
-+ n = ntohs(get_unaligned(data));
-+ data++; len -= 2;
-+
-+ if (len < n)
-+ return -EILSEQ;
-+
-+ BT_DBG("filter len %d", n);
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+ n /= 4;
-+ if (n <= BNEP_MAX_PROTO_FILTERS) {
-+ struct bnep_proto_filter *f = s->proto_filter;
-+ int i;
-+
-+ for (i = 0; i < n; i++) {
-+ f[i].start = get_unaligned(data++);
-+ f[i].end = get_unaligned(data++);
-+
-+ BT_DBG("proto filter start %d end %d",
-+ f[i].start, f[i].end);
-+ }
-+ if (i < BNEP_MAX_PROTO_FILTERS)
-+ memset(f + i, 0, sizeof(*f));
-+
-+ bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_SUCCESS);
-+ } else {
-+ bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_LIMIT_REACHED);
-+ }
-+#else
-+ bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
-+#endif
-+ return 0;
-+}
-+
-+static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
-+{
-+ int n;
-+
-+ if (len < 2)
-+ return -EILSEQ;
-+
-+ n = ntohs(get_unaligned((u16 *) data));
-+ data += 2; len -= 2;
-+
-+ if (len < n)
-+ return -EILSEQ;
-+
-+ BT_DBG("filter len %d", n);
-+
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+ n /= (ETH_ALEN * 2);
-+
-+ if (n > 0) {
-+ s->mc_filter = 0;
-+
-+ /* Always send broadcast */
-+ set_bit(bnep_mc_hash(s->dev.broadcast), &s->mc_filter);
-+
-+ /* Add address ranges to the multicast hash */
-+ for (; n > 0; n--) {
-+ u8 a1[6], *a2;
-+
-+ memcpy(a1, data, ETH_ALEN); data += ETH_ALEN;
-+ a2 = data; data += ETH_ALEN;
-+
-+ BT_DBG("mc filter %s -> %s",
-+ batostr((void *) a1), batostr((void *) a2));
-+
-+ #define INCA(a) { int i = 5; while (i >=0 && ++a[i--] == 0); }
-+
-+ /* Iterate from a1 to a2 */
-+ set_bit(bnep_mc_hash(a1), &s->mc_filter);
-+ while (memcmp(a1, a2, 6) < 0 && s->mc_filter != ~0LL) {
-+ INCA(a1);
-+ set_bit(bnep_mc_hash(a1), &s->mc_filter);
-+ }
-+ }
-+ }
-+
-+ BT_DBG("mc filter hash 0x%llx", s->mc_filter);
-+
-+ bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_SUCCESS);
-+#else
-+ bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
-+#endif
-+ return 0;
-+}
-+
-+static int bnep_rx_control(struct bnep_session *s, void *data, int len)
-+{
-+ u8 cmd = *(u8 *)data;
-+ int err = 0;
-+
-+ data++; len--;
-+
-+ switch (cmd) {
-+ case BNEP_CMD_NOT_UNDERSTOOD:
-+ case BNEP_SETUP_CONN_REQ:
-+ case BNEP_SETUP_CONN_RSP:
-+ case BNEP_FILTER_NET_TYPE_RSP:
-+ case BNEP_FILTER_MULTI_ADDR_RSP:
-+ /* Ignore these for now */
-+ break;
-+
-+ case BNEP_FILTER_NET_TYPE_SET:
-+ err = bnep_ctrl_set_netfilter(s, data, len);
-+ break;
-+
-+ case BNEP_FILTER_MULTI_ADDR_SET:
-+ err = bnep_ctrl_set_mcfilter(s, data, len);
-+ break;
-+
-+ default: {
-+ u8 pkt[3];
-+ pkt[0] = BNEP_CONTROL;
-+ pkt[1] = BNEP_CMD_NOT_UNDERSTOOD;
-+ pkt[2] = cmd;
-+ bnep_send(s, pkt, sizeof(pkt));
-+ }
-+ break;
-+ }
-+
-+ return err;
-+}
-+
-+static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb)
-+{
-+ struct bnep_ext_hdr *h;
-+ int err = 0;
-+
-+ do {
-+ h = (void *) skb->data;
-+ if (!skb_pull(skb, sizeof(*h))) {
-+ err = -EILSEQ;
-+ break;
-+ }
-+
-+ BT_DBG("type 0x%x len %d", h->type, h->len);
-+
-+ switch (h->type & BNEP_TYPE_MASK) {
-+ case BNEP_EXT_CONTROL:
-+ bnep_rx_control(s, skb->data, skb->len);
-+ break;
-+
-+ default:
-+ /* Unknown extension, skip it. */
-+ break;
-+ }
-+
-+ if (!skb_pull(skb, h->len)) {
-+ err = -EILSEQ;
-+ break;
-+ }
-+ } while (!err && (h->type & BNEP_EXT_HEADER));
-+
-+ return err;
-+}
-+
-+static u8 __bnep_rx_hlen[] = {
-+ ETH_HLEN, /* BNEP_GENERAL */
-+ 0, /* BNEP_CONTROL */
-+ 2, /* BNEP_COMPRESSED */
-+ ETH_ALEN + 2, /* BNEP_COMPRESSED_SRC_ONLY */
-+ ETH_ALEN + 2 /* BNEP_COMPRESSED_DST_ONLY */
-+};
-+#define BNEP_RX_TYPES (sizeof(__bnep_rx_hlen) - 1)
-+
-+static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
-+{
-+ struct net_device *dev = &s->dev;
-+ struct sk_buff *nskb;
-+ u8 type;
-+
-+ dev->last_rx = jiffies;
-+ s->stats.rx_bytes += skb->len;
-+
-+ type = *(u8 *) skb->data; skb_pull(skb, 1);
-+
-+ if ((type & BNEP_TYPE_MASK) > BNEP_RX_TYPES)
-+ goto badframe;
-+
-+ if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) {
-+ bnep_rx_control(s, skb->data, skb->len);
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+
-+ skb->mac.raw = skb->data;
-+
-+ /* Verify and pull out header */
-+ if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK]))
-+ goto badframe;
-+
-+ s->eh.h_proto = get_unaligned((u16 *) (skb->data - 2));
-+
-+ if (type & BNEP_EXT_HEADER) {
-+ if (bnep_rx_extension(s, skb) < 0)
-+ goto badframe;
-+ }
-+
-+ /* Strip 802.1p header */
-+ if (ntohs(s->eh.h_proto) == 0x8100) {
-+ if (!skb_pull(skb, 4))
-+ goto badframe;
-+ s->eh.h_proto = get_unaligned((u16 *) (skb->data - 2));
-+ }
-+
-+ /* We have to alloc new skb and copy data here :(. Because original skb
-+ * may not be modified and because of the alignment requirements. */
-+ nskb = alloc_skb(2 + ETH_HLEN + skb->len, GFP_KERNEL);
-+ if (!nskb) {
-+ s->stats.rx_dropped++;
-+ kfree_skb(skb);
-+ return -ENOMEM;
-+ }
-+ skb_reserve(nskb, 2);
-+
-+ /* Decompress header and construct ether frame */
-+ switch (type & BNEP_TYPE_MASK) {
-+ case BNEP_COMPRESSED:
-+ memcpy(__skb_put(nskb, ETH_HLEN), &s->eh, ETH_HLEN);
-+ break;
-+
-+ case BNEP_COMPRESSED_SRC_ONLY:
-+ memcpy(__skb_put(nskb, ETH_ALEN), s->eh.h_dest, ETH_ALEN);
-+ memcpy(__skb_put(nskb, ETH_ALEN), skb->mac.raw, ETH_ALEN);
-+ put_unaligned(s->eh.h_proto, (u16 *) __skb_put(nskb, 2));
-+ break;
-+
-+ case BNEP_COMPRESSED_DST_ONLY:
-+ memcpy(__skb_put(nskb, ETH_ALEN), skb->mac.raw, ETH_ALEN);
-+ memcpy(__skb_put(nskb, ETH_ALEN + 2), s->eh.h_source, ETH_ALEN + 2);
-+ break;
-+
-+ case BNEP_GENERAL:
-+ memcpy(__skb_put(nskb, ETH_ALEN * 2), skb->mac.raw, ETH_ALEN * 2);
-+ put_unaligned(s->eh.h_proto, (u16 *) __skb_put(nskb, 2));
-+ break;
-+ }
-+
-+ memcpy(__skb_put(nskb, skb->len), skb->data, skb->len);
-+ kfree_skb(skb);
-+
-+ s->stats.rx_packets++;
-+ nskb->dev = dev;
-+ nskb->ip_summed = CHECKSUM_UNNECESSARY;
-+ nskb->protocol = eth_type_trans(nskb, dev);
-+ netif_rx_ni(nskb);
-+ return 0;
-+
-+badframe:
-+ s->stats.rx_errors++;
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+static u8 __bnep_tx_types[] = {
-+ BNEP_GENERAL,
-+ BNEP_COMPRESSED_SRC_ONLY,
-+ BNEP_COMPRESSED_DST_ONLY,
-+ BNEP_COMPRESSED
-+};
-+
-+static inline int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb)
-+{
-+ struct ethhdr *eh = (void *) skb->data;
-+ struct socket *sock = s->sock;
-+ struct iovec iv[3];
-+ int len = 0, il = 0;
-+ u8 type = 0;
-+
-+ BT_DBG("skb %p dev %p type %d", skb, skb->dev, skb->pkt_type);
-+
-+ if (!skb->dev) {
-+ /* Control frame sent by us */
-+ goto send;
-+ }
-+
-+ iv[il++] = (struct iovec) { &type, 1 };
-+ len++;
-+
-+ if (!memcmp(eh->h_dest, s->eh.h_source, ETH_ALEN))
-+ type |= 0x01;
-+
-+ if (!memcmp(eh->h_source, s->eh.h_dest, ETH_ALEN))
-+ type |= 0x02;
-+
-+ if (type)
-+ skb_pull(skb, ETH_ALEN * 2);
-+
-+ type = __bnep_tx_types[type];
-+ switch (type) {
-+ case BNEP_COMPRESSED_SRC_ONLY:
-+ iv[il++] = (struct iovec) { eh->h_source, ETH_ALEN };
-+ len += ETH_ALEN;
-+ break;
-+
-+ case BNEP_COMPRESSED_DST_ONLY:
-+ iv[il++] = (struct iovec) { eh->h_dest, ETH_ALEN };
-+ len += ETH_ALEN;
-+ break;
-+ }
-+
-+send:
-+ iv[il++] = (struct iovec) { skb->data, skb->len };
-+ len += skb->len;
-+
-+ /* FIXME: linearize skb */
-+
-+ s->msg.msg_iov = iv;
-+ s->msg.msg_iovlen = il;
-+ len = sock->ops->sendmsg(sock, &s->msg, len, NULL);
-+ kfree_skb(skb);
-+
-+ if (len > 0) {
-+ s->stats.tx_bytes += len;
-+ s->stats.tx_packets++;
-+ return 0;
-+ }
-+
-+ return len;
-+}
-+
-+static int bnep_session(void *arg)
-+{
-+ struct bnep_session *s = arg;
-+ struct net_device *dev = &s->dev;
-+ struct sock *sk = s->sock->sk;
-+ struct sk_buff *skb;
-+ wait_queue_t wait;
-+
-+ BT_DBG("");
-+
-+ daemonize(); reparent_to_init();
-+
-+ sprintf(current->comm, "kbnepd %s", dev->name);
-+
-+ sigfillset(&current->blocked);
-+ flush_signals(current);
-+
-+ current->nice = -15;
-+
-+ set_fs(KERNEL_DS);
-+
-+ init_waitqueue_entry(&wait, current);
-+ add_wait_queue(sk->sleep, &wait);
-+ while (!atomic_read(&s->killed)) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ // RX
-+ while ((skb = skb_dequeue(&sk->receive_queue))) {
-+ skb_orphan(skb);
-+ bnep_rx_frame(s, skb);
-+ }
-+
-+ if (sk->state != BT_CONNECTED)
-+ break;
-+
-+ // TX
-+ while ((skb = skb_dequeue(&sk->write_queue)))
-+ if (bnep_tx_frame(s, skb))
-+ break;
-+ netif_wake_queue(dev);
-+
-+ schedule();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ /* Cleanup session */
-+ down_write(&bnep_session_sem);
-+
-+ /* Delete network device */
-+ unregister_netdev(dev);
-+
-+ /* Release the socket */
-+ fput(s->sock->file);
-+
-+ __bnep_unlink_session(s);
-+
-+ up_write(&bnep_session_sem);
-+ kfree(s);
-+ return 0;
-+}
-+
-+int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
-+{
-+ struct net_device *dev;
-+ struct bnep_session *s, *ss;
-+ u8 dst[ETH_ALEN], src[ETH_ALEN];
-+ int err;
-+
-+ BT_DBG("");
-+
-+ baswap((void *) dst, &bluez_pi(sock->sk)->dst);
-+ baswap((void *) src, &bluez_pi(sock->sk)->src);
-+
-+ s = kmalloc(sizeof(struct bnep_session), GFP_KERNEL);
-+ if (!s)
-+ return -ENOMEM;
-+ memset(s, 0, sizeof(struct bnep_session));
-+
-+ down_write(&bnep_session_sem);
-+
-+ ss = __bnep_get_session(dst);
-+ if (ss && ss->state == BT_CONNECTED) {
-+ err = -EEXIST;
-+ goto failed;
-+ }
-+
-+ dev = &s->dev;
-+
-+ if (*req->device)
-+ strcpy(dev->name, req->device);
-+ else
-+ strcpy(dev->name, "bnep%d");
-+
-+ memset(dev->broadcast, 0xff, ETH_ALEN);
-+
-+ /* This is rx header therefor addresses are swaped.
-+ * ie eh.h_dest is our local address. */
-+ memcpy(s->eh.h_dest, &src, ETH_ALEN);
-+ memcpy(s->eh.h_source, &dst, ETH_ALEN);
-+
-+ s->sock = sock;
-+ s->role = req->role;
-+ s->state = BT_CONNECTED;
-+
-+ s->msg.msg_flags = MSG_NOSIGNAL;
-+
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+ /* Set default mc filter */
-+ set_bit(bnep_mc_hash(dev->broadcast), &s->mc_filter);
-+#endif
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+ /* Set default protocol filter */
-+
-+ /* (IPv4, ARP) */
-+ s->proto_filter[0].start = htons(0x0800);
-+ s->proto_filter[0].end = htons(0x0806);
-+ /* (RARP, AppleTalk) */
-+ s->proto_filter[1].start = htons(0x8035);
-+ s->proto_filter[1].end = htons(0x80F3);
-+ /* (IPX, IPv6) */
-+ s->proto_filter[2].start = htons(0x8137);
-+ s->proto_filter[2].end = htons(0x86DD);
-+#endif
-+
-+ dev->init = bnep_net_init;
-+ dev->priv = s;
-+ err = register_netdev(dev);
-+ if (err) {
-+ goto failed;
-+ }
-+
-+ __bnep_link_session(s);
-+
-+ err = kernel_thread(bnep_session, s, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-+ if (err < 0) {
-+ /* Session thread start failed, gotta cleanup. */
-+ unregister_netdev(dev);
-+ __bnep_unlink_session(s);
-+ goto failed;
-+ }
-+
-+ up_write(&bnep_session_sem);
-+ strcpy(req->device, dev->name);
-+ return 0;
-+
-+failed:
-+ up_write(&bnep_session_sem);
-+ kfree(s);
-+ return err;
-+}
-+
-+int bnep_del_connection(struct bnep_conndel_req *req)
-+{
-+ struct bnep_session *s;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ down_read(&bnep_session_sem);
-+
-+ s = __bnep_get_session(req->dst);
-+ if (s) {
-+ /* Wakeup user-space which is polling for socket errors.
-+ * This is temporary hack untill we have shutdown in L2CAP */
-+ s->sock->sk->err = EUNATCH;
-+
-+ /* Kill session thread */
-+ atomic_inc(&s->killed);
-+ wake_up_interruptible(s->sock->sk->sleep);
-+ } else
-+ err = -ENOENT;
-+
-+ up_read(&bnep_session_sem);
-+ return err;
-+}
-+
-+static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s)
-+{
-+ memcpy(ci->dst, s->eh.h_source, ETH_ALEN);
-+ strcpy(ci->device, s->dev.name);
-+ ci->flags = s->flags;
-+ ci->state = s->state;
-+ ci->role = s->role;
-+}
-+
-+int bnep_get_connlist(struct bnep_connlist_req *req)
-+{
-+ struct list_head *p;
-+ int err = 0, n = 0;
-+
-+ down_read(&bnep_session_sem);
-+
-+ list_for_each(p, &bnep_session_list) {
-+ struct bnep_session *s;
-+ struct bnep_conninfo ci;
-+
-+ s = list_entry(p, struct bnep_session, list);
-+
-+ __bnep_copy_ci(&ci, s);
-+
-+ if (copy_to_user(req->ci, &ci, sizeof(ci))) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ if (++n >= req->cnum)
-+ break;
-+
-+ req->ci++;
-+ }
-+ req->cnum = n;
-+
-+ up_read(&bnep_session_sem);
-+ return err;
-+}
-+
-+int bnep_get_conninfo(struct bnep_conninfo *ci)
-+{
-+ struct bnep_session *s;
-+ int err = 0;
-+
-+ down_read(&bnep_session_sem);
-+
-+ s = __bnep_get_session(ci->dst);
-+ if (s)
-+ __bnep_copy_ci(ci, s);
-+ else
-+ err = -ENOENT;
-+
-+ up_read(&bnep_session_sem);
-+ return err;
-+}
-+
-+static int __init bnep_init_module(void)
-+{
-+ l2cap_load();
-+
-+ bnep_crc32_init();
-+ bnep_sock_init();
-+
-+ BT_INFO("BlueZ BNEP ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2001,2002 Inventel Systemes");
-+ BT_INFO("Written 2001,2002 by Clement Moreau <clement.moreau@inventel.fr>");
-+ BT_INFO("Written 2001,2002 by David Libault <david.libault@inventel.fr>");
-+ BT_INFO("Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>");
-+
-+ return 0;
-+}
-+
-+static void __exit bnep_cleanup_module(void)
-+{
-+ bnep_sock_cleanup();
-+ bnep_crc32_cleanup();
-+}
-+
-+module_init(bnep_init_module);
-+module_exit(bnep_cleanup_module);
-+
-+MODULE_DESCRIPTION("BlueZ BNEP ver " VERSION);
-+MODULE_AUTHOR("David Libault <david.libault@inventel.fr>, Maxim Krasnyanskiy <maxk@qualcomm.com>");
-+MODULE_LICENSE("GPL");
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/bnep/crc32.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,59 @@
-+/*
-+ * Based on linux-2.5/lib/crc32 by Matt Domsch <Matt_Domsch@dell.com>
-+ *
-+ * FIXME: Remove in 2.5
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <asm/atomic.h>
-+
-+#include "crc32.h"
-+
-+#define CRCPOLY_BE 0x04c11db7
-+#define CRC_BE_BITS 8
-+
-+static u32 *bnep_crc32_table;
-+
-+/*
-+ * This code is in the public domain; copyright abandoned.
-+ * Liability for non-performance of this code is limited to the amount
-+ * you paid for it. Since it is distributed for free, your refund will
-+ * be very very small. If it breaks, you get to keep both pieces.
-+ */
-+u32 bnep_crc32(u32 crc, unsigned char const *p, size_t len)
-+{
-+ while (len--)
-+ crc = (crc << 8) ^ bnep_crc32_table[(crc >> 24) ^ *p++];
-+
-+ return crc;
-+}
-+
-+int __init bnep_crc32_init(void)
-+{
-+ unsigned i, j;
-+ u32 crc = 0x80000000;
-+
-+ bnep_crc32_table = kmalloc((1 << CRC_BE_BITS) * sizeof(u32), GFP_KERNEL);
-+ if (!bnep_crc32_table)
-+ return -ENOMEM;
-+
-+ bnep_crc32_table[0] = 0;
-+
-+ for (i = 1; i < 1 << CRC_BE_BITS; i <<= 1) {
-+ crc = (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE : 0);
-+ for (j = 0; j < i; j++)
-+ bnep_crc32_table[i + j] = crc ^ bnep_crc32_table[j];
-+ }
-+ return 0;
-+}
-+
-+void __exit bnep_crc32_cleanup(void)
-+{
-+ if (bnep_crc32_table)
-+ kfree(bnep_crc32_table);
-+ bnep_crc32_table = NULL;
-+}
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/bnep/crc32.h 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,10 @@
-+/*
-+ * crc32.h
-+ * See crc32.c for license and changes
-+ *
-+ * FIXME: Remove in 2.5
-+ */
-+
-+int bnep_crc32_init(void);
-+void bnep_crc32_cleanup(void);
-+u32 bnep_crc32(u32 crc, unsigned char const *p, size_t len);
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/bnep/Makefile 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the Linux Bluetooth BNEP layer
-+#
-+
-+O_TARGET := bnep.o
-+
-+obj-y := core.o sock.o netdev.o crc32.o
-+obj-m += $(O_TARGET)
-+
-+include $(TOPDIR)/Rules.make
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/bnep/netdev.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,254 @@
-+/*
-+ BNEP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2001-2002 Inventel Systemes
-+ Written 2001-2002 by
-+ Clément Moreau <clement.moreau@inventel.fr>
-+ David Libault <david.libault@inventel.fr>
-+
-+ Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/socket.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/wait.h>
-+
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#include "bnep.h"
-+
-+#ifndef CONFIG_BLUEZ_BNEP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+#define BNEP_TX_QUEUE_LEN 20
-+
-+static int bnep_net_open(struct net_device *dev)
-+{
-+ netif_start_queue(dev);
-+ return 0;
-+}
-+
-+static int bnep_net_close(struct net_device *dev)
-+{
-+ netif_stop_queue(dev);
-+ return 0;
-+}
-+
-+static struct net_device_stats *bnep_net_get_stats(struct net_device *dev)
-+{
-+ struct bnep_session *s = dev->priv;
-+ return &s->stats;
-+}
-+
-+static void bnep_net_set_mc_list(struct net_device *dev)
-+{
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+ struct bnep_session *s = dev->priv;
-+ struct sock *sk = s->sock->sk;
-+ struct bnep_set_filter_req *r;
-+ struct sk_buff *skb;
-+ int size;
-+
-+ BT_DBG("%s mc_count %d", dev->name, dev->mc_count);
-+
-+ size = sizeof(*r) + (BNEP_MAX_MULTICAST_FILTERS + 1) * ETH_ALEN * 2;
-+ skb = alloc_skb(size, GFP_ATOMIC);
-+ if (!skb) {
-+ BT_ERR("%s Multicast list allocation failed", dev->name);
-+ return;
-+ }
-+
-+ r = (void *) skb->data;
-+ __skb_put(skb, sizeof(*r));
-+
-+ r->type = BNEP_CONTROL;
-+ r->ctrl = BNEP_FILTER_MULTI_ADDR_SET;
-+
-+ if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
-+ u8 start[ETH_ALEN] = { 0x01 };
-+
-+ /* Request all addresses */
-+ memcpy(__skb_put(skb, ETH_ALEN), start, ETH_ALEN);
-+ memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
-+ r->len = htons(ETH_ALEN * 2);
-+ } else {
-+ struct dev_mc_list *dmi = dev->mc_list;
-+ int i, len = skb->len;
-+
-+ if (dev->flags & IFF_BROADCAST) {
-+ memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
-+ memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
-+ }
-+
-+ /* FIXME: We should group addresses here. */
-+
-+ for (i = 0; i < dev->mc_count && i < BNEP_MAX_MULTICAST_FILTERS; i++) {
-+ memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN);
-+ memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN);
-+ dmi = dmi->next;
-+ }
-+ r->len = htons(skb->len - len);
-+ }
-+
-+ skb_queue_tail(&sk->write_queue, skb);
-+ wake_up_interruptible(sk->sleep);
-+#endif
-+}
-+
-+static int bnep_net_set_mac_addr(struct net_device *dev, void *arg)
-+{
-+ BT_DBG("%s", dev->name);
-+ return 0;
-+}
-+
-+static void bnep_net_timeout(struct net_device *dev)
-+{
-+ BT_DBG("net_timeout");
-+ netif_wake_queue(dev);
-+}
-+
-+static int bnep_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-+{
-+ return -EINVAL;
-+}
-+
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+static inline int bnep_net_mc_filter(struct sk_buff *skb, struct bnep_session *s)
-+{
-+ struct ethhdr *eh = (void *) skb->data;
-+
-+ if ((eh->h_dest[0] & 1) && !test_bit(bnep_mc_hash(eh->h_dest), &s->mc_filter)) {
-+ BT_DBG("BNEP: filtered skb %p, dst %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", skb,
-+ eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
-+ eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]);
-+ return 1;
-+ }
-+ return 0;
-+}
-+#endif
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+/* Determine ether protocol. Based on eth_type_trans. */
-+static inline u16 bnep_net_eth_proto(struct sk_buff *skb)
-+{
-+ struct ethhdr *eh = (void *) skb->data;
-+
-+ if (ntohs(eh->h_proto) >= 1536)
-+ return eh->h_proto;
-+
-+ if (get_unaligned((u16 *) skb->data) == 0xFFFF)
-+ return htons(ETH_P_802_3);
-+
-+ return htons(ETH_P_802_2);
-+}
-+
-+static inline int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session *s)
-+{
-+ u16 proto = bnep_net_eth_proto(skb);
-+ struct bnep_proto_filter *f = s->proto_filter;
-+ int i;
-+
-+ for (i = 0; i < BNEP_MAX_PROTO_FILTERS && f[i].end; i++) {
-+ if (proto >= f[i].start && proto <= f[i].end)
-+ return 0;
-+ }
-+
-+ BT_DBG("BNEP: filtered skb %p, proto 0x%.4x", skb, proto);
-+ return 1;
-+}
-+#endif
-+
-+static int bnep_net_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+ struct bnep_session *s = dev->priv;
-+ struct sock *sk = s->sock->sk;
-+
-+ BT_DBG("skb %p, dev %p", skb, dev);
-+
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+ if (bnep_net_mc_filter(skb, s)) {
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+#endif
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+ if (bnep_net_proto_filter(skb, s)) {
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+#endif
-+
-+ /*
-+ * We cannot send L2CAP packets from here as we are potentially in a bh.
-+ * So we have to queue them and wake up session thread which is sleeping
-+ * on the sk->sleep.
-+ */
-+ dev->trans_start = jiffies;
-+ skb_queue_tail(&sk->write_queue, skb);
-+ wake_up_interruptible(sk->sleep);
-+
-+ if (skb_queue_len(&sk->write_queue) >= BNEP_TX_QUEUE_LEN) {
-+ BT_DBG("tx queue is full");
-+
-+ /* Stop queuing.
-+ * Session thread will do netif_wake_queue() */
-+ netif_stop_queue(dev);
-+ }
-+
-+ return 0;
-+}
-+
-+int bnep_net_init(struct net_device *dev)
-+{
-+ struct bnep_session *s = dev->priv;
-+
-+ memcpy(dev->dev_addr, s->eh.h_dest, ETH_ALEN);
-+ dev->addr_len = ETH_ALEN;
-+
-+ ether_setup(dev);
-+
-+ dev->open = bnep_net_open;
-+ dev->stop = bnep_net_close;
-+ dev->hard_start_xmit = bnep_net_xmit;
-+ dev->get_stats = bnep_net_get_stats;
-+ dev->do_ioctl = bnep_net_ioctl;
-+ dev->set_mac_address = bnep_net_set_mac_addr;
-+ dev->set_multicast_list = bnep_net_set_mc_list;
-+
-+ dev->watchdog_timeo = HZ * 2;
-+ dev->tx_timeout = bnep_net_timeout;
-+
-+ return 0;
-+}
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/bnep/sock.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,238 @@
-+/*
-+ BNEP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2001-2002 Inventel Systemes
-+ Written 2001-2002 by
-+ David Libault <david.libault@inventel.fr>
-+
-+ Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include "bnep.h"
-+
-+#ifndef CONFIG_BLUEZ_BNEP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+static inline struct socket *socki_lookup(struct inode *inode)
-+{
-+ return &inode->u.socket_i;
-+}
-+
-+static struct socket *sockfd_lookup(int fd, int *err)
-+{
-+ struct file *file;
-+ struct inode *inode;
-+ struct socket *sock;
-+
-+ if (!(file = fget(fd))) {
-+ *err = -EBADF;
-+ return NULL;
-+ }
-+
-+ inode = file->f_dentry->d_inode;
-+ if (!inode->i_sock || !(sock = socki_lookup(inode))) {
-+ *err = -ENOTSOCK;
-+ fput(file);
-+ return NULL;
-+ }
-+
-+ if (sock->file != file) {
-+ printk(KERN_ERR "socki_lookup: socket file changed!\n");
-+ sock->file = file;
-+ }
-+ return sock;
-+}
-+
-+static int bnep_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ sock_orphan(sk);
-+ sock_put(sk);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct bnep_connlist_req cl;
-+ struct bnep_connadd_req ca;
-+ struct bnep_conndel_req cd;
-+ struct bnep_conninfo ci;
-+ struct socket *nsock;
-+ int err;
-+
-+ BT_DBG("cmd %x arg %lx", cmd, arg);
-+
-+ switch (cmd) {
-+ case BNEPCONNADD:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
-+ return -EFAULT;
-+
-+ nsock = sockfd_lookup(ca.sock, &err);
-+ if (!nsock)
-+ return err;
-+
-+ if (nsock->sk->state != BT_CONNECTED)
-+ return -EBADFD;
-+
-+ err = bnep_add_connection(&ca, nsock);
-+ if (!err) {
-+ if (copy_to_user((void *) arg, &ca, sizeof(ca)))
-+ err = -EFAULT;
-+ } else
-+ fput(nsock->file);
-+
-+ return err;
-+
-+ case BNEPCONNDEL:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
-+ return -EFAULT;
-+
-+ return bnep_del_connection(&cd);
-+
-+ case BNEPGETCONNLIST:
-+ if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
-+ return -EFAULT;
-+
-+ if (cl.cnum <= 0)
-+ return -EINVAL;
-+
-+ err = bnep_get_connlist(&cl);
-+ if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
-+ return -EFAULT;
-+
-+ return err;
-+
-+ case BNEPGETCONNINFO:
-+ if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
-+ return -EFAULT;
-+
-+ err = bnep_get_conninfo(&ci);
-+ if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
-+ return -EFAULT;
-+
-+ return err;
-+
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static struct proto_ops bnep_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: bnep_sock_release,
-+ ioctl: bnep_sock_ioctl,
-+ bind: sock_no_bind,
-+ getname: sock_no_getname,
-+ sendmsg: sock_no_sendmsg,
-+ recvmsg: sock_no_recvmsg,
-+ poll: sock_no_poll,
-+ listen: sock_no_listen,
-+ shutdown: sock_no_shutdown,
-+ setsockopt: sock_no_setsockopt,
-+ getsockopt: sock_no_getsockopt,
-+ connect: sock_no_connect,
-+ socketpair: sock_no_socketpair,
-+ accept: sock_no_accept,
-+ mmap: sock_no_mmap
-+};
-+
-+static int bnep_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ if (sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &bnep_sock_ops;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, 1)))
-+ return -ENOMEM;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ sock->state = SS_UNCONNECTED;
-+ sock_init_data(sock, sk);
-+
-+ sk->destruct = NULL;
-+ sk->protocol = protocol;
-+
-+ return 0;
-+}
-+
-+static struct net_proto_family bnep_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: bnep_sock_create
-+};
-+
-+int bnep_sock_init(void)
-+{
-+ bluez_sock_register(BTPROTO_BNEP, &bnep_sock_family_ops);
-+ return 0;
-+}
-+
-+int bnep_sock_cleanup(void)
-+{
-+ if (bluez_sock_unregister(BTPROTO_BNEP))
-+ BT_ERR("Can't unregister BNEP socket");
-+ return 0;
-+}
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/cmtp/capi.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,707 @@
-+/*
-+ CMTP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <net/sock.h>
-+
-+#include <linux/capi.h>
-+
-+#include "../drivers/isdn/avmb1/capilli.h"
-+#include "../drivers/isdn/avmb1/capicmd.h"
-+#include "../drivers/isdn/avmb1/capiutil.h"
-+
-+#include "cmtp.h"
-+
-+#ifndef CONFIG_BLUEZ_CMTP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define REVISION "1.0"
-+
-+#define CAPI_INTEROPERABILITY 0x20
-+
-+#define CAPI_INTEROPERABILITY_REQ CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
-+#define CAPI_INTEROPERABILITY_CONF CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
-+#define CAPI_INTEROPERABILITY_IND CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
-+#define CAPI_INTEROPERABILITY_RESP CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
-+
-+#define CAPI_INTEROPERABILITY_REQ_LEN (CAPI_MSG_BASELEN + 2)
-+#define CAPI_INTEROPERABILITY_CONF_LEN (CAPI_MSG_BASELEN + 4)
-+#define CAPI_INTEROPERABILITY_IND_LEN (CAPI_MSG_BASELEN + 2)
-+#define CAPI_INTEROPERABILITY_RESP_LEN (CAPI_MSG_BASELEN + 2)
-+
-+#define CAPI_FUNCTION_REGISTER 0
-+#define CAPI_FUNCTION_RELEASE 1
-+#define CAPI_FUNCTION_GET_PROFILE 2
-+#define CAPI_FUNCTION_GET_MANUFACTURER 3
-+#define CAPI_FUNCTION_GET_VERSION 4
-+#define CAPI_FUNCTION_GET_SERIAL_NUMBER 5
-+#define CAPI_FUNCTION_MANUFACTURER 6
-+#define CAPI_FUNCTION_LOOPBACK 7
-+
-+static struct capi_driver_interface *di;
-+
-+
-+#define CMTP_MSGNUM 1
-+#define CMTP_APPLID 2
-+#define CMTP_MAPPING 3
-+
-+static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
-+{
-+ struct cmtp_application *app = kmalloc(sizeof(*app), GFP_KERNEL);
-+
-+ BT_DBG("session %p application %p appl %d", session, app, appl);
-+
-+ if (!app)
-+ return NULL;
-+
-+ memset(app, 0, sizeof(*app));
-+
-+ app->state = BT_OPEN;
-+ app->appl = appl;
-+
-+ list_add_tail(&app->list, &session->applications);
-+
-+ return app;
-+}
-+
-+static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
-+{
-+ BT_DBG("session %p application %p", session, app);
-+
-+ if (app) {
-+ list_del(&app->list);
-+ kfree(app);
-+ }
-+}
-+
-+static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
-+{
-+ struct cmtp_application *app;
-+ struct list_head *p, *n;
-+
-+ list_for_each_safe(p, n, &session->applications) {
-+ app = list_entry(p, struct cmtp_application, list);
-+ switch (pattern) {
-+ case CMTP_MSGNUM:
-+ if (app->msgnum == value)
-+ return app;
-+ break;
-+ case CMTP_APPLID:
-+ if (app->appl == value)
-+ return app;
-+ break;
-+ case CMTP_MAPPING:
-+ if (app->mapping == value)
-+ return app;
-+ break;
-+ }
-+ }
-+
-+ return NULL;
-+}
-+
-+static int cmtp_msgnum_get(struct cmtp_session *session)
-+{
-+ session->msgnum++;
-+
-+ if ((session->msgnum & 0xff) > 200)
-+ session->msgnum = CMTP_INITIAL_MSGNUM + 1;
-+
-+ return session->msgnum;
-+}
-+
-+
-+static void cmtp_send_interopmsg(struct cmtp_session *session,
-+ __u8 subcmd, __u16 appl, __u16 msgnum,
-+ __u16 function, unsigned char *buf, int len)
-+{
-+ struct sk_buff *skb;
-+ unsigned char *s;
-+
-+ BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum);
-+
-+ if (!(skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for interoperability packet");
-+ return;
-+ }
-+
-+ s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
-+
-+ capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
-+ capimsg_setu16(s, 2, appl);
-+ capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
-+ capimsg_setu8 (s, 5, subcmd);
-+ capimsg_setu16(s, 6, msgnum);
-+
-+ /* Interoperability selector (Bluetooth Device Management) */
-+ capimsg_setu16(s, 8, 0x0001);
-+
-+ capimsg_setu8 (s, 10, 3 + len);
-+ capimsg_setu16(s, 11, function);
-+ capimsg_setu8 (s, 13, len);
-+
-+ if (len > 0)
-+ memcpy(s + 14, buf, len);
-+
-+ cmtp_send_capimsg(session, skb);
-+}
-+
-+static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
-+{
-+ struct capi_ctr *ctrl = session->ctrl;
-+ struct cmtp_application *application;
-+ __u16 appl, msgnum, func, info;
-+ __u32 controller;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ switch (CAPIMSG_SUBCOMMAND(skb->data)) {
-+ case CAPI_CONF:
-+ func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
-+ info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
-+
-+ switch (func) {
-+ case CAPI_FUNCTION_REGISTER:
-+ msgnum = CAPIMSG_MSGID(skb->data);
-+
-+ application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
-+ if (application) {
-+ application->state = BT_CONNECTED;
-+ application->msgnum = 0;
-+ application->mapping = CAPIMSG_APPID(skb->data);
-+ wake_up_interruptible(&session->wait);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_RELEASE:
-+ appl = CAPIMSG_APPID(skb->data);
-+
-+ application = cmtp_application_get(session, CMTP_MAPPING, appl);
-+ if (application) {
-+ application->state = BT_CLOSED;
-+ application->msgnum = 0;
-+ wake_up_interruptible(&session->wait);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_GET_PROFILE:
-+ controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
-+ msgnum = CAPIMSG_MSGID(skb->data);
-+
-+ if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
-+ session->ncontroller = controller;
-+ wake_up_interruptible(&session->wait);
-+ break;
-+ }
-+
-+ if (!info && ctrl) {
-+ memcpy(&ctrl->profile,
-+ skb->data + CAPI_MSG_BASELEN + 11,
-+ sizeof(capi_profile));
-+ session->state = BT_CONNECTED;
-+ ctrl->ready(ctrl);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_GET_MANUFACTURER:
-+ controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);
-+
-+ if (!info && ctrl) {
-+ strncpy(ctrl->manu,
-+ skb->data + CAPI_MSG_BASELEN + 15,
-+ skb->data[CAPI_MSG_BASELEN + 14]);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_GET_VERSION:
-+ controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
-+
-+ if (!info && ctrl) {
-+ ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
-+ ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
-+ ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
-+ ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_GET_SERIAL_NUMBER:
-+ controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
-+
-+ if (!info && ctrl) {
-+ memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
-+ strncpy(ctrl->serial,
-+ skb->data + CAPI_MSG_BASELEN + 17,
-+ skb->data[CAPI_MSG_BASELEN + 16]);
-+ }
-+
-+ break;
-+ }
-+
-+ break;
-+
-+ case CAPI_IND:
-+ func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
-+
-+ if (func == CAPI_FUNCTION_LOOPBACK) {
-+ appl = CAPIMSG_APPID(skb->data);
-+ msgnum = CAPIMSG_MSGID(skb->data);
-+ cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
-+ skb->data + CAPI_MSG_BASELEN + 6,
-+ skb->data[CAPI_MSG_BASELEN + 5]);
-+ }
-+
-+ break;
-+ }
-+
-+ kfree_skb(skb);
-+}
-+
-+void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
-+{
-+ struct capi_ctr *ctrl = session->ctrl;
-+ struct cmtp_application *application;
-+ __u16 cmd, appl, info;
-+ __u32 ncci, contr;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
-+ cmtp_recv_interopmsg(session, skb);
-+ return;
-+ }
-+
-+ if (session->flags & (1 << CMTP_LOOPBACK)) {
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data));
-+ appl = CAPIMSG_APPID(skb->data);
-+ contr = CAPIMSG_CONTROL(skb->data);
-+
-+ application = cmtp_application_get(session, CMTP_MAPPING, appl);
-+ if (application) {
-+ appl = application->appl;
-+ CAPIMSG_SETAPPID(skb->data, appl);
-+ } else {
-+ BT_ERR("Can't find application with id %d", appl);
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ if ((contr & 0x7f) == 0x01) {
-+ contr = (contr & 0xffffff80) | session->num;
-+ CAPIMSG_SETCONTROL(skb->data, contr);
-+ }
-+
-+ if (!ctrl) {
-+ BT_ERR("Can't find controller %d for message", session->num);
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ switch (cmd) {
-+ case CAPI_CONNECT_B3_CONF:
-+ ncci = CAPIMSG_NCCI(skb->data);
-+ info = CAPIMSG_U16(skb->data, 12);
-+
-+ BT_DBG("CONNECT_B3_CONF ncci 0x%02x info 0x%02x", ncci, info);
-+
-+ if (info == 0)
-+ ctrl->new_ncci(ctrl, appl, ncci, 8);
-+
-+ ctrl->handle_capimsg(ctrl, appl, skb);
-+ break;
-+
-+ case CAPI_CONNECT_B3_IND:
-+ ncci = CAPIMSG_NCCI(skb->data);
-+
-+ BT_DBG("CONNECT_B3_IND ncci 0x%02x", ncci);
-+
-+ ctrl->new_ncci(ctrl, appl, ncci, 8);
-+ ctrl->handle_capimsg(ctrl, appl, skb);
-+ break;
-+
-+ case CAPI_DISCONNECT_B3_IND:
-+ ncci = CAPIMSG_NCCI(skb->data);
-+
-+ BT_DBG("DISCONNECT_B3_IND ncci 0x%02x", ncci);
-+
-+ if (ncci == 0xffffffff)
-+ BT_ERR("DISCONNECT_B3_IND with ncci 0xffffffff");
-+
-+ ctrl->handle_capimsg(ctrl, appl, skb);
-+ ctrl->free_ncci(ctrl, appl, ncci);
-+ break;
-+
-+ default:
-+ ctrl->handle_capimsg(ctrl, appl, skb);
-+ break;
-+ }
-+}
-+
-+void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
-+{
-+ struct cmtp_scb *scb = (void *) skb->cb;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ scb->id = -1;
-+ scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
-+
-+ skb_queue_tail(&session->transmit, skb);
-+
-+ cmtp_schedule(session);
-+}
-+
-+
-+static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
-+{
-+ BT_DBG("ctrl %p data %p", ctrl, data);
-+
-+ return -EIO;
-+}
-+
-+static void cmtp_reset_ctr(struct capi_ctr *ctrl)
-+{
-+ BT_DBG("ctrl %p", ctrl);
-+
-+ ctrl->reseted(ctrl);
-+}
-+
-+static void cmtp_remove_ctr(struct capi_ctr *ctrl)
-+{
-+ struct cmtp_session *session = ctrl->driverdata;
-+
-+ BT_DBG("ctrl %p", ctrl);
-+
-+ ctrl->suspend_output(ctrl);
-+
-+ atomic_inc(&session->terminate);
-+ cmtp_schedule(session);
-+}
-+
-+static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct cmtp_session *session = ctrl->driverdata;
-+ struct cmtp_application *application;
-+ unsigned long timeo = CMTP_INTEROP_TIMEOUT;
-+ unsigned char buf[8];
-+ int err = 0, nconn, want = rp->level3cnt;
-+
-+ BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
-+ ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
-+
-+ application = cmtp_application_add(session, appl);
-+ if (!application) {
-+ BT_ERR("Can't allocate memory for new application");
-+ ctrl->appl_released(ctrl, appl);
-+ return;
-+ }
-+
-+ if (want < 0)
-+ nconn = ctrl->profile.nbchannel * -want;
-+ else
-+ nconn = want;
-+
-+ if (nconn == 0)
-+ nconn = ctrl->profile.nbchannel;
-+
-+ capimsg_setu16(buf, 0, nconn);
-+ capimsg_setu16(buf, 2, rp->datablkcnt);
-+ capimsg_setu16(buf, 4, rp->datablklen);
-+
-+ application->state = BT_CONFIG;
-+ application->msgnum = cmtp_msgnum_get(session);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
-+ CAPI_FUNCTION_REGISTER, buf, 6);
-+
-+ add_wait_queue(&session->wait, &wait);
-+ while (1) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ if (application->state == BT_CLOSED) {
-+ err = -application->err;
-+ break;
-+ }
-+
-+ if (application->state == BT_CONNECTED)
-+ break;
-+
-+ if (signal_pending(current)) {
-+ err = -EINTR;
-+ break;
-+ }
-+
-+ timeo = schedule_timeout(timeo);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&session->wait, &wait);
-+
-+ if (err) {
-+ ctrl->appl_released(ctrl, appl);
-+ cmtp_application_del(session, application);
-+ return;
-+ }
-+
-+ ctrl->appl_registered(ctrl, appl);
-+}
-+
-+static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct cmtp_session *session = ctrl->driverdata;
-+ struct cmtp_application *application;
-+ unsigned long timeo = CMTP_INTEROP_TIMEOUT;
-+
-+ BT_DBG("ctrl %p appl %d", ctrl, appl);
-+
-+ application = cmtp_application_get(session, CMTP_APPLID, appl);
-+ if (!application) {
-+ BT_ERR("Can't find application");
-+ return;
-+ }
-+
-+ application->msgnum = cmtp_msgnum_get(session);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
-+ CAPI_FUNCTION_RELEASE, NULL, 0);
-+
-+ add_wait_queue(&session->wait, &wait);
-+ while (timeo) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (application->state == BT_CLOSED)
-+ break;
-+
-+ if (signal_pending(current))
-+ break;
-+
-+ timeo = schedule_timeout(timeo);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&session->wait, &wait);
-+
-+ cmtp_application_del(session, application);
-+ ctrl->appl_released(ctrl, appl);
-+}
-+
-+static void cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
-+{
-+ struct cmtp_session *session = ctrl->driverdata;
-+ struct cmtp_application *application;
-+ __u16 appl;
-+ __u32 contr;
-+
-+ BT_DBG("ctrl %p skb %p", ctrl, skb);
-+
-+ appl = CAPIMSG_APPID(skb->data);
-+ contr = CAPIMSG_CONTROL(skb->data);
-+
-+ application = cmtp_application_get(session, CMTP_APPLID, appl);
-+ if ((!application) || (application->state != BT_CONNECTED)) {
-+ BT_ERR("Can't find application with id %d", appl);
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ CAPIMSG_SETAPPID(skb->data, application->mapping);
-+
-+ if ((contr & 0x7f) == session->num) {
-+ contr = (contr & 0xffffff80) | 0x01;
-+ CAPIMSG_SETCONTROL(skb->data, contr);
-+ }
-+
-+ cmtp_send_capimsg(session, skb);
-+}
-+
-+static char *cmtp_procinfo(struct capi_ctr *ctrl)
-+{
-+ return "CAPI Message Transport Protocol";
-+}
-+
-+static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl)
-+{
-+ struct cmtp_session *session = ctrl->driverdata;
-+ struct cmtp_application *app;
-+ struct list_head *p, *n;
-+ int len = 0;
-+
-+ len += sprintf(page + len, "%s (Revision %s)\n\n", cmtp_procinfo(ctrl), REVISION);
-+ len += sprintf(page + len, "addr %s\n", session->name);
-+ len += sprintf(page + len, "ctrl %d\n", session->num);
-+
-+ list_for_each_safe(p, n, &session->applications) {
-+ app = list_entry(p, struct cmtp_application, list);
-+ len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping);
-+ }
-+
-+ if (off + count >= len)
-+ *eof = 1;
-+
-+ if (len < off)
-+ return 0;
-+
-+ *start = page + off;
-+
-+ return ((count < len - off) ? count : len - off);
-+}
-+
-+static struct capi_driver cmtp_driver = {
-+ name: "cmtp",
-+ revision: REVISION,
-+ load_firmware: cmtp_load_firmware,
-+ reset_ctr: cmtp_reset_ctr,
-+ remove_ctr: cmtp_remove_ctr,
-+ register_appl: cmtp_register_appl,
-+ release_appl: cmtp_release_appl,
-+ send_message: cmtp_send_message,
-+ procinfo: cmtp_procinfo,
-+ ctr_read_proc: cmtp_ctr_read_proc,
-+
-+ driver_read_proc: 0,
-+ add_card: 0,
-+};
-+
-+
-+int cmtp_attach_device(struct cmtp_session *session)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ unsigned long timeo = CMTP_INTEROP_TIMEOUT;
-+ unsigned char buf[4];
-+
-+ BT_DBG("session %p", session);
-+
-+ capimsg_setu32(buf, 0, 0);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
-+ CAPI_FUNCTION_GET_PROFILE, buf, 4);
-+
-+ add_wait_queue(&session->wait, &wait);
-+ while (timeo) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (session->ncontroller)
-+ break;
-+
-+ if (signal_pending(current))
-+ break;
-+
-+ timeo = schedule_timeout(timeo);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&session->wait, &wait);
-+
-+ BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
-+
-+ if (!timeo)
-+ return -ETIMEDOUT;
-+
-+ if (!session->ncontroller)
-+ return -ENODEV;
-+
-+
-+ if (session->ncontroller > 1)
-+ BT_INFO("Setting up only CAPI controller 1");
-+
-+ if (!(session->ctrl = di->attach_ctr(&cmtp_driver, session->name, session))) {
-+ BT_ERR("Can't attach new controller");
-+ return -EBUSY;
-+ }
-+
-+ session->num = session->ctrl->cnr;
-+
-+ BT_DBG("session %p ctrl %p num %d", session, session->ctrl, session->num);
-+
-+ capimsg_setu32(buf, 0, 1);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-+ CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-+ CAPI_FUNCTION_GET_VERSION, buf, 4);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-+ CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-+ CAPI_FUNCTION_GET_PROFILE, buf, 4);
-+
-+ return 0;
-+}
-+
-+void cmtp_detach_device(struct cmtp_session *session)
-+{
-+ struct capi_ctr *ctrl = session->ctrl;
-+
-+ BT_DBG("session %p ctrl %p", session, ctrl);
-+
-+ if (!ctrl)
-+ return;
-+
-+ ctrl->reseted(ctrl);
-+
-+ di->detach_ctr(ctrl);
-+}
-+
-+int cmtp_init_capi(void)
-+{
-+ if (!(di = attach_capi_driver(&cmtp_driver))) {
-+ BT_ERR("Can't attach CAPI driver");
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+void cmtp_cleanup_capi(void)
-+{
-+ detach_capi_driver(&cmtp_driver);
-+}
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/cmtp/cmtp.h 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,138 @@
-+/*
-+ CMTP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#ifndef __CMTP_H
-+#define __CMTP_H
-+
-+#include <linux/types.h>
-+#include <net/bluetooth/bluetooth.h>
-+
-+#define BTNAMSIZ 18
-+
-+/* CMTP ioctl defines */
-+#define CMTPCONNADD _IOW('C', 200, int)
-+#define CMTPCONNDEL _IOW('C', 201, int)
-+#define CMTPGETCONNLIST _IOR('C', 210, int)
-+#define CMTPGETCONNINFO _IOR('C', 211, int)
-+
-+#define CMTP_LOOPBACK 0
-+
-+struct cmtp_connadd_req {
-+ int sock; // Connected socket
-+ __u32 flags;
-+};
-+
-+struct cmtp_conndel_req {
-+ bdaddr_t bdaddr;
-+ __u32 flags;
-+};
-+
-+struct cmtp_conninfo {
-+ bdaddr_t bdaddr;
-+ __u32 flags;
-+ __u16 state;
-+ int num;
-+};
-+
-+struct cmtp_connlist_req {
-+ __u32 cnum;
-+ struct cmtp_conninfo *ci;
-+};
-+
-+int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock);
-+int cmtp_del_connection(struct cmtp_conndel_req *req);
-+int cmtp_get_connlist(struct cmtp_connlist_req *req);
-+int cmtp_get_conninfo(struct cmtp_conninfo *ci);
-+
-+/* CMTP session defines */
-+#define CMTP_INTEROP_TIMEOUT (HZ * 5)
-+#define CMTP_INITIAL_MSGNUM 0xff00
-+
-+struct cmtp_session {
-+ struct list_head list;
-+
-+ struct socket *sock;
-+
-+ bdaddr_t bdaddr;
-+
-+ unsigned long state;
-+ unsigned long flags;
-+
-+ uint mtu;
-+
-+ char name[BTNAMSIZ];
-+
-+ atomic_t terminate;
-+
-+ wait_queue_head_t wait;
-+
-+ int ncontroller;
-+ int num;
-+ struct capi_ctr *ctrl;
-+
-+ struct list_head applications;
-+
-+ unsigned long blockids;
-+ int msgnum;
-+
-+ struct sk_buff_head transmit;
-+
-+ struct sk_buff *reassembly[16];
-+};
-+
-+struct cmtp_application {
-+ struct list_head list;
-+
-+ unsigned long state;
-+ int err;
-+
-+ __u16 appl;
-+ __u16 mapping;
-+
-+ __u16 msgnum;
-+};
-+
-+struct cmtp_scb {
-+ int id;
-+ int data;
-+};
-+
-+int cmtp_attach_device(struct cmtp_session *session);
-+void cmtp_detach_device(struct cmtp_session *session);
-+
-+void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb);
-+void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb);
-+
-+static inline void cmtp_schedule(struct cmtp_session *session)
-+{
-+ struct sock *sk = session->sock->sk;
-+
-+ wake_up_interruptible(sk->sleep);
-+}
-+
-+/* CMTP init defines */
-+int cmtp_init_capi(void);
-+int cmtp_init_sockets(void);
-+void cmtp_cleanup_capi(void);
-+void cmtp_cleanup_sockets(void);
-+
-+#endif /* __CMTP_H */
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/cmtp/Config.in 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,7 @@
-+#
-+# Bluetooth CMTP layer configuration
-+#
-+
-+if [ "$CONFIG_ISDN" = "y" -o "$CONFIG_ISDN" = "m" ]; then
-+ dep_tristate 'CMTP protocol support' CONFIG_BLUEZ_CMTP $CONFIG_ISDN_CAPI $CONFIG_BLUEZ_L2CAP
-+fi
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/cmtp/core.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,515 @@
-+/*
-+ CMTP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <linux/init.h>
-+#include <net/sock.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#include "cmtp.h"
-+
-+#ifndef CONFIG_BLUEZ_CMTP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define VERSION "1.0"
-+
-+static DECLARE_RWSEM(cmtp_session_sem);
-+static LIST_HEAD(cmtp_session_list);
-+
-+static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr)
-+{
-+ struct cmtp_session *session;
-+ struct list_head *p;
-+
-+ BT_DBG("");
-+
-+ list_for_each(p, &cmtp_session_list) {
-+ session = list_entry(p, struct cmtp_session, list);
-+ if (!bacmp(bdaddr, &session->bdaddr))
-+ return session;
-+ }
-+ return NULL;
-+}
-+
-+static void __cmtp_link_session(struct cmtp_session *session)
-+{
-+ MOD_INC_USE_COUNT;
-+ list_add(&session->list, &cmtp_session_list);
-+}
-+
-+static void __cmtp_unlink_session(struct cmtp_session *session)
-+{
-+ list_del(&session->list);
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci)
-+{
-+ bacpy(&ci->bdaddr, &session->bdaddr);
-+
-+ ci->flags = session->flags;
-+ ci->state = session->state;
-+
-+ ci->num = session->num;
-+}
-+
-+
-+static inline int cmtp_alloc_block_id(struct cmtp_session *session)
-+{
-+ int i, id = -1;
-+
-+ for (i = 0; i < 16; i++)
-+ if (!test_and_set_bit(i, &session->blockids)) {
-+ id = i;
-+ break;
-+ }
-+
-+ return id;
-+}
-+
-+static inline void cmtp_free_block_id(struct cmtp_session *session, int id)
-+{
-+ clear_bit(id, &session->blockids);
-+}
-+
-+static inline void cmtp_add_msgpart(struct cmtp_session *session, int id, const unsigned char *buf, int count)
-+{
-+ struct sk_buff *skb = session->reassembly[id], *nskb;
-+ int size;
-+
-+ BT_DBG("session %p buf %p count %d", session, buf, count);
-+
-+ size = (skb) ? skb->len + count : count;
-+
-+ if (!(nskb = alloc_skb(size, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for CAPI message");
-+ return;
-+ }
-+
-+ if (skb && (skb->len > 0))
-+ memcpy(skb_put(nskb, skb->len), skb->data, skb->len);
-+
-+ memcpy(skb_put(nskb, count), buf, count);
-+
-+ session->reassembly[id] = nskb;
-+
-+ if (skb)
-+ kfree_skb(skb);
-+}
-+
-+static inline int cmtp_recv_frame(struct cmtp_session *session, struct sk_buff *skb)
-+{
-+ __u8 hdr, hdrlen, id;
-+ __u16 len;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ while (skb->len > 0) {
-+ hdr = skb->data[0];
-+
-+ switch (hdr & 0xc0) {
-+ case 0x40:
-+ hdrlen = 2;
-+ len = skb->data[1];
-+ break;
-+ case 0x80:
-+ hdrlen = 3;
-+ len = skb->data[1] | (skb->data[2] << 8);
-+ break;
-+ default:
-+ hdrlen = 1;
-+ len = 0;
-+ break;
-+ }
-+
-+ id = (hdr & 0x3c) >> 2;
-+
-+ BT_DBG("hdr 0x%02x hdrlen %d len %d id %d", hdr, hdrlen, len, id);
-+
-+ if (hdrlen + len > skb->len) {
-+ BT_ERR("Wrong size or header information in CMTP frame");
-+ break;
-+ }
-+
-+ if (len == 0) {
-+ skb_pull(skb, hdrlen);
-+ continue;
-+ }
-+
-+ switch (hdr & 0x03) {
-+ case 0x00:
-+ cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
-+ cmtp_recv_capimsg(session, session->reassembly[id]);
-+ session->reassembly[id] = NULL;
-+ break;
-+ case 0x01:
-+ cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
-+ break;
-+ default:
-+ if (session->reassembly[id] != NULL)
-+ kfree_skb(session->reassembly[id]);
-+ session->reassembly[id] = NULL;
-+ break;
-+ }
-+
-+ skb_pull(skb, hdrlen + len);
-+ }
-+
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+static int cmtp_send_frame(struct cmtp_session *session, unsigned char *data, int len)
-+{
-+ struct socket *sock = session->sock;
-+ struct iovec iv = { data, len };
-+ struct msghdr msg;
-+ int err;
-+
-+ BT_DBG("session %p data %p len %d", session, data, len);
-+
-+ if (!len)
-+ return 0;
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_iovlen = 1;
-+ msg.msg_iov = &iv;
-+
-+ err = sock->ops->sendmsg(sock, &msg, len, 0);
-+ return err;
-+}
-+
-+static int cmtp_process_transmit(struct cmtp_session *session)
-+{
-+ struct sk_buff *skb, *nskb;
-+ unsigned char *hdr;
-+ unsigned int size, tail;
-+
-+ BT_DBG("session %p", session);
-+
-+ if (!(nskb = alloc_skb(session->mtu, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for new frame");
-+ return -ENOMEM;
-+ }
-+
-+ while ((skb = skb_dequeue(&session->transmit))) {
-+ struct cmtp_scb *scb = (void *) skb->cb;
-+
-+ if ((tail = (session->mtu - nskb->len)) < 5) {
-+ cmtp_send_frame(session, nskb->data, nskb->len);
-+ skb_trim(nskb, 0);
-+ tail = session->mtu;
-+ }
-+
-+ size = min_t(uint, ((tail < 258) ? (tail - 2) : (tail - 3)), skb->len);
-+
-+ if ((scb->id < 0) && ((scb->id = cmtp_alloc_block_id(session)) < 0)) {
-+ skb_queue_head(&session->transmit, skb);
-+ break;
-+ }
-+
-+ if (size < 256) {
-+ hdr = skb_put(nskb, 2);
-+ hdr[0] = 0x40
-+ | ((scb->id << 2) & 0x3c)
-+ | ((skb->len == size) ? 0x00 : 0x01);
-+ hdr[1] = size;
-+ } else {
-+ hdr = skb_put(nskb, 3);
-+ hdr[0] = 0x80
-+ | ((scb->id << 2) & 0x3c)
-+ | ((skb->len == size) ? 0x00 : 0x01);
-+ hdr[1] = size & 0xff;
-+ hdr[2] = size >> 8;
-+ }
-+
-+ memcpy(skb_put(nskb, size), skb->data, size);
-+ skb_pull(skb, size);
-+
-+ if (skb->len > 0) {
-+ skb_queue_head(&session->transmit, skb);
-+ } else {
-+ cmtp_free_block_id(session, scb->id);
-+ if (scb->data) {
-+ cmtp_send_frame(session, nskb->data, nskb->len);
-+ skb_trim(nskb, 0);
-+ }
-+ kfree_skb(skb);
-+ }
-+ }
-+
-+ cmtp_send_frame(session, nskb->data, nskb->len);
-+
-+ kfree_skb(nskb);
-+
-+ return skb_queue_len(&session->transmit);
-+}
-+
-+static int cmtp_session(void *arg)
-+{
-+ struct cmtp_session *session = arg;
-+ struct sock *sk = session->sock->sk;
-+ struct sk_buff *skb;
-+ wait_queue_t wait;
-+
-+ BT_DBG("session %p", session);
-+
-+ daemonize(); reparent_to_init();
-+
-+ sprintf(current->comm, "kcmtpd_ctr_%d", session->num);
-+
-+ sigfillset(&current->blocked);
-+ flush_signals(current);
-+
-+ current->nice = -15;
-+
-+ set_fs(KERNEL_DS);
-+
-+ init_waitqueue_entry(&wait, current);
-+ add_wait_queue(sk->sleep, &wait);
-+ while (!atomic_read(&session->terminate)) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (sk->state != BT_CONNECTED)
-+ break;
-+
-+ while ((skb = skb_dequeue(&sk->receive_queue))) {
-+ skb_orphan(skb);
-+ cmtp_recv_frame(session, skb);
-+ }
-+
-+ cmtp_process_transmit(session);
-+
-+ schedule();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ down_write(&cmtp_session_sem);
-+
-+ if (!(session->flags & (1 << CMTP_LOOPBACK)))
-+ cmtp_detach_device(session);
-+
-+ fput(session->sock->file);
-+
-+ __cmtp_unlink_session(session);
-+
-+ up_write(&cmtp_session_sem);
-+
-+ kfree(session);
-+ return 0;
-+}
-+
-+int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
-+{
-+ struct cmtp_session *session, *s;
-+ bdaddr_t src, dst;
-+ int i, err;
-+
-+ BT_DBG("");
-+
-+ baswap(&src, &bluez_pi(sock->sk)->src);
-+ baswap(&dst, &bluez_pi(sock->sk)->dst);
-+
-+ session = kmalloc(sizeof(struct cmtp_session), GFP_KERNEL);
-+ if (!session)
-+ return -ENOMEM;
-+ memset(session, 0, sizeof(struct cmtp_session));
-+
-+ down_write(&cmtp_session_sem);
-+
-+ s = __cmtp_get_session(&bluez_pi(sock->sk)->dst);
-+ if (s && s->state == BT_CONNECTED) {
-+ err = -EEXIST;
-+ goto failed;
-+ }
-+
-+ bacpy(&session->bdaddr, &bluez_pi(sock->sk)->dst);
-+
-+ session->mtu = min_t(uint, l2cap_pi(sock->sk)->omtu, l2cap_pi(sock->sk)->imtu);
-+
-+ BT_DBG("mtu %d", session->mtu);
-+
-+ sprintf(session->name, "%s", batostr(&dst));
-+
-+ session->sock = sock;
-+ session->state = BT_CONFIG;
-+
-+ init_waitqueue_head(&session->wait);
-+
-+ session->ctrl = NULL;
-+ session->msgnum = CMTP_INITIAL_MSGNUM;
-+
-+ INIT_LIST_HEAD(&session->applications);
-+
-+ skb_queue_head_init(&session->transmit);
-+
-+ for (i = 0; i < 16; i++)
-+ session->reassembly[i] = NULL;
-+
-+ session->flags = req->flags;
-+
-+ __cmtp_link_session(session);
-+
-+ err = kernel_thread(cmtp_session, session, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-+ if (err < 0)
-+ goto unlink;
-+
-+ if (!(session->flags & (1 << CMTP_LOOPBACK))) {
-+ err = cmtp_attach_device(session);
-+ if (err < 0)
-+ goto detach;
-+ }
-+
-+ up_write(&cmtp_session_sem);
-+ return 0;
-+
-+detach:
-+ cmtp_detach_device(session);
-+
-+unlink:
-+ __cmtp_unlink_session(session);
-+
-+failed:
-+ up_write(&cmtp_session_sem);
-+ kfree(session);
-+ return err;
-+}
-+
-+int cmtp_del_connection(struct cmtp_conndel_req *req)
-+{
-+ struct cmtp_session *session;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ down_read(&cmtp_session_sem);
-+
-+ session = __cmtp_get_session(&req->bdaddr);
-+ if (session) {
-+ /* Flush the transmit queue */
-+ skb_queue_purge(&session->transmit);
-+
-+ /* Kill session thread */
-+ atomic_inc(&session->terminate);
-+ cmtp_schedule(session);
-+ } else
-+ err = -ENOENT;
-+
-+ up_read(&cmtp_session_sem);
-+ return err;
-+}
-+
-+int cmtp_get_connlist(struct cmtp_connlist_req *req)
-+{
-+ struct list_head *p;
-+ int err = 0, n = 0;
-+
-+ BT_DBG("");
-+
-+ down_read(&cmtp_session_sem);
-+
-+ list_for_each(p, &cmtp_session_list) {
-+ struct cmtp_session *session;
-+ struct cmtp_conninfo ci;
-+
-+ session = list_entry(p, struct cmtp_session, list);
-+
-+ __cmtp_copy_session(session, &ci);
-+
-+ if (copy_to_user(req->ci, &ci, sizeof(ci))) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ if (++n >= req->cnum)
-+ break;
-+
-+ req->ci++;
-+ }
-+ req->cnum = n;
-+
-+ up_read(&cmtp_session_sem);
-+ return err;
-+}
-+
-+int cmtp_get_conninfo(struct cmtp_conninfo *ci)
-+{
-+ struct cmtp_session *session;
-+ int err = 0;
-+
-+ down_read(&cmtp_session_sem);
-+
-+ session = __cmtp_get_session(&ci->bdaddr);
-+ if (session)
-+ __cmtp_copy_session(session, ci);
-+ else
-+ err = -ENOENT;
-+
-+ up_read(&cmtp_session_sem);
-+ return err;
-+}
-+
-+
-+int __init init_cmtp(void)
-+{
-+ l2cap_load();
-+
-+ cmtp_init_capi();
-+ cmtp_init_sockets();
-+
-+ BT_INFO("BlueZ CMTP ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>");
-+
-+ return 0;
-+}
-+
-+void __exit exit_cmtp(void)
-+{
-+ cmtp_cleanup_sockets();
-+ cmtp_cleanup_capi();
-+}
-+
-+module_init(init_cmtp);
-+module_exit(exit_cmtp);
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ CMTP ver " VERSION);
-+MODULE_LICENSE("GPL");
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/cmtp/Makefile 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the Linux Bluetooth CMTP layer
-+#
-+
-+O_TARGET := cmtp.o
-+
-+obj-y := core.o sock.o capi.o
-+obj-m += $(O_TARGET)
-+
-+include $(TOPDIR)/Rules.make
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/cmtp/sock.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,236 @@
-+/*
-+ CMTP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include "cmtp.h"
-+
-+#ifndef CONFIG_BLUEZ_CMTP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+static inline struct socket *socki_lookup(struct inode *inode)
-+{
-+ return &inode->u.socket_i;
-+}
-+
-+static struct socket *sockfd_lookup(int fd, int *err)
-+{
-+ struct file *file;
-+ struct inode *inode;
-+ struct socket *sock;
-+
-+ if (!(file = fget(fd))) {
-+ *err = -EBADF;
-+ return NULL;
-+ }
-+
-+ inode = file->f_dentry->d_inode;
-+ if (!inode->i_sock || !(sock = socki_lookup(inode))) {
-+ *err = -ENOTSOCK;
-+ fput(file);
-+ return NULL;
-+ }
-+
-+ if (sock->file != file) {
-+ printk(KERN_ERR "socki_lookup: socket file changed!\n");
-+ sock->file = file;
-+ }
-+ return sock;
-+}
-+
-+static int cmtp_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ sock_orphan(sk);
-+ sock_put(sk);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct cmtp_connadd_req ca;
-+ struct cmtp_conndel_req cd;
-+ struct cmtp_connlist_req cl;
-+ struct cmtp_conninfo ci;
-+ struct socket *nsock;
-+ int err;
-+
-+ BT_DBG("cmd %x arg %lx", cmd, arg);
-+
-+ switch (cmd) {
-+ case CMTPCONNADD:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
-+ return -EFAULT;
-+
-+ nsock = sockfd_lookup(ca.sock, &err);
-+ if (!nsock)
-+ return err;
-+
-+ if (nsock->sk->state != BT_CONNECTED)
-+ return -EBADFD;
-+
-+ err = cmtp_add_connection(&ca, nsock);
-+ if (!err) {
-+ if (copy_to_user((void *) arg, &ca, sizeof(ca)))
-+ err = -EFAULT;
-+ } else
-+ fput(nsock->file);
-+
-+ return err;
-+
-+ case CMTPCONNDEL:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
-+ return -EFAULT;
-+
-+ return cmtp_del_connection(&cd);
-+
-+ case CMTPGETCONNLIST:
-+ if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
-+ return -EFAULT;
-+
-+ if (cl.cnum <= 0)
-+ return -EINVAL;
-+
-+ err = cmtp_get_connlist(&cl);
-+ if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
-+ return -EFAULT;
-+
-+ return err;
-+
-+ case CMTPGETCONNINFO:
-+ if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
-+ return -EFAULT;
-+
-+ err = cmtp_get_conninfo(&ci);
-+ if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
-+ return -EFAULT;
-+
-+ return err;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static struct proto_ops cmtp_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: cmtp_sock_release,
-+ ioctl: cmtp_sock_ioctl,
-+ bind: sock_no_bind,
-+ getname: sock_no_getname,
-+ sendmsg: sock_no_sendmsg,
-+ recvmsg: sock_no_recvmsg,
-+ poll: sock_no_poll,
-+ listen: sock_no_listen,
-+ shutdown: sock_no_shutdown,
-+ setsockopt: sock_no_setsockopt,
-+ getsockopt: sock_no_getsockopt,
-+ connect: sock_no_connect,
-+ socketpair: sock_no_socketpair,
-+ accept: sock_no_accept,
-+ mmap: sock_no_mmap
-+};
-+
-+static int cmtp_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ if (sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &cmtp_sock_ops;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, 1)))
-+ return -ENOMEM;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ sock->state = SS_UNCONNECTED;
-+ sock_init_data(sock, sk);
-+
-+ sk->destruct = NULL;
-+ sk->protocol = protocol;
-+
-+ return 0;
-+}
-+
-+static struct net_proto_family cmtp_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: cmtp_sock_create
-+};
-+
-+int cmtp_init_sockets(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_CMTP, &cmtp_sock_family_ops))) {
-+ BT_ERR("Can't register CMTP socket layer (%d)", err);
-+ return err;
-+ }
-+
-+ return 0;
-+}
-+
-+void cmtp_cleanup_sockets(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_unregister(BTPROTO_CMTP)))
-+ BT_ERR("Can't unregister CMTP socket layer (%d)", err);
-+
-+ return;
-+}
---- linux/net/bluetooth/Config.in~bluetooth-2.4.18-mh11 2001-06-12 04:15:27.000000000 +0200
-+++ linux/net/bluetooth/Config.in 2004-01-25 23:37:39.000000000 +0100
-@@ -1,16 +1,22 @@
- #
--# Bluetooth configuration
-+# Bluetooth subsystem configuration
- #
-
- if [ "$CONFIG_NET" != "n" ]; then
-+
- mainmenu_option next_comment
- comment 'Bluetooth support'
- dep_tristate 'Bluetooth subsystem support' CONFIG_BLUEZ $CONFIG_NET
-
- if [ "$CONFIG_BLUEZ" != "n" ]; then
- dep_tristate 'L2CAP protocol support' CONFIG_BLUEZ_L2CAP $CONFIG_BLUEZ
-+ dep_tristate 'SCO links support' CONFIG_BLUEZ_SCO $CONFIG_BLUEZ
-+ source net/bluetooth/rfcomm/Config.in
-+ source net/bluetooth/bnep/Config.in
-+ source net/bluetooth/cmtp/Config.in
- source drivers/bluetooth/Config.in
- fi
-+
- endmenu
- fi
-
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/hci_conn.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,435 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * HCI Connection handling.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/notifier.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+#ifndef HCI_CORE_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+void hci_acl_connect(struct hci_conn *conn)
-+{
-+ struct hci_dev *hdev = conn->hdev;
-+ struct inquiry_entry *ie;
-+ create_conn_cp cp;
-+
-+ BT_DBG("%p", conn);
-+
-+ conn->state = BT_CONNECT;
-+ conn->out = 1;
-+ conn->link_mode = HCI_LM_MASTER;
-+
-+ memset(&cp, 0, sizeof(cp));
-+ bacpy(&cp.bdaddr, &conn->dst);
-+ cp.pscan_rep_mode = 0x02;
-+
-+ if ((ie = inquiry_cache_lookup(hdev, &conn->dst)) &&
-+ inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
-+ cp.pscan_rep_mode = ie->info.pscan_rep_mode;
-+ cp.pscan_mode = ie->info.pscan_mode;
-+ cp.clock_offset = ie->info.clock_offset | __cpu_to_le16(0x8000);
-+ }
-+
-+ cp.pkt_type = __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK);
-+ if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
-+ cp.role_switch = 0x01;
-+ else
-+ cp.role_switch = 0x00;
-+
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN,
-+ CREATE_CONN_CP_SIZE, &cp);
-+}
-+
-+void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
-+{
-+ disconnect_cp cp;
-+
-+ BT_DBG("%p", conn);
-+
-+ conn->state = BT_DISCONN;
-+
-+ cp.handle = __cpu_to_le16(conn->handle);
-+ cp.reason = reason;
-+ hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT,
-+ DISCONNECT_CP_SIZE, &cp);
-+}
-+
-+void hci_add_sco(struct hci_conn *conn, __u16 handle)
-+{
-+ struct hci_dev *hdev = conn->hdev;
-+ add_sco_cp cp;
-+
-+ BT_DBG("%p", conn);
-+
-+ conn->state = BT_CONNECT;
-+ conn->out = 1;
-+
-+ cp.pkt_type = __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
-+ cp.handle = __cpu_to_le16(handle);
-+
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, ADD_SCO_CP_SIZE, &cp);
-+}
-+
-+static void hci_conn_timeout(unsigned long arg)
-+{
-+ struct hci_conn *conn = (void *)arg;
-+ struct hci_dev *hdev = conn->hdev;
-+
-+ BT_DBG("conn %p state %d", conn, conn->state);
-+
-+ if (atomic_read(&conn->refcnt))
-+ return;
-+
-+ hci_dev_lock(hdev);
-+ if (conn->state == BT_CONNECTED)
-+ hci_acl_disconn(conn, 0x13);
-+ else
-+ conn->state = BT_CLOSED;
-+ hci_dev_unlock(hdev);
-+ return;
-+}
-+
-+static void hci_conn_init_timer(struct hci_conn *conn)
-+{
-+ init_timer(&conn->timer);
-+ conn->timer.function = hci_conn_timeout;
-+ conn->timer.data = (unsigned long)conn;
-+}
-+
-+struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
-+{
-+ struct hci_conn *conn;
-+
-+ BT_DBG("%s dst %s", hdev->name, batostr(dst));
-+
-+ if (!(conn = kmalloc(sizeof(struct hci_conn), GFP_ATOMIC)))
-+ return NULL;
-+ memset(conn, 0, sizeof(struct hci_conn));
-+
-+ bacpy(&conn->dst, dst);
-+ conn->type = type;
-+ conn->hdev = hdev;
-+ conn->state = BT_OPEN;
-+
-+ skb_queue_head_init(&conn->data_q);
-+ hci_conn_init_timer(conn);
-+
-+ atomic_set(&conn->refcnt, 0);
-+
-+ hci_dev_hold(hdev);
-+
-+ tasklet_disable(&hdev->tx_task);
-+ conn_hash_add(hdev, conn);
-+ tasklet_enable(&hdev->tx_task);
-+
-+ return conn;
-+}
-+
-+int hci_conn_del(struct hci_conn *conn)
-+{
-+ struct hci_dev *hdev = conn->hdev;
-+
-+ BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
-+
-+ hci_conn_del_timer(conn);
-+
-+ if (conn->type == SCO_LINK) {
-+ struct hci_conn *acl = conn->link;
-+ if (acl) {
-+ acl->link = NULL;
-+ hci_conn_put(acl);
-+ }
-+ } else {
-+ struct hci_conn *sco = conn->link;
-+ if (sco)
-+ sco->link = NULL;
-+
-+ /* Unacked frames */
-+ hdev->acl_cnt += conn->sent;
-+ }
-+
-+ tasklet_disable(&hdev->tx_task);
-+ conn_hash_del(hdev, conn);
-+ tasklet_enable(&hdev->tx_task);
-+
-+ skb_queue_purge(&conn->data_q);
-+
-+ hci_dev_put(hdev);
-+
-+ kfree(conn);
-+ return 0;
-+}
-+
-+struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
-+{
-+ int use_src = bacmp(src, BDADDR_ANY);
-+ struct hci_dev *hdev = NULL;
-+ struct list_head *p;
-+
-+ BT_DBG("%s -> %s", batostr(src), batostr(dst));
-+
-+ read_lock_bh(&hdev_list_lock);
-+
-+ list_for_each(p, &hdev_list) {
-+ struct hci_dev *d;
-+ d = list_entry(p, struct hci_dev, list);
-+
-+ if (!test_bit(HCI_UP, &d->flags))
-+ continue;
-+
-+ /* Simple routing:
-+ * No source address - find interface with bdaddr != dst
-+ * Source address - find interface with bdaddr == src
-+ */
-+
-+ if (use_src) {
-+ if (!bacmp(&d->bdaddr, src)) {
-+ hdev = d; break;
-+ }
-+ } else {
-+ if (bacmp(&d->bdaddr, dst)) {
-+ hdev = d; break;
-+ }
-+ }
-+ }
-+
-+ if (hdev)
-+ hci_dev_hold(hdev);
-+
-+ read_unlock_bh(&hdev_list_lock);
-+ return hdev;
-+}
-+
-+/* Create SCO or ACL connection.
-+ * Device _must_ be locked */
-+struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
-+{
-+ struct hci_conn *acl;
-+
-+ BT_DBG("%s dst %s", hdev->name, batostr(dst));
-+
-+ if (!(acl = conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
-+ if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
-+ return NULL;
-+ }
-+
-+ hci_conn_hold(acl);
-+
-+ if (acl->state == BT_OPEN || acl->state == BT_CLOSED)
-+ hci_acl_connect(acl);
-+
-+ if (type == SCO_LINK) {
-+ struct hci_conn *sco;
-+
-+ if (!(sco = conn_hash_lookup_ba(hdev, SCO_LINK, dst))) {
-+ if (!(sco = hci_conn_add(hdev, SCO_LINK, dst))) {
-+ hci_conn_put(acl);
-+ return NULL;
-+ }
-+ }
-+ acl->link = sco;
-+ sco->link = acl;
-+
-+ hci_conn_hold(sco);
-+
-+ if (acl->state == BT_CONNECTED &&
-+ (sco->state == BT_OPEN || sco->state == BT_CLOSED))
-+ hci_add_sco(sco, acl->handle);
-+
-+ return sco;
-+ } else {
-+ return acl;
-+ }
-+}
-+
-+/* Authenticate remote device */
-+int hci_conn_auth(struct hci_conn *conn)
-+{
-+ BT_DBG("conn %p", conn);
-+
-+ if (conn->link_mode & HCI_LM_AUTH)
-+ return 1;
-+
-+ if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
-+ auth_requested_cp ar;
-+ ar.handle = __cpu_to_le16(conn->handle);
-+ hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_AUTH_REQUESTED,
-+ AUTH_REQUESTED_CP_SIZE, &ar);
-+ }
-+ return 0;
-+}
-+
-+/* Enable encryption */
-+int hci_conn_encrypt(struct hci_conn *conn)
-+{
-+ BT_DBG("conn %p", conn);
-+
-+ if (conn->link_mode & HCI_LM_ENCRYPT)
-+ return 1;
-+
-+ if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
-+ return 0;
-+
-+ if (hci_conn_auth(conn)) {
-+ set_conn_encrypt_cp ce;
-+ ce.handle = __cpu_to_le16(conn->handle);
-+ ce.encrypt = 1;
-+ hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT,
-+ SET_CONN_ENCRYPT_CP_SIZE, &ce);
-+ }
-+ return 0;
-+}
-+
-+/* Drop all connection on the device */
-+void hci_conn_hash_flush(struct hci_dev *hdev)
-+{
-+ struct conn_hash *h = &hdev->conn_hash;
-+ struct list_head *p;
-+
-+ BT_DBG("hdev %s", hdev->name);
-+
-+ p = h->list.next;
-+ while (p != &h->list) {
-+ struct hci_conn *c;
-+
-+ c = list_entry(p, struct hci_conn, list);
-+ p = p->next;
-+
-+ c->state = BT_CLOSED;
-+
-+ hci_proto_disconn_ind(c, 0x16);
-+ hci_conn_del(c);
-+ }
-+}
-+
-+int hci_get_conn_list(unsigned long arg)
-+{
-+ struct hci_conn_list_req req, *cl;
-+ struct hci_conn_info *ci;
-+ struct hci_dev *hdev;
-+ struct list_head *p;
-+ int n = 0, size;
-+
-+ if (copy_from_user(&req, (void *) arg, sizeof(req)))
-+ return -EFAULT;
-+
-+ if (!(hdev = hci_dev_get(req.dev_id)))
-+ return -ENODEV;
-+
-+ size = req.conn_num * sizeof(struct hci_conn_info) + sizeof(req);
-+
-+ if (verify_area(VERIFY_WRITE, (void *)arg, size))
-+ return -EFAULT;
-+
-+ if (!(cl = (void *) kmalloc(size, GFP_KERNEL)))
-+ return -ENOMEM;
-+ ci = cl->conn_info;
-+
-+ hci_dev_lock_bh(hdev);
-+ list_for_each(p, &hdev->conn_hash.list) {
-+ register struct hci_conn *c;
-+ c = list_entry(p, struct hci_conn, list);
-+
-+ bacpy(&(ci + n)->bdaddr, &c->dst);
-+ (ci + n)->handle = c->handle;
-+ (ci + n)->type = c->type;
-+ (ci + n)->out = c->out;
-+ (ci + n)->state = c->state;
-+ (ci + n)->link_mode = c->link_mode;
-+ n++;
-+ }
-+ hci_dev_unlock_bh(hdev);
-+
-+ cl->dev_id = hdev->id;
-+ cl->conn_num = n;
-+ size = n * sizeof(struct hci_conn_info) + sizeof(req);
-+
-+ hci_dev_put(hdev);
-+
-+ copy_to_user((void *) arg, cl, size);
-+ kfree(cl);
-+
-+ return 0;
-+}
-+
-+int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg)
-+{
-+ struct hci_conn_info_req req;
-+ struct hci_conn_info ci;
-+ struct hci_conn *conn;
-+ char *ptr = (void *) arg + sizeof(req);
-+
-+ if (copy_from_user(&req, (void *) arg, sizeof(req)))
-+ return -EFAULT;
-+
-+ if (verify_area(VERIFY_WRITE, ptr, sizeof(ci)))
-+ return -EFAULT;
-+
-+ hci_dev_lock_bh(hdev);
-+ conn = conn_hash_lookup_ba(hdev, req.type, &req.bdaddr);
-+ if (conn) {
-+ bacpy(&ci.bdaddr, &conn->dst);
-+ ci.handle = conn->handle;
-+ ci.type = conn->type;
-+ ci.out = conn->out;
-+ ci.state = conn->state;
-+ ci.link_mode = conn->link_mode;
-+ }
-+ hci_dev_unlock_bh(hdev);
-+
-+ if (!conn)
-+ return -ENOENT;
-+
-+ copy_to_user(ptr, &ci, sizeof(ci));
-+ return 0;
-+}
---- linux/net/bluetooth/hci_core.c~bluetooth-2.4.18-mh11 2001-11-09 23:21:21.000000000 +0100
-+++ linux/net/bluetooth/hci_core.c 2004-01-25 23:37:39.000000000 +0100
-@@ -25,11 +25,12 @@
- /*
- * BlueZ HCI Core.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
- #include <linux/module.h>
-+#include <linux/kmod.h>
-
- #include <linux/types.h>
- #include <linux/errno.h>
-@@ -50,12 +51,11 @@
- #include <asm/unaligned.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
-
- #ifndef HCI_CORE_DEBUG
--#undef DBG
--#define DBG( A... )
-+#undef BT_DBG
-+#define BT_DBG( A... )
- #endif
-
- static void hci_cmd_task(unsigned long arg);
-@@ -63,279 +63,69 @@
- static void hci_tx_task(unsigned long arg);
- static void hci_notify(struct hci_dev *hdev, int event);
-
--static rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
-+rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
-
- /* HCI device list */
--struct hci_dev *hdev_list[HCI_MAX_DEV];
--spinlock_t hdev_list_lock;
--#define GET_HDEV(a) (hdev_list[a])
-+LIST_HEAD(hdev_list);
-+rwlock_t hdev_list_lock = RW_LOCK_UNLOCKED;
-
--/* HCI protocol list */
--struct hci_proto *hproto_list[HCI_MAX_PROTO];
--#define GET_HPROTO(a) (hproto_list[a])
-+/* HCI protocols */
-+#define HCI_MAX_PROTO 2
-+struct hci_proto *hci_proto[HCI_MAX_PROTO];
-
- /* HCI notifiers list */
--struct notifier_block *hci_dev_notifier;
--
--/* HCI device notifications */
--int hci_register_notifier(struct notifier_block *nb)
--{
-- int err, i;
-- struct hci_dev *hdev;
--
-- if ((err = notifier_chain_register(&hci_dev_notifier, nb)))
-- return err;
--
-- /* Notify about already registered devices */
-- spin_lock(&hdev_list_lock);
-- for (i = 0; i < HCI_MAX_DEV; i++) {
-- if (!(hdev = GET_HDEV(i)))
-- continue;
-- if (hdev->flags & HCI_UP)
-- (*nb->notifier_call)(nb, HCI_DEV_UP, hdev);
-- }
-- spin_unlock(&hdev_list_lock);
--
-- return 0;
--}
--
--int hci_unregister_notifier(struct notifier_block *nb)
--{
-- return notifier_chain_unregister(&hci_dev_notifier, nb);
--}
--
--static inline void hci_notify(struct hci_dev *hdev, int event)
--{
-- notifier_call_chain(&hci_dev_notifier, event, hdev);
--}
--
--/* Get HCI device by index (device is locked on return)*/
--struct hci_dev *hci_dev_get(int index)
--{
-- struct hci_dev *hdev;
-- DBG("%d", index);
--
-- if (index < 0 || index >= HCI_MAX_DEV)
-- return NULL;
--
-- spin_lock(&hdev_list_lock);
-- if ((hdev = GET_HDEV(index)))
-- hci_dev_hold(hdev);
-- spin_unlock(&hdev_list_lock);
--
-- return hdev;
--}
--
--/* Flush inquiry cache */
--void inquiry_cache_flush(struct inquiry_cache *cache)
--{
-- struct inquiry_entry *next = cache->list, *e;
--
-- DBG("cache %p", cache);
--
-- cache->list = NULL;
-- while ((e = next)) {
-- next = e->next;
-- kfree(e);
-- }
--}
--
--/* Lookup by bdaddr.
-- * Cache must be locked. */
--static struct inquiry_entry * __inquiry_cache_lookup(struct inquiry_cache *cache, bdaddr_t *bdaddr)
--{
-- struct inquiry_entry *e;
--
-- DBG("cache %p, %s", cache, batostr(bdaddr));
--
-- for (e = cache->list; e; e = e->next)
-- if (!bacmp(&e->info.bdaddr, bdaddr))
-- break;
--
-- return e;
--}
--
--static void inquiry_cache_update(struct inquiry_cache *cache, inquiry_info *info)
--{
-- struct inquiry_entry *e;
--
-- DBG("cache %p, %s", cache, batostr(&info->bdaddr));
--
-- inquiry_cache_lock(cache);
--
-- if (!(e = __inquiry_cache_lookup(cache, &info->bdaddr))) {
-- /* Entry not in the cache. Add new one. */
-- if (!(e = kmalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
-- goto unlock;
-- memset(e, 0, sizeof(struct inquiry_entry));
-- e->next = cache->list;
-- cache->list = e;
-- }
--
-- memcpy(&e->info, info, sizeof(inquiry_info));
-- e->timestamp = jiffies;
-- cache->timestamp = jiffies;
--unlock:
-- inquiry_cache_unlock(cache);
--}
--
--static int inquiry_cache_dump(struct inquiry_cache *cache, int num, __u8 *buf)
--{
-- inquiry_info *info = (inquiry_info *) buf;
-- struct inquiry_entry *e;
-- int copied = 0;
--
-- inquiry_cache_lock(cache);
--
-- for (e = cache->list; e && copied < num; e = e->next, copied++)
-- memcpy(info++, &e->info, sizeof(inquiry_info));
-+static struct notifier_block *hci_notifier;
-
-- inquiry_cache_unlock(cache);
-
-- DBG("cache %p, copied %d", cache, copied);
-- return copied;
--}
-+/* ---- HCI notifications ---- */
-
--/* --------- BaseBand connections --------- */
--static struct hci_conn *hci_conn_add(struct hci_dev *hdev, __u16 handle, __u8 type, bdaddr_t *dst)
-+int hci_register_notifier(struct notifier_block *nb)
- {
-- struct hci_conn *conn;
--
-- DBG("%s handle %d dst %s", hdev->name, handle, batostr(dst));
--
-- if ( conn_hash_lookup(&hdev->conn_hash, handle)) {
-- ERR("%s handle 0x%x already exists", hdev->name, handle);
-- return NULL;
-- }
--
-- if (!(conn = kmalloc(sizeof(struct hci_conn), GFP_ATOMIC)))
-- return NULL;
-- memset(conn, 0, sizeof(struct hci_conn));
--
-- bacpy(&conn->dst, dst);
-- conn->handle = handle;
-- conn->type = type;
-- conn->hdev = hdev;
--
-- skb_queue_head_init(&conn->data_q);
--
-- hci_dev_hold(hdev);
-- conn_hash_add(&hdev->conn_hash, handle, conn);
--
-- return conn;
-+ return notifier_chain_register(&hci_notifier, nb);
- }
-
--static int hci_conn_del(struct hci_dev *hdev, struct hci_conn *conn)
-+int hci_unregister_notifier(struct notifier_block *nb)
- {
-- DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
--
-- conn_hash_del(&hdev->conn_hash, conn);
-- hci_dev_put(hdev);
--
-- /* Unacked frames */
-- hdev->acl_cnt += conn->sent;
--
-- skb_queue_purge(&conn->data_q);
--
-- kfree(conn);
-- return 0;
-+ return notifier_chain_unregister(&hci_notifier, nb);
- }
-
--/* Drop all connection on the device */
--static void hci_conn_hash_flush(struct hci_dev *hdev)
-+void hci_notify(struct hci_dev *hdev, int event)
- {
-- struct conn_hash *h = &hdev->conn_hash;
-- struct hci_proto *hp;
-- struct list_head *p;
--
-- DBG("hdev %s", hdev->name);
--
-- p = h->list.next;
-- while (p != &h->list) {
-- struct hci_conn *c;
--
-- c = list_entry(p, struct hci_conn, list);
-- p = p->next;
--
-- if (c->type == ACL_LINK) {
-- /* ACL link notify L2CAP layer */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
-- hp->disconn_ind(c, 0x16);
-- } else {
-- /* SCO link (no notification) */
-- }
--
-- hci_conn_del(hdev, c);
-- }
-+ notifier_call_chain(&hci_notifier, event, hdev);
- }
-
--int hci_connect(struct hci_dev *hdev, bdaddr_t *bdaddr)
--{
-- struct inquiry_cache *cache = &hdev->inq_cache;
-- struct inquiry_entry *e;
-- create_conn_cp cc;
-- __u16 clock_offset;
--
-- DBG("%s bdaddr %s", hdev->name, batostr(bdaddr));
--
-- if (!(hdev->flags & HCI_UP))
-- return -ENODEV;
--
-- inquiry_cache_lock_bh(cache);
--
-- if (!(e = __inquiry_cache_lookup(cache, bdaddr)) || inquiry_entry_age(e) > INQUIRY_ENTRY_AGE_MAX) {
-- cc.pscan_rep_mode = 0;
-- cc.pscan_mode = 0;
-- clock_offset = 0;
-- } else {
-- cc.pscan_rep_mode = e->info.pscan_rep_mode;
-- cc.pscan_mode = e->info.pscan_mode;
-- clock_offset = __le16_to_cpu(e->info.clock_offset) & 0x8000;
-- }
--
-- inquiry_cache_unlock_bh(cache);
--
-- bacpy(&cc.bdaddr, bdaddr);
-- cc.pkt_type = __cpu_to_le16(hdev->pkt_type);
-- cc.clock_offset = __cpu_to_le16(clock_offset);
--
-- if (lmp_rswitch_capable(hdev))
-- cc.role_switch = 0x01;
-- else
-- cc.role_switch = 0x00;
--
-- hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, CREATE_CONN_CP_SIZE, &cc);
-+/* ---- HCI hotplug support ---- */
-
-- return 0;
--}
-+#ifdef CONFIG_HOTPLUG
-
--int hci_disconnect(struct hci_conn *conn, __u8 reason)
-+static int hci_run_hotplug(char *dev, char *action)
- {
-- disconnect_cp dc;
--
-- DBG("conn %p handle %d", conn, conn->handle);
-+ char *argv[3], *envp[5], dstr[20], astr[32];
-
-- dc.handle = __cpu_to_le16(conn->handle);
-- dc.reason = reason;
-- hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT, DISCONNECT_CP_SIZE, &dc);
-+ sprintf(dstr, "DEVICE=%s", dev);
-+ sprintf(astr, "ACTION=%s", action);
-
-- return 0;
--}
-+ argv[0] = hotplug_path;
-+ argv[1] = "bluetooth";
-+ argv[2] = NULL;
-
--/* --------- HCI request handling ------------ */
--static inline void hci_req_lock(struct hci_dev *hdev)
--{
-- down(&hdev->req_lock);
-+ envp[0] = "HOME=/";
-+ envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-+ envp[2] = dstr;
-+ envp[3] = astr;
-+ envp[4] = NULL;
-+
-+ return call_usermodehelper(argv[0], argv, envp);
- }
-+#else
-+#define hci_run_hotplug(A...)
-+#endif
-
--static inline void hci_req_unlock(struct hci_dev *hdev)
--{
-- up(&hdev->req_lock);
--}
-+/* ---- HCI requests ---- */
-
--static inline void hci_req_complete(struct hci_dev *hdev, int result)
-+void hci_req_complete(struct hci_dev *hdev, int result)
- {
-- DBG("%s result 0x%2.2x", hdev->name, result);
-+ BT_DBG("%s result 0x%2.2x", hdev->name, result);
-
- if (hdev->req_status == HCI_REQ_PEND) {
- hdev->req_result = result;
-@@ -344,9 +134,9 @@
- }
- }
-
--static inline void hci_req_cancel(struct hci_dev *hdev, int err)
-+void hci_req_cancel(struct hci_dev *hdev, int err)
- {
-- DBG("%s err 0x%2.2x", hdev->name, err);
-+ BT_DBG("%s err 0x%2.2x", hdev->name, err);
-
- if (hdev->req_status == HCI_REQ_PEND) {
- hdev->req_result = err;
-@@ -356,23 +146,22 @@
- }
-
- /* Execute request and wait for completion. */
--static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
-- unsigned long opt, __u32 timeout)
-+static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), unsigned long opt, __u32 timeout)
- {
- DECLARE_WAITQUEUE(wait, current);
- int err = 0;
-
-- DBG("%s start", hdev->name);
-+ BT_DBG("%s start", hdev->name);
-
- hdev->req_status = HCI_REQ_PEND;
-
- add_wait_queue(&hdev->req_wait_q, &wait);
-- current->state = TASK_INTERRUPTIBLE;
-+ set_current_state(TASK_INTERRUPTIBLE);
-
- req(hdev, opt);
- schedule_timeout(timeout);
-
-- current->state = TASK_RUNNING;
-+ set_current_state(TASK_RUNNING);
- remove_wait_queue(&hdev->req_wait_q, &wait);
-
- if (signal_pending(current))
-@@ -394,7 +183,7 @@
-
- hdev->req_status = hdev->req_result = 0;
-
-- DBG("%s end: err %d", hdev->name, err);
-+ BT_DBG("%s end: err %d", hdev->name, err);
-
- return err;
- }
-@@ -412,10 +201,9 @@
- return ret;
- }
-
--/* --------- HCI requests ---------- */
- static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
- {
-- DBG("%s %ld", hdev->name, opt);
-+ BT_DBG("%s %ld", hdev->name, opt);
-
- /* Reset device */
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
-@@ -423,10 +211,10 @@
-
- static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
- {
-- set_event_flt_cp ec;
-+ set_event_flt_cp ef;
- __u16 param;
-
-- DBG("%s %ld", hdev->name, opt);
-+ BT_DBG("%s %ld", hdev->name, opt);
-
- /* Mandatory initialization */
-
-@@ -436,14 +224,27 @@
- /* Read Buffer Size (ACL mtu, max pkt, etc.) */
- hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
-
-+#if 0
-+ /* Host buffer size */
-+ {
-+ host_buffer_size_cp bs;
-+ bs.acl_mtu = __cpu_to_le16(HCI_MAX_ACL_SIZE);
-+ bs.sco_mtu = HCI_MAX_SCO_SIZE;
-+ bs.acl_max_pkt = __cpu_to_le16(0xffff);
-+ bs.sco_max_pkt = __cpu_to_le16(0xffff);
-+ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_HOST_BUFFER_SIZE,
-+ HOST_BUFFER_SIZE_CP_SIZE, &bs);
-+ }
-+#endif
-+
- /* Read BD Address */
- hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, NULL);
-
- /* Optional initialization */
-
- /* Clear Event Filters */
-- ec.flt_type = FLT_CLEAR_ALL;
-- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &ec);
-+ ef.flt_type = FLT_CLEAR_ALL;
-+ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &ef);
-
- /* Page timeout ~20 secs */
- param = __cpu_to_le16(0x8000);
-@@ -458,7 +259,7 @@
- {
- __u8 scan = opt;
-
-- DBG("%s %x", hdev->name, scan);
-+ BT_DBG("%s %x", hdev->name, scan);
-
- /* Inquiry and Page scans */
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, &scan);
-@@ -468,27 +269,190 @@
- {
- __u8 auth = opt;
-
-- DBG("%s %x", hdev->name, auth);
-+ BT_DBG("%s %x", hdev->name, auth);
-
- /* Authentication */
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE, 1, &auth);
- }
-
-+static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
-+{
-+ __u8 encrypt = opt;
-+
-+ BT_DBG("%s %x", hdev->name, encrypt);
-+
-+ /* Authentication */
-+ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE, 1, &encrypt);
-+}
-+
-+/* Get HCI device by index.
-+ * Device is locked on return. */
-+struct hci_dev *hci_dev_get(int index)
-+{
-+ struct hci_dev *hdev;
-+ struct list_head *p;
-+
-+ BT_DBG("%d", index);
-+
-+ if (index < 0)
-+ return NULL;
-+
-+ read_lock(&hdev_list_lock);
-+ list_for_each(p, &hdev_list) {
-+ hdev = list_entry(p, struct hci_dev, list);
-+ if (hdev->id == index) {
-+ hci_dev_hold(hdev);
-+ goto done;
-+ }
-+ }
-+ hdev = NULL;
-+done:
-+ read_unlock(&hdev_list_lock);
-+ return hdev;
-+}
-+
-+/* ---- Inquiry support ---- */
-+void inquiry_cache_flush(struct hci_dev *hdev)
-+{
-+ struct inquiry_cache *cache = &hdev->inq_cache;
-+ struct inquiry_entry *next = cache->list, *e;
-+
-+ BT_DBG("cache %p", cache);
-+
-+ cache->list = NULL;
-+ while ((e = next)) {
-+ next = e->next;
-+ kfree(e);
-+ }
-+}
-+
-+struct inquiry_entry *inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
-+{
-+ struct inquiry_cache *cache = &hdev->inq_cache;
-+ struct inquiry_entry *e;
-+
-+ BT_DBG("cache %p, %s", cache, batostr(bdaddr));
-+
-+ for (e = cache->list; e; e = e->next)
-+ if (!bacmp(&e->info.bdaddr, bdaddr))
-+ break;
-+ return e;
-+}
-+
-+void inquiry_cache_update(struct hci_dev *hdev, inquiry_info *info)
-+{
-+ struct inquiry_cache *cache = &hdev->inq_cache;
-+ struct inquiry_entry *e;
-+
-+ BT_DBG("cache %p, %s", cache, batostr(&info->bdaddr));
-+
-+ if (!(e = inquiry_cache_lookup(hdev, &info->bdaddr))) {
-+ /* Entry not in the cache. Add new one. */
-+ if (!(e = kmalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
-+ return;
-+ memset(e, 0, sizeof(struct inquiry_entry));
-+ e->next = cache->list;
-+ cache->list = e;
-+ }
-+
-+ memcpy(&e->info, info, sizeof(inquiry_info));
-+ e->timestamp = jiffies;
-+ cache->timestamp = jiffies;
-+}
-+
-+int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
-+{
-+ struct inquiry_cache *cache = &hdev->inq_cache;
-+ inquiry_info *info = (inquiry_info *) buf;
-+ struct inquiry_entry *e;
-+ int copied = 0;
-+
-+ for (e = cache->list; e && copied < num; e = e->next, copied++)
-+ memcpy(info++, &e->info, sizeof(inquiry_info));
-+
-+ BT_DBG("cache %p, copied %d", cache, copied);
-+ return copied;
-+}
-+
- static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
- {
- struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
- inquiry_cp ic;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s", hdev->name);
-+
-+ if (test_bit(HCI_INQUIRY, &hdev->flags))
-+ return;
-
- /* Start Inquiry */
- memcpy(&ic.lap, &ir->lap, 3);
-- ic.lenght = ir->length;
-+ ic.length = ir->length;
- ic.num_rsp = ir->num_rsp;
- hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, &ic);
- }
-
--/* HCI ioctl helpers */
-+int hci_inquiry(unsigned long arg)
-+{
-+ struct hci_inquiry_req ir;
-+ struct hci_dev *hdev;
-+ int err = 0, do_inquiry = 0, max_rsp;
-+ long timeo;
-+ __u8 *buf, *ptr;
-+
-+ ptr = (void *) arg;
-+ if (copy_from_user(&ir, ptr, sizeof(ir)))
-+ return -EFAULT;
-+
-+ if (!(hdev = hci_dev_get(ir.dev_id)))
-+ return -ENODEV;
-+
-+ hci_dev_lock_bh(hdev);
-+ if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
-+ inquiry_cache_empty(hdev) ||
-+ ir.flags & IREQ_CACHE_FLUSH) {
-+ inquiry_cache_flush(hdev);
-+ do_inquiry = 1;
-+ }
-+ hci_dev_unlock_bh(hdev);
-+
-+ timeo = ir.length * 2 * HZ;
-+ if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
-+ goto done;
-+
-+ /* for unlimited number of responses we will use buffer with 255 entries */
-+ max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
-+
-+ /* cache_dump can't sleep. Therefore we allocate temp buffer and then
-+ * copy it to the user space.
-+ */
-+ if (!(buf = kmalloc(sizeof(inquiry_info) * max_rsp, GFP_KERNEL))) {
-+ err = -ENOMEM;
-+ goto done;
-+ }
-+
-+ hci_dev_lock_bh(hdev);
-+ ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
-+ hci_dev_unlock_bh(hdev);
-+
-+ BT_DBG("num_rsp %d", ir.num_rsp);
-+
-+ if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) +
-+ (sizeof(inquiry_info) * ir.num_rsp))) {
-+ copy_to_user(ptr, &ir, sizeof(ir));
-+ ptr += sizeof(ir);
-+ copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
-+ } else
-+ err = -EFAULT;
-+
-+ kfree(buf);
-+
-+done:
-+ hci_dev_put(hdev);
-+ return err;
-+}
-+
-+/* ---- HCI ioctl helpers ---- */
-+
- int hci_dev_open(__u16 dev)
- {
- struct hci_dev *hdev;
-@@ -497,11 +461,11 @@
- if (!(hdev = hci_dev_get(dev)))
- return -ENODEV;
-
-- DBG("%s %p", hdev->name, hdev);
-+ BT_DBG("%s %p", hdev->name, hdev);
-
- hci_req_lock(hdev);
-
-- if (hdev->flags & HCI_UP) {
-+ if (test_bit(HCI_UP, &hdev->flags)) {
- ret = -EALREADY;
- goto done;
- }
-@@ -511,18 +475,18 @@
- goto done;
- }
-
-- if (hdev->flags & HCI_NORMAL) {
-+ if (!test_bit(HCI_RAW, &hdev->flags)) {
- atomic_set(&hdev->cmd_cnt, 1);
-- hdev->flags |= HCI_INIT;
-+ set_bit(HCI_INIT, &hdev->flags);
-
- //__hci_request(hdev, hci_reset_req, 0, HZ);
- ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
-
-- hdev->flags &= ~HCI_INIT;
-+ clear_bit(HCI_INIT, &hdev->flags);
- }
-
- if (!ret) {
-- hdev->flags |= HCI_UP;
-+ set_bit(HCI_UP, &hdev->flags);
- hci_notify(hdev, HCI_DEV_UP);
- } else {
- /* Init failed, cleanup */
-@@ -542,42 +506,36 @@
- }
-
- hdev->close(hdev);
-+ hdev->flags = 0;
- }
-
- done:
- hci_req_unlock(hdev);
- hci_dev_put(hdev);
--
- return ret;
- }
-
--int hci_dev_close(__u16 dev)
-+static int hci_dev_do_close(struct hci_dev *hdev)
- {
-- struct hci_dev *hdev;
--
-- if (!(hdev = hci_dev_get(dev)))
-- return -ENODEV;
--
-- DBG("%s %p", hdev->name, hdev);
-+ BT_DBG("%s %p", hdev->name, hdev);
-
- hci_req_cancel(hdev, ENODEV);
- hci_req_lock(hdev);
-
-- if (!(hdev->flags & HCI_UP))
-- goto done;
-+ if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
-+ hci_req_unlock(hdev);
-+ return 0;
-+ }
-
- /* Kill RX and TX tasks */
- tasklet_kill(&hdev->rx_task);
- tasklet_kill(&hdev->tx_task);
-
-- inquiry_cache_flush(&hdev->inq_cache);
--
-+ hci_dev_lock_bh(hdev);
-+ inquiry_cache_flush(hdev);
- hci_conn_hash_flush(hdev);
--
-- /* Clear flags */
-- hdev->flags &= HCI_SOCK;
-- hdev->flags |= HCI_NORMAL;
--
-+ hci_dev_unlock_bh(hdev);
-+
- hci_notify(hdev, HCI_DEV_DOWN);
-
- if (hdev->flush)
-@@ -586,9 +544,9 @@
- /* Reset device */
- skb_queue_purge(&hdev->cmd_q);
- atomic_set(&hdev->cmd_cnt, 1);
-- hdev->flags |= HCI_INIT;
-- __hci_request(hdev, hci_reset_req, 0, HZ);
-- hdev->flags &= ~HCI_INIT;
-+ set_bit(HCI_INIT, &hdev->flags);
-+ __hci_request(hdev, hci_reset_req, 0, HZ/4);
-+ clear_bit(HCI_INIT, &hdev->flags);
-
- /* Kill cmd task */
- tasklet_kill(&hdev->cmd_task);
-@@ -605,17 +563,28 @@
- }
-
- /* After this point our queues are empty
-- * and no tasks are scheduled.
-- */
-+ * and no tasks are scheduled. */
- hdev->close(hdev);
-
--done:
-- hci_req_unlock(hdev);
-- hci_dev_put(hdev);
-+ /* Clear flags */
-+ hdev->flags = 0;
-
-+ hci_req_unlock(hdev);
- return 0;
- }
-
-+int hci_dev_close(__u16 dev)
-+{
-+ struct hci_dev *hdev;
-+ int err;
-+
-+ if (!(hdev = hci_dev_get(dev)))
-+ return -ENODEV;
-+ err = hci_dev_do_close(hdev);
-+ hci_dev_put(hdev);
-+ return err;
-+}
-+
- int hci_dev_reset(__u16 dev)
- {
- struct hci_dev *hdev;
-@@ -627,16 +596,17 @@
- hci_req_lock(hdev);
- tasklet_disable(&hdev->tx_task);
-
-- if (!(hdev->flags & HCI_UP))
-+ if (!test_bit(HCI_UP, &hdev->flags))
- goto done;
-
- /* Drop queues */
- skb_queue_purge(&hdev->rx_q);
- skb_queue_purge(&hdev->cmd_q);
-
-- inquiry_cache_flush(&hdev->inq_cache);
--
-+ hci_dev_lock_bh(hdev);
-+ inquiry_cache_flush(hdev);
- hci_conn_hash_flush(hdev);
-+ hci_dev_unlock_bh(hdev);
-
- if (hdev->flush)
- hdev->flush(hdev);
-@@ -650,7 +620,6 @@
- tasklet_enable(&hdev->tx_task);
- hci_req_unlock(hdev);
- hci_dev_put(hdev);
--
- return ret;
- }
-
-@@ -669,30 +638,11 @@
- return ret;
- }
-
--int hci_dev_setauth(unsigned long arg)
--{
-- struct hci_dev *hdev;
-- struct hci_dev_req dr;
-- int ret = 0;
--
-- if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
-- return -EFAULT;
--
-- if (!(hdev = hci_dev_get(dr.dev_id)))
-- return -ENODEV;
--
-- ret = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
--
-- hci_dev_put(hdev);
--
-- return ret;
--}
--
--int hci_dev_setscan(unsigned long arg)
-+int hci_dev_cmd(unsigned int cmd, unsigned long arg)
- {
- struct hci_dev *hdev;
- struct hci_dev_req dr;
-- int ret = 0;
-+ int err = 0;
-
- if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
- return -EFAULT;
-@@ -700,48 +650,78 @@
- if (!(hdev = hci_dev_get(dr.dev_id)))
- return -ENODEV;
-
-- ret = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
--
-- hci_dev_put(hdev);
-+ switch (cmd) {
-+ case HCISETAUTH:
-+ err = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
-+ break;
-
-- return ret;
--}
-+ case HCISETENCRYPT:
-+ if (!lmp_encrypt_capable(hdev)) {
-+ err = -EOPNOTSUPP;
-+ break;
-+ }
-
--int hci_dev_setptype(unsigned long arg)
--{
-- struct hci_dev *hdev;
-- struct hci_dev_req dr;
-- int ret = 0;
-+ if (!test_bit(HCI_AUTH, &hdev->flags)) {
-+ /* Auth must be enabled first */
-+ err = hci_request(hdev, hci_auth_req,
-+ dr.dev_opt, HCI_INIT_TIMEOUT);
-+ if (err)
-+ break;
-+ }
-+
-+ err = hci_request(hdev, hci_encrypt_req,
-+ dr.dev_opt, HCI_INIT_TIMEOUT);
-+ break;
-+
-+ case HCISETSCAN:
-+ err = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
-+ break;
-+
-+ case HCISETPTYPE:
-+ hdev->pkt_type = (__u16) dr.dev_opt;
-+ break;
-+
-+ case HCISETLINKPOL:
-+ hdev->link_policy = (__u16) dr.dev_opt;
-+ break;
-
-- if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
-- return -EFAULT;
-+ case HCISETLINKMODE:
-+ hdev->link_mode = ((__u16) dr.dev_opt) & (HCI_LM_MASTER | HCI_LM_ACCEPT);
-+ break;
-
-- if (!(hdev = hci_dev_get(dr.dev_id)))
-- return -ENODEV;
-+ case HCISETACLMTU:
-+ hdev->acl_mtu = *((__u16 *)&dr.dev_opt + 1);
-+ hdev->acl_pkts = *((__u16 *)&dr.dev_opt + 0);
-+ break;
-
-- hdev->pkt_type = (__u16) dr.dev_opt;
-+ case HCISETSCOMTU:
-+ hdev->sco_mtu = *((__u16 *)&dr.dev_opt + 1);
-+ hdev->sco_pkts = *((__u16 *)&dr.dev_opt + 0);
-+ break;
-
-+ default:
-+ err = -EINVAL;
-+ break;
-+ }
- hci_dev_put(hdev);
--
-- return ret;
-+ return err;
- }
-
--int hci_dev_list(unsigned long arg)
-+int hci_get_dev_list(unsigned long arg)
- {
- struct hci_dev_list_req *dl;
- struct hci_dev_req *dr;
-- struct hci_dev *hdev;
-- int i, n, size;
-+ struct list_head *p;
-+ int n = 0, size;
- __u16 dev_num;
-
- if (get_user(dev_num, (__u16 *) arg))
- return -EFAULT;
-
-- /* Avoid long loop, overflow */
-- if (dev_num > 2048)
-+ if (!dev_num)
- return -EINVAL;
-
-- size = dev_num * sizeof(struct hci_dev_req) + sizeof(__u16);
-+ size = dev_num * sizeof(*dr) + sizeof(*dl);
-
- if (verify_area(VERIFY_WRITE, (void *) arg, size))
- return -EFAULT;
-@@ -750,25 +730,27 @@
- return -ENOMEM;
- dr = dl->dev_req;
-
-- spin_lock_bh(&hdev_list_lock);
-- for (i = 0, n = 0; i < HCI_MAX_DEV && n < dev_num; i++) {
-- if ((hdev = hdev_list[i])) {
-- (dr + n)->dev_id = hdev->id;
-- (dr + n)->dev_opt = hdev->flags;
-- n++;
-- }
-+ read_lock_bh(&hdev_list_lock);
-+ list_for_each(p, &hdev_list) {
-+ struct hci_dev *hdev;
-+ hdev = list_entry(p, struct hci_dev, list);
-+ (dr + n)->dev_id = hdev->id;
-+ (dr + n)->dev_opt = hdev->flags;
-+ if (++n >= dev_num)
-+ break;
- }
-- spin_unlock_bh(&hdev_list_lock);
-+ read_unlock_bh(&hdev_list_lock);
-
- dl->dev_num = n;
-- size = n * sizeof(struct hci_dev_req) + sizeof(__u16);
-+ size = n * sizeof(*dr) + sizeof(*dl);
-
- copy_to_user((void *) arg, dl, size);
-+ kfree(dl);
-
- return 0;
- }
-
--int hci_dev_info(unsigned long arg)
-+int hci_get_dev_info(unsigned long arg)
- {
- struct hci_dev *hdev;
- struct hci_dev_info di;
-@@ -786,9 +768,11 @@
- di.flags = hdev->flags;
- di.pkt_type = hdev->pkt_type;
- di.acl_mtu = hdev->acl_mtu;
-- di.acl_max = hdev->acl_max;
-+ di.acl_pkts = hdev->acl_pkts;
- di.sco_mtu = hdev->sco_mtu;
-- di.sco_max = hdev->sco_max;
-+ di.sco_pkts = hdev->sco_pkts;
-+ di.link_policy = hdev->link_policy;
-+ di.link_mode = hdev->link_mode;
-
- memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
- memcpy(&di.features, &hdev->features, sizeof(di.features));
-@@ -801,258 +785,168 @@
- return err;
- }
-
--__u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode)
--{
-- __u32 omode = hdev->flags & HCI_MODE_MASK;
--
-- hdev->flags &= ~HCI_MODE_MASK;
-- hdev->flags |= (mode & HCI_MODE_MASK);
-
-- return omode;
--}
--
--__u32 hci_dev_getmode(struct hci_dev *hdev)
--{
-- return hdev->flags & HCI_MODE_MASK;
--}
-+/* ---- Interface to HCI drivers ---- */
-
--int hci_conn_list(unsigned long arg)
-+/* Register HCI device */
-+int hci_register_dev(struct hci_dev *hdev)
- {
-- struct hci_conn_list_req req, *cl;
-- struct hci_conn_info *ci;
-- struct hci_dev *hdev;
-- struct list_head *p;
-- int n = 0, size;
--
-- if (copy_from_user(&req, (void *) arg, sizeof(req)))
-- return -EFAULT;
-+ struct list_head *head = &hdev_list, *p;
-+ int id = 0;
-
-- if (!(hdev = hci_dev_get(req.dev_id)))
-- return -ENODEV;
-+ BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
-
-- /* Set a limit to avoid overlong loops, and also numeric overflow - AC */
-- if(req.conn_num < 2048)
-+ if (!hdev->open || !hdev->close || !hdev->destruct)
- return -EINVAL;
--
-- size = req.conn_num * sizeof(struct hci_conn_info) + sizeof(req);
-
-- if (!(cl = kmalloc(size, GFP_KERNEL)))
-- return -ENOMEM;
-- ci = cl->conn_info;
--
-- local_bh_disable();
-- conn_hash_lock(&hdev->conn_hash);
-- list_for_each(p, &hdev->conn_hash.list) {
-- register struct hci_conn *c;
-- c = list_entry(p, struct hci_conn, list);
-+ write_lock_bh(&hdev_list_lock);
-
-- (ci + n)->handle = c->handle;
-- bacpy(&(ci + n)->bdaddr, &c->dst);
-- n++;
-+ /* Find first available device id */
-+ list_for_each(p, &hdev_list) {
-+ if (list_entry(p, struct hci_dev, list)->id != id)
-+ break;
-+ head = p; id++;
- }
-- conn_hash_unlock(&hdev->conn_hash);
-- local_bh_enable();
--
-- cl->dev_id = hdev->id;
-- cl->conn_num = n;
-- size = n * sizeof(struct hci_conn_info) + sizeof(req);
--
-- hci_dev_put(hdev);
--
-- if(copy_to_user((void *) arg, cl, size))
-- return -EFAULT;
-- return 0;
--}
--
--int hci_inquiry(unsigned long arg)
--{
-- struct inquiry_cache *cache;
-- struct hci_inquiry_req ir;
-- struct hci_dev *hdev;
-- int err = 0, do_inquiry = 0;
-- long timeo;
-- __u8 *buf, *ptr;
--
-- ptr = (void *) arg;
-- if (copy_from_user(&ir, ptr, sizeof(ir)))
-- return -EFAULT;
-+
-+ sprintf(hdev->name, "hci%d", id);
-+ hdev->id = id;
-+ list_add(&hdev->list, head);
-
-- if (!(hdev = hci_dev_get(ir.dev_id)))
-- return -ENODEV;
-+ atomic_set(&hdev->refcnt, 1);
-+ spin_lock_init(&hdev->lock);
-+
-+ hdev->flags = 0;
-+ hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1);
-+ hdev->link_mode = (HCI_LM_ACCEPT);
-
-- cache = &hdev->inq_cache;
-+ tasklet_init(&hdev->cmd_task, hci_cmd_task,(unsigned long) hdev);
-+ tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
-+ tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
-
-- inquiry_cache_lock(cache);
-- if (inquiry_cache_age(cache) > INQUIRY_CACHE_AGE_MAX || ir.flags & IREQ_CACHE_FLUSH) {
-- inquiry_cache_flush(cache);
-- do_inquiry = 1;
-- }
-- inquiry_cache_unlock(cache);
-+ skb_queue_head_init(&hdev->rx_q);
-+ skb_queue_head_init(&hdev->cmd_q);
-+ skb_queue_head_init(&hdev->raw_q);
-
-- /* Limit inquiry time, also avoid overflows */
-+ init_waitqueue_head(&hdev->req_wait_q);
-+ init_MUTEX(&hdev->req_lock);
-
-- if(ir.length > 2048 || ir.num_rsp > 2048)
-- {
-- err = -EINVAL;
-- goto done;
-- }
-+ inquiry_cache_init(hdev);
-
-- timeo = ir.length * 2 * HZ;
-- if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
-- goto done;
-+ conn_hash_init(hdev);
-
-- /* cache_dump can't sleep. Therefore we allocate temp buffer and then
-- * copy it to the user space.
-- */
-- if (!(buf = kmalloc(sizeof(inquiry_info) * ir.num_rsp, GFP_KERNEL))) {
-- err = -ENOMEM;
-- goto done;
-- }
-- ir.num_rsp = inquiry_cache_dump(cache, ir.num_rsp, buf);
-+ memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
-
-- DBG("num_rsp %d", ir.num_rsp);
-+ atomic_set(&hdev->promisc, 0);
-
-- if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) + (sizeof(inquiry_info) * ir.num_rsp))) {
-- copy_to_user(ptr, &ir, sizeof(ir));
-- ptr += sizeof(ir);
-- copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
-- } else
-- err = -EFAULT;
-+ MOD_INC_USE_COUNT;
-
-- kfree(buf);
-+ write_unlock_bh(&hdev_list_lock);
-
--done:
-- hci_dev_put(hdev);
-+ hci_notify(hdev, HCI_DEV_REG);
-+ hci_run_hotplug(hdev->name, "register");
-
-- return err;
-+ return id;
- }
-
--/* Interface to HCI drivers */
--
--/* Register HCI device */
--int hci_register_dev(struct hci_dev *hdev)
-+/* Unregister HCI device */
-+int hci_unregister_dev(struct hci_dev *hdev)
- {
-- int i;
--
-- DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
--
-- /* Find free slot */
-- spin_lock_bh(&hdev_list_lock);
-- for (i = 0; i < HCI_MAX_DEV; i++) {
-- if (!hdev_list[i]) {
-- hdev_list[i] = hdev;
--
-- sprintf(hdev->name, "hci%d", i);
-- atomic_set(&hdev->refcnt, 0);
-- hdev->id = i;
-- hdev->flags = HCI_NORMAL;
--
-- hdev->pkt_type = (HCI_DM1 | HCI_DH1);
--
-- tasklet_init(&hdev->cmd_task, hci_cmd_task, (unsigned long) hdev);
-- tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
-- tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
--
-- skb_queue_head_init(&hdev->rx_q);
-- skb_queue_head_init(&hdev->cmd_q);
-- skb_queue_head_init(&hdev->raw_q);
--
-- init_waitqueue_head(&hdev->req_wait_q);
-- init_MUTEX(&hdev->req_lock);
--
-- inquiry_cache_init(&hdev->inq_cache);
-+ BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
-
-- conn_hash_init(&hdev->conn_hash);
-+ write_lock_bh(&hdev_list_lock);
-+ list_del(&hdev->list);
-+ write_unlock_bh(&hdev_list_lock);
-
-- memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
-+ hci_dev_do_close(hdev);
-
-- hci_notify(hdev, HCI_DEV_REG);
-+ hci_notify(hdev, HCI_DEV_UNREG);
-+ hci_run_hotplug(hdev->name, "unregister");
-
-- MOD_INC_USE_COUNT;
-- break;
-- }
-- }
-- spin_unlock_bh(&hdev_list_lock);
-+ hci_dev_put(hdev);
-
-- return (i == HCI_MAX_DEV) ? -1 : i;
-+ MOD_DEC_USE_COUNT;
-+ return 0;
- }
-
--/* Unregister HCI device */
--int hci_unregister_dev(struct hci_dev *hdev)
-+/* Suspend HCI device */
-+int hci_suspend_dev(struct hci_dev *hdev)
- {
-- int i;
-+ hci_notify(hdev, HCI_DEV_SUSPEND);
-+ hci_run_hotplug(hdev->name, "suspend");
-+ return 0;
-+}
-
-- DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
-+/* Resume HCI device */
-+int hci_resume_dev(struct hci_dev *hdev)
-+{
-+ hci_notify(hdev, HCI_DEV_RESUME);
-+ hci_run_hotplug(hdev->name, "resume");
-+ return 0;
-+}
-
-- if (hdev->flags & HCI_UP)
-- hci_dev_close(hdev->id);
-+/* Receive frame from HCI drivers */
-+int hci_recv_frame(struct sk_buff *skb)
-+{
-+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-
-- /* Find device slot */
-- spin_lock(&hdev_list_lock);
-- for (i = 0; i < HCI_MAX_DEV; i++) {
-- if (hdev_list[i] == hdev) {
-- hdev_list[i] = NULL;
-- MOD_DEC_USE_COUNT;
-- break;
-- }
-+ if (!hdev || (!test_bit(HCI_UP, &hdev->flags) &&
-+ !test_bit(HCI_INIT, &hdev->flags)) ) {
-+ kfree_skb(skb);
-+ return -1;
- }
-- spin_unlock(&hdev_list_lock);
-
-- hci_notify(hdev, HCI_DEV_UNREG);
--
-- /* Sleep while device is in use */
-- while (atomic_read(&hdev->refcnt)) {
-- int sleep_cnt = 100;
-+ BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-
-- DBG("%s sleeping on lock %d", hdev->name, atomic_read(&hdev->refcnt));
-+ /* Incomming skb */
-+ bluez_cb(skb)->incomming = 1;
-
-- sleep_on_timeout(&hdev->req_wait_q, HZ*10);
-- if (!(--sleep_cnt))
-- break;
-- }
-+ /* Time stamp */
-+ do_gettimeofday(&skb->stamp);
-
-+ /* Queue frame for rx task */
-+ skb_queue_tail(&hdev->rx_q, skb);
-+ hci_sched_rx(hdev);
- return 0;
- }
-
--/* Interface to upper protocols */
-+/* ---- Interface to upper protocols ---- */
-
- /* Register/Unregister protocols.
-- * hci_task_lock is used to ensure that no tasks are running.
-- */
--int hci_register_proto(struct hci_proto *hproto)
-+ * hci_task_lock is used to ensure that no tasks are running. */
-+int hci_register_proto(struct hci_proto *hp)
- {
- int err = 0;
-
-- DBG("%p name %s", hproto, hproto->name);
-+ BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
-
-- if (hproto->id >= HCI_MAX_PROTO)
-+ if (hp->id >= HCI_MAX_PROTO)
- return -EINVAL;
-
- write_lock_bh(&hci_task_lock);
-
-- if (!hproto_list[hproto->id])
-- hproto_list[hproto->id] = hproto;
-+ if (!hci_proto[hp->id])
-+ hci_proto[hp->id] = hp;
- else
-- err = -1;
-+ err = -EEXIST;
-
- write_unlock_bh(&hci_task_lock);
-
- return err;
- }
-
--int hci_unregister_proto(struct hci_proto *hproto)
-+int hci_unregister_proto(struct hci_proto *hp)
- {
- int err = 0;
-
-- DBG("%p name %s", hproto, hproto->name);
-+ BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
-
-- if (hproto->id > HCI_MAX_PROTO)
-+ if (hp->id >= HCI_MAX_PROTO)
- return -EINVAL;
-
- write_lock_bh(&hci_task_lock);
-
-- if (hproto_list[hproto->id])
-- hproto_list[hproto->id] = NULL;
-+ if (hci_proto[hp->id])
-+ hci_proto[hp->id] = NULL;
- else
- err = -ENOENT;
-
-@@ -1070,10 +964,14 @@
- return -ENODEV;
- }
-
-- DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-+ BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-+
-+ if (atomic_read(&hdev->promisc)) {
-+ /* Time stamp */
-+ do_gettimeofday(&skb->stamp);
-
-- if (hdev->flags & HCI_SOCK)
- hci_send_to_sock(hdev, skb);
-+ }
-
- /* Get rid of skb owner, prior to sending to the driver. */
- skb_orphan(skb);
-@@ -1081,128 +979,6 @@
- return hdev->send(skb);
- }
-
--/* Connection scheduler */
--static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
--{
-- struct conn_hash *h = &hdev->conn_hash;
-- struct hci_conn *conn = NULL;
-- int num = 0, min = 0xffff;
-- struct list_head *p;
--
-- conn_hash_lock(h);
-- list_for_each(p, &h->list) {
-- register struct hci_conn *c;
--
-- c = list_entry(p, struct hci_conn, list);
--
-- if (c->type != type || skb_queue_empty(&c->data_q))
-- continue;
-- num++;
--
-- if (c->sent < min) {
-- min = c->sent;
-- conn = c;
-- }
-- }
-- conn_hash_unlock(h);
--
-- if (conn) {
-- int q = hdev->acl_cnt / num;
-- *quote = q ? q : 1;
-- } else
-- *quote = 0;
--
-- DBG("conn %p quote %d", conn, *quote);
--
-- return conn;
--}
--
--static inline void hci_sched_acl(struct hci_dev *hdev)
--{
-- struct hci_conn *conn;
-- struct sk_buff *skb;
-- int quote;
--
-- DBG("%s", hdev->name);
--
-- while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, &quote))) {
-- while (quote && (skb = skb_dequeue(&conn->data_q))) {
-- DBG("skb %p len %d", skb, skb->len);
--
-- hci_send_frame(skb);
--
-- conn->sent++;
-- hdev->acl_cnt--;
-- quote--;
-- }
-- }
--}
--
--/* Schedule SCO */
--static inline void hci_sched_sco(struct hci_dev *hdev)
--{
-- /* FIXME: For now we queue SCO packets to the raw queue
--
-- while (hdev->sco_cnt && (skb = skb_dequeue(&conn->data_q))) {
-- hci_send_frame(skb);
-- conn->sco_sent++;
-- hdev->sco_cnt--;
-- }
-- */
--}
--
--/* Get data from the previously sent command */
--static void * hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
--{
-- hci_command_hdr *hc;
--
-- if (!hdev->sent_cmd)
-- return NULL;
--
-- hc = (void *) hdev->sent_cmd->data;
--
-- if (hc->opcode != __cpu_to_le16(cmd_opcode_pack(ogf, ocf)))
-- return NULL;
--
-- DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
--
-- return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
--}
--
--/* Send raw HCI frame */
--int hci_send_raw(struct sk_buff *skb)
--{
-- struct hci_dev *hdev = (struct hci_dev *) skb->dev;
--
-- if (!hdev) {
-- kfree_skb(skb);
-- return -ENODEV;
-- }
--
-- DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
--
-- if (hdev->flags & HCI_NORMAL) {
-- /* Queue frame according it's type */
-- switch (skb->pkt_type) {
-- case HCI_COMMAND_PKT:
-- skb_queue_tail(&hdev->cmd_q, skb);
-- hci_sched_cmd(hdev);
-- return 0;
--
-- case HCI_ACLDATA_PKT:
-- case HCI_SCODATA_PKT:
-- /* FIXME:
-- * Check header here and queue to apropriate connection.
-- */
-- break;
-- }
-- }
--
-- skb_queue_tail(&hdev->raw_q, skb);
-- hci_sched_tx(hdev);
-- return 0;
--}
--
- /* Send HCI command */
- int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param)
- {
-@@ -1210,10 +986,10 @@
- hci_command_hdr *hc;
- struct sk_buff *skb;
-
-- DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
-+ BT_DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
-
- if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {
-- ERR("%s Can't allocate memory for HCI command", hdev->name);
-+ BT_ERR("%s Can't allocate memory for HCI command", hdev->name);
- return -ENOMEM;
- }
-
-@@ -1224,7 +1000,7 @@
- if (plen)
- memcpy(skb_put(skb, plen), param, plen);
-
-- DBG("skb len %d", skb->len);
-+ BT_DBG("skb len %d", skb->len);
-
- skb->pkt_type = HCI_COMMAND_PKT;
- skb->dev = (void *) hdev;
-@@ -1234,10 +1010,28 @@
- return 0;
- }
-
-+/* Get data from the previously sent command */
-+void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
-+{
-+ hci_command_hdr *hc;
-+
-+ if (!hdev->sent_cmd)
-+ return NULL;
-+
-+ hc = (void *) hdev->sent_cmd->data;
-+
-+ if (hc->opcode != __cpu_to_le16(cmd_opcode_pack(ogf, ocf)))
-+ return NULL;
-+
-+ BT_DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
-+
-+ return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
-+}
-+
- /* Send ACL data */
- static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
- {
-- int len = skb->len;
-+ int len = skb->len;
- hci_acl_hdr *ah;
-
- ah = (hci_acl_hdr *) skb_push(skb, HCI_ACL_HDR_SIZE);
-@@ -1252,7 +1046,7 @@
- struct hci_dev *hdev = conn->hdev;
- struct sk_buff *list;
-
-- DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
-+ BT_DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
-
- skb->dev = (void *) hdev;
- skb->pkt_type = HCI_ACLDATA_PKT;
-@@ -1260,12 +1054,12 @@
-
- if (!(list = skb_shinfo(skb)->frag_list)) {
- /* Non fragmented */
-- DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
-+ BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
-
- skb_queue_tail(&conn->data_q, skb);
- } else {
- /* Fragmented */
-- DBG("%s frag %p len %d", hdev->name, skb, skb->len);
-+ BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
-
- skb_shinfo(skb)->frag_list = NULL;
-
-@@ -1280,7 +1074,7 @@
- skb->pkt_type = HCI_ACLDATA_PKT;
- hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT);
-
-- DBG("%s frag %p len %d", hdev->name, skb, skb->len);
-+ BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
-
- __skb_queue_tail(&conn->data_q, skb);
- } while (list);
-@@ -1298,7 +1092,7 @@
- struct hci_dev *hdev = conn->hdev;
- hci_sco_hdr hs;
-
-- DBG("%s len %d", hdev->name, skb->len);
-+ BT_DBG("%s len %d", hdev->name, skb->len);
-
- if (skb->len > hdev->sco_mtu) {
- kfree_skb(skb);
-@@ -1315,544 +1109,136 @@
- skb->pkt_type = HCI_SCODATA_PKT;
- skb_queue_tail(&conn->data_q, skb);
- hci_sched_tx(hdev);
--
- return 0;
- }
-
--/* Handle HCI Event packets */
--
--/* Command Complete OGF LINK_CTL */
--static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
--{
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Complete OGF LINK_POLICY */
--static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
--{
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s: Command complete: ogf LINK_POLICY ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Complete OGF HOST_CTL */
--static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
--{
-- __u8 status, param;
-- void *sent;
--
--
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- case OCF_RESET:
-- status = *((__u8 *) skb->data);
--
-- hci_req_complete(hdev, status);
-- break;
--
-- case OCF_SET_EVENT_FLT:
-- status = *((__u8 *) skb->data);
--
-- if (status) {
-- DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
-- } else {
-- DBG("%s SET_EVENT_FLT succeseful", hdev->name);
-- }
-- break;
--
-- case OCF_WRITE_AUTH_ENABLE:
-- if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE)))
-- break;
--
-- status = *((__u8 *) skb->data);
-- param = *((__u8 *) sent);
--
-- if (!status) {
-- if (param == AUTH_ENABLED)
-- hdev->flags |= HCI_AUTH;
-- else
-- hdev->flags &= ~HCI_AUTH;
-- }
-- hci_req_complete(hdev, status);
-- break;
--
-- case OCF_WRITE_CA_TIMEOUT:
-- status = *((__u8 *) skb->data);
--
-- if (status) {
-- DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
-- } else {
-- DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
-- }
-- break;
--
-- case OCF_WRITE_PG_TIMEOUT:
-- status = *((__u8 *) skb->data);
--
-- if (status) {
-- DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
-- } else {
-- DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
-- }
-- break;
--
-- case OCF_WRITE_SCAN_ENABLE:
-- if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE)))
-- break;
-- status = *((__u8 *) skb->data);
-- param = *((__u8 *) sent);
--
-- DBG("param 0x%x", param);
--
-- if (!status) {
-- switch (param) {
-- case IS_ENA_PS_ENA:
-- hdev->flags |= HCI_PSCAN | HCI_ISCAN;
-- break;
--
-- case IS_ENA_PS_DIS:
-- hdev->flags &= ~HCI_PSCAN;
-- hdev->flags |= HCI_ISCAN;
-- break;
--
-- case IS_DIS_PS_ENA:
-- hdev->flags &= ~HCI_ISCAN;
-- hdev->flags |= HCI_PSCAN;
-- break;
--
-- default:
-- hdev->flags &= ~(HCI_ISCAN | HCI_PSCAN);
-- break;
-- };
-- }
-- hci_req_complete(hdev, status);
-- break;
--
-- default:
-- DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Complete OGF INFO_PARAM */
--static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
--{
-- read_local_features_rp *lf;
-- read_buffer_size_rp *bs;
-- read_bd_addr_rp *ba;
--
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- case OCF_READ_LOCAL_FEATURES:
-- lf = (read_local_features_rp *) skb->data;
--
-- if (lf->status) {
-- DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
-- break;
-- }
--
-- memcpy(hdev->features, lf->features, sizeof(hdev->features));
--
-- /* Adjust default settings according to features
-- * supported by device. */
-- if (hdev->features[0] & LMP_3SLOT)
-- hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
--
-- if (hdev->features[0] & LMP_5SLOT)
-- hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
--
-- DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
--
-- break;
--
-- case OCF_READ_BUFFER_SIZE:
-- bs = (read_buffer_size_rp *) skb->data;
--
-- if (bs->status) {
-- DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
-- break;
-- }
--
-- hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
-- hdev->sco_mtu = bs->sco_mtu;
-- hdev->acl_max = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
-- hdev->sco_max = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
--
-- DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
-- hdev->acl_mtu, hdev->sco_mtu, hdev->acl_max, hdev->sco_max);
--
-- break;
--
-- case OCF_READ_BD_ADDR:
-- ba = (read_bd_addr_rp *) skb->data;
--
-- if (!ba->status) {
-- bacpy(&hdev->bdaddr, &ba->bdaddr);
-- } else {
-- DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
-- }
--
-- hci_req_complete(hdev, ba->status);
-- break;
--
-- default:
-- DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-- break;
-- };
--}
-+/* ---- HCI TX task (outgoing data) ---- */
-
--/* Command Status OGF LINK_CTL */
--static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+/* HCI Connection scheduler */
-+static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
- {
-- struct hci_proto * hp;
--
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- case OCF_CREATE_CONN:
-- if (status) {
-- create_conn_cp *cc = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
--
-- if (!cc)
-- break;
-+ struct conn_hash *h = &hdev->conn_hash;
-+ struct hci_conn *conn = NULL;
-+ int num = 0, min = ~0;
-+ struct list_head *p;
-
-- DBG("%s Create connection error: status 0x%x %s", hdev->name,
-- status, batostr(&cc->bdaddr));
-+ /* We don't have to lock device here. Connections are always
-+ * added and removed with TX task disabled. */
-+ list_for_each(p, &h->list) {
-+ struct hci_conn *c;
-+ c = list_entry(p, struct hci_conn, list);
-
-- /* Notify upper protocols */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm) {
-- tasklet_disable(&hdev->tx_task);
-- hp->connect_cfm(hdev, &cc->bdaddr, status, NULL);
-- tasklet_enable(&hdev->tx_task);
-- }
-- }
-- break;
-+ if (c->type != type || c->state != BT_CONNECTED
-+ || skb_queue_empty(&c->data_q))
-+ continue;
-+ num++;
-
-- case OCF_INQUIRY:
-- if (status) {
-- DBG("%s Inquiry error: status 0x%x", hdev->name, status);
-- hci_req_complete(hdev, status);
-+ if (c->sent < min) {
-+ min = c->sent;
-+ conn = c;
- }
-- break;
--
-- default:
-- DBG("%s Command status: ogf LINK_CTL ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Status OGF LINK_POLICY */
--static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
--{
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Status OGF HOST_CTL */
--static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
--{
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Status OGF INFO_PARAM */
--static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
--{
-- DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Inquiry Complete */
--static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
--{
-- __u8 status = *((__u8 *) skb->data);
--
-- DBG("%s status %d", hdev->name, status);
--
-- hci_req_complete(hdev, status);
--}
--
--/* Inquiry Result */
--static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
--{
-- inquiry_info *info = (inquiry_info *) (skb->data + 1);
-- int num_rsp = *((__u8 *) skb->data);
-+ }
-
-- DBG("%s num_rsp %d", hdev->name, num_rsp);
-+ if (conn) {
-+ int cnt = (type == ACL_LINK ? hdev->acl_cnt : hdev->sco_cnt);
-+ int q = cnt / num;
-+ *quote = q ? q : 1;
-+ } else
-+ *quote = 0;
-
-- for (; num_rsp; num_rsp--)
-- inquiry_cache_update(&hdev->inq_cache, info++);
-+ BT_DBG("conn %p quote %d", conn, *quote);
-+ return conn;
- }
-
--/* Connect Request */
--static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+static inline void hci_acl_tx_to(struct hci_dev *hdev)
- {
-- evt_conn_request *cr = (evt_conn_request *) skb->data;
-- struct hci_proto *hp;
-- accept_conn_req_cp ac;
-- int accept = 0;
-+ struct conn_hash *h = &hdev->conn_hash;
-+ struct list_head *p;
-+ struct hci_conn *c;
-
-- DBG("%s Connection request: %s type 0x%x", hdev->name, batostr(&cr->bdaddr), cr->link_type);
-+ BT_ERR("%s ACL tx timeout", hdev->name);
-
-- /* Notify upper protocols */
-- if (cr->link_type == ACL_LINK) {
-- /* ACL link notify L2CAP */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_ind) {
-- tasklet_disable(&hdev->tx_task);
-- accept = hp->connect_ind(hdev, &cr->bdaddr);
-- tasklet_enable(&hdev->tx_task);
-+ /* Kill stalled connections */
-+ list_for_each(p, &h->list) {
-+ c = list_entry(p, struct hci_conn, list);
-+ if (c->type == ACL_LINK && c->sent) {
-+ BT_ERR("%s killing stalled ACL connection %s",
-+ hdev->name, batostr(&c->dst));
-+ hci_acl_disconn(c, 0x13);
- }
-- } else {
-- /* SCO link (no notification) */
-- /* FIXME: Should be accept it here or let the requester (app) accept it ? */
-- accept = 1;
-- }
--
-- if (accept) {
-- /* Connection accepted by upper layer */
-- bacpy(&ac.bdaddr, &cr->bdaddr);
-- ac.role = 0x01; /* Remain slave */
-- hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, ACCEPT_CONN_REQ_CP_SIZE, &ac);
-- } else {
-- /* Connection rejected by upper layer */
-- /* FIXME:
-- * Should we use HCI reject here ?
-- */
-- return;
- }
- }
-
--/* Connect Complete */
--static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+static inline void hci_sched_acl(struct hci_dev *hdev)
- {
-- evt_conn_complete *cc = (evt_conn_complete *) skb->data;
-- struct hci_conn *conn = NULL;
-- struct hci_proto *hp;
-+ struct hci_conn *conn;
-+ struct sk_buff *skb;
-+ int quote;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s", hdev->name);
-
-- tasklet_disable(&hdev->tx_task);
-+ /* ACL tx timeout must be longer than maximum
-+ * link supervision timeout (40.9 seconds) */
-+ if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45))
-+ hci_acl_tx_to(hdev);
-
-- if (!cc->status)
-- conn = hci_conn_add(hdev, __le16_to_cpu(cc->handle), cc->link_type, &cc->bdaddr);
-+ while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, &quote))) {
-+ while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
-+ BT_DBG("skb %p len %d", skb, skb->len);
-+ hci_send_frame(skb);
-+ hdev->acl_last_tx = jiffies;
-
-- /* Notify upper protocols */
-- if (cc->link_type == ACL_LINK) {
-- /* ACL link notify L2CAP layer */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm)
-- hp->connect_cfm(hdev, &cc->bdaddr, cc->status, conn);
-- } else {
-- /* SCO link (no notification) */
-+ hdev->acl_cnt--;
-+ conn->sent++;
-+ }
- }
--
-- tasklet_enable(&hdev->tx_task);
- }
-
--/* Disconnect Complete */
--static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+/* Schedule SCO */
-+static inline void hci_sched_sco(struct hci_dev *hdev)
- {
-- evt_disconn_complete *dc = (evt_disconn_complete *) skb->data;
-- struct hci_conn *conn = NULL;
-- struct hci_proto *hp;
-- __u16 handle = __le16_to_cpu(dc->handle);
-+ struct hci_conn *conn;
-+ struct sk_buff *skb;
-+ int quote;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s", hdev->name);
-
-- if (!dc->status && (conn = conn_hash_lookup(&hdev->conn_hash, handle))) {
-- tasklet_disable(&hdev->tx_task);
-+ while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
-+ while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
-+ BT_DBG("skb %p len %d", skb, skb->len);
-+ hci_send_frame(skb);
-
-- /* Notify upper protocols */
-- if (conn->type == ACL_LINK) {
-- /* ACL link notify L2CAP layer */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
-- hp->disconn_ind(conn, dc->reason);
-- } else {
-- /* SCO link (no notification) */
-+ conn->sent++;
-+ if (conn->sent == ~0)
-+ conn->sent = 0;
- }
--
-- hci_conn_del(hdev, conn);
--
-- tasklet_enable(&hdev->tx_task);
- }
- }
-
--/* Number of completed packets */
--static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+static void hci_tx_task(unsigned long arg)
- {
-- evt_num_comp_pkts *nc = (evt_num_comp_pkts *) skb->data;
-- __u16 *ptr;
-- int i;
--
-- skb_pull(skb, EVT_NUM_COMP_PKTS_SIZE);
--
-- DBG("%s num_hndl %d", hdev->name, nc->num_hndl);
-+ struct hci_dev *hdev = (struct hci_dev *) arg;
-+ struct sk_buff *skb;
-
-- if (skb->len < nc->num_hndl * 4) {
-- DBG("%s bad parameters", hdev->name);
-- return;
-- }
-+ read_lock(&hci_task_lock);
-
-- tasklet_disable(&hdev->tx_task);
-+ BT_DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
-
-- for (i = 0, ptr = (__u16 *) skb->data; i < nc->num_hndl; i++) {
-- struct hci_conn *conn;
-- __u16 handle, count;
-+ /* Schedule queues and send stuff to HCI driver */
-
-- handle = __le16_to_cpu(get_unaligned(ptr++));
-- count = __le16_to_cpu(get_unaligned(ptr++));
-+ hci_sched_acl(hdev);
-
-- hdev->acl_cnt += count;
-+ hci_sched_sco(hdev);
-
-- if ((conn = conn_hash_lookup(&hdev->conn_hash, handle)))
-- conn->sent -= count;
-- }
-+ /* Send next queued raw (unknown type) packet */
-+ while ((skb = skb_dequeue(&hdev->raw_q)))
-+ hci_send_frame(skb);
-
-- tasklet_enable(&hdev->tx_task);
--
-- hci_sched_tx(hdev);
-+ read_unlock(&hci_task_lock);
- }
-
--static inline void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
--{
-- hci_event_hdr *he = (hci_event_hdr *) skb->data;
-- evt_cmd_status *cs;
-- evt_cmd_complete *ec;
-- __u16 opcode, ocf, ogf;
--
-- skb_pull(skb, HCI_EVENT_HDR_SIZE);
--
-- DBG("%s evt 0x%x", hdev->name, he->evt);
--
-- switch (he->evt) {
-- case EVT_NUM_COMP_PKTS:
-- hci_num_comp_pkts_evt(hdev, skb);
-- break;
--
-- case EVT_INQUIRY_COMPLETE:
-- hci_inquiry_complete_evt(hdev, skb);
-- break;
--
-- case EVT_INQUIRY_RESULT:
-- hci_inquiry_result_evt(hdev, skb);
-- break;
--
-- case EVT_CONN_REQUEST:
-- hci_conn_request_evt(hdev, skb);
-- break;
--
-- case EVT_CONN_COMPLETE:
-- hci_conn_complete_evt(hdev, skb);
-- break;
--
-- case EVT_DISCONN_COMPLETE:
-- hci_disconn_complete_evt(hdev, skb);
-- break;
--
-- case EVT_CMD_STATUS:
-- cs = (evt_cmd_status *) skb->data;
-- skb_pull(skb, EVT_CMD_STATUS_SIZE);
--
-- opcode = __le16_to_cpu(cs->opcode);
-- ogf = cmd_opcode_ogf(opcode);
-- ocf = cmd_opcode_ocf(opcode);
--
-- switch (ogf) {
-- case OGF_INFO_PARAM:
-- hci_cs_info_param(hdev, ocf, cs->status);
-- break;
--
-- case OGF_HOST_CTL:
-- hci_cs_host_ctl(hdev, ocf, cs->status);
-- break;
-
-- case OGF_LINK_CTL:
-- hci_cs_link_ctl(hdev, ocf, cs->status);
-- break;
--
-- case OGF_LINK_POLICY:
-- hci_cs_link_policy(hdev, ocf, cs->status);
-- break;
--
-- default:
-- DBG("%s Command Status OGF %x", hdev->name, ogf);
-- break;
-- };
--
-- if (cs->ncmd) {
-- atomic_set(&hdev->cmd_cnt, 1);
-- if (!skb_queue_empty(&hdev->cmd_q))
-- hci_sched_cmd(hdev);
-- }
-- break;
--
-- case EVT_CMD_COMPLETE:
-- ec = (evt_cmd_complete *) skb->data;
-- skb_pull(skb, EVT_CMD_COMPLETE_SIZE);
--
-- opcode = __le16_to_cpu(ec->opcode);
-- ogf = cmd_opcode_ogf(opcode);
-- ocf = cmd_opcode_ocf(opcode);
--
-- switch (ogf) {
-- case OGF_INFO_PARAM:
-- hci_cc_info_param(hdev, ocf, skb);
-- break;
--
-- case OGF_HOST_CTL:
-- hci_cc_host_ctl(hdev, ocf, skb);
-- break;
--
-- case OGF_LINK_CTL:
-- hci_cc_link_ctl(hdev, ocf, skb);
-- break;
--
-- case OGF_LINK_POLICY:
-- hci_cc_link_policy(hdev, ocf, skb);
-- break;
--
-- default:
-- DBG("%s Command Completed OGF %x", hdev->name, ogf);
-- break;
-- };
--
-- if (ec->ncmd) {
-- atomic_set(&hdev->cmd_cnt, 1);
-- if (!skb_queue_empty(&hdev->cmd_q))
-- hci_sched_cmd(hdev);
-- }
-- break;
-- };
--
-- kfree_skb(skb);
-- hdev->stat.evt_rx++;
--}
-+/* ----- HCI RX task (incomming data proccessing) ----- */
-
- /* ACL data packet */
- static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
-@@ -1867,51 +1253,86 @@
- flags = acl_flags(handle);
- handle = acl_handle(handle);
-
-- DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
-+ BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
-
-- if ((conn = conn_hash_lookup(&hdev->conn_hash, handle))) {
-+ hdev->stat.acl_rx++;
-+
-+ hci_dev_lock(hdev);
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ hci_dev_unlock(hdev);
-+
-+ if (conn) {
- register struct hci_proto *hp;
-
- /* Send to upper protocol */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->recv_acldata) {
-+ if ((hp = hci_proto[HCI_PROTO_L2CAP]) && hp->recv_acldata) {
- hp->recv_acldata(conn, skb, flags);
-- goto sent;
-+ return;
- }
- } else {
-- ERR("%s ACL packet for unknown connection handle %d", hdev->name, handle);
-+ BT_ERR("%s ACL packet for unknown connection handle %d",
-+ hdev->name, handle);
- }
-
- kfree_skb(skb);
--sent:
-- hdev->stat.acl_rx++;
- }
-
- /* SCO data packet */
- static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
- {
-- DBG("%s len %d", hdev->name, skb->len);
-+ hci_sco_hdr *sh = (void *) skb->data;
-+ struct hci_conn *conn;
-+ __u16 handle;
-+
-+ skb_pull(skb, HCI_SCO_HDR_SIZE);
-+
-+ handle = __le16_to_cpu(sh->handle);
-+
-+ BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
-
-- kfree_skb(skb);
- hdev->stat.sco_rx++;
-+
-+ hci_dev_lock(hdev);
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ hci_dev_unlock(hdev);
-+
-+ if (conn) {
-+ register struct hci_proto *hp;
-+
-+ /* Send to upper protocol */
-+ if ((hp = hci_proto[HCI_PROTO_SCO]) && hp->recv_scodata) {
-+ hp->recv_scodata(conn, skb);
-+ return;
-+ }
-+ } else {
-+ BT_ERR("%s SCO packet for unknown connection handle %d",
-+ hdev->name, handle);
-+ }
-+
-+ kfree_skb(skb);
- }
-
--/* ----- HCI tasks ----- */
- void hci_rx_task(unsigned long arg)
- {
- struct hci_dev *hdev = (struct hci_dev *) arg;
- struct sk_buff *skb;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s", hdev->name);
-
- read_lock(&hci_task_lock);
-
- while ((skb = skb_dequeue(&hdev->rx_q))) {
-- if (hdev->flags & HCI_SOCK) {
-+ if (atomic_read(&hdev->promisc)) {
- /* Send copy to the sockets */
- hci_send_to_sock(hdev, skb);
- }
-
-- if (hdev->flags & HCI_INIT) {
-+ if (test_bit(HCI_RAW, &hdev->flags)) {
-+ kfree_skb(skb);
-+ continue;
-+ }
-+
-+ if (test_bit(HCI_INIT, &hdev->flags)) {
- /* Don't process data packets in this states. */
- switch (skb->pkt_type) {
- case HCI_ACLDATA_PKT:
-@@ -1921,64 +1342,43 @@
- };
- }
-
-- if (hdev->flags & HCI_NORMAL) {
-- /* Process frame */
-- switch (skb->pkt_type) {
-- case HCI_EVENT_PKT:
-- hci_event_packet(hdev, skb);
-- break;
-+ /* Process frame */
-+ switch (skb->pkt_type) {
-+ case HCI_EVENT_PKT:
-+ hci_event_packet(hdev, skb);
-+ break;
-
-- case HCI_ACLDATA_PKT:
-- DBG("%s ACL data packet", hdev->name);
-- hci_acldata_packet(hdev, skb);
-- break;
-+ case HCI_ACLDATA_PKT:
-+ BT_DBG("%s ACL data packet", hdev->name);
-+ hci_acldata_packet(hdev, skb);
-+ break;
-
-- case HCI_SCODATA_PKT:
-- DBG("%s SCO data packet", hdev->name);
-- hci_scodata_packet(hdev, skb);
-- break;
-+ case HCI_SCODATA_PKT:
-+ BT_DBG("%s SCO data packet", hdev->name);
-+ hci_scodata_packet(hdev, skb);
-+ break;
-
-- default:
-- kfree_skb(skb);
-- break;
-- };
-- } else {
-+ default:
- kfree_skb(skb);
-+ break;
- }
- }
-
- read_unlock(&hci_task_lock);
- }
-
--static void hci_tx_task(unsigned long arg)
--{
-- struct hci_dev *hdev = (struct hci_dev *) arg;
-- struct sk_buff *skb;
--
-- read_lock(&hci_task_lock);
--
-- DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
--
-- /* Schedule queues and send stuff to HCI driver */
--
-- hci_sched_acl(hdev);
--
-- hci_sched_sco(hdev);
--
-- /* Send next queued raw (unknown type) packet */
-- while ((skb = skb_dequeue(&hdev->raw_q)))
-- hci_send_frame(skb);
--
-- read_unlock(&hci_task_lock);
--}
--
- static void hci_cmd_task(unsigned long arg)
- {
- struct hci_dev *hdev = (struct hci_dev *) arg;
- struct sk_buff *skb;
-
-- DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
-+ BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
-
-+ if (!atomic_read(&hdev->cmd_cnt) && (jiffies - hdev->cmd_last_tx) > HZ) {
-+ BT_ERR("%s command tx timeout", hdev->name);
-+ atomic_set(&hdev->cmd_cnt, 1);
-+ }
-+
- /* Send queued commands */
- if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) {
- if (hdev->sent_cmd)
-@@ -1987,6 +1387,7 @@
- if ((hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC))) {
- atomic_dec(&hdev->cmd_cnt);
- hci_send_frame(skb);
-+ hdev->cmd_last_tx = jiffies;
- } else {
- skb_queue_head(&hdev->cmd_q, skb);
- hci_sched_cmd(hdev);
-@@ -1994,33 +1395,10 @@
- }
- }
-
--/* Receive frame from HCI drivers */
--int hci_recv_frame(struct sk_buff *skb)
--{
-- struct hci_dev *hdev = (struct hci_dev *) skb->dev;
--
-- if (!hdev || !(hdev->flags & (HCI_UP | HCI_INIT))) {
-- kfree_skb(skb);
-- return -1;
-- }
--
-- DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
--
-- /* Incomming skb */
-- bluez_cb(skb)->incomming = 1;
--
-- /* Queue frame for rx task */
-- skb_queue_tail(&hdev->rx_q, skb);
-- hci_sched_rx(hdev);
--
-- return 0;
--}
-+/* ---- Initialization ---- */
-
- int hci_core_init(void)
- {
-- /* Init locks */
-- spin_lock_init(&hdev_list_lock);
--
- return 0;
- }
-
-@@ -2028,5 +1406,3 @@
- {
- return 0;
- }
--
--MODULE_LICENSE("GPL");
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/hci_event.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,910 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * HCI Events.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/notifier.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+#ifndef HCI_CORE_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+/* Handle HCI Event packets */
-+
-+/* Command Complete OGF LINK_CTL */
-+static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+{
-+ __u8 status;
-+
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_INQUIRY_CANCEL:
-+ status = *((__u8 *) skb->data);
-+
-+ if (status) {
-+ BT_DBG("%s Inquiry cancel error: status 0x%x", hdev->name, status);
-+ } else {
-+ clear_bit(HCI_INQUIRY, &hdev->flags);
-+ hci_req_complete(hdev, status);
-+ }
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Complete OGF LINK_POLICY */
-+static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+{
-+ struct hci_conn *conn;
-+ role_discovery_rp *rd;
-+
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_ROLE_DISCOVERY:
-+ rd = (void *) skb->data;
-+
-+ if (rd->status)
-+ break;
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_handle(hdev, __le16_to_cpu(rd->handle));
-+ if (conn) {
-+ if (rd->role)
-+ conn->link_mode &= ~HCI_LM_MASTER;
-+ else
-+ conn->link_mode |= HCI_LM_MASTER;
-+ }
-+
-+ hci_dev_unlock(hdev);
-+ break;
-+
-+ default:
-+ BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x",
-+ hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Complete OGF HOST_CTL */
-+static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+{
-+ __u8 status, param;
-+ void *sent;
-+
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_RESET:
-+ status = *((__u8 *) skb->data);
-+ hci_req_complete(hdev, status);
-+ break;
-+
-+ case OCF_SET_EVENT_FLT:
-+ status = *((__u8 *) skb->data);
-+ if (status) {
-+ BT_DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
-+ } else {
-+ BT_DBG("%s SET_EVENT_FLT succeseful", hdev->name);
-+ }
-+ break;
-+
-+ case OCF_WRITE_AUTH_ENABLE:
-+ sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE);
-+ if (!sent)
-+ break;
-+
-+ status = *((__u8 *) skb->data);
-+ param = *((__u8 *) sent);
-+
-+ if (!status) {
-+ if (param == AUTH_ENABLED)
-+ set_bit(HCI_AUTH, &hdev->flags);
-+ else
-+ clear_bit(HCI_AUTH, &hdev->flags);
-+ }
-+ hci_req_complete(hdev, status);
-+ break;
-+
-+ case OCF_WRITE_ENCRYPT_MODE:
-+ sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE);
-+ if (!sent)
-+ break;
-+
-+ status = *((__u8 *) skb->data);
-+ param = *((__u8 *) sent);
-+
-+ if (!status) {
-+ if (param)
-+ set_bit(HCI_ENCRYPT, &hdev->flags);
-+ else
-+ clear_bit(HCI_ENCRYPT, &hdev->flags);
-+ }
-+ hci_req_complete(hdev, status);
-+ break;
-+
-+ case OCF_WRITE_CA_TIMEOUT:
-+ status = *((__u8 *) skb->data);
-+ if (status) {
-+ BT_DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
-+ } else {
-+ BT_DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
-+ }
-+ break;
-+
-+ case OCF_WRITE_PG_TIMEOUT:
-+ status = *((__u8 *) skb->data);
-+ if (status) {
-+ BT_DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
-+ } else {
-+ BT_DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
-+ }
-+ break;
-+
-+ case OCF_WRITE_SCAN_ENABLE:
-+ sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE);
-+ if (!sent)
-+ break;
-+ status = *((__u8 *) skb->data);
-+ param = *((__u8 *) sent);
-+
-+ BT_DBG("param 0x%x", param);
-+
-+ if (!status) {
-+ clear_bit(HCI_PSCAN, &hdev->flags);
-+ clear_bit(HCI_ISCAN, &hdev->flags);
-+ if (param & SCAN_INQUIRY)
-+ set_bit(HCI_ISCAN, &hdev->flags);
-+
-+ if (param & SCAN_PAGE)
-+ set_bit(HCI_PSCAN, &hdev->flags);
-+ }
-+ hci_req_complete(hdev, status);
-+ break;
-+
-+ case OCF_HOST_BUFFER_SIZE:
-+ status = *((__u8 *) skb->data);
-+ if (status) {
-+ BT_DBG("%s OCF_BUFFER_SIZE failed %d", hdev->name, status);
-+ hci_req_complete(hdev, status);
-+ }
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Complete OGF INFO_PARAM */
-+static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+{
-+ read_local_features_rp *lf;
-+ read_buffer_size_rp *bs;
-+ read_bd_addr_rp *ba;
-+
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_READ_LOCAL_FEATURES:
-+ lf = (read_local_features_rp *) skb->data;
-+
-+ if (lf->status) {
-+ BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
-+ break;
-+ }
-+
-+ memcpy(hdev->features, lf->features, sizeof(hdev->features));
-+
-+ /* Adjust default settings according to features
-+ * supported by device. */
-+ if (hdev->features[0] & LMP_3SLOT)
-+ hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
-+
-+ if (hdev->features[0] & LMP_5SLOT)
-+ hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
-+
-+ if (hdev->features[1] & LMP_HV2)
-+ hdev->pkt_type |= (HCI_HV2);
-+
-+ if (hdev->features[1] & LMP_HV3)
-+ hdev->pkt_type |= (HCI_HV3);
-+
-+ BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
-+
-+ break;
-+
-+ case OCF_READ_BUFFER_SIZE:
-+ bs = (read_buffer_size_rp *) skb->data;
-+
-+ if (bs->status) {
-+ BT_DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
-+ hci_req_complete(hdev, bs->status);
-+ break;
-+ }
-+
-+ hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
-+ hdev->sco_mtu = bs->sco_mtu ? bs->sco_mtu : 64;
-+ hdev->acl_pkts = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
-+ hdev->sco_pkts = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
-+
-+ BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
-+ hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
-+ break;
-+
-+ case OCF_READ_BD_ADDR:
-+ ba = (read_bd_addr_rp *) skb->data;
-+
-+ if (!ba->status) {
-+ bacpy(&hdev->bdaddr, &ba->bdaddr);
-+ } else {
-+ BT_DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
-+ }
-+
-+ hci_req_complete(hdev, ba->status);
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Status OGF LINK_CTL */
-+static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
-+{
-+ struct hci_conn *conn;
-+ create_conn_cp *cc = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
-+
-+ if (!cc)
-+ return;
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_ba(hdev, ACL_LINK, &cc->bdaddr);
-+
-+ BT_DBG("%s status 0x%x bdaddr %s conn %p", hdev->name,
-+ status, batostr(&cc->bdaddr), conn);
-+
-+ if (status) {
-+ if (conn) {
-+ conn->state = BT_CLOSED;
-+ hci_proto_connect_cfm(conn, status);
-+ hci_conn_del(conn);
-+ }
-+ } else {
-+ if (!conn) {
-+ conn = hci_conn_add(hdev, ACL_LINK, &cc->bdaddr);
-+ if (conn) {
-+ conn->out = 1;
-+ conn->link_mode |= HCI_LM_MASTER;
-+ } else
-+ BT_ERR("No memmory for new connection");
-+ }
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+{
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_CREATE_CONN:
-+ hci_cs_create_conn(hdev, status);
-+ break;
-+
-+ case OCF_ADD_SCO:
-+ if (status) {
-+ struct hci_conn *acl, *sco;
-+ add_sco_cp *cp = hci_sent_cmd_data(hdev,
-+ OGF_LINK_CTL, OCF_ADD_SCO);
-+ __u16 handle;
-+
-+ if (!cp)
-+ break;
-+
-+ handle = __le16_to_cpu(cp->handle);
-+
-+ BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
-+
-+ hci_dev_lock(hdev);
-+
-+ acl = conn_hash_lookup_handle(hdev, handle);
-+ if (acl && (sco = acl->link)) {
-+ sco->state = BT_CLOSED;
-+ hci_proto_connect_cfm(sco, status);
-+ hci_conn_del(sco);
-+ }
-+
-+ hci_dev_unlock(hdev);
-+ }
-+ break;
-+
-+ case OCF_INQUIRY:
-+ if (status) {
-+ BT_DBG("%s Inquiry error: status 0x%x", hdev->name, status);
-+ hci_req_complete(hdev, status);
-+ } else {
-+ set_bit(HCI_INQUIRY, &hdev->flags);
-+ }
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command status: ogf LINK_CTL ocf %x status %d",
-+ hdev->name, ocf, status);
-+ break;
-+ };
-+}
-+
-+/* Command Status OGF LINK_POLICY */
-+static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+{
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ default:
-+ BT_DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Status OGF HOST_CTL */
-+static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+{
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ default:
-+ BT_DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Status OGF INFO_PARAM */
-+static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+{
-+ BT_DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ default:
-+ BT_DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Inquiry Complete */
-+static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ __u8 status = *((__u8 *) skb->data);
-+
-+ BT_DBG("%s status %d", hdev->name, status);
-+
-+ clear_bit(HCI_INQUIRY, &hdev->flags);
-+ hci_req_complete(hdev, status);
-+}
-+
-+/* Inquiry Result */
-+static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ inquiry_info *info = (inquiry_info *) (skb->data + 1);
-+ int num_rsp = *((__u8 *) skb->data);
-+
-+ BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
-+
-+ hci_dev_lock(hdev);
-+ for (; num_rsp; num_rsp--)
-+ inquiry_cache_update(hdev, info++);
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Inquiry Result With RSSI */
-+static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ inquiry_info_with_rssi *info = (inquiry_info_with_rssi *) (skb->data + 1);
-+ int num_rsp = *((__u8 *) skb->data);
-+
-+ BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
-+
-+ hci_dev_lock(hdev);
-+ for (; num_rsp; num_rsp--) {
-+ inquiry_info tmp;
-+ bacpy(&tmp.bdaddr, &info->bdaddr);
-+ tmp.pscan_rep_mode = info->pscan_rep_mode;
-+ tmp.pscan_period_mode = info->pscan_period_mode;
-+ tmp.pscan_mode = 0x00;
-+ memcpy(tmp.dev_class, &info->dev_class, 3);
-+ tmp.clock_offset = info->clock_offset;
-+ info++;
-+ inquiry_cache_update(hdev, &tmp);
-+ }
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Connect Request */
-+static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_conn_request *cr = (evt_conn_request *) skb->data;
-+ int mask = hdev->link_mode;
-+
-+ BT_DBG("%s Connection request: %s type 0x%x", hdev->name,
-+ batostr(&cr->bdaddr), cr->link_type);
-+
-+ mask |= hci_proto_connect_ind(hdev, &cr->bdaddr, cr->link_type);
-+
-+ if (mask & HCI_LM_ACCEPT) {
-+ /* Connection accepted */
-+ struct hci_conn *conn;
-+ accept_conn_req_cp ac;
-+
-+ hci_dev_lock(hdev);
-+ conn = conn_hash_lookup_ba(hdev, cr->link_type, &cr->bdaddr);
-+ if (!conn) {
-+ if (!(conn = hci_conn_add(hdev, cr->link_type, &cr->bdaddr))) {
-+ BT_ERR("No memmory for new connection");
-+ hci_dev_unlock(hdev);
-+ return;
-+ }
-+ }
-+ conn->state = BT_CONNECT;
-+ hci_dev_unlock(hdev);
-+
-+ bacpy(&ac.bdaddr, &cr->bdaddr);
-+
-+ if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
-+ ac.role = 0x00; /* Become master */
-+ else
-+ ac.role = 0x01; /* Remain slave */
-+
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ,
-+ ACCEPT_CONN_REQ_CP_SIZE, &ac);
-+ } else {
-+ /* Connection rejected */
-+ reject_conn_req_cp rc;
-+
-+ bacpy(&rc.bdaddr, &cr->bdaddr);
-+ rc.reason = 0x0f;
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_REJECT_CONN_REQ,
-+ REJECT_CONN_REQ_CP_SIZE, &rc);
-+ }
-+}
-+
-+/* Connect Complete */
-+static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_conn_complete *cc = (evt_conn_complete *) skb->data;
-+ struct hci_conn *conn = NULL;
-+
-+ BT_DBG("%s", hdev->name);
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_ba(hdev, cc->link_type, &cc->bdaddr);
-+ if (!conn) {
-+ hci_dev_unlock(hdev);
-+ return;
-+ }
-+
-+ if (!cc->status) {
-+ conn->handle = __le16_to_cpu(cc->handle);
-+ conn->state = BT_CONNECTED;
-+
-+ if (test_bit(HCI_AUTH, &hdev->flags))
-+ conn->link_mode |= HCI_LM_AUTH;
-+
-+ if (test_bit(HCI_ENCRYPT, &hdev->flags))
-+ conn->link_mode |= HCI_LM_ENCRYPT;
-+
-+
-+ /* Set link policy */
-+ if (conn->type == ACL_LINK && hdev->link_policy) {
-+ write_link_policy_cp lp;
-+ lp.handle = cc->handle;
-+ lp.policy = __cpu_to_le16(hdev->link_policy);
-+ hci_send_cmd(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY,
-+ WRITE_LINK_POLICY_CP_SIZE, &lp);
-+ }
-+
-+ /* Set packet type for incomming connection */
-+ if (!conn->out) {
-+ change_conn_ptype_cp cp;
-+ cp.handle = cc->handle;
-+ cp.pkt_type = (conn->type == ACL_LINK) ?
-+ __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK):
-+ __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
-+
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CHANGE_CONN_PTYPE,
-+ CHANGE_CONN_PTYPE_CP_SIZE, &cp);
-+ }
-+ } else
-+ conn->state = BT_CLOSED;
-+
-+ if (conn->type == ACL_LINK) {
-+ struct hci_conn *sco = conn->link;
-+ if (sco) {
-+ if (!cc->status)
-+ hci_add_sco(sco, conn->handle);
-+ else {
-+ hci_proto_connect_cfm(sco, cc->status);
-+ hci_conn_del(sco);
-+ }
-+ }
-+ }
-+
-+ hci_proto_connect_cfm(conn, cc->status);
-+ if (cc->status)
-+ hci_conn_del(conn);
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Disconnect Complete */
-+static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_disconn_complete *dc = (evt_disconn_complete *) skb->data;
-+ struct hci_conn *conn = NULL;
-+ __u16 handle = __le16_to_cpu(dc->handle);
-+
-+ BT_DBG("%s status %d", hdev->name, dc->status);
-+
-+ if (dc->status)
-+ return;
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ if (conn) {
-+ conn->state = BT_CLOSED;
-+ hci_proto_disconn_ind(conn, dc->reason);
-+ hci_conn_del(conn);
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Number of completed packets */
-+static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_num_comp_pkts *nc = (evt_num_comp_pkts *) skb->data;
-+ __u16 *ptr;
-+ int i;
-+
-+ skb_pull(skb, EVT_NUM_COMP_PKTS_SIZE);
-+
-+ BT_DBG("%s num_hndl %d", hdev->name, nc->num_hndl);
-+
-+ if (skb->len < nc->num_hndl * 4) {
-+ BT_DBG("%s bad parameters", hdev->name);
-+ return;
-+ }
-+
-+ tasklet_disable(&hdev->tx_task);
-+
-+ for (i = 0, ptr = (__u16 *) skb->data; i < nc->num_hndl; i++) {
-+ struct hci_conn *conn;
-+ __u16 handle, count;
-+
-+ handle = __le16_to_cpu(get_unaligned(ptr++));
-+ count = __le16_to_cpu(get_unaligned(ptr++));
-+
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ if (conn) {
-+ conn->sent -= count;
-+
-+ if (conn->type == SCO_LINK) {
-+ if ((hdev->sco_cnt += count) > hdev->sco_pkts)
-+ hdev->sco_cnt = hdev->sco_pkts;
-+ } else {
-+ if ((hdev->acl_cnt += count) > hdev->acl_pkts)
-+ hdev->acl_cnt = hdev->acl_pkts;
-+ }
-+ }
-+ }
-+ hci_sched_tx(hdev);
-+
-+ tasklet_enable(&hdev->tx_task);
-+}
-+
-+/* Role Change */
-+static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_role_change *rc = (evt_role_change *) skb->data;
-+ struct hci_conn *conn = NULL;
-+
-+ BT_DBG("%s status %d", hdev->name, rc->status);
-+
-+ if (rc->status)
-+ return;
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_ba(hdev, ACL_LINK, &rc->bdaddr);
-+ if (conn) {
-+ if (rc->role)
-+ conn->link_mode &= ~HCI_LM_MASTER;
-+ else
-+ conn->link_mode |= HCI_LM_MASTER;
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Authentication Complete */
-+static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_auth_complete *ac = (evt_auth_complete *) skb->data;
-+ struct hci_conn *conn = NULL;
-+ __u16 handle = __le16_to_cpu(ac->handle);
-+
-+ BT_DBG("%s status %d", hdev->name, ac->status);
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ if (conn) {
-+ if (!ac->status)
-+ conn->link_mode |= HCI_LM_AUTH;
-+ clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
-+
-+ hci_proto_auth_cfm(conn, ac->status);
-+
-+ if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
-+ if (!ac->status) {
-+ set_conn_encrypt_cp ce;
-+ ce.handle = __cpu_to_le16(conn->handle);
-+ ce.encrypt = 1;
-+ hci_send_cmd(conn->hdev, OGF_LINK_CTL,
-+ OCF_SET_CONN_ENCRYPT,
-+ SET_CONN_ENCRYPT_CP_SIZE, &ce);
-+ } else {
-+ clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
-+ hci_proto_encrypt_cfm(conn, ac->status);
-+ }
-+ }
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Encryption Change */
-+static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_encrypt_change *ec = (evt_encrypt_change *) skb->data;
-+ struct hci_conn *conn = NULL;
-+ __u16 handle = __le16_to_cpu(ec->handle);
-+
-+ BT_DBG("%s status %d", hdev->name, ec->status);
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ if (conn) {
-+ if (!ec->status) {
-+ if (ec->encrypt)
-+ conn->link_mode |= HCI_LM_ENCRYPT;
-+ else
-+ conn->link_mode &= ~HCI_LM_ENCRYPT;
-+ }
-+ clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
-+
-+ hci_proto_encrypt_cfm(conn, ec->status);
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ hci_event_hdr *he = (hci_event_hdr *) skb->data;
-+ evt_cmd_status *cs;
-+ evt_cmd_complete *ec;
-+ __u16 opcode, ocf, ogf;
-+
-+ skb_pull(skb, HCI_EVENT_HDR_SIZE);
-+
-+ BT_DBG("%s evt 0x%x", hdev->name, he->evt);
-+
-+ switch (he->evt) {
-+ case EVT_NUM_COMP_PKTS:
-+ hci_num_comp_pkts_evt(hdev, skb);
-+ break;
-+
-+ case EVT_INQUIRY_COMPLETE:
-+ hci_inquiry_complete_evt(hdev, skb);
-+ break;
-+
-+ case EVT_INQUIRY_RESULT:
-+ hci_inquiry_result_evt(hdev, skb);
-+ break;
-+
-+ case EVT_INQUIRY_RESULT_WITH_RSSI:
-+ hci_inquiry_result_with_rssi_evt(hdev, skb);
-+ break;
-+
-+ case EVT_CONN_REQUEST:
-+ hci_conn_request_evt(hdev, skb);
-+ break;
-+
-+ case EVT_CONN_COMPLETE:
-+ hci_conn_complete_evt(hdev, skb);
-+ break;
-+
-+ case EVT_DISCONN_COMPLETE:
-+ hci_disconn_complete_evt(hdev, skb);
-+ break;
-+
-+ case EVT_ROLE_CHANGE:
-+ hci_role_change_evt(hdev, skb);
-+ break;
-+
-+ case EVT_AUTH_COMPLETE:
-+ hci_auth_complete_evt(hdev, skb);
-+ break;
-+
-+ case EVT_ENCRYPT_CHANGE:
-+ hci_encrypt_change_evt(hdev, skb);
-+ break;
-+
-+ case EVT_CMD_STATUS:
-+ cs = (evt_cmd_status *) skb->data;
-+ skb_pull(skb, EVT_CMD_STATUS_SIZE);
-+
-+ opcode = __le16_to_cpu(cs->opcode);
-+ ogf = cmd_opcode_ogf(opcode);
-+ ocf = cmd_opcode_ocf(opcode);
-+
-+ switch (ogf) {
-+ case OGF_INFO_PARAM:
-+ hci_cs_info_param(hdev, ocf, cs->status);
-+ break;
-+
-+ case OGF_HOST_CTL:
-+ hci_cs_host_ctl(hdev, ocf, cs->status);
-+ break;
-+
-+ case OGF_LINK_CTL:
-+ hci_cs_link_ctl(hdev, ocf, cs->status);
-+ break;
-+
-+ case OGF_LINK_POLICY:
-+ hci_cs_link_policy(hdev, ocf, cs->status);
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command Status OGF %x", hdev->name, ogf);
-+ break;
-+ };
-+
-+ if (cs->ncmd) {
-+ atomic_set(&hdev->cmd_cnt, 1);
-+ if (!skb_queue_empty(&hdev->cmd_q))
-+ hci_sched_cmd(hdev);
-+ }
-+ break;
-+
-+ case EVT_CMD_COMPLETE:
-+ ec = (evt_cmd_complete *) skb->data;
-+ skb_pull(skb, EVT_CMD_COMPLETE_SIZE);
-+
-+ opcode = __le16_to_cpu(ec->opcode);
-+ ogf = cmd_opcode_ogf(opcode);
-+ ocf = cmd_opcode_ocf(opcode);
-+
-+ switch (ogf) {
-+ case OGF_INFO_PARAM:
-+ hci_cc_info_param(hdev, ocf, skb);
-+ break;
-+
-+ case OGF_HOST_CTL:
-+ hci_cc_host_ctl(hdev, ocf, skb);
-+ break;
-+
-+ case OGF_LINK_CTL:
-+ hci_cc_link_ctl(hdev, ocf, skb);
-+ break;
-+
-+ case OGF_LINK_POLICY:
-+ hci_cc_link_policy(hdev, ocf, skb);
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command Completed OGF %x", hdev->name, ogf);
-+ break;
-+ };
-+
-+ if (ec->ncmd) {
-+ atomic_set(&hdev->cmd_cnt, 1);
-+ if (!skb_queue_empty(&hdev->cmd_q))
-+ hci_sched_cmd(hdev);
-+ }
-+ break;
-+ };
-+
-+ kfree_skb(skb);
-+ hdev->stat.evt_rx++;
-+}
-+
-+/* General internal stack event */
-+void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
-+{
-+ hci_event_hdr *eh;
-+ evt_stack_internal *si;
-+ struct sk_buff *skb;
-+ int size;
-+ void *ptr;
-+
-+ size = HCI_EVENT_HDR_SIZE + EVT_STACK_INTERNAL_SIZE + dlen;
-+ skb = bluez_skb_alloc(size, GFP_ATOMIC);
-+ if (!skb)
-+ return;
-+
-+ ptr = skb_put(skb, size);
-+
-+ eh = ptr;
-+ eh->evt = EVT_STACK_INTERNAL;
-+ eh->plen = EVT_STACK_INTERNAL_SIZE + dlen;
-+ ptr += HCI_EVENT_HDR_SIZE;
-+
-+ si = ptr;
-+ si->type = type;
-+ memcpy(si->data, data, dlen);
-+
-+ skb->pkt_type = HCI_EVENT_PKT;
-+ skb->dev = (void *) hdev;
-+ hci_send_to_sock(hdev, skb);
-+ kfree_skb(skb);
-+}
---- linux/net/bluetooth/hci_sock.c~bluetooth-2.4.18-mh11 2001-09-07 18:28:38.000000000 +0200
-+++ linux/net/bluetooth/hci_sock.c 2004-01-25 23:37:39.000000000 +0100
-@@ -25,7 +25,7 @@
- /*
- * BlueZ HCI socket layer.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
-@@ -49,45 +49,54 @@
-
- #include <asm/system.h>
- #include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
-
- #ifndef HCI_SOCK_DEBUG
--#undef DBG
--#define DBG( A... )
-+#undef BT_DBG
-+#define BT_DBG( A... )
- #endif
-
--/* HCI socket interface */
-+/* ----- HCI socket interface ----- */
-+
-+/* Security filter */
-+static struct hci_sec_filter hci_sec_filter = {
-+ /* Packet types */
-+ 0x10,
-+ /* Events */
-+ { 0x1000d9fe, 0x0000300c },
-+ /* Commands */
-+ {
-+ { 0x0 },
-+ /* OGF_LINK_CTL */
-+ { 0xbe000006, 0x00000001, 0x0000, 0x00 },
-+ /* OGF_LINK_POLICY */
-+ { 0x00005200, 0x00000000, 0x0000, 0x00 },
-+ /* OGF_HOST_CTL */
-+ { 0xaab00200, 0x2b402aaa, 0x0154, 0x00 },
-+ /* OGF_INFO_PARAM */
-+ { 0x000002be, 0x00000000, 0x0000, 0x00 },
-+ /* OGF_STATUS_PARAM */
-+ { 0x000000ea, 0x00000000, 0x0000, 0x00 }
-+ }
-+};
-
- static struct bluez_sock_list hci_sk_list = {
- lock: RW_LOCK_UNLOCKED
- };
-
--static struct sock *hci_sock_lookup(struct hci_dev *hdev)
--{
-- struct sock *sk;
--
-- read_lock(&hci_sk_list.lock);
-- for (sk = hci_sk_list.head; sk; sk = sk->next) {
-- if (hci_pi(sk)->hdev == hdev)
-- break;
-- }
-- read_unlock(&hci_sk_list.lock);
-- return sk;
--}
--
- /* Send frame to RAW socket */
- void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
- {
- struct sock * sk;
-
-- DBG("hdev %p len %d", hdev, skb->len);
-+ BT_DBG("hdev %p len %d", hdev, skb->len);
-
- read_lock(&hci_sk_list.lock);
- for (sk = hci_sk_list.head; sk; sk = sk->next) {
-- struct hci_filter *flt;
-+ struct hci_filter *flt;
- struct sk_buff *nskb;
-
- if (sk->state != BT_BOUND || hci_pi(sk)->hdev != hdev)
-@@ -100,13 +109,19 @@
- /* Apply filter */
- flt = &hci_pi(sk)->filter;
-
-- if (!test_bit(skb->pkt_type, &flt->type_mask))
-+ if (!hci_test_bit((skb->pkt_type & HCI_FLT_TYPE_BITS), &flt->type_mask))
- continue;
-
- if (skb->pkt_type == HCI_EVENT_PKT) {
-- register int evt = (*(__u8 *)skb->data & 63);
-+ register int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
-+
-+ if (!hci_test_bit(evt, &flt->event_mask))
-+ continue;
-
-- if (!test_bit(evt, &flt->event_mask))
-+ if (flt->opcode && ((evt == EVT_CMD_COMPLETE &&
-+ flt->opcode != *(__u16 *)(skb->data + 3)) ||
-+ (evt == EVT_CMD_STATUS &&
-+ flt->opcode != *(__u16 *)(skb->data + 4))))
- continue;
- }
-
-@@ -116,8 +131,8 @@
- /* Put type byte before the data */
- memcpy(skb_push(nskb, 1), &nskb->pkt_type, 1);
-
-- skb_queue_tail(&sk->receive_queue, nskb);
-- sk->data_ready(sk, nskb->len);
-+ if (sock_queue_rcv_skb(sk, nskb))
-+ kfree_skb(nskb);
- }
- read_unlock(&hci_sk_list.lock);
- }
-@@ -127,7 +142,7 @@
- struct sock *sk = sock->sk;
- struct hci_dev *hdev = hci_pi(sk)->hdev;
-
-- DBG("sock %p sk %p", sock, sk);
-+ BT_DBG("sock %p sk %p", sock, sk);
-
- if (!sk)
- return 0;
-@@ -135,9 +150,7 @@
- bluez_sock_unlink(&hci_sk_list, sk);
-
- if (hdev) {
-- if (!hci_sock_lookup(hdev))
-- hdev->flags &= ~HCI_SOCK;
--
-+ atomic_dec(&hdev->promisc);
- hci_dev_put(hdev);
- }
-
-@@ -149,24 +162,55 @@
- sock_put(sk);
-
- MOD_DEC_USE_COUNT;
--
- return 0;
- }
-
--static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+/* Ioctls that require bound socket */
-+static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
- {
-- struct sock *sk = sock->sk;
- struct hci_dev *hdev = hci_pi(sk)->hdev;
-- __u32 mode;
-
-- DBG("cmd %x arg %lx", cmd, arg);
-+ if (!hdev)
-+ return -EBADFD;
-
- switch (cmd) {
-- case HCIGETINFO:
-- return hci_dev_info(arg);
-+ case HCISETRAW:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (arg)
-+ set_bit(HCI_RAW, &hdev->flags);
-+ else
-+ clear_bit(HCI_RAW, &hdev->flags);
-+
-+ return 0;
-+
-+ case HCIGETCONNINFO:
-+ return hci_get_conn_info(hdev, arg);
-
-+ default:
-+ if (hdev->ioctl)
-+ return hdev->ioctl(hdev, cmd, arg);
-+ return -EINVAL;
-+ }
-+}
-+
-+static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct sock *sk = sock->sk;
-+ int err;
-+
-+ BT_DBG("cmd %x arg %lx", cmd, arg);
-+
-+ switch (cmd) {
- case HCIGETDEVLIST:
-- return hci_dev_list(arg);
-+ return hci_get_dev_list(arg);
-+
-+ case HCIGETDEVINFO:
-+ return hci_get_dev_info(arg);
-+
-+ case HCIGETCONNLIST:
-+ return hci_get_conn_list(arg);
-
- case HCIDEVUP:
- if (!capable(CAP_NET_ADMIN))
-@@ -183,48 +227,31 @@
- return -EACCES;
- return hci_dev_reset(arg);
-
-- case HCIRESETSTAT:
-+ case HCIDEVRESTAT:
- if (!capable(CAP_NET_ADMIN))
- return -EACCES;
- return hci_dev_reset_stat(arg);
-
- case HCISETSCAN:
-- if (!capable(CAP_NET_ADMIN))
-- return -EACCES;
-- return hci_dev_setscan(arg);
--
- case HCISETAUTH:
-- if (!capable(CAP_NET_ADMIN))
-- return -EACCES;
-- return hci_dev_setauth(arg);
--
-- case HCISETRAW:
-- if (!capable(CAP_NET_ADMIN))
-- return -EACCES;
--
-- if (!hdev)
-- return -EBADFD;
--
-- if (arg)
-- mode = HCI_RAW;
-- else
-- mode = HCI_NORMAL;
--
-- return hci_dev_setmode(hdev, mode);
--
-+ case HCISETENCRYPT:
- case HCISETPTYPE:
-+ case HCISETLINKPOL:
-+ case HCISETLINKMODE:
-+ case HCISETACLMTU:
-+ case HCISETSCOMTU:
- if (!capable(CAP_NET_ADMIN))
- return -EACCES;
-- return hci_dev_setptype(arg);
-+ return hci_dev_cmd(cmd, arg);
-
- case HCIINQUIRY:
- return hci_inquiry(arg);
-
-- case HCIGETCONNLIST:
-- return hci_conn_list(arg);
--
- default:
-- return -EINVAL;
-+ lock_sock(sk);
-+ err = hci_sock_bound_ioctl(sk, cmd, arg);
-+ release_sock(sk);
-+ return err;
- };
- }
-
-@@ -233,28 +260,35 @@
- struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
- struct sock *sk = sock->sk;
- struct hci_dev *hdev = NULL;
-+ int err = 0;
-
-- DBG("sock %p sk %p", sock, sk);
-+ BT_DBG("sock %p sk %p", sock, sk);
-
- if (!haddr || haddr->hci_family != AF_BLUETOOTH)
- return -EINVAL;
-
-+ lock_sock(sk);
-+
- if (hci_pi(sk)->hdev) {
-- /* Already bound */
-- return 0;
-+ err = -EALREADY;
-+ goto done;
- }
-
- if (haddr->hci_dev != HCI_DEV_NONE) {
-- if (!(hdev = hci_dev_get(haddr->hci_dev)))
-- return -ENODEV;
-+ if (!(hdev = hci_dev_get(haddr->hci_dev))) {
-+ err = -ENODEV;
-+ goto done;
-+ }
-
-- hdev->flags |= HCI_SOCK;
-+ atomic_inc(&hdev->promisc);
- }
-
- hci_pi(sk)->hdev = hdev;
- sk->state = BT_BOUND;
-
-- return 0;
-+done:
-+ release_sock(sk);
-+ return err;
- }
-
- static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer)
-@@ -262,73 +296,44 @@
- struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
- struct sock *sk = sock->sk;
-
-- DBG("sock %p sk %p", sock, sk);
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ lock_sock(sk);
-
- *addr_len = sizeof(*haddr);
- haddr->hci_family = AF_BLUETOOTH;
- haddr->hci_dev = hci_pi(sk)->hdev->id;
-
-+ release_sock(sk);
- return 0;
- }
-
--static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
-- struct scm_cookie *scm)
--{
-- struct sock *sk = sock->sk;
-- struct hci_dev *hdev = hci_pi(sk)->hdev;
-- struct sk_buff *skb;
-- int err;
--
-- DBG("sock %p sk %p", sock, sk);
--
-- if (msg->msg_flags & MSG_OOB)
-- return -EOPNOTSUPP;
--
-- if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
-- return -EINVAL;
--
-- if (!hdev)
-- return -EBADFD;
--
-- if (!(skb = bluez_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
-- return err;
--
-- if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
-- kfree_skb(skb);
-- return -EFAULT;
-- }
--
-- skb->dev = (void *) hdev;
-- skb->pkt_type = *((unsigned char *) skb->data);
-- skb_pull(skb, 1);
--
-- /* Send frame to HCI core */
-- hci_send_raw(skb);
--
-- return len;
--}
--
- static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
- {
- __u32 mask = hci_pi(sk)->cmsg_mask;
-
- if (mask & HCI_CMSG_DIR)
- put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(int), &bluez_cb(skb)->incomming);
-+
-+ if (mask & HCI_CMSG_TSTAMP)
-+ put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, sizeof(skb->stamp), &skb->stamp);
- }
-
--static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len,
-- int flags, struct scm_cookie *scm)
-+static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
- {
- int noblock = flags & MSG_DONTWAIT;
- struct sock *sk = sock->sk;
- struct sk_buff *skb;
- int copied, err;
-
-- DBG("sock %p sk %p", sock, sk);
-+ BT_DBG("sock %p, sk %p", sock, sk);
-
-- if (flags & (MSG_OOB | MSG_PEEK))
-+ if (flags & (MSG_OOB))
- return -EOPNOTSUPP;
-
-+ if (sk->state == BT_CLOSED)
-+ return 0;
-+
- if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
- return err;
-
-@@ -343,28 +348,107 @@
- skb->h.raw = skb->data;
- err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
-
-- if (hci_pi(sk)->cmsg_mask)
-- hci_sock_cmsg(sk, msg, skb);
--
-+ hci_sock_cmsg(sk, msg, skb);
-+
- skb_free_datagram(sk, skb);
-
- return err ? : copied;
- }
-
-+static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
-+ struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ struct hci_dev *hdev;
-+ struct sk_buff *skb;
-+ int err;
-+
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ if (msg->msg_flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
-+ return -EINVAL;
-+
-+ if (len < 4)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (!(hdev = hci_pi(sk)->hdev)) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ if (!(skb = bluez_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
-+ goto done;
-+
-+ if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
-+ err = -EFAULT;
-+ goto drop;
-+ }
-+
-+ skb->pkt_type = *((unsigned char *) skb->data);
-+ skb_pull(skb, 1);
-+ skb->dev = (void *) hdev;
-+
-+ if (skb->pkt_type == HCI_COMMAND_PKT) {
-+ u16 opcode = __le16_to_cpu(get_unaligned((u16 *)skb->data));
-+ u16 ogf = cmd_opcode_ogf(opcode);
-+ u16 ocf = cmd_opcode_ocf(opcode);
-+
-+ if (((ogf > HCI_SFLT_MAX_OGF) ||
-+ !hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) &&
-+ !capable(CAP_NET_RAW)) {
-+ err = -EPERM;
-+ goto drop;
-+ }
-+
-+ if (test_bit(HCI_RAW, &hdev->flags) || (ogf == OGF_VENDOR_CMD)) {
-+ skb_queue_tail(&hdev->raw_q, skb);
-+ hci_sched_tx(hdev);
-+ } else {
-+ skb_queue_tail(&hdev->cmd_q, skb);
-+ hci_sched_cmd(hdev);
-+ }
-+ } else {
-+ if (!capable(CAP_NET_RAW)) {
-+ err = -EPERM;
-+ goto drop;
-+ }
-+
-+ skb_queue_tail(&hdev->raw_q, skb);
-+ hci_sched_tx(hdev);
-+ }
-+
-+ err = len;
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+
-+drop:
-+ kfree_skb(skb);
-+ goto done;
-+}
-+
- int hci_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int len)
- {
- struct sock *sk = sock->sk;
-- struct hci_filter flt;
-+ struct hci_filter flt = { opcode: 0 };
- int err = 0, opt = 0;
-
-- DBG("sk %p, opt %d", sk, optname);
-+ BT_DBG("sk %p, opt %d", sk, optname);
-
- lock_sock(sk);
-
- switch (optname) {
- case HCI_DATA_DIR:
-- if (get_user(opt, (int *)optval))
-- return -EFAULT;
-+ if (get_user(opt, (int *)optval)) {
-+ err = -EFAULT;
-+ break;
-+ }
-
- if (opt)
- hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
-@@ -372,12 +456,31 @@
- hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
- break;
-
-+ case HCI_TIME_STAMP:
-+ if (get_user(opt, (int *)optval)) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ if (opt)
-+ hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
-+ else
-+ hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
-+ break;
-+
- case HCI_FILTER:
- len = MIN(len, sizeof(struct hci_filter));
- if (copy_from_user(&flt, optval, len)) {
- err = -EFAULT;
- break;
- }
-+
-+ if (!capable(CAP_NET_RAW)) {
-+ flt.type_mask &= hci_sec_filter.type_mask;
-+ flt.event_mask[0] &= hci_sec_filter.event_mask[0];
-+ flt.event_mask[1] &= hci_sec_filter.event_mask[1];
-+ }
-+
- memcpy(&hci_pi(sk)->filter, &flt, len);
- break;
-
-@@ -409,6 +512,16 @@
- return -EFAULT;
- break;
-
-+ case HCI_TIME_STAMP:
-+ if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
-+ opt = 1;
-+ else
-+ opt = 0;
-+
-+ if (put_user(opt, optval))
-+ return -EFAULT;
-+ break;
-+
- case HCI_FILTER:
- len = MIN(len, sizeof(struct hci_filter));
- if (copy_to_user(optval, &hci_pi(sk)->filter, len))
-@@ -446,7 +559,7 @@
- {
- struct sock *sk;
-
-- DBG("sock %p", sock);
-+ BT_DBG("sock %p", sock);
-
- if (sock->type != SOCK_RAW)
- return -ESOCKTNOSUPPORT;
-@@ -464,44 +577,31 @@
- sk->protocol = protocol;
- sk->state = BT_OPEN;
-
-- /* Initialize filter */
-- hci_pi(sk)->filter.type_mask = (1<<HCI_EVENT_PKT);
-- hci_pi(sk)->filter.event_mask[0] = ~0L;
-- hci_pi(sk)->filter.event_mask[1] = ~0L;
--
- bluez_sock_link(&hci_sk_list, sk);
-
- MOD_INC_USE_COUNT;
--
- return 0;
- }
-
- static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
- {
- struct hci_dev *hdev = (struct hci_dev *) ptr;
-- struct sk_buff *skb;
--
-- DBG("hdev %s event %ld", hdev->name, event);
-+ evt_si_device sd;
-+
-+ BT_DBG("hdev %s event %ld", hdev->name, event);
-
- /* Send event to sockets */
-- if ((skb = bluez_skb_alloc(HCI_EVENT_HDR_SIZE + EVT_HCI_DEV_EVENT_SIZE, GFP_ATOMIC))) {
-- hci_event_hdr eh = { EVT_HCI_DEV_EVENT, EVT_HCI_DEV_EVENT_SIZE };
-- evt_hci_dev_event he = { event, hdev->id };
--
-- skb->pkt_type = HCI_EVENT_PKT;
-- memcpy(skb_put(skb, HCI_EVENT_HDR_SIZE), &eh, HCI_EVENT_HDR_SIZE);
-- memcpy(skb_put(skb, EVT_HCI_DEV_EVENT_SIZE), &he, EVT_HCI_DEV_EVENT_SIZE);
--
-- hci_send_to_sock(NULL, skb);
-- kfree_skb(skb);
-- }
--
-+ sd.event = event;
-+ sd.dev_id = hdev->id;
-+ hci_si_event(NULL, EVT_SI_DEVICE, EVT_SI_DEVICE_SIZE, &sd);
-+
- if (event == HCI_DEV_UNREG) {
- struct sock *sk;
-
- /* Detach sockets from device */
- read_lock(&hci_sk_list.lock);
- for (sk = hci_sk_list.head; sk; sk = sk->next) {
-+ bh_lock_sock(sk);
- if (hci_pi(sk)->hdev == hdev) {
- hci_pi(sk)->hdev = NULL;
- sk->err = EPIPE;
-@@ -510,6 +610,7 @@
-
- hci_dev_put(hdev);
- }
-+ bh_unlock_sock(sk);
- }
- read_unlock(&hci_sk_list.lock);
- }
-@@ -529,21 +630,19 @@
- int hci_sock_init(void)
- {
- if (bluez_sock_register(BTPROTO_HCI, &hci_sock_family_ops)) {
-- ERR("Can't register HCI socket");
-+ BT_ERR("Can't register HCI socket");
- return -EPROTO;
- }
-
- hci_register_notifier(&hci_sock_nblock);
--
- return 0;
- }
-
- int hci_sock_cleanup(void)
- {
- if (bluez_sock_unregister(BTPROTO_HCI))
-- ERR("Can't unregister HCI socket");
-+ BT_ERR("Can't unregister HCI socket");
-
- hci_unregister_notifier(&hci_sock_nblock);
--
- return 0;
- }
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/l2cap.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,2187 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * BlueZ L2CAP core and sockets.
-+ *
-+ * $Id$
-+ */
-+#define VERSION "2.3"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/socket.h>
-+#include <linux/skbuff.h>
-+#include <linux/proc_fs.h>
-+#include <linux/list.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#ifndef L2CAP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+static struct proto_ops l2cap_sock_ops;
-+
-+struct bluez_sock_list l2cap_sk_list = {
-+ lock: RW_LOCK_UNLOCKED
-+};
-+
-+static int l2cap_conn_del(struct hci_conn *conn, int err);
-+
-+static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
-+static void l2cap_chan_del(struct sock *sk, int err);
-+static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len);
-+
-+static void __l2cap_sock_close(struct sock *sk, int reason);
-+static void l2cap_sock_close(struct sock *sk);
-+static void l2cap_sock_kill(struct sock *sk);
-+
-+static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data);
-+static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data);
-+
-+/* ----- L2CAP timers ------ */
-+static void l2cap_sock_timeout(unsigned long arg)
-+{
-+ struct sock *sk = (struct sock *) arg;
-+
-+ BT_DBG("sock %p state %d", sk, sk->state);
-+
-+ bh_lock_sock(sk);
-+ __l2cap_sock_close(sk, ETIMEDOUT);
-+ bh_unlock_sock(sk);
-+
-+ l2cap_sock_kill(sk);
-+ sock_put(sk);
-+}
-+
-+static void l2cap_sock_set_timer(struct sock *sk, long timeout)
-+{
-+ BT_DBG("sk %p state %d timeout %ld", sk, sk->state, timeout);
-+
-+ if (!mod_timer(&sk->timer, jiffies + timeout))
-+ sock_hold(sk);
-+}
-+
-+static void l2cap_sock_clear_timer(struct sock *sk)
-+{
-+ BT_DBG("sock %p state %d", sk, sk->state);
-+
-+ if (timer_pending(&sk->timer) && del_timer(&sk->timer))
-+ __sock_put(sk);
-+}
-+
-+static void l2cap_sock_init_timer(struct sock *sk)
-+{
-+ init_timer(&sk->timer);
-+ sk->timer.function = l2cap_sock_timeout;
-+ sk->timer.data = (unsigned long)sk;
-+}
-+
-+/* -------- L2CAP connections --------- */
-+static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, __u8 status)
-+{
-+ struct l2cap_conn *conn;
-+
-+ if ((conn = hcon->l2cap_data))
-+ return conn;
-+
-+ if (status)
-+ return conn;
-+
-+ if (!(conn = kmalloc(sizeof(struct l2cap_conn), GFP_ATOMIC)))
-+ return NULL;
-+ memset(conn, 0, sizeof(struct l2cap_conn));
-+
-+ hcon->l2cap_data = conn;
-+ conn->hcon = hcon;
-+
-+ conn->mtu = hcon->hdev->acl_mtu;
-+ conn->src = &hcon->hdev->bdaddr;
-+ conn->dst = &hcon->dst;
-+
-+ spin_lock_init(&conn->lock);
-+ conn->chan_list.lock = RW_LOCK_UNLOCKED;
-+
-+ BT_DBG("hcon %p conn %p", hcon, conn);
-+
-+ MOD_INC_USE_COUNT;
-+ return conn;
-+}
-+
-+static int l2cap_conn_del(struct hci_conn *hcon, int err)
-+{
-+ struct l2cap_conn *conn;
-+ struct sock *sk;
-+
-+ if (!(conn = hcon->l2cap_data))
-+ return 0;
-+
-+ BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
-+
-+ if (conn->rx_skb)
-+ kfree_skb(conn->rx_skb);
-+
-+ /* Kill channels */
-+ while ((sk = conn->chan_list.head)) {
-+ bh_lock_sock(sk);
-+ l2cap_chan_del(sk, err);
-+ bh_unlock_sock(sk);
-+ l2cap_sock_kill(sk);
-+ }
-+
-+ hcon->l2cap_data = NULL;
-+ kfree(conn);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+/* -------- Socket interface ---------- */
-+static struct sock *__l2cap_get_sock_by_addr(__u16 psm, bdaddr_t *src)
-+{
-+ struct sock *sk;
-+ for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-+ if (sk->sport == psm && !bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+ }
-+ return sk;
-+}
-+
-+/* Find socket with psm and source bdaddr.
-+ * Returns closest match.
-+ */
-+static struct sock *__l2cap_get_sock_by_psm(int state, __u16 psm, bdaddr_t *src)
-+{
-+ struct sock *sk, *sk1 = NULL;
-+
-+ for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-+ if (state && sk->state != state)
-+ continue;
-+
-+ if (l2cap_pi(sk)->psm == psm) {
-+ /* Exact match. */
-+ if (!bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+
-+ /* Closest match */
-+ if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
-+ sk1 = sk;
-+ }
-+ }
-+ return sk ? sk : sk1;
-+}
-+
-+/* Find socket with given address (psm, src).
-+ * Returns locked socket */
-+static inline struct sock *l2cap_get_sock_by_psm(int state, __u16 psm, bdaddr_t *src)
-+{
-+ struct sock *s;
-+ read_lock(&l2cap_sk_list.lock);
-+ s = __l2cap_get_sock_by_psm(state, psm, src);
-+ if (s) bh_lock_sock(s);
-+ read_unlock(&l2cap_sk_list.lock);
-+ return s;
-+}
-+
-+static void l2cap_sock_destruct(struct sock *sk)
-+{
-+ BT_DBG("sk %p", sk);
-+
-+ skb_queue_purge(&sk->receive_queue);
-+ skb_queue_purge(&sk->write_queue);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void l2cap_sock_cleanup_listen(struct sock *parent)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("parent %p", parent);
-+
-+ /* Close not yet accepted channels */
-+ while ((sk = bluez_accept_dequeue(parent, NULL)))
-+ l2cap_sock_close(sk);
-+
-+ parent->state = BT_CLOSED;
-+ parent->zapped = 1;
-+}
-+
-+/* Kill socket (only if zapped and orphan)
-+ * Must be called on unlocked socket.
-+ */
-+static void l2cap_sock_kill(struct sock *sk)
-+{
-+ if (!sk->zapped || sk->socket)
-+ return;
-+
-+ BT_DBG("sk %p state %d", sk, sk->state);
-+
-+ /* Kill poor orphan */
-+ bluez_sock_unlink(&l2cap_sk_list, sk);
-+ sk->dead = 1;
-+ sock_put(sk);
-+}
-+
-+/* Close socket.
-+ */
-+static void __l2cap_sock_close(struct sock *sk, int reason)
-+{
-+ BT_DBG("sk %p state %d socket %p", sk, sk->state, sk->socket);
-+
-+ switch (sk->state) {
-+ case BT_LISTEN:
-+ l2cap_sock_cleanup_listen(sk);
-+ break;
-+
-+ case BT_CONNECTED:
-+ case BT_CONFIG:
-+ case BT_CONNECT2:
-+ if (sk->type == SOCK_SEQPACKET) {
-+ struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-+ l2cap_disconn_req req;
-+
-+ sk->state = BT_DISCONN;
-+ l2cap_sock_set_timer(sk, sk->sndtimeo);
-+
-+ req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
-+ } else {
-+ l2cap_chan_del(sk, reason);
-+ }
-+ break;
-+
-+ case BT_CONNECT:
-+ case BT_DISCONN:
-+ l2cap_chan_del(sk, reason);
-+ break;
-+
-+ default:
-+ sk->zapped = 1;
-+ break;
-+ };
-+}
-+
-+/* Must be called on unlocked socket. */
-+static void l2cap_sock_close(struct sock *sk)
-+{
-+ l2cap_sock_clear_timer(sk);
-+ lock_sock(sk);
-+ __l2cap_sock_close(sk, ECONNRESET);
-+ release_sock(sk);
-+ l2cap_sock_kill(sk);
-+}
-+
-+static void l2cap_sock_init(struct sock *sk, struct sock *parent)
-+{
-+ struct l2cap_pinfo *pi = l2cap_pi(sk);
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (parent) {
-+ sk->type = parent->type;
-+ pi->imtu = l2cap_pi(parent)->imtu;
-+ pi->omtu = l2cap_pi(parent)->omtu;
-+ pi->link_mode = l2cap_pi(parent)->link_mode;
-+ } else {
-+ pi->imtu = L2CAP_DEFAULT_MTU;
-+ pi->omtu = 0;
-+ pi->link_mode = 0;
-+ }
-+
-+ /* Default config options */
-+ pi->conf_mtu = L2CAP_DEFAULT_MTU;
-+ pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
-+}
-+
-+static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
-+{
-+ struct sock *sk;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
-+ return NULL;
-+
-+ bluez_sock_init(sock, sk);
-+
-+ sk->zapped = 0;
-+
-+ sk->destruct = l2cap_sock_destruct;
-+ sk->sndtimeo = L2CAP_CONN_TIMEOUT;
-+
-+ sk->protocol = proto;
-+ sk->state = BT_OPEN;
-+
-+ l2cap_sock_init_timer(sk);
-+
-+ bluez_sock_link(&l2cap_sk_list, sk);
-+
-+ MOD_INC_USE_COUNT;
-+ return sk;
-+}
-+
-+static int l2cap_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ sock->state = SS_UNCONNECTED;
-+
-+ if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ if (sock->type == SOCK_RAW && !capable(CAP_NET_RAW))
-+ return -EPERM;
-+
-+ sock->ops = &l2cap_sock_ops;
-+
-+ if (!(sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ l2cap_sock_init(sk, NULL);
-+ return 0;
-+}
-+
-+static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
-+{
-+ struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
-+
-+ if (!addr || addr->sa_family != AF_BLUETOOTH)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_OPEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ write_lock_bh(&l2cap_sk_list.lock);
-+ if (la->l2_psm && __l2cap_get_sock_by_addr(la->l2_psm, &la->l2_bdaddr)) {
-+ err = -EADDRINUSE;
-+ } else {
-+ /* Save source address */
-+ bacpy(&bluez_pi(sk)->src, &la->l2_bdaddr);
-+ l2cap_pi(sk)->psm = la->l2_psm;
-+ sk->sport = la->l2_psm;
-+ sk->state = BT_BOUND;
-+ }
-+ write_unlock_bh(&l2cap_sk_list.lock);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_do_connect(struct sock *sk)
-+{
-+ bdaddr_t *src = &bluez_pi(sk)->src;
-+ bdaddr_t *dst = &bluez_pi(sk)->dst;
-+ struct l2cap_conn *conn;
-+ struct hci_conn *hcon;
-+ struct hci_dev *hdev;
-+ int err = 0;
-+
-+ BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
-+
-+ if (!(hdev = hci_get_route(dst, src)))
-+ return -EHOSTUNREACH;
-+
-+ hci_dev_lock_bh(hdev);
-+
-+ err = -ENOMEM;
-+
-+ hcon = hci_connect(hdev, ACL_LINK, dst);
-+ if (!hcon)
-+ goto done;
-+
-+ conn = l2cap_conn_add(hcon, 0);
-+ if (!conn) {
-+ hci_conn_put(hcon);
-+ goto done;
-+ }
-+
-+ err = 0;
-+
-+ /* Update source addr of the socket */
-+ bacpy(src, conn->src);
-+
-+ l2cap_chan_add(conn, sk, NULL);
-+
-+ sk->state = BT_CONNECT;
-+ l2cap_sock_set_timer(sk, sk->sndtimeo);
-+
-+ if (hcon->state == BT_CONNECTED) {
-+ if (sk->type == SOCK_SEQPACKET) {
-+ l2cap_conn_req req;
-+ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ req.psm = l2cap_pi(sk)->psm;
-+ l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
-+ } else {
-+ l2cap_sock_clear_timer(sk);
-+ sk->state = BT_CONNECTED;
-+ }
-+ }
-+
-+done:
-+ hci_dev_unlock_bh(hdev);
-+ hci_dev_put(hdev);
-+ return err;
-+}
-+
-+static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
-+{
-+ struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ lock_sock(sk);
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) {
-+ err = -EINVAL;
-+ goto done;
-+ }
-+
-+ if (sk->type == SOCK_SEQPACKET && !la->l2_psm) {
-+ err = -EINVAL;
-+ goto done;
-+ }
-+
-+ switch(sk->state) {
-+ case BT_CONNECT:
-+ case BT_CONNECT2:
-+ case BT_CONFIG:
-+ /* Already connecting */
-+ goto wait;
-+
-+ case BT_CONNECTED:
-+ /* Already connected */
-+ goto done;
-+
-+ case BT_OPEN:
-+ case BT_BOUND:
-+ /* Can connect */
-+ break;
-+
-+ default:
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ /* Set destination address and psm */
-+ bacpy(&bluez_pi(sk)->dst, &la->l2_bdaddr);
-+ l2cap_pi(sk)->psm = la->l2_psm;
-+
-+ if ((err = l2cap_do_connect(sk)))
-+ goto done;
-+
-+wait:
-+ err = bluez_sock_wait_state(sk, BT_CONNECTED,
-+ sock_sndtimeo(sk, flags & O_NONBLOCK));
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int l2cap_sock_listen(struct socket *sock, int backlog)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p backlog %d", sk, backlog);
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ if (!l2cap_pi(sk)->psm) {
-+ err = -EINVAL;
-+ goto done;
-+ }
-+
-+ sk->max_ack_backlog = backlog;
-+ sk->ack_backlog = 0;
-+ sk->state = BT_LISTEN;
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct sock *sk = sock->sk, *nsk;
-+ long timeo;
-+ int err = 0;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
-+
-+ BT_DBG("sk %p timeo %ld", sk, timeo);
-+
-+ /* Wait for an incoming connection. (wake-one). */
-+ add_wait_queue_exclusive(sk->sleep, &wait);
-+ while (!(nsk = bluez_accept_dequeue(sk, newsock))) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ break;
-+ }
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ break;
-+ }
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ if (err)
-+ goto done;
-+
-+ newsock->state = SS_CONNECTED;
-+
-+ BT_DBG("new socket %p", nsk);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
-+{
-+ struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ addr->sa_family = AF_BLUETOOTH;
-+ *len = sizeof(struct sockaddr_l2);
-+
-+ if (peer)
-+ bacpy(&la->l2_bdaddr, &bluez_pi(sk)->dst);
-+ else
-+ bacpy(&la->l2_bdaddr, &bluez_pi(sk)->src);
-+
-+ la->l2_psm = l2cap_pi(sk)->psm;
-+ return 0;
-+}
-+
-+static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (sk->err)
-+ return sock_error(sk);
-+
-+ if (msg->msg_flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ /* Check outgoing MTU */
-+ if (len > l2cap_pi(sk)->omtu)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state == BT_CONNECTED)
-+ err = l2cap_chan_send(sk, msg, len);
-+ else
-+ err = -ENOTCONN;
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ struct l2cap_options opts;
-+ int err = 0, len;
-+ __u32 opt;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ case L2CAP_OPTIONS:
-+ len = MIN(sizeof(opts), optlen);
-+ if (copy_from_user((char *)&opts, optval, len)) {
-+ err = -EFAULT;
-+ break;
-+ }
-+ l2cap_pi(sk)->imtu = opts.imtu;
-+ l2cap_pi(sk)->omtu = opts.omtu;
-+ break;
-+
-+ case L2CAP_LM:
-+ if (get_user(opt, (__u32 *)optval)) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ l2cap_pi(sk)->link_mode = opt;
-+ break;
-+
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ struct l2cap_options opts;
-+ struct l2cap_conninfo cinfo;
-+ int len, err = 0;
-+
-+ if (get_user(len, optlen))
-+ return -EFAULT;
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ case L2CAP_OPTIONS:
-+ opts.imtu = l2cap_pi(sk)->imtu;
-+ opts.omtu = l2cap_pi(sk)->omtu;
-+ opts.flush_to = l2cap_pi(sk)->flush_to;
-+
-+ len = MIN(len, sizeof(opts));
-+ if (copy_to_user(optval, (char *)&opts, len))
-+ err = -EFAULT;
-+
-+ break;
-+
-+ case L2CAP_LM:
-+ if (put_user(l2cap_pi(sk)->link_mode, (__u32 *)optval))
-+ err = -EFAULT;
-+ break;
-+
-+ case L2CAP_CONNINFO:
-+ if (sk->state != BT_CONNECTED) {
-+ err = -ENOTCONN;
-+ break;
-+ }
-+
-+ cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
-+
-+ len = MIN(len, sizeof(cinfo));
-+ if (copy_to_user(optval, (char *)&cinfo, len))
-+ err = -EFAULT;
-+
-+ break;
-+
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_shutdown(struct socket *sock, int how)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk) return 0;
-+
-+ lock_sock(sk);
-+ if (!sk->shutdown) {
-+ sk->shutdown = SHUTDOWN_MASK;
-+ l2cap_sock_clear_timer(sk);
-+ __l2cap_sock_close(sk, 0);
-+
-+ if (sk->linger)
-+ err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
-+ }
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+ int err;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk) return 0;
-+
-+ err = l2cap_sock_shutdown(sock, 2);
-+
-+ sock_orphan(sk);
-+ l2cap_sock_kill(sk);
-+ return err;
-+}
-+
-+/* --------- L2CAP channels --------- */
-+static struct sock * __l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
-+{
-+ struct sock *s;
-+ for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-+ if (l2cap_pi(s)->dcid == cid)
-+ break;
-+ }
-+ return s;
-+}
-+
-+static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
-+{
-+ struct sock *s;
-+ for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-+ if (l2cap_pi(s)->scid == cid)
-+ break;
-+ }
-+ return s;
-+}
-+
-+/* Find channel with given SCID.
-+ * Returns locked socket */
-+static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
-+{
-+ struct sock *s;
-+ read_lock(&l->lock);
-+ s = __l2cap_get_chan_by_scid(l, cid);
-+ if (s) bh_lock_sock(s);
-+ read_unlock(&l->lock);
-+ return s;
-+}
-+
-+static __u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
-+{
-+ __u16 cid = 0x0040;
-+
-+ for (; cid < 0xffff; cid++) {
-+ if(!__l2cap_get_chan_by_scid(l, cid))
-+ return cid;
-+ }
-+
-+ return 0;
-+}
-+
-+static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
-+{
-+ sock_hold(sk);
-+
-+ if (l->head)
-+ l2cap_pi(l->head)->prev_c = sk;
-+
-+ l2cap_pi(sk)->next_c = l->head;
-+ l2cap_pi(sk)->prev_c = NULL;
-+ l->head = sk;
-+}
-+
-+static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
-+{
-+ struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
-+
-+ write_lock(&l->lock);
-+ if (sk == l->head)
-+ l->head = next;
-+
-+ if (next)
-+ l2cap_pi(next)->prev_c = prev;
-+ if (prev)
-+ l2cap_pi(prev)->next_c = next;
-+ write_unlock(&l->lock);
-+
-+ __sock_put(sk);
-+}
-+
-+static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+
-+ BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
-+
-+ l2cap_pi(sk)->conn = conn;
-+
-+ if (sk->type == SOCK_SEQPACKET) {
-+ /* Alloc CID for connection-oriented socket */
-+ l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
-+ } else if (sk->type == SOCK_DGRAM) {
-+ /* Connectionless socket */
-+ l2cap_pi(sk)->scid = 0x0002;
-+ l2cap_pi(sk)->dcid = 0x0002;
-+ l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
-+ } else {
-+ /* Raw socket can send/recv signalling messages only */
-+ l2cap_pi(sk)->scid = 0x0001;
-+ l2cap_pi(sk)->dcid = 0x0001;
-+ l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
-+ }
-+
-+ __l2cap_chan_link(l, sk);
-+
-+ if (parent)
-+ bluez_accept_enqueue(parent, sk);
-+}
-+
-+static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+ write_lock(&l->lock);
-+ __l2cap_chan_add(conn, sk, parent);
-+ write_unlock(&l->lock);
-+}
-+
-+/* Delete channel.
-+ * Must be called on the locked socket. */
-+static void l2cap_chan_del(struct sock *sk, int err)
-+{
-+ struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-+ struct sock *parent = bluez_pi(sk)->parent;
-+
-+ l2cap_sock_clear_timer(sk);
-+
-+ BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
-+
-+ if (conn) {
-+ /* Unlink from channel list */
-+ l2cap_chan_unlink(&conn->chan_list, sk);
-+ l2cap_pi(sk)->conn = NULL;
-+ hci_conn_put(conn->hcon);
-+ }
-+
-+ sk->state = BT_CLOSED;
-+ sk->zapped = 1;
-+
-+ if (err)
-+ sk->err = err;
-+
-+ if (parent)
-+ parent->data_ready(parent, 0);
-+ else
-+ sk->state_change(sk);
-+}
-+
-+static void l2cap_conn_ready(struct l2cap_conn *conn)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+ struct sock *sk;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ bh_lock_sock(sk);
-+
-+ if (sk->type != SOCK_SEQPACKET) {
-+ l2cap_sock_clear_timer(sk);
-+ sk->state = BT_CONNECTED;
-+ sk->state_change(sk);
-+ } else if (sk->state == BT_CONNECT) {
-+ l2cap_conn_req req;
-+ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ req.psm = l2cap_pi(sk)->psm;
-+ l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
-+ }
-+
-+ bh_unlock_sock(sk);
-+ }
-+
-+ read_unlock(&l->lock);
-+}
-+
-+/* Notify sockets that we cannot guaranty reliability anymore */
-+static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+ struct sock *sk;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ if (l2cap_pi(sk)->link_mode & L2CAP_LM_RELIABLE)
-+ sk->err = err;
-+ }
-+ read_unlock(&l->lock);
-+}
-+
-+static void l2cap_chan_ready(struct sock *sk)
-+{
-+ struct sock *parent = bluez_pi(sk)->parent;
-+
-+ BT_DBG("sk %p, parent %p", sk, parent);
-+
-+ l2cap_pi(sk)->conf_state = 0;
-+ l2cap_sock_clear_timer(sk);
-+
-+ if (!parent) {
-+ /* Outgoing channel.
-+ * Wake up socket sleeping on connect.
-+ */
-+ sk->state = BT_CONNECTED;
-+ sk->state_change(sk);
-+ } else {
-+ /* Incomming channel.
-+ * Wake up socket sleeping on accept.
-+ */
-+ parent->data_ready(parent, 0);
-+ }
-+}
-+
-+/* Copy frame to all raw sockets on that connection */
-+void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+ struct sk_buff *nskb;
-+ struct sock * sk;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ if (sk->type != SOCK_RAW)
-+ continue;
-+
-+ /* Don't send frame to the socket it came from */
-+ if (skb->sk == sk)
-+ continue;
-+
-+ if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
-+ continue;
-+
-+ if (sock_queue_rcv_skb(sk, nskb))
-+ kfree_skb(nskb);
-+ }
-+ read_unlock(&l->lock);
-+}
-+
-+static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
-+{
-+ struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-+ struct sk_buff *skb, **frag;
-+ int err, hlen, count, sent=0;
-+ l2cap_hdr *lh;
-+
-+ BT_DBG("sk %p len %d", sk, len);
-+
-+ /* First fragment (with L2CAP header) */
-+ if (sk->type == SOCK_DGRAM)
-+ hlen = L2CAP_HDR_SIZE + 2;
-+ else
-+ hlen = L2CAP_HDR_SIZE;
-+
-+ count = MIN(conn->mtu - hlen, len);
-+
-+ skb = bluez_skb_send_alloc(sk, hlen + count,
-+ msg->msg_flags & MSG_DONTWAIT, &err);
-+ if (!skb)
-+ return err;
-+
-+ /* Create L2CAP header */
-+ lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-+ lh->cid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ lh->len = __cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
-+
-+ if (sk->type == SOCK_DGRAM)
-+ put_unaligned(l2cap_pi(sk)->psm, (__u16 *) skb_put(skb, 2));
-+
-+ if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
-+ err = -EFAULT;
-+ goto fail;
-+ }
-+
-+ sent += count;
-+ len -= count;
-+
-+ /* Continuation fragments (no L2CAP header) */
-+ frag = &skb_shinfo(skb)->frag_list;
-+ while (len) {
-+ count = MIN(conn->mtu, len);
-+
-+ *frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
-+ if (!*frag)
-+ goto fail;
-+
-+ if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
-+ err = -EFAULT;
-+ goto fail;
-+ }
-+
-+ sent += count;
-+ len -= count;
-+
-+ frag = &(*frag)->next;
-+ }
-+
-+ if ((err = hci_send_acl(conn->hcon, skb, 0)) < 0)
-+ goto fail;
-+
-+ return sent;
-+
-+fail:
-+ kfree_skb(skb);
-+ return err;
-+}
-+
-+/* --------- L2CAP signalling commands --------- */
-+static inline __u8 l2cap_get_ident(struct l2cap_conn *conn)
-+{
-+ __u8 id;
-+
-+ /* Get next available identificator.
-+ * 1 - 199 are used by kernel.
-+ * 200 - 254 are used by utilities like l2ping, etc
-+ */
-+
-+ spin_lock(&conn->lock);
-+
-+ if (++conn->tx_ident > 199)
-+ conn->tx_ident = 1;
-+
-+ id = conn->tx_ident;
-+
-+ spin_unlock(&conn->lock);
-+
-+ return id;
-+}
-+
-+static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
-+ __u8 code, __u8 ident, __u16 dlen, void *data)
-+{
-+ struct sk_buff *skb, **frag;
-+ l2cap_cmd_hdr *cmd;
-+ l2cap_hdr *lh;
-+ int len, count;
-+
-+ BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", conn, code, ident, dlen);
-+
-+ len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
-+ count = MIN(conn->mtu, len);
-+
-+ skb = bluez_skb_alloc(count, GFP_ATOMIC);
-+ if (!skb)
-+ return NULL;
-+
-+ lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-+ lh->len = __cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
-+ lh->cid = __cpu_to_le16(0x0001);
-+
-+ cmd = (l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
-+ cmd->code = code;
-+ cmd->ident = ident;
-+ cmd->len = __cpu_to_le16(dlen);
-+
-+ if (dlen) {
-+ count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
-+ memcpy(skb_put(skb, count), data, count);
-+ data += count;
-+ }
-+
-+ len -= skb->len;
-+
-+ /* Continuation fragments (no L2CAP header) */
-+ frag = &skb_shinfo(skb)->frag_list;
-+ while (len) {
-+ count = MIN(conn->mtu, len);
-+
-+ *frag = bluez_skb_alloc(count, GFP_ATOMIC);
-+ if (!*frag)
-+ goto fail;
-+
-+ memcpy(skb_put(*frag, count), data, count);
-+
-+ len -= count;
-+ data += count;
-+
-+ frag = &(*frag)->next;
-+ }
-+
-+ return skb;
-+
-+fail:
-+ kfree_skb(skb);
-+ return NULL;
-+}
-+
-+static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data)
-+{
-+ __u8 ident = l2cap_get_ident(conn);
-+ struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
-+
-+ BT_DBG("code 0x%2.2x", code);
-+
-+ if (!skb)
-+ return -ENOMEM;
-+ return hci_send_acl(conn->hcon, skb, 0);
-+}
-+
-+static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data)
-+{
-+ struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
-+
-+ BT_DBG("code 0x%2.2x", code);
-+
-+ if (!skb)
-+ return -ENOMEM;
-+ return hci_send_acl(conn->hcon, skb, 0);
-+}
-+
-+static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
-+{
-+ l2cap_conf_opt *opt = *ptr;
-+ int len;
-+
-+ len = L2CAP_CONF_OPT_SIZE + opt->len;
-+ *ptr += len;
-+
-+ *type = opt->type;
-+ *olen = opt->len;
-+
-+ switch (opt->len) {
-+ case 1:
-+ *val = *((__u8 *) opt->val);
-+ break;
-+
-+ case 2:
-+ *val = __le16_to_cpu(*((__u16 *)opt->val));
-+ break;
-+
-+ case 4:
-+ *val = __le32_to_cpu(*((__u32 *)opt->val));
-+ break;
-+
-+ default:
-+ *val = (unsigned long) opt->val;
-+ break;
-+ };
-+
-+ BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
-+ return len;
-+}
-+
-+static inline void l2cap_parse_conf_req(struct sock *sk, void *data, int len)
-+{
-+ int type, hint, olen;
-+ unsigned long val;
-+ void *ptr = data;
-+
-+ BT_DBG("sk %p len %d", sk, len);
-+
-+ while (len >= L2CAP_CONF_OPT_SIZE) {
-+ len -= l2cap_get_conf_opt(&ptr, &type, &olen, &val);
-+
-+ hint = type & 0x80;
-+ type &= 0x7f;
-+
-+ switch (type) {
-+ case L2CAP_CONF_MTU:
-+ l2cap_pi(sk)->conf_mtu = val;
-+ break;
-+
-+ case L2CAP_CONF_FLUSH_TO:
-+ l2cap_pi(sk)->flush_to = val;
-+ break;
-+
-+ case L2CAP_CONF_QOS:
-+ break;
-+
-+ default:
-+ if (hint)
-+ break;
-+
-+ /* FIXME: Reject unknown option */
-+ break;
-+ };
-+ }
-+}
-+
-+static void l2cap_add_conf_opt(void **ptr, __u8 type, __u8 len, unsigned long val)
-+{
-+ register l2cap_conf_opt *opt = *ptr;
-+
-+ BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
-+
-+ opt->type = type;
-+ opt->len = len;
-+
-+ switch (len) {
-+ case 1:
-+ *((__u8 *) opt->val) = val;
-+ break;
-+
-+ case 2:
-+ *((__u16 *) opt->val) = __cpu_to_le16(val);
-+ break;
-+
-+ case 4:
-+ *((__u32 *) opt->val) = __cpu_to_le32(val);
-+ break;
-+
-+ default:
-+ memcpy(opt->val, (void *) val, len);
-+ break;
-+ };
-+
-+ *ptr += L2CAP_CONF_OPT_SIZE + len;
-+}
-+
-+static int l2cap_build_conf_req(struct sock *sk, void *data)
-+{
-+ struct l2cap_pinfo *pi = l2cap_pi(sk);
-+ l2cap_conf_req *req = (l2cap_conf_req *) data;
-+ void *ptr = req->data;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (pi->imtu != L2CAP_DEFAULT_MTU)
-+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
-+
-+ /* FIXME. Need actual value of the flush timeout */
-+ //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
-+ // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
-+
-+ req->dcid = __cpu_to_le16(pi->dcid);
-+ req->flags = __cpu_to_le16(0);
-+
-+ return ptr - data;
-+}
-+
-+static inline int l2cap_conf_output(struct sock *sk, void **ptr)
-+{
-+ struct l2cap_pinfo *pi = l2cap_pi(sk);
-+ int result = 0;
-+
-+ /* Configure output options and let the other side know
-+ * which ones we don't like.
-+ */
-+ if (pi->conf_mtu < pi->omtu) {
-+ l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu);
-+ result = L2CAP_CONF_UNACCEPT;
-+ } else {
-+ pi->omtu = pi->conf_mtu;
-+ }
-+
-+ BT_DBG("sk %p result %d", sk, result);
-+ return result;
-+}
-+
-+static int l2cap_build_conf_rsp(struct sock *sk, void *data, int *result)
-+{
-+ l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data;
-+ void *ptr = rsp->data;
-+ u16 flags = 0;
-+
-+ BT_DBG("sk %p complete %d", sk, result ? 1 : 0);
-+
-+ if (result)
-+ *result = l2cap_conf_output(sk, &ptr);
-+ else
-+ flags |= 0x0001;
-+
-+ rsp->scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ rsp->result = __cpu_to_le16(result ? *result : 0);
-+ rsp->flags = __cpu_to_le16(flags);
-+
-+ return ptr - data;
-+}
-+
-+static inline int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ struct l2cap_chan_list *list = &conn->chan_list;
-+ l2cap_conn_req *req = (l2cap_conn_req *) data;
-+ l2cap_conn_rsp rsp;
-+ struct sock *sk, *parent;
-+ int result = 0, status = 0;
-+
-+ __u16 dcid = 0, scid = __le16_to_cpu(req->scid);
-+ __u16 psm = req->psm;
-+
-+ BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
-+
-+ /* Check if we have socket listening on psm */
-+ parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
-+ if (!parent) {
-+ result = L2CAP_CR_BAD_PSM;
-+ goto sendresp;
-+ }
-+
-+ result = L2CAP_CR_NO_MEM;
-+
-+ /* Check for backlog size */
-+ if (parent->ack_backlog > parent->max_ack_backlog) {
-+ BT_DBG("backlog full %d", parent->ack_backlog);
-+ goto response;
-+ }
-+
-+ sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC);
-+ if (!sk)
-+ goto response;
-+
-+ write_lock(&list->lock);
-+
-+ /* Check if we already have channel with that dcid */
-+ if (__l2cap_get_chan_by_dcid(list, scid)) {
-+ write_unlock(&list->lock);
-+ sk->zapped = 1;
-+ l2cap_sock_kill(sk);
-+ goto response;
-+ }
-+
-+ hci_conn_hold(conn->hcon);
-+
-+ l2cap_sock_init(sk, parent);
-+ bacpy(&bluez_pi(sk)->src, conn->src);
-+ bacpy(&bluez_pi(sk)->dst, conn->dst);
-+ l2cap_pi(sk)->psm = psm;
-+ l2cap_pi(sk)->dcid = scid;
-+
-+ __l2cap_chan_add(conn, sk, parent);
-+ dcid = l2cap_pi(sk)->scid;
-+
-+ l2cap_sock_set_timer(sk, sk->sndtimeo);
-+
-+ /* Service level security */
-+ result = L2CAP_CR_PEND;
-+ status = L2CAP_CS_AUTHEN_PEND;
-+ sk->state = BT_CONNECT2;
-+ l2cap_pi(sk)->ident = cmd->ident;
-+
-+ if (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) {
-+ if (!hci_conn_encrypt(conn->hcon))
-+ goto done;
-+ } else if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH) {
-+ if (!hci_conn_auth(conn->hcon))
-+ goto done;
-+ }
-+
-+ sk->state = BT_CONFIG;
-+ result = status = 0;
-+
-+done:
-+ write_unlock(&list->lock);
-+
-+response:
-+ bh_unlock_sock(parent);
-+
-+sendresp:
-+ rsp.scid = __cpu_to_le16(scid);
-+ rsp.dcid = __cpu_to_le16(dcid);
-+ rsp.result = __cpu_to_le16(result);
-+ rsp.status = __cpu_to_le16(status);
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
-+ return 0;
-+}
-+
-+static inline int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_conn_rsp *rsp = (l2cap_conn_rsp *) data;
-+ __u16 scid, dcid, result, status;
-+ struct sock *sk;
-+ char req[128];
-+
-+ scid = __le16_to_cpu(rsp->scid);
-+ dcid = __le16_to_cpu(rsp->dcid);
-+ result = __le16_to_cpu(rsp->result);
-+ status = __le16_to_cpu(rsp->status);
-+
-+ BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-+ return -ENOENT;
-+
-+ switch (result) {
-+ case L2CAP_CR_SUCCESS:
-+ sk->state = BT_CONFIG;
-+ l2cap_pi(sk)->dcid = dcid;
-+ l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
-+
-+ l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-+ break;
-+
-+ case L2CAP_CR_PEND:
-+ break;
-+
-+ default:
-+ l2cap_chan_del(sk, ECONNREFUSED);
-+ break;
-+ }
-+
-+ bh_unlock_sock(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_conf_req * req = (l2cap_conf_req *) data;
-+ __u16 dcid, flags;
-+ __u8 rsp[64];
-+ struct sock *sk;
-+ int result;
-+
-+ dcid = __le16_to_cpu(req->dcid);
-+ flags = __le16_to_cpu(req->flags);
-+
-+ BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-+ return -ENOENT;
-+
-+ l2cap_parse_conf_req(sk, req->data, cmd->len - L2CAP_CONF_REQ_SIZE);
-+
-+ if (flags & 0x0001) {
-+ /* Incomplete config. Send empty response. */
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
-+ goto unlock;
-+ }
-+
-+ /* Complete config. */
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &result), rsp);
-+
-+ if (result)
-+ goto unlock;
-+
-+ /* Output config done */
-+ l2cap_pi(sk)->conf_state |= L2CAP_CONF_OUTPUT_DONE;
-+
-+ if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
-+ sk->state = BT_CONNECTED;
-+ l2cap_chan_ready(sk);
-+ } else if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
-+ char req[64];
-+ l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-+ }
-+
-+unlock:
-+ bh_unlock_sock(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_conf_rsp *rsp = (l2cap_conf_rsp *)data;
-+ __u16 scid, flags, result;
-+ struct sock *sk;
-+ int err = 0;
-+
-+ scid = __le16_to_cpu(rsp->scid);
-+ flags = __le16_to_cpu(rsp->flags);
-+ result = __le16_to_cpu(rsp->result);
-+
-+ BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-+ return -ENOENT;
-+
-+ switch (result) {
-+ case L2CAP_CONF_SUCCESS:
-+ break;
-+
-+ case L2CAP_CONF_UNACCEPT:
-+ if (++l2cap_pi(sk)->conf_retry < L2CAP_CONF_MAX_RETRIES) {
-+ char req[128];
-+ /*
-+ It does not make sense to adjust L2CAP parameters
-+ that are currently defined in the spec. We simply
-+ resend config request that we sent earlier. It is
-+ stupid :) but it helps qualification testing
-+ which expects at least some response from us.
-+ */
-+ l2cap_send_req(conn, L2CAP_CONF_REQ,
-+ l2cap_build_conf_req(sk, req), req);
-+ goto done;
-+ }
-+ default:
-+ sk->state = BT_DISCONN;
-+ sk->err = ECONNRESET;
-+ l2cap_sock_set_timer(sk, HZ * 5);
-+ {
-+ l2cap_disconn_req req;
-+ req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
-+ }
-+ goto done;
-+ }
-+
-+ if (flags & 0x01)
-+ goto done;
-+
-+ /* Input config done */
-+ l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
-+
-+ if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
-+ sk->state = BT_CONNECTED;
-+ l2cap_chan_ready(sk);
-+ }
-+
-+done:
-+ bh_unlock_sock(sk);
-+ return err;
-+}
-+
-+static inline int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_disconn_req *req = (l2cap_disconn_req *) data;
-+ l2cap_disconn_rsp rsp;
-+ __u16 dcid, scid;
-+ struct sock *sk;
-+
-+ scid = __le16_to_cpu(req->scid);
-+ dcid = __le16_to_cpu(req->dcid);
-+
-+ BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-+ return 0;
-+
-+ rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_DISCONN_RSP, L2CAP_DISCONN_RSP_SIZE, &rsp);
-+
-+ sk->shutdown = SHUTDOWN_MASK;
-+
-+ l2cap_chan_del(sk, ECONNRESET);
-+ bh_unlock_sock(sk);
-+
-+ l2cap_sock_kill(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_disconn_rsp *rsp = (l2cap_disconn_rsp *) data;
-+ __u16 dcid, scid;
-+ struct sock *sk;
-+
-+ scid = __le16_to_cpu(rsp->scid);
-+ dcid = __le16_to_cpu(rsp->dcid);
-+
-+ BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-+ return 0;
-+ l2cap_chan_del(sk, 0);
-+ bh_unlock_sock(sk);
-+
-+ l2cap_sock_kill(sk);
-+ return 0;
-+}
-+
-+static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
-+{
-+ __u8 *data = skb->data;
-+ int len = skb->len;
-+ l2cap_cmd_hdr cmd;
-+ int err = 0;
-+
-+ while (len >= L2CAP_CMD_HDR_SIZE) {
-+ memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
-+ data += L2CAP_CMD_HDR_SIZE;
-+ len -= L2CAP_CMD_HDR_SIZE;
-+
-+ cmd.len = __le16_to_cpu(cmd.len);
-+
-+ BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
-+
-+ if (cmd.len > len || !cmd.ident) {
-+ BT_DBG("corrupted command");
-+ break;
-+ }
-+
-+ switch (cmd.code) {
-+ case L2CAP_CONN_REQ:
-+ err = l2cap_connect_req(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_CONN_RSP:
-+ err = l2cap_connect_rsp(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_CONF_REQ:
-+ err = l2cap_config_req(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_CONF_RSP:
-+ err = l2cap_config_rsp(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_DISCONN_REQ:
-+ err = l2cap_disconnect_req(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_DISCONN_RSP:
-+ err = l2cap_disconnect_rsp(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_COMMAND_REJ:
-+ /* FIXME: We should process this */
-+ l2cap_raw_recv(conn, skb);
-+ break;
-+
-+ case L2CAP_ECHO_REQ:
-+ l2cap_send_rsp(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data);
-+ break;
-+
-+ case L2CAP_ECHO_RSP:
-+ case L2CAP_INFO_REQ:
-+ case L2CAP_INFO_RSP:
-+ l2cap_raw_recv(conn, skb);
-+ break;
-+
-+ default:
-+ BT_ERR("Uknown signaling command 0x%2.2x", cmd.code);
-+ err = -EINVAL;
-+ break;
-+ };
-+
-+ if (err) {
-+ l2cap_cmd_rej rej;
-+ BT_DBG("error %d", err);
-+
-+ /* FIXME: Map err to a valid reason. */
-+ rej.reason = __cpu_to_le16(0);
-+ l2cap_send_rsp(conn, cmd.ident, L2CAP_COMMAND_REJ, L2CAP_CMD_REJ_SIZE, &rej);
-+ }
-+
-+ data += cmd.len;
-+ len -= cmd.len;
-+ }
-+
-+ kfree_skb(skb);
-+}
-+
-+static inline int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
-+{
-+ struct sock *sk;
-+
-+ sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
-+ if (!sk) {
-+ BT_DBG("unknown cid 0x%4.4x", cid);
-+ goto drop;
-+ }
-+
-+ BT_DBG("sk %p, len %d", sk, skb->len);
-+
-+ if (sk->state != BT_CONNECTED)
-+ goto drop;
-+
-+ if (l2cap_pi(sk)->imtu < skb->len)
-+ goto drop;
-+
-+ /* If socket recv buffers overflows we drop data here
-+ * which is *bad* because L2CAP has to be reliable.
-+ * But we don't have any other choice. L2CAP doesn't
-+ * provide flow control mechanism */
-+
-+ if (!sock_queue_rcv_skb(sk, skb))
-+ goto done;
-+
-+drop:
-+ kfree_skb(skb);
-+
-+done:
-+ if (sk) bh_unlock_sock(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_conless_channel(struct l2cap_conn *conn, __u16 psm, struct sk_buff *skb)
-+{
-+ struct sock *sk;
-+
-+ sk = l2cap_get_sock_by_psm(0, psm, conn->src);
-+ if (!sk)
-+ goto drop;
-+
-+ BT_DBG("sk %p, len %d", sk, skb->len);
-+
-+ if (sk->state != BT_BOUND && sk->state != BT_CONNECTED)
-+ goto drop;
-+
-+ if (l2cap_pi(sk)->imtu < skb->len)
-+ goto drop;
-+
-+ if (!sock_queue_rcv_skb(sk, skb))
-+ goto done;
-+
-+drop:
-+ kfree_skb(skb);
-+
-+done:
-+ if (sk) bh_unlock_sock(sk);
-+ return 0;
-+}
-+
-+static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
-+{
-+ l2cap_hdr *lh = (l2cap_hdr *) skb->data;
-+ __u16 cid, psm, len;
-+
-+ skb_pull(skb, L2CAP_HDR_SIZE);
-+ cid = __le16_to_cpu(lh->cid);
-+ len = __le16_to_cpu(lh->len);
-+
-+ BT_DBG("len %d, cid 0x%4.4x", len, cid);
-+
-+ switch (cid) {
-+ case 0x0001:
-+ l2cap_sig_channel(conn, skb);
-+ break;
-+
-+ case 0x0002:
-+ psm = get_unaligned((__u16 *) skb->data);
-+ skb_pull(skb, 2);
-+ l2cap_conless_channel(conn, psm, skb);
-+ break;
-+
-+ default:
-+ l2cap_data_channel(conn, cid, skb);
-+ break;
-+ }
-+}
-+
-+/* ------------ L2CAP interface with lower layer (HCI) ------------- */
-+
-+static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
-+{
-+ int exact = 0, lm1 = 0, lm2 = 0;
-+ register struct sock *sk;
-+
-+ if (type != ACL_LINK)
-+ return 0;
-+
-+ BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
-+
-+ /* Find listening sockets and check their link_mode */
-+ read_lock(&l2cap_sk_list.lock);
-+ for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-+ if (sk->state != BT_LISTEN)
-+ continue;
-+
-+ if (!bacmp(&bluez_pi(sk)->src, &hdev->bdaddr)) {
-+ lm1 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode);
-+ exact++;
-+ } else if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
-+ lm2 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode);
-+ }
-+ read_unlock(&l2cap_sk_list.lock);
-+
-+ return exact ? lm1 : lm2;
-+}
-+
-+static int l2cap_connect_cfm(struct hci_conn *hcon, __u8 status)
-+{
-+ BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
-+
-+ if (hcon->type != ACL_LINK)
-+ return 0;
-+
-+ if (!status) {
-+ struct l2cap_conn *conn;
-+
-+ conn = l2cap_conn_add(hcon, status);
-+ if (conn)
-+ l2cap_conn_ready(conn);
-+ } else
-+ l2cap_conn_del(hcon, bterr(status));
-+
-+ return 0;
-+}
-+
-+static int l2cap_disconn_ind(struct hci_conn *hcon, __u8 reason)
-+{
-+ BT_DBG("hcon %p reason %d", hcon, reason);
-+
-+ if (hcon->type != ACL_LINK)
-+ return 0;
-+
-+ l2cap_conn_del(hcon, bterr(reason));
-+ return 0;
-+}
-+
-+static int l2cap_auth_cfm(struct hci_conn *hcon, __u8 status)
-+{
-+ struct l2cap_chan_list *l;
-+ struct l2cap_conn *conn;
-+ l2cap_conn_rsp rsp;
-+ struct sock *sk;
-+ int result;
-+
-+ if (!(conn = hcon->l2cap_data))
-+ return 0;
-+ l = &conn->chan_list;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ bh_lock_sock(sk);
-+
-+ if (sk->state != BT_CONNECT2 ||
-+ (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT)) {
-+ bh_unlock_sock(sk);
-+ continue;
-+ }
-+
-+ if (!status) {
-+ sk->state = BT_CONFIG;
-+ result = 0;
-+ } else {
-+ sk->state = BT_DISCONN;
-+ l2cap_sock_set_timer(sk, HZ/10);
-+ result = L2CAP_CR_SEC_BLOCK;
-+ }
-+
-+ rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ rsp.result = __cpu_to_le16(result);
-+ rsp.status = __cpu_to_le16(0);
-+ l2cap_send_rsp(conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP,
-+ L2CAP_CONN_RSP_SIZE, &rsp);
-+
-+ bh_unlock_sock(sk);
-+ }
-+
-+ read_unlock(&l->lock);
-+ return 0;
-+}
-+
-+static int l2cap_encrypt_cfm(struct hci_conn *hcon, __u8 status)
-+{
-+ struct l2cap_chan_list *l;
-+ struct l2cap_conn *conn;
-+ l2cap_conn_rsp rsp;
-+ struct sock *sk;
-+ int result;
-+
-+ if (!(conn = hcon->l2cap_data))
-+ return 0;
-+ l = &conn->chan_list;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ bh_lock_sock(sk);
-+
-+ if (sk->state != BT_CONNECT2) {
-+ bh_unlock_sock(sk);
-+ continue;
-+ }
-+
-+ if (!status) {
-+ sk->state = BT_CONFIG;
-+ result = 0;
-+ } else {
-+ sk->state = BT_DISCONN;
-+ l2cap_sock_set_timer(sk, HZ/10);
-+ result = L2CAP_CR_SEC_BLOCK;
-+ }
-+
-+ rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ rsp.result = __cpu_to_le16(result);
-+ rsp.status = __cpu_to_le16(0);
-+ l2cap_send_rsp(conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP,
-+ L2CAP_CONN_RSP_SIZE, &rsp);
-+
-+ bh_unlock_sock(sk);
-+ }
-+
-+ read_unlock(&l->lock);
-+ return 0;
-+}
-+
-+static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, __u16 flags)
-+{
-+ struct l2cap_conn *conn = hcon->l2cap_data;
-+
-+ if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
-+ goto drop;
-+
-+ BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
-+
-+ if (flags & ACL_START) {
-+ l2cap_hdr *hdr;
-+ int len;
-+
-+ if (conn->rx_len) {
-+ BT_ERR("Unexpected start frame (len %d)", skb->len);
-+ kfree_skb(conn->rx_skb);
-+ conn->rx_skb = NULL;
-+ conn->rx_len = 0;
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ }
-+
-+ if (skb->len < 2) {
-+ BT_ERR("Frame is too short (len %d)", skb->len);
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ goto drop;
-+ }
-+
-+ hdr = (l2cap_hdr *) skb->data;
-+ len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
-+
-+ if (len == skb->len) {
-+ /* Complete frame received */
-+ l2cap_recv_frame(conn, skb);
-+ return 0;
-+ }
-+
-+ BT_DBG("Start: total len %d, frag len %d", len, skb->len);
-+
-+ if (skb->len > len) {
-+ BT_ERR("Frame is too long (len %d, expected len %d)",
-+ skb->len, len);
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ goto drop;
-+ }
-+
-+ /* Allocate skb for the complete frame including header */
-+ conn->rx_skb = bluez_skb_alloc(len, GFP_ATOMIC);
-+ if (!conn->rx_skb)
-+ goto drop;
-+
-+ memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
-+ conn->rx_len = len - skb->len;
-+ } else {
-+ BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
-+
-+ if (!conn->rx_len) {
-+ BT_ERR("Unexpected continuation frame (len %d)", skb->len);
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ goto drop;
-+ }
-+
-+ if (skb->len > conn->rx_len) {
-+ BT_ERR("Fragment is too long (len %d, expected %d)",
-+ skb->len, conn->rx_len);
-+ kfree_skb(conn->rx_skb);
-+ conn->rx_skb = NULL;
-+ conn->rx_len = 0;
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ goto drop;
-+ }
-+
-+ memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
-+ conn->rx_len -= skb->len;
-+
-+ if (!conn->rx_len) {
-+ /* Complete frame received */
-+ l2cap_recv_frame(conn, conn->rx_skb);
-+ conn->rx_skb = NULL;
-+ }
-+ }
-+
-+drop:
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+/* ----- Proc fs support ------ */
-+static int l2cap_sock_dump(char *buf, struct bluez_sock_list *list)
-+{
-+ struct l2cap_pinfo *pi;
-+ struct sock *sk;
-+ char *ptr = buf;
-+
-+ read_lock_bh(&list->lock);
-+
-+ for (sk = list->head; sk; sk = sk->next) {
-+ pi = l2cap_pi(sk);
-+ ptr += sprintf(ptr, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n",
-+ batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
-+ sk->state, pi->psm, pi->scid, pi->dcid, pi->imtu, pi->omtu,
-+ pi->link_mode);
-+ }
-+
-+ read_unlock_bh(&list->lock);
-+
-+ ptr += sprintf(ptr, "\n");
-+ return ptr - buf;
-+}
-+
-+static int l2cap_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
-+{
-+ char *ptr = buf;
-+ int len;
-+
-+ BT_DBG("count %d, offset %ld", count, offset);
-+
-+ ptr += l2cap_sock_dump(ptr, &l2cap_sk_list);
-+ len = ptr - buf;
-+
-+ if (len <= count + offset)
-+ *eof = 1;
-+
-+ *start = buf + offset;
-+ len -= offset;
-+
-+ if (len > count)
-+ len = count;
-+ if (len < 0)
-+ len = 0;
-+
-+ return len;
-+}
-+
-+static struct proto_ops l2cap_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: l2cap_sock_release,
-+ bind: l2cap_sock_bind,
-+ connect: l2cap_sock_connect,
-+ listen: l2cap_sock_listen,
-+ accept: l2cap_sock_accept,
-+ getname: l2cap_sock_getname,
-+ sendmsg: l2cap_sock_sendmsg,
-+ recvmsg: bluez_sock_recvmsg,
-+ poll: bluez_sock_poll,
-+ socketpair: sock_no_socketpair,
-+ ioctl: sock_no_ioctl,
-+ shutdown: l2cap_sock_shutdown,
-+ setsockopt: l2cap_sock_setsockopt,
-+ getsockopt: l2cap_sock_getsockopt,
-+ mmap: sock_no_mmap
-+};
-+
-+static struct net_proto_family l2cap_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: l2cap_sock_create
-+};
-+
-+static struct hci_proto l2cap_hci_proto = {
-+ name: "L2CAP",
-+ id: HCI_PROTO_L2CAP,
-+ connect_ind: l2cap_connect_ind,
-+ connect_cfm: l2cap_connect_cfm,
-+ disconn_ind: l2cap_disconn_ind,
-+ recv_acldata: l2cap_recv_acldata,
-+ auth_cfm: l2cap_auth_cfm,
-+ encrypt_cfm: l2cap_encrypt_cfm
-+};
-+
-+int __init l2cap_init(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops))) {
-+ BT_ERR("Can't register L2CAP socket");
-+ return err;
-+ }
-+
-+ if ((err = hci_register_proto(&l2cap_hci_proto))) {
-+ BT_ERR("Can't register L2CAP protocol");
-+ return err;
-+ }
-+
-+ create_proc_read_entry("bluetooth/l2cap", 0, 0, l2cap_read_proc, NULL);
-+
-+ BT_INFO("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ return 0;
-+}
-+
-+void l2cap_cleanup(void)
-+{
-+ remove_proc_entry("bluetooth/l2cap", NULL);
-+
-+ /* Unregister socket and protocol */
-+ if (bluez_sock_unregister(BTPROTO_L2CAP))
-+ BT_ERR("Can't unregister L2CAP socket");
-+
-+ if (hci_unregister_proto(&l2cap_hci_proto))
-+ BT_ERR("Can't unregister L2CAP protocol");
-+}
-+
-+void l2cap_load(void)
-+{
-+ /* Dummy function to trigger automatic L2CAP module loading by
-+ other modules that use L2CAP sockets but do not use any other
-+ symbols from it. */
-+ return;
-+}
-+
-+EXPORT_SYMBOL(l2cap_load);
-+
-+module_init(l2cap_init);
-+module_exit(l2cap_cleanup);
-+
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
-+MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
-+MODULE_LICENSE("GPL");
---- linux/net/bluetooth/l2cap_core.c~bluetooth-2.4.18-mh11
-+++ linux/net/bluetooth/l2cap_core.c
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * BlueZ L2CAP core and sockets.
-- *
-- * $Id$
-- */
--#define VERSION "1.1"
--
--#include <linux/config.h>
--#include <linux/module.h>
--
--#include <linux/types.h>
--#include <linux/errno.h>
--#include <linux/kernel.h>
--#include <linux/major.h>
--#include <linux/sched.h>
--#include <linux/slab.h>
--#include <linux/poll.h>
--#include <linux/fcntl.h>
--#include <linux/init.h>
--#include <linux/skbuff.h>
--#include <linux/interrupt.h>
--#include <linux/socket.h>
--#include <linux/skbuff.h>
--#include <linux/proc_fs.h>
--#include <linux/list.h>
--#include <net/sock.h>
--
--#include <asm/system.h>
--#include <asm/uaccess.h>
--
--#include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
--#include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/l2cap.h>
--#include <net/bluetooth/l2cap_core.h>
--
--#ifndef L2CAP_DEBUG
--#undef DBG
--#define DBG( A... )
--#endif
--
--struct proto_ops l2cap_sock_ops;
--
--struct bluez_sock_list l2cap_sk_list = {
-- lock: RW_LOCK_UNLOCKED
--};
--
--struct list_head l2cap_iff_list = LIST_HEAD_INIT(l2cap_iff_list);
--rwlock_t l2cap_rt_lock = RW_LOCK_UNLOCKED;
--
--static int l2cap_conn_del(struct l2cap_conn *conn, int err);
--
--static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
--static void l2cap_chan_del(struct sock *sk, int err);
--static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len);
--
--static void l2cap_sock_close(struct sock *sk);
--static void l2cap_sock_kill(struct sock *sk);
--
--static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data);
--static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data);
--
--/* -------- L2CAP interfaces & routing --------- */
--/* Add/delete L2CAP interface.
-- * Must be called with locked rt_lock
-- */
--
--static void l2cap_iff_add(struct hci_dev *hdev)
--{
-- struct l2cap_iff *iff;
--
-- DBG("%s", hdev->name);
--
-- DBG("iff_list %p next %p prev %p", &l2cap_iff_list, l2cap_iff_list.next, l2cap_iff_list.prev);
--
-- /* Allocate new interface and lock HCI device */
-- if (!(iff = kmalloc(sizeof(struct l2cap_iff), GFP_KERNEL))) {
-- ERR("Can't allocate new interface %s", hdev->name);
-- return;
-- }
-- memset(iff, 0, sizeof(struct l2cap_iff));
--
-- hci_dev_hold(hdev);
-- hdev->l2cap_data = iff;
-- iff->hdev = hdev;
-- iff->mtu = hdev->acl_mtu - HCI_ACL_HDR_SIZE;
-- iff->bdaddr = &hdev->bdaddr;
--
-- spin_lock_init(&iff->lock);
-- INIT_LIST_HEAD(&iff->conn_list);
--
-- list_add(&iff->list, &l2cap_iff_list);
--}
--
--static void l2cap_iff_del(struct hci_dev *hdev)
--{
-- struct l2cap_iff *iff;
--
-- if (!(iff = hdev->l2cap_data))
-- return;
--
-- DBG("%s iff %p", hdev->name, iff);
--
-- list_del(&iff->list);
--
-- l2cap_iff_lock(iff);
--
-- /* Drop connections */
-- while (!list_empty(&iff->conn_list)) {
-- struct l2cap_conn *c;
--
-- c = list_entry(iff->conn_list.next, struct l2cap_conn, list);
-- l2cap_conn_del(c, ENODEV);
-- }
--
-- l2cap_iff_unlock(iff);
--
-- /* Unlock HCI device */
-- hdev->l2cap_data = NULL;
-- hci_dev_put(hdev);
--
-- kfree(iff);
--}
--
--/* Get route. Returns L2CAP interface.
-- * Must be called with locked rt_lock
-- */
--static struct l2cap_iff *l2cap_get_route(bdaddr_t *src, bdaddr_t *dst)
--{
-- struct list_head *p;
-- int use_src;
--
-- DBG("%s -> %s", batostr(src), batostr(dst));
--
-- use_src = bacmp(src, BDADDR_ANY) ? 0 : 1;
--
-- /* Simple routing:
-- * No source address - find interface with bdaddr != dst
-- * Source address - find interface with bdaddr == src
-- */
--
-- list_for_each(p, &l2cap_iff_list) {
-- struct l2cap_iff *iff;
--
-- iff = list_entry(p, struct l2cap_iff, list);
--
-- if (use_src && !bacmp(iff->bdaddr, src))
-- return iff;
-- else if (bacmp(iff->bdaddr, dst))
-- return iff;
-- }
-- return NULL;
--}
--
--/* ----- L2CAP timers ------ */
--static void l2cap_sock_timeout(unsigned long arg)
--{
-- struct sock *sk = (struct sock *) arg;
--
-- DBG("sock %p state %d", sk, sk->state);
--
-- bh_lock_sock(sk);
-- switch (sk->state) {
-- case BT_DISCONN:
-- l2cap_chan_del(sk, ETIMEDOUT);
-- break;
--
-- default:
-- sk->err = ETIMEDOUT;
-- sk->state_change(sk);
-- break;
-- };
-- bh_unlock_sock(sk);
--
-- l2cap_sock_kill(sk);
-- sock_put(sk);
--}
--
--static void l2cap_sock_set_timer(struct sock *sk, long timeout)
--{
-- DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
--
-- if (!mod_timer(&sk->timer, jiffies + timeout))
-- sock_hold(sk);
--}
--
--static void l2cap_sock_clear_timer(struct sock *sk)
--{
-- DBG("sock %p state %d", sk, sk->state);
--
-- if (timer_pending(&sk->timer) && del_timer(&sk->timer))
-- __sock_put(sk);
--}
--
--static void l2cap_sock_init_timer(struct sock *sk)
--{
-- init_timer(&sk->timer);
-- sk->timer.function = l2cap_sock_timeout;
-- sk->timer.data = (unsigned long)sk;
--}
--
--static void l2cap_conn_timeout(unsigned long arg)
--{
-- struct l2cap_conn *conn = (void *)arg;
--
-- DBG("conn %p state %d", conn, conn->state);
--
-- if (conn->state == BT_CONNECTED) {
-- hci_disconnect(conn->hconn, 0x13);
-- }
--
-- return;
--}
--
--static void l2cap_conn_set_timer(struct l2cap_conn *conn, long timeout)
--{
-- DBG("conn %p state %d timeout %ld", conn, conn->state, timeout);
--
-- mod_timer(&conn->timer, jiffies + timeout);
--}
--
--static void l2cap_conn_clear_timer(struct l2cap_conn *conn)
--{
-- DBG("conn %p state %d", conn, conn->state);
--
-- del_timer(&conn->timer);
--}
--
--static void l2cap_conn_init_timer(struct l2cap_conn *conn)
--{
-- init_timer(&conn->timer);
-- conn->timer.function = l2cap_conn_timeout;
-- conn->timer.data = (unsigned long)conn;
--}
--
--/* -------- L2CAP connections --------- */
--/* Add new connection to the interface.
-- * Interface must be locked
-- */
--static struct l2cap_conn *l2cap_conn_add(struct l2cap_iff *iff, bdaddr_t *dst)
--{
-- struct l2cap_conn *conn;
-- bdaddr_t *src = iff->bdaddr;
--
-- if (!(conn = kmalloc(sizeof(struct l2cap_conn), GFP_KERNEL)))
-- return NULL;
--
-- memset(conn, 0, sizeof(struct l2cap_conn));
--
-- conn->state = BT_OPEN;
-- conn->iff = iff;
-- bacpy(&conn->src, src);
-- bacpy(&conn->dst, dst);
--
-- spin_lock_init(&conn->lock);
-- conn->chan_list.lock = RW_LOCK_UNLOCKED;
--
-- l2cap_conn_init_timer(conn);
--
-- __l2cap_conn_link(iff, conn);
--
-- DBG("%s -> %s, %p", batostr(src), batostr(dst), conn);
--
-- MOD_INC_USE_COUNT;
--
-- return conn;
--}
--
--/* Delete connection on the interface.
-- * Interface must be locked
-- */
--static int l2cap_conn_del(struct l2cap_conn *conn, int err)
--{
-- struct sock *sk;
--
-- DBG("conn %p, state %d, err %d", conn, conn->state, err);
--
-- l2cap_conn_clear_timer(conn);
-- __l2cap_conn_unlink(conn->iff, conn);
--
-- conn->state = BT_CLOSED;
--
-- if (conn->rx_skb)
-- kfree_skb(conn->rx_skb);
--
-- /* Kill channels */
-- while ((sk = conn->chan_list.head)) {
-- bh_lock_sock(sk);
-- l2cap_sock_clear_timer(sk);
-- l2cap_chan_del(sk, err);
-- bh_unlock_sock(sk);
--
-- l2cap_sock_kill(sk);
-- }
--
-- kfree(conn);
--
-- MOD_DEC_USE_COUNT;
-- return 0;
--}
--
--static inline struct l2cap_conn *l2cap_get_conn_by_addr(struct l2cap_iff *iff, bdaddr_t *dst)
--{
-- struct list_head *p;
--
-- list_for_each(p, &iff->conn_list) {
-- struct l2cap_conn *c;
--
-- c = list_entry(p, struct l2cap_conn, list);
-- if (!bacmp(&c->dst, dst))
-- return c;
-- }
-- return NULL;
--}
--
--int l2cap_connect(struct sock *sk)
--{
-- bdaddr_t *src = &l2cap_pi(sk)->src;
-- bdaddr_t *dst = &l2cap_pi(sk)->dst;
-- struct l2cap_conn *conn;
-- struct l2cap_iff *iff;
-- int err = 0;
--
-- DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
--
-- read_lock_bh(&l2cap_rt_lock);
--
-- /* Get route to remote BD address */
-- if (!(iff = l2cap_get_route(src, dst))) {
-- err = -EHOSTUNREACH;
-- goto done;
-- }
--
-- /* Update source addr of the socket */
-- bacpy(src, iff->bdaddr);
--
-- l2cap_iff_lock(iff);
--
-- if (!(conn = l2cap_get_conn_by_addr(iff, dst))) {
-- /* Connection doesn't exist */
-- if (!(conn = l2cap_conn_add(iff, dst))) {
-- l2cap_iff_unlock(iff);
-- err = -ENOMEM;
-- goto done;
-- }
-- conn->out = 1;
-- }
--
-- l2cap_iff_unlock(iff);
--
-- l2cap_chan_add(conn, sk, NULL);
--
-- sk->state = BT_CONNECT;
-- l2cap_sock_set_timer(sk, sk->sndtimeo);
--
-- switch (conn->state) {
-- case BT_CONNECTED:
-- if (sk->type == SOCK_SEQPACKET) {
-- l2cap_conn_req req;
-- req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- req.psm = l2cap_pi(sk)->psm;
-- l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
-- } else {
-- l2cap_sock_clear_timer(sk);
-- sk->state = BT_CONNECTED;
-- }
-- break;
--
-- case BT_CONNECT:
-- break;
--
-- default:
-- /* Create ACL connection */
-- conn->state = BT_CONNECT;
-- hci_connect(iff->hdev, dst);
-- break;
-- };
--
--done:
-- read_unlock_bh(&l2cap_rt_lock);
-- return err;
--}
--
--/* ------ Channel queues for listening sockets ------ */
--void l2cap_accept_queue(struct sock *parent, struct sock *sk)
--{
-- struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
--
-- DBG("parent %p, sk %p", parent, sk);
--
-- sock_hold(sk);
-- l2cap_pi(sk)->parent = parent;
-- l2cap_pi(sk)->next_q = NULL;
--
-- if (!q->head) {
-- q->head = q->tail = sk;
-- } else {
-- struct sock *tail = q->tail;
--
-- l2cap_pi(sk)->prev_q = tail;
-- l2cap_pi(tail)->next_q = sk;
-- q->tail = sk;
-- }
--
-- parent->ack_backlog++;
--}
--
--void l2cap_accept_unlink(struct sock *sk)
--{
-- struct sock *parent = l2cap_pi(sk)->parent;
-- struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
-- struct sock *next, *prev;
--
-- DBG("sk %p", sk);
--
-- next = l2cap_pi(sk)->next_q;
-- prev = l2cap_pi(sk)->prev_q;
--
-- if (sk == q->head)
-- q->head = next;
-- if (sk == q->tail)
-- q->tail = prev;
--
-- if (next)
-- l2cap_pi(next)->prev_q = prev;
-- if (prev)
-- l2cap_pi(prev)->next_q = next;
--
-- l2cap_pi(sk)->parent = NULL;
--
-- parent->ack_backlog--;
-- __sock_put(sk);
--}
--
--/* Get next connected channel in queue. */
--struct sock *l2cap_accept_dequeue(struct sock *parent, int state)
--{
-- struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
-- struct sock *sk;
--
-- for (sk = q->head; sk; sk = l2cap_pi(sk)->next_q) {
-- if (!state || sk->state == state) {
-- l2cap_accept_unlink(sk);
-- break;
-- }
-- }
--
-- DBG("parent %p, sk %p", parent, sk);
--
-- return sk;
--}
--
--/* -------- Socket interface ---------- */
--static struct sock *__l2cap_get_sock_by_addr(struct sockaddr_l2 *addr)
--{
-- bdaddr_t *src = &addr->l2_bdaddr;
-- __u16 psm = addr->l2_psm;
-- struct sock *sk;
--
-- for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-- if (l2cap_pi(sk)->psm == psm &&
-- !bacmp(&l2cap_pi(sk)->src, src))
-- break;
-- }
--
-- return sk;
--}
--
--/* Find socket listening on psm and source bdaddr.
-- * Returns closest match.
-- */
--static struct sock *l2cap_get_sock_listen(bdaddr_t *src, __u16 psm)
--{
-- struct sock *sk, *sk1 = NULL;
--
-- read_lock(&l2cap_sk_list.lock);
--
-- for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-- struct l2cap_pinfo *pi;
--
-- if (sk->state != BT_LISTEN)
-- continue;
--
-- pi = l2cap_pi(sk);
--
-- if (pi->psm == psm) {
-- /* Exact match. */
-- if (!bacmp(&pi->src, src))
-- break;
--
-- /* Closest match */
-- if (!bacmp(&pi->src, BDADDR_ANY))
-- sk1 = sk;
-- }
-- }
--
-- read_unlock(&l2cap_sk_list.lock);
--
-- return sk ? sk : sk1;
--}
--
--static void l2cap_sock_destruct(struct sock *sk)
--{
-- DBG("sk %p", sk);
--
-- skb_queue_purge(&sk->receive_queue);
-- skb_queue_purge(&sk->write_queue);
--
-- MOD_DEC_USE_COUNT;
--}
--
--static void l2cap_sock_cleanup_listen(struct sock *parent)
--{
-- struct sock *sk;
--
-- DBG("parent %p", parent);
--
-- /* Close not yet accepted channels */
-- while ((sk = l2cap_accept_dequeue(parent, 0)))
-- l2cap_sock_close(sk);
--
-- parent->state = BT_CLOSED;
-- parent->zapped = 1;
--}
--
--/* Kill socket (only if zapped and orphan)
-- * Must be called on unlocked socket.
-- */
--static void l2cap_sock_kill(struct sock *sk)
--{
-- if (!sk->zapped || sk->socket)
-- return;
--
-- DBG("sk %p state %d", sk, sk->state);
--
-- /* Kill poor orphan */
-- bluez_sock_unlink(&l2cap_sk_list, sk);
-- sk->dead = 1;
-- sock_put(sk);
--}
--
--/* Close socket.
-- * Must be called on unlocked socket.
-- */
--static void l2cap_sock_close(struct sock *sk)
--{
-- struct l2cap_conn *conn;
--
-- l2cap_sock_clear_timer(sk);
--
-- lock_sock(sk);
--
-- conn = l2cap_pi(sk)->conn;
--
-- DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
--
-- switch (sk->state) {
-- case BT_LISTEN:
-- l2cap_sock_cleanup_listen(sk);
-- break;
--
-- case BT_CONNECTED:
-- case BT_CONFIG:
-- if (sk->type == SOCK_SEQPACKET) {
-- l2cap_disconn_req req;
--
-- sk->state = BT_DISCONN;
--
-- req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
--
-- l2cap_sock_set_timer(sk, sk->sndtimeo);
-- } else {
-- l2cap_chan_del(sk, ECONNRESET);
-- }
-- break;
--
-- case BT_CONNECT:
-- case BT_DISCONN:
-- l2cap_chan_del(sk, ECONNRESET);
-- break;
--
-- default:
-- sk->zapped = 1;
-- break;
-- };
--
-- release_sock(sk);
--
-- l2cap_sock_kill(sk);
--}
--
--static void l2cap_sock_init(struct sock *sk, struct sock *parent)
--{
-- struct l2cap_pinfo *pi = l2cap_pi(sk);
--
-- DBG("sk %p", sk);
--
-- if (parent) {
-- sk->type = parent->type;
--
-- pi->imtu = l2cap_pi(parent)->imtu;
-- pi->omtu = l2cap_pi(parent)->omtu;
-- } else {
-- pi->imtu = L2CAP_DEFAULT_MTU;
-- pi->omtu = 0;
-- }
--
-- /* Default config options */
-- pi->conf_mtu = L2CAP_DEFAULT_MTU;
-- pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
--}
--
--static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
--{
-- struct sock *sk;
--
-- if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
-- return NULL;
--
-- sock_init_data(sock, sk);
--
-- sk->zapped = 0;
--
-- sk->destruct = l2cap_sock_destruct;
-- sk->sndtimeo = L2CAP_CONN_TIMEOUT;
--
-- sk->protocol = proto;
-- sk->state = BT_OPEN;
--
-- l2cap_sock_init_timer(sk);
--
-- bluez_sock_link(&l2cap_sk_list, sk);
--
-- MOD_INC_USE_COUNT;
--
-- return sk;
--}
--
--static int l2cap_sock_create(struct socket *sock, int protocol)
--{
-- struct sock *sk;
--
-- DBG("sock %p", sock);
--
-- sock->state = SS_UNCONNECTED;
--
-- if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_RAW)
-- return -ESOCKTNOSUPPORT;
--
-- sock->ops = &l2cap_sock_ops;
--
-- if (!(sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL)))
-- return -ENOMEM;
--
-- l2cap_sock_init(sk, NULL);
--
-- return 0;
--}
--
--static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
--{
-- struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-- struct sock *sk = sock->sk;
-- int err = 0;
--
-- DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
--
-- if (!addr || addr->sa_family != AF_BLUETOOTH)
-- return -EINVAL;
--
-- lock_sock(sk);
--
-- if (sk->state != BT_OPEN) {
-- err = -EBADFD;
-- goto done;
-- }
--
-- write_lock(&l2cap_sk_list.lock);
--
-- if (la->l2_psm && __l2cap_get_sock_by_addr(la)) {
-- err = -EADDRINUSE;
-- goto unlock;
-- }
--
-- /* Save source address */
-- bacpy(&l2cap_pi(sk)->src, &la->l2_bdaddr);
-- l2cap_pi(sk)->psm = la->l2_psm;
-- sk->state = BT_BOUND;
--
--unlock:
-- write_unlock(&l2cap_sk_list.lock);
--
--done:
-- release_sock(sk);
--
-- return err;
--}
--
--static int l2cap_sock_w4_connect(struct sock *sk, int flags)
--{
-- DECLARE_WAITQUEUE(wait, current);
-- long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
-- int err = 0;
--
-- DBG("sk %p", sk);
--
-- add_wait_queue(sk->sleep, &wait);
-- current->state = TASK_INTERRUPTIBLE;
--
-- while (sk->state != BT_CONNECTED) {
-- if (!timeo) {
-- err = -EAGAIN;
-- break;
-- }
--
-- release_sock(sk);
-- timeo = schedule_timeout(timeo);
-- lock_sock(sk);
--
-- err = 0;
-- if (sk->state == BT_CONNECTED)
-- break;
--
-- if (sk->err) {
-- err = sock_error(sk);
-- break;
-- }
--
-- if (signal_pending(current)) {
-- err = sock_intr_errno(timeo);
-- break;
-- }
-- }
-- current->state = TASK_RUNNING;
-- remove_wait_queue(sk->sleep, &wait);
--
-- return err;
--}
--
--static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
--{
-- struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-- struct sock *sk = sock->sk;
-- int err = 0;
--
-- lock_sock(sk);
--
-- DBG("sk %p", sk);
--
-- if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) {
-- err = -EINVAL;
-- goto done;
-- }
--
-- if (sk->state != BT_OPEN && sk->state != BT_BOUND) {
-- err = -EBADFD;
-- goto done;
-- }
--
-- if (sk->type == SOCK_SEQPACKET && !la->l2_psm) {
-- err = -EINVAL;
-- goto done;
-- }
--
-- /* Set destination address and psm */
-- bacpy(&l2cap_pi(sk)->dst, &la->l2_bdaddr);
-- l2cap_pi(sk)->psm = la->l2_psm;
--
-- if ((err = l2cap_connect(sk)))
-- goto done;
--
-- err = l2cap_sock_w4_connect(sk, flags);
--
--done:
-- release_sock(sk);
-- return err;
--}
--
--int l2cap_sock_listen(struct socket *sock, int backlog)
--{
-- struct sock *sk = sock->sk;
-- int err = 0;
--
-- DBG("sk %p backlog %d", sk, backlog);
--
-- lock_sock(sk);
--
-- if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
-- err = -EBADFD;
-- goto done;
-- }
--
-- if (!l2cap_pi(sk)->psm) {
-- err = -EINVAL;
-- goto done;
-- }
--
-- sk->max_ack_backlog = backlog;
-- sk->ack_backlog = 0;
-- sk->state = BT_LISTEN;
--
--done:
-- release_sock(sk);
-- return err;
--}
--
--int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
--{
-- DECLARE_WAITQUEUE(wait, current);
-- struct sock *sk = sock->sk, *ch;
-- long timeo;
-- int err = 0;
--
-- lock_sock(sk);
--
-- if (sk->state != BT_LISTEN) {
-- err = -EBADFD;
-- goto done;
-- }
--
-- timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
--
-- DBG("sk %p timeo %ld", sk, timeo);
--
-- /* Wait for an incoming connection. (wake-one). */
-- add_wait_queue_exclusive(sk->sleep, &wait);
-- current->state = TASK_INTERRUPTIBLE;
-- while (!(ch = l2cap_accept_dequeue(sk, BT_CONNECTED))) {
-- if (!timeo) {
-- err = -EAGAIN;
-- break;
-- }
--
-- release_sock(sk);
-- timeo = schedule_timeout(timeo);
-- lock_sock(sk);
--
-- if (sk->state != BT_LISTEN) {
-- err = -EBADFD;
-- break;
-- }
--
-- if (signal_pending(current)) {
-- err = sock_intr_errno(timeo);
-- break;
-- }
-- }
-- current->state = TASK_RUNNING;
-- remove_wait_queue(sk->sleep, &wait);
--
-- if (err)
-- goto done;
--
-- sock_graft(ch, newsock);
-- newsock->state = SS_CONNECTED;
--
-- DBG("new socket %p", ch);
--
--done:
-- release_sock(sk);
--
-- return err;
--}
--
--static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
--{
-- struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-- struct sock *sk = sock->sk;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- addr->sa_family = AF_BLUETOOTH;
-- *len = sizeof(struct sockaddr_l2);
--
-- if (peer)
-- bacpy(&la->l2_bdaddr, &l2cap_pi(sk)->dst);
-- else
-- bacpy(&la->l2_bdaddr, &l2cap_pi(sk)->src);
--
-- la->l2_psm = l2cap_pi(sk)->psm;
--
-- return 0;
--}
--
--static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
--{
-- struct sock *sk = sock->sk;
-- int err = 0;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- if (sk->err)
-- return sock_error(sk);
--
-- if (msg->msg_flags & MSG_OOB)
-- return -EOPNOTSUPP;
--
-- lock_sock(sk);
--
-- if (sk->state == BT_CONNECTED)
-- err = l2cap_chan_send(sk, msg, len);
-- else
-- err = -ENOTCONN;
--
-- release_sock(sk);
-- return err;
--}
--
--static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
--{
-- struct sock *sk = sock->sk;
-- int noblock = flags & MSG_DONTWAIT;
-- int copied, err;
-- struct sk_buff *skb;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- if (flags & (MSG_OOB))
-- return -EOPNOTSUPP;
--
-- if (sk->state == BT_CLOSED)
-- return 0;
--
-- if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
-- return err;
--
-- msg->msg_namelen = 0;
--
-- copied = skb->len;
-- if (len < copied) {
-- msg->msg_flags |= MSG_TRUNC;
-- copied = len;
-- }
--
-- skb->h.raw = skb->data;
-- err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
--
-- skb_free_datagram(sk, skb);
--
-- return err ? : copied;
--}
--
--int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
--{
-- struct sock *sk = sock->sk;
-- struct l2cap_options opts;
-- int err = 0;
--
-- DBG("sk %p", sk);
--
-- lock_sock(sk);
--
-- switch (optname) {
-- case L2CAP_OPTIONS:
-- if (copy_from_user((char *)&opts, optval, optlen)) {
-- err = -EFAULT;
-- break;
-- }
-- l2cap_pi(sk)->imtu = opts.imtu;
-- l2cap_pi(sk)->omtu = opts.omtu;
-- break;
--
-- default:
-- err = -ENOPROTOOPT;
-- break;
-- };
--
-- release_sock(sk);
-- return err;
--}
--
--int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
--{
-- struct sock *sk = sock->sk;
-- struct l2cap_options opts;
-- struct l2cap_conninfo cinfo;
-- int len, err = 0;
--
-- if (get_user(len, optlen))
-- return -EFAULT;
--
-- lock_sock(sk);
--
-- switch (optname) {
-- case L2CAP_OPTIONS:
-- opts.imtu = l2cap_pi(sk)->imtu;
-- opts.omtu = l2cap_pi(sk)->omtu;
-- opts.flush_to = l2cap_pi(sk)->flush_to;
--
-- len = MIN(len, sizeof(opts));
-- if (copy_to_user(optval, (char *)&opts, len))
-- err = -EFAULT;
--
-- break;
--
-- case L2CAP_CONNINFO:
-- if (sk->state != BT_CONNECTED) {
-- err = -ENOTCONN;
-- break;
-- }
--
-- cinfo.hci_handle = l2cap_pi(sk)->conn->hconn->handle;
--
-- len = MIN(len, sizeof(cinfo));
-- if (copy_to_user(optval, (char *)&cinfo, len))
-- err = -EFAULT;
--
-- break;
--
-- default:
-- err = -ENOPROTOOPT;
-- break;
-- };
--
-- release_sock(sk);
-- return err;
--}
--
--static unsigned int l2cap_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
--{
-- struct sock *sk = sock->sk;
-- struct l2cap_accept_q *aq;
-- unsigned int mask;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- poll_wait(file, sk->sleep, wait);
-- mask = 0;
--
-- if (sk->err || !skb_queue_empty(&sk->error_queue))
-- mask |= POLLERR;
--
-- if (sk->shutdown == SHUTDOWN_MASK)
-- mask |= POLLHUP;
--
-- aq = &l2cap_pi(sk)->accept_q;
-- if (!skb_queue_empty(&sk->receive_queue) || aq->head || (sk->shutdown & RCV_SHUTDOWN))
-- mask |= POLLIN | POLLRDNORM;
--
-- if (sk->state == BT_CLOSED)
-- mask |= POLLHUP;
--
-- if (sock_writeable(sk))
-- mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
-- else
-- set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
--
-- return mask;
--}
--
--static int l2cap_sock_release(struct socket *sock)
--{
-- struct sock *sk = sock->sk;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- if (!sk)
-- return 0;
--
-- sock_orphan(sk);
--
-- l2cap_sock_close(sk);
--
-- return 0;
--}
--
--/* --------- L2CAP channels --------- */
--static struct sock * __l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
--{
-- struct sock *s;
--
-- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-- if (l2cap_pi(s)->dcid == cid)
-- break;
-- }
--
-- return s;
--}
--
--static inline struct sock *l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
--{
-- struct sock *s;
--
-- read_lock(&l->lock);
-- s = __l2cap_get_chan_by_dcid(l, cid);
-- read_unlock(&l->lock);
--
-- return s;
--}
--
--static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
--{
-- struct sock *s;
--
-- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-- if (l2cap_pi(s)->scid == cid)
-- break;
-- }
--
-- return s;
--}
--static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
--{
-- struct sock *s;
--
-- read_lock(&l->lock);
-- s = __l2cap_get_chan_by_scid(l, cid);
-- read_unlock(&l->lock);
--
-- return s;
--}
--
--static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
--{
-- struct sock *s;
--
-- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-- if (l2cap_pi(s)->ident == ident)
-- break;
-- }
--
-- return s;
--}
--
--static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
--{
-- struct sock *s;
--
-- read_lock(&l->lock);
-- s = __l2cap_get_chan_by_ident(l, ident);
-- read_unlock(&l->lock);
--
-- return s;
--}
--
--static __u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
--{
-- __u16 cid = 0x0040;
--
-- for (; cid < 0xffff; cid++) {
-- if(!__l2cap_get_chan_by_scid(l, cid))
-- return cid;
-- }
--
-- return 0;
--}
--
--static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
--{
-- sock_hold(sk);
--
-- if (l->head)
-- l2cap_pi(l->head)->prev_c = sk;
--
-- l2cap_pi(sk)->next_c = l->head;
-- l2cap_pi(sk)->prev_c = NULL;
-- l->head = sk;
--}
--
--static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
--{
-- struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
--
-- write_lock(&l->lock);
-- if (sk == l->head)
-- l->head = next;
--
-- if (next)
-- l2cap_pi(next)->prev_c = prev;
-- if (prev)
-- l2cap_pi(prev)->next_c = next;
-- write_unlock(&l->lock);
--
-- __sock_put(sk);
--}
--
--static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
--{
-- struct l2cap_chan_list *l = &conn->chan_list;
--
-- DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
--
-- l2cap_conn_clear_timer(conn);
--
-- atomic_inc(&conn->refcnt);
-- l2cap_pi(sk)->conn = conn;
--
-- if (sk->type == SOCK_SEQPACKET) {
-- /* Alloc CID for normal socket */
-- l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
-- } else {
-- /* Raw socket can send only signalling messages */
-- l2cap_pi(sk)->scid = 0x0001;
-- l2cap_pi(sk)->dcid = 0x0001;
-- l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
-- }
--
-- __l2cap_chan_link(l, sk);
--
-- if (parent)
-- l2cap_accept_queue(parent, sk);
--}
--
--static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
--{
-- struct l2cap_chan_list *l = &conn->chan_list;
--
-- write_lock(&l->lock);
-- __l2cap_chan_add(conn, sk, parent);
-- write_unlock(&l->lock);
--}
--
--/* Delete channel.
-- * Must be called on the locked socket. */
--static void l2cap_chan_del(struct sock *sk, int err)
--{
-- struct l2cap_conn *conn;
-- struct sock *parent;
--
-- conn = l2cap_pi(sk)->conn;
-- parent = l2cap_pi(sk)->parent;
--
-- DBG("sk %p, conn %p, err %d", sk, conn, err);
--
-- if (parent) {
-- /* Unlink from parent accept queue */
-- bh_lock_sock(parent);
-- l2cap_accept_unlink(sk);
-- bh_unlock_sock(parent);
-- }
--
-- if (conn) {
-- long timeout;
--
-- /* Unlink from channel list */
-- l2cap_chan_unlink(&conn->chan_list, sk);
-- l2cap_pi(sk)->conn = NULL;
--
-- if (conn->out)
-- timeout = L2CAP_DISCONN_TIMEOUT;
-- else
-- timeout = L2CAP_CONN_IDLE_TIMEOUT;
--
-- if (atomic_dec_and_test(&conn->refcnt) && conn->state == BT_CONNECTED) {
-- /* Schedule Baseband disconnect */
-- l2cap_conn_set_timer(conn, timeout);
-- }
-- }
--
-- sk->state = BT_CLOSED;
-- sk->err = err;
-- sk->state_change(sk);
--
-- sk->zapped = 1;
--}
--
--static void l2cap_conn_ready(struct l2cap_conn *conn)
--{
-- struct l2cap_chan_list *l = &conn->chan_list;
-- struct sock *sk;
--
-- DBG("conn %p", conn);
--
-- read_lock(&l->lock);
--
-- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-- bh_lock_sock(sk);
--
-- if (sk->type != SOCK_SEQPACKET) {
-- sk->state = BT_CONNECTED;
-- sk->state_change(sk);
-- l2cap_sock_clear_timer(sk);
-- } else if (sk->state == BT_CONNECT) {
-- l2cap_conn_req req;
-- req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- req.psm = l2cap_pi(sk)->psm;
-- l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
--
-- l2cap_sock_set_timer(sk, sk->sndtimeo);
-- }
--
-- bh_unlock_sock(sk);
-- }
--
-- read_unlock(&l->lock);
--}
--
--static void l2cap_chan_ready(struct sock *sk)
--{
-- struct sock *parent = l2cap_pi(sk)->parent;
--
-- DBG("sk %p, parent %p", sk, parent);
--
-- l2cap_pi(sk)->conf_state = 0;
-- l2cap_sock_clear_timer(sk);
--
-- if (!parent) {
-- /* Outgoing channel.
-- * Wake up socket sleeping on connect.
-- */
-- sk->state = BT_CONNECTED;
-- sk->state_change(sk);
-- } else {
-- /* Incomming channel.
-- * Wake up socket sleeping on accept.
-- */
-- parent->data_ready(parent, 1);
-- }
--}
--
--/* Copy frame to all raw sockets on that connection */
--void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
--{
-- struct l2cap_chan_list *l = &conn->chan_list;
-- struct sk_buff *nskb;
-- struct sock * sk;
--
-- DBG("conn %p", conn);
--
-- read_lock(&l->lock);
-- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-- if (sk->type != SOCK_RAW)
-- continue;
--
-- /* Don't send frame to the socket it came from */
-- if (skb->sk == sk)
-- continue;
--
-- if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
-- continue;
--
-- skb_queue_tail(&sk->receive_queue, nskb);
-- sk->data_ready(sk, nskb->len);
-- }
-- read_unlock(&l->lock);
--}
--
--static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
--{
-- struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-- struct sk_buff *skb, **frag;
-- int err, size, count, sent=0;
-- l2cap_hdr *lh;
--
-- /* Check outgoing MTU */
-- if (len > l2cap_pi(sk)->omtu)
-- return -EINVAL;
--
-- DBG("sk %p len %d", sk, len);
--
-- /* First fragment (with L2CAP header) */
-- count = MIN(conn->iff->mtu - L2CAP_HDR_SIZE, len);
-- size = L2CAP_HDR_SIZE + count;
-- if (!(skb = bluez_skb_send_alloc(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)))
-- return err;
--
-- /* Create L2CAP header */
-- lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-- lh->len = __cpu_to_le16(len);
-- lh->cid = __cpu_to_le16(l2cap_pi(sk)->dcid);
--
-- if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
-- err = -EFAULT;
-- goto fail;
-- }
--
-- sent += count;
-- len -= count;
--
-- /* Continuation fragments (no L2CAP header) */
-- frag = &skb_shinfo(skb)->frag_list;
-- while (len) {
-- count = MIN(conn->iff->mtu, len);
--
-- *frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
-- if (!*frag)
-- goto fail;
--
-- if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
-- err = -EFAULT;
-- goto fail;
-- }
--
-- sent += count;
-- len -= count;
--
-- frag = &(*frag)->next;
-- }
--
-- if ((err = hci_send_acl(conn->hconn, skb, 0)) < 0)
-- goto fail;
--
-- return sent;
--
--fail:
-- kfree_skb(skb);
-- return err;
--}
--
--/* --------- L2CAP signalling commands --------- */
--static inline __u8 l2cap_get_ident(struct l2cap_conn *conn)
--{
-- __u8 id;
--
-- /* Get next available identificator.
-- * 1 - 199 are used by kernel.
-- * 200 - 254 are used by utilities like l2ping, etc
-- */
--
-- spin_lock(&conn->lock);
--
-- if (++conn->tx_ident > 199)
-- conn->tx_ident = 1;
--
-- id = conn->tx_ident;
--
-- spin_unlock(&conn->lock);
--
-- return id;
--}
--
--static inline struct sk_buff *l2cap_build_cmd(__u8 code, __u8 ident, __u16 len, void *data)
--{
-- struct sk_buff *skb;
-- l2cap_cmd_hdr *cmd;
-- l2cap_hdr *lh;
-- int size;
--
-- DBG("code 0x%2.2x, ident 0x%2.2x, len %d", code, ident, len);
--
-- size = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + len;
-- if (!(skb = bluez_skb_alloc(size, GFP_ATOMIC)))
-- return NULL;
--
-- lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-- lh->len = __cpu_to_le16(L2CAP_CMD_HDR_SIZE + len);
-- lh->cid = __cpu_to_le16(0x0001);
--
-- cmd = (l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
-- cmd->code = code;
-- cmd->ident = ident;
-- cmd->len = __cpu_to_le16(len);
--
-- if (len)
-- memcpy(skb_put(skb, len), data, len);
--
-- return skb;
--}
--
--static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data)
--{
-- struct sk_buff *skb;
-- __u8 ident;
--
-- DBG("code 0x%2.2x", code);
--
-- ident = l2cap_get_ident(conn);
-- if (!(skb = l2cap_build_cmd(code, ident, len, data)))
-- return -ENOMEM;
-- return hci_send_acl(conn->hconn, skb, 0);
--}
--
--static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data)
--{
-- struct sk_buff *skb;
--
-- DBG("code 0x%2.2x", code);
--
-- if (!(skb = l2cap_build_cmd(code, ident, len, data)))
-- return -ENOMEM;
-- return hci_send_acl(conn->hconn, skb, 0);
--}
--
--static inline int l2cap_get_conf_opt(__u8 **ptr, __u8 *type, __u32 *val)
--{
-- l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
-- int len;
--
-- *type = opt->type;
-- switch (opt->len) {
-- case 1:
-- *val = *((__u8 *) opt->val);
-- break;
--
-- case 2:
-- *val = __le16_to_cpu(*((__u16 *)opt->val));
-- break;
--
-- case 4:
-- *val = __le32_to_cpu(*((__u32 *)opt->val));
-- break;
--
-- default:
-- *val = 0L;
-- break;
-- };
--
-- DBG("type 0x%2.2x len %d val 0x%8.8x", *type, opt->len, *val);
--
-- len = L2CAP_CONF_OPT_SIZE + opt->len;
--
-- *ptr += len;
--
-- return len;
--}
--
--static inline void l2cap_parse_conf_req(struct sock *sk, char *data, int len)
--{
-- __u8 type, hint; __u32 val;
-- __u8 *ptr = data;
--
-- DBG("sk %p len %d", sk, len);
--
-- while (len >= L2CAP_CONF_OPT_SIZE) {
-- len -= l2cap_get_conf_opt(&ptr, &type, &val);
--
-- hint = type & 0x80;
-- type &= 0x7f;
--
-- switch (type) {
-- case L2CAP_CONF_MTU:
-- l2cap_pi(sk)->conf_mtu = val;
-- break;
--
-- case L2CAP_CONF_FLUSH_TO:
-- l2cap_pi(sk)->flush_to = val;
-- break;
--
-- case L2CAP_CONF_QOS:
-- break;
--
-- default:
-- if (hint)
-- break;
--
-- /* FIXME: Reject unknon option */
-- break;
-- };
-- }
--}
--
--static inline void l2cap_add_conf_opt(__u8 **ptr, __u8 type, __u8 len, __u32 val)
--{
-- register l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
--
-- DBG("type 0x%2.2x len %d val 0x%8.8x", type, len, val);
--
-- opt->type = type;
-- opt->len = len;
-- switch (len) {
-- case 1:
-- *((__u8 *) opt->val) = val;
-- break;
--
-- case 2:
-- *((__u16 *) opt->val) = __cpu_to_le16(val);
-- break;
--
-- case 4:
-- *((__u32 *) opt->val) = __cpu_to_le32(val);
-- break;
-- };
--
-- *ptr += L2CAP_CONF_OPT_SIZE + len;
--}
--
--static int l2cap_build_conf_req(struct sock *sk, __u8 *data)
--{
-- struct l2cap_pinfo *pi = l2cap_pi(sk);
-- l2cap_conf_req *req = (l2cap_conf_req *) data;
-- __u8 *ptr = req->data;
--
-- DBG("sk %p", sk);
--
-- if (pi->imtu != L2CAP_DEFAULT_MTU)
-- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
--
-- /* FIXME. Need actual value of the flush timeout */
-- //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
-- // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
--
-- req->dcid = __cpu_to_le16(pi->dcid);
-- req->flags = __cpu_to_le16(0);
--
-- return ptr - data;
--}
--
--static int l2cap_conf_output(struct sock *sk, __u8 **ptr)
--{
-- struct l2cap_pinfo *pi = l2cap_pi(sk);
-- int result = 0;
--
-- /* Configure output options and let other side know
-- * which ones we don't like.
-- */
-- if (pi->conf_mtu < pi->omtu) {
-- l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, l2cap_pi(sk)->omtu);
-- result = L2CAP_CONF_UNACCEPT;
-- } else {
-- pi->omtu = pi->conf_mtu;
-- }
--
-- DBG("sk %p result %d", sk, result);
-- return result;
--}
--
--static int l2cap_build_conf_rsp(struct sock *sk, __u8 *data, int *result)
--{
-- l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data;
-- __u8 *ptr = rsp->data;
--
-- DBG("sk %p complete %d", sk, result ? 1 : 0);
--
-- if (result)
-- *result = l2cap_conf_output(sk, &ptr);
--
-- rsp->scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- rsp->result = __cpu_to_le16(result ? *result : 0);
-- rsp->flags = __cpu_to_le16(0);
--
-- return ptr - data;
--}
--
--static inline int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- struct l2cap_chan_list *list = &conn->chan_list;
-- l2cap_conn_req *req = (l2cap_conn_req *) data;
-- l2cap_conn_rsp rsp;
-- struct sock *sk, *parent;
--
-- __u16 scid = __le16_to_cpu(req->scid);
-- __u16 psm = req->psm;
--
-- DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
--
-- /* Check if we have socket listening on psm */
-- if (!(parent = l2cap_get_sock_listen(&conn->src, psm)))
-- goto reject;
--
-- bh_lock_sock(parent);
-- write_lock(&list->lock);
--
-- /* Check if we already have channel with that dcid */
-- if (__l2cap_get_chan_by_dcid(list, scid))
-- goto unlock;
--
-- /* Check for backlog size */
-- if (parent->ack_backlog > parent->max_ack_backlog)
-- goto unlock;
--
-- if (!(sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC)))
-- goto unlock;
--
-- l2cap_sock_init(sk, parent);
--
-- bacpy(&l2cap_pi(sk)->src, &conn->src);
-- bacpy(&l2cap_pi(sk)->dst, &conn->dst);
-- l2cap_pi(sk)->psm = psm;
-- l2cap_pi(sk)->dcid = scid;
--
-- __l2cap_chan_add(conn, sk, parent);
-- sk->state = BT_CONFIG;
--
-- write_unlock(&list->lock);
-- bh_unlock_sock(parent);
--
-- rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- rsp.result = __cpu_to_le16(0);
-- rsp.status = __cpu_to_le16(0);
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
--
-- return 0;
--
--unlock:
-- write_unlock(&list->lock);
-- bh_unlock_sock(parent);
--
--reject:
-- rsp.scid = __cpu_to_le16(scid);
-- rsp.dcid = __cpu_to_le16(0);
-- rsp.status = __cpu_to_le16(0);
-- rsp.result = __cpu_to_le16(L2CAP_CONN_NO_MEM);
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
--
-- return 0;
--}
--
--static inline int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_conn_rsp *rsp = (l2cap_conn_rsp *) data;
-- __u16 scid, dcid, result, status;
-- struct sock *sk;
--
-- scid = __le16_to_cpu(rsp->scid);
-- dcid = __le16_to_cpu(rsp->dcid);
-- result = __le16_to_cpu(rsp->result);
-- status = __le16_to_cpu(rsp->status);
--
-- DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-- return -ENOENT;
--
-- bh_lock_sock(sk);
--
-- if (!result) {
-- char req[64];
--
-- sk->state = BT_CONFIG;
-- l2cap_pi(sk)->dcid = dcid;
-- l2cap_pi(sk)->conf_state |= CONF_REQ_SENT;
--
-- l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-- } else {
-- l2cap_chan_del(sk, ECONNREFUSED);
-- }
--
-- bh_unlock_sock(sk);
-- return 0;
--}
--
--static inline int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_conf_req * req = (l2cap_conf_req *) data;
-- __u16 dcid, flags;
-- __u8 rsp[64];
-- struct sock *sk;
-- int result;
--
-- dcid = __le16_to_cpu(req->dcid);
-- flags = __le16_to_cpu(req->flags);
--
-- DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-- return -ENOENT;
--
-- bh_lock_sock(sk);
--
-- l2cap_parse_conf_req(sk, req->data, cmd->len - L2CAP_CONF_REQ_SIZE);
--
-- if (flags & 0x01) {
-- /* Incomplete config. Send empty response. */
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
-- goto unlock;
-- }
--
-- /* Complete config. */
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &result), rsp);
--
-- if (result)
-- goto unlock;
--
-- /* Output config done */
-- l2cap_pi(sk)->conf_state |= CONF_OUTPUT_DONE;
--
-- if (l2cap_pi(sk)->conf_state & CONF_INPUT_DONE) {
-- sk->state = BT_CONNECTED;
-- l2cap_chan_ready(sk);
-- } else if (!(l2cap_pi(sk)->conf_state & CONF_REQ_SENT)) {
-- char req[64];
-- l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-- }
--
--unlock:
-- bh_unlock_sock(sk);
--
-- return 0;
--}
--
--static inline int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_conf_rsp *rsp = (l2cap_conf_rsp *)data;
-- __u16 scid, flags, result;
-- struct sock *sk;
-- int err = 0;
--
-- scid = __le16_to_cpu(rsp->scid);
-- flags = __le16_to_cpu(rsp->flags);
-- result = __le16_to_cpu(rsp->result);
--
-- DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-- return -ENOENT;
--
-- bh_lock_sock(sk);
--
-- if (result) {
-- l2cap_disconn_req req;
--
-- /* They didn't like our options. Well... we do not negotiate.
-- * Close channel.
-- */
-- sk->state = BT_DISCONN;
--
-- req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
--
-- l2cap_sock_set_timer(sk, sk->sndtimeo);
-- goto done;
-- }
--
-- if (flags & 0x01)
-- goto done;
--
-- /* Input config done */
-- l2cap_pi(sk)->conf_state |= CONF_INPUT_DONE;
--
-- if (l2cap_pi(sk)->conf_state & CONF_OUTPUT_DONE) {
-- sk->state = BT_CONNECTED;
-- l2cap_chan_ready(sk);
-- }
--
--done:
-- bh_unlock_sock(sk);
--
-- return err;
--}
--
--static inline int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_disconn_req *req = (l2cap_disconn_req *) data;
-- l2cap_disconn_rsp rsp;
-- __u16 dcid, scid;
-- struct sock *sk;
--
-- scid = __le16_to_cpu(req->scid);
-- dcid = __le16_to_cpu(req->dcid);
--
-- DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-- return 0;
--
-- bh_lock_sock(sk);
--
-- rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_DISCONN_RSP, L2CAP_DISCONN_RSP_SIZE, &rsp);
--
-- l2cap_chan_del(sk, ECONNRESET);
--
-- bh_unlock_sock(sk);
--
-- l2cap_sock_kill(sk);
--
-- return 0;
--}
--
--static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_disconn_rsp *rsp = (l2cap_disconn_rsp *) data;
-- __u16 dcid, scid;
-- struct sock *sk;
--
-- scid = __le16_to_cpu(rsp->scid);
-- dcid = __le16_to_cpu(rsp->dcid);
--
-- DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-- return -ENOENT;
--
-- bh_lock_sock(sk);
-- l2cap_sock_clear_timer(sk);
-- l2cap_chan_del(sk, ECONNABORTED);
-- bh_unlock_sock(sk);
--
-- l2cap_sock_kill(sk);
--
-- return 0;
--}
--
--static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
--{
-- __u8 *data = skb->data;
-- int len = skb->len;
-- l2cap_cmd_hdr cmd;
-- int err = 0;
--
-- while (len >= L2CAP_CMD_HDR_SIZE) {
-- memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
-- data += L2CAP_CMD_HDR_SIZE;
-- len -= L2CAP_CMD_HDR_SIZE;
--
-- cmd.len = __le16_to_cpu(cmd.len);
--
-- DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
--
-- if (cmd.len > len || !cmd.ident) {
-- DBG("corrupted command");
-- break;
-- }
--
-- switch (cmd.code) {
-- case L2CAP_CONN_REQ:
-- err = l2cap_connect_req(conn, &cmd, data);
-- break;
--
-- case L2CAP_CONN_RSP:
-- err = l2cap_connect_rsp(conn, &cmd, data);
-- break;
--
-- case L2CAP_CONF_REQ:
-- err = l2cap_config_req(conn, &cmd, data);
-- break;
--
-- case L2CAP_CONF_RSP:
-- err = l2cap_config_rsp(conn, &cmd, data);
-- break;
--
-- case L2CAP_DISCONN_REQ:
-- err = l2cap_disconnect_req(conn, &cmd, data);
-- break;
--
-- case L2CAP_DISCONN_RSP:
-- err = l2cap_disconnect_rsp(conn, &cmd, data);
-- break;
--
-- case L2CAP_COMMAND_REJ:
-- /* FIXME: We should process this */
-- l2cap_raw_recv(conn, skb);
-- break;
--
-- case L2CAP_ECHO_REQ:
-- l2cap_send_rsp(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data);
-- break;
--
-- case L2CAP_ECHO_RSP:
-- case L2CAP_INFO_REQ:
-- case L2CAP_INFO_RSP:
-- l2cap_raw_recv(conn, skb);
-- break;
--
-- default:
-- ERR("Uknown signaling command 0x%2.2x", cmd.code);
-- err = -EINVAL;
-- break;
-- };
--
-- if (err) {
-- l2cap_cmd_rej rej;
-- DBG("error %d", err);
--
-- /* FIXME: Map err to a valid reason. */
-- rej.reason = __cpu_to_le16(0);
-- l2cap_send_rsp(conn, cmd.ident, L2CAP_COMMAND_REJ, L2CAP_CMD_REJ_SIZE, &rej);
-- }
--
-- data += cmd.len;
-- len -= cmd.len;
-- }
--
-- kfree_skb(skb);
--}
--
--static inline int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
--{
-- struct sock *sk;
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, cid))) {
-- DBG("unknown cid 0x%4.4x", cid);
-- goto drop;
-- }
--
-- DBG("sk %p, len %d", sk, skb->len);
--
-- if (sk->state != BT_CONNECTED)
-- goto drop;
--
-- if (l2cap_pi(sk)->imtu < skb->len)
-- goto drop;
--
-- skb_queue_tail(&sk->receive_queue, skb);
-- sk->data_ready(sk, skb->len);
--
-- return 0;
--
--drop:
-- kfree_skb(skb);
--
-- return 0;
--}
--
--static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
--{
-- l2cap_hdr *lh = (l2cap_hdr *) skb->data;
-- __u16 cid, len;
--
-- skb_pull(skb, L2CAP_HDR_SIZE);
-- cid = __le16_to_cpu(lh->cid);
-- len = __le16_to_cpu(lh->len);
--
-- DBG("len %d, cid 0x%4.4x", len, cid);
--
-- if (cid == 0x0001)
-- l2cap_sig_channel(conn, skb);
-- else
-- l2cap_data_channel(conn, cid, skb);
--}
--
--/* ------------ L2CAP interface with lower layer (HCI) ------------- */
--static int l2cap_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
--{
-- struct hci_dev *hdev = (struct hci_dev *) ptr;
--
-- DBG("hdev %s, event %ld", hdev->name, event);
--
-- write_lock(&l2cap_rt_lock);
--
-- switch (event) {
-- case HCI_DEV_UP:
-- l2cap_iff_add(hdev);
-- break;
--
-- case HCI_DEV_DOWN:
-- l2cap_iff_del(hdev);
-- break;
-- };
--
-- write_unlock(&l2cap_rt_lock);
--
-- return NOTIFY_DONE;
--}
--
--int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
--{
-- struct l2cap_iff *iff;
--
-- DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
--
-- if (!(iff = hdev->l2cap_data)) {
-- ERR("unknown interface");
-- return 0;
-- }
--
-- /* Always accept connection */
-- return 1;
--}
--
--int l2cap_connect_cfm(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 status, struct hci_conn *hconn)
--{
-- struct l2cap_conn *conn;
-- struct l2cap_iff *iff;
-- int err = 0;
--
-- DBG("hdev %s bdaddr %s hconn %p", hdev->name, batostr(bdaddr), hconn);
--
-- if (!(iff = hdev->l2cap_data)) {
-- ERR("unknown interface");
-- return 0;
-- }
--
-- l2cap_iff_lock(iff);
--
-- conn = l2cap_get_conn_by_addr(iff, bdaddr);
--
-- if (conn) {
-- /* Outgoing connection */
-- DBG("Outgoing connection: %s -> %s, %p, %2.2x", batostr(iff->bdaddr), batostr(bdaddr), conn, status);
--
-- if (!status && hconn) {
-- conn->state = BT_CONNECTED;
-- conn->hconn = hconn;
--
-- hconn->l2cap_data = (void *)conn;
--
-- /* Establish channels */
-- l2cap_conn_ready(conn);
-- } else {
-- l2cap_conn_del(conn, bterr(status));
-- }
-- } else {
-- /* Incomming connection */
-- DBG("Incomming connection: %s -> %s, %2.2x", batostr(iff->bdaddr), batostr(bdaddr), status);
--
-- if (status || !hconn)
-- goto done;
--
-- if (!(conn = l2cap_conn_add(iff, bdaddr))) {
-- err = -ENOMEM;
-- goto done;
-- }
--
-- conn->hconn = hconn;
-- hconn->l2cap_data = (void *)conn;
--
-- conn->state = BT_CONNECTED;
-- }
--
--done:
-- l2cap_iff_unlock(iff);
--
-- return err;
--}
--
--int l2cap_disconn_ind(struct hci_conn *hconn, __u8 reason)
--{
-- struct l2cap_conn *conn = hconn->l2cap_data;
--
-- DBG("hconn %p reason %d", hconn, reason);
--
-- if (!conn) {
-- ERR("unknown connection");
-- return 0;
-- }
-- conn->hconn = NULL;
--
-- l2cap_iff_lock(conn->iff);
-- l2cap_conn_del(conn, bterr(reason));
-- l2cap_iff_unlock(conn->iff);
--
-- return 0;
--}
--
--int l2cap_recv_acldata(struct hci_conn *hconn, struct sk_buff *skb, __u16 flags)
--{
-- struct l2cap_conn *conn = hconn->l2cap_data;
--
-- if (!conn) {
-- ERR("unknown connection %p", hconn);
-- goto drop;
-- }
--
-- DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
--
-- if (flags & ACL_START) {
-- int flen, tlen, size;
-- l2cap_hdr *lh;
--
-- if (conn->rx_len) {
-- ERR("Unexpected start frame (len %d)", skb->len);
-- kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
-- conn->rx_len = 0;
-- }
--
-- if (skb->len < L2CAP_HDR_SIZE) {
-- ERR("Frame is too small (len %d)", skb->len);
-- goto drop;
-- }
--
-- lh = (l2cap_hdr *)skb->data;
-- tlen = __le16_to_cpu(lh->len);
-- flen = skb->len - L2CAP_HDR_SIZE;
--
-- DBG("Start: total len %d, frag len %d", tlen, flen);
--
-- if (flen == tlen) {
-- /* Complete frame received */
-- l2cap_recv_frame(conn, skb);
-- return 0;
-- }
--
-- /* Allocate skb for the complete frame (with header) */
-- size = L2CAP_HDR_SIZE + tlen;
-- if (!(conn->rx_skb = bluez_skb_alloc(size, GFP_ATOMIC)))
-- goto drop;
--
-- memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
--
-- conn->rx_len = tlen - flen;
-- } else {
-- DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
--
-- if (!conn->rx_len) {
-- ERR("Unexpected continuation frame (len %d)", skb->len);
-- goto drop;
-- }
--
-- if (skb->len > conn->rx_len) {
-- ERR("Fragment is too large (len %d)", skb->len);
-- kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
-- goto drop;
-- }
--
-- memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
-- conn->rx_len -= skb->len;
--
-- if (!conn->rx_len) {
-- /* Complete frame received */
-- l2cap_recv_frame(conn, conn->rx_skb);
-- conn->rx_skb = NULL;
-- }
-- }
--
--drop:
-- kfree_skb(skb);
-- return 0;
--}
--
--struct proto_ops l2cap_sock_ops = {
-- family: PF_BLUETOOTH,
-- release: l2cap_sock_release,
-- bind: l2cap_sock_bind,
-- connect: l2cap_sock_connect,
-- listen: l2cap_sock_listen,
-- accept: l2cap_sock_accept,
-- getname: l2cap_sock_getname,
-- sendmsg: l2cap_sock_sendmsg,
-- recvmsg: l2cap_sock_recvmsg,
-- poll: l2cap_sock_poll,
-- socketpair: sock_no_socketpair,
-- ioctl: sock_no_ioctl,
-- shutdown: sock_no_shutdown,
-- setsockopt: l2cap_sock_setsockopt,
-- getsockopt: l2cap_sock_getsockopt,
-- mmap: sock_no_mmap
--};
--
--struct net_proto_family l2cap_sock_family_ops = {
-- family: PF_BLUETOOTH,
-- create: l2cap_sock_create
--};
--
--struct hci_proto l2cap_hci_proto = {
-- name: "L2CAP",
-- id: HCI_PROTO_L2CAP,
-- connect_ind: l2cap_connect_ind,
-- connect_cfm: l2cap_connect_cfm,
-- disconn_ind: l2cap_disconn_ind,
-- recv_acldata: l2cap_recv_acldata,
--};
--
--struct notifier_block l2cap_nblock = {
-- notifier_call: l2cap_dev_event
--};
--
--int __init l2cap_init(void)
--{
-- INF("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
--
-- if (bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops)) {
-- ERR("Can't register L2CAP socket");
-- return -EPROTO;
-- }
--
-- if (hci_register_proto(&l2cap_hci_proto) < 0) {
-- ERR("Can't register L2CAP protocol");
-- return -EPROTO;
-- }
--
-- hci_register_notifier(&l2cap_nblock);
--
-- l2cap_register_proc();
--
-- return 0;
--}
--
--void l2cap_cleanup(void)
--{
-- l2cap_unregister_proc();
--
-- /* Unregister socket, protocol and notifier */
-- if (bluez_sock_unregister(BTPROTO_L2CAP))
-- ERR("Can't unregister L2CAP socket");
--
-- if (hci_unregister_proto(&l2cap_hci_proto) < 0)
-- ERR("Can't unregister L2CAP protocol");
--
-- hci_unregister_notifier(&l2cap_nblock);
--
-- /* We _must_ not have any sockets and/or connections
-- * at this stage.
-- */
--
-- /* Free interface list and unlock HCI devices */
-- {
-- struct list_head *list = &l2cap_iff_list;
--
-- while (!list_empty(list)) {
-- struct l2cap_iff *iff;
--
-- iff = list_entry(list->next, struct l2cap_iff, list);
-- l2cap_iff_del(iff->hdev);
-- }
-- }
--}
--
--module_init(l2cap_init);
--module_exit(l2cap_cleanup);
--
--MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
--MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
--MODULE_LICENSE("GPL");
--
---- linux/net/bluetooth/l2cap_proc.c~bluetooth-2.4.18-mh11
-+++ linux/net/bluetooth/l2cap_proc.c
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * BlueZ L2CAP proc fs support.
-- *
-- * $Id$
-- */
--
--#include <linux/config.h>
--#include <linux/module.h>
--
--#include <linux/types.h>
--#include <linux/errno.h>
--#include <linux/kernel.h>
--#include <linux/major.h>
--#include <linux/sched.h>
--#include <linux/slab.h>
--#include <linux/poll.h>
--#include <linux/fcntl.h>
--#include <linux/init.h>
--#include <linux/skbuff.h>
--#include <linux/interrupt.h>
--#include <linux/socket.h>
--#include <linux/skbuff.h>
--#include <linux/proc_fs.h>
--#include <linux/list.h>
--#include <net/sock.h>
--
--#include <asm/system.h>
--#include <asm/uaccess.h>
--
--#include <net/bluetooth/bluez.h>
--#include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/l2cap_core.h>
--
--#ifndef L2CAP_DEBUG
--#undef DBG
--#define DBG( A... )
--#endif
--
--/* ----- PROC fs support ----- */
--static int l2cap_conn_dump(char *buf, struct l2cap_iff *iff)
--{
-- struct list_head *p;
-- char *ptr = buf;
--
-- list_for_each(p, &iff->conn_list) {
-- struct l2cap_conn *c;
--
-- c = list_entry(p, struct l2cap_conn, list);
-- ptr += sprintf(ptr, " %p %d %p %p %s %s\n",
-- c, c->state, c->iff, c->hconn, batostr(&c->src), batostr(&c->dst));
-- }
--
-- return ptr - buf;
--}
--
--static int l2cap_iff_dump(char *buf)
--{
-- struct list_head *p;
-- char *ptr = buf;
--
-- ptr += sprintf(ptr, "Interfaces:\n");
--
-- write_lock(&l2cap_rt_lock);
--
-- list_for_each(p, &l2cap_iff_list) {
-- struct l2cap_iff *iff;
--
-- iff = list_entry(p, struct l2cap_iff, list);
--
-- ptr += sprintf(ptr, " %s %p %p\n", iff->hdev->name, iff, iff->hdev);
--
-- l2cap_iff_lock(iff);
-- ptr += l2cap_conn_dump(ptr, iff);
-- l2cap_iff_unlock(iff);
-- }
--
-- write_unlock(&l2cap_rt_lock);
--
-- ptr += sprintf(ptr, "\n");
--
-- return ptr - buf;
--}
--
--static int l2cap_sock_dump(char *buf, struct bluez_sock_list *list)
--{
-- struct l2cap_pinfo *pi;
-- struct sock *sk;
-- char *ptr = buf;
--
-- ptr += sprintf(ptr, "Sockets:\n");
--
-- write_lock(&list->lock);
--
-- for (sk = list->head; sk; sk = sk->next) {
-- pi = l2cap_pi(sk);
-- ptr += sprintf(ptr, " %p %d %p %d %s %s 0x%4.4x 0x%4.4x %d %d\n", sk, sk->state, pi->conn, pi->psm,
-- batostr(&pi->src), batostr(&pi->dst), pi->scid, pi->dcid, pi->imtu, pi->omtu );
-- }
--
-- write_unlock(&list->lock);
--
-- ptr += sprintf(ptr, "\n");
--
-- return ptr - buf;
--}
--
--static int l2cap_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
--{
-- char *ptr = buf;
-- int len;
--
-- DBG("count %d, offset %ld", count, offset);
--
-- ptr += l2cap_iff_dump(ptr);
-- ptr += l2cap_sock_dump(ptr, &l2cap_sk_list);
-- len = ptr - buf;
--
-- if (len <= count + offset)
-- *eof = 1;
--
-- *start = buf + offset;
-- len -= offset;
--
-- if (len > count)
-- len = count;
-- if (len < 0)
-- len = 0;
--
-- return len;
--}
--
--void l2cap_register_proc(void)
--{
-- create_proc_read_entry("bluetooth/l2cap", 0, 0, l2cap_read_proc, NULL);
--}
--
--void l2cap_unregister_proc(void)
--{
-- remove_proc_entry("bluetooth/l2cap", NULL);
--}
---- linux/net/bluetooth/lib.c~bluetooth-2.4.18-mh11 2001-09-07 18:28:38.000000000 +0200
-+++ linux/net/bluetooth/lib.c 2004-01-25 23:37:39.000000000 +0100
-@@ -25,7 +25,7 @@
- /*
- * BlueZ kernel library.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/kernel.h>
-@@ -105,7 +105,7 @@
- return EACCES;
-
- case 0x06:
-- return EINVAL;
-+ return EBADE;
-
- case 0x07:
- return ENOMEM;
---- linux/net/bluetooth/Makefile~bluetooth-2.4.18-mh11 2001-06-12 04:15:27.000000000 +0200
-+++ linux/net/bluetooth/Makefile 2004-01-25 23:37:39.000000000 +0100
-@@ -1,20 +1,31 @@
- #
--# Makefile for the Bluetooth subsystem
-+# Makefile for the Linux Bluetooth subsystem
- #
--O_TARGET := bluetooth.o
-
--list-multi := hci.o l2cap.o
--export-objs := syms.o
--hci-objs := af_bluetooth.o hci_core.o hci_sock.o lib.o syms.o
--l2cap-objs := l2cap_core.o l2cap_proc.o
-+O_TARGET := bluetooth.o
-
--obj-$(CONFIG_BLUEZ) += hci.o
-+list-multi := bluez.o
-+export-objs := syms.o l2cap.o
-+
-+bluez-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o lib.o syms.o
-+
-+obj-$(CONFIG_BLUEZ) += bluez.o
- obj-$(CONFIG_BLUEZ_L2CAP) += l2cap.o
-+obj-$(CONFIG_BLUEZ_SCO) += sco.o
-
--include $(TOPDIR)/Rules.make
-+subdir-$(CONFIG_BLUEZ_RFCOMM) += rfcomm
-+subdir-$(CONFIG_BLUEZ_BNEP) += bnep
-+subdir-$(CONFIG_BLUEZ_CMTP) += cmtp
-
--hci.o: $(hci-objs)
-- $(LD) -r -o $@ $(hci-objs)
-+ifeq ($(CONFIG_BLUEZ_RFCOMM),y)
-+obj-y += rfcomm/rfcomm.o
-+endif
-
--l2cap.o: $(l2cap-objs)
-- $(LD) -r -o $@ $(l2cap-objs)
-+ifeq ($(CONFIG_BLUEZ_BNEP),y)
-+obj-y += bnep/bnep.o
-+endif
-+
-+include $(TOPDIR)/Rules.make
-+
-+bluez.o: $(bluez-objs)
-+ $(LD) -r -o $@ $(bluez-objs)
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/rfcomm/Config.in 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,10 @@
-+#
-+# Bluetooth RFCOMM layer configuration
-+#
-+
-+dep_tristate 'RFCOMM protocol support' CONFIG_BLUEZ_RFCOMM $CONFIG_BLUEZ_L2CAP
-+
-+if [ "$CONFIG_BLUEZ_RFCOMM" != "n" ]; then
-+ bool ' RFCOMM TTY support' CONFIG_BLUEZ_RFCOMM_TTY
-+fi
-+
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/rfcomm/core.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,1939 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ RPN support - Dirk Husemann <hud@zurich.ibm.com>
-+*/
-+
-+/*
-+ * RFCOMM core.
-+ *
-+ * $Id$
-+ */
-+
-+#define __KERNEL_SYSCALLS__
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/signal.h>
-+#include <linux/init.h>
-+#include <linux/wait.h>
-+#include <linux/net.h>
-+#include <linux/proc_fs.h>
-+#include <net/sock.h>
-+#include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/l2cap.h>
-+#include <net/bluetooth/rfcomm.h>
-+
-+#define VERSION "1.1"
-+
-+#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+struct task_struct *rfcomm_thread;
-+DECLARE_MUTEX(rfcomm_sem);
-+unsigned long rfcomm_event;
-+
-+static LIST_HEAD(session_list);
-+static atomic_t terminate, running;
-+
-+static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len);
-+static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci);
-+static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci);
-+static int rfcomm_queue_disc(struct rfcomm_dlc *d);
-+static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type);
-+static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d);
-+static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig);
-+static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len);
-+static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits);
-+static void rfcomm_make_uih(struct sk_buff *skb, u8 addr);
-+
-+static void rfcomm_process_connect(struct rfcomm_session *s);
-+
-+/* ---- RFCOMM frame parsing macros ---- */
-+#define __get_dlci(b) ((b & 0xfc) >> 2)
-+#define __get_channel(b) ((b & 0xf8) >> 3)
-+#define __get_dir(b) ((b & 0x04) >> 2)
-+#define __get_type(b) ((b & 0xef))
-+
-+#define __test_ea(b) ((b & 0x01))
-+#define __test_cr(b) ((b & 0x02))
-+#define __test_pf(b) ((b & 0x10))
-+
-+#define __addr(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01)
-+#define __ctrl(type, pf) (((type & 0xef) | (pf << 4)))
-+#define __dlci(dir, chn) (((chn & 0x1f) << 1) | dir)
-+#define __srv_channel(dlci) (dlci >> 1)
-+#define __dir(dlci) (dlci & 0x01)
-+
-+#define __len8(len) (((len) << 1) | 1)
-+#define __len16(len) ((len) << 1)
-+
-+/* MCC macros */
-+#define __mcc_type(cr, type) (((type << 2) | (cr << 1) | 0x01))
-+#define __get_mcc_type(b) ((b & 0xfc) >> 2)
-+#define __get_mcc_len(b) ((b & 0xfe) >> 1)
-+
-+/* RPN macros */
-+#define __rpn_line_settings(data, stop, parity) ((data & 0x3) | ((stop & 0x1) << 2) | ((parity & 0x3) << 3))
-+#define __get_rpn_data_bits(line) ((line) & 0x3)
-+#define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1)
-+#define __get_rpn_parity(line) (((line) >> 3) & 0x3)
-+
-+/* ---- RFCOMM FCS computation ---- */
-+
-+/* CRC on 2 bytes */
-+#define __crc(data) (rfcomm_crc_table[rfcomm_crc_table[0xff ^ data[0]] ^ data[1]])
-+
-+/* FCS on 2 bytes */
-+static inline u8 __fcs(u8 *data)
-+{
-+ return (0xff - __crc(data));
-+}
-+
-+/* FCS on 3 bytes */
-+static inline u8 __fcs2(u8 *data)
-+{
-+ return (0xff - rfcomm_crc_table[__crc(data) ^ data[2]]);
-+}
-+
-+/* Check FCS */
-+static inline int __check_fcs(u8 *data, int type, u8 fcs)
-+{
-+ u8 f = __crc(data);
-+
-+ if (type != RFCOMM_UIH)
-+ f = rfcomm_crc_table[f ^ data[2]];
-+
-+ return rfcomm_crc_table[f ^ fcs] != 0xcf;
-+}
-+
-+/* ---- L2CAP callbacks ---- */
-+static void rfcomm_l2state_change(struct sock *sk)
-+{
-+ BT_DBG("%p state %d", sk, sk->state);
-+ rfcomm_schedule(RFCOMM_SCHED_STATE);
-+}
-+
-+static void rfcomm_l2data_ready(struct sock *sk, int bytes)
-+{
-+ BT_DBG("%p bytes %d", sk, bytes);
-+ rfcomm_schedule(RFCOMM_SCHED_RX);
-+}
-+
-+static int rfcomm_l2sock_create(struct socket **sock)
-+{
-+ int err;
-+
-+ BT_DBG("");
-+
-+ err = sock_create(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP, sock);
-+ if (!err) {
-+ struct sock *sk = (*sock)->sk;
-+ sk->data_ready = rfcomm_l2data_ready;
-+ sk->state_change = rfcomm_l2state_change;
-+ }
-+ return err;
-+}
-+
-+/* ---- RFCOMM DLCs ---- */
-+static void rfcomm_dlc_timeout(unsigned long arg)
-+{
-+ struct rfcomm_dlc *d = (void *) arg;
-+
-+ BT_DBG("dlc %p state %ld", d, d->state);
-+
-+ set_bit(RFCOMM_TIMED_OUT, &d->flags);
-+ rfcomm_dlc_put(d);
-+ rfcomm_schedule(RFCOMM_SCHED_TIMEO);
-+}
-+
-+static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout)
-+{
-+ BT_DBG("dlc %p state %ld timeout %ld", d, d->state, timeout);
-+
-+ if (!mod_timer(&d->timer, jiffies + timeout))
-+ rfcomm_dlc_hold(d);
-+}
-+
-+static void rfcomm_dlc_clear_timer(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("dlc %p state %ld", d, d->state);
-+
-+ if (timer_pending(&d->timer) && del_timer(&d->timer))
-+ rfcomm_dlc_put(d);
-+}
-+
-+static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("%p", d);
-+
-+ d->state = BT_OPEN;
-+ d->flags = 0;
-+ d->mscex = 0;
-+ d->mtu = RFCOMM_DEFAULT_MTU;
-+ d->v24_sig = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV;
-+
-+ d->cfc = RFCOMM_CFC_DISABLED;
-+ d->rx_credits = RFCOMM_DEFAULT_CREDITS;
-+}
-+
-+struct rfcomm_dlc *rfcomm_dlc_alloc(int prio)
-+{
-+ struct rfcomm_dlc *d = kmalloc(sizeof(*d), prio);
-+ if (!d)
-+ return NULL;
-+ memset(d, 0, sizeof(*d));
-+
-+ init_timer(&d->timer);
-+ d->timer.function = rfcomm_dlc_timeout;
-+ d->timer.data = (unsigned long) d;
-+
-+ skb_queue_head_init(&d->tx_queue);
-+ spin_lock_init(&d->lock);
-+ atomic_set(&d->refcnt, 1);
-+
-+ rfcomm_dlc_clear_state(d);
-+
-+ BT_DBG("%p", d);
-+ return d;
-+}
-+
-+void rfcomm_dlc_free(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("%p", d);
-+
-+ skb_queue_purge(&d->tx_queue);
-+ kfree(d);
-+}
-+
-+static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d)
-+{
-+ BT_DBG("dlc %p session %p", d, s);
-+
-+ rfcomm_session_hold(s);
-+
-+ rfcomm_dlc_hold(d);
-+ list_add(&d->list, &s->dlcs);
-+ d->session = s;
-+}
-+
-+static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
-+{
-+ struct rfcomm_session *s = d->session;
-+
-+ BT_DBG("dlc %p refcnt %d session %p", d, atomic_read(&d->refcnt), s);
-+
-+ list_del(&d->list);
-+ d->session = NULL;
-+ rfcomm_dlc_put(d);
-+
-+ rfcomm_session_put(s);
-+}
-+
-+static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_dlc *d;
-+ struct list_head *p;
-+
-+ list_for_each(p, &s->dlcs) {
-+ d = list_entry(p, struct rfcomm_dlc, list);
-+ if (d->dlci == dlci)
-+ return d;
-+ }
-+ return NULL;
-+}
-+
-+static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
-+{
-+ struct rfcomm_session *s;
-+ int err = 0;
-+ u8 dlci;
-+
-+ BT_DBG("dlc %p state %ld %s %s channel %d",
-+ d, d->state, batostr(src), batostr(dst), channel);
-+
-+ if (channel < 1 || channel > 30)
-+ return -EINVAL;
-+
-+ if (d->state != BT_OPEN && d->state != BT_CLOSED)
-+ return 0;
-+
-+ s = rfcomm_session_get(src, dst);
-+ if (!s) {
-+ s = rfcomm_session_create(src, dst, &err);
-+ if (!s)
-+ return err;
-+ }
-+
-+ dlci = __dlci(!s->initiator, channel);
-+
-+ /* Check if DLCI already exists */
-+ if (rfcomm_dlc_get(s, dlci))
-+ return -EBUSY;
-+
-+ rfcomm_dlc_clear_state(d);
-+
-+ d->dlci = dlci;
-+ d->addr = __addr(s->initiator, dlci);
-+ d->priority = 7;
-+
-+ d->state = BT_CONFIG;
-+ rfcomm_dlc_link(s, d);
-+
-+ d->mtu = s->mtu;
-+ d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc;
-+
-+ if (s->state == BT_CONNECTED)
-+ rfcomm_send_pn(s, 1, d);
-+ rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT);
-+ return 0;
-+}
-+
-+int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
-+{
-+ mm_segment_t fs;
-+ int r;
-+
-+ rfcomm_lock();
-+
-+ fs = get_fs(); set_fs(KERNEL_DS);
-+ r = __rfcomm_dlc_open(d, src, dst, channel);
-+ set_fs(fs);
-+
-+ rfcomm_unlock();
-+ return r;
-+}
-+
-+static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
-+{
-+ struct rfcomm_session *s = d->session;
-+ if (!s)
-+ return 0;
-+
-+ BT_DBG("dlc %p state %ld dlci %d err %d session %p",
-+ d, d->state, d->dlci, err, s);
-+
-+ switch (d->state) {
-+ case BT_CONNECTED:
-+ case BT_CONFIG:
-+ case BT_CONNECT:
-+ d->state = BT_DISCONN;
-+ if (skb_queue_empty(&d->tx_queue)) {
-+ rfcomm_send_disc(s, d->dlci);
-+ rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT);
-+ } else {
-+ rfcomm_queue_disc(d);
-+ rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT * 2);
-+ }
-+ break;
-+
-+ default:
-+ rfcomm_dlc_clear_timer(d);
-+
-+ rfcomm_dlc_lock(d);
-+ d->state = BT_CLOSED;
-+ d->state_change(d, err);
-+ rfcomm_dlc_unlock(d);
-+
-+ skb_queue_purge(&d->tx_queue);
-+ rfcomm_dlc_unlink(d);
-+ }
-+
-+ return 0;
-+}
-+
-+int rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
-+{
-+ mm_segment_t fs;
-+ int r;
-+
-+ rfcomm_lock();
-+
-+ fs = get_fs(); set_fs(KERNEL_DS);
-+ r = __rfcomm_dlc_close(d, err);
-+ set_fs(fs);
-+
-+ rfcomm_unlock();
-+ return r;
-+}
-+
-+int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
-+{
-+ int len = skb->len;
-+
-+ if (d->state != BT_CONNECTED)
-+ return -ENOTCONN;
-+
-+ BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len);
-+
-+ if (len > d->mtu)
-+ return -EINVAL;
-+
-+ rfcomm_make_uih(skb, d->addr);
-+ skb_queue_tail(&d->tx_queue, skb);
-+
-+ if (!test_bit(RFCOMM_TX_THROTTLED, &d->flags))
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+ return len;
-+}
-+
-+void __rfcomm_dlc_throttle(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("dlc %p state %ld", d, d->state);
-+
-+ if (!d->cfc) {
-+ d->v24_sig |= RFCOMM_V24_FC;
-+ set_bit(RFCOMM_MSC_PENDING, &d->flags);
-+ }
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+}
-+
-+void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("dlc %p state %ld", d, d->state);
-+
-+ if (!d->cfc) {
-+ d->v24_sig &= ~RFCOMM_V24_FC;
-+ set_bit(RFCOMM_MSC_PENDING, &d->flags);
-+ }
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+}
-+
-+/*
-+ Set/get modem status functions use _local_ status i.e. what we report
-+ to the other side.
-+ Remote status is provided by dlc->modem_status() callback.
-+ */
-+int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig)
-+{
-+ BT_DBG("dlc %p state %ld v24_sig 0x%x",
-+ d, d->state, v24_sig);
-+
-+ if (test_bit(RFCOMM_RX_THROTTLED, &d->flags))
-+ v24_sig |= RFCOMM_V24_FC;
-+ else
-+ v24_sig &= ~RFCOMM_V24_FC;
-+
-+ d->v24_sig = v24_sig;
-+
-+ if (!test_and_set_bit(RFCOMM_MSC_PENDING, &d->flags))
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+
-+ return 0;
-+}
-+
-+int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig)
-+{
-+ BT_DBG("dlc %p state %ld v24_sig 0x%x",
-+ d, d->state, d->v24_sig);
-+
-+ *v24_sig = d->v24_sig;
-+ return 0;
-+}
-+
-+/* ---- RFCOMM sessions ---- */
-+struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
-+{
-+ struct rfcomm_session *s = kmalloc(sizeof(*s), GFP_KERNEL);
-+ if (!s)
-+ return NULL;
-+ memset(s, 0, sizeof(*s));
-+
-+ BT_DBG("session %p sock %p", s, sock);
-+
-+ INIT_LIST_HEAD(&s->dlcs);
-+ s->state = state;
-+ s->sock = sock;
-+
-+ s->mtu = RFCOMM_DEFAULT_MTU;
-+ s->cfc = RFCOMM_CFC_UNKNOWN;
-+
-+ list_add(&s->list, &session_list);
-+
-+ /* Do not increment module usage count for listeting sessions.
-+ * Otherwise we won't be able to unload the module. */
-+ if (state != BT_LISTEN)
-+ MOD_INC_USE_COUNT;
-+ return s;
-+}
-+
-+void rfcomm_session_del(struct rfcomm_session *s)
-+{
-+ int state = s->state;
-+
-+ BT_DBG("session %p state %ld", s, s->state);
-+
-+ list_del(&s->list);
-+
-+ if (state == BT_CONNECTED)
-+ rfcomm_send_disc(s, 0);
-+
-+ sock_release(s->sock);
-+ kfree(s);
-+
-+ if (state != BT_LISTEN)
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
-+{
-+ struct rfcomm_session *s;
-+ struct list_head *p, *n;
-+ struct bluez_pinfo *pi;
-+ list_for_each_safe(p, n, &session_list) {
-+ s = list_entry(p, struct rfcomm_session, list);
-+ pi = bluez_pi(s->sock->sk);
-+
-+ if ((!bacmp(src, BDADDR_ANY) || !bacmp(&pi->src, src)) &&
-+ !bacmp(&pi->dst, dst))
-+ return s;
-+ }
-+ return NULL;
-+}
-+
-+void rfcomm_session_close(struct rfcomm_session *s, int err)
-+{
-+ struct rfcomm_dlc *d;
-+ struct list_head *p, *n;
-+
-+ BT_DBG("session %p state %ld err %d", s, s->state, err);
-+
-+ rfcomm_session_hold(s);
-+
-+ s->state = BT_CLOSED;
-+
-+ /* Close all dlcs */
-+ list_for_each_safe(p, n, &s->dlcs) {
-+ d = list_entry(p, struct rfcomm_dlc, list);
-+ d->state = BT_CLOSED;
-+ __rfcomm_dlc_close(d, err);
-+ }
-+
-+ rfcomm_session_put(s);
-+}
-+
-+struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err)
-+{
-+ struct rfcomm_session *s = NULL;
-+ struct sockaddr_l2 addr;
-+ struct l2cap_options opts;
-+ struct socket *sock;
-+ int size;
-+
-+ BT_DBG("%s %s", batostr(src), batostr(dst));
-+
-+ *err = rfcomm_l2sock_create(&sock);
-+ if (*err < 0)
-+ return NULL;
-+
-+ bacpy(&addr.l2_bdaddr, src);
-+ addr.l2_family = AF_BLUETOOTH;
-+ addr.l2_psm = 0;
-+ *err = sock->ops->bind(sock, (struct sockaddr *) &addr, sizeof(addr));
-+ if (*err < 0)
-+ goto failed;
-+
-+ /* Set L2CAP options */
-+ size = sizeof(opts);
-+ sock->ops->getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, &size);
-+
-+ opts.imtu = RFCOMM_MAX_L2CAP_MTU;
-+ sock->ops->setsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, size);
-+
-+ s = rfcomm_session_add(sock, BT_BOUND);
-+ if (!s) {
-+ *err = -ENOMEM;
-+ goto failed;
-+ }
-+
-+ s->initiator = 1;
-+
-+ bacpy(&addr.l2_bdaddr, dst);
-+ addr.l2_family = AF_BLUETOOTH;
-+ addr.l2_psm = htobs(RFCOMM_PSM);
-+ *err = sock->ops->connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
-+ if (*err == 0 || *err == -EAGAIN)
-+ return s;
-+
-+ rfcomm_session_del(s);
-+ return NULL;
-+
-+failed:
-+ sock_release(sock);
-+ return NULL;
-+}
-+
-+void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst)
-+{
-+ struct sock *sk = s->sock->sk;
-+ if (src)
-+ bacpy(src, &bluez_pi(sk)->src);
-+ if (dst)
-+ bacpy(dst, &bluez_pi(sk)->dst);
-+}
-+
-+/* ---- RFCOMM frame sending ---- */
-+static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len)
-+{
-+ struct socket *sock = s->sock;
-+ struct iovec iv = { data, len };
-+ struct msghdr msg;
-+ int err;
-+
-+ BT_DBG("session %p len %d", s, len);
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_iovlen = 1;
-+ msg.msg_iov = &iv;
-+
-+ err = sock->ops->sendmsg(sock, &msg, len, 0);
-+ return err;
-+}
-+
-+static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_cmd cmd;
-+
-+ BT_DBG("%p dlci %d", s, dlci);
-+
-+ cmd.addr = __addr(s->initiator, dlci);
-+ cmd.ctrl = __ctrl(RFCOMM_SABM, 1);
-+ cmd.len = __len8(0);
-+ cmd.fcs = __fcs2((u8 *) &cmd);
-+
-+ return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
-+}
-+
-+static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_cmd cmd;
-+
-+ BT_DBG("%p dlci %d", s, dlci);
-+
-+ cmd.addr = __addr(!s->initiator, dlci);
-+ cmd.ctrl = __ctrl(RFCOMM_UA, 1);
-+ cmd.len = __len8(0);
-+ cmd.fcs = __fcs2((u8 *) &cmd);
-+
-+ return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
-+}
-+
-+static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_cmd cmd;
-+
-+ BT_DBG("%p dlci %d", s, dlci);
-+
-+ cmd.addr = __addr(s->initiator, dlci);
-+ cmd.ctrl = __ctrl(RFCOMM_DISC, 1);
-+ cmd.len = __len8(0);
-+ cmd.fcs = __fcs2((u8 *) &cmd);
-+
-+ return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
-+}
-+
-+static int rfcomm_queue_disc(struct rfcomm_dlc *d)
-+{
-+ struct rfcomm_cmd *cmd;
-+ struct sk_buff *skb;
-+
-+ BT_DBG("dlc %p dlci %d", d, d->dlci);
-+
-+ skb = alloc_skb(sizeof(*cmd), GFP_KERNEL);
-+ if (!skb)
-+ return -ENOMEM;
-+
-+ cmd = (void *) __skb_put(skb, sizeof(*cmd));
-+ cmd->addr = d->addr;
-+ cmd->ctrl = __ctrl(RFCOMM_DISC, 1);
-+ cmd->len = __len8(0);
-+ cmd->fcs = __fcs2((u8 *) cmd);
-+
-+ skb_queue_tail(&d->tx_queue, skb);
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+ return 0;
-+}
-+
-+static int rfcomm_send_dm(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_cmd cmd;
-+
-+ BT_DBG("%p dlci %d", s, dlci);
-+
-+ cmd.addr = __addr(!s->initiator, dlci);
-+ cmd.ctrl = __ctrl(RFCOMM_DM, 1);
-+ cmd.len = __len8(0);
-+ cmd.fcs = __fcs2((u8 *) &cmd);
-+
-+ return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
-+}
-+
-+static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d type %d", s, cr, type);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + 1);
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_NSC);
-+ mcc->len = __len8(1);
-+
-+ /* Type that we didn't like */
-+ *ptr = __mcc_type(cr, type); ptr++;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ struct rfcomm_pn *pn;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d dlci %d mtu %d", s, cr, d->dlci, d->mtu);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + sizeof(*pn));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_PN);
-+ mcc->len = __len8(sizeof(*pn));
-+
-+ pn = (void *) ptr; ptr += sizeof(*pn);
-+ pn->dlci = d->dlci;
-+ pn->priority = d->priority;
-+ pn->ack_timer = 0;
-+ pn->max_retrans = 0;
-+
-+ if (s->cfc) {
-+ pn->flow_ctrl = cr ? 0xf0 : 0xe0;
-+ pn->credits = RFCOMM_DEFAULT_CREDITS;
-+ } else {
-+ pn->flow_ctrl = 0;
-+ pn->credits = 0;
-+ }
-+
-+ pn->mtu = htobs(d->mtu);
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,
-+ u8 bit_rate, u8 data_bits, u8 stop_bits,
-+ u8 parity, u8 flow_ctrl_settings,
-+ u8 xon_char, u8 xoff_char, u16 param_mask)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ struct rfcomm_rpn *rpn;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d dlci %d bit_r 0x%x data_b 0x%x stop_b 0x%x parity 0x%x"
-+ "flwc_s 0x%x xon_c 0x%x xoff_c 0x%x p_mask 0x%x",
-+ s, cr, dlci, bit_rate, data_bits, stop_bits, parity,
-+ flow_ctrl_settings, xon_char, xoff_char, param_mask);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + sizeof(*rpn));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_RPN);
-+ mcc->len = __len8(sizeof(*rpn));
-+
-+ rpn = (void *) ptr; ptr += sizeof(*rpn);
-+ rpn->dlci = __addr(1, dlci);
-+ rpn->bit_rate = bit_rate;
-+ rpn->line_settings = __rpn_line_settings(data_bits, stop_bits, parity);
-+ rpn->flow_ctrl = flow_ctrl_settings;
-+ rpn->xon_char = xon_char;
-+ rpn->xoff_char = xoff_char;
-+ rpn->param_mask = param_mask;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ struct rfcomm_rls *rls;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d status 0x%x", s, cr, status);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + sizeof(*rls));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_RLS);
-+ mcc->len = __len8(sizeof(*rls));
-+
-+ rls = (void *) ptr; ptr += sizeof(*rls);
-+ rls->dlci = __addr(1, dlci);
-+ rls->status = status;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ struct rfcomm_msc *msc;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d v24 0x%x", s, cr, v24_sig);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + sizeof(*msc));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_MSC);
-+ mcc->len = __len8(sizeof(*msc));
-+
-+ msc = (void *) ptr; ptr += sizeof(*msc);
-+ msc->dlci = __addr(1, dlci);
-+ msc->v24_sig = v24_sig | 0x01;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d", s, cr);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_FCOFF);
-+ mcc->len = __len8(0);
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_fcon(struct rfcomm_session *s, int cr)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d", s, cr);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_FCON);
-+ mcc->len = __len8(0);
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len)
-+{
-+ struct socket *sock = s->sock;
-+ struct iovec iv[3];
-+ struct msghdr msg;
-+ unsigned char hdr[5], crc[1];
-+
-+ if (len > 125)
-+ return -EINVAL;
-+
-+ BT_DBG("%p cr %d", s, cr);
-+
-+ hdr[0] = __addr(s->initiator, 0);
-+ hdr[1] = __ctrl(RFCOMM_UIH, 0);
-+ hdr[2] = 0x01 | ((len + 2) << 1);
-+ hdr[3] = 0x01 | ((cr & 0x01) << 1) | (RFCOMM_TEST << 2);
-+ hdr[4] = 0x01 | (len << 1);
-+
-+ crc[0] = __fcs(hdr);
-+
-+ iv[0].iov_base = hdr;
-+ iv[0].iov_len = 5;
-+ iv[1].iov_base = pattern;
-+ iv[1].iov_len = len;
-+ iv[2].iov_base = crc;
-+ iv[2].iov_len = 1;
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_iovlen = 3;
-+ msg.msg_iov = iv;
-+ return sock->ops->sendmsg(sock, &msg, 6 + len, 0);
-+}
-+
-+static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits)
-+{
-+ struct rfcomm_hdr *hdr;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p addr %d credits %d", s, addr, credits);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = addr;
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 1);
-+ hdr->len = __len8(0);
-+
-+ *ptr = credits; ptr++;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
-+{
-+ struct rfcomm_hdr *hdr;
-+ int len = skb->len;
-+ u8 *crc;
-+
-+ if (len > 127) {
-+ hdr = (void *) skb_push(skb, 4);
-+ put_unaligned(htobs(__len16(len)), (u16 *) &hdr->len);
-+ } else {
-+ hdr = (void *) skb_push(skb, 3);
-+ hdr->len = __len8(len);
-+ }
-+ hdr->addr = addr;
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+
-+ crc = skb_put(skb, 1);
-+ *crc = __fcs((void *) hdr);
-+}
-+
-+/* ---- RFCOMM frame reception ---- */
-+static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
-+{
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (dlci) {
-+ /* Data channel */
-+ struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
-+ if (!d) {
-+ rfcomm_send_dm(s, dlci);
-+ return 0;
-+ }
-+
-+ switch (d->state) {
-+ case BT_CONNECT:
-+ rfcomm_dlc_clear_timer(d);
-+
-+ rfcomm_dlc_lock(d);
-+ d->state = BT_CONNECTED;
-+ d->state_change(d, 0);
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_send_msc(s, 1, dlci, d->v24_sig);
-+ break;
-+
-+ case BT_DISCONN:
-+ d->state = BT_CLOSED;
-+ __rfcomm_dlc_close(d, 0);
-+ break;
-+ }
-+ } else {
-+ /* Control channel */
-+ switch (s->state) {
-+ case BT_CONNECT:
-+ s->state = BT_CONNECTED;
-+ rfcomm_process_connect(s);
-+ break;
-+ }
-+ }
-+ return 0;
-+}
-+
-+static int rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci)
-+{
-+ int err = 0;
-+
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (dlci) {
-+ /* Data DLC */
-+ struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
-+ if (d) {
-+ if (d->state == BT_CONNECT || d->state == BT_CONFIG)
-+ err = ECONNREFUSED;
-+ else
-+ err = ECONNRESET;
-+
-+ d->state = BT_CLOSED;
-+ __rfcomm_dlc_close(d, err);
-+ }
-+ } else {
-+ if (s->state == BT_CONNECT)
-+ err = ECONNREFUSED;
-+ else
-+ err = ECONNRESET;
-+
-+ s->state = BT_CLOSED;
-+ rfcomm_session_close(s, err);
-+ }
-+ return 0;
-+}
-+
-+static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
-+{
-+ int err = 0;
-+
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (dlci) {
-+ struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
-+ if (d) {
-+ rfcomm_send_ua(s, dlci);
-+
-+ if (d->state == BT_CONNECT || d->state == BT_CONFIG)
-+ err = ECONNREFUSED;
-+ else
-+ err = ECONNRESET;
-+
-+ d->state = BT_CLOSED;
-+ __rfcomm_dlc_close(d, err);
-+ } else
-+ rfcomm_send_dm(s, dlci);
-+
-+ } else {
-+ rfcomm_send_ua(s, 0);
-+
-+ if (s->state == BT_CONNECT)
-+ err = ECONNREFUSED;
-+ else
-+ err = ECONNRESET;
-+
-+ s->state = BT_CLOSED;
-+ rfcomm_session_close(s, err);
-+ }
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_dlc *d;
-+ u8 channel;
-+
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (!dlci) {
-+ rfcomm_send_ua(s, 0);
-+
-+ if (s->state == BT_OPEN) {
-+ s->state = BT_CONNECTED;
-+ rfcomm_process_connect(s);
-+ }
-+ return 0;
-+ }
-+
-+ /* Check if DLC exists */
-+ d = rfcomm_dlc_get(s, dlci);
-+ if (d) {
-+ if (d->state == BT_OPEN) {
-+ /* DLC was previously opened by PN request */
-+ rfcomm_send_ua(s, dlci);
-+
-+ rfcomm_dlc_lock(d);
-+ d->state = BT_CONNECTED;
-+ d->state_change(d, 0);
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_send_msc(s, 1, dlci, d->v24_sig);
-+ }
-+ return 0;
-+ }
-+
-+ /* Notify socket layer about incomming connection */
-+ channel = __srv_channel(dlci);
-+ if (rfcomm_connect_ind(s, channel, &d)) {
-+ d->dlci = dlci;
-+ d->addr = __addr(s->initiator, dlci);
-+ rfcomm_dlc_link(s, d);
-+
-+ rfcomm_send_ua(s, dlci);
-+
-+ rfcomm_dlc_lock(d);
-+ d->state = BT_CONNECTED;
-+ d->state_change(d, 0);
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_send_msc(s, 1, dlci, d->v24_sig);
-+ } else {
-+ rfcomm_send_dm(s, dlci);
-+ }
-+
-+ return 0;
-+}
-+
-+static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
-+{
-+ struct rfcomm_session *s = d->session;
-+
-+ BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d",
-+ d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits);
-+
-+ if (pn->flow_ctrl == 0xf0 || pn->flow_ctrl == 0xe0) {
-+ d->cfc = s->cfc = RFCOMM_CFC_ENABLED;
-+ d->tx_credits = pn->credits;
-+ } else {
-+ d->cfc = s->cfc = RFCOMM_CFC_DISABLED;
-+ set_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+ }
-+
-+ d->priority = pn->priority;
-+
-+ d->mtu = s->mtu = btohs(pn->mtu);
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb)
-+{
-+ struct rfcomm_pn *pn = (void *) skb->data;
-+ struct rfcomm_dlc *d;
-+ u8 dlci = pn->dlci;
-+
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (!dlci)
-+ return 0;
-+
-+ d = rfcomm_dlc_get(s, dlci);
-+ if (d) {
-+ if (cr) {
-+ /* PN request */
-+ rfcomm_apply_pn(d, cr, pn);
-+ rfcomm_send_pn(s, 0, d);
-+ } else {
-+ /* PN response */
-+ switch (d->state) {
-+ case BT_CONFIG:
-+ rfcomm_apply_pn(d, cr, pn);
-+
-+ d->state = BT_CONNECT;
-+ rfcomm_send_sabm(s, d->dlci);
-+ break;
-+ }
-+ }
-+ } else {
-+ u8 channel = __srv_channel(dlci);
-+
-+ if (!cr)
-+ return 0;
-+
-+ /* PN request for non existing DLC.
-+ * Assume incomming connection. */
-+ if (rfcomm_connect_ind(s, channel, &d)) {
-+ d->dlci = dlci;
-+ d->addr = __addr(s->initiator, dlci);
-+ rfcomm_dlc_link(s, d);
-+
-+ rfcomm_apply_pn(d, cr, pn);
-+
-+ d->state = BT_OPEN;
-+ rfcomm_send_pn(s, 0, d);
-+ } else {
-+ rfcomm_send_dm(s, dlci);
-+ }
-+ }
-+ return 0;
-+}
-+
-+static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_buff *skb)
-+{
-+ struct rfcomm_rpn *rpn = (void *) skb->data;
-+ u8 dlci = __get_dlci(rpn->dlci);
-+
-+ u8 bit_rate = 0;
-+ u8 data_bits = 0;
-+ u8 stop_bits = 0;
-+ u8 parity = 0;
-+ u8 flow_ctrl = 0;
-+ u8 xon_char = 0;
-+ u8 xoff_char = 0;
-+ u16 rpn_mask = RFCOMM_RPN_PM_ALL;
-+
-+ BT_DBG("dlci %d cr %d len 0x%x bitr 0x%x line 0x%x flow 0x%x xonc 0x%x xoffc 0x%x pm 0x%x",
-+ dlci, cr, len, rpn->bit_rate, rpn->line_settings, rpn->flow_ctrl,
-+ rpn->xon_char, rpn->xoff_char, rpn->param_mask);
-+
-+ if (!cr)
-+ return 0;
-+
-+ if (len == 1) {
-+ /* request: return default setting */
-+ bit_rate = RFCOMM_RPN_BR_115200;
-+ data_bits = RFCOMM_RPN_DATA_8;
-+ stop_bits = RFCOMM_RPN_STOP_1;
-+ parity = RFCOMM_RPN_PARITY_NONE;
-+ flow_ctrl = RFCOMM_RPN_FLOW_NONE;
-+ xon_char = RFCOMM_RPN_XON_CHAR;
-+ xoff_char = RFCOMM_RPN_XOFF_CHAR;
-+
-+ goto rpn_out;
-+ }
-+ /* check for sane values: ignore/accept bit_rate, 8 bits, 1 stop bit, no parity,
-+ no flow control lines, normal XON/XOFF chars */
-+ if (rpn->param_mask & RFCOMM_RPN_PM_BITRATE) {
-+ bit_rate = rpn->bit_rate;
-+ if (bit_rate != RFCOMM_RPN_BR_115200) {
-+ BT_DBG("RPN bit rate mismatch 0x%x", bit_rate);
-+ bit_rate = RFCOMM_RPN_BR_115200;
-+ rpn_mask ^= RFCOMM_RPN_PM_BITRATE;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_DATA) {
-+ data_bits = __get_rpn_data_bits(rpn->line_settings);
-+ if (data_bits != RFCOMM_RPN_DATA_8) {
-+ BT_DBG("RPN data bits mismatch 0x%x", data_bits);
-+ data_bits = RFCOMM_RPN_DATA_8;
-+ rpn_mask ^= RFCOMM_RPN_PM_DATA;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_STOP) {
-+ stop_bits = __get_rpn_stop_bits(rpn->line_settings);
-+ if (stop_bits != RFCOMM_RPN_STOP_1) {
-+ BT_DBG("RPN stop bits mismatch 0x%x", stop_bits);
-+ stop_bits = RFCOMM_RPN_STOP_1;
-+ rpn_mask ^= RFCOMM_RPN_PM_STOP;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_PARITY) {
-+ parity = __get_rpn_parity(rpn->line_settings);
-+ if (parity != RFCOMM_RPN_PARITY_NONE) {
-+ BT_DBG("RPN parity mismatch 0x%x", parity);
-+ parity = RFCOMM_RPN_PARITY_NONE;
-+ rpn_mask ^= RFCOMM_RPN_PM_PARITY;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_FLOW) {
-+ flow_ctrl = rpn->flow_ctrl;
-+ if (flow_ctrl != RFCOMM_RPN_FLOW_NONE) {
-+ BT_DBG("RPN flow ctrl mismatch 0x%x", flow_ctrl);
-+ flow_ctrl = RFCOMM_RPN_FLOW_NONE;
-+ rpn_mask ^= RFCOMM_RPN_PM_FLOW;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_XON) {
-+ xon_char = rpn->xon_char;
-+ if (xon_char != RFCOMM_RPN_XON_CHAR) {
-+ BT_DBG("RPN XON char mismatch 0x%x", xon_char);
-+ xon_char = RFCOMM_RPN_XON_CHAR;
-+ rpn_mask ^= RFCOMM_RPN_PM_XON;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_XOFF) {
-+ xoff_char = rpn->xoff_char;
-+ if (xoff_char != RFCOMM_RPN_XOFF_CHAR) {
-+ BT_DBG("RPN XOFF char mismatch 0x%x", xoff_char);
-+ xoff_char = RFCOMM_RPN_XOFF_CHAR;
-+ rpn_mask ^= RFCOMM_RPN_PM_XOFF;
-+ }
-+ }
-+
-+rpn_out:
-+ rfcomm_send_rpn(s, 0, dlci,
-+ bit_rate, data_bits, stop_bits, parity, flow_ctrl,
-+ xon_char, xoff_char, rpn_mask);
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_rls(struct rfcomm_session *s, int cr, struct sk_buff *skb)
-+{
-+ struct rfcomm_rls *rls = (void *) skb->data;
-+ u8 dlci = __get_dlci(rls->dlci);
-+
-+ BT_DBG("dlci %d cr %d status 0x%x", dlci, cr, rls->status);
-+
-+ if (!cr)
-+ return 0;
-+
-+ /* FIXME: We should probably do something with this
-+ information here. But for now it's sufficient just
-+ to reply -- Bluetooth 1.1 says it's mandatory to
-+ recognise and respond to RLS */
-+
-+ rfcomm_send_rls(s, 0, dlci, rls->status);
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_msc(struct rfcomm_session *s, int cr, struct sk_buff *skb)
-+{
-+ struct rfcomm_msc *msc = (void *) skb->data;
-+ struct rfcomm_dlc *d;
-+ u8 dlci = __get_dlci(msc->dlci);
-+
-+ BT_DBG("dlci %d cr %d v24 0x%x", dlci, cr, msc->v24_sig);
-+
-+ d = rfcomm_dlc_get(s, dlci);
-+ if (!d)
-+ return 0;
-+
-+ if (cr) {
-+ if (msc->v24_sig & RFCOMM_V24_FC && !d->cfc)
-+ set_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+ else
-+ clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+
-+ rfcomm_dlc_lock(d);
-+ if (d->modem_status)
-+ d->modem_status(d, msc->v24_sig);
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_send_msc(s, 0, dlci, msc->v24_sig);
-+
-+ d->mscex |= RFCOMM_MSCEX_RX;
-+ } else
-+ d->mscex |= RFCOMM_MSCEX_TX;
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb)
-+{
-+ struct rfcomm_mcc *mcc = (void *) skb->data;
-+ u8 type, cr, len;
-+
-+ cr = __test_cr(mcc->type);
-+ type = __get_mcc_type(mcc->type);
-+ len = __get_mcc_len(mcc->len);
-+
-+ BT_DBG("%p type 0x%x cr %d", s, type, cr);
-+
-+ skb_pull(skb, 2);
-+
-+ switch (type) {
-+ case RFCOMM_PN:
-+ rfcomm_recv_pn(s, cr, skb);
-+ break;
-+
-+ case RFCOMM_RPN:
-+ rfcomm_recv_rpn(s, cr, len, skb);
-+ break;
-+
-+ case RFCOMM_RLS:
-+ rfcomm_recv_rls(s, cr, skb);
-+ break;
-+
-+ case RFCOMM_MSC:
-+ rfcomm_recv_msc(s, cr, skb);
-+ break;
-+
-+ case RFCOMM_FCOFF:
-+ if (cr) {
-+ set_bit(RFCOMM_TX_THROTTLED, &s->flags);
-+ rfcomm_send_fcoff(s, 0);
-+ }
-+ break;
-+
-+ case RFCOMM_FCON:
-+ if (cr) {
-+ clear_bit(RFCOMM_TX_THROTTLED, &s->flags);
-+ rfcomm_send_fcon(s, 0);
-+ }
-+ break;
-+
-+ case RFCOMM_TEST:
-+ if (cr)
-+ rfcomm_send_test(s, 0, skb->data, skb->len);
-+ break;
-+
-+ case RFCOMM_NSC:
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown control type 0x%02x", type);
-+ rfcomm_send_nsc(s, cr, type);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static int rfcomm_recv_data(struct rfcomm_session *s, u8 dlci, int pf, struct sk_buff *skb)
-+{
-+ struct rfcomm_dlc *d;
-+
-+ BT_DBG("session %p state %ld dlci %d pf %d", s, s->state, dlci, pf);
-+
-+ d = rfcomm_dlc_get(s, dlci);
-+ if (!d) {
-+ rfcomm_send_dm(s, dlci);
-+ goto drop;
-+ }
-+
-+ if (pf && d->cfc) {
-+ u8 credits = *(u8 *) skb->data; skb_pull(skb, 1);
-+
-+ d->tx_credits += credits;
-+ if (d->tx_credits)
-+ clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+ }
-+
-+ if (skb->len && d->state == BT_CONNECTED) {
-+ rfcomm_dlc_lock(d);
-+ d->rx_credits--;
-+ d->data_ready(d, skb);
-+ rfcomm_dlc_unlock(d);
-+ return 0;
-+ }
-+
-+drop:
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
-+{
-+ struct rfcomm_hdr *hdr = (void *) skb->data;
-+ u8 type, dlci, fcs;
-+
-+ dlci = __get_dlci(hdr->addr);
-+ type = __get_type(hdr->ctrl);
-+
-+ /* Trim FCS */
-+ skb->len--; skb->tail--;
-+ fcs = *(u8 *) skb->tail;
-+
-+ if (__check_fcs(skb->data, type, fcs)) {
-+ BT_ERR("bad checksum in packet");
-+ kfree_skb(skb);
-+ return -EILSEQ;
-+ }
-+
-+ if (__test_ea(hdr->len))
-+ skb_pull(skb, 3);
-+ else
-+ skb_pull(skb, 4);
-+
-+ switch (type) {
-+ case RFCOMM_SABM:
-+ if (__test_pf(hdr->ctrl))
-+ rfcomm_recv_sabm(s, dlci);
-+ break;
-+
-+ case RFCOMM_DISC:
-+ if (__test_pf(hdr->ctrl))
-+ rfcomm_recv_disc(s, dlci);
-+ break;
-+
-+ case RFCOMM_UA:
-+ if (__test_pf(hdr->ctrl))
-+ rfcomm_recv_ua(s, dlci);
-+ break;
-+
-+ case RFCOMM_DM:
-+ rfcomm_recv_dm(s, dlci);
-+ break;
-+
-+ case RFCOMM_UIH:
-+ if (dlci)
-+ return rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb);
-+
-+ rfcomm_recv_mcc(s, skb);
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown packet type 0x%02x\n", type);
-+ break;
-+ }
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+/* ---- Connection and data processing ---- */
-+
-+static void rfcomm_process_connect(struct rfcomm_session *s)
-+{
-+ struct rfcomm_dlc *d;
-+ struct list_head *p, *n;
-+
-+ BT_DBG("session %p state %ld", s, s->state);
-+
-+ list_for_each_safe(p, n, &s->dlcs) {
-+ d = list_entry(p, struct rfcomm_dlc, list);
-+ if (d->state == BT_CONFIG) {
-+ d->mtu = s->mtu;
-+ rfcomm_send_pn(s, 1, d);
-+ }
-+ }
-+}
-+
-+/* Send data queued for the DLC.
-+ * Return number of frames left in the queue.
-+ */
-+static inline int rfcomm_process_tx(struct rfcomm_dlc *d)
-+{
-+ struct sk_buff *skb;
-+ int err;
-+
-+ BT_DBG("dlc %p state %ld cfc %d rx_credits %d tx_credits %d",
-+ d, d->state, d->cfc, d->rx_credits, d->tx_credits);
-+
-+ /* Send pending MSC */
-+ if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags))
-+ rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
-+
-+ if (d->cfc) {
-+ /* CFC enabled.
-+ * Give them some credits */
-+ if (!test_bit(RFCOMM_RX_THROTTLED, &d->flags) &&
-+ d->rx_credits <= (d->cfc >> 2)) {
-+ rfcomm_send_credits(d->session, d->addr, d->cfc - d->rx_credits);
-+ d->rx_credits = d->cfc;
-+ }
-+ } else {
-+ /* CFC disabled.
-+ * Give ourselves some credits */
-+ d->tx_credits = 5;
-+ }
-+
-+ if (test_bit(RFCOMM_TX_THROTTLED, &d->flags))
-+ return skb_queue_len(&d->tx_queue);
-+
-+ while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) {
-+ err = rfcomm_send_frame(d->session, skb->data, skb->len);
-+ if (err < 0) {
-+ skb_queue_head(&d->tx_queue, skb);
-+ break;
-+ }
-+ kfree_skb(skb);
-+ d->tx_credits--;
-+ }
-+
-+ if (d->cfc && !d->tx_credits) {
-+ /* We're out of TX credits.
-+ * Set TX_THROTTLED flag to avoid unnesary wakeups by dlc_send. */
-+ set_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+ }
-+
-+ return skb_queue_len(&d->tx_queue);
-+}
-+
-+static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
-+{
-+ struct rfcomm_dlc *d;
-+ struct list_head *p, *n;
-+
-+ BT_DBG("session %p state %ld", s, s->state);
-+
-+ list_for_each_safe(p, n, &s->dlcs) {
-+ d = list_entry(p, struct rfcomm_dlc, list);
-+ if (test_bit(RFCOMM_TIMED_OUT, &d->flags)) {
-+ __rfcomm_dlc_close(d, ETIMEDOUT);
-+ continue;
-+ }
-+
-+ if (test_bit(RFCOMM_TX_THROTTLED, &s->flags))
-+ continue;
-+
-+ if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) &&
-+ d->mscex == RFCOMM_MSCEX_OK)
-+ rfcomm_process_tx(d);
-+ }
-+}
-+
-+static inline void rfcomm_process_rx(struct rfcomm_session *s)
-+{
-+ struct socket *sock = s->sock;
-+ struct sock *sk = sock->sk;
-+ struct sk_buff *skb;
-+
-+ BT_DBG("session %p state %ld qlen %d", s, s->state, skb_queue_len(&sk->receive_queue));
-+
-+ /* Get data directly from socket receive queue without copying it. */
-+ while ((skb = skb_dequeue(&sk->receive_queue))) {
-+ skb_orphan(skb);
-+ rfcomm_recv_frame(s, skb);
-+ }
-+
-+ if (sk->state == BT_CLOSED) {
-+ if (!s->initiator)
-+ rfcomm_session_put(s);
-+
-+ rfcomm_session_close(s, sk->err);
-+ }
-+}
-+
-+static inline void rfcomm_accept_connection(struct rfcomm_session *s)
-+{
-+ struct socket *sock = s->sock, *nsock;
-+ int err;
-+
-+ /* Fast check for a new connection.
-+ * Avoids unnesesary socket allocations. */
-+ if (list_empty(&bluez_pi(sock->sk)->accept_q))
-+ return;
-+
-+ BT_DBG("session %p", s);
-+
-+ nsock = sock_alloc();
-+ if (!nsock)
-+ return;
-+
-+ nsock->type = sock->type;
-+ nsock->ops = sock->ops;
-+
-+ err = sock->ops->accept(sock, nsock, O_NONBLOCK);
-+ if (err < 0) {
-+ sock_release(nsock);
-+ return;
-+ }
-+
-+ /* Set our callbacks */
-+ nsock->sk->data_ready = rfcomm_l2data_ready;
-+ nsock->sk->state_change = rfcomm_l2state_change;
-+
-+ s = rfcomm_session_add(nsock, BT_OPEN);
-+ if (s)
-+ rfcomm_session_hold(s);
-+ else
-+ sock_release(nsock);
-+}
-+
-+static inline void rfcomm_check_connection(struct rfcomm_session *s)
-+{
-+ struct sock *sk = s->sock->sk;
-+
-+ BT_DBG("%p state %ld", s, s->state);
-+
-+ switch(sk->state) {
-+ case BT_CONNECTED:
-+ s->state = BT_CONNECT;
-+
-+ /* We can adjust MTU on outgoing sessions.
-+ * L2CAP MTU minus UIH header and FCS. */
-+ s->mtu = min(l2cap_pi(sk)->omtu, l2cap_pi(sk)->imtu) - 5;
-+
-+ rfcomm_send_sabm(s, 0);
-+ break;
-+
-+ case BT_CLOSED:
-+ s->state = BT_CLOSED;
-+ rfcomm_session_close(s, sk->err);
-+ break;
-+ }
-+}
-+
-+static inline void rfcomm_process_sessions(void)
-+{
-+ struct list_head *p, *n;
-+
-+ rfcomm_lock();
-+
-+ list_for_each_safe(p, n, &session_list) {
-+ struct rfcomm_session *s;
-+ s = list_entry(p, struct rfcomm_session, list);
-+
-+ if (s->state == BT_LISTEN) {
-+ rfcomm_accept_connection(s);
-+ continue;
-+ }
-+
-+ rfcomm_session_hold(s);
-+
-+ switch (s->state) {
-+ case BT_BOUND:
-+ rfcomm_check_connection(s);
-+ break;
-+
-+ default:
-+ rfcomm_process_rx(s);
-+ break;
-+ }
-+
-+ rfcomm_process_dlcs(s);
-+
-+ rfcomm_session_put(s);
-+ }
-+
-+ rfcomm_unlock();
-+}
-+
-+static void rfcomm_worker(void)
-+{
-+ BT_DBG("");
-+
-+ daemonize(); reparent_to_init();
-+ set_fs(KERNEL_DS);
-+
-+ while (!atomic_read(&terminate)) {
-+ BT_DBG("worker loop event 0x%lx", rfcomm_event);
-+
-+ if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
-+ /* No pending events. Let's sleep.
-+ * Incomming connections and data will wake us up. */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule();
-+ }
-+
-+ /* Process stuff */
-+ clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
-+ rfcomm_process_sessions();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ return;
-+}
-+
-+static int rfcomm_add_listener(bdaddr_t *ba)
-+{
-+ struct sockaddr_l2 addr;
-+ struct l2cap_options opts;
-+ struct socket *sock;
-+ struct rfcomm_session *s;
-+ int size, err = 0;
-+
-+ /* Create socket */
-+ err = rfcomm_l2sock_create(&sock);
-+ if (err < 0) {
-+ BT_ERR("Create socket failed %d", err);
-+ return err;
-+ }
-+
-+ /* Bind socket */
-+ bacpy(&addr.l2_bdaddr, ba);
-+ addr.l2_family = AF_BLUETOOTH;
-+ addr.l2_psm = htobs(RFCOMM_PSM);
-+ err = sock->ops->bind(sock, (struct sockaddr *) &addr, sizeof(addr));
-+ if (err < 0) {
-+ BT_ERR("Bind failed %d", err);
-+ goto failed;
-+ }
-+
-+ /* Set L2CAP options */
-+ size = sizeof(opts);
-+ sock->ops->getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, &size);
-+
-+ opts.imtu = RFCOMM_MAX_L2CAP_MTU;
-+ sock->ops->setsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, size);
-+
-+ /* Start listening on the socket */
-+ err = sock->ops->listen(sock, 10);
-+ if (err) {
-+ BT_ERR("Listen failed %d", err);
-+ goto failed;
-+ }
-+
-+ /* Add listening session */
-+ s = rfcomm_session_add(sock, BT_LISTEN);
-+ if (!s)
-+ goto failed;
-+
-+ rfcomm_session_hold(s);
-+ return 0;
-+failed:
-+ sock_release(sock);
-+ return err;
-+}
-+
-+static void rfcomm_kill_listener(void)
-+{
-+ struct rfcomm_session *s;
-+ struct list_head *p, *n;
-+
-+ BT_DBG("");
-+
-+ list_for_each_safe(p, n, &session_list) {
-+ s = list_entry(p, struct rfcomm_session, list);
-+ rfcomm_session_del(s);
-+ }
-+}
-+
-+static int rfcomm_run(void *unused)
-+{
-+ rfcomm_thread = current;
-+
-+ atomic_inc(&running);
-+
-+ daemonize(); reparent_to_init();
-+
-+ sigfillset(&current->blocked);
-+ set_fs(KERNEL_DS);
-+
-+ sprintf(current->comm, "krfcommd");
-+
-+ BT_DBG("");
-+
-+ rfcomm_add_listener(BDADDR_ANY);
-+
-+ rfcomm_worker();
-+
-+ rfcomm_kill_listener();
-+
-+ atomic_dec(&running);
-+ return 0;
-+}
-+
-+/* ---- Proc fs support ---- */
-+static int rfcomm_dlc_dump(char *buf)
-+{
-+ struct rfcomm_session *s;
-+ struct sock *sk;
-+ struct list_head *p, *pp;
-+ char *ptr = buf;
-+
-+ rfcomm_lock();
-+
-+ list_for_each(p, &session_list) {
-+ s = list_entry(p, struct rfcomm_session, list);
-+ sk = s->sock->sk;
-+
-+ list_for_each(pp, &s->dlcs) {
-+ struct rfcomm_dlc *d;
-+ d = list_entry(pp, struct rfcomm_dlc, list);
-+
-+ ptr += sprintf(ptr, "dlc %s %s %ld %d %d %d %d\n",
-+ batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
-+ d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
-+ }
-+ }
-+
-+ rfcomm_unlock();
-+
-+ return ptr - buf;
-+}
-+
-+extern int rfcomm_sock_dump(char *buf);
-+
-+static int rfcomm_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
-+{
-+ char *ptr = buf;
-+ int len;
-+
-+ BT_DBG("count %d, offset %ld", count, offset);
-+
-+ ptr += rfcomm_dlc_dump(ptr);
-+ ptr += rfcomm_sock_dump(ptr);
-+ len = ptr - buf;
-+
-+ if (len <= count + offset)
-+ *eof = 1;
-+
-+ *start = buf + offset;
-+ len -= offset;
-+
-+ if (len > count)
-+ len = count;
-+ if (len < 0)
-+ len = 0;
-+
-+ return len;
-+}
-+
-+/* ---- Initialization ---- */
-+int __init rfcomm_init(void)
-+{
-+ l2cap_load();
-+
-+ kernel_thread(rfcomm_run, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-+
-+ rfcomm_init_sockets();
-+
-+#ifdef CONFIG_BLUEZ_RFCOMM_TTY
-+ rfcomm_init_ttys();
-+#endif
-+
-+ create_proc_read_entry("bluetooth/rfcomm", 0, 0, rfcomm_read_proc, NULL);
-+
-+ BT_INFO("BlueZ RFCOMM ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>");
-+ BT_INFO("Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>");
-+ return 0;
-+}
-+
-+void rfcomm_cleanup(void)
-+{
-+ /* Terminate working thread.
-+ * ie. Set terminate flag and wake it up */
-+ atomic_inc(&terminate);
-+ rfcomm_schedule(RFCOMM_SCHED_STATE);
-+
-+ /* Wait until thread is running */
-+ while (atomic_read(&running))
-+ schedule();
-+
-+ remove_proc_entry("bluetooth/rfcomm", NULL);
-+
-+#ifdef CONFIG_BLUEZ_RFCOMM_TTY
-+ rfcomm_cleanup_ttys();
-+#endif
-+
-+ rfcomm_cleanup_sockets();
-+ return;
-+}
-+
-+module_init(rfcomm_init);
-+module_exit(rfcomm_cleanup);
-+
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ RFCOMM ver " VERSION);
-+MODULE_LICENSE("GPL");
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/rfcomm/crc.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,71 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * RFCOMM FCS calculation.
-+ *
-+ * $Id$
-+ */
-+
-+/* reversed, 8-bit, poly=0x07 */
-+unsigned char rfcomm_crc_table[256] = {
-+ 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
-+ 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
-+ 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
-+ 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
-+
-+ 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
-+ 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
-+ 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
-+ 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
-+
-+ 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
-+ 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
-+ 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
-+ 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
-+
-+ 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
-+ 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
-+ 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
-+ 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
-+
-+ 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
-+ 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
-+ 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
-+ 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
-+
-+ 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
-+ 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
-+ 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
-+ 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
-+
-+ 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
-+ 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
-+ 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
-+ 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
-+
-+ 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
-+ 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
-+ 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
-+ 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
-+};
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/rfcomm/Makefile 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,11 @@
-+#
-+# Makefile for the Linux Bluetooth RFCOMM layer
-+#
-+
-+O_TARGET := rfcomm.o
-+
-+obj-y := core.o sock.o crc.o
-+obj-$(CONFIG_BLUEZ_RFCOMM_TTY) += tty.o
-+obj-m += $(O_TARGET)
-+
-+include $(TOPDIR)/Rules.make
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/rfcomm/sock.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,847 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * RFCOMM sockets.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/socket.h>
-+#include <linux/skbuff.h>
-+#include <linux/list.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/rfcomm.h>
-+
-+#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+static struct proto_ops rfcomm_sock_ops;
-+
-+static struct bluez_sock_list rfcomm_sk_list = {
-+ lock: RW_LOCK_UNLOCKED
-+};
-+
-+static void rfcomm_sock_close(struct sock *sk);
-+static void rfcomm_sock_kill(struct sock *sk);
-+
-+/* ---- DLC callbacks ----
-+ *
-+ * called under rfcomm_dlc_lock()
-+ */
-+static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb)
-+{
-+ struct sock *sk = d->owner;
-+ if (!sk)
-+ return;
-+
-+ atomic_add(skb->len, &sk->rmem_alloc);
-+ skb_queue_tail(&sk->receive_queue, skb);
-+ sk->data_ready(sk, skb->len);
-+
-+ if (atomic_read(&sk->rmem_alloc) >= sk->rcvbuf)
-+ rfcomm_dlc_throttle(d);
-+}
-+
-+static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
-+{
-+ struct sock *sk = d->owner, *parent;
-+ if (!sk)
-+ return;
-+
-+ BT_DBG("dlc %p state %ld err %d", d, d->state, err);
-+
-+ bh_lock_sock(sk);
-+
-+ if (err)
-+ sk->err = err;
-+ sk->state = d->state;
-+
-+ parent = bluez_pi(sk)->parent;
-+ if (!parent) {
-+ if (d->state == BT_CONNECTED)
-+ rfcomm_session_getaddr(d->session, &bluez_pi(sk)->src, NULL);
-+ sk->state_change(sk);
-+ } else
-+ parent->data_ready(parent, 0);
-+
-+ bh_unlock_sock(sk);
-+}
-+
-+/* ---- Socket functions ---- */
-+static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
-+{
-+ struct sock *sk;
-+
-+ for (sk = rfcomm_sk_list.head; sk; sk = sk->next) {
-+ if (rfcomm_pi(sk)->channel == channel &&
-+ !bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+ }
-+
-+ return sk;
-+}
-+
-+/* Find socket with channel and source bdaddr.
-+ * Returns closest match.
-+ */
-+static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
-+{
-+ struct sock *sk, *sk1 = NULL;
-+
-+ for (sk = rfcomm_sk_list.head; sk; sk = sk->next) {
-+ if (state && sk->state != state)
-+ continue;
-+
-+ if (rfcomm_pi(sk)->channel == channel) {
-+ /* Exact match. */
-+ if (!bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+
-+ /* Closest match */
-+ if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
-+ sk1 = sk;
-+ }
-+ }
-+ return sk ? sk : sk1;
-+}
-+
-+/* Find socket with given address (channel, src).
-+ * Returns locked socket */
-+static inline struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
-+{
-+ struct sock *s;
-+ read_lock(&rfcomm_sk_list.lock);
-+ s = __rfcomm_get_sock_by_channel(state, channel, src);
-+ if (s) bh_lock_sock(s);
-+ read_unlock(&rfcomm_sk_list.lock);
-+ return s;
-+}
-+
-+static void rfcomm_sock_destruct(struct sock *sk)
-+{
-+ struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
-+
-+ BT_DBG("sk %p dlc %p", sk, d);
-+
-+ skb_queue_purge(&sk->receive_queue);
-+ skb_queue_purge(&sk->write_queue);
-+
-+ rfcomm_dlc_lock(d);
-+ rfcomm_pi(sk)->dlc = NULL;
-+
-+ /* Detach DLC if it's owned by this socket */
-+ if (d->owner == sk)
-+ d->owner = NULL;
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_dlc_put(d);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void rfcomm_sock_cleanup_listen(struct sock *parent)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("parent %p", parent);
-+
-+ /* Close not yet accepted dlcs */
-+ while ((sk = bluez_accept_dequeue(parent, NULL))) {
-+ rfcomm_sock_close(sk);
-+ rfcomm_sock_kill(sk);
-+ }
-+
-+ parent->state = BT_CLOSED;
-+ parent->zapped = 1;
-+}
-+
-+/* Kill socket (only if zapped and orphan)
-+ * Must be called on unlocked socket.
-+ */
-+static void rfcomm_sock_kill(struct sock *sk)
-+{
-+ if (!sk->zapped || sk->socket)
-+ return;
-+
-+ BT_DBG("sk %p state %d refcnt %d", sk, sk->state, atomic_read(&sk->refcnt));
-+
-+ /* Kill poor orphan */
-+ bluez_sock_unlink(&rfcomm_sk_list, sk);
-+ sk->dead = 1;
-+ sock_put(sk);
-+}
-+
-+static void __rfcomm_sock_close(struct sock *sk)
-+{
-+ struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
-+
-+ BT_DBG("sk %p state %d socket %p", sk, sk->state, sk->socket);
-+
-+ switch (sk->state) {
-+ case BT_LISTEN:
-+ rfcomm_sock_cleanup_listen(sk);
-+ break;
-+
-+ case BT_CONNECT:
-+ case BT_CONNECT2:
-+ case BT_CONFIG:
-+ case BT_CONNECTED:
-+ rfcomm_dlc_close(d, 0);
-+
-+ default:
-+ sk->zapped = 1;
-+ break;
-+ }
-+}
-+
-+/* Close socket.
-+ * Must be called on unlocked socket.
-+ */
-+static void rfcomm_sock_close(struct sock *sk)
-+{
-+ lock_sock(sk);
-+ __rfcomm_sock_close(sk);
-+ release_sock(sk);
-+}
-+
-+static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
-+{
-+ BT_DBG("sk %p", sk);
-+
-+ if (parent)
-+ sk->type = parent->type;
-+}
-+
-+static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, int prio)
-+{
-+ struct rfcomm_dlc *d;
-+ struct sock *sk;
-+
-+ sk = sk_alloc(PF_BLUETOOTH, prio, 1);
-+ if (!sk)
-+ return NULL;
-+
-+ d = rfcomm_dlc_alloc(prio);
-+ if (!d) {
-+ sk_free(sk);
-+ return NULL;
-+ }
-+ d->data_ready = rfcomm_sk_data_ready;
-+ d->state_change = rfcomm_sk_state_change;
-+
-+ rfcomm_pi(sk)->dlc = d;
-+ d->owner = sk;
-+
-+ bluez_sock_init(sock, sk);
-+
-+ sk->zapped = 0;
-+
-+ sk->destruct = rfcomm_sock_destruct;
-+ sk->sndtimeo = RFCOMM_CONN_TIMEOUT;
-+
-+ sk->sndbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
-+ sk->rcvbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
-+
-+ sk->protocol = proto;
-+ sk->state = BT_OPEN;
-+
-+ bluez_sock_link(&rfcomm_sk_list, sk);
-+
-+ BT_DBG("sk %p", sk);
-+
-+ MOD_INC_USE_COUNT;
-+ return sk;
-+}
-+
-+static int rfcomm_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ sock->state = SS_UNCONNECTED;
-+
-+ if (sock->type != SOCK_STREAM && sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &rfcomm_sock_ops;
-+
-+ if (!(sk = rfcomm_sock_alloc(sock, protocol, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ rfcomm_sock_init(sk, NULL);
-+ return 0;
-+}
-+
-+static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
-+{
-+ struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p %s", sk, batostr(&sa->rc_bdaddr));
-+
-+ if (!addr || addr->sa_family != AF_BLUETOOTH)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_OPEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ write_lock_bh(&rfcomm_sk_list.lock);
-+
-+ if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
-+ err = -EADDRINUSE;
-+ } else {
-+ /* Save source address */
-+ bacpy(&bluez_pi(sk)->src, &sa->rc_bdaddr);
-+ rfcomm_pi(sk)->channel = sa->rc_channel;
-+ sk->state = BT_BOUND;
-+ }
-+
-+ write_unlock_bh(&rfcomm_sk_list.lock);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
-+{
-+ struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
-+ struct sock *sk = sock->sk;
-+ struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
-+ int err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc))
-+ return -EINVAL;
-+
-+ if (sk->state != BT_OPEN && sk->state != BT_BOUND)
-+ return -EBADFD;
-+
-+ if (sk->type != SOCK_STREAM)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ sk->state = BT_CONNECT;
-+ bacpy(&bluez_pi(sk)->dst, &sa->rc_bdaddr);
-+ rfcomm_pi(sk)->channel = sa->rc_channel;
-+
-+ err = rfcomm_dlc_open(d, &bluez_pi(sk)->src, &sa->rc_bdaddr, sa->rc_channel);
-+ if (!err)
-+ err = bluez_sock_wait_state(sk, BT_CONNECTED,
-+ sock_sndtimeo(sk, flags & O_NONBLOCK));
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int rfcomm_sock_listen(struct socket *sock, int backlog)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p backlog %d", sk, backlog);
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_BOUND) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ sk->max_ack_backlog = backlog;
-+ sk->ack_backlog = 0;
-+ sk->state = BT_LISTEN;
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct sock *sk = sock->sk, *nsk;
-+ long timeo;
-+ int err = 0;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
-+
-+ BT_DBG("sk %p timeo %ld", sk, timeo);
-+
-+ /* Wait for an incoming connection. (wake-one). */
-+ add_wait_queue_exclusive(sk->sleep, &wait);
-+ while (!(nsk = bluez_accept_dequeue(sk, newsock))) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ break;
-+ }
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ break;
-+ }
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ if (err)
-+ goto done;
-+
-+ newsock->state = SS_CONNECTED;
-+
-+ BT_DBG("new socket %p", nsk);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
-+{
-+ struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ sa->rc_family = AF_BLUETOOTH;
-+ sa->rc_channel = rfcomm_pi(sk)->channel;
-+ if (peer)
-+ bacpy(&sa->rc_bdaddr, &bluez_pi(sk)->dst);
-+ else
-+ bacpy(&sa->rc_bdaddr, &bluez_pi(sk)->src);
-+
-+ *len = sizeof(struct sockaddr_rc);
-+ return 0;
-+}
-+
-+static int rfcomm_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
-+ struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
-+ struct sk_buff *skb;
-+ int err, size;
-+ int sent = 0;
-+
-+ if (msg->msg_flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ if (sk->shutdown & SEND_SHUTDOWN)
-+ return -EPIPE;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ lock_sock(sk);
-+
-+ while (len) {
-+ size = min_t(uint, len, d->mtu);
-+
-+ skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE,
-+ msg->msg_flags & MSG_DONTWAIT, &err);
-+ if (!skb)
-+ break;
-+ skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
-+
-+ err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
-+ if (err) {
-+ kfree_skb(skb);
-+ sent = err;
-+ break;
-+ }
-+
-+ err = rfcomm_dlc_send(d, skb);
-+ if (err < 0) {
-+ kfree_skb(skb);
-+ break;
-+ }
-+
-+ sent += size;
-+ len -= size;
-+ }
-+
-+ release_sock(sk);
-+
-+ return sent ? sent : err;
-+}
-+
-+static long rfcomm_sock_data_wait(struct sock *sk, long timeo)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+ add_wait_queue(sk->sleep, &wait);
-+ for (;;) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (skb_queue_len(&sk->receive_queue) || sk->err || (sk->shutdown & RCV_SHUTDOWN) ||
-+ signal_pending(current) || !timeo)
-+ break;
-+
-+ set_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+ clear_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
-+ }
-+
-+ __set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+ return timeo;
-+}
-+
-+static int rfcomm_sock_recvmsg(struct socket *sock, struct msghdr *msg, int size,
-+ int flags, struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ int target, err = 0, copied = 0;
-+ long timeo;
-+
-+ if (flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ msg->msg_namelen = 0;
-+
-+ BT_DBG("sk %p size %d", sk, size);
-+
-+ lock_sock(sk);
-+
-+ target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
-+ timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
-+
-+ do {
-+ struct sk_buff *skb;
-+ int chunk;
-+
-+ skb = skb_dequeue(&sk->receive_queue);
-+ if (!skb) {
-+ if (copied >= target)
-+ break;
-+
-+ if ((err = sock_error(sk)) != 0)
-+ break;
-+ if (sk->shutdown & RCV_SHUTDOWN)
-+ break;
-+
-+ err = -EAGAIN;
-+ if (!timeo)
-+ break;
-+
-+ timeo = rfcomm_sock_data_wait(sk, timeo);
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ goto out;
-+ }
-+ continue;
-+ }
-+
-+ chunk = min_t(unsigned int, skb->len, size);
-+ if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
-+ skb_queue_head(&sk->receive_queue, skb);
-+ if (!copied)
-+ copied = -EFAULT;
-+ break;
-+ }
-+ copied += chunk;
-+ size -= chunk;
-+
-+ if (!(flags & MSG_PEEK)) {
-+ atomic_sub(chunk, &sk->rmem_alloc);
-+
-+ skb_pull(skb, chunk);
-+ if (skb->len) {
-+ skb_queue_head(&sk->receive_queue, skb);
-+ break;
-+ }
-+ kfree_skb(skb);
-+
-+ } else {
-+ /* put message back and return */
-+ skb_queue_head(&sk->receive_queue, skb);
-+ break;
-+ }
-+ } while (size);
-+
-+out:
-+ if (atomic_read(&sk->rmem_alloc) <= (sk->rcvbuf >> 2))
-+ rfcomm_dlc_unthrottle(rfcomm_pi(sk)->dlc);
-+
-+ release_sock(sk);
-+ return copied ? : err;
-+}
-+
-+static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ int len, err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (get_user(len, optlen))
-+ return -EFAULT;
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct sock *sk = sock->sk;
-+ int err;
-+
-+ lock_sock(sk);
-+
-+#ifdef CONFIG_BLUEZ_RFCOMM_TTY
-+ err = rfcomm_dev_ioctl(sk, cmd, arg);
-+#else
-+ err = -EOPNOTSUPP;
-+#endif
-+
-+ release_sock(sk);
-+
-+ return err;
-+}
-+
-+static int rfcomm_sock_shutdown(struct socket *sock, int how)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk) return 0;
-+
-+ lock_sock(sk);
-+ if (!sk->shutdown) {
-+ sk->shutdown = SHUTDOWN_MASK;
-+ __rfcomm_sock_close(sk);
-+
-+ if (sk->linger)
-+ err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
-+ }
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ err = rfcomm_sock_shutdown(sock, 2);
-+
-+ sock_orphan(sk);
-+ rfcomm_sock_kill(sk);
-+ return err;
-+}
-+
-+/* ---- RFCOMM core layer callbacks ----
-+ *
-+ * called under rfcomm_lock()
-+ */
-+int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d)
-+{
-+ struct sock *sk, *parent;
-+ bdaddr_t src, dst;
-+ int result = 0;
-+
-+ BT_DBG("session %p channel %d", s, channel);
-+
-+ rfcomm_session_getaddr(s, &src, &dst);
-+
-+ /* Check if we have socket listening on this channel */
-+ parent = rfcomm_get_sock_by_channel(BT_LISTEN, channel, &src);
-+ if (!parent)
-+ return 0;
-+
-+ /* Check for backlog size */
-+ if (parent->ack_backlog > parent->max_ack_backlog) {
-+ BT_DBG("backlog full %d", parent->ack_backlog);
-+ goto done;
-+ }
-+
-+ sk = rfcomm_sock_alloc(NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
-+ if (!sk)
-+ goto done;
-+
-+ rfcomm_sock_init(sk, parent);
-+ bacpy(&bluez_pi(sk)->src, &src);
-+ bacpy(&bluez_pi(sk)->dst, &dst);
-+ rfcomm_pi(sk)->channel = channel;
-+
-+ sk->state = BT_CONFIG;
-+ bluez_accept_enqueue(parent, sk);
-+
-+ /* Accept connection and return socket DLC */
-+ *d = rfcomm_pi(sk)->dlc;
-+ result = 1;
-+
-+done:
-+ bh_unlock_sock(parent);
-+ return result;
-+}
-+
-+/* ---- Proc fs support ---- */
-+int rfcomm_sock_dump(char *buf)
-+{
-+ struct bluez_sock_list *list = &rfcomm_sk_list;
-+ struct rfcomm_pinfo *pi;
-+ struct sock *sk;
-+ char *ptr = buf;
-+
-+ write_lock_bh(&list->lock);
-+
-+ for (sk = list->head; sk; sk = sk->next) {
-+ pi = rfcomm_pi(sk);
-+ ptr += sprintf(ptr, "sk %s %s %d %d\n",
-+ batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
-+ sk->state, rfcomm_pi(sk)->channel);
-+ }
-+
-+ write_unlock_bh(&list->lock);
-+
-+ return ptr - buf;
-+}
-+
-+static struct proto_ops rfcomm_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: rfcomm_sock_release,
-+ bind: rfcomm_sock_bind,
-+ connect: rfcomm_sock_connect,
-+ listen: rfcomm_sock_listen,
-+ accept: rfcomm_sock_accept,
-+ getname: rfcomm_sock_getname,
-+ sendmsg: rfcomm_sock_sendmsg,
-+ recvmsg: rfcomm_sock_recvmsg,
-+ shutdown: rfcomm_sock_shutdown,
-+ setsockopt: rfcomm_sock_setsockopt,
-+ getsockopt: rfcomm_sock_getsockopt,
-+ ioctl: rfcomm_sock_ioctl,
-+ poll: bluez_sock_poll,
-+ socketpair: sock_no_socketpair,
-+ mmap: sock_no_mmap
-+};
-+
-+static struct net_proto_family rfcomm_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: rfcomm_sock_create
-+};
-+
-+int rfcomm_init_sockets(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_RFCOMM, &rfcomm_sock_family_ops))) {
-+ BT_ERR("Can't register RFCOMM socket layer");
-+ return err;
-+ }
-+
-+ return 0;
-+}
-+
-+void rfcomm_cleanup_sockets(void)
-+{
-+ int err;
-+
-+ /* Unregister socket, protocol and notifier */
-+ if ((err = bluez_sock_unregister(BTPROTO_RFCOMM)))
-+ BT_ERR("Can't unregister RFCOMM socket layer %d", err);
-+}
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/rfcomm/tty.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,945 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * RFCOMM TTY.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/tty.h>
-+#include <linux/tty_driver.h>
-+#include <linux/tty_flip.h>
-+
-+#include <linux/slab.h>
-+#include <linux/skbuff.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/rfcomm.h>
-+
-+#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define RFCOMM_TTY_MAGIC 0x6d02 /* magic number for rfcomm struct */
-+#define RFCOMM_TTY_PORTS RFCOMM_MAX_DEV /* whole lotta rfcomm devices */
-+#define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */
-+#define RFCOMM_TTY_MINOR 0
-+
-+struct rfcomm_dev {
-+ struct list_head list;
-+ atomic_t refcnt;
-+
-+ char name[12];
-+ int id;
-+ unsigned long flags;
-+ int opened;
-+ int err;
-+
-+ bdaddr_t src;
-+ bdaddr_t dst;
-+ u8 channel;
-+
-+ uint modem_status;
-+
-+ struct rfcomm_dlc *dlc;
-+ struct tty_struct *tty;
-+ wait_queue_head_t wait;
-+ struct tasklet_struct wakeup_task;
-+
-+ atomic_t wmem_alloc;
-+};
-+
-+static LIST_HEAD(rfcomm_dev_list);
-+static rwlock_t rfcomm_dev_lock = RW_LOCK_UNLOCKED;
-+
-+static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
-+static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
-+static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
-+
-+static void rfcomm_tty_wakeup(unsigned long arg);
-+
-+/* ---- Device functions ---- */
-+static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
-+{
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+
-+ BT_DBG("dev %p dlc %p", dev, dlc);
-+
-+ rfcomm_dlc_lock(dlc);
-+ /* Detach DLC if it's owned by this dev */
-+ if (dlc->owner == dev)
-+ dlc->owner = NULL;
-+ rfcomm_dlc_unlock(dlc);
-+
-+ rfcomm_dlc_put(dlc);
-+ kfree(dev);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static inline void rfcomm_dev_hold(struct rfcomm_dev *dev)
-+{
-+ atomic_inc(&dev->refcnt);
-+}
-+
-+static inline void rfcomm_dev_put(struct rfcomm_dev *dev)
-+{
-+ if (atomic_dec_and_test(&dev->refcnt))
-+ rfcomm_dev_destruct(dev);
-+}
-+
-+static struct rfcomm_dev *__rfcomm_dev_get(int id)
-+{
-+ struct rfcomm_dev *dev;
-+ struct list_head *p;
-+
-+ list_for_each(p, &rfcomm_dev_list) {
-+ dev = list_entry(p, struct rfcomm_dev, list);
-+ if (dev->id == id)
-+ return dev;
-+ }
-+
-+ return NULL;
-+}
-+
-+static inline struct rfcomm_dev *rfcomm_dev_get(int id)
-+{
-+ struct rfcomm_dev *dev;
-+
-+ read_lock(&rfcomm_dev_lock);
-+ dev = __rfcomm_dev_get(id);
-+ read_unlock(&rfcomm_dev_lock);
-+
-+ if (dev) rfcomm_dev_hold(dev);
-+ return dev;
-+}
-+
-+static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
-+{
-+ struct rfcomm_dev *dev;
-+ struct list_head *head = &rfcomm_dev_list, *p;
-+ int err = 0;
-+
-+ BT_DBG("id %d channel %d", req->dev_id, req->channel);
-+
-+ dev = kmalloc(sizeof(struct rfcomm_dev), GFP_KERNEL);
-+ if (!dev)
-+ return -ENOMEM;
-+ memset(dev, 0, sizeof(struct rfcomm_dev));
-+
-+ write_lock_bh(&rfcomm_dev_lock);
-+
-+ if (req->dev_id < 0) {
-+ dev->id = 0;
-+
-+ list_for_each(p, &rfcomm_dev_list) {
-+ if (list_entry(p, struct rfcomm_dev, list)->id != dev->id)
-+ break;
-+
-+ dev->id++;
-+ head = p;
-+ }
-+ } else {
-+ dev->id = req->dev_id;
-+
-+ list_for_each(p, &rfcomm_dev_list) {
-+ struct rfcomm_dev *entry = list_entry(p, struct rfcomm_dev, list);
-+
-+ if (entry->id == dev->id) {
-+ err = -EADDRINUSE;
-+ goto out;
-+ }
-+
-+ if (entry->id > dev->id - 1)
-+ break;
-+
-+ head = p;
-+ }
-+ }
-+
-+ if ((dev->id < 0) || (dev->id > RFCOMM_MAX_DEV - 1)) {
-+ err = -ENFILE;
-+ goto out;
-+ }
-+
-+ sprintf(dev->name, "rfcomm%d", dev->id);
-+
-+ list_add(&dev->list, head);
-+ atomic_set(&dev->refcnt, 1);
-+
-+ bacpy(&dev->src, &req->src);
-+ bacpy(&dev->dst, &req->dst);
-+ dev->channel = req->channel;
-+
-+ dev->flags = req->flags &
-+ ((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
-+
-+ init_waitqueue_head(&dev->wait);
-+ tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev);
-+
-+ rfcomm_dlc_lock(dlc);
-+ dlc->data_ready = rfcomm_dev_data_ready;
-+ dlc->state_change = rfcomm_dev_state_change;
-+ dlc->modem_status = rfcomm_dev_modem_status;
-+
-+ dlc->owner = dev;
-+ dev->dlc = dlc;
-+ rfcomm_dlc_unlock(dlc);
-+
-+ MOD_INC_USE_COUNT;
-+
-+out:
-+ write_unlock_bh(&rfcomm_dev_lock);
-+
-+ if (err) {
-+ kfree(dev);
-+ return err;
-+ } else
-+ return dev->id;
-+}
-+
-+static void rfcomm_dev_del(struct rfcomm_dev *dev)
-+{
-+ BT_DBG("dev %p", dev);
-+
-+ write_lock_bh(&rfcomm_dev_lock);
-+ list_del_init(&dev->list);
-+ write_unlock_bh(&rfcomm_dev_lock);
-+
-+ rfcomm_dev_put(dev);
-+}
-+
-+/* ---- Send buffer ---- */
-+
-+static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc)
-+{
-+ /* We can't let it be zero, because we don't get a callback
-+ when tx_credits becomes nonzero, hence we'd never wake up */
-+ return dlc->mtu * (dlc->tx_credits?:1);
-+}
-+
-+static void rfcomm_wfree(struct sk_buff *skb)
-+{
-+ struct rfcomm_dev *dev = (void *) skb->sk;
-+ atomic_sub(skb->truesize, &dev->wmem_alloc);
-+ if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags))
-+ tasklet_schedule(&dev->wakeup_task);
-+ rfcomm_dev_put(dev);
-+}
-+
-+static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
-+{
-+ rfcomm_dev_hold(dev);
-+ atomic_add(skb->truesize, &dev->wmem_alloc);
-+ skb->sk = (void *) dev;
-+ skb->destructor = rfcomm_wfree;
-+}
-+
-+static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, int force, int priority)
-+{
-+ if (force || atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) {
-+ struct sk_buff *skb = alloc_skb(size, priority);
-+ if (skb) {
-+ rfcomm_set_owner_w(skb, dev);
-+ return skb;
-+ }
-+ }
-+ return NULL;
-+}
-+
-+/* ---- Device IOCTLs ---- */
-+
-+#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
-+
-+static int rfcomm_create_dev(struct sock *sk, unsigned long arg)
-+{
-+ struct rfcomm_dev_req req;
-+ struct rfcomm_dlc *dlc;
-+ int id;
-+
-+ if (copy_from_user(&req, (void *) arg, sizeof(req)))
-+ return -EFAULT;
-+
-+ BT_DBG("sk %p dev_id %id flags 0x%x", sk, req.dev_id, req.flags);
-+
-+ if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
-+ return -EPERM;
-+
-+ if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
-+ /* Socket must be connected */
-+ if (sk->state != BT_CONNECTED)
-+ return -EBADFD;
-+
-+ dlc = rfcomm_pi(sk)->dlc;
-+ rfcomm_dlc_hold(dlc);
-+ } else {
-+ dlc = rfcomm_dlc_alloc(GFP_KERNEL);
-+ if (!dlc)
-+ return -ENOMEM;
-+ }
-+
-+ id = rfcomm_dev_add(&req, dlc);
-+ if (id < 0) {
-+ rfcomm_dlc_put(dlc);
-+ return id;
-+ }
-+
-+ if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
-+ /* DLC is now used by device.
-+ * Socket must be disconnected */
-+ sk->state = BT_CLOSED;
-+ }
-+
-+ return id;
-+}
-+
-+static int rfcomm_release_dev(unsigned long arg)
-+{
-+ struct rfcomm_dev_req req;
-+ struct rfcomm_dev *dev;
-+
-+ if (copy_from_user(&req, (void *) arg, sizeof(req)))
-+ return -EFAULT;
-+
-+ BT_DBG("dev_id %id flags 0x%x", req.dev_id, req.flags);
-+
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EPERM;
-+
-+ if (!(dev = rfcomm_dev_get(req.dev_id)))
-+ return -ENODEV;
-+
-+ if (req.flags & (1 << RFCOMM_HANGUP_NOW))
-+ rfcomm_dlc_close(dev->dlc, 0);
-+
-+ rfcomm_dev_del(dev);
-+ rfcomm_dev_put(dev);
-+ return 0;
-+}
-+
-+static int rfcomm_get_dev_list(unsigned long arg)
-+{
-+ struct rfcomm_dev_list_req *dl;
-+ struct rfcomm_dev_info *di;
-+ struct list_head *p;
-+ int n = 0, size;
-+ u16 dev_num;
-+
-+ BT_DBG("");
-+
-+ if (get_user(dev_num, (u16 *) arg))
-+ return -EFAULT;
-+
-+ if (!dev_num)
-+ return -EINVAL;
-+
-+ size = sizeof(*dl) + dev_num * sizeof(*di);
-+
-+ if (verify_area(VERIFY_WRITE, (void *)arg, size))
-+ return -EFAULT;
-+
-+ if (!(dl = kmalloc(size, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ di = dl->dev_info;
-+
-+ read_lock_bh(&rfcomm_dev_lock);
-+
-+ list_for_each(p, &rfcomm_dev_list) {
-+ struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list);
-+ (di + n)->id = dev->id;
-+ (di + n)->flags = dev->flags;
-+ (di + n)->state = dev->dlc->state;
-+ (di + n)->channel = dev->channel;
-+ bacpy(&(di + n)->src, &dev->src);
-+ bacpy(&(di + n)->dst, &dev->dst);
-+ if (++n >= dev_num)
-+ break;
-+ }
-+
-+ read_unlock_bh(&rfcomm_dev_lock);
-+
-+ dl->dev_num = n;
-+ size = sizeof(*dl) + n * sizeof(*di);
-+
-+ copy_to_user((void *) arg, dl, size);
-+ kfree(dl);
-+ return 0;
-+}
-+
-+static int rfcomm_get_dev_info(unsigned long arg)
-+{
-+ struct rfcomm_dev *dev;
-+ struct rfcomm_dev_info di;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ if (copy_from_user(&di, (void *)arg, sizeof(di)))
-+ return -EFAULT;
-+
-+ if (!(dev = rfcomm_dev_get(di.id)))
-+ return -ENODEV;
-+
-+ di.flags = dev->flags;
-+ di.channel = dev->channel;
-+ di.state = dev->dlc->state;
-+ bacpy(&di.src, &dev->src);
-+ bacpy(&di.dst, &dev->dst);
-+
-+ if (copy_to_user((void *)arg, &di, sizeof(di)))
-+ err = -EFAULT;
-+
-+ rfcomm_dev_put(dev);
-+ return err;
-+}
-+
-+int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
-+{
-+ BT_DBG("cmd %d arg %ld", cmd, arg);
-+
-+ switch (cmd) {
-+ case RFCOMMCREATEDEV:
-+ return rfcomm_create_dev(sk, arg);
-+
-+ case RFCOMMRELEASEDEV:
-+ return rfcomm_release_dev(arg);
-+
-+ case RFCOMMGETDEVLIST:
-+ return rfcomm_get_dev_list(arg);
-+
-+ case RFCOMMGETDEVINFO:
-+ return rfcomm_get_dev_info(arg);
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+/* ---- DLC callbacks ---- */
-+static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
-+{
-+ struct rfcomm_dev *dev = dlc->owner;
-+ struct tty_struct *tty;
-+
-+ if (!dev || !(tty = dev->tty)) {
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len);
-+
-+ if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
-+ register int i;
-+ for (i = 0; i < skb->len; i++) {
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+ tty_flip_buffer_push(tty);
-+
-+ tty_insert_flip_char(tty, skb->data[i], 0);
-+ }
-+ tty_flip_buffer_push(tty);
-+ } else
-+ tty->ldisc.receive_buf(tty, skb->data, NULL, skb->len);
-+
-+ kfree_skb(skb);
-+}
-+
-+static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
-+{
-+ struct rfcomm_dev *dev = dlc->owner;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("dlc %p dev %p err %d", dlc, dev, err);
-+
-+ dev->err = err;
-+ wake_up_interruptible(&dev->wait);
-+
-+ if (dlc->state == BT_CLOSED) {
-+ if (!dev->tty) {
-+ if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
-+ rfcomm_dev_hold(dev);
-+ rfcomm_dev_del(dev);
-+
-+ /* We have to drop DLC lock here, otherwise
-+ * rfcomm_dev_put() will dead lock if it's the last refference */
-+ rfcomm_dlc_unlock(dlc);
-+ rfcomm_dev_put(dev);
-+ rfcomm_dlc_lock(dlc);
-+ }
-+ } else
-+ tty_hangup(dev->tty);
-+ }
-+}
-+
-+static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
-+{
-+ struct rfcomm_dev *dev = dlc->owner;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig);
-+
-+ dev->modem_status =
-+ ((v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0) |
-+ ((v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0) |
-+ ((v24_sig & RFCOMM_V24_IC) ? TIOCM_RI : 0) |
-+ ((v24_sig & RFCOMM_V24_DV) ? TIOCM_CD : 0);
-+}
-+
-+/* ---- TTY functions ---- */
-+static void rfcomm_tty_wakeup(unsigned long arg)
-+{
-+ struct rfcomm_dev *dev = (void *) arg;
-+ struct tty_struct *tty = dev->tty;
-+ if (!tty)
-+ return;
-+
-+ BT_DBG("dev %p tty %p", dev, tty);
-+
-+ if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
-+ (tty->ldisc.write_wakeup)(tty);
-+
-+ wake_up_interruptible(&tty->write_wait);
-+#ifdef SERIAL_HAVE_POLL_WAIT
-+ wake_up_interruptible(&tty->poll_wait);
-+#endif
-+}
-+
-+static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct rfcomm_dev *dev;
-+ struct rfcomm_dlc *dlc;
-+ int err, id;
-+
-+ id = MINOR(tty->device) - tty->driver.minor_start;
-+
-+ BT_DBG("tty %p id %d", tty, id);
-+
-+ dev = rfcomm_dev_get(id);
-+ if (!dev)
-+ return -ENODEV;
-+
-+ BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst), dev->channel, dev->opened);
-+
-+ if (dev->opened++ != 0)
-+ return 0;
-+
-+ dlc = dev->dlc;
-+
-+ /* Attach TTY and open DLC */
-+
-+ rfcomm_dlc_lock(dlc);
-+ tty->driver_data = dev;
-+ dev->tty = tty;
-+ rfcomm_dlc_unlock(dlc);
-+ set_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
-+
-+ err = rfcomm_dlc_open(dlc, &dev->src, &dev->dst, dev->channel);
-+ if (err < 0)
-+ return err;
-+
-+ /* Wait for DLC to connect */
-+ add_wait_queue(&dev->wait, &wait);
-+ while (1) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (dlc->state == BT_CLOSED) {
-+ err = -dev->err;
-+ break;
-+ }
-+
-+ if (dlc->state == BT_CONNECTED)
-+ break;
-+
-+ if (signal_pending(current)) {
-+ err = -EINTR;
-+ break;
-+ }
-+
-+ schedule();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&dev->wait, &wait);
-+
-+ return err;
-+}
-+
-+static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, dev->opened);
-+
-+ if (--dev->opened == 0) {
-+ /* Close DLC and dettach TTY */
-+ rfcomm_dlc_close(dev->dlc, 0);
-+
-+ clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
-+ tasklet_kill(&dev->wakeup_task);
-+
-+ rfcomm_dlc_lock(dev->dlc);
-+ tty->driver_data = NULL;
-+ dev->tty = NULL;
-+ rfcomm_dlc_unlock(dev->dlc);
-+ }
-+
-+ rfcomm_dev_put(dev);
-+}
-+
-+static int rfcomm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+ struct sk_buff *skb;
-+ int err = 0, sent = 0, size;
-+
-+ BT_DBG("tty %p from_user %d count %d", tty, from_user, count);
-+
-+ while (count) {
-+ size = min_t(uint, count, dlc->mtu);
-+
-+ if (from_user)
-+ skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, 0, GFP_KERNEL);
-+ else
-+ skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, 0, GFP_ATOMIC);
-+
-+ if (!skb)
-+ break;
-+
-+ skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
-+
-+ if (from_user)
-+ copy_from_user(skb_put(skb, size), buf + sent, size);
-+ else
-+ memcpy(skb_put(skb, size), buf + sent, size);
-+
-+ if ((err = rfcomm_dlc_send(dlc, skb)) < 0) {
-+ kfree_skb(skb);
-+ break;
-+ }
-+
-+ sent += size;
-+ count -= size;
-+ }
-+
-+ return sent ? sent : err;
-+}
-+
-+static void rfcomm_tty_put_char(struct tty_struct *tty, unsigned char ch)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+ struct sk_buff *skb;
-+
-+ BT_DBG("tty %p char %x", tty, ch);
-+
-+ skb = rfcomm_wmalloc(dev, 1 + RFCOMM_SKB_RESERVE, 1, GFP_ATOMIC);
-+
-+ if (!skb)
-+ return;
-+
-+ skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
-+
-+ *(char *)skb_put(skb, 1) = ch;
-+
-+ if ((rfcomm_dlc_send(dlc, skb)) < 0)
-+ kfree_skb(skb);
-+}
-+
-+static int rfcomm_tty_write_room(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ int room;
-+
-+ BT_DBG("tty %p", tty);
-+
-+ room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc);
-+ if (room < 0)
-+ room = 0;
-+
-+ return room;
-+}
-+
-+static int rfcomm_tty_set_modem_status(uint cmd, struct rfcomm_dlc *dlc, uint status)
-+{
-+ u8 v24_sig, mask;
-+
-+ BT_DBG("dlc %p cmd 0x%02x", dlc, cmd);
-+
-+ if (cmd == TIOCMSET)
-+ v24_sig = 0;
-+ else
-+ rfcomm_dlc_get_modem_status(dlc, &v24_sig);
-+
-+ mask = ((status & TIOCM_DSR) ? RFCOMM_V24_RTC : 0) |
-+ ((status & TIOCM_DTR) ? RFCOMM_V24_RTC : 0) |
-+ ((status & TIOCM_RTS) ? RFCOMM_V24_RTR : 0) |
-+ ((status & TIOCM_CTS) ? RFCOMM_V24_RTR : 0) |
-+ ((status & TIOCM_RI) ? RFCOMM_V24_IC : 0) |
-+ ((status & TIOCM_CD) ? RFCOMM_V24_DV : 0);
-+
-+ if (cmd == TIOCMBIC)
-+ v24_sig &= ~mask;
-+ else
-+ v24_sig |= mask;
-+
-+ rfcomm_dlc_set_modem_status(dlc, v24_sig);
-+ return 0;
-+}
-+
-+static int rfcomm_tty_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+ uint status;
-+ int err;
-+
-+ BT_DBG("tty %p cmd 0x%02x", tty, cmd);
-+
-+ switch (cmd) {
-+ case TCGETS:
-+ BT_DBG("TCGETS is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TCSETS:
-+ BT_DBG("TCSETS is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCMGET:
-+ BT_DBG("TIOCMGET");
-+
-+ return put_user(dev->modem_status, (unsigned int *)arg);
-+
-+ case TIOCMSET: /* Turns on and off the lines as specified by the mask */
-+ case TIOCMBIS: /* Turns on the lines as specified by the mask */
-+ case TIOCMBIC: /* Turns off the lines as specified by the mask */
-+ if ((err = get_user(status, (unsigned int *)arg)))
-+ return err;
-+ return rfcomm_tty_set_modem_status(cmd, dlc, status);
-+
-+ case TIOCMIWAIT:
-+ BT_DBG("TIOCMIWAIT");
-+ break;
-+
-+ case TIOCGICOUNT:
-+ BT_DBG("TIOCGICOUNT");
-+ break;
-+
-+ case TIOCGSERIAL:
-+ BT_ERR("TIOCGSERIAL is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCSSERIAL:
-+ BT_ERR("TIOCSSERIAL is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCSERGSTRUCT:
-+ BT_ERR("TIOCSERGSTRUCT is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCSERGETLSR:
-+ BT_ERR("TIOCSERGETLSR is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCSERCONFIG:
-+ BT_ERR("TIOCSERCONFIG is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ default:
-+ return -ENOIOCTLCMD; /* ioctls which we must ignore */
-+
-+ }
-+
-+ return -ENOIOCTLCMD;
-+}
-+
-+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-+
-+static void rfcomm_tty_set_termios(struct tty_struct *tty, struct termios *old)
-+{
-+ BT_DBG("tty %p", tty);
-+
-+ if ((tty->termios->c_cflag == old->c_cflag) &&
-+ (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old->c_iflag)))
-+ return;
-+
-+ /* handle turning off CRTSCTS */
-+ if ((old->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) {
-+ BT_DBG("turning off CRTSCTS");
-+ }
-+}
-+
-+static void rfcomm_tty_throttle(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ rfcomm_dlc_throttle(dev->dlc);
-+}
-+
-+static void rfcomm_tty_unthrottle(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ rfcomm_dlc_unthrottle(dev->dlc);
-+}
-+
-+static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ if (skb_queue_len(&dlc->tx_queue))
-+ return dlc->mtu;
-+
-+ return 0;
-+}
-+
-+static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ skb_queue_purge(&dev->dlc->tx_queue);
-+
-+ if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
-+ tty->ldisc.write_wakeup(tty);
-+}
-+
-+static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
-+{
-+ BT_DBG("tty %p ch %c", tty, ch);
-+}
-+
-+static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
-+{
-+ BT_DBG("tty %p timeout %d", tty, timeout);
-+}
-+
-+static void rfcomm_tty_hangup(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ rfcomm_tty_flush_buffer(tty);
-+
-+ if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
-+ rfcomm_dev_del(dev);
-+}
-+
-+static int rfcomm_tty_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *unused)
-+{
-+ return 0;
-+}
-+
-+/* ---- TTY structure ---- */
-+static int rfcomm_tty_refcount; /* If we manage several devices */
-+
-+static struct tty_struct *rfcomm_tty_table[RFCOMM_TTY_PORTS];
-+static struct termios *rfcomm_tty_termios[RFCOMM_TTY_PORTS];
-+static struct termios *rfcomm_tty_termios_locked[RFCOMM_TTY_PORTS];
-+
-+static struct tty_driver rfcomm_tty_driver = {
-+ magic: TTY_DRIVER_MAGIC,
-+ driver_name: "rfcomm",
-+#ifdef CONFIG_DEVFS_FS
-+ name: "bluetooth/rfcomm/%d",
-+#else
-+ name: "rfcomm",
-+#endif
-+ major: RFCOMM_TTY_MAJOR,
-+ minor_start: RFCOMM_TTY_MINOR,
-+ num: RFCOMM_TTY_PORTS,
-+ type: TTY_DRIVER_TYPE_SERIAL,
-+ subtype: SERIAL_TYPE_NORMAL,
-+ flags: TTY_DRIVER_REAL_RAW,
-+
-+ refcount: &rfcomm_tty_refcount,
-+ table: rfcomm_tty_table,
-+ termios: rfcomm_tty_termios,
-+ termios_locked: rfcomm_tty_termios_locked,
-+
-+ open: rfcomm_tty_open,
-+ close: rfcomm_tty_close,
-+ put_char: rfcomm_tty_put_char,
-+ write: rfcomm_tty_write,
-+ write_room: rfcomm_tty_write_room,
-+ chars_in_buffer: rfcomm_tty_chars_in_buffer,
-+ flush_buffer: rfcomm_tty_flush_buffer,
-+ ioctl: rfcomm_tty_ioctl,
-+ throttle: rfcomm_tty_throttle,
-+ unthrottle: rfcomm_tty_unthrottle,
-+ set_termios: rfcomm_tty_set_termios,
-+ send_xchar: rfcomm_tty_send_xchar,
-+ stop: NULL,
-+ start: NULL,
-+ hangup: rfcomm_tty_hangup,
-+ wait_until_sent: rfcomm_tty_wait_until_sent,
-+ read_proc: rfcomm_tty_read_proc,
-+};
-+
-+int rfcomm_init_ttys(void)
-+{
-+ int i;
-+
-+ /* Initalize our global data */
-+ for (i = 0; i < RFCOMM_TTY_PORTS; i++)
-+ rfcomm_tty_table[i] = NULL;
-+
-+ /* Register the TTY driver */
-+ rfcomm_tty_driver.init_termios = tty_std_termios;
-+ rfcomm_tty_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-+ rfcomm_tty_driver.flags = TTY_DRIVER_REAL_RAW;
-+
-+ if (tty_register_driver(&rfcomm_tty_driver)) {
-+ BT_ERR("Can't register RFCOMM TTY driver");
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+void rfcomm_cleanup_ttys(void)
-+{
-+ tty_unregister_driver(&rfcomm_tty_driver);
-+ return;
-+}
---- /dev/null 1970-01-01 01:00:00.000000000 +0100
-+++ linux/net/bluetooth/sco.c 2004-01-25 23:37:39.000000000 +0100
-@@ -0,0 +1,1019 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * BlueZ SCO sockets.
-+ *
-+ * $Id$
-+ */
-+#define VERSION "0.3"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/socket.h>
-+#include <linux/skbuff.h>
-+#include <linux/proc_fs.h>
-+#include <linux/list.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include <net/bluetooth/sco.h>
-+
-+#ifndef SCO_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+static struct proto_ops sco_sock_ops;
-+
-+static struct bluez_sock_list sco_sk_list = {
-+ lock: RW_LOCK_UNLOCKED
-+};
-+
-+static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
-+static void sco_chan_del(struct sock *sk, int err);
-+static inline struct sock * sco_chan_get(struct sco_conn *conn);
-+
-+static int sco_conn_del(struct hci_conn *conn, int err);
-+
-+static void sco_sock_close(struct sock *sk);
-+static void sco_sock_kill(struct sock *sk);
-+
-+/* ----- SCO timers ------ */
-+static void sco_sock_timeout(unsigned long arg)
-+{
-+ struct sock *sk = (struct sock *) arg;
-+
-+ BT_DBG("sock %p state %d", sk, sk->state);
-+
-+ bh_lock_sock(sk);
-+ sk->err = ETIMEDOUT;
-+ sk->state_change(sk);
-+ bh_unlock_sock(sk);
-+
-+ sco_sock_kill(sk);
-+ sock_put(sk);
-+}
-+
-+static void sco_sock_set_timer(struct sock *sk, long timeout)
-+{
-+ BT_DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
-+
-+ if (!mod_timer(&sk->timer, jiffies + timeout))
-+ sock_hold(sk);
-+}
-+
-+static void sco_sock_clear_timer(struct sock *sk)
-+{
-+ BT_DBG("sock %p state %d", sk, sk->state);
-+
-+ if (timer_pending(&sk->timer) && del_timer(&sk->timer))
-+ __sock_put(sk);
-+}
-+
-+static void sco_sock_init_timer(struct sock *sk)
-+{
-+ init_timer(&sk->timer);
-+ sk->timer.function = sco_sock_timeout;
-+ sk->timer.data = (unsigned long)sk;
-+}
-+
-+/* -------- SCO connections --------- */
-+static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status)
-+{
-+ struct hci_dev *hdev = hcon->hdev;
-+ struct sco_conn *conn;
-+
-+ if ((conn = hcon->sco_data))
-+ return conn;
-+
-+ if (status)
-+ return conn;
-+
-+ if (!(conn = kmalloc(sizeof(struct sco_conn), GFP_ATOMIC)))
-+ return NULL;
-+ memset(conn, 0, sizeof(struct sco_conn));
-+
-+ spin_lock_init(&conn->lock);
-+
-+ hcon->sco_data = conn;
-+ conn->hcon = hcon;
-+
-+ conn->src = &hdev->bdaddr;
-+ conn->dst = &hcon->dst;
-+
-+ if (hdev->sco_mtu > 0)
-+ conn->mtu = hdev->sco_mtu;
-+ else
-+ conn->mtu = 60;
-+
-+ BT_DBG("hcon %p conn %p", hcon, conn);
-+
-+ MOD_INC_USE_COUNT;
-+ return conn;
-+}
-+
-+static int sco_conn_del(struct hci_conn *hcon, int err)
-+{
-+ struct sco_conn *conn;
-+ struct sock *sk;
-+
-+ if (!(conn = hcon->sco_data))
-+ return 0;
-+
-+ BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
-+
-+ /* Kill socket */
-+ if ((sk = sco_chan_get(conn))) {
-+ bh_lock_sock(sk);
-+ sco_sock_clear_timer(sk);
-+ sco_chan_del(sk, err);
-+ bh_unlock_sock(sk);
-+ sco_sock_kill(sk);
-+ }
-+
-+ hcon->sco_data = NULL;
-+ kfree(conn);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+int sco_connect(struct sock *sk)
-+{
-+ bdaddr_t *src = &bluez_pi(sk)->src;
-+ bdaddr_t *dst = &bluez_pi(sk)->dst;
-+ struct sco_conn *conn;
-+ struct hci_conn *hcon;
-+ struct hci_dev *hdev;
-+ int err = 0;
-+
-+ BT_DBG("%s -> %s", batostr(src), batostr(dst));
-+
-+ if (!(hdev = hci_get_route(dst, src)))
-+ return -EHOSTUNREACH;
-+
-+ hci_dev_lock_bh(hdev);
-+
-+ err = -ENOMEM;
-+
-+ hcon = hci_connect(hdev, SCO_LINK, dst);
-+ if (!hcon)
-+ goto done;
-+
-+ conn = sco_conn_add(hcon, 0);
-+ if (!conn) {
-+ hci_conn_put(hcon);
-+ goto done;
-+ }
-+
-+ /* Update source addr of the socket */
-+ bacpy(src, conn->src);
-+
-+ err = sco_chan_add(conn, sk, NULL);
-+ if (err)
-+ goto done;
-+
-+ if (hcon->state == BT_CONNECTED) {
-+ sco_sock_clear_timer(sk);
-+ sk->state = BT_CONNECTED;
-+ } else {
-+ sk->state = BT_CONNECT;
-+ sco_sock_set_timer(sk, sk->sndtimeo);
-+ }
-+done:
-+ hci_dev_unlock_bh(hdev);
-+ hci_dev_put(hdev);
-+ return err;
-+}
-+
-+static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
-+{
-+ struct sco_conn *conn = sco_pi(sk)->conn;
-+ struct sk_buff *skb;
-+ int err, count;
-+
-+ /* Check outgoing MTU */
-+ if (len > conn->mtu)
-+ return -EINVAL;
-+
-+ BT_DBG("sk %p len %d", sk, len);
-+
-+ count = MIN(conn->mtu, len);
-+ if (!(skb = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err)))
-+ return err;
-+
-+ if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
-+ err = -EFAULT;
-+ goto fail;
-+ }
-+
-+ if ((err = hci_send_sco(conn->hcon, skb)) < 0)
-+ goto fail;
-+
-+ return count;
-+
-+fail:
-+ kfree_skb(skb);
-+ return err;
-+}
-+
-+static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
-+{
-+ struct sock *sk = sco_chan_get(conn);
-+
-+ if (!sk)
-+ goto drop;
-+
-+ BT_DBG("sk %p len %d", sk, skb->len);
-+
-+ if (sk->state != BT_CONNECTED)
-+ goto drop;
-+
-+ if (!sock_queue_rcv_skb(sk, skb))
-+ return;
-+
-+drop:
-+ kfree_skb(skb);
-+ return;
-+}
-+
-+/* -------- Socket interface ---------- */
-+static struct sock *__sco_get_sock_by_addr(bdaddr_t *ba)
-+{
-+ struct sock *sk;
-+
-+ for (sk = sco_sk_list.head; sk; sk = sk->next) {
-+ if (!bacmp(&bluez_pi(sk)->src, ba))
-+ break;
-+ }
-+
-+ return sk;
-+}
-+
-+/* Find socket listening on source bdaddr.
-+ * Returns closest match.
-+ */
-+static struct sock *sco_get_sock_listen(bdaddr_t *src)
-+{
-+ struct sock *sk, *sk1 = NULL;
-+
-+ read_lock(&sco_sk_list.lock);
-+
-+ for (sk = sco_sk_list.head; sk; sk = sk->next) {
-+ if (sk->state != BT_LISTEN)
-+ continue;
-+
-+ /* Exact match. */
-+ if (!bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+
-+ /* Closest match */
-+ if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
-+ sk1 = sk;
-+ }
-+
-+ read_unlock(&sco_sk_list.lock);
-+
-+ return sk ? sk : sk1;
-+}
-+
-+static void sco_sock_destruct(struct sock *sk)
-+{
-+ BT_DBG("sk %p", sk);
-+
-+ skb_queue_purge(&sk->receive_queue);
-+ skb_queue_purge(&sk->write_queue);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void sco_sock_cleanup_listen(struct sock *parent)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("parent %p", parent);
-+
-+ /* Close not yet accepted channels */
-+ while ((sk = bluez_accept_dequeue(parent, NULL))) {
-+ sco_sock_close(sk);
-+ sco_sock_kill(sk);
-+ }
-+
-+ parent->state = BT_CLOSED;
-+ parent->zapped = 1;
-+}
-+
-+/* Kill socket (only if zapped and orphan)
-+ * Must be called on unlocked socket.
-+ */
-+static void sco_sock_kill(struct sock *sk)
-+{
-+ if (!sk->zapped || sk->socket)
-+ return;
-+
-+ BT_DBG("sk %p state %d", sk, sk->state);
-+
-+ /* Kill poor orphan */
-+ bluez_sock_unlink(&sco_sk_list, sk);
-+ sk->dead = 1;
-+ sock_put(sk);
-+}
-+
-+/* Close socket.
-+ * Must be called on unlocked socket.
-+ */
-+static void sco_sock_close(struct sock *sk)
-+{
-+ struct sco_conn *conn;
-+
-+ sco_sock_clear_timer(sk);
-+
-+ lock_sock(sk);
-+
-+ conn = sco_pi(sk)->conn;
-+
-+ BT_DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
-+
-+ switch (sk->state) {
-+ case BT_LISTEN:
-+ sco_sock_cleanup_listen(sk);
-+ break;
-+
-+ case BT_CONNECTED:
-+ case BT_CONFIG:
-+ case BT_CONNECT:
-+ case BT_DISCONN:
-+ sco_chan_del(sk, ECONNRESET);
-+ break;
-+
-+ default:
-+ sk->zapped = 1;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+}
-+
-+static void sco_sock_init(struct sock *sk, struct sock *parent)
-+{
-+ BT_DBG("sk %p", sk);
-+
-+ if (parent)
-+ sk->type = parent->type;
-+}
-+
-+static struct sock *sco_sock_alloc(struct socket *sock, int proto, int prio)
-+{
-+ struct sock *sk;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
-+ return NULL;
-+
-+ bluez_sock_init(sock, sk);
-+
-+ sk->zapped = 0;
-+
-+ sk->destruct = sco_sock_destruct;
-+ sk->sndtimeo = SCO_CONN_TIMEOUT;
-+
-+ sk->protocol = proto;
-+ sk->state = BT_OPEN;
-+
-+ sco_sock_init_timer(sk);
-+
-+ bluez_sock_link(&sco_sk_list, sk);
-+
-+ MOD_INC_USE_COUNT;
-+ return sk;
-+}
-+
-+static int sco_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ sock->state = SS_UNCONNECTED;
-+
-+ if (sock->type != SOCK_SEQPACKET)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &sco_sock_ops;
-+
-+ if (!(sk = sco_sock_alloc(sock, protocol, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ sco_sock_init(sk, NULL);
-+ return 0;
-+}
-+
-+static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
-+{
-+ struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
-+ struct sock *sk = sock->sk;
-+ bdaddr_t *src = &sa->sco_bdaddr;
-+ int err = 0;
-+
-+ BT_DBG("sk %p %s", sk, batostr(&sa->sco_bdaddr));
-+
-+ if (!addr || addr->sa_family != AF_BLUETOOTH)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_OPEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ write_lock_bh(&sco_sk_list.lock);
-+
-+ if (bacmp(src, BDADDR_ANY) && __sco_get_sock_by_addr(src)) {
-+ err = -EADDRINUSE;
-+ } else {
-+ /* Save source address */
-+ bacpy(&bluez_pi(sk)->src, &sa->sco_bdaddr);
-+ sk->state = BT_BOUND;
-+ }
-+
-+ write_unlock_bh(&sco_sk_list.lock);
-+
-+done:
-+ release_sock(sk);
-+
-+ return err;
-+}
-+
-+static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
-+{
-+ struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_sco))
-+ return -EINVAL;
-+
-+ if (sk->state != BT_OPEN && sk->state != BT_BOUND)
-+ return -EBADFD;
-+
-+ if (sk->type != SOCK_SEQPACKET)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ /* Set destination address and psm */
-+ bacpy(&bluez_pi(sk)->dst, &sa->sco_bdaddr);
-+
-+ if ((err = sco_connect(sk)))
-+ goto done;
-+
-+ err = bluez_sock_wait_state(sk, BT_CONNECTED,
-+ sock_sndtimeo(sk, flags & O_NONBLOCK));
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int sco_sock_listen(struct socket *sock, int backlog)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p backlog %d", sk, backlog);
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ sk->max_ack_backlog = backlog;
-+ sk->ack_backlog = 0;
-+ sk->state = BT_LISTEN;
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct sock *sk = sock->sk, *ch;
-+ long timeo;
-+ int err = 0;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
-+
-+ BT_DBG("sk %p timeo %ld", sk, timeo);
-+
-+ /* Wait for an incoming connection. (wake-one). */
-+ add_wait_queue_exclusive(sk->sleep, &wait);
-+ while (!(ch = bluez_accept_dequeue(sk, newsock))) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ break;
-+ }
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ break;
-+ }
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ if (err)
-+ goto done;
-+
-+ newsock->state = SS_CONNECTED;
-+
-+ BT_DBG("new socket %p", ch);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
-+{
-+ struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ addr->sa_family = AF_BLUETOOTH;
-+ *len = sizeof(struct sockaddr_sco);
-+
-+ if (peer)
-+ bacpy(&sa->sco_bdaddr, &bluez_pi(sk)->dst);
-+ else
-+ bacpy(&sa->sco_bdaddr, &bluez_pi(sk)->src);
-+
-+ return 0;
-+}
-+
-+static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (sk->err)
-+ return sock_error(sk);
-+
-+ if (msg->msg_flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state == BT_CONNECTED)
-+ err = sco_send_frame(sk, msg, len);
-+ else
-+ err = -ENOTCONN;
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int sco_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int sco_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ struct sco_options opts;
-+ struct sco_conninfo cinfo;
-+ int len, err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (get_user(len, optlen))
-+ return -EFAULT;
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ case SCO_OPTIONS:
-+ if (sk->state != BT_CONNECTED) {
-+ err = -ENOTCONN;
-+ break;
-+ }
-+
-+ opts.mtu = sco_pi(sk)->conn->mtu;
-+
-+ BT_DBG("mtu %d", opts.mtu);
-+
-+ len = MIN(len, sizeof(opts));
-+ if (copy_to_user(optval, (char *)&opts, len))
-+ err = -EFAULT;
-+
-+ break;
-+
-+ case SCO_CONNINFO:
-+ if (sk->state != BT_CONNECTED) {
-+ err = -ENOTCONN;
-+ break;
-+ }
-+
-+ cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
-+
-+ len = MIN(len, sizeof(cinfo));
-+ if (copy_to_user(optval, (char *)&cinfo, len))
-+ err = -EFAULT;
-+
-+ break;
-+
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int sco_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ sco_sock_close(sk);
-+ if (sk->linger) {
-+ lock_sock(sk);
-+ err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
-+ release_sock(sk);
-+ }
-+
-+ sock_orphan(sk);
-+ sco_sock_kill(sk);
-+ return err;
-+}
-+
-+static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
-+{
-+ BT_DBG("conn %p", conn);
-+
-+ sco_pi(sk)->conn = conn;
-+ conn->sk = sk;
-+
-+ if (parent)
-+ bluez_accept_enqueue(parent, sk);
-+}
-+
-+static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
-+{
-+ int err = 0;
-+
-+ sco_conn_lock(conn);
-+ if (conn->sk) {
-+ err = -EBUSY;
-+ } else {
-+ __sco_chan_add(conn, sk, parent);
-+ }
-+ sco_conn_unlock(conn);
-+ return err;
-+}
-+
-+static inline struct sock * sco_chan_get(struct sco_conn *conn)
-+{
-+ struct sock *sk = NULL;
-+ sco_conn_lock(conn);
-+ sk = conn->sk;
-+ sco_conn_unlock(conn);
-+ return sk;
-+}
-+
-+/* Delete channel.
-+ * Must be called on the locked socket. */
-+static void sco_chan_del(struct sock *sk, int err)
-+{
-+ struct sco_conn *conn;
-+
-+ conn = sco_pi(sk)->conn;
-+
-+ BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
-+
-+ if (conn) {
-+ sco_conn_lock(conn);
-+ conn->sk = NULL;
-+ sco_pi(sk)->conn = NULL;
-+ sco_conn_unlock(conn);
-+ hci_conn_put(conn->hcon);
-+ }
-+
-+ sk->state = BT_CLOSED;
-+ sk->err = err;
-+ sk->state_change(sk);
-+
-+ sk->zapped = 1;
-+}
-+
-+static void sco_conn_ready(struct sco_conn *conn)
-+{
-+ struct sock *parent, *sk;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ sco_conn_lock(conn);
-+
-+ if ((sk = conn->sk)) {
-+ sco_sock_clear_timer(sk);
-+ bh_lock_sock(sk);
-+ sk->state = BT_CONNECTED;
-+ sk->state_change(sk);
-+ bh_unlock_sock(sk);
-+ } else {
-+ parent = sco_get_sock_listen(conn->src);
-+ if (!parent)
-+ goto done;
-+
-+ bh_lock_sock(parent);
-+
-+ sk = sco_sock_alloc(NULL, BTPROTO_SCO, GFP_ATOMIC);
-+ if (!sk) {
-+ bh_unlock_sock(parent);
-+ goto done;
-+ }
-+
-+ sco_sock_init(sk, parent);
-+
-+ bacpy(&bluez_pi(sk)->src, conn->src);
-+ bacpy(&bluez_pi(sk)->dst, conn->dst);
-+
-+ hci_conn_hold(conn->hcon);
-+ __sco_chan_add(conn, sk, parent);
-+
-+ sk->state = BT_CONNECTED;
-+
-+ /* Wake up parent */
-+ parent->data_ready(parent, 1);
-+
-+ bh_unlock_sock(parent);
-+ }
-+
-+done:
-+ sco_conn_unlock(conn);
-+}
-+
-+/* ----- SCO interface with lower layer (HCI) ----- */
-+int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
-+{
-+ BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
-+
-+ /* Always accept connection */
-+ return HCI_LM_ACCEPT;
-+}
-+
-+int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
-+{
-+ BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
-+
-+ if (hcon->type != SCO_LINK)
-+ return 0;
-+
-+ if (!status) {
-+ struct sco_conn *conn;
-+
-+ conn = sco_conn_add(hcon, status);
-+ if (conn)
-+ sco_conn_ready(conn);
-+ } else
-+ sco_conn_del(hcon, bterr(status));
-+
-+ return 0;
-+}
-+
-+int sco_disconn_ind(struct hci_conn *hcon, __u8 reason)
-+{
-+ BT_DBG("hcon %p reason %d", hcon, reason);
-+
-+ if (hcon->type != SCO_LINK)
-+ return 0;
-+
-+ sco_conn_del(hcon, bterr(reason));
-+ return 0;
-+}
-+
-+int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
-+{
-+ struct sco_conn *conn = hcon->sco_data;
-+
-+ if (!conn)
-+ goto drop;
-+
-+ BT_DBG("conn %p len %d", conn, skb->len);
-+
-+ if (skb->len) {
-+ sco_recv_frame(conn, skb);
-+ return 0;
-+ }
-+
-+drop:
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+/* ----- Proc fs support ------ */
-+static int sco_sock_dump(char *buf, struct bluez_sock_list *list)
-+{
-+ struct sco_pinfo *pi;
-+ struct sock *sk;
-+ char *ptr = buf;
-+
-+ write_lock_bh(&list->lock);
-+
-+ for (sk = list->head; sk; sk = sk->next) {
-+ pi = sco_pi(sk);
-+ ptr += sprintf(ptr, "%s %s %d\n",
-+ batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
-+ sk->state);
-+ }
-+
-+ write_unlock_bh(&list->lock);
-+
-+ ptr += sprintf(ptr, "\n");
-+
-+ return ptr - buf;
-+}
-+
-+static int sco_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
-+{
-+ char *ptr = buf;
-+ int len;
-+
-+ BT_DBG("count %d, offset %ld", count, offset);
-+
-+ ptr += sco_sock_dump(ptr, &sco_sk_list);
-+ len = ptr - buf;
-+
-+ if (len <= count + offset)
-+ *eof = 1;
-+
-+ *start = buf + offset;
-+ len -= offset;
-+
-+ if (len > count)
-+ len = count;
-+ if (len < 0)
-+ len = 0;
-+
-+ return len;
-+}
-+
-+static struct proto_ops sco_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: sco_sock_release,
-+ bind: sco_sock_bind,
-+ connect: sco_sock_connect,
-+ listen: sco_sock_listen,
-+ accept: sco_sock_accept,
-+ getname: sco_sock_getname,
-+ sendmsg: sco_sock_sendmsg,
-+ recvmsg: bluez_sock_recvmsg,
-+ poll: bluez_sock_poll,
-+ socketpair: sock_no_socketpair,
-+ ioctl: sock_no_ioctl,
-+ shutdown: sock_no_shutdown,
-+ setsockopt: sco_sock_setsockopt,
-+ getsockopt: sco_sock_getsockopt,
-+ mmap: sock_no_mmap
-+};
-+
-+static struct net_proto_family sco_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: sco_sock_create
-+};
-+
-+static struct hci_proto sco_hci_proto = {
-+ name: "SCO",
-+ id: HCI_PROTO_SCO,
-+ connect_ind: sco_connect_ind,
-+ connect_cfm: sco_connect_cfm,
-+ disconn_ind: sco_disconn_ind,
-+ recv_scodata: sco_recv_scodata,
-+};
-+
-+int __init sco_init(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_SCO, &sco_sock_family_ops))) {
-+ BT_ERR("Can't register SCO socket layer");
-+ return err;
-+ }
-+
-+ if ((err = hci_register_proto(&sco_hci_proto))) {
-+ BT_ERR("Can't register SCO protocol");
-+ return err;
-+ }
-+
-+ create_proc_read_entry("bluetooth/sco", 0, 0, sco_read_proc, NULL);
-+
-+ BT_INFO("BlueZ SCO ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ return 0;
-+}
-+
-+void sco_cleanup(void)
-+{
-+ int err;
-+
-+ remove_proc_entry("bluetooth/sco", NULL);
-+
-+ /* Unregister socket, protocol and notifier */
-+ if ((err = bluez_sock_unregister(BTPROTO_SCO)))
-+ BT_ERR("Can't unregister SCO socket layer %d", err);
-+
-+ if ((err = hci_unregister_proto(&sco_hci_proto)))
-+ BT_ERR("Can't unregister SCO protocol %d", err);
-+}
-+
-+module_init(sco_init);
-+module_exit(sco_cleanup);
-+
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
-+MODULE_DESCRIPTION("BlueZ SCO ver " VERSION);
-+MODULE_LICENSE("GPL");
---- linux/net/bluetooth/syms.c~bluetooth-2.4.18-mh11 2001-09-07 18:28:38.000000000 +0200
-+++ linux/net/bluetooth/syms.c 2004-01-25 23:37:39.000000000 +0100
-@@ -25,7 +25,7 @@
- /*
- * BlueZ symbols.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
-@@ -39,25 +39,28 @@
- #include <linux/socket.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
-
- /* HCI Core */
- EXPORT_SYMBOL(hci_register_dev);
- EXPORT_SYMBOL(hci_unregister_dev);
-+EXPORT_SYMBOL(hci_suspend_dev);
-+EXPORT_SYMBOL(hci_resume_dev);
-+
- EXPORT_SYMBOL(hci_register_proto);
- EXPORT_SYMBOL(hci_unregister_proto);
--EXPORT_SYMBOL(hci_register_notifier);
--EXPORT_SYMBOL(hci_unregister_notifier);
-
-+EXPORT_SYMBOL(hci_get_route);
- EXPORT_SYMBOL(hci_connect);
--EXPORT_SYMBOL(hci_disconnect);
- EXPORT_SYMBOL(hci_dev_get);
-+EXPORT_SYMBOL(hci_conn_auth);
-+EXPORT_SYMBOL(hci_conn_encrypt);
-
- EXPORT_SYMBOL(hci_recv_frame);
- EXPORT_SYMBOL(hci_send_acl);
- EXPORT_SYMBOL(hci_send_sco);
--EXPORT_SYMBOL(hci_send_raw);
-+EXPORT_SYMBOL(hci_send_cmd);
-+EXPORT_SYMBOL(hci_si_event);
-
- /* BlueZ lib */
- EXPORT_SYMBOL(bluez_dump);
-@@ -68,5 +71,11 @@
- /* BlueZ sockets */
- EXPORT_SYMBOL(bluez_sock_register);
- EXPORT_SYMBOL(bluez_sock_unregister);
-+EXPORT_SYMBOL(bluez_sock_init);
- EXPORT_SYMBOL(bluez_sock_link);
- EXPORT_SYMBOL(bluez_sock_unlink);
-+EXPORT_SYMBOL(bluez_sock_recvmsg);
-+EXPORT_SYMBOL(bluez_sock_poll);
-+EXPORT_SYMBOL(bluez_accept_enqueue);
-+EXPORT_SYMBOL(bluez_accept_dequeue);
-+EXPORT_SYMBOL(bluez_sock_wait_state);
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bluetooth-2.4.18-mh15.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bluetooth-2.4.18-mh15.patch
deleted file mode 100644
index 1a7fd98653..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bluetooth-2.4.18-mh15.patch
+++ /dev/null
@@ -1,32759 +0,0 @@
-diff -urN linux-2.4.18/arch/alpha/config.in linux-2.4.18-mh15/arch/alpha/config.in
---- linux-2.4.18/arch/alpha/config.in 2001-11-21 00:49:31.000000000 +0100
-+++ linux-2.4.18-mh15/arch/alpha/config.in 2004-08-01 16:26:22.000000000 +0200
-@@ -371,9 +371,7 @@
- source drivers/usb/Config.in
- source drivers/input/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Kernel hacking'
-diff -urN linux-2.4.18/arch/arm/config.in linux-2.4.18-mh15/arch/arm/config.in
---- linux-2.4.18/arch/arm/config.in 2001-11-09 22:58:02.000000000 +0100
-+++ linux-2.4.18-mh15/arch/arm/config.in 2004-08-01 16:26:22.000000000 +0200
-@@ -584,9 +584,7 @@
-
- source drivers/usb/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Kernel hacking'
-diff -urN linux-2.4.18/arch/i386/config.in linux-2.4.18-mh15/arch/i386/config.in
---- linux-2.4.18/arch/i386/config.in 2002-02-25 20:37:52.000000000 +0100
-+++ linux-2.4.18-mh15/arch/i386/config.in 2004-08-01 16:26:22.000000000 +0200
-@@ -407,9 +407,7 @@
-
- source drivers/usb/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Kernel hacking'
-diff -urN linux-2.4.18/arch/ppc/config.in linux-2.4.18-mh15/arch/ppc/config.in
---- linux-2.4.18/arch/ppc/config.in 2002-02-25 20:37:55.000000000 +0100
-+++ linux-2.4.18-mh15/arch/ppc/config.in 2004-08-01 16:26:22.000000000 +0200
-@@ -389,9 +389,7 @@
-
- source drivers/usb/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Kernel hacking'
-diff -urN linux-2.4.18/arch/sparc/config.in linux-2.4.18-mh15/arch/sparc/config.in
---- linux-2.4.18/arch/sparc/config.in 2001-06-12 04:15:27.000000000 +0200
-+++ linux-2.4.18-mh15/arch/sparc/config.in 2004-08-01 16:26:22.000000000 +0200
-@@ -251,9 +251,7 @@
-
- source fs/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Watchdog'
-diff -urN linux-2.4.18/arch/sparc64/config.in linux-2.4.18-mh15/arch/sparc64/config.in
---- linux-2.4.18/arch/sparc64/config.in 2001-12-21 18:41:53.000000000 +0100
-+++ linux-2.4.18-mh15/arch/sparc64/config.in 2004-08-01 16:26:22.000000000 +0200
-@@ -283,9 +283,7 @@
-
- source drivers/usb/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Watchdog'
-diff -urN linux-2.4.18/arch/sparc64/kernel/ioctl32.c linux-2.4.18-mh15/arch/sparc64/kernel/ioctl32.c
---- linux-2.4.18/arch/sparc64/kernel/ioctl32.c 2002-02-25 20:37:56.000000000 +0100
-+++ linux-2.4.18-mh15/arch/sparc64/kernel/ioctl32.c 2004-08-01 16:26:23.000000000 +0200
-@@ -92,6 +92,7 @@
-
- #include <net/bluetooth/bluetooth.h>
- #include <net/bluetooth/hci.h>
-+#include <net/bluetooth/rfcomm.h>
-
- #include <linux/usb.h>
- #include <linux/usbdevice_fs.h>
-@@ -3822,6 +3823,15 @@
- return err;
- }
-
-+/* Bluetooth ioctls */
-+#define HCIUARTSETPROTO _IOW('U', 200, int)
-+#define HCIUARTGETPROTO _IOR('U', 201, int)
-+
-+#define BNEPCONNADD _IOW('B', 200, int)
-+#define BNEPCONNDEL _IOW('B', 201, int)
-+#define BNEPGETCONNLIST _IOR('B', 210, int)
-+#define BNEPGETCONNINFO _IOR('B', 211, int)
-+
- struct mtd_oob_buf32 {
- u32 start;
- u32 length;
-@@ -3878,6 +3888,16 @@
- return ((0 == ret) ? 0 : -EFAULT);
- }
-
-+#define CMTPCONNADD _IOW('C', 200, int)
-+#define CMTPCONNDEL _IOW('C', 201, int)
-+#define CMTPGETCONNLIST _IOR('C', 210, int)
-+#define CMTPGETCONNINFO _IOR('C', 211, int)
-+
-+#define HIDPCONNADD _IOW('H', 200, int)
-+#define HIDPCONNDEL _IOW('H', 201, int)
-+#define HIDPGETCONNLIST _IOR('H', 210, int)
-+#define HIDPGETCONNINFO _IOR('H', 211, int)
-+
- struct ioctl_trans {
- unsigned int cmd;
- unsigned int handler;
-@@ -4540,6 +4560,25 @@
- COMPATIBLE_IOCTL(HCISETSCAN)
- COMPATIBLE_IOCTL(HCISETAUTH)
- COMPATIBLE_IOCTL(HCIINQUIRY)
-+COMPATIBLE_IOCTL(HCIUARTSETPROTO)
-+COMPATIBLE_IOCTL(HCIUARTGETPROTO)
-+COMPATIBLE_IOCTL(RFCOMMCREATEDEV)
-+COMPATIBLE_IOCTL(RFCOMMRELEASEDEV)
-+COMPATIBLE_IOCTL(RFCOMMGETDEVLIST)
-+COMPATIBLE_IOCTL(RFCOMMGETDEVINFO)
-+COMPATIBLE_IOCTL(RFCOMMSTEALDLC)
-+COMPATIBLE_IOCTL(BNEPCONNADD)
-+COMPATIBLE_IOCTL(BNEPCONNDEL)
-+COMPATIBLE_IOCTL(BNEPGETCONNLIST)
-+COMPATIBLE_IOCTL(BNEPGETCONNINFO)
-+COMPATIBLE_IOCTL(CMTPCONNADD)
-+COMPATIBLE_IOCTL(CMTPCONNDEL)
-+COMPATIBLE_IOCTL(CMTPGETCONNLIST)
-+COMPATIBLE_IOCTL(CMTPGETCONNINFO)
-+COMPATIBLE_IOCTL(HIDPCONNADD)
-+COMPATIBLE_IOCTL(HIDPCONNDEL)
-+COMPATIBLE_IOCTL(HIDPGETCONNLIST)
-+COMPATIBLE_IOCTL(HIDPGETCONNINFO)
- /* Misc. */
- COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */
- COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */
-diff -urN linux-2.4.18/CREDITS linux-2.4.18-mh15/CREDITS
---- linux-2.4.18/CREDITS 2002-02-25 20:37:50.000000000 +0100
-+++ linux-2.4.18-mh15/CREDITS 2004-08-01 16:26:23.000000000 +0200
-@@ -1317,6 +1317,16 @@
- S: Provo, Utah 84606-5607
- S: USA
-
-+N: Marcel Holtmann
-+E: marcel@holtmann.org
-+W: http://www.holtmann.org
-+D: Maintainer of the Linux Bluetooth Subsystem
-+D: Author and maintainer of the various Bluetooth HCI drivers
-+D: Author and maintainer of the CAPI message transport protocol driver
-+D: Author and maintainer of the Bluetooth HID protocol driver
-+D: Various other Bluetooth related patches, cleanups and fixes
-+S: Germany
-+
- N: Rob W. W. Hooft
- E: hooft@EMBL-Heidelberg.DE
- D: Shared libs for graphics-tools and for the f2c compiler
-@@ -2546,6 +2556,7 @@
- N: Aristeu Sergio Rozanski Filho
- E: aris@conectiva.com.br
- D: Support for EtherExpress 10 ISA (i82595) in eepro driver
-+D: User level driver support for input
- S: Conectiva S.A.
- S: R. Tocantins, 89 - Cristo Rei
- S: 80050-430 - Curitiba - Paraná
-diff -urN linux-2.4.18/Documentation/Configure.help linux-2.4.18-mh15/Documentation/Configure.help
---- linux-2.4.18/Documentation/Configure.help 2002-02-25 20:37:51.000000000 +0100
-+++ linux-2.4.18-mh15/Documentation/Configure.help 2004-08-01 16:26:23.000000000 +0200
-@@ -2824,14 +2824,6 @@
-
- If unsure, say N.
-
--HCI EMU (virtual device) driver
--CONFIG_BLUEZ_HCIEMU
-- Bluetooth Virtual HCI device driver.
-- This driver is required if you want to use HCI Emulation software.
--
-- Say Y here to compile support for Virtual HCI devices into the
-- kernel or say M to compile it as module (hci_usb.o).
--
- # Choice: alphatype
- Alpha system type
- CONFIG_ALPHA_GENERIC
-@@ -11037,6 +11029,12 @@
-
- If unsure, say N.
-
-+Hotplug firmware loading support (EXPERIMENTAL)
-+CONFIG_FW_LOADER
-+ This option is provided for the case where no in-kernel-tree modules require
-+ hotplug firmware loading support, but a module built outside the kernel tree
-+ does.
-+
- Use PCI shared memory for NIC registers
- CONFIG_TULIP_MMIO
- Use PCI shared memory for the NIC registers, rather than going through
-@@ -12896,6 +12894,15 @@
- accessible under char device 13:64+ - /dev/input/eventX in a generic
- way. This is the future ...
-
-+CONFIG_INPUT_UINPUT
-+ Say Y here if you want to support user level drivers for input
-+ subsystem accessible under char device 10:223 - /dev/input/uinput.
-+
-+ This driver is also available as a module ( = code which can be
-+ inserted in and removed from the running kernel whenever you want).
-+ The module will be called uinput.o. If you want to compile it as a
-+ module, say M here and read <file:Documentation/modules.txt>.
-+
- USB Scanner support
- CONFIG_USB_SCANNER
- Say Y here if you want to connect a USB scanner to your computer's
-@@ -19870,19 +19877,22 @@
- Bluetooth can be found at <http://www.bluetooth.com/>.
-
- Linux Bluetooth subsystem consist of several layers:
-- HCI Core (device and connection manager, scheduler)
-- HCI Device drivers (interface to the hardware)
-- L2CAP Module (L2CAP protocol)
-+ BlueZ Core (HCI device and connection manager, scheduler)
-+ HCI Device drivers (Interface to the hardware)
-+ SCO Module (SCO audio links)
-+ L2CAP Module (Logical Link Control and Adaptation Protocol)
-+ RFCOMM Module (RFCOMM Protocol)
-+ BNEP Module (Bluetooth Network Encapsulation Protocol)
-+ CMTP Module (CAPI Message Transport Protocol)
-+ HIDP Module (Human Interface Device Protocol)
-
-- Say Y here to enable Linux Bluetooth support and to build HCI Core
-- layer.
-+ Say Y here to compile Bluetooth support into the kernel or say M to
-+ compile it as module (bluez.o).
-
- To use Linux Bluetooth subsystem, you will need several user-space
- utilities like hciconfig and hcid. These utilities and updates to
- Bluetooth kernel modules are provided in the BlueZ package.
-- For more information, see <http://bluez.sourceforge.net/>.
--
-- If you want to compile HCI Core as module (hci.o) say M here.
-+ For more information, see <http://www.bluez.org/>.
-
- L2CAP protocol support
- CONFIG_BLUEZ_L2CAP
-@@ -19893,15 +19903,96 @@
- Say Y here to compile L2CAP support into the kernel or say M to
- compile it as module (l2cap.o).
-
-+SCO links support
-+CONFIG_BLUEZ_SCO
-+ SCO link provides voice transport over Bluetooth. SCO support is
-+ required for voice applications like Headset and Audio.
-+
-+ Say Y here to compile SCO support into the kernel or say M to
-+ compile it as module (sco.o).
-+
-+RFCOMM protocol support
-+CONFIG_BLUEZ_RFCOMM
-+ RFCOMM provides connection oriented stream transport. RFCOMM
-+ support is required for Dialup Networking, OBEX and other Bluetooth
-+ applications.
-+
-+ Say Y here to compile RFCOMM support into the kernel or say M to
-+ compile it as module (rfcomm.o).
-+
-+RFCOMM TTY emulation support
-+CONFIG_BLUEZ_RFCOMM_TTY
-+ This option enables TTY emulation support for RFCOMM channels.
-+
-+BNEP protocol support
-+CONFIG_BLUEZ_BNEP
-+ BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet
-+ emulation layer on top of Bluetooth. BNEP is required for
-+ Bluetooth PAN (Personal Area Network).
-+
-+ Say Y here to compile BNEP support into the kernel or say M to
-+ compile it as module (bnep.o).
-+
-+BNEP multicast filter support
-+CONFIG_BLUEZ_BNEP_MC_FILTER
-+ This option enables the multicast filter support for BNEP.
-+
-+BNEP protocol filter support
-+CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+ This option enables the protocol filter support for BNEP.
-+
-+CMTP protocol support
-+CONFIG_BLUEZ_CMTP
-+ CMTP (CAPI Message Transport Protocol) is a transport layer
-+ for CAPI messages. CMTP is required for the Bluetooth Common
-+ ISDN Access Profile.
-+
-+ Say Y here to compile CMTP support into the kernel or say M to
-+ compile it as module (cmtp.o).
-+
-+HIDP protocol support
-+CONFIG_BLUEZ_HIDP
-+ HIDP (Human Interface Device Protocol) is a transport layer
-+ for HID reports. HIDP is required for the Bluetooth Human
-+ Interface Device Profile.
-+
-+ Say Y here to compile HIDP support into the kernel or say M to
-+ compile it as module (hidp.o).
-+
- HCI UART driver
- CONFIG_BLUEZ_HCIUART
- Bluetooth HCI UART driver.
- This driver is required if you want to use Bluetooth devices with
-- serial port interface.
-+ serial port interface. You will also need this driver if you have
-+ UART based Bluetooth PCMCIA and CF devices like Xircom Credit Card
-+ adapter and BrainBoxes Bluetooth PC Card.
-
- Say Y here to compile support for Bluetooth UART devices into the
- kernel or say M to compile it as module (hci_uart.o).
-
-+HCI UART (H4) protocol support
-+CONFIG_BLUEZ_HCIUART_H4
-+ UART (H4) is serial protocol for communication between Bluetooth
-+ device and host. This protocol is required for most Bluetooth devices
-+ with UART interface, including PCMCIA and CF cards.
-+
-+ Say Y here to compile support for HCI UART (H4) protocol.
-+
-+HCI BCSP protocol support
-+CONFIG_BLUEZ_HCIUART_BCSP
-+ BCSP (BlueCore Serial Protocol) is serial protocol for communication
-+ between Bluetooth device and host. This protocol is required for non
-+ USB Bluetooth devices based on CSR BlueCore chip, including PCMCIA and
-+ CF cards.
-+
-+ Say Y here to compile support for HCI BCSP protocol.
-+
-+HCI BCSP transmit CRC with every BCSP packet
-+CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ If you say Y here, a 16-bit CRC checksum will be transmitted along with
-+ every BCSP (BlueCore Serial Protocol) packet sent to the Bluetooth chip.
-+ This increases reliability, but slightly reduces efficiency.
-+
- HCI USB driver
- CONFIG_BLUEZ_HCIUSB
- Bluetooth HCI USB driver.
-@@ -19911,7 +20002,16 @@
- Say Y here to compile support for Bluetooth USB devices into the
- kernel or say M to compile it as module (hci_usb.o).
-
--HCI VHCI virtual HCI device driver
-+HCI USB SCO (voice) support
-+CONFIG_BLUEZ_HCIUSB_SCO
-+ This option enables the SCO support in the HCI USB driver. You need this
-+ to transmit voice data with your Bluetooth USB device. And your device
-+ must also support sending SCO data over the HCI layer, because some of
-+ them sends the SCO data to an internal PCM adapter.
-+
-+ Say Y here to compile support for HCI SCO data.
-+
-+HCI VHCI Virtual HCI device driver
- CONFIG_BLUEZ_HCIVHCI
- Bluetooth Virtual HCI device driver.
- This driver is required if you want to use HCI Emulation software.
-@@ -19919,6 +20019,63 @@
- Say Y here to compile support for virtual HCI devices into the
- kernel or say M to compile it as module (hci_vhci.o).
-
-+HCI BFUSB device driver
-+CONFIG_BLUEZ_HCIBFUSB
-+ Bluetooth HCI BlueFRITZ! USB driver.
-+ This driver provides support for Bluetooth USB devices with AVM
-+ interface:
-+ AVM BlueFRITZ! USB
-+
-+ Say Y here to compile support for HCI BFUSB devices into the
-+ kernel or say M to compile it as module (bfusb.o).
-+
-+HCI DTL1 (PC Card) device driver
-+CONFIG_BLUEZ_HCIDTL1
-+ Bluetooth HCI DTL1 (PC Card) driver.
-+ This driver provides support for Bluetooth PCMCIA devices with
-+ Nokia DTL1 interface:
-+ Nokia Bluetooth Card
-+ Socket Bluetooth CF Card
-+
-+ Say Y here to compile support for HCI DTL1 devices into the
-+ kernel or say M to compile it as module (dtl1_cs.o).
-+
-+HCI BT3C (PC Card) device driver
-+CONFIG_BLUEZ_HCIBT3C
-+ Bluetooth HCI BT3C (PC Card) driver.
-+ This driver provides support for Bluetooth PCMCIA devices with
-+ 3Com BT3C interface:
-+ 3Com Bluetooth Card (3CRWB6096)
-+ HP Bluetooth Card
-+
-+ Say Y here to compile support for HCI BT3C devices into the
-+ kernel or say M to compile it as module (bt3c_cs.o).
-+
-+HCI BlueCard (PC Card) device driver
-+CONFIG_BLUEZ_HCIBLUECARD
-+ Bluetooth HCI BlueCard (PC Card) driver.
-+ This driver provides support for Bluetooth PCMCIA devices with
-+ Anycom BlueCard interface:
-+ Anycom Bluetooth PC Card
-+ Anycom Bluetooth CF Card
-+
-+ Say Y here to compile support for HCI BlueCard devices into the
-+ kernel or say M to compile it as module (bluecard_cs.o).
-+
-+HCI UART (PC Card) device driver
-+CONFIG_BLUEZ_HCIBTUART
-+ Bluetooth HCI UART (PC Card) driver.
-+ This driver provides support for Bluetooth PCMCIA devices with
-+ an UART interface:
-+ Xircom CreditCard Bluetooth Adapter
-+ Xircom RealPort2 Bluetooth Adapter
-+ Sphinx PICO Card
-+ H-Soft blue+Card
-+ Cyber-blue Compact Flash Card
-+
-+ Say Y here to compile support for HCI UART devices into the
-+ kernel or say M to compile it as module (btuart_cs.o).
-+
- # The following options are for Linux when running on the Hitachi
- # SuperH family of RISC microprocessors.
-
-diff -urN linux-2.4.18/Documentation/devices.txt linux-2.4.18-mh15/Documentation/devices.txt
---- linux-2.4.18/Documentation/devices.txt 2001-11-07 23:46:01.000000000 +0100
-+++ linux-2.4.18-mh15/Documentation/devices.txt 2004-08-01 16:26:23.000000000 +0200
-@@ -419,6 +419,7 @@
- 220 = /dev/mptctl Message passing technology (MPT) control
- 221 = /dev/mvista/hssdsi Montavista PICMG hot swap system driver
- 222 = /dev/mvista/hasi Montavista PICMG high availability
-+ 223 = /dev/input/uinput User level driver support for input
- 240-255 Reserved for local use
-
- 11 char Raw keyboard device
-diff -urN linux-2.4.18/Documentation/firmware_class/firmware_sample_driver.c linux-2.4.18-mh15/Documentation/firmware_class/firmware_sample_driver.c
---- linux-2.4.18/Documentation/firmware_class/firmware_sample_driver.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/Documentation/firmware_class/firmware_sample_driver.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,121 @@
-+/*
-+ * firmware_sample_driver.c -
-+ *
-+ * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
-+ *
-+ * Sample code on how to use request_firmware() from drivers.
-+ *
-+ * Note that register_firmware() is currently useless.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/string.h>
-+
-+#include "linux/firmware.h"
-+
-+#define WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
-+#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
-+char __init inkernel_firmware[] = "let's say that this is firmware\n";
-+#endif
-+
-+static char ghost_device[] = "ghost0";
-+
-+static void sample_firmware_load(char *firmware, int size)
-+{
-+ u8 buf[size+1];
-+ memcpy(buf, firmware, size);
-+ buf[size] = '\0';
-+ printk("firmware_sample_driver: firmware: %s\n", buf);
-+}
-+
-+static void sample_probe_default(void)
-+{
-+ /* uses the default method to get the firmware */
-+ const struct firmware *fw_entry;
-+ printk("firmware_sample_driver: a ghost device got inserted :)\n");
-+
-+ if(request_firmware(&fw_entry, "sample_driver_fw", ghost_device)!=0)
-+ {
-+ printk(KERN_ERR
-+ "firmware_sample_driver: Firmware not available\n");
-+ return;
-+ }
-+
-+ sample_firmware_load(fw_entry->data, fw_entry->size);
-+
-+ release_firmware(fw_entry);
-+
-+ /* finish setting up the device */
-+}
-+static void sample_probe_specific(void)
-+{
-+ /* Uses some specific hotplug support to get the firmware from
-+ * userspace directly into the hardware, or via some sysfs file */
-+
-+ /* NOTE: This currently doesn't work */
-+
-+ printk("firmware_sample_driver: a ghost device got inserted :)\n");
-+
-+ if(request_firmware(NULL, "sample_driver_fw", ghost_device)!=0)
-+ {
-+ printk(KERN_ERR
-+ "firmware_sample_driver: Firmware load failed\n");
-+ return;
-+ }
-+
-+ /* request_firmware blocks until userspace finished, so at
-+ * this point the firmware should be already in the device */
-+
-+ /* finish setting up the device */
-+}
-+static void sample_probe_async_cont(const struct firmware *fw, void *context)
-+{
-+ if(!fw){
-+ printk(KERN_ERR
-+ "firmware_sample_driver: firmware load failed\n");
-+ return;
-+ }
-+
-+ printk("firmware_sample_driver: device pointer \"%s\"\n",
-+ (char *)context);
-+ sample_firmware_load(fw->data, fw->size);
-+}
-+static void sample_probe_async(void)
-+{
-+ /* Let's say that I can't sleep */
-+ int error;
-+ error = request_firmware_nowait (THIS_MODULE,
-+ "sample_driver_fw", ghost_device,
-+ "my device pointer",
-+ sample_probe_async_cont);
-+ if(error){
-+ printk(KERN_ERR
-+ "firmware_sample_driver:"
-+ " request_firmware_nowait failed\n");
-+ }
-+}
-+
-+static int sample_init(void)
-+{
-+#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
-+ register_firmware("sample_driver_fw", inkernel_firmware,
-+ sizeof(inkernel_firmware));
-+#endif
-+ /* since there is no real hardware insertion I just call the
-+ * sample probe functions here */
-+ sample_probe_specific();
-+ sample_probe_default();
-+ sample_probe_async();
-+ return 0;
-+}
-+static void __exit sample_exit(void)
-+{
-+}
-+
-+module_init (sample_init);
-+module_exit (sample_exit);
-+
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/Documentation/firmware_class/hotplug-script linux-2.4.18-mh15/Documentation/firmware_class/hotplug-script
---- linux-2.4.18/Documentation/firmware_class/hotplug-script 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/Documentation/firmware_class/hotplug-script 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,16 @@
-+#!/bin/sh
-+
-+# Simple hotplug script sample:
-+#
-+# Both $DEVPATH and $FIRMWARE are already provided in the environment.
-+
-+HOTPLUG_FW_DIR=/usr/lib/hotplug/firmware/
-+
-+echo 1 > /sysfs/$DEVPATH/loading
-+cat $HOTPLUG_FW_DIR/$FIRMWARE > /sysfs/$DEVPATH/data
-+echo 0 > /sysfs/$DEVPATH/loading
-+
-+# To cancel the load in case of error:
-+#
-+# echo -1 > /sysfs/$DEVPATH/loading
-+#
-diff -urN linux-2.4.18/Documentation/firmware_class/README linux-2.4.18-mh15/Documentation/firmware_class/README
---- linux-2.4.18/Documentation/firmware_class/README 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/Documentation/firmware_class/README 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,58 @@
-+
-+ request_firmware() hotplug interface:
-+ ------------------------------------
-+ Copyright (C) 2003 Manuel Estrada Sainz <ranty@debian.org>
-+
-+ Why:
-+ ---
-+
-+ Today, the most extended way to use firmware in the Linux kernel is linking
-+ it statically in a header file. Which has political and technical issues:
-+
-+ 1) Some firmware is not legal to redistribute.
-+ 2) The firmware occupies memory permanently, even though it often is just
-+ used once.
-+ 3) Some people, like the Debian crowd, don't consider some firmware free
-+ enough and remove entire drivers (e.g.: keyspan).
-+
-+ about in-kernel persistence:
-+ ---------------------------
-+ Under some circumstances, as explained below, it would be interesting to keep
-+ firmware images in non-swappable kernel memory or even in the kernel image
-+ (probably within initramfs).
-+
-+ Note that this functionality has not been implemented.
-+
-+ - Why OPTIONAL in-kernel persistence may be a good idea sometimes:
-+
-+ - If the device that needs the firmware is needed to access the
-+ filesystem. When upon some error the device has to be reset and the
-+ firmware reloaded, it won't be possible to get it from userspace.
-+ e.g.:
-+ - A diskless client with a network card that needs firmware.
-+ - The filesystem is stored in a disk behind an scsi device
-+ that needs firmware.
-+ - Replacing buggy DSDT/SSDT ACPI tables on boot.
-+ Note: this would require the persistent objects to be included
-+ within the kernel image, probably within initramfs.
-+
-+ And the same device can be needed to access the filesystem or not depending
-+ on the setup, so I think that the choice on what firmware to make
-+ persistent should be left to userspace.
-+
-+ - Why register_firmware()+__init can be useful:
-+ - For boot devices needing firmware.
-+ - To make the transition easier:
-+ The firmware can be declared __init and register_firmware()
-+ called on module_init. Then the firmware is warranted to be
-+ there even if "firmware hotplug userspace" is not there yet or
-+ it doesn't yet provide the needed firmware.
-+ Once the firmware is widely available in userspace, it can be
-+ removed from the kernel. Or made optional (CONFIG_.*_FIRMWARE).
-+
-+ In either case, if firmware hotplug support is there, it can move the
-+ firmware out of kernel memory into the real filesystem for later
-+ usage.
-+
-+ Note: If persistence is implemented on top of initramfs,
-+ register_firmware() may not be appropriate.
-diff -urN linux-2.4.18/drivers/bluetooth/bfusb.c linux-2.4.18-mh15/drivers/bluetooth/bfusb.c
---- linux-2.4.18/drivers/bluetooth/bfusb.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/bfusb.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,782 @@
-+/*
-+ *
-+ * AVM BlueFRITZ! USB driver
-+ *
-+ * Copyright (C) 2003 Marcel Holtmann <marcel@holtmann.org>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/skbuff.h>
-+
-+#include <linux/firmware.h>
-+#include <linux/usb.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+#ifndef CONFIG_BLUEZ_HCIBFUSB_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define VERSION "1.1"
-+
-+static struct usb_device_id bfusb_table[] = {
-+ /* AVM BlueFRITZ! USB */
-+ { USB_DEVICE(0x057c, 0x2200) },
-+
-+ { } /* Terminating entry */
-+};
-+
-+MODULE_DEVICE_TABLE(usb, bfusb_table);
-+
-+
-+#define BFUSB_MAX_BLOCK_SIZE 256
-+
-+#define BFUSB_BLOCK_TIMEOUT (HZ * 3)
-+
-+#define BFUSB_TX_PROCESS 1
-+#define BFUSB_TX_WAKEUP 2
-+
-+#define BFUSB_MAX_BULK_TX 1
-+#define BFUSB_MAX_BULK_RX 1
-+
-+struct bfusb {
-+ struct hci_dev hdev;
-+
-+ unsigned long state;
-+
-+ struct usb_device *udev;
-+
-+ unsigned int bulk_in_ep;
-+ unsigned int bulk_out_ep;
-+ unsigned int bulk_pkt_size;
-+
-+ rwlock_t lock;
-+
-+ struct sk_buff_head transmit_q;
-+
-+ struct sk_buff *reassembly;
-+
-+ atomic_t pending_tx;
-+ struct sk_buff_head pending_q;
-+ struct sk_buff_head completed_q;
-+};
-+
-+struct bfusb_scb {
-+ struct urb *urb;
-+};
-+
-+static void bfusb_tx_complete(struct urb *urb);
-+static void bfusb_rx_complete(struct urb *urb);
-+
-+static struct urb *bfusb_get_completed(struct bfusb *bfusb)
-+{
-+ struct sk_buff *skb;
-+ struct urb *urb = NULL;
-+
-+ BT_DBG("bfusb %p", bfusb);
-+
-+ skb = skb_dequeue(&bfusb->completed_q);
-+ if (skb) {
-+ urb = ((struct bfusb_scb *) skb->cb)->urb;
-+ kfree_skb(skb);
-+ }
-+
-+ return urb;
-+}
-+
-+static inline void bfusb_unlink_urbs(struct bfusb *bfusb)
-+{
-+ struct sk_buff *skb;
-+ struct urb *urb;
-+
-+ BT_DBG("bfusb %p", bfusb);
-+
-+ while ((skb = skb_dequeue(&bfusb->pending_q))) {
-+ urb = ((struct bfusb_scb *) skb->cb)->urb;
-+ usb_unlink_urb(urb);
-+ skb_queue_tail(&bfusb->completed_q, skb);
-+ }
-+
-+ while ((urb = bfusb_get_completed(bfusb)))
-+ usb_free_urb(urb);
-+}
-+
-+
-+static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb)
-+{
-+ struct bfusb_scb *scb = (void *) skb->cb;
-+ struct urb *urb = bfusb_get_completed(bfusb);
-+ int err, pipe;
-+
-+ BT_DBG("bfusb %p skb %p len %d", bfusb, skb, skb->len);
-+
-+ if (!urb && !(urb = usb_alloc_urb(0)))
-+ return -ENOMEM;
-+
-+ pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
-+
-+ FILL_BULK_URB(urb, bfusb->udev, pipe, skb->data, skb->len,
-+ bfusb_tx_complete, skb);
-+
-+ urb->transfer_flags = USB_QUEUE_BULK;
-+
-+ scb->urb = urb;
-+
-+ skb_queue_tail(&bfusb->pending_q, skb);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s bulk tx submit failed urb %p err %d",
-+ bfusb->hdev.name, urb, err);
-+ skb_unlink(skb);
-+ usb_free_urb(urb);
-+ } else
-+ atomic_inc(&bfusb->pending_tx);
-+
-+ return err;
-+}
-+
-+static void bfusb_tx_wakeup(struct bfusb *bfusb)
-+{
-+ struct sk_buff *skb;
-+
-+ BT_DBG("bfusb %p", bfusb);
-+
-+ if (test_and_set_bit(BFUSB_TX_PROCESS, &bfusb->state)) {
-+ set_bit(BFUSB_TX_WAKEUP, &bfusb->state);
-+ return;
-+ }
-+
-+ do {
-+ clear_bit(BFUSB_TX_WAKEUP, &bfusb->state);
-+
-+ while ((atomic_read(&bfusb->pending_tx) < BFUSB_MAX_BULK_TX) &&
-+ (skb = skb_dequeue(&bfusb->transmit_q))) {
-+ if (bfusb_send_bulk(bfusb, skb) < 0) {
-+ skb_queue_head(&bfusb->transmit_q, skb);
-+ break;
-+ }
-+ }
-+
-+ } while (test_bit(BFUSB_TX_WAKEUP, &bfusb->state));
-+
-+ clear_bit(BFUSB_TX_PROCESS, &bfusb->state);
-+}
-+
-+static void bfusb_tx_complete(struct urb *urb)
-+{
-+ struct sk_buff *skb = (struct sk_buff *) urb->context;
-+ struct bfusb *bfusb = (struct bfusb *) skb->dev;
-+
-+ BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
-+
-+ atomic_dec(&bfusb->pending_tx);
-+
-+ if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags))
-+ return;
-+
-+ if (!urb->status)
-+ bfusb->hdev.stat.byte_tx += skb->len;
-+ else
-+ bfusb->hdev.stat.err_tx++;
-+
-+ read_lock(&bfusb->lock);
-+
-+ skb_unlink(skb);
-+ skb_queue_tail(&bfusb->completed_q, skb);
-+
-+ bfusb_tx_wakeup(bfusb);
-+
-+ read_unlock(&bfusb->lock);
-+}
-+
-+
-+static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb)
-+{
-+ struct bfusb_scb *scb;
-+ struct sk_buff *skb;
-+ int err, pipe, size = HCI_MAX_FRAME_SIZE + 32;
-+
-+ BT_DBG("bfusb %p urb %p", bfusb, urb);
-+
-+ if (!urb && !(urb = usb_alloc_urb(0)))
-+ return -ENOMEM;
-+
-+ if (!(skb = bluez_skb_alloc(size, GFP_ATOMIC))) {
-+ usb_free_urb(urb);
-+ return -ENOMEM;
-+ }
-+
-+ skb->dev = (void *) bfusb;
-+
-+ scb = (struct bfusb_scb *) skb->cb;
-+ scb->urb = urb;
-+
-+ pipe = usb_rcvbulkpipe(bfusb->udev, bfusb->bulk_in_ep);
-+
-+ FILL_BULK_URB(urb, bfusb->udev, pipe, skb->data, size,
-+ bfusb_rx_complete, skb);
-+
-+ urb->transfer_flags = USB_QUEUE_BULK;
-+
-+ skb_queue_tail(&bfusb->pending_q, skb);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s bulk rx submit failed urb %p err %d",
-+ bfusb->hdev.name, urb, err);
-+ skb_unlink(skb);
-+ kfree_skb(skb);
-+ usb_free_urb(urb);
-+ }
-+
-+ return err;
-+}
-+
-+static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *data, int len)
-+{
-+ BT_DBG("bfusb %p hdr 0x%02x data %p len %d", bfusb, hdr, data, len);
-+
-+ if (hdr & 0x10) {
-+ BT_ERR("%s error in block", bfusb->hdev.name);
-+ if (bfusb->reassembly)
-+ kfree_skb(bfusb->reassembly);
-+ bfusb->reassembly = NULL;
-+ return -EIO;
-+ }
-+
-+ if (hdr & 0x04) {
-+ struct sk_buff *skb;
-+ unsigned char pkt_type;
-+ int pkt_len = 0;
-+
-+ if (bfusb->reassembly) {
-+ BT_ERR("%s unexpected start block", bfusb->hdev.name);
-+ kfree_skb(bfusb->reassembly);
-+ bfusb->reassembly = NULL;
-+ }
-+
-+ if (len < 1) {
-+ BT_ERR("%s no packet type found", bfusb->hdev.name);
-+ return -EPROTO;
-+ }
-+
-+ pkt_type = *data++; len--;
-+
-+ switch (pkt_type) {
-+ case HCI_EVENT_PKT:
-+ if (len >= HCI_EVENT_HDR_SIZE) {
-+ hci_event_hdr *hdr = (hci_event_hdr *) data;
-+ pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;
-+ } else {
-+ BT_ERR("%s event block is too short", bfusb->hdev.name);
-+ return -EILSEQ;
-+ }
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ if (len >= HCI_ACL_HDR_SIZE) {
-+ hci_acl_hdr *hdr = (hci_acl_hdr *) data;
-+ pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen);
-+ } else {
-+ BT_ERR("%s data block is too short", bfusb->hdev.name);
-+ return -EILSEQ;
-+ }
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ if (len >= HCI_SCO_HDR_SIZE) {
-+ hci_sco_hdr *hdr = (hci_sco_hdr *) data;
-+ pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen;
-+ } else {
-+ BT_ERR("%s audio block is too short", bfusb->hdev.name);
-+ return -EILSEQ;
-+ }
-+ break;
-+ }
-+
-+ skb = bluez_skb_alloc(pkt_len, GFP_ATOMIC);
-+ if (!skb) {
-+ BT_ERR("%s no memory for the packet", bfusb->hdev.name);
-+ return -ENOMEM;
-+ }
-+
-+ skb->dev = (void *) &bfusb->hdev;
-+ skb->pkt_type = pkt_type;
-+
-+ bfusb->reassembly = skb;
-+ } else {
-+ if (!bfusb->reassembly) {
-+ BT_ERR("%s unexpected continuation block", bfusb->hdev.name);
-+ return -EIO;
-+ }
-+ }
-+
-+ if (len > 0)
-+ memcpy(skb_put(bfusb->reassembly, len), data, len);
-+
-+ if (hdr & 0x08) {
-+ hci_recv_frame(bfusb->reassembly);
-+ bfusb->reassembly = NULL;
-+ }
-+
-+ return 0;
-+}
-+
-+static void bfusb_rx_complete(struct urb *urb)
-+{
-+ struct sk_buff *skb = (struct sk_buff *) urb->context;
-+ struct bfusb *bfusb = (struct bfusb *) skb->dev;
-+ unsigned char *buf = urb->transfer_buffer;
-+ int count = urb->actual_length;
-+ int err, hdr, len;
-+
-+ BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
-+
-+ read_lock(&bfusb->lock);
-+
-+ if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags))
-+ goto unlock;
-+
-+ if (urb->status || !count)
-+ goto resubmit;
-+
-+ bfusb->hdev.stat.byte_rx += count;
-+
-+ skb_put(skb, count);
-+
-+ while (count) {
-+ hdr = buf[0] | (buf[1] << 8);
-+
-+ if (hdr & 0x4000) {
-+ len = 0;
-+ count -= 2;
-+ buf += 2;
-+ } else {
-+ len = (buf[2] == 0) ? 256 : buf[2];
-+ count -= 3;
-+ buf += 3;
-+ }
-+
-+ if (count < len) {
-+ BT_ERR("%s block extends over URB buffer ranges",
-+ bfusb->hdev.name);
-+ }
-+
-+ if ((hdr & 0xe1) == 0xc1)
-+ bfusb_recv_block(bfusb, hdr, buf, len);
-+
-+ count -= len;
-+ buf += len;
-+ }
-+
-+ skb_unlink(skb);
-+ kfree_skb(skb);
-+
-+ bfusb_rx_submit(bfusb, urb);
-+
-+ read_unlock(&bfusb->lock);
-+
-+ return;
-+
-+resubmit:
-+ urb->dev = bfusb->udev;
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s bulk resubmit failed urb %p err %d",
-+ bfusb->hdev.name, urb, err);
-+ }
-+
-+unlock:
-+ read_unlock(&bfusb->lock);
-+}
-+
-+
-+static int bfusb_open(struct hci_dev *hdev)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
-+ unsigned long flags;
-+ int i, err;
-+
-+ BT_DBG("hdev %p bfusb %p", hdev, bfusb);
-+
-+ if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ write_lock_irqsave(&bfusb->lock, flags);
-+
-+ err = bfusb_rx_submit(bfusb, NULL);
-+ if (!err) {
-+ for (i = 1; i < BFUSB_MAX_BULK_RX; i++)
-+ bfusb_rx_submit(bfusb, NULL);
-+ } else {
-+ clear_bit(HCI_RUNNING, &hdev->flags);
-+ MOD_DEC_USE_COUNT;
-+ }
-+
-+ write_unlock_irqrestore(&bfusb->lock, flags);
-+
-+ return err;
-+}
-+
-+static int bfusb_flush(struct hci_dev *hdev)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
-+
-+ BT_DBG("hdev %p bfusb %p", hdev, bfusb);
-+
-+ skb_queue_purge(&bfusb->transmit_q);
-+
-+ return 0;
-+}
-+
-+static int bfusb_close(struct hci_dev *hdev)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
-+ unsigned long flags;
-+
-+ BT_DBG("hdev %p bfusb %p", hdev, bfusb);
-+
-+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-+
-+ write_lock_irqsave(&bfusb->lock, flags);
-+
-+ bfusb_unlink_urbs(bfusb);
-+ bfusb_flush(hdev);
-+
-+ write_unlock_irqrestore(&bfusb->lock, flags);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ return 0;
-+}
-+
-+static int bfusb_send_frame(struct sk_buff *skb)
-+{
-+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-+ struct bfusb *bfusb;
-+ struct sk_buff *nskb;
-+ unsigned char buf[3];
-+ int sent = 0, size, count;
-+
-+ BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, skb->pkt_type, skb->len);
-+
-+ if (!hdev) {
-+ BT_ERR("Frame for unknown HCI device (hdev=NULL)");
-+ return -ENODEV;
-+ }
-+
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return -EBUSY;
-+
-+ bfusb = (struct bfusb *) hdev->driver_data;
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+
-+ count = skb->len;
-+
-+ /* Max HCI frame size seems to be 1511 + 1 */
-+ if (!(nskb = bluez_skb_alloc(count + 32, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for new packet");
-+ return -ENOMEM;
-+ }
-+
-+ nskb->dev = (void *) bfusb;
-+
-+ while (count) {
-+ size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE);
-+
-+ buf[0] = 0xc1 | ((sent == 0) ? 0x04 : 0) | ((count == size) ? 0x08 : 0);
-+ buf[1] = 0x00;
-+ buf[2] = (size == BFUSB_MAX_BLOCK_SIZE) ? 0 : size;
-+
-+ memcpy(skb_put(nskb, 3), buf, 3);
-+ memcpy(skb_put(nskb, size), skb->data + sent, size);
-+
-+ sent += size;
-+ count -= size;
-+ }
-+
-+ /* Don't send frame with multiple size of bulk max packet */
-+ if ((nskb->len % bfusb->bulk_pkt_size) == 0) {
-+ buf[0] = 0xdd;
-+ buf[1] = 0x00;
-+ memcpy(skb_put(nskb, 2), buf, 2);
-+ }
-+
-+ read_lock(&bfusb->lock);
-+
-+ skb_queue_tail(&bfusb->transmit_q, nskb);
-+ bfusb_tx_wakeup(bfusb);
-+
-+ read_unlock(&bfusb->lock);
-+
-+ kfree_skb(skb);
-+
-+ return 0;
-+}
-+
-+static void bfusb_destruct(struct hci_dev *hdev)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
-+
-+ BT_DBG("hdev %p bfusb %p", hdev, bfusb);
-+
-+ kfree(bfusb);
-+}
-+
-+static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int count)
-+{
-+ unsigned char *buf;
-+ int err, pipe, len, size, sent = 0;
-+
-+ BT_DBG("bfusb %p udev %p firmware %p count %d", bfusb, bfusb->udev, firmware, count);
-+
-+ BT_INFO("BlueFRITZ! USB loading firmware");
-+
-+ if (usb_set_configuration(bfusb->udev, 1) < 0) {
-+ BT_ERR("Can't change to loading configuration");
-+ return -EBUSY;
-+ }
-+
-+ buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
-+ if (!buf) {
-+ BT_ERR("Can't allocate memory chunk for firmware");
-+ return -ENOMEM;
-+ }
-+
-+ pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
-+
-+ while (count) {
-+ size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3);
-+
-+ memcpy(buf, firmware + sent, size);
-+
-+ err = usb_bulk_msg(bfusb->udev, pipe, buf, size,
-+ &len, BFUSB_BLOCK_TIMEOUT);
-+
-+ if (err || (len != size)) {
-+ BT_ERR("Error in firmware loading");
-+ goto error;
-+ }
-+
-+ sent += size;
-+ count -= size;
-+ }
-+
-+ if ((err = usb_bulk_msg(bfusb->udev, pipe, NULL, 0,
-+ &len, BFUSB_BLOCK_TIMEOUT)) < 0) {
-+ BT_ERR("Error in null packet request");
-+ goto error;
-+ }
-+
-+ if ((err = usb_set_configuration(bfusb->udev, 2)) < 0) {
-+ BT_ERR("Can't change to running configuration");
-+ goto error;
-+ }
-+
-+ BT_INFO("BlueFRITZ! USB device ready");
-+
-+ kfree(buf);
-+ return 0;
-+
-+error:
-+ kfree(buf);
-+
-+ pipe = usb_sndctrlpipe(bfusb->udev, 0);
-+
-+ usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
-+ 0, 0, 0, NULL, 0, BFUSB_BLOCK_TIMEOUT);
-+
-+ return err;
-+}
-+
-+static void *bfusb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
-+{
-+ const struct firmware *firmware;
-+ char device[16];
-+ struct usb_interface *iface;
-+ struct usb_interface_descriptor *iface_desc;
-+ struct usb_endpoint_descriptor *bulk_out_ep;
-+ struct usb_endpoint_descriptor *bulk_in_ep;
-+ struct hci_dev *hdev;
-+ struct bfusb *bfusb;
-+
-+ BT_DBG("udev %p ifnum %d id %p", udev, ifnum, id);
-+
-+ /* Check number of endpoints */
-+ iface = &udev->actconfig->interface[0];
-+ iface_desc = &iface->altsetting[0];
-+
-+ if (iface_desc->bNumEndpoints < 2)
-+ return NULL;
-+
-+ bulk_out_ep = &iface_desc->endpoint[0];
-+ bulk_in_ep = &iface_desc->endpoint[1];
-+
-+ if (!bulk_out_ep || !bulk_in_ep) {
-+ BT_ERR("Bulk endpoints not found");
-+ goto done;
-+ }
-+
-+ /* Initialize control structure and load firmware */
-+ if (!(bfusb = kmalloc(sizeof(struct bfusb), GFP_KERNEL))) {
-+ BT_ERR("Can't allocate memory for control structure");
-+ goto done;
-+ }
-+
-+ memset(bfusb, 0, sizeof(struct bfusb));
-+
-+ bfusb->udev = udev;
-+ bfusb->bulk_in_ep = bulk_in_ep->bEndpointAddress;
-+ bfusb->bulk_out_ep = bulk_out_ep->bEndpointAddress;
-+ bfusb->bulk_pkt_size = bulk_out_ep->wMaxPacketSize;
-+
-+ bfusb->lock = RW_LOCK_UNLOCKED;
-+
-+ bfusb->reassembly = NULL;
-+
-+ skb_queue_head_init(&bfusb->transmit_q);
-+ skb_queue_head_init(&bfusb->pending_q);
-+ skb_queue_head_init(&bfusb->completed_q);
-+
-+ snprintf(device, sizeof(device), "bfusb%3.3d%3.3d", udev->bus->busnum, udev->devnum);
-+
-+ if (request_firmware(&firmware, "bfubase.frm", device) < 0) {
-+ BT_ERR("Firmware request failed");
-+ goto error;
-+ }
-+
-+ if (bfusb_load_firmware(bfusb, firmware->data, firmware->size) < 0) {
-+ BT_ERR("Firmware loading failed");
-+ goto release;
-+ }
-+
-+ release_firmware(firmware);
-+
-+ /* Initialize and register HCI device */
-+ hdev = &bfusb->hdev;
-+
-+ hdev->type = HCI_USB;
-+ hdev->driver_data = bfusb;
-+
-+ hdev->open = bfusb_open;
-+ hdev->close = bfusb_close;
-+ hdev->flush = bfusb_flush;
-+ hdev->send = bfusb_send_frame;
-+ hdev->destruct = bfusb_destruct;
-+ hdev->ioctl = bfusb_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ BT_ERR("Can't register HCI device");
-+ goto error;
-+ }
-+
-+ return bfusb;
-+
-+release:
-+ release_firmware(firmware);
-+
-+error:
-+ kfree(bfusb);
-+
-+done:
-+ return NULL;
-+}
-+
-+static void bfusb_disconnect(struct usb_device *udev, void *ptr)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) ptr;
-+ struct hci_dev *hdev = &bfusb->hdev;
-+
-+ BT_DBG("udev %p ptr %p", udev, ptr);
-+
-+ if (!hdev)
-+ return;
-+
-+ bfusb_close(hdev);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ BT_ERR("Can't unregister HCI device %s", hdev->name);
-+}
-+
-+static struct usb_driver bfusb_driver = {
-+ name: "bfusb",
-+ probe: bfusb_probe,
-+ disconnect: bfusb_disconnect,
-+ id_table: bfusb_table,
-+};
-+
-+static int __init bfusb_init(void)
-+{
-+ int err;
-+
-+ BT_INFO("BlueFRITZ! USB driver ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2003 Marcel Holtmann <marcel@holtmann.org>");
-+
-+ if ((err = usb_register(&bfusb_driver)) < 0)
-+ BT_ERR("Failed to register BlueFRITZ! USB driver");
-+
-+ return err;
-+}
-+
-+static void __exit bfusb_cleanup(void)
-+{
-+ usb_deregister(&bfusb_driver);
-+}
-+
-+module_init(bfusb_init);
-+module_exit(bfusb_cleanup);
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/drivers/bluetooth/bluecard_cs.c linux-2.4.18-mh15/drivers/bluetooth/bluecard_cs.c
---- linux-2.4.18/drivers/bluetooth/bluecard_cs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/bluecard_cs.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,1116 @@
-+/*
-+ *
-+ * Bluetooth driver for the Anycom BlueCard (LSE039/LSE041)
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+#include <linux/skbuff.h>
-+#include <asm/io.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0x86bc;
-+static int irq_list[4] = { -1 };
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ driver for the Anycom BlueCard (LSE039/LSE041)");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct bluecard_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+ struct timer_list timer; /* For LED control */
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+
-+ unsigned char ctrl_reg;
-+ unsigned long hw_state; /* Status of the hardware and LED control */
-+} bluecard_info_t;
-+
-+
-+void bluecard_config(dev_link_t *link);
-+void bluecard_release(u_long arg);
-+int bluecard_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "bluecard_cs";
-+
-+dev_link_t *bluecard_attach(void);
-+void bluecard_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+
-+/* Default baud rate: 57600, 115200, 230400 or 460800 */
-+#define DEFAULT_BAUD_RATE 230400
-+
-+
-+/* Hardware states */
-+#define CARD_READY 1
-+#define CARD_HAS_PCCARD_ID 4
-+#define CARD_HAS_POWER_LED 5
-+#define CARD_HAS_ACTIVITY_LED 6
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_BUFFER_NUMBER 5 /* unset = buffer one, set = buffer two */
-+#define XMIT_BUF_ONE_READY 6
-+#define XMIT_BUF_TWO_READY 7
-+#define XMIT_SENDING_READY 8
-+
-+/* Receiver states */
-+#define RECV_WAIT_PACKET_TYPE 0
-+#define RECV_WAIT_EVENT_HEADER 1
-+#define RECV_WAIT_ACL_HEADER 2
-+#define RECV_WAIT_SCO_HEADER 3
-+#define RECV_WAIT_DATA 4
-+
-+/* Special packet types */
-+#define PKT_BAUD_RATE_57600 0x80
-+#define PKT_BAUD_RATE_115200 0x81
-+#define PKT_BAUD_RATE_230400 0x82
-+#define PKT_BAUD_RATE_460800 0x83
-+
-+
-+/* These are the register offsets */
-+#define REG_COMMAND 0x20
-+#define REG_INTERRUPT 0x21
-+#define REG_CONTROL 0x22
-+#define REG_RX_CONTROL 0x24
-+#define REG_CARD_RESET 0x30
-+#define REG_LED_CTRL 0x30
-+
-+/* REG_COMMAND */
-+#define REG_COMMAND_TX_BUF_ONE 0x01
-+#define REG_COMMAND_TX_BUF_TWO 0x02
-+#define REG_COMMAND_RX_BUF_ONE 0x04
-+#define REG_COMMAND_RX_BUF_TWO 0x08
-+#define REG_COMMAND_RX_WIN_ONE 0x00
-+#define REG_COMMAND_RX_WIN_TWO 0x10
-+
-+/* REG_CONTROL */
-+#define REG_CONTROL_BAUD_RATE_57600 0x00
-+#define REG_CONTROL_BAUD_RATE_115200 0x01
-+#define REG_CONTROL_BAUD_RATE_230400 0x02
-+#define REG_CONTROL_BAUD_RATE_460800 0x03
-+#define REG_CONTROL_RTS 0x04
-+#define REG_CONTROL_BT_ON 0x08
-+#define REG_CONTROL_BT_RESET 0x10
-+#define REG_CONTROL_BT_RES_PU 0x20
-+#define REG_CONTROL_INTERRUPT 0x40
-+#define REG_CONTROL_CARD_RESET 0x80
-+
-+/* REG_RX_CONTROL */
-+#define RTS_LEVEL_SHIFT_BITS 0x02
-+
-+
-+
-+/* ======================== LED handling routines ======================== */
-+
-+
-+void bluecard_activity_led_timeout(u_long arg)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)arg;
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) {
-+ /* Disable activity LED */
-+ outb(0x08 | 0x20, iobase + 0x30);
-+ } else {
-+ /* Disable power LED */
-+ outb(0x00, iobase + 0x30);
-+ }
-+}
-+
-+
-+static void bluecard_enable_activity_led(bluecard_info_t *info)
-+{
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) {
-+ /* Enable activity LED */
-+ outb(0x10 | 0x40, iobase + 0x30);
-+
-+ /* Stop the LED after HZ/4 */
-+ mod_timer(&(info->timer), jiffies + HZ / 4);
-+ } else {
-+ /* Enable power LED */
-+ outb(0x08 | 0x20, iobase + 0x30);
-+
-+ /* Stop the LED after HZ/2 */
-+ mod_timer(&(info->timer), jiffies + HZ / 2);
-+ }
-+}
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int bluecard_write(unsigned int iobase, unsigned int offset, __u8 *buf, int len)
-+{
-+ int i, actual;
-+
-+ actual = (len > 15) ? 15 : len;
-+
-+ outb_p(actual, iobase + offset);
-+
-+ for (i = 0; i < actual; i++)
-+ outb_p(buf[i], iobase + offset + i + 1);
-+
-+ return actual;
-+}
-+
-+
-+static void bluecard_write_wakeup(bluecard_info_t *info)
-+{
-+ if (!info) {
-+ printk(KERN_WARNING "bluecard_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (!test_bit(XMIT_SENDING_READY, &(info->tx_state)))
-+ return;
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register unsigned int offset;
-+ register unsigned char command;
-+ register unsigned long ready_bit;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ clear_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ return;
-+
-+ if (test_bit(XMIT_BUFFER_NUMBER, &(info->tx_state))) {
-+ if (!test_bit(XMIT_BUF_TWO_READY, &(info->tx_state)))
-+ break;
-+ offset = 0x10;
-+ command = REG_COMMAND_TX_BUF_TWO;
-+ ready_bit = XMIT_BUF_TWO_READY;
-+ } else {
-+ if (!test_bit(XMIT_BUF_ONE_READY, &(info->tx_state)))
-+ break;
-+ offset = 0x00;
-+ command = REG_COMMAND_TX_BUF_ONE;
-+ ready_bit = XMIT_BUF_ONE_READY;
-+ }
-+
-+ if (!(skb = skb_dequeue(&(info->txq))))
-+ break;
-+
-+ if (skb->pkt_type & 0x80) {
-+ /* Disable RTS */
-+ info->ctrl_reg |= REG_CONTROL_RTS;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+ }
-+
-+ /* Activate LED */
-+ bluecard_enable_activity_led(info);
-+
-+ /* Send frame */
-+ len = bluecard_write(iobase, offset, skb->data, skb->len);
-+
-+ /* Tell the FPGA to send the data */
-+ outb_p(command, iobase + REG_COMMAND);
-+
-+ /* Mark the buffer as dirty */
-+ clear_bit(ready_bit, &(info->tx_state));
-+
-+ if (skb->pkt_type & 0x80) {
-+
-+ wait_queue_head_t wait;
-+ unsigned char baud_reg;
-+
-+ switch (skb->pkt_type) {
-+ case PKT_BAUD_RATE_460800:
-+ baud_reg = REG_CONTROL_BAUD_RATE_460800;
-+ break;
-+ case PKT_BAUD_RATE_230400:
-+ baud_reg = REG_CONTROL_BAUD_RATE_230400;
-+ break;
-+ case PKT_BAUD_RATE_115200:
-+ baud_reg = REG_CONTROL_BAUD_RATE_115200;
-+ break;
-+ case PKT_BAUD_RATE_57600:
-+ /* Fall through... */
-+ default:
-+ baud_reg = REG_CONTROL_BAUD_RATE_57600;
-+ break;
-+ }
-+
-+ /* Wait until the command reaches the baseband */
-+ init_waitqueue_head(&wait);
-+ interruptible_sleep_on_timeout(&wait, HZ / 10);
-+
-+ /* Set baud on baseband */
-+ info->ctrl_reg &= ~0x03;
-+ info->ctrl_reg |= baud_reg;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Enable RTS */
-+ info->ctrl_reg &= ~REG_CONTROL_RTS;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Wait before the next HCI packet can be send */
-+ interruptible_sleep_on_timeout(&wait, HZ);
-+
-+ }
-+
-+ if (len == skb->len) {
-+ kfree_skb(skb);
-+ } else {
-+ skb_pull(skb, len);
-+ skb_queue_head(&(info->txq), skb);
-+ }
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ /* Change buffer */
-+ change_bit(XMIT_BUFFER_NUMBER, &(info->tx_state));
-+
-+ } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
-+
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+}
-+
-+
-+static int bluecard_read(unsigned int iobase, unsigned int offset, __u8 *buf, int size)
-+{
-+ int i, n, len;
-+
-+ outb(REG_COMMAND_RX_WIN_ONE, iobase + REG_COMMAND);
-+
-+ len = inb(iobase + offset);
-+ n = 0;
-+ i = 1;
-+
-+ while (n < len) {
-+
-+ if (i == 16) {
-+ outb(REG_COMMAND_RX_WIN_TWO, iobase + REG_COMMAND);
-+ i = 0;
-+ }
-+
-+ buf[n] = inb(iobase + offset + i);
-+
-+ n++;
-+ i++;
-+
-+ }
-+
-+ return len;
-+}
-+
-+
-+static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
-+{
-+ unsigned int iobase;
-+ unsigned char buf[31];
-+ int i, len;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bluecard_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ if (test_bit(XMIT_SENDING_READY, &(info->tx_state)))
-+ bluecard_enable_activity_led(info);
-+
-+ len = bluecard_read(iobase, offset, buf, sizeof(buf));
-+
-+ for (i = 0; i < len; i++) {
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL) {
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "bluecard_cs: Can't allocate mem for new packet.\n");
-+ return;
-+ }
-+ }
-+
-+ if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
-+
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type = buf[i];
-+
-+ switch (info->rx_skb->pkt_type) {
-+
-+ case 0x00:
-+ /* init packet */
-+ if (offset != 0x00) {
-+ set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
-+ set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
-+ set_bit(XMIT_SENDING_READY, &(info->tx_state));
-+ bluecard_write_wakeup(info);
-+ }
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ case HCI_EVENT_PKT:
-+ info->rx_state = RECV_WAIT_EVENT_HEADER;
-+ info->rx_count = HCI_EVENT_HDR_SIZE;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ info->rx_state = RECV_WAIT_ACL_HEADER;
-+ info->rx_count = HCI_ACL_HDR_SIZE;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ info->rx_state = RECV_WAIT_SCO_HEADER;
-+ info->rx_count = HCI_SCO_HDR_SIZE;
-+ break;
-+
-+ default:
-+ /* unknown packet */
-+ printk(KERN_WARNING "bluecard_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-+ info->hdev.stat.err_rx++;
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ } else {
-+
-+ *skb_put(info->rx_skb, 1) = buf[i];
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ int dlen;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+
-+ switch (info->rx_state) {
-+
-+ case RECV_WAIT_EVENT_HEADER:
-+ eh = (hci_event_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = eh->plen;
-+ break;
-+
-+ case RECV_WAIT_ACL_HEADER:
-+ ah = (hci_acl_hdr *)(info->rx_skb->data);
-+ dlen = __le16_to_cpu(ah->dlen);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = dlen;
-+ break;
-+
-+ case RECV_WAIT_SCO_HEADER:
-+ sh = (hci_sco_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = sh->dlen;
-+ break;
-+
-+ case RECV_WAIT_DATA:
-+ hci_recv_frame(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+
-+ }
-+
-+ info->hdev.stat.byte_rx += len;
-+}
-+
-+
-+void bluecard_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ bluecard_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ unsigned char reg;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bluecard_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ if (!test_bit(CARD_READY, &(info->hw_state)))
-+ return;
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ /* Disable interrupt */
-+ info->ctrl_reg &= ~REG_CONTROL_INTERRUPT;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ reg = inb(iobase + REG_INTERRUPT);
-+
-+ if ((reg != 0x00) && (reg != 0xff)) {
-+
-+ if (reg & 0x04) {
-+ bluecard_receive(info, 0x00);
-+ outb(0x04, iobase + REG_INTERRUPT);
-+ outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
-+ }
-+
-+ if (reg & 0x08) {
-+ bluecard_receive(info, 0x10);
-+ outb(0x08, iobase + REG_INTERRUPT);
-+ outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);
-+ }
-+
-+ if (reg & 0x01) {
-+ set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
-+ outb(0x01, iobase + REG_INTERRUPT);
-+ bluecard_write_wakeup(info);
-+ }
-+
-+ if (reg & 0x02) {
-+ set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
-+ outb(0x02, iobase + REG_INTERRUPT);
-+ bluecard_write_wakeup(info);
-+ }
-+
-+ }
-+
-+ /* Enable interrupt */
-+ info->ctrl_reg |= REG_CONTROL_INTERRUPT;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+
-+
-+/* ======================== Device specific HCI commands ======================== */
-+
-+
-+static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-+ struct sk_buff *skb;
-+
-+ /* Ericsson baud rate command */
-+ unsigned char cmd[] = { HCI_COMMAND_PKT, 0x09, 0xfc, 0x01, 0x03 };
-+
-+ if (!(skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "bluecard_cs: Can't allocate mem for new packet.\n");
-+ return -1;
-+ }
-+
-+ switch (baud) {
-+ case 460800:
-+ cmd[4] = 0x00;
-+ skb->pkt_type = PKT_BAUD_RATE_460800;
-+ break;
-+ case 230400:
-+ cmd[4] = 0x01;
-+ skb->pkt_type = PKT_BAUD_RATE_230400;
-+ break;
-+ case 115200:
-+ cmd[4] = 0x02;
-+ skb->pkt_type = PKT_BAUD_RATE_115200;
-+ break;
-+ case 57600:
-+ /* Fall through... */
-+ default:
-+ cmd[4] = 0x03;
-+ skb->pkt_type = PKT_BAUD_RATE_57600;
-+ break;
-+ }
-+
-+ memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
-+
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ bluecard_write_wakeup(info);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int bluecard_hci_flush(struct hci_dev *hdev)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int bluecard_hci_open(struct hci_dev *hdev)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
-+
-+ if (test_and_set_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ /* Enable LED */
-+ outb(0x08 | 0x20, iobase + 0x30);
-+
-+ return 0;
-+}
-+
-+
-+static int bluecard_hci_close(struct hci_dev *hdev)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ bluecard_hci_flush(hdev);
-+
-+ /* Disable LED */
-+ outb(0x00, iobase + 0x30);
-+
-+ return 0;
-+}
-+
-+
-+static int bluecard_hci_send_frame(struct sk_buff *skb)
-+{
-+ bluecard_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+
-+ if (!hdev) {
-+ printk(KERN_WARNING "bluecard_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (bluecard_info_t *)(hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ bluecard_write_wakeup(info);
-+
-+ return 0;
-+}
-+
-+
-+static void bluecard_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+int bluecard_open(bluecard_info_t *info)
-+{
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev;
-+ unsigned char id;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ init_timer(&(info->timer));
-+ info->timer.function = &bluecard_activity_led_timeout;
-+ info->timer.data = (u_long)info;
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ info->rx_skb = NULL;
-+
-+ id = inb(iobase + 0x30);
-+
-+ if ((id & 0x0f) == 0x02)
-+ set_bit(CARD_HAS_PCCARD_ID, &(info->hw_state));
-+
-+ if (id & 0x10)
-+ set_bit(CARD_HAS_POWER_LED, &(info->hw_state));
-+
-+ if (id & 0x20)
-+ set_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state));
-+
-+ /* Reset card */
-+ info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Turn FPGA off */
-+ outb(0x80, iobase + 0x30);
-+
-+ /* Wait some time */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ / 100);
-+
-+ /* Turn FPGA on */
-+ outb(0x00, iobase + 0x30);
-+
-+ /* Activate card */
-+ info->ctrl_reg = REG_CONTROL_BT_ON | REG_CONTROL_BT_RES_PU;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Enable interrupt */
-+ outb(0xff, iobase + REG_INTERRUPT);
-+ info->ctrl_reg |= REG_CONTROL_INTERRUPT;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Start the RX buffers */
-+ outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
-+ outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);
-+
-+ /* Signal that the hardware is ready */
-+ set_bit(CARD_READY, &(info->hw_state));
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ /* Control the point at which RTS is enabled */
-+ outb((0x0f << RTS_LEVEL_SHIFT_BITS) | 1, iobase + REG_RX_CONTROL);
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout((HZ * 5) / 4); // or set it to 3/2
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = bluecard_hci_open;
-+ hdev->close = bluecard_hci_close;
-+ hdev->flush = bluecard_hci_flush;
-+ hdev->send = bluecard_hci_send_frame;
-+ hdev->destruct = bluecard_hci_destruct;
-+ hdev->ioctl = bluecard_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_WARNING "bluecard_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int bluecard_close(bluecard_info_t *info)
-+{
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ if (info->link.state & DEV_CONFIG_PENDING)
-+ return -ENODEV;
-+
-+ bluecard_hci_close(hdev);
-+
-+ clear_bit(CARD_READY, &(info->hw_state));
-+
-+ /* Reset card */
-+ info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Turn FPGA off */
-+ outb(0x80, iobase + 0x30);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_WARNING "bluecard_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+dev_link_t *bluecard_attach(void)
-+{
-+ bluecard_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &bluecard_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = bluecard_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.Vcc = 50;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &bluecard_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ bluecard_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+void bluecard_detach(dev_link_t *link)
-+{
-+ bluecard_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+ if (link->state & DEV_CONFIG)
-+ bluecard_release((u_long)link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+void bluecard_config(dev_link_t *link)
-+{
-+ client_handle_t handle = link->handle;
-+ bluecard_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ config_info_t config;
-+ int i, n, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ link->conf.ConfigIndex = 0x20;
-+ link->io.NumPorts1 = 64;
-+ link->io.IOAddrLines = 6;
-+
-+ for (n = 0; n < 0x400; n += 0x40) {
-+ link->io.BasePort1 = n ^ 0x300;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ break;
-+ }
-+
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (bluecard_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ bluecard_release((u_long)link);
-+}
-+
-+
-+void bluecard_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *)arg;
-+ bluecard_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ bluecard_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+int bluecard_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ bluecard_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ bluecard_close(info);
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ bluecard_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG)
-+ CardServices(ReleaseConfiguration, link->handle);
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (DEV_OK(link))
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_bluecard_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "bluecard_cs: Card Services release does not match!\n");
-+ return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &bluecard_attach, &bluecard_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_bluecard_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ bluecard_detach(dev_list);
-+}
-+
-+
-+module_init(init_bluecard_cs);
-+module_exit(exit_bluecard_cs);
-+
-+EXPORT_NO_SYMBOLS;
-diff -urN linux-2.4.18/drivers/bluetooth/bt3c_cs.c linux-2.4.18-mh15/drivers/bluetooth/bt3c_cs.c
---- linux-2.4.18/drivers/bluetooth/bt3c_cs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/bt3c_cs.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,986 @@
-+/*
-+ *
-+ * Driver for the 3Com Bluetooth PCMCIA card
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ * Jose Orlando Pereira <jop@di.uminho.pt>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/kmod.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/delay.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/unistd.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+
-+#include <linux/skbuff.h>
-+#include <linux/string.h>
-+#include <linux/serial.h>
-+#include <linux/serial_reg.h>
-+#include <asm/system.h>
-+#include <asm/bitops.h>
-+#include <asm/io.h>
-+
-+#include <linux/firmware.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0xffff;
-+static int irq_list[4] = { -1 };
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>, Jose Orlando Pereira <jop@di.uminho.pt>");
-+MODULE_DESCRIPTION("BlueZ driver for the 3Com Bluetooth PCMCIA card");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct bt3c_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+} bt3c_info_t;
-+
-+
-+void bt3c_config(dev_link_t *link);
-+void bt3c_release(u_long arg);
-+int bt3c_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "bt3c_cs";
-+
-+dev_link_t *bt3c_attach(void);
-+void bt3c_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_WAITING 8
-+
-+/* Receiver states */
-+#define RECV_WAIT_PACKET_TYPE 0
-+#define RECV_WAIT_EVENT_HEADER 1
-+#define RECV_WAIT_ACL_HEADER 2
-+#define RECV_WAIT_SCO_HEADER 3
-+#define RECV_WAIT_DATA 4
-+
-+
-+
-+/* ======================== Special I/O functions ======================== */
-+
-+
-+#define DATA_L 0
-+#define DATA_H 1
-+#define ADDR_L 2
-+#define ADDR_H 3
-+#define CONTROL 4
-+
-+
-+inline void bt3c_address(unsigned int iobase, unsigned short addr)
-+{
-+ outb(addr & 0xff, iobase + ADDR_L);
-+ outb((addr >> 8) & 0xff, iobase + ADDR_H);
-+}
-+
-+
-+inline void bt3c_put(unsigned int iobase, unsigned short value)
-+{
-+ outb(value & 0xff, iobase + DATA_L);
-+ outb((value >> 8) & 0xff, iobase + DATA_H);
-+}
-+
-+
-+inline void bt3c_io_write(unsigned int iobase, unsigned short addr, unsigned short value)
-+{
-+ bt3c_address(iobase, addr);
-+ bt3c_put(iobase, value);
-+}
-+
-+
-+inline unsigned short bt3c_get(unsigned int iobase)
-+{
-+ unsigned short value = inb(iobase + DATA_L);
-+
-+ value |= inb(iobase + DATA_H) << 8;
-+
-+ return value;
-+}
-+
-+
-+inline unsigned short bt3c_read(unsigned int iobase, unsigned short addr)
-+{
-+ bt3c_address(iobase, addr);
-+
-+ return bt3c_get(iobase);
-+}
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int bt3c_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
-+{
-+ int actual = 0;
-+
-+ bt3c_address(iobase, 0x7080);
-+
-+ /* Fill FIFO with current frame */
-+ while (actual < len) {
-+ /* Transmit next byte */
-+ bt3c_put(iobase, buf[actual]);
-+ actual++;
-+ }
-+
-+ bt3c_io_write(iobase, 0x7005, actual);
-+
-+ return actual;
-+}
-+
-+
-+static void bt3c_write_wakeup(bt3c_info_t *info, int from)
-+{
-+ unsigned long flags;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bt3c_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state)))
-+ return;
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ break;
-+
-+
-+ if (!(skb = skb_dequeue(&(info->txq)))) {
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+ break;
-+ }
-+
-+ /* Send frame */
-+ len = bt3c_write(iobase, 256, skb->data, skb->len);
-+
-+ if (len != skb->len) {
-+ printk(KERN_WARNING "bt3c_cs: very strange\n");
-+ }
-+
-+ kfree_skb(skb);
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ } while (0);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+}
-+
-+
-+static void bt3c_receive(bt3c_info_t *info)
-+{
-+ unsigned int iobase;
-+ int size = 0, avail;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bt3c_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ avail = bt3c_read(iobase, 0x7006);
-+ //printk("bt3c_cs: receiving %d bytes\n", avail);
-+
-+ bt3c_address(iobase, 0x7480);
-+ while (size < avail) {
-+ size++;
-+ info->hdev.stat.byte_rx++;
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL) {
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "bt3c_cs: Can't allocate mem for new packet.\n");
-+ return;
-+ }
-+ }
-+
-+
-+ if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
-+
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type = inb(iobase + DATA_L);
-+ inb(iobase + DATA_H);
-+ //printk("bt3c: PACKET_TYPE=%02x\n", info->rx_skb->pkt_type);
-+
-+ switch (info->rx_skb->pkt_type) {
-+
-+ case HCI_EVENT_PKT:
-+ info->rx_state = RECV_WAIT_EVENT_HEADER;
-+ info->rx_count = HCI_EVENT_HDR_SIZE;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ info->rx_state = RECV_WAIT_ACL_HEADER;
-+ info->rx_count = HCI_ACL_HDR_SIZE;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ info->rx_state = RECV_WAIT_SCO_HEADER;
-+ info->rx_count = HCI_SCO_HDR_SIZE;
-+ break;
-+
-+ default:
-+ /* Unknown packet */
-+ printk(KERN_WARNING "bt3c_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-+ info->hdev.stat.err_rx++;
-+ clear_bit(HCI_RUNNING, &(info->hdev.flags));
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ } else {
-+
-+ __u8 x = inb(iobase + DATA_L);
-+
-+ *skb_put(info->rx_skb, 1) = x;
-+ inb(iobase + DATA_H);
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ int dlen;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+
-+ switch (info->rx_state) {
-+
-+ case RECV_WAIT_EVENT_HEADER:
-+ eh = (hci_event_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = eh->plen;
-+ break;
-+
-+ case RECV_WAIT_ACL_HEADER:
-+ ah = (hci_acl_hdr *)(info->rx_skb->data);
-+ dlen = __le16_to_cpu(ah->dlen);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = dlen;
-+ break;
-+
-+ case RECV_WAIT_SCO_HEADER:
-+ sh = (hci_sco_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = sh->dlen;
-+ break;
-+
-+ case RECV_WAIT_DATA:
-+ hci_recv_frame(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+ bt3c_io_write(iobase, 0x7006, 0x0000);
-+}
-+
-+
-+void bt3c_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ bt3c_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ int iir;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bt3c_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ iir = inb(iobase + CONTROL);
-+ if (iir & 0x80) {
-+ int stat = bt3c_read(iobase, 0x7001);
-+
-+ if ((stat & 0xff) == 0x7f) {
-+ printk(KERN_WARNING "bt3c_cs: STRANGE stat=%04x\n", stat);
-+ } else if ((stat & 0xff) != 0xff) {
-+ if (stat & 0x0020) {
-+ int stat = bt3c_read(iobase, 0x7002) & 0x10;
-+ printk(KERN_WARNING "bt3c_cs: antena %s\n", stat ? "OUT" : "IN");
-+ }
-+ if (stat & 0x0001)
-+ bt3c_receive(info);
-+ if (stat & 0x0002) {
-+ //printk("bt3c_cs: ACK %04x\n", stat);
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+ bt3c_write_wakeup(info, 1);
-+ }
-+
-+ bt3c_io_write(iobase, 0x7001, 0x0000);
-+
-+ outb(iir, iobase + CONTROL);
-+ }
-+ }
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int bt3c_hci_flush(struct hci_dev *hdev)
-+{
-+ bt3c_info_t *info = (bt3c_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int bt3c_hci_open(struct hci_dev *hdev)
-+{
-+ set_bit(HCI_RUNNING, &(hdev->flags));
-+
-+ return 0;
-+}
-+
-+
-+static int bt3c_hci_close(struct hci_dev *hdev)
-+{
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ bt3c_hci_flush(hdev);
-+
-+ return 0;
-+}
-+
-+
-+static int bt3c_hci_send_frame(struct sk_buff *skb)
-+{
-+ bt3c_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+
-+ if (!hdev) {
-+ printk(KERN_WARNING "bt3c_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (bt3c_info_t *) (hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ bt3c_write_wakeup(info, 0);
-+
-+ return 0;
-+}
-+
-+
-+static void bt3c_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+static int bt3c_load_firmware(bt3c_info_t *info, unsigned char *firmware, int count)
-+{
-+ char *ptr = (char *) firmware;
-+ char b[9];
-+ unsigned int iobase, size, addr, fcs, tmp;
-+ int i, err = 0;
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ /* Reset */
-+
-+ bt3c_io_write(iobase, 0x8040, 0x0404);
-+ bt3c_io_write(iobase, 0x8040, 0x0400);
-+
-+ udelay(1);
-+
-+ bt3c_io_write(iobase, 0x8040, 0x0404);
-+
-+ udelay(17);
-+
-+ /* Load */
-+
-+ while (count) {
-+ if (ptr[0] != 'S') {
-+ printk(KERN_WARNING "bt3c_cs: Bad address in firmware.\n");
-+ err = -EFAULT;
-+ goto error;
-+ }
-+
-+ memset(b, 0, sizeof(b));
-+ memcpy(b, ptr + 2, 2);
-+ size = simple_strtol(b, NULL, 16);
-+
-+ memset(b, 0, sizeof(b));
-+ memcpy(b, ptr + 4, 8);
-+ addr = simple_strtol(b, NULL, 16);
-+
-+ memset(b, 0, sizeof(b));
-+ memcpy(b, ptr + (size * 2) + 2, 2);
-+ fcs = simple_strtol(b, NULL, 16);
-+
-+ memset(b, 0, sizeof(b));
-+ for (tmp = 0, i = 0; i < size; i++) {
-+ memcpy(b, ptr + (i * 2) + 2, 2);
-+ tmp += simple_strtol(b, NULL, 16);
-+ }
-+
-+ if (((tmp + fcs) & 0xff) != 0xff) {
-+ printk(KERN_WARNING "bt3c_cs: Checksum error in firmware.\n");
-+ err = -EILSEQ;
-+ goto error;
-+ }
-+
-+ if (ptr[1] == '3') {
-+ bt3c_address(iobase, addr);
-+
-+ memset(b, 0, sizeof(b));
-+ for (i = 0; i < (size - 4) / 2; i++) {
-+ memcpy(b, ptr + (i * 4) + 12, 4);
-+ tmp = simple_strtol(b, NULL, 16);
-+ bt3c_put(iobase, tmp);
-+ }
-+ }
-+
-+ ptr += (size * 2) + 6;
-+ count -= (size * 2) + 6;
-+ }
-+
-+ udelay(17);
-+
-+ /* Boot */
-+
-+ bt3c_address(iobase, 0x3000);
-+ outb(inb(iobase + CONTROL) | 0x40, iobase + CONTROL);
-+
-+error:
-+ udelay(17);
-+
-+ /* Clear */
-+
-+ bt3c_io_write(iobase, 0x7006, 0x0000);
-+ bt3c_io_write(iobase, 0x7005, 0x0000);
-+ bt3c_io_write(iobase, 0x7001, 0x0000);
-+
-+ return err;
-+}
-+
-+
-+int bt3c_open(bt3c_info_t *info)
-+{
-+ const struct firmware *firmware;
-+ char device[16];
-+ struct hci_dev *hdev;
-+ int err;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ info->rx_skb = NULL;
-+
-+ /* Load firmware */
-+
-+ snprintf(device, sizeof(device), "bt3c%4.4x", info->link.io.BasePort1);
-+
-+ err = request_firmware(&firmware, "BT3CPCC.bin", device);
-+ if (err < 0) {
-+ printk(KERN_WARNING "bt3c_cs: Firmware request failed.\n");
-+ return err;
-+ }
-+
-+ err = bt3c_load_firmware(info, firmware->data, firmware->size);
-+
-+ release_firmware(firmware);
-+
-+ if (err < 0) {
-+ printk(KERN_WARNING "bt3c_cs: Firmware loading failed.\n");
-+ return err;
-+ }
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ);
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = bt3c_hci_open;
-+ hdev->close = bt3c_hci_close;
-+ hdev->flush = bt3c_hci_flush;
-+ hdev->send = bt3c_hci_send_frame;
-+ hdev->destruct = bt3c_hci_destruct;
-+ hdev->ioctl = bt3c_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_WARNING "bt3c_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int bt3c_close(bt3c_info_t *info)
-+{
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ if (info->link.state & DEV_CONFIG_PENDING)
-+ return -ENODEV;
-+
-+ bt3c_hci_close(hdev);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_WARNING "bt3c_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+dev_link_t *bt3c_attach(void)
-+{
-+ bt3c_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &bt3c_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = bt3c_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.Vcc = 50;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &bt3c_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ bt3c_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+void bt3c_detach(dev_link_t *link)
-+{
-+ bt3c_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+
-+ if (link->state & DEV_CONFIG)
-+ bt3c_release((u_long)link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+void bt3c_config(dev_link_t *link)
-+{
-+ static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
-+ client_handle_t handle = link->handle;
-+ bt3c_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
-+ int i, j, try, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ /* First pass: look for a config entry that looks normal. */
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-+ /* Two tries: without IO aliases, then with aliases */
-+ for (try = 0; try < 2; try++) {
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if (i != CS_SUCCESS)
-+ goto next_entry;
-+ if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
-+ link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-+ if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
-+ link->conf.ConfigIndex = cf->index;
-+ link->io.BasePort1 = cf->io.win[0].base;
-+ link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+next_entry:
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+ }
-+
-+ /* Second pass: try to find an entry that isn't picky about
-+ its base address, then try to grab any standard serial port
-+ address, and finally try to get any free port. */
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
-+ link->conf.ConfigIndex = cf->index;
-+ for (j = 0; j < 5; j++) {
-+ link->io.BasePort1 = base[j];
-+ link->io.IOAddrLines = base[j] ? 16 : 3;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+ }
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+
-+found_port:
-+ if (i != CS_SUCCESS) {
-+ printk(KERN_NOTICE "bt3c_cs: No usable port range found. Giving up.\n");
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (bt3c_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ bt3c_release((u_long)link);
-+}
-+
-+
-+void bt3c_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *)arg;
-+ bt3c_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ bt3c_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+int bt3c_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ bt3c_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ bt3c_close(info);
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ bt3c_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG)
-+ CardServices(ReleaseConfiguration, link->handle);
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (DEV_OK(link))
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_bt3c_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "bt3c_cs: Card Services release does not match!\n");
-+ return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &bt3c_attach, &bt3c_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_bt3c_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ bt3c_detach(dev_list);
-+}
-+
-+
-+module_init(init_bt3c_cs);
-+module_exit(exit_bt3c_cs);
-+
-+EXPORT_NO_SYMBOLS;
-diff -urN linux-2.4.18/drivers/bluetooth/btuart_cs.c linux-2.4.18-mh15/drivers/bluetooth/btuart_cs.c
---- linux-2.4.18/drivers/bluetooth/btuart_cs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/btuart_cs.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,909 @@
-+/*
-+ *
-+ * Driver for Bluetooth PCMCIA cards with HCI UART interface
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+
-+#include <linux/skbuff.h>
-+#include <linux/string.h>
-+#include <linux/serial.h>
-+#include <linux/serial_reg.h>
-+#include <asm/system.h>
-+#include <asm/bitops.h>
-+#include <asm/io.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0xffff;
-+static int irq_list[4] = { -1 };
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ driver for Bluetooth PCMCIA cards with HCI UART interface");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct btuart_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+} btuart_info_t;
-+
-+
-+void btuart_config(dev_link_t *link);
-+void btuart_release(u_long arg);
-+int btuart_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "btuart_cs";
-+
-+dev_link_t *btuart_attach(void);
-+void btuart_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+
-+/* Maximum baud rate */
-+#define SPEED_MAX 115200
-+
-+/* Default baud rate: 57600, 115200, 230400 or 460800 */
-+#define DEFAULT_BAUD_RATE 115200
-+
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_WAITING 8
-+
-+/* Receiver states */
-+#define RECV_WAIT_PACKET_TYPE 0
-+#define RECV_WAIT_EVENT_HEADER 1
-+#define RECV_WAIT_ACL_HEADER 2
-+#define RECV_WAIT_SCO_HEADER 3
-+#define RECV_WAIT_DATA 4
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int btuart_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
-+{
-+ int actual = 0;
-+
-+ /* Tx FIFO should be empty */
-+ if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
-+ return 0;
-+
-+ /* Fill FIFO with current frame */
-+ while ((fifo_size-- > 0) && (actual < len)) {
-+ /* Transmit next byte */
-+ outb(buf[actual], iobase + UART_TX);
-+ actual++;
-+ }
-+
-+ return actual;
-+}
-+
-+
-+static void btuart_write_wakeup(btuart_info_t *info)
-+{
-+ if (!info) {
-+ printk(KERN_WARNING "btuart_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ clear_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ return;
-+
-+ if (!(skb = skb_dequeue(&(info->txq))))
-+ break;
-+
-+ /* Send frame */
-+ len = btuart_write(iobase, 16, skb->data, skb->len);
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (len == skb->len) {
-+ kfree_skb(skb);
-+ } else {
-+ skb_pull(skb, len);
-+ skb_queue_head(&(info->txq), skb);
-+ }
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
-+
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+}
-+
-+
-+static void btuart_receive(btuart_info_t *info)
-+{
-+ unsigned int iobase;
-+ int boguscount = 0;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "btuart_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ do {
-+ info->hdev.stat.byte_rx++;
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL) {
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "btuart_cs: Can't allocate mem for new packet.\n");
-+ return;
-+ }
-+ }
-+
-+ if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
-+
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type = inb(iobase + UART_RX);
-+
-+ switch (info->rx_skb->pkt_type) {
-+
-+ case HCI_EVENT_PKT:
-+ info->rx_state = RECV_WAIT_EVENT_HEADER;
-+ info->rx_count = HCI_EVENT_HDR_SIZE;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ info->rx_state = RECV_WAIT_ACL_HEADER;
-+ info->rx_count = HCI_ACL_HDR_SIZE;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ info->rx_state = RECV_WAIT_SCO_HEADER;
-+ info->rx_count = HCI_SCO_HDR_SIZE;
-+ break;
-+
-+ default:
-+ /* Unknown packet */
-+ printk(KERN_WARNING "btuart_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-+ info->hdev.stat.err_rx++;
-+ clear_bit(HCI_RUNNING, &(info->hdev.flags));
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ } else {
-+
-+ *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ int dlen;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+
-+
-+ switch (info->rx_state) {
-+
-+ case RECV_WAIT_EVENT_HEADER:
-+ eh = (hci_event_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = eh->plen;
-+ break;
-+
-+ case RECV_WAIT_ACL_HEADER:
-+ ah = (hci_acl_hdr *)(info->rx_skb->data);
-+ dlen = __le16_to_cpu(ah->dlen);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = dlen;
-+ break;
-+
-+ case RECV_WAIT_SCO_HEADER:
-+ sh = (hci_sco_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = sh->dlen;
-+ break;
-+
-+ case RECV_WAIT_DATA:
-+ hci_recv_frame(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+ /* Make sure we don't stay here to long */
-+ if (boguscount++ > 16)
-+ break;
-+
-+ } while (inb(iobase + UART_LSR) & UART_LSR_DR);
-+}
-+
-+
-+void btuart_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ btuart_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ int boguscount = 0;
-+ int iir, lsr;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "btuart_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-+ while (iir) {
-+
-+ /* Clear interrupt */
-+ lsr = inb(iobase + UART_LSR);
-+
-+ switch (iir) {
-+ case UART_IIR_RLSI:
-+ printk(KERN_NOTICE "btuart_cs: RLSI\n");
-+ break;
-+ case UART_IIR_RDI:
-+ /* Receive interrupt */
-+ btuart_receive(info);
-+ break;
-+ case UART_IIR_THRI:
-+ if (lsr & UART_LSR_THRE) {
-+ /* Transmitter ready for data */
-+ btuart_write_wakeup(info);
-+ }
-+ break;
-+ default:
-+ printk(KERN_NOTICE "btuart_cs: Unhandled IIR=%#x\n", iir);
-+ break;
-+ }
-+
-+ /* Make sure we don't stay here to long */
-+ if (boguscount++ > 100)
-+ break;
-+
-+ iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-+
-+ }
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+
-+static void btuart_change_speed(btuart_info_t *info, unsigned int speed)
-+{
-+ unsigned long flags;
-+ unsigned int iobase;
-+ int fcr; /* FIFO control reg */
-+ int lcr; /* Line control reg */
-+ int divisor;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "btuart_cs: Call of change speed for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ divisor = SPEED_MAX / speed;
-+
-+ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT;
-+
-+ /*
-+ * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and
-+ * almost 1,7 ms at 19200 bps. At speeds above that we can just forget
-+ * about this timeout since it will always be fast enough.
-+ */
-+
-+ if (speed < 38400)
-+ fcr |= UART_FCR_TRIGGER_1;
-+ else
-+ fcr |= UART_FCR_TRIGGER_14;
-+
-+ /* Bluetooth cards use 8N1 */
-+ lcr = UART_LCR_WLEN8;
-+
-+ outb(UART_LCR_DLAB | lcr, iobase + UART_LCR); /* Set DLAB */
-+ outb(divisor & 0xff, iobase + UART_DLL); /* Set speed */
-+ outb(divisor >> 8, iobase + UART_DLM);
-+ outb(lcr, iobase + UART_LCR); /* Set 8N1 */
-+ outb(fcr, iobase + UART_FCR); /* Enable FIFO's */
-+
-+ /* Turn on interrups */
-+ outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+}
-+
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int btuart_hci_flush(struct hci_dev *hdev)
-+{
-+ btuart_info_t *info = (btuart_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int btuart_hci_open(struct hci_dev *hdev)
-+{
-+ set_bit(HCI_RUNNING, &(hdev->flags));
-+
-+ return 0;
-+}
-+
-+
-+static int btuart_hci_close(struct hci_dev *hdev)
-+{
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ btuart_hci_flush(hdev);
-+
-+ return 0;
-+}
-+
-+
-+static int btuart_hci_send_frame(struct sk_buff *skb)
-+{
-+ btuart_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+
-+ if (!hdev) {
-+ printk(KERN_WARNING "btuart_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (btuart_info_t *)(hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ btuart_write_wakeup(info);
-+
-+ return 0;
-+}
-+
-+
-+static void btuart_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+int btuart_open(btuart_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ info->rx_skb = NULL;
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Reset UART */
-+ outb(0, iobase + UART_MCR);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ /* Initialize UART */
-+ outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
-+ outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
-+
-+ /* Turn on interrupts */
-+ // outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ btuart_change_speed(info, DEFAULT_BAUD_RATE);
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ);
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = btuart_hci_open;
-+ hdev->close = btuart_hci_close;
-+ hdev->flush = btuart_hci_flush;
-+ hdev->send = btuart_hci_send_frame;
-+ hdev->destruct = btuart_hci_destruct;
-+ hdev->ioctl = btuart_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_WARNING "btuart_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int btuart_close(btuart_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ if (info->link.state & DEV_CONFIG_PENDING)
-+ return -ENODEV;
-+
-+ btuart_hci_close(hdev);
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Reset UART */
-+ outb(0, iobase + UART_MCR);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_WARNING "btuart_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+dev_link_t *btuart_attach(void)
-+{
-+ btuart_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &btuart_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = btuart_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.Vcc = 50;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &btuart_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ btuart_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+void btuart_detach(dev_link_t *link)
-+{
-+ btuart_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+ if (link->state & DEV_CONFIG)
-+ btuart_release((u_long)link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+void btuart_config(dev_link_t *link)
-+{
-+ static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
-+ client_handle_t handle = link->handle;
-+ btuart_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
-+ int i, j, try, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ /* First pass: look for a config entry that looks normal. */
-+ tuple.TupleData = (cisdata_t *) buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-+ /* Two tries: without IO aliases, then with aliases */
-+ for (try = 0; try < 2; try++) {
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if (i != CS_SUCCESS)
-+ goto next_entry;
-+ if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
-+ link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-+ if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
-+ link->conf.ConfigIndex = cf->index;
-+ link->io.BasePort1 = cf->io.win[0].base;
-+ link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+next_entry:
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+ }
-+
-+ /* Second pass: try to find an entry that isn't picky about
-+ its base address, then try to grab any standard serial port
-+ address, and finally try to get any free port. */
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if ((i == CS_SUCCESS) && (cf->io.nwin > 0)
-+ && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
-+ link->conf.ConfigIndex = cf->index;
-+ for (j = 0; j < 5; j++) {
-+ link->io.BasePort1 = base[j];
-+ link->io.IOAddrLines = base[j] ? 16 : 3;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+ }
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+
-+found_port:
-+ if (i != CS_SUCCESS) {
-+ printk(KERN_NOTICE "btuart_cs: No usable port range found. Giving up.\n");
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (btuart_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ btuart_release((u_long) link);
-+}
-+
-+
-+void btuart_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *)arg;
-+ btuart_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ btuart_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+int btuart_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ btuart_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ btuart_close(info);
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ btuart_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG)
-+ CardServices(ReleaseConfiguration, link->handle);
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (DEV_OK(link))
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_btuart_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "btuart_cs: Card Services release does not match!\n");
-+ return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &btuart_attach, &btuart_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_btuart_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ btuart_detach(dev_list);
-+}
-+
-+
-+module_init(init_btuart_cs);
-+module_exit(exit_btuart_cs);
-+
-+EXPORT_NO_SYMBOLS;
-diff -urN linux-2.4.18/drivers/bluetooth/Config.in linux-2.4.18-mh15/drivers/bluetooth/Config.in
---- linux-2.4.18/drivers/bluetooth/Config.in 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/drivers/bluetooth/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -1,8 +1,33 @@
-+#
-+# Bluetooth HCI device drivers configuration
-+#
-+
- mainmenu_option next_comment
- comment 'Bluetooth device drivers'
-
- dep_tristate 'HCI USB driver' CONFIG_BLUEZ_HCIUSB $CONFIG_BLUEZ $CONFIG_USB
-+if [ "$CONFIG_BLUEZ_HCIUSB" != "n" ]; then
-+ bool ' SCO (voice) support' CONFIG_BLUEZ_HCIUSB_SCO
-+fi
-+
- dep_tristate 'HCI UART driver' CONFIG_BLUEZ_HCIUART $CONFIG_BLUEZ
--dep_tristate 'HCI VHCI virtual HCI device driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
-+if [ "$CONFIG_BLUEZ_HCIUART" != "n" ]; then
-+ bool ' UART (H4) protocol support' CONFIG_BLUEZ_HCIUART_H4
-+ bool ' BCSP protocol support' CONFIG_BLUEZ_HCIUART_BCSP
-+ dep_bool ' Transmit CRC with every BCSP packet' CONFIG_BLUEZ_HCIUART_BCSP_TXCRC $CONFIG_BLUEZ_HCIUART_BCSP
-+fi
-+
-+dep_tristate 'HCI BlueFRITZ! USB driver' CONFIG_BLUEZ_HCIBFUSB $CONFIG_BLUEZ $CONFIG_USB
-+
-+dep_tristate 'HCI DTL1 (PC Card) driver' CONFIG_BLUEZ_HCIDTL1 $CONFIG_PCMCIA $CONFIG_BLUEZ
-+
-+dep_tristate 'HCI BT3C (PC Card) driver' CONFIG_BLUEZ_HCIBT3C $CONFIG_PCMCIA $CONFIG_BLUEZ
-+
-+dep_tristate 'HCI BlueCard (PC Card) driver' CONFIG_BLUEZ_HCIBLUECARD $CONFIG_PCMCIA $CONFIG_BLUEZ
-+
-+dep_tristate 'HCI UART (PC Card) driver' CONFIG_BLUEZ_HCIBTUART $CONFIG_PCMCIA $CONFIG_BLUEZ
-+
-+dep_tristate 'HCI VHCI (Virtual HCI device) driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
-
- endmenu
-+
-diff -urN linux-2.4.18/drivers/bluetooth/dtl1_cs.c linux-2.4.18-mh15/drivers/bluetooth/dtl1_cs.c
---- linux-2.4.18/drivers/bluetooth/dtl1_cs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/dtl1_cs.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,861 @@
-+/*
-+ *
-+ * A driver for Nokia Connectivity Card DTL-1 devices
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+
-+#include <linux/skbuff.h>
-+#include <linux/string.h>
-+#include <linux/serial.h>
-+#include <linux/serial_reg.h>
-+#include <asm/system.h>
-+#include <asm/bitops.h>
-+#include <asm/io.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0xffff;
-+static int irq_list[4] = { -1 };
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ driver for Nokia Connectivity Card DTL-1");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct dtl1_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+
-+ unsigned long flowmask; /* HCI flow mask */
-+ int ri_latch;
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+} dtl1_info_t;
-+
-+
-+void dtl1_config(dev_link_t *link);
-+void dtl1_release(u_long arg);
-+int dtl1_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "dtl1_cs";
-+
-+dev_link_t *dtl1_attach(void);
-+void dtl1_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_WAITING 8
-+
-+/* Receiver States */
-+#define RECV_WAIT_NSH 0
-+#define RECV_WAIT_DATA 1
-+
-+
-+typedef struct {
-+ u8 type;
-+ u8 zero;
-+ u16 len;
-+} __attribute__ ((packed)) nsh_t; /* Nokia Specific Header */
-+
-+#define NSHL 4 /* Nokia Specific Header Length */
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int dtl1_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
-+{
-+ int actual = 0;
-+
-+ /* Tx FIFO should be empty */
-+ if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
-+ return 0;
-+
-+ /* Fill FIFO with current frame */
-+ while ((fifo_size-- > 0) && (actual < len)) {
-+ /* Transmit next byte */
-+ outb(buf[actual], iobase + UART_TX);
-+ actual++;
-+ }
-+
-+ return actual;
-+}
-+
-+
-+static void dtl1_write_wakeup(dtl1_info_t *info)
-+{
-+ if (!info) {
-+ printk(KERN_WARNING "dtl1_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (test_bit(XMIT_WAITING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ clear_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ return;
-+
-+ if (!(skb = skb_dequeue(&(info->txq))))
-+ break;
-+
-+ /* Send frame */
-+ len = dtl1_write(iobase, 32, skb->data, skb->len);
-+
-+ if (len == skb->len) {
-+ set_bit(XMIT_WAITING, &(info->tx_state));
-+ kfree_skb(skb);
-+ } else {
-+ skb_pull(skb, len);
-+ skb_queue_head(&(info->txq), skb);
-+ }
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
-+
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+}
-+
-+
-+static void dtl1_control(dtl1_info_t *info, struct sk_buff *skb)
-+{
-+ u8 flowmask = *(u8 *)skb->data;
-+ int i;
-+
-+ printk(KERN_INFO "dtl1_cs: Nokia control data = ");
-+ for (i = 0; i < skb->len; i++) {
-+ printk("%02x ", skb->data[i]);
-+ }
-+ printk("\n");
-+
-+ /* transition to active state */
-+ if (((info->flowmask & 0x07) == 0) && ((flowmask & 0x07) != 0)) {
-+ clear_bit(XMIT_WAITING, &(info->tx_state));
-+ dtl1_write_wakeup(info);
-+ }
-+
-+ info->flowmask = flowmask;
-+
-+ kfree_skb(skb);
-+}
-+
-+
-+static void dtl1_receive(dtl1_info_t *info)
-+{
-+ unsigned int iobase;
-+ nsh_t *nsh;
-+ int boguscount = 0;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "dtl1_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ do {
-+ info->hdev.stat.byte_rx++;
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL)
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "dtl1_cs: Can't allocate mem for new packet.\n");
-+ info->rx_state = RECV_WAIT_NSH;
-+ info->rx_count = NSHL;
-+ return;
-+ }
-+
-+ *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
-+ nsh = (nsh_t *)info->rx_skb->data;
-+
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ switch (info->rx_state) {
-+ case RECV_WAIT_NSH:
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = nsh->len + (nsh->len & 0x0001);
-+ break;
-+ case RECV_WAIT_DATA:
-+ info->rx_skb->pkt_type = nsh->type;
-+
-+ /* remove PAD byte if it exists */
-+ if (nsh->len & 0x0001) {
-+ info->rx_skb->tail--;
-+ info->rx_skb->len--;
-+ }
-+
-+ /* remove NSH */
-+ skb_pull(info->rx_skb, NSHL);
-+
-+ switch (info->rx_skb->pkt_type) {
-+ case 0x80:
-+ /* control data for the Nokia Card */
-+ dtl1_control(info, info->rx_skb);
-+ break;
-+ case 0x82:
-+ case 0x83:
-+ case 0x84:
-+ /* send frame to the HCI layer */
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type &= 0x0f;
-+ hci_recv_frame(info->rx_skb);
-+ break;
-+ default:
-+ /* unknown packet */
-+ printk(KERN_WARNING "dtl1_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-+ kfree_skb(info->rx_skb);
-+ break;
-+ }
-+
-+ info->rx_state = RECV_WAIT_NSH;
-+ info->rx_count = NSHL;
-+ info->rx_skb = NULL;
-+ break;
-+ }
-+
-+ }
-+
-+ /* Make sure we don't stay here to long */
-+ if (boguscount++ > 32)
-+ break;
-+
-+ } while (inb(iobase + UART_LSR) & UART_LSR_DR);
-+}
-+
-+
-+void dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ dtl1_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ unsigned char msr;
-+ int boguscount = 0;
-+ int iir, lsr;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "dtl1_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-+ while (iir) {
-+
-+ /* Clear interrupt */
-+ lsr = inb(iobase + UART_LSR);
-+
-+ switch (iir) {
-+ case UART_IIR_RLSI:
-+ printk(KERN_NOTICE "dtl1_cs: RLSI\n");
-+ break;
-+ case UART_IIR_RDI:
-+ /* Receive interrupt */
-+ dtl1_receive(info);
-+ break;
-+ case UART_IIR_THRI:
-+ if (lsr & UART_LSR_THRE) {
-+ /* Transmitter ready for data */
-+ dtl1_write_wakeup(info);
-+ }
-+ break;
-+ default:
-+ printk(KERN_NOTICE "dtl1_cs: Unhandled IIR=%#x\n", iir);
-+ break;
-+ }
-+
-+ /* Make sure we don't stay here to long */
-+ if (boguscount++ > 100)
-+ break;
-+
-+ iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-+
-+ }
-+
-+ msr = inb(iobase + UART_MSR);
-+
-+ if (info->ri_latch ^ (msr & UART_MSR_RI)) {
-+ info->ri_latch = msr & UART_MSR_RI;
-+ clear_bit(XMIT_WAITING, &(info->tx_state));
-+ dtl1_write_wakeup(info);
-+ }
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int dtl1_hci_open(struct hci_dev *hdev)
-+{
-+ set_bit(HCI_RUNNING, &(hdev->flags));
-+
-+ return 0;
-+}
-+
-+
-+static int dtl1_hci_flush(struct hci_dev *hdev)
-+{
-+ dtl1_info_t *info = (dtl1_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int dtl1_hci_close(struct hci_dev *hdev)
-+{
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ dtl1_hci_flush(hdev);
-+
-+ return 0;
-+}
-+
-+
-+static int dtl1_hci_send_frame(struct sk_buff *skb)
-+{
-+ dtl1_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+ struct sk_buff *s;
-+ nsh_t nsh;
-+
-+ if (!hdev) {
-+ printk(KERN_WARNING "dtl1_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (dtl1_info_t *)(hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ nsh.type = 0x81;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ nsh.type = 0x82;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ nsh.type = 0x83;
-+ break;
-+ };
-+
-+ nsh.zero = 0;
-+ nsh.len = skb->len;
-+
-+ s = bluez_skb_alloc(NSHL + skb->len + 1, GFP_ATOMIC);
-+ skb_reserve(s, NSHL);
-+ memcpy(skb_put(s, skb->len), skb->data, skb->len);
-+ if (skb->len & 0x0001)
-+ *skb_put(s, 1) = 0; /* PAD */
-+
-+ /* Prepend skb with Nokia frame header and queue */
-+ memcpy(skb_push(s, NSHL), &nsh, NSHL);
-+ skb_queue_tail(&(info->txq), s);
-+
-+ dtl1_write_wakeup(info);
-+
-+ kfree_skb(skb);
-+
-+ return 0;
-+}
-+
-+
-+static void dtl1_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+int dtl1_open(dtl1_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_NSH;
-+ info->rx_count = NSHL;
-+ info->rx_skb = NULL;
-+
-+ set_bit(XMIT_WAITING, &(info->tx_state));
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Reset UART */
-+ outb(0, iobase + UART_MCR);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ /* Initialize UART */
-+ outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
-+ outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
-+
-+ info->ri_latch = inb(info->link.io.BasePort1 + UART_MSR) & UART_MSR_RI;
-+
-+ /* Turn on interrupts */
-+ outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ * 2);
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = dtl1_hci_open;
-+ hdev->close = dtl1_hci_close;
-+ hdev->flush = dtl1_hci_flush;
-+ hdev->send = dtl1_hci_send_frame;
-+ hdev->destruct = dtl1_hci_destruct;
-+ hdev->ioctl = dtl1_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_WARNING "dtl1_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int dtl1_close(dtl1_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ if (info->link.state & DEV_CONFIG_PENDING)
-+ return -ENODEV;
-+
-+ dtl1_hci_close(hdev);
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Reset UART */
-+ outb(0, iobase + UART_MCR);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_WARNING "dtl1_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+dev_link_t *dtl1_attach(void)
-+{
-+ dtl1_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &dtl1_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = dtl1_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.Vcc = 50;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &dtl1_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ dtl1_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+void dtl1_detach(dev_link_t *link)
-+{
-+ dtl1_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+ if (link->state & DEV_CONFIG)
-+ dtl1_release((u_long)link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+void dtl1_config(dev_link_t *link)
-+{
-+ client_handle_t handle = link->handle;
-+ dtl1_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
-+ int i, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-+
-+ /* Look for a generic full-sized window */
-+ link->io.NumPorts1 = 8;
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
-+ link->conf.ConfigIndex = cf->index;
-+ link->io.BasePort1 = cf->io.win[0].base;
-+ link->io.NumPorts1 = cf->io.win[0].len; /*yo */
-+ link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ break;
-+ }
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (dtl1_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ dtl1_release((u_long)link);
-+}
-+
-+
-+void dtl1_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *)arg;
-+ dtl1_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ dtl1_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+int dtl1_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ dtl1_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ dtl1_close(info);
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ dtl1_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG)
-+ CardServices(ReleaseConfiguration, link->handle);
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (DEV_OK(link))
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_dtl1_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "dtl1_cs: Card Services release does not match!\n");
-+ return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &dtl1_attach, &dtl1_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_dtl1_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ dtl1_detach(dev_list);
-+}
-+
-+
-+module_init(init_dtl1_cs);
-+module_exit(exit_dtl1_cs);
-+
-+EXPORT_NO_SYMBOLS;
-diff -urN linux-2.4.18/drivers/bluetooth/hci_bcsp.c linux-2.4.18-mh15/drivers/bluetooth/hci_bcsp.c
---- linux-2.4.18/drivers/bluetooth/hci_bcsp.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_bcsp.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,710 @@
-+/*
-+ BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
-+ Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com>
-+
-+ Based on
-+ hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com>
-+ ABCSP by Carl Orsborn <cjo@csr.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#define VERSION "0.1"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/types.h>
-+#include <linux/fcntl.h>
-+#include <linux/interrupt.h>
-+#include <linux/ptrace.h>
-+#include <linux/poll.h>
-+
-+#include <linux/slab.h>
-+#include <linux/tty.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/signal.h>
-+#include <linux/ioctl.h>
-+#include <linux/skbuff.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include "hci_uart.h"
-+#include "hci_bcsp.h"
-+
-+#ifndef HCI_UART_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#undef BT_DMP
-+#define BT_DMP( A... )
-+#endif
-+
-+/* ---- BCSP CRC calculation ---- */
-+
-+/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
-+initial value 0xffff, bits shifted in reverse order. */
-+
-+static const u16 crc_table[] = {
-+ 0x0000, 0x1081, 0x2102, 0x3183,
-+ 0x4204, 0x5285, 0x6306, 0x7387,
-+ 0x8408, 0x9489, 0xa50a, 0xb58b,
-+ 0xc60c, 0xd68d, 0xe70e, 0xf78f
-+};
-+
-+/* Initialise the crc calculator */
-+#define BCSP_CRC_INIT(x) x = 0xffff
-+
-+/*
-+ Update crc with next data byte
-+
-+ Implementation note
-+ The data byte is treated as two nibbles. The crc is generated
-+ in reverse, i.e., bits are fed into the register from the top.
-+*/
-+static void bcsp_crc_update(u16 *crc, u8 d)
-+{
-+ u16 reg = *crc;
-+
-+ reg = (reg >> 4) ^ crc_table[(reg ^ d) & 0x000f];
-+ reg = (reg >> 4) ^ crc_table[(reg ^ (d >> 4)) & 0x000f];
-+
-+ *crc = reg;
-+}
-+
-+/*
-+ Get reverse of generated crc
-+
-+ Implementation note
-+ The crc generator (bcsp_crc_init() and bcsp_crc_update())
-+ creates a reversed crc, so it needs to be swapped back before
-+ being passed on.
-+*/
-+static u16 bcsp_crc_reverse(u16 crc)
-+{
-+ u16 b, rev;
-+
-+ for (b = 0, rev = 0; b < 16; b++) {
-+ rev = rev << 1;
-+ rev |= (crc & 1);
-+ crc = crc >> 1;
-+ }
-+ return (rev);
-+}
-+
-+/* ---- BCSP core ---- */
-+
-+static void bcsp_slip_msgdelim(struct sk_buff *skb)
-+{
-+ const char pkt_delim = 0xc0;
-+ memcpy(skb_put(skb, 1), &pkt_delim, 1);
-+}
-+
-+static void bcsp_slip_one_byte(struct sk_buff *skb, u8 c)
-+{
-+ const char esc_c0[2] = { 0xdb, 0xdc };
-+ const char esc_db[2] = { 0xdb, 0xdd };
-+
-+ switch (c) {
-+ case 0xc0:
-+ memcpy(skb_put(skb, 2), &esc_c0, 2);
-+ break;
-+ case 0xdb:
-+ memcpy(skb_put(skb, 2), &esc_db, 2);
-+ break;
-+ default:
-+ memcpy(skb_put(skb, 1), &c, 1);
-+ }
-+}
-+
-+static int bcsp_enqueue(struct hci_uart *hu, struct sk_buff *skb)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+
-+ if (skb->len > 0xFFF) {
-+ BT_ERR("Packet too long");
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+
-+ switch (skb->pkt_type) {
-+ case HCI_ACLDATA_PKT:
-+ case HCI_COMMAND_PKT:
-+ skb_queue_tail(&bcsp->rel, skb);
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ skb_queue_tail(&bcsp->unrel, skb);
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown packet type");
-+ kfree_skb(skb);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
-+ int len, int pkt_type)
-+{
-+ struct sk_buff *nskb;
-+ u8 hdr[4], chan;
-+ int rel, i;
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
-+#endif
-+
-+ switch (pkt_type) {
-+ case HCI_ACLDATA_PKT:
-+ chan = 6; /* BCSP ACL channel */
-+ rel = 1; /* reliable channel */
-+ break;
-+ case HCI_COMMAND_PKT:
-+ chan = 5; /* BCSP cmd/evt channel */
-+ rel = 1; /* reliable channel */
-+ break;
-+ case HCI_SCODATA_PKT:
-+ chan = 7; /* BCSP SCO channel */
-+ rel = 0; /* unreliable channel */
-+ break;
-+ case BCSP_LE_PKT:
-+ chan = 1; /* BCSP LE channel */
-+ rel = 0; /* unreliable channel */
-+ break;
-+ case BCSP_ACK_PKT:
-+ chan = 0; /* BCSP internal channel */
-+ rel = 0; /* unreliable channel */
-+ break;
-+ default:
-+ BT_ERR("Unknown packet type");
-+ return NULL;
-+ }
-+
-+ /* Max len of packet: (original len +4(bcsp hdr) +2(crc))*2
-+ (because bytes 0xc0 and 0xdb are escaped, worst case is
-+ when the packet is all made of 0xc0 and 0xdb :) )
-+ + 2 (0xc0 delimiters at start and end). */
-+
-+ nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC);
-+ if (!nskb)
-+ return NULL;
-+
-+ nskb->pkt_type = pkt_type;
-+
-+ bcsp_slip_msgdelim(nskb);
-+
-+ hdr[0] = bcsp->rxseq_txack << 3;
-+ bcsp->txack_req = 0;
-+ BT_DBG("We request packet no %u to card", bcsp->rxseq_txack);
-+
-+ if (rel) {
-+ hdr[0] |= 0x80 + bcsp->msgq_txseq;
-+ BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
-+ bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07;
-+ }
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ hdr[0] |= 0x40;
-+#endif
-+
-+ hdr[1] = (len << 4) & 0xFF;
-+ hdr[1] |= chan;
-+ hdr[2] = len >> 4;
-+ hdr[3] = ~(hdr[0] + hdr[1] + hdr[2]);
-+
-+ /* Put BCSP header */
-+ for (i = 0; i < 4; i++) {
-+ bcsp_slip_one_byte(nskb, hdr[i]);
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
-+#endif
-+ }
-+
-+ /* Put payload */
-+ for (i = 0; i < len; i++) {
-+ bcsp_slip_one_byte(nskb, data[i]);
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
-+#endif
-+ }
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ /* Put CRC */
-+ bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
-+ bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
-+ bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
-+#endif
-+
-+ bcsp_slip_msgdelim(nskb);
-+ return nskb;
-+}
-+
-+/* This is a rewrite of pkt_avail in ABCSP */
-+static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
-+ unsigned long flags;
-+ struct sk_buff *skb;
-+
-+ /* First of all, check for unreliable messages in the queue,
-+ since they have priority */
-+
-+ if ((skb = skb_dequeue(&bcsp->unrel)) != NULL) {
-+ struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
-+ if (nskb) {
-+ kfree_skb(skb);
-+ return nskb;
-+ } else {
-+ skb_queue_head(&bcsp->unrel, skb);
-+ BT_ERR("Could not dequeue pkt because alloc_skb failed");
-+ }
-+ }
-+
-+ /* Now, try to send a reliable pkt. We can only send a
-+ reliable packet if the number of packets sent but not yet ack'ed
-+ is < than the winsize */
-+
-+ spin_lock_irqsave(&bcsp->unack.lock, flags);
-+
-+ if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) {
-+ struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
-+ if (nskb) {
-+ __skb_queue_tail(&bcsp->unack, skb);
-+ mod_timer(&bcsp->tbcsp, jiffies + HZ / 4);
-+ spin_unlock_irqrestore(&bcsp->unack.lock, flags);
-+ return nskb;
-+ } else {
-+ skb_queue_head(&bcsp->rel, skb);
-+ BT_ERR("Could not dequeue pkt because alloc_skb failed");
-+ }
-+ }
-+
-+ spin_unlock_irqrestore(&bcsp->unack.lock, flags);
-+
-+
-+ /* We could not send a reliable packet, either because there are
-+ none or because there are too many unack'ed pkts. Did we receive
-+ any packets we have not acknowledged yet ? */
-+
-+ if (bcsp->txack_req) {
-+ /* if so, craft an empty ACK pkt and send it on BCSP unreliable
-+ channel 0 */
-+ struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, NULL, 0, BCSP_ACK_PKT);
-+ return nskb;
-+ }
-+
-+ /* We have nothing to send */
-+ return NULL;
-+}
-+
-+static int bcsp_flush(struct hci_uart *hu)
-+{
-+ BT_DBG("hu %p", hu);
-+ return 0;
-+}
-+
-+/* Remove ack'ed packets */
-+static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
-+{
-+ unsigned long flags;
-+ struct sk_buff *skb;
-+ int i, pkts_to_be_removed;
-+ u8 seqno;
-+
-+ spin_lock_irqsave(&bcsp->unack.lock, flags);
-+
-+ pkts_to_be_removed = bcsp->unack.qlen;
-+ seqno = bcsp->msgq_txseq;
-+
-+ while (pkts_to_be_removed) {
-+ if (bcsp->rxack == seqno)
-+ break;
-+ pkts_to_be_removed--;
-+ seqno = (seqno - 1) & 0x07;
-+ }
-+
-+ if (bcsp->rxack != seqno)
-+ BT_ERR("Peer acked invalid packet");
-+
-+ BT_DBG("Removing %u pkts out of %u, up to seqno %u",
-+ pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07);
-+
-+ for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed
-+ && skb != (struct sk_buff *) &bcsp->unack; i++) {
-+ struct sk_buff *nskb;
-+
-+ nskb = skb->next;
-+ __skb_unlink(skb, &bcsp->unack);
-+ kfree_skb(skb);
-+ skb = nskb;
-+ }
-+ if (bcsp->unack.qlen == 0)
-+ del_timer(&bcsp->tbcsp);
-+ spin_unlock_irqrestore(&bcsp->unack.lock, flags);
-+
-+ if (i != pkts_to_be_removed)
-+ BT_ERR("Removed only %u out of %u pkts", i, pkts_to_be_removed);
-+}
-+
-+/* Handle BCSP link-establishment packets. When we
-+ detect a "sync" packet, symptom that the BT module has reset,
-+ we do nothing :) (yet) */
-+static void bcsp_handle_le_pkt(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+ u8 conf_pkt[4] = { 0xad, 0xef, 0xac, 0xed };
-+ u8 conf_rsp_pkt[4] = { 0xde, 0xad, 0xd0, 0xd0 };
-+ u8 sync_pkt[4] = { 0xda, 0xdc, 0xed, 0xed };
-+
-+ /* spot "conf" pkts and reply with a "conf rsp" pkt */
-+ if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
-+ !memcmp(&bcsp->rx_skb->data[4], conf_pkt, 4)) {
-+ struct sk_buff *nskb = alloc_skb(4, GFP_ATOMIC);
-+
-+ BT_DBG("Found a LE conf pkt");
-+ if (!nskb)
-+ return;
-+ memcpy(skb_put(nskb, 4), conf_rsp_pkt, 4);
-+ nskb->pkt_type = BCSP_LE_PKT;
-+
-+ skb_queue_head(&bcsp->unrel, nskb);
-+ hci_uart_tx_wakeup(hu);
-+ }
-+ /* Spot "sync" pkts. If we find one...disaster! */
-+ else if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
-+ !memcmp(&bcsp->rx_skb->data[4], sync_pkt, 4)) {
-+ BT_ERR("Found a LE sync pkt, card has reset");
-+ }
-+}
-+
-+static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char byte)
-+{
-+ const u8 c0 = 0xc0, db = 0xdb;
-+
-+ switch (bcsp->rx_esc_state) {
-+ case BCSP_ESCSTATE_NOESC:
-+ switch (byte) {
-+ case 0xdb:
-+ bcsp->rx_esc_state = BCSP_ESCSTATE_ESC;
-+ break;
-+ default:
-+ memcpy(skb_put(bcsp->rx_skb, 1), &byte, 1);
-+ if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
-+ bcsp->rx_state != BCSP_W4_CRC)
-+ bcsp_crc_update(&bcsp->message_crc, byte);
-+ bcsp->rx_count--;
-+ }
-+ break;
-+
-+ case BCSP_ESCSTATE_ESC:
-+ switch (byte) {
-+ case 0xdc:
-+ memcpy(skb_put(bcsp->rx_skb, 1), &c0, 1);
-+ if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
-+ bcsp->rx_state != BCSP_W4_CRC)
-+ bcsp_crc_update(&bcsp-> message_crc, 0xc0);
-+ bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
-+ bcsp->rx_count--;
-+ break;
-+
-+ case 0xdd:
-+ memcpy(skb_put(bcsp->rx_skb, 1), &db, 1);
-+ if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
-+ bcsp->rx_state != BCSP_W4_CRC)
-+ bcsp_crc_update(&bcsp-> message_crc, 0xdb);
-+ bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
-+ bcsp->rx_count--;
-+ break;
-+
-+ default:
-+ BT_ERR ("Invalid byte %02x after esc byte", byte);
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_skb = NULL;
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ }
-+ }
-+}
-+
-+static inline void bcsp_complete_rx_pkt(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+ int pass_up;
-+
-+ if (bcsp->rx_skb->data[0] & 0x80) { /* reliable pkt */
-+ BT_DBG("Received seqno %u from card", bcsp->rxseq_txack);
-+ bcsp->rxseq_txack++;
-+ bcsp->rxseq_txack %= 0x8;
-+ bcsp->txack_req = 1;
-+
-+ /* If needed, transmit an ack pkt */
-+ hci_uart_tx_wakeup(hu);
-+ }
-+
-+ bcsp->rxack = (bcsp->rx_skb->data[0] >> 3) & 0x07;
-+ BT_DBG("Request for pkt %u from card", bcsp->rxack);
-+
-+ bcsp_pkt_cull(bcsp);
-+ if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
-+ bcsp->rx_skb->data[0] & 0x80) {
-+ bcsp->rx_skb->pkt_type = HCI_ACLDATA_PKT;
-+ pass_up = 1;
-+ } else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
-+ bcsp->rx_skb->data[0] & 0x80) {
-+ bcsp->rx_skb->pkt_type = HCI_EVENT_PKT;
-+ pass_up = 1;
-+ } else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
-+ bcsp->rx_skb->pkt_type = HCI_SCODATA_PKT;
-+ pass_up = 1;
-+ } else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 &&
-+ !(bcsp->rx_skb->data[0] & 0x80)) {
-+ bcsp_handle_le_pkt(hu);
-+ pass_up = 0;
-+ } else
-+ pass_up = 0;
-+
-+ if (!pass_up) {
-+ if ((bcsp->rx_skb->data[1] & 0x0f) != 0 &&
-+ (bcsp->rx_skb->data[1] & 0x0f) != 1) {
-+ BT_ERR ("Packet for unknown channel (%u %s)",
-+ bcsp->rx_skb->data[1] & 0x0f,
-+ bcsp->rx_skb->data[0] & 0x80 ?
-+ "reliable" : "unreliable");
-+ }
-+ kfree_skb(bcsp->rx_skb);
-+ } else {
-+ /* Pull out BCSP hdr */
-+ skb_pull(bcsp->rx_skb, 4);
-+
-+ hci_recv_frame(bcsp->rx_skb);
-+ }
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_skb = NULL;
-+}
-+
-+/* Recv data */
-+static int bcsp_recv(struct hci_uart *hu, void *data, int count)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+ register unsigned char *ptr;
-+
-+ BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
-+ hu, count, bcsp->rx_state, bcsp->rx_count);
-+
-+ ptr = data;
-+ while (count) {
-+ if (bcsp->rx_count) {
-+ if (*ptr == 0xc0) {
-+ BT_ERR("Short BCSP packet");
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_state = BCSP_W4_PKT_START;
-+ bcsp->rx_count = 0;
-+ } else
-+ bcsp_unslip_one_byte(bcsp, *ptr);
-+
-+ ptr++; count--;
-+ continue;
-+ }
-+
-+ switch (bcsp->rx_state) {
-+ case BCSP_W4_BCSP_HDR:
-+ if ((0xff & (u8) ~ (bcsp->rx_skb->data[0] + bcsp->rx_skb->data[1] +
-+ bcsp->rx_skb->data[2])) != bcsp->rx_skb->data[3]) {
-+ BT_ERR("Error in BCSP hdr checksum");
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ continue;
-+ }
-+ if (bcsp->rx_skb->data[0] & 0x80 /* reliable pkt */
-+ && (bcsp->rx_skb->data[0] & 0x07) != bcsp->rxseq_txack) {
-+ BT_ERR ("Out-of-order packet arrived, got %u expected %u",
-+ bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);
-+
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ continue;
-+ }
-+ bcsp->rx_state = BCSP_W4_DATA;
-+ bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) +
-+ (bcsp->rx_skb->data[2] << 4); /* May be 0 */
-+ continue;
-+
-+ case BCSP_W4_DATA:
-+ if (bcsp->rx_skb->data[0] & 0x40) { /* pkt with crc */
-+ bcsp->rx_state = BCSP_W4_CRC;
-+ bcsp->rx_count = 2;
-+ } else
-+ bcsp_complete_rx_pkt(hu);
-+ continue;
-+
-+ case BCSP_W4_CRC:
-+ if (bcsp_crc_reverse(bcsp->message_crc) !=
-+ (bcsp->rx_skb->data[bcsp->rx_skb->len - 2] << 8) +
-+ bcsp->rx_skb->data[bcsp->rx_skb->len - 1]) {
-+
-+ BT_ERR ("Checksum failed: computed %04x received %04x",
-+ bcsp_crc_reverse(bcsp->message_crc),
-+ (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) +
-+ bcsp->rx_skb->data[bcsp->rx_skb->len - 1]);
-+
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ continue;
-+ }
-+ skb_trim(bcsp->rx_skb, bcsp->rx_skb->len - 2);
-+ bcsp_complete_rx_pkt(hu);
-+ continue;
-+
-+ case BCSP_W4_PKT_DELIMITER:
-+ switch (*ptr) {
-+ case 0xc0:
-+ bcsp->rx_state = BCSP_W4_PKT_START;
-+ break;
-+ default:
-+ /*BT_ERR("Ignoring byte %02x", *ptr);*/
-+ break;
-+ }
-+ ptr++; count--;
-+ break;
-+
-+ case BCSP_W4_PKT_START:
-+ switch (*ptr) {
-+ case 0xc0:
-+ ptr++; count--;
-+ break;
-+
-+ default:
-+ bcsp->rx_state = BCSP_W4_BCSP_HDR;
-+ bcsp->rx_count = 4;
-+ bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
-+ BCSP_CRC_INIT(bcsp->message_crc);
-+
-+ /* Do not increment ptr or decrement count
-+ * Allocate packet. Max len of a BCSP pkt=
-+ * 0xFFF (payload) +4 (header) +2 (crc) */
-+
-+ bcsp->rx_skb = bluez_skb_alloc(0x1005, GFP_ATOMIC);
-+ if (!bcsp->rx_skb) {
-+ BT_ERR("Can't allocate mem for new packet");
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ return 0;
-+ }
-+ bcsp->rx_skb->dev = (void *) &hu->hdev;
-+ break;
-+ }
-+ break;
-+ }
-+ }
-+ return count;
-+}
-+
-+ /* Arrange to retransmit all messages in the relq. */
-+static void bcsp_timed_event(unsigned long arg)
-+{
-+ struct hci_uart *hu = (struct hci_uart *) arg;
-+ struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
-+ struct sk_buff *skb;
-+ unsigned long flags;
-+
-+ BT_DBG("hu %p retransmitting %u pkts", hu, bcsp->unack.qlen);
-+
-+ spin_lock_irqsave(&bcsp->unack.lock, flags);
-+
-+ while ((skb = __skb_dequeue_tail(&bcsp->unack)) != NULL) {
-+ bcsp->msgq_txseq = (bcsp->msgq_txseq - 1) & 0x07;
-+ skb_queue_head(&bcsp->rel, skb);
-+ }
-+
-+ spin_unlock_irqrestore(&bcsp->unack.lock, flags);
-+
-+ hci_uart_tx_wakeup(hu);
-+}
-+
-+static int bcsp_open(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp;
-+
-+ BT_DBG("hu %p", hu);
-+
-+ bcsp = kmalloc(sizeof(*bcsp), GFP_ATOMIC);
-+ if (!bcsp)
-+ return -ENOMEM;
-+ memset(bcsp, 0, sizeof(*bcsp));
-+
-+ hu->priv = bcsp;
-+ skb_queue_head_init(&bcsp->unack);
-+ skb_queue_head_init(&bcsp->rel);
-+ skb_queue_head_init(&bcsp->unrel);
-+
-+ init_timer(&bcsp->tbcsp);
-+ bcsp->tbcsp.function = bcsp_timed_event;
-+ bcsp->tbcsp.data = (u_long) hu;
-+
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+
-+ return 0;
-+}
-+
-+static int bcsp_close(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+ hu->priv = NULL;
-+
-+ BT_DBG("hu %p", hu);
-+
-+ skb_queue_purge(&bcsp->unack);
-+ skb_queue_purge(&bcsp->rel);
-+ skb_queue_purge(&bcsp->unrel);
-+ del_timer(&bcsp->tbcsp);
-+
-+ kfree(bcsp);
-+ return 0;
-+}
-+
-+static struct hci_uart_proto bcsp = {
-+ id: HCI_UART_BCSP,
-+ open: bcsp_open,
-+ close: bcsp_close,
-+ enqueue: bcsp_enqueue,
-+ dequeue: bcsp_dequeue,
-+ recv: bcsp_recv,
-+ flush: bcsp_flush
-+};
-+
-+int bcsp_init(void)
-+{
-+ return hci_uart_register_proto(&bcsp);
-+}
-+
-+int bcsp_deinit(void)
-+{
-+ return hci_uart_unregister_proto(&bcsp);
-+}
-diff -urN linux-2.4.18/drivers/bluetooth/hci_bcsp.h linux-2.4.18-mh15/drivers/bluetooth/hci_bcsp.h
---- linux-2.4.18/drivers/bluetooth/hci_bcsp.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_bcsp.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,70 @@
-+/*
-+ BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
-+ Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com>
-+
-+ Based on
-+ hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com>
-+ ABCSP by Carl Orsborn <cjo@csr.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef __HCI_BCSP_H__
-+#define __HCI_BCSP_H__
-+
-+#define BCSP_TXWINSIZE 4
-+
-+#define BCSP_ACK_PKT 0x05
-+#define BCSP_LE_PKT 0x06
-+
-+struct bcsp_struct {
-+ struct sk_buff_head unack; /* Unack'ed packets queue */
-+ struct sk_buff_head rel; /* Reliable packets queue */
-+ struct sk_buff_head unrel; /* Unreliable packets queue */
-+
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+ u8 rxseq_txack; /* rxseq == txack. */
-+ u8 rxack; /* Last packet sent by us that the peer ack'ed */
-+ struct timer_list tbcsp;
-+
-+ enum {
-+ BCSP_W4_PKT_DELIMITER,
-+ BCSP_W4_PKT_START,
-+ BCSP_W4_BCSP_HDR,
-+ BCSP_W4_DATA,
-+ BCSP_W4_CRC
-+ } rx_state;
-+
-+ enum {
-+ BCSP_ESCSTATE_NOESC,
-+ BCSP_ESCSTATE_ESC
-+ } rx_esc_state;
-+
-+ u16 message_crc;
-+ u8 txack_req; /* Do we need to send ack's to the peer? */
-+
-+ /* Reliable packet sequence number - used to assign seq to each rel pkt. */
-+ u8 msgq_txseq;
-+};
-+
-+#endif /* __HCI_BCSP_H__ */
-diff -urN linux-2.4.18/drivers/bluetooth/hci_h4.c linux-2.4.18-mh15/drivers/bluetooth/hci_h4.c
---- linux-2.4.18/drivers/bluetooth/hci_h4.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_h4.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,277 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * BlueZ HCI UART(H4) protocol.
-+ *
-+ * $Id$
-+ */
-+#define VERSION "1.2"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/types.h>
-+#include <linux/fcntl.h>
-+#include <linux/interrupt.h>
-+#include <linux/ptrace.h>
-+#include <linux/poll.h>
-+
-+#include <linux/slab.h>
-+#include <linux/tty.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/signal.h>
-+#include <linux/ioctl.h>
-+#include <linux/skbuff.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include "hci_uart.h"
-+#include "hci_h4.h"
-+
-+#ifndef HCI_UART_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#undef BT_DMP
-+#define BT_DMP( A... )
-+#endif
-+
-+/* Initialize protocol */
-+static int h4_open(struct hci_uart *hu)
-+{
-+ struct h4_struct *h4;
-+
-+ BT_DBG("hu %p", hu);
-+
-+ h4 = kmalloc(sizeof(*h4), GFP_ATOMIC);
-+ if (!h4)
-+ return -ENOMEM;
-+ memset(h4, 0, sizeof(*h4));
-+
-+ skb_queue_head_init(&h4->txq);
-+
-+ hu->priv = h4;
-+ return 0;
-+}
-+
-+/* Flush protocol data */
-+static int h4_flush(struct hci_uart *hu)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+
-+ BT_DBG("hu %p", hu);
-+ skb_queue_purge(&h4->txq);
-+ return 0;
-+}
-+
-+/* Close protocol */
-+static int h4_close(struct hci_uart *hu)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+ hu->priv = NULL;
-+
-+ BT_DBG("hu %p", hu);
-+
-+ skb_queue_purge(&h4->txq);
-+ if (h4->rx_skb)
-+ kfree_skb(h4->rx_skb);
-+
-+ hu->priv = NULL;
-+ kfree(h4);
-+ return 0;
-+}
-+
-+/* Enqueue frame for transmittion (padding, crc, etc) */
-+static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+
-+ BT_DBG("hu %p skb %p", hu, skb);
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
-+ skb_queue_tail(&h4->txq, skb);
-+ return 0;
-+}
-+
-+static inline int h4_check_data_len(struct h4_struct *h4, int len)
-+{
-+ register int room = skb_tailroom(h4->rx_skb);
-+
-+ BT_DBG("len %d room %d", len, room);
-+ if (!len) {
-+ BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
-+ hci_recv_frame(h4->rx_skb);
-+ } else if (len > room) {
-+ BT_ERR("Data length is too large");
-+ kfree_skb(h4->rx_skb);
-+ } else {
-+ h4->rx_state = H4_W4_DATA;
-+ h4->rx_count = len;
-+ return len;
-+ }
-+
-+ h4->rx_state = H4_W4_PACKET_TYPE;
-+ h4->rx_skb = NULL;
-+ h4->rx_count = 0;
-+ return 0;
-+}
-+
-+/* Recv data */
-+static int h4_recv(struct hci_uart *hu, void *data, int count)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+ register char *ptr;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+ register int len, type, dlen;
-+
-+ BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
-+ hu, count, h4->rx_state, h4->rx_count);
-+
-+ ptr = data;
-+ while (count) {
-+ if (h4->rx_count) {
-+ len = MIN(h4->rx_count, count);
-+ memcpy(skb_put(h4->rx_skb, len), ptr, len);
-+ h4->rx_count -= len; count -= len; ptr += len;
-+
-+ if (h4->rx_count)
-+ continue;
-+
-+ switch (h4->rx_state) {
-+ case H4_W4_DATA:
-+ BT_DBG("Complete data");
-+
-+ BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
-+
-+ hci_recv_frame(h4->rx_skb);
-+
-+ h4->rx_state = H4_W4_PACKET_TYPE;
-+ h4->rx_skb = NULL;
-+ continue;
-+
-+ case H4_W4_EVENT_HDR:
-+ eh = (hci_event_hdr *) h4->rx_skb->data;
-+
-+ BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
-+
-+ h4_check_data_len(h4, eh->plen);
-+ continue;
-+
-+ case H4_W4_ACL_HDR:
-+ ah = (hci_acl_hdr *) h4->rx_skb->data;
-+ dlen = __le16_to_cpu(ah->dlen);
-+
-+ BT_DBG("ACL header: dlen %d", dlen);
-+
-+ h4_check_data_len(h4, dlen);
-+ continue;
-+
-+ case H4_W4_SCO_HDR:
-+ sh = (hci_sco_hdr *) h4->rx_skb->data;
-+
-+ BT_DBG("SCO header: dlen %d", sh->dlen);
-+
-+ h4_check_data_len(h4, sh->dlen);
-+ continue;
-+ }
-+ }
-+
-+ /* H4_W4_PACKET_TYPE */
-+ switch (*ptr) {
-+ case HCI_EVENT_PKT:
-+ BT_DBG("Event packet");
-+ h4->rx_state = H4_W4_EVENT_HDR;
-+ h4->rx_count = HCI_EVENT_HDR_SIZE;
-+ type = HCI_EVENT_PKT;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ BT_DBG("ACL packet");
-+ h4->rx_state = H4_W4_ACL_HDR;
-+ h4->rx_count = HCI_ACL_HDR_SIZE;
-+ type = HCI_ACLDATA_PKT;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ BT_DBG("SCO packet");
-+ h4->rx_state = H4_W4_SCO_HDR;
-+ h4->rx_count = HCI_SCO_HDR_SIZE;
-+ type = HCI_SCODATA_PKT;
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
-+ hu->hdev.stat.err_rx++;
-+ ptr++; count--;
-+ continue;
-+ };
-+ ptr++; count--;
-+
-+ /* Allocate packet */
-+ h4->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
-+ if (!h4->rx_skb) {
-+ BT_ERR("Can't allocate mem for new packet");
-+ h4->rx_state = H4_W4_PACKET_TYPE;
-+ h4->rx_count = 0;
-+ return 0;
-+ }
-+ h4->rx_skb->dev = (void *) &hu->hdev;
-+ h4->rx_skb->pkt_type = type;
-+ }
-+ return count;
-+}
-+
-+static struct sk_buff *h4_dequeue(struct hci_uart *hu)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+ return skb_dequeue(&h4->txq);
-+}
-+
-+static struct hci_uart_proto h4p = {
-+ id: HCI_UART_H4,
-+ open: h4_open,
-+ close: h4_close,
-+ recv: h4_recv,
-+ enqueue: h4_enqueue,
-+ dequeue: h4_dequeue,
-+ flush: h4_flush,
-+};
-+
-+int h4_init(void)
-+{
-+ return hci_uart_register_proto(&h4p);
-+}
-+
-+int h4_deinit(void)
-+{
-+ return hci_uart_unregister_proto(&h4p);
-+}
-diff -urN linux-2.4.18/drivers/bluetooth/hci_h4.h linux-2.4.18-mh15/drivers/bluetooth/hci_h4.h
---- linux-2.4.18/drivers/bluetooth/hci_h4.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_h4.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,44 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifdef __KERNEL__
-+struct h4_struct {
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+ struct sk_buff_head txq;
-+};
-+
-+/* H4 receiver States */
-+#define H4_W4_PACKET_TYPE 0
-+#define H4_W4_EVENT_HDR 1
-+#define H4_W4_ACL_HDR 2
-+#define H4_W4_SCO_HDR 3
-+#define H4_W4_DATA 4
-+
-+#endif /* __KERNEL__ */
-diff -urN linux-2.4.18/drivers/bluetooth/hci_ldisc.c linux-2.4.18-mh15/drivers/bluetooth/hci_ldisc.c
---- linux-2.4.18/drivers/bluetooth/hci_ldisc.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_ldisc.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,579 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * BlueZ HCI UART driver.
-+ *
-+ * $Id$
-+ */
-+#define VERSION "2.1"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/types.h>
-+#include <linux/fcntl.h>
-+#include <linux/interrupt.h>
-+#include <linux/ptrace.h>
-+#include <linux/poll.h>
-+
-+#include <linux/slab.h>
-+#include <linux/tty.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/signal.h>
-+#include <linux/ioctl.h>
-+#include <linux/skbuff.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include "hci_uart.h"
-+
-+#ifndef HCI_UART_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#undef BT_DMP
-+#define BT_DMP( A... )
-+#endif
-+
-+static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
-+
-+int hci_uart_register_proto(struct hci_uart_proto *p)
-+{
-+ if (p->id >= HCI_UART_MAX_PROTO)
-+ return -EINVAL;
-+
-+ if (hup[p->id])
-+ return -EEXIST;
-+
-+ hup[p->id] = p;
-+ return 0;
-+}
-+
-+int hci_uart_unregister_proto(struct hci_uart_proto *p)
-+{
-+ if (p->id >= HCI_UART_MAX_PROTO)
-+ return -EINVAL;
-+
-+ if (!hup[p->id])
-+ return -EINVAL;
-+
-+ hup[p->id] = NULL;
-+ return 0;
-+}
-+
-+static struct hci_uart_proto *hci_uart_get_proto(unsigned int id)
-+{
-+ if (id >= HCI_UART_MAX_PROTO)
-+ return NULL;
-+ return hup[id];
-+}
-+
-+static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type)
-+{
-+ struct hci_dev *hdev = &hu->hdev;
-+
-+ /* Update HCI stat counters */
-+ switch (pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ }
-+}
-+
-+static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu)
-+{
-+ struct sk_buff *skb = hu->tx_skb;
-+ if (!skb)
-+ skb = hu->proto->dequeue(hu);
-+ else
-+ hu->tx_skb = NULL;
-+ return skb;
-+}
-+
-+int hci_uart_tx_wakeup(struct hci_uart *hu)
-+{
-+ struct tty_struct *tty = hu->tty;
-+ struct hci_dev *hdev = &hu->hdev;
-+ struct sk_buff *skb;
-+
-+ if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
-+ set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
-+ return 0;
-+ }
-+
-+ BT_DBG("");
-+
-+restart:
-+ clear_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
-+
-+ while ((skb = hci_uart_dequeue(hu))) {
-+ int len;
-+
-+ set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-+ len = tty->driver.write(tty, 0, skb->data, skb->len);
-+ hdev->stat.byte_tx += len;
-+
-+ skb_pull(skb, len);
-+ if (skb->len) {
-+ hu->tx_skb = skb;
-+ break;
-+ }
-+
-+ hci_uart_tx_complete(hu, skb->pkt_type);
-+ kfree_skb(skb);
-+ }
-+
-+ if (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state))
-+ goto restart;
-+
-+ clear_bit(HCI_UART_SENDING, &hu->tx_state);
-+ return 0;
-+}
-+
-+/* ------- Interface to HCI layer ------ */
-+/* Initialize device */
-+static int hci_uart_open(struct hci_dev *hdev)
-+{
-+ BT_DBG("%s %p", hdev->name, hdev);
-+
-+ /* Nothing to do for UART driver */
-+
-+ set_bit(HCI_RUNNING, &hdev->flags);
-+ return 0;
-+}
-+
-+/* Reset device */
-+static int hci_uart_flush(struct hci_dev *hdev)
-+{
-+ struct hci_uart *hu = (struct hci_uart *) hdev->driver_data;
-+ struct tty_struct *tty = hu->tty;
-+
-+ BT_DBG("hdev %p tty %p", hdev, tty);
-+
-+ if (hu->tx_skb) {
-+ kfree_skb(hu->tx_skb); hu->tx_skb = NULL;
-+ }
-+
-+ /* Flush any pending characters in the driver and discipline. */
-+ if (tty->ldisc.flush_buffer)
-+ tty->ldisc.flush_buffer(tty);
-+
-+ if (tty->driver.flush_buffer)
-+ tty->driver.flush_buffer(tty);
-+
-+ if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
-+ hu->proto->flush(hu);
-+
-+ return 0;
-+}
-+
-+/* Close device */
-+static int hci_uart_close(struct hci_dev *hdev)
-+{
-+ BT_DBG("hdev %p", hdev);
-+
-+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-+
-+ hci_uart_flush(hdev);
-+ return 0;
-+}
-+
-+/* Send frames from HCI layer */
-+static int hci_uart_send_frame(struct sk_buff *skb)
-+{
-+ struct hci_dev* hdev = (struct hci_dev *) skb->dev;
-+ struct tty_struct *tty;
-+ struct hci_uart *hu;
-+
-+ if (!hdev) {
-+ BT_ERR("Frame for uknown device (hdev=NULL)");
-+ return -ENODEV;
-+ }
-+
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return -EBUSY;
-+
-+ hu = (struct hci_uart *) hdev->driver_data;
-+ tty = hu->tty;
-+
-+ BT_DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
-+
-+ hu->proto->enqueue(hu, skb);
-+
-+ hci_uart_tx_wakeup(hu);
-+ return 0;
-+}
-+
-+static void hci_uart_destruct(struct hci_dev *hdev)
-+{
-+ struct hci_uart *hu;
-+
-+ if (!hdev) return;
-+
-+ BT_DBG("%s", hdev->name);
-+
-+ hu = (struct hci_uart *) hdev->driver_data;
-+ kfree(hu);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+/* ------ LDISC part ------ */
-+/* hci_uart_tty_open
-+ *
-+ * Called when line discipline changed to HCI_UART.
-+ *
-+ * Arguments:
-+ * tty pointer to tty info structure
-+ * Return Value:
-+ * 0 if success, otherwise error code
-+ */
-+static int hci_uart_tty_open(struct tty_struct *tty)
-+{
-+ struct hci_uart *hu = (void *) tty->disc_data;
-+
-+ BT_DBG("tty %p", tty);
-+
-+ if (hu)
-+ return -EEXIST;
-+
-+ if (!(hu = kmalloc(sizeof(struct hci_uart), GFP_KERNEL))) {
-+ BT_ERR("Can't allocate controll structure");
-+ return -ENFILE;
-+ }
-+ memset(hu, 0, sizeof(struct hci_uart));
-+
-+ tty->disc_data = hu;
-+ hu->tty = tty;
-+
-+ spin_lock_init(&hu->rx_lock);
-+
-+ /* Flush any pending characters in the driver and line discipline */
-+ if (tty->ldisc.flush_buffer)
-+ tty->ldisc.flush_buffer(tty);
-+
-+ if (tty->driver.flush_buffer)
-+ tty->driver.flush_buffer(tty);
-+
-+ MOD_INC_USE_COUNT;
-+ return 0;
-+}
-+
-+/* hci_uart_tty_close()
-+ *
-+ * Called when the line discipline is changed to something
-+ * else, the tty is closed, or the tty detects a hangup.
-+ */
-+static void hci_uart_tty_close(struct tty_struct *tty)
-+{
-+ struct hci_uart *hu = (void *)tty->disc_data;
-+
-+ BT_DBG("tty %p", tty);
-+
-+ /* Detach from the tty */
-+ tty->disc_data = NULL;
-+
-+ if (hu) {
-+ struct hci_dev *hdev = &hu->hdev;
-+ hci_uart_close(hdev);
-+
-+ if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
-+ hu->proto->close(hu);
-+ hci_unregister_dev(hdev);
-+ }
-+
-+ MOD_DEC_USE_COUNT;
-+ }
-+}
-+
-+/* hci_uart_tty_wakeup()
-+ *
-+ * Callback for transmit wakeup. Called when low level
-+ * device driver can accept more send data.
-+ *
-+ * Arguments: tty pointer to associated tty instance data
-+ * Return Value: None
-+ */
-+static void hci_uart_tty_wakeup(struct tty_struct *tty)
-+{
-+ struct hci_uart *hu = (void *)tty->disc_data;
-+
-+ BT_DBG("");
-+
-+ if (!hu)
-+ return;
-+
-+ clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-+
-+ if (tty != hu->tty)
-+ return;
-+
-+ if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
-+ hci_uart_tx_wakeup(hu);
-+}
-+
-+/* hci_uart_tty_room()
-+ *
-+ * Callback function from tty driver. Return the amount of
-+ * space left in the receiver's buffer to decide if remote
-+ * transmitter is to be throttled.
-+ *
-+ * Arguments: tty pointer to associated tty instance data
-+ * Return Value: number of bytes left in receive buffer
-+ */
-+static int hci_uart_tty_room (struct tty_struct *tty)
-+{
-+ return 65536;
-+}
-+
-+/* hci_uart_tty_receive()
-+ *
-+ * Called by tty low level driver when receive data is
-+ * available.
-+ *
-+ * Arguments: tty pointer to tty isntance data
-+ * data pointer to received data
-+ * flags pointer to flags for data
-+ * count count of received data in bytes
-+ *
-+ * Return Value: None
-+ */
-+static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char *flags, int count)
-+{
-+ struct hci_uart *hu = (void *)tty->disc_data;
-+
-+ if (!hu || tty != hu->tty)
-+ return;
-+
-+ if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
-+ return;
-+
-+ spin_lock(&hu->rx_lock);
-+ hu->proto->recv(hu, (void *) data, count);
-+ hu->hdev.stat.byte_rx += count;
-+ spin_unlock(&hu->rx_lock);
-+
-+ if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver.unthrottle)
-+ tty->driver.unthrottle(tty);
-+}
-+
-+static int hci_uart_register_dev(struct hci_uart *hu)
-+{
-+ struct hci_dev *hdev;
-+
-+ BT_DBG("");
-+
-+ /* Initialize and register HCI device */
-+ hdev = &hu->hdev;
-+
-+ hdev->type = HCI_UART;
-+ hdev->driver_data = hu;
-+
-+ hdev->open = hci_uart_open;
-+ hdev->close = hci_uart_close;
-+ hdev->flush = hci_uart_flush;
-+ hdev->send = hci_uart_send_frame;
-+ hdev->destruct = hci_uart_destruct;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ BT_ERR("Can't register HCI device %s", hdev->name);
-+ return -ENODEV;
-+ }
-+ MOD_INC_USE_COUNT;
-+ return 0;
-+}
-+
-+static int hci_uart_set_proto(struct hci_uart *hu, int id)
-+{
-+ struct hci_uart_proto *p;
-+ int err;
-+
-+ p = hci_uart_get_proto(id);
-+ if (!p)
-+ return -EPROTONOSUPPORT;
-+
-+ err = p->open(hu);
-+ if (err)
-+ return err;
-+
-+ hu->proto = p;
-+
-+ err = hci_uart_register_dev(hu);
-+ if (err) {
-+ p->close(hu);
-+ return err;
-+ }
-+ return 0;
-+}
-+
-+/* hci_uart_tty_ioctl()
-+ *
-+ * Process IOCTL system call for the tty device.
-+ *
-+ * Arguments:
-+ *
-+ * tty pointer to tty instance data
-+ * file pointer to open file object for device
-+ * cmd IOCTL command code
-+ * arg argument for IOCTL call (cmd dependent)
-+ *
-+ * Return Value: Command dependent
-+ */
-+static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ struct hci_uart *hu = (void *)tty->disc_data;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ /* Verify the status of the device */
-+ if (!hu)
-+ return -EBADF;
-+
-+ switch (cmd) {
-+ case HCIUARTSETPROTO:
-+ if (!test_and_set_bit(HCI_UART_PROTO_SET, &hu->flags)) {
-+ err = hci_uart_set_proto(hu, arg);
-+ if (err) {
-+ clear_bit(HCI_UART_PROTO_SET, &hu->flags);
-+ return err;
-+ }
-+ tty->low_latency = 1;
-+ } else
-+ return -EBUSY;
-+
-+ case HCIUARTGETPROTO:
-+ if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
-+ return hu->proto->id;
-+ return -EUNATCH;
-+
-+ default:
-+ err = n_tty_ioctl(tty, file, cmd, arg);
-+ break;
-+ };
-+
-+ return err;
-+}
-+
-+/*
-+ * We don't provide read/write/poll interface for user space.
-+ */
-+static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr)
-+{
-+ return 0;
-+}
-+static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
-+{
-+ return 0;
-+}
-+static unsigned int hci_uart_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
-+{
-+ return 0;
-+}
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_H4
-+int h4_init(void);
-+int h4_deinit(void);
-+#endif
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP
-+int bcsp_init(void);
-+int bcsp_deinit(void);
-+#endif
-+
-+int __init hci_uart_init(void)
-+{
-+ static struct tty_ldisc hci_uart_ldisc;
-+ int err;
-+
-+ BT_INFO("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-+ VERSION);
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+
-+ /* Register the tty discipline */
-+
-+ memset(&hci_uart_ldisc, 0, sizeof (hci_uart_ldisc));
-+ hci_uart_ldisc.magic = TTY_LDISC_MAGIC;
-+ hci_uart_ldisc.name = "n_hci";
-+ hci_uart_ldisc.open = hci_uart_tty_open;
-+ hci_uart_ldisc.close = hci_uart_tty_close;
-+ hci_uart_ldisc.read = hci_uart_tty_read;
-+ hci_uart_ldisc.write = hci_uart_tty_write;
-+ hci_uart_ldisc.ioctl = hci_uart_tty_ioctl;
-+ hci_uart_ldisc.poll = hci_uart_tty_poll;
-+ hci_uart_ldisc.receive_room= hci_uart_tty_room;
-+ hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
-+ hci_uart_ldisc.write_wakeup= hci_uart_tty_wakeup;
-+
-+ if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) {
-+ BT_ERR("Can't register HCI line discipline (%d)", err);
-+ return err;
-+ }
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_H4
-+ h4_init();
-+#endif
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP
-+ bcsp_init();
-+#endif
-+
-+ return 0;
-+}
-+
-+void hci_uart_cleanup(void)
-+{
-+ int err;
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_H4
-+ h4_deinit();
-+#endif
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP
-+ bcsp_deinit();
-+#endif
-+
-+ /* Release tty registration of line discipline */
-+ if ((err = tty_register_ldisc(N_HCI, NULL)))
-+ BT_ERR("Can't unregister HCI line discipline (%d)", err);
-+}
-+
-+module_init(hci_uart_init);
-+module_exit(hci_uart_cleanup);
-+
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
-+MODULE_DESCRIPTION("BlueZ HCI UART driver ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/drivers/bluetooth/hci_uart.c linux-2.4.18-mh15/drivers/bluetooth/hci_uart.c
---- linux-2.4.18/drivers/bluetooth/hci_uart.c 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_uart.c 1970-01-01 01:00:00.000000000 +0100
-@@ -1,580 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * BlueZ HCI UART driver.
-- *
-- * $Id$
-- */
--#define VERSION "1.0"
--
--#include <linux/config.h>
--#include <linux/module.h>
--
--#include <linux/version.h>
--#include <linux/config.h>
--#include <linux/kernel.h>
--#include <linux/init.h>
--#include <linux/sched.h>
--#include <linux/types.h>
--#include <linux/fcntl.h>
--#include <linux/interrupt.h>
--#include <linux/ptrace.h>
--#include <linux/poll.h>
--
--#include <linux/slab.h>
--#include <linux/tty.h>
--#include <linux/errno.h>
--#include <linux/string.h>
--#include <linux/signal.h>
--#include <linux/ioctl.h>
--#include <linux/skbuff.h>
--
--#include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
--#include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/hci_uart.h>
--
--#ifndef HCI_UART_DEBUG
--#undef DBG
--#define DBG( A... )
--#undef DMP
--#define DMP( A... )
--#endif
--
--/* ------- Interface to HCI layer ------ */
--/* Initialize device */
--int n_hci_open(struct hci_dev *hdev)
--{
-- DBG("%s %p", hdev->name, hdev);
--
-- /* Nothing to do for UART driver */
--
-- hdev->flags |= HCI_RUNNING;
--
-- return 0;
--}
--
--/* Reset device */
--int n_hci_flush(struct hci_dev *hdev)
--{
-- struct n_hci *n_hci = (struct n_hci *) hdev->driver_data;
-- struct tty_struct *tty = n_hci->tty;
--
-- DBG("hdev %p tty %p", hdev, tty);
--
-- /* Drop TX queue */
-- skb_queue_purge(&n_hci->txq);
--
-- /* Flush any pending characters in the driver and discipline. */
-- if (tty->ldisc.flush_buffer)
-- tty->ldisc.flush_buffer(tty);
--
-- if (tty->driver.flush_buffer)
-- tty->driver.flush_buffer(tty);
--
-- return 0;
--}
--
--/* Close device */
--int n_hci_close(struct hci_dev *hdev)
--{
-- DBG("hdev %p", hdev);
--
-- hdev->flags &= ~HCI_RUNNING;
--
-- n_hci_flush(hdev);
--
-- return 0;
--}
--
--int n_hci_tx_wakeup(struct n_hci *n_hci)
--{
-- register struct tty_struct *tty = n_hci->tty;
--
-- if (test_and_set_bit(TRANS_SENDING, &n_hci->tx_state)) {
-- set_bit(TRANS_WAKEUP, &n_hci->tx_state);
-- return 0;
-- }
--
-- DBG("");
-- do {
-- register struct sk_buff *skb;
-- register int len;
--
-- clear_bit(TRANS_WAKEUP, &n_hci->tx_state);
--
-- if (!(skb = skb_dequeue(&n_hci->txq)))
-- break;
--
-- DMP(skb->data, skb->len);
--
-- /* Send frame to TTY driver */
-- tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
-- len = tty->driver.write(tty, 0, skb->data, skb->len);
--
-- n_hci->hdev.stat.byte_tx += len;
--
-- DBG("sent %d", len);
--
-- if (len == skb->len) {
-- /* Full frame was sent */
-- kfree_skb(skb);
-- } else {
-- /* Subtract sent part and requeue */
-- skb_pull(skb, len);
-- skb_queue_head(&n_hci->txq, skb);
-- }
-- } while (test_bit(TRANS_WAKEUP, &n_hci->tx_state));
-- clear_bit(TRANS_SENDING, &n_hci->tx_state);
--
-- return 0;
--}
--
--/* Send frames from HCI layer */
--int n_hci_send_frame(struct sk_buff *skb)
--{
-- struct hci_dev* hdev = (struct hci_dev *) skb->dev;
-- struct tty_struct *tty;
-- struct n_hci *n_hci;
--
-- if (!hdev) {
-- ERR("Frame for uknown device (hdev=NULL)");
-- return -ENODEV;
-- }
--
-- if (!(hdev->flags & HCI_RUNNING))
-- return -EBUSY;
--
-- n_hci = (struct n_hci *) hdev->driver_data;
-- tty = n_hci2tty(n_hci);
--
-- DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
--
-- switch (skb->pkt_type) {
-- case HCI_COMMAND_PKT:
-- hdev->stat.cmd_tx++;
-- break;
--
-- case HCI_ACLDATA_PKT:
-- hdev->stat.acl_tx++;
-- break;
--
-- case HCI_SCODATA_PKT:
-- hdev->stat.cmd_tx++;
-- break;
-- };
--
-- /* Prepend skb with frame type and queue */
-- memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
-- skb_queue_tail(&n_hci->txq, skb);
--
-- n_hci_tx_wakeup(n_hci);
--
-- return 0;
--}
--
--/* ------ LDISC part ------ */
--
--/* n_hci_tty_open
-- *
-- * Called when line discipline changed to N_HCI.
-- *
-- * Arguments:
-- * tty pointer to tty info structure
-- * Return Value:
-- * 0 if success, otherwise error code
-- */
--static int n_hci_tty_open(struct tty_struct *tty)
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
-- struct hci_dev *hdev;
--
-- DBG("tty %p", tty);
--
-- if (n_hci)
-- return -EEXIST;
--
-- if (!(n_hci = kmalloc(sizeof(struct n_hci), GFP_KERNEL))) {
-- ERR("Can't allocate controll structure");
-- return -ENFILE;
-- }
-- memset(n_hci, 0, sizeof(struct n_hci));
--
-- /* Initialize and register HCI device */
-- hdev = &n_hci->hdev;
--
-- hdev->type = HCI_UART;
-- hdev->driver_data = n_hci;
--
-- hdev->open = n_hci_open;
-- hdev->close = n_hci_close;
-- hdev->flush = n_hci_flush;
-- hdev->send = n_hci_send_frame;
--
-- if (hci_register_dev(hdev) < 0) {
-- ERR("Can't register HCI device %s", hdev->name);
-- kfree(n_hci);
-- return -ENODEV;
-- }
--
-- tty->disc_data = n_hci;
-- n_hci->tty = tty;
--
-- spin_lock_init(&n_hci->rx_lock);
-- n_hci->rx_state = WAIT_PACKET_TYPE;
--
-- skb_queue_head_init(&n_hci->txq);
--
-- MOD_INC_USE_COUNT;
--
-- /* Flush any pending characters in the driver and discipline. */
-- if (tty->ldisc.flush_buffer)
-- tty->ldisc.flush_buffer(tty);
--
-- if (tty->driver.flush_buffer)
-- tty->driver.flush_buffer(tty);
--
-- return 0;
--}
--
--/* n_hci_tty_close()
-- *
-- * Called when the line discipline is changed to something
-- * else, the tty is closed, or the tty detects a hangup.
-- */
--static void n_hci_tty_close(struct tty_struct *tty)
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
-- struct hci_dev *hdev = &n_hci->hdev;
--
-- DBG("tty %p hdev %p", tty, hdev);
--
-- if (n_hci != NULL) {
-- n_hci_close(hdev);
--
-- if (hci_unregister_dev(hdev) < 0) {
-- ERR("Can't unregister HCI device %s",hdev->name);
-- }
--
-- hdev->driver_data = NULL;
-- tty->disc_data = NULL;
-- kfree(n_hci);
--
-- MOD_DEC_USE_COUNT;
-- }
--}
--
--/* n_hci_tty_wakeup()
-- *
-- * Callback for transmit wakeup. Called when low level
-- * device driver can accept more send data.
-- *
-- * Arguments: tty pointer to associated tty instance data
-- * Return Value: None
-- */
--static void n_hci_tty_wakeup( struct tty_struct *tty )
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
--
-- DBG("");
--
-- if (!n_hci)
-- return;
--
-- tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
--
-- if (tty != n_hci->tty)
-- return;
--
-- n_hci_tx_wakeup(n_hci);
--}
--
--/* n_hci_tty_room()
-- *
-- * Callback function from tty driver. Return the amount of
-- * space left in the receiver's buffer to decide if remote
-- * transmitter is to be throttled.
-- *
-- * Arguments: tty pointer to associated tty instance data
-- * Return Value: number of bytes left in receive buffer
-- */
--static int n_hci_tty_room (struct tty_struct *tty)
--{
-- return 65536;
--}
--
--static inline int n_hci_check_data_len(struct n_hci *n_hci, int len)
--{
-- register int room = skb_tailroom(n_hci->rx_skb);
--
-- DBG("len %d room %d", len, room);
-- if (!len) {
-- DMP(n_hci->rx_skb->data, n_hci->rx_skb->len);
-- hci_recv_frame(n_hci->rx_skb);
-- } else if (len > room) {
-- ERR("Data length is to large");
-- kfree_skb(n_hci->rx_skb);
-- n_hci->hdev.stat.err_rx++;
-- } else {
-- n_hci->rx_state = WAIT_DATA;
-- n_hci->rx_count = len;
-- return len;
-- }
--
-- n_hci->rx_state = WAIT_PACKET_TYPE;
-- n_hci->rx_skb = NULL;
-- n_hci->rx_count = 0;
-- return 0;
--}
--
--static inline void n_hci_rx(struct n_hci *n_hci, const __u8 * data, char *flags, int count)
--{
-- register const char *ptr;
-- hci_event_hdr *eh;
-- hci_acl_hdr *ah;
-- hci_sco_hdr *sh;
-- register int len, type, dlen;
--
-- DBG("count %d state %ld rx_count %ld", count, n_hci->rx_state, n_hci->rx_count);
--
-- n_hci->hdev.stat.byte_rx += count;
--
-- ptr = data;
-- while (count) {
-- if (n_hci->rx_count) {
-- len = MIN(n_hci->rx_count, count);
-- memcpy(skb_put(n_hci->rx_skb, len), ptr, len);
-- n_hci->rx_count -= len; count -= len; ptr += len;
--
-- if (n_hci->rx_count)
-- continue;
--
-- switch (n_hci->rx_state) {
-- case WAIT_DATA:
-- DBG("Complete data");
--
-- DMP(n_hci->rx_skb->data, n_hci->rx_skb->len);
--
-- hci_recv_frame(n_hci->rx_skb);
--
-- n_hci->rx_state = WAIT_PACKET_TYPE;
-- n_hci->rx_skb = NULL;
-- continue;
--
-- case WAIT_EVENT_HDR:
-- eh = (hci_event_hdr *) n_hci->rx_skb->data;
--
-- DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
--
-- n_hci_check_data_len(n_hci, eh->plen);
-- continue;
--
-- case WAIT_ACL_HDR:
-- ah = (hci_acl_hdr *) n_hci->rx_skb->data;
-- dlen = __le16_to_cpu(ah->dlen);
--
-- DBG("ACL header: dlen %d", dlen);
--
-- n_hci_check_data_len(n_hci, dlen);
-- continue;
--
-- case WAIT_SCO_HDR:
-- sh = (hci_sco_hdr *) n_hci->rx_skb->data;
--
-- DBG("SCO header: dlen %d", sh->dlen);
--
-- n_hci_check_data_len(n_hci, sh->dlen);
-- continue;
-- };
-- }
--
-- /* WAIT_PACKET_TYPE */
-- switch (*ptr) {
-- case HCI_EVENT_PKT:
-- DBG("Event packet");
-- n_hci->rx_state = WAIT_EVENT_HDR;
-- n_hci->rx_count = HCI_EVENT_HDR_SIZE;
-- type = HCI_EVENT_PKT;
-- break;
--
-- case HCI_ACLDATA_PKT:
-- DBG("ACL packet");
-- n_hci->rx_state = WAIT_ACL_HDR;
-- n_hci->rx_count = HCI_ACL_HDR_SIZE;
-- type = HCI_ACLDATA_PKT;
-- break;
--
-- case HCI_SCODATA_PKT:
-- DBG("SCO packet");
-- n_hci->rx_state = WAIT_SCO_HDR;
-- n_hci->rx_count = HCI_SCO_HDR_SIZE;
-- type = HCI_SCODATA_PKT;
-- break;
--
-- default:
-- ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
-- n_hci->hdev.stat.err_rx++;
-- ptr++; count--;
-- continue;
-- };
-- ptr++; count--;
--
-- /* Allocate packet */
-- if (!(n_hci->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-- ERR("Can't allocate mem for new packet");
--
-- n_hci->rx_state = WAIT_PACKET_TYPE;
-- n_hci->rx_count = 0;
-- return;
-- }
-- n_hci->rx_skb->dev = (void *) &n_hci->hdev;
-- n_hci->rx_skb->pkt_type = type;
-- }
--}
--
--/* n_hci_tty_receive()
-- *
-- * Called by tty low level driver when receive data is
-- * available.
-- *
-- * Arguments: tty pointer to tty isntance data
-- * data pointer to received data
-- * flags pointer to flags for data
-- * count count of received data in bytes
-- *
-- * Return Value: None
-- */
--static void n_hci_tty_receive(struct tty_struct *tty, const __u8 * data, char *flags, int count)
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
--
-- if (!n_hci || tty != n_hci->tty)
-- return;
--
-- spin_lock(&n_hci->rx_lock);
-- n_hci_rx(n_hci, data, flags, count);
-- spin_unlock(&n_hci->rx_lock);
--
-- if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver.unthrottle)
-- tty->driver.unthrottle(tty);
--}
--
--/* n_hci_tty_ioctl()
-- *
-- * Process IOCTL system call for the tty device.
-- *
-- * Arguments:
-- *
-- * tty pointer to tty instance data
-- * file pointer to open file object for device
-- * cmd IOCTL command code
-- * arg argument for IOCTL call (cmd dependent)
-- *
-- * Return Value: Command dependent
-- */
--static int n_hci_tty_ioctl (struct tty_struct *tty, struct file * file,
-- unsigned int cmd, unsigned long arg)
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
-- int error = 0;
--
-- DBG("");
--
-- /* Verify the status of the device */
-- if (!n_hci)
-- return -EBADF;
--
-- switch (cmd) {
-- default:
-- error = n_tty_ioctl(tty, file, cmd, arg);
-- break;
-- };
--
-- return error;
--}
--
--/*
-- * We don't provide read/write/poll interface for user space.
-- */
--static ssize_t n_hci_tty_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr)
--{
-- return 0;
--}
--static ssize_t n_hci_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
--{
-- return 0;
--}
--static unsigned int n_hci_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
--{
-- return 0;
--}
--
--int __init n_hci_init(void)
--{
-- static struct tty_ldisc n_hci_ldisc;
-- int err;
--
-- INF("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
--
-- /* Register the tty discipline */
--
-- memset(&n_hci_ldisc, 0, sizeof (n_hci_ldisc));
-- n_hci_ldisc.magic = TTY_LDISC_MAGIC;
-- n_hci_ldisc.name = "n_hci";
-- n_hci_ldisc.open = n_hci_tty_open;
-- n_hci_ldisc.close = n_hci_tty_close;
-- n_hci_ldisc.read = n_hci_tty_read;
-- n_hci_ldisc.write = n_hci_tty_write;
-- n_hci_ldisc.ioctl = n_hci_tty_ioctl;
-- n_hci_ldisc.poll = n_hci_tty_poll;
-- n_hci_ldisc.receive_room= n_hci_tty_room;
-- n_hci_ldisc.receive_buf = n_hci_tty_receive;
-- n_hci_ldisc.write_wakeup= n_hci_tty_wakeup;
--
-- if ((err = tty_register_ldisc(N_HCI, &n_hci_ldisc))) {
-- ERR("Can't register HCI line discipline (%d)", err);
-- return err;
-- }
--
-- return 0;
--}
--
--void n_hci_cleanup(void)
--{
-- int err;
--
-- /* Release tty registration of line discipline */
-- if ((err = tty_register_ldisc(N_HCI, NULL)))
-- ERR("Can't unregister HCI line discipline (%d)", err);
--}
--
--module_init(n_hci_init);
--module_exit(n_hci_cleanup);
--
--MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
--MODULE_DESCRIPTION("BlueZ HCI UART driver ver " VERSION);
--MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/drivers/bluetooth/hci_uart.h linux-2.4.18-mh15/drivers/bluetooth/hci_uart.h
---- linux-2.4.18/drivers/bluetooth/hci_uart.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_uart.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,82 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef N_HCI
-+#define N_HCI 15
-+#endif
-+
-+/* Ioctls */
-+#define HCIUARTSETPROTO _IOW('U', 200, int)
-+#define HCIUARTGETPROTO _IOR('U', 201, int)
-+
-+/* UART protocols */
-+#define HCI_UART_MAX_PROTO 4
-+
-+#define HCI_UART_H4 0
-+#define HCI_UART_BCSP 1
-+#define HCI_UART_3WIRE 2
-+#define HCI_UART_H4DS 3
-+
-+#ifdef __KERNEL__
-+struct hci_uart;
-+
-+struct hci_uart_proto {
-+ unsigned int id;
-+ int (*open)(struct hci_uart *hu);
-+ int (*close)(struct hci_uart *hu);
-+ int (*flush)(struct hci_uart *hu);
-+ int (*recv)(struct hci_uart *hu, void *data, int len);
-+ int (*enqueue)(struct hci_uart *hu, struct sk_buff *skb);
-+ struct sk_buff *(*dequeue)(struct hci_uart *hu);
-+};
-+
-+struct hci_uart {
-+ struct tty_struct *tty;
-+ struct hci_dev hdev;
-+ unsigned long flags;
-+
-+ struct hci_uart_proto *proto;
-+ void *priv;
-+
-+ struct sk_buff *tx_skb;
-+ unsigned long tx_state;
-+ spinlock_t rx_lock;
-+};
-+
-+/* HCI_UART flag bits */
-+#define HCI_UART_PROTO_SET 0
-+
-+/* TX states */
-+#define HCI_UART_SENDING 1
-+#define HCI_UART_TX_WAKEUP 2
-+
-+int hci_uart_register_proto(struct hci_uart_proto *p);
-+int hci_uart_unregister_proto(struct hci_uart_proto *p);
-+int hci_uart_tx_wakeup(struct hci_uart *hu);
-+
-+#endif /* __KERNEL__ */
-diff -urN linux-2.4.18/drivers/bluetooth/hci_usb.c linux-2.4.18-mh15/drivers/bluetooth/hci_usb.c
---- linux-2.4.18/drivers/bluetooth/hci_usb.c 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_usb.c 2004-08-01 16:26:23.000000000 +0200
-@@ -1,9 +1,10 @@
- /*
-- BlueZ - Bluetooth protocol stack for Linux
-+ HCI USB driver for Linux Bluetooth protocol stack (BlueZ)
- Copyright (C) 2000-2001 Qualcomm Incorporated
--
- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-
-+ Copyright (C) 2003 Maxim Krasnyansky <maxk@qualcomm.com>
-+
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as
- published by the Free Software Foundation;
-@@ -23,598 +24,938 @@
- */
-
- /*
-- * BlueZ HCI USB driver.
- * Based on original USB Bluetooth driver for Linux kernel
- * Copyright (c) 2000 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (c) 2000 Mark Douglas Corner <mcorner@umich.edu>
- *
-- * $Id$
-+ * $Id$
- */
--#define VERSION "1.0"
-+#define VERSION "2.7"
-
- #include <linux/config.h>
- #include <linux/module.h>
-
- #include <linux/version.h>
--#include <linux/config.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/sched.h>
-+#include <linux/unistd.h>
- #include <linux/types.h>
--#include <linux/fcntl.h>
- #include <linux/interrupt.h>
--#include <linux/ptrace.h>
--#include <linux/poll.h>
-
- #include <linux/slab.h>
--#include <linux/tty.h>
- #include <linux/errno.h>
- #include <linux/string.h>
--#include <linux/signal.h>
--#include <linux/ioctl.h>
- #include <linux/skbuff.h>
-
- #include <linux/usb.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/hci_usb.h>
-+
-+#include "hci_usb.h"
-
- #ifndef HCI_USB_DEBUG
--#undef DBG
--#define DBG( A... )
--#undef DMP
--#define DMP( A... )
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#undef BT_DMP
-+#define BT_DMP( A... )
- #endif
-
--static struct usb_device_id usb_bluetooth_ids [] = {
-+#ifndef CONFIG_BLUEZ_HCIUSB_ZERO_PACKET
-+#undef USB_ZERO_PACKET
-+#define USB_ZERO_PACKET 0
-+#endif
-+
-+static struct usb_driver hci_usb_driver;
-+
-+static struct usb_device_id bluetooth_ids[] = {
-+ /* Generic Bluetooth USB device */
- { USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) },
-+
-+ /* AVM BlueFRITZ! USB v2.0 */
-+ { USB_DEVICE(0x057c, 0x3800) },
-+
-+ /* Bluetooth Ultraport Module from IBM */
-+ { USB_DEVICE(0x04bf, 0x030a) },
-+
-+ /* ALPS Modules with non-standard id */
-+ { USB_DEVICE(0x044e, 0x3001) },
-+ { USB_DEVICE(0x044e, 0x3002) },
-+
-+ /* Ericsson with non-standard id */
-+ { USB_DEVICE(0x0bdb, 0x1002) },
-+
- { } /* Terminating entry */
- };
-
--MODULE_DEVICE_TABLE (usb, usb_bluetooth_ids);
-+MODULE_DEVICE_TABLE (usb, bluetooth_ids);
-
--static int hci_usb_ctrl_msg(struct hci_usb *husb, struct sk_buff *skb);
--static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb);
-+static struct usb_device_id blacklist_ids[] = {
-+ /* Broadcom BCM2033 without firmware */
-+ { USB_DEVICE(0x0a5c, 0x2033), driver_info: HCI_IGNORE },
-
--static void hci_usb_unlink_urbs(struct hci_usb *husb)
-+ /* Broadcom BCM2035 */
-+ { USB_DEVICE(0x0a5c, 0x200a), driver_info: HCI_RESET },
-+
-+ /* ISSC Bluetooth Adapter v3.1 */
-+ { USB_DEVICE(0x1131, 0x1001), driver_info: HCI_RESET },
-+
-+ /* Digianswer device */
-+ { USB_DEVICE(0x08fd, 0x0001), driver_info: HCI_DIGIANSWER },
-+
-+ /* RTX Telecom based adapter with buggy SCO support */
-+ { USB_DEVICE(0x0400, 0x0807), driver_info: HCI_BROKEN_ISOC },
-+
-+ { } /* Terminating entry */
-+};
-+
-+struct _urb *_urb_alloc(int isoc, int gfp)
- {
-- usb_unlink_urb(husb->read_urb);
-- usb_unlink_urb(husb->intr_urb);
-- usb_unlink_urb(husb->ctrl_urb);
-- usb_unlink_urb(husb->write_urb);
-+ struct _urb *_urb = kmalloc(sizeof(struct _urb) +
-+ sizeof(iso_packet_descriptor_t) * isoc, gfp);
-+ if (_urb) {
-+ memset(_urb, 0, sizeof(*_urb));
-+ spin_lock_init(&_urb->urb.lock);
-+ }
-+ return _urb;
-+}
-+
-+struct _urb *_urb_dequeue(struct _urb_queue *q)
-+{
-+ struct _urb *_urb = NULL;
-+ unsigned long flags;
-+ spin_lock_irqsave(&q->lock, flags);
-+ {
-+ struct list_head *head = &q->head;
-+ struct list_head *next = head->next;
-+ if (next != head) {
-+ _urb = list_entry(next, struct _urb, list);
-+ list_del(next); _urb->queue = NULL;
-+ }
-+ }
-+ spin_unlock_irqrestore(&q->lock, flags);
-+ return _urb;
- }
-
--static void hci_usb_free_bufs(struct hci_usb *husb)
-+static void hci_usb_rx_complete(struct urb *urb);
-+static void hci_usb_tx_complete(struct urb *urb);
-+
-+#define __pending_tx(husb, type) (&husb->pending_tx[type-1])
-+#define __pending_q(husb, type) (&husb->pending_q[type-1])
-+#define __completed_q(husb, type) (&husb->completed_q[type-1])
-+#define __transmit_q(husb, type) (&husb->transmit_q[type-1])
-+#define __reassembly(husb, type) (husb->reassembly[type-1])
-+
-+static inline struct _urb *__get_completed(struct hci_usb *husb, int type)
- {
-- if (husb->read_urb) {
-- if (husb->read_urb->transfer_buffer)
-- kfree(husb->read_urb->transfer_buffer);
-- usb_free_urb(husb->read_urb);
-- }
-+ return _urb_dequeue(__completed_q(husb, type));
-+}
-
-- if (husb->intr_urb) {
-- if (husb->intr_urb->transfer_buffer)
-- kfree(husb->intr_urb->transfer_buffer);
-- usb_free_urb(husb->intr_urb);
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+static void __fill_isoc_desc(struct urb *urb, int len, int mtu)
-+{
-+ int offset = 0, i;
-+
-+ BT_DBG("len %d mtu %d", len, mtu);
-+
-+ for (i=0; i < HCI_MAX_ISOC_FRAMES && len >= mtu; i++, offset += mtu, len -= mtu) {
-+ urb->iso_frame_desc[i].offset = offset;
-+ urb->iso_frame_desc[i].length = mtu;
-+ BT_DBG("desc %d offset %d len %d", i, offset, mtu);
-+ }
-+ if (len && i < HCI_MAX_ISOC_FRAMES) {
-+ urb->iso_frame_desc[i].offset = offset;
-+ urb->iso_frame_desc[i].length = len;
-+ BT_DBG("desc %d offset %d len %d", i, offset, len);
-+ i++;
- }
-+ urb->number_of_packets = i;
-+}
-+#endif
-
-- if (husb->ctrl_urb)
-- usb_free_urb(husb->ctrl_urb);
-+static int hci_usb_intr_rx_submit(struct hci_usb *husb)
-+{
-+ struct _urb *_urb;
-+ struct urb *urb;
-+ int err, pipe, interval, size;
-+ void *buf;
-+
-+ BT_DBG("%s", husb->hdev.name);
-+
-+ size = husb->intr_in_ep->wMaxPacketSize;
-+
-+ buf = kmalloc(size, GFP_ATOMIC);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ _urb = _urb_alloc(0, GFP_ATOMIC);
-+ if (!_urb) {
-+ kfree(buf);
-+ return -ENOMEM;
-+ }
-+ _urb->type = HCI_EVENT_PKT;
-+ _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
-+
-+ urb = &_urb->urb;
-+ pipe = usb_rcvintpipe(husb->udev, husb->intr_in_ep->bEndpointAddress);
-+ interval = husb->intr_in_ep->bInterval;
-+ FILL_INT_URB(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb, interval);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s intr rx submit failed urb %p err %d",
-+ husb->hdev.name, urb, err);
-+ _urb_unlink(_urb);
-+ _urb_free(_urb);
-+ kfree(buf);
-+ }
-+ return err;
-+}
-
-- if (husb->write_urb)
-- usb_free_urb(husb->write_urb);
-+static int hci_usb_bulk_rx_submit(struct hci_usb *husb)
-+{
-+ struct _urb *_urb;
-+ struct urb *urb;
-+ int err, pipe, size = HCI_MAX_FRAME_SIZE;
-+ void *buf;
-+
-+ buf = kmalloc(size, GFP_ATOMIC);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ _urb = _urb_alloc(0, GFP_ATOMIC);
-+ if (!_urb) {
-+ kfree(buf);
-+ return -ENOMEM;
-+ }
-+ _urb->type = HCI_ACLDATA_PKT;
-+ _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
-+
-+ urb = &_urb->urb;
-+ pipe = usb_rcvbulkpipe(husb->udev, husb->bulk_in_ep->bEndpointAddress);
-+ FILL_BULK_URB(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb);
-+ urb->transfer_flags = USB_QUEUE_BULK;
-+
-+ BT_DBG("%s urb %p", husb->hdev.name, urb);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s bulk rx submit failed urb %p err %d",
-+ husb->hdev.name, urb, err);
-+ _urb_unlink(_urb);
-+ _urb_free(_urb);
-+ kfree(buf);
-+ }
-+ return err;
-+}
-
-- if (husb->intr_skb)
-- kfree_skb(husb->intr_skb);
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+static int hci_usb_isoc_rx_submit(struct hci_usb *husb)
-+{
-+ struct _urb *_urb;
-+ struct urb *urb;
-+ int err, mtu, size;
-+ void *buf;
-+
-+ mtu = husb->isoc_in_ep->wMaxPacketSize;
-+ size = mtu * HCI_MAX_ISOC_FRAMES;
-+
-+ buf = kmalloc(size, GFP_ATOMIC);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
-+ if (!_urb) {
-+ kfree(buf);
-+ return -ENOMEM;
-+ }
-+ _urb->type = HCI_SCODATA_PKT;
-+ _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
-+
-+ urb = &_urb->urb;
-+
-+ urb->context = husb;
-+ urb->dev = husb->udev;
-+ urb->pipe = usb_rcvisocpipe(husb->udev, husb->isoc_in_ep->bEndpointAddress);
-+ urb->complete = hci_usb_rx_complete;
-+
-+ urb->transfer_buffer_length = size;
-+ urb->transfer_buffer = buf;
-+ urb->transfer_flags = USB_ISO_ASAP;
-+
-+ __fill_isoc_desc(urb, size, mtu);
-+
-+ BT_DBG("%s urb %p", husb->hdev.name, urb);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s isoc rx submit failed urb %p err %d",
-+ husb->hdev.name, urb, err);
-+ _urb_unlink(_urb);
-+ _urb_free(_urb);
-+ kfree(buf);
-+ }
-+ return err;
- }
-+#endif
-
--/* ------- Interface to HCI layer ------ */
- /* Initialize device */
--int hci_usb_open(struct hci_dev *hdev)
-+static int hci_usb_open(struct hci_dev *hdev)
- {
- struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-- int status;
-+ int i, err;
-+ unsigned long flags;
-+
-+ BT_DBG("%s", hdev->name);
-
-- DBG("%s", hdev->name);
-+ if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-
-- husb->read_urb->dev = husb->udev;
-- if ((status = usb_submit_urb(husb->read_urb)))
-- DBG("read submit failed. %d", status);
-+ MOD_INC_USE_COUNT;
-
-- husb->intr_urb->dev = husb->udev;
-- if ((status = usb_submit_urb(husb->intr_urb)))
-- DBG("interrupt submit failed. %d", status);
-+ write_lock_irqsave(&husb->completion_lock, flags);
-
-- hdev->flags |= HCI_RUNNING;
-+ err = hci_usb_intr_rx_submit(husb);
-+ if (!err) {
-+ for (i = 0; i < HCI_MAX_BULK_RX; i++)
-+ hci_usb_bulk_rx_submit(husb);
-+
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ if (husb->isoc_iface)
-+ for (i = 0; i < HCI_MAX_ISOC_RX; i++)
-+ hci_usb_isoc_rx_submit(husb);
-+#endif
-+ } else {
-+ clear_bit(HCI_RUNNING, &hdev->flags);
-+ MOD_DEC_USE_COUNT;
-+ }
-
-- return 0;
-+ write_unlock_irqrestore(&husb->completion_lock, flags);
-+ return err;
- }
-
- /* Reset device */
--int hci_usb_flush(struct hci_dev *hdev)
-+static int hci_usb_flush(struct hci_dev *hdev)
- {
- struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-+ int i;
-
-- DBG("%s", hdev->name);
--
-- /* Drop TX queues */
-- skb_queue_purge(&husb->tx_ctrl_q);
-- skb_queue_purge(&husb->tx_write_q);
-+ BT_DBG("%s", hdev->name);
-
-+ for (i=0; i < 4; i++)
-+ skb_queue_purge(&husb->transmit_q[i]);
- return 0;
- }
-
--/* Close device */
--int hci_usb_close(struct hci_dev *hdev)
-+static void hci_usb_unlink_urbs(struct hci_usb *husb)
- {
-- struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-+ int i;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s", husb->hdev.name);
-
-- hdev->flags &= ~HCI_RUNNING;
-- hci_usb_unlink_urbs(husb);
-+ for (i=0; i < 4; i++) {
-+ struct _urb *_urb;
-+ struct urb *urb;
-+
-+ /* Kill pending requests */
-+ while ((_urb = _urb_dequeue(&husb->pending_q[i]))) {
-+ urb = &_urb->urb;
-+ BT_DBG("%s unlinking _urb %p type %d urb %p",
-+ husb->hdev.name, _urb, _urb->type, urb);
-+ usb_unlink_urb(urb);
-+ _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
-+ }
-
-- hci_usb_flush(hdev);
-+ /* Release completed requests */
-+ while ((_urb = _urb_dequeue(&husb->completed_q[i]))) {
-+ urb = &_urb->urb;
-+ BT_DBG("%s freeing _urb %p type %d urb %p",
-+ husb->hdev.name, _urb, _urb->type, urb);
-+ if (urb->setup_packet)
-+ kfree(urb->setup_packet);
-+ if (urb->transfer_buffer)
-+ kfree(urb->transfer_buffer);
-+ _urb_free(_urb);
-+ }
-
-- return 0;
-+ /* Release reassembly buffers */
-+ if (husb->reassembly[i]) {
-+ kfree_skb(husb->reassembly[i]);
-+ husb->reassembly[i] = NULL;
-+ }
-+ }
- }
-
--void hci_usb_ctrl_wakeup(struct hci_usb *husb)
-+/* Close device */
-+static int hci_usb_close(struct hci_dev *hdev)
- {
-- struct sk_buff *skb;
-+ struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-+ unsigned long flags;
-+
-+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-
-- if (test_and_set_bit(HCI_TX_CTRL, &husb->tx_state))
-- return;
-+ BT_DBG("%s", hdev->name);
-
-- DBG("%s", husb->hdev.name);
-+ write_lock_irqsave(&husb->completion_lock, flags);
-+
-+ hci_usb_unlink_urbs(husb);
-+ hci_usb_flush(hdev);
-
-- if (!(skb = skb_dequeue(&husb->tx_ctrl_q)))
-- goto done;
-+ write_unlock_irqrestore(&husb->completion_lock, flags);
-
-- if (hci_usb_ctrl_msg(husb, skb)){
-- kfree_skb(skb);
-- goto done;
-- }
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-
-- DMP(skb->data, skb->len);
-+static int __tx_submit(struct hci_usb *husb, struct _urb *_urb)
-+{
-+ struct urb *urb = &_urb->urb;
-+ int err;
-
-- husb->hdev.stat.byte_tx += skb->len;
-- return;
-+ BT_DBG("%s urb %p type %d", husb->hdev.name, urb, _urb->type);
-+
-+ _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s tx submit failed urb %p type %d err %d",
-+ husb->hdev.name, urb, _urb->type, err);
-+ _urb_unlink(_urb);
-+ _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
-+ } else
-+ atomic_inc(__pending_tx(husb, _urb->type));
-
--done:
-- clear_bit(HCI_TX_CTRL, &husb->tx_state);
-- return;
-+ return err;
- }
-
--void hci_usb_write_wakeup(struct hci_usb *husb)
-+static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
- {
-- struct sk_buff *skb;
-+ struct _urb *_urb = __get_completed(husb, skb->pkt_type);
-+ devrequest *dr;
-+ struct urb *urb;
-+
-+ if (!_urb) {
-+ _urb = _urb_alloc(0, GFP_ATOMIC);
-+ if (!_urb)
-+ return -ENOMEM;
-+ _urb->type = skb->pkt_type;
-+
-+ dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
-+ if (!dr) {
-+ _urb_free(_urb);
-+ return -ENOMEM;
-+ }
-+ } else
-+ dr = (void *) _urb->urb.setup_packet;
-
-- if (test_and_set_bit(HCI_TX_WRITE, &husb->tx_state))
-- return;
-+ dr->requesttype = husb->ctrl_req;
-+ dr->request = 0;
-+ dr->index = 0;
-+ dr->value = 0;
-+ dr->length = __cpu_to_le16(skb->len);
-
-- DBG("%s", husb->hdev.name);
-+ urb = &_urb->urb;
-+ FILL_CONTROL_URB(urb, husb->udev, usb_sndctrlpipe(husb->udev, 0),
-+ (void *) dr, skb->data, skb->len, hci_usb_tx_complete, husb);
-
-- if (!(skb = skb_dequeue(&husb->tx_write_q)))
-- goto done;
-+ BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
-+
-+ _urb->priv = skb;
-+ return __tx_submit(husb, _urb);
-+}
-
-- if (hci_usb_write_msg(husb, skb)) {
-- skb_queue_head(&husb->tx_write_q, skb);
-- goto done;
-+static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
-+{
-+ struct _urb *_urb = __get_completed(husb, skb->pkt_type);
-+ struct urb *urb;
-+ int pipe;
-+
-+ if (!_urb) {
-+ _urb = _urb_alloc(0, GFP_ATOMIC);
-+ if (!_urb)
-+ return -ENOMEM;
-+ _urb->type = skb->pkt_type;
- }
-
-- DMP(skb->data, skb->len);
-+ urb = &_urb->urb;
-+ pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep->bEndpointAddress);
-+ FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,
-+ hci_usb_tx_complete, husb);
-+ urb->transfer_flags = USB_QUEUE_BULK | USB_ZERO_PACKET;
-
-- husb->hdev.stat.byte_tx += skb->len;
-- return;
-+ BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
-
--done:
-- clear_bit(HCI_TX_WRITE, &husb->tx_state);
-- return;
-+ _urb->priv = skb;
-+ return __tx_submit(husb, _urb);
- }
-
--/* Send frames from HCI layer */
--int hci_usb_send_frame(struct sk_buff *skb)
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb)
- {
-- struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-- struct hci_usb *husb;
--
-- if (!hdev) {
-- ERR("frame for uknown device (hdev=NULL)");
-- return -ENODEV;
-+ struct _urb *_urb = __get_completed(husb, skb->pkt_type);
-+ struct urb *urb;
-+
-+ if (!_urb) {
-+ _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
-+ if (!_urb)
-+ return -ENOMEM;
-+ _urb->type = skb->pkt_type;
- }
-
-- if (!(hdev->flags & HCI_RUNNING))
-- return 0;
-+ BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
-
-- husb = (struct hci_usb *) hdev->driver_data;
-+ urb = &_urb->urb;
-+
-+ urb->context = husb;
-+ urb->dev = husb->udev;
-+ urb->pipe = usb_sndisocpipe(husb->udev, husb->isoc_out_ep->bEndpointAddress);
-+ urb->complete = hci_usb_tx_complete;
-+ urb->transfer_flags = USB_ISO_ASAP;
-
-- DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-+ urb->transfer_buffer = skb->data;
-+ urb->transfer_buffer_length = skb->len;
-+
-+ __fill_isoc_desc(urb, skb->len, husb->isoc_out_ep->wMaxPacketSize);
-
-- switch (skb->pkt_type) {
-- case HCI_COMMAND_PKT:
-- skb_queue_tail(&husb->tx_ctrl_q, skb);
-- hci_usb_ctrl_wakeup(husb);
-- hdev->stat.cmd_tx++;
-- return 0;
--
-- case HCI_ACLDATA_PKT:
-- skb_queue_tail(&husb->tx_write_q, skb);
-- hci_usb_write_wakeup(husb);
-- hdev->stat.acl_tx++;
-- return 0;
--
-- case HCI_SCODATA_PKT:
-- return -EOPNOTSUPP;
-- };
--
-- return 0;
-+ _urb->priv = skb;
-+ return __tx_submit(husb, _urb);
- }
-+#endif
-
--/* ---------- USB ------------- */
--
--static void hci_usb_ctrl(struct urb *urb)
-+static void hci_usb_tx_process(struct hci_usb *husb)
- {
-- struct sk_buff *skb = (struct sk_buff *) urb->context;
-- struct hci_dev *hdev;
-- struct hci_usb *husb;
-+ struct sk_buff_head *q;
-+ struct sk_buff *skb;
-
-- if (!skb)
-- return;
-- hdev = (struct hci_dev *) skb->dev;
-- husb = (struct hci_usb *) hdev->driver_data;
-+ BT_DBG("%s", husb->hdev.name);
-
-- DBG("%s", hdev->name);
-+ do {
-+ clear_bit(HCI_USB_TX_WAKEUP, &husb->state);
-
-- if (urb->status)
-- DBG("%s ctrl status: %d", hdev->name, urb->status);
-+ /* Process command queue */
-+ q = __transmit_q(husb, HCI_COMMAND_PKT);
-+ if (!atomic_read(__pending_tx(husb, HCI_COMMAND_PKT)) &&
-+ (skb = skb_dequeue(q))) {
-+ if (hci_usb_send_ctrl(husb, skb) < 0)
-+ skb_queue_head(q, skb);
-+ }
-
-- clear_bit(HCI_TX_CTRL, &husb->tx_state);
-- kfree_skb(skb);
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ /* Process SCO queue */
-+ q = __transmit_q(husb, HCI_SCODATA_PKT);
-+ if (atomic_read(__pending_tx(husb, HCI_SCODATA_PKT)) < HCI_MAX_ISOC_TX &&
-+ (skb = skb_dequeue(q))) {
-+ if (hci_usb_send_isoc(husb, skb) < 0)
-+ skb_queue_head(q, skb);
-+ }
-+#endif
-+
-+ /* Process ACL queue */
-+ q = __transmit_q(husb, HCI_ACLDATA_PKT);
-+ while (atomic_read(__pending_tx(husb, HCI_ACLDATA_PKT)) < HCI_MAX_BULK_TX &&
-+ (skb = skb_dequeue(q))) {
-+ if (hci_usb_send_bulk(husb, skb) < 0) {
-+ skb_queue_head(q, skb);
-+ break;
-+ }
-+ }
-+ } while(test_bit(HCI_USB_TX_WAKEUP, &husb->state));
-+}
-
-- /* Wake up device */
-- hci_usb_ctrl_wakeup(husb);
-+static inline void hci_usb_tx_wakeup(struct hci_usb *husb)
-+{
-+ /* Serialize TX queue processing to avoid data reordering */
-+ if (!test_and_set_bit(HCI_USB_TX_PROCESS, &husb->state)) {
-+ hci_usb_tx_process(husb);
-+ clear_bit(HCI_USB_TX_PROCESS, &husb->state);
-+ } else
-+ set_bit(HCI_USB_TX_WAKEUP, &husb->state);
- }
-
--static void hci_usb_bulk_write(struct urb *urb)
-+/* Send frames from HCI layer */
-+static int hci_usb_send_frame(struct sk_buff *skb)
- {
-- struct sk_buff *skb = (struct sk_buff *) urb->context;
-- struct hci_dev *hdev;
-+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
- struct hci_usb *husb;
-
-- if (!skb)
-- return;
-- hdev = (struct hci_dev *) skb->dev;
-- husb = (struct hci_usb *) hdev->driver_data;
-+ if (!hdev) {
-+ BT_ERR("frame for uknown device (hdev=NULL)");
-+ return -ENODEV;
-+ }
-
-- DBG("%s", hdev->name);
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return -EBUSY;
-
-- if (urb->status)
-- DBG("%s bulk write status: %d", hdev->name, urb->status);
-+ BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-
-- clear_bit(HCI_TX_WRITE, &husb->tx_state);
-- kfree_skb(skb);
-+ husb = (struct hci_usb *) hdev->driver_data;
-
-- /* Wake up device */
-- hci_usb_write_wakeup(husb);
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+#endif
-
-- return;
--}
-+ default:
-+ kfree_skb(skb);
-+ return 0;
-+ }
-
--static void hci_usb_intr(struct urb *urb)
--{
-- struct hci_usb *husb = (struct hci_usb *) urb->context;
-- unsigned char *data = urb->transfer_buffer;
-- register int count = urb->actual_length;
-- register struct sk_buff *skb = husb->intr_skb;
-- hci_event_hdr *eh;
-- register int len;
-+ read_lock(&husb->completion_lock);
-
-- if (!husb)
-- return;
-+ skb_queue_tail(__transmit_q(husb, skb->pkt_type), skb);
-+ hci_usb_tx_wakeup(husb);
-
-- DBG("%s count %d", husb->hdev.name, count);
-+ read_unlock(&husb->completion_lock);
-+ return 0;
-+}
-
-- if (urb->status || !count) {
-- DBG("%s intr status %d, count %d", husb->hdev.name, urb->status, count);
-- return;
-- }
-+static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int count)
-+{
-+ BT_DBG("%s type %d data %p count %d", husb->hdev.name, type, data, count);
-
-- /* Do we really have to handle continuations here ? */
-- if (!skb) {
-- /* New frame */
-- if (count < HCI_EVENT_HDR_SIZE) {
-- DBG("%s bad frame len %d", husb->hdev.name, count);
-- return;
-- }
-+ husb->hdev.stat.byte_rx += count;
-
-- eh = (hci_event_hdr *) data;
-- len = eh->plen + HCI_EVENT_HDR_SIZE;
-+ while (count) {
-+ struct sk_buff *skb = __reassembly(husb, type);
-+ struct { int expect; } *scb;
-+ int len = 0;
-+
-+ if (!skb) {
-+ /* Start of the frame */
-+
-+ switch (type) {
-+ case HCI_EVENT_PKT:
-+ if (count >= HCI_EVENT_HDR_SIZE) {
-+ hci_event_hdr *h = data;
-+ len = HCI_EVENT_HDR_SIZE + h->plen;
-+ } else
-+ return -EILSEQ;
-+ break;
-
-- if (count > len) {
-- DBG("%s corrupted frame, len %d", husb->hdev.name, count);
-- return;
-- }
-+ case HCI_ACLDATA_PKT:
-+ if (count >= HCI_ACL_HDR_SIZE) {
-+ hci_acl_hdr *h = data;
-+ len = HCI_ACL_HDR_SIZE + __le16_to_cpu(h->dlen);
-+ } else
-+ return -EILSEQ;
-+ break;
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ case HCI_SCODATA_PKT:
-+ if (count >= HCI_SCO_HDR_SIZE) {
-+ hci_sco_hdr *h = data;
-+ len = HCI_SCO_HDR_SIZE + h->dlen;
-+ } else
-+ return -EILSEQ;
-+ break;
-+#endif
-+ }
-+ BT_DBG("new packet len %d", len);
-
-- /* Allocate skb */
-- if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {
-- ERR("Can't allocate mem for new packet");
-- return;
-+ skb = bluez_skb_alloc(len, GFP_ATOMIC);
-+ if (!skb) {
-+ BT_ERR("%s no memory for the packet", husb->hdev.name);
-+ return -ENOMEM;
-+ }
-+ skb->dev = (void *) &husb->hdev;
-+ skb->pkt_type = type;
-+
-+ __reassembly(husb, type) = skb;
-+
-+ scb = (void *) skb->cb;
-+ scb->expect = len;
-+ } else {
-+ /* Continuation */
-+ scb = (void *) skb->cb;
-+ len = scb->expect;
- }
-- skb->dev = (void *) &husb->hdev;
-- skb->pkt_type = HCI_EVENT_PKT;
--
-- husb->intr_skb = skb;
-- husb->intr_count = len;
-- } else {
-- /* Continuation */
-- if (count > husb->intr_count) {
-- ERR("%s bad frame len %d (expected %d)", husb->hdev.name, count, husb->intr_count);
-
-- kfree_skb(skb);
-- husb->intr_skb = NULL;
-- husb->intr_count = 0;
-- return;
-+ len = min(len, count);
-+
-+ memcpy(skb_put(skb, len), data, len);
-+
-+ scb->expect -= len;
-+ if (!scb->expect) {
-+ /* Complete frame */
-+ __reassembly(husb, type) = NULL;
-+ hci_recv_frame(skb);
- }
-- }
--
-- memcpy(skb_put(skb, count), data, count);
-- husb->intr_count -= count;
--
-- DMP(data, count);
--
-- if (!husb->intr_count) {
-- /* Got complete frame */
-
-- husb->hdev.stat.byte_rx += skb->len;
-- hci_recv_frame(skb);
--
-- husb->intr_skb = NULL;
-+ count -= len; data += len;
- }
-+ return 0;
- }
-
--static void hci_usb_bulk_read(struct urb *urb)
-+static void hci_usb_rx_complete(struct urb *urb)
- {
-- struct hci_usb *husb = (struct hci_usb *) urb->context;
-- unsigned char *data = urb->transfer_buffer;
-- int count = urb->actual_length, status;
-- struct sk_buff *skb;
-- hci_acl_hdr *ah;
-- register __u16 dlen;
--
-- if (!husb)
-- return;
-+ struct _urb *_urb = container_of(urb, struct _urb, urb);
-+ struct hci_usb *husb = (void *) urb->context;
-+ struct hci_dev *hdev = &husb->hdev;
-+ int err, count = urb->actual_length;
-
-- DBG("%s status %d, count %d, flags %x", husb->hdev.name, urb->status, count, urb->transfer_flags);
-+ BT_DBG("%s urb %p type %d status %d count %d flags %x", hdev->name, urb,
-+ _urb->type, urb->status, count, urb->transfer_flags);
-
-- if (urb->status) {
-- /* Do not re-submit URB on critical errors */
-- switch (urb->status) {
-- case -ENOENT:
-- return;
-- default:
-- goto resubmit;
-- };
-- }
-- if (!count)
-- goto resubmit;
--
-- DMP(data, count);
-+ read_lock(&husb->completion_lock);
-
-- ah = (hci_acl_hdr *) data;
-- dlen = le16_to_cpu(ah->dlen);
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ goto unlock;
-
-- /* Verify frame len and completeness */
-- if ((count - HCI_ACL_HDR_SIZE) != dlen) {
-- ERR("%s corrupted ACL packet: count %d, plen %d", husb->hdev.name, count, dlen);
-+ if (urb->status || !count)
- goto resubmit;
-- }
-
-- /* Allocate packet */
-- if (!(skb = bluez_skb_alloc(count, GFP_ATOMIC))) {
-- ERR("Can't allocate mem for new packet");
-- goto resubmit;
-+ if (_urb->type == HCI_SCODATA_PKT) {
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ int i;
-+ for (i=0; i < urb->number_of_packets; i++) {
-+ BT_DBG("desc %d status %d offset %d len %d", i,
-+ urb->iso_frame_desc[i].status,
-+ urb->iso_frame_desc[i].offset,
-+ urb->iso_frame_desc[i].actual_length);
-+
-+ if (!urb->iso_frame_desc[i].status)
-+ __recv_frame(husb, _urb->type,
-+ urb->transfer_buffer + urb->iso_frame_desc[i].offset,
-+ urb->iso_frame_desc[i].actual_length);
-+ }
-+#else
-+ ;
-+#endif
-+ } else {
-+ err = __recv_frame(husb, _urb->type, urb->transfer_buffer, count);
-+ if (err < 0) {
-+ BT_ERR("%s corrupted packet: type %d count %d",
-+ husb->hdev.name, _urb->type, count);
-+ hdev->stat.err_rx++;
-+ }
- }
-
-- memcpy(skb_put(skb, count), data, count);
-- skb->dev = (void *) &husb->hdev;
-- skb->pkt_type = HCI_ACLDATA_PKT;
--
-- husb->hdev.stat.byte_rx += skb->len;
--
-- hci_recv_frame(skb);
--
- resubmit:
-- husb->read_urb->dev = husb->udev;
-- if ((status = usb_submit_urb(husb->read_urb)))
-- DBG("%s read URB submit failed %d", husb->hdev.name, status);
-+ if (_urb->type != HCI_EVENT_PKT) {
-+ urb->dev = husb->udev;
-+ err = usb_submit_urb(urb);
-+ BT_DBG("%s urb %p type %d resubmit status %d", hdev->name, urb,
-+ _urb->type, err);
-+ }
-
-- DBG("%s read URB re-submited", husb->hdev.name);
-+unlock:
-+ read_unlock(&husb->completion_lock);
- }
-
--static int hci_usb_ctrl_msg(struct hci_usb *husb, struct sk_buff *skb)
-+static void hci_usb_tx_complete(struct urb *urb)
- {
-- struct urb *urb = husb->ctrl_urb;
-- devrequest *dr = &husb->dev_req;
-- int pipe, status;
-+ struct _urb *_urb = container_of(urb, struct _urb, urb);
-+ struct hci_usb *husb = (void *) urb->context;
-+ struct hci_dev *hdev = &husb->hdev;
-
-- DBG("%s len %d", husb->hdev.name, skb->len);
-+ BT_DBG("%s urb %p status %d flags %x", hdev->name, urb,
-+ urb->status, urb->transfer_flags);
-
-- pipe = usb_sndctrlpipe(husb->udev, 0);
-+ atomic_dec(__pending_tx(husb, _urb->type));
-
-- dr->requesttype = HCI_CTRL_REQ;
-- dr->request = 0;
-- dr->index = 0;
-- dr->value = 0;
-- dr->length = cpu_to_le16(skb->len);
--
-- FILL_CONTROL_URB(urb, husb->udev, pipe, (void*)dr, skb->data, skb->len,
-- hci_usb_ctrl, skb);
-+ urb->transfer_buffer = NULL;
-+ kfree_skb((struct sk_buff *) _urb->priv);
-
-- if ((status = usb_submit_urb(urb))) {
-- DBG("%s control URB submit failed %d", husb->hdev.name, status);
-- return status;
-- }
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return;
-
-- return 0;
--}
-+ if (!urb->status)
-+ hdev->stat.byte_tx += urb->transfer_buffer_length;
-+ else
-+ hdev->stat.err_tx++;
-
--static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb)
--{
-- struct urb *urb = husb->write_urb;
-- int pipe, status;
-+ read_lock(&husb->completion_lock);
-
-- DBG("%s len %d", husb->hdev.name, skb->len);
-+ _urb_unlink(_urb);
-+ _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
-
-- pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep_addr);
-+ hci_usb_tx_wakeup(husb);
-+
-+ read_unlock(&husb->completion_lock);
-+}
-
-- FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,
-- hci_usb_bulk_write, skb);
-- urb->transfer_flags |= USB_QUEUE_BULK;
-+static void hci_usb_destruct(struct hci_dev *hdev)
-+{
-+ struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-
-- if ((status = usb_submit_urb(urb))) {
-- DBG("%s write URB submit failed %d", husb->hdev.name, status);
-- return status;
-- }
-+ BT_DBG("%s", hdev->name);
-
-- return 0;
-+ kfree(husb);
- }
-
--static void * hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
-+static void *hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
- {
-- struct usb_endpoint_descriptor *bulk_out_ep, *intr_in_ep, *bulk_in_ep;
-+ struct usb_endpoint_descriptor *bulk_out_ep[HCI_MAX_IFACE_NUM];
-+ struct usb_endpoint_descriptor *isoc_out_ep[HCI_MAX_IFACE_NUM];
-+ struct usb_endpoint_descriptor *bulk_in_ep[HCI_MAX_IFACE_NUM];
-+ struct usb_endpoint_descriptor *isoc_in_ep[HCI_MAX_IFACE_NUM];
-+ struct usb_endpoint_descriptor *intr_in_ep[HCI_MAX_IFACE_NUM];
- struct usb_interface_descriptor *uif;
- struct usb_endpoint_descriptor *ep;
-+ struct usb_interface *iface, *isoc_iface;
- struct hci_usb *husb;
- struct hci_dev *hdev;
-- int i, size, pipe;
-- __u8 * buf;
-+ int i, a, e, size, ifn, isoc_ifnum, isoc_alts;
-
-- DBG("udev %p ifnum %d", udev, ifnum);
-+ BT_DBG("udev %p ifnum %d", udev, ifnum);
-
-- /* Check device signature */
-- if ((udev->descriptor.bDeviceClass != HCI_DEV_CLASS) ||
-- (udev->descriptor.bDeviceSubClass != HCI_DEV_SUBCLASS)||
-- (udev->descriptor.bDeviceProtocol != HCI_DEV_PROTOCOL) )
-- return NULL;
-+ iface = &udev->actconfig->interface[0];
-
-- MOD_INC_USE_COUNT;
--
-- uif = &udev->actconfig->interface[ifnum].altsetting[0];
-+ if (!id->driver_info) {
-+ const struct usb_device_id *match;
-+ match = usb_match_id(udev, iface, blacklist_ids);
-+ if (match)
-+ id = match;
-+ }
-
-- if (uif->bNumEndpoints != 3) {
-- DBG("Wrong number of endpoints %d", uif->bNumEndpoints);
-- MOD_DEC_USE_COUNT;
-+ if (id->driver_info & HCI_IGNORE)
- return NULL;
-- }
-
-- bulk_out_ep = intr_in_ep = bulk_in_ep = NULL;
-+ /* Check number of endpoints */
-+ if (udev->actconfig->interface[ifnum].altsetting[0].bNumEndpoints < 3)
-+ return NULL;
-
-+ memset(bulk_out_ep, 0, sizeof(bulk_out_ep));
-+ memset(isoc_out_ep, 0, sizeof(isoc_out_ep));
-+ memset(bulk_in_ep, 0, sizeof(bulk_in_ep));
-+ memset(isoc_in_ep, 0, sizeof(isoc_in_ep));
-+ memset(intr_in_ep, 0, sizeof(intr_in_ep));
-+
-+ size = 0;
-+ isoc_iface = NULL;
-+ isoc_alts = isoc_ifnum = 0;
-+
- /* Find endpoints that we need */
-- for ( i = 0; i < uif->bNumEndpoints; ++i) {
-- ep = &uif->endpoint[i];
-
-- switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
-- case USB_ENDPOINT_XFER_BULK:
-- if (ep->bEndpointAddress & USB_DIR_IN)
-- bulk_in_ep = ep;
-- else
-- bulk_out_ep = ep;
-- break;
-+ ifn = MIN(udev->actconfig->bNumInterfaces, HCI_MAX_IFACE_NUM);
-+ for (i = 0; i < ifn; i++) {
-+ iface = &udev->actconfig->interface[i];
-+ for (a = 0; a < iface->num_altsetting; a++) {
-+ uif = &iface->altsetting[a];
-+ for (e = 0; e < uif->bNumEndpoints; e++) {
-+ ep = &uif->endpoint[e];
-+
-+ switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
-+ case USB_ENDPOINT_XFER_INT:
-+ if (ep->bEndpointAddress & USB_DIR_IN)
-+ intr_in_ep[i] = ep;
-+ break;
-+
-+ case USB_ENDPOINT_XFER_BULK:
-+ if (ep->bEndpointAddress & USB_DIR_IN)
-+ bulk_in_ep[i] = ep;
-+ else
-+ bulk_out_ep[i] = ep;
-+ break;
-+
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ case USB_ENDPOINT_XFER_ISOC:
-+ if (ep->wMaxPacketSize < size || a > 2)
-+ break;
-+ size = ep->wMaxPacketSize;
-+
-+ isoc_iface = iface;
-+ isoc_alts = a;
-+ isoc_ifnum = i;
-+
-+ if (ep->bEndpointAddress & USB_DIR_IN)
-+ isoc_in_ep[i] = ep;
-+ else
-+ isoc_out_ep[i] = ep;
-+ break;
-+#endif
-+ }
-+ }
-+ }
-+ }
-
-- case USB_ENDPOINT_XFER_INT:
-- intr_in_ep = ep;
-- break;
-- };
-+ if (!bulk_in_ep[0] || !bulk_out_ep[0] || !intr_in_ep[0]) {
-+ BT_DBG("Bulk endpoints not found");
-+ goto done;
- }
-
-- if (!bulk_in_ep || !bulk_out_ep || !intr_in_ep) {
-- DBG("Endpoints not found: %p %p %p", bulk_in_ep, bulk_out_ep, intr_in_ep);
-- MOD_DEC_USE_COUNT;
-- return NULL;
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ if (id->driver_info & HCI_BROKEN_ISOC || !isoc_in_ep[1] || !isoc_out_ep[1]) {
-+ BT_DBG("Isoc endpoints not found");
-+ isoc_iface = NULL;
- }
-+#endif
-
- if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
-- ERR("Can't allocate: control structure");
-- MOD_DEC_USE_COUNT;
-- return NULL;
-+ BT_ERR("Can't allocate: control structure");
-+ goto done;
- }
-
- memset(husb, 0, sizeof(struct hci_usb));
-
- husb->udev = udev;
-- husb->bulk_out_ep_addr = bulk_out_ep->bEndpointAddress;
--
-- if (!(husb->ctrl_urb = usb_alloc_urb(0))) {
-- ERR("Can't allocate: control URB");
-- goto probe_error;
-- }
--
-- if (!(husb->write_urb = usb_alloc_urb(0))) {
-- ERR("Can't allocate: write URB");
-- goto probe_error;
-- }
--
-- if (!(husb->read_urb = usb_alloc_urb(0))) {
-- ERR("Can't allocate: read URB");
-- goto probe_error;
-- }
--
-- ep = bulk_in_ep;
-- pipe = usb_rcvbulkpipe(udev, ep->bEndpointAddress);
-- size = HCI_MAX_FRAME_SIZE;
--
-- if (!(buf = kmalloc(size, GFP_KERNEL))) {
-- ERR("Can't allocate: read buffer");
-- goto probe_error;
-- }
--
-- FILL_BULK_URB(husb->read_urb, udev, pipe, buf, size, hci_usb_bulk_read, husb);
-- husb->read_urb->transfer_flags |= USB_QUEUE_BULK;
--
-- ep = intr_in_ep;
-- pipe = usb_rcvintpipe(udev, ep->bEndpointAddress);
-- size = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
--
-- if (!(husb->intr_urb = usb_alloc_urb(0))) {
-- ERR("Can't allocate: interrupt URB");
-- goto probe_error;
-+ husb->bulk_out_ep = bulk_out_ep[0];
-+ husb->bulk_in_ep = bulk_in_ep[0];
-+ husb->intr_in_ep = intr_in_ep[0];
-+
-+ if (id->driver_info & HCI_DIGIANSWER)
-+ husb->ctrl_req = HCI_DIGI_REQ;
-+ else
-+ husb->ctrl_req = HCI_CTRL_REQ;
-+
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ if (isoc_iface) {
-+ BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, isoc_alts);
-+ if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) {
-+ BT_ERR("Can't set isoc interface settings");
-+ isoc_iface = NULL;
-+ }
-+ usb_driver_claim_interface(&hci_usb_driver, isoc_iface, husb);
-+ husb->isoc_iface = isoc_iface;
-+ husb->isoc_in_ep = isoc_in_ep[isoc_ifnum];
-+ husb->isoc_out_ep = isoc_out_ep[isoc_ifnum];
- }
-+#endif
-+
-+ husb->completion_lock = RW_LOCK_UNLOCKED;
-
-- if (!(buf = kmalloc(size, GFP_KERNEL))) {
-- ERR("Can't allocate: interrupt buffer");
-- goto probe_error;
-+ for (i = 0; i < 4; i++) {
-+ skb_queue_head_init(&husb->transmit_q[i]);
-+ _urb_queue_init(&husb->pending_q[i]);
-+ _urb_queue_init(&husb->completed_q[i]);
- }
-
-- FILL_INT_URB(husb->intr_urb, udev, pipe, buf, size, hci_usb_intr, husb, ep->bInterval);
--
-- skb_queue_head_init(&husb->tx_ctrl_q);
-- skb_queue_head_init(&husb->tx_write_q);
--
- /* Initialize and register HCI device */
- hdev = &husb->hdev;
-
-- hdev->type = HCI_USB;
-+ hdev->type = HCI_USB;
- hdev->driver_data = husb;
-
- hdev->open = hci_usb_open;
- hdev->close = hci_usb_close;
- hdev->flush = hci_usb_flush;
-- hdev->send = hci_usb_send_frame;
-+ hdev->send = hci_usb_send_frame;
-+ hdev->destruct = hci_usb_destruct;
-+
-+ if (id->driver_info & HCI_RESET)
-+ set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
-
- if (hci_register_dev(hdev) < 0) {
-- ERR("Can't register HCI device %s", hdev->name);
-+ BT_ERR("Can't register HCI device");
- goto probe_error;
- }
-
- return husb;
-
- probe_error:
-- hci_usb_free_bufs(husb);
- kfree(husb);
-- MOD_DEC_USE_COUNT;
-+
-+done:
- return NULL;
- }
-
-@@ -626,38 +967,34 @@
- if (!husb)
- return;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s", hdev->name);
-
- hci_usb_close(hdev);
-
-- if (hci_unregister_dev(hdev) < 0) {
-- ERR("Can't unregister HCI device %s", hdev->name);
-- }
-+ if (husb->isoc_iface)
-+ usb_driver_release_interface(&hci_usb_driver, husb->isoc_iface);
-
-- hci_usb_free_bufs(husb);
-- kfree(husb);
--
-- MOD_DEC_USE_COUNT;
-+ if (hci_unregister_dev(hdev) < 0)
-+ BT_ERR("Can't unregister HCI device %s", hdev->name);
- }
-
--static struct usb_driver hci_usb_driver =
--{
-+static struct usb_driver hci_usb_driver = {
- name: "hci_usb",
- probe: hci_usb_probe,
- disconnect: hci_usb_disconnect,
-- id_table: usb_bluetooth_ids,
-+ id_table: bluetooth_ids,
- };
-
- int hci_usb_init(void)
- {
- int err;
-
-- INF("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-+ BT_INFO("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-
- if ((err = usb_register(&hci_usb_driver)) < 0)
-- ERR("Failed to register HCI USB driver");
-+ BT_ERR("Failed to register HCI USB driver");
-
- return err;
- }
-@@ -670,6 +1007,6 @@
- module_init(hci_usb_init);
- module_exit(hci_usb_cleanup);
-
--MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
- MODULE_DESCRIPTION("BlueZ HCI USB driver ver " VERSION);
- MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/drivers/bluetooth/hci_usb.h linux-2.4.18-mh15/drivers/bluetooth/hci_usb.h
---- linux-2.4.18/drivers/bluetooth/hci_usb.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_usb.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,147 @@
-+/*
-+ HCI USB driver for Linux Bluetooth protocol stack (BlueZ)
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ Copyright (C) 2003 Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifdef __KERNEL__
-+
-+/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
-+#define HCI_DEV_CLASS 0xe0 /* Wireless class */
-+#define HCI_DEV_SUBCLASS 0x01 /* RF subclass */
-+#define HCI_DEV_PROTOCOL 0x01 /* Bluetooth programming protocol */
-+
-+#define HCI_CTRL_REQ 0x20
-+#define HCI_DIGI_REQ 0x40
-+
-+#define HCI_IGNORE 0x01
-+#define HCI_RESET 0x02
-+#define HCI_DIGIANSWER 0x04
-+#define HCI_BROKEN_ISOC 0x08
-+
-+#define HCI_MAX_IFACE_NUM 3
-+
-+#define HCI_MAX_BULK_TX 4
-+#define HCI_MAX_BULK_RX 1
-+
-+#define HCI_MAX_ISOC_RX 2
-+#define HCI_MAX_ISOC_TX 2
-+
-+#define HCI_MAX_ISOC_FRAMES 10
-+
-+struct _urb_queue {
-+ struct list_head head;
-+ spinlock_t lock;
-+};
-+
-+struct _urb {
-+ struct list_head list;
-+ struct _urb_queue *queue;
-+ int type;
-+ void *priv;
-+ struct urb urb;
-+};
-+
-+struct _urb *_urb_alloc(int isoc, int gfp);
-+
-+static inline void _urb_free(struct _urb *_urb)
-+{
-+ kfree(_urb);
-+}
-+
-+static inline void _urb_queue_init(struct _urb_queue *q)
-+{
-+ INIT_LIST_HEAD(&q->head);
-+ spin_lock_init(&q->lock);
-+}
-+
-+static inline void _urb_queue_head(struct _urb_queue *q, struct _urb *_urb)
-+{
-+ unsigned long flags;
-+ spin_lock_irqsave(&q->lock, flags);
-+ list_add(&_urb->list, &q->head); _urb->queue = q;
-+ spin_unlock_irqrestore(&q->lock, flags);
-+}
-+
-+static inline void _urb_queue_tail(struct _urb_queue *q, struct _urb *_urb)
-+{
-+ unsigned long flags;
-+ spin_lock_irqsave(&q->lock, flags);
-+ list_add_tail(&_urb->list, &q->head); _urb->queue = q;
-+ spin_unlock_irqrestore(&q->lock, flags);
-+}
-+
-+static inline void _urb_unlink(struct _urb *_urb)
-+{
-+ struct _urb_queue *q = _urb->queue;
-+ unsigned long flags;
-+ if (q) {
-+ spin_lock_irqsave(&q->lock, flags);
-+ list_del(&_urb->list); _urb->queue = NULL;
-+ spin_unlock_irqrestore(&q->lock, flags);
-+ }
-+}
-+
-+struct _urb *_urb_dequeue(struct _urb_queue *q);
-+
-+#ifndef container_of
-+#define container_of(ptr, type, member) ({ \
-+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
-+ (type *)( (char *)__mptr - offsetof(type,member) );})
-+#endif
-+
-+struct hci_usb {
-+ struct hci_dev hdev;
-+
-+ unsigned long state;
-+
-+ struct usb_device *udev;
-+
-+ struct usb_endpoint_descriptor *bulk_in_ep;
-+ struct usb_endpoint_descriptor *bulk_out_ep;
-+ struct usb_endpoint_descriptor *intr_in_ep;
-+
-+ struct usb_interface *isoc_iface;
-+ struct usb_endpoint_descriptor *isoc_out_ep;
-+ struct usb_endpoint_descriptor *isoc_in_ep;
-+
-+ __u8 ctrl_req;
-+
-+ struct sk_buff_head transmit_q[4];
-+ struct sk_buff *reassembly[4]; // Reassembly buffers
-+
-+ rwlock_t completion_lock;
-+
-+ atomic_t pending_tx[4]; // Number of pending requests
-+ struct _urb_queue pending_q[4]; // Pending requests
-+ struct _urb_queue completed_q[4]; // Completed requests
-+};
-+
-+/* States */
-+#define HCI_USB_TX_PROCESS 1
-+#define HCI_USB_TX_WAKEUP 2
-+
-+#endif /* __KERNEL__ */
-diff -urN linux-2.4.18/drivers/bluetooth/hci_vhci.c linux-2.4.18-mh15/drivers/bluetooth/hci_vhci.c
---- linux-2.4.18/drivers/bluetooth/hci_vhci.c 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_vhci.c 2004-08-01 16:26:23.000000000 +0200
-@@ -25,9 +25,9 @@
- /*
- * BlueZ HCI virtual device driver.
- *
-- * $Id$
-+ * $Id$
- */
--#define VERSION "1.0"
-+#define VERSION "1.1"
-
- #include <linux/config.h>
- #include <linux/module.h>
-@@ -49,43 +49,56 @@
- #include <asm/uaccess.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/hci_vhci.h>
-+#include "hci_vhci.h"
-
- /* HCI device part */
-
--int hci_vhci_open(struct hci_dev *hdev)
-+static int hci_vhci_open(struct hci_dev *hdev)
- {
-- hdev->flags |= HCI_RUNNING;
-+ set_bit(HCI_RUNNING, &hdev->flags);
- return 0;
- }
-
--int hci_vhci_flush(struct hci_dev *hdev)
-+static int hci_vhci_flush(struct hci_dev *hdev)
- {
- struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
- skb_queue_purge(&hci_vhci->readq);
- return 0;
- }
-
--int hci_vhci_close(struct hci_dev *hdev)
-+static int hci_vhci_close(struct hci_dev *hdev)
- {
-- hdev->flags &= ~HCI_RUNNING;
-+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-+
- hci_vhci_flush(hdev);
- return 0;
- }
-
--int hci_vhci_send_frame(struct sk_buff *skb)
-+static void hci_vhci_destruct(struct hci_dev *hdev)
-+{
-+ struct hci_vhci_struct *vhci;
-+
-+ if (!hdev) return;
-+
-+ vhci = (struct hci_vhci_struct *) hdev->driver_data;
-+ kfree(vhci);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static int hci_vhci_send_frame(struct sk_buff *skb)
- {
- struct hci_dev* hdev = (struct hci_dev *) skb->dev;
- struct hci_vhci_struct *hci_vhci;
-
- if (!hdev) {
-- ERR("Frame for uknown device (hdev=NULL)");
-+ BT_ERR("Frame for uknown device (hdev=NULL)");
- return -ENODEV;
- }
-
-- if (!(hdev->flags & HCI_RUNNING))
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
- return -EBUSY;
-
- hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
-@@ -188,7 +201,7 @@
-
- add_wait_queue(&hci_vhci->read_wait, &wait);
- while (count) {
-- current->state = TASK_INTERRUPTIBLE;
-+ set_current_state(TASK_INTERRUPTIBLE);
-
- /* Read frames from device queue */
- if (!(skb = skb_dequeue(&hci_vhci->readq))) {
-@@ -214,8 +227,7 @@
- kfree_skb(skb);
- break;
- }
--
-- current->state = TASK_RUNNING;
-+ set_current_state(TASK_RUNNING);
- remove_wait_queue(&hci_vhci->read_wait, &wait);
-
- return ret;
-@@ -270,11 +282,13 @@
- hdev->close = hci_vhci_close;
- hdev->flush = hci_vhci_flush;
- hdev->send = hci_vhci_send_frame;
-+ hdev->destruct = hci_vhci_destruct;
-
- if (hci_register_dev(hdev) < 0) {
- kfree(hci_vhci);
- return -EBUSY;
- }
-+ MOD_INC_USE_COUNT;
-
- file->private_data = hci_vhci;
- return 0;
-@@ -285,12 +299,10 @@
- struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
-
- if (hci_unregister_dev(&hci_vhci->hdev) < 0) {
-- ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
-+ BT_ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
- }
-
-- kfree(hci_vhci);
- file->private_data = NULL;
--
- return 0;
- }
-
-@@ -315,12 +327,12 @@
-
- int __init hci_vhci_init(void)
- {
-- INF("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-+ BT_INFO("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-
- if (misc_register(&hci_vhci_miscdev)) {
-- ERR("Can't register misc device %d\n", VHCI_MINOR);
-+ BT_ERR("Can't register misc device %d\n", VHCI_MINOR);
- return -EIO;
- }
-
-@@ -337,4 +349,4 @@
-
- MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
- MODULE_DESCRIPTION("BlueZ VHCI driver ver " VERSION);
--MODULE_LICENSE("GPL");
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/drivers/bluetooth/hci_vhci.h linux-2.4.18-mh15/drivers/bluetooth/hci_vhci.h
---- linux-2.4.18/drivers/bluetooth/hci_vhci.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_vhci.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,50 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef __HCI_VHCI_H
-+#define __HCI_VHCI_H
-+
-+#ifdef __KERNEL__
-+
-+struct hci_vhci_struct {
-+ struct hci_dev hdev;
-+ __u32 flags;
-+ wait_queue_head_t read_wait;
-+ struct sk_buff_head readq;
-+ struct fasync_struct *fasync;
-+};
-+
-+/* VHCI device flags */
-+#define VHCI_FASYNC 0x0010
-+
-+#endif /* __KERNEL__ */
-+
-+#define VHCI_DEV "/dev/vhci"
-+#define VHCI_MINOR 250
-+
-+#endif /* __HCI_VHCI_H */
-diff -urN linux-2.4.18/drivers/bluetooth/Makefile linux-2.4.18-mh15/drivers/bluetooth/Makefile
---- linux-2.4.18/drivers/bluetooth/Makefile 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/drivers/bluetooth/Makefile 2004-08-01 16:26:23.000000000 +0200
-@@ -1,11 +1,27 @@
- #
--# Makefile for Bluetooth HCI device drivers.
-+# Makefile for the Linux Bluetooth HCI device drivers
- #
-
- O_TARGET := bluetooth.o
-
-+list-multi := hci_uart.o
-+
- obj-$(CONFIG_BLUEZ_HCIUSB) += hci_usb.o
--obj-$(CONFIG_BLUEZ_HCIUART) += hci_uart.o
- obj-$(CONFIG_BLUEZ_HCIVHCI) += hci_vhci.o
-
-+obj-$(CONFIG_BLUEZ_HCIUART) += hci_uart.o
-+uart-y := hci_ldisc.o
-+uart-$(CONFIG_BLUEZ_HCIUART_H4) += hci_h4.o
-+uart-$(CONFIG_BLUEZ_HCIUART_BCSP) += hci_bcsp.o
-+
-+obj-$(CONFIG_BLUEZ_HCIBFUSB) += bfusb.o
-+
-+obj-$(CONFIG_BLUEZ_HCIDTL1) += dtl1_cs.o
-+obj-$(CONFIG_BLUEZ_HCIBT3C) += bt3c_cs.o
-+obj-$(CONFIG_BLUEZ_HCIBLUECARD) += bluecard_cs.o
-+obj-$(CONFIG_BLUEZ_HCIBTUART) += btuart_cs.o
-+
- include $(TOPDIR)/Rules.make
-+
-+hci_uart.o: $(uart-y)
-+ $(LD) -r -o $@ $(uart-y)
-diff -urN linux-2.4.18/drivers/bluetooth/Makefile.lib linux-2.4.18-mh15/drivers/bluetooth/Makefile.lib
---- linux-2.4.18/drivers/bluetooth/Makefile.lib 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/Makefile.lib 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,2 @@
-+obj-$(CONFIG_BLUEZ_HCIBFUSB) += firmware_class.o
-+obj-$(CONFIG_BLUEZ_HCIBT3C) += firmware_class.o
-diff -urN linux-2.4.18/drivers/char/pcmcia/serial_cs.c linux-2.4.18-mh15/drivers/char/pcmcia/serial_cs.c
---- linux-2.4.18/drivers/char/pcmcia/serial_cs.c 2001-12-21 18:41:54.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/char/pcmcia/serial_cs.c 2004-08-01 16:26:23.000000000 +0200
-@@ -2,7 +2,7 @@
-
- A driver for PCMCIA serial devices
-
-- serial_cs.c 1.128 2001/10/18 12:18:35
-+ serial_cs.c 1.138 2002/10/25 06:24:52
-
- The contents of this file are subject to the Mozilla Public
- License Version 1.1 (the "License"); you may not use this file
-@@ -69,14 +69,14 @@
- static int irq_list[4] = { -1 };
- MODULE_PARM(irq_list, "1-4i");
-
--/* Enable the speaker? */
--INT_MODULE_PARM(do_sound, 1);
-+INT_MODULE_PARM(do_sound, 1); /* Enable the speaker? */
-+INT_MODULE_PARM(buggy_uart, 0); /* Skip strict UART tests? */
-
- #ifdef PCMCIA_DEBUG
- INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
- #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
- static char *version =
--"serial_cs.c 1.128 2001/10/18 12:18:35 (David Hinds)";
-+"serial_cs.c 1.138 2002/10/25 06:24:52 (David Hinds)";
- #else
- #define DEBUG(n, args...)
- #endif
-@@ -95,6 +95,7 @@
- { MANFID_OMEGA, PRODID_OMEGA_QSP_100, 4 },
- { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232, 2 },
- { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 },
-+ { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D2, 2 },
- { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS232, 4 },
- { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS422, 2 },
- { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS422, 4 },
-@@ -148,7 +149,7 @@
- client_reg_t client_reg;
- dev_link_t *link;
- int i, ret;
--
-+
- DEBUG(0, "serial_attach()\n");
-
- /* Create new serial device */
-@@ -160,7 +161,7 @@
- link->release.function = &serial_release;
- link->release.data = (u_long)link;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-- link->io.NumPorts1 = 8;
-+ link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
- link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
- if (irq_list[0] == -1)
-@@ -169,13 +170,12 @@
- for (i = 0; i < 4; i++)
- link->irq.IRQInfo2 |= 1 << irq_list[i];
- link->conf.Attributes = CONF_ENABLE_IRQ;
-- link->conf.Vcc = 50;
- if (do_sound) {
- link->conf.Attributes |= CONF_ENABLE_SPKR;
- link->conf.Status = CCSR_AUDIO_ENA;
- }
- link->conf.IntType = INT_MEMORY_AND_IO;
--
-+
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
-@@ -194,7 +194,7 @@
- serial_detach(link);
- return NULL;
- }
--
-+
- return link;
- } /* serial_attach */
-
-@@ -214,7 +214,7 @@
- int ret;
-
- DEBUG(0, "serial_detach(0x%p)\n", link);
--
-+
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
-@@ -224,17 +224,17 @@
- del_timer(&link->release);
- if (link->state & DEV_CONFIG)
- serial_release((u_long)link);
--
-+
- if (link->handle) {
- ret = CardServices(DeregisterClient, link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
- }
--
-+
- /* Unlink device structure, free bits */
- *linkp = link->next;
- kfree(info);
--
-+
- } /* serial_detach */
-
- /*====================================================================*/
-@@ -243,18 +243,20 @@
- {
- struct serial_struct serial;
- int line;
--
-+
- memset(&serial, 0, sizeof(serial));
- serial.port = port;
- serial.irq = irq;
- serial.flags = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ;
-+ if (buggy_uart)
-+ serial.flags |= ASYNC_BUGGY_UART;
- line = register_serial(&serial);
- if (line < 0) {
- printk(KERN_NOTICE "serial_cs: register_serial() at 0x%04lx,"
- " irq %d failed\n", (u_long)serial.port, serial.irq);
- return -1;
- }
--
-+
- info->line[info->ndev] = line;
- sprintf(info->node[info->ndev].dev_name, "ttyS%d", line);
- info->node[info->ndev].major = TTY_MAJOR;
-@@ -262,7 +264,7 @@
- if (info->ndev > 0)
- info->node[info->ndev-1].next = &info->node[info->ndev];
- info->ndev++;
--
-+
- return 0;
- }
-
-@@ -313,7 +315,10 @@
- return setup_serial(info, port, config.AssignedIRQ);
- }
- link->conf.Vcc = config.Vcc;
--
-+
-+ link->io.NumPorts1 = 8;
-+ link->io.NumPorts2 = 0;
-+
- /* First pass: look for a config entry that looks normal. */
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
-@@ -340,7 +345,7 @@
- i = next_tuple(handle, &tuple, &parse);
- }
- }
--
-+
- /* Second pass: try to find an entry that isn't picky about
- its base address, then try to grab any standard serial port
- address, and finally try to get any free port. */
-@@ -352,8 +357,7 @@
- for (j = 0; j < 5; j++) {
- link->io.BasePort1 = base[j];
- link->io.IOAddrLines = base[j] ? 16 : 3;
-- i = CardServices(RequestIO, link->handle,
-- &link->io);
-+ i = CardServices(RequestIO, link->handle, &link->io);
- if (i == CS_SUCCESS) goto found_port;
- }
- }
-@@ -365,7 +369,7 @@
- cs_error(link->handle, RequestIO, i);
- return -1;
- }
--
-+
- i = CardServices(RequestIRQ, link->handle, &link->irq);
- if (i != CS_SUCCESS) {
- cs_error(link->handle, RequestIRQ, i);
-@@ -390,8 +394,12 @@
- u_char buf[256];
- cisparse_t parse;
- cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
- int i, base2 = 0;
-
-+ CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
-@@ -433,12 +441,12 @@
- i = next_tuple(handle, &tuple, &parse);
- }
- }
--
-+
- if (i != CS_SUCCESS) {
-- cs_error(link->handle, RequestIO, i);
-- return -1;
-+ /* At worst, try to configure as a single port */
-+ return simple_config(link);
- }
--
-+
- i = CardServices(RequestIRQ, link->handle, &link->irq);
- if (i != CS_SUCCESS) {
- cs_error(link->handle, RequestIRQ, i);
-@@ -454,14 +462,27 @@
- cs_error(link->handle, RequestConfiguration, i);
- return -1;
- }
--
-+
-+ /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
-+ 8 registers are for the UART, the others are extra registers */
-+ if (info->manfid == MANFID_OXSEMI) {
-+ if (cf->index == 1 || cf->index == 3) {
-+ setup_serial(info, base2, link->irq.AssignedIRQ);
-+ outb(12,link->io.BasePort1+1);
-+ } else {
-+ setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
-+ outb(12,base2+1);
-+ }
-+ return 0;
-+ }
-+
- setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
- /* The Nokia cards are not really multiport cards */
- if (info->manfid == MANFID_NOKIA)
- return 0;
- for (i = 0; i < info->multi-1; i++)
- setup_serial(info, base2+(8*i), link->irq.AssignedIRQ);
--
-+
- return 0;
- }
-
-@@ -500,7 +521,7 @@
- }
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
--
-+
- /* Configure card */
- link->state |= DEV_CONFIG;
-
-@@ -508,8 +529,8 @@
- tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
- tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
- info->multi = (first_tuple(handle, &tuple, &parse) == CS_SUCCESS);
--
-- /* Is this a multiport card? */
-+
-+ /* Scan list of known multiport card ID's */
- tuple.DesiredTuple = CISTPL_MANFID;
- if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
- info->manfid = le16_to_cpu(buf[0]);
-@@ -537,15 +558,15 @@
- info->multi = 2;
- }
- }
--
-+
- if (info->multi > 1)
- multi_config(link);
- else
- simple_config(link);
--
-+
- if (info->ndev == 0)
- goto failed;
--
-+
- if (info->manfid == MANFID_IBM) {
- conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
- CS_CHECK(AccessConfigurationRegister, link->handle, &reg);
-@@ -562,6 +583,7 @@
- cs_error(link->handle, last_fn, last_ret);
- failed:
- serial_release((u_long)link);
-+ link->state &= ~DEV_CONFIG_PENDING;
-
- } /* serial_config */
-
-@@ -569,7 +591,7 @@
-
- After a card is removed, serial_release() will unregister the net
- device, and release the PCMCIA configuration.
--
-+
- ======================================================================*/
-
- void serial_release(u_long arg)
-@@ -577,7 +599,7 @@
- dev_link_t *link = (dev_link_t *)arg;
- serial_info_t *info = link->priv;
- int i;
--
-+
- DEBUG(0, "serial_release(0x%p)\n", link);
-
- for (i = 0; i < info->ndev; i++) {
-@@ -590,7 +612,7 @@
- CardServices(ReleaseIO, link->handle, &link->io);
- CardServices(ReleaseIRQ, link->handle, &link->irq);
- }
--
-+
- link->state &= ~DEV_CONFIG;
-
- } /* serial_release */
-@@ -601,7 +623,7 @@
- stuff to run after an event is received. A CARD_REMOVAL event
- also sets some flags to discourage the serial drivers from
- talking to the ports.
--
-+
- ======================================================================*/
-
- static int serial_event(event_t event, int priority,
-@@ -609,9 +631,9 @@
- {
- dev_link_t *link = args->client_data;
- serial_info_t *info = link->priv;
--
-+
- DEBUG(1, "serial_event(0x%06x)\n", event);
--
-+
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
-@@ -650,7 +672,7 @@
- if (serv.Revision != CS_RELEASE_CODE) {
- printk(KERN_NOTICE "serial_cs: Card Services release "
- "does not match!\n");
-- return -1;
-+ return -EINVAL;
- }
- register_pccard_driver(&dev_info, &serial_attach, &serial_detach);
- return 0;
-diff -urN linux-2.4.18/drivers/input/Config.in linux-2.4.18-mh15/drivers/input/Config.in
---- linux-2.4.18/drivers/input/Config.in 2001-09-13 00:34:06.000000000 +0200
-+++ linux-2.4.18-mh15/drivers/input/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -14,5 +14,6 @@
- fi
- dep_tristate ' Joystick support' CONFIG_INPUT_JOYDEV $CONFIG_INPUT
- dep_tristate ' Event interface support' CONFIG_INPUT_EVDEV $CONFIG_INPUT
-+dep_tristate ' User level driver support' CONFIG_INPUT_UINPUT $CONFIG_INPUT
-
- endmenu
-diff -urN linux-2.4.18/drivers/input/keybdev.c linux-2.4.18-mh15/drivers/input/keybdev.c
---- linux-2.4.18/drivers/input/keybdev.c 2001-10-11 18:14:32.000000000 +0200
-+++ linux-2.4.18-mh15/drivers/input/keybdev.c 2004-08-01 16:26:23.000000000 +0200
-@@ -154,16 +154,18 @@
-
- static struct input_handler keybdev_handler;
-
-+static unsigned int ledstate = 0xff;
-+
- void keybdev_ledfunc(unsigned int led)
- {
- struct input_handle *handle;
-
-- for (handle = keybdev_handler.handle; handle; handle = handle->hnext) {
-+ ledstate = led;
-
-+ for (handle = keybdev_handler.handle; handle; handle = handle->hnext) {
- input_event(handle->dev, EV_LED, LED_SCROLLL, !!(led & 0x01));
- input_event(handle->dev, EV_LED, LED_NUML, !!(led & 0x02));
- input_event(handle->dev, EV_LED, LED_CAPSL, !!(led & 0x04));
--
- }
- }
-
-@@ -202,6 +204,12 @@
-
- // printk(KERN_INFO "keybdev.c: Adding keyboard: input%d\n", dev->number);
-
-+ if (ledstate != 0xff) {
-+ input_event(dev, EV_LED, LED_SCROLLL, !!(ledstate & 0x01));
-+ input_event(dev, EV_LED, LED_NUML, !!(ledstate & 0x02));
-+ input_event(dev, EV_LED, LED_CAPSL, !!(ledstate & 0x04));
-+ }
-+
- return handle;
- }
-
-diff -urN linux-2.4.18/drivers/input/Makefile linux-2.4.18-mh15/drivers/input/Makefile
---- linux-2.4.18/drivers/input/Makefile 2000-12-29 23:07:22.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/input/Makefile 2004-08-01 16:26:23.000000000 +0200
-@@ -24,6 +24,7 @@
- obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
- obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
- obj-$(CONFIG_INPUT_EVDEV) += evdev.o
-+obj-$(CONFIG_INPUT_UINPUT) += uinput.o
-
- # The global Rules.make.
-
-diff -urN linux-2.4.18/drivers/input/uinput.c linux-2.4.18-mh15/drivers/input/uinput.c
---- linux-2.4.18/drivers/input/uinput.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/input/uinput.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,428 @@
-+/*
-+ * User level driver support for input subsystem
-+ *
-+ * Heavily based on evdev.c by Vojtech Pavlik
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
-+ *
-+ * Changes/Revisions:
-+ * 0.1 20/06/2002
-+ * - first public version
-+ */
-+
-+#include <linux/poll.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/input.h>
-+#include <linux/smp_lock.h>
-+#include <linux/fs.h>
-+#include <linux/miscdevice.h>
-+#include <linux/uinput.h>
-+
-+static int uinput_dev_open(struct input_dev *dev)
-+{
-+ return 0;
-+}
-+
-+static void uinput_dev_close(struct input_dev *dev)
-+{
-+}
-+
-+static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
-+{
-+ struct uinput_device *udev;
-+
-+ udev = (struct uinput_device *)dev->private;
-+
-+ udev->buff[udev->head].type = type;
-+ udev->buff[udev->head].code = code;
-+ udev->buff[udev->head].value = value;
-+ do_gettimeofday(&udev->buff[udev->head].time);
-+ udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE;
-+
-+ wake_up_interruptible(&udev->waitq);
-+
-+ return 0;
-+}
-+
-+static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect)
-+{
-+ return 0;
-+}
-+
-+static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
-+{
-+ return 0;
-+}
-+
-+static int uinput_create_device(struct uinput_device *udev)
-+{
-+ if (!udev->dev->name) {
-+ printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME);
-+ return -EINVAL;
-+ }
-+
-+ udev->dev->open = uinput_dev_open;
-+ udev->dev->close = uinput_dev_close;
-+ udev->dev->event = uinput_dev_event;
-+ udev->dev->upload_effect = uinput_dev_upload_effect;
-+ udev->dev->erase_effect = uinput_dev_erase_effect;
-+ udev->dev->private = udev;
-+
-+ init_waitqueue_head(&(udev->waitq));
-+
-+ input_register_device(udev->dev);
-+
-+ set_bit(UIST_CREATED, &(udev->state));
-+
-+ return 0;
-+}
-+
-+static int uinput_destroy_device(struct uinput_device *udev)
-+{
-+ if (!test_bit(UIST_CREATED, &(udev->state))) {
-+ printk(KERN_WARNING "%s: create the device first\n", UINPUT_NAME);
-+ return -EINVAL;
-+ }
-+
-+ input_unregister_device(udev->dev);
-+
-+ clear_bit(UIST_CREATED, &(udev->state));
-+
-+ return 0;
-+}
-+
-+static int uinput_open(struct inode *inode, struct file *file)
-+{
-+ struct uinput_device *newdev;
-+ struct input_dev *newinput;
-+
-+ newdev = kmalloc(sizeof(struct uinput_device), GFP_KERNEL);
-+ if (!newdev)
-+ goto error;
-+ memset(newdev, 0, sizeof(struct uinput_device));
-+
-+ newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
-+ if (!newinput)
-+ goto cleanup;
-+ memset(newinput, 0, sizeof(struct input_dev));
-+
-+ newdev->dev = newinput;
-+
-+ file->private_data = newdev;
-+
-+ return 0;
-+cleanup:
-+ kfree(newdev);
-+error:
-+ return -ENOMEM;
-+}
-+
-+static int uinput_validate_absbits(struct input_dev *dev)
-+{
-+ unsigned int cnt;
-+ int retval = 0;
-+
-+ for (cnt = 0; cnt < ABS_MAX; cnt++) {
-+ if (!test_bit(cnt, dev->absbit))
-+ continue;
-+
-+ if (/*!dev->absmin[cnt] || !dev->absmax[cnt] || */
-+ (dev->absmax[cnt] <= dev->absmin[cnt])) {
-+ printk(KERN_DEBUG
-+ "%s: invalid abs[%02x] min:%d max:%d\n",
-+ UINPUT_NAME, cnt,
-+ dev->absmin[cnt], dev->absmax[cnt]);
-+ retval = -EINVAL;
-+ break;
-+ }
-+
-+ if ((dev->absflat[cnt] < dev->absmin[cnt]) ||
-+ (dev->absflat[cnt] > dev->absmax[cnt])) {
-+ printk(KERN_DEBUG
-+ "%s: absflat[%02x] out of range: %d "
-+ "(min:%d/max:%d)\n",
-+ UINPUT_NAME, cnt, dev->absflat[cnt],
-+ dev->absmin[cnt], dev->absmax[cnt]);
-+ retval = -EINVAL;
-+ break;
-+ }
-+ }
-+ return retval;
-+}
-+
-+static int uinput_alloc_device(struct file *file, const char *buffer, size_t count)
-+{
-+ struct uinput_user_dev *user_dev;
-+ struct input_dev *dev;
-+ struct uinput_device *udev;
-+ int size,
-+ retval;
-+
-+ retval = count;
-+
-+ udev = (struct uinput_device *)file->private_data;
-+ dev = udev->dev;
-+
-+ user_dev = kmalloc(sizeof(*user_dev), GFP_KERNEL);
-+ if (!user_dev) {
-+ retval = -ENOMEM;
-+ goto exit;
-+ }
-+
-+ if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) {
-+ retval = -EFAULT;
-+ goto exit;
-+ }
-+
-+ if (NULL != dev->name)
-+ kfree(dev->name);
-+
-+ size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
-+ dev->name = kmalloc(size, GFP_KERNEL);
-+ if (!dev->name) {
-+ retval = -ENOMEM;
-+ goto exit;
-+ }
-+
-+ strncpy(dev->name, user_dev->name, size);
-+ dev->idbus = user_dev->idbus;
-+ dev->idvendor = user_dev->idvendor;
-+ dev->idproduct = user_dev->idproduct;
-+ dev->idversion = user_dev->idversion;
-+ dev->ff_effects_max = user_dev->ff_effects_max;
-+
-+ size = sizeof(int) * (ABS_MAX + 1);
-+ memcpy(dev->absmax, user_dev->absmax, size);
-+ memcpy(dev->absmin, user_dev->absmin, size);
-+ memcpy(dev->absfuzz, user_dev->absfuzz, size);
-+ memcpy(dev->absflat, user_dev->absflat, size);
-+
-+ /* check if absmin/absmax/absfuzz/absflat are filled as
-+ * told in Documentation/input/input-programming.txt */
-+ if (test_bit(EV_ABS, dev->evbit)) {
-+ retval = uinput_validate_absbits(dev);
-+ if (retval < 0)
-+ kfree(dev->name);
-+ }
-+
-+exit:
-+ kfree(user_dev);
-+ return retval;
-+}
-+
-+static ssize_t uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
-+{
-+ struct uinput_device *udev = file->private_data;
-+
-+ if (test_bit(UIST_CREATED, &(udev->state))) {
-+ struct input_event ev;
-+
-+ if (copy_from_user(&ev, buffer, sizeof(struct input_event)))
-+ return -EFAULT;
-+ input_event(udev->dev, ev.type, ev.code, ev.value);
-+ }
-+ else
-+ count = uinput_alloc_device(file, buffer, count);
-+
-+ return count;
-+}
-+
-+static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
-+{
-+ struct uinput_device *udev = file->private_data;
-+ int retval = 0;
-+
-+ if (!test_bit(UIST_CREATED, &(udev->state)))
-+ return -ENODEV;
-+
-+ if ((udev->head == udev->tail) && (file->f_flags & O_NONBLOCK))
-+ return -EAGAIN;
-+
-+ retval = wait_event_interruptible(udev->waitq,
-+ (udev->head != udev->tail) ||
-+ !test_bit(UIST_CREATED, &(udev->state)));
-+
-+ if (retval)
-+ return retval;
-+
-+ if (!test_bit(UIST_CREATED, &(udev->state)))
-+ return -ENODEV;
-+
-+ while ((udev->head != udev->tail) &&
-+ (retval + sizeof(struct input_event) <= count)) {
-+ if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]),
-+ sizeof(struct input_event))) return -EFAULT;
-+ udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE;
-+ retval += sizeof(struct input_event);
-+ }
-+
-+ return retval;
-+}
-+
-+static unsigned int uinput_poll(struct file *file, poll_table *wait)
-+{
-+ struct uinput_device *udev = file->private_data;
-+
-+ poll_wait(file, &udev->waitq, wait);
-+
-+ if (udev->head != udev->tail)
-+ return POLLIN | POLLRDNORM;
-+
-+ return 0;
-+}
-+
-+static int uinput_burn_device(struct uinput_device *udev)
-+{
-+ if (test_bit(UIST_CREATED, &(udev->state)))
-+ uinput_destroy_device(udev);
-+
-+ kfree(udev->dev);
-+ kfree(udev);
-+
-+ return 0;
-+}
-+
-+static int uinput_close(struct inode *inode, struct file *file)
-+{
-+ return uinput_burn_device((struct uinput_device *)file->private_data);
-+}
-+
-+static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-+{
-+ int retval = 0;
-+ struct uinput_device *udev;
-+
-+ udev = (struct uinput_device *)file->private_data;
-+
-+ /* device attributes can not be changed after the device is created */
-+ if (cmd >= UI_SET_EVBIT && test_bit(UIST_CREATED, &(udev->state)))
-+ return -EINVAL;
-+
-+ switch (cmd) {
-+ case UI_DEV_CREATE:
-+ retval = uinput_create_device(udev);
-+ break;
-+
-+ case UI_DEV_DESTROY:
-+ retval = uinput_destroy_device(udev);
-+ break;
-+
-+ case UI_SET_EVBIT:
-+ if (arg > EV_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->evbit);
-+ break;
-+
-+ case UI_SET_KEYBIT:
-+ if (arg > KEY_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->keybit);
-+ break;
-+
-+ case UI_SET_RELBIT:
-+ if (arg > REL_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->relbit);
-+ break;
-+
-+ case UI_SET_ABSBIT:
-+ if (arg > ABS_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->absbit);
-+ break;
-+
-+ case UI_SET_MSCBIT:
-+ if (arg > MSC_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->mscbit);
-+ break;
-+
-+ case UI_SET_LEDBIT:
-+ if (arg > LED_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->ledbit);
-+ break;
-+
-+ case UI_SET_SNDBIT:
-+ if (arg > SND_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->sndbit);
-+ break;
-+
-+ case UI_SET_FFBIT:
-+ if (arg > FF_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->ffbit);
-+ break;
-+
-+ default:
-+ retval = -EFAULT;
-+ }
-+ return retval;
-+}
-+
-+struct file_operations uinput_fops = {
-+ owner: THIS_MODULE,
-+ open: uinput_open,
-+ release: uinput_close,
-+ read: uinput_read,
-+ write: uinput_write,
-+ poll: uinput_poll,
-+ ioctl: uinput_ioctl,
-+};
-+
-+static struct miscdevice uinput_misc = {
-+ fops: &uinput_fops,
-+ minor: UINPUT_MINOR,
-+ name: UINPUT_NAME,
-+};
-+
-+static int __init uinput_init(void)
-+{
-+ return misc_register(&uinput_misc);
-+}
-+
-+static void __exit uinput_exit(void)
-+{
-+ misc_deregister(&uinput_misc);
-+}
-+
-+MODULE_AUTHOR("Aristeu Sergio Rozanski Filho");
-+MODULE_DESCRIPTION("User level driver support for input subsystem");
-+MODULE_LICENSE("GPL");
-+
-+module_init(uinput_init);
-+module_exit(uinput_exit);
-+
-diff -urN linux-2.4.18/drivers/isdn/avmb1/capidrv.c linux-2.4.18-mh15/drivers/isdn/avmb1/capidrv.c
---- linux-2.4.18/drivers/isdn/avmb1/capidrv.c 2001-12-21 18:41:54.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/isdn/avmb1/capidrv.c 2004-08-01 16:26:23.000000000 +0200
-@@ -514,13 +514,25 @@
-
- static void send_message(capidrv_contr * card, _cmsg * cmsg)
- {
-- struct sk_buff *skb;
-- size_t len;
-+ struct sk_buff *skb;
-+ size_t len;
-+ u16 err;
-+
- capi_cmsg2message(cmsg, cmsg->buf);
- len = CAPIMSG_LEN(cmsg->buf);
- skb = alloc_skb(len, GFP_ATOMIC);
-+ if(!skb) {
-+ printk(KERN_ERR "no skb len(%d) memory\n", len);
-+ return;
-+ }
- memcpy(skb_put(skb, len), cmsg->buf, len);
-- (*capifuncs->capi_put_message) (global.appid, skb);
-+ err = (*capifuncs->capi_put_message) (global.appid, skb);
-+ if (err) {
-+ printk(KERN_WARNING "%s: capi_put_message error: %04x\n",
-+ __FUNCTION__, err);
-+ kfree_skb(skb);
-+ return;
-+ }
- global.nsentctlpkt++;
- }
-
-@@ -2179,10 +2191,10 @@
- free_ncci(card, card->bchans[card->nbchan-1].nccip);
- if (card->bchans[card->nbchan-1].plcip)
- free_plci(card, card->bchans[card->nbchan-1].plcip);
-- if (card->plci_list)
-- printk(KERN_ERR "capidrv: bug in free_plci()\n");
- card->nbchan--;
- }
-+ if (card->plci_list)
-+ printk(KERN_ERR "capidrv: bug in free_plci()\n");
- kfree(card->bchans);
- card->bchans = 0;
-
-diff -urN linux-2.4.18/drivers/isdn/avmb1/kcapi.c linux-2.4.18-mh15/drivers/isdn/avmb1/kcapi.c
---- linux-2.4.18/drivers/isdn/avmb1/kcapi.c 2001-12-21 18:41:54.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/isdn/avmb1/kcapi.c 2004-08-01 16:26:23.000000000 +0200
-@@ -545,7 +545,13 @@
- static void notify_up(__u32 contr)
- {
- struct capi_interface_user *p;
-+ __u16 appl;
-
-+ for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
-+ if (!VALID_APPLID(appl)) continue;
-+ if (APPL(appl)->releasing) continue;
-+ CARD(contr)->driver->register_appl(CARD(contr), appl, &APPL(appl)->rparam);
-+ }
- printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr);
- spin_lock(&capi_users_lock);
- for (p = capi_users; p; p = p->next) {
-@@ -705,12 +711,16 @@
- nextpp = &(*pp)->next;
- }
- }
-- APPL(appl)->releasing--;
-- if (APPL(appl)->releasing <= 0) {
-- APPL(appl)->signal = 0;
-- APPL_MARK_FREE(appl);
-- printk(KERN_INFO "kcapi: appl %d down\n", appl);
-- }
-+ if (APPL(appl)->releasing) { /* only release if the application was marked for release */
-+ printk(KERN_DEBUG "kcapi: appl %d releasing(%d)\n", appl, APPL(appl)->releasing);
-+ APPL(appl)->releasing--;
-+ if (APPL(appl)->releasing <= 0) {
-+ APPL(appl)->signal = 0;
-+ APPL_MARK_FREE(appl);
-+ printk(KERN_INFO "kcapi: appl %d down\n", appl);
-+ }
-+ } else
-+ printk(KERN_WARNING "kcapi: appl %d card%d released without request\n", appl, card->cnr);
- }
- /*
- * ncci management
-@@ -863,16 +873,7 @@
-
- static void controllercb_ready(struct capi_ctr * card)
- {
-- __u16 appl;
--
- card->cardstate = CARD_RUNNING;
--
-- for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
-- if (!VALID_APPLID(appl)) continue;
-- if (APPL(appl)->releasing) continue;
-- card->driver->register_appl(card, appl, &APPL(appl)->rparam);
-- }
--
- printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n",
- CARDNR(card), card->name);
-
-diff -urN linux-2.4.18/drivers/usb/Config.in linux-2.4.18-mh15/drivers/usb/Config.in
---- linux-2.4.18/drivers/usb/Config.in 2002-02-25 20:38:07.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/usb/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -31,7 +31,13 @@
-
- comment 'USB Device Class drivers'
- dep_tristate ' USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND
--dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB $CONFIG_EXPERIMENTAL
-+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-+ if [ "$CONFIG_BLUEZ" = "n" ]; then
-+ dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB
-+ else
-+ comment ' USB Bluetooth can only be used with disabled Bluetooth subsystem'
-+ fi
-+fi
- if [ "$CONFIG_SCSI" = "n" ]; then
- comment ' SCSI support is needed for USB Storage'
- fi
-diff -urN linux-2.4.18/drivers/usb/hid-core.c linux-2.4.18-mh15/drivers/usb/hid-core.c
---- linux-2.4.18/drivers/usb/hid-core.c 2001-12-21 18:41:55.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/usb/hid-core.c 2004-08-01 16:26:23.000000000 +0200
-@@ -217,6 +217,8 @@
-
- offset = report->size;
- report->size += parser->global.report_size * parser->global.report_count;
-+ if (usages < parser->global.report_count)
-+ usages = parser->global.report_count;
-
- if (usages == 0)
- return 0; /* ignore padding fields */
-diff -urN linux-2.4.18/include/linux/firmware.h linux-2.4.18-mh15/include/linux/firmware.h
---- linux-2.4.18/include/linux/firmware.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/include/linux/firmware.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,20 @@
-+#ifndef _LINUX_FIRMWARE_H
-+#define _LINUX_FIRMWARE_H
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#define FIRMWARE_NAME_MAX 30
-+struct firmware {
-+ size_t size;
-+ u8 *data;
-+};
-+int request_firmware (const struct firmware **fw, const char *name,
-+ const char *device);
-+int request_firmware_nowait (
-+ struct module *module,
-+ const char *name, const char *device, void *context,
-+ void (*cont)(const struct firmware *fw, void *context));
-+/* On 2.5 'device' is 'struct device *' */
-+
-+void release_firmware (const struct firmware *fw);
-+void register_firmware (const char *name, const u8 *data, size_t size);
-+#endif
-diff -urN linux-2.4.18/include/linux/input.h linux-2.4.18-mh15/include/linux/input.h
---- linux-2.4.18/include/linux/input.h 2001-09-13 00:34:06.000000000 +0200
-+++ linux-2.4.18-mh15/include/linux/input.h 2004-08-01 16:26:23.000000000 +0200
-@@ -468,6 +468,8 @@
- #define BUS_PCI 0x01
- #define BUS_ISAPNP 0x02
- #define BUS_USB 0x03
-+#define BUS_HIL 0x04
-+#define BUS_BLUETOOTH 0x05
-
- #define BUS_ISA 0x10
- #define BUS_I8042 0x11
-diff -urN linux-2.4.18/include/linux/kernel.h linux-2.4.18-mh15/include/linux/kernel.h
---- linux-2.4.18/include/linux/kernel.h 2002-02-25 20:38:13.000000000 +0100
-+++ linux-2.4.18-mh15/include/linux/kernel.h 2004-08-01 16:26:23.000000000 +0200
-@@ -11,6 +11,7 @@
- #include <linux/linkage.h>
- #include <linux/stddef.h>
- #include <linux/types.h>
-+#include <linux/compiler.h>
-
- /* Optimization barrier */
- /* The "volatile" is due to gcc bugs */
-@@ -181,4 +182,6 @@
- char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
- };
-
--#endif
-+#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
-+
-+#endif /* _LINUX_KERNEL_H */
-diff -urN linux-2.4.18/include/linux/net.h linux-2.4.18-mh15/include/linux/net.h
---- linux-2.4.18/include/linux/net.h 2001-11-22 20:46:19.000000000 +0100
-+++ linux-2.4.18-mh15/include/linux/net.h 2004-08-01 16:26:23.000000000 +0200
-@@ -139,6 +139,7 @@
- extern int sock_recvmsg(struct socket *, struct msghdr *m, int len, int flags);
- extern int sock_readv_writev(int type, struct inode * inode, struct file * file,
- const struct iovec * iov, long count, long size);
-+extern struct socket *sockfd_lookup(int fd, int *err);
-
- extern int net_ratelimit(void);
- extern unsigned long net_random(void);
-diff -urN linux-2.4.18/include/linux/uinput.h linux-2.4.18-mh15/include/linux/uinput.h
---- linux-2.4.18/include/linux/uinput.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/include/linux/uinput.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,79 @@
-+/*
-+ * User level driver support for input subsystem
-+ *
-+ * Heavily based on evdev.c by Vojtech Pavlik
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
-+ *
-+ * Changes/Revisions:
-+ * 0.1 20/06/2002
-+ * - first public version
-+ */
-+
-+#ifndef __UINPUT_H_
-+#define __UINPUT_H_
-+
-+#ifdef __KERNEL__
-+#define UINPUT_MINOR 223
-+#define UINPUT_NAME "uinput"
-+#define UINPUT_BUFFER_SIZE 16
-+
-+/* state flags => bit index for {set|clear|test}_bit ops */
-+#define UIST_CREATED 0
-+
-+struct uinput_device {
-+ struct input_dev *dev;
-+ unsigned long state;
-+ wait_queue_head_t waitq;
-+ unsigned char ready,
-+ head,
-+ tail;
-+ struct input_event buff[UINPUT_BUFFER_SIZE];
-+};
-+#endif /* __KERNEL__ */
-+
-+/* ioctl */
-+#define UINPUT_IOCTL_BASE 'U'
-+#define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1)
-+#define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2)
-+#define UI_SET_EVBIT _IOW(UINPUT_IOCTL_BASE, 100, int)
-+#define UI_SET_KEYBIT _IOW(UINPUT_IOCTL_BASE, 101, int)
-+#define UI_SET_RELBIT _IOW(UINPUT_IOCTL_BASE, 102, int)
-+#define UI_SET_ABSBIT _IOW(UINPUT_IOCTL_BASE, 103, int)
-+#define UI_SET_MSCBIT _IOW(UINPUT_IOCTL_BASE, 104, int)
-+#define UI_SET_LEDBIT _IOW(UINPUT_IOCTL_BASE, 105, int)
-+#define UI_SET_SNDBIT _IOW(UINPUT_IOCTL_BASE, 106, int)
-+#define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int)
-+
-+#ifndef NBITS
-+#define NBITS(x) ((((x)-1)/(sizeof(long)*8))+1)
-+#endif /* NBITS */
-+
-+#define UINPUT_MAX_NAME_SIZE 80
-+struct uinput_user_dev {
-+ char name[UINPUT_MAX_NAME_SIZE];
-+ unsigned short idbus;
-+ unsigned short idvendor;
-+ unsigned short idproduct;
-+ unsigned short idversion;
-+ int ff_effects_max;
-+ int absmax[ABS_MAX + 1];
-+ int absmin[ABS_MAX + 1];
-+ int absfuzz[ABS_MAX + 1];
-+ int absflat[ABS_MAX + 1];
-+};
-+#endif /* __UINPUT_H_ */
-diff -urN linux-2.4.18/include/net/bluetooth/bluetooth.h linux-2.4.18-mh15/include/net/bluetooth/bluetooth.h
---- linux-2.4.18/include/net/bluetooth/bluetooth.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/bluetooth.h 2004-08-01 16:26:23.000000000 +0200
-@@ -23,7 +23,7 @@
- */
-
- /*
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __BLUETOOTH_H
-@@ -31,17 +31,64 @@
-
- #include <asm/types.h>
- #include <asm/byteorder.h>
-+#include <linux/poll.h>
-+#include <net/sock.h>
-
- #ifndef AF_BLUETOOTH
- #define AF_BLUETOOTH 31
- #define PF_BLUETOOTH AF_BLUETOOTH
- #endif
-
-+/* Reserv for core and drivers use */
-+#define BLUEZ_SKB_RESERVE 8
-+
-+#ifndef MIN
-+#define MIN(a,b) ((a) < (b) ? (a) : (b))
-+#endif
-+
- #define BTPROTO_L2CAP 0
- #define BTPROTO_HCI 1
-+#define BTPROTO_SCO 2
-+#define BTPROTO_RFCOMM 3
-+#define BTPROTO_BNEP 4
-+#define BTPROTO_CMTP 5
-+#define BTPROTO_HIDP 6
-
- #define SOL_HCI 0
- #define SOL_L2CAP 6
-+#define SOL_SCO 17
-+#define SOL_RFCOMM 18
-+
-+/* Debugging */
-+#ifdef CONFIG_BLUEZ_DEBUG
-+
-+#define HCI_CORE_DEBUG 1
-+#define HCI_SOCK_DEBUG 1
-+#define HCI_UART_DEBUG 1
-+#define HCI_USB_DEBUG 1
-+//#define HCI_DATA_DUMP 1
-+
-+#define L2CAP_DEBUG 1
-+#define SCO_DEBUG 1
-+#define AF_BLUETOOTH_DEBUG 1
-+
-+#endif /* CONFIG_BLUEZ_DEBUG */
-+
-+extern void bluez_dump(char *pref, __u8 *buf, int count);
-+
-+#if __GNUC__ <= 2 && __GNUC_MINOR__ < 95
-+#define __func__ __FUNCTION__
-+#endif
-+
-+#define BT_INFO(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
-+#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __func__ , ## arg)
-+#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
-+
-+#ifdef HCI_DATA_DUMP
-+#define BT_DMP(buf, len) bluez_dump(__func__, buf, len)
-+#else
-+#define BT_DMP(D...)
-+#endif
-
- /* Connection and socket states */
- enum {
-@@ -50,6 +97,7 @@
- BT_BOUND,
- BT_LISTEN,
- BT_CONNECT,
-+ BT_CONNECT2,
- BT_CONFIG,
- BT_DISCONN,
- BT_CLOSED
-@@ -66,7 +114,8 @@
- __u8 b[6];
- } __attribute__((packed)) bdaddr_t;
-
--#define BDADDR_ANY ((bdaddr_t *)"\000\000\000\000\000")
-+#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
-+#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
-
- /* Copy, swap, convert BD Address */
- static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2)
-@@ -82,6 +131,91 @@
- char *batostr(bdaddr_t *ba);
- bdaddr_t *strtoba(char *str);
-
-+/* Common socket structures and functions */
-+
-+#define bluez_pi(sk) ((struct bluez_pinfo *) &sk->protinfo)
-+#define bluez_sk(pi) ((struct sock *) \
-+ ((void *)pi - (unsigned long)(&((struct sock *)0)->protinfo)))
-+
-+struct bluez_pinfo {
-+ bdaddr_t src;
-+ bdaddr_t dst;
-+
-+ struct list_head accept_q;
-+ struct sock *parent;
-+};
-+
-+struct bluez_sock_list {
-+ struct sock *head;
-+ rwlock_t lock;
-+};
-+
-+int bluez_sock_register(int proto, struct net_proto_family *ops);
-+int bluez_sock_unregister(int proto);
-+void bluez_sock_init(struct socket *sock, struct sock *sk);
-+void bluez_sock_link(struct bluez_sock_list *l, struct sock *s);
-+void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *s);
-+int bluez_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm);
-+uint bluez_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
-+int bluez_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
-+
-+void bluez_accept_enqueue(struct sock *parent, struct sock *sk);
-+struct sock * bluez_accept_dequeue(struct sock *parent, struct socket *newsock);
-+
-+/* Skb helpers */
-+struct bluez_skb_cb {
-+ int incomming;
-+};
-+#define bluez_cb(skb) ((struct bluez_skb_cb *)(skb->cb))
-+
-+static inline struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
-+{
-+ struct sk_buff *skb;
-+
-+ if ((skb = alloc_skb(len + BLUEZ_SKB_RESERVE, how))) {
-+ skb_reserve(skb, BLUEZ_SKB_RESERVE);
-+ bluez_cb(skb)->incomming = 0;
-+ }
-+ return skb;
-+}
-+
-+static inline struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len,
-+ int nb, int *err)
-+{
-+ struct sk_buff *skb;
-+
-+ if ((skb = sock_alloc_send_skb(sk, len + BLUEZ_SKB_RESERVE, nb, err))) {
-+ skb_reserve(skb, BLUEZ_SKB_RESERVE);
-+ bluez_cb(skb)->incomming = 0;
-+ }
-+
-+ return skb;
-+}
-+
-+static inline int skb_frags_no(struct sk_buff *skb)
-+{
-+ register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
-+ register int n = 1;
-+
-+ for (; frag; frag=frag->next, n++);
-+ return n;
-+}
-+
-+int hci_core_init(void);
-+int hci_core_cleanup(void);
-+int hci_sock_init(void);
-+int hci_sock_cleanup(void);
-+
- int bterr(__u16 code);
-
-+#ifndef MODULE_LICENSE
-+#define MODULE_LICENSE(x)
-+#endif
-+
-+#ifndef list_for_each_safe
-+#define list_for_each_safe(pos, n, head) \
-+ for (pos = (head)->next, n = pos->next; pos != (head); \
-+ pos = n, n = pos->next)
-+#endif
-+
- #endif /* __BLUETOOTH_H */
-diff -urN linux-2.4.18/include/net/bluetooth/bluez.h linux-2.4.18-mh15/include/net/bluetooth/bluez.h
---- linux-2.4.18/include/net/bluetooth/bluez.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/bluez.h 1970-01-01 01:00:00.000000000 +0100
-@@ -1,124 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifndef __IF_BLUEZ_H
--#define __IF_BLUEZ_H
--
--#include <net/sock.h>
--
--#define BLUEZ_MAX_PROTO 2
--
--/* Reserv for core and drivers use */
--#define BLUEZ_SKB_RESERVE 8
--
--#ifndef MIN
--#define MIN(a,b) ((a) < (b) ? (a) : (b))
--#endif
--
--/* Debugging */
--#ifdef BLUEZ_DEBUG
--
--#define HCI_CORE_DEBUG 1
--#define HCI_SOCK_DEBUG 1
--#define HCI_UART_DEBUG 1
--#define HCI_USB_DEBUG 1
--//#define HCI_DATA_DUMP 1
--
--#define L2CAP_DEBUG 1
--
--#endif /* BLUEZ_DEBUG */
--
--extern void bluez_dump(char *pref, __u8 *buf, int count);
--
--#define INF(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
--#define DBG(fmt, arg...) printk(KERN_INFO __FUNCTION__ ": " fmt "\n" , ## arg)
--#define ERR(fmt, arg...) printk(KERN_ERR __FUNCTION__ ": " fmt "\n" , ## arg)
--
--#ifdef HCI_DATA_DUMP
--#define DMP(buf, len) bluez_dump(__FUNCTION__, buf, len)
--#else
--#define DMP(D...)
--#endif
--
--/* ----- Sockets ------ */
--struct bluez_sock_list {
-- struct sock *head;
-- rwlock_t lock;
--};
--
--extern int bluez_sock_register(int proto, struct net_proto_family *ops);
--extern int bluez_sock_unregister(int proto);
--
--extern void bluez_sock_link(struct bluez_sock_list *l, struct sock *s);
--extern void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *s);
--
--/* ----- SKB helpers ----- */
--struct bluez_skb_cb {
-- int incomming;
--};
--#define bluez_cb(skb) ((struct bluez_skb_cb *)(skb->cb))
--
--static inline struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
--{
-- struct sk_buff *skb;
--
-- if ((skb = alloc_skb(len + BLUEZ_SKB_RESERVE, how))) {
-- skb_reserve(skb, BLUEZ_SKB_RESERVE);
-- bluez_cb(skb)->incomming = 0;
-- }
-- return skb;
--}
--
--static inline struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len,
-- int nb, int *err)
--{
-- struct sk_buff *skb;
--
-- if ((skb = sock_alloc_send_skb(sk, len + BLUEZ_SKB_RESERVE, nb, err))) {
-- skb_reserve(skb, BLUEZ_SKB_RESERVE);
-- bluez_cb(skb)->incomming = 0;
-- }
--
-- return skb;
--}
--
--static inline int skb_frags_no(struct sk_buff *skb)
--{
-- register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
-- register int n = 1;
--
-- for (; frag; frag=frag->next, n++);
-- return n;
--}
--
--extern int hci_core_init(void);
--extern int hci_core_cleanup(void);
--extern int hci_sock_init(void);
--extern int hci_sock_cleanup(void);
--
--#endif /* __IF_BLUEZ_H */
-diff -urN linux-2.4.18/include/net/bluetooth/hci_core.h linux-2.4.18-mh15/include/net/bluetooth/hci_core.h
---- linux-2.4.18/include/net/bluetooth/hci_core.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/hci_core.h 2004-08-01 16:26:23.000000000 +0200
-@@ -23,7 +23,7 @@
- */
-
- /*
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __HCI_CORE_H
-@@ -32,14 +32,12 @@
- #include <net/bluetooth/hci.h>
-
- /* HCI upper protocols */
--#define HCI_MAX_PROTO 1
- #define HCI_PROTO_L2CAP 0
-+#define HCI_PROTO_SCO 1
-
- #define HCI_INIT_TIMEOUT (HZ * 10)
-
--/* ----- Inquiry cache ----- */
--#define INQUIRY_CACHE_AGE_MAX (HZ*5) // 5 seconds
--#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds
-+/* HCI Core structures */
-
- struct inquiry_entry {
- struct inquiry_entry *next;
-@@ -53,111 +51,188 @@
- struct inquiry_entry *list;
- };
-
--static inline void inquiry_cache_init(struct inquiry_cache *cache)
--{
-- spin_lock_init(&cache->lock);
-- cache->list = NULL;
--}
-+struct conn_hash {
-+ struct list_head list;
-+ spinlock_t lock;
-+ unsigned int num;
-+};
-
--static inline void inquiry_cache_lock(struct inquiry_cache *cache)
--{
-- spin_lock(&cache->lock);
--}
-+struct hci_dev {
-+ struct list_head list;
-+ spinlock_t lock;
-+ atomic_t refcnt;
-
--static inline void inquiry_cache_unlock(struct inquiry_cache *cache)
--{
-- spin_unlock(&cache->lock);
--}
-+ char name[8];
-+ unsigned long flags;
-+ __u16 id;
-+ __u8 type;
-+ bdaddr_t bdaddr;
-+ __u8 features[8];
-
--static inline void inquiry_cache_lock_bh(struct inquiry_cache *cache)
--{
-- spin_lock_bh(&cache->lock);
--}
-+ __u16 pkt_type;
-+ __u16 link_policy;
-+ __u16 link_mode;
-
--static inline void inquiry_cache_unlock_bh(struct inquiry_cache *cache)
--{
-- spin_unlock_bh(&cache->lock);
--}
-+ unsigned long quirks;
-
--static inline long inquiry_cache_age(struct inquiry_cache *cache)
--{
-- return jiffies - cache->timestamp;
--}
-+ atomic_t cmd_cnt;
-+ unsigned int acl_cnt;
-+ unsigned int sco_cnt;
-
--static inline long inquiry_entry_age(struct inquiry_entry *e)
--{
-- return jiffies - e->timestamp;
--}
--extern void inquiry_cache_flush(struct inquiry_cache *cache);
-+ unsigned int acl_mtu;
-+ unsigned int sco_mtu;
-+ unsigned int acl_pkts;
-+ unsigned int sco_pkts;
-
--struct hci_dev;
-+ unsigned long cmd_last_tx;
-+ unsigned long acl_last_tx;
-+ unsigned long sco_last_tx;
-+
-+ struct tasklet_struct cmd_task;
-+ struct tasklet_struct rx_task;
-+ struct tasklet_struct tx_task;
-+
-+ struct sk_buff_head rx_q;
-+ struct sk_buff_head raw_q;
-+ struct sk_buff_head cmd_q;
-+
-+ struct sk_buff *sent_cmd;
-+
-+ struct semaphore req_lock;
-+ wait_queue_head_t req_wait_q;
-+ __u32 req_status;
-+ __u32 req_result;
-+
-+ struct inquiry_cache inq_cache;
-+ struct conn_hash conn_hash;
-+
-+ struct hci_dev_stats stat;
-+
-+ void *driver_data;
-+ void *core_data;
-+
-+ atomic_t promisc;
-+
-+ int (*open)(struct hci_dev *hdev);
-+ int (*close)(struct hci_dev *hdev);
-+ int (*flush)(struct hci_dev *hdev);
-+ int (*send)(struct sk_buff *skb);
-+ void (*destruct)(struct hci_dev *hdev);
-+ int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
-+};
-
--/* ----- HCI Connections ----- */
- struct hci_conn {
- struct list_head list;
-+
-+ atomic_t refcnt;
-+ spinlock_t lock;
-+
- bdaddr_t dst;
- __u16 handle;
-+ __u16 state;
- __u8 type;
-- unsigned int sent;
-+ __u8 out;
-+ __u32 link_mode;
-+ unsigned long pend;
-+
-+ unsigned int sent;
-+
-+ struct sk_buff_head data_q;
-
-+ struct timer_list timer;
-+
- struct hci_dev *hdev;
- void *l2cap_data;
-+ void *sco_data;
- void *priv;
-
-- struct sk_buff_head data_q;
-+ struct hci_conn *link;
- };
-
--struct conn_hash {
-- struct list_head list;
-- spinlock_t lock;
-- unsigned int num;
--};
-+extern struct hci_proto *hci_proto[];
-+extern struct list_head hdev_list;
-+extern rwlock_t hdev_list_lock;
-+
-+/* ----- Inquiry cache ----- */
-+#define INQUIRY_CACHE_AGE_MAX (HZ*30) // 30 seconds
-+#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds
-+
-+#define inquiry_cache_lock(c) spin_lock(&c->lock)
-+#define inquiry_cache_unlock(c) spin_unlock(&c->lock)
-+#define inquiry_cache_lock_bh(c) spin_lock_bh(&c->lock)
-+#define inquiry_cache_unlock_bh(c) spin_unlock_bh(&c->lock)
-
--static inline void conn_hash_init(struct conn_hash *h)
-+static inline void inquiry_cache_init(struct hci_dev *hdev)
- {
-- INIT_LIST_HEAD(&h->list);
-- spin_lock_init(&h->lock);
-- h->num = 0;
-+ struct inquiry_cache *c = &hdev->inq_cache;
-+ spin_lock_init(&c->lock);
-+ c->list = NULL;
- }
-
--static inline void conn_hash_lock(struct conn_hash *h)
-+static inline int inquiry_cache_empty(struct hci_dev *hdev)
- {
-- spin_lock(&h->lock);
-+ struct inquiry_cache *c = &hdev->inq_cache;
-+ return (c->list == NULL);
- }
-
--static inline void conn_hash_unlock(struct conn_hash *h)
-+static inline long inquiry_cache_age(struct hci_dev *hdev)
- {
-- spin_unlock(&h->lock);
-+ struct inquiry_cache *c = &hdev->inq_cache;
-+ return jiffies - c->timestamp;
- }
-
--static inline void __conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
-+static inline long inquiry_entry_age(struct inquiry_entry *e)
- {
-- list_add(&c->list, &h->list);
-- h->num++;
-+ return jiffies - e->timestamp;
- }
-
--static inline void conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
-+struct inquiry_entry *inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
-+void inquiry_cache_update(struct hci_dev *hdev, inquiry_info *info);
-+void inquiry_cache_flush(struct hci_dev *hdev);
-+int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf);
-+
-+/* ----- HCI Connections ----- */
-+enum {
-+ HCI_CONN_AUTH_PEND,
-+ HCI_CONN_ENCRYPT_PEND
-+};
-+
-+#define hci_conn_lock(c) spin_lock(&c->lock)
-+#define hci_conn_unlock(c) spin_unlock(&c->lock)
-+#define hci_conn_lock_bh(c) spin_lock_bh(&c->lock)
-+#define hci_conn_unlock_bh(c) spin_unlock_bh(&c->lock)
-+
-+#define conn_hash_lock(d) spin_lock(&d->conn_hash->lock)
-+#define conn_hash_unlock(d) spin_unlock(&d->conn_hash->lock)
-+#define conn_hash_lock_bh(d) spin_lock_bh(&d->conn_hash->lock)
-+#define conn_hash_unlock_bh(d) spin_unlock_bh(&d->conn_hash->lock)
-+
-+static inline void conn_hash_init(struct hci_dev *hdev)
- {
-- conn_hash_lock(h);
-- __conn_hash_add(h, handle, c);
-- conn_hash_unlock(h);
-+ struct conn_hash *h = &hdev->conn_hash;
-+ INIT_LIST_HEAD(&h->list);
-+ spin_lock_init(&h->lock);
-+ h->num = 0;
- }
-
--static inline void __conn_hash_del(struct conn_hash *h, struct hci_conn *c)
-+static inline void conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
- {
-- list_del(&c->list);
-- h->num--;
-+ struct conn_hash *h = &hdev->conn_hash;
-+ list_add(&c->list, &h->list);
-+ h->num++;
- }
-
--static inline void conn_hash_del(struct conn_hash *h, struct hci_conn *c)
-+static inline void conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
- {
-- conn_hash_lock(h);
-- __conn_hash_del(h, c);
-- conn_hash_unlock(h);
-+ struct conn_hash *h = &hdev->conn_hash;
-+ list_del(&c->list);
-+ h->num--;
- }
-
--static inline struct hci_conn *__conn_hash_lookup(struct conn_hash *h, __u16 handle)
-+static inline struct hci_conn *conn_hash_lookup_handle(struct hci_dev *hdev,
-+ __u16 handle)
- {
-+ register struct conn_hash *h = &hdev->conn_hash;
- register struct list_head *p;
- register struct hci_conn *c;
-
-@@ -169,101 +244,97 @@
- return NULL;
- }
-
--static inline struct hci_conn *conn_hash_lookup(struct conn_hash *h, __u16 handle)
-+static inline struct hci_conn *conn_hash_lookup_ba(struct hci_dev *hdev,
-+ __u8 type, bdaddr_t *ba)
- {
-- struct hci_conn *conn;
-+ register struct conn_hash *h = &hdev->conn_hash;
-+ register struct list_head *p;
-+ register struct hci_conn *c;
-
-- conn_hash_lock(h);
-- conn = __conn_hash_lookup(h, handle);
-- conn_hash_unlock(h);
-- return conn;
-+ list_for_each(p, &h->list) {
-+ c = list_entry(p, struct hci_conn, list);
-+ if (c->type == type && !bacmp(&c->dst, ba))
-+ return c;
-+ }
-+ return NULL;
- }
-
--/* ----- HCI Devices ----- */
--struct hci_dev {
-- atomic_t refcnt;
--
-- char name[8];
-- __u32 flags;
-- __u16 id;
-- __u8 type;
-- bdaddr_t bdaddr;
-- __u8 features[8];
--
-- __u16 pkt_type;
--
-- atomic_t cmd_cnt;
-- unsigned int acl_cnt;
-- unsigned int sco_cnt;
--
-- unsigned int acl_mtu;
-- unsigned int sco_mtu;
-- unsigned int acl_max;
-- unsigned int sco_max;
--
-- void *driver_data;
-- void *l2cap_data;
-- void *priv;
--
-- struct tasklet_struct cmd_task;
-- struct tasklet_struct rx_task;
-- struct tasklet_struct tx_task;
--
-- struct sk_buff_head rx_q;
-- struct sk_buff_head raw_q;
-- struct sk_buff_head cmd_q;
--
-- struct sk_buff *sent_cmd;
-+void hci_acl_connect(struct hci_conn *conn);
-+void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
-+void hci_add_sco(struct hci_conn *conn, __u16 handle);
-
-- struct semaphore req_lock;
-- wait_queue_head_t req_wait_q;
-- __u32 req_status;
-- __u32 req_result;
-+struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
-+int hci_conn_del(struct hci_conn *conn);
-+void hci_conn_hash_flush(struct hci_dev *hdev);
-
-- struct inquiry_cache inq_cache;
-+struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src);
-+int hci_conn_auth(struct hci_conn *conn);
-+int hci_conn_encrypt(struct hci_conn *conn);
-
-- struct conn_hash conn_hash;
--
-- struct hci_dev_stats stat;
--
-- int (*open)(struct hci_dev *hdev);
-- int (*close)(struct hci_dev *hdev);
-- int (*flush)(struct hci_dev *hdev);
-- int (*send)(struct sk_buff *skb);
--};
-+static inline void hci_conn_set_timer(struct hci_conn *conn, long timeout)
-+{
-+ mod_timer(&conn->timer, jiffies + timeout);
-+}
-
--static inline void hci_dev_hold(struct hci_dev *hdev)
-+static inline void hci_conn_del_timer(struct hci_conn *conn)
- {
-- atomic_inc(&hdev->refcnt);
-+ del_timer(&conn->timer);
- }
-
--static inline void hci_dev_put(struct hci_dev *hdev)
-+static inline void hci_conn_hold(struct hci_conn *conn)
- {
-- atomic_dec(&hdev->refcnt);
-+ atomic_inc(&conn->refcnt);
-+ hci_conn_del_timer(conn);
- }
-
--extern struct hci_dev *hci_dev_get(int index);
--extern int hci_register_dev(struct hci_dev *hdev);
--extern int hci_unregister_dev(struct hci_dev *hdev);
--extern int hci_dev_open(__u16 dev);
--extern int hci_dev_close(__u16 dev);
--extern int hci_dev_reset(__u16 dev);
--extern int hci_dev_reset_stat(__u16 dev);
--extern int hci_dev_info(unsigned long arg);
--extern int hci_dev_list(unsigned long arg);
--extern int hci_dev_setscan(unsigned long arg);
--extern int hci_dev_setauth(unsigned long arg);
--extern int hci_dev_setptype(unsigned long arg);
--extern int hci_conn_list(unsigned long arg);
--extern int hci_inquiry(unsigned long arg);
-+static inline void hci_conn_put(struct hci_conn *conn)
-+{
-+ if (atomic_dec_and_test(&conn->refcnt)) {
-+ if (conn->type == ACL_LINK) {
-+ unsigned long timeo = (conn->out) ?
-+ HCI_DISCONN_TIMEOUT : HCI_DISCONN_TIMEOUT * 2;
-+ hci_conn_set_timer(conn, timeo);
-+ } else
-+ hci_conn_set_timer(conn, HZ / 100);
-+ }
-+}
-
--extern __u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode);
--extern __u32 hci_dev_getmode(struct hci_dev *hdev);
-+/* ----- HCI Devices ----- */
-+static inline void hci_dev_put(struct hci_dev *d)
-+{
-+ if (atomic_dec_and_test(&d->refcnt))
-+ d->destruct(d);
-+}
-+#define hci_dev_hold(d) atomic_inc(&d->refcnt)
-+
-+#define hci_dev_lock(d) spin_lock(&d->lock)
-+#define hci_dev_unlock(d) spin_unlock(&d->lock)
-+#define hci_dev_lock_bh(d) spin_lock_bh(&d->lock)
-+#define hci_dev_unlock_bh(d) spin_unlock_bh(&d->lock)
-+
-+struct hci_dev *hci_dev_get(int index);
-+struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst);
-+int hci_register_dev(struct hci_dev *hdev);
-+int hci_unregister_dev(struct hci_dev *hdev);
-+int hci_suspend_dev(struct hci_dev *hdev);
-+int hci_resume_dev(struct hci_dev *hdev);
-+int hci_dev_open(__u16 dev);
-+int hci_dev_close(__u16 dev);
-+int hci_dev_reset(__u16 dev);
-+int hci_dev_reset_stat(__u16 dev);
-+int hci_dev_cmd(unsigned int cmd, unsigned long arg);
-+int hci_get_dev_list(unsigned long arg);
-+int hci_get_dev_info(unsigned long arg);
-+int hci_get_conn_list(unsigned long arg);
-+int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg);
-+int hci_inquiry(unsigned long arg);
-
--extern int hci_recv_frame(struct sk_buff *skb);
-+int hci_recv_frame(struct sk_buff *skb);
-+void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
-
- /* ----- LMP capabilities ----- */
- #define lmp_rswitch_capable(dev) (dev->features[0] & LMP_RSWITCH)
-+#define lmp_encrypt_capable(dev) (dev->features[0] & LMP_ENCRYPT)
-
- /* ----- HCI tasks ----- */
- static inline void hci_sched_cmd(struct hci_dev *hdev)
-@@ -284,43 +355,130 @@
- /* ----- HCI protocols ----- */
- struct hci_proto {
- char *name;
-- __u32 id;
-- __u32 flags;
-+ unsigned int id;
-+ unsigned long flags;
-
- void *priv;
-
-- int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr);
-- int (*connect_cfm) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 status, struct hci_conn *conn);
-+ int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type);
-+ int (*connect_cfm) (struct hci_conn *conn, __u8 status);
- int (*disconn_ind) (struct hci_conn *conn, __u8 reason);
-- int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb , __u16 flags);
-+ int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
- int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb);
-+ int (*auth_cfm) (struct hci_conn *conn, __u8 status);
-+ int (*encrypt_cfm) (struct hci_conn *conn, __u8 status);
- };
-
--extern int hci_register_proto(struct hci_proto *hproto);
--extern int hci_unregister_proto(struct hci_proto *hproto);
--extern int hci_register_notifier(struct notifier_block *nb);
--extern int hci_unregister_notifier(struct notifier_block *nb);
--extern int hci_connect(struct hci_dev * hdev, bdaddr_t * bdaddr);
--extern int hci_disconnect(struct hci_conn *conn, __u8 reason);
--extern int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void * param);
--extern int hci_send_raw(struct sk_buff *skb);
--extern int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
--extern int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
-+static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
-+{
-+ register struct hci_proto *hp;
-+ int mask = 0;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->connect_ind)
-+ mask |= hp->connect_ind(hdev, bdaddr, type);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->connect_ind)
-+ mask |= hp->connect_ind(hdev, bdaddr, type);
-+
-+ return mask;
-+}
-+
-+static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
-+{
-+ register struct hci_proto *hp;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->connect_cfm)
-+ hp->connect_cfm(conn, status);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->connect_cfm)
-+ hp->connect_cfm(conn, status);
-+}
-+
-+static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason)
-+{
-+ register struct hci_proto *hp;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->disconn_ind)
-+ hp->disconn_ind(conn, reason);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->disconn_ind)
-+ hp->disconn_ind(conn, reason);
-+}
-+
-+static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
-+{
-+ register struct hci_proto *hp;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->auth_cfm)
-+ hp->auth_cfm(conn, status);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->auth_cfm)
-+ hp->auth_cfm(conn, status);
-+}
-+
-+static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status)
-+{
-+ register struct hci_proto *hp;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->encrypt_cfm)
-+ hp->encrypt_cfm(conn, status);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->encrypt_cfm)
-+ hp->encrypt_cfm(conn, status);
-+}
-+
-+int hci_register_proto(struct hci_proto *hproto);
-+int hci_unregister_proto(struct hci_proto *hproto);
-+int hci_register_notifier(struct notifier_block *nb);
-+int hci_unregister_notifier(struct notifier_block *nb);
-+
-+int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param);
-+int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
-+int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
-+
-+void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf);
-+
-+void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
-
- /* ----- HCI Sockets ----- */
--extern void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
-+void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
-
- /* HCI info for socket */
--#define hci_pi(sk) ((struct hci_pinfo *) &sk->protinfo)
-+#define hci_pi(sk) ((struct hci_pinfo *) &sk->tp_pinfo)
- struct hci_pinfo {
- struct hci_dev *hdev;
- struct hci_filter filter;
- __u32 cmsg_mask;
- };
-
-+/* HCI security filter */
-+#define HCI_SFLT_MAX_OGF 5
-+
-+struct hci_sec_filter {
-+ __u32 type_mask;
-+ __u32 event_mask[2];
-+ __u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4];
-+};
-+
- /* ----- HCI requests ----- */
- #define HCI_REQ_DONE 0
- #define HCI_REQ_PEND 1
- #define HCI_REQ_CANCELED 2
-
-+#define hci_req_lock(d) down(&d->req_lock)
-+#define hci_req_unlock(d) up(&d->req_lock)
-+
-+void hci_req_complete(struct hci_dev *hdev, int result);
-+void hci_req_cancel(struct hci_dev *hdev, int err);
-+
- #endif /* __HCI_CORE_H */
-diff -urN linux-2.4.18/include/net/bluetooth/hci.h linux-2.4.18-mh15/include/net/bluetooth/hci.h
---- linux-2.4.18/include/net/bluetooth/hci.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/hci.h 2004-08-01 16:26:23.000000000 +0200
-@@ -23,59 +23,80 @@
- */
-
- /*
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __HCI_H
- #define __HCI_H
-
--#include <asm/byteorder.h>
--
--#define HCI_MAX_DEV 8
--#define HCI_MAX_FRAME_SIZE 2048
-+#define HCI_MAX_ACL_SIZE 1024
-+#define HCI_MAX_SCO_SIZE 255
-+#define HCI_MAX_EVENT_SIZE 260
-+#define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4)
-
- /* HCI dev events */
- #define HCI_DEV_REG 1
- #define HCI_DEV_UNREG 2
- #define HCI_DEV_UP 3
- #define HCI_DEV_DOWN 4
-+#define HCI_DEV_SUSPEND 5
-+#define HCI_DEV_RESUME 6
-
- /* HCI device types */
--#define HCI_UART 0
-+#define HCI_VHCI 0
- #define HCI_USB 1
--#define HCI_VHCI 2
--
--/* HCI device modes */
--#define HCI_NORMAL 0x0001
--#define HCI_RAW 0x0002
--#define HCI_MODE_MASK (HCI_NORMAL | HCI_RAW)
--#define HCI_SOCK 0x1000
--
--/* HCI device states */
--#define HCI_INIT 0x0010
--#define HCI_UP 0x0020
--#define HCI_RUNNING 0x0040
-+#define HCI_PCCARD 2
-+#define HCI_UART 3
-+#define HCI_RS232 4
-+#define HCI_PCI 5
-+
-+/* HCI device quirks */
-+enum {
-+ HCI_QUIRK_RESET_ON_INIT
-+};
-
- /* HCI device flags */
--#define HCI_PSCAN 0x0100
--#define HCI_ISCAN 0x0200
--#define HCI_AUTH 0x0400
-+enum {
-+ HCI_UP,
-+ HCI_INIT,
-+ HCI_RUNNING,
-+
-+ HCI_PSCAN,
-+ HCI_ISCAN,
-+ HCI_AUTH,
-+ HCI_ENCRYPT,
-+ HCI_INQUIRY,
-+
-+ HCI_RAW
-+};
-
--/* HCI Ioctl defines */
-+/* HCI ioctl defines */
- #define HCIDEVUP _IOW('H', 201, int)
- #define HCIDEVDOWN _IOW('H', 202, int)
- #define HCIDEVRESET _IOW('H', 203, int)
--#define HCIRESETSTAT _IOW('H', 204, int)
--#define HCIGETINFO _IOR('H', 205, int)
--#define HCIGETDEVLIST _IOR('H', 206, int)
--#define HCISETRAW _IOW('H', 207, int)
--#define HCISETSCAN _IOW('H', 208, int)
--#define HCISETAUTH _IOW('H', 209, int)
--#define HCIINQUIRY _IOR('H', 210, int)
--#define HCISETPTYPE _IOW('H', 211, int)
-+#define HCIDEVRESTAT _IOW('H', 204, int)
-+
-+#define HCIGETDEVLIST _IOR('H', 210, int)
-+#define HCIGETDEVINFO _IOR('H', 211, int)
- #define HCIGETCONNLIST _IOR('H', 212, int)
-+#define HCIGETCONNINFO _IOR('H', 213, int)
-
--#ifndef __NO_HCI_DEFS
-+#define HCISETRAW _IOW('H', 220, int)
-+#define HCISETSCAN _IOW('H', 221, int)
-+#define HCISETAUTH _IOW('H', 222, int)
-+#define HCISETENCRYPT _IOW('H', 223, int)
-+#define HCISETPTYPE _IOW('H', 224, int)
-+#define HCISETLINKPOL _IOW('H', 225, int)
-+#define HCISETLINKMODE _IOW('H', 226, int)
-+#define HCISETACLMTU _IOW('H', 227, int)
-+#define HCISETSCOMTU _IOW('H', 228, int)
-+
-+#define HCIINQUIRY _IOR('H', 240, int)
-+
-+/* HCI timeouts */
-+#define HCI_CONN_TIMEOUT (HZ * 40)
-+#define HCI_DISCONN_TIMEOUT (HZ * 2)
-+#define HCI_CONN_IDLE_TIMEOUT (HZ * 60)
-
- /* HCI Packet types */
- #define HCI_COMMAND_PKT 0x01
-@@ -92,11 +113,18 @@
- #define HCI_DH3 0x0800
- #define HCI_DH5 0x8000
-
-+#define HCI_HV1 0x0020
-+#define HCI_HV2 0x0040
-+#define HCI_HV3 0x0080
-+
-+#define SCO_PTYPE_MASK (HCI_HV1 | HCI_HV2 | HCI_HV3)
-+#define ACL_PTYPE_MASK (~SCO_PTYPE_MASK)
-+
- /* ACL flags */
--#define ACL_CONT 0x0001
--#define ACL_START 0x0002
--#define ACL_ACTIVE_BCAST 0x0010
--#define ACL_PICO_BCAST 0x0020
-+#define ACL_CONT 0x01
-+#define ACL_START 0x02
-+#define ACL_ACTIVE_BCAST 0x04
-+#define ACL_PICO_BCAST 0x08
-
- /* Baseband links */
- #define SCO_LINK 0x00
-@@ -125,6 +153,20 @@
- #define LMP_PSCHEME 0x02
- #define LMP_PCONTROL 0x04
-
-+/* Link policies */
-+#define HCI_LP_RSWITCH 0x0001
-+#define HCI_LP_HOLD 0x0002
-+#define HCI_LP_SNIFF 0x0004
-+#define HCI_LP_PARK 0x0008
-+
-+/* Link mode */
-+#define HCI_LM_ACCEPT 0x8000
-+#define HCI_LM_MASTER 0x0001
-+#define HCI_LM_AUTH 0x0002
-+#define HCI_LM_ENCRYPT 0x0004
-+#define HCI_LM_TRUSTED 0x0008
-+#define HCI_LM_RELIABLE 0x0010
-+
- /* ----- HCI Commands ----- */
- /* OGF & OCF values */
-
-@@ -137,9 +179,10 @@
- __u8 hci_ver;
- __u16 hci_rev;
- __u8 lmp_ver;
-- __u16 man_name;
-- __u16 lmp_sub;
-+ __u16 manufacturer;
-+ __u16 lmp_subver;
- } __attribute__ ((packed)) read_local_version_rp;
-+#define READ_LOCAL_VERSION_RP_SIZE 9
-
- #define OCF_READ_LOCAL_FEATURES 0x0003
- typedef struct {
-@@ -165,18 +208,24 @@
- /* Host Controller and Baseband */
- #define OGF_HOST_CTL 0x03
- #define OCF_RESET 0x0003
-+#define OCF_READ_AUTH_ENABLE 0x001F
- #define OCF_WRITE_AUTH_ENABLE 0x0020
-- #define AUTH_DISABLED 0x00
-- #define AUTH_ENABLED 0x01
-+ #define AUTH_DISABLED 0x00
-+ #define AUTH_ENABLED 0x01
-+
-+#define OCF_READ_ENCRYPT_MODE 0x0021
-+#define OCF_WRITE_ENCRYPT_MODE 0x0022
-+ #define ENCRYPT_DISABLED 0x00
-+ #define ENCRYPT_P2P 0x01
-+ #define ENCRYPT_BOTH 0x02
-
- #define OCF_WRITE_CA_TIMEOUT 0x0016
- #define OCF_WRITE_PG_TIMEOUT 0x0018
-
- #define OCF_WRITE_SCAN_ENABLE 0x001A
-- #define SCANS_DISABLED 0x00
-- #define IS_ENA_PS_DIS 0x01
-- #define IS_DIS_PS_ENA 0x02
-- #define IS_ENA_PS_ENA 0x03
-+ #define SCAN_DISABLED 0x00
-+ #define SCAN_INQUIRY 0x01
-+ #define SCAN_PAGE 0x02
-
- #define OCF_SET_EVENT_FLT 0x0005
- typedef struct {
-@@ -226,9 +275,18 @@
- } __attribute__ ((packed)) write_class_of_dev_cp;
- #define WRITE_CLASS_OF_DEV_CP_SIZE 3
-
-+#define OCF_HOST_BUFFER_SIZE 0x0033
-+typedef struct {
-+ __u16 acl_mtu;
-+ __u8 sco_mtu;
-+ __u16 acl_max_pkt;
-+ __u16 sco_max_pkt;
-+} __attribute__ ((packed)) host_buffer_size_cp;
-+#define HOST_BUFFER_SIZE_CP_SIZE 7
-+
- /* Link Control */
- #define OGF_LINK_CTL 0x01
--#define OCF_CREATE_CONN 0x0005
-+#define OCF_CREATE_CONN 0x0005
- typedef struct {
- bdaddr_t bdaddr;
- __u16 pkt_type;
-@@ -246,6 +304,13 @@
- } __attribute__ ((packed)) accept_conn_req_cp;
- #define ACCEPT_CONN_REQ_CP_SIZE 7
-
-+#define OCF_REJECT_CONN_REQ 0x000a
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 reason;
-+} __attribute__ ((packed)) reject_conn_req_cp;
-+#define REJECT_CONN_REQ_CP_SIZE 7
-+
- #define OCF_DISCONNECT 0x0006
- typedef struct {
- __u16 handle;
-@@ -253,17 +318,142 @@
- } __attribute__ ((packed)) disconnect_cp;
- #define DISCONNECT_CP_SIZE 3
-
-+#define OCF_ADD_SCO 0x0007
-+typedef struct {
-+ __u16 handle;
-+ __u16 pkt_type;
-+} __attribute__ ((packed)) add_sco_cp;
-+#define ADD_SCO_CP_SIZE 4
-+
- #define OCF_INQUIRY 0x0001
- typedef struct {
- __u8 lap[3];
-- __u8 lenght;
-+ __u8 length;
- __u8 num_rsp;
- } __attribute__ ((packed)) inquiry_cp;
- #define INQUIRY_CP_SIZE 5
-
--#define OGF_LINK_POLICY 0x02 /* Link Policy */
-+typedef struct {
-+ __u8 status;
-+ bdaddr_t bdaddr;
-+} __attribute__ ((packed)) status_bdaddr_rp;
-+#define STATUS_BDADDR_RP_SIZE 7
-+
-+#define OCF_INQUIRY_CANCEL 0x0002
-+
-+#define OCF_LINK_KEY_REPLY 0x000B
-+#define OCF_LINK_KEY_NEG_REPLY 0x000C
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 link_key[16];
-+} __attribute__ ((packed)) link_key_reply_cp;
-+#define LINK_KEY_REPLY_CP_SIZE 22
-+
-+#define OCF_PIN_CODE_REPLY 0x000D
-+#define OCF_PIN_CODE_NEG_REPLY 0x000E
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 pin_len;
-+ __u8 pin_code[16];
-+} __attribute__ ((packed)) pin_code_reply_cp;
-+#define PIN_CODE_REPLY_CP_SIZE 23
-+
-+#define OCF_CHANGE_CONN_PTYPE 0x000F
-+typedef struct {
-+ __u16 handle;
-+ __u16 pkt_type;
-+} __attribute__ ((packed)) change_conn_ptype_cp;
-+#define CHANGE_CONN_PTYPE_CP_SIZE 4
-+
-+#define OCF_AUTH_REQUESTED 0x0011
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) auth_requested_cp;
-+#define AUTH_REQUESTED_CP_SIZE 2
-+
-+#define OCF_SET_CONN_ENCRYPT 0x0013
-+typedef struct {
-+ __u16 handle;
-+ __u8 encrypt;
-+} __attribute__ ((packed)) set_conn_encrypt_cp;
-+#define SET_CONN_ENCRYPT_CP_SIZE 3
-+
-+#define OCF_REMOTE_NAME_REQ 0x0019
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 pscan_rep_mode;
-+ __u8 pscan_mode;
-+ __u16 clock_offset;
-+} __attribute__ ((packed)) remote_name_req_cp;
-+#define REMOTE_NAME_REQ_CP_SIZE 10
-+
-+#define OCF_READ_REMOTE_FEATURES 0x001B
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) read_remote_features_cp;
-+#define READ_REMOTE_FEATURES_CP_SIZE 2
-+
-+#define OCF_READ_REMOTE_VERSION 0x001D
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) read_remote_version_cp;
-+#define READ_REMOTE_VERSION_CP_SIZE 2
-+
-+/* Link Policy */
-+#define OGF_LINK_POLICY 0x02
-+#define OCF_ROLE_DISCOVERY 0x0009
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) role_discovery_cp;
-+#define ROLE_DISCOVERY_CP_SIZE 2
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u8 role;
-+} __attribute__ ((packed)) role_discovery_rp;
-+#define ROLE_DISCOVERY_RP_SIZE 4
-+
-+#define OCF_READ_LINK_POLICY 0x000C
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) read_link_policy_cp;
-+#define READ_LINK_POLICY_CP_SIZE 2
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u16 policy;
-+} __attribute__ ((packed)) read_link_policy_rp;
-+#define READ_LINK_POLICY_RP_SIZE 5
-
--/* --------- HCI Events --------- */
-+#define OCF_SWITCH_ROLE 0x000B
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 role;
-+} __attribute__ ((packed)) switch_role_cp;
-+#define SWITCH_ROLE_CP_SIZE 7
-+
-+#define OCF_WRITE_LINK_POLICY 0x000D
-+typedef struct {
-+ __u16 handle;
-+ __u16 policy;
-+} __attribute__ ((packed)) write_link_policy_cp;
-+#define WRITE_LINK_POLICY_CP_SIZE 4
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+} __attribute__ ((packed)) write_link_policy_rp;
-+#define WRITE_LINK_POLICY_RP_SIZE 3
-+
-+/* Status params */
-+#define OGF_STATUS_PARAM 0x05
-+
-+/* Testing commands */
-+#define OGF_TESTING_CMD 0x3e
-+
-+/* Vendor specific commands */
-+#define OGF_VENDOR_CMD 0x3f
-+
-+/* ---- HCI Events ---- */
- #define EVT_INQUIRY_COMPLETE 0x01
-
- #define EVT_INQUIRY_RESULT 0x02
-@@ -272,11 +462,22 @@
- __u8 pscan_rep_mode;
- __u8 pscan_period_mode;
- __u8 pscan_mode;
-- __u8 class[3];
-+ __u8 dev_class[3];
- __u16 clock_offset;
- } __attribute__ ((packed)) inquiry_info;
- #define INQUIRY_INFO_SIZE 14
-
-+#define EVT_INQUIRY_RESULT_WITH_RSSI 0x22
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 pscan_rep_mode;
-+ __u8 pscan_period_mode;
-+ __u8 dev_class[3];
-+ __u16 clock_offset;
-+ __s8 rssi;
-+} __attribute__ ((packed)) inquiry_info_with_rssi;
-+#define INQUIRY_INFO_WITH_RSSI_SIZE 14
-+
- #define EVT_CONN_COMPLETE 0x03
- typedef struct {
- __u8 status;
-@@ -303,6 +504,44 @@
- } __attribute__ ((packed)) evt_disconn_complete;
- #define EVT_DISCONN_COMPLETE_SIZE 4
-
-+#define EVT_AUTH_COMPLETE 0x06
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+} __attribute__ ((packed)) evt_auth_complete;
-+#define EVT_AUTH_COMPLETE_SIZE 3
-+
-+#define EVT_REMOTE_NAME_REQ_COMPLETE 0x07
-+typedef struct {
-+ __u8 status;
-+ bdaddr_t bdaddr;
-+ __u8 name[248];
-+} __attribute__ ((packed)) evt_remote_name_req_complete;
-+#define EVT_REMOTE_NAME_REQ_COMPLETE_SIZE 255
-+
-+#define EVT_ENCRYPT_CHANGE 0x08
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u8 encrypt;
-+} __attribute__ ((packed)) evt_encrypt_change;
-+#define EVT_ENCRYPT_CHANGE_SIZE 5
-+
-+#define EVT_QOS_SETUP_COMPLETE 0x0D
-+typedef struct {
-+ __u8 service_type;
-+ __u32 token_rate;
-+ __u32 peak_bandwidth;
-+ __u32 latency;
-+ __u32 delay_variation;
-+} __attribute__ ((packed)) hci_qos;
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ hci_qos qos;
-+} __attribute__ ((packed)) evt_qos_setup_complete;
-+#define EVT_QOS_SETUP_COMPLETE_SIZE 20
-+
- #define EVT_CMD_COMPLETE 0x0e
- typedef struct {
- __u8 ncmd;
-@@ -321,16 +560,78 @@
- #define EVT_NUM_COMP_PKTS 0x13
- typedef struct {
- __u8 num_hndl;
-- /* variable lenght part */
-+ /* variable length part */
- } __attribute__ ((packed)) evt_num_comp_pkts;
- #define EVT_NUM_COMP_PKTS_SIZE 1
-
--#define EVT_HCI_DEV_EVENT 0xfd
-+#define EVT_ROLE_CHANGE 0x12
-+typedef struct {
-+ __u8 status;
-+ bdaddr_t bdaddr;
-+ __u8 role;
-+} __attribute__ ((packed)) evt_role_change;
-+#define EVT_ROLE_CHANGE_SIZE 8
-+
-+#define EVT_PIN_CODE_REQ 0x16
-+typedef struct {
-+ bdaddr_t bdaddr;
-+} __attribute__ ((packed)) evt_pin_code_req;
-+#define EVT_PIN_CODE_REQ_SIZE 6
-+
-+#define EVT_LINK_KEY_REQ 0x17
-+typedef struct {
-+ bdaddr_t bdaddr;
-+} __attribute__ ((packed)) evt_link_key_req;
-+#define EVT_LINK_KEY_REQ_SIZE 6
-+
-+#define EVT_LINK_KEY_NOTIFY 0x18
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 link_key[16];
-+ __u8 key_type;
-+} __attribute__ ((packed)) evt_link_key_notify;
-+#define EVT_LINK_KEY_NOTIFY_SIZE 23
-+
-+#define EVT_READ_REMOTE_FEATURES_COMPLETE 0x0B
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u8 features[8];
-+} __attribute__ ((packed)) evt_read_remote_features_complete;
-+#define EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE 11
-+
-+#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u8 lmp_ver;
-+ __u16 manufacturer;
-+ __u16 lmp_subver;
-+} __attribute__ ((packed)) evt_read_remote_version_complete;
-+#define EVT_READ_REMOTE_VERSION_COMPLETE_SIZE 8
-+
-+/* Internal events generated by BlueZ stack */
-+#define EVT_STACK_INTERNAL 0xfd
-+typedef struct {
-+ __u16 type;
-+ __u8 data[0];
-+} __attribute__ ((packed)) evt_stack_internal;
-+#define EVT_STACK_INTERNAL_SIZE 2
-+
-+#define EVT_SI_DEVICE 0x01
-+typedef struct {
-+ __u16 event;
-+ __u16 dev_id;
-+} __attribute__ ((packed)) evt_si_device;
-+#define EVT_SI_DEVICE_SIZE 4
-+
-+#define EVT_SI_SECURITY 0x02
- typedef struct {
- __u16 event;
-- __u16 param;
--} __attribute__ ((packed)) evt_hci_dev_event;
--#define EVT_HCI_DEV_EVENT_SIZE 4
-+ __u16 proto;
-+ __u16 subproto;
-+ __u8 incomming;
-+} __attribute__ ((packed)) evt_si_security;
-
- /* -------- HCI Packet structures -------- */
- #define HCI_TYPE_LEN 1
-@@ -369,14 +670,14 @@
- #define acl_handle(h) (h & 0x0fff)
- #define acl_flags(h) (h >> 12)
-
--#endif /* _NO_HCI_DEFS */
--
- /* HCI Socket options */
--#define HCI_DATA_DIR 0x0001
--#define HCI_FILTER 0x0002
-+#define HCI_DATA_DIR 1
-+#define HCI_FILTER 2
-+#define HCI_TIME_STAMP 3
-
- /* HCI CMSG flags */
- #define HCI_CMSG_DIR 0x0001
-+#define HCI_CMSG_TSTAMP 0x0002
-
- struct sockaddr_hci {
- sa_family_t hci_family;
-@@ -387,27 +688,29 @@
- struct hci_filter {
- __u32 type_mask;
- __u32 event_mask[2];
-+ __u16 opcode;
- };
-
--struct hci_dev_req {
-- __u16 dev_id;
-- __u32 dev_opt;
--};
--
--struct hci_dev_list_req {
-- __u16 dev_num;
-- struct hci_dev_req dev_req[0]; /* hci_dev_req structures */
--};
--
--struct hci_inquiry_req {
-- __u16 dev_id;
-- __u16 flags;
-- __u8 lap[3];
-- __u8 length;
-- __u8 num_rsp;
--};
--#define IREQ_CACHE_FLUSH 0x0001
-+#define HCI_FLT_TYPE_BITS 31
-+#define HCI_FLT_EVENT_BITS 63
-+#define HCI_FLT_OGF_BITS 63
-+#define HCI_FLT_OCF_BITS 127
-+
-+#if BITS_PER_LONG == 64
-+static inline void hci_set_bit(int nr, void *addr)
-+{
-+ *((__u32 *) addr + (nr >> 5)) |= ((__u32) 1 << (nr & 31));
-+}
-+static inline int hci_test_bit(int nr, void *addr)
-+{
-+ return *((__u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
-+}
-+#else
-+#define hci_set_bit set_bit
-+#define hci_test_bit test_bit
-+#endif
-
-+/* Ioctl requests structures */
- struct hci_dev_stats {
- __u32 err_rx;
- __u32 err_tx;
-@@ -433,11 +736,13 @@
- __u8 features[8];
-
- __u32 pkt_type;
-+ __u32 link_policy;
-+ __u32 link_mode;
-
- __u16 acl_mtu;
-- __u16 acl_max;
-+ __u16 acl_pkts;
- __u16 sco_mtu;
-- __u16 sco_max;
-+ __u16 sco_pkts;
-
- struct hci_dev_stats stat;
- };
-@@ -445,6 +750,20 @@
- struct hci_conn_info {
- __u16 handle;
- bdaddr_t bdaddr;
-+ __u8 type;
-+ __u8 out;
-+ __u16 state;
-+ __u32 link_mode;
-+};
-+
-+struct hci_dev_req {
-+ __u16 dev_id;
-+ __u32 dev_opt;
-+};
-+
-+struct hci_dev_list_req {
-+ __u16 dev_num;
-+ struct hci_dev_req dev_req[0]; /* hci_dev_req structures */
- };
-
- struct hci_conn_list_req {
-@@ -453,4 +772,26 @@
- struct hci_conn_info conn_info[0];
- };
-
-+struct hci_conn_info_req {
-+ bdaddr_t bdaddr;
-+ __u8 type;
-+ struct hci_conn_info conn_info[0];
-+};
-+
-+struct hci_inquiry_req {
-+ __u16 dev_id;
-+ __u16 flags;
-+ __u8 lap[3];
-+ __u8 length;
-+ __u8 num_rsp;
-+};
-+#define IREQ_CACHE_FLUSH 0x0001
-+
-+struct hci_remotename_req {
-+ __u16 dev_id;
-+ __u16 flags;
-+ bdaddr_t bdaddr;
-+ __u8 name[248];
-+};
-+
- #endif /* __HCI_H */
-diff -urN linux-2.4.18/include/net/bluetooth/hci_uart.h linux-2.4.18-mh15/include/net/bluetooth/hci_uart.h
---- linux-2.4.18/include/net/bluetooth/hci_uart.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/hci_uart.h 1970-01-01 01:00:00.000000000 +0100
-@@ -1,62 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifndef N_HCI
--#define N_HCI 15
--#endif
--
--#ifdef __KERNEL__
--
--#define tty2n_hci(tty) ((struct n_hci *)((tty)->disc_data))
--#define n_hci2tty(n_hci) ((n_hci)->tty)
--
--struct n_hci {
-- struct tty_struct *tty;
-- struct hci_dev hdev;
--
-- struct sk_buff_head txq;
-- unsigned long tx_state;
--
-- spinlock_t rx_lock;
-- unsigned long rx_state;
-- unsigned long rx_count;
-- struct sk_buff *rx_skb;
--};
--
--/* Transmit states */
--#define TRANS_SENDING 1
--#define TRANS_WAKEUP 2
--
--/* Receiver States */
--#define WAIT_PACKET_TYPE 0
--#define WAIT_EVENT_HDR 1
--#define WAIT_ACL_HDR 2
--#define WAIT_SCO_HDR 3
--#define WAIT_DATA 4
--
--#endif /* __KERNEL__ */
-diff -urN linux-2.4.18/include/net/bluetooth/hci_usb.h linux-2.4.18-mh15/include/net/bluetooth/hci_usb.h
---- linux-2.4.18/include/net/bluetooth/hci_usb.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/hci_usb.h 1970-01-01 01:00:00.000000000 +0100
-@@ -1,68 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifdef __KERNEL__
--
--/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
--#define HCI_DEV_CLASS 0xe0 /* Wireless class */
--#define HCI_DEV_SUBCLASS 0x01 /* RF subclass */
--#define HCI_DEV_PROTOCOL 0x01 /* Bluetooth programming protocol */
--
--#define HCI_CTRL_REQ 0x20
--
--struct hci_usb {
-- struct usb_device *udev;
--
-- devrequest dev_req;
-- struct urb *ctrl_urb;
-- struct urb *intr_urb;
-- struct urb *read_urb;
-- struct urb *write_urb;
--
-- __u8 *read_buf;
-- __u8 *intr_buf;
-- struct sk_buff *intr_skb;
-- int intr_count;
--
-- __u8 bulk_out_ep_addr;
-- __u8 bulk_in_ep_addr;
-- __u8 intr_in_ep_addr;
-- __u8 intr_in_interval;
--
-- struct hci_dev hdev;
--
-- unsigned long tx_state;
-- struct sk_buff_head tx_ctrl_q;
-- struct sk_buff_head tx_write_q;
--};
--
--/* Transmit states */
--#define HCI_TX_CTRL 1
--#define HCI_TX_WRITE 2
--
--#endif /* __KERNEL__ */
-diff -urN linux-2.4.18/include/net/bluetooth/hci_vhci.h linux-2.4.18-mh15/include/net/bluetooth/hci_vhci.h
---- linux-2.4.18/include/net/bluetooth/hci_vhci.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/hci_vhci.h 1970-01-01 01:00:00.000000000 +0100
-@@ -1,50 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifndef __HCI_VHCI_H
--#define __HCI_VHCI_H
--
--#ifdef __KERNEL__
--
--struct hci_vhci_struct {
-- struct hci_dev hdev;
-- __u32 flags;
-- wait_queue_head_t read_wait;
-- struct sk_buff_head readq;
-- struct fasync_struct *fasync;
--};
--
--/* VHCI device flags */
--#define VHCI_FASYNC 0x0010
--
--#endif /* __KERNEL__ */
--
--#define VHCI_DEV "/dev/vhci"
--#define VHCI_MINOR 250
--
--#endif /* __HCI_VHCI_H */
-diff -urN linux-2.4.18/include/net/bluetooth/l2cap_core.h linux-2.4.18-mh15/include/net/bluetooth/l2cap_core.h
---- linux-2.4.18/include/net/bluetooth/l2cap_core.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/l2cap_core.h 1970-01-01 01:00:00.000000000 +0100
-@@ -1,144 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifndef __L2CAP_CORE_H
--#define __L2CAP_CORE_H
--
--#ifdef __KERNEL__
--
--/* ----- L2CAP interface ----- */
--struct l2cap_iff {
-- struct list_head list;
-- struct hci_dev *hdev;
-- bdaddr_t *bdaddr;
-- __u16 mtu;
-- spinlock_t lock;
-- struct list_head conn_list;
--};
--
--static inline void l2cap_iff_lock(struct l2cap_iff *iff)
--{
-- spin_lock(&iff->lock);
--}
--
--static inline void l2cap_iff_unlock(struct l2cap_iff *iff)
--{
-- spin_unlock(&iff->lock);
--}
--
--/* ----- L2CAP connections ----- */
--struct l2cap_chan_list {
-- struct sock *head;
-- rwlock_t lock;
-- long num;
--};
--
--struct l2cap_conn {
-- struct l2cap_iff *iff;
-- struct list_head list;
--
-- struct hci_conn *hconn;
--
-- __u16 state;
-- __u8 out;
-- bdaddr_t src;
-- bdaddr_t dst;
--
-- spinlock_t lock;
-- atomic_t refcnt;
--
-- struct sk_buff *rx_skb;
-- __u32 rx_len;
-- __u8 rx_ident;
-- __u8 tx_ident;
--
-- struct l2cap_chan_list chan_list;
--
-- struct timer_list timer;
--};
--
--static inline void __l2cap_conn_link(struct l2cap_iff *iff, struct l2cap_conn *c)
--{
-- list_add(&c->list, &iff->conn_list);
--}
--
--static inline void __l2cap_conn_unlink(struct l2cap_iff *iff, struct l2cap_conn *c)
--{
-- list_del(&c->list);
--}
--
--/* ----- L2CAP channel and socket info ----- */
--#define l2cap_pi(sk) ((struct l2cap_pinfo *) &sk->protinfo)
--
--struct l2cap_accept_q {
-- struct sock *head;
-- struct sock *tail;
--};
--
--struct l2cap_pinfo {
-- bdaddr_t src;
-- bdaddr_t dst;
-- __u16 psm;
-- __u16 dcid;
-- __u16 scid;
-- __u32 flags;
--
-- __u16 imtu;
-- __u16 omtu;
-- __u16 flush_to;
--
-- __u8 conf_state;
-- __u16 conf_mtu;
--
-- __u8 ident;
--
-- struct l2cap_conn *conn;
-- struct sock *next_c;
-- struct sock *prev_c;
--
-- struct sock *parent;
-- struct sock *next_q;
-- struct sock *prev_q;
--
-- struct l2cap_accept_q accept_q;
--};
--
--#define CONF_REQ_SENT 0x01
--#define CONF_INPUT_DONE 0x02
--#define CONF_OUTPUT_DONE 0x04
--
--extern struct bluez_sock_list l2cap_sk_list;
--extern struct list_head l2cap_iff_list;
--extern rwlock_t l2cap_rt_lock;
--
--extern void l2cap_register_proc(void);
--extern void l2cap_unregister_proc(void);
--
--#endif /* __KERNEL__ */
--
--#endif /* __L2CAP_CORE_H */
-diff -urN linux-2.4.18/include/net/bluetooth/l2cap.h linux-2.4.18-mh15/include/net/bluetooth/l2cap.h
---- linux-2.4.18/include/net/bluetooth/l2cap.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/l2cap.h 2004-08-01 16:26:23.000000000 +0200
-@@ -23,22 +23,17 @@
- */
-
- /*
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __L2CAP_H
- #define __L2CAP_H
-
--#include <asm/types.h>
--#include <asm/byteorder.h>
--
- /* L2CAP defaults */
- #define L2CAP_DEFAULT_MTU 672
- #define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
-
- #define L2CAP_CONN_TIMEOUT (HZ * 40)
--#define L2CAP_DISCONN_TIMEOUT (HZ * 2)
--#define L2CAP_CONN_IDLE_TIMEOUT (HZ * 60)
-
- /* L2CAP socket address */
- struct sockaddr_l2 {
-@@ -47,17 +42,12 @@
- bdaddr_t l2_bdaddr;
- };
-
--/* set/get sockopt defines */
--#define L2CAP_OPTIONS 0x01
-+/* Socket options */
-+#define L2CAP_OPTIONS 0x01
- struct l2cap_options {
- __u16 omtu;
- __u16 imtu;
- __u16 flush_to;
-- __u32 token_rate;
-- __u32 bucket_size;
-- __u32 pick_band;
-- __u32 latency;
-- __u32 delay_var;
- };
-
- #define L2CAP_CONNINFO 0x02
-@@ -65,6 +55,27 @@
- __u16 hci_handle;
- };
-
-+#define L2CAP_LM 0x03
-+#define L2CAP_LM_MASTER 0x0001
-+#define L2CAP_LM_AUTH 0x0002
-+#define L2CAP_LM_ENCRYPT 0x0004
-+#define L2CAP_LM_TRUSTED 0x0008
-+#define L2CAP_LM_RELIABLE 0x0010
-+
-+#define L2CAP_QOS 0x04
-+struct l2cap_qos {
-+ __u16 service_type;
-+ __u32 token_rate;
-+ __u32 token_bucket_size;
-+ __u32 peak_bandwidth;
-+ __u32 latency;
-+ __u32 delay_variation;
-+};
-+
-+#define L2CAP_SERV_NO_TRAFFIC 0x00
-+#define L2CAP_SERV_BEST_EFFORT 0x01
-+#define L2CAP_SERV_GUARANTEED 0x02
-+
- /* L2CAP command codes */
- #define L2CAP_COMMAND_REJ 0x01
- #define L2CAP_CONN_REQ 0x02
-@@ -79,7 +90,6 @@
- #define L2CAP_INFO_RSP 0x0b
-
- /* L2CAP structures */
--
- typedef struct {
- __u16 len;
- __u16 cid;
-@@ -112,11 +122,17 @@
- } __attribute__ ((packed)) l2cap_conn_rsp;
- #define L2CAP_CONN_RSP_SIZE 8
-
--#define L2CAP_CONN_SUCCESS 0x0000
--#define L2CAP_CONN_PEND 0x0001
--#define L2CAP_CONN_BAD_PSM 0x0002
--#define L2CAP_CONN_SEC_BLOCK 0x0003
--#define L2CAP_CONN_NO_MEM 0x0004
-+/* connect result */
-+#define L2CAP_CR_SUCCESS 0x0000
-+#define L2CAP_CR_PEND 0x0001
-+#define L2CAP_CR_BAD_PSM 0x0002
-+#define L2CAP_CR_SEC_BLOCK 0x0003
-+#define L2CAP_CR_NO_MEM 0x0004
-+
-+/* connect status */
-+#define L2CAP_CS_NO_INFO 0x0000
-+#define L2CAP_CS_AUTHEN_PEND 0x0001
-+#define L2CAP_CS_AUTHOR_PEND 0x0002
-
- typedef struct {
- __u16 dcid;
-@@ -147,6 +163,8 @@
- #define L2CAP_CONF_FLUSH_TO 0x02
- #define L2CAP_CONF_QOS 0x03
-
-+#define L2CAP_CONF_MAX_SIZE 22
-+
- typedef struct {
- __u16 dcid;
- __u16 scid;
-@@ -159,4 +177,82 @@
- } __attribute__ ((packed)) l2cap_disconn_rsp;
- #define L2CAP_DISCONN_RSP_SIZE 4
-
-+typedef struct {
-+ __u16 type;
-+ __u8 data[0];
-+} __attribute__ ((packed)) l2cap_info_req;
-+#define L2CAP_INFO_REQ_SIZE 2
-+
-+typedef struct {
-+ __u16 type;
-+ __u16 result;
-+ __u8 data[0];
-+} __attribute__ ((packed)) l2cap_info_rsp;
-+#define L2CAP_INFO_RSP_SIZE 4
-+
-+/* info type */
-+#define L2CAP_IT_CL_MTU 0x0001
-+#define L2CAP_IT_FEAT_MASK 0x0002
-+
-+/* info result */
-+#define L2CAP_IR_SUCCESS 0x0000
-+#define L2CAP_IR_NOTSUPP 0x0001
-+
-+/* ----- L2CAP connections ----- */
-+struct l2cap_chan_list {
-+ struct sock *head;
-+ rwlock_t lock;
-+ long num;
-+};
-+
-+struct l2cap_conn {
-+ struct hci_conn *hcon;
-+
-+ bdaddr_t *dst;
-+ bdaddr_t *src;
-+
-+ unsigned int mtu;
-+
-+ spinlock_t lock;
-+
-+ struct sk_buff *rx_skb;
-+ __u32 rx_len;
-+ __u8 rx_ident;
-+ __u8 tx_ident;
-+
-+ struct l2cap_chan_list chan_list;
-+};
-+
-+/* ----- L2CAP channel and socket info ----- */
-+#define l2cap_pi(sk) ((struct l2cap_pinfo *) &sk->tp_pinfo)
-+
-+struct l2cap_pinfo {
-+ __u16 psm;
-+ __u16 dcid;
-+ __u16 scid;
-+
-+ __u16 imtu;
-+ __u16 omtu;
-+ __u16 flush_to;
-+
-+ __u32 link_mode;
-+
-+ __u8 conf_state;
-+ __u8 conf_retry;
-+ __u16 conf_mtu;
-+
-+ __u8 ident;
-+
-+ struct l2cap_conn *conn;
-+ struct sock *next_c;
-+ struct sock *prev_c;
-+};
-+
-+#define L2CAP_CONF_REQ_SENT 0x01
-+#define L2CAP_CONF_INPUT_DONE 0x02
-+#define L2CAP_CONF_OUTPUT_DONE 0x04
-+#define L2CAP_CONF_MAX_RETRIES 2
-+
-+void l2cap_load(void);
-+
- #endif /* __L2CAP_H */
-diff -urN linux-2.4.18/include/net/bluetooth/rfcomm.h linux-2.4.18-mh15/include/net/bluetooth/rfcomm.h
---- linux-2.4.18/include/net/bluetooth/rfcomm.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/include/net/bluetooth/rfcomm.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,361 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ RPN support - Dirk Husemann <hud@zurich.ibm.com>
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef __RFCOMM_H
-+#define __RFCOMM_H
-+
-+#define RFCOMM_PSM 3
-+
-+#define RFCOMM_CONN_TIMEOUT (HZ * 30)
-+#define RFCOMM_DISC_TIMEOUT (HZ * 20)
-+
-+#define RFCOMM_DEFAULT_MTU 127
-+#define RFCOMM_DEFAULT_CREDITS 7
-+
-+#define RFCOMM_MAX_L2CAP_MTU 1024
-+#define RFCOMM_MAX_CREDITS 40
-+
-+#define RFCOMM_SKB_HEAD_RESERVE 8
-+#define RFCOMM_SKB_TAIL_RESERVE 2
-+#define RFCOMM_SKB_RESERVE (RFCOMM_SKB_HEAD_RESERVE + RFCOMM_SKB_TAIL_RESERVE)
-+
-+#define RFCOMM_SABM 0x2f
-+#define RFCOMM_DISC 0x43
-+#define RFCOMM_UA 0x63
-+#define RFCOMM_DM 0x0f
-+#define RFCOMM_UIH 0xef
-+
-+#define RFCOMM_TEST 0x08
-+#define RFCOMM_FCON 0x28
-+#define RFCOMM_FCOFF 0x18
-+#define RFCOMM_MSC 0x38
-+#define RFCOMM_RPN 0x24
-+#define RFCOMM_RLS 0x14
-+#define RFCOMM_PN 0x20
-+#define RFCOMM_NSC 0x04
-+
-+#define RFCOMM_V24_FC 0x02
-+#define RFCOMM_V24_RTC 0x04
-+#define RFCOMM_V24_RTR 0x08
-+#define RFCOMM_V24_IC 0x40
-+#define RFCOMM_V24_DV 0x80
-+
-+#define RFCOMM_RPN_BR_2400 0x0
-+#define RFCOMM_RPN_BR_4800 0x1
-+#define RFCOMM_RPN_BR_7200 0x2
-+#define RFCOMM_RPN_BR_9600 0x3
-+#define RFCOMM_RPN_BR_19200 0x4
-+#define RFCOMM_RPN_BR_38400 0x5
-+#define RFCOMM_RPN_BR_57600 0x6
-+#define RFCOMM_RPN_BR_115200 0x7
-+#define RFCOMM_RPN_BR_230400 0x8
-+
-+#define RFCOMM_RPN_DATA_5 0x0
-+#define RFCOMM_RPN_DATA_6 0x1
-+#define RFCOMM_RPN_DATA_7 0x2
-+#define RFCOMM_RPN_DATA_8 0x3
-+
-+#define RFCOMM_RPN_STOP_1 0
-+#define RFCOMM_RPN_STOP_15 1
-+
-+#define RFCOMM_RPN_PARITY_NONE 0x0
-+#define RFCOMM_RPN_PARITY_ODD 0x4
-+#define RFCOMM_RPN_PARITY_EVEN 0x5
-+#define RFCOMM_RPN_PARITY_MARK 0x6
-+#define RFCOMM_RPN_PARITY_SPACE 0x7
-+
-+#define RFCOMM_RPN_FLOW_NONE 0x00
-+
-+#define RFCOMM_RPN_XON_CHAR 0x11
-+#define RFCOMM_RPN_XOFF_CHAR 0x13
-+
-+#define RFCOMM_RPN_PM_BITRATE 0x0001
-+#define RFCOMM_RPN_PM_DATA 0x0002
-+#define RFCOMM_RPN_PM_STOP 0x0004
-+#define RFCOMM_RPN_PM_PARITY 0x0008
-+#define RFCOMM_RPN_PM_PARITY_TYPE 0x0010
-+#define RFCOMM_RPN_PM_XON 0x0020
-+#define RFCOMM_RPN_PM_XOFF 0x0040
-+#define RFCOMM_RPN_PM_FLOW 0x3F00
-+
-+#define RFCOMM_RPN_PM_ALL 0x3F7F
-+
-+struct rfcomm_hdr {
-+ u8 addr;
-+ u8 ctrl;
-+ u8 len; // Actual size can be 2 bytes
-+} __attribute__ ((packed));
-+
-+struct rfcomm_cmd {
-+ u8 addr;
-+ u8 ctrl;
-+ u8 len;
-+ u8 fcs;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_mcc {
-+ u8 type;
-+ u8 len;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_pn {
-+ u8 dlci;
-+ u8 flow_ctrl;
-+ u8 priority;
-+ u8 ack_timer;
-+ u16 mtu;
-+ u8 max_retrans;
-+ u8 credits;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_rpn {
-+ u8 dlci;
-+ u8 bit_rate;
-+ u8 line_settings;
-+ u8 flow_ctrl;
-+ u8 xon_char;
-+ u8 xoff_char;
-+ u16 param_mask;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_rls {
-+ u8 dlci;
-+ u8 status;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_msc {
-+ u8 dlci;
-+ u8 v24_sig;
-+} __attribute__ ((packed));
-+
-+/* ---- Core structures, flags etc ---- */
-+
-+struct rfcomm_session {
-+ struct list_head list;
-+ struct socket *sock;
-+ unsigned long state;
-+ unsigned long flags;
-+ atomic_t refcnt;
-+ int initiator;
-+
-+ /* Default DLC parameters */
-+ int cfc;
-+ uint mtu;
-+
-+ struct list_head dlcs;
-+};
-+
-+struct rfcomm_dlc {
-+ struct list_head list;
-+ struct rfcomm_session *session;
-+ struct sk_buff_head tx_queue;
-+ struct timer_list timer;
-+
-+ spinlock_t lock;
-+ unsigned long state;
-+ unsigned long flags;
-+ atomic_t refcnt;
-+ u8 dlci;
-+ u8 addr;
-+ u8 priority;
-+ u8 v24_sig;
-+ u8 mscex;
-+
-+ uint mtu;
-+ uint cfc;
-+ uint rx_credits;
-+ uint tx_credits;
-+
-+ void *owner;
-+
-+ void (*data_ready)(struct rfcomm_dlc *d, struct sk_buff *skb);
-+ void (*state_change)(struct rfcomm_dlc *d, int err);
-+ void (*modem_status)(struct rfcomm_dlc *d, u8 v24_sig);
-+};
-+
-+/* DLC and session flags */
-+#define RFCOMM_RX_THROTTLED 0
-+#define RFCOMM_TX_THROTTLED 1
-+#define RFCOMM_MSC_PENDING 2
-+#define RFCOMM_TIMED_OUT 3
-+
-+/* Scheduling flags and events */
-+#define RFCOMM_SCHED_STATE 0
-+#define RFCOMM_SCHED_RX 1
-+#define RFCOMM_SCHED_TX 2
-+#define RFCOMM_SCHED_TIMEO 3
-+#define RFCOMM_SCHED_WAKEUP 31
-+
-+/* MSC exchange flags */
-+#define RFCOMM_MSCEX_TX 1
-+#define RFCOMM_MSCEX_RX 2
-+#define RFCOMM_MSCEX_OK (RFCOMM_MSCEX_TX + RFCOMM_MSCEX_RX)
-+
-+/* CFC states */
-+#define RFCOMM_CFC_UNKNOWN -1
-+#define RFCOMM_CFC_DISABLED 0
-+#define RFCOMM_CFC_ENABLED RFCOMM_MAX_CREDITS
-+
-+extern struct task_struct *rfcomm_thread;
-+extern unsigned long rfcomm_event;
-+
-+static inline void rfcomm_schedule(uint event)
-+{
-+ if (!rfcomm_thread)
-+ return;
-+ set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
-+ wake_up_process(rfcomm_thread);
-+}
-+
-+extern struct semaphore rfcomm_sem;
-+#define rfcomm_lock() down(&rfcomm_sem);
-+#define rfcomm_unlock() up(&rfcomm_sem);
-+
-+/* ---- RFCOMM DLCs (channels) ---- */
-+struct rfcomm_dlc *rfcomm_dlc_alloc(int prio);
-+void rfcomm_dlc_free(struct rfcomm_dlc *d);
-+int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel);
-+int rfcomm_dlc_close(struct rfcomm_dlc *d, int reason);
-+int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb);
-+int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig);
-+int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig);
-+
-+#define rfcomm_dlc_lock(d) spin_lock(&d->lock)
-+#define rfcomm_dlc_unlock(d) spin_unlock(&d->lock)
-+
-+static inline void rfcomm_dlc_hold(struct rfcomm_dlc *d)
-+{
-+ atomic_inc(&d->refcnt);
-+}
-+
-+static inline void rfcomm_dlc_put(struct rfcomm_dlc *d)
-+{
-+ if (atomic_dec_and_test(&d->refcnt))
-+ rfcomm_dlc_free(d);
-+}
-+
-+extern void FASTCALL(__rfcomm_dlc_throttle(struct rfcomm_dlc *d));
-+extern void FASTCALL(__rfcomm_dlc_unthrottle(struct rfcomm_dlc *d));
-+
-+static inline void rfcomm_dlc_throttle(struct rfcomm_dlc *d)
-+{
-+ if (!test_and_set_bit(RFCOMM_RX_THROTTLED, &d->flags))
-+ __rfcomm_dlc_throttle(d);
-+}
-+
-+static inline void rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
-+{
-+ if (test_and_clear_bit(RFCOMM_RX_THROTTLED, &d->flags))
-+ __rfcomm_dlc_unthrottle(d);
-+}
-+
-+/* ---- RFCOMM sessions ---- */
-+struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state);
-+struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
-+struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err);
-+void rfcomm_session_del(struct rfcomm_session *s);
-+void rfcomm_session_close(struct rfcomm_session *s, int err);
-+void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst);
-+
-+static inline void rfcomm_session_hold(struct rfcomm_session *s)
-+{
-+ atomic_inc(&s->refcnt);
-+}
-+
-+static inline void rfcomm_session_put(struct rfcomm_session *s)
-+{
-+ if (atomic_dec_and_test(&s->refcnt))
-+ rfcomm_session_del(s);
-+}
-+
-+/* ---- RFCOMM chechsum ---- */
-+extern u8 rfcomm_crc_table[];
-+
-+/* ---- RFCOMM sockets ---- */
-+struct sockaddr_rc {
-+ sa_family_t rc_family;
-+ bdaddr_t rc_bdaddr;
-+ u8 rc_channel;
-+};
-+
-+#define rfcomm_pi(sk) ((struct rfcomm_pinfo *) &sk->tp_pinfo)
-+
-+struct rfcomm_pinfo {
-+ struct rfcomm_dlc *dlc;
-+ u8 channel;
-+};
-+
-+int rfcomm_init_sockets(void);
-+void rfcomm_cleanup_sockets(void);
-+
-+int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d);
-+
-+/* ---- RFCOMM TTY ---- */
-+#define RFCOMM_MAX_DEV 256
-+
-+#define RFCOMMCREATEDEV _IOW('R', 200, int)
-+#define RFCOMMRELEASEDEV _IOW('R', 201, int)
-+#define RFCOMMGETDEVLIST _IOR('R', 210, int)
-+#define RFCOMMGETDEVINFO _IOR('R', 211, int)
-+#define RFCOMMSTEALDLC _IOW('R', 220, int)
-+
-+#define RFCOMM_REUSE_DLC 0
-+#define RFCOMM_RELEASE_ONHUP 1
-+#define RFCOMM_HANGUP_NOW 2
-+#define RFCOMM_TTY_ATTACHED 3
-+
-+struct rfcomm_dev_req {
-+ s16 dev_id;
-+ u32 flags;
-+ bdaddr_t src;
-+ bdaddr_t dst;
-+ u8 channel;
-+};
-+
-+struct rfcomm_dev_info {
-+ s16 id;
-+ u32 flags;
-+ u16 state;
-+ bdaddr_t src;
-+ bdaddr_t dst;
-+ u8 channel;
-+};
-+
-+struct rfcomm_dev_list_req {
-+ u16 dev_num;
-+ struct rfcomm_dev_info dev_info[0];
-+};
-+
-+int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg);
-+int rfcomm_init_ttys(void);
-+void rfcomm_cleanup_ttys(void);
-+
-+#endif /* __RFCOMM_H */
-diff -urN linux-2.4.18/include/net/bluetooth/sco.h linux-2.4.18-mh15/include/net/bluetooth/sco.h
---- linux-2.4.18/include/net/bluetooth/sco.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/include/net/bluetooth/sco.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,81 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef __SCO_H
-+#define __SCO_H
-+
-+/* SCO defaults */
-+#define SCO_DEFAULT_MTU 500
-+#define SCO_DEFAULT_FLUSH_TO 0xFFFF
-+
-+#define SCO_CONN_TIMEOUT (HZ * 40)
-+#define SCO_DISCONN_TIMEOUT (HZ * 2)
-+#define SCO_CONN_IDLE_TIMEOUT (HZ * 60)
-+
-+/* SCO socket address */
-+struct sockaddr_sco {
-+ sa_family_t sco_family;
-+ bdaddr_t sco_bdaddr;
-+};
-+
-+/* set/get sockopt defines */
-+#define SCO_OPTIONS 0x01
-+struct sco_options {
-+ __u16 mtu;
-+};
-+
-+#define SCO_CONNINFO 0x02
-+struct sco_conninfo {
-+ __u16 hci_handle;
-+};
-+
-+/* ---- SCO connections ---- */
-+struct sco_conn {
-+ struct hci_conn *hcon;
-+
-+ bdaddr_t *dst;
-+ bdaddr_t *src;
-+
-+ spinlock_t lock;
-+ struct sock *sk;
-+
-+ unsigned int mtu;
-+};
-+
-+#define sco_conn_lock(c) spin_lock(&c->lock);
-+#define sco_conn_unlock(c) spin_unlock(&c->lock);
-+
-+/* ----- SCO socket info ----- */
-+#define sco_pi(sk) ((struct sco_pinfo *) &sk->tp_pinfo)
-+
-+struct sco_pinfo {
-+ __u32 flags;
-+ struct sco_conn *conn;
-+};
-+
-+#endif /* __SCO_H */
-diff -urN linux-2.4.18/include/pcmcia/ciscode.h linux-2.4.18-mh15/include/pcmcia/ciscode.h
---- linux-2.4.18/include/pcmcia/ciscode.h 2001-12-21 18:42:04.000000000 +0100
-+++ linux-2.4.18-mh15/include/pcmcia/ciscode.h 2004-08-01 16:26:23.000000000 +0200
-@@ -1,5 +1,5 @@
- /*
-- * ciscode.h 1.48 2001/08/24 12:16:12
-+ * ciscode.h 1.57 2002/11/03 20:38:14
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
-@@ -60,6 +60,10 @@
- #define PRODID_INTEL_DUAL_RS232 0x0301
- #define PRODID_INTEL_2PLUS 0x8422
-
-+#define MANFID_KME 0x0032
-+#define PRODID_KME_KXLC005_A 0x0704
-+#define PRODID_KME_KXLC005_B 0x2904
-+
- #define MANFID_LINKSYS 0x0143
- #define PRODID_LINKSYS_PCMLM28 0xc0ab
- #define PRODID_LINKSYS_3400 0x3341
-@@ -94,6 +98,8 @@
- #define PRODID_OSITECH_JACK_336 0x0007
- #define PRODID_OSITECH_SEVEN 0x0008
-
-+#define MANFID_OXSEMI 0x0279
-+
- #define MANFID_PIONEER 0x000b
-
- #define MANFID_PSION 0x016c
-@@ -103,6 +109,7 @@
- #define PRODID_QUATECH_SPP100 0x0003
- #define PRODID_QUATECH_DUAL_RS232 0x0012
- #define PRODID_QUATECH_DUAL_RS232_D1 0x0007
-+#define PRODID_QUATECH_DUAL_RS232_D2 0x0052
- #define PRODID_QUATECH_QUAD_RS232 0x001b
- #define PRODID_QUATECH_DUAL_RS422 0x000e
- #define PRODID_QUATECH_QUAD_RS422 0x0045
-@@ -120,9 +127,12 @@
-
- #define MANFID_TDK 0x0105
- #define PRODID_TDK_CF010 0x0900
-+#define PRODID_TDK_GN3410 0x4815
-
- #define MANFID_TOSHIBA 0x0098
-
-+#define MANFID_UNGERMANN 0x02c0
-+
- #define MANFID_XIRCOM 0x0105
-
- #endif /* _LINUX_CISCODE_H */
-diff -urN linux-2.4.18/kernel/ksyms.c linux-2.4.18-mh15/kernel/ksyms.c
---- linux-2.4.18/kernel/ksyms.c 2002-02-25 20:38:13.000000000 +0100
-+++ linux-2.4.18-mh15/kernel/ksyms.c 2004-08-01 16:26:23.000000000 +0200
-@@ -47,6 +47,7 @@
- #include <linux/in6.h>
- #include <linux/completion.h>
- #include <linux/seq_file.h>
-+#include <linux/firmware.h>
- #include <asm/checksum.h>
-
- #if defined(CONFIG_PROC_FS)
-@@ -538,6 +539,13 @@
- EXPORT_SYMBOL(strspn);
- EXPORT_SYMBOL(strsep);
-
-+#ifdef CONFIG_FW_LOADER
-+EXPORT_SYMBOL(release_firmware);
-+EXPORT_SYMBOL(request_firmware);
-+EXPORT_SYMBOL(request_firmware_nowait);
-+EXPORT_SYMBOL(register_firmware);
-+#endif
-+
- /* software interrupts */
- EXPORT_SYMBOL(tasklet_hi_vec);
- EXPORT_SYMBOL(tasklet_vec);
-diff -urN linux-2.4.18/lib/Config.in linux-2.4.18-mh15/lib/Config.in
---- linux-2.4.18/lib/Config.in 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/lib/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,12 @@
-+#
-+# Library configuration
-+#
-+mainmenu_option next_comment
-+comment 'Library routines'
-+
-+if [ "$CONFIG_EXPERIMENTAL" = "y" -a \
-+ "$CONFIG_HOTPLUG" = "y" ]; then
-+ tristate 'Hotplug firmware loading support (EXPERIMENTAL)' CONFIG_FW_LOADER
-+fi
-+
-+endmenu
-diff -urN linux-2.4.18/lib/firmware_class.c linux-2.4.18-mh15/lib/firmware_class.c
---- linux-2.4.18/lib/firmware_class.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/lib/firmware_class.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,573 @@
-+/*
-+ * firmware_class.c - Multi purpose firmware loading support
-+ *
-+ * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
-+ *
-+ * Please see Documentation/firmware_class/ for more information.
-+ *
-+ */
-+/*
-+ * Based on kernel/kmod.c and drivers/usb/usb.c
-+ */
-+/*
-+ kernel/kmod.c
-+ Kirk Petersen
-+
-+ Reorganized not to be a daemon by Adam Richter, with guidance
-+ from Greg Zornetzer.
-+
-+ Modified to avoid chroot and file sharing problems.
-+ Mikael Pettersson
-+
-+ Limit the concurrent number of kmod modprobes to catch loops from
-+ "modprobe needs a service that is in a module".
-+ Keith Owens <kaos@ocs.com.au> December 1999
-+
-+ Unblock all signals when we exec a usermode process.
-+ Shuu Yamaguchi <shuu@wondernetworkresources.com> December 2000
-+*/
-+/*
-+ * drivers/usb/usb.c
-+ *
-+ * (C) Copyright Linus Torvalds 1999
-+ * (C) Copyright Johannes Erdfelt 1999-2001
-+ * (C) Copyright Andreas Gal 1999
-+ * (C) Copyright Gregory P. Smith 1999
-+ * (C) Copyright Deti Fliegl 1999 (new USB architecture)
-+ * (C) Copyright Randy Dunlap 2000
-+ * (C) Copyright David Brownell 2000 (kernel hotplug, usb_device_id)
-+ * (C) Copyright Yggdrasil Computing, Inc. 2000
-+ * (usb_device_id matching changes by Adam J. Richter)
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/types.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/kmod.h>
-+#include <linux/proc_fs.h>
-+#include <linux/vmalloc.h>
-+#include <asm/hardirq.h>
-+
-+#include "linux/firmware.h"
-+
-+MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>");
-+MODULE_DESCRIPTION("Multi purpose firmware loading support");
-+MODULE_LICENSE("GPL");
-+
-+#define err(format, arg...) \
-+ printk(KERN_ERR "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
-+#define warn(format, arg...) \
-+ printk(KERN_WARNING "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
-+#define dbg(format, arg...) \
-+ printk(KERN_DEBUG "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
-+
-+static int loading_timeout = 10; /* In seconds */
-+static struct proc_dir_entry *proc_dir_timeout;
-+static struct proc_dir_entry *proc_dir;
-+
-+#ifdef CONFIG_HOTPLUG
-+
-+static int
-+call_helper(char *verb, const char *name, const char *device)
-+{
-+ char *argv[3], **envp, *buf, *scratch;
-+ int i = 0;
-+
-+ int retval = 0;
-+
-+ if (!hotplug_path[0])
-+ return -ENOENT;
-+ if (in_interrupt()) {
-+ err("in_interrupt");
-+ return -EFAULT;
-+ }
-+ if (!current->fs->root) {
-+ warn("call_policy %s -- no FS yet", verb);
-+ return -EPERM;
-+ }
-+
-+ if (!(envp = (char **) kmalloc(20 * sizeof (char *), GFP_KERNEL))) {
-+ err("unable to allocate envp");
-+ return -ENOMEM;
-+ }
-+ if (!(buf = kmalloc(256, GFP_KERNEL))) {
-+ kfree(envp);
-+ err("unable to allocate buf");
-+ return -ENOMEM;
-+ }
-+
-+ /* only one standardized param to hotplug command: type */
-+ argv[0] = hotplug_path;
-+ argv[1] = "firmware";
-+ argv[2] = 0;
-+
-+ /* minimal command environment */
-+ envp[i++] = "HOME=/";
-+ envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-+
-+#ifdef DEBUG
-+ /* hint that policy agent should enter no-stdout debug mode */
-+ envp[i++] = "DEBUG=kernel";
-+#endif
-+ scratch = buf;
-+
-+ if (device) {
-+ envp[i++] = scratch;
-+ scratch += snprintf(scratch, FIRMWARE_NAME_MAX+25,
-+ "DEVPATH=/driver/firmware/%s", device) + 1;
-+ }
-+
-+ envp[i++] = scratch;
-+ scratch += sprintf(scratch, "ACTION=%s", verb) + 1;
-+
-+ envp[i++] = scratch;
-+ scratch += snprintf(scratch, FIRMWARE_NAME_MAX,
-+ "FIRMWARE=%s", name) + 1;
-+
-+ envp[i++] = 0;
-+
-+#ifdef DEBUG
-+ dbg("firmware: %s %s %s", argv[0], argv[1], verb);
-+#endif
-+
-+ retval = call_usermodehelper(argv[0], argv, envp);
-+ if (retval) {
-+ printk("call_usermodehelper return %d\n", retval);
-+ }
-+
-+ kfree(buf);
-+ kfree(envp);
-+ return retval;
-+}
-+#else
-+
-+static inline int
-+call_helper(char *verb, const char *name, const char *device)
-+{
-+ return -ENOENT;
-+}
-+
-+#endif /* CONFIG_HOTPLUG */
-+
-+struct firmware_priv {
-+ struct completion completion;
-+ struct proc_dir_entry *proc_dir;
-+ struct proc_dir_entry *attr_data;
-+ struct proc_dir_entry *attr_loading;
-+ struct firmware *fw;
-+ int loading;
-+ int abort;
-+ int alloc_size;
-+ struct timer_list timeout;
-+};
-+
-+static int
-+firmware_timeout_show(char *buf, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ return sprintf(buf, "%d\n", loading_timeout);
-+}
-+
-+/**
-+ * firmware_timeout_store:
-+ * Description:
-+ * Sets the number of seconds to wait for the firmware. Once
-+ * this expires an error will be return to the driver and no
-+ * firmware will be provided.
-+ *
-+ * Note: zero means 'wait for ever'
-+ *
-+ **/
-+static int
-+firmware_timeout_store(struct file *file, const char *buf,
-+ unsigned long count, void *data)
-+{
-+ loading_timeout = simple_strtol(buf, NULL, 10);
-+ return count;
-+}
-+
-+static int
-+firmware_loading_show(char *buf, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ struct firmware_priv *fw_priv = data;
-+ return sprintf(buf, "%d\n", fw_priv->loading);
-+}
-+
-+/**
-+ * firmware_loading_store: - loading control file
-+ * Description:
-+ * The relevant values are:
-+ *
-+ * 1: Start a load, discarding any previous partial load.
-+ * 0: Conclude the load and handle the data to the driver code.
-+ * -1: Conclude the load with an error and discard any written data.
-+ **/
-+static int
-+firmware_loading_store(struct file *file, const char *buf,
-+ unsigned long count, void *data)
-+{
-+ struct firmware_priv *fw_priv = data;
-+ int prev_loading = fw_priv->loading;
-+
-+ fw_priv->loading = simple_strtol(buf, NULL, 10);
-+
-+ switch (fw_priv->loading) {
-+ case -1:
-+ fw_priv->abort = 1;
-+ wmb();
-+ complete(&fw_priv->completion);
-+ break;
-+ case 1:
-+ kfree(fw_priv->fw->data);
-+ fw_priv->fw->data = NULL;
-+ fw_priv->fw->size = 0;
-+ fw_priv->alloc_size = 0;
-+ break;
-+ case 0:
-+ if (prev_loading == 1)
-+ complete(&fw_priv->completion);
-+ break;
-+ }
-+
-+ return count;
-+}
-+
-+static int
-+firmware_data_read(char *buffer, char **start, off_t offset,
-+ int count, int *eof, void *data)
-+{
-+ struct firmware_priv *fw_priv = data;
-+ struct firmware *fw = fw_priv->fw;
-+
-+ if (offset > fw->size)
-+ return 0;
-+ if (offset + count > fw->size)
-+ count = fw->size - offset;
-+
-+ memcpy(buffer, fw->data + offset, count);
-+ *start = (void *) ((long) count);
-+ return count;
-+}
-+static int
-+fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
-+{
-+ u8 *new_data;
-+ int new_size;
-+
-+ if (min_size <= fw_priv->alloc_size)
-+ return 0;
-+ if((min_size % PAGE_SIZE) == 0)
-+ new_size = min_size;
-+ else
-+ new_size = (min_size + PAGE_SIZE) & PAGE_MASK;
-+ new_data = vmalloc(new_size);
-+ if (!new_data) {
-+ printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__);
-+ /* Make sure that we don't keep incomplete data */
-+ fw_priv->abort = 1;
-+ return -ENOMEM;
-+ }
-+ fw_priv->alloc_size = new_size;
-+ if (fw_priv->fw->data) {
-+ memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size);
-+ vfree(fw_priv->fw->data);
-+ }
-+ fw_priv->fw->data = new_data;
-+ BUG_ON(min_size > fw_priv->alloc_size);
-+ return 0;
-+}
-+
-+/**
-+ * firmware_data_write:
-+ *
-+ * Description:
-+ *
-+ * Data written to the 'data' attribute will be later handled to
-+ * the driver as a firmware image.
-+ **/
-+static int
-+firmware_data_write(struct file *file, const char *buffer,
-+ unsigned long count, void *data)
-+{
-+ struct firmware_priv *fw_priv = data;
-+ struct firmware *fw = fw_priv->fw;
-+ int offset = file->f_pos;
-+ int retval;
-+
-+ retval = fw_realloc_buffer(fw_priv, offset + count);
-+ if (retval) {
-+ printk("%s: retval:%d\n", __FUNCTION__, retval);
-+ return retval;
-+ }
-+
-+ memcpy(fw->data + offset, buffer, count);
-+
-+ fw->size = max_t(size_t, offset + count, fw->size);
-+ file->f_pos += count;
-+ return count;
-+}
-+
-+static void
-+firmware_class_timeout(u_long data)
-+{
-+ struct firmware_priv *fw_priv = (struct firmware_priv *) data;
-+ fw_priv->abort = 1;
-+ wmb();
-+ complete(&fw_priv->completion);
-+}
-+static int
-+fw_setup_class_device(struct firmware_priv **fw_priv_p,
-+ const char *fw_name, const char *device)
-+{
-+ int retval;
-+ struct firmware_priv *fw_priv = kmalloc(sizeof (struct firmware_priv),
-+ GFP_KERNEL);
-+ *fw_priv_p = fw_priv;
-+ if (!fw_priv) {
-+ retval = -ENOMEM;
-+ goto out;
-+ }
-+ memset(fw_priv, 0, sizeof (*fw_priv));
-+
-+ init_completion(&fw_priv->completion);
-+
-+ fw_priv->timeout.function = firmware_class_timeout;
-+ fw_priv->timeout.data = (u_long) fw_priv;
-+ init_timer(&fw_priv->timeout);
-+
-+ retval = -EAGAIN;
-+ fw_priv->proc_dir = create_proc_entry(device, 0644 | S_IFDIR, proc_dir);
-+ if (!fw_priv->proc_dir)
-+ goto err_free_fw_priv;
-+
-+ fw_priv->attr_data = create_proc_entry("data", 0644 | S_IFREG,
-+ fw_priv->proc_dir);
-+ if (!fw_priv->attr_data)
-+ goto err_remove_dir;
-+
-+ fw_priv->attr_data->read_proc = firmware_data_read;
-+ fw_priv->attr_data->write_proc = firmware_data_write;
-+ fw_priv->attr_data->data = fw_priv;
-+
-+ fw_priv->attr_loading = create_proc_entry("loading", 0644 | S_IFREG,
-+ fw_priv->proc_dir);
-+ if (!fw_priv->attr_loading)
-+ goto err_remove_data;
-+
-+ fw_priv->attr_loading->read_proc = firmware_loading_show;
-+ fw_priv->attr_loading->write_proc = firmware_loading_store;
-+ fw_priv->attr_loading->data = fw_priv;
-+
-+ retval = 0;
-+ fw_priv->fw = kmalloc(sizeof (struct firmware), GFP_KERNEL);
-+ if (!fw_priv->fw) {
-+ printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n",
-+ __FUNCTION__);
-+ retval = -ENOMEM;
-+ goto err_remove_loading;
-+ }
-+ memset(fw_priv->fw, 0, sizeof (*fw_priv->fw));
-+
-+ goto out;
-+
-+err_remove_loading:
-+ remove_proc_entry("loading", fw_priv->proc_dir);
-+err_remove_data:
-+ remove_proc_entry("data", fw_priv->proc_dir);
-+err_remove_dir:
-+ remove_proc_entry(device, proc_dir);
-+err_free_fw_priv:
-+ kfree(fw_priv);
-+out:
-+ return retval;
-+}
-+static void
-+fw_remove_class_device(struct firmware_priv *fw_priv)
-+{
-+ remove_proc_entry("loading", fw_priv->proc_dir);
-+ remove_proc_entry("data", fw_priv->proc_dir);
-+ remove_proc_entry(fw_priv->proc_dir->name, proc_dir);
-+}
-+
-+/**
-+ * request_firmware: - request firmware to hotplug and wait for it
-+ * Description:
-+ * @firmware will be used to return a firmware image by the name
-+ * of @name for device @device.
-+ *
-+ * Should be called from user context where sleeping is allowed.
-+ *
-+ * @name will be use as $FIRMWARE in the hotplug environment and
-+ * should be distinctive enough not to be confused with any other
-+ * firmware image for this or any other device.
-+ **/
-+int
-+request_firmware(const struct firmware **firmware, const char *name,
-+ const char *device)
-+{
-+ struct firmware_priv *fw_priv;
-+ int retval;
-+
-+ if (!firmware) {
-+ retval = -EINVAL;
-+ goto out;
-+ }
-+ *firmware = NULL;
-+
-+ retval = fw_setup_class_device(&fw_priv, name, device);
-+ if (retval)
-+ goto out;
-+
-+ retval = call_helper("add", name, device);
-+ if (retval)
-+ goto out;
-+ if (loading_timeout) {
-+ fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
-+ add_timer(&fw_priv->timeout);
-+ }
-+
-+ wait_for_completion(&fw_priv->completion);
-+
-+ del_timer(&fw_priv->timeout);
-+ fw_remove_class_device(fw_priv);
-+
-+ if (fw_priv->fw->size && !fw_priv->abort) {
-+ *firmware = fw_priv->fw;
-+ } else {
-+ retval = -ENOENT;
-+ vfree(fw_priv->fw->data);
-+ kfree(fw_priv->fw);
-+ }
-+out:
-+ kfree(fw_priv);
-+ return retval;
-+}
-+
-+void
-+release_firmware(const struct firmware *fw)
-+{
-+ if (fw) {
-+ vfree(fw->data);
-+ kfree(fw);
-+ }
-+}
-+
-+/**
-+ * register_firmware: - provide a firmware image for later usage
-+ *
-+ * Description:
-+ * Make sure that @data will be available by requesting firmware @name.
-+ *
-+ * Note: This will not be possible until some kind of persistence
-+ * is available.
-+ **/
-+void
-+register_firmware(const char *name, const u8 *data, size_t size)
-+{
-+ /* This is meaningless without firmware caching, so until we
-+ * decide if firmware caching is reasonable just leave it as a
-+ * noop */
-+}
-+
-+/* Async support */
-+struct firmware_work {
-+ struct tq_struct work;
-+ struct module *module;
-+ const char *name;
-+ const char *device;
-+ void *context;
-+ void (*cont)(const struct firmware *fw, void *context);
-+};
-+
-+static void
-+request_firmware_work_func(void *arg)
-+{
-+ struct firmware_work *fw_work = arg;
-+ const struct firmware *fw;
-+ if (!arg)
-+ return;
-+ request_firmware(&fw, fw_work->name, fw_work->device);
-+ fw_work->cont(fw, fw_work->context);
-+ release_firmware(fw);
-+ __MOD_DEC_USE_COUNT(fw_work->module);
-+ kfree(fw_work);
-+}
-+
-+/**
-+ * request_firmware_nowait:
-+ *
-+ * Description:
-+ * Asynchronous variant of request_firmware() for contexts where
-+ * it is not possible to sleep.
-+ *
-+ * @cont will be called asynchronously when the firmware request is over.
-+ *
-+ * @context will be passed over to @cont.
-+ *
-+ * @fw may be %NULL if firmware request fails.
-+ *
-+ **/
-+int
-+request_firmware_nowait(
-+ struct module *module,
-+ const char *name, const char *device, void *context,
-+ void (*cont)(const struct firmware *fw, void *context))
-+{
-+ struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
-+ GFP_ATOMIC);
-+ if (!fw_work)
-+ return -ENOMEM;
-+ if (!try_inc_mod_count(module)) {
-+ kfree(fw_work);
-+ return -EFAULT;
-+ }
-+
-+ *fw_work = (struct firmware_work) {
-+ .module = module,
-+ .name = name,
-+ .device = device,
-+ .context = context,
-+ .cont = cont,
-+ };
-+ INIT_TQUEUE(&fw_work->work, request_firmware_work_func, fw_work);
-+
-+ schedule_task(&fw_work->work);
-+ return 0;
-+}
-+
-+static int __init
-+firmware_class_init(void)
-+{
-+ proc_dir = create_proc_entry("driver/firmware", 0755 | S_IFDIR, NULL);
-+ if (!proc_dir)
-+ return -EAGAIN;
-+ proc_dir_timeout = create_proc_entry("timeout",
-+ 0644 | S_IFREG, proc_dir);
-+ if (!proc_dir_timeout) {
-+ remove_proc_entry("driver/firmware", NULL);
-+ return -EAGAIN;
-+ }
-+ proc_dir_timeout->read_proc = firmware_timeout_show;
-+ proc_dir_timeout->write_proc = firmware_timeout_store;
-+ return 0;
-+}
-+static void __exit
-+firmware_class_exit(void)
-+{
-+ remove_proc_entry("timeout", proc_dir);
-+ remove_proc_entry("driver/firmware", NULL);
-+}
-+
-+module_init(firmware_class_init);
-+module_exit(firmware_class_exit);
-+
-+#ifndef CONFIG_FW_LOADER
-+EXPORT_SYMBOL(release_firmware);
-+EXPORT_SYMBOL(request_firmware);
-+EXPORT_SYMBOL(request_firmware_nowait);
-+EXPORT_SYMBOL(register_firmware);
-+#endif
-diff -urN linux-2.4.18/lib/Makefile linux-2.4.18-mh15/lib/Makefile
---- linux-2.4.18/lib/Makefile 2001-09-18 00:31:15.000000000 +0200
-+++ linux-2.4.18-mh15/lib/Makefile 2004-08-01 16:26:23.000000000 +0200
-@@ -8,13 +8,17 @@
-
- L_TARGET := lib.a
-
--export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o
-+export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o \
-+ firmware_class.o
-
- obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o bust_spinlocks.o rbtree.o
-
-+obj-$(CONFIG_FW_LOADER) += firmware_class.o
- obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
- obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
-
-+include $(TOPDIR)/drivers/bluetooth/Makefile.lib
-+
- ifneq ($(CONFIG_HAVE_DEC_LOCK),y)
- obj-y += dec_and_lock.o
- endif
-diff -urN linux-2.4.18/MAINTAINERS linux-2.4.18-mh15/MAINTAINERS
---- linux-2.4.18/MAINTAINERS 2002-02-25 20:37:52.000000000 +0100
-+++ linux-2.4.18-mh15/MAINTAINERS 2004-08-01 16:26:23.000000000 +0200
-@@ -252,10 +252,88 @@
- L: linux-kernel@vger.kernel.org
- S: Maintained
-
--BLUETOOTH SUBSYSTEM (BlueZ)
-+BLUETOOTH SUBSYSTEM
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
- P: Maxim Krasnyansky
- M: maxk@qualcomm.com
-+L: bluez-devel@lists.sf.net
- W: http://bluez.sf.net
-+W: http://www.bluez.org
-+W: http://www.holtmann.org/linux/bluetooth/
-+S: Maintained
-+
-+BLUETOOTH RFCOMM LAYER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+S: Maintained
-+
-+BLUETOOTH BNEP LAYER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+S: Maintained
-+
-+BLUETOOTH CMTP LAYER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+S: Maintained
-+
-+BLUETOOTH HIDP LAYER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+S: Maintained
-+
-+BLUETOOTH HCI UART DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+S: Maintained
-+
-+BLUETOOTH HCI USB DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+S: Maintained
-+
-+BLUETOOTH HCI BCM203X DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+S: Maintained
-+
-+BLUETOOTH HCI BFUSB DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+S: Maintained
-+
-+BLUETOOTH HCI DTL1 DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+S: Maintained
-+
-+BLUETOOTH HCI BLUECARD DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+S: Maintained
-+
-+BLUETOOTH HCI BT3C DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+S: Maintained
-+
-+BLUETOOTH HCI BTUART DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+S: Maintained
-+
-+BLUETOOTH HCI VHCI DRIVER
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
- S: Maintained
-
- BTTV VIDEO4LINUX DRIVER
-diff -urN linux-2.4.18/net/bluetooth/af_bluetooth.c linux-2.4.18-mh15/net/bluetooth/af_bluetooth.c
---- linux-2.4.18/net/bluetooth/af_bluetooth.c 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/net/bluetooth/af_bluetooth.c 2004-08-01 16:26:23.000000000 +0200
-@@ -25,14 +25,15 @@
- /*
- * BlueZ Bluetooth address family and sockets.
- *
-- * $Id$
-+ * $Id$
- */
--#define VERSION "1.1"
-+#define VERSION "2.4"
-
- #include <linux/config.h>
- #include <linux/module.h>
-
- #include <linux/types.h>
-+#include <linux/list.h>
- #include <linux/errno.h>
- #include <linux/kernel.h>
- #include <linux/major.h>
-@@ -40,6 +41,7 @@
- #include <linux/slab.h>
- #include <linux/skbuff.h>
- #include <linux/init.h>
-+#include <linux/poll.h>
- #include <linux/proc_fs.h>
- #include <net/sock.h>
-
-@@ -48,70 +50,79 @@
- #endif
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
-+
-+#ifndef AF_BLUETOOTH_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-
- /* Bluetooth sockets */
--static struct net_proto_family *bluez_sock[BLUEZ_MAX_PROTO];
-+#define BLUEZ_MAX_PROTO 7
-+static struct net_proto_family *bluez_proto[BLUEZ_MAX_PROTO];
-
- int bluez_sock_register(int proto, struct net_proto_family *ops)
- {
-- if (proto > BLUEZ_MAX_PROTO)
-+ if (proto >= BLUEZ_MAX_PROTO)
- return -EINVAL;
-
-- if (bluez_sock[proto])
-+ if (bluez_proto[proto])
- return -EEXIST;
-
-- bluez_sock[proto] = ops;
-+ bluez_proto[proto] = ops;
- return 0;
- }
-
- int bluez_sock_unregister(int proto)
- {
-- if (proto > BLUEZ_MAX_PROTO)
-+ if (proto >= BLUEZ_MAX_PROTO)
- return -EINVAL;
-
-- if (!bluez_sock[proto])
-+ if (!bluez_proto[proto])
- return -ENOENT;
-
-- bluez_sock[proto] = NULL;
-+ bluez_proto[proto] = NULL;
- return 0;
- }
-
- static int bluez_sock_create(struct socket *sock, int proto)
- {
-- if (proto > BLUEZ_MAX_PROTO)
-+ if (proto >= BLUEZ_MAX_PROTO)
- return -EINVAL;
-
- #if defined(CONFIG_KMOD)
-- if (!bluez_sock[proto]) {
-+ if (!bluez_proto[proto]) {
- char module_name[30];
- sprintf(module_name, "bt-proto-%d", proto);
- request_module(module_name);
- }
- #endif
-
-- if (!bluez_sock[proto])
-+ if (!bluez_proto[proto])
- return -ENOENT;
-
-- return bluez_sock[proto]->create(sock, proto);
-+ return bluez_proto[proto]->create(sock, proto);
-+}
-+
-+void bluez_sock_init(struct socket *sock, struct sock *sk)
-+{
-+ sock_init_data(sock, sk);
-+ INIT_LIST_HEAD(&bluez_pi(sk)->accept_q);
- }
-
- void bluez_sock_link(struct bluez_sock_list *l, struct sock *sk)
- {
-- write_lock(&l->lock);
--
-+ write_lock_bh(&l->lock);
- sk->next = l->head;
- l->head = sk;
- sock_hold(sk);
--
-- write_unlock(&l->lock);
-+ write_unlock_bh(&l->lock);
- }
-
- void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *sk)
- {
- struct sock **skp;
-
-- write_lock(&l->lock);
-+ write_lock_bh(&l->lock);
- for (skp = &l->head; *skp; skp = &((*skp)->next)) {
- if (*skp == sk) {
- *skp = sk->next;
-@@ -119,7 +130,163 @@
- break;
- }
- }
-- write_unlock(&l->lock);
-+ write_unlock_bh(&l->lock);
-+}
-+
-+void bluez_accept_enqueue(struct sock *parent, struct sock *sk)
-+{
-+ BT_DBG("parent %p, sk %p", parent, sk);
-+
-+ sock_hold(sk);
-+ list_add_tail(&bluez_pi(sk)->accept_q, &bluez_pi(parent)->accept_q);
-+ bluez_pi(sk)->parent = parent;
-+ parent->ack_backlog++;
-+}
-+
-+static void bluez_accept_unlink(struct sock *sk)
-+{
-+ BT_DBG("sk %p state %d", sk, sk->state);
-+
-+ list_del_init(&bluez_pi(sk)->accept_q);
-+ bluez_pi(sk)->parent->ack_backlog--;
-+ bluez_pi(sk)->parent = NULL;
-+ sock_put(sk);
-+}
-+
-+struct sock *bluez_accept_dequeue(struct sock *parent, struct socket *newsock)
-+{
-+ struct list_head *p, *n;
-+ struct bluez_pinfo *pi;
-+ struct sock *sk;
-+
-+ BT_DBG("parent %p", parent);
-+
-+ list_for_each_safe(p, n, &bluez_pi(parent)->accept_q) {
-+ pi = list_entry(p, struct bluez_pinfo, accept_q);
-+ sk = bluez_sk(pi);
-+
-+ lock_sock(sk);
-+ if (sk->state == BT_CLOSED) {
-+ release_sock(sk);
-+ bluez_accept_unlink(sk);
-+ continue;
-+ }
-+
-+ if (sk->state == BT_CONNECTED || !newsock) {
-+ bluez_accept_unlink(sk);
-+ if (newsock)
-+ sock_graft(sk, newsock);
-+ release_sock(sk);
-+ return sk;
-+ }
-+ release_sock(sk);
-+ }
-+ return NULL;
-+}
-+
-+int bluez_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
-+{
-+ int noblock = flags & MSG_DONTWAIT;
-+ struct sock *sk = sock->sk;
-+ struct sk_buff *skb;
-+ int copied, err;
-+
-+ BT_DBG("sock %p sk %p len %d", sock, sk, len);
-+
-+ if (flags & (MSG_OOB))
-+ return -EOPNOTSUPP;
-+
-+ if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) {
-+ if (sk->shutdown & RCV_SHUTDOWN)
-+ return 0;
-+ return err;
-+ }
-+
-+ msg->msg_namelen = 0;
-+
-+ copied = skb->len;
-+ if (len < copied) {
-+ msg->msg_flags |= MSG_TRUNC;
-+ copied = len;
-+ }
-+
-+ skb->h.raw = skb->data;
-+ err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
-+
-+ skb_free_datagram(sk, skb);
-+
-+ return err ? : copied;
-+}
-+
-+unsigned int bluez_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
-+{
-+ struct sock *sk = sock->sk;
-+ unsigned int mask = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ poll_wait(file, sk->sleep, wait);
-+
-+ if (sk->err || !skb_queue_empty(&sk->error_queue))
-+ mask |= POLLERR;
-+
-+ if (sk->shutdown == SHUTDOWN_MASK)
-+ mask |= POLLHUP;
-+
-+ if (!skb_queue_empty(&sk->receive_queue) ||
-+ !list_empty(&bluez_pi(sk)->accept_q) ||
-+ (sk->shutdown & RCV_SHUTDOWN))
-+ mask |= POLLIN | POLLRDNORM;
-+
-+ if (sk->state == BT_CLOSED)
-+ mask |= POLLHUP;
-+
-+ if (sk->state == BT_CONNECT ||
-+ sk->state == BT_CONNECT2 ||
-+ sk->state == BT_CONFIG)
-+ return mask;
-+
-+ if (sock_writeable(sk))
-+ mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
-+ else
-+ set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
-+
-+ return mask;
-+}
-+
-+int bluez_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ int err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ add_wait_queue(sk->sleep, &wait);
-+ while (sk->state != state) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+
-+ if (sk->err) {
-+ err = sock_error(sk);
-+ break;
-+ }
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+ return err;
- }
-
- struct net_proto_family bluez_sock_family_ops =
-@@ -129,9 +296,9 @@
-
- int bluez_init(void)
- {
-- INF("BlueZ HCI Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-+ BT_INFO("BlueZ Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-
- proc_mkdir("bluetooth", NULL);
-
-@@ -164,5 +331,6 @@
- module_exit(bluez_cleanup);
-
- MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
--MODULE_DESCRIPTION("BlueZ HCI Core ver " VERSION);
-+MODULE_DESCRIPTION("BlueZ Core ver " VERSION);
-+MODULE_LICENSE("GPL");
- #endif
-diff -urN linux-2.4.18/net/bluetooth/bnep/bnep.h linux-2.4.18-mh15/net/bluetooth/bnep/bnep.h
---- linux-2.4.18/net/bluetooth/bnep/bnep.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/bnep/bnep.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,185 @@
-+/*
-+ BNEP protocol definition for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License, version 2, as
-+ published by the Free Software Foundation.
-+
-+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef _BNEP_H
-+#define _BNEP_H
-+
-+#include <linux/types.h>
-+#include <net/bluetooth/bluetooth.h>
-+
-+#include "crc32.h"
-+
-+// Limits
-+#define BNEP_MAX_PROTO_FILTERS 5
-+#define BNEP_MAX_MULTICAST_FILTERS 20
-+
-+// UUIDs
-+#define BNEP_BASE_UUID 0x0000000000001000800000805F9B34FB
-+#define BNEP_UUID16 0x02
-+#define BNEP_UUID32 0x04
-+#define BNEP_UUID128 0x16
-+
-+#define BNEP_SVC_PANU 0x1115
-+#define BNEP_SVC_NAP 0x1116
-+#define BNEP_SVC_GN 0x1117
-+
-+// Packet types
-+#define BNEP_GENERAL 0x00
-+#define BNEP_CONTROL 0x01
-+#define BNEP_COMPRESSED 0x02
-+#define BNEP_COMPRESSED_SRC_ONLY 0x03
-+#define BNEP_COMPRESSED_DST_ONLY 0x04
-+
-+// Control types
-+#define BNEP_CMD_NOT_UNDERSTOOD 0x00
-+#define BNEP_SETUP_CONN_REQ 0x01
-+#define BNEP_SETUP_CONN_RSP 0x02
-+#define BNEP_FILTER_NET_TYPE_SET 0x03
-+#define BNEP_FILTER_NET_TYPE_RSP 0x04
-+#define BNEP_FILTER_MULTI_ADDR_SET 0x05
-+#define BNEP_FILTER_MULTI_ADDR_RSP 0x06
-+
-+// Extension types
-+#define BNEP_EXT_CONTROL 0x00
-+
-+// Response messages
-+#define BNEP_SUCCESS 0x00
-+
-+#define BNEP_CONN_INVALID_DST 0x01
-+#define BNEP_CONN_INVALID_SRC 0x02
-+#define BNEP_CONN_INVALID_SVC 0x03
-+#define BNEP_CONN_NOT_ALLOWED 0x04
-+
-+#define BNEP_FILTER_UNSUPPORTED_REQ 0x01
-+#define BNEP_FILTER_INVALID_RANGE 0x02
-+#define BNEP_FILTER_INVALID_MCADDR 0x02
-+#define BNEP_FILTER_LIMIT_REACHED 0x03
-+#define BNEP_FILTER_DENIED_SECURITY 0x04
-+
-+// L2CAP settings
-+#define BNEP_MTU 1691
-+#define BNEP_PSM 0x0f
-+#define BNEP_FLUSH_TO 0xffff
-+#define BNEP_CONNECT_TO 15
-+#define BNEP_FILTER_TO 15
-+
-+// Headers
-+#define BNEP_TYPE_MASK 0x7f
-+#define BNEP_EXT_HEADER 0x80
-+
-+struct bnep_setup_conn_req {
-+ __u8 type;
-+ __u8 ctrl;
-+ __u8 uuid_size;
-+ __u8 service[0];
-+} __attribute__((packed));
-+
-+struct bnep_set_filter_req {
-+ __u8 type;
-+ __u8 ctrl;
-+ __u16 len;
-+ __u8 list[0];
-+} __attribute__((packed));
-+
-+struct bnep_control_rsp {
-+ __u8 type;
-+ __u8 ctrl;
-+ __u16 resp;
-+} __attribute__((packed));
-+
-+struct bnep_ext_hdr {
-+ __u8 type;
-+ __u8 len;
-+ __u8 data[0];
-+} __attribute__((packed));
-+
-+/* BNEP ioctl defines */
-+#define BNEPCONNADD _IOW('B', 200, int)
-+#define BNEPCONNDEL _IOW('B', 201, int)
-+#define BNEPGETCONNLIST _IOR('B', 210, int)
-+#define BNEPGETCONNINFO _IOR('B', 211, int)
-+
-+struct bnep_connadd_req {
-+ int sock; // Connected socket
-+ __u32 flags;
-+ __u16 role;
-+ char device[16]; // Name of the Ethernet device
-+};
-+
-+struct bnep_conndel_req {
-+ __u32 flags;
-+ __u8 dst[ETH_ALEN];
-+};
-+
-+struct bnep_conninfo {
-+ __u32 flags;
-+ __u16 role;
-+ __u16 state;
-+ __u8 dst[ETH_ALEN];
-+ char device[16];
-+};
-+
-+struct bnep_connlist_req {
-+ __u32 cnum;
-+ struct bnep_conninfo *ci;
-+};
-+
-+struct bnep_proto_filter {
-+ __u16 start;
-+ __u16 end;
-+};
-+
-+int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock);
-+int bnep_del_connection(struct bnep_conndel_req *req);
-+int bnep_get_connlist(struct bnep_connlist_req *req);
-+int bnep_get_conninfo(struct bnep_conninfo *ci);
-+
-+// BNEP sessions
-+struct bnep_session {
-+ struct list_head list;
-+
-+ unsigned int role;
-+ unsigned long state;
-+ unsigned long flags;
-+ atomic_t killed;
-+
-+ struct ethhdr eh;
-+ struct msghdr msg;
-+
-+ struct bnep_proto_filter proto_filter[BNEP_MAX_PROTO_FILTERS];
-+ u64 mc_filter;
-+
-+ struct socket *sock;
-+ struct net_device dev;
-+ struct net_device_stats stats;
-+};
-+
-+int bnep_net_init(struct net_device *dev);
-+int bnep_sock_init(void);
-+int bnep_sock_cleanup(void);
-+
-+static inline int bnep_mc_hash(__u8 *addr)
-+{
-+ return (bnep_crc32(~0, addr, ETH_ALEN) >> 26);
-+}
-+
-+#endif
-diff -urN linux-2.4.18/net/bluetooth/bnep/Config.in linux-2.4.18-mh15/net/bluetooth/bnep/Config.in
---- linux-2.4.18/net/bluetooth/bnep/Config.in 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/bnep/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,11 @@
-+#
-+# Bluetooth BNEP layer configuration
-+#
-+
-+dep_tristate 'BNEP protocol support' CONFIG_BLUEZ_BNEP $CONFIG_BLUEZ_L2CAP
-+
-+if [ "$CONFIG_BLUEZ_BNEP" != "n" ]; then
-+ bool ' Multicast filter support' CONFIG_BLUEZ_BNEP_MC_FILTER
-+ bool ' Protocol filter support' CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+fi
-+
-diff -urN linux-2.4.18/net/bluetooth/bnep/core.c linux-2.4.18-mh15/net/bluetooth/bnep/core.c
---- linux-2.4.18/net/bluetooth/bnep/core.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/bnep/core.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,718 @@
-+/*
-+ BNEP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2001-2002 Inventel Systemes
-+ Written 2001-2002 by
-+ Clément Moreau <clement.moreau@inventel.fr>
-+ David Libault <david.libault@inventel.fr>
-+
-+ Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#define __KERNEL_SYSCALLS__
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/signal.h>
-+#include <linux/init.h>
-+#include <linux/wait.h>
-+#include <linux/errno.h>
-+#include <linux/smp_lock.h>
-+#include <linux/net.h>
-+#include <net/sock.h>
-+
-+#include <linux/socket.h>
-+#include <linux/file.h>
-+
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#include "bnep.h"
-+
-+#ifndef CONFIG_BLUEZ_BNEP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define VERSION "1.2"
-+
-+static LIST_HEAD(bnep_session_list);
-+static DECLARE_RWSEM(bnep_session_sem);
-+
-+static struct bnep_session *__bnep_get_session(u8 *dst)
-+{
-+ struct bnep_session *s;
-+ struct list_head *p;
-+
-+ BT_DBG("");
-+
-+ list_for_each(p, &bnep_session_list) {
-+ s = list_entry(p, struct bnep_session, list);
-+ if (!memcmp(dst, s->eh.h_source, ETH_ALEN))
-+ return s;
-+ }
-+ return NULL;
-+}
-+
-+static void __bnep_link_session(struct bnep_session *s)
-+{
-+ MOD_INC_USE_COUNT;
-+ list_add(&s->list, &bnep_session_list);
-+}
-+
-+static void __bnep_unlink_session(struct bnep_session *s)
-+{
-+ list_del(&s->list);
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static int bnep_send(struct bnep_session *s, void *data, size_t len)
-+{
-+ struct socket *sock = s->sock;
-+ struct iovec iv = { data, len };
-+ s->msg.msg_iov = &iv;
-+ s->msg.msg_iovlen = 1;
-+ return sock->ops->sendmsg(sock, &s->msg, len, NULL);
-+}
-+
-+static int bnep_send_rsp(struct bnep_session *s, u8 ctrl, u16 resp)
-+{
-+ struct bnep_control_rsp rsp;
-+ rsp.type = BNEP_CONTROL;
-+ rsp.ctrl = ctrl;
-+ rsp.resp = htons(resp);
-+ return bnep_send(s, &rsp, sizeof(rsp));
-+}
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+static inline void bnep_set_default_proto_filter(struct bnep_session *s)
-+{
-+ /* (IPv4, ARP) */
-+ s->proto_filter[0].start = htons(0x0800);
-+ s->proto_filter[0].end = htons(0x0806);
-+ /* (RARP, AppleTalk) */
-+ s->proto_filter[1].start = htons(0x8035);
-+ s->proto_filter[1].end = htons(0x80F3);
-+ /* (IPX, IPv6) */
-+ s->proto_filter[2].start = htons(0x8137);
-+ s->proto_filter[2].end = htons(0x86DD);
-+}
-+#endif
-+
-+static int bnep_ctrl_set_netfilter(struct bnep_session *s, u16 *data, int len)
-+{
-+ int n;
-+
-+ if (len < 2)
-+ return -EILSEQ;
-+
-+ n = ntohs(get_unaligned(data));
-+ data++; len -= 2;
-+
-+ if (len < n)
-+ return -EILSEQ;
-+
-+ BT_DBG("filter len %d", n);
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+ n /= 4;
-+ if (n <= BNEP_MAX_PROTO_FILTERS) {
-+ struct bnep_proto_filter *f = s->proto_filter;
-+ int i;
-+
-+ for (i = 0; i < n; i++) {
-+ f[i].start = get_unaligned(data++);
-+ f[i].end = get_unaligned(data++);
-+
-+ BT_DBG("proto filter start %d end %d",
-+ f[i].start, f[i].end);
-+ }
-+
-+ if (i < BNEP_MAX_PROTO_FILTERS)
-+ memset(f + i, 0, sizeof(*f));
-+
-+ if (n == 0)
-+ bnep_set_default_proto_filter(s);
-+
-+ bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_SUCCESS);
-+ } else {
-+ bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_LIMIT_REACHED);
-+ }
-+#else
-+ bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
-+#endif
-+ return 0;
-+}
-+
-+static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
-+{
-+ int n;
-+
-+ if (len < 2)
-+ return -EILSEQ;
-+
-+ n = ntohs(get_unaligned((u16 *) data));
-+ data += 2; len -= 2;
-+
-+ if (len < n)
-+ return -EILSEQ;
-+
-+ BT_DBG("filter len %d", n);
-+
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+ n /= (ETH_ALEN * 2);
-+
-+ if (n > 0) {
-+ s->mc_filter = 0;
-+
-+ /* Always send broadcast */
-+ set_bit(bnep_mc_hash(s->dev.broadcast), &s->mc_filter);
-+
-+ /* Add address ranges to the multicast hash */
-+ for (; n > 0; n--) {
-+ u8 a1[6], *a2;
-+
-+ memcpy(a1, data, ETH_ALEN); data += ETH_ALEN;
-+ a2 = data; data += ETH_ALEN;
-+
-+ BT_DBG("mc filter %s -> %s",
-+ batostr((void *) a1), batostr((void *) a2));
-+
-+ #define INCA(a) { int i = 5; while (i >=0 && ++a[i--] == 0); }
-+
-+ /* Iterate from a1 to a2 */
-+ set_bit(bnep_mc_hash(a1), &s->mc_filter);
-+ while (memcmp(a1, a2, 6) < 0 && s->mc_filter != ~0LL) {
-+ INCA(a1);
-+ set_bit(bnep_mc_hash(a1), &s->mc_filter);
-+ }
-+ }
-+ }
-+
-+ BT_DBG("mc filter hash 0x%llx", s->mc_filter);
-+
-+ bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_SUCCESS);
-+#else
-+ bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
-+#endif
-+ return 0;
-+}
-+
-+static int bnep_rx_control(struct bnep_session *s, void *data, int len)
-+{
-+ u8 cmd = *(u8 *)data;
-+ int err = 0;
-+
-+ data++; len--;
-+
-+ switch (cmd) {
-+ case BNEP_CMD_NOT_UNDERSTOOD:
-+ case BNEP_SETUP_CONN_REQ:
-+ case BNEP_SETUP_CONN_RSP:
-+ case BNEP_FILTER_NET_TYPE_RSP:
-+ case BNEP_FILTER_MULTI_ADDR_RSP:
-+ /* Ignore these for now */
-+ break;
-+
-+ case BNEP_FILTER_NET_TYPE_SET:
-+ err = bnep_ctrl_set_netfilter(s, data, len);
-+ break;
-+
-+ case BNEP_FILTER_MULTI_ADDR_SET:
-+ err = bnep_ctrl_set_mcfilter(s, data, len);
-+ break;
-+
-+ default: {
-+ u8 pkt[3];
-+ pkt[0] = BNEP_CONTROL;
-+ pkt[1] = BNEP_CMD_NOT_UNDERSTOOD;
-+ pkt[2] = cmd;
-+ bnep_send(s, pkt, sizeof(pkt));
-+ }
-+ break;
-+ }
-+
-+ return err;
-+}
-+
-+static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb)
-+{
-+ struct bnep_ext_hdr *h;
-+ int err = 0;
-+
-+ do {
-+ h = (void *) skb->data;
-+ if (!skb_pull(skb, sizeof(*h))) {
-+ err = -EILSEQ;
-+ break;
-+ }
-+
-+ BT_DBG("type 0x%x len %d", h->type, h->len);
-+
-+ switch (h->type & BNEP_TYPE_MASK) {
-+ case BNEP_EXT_CONTROL:
-+ bnep_rx_control(s, skb->data, skb->len);
-+ break;
-+
-+ default:
-+ /* Unknown extension, skip it. */
-+ break;
-+ }
-+
-+ if (!skb_pull(skb, h->len)) {
-+ err = -EILSEQ;
-+ break;
-+ }
-+ } while (!err && (h->type & BNEP_EXT_HEADER));
-+
-+ return err;
-+}
-+
-+static u8 __bnep_rx_hlen[] = {
-+ ETH_HLEN, /* BNEP_GENERAL */
-+ 0, /* BNEP_CONTROL */
-+ 2, /* BNEP_COMPRESSED */
-+ ETH_ALEN + 2, /* BNEP_COMPRESSED_SRC_ONLY */
-+ ETH_ALEN + 2 /* BNEP_COMPRESSED_DST_ONLY */
-+};
-+#define BNEP_RX_TYPES (sizeof(__bnep_rx_hlen) - 1)
-+
-+static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
-+{
-+ struct net_device *dev = &s->dev;
-+ struct sk_buff *nskb;
-+ u8 type;
-+
-+ dev->last_rx = jiffies;
-+ s->stats.rx_bytes += skb->len;
-+
-+ type = *(u8 *) skb->data; skb_pull(skb, 1);
-+
-+ if ((type & BNEP_TYPE_MASK) > BNEP_RX_TYPES)
-+ goto badframe;
-+
-+ if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) {
-+ bnep_rx_control(s, skb->data, skb->len);
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+
-+ skb->mac.raw = skb->data;
-+
-+ /* Verify and pull out header */
-+ if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK]))
-+ goto badframe;
-+
-+ s->eh.h_proto = get_unaligned((u16 *) (skb->data - 2));
-+
-+ if (type & BNEP_EXT_HEADER) {
-+ if (bnep_rx_extension(s, skb) < 0)
-+ goto badframe;
-+ }
-+
-+ /* Strip 802.1p header */
-+ if (ntohs(s->eh.h_proto) == 0x8100) {
-+ if (!skb_pull(skb, 4))
-+ goto badframe;
-+ s->eh.h_proto = get_unaligned((u16 *) (skb->data - 2));
-+ }
-+
-+ /* We have to alloc new skb and copy data here :(. Because original skb
-+ * may not be modified and because of the alignment requirements. */
-+ nskb = alloc_skb(2 + ETH_HLEN + skb->len, GFP_KERNEL);
-+ if (!nskb) {
-+ s->stats.rx_dropped++;
-+ kfree_skb(skb);
-+ return -ENOMEM;
-+ }
-+ skb_reserve(nskb, 2);
-+
-+ /* Decompress header and construct ether frame */
-+ switch (type & BNEP_TYPE_MASK) {
-+ case BNEP_COMPRESSED:
-+ memcpy(__skb_put(nskb, ETH_HLEN), &s->eh, ETH_HLEN);
-+ break;
-+
-+ case BNEP_COMPRESSED_SRC_ONLY:
-+ memcpy(__skb_put(nskb, ETH_ALEN), s->eh.h_dest, ETH_ALEN);
-+ memcpy(__skb_put(nskb, ETH_ALEN), skb->mac.raw, ETH_ALEN);
-+ put_unaligned(s->eh.h_proto, (u16 *) __skb_put(nskb, 2));
-+ break;
-+
-+ case BNEP_COMPRESSED_DST_ONLY:
-+ memcpy(__skb_put(nskb, ETH_ALEN), skb->mac.raw, ETH_ALEN);
-+ memcpy(__skb_put(nskb, ETH_ALEN + 2), s->eh.h_source, ETH_ALEN + 2);
-+ break;
-+
-+ case BNEP_GENERAL:
-+ memcpy(__skb_put(nskb, ETH_ALEN * 2), skb->mac.raw, ETH_ALEN * 2);
-+ put_unaligned(s->eh.h_proto, (u16 *) __skb_put(nskb, 2));
-+ break;
-+ }
-+
-+ memcpy(__skb_put(nskb, skb->len), skb->data, skb->len);
-+ kfree_skb(skb);
-+
-+ s->stats.rx_packets++;
-+ nskb->dev = dev;
-+ nskb->ip_summed = CHECKSUM_UNNECESSARY;
-+ nskb->protocol = eth_type_trans(nskb, dev);
-+ netif_rx_ni(nskb);
-+ return 0;
-+
-+badframe:
-+ s->stats.rx_errors++;
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+static u8 __bnep_tx_types[] = {
-+ BNEP_GENERAL,
-+ BNEP_COMPRESSED_SRC_ONLY,
-+ BNEP_COMPRESSED_DST_ONLY,
-+ BNEP_COMPRESSED
-+};
-+
-+static inline int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb)
-+{
-+ struct ethhdr *eh = (void *) skb->data;
-+ struct socket *sock = s->sock;
-+ struct iovec iv[3];
-+ int len = 0, il = 0;
-+ u8 type = 0;
-+
-+ BT_DBG("skb %p dev %p type %d", skb, skb->dev, skb->pkt_type);
-+
-+ if (!skb->dev) {
-+ /* Control frame sent by us */
-+ goto send;
-+ }
-+
-+ iv[il++] = (struct iovec) { &type, 1 };
-+ len++;
-+
-+ if (!memcmp(eh->h_dest, s->eh.h_source, ETH_ALEN))
-+ type |= 0x01;
-+
-+ if (!memcmp(eh->h_source, s->eh.h_dest, ETH_ALEN))
-+ type |= 0x02;
-+
-+ if (type)
-+ skb_pull(skb, ETH_ALEN * 2);
-+
-+ type = __bnep_tx_types[type];
-+ switch (type) {
-+ case BNEP_COMPRESSED_SRC_ONLY:
-+ iv[il++] = (struct iovec) { eh->h_source, ETH_ALEN };
-+ len += ETH_ALEN;
-+ break;
-+
-+ case BNEP_COMPRESSED_DST_ONLY:
-+ iv[il++] = (struct iovec) { eh->h_dest, ETH_ALEN };
-+ len += ETH_ALEN;
-+ break;
-+ }
-+
-+send:
-+ iv[il++] = (struct iovec) { skb->data, skb->len };
-+ len += skb->len;
-+
-+ /* FIXME: linearize skb */
-+
-+ s->msg.msg_iov = iv;
-+ s->msg.msg_iovlen = il;
-+ len = sock->ops->sendmsg(sock, &s->msg, len, NULL);
-+ kfree_skb(skb);
-+
-+ if (len > 0) {
-+ s->stats.tx_bytes += len;
-+ s->stats.tx_packets++;
-+ return 0;
-+ }
-+
-+ return len;
-+}
-+
-+static int bnep_session(void *arg)
-+{
-+ struct bnep_session *s = arg;
-+ struct net_device *dev = &s->dev;
-+ struct sock *sk = s->sock->sk;
-+ struct sk_buff *skb;
-+ wait_queue_t wait;
-+
-+ BT_DBG("");
-+
-+ daemonize(); reparent_to_init();
-+
-+ sprintf(current->comm, "kbnepd %s", dev->name);
-+
-+ sigfillset(&current->blocked);
-+ flush_signals(current);
-+
-+ current->nice = -15;
-+
-+ set_fs(KERNEL_DS);
-+
-+ init_waitqueue_entry(&wait, current);
-+ add_wait_queue(sk->sleep, &wait);
-+ while (!atomic_read(&s->killed)) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ // RX
-+ while ((skb = skb_dequeue(&sk->receive_queue))) {
-+ skb_orphan(skb);
-+ bnep_rx_frame(s, skb);
-+ }
-+
-+ if (sk->state != BT_CONNECTED)
-+ break;
-+
-+ // TX
-+ while ((skb = skb_dequeue(&sk->write_queue)))
-+ if (bnep_tx_frame(s, skb))
-+ break;
-+ netif_wake_queue(dev);
-+
-+ schedule();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ /* Cleanup session */
-+ down_write(&bnep_session_sem);
-+
-+ /* Delete network device */
-+ unregister_netdev(dev);
-+
-+ /* Release the socket */
-+ fput(s->sock->file);
-+
-+ __bnep_unlink_session(s);
-+
-+ up_write(&bnep_session_sem);
-+ kfree(s);
-+ return 0;
-+}
-+
-+int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
-+{
-+ struct net_device *dev;
-+ struct bnep_session *s, *ss;
-+ u8 dst[ETH_ALEN], src[ETH_ALEN];
-+ int err;
-+
-+ BT_DBG("");
-+
-+ baswap((void *) dst, &bluez_pi(sock->sk)->dst);
-+ baswap((void *) src, &bluez_pi(sock->sk)->src);
-+
-+ s = kmalloc(sizeof(struct bnep_session), GFP_KERNEL);
-+ if (!s)
-+ return -ENOMEM;
-+ memset(s, 0, sizeof(struct bnep_session));
-+
-+ down_write(&bnep_session_sem);
-+
-+ ss = __bnep_get_session(dst);
-+ if (ss && ss->state == BT_CONNECTED) {
-+ err = -EEXIST;
-+ goto failed;
-+ }
-+
-+ dev = &s->dev;
-+
-+ if (*req->device)
-+ strcpy(dev->name, req->device);
-+ else
-+ strcpy(dev->name, "bnep%d");
-+
-+ memset(dev->broadcast, 0xff, ETH_ALEN);
-+
-+ /* This is rx header therefor addresses are swaped.
-+ * ie eh.h_dest is our local address. */
-+ memcpy(s->eh.h_dest, &src, ETH_ALEN);
-+ memcpy(s->eh.h_source, &dst, ETH_ALEN);
-+
-+ s->sock = sock;
-+ s->role = req->role;
-+ s->state = BT_CONNECTED;
-+
-+ s->msg.msg_flags = MSG_NOSIGNAL;
-+
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+ /* Set default mc filter */
-+ set_bit(bnep_mc_hash(dev->broadcast), &s->mc_filter);
-+#endif
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+ /* Set default protocol filter */
-+ bnep_set_default_proto_filter(s);
-+#endif
-+
-+ dev->init = bnep_net_init;
-+ dev->priv = s;
-+ err = register_netdev(dev);
-+ if (err) {
-+ goto failed;
-+ }
-+
-+ __bnep_link_session(s);
-+
-+ err = kernel_thread(bnep_session, s, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-+ if (err < 0) {
-+ /* Session thread start failed, gotta cleanup. */
-+ unregister_netdev(dev);
-+ __bnep_unlink_session(s);
-+ goto failed;
-+ }
-+
-+ up_write(&bnep_session_sem);
-+ strcpy(req->device, dev->name);
-+ return 0;
-+
-+failed:
-+ up_write(&bnep_session_sem);
-+ kfree(s);
-+ return err;
-+}
-+
-+int bnep_del_connection(struct bnep_conndel_req *req)
-+{
-+ struct bnep_session *s;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ down_read(&bnep_session_sem);
-+
-+ s = __bnep_get_session(req->dst);
-+ if (s) {
-+ /* Wakeup user-space which is polling for socket errors.
-+ * This is temporary hack untill we have shutdown in L2CAP */
-+ s->sock->sk->err = EUNATCH;
-+
-+ /* Kill session thread */
-+ atomic_inc(&s->killed);
-+ wake_up_interruptible(s->sock->sk->sleep);
-+ } else
-+ err = -ENOENT;
-+
-+ up_read(&bnep_session_sem);
-+ return err;
-+}
-+
-+static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s)
-+{
-+ memcpy(ci->dst, s->eh.h_source, ETH_ALEN);
-+ strcpy(ci->device, s->dev.name);
-+ ci->flags = s->flags;
-+ ci->state = s->state;
-+ ci->role = s->role;
-+}
-+
-+int bnep_get_connlist(struct bnep_connlist_req *req)
-+{
-+ struct list_head *p;
-+ int err = 0, n = 0;
-+
-+ down_read(&bnep_session_sem);
-+
-+ list_for_each(p, &bnep_session_list) {
-+ struct bnep_session *s;
-+ struct bnep_conninfo ci;
-+
-+ s = list_entry(p, struct bnep_session, list);
-+
-+ __bnep_copy_ci(&ci, s);
-+
-+ if (copy_to_user(req->ci, &ci, sizeof(ci))) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ if (++n >= req->cnum)
-+ break;
-+
-+ req->ci++;
-+ }
-+ req->cnum = n;
-+
-+ up_read(&bnep_session_sem);
-+ return err;
-+}
-+
-+int bnep_get_conninfo(struct bnep_conninfo *ci)
-+{
-+ struct bnep_session *s;
-+ int err = 0;
-+
-+ down_read(&bnep_session_sem);
-+
-+ s = __bnep_get_session(ci->dst);
-+ if (s)
-+ __bnep_copy_ci(ci, s);
-+ else
-+ err = -ENOENT;
-+
-+ up_read(&bnep_session_sem);
-+ return err;
-+}
-+
-+static int __init bnep_init_module(void)
-+{
-+ l2cap_load();
-+
-+ bnep_crc32_init();
-+ bnep_sock_init();
-+
-+ BT_INFO("BlueZ BNEP ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2001,2002 Inventel Systemes");
-+ BT_INFO("Written 2001,2002 by Clement Moreau <clement.moreau@inventel.fr>");
-+ BT_INFO("Written 2001,2002 by David Libault <david.libault@inventel.fr>");
-+ BT_INFO("Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>");
-+
-+ return 0;
-+}
-+
-+static void __exit bnep_cleanup_module(void)
-+{
-+ bnep_sock_cleanup();
-+ bnep_crc32_cleanup();
-+}
-+
-+module_init(bnep_init_module);
-+module_exit(bnep_cleanup_module);
-+
-+MODULE_DESCRIPTION("BlueZ BNEP ver " VERSION);
-+MODULE_AUTHOR("David Libault <david.libault@inventel.fr>, Maxim Krasnyanskiy <maxk@qualcomm.com>");
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/bnep/crc32.c linux-2.4.18-mh15/net/bluetooth/bnep/crc32.c
---- linux-2.4.18/net/bluetooth/bnep/crc32.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/bnep/crc32.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,59 @@
-+/*
-+ * Based on linux-2.5/lib/crc32 by Matt Domsch <Matt_Domsch@dell.com>
-+ *
-+ * FIXME: Remove in 2.5
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <asm/atomic.h>
-+
-+#include "crc32.h"
-+
-+#define CRCPOLY_BE 0x04c11db7
-+#define CRC_BE_BITS 8
-+
-+static u32 *bnep_crc32_table;
-+
-+/*
-+ * This code is in the public domain; copyright abandoned.
-+ * Liability for non-performance of this code is limited to the amount
-+ * you paid for it. Since it is distributed for free, your refund will
-+ * be very very small. If it breaks, you get to keep both pieces.
-+ */
-+u32 bnep_crc32(u32 crc, unsigned char const *p, size_t len)
-+{
-+ while (len--)
-+ crc = (crc << 8) ^ bnep_crc32_table[(crc >> 24) ^ *p++];
-+
-+ return crc;
-+}
-+
-+int __init bnep_crc32_init(void)
-+{
-+ unsigned i, j;
-+ u32 crc = 0x80000000;
-+
-+ bnep_crc32_table = kmalloc((1 << CRC_BE_BITS) * sizeof(u32), GFP_KERNEL);
-+ if (!bnep_crc32_table)
-+ return -ENOMEM;
-+
-+ bnep_crc32_table[0] = 0;
-+
-+ for (i = 1; i < 1 << CRC_BE_BITS; i <<= 1) {
-+ crc = (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE : 0);
-+ for (j = 0; j < i; j++)
-+ bnep_crc32_table[i + j] = crc ^ bnep_crc32_table[j];
-+ }
-+ return 0;
-+}
-+
-+void __exit bnep_crc32_cleanup(void)
-+{
-+ if (bnep_crc32_table)
-+ kfree(bnep_crc32_table);
-+ bnep_crc32_table = NULL;
-+}
-diff -urN linux-2.4.18/net/bluetooth/bnep/crc32.h linux-2.4.18-mh15/net/bluetooth/bnep/crc32.h
---- linux-2.4.18/net/bluetooth/bnep/crc32.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/bnep/crc32.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,10 @@
-+/*
-+ * crc32.h
-+ * See crc32.c for license and changes
-+ *
-+ * FIXME: Remove in 2.5
-+ */
-+
-+int bnep_crc32_init(void);
-+void bnep_crc32_cleanup(void);
-+u32 bnep_crc32(u32 crc, unsigned char const *p, size_t len);
-diff -urN linux-2.4.18/net/bluetooth/bnep/Makefile linux-2.4.18-mh15/net/bluetooth/bnep/Makefile
---- linux-2.4.18/net/bluetooth/bnep/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/bnep/Makefile 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the Linux Bluetooth BNEP layer
-+#
-+
-+O_TARGET := bnep.o
-+
-+obj-y := core.o sock.o netdev.o crc32.o
-+obj-m += $(O_TARGET)
-+
-+include $(TOPDIR)/Rules.make
-diff -urN linux-2.4.18/net/bluetooth/bnep/netdev.c linux-2.4.18-mh15/net/bluetooth/bnep/netdev.c
---- linux-2.4.18/net/bluetooth/bnep/netdev.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/bnep/netdev.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,254 @@
-+/*
-+ BNEP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2001-2002 Inventel Systemes
-+ Written 2001-2002 by
-+ Clément Moreau <clement.moreau@inventel.fr>
-+ David Libault <david.libault@inventel.fr>
-+
-+ Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/socket.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/wait.h>
-+
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#include "bnep.h"
-+
-+#ifndef CONFIG_BLUEZ_BNEP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+#define BNEP_TX_QUEUE_LEN 20
-+
-+static int bnep_net_open(struct net_device *dev)
-+{
-+ netif_start_queue(dev);
-+ return 0;
-+}
-+
-+static int bnep_net_close(struct net_device *dev)
-+{
-+ netif_stop_queue(dev);
-+ return 0;
-+}
-+
-+static struct net_device_stats *bnep_net_get_stats(struct net_device *dev)
-+{
-+ struct bnep_session *s = dev->priv;
-+ return &s->stats;
-+}
-+
-+static void bnep_net_set_mc_list(struct net_device *dev)
-+{
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+ struct bnep_session *s = dev->priv;
-+ struct sock *sk = s->sock->sk;
-+ struct bnep_set_filter_req *r;
-+ struct sk_buff *skb;
-+ int size;
-+
-+ BT_DBG("%s mc_count %d", dev->name, dev->mc_count);
-+
-+ size = sizeof(*r) + (BNEP_MAX_MULTICAST_FILTERS + 1) * ETH_ALEN * 2;
-+ skb = alloc_skb(size, GFP_ATOMIC);
-+ if (!skb) {
-+ BT_ERR("%s Multicast list allocation failed", dev->name);
-+ return;
-+ }
-+
-+ r = (void *) skb->data;
-+ __skb_put(skb, sizeof(*r));
-+
-+ r->type = BNEP_CONTROL;
-+ r->ctrl = BNEP_FILTER_MULTI_ADDR_SET;
-+
-+ if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
-+ u8 start[ETH_ALEN] = { 0x01 };
-+
-+ /* Request all addresses */
-+ memcpy(__skb_put(skb, ETH_ALEN), start, ETH_ALEN);
-+ memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
-+ r->len = htons(ETH_ALEN * 2);
-+ } else {
-+ struct dev_mc_list *dmi = dev->mc_list;
-+ int i, len = skb->len;
-+
-+ if (dev->flags & IFF_BROADCAST) {
-+ memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
-+ memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
-+ }
-+
-+ /* FIXME: We should group addresses here. */
-+
-+ for (i = 0; i < dev->mc_count && i < BNEP_MAX_MULTICAST_FILTERS; i++) {
-+ memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN);
-+ memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN);
-+ dmi = dmi->next;
-+ }
-+ r->len = htons(skb->len - len);
-+ }
-+
-+ skb_queue_tail(&sk->write_queue, skb);
-+ wake_up_interruptible(sk->sleep);
-+#endif
-+}
-+
-+static int bnep_net_set_mac_addr(struct net_device *dev, void *arg)
-+{
-+ BT_DBG("%s", dev->name);
-+ return 0;
-+}
-+
-+static void bnep_net_timeout(struct net_device *dev)
-+{
-+ BT_DBG("net_timeout");
-+ netif_wake_queue(dev);
-+}
-+
-+static int bnep_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-+{
-+ return -EINVAL;
-+}
-+
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+static inline int bnep_net_mc_filter(struct sk_buff *skb, struct bnep_session *s)
-+{
-+ struct ethhdr *eh = (void *) skb->data;
-+
-+ if ((eh->h_dest[0] & 1) && !test_bit(bnep_mc_hash(eh->h_dest), &s->mc_filter)) {
-+ BT_DBG("BNEP: filtered skb %p, dst %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", skb,
-+ eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
-+ eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]);
-+ return 1;
-+ }
-+ return 0;
-+}
-+#endif
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+/* Determine ether protocol. Based on eth_type_trans. */
-+static inline u16 bnep_net_eth_proto(struct sk_buff *skb)
-+{
-+ struct ethhdr *eh = (void *) skb->data;
-+
-+ if (ntohs(eh->h_proto) >= 1536)
-+ return eh->h_proto;
-+
-+ if (get_unaligned((u16 *) skb->data) == 0xFFFF)
-+ return htons(ETH_P_802_3);
-+
-+ return htons(ETH_P_802_2);
-+}
-+
-+static inline int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session *s)
-+{
-+ u16 proto = bnep_net_eth_proto(skb);
-+ struct bnep_proto_filter *f = s->proto_filter;
-+ int i;
-+
-+ for (i = 0; i < BNEP_MAX_PROTO_FILTERS && f[i].end; i++) {
-+ if (proto >= f[i].start && proto <= f[i].end)
-+ return 0;
-+ }
-+
-+ BT_DBG("BNEP: filtered skb %p, proto 0x%.4x", skb, proto);
-+ return 1;
-+}
-+#endif
-+
-+static int bnep_net_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+ struct bnep_session *s = dev->priv;
-+ struct sock *sk = s->sock->sk;
-+
-+ BT_DBG("skb %p, dev %p", skb, dev);
-+
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+ if (bnep_net_mc_filter(skb, s)) {
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+#endif
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+ if (bnep_net_proto_filter(skb, s)) {
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+#endif
-+
-+ /*
-+ * We cannot send L2CAP packets from here as we are potentially in a bh.
-+ * So we have to queue them and wake up session thread which is sleeping
-+ * on the sk->sleep.
-+ */
-+ dev->trans_start = jiffies;
-+ skb_queue_tail(&sk->write_queue, skb);
-+ wake_up_interruptible(sk->sleep);
-+
-+ if (skb_queue_len(&sk->write_queue) >= BNEP_TX_QUEUE_LEN) {
-+ BT_DBG("tx queue is full");
-+
-+ /* Stop queuing.
-+ * Session thread will do netif_wake_queue() */
-+ netif_stop_queue(dev);
-+ }
-+
-+ return 0;
-+}
-+
-+int bnep_net_init(struct net_device *dev)
-+{
-+ struct bnep_session *s = dev->priv;
-+
-+ memcpy(dev->dev_addr, s->eh.h_dest, ETH_ALEN);
-+ dev->addr_len = ETH_ALEN;
-+
-+ ether_setup(dev);
-+
-+ dev->open = bnep_net_open;
-+ dev->stop = bnep_net_close;
-+ dev->hard_start_xmit = bnep_net_xmit;
-+ dev->get_stats = bnep_net_get_stats;
-+ dev->do_ioctl = bnep_net_ioctl;
-+ dev->set_mac_address = bnep_net_set_mac_addr;
-+ dev->set_multicast_list = bnep_net_set_mc_list;
-+
-+ dev->watchdog_timeo = HZ * 2;
-+ dev->tx_timeout = bnep_net_timeout;
-+
-+ return 0;
-+}
-diff -urN linux-2.4.18/net/bluetooth/bnep/sock.c linux-2.4.18-mh15/net/bluetooth/bnep/sock.c
---- linux-2.4.18/net/bluetooth/bnep/sock.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/bnep/sock.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,210 @@
-+/*
-+ BNEP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2001-2002 Inventel Systemes
-+ Written 2001-2002 by
-+ David Libault <david.libault@inventel.fr>
-+
-+ Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include "bnep.h"
-+
-+#ifndef CONFIG_BLUEZ_BNEP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+static int bnep_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ sock_orphan(sk);
-+ sock_put(sk);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct bnep_connlist_req cl;
-+ struct bnep_connadd_req ca;
-+ struct bnep_conndel_req cd;
-+ struct bnep_conninfo ci;
-+ struct socket *nsock;
-+ int err;
-+
-+ BT_DBG("cmd %x arg %lx", cmd, arg);
-+
-+ switch (cmd) {
-+ case BNEPCONNADD:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
-+ return -EFAULT;
-+
-+ nsock = sockfd_lookup(ca.sock, &err);
-+ if (!nsock)
-+ return err;
-+
-+ if (nsock->sk->state != BT_CONNECTED) {
-+ fput(nsock->file);
-+ return -EBADFD;
-+ }
-+
-+ err = bnep_add_connection(&ca, nsock);
-+ if (!err) {
-+ if (copy_to_user((void *) arg, &ca, sizeof(ca)))
-+ err = -EFAULT;
-+ } else
-+ fput(nsock->file);
-+
-+ return err;
-+
-+ case BNEPCONNDEL:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
-+ return -EFAULT;
-+
-+ return bnep_del_connection(&cd);
-+
-+ case BNEPGETCONNLIST:
-+ if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
-+ return -EFAULT;
-+
-+ if (cl.cnum <= 0)
-+ return -EINVAL;
-+
-+ err = bnep_get_connlist(&cl);
-+ if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
-+ return -EFAULT;
-+
-+ return err;
-+
-+ case BNEPGETCONNINFO:
-+ if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
-+ return -EFAULT;
-+
-+ err = bnep_get_conninfo(&ci);
-+ if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
-+ return -EFAULT;
-+
-+ return err;
-+
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static struct proto_ops bnep_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: bnep_sock_release,
-+ ioctl: bnep_sock_ioctl,
-+ bind: sock_no_bind,
-+ getname: sock_no_getname,
-+ sendmsg: sock_no_sendmsg,
-+ recvmsg: sock_no_recvmsg,
-+ poll: sock_no_poll,
-+ listen: sock_no_listen,
-+ shutdown: sock_no_shutdown,
-+ setsockopt: sock_no_setsockopt,
-+ getsockopt: sock_no_getsockopt,
-+ connect: sock_no_connect,
-+ socketpair: sock_no_socketpair,
-+ accept: sock_no_accept,
-+ mmap: sock_no_mmap
-+};
-+
-+static int bnep_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ if (sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &bnep_sock_ops;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, 1)))
-+ return -ENOMEM;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ sock->state = SS_UNCONNECTED;
-+ sock_init_data(sock, sk);
-+
-+ sk->destruct = NULL;
-+ sk->protocol = protocol;
-+
-+ return 0;
-+}
-+
-+static struct net_proto_family bnep_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: bnep_sock_create
-+};
-+
-+int bnep_sock_init(void)
-+{
-+ bluez_sock_register(BTPROTO_BNEP, &bnep_sock_family_ops);
-+ return 0;
-+}
-+
-+int bnep_sock_cleanup(void)
-+{
-+ if (bluez_sock_unregister(BTPROTO_BNEP))
-+ BT_ERR("Can't unregister BNEP socket");
-+ return 0;
-+}
-diff -urN linux-2.4.18/net/bluetooth/cmtp/capi.c linux-2.4.18-mh15/net/bluetooth/cmtp/capi.c
---- linux-2.4.18/net/bluetooth/cmtp/capi.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/cmtp/capi.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,707 @@
-+/*
-+ CMTP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <net/sock.h>
-+
-+#include <linux/capi.h>
-+
-+#include "../drivers/isdn/avmb1/capilli.h"
-+#include "../drivers/isdn/avmb1/capicmd.h"
-+#include "../drivers/isdn/avmb1/capiutil.h"
-+
-+#include "cmtp.h"
-+
-+#ifndef CONFIG_BLUEZ_CMTP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define REVISION "1.0"
-+
-+#define CAPI_INTEROPERABILITY 0x20
-+
-+#define CAPI_INTEROPERABILITY_REQ CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
-+#define CAPI_INTEROPERABILITY_CONF CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
-+#define CAPI_INTEROPERABILITY_IND CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
-+#define CAPI_INTEROPERABILITY_RESP CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
-+
-+#define CAPI_INTEROPERABILITY_REQ_LEN (CAPI_MSG_BASELEN + 2)
-+#define CAPI_INTEROPERABILITY_CONF_LEN (CAPI_MSG_BASELEN + 4)
-+#define CAPI_INTEROPERABILITY_IND_LEN (CAPI_MSG_BASELEN + 2)
-+#define CAPI_INTEROPERABILITY_RESP_LEN (CAPI_MSG_BASELEN + 2)
-+
-+#define CAPI_FUNCTION_REGISTER 0
-+#define CAPI_FUNCTION_RELEASE 1
-+#define CAPI_FUNCTION_GET_PROFILE 2
-+#define CAPI_FUNCTION_GET_MANUFACTURER 3
-+#define CAPI_FUNCTION_GET_VERSION 4
-+#define CAPI_FUNCTION_GET_SERIAL_NUMBER 5
-+#define CAPI_FUNCTION_MANUFACTURER 6
-+#define CAPI_FUNCTION_LOOPBACK 7
-+
-+static struct capi_driver_interface *di;
-+
-+
-+#define CMTP_MSGNUM 1
-+#define CMTP_APPLID 2
-+#define CMTP_MAPPING 3
-+
-+static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
-+{
-+ struct cmtp_application *app = kmalloc(sizeof(*app), GFP_KERNEL);
-+
-+ BT_DBG("session %p application %p appl %d", session, app, appl);
-+
-+ if (!app)
-+ return NULL;
-+
-+ memset(app, 0, sizeof(*app));
-+
-+ app->state = BT_OPEN;
-+ app->appl = appl;
-+
-+ list_add_tail(&app->list, &session->applications);
-+
-+ return app;
-+}
-+
-+static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
-+{
-+ BT_DBG("session %p application %p", session, app);
-+
-+ if (app) {
-+ list_del(&app->list);
-+ kfree(app);
-+ }
-+}
-+
-+static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
-+{
-+ struct cmtp_application *app;
-+ struct list_head *p, *n;
-+
-+ list_for_each_safe(p, n, &session->applications) {
-+ app = list_entry(p, struct cmtp_application, list);
-+ switch (pattern) {
-+ case CMTP_MSGNUM:
-+ if (app->msgnum == value)
-+ return app;
-+ break;
-+ case CMTP_APPLID:
-+ if (app->appl == value)
-+ return app;
-+ break;
-+ case CMTP_MAPPING:
-+ if (app->mapping == value)
-+ return app;
-+ break;
-+ }
-+ }
-+
-+ return NULL;
-+}
-+
-+static int cmtp_msgnum_get(struct cmtp_session *session)
-+{
-+ session->msgnum++;
-+
-+ if ((session->msgnum & 0xff) > 200)
-+ session->msgnum = CMTP_INITIAL_MSGNUM + 1;
-+
-+ return session->msgnum;
-+}
-+
-+
-+static void cmtp_send_interopmsg(struct cmtp_session *session,
-+ __u8 subcmd, __u16 appl, __u16 msgnum,
-+ __u16 function, unsigned char *buf, int len)
-+{
-+ struct sk_buff *skb;
-+ unsigned char *s;
-+
-+ BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum);
-+
-+ if (!(skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for interoperability packet");
-+ return;
-+ }
-+
-+ s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
-+
-+ capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
-+ capimsg_setu16(s, 2, appl);
-+ capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
-+ capimsg_setu8 (s, 5, subcmd);
-+ capimsg_setu16(s, 6, msgnum);
-+
-+ /* Interoperability selector (Bluetooth Device Management) */
-+ capimsg_setu16(s, 8, 0x0001);
-+
-+ capimsg_setu8 (s, 10, 3 + len);
-+ capimsg_setu16(s, 11, function);
-+ capimsg_setu8 (s, 13, len);
-+
-+ if (len > 0)
-+ memcpy(s + 14, buf, len);
-+
-+ cmtp_send_capimsg(session, skb);
-+}
-+
-+static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
-+{
-+ struct capi_ctr *ctrl = session->ctrl;
-+ struct cmtp_application *application;
-+ __u16 appl, msgnum, func, info;
-+ __u32 controller;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ switch (CAPIMSG_SUBCOMMAND(skb->data)) {
-+ case CAPI_CONF:
-+ func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
-+ info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
-+
-+ switch (func) {
-+ case CAPI_FUNCTION_REGISTER:
-+ msgnum = CAPIMSG_MSGID(skb->data);
-+
-+ application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
-+ if (application) {
-+ application->state = BT_CONNECTED;
-+ application->msgnum = 0;
-+ application->mapping = CAPIMSG_APPID(skb->data);
-+ wake_up_interruptible(&session->wait);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_RELEASE:
-+ appl = CAPIMSG_APPID(skb->data);
-+
-+ application = cmtp_application_get(session, CMTP_MAPPING, appl);
-+ if (application) {
-+ application->state = BT_CLOSED;
-+ application->msgnum = 0;
-+ wake_up_interruptible(&session->wait);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_GET_PROFILE:
-+ controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
-+ msgnum = CAPIMSG_MSGID(skb->data);
-+
-+ if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
-+ session->ncontroller = controller;
-+ wake_up_interruptible(&session->wait);
-+ break;
-+ }
-+
-+ if (!info && ctrl) {
-+ memcpy(&ctrl->profile,
-+ skb->data + CAPI_MSG_BASELEN + 11,
-+ sizeof(capi_profile));
-+ session->state = BT_CONNECTED;
-+ ctrl->ready(ctrl);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_GET_MANUFACTURER:
-+ controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);
-+
-+ if (!info && ctrl) {
-+ strncpy(ctrl->manu,
-+ skb->data + CAPI_MSG_BASELEN + 15,
-+ skb->data[CAPI_MSG_BASELEN + 14]);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_GET_VERSION:
-+ controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
-+
-+ if (!info && ctrl) {
-+ ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
-+ ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
-+ ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
-+ ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_GET_SERIAL_NUMBER:
-+ controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
-+
-+ if (!info && ctrl) {
-+ memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
-+ strncpy(ctrl->serial,
-+ skb->data + CAPI_MSG_BASELEN + 17,
-+ skb->data[CAPI_MSG_BASELEN + 16]);
-+ }
-+
-+ break;
-+ }
-+
-+ break;
-+
-+ case CAPI_IND:
-+ func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
-+
-+ if (func == CAPI_FUNCTION_LOOPBACK) {
-+ appl = CAPIMSG_APPID(skb->data);
-+ msgnum = CAPIMSG_MSGID(skb->data);
-+ cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
-+ skb->data + CAPI_MSG_BASELEN + 6,
-+ skb->data[CAPI_MSG_BASELEN + 5]);
-+ }
-+
-+ break;
-+ }
-+
-+ kfree_skb(skb);
-+}
-+
-+void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
-+{
-+ struct capi_ctr *ctrl = session->ctrl;
-+ struct cmtp_application *application;
-+ __u16 cmd, appl, info;
-+ __u32 ncci, contr;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
-+ cmtp_recv_interopmsg(session, skb);
-+ return;
-+ }
-+
-+ if (session->flags & (1 << CMTP_LOOPBACK)) {
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data));
-+ appl = CAPIMSG_APPID(skb->data);
-+ contr = CAPIMSG_CONTROL(skb->data);
-+
-+ application = cmtp_application_get(session, CMTP_MAPPING, appl);
-+ if (application) {
-+ appl = application->appl;
-+ CAPIMSG_SETAPPID(skb->data, appl);
-+ } else {
-+ BT_ERR("Can't find application with id %d", appl);
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ if ((contr & 0x7f) == 0x01) {
-+ contr = (contr & 0xffffff80) | session->num;
-+ CAPIMSG_SETCONTROL(skb->data, contr);
-+ }
-+
-+ if (!ctrl) {
-+ BT_ERR("Can't find controller %d for message", session->num);
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ switch (cmd) {
-+ case CAPI_CONNECT_B3_CONF:
-+ ncci = CAPIMSG_NCCI(skb->data);
-+ info = CAPIMSG_U16(skb->data, 12);
-+
-+ BT_DBG("CONNECT_B3_CONF ncci 0x%02x info 0x%02x", ncci, info);
-+
-+ if (info == 0)
-+ ctrl->new_ncci(ctrl, appl, ncci, 8);
-+
-+ ctrl->handle_capimsg(ctrl, appl, skb);
-+ break;
-+
-+ case CAPI_CONNECT_B3_IND:
-+ ncci = CAPIMSG_NCCI(skb->data);
-+
-+ BT_DBG("CONNECT_B3_IND ncci 0x%02x", ncci);
-+
-+ ctrl->new_ncci(ctrl, appl, ncci, 8);
-+ ctrl->handle_capimsg(ctrl, appl, skb);
-+ break;
-+
-+ case CAPI_DISCONNECT_B3_IND:
-+ ncci = CAPIMSG_NCCI(skb->data);
-+
-+ BT_DBG("DISCONNECT_B3_IND ncci 0x%02x", ncci);
-+
-+ if (ncci == 0xffffffff)
-+ BT_ERR("DISCONNECT_B3_IND with ncci 0xffffffff");
-+
-+ ctrl->handle_capimsg(ctrl, appl, skb);
-+ ctrl->free_ncci(ctrl, appl, ncci);
-+ break;
-+
-+ default:
-+ ctrl->handle_capimsg(ctrl, appl, skb);
-+ break;
-+ }
-+}
-+
-+void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
-+{
-+ struct cmtp_scb *scb = (void *) skb->cb;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ scb->id = -1;
-+ scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
-+
-+ skb_queue_tail(&session->transmit, skb);
-+
-+ cmtp_schedule(session);
-+}
-+
-+
-+static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
-+{
-+ BT_DBG("ctrl %p data %p", ctrl, data);
-+
-+ return -EIO;
-+}
-+
-+static void cmtp_reset_ctr(struct capi_ctr *ctrl)
-+{
-+ BT_DBG("ctrl %p", ctrl);
-+
-+ ctrl->reseted(ctrl);
-+}
-+
-+static void cmtp_remove_ctr(struct capi_ctr *ctrl)
-+{
-+ struct cmtp_session *session = ctrl->driverdata;
-+
-+ BT_DBG("ctrl %p", ctrl);
-+
-+ ctrl->suspend_output(ctrl);
-+
-+ atomic_inc(&session->terminate);
-+ cmtp_schedule(session);
-+}
-+
-+static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct cmtp_session *session = ctrl->driverdata;
-+ struct cmtp_application *application;
-+ unsigned long timeo = CMTP_INTEROP_TIMEOUT;
-+ unsigned char buf[8];
-+ int err = 0, nconn, want = rp->level3cnt;
-+
-+ BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
-+ ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
-+
-+ application = cmtp_application_add(session, appl);
-+ if (!application) {
-+ BT_ERR("Can't allocate memory for new application");
-+ ctrl->appl_released(ctrl, appl);
-+ return;
-+ }
-+
-+ if (want < 0)
-+ nconn = ctrl->profile.nbchannel * -want;
-+ else
-+ nconn = want;
-+
-+ if (nconn == 0)
-+ nconn = ctrl->profile.nbchannel;
-+
-+ capimsg_setu16(buf, 0, nconn);
-+ capimsg_setu16(buf, 2, rp->datablkcnt);
-+ capimsg_setu16(buf, 4, rp->datablklen);
-+
-+ application->state = BT_CONFIG;
-+ application->msgnum = cmtp_msgnum_get(session);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
-+ CAPI_FUNCTION_REGISTER, buf, 6);
-+
-+ add_wait_queue(&session->wait, &wait);
-+ while (1) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ if (application->state == BT_CLOSED) {
-+ err = -application->err;
-+ break;
-+ }
-+
-+ if (application->state == BT_CONNECTED)
-+ break;
-+
-+ if (signal_pending(current)) {
-+ err = -EINTR;
-+ break;
-+ }
-+
-+ timeo = schedule_timeout(timeo);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&session->wait, &wait);
-+
-+ if (err) {
-+ ctrl->appl_released(ctrl, appl);
-+ cmtp_application_del(session, application);
-+ return;
-+ }
-+
-+ ctrl->appl_registered(ctrl, appl);
-+}
-+
-+static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct cmtp_session *session = ctrl->driverdata;
-+ struct cmtp_application *application;
-+ unsigned long timeo = CMTP_INTEROP_TIMEOUT;
-+
-+ BT_DBG("ctrl %p appl %d", ctrl, appl);
-+
-+ application = cmtp_application_get(session, CMTP_APPLID, appl);
-+ if (!application) {
-+ BT_ERR("Can't find application");
-+ return;
-+ }
-+
-+ application->msgnum = cmtp_msgnum_get(session);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
-+ CAPI_FUNCTION_RELEASE, NULL, 0);
-+
-+ add_wait_queue(&session->wait, &wait);
-+ while (timeo) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (application->state == BT_CLOSED)
-+ break;
-+
-+ if (signal_pending(current))
-+ break;
-+
-+ timeo = schedule_timeout(timeo);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&session->wait, &wait);
-+
-+ cmtp_application_del(session, application);
-+ ctrl->appl_released(ctrl, appl);
-+}
-+
-+static void cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
-+{
-+ struct cmtp_session *session = ctrl->driverdata;
-+ struct cmtp_application *application;
-+ __u16 appl;
-+ __u32 contr;
-+
-+ BT_DBG("ctrl %p skb %p", ctrl, skb);
-+
-+ appl = CAPIMSG_APPID(skb->data);
-+ contr = CAPIMSG_CONTROL(skb->data);
-+
-+ application = cmtp_application_get(session, CMTP_APPLID, appl);
-+ if ((!application) || (application->state != BT_CONNECTED)) {
-+ BT_ERR("Can't find application with id %d", appl);
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ CAPIMSG_SETAPPID(skb->data, application->mapping);
-+
-+ if ((contr & 0x7f) == session->num) {
-+ contr = (contr & 0xffffff80) | 0x01;
-+ CAPIMSG_SETCONTROL(skb->data, contr);
-+ }
-+
-+ cmtp_send_capimsg(session, skb);
-+}
-+
-+static char *cmtp_procinfo(struct capi_ctr *ctrl)
-+{
-+ return "CAPI Message Transport Protocol";
-+}
-+
-+static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl)
-+{
-+ struct cmtp_session *session = ctrl->driverdata;
-+ struct cmtp_application *app;
-+ struct list_head *p, *n;
-+ int len = 0;
-+
-+ len += sprintf(page + len, "%s (Revision %s)\n\n", cmtp_procinfo(ctrl), REVISION);
-+ len += sprintf(page + len, "addr %s\n", session->name);
-+ len += sprintf(page + len, "ctrl %d\n", session->num);
-+
-+ list_for_each_safe(p, n, &session->applications) {
-+ app = list_entry(p, struct cmtp_application, list);
-+ len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping);
-+ }
-+
-+ if (off + count >= len)
-+ *eof = 1;
-+
-+ if (len < off)
-+ return 0;
-+
-+ *start = page + off;
-+
-+ return ((count < len - off) ? count : len - off);
-+}
-+
-+static struct capi_driver cmtp_driver = {
-+ name: "cmtp",
-+ revision: REVISION,
-+ load_firmware: cmtp_load_firmware,
-+ reset_ctr: cmtp_reset_ctr,
-+ remove_ctr: cmtp_remove_ctr,
-+ register_appl: cmtp_register_appl,
-+ release_appl: cmtp_release_appl,
-+ send_message: cmtp_send_message,
-+ procinfo: cmtp_procinfo,
-+ ctr_read_proc: cmtp_ctr_read_proc,
-+
-+ driver_read_proc: 0,
-+ add_card: 0,
-+};
-+
-+
-+int cmtp_attach_device(struct cmtp_session *session)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ unsigned long timeo = CMTP_INTEROP_TIMEOUT;
-+ unsigned char buf[4];
-+
-+ BT_DBG("session %p", session);
-+
-+ capimsg_setu32(buf, 0, 0);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
-+ CAPI_FUNCTION_GET_PROFILE, buf, 4);
-+
-+ add_wait_queue(&session->wait, &wait);
-+ while (timeo) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (session->ncontroller)
-+ break;
-+
-+ if (signal_pending(current))
-+ break;
-+
-+ timeo = schedule_timeout(timeo);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&session->wait, &wait);
-+
-+ BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
-+
-+ if (!timeo)
-+ return -ETIMEDOUT;
-+
-+ if (!session->ncontroller)
-+ return -ENODEV;
-+
-+
-+ if (session->ncontroller > 1)
-+ BT_INFO("Setting up only CAPI controller 1");
-+
-+ if (!(session->ctrl = di->attach_ctr(&cmtp_driver, session->name, session))) {
-+ BT_ERR("Can't attach new controller");
-+ return -EBUSY;
-+ }
-+
-+ session->num = session->ctrl->cnr;
-+
-+ BT_DBG("session %p ctrl %p num %d", session, session->ctrl, session->num);
-+
-+ capimsg_setu32(buf, 0, 1);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-+ CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-+ CAPI_FUNCTION_GET_VERSION, buf, 4);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-+ CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-+ CAPI_FUNCTION_GET_PROFILE, buf, 4);
-+
-+ return 0;
-+}
-+
-+void cmtp_detach_device(struct cmtp_session *session)
-+{
-+ struct capi_ctr *ctrl = session->ctrl;
-+
-+ BT_DBG("session %p ctrl %p", session, ctrl);
-+
-+ if (!ctrl)
-+ return;
-+
-+ ctrl->reseted(ctrl);
-+
-+ di->detach_ctr(ctrl);
-+}
-+
-+int cmtp_init_capi(void)
-+{
-+ if (!(di = attach_capi_driver(&cmtp_driver))) {
-+ BT_ERR("Can't attach CAPI driver");
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+void cmtp_cleanup_capi(void)
-+{
-+ detach_capi_driver(&cmtp_driver);
-+}
-diff -urN linux-2.4.18/net/bluetooth/cmtp/cmtp.h linux-2.4.18-mh15/net/bluetooth/cmtp/cmtp.h
---- linux-2.4.18/net/bluetooth/cmtp/cmtp.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/cmtp/cmtp.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,138 @@
-+/*
-+ CMTP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#ifndef __CMTP_H
-+#define __CMTP_H
-+
-+#include <linux/types.h>
-+#include <net/bluetooth/bluetooth.h>
-+
-+#define BTNAMSIZ 18
-+
-+/* CMTP ioctl defines */
-+#define CMTPCONNADD _IOW('C', 200, int)
-+#define CMTPCONNDEL _IOW('C', 201, int)
-+#define CMTPGETCONNLIST _IOR('C', 210, int)
-+#define CMTPGETCONNINFO _IOR('C', 211, int)
-+
-+#define CMTP_LOOPBACK 0
-+
-+struct cmtp_connadd_req {
-+ int sock; // Connected socket
-+ __u32 flags;
-+};
-+
-+struct cmtp_conndel_req {
-+ bdaddr_t bdaddr;
-+ __u32 flags;
-+};
-+
-+struct cmtp_conninfo {
-+ bdaddr_t bdaddr;
-+ __u32 flags;
-+ __u16 state;
-+ int num;
-+};
-+
-+struct cmtp_connlist_req {
-+ __u32 cnum;
-+ struct cmtp_conninfo *ci;
-+};
-+
-+int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock);
-+int cmtp_del_connection(struct cmtp_conndel_req *req);
-+int cmtp_get_connlist(struct cmtp_connlist_req *req);
-+int cmtp_get_conninfo(struct cmtp_conninfo *ci);
-+
-+/* CMTP session defines */
-+#define CMTP_INTEROP_TIMEOUT (HZ * 5)
-+#define CMTP_INITIAL_MSGNUM 0xff00
-+
-+struct cmtp_session {
-+ struct list_head list;
-+
-+ struct socket *sock;
-+
-+ bdaddr_t bdaddr;
-+
-+ unsigned long state;
-+ unsigned long flags;
-+
-+ uint mtu;
-+
-+ char name[BTNAMSIZ];
-+
-+ atomic_t terminate;
-+
-+ wait_queue_head_t wait;
-+
-+ int ncontroller;
-+ int num;
-+ struct capi_ctr *ctrl;
-+
-+ struct list_head applications;
-+
-+ unsigned long blockids;
-+ int msgnum;
-+
-+ struct sk_buff_head transmit;
-+
-+ struct sk_buff *reassembly[16];
-+};
-+
-+struct cmtp_application {
-+ struct list_head list;
-+
-+ unsigned long state;
-+ int err;
-+
-+ __u16 appl;
-+ __u16 mapping;
-+
-+ __u16 msgnum;
-+};
-+
-+struct cmtp_scb {
-+ int id;
-+ int data;
-+};
-+
-+int cmtp_attach_device(struct cmtp_session *session);
-+void cmtp_detach_device(struct cmtp_session *session);
-+
-+void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb);
-+void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb);
-+
-+static inline void cmtp_schedule(struct cmtp_session *session)
-+{
-+ struct sock *sk = session->sock->sk;
-+
-+ wake_up_interruptible(sk->sleep);
-+}
-+
-+/* CMTP init defines */
-+int cmtp_init_capi(void);
-+int cmtp_init_sockets(void);
-+void cmtp_cleanup_capi(void);
-+void cmtp_cleanup_sockets(void);
-+
-+#endif /* __CMTP_H */
-diff -urN linux-2.4.18/net/bluetooth/cmtp/Config.in linux-2.4.18-mh15/net/bluetooth/cmtp/Config.in
---- linux-2.4.18/net/bluetooth/cmtp/Config.in 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/cmtp/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,7 @@
-+#
-+# Bluetooth CMTP layer configuration
-+#
-+
-+if [ "$CONFIG_ISDN" = "y" -o "$CONFIG_ISDN" = "m" ]; then
-+ dep_tristate 'CMTP protocol support' CONFIG_BLUEZ_CMTP $CONFIG_ISDN_CAPI $CONFIG_BLUEZ_L2CAP
-+fi
-diff -urN linux-2.4.18/net/bluetooth/cmtp/core.c linux-2.4.18-mh15/net/bluetooth/cmtp/core.c
---- linux-2.4.18/net/bluetooth/cmtp/core.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/cmtp/core.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,515 @@
-+/*
-+ CMTP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <linux/init.h>
-+#include <net/sock.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#include "cmtp.h"
-+
-+#ifndef CONFIG_BLUEZ_CMTP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define VERSION "1.0"
-+
-+static DECLARE_RWSEM(cmtp_session_sem);
-+static LIST_HEAD(cmtp_session_list);
-+
-+static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr)
-+{
-+ struct cmtp_session *session;
-+ struct list_head *p;
-+
-+ BT_DBG("");
-+
-+ list_for_each(p, &cmtp_session_list) {
-+ session = list_entry(p, struct cmtp_session, list);
-+ if (!bacmp(bdaddr, &session->bdaddr))
-+ return session;
-+ }
-+ return NULL;
-+}
-+
-+static void __cmtp_link_session(struct cmtp_session *session)
-+{
-+ MOD_INC_USE_COUNT;
-+ list_add(&session->list, &cmtp_session_list);
-+}
-+
-+static void __cmtp_unlink_session(struct cmtp_session *session)
-+{
-+ list_del(&session->list);
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci)
-+{
-+ bacpy(&ci->bdaddr, &session->bdaddr);
-+
-+ ci->flags = session->flags;
-+ ci->state = session->state;
-+
-+ ci->num = session->num;
-+}
-+
-+
-+static inline int cmtp_alloc_block_id(struct cmtp_session *session)
-+{
-+ int i, id = -1;
-+
-+ for (i = 0; i < 16; i++)
-+ if (!test_and_set_bit(i, &session->blockids)) {
-+ id = i;
-+ break;
-+ }
-+
-+ return id;
-+}
-+
-+static inline void cmtp_free_block_id(struct cmtp_session *session, int id)
-+{
-+ clear_bit(id, &session->blockids);
-+}
-+
-+static inline void cmtp_add_msgpart(struct cmtp_session *session, int id, const unsigned char *buf, int count)
-+{
-+ struct sk_buff *skb = session->reassembly[id], *nskb;
-+ int size;
-+
-+ BT_DBG("session %p buf %p count %d", session, buf, count);
-+
-+ size = (skb) ? skb->len + count : count;
-+
-+ if (!(nskb = alloc_skb(size, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for CAPI message");
-+ return;
-+ }
-+
-+ if (skb && (skb->len > 0))
-+ memcpy(skb_put(nskb, skb->len), skb->data, skb->len);
-+
-+ memcpy(skb_put(nskb, count), buf, count);
-+
-+ session->reassembly[id] = nskb;
-+
-+ if (skb)
-+ kfree_skb(skb);
-+}
-+
-+static inline int cmtp_recv_frame(struct cmtp_session *session, struct sk_buff *skb)
-+{
-+ __u8 hdr, hdrlen, id;
-+ __u16 len;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ while (skb->len > 0) {
-+ hdr = skb->data[0];
-+
-+ switch (hdr & 0xc0) {
-+ case 0x40:
-+ hdrlen = 2;
-+ len = skb->data[1];
-+ break;
-+ case 0x80:
-+ hdrlen = 3;
-+ len = skb->data[1] | (skb->data[2] << 8);
-+ break;
-+ default:
-+ hdrlen = 1;
-+ len = 0;
-+ break;
-+ }
-+
-+ id = (hdr & 0x3c) >> 2;
-+
-+ BT_DBG("hdr 0x%02x hdrlen %d len %d id %d", hdr, hdrlen, len, id);
-+
-+ if (hdrlen + len > skb->len) {
-+ BT_ERR("Wrong size or header information in CMTP frame");
-+ break;
-+ }
-+
-+ if (len == 0) {
-+ skb_pull(skb, hdrlen);
-+ continue;
-+ }
-+
-+ switch (hdr & 0x03) {
-+ case 0x00:
-+ cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
-+ cmtp_recv_capimsg(session, session->reassembly[id]);
-+ session->reassembly[id] = NULL;
-+ break;
-+ case 0x01:
-+ cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
-+ break;
-+ default:
-+ if (session->reassembly[id] != NULL)
-+ kfree_skb(session->reassembly[id]);
-+ session->reassembly[id] = NULL;
-+ break;
-+ }
-+
-+ skb_pull(skb, hdrlen + len);
-+ }
-+
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+static int cmtp_send_frame(struct cmtp_session *session, unsigned char *data, int len)
-+{
-+ struct socket *sock = session->sock;
-+ struct iovec iv = { data, len };
-+ struct msghdr msg;
-+ int err;
-+
-+ BT_DBG("session %p data %p len %d", session, data, len);
-+
-+ if (!len)
-+ return 0;
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_iovlen = 1;
-+ msg.msg_iov = &iv;
-+
-+ err = sock->ops->sendmsg(sock, &msg, len, 0);
-+ return err;
-+}
-+
-+static int cmtp_process_transmit(struct cmtp_session *session)
-+{
-+ struct sk_buff *skb, *nskb;
-+ unsigned char *hdr;
-+ unsigned int size, tail;
-+
-+ BT_DBG("session %p", session);
-+
-+ if (!(nskb = alloc_skb(session->mtu, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for new frame");
-+ return -ENOMEM;
-+ }
-+
-+ while ((skb = skb_dequeue(&session->transmit))) {
-+ struct cmtp_scb *scb = (void *) skb->cb;
-+
-+ if ((tail = (session->mtu - nskb->len)) < 5) {
-+ cmtp_send_frame(session, nskb->data, nskb->len);
-+ skb_trim(nskb, 0);
-+ tail = session->mtu;
-+ }
-+
-+ size = min_t(uint, ((tail < 258) ? (tail - 2) : (tail - 3)), skb->len);
-+
-+ if ((scb->id < 0) && ((scb->id = cmtp_alloc_block_id(session)) < 0)) {
-+ skb_queue_head(&session->transmit, skb);
-+ break;
-+ }
-+
-+ if (size < 256) {
-+ hdr = skb_put(nskb, 2);
-+ hdr[0] = 0x40
-+ | ((scb->id << 2) & 0x3c)
-+ | ((skb->len == size) ? 0x00 : 0x01);
-+ hdr[1] = size;
-+ } else {
-+ hdr = skb_put(nskb, 3);
-+ hdr[0] = 0x80
-+ | ((scb->id << 2) & 0x3c)
-+ | ((skb->len == size) ? 0x00 : 0x01);
-+ hdr[1] = size & 0xff;
-+ hdr[2] = size >> 8;
-+ }
-+
-+ memcpy(skb_put(nskb, size), skb->data, size);
-+ skb_pull(skb, size);
-+
-+ if (skb->len > 0) {
-+ skb_queue_head(&session->transmit, skb);
-+ } else {
-+ cmtp_free_block_id(session, scb->id);
-+ if (scb->data) {
-+ cmtp_send_frame(session, nskb->data, nskb->len);
-+ skb_trim(nskb, 0);
-+ }
-+ kfree_skb(skb);
-+ }
-+ }
-+
-+ cmtp_send_frame(session, nskb->data, nskb->len);
-+
-+ kfree_skb(nskb);
-+
-+ return skb_queue_len(&session->transmit);
-+}
-+
-+static int cmtp_session(void *arg)
-+{
-+ struct cmtp_session *session = arg;
-+ struct sock *sk = session->sock->sk;
-+ struct sk_buff *skb;
-+ wait_queue_t wait;
-+
-+ BT_DBG("session %p", session);
-+
-+ daemonize(); reparent_to_init();
-+
-+ sprintf(current->comm, "kcmtpd_ctr_%d", session->num);
-+
-+ sigfillset(&current->blocked);
-+ flush_signals(current);
-+
-+ current->nice = -15;
-+
-+ set_fs(KERNEL_DS);
-+
-+ init_waitqueue_entry(&wait, current);
-+ add_wait_queue(sk->sleep, &wait);
-+ while (!atomic_read(&session->terminate)) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (sk->state != BT_CONNECTED)
-+ break;
-+
-+ while ((skb = skb_dequeue(&sk->receive_queue))) {
-+ skb_orphan(skb);
-+ cmtp_recv_frame(session, skb);
-+ }
-+
-+ cmtp_process_transmit(session);
-+
-+ schedule();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ down_write(&cmtp_session_sem);
-+
-+ if (!(session->flags & (1 << CMTP_LOOPBACK)))
-+ cmtp_detach_device(session);
-+
-+ fput(session->sock->file);
-+
-+ __cmtp_unlink_session(session);
-+
-+ up_write(&cmtp_session_sem);
-+
-+ kfree(session);
-+ return 0;
-+}
-+
-+int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
-+{
-+ struct cmtp_session *session, *s;
-+ bdaddr_t src, dst;
-+ int i, err;
-+
-+ BT_DBG("");
-+
-+ baswap(&src, &bluez_pi(sock->sk)->src);
-+ baswap(&dst, &bluez_pi(sock->sk)->dst);
-+
-+ session = kmalloc(sizeof(struct cmtp_session), GFP_KERNEL);
-+ if (!session)
-+ return -ENOMEM;
-+ memset(session, 0, sizeof(struct cmtp_session));
-+
-+ down_write(&cmtp_session_sem);
-+
-+ s = __cmtp_get_session(&bluez_pi(sock->sk)->dst);
-+ if (s && s->state == BT_CONNECTED) {
-+ err = -EEXIST;
-+ goto failed;
-+ }
-+
-+ bacpy(&session->bdaddr, &bluez_pi(sock->sk)->dst);
-+
-+ session->mtu = min_t(uint, l2cap_pi(sock->sk)->omtu, l2cap_pi(sock->sk)->imtu);
-+
-+ BT_DBG("mtu %d", session->mtu);
-+
-+ sprintf(session->name, "%s", batostr(&dst));
-+
-+ session->sock = sock;
-+ session->state = BT_CONFIG;
-+
-+ init_waitqueue_head(&session->wait);
-+
-+ session->ctrl = NULL;
-+ session->msgnum = CMTP_INITIAL_MSGNUM;
-+
-+ INIT_LIST_HEAD(&session->applications);
-+
-+ skb_queue_head_init(&session->transmit);
-+
-+ for (i = 0; i < 16; i++)
-+ session->reassembly[i] = NULL;
-+
-+ session->flags = req->flags;
-+
-+ __cmtp_link_session(session);
-+
-+ err = kernel_thread(cmtp_session, session, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-+ if (err < 0)
-+ goto unlink;
-+
-+ if (!(session->flags & (1 << CMTP_LOOPBACK))) {
-+ err = cmtp_attach_device(session);
-+ if (err < 0)
-+ goto detach;
-+ }
-+
-+ up_write(&cmtp_session_sem);
-+ return 0;
-+
-+detach:
-+ cmtp_detach_device(session);
-+
-+unlink:
-+ __cmtp_unlink_session(session);
-+
-+failed:
-+ up_write(&cmtp_session_sem);
-+ kfree(session);
-+ return err;
-+}
-+
-+int cmtp_del_connection(struct cmtp_conndel_req *req)
-+{
-+ struct cmtp_session *session;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ down_read(&cmtp_session_sem);
-+
-+ session = __cmtp_get_session(&req->bdaddr);
-+ if (session) {
-+ /* Flush the transmit queue */
-+ skb_queue_purge(&session->transmit);
-+
-+ /* Kill session thread */
-+ atomic_inc(&session->terminate);
-+ cmtp_schedule(session);
-+ } else
-+ err = -ENOENT;
-+
-+ up_read(&cmtp_session_sem);
-+ return err;
-+}
-+
-+int cmtp_get_connlist(struct cmtp_connlist_req *req)
-+{
-+ struct list_head *p;
-+ int err = 0, n = 0;
-+
-+ BT_DBG("");
-+
-+ down_read(&cmtp_session_sem);
-+
-+ list_for_each(p, &cmtp_session_list) {
-+ struct cmtp_session *session;
-+ struct cmtp_conninfo ci;
-+
-+ session = list_entry(p, struct cmtp_session, list);
-+
-+ __cmtp_copy_session(session, &ci);
-+
-+ if (copy_to_user(req->ci, &ci, sizeof(ci))) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ if (++n >= req->cnum)
-+ break;
-+
-+ req->ci++;
-+ }
-+ req->cnum = n;
-+
-+ up_read(&cmtp_session_sem);
-+ return err;
-+}
-+
-+int cmtp_get_conninfo(struct cmtp_conninfo *ci)
-+{
-+ struct cmtp_session *session;
-+ int err = 0;
-+
-+ down_read(&cmtp_session_sem);
-+
-+ session = __cmtp_get_session(&ci->bdaddr);
-+ if (session)
-+ __cmtp_copy_session(session, ci);
-+ else
-+ err = -ENOENT;
-+
-+ up_read(&cmtp_session_sem);
-+ return err;
-+}
-+
-+
-+int __init init_cmtp(void)
-+{
-+ l2cap_load();
-+
-+ cmtp_init_capi();
-+ cmtp_init_sockets();
-+
-+ BT_INFO("BlueZ CMTP ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>");
-+
-+ return 0;
-+}
-+
-+void __exit exit_cmtp(void)
-+{
-+ cmtp_cleanup_sockets();
-+ cmtp_cleanup_capi();
-+}
-+
-+module_init(init_cmtp);
-+module_exit(exit_cmtp);
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ CMTP ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/cmtp/Makefile linux-2.4.18-mh15/net/bluetooth/cmtp/Makefile
---- linux-2.4.18/net/bluetooth/cmtp/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/cmtp/Makefile 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the Linux Bluetooth CMTP layer
-+#
-+
-+O_TARGET := cmtp.o
-+
-+obj-y := core.o sock.o capi.o
-+obj-m += $(O_TARGET)
-+
-+include $(TOPDIR)/Rules.make
-diff -urN linux-2.4.18/net/bluetooth/cmtp/sock.c linux-2.4.18-mh15/net/bluetooth/cmtp/sock.c
---- linux-2.4.18/net/bluetooth/cmtp/sock.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/cmtp/sock.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,208 @@
-+/*
-+ CMTP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include "cmtp.h"
-+
-+#ifndef CONFIG_BLUEZ_CMTP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+static int cmtp_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ sock_orphan(sk);
-+ sock_put(sk);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct cmtp_connadd_req ca;
-+ struct cmtp_conndel_req cd;
-+ struct cmtp_connlist_req cl;
-+ struct cmtp_conninfo ci;
-+ struct socket *nsock;
-+ int err;
-+
-+ BT_DBG("cmd %x arg %lx", cmd, arg);
-+
-+ switch (cmd) {
-+ case CMTPCONNADD:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
-+ return -EFAULT;
-+
-+ nsock = sockfd_lookup(ca.sock, &err);
-+ if (!nsock)
-+ return err;
-+
-+ if (nsock->sk->state != BT_CONNECTED) {
-+ fput(nsock->file);
-+ return -EBADFD;
-+ }
-+
-+ err = cmtp_add_connection(&ca, nsock);
-+ if (!err) {
-+ if (copy_to_user((void *) arg, &ca, sizeof(ca)))
-+ err = -EFAULT;
-+ } else
-+ fput(nsock->file);
-+
-+ return err;
-+
-+ case CMTPCONNDEL:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
-+ return -EFAULT;
-+
-+ return cmtp_del_connection(&cd);
-+
-+ case CMTPGETCONNLIST:
-+ if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
-+ return -EFAULT;
-+
-+ if (cl.cnum <= 0)
-+ return -EINVAL;
-+
-+ err = cmtp_get_connlist(&cl);
-+ if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
-+ return -EFAULT;
-+
-+ return err;
-+
-+ case CMTPGETCONNINFO:
-+ if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
-+ return -EFAULT;
-+
-+ err = cmtp_get_conninfo(&ci);
-+ if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
-+ return -EFAULT;
-+
-+ return err;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static struct proto_ops cmtp_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: cmtp_sock_release,
-+ ioctl: cmtp_sock_ioctl,
-+ bind: sock_no_bind,
-+ getname: sock_no_getname,
-+ sendmsg: sock_no_sendmsg,
-+ recvmsg: sock_no_recvmsg,
-+ poll: sock_no_poll,
-+ listen: sock_no_listen,
-+ shutdown: sock_no_shutdown,
-+ setsockopt: sock_no_setsockopt,
-+ getsockopt: sock_no_getsockopt,
-+ connect: sock_no_connect,
-+ socketpair: sock_no_socketpair,
-+ accept: sock_no_accept,
-+ mmap: sock_no_mmap
-+};
-+
-+static int cmtp_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ if (sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &cmtp_sock_ops;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, 1)))
-+ return -ENOMEM;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ sock->state = SS_UNCONNECTED;
-+ sock_init_data(sock, sk);
-+
-+ sk->destruct = NULL;
-+ sk->protocol = protocol;
-+
-+ return 0;
-+}
-+
-+static struct net_proto_family cmtp_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: cmtp_sock_create
-+};
-+
-+int cmtp_init_sockets(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_CMTP, &cmtp_sock_family_ops))) {
-+ BT_ERR("Can't register CMTP socket layer (%d)", err);
-+ return err;
-+ }
-+
-+ return 0;
-+}
-+
-+void cmtp_cleanup_sockets(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_unregister(BTPROTO_CMTP)))
-+ BT_ERR("Can't unregister CMTP socket layer (%d)", err);
-+
-+ return;
-+}
-diff -urN linux-2.4.18/net/bluetooth/Config.in linux-2.4.18-mh15/net/bluetooth/Config.in
---- linux-2.4.18/net/bluetooth/Config.in 2001-06-12 04:15:27.000000000 +0200
-+++ linux-2.4.18-mh15/net/bluetooth/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -1,16 +1,23 @@
- #
--# Bluetooth configuration
-+# Bluetooth subsystem configuration
- #
-
- if [ "$CONFIG_NET" != "n" ]; then
-+
- mainmenu_option next_comment
- comment 'Bluetooth support'
- dep_tristate 'Bluetooth subsystem support' CONFIG_BLUEZ $CONFIG_NET
-
- if [ "$CONFIG_BLUEZ" != "n" ]; then
- dep_tristate 'L2CAP protocol support' CONFIG_BLUEZ_L2CAP $CONFIG_BLUEZ
-+ dep_tristate 'SCO links support' CONFIG_BLUEZ_SCO $CONFIG_BLUEZ
-+ source net/bluetooth/rfcomm/Config.in
-+ source net/bluetooth/bnep/Config.in
-+ source net/bluetooth/cmtp/Config.in
-+ source net/bluetooth/hidp/Config.in
- source drivers/bluetooth/Config.in
- fi
-+
- endmenu
- fi
-
-diff -urN linux-2.4.18/net/bluetooth/hci_conn.c linux-2.4.18-mh15/net/bluetooth/hci_conn.c
---- linux-2.4.18/net/bluetooth/hci_conn.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/hci_conn.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,435 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * HCI Connection handling.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/notifier.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+#ifndef HCI_CORE_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+void hci_acl_connect(struct hci_conn *conn)
-+{
-+ struct hci_dev *hdev = conn->hdev;
-+ struct inquiry_entry *ie;
-+ create_conn_cp cp;
-+
-+ BT_DBG("%p", conn);
-+
-+ conn->state = BT_CONNECT;
-+ conn->out = 1;
-+ conn->link_mode = HCI_LM_MASTER;
-+
-+ memset(&cp, 0, sizeof(cp));
-+ bacpy(&cp.bdaddr, &conn->dst);
-+ cp.pscan_rep_mode = 0x02;
-+
-+ if ((ie = inquiry_cache_lookup(hdev, &conn->dst)) &&
-+ inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
-+ cp.pscan_rep_mode = ie->info.pscan_rep_mode;
-+ cp.pscan_mode = ie->info.pscan_mode;
-+ cp.clock_offset = ie->info.clock_offset | __cpu_to_le16(0x8000);
-+ }
-+
-+ cp.pkt_type = __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK);
-+ if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
-+ cp.role_switch = 0x01;
-+ else
-+ cp.role_switch = 0x00;
-+
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN,
-+ CREATE_CONN_CP_SIZE, &cp);
-+}
-+
-+void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
-+{
-+ disconnect_cp cp;
-+
-+ BT_DBG("%p", conn);
-+
-+ conn->state = BT_DISCONN;
-+
-+ cp.handle = __cpu_to_le16(conn->handle);
-+ cp.reason = reason;
-+ hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT,
-+ DISCONNECT_CP_SIZE, &cp);
-+}
-+
-+void hci_add_sco(struct hci_conn *conn, __u16 handle)
-+{
-+ struct hci_dev *hdev = conn->hdev;
-+ add_sco_cp cp;
-+
-+ BT_DBG("%p", conn);
-+
-+ conn->state = BT_CONNECT;
-+ conn->out = 1;
-+
-+ cp.pkt_type = __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
-+ cp.handle = __cpu_to_le16(handle);
-+
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, ADD_SCO_CP_SIZE, &cp);
-+}
-+
-+static void hci_conn_timeout(unsigned long arg)
-+{
-+ struct hci_conn *conn = (void *)arg;
-+ struct hci_dev *hdev = conn->hdev;
-+
-+ BT_DBG("conn %p state %d", conn, conn->state);
-+
-+ if (atomic_read(&conn->refcnt))
-+ return;
-+
-+ hci_dev_lock(hdev);
-+ if (conn->state == BT_CONNECTED)
-+ hci_acl_disconn(conn, 0x13);
-+ else
-+ conn->state = BT_CLOSED;
-+ hci_dev_unlock(hdev);
-+ return;
-+}
-+
-+static void hci_conn_init_timer(struct hci_conn *conn)
-+{
-+ init_timer(&conn->timer);
-+ conn->timer.function = hci_conn_timeout;
-+ conn->timer.data = (unsigned long)conn;
-+}
-+
-+struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
-+{
-+ struct hci_conn *conn;
-+
-+ BT_DBG("%s dst %s", hdev->name, batostr(dst));
-+
-+ if (!(conn = kmalloc(sizeof(struct hci_conn), GFP_ATOMIC)))
-+ return NULL;
-+ memset(conn, 0, sizeof(struct hci_conn));
-+
-+ bacpy(&conn->dst, dst);
-+ conn->type = type;
-+ conn->hdev = hdev;
-+ conn->state = BT_OPEN;
-+
-+ skb_queue_head_init(&conn->data_q);
-+ hci_conn_init_timer(conn);
-+
-+ atomic_set(&conn->refcnt, 0);
-+
-+ hci_dev_hold(hdev);
-+
-+ tasklet_disable(&hdev->tx_task);
-+ conn_hash_add(hdev, conn);
-+ tasklet_enable(&hdev->tx_task);
-+
-+ return conn;
-+}
-+
-+int hci_conn_del(struct hci_conn *conn)
-+{
-+ struct hci_dev *hdev = conn->hdev;
-+
-+ BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
-+
-+ hci_conn_del_timer(conn);
-+
-+ if (conn->type == SCO_LINK) {
-+ struct hci_conn *acl = conn->link;
-+ if (acl) {
-+ acl->link = NULL;
-+ hci_conn_put(acl);
-+ }
-+ } else {
-+ struct hci_conn *sco = conn->link;
-+ if (sco)
-+ sco->link = NULL;
-+
-+ /* Unacked frames */
-+ hdev->acl_cnt += conn->sent;
-+ }
-+
-+ tasklet_disable(&hdev->tx_task);
-+ conn_hash_del(hdev, conn);
-+ tasklet_enable(&hdev->tx_task);
-+
-+ skb_queue_purge(&conn->data_q);
-+
-+ hci_dev_put(hdev);
-+
-+ kfree(conn);
-+ return 0;
-+}
-+
-+struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
-+{
-+ int use_src = bacmp(src, BDADDR_ANY);
-+ struct hci_dev *hdev = NULL;
-+ struct list_head *p;
-+
-+ BT_DBG("%s -> %s", batostr(src), batostr(dst));
-+
-+ read_lock_bh(&hdev_list_lock);
-+
-+ list_for_each(p, &hdev_list) {
-+ struct hci_dev *d;
-+ d = list_entry(p, struct hci_dev, list);
-+
-+ if (!test_bit(HCI_UP, &d->flags))
-+ continue;
-+
-+ /* Simple routing:
-+ * No source address - find interface with bdaddr != dst
-+ * Source address - find interface with bdaddr == src
-+ */
-+
-+ if (use_src) {
-+ if (!bacmp(&d->bdaddr, src)) {
-+ hdev = d; break;
-+ }
-+ } else {
-+ if (bacmp(&d->bdaddr, dst)) {
-+ hdev = d; break;
-+ }
-+ }
-+ }
-+
-+ if (hdev)
-+ hci_dev_hold(hdev);
-+
-+ read_unlock_bh(&hdev_list_lock);
-+ return hdev;
-+}
-+
-+/* Create SCO or ACL connection.
-+ * Device _must_ be locked */
-+struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
-+{
-+ struct hci_conn *acl;
-+
-+ BT_DBG("%s dst %s", hdev->name, batostr(dst));
-+
-+ if (!(acl = conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
-+ if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
-+ return NULL;
-+ }
-+
-+ hci_conn_hold(acl);
-+
-+ if (acl->state == BT_OPEN || acl->state == BT_CLOSED)
-+ hci_acl_connect(acl);
-+
-+ if (type == SCO_LINK) {
-+ struct hci_conn *sco;
-+
-+ if (!(sco = conn_hash_lookup_ba(hdev, SCO_LINK, dst))) {
-+ if (!(sco = hci_conn_add(hdev, SCO_LINK, dst))) {
-+ hci_conn_put(acl);
-+ return NULL;
-+ }
-+ }
-+ acl->link = sco;
-+ sco->link = acl;
-+
-+ hci_conn_hold(sco);
-+
-+ if (acl->state == BT_CONNECTED &&
-+ (sco->state == BT_OPEN || sco->state == BT_CLOSED))
-+ hci_add_sco(sco, acl->handle);
-+
-+ return sco;
-+ } else {
-+ return acl;
-+ }
-+}
-+
-+/* Authenticate remote device */
-+int hci_conn_auth(struct hci_conn *conn)
-+{
-+ BT_DBG("conn %p", conn);
-+
-+ if (conn->link_mode & HCI_LM_AUTH)
-+ return 1;
-+
-+ if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
-+ auth_requested_cp ar;
-+ ar.handle = __cpu_to_le16(conn->handle);
-+ hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_AUTH_REQUESTED,
-+ AUTH_REQUESTED_CP_SIZE, &ar);
-+ }
-+ return 0;
-+}
-+
-+/* Enable encryption */
-+int hci_conn_encrypt(struct hci_conn *conn)
-+{
-+ BT_DBG("conn %p", conn);
-+
-+ if (conn->link_mode & HCI_LM_ENCRYPT)
-+ return 1;
-+
-+ if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
-+ return 0;
-+
-+ if (hci_conn_auth(conn)) {
-+ set_conn_encrypt_cp ce;
-+ ce.handle = __cpu_to_le16(conn->handle);
-+ ce.encrypt = 1;
-+ hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT,
-+ SET_CONN_ENCRYPT_CP_SIZE, &ce);
-+ }
-+ return 0;
-+}
-+
-+/* Drop all connection on the device */
-+void hci_conn_hash_flush(struct hci_dev *hdev)
-+{
-+ struct conn_hash *h = &hdev->conn_hash;
-+ struct list_head *p;
-+
-+ BT_DBG("hdev %s", hdev->name);
-+
-+ p = h->list.next;
-+ while (p != &h->list) {
-+ struct hci_conn *c;
-+
-+ c = list_entry(p, struct hci_conn, list);
-+ p = p->next;
-+
-+ c->state = BT_CLOSED;
-+
-+ hci_proto_disconn_ind(c, 0x16);
-+ hci_conn_del(c);
-+ }
-+}
-+
-+int hci_get_conn_list(unsigned long arg)
-+{
-+ struct hci_conn_list_req req, *cl;
-+ struct hci_conn_info *ci;
-+ struct hci_dev *hdev;
-+ struct list_head *p;
-+ int n = 0, size, err;
-+
-+ if (copy_from_user(&req, (void *) arg, sizeof(req)))
-+ return -EFAULT;
-+
-+ if (!req.conn_num || req.conn_num > (PAGE_SIZE * 2) / sizeof(*ci))
-+ return -EINVAL;
-+
-+ size = sizeof(req) + req.conn_num * sizeof(*ci);
-+
-+ if (!(cl = (void *) kmalloc(size, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ if (!(hdev = hci_dev_get(req.dev_id))) {
-+ kfree(cl);
-+ return -ENODEV;
-+ }
-+
-+ ci = cl->conn_info;
-+
-+ hci_dev_lock_bh(hdev);
-+ list_for_each(p, &hdev->conn_hash.list) {
-+ register struct hci_conn *c;
-+ c = list_entry(p, struct hci_conn, list);
-+
-+ bacpy(&(ci + n)->bdaddr, &c->dst);
-+ (ci + n)->handle = c->handle;
-+ (ci + n)->type = c->type;
-+ (ci + n)->out = c->out;
-+ (ci + n)->state = c->state;
-+ (ci + n)->link_mode = c->link_mode;
-+ if (++n >= req.conn_num)
-+ break;
-+ }
-+ hci_dev_unlock_bh(hdev);
-+
-+ cl->dev_id = hdev->id;
-+ cl->conn_num = n;
-+ size = sizeof(req) + n * sizeof(*ci);
-+
-+ hci_dev_put(hdev);
-+
-+ err = copy_to_user((void *) arg, cl, size);
-+ kfree(cl);
-+
-+ return err ? -EFAULT : 0;
-+}
-+
-+int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg)
-+{
-+ struct hci_conn_info_req req;
-+ struct hci_conn_info ci;
-+ struct hci_conn *conn;
-+ char *ptr = (void *) arg + sizeof(req);
-+
-+ if (copy_from_user(&req, (void *) arg, sizeof(req)))
-+ return -EFAULT;
-+
-+ hci_dev_lock_bh(hdev);
-+ conn = conn_hash_lookup_ba(hdev, req.type, &req.bdaddr);
-+ if (conn) {
-+ bacpy(&ci.bdaddr, &conn->dst);
-+ ci.handle = conn->handle;
-+ ci.type = conn->type;
-+ ci.out = conn->out;
-+ ci.state = conn->state;
-+ ci.link_mode = conn->link_mode;
-+ }
-+ hci_dev_unlock_bh(hdev);
-+
-+ if (!conn)
-+ return -ENOENT;
-+
-+ return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0;
-+}
-diff -urN linux-2.4.18/net/bluetooth/hci_core.c linux-2.4.18-mh15/net/bluetooth/hci_core.c
---- linux-2.4.18/net/bluetooth/hci_core.c 2001-11-09 23:21:21.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/hci_core.c 2004-08-01 16:26:23.000000000 +0200
-@@ -25,11 +25,12 @@
- /*
- * BlueZ HCI Core.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
- #include <linux/module.h>
-+#include <linux/kmod.h>
-
- #include <linux/types.h>
- #include <linux/errno.h>
-@@ -50,12 +51,11 @@
- #include <asm/unaligned.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
-
- #ifndef HCI_CORE_DEBUG
--#undef DBG
--#define DBG( A... )
-+#undef BT_DBG
-+#define BT_DBG( A... )
- #endif
-
- static void hci_cmd_task(unsigned long arg);
-@@ -63,279 +63,69 @@
- static void hci_tx_task(unsigned long arg);
- static void hci_notify(struct hci_dev *hdev, int event);
-
--static rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
-+rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
-
- /* HCI device list */
--struct hci_dev *hdev_list[HCI_MAX_DEV];
--spinlock_t hdev_list_lock;
--#define GET_HDEV(a) (hdev_list[a])
--
--/* HCI protocol list */
--struct hci_proto *hproto_list[HCI_MAX_PROTO];
--#define GET_HPROTO(a) (hproto_list[a])
-+LIST_HEAD(hdev_list);
-+rwlock_t hdev_list_lock = RW_LOCK_UNLOCKED;
-
--/* HCI notifiers list */
--struct notifier_block *hci_dev_notifier;
--
--/* HCI device notifications */
--int hci_register_notifier(struct notifier_block *nb)
--{
-- int err, i;
-- struct hci_dev *hdev;
--
-- if ((err = notifier_chain_register(&hci_dev_notifier, nb)))
-- return err;
--
-- /* Notify about already registered devices */
-- spin_lock(&hdev_list_lock);
-- for (i = 0; i < HCI_MAX_DEV; i++) {
-- if (!(hdev = GET_HDEV(i)))
-- continue;
-- if (hdev->flags & HCI_UP)
-- (*nb->notifier_call)(nb, HCI_DEV_UP, hdev);
-- }
-- spin_unlock(&hdev_list_lock);
--
-- return 0;
--}
--
--int hci_unregister_notifier(struct notifier_block *nb)
--{
-- return notifier_chain_unregister(&hci_dev_notifier, nb);
--}
--
--static inline void hci_notify(struct hci_dev *hdev, int event)
--{
-- notifier_call_chain(&hci_dev_notifier, event, hdev);
--}
--
--/* Get HCI device by index (device is locked on return)*/
--struct hci_dev *hci_dev_get(int index)
--{
-- struct hci_dev *hdev;
-- DBG("%d", index);
--
-- if (index < 0 || index >= HCI_MAX_DEV)
-- return NULL;
--
-- spin_lock(&hdev_list_lock);
-- if ((hdev = GET_HDEV(index)))
-- hci_dev_hold(hdev);
-- spin_unlock(&hdev_list_lock);
--
-- return hdev;
--}
--
--/* Flush inquiry cache */
--void inquiry_cache_flush(struct inquiry_cache *cache)
--{
-- struct inquiry_entry *next = cache->list, *e;
--
-- DBG("cache %p", cache);
--
-- cache->list = NULL;
-- while ((e = next)) {
-- next = e->next;
-- kfree(e);
-- }
--}
--
--/* Lookup by bdaddr.
-- * Cache must be locked. */
--static struct inquiry_entry * __inquiry_cache_lookup(struct inquiry_cache *cache, bdaddr_t *bdaddr)
--{
-- struct inquiry_entry *e;
--
-- DBG("cache %p, %s", cache, batostr(bdaddr));
--
-- for (e = cache->list; e; e = e->next)
-- if (!bacmp(&e->info.bdaddr, bdaddr))
-- break;
--
-- return e;
--}
--
--static void inquiry_cache_update(struct inquiry_cache *cache, inquiry_info *info)
--{
-- struct inquiry_entry *e;
--
-- DBG("cache %p, %s", cache, batostr(&info->bdaddr));
--
-- inquiry_cache_lock(cache);
--
-- if (!(e = __inquiry_cache_lookup(cache, &info->bdaddr))) {
-- /* Entry not in the cache. Add new one. */
-- if (!(e = kmalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
-- goto unlock;
-- memset(e, 0, sizeof(struct inquiry_entry));
-- e->next = cache->list;
-- cache->list = e;
-- }
--
-- memcpy(&e->info, info, sizeof(inquiry_info));
-- e->timestamp = jiffies;
-- cache->timestamp = jiffies;
--unlock:
-- inquiry_cache_unlock(cache);
--}
--
--static int inquiry_cache_dump(struct inquiry_cache *cache, int num, __u8 *buf)
--{
-- inquiry_info *info = (inquiry_info *) buf;
-- struct inquiry_entry *e;
-- int copied = 0;
-+/* HCI protocols */
-+#define HCI_MAX_PROTO 2
-+struct hci_proto *hci_proto[HCI_MAX_PROTO];
-
-- inquiry_cache_lock(cache);
--
-- for (e = cache->list; e && copied < num; e = e->next, copied++)
-- memcpy(info++, &e->info, sizeof(inquiry_info));
-+/* HCI notifiers list */
-+static struct notifier_block *hci_notifier;
-
-- inquiry_cache_unlock(cache);
-
-- DBG("cache %p, copied %d", cache, copied);
-- return copied;
--}
-+/* ---- HCI notifications ---- */
-
--/* --------- BaseBand connections --------- */
--static struct hci_conn *hci_conn_add(struct hci_dev *hdev, __u16 handle, __u8 type, bdaddr_t *dst)
-+int hci_register_notifier(struct notifier_block *nb)
- {
-- struct hci_conn *conn;
--
-- DBG("%s handle %d dst %s", hdev->name, handle, batostr(dst));
--
-- if ( conn_hash_lookup(&hdev->conn_hash, handle)) {
-- ERR("%s handle 0x%x already exists", hdev->name, handle);
-- return NULL;
-- }
--
-- if (!(conn = kmalloc(sizeof(struct hci_conn), GFP_ATOMIC)))
-- return NULL;
-- memset(conn, 0, sizeof(struct hci_conn));
--
-- bacpy(&conn->dst, dst);
-- conn->handle = handle;
-- conn->type = type;
-- conn->hdev = hdev;
--
-- skb_queue_head_init(&conn->data_q);
--
-- hci_dev_hold(hdev);
-- conn_hash_add(&hdev->conn_hash, handle, conn);
--
-- return conn;
-+ return notifier_chain_register(&hci_notifier, nb);
- }
-
--static int hci_conn_del(struct hci_dev *hdev, struct hci_conn *conn)
-+int hci_unregister_notifier(struct notifier_block *nb)
- {
-- DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
--
-- conn_hash_del(&hdev->conn_hash, conn);
-- hci_dev_put(hdev);
--
-- /* Unacked frames */
-- hdev->acl_cnt += conn->sent;
--
-- skb_queue_purge(&conn->data_q);
--
-- kfree(conn);
-- return 0;
-+ return notifier_chain_unregister(&hci_notifier, nb);
- }
-
--/* Drop all connection on the device */
--static void hci_conn_hash_flush(struct hci_dev *hdev)
-+void hci_notify(struct hci_dev *hdev, int event)
- {
-- struct conn_hash *h = &hdev->conn_hash;
-- struct hci_proto *hp;
-- struct list_head *p;
--
-- DBG("hdev %s", hdev->name);
--
-- p = h->list.next;
-- while (p != &h->list) {
-- struct hci_conn *c;
--
-- c = list_entry(p, struct hci_conn, list);
-- p = p->next;
--
-- if (c->type == ACL_LINK) {
-- /* ACL link notify L2CAP layer */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
-- hp->disconn_ind(c, 0x16);
-- } else {
-- /* SCO link (no notification) */
-- }
--
-- hci_conn_del(hdev, c);
-- }
-+ notifier_call_chain(&hci_notifier, event, hdev);
- }
-
--int hci_connect(struct hci_dev *hdev, bdaddr_t *bdaddr)
--{
-- struct inquiry_cache *cache = &hdev->inq_cache;
-- struct inquiry_entry *e;
-- create_conn_cp cc;
-- __u16 clock_offset;
--
-- DBG("%s bdaddr %s", hdev->name, batostr(bdaddr));
--
-- if (!(hdev->flags & HCI_UP))
-- return -ENODEV;
--
-- inquiry_cache_lock_bh(cache);
--
-- if (!(e = __inquiry_cache_lookup(cache, bdaddr)) || inquiry_entry_age(e) > INQUIRY_ENTRY_AGE_MAX) {
-- cc.pscan_rep_mode = 0;
-- cc.pscan_mode = 0;
-- clock_offset = 0;
-- } else {
-- cc.pscan_rep_mode = e->info.pscan_rep_mode;
-- cc.pscan_mode = e->info.pscan_mode;
-- clock_offset = __le16_to_cpu(e->info.clock_offset) & 0x8000;
-- }
--
-- inquiry_cache_unlock_bh(cache);
--
-- bacpy(&cc.bdaddr, bdaddr);
-- cc.pkt_type = __cpu_to_le16(hdev->pkt_type);
-- cc.clock_offset = __cpu_to_le16(clock_offset);
--
-- if (lmp_rswitch_capable(hdev))
-- cc.role_switch = 0x01;
-- else
-- cc.role_switch = 0x00;
--
-- hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, CREATE_CONN_CP_SIZE, &cc);
-+/* ---- HCI hotplug support ---- */
-
-- return 0;
--}
-+#ifdef CONFIG_HOTPLUG
-
--int hci_disconnect(struct hci_conn *conn, __u8 reason)
-+static int hci_run_hotplug(char *dev, char *action)
- {
-- disconnect_cp dc;
--
-- DBG("conn %p handle %d", conn, conn->handle);
-+ char *argv[3], *envp[5], dstr[20], astr[32];
-
-- dc.handle = __cpu_to_le16(conn->handle);
-- dc.reason = reason;
-- hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT, DISCONNECT_CP_SIZE, &dc);
-+ sprintf(dstr, "DEVICE=%s", dev);
-+ sprintf(astr, "ACTION=%s", action);
-
-- return 0;
--}
-+ argv[0] = hotplug_path;
-+ argv[1] = "bluetooth";
-+ argv[2] = NULL;
-
--/* --------- HCI request handling ------------ */
--static inline void hci_req_lock(struct hci_dev *hdev)
--{
-- down(&hdev->req_lock);
-+ envp[0] = "HOME=/";
-+ envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-+ envp[2] = dstr;
-+ envp[3] = astr;
-+ envp[4] = NULL;
-+
-+ return call_usermodehelper(argv[0], argv, envp);
- }
-+#else
-+#define hci_run_hotplug(A...)
-+#endif
-
--static inline void hci_req_unlock(struct hci_dev *hdev)
--{
-- up(&hdev->req_lock);
--}
-+/* ---- HCI requests ---- */
-
--static inline void hci_req_complete(struct hci_dev *hdev, int result)
-+void hci_req_complete(struct hci_dev *hdev, int result)
- {
-- DBG("%s result 0x%2.2x", hdev->name, result);
-+ BT_DBG("%s result 0x%2.2x", hdev->name, result);
-
- if (hdev->req_status == HCI_REQ_PEND) {
- hdev->req_result = result;
-@@ -344,9 +134,9 @@
- }
- }
-
--static inline void hci_req_cancel(struct hci_dev *hdev, int err)
-+void hci_req_cancel(struct hci_dev *hdev, int err)
- {
-- DBG("%s err 0x%2.2x", hdev->name, err);
-+ BT_DBG("%s err 0x%2.2x", hdev->name, err);
-
- if (hdev->req_status == HCI_REQ_PEND) {
- hdev->req_result = err;
-@@ -356,23 +146,22 @@
- }
-
- /* Execute request and wait for completion. */
--static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
-- unsigned long opt, __u32 timeout)
-+static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), unsigned long opt, __u32 timeout)
- {
- DECLARE_WAITQUEUE(wait, current);
- int err = 0;
-
-- DBG("%s start", hdev->name);
-+ BT_DBG("%s start", hdev->name);
-
- hdev->req_status = HCI_REQ_PEND;
-
- add_wait_queue(&hdev->req_wait_q, &wait);
-- current->state = TASK_INTERRUPTIBLE;
-+ set_current_state(TASK_INTERRUPTIBLE);
-
- req(hdev, opt);
- schedule_timeout(timeout);
-
-- current->state = TASK_RUNNING;
-+ set_current_state(TASK_RUNNING);
- remove_wait_queue(&hdev->req_wait_q, &wait);
-
- if (signal_pending(current))
-@@ -394,7 +183,7 @@
-
- hdev->req_status = hdev->req_result = 0;
-
-- DBG("%s end: err %d", hdev->name, err);
-+ BT_DBG("%s end: err %d", hdev->name, err);
-
- return err;
- }
-@@ -412,10 +201,9 @@
- return ret;
- }
-
--/* --------- HCI requests ---------- */
- static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
- {
-- DBG("%s %ld", hdev->name, opt);
-+ BT_DBG("%s %ld", hdev->name, opt);
-
- /* Reset device */
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
-@@ -423,27 +211,44 @@
-
- static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
- {
-- set_event_flt_cp ec;
-+ set_event_flt_cp ef;
- __u16 param;
-
-- DBG("%s %ld", hdev->name, opt);
-+ BT_DBG("%s %ld", hdev->name, opt);
-
- /* Mandatory initialization */
-
-+ /* Reset */
-+ if (test_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks))
-+ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
-+
- /* Read Local Supported Features */
- hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES, 0, NULL);
-
- /* Read Buffer Size (ACL mtu, max pkt, etc.) */
- hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
-
-+#if 0
-+ /* Host buffer size */
-+ {
-+ host_buffer_size_cp bs;
-+ bs.acl_mtu = __cpu_to_le16(HCI_MAX_ACL_SIZE);
-+ bs.sco_mtu = HCI_MAX_SCO_SIZE;
-+ bs.acl_max_pkt = __cpu_to_le16(0xffff);
-+ bs.sco_max_pkt = __cpu_to_le16(0xffff);
-+ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_HOST_BUFFER_SIZE,
-+ HOST_BUFFER_SIZE_CP_SIZE, &bs);
-+ }
-+#endif
-+
- /* Read BD Address */
- hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, NULL);
-
- /* Optional initialization */
-
- /* Clear Event Filters */
-- ec.flt_type = FLT_CLEAR_ALL;
-- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &ec);
-+ ef.flt_type = FLT_CLEAR_ALL;
-+ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &ef);
-
- /* Page timeout ~20 secs */
- param = __cpu_to_le16(0x8000);
-@@ -458,7 +263,7 @@
- {
- __u8 scan = opt;
-
-- DBG("%s %x", hdev->name, scan);
-+ BT_DBG("%s %x", hdev->name, scan);
-
- /* Inquiry and Page scans */
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, &scan);
-@@ -468,116 +273,273 @@
- {
- __u8 auth = opt;
-
-- DBG("%s %x", hdev->name, auth);
-+ BT_DBG("%s %x", hdev->name, auth);
-
- /* Authentication */
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE, 1, &auth);
- }
-
--static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
-+static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
- {
-- struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
-- inquiry_cp ic;
-+ __u8 encrypt = opt;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s %x", hdev->name, encrypt);
-
-- /* Start Inquiry */
-- memcpy(&ic.lap, &ir->lap, 3);
-- ic.lenght = ir->length;
-- ic.num_rsp = ir->num_rsp;
-- hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, &ic);
-+ /* Authentication */
-+ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE, 1, &encrypt);
- }
-
--/* HCI ioctl helpers */
--int hci_dev_open(__u16 dev)
-+/* Get HCI device by index.
-+ * Device is locked on return. */
-+struct hci_dev *hci_dev_get(int index)
- {
- struct hci_dev *hdev;
-- int ret = 0;
--
-- if (!(hdev = hci_dev_get(dev)))
-- return -ENODEV;
-+ struct list_head *p;
-
-- DBG("%s %p", hdev->name, hdev);
-+ BT_DBG("%d", index);
-
-- hci_req_lock(hdev);
-+ if (index < 0)
-+ return NULL;
-
-- if (hdev->flags & HCI_UP) {
-- ret = -EALREADY;
-- goto done;
-+ read_lock(&hdev_list_lock);
-+ list_for_each(p, &hdev_list) {
-+ hdev = list_entry(p, struct hci_dev, list);
-+ if (hdev->id == index) {
-+ hci_dev_hold(hdev);
-+ goto done;
-+ }
- }
-+ hdev = NULL;
-+done:
-+ read_unlock(&hdev_list_lock);
-+ return hdev;
-+}
-
-- if (hdev->open(hdev)) {
-- ret = -EIO;
-- goto done;
-- }
-+/* ---- Inquiry support ---- */
-+void inquiry_cache_flush(struct hci_dev *hdev)
-+{
-+ struct inquiry_cache *cache = &hdev->inq_cache;
-+ struct inquiry_entry *next = cache->list, *e;
-
-- if (hdev->flags & HCI_NORMAL) {
-- atomic_set(&hdev->cmd_cnt, 1);
-- hdev->flags |= HCI_INIT;
-+ BT_DBG("cache %p", cache);
-
-- //__hci_request(hdev, hci_reset_req, 0, HZ);
-- ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
--
-- hdev->flags &= ~HCI_INIT;
-+ cache->list = NULL;
-+ while ((e = next)) {
-+ next = e->next;
-+ kfree(e);
- }
-+}
-
-- if (!ret) {
-- hdev->flags |= HCI_UP;
-- hci_notify(hdev, HCI_DEV_UP);
-- } else {
-- /* Init failed, cleanup */
-- tasklet_kill(&hdev->rx_task);
-- tasklet_kill(&hdev->tx_task);
-- tasklet_kill(&hdev->cmd_task);
-+struct inquiry_entry *inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
-+{
-+ struct inquiry_cache *cache = &hdev->inq_cache;
-+ struct inquiry_entry *e;
-
-- skb_queue_purge(&hdev->cmd_q);
-- skb_queue_purge(&hdev->rx_q);
-+ BT_DBG("cache %p, %s", cache, batostr(bdaddr));
-
-- if (hdev->flush)
-- hdev->flush(hdev);
-+ for (e = cache->list; e; e = e->next)
-+ if (!bacmp(&e->info.bdaddr, bdaddr))
-+ break;
-+ return e;
-+}
-
-- if (hdev->sent_cmd) {
-- kfree_skb(hdev->sent_cmd);
-- hdev->sent_cmd = NULL;
-- }
-+void inquiry_cache_update(struct hci_dev *hdev, inquiry_info *info)
-+{
-+ struct inquiry_cache *cache = &hdev->inq_cache;
-+ struct inquiry_entry *e;
-
-- hdev->close(hdev);
-- }
-+ BT_DBG("cache %p, %s", cache, batostr(&info->bdaddr));
-
--done:
-- hci_req_unlock(hdev);
-- hci_dev_put(hdev);
-+ if (!(e = inquiry_cache_lookup(hdev, &info->bdaddr))) {
-+ /* Entry not in the cache. Add new one. */
-+ if (!(e = kmalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
-+ return;
-+ memset(e, 0, sizeof(struct inquiry_entry));
-+ e->next = cache->list;
-+ cache->list = e;
-+ }
-
-- return ret;
-+ memcpy(&e->info, info, sizeof(inquiry_info));
-+ e->timestamp = jiffies;
-+ cache->timestamp = jiffies;
- }
-
--int hci_dev_close(__u16 dev)
-+int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
- {
-- struct hci_dev *hdev;
--
-- if (!(hdev = hci_dev_get(dev)))
-- return -ENODEV;
-+ struct inquiry_cache *cache = &hdev->inq_cache;
-+ inquiry_info *info = (inquiry_info *) buf;
-+ struct inquiry_entry *e;
-+ int copied = 0;
-
-- DBG("%s %p", hdev->name, hdev);
-+ for (e = cache->list; e && copied < num; e = e->next, copied++)
-+ memcpy(info++, &e->info, sizeof(inquiry_info));
-
-- hci_req_cancel(hdev, ENODEV);
-- hci_req_lock(hdev);
-+ BT_DBG("cache %p, copied %d", cache, copied);
-+ return copied;
-+}
-
-- if (!(hdev->flags & HCI_UP))
-- goto done;
-+static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
-+{
-+ struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
-+ inquiry_cp ic;
-
-- /* Kill RX and TX tasks */
-- tasklet_kill(&hdev->rx_task);
-- tasklet_kill(&hdev->tx_task);
-+ BT_DBG("%s", hdev->name);
-
-- inquiry_cache_flush(&hdev->inq_cache);
-+ if (test_bit(HCI_INQUIRY, &hdev->flags))
-+ return;
-
-- hci_conn_hash_flush(hdev);
-+ /* Start Inquiry */
-+ memcpy(&ic.lap, &ir->lap, 3);
-+ ic.length = ir->length;
-+ ic.num_rsp = ir->num_rsp;
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, &ic);
-+}
-
-- /* Clear flags */
-- hdev->flags &= HCI_SOCK;
-- hdev->flags |= HCI_NORMAL;
-+int hci_inquiry(unsigned long arg)
-+{
-+ struct hci_inquiry_req ir;
-+ struct hci_dev *hdev;
-+ int err = 0, do_inquiry = 0, max_rsp;
-+ long timeo;
-+ __u8 *buf, *ptr;
-
-+ ptr = (void *) arg;
-+ if (copy_from_user(&ir, ptr, sizeof(ir)))
-+ return -EFAULT;
-+
-+ if (!(hdev = hci_dev_get(ir.dev_id)))
-+ return -ENODEV;
-+
-+ hci_dev_lock_bh(hdev);
-+ if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
-+ inquiry_cache_empty(hdev) ||
-+ ir.flags & IREQ_CACHE_FLUSH) {
-+ inquiry_cache_flush(hdev);
-+ do_inquiry = 1;
-+ }
-+ hci_dev_unlock_bh(hdev);
-+
-+ timeo = ir.length * 2 * HZ;
-+ if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
-+ goto done;
-+
-+ /* for unlimited number of responses we will use buffer with 255 entries */
-+ max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
-+
-+ /* cache_dump can't sleep. Therefore we allocate temp buffer and then
-+ * copy it to the user space.
-+ */
-+ if (!(buf = kmalloc(sizeof(inquiry_info) * max_rsp, GFP_KERNEL))) {
-+ err = -ENOMEM;
-+ goto done;
-+ }
-+
-+ hci_dev_lock_bh(hdev);
-+ ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
-+ hci_dev_unlock_bh(hdev);
-+
-+ BT_DBG("num_rsp %d", ir.num_rsp);
-+
-+ if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) +
-+ (sizeof(inquiry_info) * ir.num_rsp))) {
-+ copy_to_user(ptr, &ir, sizeof(ir));
-+ ptr += sizeof(ir);
-+ copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
-+ } else
-+ err = -EFAULT;
-+
-+ kfree(buf);
-+
-+done:
-+ hci_dev_put(hdev);
-+ return err;
-+}
-+
-+/* ---- HCI ioctl helpers ---- */
-+
-+int hci_dev_open(__u16 dev)
-+{
-+ struct hci_dev *hdev;
-+ int ret = 0;
-+
-+ if (!(hdev = hci_dev_get(dev)))
-+ return -ENODEV;
-+
-+ BT_DBG("%s %p", hdev->name, hdev);
-+
-+ hci_req_lock(hdev);
-+
-+ if (test_bit(HCI_UP, &hdev->flags)) {
-+ ret = -EALREADY;
-+ goto done;
-+ }
-+
-+ if (hdev->open(hdev)) {
-+ ret = -EIO;
-+ goto done;
-+ }
-+
-+ if (!test_bit(HCI_RAW, &hdev->flags)) {
-+ atomic_set(&hdev->cmd_cnt, 1);
-+ set_bit(HCI_INIT, &hdev->flags);
-+
-+ //__hci_request(hdev, hci_reset_req, 0, HZ);
-+ ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
-+
-+ clear_bit(HCI_INIT, &hdev->flags);
-+ }
-+
-+ if (!ret) {
-+ set_bit(HCI_UP, &hdev->flags);
-+ hci_notify(hdev, HCI_DEV_UP);
-+ } else {
-+ /* Init failed, cleanup */
-+ tasklet_kill(&hdev->rx_task);
-+ tasklet_kill(&hdev->tx_task);
-+ tasklet_kill(&hdev->cmd_task);
-+
-+ skb_queue_purge(&hdev->cmd_q);
-+ skb_queue_purge(&hdev->rx_q);
-+
-+ if (hdev->flush)
-+ hdev->flush(hdev);
-+
-+ if (hdev->sent_cmd) {
-+ kfree_skb(hdev->sent_cmd);
-+ hdev->sent_cmd = NULL;
-+ }
-+
-+ hdev->close(hdev);
-+ hdev->flags = 0;
-+ }
-+
-+done:
-+ hci_req_unlock(hdev);
-+ hci_dev_put(hdev);
-+ return ret;
-+}
-+
-+static int hci_dev_do_close(struct hci_dev *hdev)
-+{
-+ BT_DBG("%s %p", hdev->name, hdev);
-+
-+ hci_req_cancel(hdev, ENODEV);
-+ hci_req_lock(hdev);
-+
-+ if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
-+ hci_req_unlock(hdev);
-+ return 0;
-+ }
-+
-+ /* Kill RX and TX tasks */
-+ tasklet_kill(&hdev->rx_task);
-+ tasklet_kill(&hdev->tx_task);
-+
-+ hci_dev_lock_bh(hdev);
-+ inquiry_cache_flush(hdev);
-+ hci_conn_hash_flush(hdev);
-+ hci_dev_unlock_bh(hdev);
-+
- hci_notify(hdev, HCI_DEV_DOWN);
-
- if (hdev->flush)
-@@ -586,9 +548,9 @@
- /* Reset device */
- skb_queue_purge(&hdev->cmd_q);
- atomic_set(&hdev->cmd_cnt, 1);
-- hdev->flags |= HCI_INIT;
-- __hci_request(hdev, hci_reset_req, 0, HZ);
-- hdev->flags &= ~HCI_INIT;
-+ set_bit(HCI_INIT, &hdev->flags);
-+ __hci_request(hdev, hci_reset_req, 0, HZ/4);
-+ clear_bit(HCI_INIT, &hdev->flags);
-
- /* Kill cmd task */
- tasklet_kill(&hdev->cmd_task);
-@@ -605,17 +567,28 @@
- }
-
- /* After this point our queues are empty
-- * and no tasks are scheduled.
-- */
-+ * and no tasks are scheduled. */
- hdev->close(hdev);
-
--done:
-- hci_req_unlock(hdev);
-- hci_dev_put(hdev);
-+ /* Clear flags */
-+ hdev->flags = 0;
-
-+ hci_req_unlock(hdev);
- return 0;
- }
-
-+int hci_dev_close(__u16 dev)
-+{
-+ struct hci_dev *hdev;
-+ int err;
-+
-+ if (!(hdev = hci_dev_get(dev)))
-+ return -ENODEV;
-+ err = hci_dev_do_close(hdev);
-+ hci_dev_put(hdev);
-+ return err;
-+}
-+
- int hci_dev_reset(__u16 dev)
- {
- struct hci_dev *hdev;
-@@ -627,16 +600,17 @@
- hci_req_lock(hdev);
- tasklet_disable(&hdev->tx_task);
-
-- if (!(hdev->flags & HCI_UP))
-+ if (!test_bit(HCI_UP, &hdev->flags))
- goto done;
-
- /* Drop queues */
- skb_queue_purge(&hdev->rx_q);
- skb_queue_purge(&hdev->cmd_q);
-
-- inquiry_cache_flush(&hdev->inq_cache);
--
-+ hci_dev_lock_bh(hdev);
-+ inquiry_cache_flush(hdev);
- hci_conn_hash_flush(hdev);
-+ hci_dev_unlock_bh(hdev);
-
- if (hdev->flush)
- hdev->flush(hdev);
-@@ -650,7 +624,6 @@
- tasklet_enable(&hdev->tx_task);
- hci_req_unlock(hdev);
- hci_dev_put(hdev);
--
- return ret;
- }
-
-@@ -669,30 +642,11 @@
- return ret;
- }
-
--int hci_dev_setauth(unsigned long arg)
--{
-- struct hci_dev *hdev;
-- struct hci_dev_req dr;
-- int ret = 0;
--
-- if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
-- return -EFAULT;
--
-- if (!(hdev = hci_dev_get(dr.dev_id)))
-- return -ENODEV;
--
-- ret = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
--
-- hci_dev_put(hdev);
--
-- return ret;
--}
--
--int hci_dev_setscan(unsigned long arg)
-+int hci_dev_cmd(unsigned int cmd, unsigned long arg)
- {
- struct hci_dev *hdev;
- struct hci_dev_req dr;
-- int ret = 0;
-+ int err = 0;
-
- if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
- return -EFAULT;
-@@ -700,75 +654,105 @@
- if (!(hdev = hci_dev_get(dr.dev_id)))
- return -ENODEV;
-
-- ret = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
--
-- hci_dev_put(hdev);
-+ switch (cmd) {
-+ case HCISETAUTH:
-+ err = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
-+ break;
-
-- return ret;
--}
-+ case HCISETENCRYPT:
-+ if (!lmp_encrypt_capable(hdev)) {
-+ err = -EOPNOTSUPP;
-+ break;
-+ }
-
--int hci_dev_setptype(unsigned long arg)
--{
-- struct hci_dev *hdev;
-- struct hci_dev_req dr;
-- int ret = 0;
-+ if (!test_bit(HCI_AUTH, &hdev->flags)) {
-+ /* Auth must be enabled first */
-+ err = hci_request(hdev, hci_auth_req,
-+ dr.dev_opt, HCI_INIT_TIMEOUT);
-+ if (err)
-+ break;
-+ }
-+
-+ err = hci_request(hdev, hci_encrypt_req,
-+ dr.dev_opt, HCI_INIT_TIMEOUT);
-+ break;
-+
-+ case HCISETSCAN:
-+ err = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
-+ break;
-+
-+ case HCISETPTYPE:
-+ hdev->pkt_type = (__u16) dr.dev_opt;
-+ break;
-+
-+ case HCISETLINKPOL:
-+ hdev->link_policy = (__u16) dr.dev_opt;
-+ break;
-
-- if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
-- return -EFAULT;
-+ case HCISETLINKMODE:
-+ hdev->link_mode = ((__u16) dr.dev_opt) & (HCI_LM_MASTER | HCI_LM_ACCEPT);
-+ break;
-
-- if (!(hdev = hci_dev_get(dr.dev_id)))
-- return -ENODEV;
-+ case HCISETACLMTU:
-+ hdev->acl_mtu = *((__u16 *)&dr.dev_opt + 1);
-+ hdev->acl_pkts = *((__u16 *)&dr.dev_opt + 0);
-+ break;
-
-- hdev->pkt_type = (__u16) dr.dev_opt;
-+ case HCISETSCOMTU:
-+ hdev->sco_mtu = *((__u16 *)&dr.dev_opt + 1);
-+ hdev->sco_pkts = *((__u16 *)&dr.dev_opt + 0);
-+ break;
-
-+ default:
-+ err = -EINVAL;
-+ break;
-+ }
- hci_dev_put(hdev);
--
-- return ret;
-+ return err;
- }
-
--int hci_dev_list(unsigned long arg)
-+int hci_get_dev_list(unsigned long arg)
- {
- struct hci_dev_list_req *dl;
- struct hci_dev_req *dr;
-- struct hci_dev *hdev;
-- int i, n, size;
-+ struct list_head *p;
-+ int n = 0, size, err;
- __u16 dev_num;
-
- if (get_user(dev_num, (__u16 *) arg))
- return -EFAULT;
-
-- /* Avoid long loop, overflow */
-- if (dev_num > 2048)
-+ if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
- return -EINVAL;
--
-- size = dev_num * sizeof(struct hci_dev_req) + sizeof(__u16);
-
-- if (verify_area(VERIFY_WRITE, (void *) arg, size))
-- return -EFAULT;
-+ size = sizeof(*dl) + dev_num * sizeof(*dr);
-
- if (!(dl = kmalloc(size, GFP_KERNEL)))
- return -ENOMEM;
-+
- dr = dl->dev_req;
-
-- spin_lock_bh(&hdev_list_lock);
-- for (i = 0, n = 0; i < HCI_MAX_DEV && n < dev_num; i++) {
-- if ((hdev = hdev_list[i])) {
-- (dr + n)->dev_id = hdev->id;
-- (dr + n)->dev_opt = hdev->flags;
-- n++;
-- }
-+ read_lock_bh(&hdev_list_lock);
-+ list_for_each(p, &hdev_list) {
-+ struct hci_dev *hdev;
-+ hdev = list_entry(p, struct hci_dev, list);
-+ (dr + n)->dev_id = hdev->id;
-+ (dr + n)->dev_opt = hdev->flags;
-+ if (++n >= dev_num)
-+ break;
- }
-- spin_unlock_bh(&hdev_list_lock);
-+ read_unlock_bh(&hdev_list_lock);
-
- dl->dev_num = n;
-- size = n * sizeof(struct hci_dev_req) + sizeof(__u16);
-+ size = sizeof(*dl) + n * sizeof(*dr);
-
-- copy_to_user((void *) arg, dl, size);
-+ err = copy_to_user((void *) arg, dl, size);
-+ kfree(dl);
-
-- return 0;
-+ return err ? -EFAULT : 0;
- }
-
--int hci_dev_info(unsigned long arg)
-+int hci_get_dev_info(unsigned long arg)
- {
- struct hci_dev *hdev;
- struct hci_dev_info di;
-@@ -786,9 +770,11 @@
- di.flags = hdev->flags;
- di.pkt_type = hdev->pkt_type;
- di.acl_mtu = hdev->acl_mtu;
-- di.acl_max = hdev->acl_max;
-+ di.acl_pkts = hdev->acl_pkts;
- di.sco_mtu = hdev->sco_mtu;
-- di.sco_max = hdev->sco_max;
-+ di.sco_pkts = hdev->sco_pkts;
-+ di.link_policy = hdev->link_policy;
-+ di.link_mode = hdev->link_mode;
-
- memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
- memcpy(&di.features, &hdev->features, sizeof(di.features));
-@@ -801,258 +787,168 @@
- return err;
- }
-
--__u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode)
--{
-- __u32 omode = hdev->flags & HCI_MODE_MASK;
--
-- hdev->flags &= ~HCI_MODE_MASK;
-- hdev->flags |= (mode & HCI_MODE_MASK);
-
-- return omode;
--}
-+/* ---- Interface to HCI drivers ---- */
-
--__u32 hci_dev_getmode(struct hci_dev *hdev)
-+/* Register HCI device */
-+int hci_register_dev(struct hci_dev *hdev)
- {
-- return hdev->flags & HCI_MODE_MASK;
--}
-+ struct list_head *head = &hdev_list, *p;
-+ int id = 0;
-
--int hci_conn_list(unsigned long arg)
--{
-- struct hci_conn_list_req req, *cl;
-- struct hci_conn_info *ci;
-- struct hci_dev *hdev;
-- struct list_head *p;
-- int n = 0, size;
-+ BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
-
-- if (copy_from_user(&req, (void *) arg, sizeof(req)))
-- return -EFAULT;
-+ if (!hdev->open || !hdev->close || !hdev->destruct)
-+ return -EINVAL;
-
-- if (!(hdev = hci_dev_get(req.dev_id)))
-- return -ENODEV;
-+ write_lock_bh(&hdev_list_lock);
-
-- /* Set a limit to avoid overlong loops, and also numeric overflow - AC */
-- if(req.conn_num < 2048)
-- return -EINVAL;
-+ /* Find first available device id */
-+ list_for_each(p, &hdev_list) {
-+ if (list_entry(p, struct hci_dev, list)->id != id)
-+ break;
-+ head = p; id++;
-+ }
-
-- size = req.conn_num * sizeof(struct hci_conn_info) + sizeof(req);
-+ sprintf(hdev->name, "hci%d", id);
-+ hdev->id = id;
-+ list_add(&hdev->list, head);
-
-- if (!(cl = kmalloc(size, GFP_KERNEL)))
-- return -ENOMEM;
-- ci = cl->conn_info;
--
-- local_bh_disable();
-- conn_hash_lock(&hdev->conn_hash);
-- list_for_each(p, &hdev->conn_hash.list) {
-- register struct hci_conn *c;
-- c = list_entry(p, struct hci_conn, list);
-+ atomic_set(&hdev->refcnt, 1);
-+ spin_lock_init(&hdev->lock);
-+
-+ hdev->flags = 0;
-+ hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1);
-+ hdev->link_mode = (HCI_LM_ACCEPT);
-
-- (ci + n)->handle = c->handle;
-- bacpy(&(ci + n)->bdaddr, &c->dst);
-- n++;
-- }
-- conn_hash_unlock(&hdev->conn_hash);
-- local_bh_enable();
--
-- cl->dev_id = hdev->id;
-- cl->conn_num = n;
-- size = n * sizeof(struct hci_conn_info) + sizeof(req);
-+ tasklet_init(&hdev->cmd_task, hci_cmd_task,(unsigned long) hdev);
-+ tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
-+ tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
-
-- hci_dev_put(hdev);
-+ skb_queue_head_init(&hdev->rx_q);
-+ skb_queue_head_init(&hdev->cmd_q);
-+ skb_queue_head_init(&hdev->raw_q);
-
-- if(copy_to_user((void *) arg, cl, size))
-- return -EFAULT;
-- return 0;
--}
-+ init_waitqueue_head(&hdev->req_wait_q);
-+ init_MUTEX(&hdev->req_lock);
-
--int hci_inquiry(unsigned long arg)
--{
-- struct inquiry_cache *cache;
-- struct hci_inquiry_req ir;
-- struct hci_dev *hdev;
-- int err = 0, do_inquiry = 0;
-- long timeo;
-- __u8 *buf, *ptr;
-+ inquiry_cache_init(hdev);
-
-- ptr = (void *) arg;
-- if (copy_from_user(&ir, ptr, sizeof(ir)))
-- return -EFAULT;
-+ conn_hash_init(hdev);
-
-- if (!(hdev = hci_dev_get(ir.dev_id)))
-- return -ENODEV;
-+ memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
-
-- cache = &hdev->inq_cache;
-+ atomic_set(&hdev->promisc, 0);
-
-- inquiry_cache_lock(cache);
-- if (inquiry_cache_age(cache) > INQUIRY_CACHE_AGE_MAX || ir.flags & IREQ_CACHE_FLUSH) {
-- inquiry_cache_flush(cache);
-- do_inquiry = 1;
-- }
-- inquiry_cache_unlock(cache);
-+ MOD_INC_USE_COUNT;
-
-- /* Limit inquiry time, also avoid overflows */
-+ write_unlock_bh(&hdev_list_lock);
-
-- if(ir.length > 2048 || ir.num_rsp > 2048)
-- {
-- err = -EINVAL;
-- goto done;
-- }
-+ hci_notify(hdev, HCI_DEV_REG);
-+ hci_run_hotplug(hdev->name, "register");
-
-- timeo = ir.length * 2 * HZ;
-- if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
-- goto done;
-+ return id;
-+}
-
-- /* cache_dump can't sleep. Therefore we allocate temp buffer and then
-- * copy it to the user space.
-- */
-- if (!(buf = kmalloc(sizeof(inquiry_info) * ir.num_rsp, GFP_KERNEL))) {
-- err = -ENOMEM;
-- goto done;
-- }
-- ir.num_rsp = inquiry_cache_dump(cache, ir.num_rsp, buf);
-+/* Unregister HCI device */
-+int hci_unregister_dev(struct hci_dev *hdev)
-+{
-+ BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
-
-- DBG("num_rsp %d", ir.num_rsp);
-+ write_lock_bh(&hdev_list_lock);
-+ list_del(&hdev->list);
-+ write_unlock_bh(&hdev_list_lock);
-
-- if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) + (sizeof(inquiry_info) * ir.num_rsp))) {
-- copy_to_user(ptr, &ir, sizeof(ir));
-- ptr += sizeof(ir);
-- copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
-- } else
-- err = -EFAULT;
-+ hci_dev_do_close(hdev);
-
-- kfree(buf);
-+ hci_notify(hdev, HCI_DEV_UNREG);
-+ hci_run_hotplug(hdev->name, "unregister");
-
--done:
- hci_dev_put(hdev);
-
-- return err;
-+ MOD_DEC_USE_COUNT;
-+ return 0;
- }
-
--/* Interface to HCI drivers */
--
--/* Register HCI device */
--int hci_register_dev(struct hci_dev *hdev)
-+/* Suspend HCI device */
-+int hci_suspend_dev(struct hci_dev *hdev)
- {
-- int i;
-+ hci_notify(hdev, HCI_DEV_SUSPEND);
-+ hci_run_hotplug(hdev->name, "suspend");
-+ return 0;
-+}
-
-- DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
-+/* Resume HCI device */
-+int hci_resume_dev(struct hci_dev *hdev)
-+{
-+ hci_notify(hdev, HCI_DEV_RESUME);
-+ hci_run_hotplug(hdev->name, "resume");
-+ return 0;
-+}
-
-- /* Find free slot */
-- spin_lock_bh(&hdev_list_lock);
-- for (i = 0; i < HCI_MAX_DEV; i++) {
-- if (!hdev_list[i]) {
-- hdev_list[i] = hdev;
--
-- sprintf(hdev->name, "hci%d", i);
-- atomic_set(&hdev->refcnt, 0);
-- hdev->id = i;
-- hdev->flags = HCI_NORMAL;
--
-- hdev->pkt_type = (HCI_DM1 | HCI_DH1);
--
-- tasklet_init(&hdev->cmd_task, hci_cmd_task, (unsigned long) hdev);
-- tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
-- tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
--
-- skb_queue_head_init(&hdev->rx_q);
-- skb_queue_head_init(&hdev->cmd_q);
-- skb_queue_head_init(&hdev->raw_q);
--
-- init_waitqueue_head(&hdev->req_wait_q);
-- init_MUTEX(&hdev->req_lock);
--
-- inquiry_cache_init(&hdev->inq_cache);
--
-- conn_hash_init(&hdev->conn_hash);
--
-- memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
--
-- hci_notify(hdev, HCI_DEV_REG);
--
-- MOD_INC_USE_COUNT;
-- break;
-- }
-- }
-- spin_unlock_bh(&hdev_list_lock);
--
-- return (i == HCI_MAX_DEV) ? -1 : i;
--}
--
--/* Unregister HCI device */
--int hci_unregister_dev(struct hci_dev *hdev)
-+/* Receive frame from HCI drivers */
-+int hci_recv_frame(struct sk_buff *skb)
- {
-- int i;
--
-- DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
--
-- if (hdev->flags & HCI_UP)
-- hci_dev_close(hdev->id);
-+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-
-- /* Find device slot */
-- spin_lock(&hdev_list_lock);
-- for (i = 0; i < HCI_MAX_DEV; i++) {
-- if (hdev_list[i] == hdev) {
-- hdev_list[i] = NULL;
-- MOD_DEC_USE_COUNT;
-- break;
-- }
-+ if (!hdev || (!test_bit(HCI_UP, &hdev->flags) &&
-+ !test_bit(HCI_INIT, &hdev->flags)) ) {
-+ kfree_skb(skb);
-+ return -1;
- }
-- spin_unlock(&hdev_list_lock);
-
-- hci_notify(hdev, HCI_DEV_UNREG);
--
-- /* Sleep while device is in use */
-- while (atomic_read(&hdev->refcnt)) {
-- int sleep_cnt = 100;
-+ BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-
-- DBG("%s sleeping on lock %d", hdev->name, atomic_read(&hdev->refcnt));
-+ /* Incomming skb */
-+ bluez_cb(skb)->incomming = 1;
-
-- sleep_on_timeout(&hdev->req_wait_q, HZ*10);
-- if (!(--sleep_cnt))
-- break;
-- }
-+ /* Time stamp */
-+ do_gettimeofday(&skb->stamp);
-
-+ /* Queue frame for rx task */
-+ skb_queue_tail(&hdev->rx_q, skb);
-+ hci_sched_rx(hdev);
- return 0;
- }
-
--/* Interface to upper protocols */
-+/* ---- Interface to upper protocols ---- */
-
- /* Register/Unregister protocols.
-- * hci_task_lock is used to ensure that no tasks are running.
-- */
--int hci_register_proto(struct hci_proto *hproto)
-+ * hci_task_lock is used to ensure that no tasks are running. */
-+int hci_register_proto(struct hci_proto *hp)
- {
- int err = 0;
-
-- DBG("%p name %s", hproto, hproto->name);
-+ BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
-
-- if (hproto->id >= HCI_MAX_PROTO)
-+ if (hp->id >= HCI_MAX_PROTO)
- return -EINVAL;
-
- write_lock_bh(&hci_task_lock);
-
-- if (!hproto_list[hproto->id])
-- hproto_list[hproto->id] = hproto;
-+ if (!hci_proto[hp->id])
-+ hci_proto[hp->id] = hp;
- else
-- err = -1;
-+ err = -EEXIST;
-
- write_unlock_bh(&hci_task_lock);
-
- return err;
- }
-
--int hci_unregister_proto(struct hci_proto *hproto)
-+int hci_unregister_proto(struct hci_proto *hp)
- {
- int err = 0;
-
-- DBG("%p name %s", hproto, hproto->name);
-+ BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
-
-- if (hproto->id > HCI_MAX_PROTO)
-+ if (hp->id >= HCI_MAX_PROTO)
- return -EINVAL;
-
- write_lock_bh(&hci_task_lock);
-
-- if (hproto_list[hproto->id])
-- hproto_list[hproto->id] = NULL;
-+ if (hci_proto[hp->id])
-+ hci_proto[hp->id] = NULL;
- else
- err = -ENOENT;
-
-@@ -1070,10 +966,14 @@
- return -ENODEV;
- }
-
-- DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-+ BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-+
-+ if (atomic_read(&hdev->promisc)) {
-+ /* Time stamp */
-+ do_gettimeofday(&skb->stamp);
-
-- if (hdev->flags & HCI_SOCK)
- hci_send_to_sock(hdev, skb);
-+ }
-
- /* Get rid of skb owner, prior to sending to the driver. */
- skb_orphan(skb);
-@@ -1081,128 +981,6 @@
- return hdev->send(skb);
- }
-
--/* Connection scheduler */
--static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
--{
-- struct conn_hash *h = &hdev->conn_hash;
-- struct hci_conn *conn = NULL;
-- int num = 0, min = 0xffff;
-- struct list_head *p;
--
-- conn_hash_lock(h);
-- list_for_each(p, &h->list) {
-- register struct hci_conn *c;
--
-- c = list_entry(p, struct hci_conn, list);
--
-- if (c->type != type || skb_queue_empty(&c->data_q))
-- continue;
-- num++;
--
-- if (c->sent < min) {
-- min = c->sent;
-- conn = c;
-- }
-- }
-- conn_hash_unlock(h);
--
-- if (conn) {
-- int q = hdev->acl_cnt / num;
-- *quote = q ? q : 1;
-- } else
-- *quote = 0;
--
-- DBG("conn %p quote %d", conn, *quote);
--
-- return conn;
--}
--
--static inline void hci_sched_acl(struct hci_dev *hdev)
--{
-- struct hci_conn *conn;
-- struct sk_buff *skb;
-- int quote;
--
-- DBG("%s", hdev->name);
--
-- while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, &quote))) {
-- while (quote && (skb = skb_dequeue(&conn->data_q))) {
-- DBG("skb %p len %d", skb, skb->len);
--
-- hci_send_frame(skb);
--
-- conn->sent++;
-- hdev->acl_cnt--;
-- quote--;
-- }
-- }
--}
--
--/* Schedule SCO */
--static inline void hci_sched_sco(struct hci_dev *hdev)
--{
-- /* FIXME: For now we queue SCO packets to the raw queue
--
-- while (hdev->sco_cnt && (skb = skb_dequeue(&conn->data_q))) {
-- hci_send_frame(skb);
-- conn->sco_sent++;
-- hdev->sco_cnt--;
-- }
-- */
--}
--
--/* Get data from the previously sent command */
--static void * hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
--{
-- hci_command_hdr *hc;
--
-- if (!hdev->sent_cmd)
-- return NULL;
--
-- hc = (void *) hdev->sent_cmd->data;
--
-- if (hc->opcode != __cpu_to_le16(cmd_opcode_pack(ogf, ocf)))
-- return NULL;
--
-- DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
--
-- return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
--}
--
--/* Send raw HCI frame */
--int hci_send_raw(struct sk_buff *skb)
--{
-- struct hci_dev *hdev = (struct hci_dev *) skb->dev;
--
-- if (!hdev) {
-- kfree_skb(skb);
-- return -ENODEV;
-- }
--
-- DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
--
-- if (hdev->flags & HCI_NORMAL) {
-- /* Queue frame according it's type */
-- switch (skb->pkt_type) {
-- case HCI_COMMAND_PKT:
-- skb_queue_tail(&hdev->cmd_q, skb);
-- hci_sched_cmd(hdev);
-- return 0;
--
-- case HCI_ACLDATA_PKT:
-- case HCI_SCODATA_PKT:
-- /* FIXME:
-- * Check header here and queue to apropriate connection.
-- */
-- break;
-- }
-- }
--
-- skb_queue_tail(&hdev->raw_q, skb);
-- hci_sched_tx(hdev);
-- return 0;
--}
--
- /* Send HCI command */
- int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param)
- {
-@@ -1210,10 +988,10 @@
- hci_command_hdr *hc;
- struct sk_buff *skb;
-
-- DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
-+ BT_DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
-
- if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {
-- ERR("%s Can't allocate memory for HCI command", hdev->name);
-+ BT_ERR("%s Can't allocate memory for HCI command", hdev->name);
- return -ENOMEM;
- }
-
-@@ -1224,7 +1002,7 @@
- if (plen)
- memcpy(skb_put(skb, plen), param, plen);
-
-- DBG("skb len %d", skb->len);
-+ BT_DBG("skb len %d", skb->len);
-
- skb->pkt_type = HCI_COMMAND_PKT;
- skb->dev = (void *) hdev;
-@@ -1234,10 +1012,28 @@
- return 0;
- }
-
-+/* Get data from the previously sent command */
-+void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
-+{
-+ hci_command_hdr *hc;
-+
-+ if (!hdev->sent_cmd)
-+ return NULL;
-+
-+ hc = (void *) hdev->sent_cmd->data;
-+
-+ if (hc->opcode != __cpu_to_le16(cmd_opcode_pack(ogf, ocf)))
-+ return NULL;
-+
-+ BT_DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
-+
-+ return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
-+}
-+
- /* Send ACL data */
- static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
- {
-- int len = skb->len;
-+ int len = skb->len;
- hci_acl_hdr *ah;
-
- ah = (hci_acl_hdr *) skb_push(skb, HCI_ACL_HDR_SIZE);
-@@ -1252,7 +1048,7 @@
- struct hci_dev *hdev = conn->hdev;
- struct sk_buff *list;
-
-- DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
-+ BT_DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
-
- skb->dev = (void *) hdev;
- skb->pkt_type = HCI_ACLDATA_PKT;
-@@ -1260,12 +1056,12 @@
-
- if (!(list = skb_shinfo(skb)->frag_list)) {
- /* Non fragmented */
-- DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
-+ BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
-
- skb_queue_tail(&conn->data_q, skb);
- } else {
- /* Fragmented */
-- DBG("%s frag %p len %d", hdev->name, skb, skb->len);
-+ BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
-
- skb_shinfo(skb)->frag_list = NULL;
-
-@@ -1280,7 +1076,7 @@
- skb->pkt_type = HCI_ACLDATA_PKT;
- hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT);
-
-- DBG("%s frag %p len %d", hdev->name, skb, skb->len);
-+ BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
-
- __skb_queue_tail(&conn->data_q, skb);
- } while (list);
-@@ -1298,7 +1094,7 @@
- struct hci_dev *hdev = conn->hdev;
- hci_sco_hdr hs;
-
-- DBG("%s len %d", hdev->name, skb->len);
-+ BT_DBG("%s len %d", hdev->name, skb->len);
-
- if (skb->len > hdev->sco_mtu) {
- kfree_skb(skb);
-@@ -1315,544 +1111,136 @@
- skb->pkt_type = HCI_SCODATA_PKT;
- skb_queue_tail(&conn->data_q, skb);
- hci_sched_tx(hdev);
--
- return 0;
- }
-
--/* Handle HCI Event packets */
--
--/* Command Complete OGF LINK_CTL */
--static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
--{
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Complete OGF LINK_POLICY */
--static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
--{
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s: Command complete: ogf LINK_POLICY ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Complete OGF HOST_CTL */
--static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
--{
-- __u8 status, param;
-- void *sent;
--
--
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- case OCF_RESET:
-- status = *((__u8 *) skb->data);
--
-- hci_req_complete(hdev, status);
-- break;
--
-- case OCF_SET_EVENT_FLT:
-- status = *((__u8 *) skb->data);
--
-- if (status) {
-- DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
-- } else {
-- DBG("%s SET_EVENT_FLT succeseful", hdev->name);
-- }
-- break;
--
-- case OCF_WRITE_AUTH_ENABLE:
-- if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE)))
-- break;
--
-- status = *((__u8 *) skb->data);
-- param = *((__u8 *) sent);
--
-- if (!status) {
-- if (param == AUTH_ENABLED)
-- hdev->flags |= HCI_AUTH;
-- else
-- hdev->flags &= ~HCI_AUTH;
-- }
-- hci_req_complete(hdev, status);
-- break;
--
-- case OCF_WRITE_CA_TIMEOUT:
-- status = *((__u8 *) skb->data);
--
-- if (status) {
-- DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
-- } else {
-- DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
-- }
-- break;
--
-- case OCF_WRITE_PG_TIMEOUT:
-- status = *((__u8 *) skb->data);
--
-- if (status) {
-- DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
-- } else {
-- DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
-- }
-- break;
--
-- case OCF_WRITE_SCAN_ENABLE:
-- if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE)))
-- break;
-- status = *((__u8 *) skb->data);
-- param = *((__u8 *) sent);
--
-- DBG("param 0x%x", param);
--
-- if (!status) {
-- switch (param) {
-- case IS_ENA_PS_ENA:
-- hdev->flags |= HCI_PSCAN | HCI_ISCAN;
-- break;
--
-- case IS_ENA_PS_DIS:
-- hdev->flags &= ~HCI_PSCAN;
-- hdev->flags |= HCI_ISCAN;
-- break;
-+/* ---- HCI TX task (outgoing data) ---- */
-
-- case IS_DIS_PS_ENA:
-- hdev->flags &= ~HCI_ISCAN;
-- hdev->flags |= HCI_PSCAN;
-- break;
--
-- default:
-- hdev->flags &= ~(HCI_ISCAN | HCI_PSCAN);
-- break;
-- };
-- }
-- hci_req_complete(hdev, status);
-- break;
--
-- default:
-- DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Complete OGF INFO_PARAM */
--static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+/* HCI Connection scheduler */
-+static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
- {
-- read_local_features_rp *lf;
-- read_buffer_size_rp *bs;
-- read_bd_addr_rp *ba;
--
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- case OCF_READ_LOCAL_FEATURES:
-- lf = (read_local_features_rp *) skb->data;
--
-- if (lf->status) {
-- DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
-- break;
-- }
--
-- memcpy(hdev->features, lf->features, sizeof(hdev->features));
--
-- /* Adjust default settings according to features
-- * supported by device. */
-- if (hdev->features[0] & LMP_3SLOT)
-- hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
--
-- if (hdev->features[0] & LMP_5SLOT)
-- hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
--
-- DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
--
-- break;
--
-- case OCF_READ_BUFFER_SIZE:
-- bs = (read_buffer_size_rp *) skb->data;
--
-- if (bs->status) {
-- DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
-- break;
-- }
--
-- hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
-- hdev->sco_mtu = bs->sco_mtu;
-- hdev->acl_max = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
-- hdev->sco_max = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
--
-- DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
-- hdev->acl_mtu, hdev->sco_mtu, hdev->acl_max, hdev->sco_max);
-+ struct conn_hash *h = &hdev->conn_hash;
-+ struct hci_conn *conn = NULL;
-+ int num = 0, min = ~0;
-+ struct list_head *p;
-
-- break;
-+ /* We don't have to lock device here. Connections are always
-+ * added and removed with TX task disabled. */
-+ list_for_each(p, &h->list) {
-+ struct hci_conn *c;
-+ c = list_entry(p, struct hci_conn, list);
-
-- case OCF_READ_BD_ADDR:
-- ba = (read_bd_addr_rp *) skb->data;
-+ if (c->type != type || c->state != BT_CONNECTED
-+ || skb_queue_empty(&c->data_q))
-+ continue;
-+ num++;
-
-- if (!ba->status) {
-- bacpy(&hdev->bdaddr, &ba->bdaddr);
-- } else {
-- DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
-+ if (c->sent < min) {
-+ min = c->sent;
-+ conn = c;
- }
-+ }
-
-- hci_req_complete(hdev, ba->status);
-- break;
-+ if (conn) {
-+ int cnt = (type == ACL_LINK ? hdev->acl_cnt : hdev->sco_cnt);
-+ int q = cnt / num;
-+ *quote = q ? q : 1;
-+ } else
-+ *quote = 0;
-
-- default:
-- DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-- break;
-- };
-+ BT_DBG("conn %p quote %d", conn, *quote);
-+ return conn;
- }
-
--/* Command Status OGF LINK_CTL */
--static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+static inline void hci_acl_tx_to(struct hci_dev *hdev)
- {
-- struct hci_proto * hp;
--
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- case OCF_CREATE_CONN:
-- if (status) {
-- create_conn_cp *cc = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
--
-- if (!cc)
-- break;
--
-- DBG("%s Create connection error: status 0x%x %s", hdev->name,
-- status, batostr(&cc->bdaddr));
-+ struct conn_hash *h = &hdev->conn_hash;
-+ struct list_head *p;
-+ struct hci_conn *c;
-
-- /* Notify upper protocols */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm) {
-- tasklet_disable(&hdev->tx_task);
-- hp->connect_cfm(hdev, &cc->bdaddr, status, NULL);
-- tasklet_enable(&hdev->tx_task);
-- }
-- }
-- break;
-+ BT_ERR("%s ACL tx timeout", hdev->name);
-
-- case OCF_INQUIRY:
-- if (status) {
-- DBG("%s Inquiry error: status 0x%x", hdev->name, status);
-- hci_req_complete(hdev, status);
-+ /* Kill stalled connections */
-+ list_for_each(p, &h->list) {
-+ c = list_entry(p, struct hci_conn, list);
-+ if (c->type == ACL_LINK && c->sent) {
-+ BT_ERR("%s killing stalled ACL connection %s",
-+ hdev->name, batostr(&c->dst));
-+ hci_acl_disconn(c, 0x13);
- }
-- break;
--
-- default:
-- DBG("%s Command status: ogf LINK_CTL ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Status OGF LINK_POLICY */
--static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
--{
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Status OGF HOST_CTL */
--static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
--{
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Status OGF INFO_PARAM */
--static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
--{
-- DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Inquiry Complete */
--static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
--{
-- __u8 status = *((__u8 *) skb->data);
--
-- DBG("%s status %d", hdev->name, status);
--
-- hci_req_complete(hdev, status);
-+ }
- }
-
--/* Inquiry Result */
--static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+static inline void hci_sched_acl(struct hci_dev *hdev)
- {
-- inquiry_info *info = (inquiry_info *) (skb->data + 1);
-- int num_rsp = *((__u8 *) skb->data);
--
-- DBG("%s num_rsp %d", hdev->name, num_rsp);
-+ struct hci_conn *conn;
-+ struct sk_buff *skb;
-+ int quote;
-
-- for (; num_rsp; num_rsp--)
-- inquiry_cache_update(&hdev->inq_cache, info++);
--}
-+ BT_DBG("%s", hdev->name);
-
--/* Connect Request */
--static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
--{
-- evt_conn_request *cr = (evt_conn_request *) skb->data;
-- struct hci_proto *hp;
-- accept_conn_req_cp ac;
-- int accept = 0;
-+ /* ACL tx timeout must be longer than maximum
-+ * link supervision timeout (40.9 seconds) */
-+ if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45))
-+ hci_acl_tx_to(hdev);
-
-- DBG("%s Connection request: %s type 0x%x", hdev->name, batostr(&cr->bdaddr), cr->link_type);
-+ while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, &quote))) {
-+ while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
-+ BT_DBG("skb %p len %d", skb, skb->len);
-+ hci_send_frame(skb);
-+ hdev->acl_last_tx = jiffies;
-
-- /* Notify upper protocols */
-- if (cr->link_type == ACL_LINK) {
-- /* ACL link notify L2CAP */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_ind) {
-- tasklet_disable(&hdev->tx_task);
-- accept = hp->connect_ind(hdev, &cr->bdaddr);
-- tasklet_enable(&hdev->tx_task);
-+ hdev->acl_cnt--;
-+ conn->sent++;
- }
-- } else {
-- /* SCO link (no notification) */
-- /* FIXME: Should be accept it here or let the requester (app) accept it ? */
-- accept = 1;
-- }
--
-- if (accept) {
-- /* Connection accepted by upper layer */
-- bacpy(&ac.bdaddr, &cr->bdaddr);
-- ac.role = 0x01; /* Remain slave */
-- hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, ACCEPT_CONN_REQ_CP_SIZE, &ac);
-- } else {
-- /* Connection rejected by upper layer */
-- /* FIXME:
-- * Should we use HCI reject here ?
-- */
-- return;
- }
- }
-
--/* Connect Complete */
--static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+/* Schedule SCO */
-+static inline void hci_sched_sco(struct hci_dev *hdev)
- {
-- evt_conn_complete *cc = (evt_conn_complete *) skb->data;
-- struct hci_conn *conn = NULL;
-- struct hci_proto *hp;
--
-- DBG("%s", hdev->name);
--
-- tasklet_disable(&hdev->tx_task);
--
-- if (!cc->status)
-- conn = hci_conn_add(hdev, __le16_to_cpu(cc->handle), cc->link_type, &cc->bdaddr);
-+ struct hci_conn *conn;
-+ struct sk_buff *skb;
-+ int quote;
-
-- /* Notify upper protocols */
-- if (cc->link_type == ACL_LINK) {
-- /* ACL link notify L2CAP layer */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm)
-- hp->connect_cfm(hdev, &cc->bdaddr, cc->status, conn);
-- } else {
-- /* SCO link (no notification) */
-- }
-+ BT_DBG("%s", hdev->name);
-
-- tasklet_enable(&hdev->tx_task);
--}
-+ while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
-+ while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
-+ BT_DBG("skb %p len %d", skb, skb->len);
-+ hci_send_frame(skb);
-
--/* Disconnect Complete */
--static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
--{
-- evt_disconn_complete *dc = (evt_disconn_complete *) skb->data;
-- struct hci_conn *conn = NULL;
-- struct hci_proto *hp;
-- __u16 handle = __le16_to_cpu(dc->handle);
--
-- DBG("%s", hdev->name);
--
-- if (!dc->status && (conn = conn_hash_lookup(&hdev->conn_hash, handle))) {
-- tasklet_disable(&hdev->tx_task);
--
-- /* Notify upper protocols */
-- if (conn->type == ACL_LINK) {
-- /* ACL link notify L2CAP layer */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
-- hp->disconn_ind(conn, dc->reason);
-- } else {
-- /* SCO link (no notification) */
-+ conn->sent++;
-+ if (conn->sent == ~0)
-+ conn->sent = 0;
- }
--
-- hci_conn_del(hdev, conn);
--
-- tasklet_enable(&hdev->tx_task);
- }
- }
-
--/* Number of completed packets */
--static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+static void hci_tx_task(unsigned long arg)
- {
-- evt_num_comp_pkts *nc = (evt_num_comp_pkts *) skb->data;
-- __u16 *ptr;
-- int i;
--
-- skb_pull(skb, EVT_NUM_COMP_PKTS_SIZE);
--
-- DBG("%s num_hndl %d", hdev->name, nc->num_hndl);
-+ struct hci_dev *hdev = (struct hci_dev *) arg;
-+ struct sk_buff *skb;
-
-- if (skb->len < nc->num_hndl * 4) {
-- DBG("%s bad parameters", hdev->name);
-- return;
-- }
-+ read_lock(&hci_task_lock);
-
-- tasklet_disable(&hdev->tx_task);
-+ BT_DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
-
-- for (i = 0, ptr = (__u16 *) skb->data; i < nc->num_hndl; i++) {
-- struct hci_conn *conn;
-- __u16 handle, count;
-+ /* Schedule queues and send stuff to HCI driver */
-
-- handle = __le16_to_cpu(get_unaligned(ptr++));
-- count = __le16_to_cpu(get_unaligned(ptr++));
-+ hci_sched_acl(hdev);
-
-- hdev->acl_cnt += count;
-+ hci_sched_sco(hdev);
-
-- if ((conn = conn_hash_lookup(&hdev->conn_hash, handle)))
-- conn->sent -= count;
-- }
-+ /* Send next queued raw (unknown type) packet */
-+ while ((skb = skb_dequeue(&hdev->raw_q)))
-+ hci_send_frame(skb);
-
-- tasklet_enable(&hdev->tx_task);
--
-- hci_sched_tx(hdev);
-+ read_unlock(&hci_task_lock);
- }
-
--static inline void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
--{
-- hci_event_hdr *he = (hci_event_hdr *) skb->data;
-- evt_cmd_status *cs;
-- evt_cmd_complete *ec;
-- __u16 opcode, ocf, ogf;
--
-- skb_pull(skb, HCI_EVENT_HDR_SIZE);
--
-- DBG("%s evt 0x%x", hdev->name, he->evt);
--
-- switch (he->evt) {
-- case EVT_NUM_COMP_PKTS:
-- hci_num_comp_pkts_evt(hdev, skb);
-- break;
--
-- case EVT_INQUIRY_COMPLETE:
-- hci_inquiry_complete_evt(hdev, skb);
-- break;
-
-- case EVT_INQUIRY_RESULT:
-- hci_inquiry_result_evt(hdev, skb);
-- break;
--
-- case EVT_CONN_REQUEST:
-- hci_conn_request_evt(hdev, skb);
-- break;
--
-- case EVT_CONN_COMPLETE:
-- hci_conn_complete_evt(hdev, skb);
-- break;
--
-- case EVT_DISCONN_COMPLETE:
-- hci_disconn_complete_evt(hdev, skb);
-- break;
--
-- case EVT_CMD_STATUS:
-- cs = (evt_cmd_status *) skb->data;
-- skb_pull(skb, EVT_CMD_STATUS_SIZE);
--
-- opcode = __le16_to_cpu(cs->opcode);
-- ogf = cmd_opcode_ogf(opcode);
-- ocf = cmd_opcode_ocf(opcode);
--
-- switch (ogf) {
-- case OGF_INFO_PARAM:
-- hci_cs_info_param(hdev, ocf, cs->status);
-- break;
--
-- case OGF_HOST_CTL:
-- hci_cs_host_ctl(hdev, ocf, cs->status);
-- break;
--
-- case OGF_LINK_CTL:
-- hci_cs_link_ctl(hdev, ocf, cs->status);
-- break;
--
-- case OGF_LINK_POLICY:
-- hci_cs_link_policy(hdev, ocf, cs->status);
-- break;
--
-- default:
-- DBG("%s Command Status OGF %x", hdev->name, ogf);
-- break;
-- };
--
-- if (cs->ncmd) {
-- atomic_set(&hdev->cmd_cnt, 1);
-- if (!skb_queue_empty(&hdev->cmd_q))
-- hci_sched_cmd(hdev);
-- }
-- break;
--
-- case EVT_CMD_COMPLETE:
-- ec = (evt_cmd_complete *) skb->data;
-- skb_pull(skb, EVT_CMD_COMPLETE_SIZE);
--
-- opcode = __le16_to_cpu(ec->opcode);
-- ogf = cmd_opcode_ogf(opcode);
-- ocf = cmd_opcode_ocf(opcode);
--
-- switch (ogf) {
-- case OGF_INFO_PARAM:
-- hci_cc_info_param(hdev, ocf, skb);
-- break;
--
-- case OGF_HOST_CTL:
-- hci_cc_host_ctl(hdev, ocf, skb);
-- break;
--
-- case OGF_LINK_CTL:
-- hci_cc_link_ctl(hdev, ocf, skb);
-- break;
--
-- case OGF_LINK_POLICY:
-- hci_cc_link_policy(hdev, ocf, skb);
-- break;
--
-- default:
-- DBG("%s Command Completed OGF %x", hdev->name, ogf);
-- break;
-- };
--
-- if (ec->ncmd) {
-- atomic_set(&hdev->cmd_cnt, 1);
-- if (!skb_queue_empty(&hdev->cmd_q))
-- hci_sched_cmd(hdev);
-- }
-- break;
-- };
--
-- kfree_skb(skb);
-- hdev->stat.evt_rx++;
--}
-+/* ----- HCI RX task (incomming data proccessing) ----- */
-
- /* ACL data packet */
- static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
-@@ -1867,51 +1255,86 @@
- flags = acl_flags(handle);
- handle = acl_handle(handle);
-
-- DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
-+ BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
-+
-+ hdev->stat.acl_rx++;
-
-- if ((conn = conn_hash_lookup(&hdev->conn_hash, handle))) {
-+ hci_dev_lock(hdev);
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ hci_dev_unlock(hdev);
-+
-+ if (conn) {
- register struct hci_proto *hp;
-
- /* Send to upper protocol */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->recv_acldata) {
-+ if ((hp = hci_proto[HCI_PROTO_L2CAP]) && hp->recv_acldata) {
- hp->recv_acldata(conn, skb, flags);
-- goto sent;
-+ return;
- }
- } else {
-- ERR("%s ACL packet for unknown connection handle %d", hdev->name, handle);
-+ BT_ERR("%s ACL packet for unknown connection handle %d",
-+ hdev->name, handle);
- }
-
- kfree_skb(skb);
--sent:
-- hdev->stat.acl_rx++;
- }
-
- /* SCO data packet */
- static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
- {
-- DBG("%s len %d", hdev->name, skb->len);
-+ hci_sco_hdr *sh = (void *) skb->data;
-+ struct hci_conn *conn;
-+ __u16 handle;
-+
-+ skb_pull(skb, HCI_SCO_HDR_SIZE);
-+
-+ handle = __le16_to_cpu(sh->handle);
-+
-+ BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
-
-- kfree_skb(skb);
- hdev->stat.sco_rx++;
-+
-+ hci_dev_lock(hdev);
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ hci_dev_unlock(hdev);
-+
-+ if (conn) {
-+ register struct hci_proto *hp;
-+
-+ /* Send to upper protocol */
-+ if ((hp = hci_proto[HCI_PROTO_SCO]) && hp->recv_scodata) {
-+ hp->recv_scodata(conn, skb);
-+ return;
-+ }
-+ } else {
-+ BT_ERR("%s SCO packet for unknown connection handle %d",
-+ hdev->name, handle);
-+ }
-+
-+ kfree_skb(skb);
- }
-
--/* ----- HCI tasks ----- */
- void hci_rx_task(unsigned long arg)
- {
- struct hci_dev *hdev = (struct hci_dev *) arg;
- struct sk_buff *skb;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s", hdev->name);
-
- read_lock(&hci_task_lock);
-
- while ((skb = skb_dequeue(&hdev->rx_q))) {
-- if (hdev->flags & HCI_SOCK) {
-+ if (atomic_read(&hdev->promisc)) {
- /* Send copy to the sockets */
- hci_send_to_sock(hdev, skb);
- }
-
-- if (hdev->flags & HCI_INIT) {
-+ if (test_bit(HCI_RAW, &hdev->flags)) {
-+ kfree_skb(skb);
-+ continue;
-+ }
-+
-+ if (test_bit(HCI_INIT, &hdev->flags)) {
- /* Don't process data packets in this states. */
- switch (skb->pkt_type) {
- case HCI_ACLDATA_PKT:
-@@ -1921,64 +1344,43 @@
- };
- }
-
-- if (hdev->flags & HCI_NORMAL) {
-- /* Process frame */
-- switch (skb->pkt_type) {
-- case HCI_EVENT_PKT:
-- hci_event_packet(hdev, skb);
-- break;
-+ /* Process frame */
-+ switch (skb->pkt_type) {
-+ case HCI_EVENT_PKT:
-+ hci_event_packet(hdev, skb);
-+ break;
-
-- case HCI_ACLDATA_PKT:
-- DBG("%s ACL data packet", hdev->name);
-- hci_acldata_packet(hdev, skb);
-- break;
-+ case HCI_ACLDATA_PKT:
-+ BT_DBG("%s ACL data packet", hdev->name);
-+ hci_acldata_packet(hdev, skb);
-+ break;
-
-- case HCI_SCODATA_PKT:
-- DBG("%s SCO data packet", hdev->name);
-- hci_scodata_packet(hdev, skb);
-- break;
-+ case HCI_SCODATA_PKT:
-+ BT_DBG("%s SCO data packet", hdev->name);
-+ hci_scodata_packet(hdev, skb);
-+ break;
-
-- default:
-- kfree_skb(skb);
-- break;
-- };
-- } else {
-+ default:
- kfree_skb(skb);
-+ break;
- }
- }
-
- read_unlock(&hci_task_lock);
- }
-
--static void hci_tx_task(unsigned long arg)
--{
-- struct hci_dev *hdev = (struct hci_dev *) arg;
-- struct sk_buff *skb;
--
-- read_lock(&hci_task_lock);
--
-- DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
--
-- /* Schedule queues and send stuff to HCI driver */
--
-- hci_sched_acl(hdev);
--
-- hci_sched_sco(hdev);
--
-- /* Send next queued raw (unknown type) packet */
-- while ((skb = skb_dequeue(&hdev->raw_q)))
-- hci_send_frame(skb);
--
-- read_unlock(&hci_task_lock);
--}
--
- static void hci_cmd_task(unsigned long arg)
- {
- struct hci_dev *hdev = (struct hci_dev *) arg;
- struct sk_buff *skb;
-
-- DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
-+ BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
-
-+ if (!atomic_read(&hdev->cmd_cnt) && (jiffies - hdev->cmd_last_tx) > HZ) {
-+ BT_ERR("%s command tx timeout", hdev->name);
-+ atomic_set(&hdev->cmd_cnt, 1);
-+ }
-+
- /* Send queued commands */
- if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) {
- if (hdev->sent_cmd)
-@@ -1987,6 +1389,7 @@
- if ((hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC))) {
- atomic_dec(&hdev->cmd_cnt);
- hci_send_frame(skb);
-+ hdev->cmd_last_tx = jiffies;
- } else {
- skb_queue_head(&hdev->cmd_q, skb);
- hci_sched_cmd(hdev);
-@@ -1994,33 +1397,10 @@
- }
- }
-
--/* Receive frame from HCI drivers */
--int hci_recv_frame(struct sk_buff *skb)
--{
-- struct hci_dev *hdev = (struct hci_dev *) skb->dev;
--
-- if (!hdev || !(hdev->flags & (HCI_UP | HCI_INIT))) {
-- kfree_skb(skb);
-- return -1;
-- }
--
-- DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
--
-- /* Incomming skb */
-- bluez_cb(skb)->incomming = 1;
--
-- /* Queue frame for rx task */
-- skb_queue_tail(&hdev->rx_q, skb);
-- hci_sched_rx(hdev);
--
-- return 0;
--}
-+/* ---- Initialization ---- */
-
- int hci_core_init(void)
- {
-- /* Init locks */
-- spin_lock_init(&hdev_list_lock);
--
- return 0;
- }
-
-@@ -2028,5 +1408,3 @@
- {
- return 0;
- }
--
--MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/hci_event.c linux-2.4.18-mh15/net/bluetooth/hci_event.c
---- linux-2.4.18/net/bluetooth/hci_event.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/hci_event.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,910 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * HCI Events.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/notifier.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+#ifndef HCI_CORE_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+/* Handle HCI Event packets */
-+
-+/* Command Complete OGF LINK_CTL */
-+static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+{
-+ __u8 status;
-+
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_INQUIRY_CANCEL:
-+ status = *((__u8 *) skb->data);
-+
-+ if (status) {
-+ BT_DBG("%s Inquiry cancel error: status 0x%x", hdev->name, status);
-+ } else {
-+ clear_bit(HCI_INQUIRY, &hdev->flags);
-+ hci_req_complete(hdev, status);
-+ }
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Complete OGF LINK_POLICY */
-+static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+{
-+ struct hci_conn *conn;
-+ role_discovery_rp *rd;
-+
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_ROLE_DISCOVERY:
-+ rd = (void *) skb->data;
-+
-+ if (rd->status)
-+ break;
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_handle(hdev, __le16_to_cpu(rd->handle));
-+ if (conn) {
-+ if (rd->role)
-+ conn->link_mode &= ~HCI_LM_MASTER;
-+ else
-+ conn->link_mode |= HCI_LM_MASTER;
-+ }
-+
-+ hci_dev_unlock(hdev);
-+ break;
-+
-+ default:
-+ BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x",
-+ hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Complete OGF HOST_CTL */
-+static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+{
-+ __u8 status, param;
-+ void *sent;
-+
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_RESET:
-+ status = *((__u8 *) skb->data);
-+ hci_req_complete(hdev, status);
-+ break;
-+
-+ case OCF_SET_EVENT_FLT:
-+ status = *((__u8 *) skb->data);
-+ if (status) {
-+ BT_DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
-+ } else {
-+ BT_DBG("%s SET_EVENT_FLT succeseful", hdev->name);
-+ }
-+ break;
-+
-+ case OCF_WRITE_AUTH_ENABLE:
-+ sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE);
-+ if (!sent)
-+ break;
-+
-+ status = *((__u8 *) skb->data);
-+ param = *((__u8 *) sent);
-+
-+ if (!status) {
-+ if (param == AUTH_ENABLED)
-+ set_bit(HCI_AUTH, &hdev->flags);
-+ else
-+ clear_bit(HCI_AUTH, &hdev->flags);
-+ }
-+ hci_req_complete(hdev, status);
-+ break;
-+
-+ case OCF_WRITE_ENCRYPT_MODE:
-+ sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE);
-+ if (!sent)
-+ break;
-+
-+ status = *((__u8 *) skb->data);
-+ param = *((__u8 *) sent);
-+
-+ if (!status) {
-+ if (param)
-+ set_bit(HCI_ENCRYPT, &hdev->flags);
-+ else
-+ clear_bit(HCI_ENCRYPT, &hdev->flags);
-+ }
-+ hci_req_complete(hdev, status);
-+ break;
-+
-+ case OCF_WRITE_CA_TIMEOUT:
-+ status = *((__u8 *) skb->data);
-+ if (status) {
-+ BT_DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
-+ } else {
-+ BT_DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
-+ }
-+ break;
-+
-+ case OCF_WRITE_PG_TIMEOUT:
-+ status = *((__u8 *) skb->data);
-+ if (status) {
-+ BT_DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
-+ } else {
-+ BT_DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
-+ }
-+ break;
-+
-+ case OCF_WRITE_SCAN_ENABLE:
-+ sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE);
-+ if (!sent)
-+ break;
-+ status = *((__u8 *) skb->data);
-+ param = *((__u8 *) sent);
-+
-+ BT_DBG("param 0x%x", param);
-+
-+ if (!status) {
-+ clear_bit(HCI_PSCAN, &hdev->flags);
-+ clear_bit(HCI_ISCAN, &hdev->flags);
-+ if (param & SCAN_INQUIRY)
-+ set_bit(HCI_ISCAN, &hdev->flags);
-+
-+ if (param & SCAN_PAGE)
-+ set_bit(HCI_PSCAN, &hdev->flags);
-+ }
-+ hci_req_complete(hdev, status);
-+ break;
-+
-+ case OCF_HOST_BUFFER_SIZE:
-+ status = *((__u8 *) skb->data);
-+ if (status) {
-+ BT_DBG("%s OCF_BUFFER_SIZE failed %d", hdev->name, status);
-+ hci_req_complete(hdev, status);
-+ }
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Complete OGF INFO_PARAM */
-+static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+{
-+ read_local_features_rp *lf;
-+ read_buffer_size_rp *bs;
-+ read_bd_addr_rp *ba;
-+
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_READ_LOCAL_FEATURES:
-+ lf = (read_local_features_rp *) skb->data;
-+
-+ if (lf->status) {
-+ BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
-+ break;
-+ }
-+
-+ memcpy(hdev->features, lf->features, sizeof(hdev->features));
-+
-+ /* Adjust default settings according to features
-+ * supported by device. */
-+ if (hdev->features[0] & LMP_3SLOT)
-+ hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
-+
-+ if (hdev->features[0] & LMP_5SLOT)
-+ hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
-+
-+ if (hdev->features[1] & LMP_HV2)
-+ hdev->pkt_type |= (HCI_HV2);
-+
-+ if (hdev->features[1] & LMP_HV3)
-+ hdev->pkt_type |= (HCI_HV3);
-+
-+ BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
-+
-+ break;
-+
-+ case OCF_READ_BUFFER_SIZE:
-+ bs = (read_buffer_size_rp *) skb->data;
-+
-+ if (bs->status) {
-+ BT_DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
-+ hci_req_complete(hdev, bs->status);
-+ break;
-+ }
-+
-+ hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
-+ hdev->sco_mtu = bs->sco_mtu ? bs->sco_mtu : 64;
-+ hdev->acl_pkts = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
-+ hdev->sco_pkts = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
-+
-+ BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
-+ hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
-+ break;
-+
-+ case OCF_READ_BD_ADDR:
-+ ba = (read_bd_addr_rp *) skb->data;
-+
-+ if (!ba->status) {
-+ bacpy(&hdev->bdaddr, &ba->bdaddr);
-+ } else {
-+ BT_DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
-+ }
-+
-+ hci_req_complete(hdev, ba->status);
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Status OGF LINK_CTL */
-+static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
-+{
-+ struct hci_conn *conn;
-+ create_conn_cp *cc = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
-+
-+ if (!cc)
-+ return;
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_ba(hdev, ACL_LINK, &cc->bdaddr);
-+
-+ BT_DBG("%s status 0x%x bdaddr %s conn %p", hdev->name,
-+ status, batostr(&cc->bdaddr), conn);
-+
-+ if (status) {
-+ if (conn && conn->state == BT_CONNECT) {
-+ conn->state = BT_CLOSED;
-+ hci_proto_connect_cfm(conn, status);
-+ hci_conn_del(conn);
-+ }
-+ } else {
-+ if (!conn) {
-+ conn = hci_conn_add(hdev, ACL_LINK, &cc->bdaddr);
-+ if (conn) {
-+ conn->out = 1;
-+ conn->link_mode |= HCI_LM_MASTER;
-+ } else
-+ BT_ERR("No memmory for new connection");
-+ }
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+{
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_CREATE_CONN:
-+ hci_cs_create_conn(hdev, status);
-+ break;
-+
-+ case OCF_ADD_SCO:
-+ if (status) {
-+ struct hci_conn *acl, *sco;
-+ add_sco_cp *cp = hci_sent_cmd_data(hdev,
-+ OGF_LINK_CTL, OCF_ADD_SCO);
-+ __u16 handle;
-+
-+ if (!cp)
-+ break;
-+
-+ handle = __le16_to_cpu(cp->handle);
-+
-+ BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
-+
-+ hci_dev_lock(hdev);
-+
-+ acl = conn_hash_lookup_handle(hdev, handle);
-+ if (acl && (sco = acl->link)) {
-+ sco->state = BT_CLOSED;
-+ hci_proto_connect_cfm(sco, status);
-+ hci_conn_del(sco);
-+ }
-+
-+ hci_dev_unlock(hdev);
-+ }
-+ break;
-+
-+ case OCF_INQUIRY:
-+ if (status) {
-+ BT_DBG("%s Inquiry error: status 0x%x", hdev->name, status);
-+ hci_req_complete(hdev, status);
-+ } else {
-+ set_bit(HCI_INQUIRY, &hdev->flags);
-+ }
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command status: ogf LINK_CTL ocf %x status %d",
-+ hdev->name, ocf, status);
-+ break;
-+ };
-+}
-+
-+/* Command Status OGF LINK_POLICY */
-+static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+{
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ default:
-+ BT_DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Status OGF HOST_CTL */
-+static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+{
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ default:
-+ BT_DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Status OGF INFO_PARAM */
-+static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+{
-+ BT_DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ default:
-+ BT_DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Inquiry Complete */
-+static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ __u8 status = *((__u8 *) skb->data);
-+
-+ BT_DBG("%s status %d", hdev->name, status);
-+
-+ clear_bit(HCI_INQUIRY, &hdev->flags);
-+ hci_req_complete(hdev, status);
-+}
-+
-+/* Inquiry Result */
-+static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ inquiry_info *info = (inquiry_info *) (skb->data + 1);
-+ int num_rsp = *((__u8 *) skb->data);
-+
-+ BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
-+
-+ hci_dev_lock(hdev);
-+ for (; num_rsp; num_rsp--)
-+ inquiry_cache_update(hdev, info++);
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Inquiry Result With RSSI */
-+static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ inquiry_info_with_rssi *info = (inquiry_info_with_rssi *) (skb->data + 1);
-+ int num_rsp = *((__u8 *) skb->data);
-+
-+ BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
-+
-+ hci_dev_lock(hdev);
-+ for (; num_rsp; num_rsp--) {
-+ inquiry_info tmp;
-+ bacpy(&tmp.bdaddr, &info->bdaddr);
-+ tmp.pscan_rep_mode = info->pscan_rep_mode;
-+ tmp.pscan_period_mode = info->pscan_period_mode;
-+ tmp.pscan_mode = 0x00;
-+ memcpy(tmp.dev_class, &info->dev_class, 3);
-+ tmp.clock_offset = info->clock_offset;
-+ info++;
-+ inquiry_cache_update(hdev, &tmp);
-+ }
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Connect Request */
-+static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_conn_request *cr = (evt_conn_request *) skb->data;
-+ int mask = hdev->link_mode;
-+
-+ BT_DBG("%s Connection request: %s type 0x%x", hdev->name,
-+ batostr(&cr->bdaddr), cr->link_type);
-+
-+ mask |= hci_proto_connect_ind(hdev, &cr->bdaddr, cr->link_type);
-+
-+ if (mask & HCI_LM_ACCEPT) {
-+ /* Connection accepted */
-+ struct hci_conn *conn;
-+ accept_conn_req_cp ac;
-+
-+ hci_dev_lock(hdev);
-+ conn = conn_hash_lookup_ba(hdev, cr->link_type, &cr->bdaddr);
-+ if (!conn) {
-+ if (!(conn = hci_conn_add(hdev, cr->link_type, &cr->bdaddr))) {
-+ BT_ERR("No memmory for new connection");
-+ hci_dev_unlock(hdev);
-+ return;
-+ }
-+ }
-+ conn->state = BT_CONNECT;
-+ hci_dev_unlock(hdev);
-+
-+ bacpy(&ac.bdaddr, &cr->bdaddr);
-+
-+ if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
-+ ac.role = 0x00; /* Become master */
-+ else
-+ ac.role = 0x01; /* Remain slave */
-+
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ,
-+ ACCEPT_CONN_REQ_CP_SIZE, &ac);
-+ } else {
-+ /* Connection rejected */
-+ reject_conn_req_cp rc;
-+
-+ bacpy(&rc.bdaddr, &cr->bdaddr);
-+ rc.reason = 0x0f;
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_REJECT_CONN_REQ,
-+ REJECT_CONN_REQ_CP_SIZE, &rc);
-+ }
-+}
-+
-+/* Connect Complete */
-+static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_conn_complete *cc = (evt_conn_complete *) skb->data;
-+ struct hci_conn *conn = NULL;
-+
-+ BT_DBG("%s", hdev->name);
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_ba(hdev, cc->link_type, &cc->bdaddr);
-+ if (!conn) {
-+ hci_dev_unlock(hdev);
-+ return;
-+ }
-+
-+ if (!cc->status) {
-+ conn->handle = __le16_to_cpu(cc->handle);
-+ conn->state = BT_CONNECTED;
-+
-+ if (test_bit(HCI_AUTH, &hdev->flags))
-+ conn->link_mode |= HCI_LM_AUTH;
-+
-+ if (test_bit(HCI_ENCRYPT, &hdev->flags))
-+ conn->link_mode |= HCI_LM_ENCRYPT;
-+
-+
-+ /* Set link policy */
-+ if (conn->type == ACL_LINK && hdev->link_policy) {
-+ write_link_policy_cp lp;
-+ lp.handle = cc->handle;
-+ lp.policy = __cpu_to_le16(hdev->link_policy);
-+ hci_send_cmd(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY,
-+ WRITE_LINK_POLICY_CP_SIZE, &lp);
-+ }
-+
-+ /* Set packet type for incomming connection */
-+ if (!conn->out) {
-+ change_conn_ptype_cp cp;
-+ cp.handle = cc->handle;
-+ cp.pkt_type = (conn->type == ACL_LINK) ?
-+ __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK):
-+ __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
-+
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CHANGE_CONN_PTYPE,
-+ CHANGE_CONN_PTYPE_CP_SIZE, &cp);
-+ }
-+ } else
-+ conn->state = BT_CLOSED;
-+
-+ if (conn->type == ACL_LINK) {
-+ struct hci_conn *sco = conn->link;
-+ if (sco) {
-+ if (!cc->status)
-+ hci_add_sco(sco, conn->handle);
-+ else {
-+ hci_proto_connect_cfm(sco, cc->status);
-+ hci_conn_del(sco);
-+ }
-+ }
-+ }
-+
-+ hci_proto_connect_cfm(conn, cc->status);
-+ if (cc->status)
-+ hci_conn_del(conn);
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Disconnect Complete */
-+static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_disconn_complete *dc = (evt_disconn_complete *) skb->data;
-+ struct hci_conn *conn = NULL;
-+ __u16 handle = __le16_to_cpu(dc->handle);
-+
-+ BT_DBG("%s status %d", hdev->name, dc->status);
-+
-+ if (dc->status)
-+ return;
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ if (conn) {
-+ conn->state = BT_CLOSED;
-+ hci_proto_disconn_ind(conn, dc->reason);
-+ hci_conn_del(conn);
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Number of completed packets */
-+static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_num_comp_pkts *nc = (evt_num_comp_pkts *) skb->data;
-+ __u16 *ptr;
-+ int i;
-+
-+ skb_pull(skb, EVT_NUM_COMP_PKTS_SIZE);
-+
-+ BT_DBG("%s num_hndl %d", hdev->name, nc->num_hndl);
-+
-+ if (skb->len < nc->num_hndl * 4) {
-+ BT_DBG("%s bad parameters", hdev->name);
-+ return;
-+ }
-+
-+ tasklet_disable(&hdev->tx_task);
-+
-+ for (i = 0, ptr = (__u16 *) skb->data; i < nc->num_hndl; i++) {
-+ struct hci_conn *conn;
-+ __u16 handle, count;
-+
-+ handle = __le16_to_cpu(get_unaligned(ptr++));
-+ count = __le16_to_cpu(get_unaligned(ptr++));
-+
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ if (conn) {
-+ conn->sent -= count;
-+
-+ if (conn->type == SCO_LINK) {
-+ if ((hdev->sco_cnt += count) > hdev->sco_pkts)
-+ hdev->sco_cnt = hdev->sco_pkts;
-+ } else {
-+ if ((hdev->acl_cnt += count) > hdev->acl_pkts)
-+ hdev->acl_cnt = hdev->acl_pkts;
-+ }
-+ }
-+ }
-+ hci_sched_tx(hdev);
-+
-+ tasklet_enable(&hdev->tx_task);
-+}
-+
-+/* Role Change */
-+static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_role_change *rc = (evt_role_change *) skb->data;
-+ struct hci_conn *conn = NULL;
-+
-+ BT_DBG("%s status %d", hdev->name, rc->status);
-+
-+ if (rc->status)
-+ return;
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_ba(hdev, ACL_LINK, &rc->bdaddr);
-+ if (conn) {
-+ if (rc->role)
-+ conn->link_mode &= ~HCI_LM_MASTER;
-+ else
-+ conn->link_mode |= HCI_LM_MASTER;
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Authentication Complete */
-+static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_auth_complete *ac = (evt_auth_complete *) skb->data;
-+ struct hci_conn *conn = NULL;
-+ __u16 handle = __le16_to_cpu(ac->handle);
-+
-+ BT_DBG("%s status %d", hdev->name, ac->status);
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ if (conn) {
-+ if (!ac->status)
-+ conn->link_mode |= HCI_LM_AUTH;
-+ clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
-+
-+ hci_proto_auth_cfm(conn, ac->status);
-+
-+ if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
-+ if (!ac->status) {
-+ set_conn_encrypt_cp ce;
-+ ce.handle = __cpu_to_le16(conn->handle);
-+ ce.encrypt = 1;
-+ hci_send_cmd(conn->hdev, OGF_LINK_CTL,
-+ OCF_SET_CONN_ENCRYPT,
-+ SET_CONN_ENCRYPT_CP_SIZE, &ce);
-+ } else {
-+ clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
-+ hci_proto_encrypt_cfm(conn, ac->status);
-+ }
-+ }
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Encryption Change */
-+static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_encrypt_change *ec = (evt_encrypt_change *) skb->data;
-+ struct hci_conn *conn = NULL;
-+ __u16 handle = __le16_to_cpu(ec->handle);
-+
-+ BT_DBG("%s status %d", hdev->name, ec->status);
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ if (conn) {
-+ if (!ec->status) {
-+ if (ec->encrypt)
-+ conn->link_mode |= HCI_LM_ENCRYPT;
-+ else
-+ conn->link_mode &= ~HCI_LM_ENCRYPT;
-+ }
-+ clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
-+
-+ hci_proto_encrypt_cfm(conn, ec->status);
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ hci_event_hdr *he = (hci_event_hdr *) skb->data;
-+ evt_cmd_status *cs;
-+ evt_cmd_complete *ec;
-+ __u16 opcode, ocf, ogf;
-+
-+ skb_pull(skb, HCI_EVENT_HDR_SIZE);
-+
-+ BT_DBG("%s evt 0x%x", hdev->name, he->evt);
-+
-+ switch (he->evt) {
-+ case EVT_NUM_COMP_PKTS:
-+ hci_num_comp_pkts_evt(hdev, skb);
-+ break;
-+
-+ case EVT_INQUIRY_COMPLETE:
-+ hci_inquiry_complete_evt(hdev, skb);
-+ break;
-+
-+ case EVT_INQUIRY_RESULT:
-+ hci_inquiry_result_evt(hdev, skb);
-+ break;
-+
-+ case EVT_INQUIRY_RESULT_WITH_RSSI:
-+ hci_inquiry_result_with_rssi_evt(hdev, skb);
-+ break;
-+
-+ case EVT_CONN_REQUEST:
-+ hci_conn_request_evt(hdev, skb);
-+ break;
-+
-+ case EVT_CONN_COMPLETE:
-+ hci_conn_complete_evt(hdev, skb);
-+ break;
-+
-+ case EVT_DISCONN_COMPLETE:
-+ hci_disconn_complete_evt(hdev, skb);
-+ break;
-+
-+ case EVT_ROLE_CHANGE:
-+ hci_role_change_evt(hdev, skb);
-+ break;
-+
-+ case EVT_AUTH_COMPLETE:
-+ hci_auth_complete_evt(hdev, skb);
-+ break;
-+
-+ case EVT_ENCRYPT_CHANGE:
-+ hci_encrypt_change_evt(hdev, skb);
-+ break;
-+
-+ case EVT_CMD_STATUS:
-+ cs = (evt_cmd_status *) skb->data;
-+ skb_pull(skb, EVT_CMD_STATUS_SIZE);
-+
-+ opcode = __le16_to_cpu(cs->opcode);
-+ ogf = cmd_opcode_ogf(opcode);
-+ ocf = cmd_opcode_ocf(opcode);
-+
-+ switch (ogf) {
-+ case OGF_INFO_PARAM:
-+ hci_cs_info_param(hdev, ocf, cs->status);
-+ break;
-+
-+ case OGF_HOST_CTL:
-+ hci_cs_host_ctl(hdev, ocf, cs->status);
-+ break;
-+
-+ case OGF_LINK_CTL:
-+ hci_cs_link_ctl(hdev, ocf, cs->status);
-+ break;
-+
-+ case OGF_LINK_POLICY:
-+ hci_cs_link_policy(hdev, ocf, cs->status);
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command Status OGF %x", hdev->name, ogf);
-+ break;
-+ };
-+
-+ if (cs->ncmd) {
-+ atomic_set(&hdev->cmd_cnt, 1);
-+ if (!skb_queue_empty(&hdev->cmd_q))
-+ hci_sched_cmd(hdev);
-+ }
-+ break;
-+
-+ case EVT_CMD_COMPLETE:
-+ ec = (evt_cmd_complete *) skb->data;
-+ skb_pull(skb, EVT_CMD_COMPLETE_SIZE);
-+
-+ opcode = __le16_to_cpu(ec->opcode);
-+ ogf = cmd_opcode_ogf(opcode);
-+ ocf = cmd_opcode_ocf(opcode);
-+
-+ switch (ogf) {
-+ case OGF_INFO_PARAM:
-+ hci_cc_info_param(hdev, ocf, skb);
-+ break;
-+
-+ case OGF_HOST_CTL:
-+ hci_cc_host_ctl(hdev, ocf, skb);
-+ break;
-+
-+ case OGF_LINK_CTL:
-+ hci_cc_link_ctl(hdev, ocf, skb);
-+ break;
-+
-+ case OGF_LINK_POLICY:
-+ hci_cc_link_policy(hdev, ocf, skb);
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command Completed OGF %x", hdev->name, ogf);
-+ break;
-+ };
-+
-+ if (ec->ncmd) {
-+ atomic_set(&hdev->cmd_cnt, 1);
-+ if (!skb_queue_empty(&hdev->cmd_q))
-+ hci_sched_cmd(hdev);
-+ }
-+ break;
-+ };
-+
-+ kfree_skb(skb);
-+ hdev->stat.evt_rx++;
-+}
-+
-+/* General internal stack event */
-+void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
-+{
-+ hci_event_hdr *eh;
-+ evt_stack_internal *si;
-+ struct sk_buff *skb;
-+ int size;
-+ void *ptr;
-+
-+ size = HCI_EVENT_HDR_SIZE + EVT_STACK_INTERNAL_SIZE + dlen;
-+ skb = bluez_skb_alloc(size, GFP_ATOMIC);
-+ if (!skb)
-+ return;
-+
-+ ptr = skb_put(skb, size);
-+
-+ eh = ptr;
-+ eh->evt = EVT_STACK_INTERNAL;
-+ eh->plen = EVT_STACK_INTERNAL_SIZE + dlen;
-+ ptr += HCI_EVENT_HDR_SIZE;
-+
-+ si = ptr;
-+ si->type = type;
-+ memcpy(si->data, data, dlen);
-+
-+ skb->pkt_type = HCI_EVENT_PKT;
-+ skb->dev = (void *) hdev;
-+ hci_send_to_sock(hdev, skb);
-+ kfree_skb(skb);
-+}
-diff -urN linux-2.4.18/net/bluetooth/hci_sock.c linux-2.4.18-mh15/net/bluetooth/hci_sock.c
---- linux-2.4.18/net/bluetooth/hci_sock.c 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/net/bluetooth/hci_sock.c 2004-08-01 16:26:23.000000000 +0200
-@@ -25,7 +25,7 @@
- /*
- * BlueZ HCI socket layer.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
-@@ -49,45 +49,54 @@
-
- #include <asm/system.h>
- #include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
-
- #ifndef HCI_SOCK_DEBUG
--#undef DBG
--#define DBG( A... )
-+#undef BT_DBG
-+#define BT_DBG( A... )
- #endif
-
--/* HCI socket interface */
-+/* ----- HCI socket interface ----- */
-+
-+/* Security filter */
-+static struct hci_sec_filter hci_sec_filter = {
-+ /* Packet types */
-+ 0x10,
-+ /* Events */
-+ { 0x1000d9fe, 0x0000300c },
-+ /* Commands */
-+ {
-+ { 0x0 },
-+ /* OGF_LINK_CTL */
-+ { 0xbe000006, 0x00000001, 0x0000, 0x00 },
-+ /* OGF_LINK_POLICY */
-+ { 0x00005200, 0x00000000, 0x0000, 0x00 },
-+ /* OGF_HOST_CTL */
-+ { 0xaab00200, 0x2b402aaa, 0x0154, 0x00 },
-+ /* OGF_INFO_PARAM */
-+ { 0x000002be, 0x00000000, 0x0000, 0x00 },
-+ /* OGF_STATUS_PARAM */
-+ { 0x000000ea, 0x00000000, 0x0000, 0x00 }
-+ }
-+};
-
- static struct bluez_sock_list hci_sk_list = {
- lock: RW_LOCK_UNLOCKED
- };
-
--static struct sock *hci_sock_lookup(struct hci_dev *hdev)
--{
-- struct sock *sk;
--
-- read_lock(&hci_sk_list.lock);
-- for (sk = hci_sk_list.head; sk; sk = sk->next) {
-- if (hci_pi(sk)->hdev == hdev)
-- break;
-- }
-- read_unlock(&hci_sk_list.lock);
-- return sk;
--}
--
- /* Send frame to RAW socket */
- void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
- {
- struct sock * sk;
-
-- DBG("hdev %p len %d", hdev, skb->len);
-+ BT_DBG("hdev %p len %d", hdev, skb->len);
-
- read_lock(&hci_sk_list.lock);
- for (sk = hci_sk_list.head; sk; sk = sk->next) {
-- struct hci_filter *flt;
-+ struct hci_filter *flt;
- struct sk_buff *nskb;
-
- if (sk->state != BT_BOUND || hci_pi(sk)->hdev != hdev)
-@@ -100,13 +109,19 @@
- /* Apply filter */
- flt = &hci_pi(sk)->filter;
-
-- if (!test_bit(skb->pkt_type, &flt->type_mask))
-+ if (!hci_test_bit((skb->pkt_type & HCI_FLT_TYPE_BITS), &flt->type_mask))
- continue;
-
- if (skb->pkt_type == HCI_EVENT_PKT) {
-- register int evt = (*(__u8 *)skb->data & 63);
-+ register int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
-+
-+ if (!hci_test_bit(evt, &flt->event_mask))
-+ continue;
-
-- if (!test_bit(evt, &flt->event_mask))
-+ if (flt->opcode && ((evt == EVT_CMD_COMPLETE &&
-+ flt->opcode != *(__u16 *)(skb->data + 3)) ||
-+ (evt == EVT_CMD_STATUS &&
-+ flt->opcode != *(__u16 *)(skb->data + 4))))
- continue;
- }
-
-@@ -116,8 +131,8 @@
- /* Put type byte before the data */
- memcpy(skb_push(nskb, 1), &nskb->pkt_type, 1);
-
-- skb_queue_tail(&sk->receive_queue, nskb);
-- sk->data_ready(sk, nskb->len);
-+ if (sock_queue_rcv_skb(sk, nskb))
-+ kfree_skb(nskb);
- }
- read_unlock(&hci_sk_list.lock);
- }
-@@ -127,7 +142,7 @@
- struct sock *sk = sock->sk;
- struct hci_dev *hdev = hci_pi(sk)->hdev;
-
-- DBG("sock %p sk %p", sock, sk);
-+ BT_DBG("sock %p sk %p", sock, sk);
-
- if (!sk)
- return 0;
-@@ -135,9 +150,7 @@
- bluez_sock_unlink(&hci_sk_list, sk);
-
- if (hdev) {
-- if (!hci_sock_lookup(hdev))
-- hdev->flags &= ~HCI_SOCK;
--
-+ atomic_dec(&hdev->promisc);
- hci_dev_put(hdev);
- }
-
-@@ -149,24 +162,55 @@
- sock_put(sk);
-
- MOD_DEC_USE_COUNT;
--
- return 0;
- }
-
--static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+/* Ioctls that require bound socket */
-+static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
- {
-- struct sock *sk = sock->sk;
- struct hci_dev *hdev = hci_pi(sk)->hdev;
-- __u32 mode;
-
-- DBG("cmd %x arg %lx", cmd, arg);
-+ if (!hdev)
-+ return -EBADFD;
-
- switch (cmd) {
-- case HCIGETINFO:
-- return hci_dev_info(arg);
-+ case HCISETRAW:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-
-+ if (arg)
-+ set_bit(HCI_RAW, &hdev->flags);
-+ else
-+ clear_bit(HCI_RAW, &hdev->flags);
-+
-+ return 0;
-+
-+ case HCIGETCONNINFO:
-+ return hci_get_conn_info(hdev, arg);
-+
-+ default:
-+ if (hdev->ioctl)
-+ return hdev->ioctl(hdev, cmd, arg);
-+ return -EINVAL;
-+ }
-+}
-+
-+static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct sock *sk = sock->sk;
-+ int err;
-+
-+ BT_DBG("cmd %x arg %lx", cmd, arg);
-+
-+ switch (cmd) {
- case HCIGETDEVLIST:
-- return hci_dev_list(arg);
-+ return hci_get_dev_list(arg);
-+
-+ case HCIGETDEVINFO:
-+ return hci_get_dev_info(arg);
-+
-+ case HCIGETCONNLIST:
-+ return hci_get_conn_list(arg);
-
- case HCIDEVUP:
- if (!capable(CAP_NET_ADMIN))
-@@ -183,48 +227,31 @@
- return -EACCES;
- return hci_dev_reset(arg);
-
-- case HCIRESETSTAT:
-+ case HCIDEVRESTAT:
- if (!capable(CAP_NET_ADMIN))
- return -EACCES;
- return hci_dev_reset_stat(arg);
-
- case HCISETSCAN:
-- if (!capable(CAP_NET_ADMIN))
-- return -EACCES;
-- return hci_dev_setscan(arg);
--
- case HCISETAUTH:
-- if (!capable(CAP_NET_ADMIN))
-- return -EACCES;
-- return hci_dev_setauth(arg);
--
-- case HCISETRAW:
-- if (!capable(CAP_NET_ADMIN))
-- return -EACCES;
--
-- if (!hdev)
-- return -EBADFD;
--
-- if (arg)
-- mode = HCI_RAW;
-- else
-- mode = HCI_NORMAL;
--
-- return hci_dev_setmode(hdev, mode);
--
-+ case HCISETENCRYPT:
- case HCISETPTYPE:
-+ case HCISETLINKPOL:
-+ case HCISETLINKMODE:
-+ case HCISETACLMTU:
-+ case HCISETSCOMTU:
- if (!capable(CAP_NET_ADMIN))
- return -EACCES;
-- return hci_dev_setptype(arg);
-+ return hci_dev_cmd(cmd, arg);
-
- case HCIINQUIRY:
- return hci_inquiry(arg);
-
-- case HCIGETCONNLIST:
-- return hci_conn_list(arg);
--
- default:
-- return -EINVAL;
-+ lock_sock(sk);
-+ err = hci_sock_bound_ioctl(sk, cmd, arg);
-+ release_sock(sk);
-+ return err;
- };
- }
-
-@@ -233,28 +260,35 @@
- struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
- struct sock *sk = sock->sk;
- struct hci_dev *hdev = NULL;
-+ int err = 0;
-
-- DBG("sock %p sk %p", sock, sk);
-+ BT_DBG("sock %p sk %p", sock, sk);
-
- if (!haddr || haddr->hci_family != AF_BLUETOOTH)
- return -EINVAL;
-
-+ lock_sock(sk);
-+
- if (hci_pi(sk)->hdev) {
-- /* Already bound */
-- return 0;
-+ err = -EALREADY;
-+ goto done;
- }
-
- if (haddr->hci_dev != HCI_DEV_NONE) {
-- if (!(hdev = hci_dev_get(haddr->hci_dev)))
-- return -ENODEV;
-+ if (!(hdev = hci_dev_get(haddr->hci_dev))) {
-+ err = -ENODEV;
-+ goto done;
-+ }
-
-- hdev->flags |= HCI_SOCK;
-+ atomic_inc(&hdev->promisc);
- }
-
- hci_pi(sk)->hdev = hdev;
- sk->state = BT_BOUND;
-
-- return 0;
-+done:
-+ release_sock(sk);
-+ return err;
- }
-
- static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer)
-@@ -262,73 +296,44 @@
- struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
- struct sock *sk = sock->sk;
-
-- DBG("sock %p sk %p", sock, sk);
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ lock_sock(sk);
-
- *addr_len = sizeof(*haddr);
- haddr->hci_family = AF_BLUETOOTH;
- haddr->hci_dev = hci_pi(sk)->hdev->id;
-
-+ release_sock(sk);
- return 0;
- }
-
--static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
-- struct scm_cookie *scm)
--{
-- struct sock *sk = sock->sk;
-- struct hci_dev *hdev = hci_pi(sk)->hdev;
-- struct sk_buff *skb;
-- int err;
--
-- DBG("sock %p sk %p", sock, sk);
--
-- if (msg->msg_flags & MSG_OOB)
-- return -EOPNOTSUPP;
--
-- if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
-- return -EINVAL;
--
-- if (!hdev)
-- return -EBADFD;
--
-- if (!(skb = bluez_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
-- return err;
--
-- if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
-- kfree_skb(skb);
-- return -EFAULT;
-- }
--
-- skb->dev = (void *) hdev;
-- skb->pkt_type = *((unsigned char *) skb->data);
-- skb_pull(skb, 1);
--
-- /* Send frame to HCI core */
-- hci_send_raw(skb);
--
-- return len;
--}
--
- static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
- {
- __u32 mask = hci_pi(sk)->cmsg_mask;
-
- if (mask & HCI_CMSG_DIR)
- put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(int), &bluez_cb(skb)->incomming);
-+
-+ if (mask & HCI_CMSG_TSTAMP)
-+ put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, sizeof(skb->stamp), &skb->stamp);
- }
-
--static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len,
-- int flags, struct scm_cookie *scm)
-+static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
- {
- int noblock = flags & MSG_DONTWAIT;
- struct sock *sk = sock->sk;
- struct sk_buff *skb;
- int copied, err;
-
-- DBG("sock %p sk %p", sock, sk);
-+ BT_DBG("sock %p, sk %p", sock, sk);
-
-- if (flags & (MSG_OOB | MSG_PEEK))
-+ if (flags & (MSG_OOB))
- return -EOPNOTSUPP;
-
-+ if (sk->state == BT_CLOSED)
-+ return 0;
-+
- if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
- return err;
-
-@@ -343,28 +348,107 @@
- skb->h.raw = skb->data;
- err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
-
-- if (hci_pi(sk)->cmsg_mask)
-- hci_sock_cmsg(sk, msg, skb);
--
-+ hci_sock_cmsg(sk, msg, skb);
-+
- skb_free_datagram(sk, skb);
-
- return err ? : copied;
- }
-
-+static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
-+ struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ struct hci_dev *hdev;
-+ struct sk_buff *skb;
-+ int err;
-+
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ if (msg->msg_flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
-+ return -EINVAL;
-+
-+ if (len < 4)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (!(hdev = hci_pi(sk)->hdev)) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ if (!(skb = bluez_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
-+ goto done;
-+
-+ if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
-+ err = -EFAULT;
-+ goto drop;
-+ }
-+
-+ skb->pkt_type = *((unsigned char *) skb->data);
-+ skb_pull(skb, 1);
-+ skb->dev = (void *) hdev;
-+
-+ if (skb->pkt_type == HCI_COMMAND_PKT) {
-+ u16 opcode = __le16_to_cpu(get_unaligned((u16 *)skb->data));
-+ u16 ogf = cmd_opcode_ogf(opcode);
-+ u16 ocf = cmd_opcode_ocf(opcode);
-+
-+ if (((ogf > HCI_SFLT_MAX_OGF) ||
-+ !hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) &&
-+ !capable(CAP_NET_RAW)) {
-+ err = -EPERM;
-+ goto drop;
-+ }
-+
-+ if (test_bit(HCI_RAW, &hdev->flags) || (ogf == OGF_VENDOR_CMD)) {
-+ skb_queue_tail(&hdev->raw_q, skb);
-+ hci_sched_tx(hdev);
-+ } else {
-+ skb_queue_tail(&hdev->cmd_q, skb);
-+ hci_sched_cmd(hdev);
-+ }
-+ } else {
-+ if (!capable(CAP_NET_RAW)) {
-+ err = -EPERM;
-+ goto drop;
-+ }
-+
-+ skb_queue_tail(&hdev->raw_q, skb);
-+ hci_sched_tx(hdev);
-+ }
-+
-+ err = len;
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+
-+drop:
-+ kfree_skb(skb);
-+ goto done;
-+}
-+
- int hci_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int len)
- {
- struct sock *sk = sock->sk;
-- struct hci_filter flt;
-+ struct hci_filter flt = { opcode: 0 };
- int err = 0, opt = 0;
-
-- DBG("sk %p, opt %d", sk, optname);
-+ BT_DBG("sk %p, opt %d", sk, optname);
-
- lock_sock(sk);
-
- switch (optname) {
- case HCI_DATA_DIR:
-- if (get_user(opt, (int *)optval))
-- return -EFAULT;
-+ if (get_user(opt, (int *)optval)) {
-+ err = -EFAULT;
-+ break;
-+ }
-
- if (opt)
- hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
-@@ -372,12 +456,31 @@
- hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
- break;
-
-+ case HCI_TIME_STAMP:
-+ if (get_user(opt, (int *)optval)) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ if (opt)
-+ hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
-+ else
-+ hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
-+ break;
-+
- case HCI_FILTER:
- len = MIN(len, sizeof(struct hci_filter));
- if (copy_from_user(&flt, optval, len)) {
- err = -EFAULT;
- break;
- }
-+
-+ if (!capable(CAP_NET_RAW)) {
-+ flt.type_mask &= hci_sec_filter.type_mask;
-+ flt.event_mask[0] &= hci_sec_filter.event_mask[0];
-+ flt.event_mask[1] &= hci_sec_filter.event_mask[1];
-+ }
-+
- memcpy(&hci_pi(sk)->filter, &flt, len);
- break;
-
-@@ -409,6 +512,16 @@
- return -EFAULT;
- break;
-
-+ case HCI_TIME_STAMP:
-+ if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
-+ opt = 1;
-+ else
-+ opt = 0;
-+
-+ if (put_user(opt, optval))
-+ return -EFAULT;
-+ break;
-+
- case HCI_FILTER:
- len = MIN(len, sizeof(struct hci_filter));
- if (copy_to_user(optval, &hci_pi(sk)->filter, len))
-@@ -446,7 +559,7 @@
- {
- struct sock *sk;
-
-- DBG("sock %p", sock);
-+ BT_DBG("sock %p", sock);
-
- if (sock->type != SOCK_RAW)
- return -ESOCKTNOSUPPORT;
-@@ -464,44 +577,31 @@
- sk->protocol = protocol;
- sk->state = BT_OPEN;
-
-- /* Initialize filter */
-- hci_pi(sk)->filter.type_mask = (1<<HCI_EVENT_PKT);
-- hci_pi(sk)->filter.event_mask[0] = ~0L;
-- hci_pi(sk)->filter.event_mask[1] = ~0L;
--
- bluez_sock_link(&hci_sk_list, sk);
-
- MOD_INC_USE_COUNT;
--
- return 0;
- }
-
- static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
- {
- struct hci_dev *hdev = (struct hci_dev *) ptr;
-- struct sk_buff *skb;
--
-- DBG("hdev %s event %ld", hdev->name, event);
-+ evt_si_device sd;
-+
-+ BT_DBG("hdev %s event %ld", hdev->name, event);
-
- /* Send event to sockets */
-- if ((skb = bluez_skb_alloc(HCI_EVENT_HDR_SIZE + EVT_HCI_DEV_EVENT_SIZE, GFP_ATOMIC))) {
-- hci_event_hdr eh = { EVT_HCI_DEV_EVENT, EVT_HCI_DEV_EVENT_SIZE };
-- evt_hci_dev_event he = { event, hdev->id };
--
-- skb->pkt_type = HCI_EVENT_PKT;
-- memcpy(skb_put(skb, HCI_EVENT_HDR_SIZE), &eh, HCI_EVENT_HDR_SIZE);
-- memcpy(skb_put(skb, EVT_HCI_DEV_EVENT_SIZE), &he, EVT_HCI_DEV_EVENT_SIZE);
--
-- hci_send_to_sock(NULL, skb);
-- kfree_skb(skb);
-- }
--
-+ sd.event = event;
-+ sd.dev_id = hdev->id;
-+ hci_si_event(NULL, EVT_SI_DEVICE, EVT_SI_DEVICE_SIZE, &sd);
-+
- if (event == HCI_DEV_UNREG) {
- struct sock *sk;
-
- /* Detach sockets from device */
- read_lock(&hci_sk_list.lock);
- for (sk = hci_sk_list.head; sk; sk = sk->next) {
-+ bh_lock_sock(sk);
- if (hci_pi(sk)->hdev == hdev) {
- hci_pi(sk)->hdev = NULL;
- sk->err = EPIPE;
-@@ -510,6 +610,7 @@
-
- hci_dev_put(hdev);
- }
-+ bh_unlock_sock(sk);
- }
- read_unlock(&hci_sk_list.lock);
- }
-@@ -529,21 +630,19 @@
- int hci_sock_init(void)
- {
- if (bluez_sock_register(BTPROTO_HCI, &hci_sock_family_ops)) {
-- ERR("Can't register HCI socket");
-+ BT_ERR("Can't register HCI socket");
- return -EPROTO;
- }
-
- hci_register_notifier(&hci_sock_nblock);
--
- return 0;
- }
-
- int hci_sock_cleanup(void)
- {
- if (bluez_sock_unregister(BTPROTO_HCI))
-- ERR("Can't unregister HCI socket");
-+ BT_ERR("Can't unregister HCI socket");
-
- hci_unregister_notifier(&hci_sock_nblock);
--
- return 0;
- }
-diff -urN linux-2.4.18/net/bluetooth/hidp/Config.in linux-2.4.18-mh15/net/bluetooth/hidp/Config.in
---- linux-2.4.18/net/bluetooth/hidp/Config.in 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/hidp/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,5 @@
-+#
-+# Bluetooth HIDP layer configuration
-+#
-+
-+dep_tristate 'HIDP protocol support' CONFIG_BLUEZ_HIDP $CONFIG_INPUT $CONFIG_BLUEZ_L2CAP
-diff -urN linux-2.4.18/net/bluetooth/hidp/core.c linux-2.4.18-mh15/net/bluetooth/hidp/core.c
---- linux-2.4.18/net/bluetooth/hidp/core.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/hidp/core.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,655 @@
-+/*
-+ HIDP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <linux/init.h>
-+#include <net/sock.h>
-+
-+#include <linux/input.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#include "hidp.h"
-+
-+#ifndef CONFIG_BT_HIDP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define VERSION "1.0"
-+
-+static DECLARE_RWSEM(hidp_session_sem);
-+static LIST_HEAD(hidp_session_list);
-+
-+static unsigned char hidp_keycode[256] = {
-+ 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
-+ 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
-+ 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
-+ 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
-+ 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
-+ 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
-+ 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
-+ 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
-+ 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,
-+ 122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
-+ 150,158,159,128,136,177,178,176,142,152,173,140
-+};
-+
-+static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr)
-+{
-+ struct hidp_session *session;
-+ struct list_head *p;
-+
-+ BT_DBG("");
-+
-+ list_for_each(p, &hidp_session_list) {
-+ session = list_entry(p, struct hidp_session, list);
-+ if (!bacmp(bdaddr, &session->bdaddr))
-+ return session;
-+ }
-+ return NULL;
-+}
-+
-+static void __hidp_link_session(struct hidp_session *session)
-+{
-+ MOD_INC_USE_COUNT;
-+ list_add(&session->list, &hidp_session_list);
-+}
-+
-+static void __hidp_unlink_session(struct hidp_session *session)
-+{
-+ list_del(&session->list);
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci)
-+{
-+ bacpy(&ci->bdaddr, &session->bdaddr);
-+
-+ ci->flags = session->flags;
-+ ci->state = session->state;
-+
-+ ci->vendor = 0x0000;
-+ ci->product = 0x0000;
-+ ci->version = 0x0000;
-+ memset(ci->name, 0, 128);
-+
-+ if (session->input) {
-+ ci->vendor = session->input->idvendor;
-+ ci->product = session->input->idproduct;
-+ ci->version = session->input->idversion;
-+ if (session->input->name)
-+ strncpy(ci->name, session->input->name, 128);
-+ else
-+ strncpy(ci->name, "HID Boot Device", 128);
-+ }
-+}
-+
-+static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
-+{
-+ struct hidp_session *session = dev->private;
-+ struct sk_buff *skb;
-+ unsigned char newleds;
-+
-+ BT_DBG("session %p hid %p data %p size %d", session, device, data, size);
-+
-+ if (type != EV_LED)
-+ return -1;
-+
-+ newleds = (!!test_bit(LED_KANA, dev->led) << 3) |
-+ (!!test_bit(LED_COMPOSE, dev->led) << 3) |
-+ (!!test_bit(LED_SCROLLL, dev->led) << 2) |
-+ (!!test_bit(LED_CAPSL, dev->led) << 1) |
-+ (!!test_bit(LED_NUML, dev->led));
-+
-+ if (session->leds == newleds)
-+ return 0;
-+
-+ session->leds = newleds;
-+
-+ if (!(skb = alloc_skb(3, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for new frame");
-+ return -ENOMEM;
-+ }
-+
-+ *skb_put(skb, 1) = 0xa2;
-+ *skb_put(skb, 1) = 0x01;
-+ *skb_put(skb, 1) = newleds;
-+
-+ skb_queue_tail(&session->intr_transmit, skb);
-+
-+ hidp_schedule(session);
-+
-+ return 0;
-+}
-+
-+static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
-+{
-+ struct input_dev *dev = session->input;
-+ unsigned char *keys = session->keys;
-+ unsigned char *udata = skb->data + 1;
-+ signed char *sdata = skb->data + 1;
-+ int i, size = skb->len - 1;
-+
-+ switch (skb->data[0]) {
-+ case 0x01: /* Keyboard report */
-+ for (i = 0; i < 8; i++)
-+ input_report_key(dev, hidp_keycode[i + 224], (udata[0] >> i) & 1);
-+
-+ for (i = 2; i < 8; i++) {
-+ if (keys[i] > 3 && memscan(udata + 2, keys[i], 6) == udata + 8) {
-+ if (hidp_keycode[keys[i]])
-+ input_report_key(dev, hidp_keycode[keys[i]], 0);
-+ else
-+ BT_ERR("Unknown key (scancode %#x) released.", keys[i]);
-+ }
-+
-+ if (udata[i] > 3 && memscan(keys + 2, udata[i], 6) == keys + 8) {
-+ if (hidp_keycode[udata[i]])
-+ input_report_key(dev, hidp_keycode[udata[i]], 1);
-+ else
-+ BT_ERR("Unknown key (scancode %#x) pressed.", udata[i]);
-+ }
-+ }
-+
-+ memcpy(keys, udata, 8);
-+ break;
-+
-+ case 0x02: /* Mouse report */
-+ input_report_key(dev, BTN_LEFT, sdata[0] & 0x01);
-+ input_report_key(dev, BTN_RIGHT, sdata[0] & 0x02);
-+ input_report_key(dev, BTN_MIDDLE, sdata[0] & 0x04);
-+ input_report_key(dev, BTN_SIDE, sdata[0] & 0x08);
-+ input_report_key(dev, BTN_EXTRA, sdata[0] & 0x10);
-+
-+ input_report_rel(dev, REL_X, sdata[1]);
-+ input_report_rel(dev, REL_Y, sdata[2]);
-+
-+ if (size > 3)
-+ input_report_rel(dev, REL_WHEEL, sdata[3]);
-+ break;
-+ }
-+
-+ input_event(dev, EV_RST, 0, 0);
-+}
-+
-+static void hidp_idle_timeout(unsigned long arg)
-+{
-+ struct hidp_session *session = (struct hidp_session *) arg;
-+
-+ atomic_inc(&session->terminate);
-+ hidp_schedule(session);
-+}
-+
-+static inline void hidp_set_timer(struct hidp_session *session)
-+{
-+ if (session->idle_to > 0)
-+ mod_timer(&session->timer, jiffies + HZ * session->idle_to);
-+}
-+
-+static inline void hidp_del_timer(struct hidp_session *session)
-+{
-+ if (session->idle_to > 0)
-+ del_timer(&session->timer);
-+}
-+
-+static inline void hidp_send_message(struct hidp_session *session, unsigned char hdr)
-+{
-+ struct sk_buff *skb;
-+
-+ BT_DBG("session %p", session);
-+
-+ if (!(skb = alloc_skb(1, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for message");
-+ return;
-+ }
-+
-+ *skb_put(skb, 1) = hdr;
-+
-+ skb_queue_tail(&session->ctrl_transmit, skb);
-+
-+ hidp_schedule(session);
-+}
-+
-+static inline int hidp_recv_frame(struct hidp_session *session, struct sk_buff *skb)
-+{
-+ __u8 hdr;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ hdr = skb->data[0];
-+ skb_pull(skb, 1);
-+
-+ if (hdr == 0xa1) {
-+ hidp_set_timer(session);
-+
-+ if (session->input)
-+ hidp_input_report(session, skb);
-+ } else {
-+ BT_DBG("Unsupported protocol header 0x%02x", hdr);
-+ }
-+
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+static int hidp_send_frame(struct socket *sock, unsigned char *data, int len)
-+{
-+ struct iovec iv = { data, len };
-+ struct msghdr msg;
-+
-+ BT_DBG("sock %p data %p len %d", sock, data, len);
-+
-+ if (!len)
-+ return 0;
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_iovlen = 1;
-+ msg.msg_iov = &iv;
-+
-+ return sock_sendmsg(sock, &msg, len);
-+}
-+
-+static int hidp_process_transmit(struct hidp_session *session)
-+{
-+ struct sk_buff *skb;
-+
-+ BT_DBG("session %p", session);
-+
-+ while ((skb = skb_dequeue(&session->ctrl_transmit))) {
-+ if (hidp_send_frame(session->ctrl_sock, skb->data, skb->len) < 0) {
-+ skb_queue_head(&session->ctrl_transmit, skb);
-+ break;
-+ }
-+
-+ hidp_set_timer(session);
-+ kfree_skb(skb);
-+ }
-+
-+ while ((skb = skb_dequeue(&session->intr_transmit))) {
-+ if (hidp_send_frame(session->intr_sock, skb->data, skb->len) < 0) {
-+ skb_queue_head(&session->intr_transmit, skb);
-+ break;
-+ }
-+
-+ hidp_set_timer(session);
-+ kfree_skb(skb);
-+ }
-+
-+ return skb_queue_len(&session->ctrl_transmit) +
-+ skb_queue_len(&session->intr_transmit);
-+}
-+
-+static int hidp_session(void *arg)
-+{
-+ struct hidp_session *session = arg;
-+ struct sock *ctrl_sk = session->ctrl_sock->sk;
-+ struct sock *intr_sk = session->intr_sock->sk;
-+ struct sk_buff *skb;
-+ int vendor = 0x0000, product = 0x0000;
-+ wait_queue_t ctrl_wait, intr_wait;
-+ unsigned long timeo = HZ;
-+
-+ BT_DBG("session %p", session);
-+
-+ if (session->input) {
-+ vendor = session->input->idvendor;
-+ product = session->input->idproduct;
-+ }
-+
-+ daemonize(); reparent_to_init();
-+
-+ sprintf(current->comm, "khidpd_%04x%04x", vendor, product);
-+
-+ sigfillset(&current->blocked);
-+ flush_signals(current);
-+
-+ current->nice = -15;
-+
-+ set_fs(KERNEL_DS);
-+
-+ init_waitqueue_entry(&ctrl_wait, current);
-+ init_waitqueue_entry(&intr_wait, current);
-+ add_wait_queue(ctrl_sk->sleep, &ctrl_wait);
-+ add_wait_queue(intr_sk->sleep, &intr_wait);
-+ while (!atomic_read(&session->terminate)) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (ctrl_sk->state != BT_CONNECTED || intr_sk->state != BT_CONNECTED)
-+ break;
-+
-+ while ((skb = skb_dequeue(&ctrl_sk->receive_queue))) {
-+ skb_orphan(skb);
-+ hidp_recv_frame(session, skb);
-+ }
-+
-+ while ((skb = skb_dequeue(&intr_sk->receive_queue))) {
-+ skb_orphan(skb);
-+ hidp_recv_frame(session, skb);
-+ }
-+
-+ hidp_process_transmit(session);
-+
-+ schedule();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(intr_sk->sleep, &intr_wait);
-+ remove_wait_queue(ctrl_sk->sleep, &ctrl_wait);
-+
-+ down_write(&hidp_session_sem);
-+
-+ hidp_del_timer(session);
-+
-+ if (intr_sk->state != BT_CONNECTED) {
-+ init_waitqueue_entry(&ctrl_wait, current);
-+ add_wait_queue(ctrl_sk->sleep, &ctrl_wait);
-+ while (timeo && ctrl_sk->state != BT_CLOSED) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ timeo = schedule_timeout(timeo);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(ctrl_sk->sleep, &ctrl_wait);
-+ timeo = HZ;
-+ }
-+
-+ fput(session->ctrl_sock->file);
-+
-+ init_waitqueue_entry(&intr_wait, current);
-+ add_wait_queue(intr_sk->sleep, &intr_wait);
-+ while (timeo && intr_sk->state != BT_CLOSED) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ timeo = schedule_timeout(timeo);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(intr_sk->sleep, &intr_wait);
-+
-+ fput(session->intr_sock->file);
-+
-+ __hidp_unlink_session(session);
-+
-+ if (session->input) {
-+ input_unregister_device(session->input);
-+ kfree(session->input);
-+ }
-+
-+ up_write(&hidp_session_sem);
-+
-+ kfree(session);
-+ return 0;
-+}
-+
-+static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req)
-+{
-+ struct input_dev *input = session->input;
-+ int i;
-+
-+ input->private = session;
-+
-+ input->idbus = BUS_BLUETOOTH;
-+ input->idvendor = req->vendor;
-+ input->idproduct = req->product;
-+ input->idversion = req->version;
-+
-+ if (req->subclass & 0x40) {
-+ set_bit(EV_KEY, input->evbit);
-+ set_bit(EV_LED, input->evbit);
-+ set_bit(EV_REP, input->evbit);
-+
-+ set_bit(LED_NUML, input->ledbit);
-+ set_bit(LED_CAPSL, input->ledbit);
-+ set_bit(LED_SCROLLL, input->ledbit);
-+ set_bit(LED_COMPOSE, input->ledbit);
-+ set_bit(LED_KANA, input->ledbit);
-+
-+ for (i = 0; i < sizeof(hidp_keycode); i++)
-+ set_bit(hidp_keycode[i], input->keybit);
-+ clear_bit(0, input->keybit);
-+ }
-+
-+ if (req->subclass & 0x80) {
-+ input->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-+ input->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-+ input->relbit[0] = BIT(REL_X) | BIT(REL_Y);
-+ input->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
-+ input->relbit[0] |= BIT(REL_WHEEL);
-+ }
-+
-+ input->event = hidp_input_event;
-+
-+ input_register_device(input);
-+}
-+
-+int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
-+{
-+ struct hidp_session *session, *s;
-+ int err;
-+
-+ BT_DBG("");
-+
-+ if (bacmp(&bluez_pi(ctrl_sock->sk)->src, &bluez_pi(intr_sock->sk)->src) ||
-+ bacmp(&bluez_pi(ctrl_sock->sk)->dst, &bluez_pi(intr_sock->sk)->dst))
-+ return -ENOTUNIQ;
-+
-+ session = kmalloc(sizeof(struct hidp_session), GFP_KERNEL);
-+ if (!session)
-+ return -ENOMEM;
-+ memset(session, 0, sizeof(struct hidp_session));
-+
-+ session->input = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
-+ if (!session->input) {
-+ kfree(session);
-+ return -ENOMEM;
-+ }
-+ memset(session->input, 0, sizeof(struct input_dev));
-+
-+ down_write(&hidp_session_sem);
-+
-+ s = __hidp_get_session(&bluez_pi(ctrl_sock->sk)->dst);
-+ if (s && s->state == BT_CONNECTED) {
-+ err = -EEXIST;
-+ goto failed;
-+ }
-+
-+ bacpy(&session->bdaddr, &bluez_pi(ctrl_sock->sk)->dst);
-+
-+ session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl_sock->sk)->omtu, l2cap_pi(ctrl_sock->sk)->imtu);
-+ session->intr_mtu = min_t(uint, l2cap_pi(intr_sock->sk)->omtu, l2cap_pi(intr_sock->sk)->imtu);
-+
-+ BT_DBG("ctrl mtu %d intr mtu %d", session->ctrl_mtu, session->intr_mtu);
-+
-+ session->ctrl_sock = ctrl_sock;
-+ session->intr_sock = intr_sock;
-+ session->state = BT_CONNECTED;
-+
-+ init_timer(&session->timer);
-+
-+ session->timer.function = hidp_idle_timeout;
-+ session->timer.data = (unsigned long) session;
-+
-+ skb_queue_head_init(&session->ctrl_transmit);
-+ skb_queue_head_init(&session->intr_transmit);
-+
-+ session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID);
-+ session->idle_to = req->idle_to;
-+
-+ if (session->input)
-+ hidp_setup_input(session, req);
-+
-+ __hidp_link_session(session);
-+
-+ hidp_set_timer(session);
-+
-+ err = kernel_thread(hidp_session, session, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-+ if (err < 0)
-+ goto unlink;
-+
-+ if (session->input) {
-+ hidp_send_message(session, 0x70);
-+ session->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE);
-+
-+ session->leds = 0xff;
-+ hidp_input_event(session->input, EV_LED, 0, 0);
-+ }
-+
-+ up_write(&hidp_session_sem);
-+ return 0;
-+
-+unlink:
-+ hidp_del_timer(session);
-+
-+ __hidp_unlink_session(session);
-+
-+ if (session->input)
-+ input_unregister_device(session->input);
-+
-+failed:
-+ up_write(&hidp_session_sem);
-+
-+ if (session->input)
-+ kfree(session->input);
-+
-+ kfree(session);
-+ return err;
-+}
-+
-+int hidp_del_connection(struct hidp_conndel_req *req)
-+{
-+ struct hidp_session *session;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ down_read(&hidp_session_sem);
-+
-+ session = __hidp_get_session(&req->bdaddr);
-+ if (session) {
-+ if (req->flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG)) {
-+ hidp_send_message(session, 0x15);
-+ } else {
-+ /* Flush the transmit queues */
-+ skb_queue_purge(&session->ctrl_transmit);
-+ skb_queue_purge(&session->intr_transmit);
-+
-+ /* Kill session thread */
-+ atomic_inc(&session->terminate);
-+ hidp_schedule(session);
-+ }
-+ } else
-+ err = -ENOENT;
-+
-+ up_read(&hidp_session_sem);
-+ return err;
-+}
-+
-+int hidp_get_connlist(struct hidp_connlist_req *req)
-+{
-+ struct list_head *p;
-+ int err = 0, n = 0;
-+
-+ BT_DBG("");
-+
-+ down_read(&hidp_session_sem);
-+
-+ list_for_each(p, &hidp_session_list) {
-+ struct hidp_session *session;
-+ struct hidp_conninfo ci;
-+
-+ session = list_entry(p, struct hidp_session, list);
-+
-+ __hidp_copy_session(session, &ci);
-+
-+ if (copy_to_user(req->ci, &ci, sizeof(ci))) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ if (++n >= req->cnum)
-+ break;
-+
-+ req->ci++;
-+ }
-+ req->cnum = n;
-+
-+ up_read(&hidp_session_sem);
-+ return err;
-+}
-+
-+int hidp_get_conninfo(struct hidp_conninfo *ci)
-+{
-+ struct hidp_session *session;
-+ int err = 0;
-+
-+ down_read(&hidp_session_sem);
-+
-+ session = __hidp_get_session(&ci->bdaddr);
-+ if (session)
-+ __hidp_copy_session(session, ci);
-+ else
-+ err = -ENOENT;
-+
-+ up_read(&hidp_session_sem);
-+ return err;
-+}
-+
-+static int __init hidp_init(void)
-+{
-+ l2cap_load();
-+
-+ hidp_init_sockets();
-+
-+ BT_INFO("BlueZ HIDP ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>");
-+
-+ return 0;
-+}
-+
-+static void __exit hidp_exit(void)
-+{
-+ hidp_cleanup_sockets();
-+}
-+
-+module_init(hidp_init);
-+module_exit(hidp_exit);
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("Bluetooth HIDP ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/hidp/hidp.h linux-2.4.18-mh15/net/bluetooth/hidp/hidp.h
---- linux-2.4.18/net/bluetooth/hidp/hidp.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/hidp/hidp.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,122 @@
-+/*
-+ HIDP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#ifndef __HIDP_H
-+#define __HIDP_H
-+
-+#include <linux/types.h>
-+#include <net/bluetooth/bluetooth.h>
-+
-+/* HIDP ioctl defines */
-+#define HIDPCONNADD _IOW('H', 200, int)
-+#define HIDPCONNDEL _IOW('H', 201, int)
-+#define HIDPGETCONNLIST _IOR('H', 210, int)
-+#define HIDPGETCONNINFO _IOR('H', 211, int)
-+
-+#define HIDP_VIRTUAL_CABLE_UNPLUG 0
-+#define HIDP_BOOT_PROTOCOL_MODE 1
-+#define HIDP_BLUETOOTH_VENDOR_ID 9
-+
-+struct hidp_connadd_req {
-+ int ctrl_sock; // Connected control socket
-+ int intr_sock; // Connteted interrupt socket
-+ __u16 parser;
-+ __u16 rd_size;
-+ __u8 *rd_data;
-+ __u8 country;
-+ __u8 subclass;
-+ __u16 vendor;
-+ __u16 product;
-+ __u16 version;
-+ __u32 flags;
-+ __u32 idle_to;
-+ char name[128];
-+};
-+
-+struct hidp_conndel_req {
-+ bdaddr_t bdaddr;
-+ __u32 flags;
-+};
-+
-+struct hidp_conninfo {
-+ bdaddr_t bdaddr;
-+ __u32 flags;
-+ __u16 state;
-+ __u16 vendor;
-+ __u16 product;
-+ __u16 version;
-+ char name[128];
-+};
-+
-+struct hidp_connlist_req {
-+ __u32 cnum;
-+ struct hidp_conninfo *ci;
-+};
-+
-+int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock);
-+int hidp_del_connection(struct hidp_conndel_req *req);
-+int hidp_get_connlist(struct hidp_connlist_req *req);
-+int hidp_get_conninfo(struct hidp_conninfo *ci);
-+
-+/* HIDP session defines */
-+struct hidp_session {
-+ struct list_head list;
-+
-+ struct socket *ctrl_sock;
-+ struct socket *intr_sock;
-+
-+ bdaddr_t bdaddr;
-+
-+ unsigned long state;
-+ unsigned long flags;
-+ unsigned long idle_to;
-+
-+ uint ctrl_mtu;
-+ uint intr_mtu;
-+
-+ atomic_t terminate;
-+
-+ unsigned char keys[8];
-+ unsigned char leds;
-+
-+ struct input_dev *input;
-+
-+ struct timer_list timer;
-+
-+ struct sk_buff_head ctrl_transmit;
-+ struct sk_buff_head intr_transmit;
-+};
-+
-+static inline void hidp_schedule(struct hidp_session *session)
-+{
-+ struct sock *ctrl_sk = session->ctrl_sock->sk;
-+ struct sock *intr_sk = session->intr_sock->sk;
-+
-+ wake_up_interruptible(ctrl_sk->sleep);
-+ wake_up_interruptible(intr_sk->sleep);
-+}
-+
-+/* HIDP init defines */
-+extern int __init hidp_init_sockets(void);
-+extern void __exit hidp_cleanup_sockets(void);
-+
-+#endif /* __HIDP_H */
-diff -urN linux-2.4.18/net/bluetooth/hidp/Makefile linux-2.4.18-mh15/net/bluetooth/hidp/Makefile
---- linux-2.4.18/net/bluetooth/hidp/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/hidp/Makefile 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the Linux Bluetooth HIDP layer
-+#
-+
-+O_TARGET := hidp.o
-+
-+obj-y := core.o sock.o
-+obj-m += $(O_TARGET)
-+
-+include $(TOPDIR)/Rules.make
-diff -urN linux-2.4.18/net/bluetooth/hidp/sock.c linux-2.4.18-mh15/net/bluetooth/hidp/sock.c
---- linux-2.4.18/net/bluetooth/hidp/sock.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/hidp/sock.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,212 @@
-+/*
-+ HIDP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <linux/init.h>
-+#include <net/sock.h>
-+
-+#include "hidp.h"
-+
-+#ifndef CONFIG_BT_HIDP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+static int hidp_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ sock_orphan(sk);
-+ sock_put(sk);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct hidp_connadd_req ca;
-+ struct hidp_conndel_req cd;
-+ struct hidp_connlist_req cl;
-+ struct hidp_conninfo ci;
-+ struct socket *csock;
-+ struct socket *isock;
-+ int err;
-+
-+ BT_DBG("cmd %x arg %lx", cmd, arg);
-+
-+ switch (cmd) {
-+ case HIDPCONNADD:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
-+ return -EFAULT;
-+
-+ csock = sockfd_lookup(ca.ctrl_sock, &err);
-+ if (!csock)
-+ return err;
-+
-+ isock = sockfd_lookup(ca.intr_sock, &err);
-+ if (!isock) {
-+ fput(csock->file);
-+ return err;
-+ }
-+
-+ if (csock->sk->state != BT_CONNECTED || isock->sk->state != BT_CONNECTED) {
-+ fput(csock->file);
-+ fput(isock->file);
-+ return -EBADFD;
-+ }
-+
-+ err = hidp_add_connection(&ca, csock, isock);
-+ if (!err) {
-+ if (copy_to_user((void *) arg, &ca, sizeof(ca)))
-+ err = -EFAULT;
-+ } else {
-+ fput(csock->file);
-+ fput(isock->file);
-+ }
-+
-+ return err;
-+
-+ case HIDPCONNDEL:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
-+ return -EFAULT;
-+
-+ return hidp_del_connection(&cd);
-+
-+ case HIDPGETCONNLIST:
-+ if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
-+ return -EFAULT;
-+
-+ if (cl.cnum <= 0)
-+ return -EINVAL;
-+
-+ err = hidp_get_connlist(&cl);
-+ if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
-+ return -EFAULT;
-+
-+ return err;
-+
-+ case HIDPGETCONNINFO:
-+ if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
-+ return -EFAULT;
-+
-+ err = hidp_get_conninfo(&ci);
-+ if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
-+ return -EFAULT;
-+
-+ return err;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static struct proto_ops hidp_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: hidp_sock_release,
-+ ioctl: hidp_sock_ioctl,
-+ bind: sock_no_bind,
-+ getname: sock_no_getname,
-+ sendmsg: sock_no_sendmsg,
-+ recvmsg: sock_no_recvmsg,
-+ poll: sock_no_poll,
-+ listen: sock_no_listen,
-+ shutdown: sock_no_shutdown,
-+ setsockopt: sock_no_setsockopt,
-+ getsockopt: sock_no_getsockopt,
-+ connect: sock_no_connect,
-+ socketpair: sock_no_socketpair,
-+ accept: sock_no_accept,
-+ mmap: sock_no_mmap
-+};
-+
-+static int hidp_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ if (sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &hidp_sock_ops;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, 1)))
-+ return -ENOMEM;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ sock->state = SS_UNCONNECTED;
-+ sock_init_data(sock, sk);
-+
-+ sk->destruct = NULL;
-+ sk->protocol = protocol;
-+
-+ return 0;
-+}
-+
-+static struct net_proto_family hidp_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: hidp_sock_create
-+};
-+
-+int __init hidp_init_sockets(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_HIDP, &hidp_sock_family_ops)))
-+ BT_ERR("Can't register HIDP socket layer (%d)", err);
-+
-+ return err;
-+}
-+
-+void __exit hidp_cleanup_sockets(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_unregister(BTPROTO_HIDP)))
-+ BT_ERR("Can't unregister HIDP socket layer (%d)", err);
-+}
-diff -urN linux-2.4.18/net/bluetooth/l2cap.c linux-2.4.18-mh15/net/bluetooth/l2cap.c
---- linux-2.4.18/net/bluetooth/l2cap.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/l2cap.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,2222 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * BlueZ L2CAP core and sockets.
-+ *
-+ * $Id$
-+ */
-+#define VERSION "2.3"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/socket.h>
-+#include <linux/skbuff.h>
-+#include <linux/proc_fs.h>
-+#include <linux/list.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#ifndef L2CAP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+static struct proto_ops l2cap_sock_ops;
-+
-+struct bluez_sock_list l2cap_sk_list = {
-+ lock: RW_LOCK_UNLOCKED
-+};
-+
-+static int l2cap_conn_del(struct hci_conn *conn, int err);
-+
-+static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
-+static void l2cap_chan_del(struct sock *sk, int err);
-+static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len);
-+
-+static void __l2cap_sock_close(struct sock *sk, int reason);
-+static void l2cap_sock_close(struct sock *sk);
-+static void l2cap_sock_kill(struct sock *sk);
-+
-+static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data);
-+static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data);
-+
-+/* ----- L2CAP timers ------ */
-+static void l2cap_sock_timeout(unsigned long arg)
-+{
-+ struct sock *sk = (struct sock *) arg;
-+
-+ BT_DBG("sock %p state %d", sk, sk->state);
-+
-+ bh_lock_sock(sk);
-+ __l2cap_sock_close(sk, ETIMEDOUT);
-+ bh_unlock_sock(sk);
-+
-+ l2cap_sock_kill(sk);
-+ sock_put(sk);
-+}
-+
-+static void l2cap_sock_set_timer(struct sock *sk, long timeout)
-+{
-+ BT_DBG("sk %p state %d timeout %ld", sk, sk->state, timeout);
-+
-+ if (!mod_timer(&sk->timer, jiffies + timeout))
-+ sock_hold(sk);
-+}
-+
-+static void l2cap_sock_clear_timer(struct sock *sk)
-+{
-+ BT_DBG("sock %p state %d", sk, sk->state);
-+
-+ if (timer_pending(&sk->timer) && del_timer(&sk->timer))
-+ __sock_put(sk);
-+}
-+
-+static void l2cap_sock_init_timer(struct sock *sk)
-+{
-+ init_timer(&sk->timer);
-+ sk->timer.function = l2cap_sock_timeout;
-+ sk->timer.data = (unsigned long)sk;
-+}
-+
-+/* -------- L2CAP connections --------- */
-+static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, __u8 status)
-+{
-+ struct l2cap_conn *conn;
-+
-+ if ((conn = hcon->l2cap_data))
-+ return conn;
-+
-+ if (status)
-+ return conn;
-+
-+ if (!(conn = kmalloc(sizeof(struct l2cap_conn), GFP_ATOMIC)))
-+ return NULL;
-+ memset(conn, 0, sizeof(struct l2cap_conn));
-+
-+ hcon->l2cap_data = conn;
-+ conn->hcon = hcon;
-+
-+ conn->mtu = hcon->hdev->acl_mtu;
-+ conn->src = &hcon->hdev->bdaddr;
-+ conn->dst = &hcon->dst;
-+
-+ spin_lock_init(&conn->lock);
-+ conn->chan_list.lock = RW_LOCK_UNLOCKED;
-+
-+ BT_DBG("hcon %p conn %p", hcon, conn);
-+
-+ MOD_INC_USE_COUNT;
-+ return conn;
-+}
-+
-+static int l2cap_conn_del(struct hci_conn *hcon, int err)
-+{
-+ struct l2cap_conn *conn;
-+ struct sock *sk;
-+
-+ if (!(conn = hcon->l2cap_data))
-+ return 0;
-+
-+ BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
-+
-+ if (conn->rx_skb)
-+ kfree_skb(conn->rx_skb);
-+
-+ /* Kill channels */
-+ while ((sk = conn->chan_list.head)) {
-+ bh_lock_sock(sk);
-+ l2cap_chan_del(sk, err);
-+ bh_unlock_sock(sk);
-+ l2cap_sock_kill(sk);
-+ }
-+
-+ hcon->l2cap_data = NULL;
-+ kfree(conn);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+/* -------- Socket interface ---------- */
-+static struct sock *__l2cap_get_sock_by_addr(__u16 psm, bdaddr_t *src)
-+{
-+ struct sock *sk;
-+ for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-+ if (sk->sport == psm && !bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+ }
-+ return sk;
-+}
-+
-+/* Find socket with psm and source bdaddr.
-+ * Returns closest match.
-+ */
-+static struct sock *__l2cap_get_sock_by_psm(int state, __u16 psm, bdaddr_t *src)
-+{
-+ struct sock *sk, *sk1 = NULL;
-+
-+ for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-+ if (state && sk->state != state)
-+ continue;
-+
-+ if (l2cap_pi(sk)->psm == psm) {
-+ /* Exact match. */
-+ if (!bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+
-+ /* Closest match */
-+ if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
-+ sk1 = sk;
-+ }
-+ }
-+ return sk ? sk : sk1;
-+}
-+
-+/* Find socket with given address (psm, src).
-+ * Returns locked socket */
-+static inline struct sock *l2cap_get_sock_by_psm(int state, __u16 psm, bdaddr_t *src)
-+{
-+ struct sock *s;
-+ read_lock(&l2cap_sk_list.lock);
-+ s = __l2cap_get_sock_by_psm(state, psm, src);
-+ if (s) bh_lock_sock(s);
-+ read_unlock(&l2cap_sk_list.lock);
-+ return s;
-+}
-+
-+static void l2cap_sock_destruct(struct sock *sk)
-+{
-+ BT_DBG("sk %p", sk);
-+
-+ skb_queue_purge(&sk->receive_queue);
-+ skb_queue_purge(&sk->write_queue);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void l2cap_sock_cleanup_listen(struct sock *parent)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("parent %p", parent);
-+
-+ /* Close not yet accepted channels */
-+ while ((sk = bluez_accept_dequeue(parent, NULL)))
-+ l2cap_sock_close(sk);
-+
-+ parent->state = BT_CLOSED;
-+ parent->zapped = 1;
-+}
-+
-+/* Kill socket (only if zapped and orphan)
-+ * Must be called on unlocked socket.
-+ */
-+static void l2cap_sock_kill(struct sock *sk)
-+{
-+ if (!sk->zapped || sk->socket)
-+ return;
-+
-+ BT_DBG("sk %p state %d", sk, sk->state);
-+
-+ /* Kill poor orphan */
-+ bluez_sock_unlink(&l2cap_sk_list, sk);
-+ sk->dead = 1;
-+ sock_put(sk);
-+}
-+
-+/* Close socket.
-+ */
-+static void __l2cap_sock_close(struct sock *sk, int reason)
-+{
-+ BT_DBG("sk %p state %d socket %p", sk, sk->state, sk->socket);
-+
-+ switch (sk->state) {
-+ case BT_LISTEN:
-+ l2cap_sock_cleanup_listen(sk);
-+ break;
-+
-+ case BT_CONNECTED:
-+ case BT_CONFIG:
-+ case BT_CONNECT2:
-+ if (sk->type == SOCK_SEQPACKET) {
-+ struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-+ l2cap_disconn_req req;
-+
-+ sk->state = BT_DISCONN;
-+ l2cap_sock_set_timer(sk, sk->sndtimeo);
-+
-+ req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
-+ } else {
-+ l2cap_chan_del(sk, reason);
-+ }
-+ break;
-+
-+ case BT_CONNECT:
-+ case BT_DISCONN:
-+ l2cap_chan_del(sk, reason);
-+ break;
-+
-+ default:
-+ sk->zapped = 1;
-+ break;
-+ };
-+}
-+
-+/* Must be called on unlocked socket. */
-+static void l2cap_sock_close(struct sock *sk)
-+{
-+ l2cap_sock_clear_timer(sk);
-+ lock_sock(sk);
-+ __l2cap_sock_close(sk, ECONNRESET);
-+ release_sock(sk);
-+ l2cap_sock_kill(sk);
-+}
-+
-+static void l2cap_sock_init(struct sock *sk, struct sock *parent)
-+{
-+ struct l2cap_pinfo *pi = l2cap_pi(sk);
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (parent) {
-+ sk->type = parent->type;
-+ pi->imtu = l2cap_pi(parent)->imtu;
-+ pi->omtu = l2cap_pi(parent)->omtu;
-+ pi->link_mode = l2cap_pi(parent)->link_mode;
-+ } else {
-+ pi->imtu = L2CAP_DEFAULT_MTU;
-+ pi->omtu = 0;
-+ pi->link_mode = 0;
-+ }
-+
-+ /* Default config options */
-+ pi->conf_mtu = L2CAP_DEFAULT_MTU;
-+ pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
-+}
-+
-+static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
-+{
-+ struct sock *sk;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
-+ return NULL;
-+
-+ bluez_sock_init(sock, sk);
-+
-+ sk->zapped = 0;
-+
-+ sk->destruct = l2cap_sock_destruct;
-+ sk->sndtimeo = L2CAP_CONN_TIMEOUT;
-+
-+ sk->protocol = proto;
-+ sk->state = BT_OPEN;
-+
-+ l2cap_sock_init_timer(sk);
-+
-+ bluez_sock_link(&l2cap_sk_list, sk);
-+
-+ MOD_INC_USE_COUNT;
-+ return sk;
-+}
-+
-+static int l2cap_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ sock->state = SS_UNCONNECTED;
-+
-+ if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ if (sock->type == SOCK_RAW && !capable(CAP_NET_RAW))
-+ return -EPERM;
-+
-+ sock->ops = &l2cap_sock_ops;
-+
-+ if (!(sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ l2cap_sock_init(sk, NULL);
-+ return 0;
-+}
-+
-+static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
-+{
-+ struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
-+
-+ if (!addr || addr->sa_family != AF_BLUETOOTH)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_OPEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ write_lock_bh(&l2cap_sk_list.lock);
-+ if (la->l2_psm && __l2cap_get_sock_by_addr(la->l2_psm, &la->l2_bdaddr)) {
-+ err = -EADDRINUSE;
-+ } else {
-+ /* Save source address */
-+ bacpy(&bluez_pi(sk)->src, &la->l2_bdaddr);
-+ l2cap_pi(sk)->psm = la->l2_psm;
-+ sk->sport = la->l2_psm;
-+ sk->state = BT_BOUND;
-+ }
-+ write_unlock_bh(&l2cap_sk_list.lock);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_do_connect(struct sock *sk)
-+{
-+ bdaddr_t *src = &bluez_pi(sk)->src;
-+ bdaddr_t *dst = &bluez_pi(sk)->dst;
-+ struct l2cap_conn *conn;
-+ struct hci_conn *hcon;
-+ struct hci_dev *hdev;
-+ int err = 0;
-+
-+ BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
-+
-+ if (!(hdev = hci_get_route(dst, src)))
-+ return -EHOSTUNREACH;
-+
-+ hci_dev_lock_bh(hdev);
-+
-+ err = -ENOMEM;
-+
-+ hcon = hci_connect(hdev, ACL_LINK, dst);
-+ if (!hcon)
-+ goto done;
-+
-+ conn = l2cap_conn_add(hcon, 0);
-+ if (!conn) {
-+ hci_conn_put(hcon);
-+ goto done;
-+ }
-+
-+ err = 0;
-+
-+ /* Update source addr of the socket */
-+ bacpy(src, conn->src);
-+
-+ l2cap_chan_add(conn, sk, NULL);
-+
-+ sk->state = BT_CONNECT;
-+ l2cap_sock_set_timer(sk, sk->sndtimeo);
-+
-+ if (hcon->state == BT_CONNECTED) {
-+ if (sk->type == SOCK_SEQPACKET) {
-+ l2cap_conn_req req;
-+ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ req.psm = l2cap_pi(sk)->psm;
-+ l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
-+ } else {
-+ l2cap_sock_clear_timer(sk);
-+ sk->state = BT_CONNECTED;
-+ }
-+ }
-+
-+done:
-+ hci_dev_unlock_bh(hdev);
-+ hci_dev_put(hdev);
-+ return err;
-+}
-+
-+static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
-+{
-+ struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ lock_sock(sk);
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) {
-+ err = -EINVAL;
-+ goto done;
-+ }
-+
-+ if (sk->type == SOCK_SEQPACKET && !la->l2_psm) {
-+ err = -EINVAL;
-+ goto done;
-+ }
-+
-+ switch(sk->state) {
-+ case BT_CONNECT:
-+ case BT_CONNECT2:
-+ case BT_CONFIG:
-+ /* Already connecting */
-+ goto wait;
-+
-+ case BT_CONNECTED:
-+ /* Already connected */
-+ goto done;
-+
-+ case BT_OPEN:
-+ case BT_BOUND:
-+ /* Can connect */
-+ break;
-+
-+ default:
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ /* Set destination address and psm */
-+ bacpy(&bluez_pi(sk)->dst, &la->l2_bdaddr);
-+ l2cap_pi(sk)->psm = la->l2_psm;
-+
-+ if ((err = l2cap_do_connect(sk)))
-+ goto done;
-+
-+wait:
-+ err = bluez_sock_wait_state(sk, BT_CONNECTED,
-+ sock_sndtimeo(sk, flags & O_NONBLOCK));
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int l2cap_sock_listen(struct socket *sock, int backlog)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p backlog %d", sk, backlog);
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ if (!l2cap_pi(sk)->psm) {
-+ err = -EINVAL;
-+ goto done;
-+ }
-+
-+ sk->max_ack_backlog = backlog;
-+ sk->ack_backlog = 0;
-+ sk->state = BT_LISTEN;
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct sock *sk = sock->sk, *nsk;
-+ long timeo;
-+ int err = 0;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
-+
-+ BT_DBG("sk %p timeo %ld", sk, timeo);
-+
-+ /* Wait for an incoming connection. (wake-one). */
-+ add_wait_queue_exclusive(sk->sleep, &wait);
-+ while (!(nsk = bluez_accept_dequeue(sk, newsock))) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ break;
-+ }
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ break;
-+ }
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ if (err)
-+ goto done;
-+
-+ newsock->state = SS_CONNECTED;
-+
-+ BT_DBG("new socket %p", nsk);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
-+{
-+ struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ addr->sa_family = AF_BLUETOOTH;
-+ *len = sizeof(struct sockaddr_l2);
-+
-+ if (peer)
-+ bacpy(&la->l2_bdaddr, &bluez_pi(sk)->dst);
-+ else
-+ bacpy(&la->l2_bdaddr, &bluez_pi(sk)->src);
-+
-+ la->l2_psm = l2cap_pi(sk)->psm;
-+ return 0;
-+}
-+
-+static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (sk->err)
-+ return sock_error(sk);
-+
-+ if (msg->msg_flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ /* Check outgoing MTU */
-+ if (len > l2cap_pi(sk)->omtu)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state == BT_CONNECTED)
-+ err = l2cap_chan_send(sk, msg, len);
-+ else
-+ err = -ENOTCONN;
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ struct l2cap_options opts;
-+ int err = 0, len;
-+ __u32 opt;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ case L2CAP_OPTIONS:
-+ len = MIN(sizeof(opts), optlen);
-+ if (copy_from_user((char *)&opts, optval, len)) {
-+ err = -EFAULT;
-+ break;
-+ }
-+ l2cap_pi(sk)->imtu = opts.imtu;
-+ l2cap_pi(sk)->omtu = opts.omtu;
-+ break;
-+
-+ case L2CAP_LM:
-+ if (get_user(opt, (__u32 *)optval)) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ l2cap_pi(sk)->link_mode = opt;
-+ break;
-+
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ struct l2cap_options opts;
-+ struct l2cap_conninfo cinfo;
-+ int len, err = 0;
-+
-+ if (get_user(len, optlen))
-+ return -EFAULT;
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ case L2CAP_OPTIONS:
-+ opts.imtu = l2cap_pi(sk)->imtu;
-+ opts.omtu = l2cap_pi(sk)->omtu;
-+ opts.flush_to = l2cap_pi(sk)->flush_to;
-+
-+ len = MIN(len, sizeof(opts));
-+ if (copy_to_user(optval, (char *)&opts, len))
-+ err = -EFAULT;
-+
-+ break;
-+
-+ case L2CAP_LM:
-+ if (put_user(l2cap_pi(sk)->link_mode, (__u32 *)optval))
-+ err = -EFAULT;
-+ break;
-+
-+ case L2CAP_CONNINFO:
-+ if (sk->state != BT_CONNECTED) {
-+ err = -ENOTCONN;
-+ break;
-+ }
-+
-+ cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
-+
-+ len = MIN(len, sizeof(cinfo));
-+ if (copy_to_user(optval, (char *)&cinfo, len))
-+ err = -EFAULT;
-+
-+ break;
-+
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_shutdown(struct socket *sock, int how)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk) return 0;
-+
-+ lock_sock(sk);
-+ if (!sk->shutdown) {
-+ sk->shutdown = SHUTDOWN_MASK;
-+ l2cap_sock_clear_timer(sk);
-+ __l2cap_sock_close(sk, 0);
-+
-+ if (sk->linger)
-+ err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
-+ }
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+ int err;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk) return 0;
-+
-+ err = l2cap_sock_shutdown(sock, 2);
-+
-+ sock_orphan(sk);
-+ l2cap_sock_kill(sk);
-+ return err;
-+}
-+
-+/* --------- L2CAP channels --------- */
-+static struct sock * __l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
-+{
-+ struct sock *s;
-+ for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-+ if (l2cap_pi(s)->dcid == cid)
-+ break;
-+ }
-+ return s;
-+}
-+
-+static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
-+{
-+ struct sock *s;
-+ for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-+ if (l2cap_pi(s)->scid == cid)
-+ break;
-+ }
-+ return s;
-+}
-+
-+/* Find channel with given SCID.
-+ * Returns locked socket */
-+static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
-+{
-+ struct sock *s;
-+ read_lock(&l->lock);
-+ s = __l2cap_get_chan_by_scid(l, cid);
-+ if (s) bh_lock_sock(s);
-+ read_unlock(&l->lock);
-+ return s;
-+}
-+
-+static __u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
-+{
-+ __u16 cid = 0x0040;
-+
-+ for (; cid < 0xffff; cid++) {
-+ if(!__l2cap_get_chan_by_scid(l, cid))
-+ return cid;
-+ }
-+
-+ return 0;
-+}
-+
-+static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
-+{
-+ sock_hold(sk);
-+
-+ if (l->head)
-+ l2cap_pi(l->head)->prev_c = sk;
-+
-+ l2cap_pi(sk)->next_c = l->head;
-+ l2cap_pi(sk)->prev_c = NULL;
-+ l->head = sk;
-+}
-+
-+static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
-+{
-+ struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
-+
-+ write_lock(&l->lock);
-+ if (sk == l->head)
-+ l->head = next;
-+
-+ if (next)
-+ l2cap_pi(next)->prev_c = prev;
-+ if (prev)
-+ l2cap_pi(prev)->next_c = next;
-+ write_unlock(&l->lock);
-+
-+ __sock_put(sk);
-+}
-+
-+static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+
-+ BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
-+
-+ l2cap_pi(sk)->conn = conn;
-+
-+ if (sk->type == SOCK_SEQPACKET) {
-+ /* Alloc CID for connection-oriented socket */
-+ l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
-+ } else if (sk->type == SOCK_DGRAM) {
-+ /* Connectionless socket */
-+ l2cap_pi(sk)->scid = 0x0002;
-+ l2cap_pi(sk)->dcid = 0x0002;
-+ l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
-+ } else {
-+ /* Raw socket can send/recv signalling messages only */
-+ l2cap_pi(sk)->scid = 0x0001;
-+ l2cap_pi(sk)->dcid = 0x0001;
-+ l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
-+ }
-+
-+ __l2cap_chan_link(l, sk);
-+
-+ if (parent)
-+ bluez_accept_enqueue(parent, sk);
-+}
-+
-+static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+ write_lock(&l->lock);
-+ __l2cap_chan_add(conn, sk, parent);
-+ write_unlock(&l->lock);
-+}
-+
-+/* Delete channel.
-+ * Must be called on the locked socket. */
-+static void l2cap_chan_del(struct sock *sk, int err)
-+{
-+ struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-+ struct sock *parent = bluez_pi(sk)->parent;
-+
-+ l2cap_sock_clear_timer(sk);
-+
-+ BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
-+
-+ if (conn) {
-+ /* Unlink from channel list */
-+ l2cap_chan_unlink(&conn->chan_list, sk);
-+ l2cap_pi(sk)->conn = NULL;
-+ hci_conn_put(conn->hcon);
-+ }
-+
-+ sk->state = BT_CLOSED;
-+ sk->zapped = 1;
-+
-+ if (err)
-+ sk->err = err;
-+
-+ if (parent)
-+ parent->data_ready(parent, 0);
-+ else
-+ sk->state_change(sk);
-+}
-+
-+static void l2cap_conn_ready(struct l2cap_conn *conn)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+ struct sock *sk;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ bh_lock_sock(sk);
-+
-+ if (sk->type != SOCK_SEQPACKET) {
-+ l2cap_sock_clear_timer(sk);
-+ sk->state = BT_CONNECTED;
-+ sk->state_change(sk);
-+ } else if (sk->state == BT_CONNECT) {
-+ l2cap_conn_req req;
-+ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ req.psm = l2cap_pi(sk)->psm;
-+ l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
-+ }
-+
-+ bh_unlock_sock(sk);
-+ }
-+
-+ read_unlock(&l->lock);
-+}
-+
-+/* Notify sockets that we cannot guaranty reliability anymore */
-+static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+ struct sock *sk;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ if (l2cap_pi(sk)->link_mode & L2CAP_LM_RELIABLE)
-+ sk->err = err;
-+ }
-+ read_unlock(&l->lock);
-+}
-+
-+static void l2cap_chan_ready(struct sock *sk)
-+{
-+ struct sock *parent = bluez_pi(sk)->parent;
-+
-+ BT_DBG("sk %p, parent %p", sk, parent);
-+
-+ l2cap_pi(sk)->conf_state = 0;
-+ l2cap_sock_clear_timer(sk);
-+
-+ if (!parent) {
-+ /* Outgoing channel.
-+ * Wake up socket sleeping on connect.
-+ */
-+ sk->state = BT_CONNECTED;
-+ sk->state_change(sk);
-+ } else {
-+ /* Incomming channel.
-+ * Wake up socket sleeping on accept.
-+ */
-+ parent->data_ready(parent, 0);
-+ }
-+}
-+
-+/* Copy frame to all raw sockets on that connection */
-+void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+ struct sk_buff *nskb;
-+ struct sock * sk;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ if (sk->type != SOCK_RAW)
-+ continue;
-+
-+ /* Don't send frame to the socket it came from */
-+ if (skb->sk == sk)
-+ continue;
-+
-+ if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
-+ continue;
-+
-+ if (sock_queue_rcv_skb(sk, nskb))
-+ kfree_skb(nskb);
-+ }
-+ read_unlock(&l->lock);
-+}
-+
-+static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
-+{
-+ struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-+ struct sk_buff *skb, **frag;
-+ int err, hlen, count, sent=0;
-+ l2cap_hdr *lh;
-+
-+ BT_DBG("sk %p len %d", sk, len);
-+
-+ /* First fragment (with L2CAP header) */
-+ if (sk->type == SOCK_DGRAM)
-+ hlen = L2CAP_HDR_SIZE + 2;
-+ else
-+ hlen = L2CAP_HDR_SIZE;
-+
-+ count = MIN(conn->mtu - hlen, len);
-+
-+ skb = bluez_skb_send_alloc(sk, hlen + count,
-+ msg->msg_flags & MSG_DONTWAIT, &err);
-+ if (!skb)
-+ return err;
-+
-+ /* Create L2CAP header */
-+ lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-+ lh->cid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ lh->len = __cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
-+
-+ if (sk->type == SOCK_DGRAM)
-+ put_unaligned(l2cap_pi(sk)->psm, (__u16 *) skb_put(skb, 2));
-+
-+ if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
-+ err = -EFAULT;
-+ goto fail;
-+ }
-+
-+ sent += count;
-+ len -= count;
-+
-+ /* Continuation fragments (no L2CAP header) */
-+ frag = &skb_shinfo(skb)->frag_list;
-+ while (len) {
-+ count = MIN(conn->mtu, len);
-+
-+ *frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
-+ if (!*frag)
-+ goto fail;
-+
-+ if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
-+ err = -EFAULT;
-+ goto fail;
-+ }
-+
-+ sent += count;
-+ len -= count;
-+
-+ frag = &(*frag)->next;
-+ }
-+
-+ if ((err = hci_send_acl(conn->hcon, skb, 0)) < 0)
-+ goto fail;
-+
-+ return sent;
-+
-+fail:
-+ kfree_skb(skb);
-+ return err;
-+}
-+
-+/* --------- L2CAP signalling commands --------- */
-+static inline __u8 l2cap_get_ident(struct l2cap_conn *conn)
-+{
-+ __u8 id;
-+
-+ /* Get next available identificator.
-+ * 1 - 199 are used by kernel.
-+ * 200 - 254 are used by utilities like l2ping, etc
-+ */
-+
-+ spin_lock(&conn->lock);
-+
-+ if (++conn->tx_ident > 199)
-+ conn->tx_ident = 1;
-+
-+ id = conn->tx_ident;
-+
-+ spin_unlock(&conn->lock);
-+
-+ return id;
-+}
-+
-+static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
-+ __u8 code, __u8 ident, __u16 dlen, void *data)
-+{
-+ struct sk_buff *skb, **frag;
-+ l2cap_cmd_hdr *cmd;
-+ l2cap_hdr *lh;
-+ int len, count;
-+
-+ BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", conn, code, ident, dlen);
-+
-+ len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
-+ count = MIN(conn->mtu, len);
-+
-+ skb = bluez_skb_alloc(count, GFP_ATOMIC);
-+ if (!skb)
-+ return NULL;
-+
-+ lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-+ lh->len = __cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
-+ lh->cid = __cpu_to_le16(0x0001);
-+
-+ cmd = (l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
-+ cmd->code = code;
-+ cmd->ident = ident;
-+ cmd->len = __cpu_to_le16(dlen);
-+
-+ if (dlen) {
-+ count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
-+ memcpy(skb_put(skb, count), data, count);
-+ data += count;
-+ }
-+
-+ len -= skb->len;
-+
-+ /* Continuation fragments (no L2CAP header) */
-+ frag = &skb_shinfo(skb)->frag_list;
-+ while (len) {
-+ count = MIN(conn->mtu, len);
-+
-+ *frag = bluez_skb_alloc(count, GFP_ATOMIC);
-+ if (!*frag)
-+ goto fail;
-+
-+ memcpy(skb_put(*frag, count), data, count);
-+
-+ len -= count;
-+ data += count;
-+
-+ frag = &(*frag)->next;
-+ }
-+
-+ return skb;
-+
-+fail:
-+ kfree_skb(skb);
-+ return NULL;
-+}
-+
-+static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data)
-+{
-+ __u8 ident = l2cap_get_ident(conn);
-+ struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
-+
-+ BT_DBG("code 0x%2.2x", code);
-+
-+ if (!skb)
-+ return -ENOMEM;
-+ return hci_send_acl(conn->hcon, skb, 0);
-+}
-+
-+static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data)
-+{
-+ struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
-+
-+ BT_DBG("code 0x%2.2x", code);
-+
-+ if (!skb)
-+ return -ENOMEM;
-+ return hci_send_acl(conn->hcon, skb, 0);
-+}
-+
-+static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
-+{
-+ l2cap_conf_opt *opt = *ptr;
-+ int len;
-+
-+ len = L2CAP_CONF_OPT_SIZE + opt->len;
-+ *ptr += len;
-+
-+ *type = opt->type;
-+ *olen = opt->len;
-+
-+ switch (opt->len) {
-+ case 1:
-+ *val = *((__u8 *) opt->val);
-+ break;
-+
-+ case 2:
-+ *val = __le16_to_cpu(*((__u16 *)opt->val));
-+ break;
-+
-+ case 4:
-+ *val = __le32_to_cpu(*((__u32 *)opt->val));
-+ break;
-+
-+ default:
-+ *val = (unsigned long) opt->val;
-+ break;
-+ };
-+
-+ BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
-+ return len;
-+}
-+
-+static inline void l2cap_parse_conf_req(struct sock *sk, void *data, int len)
-+{
-+ int type, hint, olen;
-+ unsigned long val;
-+ void *ptr = data;
-+
-+ BT_DBG("sk %p len %d", sk, len);
-+
-+ while (len >= L2CAP_CONF_OPT_SIZE) {
-+ len -= l2cap_get_conf_opt(&ptr, &type, &olen, &val);
-+
-+ hint = type & 0x80;
-+ type &= 0x7f;
-+
-+ switch (type) {
-+ case L2CAP_CONF_MTU:
-+ l2cap_pi(sk)->conf_mtu = val;
-+ break;
-+
-+ case L2CAP_CONF_FLUSH_TO:
-+ l2cap_pi(sk)->flush_to = val;
-+ break;
-+
-+ case L2CAP_CONF_QOS:
-+ break;
-+
-+ default:
-+ if (hint)
-+ break;
-+
-+ /* FIXME: Reject unknown option */
-+ break;
-+ };
-+ }
-+}
-+
-+static void l2cap_add_conf_opt(void **ptr, __u8 type, __u8 len, unsigned long val)
-+{
-+ register l2cap_conf_opt *opt = *ptr;
-+
-+ BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
-+
-+ opt->type = type;
-+ opt->len = len;
-+
-+ switch (len) {
-+ case 1:
-+ *((__u8 *) opt->val) = val;
-+ break;
-+
-+ case 2:
-+ *((__u16 *) opt->val) = __cpu_to_le16(val);
-+ break;
-+
-+ case 4:
-+ *((__u32 *) opt->val) = __cpu_to_le32(val);
-+ break;
-+
-+ default:
-+ memcpy(opt->val, (void *) val, len);
-+ break;
-+ };
-+
-+ *ptr += L2CAP_CONF_OPT_SIZE + len;
-+}
-+
-+static int l2cap_build_conf_req(struct sock *sk, void *data)
-+{
-+ struct l2cap_pinfo *pi = l2cap_pi(sk);
-+ l2cap_conf_req *req = (l2cap_conf_req *) data;
-+ void *ptr = req->data;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (pi->imtu != L2CAP_DEFAULT_MTU)
-+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
-+
-+ /* FIXME. Need actual value of the flush timeout */
-+ //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
-+ // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
-+
-+ req->dcid = __cpu_to_le16(pi->dcid);
-+ req->flags = __cpu_to_le16(0);
-+
-+ return ptr - data;
-+}
-+
-+static inline int l2cap_conf_output(struct sock *sk, void **ptr)
-+{
-+ struct l2cap_pinfo *pi = l2cap_pi(sk);
-+ int result = 0;
-+
-+ /* Configure output options and let the other side know
-+ * which ones we don't like.
-+ */
-+ if (pi->conf_mtu < pi->omtu) {
-+ l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu);
-+ result = L2CAP_CONF_UNACCEPT;
-+ } else {
-+ pi->omtu = pi->conf_mtu;
-+ }
-+
-+ BT_DBG("sk %p result %d", sk, result);
-+ return result;
-+}
-+
-+static int l2cap_build_conf_rsp(struct sock *sk, void *data, int *result)
-+{
-+ l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data;
-+ void *ptr = rsp->data;
-+ u16 flags = 0;
-+
-+ BT_DBG("sk %p complete %d", sk, result ? 1 : 0);
-+
-+ if (result)
-+ *result = l2cap_conf_output(sk, &ptr);
-+ else
-+ flags |= 0x0001;
-+
-+ rsp->scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ rsp->result = __cpu_to_le16(result ? *result : 0);
-+ rsp->flags = __cpu_to_le16(flags);
-+
-+ return ptr - data;
-+}
-+
-+static inline int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ struct l2cap_chan_list *list = &conn->chan_list;
-+ l2cap_conn_req *req = (l2cap_conn_req *) data;
-+ l2cap_conn_rsp rsp;
-+ struct sock *sk, *parent;
-+ int result = 0, status = 0;
-+
-+ __u16 dcid = 0, scid = __le16_to_cpu(req->scid);
-+ __u16 psm = req->psm;
-+
-+ BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
-+
-+ /* Check if we have socket listening on psm */
-+ parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
-+ if (!parent) {
-+ result = L2CAP_CR_BAD_PSM;
-+ goto sendresp;
-+ }
-+
-+ result = L2CAP_CR_NO_MEM;
-+
-+ /* Check for backlog size */
-+ if (parent->ack_backlog > parent->max_ack_backlog) {
-+ BT_DBG("backlog full %d", parent->ack_backlog);
-+ goto response;
-+ }
-+
-+ sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC);
-+ if (!sk)
-+ goto response;
-+
-+ write_lock(&list->lock);
-+
-+ /* Check if we already have channel with that dcid */
-+ if (__l2cap_get_chan_by_dcid(list, scid)) {
-+ write_unlock(&list->lock);
-+ sk->zapped = 1;
-+ l2cap_sock_kill(sk);
-+ goto response;
-+ }
-+
-+ hci_conn_hold(conn->hcon);
-+
-+ l2cap_sock_init(sk, parent);
-+ bacpy(&bluez_pi(sk)->src, conn->src);
-+ bacpy(&bluez_pi(sk)->dst, conn->dst);
-+ l2cap_pi(sk)->psm = psm;
-+ l2cap_pi(sk)->dcid = scid;
-+
-+ __l2cap_chan_add(conn, sk, parent);
-+ dcid = l2cap_pi(sk)->scid;
-+
-+ l2cap_sock_set_timer(sk, sk->sndtimeo);
-+
-+ /* Service level security */
-+ result = L2CAP_CR_PEND;
-+ status = L2CAP_CS_AUTHEN_PEND;
-+ sk->state = BT_CONNECT2;
-+ l2cap_pi(sk)->ident = cmd->ident;
-+
-+ if (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) {
-+ if (!hci_conn_encrypt(conn->hcon))
-+ goto done;
-+ } else if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH) {
-+ if (!hci_conn_auth(conn->hcon))
-+ goto done;
-+ }
-+
-+ sk->state = BT_CONFIG;
-+ result = status = 0;
-+
-+done:
-+ write_unlock(&list->lock);
-+
-+response:
-+ bh_unlock_sock(parent);
-+
-+sendresp:
-+ rsp.scid = __cpu_to_le16(scid);
-+ rsp.dcid = __cpu_to_le16(dcid);
-+ rsp.result = __cpu_to_le16(result);
-+ rsp.status = __cpu_to_le16(status);
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
-+ return 0;
-+}
-+
-+static inline int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_conn_rsp *rsp = (l2cap_conn_rsp *) data;
-+ __u16 scid, dcid, result, status;
-+ struct sock *sk;
-+ char req[128];
-+
-+ scid = __le16_to_cpu(rsp->scid);
-+ dcid = __le16_to_cpu(rsp->dcid);
-+ result = __le16_to_cpu(rsp->result);
-+ status = __le16_to_cpu(rsp->status);
-+
-+ BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-+ return -ENOENT;
-+
-+ switch (result) {
-+ case L2CAP_CR_SUCCESS:
-+ sk->state = BT_CONFIG;
-+ l2cap_pi(sk)->dcid = dcid;
-+ l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
-+
-+ l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-+ break;
-+
-+ case L2CAP_CR_PEND:
-+ break;
-+
-+ default:
-+ l2cap_chan_del(sk, ECONNREFUSED);
-+ break;
-+ }
-+
-+ bh_unlock_sock(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_conf_req * req = (l2cap_conf_req *) data;
-+ __u16 dcid, flags;
-+ __u8 rsp[64];
-+ struct sock *sk;
-+ int result;
-+
-+ dcid = __le16_to_cpu(req->dcid);
-+ flags = __le16_to_cpu(req->flags);
-+
-+ BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-+ return -ENOENT;
-+
-+ l2cap_parse_conf_req(sk, req->data, cmd->len - L2CAP_CONF_REQ_SIZE);
-+
-+ if (flags & 0x0001) {
-+ /* Incomplete config. Send empty response. */
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
-+ goto unlock;
-+ }
-+
-+ /* Complete config. */
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &result), rsp);
-+
-+ if (result)
-+ goto unlock;
-+
-+ /* Output config done */
-+ l2cap_pi(sk)->conf_state |= L2CAP_CONF_OUTPUT_DONE;
-+
-+ if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
-+ sk->state = BT_CONNECTED;
-+ l2cap_chan_ready(sk);
-+ } else if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
-+ char req[64];
-+ l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-+ }
-+
-+unlock:
-+ bh_unlock_sock(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_conf_rsp *rsp = (l2cap_conf_rsp *)data;
-+ __u16 scid, flags, result;
-+ struct sock *sk;
-+ int err = 0;
-+
-+ scid = __le16_to_cpu(rsp->scid);
-+ flags = __le16_to_cpu(rsp->flags);
-+ result = __le16_to_cpu(rsp->result);
-+
-+ BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-+ return -ENOENT;
-+
-+ switch (result) {
-+ case L2CAP_CONF_SUCCESS:
-+ break;
-+
-+ case L2CAP_CONF_UNACCEPT:
-+ if (++l2cap_pi(sk)->conf_retry < L2CAP_CONF_MAX_RETRIES) {
-+ char req[128];
-+ /*
-+ It does not make sense to adjust L2CAP parameters
-+ that are currently defined in the spec. We simply
-+ resend config request that we sent earlier. It is
-+ stupid :) but it helps qualification testing
-+ which expects at least some response from us.
-+ */
-+ l2cap_send_req(conn, L2CAP_CONF_REQ,
-+ l2cap_build_conf_req(sk, req), req);
-+ goto done;
-+ }
-+ default:
-+ sk->state = BT_DISCONN;
-+ sk->err = ECONNRESET;
-+ l2cap_sock_set_timer(sk, HZ * 5);
-+ {
-+ l2cap_disconn_req req;
-+ req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
-+ }
-+ goto done;
-+ }
-+
-+ if (flags & 0x01)
-+ goto done;
-+
-+ /* Input config done */
-+ l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
-+
-+ if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
-+ sk->state = BT_CONNECTED;
-+ l2cap_chan_ready(sk);
-+ }
-+
-+done:
-+ bh_unlock_sock(sk);
-+ return err;
-+}
-+
-+static inline int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_disconn_req *req = (l2cap_disconn_req *) data;
-+ l2cap_disconn_rsp rsp;
-+ __u16 dcid, scid;
-+ struct sock *sk;
-+
-+ scid = __le16_to_cpu(req->scid);
-+ dcid = __le16_to_cpu(req->dcid);
-+
-+ BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-+ return 0;
-+
-+ rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_DISCONN_RSP, L2CAP_DISCONN_RSP_SIZE, &rsp);
-+
-+ sk->shutdown = SHUTDOWN_MASK;
-+
-+ l2cap_chan_del(sk, ECONNRESET);
-+ bh_unlock_sock(sk);
-+
-+ l2cap_sock_kill(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_disconn_rsp *rsp = (l2cap_disconn_rsp *) data;
-+ __u16 dcid, scid;
-+ struct sock *sk;
-+
-+ scid = __le16_to_cpu(rsp->scid);
-+ dcid = __le16_to_cpu(rsp->dcid);
-+
-+ BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-+ return 0;
-+ l2cap_chan_del(sk, 0);
-+ bh_unlock_sock(sk);
-+
-+ l2cap_sock_kill(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_information_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, u8 *data)
-+{
-+ l2cap_info_req *req = (l2cap_info_req *) data;
-+ l2cap_info_rsp rsp;
-+ u16 type;
-+
-+ type = __le16_to_cpu(req->type);
-+
-+ BT_DBG("type 0x%4.4x", type);
-+
-+ rsp.type = __cpu_to_le16(type);
-+ rsp.result = __cpu_to_le16(L2CAP_IR_NOTSUPP);
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp), &rsp);
-+ return 0;
-+}
-+
-+static inline int l2cap_information_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, u8 *data)
-+{
-+ l2cap_info_rsp *rsp = (l2cap_info_rsp *) data;
-+ u16 type, result;
-+
-+ type = __le16_to_cpu(rsp->type);
-+ result = __le16_to_cpu(rsp->result);
-+
-+ BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
-+
-+ return 0;
-+}
-+
-+static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
-+{
-+ __u8 *data = skb->data;
-+ int len = skb->len;
-+ l2cap_cmd_hdr cmd;
-+ int err = 0;
-+
-+ l2cap_raw_recv(conn, skb);
-+
-+ while (len >= L2CAP_CMD_HDR_SIZE) {
-+ memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
-+ data += L2CAP_CMD_HDR_SIZE;
-+ len -= L2CAP_CMD_HDR_SIZE;
-+
-+ cmd.len = __le16_to_cpu(cmd.len);
-+
-+ BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
-+
-+ if (cmd.len > len || !cmd.ident) {
-+ BT_DBG("corrupted command");
-+ break;
-+ }
-+
-+ switch (cmd.code) {
-+ case L2CAP_COMMAND_REJ:
-+ /* FIXME: We should process this */
-+ break;
-+
-+ case L2CAP_CONN_REQ:
-+ err = l2cap_connect_req(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_CONN_RSP:
-+ err = l2cap_connect_rsp(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_CONF_REQ:
-+ err = l2cap_config_req(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_CONF_RSP:
-+ err = l2cap_config_rsp(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_DISCONN_REQ:
-+ err = l2cap_disconnect_req(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_DISCONN_RSP:
-+ err = l2cap_disconnect_rsp(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_ECHO_REQ:
-+ l2cap_send_rsp(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data);
-+ break;
-+
-+ case L2CAP_ECHO_RSP:
-+ break;
-+
-+ case L2CAP_INFO_REQ:
-+ err = l2cap_information_req(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_INFO_RSP:
-+ err = l2cap_information_rsp(conn, &cmd, data);
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
-+ err = -EINVAL;
-+ break;
-+ };
-+
-+ if (err) {
-+ l2cap_cmd_rej rej;
-+ BT_DBG("error %d", err);
-+
-+ /* FIXME: Map err to a valid reason */
-+ rej.reason = __cpu_to_le16(0);
-+ l2cap_send_rsp(conn, cmd.ident, L2CAP_COMMAND_REJ, L2CAP_CMD_REJ_SIZE, &rej);
-+ }
-+
-+ data += cmd.len;
-+ len -= cmd.len;
-+ }
-+
-+ kfree_skb(skb);
-+}
-+
-+static inline int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
-+{
-+ struct sock *sk;
-+
-+ sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
-+ if (!sk) {
-+ BT_DBG("unknown cid 0x%4.4x", cid);
-+ goto drop;
-+ }
-+
-+ BT_DBG("sk %p, len %d", sk, skb->len);
-+
-+ if (sk->state != BT_CONNECTED)
-+ goto drop;
-+
-+ if (l2cap_pi(sk)->imtu < skb->len)
-+ goto drop;
-+
-+ /* If socket recv buffers overflows we drop data here
-+ * which is *bad* because L2CAP has to be reliable.
-+ * But we don't have any other choice. L2CAP doesn't
-+ * provide flow control mechanism */
-+
-+ if (!sock_queue_rcv_skb(sk, skb))
-+ goto done;
-+
-+drop:
-+ kfree_skb(skb);
-+
-+done:
-+ if (sk) bh_unlock_sock(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_conless_channel(struct l2cap_conn *conn, __u16 psm, struct sk_buff *skb)
-+{
-+ struct sock *sk;
-+
-+ sk = l2cap_get_sock_by_psm(0, psm, conn->src);
-+ if (!sk)
-+ goto drop;
-+
-+ BT_DBG("sk %p, len %d", sk, skb->len);
-+
-+ if (sk->state != BT_BOUND && sk->state != BT_CONNECTED)
-+ goto drop;
-+
-+ if (l2cap_pi(sk)->imtu < skb->len)
-+ goto drop;
-+
-+ if (!sock_queue_rcv_skb(sk, skb))
-+ goto done;
-+
-+drop:
-+ kfree_skb(skb);
-+
-+done:
-+ if (sk) bh_unlock_sock(sk);
-+ return 0;
-+}
-+
-+static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
-+{
-+ l2cap_hdr *lh = (l2cap_hdr *) skb->data;
-+ __u16 cid, psm, len;
-+
-+ skb_pull(skb, L2CAP_HDR_SIZE);
-+ cid = __le16_to_cpu(lh->cid);
-+ len = __le16_to_cpu(lh->len);
-+
-+ BT_DBG("len %d, cid 0x%4.4x", len, cid);
-+
-+ switch (cid) {
-+ case 0x0001:
-+ l2cap_sig_channel(conn, skb);
-+ break;
-+
-+ case 0x0002:
-+ psm = get_unaligned((__u16 *) skb->data);
-+ skb_pull(skb, 2);
-+ l2cap_conless_channel(conn, psm, skb);
-+ break;
-+
-+ default:
-+ l2cap_data_channel(conn, cid, skb);
-+ break;
-+ }
-+}
-+
-+/* ------------ L2CAP interface with lower layer (HCI) ------------- */
-+
-+static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
-+{
-+ int exact = 0, lm1 = 0, lm2 = 0;
-+ register struct sock *sk;
-+
-+ if (type != ACL_LINK)
-+ return 0;
-+
-+ BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
-+
-+ /* Find listening sockets and check their link_mode */
-+ read_lock(&l2cap_sk_list.lock);
-+ for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-+ if (sk->state != BT_LISTEN)
-+ continue;
-+
-+ if (!bacmp(&bluez_pi(sk)->src, &hdev->bdaddr)) {
-+ lm1 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode);
-+ exact++;
-+ } else if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
-+ lm2 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode);
-+ }
-+ read_unlock(&l2cap_sk_list.lock);
-+
-+ return exact ? lm1 : lm2;
-+}
-+
-+static int l2cap_connect_cfm(struct hci_conn *hcon, __u8 status)
-+{
-+ BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
-+
-+ if (hcon->type != ACL_LINK)
-+ return 0;
-+
-+ if (!status) {
-+ struct l2cap_conn *conn;
-+
-+ conn = l2cap_conn_add(hcon, status);
-+ if (conn)
-+ l2cap_conn_ready(conn);
-+ } else
-+ l2cap_conn_del(hcon, bterr(status));
-+
-+ return 0;
-+}
-+
-+static int l2cap_disconn_ind(struct hci_conn *hcon, __u8 reason)
-+{
-+ BT_DBG("hcon %p reason %d", hcon, reason);
-+
-+ if (hcon->type != ACL_LINK)
-+ return 0;
-+
-+ l2cap_conn_del(hcon, bterr(reason));
-+ return 0;
-+}
-+
-+static int l2cap_auth_cfm(struct hci_conn *hcon, __u8 status)
-+{
-+ struct l2cap_chan_list *l;
-+ struct l2cap_conn *conn;
-+ l2cap_conn_rsp rsp;
-+ struct sock *sk;
-+ int result;
-+
-+ if (!(conn = hcon->l2cap_data))
-+ return 0;
-+ l = &conn->chan_list;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ bh_lock_sock(sk);
-+
-+ if (sk->state != BT_CONNECT2 ||
-+ (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT)) {
-+ bh_unlock_sock(sk);
-+ continue;
-+ }
-+
-+ if (!status) {
-+ sk->state = BT_CONFIG;
-+ result = 0;
-+ } else {
-+ sk->state = BT_DISCONN;
-+ l2cap_sock_set_timer(sk, HZ/10);
-+ result = L2CAP_CR_SEC_BLOCK;
-+ }
-+
-+ rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ rsp.result = __cpu_to_le16(result);
-+ rsp.status = __cpu_to_le16(0);
-+ l2cap_send_rsp(conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP,
-+ L2CAP_CONN_RSP_SIZE, &rsp);
-+
-+ bh_unlock_sock(sk);
-+ }
-+
-+ read_unlock(&l->lock);
-+ return 0;
-+}
-+
-+static int l2cap_encrypt_cfm(struct hci_conn *hcon, __u8 status)
-+{
-+ struct l2cap_chan_list *l;
-+ struct l2cap_conn *conn;
-+ l2cap_conn_rsp rsp;
-+ struct sock *sk;
-+ int result;
-+
-+ if (!(conn = hcon->l2cap_data))
-+ return 0;
-+ l = &conn->chan_list;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ bh_lock_sock(sk);
-+
-+ if (sk->state != BT_CONNECT2) {
-+ bh_unlock_sock(sk);
-+ continue;
-+ }
-+
-+ if (!status) {
-+ sk->state = BT_CONFIG;
-+ result = 0;
-+ } else {
-+ sk->state = BT_DISCONN;
-+ l2cap_sock_set_timer(sk, HZ/10);
-+ result = L2CAP_CR_SEC_BLOCK;
-+ }
-+
-+ rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ rsp.result = __cpu_to_le16(result);
-+ rsp.status = __cpu_to_le16(0);
-+ l2cap_send_rsp(conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP,
-+ L2CAP_CONN_RSP_SIZE, &rsp);
-+
-+ bh_unlock_sock(sk);
-+ }
-+
-+ read_unlock(&l->lock);
-+ return 0;
-+}
-+
-+static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, __u16 flags)
-+{
-+ struct l2cap_conn *conn = hcon->l2cap_data;
-+
-+ if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
-+ goto drop;
-+
-+ BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
-+
-+ if (flags & ACL_START) {
-+ l2cap_hdr *hdr;
-+ int len;
-+
-+ if (conn->rx_len) {
-+ BT_ERR("Unexpected start frame (len %d)", skb->len);
-+ kfree_skb(conn->rx_skb);
-+ conn->rx_skb = NULL;
-+ conn->rx_len = 0;
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ }
-+
-+ if (skb->len < 2) {
-+ BT_ERR("Frame is too short (len %d)", skb->len);
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ goto drop;
-+ }
-+
-+ hdr = (l2cap_hdr *) skb->data;
-+ len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
-+
-+ if (len == skb->len) {
-+ /* Complete frame received */
-+ l2cap_recv_frame(conn, skb);
-+ return 0;
-+ }
-+
-+ BT_DBG("Start: total len %d, frag len %d", len, skb->len);
-+
-+ if (skb->len > len) {
-+ BT_ERR("Frame is too long (len %d, expected len %d)",
-+ skb->len, len);
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ goto drop;
-+ }
-+
-+ /* Allocate skb for the complete frame including header */
-+ conn->rx_skb = bluez_skb_alloc(len, GFP_ATOMIC);
-+ if (!conn->rx_skb)
-+ goto drop;
-+
-+ memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
-+ conn->rx_len = len - skb->len;
-+ } else {
-+ BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
-+
-+ if (!conn->rx_len) {
-+ BT_ERR("Unexpected continuation frame (len %d)", skb->len);
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ goto drop;
-+ }
-+
-+ if (skb->len > conn->rx_len) {
-+ BT_ERR("Fragment is too long (len %d, expected %d)",
-+ skb->len, conn->rx_len);
-+ kfree_skb(conn->rx_skb);
-+ conn->rx_skb = NULL;
-+ conn->rx_len = 0;
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ goto drop;
-+ }
-+
-+ memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
-+ conn->rx_len -= skb->len;
-+
-+ if (!conn->rx_len) {
-+ /* Complete frame received */
-+ l2cap_recv_frame(conn, conn->rx_skb);
-+ conn->rx_skb = NULL;
-+ }
-+ }
-+
-+drop:
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+/* ----- Proc fs support ------ */
-+static int l2cap_sock_dump(char *buf, struct bluez_sock_list *list)
-+{
-+ struct l2cap_pinfo *pi;
-+ struct sock *sk;
-+ char *ptr = buf;
-+
-+ read_lock_bh(&list->lock);
-+
-+ for (sk = list->head; sk; sk = sk->next) {
-+ pi = l2cap_pi(sk);
-+ ptr += sprintf(ptr, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n",
-+ batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
-+ sk->state, pi->psm, pi->scid, pi->dcid, pi->imtu, pi->omtu,
-+ pi->link_mode);
-+ }
-+
-+ read_unlock_bh(&list->lock);
-+
-+ ptr += sprintf(ptr, "\n");
-+ return ptr - buf;
-+}
-+
-+static int l2cap_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
-+{
-+ char *ptr = buf;
-+ int len;
-+
-+ BT_DBG("count %d, offset %ld", count, offset);
-+
-+ ptr += l2cap_sock_dump(ptr, &l2cap_sk_list);
-+ len = ptr - buf;
-+
-+ if (len <= count + offset)
-+ *eof = 1;
-+
-+ *start = buf + offset;
-+ len -= offset;
-+
-+ if (len > count)
-+ len = count;
-+ if (len < 0)
-+ len = 0;
-+
-+ return len;
-+}
-+
-+static struct proto_ops l2cap_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: l2cap_sock_release,
-+ bind: l2cap_sock_bind,
-+ connect: l2cap_sock_connect,
-+ listen: l2cap_sock_listen,
-+ accept: l2cap_sock_accept,
-+ getname: l2cap_sock_getname,
-+ sendmsg: l2cap_sock_sendmsg,
-+ recvmsg: bluez_sock_recvmsg,
-+ poll: bluez_sock_poll,
-+ socketpair: sock_no_socketpair,
-+ ioctl: sock_no_ioctl,
-+ shutdown: l2cap_sock_shutdown,
-+ setsockopt: l2cap_sock_setsockopt,
-+ getsockopt: l2cap_sock_getsockopt,
-+ mmap: sock_no_mmap
-+};
-+
-+static struct net_proto_family l2cap_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: l2cap_sock_create
-+};
-+
-+static struct hci_proto l2cap_hci_proto = {
-+ name: "L2CAP",
-+ id: HCI_PROTO_L2CAP,
-+ connect_ind: l2cap_connect_ind,
-+ connect_cfm: l2cap_connect_cfm,
-+ disconn_ind: l2cap_disconn_ind,
-+ recv_acldata: l2cap_recv_acldata,
-+ auth_cfm: l2cap_auth_cfm,
-+ encrypt_cfm: l2cap_encrypt_cfm
-+};
-+
-+int __init l2cap_init(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops))) {
-+ BT_ERR("Can't register L2CAP socket");
-+ return err;
-+ }
-+
-+ if ((err = hci_register_proto(&l2cap_hci_proto))) {
-+ BT_ERR("Can't register L2CAP protocol");
-+ return err;
-+ }
-+
-+ create_proc_read_entry("bluetooth/l2cap", 0, 0, l2cap_read_proc, NULL);
-+
-+ BT_INFO("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ return 0;
-+}
-+
-+void l2cap_cleanup(void)
-+{
-+ remove_proc_entry("bluetooth/l2cap", NULL);
-+
-+ /* Unregister socket and protocol */
-+ if (bluez_sock_unregister(BTPROTO_L2CAP))
-+ BT_ERR("Can't unregister L2CAP socket");
-+
-+ if (hci_unregister_proto(&l2cap_hci_proto))
-+ BT_ERR("Can't unregister L2CAP protocol");
-+}
-+
-+void l2cap_load(void)
-+{
-+ /* Dummy function to trigger automatic L2CAP module loading by
-+ other modules that use L2CAP sockets but do not use any other
-+ symbols from it. */
-+ return;
-+}
-+
-+EXPORT_SYMBOL(l2cap_load);
-+
-+module_init(l2cap_init);
-+module_exit(l2cap_cleanup);
-+
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
-+MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/l2cap_core.c linux-2.4.18-mh15/net/bluetooth/l2cap_core.c
---- linux-2.4.18/net/bluetooth/l2cap_core.c 2001-09-30 21:26:08.000000000 +0200
-+++ linux-2.4.18-mh15/net/bluetooth/l2cap_core.c 1970-01-01 01:00:00.000000000 +0100
-@@ -1,2316 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * BlueZ L2CAP core and sockets.
-- *
-- * $Id$
-- */
--#define VERSION "1.1"
--
--#include <linux/config.h>
--#include <linux/module.h>
--
--#include <linux/types.h>
--#include <linux/errno.h>
--#include <linux/kernel.h>
--#include <linux/major.h>
--#include <linux/sched.h>
--#include <linux/slab.h>
--#include <linux/poll.h>
--#include <linux/fcntl.h>
--#include <linux/init.h>
--#include <linux/skbuff.h>
--#include <linux/interrupt.h>
--#include <linux/socket.h>
--#include <linux/skbuff.h>
--#include <linux/proc_fs.h>
--#include <linux/list.h>
--#include <net/sock.h>
--
--#include <asm/system.h>
--#include <asm/uaccess.h>
--
--#include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
--#include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/l2cap.h>
--#include <net/bluetooth/l2cap_core.h>
--
--#ifndef L2CAP_DEBUG
--#undef DBG
--#define DBG( A... )
--#endif
--
--struct proto_ops l2cap_sock_ops;
--
--struct bluez_sock_list l2cap_sk_list = {
-- lock: RW_LOCK_UNLOCKED
--};
--
--struct list_head l2cap_iff_list = LIST_HEAD_INIT(l2cap_iff_list);
--rwlock_t l2cap_rt_lock = RW_LOCK_UNLOCKED;
--
--static int l2cap_conn_del(struct l2cap_conn *conn, int err);
--
--static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
--static void l2cap_chan_del(struct sock *sk, int err);
--static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len);
--
--static void l2cap_sock_close(struct sock *sk);
--static void l2cap_sock_kill(struct sock *sk);
--
--static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data);
--static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data);
--
--/* -------- L2CAP interfaces & routing --------- */
--/* Add/delete L2CAP interface.
-- * Must be called with locked rt_lock
-- */
--
--static void l2cap_iff_add(struct hci_dev *hdev)
--{
-- struct l2cap_iff *iff;
--
-- DBG("%s", hdev->name);
--
-- DBG("iff_list %p next %p prev %p", &l2cap_iff_list, l2cap_iff_list.next, l2cap_iff_list.prev);
--
-- /* Allocate new interface and lock HCI device */
-- if (!(iff = kmalloc(sizeof(struct l2cap_iff), GFP_KERNEL))) {
-- ERR("Can't allocate new interface %s", hdev->name);
-- return;
-- }
-- memset(iff, 0, sizeof(struct l2cap_iff));
--
-- hci_dev_hold(hdev);
-- hdev->l2cap_data = iff;
-- iff->hdev = hdev;
-- iff->mtu = hdev->acl_mtu - HCI_ACL_HDR_SIZE;
-- iff->bdaddr = &hdev->bdaddr;
--
-- spin_lock_init(&iff->lock);
-- INIT_LIST_HEAD(&iff->conn_list);
--
-- list_add(&iff->list, &l2cap_iff_list);
--}
--
--static void l2cap_iff_del(struct hci_dev *hdev)
--{
-- struct l2cap_iff *iff;
--
-- if (!(iff = hdev->l2cap_data))
-- return;
--
-- DBG("%s iff %p", hdev->name, iff);
--
-- list_del(&iff->list);
--
-- l2cap_iff_lock(iff);
--
-- /* Drop connections */
-- while (!list_empty(&iff->conn_list)) {
-- struct l2cap_conn *c;
--
-- c = list_entry(iff->conn_list.next, struct l2cap_conn, list);
-- l2cap_conn_del(c, ENODEV);
-- }
--
-- l2cap_iff_unlock(iff);
--
-- /* Unlock HCI device */
-- hdev->l2cap_data = NULL;
-- hci_dev_put(hdev);
--
-- kfree(iff);
--}
--
--/* Get route. Returns L2CAP interface.
-- * Must be called with locked rt_lock
-- */
--static struct l2cap_iff *l2cap_get_route(bdaddr_t *src, bdaddr_t *dst)
--{
-- struct list_head *p;
-- int use_src;
--
-- DBG("%s -> %s", batostr(src), batostr(dst));
--
-- use_src = bacmp(src, BDADDR_ANY) ? 0 : 1;
--
-- /* Simple routing:
-- * No source address - find interface with bdaddr != dst
-- * Source address - find interface with bdaddr == src
-- */
--
-- list_for_each(p, &l2cap_iff_list) {
-- struct l2cap_iff *iff;
--
-- iff = list_entry(p, struct l2cap_iff, list);
--
-- if (use_src && !bacmp(iff->bdaddr, src))
-- return iff;
-- else if (bacmp(iff->bdaddr, dst))
-- return iff;
-- }
-- return NULL;
--}
--
--/* ----- L2CAP timers ------ */
--static void l2cap_sock_timeout(unsigned long arg)
--{
-- struct sock *sk = (struct sock *) arg;
--
-- DBG("sock %p state %d", sk, sk->state);
--
-- bh_lock_sock(sk);
-- switch (sk->state) {
-- case BT_DISCONN:
-- l2cap_chan_del(sk, ETIMEDOUT);
-- break;
--
-- default:
-- sk->err = ETIMEDOUT;
-- sk->state_change(sk);
-- break;
-- };
-- bh_unlock_sock(sk);
--
-- l2cap_sock_kill(sk);
-- sock_put(sk);
--}
--
--static void l2cap_sock_set_timer(struct sock *sk, long timeout)
--{
-- DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
--
-- if (!mod_timer(&sk->timer, jiffies + timeout))
-- sock_hold(sk);
--}
--
--static void l2cap_sock_clear_timer(struct sock *sk)
--{
-- DBG("sock %p state %d", sk, sk->state);
--
-- if (timer_pending(&sk->timer) && del_timer(&sk->timer))
-- __sock_put(sk);
--}
--
--static void l2cap_sock_init_timer(struct sock *sk)
--{
-- init_timer(&sk->timer);
-- sk->timer.function = l2cap_sock_timeout;
-- sk->timer.data = (unsigned long)sk;
--}
--
--static void l2cap_conn_timeout(unsigned long arg)
--{
-- struct l2cap_conn *conn = (void *)arg;
--
-- DBG("conn %p state %d", conn, conn->state);
--
-- if (conn->state == BT_CONNECTED) {
-- hci_disconnect(conn->hconn, 0x13);
-- }
--
-- return;
--}
--
--static void l2cap_conn_set_timer(struct l2cap_conn *conn, long timeout)
--{
-- DBG("conn %p state %d timeout %ld", conn, conn->state, timeout);
--
-- mod_timer(&conn->timer, jiffies + timeout);
--}
--
--static void l2cap_conn_clear_timer(struct l2cap_conn *conn)
--{
-- DBG("conn %p state %d", conn, conn->state);
--
-- del_timer(&conn->timer);
--}
--
--static void l2cap_conn_init_timer(struct l2cap_conn *conn)
--{
-- init_timer(&conn->timer);
-- conn->timer.function = l2cap_conn_timeout;
-- conn->timer.data = (unsigned long)conn;
--}
--
--/* -------- L2CAP connections --------- */
--/* Add new connection to the interface.
-- * Interface must be locked
-- */
--static struct l2cap_conn *l2cap_conn_add(struct l2cap_iff *iff, bdaddr_t *dst)
--{
-- struct l2cap_conn *conn;
-- bdaddr_t *src = iff->bdaddr;
--
-- if (!(conn = kmalloc(sizeof(struct l2cap_conn), GFP_KERNEL)))
-- return NULL;
--
-- memset(conn, 0, sizeof(struct l2cap_conn));
--
-- conn->state = BT_OPEN;
-- conn->iff = iff;
-- bacpy(&conn->src, src);
-- bacpy(&conn->dst, dst);
--
-- spin_lock_init(&conn->lock);
-- conn->chan_list.lock = RW_LOCK_UNLOCKED;
--
-- l2cap_conn_init_timer(conn);
--
-- __l2cap_conn_link(iff, conn);
--
-- DBG("%s -> %s, %p", batostr(src), batostr(dst), conn);
--
-- MOD_INC_USE_COUNT;
--
-- return conn;
--}
--
--/* Delete connection on the interface.
-- * Interface must be locked
-- */
--static int l2cap_conn_del(struct l2cap_conn *conn, int err)
--{
-- struct sock *sk;
--
-- DBG("conn %p, state %d, err %d", conn, conn->state, err);
--
-- l2cap_conn_clear_timer(conn);
-- __l2cap_conn_unlink(conn->iff, conn);
--
-- conn->state = BT_CLOSED;
--
-- if (conn->rx_skb)
-- kfree_skb(conn->rx_skb);
--
-- /* Kill channels */
-- while ((sk = conn->chan_list.head)) {
-- bh_lock_sock(sk);
-- l2cap_sock_clear_timer(sk);
-- l2cap_chan_del(sk, err);
-- bh_unlock_sock(sk);
--
-- l2cap_sock_kill(sk);
-- }
--
-- kfree(conn);
--
-- MOD_DEC_USE_COUNT;
-- return 0;
--}
--
--static inline struct l2cap_conn *l2cap_get_conn_by_addr(struct l2cap_iff *iff, bdaddr_t *dst)
--{
-- struct list_head *p;
--
-- list_for_each(p, &iff->conn_list) {
-- struct l2cap_conn *c;
--
-- c = list_entry(p, struct l2cap_conn, list);
-- if (!bacmp(&c->dst, dst))
-- return c;
-- }
-- return NULL;
--}
--
--int l2cap_connect(struct sock *sk)
--{
-- bdaddr_t *src = &l2cap_pi(sk)->src;
-- bdaddr_t *dst = &l2cap_pi(sk)->dst;
-- struct l2cap_conn *conn;
-- struct l2cap_iff *iff;
-- int err = 0;
--
-- DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
--
-- read_lock_bh(&l2cap_rt_lock);
--
-- /* Get route to remote BD address */
-- if (!(iff = l2cap_get_route(src, dst))) {
-- err = -EHOSTUNREACH;
-- goto done;
-- }
--
-- /* Update source addr of the socket */
-- bacpy(src, iff->bdaddr);
--
-- l2cap_iff_lock(iff);
--
-- if (!(conn = l2cap_get_conn_by_addr(iff, dst))) {
-- /* Connection doesn't exist */
-- if (!(conn = l2cap_conn_add(iff, dst))) {
-- l2cap_iff_unlock(iff);
-- err = -ENOMEM;
-- goto done;
-- }
-- conn->out = 1;
-- }
--
-- l2cap_iff_unlock(iff);
--
-- l2cap_chan_add(conn, sk, NULL);
--
-- sk->state = BT_CONNECT;
-- l2cap_sock_set_timer(sk, sk->sndtimeo);
--
-- switch (conn->state) {
-- case BT_CONNECTED:
-- if (sk->type == SOCK_SEQPACKET) {
-- l2cap_conn_req req;
-- req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- req.psm = l2cap_pi(sk)->psm;
-- l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
-- } else {
-- l2cap_sock_clear_timer(sk);
-- sk->state = BT_CONNECTED;
-- }
-- break;
--
-- case BT_CONNECT:
-- break;
--
-- default:
-- /* Create ACL connection */
-- conn->state = BT_CONNECT;
-- hci_connect(iff->hdev, dst);
-- break;
-- };
--
--done:
-- read_unlock_bh(&l2cap_rt_lock);
-- return err;
--}
--
--/* ------ Channel queues for listening sockets ------ */
--void l2cap_accept_queue(struct sock *parent, struct sock *sk)
--{
-- struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
--
-- DBG("parent %p, sk %p", parent, sk);
--
-- sock_hold(sk);
-- l2cap_pi(sk)->parent = parent;
-- l2cap_pi(sk)->next_q = NULL;
--
-- if (!q->head) {
-- q->head = q->tail = sk;
-- } else {
-- struct sock *tail = q->tail;
--
-- l2cap_pi(sk)->prev_q = tail;
-- l2cap_pi(tail)->next_q = sk;
-- q->tail = sk;
-- }
--
-- parent->ack_backlog++;
--}
--
--void l2cap_accept_unlink(struct sock *sk)
--{
-- struct sock *parent = l2cap_pi(sk)->parent;
-- struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
-- struct sock *next, *prev;
--
-- DBG("sk %p", sk);
--
-- next = l2cap_pi(sk)->next_q;
-- prev = l2cap_pi(sk)->prev_q;
--
-- if (sk == q->head)
-- q->head = next;
-- if (sk == q->tail)
-- q->tail = prev;
--
-- if (next)
-- l2cap_pi(next)->prev_q = prev;
-- if (prev)
-- l2cap_pi(prev)->next_q = next;
--
-- l2cap_pi(sk)->parent = NULL;
--
-- parent->ack_backlog--;
-- __sock_put(sk);
--}
--
--/* Get next connected channel in queue. */
--struct sock *l2cap_accept_dequeue(struct sock *parent, int state)
--{
-- struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
-- struct sock *sk;
--
-- for (sk = q->head; sk; sk = l2cap_pi(sk)->next_q) {
-- if (!state || sk->state == state) {
-- l2cap_accept_unlink(sk);
-- break;
-- }
-- }
--
-- DBG("parent %p, sk %p", parent, sk);
--
-- return sk;
--}
--
--/* -------- Socket interface ---------- */
--static struct sock *__l2cap_get_sock_by_addr(struct sockaddr_l2 *addr)
--{
-- bdaddr_t *src = &addr->l2_bdaddr;
-- __u16 psm = addr->l2_psm;
-- struct sock *sk;
--
-- for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-- if (l2cap_pi(sk)->psm == psm &&
-- !bacmp(&l2cap_pi(sk)->src, src))
-- break;
-- }
--
-- return sk;
--}
--
--/* Find socket listening on psm and source bdaddr.
-- * Returns closest match.
-- */
--static struct sock *l2cap_get_sock_listen(bdaddr_t *src, __u16 psm)
--{
-- struct sock *sk, *sk1 = NULL;
--
-- read_lock(&l2cap_sk_list.lock);
--
-- for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-- struct l2cap_pinfo *pi;
--
-- if (sk->state != BT_LISTEN)
-- continue;
--
-- pi = l2cap_pi(sk);
--
-- if (pi->psm == psm) {
-- /* Exact match. */
-- if (!bacmp(&pi->src, src))
-- break;
--
-- /* Closest match */
-- if (!bacmp(&pi->src, BDADDR_ANY))
-- sk1 = sk;
-- }
-- }
--
-- read_unlock(&l2cap_sk_list.lock);
--
-- return sk ? sk : sk1;
--}
--
--static void l2cap_sock_destruct(struct sock *sk)
--{
-- DBG("sk %p", sk);
--
-- skb_queue_purge(&sk->receive_queue);
-- skb_queue_purge(&sk->write_queue);
--
-- MOD_DEC_USE_COUNT;
--}
--
--static void l2cap_sock_cleanup_listen(struct sock *parent)
--{
-- struct sock *sk;
--
-- DBG("parent %p", parent);
--
-- /* Close not yet accepted channels */
-- while ((sk = l2cap_accept_dequeue(parent, 0)))
-- l2cap_sock_close(sk);
--
-- parent->state = BT_CLOSED;
-- parent->zapped = 1;
--}
--
--/* Kill socket (only if zapped and orphan)
-- * Must be called on unlocked socket.
-- */
--static void l2cap_sock_kill(struct sock *sk)
--{
-- if (!sk->zapped || sk->socket)
-- return;
--
-- DBG("sk %p state %d", sk, sk->state);
--
-- /* Kill poor orphan */
-- bluez_sock_unlink(&l2cap_sk_list, sk);
-- sk->dead = 1;
-- sock_put(sk);
--}
--
--/* Close socket.
-- * Must be called on unlocked socket.
-- */
--static void l2cap_sock_close(struct sock *sk)
--{
-- struct l2cap_conn *conn;
--
-- l2cap_sock_clear_timer(sk);
--
-- lock_sock(sk);
--
-- conn = l2cap_pi(sk)->conn;
--
-- DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
--
-- switch (sk->state) {
-- case BT_LISTEN:
-- l2cap_sock_cleanup_listen(sk);
-- break;
--
-- case BT_CONNECTED:
-- case BT_CONFIG:
-- if (sk->type == SOCK_SEQPACKET) {
-- l2cap_disconn_req req;
--
-- sk->state = BT_DISCONN;
--
-- req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
--
-- l2cap_sock_set_timer(sk, sk->sndtimeo);
-- } else {
-- l2cap_chan_del(sk, ECONNRESET);
-- }
-- break;
--
-- case BT_CONNECT:
-- case BT_DISCONN:
-- l2cap_chan_del(sk, ECONNRESET);
-- break;
--
-- default:
-- sk->zapped = 1;
-- break;
-- };
--
-- release_sock(sk);
--
-- l2cap_sock_kill(sk);
--}
--
--static void l2cap_sock_init(struct sock *sk, struct sock *parent)
--{
-- struct l2cap_pinfo *pi = l2cap_pi(sk);
--
-- DBG("sk %p", sk);
--
-- if (parent) {
-- sk->type = parent->type;
--
-- pi->imtu = l2cap_pi(parent)->imtu;
-- pi->omtu = l2cap_pi(parent)->omtu;
-- } else {
-- pi->imtu = L2CAP_DEFAULT_MTU;
-- pi->omtu = 0;
-- }
--
-- /* Default config options */
-- pi->conf_mtu = L2CAP_DEFAULT_MTU;
-- pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
--}
--
--static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
--{
-- struct sock *sk;
--
-- if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
-- return NULL;
--
-- sock_init_data(sock, sk);
--
-- sk->zapped = 0;
--
-- sk->destruct = l2cap_sock_destruct;
-- sk->sndtimeo = L2CAP_CONN_TIMEOUT;
--
-- sk->protocol = proto;
-- sk->state = BT_OPEN;
--
-- l2cap_sock_init_timer(sk);
--
-- bluez_sock_link(&l2cap_sk_list, sk);
--
-- MOD_INC_USE_COUNT;
--
-- return sk;
--}
--
--static int l2cap_sock_create(struct socket *sock, int protocol)
--{
-- struct sock *sk;
--
-- DBG("sock %p", sock);
--
-- sock->state = SS_UNCONNECTED;
--
-- if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_RAW)
-- return -ESOCKTNOSUPPORT;
--
-- sock->ops = &l2cap_sock_ops;
--
-- if (!(sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL)))
-- return -ENOMEM;
--
-- l2cap_sock_init(sk, NULL);
--
-- return 0;
--}
--
--static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
--{
-- struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-- struct sock *sk = sock->sk;
-- int err = 0;
--
-- DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
--
-- if (!addr || addr->sa_family != AF_BLUETOOTH)
-- return -EINVAL;
--
-- lock_sock(sk);
--
-- if (sk->state != BT_OPEN) {
-- err = -EBADFD;
-- goto done;
-- }
--
-- write_lock(&l2cap_sk_list.lock);
--
-- if (la->l2_psm && __l2cap_get_sock_by_addr(la)) {
-- err = -EADDRINUSE;
-- goto unlock;
-- }
--
-- /* Save source address */
-- bacpy(&l2cap_pi(sk)->src, &la->l2_bdaddr);
-- l2cap_pi(sk)->psm = la->l2_psm;
-- sk->state = BT_BOUND;
--
--unlock:
-- write_unlock(&l2cap_sk_list.lock);
--
--done:
-- release_sock(sk);
--
-- return err;
--}
--
--static int l2cap_sock_w4_connect(struct sock *sk, int flags)
--{
-- DECLARE_WAITQUEUE(wait, current);
-- long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
-- int err = 0;
--
-- DBG("sk %p", sk);
--
-- add_wait_queue(sk->sleep, &wait);
-- current->state = TASK_INTERRUPTIBLE;
--
-- while (sk->state != BT_CONNECTED) {
-- if (!timeo) {
-- err = -EAGAIN;
-- break;
-- }
--
-- release_sock(sk);
-- timeo = schedule_timeout(timeo);
-- lock_sock(sk);
--
-- err = 0;
-- if (sk->state == BT_CONNECTED)
-- break;
--
-- if (sk->err) {
-- err = sock_error(sk);
-- break;
-- }
--
-- if (signal_pending(current)) {
-- err = sock_intr_errno(timeo);
-- break;
-- }
-- }
-- current->state = TASK_RUNNING;
-- remove_wait_queue(sk->sleep, &wait);
--
-- return err;
--}
--
--static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
--{
-- struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-- struct sock *sk = sock->sk;
-- int err = 0;
--
-- lock_sock(sk);
--
-- DBG("sk %p", sk);
--
-- if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) {
-- err = -EINVAL;
-- goto done;
-- }
--
-- if (sk->state != BT_OPEN && sk->state != BT_BOUND) {
-- err = -EBADFD;
-- goto done;
-- }
--
-- if (sk->type == SOCK_SEQPACKET && !la->l2_psm) {
-- err = -EINVAL;
-- goto done;
-- }
--
-- /* Set destination address and psm */
-- bacpy(&l2cap_pi(sk)->dst, &la->l2_bdaddr);
-- l2cap_pi(sk)->psm = la->l2_psm;
--
-- if ((err = l2cap_connect(sk)))
-- goto done;
--
-- err = l2cap_sock_w4_connect(sk, flags);
--
--done:
-- release_sock(sk);
-- return err;
--}
--
--int l2cap_sock_listen(struct socket *sock, int backlog)
--{
-- struct sock *sk = sock->sk;
-- int err = 0;
--
-- DBG("sk %p backlog %d", sk, backlog);
--
-- lock_sock(sk);
--
-- if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
-- err = -EBADFD;
-- goto done;
-- }
--
-- if (!l2cap_pi(sk)->psm) {
-- err = -EINVAL;
-- goto done;
-- }
--
-- sk->max_ack_backlog = backlog;
-- sk->ack_backlog = 0;
-- sk->state = BT_LISTEN;
--
--done:
-- release_sock(sk);
-- return err;
--}
--
--int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
--{
-- DECLARE_WAITQUEUE(wait, current);
-- struct sock *sk = sock->sk, *ch;
-- long timeo;
-- int err = 0;
--
-- lock_sock(sk);
--
-- if (sk->state != BT_LISTEN) {
-- err = -EBADFD;
-- goto done;
-- }
--
-- timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
--
-- DBG("sk %p timeo %ld", sk, timeo);
--
-- /* Wait for an incoming connection. (wake-one). */
-- add_wait_queue_exclusive(sk->sleep, &wait);
-- current->state = TASK_INTERRUPTIBLE;
-- while (!(ch = l2cap_accept_dequeue(sk, BT_CONNECTED))) {
-- if (!timeo) {
-- err = -EAGAIN;
-- break;
-- }
--
-- release_sock(sk);
-- timeo = schedule_timeout(timeo);
-- lock_sock(sk);
--
-- if (sk->state != BT_LISTEN) {
-- err = -EBADFD;
-- break;
-- }
--
-- if (signal_pending(current)) {
-- err = sock_intr_errno(timeo);
-- break;
-- }
-- }
-- current->state = TASK_RUNNING;
-- remove_wait_queue(sk->sleep, &wait);
--
-- if (err)
-- goto done;
--
-- sock_graft(ch, newsock);
-- newsock->state = SS_CONNECTED;
--
-- DBG("new socket %p", ch);
--
--done:
-- release_sock(sk);
--
-- return err;
--}
--
--static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
--{
-- struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-- struct sock *sk = sock->sk;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- addr->sa_family = AF_BLUETOOTH;
-- *len = sizeof(struct sockaddr_l2);
--
-- if (peer)
-- bacpy(&la->l2_bdaddr, &l2cap_pi(sk)->dst);
-- else
-- bacpy(&la->l2_bdaddr, &l2cap_pi(sk)->src);
--
-- la->l2_psm = l2cap_pi(sk)->psm;
--
-- return 0;
--}
--
--static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
--{
-- struct sock *sk = sock->sk;
-- int err = 0;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- if (sk->err)
-- return sock_error(sk);
--
-- if (msg->msg_flags & MSG_OOB)
-- return -EOPNOTSUPP;
--
-- lock_sock(sk);
--
-- if (sk->state == BT_CONNECTED)
-- err = l2cap_chan_send(sk, msg, len);
-- else
-- err = -ENOTCONN;
--
-- release_sock(sk);
-- return err;
--}
--
--static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
--{
-- struct sock *sk = sock->sk;
-- int noblock = flags & MSG_DONTWAIT;
-- int copied, err;
-- struct sk_buff *skb;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- if (flags & (MSG_OOB))
-- return -EOPNOTSUPP;
--
-- if (sk->state == BT_CLOSED)
-- return 0;
--
-- if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
-- return err;
--
-- msg->msg_namelen = 0;
--
-- copied = skb->len;
-- if (len < copied) {
-- msg->msg_flags |= MSG_TRUNC;
-- copied = len;
-- }
--
-- skb->h.raw = skb->data;
-- err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
--
-- skb_free_datagram(sk, skb);
--
-- return err ? : copied;
--}
--
--int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
--{
-- struct sock *sk = sock->sk;
-- struct l2cap_options opts;
-- int err = 0;
--
-- DBG("sk %p", sk);
--
-- lock_sock(sk);
--
-- switch (optname) {
-- case L2CAP_OPTIONS:
-- if (copy_from_user((char *)&opts, optval, optlen)) {
-- err = -EFAULT;
-- break;
-- }
-- l2cap_pi(sk)->imtu = opts.imtu;
-- l2cap_pi(sk)->omtu = opts.omtu;
-- break;
--
-- default:
-- err = -ENOPROTOOPT;
-- break;
-- };
--
-- release_sock(sk);
-- return err;
--}
--
--int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
--{
-- struct sock *sk = sock->sk;
-- struct l2cap_options opts;
-- struct l2cap_conninfo cinfo;
-- int len, err = 0;
--
-- if (get_user(len, optlen))
-- return -EFAULT;
--
-- lock_sock(sk);
--
-- switch (optname) {
-- case L2CAP_OPTIONS:
-- opts.imtu = l2cap_pi(sk)->imtu;
-- opts.omtu = l2cap_pi(sk)->omtu;
-- opts.flush_to = l2cap_pi(sk)->flush_to;
--
-- len = MIN(len, sizeof(opts));
-- if (copy_to_user(optval, (char *)&opts, len))
-- err = -EFAULT;
--
-- break;
--
-- case L2CAP_CONNINFO:
-- if (sk->state != BT_CONNECTED) {
-- err = -ENOTCONN;
-- break;
-- }
--
-- cinfo.hci_handle = l2cap_pi(sk)->conn->hconn->handle;
--
-- len = MIN(len, sizeof(cinfo));
-- if (copy_to_user(optval, (char *)&cinfo, len))
-- err = -EFAULT;
--
-- break;
--
-- default:
-- err = -ENOPROTOOPT;
-- break;
-- };
--
-- release_sock(sk);
-- return err;
--}
--
--static unsigned int l2cap_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
--{
-- struct sock *sk = sock->sk;
-- struct l2cap_accept_q *aq;
-- unsigned int mask;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- poll_wait(file, sk->sleep, wait);
-- mask = 0;
--
-- if (sk->err || !skb_queue_empty(&sk->error_queue))
-- mask |= POLLERR;
--
-- if (sk->shutdown == SHUTDOWN_MASK)
-- mask |= POLLHUP;
--
-- aq = &l2cap_pi(sk)->accept_q;
-- if (!skb_queue_empty(&sk->receive_queue) || aq->head || (sk->shutdown & RCV_SHUTDOWN))
-- mask |= POLLIN | POLLRDNORM;
--
-- if (sk->state == BT_CLOSED)
-- mask |= POLLHUP;
--
-- if (sock_writeable(sk))
-- mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
-- else
-- set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
--
-- return mask;
--}
--
--static int l2cap_sock_release(struct socket *sock)
--{
-- struct sock *sk = sock->sk;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- if (!sk)
-- return 0;
--
-- sock_orphan(sk);
--
-- l2cap_sock_close(sk);
--
-- return 0;
--}
--
--/* --------- L2CAP channels --------- */
--static struct sock * __l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
--{
-- struct sock *s;
--
-- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-- if (l2cap_pi(s)->dcid == cid)
-- break;
-- }
--
-- return s;
--}
--
--static inline struct sock *l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
--{
-- struct sock *s;
--
-- read_lock(&l->lock);
-- s = __l2cap_get_chan_by_dcid(l, cid);
-- read_unlock(&l->lock);
--
-- return s;
--}
--
--static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
--{
-- struct sock *s;
--
-- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-- if (l2cap_pi(s)->scid == cid)
-- break;
-- }
--
-- return s;
--}
--static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
--{
-- struct sock *s;
--
-- read_lock(&l->lock);
-- s = __l2cap_get_chan_by_scid(l, cid);
-- read_unlock(&l->lock);
--
-- return s;
--}
--
--static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
--{
-- struct sock *s;
--
-- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-- if (l2cap_pi(s)->ident == ident)
-- break;
-- }
--
-- return s;
--}
--
--static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
--{
-- struct sock *s;
--
-- read_lock(&l->lock);
-- s = __l2cap_get_chan_by_ident(l, ident);
-- read_unlock(&l->lock);
--
-- return s;
--}
--
--static __u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
--{
-- __u16 cid = 0x0040;
--
-- for (; cid < 0xffff; cid++) {
-- if(!__l2cap_get_chan_by_scid(l, cid))
-- return cid;
-- }
--
-- return 0;
--}
--
--static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
--{
-- sock_hold(sk);
--
-- if (l->head)
-- l2cap_pi(l->head)->prev_c = sk;
--
-- l2cap_pi(sk)->next_c = l->head;
-- l2cap_pi(sk)->prev_c = NULL;
-- l->head = sk;
--}
--
--static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
--{
-- struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
--
-- write_lock(&l->lock);
-- if (sk == l->head)
-- l->head = next;
--
-- if (next)
-- l2cap_pi(next)->prev_c = prev;
-- if (prev)
-- l2cap_pi(prev)->next_c = next;
-- write_unlock(&l->lock);
--
-- __sock_put(sk);
--}
--
--static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
--{
-- struct l2cap_chan_list *l = &conn->chan_list;
--
-- DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
--
-- l2cap_conn_clear_timer(conn);
--
-- atomic_inc(&conn->refcnt);
-- l2cap_pi(sk)->conn = conn;
--
-- if (sk->type == SOCK_SEQPACKET) {
-- /* Alloc CID for normal socket */
-- l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
-- } else {
-- /* Raw socket can send only signalling messages */
-- l2cap_pi(sk)->scid = 0x0001;
-- l2cap_pi(sk)->dcid = 0x0001;
-- l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
-- }
--
-- __l2cap_chan_link(l, sk);
--
-- if (parent)
-- l2cap_accept_queue(parent, sk);
--}
--
--static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
--{
-- struct l2cap_chan_list *l = &conn->chan_list;
--
-- write_lock(&l->lock);
-- __l2cap_chan_add(conn, sk, parent);
-- write_unlock(&l->lock);
--}
--
--/* Delete channel.
-- * Must be called on the locked socket. */
--static void l2cap_chan_del(struct sock *sk, int err)
--{
-- struct l2cap_conn *conn;
-- struct sock *parent;
--
-- conn = l2cap_pi(sk)->conn;
-- parent = l2cap_pi(sk)->parent;
--
-- DBG("sk %p, conn %p, err %d", sk, conn, err);
--
-- if (parent) {
-- /* Unlink from parent accept queue */
-- bh_lock_sock(parent);
-- l2cap_accept_unlink(sk);
-- bh_unlock_sock(parent);
-- }
--
-- if (conn) {
-- long timeout;
--
-- /* Unlink from channel list */
-- l2cap_chan_unlink(&conn->chan_list, sk);
-- l2cap_pi(sk)->conn = NULL;
--
-- if (conn->out)
-- timeout = L2CAP_DISCONN_TIMEOUT;
-- else
-- timeout = L2CAP_CONN_IDLE_TIMEOUT;
--
-- if (atomic_dec_and_test(&conn->refcnt) && conn->state == BT_CONNECTED) {
-- /* Schedule Baseband disconnect */
-- l2cap_conn_set_timer(conn, timeout);
-- }
-- }
--
-- sk->state = BT_CLOSED;
-- sk->err = err;
-- sk->state_change(sk);
--
-- sk->zapped = 1;
--}
--
--static void l2cap_conn_ready(struct l2cap_conn *conn)
--{
-- struct l2cap_chan_list *l = &conn->chan_list;
-- struct sock *sk;
--
-- DBG("conn %p", conn);
--
-- read_lock(&l->lock);
--
-- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-- bh_lock_sock(sk);
--
-- if (sk->type != SOCK_SEQPACKET) {
-- sk->state = BT_CONNECTED;
-- sk->state_change(sk);
-- l2cap_sock_clear_timer(sk);
-- } else if (sk->state == BT_CONNECT) {
-- l2cap_conn_req req;
-- req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- req.psm = l2cap_pi(sk)->psm;
-- l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
--
-- l2cap_sock_set_timer(sk, sk->sndtimeo);
-- }
--
-- bh_unlock_sock(sk);
-- }
--
-- read_unlock(&l->lock);
--}
--
--static void l2cap_chan_ready(struct sock *sk)
--{
-- struct sock *parent = l2cap_pi(sk)->parent;
--
-- DBG("sk %p, parent %p", sk, parent);
--
-- l2cap_pi(sk)->conf_state = 0;
-- l2cap_sock_clear_timer(sk);
--
-- if (!parent) {
-- /* Outgoing channel.
-- * Wake up socket sleeping on connect.
-- */
-- sk->state = BT_CONNECTED;
-- sk->state_change(sk);
-- } else {
-- /* Incomming channel.
-- * Wake up socket sleeping on accept.
-- */
-- parent->data_ready(parent, 1);
-- }
--}
--
--/* Copy frame to all raw sockets on that connection */
--void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
--{
-- struct l2cap_chan_list *l = &conn->chan_list;
-- struct sk_buff *nskb;
-- struct sock * sk;
--
-- DBG("conn %p", conn);
--
-- read_lock(&l->lock);
-- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-- if (sk->type != SOCK_RAW)
-- continue;
--
-- /* Don't send frame to the socket it came from */
-- if (skb->sk == sk)
-- continue;
--
-- if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
-- continue;
--
-- skb_queue_tail(&sk->receive_queue, nskb);
-- sk->data_ready(sk, nskb->len);
-- }
-- read_unlock(&l->lock);
--}
--
--static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
--{
-- struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-- struct sk_buff *skb, **frag;
-- int err, size, count, sent=0;
-- l2cap_hdr *lh;
--
-- /* Check outgoing MTU */
-- if (len > l2cap_pi(sk)->omtu)
-- return -EINVAL;
--
-- DBG("sk %p len %d", sk, len);
--
-- /* First fragment (with L2CAP header) */
-- count = MIN(conn->iff->mtu - L2CAP_HDR_SIZE, len);
-- size = L2CAP_HDR_SIZE + count;
-- if (!(skb = bluez_skb_send_alloc(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)))
-- return err;
--
-- /* Create L2CAP header */
-- lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-- lh->len = __cpu_to_le16(len);
-- lh->cid = __cpu_to_le16(l2cap_pi(sk)->dcid);
--
-- if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
-- err = -EFAULT;
-- goto fail;
-- }
--
-- sent += count;
-- len -= count;
--
-- /* Continuation fragments (no L2CAP header) */
-- frag = &skb_shinfo(skb)->frag_list;
-- while (len) {
-- count = MIN(conn->iff->mtu, len);
--
-- *frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
-- if (!*frag)
-- goto fail;
--
-- if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
-- err = -EFAULT;
-- goto fail;
-- }
--
-- sent += count;
-- len -= count;
--
-- frag = &(*frag)->next;
-- }
--
-- if ((err = hci_send_acl(conn->hconn, skb, 0)) < 0)
-- goto fail;
--
-- return sent;
--
--fail:
-- kfree_skb(skb);
-- return err;
--}
--
--/* --------- L2CAP signalling commands --------- */
--static inline __u8 l2cap_get_ident(struct l2cap_conn *conn)
--{
-- __u8 id;
--
-- /* Get next available identificator.
-- * 1 - 199 are used by kernel.
-- * 200 - 254 are used by utilities like l2ping, etc
-- */
--
-- spin_lock(&conn->lock);
--
-- if (++conn->tx_ident > 199)
-- conn->tx_ident = 1;
--
-- id = conn->tx_ident;
--
-- spin_unlock(&conn->lock);
--
-- return id;
--}
--
--static inline struct sk_buff *l2cap_build_cmd(__u8 code, __u8 ident, __u16 len, void *data)
--{
-- struct sk_buff *skb;
-- l2cap_cmd_hdr *cmd;
-- l2cap_hdr *lh;
-- int size;
--
-- DBG("code 0x%2.2x, ident 0x%2.2x, len %d", code, ident, len);
--
-- size = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + len;
-- if (!(skb = bluez_skb_alloc(size, GFP_ATOMIC)))
-- return NULL;
--
-- lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-- lh->len = __cpu_to_le16(L2CAP_CMD_HDR_SIZE + len);
-- lh->cid = __cpu_to_le16(0x0001);
--
-- cmd = (l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
-- cmd->code = code;
-- cmd->ident = ident;
-- cmd->len = __cpu_to_le16(len);
--
-- if (len)
-- memcpy(skb_put(skb, len), data, len);
--
-- return skb;
--}
--
--static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data)
--{
-- struct sk_buff *skb;
-- __u8 ident;
--
-- DBG("code 0x%2.2x", code);
--
-- ident = l2cap_get_ident(conn);
-- if (!(skb = l2cap_build_cmd(code, ident, len, data)))
-- return -ENOMEM;
-- return hci_send_acl(conn->hconn, skb, 0);
--}
--
--static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data)
--{
-- struct sk_buff *skb;
--
-- DBG("code 0x%2.2x", code);
--
-- if (!(skb = l2cap_build_cmd(code, ident, len, data)))
-- return -ENOMEM;
-- return hci_send_acl(conn->hconn, skb, 0);
--}
--
--static inline int l2cap_get_conf_opt(__u8 **ptr, __u8 *type, __u32 *val)
--{
-- l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
-- int len;
--
-- *type = opt->type;
-- switch (opt->len) {
-- case 1:
-- *val = *((__u8 *) opt->val);
-- break;
--
-- case 2:
-- *val = __le16_to_cpu(*((__u16 *)opt->val));
-- break;
--
-- case 4:
-- *val = __le32_to_cpu(*((__u32 *)opt->val));
-- break;
--
-- default:
-- *val = 0L;
-- break;
-- };
--
-- DBG("type 0x%2.2x len %d val 0x%8.8x", *type, opt->len, *val);
--
-- len = L2CAP_CONF_OPT_SIZE + opt->len;
--
-- *ptr += len;
--
-- return len;
--}
--
--static inline void l2cap_parse_conf_req(struct sock *sk, char *data, int len)
--{
-- __u8 type, hint; __u32 val;
-- __u8 *ptr = data;
--
-- DBG("sk %p len %d", sk, len);
--
-- while (len >= L2CAP_CONF_OPT_SIZE) {
-- len -= l2cap_get_conf_opt(&ptr, &type, &val);
--
-- hint = type & 0x80;
-- type &= 0x7f;
--
-- switch (type) {
-- case L2CAP_CONF_MTU:
-- l2cap_pi(sk)->conf_mtu = val;
-- break;
--
-- case L2CAP_CONF_FLUSH_TO:
-- l2cap_pi(sk)->flush_to = val;
-- break;
--
-- case L2CAP_CONF_QOS:
-- break;
--
-- default:
-- if (hint)
-- break;
--
-- /* FIXME: Reject unknon option */
-- break;
-- };
-- }
--}
--
--static inline void l2cap_add_conf_opt(__u8 **ptr, __u8 type, __u8 len, __u32 val)
--{
-- register l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
--
-- DBG("type 0x%2.2x len %d val 0x%8.8x", type, len, val);
--
-- opt->type = type;
-- opt->len = len;
-- switch (len) {
-- case 1:
-- *((__u8 *) opt->val) = val;
-- break;
--
-- case 2:
-- *((__u16 *) opt->val) = __cpu_to_le16(val);
-- break;
--
-- case 4:
-- *((__u32 *) opt->val) = __cpu_to_le32(val);
-- break;
-- };
--
-- *ptr += L2CAP_CONF_OPT_SIZE + len;
--}
--
--static int l2cap_build_conf_req(struct sock *sk, __u8 *data)
--{
-- struct l2cap_pinfo *pi = l2cap_pi(sk);
-- l2cap_conf_req *req = (l2cap_conf_req *) data;
-- __u8 *ptr = req->data;
--
-- DBG("sk %p", sk);
--
-- if (pi->imtu != L2CAP_DEFAULT_MTU)
-- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
--
-- /* FIXME. Need actual value of the flush timeout */
-- //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
-- // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
--
-- req->dcid = __cpu_to_le16(pi->dcid);
-- req->flags = __cpu_to_le16(0);
--
-- return ptr - data;
--}
--
--static int l2cap_conf_output(struct sock *sk, __u8 **ptr)
--{
-- struct l2cap_pinfo *pi = l2cap_pi(sk);
-- int result = 0;
--
-- /* Configure output options and let other side know
-- * which ones we don't like.
-- */
-- if (pi->conf_mtu < pi->omtu) {
-- l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, l2cap_pi(sk)->omtu);
-- result = L2CAP_CONF_UNACCEPT;
-- } else {
-- pi->omtu = pi->conf_mtu;
-- }
--
-- DBG("sk %p result %d", sk, result);
-- return result;
--}
--
--static int l2cap_build_conf_rsp(struct sock *sk, __u8 *data, int *result)
--{
-- l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data;
-- __u8 *ptr = rsp->data;
--
-- DBG("sk %p complete %d", sk, result ? 1 : 0);
--
-- if (result)
-- *result = l2cap_conf_output(sk, &ptr);
--
-- rsp->scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- rsp->result = __cpu_to_le16(result ? *result : 0);
-- rsp->flags = __cpu_to_le16(0);
--
-- return ptr - data;
--}
--
--static inline int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- struct l2cap_chan_list *list = &conn->chan_list;
-- l2cap_conn_req *req = (l2cap_conn_req *) data;
-- l2cap_conn_rsp rsp;
-- struct sock *sk, *parent;
--
-- __u16 scid = __le16_to_cpu(req->scid);
-- __u16 psm = req->psm;
--
-- DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
--
-- /* Check if we have socket listening on psm */
-- if (!(parent = l2cap_get_sock_listen(&conn->src, psm)))
-- goto reject;
--
-- bh_lock_sock(parent);
-- write_lock(&list->lock);
--
-- /* Check if we already have channel with that dcid */
-- if (__l2cap_get_chan_by_dcid(list, scid))
-- goto unlock;
--
-- /* Check for backlog size */
-- if (parent->ack_backlog > parent->max_ack_backlog)
-- goto unlock;
--
-- if (!(sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC)))
-- goto unlock;
--
-- l2cap_sock_init(sk, parent);
--
-- bacpy(&l2cap_pi(sk)->src, &conn->src);
-- bacpy(&l2cap_pi(sk)->dst, &conn->dst);
-- l2cap_pi(sk)->psm = psm;
-- l2cap_pi(sk)->dcid = scid;
--
-- __l2cap_chan_add(conn, sk, parent);
-- sk->state = BT_CONFIG;
--
-- write_unlock(&list->lock);
-- bh_unlock_sock(parent);
--
-- rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- rsp.result = __cpu_to_le16(0);
-- rsp.status = __cpu_to_le16(0);
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
--
-- return 0;
--
--unlock:
-- write_unlock(&list->lock);
-- bh_unlock_sock(parent);
--
--reject:
-- rsp.scid = __cpu_to_le16(scid);
-- rsp.dcid = __cpu_to_le16(0);
-- rsp.status = __cpu_to_le16(0);
-- rsp.result = __cpu_to_le16(L2CAP_CONN_NO_MEM);
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
--
-- return 0;
--}
--
--static inline int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_conn_rsp *rsp = (l2cap_conn_rsp *) data;
-- __u16 scid, dcid, result, status;
-- struct sock *sk;
--
-- scid = __le16_to_cpu(rsp->scid);
-- dcid = __le16_to_cpu(rsp->dcid);
-- result = __le16_to_cpu(rsp->result);
-- status = __le16_to_cpu(rsp->status);
--
-- DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-- return -ENOENT;
--
-- bh_lock_sock(sk);
--
-- if (!result) {
-- char req[64];
--
-- sk->state = BT_CONFIG;
-- l2cap_pi(sk)->dcid = dcid;
-- l2cap_pi(sk)->conf_state |= CONF_REQ_SENT;
--
-- l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-- } else {
-- l2cap_chan_del(sk, ECONNREFUSED);
-- }
--
-- bh_unlock_sock(sk);
-- return 0;
--}
--
--static inline int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_conf_req * req = (l2cap_conf_req *) data;
-- __u16 dcid, flags;
-- __u8 rsp[64];
-- struct sock *sk;
-- int result;
--
-- dcid = __le16_to_cpu(req->dcid);
-- flags = __le16_to_cpu(req->flags);
--
-- DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-- return -ENOENT;
--
-- bh_lock_sock(sk);
--
-- l2cap_parse_conf_req(sk, req->data, cmd->len - L2CAP_CONF_REQ_SIZE);
--
-- if (flags & 0x01) {
-- /* Incomplete config. Send empty response. */
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
-- goto unlock;
-- }
--
-- /* Complete config. */
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &result), rsp);
--
-- if (result)
-- goto unlock;
--
-- /* Output config done */
-- l2cap_pi(sk)->conf_state |= CONF_OUTPUT_DONE;
--
-- if (l2cap_pi(sk)->conf_state & CONF_INPUT_DONE) {
-- sk->state = BT_CONNECTED;
-- l2cap_chan_ready(sk);
-- } else if (!(l2cap_pi(sk)->conf_state & CONF_REQ_SENT)) {
-- char req[64];
-- l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-- }
--
--unlock:
-- bh_unlock_sock(sk);
--
-- return 0;
--}
--
--static inline int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_conf_rsp *rsp = (l2cap_conf_rsp *)data;
-- __u16 scid, flags, result;
-- struct sock *sk;
-- int err = 0;
--
-- scid = __le16_to_cpu(rsp->scid);
-- flags = __le16_to_cpu(rsp->flags);
-- result = __le16_to_cpu(rsp->result);
--
-- DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-- return -ENOENT;
--
-- bh_lock_sock(sk);
--
-- if (result) {
-- l2cap_disconn_req req;
--
-- /* They didn't like our options. Well... we do not negotiate.
-- * Close channel.
-- */
-- sk->state = BT_DISCONN;
--
-- req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
--
-- l2cap_sock_set_timer(sk, sk->sndtimeo);
-- goto done;
-- }
--
-- if (flags & 0x01)
-- goto done;
--
-- /* Input config done */
-- l2cap_pi(sk)->conf_state |= CONF_INPUT_DONE;
--
-- if (l2cap_pi(sk)->conf_state & CONF_OUTPUT_DONE) {
-- sk->state = BT_CONNECTED;
-- l2cap_chan_ready(sk);
-- }
--
--done:
-- bh_unlock_sock(sk);
--
-- return err;
--}
--
--static inline int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_disconn_req *req = (l2cap_disconn_req *) data;
-- l2cap_disconn_rsp rsp;
-- __u16 dcid, scid;
-- struct sock *sk;
--
-- scid = __le16_to_cpu(req->scid);
-- dcid = __le16_to_cpu(req->dcid);
--
-- DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-- return 0;
--
-- bh_lock_sock(sk);
--
-- rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_DISCONN_RSP, L2CAP_DISCONN_RSP_SIZE, &rsp);
--
-- l2cap_chan_del(sk, ECONNRESET);
--
-- bh_unlock_sock(sk);
--
-- l2cap_sock_kill(sk);
--
-- return 0;
--}
--
--static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_disconn_rsp *rsp = (l2cap_disconn_rsp *) data;
-- __u16 dcid, scid;
-- struct sock *sk;
--
-- scid = __le16_to_cpu(rsp->scid);
-- dcid = __le16_to_cpu(rsp->dcid);
--
-- DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-- return -ENOENT;
--
-- bh_lock_sock(sk);
-- l2cap_sock_clear_timer(sk);
-- l2cap_chan_del(sk, ECONNABORTED);
-- bh_unlock_sock(sk);
--
-- l2cap_sock_kill(sk);
--
-- return 0;
--}
--
--static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
--{
-- __u8 *data = skb->data;
-- int len = skb->len;
-- l2cap_cmd_hdr cmd;
-- int err = 0;
--
-- while (len >= L2CAP_CMD_HDR_SIZE) {
-- memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
-- data += L2CAP_CMD_HDR_SIZE;
-- len -= L2CAP_CMD_HDR_SIZE;
--
-- cmd.len = __le16_to_cpu(cmd.len);
--
-- DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
--
-- if (cmd.len > len || !cmd.ident) {
-- DBG("corrupted command");
-- break;
-- }
--
-- switch (cmd.code) {
-- case L2CAP_CONN_REQ:
-- err = l2cap_connect_req(conn, &cmd, data);
-- break;
--
-- case L2CAP_CONN_RSP:
-- err = l2cap_connect_rsp(conn, &cmd, data);
-- break;
--
-- case L2CAP_CONF_REQ:
-- err = l2cap_config_req(conn, &cmd, data);
-- break;
--
-- case L2CAP_CONF_RSP:
-- err = l2cap_config_rsp(conn, &cmd, data);
-- break;
--
-- case L2CAP_DISCONN_REQ:
-- err = l2cap_disconnect_req(conn, &cmd, data);
-- break;
--
-- case L2CAP_DISCONN_RSP:
-- err = l2cap_disconnect_rsp(conn, &cmd, data);
-- break;
--
-- case L2CAP_COMMAND_REJ:
-- /* FIXME: We should process this */
-- l2cap_raw_recv(conn, skb);
-- break;
--
-- case L2CAP_ECHO_REQ:
-- l2cap_send_rsp(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data);
-- break;
--
-- case L2CAP_ECHO_RSP:
-- case L2CAP_INFO_REQ:
-- case L2CAP_INFO_RSP:
-- l2cap_raw_recv(conn, skb);
-- break;
--
-- default:
-- ERR("Uknown signaling command 0x%2.2x", cmd.code);
-- err = -EINVAL;
-- break;
-- };
--
-- if (err) {
-- l2cap_cmd_rej rej;
-- DBG("error %d", err);
--
-- /* FIXME: Map err to a valid reason. */
-- rej.reason = __cpu_to_le16(0);
-- l2cap_send_rsp(conn, cmd.ident, L2CAP_COMMAND_REJ, L2CAP_CMD_REJ_SIZE, &rej);
-- }
--
-- data += cmd.len;
-- len -= cmd.len;
-- }
--
-- kfree_skb(skb);
--}
--
--static inline int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
--{
-- struct sock *sk;
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, cid))) {
-- DBG("unknown cid 0x%4.4x", cid);
-- goto drop;
-- }
--
-- DBG("sk %p, len %d", sk, skb->len);
--
-- if (sk->state != BT_CONNECTED)
-- goto drop;
--
-- if (l2cap_pi(sk)->imtu < skb->len)
-- goto drop;
--
-- skb_queue_tail(&sk->receive_queue, skb);
-- sk->data_ready(sk, skb->len);
--
-- return 0;
--
--drop:
-- kfree_skb(skb);
--
-- return 0;
--}
--
--static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
--{
-- l2cap_hdr *lh = (l2cap_hdr *) skb->data;
-- __u16 cid, len;
--
-- skb_pull(skb, L2CAP_HDR_SIZE);
-- cid = __le16_to_cpu(lh->cid);
-- len = __le16_to_cpu(lh->len);
--
-- DBG("len %d, cid 0x%4.4x", len, cid);
--
-- if (cid == 0x0001)
-- l2cap_sig_channel(conn, skb);
-- else
-- l2cap_data_channel(conn, cid, skb);
--}
--
--/* ------------ L2CAP interface with lower layer (HCI) ------------- */
--static int l2cap_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
--{
-- struct hci_dev *hdev = (struct hci_dev *) ptr;
--
-- DBG("hdev %s, event %ld", hdev->name, event);
--
-- write_lock(&l2cap_rt_lock);
--
-- switch (event) {
-- case HCI_DEV_UP:
-- l2cap_iff_add(hdev);
-- break;
--
-- case HCI_DEV_DOWN:
-- l2cap_iff_del(hdev);
-- break;
-- };
--
-- write_unlock(&l2cap_rt_lock);
--
-- return NOTIFY_DONE;
--}
--
--int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
--{
-- struct l2cap_iff *iff;
--
-- DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
--
-- if (!(iff = hdev->l2cap_data)) {
-- ERR("unknown interface");
-- return 0;
-- }
--
-- /* Always accept connection */
-- return 1;
--}
--
--int l2cap_connect_cfm(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 status, struct hci_conn *hconn)
--{
-- struct l2cap_conn *conn;
-- struct l2cap_iff *iff;
-- int err = 0;
--
-- DBG("hdev %s bdaddr %s hconn %p", hdev->name, batostr(bdaddr), hconn);
--
-- if (!(iff = hdev->l2cap_data)) {
-- ERR("unknown interface");
-- return 0;
-- }
--
-- l2cap_iff_lock(iff);
--
-- conn = l2cap_get_conn_by_addr(iff, bdaddr);
--
-- if (conn) {
-- /* Outgoing connection */
-- DBG("Outgoing connection: %s -> %s, %p, %2.2x", batostr(iff->bdaddr), batostr(bdaddr), conn, status);
--
-- if (!status && hconn) {
-- conn->state = BT_CONNECTED;
-- conn->hconn = hconn;
--
-- hconn->l2cap_data = (void *)conn;
--
-- /* Establish channels */
-- l2cap_conn_ready(conn);
-- } else {
-- l2cap_conn_del(conn, bterr(status));
-- }
-- } else {
-- /* Incomming connection */
-- DBG("Incomming connection: %s -> %s, %2.2x", batostr(iff->bdaddr), batostr(bdaddr), status);
--
-- if (status || !hconn)
-- goto done;
--
-- if (!(conn = l2cap_conn_add(iff, bdaddr))) {
-- err = -ENOMEM;
-- goto done;
-- }
--
-- conn->hconn = hconn;
-- hconn->l2cap_data = (void *)conn;
--
-- conn->state = BT_CONNECTED;
-- }
--
--done:
-- l2cap_iff_unlock(iff);
--
-- return err;
--}
--
--int l2cap_disconn_ind(struct hci_conn *hconn, __u8 reason)
--{
-- struct l2cap_conn *conn = hconn->l2cap_data;
--
-- DBG("hconn %p reason %d", hconn, reason);
--
-- if (!conn) {
-- ERR("unknown connection");
-- return 0;
-- }
-- conn->hconn = NULL;
--
-- l2cap_iff_lock(conn->iff);
-- l2cap_conn_del(conn, bterr(reason));
-- l2cap_iff_unlock(conn->iff);
--
-- return 0;
--}
--
--int l2cap_recv_acldata(struct hci_conn *hconn, struct sk_buff *skb, __u16 flags)
--{
-- struct l2cap_conn *conn = hconn->l2cap_data;
--
-- if (!conn) {
-- ERR("unknown connection %p", hconn);
-- goto drop;
-- }
--
-- DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
--
-- if (flags & ACL_START) {
-- int flen, tlen, size;
-- l2cap_hdr *lh;
--
-- if (conn->rx_len) {
-- ERR("Unexpected start frame (len %d)", skb->len);
-- kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
-- conn->rx_len = 0;
-- }
--
-- if (skb->len < L2CAP_HDR_SIZE) {
-- ERR("Frame is too small (len %d)", skb->len);
-- goto drop;
-- }
--
-- lh = (l2cap_hdr *)skb->data;
-- tlen = __le16_to_cpu(lh->len);
-- flen = skb->len - L2CAP_HDR_SIZE;
--
-- DBG("Start: total len %d, frag len %d", tlen, flen);
--
-- if (flen == tlen) {
-- /* Complete frame received */
-- l2cap_recv_frame(conn, skb);
-- return 0;
-- }
--
-- /* Allocate skb for the complete frame (with header) */
-- size = L2CAP_HDR_SIZE + tlen;
-- if (!(conn->rx_skb = bluez_skb_alloc(size, GFP_ATOMIC)))
-- goto drop;
--
-- memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
--
-- conn->rx_len = tlen - flen;
-- } else {
-- DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
--
-- if (!conn->rx_len) {
-- ERR("Unexpected continuation frame (len %d)", skb->len);
-- goto drop;
-- }
--
-- if (skb->len > conn->rx_len) {
-- ERR("Fragment is too large (len %d)", skb->len);
-- kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
-- goto drop;
-- }
--
-- memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
-- conn->rx_len -= skb->len;
--
-- if (!conn->rx_len) {
-- /* Complete frame received */
-- l2cap_recv_frame(conn, conn->rx_skb);
-- conn->rx_skb = NULL;
-- }
-- }
--
--drop:
-- kfree_skb(skb);
-- return 0;
--}
--
--struct proto_ops l2cap_sock_ops = {
-- family: PF_BLUETOOTH,
-- release: l2cap_sock_release,
-- bind: l2cap_sock_bind,
-- connect: l2cap_sock_connect,
-- listen: l2cap_sock_listen,
-- accept: l2cap_sock_accept,
-- getname: l2cap_sock_getname,
-- sendmsg: l2cap_sock_sendmsg,
-- recvmsg: l2cap_sock_recvmsg,
-- poll: l2cap_sock_poll,
-- socketpair: sock_no_socketpair,
-- ioctl: sock_no_ioctl,
-- shutdown: sock_no_shutdown,
-- setsockopt: l2cap_sock_setsockopt,
-- getsockopt: l2cap_sock_getsockopt,
-- mmap: sock_no_mmap
--};
--
--struct net_proto_family l2cap_sock_family_ops = {
-- family: PF_BLUETOOTH,
-- create: l2cap_sock_create
--};
--
--struct hci_proto l2cap_hci_proto = {
-- name: "L2CAP",
-- id: HCI_PROTO_L2CAP,
-- connect_ind: l2cap_connect_ind,
-- connect_cfm: l2cap_connect_cfm,
-- disconn_ind: l2cap_disconn_ind,
-- recv_acldata: l2cap_recv_acldata,
--};
--
--struct notifier_block l2cap_nblock = {
-- notifier_call: l2cap_dev_event
--};
--
--int __init l2cap_init(void)
--{
-- INF("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
--
-- if (bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops)) {
-- ERR("Can't register L2CAP socket");
-- return -EPROTO;
-- }
--
-- if (hci_register_proto(&l2cap_hci_proto) < 0) {
-- ERR("Can't register L2CAP protocol");
-- return -EPROTO;
-- }
--
-- hci_register_notifier(&l2cap_nblock);
--
-- l2cap_register_proc();
--
-- return 0;
--}
--
--void l2cap_cleanup(void)
--{
-- l2cap_unregister_proc();
--
-- /* Unregister socket, protocol and notifier */
-- if (bluez_sock_unregister(BTPROTO_L2CAP))
-- ERR("Can't unregister L2CAP socket");
--
-- if (hci_unregister_proto(&l2cap_hci_proto) < 0)
-- ERR("Can't unregister L2CAP protocol");
--
-- hci_unregister_notifier(&l2cap_nblock);
--
-- /* We _must_ not have any sockets and/or connections
-- * at this stage.
-- */
--
-- /* Free interface list and unlock HCI devices */
-- {
-- struct list_head *list = &l2cap_iff_list;
--
-- while (!list_empty(list)) {
-- struct l2cap_iff *iff;
--
-- iff = list_entry(list->next, struct l2cap_iff, list);
-- l2cap_iff_del(iff->hdev);
-- }
-- }
--}
--
--module_init(l2cap_init);
--module_exit(l2cap_cleanup);
--
--MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
--MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
--MODULE_LICENSE("GPL");
--
-diff -urN linux-2.4.18/net/bluetooth/l2cap_proc.c linux-2.4.18-mh15/net/bluetooth/l2cap_proc.c
---- linux-2.4.18/net/bluetooth/l2cap_proc.c 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/net/bluetooth/l2cap_proc.c 1970-01-01 01:00:00.000000000 +0100
-@@ -1,165 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * BlueZ L2CAP proc fs support.
-- *
-- * $Id$
-- */
--
--#include <linux/config.h>
--#include <linux/module.h>
--
--#include <linux/types.h>
--#include <linux/errno.h>
--#include <linux/kernel.h>
--#include <linux/major.h>
--#include <linux/sched.h>
--#include <linux/slab.h>
--#include <linux/poll.h>
--#include <linux/fcntl.h>
--#include <linux/init.h>
--#include <linux/skbuff.h>
--#include <linux/interrupt.h>
--#include <linux/socket.h>
--#include <linux/skbuff.h>
--#include <linux/proc_fs.h>
--#include <linux/list.h>
--#include <net/sock.h>
--
--#include <asm/system.h>
--#include <asm/uaccess.h>
--
--#include <net/bluetooth/bluez.h>
--#include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/l2cap_core.h>
--
--#ifndef L2CAP_DEBUG
--#undef DBG
--#define DBG( A... )
--#endif
--
--/* ----- PROC fs support ----- */
--static int l2cap_conn_dump(char *buf, struct l2cap_iff *iff)
--{
-- struct list_head *p;
-- char *ptr = buf;
--
-- list_for_each(p, &iff->conn_list) {
-- struct l2cap_conn *c;
--
-- c = list_entry(p, struct l2cap_conn, list);
-- ptr += sprintf(ptr, " %p %d %p %p %s %s\n",
-- c, c->state, c->iff, c->hconn, batostr(&c->src), batostr(&c->dst));
-- }
--
-- return ptr - buf;
--}
--
--static int l2cap_iff_dump(char *buf)
--{
-- struct list_head *p;
-- char *ptr = buf;
--
-- ptr += sprintf(ptr, "Interfaces:\n");
--
-- write_lock(&l2cap_rt_lock);
--
-- list_for_each(p, &l2cap_iff_list) {
-- struct l2cap_iff *iff;
--
-- iff = list_entry(p, struct l2cap_iff, list);
--
-- ptr += sprintf(ptr, " %s %p %p\n", iff->hdev->name, iff, iff->hdev);
--
-- l2cap_iff_lock(iff);
-- ptr += l2cap_conn_dump(ptr, iff);
-- l2cap_iff_unlock(iff);
-- }
--
-- write_unlock(&l2cap_rt_lock);
--
-- ptr += sprintf(ptr, "\n");
--
-- return ptr - buf;
--}
--
--static int l2cap_sock_dump(char *buf, struct bluez_sock_list *list)
--{
-- struct l2cap_pinfo *pi;
-- struct sock *sk;
-- char *ptr = buf;
--
-- ptr += sprintf(ptr, "Sockets:\n");
--
-- write_lock(&list->lock);
--
-- for (sk = list->head; sk; sk = sk->next) {
-- pi = l2cap_pi(sk);
-- ptr += sprintf(ptr, " %p %d %p %d %s %s 0x%4.4x 0x%4.4x %d %d\n", sk, sk->state, pi->conn, pi->psm,
-- batostr(&pi->src), batostr(&pi->dst), pi->scid, pi->dcid, pi->imtu, pi->omtu );
-- }
--
-- write_unlock(&list->lock);
--
-- ptr += sprintf(ptr, "\n");
--
-- return ptr - buf;
--}
--
--static int l2cap_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
--{
-- char *ptr = buf;
-- int len;
--
-- DBG("count %d, offset %ld", count, offset);
--
-- ptr += l2cap_iff_dump(ptr);
-- ptr += l2cap_sock_dump(ptr, &l2cap_sk_list);
-- len = ptr - buf;
--
-- if (len <= count + offset)
-- *eof = 1;
--
-- *start = buf + offset;
-- len -= offset;
--
-- if (len > count)
-- len = count;
-- if (len < 0)
-- len = 0;
--
-- return len;
--}
--
--void l2cap_register_proc(void)
--{
-- create_proc_read_entry("bluetooth/l2cap", 0, 0, l2cap_read_proc, NULL);
--}
--
--void l2cap_unregister_proc(void)
--{
-- remove_proc_entry("bluetooth/l2cap", NULL);
--}
-diff -urN linux-2.4.18/net/bluetooth/lib.c linux-2.4.18-mh15/net/bluetooth/lib.c
---- linux-2.4.18/net/bluetooth/lib.c 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/net/bluetooth/lib.c 2004-08-01 16:26:23.000000000 +0200
-@@ -25,7 +25,7 @@
- /*
- * BlueZ kernel library.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/kernel.h>
-@@ -105,7 +105,7 @@
- return EACCES;
-
- case 0x06:
-- return EINVAL;
-+ return EBADE;
-
- case 0x07:
- return ENOMEM;
-diff -urN linux-2.4.18/net/bluetooth/Makefile linux-2.4.18-mh15/net/bluetooth/Makefile
---- linux-2.4.18/net/bluetooth/Makefile 2001-06-12 04:15:27.000000000 +0200
-+++ linux-2.4.18-mh15/net/bluetooth/Makefile 2004-08-01 16:26:23.000000000 +0200
-@@ -1,20 +1,40 @@
- #
--# Makefile for the Bluetooth subsystem
-+# Makefile for the Linux Bluetooth subsystem
- #
--O_TARGET := bluetooth.o
-
--list-multi := hci.o l2cap.o
--export-objs := syms.o
--hci-objs := af_bluetooth.o hci_core.o hci_sock.o lib.o syms.o
--l2cap-objs := l2cap_core.o l2cap_proc.o
-+O_TARGET := bluetooth.o
-
--obj-$(CONFIG_BLUEZ) += hci.o
-+list-multi := bluez.o
-+export-objs := syms.o l2cap.o
-+
-+bluez-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o lib.o syms.o
-+
-+obj-$(CONFIG_BLUEZ) += bluez.o
- obj-$(CONFIG_BLUEZ_L2CAP) += l2cap.o
-+obj-$(CONFIG_BLUEZ_SCO) += sco.o
-
--include $(TOPDIR)/Rules.make
-+subdir-$(CONFIG_BLUEZ_RFCOMM) += rfcomm
-+subdir-$(CONFIG_BLUEZ_BNEP) += bnep
-+subdir-$(CONFIG_BLUEZ_CMTP) += cmtp
-+subdir-$(CONFIG_BLUEZ_HIDP) += hidp
-+
-+ifeq ($(CONFIG_BLUEZ_RFCOMM),y)
-+obj-y += rfcomm/rfcomm.o
-+endif
-
--hci.o: $(hci-objs)
-- $(LD) -r -o $@ $(hci-objs)
-+ifeq ($(CONFIG_BLUEZ_BNEP),y)
-+obj-y += bnep/bnep.o
-+endif
-+
-+ifeq ($(CONFIG_BLUEZ_CMTP),y)
-+obj-y += cmtp/cmtp.o
-+endif
-+
-+ifeq ($(CONFIG_BLUEZ_HIDP),y)
-+obj-y += hidp/hidp.o
-+endif
-+
-+include $(TOPDIR)/Rules.make
-
--l2cap.o: $(l2cap-objs)
-- $(LD) -r -o $@ $(l2cap-objs)
-+bluez.o: $(bluez-objs)
-+ $(LD) -r -o $@ $(bluez-objs)
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/Config.in linux-2.4.18-mh15/net/bluetooth/rfcomm/Config.in
---- linux-2.4.18/net/bluetooth/rfcomm/Config.in 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/rfcomm/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,10 @@
-+#
-+# Bluetooth RFCOMM layer configuration
-+#
-+
-+dep_tristate 'RFCOMM protocol support' CONFIG_BLUEZ_RFCOMM $CONFIG_BLUEZ_L2CAP
-+
-+if [ "$CONFIG_BLUEZ_RFCOMM" != "n" ]; then
-+ bool ' RFCOMM TTY support' CONFIG_BLUEZ_RFCOMM_TTY
-+fi
-+
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/core.c linux-2.4.18-mh15/net/bluetooth/rfcomm/core.c
---- linux-2.4.18/net/bluetooth/rfcomm/core.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/rfcomm/core.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,1940 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ RPN support - Dirk Husemann <hud@zurich.ibm.com>
-+*/
-+
-+/*
-+ * RFCOMM core.
-+ *
-+ * $Id$
-+ */
-+
-+#define __KERNEL_SYSCALLS__
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/signal.h>
-+#include <linux/init.h>
-+#include <linux/wait.h>
-+#include <linux/net.h>
-+#include <linux/proc_fs.h>
-+#include <net/sock.h>
-+#include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/l2cap.h>
-+#include <net/bluetooth/rfcomm.h>
-+
-+#define VERSION "1.1"
-+
-+#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+struct task_struct *rfcomm_thread;
-+DECLARE_MUTEX(rfcomm_sem);
-+unsigned long rfcomm_event;
-+
-+static LIST_HEAD(session_list);
-+static atomic_t terminate, running;
-+
-+static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len);
-+static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci);
-+static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci);
-+static int rfcomm_queue_disc(struct rfcomm_dlc *d);
-+static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type);
-+static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d);
-+static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig);
-+static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len);
-+static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits);
-+static void rfcomm_make_uih(struct sk_buff *skb, u8 addr);
-+
-+static void rfcomm_process_connect(struct rfcomm_session *s);
-+
-+/* ---- RFCOMM frame parsing macros ---- */
-+#define __get_dlci(b) ((b & 0xfc) >> 2)
-+#define __get_channel(b) ((b & 0xf8) >> 3)
-+#define __get_dir(b) ((b & 0x04) >> 2)
-+#define __get_type(b) ((b & 0xef))
-+
-+#define __test_ea(b) ((b & 0x01))
-+#define __test_cr(b) ((b & 0x02))
-+#define __test_pf(b) ((b & 0x10))
-+
-+#define __addr(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01)
-+#define __ctrl(type, pf) (((type & 0xef) | (pf << 4)))
-+#define __dlci(dir, chn) (((chn & 0x1f) << 1) | dir)
-+#define __srv_channel(dlci) (dlci >> 1)
-+#define __dir(dlci) (dlci & 0x01)
-+
-+#define __len8(len) (((len) << 1) | 1)
-+#define __len16(len) ((len) << 1)
-+
-+/* MCC macros */
-+#define __mcc_type(cr, type) (((type << 2) | (cr << 1) | 0x01))
-+#define __get_mcc_type(b) ((b & 0xfc) >> 2)
-+#define __get_mcc_len(b) ((b & 0xfe) >> 1)
-+
-+/* RPN macros */
-+#define __rpn_line_settings(data, stop, parity) ((data & 0x3) | ((stop & 0x1) << 2) | ((parity & 0x3) << 3))
-+#define __get_rpn_data_bits(line) ((line) & 0x3)
-+#define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1)
-+#define __get_rpn_parity(line) (((line) >> 3) & 0x3)
-+
-+/* ---- RFCOMM FCS computation ---- */
-+
-+/* CRC on 2 bytes */
-+#define __crc(data) (rfcomm_crc_table[rfcomm_crc_table[0xff ^ data[0]] ^ data[1]])
-+
-+/* FCS on 2 bytes */
-+static inline u8 __fcs(u8 *data)
-+{
-+ return (0xff - __crc(data));
-+}
-+
-+/* FCS on 3 bytes */
-+static inline u8 __fcs2(u8 *data)
-+{
-+ return (0xff - rfcomm_crc_table[__crc(data) ^ data[2]]);
-+}
-+
-+/* Check FCS */
-+static inline int __check_fcs(u8 *data, int type, u8 fcs)
-+{
-+ u8 f = __crc(data);
-+
-+ if (type != RFCOMM_UIH)
-+ f = rfcomm_crc_table[f ^ data[2]];
-+
-+ return rfcomm_crc_table[f ^ fcs] != 0xcf;
-+}
-+
-+/* ---- L2CAP callbacks ---- */
-+static void rfcomm_l2state_change(struct sock *sk)
-+{
-+ BT_DBG("%p state %d", sk, sk->state);
-+ rfcomm_schedule(RFCOMM_SCHED_STATE);
-+}
-+
-+static void rfcomm_l2data_ready(struct sock *sk, int bytes)
-+{
-+ BT_DBG("%p bytes %d", sk, bytes);
-+ rfcomm_schedule(RFCOMM_SCHED_RX);
-+}
-+
-+static int rfcomm_l2sock_create(struct socket **sock)
-+{
-+ int err;
-+
-+ BT_DBG("");
-+
-+ err = sock_create(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP, sock);
-+ if (!err) {
-+ struct sock *sk = (*sock)->sk;
-+ sk->data_ready = rfcomm_l2data_ready;
-+ sk->state_change = rfcomm_l2state_change;
-+ }
-+ return err;
-+}
-+
-+/* ---- RFCOMM DLCs ---- */
-+static void rfcomm_dlc_timeout(unsigned long arg)
-+{
-+ struct rfcomm_dlc *d = (void *) arg;
-+
-+ BT_DBG("dlc %p state %ld", d, d->state);
-+
-+ set_bit(RFCOMM_TIMED_OUT, &d->flags);
-+ rfcomm_dlc_put(d);
-+ rfcomm_schedule(RFCOMM_SCHED_TIMEO);
-+}
-+
-+static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout)
-+{
-+ BT_DBG("dlc %p state %ld timeout %ld", d, d->state, timeout);
-+
-+ if (!mod_timer(&d->timer, jiffies + timeout))
-+ rfcomm_dlc_hold(d);
-+}
-+
-+static void rfcomm_dlc_clear_timer(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("dlc %p state %ld", d, d->state);
-+
-+ if (timer_pending(&d->timer) && del_timer(&d->timer))
-+ rfcomm_dlc_put(d);
-+}
-+
-+static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("%p", d);
-+
-+ d->state = BT_OPEN;
-+ d->flags = 0;
-+ d->mscex = 0;
-+ d->mtu = RFCOMM_DEFAULT_MTU;
-+ d->v24_sig = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV;
-+
-+ d->cfc = RFCOMM_CFC_DISABLED;
-+ d->rx_credits = RFCOMM_DEFAULT_CREDITS;
-+}
-+
-+struct rfcomm_dlc *rfcomm_dlc_alloc(int prio)
-+{
-+ struct rfcomm_dlc *d = kmalloc(sizeof(*d), prio);
-+ if (!d)
-+ return NULL;
-+ memset(d, 0, sizeof(*d));
-+
-+ init_timer(&d->timer);
-+ d->timer.function = rfcomm_dlc_timeout;
-+ d->timer.data = (unsigned long) d;
-+
-+ skb_queue_head_init(&d->tx_queue);
-+ spin_lock_init(&d->lock);
-+ atomic_set(&d->refcnt, 1);
-+
-+ rfcomm_dlc_clear_state(d);
-+
-+ BT_DBG("%p", d);
-+ return d;
-+}
-+
-+void rfcomm_dlc_free(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("%p", d);
-+
-+ skb_queue_purge(&d->tx_queue);
-+ kfree(d);
-+}
-+
-+static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d)
-+{
-+ BT_DBG("dlc %p session %p", d, s);
-+
-+ rfcomm_session_hold(s);
-+
-+ rfcomm_dlc_hold(d);
-+ list_add(&d->list, &s->dlcs);
-+ d->session = s;
-+}
-+
-+static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
-+{
-+ struct rfcomm_session *s = d->session;
-+
-+ BT_DBG("dlc %p refcnt %d session %p", d, atomic_read(&d->refcnt), s);
-+
-+ list_del(&d->list);
-+ d->session = NULL;
-+ rfcomm_dlc_put(d);
-+
-+ rfcomm_session_put(s);
-+}
-+
-+static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_dlc *d;
-+ struct list_head *p;
-+
-+ list_for_each(p, &s->dlcs) {
-+ d = list_entry(p, struct rfcomm_dlc, list);
-+ if (d->dlci == dlci)
-+ return d;
-+ }
-+ return NULL;
-+}
-+
-+static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
-+{
-+ struct rfcomm_session *s;
-+ int err = 0;
-+ u8 dlci;
-+
-+ BT_DBG("dlc %p state %ld %s %s channel %d",
-+ d, d->state, batostr(src), batostr(dst), channel);
-+
-+ if (channel < 1 || channel > 30)
-+ return -EINVAL;
-+
-+ if (d->state != BT_OPEN && d->state != BT_CLOSED)
-+ return 0;
-+
-+ s = rfcomm_session_get(src, dst);
-+ if (!s) {
-+ s = rfcomm_session_create(src, dst, &err);
-+ if (!s)
-+ return err;
-+ }
-+
-+ dlci = __dlci(!s->initiator, channel);
-+
-+ /* Check if DLCI already exists */
-+ if (rfcomm_dlc_get(s, dlci))
-+ return -EBUSY;
-+
-+ rfcomm_dlc_clear_state(d);
-+
-+ d->dlci = dlci;
-+ d->addr = __addr(s->initiator, dlci);
-+ d->priority = 7;
-+
-+ d->state = BT_CONFIG;
-+ rfcomm_dlc_link(s, d);
-+
-+ d->mtu = s->mtu;
-+ d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc;
-+
-+ if (s->state == BT_CONNECTED)
-+ rfcomm_send_pn(s, 1, d);
-+ rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT);
-+ return 0;
-+}
-+
-+int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
-+{
-+ mm_segment_t fs;
-+ int r;
-+
-+ rfcomm_lock();
-+
-+ fs = get_fs(); set_fs(KERNEL_DS);
-+ r = __rfcomm_dlc_open(d, src, dst, channel);
-+ set_fs(fs);
-+
-+ rfcomm_unlock();
-+ return r;
-+}
-+
-+static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
-+{
-+ struct rfcomm_session *s = d->session;
-+ if (!s)
-+ return 0;
-+
-+ BT_DBG("dlc %p state %ld dlci %d err %d session %p",
-+ d, d->state, d->dlci, err, s);
-+
-+ switch (d->state) {
-+ case BT_CONNECTED:
-+ case BT_CONFIG:
-+ case BT_CONNECT:
-+ d->state = BT_DISCONN;
-+ if (skb_queue_empty(&d->tx_queue)) {
-+ rfcomm_send_disc(s, d->dlci);
-+ rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT);
-+ } else {
-+ rfcomm_queue_disc(d);
-+ rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT * 2);
-+ }
-+ break;
-+
-+ default:
-+ rfcomm_dlc_clear_timer(d);
-+
-+ rfcomm_dlc_lock(d);
-+ d->state = BT_CLOSED;
-+ d->state_change(d, err);
-+ rfcomm_dlc_unlock(d);
-+
-+ skb_queue_purge(&d->tx_queue);
-+ rfcomm_dlc_unlink(d);
-+ }
-+
-+ return 0;
-+}
-+
-+int rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
-+{
-+ mm_segment_t fs;
-+ int r;
-+
-+ rfcomm_lock();
-+
-+ fs = get_fs(); set_fs(KERNEL_DS);
-+ r = __rfcomm_dlc_close(d, err);
-+ set_fs(fs);
-+
-+ rfcomm_unlock();
-+ return r;
-+}
-+
-+int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
-+{
-+ int len = skb->len;
-+
-+ if (d->state != BT_CONNECTED)
-+ return -ENOTCONN;
-+
-+ BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len);
-+
-+ if (len > d->mtu)
-+ return -EINVAL;
-+
-+ rfcomm_make_uih(skb, d->addr);
-+ skb_queue_tail(&d->tx_queue, skb);
-+
-+ if (!test_bit(RFCOMM_TX_THROTTLED, &d->flags))
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+ return len;
-+}
-+
-+void __rfcomm_dlc_throttle(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("dlc %p state %ld", d, d->state);
-+
-+ if (!d->cfc) {
-+ d->v24_sig |= RFCOMM_V24_FC;
-+ set_bit(RFCOMM_MSC_PENDING, &d->flags);
-+ }
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+}
-+
-+void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("dlc %p state %ld", d, d->state);
-+
-+ if (!d->cfc) {
-+ d->v24_sig &= ~RFCOMM_V24_FC;
-+ set_bit(RFCOMM_MSC_PENDING, &d->flags);
-+ }
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+}
-+
-+/*
-+ Set/get modem status functions use _local_ status i.e. what we report
-+ to the other side.
-+ Remote status is provided by dlc->modem_status() callback.
-+ */
-+int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig)
-+{
-+ BT_DBG("dlc %p state %ld v24_sig 0x%x",
-+ d, d->state, v24_sig);
-+
-+ if (test_bit(RFCOMM_RX_THROTTLED, &d->flags))
-+ v24_sig |= RFCOMM_V24_FC;
-+ else
-+ v24_sig &= ~RFCOMM_V24_FC;
-+
-+ d->v24_sig = v24_sig;
-+
-+ if (!test_and_set_bit(RFCOMM_MSC_PENDING, &d->flags))
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+
-+ return 0;
-+}
-+
-+int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig)
-+{
-+ BT_DBG("dlc %p state %ld v24_sig 0x%x",
-+ d, d->state, d->v24_sig);
-+
-+ *v24_sig = d->v24_sig;
-+ return 0;
-+}
-+
-+/* ---- RFCOMM sessions ---- */
-+struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
-+{
-+ struct rfcomm_session *s = kmalloc(sizeof(*s), GFP_KERNEL);
-+ if (!s)
-+ return NULL;
-+ memset(s, 0, sizeof(*s));
-+
-+ BT_DBG("session %p sock %p", s, sock);
-+
-+ INIT_LIST_HEAD(&s->dlcs);
-+ s->state = state;
-+ s->sock = sock;
-+
-+ s->mtu = RFCOMM_DEFAULT_MTU;
-+ s->cfc = RFCOMM_CFC_UNKNOWN;
-+
-+ list_add(&s->list, &session_list);
-+
-+ /* Do not increment module usage count for listeting sessions.
-+ * Otherwise we won't be able to unload the module. */
-+ if (state != BT_LISTEN)
-+ MOD_INC_USE_COUNT;
-+ return s;
-+}
-+
-+void rfcomm_session_del(struct rfcomm_session *s)
-+{
-+ int state = s->state;
-+
-+ BT_DBG("session %p state %ld", s, s->state);
-+
-+ list_del(&s->list);
-+
-+ if (state == BT_CONNECTED)
-+ rfcomm_send_disc(s, 0);
-+
-+ sock_release(s->sock);
-+ kfree(s);
-+
-+ if (state != BT_LISTEN)
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
-+{
-+ struct rfcomm_session *s;
-+ struct list_head *p, *n;
-+ struct bluez_pinfo *pi;
-+ list_for_each_safe(p, n, &session_list) {
-+ s = list_entry(p, struct rfcomm_session, list);
-+ pi = bluez_pi(s->sock->sk);
-+
-+ if ((!bacmp(src, BDADDR_ANY) || !bacmp(&pi->src, src)) &&
-+ !bacmp(&pi->dst, dst))
-+ return s;
-+ }
-+ return NULL;
-+}
-+
-+void rfcomm_session_close(struct rfcomm_session *s, int err)
-+{
-+ struct rfcomm_dlc *d;
-+ struct list_head *p, *n;
-+
-+ BT_DBG("session %p state %ld err %d", s, s->state, err);
-+
-+ rfcomm_session_hold(s);
-+
-+ s->state = BT_CLOSED;
-+
-+ /* Close all dlcs */
-+ list_for_each_safe(p, n, &s->dlcs) {
-+ d = list_entry(p, struct rfcomm_dlc, list);
-+ d->state = BT_CLOSED;
-+ __rfcomm_dlc_close(d, err);
-+ }
-+
-+ rfcomm_session_put(s);
-+}
-+
-+struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err)
-+{
-+ struct rfcomm_session *s = NULL;
-+ struct sockaddr_l2 addr;
-+ struct l2cap_options opts;
-+ struct socket *sock;
-+ int size;
-+
-+ BT_DBG("%s %s", batostr(src), batostr(dst));
-+
-+ *err = rfcomm_l2sock_create(&sock);
-+ if (*err < 0)
-+ return NULL;
-+
-+ bacpy(&addr.l2_bdaddr, src);
-+ addr.l2_family = AF_BLUETOOTH;
-+ addr.l2_psm = 0;
-+ *err = sock->ops->bind(sock, (struct sockaddr *) &addr, sizeof(addr));
-+ if (*err < 0)
-+ goto failed;
-+
-+ /* Set L2CAP options */
-+ size = sizeof(opts);
-+ sock->ops->getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, &size);
-+
-+ opts.imtu = RFCOMM_MAX_L2CAP_MTU;
-+ sock->ops->setsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, size);
-+
-+ s = rfcomm_session_add(sock, BT_BOUND);
-+ if (!s) {
-+ *err = -ENOMEM;
-+ goto failed;
-+ }
-+
-+ s->initiator = 1;
-+
-+ bacpy(&addr.l2_bdaddr, dst);
-+ addr.l2_family = AF_BLUETOOTH;
-+ addr.l2_psm = htobs(RFCOMM_PSM);
-+ *err = sock->ops->connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
-+ if (*err == 0 || *err == -EAGAIN)
-+ return s;
-+
-+ rfcomm_session_del(s);
-+ return NULL;
-+
-+failed:
-+ sock_release(sock);
-+ return NULL;
-+}
-+
-+void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst)
-+{
-+ struct sock *sk = s->sock->sk;
-+ if (src)
-+ bacpy(src, &bluez_pi(sk)->src);
-+ if (dst)
-+ bacpy(dst, &bluez_pi(sk)->dst);
-+}
-+
-+/* ---- RFCOMM frame sending ---- */
-+static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len)
-+{
-+ struct socket *sock = s->sock;
-+ struct iovec iv = { data, len };
-+ struct msghdr msg;
-+ int err;
-+
-+ BT_DBG("session %p len %d", s, len);
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_iovlen = 1;
-+ msg.msg_iov = &iv;
-+
-+ err = sock->ops->sendmsg(sock, &msg, len, 0);
-+ return err;
-+}
-+
-+static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_cmd cmd;
-+
-+ BT_DBG("%p dlci %d", s, dlci);
-+
-+ cmd.addr = __addr(s->initiator, dlci);
-+ cmd.ctrl = __ctrl(RFCOMM_SABM, 1);
-+ cmd.len = __len8(0);
-+ cmd.fcs = __fcs2((u8 *) &cmd);
-+
-+ return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
-+}
-+
-+static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_cmd cmd;
-+
-+ BT_DBG("%p dlci %d", s, dlci);
-+
-+ cmd.addr = __addr(!s->initiator, dlci);
-+ cmd.ctrl = __ctrl(RFCOMM_UA, 1);
-+ cmd.len = __len8(0);
-+ cmd.fcs = __fcs2((u8 *) &cmd);
-+
-+ return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
-+}
-+
-+static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_cmd cmd;
-+
-+ BT_DBG("%p dlci %d", s, dlci);
-+
-+ cmd.addr = __addr(s->initiator, dlci);
-+ cmd.ctrl = __ctrl(RFCOMM_DISC, 1);
-+ cmd.len = __len8(0);
-+ cmd.fcs = __fcs2((u8 *) &cmd);
-+
-+ return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
-+}
-+
-+static int rfcomm_queue_disc(struct rfcomm_dlc *d)
-+{
-+ struct rfcomm_cmd *cmd;
-+ struct sk_buff *skb;
-+
-+ BT_DBG("dlc %p dlci %d", d, d->dlci);
-+
-+ skb = alloc_skb(sizeof(*cmd), GFP_KERNEL);
-+ if (!skb)
-+ return -ENOMEM;
-+
-+ cmd = (void *) __skb_put(skb, sizeof(*cmd));
-+ cmd->addr = d->addr;
-+ cmd->ctrl = __ctrl(RFCOMM_DISC, 1);
-+ cmd->len = __len8(0);
-+ cmd->fcs = __fcs2((u8 *) cmd);
-+
-+ skb_queue_tail(&d->tx_queue, skb);
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+ return 0;
-+}
-+
-+static int rfcomm_send_dm(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_cmd cmd;
-+
-+ BT_DBG("%p dlci %d", s, dlci);
-+
-+ cmd.addr = __addr(!s->initiator, dlci);
-+ cmd.ctrl = __ctrl(RFCOMM_DM, 1);
-+ cmd.len = __len8(0);
-+ cmd.fcs = __fcs2((u8 *) &cmd);
-+
-+ return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
-+}
-+
-+static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d type %d", s, cr, type);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + 1);
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_NSC);
-+ mcc->len = __len8(1);
-+
-+ /* Type that we didn't like */
-+ *ptr = __mcc_type(cr, type); ptr++;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ struct rfcomm_pn *pn;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d dlci %d mtu %d", s, cr, d->dlci, d->mtu);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + sizeof(*pn));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_PN);
-+ mcc->len = __len8(sizeof(*pn));
-+
-+ pn = (void *) ptr; ptr += sizeof(*pn);
-+ pn->dlci = d->dlci;
-+ pn->priority = d->priority;
-+ pn->ack_timer = 0;
-+ pn->max_retrans = 0;
-+
-+ if (s->cfc) {
-+ pn->flow_ctrl = cr ? 0xf0 : 0xe0;
-+ pn->credits = RFCOMM_DEFAULT_CREDITS;
-+ } else {
-+ pn->flow_ctrl = 0;
-+ pn->credits = 0;
-+ }
-+
-+ pn->mtu = htobs(d->mtu);
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,
-+ u8 bit_rate, u8 data_bits, u8 stop_bits,
-+ u8 parity, u8 flow_ctrl_settings,
-+ u8 xon_char, u8 xoff_char, u16 param_mask)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ struct rfcomm_rpn *rpn;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d dlci %d bit_r 0x%x data_b 0x%x stop_b 0x%x parity 0x%x"
-+ "flwc_s 0x%x xon_c 0x%x xoff_c 0x%x p_mask 0x%x",
-+ s, cr, dlci, bit_rate, data_bits, stop_bits, parity,
-+ flow_ctrl_settings, xon_char, xoff_char, param_mask);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + sizeof(*rpn));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_RPN);
-+ mcc->len = __len8(sizeof(*rpn));
-+
-+ rpn = (void *) ptr; ptr += sizeof(*rpn);
-+ rpn->dlci = __addr(1, dlci);
-+ rpn->bit_rate = bit_rate;
-+ rpn->line_settings = __rpn_line_settings(data_bits, stop_bits, parity);
-+ rpn->flow_ctrl = flow_ctrl_settings;
-+ rpn->xon_char = xon_char;
-+ rpn->xoff_char = xoff_char;
-+ rpn->param_mask = param_mask;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ struct rfcomm_rls *rls;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d status 0x%x", s, cr, status);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + sizeof(*rls));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_RLS);
-+ mcc->len = __len8(sizeof(*rls));
-+
-+ rls = (void *) ptr; ptr += sizeof(*rls);
-+ rls->dlci = __addr(1, dlci);
-+ rls->status = status;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ struct rfcomm_msc *msc;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d v24 0x%x", s, cr, v24_sig);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + sizeof(*msc));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_MSC);
-+ mcc->len = __len8(sizeof(*msc));
-+
-+ msc = (void *) ptr; ptr += sizeof(*msc);
-+ msc->dlci = __addr(1, dlci);
-+ msc->v24_sig = v24_sig | 0x01;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d", s, cr);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_FCOFF);
-+ mcc->len = __len8(0);
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_fcon(struct rfcomm_session *s, int cr)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d", s, cr);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_FCON);
-+ mcc->len = __len8(0);
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len)
-+{
-+ struct socket *sock = s->sock;
-+ struct iovec iv[3];
-+ struct msghdr msg;
-+ unsigned char hdr[5], crc[1];
-+
-+ if (len > 125)
-+ return -EINVAL;
-+
-+ BT_DBG("%p cr %d", s, cr);
-+
-+ hdr[0] = __addr(s->initiator, 0);
-+ hdr[1] = __ctrl(RFCOMM_UIH, 0);
-+ hdr[2] = 0x01 | ((len + 2) << 1);
-+ hdr[3] = 0x01 | ((cr & 0x01) << 1) | (RFCOMM_TEST << 2);
-+ hdr[4] = 0x01 | (len << 1);
-+
-+ crc[0] = __fcs(hdr);
-+
-+ iv[0].iov_base = hdr;
-+ iv[0].iov_len = 5;
-+ iv[1].iov_base = pattern;
-+ iv[1].iov_len = len;
-+ iv[2].iov_base = crc;
-+ iv[2].iov_len = 1;
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_iovlen = 3;
-+ msg.msg_iov = iv;
-+ return sock->ops->sendmsg(sock, &msg, 6 + len, 0);
-+}
-+
-+static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits)
-+{
-+ struct rfcomm_hdr *hdr;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p addr %d credits %d", s, addr, credits);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = addr;
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 1);
-+ hdr->len = __len8(0);
-+
-+ *ptr = credits; ptr++;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
-+{
-+ struct rfcomm_hdr *hdr;
-+ int len = skb->len;
-+ u8 *crc;
-+
-+ if (len > 127) {
-+ hdr = (void *) skb_push(skb, 4);
-+ put_unaligned(htobs(__len16(len)), (u16 *) &hdr->len);
-+ } else {
-+ hdr = (void *) skb_push(skb, 3);
-+ hdr->len = __len8(len);
-+ }
-+ hdr->addr = addr;
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+
-+ crc = skb_put(skb, 1);
-+ *crc = __fcs((void *) hdr);
-+}
-+
-+/* ---- RFCOMM frame reception ---- */
-+static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
-+{
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (dlci) {
-+ /* Data channel */
-+ struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
-+ if (!d) {
-+ rfcomm_send_dm(s, dlci);
-+ return 0;
-+ }
-+
-+ switch (d->state) {
-+ case BT_CONNECT:
-+ rfcomm_dlc_clear_timer(d);
-+
-+ rfcomm_dlc_lock(d);
-+ d->state = BT_CONNECTED;
-+ d->state_change(d, 0);
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_send_msc(s, 1, dlci, d->v24_sig);
-+ break;
-+
-+ case BT_DISCONN:
-+ d->state = BT_CLOSED;
-+ __rfcomm_dlc_close(d, 0);
-+ break;
-+ }
-+ } else {
-+ /* Control channel */
-+ switch (s->state) {
-+ case BT_CONNECT:
-+ s->state = BT_CONNECTED;
-+ rfcomm_process_connect(s);
-+ break;
-+ }
-+ }
-+ return 0;
-+}
-+
-+static int rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci)
-+{
-+ int err = 0;
-+
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (dlci) {
-+ /* Data DLC */
-+ struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
-+ if (d) {
-+ if (d->state == BT_CONNECT || d->state == BT_CONFIG)
-+ err = ECONNREFUSED;
-+ else
-+ err = ECONNRESET;
-+
-+ d->state = BT_CLOSED;
-+ __rfcomm_dlc_close(d, err);
-+ }
-+ } else {
-+ if (s->state == BT_CONNECT)
-+ err = ECONNREFUSED;
-+ else
-+ err = ECONNRESET;
-+
-+ s->state = BT_CLOSED;
-+ rfcomm_session_close(s, err);
-+ }
-+ return 0;
-+}
-+
-+static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
-+{
-+ int err = 0;
-+
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (dlci) {
-+ struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
-+ if (d) {
-+ rfcomm_send_ua(s, dlci);
-+
-+ if (d->state == BT_CONNECT || d->state == BT_CONFIG)
-+ err = ECONNREFUSED;
-+ else
-+ err = ECONNRESET;
-+
-+ d->state = BT_CLOSED;
-+ __rfcomm_dlc_close(d, err);
-+ } else
-+ rfcomm_send_dm(s, dlci);
-+
-+ } else {
-+ rfcomm_send_ua(s, 0);
-+
-+ if (s->state == BT_CONNECT)
-+ err = ECONNREFUSED;
-+ else
-+ err = ECONNRESET;
-+
-+ s->state = BT_CLOSED;
-+ rfcomm_session_close(s, err);
-+ }
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_dlc *d;
-+ u8 channel;
-+
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (!dlci) {
-+ rfcomm_send_ua(s, 0);
-+
-+ if (s->state == BT_OPEN) {
-+ s->state = BT_CONNECTED;
-+ rfcomm_process_connect(s);
-+ }
-+ return 0;
-+ }
-+
-+ /* Check if DLC exists */
-+ d = rfcomm_dlc_get(s, dlci);
-+ if (d) {
-+ if (d->state == BT_OPEN) {
-+ /* DLC was previously opened by PN request */
-+ rfcomm_send_ua(s, dlci);
-+
-+ rfcomm_dlc_lock(d);
-+ d->state = BT_CONNECTED;
-+ d->state_change(d, 0);
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_send_msc(s, 1, dlci, d->v24_sig);
-+ }
-+ return 0;
-+ }
-+
-+ /* Notify socket layer about incomming connection */
-+ channel = __srv_channel(dlci);
-+ if (rfcomm_connect_ind(s, channel, &d)) {
-+ d->dlci = dlci;
-+ d->addr = __addr(s->initiator, dlci);
-+ rfcomm_dlc_link(s, d);
-+
-+ rfcomm_send_ua(s, dlci);
-+
-+ rfcomm_dlc_lock(d);
-+ d->state = BT_CONNECTED;
-+ d->state_change(d, 0);
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_send_msc(s, 1, dlci, d->v24_sig);
-+ } else {
-+ rfcomm_send_dm(s, dlci);
-+ }
-+
-+ return 0;
-+}
-+
-+static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
-+{
-+ struct rfcomm_session *s = d->session;
-+
-+ BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d",
-+ d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits);
-+
-+ if (pn->flow_ctrl == 0xf0 || pn->flow_ctrl == 0xe0) {
-+ d->cfc = s->cfc = RFCOMM_CFC_ENABLED;
-+ d->tx_credits = pn->credits;
-+ } else {
-+ d->cfc = s->cfc = RFCOMM_CFC_DISABLED;
-+ set_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+ }
-+
-+ d->priority = pn->priority;
-+
-+ d->mtu = s->mtu = btohs(pn->mtu);
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb)
-+{
-+ struct rfcomm_pn *pn = (void *) skb->data;
-+ struct rfcomm_dlc *d;
-+ u8 dlci = pn->dlci;
-+
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (!dlci)
-+ return 0;
-+
-+ d = rfcomm_dlc_get(s, dlci);
-+ if (d) {
-+ if (cr) {
-+ /* PN request */
-+ rfcomm_apply_pn(d, cr, pn);
-+ rfcomm_send_pn(s, 0, d);
-+ } else {
-+ /* PN response */
-+ switch (d->state) {
-+ case BT_CONFIG:
-+ rfcomm_apply_pn(d, cr, pn);
-+
-+ d->state = BT_CONNECT;
-+ rfcomm_send_sabm(s, d->dlci);
-+ break;
-+ }
-+ }
-+ } else {
-+ u8 channel = __srv_channel(dlci);
-+
-+ if (!cr)
-+ return 0;
-+
-+ /* PN request for non existing DLC.
-+ * Assume incomming connection. */
-+ if (rfcomm_connect_ind(s, channel, &d)) {
-+ d->dlci = dlci;
-+ d->addr = __addr(s->initiator, dlci);
-+ rfcomm_dlc_link(s, d);
-+
-+ rfcomm_apply_pn(d, cr, pn);
-+
-+ d->state = BT_OPEN;
-+ rfcomm_send_pn(s, 0, d);
-+ } else {
-+ rfcomm_send_dm(s, dlci);
-+ }
-+ }
-+ return 0;
-+}
-+
-+static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_buff *skb)
-+{
-+ struct rfcomm_rpn *rpn = (void *) skb->data;
-+ u8 dlci = __get_dlci(rpn->dlci);
-+
-+ u8 bit_rate = 0;
-+ u8 data_bits = 0;
-+ u8 stop_bits = 0;
-+ u8 parity = 0;
-+ u8 flow_ctrl = 0;
-+ u8 xon_char = 0;
-+ u8 xoff_char = 0;
-+ u16 rpn_mask = RFCOMM_RPN_PM_ALL;
-+
-+ BT_DBG("dlci %d cr %d len 0x%x bitr 0x%x line 0x%x flow 0x%x xonc 0x%x xoffc 0x%x pm 0x%x",
-+ dlci, cr, len, rpn->bit_rate, rpn->line_settings, rpn->flow_ctrl,
-+ rpn->xon_char, rpn->xoff_char, rpn->param_mask);
-+
-+ if (!cr)
-+ return 0;
-+
-+ if (len == 1) {
-+ /* request: return default setting */
-+ bit_rate = RFCOMM_RPN_BR_115200;
-+ data_bits = RFCOMM_RPN_DATA_8;
-+ stop_bits = RFCOMM_RPN_STOP_1;
-+ parity = RFCOMM_RPN_PARITY_NONE;
-+ flow_ctrl = RFCOMM_RPN_FLOW_NONE;
-+ xon_char = RFCOMM_RPN_XON_CHAR;
-+ xoff_char = RFCOMM_RPN_XOFF_CHAR;
-+
-+ goto rpn_out;
-+ }
-+ /* check for sane values: ignore/accept bit_rate, 8 bits, 1 stop bit, no parity,
-+ no flow control lines, normal XON/XOFF chars */
-+ if (rpn->param_mask & RFCOMM_RPN_PM_BITRATE) {
-+ bit_rate = rpn->bit_rate;
-+ if (bit_rate != RFCOMM_RPN_BR_115200) {
-+ BT_DBG("RPN bit rate mismatch 0x%x", bit_rate);
-+ bit_rate = RFCOMM_RPN_BR_115200;
-+ rpn_mask ^= RFCOMM_RPN_PM_BITRATE;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_DATA) {
-+ data_bits = __get_rpn_data_bits(rpn->line_settings);
-+ if (data_bits != RFCOMM_RPN_DATA_8) {
-+ BT_DBG("RPN data bits mismatch 0x%x", data_bits);
-+ data_bits = RFCOMM_RPN_DATA_8;
-+ rpn_mask ^= RFCOMM_RPN_PM_DATA;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_STOP) {
-+ stop_bits = __get_rpn_stop_bits(rpn->line_settings);
-+ if (stop_bits != RFCOMM_RPN_STOP_1) {
-+ BT_DBG("RPN stop bits mismatch 0x%x", stop_bits);
-+ stop_bits = RFCOMM_RPN_STOP_1;
-+ rpn_mask ^= RFCOMM_RPN_PM_STOP;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_PARITY) {
-+ parity = __get_rpn_parity(rpn->line_settings);
-+ if (parity != RFCOMM_RPN_PARITY_NONE) {
-+ BT_DBG("RPN parity mismatch 0x%x", parity);
-+ parity = RFCOMM_RPN_PARITY_NONE;
-+ rpn_mask ^= RFCOMM_RPN_PM_PARITY;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_FLOW) {
-+ flow_ctrl = rpn->flow_ctrl;
-+ if (flow_ctrl != RFCOMM_RPN_FLOW_NONE) {
-+ BT_DBG("RPN flow ctrl mismatch 0x%x", flow_ctrl);
-+ flow_ctrl = RFCOMM_RPN_FLOW_NONE;
-+ rpn_mask ^= RFCOMM_RPN_PM_FLOW;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_XON) {
-+ xon_char = rpn->xon_char;
-+ if (xon_char != RFCOMM_RPN_XON_CHAR) {
-+ BT_DBG("RPN XON char mismatch 0x%x", xon_char);
-+ xon_char = RFCOMM_RPN_XON_CHAR;
-+ rpn_mask ^= RFCOMM_RPN_PM_XON;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_XOFF) {
-+ xoff_char = rpn->xoff_char;
-+ if (xoff_char != RFCOMM_RPN_XOFF_CHAR) {
-+ BT_DBG("RPN XOFF char mismatch 0x%x", xoff_char);
-+ xoff_char = RFCOMM_RPN_XOFF_CHAR;
-+ rpn_mask ^= RFCOMM_RPN_PM_XOFF;
-+ }
-+ }
-+
-+rpn_out:
-+ rfcomm_send_rpn(s, 0, dlci,
-+ bit_rate, data_bits, stop_bits, parity, flow_ctrl,
-+ xon_char, xoff_char, rpn_mask);
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_rls(struct rfcomm_session *s, int cr, struct sk_buff *skb)
-+{
-+ struct rfcomm_rls *rls = (void *) skb->data;
-+ u8 dlci = __get_dlci(rls->dlci);
-+
-+ BT_DBG("dlci %d cr %d status 0x%x", dlci, cr, rls->status);
-+
-+ if (!cr)
-+ return 0;
-+
-+ /* FIXME: We should probably do something with this
-+ information here. But for now it's sufficient just
-+ to reply -- Bluetooth 1.1 says it's mandatory to
-+ recognise and respond to RLS */
-+
-+ rfcomm_send_rls(s, 0, dlci, rls->status);
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_msc(struct rfcomm_session *s, int cr, struct sk_buff *skb)
-+{
-+ struct rfcomm_msc *msc = (void *) skb->data;
-+ struct rfcomm_dlc *d;
-+ u8 dlci = __get_dlci(msc->dlci);
-+
-+ BT_DBG("dlci %d cr %d v24 0x%x", dlci, cr, msc->v24_sig);
-+
-+ d = rfcomm_dlc_get(s, dlci);
-+ if (!d)
-+ return 0;
-+
-+ if (cr) {
-+ if (msc->v24_sig & RFCOMM_V24_FC && !d->cfc)
-+ set_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+ else
-+ clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+
-+ rfcomm_dlc_lock(d);
-+ if (d->modem_status)
-+ d->modem_status(d, msc->v24_sig);
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_send_msc(s, 0, dlci, msc->v24_sig);
-+
-+ d->mscex |= RFCOMM_MSCEX_RX;
-+ } else
-+ d->mscex |= RFCOMM_MSCEX_TX;
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb)
-+{
-+ struct rfcomm_mcc *mcc = (void *) skb->data;
-+ u8 type, cr, len;
-+
-+ cr = __test_cr(mcc->type);
-+ type = __get_mcc_type(mcc->type);
-+ len = __get_mcc_len(mcc->len);
-+
-+ BT_DBG("%p type 0x%x cr %d", s, type, cr);
-+
-+ skb_pull(skb, 2);
-+
-+ switch (type) {
-+ case RFCOMM_PN:
-+ rfcomm_recv_pn(s, cr, skb);
-+ break;
-+
-+ case RFCOMM_RPN:
-+ rfcomm_recv_rpn(s, cr, len, skb);
-+ break;
-+
-+ case RFCOMM_RLS:
-+ rfcomm_recv_rls(s, cr, skb);
-+ break;
-+
-+ case RFCOMM_MSC:
-+ rfcomm_recv_msc(s, cr, skb);
-+ break;
-+
-+ case RFCOMM_FCOFF:
-+ if (cr) {
-+ set_bit(RFCOMM_TX_THROTTLED, &s->flags);
-+ rfcomm_send_fcoff(s, 0);
-+ }
-+ break;
-+
-+ case RFCOMM_FCON:
-+ if (cr) {
-+ clear_bit(RFCOMM_TX_THROTTLED, &s->flags);
-+ rfcomm_send_fcon(s, 0);
-+ }
-+ break;
-+
-+ case RFCOMM_TEST:
-+ if (cr)
-+ rfcomm_send_test(s, 0, skb->data, skb->len);
-+ break;
-+
-+ case RFCOMM_NSC:
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown control type 0x%02x", type);
-+ rfcomm_send_nsc(s, cr, type);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static int rfcomm_recv_data(struct rfcomm_session *s, u8 dlci, int pf, struct sk_buff *skb)
-+{
-+ struct rfcomm_dlc *d;
-+
-+ BT_DBG("session %p state %ld dlci %d pf %d", s, s->state, dlci, pf);
-+
-+ d = rfcomm_dlc_get(s, dlci);
-+ if (!d) {
-+ rfcomm_send_dm(s, dlci);
-+ goto drop;
-+ }
-+
-+ if (pf && d->cfc) {
-+ u8 credits = *(u8 *) skb->data; skb_pull(skb, 1);
-+
-+ d->tx_credits += credits;
-+ if (d->tx_credits)
-+ clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+ }
-+
-+ if (skb->len && d->state == BT_CONNECTED) {
-+ rfcomm_dlc_lock(d);
-+ d->rx_credits--;
-+ d->data_ready(d, skb);
-+ rfcomm_dlc_unlock(d);
-+ return 0;
-+ }
-+
-+drop:
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
-+{
-+ struct rfcomm_hdr *hdr = (void *) skb->data;
-+ u8 type, dlci, fcs;
-+
-+ dlci = __get_dlci(hdr->addr);
-+ type = __get_type(hdr->ctrl);
-+
-+ /* Trim FCS */
-+ skb->len--; skb->tail--;
-+ fcs = *(u8 *) skb->tail;
-+
-+ if (__check_fcs(skb->data, type, fcs)) {
-+ BT_ERR("bad checksum in packet");
-+ kfree_skb(skb);
-+ return -EILSEQ;
-+ }
-+
-+ if (__test_ea(hdr->len))
-+ skb_pull(skb, 3);
-+ else
-+ skb_pull(skb, 4);
-+
-+ switch (type) {
-+ case RFCOMM_SABM:
-+ if (__test_pf(hdr->ctrl))
-+ rfcomm_recv_sabm(s, dlci);
-+ break;
-+
-+ case RFCOMM_DISC:
-+ if (__test_pf(hdr->ctrl))
-+ rfcomm_recv_disc(s, dlci);
-+ break;
-+
-+ case RFCOMM_UA:
-+ if (__test_pf(hdr->ctrl))
-+ rfcomm_recv_ua(s, dlci);
-+ break;
-+
-+ case RFCOMM_DM:
-+ rfcomm_recv_dm(s, dlci);
-+ break;
-+
-+ case RFCOMM_UIH:
-+ if (dlci)
-+ return rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb);
-+
-+ rfcomm_recv_mcc(s, skb);
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown packet type 0x%02x\n", type);
-+ break;
-+ }
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+/* ---- Connection and data processing ---- */
-+
-+static void rfcomm_process_connect(struct rfcomm_session *s)
-+{
-+ struct rfcomm_dlc *d;
-+ struct list_head *p, *n;
-+
-+ BT_DBG("session %p state %ld", s, s->state);
-+
-+ list_for_each_safe(p, n, &s->dlcs) {
-+ d = list_entry(p, struct rfcomm_dlc, list);
-+ if (d->state == BT_CONFIG) {
-+ d->mtu = s->mtu;
-+ rfcomm_send_pn(s, 1, d);
-+ }
-+ }
-+}
-+
-+/* Send data queued for the DLC.
-+ * Return number of frames left in the queue.
-+ */
-+static inline int rfcomm_process_tx(struct rfcomm_dlc *d)
-+{
-+ struct sk_buff *skb;
-+ int err;
-+
-+ BT_DBG("dlc %p state %ld cfc %d rx_credits %d tx_credits %d",
-+ d, d->state, d->cfc, d->rx_credits, d->tx_credits);
-+
-+ /* Send pending MSC */
-+ if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags))
-+ rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
-+
-+ if (d->cfc) {
-+ /* CFC enabled.
-+ * Give them some credits */
-+ if (!test_bit(RFCOMM_RX_THROTTLED, &d->flags) &&
-+ d->rx_credits <= (d->cfc >> 2)) {
-+ rfcomm_send_credits(d->session, d->addr, d->cfc - d->rx_credits);
-+ d->rx_credits = d->cfc;
-+ }
-+ } else {
-+ /* CFC disabled.
-+ * Give ourselves some credits */
-+ d->tx_credits = 5;
-+ }
-+
-+ if (test_bit(RFCOMM_TX_THROTTLED, &d->flags))
-+ return skb_queue_len(&d->tx_queue);
-+
-+ while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) {
-+ err = rfcomm_send_frame(d->session, skb->data, skb->len);
-+ if (err < 0) {
-+ skb_queue_head(&d->tx_queue, skb);
-+ break;
-+ }
-+ kfree_skb(skb);
-+ d->tx_credits--;
-+ }
-+
-+ if (d->cfc && !d->tx_credits) {
-+ /* We're out of TX credits.
-+ * Set TX_THROTTLED flag to avoid unnesary wakeups by dlc_send. */
-+ set_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+ }
-+
-+ return skb_queue_len(&d->tx_queue);
-+}
-+
-+static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
-+{
-+ struct rfcomm_dlc *d;
-+ struct list_head *p, *n;
-+
-+ BT_DBG("session %p state %ld", s, s->state);
-+
-+ list_for_each_safe(p, n, &s->dlcs) {
-+ d = list_entry(p, struct rfcomm_dlc, list);
-+ if (test_bit(RFCOMM_TIMED_OUT, &d->flags)) {
-+ __rfcomm_dlc_close(d, ETIMEDOUT);
-+ continue;
-+ }
-+
-+ if (test_bit(RFCOMM_TX_THROTTLED, &s->flags))
-+ continue;
-+
-+ if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) &&
-+ d->mscex == RFCOMM_MSCEX_OK)
-+ rfcomm_process_tx(d);
-+ }
-+}
-+
-+static inline void rfcomm_process_rx(struct rfcomm_session *s)
-+{
-+ struct socket *sock = s->sock;
-+ struct sock *sk = sock->sk;
-+ struct sk_buff *skb;
-+
-+ BT_DBG("session %p state %ld qlen %d", s, s->state, skb_queue_len(&sk->receive_queue));
-+
-+ /* Get data directly from socket receive queue without copying it. */
-+ while ((skb = skb_dequeue(&sk->receive_queue))) {
-+ skb_orphan(skb);
-+ rfcomm_recv_frame(s, skb);
-+ }
-+
-+ if (sk->state == BT_CLOSED) {
-+ if (!s->initiator)
-+ rfcomm_session_put(s);
-+
-+ rfcomm_session_close(s, sk->err);
-+ }
-+}
-+
-+static inline void rfcomm_accept_connection(struct rfcomm_session *s)
-+{
-+ struct socket *sock = s->sock, *nsock;
-+ int err;
-+
-+ /* Fast check for a new connection.
-+ * Avoids unnesesary socket allocations. */
-+ if (list_empty(&bluez_pi(sock->sk)->accept_q))
-+ return;
-+
-+ BT_DBG("session %p", s);
-+
-+ nsock = sock_alloc();
-+ if (!nsock)
-+ return;
-+
-+ nsock->type = sock->type;
-+ nsock->ops = sock->ops;
-+
-+ err = sock->ops->accept(sock, nsock, O_NONBLOCK);
-+ if (err < 0) {
-+ sock_release(nsock);
-+ return;
-+ }
-+
-+ /* Set our callbacks */
-+ nsock->sk->data_ready = rfcomm_l2data_ready;
-+ nsock->sk->state_change = rfcomm_l2state_change;
-+
-+ s = rfcomm_session_add(nsock, BT_OPEN);
-+ if (s) {
-+ rfcomm_session_hold(s);
-+ rfcomm_schedule(RFCOMM_SCHED_RX);
-+ } else
-+ sock_release(nsock);
-+}
-+
-+static inline void rfcomm_check_connection(struct rfcomm_session *s)
-+{
-+ struct sock *sk = s->sock->sk;
-+
-+ BT_DBG("%p state %ld", s, s->state);
-+
-+ switch(sk->state) {
-+ case BT_CONNECTED:
-+ s->state = BT_CONNECT;
-+
-+ /* We can adjust MTU on outgoing sessions.
-+ * L2CAP MTU minus UIH header and FCS. */
-+ s->mtu = min(l2cap_pi(sk)->omtu, l2cap_pi(sk)->imtu) - 5;
-+
-+ rfcomm_send_sabm(s, 0);
-+ break;
-+
-+ case BT_CLOSED:
-+ s->state = BT_CLOSED;
-+ rfcomm_session_close(s, sk->err);
-+ break;
-+ }
-+}
-+
-+static inline void rfcomm_process_sessions(void)
-+{
-+ struct list_head *p, *n;
-+
-+ rfcomm_lock();
-+
-+ list_for_each_safe(p, n, &session_list) {
-+ struct rfcomm_session *s;
-+ s = list_entry(p, struct rfcomm_session, list);
-+
-+ if (s->state == BT_LISTEN) {
-+ rfcomm_accept_connection(s);
-+ continue;
-+ }
-+
-+ rfcomm_session_hold(s);
-+
-+ switch (s->state) {
-+ case BT_BOUND:
-+ rfcomm_check_connection(s);
-+ break;
-+
-+ default:
-+ rfcomm_process_rx(s);
-+ break;
-+ }
-+
-+ rfcomm_process_dlcs(s);
-+
-+ rfcomm_session_put(s);
-+ }
-+
-+ rfcomm_unlock();
-+}
-+
-+static void rfcomm_worker(void)
-+{
-+ BT_DBG("");
-+
-+ daemonize(); reparent_to_init();
-+ set_fs(KERNEL_DS);
-+
-+ while (!atomic_read(&terminate)) {
-+ BT_DBG("worker loop event 0x%lx", rfcomm_event);
-+
-+ if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
-+ /* No pending events. Let's sleep.
-+ * Incomming connections and data will wake us up. */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule();
-+ }
-+
-+ /* Process stuff */
-+ clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
-+ rfcomm_process_sessions();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ return;
-+}
-+
-+static int rfcomm_add_listener(bdaddr_t *ba)
-+{
-+ struct sockaddr_l2 addr;
-+ struct l2cap_options opts;
-+ struct socket *sock;
-+ struct rfcomm_session *s;
-+ int size, err = 0;
-+
-+ /* Create socket */
-+ err = rfcomm_l2sock_create(&sock);
-+ if (err < 0) {
-+ BT_ERR("Create socket failed %d", err);
-+ return err;
-+ }
-+
-+ /* Bind socket */
-+ bacpy(&addr.l2_bdaddr, ba);
-+ addr.l2_family = AF_BLUETOOTH;
-+ addr.l2_psm = htobs(RFCOMM_PSM);
-+ err = sock->ops->bind(sock, (struct sockaddr *) &addr, sizeof(addr));
-+ if (err < 0) {
-+ BT_ERR("Bind failed %d", err);
-+ goto failed;
-+ }
-+
-+ /* Set L2CAP options */
-+ size = sizeof(opts);
-+ sock->ops->getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, &size);
-+
-+ opts.imtu = RFCOMM_MAX_L2CAP_MTU;
-+ sock->ops->setsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, size);
-+
-+ /* Start listening on the socket */
-+ err = sock->ops->listen(sock, 10);
-+ if (err) {
-+ BT_ERR("Listen failed %d", err);
-+ goto failed;
-+ }
-+
-+ /* Add listening session */
-+ s = rfcomm_session_add(sock, BT_LISTEN);
-+ if (!s)
-+ goto failed;
-+
-+ rfcomm_session_hold(s);
-+ return 0;
-+failed:
-+ sock_release(sock);
-+ return err;
-+}
-+
-+static void rfcomm_kill_listener(void)
-+{
-+ struct rfcomm_session *s;
-+ struct list_head *p, *n;
-+
-+ BT_DBG("");
-+
-+ list_for_each_safe(p, n, &session_list) {
-+ s = list_entry(p, struct rfcomm_session, list);
-+ rfcomm_session_del(s);
-+ }
-+}
-+
-+static int rfcomm_run(void *unused)
-+{
-+ rfcomm_thread = current;
-+
-+ atomic_inc(&running);
-+
-+ daemonize(); reparent_to_init();
-+
-+ sigfillset(&current->blocked);
-+ set_fs(KERNEL_DS);
-+
-+ sprintf(current->comm, "krfcommd");
-+
-+ BT_DBG("");
-+
-+ rfcomm_add_listener(BDADDR_ANY);
-+
-+ rfcomm_worker();
-+
-+ rfcomm_kill_listener();
-+
-+ atomic_dec(&running);
-+ return 0;
-+}
-+
-+/* ---- Proc fs support ---- */
-+static int rfcomm_dlc_dump(char *buf)
-+{
-+ struct rfcomm_session *s;
-+ struct sock *sk;
-+ struct list_head *p, *pp;
-+ char *ptr = buf;
-+
-+ rfcomm_lock();
-+
-+ list_for_each(p, &session_list) {
-+ s = list_entry(p, struct rfcomm_session, list);
-+ sk = s->sock->sk;
-+
-+ list_for_each(pp, &s->dlcs) {
-+ struct rfcomm_dlc *d;
-+ d = list_entry(pp, struct rfcomm_dlc, list);
-+
-+ ptr += sprintf(ptr, "dlc %s %s %ld %d %d %d %d\n",
-+ batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
-+ d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
-+ }
-+ }
-+
-+ rfcomm_unlock();
-+
-+ return ptr - buf;
-+}
-+
-+extern int rfcomm_sock_dump(char *buf);
-+
-+static int rfcomm_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
-+{
-+ char *ptr = buf;
-+ int len;
-+
-+ BT_DBG("count %d, offset %ld", count, offset);
-+
-+ ptr += rfcomm_dlc_dump(ptr);
-+ ptr += rfcomm_sock_dump(ptr);
-+ len = ptr - buf;
-+
-+ if (len <= count + offset)
-+ *eof = 1;
-+
-+ *start = buf + offset;
-+ len -= offset;
-+
-+ if (len > count)
-+ len = count;
-+ if (len < 0)
-+ len = 0;
-+
-+ return len;
-+}
-+
-+/* ---- Initialization ---- */
-+int __init rfcomm_init(void)
-+{
-+ l2cap_load();
-+
-+ kernel_thread(rfcomm_run, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-+
-+ rfcomm_init_sockets();
-+
-+#ifdef CONFIG_BLUEZ_RFCOMM_TTY
-+ rfcomm_init_ttys();
-+#endif
-+
-+ create_proc_read_entry("bluetooth/rfcomm", 0, 0, rfcomm_read_proc, NULL);
-+
-+ BT_INFO("BlueZ RFCOMM ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>");
-+ BT_INFO("Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>");
-+ return 0;
-+}
-+
-+void rfcomm_cleanup(void)
-+{
-+ /* Terminate working thread.
-+ * ie. Set terminate flag and wake it up */
-+ atomic_inc(&terminate);
-+ rfcomm_schedule(RFCOMM_SCHED_STATE);
-+
-+ /* Wait until thread is running */
-+ while (atomic_read(&running))
-+ schedule();
-+
-+ remove_proc_entry("bluetooth/rfcomm", NULL);
-+
-+#ifdef CONFIG_BLUEZ_RFCOMM_TTY
-+ rfcomm_cleanup_ttys();
-+#endif
-+
-+ rfcomm_cleanup_sockets();
-+ return;
-+}
-+
-+module_init(rfcomm_init);
-+module_exit(rfcomm_cleanup);
-+
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ RFCOMM ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/crc.c linux-2.4.18-mh15/net/bluetooth/rfcomm/crc.c
---- linux-2.4.18/net/bluetooth/rfcomm/crc.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/rfcomm/crc.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,71 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * RFCOMM FCS calculation.
-+ *
-+ * $Id$
-+ */
-+
-+/* reversed, 8-bit, poly=0x07 */
-+unsigned char rfcomm_crc_table[256] = {
-+ 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
-+ 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
-+ 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
-+ 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
-+
-+ 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
-+ 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
-+ 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
-+ 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
-+
-+ 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
-+ 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
-+ 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
-+ 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
-+
-+ 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
-+ 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
-+ 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
-+ 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
-+
-+ 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
-+ 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
-+ 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
-+ 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
-+
-+ 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
-+ 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
-+ 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
-+ 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
-+
-+ 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
-+ 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
-+ 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
-+ 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
-+
-+ 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
-+ 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
-+ 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
-+ 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
-+};
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/Makefile linux-2.4.18-mh15/net/bluetooth/rfcomm/Makefile
---- linux-2.4.18/net/bluetooth/rfcomm/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/rfcomm/Makefile 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,11 @@
-+#
-+# Makefile for the Linux Bluetooth RFCOMM layer
-+#
-+
-+O_TARGET := rfcomm.o
-+
-+obj-y := core.o sock.o crc.o
-+obj-$(CONFIG_BLUEZ_RFCOMM_TTY) += tty.o
-+obj-m += $(O_TARGET)
-+
-+include $(TOPDIR)/Rules.make
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/sock.c linux-2.4.18-mh15/net/bluetooth/rfcomm/sock.c
---- linux-2.4.18/net/bluetooth/rfcomm/sock.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/rfcomm/sock.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,847 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * RFCOMM sockets.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/socket.h>
-+#include <linux/skbuff.h>
-+#include <linux/list.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/rfcomm.h>
-+
-+#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+static struct proto_ops rfcomm_sock_ops;
-+
-+static struct bluez_sock_list rfcomm_sk_list = {
-+ lock: RW_LOCK_UNLOCKED
-+};
-+
-+static void rfcomm_sock_close(struct sock *sk);
-+static void rfcomm_sock_kill(struct sock *sk);
-+
-+/* ---- DLC callbacks ----
-+ *
-+ * called under rfcomm_dlc_lock()
-+ */
-+static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb)
-+{
-+ struct sock *sk = d->owner;
-+ if (!sk)
-+ return;
-+
-+ atomic_add(skb->len, &sk->rmem_alloc);
-+ skb_queue_tail(&sk->receive_queue, skb);
-+ sk->data_ready(sk, skb->len);
-+
-+ if (atomic_read(&sk->rmem_alloc) >= sk->rcvbuf)
-+ rfcomm_dlc_throttle(d);
-+}
-+
-+static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
-+{
-+ struct sock *sk = d->owner, *parent;
-+ if (!sk)
-+ return;
-+
-+ BT_DBG("dlc %p state %ld err %d", d, d->state, err);
-+
-+ bh_lock_sock(sk);
-+
-+ if (err)
-+ sk->err = err;
-+ sk->state = d->state;
-+
-+ parent = bluez_pi(sk)->parent;
-+ if (!parent) {
-+ if (d->state == BT_CONNECTED)
-+ rfcomm_session_getaddr(d->session, &bluez_pi(sk)->src, NULL);
-+ sk->state_change(sk);
-+ } else
-+ parent->data_ready(parent, 0);
-+
-+ bh_unlock_sock(sk);
-+}
-+
-+/* ---- Socket functions ---- */
-+static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
-+{
-+ struct sock *sk;
-+
-+ for (sk = rfcomm_sk_list.head; sk; sk = sk->next) {
-+ if (rfcomm_pi(sk)->channel == channel &&
-+ !bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+ }
-+
-+ return sk;
-+}
-+
-+/* Find socket with channel and source bdaddr.
-+ * Returns closest match.
-+ */
-+static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
-+{
-+ struct sock *sk, *sk1 = NULL;
-+
-+ for (sk = rfcomm_sk_list.head; sk; sk = sk->next) {
-+ if (state && sk->state != state)
-+ continue;
-+
-+ if (rfcomm_pi(sk)->channel == channel) {
-+ /* Exact match. */
-+ if (!bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+
-+ /* Closest match */
-+ if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
-+ sk1 = sk;
-+ }
-+ }
-+ return sk ? sk : sk1;
-+}
-+
-+/* Find socket with given address (channel, src).
-+ * Returns locked socket */
-+static inline struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
-+{
-+ struct sock *s;
-+ read_lock(&rfcomm_sk_list.lock);
-+ s = __rfcomm_get_sock_by_channel(state, channel, src);
-+ if (s) bh_lock_sock(s);
-+ read_unlock(&rfcomm_sk_list.lock);
-+ return s;
-+}
-+
-+static void rfcomm_sock_destruct(struct sock *sk)
-+{
-+ struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
-+
-+ BT_DBG("sk %p dlc %p", sk, d);
-+
-+ skb_queue_purge(&sk->receive_queue);
-+ skb_queue_purge(&sk->write_queue);
-+
-+ rfcomm_dlc_lock(d);
-+ rfcomm_pi(sk)->dlc = NULL;
-+
-+ /* Detach DLC if it's owned by this socket */
-+ if (d->owner == sk)
-+ d->owner = NULL;
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_dlc_put(d);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void rfcomm_sock_cleanup_listen(struct sock *parent)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("parent %p", parent);
-+
-+ /* Close not yet accepted dlcs */
-+ while ((sk = bluez_accept_dequeue(parent, NULL))) {
-+ rfcomm_sock_close(sk);
-+ rfcomm_sock_kill(sk);
-+ }
-+
-+ parent->state = BT_CLOSED;
-+ parent->zapped = 1;
-+}
-+
-+/* Kill socket (only if zapped and orphan)
-+ * Must be called on unlocked socket.
-+ */
-+static void rfcomm_sock_kill(struct sock *sk)
-+{
-+ if (!sk->zapped || sk->socket)
-+ return;
-+
-+ BT_DBG("sk %p state %d refcnt %d", sk, sk->state, atomic_read(&sk->refcnt));
-+
-+ /* Kill poor orphan */
-+ bluez_sock_unlink(&rfcomm_sk_list, sk);
-+ sk->dead = 1;
-+ sock_put(sk);
-+}
-+
-+static void __rfcomm_sock_close(struct sock *sk)
-+{
-+ struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
-+
-+ BT_DBG("sk %p state %d socket %p", sk, sk->state, sk->socket);
-+
-+ switch (sk->state) {
-+ case BT_LISTEN:
-+ rfcomm_sock_cleanup_listen(sk);
-+ break;
-+
-+ case BT_CONNECT:
-+ case BT_CONNECT2:
-+ case BT_CONFIG:
-+ case BT_CONNECTED:
-+ rfcomm_dlc_close(d, 0);
-+
-+ default:
-+ sk->zapped = 1;
-+ break;
-+ }
-+}
-+
-+/* Close socket.
-+ * Must be called on unlocked socket.
-+ */
-+static void rfcomm_sock_close(struct sock *sk)
-+{
-+ lock_sock(sk);
-+ __rfcomm_sock_close(sk);
-+ release_sock(sk);
-+}
-+
-+static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
-+{
-+ BT_DBG("sk %p", sk);
-+
-+ if (parent)
-+ sk->type = parent->type;
-+}
-+
-+static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, int prio)
-+{
-+ struct rfcomm_dlc *d;
-+ struct sock *sk;
-+
-+ sk = sk_alloc(PF_BLUETOOTH, prio, 1);
-+ if (!sk)
-+ return NULL;
-+
-+ d = rfcomm_dlc_alloc(prio);
-+ if (!d) {
-+ sk_free(sk);
-+ return NULL;
-+ }
-+ d->data_ready = rfcomm_sk_data_ready;
-+ d->state_change = rfcomm_sk_state_change;
-+
-+ rfcomm_pi(sk)->dlc = d;
-+ d->owner = sk;
-+
-+ bluez_sock_init(sock, sk);
-+
-+ sk->zapped = 0;
-+
-+ sk->destruct = rfcomm_sock_destruct;
-+ sk->sndtimeo = RFCOMM_CONN_TIMEOUT;
-+
-+ sk->sndbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
-+ sk->rcvbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
-+
-+ sk->protocol = proto;
-+ sk->state = BT_OPEN;
-+
-+ bluez_sock_link(&rfcomm_sk_list, sk);
-+
-+ BT_DBG("sk %p", sk);
-+
-+ MOD_INC_USE_COUNT;
-+ return sk;
-+}
-+
-+static int rfcomm_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ sock->state = SS_UNCONNECTED;
-+
-+ if (sock->type != SOCK_STREAM && sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &rfcomm_sock_ops;
-+
-+ if (!(sk = rfcomm_sock_alloc(sock, protocol, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ rfcomm_sock_init(sk, NULL);
-+ return 0;
-+}
-+
-+static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
-+{
-+ struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p %s", sk, batostr(&sa->rc_bdaddr));
-+
-+ if (!addr || addr->sa_family != AF_BLUETOOTH)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_OPEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ write_lock_bh(&rfcomm_sk_list.lock);
-+
-+ if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
-+ err = -EADDRINUSE;
-+ } else {
-+ /* Save source address */
-+ bacpy(&bluez_pi(sk)->src, &sa->rc_bdaddr);
-+ rfcomm_pi(sk)->channel = sa->rc_channel;
-+ sk->state = BT_BOUND;
-+ }
-+
-+ write_unlock_bh(&rfcomm_sk_list.lock);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
-+{
-+ struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
-+ struct sock *sk = sock->sk;
-+ struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
-+ int err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc))
-+ return -EINVAL;
-+
-+ if (sk->state != BT_OPEN && sk->state != BT_BOUND)
-+ return -EBADFD;
-+
-+ if (sk->type != SOCK_STREAM)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ sk->state = BT_CONNECT;
-+ bacpy(&bluez_pi(sk)->dst, &sa->rc_bdaddr);
-+ rfcomm_pi(sk)->channel = sa->rc_channel;
-+
-+ err = rfcomm_dlc_open(d, &bluez_pi(sk)->src, &sa->rc_bdaddr, sa->rc_channel);
-+ if (!err)
-+ err = bluez_sock_wait_state(sk, BT_CONNECTED,
-+ sock_sndtimeo(sk, flags & O_NONBLOCK));
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int rfcomm_sock_listen(struct socket *sock, int backlog)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p backlog %d", sk, backlog);
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_BOUND) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ sk->max_ack_backlog = backlog;
-+ sk->ack_backlog = 0;
-+ sk->state = BT_LISTEN;
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct sock *sk = sock->sk, *nsk;
-+ long timeo;
-+ int err = 0;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
-+
-+ BT_DBG("sk %p timeo %ld", sk, timeo);
-+
-+ /* Wait for an incoming connection. (wake-one). */
-+ add_wait_queue_exclusive(sk->sleep, &wait);
-+ while (!(nsk = bluez_accept_dequeue(sk, newsock))) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ break;
-+ }
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ break;
-+ }
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ if (err)
-+ goto done;
-+
-+ newsock->state = SS_CONNECTED;
-+
-+ BT_DBG("new socket %p", nsk);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
-+{
-+ struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ sa->rc_family = AF_BLUETOOTH;
-+ sa->rc_channel = rfcomm_pi(sk)->channel;
-+ if (peer)
-+ bacpy(&sa->rc_bdaddr, &bluez_pi(sk)->dst);
-+ else
-+ bacpy(&sa->rc_bdaddr, &bluez_pi(sk)->src);
-+
-+ *len = sizeof(struct sockaddr_rc);
-+ return 0;
-+}
-+
-+static int rfcomm_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
-+ struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
-+ struct sk_buff *skb;
-+ int err, size;
-+ int sent = 0;
-+
-+ if (msg->msg_flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ if (sk->shutdown & SEND_SHUTDOWN)
-+ return -EPIPE;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ lock_sock(sk);
-+
-+ while (len) {
-+ size = min_t(uint, len, d->mtu);
-+
-+ skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE,
-+ msg->msg_flags & MSG_DONTWAIT, &err);
-+ if (!skb)
-+ break;
-+ skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
-+
-+ err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
-+ if (err) {
-+ kfree_skb(skb);
-+ sent = err;
-+ break;
-+ }
-+
-+ err = rfcomm_dlc_send(d, skb);
-+ if (err < 0) {
-+ kfree_skb(skb);
-+ break;
-+ }
-+
-+ sent += size;
-+ len -= size;
-+ }
-+
-+ release_sock(sk);
-+
-+ return sent ? sent : err;
-+}
-+
-+static long rfcomm_sock_data_wait(struct sock *sk, long timeo)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+ add_wait_queue(sk->sleep, &wait);
-+ for (;;) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (skb_queue_len(&sk->receive_queue) || sk->err || (sk->shutdown & RCV_SHUTDOWN) ||
-+ signal_pending(current) || !timeo)
-+ break;
-+
-+ set_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+ clear_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
-+ }
-+
-+ __set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+ return timeo;
-+}
-+
-+static int rfcomm_sock_recvmsg(struct socket *sock, struct msghdr *msg, int size,
-+ int flags, struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ int target, err = 0, copied = 0;
-+ long timeo;
-+
-+ if (flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ msg->msg_namelen = 0;
-+
-+ BT_DBG("sk %p size %d", sk, size);
-+
-+ lock_sock(sk);
-+
-+ target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
-+ timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
-+
-+ do {
-+ struct sk_buff *skb;
-+ int chunk;
-+
-+ skb = skb_dequeue(&sk->receive_queue);
-+ if (!skb) {
-+ if (copied >= target)
-+ break;
-+
-+ if ((err = sock_error(sk)) != 0)
-+ break;
-+ if (sk->shutdown & RCV_SHUTDOWN)
-+ break;
-+
-+ err = -EAGAIN;
-+ if (!timeo)
-+ break;
-+
-+ timeo = rfcomm_sock_data_wait(sk, timeo);
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ goto out;
-+ }
-+ continue;
-+ }
-+
-+ chunk = min_t(unsigned int, skb->len, size);
-+ if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
-+ skb_queue_head(&sk->receive_queue, skb);
-+ if (!copied)
-+ copied = -EFAULT;
-+ break;
-+ }
-+ copied += chunk;
-+ size -= chunk;
-+
-+ if (!(flags & MSG_PEEK)) {
-+ atomic_sub(chunk, &sk->rmem_alloc);
-+
-+ skb_pull(skb, chunk);
-+ if (skb->len) {
-+ skb_queue_head(&sk->receive_queue, skb);
-+ break;
-+ }
-+ kfree_skb(skb);
-+
-+ } else {
-+ /* put message back and return */
-+ skb_queue_head(&sk->receive_queue, skb);
-+ break;
-+ }
-+ } while (size);
-+
-+out:
-+ if (atomic_read(&sk->rmem_alloc) <= (sk->rcvbuf >> 2))
-+ rfcomm_dlc_unthrottle(rfcomm_pi(sk)->dlc);
-+
-+ release_sock(sk);
-+ return copied ? : err;
-+}
-+
-+static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ int len, err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (get_user(len, optlen))
-+ return -EFAULT;
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct sock *sk = sock->sk;
-+ int err;
-+
-+ lock_sock(sk);
-+
-+#ifdef CONFIG_BLUEZ_RFCOMM_TTY
-+ err = rfcomm_dev_ioctl(sk, cmd, arg);
-+#else
-+ err = -EOPNOTSUPP;
-+#endif
-+
-+ release_sock(sk);
-+
-+ return err;
-+}
-+
-+static int rfcomm_sock_shutdown(struct socket *sock, int how)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk) return 0;
-+
-+ lock_sock(sk);
-+ if (!sk->shutdown) {
-+ sk->shutdown = SHUTDOWN_MASK;
-+ __rfcomm_sock_close(sk);
-+
-+ if (sk->linger)
-+ err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
-+ }
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ err = rfcomm_sock_shutdown(sock, 2);
-+
-+ sock_orphan(sk);
-+ rfcomm_sock_kill(sk);
-+ return err;
-+}
-+
-+/* ---- RFCOMM core layer callbacks ----
-+ *
-+ * called under rfcomm_lock()
-+ */
-+int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d)
-+{
-+ struct sock *sk, *parent;
-+ bdaddr_t src, dst;
-+ int result = 0;
-+
-+ BT_DBG("session %p channel %d", s, channel);
-+
-+ rfcomm_session_getaddr(s, &src, &dst);
-+
-+ /* Check if we have socket listening on this channel */
-+ parent = rfcomm_get_sock_by_channel(BT_LISTEN, channel, &src);
-+ if (!parent)
-+ return 0;
-+
-+ /* Check for backlog size */
-+ if (parent->ack_backlog > parent->max_ack_backlog) {
-+ BT_DBG("backlog full %d", parent->ack_backlog);
-+ goto done;
-+ }
-+
-+ sk = rfcomm_sock_alloc(NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
-+ if (!sk)
-+ goto done;
-+
-+ rfcomm_sock_init(sk, parent);
-+ bacpy(&bluez_pi(sk)->src, &src);
-+ bacpy(&bluez_pi(sk)->dst, &dst);
-+ rfcomm_pi(sk)->channel = channel;
-+
-+ sk->state = BT_CONFIG;
-+ bluez_accept_enqueue(parent, sk);
-+
-+ /* Accept connection and return socket DLC */
-+ *d = rfcomm_pi(sk)->dlc;
-+ result = 1;
-+
-+done:
-+ bh_unlock_sock(parent);
-+ return result;
-+}
-+
-+/* ---- Proc fs support ---- */
-+int rfcomm_sock_dump(char *buf)
-+{
-+ struct bluez_sock_list *list = &rfcomm_sk_list;
-+ struct rfcomm_pinfo *pi;
-+ struct sock *sk;
-+ char *ptr = buf;
-+
-+ write_lock_bh(&list->lock);
-+
-+ for (sk = list->head; sk; sk = sk->next) {
-+ pi = rfcomm_pi(sk);
-+ ptr += sprintf(ptr, "sk %s %s %d %d\n",
-+ batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
-+ sk->state, rfcomm_pi(sk)->channel);
-+ }
-+
-+ write_unlock_bh(&list->lock);
-+
-+ return ptr - buf;
-+}
-+
-+static struct proto_ops rfcomm_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: rfcomm_sock_release,
-+ bind: rfcomm_sock_bind,
-+ connect: rfcomm_sock_connect,
-+ listen: rfcomm_sock_listen,
-+ accept: rfcomm_sock_accept,
-+ getname: rfcomm_sock_getname,
-+ sendmsg: rfcomm_sock_sendmsg,
-+ recvmsg: rfcomm_sock_recvmsg,
-+ shutdown: rfcomm_sock_shutdown,
-+ setsockopt: rfcomm_sock_setsockopt,
-+ getsockopt: rfcomm_sock_getsockopt,
-+ ioctl: rfcomm_sock_ioctl,
-+ poll: bluez_sock_poll,
-+ socketpair: sock_no_socketpair,
-+ mmap: sock_no_mmap
-+};
-+
-+static struct net_proto_family rfcomm_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: rfcomm_sock_create
-+};
-+
-+int rfcomm_init_sockets(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_RFCOMM, &rfcomm_sock_family_ops))) {
-+ BT_ERR("Can't register RFCOMM socket layer");
-+ return err;
-+ }
-+
-+ return 0;
-+}
-+
-+void rfcomm_cleanup_sockets(void)
-+{
-+ int err;
-+
-+ /* Unregister socket, protocol and notifier */
-+ if ((err = bluez_sock_unregister(BTPROTO_RFCOMM)))
-+ BT_ERR("Can't unregister RFCOMM socket layer %d", err);
-+}
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/tty.c linux-2.4.18-mh15/net/bluetooth/rfcomm/tty.c
---- linux-2.4.18/net/bluetooth/rfcomm/tty.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/rfcomm/tty.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,960 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * RFCOMM TTY.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/tty.h>
-+#include <linux/tty_driver.h>
-+#include <linux/tty_flip.h>
-+
-+#include <linux/slab.h>
-+#include <linux/skbuff.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/rfcomm.h>
-+
-+#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define RFCOMM_TTY_MAGIC 0x6d02 /* magic number for rfcomm struct */
-+#define RFCOMM_TTY_PORTS RFCOMM_MAX_DEV /* whole lotta rfcomm devices */
-+#define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */
-+#define RFCOMM_TTY_MINOR 0
-+
-+struct rfcomm_dev {
-+ struct list_head list;
-+ atomic_t refcnt;
-+
-+ char name[12];
-+ int id;
-+ unsigned long flags;
-+ int opened;
-+ int err;
-+
-+ bdaddr_t src;
-+ bdaddr_t dst;
-+ u8 channel;
-+
-+ uint modem_status;
-+
-+ struct rfcomm_dlc *dlc;
-+ struct tty_struct *tty;
-+ wait_queue_head_t wait;
-+ struct tasklet_struct wakeup_task;
-+
-+ atomic_t wmem_alloc;
-+};
-+
-+static LIST_HEAD(rfcomm_dev_list);
-+static rwlock_t rfcomm_dev_lock = RW_LOCK_UNLOCKED;
-+
-+static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
-+static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
-+static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
-+
-+static void rfcomm_tty_wakeup(unsigned long arg);
-+
-+/* ---- Device functions ---- */
-+static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
-+{
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+
-+ BT_DBG("dev %p dlc %p", dev, dlc);
-+
-+ rfcomm_dlc_lock(dlc);
-+ /* Detach DLC if it's owned by this dev */
-+ if (dlc->owner == dev)
-+ dlc->owner = NULL;
-+ rfcomm_dlc_unlock(dlc);
-+
-+ rfcomm_dlc_put(dlc);
-+ kfree(dev);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static inline void rfcomm_dev_hold(struct rfcomm_dev *dev)
-+{
-+ atomic_inc(&dev->refcnt);
-+}
-+
-+static inline void rfcomm_dev_put(struct rfcomm_dev *dev)
-+{
-+ /* The reason this isn't actually a race, as you no
-+ doubt have a little voice screaming at you in your
-+ head, is that the refcount should never actually
-+ reach zero unless the device has already been taken
-+ off the list, in rfcomm_dev_del(). And if that's not
-+ true, we'll hit the BUG() in rfcomm_dev_destruct()
-+ anyway. */
-+ if (atomic_dec_and_test(&dev->refcnt))
-+ rfcomm_dev_destruct(dev);
-+}
-+
-+static struct rfcomm_dev *__rfcomm_dev_get(int id)
-+{
-+ struct rfcomm_dev *dev;
-+ struct list_head *p;
-+
-+ list_for_each(p, &rfcomm_dev_list) {
-+ dev = list_entry(p, struct rfcomm_dev, list);
-+ if (dev->id == id)
-+ return dev;
-+ }
-+
-+ return NULL;
-+}
-+
-+static inline struct rfcomm_dev *rfcomm_dev_get(int id)
-+{
-+ struct rfcomm_dev *dev;
-+
-+ read_lock(&rfcomm_dev_lock);
-+
-+ dev = __rfcomm_dev_get(id);
-+ if (dev)
-+ rfcomm_dev_hold(dev);
-+
-+ read_unlock(&rfcomm_dev_lock);
-+
-+ return dev;
-+}
-+
-+static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
-+{
-+ struct rfcomm_dev *dev;
-+ struct list_head *head = &rfcomm_dev_list, *p;
-+ int err = 0;
-+
-+ BT_DBG("id %d channel %d", req->dev_id, req->channel);
-+
-+ dev = kmalloc(sizeof(struct rfcomm_dev), GFP_KERNEL);
-+ if (!dev)
-+ return -ENOMEM;
-+ memset(dev, 0, sizeof(struct rfcomm_dev));
-+
-+ write_lock_bh(&rfcomm_dev_lock);
-+
-+ if (req->dev_id < 0) {
-+ dev->id = 0;
-+
-+ list_for_each(p, &rfcomm_dev_list) {
-+ if (list_entry(p, struct rfcomm_dev, list)->id != dev->id)
-+ break;
-+
-+ dev->id++;
-+ head = p;
-+ }
-+ } else {
-+ dev->id = req->dev_id;
-+
-+ list_for_each(p, &rfcomm_dev_list) {
-+ struct rfcomm_dev *entry = list_entry(p, struct rfcomm_dev, list);
-+
-+ if (entry->id == dev->id) {
-+ err = -EADDRINUSE;
-+ goto out;
-+ }
-+
-+ if (entry->id > dev->id - 1)
-+ break;
-+
-+ head = p;
-+ }
-+ }
-+
-+ if ((dev->id < 0) || (dev->id > RFCOMM_MAX_DEV - 1)) {
-+ err = -ENFILE;
-+ goto out;
-+ }
-+
-+ sprintf(dev->name, "rfcomm%d", dev->id);
-+
-+ list_add(&dev->list, head);
-+ atomic_set(&dev->refcnt, 1);
-+
-+ bacpy(&dev->src, &req->src);
-+ bacpy(&dev->dst, &req->dst);
-+ dev->channel = req->channel;
-+
-+ dev->flags = req->flags &
-+ ((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
-+
-+ init_waitqueue_head(&dev->wait);
-+ tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev);
-+
-+ rfcomm_dlc_lock(dlc);
-+ dlc->data_ready = rfcomm_dev_data_ready;
-+ dlc->state_change = rfcomm_dev_state_change;
-+ dlc->modem_status = rfcomm_dev_modem_status;
-+
-+ dlc->owner = dev;
-+ dev->dlc = dlc;
-+ rfcomm_dlc_unlock(dlc);
-+
-+ MOD_INC_USE_COUNT;
-+
-+out:
-+ write_unlock_bh(&rfcomm_dev_lock);
-+
-+ if (err) {
-+ kfree(dev);
-+ return err;
-+ } else
-+ return dev->id;
-+}
-+
-+static void rfcomm_dev_del(struct rfcomm_dev *dev)
-+{
-+ BT_DBG("dev %p", dev);
-+
-+ write_lock_bh(&rfcomm_dev_lock);
-+ list_del_init(&dev->list);
-+ write_unlock_bh(&rfcomm_dev_lock);
-+
-+ rfcomm_dev_put(dev);
-+}
-+
-+/* ---- Send buffer ---- */
-+
-+static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc)
-+{
-+ /* We can't let it be zero, because we don't get a callback
-+ when tx_credits becomes nonzero, hence we'd never wake up */
-+ return dlc->mtu * (dlc->tx_credits?:1);
-+}
-+
-+static void rfcomm_wfree(struct sk_buff *skb)
-+{
-+ struct rfcomm_dev *dev = (void *) skb->sk;
-+ atomic_sub(skb->truesize, &dev->wmem_alloc);
-+ if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags))
-+ tasklet_schedule(&dev->wakeup_task);
-+ rfcomm_dev_put(dev);
-+}
-+
-+static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
-+{
-+ rfcomm_dev_hold(dev);
-+ atomic_add(skb->truesize, &dev->wmem_alloc);
-+ skb->sk = (void *) dev;
-+ skb->destructor = rfcomm_wfree;
-+}
-+
-+static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, int force, int priority)
-+{
-+ if (force || atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) {
-+ struct sk_buff *skb = alloc_skb(size, priority);
-+ if (skb) {
-+ rfcomm_set_owner_w(skb, dev);
-+ return skb;
-+ }
-+ }
-+ return NULL;
-+}
-+
-+/* ---- Device IOCTLs ---- */
-+
-+#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
-+
-+static int rfcomm_create_dev(struct sock *sk, unsigned long arg)
-+{
-+ struct rfcomm_dev_req req;
-+ struct rfcomm_dlc *dlc;
-+ int id;
-+
-+ if (copy_from_user(&req, (void *) arg, sizeof(req)))
-+ return -EFAULT;
-+
-+ BT_DBG("sk %p dev_id %id flags 0x%x", sk, req.dev_id, req.flags);
-+
-+ if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
-+ return -EPERM;
-+
-+ if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
-+ /* Socket must be connected */
-+ if (sk->state != BT_CONNECTED)
-+ return -EBADFD;
-+
-+ dlc = rfcomm_pi(sk)->dlc;
-+ rfcomm_dlc_hold(dlc);
-+ } else {
-+ dlc = rfcomm_dlc_alloc(GFP_KERNEL);
-+ if (!dlc)
-+ return -ENOMEM;
-+ }
-+
-+ id = rfcomm_dev_add(&req, dlc);
-+ if (id < 0) {
-+ rfcomm_dlc_put(dlc);
-+ return id;
-+ }
-+
-+ if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
-+ /* DLC is now used by device.
-+ * Socket must be disconnected */
-+ sk->state = BT_CLOSED;
-+ }
-+
-+ return id;
-+}
-+
-+static int rfcomm_release_dev(unsigned long arg)
-+{
-+ struct rfcomm_dev_req req;
-+ struct rfcomm_dev *dev;
-+
-+ if (copy_from_user(&req, (void *) arg, sizeof(req)))
-+ return -EFAULT;
-+
-+ BT_DBG("dev_id %id flags 0x%x", req.dev_id, req.flags);
-+
-+ if (!(dev = rfcomm_dev_get(req.dev_id)))
-+ return -ENODEV;
-+
-+ if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) {
-+ rfcomm_dev_put(dev);
-+ return -EPERM;
-+ }
-+
-+ if (req.flags & (1 << RFCOMM_HANGUP_NOW))
-+ rfcomm_dlc_close(dev->dlc, 0);
-+
-+ rfcomm_dev_del(dev);
-+ rfcomm_dev_put(dev);
-+ return 0;
-+}
-+
-+static int rfcomm_get_dev_list(unsigned long arg)
-+{
-+ struct rfcomm_dev_list_req *dl;
-+ struct rfcomm_dev_info *di;
-+ struct list_head *p;
-+ int n = 0, size, err;
-+ u16 dev_num;
-+
-+ BT_DBG("");
-+
-+ if (get_user(dev_num, (u16 *) arg))
-+ return -EFAULT;
-+
-+ if (!dev_num || dev_num > (PAGE_SIZE * 4) / sizeof(*di))
-+ return -EINVAL;
-+
-+ size = sizeof(*dl) + dev_num * sizeof(*di);
-+
-+ if (!(dl = kmalloc(size, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ di = dl->dev_info;
-+
-+ read_lock_bh(&rfcomm_dev_lock);
-+
-+ list_for_each(p, &rfcomm_dev_list) {
-+ struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list);
-+ (di + n)->id = dev->id;
-+ (di + n)->flags = dev->flags;
-+ (di + n)->state = dev->dlc->state;
-+ (di + n)->channel = dev->channel;
-+ bacpy(&(di + n)->src, &dev->src);
-+ bacpy(&(di + n)->dst, &dev->dst);
-+ if (++n >= dev_num)
-+ break;
-+ }
-+
-+ read_unlock_bh(&rfcomm_dev_lock);
-+
-+ dl->dev_num = n;
-+ size = sizeof(*dl) + n * sizeof(*di);
-+
-+ err = copy_to_user((void *) arg, dl, size);
-+ kfree(dl);
-+
-+ return err ? -EFAULT : 0;
-+}
-+
-+static int rfcomm_get_dev_info(unsigned long arg)
-+{
-+ struct rfcomm_dev *dev;
-+ struct rfcomm_dev_info di;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ if (copy_from_user(&di, (void *)arg, sizeof(di)))
-+ return -EFAULT;
-+
-+ if (!(dev = rfcomm_dev_get(di.id)))
-+ return -ENODEV;
-+
-+ di.flags = dev->flags;
-+ di.channel = dev->channel;
-+ di.state = dev->dlc->state;
-+ bacpy(&di.src, &dev->src);
-+ bacpy(&di.dst, &dev->dst);
-+
-+ if (copy_to_user((void *)arg, &di, sizeof(di)))
-+ err = -EFAULT;
-+
-+ rfcomm_dev_put(dev);
-+ return err;
-+}
-+
-+int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
-+{
-+ BT_DBG("cmd %d arg %ld", cmd, arg);
-+
-+ switch (cmd) {
-+ case RFCOMMCREATEDEV:
-+ return rfcomm_create_dev(sk, arg);
-+
-+ case RFCOMMRELEASEDEV:
-+ return rfcomm_release_dev(arg);
-+
-+ case RFCOMMGETDEVLIST:
-+ return rfcomm_get_dev_list(arg);
-+
-+ case RFCOMMGETDEVINFO:
-+ return rfcomm_get_dev_info(arg);
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+/* ---- DLC callbacks ---- */
-+static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
-+{
-+ struct rfcomm_dev *dev = dlc->owner;
-+ struct tty_struct *tty;
-+
-+ if (!dev || !(tty = dev->tty)) {
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len);
-+
-+ if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
-+ register int i;
-+ for (i = 0; i < skb->len; i++) {
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+ tty_flip_buffer_push(tty);
-+
-+ tty_insert_flip_char(tty, skb->data[i], 0);
-+ }
-+ tty_flip_buffer_push(tty);
-+ } else
-+ tty->ldisc.receive_buf(tty, skb->data, NULL, skb->len);
-+
-+ kfree_skb(skb);
-+}
-+
-+static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
-+{
-+ struct rfcomm_dev *dev = dlc->owner;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("dlc %p dev %p err %d", dlc, dev, err);
-+
-+ dev->err = err;
-+ wake_up_interruptible(&dev->wait);
-+
-+ if (dlc->state == BT_CLOSED) {
-+ if (!dev->tty) {
-+ if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
-+ rfcomm_dev_hold(dev);
-+ rfcomm_dev_del(dev);
-+
-+ /* We have to drop DLC lock here, otherwise
-+ rfcomm_dev_put() will dead lock if it's
-+ the last reference. */
-+ rfcomm_dlc_unlock(dlc);
-+ rfcomm_dev_put(dev);
-+ rfcomm_dlc_lock(dlc);
-+ }
-+ } else
-+ tty_hangup(dev->tty);
-+ }
-+}
-+
-+static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
-+{
-+ struct rfcomm_dev *dev = dlc->owner;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig);
-+
-+ dev->modem_status =
-+ ((v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0) |
-+ ((v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0) |
-+ ((v24_sig & RFCOMM_V24_IC) ? TIOCM_RI : 0) |
-+ ((v24_sig & RFCOMM_V24_DV) ? TIOCM_CD : 0);
-+}
-+
-+/* ---- TTY functions ---- */
-+static void rfcomm_tty_wakeup(unsigned long arg)
-+{
-+ struct rfcomm_dev *dev = (void *) arg;
-+ struct tty_struct *tty = dev->tty;
-+ if (!tty)
-+ return;
-+
-+ BT_DBG("dev %p tty %p", dev, tty);
-+
-+ if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
-+ (tty->ldisc.write_wakeup)(tty);
-+
-+ wake_up_interruptible(&tty->write_wait);
-+#ifdef SERIAL_HAVE_POLL_WAIT
-+ wake_up_interruptible(&tty->poll_wait);
-+#endif
-+}
-+
-+static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct rfcomm_dev *dev;
-+ struct rfcomm_dlc *dlc;
-+ int err, id;
-+
-+ id = MINOR(tty->device) - tty->driver.minor_start;
-+
-+ BT_DBG("tty %p id %d", tty, id);
-+
-+ /* We don't leak this refcount. For reasons which are not entirely
-+ clear, the TTY layer will call our ->close() method even if the
-+ open fails. We decrease the refcount there, and decreasing it
-+ here too would cause breakage. */
-+ dev = rfcomm_dev_get(id);
-+ if (!dev)
-+ return -ENODEV;
-+
-+ BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst), dev->channel, dev->opened);
-+
-+ if (dev->opened++ != 0)
-+ return 0;
-+
-+ dlc = dev->dlc;
-+
-+ /* Attach TTY and open DLC */
-+
-+ rfcomm_dlc_lock(dlc);
-+ tty->driver_data = dev;
-+ dev->tty = tty;
-+ rfcomm_dlc_unlock(dlc);
-+ set_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
-+
-+ err = rfcomm_dlc_open(dlc, &dev->src, &dev->dst, dev->channel);
-+ if (err < 0)
-+ return err;
-+
-+ /* Wait for DLC to connect */
-+ add_wait_queue(&dev->wait, &wait);
-+ while (1) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (dlc->state == BT_CLOSED) {
-+ err = -dev->err;
-+ break;
-+ }
-+
-+ if (dlc->state == BT_CONNECTED)
-+ break;
-+
-+ if (signal_pending(current)) {
-+ err = -EINTR;
-+ break;
-+ }
-+
-+ schedule();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&dev->wait, &wait);
-+
-+ return err;
-+}
-+
-+static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, dev->opened);
-+
-+ if (--dev->opened == 0) {
-+ /* Close DLC and dettach TTY */
-+ rfcomm_dlc_close(dev->dlc, 0);
-+
-+ clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
-+ tasklet_kill(&dev->wakeup_task);
-+
-+ rfcomm_dlc_lock(dev->dlc);
-+ tty->driver_data = NULL;
-+ dev->tty = NULL;
-+ rfcomm_dlc_unlock(dev->dlc);
-+ }
-+
-+ rfcomm_dev_put(dev);
-+}
-+
-+static int rfcomm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+ struct sk_buff *skb;
-+ int err = 0, sent = 0, size;
-+
-+ BT_DBG("tty %p from_user %d count %d", tty, from_user, count);
-+
-+ while (count) {
-+ size = min_t(uint, count, dlc->mtu);
-+
-+ if (from_user)
-+ skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, 0, GFP_KERNEL);
-+ else
-+ skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, 0, GFP_ATOMIC);
-+
-+ if (!skb)
-+ break;
-+
-+ skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
-+
-+ if (from_user)
-+ copy_from_user(skb_put(skb, size), buf + sent, size);
-+ else
-+ memcpy(skb_put(skb, size), buf + sent, size);
-+
-+ if ((err = rfcomm_dlc_send(dlc, skb)) < 0) {
-+ kfree_skb(skb);
-+ break;
-+ }
-+
-+ sent += size;
-+ count -= size;
-+ }
-+
-+ return sent ? sent : err;
-+}
-+
-+static void rfcomm_tty_put_char(struct tty_struct *tty, unsigned char ch)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+ struct sk_buff *skb;
-+
-+ BT_DBG("tty %p char %x", tty, ch);
-+
-+ skb = rfcomm_wmalloc(dev, 1 + RFCOMM_SKB_RESERVE, 1, GFP_ATOMIC);
-+
-+ if (!skb)
-+ return;
-+
-+ skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
-+
-+ *(char *)skb_put(skb, 1) = ch;
-+
-+ if ((rfcomm_dlc_send(dlc, skb)) < 0)
-+ kfree_skb(skb);
-+}
-+
-+static int rfcomm_tty_write_room(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ int room;
-+
-+ BT_DBG("tty %p", tty);
-+
-+ room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc);
-+ if (room < 0)
-+ room = 0;
-+
-+ return room;
-+}
-+
-+static int rfcomm_tty_set_modem_status(uint cmd, struct rfcomm_dlc *dlc, uint status)
-+{
-+ u8 v24_sig, mask;
-+
-+ BT_DBG("dlc %p cmd 0x%02x", dlc, cmd);
-+
-+ if (cmd == TIOCMSET)
-+ v24_sig = 0;
-+ else
-+ rfcomm_dlc_get_modem_status(dlc, &v24_sig);
-+
-+ mask = ((status & TIOCM_DSR) ? RFCOMM_V24_RTC : 0) |
-+ ((status & TIOCM_DTR) ? RFCOMM_V24_RTC : 0) |
-+ ((status & TIOCM_RTS) ? RFCOMM_V24_RTR : 0) |
-+ ((status & TIOCM_CTS) ? RFCOMM_V24_RTR : 0) |
-+ ((status & TIOCM_RI) ? RFCOMM_V24_IC : 0) |
-+ ((status & TIOCM_CD) ? RFCOMM_V24_DV : 0);
-+
-+ if (cmd == TIOCMBIC)
-+ v24_sig &= ~mask;
-+ else
-+ v24_sig |= mask;
-+
-+ rfcomm_dlc_set_modem_status(dlc, v24_sig);
-+ return 0;
-+}
-+
-+static int rfcomm_tty_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+ uint status;
-+ int err;
-+
-+ BT_DBG("tty %p cmd 0x%02x", tty, cmd);
-+
-+ switch (cmd) {
-+ case TCGETS:
-+ BT_DBG("TCGETS is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TCSETS:
-+ BT_DBG("TCSETS is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCMGET:
-+ BT_DBG("TIOCMGET");
-+
-+ return put_user(dev->modem_status, (unsigned int *)arg);
-+
-+ case TIOCMSET: /* Turns on and off the lines as specified by the mask */
-+ case TIOCMBIS: /* Turns on the lines as specified by the mask */
-+ case TIOCMBIC: /* Turns off the lines as specified by the mask */
-+ if ((err = get_user(status, (unsigned int *)arg)))
-+ return err;
-+ return rfcomm_tty_set_modem_status(cmd, dlc, status);
-+
-+ case TIOCMIWAIT:
-+ BT_DBG("TIOCMIWAIT");
-+ break;
-+
-+ case TIOCGICOUNT:
-+ BT_DBG("TIOCGICOUNT");
-+ break;
-+
-+ case TIOCGSERIAL:
-+ BT_ERR("TIOCGSERIAL is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCSSERIAL:
-+ BT_ERR("TIOCSSERIAL is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCSERGSTRUCT:
-+ BT_ERR("TIOCSERGSTRUCT is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCSERGETLSR:
-+ BT_ERR("TIOCSERGETLSR is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCSERCONFIG:
-+ BT_ERR("TIOCSERCONFIG is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ default:
-+ return -ENOIOCTLCMD; /* ioctls which we must ignore */
-+
-+ }
-+
-+ return -ENOIOCTLCMD;
-+}
-+
-+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-+
-+static void rfcomm_tty_set_termios(struct tty_struct *tty, struct termios *old)
-+{
-+ BT_DBG("tty %p", tty);
-+
-+ if ((tty->termios->c_cflag == old->c_cflag) &&
-+ (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old->c_iflag)))
-+ return;
-+
-+ /* handle turning off CRTSCTS */
-+ if ((old->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) {
-+ BT_DBG("turning off CRTSCTS");
-+ }
-+}
-+
-+static void rfcomm_tty_throttle(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ rfcomm_dlc_throttle(dev->dlc);
-+}
-+
-+static void rfcomm_tty_unthrottle(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ rfcomm_dlc_unthrottle(dev->dlc);
-+}
-+
-+static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ if (skb_queue_len(&dlc->tx_queue))
-+ return dlc->mtu;
-+
-+ return 0;
-+}
-+
-+static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ skb_queue_purge(&dev->dlc->tx_queue);
-+
-+ if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
-+ tty->ldisc.write_wakeup(tty);
-+}
-+
-+static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
-+{
-+ BT_DBG("tty %p ch %c", tty, ch);
-+}
-+
-+static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
-+{
-+ BT_DBG("tty %p timeout %d", tty, timeout);
-+}
-+
-+static void rfcomm_tty_hangup(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ rfcomm_tty_flush_buffer(tty);
-+
-+ if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
-+ rfcomm_dev_del(dev);
-+}
-+
-+static int rfcomm_tty_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *unused)
-+{
-+ return 0;
-+}
-+
-+/* ---- TTY structure ---- */
-+static int rfcomm_tty_refcount; /* If we manage several devices */
-+
-+static struct tty_struct *rfcomm_tty_table[RFCOMM_TTY_PORTS];
-+static struct termios *rfcomm_tty_termios[RFCOMM_TTY_PORTS];
-+static struct termios *rfcomm_tty_termios_locked[RFCOMM_TTY_PORTS];
-+
-+static struct tty_driver rfcomm_tty_driver = {
-+ magic: TTY_DRIVER_MAGIC,
-+ driver_name: "rfcomm",
-+#ifdef CONFIG_DEVFS_FS
-+ name: "bluetooth/rfcomm/%d",
-+#else
-+ name: "rfcomm",
-+#endif
-+ major: RFCOMM_TTY_MAJOR,
-+ minor_start: RFCOMM_TTY_MINOR,
-+ num: RFCOMM_TTY_PORTS,
-+ type: TTY_DRIVER_TYPE_SERIAL,
-+ subtype: SERIAL_TYPE_NORMAL,
-+ flags: TTY_DRIVER_REAL_RAW,
-+
-+ refcount: &rfcomm_tty_refcount,
-+ table: rfcomm_tty_table,
-+ termios: rfcomm_tty_termios,
-+ termios_locked: rfcomm_tty_termios_locked,
-+
-+ open: rfcomm_tty_open,
-+ close: rfcomm_tty_close,
-+ put_char: rfcomm_tty_put_char,
-+ write: rfcomm_tty_write,
-+ write_room: rfcomm_tty_write_room,
-+ chars_in_buffer: rfcomm_tty_chars_in_buffer,
-+ flush_buffer: rfcomm_tty_flush_buffer,
-+ ioctl: rfcomm_tty_ioctl,
-+ throttle: rfcomm_tty_throttle,
-+ unthrottle: rfcomm_tty_unthrottle,
-+ set_termios: rfcomm_tty_set_termios,
-+ send_xchar: rfcomm_tty_send_xchar,
-+ stop: NULL,
-+ start: NULL,
-+ hangup: rfcomm_tty_hangup,
-+ wait_until_sent: rfcomm_tty_wait_until_sent,
-+ read_proc: rfcomm_tty_read_proc,
-+};
-+
-+int rfcomm_init_ttys(void)
-+{
-+ int i;
-+
-+ /* Initalize our global data */
-+ for (i = 0; i < RFCOMM_TTY_PORTS; i++)
-+ rfcomm_tty_table[i] = NULL;
-+
-+ /* Register the TTY driver */
-+ rfcomm_tty_driver.init_termios = tty_std_termios;
-+ rfcomm_tty_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-+ rfcomm_tty_driver.flags = TTY_DRIVER_REAL_RAW;
-+
-+ if (tty_register_driver(&rfcomm_tty_driver)) {
-+ BT_ERR("Can't register RFCOMM TTY driver");
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+void rfcomm_cleanup_ttys(void)
-+{
-+ tty_unregister_driver(&rfcomm_tty_driver);
-+ return;
-+}
-diff -urN linux-2.4.18/net/bluetooth/sco.c linux-2.4.18-mh15/net/bluetooth/sco.c
---- linux-2.4.18/net/bluetooth/sco.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/sco.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,1019 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * BlueZ SCO sockets.
-+ *
-+ * $Id$
-+ */
-+#define VERSION "0.3"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/socket.h>
-+#include <linux/skbuff.h>
-+#include <linux/proc_fs.h>
-+#include <linux/list.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include <net/bluetooth/sco.h>
-+
-+#ifndef SCO_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+static struct proto_ops sco_sock_ops;
-+
-+static struct bluez_sock_list sco_sk_list = {
-+ lock: RW_LOCK_UNLOCKED
-+};
-+
-+static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
-+static void sco_chan_del(struct sock *sk, int err);
-+static inline struct sock * sco_chan_get(struct sco_conn *conn);
-+
-+static int sco_conn_del(struct hci_conn *conn, int err);
-+
-+static void sco_sock_close(struct sock *sk);
-+static void sco_sock_kill(struct sock *sk);
-+
-+/* ----- SCO timers ------ */
-+static void sco_sock_timeout(unsigned long arg)
-+{
-+ struct sock *sk = (struct sock *) arg;
-+
-+ BT_DBG("sock %p state %d", sk, sk->state);
-+
-+ bh_lock_sock(sk);
-+ sk->err = ETIMEDOUT;
-+ sk->state_change(sk);
-+ bh_unlock_sock(sk);
-+
-+ sco_sock_kill(sk);
-+ sock_put(sk);
-+}
-+
-+static void sco_sock_set_timer(struct sock *sk, long timeout)
-+{
-+ BT_DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
-+
-+ if (!mod_timer(&sk->timer, jiffies + timeout))
-+ sock_hold(sk);
-+}
-+
-+static void sco_sock_clear_timer(struct sock *sk)
-+{
-+ BT_DBG("sock %p state %d", sk, sk->state);
-+
-+ if (timer_pending(&sk->timer) && del_timer(&sk->timer))
-+ __sock_put(sk);
-+}
-+
-+static void sco_sock_init_timer(struct sock *sk)
-+{
-+ init_timer(&sk->timer);
-+ sk->timer.function = sco_sock_timeout;
-+ sk->timer.data = (unsigned long)sk;
-+}
-+
-+/* -------- SCO connections --------- */
-+static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status)
-+{
-+ struct hci_dev *hdev = hcon->hdev;
-+ struct sco_conn *conn;
-+
-+ if ((conn = hcon->sco_data))
-+ return conn;
-+
-+ if (status)
-+ return conn;
-+
-+ if (!(conn = kmalloc(sizeof(struct sco_conn), GFP_ATOMIC)))
-+ return NULL;
-+ memset(conn, 0, sizeof(struct sco_conn));
-+
-+ spin_lock_init(&conn->lock);
-+
-+ hcon->sco_data = conn;
-+ conn->hcon = hcon;
-+
-+ conn->src = &hdev->bdaddr;
-+ conn->dst = &hcon->dst;
-+
-+ if (hdev->sco_mtu > 0)
-+ conn->mtu = hdev->sco_mtu;
-+ else
-+ conn->mtu = 60;
-+
-+ BT_DBG("hcon %p conn %p", hcon, conn);
-+
-+ MOD_INC_USE_COUNT;
-+ return conn;
-+}
-+
-+static int sco_conn_del(struct hci_conn *hcon, int err)
-+{
-+ struct sco_conn *conn;
-+ struct sock *sk;
-+
-+ if (!(conn = hcon->sco_data))
-+ return 0;
-+
-+ BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
-+
-+ /* Kill socket */
-+ if ((sk = sco_chan_get(conn))) {
-+ bh_lock_sock(sk);
-+ sco_sock_clear_timer(sk);
-+ sco_chan_del(sk, err);
-+ bh_unlock_sock(sk);
-+ sco_sock_kill(sk);
-+ }
-+
-+ hcon->sco_data = NULL;
-+ kfree(conn);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+int sco_connect(struct sock *sk)
-+{
-+ bdaddr_t *src = &bluez_pi(sk)->src;
-+ bdaddr_t *dst = &bluez_pi(sk)->dst;
-+ struct sco_conn *conn;
-+ struct hci_conn *hcon;
-+ struct hci_dev *hdev;
-+ int err = 0;
-+
-+ BT_DBG("%s -> %s", batostr(src), batostr(dst));
-+
-+ if (!(hdev = hci_get_route(dst, src)))
-+ return -EHOSTUNREACH;
-+
-+ hci_dev_lock_bh(hdev);
-+
-+ err = -ENOMEM;
-+
-+ hcon = hci_connect(hdev, SCO_LINK, dst);
-+ if (!hcon)
-+ goto done;
-+
-+ conn = sco_conn_add(hcon, 0);
-+ if (!conn) {
-+ hci_conn_put(hcon);
-+ goto done;
-+ }
-+
-+ /* Update source addr of the socket */
-+ bacpy(src, conn->src);
-+
-+ err = sco_chan_add(conn, sk, NULL);
-+ if (err)
-+ goto done;
-+
-+ if (hcon->state == BT_CONNECTED) {
-+ sco_sock_clear_timer(sk);
-+ sk->state = BT_CONNECTED;
-+ } else {
-+ sk->state = BT_CONNECT;
-+ sco_sock_set_timer(sk, sk->sndtimeo);
-+ }
-+done:
-+ hci_dev_unlock_bh(hdev);
-+ hci_dev_put(hdev);
-+ return err;
-+}
-+
-+static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
-+{
-+ struct sco_conn *conn = sco_pi(sk)->conn;
-+ struct sk_buff *skb;
-+ int err, count;
-+
-+ /* Check outgoing MTU */
-+ if (len > conn->mtu)
-+ return -EINVAL;
-+
-+ BT_DBG("sk %p len %d", sk, len);
-+
-+ count = MIN(conn->mtu, len);
-+ if (!(skb = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err)))
-+ return err;
-+
-+ if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
-+ err = -EFAULT;
-+ goto fail;
-+ }
-+
-+ if ((err = hci_send_sco(conn->hcon, skb)) < 0)
-+ goto fail;
-+
-+ return count;
-+
-+fail:
-+ kfree_skb(skb);
-+ return err;
-+}
-+
-+static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
-+{
-+ struct sock *sk = sco_chan_get(conn);
-+
-+ if (!sk)
-+ goto drop;
-+
-+ BT_DBG("sk %p len %d", sk, skb->len);
-+
-+ if (sk->state != BT_CONNECTED)
-+ goto drop;
-+
-+ if (!sock_queue_rcv_skb(sk, skb))
-+ return;
-+
-+drop:
-+ kfree_skb(skb);
-+ return;
-+}
-+
-+/* -------- Socket interface ---------- */
-+static struct sock *__sco_get_sock_by_addr(bdaddr_t *ba)
-+{
-+ struct sock *sk;
-+
-+ for (sk = sco_sk_list.head; sk; sk = sk->next) {
-+ if (!bacmp(&bluez_pi(sk)->src, ba))
-+ break;
-+ }
-+
-+ return sk;
-+}
-+
-+/* Find socket listening on source bdaddr.
-+ * Returns closest match.
-+ */
-+static struct sock *sco_get_sock_listen(bdaddr_t *src)
-+{
-+ struct sock *sk, *sk1 = NULL;
-+
-+ read_lock(&sco_sk_list.lock);
-+
-+ for (sk = sco_sk_list.head; sk; sk = sk->next) {
-+ if (sk->state != BT_LISTEN)
-+ continue;
-+
-+ /* Exact match. */
-+ if (!bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+
-+ /* Closest match */
-+ if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
-+ sk1 = sk;
-+ }
-+
-+ read_unlock(&sco_sk_list.lock);
-+
-+ return sk ? sk : sk1;
-+}
-+
-+static void sco_sock_destruct(struct sock *sk)
-+{
-+ BT_DBG("sk %p", sk);
-+
-+ skb_queue_purge(&sk->receive_queue);
-+ skb_queue_purge(&sk->write_queue);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void sco_sock_cleanup_listen(struct sock *parent)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("parent %p", parent);
-+
-+ /* Close not yet accepted channels */
-+ while ((sk = bluez_accept_dequeue(parent, NULL))) {
-+ sco_sock_close(sk);
-+ sco_sock_kill(sk);
-+ }
-+
-+ parent->state = BT_CLOSED;
-+ parent->zapped = 1;
-+}
-+
-+/* Kill socket (only if zapped and orphan)
-+ * Must be called on unlocked socket.
-+ */
-+static void sco_sock_kill(struct sock *sk)
-+{
-+ if (!sk->zapped || sk->socket)
-+ return;
-+
-+ BT_DBG("sk %p state %d", sk, sk->state);
-+
-+ /* Kill poor orphan */
-+ bluez_sock_unlink(&sco_sk_list, sk);
-+ sk->dead = 1;
-+ sock_put(sk);
-+}
-+
-+/* Close socket.
-+ * Must be called on unlocked socket.
-+ */
-+static void sco_sock_close(struct sock *sk)
-+{
-+ struct sco_conn *conn;
-+
-+ sco_sock_clear_timer(sk);
-+
-+ lock_sock(sk);
-+
-+ conn = sco_pi(sk)->conn;
-+
-+ BT_DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
-+
-+ switch (sk->state) {
-+ case BT_LISTEN:
-+ sco_sock_cleanup_listen(sk);
-+ break;
-+
-+ case BT_CONNECTED:
-+ case BT_CONFIG:
-+ case BT_CONNECT:
-+ case BT_DISCONN:
-+ sco_chan_del(sk, ECONNRESET);
-+ break;
-+
-+ default:
-+ sk->zapped = 1;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+}
-+
-+static void sco_sock_init(struct sock *sk, struct sock *parent)
-+{
-+ BT_DBG("sk %p", sk);
-+
-+ if (parent)
-+ sk->type = parent->type;
-+}
-+
-+static struct sock *sco_sock_alloc(struct socket *sock, int proto, int prio)
-+{
-+ struct sock *sk;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
-+ return NULL;
-+
-+ bluez_sock_init(sock, sk);
-+
-+ sk->zapped = 0;
-+
-+ sk->destruct = sco_sock_destruct;
-+ sk->sndtimeo = SCO_CONN_TIMEOUT;
-+
-+ sk->protocol = proto;
-+ sk->state = BT_OPEN;
-+
-+ sco_sock_init_timer(sk);
-+
-+ bluez_sock_link(&sco_sk_list, sk);
-+
-+ MOD_INC_USE_COUNT;
-+ return sk;
-+}
-+
-+static int sco_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ sock->state = SS_UNCONNECTED;
-+
-+ if (sock->type != SOCK_SEQPACKET)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &sco_sock_ops;
-+
-+ if (!(sk = sco_sock_alloc(sock, protocol, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ sco_sock_init(sk, NULL);
-+ return 0;
-+}
-+
-+static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
-+{
-+ struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
-+ struct sock *sk = sock->sk;
-+ bdaddr_t *src = &sa->sco_bdaddr;
-+ int err = 0;
-+
-+ BT_DBG("sk %p %s", sk, batostr(&sa->sco_bdaddr));
-+
-+ if (!addr || addr->sa_family != AF_BLUETOOTH)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_OPEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ write_lock_bh(&sco_sk_list.lock);
-+
-+ if (bacmp(src, BDADDR_ANY) && __sco_get_sock_by_addr(src)) {
-+ err = -EADDRINUSE;
-+ } else {
-+ /* Save source address */
-+ bacpy(&bluez_pi(sk)->src, &sa->sco_bdaddr);
-+ sk->state = BT_BOUND;
-+ }
-+
-+ write_unlock_bh(&sco_sk_list.lock);
-+
-+done:
-+ release_sock(sk);
-+
-+ return err;
-+}
-+
-+static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
-+{
-+ struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_sco))
-+ return -EINVAL;
-+
-+ if (sk->state != BT_OPEN && sk->state != BT_BOUND)
-+ return -EBADFD;
-+
-+ if (sk->type != SOCK_SEQPACKET)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ /* Set destination address and psm */
-+ bacpy(&bluez_pi(sk)->dst, &sa->sco_bdaddr);
-+
-+ if ((err = sco_connect(sk)))
-+ goto done;
-+
-+ err = bluez_sock_wait_state(sk, BT_CONNECTED,
-+ sock_sndtimeo(sk, flags & O_NONBLOCK));
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int sco_sock_listen(struct socket *sock, int backlog)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p backlog %d", sk, backlog);
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ sk->max_ack_backlog = backlog;
-+ sk->ack_backlog = 0;
-+ sk->state = BT_LISTEN;
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct sock *sk = sock->sk, *ch;
-+ long timeo;
-+ int err = 0;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
-+
-+ BT_DBG("sk %p timeo %ld", sk, timeo);
-+
-+ /* Wait for an incoming connection. (wake-one). */
-+ add_wait_queue_exclusive(sk->sleep, &wait);
-+ while (!(ch = bluez_accept_dequeue(sk, newsock))) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ break;
-+ }
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ break;
-+ }
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ if (err)
-+ goto done;
-+
-+ newsock->state = SS_CONNECTED;
-+
-+ BT_DBG("new socket %p", ch);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
-+{
-+ struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ addr->sa_family = AF_BLUETOOTH;
-+ *len = sizeof(struct sockaddr_sco);
-+
-+ if (peer)
-+ bacpy(&sa->sco_bdaddr, &bluez_pi(sk)->dst);
-+ else
-+ bacpy(&sa->sco_bdaddr, &bluez_pi(sk)->src);
-+
-+ return 0;
-+}
-+
-+static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (sk->err)
-+ return sock_error(sk);
-+
-+ if (msg->msg_flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state == BT_CONNECTED)
-+ err = sco_send_frame(sk, msg, len);
-+ else
-+ err = -ENOTCONN;
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int sco_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int sco_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ struct sco_options opts;
-+ struct sco_conninfo cinfo;
-+ int len, err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (get_user(len, optlen))
-+ return -EFAULT;
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ case SCO_OPTIONS:
-+ if (sk->state != BT_CONNECTED) {
-+ err = -ENOTCONN;
-+ break;
-+ }
-+
-+ opts.mtu = sco_pi(sk)->conn->mtu;
-+
-+ BT_DBG("mtu %d", opts.mtu);
-+
-+ len = MIN(len, sizeof(opts));
-+ if (copy_to_user(optval, (char *)&opts, len))
-+ err = -EFAULT;
-+
-+ break;
-+
-+ case SCO_CONNINFO:
-+ if (sk->state != BT_CONNECTED) {
-+ err = -ENOTCONN;
-+ break;
-+ }
-+
-+ cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
-+
-+ len = MIN(len, sizeof(cinfo));
-+ if (copy_to_user(optval, (char *)&cinfo, len))
-+ err = -EFAULT;
-+
-+ break;
-+
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int sco_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ sco_sock_close(sk);
-+ if (sk->linger) {
-+ lock_sock(sk);
-+ err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
-+ release_sock(sk);
-+ }
-+
-+ sock_orphan(sk);
-+ sco_sock_kill(sk);
-+ return err;
-+}
-+
-+static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
-+{
-+ BT_DBG("conn %p", conn);
-+
-+ sco_pi(sk)->conn = conn;
-+ conn->sk = sk;
-+
-+ if (parent)
-+ bluez_accept_enqueue(parent, sk);
-+}
-+
-+static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
-+{
-+ int err = 0;
-+
-+ sco_conn_lock(conn);
-+ if (conn->sk) {
-+ err = -EBUSY;
-+ } else {
-+ __sco_chan_add(conn, sk, parent);
-+ }
-+ sco_conn_unlock(conn);
-+ return err;
-+}
-+
-+static inline struct sock * sco_chan_get(struct sco_conn *conn)
-+{
-+ struct sock *sk = NULL;
-+ sco_conn_lock(conn);
-+ sk = conn->sk;
-+ sco_conn_unlock(conn);
-+ return sk;
-+}
-+
-+/* Delete channel.
-+ * Must be called on the locked socket. */
-+static void sco_chan_del(struct sock *sk, int err)
-+{
-+ struct sco_conn *conn;
-+
-+ conn = sco_pi(sk)->conn;
-+
-+ BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
-+
-+ if (conn) {
-+ sco_conn_lock(conn);
-+ conn->sk = NULL;
-+ sco_pi(sk)->conn = NULL;
-+ sco_conn_unlock(conn);
-+ hci_conn_put(conn->hcon);
-+ }
-+
-+ sk->state = BT_CLOSED;
-+ sk->err = err;
-+ sk->state_change(sk);
-+
-+ sk->zapped = 1;
-+}
-+
-+static void sco_conn_ready(struct sco_conn *conn)
-+{
-+ struct sock *parent, *sk;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ sco_conn_lock(conn);
-+
-+ if ((sk = conn->sk)) {
-+ sco_sock_clear_timer(sk);
-+ bh_lock_sock(sk);
-+ sk->state = BT_CONNECTED;
-+ sk->state_change(sk);
-+ bh_unlock_sock(sk);
-+ } else {
-+ parent = sco_get_sock_listen(conn->src);
-+ if (!parent)
-+ goto done;
-+
-+ bh_lock_sock(parent);
-+
-+ sk = sco_sock_alloc(NULL, BTPROTO_SCO, GFP_ATOMIC);
-+ if (!sk) {
-+ bh_unlock_sock(parent);
-+ goto done;
-+ }
-+
-+ sco_sock_init(sk, parent);
-+
-+ bacpy(&bluez_pi(sk)->src, conn->src);
-+ bacpy(&bluez_pi(sk)->dst, conn->dst);
-+
-+ hci_conn_hold(conn->hcon);
-+ __sco_chan_add(conn, sk, parent);
-+
-+ sk->state = BT_CONNECTED;
-+
-+ /* Wake up parent */
-+ parent->data_ready(parent, 1);
-+
-+ bh_unlock_sock(parent);
-+ }
-+
-+done:
-+ sco_conn_unlock(conn);
-+}
-+
-+/* ----- SCO interface with lower layer (HCI) ----- */
-+int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
-+{
-+ BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
-+
-+ /* Always accept connection */
-+ return HCI_LM_ACCEPT;
-+}
-+
-+int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
-+{
-+ BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
-+
-+ if (hcon->type != SCO_LINK)
-+ return 0;
-+
-+ if (!status) {
-+ struct sco_conn *conn;
-+
-+ conn = sco_conn_add(hcon, status);
-+ if (conn)
-+ sco_conn_ready(conn);
-+ } else
-+ sco_conn_del(hcon, bterr(status));
-+
-+ return 0;
-+}
-+
-+int sco_disconn_ind(struct hci_conn *hcon, __u8 reason)
-+{
-+ BT_DBG("hcon %p reason %d", hcon, reason);
-+
-+ if (hcon->type != SCO_LINK)
-+ return 0;
-+
-+ sco_conn_del(hcon, bterr(reason));
-+ return 0;
-+}
-+
-+int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
-+{
-+ struct sco_conn *conn = hcon->sco_data;
-+
-+ if (!conn)
-+ goto drop;
-+
-+ BT_DBG("conn %p len %d", conn, skb->len);
-+
-+ if (skb->len) {
-+ sco_recv_frame(conn, skb);
-+ return 0;
-+ }
-+
-+drop:
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+/* ----- Proc fs support ------ */
-+static int sco_sock_dump(char *buf, struct bluez_sock_list *list)
-+{
-+ struct sco_pinfo *pi;
-+ struct sock *sk;
-+ char *ptr = buf;
-+
-+ write_lock_bh(&list->lock);
-+
-+ for (sk = list->head; sk; sk = sk->next) {
-+ pi = sco_pi(sk);
-+ ptr += sprintf(ptr, "%s %s %d\n",
-+ batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
-+ sk->state);
-+ }
-+
-+ write_unlock_bh(&list->lock);
-+
-+ ptr += sprintf(ptr, "\n");
-+
-+ return ptr - buf;
-+}
-+
-+static int sco_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
-+{
-+ char *ptr = buf;
-+ int len;
-+
-+ BT_DBG("count %d, offset %ld", count, offset);
-+
-+ ptr += sco_sock_dump(ptr, &sco_sk_list);
-+ len = ptr - buf;
-+
-+ if (len <= count + offset)
-+ *eof = 1;
-+
-+ *start = buf + offset;
-+ len -= offset;
-+
-+ if (len > count)
-+ len = count;
-+ if (len < 0)
-+ len = 0;
-+
-+ return len;
-+}
-+
-+static struct proto_ops sco_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: sco_sock_release,
-+ bind: sco_sock_bind,
-+ connect: sco_sock_connect,
-+ listen: sco_sock_listen,
-+ accept: sco_sock_accept,
-+ getname: sco_sock_getname,
-+ sendmsg: sco_sock_sendmsg,
-+ recvmsg: bluez_sock_recvmsg,
-+ poll: bluez_sock_poll,
-+ socketpair: sock_no_socketpair,
-+ ioctl: sock_no_ioctl,
-+ shutdown: sock_no_shutdown,
-+ setsockopt: sco_sock_setsockopt,
-+ getsockopt: sco_sock_getsockopt,
-+ mmap: sock_no_mmap
-+};
-+
-+static struct net_proto_family sco_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: sco_sock_create
-+};
-+
-+static struct hci_proto sco_hci_proto = {
-+ name: "SCO",
-+ id: HCI_PROTO_SCO,
-+ connect_ind: sco_connect_ind,
-+ connect_cfm: sco_connect_cfm,
-+ disconn_ind: sco_disconn_ind,
-+ recv_scodata: sco_recv_scodata,
-+};
-+
-+int __init sco_init(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_SCO, &sco_sock_family_ops))) {
-+ BT_ERR("Can't register SCO socket layer");
-+ return err;
-+ }
-+
-+ if ((err = hci_register_proto(&sco_hci_proto))) {
-+ BT_ERR("Can't register SCO protocol");
-+ return err;
-+ }
-+
-+ create_proc_read_entry("bluetooth/sco", 0, 0, sco_read_proc, NULL);
-+
-+ BT_INFO("BlueZ SCO ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ return 0;
-+}
-+
-+void sco_cleanup(void)
-+{
-+ int err;
-+
-+ remove_proc_entry("bluetooth/sco", NULL);
-+
-+ /* Unregister socket, protocol and notifier */
-+ if ((err = bluez_sock_unregister(BTPROTO_SCO)))
-+ BT_ERR("Can't unregister SCO socket layer %d", err);
-+
-+ if ((err = hci_unregister_proto(&sco_hci_proto)))
-+ BT_ERR("Can't unregister SCO protocol %d", err);
-+}
-+
-+module_init(sco_init);
-+module_exit(sco_cleanup);
-+
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
-+MODULE_DESCRIPTION("BlueZ SCO ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/syms.c linux-2.4.18-mh15/net/bluetooth/syms.c
---- linux-2.4.18/net/bluetooth/syms.c 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/net/bluetooth/syms.c 2004-08-01 16:26:23.000000000 +0200
-@@ -25,7 +25,7 @@
- /*
- * BlueZ symbols.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
-@@ -39,25 +39,28 @@
- #include <linux/socket.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
-
- /* HCI Core */
- EXPORT_SYMBOL(hci_register_dev);
- EXPORT_SYMBOL(hci_unregister_dev);
-+EXPORT_SYMBOL(hci_suspend_dev);
-+EXPORT_SYMBOL(hci_resume_dev);
-+
- EXPORT_SYMBOL(hci_register_proto);
- EXPORT_SYMBOL(hci_unregister_proto);
--EXPORT_SYMBOL(hci_register_notifier);
--EXPORT_SYMBOL(hci_unregister_notifier);
-
-+EXPORT_SYMBOL(hci_get_route);
- EXPORT_SYMBOL(hci_connect);
--EXPORT_SYMBOL(hci_disconnect);
- EXPORT_SYMBOL(hci_dev_get);
-+EXPORT_SYMBOL(hci_conn_auth);
-+EXPORT_SYMBOL(hci_conn_encrypt);
-
- EXPORT_SYMBOL(hci_recv_frame);
- EXPORT_SYMBOL(hci_send_acl);
- EXPORT_SYMBOL(hci_send_sco);
--EXPORT_SYMBOL(hci_send_raw);
-+EXPORT_SYMBOL(hci_send_cmd);
-+EXPORT_SYMBOL(hci_si_event);
-
- /* BlueZ lib */
- EXPORT_SYMBOL(bluez_dump);
-@@ -68,5 +71,11 @@
- /* BlueZ sockets */
- EXPORT_SYMBOL(bluez_sock_register);
- EXPORT_SYMBOL(bluez_sock_unregister);
-+EXPORT_SYMBOL(bluez_sock_init);
- EXPORT_SYMBOL(bluez_sock_link);
- EXPORT_SYMBOL(bluez_sock_unlink);
-+EXPORT_SYMBOL(bluez_sock_recvmsg);
-+EXPORT_SYMBOL(bluez_sock_poll);
-+EXPORT_SYMBOL(bluez_accept_enqueue);
-+EXPORT_SYMBOL(bluez_accept_dequeue);
-+EXPORT_SYMBOL(bluez_sock_wait_state);
-diff -urN linux-2.4.18/net/netsyms.c linux-2.4.18-mh15/net/netsyms.c
---- linux-2.4.18/net/netsyms.c 2002-02-25 20:38:14.000000000 +0100
-+++ linux-2.4.18-mh15/net/netsyms.c 2004-08-01 16:26:23.000000000 +0200
-@@ -159,6 +159,7 @@
- EXPORT_SYMBOL(put_cmsg);
- EXPORT_SYMBOL(sock_kmalloc);
- EXPORT_SYMBOL(sock_kfree_s);
-+EXPORT_SYMBOL(sockfd_lookup);
-
- #ifdef CONFIG_FILTER
- EXPORT_SYMBOL(sk_run_filter);
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bt950_cs.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bt950_cs.patch
deleted file mode 100644
index c29f0d02f2..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/bt950_cs.patch
+++ /dev/null
@@ -1,1174 +0,0 @@
-diff -Nur linux-orig/drivers/bluetooth/bt950_cs.c linux/drivers/bluetooth/bt950_cs.c
---- linux-orig/drivers/bluetooth/bt950_cs.c 1970-01-01 03:00:00.000000000 +0300
-+++ linux/drivers/bluetooth/bt950_cs.c 2004-02-04 09:55:04.000000000 +0300
-@@ -0,0 +1,1133 @@
-+/*
-+ *
-+ * Driver for Bluetooth cards with OXCF950 UART interface
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ * Albert Rybalkin <albertr@iral.com>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+
-+#ifdef CONFIG_MODVERSIONS
-+#ifndef MODVERSIONS
-+#define MODVERSIONS
-+#endif
-+#include <linux/modversions.h>
-+#endif
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+#include <linux/delay.h>
-+
-+#include <linux/skbuff.h>
-+#include <linux/string.h>
-+#include <linux/serial.h>
-+#include <linux/serial_reg.h>
-+#include <asm/system.h>
-+#include <asm/bitops.h>
-+#include <asm/io.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+/* Default baud rate: 57600, 115200, 230400 or 460800 */
-+#define DEFAULT_BAUD_RATE 460800
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0x86bc;
-+static int irq_list[4] = { -1 };
-+static long baud_rate = DEFAULT_BAUD_RATE;
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+MODULE_PARM(baud_rate, "l");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>, Albert Rybalkin <albertr@iral.com>");
-+MODULE_DESCRIPTION("BlueZ driver for Bluetooth cards with OXCF950 UART interface");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct bt950_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+} bt950_info_t;
-+
-+
-+static void bt950_config(dev_link_t *link);
-+static void bt950_release(u_long arg);
-+static int bt950_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "bt950_cs";
-+
-+static dev_link_t *bt950_attach(void);
-+static void bt950_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_WAITING 8
-+
-+/* Receiver states */
-+#define RECV_WAIT_PACKET_TYPE 0
-+#define RECV_WAIT_EVENT_HEADER 1
-+#define RECV_WAIT_ACL_HEADER 2
-+#define RECV_WAIT_SCO_HEADER 3
-+#define RECV_WAIT_DATA 4
-+
-+/* Special packet types */
-+#define PKT_BAUD_RATE_57600 0x80
-+#define PKT_BAUD_RATE_115200 0x81
-+#define PKT_BAUD_RATE_230400 0x82
-+#define PKT_BAUD_RATE_460800 0x83
-+
-+/* 950-specific stuff */
-+#define MAX_WAIT 0xFFFF
-+#define FIFO_SIZE 128
-+
-+#define TR_TX_INT 0x10 /* TTL: TX interrupt trigger level (0-127) */
-+#define TR_RX_INT 0x40 /* RTL: RX interrupt trigger level (1-127) */
-+#define TR_CTL_LO 0x08 /* FCL: auto flow control LOWER trigger level (0-127) */
-+#define TR_CTL_HI 0x60 /* FCH: auto flow control HIGH trigger level (1-127) */
-+
-+/* 950-specific registers and values we use. It should
-+ * eventually go to include/linux/serial_reg.h */
-+#define UART_IER_CTS 0x80 /* enable CTS interrupt */
-+#define UART_IER_RTS 0x40 /* enable RTS interrupt */
-+#define UART_IER_SLP 0x10 /* enable sleep mode */
-+#define UART_LCR_650 0xBF /* enable 650-compatible registers access */
-+#define UART_LSR_DE 0x80 /* data error */
-+#define UART_LSR_ERR (UART_LSR_OE|UART_LSR_PE|UART_LSR_FE|UART_LSR_BI|UART_LSR_DE)
-+#define UART_IIR_RXTOUT 0x0C /* RX timeout interrupt */
-+#define UART_IIR_CTSRTS 0x20 /* CTS or RTS change interrupt */
-+#define UART_IIR_RTS 0x40
-+#define UART_IIR_CTS 0x80
-+#define UART_IIR_MASK 0x3E /* interrupt mask */
-+#define UART_SRT 0x0D /* soft reset register */
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int bt950_write(unsigned int iobase, int fifo_size, const unsigned char *buf, int len)
-+{
-+ int i, actual = 0;
-+
-+ /* Activate DTR and RTS */
-+ outb(UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2, iobase + UART_MCR);
-+
-+ /* Wait for CTS flow control */
-+ for (i = MAX_WAIT; i; i--)
-+ if (inb(iobase + UART_MSR) & UART_MSR_CTS)
-+ break;
-+
-+ if (!i) {
-+ printk(KERN_WARNING "bt950_cs: Timeout waiting for CTS on write.\n");
-+ return 0;
-+ }
-+
-+ /* The TX FIFO should be empty */
-+ for (i = MAX_WAIT; i; i--)
-+ if (inb(iobase + UART_LSR) & UART_LSR_THRE)
-+ break;
-+
-+ if (!i) {
-+ printk(KERN_WARNING "bt950_cs: Timeout waiting for empty TX FIFO on write.\n");
-+ return 0;
-+ }
-+
-+ /* Fill FIFO with current frame */
-+ while ((fifo_size-- > 0) && (actual < len)) {
-+ /* Transmit next byte */
-+ outb(buf[actual], iobase + UART_TX);
-+ actual++;
-+ }
-+
-+ return actual;
-+}
-+
-+
-+static void bt950_write_wakeup(bt950_info_t *info)
-+{
-+ unsigned char lcr;
-+ unsigned int divisor;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bt950_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ clear_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ return;
-+
-+ if (!(skb = skb_dequeue(&(info->txq))))
-+ break;
-+
-+ if (skb->pkt_type & 0x80) {
-+ /* Disable RTS */
-+ outb((inb(iobase + UART_MCR) & ~UART_MCR_RTS), iobase + UART_MCR);
-+ }
-+
-+ /* Send frame */
-+ len = bt950_write(iobase, FIFO_SIZE, skb->data, skb->len);
-+
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (skb->pkt_type & 0x80) {
-+
-+ wait_queue_head_t wait;
-+
-+ switch (skb->pkt_type) {
-+
-+ case PKT_BAUD_RATE_460800:
-+ divisor = 1;
-+ break;
-+
-+ case PKT_BAUD_RATE_230400:
-+ divisor = 2;
-+ break;
-+
-+ case PKT_BAUD_RATE_115200:
-+ divisor = 4;
-+ break;
-+
-+ case PKT_BAUD_RATE_57600:
-+ /* Fall through... */
-+
-+ default:
-+ divisor = 8;
-+ break;
-+ }
-+
-+ /* Wait until the command reaches the baseband */
-+ init_waitqueue_head(&wait);
-+ interruptible_sleep_on_timeout(&wait, HZ / 10);
-+
-+ /* Set baud on baseband */
-+ /* Enable divisor latch access */
-+ lcr = inb(iobase + UART_LCR) & 0x3F;
-+ outb(lcr | UART_LCR_DLAB, iobase + UART_LCR);
-+
-+ /* Setup divisor latch */
-+ outb(divisor & 0x00FF, iobase + UART_DLL); /* divisor latch LOW byte */
-+ outb((divisor & 0xFF00) >> 8, iobase + UART_DLM); /* divisor latch HI byte */
-+
-+ /* Disable divisor latch access */
-+ outb(lcr, iobase + UART_LCR);
-+
-+ /* Enable RTS */
-+ outb((inb(iobase + UART_MCR) | UART_MCR_RTS), iobase + UART_MCR);
-+
-+ /* Wait before the next HCI packet can be send */
-+ interruptible_sleep_on_timeout(&wait, HZ);
-+
-+ }
-+
-+ if (len == skb->len) {
-+ kfree_skb(skb);
-+ } else {
-+ skb_pull(skb, len);
-+ skb_queue_head(&(info->txq), skb);
-+ }
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
-+
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+}
-+
-+
-+static inline void bt950_receive(bt950_info_t *info)
-+{
-+ unsigned int iobase;
-+ int boguscount = 0;
-+
-+ if (!info) {
-+ printk(KERN_ERR "bt950_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ /* Fixme: BUG? */
-+ inb(iobase + UART_MCR);
-+
-+ do {
-+ info->hdev.stat.byte_rx++;
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL) {
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_ERR "bt950_cs: Can't allocate mem for new packet.\n");
-+ return;
-+ }
-+ }
-+
-+ if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
-+
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type = inb(iobase + UART_RX);
-+
-+ switch (info->rx_skb->pkt_type) {
-+
-+ case HCI_EVENT_PKT:
-+ info->rx_state = RECV_WAIT_EVENT_HEADER;
-+ info->rx_count = HCI_EVENT_HDR_SIZE;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ info->rx_state = RECV_WAIT_ACL_HEADER;
-+ info->rx_count = HCI_ACL_HDR_SIZE;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ info->rx_state = RECV_WAIT_SCO_HEADER;
-+ info->rx_count = HCI_SCO_HDR_SIZE;
-+ break;
-+
-+ default:
-+ /* Unknown packet */
-+ printk(KERN_WARNING "bt950_cs: Unknown HCI packet with type 0x%02X received.\n", info->rx_skb->pkt_type);
-+ info->hdev.stat.err_rx++;
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ } else {
-+
-+ *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ int dlen;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+
-+
-+ switch (info->rx_state) {
-+
-+ case RECV_WAIT_EVENT_HEADER:
-+ eh = (hci_event_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = eh->plen;
-+ break;
-+
-+ case RECV_WAIT_ACL_HEADER:
-+ ah = (hci_acl_hdr *)(info->rx_skb->data);
-+ dlen = __le16_to_cpu(ah->dlen);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = dlen;
-+ break;
-+
-+ case RECV_WAIT_SCO_HEADER:
-+ sh = (hci_sco_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = sh->dlen;
-+ break;
-+
-+ case RECV_WAIT_DATA:
-+ hci_recv_frame(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+ /* Make sure we don't stay here too long */
-+ if (boguscount++ > 16)
-+ break;
-+
-+ } while (inb(iobase + UART_LSR) & UART_LSR_DR);
-+}
-+
-+
-+static void bt950_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ bt950_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ int boguscount = 0;
-+ int iir, lsr;
-+
-+ if (!info) {
-+ printk(KERN_ERR "bt950_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ iir = inb(iobase + UART_IIR);
-+
-+ while (!(iir & UART_IIR_NO_INT)) {
-+
-+ switch (iir & UART_IIR_ID) {
-+ case UART_IIR_RLSI:
-+ /* Clear RLSI interrupt */
-+ lsr = inb(iobase + UART_LSR);
-+ printk(KERN_NOTICE "bt950_cs: RLSI interrupt, LSR=%#x\n", lsr);
-+ /* Fixme: we need to process errors ... */
-+ break;
-+ case UART_IIR_RDI:
-+ /* Receive interrupt */
-+ bt950_receive(info);
-+ break;
-+ case UART_IIR_THRI:
-+ /* Transmitter ready for data */
-+ bt950_write_wakeup(info);
-+ break;
-+ default:
-+ printk(KERN_NOTICE "bt950_cs: Unhandled IIR=%#x\n", iir);
-+ break;
-+ }
-+
-+ /* Make sure we don't stay here too long */
-+ if (boguscount++ > 100)
-+ break;
-+
-+ iir = inb(iobase + UART_IIR);
-+
-+ }
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+/* ======================== Device specific HCI commands ======================== */
-+
-+
-+static int bt950_hci_set_baud_rate(struct hci_dev *hdev, int baud)
-+{
-+ bt950_info_t *info = (bt950_info_t *)(hdev->driver_data);
-+ struct sk_buff *skb;
-+
-+ /* Ericsson baud rate command */
-+ unsigned char cmd[] = { HCI_COMMAND_PKT, 0x09, 0xfc, 0x01, 0x03 };
-+
-+ if (!(skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "bt950_cs: Can't allocate mem for new packet.\n");
-+ return -1;
-+ }
-+
-+ switch (baud) {
-+ case 460800:
-+ cmd[4] = 0x00;
-+ skb->pkt_type = PKT_BAUD_RATE_460800;
-+ break;
-+ case 230400:
-+ cmd[4] = 0x01;
-+ skb->pkt_type = PKT_BAUD_RATE_230400;
-+ break;
-+ case 115200:
-+ cmd[4] = 0x02;
-+ skb->pkt_type = PKT_BAUD_RATE_115200;
-+ break;
-+ case 57600:
-+ /* Fall through... */
-+ default:
-+ baud = 57600;
-+ cmd[4] = 0x03;
-+ skb->pkt_type = PKT_BAUD_RATE_57600;
-+ break;
-+ }
-+
-+ memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
-+
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ printk(KERN_WARNING "bt950_cs: setting baud rate: %d.\n", baud);
-+
-+ bt950_write_wakeup(info);
-+
-+ return 0;
-+}
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int bt950_hci_flush(struct hci_dev *hdev)
-+{
-+ bt950_info_t *info = (bt950_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int bt950_hci_open(struct hci_dev *hdev)
-+{
-+ bt950_hci_set_baud_rate(hdev, baud_rate);
-+ set_bit(HCI_RUNNING, &(hdev->flags));
-+
-+ return 0;
-+}
-+
-+
-+static int bt950_hci_close(struct hci_dev *hdev)
-+{
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ bt950_hci_flush(hdev);
-+
-+ return 0;
-+}
-+
-+
-+static int bt950_hci_send_frame(struct sk_buff *skb)
-+{
-+ bt950_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+
-+ if (!hdev) {
-+ printk(KERN_ERR "bt950_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (bt950_info_t *)(hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ bt950_write_wakeup(info);
-+
-+ return 0;
-+}
-+
-+
-+static void bt950_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int bt950_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+static int bt950_setup_uart(bt950_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ unsigned char lcr, ier = UART_IER_RDI | UART_IER_RLSI | UART_IER_SLP;
-+ unsigned int divisor = 8; /* Fixme: divisor == 0x0c ??? */
-+ unsigned char id1, id2, id3, rev;
-+ register int i;
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Disable interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ /* Activate RTS and OUT2 */
-+ /* Fixme: is OUT2 used to enable interrupts? */
-+ outb(UART_MCR_RTS | UART_MCR_OUT2, iobase + UART_MCR);
-+
-+ /* Setup the FIFO's */
-+ outb(0, iobase + UART_FCR);
-+ inb(iobase + UART_RX);
-+ outb(UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
-+ UART_FCR_CLEAR_XMIT | UART_FCR_TRIGGER_14, iobase + UART_FCR);
-+
-+ /* Disable divisor latch access */
-+ lcr = inb(iobase + UART_LCR) & 0x3F; /* mask out UART_LCR_DLAB and UART_LCR_SBC */
-+ outb(lcr, iobase + UART_LCR);
-+
-+ /* Read up to 4 bytes from RX FIFO */
-+ for (i = 0; i < 4; i++) {
-+ inb(iobase + UART_RX);
-+ if (!(inb(iobase + UART_LSR) & UART_LSR_DR))
-+ break;
-+ }
-+
-+ /* Wait if CTS/DSR/DCD changing */
-+ for (i = 1; i < 0x3E8; i++) {
-+ if (!(inb(iobase + UART_MSR) & UART_MSR_ANY_DELTA))
-+ break;
-+ }
-+
-+ /* Enable divisor latch access */
-+ outb(lcr | UART_LCR_DLAB, iobase + UART_LCR);
-+
-+ /* Setup divisor latch */
-+ outb(divisor & 0x00FF, iobase + UART_DLL); /* divisor latch LOW byte */
-+ outb((divisor & 0xFF00) >> 8, iobase + UART_DLM); /* divisor latch HIGH byte */
-+
-+ /* Disable divisor latch access */
-+ outb(lcr, iobase + UART_LCR);
-+
-+ /* Setup interrupts, enable sleep mode */
-+ outb(ier, iobase + UART_IER); /* we don't want to handle TX interrupts */
-+
-+ /* Skip pending interrupts */
-+ for (i = 0; i < 4; i++) {
-+ if (inb(iobase + UART_IIR) & UART_IIR_NO_INT)
-+ break;
-+ }
-+
-+ /* 8N1 */
-+ lcr = UART_LCR_WLEN8;
-+ outb(lcr, iobase + UART_LCR);
-+
-+ /* Setup CTS/RTS flow control and 950 enhanced mode */
-+ outb(UART_LCR_650, iobase + UART_LCR);
-+ outb(UART_EFR_CTS | UART_EFR_RTS | UART_EFR_ECB,
-+ iobase + UART_EFR);
-+ outb(lcr, iobase + UART_LCR);
-+
-+ /* Read core id and revision */
-+ outb(UART_ACR, iobase + UART_EMSR);
-+ outb(UART_ACR_ICRRD, iobase + UART_LSR); /* enable ICR read access, we don't need to save the old value of ACR */
-+
-+ outb(UART_ID1, iobase + UART_EMSR);
-+ id1 = inb(iobase + UART_LSR);
-+
-+ outb(UART_ID2, iobase + UART_EMSR);
-+ id2 = inb(iobase + UART_LSR);
-+
-+ outb(UART_ID3, iobase + UART_EMSR);
-+ id3 = inb(iobase + UART_LSR);
-+
-+ outb(UART_REV, iobase + UART_EMSR);
-+ rev = inb(iobase + UART_LSR);
-+
-+ if (id1 != 0x16 || id2 != 0xC9 || id3 != 0x50) {
-+ printk(KERN_ERR "bt950_cs: Unknown UART core %02X%02X%02X found.\n", id1, id2, id3);
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+ return -ENODEV;
-+ }
-+
-+
-+ /* Init ICR registers */
-+ outb(UART_TTL, iobase + UART_EMSR);
-+ outb(TR_TX_INT, iobase + UART_LSR); /* TX interrupt trigger level (0-127) */
-+
-+ outb(UART_RTL, iobase + UART_EMSR);
-+ outb(TR_RX_INT, iobase + UART_LSR); /* RX interrupt trigger level (1-127) */
-+
-+ outb(UART_FCL, iobase + UART_EMSR);
-+ outb(TR_CTL_LO, iobase + UART_LSR); /* auto flow control LOWER trigger level (0-127) */
-+
-+ outb(UART_FCH, iobase + UART_EMSR);
-+ outb(TR_CTL_HI, iobase + UART_LSR); /* auto flow control HIGH trigger level (1-127) */
-+
-+ outb(UART_ACR, iobase + UART_EMSR);
-+ outb(UART_ACR_TLENB, iobase + UART_LSR); /* disable ICR read access, enable trigger levels */
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ return 0;
-+}
-+
-+
-+static void bt950_stop_uart(bt950_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Disable interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ /* Set RTS and OUT2 low */
-+ outb(0, iobase + UART_MCR);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+}
-+
-+
-+static int bt950_open(bt950_info_t *info)
-+{
-+ struct hci_dev *hdev;
-+ int err;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ info->rx_skb = NULL;
-+
-+ /* Setup hardware */
-+ if ((err = bt950_setup_uart(info)) < 0)
-+ return err;
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ);
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = bt950_hci_open;
-+ hdev->close = bt950_hci_close;
-+ hdev->flush = bt950_hci_flush;
-+ hdev->send = bt950_hci_send_frame;
-+ hdev->destruct = bt950_hci_destruct;
-+ hdev->ioctl = bt950_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_ERR "bt950_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static int bt950_close(bt950_info_t *info)
-+{
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ bt950_hci_close(hdev);
-+
-+ /* Stop hardware */
-+ bt950_stop_uart(info);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_ERR "bt950_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+static dev_link_t *bt950_attach(void)
-+{
-+ bt950_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &bt950_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = bt950_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+ link->conf.Present =
-+ PRESENT_OPTION | PRESENT_STATUS | PRESENT_PIN_REPLACE |
-+ PRESENT_COPY;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &bt950_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ bt950_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+static void bt950_detach(dev_link_t *link)
-+{
-+ bt950_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+ if (link->state & DEV_CONFIG)
-+ bt950_release((u_long) link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+static void bt950_config(dev_link_t *link)
-+{
-+ static ioaddr_t base[4] = { 0x2f8, 0x3e8, 0x2e8, 0x0 };
-+ client_handle_t handle = link->handle;
-+ bt950_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
-+ int i, j, try, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ /* First pass: look for a config entry that looks normal. */
-+ tuple.TupleData = (cisdata_t *) buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-+ /* Two tries: without IO aliases, then with aliases */
-+ for (try = 0; try < 2; try++) {
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if (i != CS_SUCCESS)
-+ goto next_entry;
-+ if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
-+ link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-+ if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
-+ link->conf.ConfigIndex = cf->index;
-+ link->io.BasePort1 = cf->io.win[0].base;
-+ link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+next_entry:
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+ }
-+
-+ /* Second pass: try to find an entry that isn't picky about
-+ its base address, then try to grab any standard serial port
-+ address, and finally try to get any free port. */
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if ((i == CS_SUCCESS) && (cf->io.nwin > 0)
-+ && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
-+ link->conf.ConfigIndex = cf->index;
-+ for (j = 0; j < 5; j++) {
-+ link->io.BasePort1 = base[j];
-+ link->io.IOAddrLines = base[j] ? 16 : 3;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+ }
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+
-+found_port:
-+ if (i != CS_SUCCESS) {
-+ printk(KERN_ERR "bt950_cs: No usable port range found. Giving up.\n");
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (bt950_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ bt950_release((u_long)link);
-+ link->state &= ~DEV_CONFIG_PENDING;
-+}
-+
-+
-+static void bt950_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *) arg;
-+ bt950_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ bt950_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+static int bt950_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ bt950_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ bt950_close(info);
-+ link->state |= DEV_RELEASE_PENDING;
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ bt950_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG) {
-+ bt950_stop_uart(info);
-+ CardServices(ReleaseConfiguration, link->handle);
-+ }
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (link->state & DEV_CONFIG) {
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ bt950_setup_uart(info);
-+ }
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_bt950_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "bt950_cs: Card Services release does not match!\n");
-+// return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &bt950_attach, &bt950_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_bt950_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ bt950_detach(dev_list);
-+}
-+
-+
-+module_init(init_bt950_cs);
-+module_exit(exit_bt950_cs);
-+
-+EXPORT_NO_SYMBOLS;
-diff -Nur linux-orig/drivers/bluetooth/Config.in linux/drivers/bluetooth/Config.in
---- linux-orig/drivers/bluetooth/Config.in 2004-02-16 08:45:33.000000000 +0300
-+++ linux/drivers/bluetooth/Config.in 2004-02-16 08:50:36.000000000 +0300
-@@ -21,7 +21,7 @@
-
- dep_tristate 'HCI DTL1 (PC Card) driver' CONFIG_BLUEZ_HCIDTL1 $CONFIG_PCMCIA $CONFIG_BLUEZ
-
--dep_tristate 'HCI BT3C (PC Card) driver' CONFIG_BLUEZ_HCIBT3C $CONFIG_PCMCIA $CONFIG_BLUEZ
-+# dep_tristate 'HCI BT3C (PC Card) driver' CONFIG_BLUEZ_HCIBT3C $CONFIG_PCMCIA $CONFIG_BLUEZ
-
- dep_tristate 'HCI BlueCard (PC Card) driver' CONFIG_BLUEZ_HCIBLUECARD $CONFIG_PCMCIA $CONFIG_BLUEZ
-
-@@ -29,5 +29,7 @@
-
- dep_tristate 'HCI VHCI (Virtual HCI device) driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
-
-+dep_tristate 'HCI BT950 (BT950 device) driver' CONFIG_BLUEZ_BT950 $CONFIG_BLUEZ
-+
- endmenu
-
-diff -Nur linux-orig/drivers/bluetooth/Makefile linux/drivers/bluetooth/Makefile
---- linux-orig/drivers/bluetooth/Makefile 2004-02-16 08:45:33.000000000 +0300
-+++ linux/drivers/bluetooth/Makefile 2004-02-16 08:50:47.000000000 +0300
-@@ -17,10 +17,12 @@
- obj-$(CONFIG_BLUEZ_HCIBFUSB) += bfusb.o
-
- obj-$(CONFIG_BLUEZ_HCIDTL1) += dtl1_cs.o
--obj-$(CONFIG_BLUEZ_HCIBT3C) += bt3c_cs.o
-+# obj-$(CONFIG_BLUEZ_HCIBT3C) += bt3c_cs.o
- obj-$(CONFIG_BLUEZ_HCIBLUECARD) += bluecard_cs.o
- obj-$(CONFIG_BLUEZ_HCIBTUART) += btuart_cs.o
-
-+obj-$(CONFIG_BLUEZ_BT950) += bt950_cs.o
-+
- include $(TOPDIR)/Rules.make
-
- hci_uart.o: $(uart-y)
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/buffered-fbmem.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/buffered-fbmem.patch
deleted file mode 100644
index 554f118936..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/buffered-fbmem.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-
-#
-# Made by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux/drivers/video/fbmem.c~buffered-fbmem 2003-09-16 00:48:18.000000000 +0200
-+++ linux/drivers/video/fbmem.c 2003-09-19 00:38:00.000000000 +0200
-@@ -650,7 +650,11 @@
- pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;
- pgprot_val(vma->vm_page_prot) |= _CACHE_UNCACHED;
- #elif defined(__arm__)
-+#ifdef CONFIG_PXA
-+ vma->vm_page_prot = pgprot_noncached_buffered(vma->vm_page_prot);
-+#else
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-+#endif
- #ifdef CONFIG_POODLE_CONSISTENT_ALLOC
- vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | L_PTE_CACHEABLE);
- #endif
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/compile.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/compile.patch
deleted file mode 100644
index 1a19b85daa..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/compile.patch
+++ /dev/null
@@ -1,14 +0,0 @@
---- linux/include/linux/jffs2_fs_i.h.old 2003-02-01 00:24:48.000000000 -0600
-+++ linux/include/linux/jffs2_fs_i.h 2003-02-01 00:25:14.000000000 -0600
-@@ -48,9 +48,11 @@
- uint32_t nr_frags;
- #endif
-
-+#ifdef KERNEL_VERSION
- #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
- struct inode vfs_inode;
- #endif
-+#endif
- };
-
- #endif /* _JFFS2_FS_I */
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/corgi-fbcon-logo.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/corgi-fbcon-logo.patch
deleted file mode 100644
index 4d3b42445b..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/corgi-fbcon-logo.patch
+++ /dev/null
@@ -1,281 +0,0 @@
---- linux/drivers/video/w100fb.c 2004-11-04 12:44:29.000000000 -0600
-+++ linux/drivers/video/w100fb.c~corgi.patch 2004-11-04 12:50:27.000000000 -0600
-@@ -982,6 +982,17 @@
- #endif
- #endif
-
-+#ifdef CONFIG_ARCH_SHARP_SL_E // English message
-+#include "corgiLogoMsg.c"
-+#if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+static int logo_msg_xoff __initdata = 400;
-+static int logo_msg_yoff __initdata = 100;
-+#else
-+static int logo_msg_xoff __initdata = 120;
-+static int logo_msg_yoff __initdata = 500;
-+#endif
-+#endif
-+
- #endif // CONFIG_ARCH_PXA_SHEPHERD
-
- #endif
---- /dev/null 2004-06-13 02:32:19.000000000 +0100
-+++ linux/drivers/video/corgiLogoMsg.c 2004-11-12 19:57:23.000000000 +0000
-@@ -0,0 +1,258 @@
-+/* Logo Screen 16bits RGB(565) data*/
-+#ifndef __initdata
-+#define __initdata
-+#endif
-+
-+static int logo_msg_width __initdata = 30;
-+static int logo_msg_height __initdata = 250;
-+static unsigned short logo_msg_data[] __initdata ={
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0xad55,0x7bef,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedb,0xc638,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x738e,0x0020,0x0000,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0x0020,0x528a,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x18c3,0x738e,0x9cf3,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x52aa,0x2104,0x0000,0x2104,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffbf,0x1082,0x18e3,0xef3d,0xffff,0xffff,0xffff,0xffff,0xe73c,0xbdf7,0xdebb,0xffdf,0xffff,0xffff,0xffdf,0x6b6d,0x0000,0x9cf3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xdebd,0xad17,0x0000,0x5a8c,0xef3e,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x7bb1,0xc5da,0xd67c,0xffbf,0xffff,0xef7d,0x0000,0x632c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xb558,0x0000,0x6b4e,0xf7bf,0xffff,0xffff,0xffff,0xffff,0x9492,0x0000,0x62ec,0xce1b,0xc5ba,0xce1b,0xffff,0xf7be,0x0000,0x630c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xc5fb,0xce1b,0xffff,0x18e3,0x2124,0xf79e,0xffff,0xffdf,0xf77e,0xef7d,0x2945,0x0000,0x10a2,0xe71c,0xdebd,0xc5ba,0xef1e,0x94b2,0x0000,0x9cd3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffbf,0xc5ba,0xdebd,0xffff,0x8c71,0x0000,0x2945,0x8430,0x9493,0x6b0e,0x2125,0x0000,0x94b2,0x0020,0x0841,0x526a,0x4209,0x3166,0x0000,0x2104,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffbf,0xc5ba,0xdedd,0xffff,0xffff,0x8430,0x0020,0x0000,0x0000,0x0000,0x0000,0x8410,0xffff,0xb596,0x18e3,0x0000,0x0000,0x0000,0x3186,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xcdfb,0xce1b,0xffff,0xffff,0xffff,0xe71c,0x9cd3,0x630d,0x6b4f,0xa4f6,0xffbf,0xffff,0xffff,0xffff,0xbdd8,0x9474,0xc5f9,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe6fd,0xc5ba,0xce1b,0xe6fd,0xef3e,0xe6fd,0xce1b,0xc5ba,0xe71d,0xc5da,0xc5db,0xd67c,0xde9c,0xd63c,0xc5ba,0xce1b,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe6fd,0xc5da,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xe6dd,0xffff,0xef5e,0xcdfb,0xc5ba,0xc5ba,0xc5ba,0xce3b,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffbf,0xef1e,0xe6dd,0xe71d,0xf79f,0xffff,0xffff,0xffff,0xffff,0xf79f,0xf77e,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x2124,0x2104,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c71,0x0000,0x4a69,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedb,0x6b6d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xf79f,0xffff,0xffff,0x4a69,0x0000,0x738e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x52aa,0x0000,0x9cd3,0xffff,0xffff,0xffff,0xffff,0xce1b,0xce1b,0xffff,0x4208,0x632c,0x2945,0x0000,0x630c,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0x1082,0x0841,0xc618,0xffff,0xffff,0xffff,0xe6fd,0xc5ba,0xd67c,0x2104,0x5aeb,0xe73c,0x2965,0x0000,0x39c7,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xf7bf,0xdebd,0xffff,0xffff,0xc618,0x0861,0x0861,0x94b2,0xffdf,0xffff,0xffff,0xd67c,0xc5ba,0x18e3,0x5aeb,0xffff,0xf79e,0x5aeb,0x0000,0x0861,0x8c71,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xd67c,0xc5ba,0xe71d,0xffff,0xffff,0xc638,0x18e3,0x0000,0x18c3,0x6b6d,0x9494,0xc5fa,0xce1b,0x18c3,0x526a,0xffff,0xffff,0xffff,0xad55,0x10a2,0x0000,0x2124,0xef7d,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffbf,0xc5fb,0xc5db,0xf77e,0xffff,0xffff,0xf79e,0x8410,0x18e3,0x0000,0x0000,0x0000,0x0861,0x0000,0x4209,0xd63c,0xffbf,0xffff,0xffff,0xef7d,0x738e,0x39c7,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf77e,0xc5db,0xc5db,0xe71d,0xffff,0xffff,0xffff,0xffff,0xc618,0x6b0e,0x4209,0x2945,0x0000,0x4a6a,0xc5ba,0xc5db,0xe6fd,0xffff,0xffff,0xffff,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf77e,0x9cb5,0x8c13,0xcdfb,0xdebd,0xef5e,0xffdf,0xffff,0xce1b,0xde9c,0xffff,0x2104,0x5aeb,0xef3e,0xc5fb,0xc5ba,0xce1b,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x528a,0xcdfb,0xc5ba,0xc5ba,0xc5ba,0xc5db,0xc5da,0xde9c,0xffff,0x2104,0x5aeb,0xffff,0xffdf,0xdebd,0xd65c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x5aeb,0xffff,0xf77e,0xe6fd,0xd67c,0xce1b,0xc5ba,0xde9c,0xffff,0x2104,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xf7be,0x9492,0x630c,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xf79e,0xef5e,0xffff,0x2104,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xce1b,0xde9c,0xffff,0x2104,0x5aeb,0xffff,0xffff,0xffff,0xbdf7,0x2124,0x0000,0x0841,0xef7d,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xde9c,0xffff,0x2104,0x528a,0xdefb,0xdefb,0xdefb,0xffdf,0xffff,0xce1b,0xde9c,0xffff,0x2104,0x5aeb,0xffff,0xffff,0x8410,0x0020,0x0020,0x6b4d,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xde9c,0xffff,0x4a49,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x5aeb,0xffdf,0x5acb,0x0000,0x18e3,0xce59,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xde9c,0xffff,0xdefb,0x5aeb,0x4228,0x4228,0x4228,0x4228,0x4228,0x31a7,0x20e4,0x2104,0x2104,0x73ae,0x4a6a,0x0000,0x2946,0xbd79,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xd67c,0xf7bf,0xf7bf,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xce1b,0xde9c,0xffff,0xffff,0x6b4e,0x0000,0x3187,0xd65b,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xd65c,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xde9c,0xffff,0x9473,0x0000,0x2105,0xe73d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xf7bf,0xde9c,0xd65c,0xd65c,0xd65c,0xd65c,0xd65c,0xd65c,0xce1b,0xce1b,0xce1b,0xdebd,0xd67c,0x3166,0x0861,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xce1a,0xbdd7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0xd69a,0xffff,0xffff,0xffff,0xef5e,0xc5ba,0xce3b,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9492,0x0000,0x4228,0xad55,0xffdf,0xd65c,0xc5fb,0xffbf,0xffff,0xffff,0x2104,0x5aeb,0xffff,0xffff,0xce59,0x2945,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedb,0x6b6d,0x2104,0x0000,0x10a2,0x630c,0xad55,0xf79e,0xffff,0xffff,0x2104,0x5aeb,0xffff,0xffff,0xce79,0x0000,0xb5b6,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xdebb,0xdefb,0xdefb,0xdefb,0xdefb,0xb5b6,0x6b6d,0x31a6,0x0000,0x0841,0x39c7,0x6b6d,0x1082,0x528a,0xdefb,0xdefb,0xce59,0x0000,0x9cd3,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe71d,0x18c3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6b6d,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf7bf,0x9493,0x83d1,0x7bb1,0x7bb1,0x8c32,0x94b3,0xa514,0x8430,0x2945,0x0000,0x18e3,0x9492,0x10a2,0x39c7,0x7bb1,0x94b3,0xa514,0x2945,0x4208,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffbf,0xf7bf,0xf7bf,0xf7bf,0xf7bf,0xef5e,0xdebd,0xbdb9,0x7b90,0x3187,0x0000,0x10a2,0x734f,0xce3b,0xf7bf,0x2104,0x5acb,0xc5ba,0xe71d,0xffff,0x7bcf,0x0841,0xf79e,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0x62ee,0x0000,0x0000,0x20e4,0x7370,0xbd9a,0xc5ba,0xc5ba,0xc5ba,0x18c3,0x4209,0xc5ba,0xdebd,0xffff,0xbdd7,0x3186,0xe73c,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xef5e,0xef3e,0xef3e,0x8411,0x18e4,0xef3e,0xb577,0x526a,0x9c94,0xc5ba,0xce1b,0xe71d,0x8c33,0x9494,0xef3e,0xce3a,0xb5b7,0xb558,0xb578,0xdefb,0xdedb,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0xef1e,0xd65c,0xc5ba,0x0000,0x738e,0xffff,0xffff,0x31a7,0x39c7,0xffff,0xdefb,0x0000,0x0000,0x0000,0x0000,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x736e,0x0000,0xc5ba,0xce1b,0xe71d,0x0000,0x7bef,0xffff,0xffff,0x31a7,0x39c7,0xffff,0xdefb,0x0000,0x62ec,0x83f1,0x9cf3,0x39c7,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe71d,0xce1b,0xffff,0x7baf,0x0000,0xf77e,0xffff,0xffff,0x0000,0x73af,0xef5e,0xffff,0x4208,0x4208,0xf7bf,0xd6bb,0x0000,0x9cd3,0xf7bf,0xffff,0x5aeb,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0x7bef,0x0000,0xc5ba,0xe6dd,0xffff,0x0000,0x6b2e,0xd65c,0xffff,0x4208,0x3187,0xc5ba,0xacf7,0x0000,0x7bb1,0xce1b,0xffff,0x5aeb,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0x7bef,0x0000,0x62cd,0x736e,0x7bef,0x0000,0x3187,0x6b2e,0x7bef,0x2104,0x3187,0xdebc,0xce3a,0x0000,0x83f1,0xce1b,0xffff,0x5aeb,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0x7bef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3187,0xef3e,0xdefb,0x0000,0x8c32,0xce1b,0xffff,0x5aeb,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0x7bef,0x0000,0xc5ba,0xe6dd,0xffff,0x0000,0x6b2e,0xd65c,0xffff,0x4208,0x3187,0xef3e,0xdefb,0x0000,0x8c32,0xce1b,0xffff,0x5aeb,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xe6dd,0x736e,0x0000,0xc5ba,0xd65c,0xe6dd,0x0000,0x630d,0xd65c,0xffff,0x4208,0x3187,0xef3e,0xdefb,0x0000,0x8c32,0xce1b,0xffff,0x5aeb,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xc5ba,0x62cd,0x0000,0xc5ba,0xc5ba,0xc5ba,0x0000,0x62cd,0xd65c,0xffff,0x4208,0x3187,0xef3e,0xdefb,0x0000,0x738f,0xb537,0xdefb,0x528a,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0x7bef,0x0000,0xc5ba,0xe6dd,0xffff,0x0000,0x6b2e,0xd65c,0xffff,0x4208,0x3187,0xef3e,0xdefb,0x0000,0x0000,0x0000,0x0000,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0x7bef,0x0000,0xc5ba,0xe6dd,0xffff,0xc638,0xbd98,0xd65c,0xffff,0x736e,0x5a8c,0xef3e,0xf79e,0xa514,0x8c32,0x83d1,0xa514,0xa514,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0xe71c,0xc638,0xc5ba,0xe6dd,0xffff,0xffff,0xd65c,0xd65c,0xffff,0xf7bf,0xc5ba,0xe6fd,0xf7bf,0xf7bf,0xd67c,0xce1b,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0xffff,0xffff,0xc5ba,0xe6dd,0xffff,0xffff,0xd65c,0xd65c,0xffff,0xf7bf,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xce1b,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0xdefb,0xdedb,0xf77e,0xffbf,0xffff,0xffff,0xdebd,0xdebd,0xffff,0xffff,0xef3e,0xef3e,0xef3e,0xef3e,0xef3e,0xef5e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffbf,0xf77e,0xffff,0x5aeb,0x0000,0x39e7,0x8c71,0xbdf7,0xdefb,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9cd3,0x2965,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xf7bf,0xf7bf,0xffff,0xffff,0xffff,0xe73c,0xb5b6,0x9492,0x7bef,0x630c,0x5aeb,0x5aeb,0x5aeb,0x5aeb,0x5aeb,0x5aeb,0x5aeb,0x5aeb,0x528a,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xd65c,0xbdd8,0x9493,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc638,0xad75,0xffff,0xdefb,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe71d,0xce3b,0xc5ba,0x2945,0x1082,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0x4209,0x18c3,0xef3e,0xdefb,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x736e,0x0000,0xb577,0xde9c,0xde9c,0xd67c,0x9473,0x18e3,0xbdd9,0xde9c,0xde9c,0xde9c,0x4a4a,0x18c3,0xef3e,0xdefb,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xf79f,0xef1e,0xffff,0xc618,0x0000,0x8430,0xffff,0xf7be,0x2965,0x528a,0x0000,0xdefb,0xa514,0x73af,0x7bef,0x2965,0x0861,0x738f,0xad75,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xd63c,0xcdfb,0xffff,0xffff,0x18e3,0x39e7,0xffff,0x7bcf,0x0000,0x5aeb,0x0000,0xdefb,0x4a6a,0x0000,0x0000,0x0000,0x0000,0x0000,0x8410,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xdedd,0xc5ba,0xf79e,0xffff,0x73ae,0x0000,0xbdb7,0x0020,0x4a69,0xa514,0x0000,0xdefb,0x4a6a,0x10a3,0xdefb,0x4a69,0x10a3,0xce3a,0xd69a,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xf77e,0xc5ba,0xe6fd,0xffff,0xdefb,0x0000,0x10a2,0x0000,0xce59,0x9493,0x0000,0xc5f9,0x4a2a,0x18c3,0xe6dd,0x52ab,0x18c3,0xef3e,0xdefb,0x0000,0x39c7,0x5aeb,0xdedb,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xcdfb,0xd65c,0xffff,0xe6dd,0x39c8,0x0000,0x3187,0xf7bf,0x8c32,0x0000,0xacf7,0x4209,0x18c3,0xc5ba,0x528a,0x18c3,0xef3e,0xdefb,0x0000,0x0000,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdedd,0xc5ba,0xf79e,0xc5db,0x630d,0x0000,0x62ed,0xf7bf,0x8c32,0x0000,0xd6bb,0x4a4a,0x18c3,0xf7bf,0x5acb,0x18c3,0xef3e,0xdefb,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf7bf,0xc5ba,0xcdfb,0xbd9a,0x1082,0x0000,0x1082,0xef7e,0x8c32,0x0000,0xdefb,0x4a6a,0x18c3,0xffff,0x5acb,0x18c3,0xd65c,0xbdb8,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xd67c,0xc5ba,0x8411,0x0000,0x6b4d,0x0000,0x8410,0x8c32,0x0000,0xdefb,0x4a6a,0x18c3,0xffff,0x5acb,0x18c3,0xc5ba,0xacf7,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0x39a7,0x1082,0xe6fd,0x4a2a,0x0861,0x736e,0x0000,0xdefb,0x4a6a,0x0020,0x4228,0x18c3,0x0020,0x39e8,0x94b2,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xc5fb,0xb558,0x0000,0x5acb,0xef3e,0xb559,0x2104,0x0020,0x0000,0xdefb,0x62ed,0x18c3,0x2104,0x0861,0x0000,0x18e4,0x8c71,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xef3e,0xc5ba,0x9452,0x0000,0x9493,0xef3e,0xc5ba,0xce59,0x0841,0x0000,0xdefb,0xde9c,0xce1b,0xffff,0x5acb,0x18c3,0xef3e,0xdefb,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xd65c,0xc5fb,0x5aeb,0x0000,0xb558,0xe6fd,0xc5ba,0xf7bf,0xa515,0x62ed,0xc5fa,0xcdfb,0xc5db,0xd65c,0x528a,0x18c3,0xef3e,0xdefb,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffdf,0xc5da,0xde9c,0x5aeb,0x2124,0xce1b,0xc5db,0xc5ba,0xf7bf,0xdebd,0xce1b,0xce1b,0xc5db,0xc5da,0xce1b,0x7bcf,0x4209,0xef3e,0xdefb,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xef3e,0xc5ba,0xef3e,0xffff,0xef7d,0xf79f,0xc5db,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xde9c,0xce1b,0xffff,0xf7bf,0xc5ba,0xef3e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xffdf,0xffff,0xffff,0xffff,0xf77e,0xe6dd,0xffdf,0xffff,0xffff,0xffff,0xde9c,0xce1b,0xffff,0xf7bf,0xc5ba,0xef3e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xde9c,0xce1b,0xffff,0xffff,0xffff,0xffff,0xef5d,0x9cd3,0x7bef,0xa534,0xef7d,0xffff,0xe6fd,0xde9c,0xffff,0xf7bf,0xc5ba,0xef3e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffdf,0xffff,0xffff,0xffff,0xad55,0x0861,0x0000,0x0000,0x0000,0x1082,0x9cf3,0xffff,0xffff,0xffff,0xffff,0xffff,0x9492,0x2104,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0x0841,0x1082,0xa534,0xdefb,0xad75,0x2965,0x0000,0x94b2,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x6b4e,0x0000,0xa535,0xffdf,0xffff,0xffff,0xf79e,0x2965,0x0841,0xdefb,0xffff,0xffff,0xffff,0x7bef,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xef3e,0xc5db,0x4209,0x0000,0xbd9a,0xc5fb,0xef1e,0xffff,0xffff,0xd69a,0x0000,0x630c,0xe71d,0xce1b,0xffbf,0x7bef,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf7bf,0xc5db,0xc5fb,0x83f0,0x0000,0x4a6a,0x8c32,0x9474,0xb576,0xc638,0xc638,0x3186,0x0861,0xad56,0x9474,0xbdf8,0x630c,0x0000,0xad55,0xc638,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdedd,0xc5ba,0xef5e,0xf79e,0x4a49,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xffff,0xffff,0xffff,0xd6ba,0xad75,0x9cd3,0x7bb1,0x8c32,0xa514,0x8430,0x0000,0x528a,0x7bb1,0x9cf3,0x528a,0x0000,0x8c71,0xa514,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe6fd,0xc5ba,0xd67c,0xef5e,0xef3d,0xf77e,0xf77e,0xf77e,0xce3b,0xc5db,0xf77e,0xef5e,0x0000,0x5aac,0xc5ba,0xef3e,0x7baf,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xd65c,0xc5ba,0x4a2a,0x20e4,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0x18c3,0x3187,0xc5ba,0xc5ba,0x62cd,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7bf,0x41e8,0x0841,0xef3e,0xef3e,0xef3e,0xe6fd,0xc5ba,0xde9c,0xef3e,0x18e4,0x39a7,0xc5ba,0xe6fd,0x738f,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5acb,0x0000,0xef5d,0xffff,0xffff,0xffff,0xc5ba,0xdebc,0xffff,0x1082,0x4229,0xc5ba,0xf7bf,0x7bef,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xde9c,0xce1b,0xffff,0x8c71,0x0000,0xb596,0xffff,0xffff,0xffff,0xce1b,0xd65c,0xdefb,0x0000,0x630d,0xc5ba,0xf7bf,0xe71c,0xc638,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xd65c,0xc5db,0xffff,0xd69a,0x0000,0x5acb,0xffff,0xffff,0xffff,0xce1b,0xd65c,0x8410,0x0000,0xa515,0xc5ba,0xf7bf,0xffff,0x94b2,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xffdf,0xffff,0x2965,0x0020,0xc618,0xffff,0xffff,0xc5fb,0xad57,0x0861,0x2124,0xdebc,0xc5ba,0xf7bf,0x8c71,0x0000,0x39e7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe6fd,0xc5ba,0xef5e,0xffff,0xce59,0x0020,0x0861,0x73ae,0x9cf3,0x526b,0x0020,0x0861,0xc638,0xffbf,0xf77e,0x7bef,0x0000,0x2124,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf79f,0xc5ba,0xde9c,0xffff,0xffff,0xb5b6,0x2104,0x0000,0x0000,0x0000,0x3186,0xd69a,0xffff,0xffff,0xce5a,0x18a3,0x39e7,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xce3b,0xc5da,0xf77e,0xffff,0xffff,0xffff,0xce39,0x9474,0xb578,0xffff,0xffff,0xffff,0xe6fd,0xc5ba,0xbd98,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xc5da,0xc5db,0xdedd,0xef3e,0xdebc,0xc5db,0xc5db,0xf77e,0xffff,0xffff,0xe6dd,0xc5ba,0xce1b,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5e,0xce1b,0xc5ba,0xc5ba,0xc5ba,0xd63b,0xf79f,0xd6ba,0xffff,0xffdf,0xcdfb,0xd65c,0xffdf,0xef5d,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79f,0xf77e,0xffbf,0xffff,0x9cd3,0x0020,0xad55,0xffff,0xffbf,0xffff,0xffdf,0x39e7,0x4a69,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc618,0x18c3,0x0000,0x8430,0xffff,0xffff,0xffdf,0x52aa,0x0000,0x3186,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x73ae,0x5aeb,0x5aeb,0x5aeb,0x5acb,0x5aeb,0x5aeb,0x4228,0x0000,0x0000,0x4228,0xe71c,0xffff,0xffdf,0x7bef,0x0000,0x1082,0x9cd3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0020,0x7bef,0xef7d,0xffff,0xbdf7,0x2104,0x0000,0x2965,0xd69a,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf77e,0xcdfb,0xc5ba,0xe6fd,0xffff,0xffff,0xffff,0xad57,0x2925,0x0000,0x1082,0xd69a,0xffff,0xf7be,0x8410,0x0841,0xdedb,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xdebd,0xde9c,0xde9c,0xde9c,0xde9c,0xde9c,0xde9c,0xd65c,0xc5ba,0xc5ba,0xd65c,0xffbf,0xffff,0xffff,0xe6dd,0x83d1,0x39a7,0xe6fd,0xffff,0xffff,0xffff,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0x3187,0x7bb1,0xe6dd,0xffdf,0x5aeb,0x2104,0xce1b,0xc5ba,0xa516,0x7bcf,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x0000,0x6b0d,0xc5ba,0xc5fb,0x5acb,0x2104,0xffff,0xe6dd,0x7bb1,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa534,0x4228,0xffdf,0x0000,0x7bef,0xef3e,0xd65c,0x5aeb,0x2104,0xffff,0xffff,0x9cf4,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0x5aeb,0x0000,0x10a3,0xd6ba,0x0000,0x6b4e,0xce1b,0xffff,0x5aeb,0x2104,0xe6dd,0xffdf,0xa514,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4208,0x0000,0x39a8,0xc61a,0xffff,0x0000,0x6b4e,0xce1b,0xffff,0x5aeb,0x18e4,0xc5ba,0xf7bf,0xa514,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef3e,0xb577,0xa514,0xc5ba,0xe6dd,0xffff,0x0000,0x6b4e,0xce1b,0xffff,0x5aeb,0x10a3,0x9474,0xbdf8,0x7bef,0x0000,0xad55,0xc638,0xef7d,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xd67c,0xacf7,0xcdfb,0xf79f,0xc5ba,0xe6dd,0xffff,0x0000,0x6b4e,0xce1b,0xffff,0x5aeb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xd65c,0x20e4,0x4a4a,0xffbf,0xffff,0xc5ba,0xe6dd,0xffff,0x0000,0x6b4e,0xce1b,0xffff,0x5aeb,0x1082,0x7bb1,0x9cf3,0x632c,0x0000,0x8c71,0xa514,0xe73c,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf7bf,0x18e4,0x5aeb,0xffff,0xffff,0xc5ba,0xe6dd,0xffff,0x0000,0x6b4e,0xcdfb,0xf77e,0x5aab,0x18e3,0xc5ba,0xef3e,0x9cb3,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf7bf,0xffff,0x2104,0x4228,0xc638,0xc638,0x9474,0xad56,0xc638,0x0000,0x528b,0x9474,0x9474,0x31a7,0x18c3,0xc5ba,0xc5ba,0x7bb1,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xde9c,0xffff,0x4a69,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x18e3,0xc5ba,0xe6fd,0x9493,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xde9c,0xffff,0xf79e,0xa534,0xa514,0xa514,0x7bb1,0x8c52,0xa514,0x0000,0x4209,0x83d1,0xa514,0x39c7,0x18e4,0xc5ba,0xf7bf,0xa514,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xd65c,0xf77e,0xf77e,0xf77e,0xf77e,0xf77e,0xc5ba,0xde9c,0xf77e,0x0000,0x6b2e,0xce1b,0xffff,0x5aeb,0x18e4,0xc5ba,0xf7bf,0xb5b6,0x4228,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xd67c,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xce1b,0xffff,0xdedb,0xb5b7,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xef3e,0xef3e,0xef3e,0xef3e,0xef3e,0xef3e,0xc5ba,0xd67c,0xef3e,0xef3e,0xd65c,0xce1b,0xffff,0xffff,0xef3e,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc5ba,0xe6dd,0xffff,0xffff,0xde9c,0xce1b,0xffff,0xffff,0xef5e,0xa4d5,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc638,0xad75,0xef5d,0xf79e,0xffff,0xffff,0xffff,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x632c,0x0000,0x0841,0x4a69,0x9cf3,0xe73c,0xffff,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x632c,0x0000,0x18c3,0x1082,0x0000,0x0000,0x3186,0x5aeb,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xbdf7,0x7bef,0xd6bb,0xef5e,0xffff,0xf79e,0x3186,0x0020,0xce79,0xa4f4,0x41e9,0x0841,0x0000,0x0000,0x0861,0x528a,0x9492,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x6b6d,0x0000,0xbdb8,0xc5ba,0xc5db,0xd67c,0xce5a,0x0861,0x4208,0xf77e,0xc5ba,0xe6fd,0x94b2,0x0000,0x18e3,0x0000,0x0000,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4a49,0x0861,0xdebc,0xc5ba,0xcdfb,0xc5fb,0xc5ba,0x62ed,0x0000,0xa4f5,0xc5ba,0xef3e,0xc638,0x0000,0xa514,0xef5d,0xa534,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf77e,0xe6dd,0xffbf,0x2965,0x31a6,0xffff,0xce3b,0xc5da,0xf79e,0xef3e,0xce1a,0x0020,0x4209,0xc5ba,0xc5db,0xa4f5,0x0000,0x9cf4,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdebd,0xc5ba,0xf7bf,0x2104,0x4228,0xffff,0xffbf,0xc5db,0xd65c,0xffff,0xffff,0x4229,0x10a2,0xc5ba,0xcdfb,0x9474,0x0000,0x9cf3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xd65c,0xc5db,0xffff,0x2104,0x4228,0xffff,0xffff,0xe6dd,0xc5ba,0xf77e,0xffff,0x738e,0x0000,0xb558,0xef3e,0xc5f8,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce3b,0xce3b,0xffff,0x4208,0x18e3,0xffff,0xffff,0xffdf,0xc5db,0xde9c,0xffff,0x7bef,0x0000,0xacf7,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xd65c,0xffff,0x632c,0x0000,0xef5d,0xffff,0xffff,0xd65c,0xcdfb,0xffff,0x6b4d,0x0000,0xb559,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xd65c,0xffff,0xad55,0x0000,0x9cd3,0xffff,0xffff,0xdebd,0xc5ba,0xffdf,0x2124,0x2104,0xc5ba,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xd65c,0xcdfb,0xffff,0xf7be,0x10a2,0x2104,0xf79e,0xffff,0xe6dd,0xc5ba,0xa4f4,0x0000,0x6b4d,0xc5ba,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdebc,0xc5ba,0xffdf,0xffff,0x9492,0x0000,0x4228,0xdedb,0xde9c,0x83d1,0x0861,0x10a2,0xdedc,0xc5ba,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xef3e,0xc5ba,0xe71d,0xffff,0xffff,0x5aeb,0x0000,0x0000,0x0000,0x0000,0x1082,0xc618,0xf77e,0xc5ba,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xc5fb,0xce1b,0xffff,0xffff,0xffff,0xbdd7,0x630d,0x4209,0x7bd0,0xef5d,0xffff,0xf77e,0xc5ba,0xef3e,0xe71c,0x7bef,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5ba,0xd65c,0xf7bf,0xffff,0xef3e,0xc5db,0xc5fb,0xffdf,0xffff,0xffff,0xf77e,0xc5ba,0xef3e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5fb,0xf77e,0xffff,0xe71c,0x8430,0xbdd8,0xc5ba,0xef3e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef7e,0xdebd,0xde9c,0xe71d,0xffdf,0xffff,0xe73c,0x18c3,0x0000,0x0020,0xb557,0xf79f,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x6b4d,0x0000,0x73ae,0x0020,0x3186,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffbf,0xc619,0x0020,0x528a,0xffff,0x7bcf,0x0000,0x94b2,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xcdfb,0x41e9,0x0000,0xc639,0xffff,0xf7be,0x2104,0x1082,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdebc,0x9474,0x0000,0x39c8,0xce3b,0xffff,0xffff,0xb596,0x0000,0x52aa,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7bf,0xc5ba,0x2104,0x0020,0xc5f9,0xc5ba,0xe71d,0xffff,0xffff,0x52aa,0x0000,0xad55,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd67c,0x62cd,0x0000,0x6b6d,0xffff,0xce1b,0xc5fb,0xffbf,0xffff,0xe71c,0x1082,0x10a2,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf77e,0x9cb5,0x0000,0x18c3,0xef7d,0xffff,0xef5e,0xc5ba,0xd67c,0xffff,0xffff,0x94b2,0x0000,0x52aa,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc5fa,0x2105,0x0000,0xad55,0xffff,0xffff,0xffff,0xd67c,0xc5ba,0xef3e,0xffff,0xffff,0x39c7,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe6dd,0x524b,0x0000,0x52aa,0xffff,0xffff,0xffff,0xffff,0xffbf,0xc5fb,0xc5fb,0xffdf,0xffff,0xdedb,0x0841,0x0861,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79f,0x7bb1,0x0000,0x18c3,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5ba,0xd67c,0xffff,0xffff,0x9492,0x0000,0x4208,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xce3b,0x5acd,0x0020,0xbdd7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd65c,0xc5ba,0xef3e,0xffff,0xffff,0x5aeb,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xdebc,0xc5ba,0xd67c,0xc618,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7bf,0xc5db,0xc5db,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xef3e,0xc5ba,0xcdfb,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5ba,0xd65c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe6dd,0xc5da,0xef7e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xde9c,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf77e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xce79,0x528a,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x73ae,0x0000,0x0000,0x39e7,0xa534,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xce59,0x5aeb,0x0861,0x0000,0x0861,0x52aa,0xa514,0xe73c,0xffff,0xffff,0xffff,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf79e,0xd67c,0xf79f,0xffff,0xffff,0xffff,0xf79e,0xa534,0x52aa,0x0861,0x0000,0x0000,0x2104,0x39c8,0x7bd0,0x8410,0x0000,0x8c71,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdebd,0xc5ba,0xc5ba,0xd65c,0xef3e,0xffff,0xffff,0xffff,0xffff,0xf7be,0xbdd7,0x7bcf,0x39c7,0x0841,0x0000,0x0000,0x0000,0x0000,0x0000,0x18e3,0xb596,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xde9c,0xc5db,0xc5ba,0xc5db,0xd67c,0xef3e,0xffdf,0xffff,0xffff,0xffff,0xf77e,0xc5ba,0xbdf8,0x8c51,0x0000,0x4208,0x4a69,0x2945,0xb596,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9cd4,0x1082,0x0841,0x528c,0xbd79,0xce1b,0xd67c,0xe6fd,0xe6dd,0xc5ba,0xe6fd,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0x0841,0x0020,0x10a2,0x1082,0xd65b,0xd65c,0xc5db,0x9474,0x62cd,0xb559,0xc5ba,0x9474,0x0000,0x94b3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9492,0x0000,0x9cf3,0xffdf,0xbdf7,0xffff,0xffff,0xffff,0x7bf0,0x0000,0x9454,0xd65c,0xa4f5,0x0000,0x94b3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xef3e,0xc5fb,0x4a29,0x0000,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xad75,0x0000,0x7bb1,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffbf,0xc5db,0xc5da,0x3187,0x10a3,0xffdf,0xffff,0xffff,0xf77e,0xe6dd,0xffdf,0xce79,0x0000,0x62ed,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5ba,0xef1e,0x4228,0x2104,0xffff,0xffff,0xffff,0xe6fd,0xc5ba,0xf77e,0xdefb,0x0000,0x62cd,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xffff,0x4228,0x18e3,0xffff,0xffff,0xffff,0xef5e,0xc5ba,0xef3e,0xdefb,0x0000,0x62cd,0xef3e,0xe71c,0x7bef,0xd69a,0xf7be,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xd65c,0xcdfb,0xffff,0x5acb,0x0000,0xffdf,0xffff,0xffff,0xf79e,0xc5ba,0xe6fd,0xc638,0x0000,0x7370,0xef3e,0xffff,0xe71c,0x630c,0x10a2,0x4a69,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xd65c,0xce1b,0xffff,0x738e,0x0000,0xd69a,0xffff,0xffff,0xf7bf,0xc5ba,0xe6dd,0xad55,0x0000,0x8c12,0xef3e,0xffff,0xf79e,0x1082,0x528a,0xb5b6,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xd65c,0xcdfb,0xffff,0xa534,0x0000,0x94b2,0xffff,0xffff,0xf7bf,0xc5ba,0xe6dd,0x9cf3,0x2104,0xbdd9,0xf79f,0xffff,0xffdf,0xf7be,0xffff,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xffff,0xdedb,0x5aeb,0xbdf7,0xffff,0xffff,0xf77e,0xc5ba,0xe71d,0xffff,0xffff,0xffbf,0xde9c,0xc5fb,0xd67c,0xbdf7,0x4a69,0x0020,0xbdf7,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdebd,0xc5ba,0xf79f,0xffff,0xffff,0xffff,0xffff,0xffff,0xef3e,0xc5ba,0xef5e,0xffff,0xffff,0xffff,0xc5fb,0xd67c,0xef5e,0xa534,0x18e3,0x73ae,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xef3e,0xc5ba,0xe71d,0xffff,0xffff,0xffff,0xffff,0xffff,0xef1e,0xce1b,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffbf,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf7bf,0xde9c,0xf77e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf77e,0xd67c,0xc5da,0xf77e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xa534,0x528a,0x4228,0x738e,0xe71c,0xffff,0xffff,0xffff,0xef3e,0xcdfb,0x0000,0x5acb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x52aa,0x0000,0x0861,0x18c3,0x0000,0x18c3,0xdedb,0xffff,0xffff,0xffff,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9492,0x0000,0x632c,0xf7be,0xffff,0xb5b6,0x0841,0x3186,0xffff,0xffff,0xffff,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71d,0x10a2,0x20e4,0xdebc,0xffbf,0xffff,0xffff,0x73ae,0x0000,0xbdd7,0xc5ba,0xde9c,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd67c,0x9474,0x0000,0x7370,0xc5ba,0xcdfb,0xf7bf,0xffff,0xd6ba,0x0000,0x6b6d,0xc5ba,0xde9c,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5ba,0x7bd0,0x0000,0xd69a,0xef5e,0xc5db,0xce3b,0xffff,0xffff,0x1082,0x4a49,0xc5ba,0xde9c,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xcdfb,0xce1b,0x6b6d,0x0000,0xf79e,0xffff,0xdedd,0xc5ba,0xef7e,0xffff,0x2104,0x4228,0xc5ba,0xde9c,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf77e,0xc5ba,0xe71d,0x5aeb,0x0000,0xffff,0xffff,0xf7bf,0xc5ba,0xdebd,0xffff,0x10a2,0x4a69,0xc5ba,0xde9c,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5ba,0xf79f,0x5aeb,0x0000,0xffff,0xffff,0xffff,0xc5fb,0xd65c,0xe71c,0x0000,0x6b6d,0xc5ba,0xde9c,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdebd,0xc5ba,0xffff,0x6b6d,0x0000,0xe73c,0xffff,0xffff,0xce1b,0xd65c,0x9cd3,0x0000,0xb596,0xc5ba,0xde9c,0xffff,0x0000,0x5aeb,0xdedb,0x9cd3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xffff,0x9492,0x0000,0xbdf7,0xffff,0xffff,0xc5fb,0xd67c,0x2965,0x1082,0xf7be,0xc5ba,0xde9c,0xd69a,0x0000,0x0841,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xffff,0xbdf7,0x0000,0x8430,0xffff,0xffbf,0xc5ba,0x8c52,0x0000,0x8410,0xf7be,0x7370,0x2945,0x0000,0x0000,0x18c3,0x6b6d,0xb596,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdebd,0xc5ba,0xffdf,0xf7be,0x4228,0x6b4d,0xffff,0xe71d,0xbd79,0x18c3,0x1082,0x6b6d,0x10a2,0x0000,0x0861,0x632d,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5ba,0xf77e,0xffff,0xffff,0xffff,0xffff,0xce3b,0x5aac,0x0000,0x0000,0x0000,0x2124,0x7370,0xbd9a,0xc5ba,0x0000,0x5acb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf77e,0xc5ba,0xe6fd,0xffff,0xffff,0xffff,0xef3e,0xc5ba,0x9cb4,0x0000,0x2945,0x8c33,0xc5ba,0xc5ba,0xcdfb,0xdebd,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xd65c,0xdebc,0xffff,0xffff,0xffff,0xcdfb,0xc5fb,0xdebd,0x9474,0xc5ba,0xc5fb,0xdebc,0xc5ba,0xde9c,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedd,0xc5ba,0xc5ba,0xc5ba,0xce1b,0xe71d,0xffff,0xffff,0xc5ba,0xde9c,0xffff,0x7bef,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5e,0xc5ba,0xce3b,0xef5e,0xffff,0xffff,0xffff,0xffff,0xc5ba,0xde9c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf77e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc5ba,0xde9c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedb,0xb596,0x9cf3,0x7bef,0x7bef,0x736e,0x73af,0xa514,0xad55,0xc638,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0x632c,0x18c3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x31a6,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9cd3,0x0020,0x0000,0x18e3,0x632c,0xa514,0xc638,0xdefb,0xdefb,0xdefb,0xd69a,0xc638,0x9cf3,0x738e,0x8c51,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0x0020,0x18c3,0x9cd4,0xe6fd,0xe6dd,0xe6dd,0xe6dd,0xe6dd,0xef3e,0xef3e,0xf77e,0xffbf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7bf,0x8c32,0x0000,0x4a2a,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xce3b,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5da,0xa4d6,0x0000,0x0000,0x4a49,0xb576,0xef7e,0xf7bf,0xf7bf,0xf79f,0xf77e,0xef1e,0xdebd,0xe6fd,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf7bf,0xc5da,0xcdfb,0xef3e,0x94b2,0x1082,0x0000,0x0000,0x2104,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xef3e,0xc5ba,0xde9c,0xffff,0xffff,0xef7d,0x94b2,0x4208,0x7bcf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf79f,0xc5ba,0xc5ba,0xd67c,0xef7e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5fb,0xc5ba,0xc5ba,0xce1b,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xe71d,0xd65c,0xe6dd,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0x8410,0x18e3,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xad55,0x52aa,0x0841,0x0000,0x0841,0xc618,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0xd69a,0xbdd7,0x94b2,0x6b4d,0x39c7,0x0020,0x0000,0x0000,0x2104,0x8c51,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4208,0x0000,0x0000,0x0000,0x0000,0x0000,0x2945,0x630d,0x9c94,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8410,0x4228,0x630c,0x8430,0xad35,0xc5fa,0xc5db,0xc5ba,0xc5db,0xf77e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffbf,0xf79f,0xef7e,0xe71d,0xdebc,0xd63c,0xc5da,0xc5ba,0xc5ba,0xce1b,0xe6fd,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd65c,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xce1b,0xdebd,0xf77e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe6dd,0xd65c,0xde9c,0xe6fd,0xef5e,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0x8c51,0x7bef,0x7bef,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe71d,0xe6dd,0xe6dd,0x8c71,0x7bef,0x7bef,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe71d,0xe6dd,0xe6dd,0x2104,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff};
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-corgi b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-corgi
deleted file mode 100644
index 3f1fe02f41..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-corgi
+++ /dev/null
@@ -1,1304 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-CONFIG_ARCH_PXA=y
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_MX1ADS is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-
-#
-# Archimedes/A5000 Implementations (select only ONE)
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CEP is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_COLLIE is not set
-# CONFIG_LOCOMO is not set
-# CONFIG_COLLIE_TS is not set
-# CONFIG_COLLIE_TR0 is not set
-# CONFIG_COLLIE_TR1 is not set
-# CONFIG_COLLIE_DEV is not set
-# CONFIG_COLLIE_G is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_H3XXX is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_FRODO is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_USB is not set
-# CONFIG_SA1100_USB_NETLINK is not set
-# CONFIG_SA1100_USB_CHAR is not set
-# CONFIG_H3600_SLEEVE is not set
-
-#
-# Intel PXA250/210 Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_ARCH_PXA_IDP is not set
-# CONFIG_ARCH_PXA_CERF is not set
-# CONFIG_COTULLA_DMA is not set
-# CONFIG_SABINAL_DISCOVERY is not set
-# CONFIG_ARCH_SABINAL is not set
-# CONFIG_ARCH_PXA_POODLE is not set
-# CONFIG_POODLE_TR0 is not set
-CONFIG_ARCH_PXA_CORGI=y
-# CONFIG_CORGI_TR0 is not set
-CONFIG_CORGI_LCD_BUFF=y
-# CONFIG_ARCH_PXA_SHEPHERD is not set
-# CONFIG_ARCH_PXA_HUSKY is not set
-# CONFIG_ARCH_PXA_BOXER is not set
-# CONFIG_ARCH_PXA_TOSA is not set
-# CONFIG_ARCH_PXA_TOSA_SKIP is not set
-CONFIG_ARCH_SHARP_SL=y
-CONFIG_SL_CCCR_CHANGE=y
-# CONFIG_SL_CCCR242 is not set
-# CONFIG_SL_CCCR162 is not set
-
-#
-# Language type
-#
-CONFIG_ARCH_SHARP_SL_E=y
-# CONFIG_ARCH_SHARP_SL_V is not set
-# CONFIG_ARCH_SHARP_SL_G is not set
-# CONFIG_ARCH_SHARP_SL_J is not set
-# CONFIG_ARCH_SHARP_SL_S is not set
-# CONFIG_ARCH_SHARP_SL_I is not set
-# CONFIG_PXA_USB is not set
-# CONFIG_PXA_USB_NETLINK is not set
-# CONFIG_PXA_USB_CHAR is not set
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_FORTUNET is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-
-#
-# Processor Type
-#
-# CONFIG_CPU_32v3 is not set
-# CONFIG_CPU_32v4 is not set
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM922T is not set
-# CONFIG_PLD is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_SA110 is not set
-# CONFIG_CPU_SA1100 is not set
-CONFIG_CPU_32v5=y
-CONFIG_CPU_XSCALE=y
-CONFIG_BATT=y
-CONFIG_XSCALE_CACHE_ERRATA=y
-CONFIG_ARM_THUMB=y
-# CONFIG_ARM_FCSE is not set
-# CONFIG_DISCONTIGMEM is not set
-# CONFIG_PREEMPT is not set
-
-#
-# General setup
-#
-# CONFIG_PCI is not set
-# CONFIG_ISA is not set
-# CONFIG_ISA_DMA is not set
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=y
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_CLPS6700 is not set
-# CONFIG_PCMCIA_SA1100 is not set
-CONFIG_PCMCIA_PXA=y
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_PM=y
-CONFIG_APM=y
-# CONFIG_APM_IGNORE_USER_SUSPEND is not set
-CONFIG_APM_CPU_IDLE=y
-CONFIG_APM_DISPLAY_BLANK=y
-CONFIG_APM_RTC_IS_GMT=y
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="<see .oe file>"
-# CONFIG_SHARPSL_BOOTLDR_PARAMS is not set
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_FREEPG_SIGNAL=y
-CONFIG_OOM_KILL_SURVIVAL=y
-CONFIG_DEVICEINFO=m
-CONFIG_CORGI_DEVICEINFO=m
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-# CONFIG_MTD_CFI is not set
-# CONFIG_MTD_JEDECPROBE is not set
-# CONFIG_MTD_GEN_PROBE is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-CONFIG_MTD_ROM=y
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_LUBBOCK is not set
-# CONFIG_MTD_NORA is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-# CONFIG_MTD_SA1100 is not set
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_FORTUNET is not set
-# CONFIG_MTD_PXA_CERF is not set
-# CONFIG_MTD_EPXA10DB is not set
-# CONFIG_MTD_AUTCPU12 is not set
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_DISCOVERY is not set
-CONFIG_MTD_SHARP_SL=y
-# CONFIG_MTD_PCI is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDROM_SA1100 is not set
-# CONFIG_MTD_MTDRAM_SA1100 is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_MTDRAM_SHARP_SL is not set
-# CONFIG_MTD_BLKMTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC1000 is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
-CONFIG_MTD_NAND_POST_BADBLOCK=y
-# CONFIG_MTD_NAND_ERASE_BY_FORCE is not set
-CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS=y
-CONFIG_MTD_NAND_PAGE_CACHE=y
-CONFIG_MTD_NAND_SHARP_SL_CORGI=y
-CONFIG_MTD_NAND_SHARP_SL=y
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-CONFIG_SYN_COOKIES=y
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=y
-# CONFIG_IP_NF_MATCH_LIMIT is not set
-# CONFIG_IP_NF_MATCH_MAC is not set
-# CONFIG_IP_NF_MATCH_MARK is not set
-# CONFIG_IP_NF_MATCH_MULTIPORT is not set
-# CONFIG_IP_NF_MATCH_TOS is not set
-# CONFIG_IP_NF_MATCH_AH_ESP is not set
-# CONFIG_IP_NF_MATCH_LENGTH is not set
-# CONFIG_IP_NF_MATCH_TTL is not set
-# CONFIG_IP_NF_MATCH_TCPMSS is not set
-# CONFIG_IP_NF_MATCH_UNCLEAN is not set
-# CONFIG_IP_NF_MATCH_OWNER is not set
-CONFIG_IP_NF_FILTER=y
-CONFIG_IP_NF_TARGET_REJECT=y
-# CONFIG_IP_NF_TARGET_MIRROR is not set
-# CONFIG_IP_NF_MANGLE is not set
-CONFIG_IP_NF_TARGET_LOG=y
-# CONFIG_IP_NF_TARGET_ULOG is not set
-# CONFIG_IP_NF_TARGET_TCPMSS is not set
-CONFIG_IPV6=y
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-CONFIG_IP6_NF_IPTABLES=y
-# CONFIG_IP6_NF_MATCH_LIMIT is not set
-# CONFIG_IP6_NF_MATCH_MAC is not set
-# CONFIG_IP6_NF_MATCH_MULTIPORT is not set
-# CONFIG_IP6_NF_MATCH_OWNER is not set
-# CONFIG_IP6_NF_MATCH_MARK is not set
-CONFIG_IP6_NF_FILTER=y
-CONFIG_IP6_NF_TARGET_LOG=y
-# CONFIG_IP6_NF_MANGLE is not set
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-
-#
-#
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-CONFIG_IPSEC=m
-
-#
-# IPSec options (Openswan)
-#
-CONFIG_IPSEC_IPIP=y
-CONFIG_IPSEC_AH=y
-# CONFIG_IPSEC_AUTH_HMAC_MD5 is not set
-CONFIG_IPSEC_AUTH_HMAC_SHA1=y
-CONFIG_IPSEC_ESP=y
-CONFIG_IPSEC_ENC_3DES=y
-# CONFIG_IPSEC_ENC_AES is not set
-CONFIG_IPSEC_ALG=y
-CONFIG_IPSEC_IPCOMP=y
-CONFIG_IPSEC_DEBUG=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_ARM_AM79C961A is not set
-# CONFIG_SUNLANCE is not set
-# CONFIG_SUNBMAC is not set
-# CONFIG_SUNQE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=y
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=y
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-CONFIG_PPP_BSDCOMP=y
-CONFIG_PPP_MPPE=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_STRIP is not set
-# CONFIG_WAVELAN is not set
-# CONFIG_ARLAN is not set
-# CONFIG_AIRONET4500 is not set
-# CONFIG_AIRONET4500_NONCS is not set
-# CONFIG_AIRONET4500_PROC is not set
-# CONFIG_HERMES is not set
-
-#
-# Wireless Pcmcia cards support
-#
-# CONFIG_PCMCIA_HERMES is not set
-# CONFIG_AIRO_CS is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-# CONFIG_PCMCIA_3C589 is not set
-# CONFIG_PCMCIA_3C574 is not set
-# CONFIG_PCMCIA_FMVJ18X is not set
-CONFIG_PCMCIA_PCNET=y
-# CONFIG_PCMCIA_AXNET is not set
-# CONFIG_PCMCIA_NMCLAN is not set
-# CONFIG_PCMCIA_SMC91C92 is not set
-# CONFIG_PCMCIA_XIRC2PS is not set
-# CONFIG_ARCNET_COM20020_CS is not set
-# CONFIG_PCMCIA_IBMTR is not set
-# CONFIG_NET_PCMCIA_RADIO is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-CONFIG_IRDA=y
-
-#
-# IrDA protocols
-#
-# CONFIG_IRLAN is not set
-CONFIG_IRNET=m
-CONFIG_IRCOMM=y
-# CONFIG_IRDA_ULTRA is not set
-
-#
-# IrDA options
-#
-# CONFIG_IRDA_CACHE_LAST_LSAP is not set
-CONFIG_IRDA_FAST_RR=y
-# CONFIG_IRDA_DEBUG is not set
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=y
-# CONFIG_IRPORT_SIR is not set
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-
-#
-# ATA/IDE/MFM/RLL support
-#
-CONFIG_IDE=y
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-# CONFIG_BLK_DEV_IDEDISK_WD is not set
-# CONFIG_BLK_DEV_COMMERIAL is not set
-# CONFIG_BLK_DEV_TIVO is not set
-CONFIG_BLK_DEV_IDECS=y
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_DMA_NONPCI is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-
-#
-# SCSI support
-#
-# CONFIG_SCSI is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_UINPUT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
-CONFIG_SERIAL_SL_SERIES=y
-# CONFIG_SL_TS_PRESSURE is not set
-# CONFIG_BOOT_PRESSURE_ON is not set
-CONFIG_SL7X0_POWER_KEY_OFF=y
-# CONFIG_BOOT_POWER_KEY_OFF is not set
-# CONFIG_SL_3BUTTON_PATCH is not set
-# CONFIG_BOOT_3BUTTON_PATCH_ON is not set
-# CONFIG_SL_WRITE_TS is not set
-# CONFIG_BLUETOOTH_SL is not set
-# CONFIG_KBD_DEV_FILE is not set
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_ANAKIN is not set
-# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_UART00 is not set
-# CONFIG_SERIAL_UART00_CONSOLE is not set
-# CONFIG_SERIAL_SA1100 is not set
-# CONFIG_SERIAL_SA1100_CONSOLE is not set
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# L3 serial bus support
-#
-# CONFIG_L3 is not set
-# CONFIG_L3_ALGOBIT is not set
-# CONFIG_L3_BIT_SA1100_GPIO is not set
-
-#
-# Other L3 adapters
-#
-# CONFIG_L3_SA1111 is not set
-# CONFIG_BIT_SA1100_GPIO is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-
-#
-# Input core support is needed for gameports
-#
-
-#
-# Input core support is needed for joysticks
-#
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_COTULLA_RTC=y
-CONFIG_ADS7846_TS=y
-# CONFIG_TOSA_TS is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-CONFIG_PCMCIA_SERIAL_CS=y
-CONFIG_PCMCIA_CHRDEV=y
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FS_SYNC is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=y
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=y
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_NAND=y
-CONFIG_JFFS2_PROC_FS=y
-CONFIG_JFFS2_NODEMERGE=y
-CONFIG_JFFS2_DYNFRAGTREE=y
-CONFIG_CRAMFS=y
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-CONFIG_MINIX_FS=y
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_ROOT_NFS is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_CIFS=m
-# CONFIG_CIFS_STATS is not set
-CONFIG_CIFS_POSIX=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-CONFIG_ZLIB_FS_INFLATE=y
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-CONFIG_NLS_CODEPAGE_850=y
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-CONFIG_NLS_CODEPAGE_932=y
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-CONFIG_NLS_UTF8=y
-
-#
-# Console drivers
-#
-CONFIG_PC_KEYMAP=y
-# CONFIG_VGA_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_UNICON is not set
-# CONFIG_FB_COLLIE is not set
-# CONFIG_FB_ACORN is not set
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_SA1100 is not set
-# CONFIG_FB_PXA is not set
-# CONFIG_FB_COTULLA is not set
-# CONFIG_FB_POODLE is not set
-CONFIG_FB_CORGI=y
-# CONFIG_FB_TOSA is not set
-# CONFIG_SHARP_LOGO_SCREEN is not set
-# CONFIG_SL_SYSCLK100 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-# CONFIG_FBCON_CFB4 is not set
-# CONFIG_FBCON_CFB8 is not set
-CONFIG_FBCON_CFB16=y
-# CONFIG_FBCON_CFB24 is not set
-# CONFIG_FBCON_CFB32 is not set
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA_PLANES is not set
-# CONFIG_FBCON_VGA is not set
-# CONFIG_FBCON_HGA is not set
-CONFIG_FBCON_ROTATE_R=y
-# CONFIG_FBCON_ROTATE_L is not set
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_COLLIE_SSP is not set
-# CONFIG_SOUND_COLLIE_TC35143 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_WAVEARTIST is not set
-# CONFIG_SOUND_PXA_AC97 is not set
-# CONFIG_SOUND_POODLE is not set
-CONFIG_SOUND_CORGI=y
-# CONFIG_SOUND_TOSA is not set
-# CONFIG_BUZZER_TOSA is not set
-# CONFIG_SOUND_TVMIXER is not set
-
-#
-# Multimedia Capabilities Port drivers
-#
-# CONFIG_MCP is not set
-# CONFIG_MCP_SA1100 is not set
-# CONFIG_MCP_UCB1200 is not set
-# CONFIG_MCP_UCB1200_AUDIO is not set
-# CONFIG_MCP_UCB1200_TS is not set
-# CONFIG_MCP_UCB1400_TS is not set
-
-#
-# USB support
-#
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_LONG_TIMEOUT is not set
-
-#
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-# CONFIG_USB_OHCI_SA1111 is not set
-# CONFIG_USB_OHCI_TC6393 is not set
-# CONFIG_USB_USE_INTERNAL_MEMORY is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_AUDIO is not set
-
-#
-# USB Bluetooth can only be used with disabled Bluetooth subsystem
-#
-
-#
-# SCSI support is needed for USB Storage
-#
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-
-#
-# Input core support is needed for USB HID
-#
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDCETHER is not set
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_RIO500 is not set
-
-#
-# USB Device Support
-#
-CONFIG_USBD=m
-CONFIG_USBD_VENDORID=04DD
-CONFIG_USBD_PRODUCTID=8007
-CONFIG_USBD_PRODUCT_NAME="SL-C700"
-CONFIG_USBD_MANUFACTURER="Sharp"
-# CONFIG_USBD_USE_SERIAL_NUMBER is not set
-CONFIG_USBD_SELFPOWERED=y
-CONFIG_USBD_MONITOR=m
-
-#
-#
-#
-# CONFIG_USBD_PROCFS is not set
-
-#
-# USB Device functions
-#
-
-#
-# Network Function
-#
-CONFIG_USBD_NET=m
-CONFIG_USBD_NET_VENDORID=04DD
-CONFIG_USBD_NET_PRODUCTID=8007
-CONFIG_USBD_NET_IFNAME="usbd"
-CONFIG_USBD_NET_OUT_ENDPOINT=1
-CONFIG_USBD_NET_OUT_PKTSIZE=64
-CONFIG_USBD_NET_IN_ENDPOINT=2
-CONFIG_USBD_NET_IN_PKTSIZE=64
-CONFIG_USBD_NET_INT_ENDPOINT=3
-CONFIG_USBD_NET_INT_PKTSIZE=16
-# CONFIG_USBD_NET_ALWAYSUP is not set
-# CONFIG_USBD_NET_SAFE is not set
-CONFIG_USBD_NET_MDLM=y
-# CONFIG_USBD_NET_CDC is not set
-CONFIG_USBD_NET_REMOTE_MACADDR="400001000002"
-CONFIG_USBD_NET_REMOTE_OUI=400002
-CONFIG_USBD_MAC_AS_SERIAL_NUMBER=y
-CONFIG_USBD_NET_LOCAL_MACADDR="400001000001"
-CONFIG_USBD_NET_LOCAL_OUI=400001
-
-#
-# Serial Function
-#
-# CONFIG_USBD_SERIAL is not set
-
-#
-# Mass Storage Function
-#
-CONFIG_USBD_STORAGE=m
-CONFIG_USBD_STORAGE_VENDORID=0000
-CONFIG_USBD_STORAGE_PRODUCTID=0000
-CONFIG_USBD_STORAGE_OUT_ENDPOINT=1
-CONFIG_USBD_STORAGE_OUT_PKTSIZE=64
-CONFIG_USBD_STORAGE_IN_ENDPOINT=2
-CONFIG_USBD_STORAGE_IN_PKTSIZE=64
-CONFIG_USBD_STORAGE_INT_ENDPOINT=3
-CONFIG_USBD_STORAGE_INT_PKTSIZE=16
-CONFIG_USBD_STORAGE_DEF_DEVICE_NAME="SL-C700"
-
-#
-# USB Device bus interfaces
-#
-
-#
-# USB Device Bus Interface Support
-#
-CONFIG_USBD_PXA_BUS=m
-# CONFIG_USBD_GENERIC_BUS is not set
-
-#
-# Bluetooth support
-#
-CONFIG_BLUEZ=y
-CONFIG_BLUEZ_L2CAP=y
-CONFIG_BLUEZ_SCO=y
-CONFIG_BLUEZ_RFCOMM=y
-CONFIG_BLUEZ_RFCOMM_TTY=y
-CONFIG_BLUEZ_BNEP=y
-CONFIG_BLUEZ_BNEP_MC_FILTER=y
-CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
-# CONFIG_BLUEZ_HIDP is not set
-
-#
-# Bluetooth device drivers
-#
-CONFIG_BLUEZ_HCIUSB=m
-CONFIG_BLUEZ_HCIUSB_SCO=y
-CONFIG_BLUEZ_HCIUART=y
-CONFIG_BLUEZ_HCIUART_H4=y
-CONFIG_BLUEZ_HCIUART_BCSP=y
-CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y
-CONFIG_BLUEZ_HCIBFUSB=m
-CONFIG_BLUEZ_HCIDTL1=m
-CONFIG_BLUEZ_HCIBLUECARD=m
-CONFIG_BLUEZ_HCIBTUART=m
-CONFIG_BLUEZ_HCIVHCI=m
-CONFIG_BLUEZ_BT950=m
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_COREDUMP_SIGNAL is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_NO_PGT_CACHE is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_ERRORS is not set
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-husky b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-husky
deleted file mode 100644
index bc972265fd..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-husky
+++ /dev/null
@@ -1,1304 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-CONFIG_ARCH_PXA=y
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_MX1ADS is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-
-#
-# Archimedes/A5000 Implementations (select only ONE)
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CEP is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_COLLIE is not set
-# CONFIG_LOCOMO is not set
-# CONFIG_COLLIE_TS is not set
-# CONFIG_COLLIE_TR0 is not set
-# CONFIG_COLLIE_TR1 is not set
-# CONFIG_COLLIE_DEV is not set
-# CONFIG_COLLIE_G is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_H3XXX is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_FRODO is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_USB is not set
-# CONFIG_SA1100_USB_NETLINK is not set
-# CONFIG_SA1100_USB_CHAR is not set
-# CONFIG_H3600_SLEEVE is not set
-
-#
-# Intel PXA250/210 Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_ARCH_PXA_IDP is not set
-# CONFIG_ARCH_PXA_CERF is not set
-# CONFIG_COTULLA_DMA is not set
-# CONFIG_SABINAL_DISCOVERY is not set
-# CONFIG_ARCH_SABINAL is not set
-# CONFIG_ARCH_PXA_POODLE is not set
-# CONFIG_POODLE_TR0 is not set
-CONFIG_ARCH_PXA_CORGI=y
-# CONFIG_CORGI_TR0 is not set
-CONFIG_CORGI_LCD_BUFF=y
-CONFIG_ARCH_PXA_SHEPHERD=y
-CONFIG_ARCH_PXA_HUSKY=y
-CONFIG_ARCH_PXA_BOXER=y
-# CONFIG_ARCH_PXA_TOSA is not set
-# CONFIG_ARCH_PXA_TOSA_SKIP is not set
-CONFIG_ARCH_SHARP_SL=y
-CONFIG_SL_CCCR_CHANGE=y
-# CONFIG_SL_CCCR242 is not set
-# CONFIG_SL_CCCR162 is not set
-
-#
-# Language type
-#
-CONFIG_ARCH_SHARP_SL_E=y
-# CONFIG_ARCH_SHARP_SL_V is not set
-# CONFIG_ARCH_SHARP_SL_G is not set
-# CONFIG_ARCH_SHARP_SL_J is not set
-# CONFIG_ARCH_SHARP_SL_S is not set
-# CONFIG_ARCH_SHARP_SL_I is not set
-# CONFIG_PXA_USB is not set
-# CONFIG_PXA_USB_NETLINK is not set
-# CONFIG_PXA_USB_CHAR is not set
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_FORTUNET is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-
-#
-# Processor Type
-#
-# CONFIG_CPU_32v3 is not set
-# CONFIG_CPU_32v4 is not set
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM922T is not set
-# CONFIG_PLD is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_SA110 is not set
-# CONFIG_CPU_SA1100 is not set
-CONFIG_CPU_32v5=y
-CONFIG_CPU_XSCALE=y
-CONFIG_BATT=y
-# CONFIG_XSCALE_CACHE_ERRATA is not set
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_FCSE=y
-# CONFIG_DISCONTIGMEM is not set
-# CONFIG_PREEMPT is not set
-
-#
-# General setup
-#
-# CONFIG_PCI is not set
-# CONFIG_ISA is not set
-# CONFIG_ISA_DMA is not set
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=y
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_CLPS6700 is not set
-# CONFIG_PCMCIA_SA1100 is not set
-CONFIG_PCMCIA_PXA=y
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_PM=y
-CONFIG_APM=y
-# CONFIG_APM_IGNORE_USER_SUSPEND is not set
-CONFIG_APM_CPU_IDLE=y
-CONFIG_APM_DISPLAY_BLANK=y
-CONFIG_APM_RTC_IS_GMT=y
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="<see .oe file>"
-# CONFIG_SHARPSL_BOOTLDR_PARAMS is not set
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_FREEPG_SIGNAL=y
-CONFIG_OOM_KILL_SURVIVAL=y
-CONFIG_DEVICEINFO=m
-CONFIG_CORGI_DEVICEINFO=m
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-# CONFIG_MTD_CFI is not set
-# CONFIG_MTD_JEDECPROBE is not set
-# CONFIG_MTD_GEN_PROBE is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-CONFIG_MTD_ROM=y
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_LUBBOCK is not set
-# CONFIG_MTD_NORA is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-# CONFIG_MTD_SA1100 is not set
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_FORTUNET is not set
-# CONFIG_MTD_PXA_CERF is not set
-# CONFIG_MTD_EPXA10DB is not set
-# CONFIG_MTD_AUTCPU12 is not set
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_DISCOVERY is not set
-CONFIG_MTD_SHARP_SL=y
-# CONFIG_MTD_PCI is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDROM_SA1100 is not set
-# CONFIG_MTD_MTDRAM_SA1100 is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_MTDRAM_SHARP_SL is not set
-# CONFIG_MTD_BLKMTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC1000 is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
-CONFIG_MTD_NAND_POST_BADBLOCK=y
-# CONFIG_MTD_NAND_ERASE_BY_FORCE is not set
-CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS=y
-CONFIG_MTD_NAND_PAGE_CACHE=y
-CONFIG_MTD_NAND_SHARP_SL_CORGI=y
-CONFIG_MTD_NAND_SHARP_SL=y
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-CONFIG_SYN_COOKIES=y
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=y
-# CONFIG_IP_NF_MATCH_LIMIT is not set
-# CONFIG_IP_NF_MATCH_MAC is not set
-# CONFIG_IP_NF_MATCH_MARK is not set
-# CONFIG_IP_NF_MATCH_MULTIPORT is not set
-# CONFIG_IP_NF_MATCH_TOS is not set
-# CONFIG_IP_NF_MATCH_AH_ESP is not set
-# CONFIG_IP_NF_MATCH_LENGTH is not set
-# CONFIG_IP_NF_MATCH_TTL is not set
-# CONFIG_IP_NF_MATCH_TCPMSS is not set
-# CONFIG_IP_NF_MATCH_UNCLEAN is not set
-# CONFIG_IP_NF_MATCH_OWNER is not set
-CONFIG_IP_NF_FILTER=y
-CONFIG_IP_NF_TARGET_REJECT=y
-# CONFIG_IP_NF_TARGET_MIRROR is not set
-# CONFIG_IP_NF_MANGLE is not set
-CONFIG_IP_NF_TARGET_LOG=y
-# CONFIG_IP_NF_TARGET_ULOG is not set
-# CONFIG_IP_NF_TARGET_TCPMSS is not set
-CONFIG_IPV6=y
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-CONFIG_IP6_NF_IPTABLES=y
-# CONFIG_IP6_NF_MATCH_LIMIT is not set
-# CONFIG_IP6_NF_MATCH_MAC is not set
-# CONFIG_IP6_NF_MATCH_MULTIPORT is not set
-# CONFIG_IP6_NF_MATCH_OWNER is not set
-# CONFIG_IP6_NF_MATCH_MARK is not set
-CONFIG_IP6_NF_FILTER=y
-CONFIG_IP6_NF_TARGET_LOG=y
-# CONFIG_IP6_NF_MANGLE is not set
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-
-#
-#
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-CONFIG_IPSEC=m
-
-#
-# IPSec options (Openswan)
-#
-CONFIG_IPSEC_IPIP=y
-CONFIG_IPSEC_AH=y
-# CONFIG_IPSEC_AUTH_HMAC_MD5 is not set
-CONFIG_IPSEC_AUTH_HMAC_SHA1=y
-CONFIG_IPSEC_ESP=y
-CONFIG_IPSEC_ENC_3DES=y
-# CONFIG_IPSEC_ENC_AES is not set
-CONFIG_IPSEC_ALG=y
-CONFIG_IPSEC_IPCOMP=y
-CONFIG_IPSEC_DEBUG=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_ARM_AM79C961A is not set
-# CONFIG_SUNLANCE is not set
-# CONFIG_SUNBMAC is not set
-# CONFIG_SUNQE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=y
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=y
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-CONFIG_PPP_BSDCOMP=y
-CONFIG_PPP_MPPE=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_STRIP is not set
-# CONFIG_WAVELAN is not set
-# CONFIG_ARLAN is not set
-# CONFIG_AIRONET4500 is not set
-# CONFIG_AIRONET4500_NONCS is not set
-# CONFIG_AIRONET4500_PROC is not set
-# CONFIG_HERMES is not set
-
-#
-# Wireless Pcmcia cards support
-#
-# CONFIG_PCMCIA_HERMES is not set
-# CONFIG_AIRO_CS is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-# CONFIG_PCMCIA_3C589 is not set
-# CONFIG_PCMCIA_3C574 is not set
-# CONFIG_PCMCIA_FMVJ18X is not set
-CONFIG_PCMCIA_PCNET=y
-# CONFIG_PCMCIA_AXNET is not set
-# CONFIG_PCMCIA_NMCLAN is not set
-# CONFIG_PCMCIA_SMC91C92 is not set
-# CONFIG_PCMCIA_XIRC2PS is not set
-# CONFIG_ARCNET_COM20020_CS is not set
-# CONFIG_PCMCIA_IBMTR is not set
-# CONFIG_NET_PCMCIA_RADIO is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-CONFIG_IRDA=y
-
-#
-# IrDA protocols
-#
-# CONFIG_IRLAN is not set
-CONFIG_IRNET=m
-CONFIG_IRCOMM=y
-# CONFIG_IRDA_ULTRA is not set
-
-#
-# IrDA options
-#
-# CONFIG_IRDA_CACHE_LAST_LSAP is not set
-CONFIG_IRDA_FAST_RR=y
-# CONFIG_IRDA_DEBUG is not set
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=y
-# CONFIG_IRPORT_SIR is not set
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-
-#
-# ATA/IDE/MFM/RLL support
-#
-CONFIG_IDE=y
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-# CONFIG_BLK_DEV_IDEDISK_WD is not set
-# CONFIG_BLK_DEV_COMMERIAL is not set
-# CONFIG_BLK_DEV_TIVO is not set
-CONFIG_BLK_DEV_IDECS=y
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_DMA_NONPCI is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-
-#
-# SCSI support
-#
-# CONFIG_SCSI is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_UINPUT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
-CONFIG_SERIAL_SL_SERIES=y
-# CONFIG_SL_TS_PRESSURE is not set
-# CONFIG_BOOT_PRESSURE_ON is not set
-CONFIG_SL7X0_POWER_KEY_OFF=y
-# CONFIG_BOOT_POWER_KEY_OFF is not set
-# CONFIG_SL_3BUTTON_PATCH is not set
-# CONFIG_BOOT_3BUTTON_PATCH_ON is not set
-# CONFIG_SL_WRITE_TS is not set
-# CONFIG_BLUETOOTH_SL is not set
-# CONFIG_KBD_DEV_FILE is not set
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_ANAKIN is not set
-# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_UART00 is not set
-# CONFIG_SERIAL_UART00_CONSOLE is not set
-# CONFIG_SERIAL_SA1100 is not set
-# CONFIG_SERIAL_SA1100_CONSOLE is not set
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# L3 serial bus support
-#
-# CONFIG_L3 is not set
-# CONFIG_L3_ALGOBIT is not set
-# CONFIG_L3_BIT_SA1100_GPIO is not set
-
-#
-# Other L3 adapters
-#
-# CONFIG_L3_SA1111 is not set
-# CONFIG_BIT_SA1100_GPIO is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-
-#
-# Input core support is needed for gameports
-#
-
-#
-# Input core support is needed for joysticks
-#
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_COTULLA_RTC=y
-CONFIG_ADS7846_TS=y
-# CONFIG_TOSA_TS is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-CONFIG_PCMCIA_SERIAL_CS=y
-CONFIG_PCMCIA_CHRDEV=y
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FS_SYNC is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=y
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=y
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_NAND=y
-CONFIG_JFFS2_PROC_FS=y
-CONFIG_JFFS2_NODEMERGE=y
-CONFIG_JFFS2_DYNFRAGTREE=y
-CONFIG_CRAMFS=y
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-CONFIG_MINIX_FS=y
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_ROOT_NFS is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_CIFS=m
-# CONFIG_CIFS_STATS is not set
-CONFIG_CIFS_POSIX=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-CONFIG_ZLIB_FS_INFLATE=y
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-CONFIG_NLS_CODEPAGE_850=y
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-CONFIG_NLS_CODEPAGE_932=y
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-CONFIG_NLS_UTF8=y
-
-#
-# Console drivers
-#
-CONFIG_PC_KEYMAP=y
-# CONFIG_VGA_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_UNICON is not set
-# CONFIG_FB_COLLIE is not set
-# CONFIG_FB_ACORN is not set
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_SA1100 is not set
-# CONFIG_FB_PXA is not set
-# CONFIG_FB_COTULLA is not set
-# CONFIG_FB_POODLE is not set
-CONFIG_FB_CORGI=y
-# CONFIG_FB_TOSA is not set
-# CONFIG_SHARP_LOGO_SCREEN is not set
-# CONFIG_SL_SYSCLK100 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-# CONFIG_FBCON_CFB4 is not set
-# CONFIG_FBCON_CFB8 is not set
-CONFIG_FBCON_CFB16=y
-# CONFIG_FBCON_CFB24 is not set
-# CONFIG_FBCON_CFB32 is not set
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA_PLANES is not set
-# CONFIG_FBCON_VGA is not set
-# CONFIG_FBCON_HGA is not set
-CONFIG_FBCON_ROTATE_R=y
-# CONFIG_FBCON_ROTATE_L is not set
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_COLLIE_SSP is not set
-# CONFIG_SOUND_COLLIE_TC35143 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_WAVEARTIST is not set
-# CONFIG_SOUND_PXA_AC97 is not set
-# CONFIG_SOUND_POODLE is not set
-CONFIG_SOUND_CORGI=y
-# CONFIG_SOUND_TOSA is not set
-# CONFIG_BUZZER_TOSA is not set
-# CONFIG_SOUND_TVMIXER is not set
-
-#
-# Multimedia Capabilities Port drivers
-#
-# CONFIG_MCP is not set
-# CONFIG_MCP_SA1100 is not set
-# CONFIG_MCP_UCB1200 is not set
-# CONFIG_MCP_UCB1200_AUDIO is not set
-# CONFIG_MCP_UCB1200_TS is not set
-# CONFIG_MCP_UCB1400_TS is not set
-
-#
-# USB support
-#
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_LONG_TIMEOUT is not set
-
-#
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-# CONFIG_USB_OHCI_SA1111 is not set
-# CONFIG_USB_OHCI_TC6393 is not set
-# CONFIG_USB_USE_INTERNAL_MEMORY is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_AUDIO is not set
-
-#
-# USB Bluetooth can only be used with disabled Bluetooth subsystem
-#
-
-#
-# SCSI support is needed for USB Storage
-#
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-
-#
-# Input core support is needed for USB HID
-#
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDCETHER is not set
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_RIO500 is not set
-
-#
-# USB Device Support
-#
-CONFIG_USBD=m
-CONFIG_USBD_VENDORID=04DD
-CONFIG_USBD_PRODUCTID=8007
-CONFIG_USBD_PRODUCT_NAME="SL-C750"
-CONFIG_USBD_MANUFACTURER="Sharp"
-# CONFIG_USBD_USE_SERIAL_NUMBER is not set
-CONFIG_USBD_SELFPOWERED=y
-CONFIG_USBD_MONITOR=m
-
-#
-#
-#
-# CONFIG_USBD_PROCFS is not set
-
-#
-# USB Device functions
-#
-
-#
-# Network Function
-#
-CONFIG_USBD_NET=m
-CONFIG_USBD_NET_VENDORID=04DD
-CONFIG_USBD_NET_PRODUCTID=8007
-CONFIG_USBD_NET_IFNAME="usbd"
-CONFIG_USBD_NET_OUT_ENDPOINT=1
-CONFIG_USBD_NET_OUT_PKTSIZE=64
-CONFIG_USBD_NET_IN_ENDPOINT=2
-CONFIG_USBD_NET_IN_PKTSIZE=64
-CONFIG_USBD_NET_INT_ENDPOINT=3
-CONFIG_USBD_NET_INT_PKTSIZE=16
-# CONFIG_USBD_NET_ALWAYSUP is not set
-# CONFIG_USBD_NET_SAFE is not set
-CONFIG_USBD_NET_MDLM=y
-# CONFIG_USBD_NET_CDC is not set
-CONFIG_USBD_NET_REMOTE_MACADDR="400001000002"
-CONFIG_USBD_NET_REMOTE_OUI=400002
-CONFIG_USBD_MAC_AS_SERIAL_NUMBER=y
-CONFIG_USBD_NET_LOCAL_MACADDR="400001000001"
-CONFIG_USBD_NET_LOCAL_OUI=400001
-
-#
-# Serial Function
-#
-# CONFIG_USBD_SERIAL is not set
-
-#
-# Mass Storage Function
-#
-CONFIG_USBD_STORAGE=m
-CONFIG_USBD_STORAGE_VENDORID=0000
-CONFIG_USBD_STORAGE_PRODUCTID=0000
-CONFIG_USBD_STORAGE_OUT_ENDPOINT=1
-CONFIG_USBD_STORAGE_OUT_PKTSIZE=64
-CONFIG_USBD_STORAGE_IN_ENDPOINT=2
-CONFIG_USBD_STORAGE_IN_PKTSIZE=64
-CONFIG_USBD_STORAGE_INT_ENDPOINT=3
-CONFIG_USBD_STORAGE_INT_PKTSIZE=16
-CONFIG_USBD_STORAGE_DEF_DEVICE_NAME="SL-C760"
-
-#
-# USB Device bus interfaces
-#
-
-#
-# USB Device Bus Interface Support
-#
-CONFIG_USBD_PXA_BUS=m
-# CONFIG_USBD_GENERIC_BUS is not set
-
-#
-# Bluetooth support
-#
-CONFIG_BLUEZ=y
-CONFIG_BLUEZ_L2CAP=y
-CONFIG_BLUEZ_SCO=y
-CONFIG_BLUEZ_RFCOMM=y
-CONFIG_BLUEZ_RFCOMM_TTY=y
-CONFIG_BLUEZ_BNEP=y
-CONFIG_BLUEZ_BNEP_MC_FILTER=y
-CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
-# CONFIG_BLUEZ_HIDP is not set
-
-#
-# Bluetooth device drivers
-#
-CONFIG_BLUEZ_HCIUSB=m
-CONFIG_BLUEZ_HCIUSB_SCO=y
-CONFIG_BLUEZ_HCIUART=y
-CONFIG_BLUEZ_HCIUART_H4=y
-CONFIG_BLUEZ_HCIUART_BCSP=y
-CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y
-CONFIG_BLUEZ_HCIBFUSB=m
-CONFIG_BLUEZ_HCIDTL1=m
-CONFIG_BLUEZ_HCIBLUECARD=m
-CONFIG_BLUEZ_HCIBTUART=m
-CONFIG_BLUEZ_HCIVHCI=m
-CONFIG_BLUEZ_BT950=m
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_COREDUMP_SIGNAL is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_NO_PGT_CACHE is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_ERRORS is not set
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-poodle b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-poodle
deleted file mode 100644
index 6102a630c0..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-poodle
+++ /dev/null
@@ -1,1110 +0,0 @@
-#
-# Automatically generated by make menuconfig: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-CONFIG_ARCH_PXA=y
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_MX1ADS is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CEP is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_COLLIE is not set
-# CONFIG_LOCOMO is not set
-# CONFIG_COLLIE_TS is not set
-# CONFIG_COLLIE_TR0 is not set
-# CONFIG_COLLIE_TR1 is not set
-# CONFIG_COLLIE_DEV is not set
-# CONFIG_COLLIE_G is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_H3XXX is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_FRODO is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_USB is not set
-# CONFIG_SA1100_USB_NETLINK is not set
-# CONFIG_SA1100_USB_CHAR is not set
-# CONFIG_H3600_SLEEVE is not set
-
-#
-# Intel PXA250/210 Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_ARCH_PXA_IDP is not set
-# CONFIG_ARCH_PXA_CERF is not set
-# CONFIG_COTULLA_DMA is not set
-# CONFIG_SABINAL_DISCOVERY is not set
-# CONFIG_ARCH_SABINAL is not set
-CONFIG_ARCH_PXA_POODLE=y
-# CONFIG_POODLE_TR0 is not set
-# CONFIG_ARCH_PXA_CORGI is not set
-# CONFIG_CORGI_TR0 is not set
-# CONFIG_CORGI_LCD_BUFF is not set
-# CONFIG_ARCH_PXA_SHEPHERD is not set
-# CONFIG_ARCH_PXA_HUSKY is not set
-# CONFIG_ARCH_PXA_BOXER is not set
-CONFIG_ARCH_SHARP_SL=y
-CONFIG_SL_CCCR_CHANGE=y
-CONFIG_SL_CCCR242=y
-CONFIG_ARCH_SHARP_SL_E=y
-# CONFIG_ARCH_SHARP_SL_V is not set
-# CONFIG_ARCH_SHARP_SL_G is not set
-# CONFIG_ARCH_SHARP_SL_J is not set
-# CONFIG_ARCH_SHARP_SL_S is not set
-# CONFIG_ARCH_SHARP_SL_I is not set
-# CONFIG_PXA_USB is not set
-# CONFIG_PXA_USB_NETLINK is not set
-# CONFIG_PXA_USB_CHAR is not set
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_FORTUNET is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-# CONFIG_CPU_32v3 is not set
-# CONFIG_CPU_32v4 is not set
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM922T is not set
-# CONFIG_PLD is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_SA110 is not set
-# CONFIG_CPU_SA1100 is not set
-CONFIG_CPU_32v5=y
-CONFIG_CPU_XSCALE=y
-CONFIG_BATT=y
-CONFIG_XSCALE_CACHE_ERRATA=y
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_FCSE=y
-# CONFIG_DISCONTIGMEM is not set
-# CONFIG_PREEMPT is not set
-
-#
-# General setup
-#
-# CONFIG_PCI is not set
-# CONFIG_ISA is not set
-# CONFIG_ISA_DMA is not set
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=y
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_CLPS6700 is not set
-# CONFIG_PCMCIA_SA1100 is not set
-CONFIG_PCMCIA_PXA=y
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_PM=y
-CONFIG_APM=y
-# CONFIG_APM_IGNORE_USER_SUSPEND is not set
-CONFIG_APM_CPU_IDLE=y
-CONFIG_APM_DISPLAY_BLANK=y
-CONFIG_APM_RTC_IS_GMT=y
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="<see .oe file>"
-# CONFIG_SHARPSL_BOOTLDR_PARAMS is not set
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_FREEPG_SIGNAL=y
-CONFIG_OOM_KILL_SURVIVAL=y
-CONFIG_DEVICEINFO=m
-CONFIG_POODLE_DEVICEINFO=m
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-# CONFIG_MTD_CFI is not set
-# CONFIG_MTD_JEDECPROBE is not set
-# CONFIG_MTD_GEN_PROBE is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-CONFIG_MTD_ROM=y
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_LUBBOCK is not set
-# CONFIG_MTD_NORA is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-# CONFIG_MTD_SA1100 is not set
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_FORTUNET is not set
-# CONFIG_MTD_PXA_CERF is not set
-# CONFIG_MTD_EPXA10DB is not set
-# CONFIG_MTD_AUTCPU12 is not set
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_DISCOVERY is not set
-CONFIG_MTD_SHARP_SL=y
-# CONFIG_MTD_PCI is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDROM_SA1100 is not set
-# CONFIG_MTD_MTDRAM_SA1100 is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_MTDRAM_SHARP_SL is not set
-# CONFIG_MTD_BLKMTD is not set
-# CONFIG_MTD_DOC1000 is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
-CONFIG_MTD_NAND_POST_BADBLOCK=y
-# CONFIG_MTD_NAND_ERASE_BY_FORCE is not set
-CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS=y
-CONFIG_MTD_NAND_PAGE_CACHE=y
-CONFIG_MTD_NAND_SHARP_SL_POODLE=y
-CONFIG_MTD_NAND_SHARP_SL=y
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_BLK_DEV_INITRD=y
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-# CONFIG_IPV6 is not set
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_ARM_AM79C961A is not set
-# CONFIG_SUNLANCE is not set
-# CONFIG_SUNBMAC is not set
-# CONFIG_SUNQE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=y
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=y
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-CONFIG_PPP_BSDCOMP=y
-CONFIG_PPP_MPPE=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_STRIP is not set
-# CONFIG_WAVELAN is not set
-# CONFIG_ARLAN is not set
-# CONFIG_AIRONET4500 is not set
-# CONFIG_AIRONET4500_NONCS is not set
-# CONFIG_AIRONET4500_PROC is not set
-# CONFIG_HERMES is not set
-# CONFIG_PCMCIA_HERMES is not set
-# CONFIG_AIRO_CS is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-# CONFIG_PCMCIA_3C589 is not set
-# CONFIG_PCMCIA_3C574 is not set
-# CONFIG_PCMCIA_FMVJ18X is not set
-CONFIG_PCMCIA_PCNET=y
-# CONFIG_PCMCIA_AXNET is not set
-# CONFIG_PCMCIA_NMCLAN is not set
-# CONFIG_PCMCIA_SMC91C92 is not set
-# CONFIG_PCMCIA_XIRC2PS is not set
-# CONFIG_ARCNET_COM20020_CS is not set
-# CONFIG_PCMCIA_IBMTR is not set
-# CONFIG_NET_PCMCIA_RADIO is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-CONFIG_IRDA=y
-# CONFIG_IRLAN is not set
-CONFIG_IRNET=m
-CONFIG_IRCOMM=y
-# CONFIG_IRDA_ULTRA is not set
-# CONFIG_IRDA_CACHE_LAST_LSAP is not set
-CONFIG_IRDA_FAST_RR=y
-# CONFIG_IRDA_DEBUG is not set
-
-#
-# Infrared-port device drivers
-#
-CONFIG_IRTTY_SIR=y
-# CONFIG_IRPORT_SIR is not set
-# CONFIG_DONGLE is not set
-# CONFIG_USB_IRDA is not set
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-
-#
-# ATA/IDE/MFM/RLL support
-#
-CONFIG_IDE=y
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=y
-# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-# CONFIG_BLK_DEV_IDEDISK_WD is not set
-# CONFIG_BLK_DEV_COMMERIAL is not set
-# CONFIG_BLK_DEV_TIVO is not set
-CONFIG_BLK_DEV_IDECS=y
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_DMA_NONPCI is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-
-#
-# SCSI support
-#
-# CONFIG_SCSI is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_UINPUT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
-CONFIG_SERIAL_SL_SERIES=y
-# CONFIG_SL_TS_PRESSURE is not set
-# CONFIG_SL7X0_POWER_KEY_OFF is not set
-# CONFIG_SL_3BUTTON_PATCH is not set
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_ANAKIN is not set
-# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_UART00 is not set
-# CONFIG_SERIAL_UART00_CONSOLE is not set
-# CONFIG_SERIAL_SA1100 is not set
-# CONFIG_SERIAL_SA1100_CONSOLE is not set
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# L3 serial bus support
-#
-# CONFIG_L3 is not set
-# CONFIG_L3_ALGOBIT is not set
-# CONFIG_L3_BIT_SA1100_GPIO is not set
-# CONFIG_L3_SA1111 is not set
-# CONFIG_BIT_SA1100_GPIO is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_COTULLA_RTC=y
-CONFIG_ADS7846_TS=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-CONFIG_PCMCIA_SERIAL_CS=y
-CONFIG_PCMCIA_CHRDEV=y
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FS_SYNC is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=y
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=y
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_NAND=y
-CONFIG_JFFS2_PROC_FS=y
-CONFIG_JFFS2_NODEMERGE=y
-CONFIG_JFFS2_DYNFRAGTREE=y
-CONFIG_CRAMFS=y
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-CONFIG_MINIX_FS=y
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_ROOT_NFS is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_CIFS=m
-# CONFIG_CIFS_STATS is not set
-CONFIG_CIFS_POSIX=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-CONFIG_ZLIB_FS_INFLATE=y
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-CONFIG_NLS_CODEPAGE_850=y
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-CONFIG_NLS_CODEPAGE_932=y
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-CONFIG_NLS_UTF8=y
-
-#
-# Console drivers
-#
-CONFIG_PC_KEYMAP=y
-# CONFIG_VGA_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_UNICON is not set
-# CONFIG_FB_COLLIE is not set
-# CONFIG_FB_ACORN is not set
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_SA1100 is not set
-# CONFIG_FB_PXA is not set
-# CONFIG_FB_COTULLA is not set
-CONFIG_FB_POODLE=y
-CONFIG_POODLE_CONSISTENT_ALLOC=y
-# CONFIG_FB_CORGI is not set
-# CONFIG_SHARP_LOGO_SCREEN is not set
-# CONFIG_SL_SYSCLK100 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-# CONFIG_FBCON_CFB4 is not set
-# CONFIG_FBCON_CFB8 is not set
-CONFIG_FBCON_CFB16=y
-# CONFIG_FBCON_CFB24 is not set
-# CONFIG_FBCON_CFB32 is not set
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA_PLANES is not set
-# CONFIG_FBCON_VGA is not set
-# CONFIG_FBCON_HGA is not set
-CONFIG_FBCON_ROTATE_R=y
-# CONFIG_FBCON_ROTATE_L is not set
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-# CONFIG_FONT_8x8 is not set
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_6x11 is not set
-CONFIG_FONT_4x6=y
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_COLLIE_SSP is not set
-# CONFIG_SOUND_COLLIE_TC35143 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_WAVEARTIST is not set
-# CONFIG_SOUND_PXA_AC97 is not set
-CONFIG_SOUND_POODLE=y
-# CONFIG_SOUND_CORGI is not set
-# CONFIG_SOUND_TVMIXER is not set
-
-#
-# Multimedia Capabilities Port drivers
-#
-# CONFIG_MCP is not set
-# CONFIG_MCP_SA1100 is not set
-# CONFIG_MCP_UCB1200 is not set
-# CONFIG_MCP_UCB1200_AUDIO is not set
-# CONFIG_MCP_UCB1200_TS is not set
-# CONFIG_MCP_UCB1400_TS is not set
-
-#
-# USB support
-#
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_LONG_TIMEOUT is not set
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-# CONFIG_USB_OHCI_SA1111 is not set
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDCETHER is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-# CONFIG_USB_RIO500 is not set
-
-#
-# USB Device Support
-#
-CONFIG_USBD=m
-CONFIG_USBD_VENDORID=04DD
-CONFIG_USBD_PRODUCTID=8006
-CONFIG_USBD_PRODUCT_NAME="SL-5600"
-CONFIG_USBD_MANUFACTURER="Sharp"
-# CONFIG_USBD_USE_SERIAL_NUMBER is not set
-CONFIG_USBD_SELFPOWERED=y
-CONFIG_USBD_MONITOR=m
-# CONFIG_USBD_PROCFS is not set
-
-#
-# Network Function
-#
-CONFIG_USBD_NET=m
-CONFIG_USBD_NET_VENDORID=04DD
-CONFIG_USBD_NET_PRODUCTID=8006
-CONFIG_USBD_NET_IFNAME="usbd"
-CONFIG_USBD_NET_OUT_ENDPOINT=1
-CONFIG_USBD_NET_OUT_PKTSIZE=64
-CONFIG_USBD_NET_IN_ENDPOINT=2
-CONFIG_USBD_NET_IN_PKTSIZE=64
-CONFIG_USBD_NET_INT_ENDPOINT=3
-CONFIG_USBD_NET_INT_PKTSIZE=16
-# CONFIG_USBD_NET_ALWAYSUP is not set
-# CONFIG_USBD_NET_SAFE is not set
-CONFIG_USBD_NET_MDLM=y
-# CONFIG_USBD_NET_CDC is not set
-CONFIG_USBD_NET_REMOTE_MACADDR="400001000002"
-CONFIG_USBD_NET_REMOTE_OUI=400002
-CONFIG_USBD_MAC_AS_SERIAL_NUMBER=y
-CONFIG_USBD_NET_LOCAL_MACADDR="400001000001"
-CONFIG_USBD_NET_LOCAL_OUI=400001
-
-#
-# Serial Function
-#
-# CONFIG_USBD_SERIAL is not set
-
-#
-# Mass Storage Function
-#
-CONFIG_USBD_STORAGE=m
-CONFIG_USBD_STORAGE_VENDORID=0000
-CONFIG_USBD_STORAGE_PRODUCTID=0000
-CONFIG_USBD_STORAGE_OUT_ENDPOINT=1
-CONFIG_USBD_STORAGE_OUT_PKTSIZE=64
-CONFIG_USBD_STORAGE_IN_ENDPOINT=2
-CONFIG_USBD_STORAGE_IN_PKTSIZE=64
-CONFIG_USBD_STORAGE_INT_ENDPOINT=3
-CONFIG_USBD_STORAGE_INT_PKTSIZE=16
-CONFIG_USBD_STORAGE_DEF_DEVICE_NAME="/dev/hda1"
-
-#
-# USB Device Bus Interface Support
-#
-CONFIG_USBD_PXA_BUS=m
-# CONFIG_USBD_GENERIC_BUS is not set
-
-#
-# Bluetooth support
-#
-CONFIG_BLUEZ=m
-CONFIG_BLUEZ_L2CAP=m
-CONFIG_BLUEZ_SCO=m
-CONFIG_BLUEZ_RFCOMM=m
-CONFIG_BLUEZ_RFCOMM_TTY=y
-CONFIG_BLUEZ_BNEP=m
-CONFIG_BLUEZ_BNEP_MC_FILTER=y
-CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
-
-#
-# Bluetooth device drivers
-#
-CONFIG_BLUEZ_HCIUSB=m
-CONFIG_BLUEZ_HCIUSB_SCO=y
-CONFIG_BLUEZ_HCIUART=m
-CONFIG_BLUEZ_HCIUART_H4=y
-CONFIG_BLUEZ_HCIUART_BCSP=y
-CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y
-CONFIG_BLUEZ_HCIBFUSB=m
-CONFIG_BLUEZ_HCIDTL1=m
-CONFIG_BLUEZ_HCIBLUECARD=m
-CONFIG_BLUEZ_HCIBTUART=m
-CONFIG_BLUEZ_HCIVHCI=m
-CONFIG_BLUEZ_BT950=m
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_COREDUMP_SIGNAL is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_NO_PGT_CACHE is not set
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_ERRORS is not set
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-shepherd b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-shepherd
deleted file mode 100644
index 95855cd4ee..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-shepherd
+++ /dev/null
@@ -1,1303 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-CONFIG_ARCH_PXA=y
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_MX1ADS is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-
-#
-# Archimedes/A5000 Implementations (select only ONE)
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CEP is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_COLLIE is not set
-# CONFIG_LOCOMO is not set
-# CONFIG_COLLIE_TS is not set
-# CONFIG_COLLIE_TR0 is not set
-# CONFIG_COLLIE_TR1 is not set
-# CONFIG_COLLIE_DEV is not set
-# CONFIG_COLLIE_G is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_H3XXX is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_FRODO is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_USB is not set
-# CONFIG_SA1100_USB_NETLINK is not set
-# CONFIG_SA1100_USB_CHAR is not set
-# CONFIG_H3600_SLEEVE is not set
-
-#
-# Intel PXA250/210 Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_ARCH_PXA_IDP is not set
-# CONFIG_ARCH_PXA_CERF is not set
-# CONFIG_COTULLA_DMA is not set
-# CONFIG_SABINAL_DISCOVERY is not set
-# CONFIG_ARCH_SABINAL is not set
-# CONFIG_ARCH_PXA_POODLE is not set
-# CONFIG_POODLE_TR0 is not set
-CONFIG_ARCH_PXA_CORGI=y
-# CONFIG_CORGI_TR0 is not set
-CONFIG_CORGI_LCD_BUFF=y
-CONFIG_ARCH_PXA_SHEPHERD=y
-# CONFIG_ARCH_PXA_HUSKY is not set
-# CONFIG_ARCH_PXA_BOXER is not set
-# CONFIG_ARCH_PXA_TOSA is not set
-# CONFIG_ARCH_PXA_TOSA_SKIP is not set
-CONFIG_ARCH_SHARP_SL=y
-CONFIG_SL_CCCR_CHANGE=y
-# CONFIG_SL_CCCR242 is not set
-# CONFIG_SL_CCCR162 is not set
-
-#
-# Language type
-#
-CONFIG_ARCH_SHARP_SL_E=y
-# CONFIG_ARCH_SHARP_SL_V is not set
-# CONFIG_ARCH_SHARP_SL_G is not set
-# CONFIG_ARCH_SHARP_SL_J is not set
-# CONFIG_ARCH_SHARP_SL_S is not set
-# CONFIG_ARCH_SHARP_SL_I is not set
-# CONFIG_PXA_USB is not set
-# CONFIG_PXA_USB_NETLINK is not set
-# CONFIG_PXA_USB_CHAR is not set
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_FORTUNET is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-
-#
-# Processor Type
-#
-# CONFIG_CPU_32v3 is not set
-# CONFIG_CPU_32v4 is not set
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM922T is not set
-# CONFIG_PLD is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_SA110 is not set
-# CONFIG_CPU_SA1100 is not set
-CONFIG_CPU_32v5=y
-CONFIG_CPU_XSCALE=y
-CONFIG_BATT=y
-# CONFIG_XSCALE_CACHE_ERRATA is not set
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_FCSE=y
-# CONFIG_DISCONTIGMEM is not set
-# CONFIG_PREEMPT is not set
-
-#
-# General setup
-#
-# CONFIG_PCI is not set
-# CONFIG_ISA is not set
-# CONFIG_ISA_DMA is not set
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=y
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_CLPS6700 is not set
-# CONFIG_PCMCIA_SA1100 is not set
-CONFIG_PCMCIA_PXA=y
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_PM=y
-CONFIG_APM=y
-# CONFIG_APM_IGNORE_USER_SUSPEND is not set
-CONFIG_APM_CPU_IDLE=y
-CONFIG_APM_DISPLAY_BLANK=y
-CONFIG_APM_RTC_IS_GMT=y
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="<see .oe file>"
-# CONFIG_SHARPSL_BOOTLDR_PARAMS is not set
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_FREEPG_SIGNAL=y
-CONFIG_OOM_KILL_SURVIVAL=y
-CONFIG_DEVICEINFO=m
-CONFIG_CORGI_DEVICEINFO=m
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-# CONFIG_MTD_CFI is not set
-# CONFIG_MTD_JEDECPROBE is not set
-# CONFIG_MTD_GEN_PROBE is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-CONFIG_MTD_ROM=y
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_LUBBOCK is not set
-# CONFIG_MTD_NORA is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-# CONFIG_MTD_SA1100 is not set
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_FORTUNET is not set
-# CONFIG_MTD_PXA_CERF is not set
-# CONFIG_MTD_EPXA10DB is not set
-# CONFIG_MTD_AUTCPU12 is not set
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_DISCOVERY is not set
-CONFIG_MTD_SHARP_SL=y
-# CONFIG_MTD_PCI is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDROM_SA1100 is not set
-# CONFIG_MTD_MTDRAM_SA1100 is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_MTDRAM_SHARP_SL is not set
-# CONFIG_MTD_BLKMTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC1000 is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
-CONFIG_MTD_NAND_POST_BADBLOCK=y
-# CONFIG_MTD_NAND_ERASE_BY_FORCE is not set
-CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS=y
-CONFIG_MTD_NAND_PAGE_CACHE=y
-CONFIG_MTD_NAND_SHARP_SL_CORGI=y
-CONFIG_MTD_NAND_SHARP_SL=y
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-CONFIG_SYN_COOKIES=y
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=y
-# CONFIG_IP_NF_MATCH_LIMIT is not set
-# CONFIG_IP_NF_MATCH_MAC is not set
-# CONFIG_IP_NF_MATCH_MARK is not set
-# CONFIG_IP_NF_MATCH_MULTIPORT is not set
-# CONFIG_IP_NF_MATCH_TOS is not set
-# CONFIG_IP_NF_MATCH_AH_ESP is not set
-# CONFIG_IP_NF_MATCH_LENGTH is not set
-# CONFIG_IP_NF_MATCH_TTL is not set
-# CONFIG_IP_NF_MATCH_TCPMSS is not set
-# CONFIG_IP_NF_MATCH_UNCLEAN is not set
-# CONFIG_IP_NF_MATCH_OWNER is not set
-CONFIG_IP_NF_FILTER=y
-CONFIG_IP_NF_TARGET_REJECT=y
-# CONFIG_IP_NF_TARGET_MIRROR is not set
-# CONFIG_IP_NF_MANGLE is not set
-CONFIG_IP_NF_TARGET_LOG=y
-# CONFIG_IP_NF_TARGET_ULOG is not set
-# CONFIG_IP_NF_TARGET_TCPMSS is not set
-CONFIG_IPV6=y
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-CONFIG_IP6_NF_IPTABLES=y
-# CONFIG_IP6_NF_MATCH_LIMIT is not set
-# CONFIG_IP6_NF_MATCH_MAC is not set
-# CONFIG_IP6_NF_MATCH_MULTIPORT is not set
-# CONFIG_IP6_NF_MATCH_OWNER is not set
-# CONFIG_IP6_NF_MATCH_MARK is not set
-CONFIG_IP6_NF_FILTER=y
-CONFIG_IP6_NF_TARGET_LOG=y
-# CONFIG_IP6_NF_MANGLE is not set
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-
-#
-#
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-CONFIG_IPSEC=m
-
-#
-# IPSec options (Openswan)
-#
-CONFIG_IPSEC_IPIP=y
-CONFIG_IPSEC_AH=y
-# CONFIG_IPSEC_AUTH_HMAC_MD5 is not set
-CONFIG_IPSEC_AUTH_HMAC_SHA1=y
-CONFIG_IPSEC_ESP=y
-CONFIG_IPSEC_ENC_3DES=y
-# CONFIG_IPSEC_ENC_AES is not set
-CONFIG_IPSEC_ALG=y
-CONFIG_IPSEC_IPCOMP=y
-CONFIG_IPSEC_DEBUG=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_ARM_AM79C961A is not set
-# CONFIG_SUNLANCE is not set
-# CONFIG_SUNBMAC is not set
-# CONFIG_SUNQE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=y
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=y
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-CONFIG_PPP_BSDCOMP=y
-CONFIG_PPP_MPPE=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_STRIP is not set
-# CONFIG_WAVELAN is not set
-# CONFIG_ARLAN is not set
-# CONFIG_AIRONET4500 is not set
-# CONFIG_AIRONET4500_NONCS is not set
-# CONFIG_AIRONET4500_PROC is not set
-# CONFIG_HERMES is not set
-
-#
-# Wireless Pcmcia cards support
-#
-# CONFIG_PCMCIA_HERMES is not set
-# CONFIG_AIRO_CS is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-# CONFIG_PCMCIA_3C589 is not set
-# CONFIG_PCMCIA_3C574 is not set
-# CONFIG_PCMCIA_FMVJ18X is not set
-CONFIG_PCMCIA_PCNET=y
-# CONFIG_PCMCIA_AXNET is not set
-# CONFIG_PCMCIA_NMCLAN is not set
-# CONFIG_PCMCIA_SMC91C92 is not set
-# CONFIG_PCMCIA_XIRC2PS is not set
-# CONFIG_ARCNET_COM20020_CS is not set
-# CONFIG_PCMCIA_IBMTR is not set
-# CONFIG_NET_PCMCIA_RADIO is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-CONFIG_IRDA=y
-
-#
-# IrDA protocols
-#
-# CONFIG_IRLAN is not set
-CONFIG_IRNET=m
-CONFIG_IRCOMM=y
-# CONFIG_IRDA_ULTRA is not set
-
-#
-# IrDA options
-#
-# CONFIG_IRDA_CACHE_LAST_LSAP is not set
-CONFIG_IRDA_FAST_RR=y
-# CONFIG_IRDA_DEBUG is not set
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=y
-# CONFIG_IRPORT_SIR is not set
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-
-#
-# ATA/IDE/MFM/RLL support
-#
-CONFIG_IDE=y
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-# CONFIG_BLK_DEV_IDEDISK_WD is not set
-# CONFIG_BLK_DEV_COMMERIAL is not set
-# CONFIG_BLK_DEV_TIVO is not set
-CONFIG_BLK_DEV_IDECS=y
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_DMA_NONPCI is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-
-#
-# SCSI support
-#
-# CONFIG_SCSI is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_UINPUT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
-CONFIG_SERIAL_SL_SERIES=y
-# CONFIG_SL_TS_PRESSURE is not set
-# CONFIG_BOOT_PRESSURE_ON is not set
-CONFIG_SL7X0_POWER_KEY_OFF=y
-# CONFIG_BOOT_POWER_KEY_OFF is not set
-# CONFIG_SL_3BUTTON_PATCH is not set
-# CONFIG_BOOT_3BUTTON_PATCH_ON is not set
-# CONFIG_SL_WRITE_TS is not set
-# CONFIG_BLUETOOTH_SL is not set
-# CONFIG_KBD_DEV_FILE is not set
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_ANAKIN is not set
-# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_UART00 is not set
-# CONFIG_SERIAL_UART00_CONSOLE is not set
-# CONFIG_SERIAL_SA1100 is not set
-# CONFIG_SERIAL_SA1100_CONSOLE is not set
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# L3 serial bus support
-#
-# CONFIG_L3 is not set
-# CONFIG_L3_ALGOBIT is not set
-# CONFIG_L3_BIT_SA1100_GPIO is not set
-
-#
-# Other L3 adapters
-#
-# CONFIG_L3_SA1111 is not set
-# CONFIG_BIT_SA1100_GPIO is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-
-#
-# Input core support is needed for gameports
-#
-
-#
-# Input core support is needed for joysticks
-#
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_COTULLA_RTC=y
-CONFIG_ADS7846_TS=y
-# CONFIG_TOSA_TS is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-CONFIG_PCMCIA_SERIAL_CS=y
-CONFIG_PCMCIA_CHRDEV=y
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FS_SYNC is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=y
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=y
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_NAND=y
-CONFIG_JFFS2_PROC_FS=y
-CONFIG_JFFS2_NODEMERGE=y
-CONFIG_JFFS2_DYNFRAGTREE=y
-CONFIG_CRAMFS=y
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-CONFIG_MINIX_FS=y
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_ROOT_NFS is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_CIFS=m
-# CONFIG_CIFS_STATS is not set
-CONFIG_CIFS_POSIX=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-CONFIG_ZLIB_FS_INFLATE=y
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-CONFIG_NLS_CODEPAGE_850=y
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-CONFIG_NLS_CODEPAGE_932=y
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-CONFIG_NLS_UTF8=y
-
-#
-# Console drivers
-#
-CONFIG_PC_KEYMAP=y
-# CONFIG_VGA_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_UNICON is not set
-# CONFIG_FB_COLLIE is not set
-# CONFIG_FB_ACORN is not set
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_SA1100 is not set
-# CONFIG_FB_PXA is not set
-# CONFIG_FB_COTULLA is not set
-# CONFIG_FB_POODLE is not set
-CONFIG_FB_CORGI=y
-# CONFIG_FB_TOSA is not set
-# CONFIG_SHARP_LOGO_SCREEN is not set
-# CONFIG_SL_SYSCLK100 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-# CONFIG_FBCON_CFB4 is not set
-# CONFIG_FBCON_CFB8 is not set
-CONFIG_FBCON_CFB16=y
-# CONFIG_FBCON_CFB24 is not set
-# CONFIG_FBCON_CFB32 is not set
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA_PLANES is not set
-# CONFIG_FBCON_VGA is not set
-# CONFIG_FBCON_HGA is not set
-CONFIG_FBCON_ROTATE_R=y
-# CONFIG_FBCON_ROTATE_L is not set
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_COLLIE_SSP is not set
-# CONFIG_SOUND_COLLIE_TC35143 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_WAVEARTIST is not set
-# CONFIG_SOUND_PXA_AC97 is not set
-# CONFIG_SOUND_POODLE is not set
-CONFIG_SOUND_CORGI=y
-# CONFIG_SOUND_TOSA is not set
-# CONFIG_BUZZER_TOSA is not set
-# CONFIG_SOUND_TVMIXER is not set
-
-#
-# Multimedia Capabilities Port drivers
-#
-# CONFIG_MCP is not set
-# CONFIG_MCP_SA1100 is not set
-# CONFIG_MCP_UCB1200 is not set
-# CONFIG_MCP_UCB1200_AUDIO is not set
-# CONFIG_MCP_UCB1200_TS is not set
-# CONFIG_MCP_UCB1400_TS is not set
-
-#
-# USB support
-#
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_LONG_TIMEOUT is not set
-
-#
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-# CONFIG_USB_OHCI_SA1111 is not set
-# CONFIG_USB_OHCI_TC6393 is not set
-# CONFIG_USB_USE_INTERNAL_MEMORY is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_AUDIO is not set
-
-#
-# USB Bluetooth can only be used with disabled Bluetooth subsystem
-#
-
-#
-# SCSI support is needed for USB Storage
-#
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-
-#
-# Input core support is needed for USB HID
-#
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDCETHER is not set
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_RIO500 is not set
-
-#
-# USB Device Support
-#
-CONFIG_USBD=m
-CONFIG_USBD_VENDORID=04DD
-CONFIG_USBD_PRODUCTID=8007
-CONFIG_USBD_PRODUCT_NAME="SL-7500"
-CONFIG_USBD_MANUFACTURER="Sharp"
-# CONFIG_USBD_USE_SERIAL_NUMBER is not set
-CONFIG_USBD_SELFPOWERED=y
-CONFIG_USBD_MONITOR=m
-
-#
-#
-#
-# CONFIG_USBD_PROCFS is not set
-
-#
-# USB Device functions
-#
-
-#
-# Network Function
-#
-CONFIG_USBD_NET=m
-CONFIG_USBD_NET_VENDORID=04DD
-CONFIG_USBD_NET_PRODUCTID=8007
-CONFIG_USBD_NET_IFNAME="usbd"
-CONFIG_USBD_NET_OUT_ENDPOINT=1
-CONFIG_USBD_NET_OUT_PKTSIZE=64
-CONFIG_USBD_NET_IN_ENDPOINT=2
-CONFIG_USBD_NET_IN_PKTSIZE=64
-CONFIG_USBD_NET_INT_ENDPOINT=3
-CONFIG_USBD_NET_INT_PKTSIZE=16
-# CONFIG_USBD_NET_ALWAYSUP is not set
-# CONFIG_USBD_NET_SAFE is not set
-CONFIG_USBD_NET_MDLM=y
-# CONFIG_USBD_NET_CDC is not set
-CONFIG_USBD_NET_REMOTE_MACADDR="400001000002"
-CONFIG_USBD_NET_REMOTE_OUI=400002
-CONFIG_USBD_MAC_AS_SERIAL_NUMBER=y
-CONFIG_USBD_NET_LOCAL_MACADDR="400001000001"
-CONFIG_USBD_NET_LOCAL_OUI=400001
-
-#
-# Serial Function
-#
-# CONFIG_USBD_SERIAL is not set
-
-#
-# Mass Storage Function
-#
-CONFIG_USBD_STORAGE=m
-CONFIG_USBD_STORAGE_VENDORID=04DD
-CONFIG_USBD_STORAGE_PRODUCTID=9050
-CONFIG_USBD_STORAGE_OUT_ENDPOINT=1
-CONFIG_USBD_STORAGE_OUT_PKTSIZE=64
-CONFIG_USBD_STORAGE_IN_ENDPOINT=2
-CONFIG_USBD_STORAGE_IN_PKTSIZE=64
-CONFIG_USBD_STORAGE_INT_ENDPOINT=3
-CONFIG_USBD_STORAGE_INT_PKTSIZE=16
-CONFIG_USBD_STORAGE_DEF_DEVICE_NAME="/dev/hda1"
-
-#
-# USB Device bus interfaces
-#
-
-#
-# USB Device Bus Interface Support
-#
-CONFIG_USBD_PXA_BUS=m
-# CONFIG_USBD_GENERIC_BUS is not set
-
-#
-# Bluetooth support
-#
-CONFIG_BLUEZ=y
-CONFIG_BLUEZ_L2CAP=y
-CONFIG_BLUEZ_SCO=y
-CONFIG_BLUEZ_RFCOMM=y
-CONFIG_BLUEZ_RFCOMM_TTY=y
-CONFIG_BLUEZ_BNEP=y
-CONFIG_BLUEZ_BNEP_MC_FILTER=y
-CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
-# CONFIG_BLUEZ_HIDP is not set
-
-#
-# Bluetooth device drivers
-#
-# CONFIG_BLUEZ_HCIUSB is not set
-CONFIG_BLUEZ_HCIUART=y
-CONFIG_BLUEZ_HCIUART_H4=y
-CONFIG_BLUEZ_HCIUART_BCSP=y
-CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y
-# CONFIG_BLUEZ_HCIBFUSB is not set
-CONFIG_BLUEZ_HCIDTL1=m
-CONFIG_BLUEZ_HCIBLUECARD=m
-CONFIG_BLUEZ_HCIBTUART=m
-# CONFIG_BLUEZ_HCIVHCI is not set
-CONFIG_BLUEZ_BT950=m
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_COREDUMP_SIGNAL is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_NO_PGT_CACHE is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_ERRORS is not set
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-tosa b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-tosa
deleted file mode 100644
index fbd5c97be5..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/defconfig-tosa
+++ /dev/null
@@ -1,1377 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-CONFIG_ARCH_PXA=y
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_MX1ADS is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-
-#
-# Archimedes/A5000 Implementations (select only ONE)
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CEP is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_COLLIE is not set
-# CONFIG_LOCOMO is not set
-# CONFIG_COLLIE_TS is not set
-# CONFIG_COLLIE_TR0 is not set
-# CONFIG_COLLIE_TR1 is not set
-# CONFIG_COLLIE_DEV is not set
-# CONFIG_COLLIE_G is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_H3XXX is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_FRODO is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_USB is not set
-# CONFIG_SA1100_USB_NETLINK is not set
-# CONFIG_SA1100_USB_CHAR is not set
-# CONFIG_H3600_SLEEVE is not set
-
-#
-# Intel PXA250/210 Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_ARCH_PXA_IDP is not set
-# CONFIG_ARCH_PXA_CERF is not set
-# CONFIG_COTULLA_DMA is not set
-# CONFIG_SABINAL_DISCOVERY is not set
-# CONFIG_ARCH_SABINAL is not set
-# CONFIG_ARCH_PXA_POODLE is not set
-# CONFIG_POODLE_TR0 is not set
-# CONFIG_ARCH_PXA_CORGI is not set
-# CONFIG_CORGI_TR0 is not set
-CONFIG_ARCH_PXA_TOSA=y
-CONFIG_ARCH_PXA_TOSA_SKIP=y
-CONFIG_ARCH_SHARP_SL=y
-CONFIG_SL_CCCR_CHANGE=y
-# CONFIG_SL_CCCR242 is not set
-# CONFIG_SL_CCCR162 is not set
-
-#
-# Language type
-#
-CONFIG_ARCH_SHARP_SL_E=y
-# CONFIG_ARCH_SHARP_SL_V is not set
-# CONFIG_ARCH_SHARP_SL_G is not set
-# CONFIG_ARCH_SHARP_SL_J is not set
-# CONFIG_ARCH_SHARP_SL_S is not set
-# CONFIG_ARCH_SHARP_SL_I is not set
-# CONFIG_PXA_USB is not set
-# CONFIG_PXA_USB_NETLINK is not set
-# CONFIG_PXA_USB_CHAR is not set
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_FORTUNET is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-
-#
-# Processor Type
-#
-# CONFIG_CPU_32v3 is not set
-# CONFIG_CPU_32v4 is not set
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM922T is not set
-# CONFIG_PLD is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_SA110 is not set
-# CONFIG_CPU_SA1100 is not set
-CONFIG_CPU_32v5=y
-CONFIG_CPU_XSCALE=y
-CONFIG_BATT=y
-# CONFIG_XSCALE_CACHE_ERRATA is not set
-CONFIG_ARM_THUMB=y
-CONFIG_ARM_FCSE=y
-# CONFIG_DISCONTIGMEM is not set
-# CONFIG_PREEMPT is not set
-
-#
-# General setup
-#
-# CONFIG_PCI is not set
-# CONFIG_ISA is not set
-# CONFIG_ISA_DMA is not set
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=y
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_CLPS6700 is not set
-# CONFIG_PCMCIA_SA1100 is not set
-CONFIG_PCMCIA_PXA=y
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_PM=y
-CONFIG_APM=y
-# CONFIG_APM_IGNORE_USER_SUSPEND is not set
-CONFIG_APM_CPU_IDLE=y
-CONFIG_APM_DISPLAY_BLANK=y
-CONFIG_APM_RTC_IS_GMT=y
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="<see .oe file>"
-# CONFIG_SHARPSL_BOOTLDR_PARAMS is not set
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_FREEPG_SIGNAL=y
-CONFIG_OOM_KILL_SURVIVAL=y
-CONFIG_DEVICEINFO=m
-CONFIG_CORGI_DEVICEINFO=m
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-# CONFIG_MTD_CFI is not set
-# CONFIG_MTD_JEDECPROBE is not set
-# CONFIG_MTD_GEN_PROBE is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-CONFIG_MTD_ROM=y
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_LUBBOCK is not set
-# CONFIG_MTD_NORA is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-# CONFIG_MTD_SA1100 is not set
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_FORTUNET is not set
-# CONFIG_MTD_PXA_CERF is not set
-# CONFIG_MTD_EPXA10DB is not set
-# CONFIG_MTD_AUTCPU12 is not set
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_DISCOVERY is not set
-CONFIG_MTD_SHARP_SL=y
-# CONFIG_MTD_PCI is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDROM_SA1100 is not set
-# CONFIG_MTD_MTDRAM_SA1100 is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_MTDRAM_SHARP_SL is not set
-# CONFIG_MTD_BLKMTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC1000 is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
-CONFIG_MTD_NAND_POST_BADBLOCK=y
-# CONFIG_MTD_NAND_ERASE_BY_FORCE is not set
-CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS=y
-CONFIG_MTD_NAND_PAGE_CACHE=y
-CONFIG_MTD_NAND_SHARP_SL_TC6393=y
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-CONFIG_SYN_COOKIES=y
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_QUEUE is not set
-CONFIG_IP_NF_IPTABLES=y
-# CONFIG_IP_NF_MATCH_LIMIT is not set
-# CONFIG_IP_NF_MATCH_MAC is not set
-# CONFIG_IP_NF_MATCH_MARK is not set
-# CONFIG_IP_NF_MATCH_MULTIPORT is not set
-# CONFIG_IP_NF_MATCH_TOS is not set
-# CONFIG_IP_NF_MATCH_AH_ESP is not set
-# CONFIG_IP_NF_MATCH_LENGTH is not set
-# CONFIG_IP_NF_MATCH_TTL is not set
-# CONFIG_IP_NF_MATCH_TCPMSS is not set
-# CONFIG_IP_NF_MATCH_UNCLEAN is not set
-# CONFIG_IP_NF_MATCH_OWNER is not set
-CONFIG_IP_NF_FILTER=y
-CONFIG_IP_NF_TARGET_REJECT=y
-# CONFIG_IP_NF_TARGET_MIRROR is not set
-# CONFIG_IP_NF_MANGLE is not set
-CONFIG_IP_NF_TARGET_LOG=y
-# CONFIG_IP_NF_TARGET_ULOG is not set
-# CONFIG_IP_NF_TARGET_TCPMSS is not set
-CONFIG_IPV6=y
-
-#
-# IPv6: Netfilter Configuration
-#
-# CONFIG_IP6_NF_QUEUE is not set
-CONFIG_IP6_NF_IPTABLES=y
-# CONFIG_IP6_NF_MATCH_LIMIT is not set
-# CONFIG_IP6_NF_MATCH_MAC is not set
-# CONFIG_IP6_NF_MATCH_MULTIPORT is not set
-# CONFIG_IP6_NF_MATCH_OWNER is not set
-# CONFIG_IP6_NF_MATCH_MARK is not set
-CONFIG_IP6_NF_FILTER=y
-CONFIG_IP6_NF_TARGET_LOG=y
-# CONFIG_IP6_NF_MANGLE is not set
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-
-#
-#
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-CONFIG_IPSEC=m
-
-#
-# IPSec options (Openswan)
-#
-CONFIG_IPSEC_IPIP=y
-CONFIG_IPSEC_AH=y
-# CONFIG_IPSEC_AUTH_HMAC_MD5 is not set
-CONFIG_IPSEC_AUTH_HMAC_SHA1=y
-CONFIG_IPSEC_ESP=y
-CONFIG_IPSEC_ENC_3DES=y
-# CONFIG_IPSEC_ENC_AES is not set
-CONFIG_IPSEC_ALG=y
-CONFIG_IPSEC_IPCOMP=y
-CONFIG_IPSEC_DEBUG=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_ARM_AM79C961A is not set
-# CONFIG_SUNLANCE is not set
-# CONFIG_SUNBMAC is not set
-# CONFIG_SUNQE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=y
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=y
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-CONFIG_PPP_BSDCOMP=y
-CONFIG_PPP_MPPE=m
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_STRIP is not set
-# CONFIG_WAVELAN is not set
-# CONFIG_ARLAN is not set
-# CONFIG_AIRONET4500 is not set
-# CONFIG_AIRONET4500_NONCS is not set
-# CONFIG_AIRONET4500_PROC is not set
-# CONFIG_HERMES is not set
-
-#
-# Wireless Pcmcia cards support
-#
-# CONFIG_PCMCIA_HERMES is not set
-# CONFIG_AIRO_CS is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-# CONFIG_PCMCIA_3C589 is not set
-# CONFIG_PCMCIA_3C574 is not set
-# CONFIG_PCMCIA_FMVJ18X is not set
-CONFIG_PCMCIA_PCNET=y
-# CONFIG_PCMCIA_AXNET is not set
-# CONFIG_PCMCIA_NMCLAN is not set
-# CONFIG_PCMCIA_SMC91C92 is not set
-# CONFIG_PCMCIA_XIRC2PS is not set
-# CONFIG_ARCNET_COM20020_CS is not set
-# CONFIG_PCMCIA_IBMTR is not set
-# CONFIG_NET_PCMCIA_RADIO is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-CONFIG_IRDA=y
-
-#
-# IrDA protocols
-#
-# CONFIG_IRLAN is not set
-CONFIG_IRNET=m
-CONFIG_IRCOMM=y
-# CONFIG_IRDA_ULTRA is not set
-
-#
-# IrDA options
-#
-# CONFIG_IRDA_CACHE_LAST_LSAP is not set
-CONFIG_IRDA_FAST_RR=y
-# CONFIG_IRDA_DEBUG is not set
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=y
-# CONFIG_IRPORT_SIR is not set
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-
-#
-# ATA/IDE/MFM/RLL support
-#
-CONFIG_IDE=y
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-# CONFIG_BLK_DEV_IDEDISK_WD is not set
-# CONFIG_BLK_DEV_COMMERIAL is not set
-# CONFIG_BLK_DEV_TIVO is not set
-CONFIG_BLK_DEV_IDECS=y
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_DMA_NONPCI is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-CONFIG_SD_EXTRA_DEVS=40
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_DEBUG_QUEUES is not set
-# CONFIG_SCSI_MULTI_LUN is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_SIM710 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# PCMCIA SCSI adapter support
-#
-# CONFIG_SCSI_PCMCIA is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-CONFIG_INPUT=y
-CONFIG_INPUT_KEYBDEV=y
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=480
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=640
-CONFIG_INPUT_JOYDEV=m
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_UINPUT=y
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
-CONFIG_SERIAL_SL_SERIES=y
-CONFIG_BLUETOOTH_SL=y
-# CONFIG_KBD_DEV_FILE is not set
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_ANAKIN is not set
-# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_UART00 is not set
-# CONFIG_SERIAL_UART00_CONSOLE is not set
-# CONFIG_SERIAL_SA1100 is not set
-# CONFIG_SERIAL_SA1100_CONSOLE is not set
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# L3 serial bus support
-#
-# CONFIG_L3 is not set
-# CONFIG_L3_ALGOBIT is not set
-# CONFIG_L3_BIT_SA1100_GPIO is not set
-
-#
-# Other L3 adapters
-#
-# CONFIG_L3_SA1111 is not set
-# CONFIG_BIT_SA1100_GPIO is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_INPUT_NS558 is not set
-# CONFIG_INPUT_LIGHTNING is not set
-# CONFIG_INPUT_PCIGAME is not set
-# CONFIG_INPUT_CS461X is not set
-# CONFIG_INPUT_EMU10K1 is not set
-# CONFIG_INPUT_SERIO is not set
-# CONFIG_INPUT_SERPORT is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_ANALOG is not set
-# CONFIG_INPUT_A3D is not set
-# CONFIG_INPUT_ADI is not set
-# CONFIG_INPUT_COBRA is not set
-# CONFIG_INPUT_GF2K is not set
-# CONFIG_INPUT_GRIP is not set
-# CONFIG_INPUT_INTERACT is not set
-# CONFIG_INPUT_TMDC is not set
-# CONFIG_INPUT_SIDEWINDER is not set
-# CONFIG_INPUT_IFORCE_USB is not set
-# CONFIG_INPUT_IFORCE_232 is not set
-# CONFIG_INPUT_WARRIOR is not set
-# CONFIG_INPUT_MAGELLAN is not set
-# CONFIG_INPUT_SPACEORB is not set
-# CONFIG_INPUT_SPACEBALL is not set
-# CONFIG_INPUT_STINGER is not set
-# CONFIG_INPUT_DB9 is not set
-# CONFIG_INPUT_GAMECON is not set
-# CONFIG_INPUT_TURBOGRAFX is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_COTULLA_RTC=y
-# CONFIG_ADS7846_TS is not set
-CONFIG_TOSA_TS=y
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-# these shouldnt be here
-CONFIG_TOSA_POWER_KEY_OFF=y
-CONFIG_BOOT_TOSA_POWER_KEY_OFF=y
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-CONFIG_PCMCIA_SERIAL_CS=y
-CONFIG_PCMCIA_CHRDEV=y
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FS_SYNC is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_JBD is not set
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=y
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=y
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-CONFIG_JFFS2_FS_NAND=y
-CONFIG_JFFS2_PROC_FS=y
-CONFIG_JFFS2_NODEMERGE=y
-CONFIG_JFFS2_DYNFRAGTREE=y
-CONFIG_CRAMFS=y
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-CONFIG_MINIX_FS=y
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_ROOT_NFS is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_CIFS=m
-# CONFIG_CIFS_STATS is not set
-CONFIG_CIFS_POSIX=y
-CONFIG_SMB_FS=m
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-CONFIG_ZLIB_FS_INFLATE=y
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_ULTRIX_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=y
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-CONFIG_NLS_CODEPAGE_850=y
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-CONFIG_NLS_CODEPAGE_932=y
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-CONFIG_NLS_UTF8=y
-
-#
-# Console drivers
-#
-CONFIG_PC_KEYMAP=y
-# CONFIG_VGA_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-# CONFIG_UNICON is not set
-# CONFIG_FB_COLLIE is not set
-# CONFIG_FB_ACORN is not set
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_SA1100 is not set
-# CONFIG_FB_PXA is not set
-# CONFIG_FB_COTULLA is not set
-# CONFIG_FB_POODLE is not set
-# CONFIG_FB_CORGI is not set
-CONFIG_FB_TOSA=y
-# CONFIG_SHARP_LOGO_SCREEN is not set
-# CONFIG_SL_SYSCLK100 is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-# CONFIG_FBCON_CFB4 is not set
-# CONFIG_FBCON_CFB8 is not set
-CONFIG_FBCON_CFB16=y
-# CONFIG_FBCON_CFB24 is not set
-# CONFIG_FBCON_CFB32 is not set
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA_PLANES is not set
-# CONFIG_FBCON_VGA is not set
-# CONFIG_FBCON_HGA is not set
-# CONFIG_FBCON_ROTATE_R is not set
-# CONFIG_FBCON_ROTATE_L is not set
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_BT878 is not set
-# CONFIG_SOUND_COLLIE_SSP is not set
-# CONFIG_SOUND_COLLIE_TC35143 is not set
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_WAVEARTIST is not set
-# CONFIG_SOUND_PXA_AC97 is not set
-# CONFIG_SOUND_POODLE is not set
-# CONFIG_SOUND_CORGI is not set
-CONFIG_SOUND_TOSA=y
-CONFIG_BUZZER_TOSA=y
-# CONFIG_SOUND_TVMIXER is not set
-
-#
-# Multimedia Capabilities Port drivers
-#
-# CONFIG_MCP is not set
-# CONFIG_MCP_SA1100 is not set
-# CONFIG_MCP_UCB1200 is not set
-# CONFIG_MCP_UCB1200_AUDIO is not set
-# CONFIG_MCP_UCB1200_TS is not set
-# CONFIG_MCP_UCB1400_TS is not set
-
-#
-# USB support
-#
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_LONG_TIMEOUT is not set
-
-#
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-# CONFIG_USB_OHCI_SA1111 is not set
-CONFIG_USB_OHCI_TC6393=m
-CONFIG_USB_USE_INTERNAL_MEMORY=y
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_BLUETOOTH is not set
-CONFIG_USB_STORAGE=m
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-CONFIG_USB_STORAGE_ISD200=y
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-CONFIG_USB_ACM=m
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-CONFIG_USB_HID=m
-# CONFIG_USB_HIDDEV is not set
-CONFIG_USB_KBD=m
-CONFIG_USB_MOUSE=m
-# CONFIG_USB_WACOM is not set
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDCETHER is not set
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_RIO500 is not set
-
-#
-# USB Device Support
-#
-CONFIG_USBD=m
-CONFIG_USBD_VENDORID=04DD
-CONFIG_USBD_PRODUCTID=9032
-CONFIG_USBD_PRODUCT_NAME="SL-6000"
-CONFIG_USBD_MANUFACTURER="Sharp"
-# CONFIG_USBD_USE_SERIAL_NUMBER is not set
-CONFIG_USBD_SELFPOWERED=y
-CONFIG_USBD_MONITOR=m
-
-#
-#
-#
-CONFIG_USBD_PROCFS=y
-
-#
-# USB Device functions
-#
-
-#
-# Network Function
-#
-CONFIG_USBD_NET=m
-CONFIG_USBD_NET_VENDORID=04DD
-CONFIG_USBD_NET_PRODUCTID=9032
-CONFIG_USBD_NET_IFNAME="usbd"
-CONFIG_USBD_NET_OUT_ENDPOINT=1
-CONFIG_USBD_NET_OUT_PKTSIZE=64
-CONFIG_USBD_NET_IN_ENDPOINT=2
-CONFIG_USBD_NET_IN_PKTSIZE=64
-CONFIG_USBD_NET_INT_ENDPOINT=3
-CONFIG_USBD_NET_INT_PKTSIZE=16
-# CONFIG_USBD_NET_ALWAYSUP is not set
-# CONFIG_USBD_NET_SAFE is not set
-CONFIG_USBD_NET_MDLM=y
-# CONFIG_USBD_NET_CDC is not set
-CONFIG_USBD_NET_REMOTE_MACADDR="400002000001"
-CONFIG_USBD_NET_REMOTE_OUI=400002
-CONFIG_USBD_MAC_AS_SERIAL_NUMBER=y
-CONFIG_USBD_NET_LOCAL_MACADDR="400001000001"
-CONFIG_USBD_NET_LOCAL_OUI=400001
-
-#
-# Serial Function
-#
-# CONFIG_USBD_SERIAL is not set
-
-#
-# Mass Storage Function
-#
-CONFIG_USBD_STORAGE=m
-CONFIG_USBD_STORAGE_VENDORID=0000
-CONFIG_USBD_STORAGE_PRODUCTID=0000
-CONFIG_USBD_STORAGE_OUT_ENDPOINT=1
-CONFIG_USBD_STORAGE_OUT_PKTSIZE=64
-CONFIG_USBD_STORAGE_IN_ENDPOINT=2
-CONFIG_USBD_STORAGE_IN_PKTSIZE=64
-CONFIG_USBD_STORAGE_INT_ENDPOINT=3
-CONFIG_USBD_STORAGE_INT_PKTSIZE=16
-CONFIG_USBD_STORAGE_DEF_DEVICE_NAME=""
-
-#
-# USB Device bus interfaces
-#
-
-#
-# USB Device Bus Interface Support
-#
-CONFIG_USBD_PXA_BUS=m
-# CONFIG_USBD_GENERIC_BUS is not set
-
-#
-# Bluetooth support
-#
-CONFIG_BLUEZ=y
-CONFIG_BLUEZ_L2CAP=y
-CONFIG_BLUEZ_SCO=y
-CONFIG_BLUEZ_RFCOMM=y
-CONFIG_BLUEZ_RFCOMM_TTY=y
-CONFIG_BLUEZ_BNEP=y
-CONFIG_BLUEZ_BNEP_MC_FILTER=y
-CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
-# CONFIG_BLUEZ_HIDP is not set
-
-#
-# Bluetooth device drivers
-#
-CONFIG_BLUEZ_HCIUSB=m
-CONFIG_BLUEZ_HCIUSB_SCO=y
-CONFIG_BLUEZ_HCIUART=y
-CONFIG_BLUEZ_HCIUART_H4=y
-CONFIG_BLUEZ_HCIUART_BCSP=y
-CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y
-CONFIG_BLUEZ_HCIBFUSB=m
-CONFIG_BLUEZ_HCIDTL1=m
-CONFIG_BLUEZ_HCIBLUECARD=m
-CONFIG_BLUEZ_HCIBTUART=m
-CONFIG_BLUEZ_HCIVHCI=m
-CONFIG_BLUEZ_BT950=m
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_COREDUMP_SIGNAL is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_NO_PGT_CACHE is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_SLAB is not set
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_ERRORS is not set
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/deviceinfo.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/deviceinfo.patch
deleted file mode 100644
index 58343c5b55..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/deviceinfo.patch
+++ /dev/null
@@ -1,26 +0,0 @@
---- linux/arch/arm/mach-pxa/Makefile.old 2004-09-24 20:49:09.000000000 +0930
-+++ linux/arch/arm/mach-pxa/Makefile 2004-09-24 20:49:11.000000000 +0930
-@@ -94,6 +94,23 @@
- endif
- endif
-
-+ifeq ($(CONFIG_DEVICEINFO),m)
-+ obj-$(CONFIG_DEVICEINFO) += devinfo.o
-+ ifeq ($(CONFIG_SABINAL_DISCOVERY),y)
-+ devinfo-objs-m += deviceinfo.o
-+ devinfo-objs-$(CONFIG_DISCOVERY_DEVICEINFO) += discovery_deviceinfo.o
-+ endif
-+ ifeq ($(CONFIG_ARCH_PXA_POODLE),y)
-+ devinfo-objs-m += sharpsl_deviceinfo.o
-+ endif
-+ ifeq ($(CONFIG_ARCH_PXA_CORGI),y)
-+ devinfo-objs-m += sharpsl_deviceinfo.o
-+ endif
-+ ifeq ($(CONFIG_ARCH_PXA_TOSA),y)
-+ devinfo-objs-m += sharpsl_deviceinfo.o
-+ endif
-+endif
-+
- obj-m += registers.o
-
- include $(TOPDIR)/Rules.make
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/disable-pcmcia-probe.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/disable-pcmcia-probe.patch
deleted file mode 100644
index 79ba036323..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/disable-pcmcia-probe.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-
-#
-# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux/drivers/pcmcia/Config.in~disable-pcmcia-probe 2003-05-13 11:18:23.000000000 +0200
-+++ linux/drivers/pcmcia/Config.in 2004-05-27 13:59:50.000000000 +0200
-@@ -15,9 +15,6 @@
- tristate 'PCMCIA/CardBus support' CONFIG_PCMCIA
- if [ "$CONFIG_PCMCIA" != "n" ]; then
- # yes, I really mean the following...
-- if [ "$CONFIG_ISA" = "y" -o "$CONFIG_ARCH_SA1100" = "y" ]; then
-- define_bool CONFIG_PCMCIA_PROBE y
-- fi
- if [ "$CONFIG_PCI" != "n" ]; then
- bool ' CardBus support' CONFIG_CARDBUS
- fi
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/enable-sysrq.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/enable-sysrq.patch
deleted file mode 100644
index b1ea85018b..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/enable-sysrq.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- linux/drivers/char/corgi_keyb.c~enable-sysrq
-+++ linux/drivers/char/corgi_keyb.c
-@@ -23,7 +23,7 @@
- #include <linux/init.h>
- #include <linux/poll.h>
- #include <linux/wait.h>
--#include <asm/arch/keyboard.h>
-+#include <asm/keyboard.h>
- #include <asm/uaccess.h>
- #include <linux/tqueue.h>
- #include <linux/kbd_ll.h>
-@@ -46,6 +46,18 @@
- #endif
-
- /*
-+ * This is the KeyCode [not ScanCode!] to ASCII Code mapping table
-+ */
-+
-+#ifdef CONFIG_MAGIC_SYSRQ
-+static unsigned char corgi_sysrq_xlate[128] =
-+ "\000abcdefghijklmno" /* 00-0f */
-+ "pqrstuvwxyz\000\000\000\000\000" /* 10-1f */
-+ " \000\000\000\000\000\000\000\0001234567" /* 20-2f */
-+ "890\000\000\000\000\000\000\000\000\000\000\000\000\000"; /* 30-3f */
-+#endif
-+
-+/*
- * common logical driver definition
- */
- extern void sharppda_kbd_press(int keycode);
-@@ -251,7 +263,13 @@
- corgi_wakeup_button_init();
- #endif // USE_WAKEUP_BUTTON
-
-- printk("keyboard initilaized.\n");
-+ printk("keyboard initialized.\n");
-+#ifdef CONFIG_MAGIC_SYSRQ
-+ k_sysrq_key = 0x28; // KEY_HOME
-+ k_sysrq_xlate = corgi_sysrq_xlate;
-+ printk("magic_sysrq initialized.\n");
-+#endif
-+
- }
-
- int corgi_kbd_translate(unsigned char scancode, unsigned char *keycode_p)
---- linux/drivers/char/keyboard.c~enable-sysrq
-+++ linux/drivers/char/keyboard.c
-@@ -366,7 +366,7 @@
- #ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
- if (keycode == SYSRQ_KEY) {
- sysrq_pressed = !up_flag;
-- goto out;
-+ // goto out;
- } else if (sysrq_pressed) {
- if (!up_flag) {
- handle_sysrq(kbd_sysrq_xlate[keycode], kbd_pt_regs, kbd, tty);
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/idecs.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/idecs.patch
deleted file mode 100644
index 62038c34e2..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/idecs.patch
+++ /dev/null
@@ -1,77 +0,0 @@
---- linux/drivers/ide/ide-cs.c 2003-02-28 17:04:00.000000000 -0600
-+++ linux.new/drivers/ide/ide-cs.c 2003-02-28 17:18:53.000000000 -0600
-@@ -2,7 +2,7 @@
-
- A driver for PCMCIA IDE/ATA disk cards
-
-- ide_cs.c 1.26 1999/11/16 02:10:49
-+ ide-cs.c 1.26 1999/11/16 02:10:49
-
- The contents of this file are subject to the Mozilla Public
- License Version 1.1 (the "License"); you may not use this file
-@@ -66,7 +66,7 @@
- MODULE_PARM(pc_debug, "i");
- #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
- static char *version =
--"ide_cs.c 1.26 1999/11/16 02:10:49 (David Hinds)";
-+"ide-cs.c 1.26 1999/11/16 02:10:49 (David Hinds)";
- #else
- #define DEBUG(n, args...)
- #endif
-@@ -110,7 +110,7 @@
- static int ide_event(event_t event, int priority,
- event_callback_args_t *args);
-
--static dev_info_t dev_info = "ide_cs";
-+static dev_info_t dev_info = "ide-cs";
-
- static dev_link_t *ide_attach(void);
- static void ide_detach(dev_link_t *);
-@@ -356,7 +356,7 @@
- }
-
- if (hd < 0) {
-- printk(KERN_NOTICE "ide_cs: ide_register() at 0x%03x & 0x%03x"
-+ printk(KERN_NOTICE "ide-cs: ide_register() at 0x%03x & 0x%03x"
- ", irq %u failed\n", io_base, ctl_base,
- link->irq.AssignedIRQ);
- goto failed;
-@@ -369,7 +369,7 @@
- info->node.minor = 0;
- info->hd = hd;
- link->dev = &info->node;
-- printk(KERN_INFO "ide_cs: %s: Vcc = %d.%d, Vpp = %d.%d\n",
-+ printk(KERN_INFO "ide-cs: %s: Vcc = %d.%d, Vpp = %d.%d\n",
- info->node.dev_name, link->conf.Vcc/10, link->conf.Vcc%10,
- link->conf.Vpp1/10, link->conf.Vpp1%10);
-
-@@ -409,9 +409,9 @@
- MOD_DEC_USE_COUNT;
- }
-
-- request_region(link->io.BasePort1, link->io.NumPorts1,"ide_cs");
-+ request_region(link->io.BasePort1, link->io.NumPorts1,"ide-cs");
- if (link->io.NumPorts2)
-- request_region(link->io.BasePort2, link->io.NumPorts2,"ide_cs");
-+ request_region(link->io.BasePort2, link->io.NumPorts2,"ide-cs");
-
- info->ndev = 0;
- link->dev = NULL;
-@@ -508,7 +508,7 @@
- DEBUG(0, "%s\n", version);
- CardServices(GetCardServicesInfo, &serv);
- if (serv.Revision != CS_RELEASE_CODE) {
-- printk(KERN_NOTICE "ide_cs: Card Services release "
-+ printk(KERN_NOTICE "ide-cs: Card Services release "
- "does not match!\n");
- return -1;
- }
-@@ -518,7 +518,7 @@
-
- static void __exit exit_ide_cs(void)
- {
-- DEBUG(0, "ide_cs: unloading\n");
-+ DEBUG(0, "ide-cs: unloading\n");
- unregister_pccard_driver(&dev_info);
- while (dev_list != NULL)
- ide_detach(dev_list);
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/initsh.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/initsh.patch
deleted file mode 100644
index a672631194..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/initsh.patch
+++ /dev/null
@@ -1,14 +0,0 @@
---- linux/init/main.c 2002-02-25 13:38:13.000000000 -0600
-+++ linux.new/init/main.c 2003-03-16 11:49:45.000000000 -0600
-@@ -830,8 +830,10 @@
- * trying to recover a really broken machine.
- */
-
-- if (execute_command)
-+ if (execute_command) {
-+ argv_init[0] = execute_command;
- execve(execute_command,argv_init,envp_init);
-+ }
- execve("/sbin/init",argv_init,envp_init);
- execve("/etc/init",argv_init,envp_init);
- execve("/bin/init",argv_init,envp_init);
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/irda-qos.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/irda-qos.patch
deleted file mode 100644
index 559f4ad564..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/irda-qos.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-diff -urN linux.orig/net/irda/irsysctl.c linux/net/irda/irsysctl.c
---- linux.orig/net/irda/irsysctl.c Fri Feb 27 18:28:04 2004
-+++ linux/net/irda/irsysctl.c Wed Jan 14 19:36:40 2004
-@@ -40,7 +40,8 @@
-
- enum { DISCOVERY=1, DEVNAME, DEBUG, FAST_POLL, DISCOVERY_SLOTS,
- DISCOVERY_TIMEOUT, SLOT_TIMEOUT, MAX_BAUD_RATE, MIN_TX_TURN_TIME,
-- MAX_NOREPLY_TIME, WARN_NOREPLY_TIME, LAP_KEEPALIVE_TIME, SPECIFIC_DEV };
-+ MAX_TX_WINDOW, MAX_NOREPLY_TIME, WARN_NOREPLY_TIME,
-+ LAP_KEEPALIVE_TIME, SPECIFIC_DEV };
-
- extern int sysctl_discovery;
- extern int sysctl_discovery_slots;
-@@ -51,6 +52,7 @@
- extern char sysctl_devname[];
- extern int sysctl_max_baud_rate;
- extern int sysctl_min_tx_turn_time;
-+extern int sysctl_max_tx_window;
- extern int sysctl_max_noreply_time;
- extern int sysctl_warn_noreply_time;
- extern int sysctl_lap_keepalive_time;
-@@ -71,6 +73,8 @@
- static int min_max_baud_rate = 2400;
- static int max_min_tx_turn_time = 10000; /* See qos.c - IrLAP spec */
- static int min_min_tx_turn_time = 0;
-+static int max_max_tx_window=7;
-+static int min_max_tx_window=1;
- static int max_max_noreply_time = 40; /* See qos.c - IrLAP spec */
- static int min_max_noreply_time = 3;
- static int max_warn_noreply_time = 3; /* 3s == standard */
-@@ -128,6 +132,9 @@
- { MIN_TX_TURN_TIME, "min_tx_turn_time", &sysctl_min_tx_turn_time,
- sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec,
- NULL, &min_min_tx_turn_time, &max_min_tx_turn_time },
-+ { MAX_TX_WINDOW, "max_tx_window", &sysctl_max_tx_window,
-+ sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec,
-+ NULL, &min_max_tx_window, &max_max_tx_window },
- { MAX_NOREPLY_TIME, "max_noreply_time", &sysctl_max_noreply_time,
- sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec,
- NULL, &min_max_noreply_time, &max_max_noreply_time },
-diff -urN linux.orig/net/irda/parameters.c linux/net/irda/parameters.c
---- linux.orig/net/irda/parameters.c Sat Nov 10 01:22:17 2001
-+++ linux/net/irda/parameters.c Wed Jan 14 19:34:23 2004
-@@ -204,12 +204,14 @@
- {
- irda_param_t p;
- int n = 0;
-+ int extract_len;
- int err;
-
- p.pi = pi; /* In case handler needs to know */
- p.pl = buf[1]; /* Extract lenght of value */
- p.pv.i = 0; /* Clear value */
--
-+ extract_len = p.pl;
-+
- /* Check if buffer is long enough for parsing */
- if (len < (2+p.pl)) {
- WARNING(__FUNCTION__ "(), buffer to short for parsing! "
-@@ -226,12 +228,15 @@
- "Expected %d bytes, but value had %d bytes!\n",
- type & PV_MASK, p.pl);
-
-- /* Skip parameter */
-+ if((p.pl < (type & PV_MASK)) || (type & PV_BIG_ENDIAN)) {
- return p.pl+2;
-+ } else {
-+ extract_len = type & PV_MASK;
-+ }
- }
-
-
-- switch (p.pl) {
-+ switch (extract_len) {
- case 1:
- n += irda_param_unpack(buf+2, "b", &p.pv.i);
- break;
-diff -urN linux.orig/net/irda/qos.c linux/net/irda/qos.c
---- linux.orig/net/irda/qos.c Fri Feb 27 18:28:04 2004
-+++ linux/net/irda/qos.c Wed Jan 14 18:18:20 2004
-@@ -65,6 +65,7 @@
- */
- unsigned sysctl_min_tx_turn_time = 10;
-
-+unsigned sysctl_max_tx_window = 7;
- /*
- * Specific device list limits some negotiation parameters at the connection
- * with listed peer devices.
-@@ -212,6 +213,9 @@
- __u16 msb = 0x8000;
- int index = 15; /* Current MSB */
-
-+ if(!word)
-+ word=0x1;
-+
- while (msb) {
- if (word & msb)
- break; /* Found it! */
-@@ -386,6 +390,9 @@
- qos->max_turn_time.value = 500;
- }
-
-+ if(qos->window_size.value > sysctl_max_tx_window)
-+ qos->window_size.value = sysctl_max_tx_window;
-+
- /*
- * The data size must be adjusted according to the baud rate and max
- * turn time
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/iw240_we15-6.diff b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/iw240_we15-6.diff
deleted file mode 100644
index 2ebfd8ec12..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/iw240_we15-6.diff
+++ /dev/null
@@ -1,399 +0,0 @@
-diff -u -p linux/include/linux/wireless.14.h linux/include/linux/wireless.h
---- linux/include/linux/wireless.14.h Mon Dec 2 18:51:00 2002
-+++ linux/include/linux/wireless.h Mon Dec 2 18:53:35 2002
-@@ -1,7 +1,7 @@
- /*
- * This file define a set of standard wireless extensions
- *
-- * Version : 14 25.1.02
-+ * Version : 15 12.7.02
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
- * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
-@@ -80,7 +80,7 @@
- * (there is some stuff that will be added in the future...)
- * I just plan to increment with each new version.
- */
--#define WIRELESS_EXT 14
-+#define WIRELESS_EXT 15
-
- /*
- * Changes :
-@@ -153,17 +153,32 @@
- * - Define additional specific event numbers
- * - Add "addr" and "param" fields in union iwreq_data
- * - AP scanning stuff (SIOCSIWSCAN and friends)
-+ *
-+ * V14 to V15
-+ * ----------
-+ * - Add IW_PRIV_TYPE_ADDR for struct sockaddr private arg
-+ * - Make struct iw_freq signed (both m & e), add explicit padding
-+ * - Add IWEVCUSTOM for driver specific event/scanning token
-+ * - Add IW_MAX_GET_SPY for driver returning a lot of addresses
-+ * - Add IW_TXPOW_RANGE for range of Tx Powers
-+ * - Add IWEVREGISTERED & IWEVEXPIRED events for Access Points
-+ * - Add IW_MODE_MONITOR for passive monitor
- */
-
- /**************************** CONSTANTS ****************************/
-
- /* -------------------------- IOCTL LIST -------------------------- */
-
--/* Basic operations */
-+/* Wireless Identification */
- #define SIOCSIWCOMMIT 0x8B00 /* Commit pending changes to driver */
- #define SIOCGIWNAME 0x8B01 /* get name == wireless protocol */
--#define SIOCSIWNWID 0x8B02 /* set network id (the cell) */
--#define SIOCGIWNWID 0x8B03 /* get network id */
-+/* SIOCGIWNAME is used to verify the presence of Wireless Extensions.
-+ * Common values : "IEEE 802.11-DS", "IEEE 802.11-FH", "IEEE 802.11b"...
-+ * Don't put the name of your driver there, it's useless. */
-+
-+/* Basic operations */
-+#define SIOCSIWNWID 0x8B02 /* set network id (pre-802.11) */
-+#define SIOCGIWNWID 0x8B03 /* get network id (the cell) */
- #define SIOCSIWFREQ 0x8B04 /* set channel/frequency (Hz) */
- #define SIOCGIWFREQ 0x8B05 /* get channel/frequency (Hz) */
- #define SIOCSIWMODE 0x8B06 /* set operation mode */
-@@ -178,16 +193,18 @@
- #define SIOCGIWPRIV 0x8B0D /* get private ioctl interface info */
- #define SIOCSIWSTATS 0x8B0E /* Unused */
- #define SIOCGIWSTATS 0x8B0F /* Get /proc/net/wireless stats */
-+/* SIOCGIWSTATS is strictly used between user space and the kernel, and
-+ * is never passed to the driver (i.e. the driver will never see it). */
-
--/* Mobile IP support */
-+/* Mobile IP support (statistics per MAC address) */
- #define SIOCSIWSPY 0x8B10 /* set spy addresses */
- #define SIOCGIWSPY 0x8B11 /* get spy info (quality of link) */
-
- /* Access Point manipulation */
- #define SIOCSIWAP 0x8B14 /* set access point MAC addresses */
- #define SIOCGIWAP 0x8B15 /* get access point MAC addresses */
--#define SIOCGIWAPLIST 0x8B17 /* get list of access point in range */
--#define SIOCSIWSCAN 0x8B18 /* trigger scanning */
-+#define SIOCGIWAPLIST 0x8B17 /* Deprecated in favor of scanning */
-+#define SIOCSIWSCAN 0x8B18 /* trigger scanning (list cells) */
- #define SIOCGIWSCAN 0x8B19 /* get scanning results */
-
- /* 802.11 specific support */
-@@ -197,9 +214,7 @@
- #define SIOCGIWNICKN 0x8B1D /* get node name/nickname */
- /* As the ESSID and NICKN are strings up to 32 bytes long, it doesn't fit
- * within the 'iwreq' structure, so we need to use the 'data' member to
-- * point to a string in user space, like it is done for RANGE...
-- * The "flags" member indicate if the ESSID is active or not (promiscuous).
-- */
-+ * point to a string in user space, like it is done for RANGE... */
-
- /* Other parameters useful in 802.11 and some other devices */
- #define SIOCSIWRATE 0x8B20 /* set default bit rate (bps) */
-@@ -257,7 +272,10 @@
- /* Most events use the same identifier as ioctl requests */
-
- #define IWEVTXDROP 0x8C00 /* Packet dropped to excessive retry */
--#define IWEVQUAL 0x8C01 /* Quality part of statistics */
-+#define IWEVQUAL 0x8C01 /* Quality part of statistics (scan) */
-+#define IWEVCUSTOM 0x8C02 /* Driver specific ascii string */
-+#define IWEVREGISTERED 0x8C03 /* Discovered a new node (AP mode) */
-+#define IWEVEXPIRED 0x8C04 /* Expired a node (AP mode) */
-
- #define IWEVFIRST 0x8C00
-
-@@ -273,7 +291,8 @@
- #define IW_PRIV_TYPE_BYTE 0x1000 /* Char as number */
- #define IW_PRIV_TYPE_CHAR 0x2000 /* Char as character */
- #define IW_PRIV_TYPE_INT 0x4000 /* 32 bits int */
--#define IW_PRIV_TYPE_FLOAT 0x5000
-+#define IW_PRIV_TYPE_FLOAT 0x5000 /* struct iw_freq */
-+#define IW_PRIV_TYPE_ADDR 0x6000 /* struct sockaddr */
-
- #define IW_PRIV_SIZE_FIXED 0x0800 /* Variable or fixed nuber of args */
-
-@@ -297,13 +316,16 @@
-
- /* Maximum tx powers in the range struct */
- #define IW_MAX_TXPOWER 8
-+/* Note : if you more than 8 TXPowers, just set the max and min or
-+ * a few of them in the struct iw_range. */
-
- /* Maximum of address that you may set with SPY */
--#define IW_MAX_SPY 8
-+#define IW_MAX_SPY 8 /* set */
-+#define IW_MAX_GET_SPY 64 /* get */
-
- /* Maximum of address that you may get in the
- list of access points in range */
--#define IW_MAX_AP 8
-+#define IW_MAX_AP 64
-
- /* Maximum size of the ESSID and NICKN strings */
- #define IW_ESSID_MAX_SIZE 32
-@@ -315,6 +337,7 @@
- #define IW_MODE_MASTER 3 /* Synchronisation master or Access Point */
- #define IW_MODE_REPEAT 4 /* Wireless Repeater (forwarder) */
- #define IW_MODE_SECOND 5 /* Secondary master/repeater (backup) */
-+#define IW_MODE_MONITOR 6 /* Passive monitor (listen only) */
-
- /* Maximum number of size of encoding token available
- * they are listed in the range structure */
-@@ -350,8 +373,10 @@
- #define IW_POWER_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
-
- /* Transmit Power flags available */
-+#define IW_TXPOW_TYPE 0x00FF /* Type of value */
- #define IW_TXPOW_DBM 0x0000 /* Value is in dBm */
- #define IW_TXPOW_MWATT 0x0001 /* Value is in mW */
-+#define IW_TXPOW_RANGE 0x1000 /* Range of value between min/max */
-
- /* Retry limits and lifetime flags available */
- #define IW_RETRY_ON 0x0000 /* No details... */
-@@ -376,6 +401,9 @@
- /* Maximum size of returned data */
- #define IW_SCAN_MAX_DATA 4096 /* In bytes */
-
-+/* Max number of char in custom event - use multiple of them if needed */
-+#define IW_CUSTOM_MAX 256 /* In bytes */
-+
- /****************************** TYPES ******************************/
-
- /* --------------------------- SUBTYPES --------------------------- */
-@@ -411,9 +439,10 @@ struct iw_point
- */
- struct iw_freq
- {
-- __u32 m; /* Mantissa */
-- __u16 e; /* Exponent */
-+ __s32 m; /* Mantissa */
-+ __s16 e; /* Exponent */
- __u8 i; /* List index (when in range struct) */
-+ __u8 pad; /* Unused - just for alignement */
- };
-
- /*
-diff -u -p linux/include/net/iw_handler.14.h linux/include/net/iw_handler.h
---- linux/include/net/iw_handler.14.h Mon Dec 2 18:51:17 2002
-+++ linux/include/net/iw_handler.h Mon Dec 2 18:54:51 2002
-@@ -1,7 +1,7 @@
- /*
- * This file define the new driver API for Wireless Extensions
- *
-- * Version : 3 17.1.02
-+ * Version : 4 21.6.02
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
- * Copyright (c) 2001-2002 Jean Tourrilhes, All Rights Reserved.
-@@ -206,7 +206,7 @@
- * will be needed...
- * I just plan to increment with each new version.
- */
--#define IW_HANDLER_VERSION 3
-+#define IW_HANDLER_VERSION 4
-
- /*
- * Changes :
-@@ -217,6 +217,9 @@
- * - Add Wireless Event support :
- * o wireless_send_event() prototype
- * o iwe_stream_add_event/point() inline functions
-+ * V3 to V4
-+ * --------
-+ * - Reshuffle IW_HEADER_TYPE_XXX to map IW_PRIV_TYPE_XXX changes
- */
-
- /**************************** CONSTANTS ****************************/
-@@ -233,10 +236,10 @@
- #define IW_HEADER_TYPE_CHAR 2 /* char [IFNAMSIZ] */
- #define IW_HEADER_TYPE_UINT 4 /* __u32 */
- #define IW_HEADER_TYPE_FREQ 5 /* struct iw_freq */
--#define IW_HEADER_TYPE_POINT 6 /* struct iw_point */
--#define IW_HEADER_TYPE_PARAM 7 /* struct iw_param */
--#define IW_HEADER_TYPE_ADDR 8 /* struct sockaddr */
--#define IW_HEADER_TYPE_QUAL 9 /* struct iw_quality */
-+#define IW_HEADER_TYPE_ADDR 6 /* struct sockaddr */
-+#define IW_HEADER_TYPE_POINT 8 /* struct iw_point */
-+#define IW_HEADER_TYPE_PARAM 9 /* struct iw_param */
-+#define IW_HEADER_TYPE_QUAL 10 /* struct iw_quality */
-
- /* Handling flags */
- /* Most are not implemented. I just use them as a reminder of some
-diff -u -p linux/net/core/wireless.14.c linux/net/core/wireless.c
---- linux/net/core/wireless.14.c Mon Dec 2 18:51:35 2002
-+++ linux/net/core/wireless.c Mon Dec 2 18:53:10 2002
-@@ -33,8 +33,16 @@
- * o Propagate events as rtnetlink IFLA_WIRELESS option
- * o Generate event on selected SET requests
- *
-- * v4 - 18.04.01 - Jean II
-+ * v4 - 18.04.02 - Jean II
- * o Fix stupid off by one in iw_ioctl_description : IW_ESSID_MAX_SIZE + 1
-+ *
-+ * v5 - 21.06.02 - Jean II
-+ * o Add IW_PRIV_TYPE_ADDR in priv_type_size (+cleanup)
-+ * o Reshuffle IW_HEADER_TYPE_XXX to map IW_PRIV_TYPE_XXX changes
-+ * o Add IWEVCUSTOM for driver specific event/scanning token
-+ * o Turn on WE_STRICT_WRITE by default + kernel warning
-+ * o Fix WE_STRICT_WRITE in ioctl_export_private() (32 => iw_num)
-+ * o Fix off-by-one in test (extra_size <= IFNAMSIZ)
- */
-
- /***************************** INCLUDES *****************************/
-@@ -50,8 +58,9 @@
-
- /**************************** CONSTANTS ****************************/
-
--/* This will be turned on later on... */
--#undef WE_STRICT_WRITE /* Check write buffer size */
-+/* Enough lenience, let's make sure things are proper... */
-+#define WE_STRICT_WRITE /* Check write buffer size */
-+/* I'll probably drop both the define and kernel message in the next version */
-
- /* Debuging stuff */
- #undef WE_IOCTL_DEBUG /* Debug IOCTL API */
-@@ -106,7 +115,7 @@ static const struct iw_ioctl_description
- /* SIOCSIWSPY */
- { IW_HEADER_TYPE_POINT, 0, sizeof(struct sockaddr), 0, IW_MAX_SPY, 0},
- /* SIOCGIWSPY */
-- { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_SPY, 0},
-+ { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_GET_SPY, 0},
- /* -- hole -- */
- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
- /* -- hole -- */
-@@ -176,25 +185,41 @@ static const struct iw_ioctl_description
- { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
- /* IWEVQUAL */
- { IW_HEADER_TYPE_QUAL, 0, 0, 0, 0, 0},
-+ /* IWEVCUSTOM */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_CUSTOM_MAX, 0},
-+ /* IWEVREGISTERED */
-+ { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
-+ /* IWEVEXPIRED */
-+ { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
- };
- static const int standard_event_num = (sizeof(standard_event) /
- sizeof(struct iw_ioctl_description));
-
- /* Size (in bytes) of the various private data types */
--static const char priv_type_size[] = { 0, 1, 1, 0, 4, 4, 0, 0 };
-+static const char priv_type_size[] = {
-+ 0, /* IW_PRIV_TYPE_NONE */
-+ 1, /* IW_PRIV_TYPE_BYTE */
-+ 1, /* IW_PRIV_TYPE_CHAR */
-+ 0, /* Not defined */
-+ sizeof(__u32), /* IW_PRIV_TYPE_INT */
-+ sizeof(struct iw_freq), /* IW_PRIV_TYPE_FLOAT */
-+ sizeof(struct sockaddr), /* IW_PRIV_TYPE_ADDR */
-+ 0, /* Not defined */
-+};
-
- /* Size (in bytes) of various events */
- static const int event_type_size[] = {
-- IW_EV_LCP_LEN,
-+ IW_EV_LCP_LEN, /* IW_HEADER_TYPE_NULL */
-+ 0,
-+ IW_EV_CHAR_LEN, /* IW_HEADER_TYPE_CHAR */
- 0,
-- IW_EV_CHAR_LEN,
-+ IW_EV_UINT_LEN, /* IW_HEADER_TYPE_UINT */
-+ IW_EV_FREQ_LEN, /* IW_HEADER_TYPE_FREQ */
-+ IW_EV_ADDR_LEN, /* IW_HEADER_TYPE_ADDR */
- 0,
-- IW_EV_UINT_LEN,
-- IW_EV_FREQ_LEN,
- IW_EV_POINT_LEN, /* Without variable payload */
-- IW_EV_PARAM_LEN,
-- IW_EV_ADDR_LEN,
-- IW_EV_QUAL_LEN,
-+ IW_EV_PARAM_LEN, /* IW_HEADER_TYPE_PARAM */
-+ IW_EV_QUAL_LEN, /* IW_HEADER_TYPE_QUAL */
- };
-
- /************************ COMMON SUBROUTINES ************************/
-@@ -440,8 +465,10 @@ static inline int ioctl_export_private(s
- return -EFAULT;
- #ifdef WE_STRICT_WRITE
- /* Check if there is enough buffer up there */
-- if(iwr->u.data.length < (SIOCIWLASTPRIV - SIOCIWFIRSTPRIV + 1))
-+ if(iwr->u.data.length < dev->wireless_handlers->num_private_args) {
-+ printk(KERN_ERR "%s (WE) : Buffer for request SIOCGIWPRIV too small (%d<%d)\n", dev->name, iwr->u.data.length, dev->wireless_handlers->num_private_args);
- return -E2BIG;
-+ }
- #endif /* WE_STRICT_WRITE */
-
- /* Set the number of available ioctls. */
-@@ -471,6 +498,7 @@ static inline int ioctl_standard_call(st
- const struct iw_ioctl_description * descr;
- struct iw_request_info info;
- int ret = -EINVAL;
-+ int user_size = 0;
-
- /* Get the description of the IOCTL */
- if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
-@@ -518,11 +546,8 @@ static inline int ioctl_standard_call(st
- /* Check NULL pointer */
- if(iwr->u.data.pointer == NULL)
- return -EFAULT;
--#ifdef WE_STRICT_WRITE
-- /* Check if there is enough buffer up there */
-- if(iwr->u.data.length < descr->max_tokens)
-- return -E2BIG;
--#endif /* WE_STRICT_WRITE */
-+ /* Save user space buffer size for checking */
-+ user_size = iwr->u.data.length;
- }
-
- #ifdef WE_IOCTL_DEBUG
-@@ -559,6 +584,15 @@ static inline int ioctl_standard_call(st
-
- /* If we have something to return to the user */
- if (!ret && IW_IS_GET(cmd)) {
-+#ifdef WE_STRICT_WRITE
-+ /* Check if there is enough buffer up there */
-+ if(user_size < iwr->u.data.length) {
-+ printk(KERN_ERR "%s (WE) : Buffer for request %04X too small (%d<%d)\n", dev->name, cmd, user_size, iwr->u.data.length);
-+ kfree(extra);
-+ return -E2BIG;
-+ }
-+#endif /* WE_STRICT_WRITE */
-+
- err = copy_to_user(iwr->u.data.pointer, extra,
- iwr->u.data.length *
- descr->token_size);
-@@ -646,12 +680,18 @@ static inline int ioctl_private_call(str
- /* Compute the size of the set/get arguments */
- if(descr != NULL) {
- if(IW_IS_SET(cmd)) {
-+ int offset = 0; /* For sub-ioctls */
-+ /* Check for sub-ioctl handler */
-+ if(descr->name[0] == '\0')
-+ /* Reserve one int for sub-ioctl index */
-+ offset = sizeof(__u32);
-+
- /* Size of set arguments */
- extra_size = get_priv_size(descr->set_args);
-
- /* Does it fits in iwr ? */
- if((descr->set_args & IW_PRIV_SIZE_FIXED) &&
-- (extra_size < IFNAMSIZ))
-+ ((extra_size + offset) <= IFNAMSIZ))
- extra_size = 0;
- } else {
- /* Size of set arguments */
-@@ -659,7 +699,7 @@ static inline int ioctl_private_call(str
-
- /* Does it fits in iwr ? */
- if((descr->get_args & IW_PRIV_SIZE_FIXED) &&
-- (extra_size < IFNAMSIZ))
-+ (extra_size <= IFNAMSIZ))
- extra_size = 0;
- }
- }
-@@ -925,7 +965,7 @@ void wireless_send_event(struct net_devi
- * The best the driver could do is to log an error message.
- * We will do it ourselves instead...
- */
-- printk(KERN_ERR "%s (WE) : Invalid Wireless Event (0x%04X)\n",
-+ printk(KERN_ERR "%s (WE) : Invalid/Unknown Wireless Event (0x%04X)\n",
- dev->name, cmd);
- return;
- }
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/iw_handlers.w13-5.diff b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/iw_handlers.w13-5.diff
deleted file mode 100644
index a27a7654a9..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/iw_handlers.w13-5.diff
+++ /dev/null
@@ -1,1513 +0,0 @@
-diff -u -p -r --new-file linux/include/linux-w12/netdevice.h linux/include/linux/netdevice.h
---- linux/include/linux-w12/netdevice.h Thu Nov 22 11:47:09 2001
-+++ linux/include/linux/netdevice.h Thu Jan 17 12:00:39 2002
-@@ -278,6 +278,10 @@ struct net_device
- struct net_device_stats* (*get_stats)(struct net_device *dev);
- struct iw_statistics* (*get_wireless_stats)(struct net_device *dev);
-
-+ /* List of functions to handle Wireless Extensions (instead of ioctl).
-+ * See <net/iw_handler.h> for details. Jean II */
-+ struct iw_handler_def * wireless_handlers;
-+
- /*
- * This marks the end of the "visible" part of the structure. All
- * fields hereafter are internal to the system, and may change at
-diff -u -p -r --new-file linux/include/linux-w12/wireless.h linux/include/linux/wireless.h
---- linux/include/linux-w12/wireless.h Thu Nov 22 11:47:12 2001
-+++ linux/include/linux/wireless.h Thu Jan 17 12:04:08 2002
-@@ -1,9 +1,10 @@
- /*
- * This file define a set of standard wireless extensions
- *
-- * Version : 12 5.10.01
-+ * Version : 13 6.12.01
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-+ * Copyright (c) 1997-2001 Jean Tourrilhes, All Rights Reserved.
- */
-
- #ifndef _LINUX_WIRELESS_H
-@@ -11,6 +12,8 @@
-
- /************************** DOCUMENTATION **************************/
- /*
-+ * Initial APIs (1996 -> onward) :
-+ * -----------------------------
- * Basically, the wireless extensions are for now a set of standard ioctl
- * call + /proc/net/wireless
- *
-@@ -27,16 +30,27 @@
- * We have the list of command plus a structure descibing the
- * data exchanged...
- * Note that to add these ioctl, I was obliged to modify :
-- * net/core/dev.c (two place + add include)
-- * net/ipv4/af_inet.c (one place + add include)
-+ * # net/core/dev.c (two place + add include)
-+ * # net/ipv4/af_inet.c (one place + add include)
- *
- * /proc/net/wireless is a copy of /proc/net/dev.
- * We have a structure for data passed from the driver to /proc/net/wireless
- * Too add this, I've modified :
-- * net/core/dev.c (two other places)
-- * include/linux/netdevice.h (one place)
-- * include/linux/proc_fs.h (one place)
-+ * # net/core/dev.c (two other places)
-+ * # include/linux/netdevice.h (one place)
-+ * # include/linux/proc_fs.h (one place)
-+ *
-+ * New driver API (2001 -> onward) :
-+ * -------------------------------
-+ * This file is only concerned with the user space API and common definitions.
-+ * The new driver API is defined and documented in :
-+ * # include/net/iw_handler.h
- *
-+ * Note as well that /proc/net/wireless implementation has now moved in :
-+ * # include/linux/wireless.c
-+ *
-+ * Other comments :
-+ * --------------
- * Do not add here things that are redundant with other mechanisms
- * (drivers init, ifconfig, /proc/net/dev, ...) and with are not
- * wireless specific.
-@@ -54,16 +68,14 @@
- #include <linux/socket.h> /* for "struct sockaddr" et al */
- #include <linux/if.h> /* for IFNAMSIZ and co... */
-
--/**************************** CONSTANTS ****************************/
--
--/* --------------------------- VERSION --------------------------- */
-+/***************************** VERSION *****************************/
- /*
- * This constant is used to know the availability of the wireless
- * extensions and to know which version of wireless extensions it is
- * (there is some stuff that will be added in the future...)
- * I just plan to increment with each new version.
- */
--#define WIRELESS_EXT 12
-+#define WIRELESS_EXT 13
-
- /*
- * Changes :
-@@ -123,12 +135,20 @@
- * - Add DEV PRIVATE IOCTL to avoid collisions in SIOCDEVPRIVATE space
- * - Add new statistics (frag, retry, beacon)
- * - Add average quality (for user space calibration)
-+ *
-+ * V12 to V13
-+ * ----------
-+ * - Document creation of new driver API.
-+ * - Extract union iwreq_data from struct iwreq (for new driver API).
-+ * - Rename SIOCSIWNAME as SIOCSIWCOMMIT
- */
-
-+/**************************** CONSTANTS ****************************/
-+
- /* -------------------------- IOCTL LIST -------------------------- */
-
- /* Basic operations */
--#define SIOCSIWNAME 0x8B00 /* Unused */
-+#define SIOCSIWCOMMIT 0x8B00 /* Commit pending changes to driver */
- #define SIOCGIWNAME 0x8B01 /* get name == wireless protocol */
- #define SIOCSIWNWID 0x8B02 /* set network id (the cell) */
- #define SIOCGIWNWID 0x8B03 /* get network id */
-@@ -414,13 +434,49 @@ struct iw_statistics
-
- /* ------------------------ IOCTL REQUEST ------------------------ */
- /*
-+ * This structure defines the payload of an ioctl, and is used
-+ * below.
-+ *
-+ * Note that this structure should fit on the memory footprint
-+ * of iwreq (which is the same as ifreq), which mean a max size of
-+ * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
-+ * You should check this when increasing the structures defined
-+ * above in this file...
-+ */
-+union iwreq_data
-+{
-+ /* Config - generic */
-+ char name[IFNAMSIZ];
-+ /* Name : used to verify the presence of wireless extensions.
-+ * Name of the protocol/provider... */
-+
-+ struct iw_point essid; /* Extended network name */
-+ struct iw_param nwid; /* network id (or domain - the cell) */
-+ struct iw_freq freq; /* frequency or channel :
-+ * 0-1000 = channel
-+ * > 1000 = frequency in Hz */
-+
-+ struct iw_param sens; /* signal level threshold */
-+ struct iw_param bitrate; /* default bit rate */
-+ struct iw_param txpower; /* default transmit power */
-+ struct iw_param rts; /* RTS threshold threshold */
-+ struct iw_param frag; /* Fragmentation threshold */
-+ __u32 mode; /* Operation mode */
-+ struct iw_param retry; /* Retry limits & lifetime */
-+
-+ struct iw_point encoding; /* Encoding stuff : tokens */
-+ struct iw_param power; /* PM duration/timeout */
-+
-+ struct sockaddr ap_addr; /* Access point address */
-+
-+ struct iw_point data; /* Other large parameters */
-+};
-+
-+/*
- * The structure to exchange data for ioctl.
- * This structure is the same as 'struct ifreq', but (re)defined for
- * convenience...
-- *
-- * Note that it should fit on the same memory footprint !
-- * You should check this when increasing the above structures (16 octets)
-- * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
-+ * Do I need to remind you about structure size (32 octets) ?
- */
- struct iwreq
- {
-@@ -429,35 +485,8 @@ struct iwreq
- char ifrn_name[IFNAMSIZ]; /* if name, e.g. "eth0" */
- } ifr_ifrn;
-
-- /* Data part */
-- union
-- {
-- /* Config - generic */
-- char name[IFNAMSIZ];
-- /* Name : used to verify the presence of wireless extensions.
-- * Name of the protocol/provider... */
--
-- struct iw_point essid; /* Extended network name */
-- struct iw_param nwid; /* network id (or domain - the cell) */
-- struct iw_freq freq; /* frequency or channel :
-- * 0-1000 = channel
-- * > 1000 = frequency in Hz */
--
-- struct iw_param sens; /* signal level threshold */
-- struct iw_param bitrate; /* default bit rate */
-- struct iw_param txpower; /* default transmit power */
-- struct iw_param rts; /* RTS threshold threshold */
-- struct iw_param frag; /* Fragmentation threshold */
-- __u32 mode; /* Operation mode */
-- struct iw_param retry; /* Retry limits & lifetime */
--
-- struct iw_point encoding; /* Encoding stuff : tokens */
-- struct iw_param power; /* PM duration/timeout */
--
-- struct sockaddr ap_addr; /* Access point address */
--
-- struct iw_point data; /* Other large parameters */
-- } u;
-+ /* Data part (defined just above) */
-+ union iwreq_data u;
- };
-
- /* -------------------------- IOCTL DATA -------------------------- */
-diff -u -p -r --new-file linux/include/net-w12/iw_handler.h linux/include/net/iw_handler.h
---- linux/include/net-w12/iw_handler.h Wed Dec 31 16:00:00 1969
-+++ linux/include/net/iw_handler.h Thu Jan 17 12:16:46 2002
-@@ -0,0 +1,374 @@
-+/*
-+ * This file define the new driver API for Wireless Extensions
-+ *
-+ * Version : 2 6.12.01
-+ *
-+ * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-+ * Copyright (c) 2001 Jean Tourrilhes, All Rights Reserved.
-+ */
-+
-+#ifndef _IW_HANDLER_H
-+#define _IW_HANDLER_H
-+
-+/************************** DOCUMENTATION **************************/
-+/*
-+ * Initial driver API (1996 -> onward) :
-+ * -----------------------------------
-+ * The initial API just sends the IOCTL request received from user space
-+ * to the driver (via the driver ioctl handler). The driver has to
-+ * handle all the rest...
-+ *
-+ * The initial API also defines a specific handler in struct net_device
-+ * to handle wireless statistics.
-+ *
-+ * The initial APIs served us well and has proven a reasonably good design.
-+ * However, there is a few shortcommings :
-+ * o No events, everything is a request to the driver.
-+ * o Large ioctl function in driver with gigantic switch statement
-+ * (i.e. spaghetti code).
-+ * o Driver has to mess up with copy_to/from_user, and in many cases
-+ * does it unproperly. Common mistakes are :
-+ * * buffer overflows (no checks or off by one checks)
-+ * * call copy_to/from_user with irq disabled
-+ * o The user space interface is tied to ioctl because of the use
-+ * copy_to/from_user.
-+ *
-+ * New driver API (2001 -> onward) :
-+ * -------------------------------
-+ * The new driver API is just a bunch of standard functions (handlers),
-+ * each handling a specific Wireless Extension. The driver just export
-+ * the list of handler it supports, and those will be called apropriately.
-+ *
-+ * I tried to keep the main advantage of the previous API (simplicity,
-+ * efficiency and light weight), and also I provide a good dose of backward
-+ * compatibility (most structures are the same, driver can use both API
-+ * simultaneously, ...).
-+ * Hopefully, I've also addressed the shortcomming of the initial API.
-+ *
-+ * The advantage of the new API are :
-+ * o Handling of Extensions in driver broken in small contained functions
-+ * o Tighter checks of ioctl before calling the driver
-+ * o Flexible commit strategy (at least, the start of it)
-+ * o Backward compatibility (can be mixed with old API)
-+ * o Driver doesn't have to worry about memory and user-space issues
-+ * The last point is important for the following reasons :
-+ * o You are now able to call the new driver API from any API you
-+ * want (including from within other parts of the kernel).
-+ * o Common mistakes are avoided (buffer overflow, user space copy
-+ * with irq disabled and so on).
-+ *
-+ * The Drawback of the new API are :
-+ * o bloat (especially kernel)
-+ * o need to migrate existing drivers to new API
-+ * My initial testing shows that the new API adds around 3kB to the kernel
-+ * and save between 0 and 5kB from a typical driver.
-+ * Also, as all structures and data types are unchanged, the migration is
-+ * quite straightforward (but tedious).
-+ *
-+ * ---
-+ *
-+ * The new driver API is defined below in this file. User space should
-+ * not be aware of what's happening down there...
-+ *
-+ * A new kernel wrapper is in charge of validating the IOCTLs and calling
-+ * the appropriate driver handler. This is implemented in :
-+ * # net/core/wireless.c
-+ *
-+ * The driver export the list of handlers in :
-+ * # include/linux/netdevice.h (one place)
-+ *
-+ * The new driver API is available for WIRELESS_EXT >= 13.
-+ * Good luck with migration to the new API ;-)
-+ */
-+
-+/* ---------------------- THE IMPLEMENTATION ---------------------- */
-+/*
-+ * Some of the choice I've made are pretty controversials. Defining an
-+ * API is very much weighting compromises. This goes into some of the
-+ * details and the thinking behind the implementation.
-+ *
-+ * Implementation goals :
-+ * --------------------
-+ * The implementation goals were as follow :
-+ * o Obvious : you should not need a PhD to understand what's happening,
-+ * the benefit is easier maintainance.
-+ * o Flexible : it should accomodate a wide variety of driver
-+ * implementations and be as flexible as the old API.
-+ * o Lean : it should be efficient memory wise to minimise the impact
-+ * on kernel footprint.
-+ * o Transparent to user space : the large number of user space
-+ * applications that use Wireless Extensions should not need
-+ * any modifications.
-+ *
-+ * Array of functions versus Struct of functions
-+ * ---------------------------------------------
-+ * 1) Having an array of functions allow the kernel code to access the
-+ * handler in a single lookup, which is much more efficient (think hash
-+ * table here).
-+ * 2) The only drawback is that driver writer may put their handler in
-+ * the wrong slot. This is trivial to test (I set the frequency, the
-+ * bitrate changes). Once the handler is in the proper slot, it will be
-+ * there forever, because the array is only extended at the end.
-+ * 3) Backward/forward compatibility : adding new handler just require
-+ * extending the array, so you can put newer driver in older kernel
-+ * without having to patch the kernel code (and vice versa).
-+ *
-+ * All handler are of the same generic type
-+ * ----------------------------------------
-+ * That's a feature !!!
-+ * 1) Having a generic handler allow to have generic code, which is more
-+ * efficient. If each of the handler was individually typed I would need
-+ * to add a big switch in the kernel (== more bloat). This solution is
-+ * more scalable, adding new Wireless Extensions doesn't add new code.
-+ * 2) You can use the same handler in different slots of the array. For
-+ * hardware, it may be more efficient or logical to handle multiple
-+ * Wireless Extensions with a single function, and the API allow you to
-+ * do that. (An example would be a single record on the card to control
-+ * both bitrate and frequency, the handler would read the old record,
-+ * modify it according to info->cmd and rewrite it).
-+ *
-+ * Functions prototype uses union iwreq_data
-+ * -----------------------------------------
-+ * Some would have prefered functions defined this way :
-+ * static int mydriver_ioctl_setrate(struct net_device *dev,
-+ * long rate, int auto)
-+ * 1) The kernel code doesn't "validate" the content of iwreq_data, and
-+ * can't do it (different hardware may have different notion of what a
-+ * valid frequency is), so we don't pretend that we do it.
-+ * 2) The above form is not extendable. If I want to add a flag (for
-+ * example to distinguish setting max rate and basic rate), I would
-+ * break the prototype. Using iwreq_data is more flexible.
-+ * 3) Also, the above form is not generic (see above).
-+ * 4) I don't expect driver developper using the wrong field of the
-+ * union (Doh !), so static typechecking doesn't add much value.
-+ * 5) Lastly, you can skip the union by doing :
-+ * static int mydriver_ioctl_setrate(struct net_device *dev,
-+ * struct iw_request_info *info,
-+ * struct iw_param *rrq,
-+ * char *extra)
-+ * And then adding the handler in the array like this :
-+ * (iw_handler) mydriver_ioctl_setrate, // SIOCSIWRATE
-+ *
-+ * Using functions and not a registry
-+ * ----------------------------------
-+ * Another implementation option would have been for every instance to
-+ * define a registry (a struct containing all the Wireless Extensions)
-+ * and only have a function to commit the registry to the hardware.
-+ * 1) This approach can be emulated by the current code, but not
-+ * vice versa.
-+ * 2) Some drivers don't keep any configuration in the driver, for them
-+ * adding such a registry would be a significant bloat.
-+ * 3) The code to translate from Wireless Extension to native format is
-+ * needed anyway, so it would not reduce significantely the amount of code.
-+ * 4) The current approach only selectively translate Wireless Extensions
-+ * to native format and only selectively set, whereas the registry approach
-+ * would require to translate all WE and set all parameters for any single
-+ * change.
-+ * 5) For many Wireless Extensions, the GET operation return the current
-+ * dynamic value, not the value that was set.
-+ *
-+ * This header is <net/iw_handler.h>
-+ * ---------------------------------
-+ * 1) This header is kernel space only and should not be exported to
-+ * user space. Headers in "include/linux/" are exported, headers in
-+ * "include/net/" are not.
-+ *
-+ * Mixed 32/64 bit issues
-+ * ----------------------
-+ * The Wireless Extensions are designed to be 64 bit clean, by using only
-+ * datatypes with explicit storage size.
-+ * There are some issues related to kernel and user space using different
-+ * memory model, and in particular 64bit kernel with 32bit user space.
-+ * The problem is related to struct iw_point, that contains a pointer
-+ * that *may* need to be translated.
-+ * This is quite messy. The new API doesn't solve this problem (it can't),
-+ * but is a step in the right direction :
-+ * 1) Meta data about each ioctl is easily available, so we know what type
-+ * of translation is needed.
-+ * 2) The move of data between kernel and user space is only done in a single
-+ * place in the kernel, so adding specific hooks in there is possible.
-+ * 3) In the long term, it allows to move away from using ioctl as the
-+ * user space API.
-+ *
-+ * So many comments and so few code
-+ * --------------------------------
-+ * That's a feature. Comments won't bloat the resulting kernel binary.
-+ */
-+
-+/***************************** INCLUDES *****************************/
-+
-+#include <linux/wireless.h> /* IOCTL user space API */
-+
-+/***************************** VERSION *****************************/
-+/*
-+ * This constant is used to know which version of the driver API is
-+ * available. Hopefully, this will be pretty stable and no changes
-+ * will be needed...
-+ * I just plan to increment with each new version.
-+ */
-+#define IW_HANDLER_VERSION 2
-+
-+/**************************** CONSTANTS ****************************/
-+
-+/* Special error message for the driver to indicate that we
-+ * should do a commit after return from the iw_handler */
-+#define EIWCOMMIT EINPROGRESS
-+
-+/* Flags available in struct iw_request_info */
-+#define IW_REQUEST_FLAG_NONE 0x0000 /* No flag so far */
-+
-+/* Type of headers we know about (basically union iwreq_data) */
-+#define IW_HEADER_TYPE_NULL 0 /* Not available */
-+#define IW_HEADER_TYPE_CHAR 2 /* char [IFNAMSIZ] */
-+#define IW_HEADER_TYPE_UINT 4 /* __u32 */
-+#define IW_HEADER_TYPE_FREQ 5 /* struct iw_freq */
-+#define IW_HEADER_TYPE_POINT 6 /* struct iw_point */
-+#define IW_HEADER_TYPE_PARAM 7 /* struct iw_param */
-+#define IW_HEADER_TYPE_ADDR 8 /* struct sockaddr */
-+
-+/* Handling flags */
-+/* Most are not implemented. I just use them as a reminder of some
-+ * cool features we might need one day ;-) */
-+#define IW_DESCR_FLAG_NONE 0x0000 /* Obvious */
-+/* Wrapper level flags */
-+#define IW_DESCR_FLAG_DUMP 0x0001 /* Not part of the dump command */
-+#define IW_DESCR_FLAG_EVENT 0x0002 /* Generate an event on SET */
-+#define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET request is ROOT only */
-+/* Driver level flags */
-+#define IW_DESCR_FLAG_WAIT 0x0100 /* Wait for driver event */
-+
-+/****************************** TYPES ******************************/
-+
-+/* ----------------------- WIRELESS HANDLER ----------------------- */
-+/*
-+ * A wireless handler is just a standard function, that looks like the
-+ * ioctl handler.
-+ * We also define there how a handler list look like... As the Wireless
-+ * Extension space is quite dense, we use a simple array, which is faster
-+ * (that's the perfect hash table ;-).
-+ */
-+
-+/*
-+ * Meta data about the request passed to the iw_handler.
-+ * Most handlers can safely ignore what's in there.
-+ * The 'cmd' field might come handy if you want to use the same handler
-+ * for multiple command...
-+ * This struct is also my long term insurance. I can add new fields here
-+ * without breaking the prototype of iw_handler...
-+ */
-+struct iw_request_info
-+{
-+ __u16 cmd; /* Wireless Extension command */
-+ __u16 flags; /* More to come ;-) */
-+};
-+
-+/*
-+ * This is how a function handling a Wireless Extension should look
-+ * like (both get and set, standard and private).
-+ */
-+typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,
-+ union iwreq_data *wrqu, char *extra);
-+
-+/*
-+ * This define all the handler that the driver export.
-+ * As you need only one per driver type, please use a static const
-+ * shared by all driver instances... Same for the members...
-+ * This will be linked from net_device in <linux/netdevice.h>
-+ */
-+struct iw_handler_def
-+{
-+ /* Number of handlers defined (more precisely, index of the
-+ * last defined handler + 1) */
-+ __u16 num_standard;
-+ __u16 num_private;
-+ /* Number of private arg description */
-+ __u16 num_private_args;
-+
-+ /* Array of handlers for standard ioctls
-+ * We will call dev->wireless_handlers->standard[ioctl - SIOCSIWNAME]
-+ */
-+ iw_handler * standard;
-+
-+ /* Array of handlers for private ioctls
-+ * Will call dev->wireless_handlers->private[ioctl - SIOCIWFIRSTPRIV]
-+ */
-+ iw_handler * private;
-+
-+ /* Arguments of private handler. This one is just a list, so you
-+ * can put it in any order you want and should not leave holes...
-+ * We will automatically export that to user space... */
-+ struct iw_priv_args * private_args;
-+
-+ /* In the long term, get_wireless_stats will move from
-+ * 'struct net_device' to here, to minimise bloat. */
-+};
-+
-+/* ----------------------- WIRELESS EVENTS ----------------------- */
-+/*
-+ * Currently we don't support events, so let's just plan for the
-+ * future...
-+ */
-+
-+/*
-+ * A Wireless Event.
-+ */
-+// How do we define short header ? We don't want a flag on length.
-+// Probably a flag on event ? Highest bit to zero...
-+struct iw_event
-+{
-+ __u16 length; /* Lenght of this stuff */
-+ __u16 event; /* Wireless IOCTL */
-+ union iwreq_data header; /* IOCTL fixed payload */
-+ char extra[0]; /* Optional IOCTL data */
-+};
-+
-+/* ---------------------- IOCTL DESCRIPTION ---------------------- */
-+/*
-+ * One of the main goal of the new interface is to deal entirely with
-+ * user space/kernel space memory move.
-+ * For that, we need to know :
-+ * o if iwreq is a pointer or contain the full data
-+ * o what is the size of the data to copy
-+ *
-+ * For private IOCTLs, we use the same rules as used by iwpriv and
-+ * defined in struct iw_priv_args.
-+ *
-+ * For standard IOCTLs, things are quite different and we need to
-+ * use the stuctures below. Actually, this struct is also more
-+ * efficient, but that's another story...
-+ */
-+
-+/*
-+ * Describe how a standard IOCTL looks like.
-+ */
-+struct iw_ioctl_description
-+{
-+ __u8 header_type; /* NULL, iw_point or other */
-+ __u8 token_type; /* Future */
-+ __u16 token_size; /* Granularity of payload */
-+ __u16 min_tokens; /* Min acceptable token number */
-+ __u16 max_tokens; /* Max acceptable token number */
-+ __u32 flags; /* Special handling of the request */
-+};
-+
-+/* Need to think of short header translation table. Later. */
-+
-+/**************************** PROTOTYPES ****************************/
-+/*
-+ * Functions part of the Wireless Extensions (defined in net/core/wireless.c).
-+ * Those may be called only within the kernel.
-+ */
-+
-+/* First : function strictly used inside the kernel */
-+
-+/* Handle /proc/net/wireless, called in net/code/dev.c */
-+extern int dev_get_wireless_info(char * buffer, char **start, off_t offset,
-+ int length);
-+
-+/* Handle IOCTLs, called in net/code/dev.c */
-+extern int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd);
-+
-+/* Second : functions that may be called by driver modules */
-+/* None yet */
-+
-+#endif /* _LINUX_WIRELESS_H */
-diff -u -p -r --new-file linux/net/core-w12/Makefile linux/net/core/Makefile
---- linux/net/core-w12/Makefile Tue Oct 30 15:08:12 2001
-+++ linux/net/core/Makefile Thu Jan 17 11:06:07 2002
-@@ -26,5 +26,8 @@ obj-$(CONFIG_NET) += dev.o dev_mcast.o d
- obj-$(CONFIG_NETFILTER) += netfilter.o
- obj-$(CONFIG_NET_DIVERT) += dv.o
- obj-$(CONFIG_NET_PROFILE) += profile.o
-+obj-$(CONFIG_NET_RADIO) += wireless.o
-+# Ugly. I wish all wireless drivers were moved in drivers/net/wireless
-+obj-$(CONFIG_NET_PCMCIA_RADIO) += wireless.o
-
- include $(TOPDIR)/Rules.make
-diff -u -p -r --new-file linux/net/core-w12/dev.c linux/net/core/dev.c
---- linux/net/core-w12/dev.c Wed Nov 7 14:39:36 2001
-+++ linux/net/core/dev.c Thu Jan 17 11:06:07 2002
-@@ -102,6 +102,7 @@
- #include <linux/module.h>
- #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
- #include <linux/wireless.h> /* Note : will define WIRELESS_EXT */
-+#include <net/iw_handler.h>
- #endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
- #ifdef CONFIG_PLIP
- extern int plip_init(void);
-@@ -1796,122 +1797,6 @@ static int dev_proc_stats(char *buffer,
- #endif /* CONFIG_PROC_FS */
-
-
--#ifdef WIRELESS_EXT
--#ifdef CONFIG_PROC_FS
--
--/*
-- * Print one entry of /proc/net/wireless
-- * This is a clone of /proc/net/dev (just above)
-- */
--static int sprintf_wireless_stats(char *buffer, struct net_device *dev)
--{
-- /* Get stats from the driver */
-- struct iw_statistics *stats = (dev->get_wireless_stats ?
-- dev->get_wireless_stats(dev) :
-- (struct iw_statistics *) NULL);
-- int size;
--
-- if (stats != (struct iw_statistics *) NULL) {
-- size = sprintf(buffer,
-- "%6s: %04x %3d%c %3d%c %3d%c %6d %6d %6d %6d %6d %6d\n",
-- dev->name,
-- stats->status,
-- stats->qual.qual,
-- stats->qual.updated & 1 ? '.' : ' ',
-- stats->qual.level,
-- stats->qual.updated & 2 ? '.' : ' ',
-- stats->qual.noise,
-- stats->qual.updated & 4 ? '.' : ' ',
-- stats->discard.nwid,
-- stats->discard.code,
-- stats->discard.fragment,
-- stats->discard.retries,
-- stats->discard.misc,
-- stats->miss.beacon);
-- stats->qual.updated = 0;
-- }
-- else
-- size = 0;
--
-- return size;
--}
--
--/*
-- * Print info for /proc/net/wireless (print all entries)
-- * This is a clone of /proc/net/dev (just above)
-- */
--static int dev_get_wireless_info(char * buffer, char **start, off_t offset,
-- int length)
--{
-- int len = 0;
-- off_t begin = 0;
-- off_t pos = 0;
-- int size;
--
-- struct net_device * dev;
--
-- size = sprintf(buffer,
-- "Inter-| sta-| Quality | Discarded packets | Missed\n"
-- " face | tus | link level noise | nwid crypt frag retry misc | beacon\n"
-- );
--
-- pos += size;
-- len += size;
--
-- read_lock(&dev_base_lock);
-- for (dev = dev_base; dev != NULL; dev = dev->next) {
-- size = sprintf_wireless_stats(buffer + len, dev);
-- len += size;
-- pos = begin + len;
--
-- if (pos < offset) {
-- len = 0;
-- begin = pos;
-- }
-- if (pos > offset + length)
-- break;
-- }
-- read_unlock(&dev_base_lock);
--
-- *start = buffer + (offset - begin); /* Start of wanted data */
-- len -= (offset - begin); /* Start slop */
-- if (len > length)
-- len = length; /* Ending slop */
-- if (len < 0)
-- len = 0;
--
-- return len;
--}
--#endif /* CONFIG_PROC_FS */
--
--/*
-- * Allow programatic access to /proc/net/wireless even if /proc
-- * doesn't exist... Also more efficient...
-- */
--static inline int dev_iwstats(struct net_device *dev, struct ifreq *ifr)
--{
-- /* Get stats from the driver */
-- struct iw_statistics *stats = (dev->get_wireless_stats ?
-- dev->get_wireless_stats(dev) :
-- (struct iw_statistics *) NULL);
--
-- if (stats != (struct iw_statistics *) NULL) {
-- struct iwreq * wrq = (struct iwreq *)ifr;
--
-- /* Copy statistics to the user buffer */
-- if(copy_to_user(wrq->u.data.pointer, stats,
-- sizeof(struct iw_statistics)))
-- return -EFAULT;
--
-- /* Check if we need to clear the update flag */
-- if(wrq->u.data.flags != 0)
-- stats->qual.updated = 0;
-- return(0);
-- } else
-- return -EOPNOTSUPP;
--}
--#endif /* WIRELESS_EXT */
--
- /**
- * netdev_set_master - set up master/slave pair
- * @slave: slave device
-@@ -2209,11 +2094,6 @@ static int dev_ifsioc(struct ifreq *ifr,
- notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev);
- return 0;
-
--#ifdef WIRELESS_EXT
-- case SIOCGIWSTATS:
-- return dev_iwstats(dev, ifr);
--#endif /* WIRELESS_EXT */
--
- /*
- * Unknown or private ioctl
- */
-@@ -2239,17 +2119,6 @@ static int dev_ifsioc(struct ifreq *ifr,
- return -EOPNOTSUPP;
- }
-
--#ifdef WIRELESS_EXT
-- if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
-- if (dev->do_ioctl) {
-- if (!netif_device_present(dev))
-- return -ENODEV;
-- return dev->do_ioctl(dev, ifr, cmd);
-- }
-- return -EOPNOTSUPP;
-- }
--#endif /* WIRELESS_EXT */
--
- }
- return -EINVAL;
- }
-@@ -2431,7 +2300,8 @@ int dev_ioctl(unsigned int cmd, void *ar
- }
- dev_load(ifr.ifr_name);
- rtnl_lock();
-- ret = dev_ifsioc(&ifr, cmd);
-+ /* Follow me in net/core/wireless.c */
-+ ret = wireless_process_ioctl(&ifr, cmd);
- rtnl_unlock();
- if (!ret && IW_IS_GET(cmd) &&
- copy_to_user(arg, &ifr, sizeof(struct ifreq)))
-@@ -2856,6 +2726,7 @@ int __init net_dev_init(void)
- proc_net_create("dev", 0, dev_get_info);
- create_proc_read_entry("net/softnet_stat", 0, 0, dev_proc_stats, NULL);
- #ifdef WIRELESS_EXT
-+ /* Available in net/core/wireless.c */
- proc_net_create("wireless", 0, dev_get_wireless_info);
- #endif /* WIRELESS_EXT */
- #endif /* CONFIG_PROC_FS */
-diff -u -p -r --new-file linux/net/core-w12/wireless.c linux/net/core/wireless.c
---- linux/net/core-w12/wireless.c Wed Dec 31 16:00:00 1969
-+++ linux/net/core/wireless.c Mon Jan 21 11:13:23 2002
-@@ -0,0 +1,733 @@
-+/*
-+ * This file implement the Wireless Extensions APIs.
-+ *
-+ * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-+ * Copyright (c) 1997-2001 Jean Tourrilhes, All Rights Reserved.
-+ *
-+ * (As all part of the Linux kernel, this file is GPL)
-+ */
-+
-+/************************** DOCUMENTATION **************************/
-+/*
-+ * API definition :
-+ * --------------
-+ * See <linux/wireless.h> for details of the APIs and the rest.
-+ *
-+ * History :
-+ * -------
-+ *
-+ * v1 - 5.12.01 - Jean II
-+ * o Created this file.
-+ *
-+ * v2 - 13.12.01 - Jean II
-+ * o Move /proc/net/wireless stuff from net/core/dev.c to here
-+ * o Make Wireless Extension IOCTLs go through here
-+ * o Added iw_handler handling ;-)
-+ * o Added standard ioctl description
-+ * o Initial dumb commit strategy based on orinoco.c
-+ */
-+
-+/***************************** INCLUDES *****************************/
-+
-+#include <asm/uaccess.h> /* copy_to_user() */
-+#include <linux/config.h> /* Not needed ??? */
-+#include <linux/types.h> /* off_t */
-+#include <linux/netdevice.h> /* struct ifreq, dev_get_by_name() */
-+
-+#include <linux/wireless.h> /* Pretty obvious */
-+#include <net/iw_handler.h> /* New driver API */
-+
-+/**************************** CONSTANTS ****************************/
-+
-+/* This will be turned on later on... */
-+#undef WE_STRICT_WRITE /* Check write buffer size */
-+
-+/* Debuging stuff */
-+#undef WE_IOCTL_DEBUG /* Debug IOCTL API */
-+
-+/************************* GLOBAL VARIABLES *************************/
-+/*
-+ * You should not use global variables, because or re-entrancy.
-+ * On our case, it's only const, so it's OK...
-+ */
-+static const struct iw_ioctl_description standard_ioctl[] = {
-+ /* SIOCSIWCOMMIT (internal) */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCGIWNAME */
-+ { IW_HEADER_TYPE_CHAR, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWNWID */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, IW_DESCR_FLAG_EVENT},
-+ /* SIOCGIWNWID */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWFREQ */
-+ { IW_HEADER_TYPE_FREQ, 0, 0, 0, 0, IW_DESCR_FLAG_EVENT},
-+ /* SIOCGIWFREQ */
-+ { IW_HEADER_TYPE_FREQ, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWMODE */
-+ { IW_HEADER_TYPE_UINT, 0, 0, 0, 0, IW_DESCR_FLAG_EVENT},
-+ /* SIOCGIWMODE */
-+ { IW_HEADER_TYPE_UINT, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWSENS */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWSENS */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWRANGE */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCGIWRANGE */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, sizeof(struct iw_range), IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWPRIV */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCGIWPRIV (handled directly by us) */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCSIWSTATS */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCGIWSTATS (handled directly by us) */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWSPY */
-+ { IW_HEADER_TYPE_POINT, 0, sizeof(struct sockaddr), 0, IW_MAX_SPY, 0},
-+ /* SIOCGIWSPY */
-+ { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_SPY, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCSIWAP */
-+ { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
-+ /* SIOCGIWAP */
-+ { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCGIWAPLIST */
-+ { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_AP, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCSIWESSID */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, IW_DESCR_FLAG_EVENT},
-+ /* SIOCGIWESSID */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWNICKN */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, 0},
-+ /* SIOCGIWNICKN */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCSIWRATE */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWRATE */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWRTS */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWRTS */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWFRAG */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWFRAG */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWTXPOW */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWTXPOW */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWRETRY */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWRETRY */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWENCODE */
-+ { IW_HEADER_TYPE_POINT, 4, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT},
-+ /* SIOCGIWENCODE */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_DUMP | IW_DESCR_FLAG_RESTRICT},
-+ /* SIOCSIWPOWER */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWPOWER */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+};
-+
-+/* Size (in bytes) of the various private data types */
-+char priv_type_size[] = { 0, 1, 1, 0, 4, 4, 0, 0 };
-+
-+/************************ COMMON SUBROUTINES ************************/
-+/*
-+ * Stuff that may be used in various place or doesn't fit in one
-+ * of the section below.
-+ */
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Return the driver handler associated with a specific Wireless Extension.
-+ * Called from various place, so make sure it remains efficient.
-+ */
-+static inline iw_handler get_handler(struct net_device *dev,
-+ unsigned int cmd)
-+{
-+ unsigned int index; /* MUST be unsigned */
-+
-+ /* Check if we have some wireless handlers defined */
-+ if(dev->wireless_handlers == NULL)
-+ return NULL;
-+
-+ /* Try as a standard command */
-+ index = cmd - SIOCIWFIRST;
-+ if(index < dev->wireless_handlers->num_standard)
-+ return dev->wireless_handlers->standard[index];
-+
-+ /* Try as a private command */
-+ index = cmd - SIOCIWFIRSTPRIV;
-+ if(index < dev->wireless_handlers->num_private)
-+ return dev->wireless_handlers->private[index];
-+
-+ /* Not found */
-+ return NULL;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Get statistics out of the driver
-+ */
-+static inline struct iw_statistics *get_wireless_stats(struct net_device *dev)
-+{
-+ return (dev->get_wireless_stats ?
-+ dev->get_wireless_stats(dev) :
-+ (struct iw_statistics *) NULL);
-+ /* In the future, get_wireless_stats may move from 'struct net_device'
-+ * to 'struct iw_handler_def', to de-bloat struct net_device.
-+ * Definitely worse a thought... */
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Call the commit handler in the driver
-+ * (if exist and if conditions are right)
-+ *
-+ * Note : our current commit strategy is currently pretty dumb,
-+ * but we will be able to improve on that...
-+ * The goal is to try to agreagate as many changes as possible
-+ * before doing the commit. Drivers that will define a commit handler
-+ * are usually those that need a reset after changing parameters, so
-+ * we want to minimise the number of reset.
-+ * A cool idea is to use a timer : at each "set" command, we re-set the
-+ * timer, when the timer eventually fires, we call the driver.
-+ * Hopefully, more on that later.
-+ *
-+ * Also, I'm waiting to see how many people will complain about the
-+ * netif_running(dev) test. I'm open on that one...
-+ * Hopefully, the driver will remember to do a commit in "open()" ;-)
-+ */
-+static inline int call_commit_handler(struct net_device * dev)
-+{
-+ if((netif_running(dev)) &&
-+ (dev->wireless_handlers->standard[0] != NULL)) {
-+ /* Call the commit handler on the driver */
-+ return dev->wireless_handlers->standard[0](dev, NULL,
-+ NULL, NULL);
-+ } else
-+ return 0; /* Command completed successfully */
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Number of private arguments
-+ */
-+static inline int get_priv_size(__u16 args)
-+{
-+ int num = args & IW_PRIV_SIZE_MASK;
-+ int type = (args & IW_PRIV_TYPE_MASK) >> 12;
-+
-+ return num * priv_type_size[type];
-+}
-+
-+
-+/******************** /proc/net/wireless SUPPORT ********************/
-+/*
-+ * The /proc/net/wireless file is a human readable user-space interface
-+ * exporting various wireless specific statistics from the wireless devices.
-+ * This is the most popular part of the Wireless Extensions ;-)
-+ *
-+ * This interface is a pure clone of /proc/net/dev (in net/core/dev.c).
-+ * The content of the file is basically the content of "struct iw_statistics".
-+ */
-+
-+#ifdef CONFIG_PROC_FS
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Print one entry (line) of /proc/net/wireless
-+ */
-+static inline int sprintf_wireless_stats(char *buffer, struct net_device *dev)
-+{
-+ /* Get stats from the driver */
-+ struct iw_statistics *stats;
-+ int size;
-+
-+ stats = get_wireless_stats(dev);
-+ if (stats != (struct iw_statistics *) NULL) {
-+ size = sprintf(buffer,
-+ "%6s: %04x %3d%c %3d%c %3d%c %6d %6d %6d %6d %6d %6d\n",
-+ dev->name,
-+ stats->status,
-+ stats->qual.qual,
-+ stats->qual.updated & 1 ? '.' : ' ',
-+ stats->qual.level,
-+ stats->qual.updated & 2 ? '.' : ' ',
-+ stats->qual.noise,
-+ stats->qual.updated & 4 ? '.' : ' ',
-+ stats->discard.nwid,
-+ stats->discard.code,
-+ stats->discard.fragment,
-+ stats->discard.retries,
-+ stats->discard.misc,
-+ stats->miss.beacon);
-+ stats->qual.updated = 0;
-+ }
-+ else
-+ size = 0;
-+
-+ return size;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Print info for /proc/net/wireless (print all entries)
-+ */
-+int dev_get_wireless_info(char * buffer, char **start, off_t offset,
-+ int length)
-+{
-+ int len = 0;
-+ off_t begin = 0;
-+ off_t pos = 0;
-+ int size;
-+
-+ struct net_device * dev;
-+
-+ size = sprintf(buffer,
-+ "Inter-| sta-| Quality | Discarded packets | Missed\n"
-+ " face | tus | link level noise | nwid crypt frag retry misc | beacon\n"
-+ );
-+
-+ pos += size;
-+ len += size;
-+
-+ read_lock(&dev_base_lock);
-+ for (dev = dev_base; dev != NULL; dev = dev->next) {
-+ size = sprintf_wireless_stats(buffer + len, dev);
-+ len += size;
-+ pos = begin + len;
-+
-+ if (pos < offset) {
-+ len = 0;
-+ begin = pos;
-+ }
-+ if (pos > offset + length)
-+ break;
-+ }
-+ read_unlock(&dev_base_lock);
-+
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ len -= (offset - begin); /* Start slop */
-+ if (len > length)
-+ len = length; /* Ending slop */
-+ if (len < 0)
-+ len = 0;
-+
-+ return len;
-+}
-+#endif /* CONFIG_PROC_FS */
-+
-+/************************** IOCTL SUPPORT **************************/
-+/*
-+ * The original user space API to configure all those Wireless Extensions
-+ * is through IOCTLs.
-+ * In there, we check if we need to call the new driver API (iw_handler)
-+ * or just call the driver ioctl handler.
-+ */
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Allow programatic access to /proc/net/wireless even if /proc
-+ * doesn't exist... Also more efficient...
-+ */
-+static inline int dev_iwstats(struct net_device *dev, struct ifreq *ifr)
-+{
-+ /* Get stats from the driver */
-+ struct iw_statistics *stats;
-+
-+ stats = get_wireless_stats(dev);
-+ if (stats != (struct iw_statistics *) NULL) {
-+ struct iwreq * wrq = (struct iwreq *)ifr;
-+
-+ /* Copy statistics to the user buffer */
-+ if(copy_to_user(wrq->u.data.pointer, stats,
-+ sizeof(struct iw_statistics)))
-+ return -EFAULT;
-+
-+ /* Check if we need to clear the update flag */
-+ if(wrq->u.data.flags != 0)
-+ stats->qual.updated = 0;
-+ return 0;
-+ } else
-+ return -EOPNOTSUPP;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Export the driver private handler definition
-+ * They will be picked up by tools like iwpriv...
-+ */
-+static inline int ioctl_export_private(struct net_device * dev,
-+ struct ifreq * ifr)
-+{
-+ struct iwreq * iwr = (struct iwreq *) ifr;
-+
-+ /* Check if the driver has something to export */
-+ if((dev->wireless_handlers->num_private_args == 0) ||
-+ (dev->wireless_handlers->private_args == NULL))
-+ return -EOPNOTSUPP;
-+
-+ /* Check NULL pointer */
-+ if(iwr->u.data.pointer == NULL)
-+ return -EFAULT;
-+#ifdef WE_STRICT_WRITE
-+ /* Check if there is enough buffer up there */
-+ if(iwr->u.data.length < (SIOCIWLASTPRIV - SIOCIWFIRSTPRIV + 1))
-+ return -E2BIG;
-+#endif /* WE_STRICT_WRITE */
-+
-+ /* Set the number of available ioctls. */
-+ iwr->u.data.length = dev->wireless_handlers->num_private_args;
-+
-+ /* Copy structure to the user buffer. */
-+ if (copy_to_user(iwr->u.data.pointer,
-+ dev->wireless_handlers->private_args,
-+ sizeof(struct iw_priv_args) * iwr->u.data.length))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Wrapper to call a standard Wireless Extension handler.
-+ * We do various checks and also take care of moving data between
-+ * user space and kernel space.
-+ */
-+static inline int ioctl_standard_call(struct net_device * dev,
-+ struct ifreq * ifr,
-+ unsigned int cmd,
-+ iw_handler handler)
-+{
-+ struct iwreq * iwr = (struct iwreq *) ifr;
-+ const struct iw_ioctl_description * descr;
-+ struct iw_request_info info;
-+ int ret = -EINVAL;
-+
-+ /* Get the description of the IOCTL */
-+ descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
-+
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "%s : Found standard handler for 0x%04X\n",
-+ ifr->ifr_name, cmd);
-+ printk(KERN_DEBUG "Header type : %d, token type : %d, token_size : %d, max_token : %d\n", descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
-+#endif /* WE_IOCTL_DEBUG */
-+
-+ /* Prepare the call */
-+ info.cmd = cmd;
-+ info.flags = 0;
-+
-+ /* Check if we have a pointer to user space data or not */
-+ if(descr->header_type != IW_HEADER_TYPE_POINT) {
-+ /* No extra arguments. Trivial to handle */
-+ ret = handler(dev, &info, &(iwr->u), NULL);
-+ } else {
-+ char * extra;
-+ int err;
-+
-+ /* Check what user space is giving us */
-+ if(IW_IS_SET(cmd)) {
-+ /* Check NULL pointer */
-+ if((iwr->u.data.pointer == NULL) &&
-+ (iwr->u.data.length != 0))
-+ return -EFAULT;
-+ /* Check if number of token fits within bounds */
-+ if(iwr->u.data.length > descr->max_tokens)
-+ return -E2BIG;
-+ if(iwr->u.data.length < descr->min_tokens)
-+ return -EINVAL;
-+ } else {
-+ /* Check NULL pointer */
-+ if(iwr->u.data.pointer == NULL)
-+ return -EFAULT;
-+#ifdef WE_STRICT_WRITE
-+ /* Check if there is enough buffer up there */
-+ if(iwr->u.data.length < descr->max_tokens)
-+ return -E2BIG;
-+#endif /* WE_STRICT_WRITE */
-+ }
-+
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Malloc %d bytes\n",
-+ descr->max_tokens * descr->token_size);
-+#endif /* WE_IOCTL_DEBUG */
-+
-+ /* Always allocate for max space. Easier, and won't last
-+ * long... */
-+ extra = kmalloc(descr->max_tokens * descr->token_size,
-+ GFP_KERNEL);
-+ if (extra == NULL) {
-+ return -ENOMEM;
-+ }
-+
-+ /* If it is a SET, get all the extra data in here */
-+ if(IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
-+ err = copy_from_user(extra, iwr->u.data.pointer,
-+ iwr->u.data.length *
-+ descr->token_size);
-+ if (err) {
-+ kfree(extra);
-+ return -EFAULT;
-+ }
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Got %d bytes\n",
-+ iwr->u.data.length * descr->token_size);
-+#endif /* WE_IOCTL_DEBUG */
-+ }
-+
-+ /* Call the handler */
-+ ret = handler(dev, &info, &(iwr->u), extra);
-+
-+ /* If we have something to return to the user */
-+ if (!ret && IW_IS_GET(cmd)) {
-+ err = copy_to_user(iwr->u.data.pointer, extra,
-+ iwr->u.data.length *
-+ descr->token_size);
-+ if (err)
-+ ret = -EFAULT;
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Wrote %d bytes\n",
-+ iwr->u.data.length * descr->token_size);
-+#endif /* WE_IOCTL_DEBUG */
-+ }
-+
-+ /* Cleanup - I told you it wasn't that long ;-) */
-+ kfree(extra);
-+ }
-+
-+ /* Call commit handler if needed and defined */
-+ if(ret == -EIWCOMMIT)
-+ ret = call_commit_handler(dev);
-+
-+ /* Here, we will generate the appropriate event if needed */
-+
-+ return ret;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Wrapper to call a private Wireless Extension handler.
-+ * We do various checks and also take care of moving data between
-+ * user space and kernel space.
-+ * It's not as nice and slimline as the standard wrapper. The cause
-+ * is struct iw_priv_args, which was not really designed for the
-+ * job we are going here.
-+ *
-+ * IMPORTANT : This function prevent to set and get data on the same
-+ * IOCTL and enforce the SET/GET convention. Not doing it would be
-+ * far too hairy...
-+ * If you need to set and get data at the same time, please don't use
-+ * a iw_handler but process it in your ioctl handler (i.e. use the
-+ * old driver API).
-+ */
-+static inline int ioctl_private_call(struct net_device * dev,
-+ struct ifreq * ifr,
-+ unsigned int cmd,
-+ iw_handler handler)
-+{
-+ struct iwreq * iwr = (struct iwreq *) ifr;
-+ struct iw_priv_args * descr = NULL;
-+ struct iw_request_info info;
-+ int extra_size = 0;
-+ int i;
-+ int ret = -EINVAL;
-+
-+ /* Get the description of the IOCTL */
-+ for(i = 0; i < dev->wireless_handlers->num_private_args; i++)
-+ if(cmd == dev->wireless_handlers->private_args[i].cmd) {
-+ descr = &(dev->wireless_handlers->private_args[i]);
-+ break;
-+ }
-+
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "%s : Found private handler for 0x%04X\n",
-+ ifr->ifr_name, cmd);
-+ if(descr) {
-+ printk(KERN_DEBUG "Name %s, set %X, get %X\n",
-+ descr->name, descr->set_args, descr->get_args);
-+ }
-+#endif /* WE_IOCTL_DEBUG */
-+
-+ /* Compute the size of the set/get arguments */
-+ if(descr != NULL) {
-+ if(IW_IS_SET(cmd)) {
-+ /* Size of set arguments */
-+ extra_size = get_priv_size(descr->set_args);
-+
-+ /* Does it fits in iwr ? */
-+ if((descr->set_args & IW_PRIV_SIZE_FIXED) &&
-+ (extra_size < IFNAMSIZ))
-+ extra_size = 0;
-+ } else {
-+ /* Size of set arguments */
-+ extra_size = get_priv_size(descr->get_args);
-+
-+ /* Does it fits in iwr ? */
-+ if((descr->get_args & IW_PRIV_SIZE_FIXED) &&
-+ (extra_size < IFNAMSIZ))
-+ extra_size = 0;
-+ }
-+ }
-+
-+ /* Prepare the call */
-+ info.cmd = cmd;
-+ info.flags = 0;
-+
-+ /* Check if we have a pointer to user space data or not. */
-+ if(extra_size == 0) {
-+ /* No extra arguments. Trivial to handle */
-+ ret = handler(dev, &info, &(iwr->u), (char *) &(iwr->u));
-+ } else {
-+ char * extra;
-+ int err;
-+
-+ /* Check what user space is giving us */
-+ if(IW_IS_SET(cmd)) {
-+ /* Check NULL pointer */
-+ if((iwr->u.data.pointer == NULL) &&
-+ (iwr->u.data.length != 0))
-+ return -EFAULT;
-+
-+ /* Does it fits within bounds ? */
-+ if(iwr->u.data.length > (descr->set_args &
-+ IW_PRIV_SIZE_MASK))
-+ return -E2BIG;
-+ } else {
-+ /* Check NULL pointer */
-+ if(iwr->u.data.pointer == NULL)
-+ return -EFAULT;
-+ }
-+
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Malloc %d bytes\n", extra_size);
-+#endif /* WE_IOCTL_DEBUG */
-+
-+ /* Always allocate for max space. Easier, and won't last
-+ * long... */
-+ extra = kmalloc(extra_size, GFP_KERNEL);
-+ if (extra == NULL) {
-+ return -ENOMEM;
-+ }
-+
-+ /* If it is a SET, get all the extra data in here */
-+ if(IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
-+ err = copy_from_user(extra, iwr->u.data.pointer,
-+ extra_size);
-+ if (err) {
-+ kfree(extra);
-+ return -EFAULT;
-+ }
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Got %d elem\n", iwr->u.data.length);
-+#endif /* WE_IOCTL_DEBUG */
-+ }
-+
-+ /* Call the handler */
-+ ret = handler(dev, &info, &(iwr->u), extra);
-+
-+ /* If we have something to return to the user */
-+ if (!ret && IW_IS_GET(cmd)) {
-+ err = copy_to_user(iwr->u.data.pointer, extra,
-+ extra_size);
-+ if (err)
-+ ret = -EFAULT;
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Wrote %d elem\n",
-+ iwr->u.data.length);
-+#endif /* WE_IOCTL_DEBUG */
-+ }
-+
-+ /* Cleanup - I told you it wasn't that long ;-) */
-+ kfree(extra);
-+ }
-+
-+
-+ /* Call commit handler if needed and defined */
-+ if(ret == -EIWCOMMIT)
-+ ret = call_commit_handler(dev);
-+
-+ return ret;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Main IOCTl dispatcher. Called from the main networking code
-+ * (dev_ioctl() in net/core/dev.c).
-+ * Check the type of IOCTL and call the appropriate wrapper...
-+ */
-+int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd)
-+{
-+ struct net_device *dev;
-+ iw_handler handler;
-+
-+ /* Permissions are already checked in dev_ioctl() before calling us.
-+ * The copy_to/from_user() of ifr is also dealt with in there */
-+
-+ /* Make sure the device exist */
-+ if ((dev = __dev_get_by_name(ifr->ifr_name)) == NULL)
-+ return -ENODEV;
-+
-+ /* A bunch of special cases, then the generic case...
-+ * Note that 'cmd' is already filtered in dev_ioctl() with
-+ * (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) */
-+ switch(cmd)
-+ {
-+ case SIOCGIWSTATS:
-+ /* Get Wireless Stats */
-+ return dev_iwstats(dev, ifr);
-+
-+ case SIOCGIWPRIV:
-+ /* Check if we have some wireless handlers defined */
-+ if(dev->wireless_handlers != NULL) {
-+ /* We export to user space the definition of
-+ * the private handler ourselves */
-+ return ioctl_export_private(dev, ifr);
-+ }
-+ // ## Fall-through for old API ##
-+ default:
-+ /* Generic IOCTL */
-+ /* Basic check */
-+ if (!netif_device_present(dev))
-+ return -ENODEV;
-+ /* New driver API : try to find the handler */
-+ handler = get_handler(dev, cmd);
-+ if(handler != NULL) {
-+ /* Standard and private are not the same */
-+ if(cmd < SIOCIWFIRSTPRIV)
-+ return ioctl_standard_call(dev,
-+ ifr,
-+ cmd,
-+ handler);
-+ else
-+ return ioctl_private_call(dev,
-+ ifr,
-+ cmd,
-+ handler);
-+ }
-+ /* Old driver API : call driver ioctl handler */
-+ if (dev->do_ioctl) {
-+ return dev->do_ioctl(dev, ifr, cmd);
-+ }
-+ return -EOPNOTSUPP;
-+ }
-+ /* Not reached */
-+ return -EINVAL;
-+}
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/iw_handlers.w14-5.diff b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/iw_handlers.w14-5.diff
deleted file mode 100644
index 539b160068..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/iw_handlers.w14-5.diff
+++ /dev/null
@@ -1,838 +0,0 @@
-diff -u -p -r --new-file linux/include/linux-w13/rtnetlink.h linux/include/linux/rtnetlink.h
---- linux/include/linux-w13/rtnetlink.h Thu Jun 6 14:44:08 2002
-+++ linux/include/linux/rtnetlink.h Thu Jun 6 15:47:44 2002
-@@ -440,12 +440,14 @@ enum
- #define IFLA_COST IFLA_COST
- IFLA_PRIORITY,
- #define IFLA_PRIORITY IFLA_PRIORITY
-- IFLA_MASTER
-+ IFLA_MASTER,
- #define IFLA_MASTER IFLA_MASTER
-+ IFLA_WIRELESS, /* Wireless Extension event - see wireless.h */
-+#define IFLA_WIRELESS IFLA_WIRELESS
- };
-
-
--#define IFLA_MAX IFLA_MASTER
-+#define IFLA_MAX IFLA_WIRELESS
-
- #define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
- #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
-diff -u -p -r --new-file linux/include/linux-w13/wireless.h linux/include/linux/wireless.h
---- linux/include/linux-w13/wireless.h Thu Jun 6 15:00:28 2002
-+++ linux/include/linux/wireless.h Thu Jun 6 15:47:44 2002
-@@ -1,10 +1,10 @@
- /*
- * This file define a set of standard wireless extensions
- *
-- * Version : 13 6.12.01
-+ * Version : 14 25.1.02
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-- * Copyright (c) 1997-2001 Jean Tourrilhes, All Rights Reserved.
-+ * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
- */
-
- #ifndef _LINUX_WIRELESS_H
-@@ -40,7 +40,7 @@
- * # include/linux/netdevice.h (one place)
- * # include/linux/proc_fs.h (one place)
- *
-- * New driver API (2001 -> onward) :
-+ * New driver API (2002 -> onward) :
- * -------------------------------
- * This file is only concerned with the user space API and common definitions.
- * The new driver API is defined and documented in :
-@@ -49,6 +49,11 @@
- * Note as well that /proc/net/wireless implementation has now moved in :
- * # include/linux/wireless.c
- *
-+ * Wireless Events (2002 -> onward) :
-+ * --------------------------------
-+ * Events are defined at the end of this file, and implemented in :
-+ * # include/linux/wireless.c
-+ *
- * Other comments :
- * --------------
- * Do not add here things that are redundant with other mechanisms
-@@ -75,7 +80,7 @@
- * (there is some stuff that will be added in the future...)
- * I just plan to increment with each new version.
- */
--#define WIRELESS_EXT 13
-+#define WIRELESS_EXT 14
-
- /*
- * Changes :
-@@ -141,6 +146,13 @@
- * - Document creation of new driver API.
- * - Extract union iwreq_data from struct iwreq (for new driver API).
- * - Rename SIOCSIWNAME as SIOCSIWCOMMIT
-+ *
-+ * V13 to V14
-+ * ----------
-+ * - Wireless Events support : define struct iw_event
-+ * - Define additional specific event numbers
-+ * - Add "addr" and "param" fields in union iwreq_data
-+ * - AP scanning stuff (SIOCSIWSCAN and friends)
- */
-
- /**************************** CONSTANTS ****************************/
-@@ -175,6 +187,8 @@
- #define SIOCSIWAP 0x8B14 /* set access point MAC addresses */
- #define SIOCGIWAP 0x8B15 /* get access point MAC addresses */
- #define SIOCGIWAPLIST 0x8B17 /* get list of access point in range */
-+#define SIOCSIWSCAN 0x8B18 /* trigger scanning */
-+#define SIOCGIWSCAN 0x8B19 /* get scanning results */
-
- /* 802.11 specific support */
- #define SIOCSIWESSID 0x8B1A /* set ESSID (network name) */
-@@ -238,6 +252,15 @@
- #define IW_IS_SET(cmd) (!((cmd) & 0x1))
- #define IW_IS_GET(cmd) ((cmd) & 0x1)
-
-+/* ----------------------- WIRELESS EVENTS ----------------------- */
-+/* Those are *NOT* ioctls, do not issue request on them !!! */
-+/* Most events use the same identifier as ioctl requests */
-+
-+#define IWEVTXDROP 0x8C00 /* Packet dropped to excessive retry */
-+#define IWEVQUAL 0x8C01 /* Quality part of statistics */
-+
-+#define IWEVFIRST 0x8C00
-+
- /* ------------------------- PRIVATE INFO ------------------------- */
- /*
- * The following is used with SIOCGIWPRIV. It allow a driver to define
-@@ -340,6 +363,19 @@
- #define IW_RETRY_MAX 0x0002 /* Value is a maximum */
- #define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
-
-+/* Scanning request flags */
-+#define IW_SCAN_DEFAULT 0x0000 /* Default scan of the driver */
-+#define IW_SCAN_ALL_ESSID 0x0001 /* Scan all ESSIDs */
-+#define IW_SCAN_THIS_ESSID 0x0002 /* Scan only this ESSID */
-+#define IW_SCAN_ALL_FREQ 0x0004 /* Scan all Frequencies */
-+#define IW_SCAN_THIS_FREQ 0x0008 /* Scan only this Frequency */
-+#define IW_SCAN_ALL_MODE 0x0010 /* Scan all Modes */
-+#define IW_SCAN_THIS_MODE 0x0020 /* Scan only this Mode */
-+#define IW_SCAN_ALL_RATE 0x0040 /* Scan all Bit-Rates */
-+#define IW_SCAN_THIS_RATE 0x0080 /* Scan only this Bit-Rate */
-+/* Maximum size of returned data */
-+#define IW_SCAN_MAX_DATA 4096 /* In bytes */
-+
- /****************************** TYPES ******************************/
-
- /* --------------------------- SUBTYPES --------------------------- */
-@@ -466,9 +502,12 @@ union iwreq_data
-
- struct iw_point encoding; /* Encoding stuff : tokens */
- struct iw_param power; /* PM duration/timeout */
-+ struct iw_quality qual; /* Quality part of statistics */
-
- struct sockaddr ap_addr; /* Access point address */
-+ struct sockaddr addr; /* Destination address (hw) */
-
-+ struct iw_param param; /* Other small parameters */
- struct iw_point data; /* Other large parameters */
- };
-
-@@ -595,5 +634,36 @@ struct iw_priv_args
- __u16 get_args; /* Type and number of args */
- char name[IFNAMSIZ]; /* Name of the extension */
- };
-+
-+/* ----------------------- WIRELESS EVENTS ----------------------- */
-+/*
-+ * Wireless events are carried through the rtnetlink socket to user
-+ * space. They are encapsulated in the IFLA_WIRELESS field of
-+ * a RTM_NEWLINK message.
-+ */
-+
-+/*
-+ * A Wireless Event. Contains basically the same data as the ioctl...
-+ */
-+struct iw_event
-+{
-+ __u16 len; /* Real lenght of this stuff */
-+ __u16 cmd; /* Wireless IOCTL */
-+ union iwreq_data u; /* IOCTL fixed payload */
-+};
-+
-+/* Size of the Event prefix (including padding and alignement junk) */
-+#define IW_EV_LCP_LEN (sizeof(struct iw_event) - sizeof(union iwreq_data))
-+/* Size of the various events */
-+#define IW_EV_CHAR_LEN (IW_EV_LCP_LEN + IFNAMSIZ)
-+#define IW_EV_UINT_LEN (IW_EV_LCP_LEN + sizeof(__u32))
-+#define IW_EV_FREQ_LEN (IW_EV_LCP_LEN + sizeof(struct iw_freq))
-+#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point))
-+#define IW_EV_PARAM_LEN (IW_EV_LCP_LEN + sizeof(struct iw_param))
-+#define IW_EV_ADDR_LEN (IW_EV_LCP_LEN + sizeof(struct sockaddr))
-+#define IW_EV_QUAL_LEN (IW_EV_LCP_LEN + sizeof(struct iw_quality))
-+
-+/* Note : in the case of iw_point, the extra data will come at the
-+ * end of the event */
-
- #endif /* _LINUX_WIRELESS_H */
-diff -u -p -r --new-file linux/include/net-w13/iw_handler.h linux/include/net/iw_handler.h
---- linux/include/net-w13/iw_handler.h Thu Jun 6 15:06:16 2002
-+++ linux/include/net/iw_handler.h Thu Jun 6 15:48:06 2002
-@@ -1,10 +1,10 @@
- /*
- * This file define the new driver API for Wireless Extensions
- *
-- * Version : 2 6.12.01
-+ * Version : 3 17.1.02
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-- * Copyright (c) 2001 Jean Tourrilhes, All Rights Reserved.
-+ * Copyright (c) 2001-2002 Jean Tourrilhes, All Rights Reserved.
- */
-
- #ifndef _IW_HANDLER_H
-@@ -33,7 +33,7 @@
- * o The user space interface is tied to ioctl because of the use
- * copy_to/from_user.
- *
-- * New driver API (2001 -> onward) :
-+ * New driver API (2002 -> onward) :
- * -------------------------------
- * The new driver API is just a bunch of standard functions (handlers),
- * each handling a specific Wireless Extension. The driver just export
-@@ -206,7 +206,18 @@
- * will be needed...
- * I just plan to increment with each new version.
- */
--#define IW_HANDLER_VERSION 2
-+#define IW_HANDLER_VERSION 3
-+
-+/*
-+ * Changes :
-+ *
-+ * V2 to V3
-+ * --------
-+ * - Move event definition in <linux/wireless.h>
-+ * - Add Wireless Event support :
-+ * o wireless_send_event() prototype
-+ * o iwe_stream_add_event/point() inline functions
-+ */
-
- /**************************** CONSTANTS ****************************/
-
-@@ -225,6 +236,7 @@
- #define IW_HEADER_TYPE_POINT 6 /* struct iw_point */
- #define IW_HEADER_TYPE_PARAM 7 /* struct iw_param */
- #define IW_HEADER_TYPE_ADDR 8 /* struct sockaddr */
-+#define IW_HEADER_TYPE_QUAL 9 /* struct iw_quality */
-
- /* Handling flags */
- /* Most are not implemented. I just use them as a reminder of some
-@@ -233,7 +245,8 @@
- /* Wrapper level flags */
- #define IW_DESCR_FLAG_DUMP 0x0001 /* Not part of the dump command */
- #define IW_DESCR_FLAG_EVENT 0x0002 /* Generate an event on SET */
--#define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET request is ROOT only */
-+#define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET : request is ROOT only */
-+ /* SET : Omit payload from generated iwevent */
- /* Driver level flags */
- #define IW_DESCR_FLAG_WAIT 0x0100 /* Wait for driver event */
-
-@@ -303,25 +316,6 @@ struct iw_handler_def
- * 'struct net_device' to here, to minimise bloat. */
- };
-
--/* ----------------------- WIRELESS EVENTS ----------------------- */
--/*
-- * Currently we don't support events, so let's just plan for the
-- * future...
-- */
--
--/*
-- * A Wireless Event.
-- */
--// How do we define short header ? We don't want a flag on length.
--// Probably a flag on event ? Highest bit to zero...
--struct iw_event
--{
-- __u16 length; /* Lenght of this stuff */
-- __u16 event; /* Wireless IOCTL */
-- union iwreq_data header; /* IOCTL fixed payload */
-- char extra[0]; /* Optional IOCTL data */
--};
--
- /* ---------------------- IOCTL DESCRIPTION ---------------------- */
- /*
- * One of the main goal of the new interface is to deal entirely with
-@@ -369,6 +363,88 @@ extern int dev_get_wireless_info(char *
- extern int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd);
-
- /* Second : functions that may be called by driver modules */
--/* None yet */
-
--#endif /* _LINUX_WIRELESS_H */
-+/* Send a single event to user space */
-+extern void wireless_send_event(struct net_device * dev,
-+ unsigned int cmd,
-+ union iwreq_data * wrqu,
-+ char * extra);
-+
-+/* We may need a function to send a stream of events to user space.
-+ * More on that later... */
-+
-+/************************* INLINE FUNTIONS *************************/
-+/*
-+ * Function that are so simple that it's more efficient inlining them
-+ */
-+
-+/*------------------------------------------------------------------*/
-+/*
-+ * Wrapper to add an Wireless Event to a stream of events.
-+ */
-+static inline char *
-+iwe_stream_add_event(char * stream, /* Stream of events */
-+ char * ends, /* End of stream */
-+ struct iw_event *iwe, /* Payload */
-+ int event_len) /* Real size of payload */
-+{
-+ /* Check if it's possible */
-+ if((stream + event_len) < ends) {
-+ iwe->len = event_len;
-+ memcpy(stream, (char *) iwe, event_len);
-+ stream += event_len;
-+ }
-+ return stream;
-+}
-+
-+/*------------------------------------------------------------------*/
-+/*
-+ * Wrapper to add an short Wireless Event containing a pointer to a
-+ * stream of events.
-+ */
-+static inline char *
-+iwe_stream_add_point(char * stream, /* Stream of events */
-+ char * ends, /* End of stream */
-+ struct iw_event *iwe, /* Payload */
-+ char * extra)
-+{
-+ int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
-+ /* Check if it's possible */
-+ if((stream + event_len) < ends) {
-+ iwe->len = event_len;
-+ memcpy(stream, (char *) iwe, IW_EV_POINT_LEN);
-+ memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
-+ stream += event_len;
-+ }
-+ return stream;
-+}
-+
-+/*------------------------------------------------------------------*/
-+/*
-+ * Wrapper to add a value to a Wireless Event in a stream of events.
-+ * Be careful, this one is tricky to use properly :
-+ * At the first run, you need to have (value = event + IW_EV_LCP_LEN).
-+ */
-+static inline char *
-+iwe_stream_add_value(char * event, /* Event in the stream */
-+ char * value, /* Value in event */
-+ char * ends, /* End of stream */
-+ struct iw_event *iwe, /* Payload */
-+ int event_len) /* Real size of payload */
-+{
-+ /* Don't duplicate LCP */
-+ event_len -= IW_EV_LCP_LEN;
-+
-+ /* Check if it's possible */
-+ if((value + event_len) < ends) {
-+ /* Add new value */
-+ memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
-+ value += event_len;
-+ /* Patch LCP */
-+ iwe->len = value - event;
-+ memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
-+ }
-+ return value;
-+}
-+
-+#endif /* _IW_HANDLER_H */
-diff -u -p -r --new-file linux/net/netsyms-w13.c linux/net/netsyms.c
---- linux/net/netsyms-w13.c Thu Jun 6 15:46:34 2002
-+++ linux/net/netsyms.c Thu Jun 6 15:47:44 2002
-@@ -588,4 +588,10 @@ EXPORT_SYMBOL(register_gifconf);
- EXPORT_SYMBOL(net_call_rx_atomic);
- EXPORT_SYMBOL(softnet_data);
-
-+#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
-+/* Don't include the whole header mess for a single function */
-+extern void wireless_send_event(struct net_device *dev, unsigned int cmd, union iwreq_data *wrqu, char *extra);
-+EXPORT_SYMBOL(wireless_send_event);
-+#endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
-+
- #endif /* CONFIG_NET */
-diff -u -p -r --new-file linux/net/core/wireless-w13.c linux/net/core/wireless.c
---- linux/net/core/wireless-w13.c Thu Jun 6 15:46:45 2002
-+++ linux/net/core/wireless.c Thu Jun 6 15:48:06 2002
-@@ -2,7 +2,7 @@
- * This file implement the Wireless Extensions APIs.
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-- * Copyright (c) 1997-2001 Jean Tourrilhes, All Rights Reserved.
-+ * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
- *
- * (As all part of the Linux kernel, this file is GPL)
- */
-@@ -25,6 +25,16 @@
- * o Added iw_handler handling ;-)
- * o Added standard ioctl description
- * o Initial dumb commit strategy based on orinoco.c
-+ *
-+ * v3 - 19.12.01 - Jean II
-+ * o Make sure we don't go out of standard_ioctl[] in ioctl_standard_call
-+ * o Add event dispatcher function
-+ * o Add event description
-+ * o Propagate events as rtnetlink IFLA_WIRELESS option
-+ * o Generate event on selected SET requests
-+ *
-+ * v4 - 18.04.01 - Jean II
-+ * o Fix stupid off by one in iw_ioctl_description : IW_ESSID_MAX_SIZE + 1
- */
-
- /***************************** INCLUDES *****************************/
-@@ -33,6 +43,7 @@
- #include <linux/config.h> /* Not needed ??? */
- #include <linux/types.h> /* off_t */
- #include <linux/netdevice.h> /* struct ifreq, dev_get_by_name() */
-+#include <linux/rtnetlink.h> /* rtnetlink stuff */
-
- #include <linux/wireless.h> /* Pretty obvious */
- #include <net/iw_handler.h> /* New driver API */
-@@ -44,14 +55,23 @@
-
- /* Debuging stuff */
- #undef WE_IOCTL_DEBUG /* Debug IOCTL API */
-+#undef WE_EVENT_DEBUG /* Debug Event dispatcher */
-+
-+/* Options */
-+#define WE_EVENT_NETLINK /* Propagate events using rtnetlink */
-+#define WE_SET_EVENT /* Generate an event on some set commands */
-
- /************************* GLOBAL VARIABLES *************************/
- /*
- * You should not use global variables, because or re-entrancy.
- * On our case, it's only const, so it's OK...
- */
-+/*
-+ * Meta-data about all the standard Wireless Extension request we
-+ * know about.
-+ */
- static const struct iw_ioctl_description standard_ioctl[] = {
-- /* SIOCSIWCOMMIT (internal) */
-+ /* SIOCSIWCOMMIT */
- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
- /* SIOCGIWNAME */
- { IW_HEADER_TYPE_CHAR, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-@@ -99,18 +119,18 @@ static const struct iw_ioctl_description
- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
- /* SIOCGIWAPLIST */
- { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_AP, 0},
-- /* -- hole -- */
-- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-- /* -- hole -- */
-- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCSIWSCAN */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWSCAN */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_SCAN_MAX_DATA, 0},
- /* SIOCSIWESSID */
-- { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, IW_DESCR_FLAG_EVENT},
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, IW_DESCR_FLAG_EVENT},
- /* SIOCGIWESSID */
-- { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, IW_DESCR_FLAG_DUMP},
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, IW_DESCR_FLAG_DUMP},
- /* SIOCSIWNICKN */
-- { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, 0},
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, 0},
- /* SIOCGIWNICKN */
-- { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, 0},
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, 0},
- /* -- hole -- */
- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
- /* -- hole -- */
-@@ -136,7 +156,7 @@ static const struct iw_ioctl_description
- /* SIOCGIWRETRY */
- { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
- /* SIOCSIWENCODE */
-- { IW_HEADER_TYPE_POINT, 4, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT},
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT},
- /* SIOCGIWENCODE */
- { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_DUMP | IW_DESCR_FLAG_RESTRICT},
- /* SIOCSIWPOWER */
-@@ -144,9 +164,38 @@ static const struct iw_ioctl_description
- /* SIOCGIWPOWER */
- { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
- };
-+static const int standard_ioctl_num = (sizeof(standard_ioctl) /
-+ sizeof(struct iw_ioctl_description));
-+
-+/*
-+ * Meta-data about all the additional standard Wireless Extension events
-+ * we know about.
-+ */
-+static const struct iw_ioctl_description standard_event[] = {
-+ /* IWEVTXDROP */
-+ { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
-+ /* IWEVQUAL */
-+ { IW_HEADER_TYPE_QUAL, 0, 0, 0, 0, 0},
-+};
-+static const int standard_event_num = (sizeof(standard_event) /
-+ sizeof(struct iw_ioctl_description));
-
- /* Size (in bytes) of the various private data types */
--char priv_type_size[] = { 0, 1, 1, 0, 4, 4, 0, 0 };
-+static const char priv_type_size[] = { 0, 1, 1, 0, 4, 4, 0, 0 };
-+
-+/* Size (in bytes) of various events */
-+static const int event_type_size[] = {
-+ IW_EV_LCP_LEN,
-+ 0,
-+ IW_EV_CHAR_LEN,
-+ 0,
-+ IW_EV_UINT_LEN,
-+ IW_EV_FREQ_LEN,
-+ IW_EV_POINT_LEN, /* Without variable payload */
-+ IW_EV_PARAM_LEN,
-+ IW_EV_ADDR_LEN,
-+ IW_EV_QUAL_LEN,
-+};
-
- /************************ COMMON SUBROUTINES ************************/
- /*
-@@ -162,7 +211,8 @@ char priv_type_size[] = { 0, 1, 1, 0, 4,
- static inline iw_handler get_handler(struct net_device *dev,
- unsigned int cmd)
- {
-- unsigned int index; /* MUST be unsigned */
-+ /* Don't "optimise" the following variable, it will crash */
-+ unsigned int index; /* *MUST* be unsigned */
-
- /* Check if we have some wireless handlers defined */
- if(dev->wireless_handlers == NULL)
-@@ -269,9 +319,9 @@ static inline int sprintf_wireless_stats
- stats->status,
- stats->qual.qual,
- stats->qual.updated & 1 ? '.' : ' ',
-- stats->qual.level,
-+ ((__u8) stats->qual.level),
- stats->qual.updated & 2 ? '.' : ' ',
-- stats->qual.noise,
-+ ((__u8) stats->qual.noise),
- stats->qual.updated & 4 ? '.' : ' ',
- stats->discard.nwid,
- stats->discard.code,
-@@ -423,12 +473,14 @@ static inline int ioctl_standard_call(st
- int ret = -EINVAL;
-
- /* Get the description of the IOCTL */
-+ if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
-+ return -EOPNOTSUPP;
- descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
-
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "%s : Found standard handler for 0x%04X\n",
-+ printk(KERN_DEBUG "%s (WE) : Found standard handler for 0x%04X\n",
- ifr->ifr_name, cmd);
-- printk(KERN_DEBUG "Header type : %d, token type : %d, token_size : %d, max_token : %d\n", descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
-+ printk(KERN_DEBUG "%s (WE) : Header type : %d, Token type : %d, size : %d, token : %d\n", dev->name, descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
- #endif /* WE_IOCTL_DEBUG */
-
- /* Prepare the call */
-@@ -437,8 +489,16 @@ static inline int ioctl_standard_call(st
-
- /* Check if we have a pointer to user space data or not */
- if(descr->header_type != IW_HEADER_TYPE_POINT) {
-+
- /* No extra arguments. Trivial to handle */
- ret = handler(dev, &info, &(iwr->u), NULL);
-+
-+#ifdef WE_SET_EVENT
-+ /* Generate an event to notify listeners of the change */
-+ if((descr->flags & IW_DESCR_FLAG_EVENT) &&
-+ ((ret == 0) || (ret == -EIWCOMMIT)))
-+ wireless_send_event(dev, cmd, &(iwr->u), NULL);
-+#endif /* WE_SET_EVENT */
- } else {
- char * extra;
- int err;
-@@ -466,8 +526,8 @@ static inline int ioctl_standard_call(st
- }
-
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Malloc %d bytes\n",
-- descr->max_tokens * descr->token_size);
-+ printk(KERN_DEBUG "%s (WE) : Malloc %d bytes\n",
-+ dev->name, descr->max_tokens * descr->token_size);
- #endif /* WE_IOCTL_DEBUG */
-
- /* Always allocate for max space. Easier, and won't last
-@@ -488,7 +548,8 @@ static inline int ioctl_standard_call(st
- return -EFAULT;
- }
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Got %d bytes\n",
-+ printk(KERN_DEBUG "%s (WE) : Got %d bytes\n",
-+ dev->name,
- iwr->u.data.length * descr->token_size);
- #endif /* WE_IOCTL_DEBUG */
- }
-@@ -504,11 +565,26 @@ static inline int ioctl_standard_call(st
- if (err)
- ret = -EFAULT;
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Wrote %d bytes\n",
-+ printk(KERN_DEBUG "%s (WE) : Wrote %d bytes\n",
-+ dev->name,
- iwr->u.data.length * descr->token_size);
- #endif /* WE_IOCTL_DEBUG */
- }
-
-+#ifdef WE_SET_EVENT
-+ /* Generate an event to notify listeners of the change */
-+ if((descr->flags & IW_DESCR_FLAG_EVENT) &&
-+ ((ret == 0) || (ret == -EIWCOMMIT))) {
-+ if(descr->flags & IW_DESCR_FLAG_RESTRICT)
-+ /* If the event is restricted, don't
-+ * export the payload */
-+ wireless_send_event(dev, cmd, &(iwr->u), NULL);
-+ else
-+ wireless_send_event(dev, cmd, &(iwr->u),
-+ extra);
-+ }
-+#endif /* WE_SET_EVENT */
-+
- /* Cleanup - I told you it wasn't that long ;-) */
- kfree(extra);
- }
-@@ -558,11 +634,12 @@ static inline int ioctl_private_call(str
- }
-
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "%s : Found private handler for 0x%04X\n",
-+ printk(KERN_DEBUG "%s (WE) : Found private handler for 0x%04X\n",
- ifr->ifr_name, cmd);
- if(descr) {
-- printk(KERN_DEBUG "Name %s, set %X, get %X\n",
-- descr->name, descr->set_args, descr->get_args);
-+ printk(KERN_DEBUG "%s (WE) : Name %s, set %X, get %X\n",
-+ dev->name, descr->name,
-+ descr->set_args, descr->get_args);
- }
- #endif /* WE_IOCTL_DEBUG */
-
-@@ -617,7 +694,8 @@ static inline int ioctl_private_call(str
- }
-
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Malloc %d bytes\n", extra_size);
-+ printk(KERN_DEBUG "%s (WE) : Malloc %d bytes\n",
-+ dev->name, extra_size);
- #endif /* WE_IOCTL_DEBUG */
-
- /* Always allocate for max space. Easier, and won't last
-@@ -636,7 +714,8 @@ static inline int ioctl_private_call(str
- return -EFAULT;
- }
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Got %d elem\n", iwr->u.data.length);
-+ printk(KERN_DEBUG "%s (WE) : Got %d elem\n",
-+ dev->name, iwr->u.data.length);
- #endif /* WE_IOCTL_DEBUG */
- }
-
-@@ -650,8 +729,8 @@ static inline int ioctl_private_call(str
- if (err)
- ret = -EFAULT;
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Wrote %d elem\n",
-- iwr->u.data.length);
-+ printk(KERN_DEBUG "%s (WE) : Wrote %d elem\n",
-+ dev->name, iwr->u.data.length);
- #endif /* WE_IOCTL_DEBUG */
- }
-
-@@ -730,4 +809,178 @@ int wireless_process_ioctl(struct ifreq
- }
- /* Not reached */
- return -EINVAL;
-+}
-+
-+/************************* EVENT PROCESSING *************************/
-+/*
-+ * Process events generated by the wireless layer or the driver.
-+ * Most often, the event will be propagated through rtnetlink
-+ */
-+
-+#ifdef WE_EVENT_NETLINK
-+/* "rtnl" is defined in net/core/rtnetlink.c, but we need it here.
-+ * It is declared in <linux/rtnetlink.h> */
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Fill a rtnetlink message with our event data.
-+ * Note that we propage only the specified event and don't dump the
-+ * current wireless config. Dumping the wireless config is far too
-+ * expensive (for each parameter, the driver need to query the hardware).
-+ */
-+static inline int rtnetlink_fill_iwinfo(struct sk_buff * skb,
-+ struct net_device * dev,
-+ int type,
-+ char * event,
-+ int event_len)
-+{
-+ struct ifinfomsg *r;
-+ struct nlmsghdr *nlh;
-+ unsigned char *b = skb->tail;
-+
-+ nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(*r));
-+ r = NLMSG_DATA(nlh);
-+ r->ifi_family = AF_UNSPEC;
-+ r->ifi_type = dev->type;
-+ r->ifi_index = dev->ifindex;
-+ r->ifi_flags = dev->flags;
-+ r->ifi_change = 0; /* Wireless changes don't affect those flags */
-+
-+ /* Add the wireless events in the netlink packet */
-+ RTA_PUT(skb, IFLA_WIRELESS,
-+ event_len, event);
-+
-+ nlh->nlmsg_len = skb->tail - b;
-+ return skb->len;
-+
-+nlmsg_failure:
-+rtattr_failure:
-+ skb_trim(skb, b - skb->data);
-+ return -1;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Create and broadcast and send it on the standard rtnetlink socket
-+ * This is a pure clone rtmsg_ifinfo() in net/core/rtnetlink.c
-+ * Andrzej Krzysztofowicz mandated that I used a IFLA_XXX field
-+ * within a RTM_NEWLINK event.
-+ */
-+static inline void rtmsg_iwinfo(struct net_device * dev,
-+ char * event,
-+ int event_len)
-+{
-+ struct sk_buff *skb;
-+ int size = NLMSG_GOODSIZE;
-+
-+ skb = alloc_skb(size, GFP_ATOMIC);
-+ if (!skb)
-+ return;
-+
-+ if (rtnetlink_fill_iwinfo(skb, dev, RTM_NEWLINK,
-+ event, event_len) < 0) {
-+ kfree_skb(skb);
-+ return;
-+ }
-+ NETLINK_CB(skb).dst_groups = RTMGRP_LINK;
-+ netlink_broadcast(rtnl, skb, 0, RTMGRP_LINK, GFP_ATOMIC);
-+}
-+#endif /* WE_EVENT_NETLINK */
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Main event dispatcher. Called from other parts and drivers.
-+ * Send the event on the apropriate channels.
-+ * May be called from interrupt context.
-+ */
-+void wireless_send_event(struct net_device * dev,
-+ unsigned int cmd,
-+ union iwreq_data * wrqu,
-+ char * extra)
-+{
-+ const struct iw_ioctl_description * descr = NULL;
-+ int extra_len = 0;
-+ struct iw_event *event; /* Mallocated whole event */
-+ int event_len; /* Its size */
-+ int hdr_len; /* Size of the event header */
-+ /* Don't "optimise" the following variable, it will crash */
-+ unsigned cmd_index; /* *MUST* be unsigned */
-+
-+ /* Get the description of the IOCTL */
-+ if(cmd <= SIOCIWLAST) {
-+ cmd_index = cmd - SIOCIWFIRST;
-+ if(cmd_index < standard_ioctl_num)
-+ descr = &(standard_ioctl[cmd_index]);
-+ } else {
-+ cmd_index = cmd - IWEVFIRST;
-+ if(cmd_index < standard_event_num)
-+ descr = &(standard_event[cmd_index]);
-+ }
-+ /* Don't accept unknown events */
-+ if(descr == NULL) {
-+ /* Note : we don't return an error to the driver, because
-+ * the driver would not know what to do about it. It can't
-+ * return an error to the user, because the event is not
-+ * initiated by a user request.
-+ * The best the driver could do is to log an error message.
-+ * We will do it ourselves instead...
-+ */
-+ printk(KERN_ERR "%s (WE) : Invalid Wireless Event (0x%04X)\n",
-+ dev->name, cmd);
-+ return;
-+ }
-+#ifdef WE_EVENT_DEBUG
-+ printk(KERN_DEBUG "%s (WE) : Got event 0x%04X\n",
-+ dev->name, cmd);
-+ printk(KERN_DEBUG "%s (WE) : Header type : %d, Token type : %d, size : %d, token : %d\n", dev->name, descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
-+#endif /* WE_EVENT_DEBUG */
-+
-+ /* Check extra parameters and set extra_len */
-+ if(descr->header_type == IW_HEADER_TYPE_POINT) {
-+ /* Check if number of token fits within bounds */
-+ if(wrqu->data.length > descr->max_tokens) {
-+ printk(KERN_ERR "%s (WE) : Wireless Event too big (%d)\n", dev->name, wrqu->data.length);
-+ return;
-+ }
-+ if(wrqu->data.length < descr->min_tokens) {
-+ printk(KERN_ERR "%s (WE) : Wireless Event too small (%d)\n", dev->name, wrqu->data.length);
-+ return;
-+ }
-+ /* Calculate extra_len - extra is NULL for restricted events */
-+ if(extra != NULL)
-+ extra_len = wrqu->data.length * descr->token_size;
-+#ifdef WE_EVENT_DEBUG
-+ printk(KERN_DEBUG "%s (WE) : Event 0x%04X, tokens %d, extra_len %d\n", dev->name, cmd, wrqu->data.length, extra_len);
-+#endif /* WE_EVENT_DEBUG */
-+ }
-+
-+ /* Total length of the event */
-+ hdr_len = event_type_size[descr->header_type];
-+ event_len = hdr_len + extra_len;
-+
-+#ifdef WE_EVENT_DEBUG
-+ printk(KERN_DEBUG "%s (WE) : Event 0x%04X, hdr_len %d, event_len %d\n", dev->name, cmd, hdr_len, event_len);
-+#endif /* WE_EVENT_DEBUG */
-+
-+ /* Create temporary buffer to hold the event */
-+ event = kmalloc(event_len, GFP_ATOMIC);
-+ if(event == NULL)
-+ return;
-+
-+ /* Fill event */
-+ event->len = event_len;
-+ event->cmd = cmd;
-+ memcpy(&event->u, wrqu, hdr_len - IW_EV_LCP_LEN);
-+ if(extra != NULL)
-+ memcpy(((char *) event) + hdr_len, extra, extra_len);
-+
-+#ifdef WE_EVENT_NETLINK
-+ /* rtnetlink event channel */
-+ rtmsg_iwinfo(dev, (char *) event, event_len);
-+#endif /* WE_EVENT_NETLINK */
-+
-+ /* Cleanup */
-+ kfree(event);
-+
-+ return; /* Always success, I guess ;-) */
- }
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/keyboard-ctrl+alt.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/keyboard-ctrl+alt.patch
deleted file mode 100644
index 93a80bae3c..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/keyboard-ctrl+alt.patch
+++ /dev/null
@@ -1,79 +0,0 @@
-
-#
-# Made by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux/drivers/char/corgi_rawmap.h~keyboard-ctrl+alt 2003-09-15 14:30:08.000000000 +0200
-+++ linux/drivers/char/corgi_rawmap.h 2003-09-16 00:45:39.000000000 +0200
-@@ -55,7 +55,7 @@
- SLKEY_ACTIVITY, SLKEY_W, SLKEY_S, SLKEY_F, SLKEY_V, SLKEY_H, SLKEY_M, SLKEY_L, KEY_IGN, SLKEY_RSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_CONTACTS, SLKEY_A, SLKEY_D, SLKEY_C, SLKEY_B, SLKEY_N, SLKEY_PERIOD, KEY_IGN, SLKEY_ENTER, KEY_IGN, SLKEY_LSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_MAIL, SLKEY_Z, SLKEY_X, SLKEY_MINUS, SLKEY_SPACE, SLKEY_COMMA, KEY_IGN, SLKEY_UP, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_2ND, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-- SLKEY_HOME, SLKEY_KANA, SLKEY_ZENHAN, SLKEY_F9, SLKEY_F4, SLKEY_F2, SLKEY_LEFT, SLKEY_DOWN, SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+ SLKEY_HOME, SLKEY_LCONTROL, SLKEY_LALT, SLKEY_F9, SLKEY_F4, SLKEY_F2, SLKEY_LEFT, SLKEY_DOWN, SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_OFF, SLKEY_EXSELECT, SLKEY_EXCANCEL, SLKEY_EXJOGDOWN, SLKEY_EXJOGUP, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN};
-
- static unsigned char rawkeytable_table_NormalUpper[(NR_KEYCODES+1)] = {
-@@ -66,7 +66,7 @@
- SLKEY_ACTIVITY, SLKEY_W, SLKEY_S, SLKEY_F, SLKEY_V, SLKEY_H, SLKEY_M, SLKEY_L, KEY_IGN, SLKEY_RSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_CONTACTS, SLKEY_A, SLKEY_D, SLKEY_C, SLKEY_B, SLKEY_N, SLKEY_PERIOD, KEY_IGN, SLKEY_ENTER, KEY_IGN, SLKEY_LSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_MAIL, SLKEY_Z, SLKEY_X, SLKEY_MINUS, SLKEY_SPACE, SLKEY_COMMA, KEY_IGN, SLKEY_UP, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_2ND, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-- SLKEY_HOME, SLKEY_KANA, SLKEY_ZENHAN, SLKEY_F9, SLKEY_F4, SLKEY_F2, SLKEY_LEFT, SLKEY_DOWN, SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+ SLKEY_HOME, SLKEY_LCONTROL, SLKEY_LALT, SLKEY_F9, SLKEY_F4, SLKEY_F2, SLKEY_LEFT, SLKEY_DOWN, SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_OFF, SLKEY_EXSELECT, SLKEY_EXCANCEL, SLKEY_EXJOGDOWN, SLKEY_EXJOGUP, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN};
-
- static unsigned char rawkeytable_table_2ndLower[(NR_KEYCODES+1)] = {
-@@ -77,7 +77,7 @@
- SLKEY_ACTIVITY, SLKEY_W, SLKEY_S, SLKEY_F, SLKEY_V, SLKEY_H, SLKEY_M, SLKEY_L, KEY_IGN, SLKEY_RSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_CONTACTS, SLKEY_A, SLKEY_D, SLKEY_C, SLKEY_B, SLKEY_N, SLKEY_PERIOD, KEY_IGN, SLKEY_ENTER, KEY_IGN, SLKEY_LSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_MAIL, SLKEY_Z, SLKEY_X, SLKEY_MINUS, SLKEY_SPACE, SLKEY_COMMA, KEY_IGN, SLKEY_UP, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_2ND, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-- SLKEY_HOME, SLKEY_KANA, SLKEY_ZENHAN, SLKEY_F9, SLKEY_F4, SLKEY_F2, SLKEY_LEFT, SLKEY_DOWN, SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+ SLKEY_HOME, SLKEY_LCONTROL, SLKEY_LALT, SLKEY_F9, SLKEY_F4, SLKEY_F2, SLKEY_LEFT, SLKEY_DOWN, SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_OFF, SLKEY_EXSELECT, SLKEY_EXCANCEL, SLKEY_EXJOGDOWN, SLKEY_EXJOGUP, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN};
-
- static unsigned char rawkeytable_table_2ndUpper[(NR_KEYCODES+1)] = {
-@@ -88,7 +88,7 @@
- SLKEY_ACTIVITY, SLKEY_W, SLKEY_S, SLKEY_F, SLKEY_V, SLKEY_H, SLKEY_M, SLKEY_L, KEY_IGN, SLKEY_RSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_CONTACTS, SLKEY_A, SLKEY_D, SLKEY_PRINTSCREEN, SLKEY_B, SLKEY_N, SLKEY_PERIOD, KEY_IGN, SLKEY_ENTER, KEY_IGN, SLKEY_LSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_MAIL, SLKEY_Z, SLKEY_X, SLKEY_MINUS, SLKEY_SPACE, SLKEY_COMMA, KEY_IGN, SLKEY_UP, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_2ND, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-- SLKEY_HOME, SLKEY_KANA, SLKEY_ZENHAN, SLKEY_F9, SLKEY_F4, SLKEY_F2, SLKEY_LEFT, SLKEY_DOWN, SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+ SLKEY_HOME, SLKEY_LCONTROL, SLKEY_LALT, SLKEY_F9, SLKEY_F4, SLKEY_F2, SLKEY_LEFT, SLKEY_DOWN, SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_OFF, SLKEY_EXSELECT, SLKEY_EXCANCEL, SLKEY_EXJOGDOWN, SLKEY_EXJOGUP, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN};
-
- static unsigned char rawkeytable_table_NumlockLower[(NR_KEYCODES+1)] = {
-@@ -99,7 +99,7 @@
- SLKEY_ACTIVITY, SLKEY_W, SLKEY_S, SLKEY_F, SLKEY_V, SLKEY_H, SLKEY_M, SLKEY_L, KEY_IGN, SLKEY_RSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_CONTACTS, SLKEY_A, SLKEY_D, SLKEY_C, SLKEY_B, SLKEY_N, SLKEY_PERIOD, KEY_IGN, SLKEY_ENTER, KEY_IGN, SLKEY_LSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_MAIL, SLKEY_Z, SLKEY_X, SLKEY_MINUS, SLKEY_SPACE, SLKEY_COMMA, KEY_IGN, SLKEY_UP, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_2ND, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-- SLKEY_HOME, SLKEY_KANA, SLKEY_ZENHAN, SLKEY_F9, SLKEY_F4, SLKEY_F2, SLKEY_LEFT, SLKEY_DOWN, SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+ SLKEY_HOME, SLKEY_LCONTROL, SLKEY_LALT, SLKEY_F9, SLKEY_F4, SLKEY_F2, SLKEY_LEFT, SLKEY_DOWN, SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_OFF, SLKEY_EXSELECT, SLKEY_EXCANCEL, SLKEY_EXJOGDOWN, SLKEY_EXJOGUP, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN};
-
- static unsigned char rawkeytable_table_NumlockUpper[(NR_KEYCODES+1)] = {
-@@ -110,7 +110,7 @@
- SLKEY_ACTIVITY, SLKEY_W, SLKEY_S, SLKEY_F, SLKEY_V, SLKEY_H, SLKEY_M, SLKEY_L, KEY_IGN, SLKEY_RSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_CONTACTS, SLKEY_A, SLKEY_D, SLKEY_C, SLKEY_B, SLKEY_N, SLKEY_PERIOD, KEY_IGN, SLKEY_ENTER, KEY_IGN, SLKEY_LSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_MAIL, SLKEY_Z, SLKEY_X, SLKEY_MINUS, SLKEY_SPACE, SLKEY_COMMA, KEY_IGN, SLKEY_UP, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_2ND, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-- SLKEY_HOME, SLKEY_KANA, SLKEY_ZENHAN, SLKEY_F9, SLKEY_F4, SLKEY_F2, SLKEY_LEFT, SLKEY_DOWN, SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+ SLKEY_HOME, SLKEY_LCONTROL, SLKEY_LALT, SLKEY_F9, SLKEY_F4, SLKEY_F2, SLKEY_LEFT, SLKEY_DOWN, SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_OFF, SLKEY_EXSELECT, SLKEY_EXCANCEL, SLKEY_EXJOGDOWN, SLKEY_EXJOGUP, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN};
-
- static unsigned char rawkeytable_table_Num2ndLower[(NR_KEYCODES+1)] = {
-@@ -121,7 +121,7 @@
- SLKEY_ACTIVITY, SLKEY_W, SLKEY_S, SLKEY_F, SLKEY_V, SLKEY_H, SLKEY_M, SLKEY_L, KEY_IGN, SLKEY_RSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_CONTACTS, SLKEY_A, SLKEY_D, SLKEY_C, SLKEY_B, SLKEY_N, SLKEY_PERIOD, KEY_IGN, SLKEY_ENTER, KEY_IGN, SLKEY_LSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_MAIL, SLKEY_Z, SLKEY_X, SLKEY_MINUS, SLKEY_SPACE, SLKEY_COMMA, KEY_IGN, SLKEY_UP, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_2ND, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-- SLKEY_HOME, SLKEY_KANA, SLKEY_ZENHAN, SLKEY_F9, SLKEY_F4, SLKEY_F2, SLKEY_LEFT, SLKEY_DOWN, SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+ SLKEY_HOME, SLKEY_LCONTROL, SLKEY_LALT, SLKEY_F9, SLKEY_F4, SLKEY_F2, SLKEY_LEFT, SLKEY_DOWN, SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_OFF, SLKEY_EXSELECT, SLKEY_EXCANCEL, SLKEY_EXJOGDOWN, SLKEY_EXJOGUP, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN};
-
- static unsigned char rawkeytable_table_Num2ndUpper[(NR_KEYCODES+1)] = {
-@@ -132,7 +132,7 @@
- SLKEY_ACTIVITY, SLKEY_W, SLKEY_S, SLKEY_F, SLKEY_V, SLKEY_H, SLKEY_M, SLKEY_L, KEY_IGN, SLKEY_RSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_CONTACTS, SLKEY_A, SLKEY_D, SLKEY_PRINTSCREEN, SLKEY_B, SLKEY_N, SLKEY_PERIOD, KEY_IGN, SLKEY_ENTER, KEY_IGN, SLKEY_LSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_MAIL, SLKEY_Z, SLKEY_X, SLKEY_MINUS, SLKEY_SPACE, SLKEY_COMMA, KEY_IGN, SLKEY_UP, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_2ND, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-- SLKEY_HOME, SLKEY_KANA, SLKEY_ZENHAN, SLKEY_F9, SLKEY_F4, SLKEY_F2, SLKEY_LEFT, SLKEY_DOWN, SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+ SLKEY_HOME, SLKEY_LCONTROL, SLKEY_LALT, SLKEY_F9, SLKEY_F4, SLKEY_F2, SLKEY_LEFT, SLKEY_DOWN, SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
- SLKEY_OFF, SLKEY_EXSELECT, SLKEY_EXCANCEL, SLKEY_EXJOGDOWN, SLKEY_EXJOGUP, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN};
-
-
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/keymap-more-sane.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/keymap-more-sane.patch
deleted file mode 100644
index a58dd13fbd..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/keymap-more-sane.patch
+++ /dev/null
@@ -1,23 +0,0 @@
---- linux/drivers/char/corgi_keymap.map~keymap-more-sane 2003-08-30 01:05:14.000000000 +0200
-+++ linux/drivers/char/corgi_keymap.map 2003-09-03 20:44:27.000000000 +0200
-@@ -71,9 +71,11 @@
- # (Cancel:34) F9 -> Escape
- keycode 34 = Escape
- keycode 35 = Left
-+ alt keycode 35 = Decr_Console
- keycode 36 = Up
- keycode 37 = Down
- keycode 38 = Right
-+ alt keycode 38 = Incr_Console
- # (OK:39) F4 -> Return
- keycode 39 = Return
- keycode 40 =
-@@ -100,7 +102,7 @@
- keycode 60 = Shift_Lock
- keycode 61 = at
- keycode 62 = question
--keycode 63 = comma slash
-+keycode 63 = slash comma
- alt keycode 63 = less
- keycode 64 = period question
- alt keycode 64 = greater
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/logo.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/logo.patch
deleted file mode 100644
index c006684f23..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/logo.patch
+++ /dev/null
@@ -1,2598 +0,0 @@
---- linux/drivers/video/fbcon.c 2003-02-27 21:47:36.000000000 -0600
-+++ linux.new/drivers/video/fbcon.c 2003-02-27 18:39:39.000000000 -0600
-@@ -126,8 +126,8 @@
- #define LOGO_H (320-16)
- #define LOGO_W 240
- #else
--#define LOGO_H 80
--#define LOGO_W 80
-+#define LOGO_H 52
-+#define LOGO_W 240
- #endif
- #define LOGO_LINE (LOGO_W/8)
- #if defined(CONFIG_SHARP_LOGO_SCREEN)
---- linux/include/linux/linux_logo.h 2001-06-11 21:15:27.000000000 -0500
-+++ linux.new/include/linux/linux_logo.h 2003-02-27 15:58:15.000000000 -0600
-@@ -1,4 +1,4 @@
--/* $Id$
-+/* linux_logo.h created with fblogo, 2002/12/29 02:43:36
- * include/linux/linux_logo.h: This is a linux logo
- * to be displayed on boot.
- *
-@@ -7,907 +7,1673 @@
- *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
-- * image size has to be 80x80
-- * values have to start from 0x20
-- * (i.e. RGB(linux_logo_red[0],
-- * linux_logo_green[0],
-- * linux_logo_blue[0]) is color 0x20)
-- * BW image has to be 80x80 as well, with MS bit
-- * on the left
-- * Serial_console ascii image can be any size,
-- * but should contain %s to display the version
-+ * Generated by fblogo version 0.5.0
-+ *
-+ *
-+ * Remember to modify drivers/video/fbcon.c:
-+ * Change "#define LOGO_H 80" to "#define LOGO_H 52"
-+ * Change "#define LOGO_W 80" to "#define LOGO_W 240"
- */
-
- #ifndef __HAVE_ARCH_LINUX_LOGO
--#define LINUX_LOGO_COLORS 187
-+#define LINUX_LOGO_COLORS 223
- #endif
--
- #ifdef INCLUDE_LINUX_LOGO_DATA
--
- #ifndef __HAVE_ARCH_LINUX_LOGO
--
- unsigned char linux_logo_red[] __initdata = {
-- 0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-- 0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-- 0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
-- 0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-- 0xc3, 0x65, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-- 0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-- 0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x76, 0x79,
-- 0x62, 0x36, 0x9a, 0xe2, 0xec, 0xe1, 0xb8, 0xd7,
-- 0xaf, 0x25, 0xbc, 0xc0, 0xef, 0xea, 0xe8, 0xe8,
-- 0xf5, 0xf1, 0xda, 0xd3, 0x79, 0xdb, 0xf4, 0xf6,
-- 0xf6, 0xf6, 0xe2, 0x3d, 0xb4, 0xce, 0xe6, 0xee,
-- 0xf6, 0x68, 0xd8, 0xec, 0xf5, 0xc6, 0xc8, 0x9c,
-- 0x89, 0xd2, 0xee, 0xcb, 0xb9, 0xd2, 0x66, 0x5e,
-- 0x8b, 0xbe, 0xa8, 0xd5, 0xca, 0xb6, 0xae, 0x9c,
-- 0xc5, 0xbe, 0xbe, 0xca, 0x90, 0xb2, 0x9a, 0xa8,
-- 0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x12,
-- 0x4a, 0x8e, 0xf2, 0xf6, 0xf6, 0xee, 0xb5, 0xe4,
-- 0xf1, 0x26, 0x9a, 0xea, 0xf6, 0xe0, 0xd2, 0x16,
-- 0x9a, 0x2e, 0x70, 0xd6, 0x46, 0x7c, 0xb4, 0x62,
-- 0xd6, 0xa3, 0x74, 0xa7, 0xa2, 0xca, 0xe0, 0xae,
-- 0xbe, 0xce, 0xa3, 0x8e, 0x6d, 0x8e, 0x32, 0xaf,
-- 0x50, 0x9e, 0x5b, 0x8a, 0x98, 0x82, 0x7a, 0x82,
-- 0x56, 0x7c, 0x8a, 0x56, 0x5e, 0x86, 0x6a, 0x52,
-- 0x59, 0x64, 0x5e,
-+ 0x00, 0x02, 0x06, 0x0A, 0x56, 0xA6, 0xBE, 0xBA,
-+ 0xB6, 0x92, 0x3E, 0x1A, 0x8A, 0xF3, 0xFB, 0xEE,
-+ 0xC6, 0x62, 0x4A, 0x12, 0x26, 0x0E, 0x76, 0xDA,
-+ 0x6E, 0x32, 0x8E, 0x1E, 0x2A, 0xCE, 0xE2, 0x36,
-+ 0x66, 0xA2, 0x2E, 0x9E, 0xCA, 0x6A, 0x5A, 0x82,
-+ 0x7E, 0xE9, 0xD2, 0xDE, 0x22, 0x72, 0xAE, 0xD6,
-+ 0x86, 0x3A, 0x52, 0x9A, 0xAA, 0x16, 0x46, 0x4E,
-+ 0x42, 0xC2, 0x96, 0x7A, 0x5E, 0xB2, 0x32, 0x7E,
-+ 0x3A, 0x16, 0x02, 0x02, 0x06, 0x1F, 0x02, 0x02,
-+ 0x06, 0x02, 0x22, 0x3A, 0x35, 0x16, 0x0A, 0x02,
-+ 0x2A, 0x3E, 0x39, 0x32, 0x2A, 0x1E, 0x16, 0x06,
-+ 0x22, 0x22, 0x1E, 0x16, 0x6E, 0x82, 0x6E, 0x2E,
-+ 0x1E, 0x2E, 0x1E, 0x0A, 0x3A, 0xDA, 0xFE, 0xFA,
-+ 0xFA, 0xE2, 0x6A, 0x3A, 0x1A, 0xFA, 0xF6, 0x9E,
-+ 0x02, 0x6E, 0xFE, 0xF6, 0x3E, 0x66, 0x52, 0x1B,
-+ 0xD6, 0x5A, 0xEE, 0xC6, 0x72, 0x36, 0x22, 0x1E,
-+ 0x02, 0x96, 0xF6, 0xDE, 0xA2, 0xD6, 0x39, 0x0E,
-+ 0xAA, 0x52, 0x5A, 0xD2, 0xDE, 0x61, 0x46, 0xDE,
-+ 0x7A, 0x57, 0x9E, 0xBA, 0xB6, 0x4A, 0x5A, 0xA6,
-+ 0x96, 0x23, 0x1E, 0x12, 0x9A, 0x4E, 0x76, 0xAE,
-+ 0x2E, 0xBE, 0x86, 0x48, 0xA6, 0x52, 0x06, 0x2E,
-+ 0x56, 0x13, 0x2A, 0x4A, 0x36, 0x56, 0x2E, 0x1E,
-+ 0x46, 0x3A, 0x66, 0x02, 0x3D, 0x3E, 0x2E, 0x3E,
-+ 0x4A, 0x32, 0x52, 0x72, 0x76, 0x67, 0x68, 0x5A,
-+ 0x3A, 0x1A, 0x0E, 0x2E, 0x4E, 0x02, 0x3E, 0x0A,
-+ 0x28, 0x42, 0x10, 0x26, 0x8E, 0x0A, 0x86, 0xC2,
-+ 0x02, 0x6E, 0x92, 0x02, 0x42, 0x02, 0xBE, 0x4E,
-+ 0x02, 0x22, 0x02, 0x3E, 0x3A, 0x32
- };
-
- unsigned char linux_logo_green[] __initdata = {
-- 0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-- 0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-- 0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
-- 0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-- 0xc3, 0x62, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-- 0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-- 0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x62, 0x5c,
-- 0x4e, 0x26, 0x72, 0xaa, 0xba, 0xaf, 0x90, 0xae,
-- 0x92, 0x1a, 0xa4, 0x85, 0xb6, 0xbe, 0xc3, 0xc8,
-- 0xcf, 0xd0, 0xc2, 0xce, 0x57, 0xa2, 0xd6, 0xda,
-- 0xda, 0xd7, 0xb8, 0x2a, 0x7b, 0x91, 0xae, 0xca,
-- 0xda, 0x45, 0x9e, 0xb2, 0xd7, 0x9b, 0x90, 0x76,
-- 0x5c, 0xa2, 0xbe, 0xa6, 0x85, 0x96, 0x4e, 0x46,
-- 0x66, 0x92, 0x7a, 0x9a, 0x96, 0x9d, 0x9a, 0x6b,
-- 0x8a, 0x8e, 0xb2, 0xca, 0x90, 0xa6, 0x79, 0x7c,
-- 0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x0e,
-- 0x36, 0x86, 0xba, 0xbe, 0xe6, 0xcc, 0x8e, 0xb8,
-- 0xc4, 0x1e, 0x8e, 0xae, 0xba, 0xb2, 0xa6, 0x12,
-- 0x7a, 0x20, 0x64, 0xaa, 0x2f, 0x70, 0x85, 0x46,
-- 0xa6, 0x6e, 0x51, 0x72, 0x92, 0xa2, 0xa6, 0x87,
-- 0x96, 0xa2, 0x85, 0x7a, 0x6a, 0x6e, 0x22, 0x76,
-- 0x36, 0x76, 0x3c, 0x6e, 0x63, 0x53, 0x66, 0x62,
-- 0x42, 0x50, 0x56, 0x42, 0x56, 0x56, 0x56, 0x3e,
-- 0x51, 0x52, 0x56,
-+ 0x00, 0x02, 0x06, 0x0A, 0x56, 0xA6, 0xBE, 0xBA,
-+ 0xB6, 0x92, 0x3E, 0x1A, 0x8A, 0xF3, 0xFB, 0xEE,
-+ 0xC6, 0x62, 0x4A, 0x12, 0x26, 0x0E, 0x76, 0xDA,
-+ 0x6E, 0x32, 0x8E, 0x1E, 0x2A, 0xCE, 0xE2, 0x36,
-+ 0x66, 0xA2, 0x2E, 0x9E, 0xCA, 0x6A, 0x5A, 0x82,
-+ 0x7E, 0xE9, 0xD2, 0xDE, 0x22, 0x72, 0xAE, 0xD6,
-+ 0x86, 0x3A, 0x52, 0x9A, 0xAA, 0x16, 0x46, 0x4E,
-+ 0x42, 0xC2, 0x96, 0x7A, 0x5E, 0xB2, 0x2E, 0x7E,
-+ 0x3A, 0x3E, 0x6A, 0xA2, 0x92, 0x30, 0x95, 0x76,
-+ 0x4E, 0x86, 0x36, 0x7E, 0x9A, 0x6E, 0x42, 0x56,
-+ 0x5A, 0xC2, 0xBE, 0xB2, 0xAA, 0x9A, 0x63, 0x1E,
-+ 0xA2, 0x9E, 0x96, 0x5A, 0x3A, 0x42, 0x4A, 0x52,
-+ 0x91, 0x46, 0x4E, 0x62, 0x22, 0x4A, 0x6E, 0x86,
-+ 0x92, 0x9A, 0x52, 0x4A, 0x76, 0x7A, 0x9E, 0x76,
-+ 0x62, 0x32, 0x5E, 0xAE, 0x3E, 0x66, 0x52, 0x81,
-+ 0xA6, 0x5A, 0xEE, 0xC6, 0x72, 0x5C, 0x6A, 0x8A,
-+ 0x36, 0x3E, 0xBA, 0xBA, 0xA2, 0xD6, 0xAA, 0x4E,
-+ 0x8A, 0x4E, 0x5A, 0xD2, 0xDE, 0x64, 0x32, 0x9A,
-+ 0x5E, 0x57, 0x9E, 0xBA, 0xB6, 0x52, 0x62, 0xA6,
-+ 0x9A, 0x47, 0x3E, 0x56, 0x02, 0x1A, 0x76, 0xAE,
-+ 0x4A, 0x02, 0x02, 0x38, 0x02, 0x4A, 0x46, 0x86,
-+ 0x1E, 0x2E, 0x7A, 0xD2, 0x5E, 0x26, 0x92, 0x62,
-+ 0xCA, 0x42, 0x66, 0x26, 0x67, 0xB6, 0x62, 0x92,
-+ 0x9E, 0x72, 0xB2, 0xF2, 0xFE, 0xDE, 0xFE, 0xFE,
-+ 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0x8A, 0x2A,
-+ 0x42, 0x52, 0x6A, 0x26, 0x8E, 0x26, 0x86, 0xC2,
-+ 0xE2, 0x6E, 0x92, 0xBE, 0x42, 0xC6, 0xBE, 0x4E,
-+ 0xEE, 0x5A, 0xEA, 0x3E, 0x4A, 0x32
- };
-
- unsigned char linux_logo_blue[] __initdata = {
-- 0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-- 0x12, 0x01, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-- 0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x06, 0x65,
-- 0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-- 0xc3, 0x59, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-- 0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-- 0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x2e, 0x08,
-- 0x0a, 0x06, 0x0a, 0x0b, 0x0b, 0x0f, 0x0c, 0x0f,
-- 0x3d, 0x09, 0x73, 0x09, 0x0d, 0x0a, 0x10, 0x1e,
-- 0x2d, 0x13, 0x86, 0xba, 0x19, 0x0a, 0x36, 0x3c,
-- 0x26, 0x14, 0x0d, 0x06, 0x07, 0x0a, 0x0b, 0x0f,
-- 0x4a, 0x06, 0x0a, 0x0c, 0x2b, 0x0a, 0x0b, 0x0a,
-- 0x06, 0x0a, 0x0a, 0x11, 0x0b, 0x0a, 0x0a, 0x1e,
-- 0x0f, 0x0d, 0x0a, 0x0b, 0x22, 0x6a, 0x72, 0x0b,
-- 0x0b, 0x22, 0x90, 0xca, 0x90, 0x92, 0x3c, 0x2c,
-- 0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x06,
-- 0x0e, 0x6a, 0x0e, 0x0e, 0xbe, 0x5b, 0x2c, 0x3e,
-- 0x0e, 0x0a, 0x5a, 0x0d, 0x0e, 0x3e, 0x0a, 0x06,
-- 0x2e, 0x06, 0x4e, 0x36, 0x06, 0x58, 0x24, 0x06,
-- 0x3a, 0x08, 0x08, 0x07, 0x5e, 0x45, 0x0a, 0x32,
-- 0x2e, 0x2a, 0x43, 0x48, 0x5f, 0x2e, 0x06, 0x06,
-- 0x07, 0x24, 0x06, 0x32, 0x06, 0x06, 0x46, 0x2e,
-- 0x22, 0x06, 0x06, 0x1e, 0x4c, 0x06, 0x3a, 0x22,
-- 0x42, 0x34, 0x42,
-+ 0x00, 0x02, 0x06, 0x0A, 0x56, 0xA6, 0xBE, 0xBA,
-+ 0xB6, 0x92, 0x3E, 0x1A, 0x8A, 0xF3, 0xFB, 0xEE,
-+ 0xC6, 0x62, 0x4A, 0x12, 0x26, 0x0E, 0x76, 0xDA,
-+ 0x6E, 0x32, 0x8E, 0x1E, 0x2A, 0xCE, 0xE2, 0x36,
-+ 0x66, 0xA2, 0x2E, 0x9E, 0xCA, 0x6A, 0x5A, 0x82,
-+ 0x7E, 0xE9, 0xD2, 0xDE, 0x22, 0x72, 0xAE, 0xD6,
-+ 0x86, 0x3A, 0x52, 0x9A, 0xAA, 0x16, 0x46, 0x4E,
-+ 0x42, 0xC2, 0x96, 0x7A, 0x5E, 0xB2, 0x1A, 0x06,
-+ 0x1A, 0x2A, 0x36, 0x52, 0x46, 0x23, 0x4D, 0x3E,
-+ 0x2A, 0x42, 0x2A, 0x5A, 0x69, 0x42, 0x26, 0x2E,
-+ 0x42, 0x7E, 0x7C, 0x72, 0x6A, 0x5E, 0x3B, 0x12,
-+ 0x62, 0x5E, 0x5A, 0x36, 0x26, 0x1E, 0x26, 0x42,
-+ 0x56, 0x3A, 0x36, 0x36, 0x1E, 0x2E, 0x2A, 0x22,
-+ 0x22, 0x1A, 0x16, 0x42, 0x46, 0x26, 0x1E, 0x12,
-+ 0x32, 0x2A, 0x2E, 0x16, 0x2A, 0x1A, 0x2E, 0x4E,
-+ 0x12, 0x22, 0x02, 0x02, 0x12, 0x4A, 0x46, 0x52,
-+ 0x1E, 0x1E, 0x16, 0x0E, 0x02, 0x02, 0x6F, 0x2E,
-+ 0x0E, 0x1A, 0x06, 0x02, 0x02, 0x04, 0x22, 0x16,
-+ 0x0E, 0x12, 0x02, 0x02, 0x02, 0x0A, 0x5A, 0x02,
-+ 0x02, 0x1B, 0x2E, 0x32, 0x02, 0x02, 0x02, 0x02,
-+ 0x16, 0x02, 0x02, 0x10, 0x02, 0x02, 0x26, 0x5A,
-+ 0x02, 0x1F, 0x52, 0x8E, 0x22, 0x02, 0x5E, 0x3E,
-+ 0x86, 0x0E, 0x16, 0x16, 0x52, 0x7A, 0x4A, 0x66,
-+ 0x72, 0x52, 0x82, 0xB2, 0xBA, 0xA4, 0xB2, 0xAA,
-+ 0x9E, 0x8E, 0x88, 0x96, 0xA6, 0x82, 0x62, 0x1A,
-+ 0x34, 0x4A, 0x31, 0x16, 0x02, 0x1A, 0x02, 0x02,
-+ 0x72, 0x02, 0x02, 0x5E, 0x1A, 0x62, 0x02, 0x0E,
-+ 0x76, 0x1E, 0x76, 0x1E, 0x0A, 0x02
- };
-
- unsigned char linux_logo[] __initdata = {
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
-- 0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-- 0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x21, 0x23, 0x25, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d,
-- 0x2d, 0x2e, 0x2c, 0x2b, 0x2a, 0x25, 0x28, 0x22,
-- 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-- 0x24, 0x2a, 0x2c, 0x2f, 0x2c, 0x30, 0x30, 0x24,
-- 0x25, 0x27, 0x2b, 0x2c, 0x2f, 0x31, 0x32, 0x25,
-- 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
-- 0x33, 0x34, 0x35, 0x21, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x21, 0x2b, 0x2f, 0x2c,
-- 0x30, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
-- 0x2d, 0x27, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x31,
-- 0x2d, 0x32, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x2a, 0x34,
-- 0x25, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x23, 0x32, 0x27, 0x21, 0x36,
-- 0x2a, 0x2d, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2c, 0x35,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x25, 0x2f, 0x37, 0x32, 0x22,
-- 0x36, 0x35, 0x31, 0x27, 0x22, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x22,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x26, 0x38, 0x38, 0x35, 0x25,
-- 0x36, 0x21, 0x2d, 0x2b, 0x24, 0x21, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x21, 0x24, 0x39, 0x39, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x25, 0x2b, 0x30, 0x28, 0x22,
-- 0x36, 0x36, 0x27, 0x34, 0x30, 0x23, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x21, 0x26, 0x2d, 0x26, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x22, 0x22, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x2d, 0x33, 0x28, 0x21, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x2b, 0x2c, 0x25, 0x21, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x36, 0x36,
-- 0x36, 0x21, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x21, 0x23, 0x22, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x28, 0x34, 0x27, 0x22, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
-- 0x21, 0x21, 0x24, 0x27, 0x21, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x28, 0x27, 0x22, 0x33, 0x24, 0x36,
-- 0x36, 0x36, 0x36, 0x22, 0x2f, 0x2a, 0x23, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
-- 0x30, 0x3a, 0x38, 0x24, 0x24, 0x36, 0x36, 0x36,
-- 0x23, 0x2f, 0x3b, 0x3c, 0x3d, 0x30, 0x25, 0x21,
-- 0x36, 0x36, 0x36, 0x36, 0x2f, 0x32, 0x23, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x23,
-- 0x3e, 0x3f, 0x40, 0x3a, 0x22, 0x36, 0x36, 0x21,
-- 0x41, 0x42, 0x43, 0x44, 0x45, 0x3e, 0x23, 0x21,
-- 0x36, 0x36, 0x36, 0x36, 0x2f, 0x33, 0x28, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x2b,
-- 0x44, 0x40, 0x46, 0x47, 0x35, 0x36, 0x36, 0x26,
-- 0x43, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x2e, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x32, 0x34, 0x36, 0x4d,
-- 0x4e, 0x25, 0x2f, 0x46, 0x4a, 0x22, 0x23, 0x32,
-- 0x4f, 0x50, 0x21, 0x31, 0x51, 0x52, 0x53, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x21, 0x3a,
-- 0x4d, 0x21, 0x31, 0x54, 0x55, 0x28, 0x30, 0x2b,
-- 0x4b, 0x4d, 0x36, 0x23, 0x32, 0x50, 0x3f, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x29, 0x20, 0x29, 0x20, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x2a, 0x38, 0x23, 0x37,
-- 0x55, 0x36, 0x28, 0x3a, 0x56, 0x57, 0x57, 0x58,
-- 0x3c, 0x4d, 0x36, 0x36, 0x36, 0x40, 0x40, 0x21,
-- 0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x30, 0x51, 0x23, 0x35,
-- 0x43, 0x25, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
-- 0x5f, 0x60, 0x61, 0x36, 0x31, 0x47, 0x3b, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x31, 0x2c, 0x25, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x22,
-- 0x40, 0x62, 0x63, 0x5d, 0x64, 0x65, 0x66, 0x67,
-- 0x68, 0x69, 0x66, 0x5e, 0x6a, 0x6b, 0x2a, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x33, 0x2e, 0x26, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x27, 0x2f, 0x23, 0x36,
-- 0x6c, 0x63, 0x6d, 0x64, 0x5c, 0x66, 0x69, 0x6e,
-- 0x6f, 0x70, 0x71, 0x69, 0x69, 0x72, 0x6c, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x33, 0x34, 0x27, 0x22,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x27, 0x34, 0x26, 0x73,
-- 0x74, 0x75, 0x76, 0x64, 0x65, 0x77, 0x69, 0x78,
-- 0x70, 0x71, 0x71, 0x71, 0x72, 0x5f, 0x5e, 0x21,
-- 0x36, 0x36, 0x36, 0x36, 0x25, 0x38, 0x2a, 0x23,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x33, 0x79,
-- 0x63, 0x7a, 0x7b, 0x5c, 0x66, 0x69, 0x6e, 0x7c,
-- 0x71, 0x71, 0x69, 0x7d, 0x7e, 0x7a, 0x7f, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x21, 0x51, 0x2b, 0x28,
-- 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x32, 0x24,
-- 0x80, 0x81, 0x64, 0x82, 0x77, 0x69, 0x71, 0x71,
-- 0x69, 0x83, 0x84, 0x85, 0x7a, 0x85, 0x86, 0x36,
-- 0x21, 0x2b, 0x23, 0x36, 0x36, 0x39, 0x2e, 0x26,
-- 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x27, 0x2d, 0x33, 0x21,
-- 0x87, 0x88, 0x89, 0x72, 0x67, 0x66, 0x5f, 0x89,
-- 0x8a, 0x63, 0x85, 0x8b, 0x8c, 0x8d, 0x41, 0x36,
-- 0x36, 0x2d, 0x3a, 0x35, 0x36, 0x24, 0x51, 0x32,
-- 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x33, 0x21,
-- 0x55, 0x8e, 0x8f, 0x8a, 0x7d, 0x5e, 0x90, 0x7e,
-- 0x75, 0x75, 0x90, 0x62, 0x40, 0x3f, 0x49, 0x23,
-- 0x36, 0x24, 0x3a, 0x3a, 0x24, 0x36, 0x2e, 0x31,
-- 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x21, 0x28, 0x33, 0x37, 0x25, 0x22,
-- 0x3b, 0x50, 0x8e, 0x8f, 0x90, 0x7e, 0x90, 0x63,
-- 0x74, 0x91, 0x92, 0x42, 0x93, 0x4b, 0x45, 0x2c,
-- 0x36, 0x36, 0x33, 0x39, 0x21, 0x36, 0x22, 0x51,
-- 0x33, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x36, 0x21,
-- 0x94, 0x3f, 0x50, 0x95, 0x96, 0x8f, 0x8f, 0x97,
-- 0x8e, 0x42, 0x50, 0x43, 0x47, 0x48, 0x48, 0x98,
-- 0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39,
-- 0x2e, 0x27, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x22, 0x24, 0x2b, 0x38, 0x28, 0x36, 0x32,
-- 0x4c, 0x4b, 0x50, 0x50, 0x50, 0x42, 0x42, 0x50,
-- 0x50, 0x40, 0x45, 0x99, 0x48, 0x48, 0x48, 0x48,
-- 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23,
-- 0x2f, 0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x21, 0x28, 0x32, 0x51, 0x32, 0x28, 0x21, 0x98,
-- 0x48, 0x47, 0x9a, 0x50, 0x50, 0x50, 0x50, 0x50,
-- 0x9a, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x93, 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x2a, 0x2f, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-- 0x23, 0x30, 0x2e, 0x2c, 0x36, 0x21, 0x51, 0x9b,
-- 0x48, 0x48, 0x52, 0x3f, 0x50, 0x50, 0x40, 0x4b,
-- 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x2d, 0x31, 0x27, 0x23, 0x21, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-- 0x27, 0x2c, 0x2d, 0x21, 0x36, 0x28, 0x44, 0x48,
-- 0x48, 0x48, 0x48, 0x47, 0x46, 0x4f, 0x47, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x9c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x28, 0x51, 0x39, 0x26, 0x22, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
-- 0x35, 0x51, 0x28, 0x36, 0x36, 0x9d, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x4f, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x28, 0x38, 0x2b, 0x25, 0x22, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
-- 0x51, 0x25, 0x36, 0x36, 0x23, 0x40, 0x9b, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x9b, 0x99, 0x2b, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x30, 0x2f, 0x33, 0x24, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x30, 0x34,
-- 0x27, 0x36, 0x36, 0x36, 0x2a, 0x40, 0x47, 0x48,
-- 0x48, 0x48, 0x48, 0x9b, 0x99, 0x99, 0x9b, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x47, 0x52,
-- 0x46, 0x4f, 0x37, 0x21, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x30, 0x34, 0x2a, 0x23,
-- 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x39, 0x2c,
-- 0x36, 0x36, 0x36, 0x21, 0x31, 0x4e, 0x9a, 0x4c,
-- 0x47, 0x9b, 0x9b, 0x52, 0x46, 0x4f, 0x52, 0x9b,
-- 0x9b, 0x9b, 0x47, 0x4f, 0x45, 0x9a, 0x93, 0x93,
-- 0x3f, 0x93, 0x98, 0x28, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c, 0x26,
-- 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x28,
-- 0x36, 0x36, 0x36, 0x22, 0x38, 0x98, 0x44, 0x99,
-- 0x9b, 0x48, 0x48, 0x9b, 0x4c, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x47, 0x52, 0x46, 0x43, 0x93,
-- 0x40, 0x40, 0x43, 0x53, 0x21, 0x23, 0x33, 0x23,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x2f, 0x32,
-- 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x21, 0x24, 0x2b, 0x31, 0x36,
-- 0x36, 0x22, 0x36, 0x24, 0x9e, 0x4f, 0x9b, 0x48,
-- 0x48, 0x48, 0x48, 0x9b, 0x99, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47,
-- 0x4f, 0x9a, 0x3f, 0x46, 0x38, 0x36, 0x21, 0x30,
-- 0x26, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c,
-- 0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x26, 0x2e, 0x33, 0x36,
-- 0x25, 0x25, 0x36, 0x4d, 0x52, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x47, 0x44, 0x93, 0x43, 0x23, 0x36, 0x36,
-- 0x26, 0x24, 0x36, 0x36, 0x36, 0x36, 0x28, 0x2f,
-- 0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x2a, 0x51, 0x24, 0x36,
-- 0x2a, 0x36, 0x28, 0x44, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x9b, 0x4b, 0x44, 0x37, 0x36, 0x23,
-- 0x28, 0x30, 0x22, 0x36, 0x36, 0x36, 0x36, 0x2d,
-- 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x21, 0x28, 0x2b, 0x34, 0x36, 0x25,
-- 0x24, 0x36, 0x4a, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x9b, 0x52, 0x3f, 0x21, 0x30,
-- 0x35, 0x25, 0x30, 0x36, 0x36, 0x36, 0x36, 0x32,
-- 0x2d, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x22, 0x26, 0x2e, 0x35, 0x36, 0x2a,
-- 0x36, 0x24, 0x4f, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x47, 0x32, 0x30,
-- 0x2a, 0x23, 0x30, 0x23, 0x36, 0x36, 0x36, 0x21,
-- 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x21, 0x23, 0x2a, 0x51, 0x28, 0x28, 0x25,
-- 0x36, 0x3a, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x9b, 0x52, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x38, 0x21,
-- 0x36, 0x36, 0x22, 0x27, 0x36, 0x36, 0x36, 0x36,
-- 0x2e, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x22, 0x25, 0x2c, 0x34, 0x36, 0x30, 0x21,
-- 0x23, 0x43, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x47, 0x99, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x94, 0x36,
-- 0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
-- 0x2a, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x21, 0x23, 0x2a, 0x51, 0x25, 0x21, 0x2a, 0x36,
-- 0x2e, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x99, 0x99, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x98, 0x36,
-- 0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
-- 0x22, 0x2f, 0x30, 0x22, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x22, 0x25, 0x2c, 0x34, 0x36, 0x24, 0x28, 0x36,
-- 0x54, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4c, 0x99, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
-- 0x36, 0x36, 0x36, 0x30, 0x36, 0x36, 0x36, 0x36,
-- 0x21, 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-- 0x28, 0x32, 0x2f, 0x28, 0x36, 0x27, 0x22, 0x21,
-- 0x43, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4c, 0x99, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4b, 0x21,
-- 0x36, 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-- 0x25, 0x2c, 0x39, 0x36, 0x36, 0x30, 0x22, 0x25,
-- 0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4f, 0x52, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4f, 0x21,
-- 0x36, 0x36, 0x22, 0x26, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-- 0x30, 0x2d, 0x21, 0x36, 0x36, 0x32, 0x23, 0x2a,
-- 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4f, 0x99, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x22,
-- 0x36, 0x36, 0x24, 0x23, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-- 0x33, 0x2e, 0x36, 0x36, 0x23, 0x31, 0x27, 0x39,
-- 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x23,
-- 0x36, 0x36, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-- 0x2b, 0x39, 0x36, 0x36, 0x36, 0x26, 0x32, 0x31,
-- 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x46, 0x22,
-- 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-- 0x35, 0x39, 0x36, 0x36, 0x36, 0x36, 0x26, 0x2d,
-- 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
-- 0x24, 0x27, 0x9f, 0x24, 0x25, 0x28, 0x21, 0x36,
-- 0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25,
-- 0x39, 0x4d, 0xa0, 0x84, 0x81, 0x57, 0x21, 0x39,
-- 0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x53, 0x28,
-- 0x23, 0x36, 0x36, 0x36, 0x21, 0x28, 0x2c, 0x30,
-- 0x21, 0x38, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x30,
-- 0x2d, 0xa1, 0x7a, 0xa2, 0xa3, 0xa3, 0x7f, 0x22,
-- 0x51, 0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0xa4, 0xa5, 0xa5, 0xa6, 0x61,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x32,
-- 0x25, 0x4d, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x21, 0x23, 0x24, 0x26, 0x30, 0x33, 0x31,
-- 0x4d, 0x91, 0x5b, 0xa2, 0xa3, 0xa3, 0xa3, 0x5a,
-- 0x21, 0x2e, 0x46, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0xa7, 0xa8, 0x69, 0x66, 0xa9,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x26, 0x25,
-- 0x83, 0xaa, 0x2c, 0x25, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x21, 0x28, 0x30, 0x35, 0x2d, 0x2f, 0x37, 0x4a,
-- 0x60, 0x85, 0xab, 0xac, 0xa3, 0xa3, 0xa3, 0x82,
-- 0x86, 0x36, 0x32, 0x3f, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4c, 0x99, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0xad, 0xa2, 0xa8, 0xae, 0xaf,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x57,
-- 0x77, 0x66, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x23, 0x30, 0x31, 0xb0, 0x91, 0x7e, 0x90, 0x90,
-- 0x8b, 0x5b, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0x5d, 0xb1, 0x36, 0x24, 0x53, 0x9b, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x9b, 0x99, 0xad, 0x64, 0x5c, 0x8b, 0xb1,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x73, 0x5d,
-- 0x82, 0x5c, 0xb2, 0x2a, 0x23, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-- 0x24, 0x2b, 0xb0, 0x8b, 0x5b, 0x76, 0x5b, 0x5b,
-- 0x7b, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa8, 0x5e, 0x22, 0x36, 0x21, 0x3a, 0x99, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x4f, 0x3f, 0xb3, 0x7b, 0x7b, 0x85, 0x80,
-- 0x9f, 0x36, 0x36, 0x36, 0x21, 0xb4, 0x7e, 0x7b,
-- 0x64, 0x64, 0xb5, 0x35, 0x24, 0x21, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-- 0x26, 0x31, 0xb6, 0x5b, 0x64, 0xa2, 0xa2, 0xac,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0x66, 0xb7, 0x36, 0x36, 0x36, 0x2c, 0x4b,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x9a, 0x3f, 0xb8, 0x76, 0x76, 0x7a, 0x63,
-- 0xb9, 0xba, 0x86, 0xba, 0xbb, 0x90, 0x5b, 0x64,
-- 0xa2, 0xa2, 0xbc, 0x2d, 0x27, 0x23, 0x21, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-- 0x26, 0x2d, 0x91, 0x5b, 0x64, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa8, 0x83, 0xaf, 0x36, 0x36, 0x36, 0x30,
-- 0x44, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x9b, 0x9a, 0x3f, 0xbd, 0x5b, 0x7b, 0xbe, 0x85,
-- 0x7e, 0x90, 0x63, 0x90, 0x85, 0x5b, 0xa2, 0xa3,
-- 0xa3, 0xac, 0x5d, 0xb5, 0x39, 0x26, 0x23, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-- 0x26, 0x2d, 0xbf, 0xbe, 0x64, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa8, 0x88, 0x36, 0x36, 0x36, 0x36,
-- 0x2d, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x9b, 0x45, 0x3f, 0xc0, 0x6d, 0x7b, 0xab, 0xbe,
-- 0x7a, 0x8b, 0x8b, 0x7a, 0x5b, 0x64, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa2, 0xc1, 0x37, 0x35, 0x26, 0x23,
-- 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-- 0x26, 0x2e, 0xbf, 0x7a, 0x7b, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa8, 0x72, 0x73, 0x36, 0x36, 0x36,
-- 0x24, 0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x46, 0x42, 0xb6, 0x7a, 0x7b, 0x64, 0x7b,
-- 0x76, 0x5b, 0x5b, 0x76, 0x7b, 0xa2, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xac, 0x64, 0xc1, 0x4d, 0x2c, 0x27,
-- 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-- 0x25, 0x31, 0xc2, 0x8b, 0x7b, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa8, 0x89, 0x9f, 0x36, 0x36,
-- 0x32, 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x4b, 0x2f, 0x8f, 0x7a, 0x7b, 0xa2, 0xac,
-- 0xa2, 0x64, 0x64, 0xa2, 0xa2, 0xac, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x5d, 0xc3, 0x2c,
-- 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-- 0x25, 0x31, 0xc2, 0x85, 0x7b, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0x66, 0x57, 0x27, 0x4d,
-- 0x4b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x99, 0x34, 0x9f, 0xb9, 0x7a, 0x7b, 0xa2, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xc2,
-- 0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-- 0x26, 0x2d, 0xc2, 0x85, 0x7b, 0xac, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa8, 0x5f, 0x92, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x44,
-- 0x35, 0x36, 0xaf, 0xbb, 0x7a, 0x7b, 0xac, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0xa2, 0xc0,
-- 0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-- 0x30, 0x2f, 0xb6, 0x8b, 0x7b, 0xac, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x66, 0x89, 0x45,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x4e, 0x25,
-- 0x36, 0x36, 0x61, 0xb9, 0x6d, 0x64, 0xac, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0x7b, 0xbe, 0xc3,
-- 0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-- 0x33, 0xc4, 0x63, 0xbe, 0xa2, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x72, 0x81, 0xc5,
-- 0x46, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x3f, 0x2c, 0x36, 0x36,
-- 0x36, 0x36, 0xc6, 0x8f, 0x6d, 0x64, 0xac, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa2, 0xab, 0x8b, 0xb0, 0x2c,
-- 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-- 0x35, 0x96, 0x75, 0xab, 0xa2, 0xac, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0x7b, 0x81, 0xb9,
-- 0x73, 0x3b, 0x44, 0x9b, 0x48, 0x48, 0x48, 0x9b,
-- 0x99, 0x43, 0x94, 0x2c, 0x21, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x73, 0xb9, 0x7a, 0x7b, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0x64, 0x76, 0x7a, 0x91, 0xb5, 0x31, 0x30,
-- 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-- 0x39, 0x97, 0x75, 0xbe, 0x7b, 0x64, 0xa2, 0xa2,
-- 0xac, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x7b, 0x7a, 0xc7,
-- 0xc8, 0x36, 0x21, 0x26, 0x2b, 0x39, 0x33, 0x30,
-- 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x21, 0xc8, 0xbb, 0x8b, 0x7b, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x64, 0x64,
-- 0x76, 0x85, 0xbf, 0xb5, 0x34, 0x2b, 0x27, 0x28,
-- 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-- 0x33, 0xc9, 0x63, 0x7e, 0x7a, 0x6d, 0xbe, 0x5b,
-- 0x76, 0x7b, 0x64, 0x64, 0xa2, 0xac, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0x76, 0x85, 0xb9,
-- 0x79, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x21, 0xca, 0xbb, 0x75, 0x76, 0xa2, 0xa3,
-- 0xa3, 0xa3, 0xac, 0xa2, 0x64, 0x76, 0xbe, 0x8b,
-- 0xb6, 0xb5, 0x2f, 0x35, 0x30, 0x24, 0x22, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-- 0x27, 0x31, 0xcb, 0xc9, 0xbb, 0x74, 0x63, 0x90,
-- 0x7e, 0x75, 0x8b, 0x6d, 0xbe, 0x76, 0x64, 0xa2,
-- 0xac, 0xac, 0xac, 0xac, 0x64, 0x7a, 0x84, 0xcc,
-- 0x79, 0x9f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x21, 0xc8, 0xcc, 0x63, 0x6d, 0x7b, 0x64,
-- 0xac, 0xa2, 0x64, 0x7b, 0xbe, 0x75, 0x63, 0x96,
-- 0x38, 0x39, 0x2a, 0x24, 0x23, 0x21, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-- 0x28, 0x27, 0x35, 0x2d, 0x41, 0xb5, 0xc5, 0x8f,
-- 0xb9, 0xbb, 0xc7, 0x74, 0x84, 0x90, 0x85, 0x6d,
-- 0x5b, 0x7b, 0x7b, 0xab, 0x6d, 0x90, 0xb9, 0xcd,
-- 0xca, 0x22, 0x36, 0x36, 0x28, 0x30, 0x30, 0x30,
-- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x25, 0x36,
-- 0x36, 0x21, 0xb4, 0x80, 0xc7, 0x7e, 0x6d, 0x76,
-- 0xab, 0x76, 0x6d, 0x85, 0x63, 0xb9, 0xb5, 0x34,
-- 0x33, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x21, 0x23, 0x24, 0x27, 0x2a, 0x35, 0x2e, 0x2f,
-- 0x41, 0xce, 0xcf, 0x6c, 0x80, 0xcc, 0xb9, 0x74,
-- 0x84, 0x90, 0x75, 0x7e, 0x74, 0x8f, 0xcd, 0x79,
-- 0xc6, 0x2b, 0x9d, 0x41, 0x2f, 0x34, 0x2d, 0x2d,
-- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x2f, 0x38,
-- 0x4d, 0x37, 0xd0, 0xd1, 0x8f, 0x74, 0x63, 0x7e,
-- 0x75, 0x7e, 0x63, 0xc7, 0x88, 0xc4, 0x31, 0x2a,
-- 0x24, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x30,
-- 0x33, 0x39, 0x2e, 0x51, 0x41, 0xb2, 0x6c, 0xd1,
-- 0x80, 0xcc, 0xcc, 0xcc, 0xd2, 0xd1, 0xb7, 0xd3,
-- 0x41, 0x34, 0x35, 0x32, 0x30, 0x27, 0x27, 0x27,
-- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x2a,
-- 0x2b, 0x34, 0xd4, 0xca, 0xd5, 0x8f, 0xbb, 0xc7,
-- 0xc7, 0xbb, 0xcc, 0x6c, 0x41, 0x39, 0x27, 0x28,
-- 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22,
-- 0x28, 0x24, 0x26, 0x2a, 0x33, 0x2c, 0x2f, 0x41,
-- 0xd6, 0xb7, 0x79, 0x79, 0x79, 0xca, 0xd7, 0x51,
-- 0x39, 0x30, 0x24, 0x23, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23,
-- 0x24, 0x2a, 0x31, 0xd8, 0xc8, 0x79, 0xd1, 0x80,
-- 0xd5, 0xba, 0xd9, 0x2f, 0x35, 0x26, 0x23, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x21, 0x22, 0x23, 0x28, 0x25, 0x30, 0x2b,
-- 0x31, 0x2f, 0xd4, 0xd8, 0xd8, 0x2f, 0x2e, 0x33,
-- 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x21, 0x28, 0x27, 0x35, 0x34, 0xd8, 0xd8, 0xd8,
-- 0xda, 0xd4, 0x2e, 0x33, 0x25, 0x23, 0x21, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x23, 0x28,
-- 0x26, 0x30, 0x32, 0x2b, 0x33, 0x2a, 0x26, 0x28,
-- 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x21, 0x23, 0x25, 0x30, 0x33, 0x35, 0x35,
-- 0x2b, 0x2a, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-- 0x21, 0x22, 0x23, 0x28, 0x28, 0x23, 0x22, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x21, 0x23, 0x28, 0x24, 0x24,
-- 0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x23, 0x33, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x23, 0x61, 0x62, 0x2B, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x35, 0x61, 0x63, 0x64, 0x35, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x65, 0x66, 0x66, 0x67, 0x55, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x3B,
-+ 0x3B, 0x68, 0x64, 0x69, 0x62, 0x55, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x22, 0x23, 0x23, 0x55, 0x6A, 0x6B,
-+ 0x6C, 0x6D, 0x6E, 0x6F, 0x6F, 0x33, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23,
-+ 0x22, 0x23, 0x35, 0x33, 0x3B, 0x70, 0x71, 0x72,
-+ 0x73, 0x74, 0x75, 0x76, 0x77, 0x55, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x22, 0x23, 0x23, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x23, 0x55,
-+ 0x2B, 0x34, 0x34, 0x42, 0x70, 0x71, 0x73, 0x78,
-+ 0x78, 0x78, 0x79, 0x7A, 0x7B, 0x34, 0x22, 0x21,
-+ 0x55, 0x33, 0x23, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x22, 0x3B, 0x7C, 0x7D, 0x7E, 0x34, 0x35,
-+ 0x21, 0x21, 0x21, 0x21, 0x35, 0x3B, 0x4C, 0x3C,
-+ 0x42, 0x3F, 0x56, 0x7F, 0x71, 0x74, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x79, 0x80, 0x81, 0x3C, 0x82,
-+ 0x83, 0x62, 0x61, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x23, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A,
-+ 0x3B, 0x21, 0x55, 0x55, 0x2B, 0x34, 0x39, 0x3F,
-+ 0x2A, 0x57, 0x8B, 0x72, 0x74, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x75, 0x8C, 0x6F, 0x63,
-+ 0x63, 0x66, 0x61, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x84, 0x85, 0x86, 0x8D, 0x88, 0x8E, 0x8F, 0x5E,
-+ 0x3C, 0x34, 0x3B, 0x34, 0x3F, 0x2A, 0x58, 0x57,
-+ 0x52, 0x46, 0x6C, 0x73, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x79, 0x7A, 0x6E, 0x69,
-+ 0x69, 0x90, 0x34, 0x33, 0x22, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23,
-+ 0x91, 0x92, 0x8D, 0x87, 0x8E, 0x93, 0x8A, 0x35,
-+ 0x94, 0x95, 0x96, 0x56, 0x32, 0x32, 0x52, 0x5C,
-+ 0x4D, 0x82, 0x72, 0x78, 0x78, 0x78, 0x78, 0x79,
-+ 0x97, 0x78, 0x78, 0x78, 0x78, 0x75, 0x6D, 0x6F,
-+ 0x62, 0x65, 0x34, 0x4C, 0x33, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2B,
-+ 0x91, 0x86, 0x87, 0x88, 0x93, 0x98, 0x60, 0x3F,
-+ 0x99, 0x9A, 0x9A, 0x9B, 0x9C, 0x57, 0x5C, 0x36,
-+ 0x9D, 0x9E, 0x6D, 0x78, 0x78, 0x78, 0x97, 0x6E,
-+ 0x9F, 0x78, 0x78, 0x78, 0x78, 0x79, 0x80, 0xA0,
-+ 0x61, 0x51, 0x51, 0x3C, 0x4C, 0x55, 0x35, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x3B, 0x22,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x4C,
-+ 0xA1, 0x8D, 0x88, 0x8E, 0xA2, 0xA3, 0x94, 0x42,
-+ 0x51, 0xA4, 0x9A, 0x9A, 0x9A, 0xA5, 0x9C, 0x2A,
-+ 0xA6, 0x74, 0x8C, 0x75, 0x97, 0xA7, 0x76, 0x75,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x75, 0x6E,
-+ 0x46, 0x52, 0x56, 0x3F, 0x42, 0x34, 0x33, 0x35,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x22,
-+ 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x52, 0x3A,
-+ 0x5A, 0x53, 0x53, 0x29, 0x43, 0x50, 0x53, 0x5A,
-+ 0x5A, 0x29, 0x5A, 0x43, 0x53, 0x5D, 0x44, 0x2A,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x55,
-+ 0x7D, 0x87, 0x8E, 0x93, 0xA8, 0xA9, 0xAA, 0x2A,
-+ 0x57, 0x94, 0xA4, 0x9B, 0xAB, 0xAC, 0x9A, 0x9B,
-+ 0xAD, 0x76, 0x79, 0x78, 0x75, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x75, 0x6D,
-+ 0x46, 0x5C, 0x57, 0x56, 0x51, 0x42, 0x4C, 0x55,
-+ 0x23, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x23, 0x24, 0x25, 0x26, 0x26, 0x27, 0x28, 0x27,
-+ 0x29, 0x2A, 0x2B, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x38, 0x30,
-+ 0x59, 0x3D, 0x3D, 0x3D, 0x27, 0x27, 0x26, 0x5D,
-+ 0x27, 0x27, 0x54, 0x37, 0x2E, 0x4A, 0x36, 0x2B,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0xAE, 0x88, 0xAF, 0xB0, 0xAA, 0x2A, 0x39, 0x34,
-+ 0x4C, 0x5C, 0x58, 0xB1, 0xB2, 0xB3, 0xAB, 0xA5,
-+ 0x9A, 0xB4, 0xB5, 0x8C, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x80,
-+ 0xB6, 0x38, 0x5C, 0x57, 0x56, 0x3F, 0x42, 0x3B,
-+ 0x55, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23,
-+ 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x32,
-+ 0x31, 0x2C, 0x26, 0x2C, 0x33, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x34,
-+ 0x32, 0x2B, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x33,
-+ 0x33, 0x55, 0x55, 0x55, 0x23, 0x23, 0x35, 0x23,
-+ 0x23, 0x35, 0x2B, 0x4E, 0x4F, 0x2A, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x55, 0x38, 0x25,
-+ 0x2C, 0x52, 0x34, 0x22, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x55, 0x8A, 0x8F, 0x39, 0x34, 0x3C, 0x57, 0x32,
-+ 0x46, 0x42, 0x52, 0x4A, 0x51, 0xAA, 0xB7, 0xB3,
-+ 0xAB, 0xAC, 0xAC, 0xB8, 0xB9, 0x79, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x7A,
-+ 0xBA, 0x70, 0x7B, 0xBB, 0x82, 0x56, 0x3F, 0x34,
-+ 0x4C, 0x55, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35, 0x36,
-+ 0x2D, 0x37, 0x38, 0x2A, 0x2B, 0x21, 0x21, 0x21,
-+ 0x21, 0x22, 0x39, 0x3A, 0x2C, 0x3B, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x33, 0x3C, 0x22, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x24, 0x3D,
-+ 0x3E, 0x25, 0x3C, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x33, 0x29, 0x26, 0x2A, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x3B, 0x54, 0x3E, 0x28,
-+ 0x28, 0x59, 0x59, 0x48, 0x51, 0x3F, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x2B, 0x56, 0x4D, 0x29, 0x5B, 0x34,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x55, 0x60, 0x3F, 0x42, 0x51, 0x32, 0x52,
-+ 0x40, 0x38, 0x40, 0x46, 0x42, 0xBC, 0xBD, 0xBE,
-+ 0xBF, 0x9B, 0xAB, 0x9B, 0xC0, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x75,
-+ 0xA7, 0x63, 0x63, 0x66, 0x6F, 0x58, 0x56, 0x39,
-+ 0x34, 0x2B, 0x23, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x24, 0x2F,
-+ 0x3D, 0x3F, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x22, 0x40, 0x41, 0x3B, 0x21,
-+ 0x21, 0x22, 0x42, 0x38, 0x43, 0x44, 0x3A, 0x45,
-+ 0x34, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x46, 0x30, 0x47,
-+ 0x2A, 0x48, 0x48, 0x21, 0x21, 0x21, 0x21, 0x22,
-+ 0x23, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x22, 0x34, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x22, 0x4D, 0x44, 0x2A, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x22, 0x50, 0x4A, 0x57, 0x35,
-+ 0x35, 0x2B, 0x56, 0x27, 0x4B, 0x5D, 0x35, 0x21,
-+ 0x21, 0x21, 0x21, 0x3B, 0x52, 0x23, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2B,
-+ 0x55, 0x21, 0x21, 0x21, 0x21, 0x21, 0x3B, 0x38,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x33,
-+ 0x3C, 0x42, 0x21, 0x33, 0x24, 0x35, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x33,
-+ 0x2B, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x33, 0x38, 0x59, 0x37, 0x27, 0x27, 0x4A, 0x47,
-+ 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x23, 0x4C, 0x4C, 0x2A, 0x56, 0x46, 0x31,
-+ 0x4D, 0x36, 0x50, 0x5A, 0x35, 0xC1, 0xC1, 0xC2,
-+ 0xC3, 0xB7, 0xB3, 0xBE, 0x76, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x75,
-+ 0x6D, 0x62, 0x69, 0x6F, 0x58, 0x46, 0x32, 0x2A,
-+ 0x39, 0x34, 0x35, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x3B, 0x44, 0x49,
-+ 0x31, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x23, 0x29, 0x48, 0x22,
-+ 0x42, 0x3A, 0x4A, 0x49, 0x4B, 0x2E, 0x4B, 0x3E,
-+ 0x4A, 0x2C, 0x34, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x4C, 0x30, 0x40, 0x22,
-+ 0x21, 0x32, 0x3A, 0x22, 0x21, 0x21, 0x21, 0x39,
-+ 0x36, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22,
-+ 0x31, 0x4F, 0x2A, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x31, 0x59, 0x2A, 0x22, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x55, 0x27, 0x24, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x4C, 0x44, 0x27, 0x35, 0x21,
-+ 0x21, 0x21, 0x21, 0x2A, 0x26, 0x2B, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x3A,
-+ 0x40, 0x21, 0x21, 0x21, 0x21, 0x21, 0x51, 0x49,
-+ 0x35, 0x21, 0x21, 0x21, 0x21, 0x22, 0x58, 0x25,
-+ 0x5A, 0x57, 0x21, 0x4C, 0x3D, 0x34, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x38,
-+ 0x47, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35,
-+ 0x3A, 0x4B, 0x53, 0x56, 0x55, 0x33, 0x42, 0x56,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x55, 0x4C, 0x42, 0x2A, 0x57, 0x5C, 0x38,
-+ 0x36, 0x47, 0x5A, 0xB6, 0x77, 0xC4, 0xC1, 0xC1,
-+ 0xC4, 0xC5, 0xB7, 0xB9, 0x79, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x75,
-+ 0x97, 0xC6, 0x68, 0x57, 0x4D, 0x38, 0x46, 0x32,
-+ 0x51, 0x42, 0x2B, 0x35, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x4D, 0x2D, 0x38,
-+ 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x4C, 0x4E, 0x3C,
-+ 0x47, 0x4F, 0x50, 0x51, 0x3F, 0x44, 0x42, 0x34,
-+ 0x52, 0x53, 0x28, 0x2A, 0x22, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x48, 0x54, 0x33, 0x21,
-+ 0x23, 0x3A, 0x3A, 0x22, 0x21, 0x21, 0x21, 0x2A,
-+ 0x26, 0x33, 0x21, 0x21, 0x21, 0x21, 0x23, 0x45,
-+ 0x37, 0x3D, 0x41, 0x22, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x31,
-+ 0x59, 0x3F, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x3C, 0x28, 0x33, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x23, 0x27, 0x5B, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x3C, 0x54, 0x55, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x4C, 0x4B,
-+ 0x46, 0x21, 0x21, 0x21, 0x21, 0x21, 0x3B, 0x49,
-+ 0x2B, 0x21, 0x21, 0x21, 0x23, 0x40, 0x43, 0x32,
-+ 0x35, 0x21, 0x21, 0x33, 0x28, 0x4C, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x4F,
-+ 0x5B, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x50,
-+ 0x44, 0x39, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x23, 0x3B, 0x34, 0x3F, 0x58, 0x46, 0x40, 0x36,
-+ 0x50, 0x41, 0x4D, 0xC7, 0x65, 0xC2, 0xC1, 0xC1,
-+ 0xC8, 0xBF, 0xB1, 0x97, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79,
-+ 0x80, 0xC9, 0x36, 0x50, 0x36, 0x38, 0x31, 0x32,
-+ 0x56, 0x39, 0x34, 0x33, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x2B, 0x3D, 0x28, 0x35,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x40, 0x4D,
-+ 0x55, 0x2B, 0x21, 0x21, 0x2B, 0x28, 0x3B, 0x21,
-+ 0x21, 0x22, 0x52, 0x27, 0x56, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x23, 0x2A, 0x30, 0x3F, 0x21, 0x22,
-+ 0x57, 0x44, 0x58, 0x21, 0x21, 0x21, 0x21, 0x56,
-+ 0x37, 0x2B, 0x21, 0x21, 0x21, 0x21, 0x56, 0x3E,
-+ 0x36, 0x2A, 0x59, 0x23, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x33, 0x50, 0x3D,
-+ 0x42, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x40, 0x5A, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x56, 0x49, 0x24, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x42, 0x54, 0x33, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x4D, 0x59,
-+ 0x55, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35, 0x4A,
-+ 0x51, 0x21, 0x21, 0x33, 0x47, 0x47, 0x33, 0x21,
-+ 0x21, 0x21, 0x21, 0x55, 0x27, 0x3B, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x32, 0x4B,
-+ 0x4C, 0x21, 0x21, 0x21, 0x21, 0x21, 0x34, 0x44,
-+ 0x3F, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x33, 0x4C, 0x3C, 0x51, 0x57, 0x5C, 0x38, 0x38,
-+ 0x9D, 0xCA, 0x61, 0xCB, 0xCC, 0xCD, 0xC4, 0xC8,
-+ 0xA4, 0x9C, 0x76, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79,
-+ 0x7A, 0x7F, 0x41, 0x29, 0x47, 0x38, 0x40, 0x57,
-+ 0x32, 0x51, 0x42, 0x2B, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x57, 0x49, 0x32, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x57, 0x27,
-+ 0x35, 0x21, 0x21, 0x21, 0x2B, 0x59, 0x2A, 0x21,
-+ 0x21, 0x21, 0x21, 0x56, 0x54, 0x2B, 0x21, 0x21,
-+ 0x21, 0x21, 0x4C, 0x2E, 0x5A, 0x23, 0x55, 0x5B,
-+ 0x49, 0x3A, 0x22, 0x21, 0x21, 0x21, 0x21, 0x32,
-+ 0x3E, 0x3B, 0x21, 0x21, 0x21, 0x35, 0x54, 0x53,
-+ 0x23, 0x55, 0x4F, 0x55, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x4C, 0x25, 0x44, 0x42,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x23, 0x41, 0x46, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x23, 0x53, 0x2F, 0x2A, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x32, 0x28, 0x33, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x35, 0x59, 0x5B,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x54,
-+ 0x57, 0x21, 0x35, 0x53, 0x47, 0x23, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x3C, 0x44, 0x3B, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x41, 0x43,
-+ 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x3F, 0x29,
-+ 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x55, 0x4C, 0x3F, 0x2A, 0x46, 0x31, 0x36, 0x46,
-+ 0x71, 0x97, 0xCE, 0xCB, 0xCF, 0xA4, 0x9C, 0xA4,
-+ 0xAD, 0x76, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x80, 0x8C,
-+ 0x7A, 0xA7, 0x36, 0x50, 0x3A, 0x36, 0x38, 0x52,
-+ 0x32, 0x2A, 0x3F, 0x2B, 0x22, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x22, 0x5A, 0x5A, 0x23, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x52, 0x28,
-+ 0x35, 0x21, 0x21, 0x21, 0x55, 0x30, 0x56, 0x21,
-+ 0x21, 0x21, 0x21, 0x22, 0x5B, 0x45, 0x21, 0x21,
-+ 0x21, 0x21, 0x2B, 0x2E, 0x25, 0x47, 0x3D, 0x2D,
-+ 0x25, 0x4C, 0x21, 0x21, 0x21, 0x21, 0x21, 0x39,
-+ 0x44, 0x55, 0x21, 0x21, 0x21, 0x46, 0x59, 0x3B,
-+ 0x21, 0x23, 0x30, 0x34, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x2A, 0x28, 0x4E, 0x42, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x3C, 0x3D, 0x42, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x51, 0x4B, 0x49, 0x39, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x5C, 0x25, 0x23, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x38, 0x4B, 0x3B,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x54,
-+ 0x56, 0x21, 0x5B, 0x3A, 0x35, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x51, 0x59, 0x55, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x32, 0x2D, 0x42,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x4C, 0x3A,
-+ 0x23, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x2B, 0x3C, 0x39, 0x56, 0x46, 0x40, 0x36, 0xB6,
-+ 0x73, 0x82, 0xCB, 0xD0, 0x75, 0xD1, 0xD2, 0xD1,
-+ 0x8C, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x74, 0xCE,
-+ 0x9E, 0x6E, 0xD3, 0xC6, 0x6F, 0x81, 0x38, 0x5C,
-+ 0x52, 0x58, 0x39, 0x4C, 0x35, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x4C, 0x4A, 0x40, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x36, 0x3A,
-+ 0x21, 0x21, 0x21, 0x21, 0x55, 0x27, 0x3F, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x3B, 0x25, 0x3B, 0x21,
-+ 0x21, 0x21, 0x42, 0x2E, 0x2D, 0x2D, 0x26, 0x46,
-+ 0x35, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x51,
-+ 0x44, 0x55, 0x21, 0x21, 0x35, 0x25, 0x40, 0x21,
-+ 0x21, 0x22, 0x4E, 0x58, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x39, 0x59, 0x38, 0x35, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x56, 0x59, 0x23, 0x21, 0x21, 0x21,
-+ 0x21, 0x4C, 0x54, 0x5B, 0x59, 0x4C, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x57, 0x3A, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x22, 0x4D, 0x49, 0x26, 0x23,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x53,
-+ 0x32, 0x51, 0x27, 0x42, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x42, 0x25, 0x35, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x22, 0x24, 0x37, 0x3E, 0x35,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x48,
-+ 0x48, 0x33, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x33,
-+ 0x3B, 0x39, 0x3F, 0x32, 0x5C, 0x38, 0x47, 0xD4,
-+ 0x7A, 0xC7, 0xCB, 0xD0, 0x74, 0x80, 0x8C, 0x9F,
-+ 0x80, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x73, 0x72, 0xD5, 0xCA, 0x61, 0xD3, 0x40, 0x5C,
-+ 0x46, 0x58, 0x51, 0x42, 0x33, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x39, 0x4B, 0x58, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x2A, 0x3D, 0x51,
-+ 0x21, 0x21, 0x21, 0x21, 0x55, 0x28, 0x42, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x47, 0x52, 0x21,
-+ 0x21, 0x21, 0x58, 0x59, 0x42, 0x3C, 0x35, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x57,
-+ 0x4E, 0x23, 0x21, 0x22, 0x4D, 0x54, 0x35, 0x21,
-+ 0x21, 0x21, 0x5A, 0x46, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x22, 0x56, 0x59, 0x36, 0x35, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x36, 0x5B, 0x21, 0x21, 0x21, 0x21,
-+ 0x23, 0x53, 0x48, 0x3F, 0x27, 0x55, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x24, 0x47, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x22, 0x40, 0x27, 0x29, 0x29, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x47,
-+ 0x40, 0x41, 0x5C, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x39, 0x41, 0x23, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x32, 0x26, 0x47, 0x28, 0x22,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2B,
-+ 0x53, 0x28, 0x36, 0x42, 0x23, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35,
-+ 0x4C, 0x39, 0x58, 0x32, 0x31, 0x38, 0x47, 0xD4,
-+ 0xCF, 0xD0, 0x6C, 0x9E, 0xD6, 0x6B, 0xD7, 0xD8,
-+ 0xD7, 0x6B, 0xCF, 0x7B, 0x80, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x74, 0x72, 0xD0, 0xA6, 0x70, 0x51,
-+ 0x46, 0x56, 0x51, 0x42, 0x55, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x5C, 0x27, 0x35, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x32, 0x37, 0x54, 0x33,
-+ 0x21, 0x21, 0x21, 0x21, 0x2B, 0x44, 0x2A, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x52, 0x2C, 0x21,
-+ 0x21, 0x21, 0x47, 0x36, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x52,
-+ 0x54, 0x23, 0x21, 0x24, 0x4F, 0x46, 0x21, 0x21,
-+ 0x21, 0x21, 0x38, 0x2C, 0x22, 0x21, 0x21, 0x21,
-+ 0x21, 0x42, 0x55, 0x21, 0x21, 0x21, 0x21, 0x33,
-+ 0x45, 0x54, 0x56, 0x22, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x22, 0x53, 0x24, 0x21, 0x21, 0x21, 0x21,
-+ 0x46, 0x5D, 0x4C, 0x52, 0x4E, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x31, 0x48, 0x22, 0x21, 0x21,
-+ 0x21, 0x22, 0x46, 0x54, 0x3B, 0x45, 0x29, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x47,
-+ 0x28, 0x28, 0x55, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x51, 0x41, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x56, 0x54, 0x39, 0x56, 0x28, 0x22,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x23, 0x34, 0x50, 0x30, 0x4E, 0x40, 0x34, 0x22,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35,
-+ 0x4C, 0x39, 0x58, 0x52, 0x5C, 0x38, 0x47, 0x9D,
-+ 0xC9, 0xD9, 0xDA, 0xDB, 0xDC, 0xDC, 0xDC, 0xDC,
-+ 0xDC, 0xDC, 0xDC, 0xDD, 0x6B, 0x7B, 0x75, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x74, 0x71, 0xD0, 0x3F,
-+ 0x52, 0x57, 0x2A, 0x42, 0x2B, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x47, 0x3A, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x35, 0x45, 0x4A, 0x2C, 0x3B, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x2B, 0x30, 0x56, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x58, 0x29, 0x21,
-+ 0x21, 0x21, 0x53, 0x3F, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x31,
-+ 0x43, 0x22, 0x3B, 0x28, 0x48, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x56, 0x25, 0x35, 0x21, 0x21, 0x21,
-+ 0x39, 0x54, 0x34, 0x21, 0x21, 0x21, 0x35, 0x3A,
-+ 0x30, 0x57, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x33, 0x39, 0x21, 0x21,
-+ 0x21, 0x35, 0x25, 0x3F, 0x21, 0x21, 0x21, 0x56,
-+ 0x30, 0x58, 0x21, 0x24, 0x43, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x4D, 0x29, 0x22, 0x21, 0x21,
-+ 0x22, 0x32, 0x26, 0x42, 0x21, 0x46, 0x2C, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x48,
-+ 0x2E, 0x36, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x56, 0x28, 0x35, 0x21, 0x21,
-+ 0x21, 0x3F, 0x27, 0x32, 0x21, 0x51, 0x25, 0x22,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x22, 0x39, 0x38, 0x25, 0x54, 0x50,
-+ 0x58, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x33,
-+ 0x4C, 0x3F, 0x56, 0x52, 0x31, 0x4D, 0x47, 0x39,
-+ 0xD8, 0xDC, 0xDC, 0xDC, 0xDE, 0xDF, 0xDF, 0xDF,
-+ 0xDF, 0xDF, 0xDE, 0xDE, 0xDC, 0xDD, 0xD6, 0x97,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x75, 0x97, 0x56,
-+ 0x46, 0x57, 0x2A, 0x42, 0x2B, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x38, 0x29, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x35, 0x5B, 0x3D, 0x40, 0x35, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x2B, 0x59, 0x3F, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x40, 0x5A, 0x21,
-+ 0x21, 0x22, 0x5D, 0x34, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x5B,
-+ 0x2C, 0x33, 0x29, 0x28, 0x3B, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x34, 0x59, 0x3C, 0x21, 0x21, 0x2B,
-+ 0x53, 0x36, 0x22, 0x21, 0x21, 0x34, 0x5A, 0x28,
-+ 0x3F, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x40, 0x41, 0x23, 0x21,
-+ 0x21, 0x3B, 0x28, 0x2B, 0x21, 0x21, 0x2A, 0x44,
-+ 0x38, 0x22, 0x21, 0x24, 0x50, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x50, 0x25, 0x23, 0x21, 0x23,
-+ 0x45, 0x5D, 0x52, 0x21, 0x21, 0x40, 0x50, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x50,
-+ 0x2D, 0x39, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x46, 0x30, 0x33, 0x21, 0x22,
-+ 0x24, 0x4E, 0x45, 0x22, 0x21, 0x58, 0x25, 0x22,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x33, 0x3C, 0x48,
-+ 0x27, 0x39, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35,
-+ 0x34, 0x3F, 0x58, 0x57, 0x31, 0x4D, 0x47, 0x56,
-+ 0xDB, 0xDC, 0xDE, 0xE0, 0xE1, 0xE2, 0xE2, 0xE2,
-+ 0xE2, 0xE2, 0xE1, 0xE3, 0xE4, 0xDE, 0xDC, 0x6B,
-+ 0x8C, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x80, 0xA7, 0x38,
-+ 0x46, 0x56, 0x2A, 0x39, 0x3B, 0x23, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x32, 0x44, 0x34, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x3F,
-+ 0x4D, 0x41, 0x29, 0x42, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x2B, 0x44, 0x46, 0x34,
-+ 0x2B, 0x55, 0x55, 0x2B, 0x56, 0x59, 0x36, 0x21,
-+ 0x21, 0x22, 0x59, 0x2B, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x55, 0x5C, 0x21, 0x21, 0x21, 0x40,
-+ 0x50, 0x4D, 0x4F, 0x32, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x55, 0x44, 0x31, 0x22, 0x3B, 0x5A,
-+ 0x41, 0x55, 0x21, 0x35, 0x57, 0x4A, 0x2E, 0x48,
-+ 0x57, 0x32, 0x3F, 0x55, 0x35, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x25, 0x47, 0x22, 0x21,
-+ 0x21, 0x4C, 0x28, 0x35, 0x21, 0x34, 0x30, 0x3A,
-+ 0x23, 0x21, 0x21, 0x58, 0x3A, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x4D, 0x4E, 0x35, 0x33, 0x48,
-+ 0x44, 0x56, 0x21, 0x21, 0x21, 0x58, 0x41, 0x23,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x29,
-+ 0x4A, 0x23, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x32, 0x44, 0x2B, 0x23, 0x45,
-+ 0x3D, 0x31, 0x22, 0x21, 0x21, 0x4C, 0x27, 0x35,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35,
-+ 0x53, 0x53, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35,
-+ 0x34, 0x3F, 0x58, 0x57, 0x40, 0x38, 0x47, 0xD4,
-+ 0xDC, 0xDE, 0xE0, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE2, 0xE1, 0xDF, 0xDC,
-+ 0xE6, 0x8C, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x80, 0x2A, 0x40,
-+ 0x46, 0x58, 0x2A, 0x42, 0x34, 0x34, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x2B, 0x54, 0x5A, 0x34, 0x23,
-+ 0x35, 0x23, 0x35, 0x33, 0x2B, 0x24, 0x54, 0x4B,
-+ 0x59, 0x5C, 0x23, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x4C, 0x4B, 0x44, 0x59,
-+ 0x27, 0x26, 0x26, 0x4A, 0x3E, 0x41, 0x55, 0x21,
-+ 0x21, 0x22, 0x41, 0x39, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x34, 0x53, 0x4D, 0x21, 0x21, 0x21, 0x5C,
-+ 0x4B, 0x4F, 0x40, 0x22, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x48, 0x30, 0x50, 0x26, 0x54,
-+ 0x34, 0x21, 0x55, 0x4E, 0x2D, 0x2F, 0x4F, 0x37,
-+ 0x3E, 0x4B, 0x4B, 0x30, 0x27, 0x53, 0x2C, 0x57,
-+ 0x42, 0x4C, 0x55, 0x22, 0x22, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x39, 0x4A, 0x3F, 0x21, 0x21,
-+ 0x21, 0x55, 0x53, 0x55, 0x2A, 0x26, 0x54, 0x33,
-+ 0x21, 0x21, 0x21, 0x51, 0x54, 0x3B, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x51, 0x3D, 0x46, 0x5A, 0x4F,
-+ 0x52, 0x21, 0x21, 0x21, 0x21, 0x22, 0x27, 0x31,
-+ 0x33, 0x23, 0x42, 0x4C, 0x21, 0x21, 0x21, 0x5B,
-+ 0x54, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x3B, 0x44, 0x45, 0x48, 0x4B,
-+ 0x38, 0x22, 0x21, 0x21, 0x21, 0x21, 0x53, 0x48,
-+ 0x33, 0x23, 0x34, 0x3C, 0x22, 0x57, 0x4D, 0x33,
-+ 0x21, 0x21, 0x21, 0x21, 0x22, 0x23, 0x34, 0x40,
-+ 0x44, 0x31, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35,
-+ 0x3B, 0x42, 0x2A, 0x57, 0x31, 0x38, 0x5C, 0xD8,
-+ 0xDC, 0xE4, 0xE2, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE2, 0xE0,
-+ 0xDE, 0xCA, 0x9F, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x80, 0x76, 0x57, 0x5C,
-+ 0x31, 0x6E, 0x34, 0x3C, 0xC9, 0x3B, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x33, 0x5B, 0x30, 0x25,
-+ 0x5D, 0x5A, 0x53, 0x27, 0x26, 0x59, 0x36, 0x56,
-+ 0x55, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x3B, 0x3D, 0x2A, 0x55,
-+ 0x42, 0x51, 0x56, 0x24, 0x2A, 0x35, 0x21, 0x21,
-+ 0x21, 0x21, 0x45, 0x53, 0x3B, 0x22, 0x22, 0x35,
-+ 0x46, 0x59, 0x54, 0x55, 0x21, 0x21, 0x21, 0x31,
-+ 0x2D, 0x47, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x33, 0x50, 0x5D, 0x45, 0x55,
-+ 0x21, 0x21, 0x34, 0x4F, 0x29, 0x58, 0x33, 0x4C,
-+ 0x39, 0x3C, 0x2A, 0x40, 0x48, 0x54, 0x3D, 0x3D,
-+ 0x37, 0x4A, 0x59, 0x29, 0x5B, 0x36, 0x52, 0x2A,
-+ 0x42, 0x3C, 0x32, 0x30, 0x41, 0x35, 0x21, 0x21,
-+ 0x21, 0x33, 0x41, 0x26, 0x4B, 0x5A, 0x35, 0x21,
-+ 0x21, 0x21, 0x21, 0x3C, 0x3E, 0x41, 0x23, 0x21,
-+ 0x21, 0x21, 0x21, 0x23, 0x41, 0x49, 0x30, 0x32,
-+ 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x52, 0x4F,
-+ 0x5D, 0x41, 0x27, 0x58, 0x21, 0x21, 0x21, 0x5B,
-+ 0x41, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x47, 0x49, 0x4F, 0x5C,
-+ 0x23, 0x21, 0x21, 0x21, 0x21, 0x21, 0x39, 0x4A,
-+ 0x28, 0x43, 0x27, 0x5C, 0x35, 0x25, 0x49, 0x5B,
-+ 0x58, 0x52, 0x5C, 0x38, 0x48, 0x41, 0x4A, 0x4B,
-+ 0x50, 0x33, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35,
-+ 0x3B, 0x3C, 0x2A, 0x32, 0x5C, 0x40, 0x32, 0xDD,
-+ 0xDC, 0xE3, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE1, 0xE0, 0xBB, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x80, 0xE7, 0x58, 0x52,
-+ 0x5C, 0x67, 0xE7, 0x6C, 0xE8, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x23, 0x39, 0x5C,
-+ 0x29, 0x5A, 0x4D, 0x5C, 0x2A, 0x2B, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x3B, 0x44, 0x42, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x33, 0x27, 0x30, 0x5A, 0x2C, 0x25,
-+ 0x4B, 0x50, 0x3B, 0x21, 0x21, 0x21, 0x21, 0x33,
-+ 0x2C, 0x3B, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x4C, 0x22, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x55, 0x2B,
-+ 0x39, 0x32, 0x4D, 0x29, 0x26, 0x3D, 0x2D, 0x2D,
-+ 0x4B, 0x4B, 0x2F, 0x30, 0x42, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x3B, 0x29, 0x2C, 0x55, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x23, 0x50, 0x4D, 0x22, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x2B, 0x32, 0x3B, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x51,
-+ 0x48, 0x45, 0x34, 0x21, 0x21, 0x21, 0x21, 0x38,
-+ 0x44, 0x35, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x33, 0x32, 0x34, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x3C,
-+ 0x5B, 0x4D, 0x42, 0x21, 0x21, 0x34, 0x4D, 0x47,
-+ 0x5A, 0x5D, 0x27, 0x4E, 0x25, 0x3A, 0x5C, 0x42,
-+ 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23,
-+ 0x2B, 0x34, 0x51, 0x56, 0x46, 0x40, 0xE9, 0xDA,
-+ 0xDD, 0xE1, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE2, 0xEA, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x76, 0xD3, 0x67, 0x39,
-+ 0x3C, 0xCF, 0xD5, 0x9F, 0x3B, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x3B, 0x28, 0x2B, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x3C, 0x53, 0x44, 0x3D, 0x43,
-+ 0x57, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x35, 0x55, 0x3F, 0x2A,
-+ 0x57, 0x24, 0x3F, 0x3B, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x55,
-+ 0x3C, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x55, 0x4C, 0x3F, 0x58, 0x46, 0x31, 0x8B, 0xAD,
-+ 0xCC, 0xE2, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xEA, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x97, 0x35, 0x6E, 0xC6, 0x82,
-+ 0xA6, 0x73, 0x75, 0xBA, 0x2B, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x34, 0x44, 0x3B, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x23, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x33, 0x34, 0xEB, 0x34, 0x57, 0x5C, 0x4C, 0xA4,
-+ 0xEC, 0x64, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0x83, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x80, 0xED, 0xCF, 0xCE, 0x78, 0x78,
-+ 0x78, 0x7A, 0x6D, 0x34, 0x22, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x55, 0x25, 0x55, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x23, 0x34, 0xEE, 0xEF, 0x5F, 0x96, 0x23, 0xB3,
-+ 0xBF, 0xB5, 0xF0, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xBB, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x9F, 0x78, 0x78, 0x78, 0x78,
-+ 0x80, 0x9F, 0x65, 0x33, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x3B, 0x28, 0x55, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x22, 0x4C, 0xF1, 0xA5, 0xAC, 0xAB, 0x60, 0xB3,
-+ 0xB3, 0xF2, 0xEA, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xF3, 0x6D, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x80, 0x61, 0x34, 0x23, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x3B, 0x25, 0x22, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2B, 0x5E,
-+ 0x4C, 0x3B, 0xF4, 0xA5, 0x9B, 0x9B, 0xB4, 0xEF,
-+ 0xEF, 0xBF, 0xAD, 0xF5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0x67, 0x75, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x80,
-+ 0xA7, 0x3F, 0x55, 0x22, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x4C, 0x4E, 0x23, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2B, 0x5F,
-+ 0x9B, 0xD2, 0x3C, 0xB7, 0xEF, 0xEF, 0xEF, 0xEF,
-+ 0xEF, 0xB3, 0xB8, 0xEA, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xF0, 0xBB, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x80, 0x82,
-+ 0x34, 0x3B, 0x33, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x4C, 0x5D, 0x23, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x60,
-+ 0xAB, 0xA5, 0xB8, 0xB1, 0xEF, 0xEF, 0xEF, 0xEF,
-+ 0xEF, 0xF6, 0xB7, 0xB5, 0xF0, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0x67, 0x80, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x80, 0x9F, 0xBA, 0x42,
-+ 0x4C, 0x2B, 0x22, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x4C, 0x3A, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x55,
-+ 0xF2, 0x9B, 0x9B, 0xB4, 0xEF, 0xEF, 0xEF, 0xEF,
-+ 0xEF, 0xEF, 0xB4, 0x5F, 0x63, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xF5,
-+ 0x76, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x80, 0x6D, 0x65, 0x3C, 0x34,
-+ 0x3B, 0x35, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x2A, 0x29, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23,
-+ 0xF7, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
-+ 0xEF, 0xEF, 0xB3, 0xB8, 0xEA, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xF8, 0x68,
-+ 0x7A, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x80, 0x97, 0x82, 0x39, 0x39, 0x34, 0x3B,
-+ 0x33, 0x23, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x2A, 0x29, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x3B, 0xB8, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
-+ 0xEF, 0xEF, 0xF6, 0xB2, 0xF9, 0xFA, 0xFA, 0xFA,
-+ 0xFA, 0xF8, 0xF8, 0xF8, 0xF0, 0xF0, 0x6F, 0x97,
-+ 0x80, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x8C, 0x61, 0x39, 0x2A, 0x3F, 0x3C, 0x4C, 0x55,
-+ 0x33, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x4C, 0x31, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x22, 0xFB, 0xF6, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
-+ 0xEF, 0xEF, 0xB3, 0xB2, 0xF9, 0xF3, 0xF3, 0xF3,
-+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0x90, 0x6D, 0x97,
-+ 0x8C, 0x6D, 0x76, 0xBB, 0xC6, 0xB9, 0xC0, 0xFC,
-+ 0xAD, 0xFB, 0x2A, 0x58, 0x42, 0x4C, 0x55, 0x33,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x33, 0xD2, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
-+ 0xEF, 0xEF, 0xB4, 0xB8, 0xEB, 0xE8, 0x7F, 0xD6,
-+ 0xD6, 0xD6, 0xD6, 0x9D, 0x9D, 0x52, 0xEB, 0x5F,
-+ 0x5F, 0x5F, 0xF2, 0xA4, 0xBF, 0xBF, 0xB4, 0xBF,
-+ 0xEE, 0x56, 0x2A, 0x42, 0x4C, 0x2B, 0x33, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x4C, 0xBE, 0xF6, 0xEF, 0xEF, 0xEF,
-+ 0xF6, 0xB4, 0xB2, 0xF1, 0x3C, 0x56, 0x46, 0x5C,
-+ 0x31, 0x38, 0x40, 0x40, 0x4D, 0x4D, 0xB8, 0xAC,
-+ 0xBF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xB4,
-+ 0xB1, 0x39, 0x39, 0x3B, 0x2B, 0x23, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x3B, 0xAD, 0xA4, 0xBF, 0xBF,
-+ 0xB7, 0xB2, 0xEE, 0x5E, 0x39, 0x51, 0x2A, 0x32,
-+ 0x52, 0x46, 0x5C, 0x31, 0x31, 0x2A, 0xA5, 0xEF,
-+ 0xFD, 0xB4, 0xEF, 0xF6, 0xF6, 0xEF, 0xF6, 0xB2,
-+ 0x3F, 0x34, 0x2B, 0x55, 0x23, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x33, 0xEB, 0xF7, 0xAA,
-+ 0xAA, 0xF7, 0xEB, 0x55, 0x3B, 0x3C, 0x39, 0x51,
-+ 0x2A, 0x56, 0x32, 0x57, 0x57, 0x2A, 0x96, 0x3C,
-+ 0x2A, 0xEE, 0xEF, 0x5F, 0xD2, 0xEF, 0xB4, 0xAA,
-+ 0x42, 0x55, 0x35, 0x22, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x3B,
-+ 0x3B, 0x35, 0x21, 0x23, 0x33, 0x3B, 0x4C, 0x3C,
-+ 0x39, 0x3F, 0x51, 0x2A, 0x51, 0x51, 0x58, 0x32,
-+ 0x56, 0xF4, 0xB1, 0x42, 0x3C, 0xF2, 0x9C, 0x3F,
-+ 0x33, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x33, 0x55,
-+ 0x3B, 0x4C, 0x4C, 0x3C, 0x42, 0x42, 0x3C, 0x34,
-+ 0x34, 0x3F, 0x4C, 0x3B, 0x4C, 0x3B, 0x3C, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x35, 0x33, 0x55, 0x33, 0x33, 0x33, 0x55, 0x2B,
-+ 0x2B, 0x35, 0x35, 0x35, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
- };
-
- #endif /* !__HAVE_ARCH_LINUX_LOGO */
-@@ -994,7 +1760,7 @@
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
- };
-
- #endif /* !__HAVE_ARCH_LINUX_LOGOBW */
-@@ -1401,7 +2167,7 @@
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
-
- #endif /* !__HAVE_ARCH_LINUX_LOGO16 */
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/mkdep.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/mkdep.patch
deleted file mode 100644
index 4daeaa11be..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/mkdep.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-
-#
-# Made by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux/Makefile~mkdep 2003-12-19 09:36:51.000000000 -0800
-+++ linux/Makefile 2003-12-19 09:57:44.000000000 -0800
-@@ -458,7 +458,7 @@
-
- dep-files: scripts/mkdep archdep include/linux/version.h
- scripts/mkdep -- init/*.c > .depend
-- scripts/mkdep -- `find $(FINDHPATH) -name SCCS -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend
-+ $(foreach, dir, $(FINDHPATH), scripts/mkdep -- `find $(dir) -name SCCS -prune -o -follow -name \*.h ! -name modversions.h -print` >> .hdepend)
- $(MAKE) $(patsubst %,_sfdep_%,$(SUBDIRS)) _FASTDEP_ALL_SUB_DIRS="$(SUBDIRS)"
- ifdef CONFIG_MODVERSIONS
- $(MAKE) update-modverfile
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/module_licence.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/module_licence.patch
deleted file mode 100644
index e70fc28031..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/module_licence.patch
+++ /dev/null
@@ -1,96 +0,0 @@
-
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- linux/drivers/usb/device/bi/sa1100.c~modulelicence
-+++ linux/drivers/usb/device/bi/sa1100.c
-@@ -43,6 +43,7 @@
- #include "../usbd-build.h"
- #include "../usbd-module.h"
-
-+MODULE_LICENSE("GPL");
- MODULE_AUTHOR ("sl@lineo.com, tbr@lineo.com");
- MODULE_DESCRIPTION ("USB Device SA-1100 Bus Interface");
-
---- linux/drivers/usb/device/usbd.c~modulelicence
-+++ linux/drivers/usb/device/usbd.c
-@@ -72,6 +72,7 @@
- #include "usbd-build.h"
- #include "usbd-module.h"
-
-+MODULE_LICENSE("GPL");
- MODULE_AUTHOR ("sl@lineo.com, tbr@lineo.com");
- MODULE_DESCRIPTION ("USB Device Core Support");
-
---- linux/drivers/usb/device/usbd-monitor.c~modulelicence
-+++ linux/drivers/usb/device/usbd-monitor.c
-@@ -35,6 +35,7 @@
- #include "usbd-build.h"
- #include "usbd-module.h"
-
-+MODULE_LICENSE("GPL");
- MODULE_AUTHOR ("sl@lineo.com, tbr@lineo.com");
- MODULE_DESCRIPTION ("USB Device Monitor");
- USBD_MODULE_INFO ("usbd_monitor 0.3");
---- linux/drivers/usb/device/net_fd/net-fd.c~modulelicence
-+++ linux/drivers/usb/device/net_fd/net-fd.c
-@@ -33,6 +33,7 @@
- #include "../usbd-build.h"
- #include "../usbd-module.h"
-
-+MODULE_LICENSE("GPL");
- MODULE_AUTHOR ("sl@lineo.com, tbr@lineo.com");
- MODULE_DESCRIPTION ("USB Device Network Function");
-
---- linux/arch/arm/mach-sa1100/deviceinfo.c~modulelicence
-+++ linux/arch/arm/mach-sa1100/deviceinfo.c
-@@ -28,6 +28,7 @@
-
- #define MODULE_NAME "deviceinfo"
- #define DEVINFO_DIRNAME "deviceinfo"
-+MODULE_LICENSE("GPL");
-
- static int proc_read_deviceinfo(struct file * file, char * buf,
- size_t nbytes, loff_t *ppos);
---- linux/arch/arm/mach-sa1100/gpio.c~modulelicence
-+++ linux/arch/arm/mach-sa1100/gpio.c
-@@ -15,7 +15,7 @@
-
- #include <asm/hardware.h>
-
--
-+MODULE_LICENSE("GPL");
-
- static int proc_gpio_read(char *page, char **start, off_t off,
- int count, int *eof, void *data)
---- linux/drivers/usb/device/serial_fd/serial.c~modulelicence
-+++ linux/drivers/usb/device/serial_fd/serial.c
-@@ -80,6 +80,7 @@
- #include "../usbd-module.h"
-
-
-+MODULE_LICENSE("GPL");
- MODULE_AUTHOR ("sl@lineo.com, tbr@lineo.com");
- MODULE_DESCRIPTION ("USB Device Serial Function");
-
---- linux/drivers/usb/device/usbd-serialnumber.c~modulelicence
-+++ linux/drivers/usb/device/usbd-serialnumber.c
-@@ -33,6 +33,7 @@
- #include "usbd-build.h"
- #include "usbd-module.h"
-
-+MODULE_LICENSE("GPL");
- MODULE_AUTHOR ("sl@lineo.com, tbr@lineo.com");
- MODULE_DESCRIPTION ("USB Device Monitor");
- USBD_MODULE_INFO ("usbd_monitor 0.2-alpha");
---- linux/drivers/usb/device/bi/pxa.c~modulelicence
-+++ linux/drivers/usb/device/bi/pxa.c
-@@ -48,6 +48,7 @@
- #include "../usbd-build.h"
- #include "../usbd-module.h"
-
-+MODULE_LICENSE ("GPL");
- MODULE_AUTHOR ("sl@lineo.com, tbr@lineo.com");
- MODULE_DESCRIPTION ("Xscale USB Device Bus Interface");
-
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/piro.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/piro.patch
deleted file mode 100644
index 27fc518a79..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/piro.patch
+++ /dev/null
@@ -1,75444 +0,0 @@
-diff -Nur linux_c860_org/CREDITS linux/CREDITS
---- linux_c860_org/CREDITS 2002-08-26 14:43:17.000000000 +0900
-+++ linux/CREDITS 2004-06-10 21:09:10.000000000 +0900
-@@ -981,8 +981,8 @@
-
- N: Nigel Gamble
- E: nigel@nrg.org
--E: nigel@sgi.com
- D: Interrupt-driven printer driver
-+D: Preemptible kernel
- S: 120 Alley Way
- S: Mountain View, California 94040
- S: USA
-diff -Nur linux_c860_org/Documentation/Configure.help linux/Documentation/Configure.help
---- linux_c860_org/Documentation/Configure.help 2002-10-09 10:20:29.000000000 +0900
-+++ linux/Documentation/Configure.help 2004-06-10 21:09:10.000000000 +0900
-@@ -266,6 +266,29 @@
- If you have a system with several CPUs, you do not need to say Y
- here: the local APIC will be used automatically.
-
-+Preemptible Kernel
-+CONFIG_PREEMPT
-+ This option reduces the latency of the kernel when reacting to
-+ real-time or interactive events by allowing a low priority process to
-+ be preempted even if it is in kernel mode executing a system call.
-+ This allows applications to run more reliably even when the system is
-+ under load.
-+
-+ Say Y here if you are building a kernel for a desktop, embedded or
-+ real-time system. Say N if you are unsure.
-+
-+Break Selected Locks
-+CONFIG_LOCK_BREAK
-+ This option will break certain locks in high-latency regions
-+ throughout the kernel. It is intended for use in conjunction with
-+ the preemptible kernel (CONFIG_PREEMPT). Since in-kernel preemption
-+ can not occur while locks are held, temporarily releasing and then
-+ reacquiring long-held locks will further improve system response.
-+
-+ Say Y if you are compiling for a system with strict latency
-+ requirements such as an embedded, real-time, or audio processing
-+ system. Say N otherwise.
-+
- Kernel math emulation
- CONFIG_MATH_EMULATION
- Linux can emulate a math coprocessor (used for floating point
-diff -Nur linux_c860_org/Documentation/preempt-locking.txt linux/Documentation/preempt-locking.txt
---- linux_c860_org/Documentation/preempt-locking.txt 1970-01-01 09:00:00.000000000 +0900
-+++ linux/Documentation/preempt-locking.txt 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,104 @@
-+ Proper Locking Under a Preemptible Kernel:
-+ Keeping Kernel Code Preempt-Safe
-+ Robert Love <rml@tech9.net>
-+ Last Updated: 22 Jan 2002
-+
-+
-+INTRODUCTION
-+
-+
-+A preemptible kernel creates new locking issues. The issues are the same as
-+those under SMP: concurrency and reentrancy. Thankfully, the Linux preemptible
-+kernel model leverages existing SMP locking mechanisms. Thus, the kernel
-+requires explicit additional locking for very few additional situations.
-+
-+This document is for all kernel hackers. Developing code in the kernel
-+requires protecting these situations.
-+
-+
-+RULE #1: Per-CPU data structures need explicit protection
-+
-+
-+Two similar problems arise. An example code snippet:
-+
-+ struct this_needs_locking tux[NR_CPUS];
-+ tux[smp_processor_id()] = some_value;
-+ /* task is preempted here... */
-+ something = tux[smp_processor_id()];
-+
-+First, since the data is per-CPU, it may not have explicit SMP locking, but
-+require it otherwise. Second, when a preempted task is finally rescheduled,
-+the previous value of smp_processor_id may not equal the current. You must
-+protect these situations by disabling preemption around them.
-+
-+
-+RULE #2: CPU state must be protected.
-+
-+
-+Under preemption, the state of the CPU must be protected. This is arch-
-+dependent, but includes CPU structures and state not preserved over a context
-+switch. For example, on x86, entering and exiting FPU mode is now a critical
-+section that must occur while preemption is disabled. Think what would happen
-+if the kernel is executing a floating-point instruction and is then preempted.
-+Remember, the kernel does not save FPU state except for user tasks. Therefore,
-+upon preemption, the FPU registers will be sold to the lowest bidder. Thus,
-+preemption must be disabled around such regions.
-+
-+Note, some FPU functions are already explicitly preempt safe. For example,
-+kernel_fpu_begin and kernel_fpu_end will disable and enable preemption.
-+However, math_state_restore must be called with preemption disabled.
-+
-+
-+RULE #3: Lock acquire and release must be performed by same task
-+
-+
-+A lock acquired in one task must be released by the same task. This
-+means you can't do oddball things like acquire a lock and go off to
-+play while another task releases it. If you want to do something
-+like this, acquire and release the task in the same code path and
-+have the caller wait on an event by the other task.
-+
-+
-+SOLUTION
-+
-+
-+Data protection under preemption is achieved by disabling preemption for the
-+duration of the critical region.
-+
-+preempt_enable() decrement the preempt counter
-+preempt_disable() increment the preempt counter
-+preempt_enable_no_resched() decrement, but do not immediately preempt
-+preempt_get_count() return the preempt counter
-+
-+The functions are nestable. In other words, you can call preempt_disable
-+n-times in a code path, and preemption will not be reenabled until the n-th
-+call to preempt_enable. The preempt statements define to nothing if
-+preemption is not enabled.
-+
-+Note that you do not need to explicitly prevent preemption if you are holding
-+any locks or interrupts are disabled, since preemption is implicitly disabled
-+in those cases.
-+
-+Example:
-+
-+ cpucache_t *cc; /* this is per-CPU */
-+ preempt_disable();
-+ cc = cc_data(searchp);
-+ if (cc && cc->avail) {
-+ __free_block(searchp, cc_entry(cc), cc->avail);
-+ cc->avail = 0;
-+ }
-+ preempt_enable();
-+ return 0;
-+
-+Notice how the preemption statements must encompass every reference of the
-+critical variables. Another example:
-+
-+ int buf[NR_CPUS];
-+ set_cpu_val(buf);
-+ if (buf[smp_processor_id()] == -1) printf(KERN_INFO "wee!\n");
-+ spin_lock(&buf_lock);
-+ /* ... */
-+
-+This code is not preempt-safe, but see how easily we can fix it by simply
-+moving the spin_lock up two lines.
-diff -Nur linux_c860_org/MAINTAINERS linux/MAINTAINERS
---- linux_c860_org/MAINTAINERS 2002-08-26 14:43:17.000000000 +0900
-+++ linux/MAINTAINERS 2004-06-10 21:09:10.000000000 +0900
-@@ -1255,6 +1255,14 @@
- M: mostrows@styx.uwaterloo.ca
- S: Maintained
-
-+PREEMPTIBLE KERNEL
-+P: Robert M. Love
-+M: rml@tech9.net
-+L: linux-kernel@vger.kernel.org
-+L: kpreempt-tech@lists.sourceforge.net
-+W: http://tech9.net/rml/linux
-+S: Supported
-+
- PROMISE DC4030 CACHING DISK CONTROLLER DRIVER
- P: Peter Denison
- M: promise@pnd-pc.demon.co.uk
-diff -Nur linux_c860_org/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S
---- linux_c860_org/arch/alpha/kernel/entry.S 2002-08-26 14:39:34.000000000 +0900
-+++ linux/arch/alpha/kernel/entry.S 2004-06-10 21:09:10.000000000 +0900
-@@ -231,12 +231,12 @@
- .end kernel_clone
-
- /*
-- * kernel_thread(fn, arg, clone_flags)
-+ * arch_kernel_thread(fn, arg, clone_flags)
- */
- .align 3
- .globl kernel_thread
- .ent kernel_thread
--kernel_thread:
-+arch_kernel_thread:
- ldgp $29,0($27) /* we can be called from a module */
- .frame $30, 4*8, $26
- subq $30,4*8,$30
-diff -Nur linux_c860_org/arch/arm/boot/compressed/head-xscale.S linux/arch/arm/boot/compressed/head-xscale.S
---- linux_c860_org/arch/arm/boot/compressed/head-xscale.S 2002-12-18 19:27:19.000000000 +0900
-+++ linux/arch/arm/boot/compressed/head-xscale.S 2004-06-10 21:09:10.000000000 +0900
-@@ -5,6 +5,7 @@
- *
- * ChangLog:
- * 12-Dec-2002 Lineo Japan, Inc.
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- #include <linux/config.h>
-@@ -51,3 +52,7 @@
- #ifdef CONFIG_ARCH_PXA_CORGI
- mov r7, #MACH_TYPE_CORGI
- #endif
-+
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+ mov r7, #MACH_TYPE_TOSA
-+#endif
-diff -Nur linux_c860_org/arch/arm/config.in linux/arch/arm/config.in
---- linux_c860_org/arch/arm/config.in 2003-10-09 14:41:35.000000000 +0900
-+++ linux/arch/arm/config.in 2004-06-10 21:10:22.000000000 +0900
-@@ -196,16 +196,33 @@
- dep_bool ' Using Trial 0' CONFIG_POODLE_TR0 $CONFIG_ARCH_PXA_POODLE
- dep_bool ' SHARP Corgi' CONFIG_ARCH_PXA_CORGI $CONFIG_ARCH_PXA
- dep_bool ' Using Trial 0' CONFIG_CORGI_TR0 $CONFIG_ARCH_PXA_CORGI
-+dep_bool ' LCD Bufferable (EXPERIMENTAL)' CONFIG_CORGI_LCD_BUFF $CONFIG_ARCH_PXA_CORGI
- dep_bool ' SHARP Shepherd' CONFIG_ARCH_PXA_SHEPHERD $CONFIG_ARCH_PXA_CORGI
- dep_bool ' SHARP Husky' CONFIG_ARCH_PXA_HUSKY $CONFIG_ARCH_PXA_SHEPHERD
- dep_bool ' SHARP Boxer' CONFIG_ARCH_PXA_BOXER $CONFIG_ARCH_PXA_HUSKY
-+dep_bool ' SHARP Tosa' CONFIG_ARCH_PXA_TOSA $CONFIG_ARCH_PXA
-+dep_bool ' SHARP Tosa skipping' CONFIG_ARCH_PXA_TOSA_SKIP $CONFIG_ARCH_PXA_TOSA
-
- if [ "$CONFIG_SA1100_COLLIE" = "y" -o "$CONFIG_SABINAL_DISCOVERY" = "y" -o \
-- "$CONFIG_ARCH_PXA_POODLE" = "y" -o "$CONFIG_ARCH_PXA_CORGI" = "y" ]; then
-+ "$CONFIG_ARCH_PXA_POODLE" = "y" -o "$CONFIG_ARCH_PXA_CORGI" = "y" -o \
-+ "$CONFIG_ARCH_PXA_TOSA" = "y" ]; then
- define_bool CONFIG_ARCH_SHARP_SL y
- fi
-
--if [ "$CONFIG_ARCH_PXA_POODLE" = "y" -o "$CONFIG_ARCH_PXA_CORGI" = "y" ]; then
-+
-+if [ "$CONFIG_ARCH_PXA_POODLE" = "y" -o "$CONFIG_ARCH_PXA_CORGI" = "y" -o \
-+ "$CONFIG_ARCH_PXA_TOSA" = "y" ]; then
-+ bool 'Use clock change(cccr_change) enable (EXPERIMENTAL)' CONFIG_SL_CCCR_CHANGE
-+ if [ "$CONFIG_SL_CCCR162" != "y" -a "$CONFIG_SL_CCCR_CHANGE" = "y" ]; then
-+ bool 'Boot CCCR=0x242 (EXPERIMENTAL)' CONFIG_SL_CCCR242
-+ fi
-+ if [ "$CONFIG_SL_CCCR242" != "y" -a "$CONFIG_SL_CCCR_CHANGE" = "y" ]; then
-+ bool 'Boot CCCR=0x162 (DANGEROUS ESPECIALLY FOR SL-C700)' CONFIG_SL_CCCR162
-+ fi
-+fi
-+
-+if [ "$CONFIG_ARCH_PXA_POODLE" = "y" -o "$CONFIG_ARCH_PXA_CORGI" = "y" -o \
-+ "$CONFIG_ARCH_PXA_TOSA" = "y" ]; then
- comment 'Language type'
- choice 'Language type' \
- "English CONFIG_ARCH_SHARP_SL_E \
-@@ -472,7 +489,10 @@
- else
- define_bool CONFIG_DISCONTIGMEM n
- fi
--
-+dep_bool 'Preemptible Kernel' CONFIG_PREEMPT $CONFIG_CPU_32
-+if [ "$CONFIG_PREEMPT" = "y" ]; then
-+ bool 'Break selected locks' CONFIG_LOCK_BREAK
-+fi
- endmenu
-
- mainmenu_option next_comment
-@@ -628,6 +648,9 @@
- if [ "$CONFIG_DEVICEINFO" = "m" -a "$CONFIG_ARCH_PXA_CORGI" = "y" ]; then
- define_tristate CONFIG_CORGI_DEVICEINFO m
- fi
-+if [ "$CONFIG_DEVICEINFO" = "m" -a "$CONFIG_ARCH_PXA_TOSA" = "y" ]; then
-+ define_tristate CONFIG_TOSA_DEVICEINFO m
-+fi
- endmenu
-
- source drivers/parport/Config.in
-diff -Nur linux_c860_org/arch/arm/def-configs/boxer-j linux/arch/arm/def-configs/boxer-j
---- linux_c860_org/arch/arm/def-configs/boxer-j 2003-11-07 11:37:08.000000000 +0900
-+++ linux/arch/arm/def-configs/boxer-j 2004-06-10 21:09:10.000000000 +0900
-@@ -299,6 +299,7 @@
- # CONFIG_MTD_NAND_ERASE_BY_FORCE is not set
- CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS=y
- CONFIG_MTD_NAND_PAGE_CACHE=y
-+CONFIG_MTD_NAND_SHARP_SL_CORGI=y
- CONFIG_MTD_NAND_SHARP_SL=y
-
- #
-diff -Nur linux_c860_org/arch/arm/def-configs/corgi linux/arch/arm/def-configs/corgi
---- linux_c860_org/arch/arm/def-configs/corgi 2002-11-26 15:25:56.000000000 +0900
-+++ linux/arch/arm/def-configs/corgi 2004-06-10 21:09:10.000000000 +0900
-@@ -295,6 +295,7 @@
- # CONFIG_MTD_NAND_ERASE_BY_FORCE is not set
- CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS=y
- CONFIG_MTD_NAND_PAGE_CACHE=y
-+CONFIG_MTD_NAND_SHARP_SL_CORGI=y
- CONFIG_MTD_NAND_SHARP_SL=y
-
- #
-diff -Nur linux_c860_org/arch/arm/def-configs/corgi_cramfs linux/arch/arm/def-configs/corgi_cramfs
---- linux_c860_org/arch/arm/def-configs/corgi_cramfs 2002-10-21 10:17:42.000000000 +0900
-+++ linux/arch/arm/def-configs/corgi_cramfs 2004-06-10 21:09:10.000000000 +0900
-@@ -297,6 +297,7 @@
- CONFIG_MTD_NAND_POST_BADBLOCK=y
- # CONFIG_MTD_NAND_ERASE_BY_FORCE is not set
- # CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS is not set
-+CONFIG_MTD_NAND_SHARP_SL_CORGI=y
- CONFIG_MTD_NAND_SHARP_SL=y
-
- #
-diff -Nur linux_c860_org/arch/arm/def-configs/corgi_initrd linux/arch/arm/def-configs/corgi_initrd
---- linux_c860_org/arch/arm/def-configs/corgi_initrd 2002-10-21 10:17:42.000000000 +0900
-+++ linux/arch/arm/def-configs/corgi_initrd 2004-06-10 21:09:10.000000000 +0900
-@@ -297,6 +297,7 @@
- CONFIG_MTD_NAND_POST_BADBLOCK=y
- # CONFIG_MTD_NAND_ERASE_BY_FORCE is not set
- # CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS is not set
-+CONFIG_MTD_NAND_SHARP_SL_CORGI=y
- CONFIG_MTD_NAND_SHARP_SL=y
-
- #
-diff -Nur linux_c860_org/arch/arm/def-configs/husky linux/arch/arm/def-configs/husky
---- linux_c860_org/arch/arm/def-configs/husky 2003-05-20 09:48:12.000000000 +0900
-+++ linux/arch/arm/def-configs/husky 2004-06-10 21:09:10.000000000 +0900
-@@ -298,6 +298,7 @@
- # CONFIG_MTD_NAND_ERASE_BY_FORCE is not set
- CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS=y
- CONFIG_MTD_NAND_PAGE_CACHE=y
-+CONFIG_MTD_NAND_SHARP_SL_CORGI=y
- CONFIG_MTD_NAND_SHARP_SL=y
-
- #
-diff -Nur linux_c860_org/arch/arm/def-configs/husky-j linux/arch/arm/def-configs/husky-j
---- linux_c860_org/arch/arm/def-configs/husky-j 2003-05-20 09:48:12.000000000 +0900
-+++ linux/arch/arm/def-configs/husky-j 2004-06-10 21:09:10.000000000 +0900
-@@ -298,6 +298,7 @@
- # CONFIG_MTD_NAND_ERASE_BY_FORCE is not set
- CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS=y
- CONFIG_MTD_NAND_PAGE_CACHE=y
-+CONFIG_MTD_NAND_SHARP_SL_CORGI=y
- CONFIG_MTD_NAND_SHARP_SL=y
-
- #
-diff -Nur linux_c860_org/arch/arm/def-configs/poodle linux/arch/arm/def-configs/poodle
---- linux_c860_org/arch/arm/def-configs/poodle 2002-11-26 15:25:56.000000000 +0900
-+++ linux/arch/arm/def-configs/poodle 2004-06-10 21:09:10.000000000 +0900
-@@ -295,6 +295,7 @@
- # CONFIG_MTD_NAND_ERASE_BY_FORCE is not set
- CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS=y
- CONFIG_MTD_NAND_PAGE_CACHE=y
-+CONFIG_MTD_NAND_SHARP_SL_POODLE=y
- CONFIG_MTD_NAND_SHARP_SL=y
-
- #
-diff -Nur linux_c860_org/arch/arm/def-configs/poodle-j linux/arch/arm/def-configs/poodle-j
---- linux_c860_org/arch/arm/def-configs/poodle-j 2002-11-26 15:25:56.000000000 +0900
-+++ linux/arch/arm/def-configs/poodle-j 2004-06-10 21:09:10.000000000 +0900
-@@ -295,6 +295,7 @@
- # CONFIG_MTD_NAND_ERASE_BY_FORCE is not set
- CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS=y
- CONFIG_MTD_NAND_PAGE_CACHE=y
-+CONFIG_MTD_NAND_SHARP_SL_POODLE=y
- CONFIG_MTD_NAND_SHARP_SL=y
-
- #
-diff -Nur linux_c860_org/arch/arm/def-configs/poodle_cramfs linux/arch/arm/def-configs/poodle_cramfs
---- linux_c860_org/arch/arm/def-configs/poodle_cramfs 2002-10-21 10:16:27.000000000 +0900
-+++ linux/arch/arm/def-configs/poodle_cramfs 2004-06-10 21:09:10.000000000 +0900
-@@ -298,6 +298,7 @@
- CONFIG_MTD_NAND_POST_BADBLOCK=y
- # CONFIG_MTD_NAND_ERASE_BY_FORCE is not set
- # CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS is not set
-+CONFIG_MTD_NAND_SHARP_SL_POODLE=y
- CONFIG_MTD_NAND_SHARP_SL=y
-
- #
-diff -Nur linux_c860_org/arch/arm/def-configs/shepherd linux/arch/arm/def-configs/shepherd
---- linux_c860_org/arch/arm/def-configs/shepherd 2003-04-04 08:55:58.000000000 +0900
-+++ linux/arch/arm/def-configs/shepherd 2004-06-10 21:09:10.000000000 +0900
-@@ -297,6 +297,7 @@
- # CONFIG_MTD_NAND_ERASE_BY_FORCE is not set
- CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS=y
- CONFIG_MTD_NAND_PAGE_CACHE=y
-+CONFIG_MTD_NAND_SHARP_SL_CORGI=y
- CONFIG_MTD_NAND_SHARP_SL=y
-
- #
-diff -Nur linux_c860_org/arch/arm/def-configs/shepherd-j linux/arch/arm/def-configs/shepherd-j
---- linux_c860_org/arch/arm/def-configs/shepherd-j 2003-04-04 08:56:28.000000000 +0900
-+++ linux/arch/arm/def-configs/shepherd-j 2004-06-10 21:09:10.000000000 +0900
-@@ -297,6 +297,7 @@
- # CONFIG_MTD_NAND_ERASE_BY_FORCE is not set
- CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS=y
- CONFIG_MTD_NAND_PAGE_CACHE=y
-+CONFIG_MTD_NAND_SHARP_SL_CORGI=y
- CONFIG_MTD_NAND_SHARP_SL=y
-
- #
-diff -Nur linux_c860_org/arch/arm/def-configs/tosa-j linux/arch/arm/def-configs/tosa-j
---- linux_c860_org/arch/arm/def-configs/tosa-j 1970-01-01 09:00:00.000000000 +0900
-+++ linux/arch/arm/def-configs/tosa-j 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,1156 @@
-+#
-+# Automatically generated by make menuconfig: don't edit
-+#
-+CONFIG_ARM=y
-+# CONFIG_EISA is not set
-+# CONFIG_SBUS is not set
-+# CONFIG_MCA is not set
-+CONFIG_UID16=y
-+CONFIG_RWSEM_GENERIC_SPINLOCK=y
-+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-+# CONFIG_GENERIC_BUST_SPINLOCK is not set
-+# CONFIG_GENERIC_ISA_DMA is not set
-+
-+#
-+# Code maturity level options
-+#
-+CONFIG_EXPERIMENTAL=y
-+# CONFIG_OBSOLETE is not set
-+
-+#
-+# Loadable module support
-+#
-+CONFIG_MODULES=y
-+# CONFIG_MODVERSIONS is not set
-+CONFIG_KMOD=y
-+
-+#
-+# System Type
-+#
-+# CONFIG_ARCH_ANAKIN is not set
-+# CONFIG_ARCH_ARCA5K is not set
-+# CONFIG_ARCH_CLPS7500 is not set
-+# CONFIG_ARCH_CLPS711X is not set
-+# CONFIG_ARCH_CO285 is not set
-+CONFIG_ARCH_PXA=y
-+# CONFIG_ARCH_EBSA110 is not set
-+# CONFIG_ARCH_CAMELOT is not set
-+# CONFIG_ARCH_FOOTBRIDGE is not set
-+# CONFIG_ARCH_INTEGRATOR is not set
-+# CONFIG_ARCH_L7200 is not set
-+# CONFIG_ARCH_MX1ADS is not set
-+# CONFIG_ARCH_RPC is not set
-+# CONFIG_ARCH_SA1100 is not set
-+# CONFIG_ARCH_SHARK is not set
-+
-+#
-+# Archimedes/A5000 Implementations
-+#
-+# CONFIG_ARCH_ARC is not set
-+# CONFIG_ARCH_A5K is not set
-+
-+#
-+# Footbridge Implementations
-+#
-+# CONFIG_ARCH_CATS is not set
-+# CONFIG_ARCH_PERSONAL_SERVER is not set
-+# CONFIG_ARCH_EBSA285_ADDIN is not set
-+# CONFIG_ARCH_EBSA285_HOST is not set
-+# CONFIG_ARCH_NETWINDER is not set
-+
-+#
-+# SA11x0 Implementations
-+#
-+# CONFIG_SA1100_ASSABET is not set
-+# CONFIG_ASSABET_NEPONSET is not set
-+# CONFIG_SA1100_ADSBITSY is not set
-+# CONFIG_SA1100_BRUTUS is not set
-+# CONFIG_SA1100_CEP is not set
-+# CONFIG_SA1100_CERF is not set
-+# CONFIG_SA1100_COLLIE is not set
-+# CONFIG_LOCOMO is not set
-+# CONFIG_COLLIE_TS is not set
-+# CONFIG_COLLIE_TR0 is not set
-+# CONFIG_COLLIE_TR1 is not set
-+# CONFIG_COLLIE_DEV is not set
-+# CONFIG_COLLIE_G is not set
-+# CONFIG_SA1100_H3100 is not set
-+# CONFIG_SA1100_H3600 is not set
-+# CONFIG_SA1100_H3800 is not set
-+# CONFIG_SA1100_H3XXX is not set
-+# CONFIG_SA1100_EXTENEX1 is not set
-+# CONFIG_SA1100_FLEXANET is not set
-+# CONFIG_SA1100_FREEBIRD is not set
-+# CONFIG_SA1100_FRODO is not set
-+# CONFIG_SA1100_GRAPHICSCLIENT is not set
-+# CONFIG_SA1100_GRAPHICSMASTER is not set
-+# CONFIG_SA1100_BADGE4 is not set
-+# CONFIG_SA1100_JORNADA720 is not set
-+# CONFIG_SA1100_HUW_WEBPANEL is not set
-+# CONFIG_SA1100_ITSY is not set
-+# CONFIG_SA1100_LART is not set
-+# CONFIG_SA1100_NANOENGINE is not set
-+# CONFIG_SA1100_OMNIMETER is not set
-+# CONFIG_SA1100_PANGOLIN is not set
-+# CONFIG_SA1100_PLEB is not set
-+# CONFIG_SA1100_PT_SYSTEM3 is not set
-+# CONFIG_SA1100_SHANNON is not set
-+# CONFIG_SA1100_SHERMAN is not set
-+# CONFIG_SA1100_SIMPAD is not set
-+# CONFIG_SA1100_PFS168 is not set
-+# CONFIG_SA1100_VICTOR is not set
-+# CONFIG_SA1100_XP860 is not set
-+# CONFIG_SA1100_YOPY is not set
-+# CONFIG_SA1100_USB is not set
-+# CONFIG_SA1100_USB_NETLINK is not set
-+# CONFIG_SA1100_USB_CHAR is not set
-+# CONFIG_H3600_SLEEVE is not set
-+
-+#
-+# Intel PXA250/210 Implementations
-+#
-+# CONFIG_ARCH_LUBBOCK is not set
-+# CONFIG_ARCH_PXA_IDP is not set
-+# CONFIG_ARCH_PXA_CERF is not set
-+# CONFIG_COTULLA_DMA is not set
-+# CONFIG_SABINAL_DISCOVERY is not set
-+# CONFIG_ARCH_SABINAL is not set
-+# CONFIG_ARCH_PXA_POODLE is not set
-+# CONFIG_POODLE_TR0 is not set
-+# CONFIG_ARCH_PXA_CORGI is not set
-+# CONFIG_CORGI_TR0 is not set
-+# CONFIG_ARCH_PXA_SHEPHERD is not set
-+# CONFIG_ARCH_PXA_HUSKY is not set
-+CONFIG_ARCH_PXA_TOSA=y
-+CONFIG_ARCH_PXA_TOSA_SKIP=y
-+CONFIG_ARCH_SHARP_SL=y
-+# CONFIG_ARCH_SHARP_SL_E is not set
-+# CONFIG_ARCH_SHARP_SL_V is not set
-+# CONFIG_ARCH_SHARP_SL_G is not set
-+CONFIG_ARCH_SHARP_SL_J=y
-+# CONFIG_ARCH_SHARP_SL_S is not set
-+# CONFIG_ARCH_SHARP_SL_I is not set
-+# CONFIG_PXA_USB is not set
-+# CONFIG_PXA_USB_NETLINK is not set
-+# CONFIG_PXA_USB_CHAR is not set
-+
-+#
-+# CLPS711X/EP721X Implementations
-+#
-+# CONFIG_ARCH_AUTCPU12 is not set
-+# CONFIG_ARCH_CDB89712 is not set
-+# CONFIG_ARCH_CLEP7312 is not set
-+# CONFIG_ARCH_EDB7211 is not set
-+# CONFIG_ARCH_P720T is not set
-+# CONFIG_ARCH_FORTUNET is not set
-+# CONFIG_ARCH_EP7211 is not set
-+# CONFIG_ARCH_EP7212 is not set
-+# CONFIG_ARCH_ACORN is not set
-+# CONFIG_FOOTBRIDGE is not set
-+# CONFIG_FOOTBRIDGE_HOST is not set
-+# CONFIG_FOOTBRIDGE_ADDIN is not set
-+CONFIG_CPU_32=y
-+# CONFIG_CPU_26 is not set
-+# CONFIG_CPU_32v3 is not set
-+# CONFIG_CPU_32v4 is not set
-+# CONFIG_CPU_ARM610 is not set
-+# CONFIG_CPU_ARM710 is not set
-+# CONFIG_CPU_ARM720T is not set
-+# CONFIG_CPU_ARM920T is not set
-+# CONFIG_CPU_ARM922T is not set
-+# CONFIG_PLD is not set
-+# CONFIG_CPU_ARM926T is not set
-+# CONFIG_CPU_ARM1020 is not set
-+# CONFIG_CPU_SA110 is not set
-+# CONFIG_CPU_SA1100 is not set
-+CONFIG_CPU_32v5=y
-+CONFIG_CPU_XSCALE=y
-+CONFIG_BATT=y
-+# CONFIG_XSCALE_CACHE_ERRATA is not set
-+CONFIG_ARM_THUMB=y
-+CONFIG_ARM_FCSE=y
-+# CONFIG_DISCONTIGMEM is not set
-+
-+#
-+# General setup
-+#
-+# CONFIG_PCI is not set
-+# CONFIG_ISA is not set
-+# CONFIG_ISA_DMA is not set
-+# CONFIG_ZBOOT_ROM is not set
-+CONFIG_ZBOOT_ROM_TEXT=0
-+CONFIG_ZBOOT_ROM_BSS=0
-+CONFIG_HOTPLUG=y
-+
-+#
-+# PCMCIA/CardBus support
-+#
-+CONFIG_PCMCIA=y
-+# CONFIG_I82092 is not set
-+# CONFIG_I82365 is not set
-+# CONFIG_TCIC is not set
-+# CONFIG_PCMCIA_CLPS6700 is not set
-+# CONFIG_PCMCIA_SA1100 is not set
-+CONFIG_PCMCIA_PXA=y
-+CONFIG_NET=y
-+CONFIG_SYSVIPC=y
-+# CONFIG_BSD_PROCESS_ACCT is not set
-+CONFIG_SYSCTL=y
-+CONFIG_FPE_NWFPE=y
-+# CONFIG_FPE_FASTFPE is not set
-+CONFIG_KCORE_ELF=y
-+# CONFIG_KCORE_AOUT is not set
-+CONFIG_BINFMT_AOUT=y
-+CONFIG_BINFMT_ELF=y
-+# CONFIG_BINFMT_MISC is not set
-+CONFIG_PM=y
-+CONFIG_APM=y
-+# CONFIG_APM_IGNORE_USER_SUSPEND is not set
-+CONFIG_APM_CPU_IDLE=y
-+CONFIG_APM_DISPLAY_BLANK=y
-+CONFIG_APM_RTC_IS_GMT=y
-+# CONFIG_ARTHUR is not set
-+CONFIG_CMDLINE="console=ttyS0 root=/dev/mtdblock2"
-+CONFIG_SHARPSL_BOOTLDR_PARAMS=y
-+CONFIG_ALIGNMENT_TRAP=y
-+CONFIG_FREEPG_SIGNAL=y
-+CONFIG_OOM_KILL_SURVIVAL=y
-+CONFIG_DEVICEINFO=y
-+
-+#
-+# Parallel port support
-+#
-+# CONFIG_PARPORT is not set
-+
-+#
-+# Memory Technology Devices (MTD)
-+#
-+CONFIG_MTD=y
-+# CONFIG_MTD_DEBUG is not set
-+CONFIG_MTD_PARTITIONS=y
-+# CONFIG_MTD_CONCAT is not set
-+# CONFIG_MTD_REDBOOT_PARTS is not set
-+CONFIG_MTD_CMDLINE_PARTS=y
-+# CONFIG_MTD_AFS_PARTS is not set
-+CONFIG_MTD_CHAR=y
-+CONFIG_MTD_BLOCK=y
-+# CONFIG_FTL is not set
-+# CONFIG_NFTL is not set
-+
-+#
-+# RAM/ROM/Flash chip drivers
-+#
-+# CONFIG_MTD_CFI is not set
-+# CONFIG_MTD_JEDECPROBE is not set
-+# CONFIG_MTD_GEN_PROBE is not set
-+# CONFIG_MTD_CFI_INTELEXT is not set
-+# CONFIG_MTD_CFI_AMDSTD is not set
-+# CONFIG_MTD_CFI_STAA is not set
-+# CONFIG_MTD_RAM is not set
-+CONFIG_MTD_ROM=y
-+# CONFIG_MTD_ABSENT is not set
-+# CONFIG_MTD_OBSOLETE_CHIPS is not set
-+# CONFIG_MTD_AMDSTD is not set
-+# CONFIG_MTD_SHARP is not set
-+# CONFIG_MTD_JEDEC is not set
-+
-+#
-+# Mapping drivers for chip access
-+#
-+# CONFIG_MTD_PHYSMAP is not set
-+# CONFIG_MTD_LUBBOCK is not set
-+# CONFIG_MTD_NORA is not set
-+# CONFIG_MTD_ARM_INTEGRATOR is not set
-+# CONFIG_MTD_CDB89712 is not set
-+# CONFIG_MTD_SA1100 is not set
-+# CONFIG_MTD_DC21285 is not set
-+# CONFIG_MTD_IQ80310 is not set
-+# CONFIG_MTD_FORTUNET is not set
-+# CONFIG_MTD_PXA_CERF is not set
-+# CONFIG_MTD_EPXA10DB is not set
-+# CONFIG_MTD_AUTCPU12 is not set
-+# CONFIG_MTD_EDB7312 is not set
-+# CONFIG_MTD_IMPA7 is not set
-+# CONFIG_MTD_DISCOVERY is not set
-+CONFIG_MTD_SHARP_SL=y
-+# CONFIG_MTD_PCI is not set
-+
-+#
-+# Self-contained MTD device drivers
-+#
-+# CONFIG_MTD_PMC551 is not set
-+# CONFIG_MTD_SLRAM is not set
-+# CONFIG_MTD_MTDROM_SA1100 is not set
-+# CONFIG_MTD_MTDRAM_SA1100 is not set
-+# CONFIG_MTD_MTDRAM is not set
-+# CONFIG_MTD_MTDRAM_SHARP_SL is not set
-+# CONFIG_MTD_BLKMTD is not set
-+# CONFIG_MTD_DOC1000 is not set
-+# CONFIG_MTD_DOC2000 is not set
-+# CONFIG_MTD_DOC2001 is not set
-+# CONFIG_MTD_DOCPROBE is not set
-+
-+#
-+# NAND Flash Device Drivers
-+#
-+CONFIG_MTD_NAND=y
-+CONFIG_MTD_NAND_ECC=y
-+CONFIG_MTD_NAND_VERIFY_WRITE=y
-+CONFIG_MTD_NAND_POST_BADBLOCK=y
-+# CONFIG_MTD_NAND_ERASE_BY_FORCE is not set
-+CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS=y
-+CONFIG_MTD_NAND_PAGE_CACHE=y
-+CONFIG_MTD_NAND_SHARP_SL_TC6393=y
-+# CONFIG_MTD_NAND_SHARP_SL is not set
-+
-+#
-+# Plug and Play configuration
-+#
-+# CONFIG_PNP is not set
-+# CONFIG_ISAPNP is not set
-+
-+#
-+# Block devices
-+#
-+# CONFIG_BLK_DEV_FD is not set
-+# CONFIG_BLK_DEV_XD is not set
-+# CONFIG_PARIDE is not set
-+# CONFIG_BLK_CPQ_DA is not set
-+# CONFIG_BLK_CPQ_CISS_DA is not set
-+# CONFIG_BLK_DEV_DAC960 is not set
-+# CONFIG_BLK_DEV_COLLIE_MMCSD is not set
-+CONFIG_BLK_DEV_SL_MMCSD=m
-+CONFIG_BLK_DEV_SL_MMCSD_PSAVE=y
-+CONFIG_BLK_DEV_LOOP=y
-+# CONFIG_BLK_DEV_NBD is not set
-+CONFIG_BLK_DEV_RAM=y
-+CONFIG_BLK_DEV_RAM_SIZE=8192
-+CONFIG_BLK_DEV_INITRD=y
-+
-+#
-+# Multi-device support (RAID and LVM)
-+#
-+# CONFIG_MD is not set
-+# CONFIG_BLK_DEV_MD is not set
-+# CONFIG_MD_LINEAR is not set
-+# CONFIG_MD_RAID0 is not set
-+# CONFIG_MD_RAID1 is not set
-+# CONFIG_MD_RAID5 is not set
-+# CONFIG_MD_MULTIPATH is not set
-+# CONFIG_BLK_DEV_LVM is not set
-+
-+#
-+# Networking options
-+#
-+CONFIG_PACKET=y
-+CONFIG_PACKET_MMAP=y
-+CONFIG_NETLINK_DEV=y
-+CONFIG_NETFILTER=y
-+# CONFIG_NETFILTER_DEBUG is not set
-+# CONFIG_FILTER is not set
-+CONFIG_UNIX=y
-+CONFIG_INET=y
-+# CONFIG_IP_MULTICAST is not set
-+# CONFIG_IP_ADVANCED_ROUTER is not set
-+# CONFIG_IP_PNP is not set
-+# CONFIG_NET_IPIP is not set
-+# CONFIG_NET_IPGRE is not set
-+# CONFIG_ARPD is not set
-+# CONFIG_INET_ECN is not set
-+# CONFIG_SYN_COOKIES is not set
-+
-+#
-+# IP: Netfilter Configuration
-+#
-+# CONFIG_IP_NF_CONNTRACK is not set
-+# CONFIG_IP_NF_QUEUE is not set
-+# CONFIG_IP_NF_IPTABLES is not set
-+# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-+# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-+# CONFIG_IPV6 is not set
-+# CONFIG_KHTTPD is not set
-+# CONFIG_ATM is not set
-+# CONFIG_VLAN_8021Q is not set
-+# CONFIG_IPX is not set
-+# CONFIG_ATALK is not set
-+# CONFIG_DECNET is not set
-+# CONFIG_BRIDGE is not set
-+# CONFIG_X25 is not set
-+# CONFIG_LAPB is not set
-+# CONFIG_LLC is not set
-+# CONFIG_NET_DIVERT is not set
-+# CONFIG_ECONET is not set
-+# CONFIG_WAN_ROUTER is not set
-+# CONFIG_NET_FASTROUTE is not set
-+# CONFIG_NET_HW_FLOWCONTROL is not set
-+
-+#
-+# QoS and/or fair queueing
-+#
-+# CONFIG_NET_SCHED is not set
-+
-+#
-+# Network device support
-+#
-+CONFIG_NETDEVICES=y
-+
-+#
-+# ARCnet devices
-+#
-+# CONFIG_ARCNET is not set
-+# CONFIG_DUMMY is not set
-+# CONFIG_BONDING is not set
-+# CONFIG_EQUALIZER is not set
-+# CONFIG_TUN is not set
-+# CONFIG_ETHERTAP is not set
-+
-+#
-+# Ethernet (10 or 100Mbit)
-+#
-+CONFIG_NET_ETHERNET=y
-+# CONFIG_ARM_AM79C961A is not set
-+# CONFIG_SUNLANCE is not set
-+# CONFIG_SUNBMAC is not set
-+# CONFIG_SUNQE is not set
-+# CONFIG_SUNGEM is not set
-+# CONFIG_NET_VENDOR_3COM is not set
-+# CONFIG_LANCE is not set
-+# CONFIG_NET_VENDOR_SMC is not set
-+# CONFIG_NET_VENDOR_RACAL is not set
-+# CONFIG_NET_ISA is not set
-+# CONFIG_NET_PCI is not set
-+# CONFIG_NET_POCKET is not set
-+
-+#
-+# Ethernet (1000 Mbit)
-+#
-+# CONFIG_ACENIC is not set
-+# CONFIG_DL2K is not set
-+# CONFIG_MYRI_SBUS is not set
-+# CONFIG_NS83820 is not set
-+# CONFIG_HAMACHI is not set
-+# CONFIG_YELLOWFIN is not set
-+# CONFIG_SK98LIN is not set
-+# CONFIG_FDDI is not set
-+# CONFIG_HIPPI is not set
-+# CONFIG_PLIP is not set
-+CONFIG_PPP=y
-+# CONFIG_PPP_MULTILINK is not set
-+# CONFIG_PPP_FILTER is not set
-+CONFIG_PPP_ASYNC=y
-+# CONFIG_PPP_SYNC_TTY is not set
-+# CONFIG_PPP_DEFLATE is not set
-+CONFIG_PPP_BSDCOMP=y
-+# CONFIG_PPPOE is not set
-+# CONFIG_SLIP is not set
-+
-+#
-+# Wireless LAN (non-hamradio)
-+#
-+CONFIG_NET_RADIO=y
-+# CONFIG_STRIP is not set
-+# CONFIG_WAVELAN is not set
-+# CONFIG_ARLAN is not set
-+# CONFIG_AIRONET4500 is not set
-+# CONFIG_AIRONET4500_NONCS is not set
-+# CONFIG_AIRONET4500_PROC is not set
-+CONFIG_HERMES=y
-+CONFIG_PCMCIA_HERMES=y
-+# CONFIG_AIRO_CS is not set
-+CONFIG_NET_WIRELESS=y
-+
-+#
-+# Token Ring devices
-+#
-+# CONFIG_TR is not set
-+# CONFIG_NET_FC is not set
-+# CONFIG_RCPCI is not set
-+# CONFIG_SHAPER is not set
-+
-+#
-+# Wan interfaces
-+#
-+# CONFIG_WAN is not set
-+
-+#
-+# PCMCIA network device support
-+#
-+CONFIG_NET_PCMCIA=y
-+# CONFIG_PCMCIA_3C589 is not set
-+# CONFIG_PCMCIA_3C574 is not set
-+# CONFIG_PCMCIA_FMVJ18X is not set
-+CONFIG_PCMCIA_PCNET=y
-+# CONFIG_PCMCIA_AXNET is not set
-+# CONFIG_PCMCIA_NMCLAN is not set
-+# CONFIG_PCMCIA_SMC91C92 is not set
-+# CONFIG_PCMCIA_XIRC2PS is not set
-+# CONFIG_ARCNET_COM20020_CS is not set
-+# CONFIG_PCMCIA_IBMTR is not set
-+# CONFIG_NET_PCMCIA_RADIO is not set
-+
-+#
-+# Amateur Radio support
-+#
-+# CONFIG_HAMRADIO is not set
-+
-+#
-+# IrDA (infrared) support
-+#
-+CONFIG_IRDA=y
-+# CONFIG_IRLAN is not set
-+# CONFIG_IRNET is not set
-+CONFIG_IRCOMM=y
-+# CONFIG_IRDA_ULTRA is not set
-+# CONFIG_IRDA_CACHE_LAST_LSAP is not set
-+CONFIG_IRDA_FAST_RR=y
-+# CONFIG_IRDA_DEBUG is not set
-+
-+#
-+# Infrared-port device drivers
-+#
-+CONFIG_IRTTY_SIR=y
-+# CONFIG_IRPORT_SIR is not set
-+# CONFIG_DONGLE is not set
-+# CONFIG_USB_IRDA is not set
-+# CONFIG_NSC_FIR is not set
-+# CONFIG_WINBOND_FIR is not set
-+# CONFIG_TOSHIBA_FIR is not set
-+# CONFIG_SMC_IRCC_FIR is not set
-+# CONFIG_ALI_FIR is not set
-+# CONFIG_VLSI_FIR is not set
-+
-+#
-+# ATA/IDE/MFM/RLL support
-+#
-+CONFIG_IDE=y
-+
-+#
-+# IDE, ATA and ATAPI Block devices
-+#
-+CONFIG_BLK_DEV_IDE=y
-+# CONFIG_BLK_DEV_HD_IDE is not set
-+# CONFIG_BLK_DEV_HD is not set
-+CONFIG_BLK_DEV_IDEDISK=y
-+# CONFIG_IDEDISK_MULTI_MODE is not set
-+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-+# CONFIG_BLK_DEV_IDEDISK_WD is not set
-+# CONFIG_BLK_DEV_COMMERIAL is not set
-+# CONFIG_BLK_DEV_TIVO is not set
-+CONFIG_BLK_DEV_IDECS=y
-+# CONFIG_BLK_DEV_IDECD is not set
-+# CONFIG_BLK_DEV_IDETAPE is not set
-+# CONFIG_BLK_DEV_IDEFLOPPY is not set
-+# CONFIG_BLK_DEV_IDESCSI is not set
-+# CONFIG_BLK_DEV_CMD640 is not set
-+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-+# CONFIG_BLK_DEV_ISAPNP is not set
-+# CONFIG_IDE_CHIPSETS is not set
-+# CONFIG_IDEDMA_AUTO is not set
-+# CONFIG_DMA_NONPCI is not set
-+# CONFIG_BLK_DEV_IDE_MODES is not set
-+# CONFIG_BLK_DEV_ATARAID is not set
-+# CONFIG_BLK_DEV_ATARAID_PDC is not set
-+# CONFIG_BLK_DEV_ATARAID_HPT is not set
-+
-+#
-+# SCSI support
-+#
-+CONFIG_SCSI=y
-+CONFIG_BLK_DEV_SD=y
-+CONFIG_SD_EXTRA_DEVS=40
-+# CONFIG_CHR_DEV_ST is not set
-+# CONFIG_CHR_DEV_OSST is not set
-+# CONFIG_BLK_DEV_SR is not set
-+# CONFIG_CHR_DEV_SG is not set
-+# CONFIG_SCSI_DEBUG_QUEUES is not set
-+# CONFIG_SCSI_MULTI_LUN is not set
-+# CONFIG_SCSI_CONSTANTS is not set
-+# CONFIG_SCSI_LOGGING is not set
-+
-+#
-+# SCSI low-level drivers
-+#
-+# CONFIG_SCSI_7000FASST is not set
-+# CONFIG_SCSI_ACARD is not set
-+# CONFIG_SCSI_AHA152X is not set
-+# CONFIG_SCSI_AHA1542 is not set
-+# CONFIG_SCSI_AHA1740 is not set
-+# CONFIG_SCSI_AACRAID is not set
-+# CONFIG_SCSI_AIC7XXX is not set
-+# CONFIG_SCSI_AIC7XXX_OLD is not set
-+# CONFIG_SCSI_DPT_I2O is not set
-+# CONFIG_SCSI_ADVANSYS is not set
-+# CONFIG_SCSI_IN2000 is not set
-+# CONFIG_SCSI_AM53C974 is not set
-+# CONFIG_SCSI_MEGARAID is not set
-+# CONFIG_SCSI_BUSLOGIC is not set
-+# CONFIG_SCSI_DMX3191D is not set
-+# CONFIG_SCSI_DTC3280 is not set
-+# CONFIG_SCSI_EATA is not set
-+# CONFIG_SCSI_EATA_DMA is not set
-+# CONFIG_SCSI_EATA_PIO is not set
-+# CONFIG_SCSI_FUTURE_DOMAIN is not set
-+# CONFIG_SCSI_GDTH is not set
-+# CONFIG_SCSI_GENERIC_NCR5380 is not set
-+# CONFIG_SCSI_INITIO is not set
-+# CONFIG_SCSI_INIA100 is not set
-+# CONFIG_SCSI_NCR53C406A is not set
-+# CONFIG_SCSI_NCR53C7xx is not set
-+# CONFIG_SCSI_PAS16 is not set
-+# CONFIG_SCSI_PCI2000 is not set
-+# CONFIG_SCSI_PCI2220I is not set
-+# CONFIG_SCSI_PSI240I is not set
-+# CONFIG_SCSI_QLOGIC_FAS is not set
-+# CONFIG_SCSI_SIM710 is not set
-+# CONFIG_SCSI_SYM53C416 is not set
-+# CONFIG_SCSI_T128 is not set
-+# CONFIG_SCSI_U14_34F is not set
-+# CONFIG_SCSI_DEBUG is not set
-+
-+#
-+# PCMCIA SCSI adapter support
-+#
-+# CONFIG_SCSI_PCMCIA is not set
-+
-+#
-+# I2O device support
-+#
-+# CONFIG_I2O is not set
-+# CONFIG_I2O_BLOCK is not set
-+# CONFIG_I2O_LAN is not set
-+# CONFIG_I2O_SCSI is not set
-+# CONFIG_I2O_PROC is not set
-+
-+#
-+# ISDN subsystem
-+#
-+# CONFIG_ISDN is not set
-+
-+#
-+# Input core support
-+#
-+CONFIG_INPUT=y
-+CONFIG_INPUT_KEYBDEV=y
-+CONFIG_INPUT_MOUSEDEV=y
-+CONFIG_INPUT_MOUSEDEV_SCREEN_X=480
-+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=640
-+CONFIG_INPUT_JOYDEV=m
-+CONFIG_INPUT_EVDEV=m
-+
-+#
-+# Character devices
-+#
-+CONFIG_VT=y
-+CONFIG_VT_CONSOLE=y
-+CONFIG_SERIAL=y
-+# CONFIG_SERIAL_CONSOLE is not set
-+CONFIG_SERIAL_SL_SERIES=y
-+CONFIG_BLUETOOTH_SL=y
-+# CONFIG_SERIAL_EXTENDED is not set
-+# CONFIG_SERIAL_NONSTANDARD is not set
-+
-+#
-+# Serial drivers
-+#
-+# CONFIG_SERIAL_ANAKIN is not set
-+# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-+# CONFIG_SERIAL_AMBA is not set
-+# CONFIG_SERIAL_AMBA_CONSOLE is not set
-+# CONFIG_SERIAL_CLPS711X is not set
-+# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-+# CONFIG_SERIAL_21285 is not set
-+# CONFIG_SERIAL_21285_OLD is not set
-+# CONFIG_SERIAL_21285_CONSOLE is not set
-+# CONFIG_SERIAL_UART00 is not set
-+# CONFIG_SERIAL_UART00_CONSOLE is not set
-+# CONFIG_SERIAL_SA1100 is not set
-+# CONFIG_SERIAL_SA1100_CONSOLE is not set
-+# CONFIG_SERIAL_8250 is not set
-+# CONFIG_SERIAL_8250_CONSOLE is not set
-+# CONFIG_SERIAL_8250_EXTENDED is not set
-+# CONFIG_SERIAL_8250_MANY_PORTS is not set
-+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-+# CONFIG_SERIAL_8250_MULTIPORT is not set
-+# CONFIG_SERIAL_8250_HUB6 is not set
-+CONFIG_UNIX98_PTYS=y
-+CONFIG_UNIX98_PTY_COUNT=256
-+
-+#
-+# I2C support
-+#
-+# CONFIG_I2C is not set
-+
-+#
-+# L3 serial bus support
-+#
-+# CONFIG_L3 is not set
-+# CONFIG_L3_ALGOBIT is not set
-+# CONFIG_L3_BIT_SA1100_GPIO is not set
-+# CONFIG_L3_SA1111 is not set
-+# CONFIG_BIT_SA1100_GPIO is not set
-+
-+#
-+# Mice
-+#
-+# CONFIG_BUSMOUSE is not set
-+# CONFIG_MOUSE is not set
-+
-+#
-+# Joysticks
-+#
-+# CONFIG_INPUT_GAMEPORT is not set
-+# CONFIG_INPUT_NS558 is not set
-+# CONFIG_INPUT_LIGHTNING is not set
-+# CONFIG_INPUT_PCIGAME is not set
-+# CONFIG_INPUT_CS461X is not set
-+# CONFIG_INPUT_EMU10K1 is not set
-+# CONFIG_INPUT_SERIO is not set
-+# CONFIG_INPUT_SERPORT is not set
-+# CONFIG_INPUT_ANALOG is not set
-+# CONFIG_INPUT_A3D is not set
-+# CONFIG_INPUT_ADI is not set
-+# CONFIG_INPUT_COBRA is not set
-+# CONFIG_INPUT_GF2K is not set
-+# CONFIG_INPUT_GRIP is not set
-+# CONFIG_INPUT_INTERACT is not set
-+# CONFIG_INPUT_TMDC is not set
-+# CONFIG_INPUT_SIDEWINDER is not set
-+# CONFIG_INPUT_IFORCE_USB is not set
-+# CONFIG_INPUT_IFORCE_232 is not set
-+# CONFIG_INPUT_WARRIOR is not set
-+# CONFIG_INPUT_MAGELLAN is not set
-+# CONFIG_INPUT_SPACEORB is not set
-+# CONFIG_INPUT_SPACEBALL is not set
-+# CONFIG_INPUT_STINGER is not set
-+# CONFIG_INPUT_DB9 is not set
-+# CONFIG_INPUT_GAMECON is not set
-+# CONFIG_INPUT_TURBOGRAFX is not set
-+# CONFIG_QIC02_TAPE is not set
-+
-+#
-+# Watchdog Cards
-+#
-+# CONFIG_WATCHDOG is not set
-+# CONFIG_INTEL_RNG is not set
-+# CONFIG_NVRAM is not set
-+# CONFIG_RTC is not set
-+CONFIG_COTULLA_RTC=y
-+# CONFIG_ADS7846_TS is not set
-+CONFIG_TOSA_TS=y
-+# CONFIG_DTLK is not set
-+# CONFIG_R3964 is not set
-+# CONFIG_APPLICOM is not set
-+
-+#
-+# Ftape, the floppy tape device driver
-+#
-+# CONFIG_FTAPE is not set
-+# CONFIG_AGP is not set
-+# CONFIG_DRM is not set
-+
-+#
-+# PCMCIA character devices
-+#
-+CONFIG_PCMCIA_SERIAL_CS=y
-+CONFIG_PCMCIA_CHRDEV=y
-+
-+#
-+# Multimedia devices
-+#
-+# CONFIG_VIDEO_DEV is not set
-+
-+#
-+# File systems
-+#
-+# CONFIG_QUOTA is not set
-+# CONFIG_AUTOFS_FS is not set
-+# CONFIG_AUTOFS4_FS is not set
-+CONFIG_FS_SYNC=y
-+# CONFIG_REISERFS_FS is not set
-+# CONFIG_REISERFS_CHECK is not set
-+# CONFIG_REISERFS_PROC_INFO is not set
-+# CONFIG_ADFS_FS is not set
-+# CONFIG_ADFS_FS_RW is not set
-+# CONFIG_AFFS_FS is not set
-+# CONFIG_HFS_FS is not set
-+# CONFIG_BFS_FS is not set
-+# CONFIG_EXT3_FS is not set
-+# CONFIG_JBD is not set
-+# CONFIG_JBD_DEBUG is not set
-+CONFIG_FAT_FS=y
-+# CONFIG_MSDOS_FS is not set
-+# CONFIG_UMSDOS_FS is not set
-+CONFIG_VFAT_FS=y
-+# CONFIG_EFS_FS is not set
-+# CONFIG_JFFS_FS is not set
-+CONFIG_JFFS2_FS=y
-+CONFIG_JFFS2_FS_DEBUG=0
-+CONFIG_JFFS2_FS_NAND=y
-+CONFIG_JFFS2_PROC_FS=y
-+CONFIG_JFFS2_NODEMERGE=y
-+CONFIG_JFFS2_DYNFRAGTREE=y
-+CONFIG_CRAMFS=y
-+CONFIG_TMPFS=y
-+# CONFIG_RAMFS is not set
-+# CONFIG_ISO9660_FS is not set
-+# CONFIG_JOLIET is not set
-+# CONFIG_ZISOFS is not set
-+CONFIG_MINIX_FS=y
-+# CONFIG_VXFS_FS is not set
-+# CONFIG_NTFS_FS is not set
-+# CONFIG_NTFS_RW is not set
-+# CONFIG_HPFS_FS is not set
-+CONFIG_PROC_FS=y
-+# CONFIG_DEVFS_FS is not set
-+# CONFIG_DEVFS_MOUNT is not set
-+# CONFIG_DEVFS_DEBUG is not set
-+CONFIG_DEVPTS_FS=y
-+# CONFIG_QNX4FS_FS is not set
-+# CONFIG_QNX4FS_RW is not set
-+# CONFIG_ROMFS_FS is not set
-+CONFIG_EXT2_FS=y
-+# CONFIG_SYSV_FS is not set
-+# CONFIG_UDF_FS is not set
-+# CONFIG_UDF_RW is not set
-+# CONFIG_UFS_FS is not set
-+# CONFIG_UFS_FS_WRITE is not set
-+
-+#
-+# Network File Systems
-+#
-+# CONFIG_CODA_FS is not set
-+# CONFIG_INTERMEZZO_FS is not set
-+CONFIG_NFS_FS=y
-+CONFIG_NFS_V3=y
-+# CONFIG_ROOT_NFS is not set
-+# CONFIG_NFSD is not set
-+# CONFIG_NFSD_V3 is not set
-+CONFIG_SUNRPC=y
-+CONFIG_LOCKD=y
-+CONFIG_LOCKD_V4=y
-+CONFIG_SMB_FS=y
-+# CONFIG_SMB_NLS_DEFAULT is not set
-+# CONFIG_NCP_FS is not set
-+# CONFIG_NCPFS_PACKET_SIGNING is not set
-+# CONFIG_NCPFS_IOCTL_LOCKING is not set
-+# CONFIG_NCPFS_STRONG is not set
-+# CONFIG_NCPFS_NFS_NS is not set
-+# CONFIG_NCPFS_OS2_NS is not set
-+# CONFIG_NCPFS_SMALLDOS is not set
-+# CONFIG_NCPFS_NLS is not set
-+# CONFIG_NCPFS_EXTRAS is not set
-+# CONFIG_ZISOFS_FS is not set
-+CONFIG_ZLIB_FS_INFLATE=y
-+
-+#
-+# Partition Types
-+#
-+CONFIG_PARTITION_ADVANCED=y
-+# CONFIG_ACORN_PARTITION is not set
-+# CONFIG_OSF_PARTITION is not set
-+# CONFIG_AMIGA_PARTITION is not set
-+# CONFIG_ATARI_PARTITION is not set
-+# CONFIG_MAC_PARTITION is not set
-+CONFIG_MSDOS_PARTITION=y
-+# CONFIG_BSD_DISKLABEL is not set
-+# CONFIG_MINIX_SUBPARTITION is not set
-+# CONFIG_SOLARIS_X86_PARTITION is not set
-+# CONFIG_UNIXWARE_DISKLABEL is not set
-+# CONFIG_LDM_PARTITION is not set
-+# CONFIG_SGI_PARTITION is not set
-+# CONFIG_ULTRIX_PARTITION is not set
-+# CONFIG_SUN_PARTITION is not set
-+CONFIG_SMB_NLS=y
-+CONFIG_NLS=y
-+
-+#
-+# Native Language Support
-+#
-+CONFIG_NLS_DEFAULT="iso8859-1"
-+CONFIG_NLS_CODEPAGE_437=y
-+# CONFIG_NLS_CODEPAGE_737 is not set
-+# CONFIG_NLS_CODEPAGE_775 is not set
-+CONFIG_NLS_CODEPAGE_850=y
-+# CONFIG_NLS_CODEPAGE_852 is not set
-+# CONFIG_NLS_CODEPAGE_855 is not set
-+# CONFIG_NLS_CODEPAGE_857 is not set
-+# CONFIG_NLS_CODEPAGE_860 is not set
-+# CONFIG_NLS_CODEPAGE_861 is not set
-+# CONFIG_NLS_CODEPAGE_862 is not set
-+# CONFIG_NLS_CODEPAGE_863 is not set
-+# CONFIG_NLS_CODEPAGE_864 is not set
-+# CONFIG_NLS_CODEPAGE_865 is not set
-+# CONFIG_NLS_CODEPAGE_866 is not set
-+# CONFIG_NLS_CODEPAGE_869 is not set
-+# CONFIG_NLS_CODEPAGE_936 is not set
-+# CONFIG_NLS_CODEPAGE_950 is not set
-+CONFIG_NLS_CODEPAGE_932=y
-+# CONFIG_NLS_CODEPAGE_949 is not set
-+# CONFIG_NLS_CODEPAGE_874 is not set
-+# CONFIG_NLS_ISO8859_8 is not set
-+# CONFIG_NLS_CODEPAGE_1250 is not set
-+# CONFIG_NLS_CODEPAGE_1251 is not set
-+CONFIG_NLS_ISO8859_1=y
-+# CONFIG_NLS_ISO8859_2 is not set
-+# CONFIG_NLS_ISO8859_3 is not set
-+# CONFIG_NLS_ISO8859_4 is not set
-+# CONFIG_NLS_ISO8859_5 is not set
-+# CONFIG_NLS_ISO8859_6 is not set
-+# CONFIG_NLS_ISO8859_7 is not set
-+# CONFIG_NLS_ISO8859_9 is not set
-+# CONFIG_NLS_ISO8859_13 is not set
-+# CONFIG_NLS_ISO8859_14 is not set
-+# CONFIG_NLS_ISO8859_15 is not set
-+# CONFIG_NLS_KOI8_R is not set
-+# CONFIG_NLS_KOI8_U is not set
-+CONFIG_NLS_UTF8=y
-+
-+#
-+# Console drivers
-+#
-+CONFIG_PC_KEYMAP=y
-+# CONFIG_VGA_CONSOLE is not set
-+
-+#
-+# Frame-buffer support
-+#
-+CONFIG_FB=y
-+CONFIG_DUMMY_CONSOLE=y
-+# CONFIG_FB_COLLIE is not set
-+# CONFIG_FB_ACORN is not set
-+# CONFIG_FB_ANAKIN is not set
-+# CONFIG_FB_CLPS711X is not set
-+# CONFIG_FB_SA1100 is not set
-+# CONFIG_FB_PXA is not set
-+# CONFIG_FB_COTULLA is not set
-+# CONFIG_FB_POODLE is not set
-+# CONFIG_FB_CORGI is not set
-+CONFIG_FB_TOSA=y
-+CONFIG_SHARP_LOGO_SCREEN=y
-+# CONFIG_FB_CYBER2000 is not set
-+# CONFIG_FB_VIRTUAL is not set
-+CONFIG_FBCON_ADVANCED=y
-+# CONFIG_FBCON_MFB is not set
-+# CONFIG_FBCON_CFB2 is not set
-+# CONFIG_FBCON_CFB4 is not set
-+# CONFIG_FBCON_CFB8 is not set
-+CONFIG_FBCON_CFB16=y
-+# CONFIG_FBCON_CFB24 is not set
-+# CONFIG_FBCON_CFB32 is not set
-+# CONFIG_FBCON_AFB is not set
-+# CONFIG_FBCON_ILBM is not set
-+# CONFIG_FBCON_IPLAN2P2 is not set
-+# CONFIG_FBCON_IPLAN2P4 is not set
-+# CONFIG_FBCON_IPLAN2P8 is not set
-+# CONFIG_FBCON_MAC is not set
-+# CONFIG_FBCON_VGA_PLANES is not set
-+# CONFIG_FBCON_VGA is not set
-+# CONFIG_FBCON_HGA is not set
-+# CONFIG_FBCON_ROTATE_R is not set
-+# CONFIG_FBCON_ROTATE_L is not set
-+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-+CONFIG_FBCON_FONTS=y
-+CONFIG_FONT_8x8=y
-+CONFIG_FONT_8x16=y
-+# CONFIG_FONT_SUN8x16 is not set
-+# CONFIG_FONT_SUN12x22 is not set
-+# CONFIG_FONT_6x11 is not set
-+# CONFIG_FONT_PEARL_8x8 is not set
-+# CONFIG_FONT_ACORN_8x8 is not set
-+
-+#
-+# Sound
-+#
-+CONFIG_SOUND=y
-+# CONFIG_SOUND_BT878 is not set
-+# CONFIG_SOUND_COLLIE_SSP is not set
-+# CONFIG_SOUND_COLLIE_TC35143 is not set
-+# CONFIG_SOUND_CMPCI is not set
-+# CONFIG_SOUND_EMU10K1 is not set
-+# CONFIG_MIDI_EMU10K1 is not set
-+# CONFIG_SOUND_FUSION is not set
-+# CONFIG_SOUND_CS4281 is not set
-+# CONFIG_SOUND_ES1370 is not set
-+# CONFIG_SOUND_ES1371 is not set
-+# CONFIG_SOUND_ESSSOLO1 is not set
-+# CONFIG_SOUND_MAESTRO is not set
-+# CONFIG_SOUND_MAESTRO3 is not set
-+# CONFIG_SOUND_ICH is not set
-+# CONFIG_SOUND_RME96XX is not set
-+# CONFIG_SOUND_SONICVIBES is not set
-+# CONFIG_SOUND_TRIDENT is not set
-+# CONFIG_SOUND_MSNDCLAS is not set
-+# CONFIG_SOUND_MSNDPIN is not set
-+# CONFIG_SOUND_VIA82CXXX is not set
-+# CONFIG_MIDI_VIA82CXXX is not set
-+# CONFIG_SOUND_OSS is not set
-+# CONFIG_SOUND_WAVEARTIST is not set
-+# CONFIG_SOUND_PXA_AC97 is not set
-+# CONFIG_SOUND_POODLE is not set
-+# CONFIG_SOUND_CORGI is not set
-+CONFIG_SOUND_TOSA=y
-+CONFIG_BUZZER_TOSA=y
-+# CONFIG_SOUND_TVMIXER is not set
-+
-+#
-+# Multimedia Capabilities Port drivers
-+#
-+# CONFIG_MCP is not set
-+# CONFIG_MCP_SA1100 is not set
-+# CONFIG_MCP_UCB1200 is not set
-+# CONFIG_MCP_UCB1200_AUDIO is not set
-+# CONFIG_MCP_UCB1200_TS is not set
-+# CONFIG_MCP_UCB1400_TS is not set
-+
-+#
-+# USB support
-+#
-+CONFIG_USB=y
-+# CONFIG_USB_DEBUG is not set
-+CONFIG_USB_DEVICEFS=y
-+# CONFIG_USB_BANDWIDTH is not set
-+# CONFIG_USB_LONG_TIMEOUT is not set
-+# CONFIG_USB_UHCI is not set
-+# CONFIG_USB_UHCI_ALT is not set
-+# CONFIG_USB_OHCI is not set
-+# CONFIG_USB_OHCI_SA1111 is not set
-+CONFIG_USB_OHCI_TC6393=m
-+CONFIG_USB_USE_INTERNAL_MEMORY=y
-+# CONFIG_USB_AUDIO is not set
-+# CONFIG_USB_BLUETOOTH is not set
-+CONFIG_USB_STORAGE=m
-+# CONFIG_USB_STORAGE_DEBUG is not set
-+# CONFIG_USB_STORAGE_DATAFAB is not set
-+# CONFIG_USB_STORAGE_FREECOM is not set
-+CONFIG_USB_STORAGE_ISD200=y
-+# CONFIG_USB_STORAGE_DPCM is not set
-+# CONFIG_USB_STORAGE_HP8200e is not set
-+# CONFIG_USB_STORAGE_SDDR09 is not set
-+# CONFIG_USB_STORAGE_JUMPSHOT is not set
-+CONFIG_USB_ACM=m
-+# CONFIG_USB_PRINTER is not set
-+CONFIG_USB_HID=m
-+# CONFIG_USB_HIDDEV is not set
-+CONFIG_USB_KBD=m
-+CONFIG_USB_MOUSE=m
-+# CONFIG_USB_WACOM is not set
-+# CONFIG_USB_DC2XX is not set
-+# CONFIG_USB_MDC800 is not set
-+# CONFIG_USB_SCANNER is not set
-+# CONFIG_USB_MICROTEK is not set
-+# CONFIG_USB_HPUSBSCSI is not set
-+# CONFIG_USB_PEGASUS is not set
-+# CONFIG_USB_KAWETH is not set
-+# CONFIG_USB_CATC is not set
-+# CONFIG_USB_CDCETHER is not set
-+# CONFIG_USB_USBNET is not set
-+# CONFIG_USB_USS720 is not set
-+
-+#
-+# USB Serial Converter support
-+#
-+# CONFIG_USB_SERIAL is not set
-+# CONFIG_USB_SERIAL_GENERIC is not set
-+# CONFIG_USB_SERIAL_BELKIN is not set
-+# CONFIG_USB_SERIAL_WHITEHEAT is not set
-+# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-+# CONFIG_USB_SERIAL_EMPEG is not set
-+# CONFIG_USB_SERIAL_FTDI_SIO is not set
-+# CONFIG_USB_SERIAL_VISOR is not set
-+# CONFIG_USB_SERIAL_IPAQ is not set
-+# CONFIG_USB_SERIAL_IR is not set
-+# CONFIG_USB_SERIAL_EDGEPORT is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-+# CONFIG_USB_SERIAL_KEYSPAN is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-+# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-+# CONFIG_USB_SERIAL_MCT_U232 is not set
-+# CONFIG_USB_SERIAL_KLSI is not set
-+# CONFIG_USB_SERIAL_PL2303 is not set
-+# CONFIG_USB_SERIAL_CYBERJACK is not set
-+# CONFIG_USB_SERIAL_XIRCOM is not set
-+# CONFIG_USB_SERIAL_OMNINET is not set
-+# CONFIG_USB_RIO500 is not set
-+
-+#
-+# USB Device Support
-+#
-+CONFIG_USBD=m
-+CONFIG_USBD_VENDORID=04DD
-+CONFIG_USBD_PRODUCTID=9032
-+CONFIG_USBD_PRODUCT_NAME="SL-6000"
-+CONFIG_USBD_MANUFACTURER="Sharp"
-+# CONFIG_USBD_USE_SERIAL_NUMBER is not set
-+CONFIG_USBD_SELFPOWERED=y
-+CONFIG_USBD_MONITOR=m
-+CONFIG_USBD_PROCFS=y
-+
-+#
-+# Network Function
-+#
-+CONFIG_USBD_NET=m
-+CONFIG_USBD_NET_VENDORID=04DD
-+CONFIG_USBD_NET_PRODUCTID=9032
-+CONFIG_USBD_NET_IFNAME="usbd"
-+CONFIG_USBD_NET_OUT_ENDPOINT=1
-+CONFIG_USBD_NET_OUT_PKTSIZE=64
-+CONFIG_USBD_NET_IN_ENDPOINT=2
-+CONFIG_USBD_NET_IN_PKTSIZE=64
-+CONFIG_USBD_NET_INT_ENDPOINT=3
-+CONFIG_USBD_NET_INT_PKTSIZE=16
-+# CONFIG_USBD_NET_ALWAYSUP is not set
-+# CONFIG_USBD_NET_SAFE is not set
-+CONFIG_USBD_NET_MDLM=y
-+# CONFIG_USBD_NET_CDC is not set
-+CONFIG_USBD_NET_REMOTE_MACADDR=""
-+CONFIG_USBD_NET_REMOTE_OUI=400002
-+CONFIG_USBD_MAC_AS_SERIAL_NUMBER=y
-+CONFIG_USBD_NET_LOCAL_MACADDR="400001000001"
-+CONFIG_USBD_NET_LOCAL_OUI=400001
-+
-+#
-+# Serial Function
-+#
-+# CONFIG_USBD_SERIAL is not set
-+
-+#
-+# USB Device Bus Interface Support
-+#
-+CONFIG_USBD_PXA_BUS=m
-+# CONFIG_USBD_GENERIC_BUS is not set
-+
-+#
-+# Bluetooth support
-+#
-+# CONFIG_BLUEZ is not set
-+
-+#
-+# Kernel hacking
-+#
-+CONFIG_FRAME_POINTER=y
-+# CONFIG_DEBUG_USER is not set
-+# CONFIG_DEBUG_COREDUMP_SIGNAL is not set
-+# CONFIG_DEBUG_INFO is not set
-+# CONFIG_NO_PGT_CACHE is not set
-+# CONFIG_DEBUG_KERNEL is not set
-+# CONFIG_DEBUG_SLAB is not set
-+# CONFIG_MAGIC_SYSRQ is not set
-+# CONFIG_DEBUG_SPINLOCK is not set
-+# CONFIG_DEBUG_WAITQ is not set
-+# CONFIG_DEBUG_BUGVERBOSE is not set
-+# CONFIG_DEBUG_ERRORS is not set
-+# CONFIG_DEBUG_LL is not set
-+# CONFIG_DEBUG_DC21285_PORT is not set
-+# CONFIG_DEBUG_CLPS711X_UART2 is not set
-diff -Nur linux_c860_org/arch/arm/kernel/entry-armv.S linux/arch/arm/kernel/entry-armv.S
---- linux_c860_org/arch/arm/kernel/entry-armv.S 2002-12-18 19:27:21.000000000 +0900
-+++ linux/arch/arm/kernel/entry-armv.S 2004-06-10 21:09:10.000000000 +0900
-@@ -769,6 +769,12 @@
- add r4, sp, #S_SP
- mov r6, lr
- stmia r4, {r5, r6, r7, r8, r9} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
-+#ifdef CONFIG_PREEMPT
-+ get_current_task r9
-+ ldr r8, [r9, #TSK_PREEMPT]
-+ add r8, r8, #1
-+ str r8, [r9, #TSK_PREEMPT]
-+#endif
- 1: get_irqnr_and_base r0, r6, r5, lr
- movne r1, sp
- @
-@@ -776,6 +782,25 @@
- @
- adrsvc ne, lr, 1b
- bne do_IRQ
-+#ifdef CONFIG_PREEMPT
-+2: ldr r8, [r9, #TSK_PREEMPT]
-+ subs r8, r8, #1
-+ bne 3f
-+ ldr r7, [r9, #TSK_NEED_RESCHED]
-+ teq r7, #0
-+ beq 3f
-+ ldr r6, .LCirqstat
-+ ldr r0, [r6, #IRQSTAT_BH_COUNT]
-+ teq r0, #0
-+ bne 3f
-+ mov r0, #MODE_SVC
-+ msr cpsr_c, r0 @ enable interrupts
-+ bl SYMBOL_NAME(preempt_schedule)
-+ mov r0, #I_BIT | MODE_SVC
-+ msr cpsr_c, r0 @ disable interrupts
-+ b 2b
-+3: str r8, [r9, #TSK_PREEMPT]
-+#endif
- ldr r0, [sp, #S_PSR] @ irqs are already disabled
- msr spsr, r0
- ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
-@@ -833,6 +858,9 @@
- .LCprocfns: .word SYMBOL_NAME(processor)
- #endif
- .LCfp: .word SYMBOL_NAME(fp_enter)
-+#ifdef CONFIG_PREEMPT
-+.LCirqstat: .word SYMBOL_NAME(irq_stat)
-+#endif
-
- irq_prio_table
-
-@@ -873,6 +901,12 @@
- stmdb r8, {sp, lr}^
- alignment_trap r4, r7, __temp_irq
- zero_fp
-+ get_current_task tsk
-+#ifdef CONFIG_PREEMPT
-+ ldr r0, [tsk, #TSK_PREEMPT]
-+ add r0, r0, #1
-+ str r0, [tsk, #TSK_PREEMPT]
-+#endif
- 1: get_irqnr_and_base r0, r6, r5, lr
- movne r1, sp
- adrsvc ne, lr, 1b
-@@ -880,8 +914,12 @@
- @ routine called with r0 = irq number, r1 = struct pt_regs *
- @
- bne do_IRQ
-+#ifdef CONFIG_PREEMPT
-+ ldr r0, [tsk, #TSK_PREEMPT]
-+ sub r0, r0, #1
-+ str r0, [tsk, #TSK_PREEMPT]
-+#endif
- mov why, #0
-- get_current_task tsk
- b ret_to_user
-
- .align 5
-diff -Nur linux_c860_org/arch/arm/kernel/process.c linux/arch/arm/kernel/process.c
---- linux_c860_org/arch/arm/kernel/process.c 2003-06-18 16:12:25.000000000 +0900
-+++ linux/arch/arm/kernel/process.c 2004-06-10 21:09:10.000000000 +0900
-@@ -382,7 +382,7 @@
- * a system call from a "real" process, but the process memory space will
- * not be free'd until both the parent and the child have exited.
- */
--pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-+pid_t arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
- {
- pid_t __ret;
-
-diff -Nur linux_c860_org/arch/arm/kernel/time.c linux/arch/arm/kernel/time.c
---- linux_c860_org/arch/arm/kernel/time.c 2002-08-26 14:39:49.000000000 +0900
-+++ linux/arch/arm/kernel/time.c 2004-06-10 21:09:10.000000000 +0900
-@@ -15,6 +15,7 @@
- * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
- * 1998-12-20 Updated NTP code according to technical memorandum Jan '96
- * "A Kernel Model for Precision Timekeeping" by Dave Mills
-+ * 1-Nov-2003 Sharp Corporation for Tosa
- */
- #include <linux/config.h>
- #include <linux/module.h>
-@@ -149,6 +150,15 @@
- #define do_leds()
- #endif
-
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+#define AVOID_ROLLBACK
-+#ifdef AVOID_ROLLBACK
-+int rollback_cancel = 0;
-+static unsigned long last_sec = 0;
-+static unsigned long last_usec = 0;
-+#endif
-+#endif
-+
- void do_gettimeofday(struct timeval *tv)
- {
- unsigned long flags;
-@@ -172,6 +182,25 @@
- sec++;
- }
-
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+#ifdef AVOID_ROLLBACK
-+ if (rollback_cancel && last_sec) {
-+ if (last_sec>sec && last_sec-sec<4 ) {
-+ //X printk("ERROR: time was fixed!(-%d sec)\n",last_sec-sec);
-+ sec = last_sec;
-+ usec = last_usec+1;
-+ } else if (last_sec==sec) {
-+ if (last_usec>usec) { // usec is always fixed.
-+ //X printk("ERROR: time was fixed!!(-%d usec)\n",last_usec-usec);
-+ usec = last_usec+1;
-+ }
-+ }
-+ }
-+ last_sec = sec;
-+ last_usec = usec;
-+#endif
-+#endif
-+
- tv->tv_sec = sec;
- tv->tv_usec = usec;
- }
-@@ -199,6 +228,13 @@
- time_maxerror = NTP_PHASE_LIMIT;
- time_esterror = NTP_PHASE_LIMIT;
- write_unlock_irq(&xtime_lock);
-+
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+#ifdef AVOID_ROLLBACK
-+ last_sec = 0;
-+ last_usec = 0;
-+#endif
-+#endif
- }
-
- static struct irqaction timer_irq = {
-diff -Nur linux_c860_org/arch/arm/kernel/traps.c linux/arch/arm/kernel/traps.c
---- linux_c860_org/arch/arm/kernel/traps.c 2003-01-14 12:07:55.000000000 +0900
-+++ linux/arch/arm/kernel/traps.c 2004-06-10 21:09:10.000000000 +0900
-@@ -14,6 +14,7 @@
- *
- * Change Log
- * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- *
- */
- #include <linux/config.h>
-@@ -35,7 +36,7 @@
- #include <asm/unistd.h>
-
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- #include <asm/mach-types.h>
- #include <asm/hardware.h>
- #include <asm/memory.h>
-@@ -292,10 +293,12 @@
- mm_segment_t fs;
-
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
-+#if CONFIG_PM
- extern sharpsl_fataloff(void);
- sharpsl_fataloff();
- #endif
-+#endif
-
- console_verbose();
-
-diff -Nur linux_c860_org/arch/arm/mach-pxa/Makefile linux/arch/arm/mach-pxa/Makefile
---- linux_c860_org/arch/arm/mach-pxa/Makefile 2002-11-14 10:33:31.000000000 +0900
-+++ linux/arch/arm/mach-pxa/Makefile 2004-06-10 21:09:10.000000000 +0900
-@@ -16,7 +16,8 @@
-
- export-objs := generic.o irq.o dma.o sa1111.o \
- usb_ctl.o usb_recv.o usb_send.o \
-- discovery.o cotulla_dma.o pxa_ssp.o
-+ discovery.o cotulla_dma.o pxa_ssp.o tosa.o \
-+ tosa_ac97.o
-
- # Common support (must be linked before board specific support)
- obj-y += generic.o irq.o
-@@ -33,6 +34,8 @@
- obj-$(CONFIG_SABINAL_DISCOVERY) += discovery.o discovery_arch.o pxa_ssp.o
- obj-$(CONFIG_ARCH_PXA_POODLE) += poodle.o m62332.o pxa_ssp.o poodle_buzzer.o
- obj-$(CONFIG_ARCH_PXA_CORGI) += corgi.o pxa_ssp.o poodle_buzzer.o
-+obj-$(CONFIG_ARCH_PXA_TOSA) += tosa.o pxa_nssp.o tosa_ac97.o
-+obj-$(CONFIG_BUZZER_TOSA) += tosa_buzzer.o
-
- # Support for blinky lights
- leds-y := leds.o
-@@ -66,6 +69,10 @@
- obj-$(CONFIG_BATT) += sharpsl_battery.o sharpsl_param.o
- export-objs += sharpsl_battery.o
- endif
-+ ifeq ($(CONFIG_ARCH_PXA_TOSA),y)
-+ obj-$(CONFIG_BATT) += tosa_battery.o sharpsl_param.o
-+ export-objs += tosa_battery.o
-+ endif
- else
- obj-$(CONFIG_PM) += pm.o sleep.o
- endif
-@@ -82,6 +89,9 @@
- ifeq ($(CONFIG_ARCH_PXA_CORGI),y)
- devinfo-objs-m += sharpsl_deviceinfo.o
- endif
-+ ifeq ($(CONFIG_ARCH_PXA_TOSA),y)
-+ devinfo-objs-m += sharpsl_deviceinfo.o
-+ endif
- endif
-
- obj-m += registers.o
-diff -Nur linux_c860_org/arch/arm/mach-pxa/corgi.c linux/arch/arm/mach-pxa/corgi.c
---- linux_c860_org/arch/arm/mach-pxa/corgi.c 2003-06-18 16:12:25.000000000 +0900
-+++ linux/arch/arm/mach-pxa/corgi.c 2004-06-10 21:09:10.000000000 +0900
-@@ -298,7 +298,11 @@
-
- static struct map_desc corgi_io_desc[] __initdata = {
- /* virtual physical length domain r w c b */
-+#if defined(CONFIG_CORGI_LCD_BUFF)
-+ { 0xf1000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 1 }, /* LCDC (readable for Qt driver) */
-+#else
- { 0xf1000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* LCDC (readable for Qt driver) */
-+#endif
- { 0xf2000000, 0x10800000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* SCOOP */
- { 0xf2100000, 0x0C000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }, /* Nand Flash */
- { 0xef000000, 0x00000000, 0x00800000, DOMAIN_IO, 1, 1, 1, 0 }, /* Boot Flash */
-diff -Nur linux_c860_org/arch/arm/mach-pxa/pxa_nssp.c linux/arch/arm/mach-pxa/pxa_nssp.c
---- linux_c860_org/arch/arm/mach-pxa/pxa_nssp.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/arch/arm/mach-pxa/pxa_nssp.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,57 @@
-+/*
-+ * linux/arch/arm/mach-pxa/pxa_nssp.c
-+ *
-+ * NSSP read routines for tosa (SHARP)
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/interrupt.h>
-+#include <linux/random.h>
-+#include <linux/proc_fs.h>
-+#include <linux/delay.h>
-+#include <linux/init.h>
-+#include <asm/hardware.h>
-+
-+static spinlock_t pxa_nssp_lock = SPIN_LOCK_UNLOCKED;
-+static unsigned long flag;
-+static unsigned char initialized = 0;
-+
-+void pxa_nssp_output(unsigned char reg, unsigned char data)
-+{
-+ int i;
-+ unsigned char dat = ( ((reg << 5) & 0xe0) | (data & 0x1f) );
-+
-+ spin_lock_irqsave(&pxa_nssp_lock, flag);
-+
-+ GPCR(GPIO_TG_SPI_SCLK) |= GPIO_bit(GPIO_TG_SPI_SCLK);
-+ GPCR(GPIO_TG_SPI_CS) |= GPIO_bit(GPIO_TG_SPI_CS);
-+ for(i = 0; i < 8; i++) {
-+ if( !(dat & (1<<(7-i))) )
-+ GPCR(GPIO_TG_SPI_MOSI) |= GPIO_bit(GPIO_TG_SPI_MOSI);
-+ else
-+ GPSR(GPIO_TG_SPI_MOSI) |= GPIO_bit(GPIO_TG_SPI_MOSI);
-+ GPSR(GPIO_TG_SPI_SCLK) |= GPIO_bit(GPIO_TG_SPI_SCLK);
-+ GPCR(GPIO_TG_SPI_SCLK) |= GPIO_bit(GPIO_TG_SPI_SCLK);
-+ }
-+ GPSR(GPIO_TG_SPI_CS) |= GPIO_bit(GPIO_TG_SPI_CS);
-+ spin_unlock_irqrestore(&pxa_nssp_lock, flag);
-+}
-+
-+void pxa_nssp_init(void)
-+{
-+ /* initialize SSP */
-+ set_GPIO_mode(GPIO_TG_SPI_SCLK | GPIO_OUT);
-+ set_GPIO_mode(GPIO_TG_SPI_CS | GPIO_OUT);
-+ set_GPIO_mode(GPIO_TG_SPI_MOSI | GPIO_OUT);
-+ GPSR(GPIO_TG_SPI_CS) |= GPIO_bit(GPIO_TG_SPI_CS);
-+ GPCR(GPIO_TG_SPI_SCLK) |= GPIO_bit(GPIO_TG_SPI_SCLK);
-+}
-diff -Nur linux_c860_org/arch/arm/mach-pxa/registers.c linux/arch/arm/mach-pxa/registers.c
---- linux_c860_org/arch/arm/mach-pxa/registers.c 2002-09-18 18:42:27.000000000 +0900
-+++ linux/arch/arm/mach-pxa/registers.c 2004-06-10 21:09:10.000000000 +0900
-@@ -5,7 +5,10 @@
- This code is based on SA1110's register moniter
-
- ****************************************************************************/
--
-+/*
-+ * ChangeLog:
-+ * 1-Nov-2003 Sharp Corporation for Tosa
-+ */
- /****************************************************************************
-
- registers.c: Register monitor of SA-1110
-@@ -66,6 +69,7 @@
- #include <linux/ioport.h>
- #include <asm/uaccess.h> /* to copy to/from userspace */
- #include <asm/arch/hardware.h>
-+#include <asm/io.h>
-
- //typedef unsigned long Word;
-
-@@ -74,6 +78,10 @@
- #define USE_LOCOMO
- #elif defined(CONFIG_ARCH_PXA_CORGI)
- #define USE_SCOOP
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+#define USE_SCOOP
-+#define USE_SCOOP2
-+#define USE_KUROHYO
- #endif
-
- #define MODULE_NAME "regmon"
-@@ -83,6 +91,12 @@
- #ifdef USE_SCOOP
- #define SCOOP_DIRNAME "scoop"
- #endif
-+#ifdef USE_SCOOP2
-+#define SCOOP2_DIRNAME "scoop2"
-+#endif
-+#ifdef USE_KUROHYO
-+#define KUROHYO_DIRNAME "kurohyo"
-+#endif
- #ifdef USE_LOCOMO
- #define LOCOMO_DIRNAME "locomo"
- #endif
-@@ -183,6 +197,223 @@
- SCP_REG(current_reg->phyaddr)=newRegValue;
- return (count+endp-buffer);
- }
-+#endif
-+#ifdef USE_SCOOP2
-+static ssize_t proc_scoop2_read_reg(struct file * file, char * buf,
-+ size_t nbytes, loff_t *ppos);
-+static ssize_t proc_scoop2_write_reg(struct file * file, const char * buffer,
-+ size_t count, loff_t *ppos);
-+
-+
-+static struct file_operations proc_scoop2_reg_operations = {
-+ read: proc_scoop2_read_reg,
-+ write: proc_scoop2_write_reg
-+};
-+
-+typedef struct scoop2_reg_entry {
-+ u32 phyaddr;
-+ char* name;
-+ char* description;
-+ unsigned short low_ino;
-+} scoop2_reg_entry_t;
-+
-+
-+static scoop2_reg_entry_t scoop2_regs[] =
-+{
-+/* { phyaddr, name, description } */
-+ { 0x00, "MCR", " " },
-+ { 0x04, "CDR", " " },
-+ { 0x08, "CSR", " " },
-+ { 0x0C, "CPR", " " },
-+ { 0x10, "CCR", " " },
-+ { 0x14, "IRR", " " },
-+ { 0x18, "IMR", " " },
-+ { 0x1C, "ISR", " " },
-+ { 0x20, "GPCR", " " },
-+ { 0x24, "GPWR", " " },
-+ { 0x28, "GPRR", " " }
-+};
-+
-+
-+#define NUM_OF_SCOOP2_REG_ENTRY (sizeof(scoop2_regs)/sizeof(scoop2_reg_entry_t))
-+
-+
-+static int proc_scoop2_read_reg(struct file * file, char * buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ int i_ino = (file->f_dentry->d_inode)->i_ino;
-+ char outputbuf[15];
-+ int count;
-+ int i;
-+ scoop2_reg_entry_t* current_reg=NULL;
-+ if (*ppos>0) /* Assume reading completed in previous read*/
-+ return 0;
-+ for (i=0;i<NUM_OF_SCOOP2_REG_ENTRY;i++) {
-+ if (scoop2_regs[i].low_ino==i_ino) {
-+ current_reg = &scoop2_regs[i];
-+ break;
-+ }
-+ }
-+ if (current_reg==NULL)
-+ return -EINVAL;
-+
-+ count = sprintf(outputbuf, "0x%04X\n",SCP_JC_REG(current_reg->phyaddr));
-+ *ppos+=count;
-+ if (count>nbytes) /* Assume output can be read at one time */
-+ return -EINVAL;
-+ if (copy_to_user(buf, outputbuf, count))
-+ return -EFAULT;
-+ return count;
-+}
-+
-+static ssize_t proc_scoop2_write_reg(struct file * file, const char * buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ int i_ino = (file->f_dentry->d_inode)->i_ino;
-+ scoop2_reg_entry_t* current_reg=NULL;
-+ int i;
-+ unsigned long newRegValue;
-+ char *endp;
-+
-+ for (i=0;i<NUM_OF_SCOOP2_REG_ENTRY;i++) {
-+ if (scoop2_regs[i].low_ino==i_ino) {
-+ current_reg = &scoop2_regs[i];
-+ break;
-+ }
-+ }
-+ if (current_reg==NULL)
-+ return -EINVAL;
-+
-+ newRegValue = simple_strtoul(buffer,&endp,0);
-+ SCP_JC_REG(current_reg->phyaddr)=newRegValue;
-+ return (count+endp-buffer);
-+}
-+
-+#endif
-+#ifdef USE_KUROHYO
-+static ssize_t proc_kurohyo_read_reg(struct file * file, char * buf,
-+ size_t nbytes, loff_t *ppos);
-+static ssize_t proc_kurohyo_write_reg(struct file * file, const char * buffer,
-+ size_t count, loff_t *ppos);
-+
-+
-+static struct file_operations proc_kurohyo_reg_operations = {
-+ read: proc_kurohyo_read_reg,
-+ write: proc_kurohyo_write_reg
-+};
-+
-+typedef struct kurohyo_reg_entry {
-+ u32 phyaddr;
-+ char* name;
-+ char* description;
-+ unsigned short low_ino;
-+} kurohyo_reg_entry_t;
-+
-+
-+static kurohyo_reg_entry_t kurohyo_regs[] =
-+{
-+/* { phyaddr, name, description } */
-+ { 0x000, "PINTST", " " },
-+ { 0x008, "VHLIN", " " },
-+ { 0x00A, "CMDADR_L", " " },
-+ { 0x00C, "CMDADR_H", " " },
-+ { 0x00E, "CMDFIF", " " },
-+ { 0x010, "CMDFINT", " " },
-+ { 0x012, "BINTMSK", " " },
-+ { 0x014, "BINTST", " " },
-+ { 0x016, "FIPT", " " },
-+ { 0x018, "DMAST", " " },
-+ { 0x01C, "COMD_L", " "},
-+ { 0x01E, "COMD_H", " "},
-+ { 0x022, "FIFOR", " "},
-+ { 0x024, "COMSMD", " "},
-+
-+ { 0x100, "PLCNT", " " },
-+ { 0x102, "PLCST", " " },
-+ { 0x108, "PLIST", " " },
-+ { 0x10A, "PLIEN", " " },
-+ { 0x10C, "PLSEN", " " },
-+ { 0x122, "PLDSA_L", " " },
-+ { 0x124, "PLDSA_H", " " },
-+ { 0x12A, "PLPIT_L", " " },
-+ { 0x12C, "PLPIT_H", " " },
-+ { 0x12E, "PLGMD", " " },
-+ { 0x140, "PLHT", " " },
-+ { 0x142, "PLHDS", " " },
-+ { 0x144, "PLHSS", " " },
-+ { 0x146, "PLHSE", " " },
-+ { 0x14C, "PLHPX", " " },
-+ { 0x150, "PLVT", " " },
-+ { 0x152, "PLVDS", " " },
-+ { 0x154, "PLVSS", " " },
-+ { 0x156, "PLVSE", " " },
-+ { 0x160, "PLCLN", " " },
-+ { 0x162, "PLILN", " " },
-+ { 0x164, "PLMOD", " " },
-+ { 0x166, "MISC", " " },
-+ { 0x16A, "PWHSP", " " },
-+ { 0x16C, "PWVDS", " " },
-+ { 0x16E, "PWVDE", " " },
-+ { 0x170, "PWVSP", " " },
-+ { 0x180, "VWADR_L", " " },
-+ { 0x182, "VWADR_H", " " },
-+};
-+
-+
-+#define NUM_OF_KUROHYO_REG_ENTRY (sizeof(kurohyo_regs)/sizeof(kurohyo_reg_entry_t))
-+
-+#define KUROHYO_LCD_INNER_ADDRESS (TC6393_SYS_BASE+TC6393_GC_INTERNAL_REG_BASE)
-+
-+static int proc_kurohyo_read_reg(struct file * file, char * buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ int i_ino = (file->f_dentry->d_inode)->i_ino;
-+ char outputbuf[15];
-+ int count;
-+ int i;
-+ kurohyo_reg_entry_t* current_reg=NULL;
-+ if (*ppos>0) /* Assume reading completed in previous read*/
-+ return 0;
-+ for (i=0;i<NUM_OF_KUROHYO_REG_ENTRY;i++) {
-+ if (kurohyo_regs[i].low_ino==i_ino) {
-+ current_reg = &kurohyo_regs[i];
-+ break;
-+ }
-+ }
-+ if (current_reg==NULL)
-+ return -EINVAL;
-+
-+ count = sprintf(outputbuf, "0x%04X\n",readw(KUROHYO_LCD_INNER_ADDRESS + current_reg->phyaddr));
-+ *ppos+=count;
-+ if (count>nbytes) /* Assume output can be read at one time */
-+ return -EINVAL;
-+ if (copy_to_user(buf, outputbuf, count))
-+ return -EFAULT;
-+ return count;
-+}
-+
-+static ssize_t proc_kurohyo_write_reg(struct file * file, const char * buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ int i_ino = (file->f_dentry->d_inode)->i_ino;
-+ kurohyo_reg_entry_t* current_reg=NULL;
-+ int i;
-+ unsigned long newRegValue;
-+ char *endp;
-+
-+ for (i=0;i<NUM_OF_KUROHYO_REG_ENTRY;i++) {
-+ if (kurohyo_regs[i].low_ino==i_ino) {
-+ current_reg = &kurohyo_regs[i];
-+ break;
-+ }
-+ }
-+ if (current_reg==NULL)
-+ return -EINVAL;
-+
-+ newRegValue = simple_strtoul(buffer,&endp,0);
-+ writew(newRegValue,KUROHYO_LCD_INNER_ADDRESS + current_reg->phyaddr);
-+ return (count+endp-buffer);
-+}
-
- #endif
-
-@@ -814,6 +1045,14 @@
- static struct proc_dir_entry *scoop_regdir;
- static struct proc_dir_entry *scoopdir;
- #endif
-+#ifdef USE_SCOOP2
-+static struct proc_dir_entry *scoop2_regdir;
-+static struct proc_dir_entry *scoop2dir;
-+#endif
-+#ifdef USE_KUROHYO
-+static struct proc_dir_entry *kurohyo_regdir;
-+static struct proc_dir_entry *kurohyodir;
-+#endif
-
- #ifdef USE_LOCOMO
- static struct proc_dir_entry *locomo_regdir;
-@@ -879,6 +1118,62 @@
- }
- }
- #endif
-+#ifdef USE_SCOOP2
-+ scoop2dir = proc_mkdir(SCOOP2_DIRNAME, &proc_root);
-+ if (scoop2dir == NULL) {
-+ printk(KERN_ERR MODULE_NAME": can't create /proc/" SCOOP2_DIRNAME "\n");
-+ return(-ENOMEM);
-+ }
-+
-+ scoop2_regdir = proc_mkdir(REG_DIRNAME, scoop2dir);
-+ if (scoop2_regdir == NULL) {
-+ printk(KERN_ERR MODULE_NAME": can't create /proc/" SCOOP2_DIRNAME "/" REG_DIRNAME "\n");
-+ return(-ENOMEM);
-+ }
-+
-+ for(i=0;i<NUM_OF_SCOOP2_REG_ENTRY;i++) {
-+ entry = create_proc_entry(scoop2_regs[i].name,
-+ S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH,
-+ scoop2_regdir);
-+ if(entry) {
-+ scoop2_regs[i].low_ino = entry->low_ino;
-+ entry->proc_fops = &proc_scoop2_reg_operations;
-+ } else {
-+ printk( KERN_ERR MODULE_NAME
-+ ": can't create /proc/" REG_DIRNAME
-+ "/%s\n", scoop2_regs[i].name);
-+ return(-ENOMEM);
-+ }
-+ }
-+#endif
-+#ifdef USE_KUROHYO
-+ kurohyodir = proc_mkdir(KUROHYO_DIRNAME, &proc_root);
-+ if (kurohyodir == NULL) {
-+ printk(KERN_ERR MODULE_NAME": can't create /proc/" KUROHYO_DIRNAME "\n");
-+ return(-ENOMEM);
-+ }
-+
-+ kurohyo_regdir = proc_mkdir(REG_DIRNAME, kurohyodir);
-+ if (kurohyo_regdir == NULL) {
-+ printk(KERN_ERR MODULE_NAME": can't create /proc/" KUROHYO_DIRNAME "/" REG_DIRNAME "\n");
-+ return(-ENOMEM);
-+ }
-+
-+ for(i=0;i<NUM_OF_KUROHYO_REG_ENTRY;i++) {
-+ entry = create_proc_entry(kurohyo_regs[i].name,
-+ S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH,
-+ kurohyo_regdir);
-+ if(entry) {
-+ kurohyo_regs[i].low_ino = entry->low_ino;
-+ entry->proc_fops = &proc_kurohyo_reg_operations;
-+ } else {
-+ printk( KERN_ERR MODULE_NAME
-+ ": can't create /proc/" REG_DIRNAME
-+ "/%s\n", kurohyo_regs[i].name);
-+ return(-ENOMEM);
-+ }
-+ }
-+#endif
-
- #ifdef USE_LOCOMO
- locomodir = proc_mkdir(LOCOMO_DIRNAME, &proc_root);
-@@ -925,6 +1220,18 @@
- remove_proc_entry(REG_DIRNAME, scoopdir);
- remove_proc_entry(SCOOP_DIRNAME, &proc_root);
- #endif
-+#ifdef USE_SCOOP2
-+ for(i=0;i<NUM_OF_SCOOP2_REG_ENTRY;i++)
-+ remove_proc_entry(scoop2_regs[i].name,scoop2_regdir);
-+ remove_proc_entry(REG_DIRNAME, scoop2dir);
-+ remove_proc_entry(SCOOP2_DIRNAME, &proc_root);
-+#endif
-+#ifdef USE_KUROHYO
-+ for(i=0;i<NUM_OF_KUROHYO_REG_ENTRY;i++)
-+ remove_proc_entry(kurohyo_regs[i].name,kurohyo_regdir);
-+ remove_proc_entry(REG_DIRNAME, kurohyodir);
-+ remove_proc_entry(KUROHYO_DIRNAME, &proc_root);
-+#endif
- #ifdef USE_LOCOMO
- for(i=0;i<NUM_OF_LOCOMO_REG_ENTRY;i++)
- remove_proc_entry(locomo_regs[i].name,locomo_regdir);
-diff -Nur linux_c860_org/arch/arm/mach-pxa/sharpsl_apm.c linux/arch/arm/mach-pxa/sharpsl_apm.c
---- linux_c860_org/arch/arm/mach-pxa/sharpsl_apm.c 2003-06-18 16:12:25.000000000 +0900
-+++ linux/arch/arm/mach-pxa/sharpsl_apm.c 2004-06-10 21:09:10.000000000 +0900
-@@ -49,6 +49,8 @@
- * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
- * 16-Jan-2003 SHARP sleep_on -> interruptible_sleep_on
- * 13-Mar-2003 SHARP for PXA255
-+ * 29-Jan-2004 Sharp Corporation for Tosa
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- #include <linux/config.h>
-@@ -72,6 +74,12 @@
- #include <asm/system.h>
- #include <asm/hardware.h>
-
-+extern int errno;
-+
-+// unistd.h is included for the configuration ioctl stuff
-+#define __KERNEL_SYSCALLS__ 1
-+#include <asm/unistd.h>
-+
- #ifdef CONFIG_ARCH_SHARP_SL
- #include <asm/irq.h>
- #include <asm/arch/irqs.h>
-@@ -91,7 +99,7 @@
- #define KBDOWN (0)
-
- #ifdef CONFIG_APM_CPU_IDLE
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- #define SHARPSL_NEW_IDLE
- #endif
- #endif
-@@ -99,9 +107,17 @@
- #if defined(CONFIG_SABINAL_DISCOVERY)
- extern int discovery_get_main_battery(void);
- #define get_main_battery discovery_get_main_battery
--#elif defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#elif defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
-+
- extern int sharpsl_get_main_battery(void);
- #define get_main_battery sharpsl_get_main_battery
-+
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+extern int sharpsl_jacket_battery;
-+extern int sharpsl_jacket_exist;
-+extern int sharpsl_get_cardslot_error(void);
-+#endif
-+
- #ifdef SHARPSL_NEW_IDLE
- static int chg_freq_mode = 0;
- #endif
-@@ -119,17 +135,25 @@
- extern int HWR_flag;
- #endif
-
-+#if defined(CONFIG_SL_CCCR_CHANGE)
-+extern unsigned int cccr_clkparam;
-+#endif
-+
- #if defined(CONFIG_SABINAL_DISCOVERY)
- #define SHARPSL_AC_LINE_STATUS (( ASIC3_GPIO_PSTS_D & AC_IN )? APM_AC_OFFLINE : APM_AC_ONLINE)
- #define BACKPACK_IN_DETECT() ( ASIC3_GPIO_PSTS_D & BACKPACK_DETECT ) /* 0: exist , 1: not in */
- #else
- #define SHARPSL_BATTERY_OK (( GPLR(GPIO_MAIN_BAT_LOW) & GPIO_bit(GPIO_MAIN_BAT_LOW) ) ? 1 : 0) /* 1: OK / 0: FATAL */
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+#define SHARPSL_AC_LINE_STATUS ((GPLR(GPIO_AC_IN) & GPIO_bit(GPIO_AC_IN)) ? APM_AC_OFFLINE : APM_AC_ONLINE)
-+#else
- #define SHARPSL_AC_LINE_STATUS ((GPLR(GPIO_AC_IN) & GPIO_bit(GPIO_AC_IN)) ? APM_AC_ONLINE : APM_AC_OFFLINE)
- #endif
-+#endif
-
-
- /// ioctl
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- static u32 apm_event_mask = (APM_EVT_POWER_BUTTON);
- #else
- static u32 apm_event_mask = (APM_EVT_POWER_BUTTON | APM_EVT_BATTERY_STATUS);
-@@ -151,6 +175,7 @@
-
- #endif
-
-+#define DEBUG
- #ifdef DEBUG
- #define DPRINTK(x, args...) printk(__FUNCTION__ ": " x,##args)
- #else
-@@ -339,6 +364,7 @@
- };
- #define ERROR_COUNT (sizeof(error_table)/sizeof(lookup_t))
-
-+#define APP_NAME_LIST "/etc/suspend.lst"
- /*
- * Function
- */
-@@ -347,6 +373,8 @@
- static int set_power_state(u_short what, u_short state);
- #ifndef CONFIG_SABINAL_DISCOVERY
- extern int sharpsl_main_battery;
-+extern int sharpsl_backup_battery;
-+extern int sharpsl_bu_battery;
- #endif
- static int apm_get_power_status(u_char *ac_line_status,
- u_char *battery_status,
-@@ -440,7 +468,8 @@
-
- #if defined(CONFIG_ARCH_PXA_POODLE)
- if (irq == IRQ_GPIO_ON_KEY) { /* suspend */
-- //DPRINTK("irq=%d count=%d sharpsl_suspend_request%d\n",irq, count, sharpsl_suspend_request);
-+
-+ DPRINTK("irq=%d count=%d sharpsl_suspend_request%d\n",irq, count, sharpsl_suspend_request);
- if ( GPLR(GPIO_ON_KEY) & GPIO_bit(GPIO_ON_KEY) ) {
- /* release */
- count = 0;
-@@ -623,24 +652,75 @@
- struct task_struct* p = NULL;
- struct task_struct* tsk = current;
-
-+ int fd,x;
-+ mm_segment_t old_fs = get_fs ();
-+ char line_buffer[256];
-+
- if (! spin_trylock(&lock))
- return;
-+
-+ // Try opening the send sig application name list
-+ set_fs(KERNEL_DS);
-+// printk("open sig file\n");
-+ fd = open(APP_NAME_LIST, O_RDONLY, 0);
-+ set_fs(old_fs);
-
- /* send signal to all procs except for kernel-threads */
- read_lock(&tasklist_lock);
-- for_each_task(p) {
-- struct siginfo si;
-
-- if (p->pid == 1 || p->pid == tsk->pid || is_kernel_thread(p))
-- continue;
-+ if(fd < 0){
-+ for_each_task(p) {
-+ struct siginfo si;
-+
-+ if (p->pid == 1 || p->pid == tsk->pid || is_kernel_thread(p))
-+ continue;
-+ if (!strcmp(p->comm,"cardmgr")) { //Send sig to cardmgr
-+// printk ("Send SIG to application\n");
-+ si.si_signo = signo;
-+ si.si_errno = 0;
-+ si.si_code = SI_KERNEL;
-+ si.si_pid = tsk->pid;
-+ si.si_uid = tsk->uid;
-+ send_sig_info(signo, &si, p);
-+ }
-+ }
-+
-+ }else {
-+ for(;;){
-+ memset(line_buffer, '\0', 256);
-+ set_fs(KERNEL_DS);
-+ for (x = 0; x < 256; x++) {
-+ if (!read(fd, &line_buffer[x], 1))
-+ goto sig_send_done;
-+ if (line_buffer[x] == '\n' || line_buffer[x] == '\r')
-+ break;
-+ }
-+ set_fs(old_fs);
-+
-+ for_each_task(p) {
-+ struct siginfo si;
-+
-+ if (p->pid == 1 || p->pid == tsk->pid || is_kernel_thread(p))
-+ continue;
-+ if (!strncmp(p->comm,line_buffer,strlen(p->comm))) { //Send sig to cardmgr
-+// printk ("Send SIG to application\n");
-+ si.si_signo = signo;
-+ si.si_errno = 0;
-+ si.si_code = SI_KERNEL;
-+ si.si_pid = tsk->pid;
-+ si.si_uid = tsk->uid;
-+ send_sig_info(signo, &si, p);
-+ }
-+ }
-+ }
-
-- si.si_signo = signo;
-- si.si_errno = 0;
-- si.si_code = SI_KERNEL;
-- si.si_pid = tsk->pid;
-- si.si_uid = tsk->uid;
-- send_sig_info(signo, &si, p);
-+ sig_send_done:
-+// printk("close sig\n");
-+ close(fd);
- }
-+
-+
-+
- read_unlock(&tasklist_lock);
-
- if (signo == SIGSTOP) {
-@@ -652,16 +732,58 @@
- schedule();
- set_current_state(state);
-
-+ set_fs(KERNEL_DS);
-+ fd = open(APP_NAME_LIST, O_RDONLY, 0);
-+// printk("open sigstop\n");
-+ set_fs(old_fs);
-+
- read_lock(&tasklist_lock);
-- for_each_task(p) {
-- if (p->pid == 1 || p->pid == tsk->pid || is_kernel_thread(p))
-- continue;
-
-- if (p->state != TASK_STOPPED) {
-- read_unlock(&tasklist_lock);
-- goto retry;
-+ if(fd < 0){
-+ for_each_task(p) {
-+ if (p->pid == 1 || p->pid == tsk->pid || is_kernel_thread(p))
-+ continue;
-+ if (!strcmp(p->comm,"cardmgr")) {
-+// printk ("Check application stopped\n");
-+
-+ if (p->state != TASK_STOPPED) {
-+ read_unlock(&tasklist_lock);
-+ goto retry;
-+ }
-+ }
- }
-+ }else {
-+
-+ for(;;){
-+ memset(line_buffer, '\0', 256);
-+ old_fs = get_fs();
-+ set_fs(KERNEL_DS);
-+ for (x = 0; x < 256; x++) {
-+ if (!read(fd, &line_buffer[x], 1))
-+ goto sig_stop_done;
-+ if (line_buffer[x] == '\n' || line_buffer[x] == '\r')
-+ break;
-+ }
-+ set_fs(old_fs);
-+
-+ for_each_task(p) {
-+ if (p->pid == 1 || p->pid == tsk->pid || is_kernel_thread(p))
-+ continue;
-+ if (!strncmp(p->comm,line_buffer,strlen(p->comm))) {
-+// printk ("Check application stopped\n");
-+
-+ if (p->state != TASK_STOPPED) {
-+ read_unlock(&tasklist_lock);
-+ goto retry;
-+ }
-+ }
-+ }
-+ }
-+ sig_stop_done:
-+// printk("close sigstop\n");
-+ close(fd);
- }
-+
- read_unlock(&tasklist_lock);
- }
-
-@@ -711,7 +833,11 @@
- }
-
- static spinlock_t locklockFCS = SPIN_LOCK_UNLOCKED;
-+#if 0 // for debug
-+static unsigned long lockFCS = 0x80000000;
-+#else
- static unsigned long lockFCS = 0;
-+#endif
- static int change_lockFCS = 0;
- static spinlock_t lock_power_mode = SPIN_LOCK_UNLOCKED;
- static unsigned long power_mode = 0;
-@@ -986,6 +1112,49 @@
-
- EXPORT_SYMBOL(lock_FCS);
-
-+#if defined(CONFIG_SL_CCCR_CHANGE)
-+static ssize_t cccr_change_read_params(struct file *file, char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ char outputbuf[32];
-+ int count;
-+
-+ if (*ppos>0) /* Assume reading completed in previous read*/
-+ return 0;
-+ count = sprintf(outputbuf, "0x%08X\n", (unsigned int)cccr_clkparam);
-+ count++;
-+ *ppos += count;
-+ if (count>nbytes) /* Assume output can be read at one time */
-+ return -EINVAL;
-+ if (copy_to_user(buf, outputbuf, count+1))
-+ return -EFAULT;
-+ return count;
-+}
-+
-+static ssize_t cccr_change_write_params(struct file *file, const char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ unsigned int param=0;
-+
-+ sscanf(buf,"%x",&param);
-+ if (param) {
-+ printk("Change CCCR = %x.\n",param);
-+ cccr_clkparam = param;
-+ sharpsl_chg_freq = param;
-+ cpu_xscale_sl_change_speed_num();
-+ cccr_reg = CCCR;
-+ printk("Changed CCCR = %x.\n",cccr_reg);
-+
-+ }
-+ return nbytes;
-+}
-+
-+static struct file_operations proc_cccr_change_params_operations = {
-+ read: cccr_change_read_params,
-+ write: cccr_change_write_params,
-+};
-+#endif
-+
- #ifdef CONFIG_APM_CPU_IDLE
- #ifdef SHARPSL_NEW_IDLE
- static int save_icmr;
-@@ -1021,21 +1190,35 @@
- if ( !chg_freq_mode ) {
- //LCM_LPT1 = 0x0080;
- // if (!lockFCS || ((lockFCS == LOCK_FCS_FFUART) && (!(FFMSR & MSR_DSR)))) {
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ if (!lockFCS) {
-+#else
- #if defined(CONFIG_ARCH_SHARP_SL_J)
- if (!(lockFCS & ~LOCK_FCS_FFUART)) {
- #else
- if (!lockFCS) {
- #endif
-+#endif
- #if defined(CONFIG_ARCH_PXA_POODLE)
- while(1) {
- if ( !( LCCR0 & 0x1 ) || ( GPLR(74) & GPIO_bit(74)) ) break;
- }
- #endif
-+
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ CKEN &= ~CKEN2_AC97;
-+#endif
-+
- if ( cccr_reg == 0x145 ) {
- cpu_xscale_sl_change_speed_121();
- } else {
- cpu_xscale_change_speed_121();
- }
-+
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ CKEN |= CKEN2_AC97;
-+#endif
-+
- }
- }
- chg_freq_mode = 1;
-@@ -1100,22 +1283,46 @@
- }
- #endif
- MDREFR &= ~MDREFR_APD;
--#if defined(CONFIG_ARCH_PXA_SHEPHERD)
-+
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ CKEN &= ~CKEN2_AC97;
-+#endif
-+
-+#if defined(CONFIG_ARCH_PXA_SHEPHERD) || defined(CONFIG_ARCH_PXA_TOSA)
- if ( cccr_reg == 0x161 ) {
- cpu_xscale_sl_change_speed_161();
- }
- else if ( cccr_reg == 0x145 ) {
- cpu_xscale_sl_change_speed_145();
-+#if defined(CONFIG_SL_CCCR_CHANGE)
-+ } else {
-+ cccr_clkparam = (unsigned int)cccr_reg;
-+ cpu_xscale_sl_change_speed_num();
-+ }
-+#else
- } else {
- cpu_xscale_change_speed_241();
- }
-+#endif
- #else
- if ( cccr_reg == 0x145 ) {
- cpu_xscale_sl_change_speed_145();
-+#if defined(CONFIG_SL_CCCR_CHANGE)
-+ } else {
-+ cccr_clkparam = (unsigned int)cccr_reg;
-+ cpu_xscale_sl_change_speed_num();
-+ }
-+#else
- } else {
- cpu_xscale_change_speed_241();
- }
- #endif
-+#endif
-+
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ CKEN |= CKEN2_AC97;
-+#endif
-+
- } else {
- MDREFR &= ~MDREFR_APD;
- }
-@@ -1281,6 +1488,11 @@
- u_short *battery_life)
- {
-
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+u_char dumm_status;
-+u_short dumm_life;
-+#endif
-+
- #ifdef CONFIG_SABINAL_DISCOVERY
- discovery_apm_get_power_status(ac_line_status,
- battery_status, battery_flag, battery_percentage, battery_life);
-@@ -1290,7 +1502,11 @@
- #if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
- sharpsl_apm_get_power_status(ac_line_status,
- battery_status, battery_flag, battery_percentage, battery_life);
--
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+ sharpsl_apm_get_power_status(ac_line_status,
-+ battery_status,&dumm_status,&dumm_status,battery_flag,
-+ battery_percentage,&dumm_status,&dumm_status,
-+ battery_life,&dumm_life,&dumm_life);
- #endif
- return APM_SUCCESS;
- }
-@@ -1302,12 +1518,15 @@
- u_short *battery_life)
- {
-
--#ifdef CONFIG_SABINAL_DISCOVERY
--
-+#if defined(CONFIG_SABINAL_DISCOVERY) || defined(CONFIG_ARCH_PXA_TOSA)
-+#if defined(CONFIG_SABINAL_DISCOVERY)
- discovery_apm_get_bp_status(ac_line_status,
- battery_status, battery_flag, battery_percentage, battery_life);
--
-+#else
-+ sharpsl_apm_get_bp_status(ac_line_status,
-+ battery_status, battery_flag, battery_percentage, battery_life);
- #endif // CONFIG_SABINAL_DISCOVERY
-+#endif
- return APM_SUCCESS;
- }
-
-@@ -1475,6 +1694,9 @@
- is_goto_suspend = 1;
- #ifdef CONFIG_PCMCIA
- pcmcia_set_detect_interrupt(0, 0, 1);
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ pcmcia_set_detect_interrupt(1, 0, 1);
-+#endif
- #endif
- send_sig_to_all_procs(SIGSTOP);
- /* map all suspends to ACPI D3 */
-@@ -1498,6 +1720,9 @@
- resume_handling = 1;
- #ifdef CONFIG_PCMCIA
- pcmcia_set_detect_interrupt(0, 1, 0);
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ pcmcia_set_detect_interrupt(1, 1, 0);
-+#endif
- #endif
-
- #ifdef CONFIG_SABINAL_DISCOVERY
-@@ -1533,6 +1758,9 @@
- send_sig_to_all_procs(SIGCONT);
- #ifdef CONFIG_PCMCIA
- pcmcia_set_detect_interrupt(0, 1, 1);
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ pcmcia_set_detect_interrupt(1, 1, 1);
-+#endif
- #endif
- resume_handling = 0;
-
-@@ -1681,8 +1909,9 @@
- if (send_event(event)) {
- queue_event(event, NULL);
- waiting_for_resume = 1;
-- if (suspends_pending <= 0)
-+ if (suspends_pending <= 0){
- (void) suspend();
-+ }
- }
- break;
-
-@@ -1833,7 +2062,7 @@
-
- for (;;) {
- /* Nothing to do, just sleep for the timeout */
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- timeout = 2*timeout;
- if (timeout > APM_CHECK_TIMEOUT)
- #endif
-@@ -1863,7 +2092,7 @@
-
- for (;;) {
- /* Nothing to do, just sleep for the timeout */
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- timeout = 2*timeout;
- if (timeout > APM_CHECK_TIMEOUT)
- #endif
-@@ -2012,6 +2241,7 @@
- else
- queue_event(APM_USER_SUSPEND, as);
- if (suspends_pending <= 0) {
-+
- if (suspend() != APM_SUCCESS)
- return -EIO;
- } else {
-@@ -2040,7 +2270,7 @@
- case APM_IOC_GET_REGISTER: {
- } break;
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- case APM_IOC_RESET_PM: {
- extern int sharpsl_main_bk_flag;
- sharpsl_main_bk_flag = 1;
-@@ -2114,11 +2344,14 @@
-
- case APM_IOC_BATTERY_BACK_CHK: {
- //return collie_backup_battery;
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+ return sharpsl_bu_battery;
-+#endif
- } break;
-
- case APM_IOC_BATTERY_MAIN_CHK: {
- #ifndef CONFIG_SABINAL_DISCOVERY
-- return sharpsl_main_battery;
-+ return sharpsl_main_battery;
- #endif
- } break;
-
-@@ -2132,7 +2365,7 @@
- return 1;
- } break;
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- case APM_IOC_SFREQ: {
- int freq;
- get_user(freq, (unsigned int *)(arg));
-@@ -2179,11 +2412,11 @@
- unsigned long flags;
-
- sleeping = 1;
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- sharpsl_off_mode = 1;
- #endif
- save_flags_cli(flags);
--#if defined(CONFIG_ARCH_PXA_SHEPHERD)
-+#if defined(CONFIG_ARCH_PXA_SHEPHERD) || defined(CONFIG_ARCH_PXA_TOSA)
- sharpsl_restart_nonstop();
- #else
- sharpsl_restart();
-@@ -2213,7 +2446,25 @@
- apm_event_mask = arg;
- return tmp;
- }
-+
-+ case APM_IOC_GET_CARDSLOT_ERROR: {
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ return sharpsl_get_cardslot_error();
-+#endif
-+ }
-+
-+ case APM_IOC_BATTERY_JACKET_CHK: {
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ return sharpsl_jacket_battery;
-+#endif
-+ } break;
-+
-+ case APM_IOC_GET_JACKET_STATE:
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ return sharpsl_jacket_exist;
-+#endif
- #endif
-+
- default:
- return -EINVAL;
- }
-@@ -2236,8 +2487,9 @@
- }
- if (as->suspends_pending > 0) {
- suspends_pending -= as->suspends_pending;
-- if (suspends_pending <= 0)
-+ if (suspends_pending <= 0){
- (void) suspend();
-+ }
- }
- if (user_list == as)
- user_list = as->next;
-@@ -2367,7 +2619,7 @@
- }
-
-
--#ifdef CONFIG_SABINAL_DISCOVERY
-+#if defined(CONFIG_SABINAL_DISCOVERY) || defined(CONFIG_ARCH_PXA_TOSA)
- static int apm_bp_get_info(char *buf, char **start, off_t fpos, int length)
- {
- char * p;
-@@ -2446,8 +2698,7 @@
- }
- #endif
-
--
--#ifdef CONFIG_SABINAL_DISCOVERY
-+#if defined(CONFIG_SABINAL_DISCOVERY)
- static int discovery_key_check(void *unused)
- {
-
-@@ -2457,18 +2708,28 @@
-
- while(1) {
-
-- interruptiblee_sleep_on(&fl_key);
-+ interruptible_sleep_on(&fl_key);
-
- while(1) {
- interruptible_sleep_on_timeout((wait_queue_head_t*)&queue, KEY_TICK );
-- if ( (ASIC3_GPIO_PSTS_A & PWR_ON_KEY) != 0 ) { //key up
-- break;
-- }
-+#ifdef CONFIG_SABINAL_DISCOVERY
-+ if ( (ASIC3_GPIO_PSTS_A & PWR_ON_KEY) != 0 ) { //key up
-+ break;
-+ }
-+#else
-+ if ( GPLR(GPIO_ON_KEY) & GPIO_bit(GPIO_ON_KEY) ) {
-+ break;
-+ }
-+#endif
- if ( ( jiffies - on_press_time ) < 0 ) {
-
- if ( ( jiffies + (0xffffffff - on_press_time) ) > FLONT_LIGHT_TOGGLE_TIME ) {
- if ( apm_event_mask & APM_EVT_POWER_BUTTON ) {
-+#ifdef CONFIG_SABINAL_DISCOVERY
- discoveryfl_blank_power_button();
-+#else
-+ sharpslfl_blank_power_button();
-+#endif
- } else {
- handle_scancode(SLKEY_FRONTLIGHT|KBDOWN , 1);
- handle_scancode(SLKEY_FRONTLIGHT|KBUP , 0);
-@@ -2480,7 +2741,11 @@
- if ( ( jiffies - on_press_time ) > FLONT_LIGHT_TOGGLE_TIME ) {
-
- if ( apm_event_mask & APM_EVT_POWER_BUTTON ) {
-+#ifdef CONFIG_SABINAL_DISCOVERY
- discoveryfl_blank_power_button();
-+#else
-+ tosa_l_blank_power_button();
-+#endif
- } else {
- handle_scancode(SLKEY_FRONTLIGHT|KBDOWN , 1);
- handle_scancode(SLKEY_FRONTLIGHT|KBUP , 0);
-@@ -2623,6 +2888,7 @@
- struct proc_dir_entry *apm_proc;
- struct proc_dir_entry *lock_fcs_proc;
- struct proc_dir_entry *power_mode_proc;
-+ struct proc_dir_entry *cccr_change_proc;
-
- apm_info.bios = apm_bios_info;
- if (apm_info.bios.version == 0) {
-@@ -2640,19 +2906,35 @@
- }
-
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
--#if defined(CONFIG_ARCH_PXA_SHEPHERD)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
-+#if defined(CONFIG_SL_CCCR242)
-+ sharpsl_chg_freq = (unsigned int)0x00000242;
-+ cccr_clkparam = (unsigned int)sharpsl_chg_freq;
-+ cpu_xscale_sl_change_speed_num();
-+#elif defined(CONFIG_SL_CCCR162)
-+ sharpsl_chg_freq = (unsigned int)0x00000162;
-+ cccr_clkparam = (unsigned int)sharpsl_chg_freq;
-+ cpu_xscale_sl_change_speed_num();
-+#else
-+#if defined(CONFIG_ARCH_PXA_SHEPHERD) || defined(CONFIG_ARCH_PXA_TOSA)
- sharpsl_chg_freq = (unsigned int)0x00000161;
-+#if defined(CONFIG_SL_CCCR_CHANGE)
-+ cccr_clkparam = (unsigned int)sharpsl_chg_freq;
-+#endif
- cpu_xscale_sl_change_speed_161();
- #else
- #if 1 // default 400MHz
- sharpsl_chg_freq = (unsigned int)0x00000241;
-+#if defined(CONFIG_SL_CCCR_CHANGE)
-+ cccr_clkparam = (unsigned int)sharpsl_chg_freq;
-+#endif
- #else
- cpu_xscale_sl_change_speed_145_without_lcd();
- #endif
- #endif
-+#endif
- cccr_reg = CCCR;
-- printk("FCS : CCCR = %x\n",cccr_reg);
-+// printk("FCS : CCCR = %x\n",cccr_reg);
- #endif
-
- /*
-@@ -2732,11 +3014,19 @@
- power_mode_proc->proc_fops = &proc_power_mode_params_operations;
- }
-
-+#if defined(CONFIG_SL_CCCR_CHANGE)
-+ cccr_change_proc = create_proc_entry("cccr_change", 0, NULL);
-+ if (cccr_change_proc) {
-+ cccr_change_proc->proc_fops = &proc_cccr_change_params_operations;
-+ }
-+#endif
-+
- kernel_thread(apm_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
-
--#ifdef CONFIG_SABINAL_DISCOVERY
-+#if defined(CONFIG_SABINAL_DISCOVERY) || defined(CONFIG_ARCH_PXA_TOSA)
-+#if defined(CONFIG_SABINAL_DISCOVERY)
- kernel_thread( discovery_key_check, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
--
-+#endif
- {
- struct proc_dir_entry *apm_proc_backpack;
-
-diff -Nur linux_c860_org/arch/arm/mach-pxa/sharpsl_deviceinfo.c linux/arch/arm/mach-pxa/sharpsl_deviceinfo.c
---- linux_c860_org/arch/arm/mach-pxa/sharpsl_deviceinfo.c 2002-11-14 19:27:18.000000000 +0900
-+++ linux/arch/arm/mach-pxa/sharpsl_deviceinfo.c 2004-06-10 21:09:10.000000000 +0900
-@@ -14,6 +14,10 @@
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * ChangeLog:
-+ * 1-Nov-2003 Sharp Corporation for Tosa
-+ *
- */
-
- #include <linux/config.h>
-@@ -63,7 +67,10 @@
- {"serial", "device individual id"},
- {"checksum", "ROM checksum"},
- {"bootstr", "boot string"},
-- {"hardno", "hardware number"}
-+ {"hardno", "hardware number"},
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ {"equipment", "built-in equipment"},
-+#endif
- };
-
- #define NUM_OF_DEVICEINFO_ENTRY (sizeof(deviceinfo)/sizeof(deviceinfo_entry_t))
-diff -Nur linux_c860_org/arch/arm/mach-pxa/sharpsl_param.c linux/arch/arm/mach-pxa/sharpsl_param.c
---- linux_c860_org/arch/arm/mach-pxa/sharpsl_param.c 2002-10-23 14:09:20.000000000 +0900
-+++ linux/arch/arm/mach-pxa/sharpsl_param.c 2004-06-10 21:09:10.000000000 +0900
-@@ -16,11 +16,12 @@
- * GNU General Public License for more details.
- *
- * ChangeLog:
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- *
- */
- #include <linux/types.h>
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- #include <asm/arch/sharpsl_param.h>
- #endif
-
-@@ -28,7 +29,7 @@
- sharpsl_flash_param_info sharpsl_flash_param;
-
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- int sharpsl_get_comadj()
- {
- if ( sharpsl_flash_param.comadj_keyword == FLASH_COMADJ_MAJIC ) {
-@@ -39,7 +40,7 @@
- }
- #endif
-
--#if defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- int sharpsl_get_phadadj()
- {
- if ( sharpsl_flash_param.phad_keyword == FLASH_PHAD_MAJIC ) {
-@@ -51,7 +52,7 @@
- #endif
-
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- void sharpsl_get_param(void)
- {
- // get comadj
-diff -Nur linux_c860_org/arch/arm/mach-pxa/sharpsl_power.c linux/arch/arm/mach-pxa/sharpsl_power.c
---- linux_c860_org/arch/arm/mach-pxa/sharpsl_power.c 2003-10-09 14:47:25.000000000 +0900
-+++ linux/arch/arm/mach-pxa/sharpsl_power.c 2004-06-10 21:09:10.000000000 +0900
-@@ -35,6 +35,8 @@
- * 16-Jan-2003 SHARP sleep_on -> interruptible_sleep_on
- * 09-Apr-2003 SHARP for Shaphard (software reset)
- * October-2003 SHARP for boxer
-+ * 28-Nov-2003 Sharp Corporation for Tosa
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- *
- */
-
-@@ -42,12 +44,17 @@
- /*
- * Debug macros
- */
-+//#define DEBUG 1
- #ifdef DEBUG
- # define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
- #else
- # define DPRINTK(fmt, args...)
- #endif
-
-+//#define WUPSRC_DEBUG
-+#ifdef WUPSRC_DEBUG
-+unsigned int debug1,debug2,debug3,debug4;
-+#endif
-
- #include <linux/config.h>
- #include <linux/module.h>
-@@ -82,8 +89,15 @@
- #include <asm/arch/keyboard_poodle.h>
- #elif defined(CONFIG_ARCH_PXA_CORGI)
- #include <asm/arch/keyboard_corgi.h>
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+#include <asm/arch/keyboard_tosa.h>
-+#include <linux/ac97_codec.h>
- #endif
-
-+#ifdef LOGICAL_WAKEUP_SRC
-+#include <asm/arch/sharpsl_wakeup.h>
-+unsigned long logical_wakeup_src_mask = IDPM_WAKEUP_REC|IDPM_WAKEUP_SYNC;
-+#endif
- #include "sharpsl_param.h"
-
-
-@@ -116,9 +130,16 @@
- extern int cpu_pxa_do_suspend(void);
- extern unsigned short chkFatalBatt(void);
- extern int sharpsl_off_charge_battery(void);
--void pxa_ssp_init(void);
-+extern int charge_status;
-
- #if defined(CONFIG_ARCH_PXA_POODLE)
-+void pxa_ssp_init(void);
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+void tosa_ac97_init(void);
-+int pxa_ac97_get(struct ac97_codec **codec, unsigned char *ac97_on);
-+static unsigned char ac97_on = 0;
-+#endif
-+#if defined(CONFIG_ARCH_PXA_POODLE)
- #define PWER_RTC 0x80000000
- #define R_WAKEUP_SRC (GPIO_bit(GPIO_AC_IN) | GPIO_bit(GPIO_CF_STSCHG) /*|
- GPIO_bit(GPIO_CHRG_FULL) */ )
-@@ -139,6 +160,32 @@
- GPIO_bit(GPIO_AC_IN) | GPIO_bit(GPIO_MAIN_BAT_LOW))
- #define WAKEUP_SRC ( R_WAKEUP_SRC | F_WAKEUP_SRC | PWER_RTC )
- #define WAKEUP_DEF_SRC ( WAKEUP_SRC );
-+
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+/*
-+<F_WAKEUP_SRC>
-+GPIO_POWERON (0)
-+GPIO_AC_IN (2)
-+GPIO_RECORD_BTN (3)
-+GPIO_SYNC (4)
-+GPIO_USB_IN (5)
-+GPIO_JACKET_DETECT (7)
-+GPIO_nSD_DETECT (9)
-+GPIO_nSD_INT (10)
-+GPIO_BAT1_CRG (12)
-+GPIO_CF_CD (13)
-+GPIO_BAT0_CRG (14)
-+*/
-+#define PWER_RTC 0x80000000
-+#define R_WAKEUP_SRC (GPIO_bit(GPIO_AC_IN) | GPIO_bit(GPIO_JACKET_DETECT))
-+#define F_WAKEUP_SRC (GPIO_bit(GPIO_POWERON) | GPIO_bit(GPIO_RESET) | \
-+ GPIO_bit(GPIO_AC_IN) | GPIO_bit(GPIO_RECORD_BTN) | \
-+ GPIO_bit(GPIO_SYNC) | GPIO_bit(GPIO_USB_IN) | \
-+ GPIO_bit(GPIO_JACKET_DETECT) )
-+#define WAKEUP_SRC ( R_WAKEUP_SRC | F_WAKEUP_SRC | PWER_RTC )
-+#define WAKEUP_DEF_SRC ( GPIO_bit(GPIO_POWERON) | GPIO_bit(GPIO_RESET) | \
-+ GPIO_bit(GPIO_AC_IN) | GPIO_bit(GPIO_JACKET_DETECT) | \
-+ GPIO_bit(GPIO_RECORD_BTN) | GPIO_bit(GPIO_SYNC) )
- #endif
-
- #if defined(CONFIG_SABINAL_DISCOVERY)
-@@ -148,6 +195,7 @@
- u32 sharpsl_emergency_off = 0;
- unsigned int sharpsl_chg_freq = 0x0145;
- static DECLARE_WAIT_QUEUE_HEAD(wq_off);
-+static DECLARE_WAIT_QUEUE_HEAD(key_off);
- int sharpsl_off_mode = 0;
- int sharpsl_off_state = 0;
- int pass_charge_flag = 0;
-@@ -158,18 +206,26 @@
- extern int corgi_wakeup_remocon_hook(void);
- #endif
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- extern unsigned long cccr_reg;
- static int sharpsl_alarm_flag;
- #endif
-
-+//@@#if defined(CONFIG_ARCH_PXA_TOSA)
-+//@@extern int sharpsl_get_jacket_status(void);
-+//@@#endif
-+
-+#if defined(CONFIG_SL_CCCR_CHANGE)
-+extern unsigned int cccr_clkparam;
-+#endif
-+
- void PrintParamTable(void);
-
- #ifdef CONFIG_SABINAL_DISCOVERY
- static u32 alarm_enable=0;
- #endif
-
--#ifdef CONFIG_ARCH_PXA_SHEPHERD
-+#if defined(CONFIG_ARCH_PXA_SHEPHERD) || defined(CONFIG_ARCH_PXA_TOSA)
- int sharpsl_restart(void)
- {
- return sharpsl_restart_core(0);
-@@ -183,16 +239,23 @@
- int sharpsl_restart_core(int nonstop_flag)
- {
- int flag = 1;
--
-+#if !defined(CONFIG_ARCH_PXA_TOSA)
- if (nonstop_flag) {
- SCP_REG_GPWR |= SCP_LED_GREEN;
- }
- else {
- SCP_REG_GPWR &= ~SCP_LED_GREEN;
- }
--
-+#endif
- RCSR = 0xf;
-
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ if( nonstop_flag && ((MSC0 & 0xffff0000) == 0x7ff00000) )
-+ MSC0 = (MSC0 & 0xffff)|0x7ee00000;
-+ // GPIO reset
-+ set_GPIO_mode(GPIO_ON_RESET | GPIO_OUT);
-+ GPCR(GPIO_ON_RESET) |= GPIO_bit(GPIO_ON_RESET);
-+#else
- OSMR3 = OSCR+0x100;
- OWER = 0x01;
- OIER |= 0x08;
-@@ -200,7 +263,7 @@
- while(1) {
- if ( flag++ > 0x20000000 ) break;
- }
--
-+#endif
- return 0;
- }
- #else
-@@ -258,17 +321,47 @@
-
- #if !defined(CONFIG_SABINAL_DISCOVERY)
-
--#if defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- int sharpsl_wakeup_check_charge(void)
- {
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ unsigned int pfer;
-+ unsigned int prer;
-+
-+ pfer = F_WAKEUP_SRC & apm_wakeup_src_mask & WAKEUP_SRC;
-+ prer = R_WAKEUP_SRC & apm_wakeup_src_mask & WAKEUP_SRC;
-+ //printk("pfer = %08x",pfer);
-+ //printk("prer = %08x",prer);
-+
-+ pfer &= ~(F_WAKEUP_SRC & R_WAKEUP_SRC);
-+ prer &= ~(F_WAKEUP_SRC & R_WAKEUP_SRC);
-+ //printk("pfer = %08x",pfer);
-+ //printk("prer = %08x",prer);
-+
-+ pfer = ~GPLR0 & pfer;
-+ prer = GPLR0 & prer;
-+ //printk("pfer = %08x",pfer);
-+ //printk("prer = %08x",prer);
-+
-+ if(pfer != 0 || prer != 0){
-+ apm_wakeup_factor = pfer | prer;
-+ return 0; // wakeup
-+ }
-+
-+ if ( ( ( RTAR - RCNR ) < 20 ) && ( RTSR & RTSR_ALE ) ) {
-+ return -1; // go off.
-+ }
-+
-+ return 1; // continue.
-+#else
- unsigned int temp;
-
- temp = ~GPLR0 & ( GPIO_bit(GPIO_AC_IN) | GPIO_bit(GPIO_KEY_INT) | GPIO_bit(GPIO_WAKEUP) );
- if ( temp != 0 ) {
- apm_wakeup_factor = temp;
- }
--
- return temp;
-+#endif
- }
- #endif
-
-@@ -276,31 +369,71 @@
- {
- int i;
- u32 gplr;
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ int batt_fault = ((PSSR & 0x02) != 0);
-+#endif
-
- /* setting GPIO */
- GPDR0 = sys_ctx.gpdr0;
- GAFR0_L = sys_ctx.gafr0_l;
- GPDR0 &= ~WAKEUP_SRC;
-- GAFR0_L &= ~WAKEUP_SRC;
-+// GAFR0_L &= ~WAKEUP_SRC;
- gplr = GPLR0;
-
-+#ifdef WUPSRC_DEBUG
-+ debug1 = PEDR;
-+ debug2 = WAKEUP_SRC;
-+ debug3 = apm_wakeup_src_mask;
-+ debug4 = PSSR;
-+#endif
- apm_wakeup_factor = PEDR & WAKEUP_SRC & apm_wakeup_src_mask;
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- apm_wakeup_factor &= ~0x80000000; /* clear ALARM */
- if ( ( RTSR & 0x1 ) && ( RTSR & RTSR_ALE ) )
- #else
- if ( RTSR & 0x1 )
- #endif
- apm_wakeup_factor |= 0x80000000; /* ALARM */
-+
-+
- PEDR = WAKEUP_SRC;
-
-- if ( !apm_wakeup_factor )
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ if(batt_fault) PSSR = 0x02; /* clear BFS bit */
-+#endif
-+
-+ if ( !apm_wakeup_factor ){
- return 0; /* no wakeup factor */
-+ }
-
- #if defined(CONFIG_ARCH_PXA_CORGI)
- gplr &= ~GPIO_bit(GPIO_KEY_INT);
- #endif
-
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ //if(PSSR & 0x02){
-+ if(batt_fault){
-+ // Asserted battery fault.
-+ // It must have changed the main battery.
-+ if(GPIO_bit(GPIO_POWERON) & apm_wakeup_factor){
-+ int change_ac_status = 0;
-+ if ( apm_wakeup_src_mask & GPIO_bit(GPIO_AC_IN)){
-+ if ( !charge_status && ( gplr & GPIO_bit(GPIO_AC_IN) ) == 0)
-+ change_ac_status = 1;
-+
-+ if ( charge_status && ( gplr & GPIO_bit(GPIO_AC_IN) ) != 0)
-+ change_ac_status = 1;
-+ }
-+ if(change_ac_status)
-+ apm_wakeup_factor |= GPIO_bit(GPIO_AC_IN);
-+
-+ return apm_wakeup_factor;
-+ }
-+ if(GPIO_bit(GPIO_RESET) & apm_wakeup_factor){
-+ return apm_wakeup_factor;
-+ }
-+ }
-+#endif
- /* Faulty operation check */
- for (i = 0; i <= 15; i++) {
- #if defined(CONFIG_ARCH_PXA_CORGI)
-@@ -329,27 +462,56 @@
- u32 gplr = GPLR0;
- int is_resume = 0;
-
-+ DPRINTK("GPLR0 = %x\n",gplr);
-+#ifdef WUPSRC_DEBUG
-+ printk("PEDR=%08x\n",debug1);
-+ printk("src=%08x\n",debug2);
-+ printk("src_mask=%08x\n",debug3);
-+ printk("PSSR=%08x->%08x\n",debug4,PSSR);
-+#endif
- if ( (apm_wakeup_factor & GPIO_bit(GPIO_AC_IN)) &&
- sharpsl_battery_charge_hook ) {
-+
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ if ( !(gplr & GPIO_bit(GPIO_AC_IN)) ) {
-+#else
- if ( gplr & GPIO_bit(GPIO_AC_IN) ) {
-+#endif
- sharpsl_battery_charge_hook(2); /* charge on */
- } else
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ if ( gplr & GPIO_bit(GPIO_AC_IN) ) {
-+#else
- if ( !( gplr & GPIO_bit(GPIO_AC_IN) ) ) {
-+#endif
- sharpsl_battery_charge_hook(1); /* charge off */
- }
- }
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ if ( (apm_wakeup_factor & GPIO_bit(GPIO_BAT0_CRG)) &&
-+ sharpsl_battery_charge_hook ) {
-+ sharpsl_battery_charge_hook(0); /* tosa: main battery full */
-+ }
-+ if ( (apm_wakeup_factor & GPIO_bit(GPIO_BAT1_CRG)) &&
-+ sharpsl_battery_charge_hook ) {
-+ sharpsl_battery_charge_hook(3); /* tosa: jacket battery full */
-+ }
-+#else
- if ( (apm_wakeup_factor & GPIO_bit(GPIO_CHRG_FULL)) &&
- sharpsl_battery_charge_hook ) {
- sharpsl_battery_charge_hook(0); /* charge off */
- }
-+#endif
-+
- #if defined(CONFIG_ARCH_PXA_POODLE)
- if ( apm_wakeup_factor & GPIO_bit(GPIO_ON_KEY) )
- is_resume |= GPIO_bit(GPIO_ON_KEY);
- #endif
- #if defined(CONFIG_ARCH_PXA_CORGI)
- if ( apm_wakeup_factor & GPIO_bit(GPIO_KEY_INT) ) {
-- if (sharppda_kbd_is_wakeup())
-+ if (sharppda_kbd_is_wakeup()){
- is_resume |= GPIO_bit(GPIO_KEY_INT);
-+ }
- }
- #if defined(CONFIG_ARCH_PXA_SHEPHERD)
- if ((apm_wakeup_factor & GPIO_bit(GPIO_MAIN_BAT_LOW)) &&
-@@ -373,14 +535,15 @@
- ( sharpsl_battery_charge_hook )) {
- sharpsl_battery_charge_hook(1); /* charge off */
- }
--
- #else
- if ( apm_wakeup_factor & GPIO_bit(GPIO_MAIN_BAT_LOW) )
- apm_wakeup_src_mask = 0;
- #endif
- #endif
-+#if !defined(CONFIG_ARCH_PXA_TOSA)
- if ( apm_wakeup_factor & GPIO_bit(GPIO_WAKEUP) )
- is_resume |= GPIO_bit(GPIO_WAKEUP);
-+#endif
- #if defined(CONFIG_ARCH_PXA_POODLE)
- if ( (apm_wakeup_factor & GPIO_bit(GPIO_GA_INT)) && (LCM_KIC & 1) ) {
- LCM_KIC &= ~0x100;
-@@ -397,28 +560,116 @@
- #endif
- #if defined(CONFIG_ARCH_PXA_CORGI)
- if ( apm_wakeup_factor & GPIO_bit(GPIO_AK_INT) ) {
-- if ( corgi_wakeup_remocon_hook() )
-+ if ( corgi_wakeup_remocon_hook() ){
- is_resume |= GPIO_bit(GPIO_AK_INT);
-+ }
-+ }
-+#endif
-+
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ if ( (apm_wakeup_factor & GPIO_bit(GPIO_AC_IN)) ) {
-+#ifdef LOGICAL_WAKEUP_SRC
-+ if (logical_wakeup_src_mask&IDPM_WAKEUP_AC) {
-+ is_resume |= GPIO_bit(GPIO_AC_IN);
-+ }
-+#endif
-+ }
-+ if (apm_wakeup_factor & GPIO_bit(GPIO_POWERON)) { // function key
-+ if (sharppda_kbd_is_wakeup()){
-+ is_resume |= GPIO_bit(GPIO_POWERON);
-+ }
-+ }
-+ if (apm_wakeup_factor & GPIO_bit(GPIO_RECORD_BTN)) { // rec key
-+ if (sharppda_kbd_is_wakeup()){
-+ is_resume |= GPIO_bit(GPIO_RECORD_BTN);
-+ }
-+ }
-+ if (apm_wakeup_factor & GPIO_bit(GPIO_SYNC)) { // sync key
-+ if (sharppda_kbd_is_wakeup()){
-+ is_resume |= GPIO_bit(GPIO_SYNC);
-+ }
-+ }
-+ if (apm_wakeup_factor & GPIO_bit(GPIO_USB_IN)) {
-+#ifdef LOGICAL_WAKEUP_SRC
-+ if (logical_wakeup_src_mask&IDPM_WAKEUP_USBD) {
-+ is_resume |= GPIO_bit(GPIO_USB_IN);
-+ }
-+#endif
-+ }
-+ if (apm_wakeup_factor & GPIO_bit(GPIO_JACKET_DETECT)){
-+ sharpsl_battery_charge_hook(4);
-+#ifdef LOGICAL_WAKEUP_SRC
-+ if (logical_wakeup_src_mask&IDPM_WAKEUP_JACKET) {
-+ is_resume |= GPIO_bit(GPIO_JACKET_DETECT);
-+ }
-+#endif
- }
- #endif
-
-- DPRINTK("alarm flag = %8x\n",sharpsl_alarm_flag);
-- if ( ( apm_wakeup_factor & PWER_RTC ) && !sharpsl_alarm_flag)
-+ if ( ( apm_wakeup_factor & PWER_RTC ) && !sharpsl_alarm_flag){
- is_resume |= PWER_RTC;
-+ }
-
- return is_resume;
- }
- #endif
-
--
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+#define BATTERY_CHECK_TIME (60*5) // 5 min
-+#else
- #define BATTERY_CHECK_TIME 60*10 // 10 min
--extern int charge_status;
-+#endif
-+
-+//extern int charge_status;
- extern int sharpsl_off_charge;
-
-
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+#if 0 /////////////////////////////////////////////////////////
-+static void tc6393_susx(void)
-+{
-+#if 1
-+ reset_scoop_jc_gpio(SCP_JC_TC3693_L3V_ON);
-+// reset_scoop_jc_gpio(SCP_JC_TC6393_SUSPEND);
-+// reset_scoop_gpio(SCP_TC6393_REST_IN);
-+#endif
-+
-+// TC6393_SYS_REG(TC6393_SYS_GPOOECR1) = TC6393_CARD_VCC_ON;
-+// TC6393_SYS_REG(TC6393_SYS_GPODSR1) = 0; /* CARD_VCC_OFF */
-+#if 1
-+// TC6393_SYS_REG(TC6393_SYS_GPOOECR1) = TC6393_GPO_OE;
-+// TC6393_SYS_REG(TC6393_SYS_GPOOECR1) = TC6393_CARD_VCC_ON;
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) |= TC6393_CARD_VCC_ON;
-+ TC6393_SYS_REG(TC6393_SYS_GPOOECR1) = TC6393_GPO_OE;
-+#endif
-+}
-+
-+static void tc6393_resx(void)
-+{
-+ set_GPIO_mode(GPIO11_3_6MHz_MD);
-+ set_GPIO_mode(GPIO18_RDY_MD);
-+ mdelay(1);
-+ set_scoop_jc_gpio(SCP_JC_TC6393_SUSPEND);
-+ mdelay(10);
-+ set_scoop_gpio(SCP_TC6393_REST_IN);
-+ //set_scoop_jc_gpio(SCP_JC_TC3693_L3V_ON);
-+ TC6393_SYS_REG(TC6393_SYS_FER) = 0;
-+ /* clock setting */
-+ TC6393_SYS_REG(TC6393_SYS_PLL2CR) = 0x0cc1;
-+ TC6393_SYS_REG(TC6393_SYS_CCR) = 0x1310;
-+ TC6393_SYS_REG(TC6393_SYS_MCR) = 0x80AA;
-+ /* GPIO */
-+ TC6393_SYS_REG(TC6393_SYS_GPER) = 0x0030; /* 15-0 GPO */
-+ TC6393_SYS_REG(TC6393_SYS_GPOOECR1) = TC6393_GPO_OE;
-+ /* 15-0 GPO set H */
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) = TC6393_CARD_VCC_ON;
-+}
-+#endif ///////////////////////////////////////////////
-+#endif
-
- int pxa_suspend(void)
- {
-+
- unsigned long flags;
- #if defined (CONFIG_SABINAL_DISCOVERY)
- unsigned long RTAR_buffer;
-@@ -426,10 +677,11 @@
- #else
- unsigned long RTAR_buffer;
- unsigned long RTAR_buffer2;
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ unsigned long RCNR_buffer;
-+#endif
- #endif
-
--
--
- #ifndef CONFIG_SABINAL_DISCOVERY
- sharpsl_off_state = 1;
-
-@@ -459,13 +711,22 @@
- cpu_xscale_sl_change_speed_145_without_lcd();
- cccr_reg = CCCR;
- break;
--#if defined(CONFIG_ARCH_PXA_SHEPHERD)
-+#if defined(CONFIG_ARCH_PXA_SHEPHERD) || defined(CONFIG_ARCH_PXA_TOSA)
- case 0x161:
- if ( CCCR == 0x0161 ) break;
- cpu_xscale_sl_change_speed_161();
- cccr_reg = CCCR;
- break;
- #endif
-+#if defined(CONFIG_SL_CCCR_CHANGE)
-+ default:
-+ if ( (sharpsl_chg_freq & 0xffff) !=0 ){
-+ cccr_clkparam = (unsigned int)(sharpsl_chg_freq & 0xffff);
-+ cpu_xscale_sl_change_speed_num();
-+ cccr_reg = CCCR;
-+ }
-+ break;
-+#endif
- }
- sharpsl_chg_freq &= 0x0000ffff;
- mdelay(500);
-@@ -473,7 +734,7 @@
- }
- #endif
-
--#if defined(CONFIG_ARCH_PXA_SHEPHERD)
-+#if defined(CONFIG_ARCH_PXA_SHEPHERD) || defined(CONFIG_ARCH_PXA_TOSA)
- if (sharpsl_off_mode == 2) sharpsl_restart(); /* off in maintenance */
- #endif
-
-@@ -553,7 +814,7 @@
- ASIC3_GPIO_INTSTAT_D = 0;
- #endif
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- if ( CCCR != 0x241 ) {
- cpu_xscale_sl_change_speed_241_without_lcd();
- }
-@@ -561,20 +822,39 @@
- DPRINTK("FCS : CCCR = %x\n",cccr_reg);
- #endif
-
--
--DO_SUSPEND:
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ // check jacket status.
-+ sharpsl_request_dac_init(); // in sharpsl_battery.c
-+ if(sharpsl_battery_charge_hook)
-+ sharpsl_battery_charge_hook(4); // check jacket.
-+#endif
-
-+DO_SUSPEND:
-
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
-+ DPRINTK("pass_charge_flag = %d\n",pass_charge_flag);
- if ( !pass_charge_flag ) {
- // not charging and AC-IN !
-- if ( !charge_status && ( GPLR(GPIO_AC_IN) & GPIO_bit(GPIO_AC_IN)) != 0 ) {
-+
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ DPRINTK("check AC-adaptor\n");
-+ if ( !charge_status && ( GPLR(GPIO_AC_IN) & GPIO_bit(GPIO_AC_IN) ) == 0){
-+#else
-+ if ( !charge_status && ( GPLR(GPIO_AC_IN) & GPIO_bit(GPIO_AC_IN)) != 0){
-+#endif
- DPRINTK("kick charging\n");
- charge_status = 1;
- sharpsl_off_charge_battery();
- }
- }
-
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ tosa_check_ac_and_jacket_state();
-+ DPRINTK("ac97&tc6393 down\n");
-+ tc6393_suspend();
-+ tosa_ac97_exit();
-+#endif
-+
- if ( charge_status ) {
- if ( ( ( RTAR - RCNR ) < ( BATTERY_CHECK_TIME + 30 ) ) && ( RTSR & RTSR_ALE ) ) {
- // maybe alarm will occur
-@@ -611,6 +891,8 @@
- } else {
- PGSR1 &= ~GPIO_bit(GPIO43_BTTXD);
- }
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+// non
- #endif
-
- #endif
-@@ -657,12 +939,12 @@
- LCM_ICR &= ~0x100;
- #endif
-
--#if !defined(CONFIG_SABINAL_DISCOVERY)
-+#if !defined(CONFIG_SABINAL_DISCOVERY)
- /* Scoop suspend */
- sys_ctx.scp_gpwr = SCP_REG_GPWR;
- SCP_REG_GPWR = 0;
--#endif
-
-+#endif
- sys_ctx.gpdr0 = GPDR0;
- sys_ctx.gpdr1 = GPDR1;
- sys_ctx.gpdr2 = GPDR2;
-@@ -718,7 +1000,9 @@
- PWER = WAKEUP_SRC & apm_wakeup_src_mask;
- PRER = R_WAKEUP_SRC & apm_wakeup_src_mask;
- PFER = F_WAKEUP_SRC & apm_wakeup_src_mask;
-+
- PEDR = WAKEUP_SRC & apm_wakeup_src_mask;
-+
- for (i = 0; i <=15; i++) {
- if ( PRER & PFER & GPIO_bit(i) ) {
- if ( GPLR0 & GPIO_bit(i) )
-@@ -728,14 +1012,13 @@
- }
- }
-
--
- /* Clear reset status */
- RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-
- /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
- PCFR = PCFR_OPDE;
-
--#ifdef CONFIG_ARCH_PXA_CORGI
-+#if defined(CONFIG_ARCH_PXA_CORGI)
- /* GPIO Sleep Register */
- PGSR2 = (PGSR2 & ~GPIO_ALL_STROBE_BIT) | GPIO_STROBE_BIT(0);
-
-@@ -747,6 +1030,19 @@
- #endif
- GPDR1 = 0x00FFAFC3;
- GPDR2 = 0x0001C004;
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+ /* GPIO Sleep Register */
-+ PGSR1 = (PGSR1 & ~GPIO_LOW_STROBE_BIT);
-+ PGSR2 = (PGSR2 & ~GPIO_HIGH_STROBE_BIT);
-+#ifdef LOGICAL_WAKEUP_SRC
-+ if (logical_wakeup_src_mask &
-+ (IDPM_WAKEUP_ADDRESSBOOK|IDPM_WAKEUP_CALENDAR|IDPM_WAKEUP_MENU|IDPM_WAKEUP_MAIL)) {
-+ PGSR1 |= GPIO_STROBE_BIT(4);
-+ }
-+#endif
-+ GPDR0 = 0xC3810940;
-+ GPDR1 = 0xFCFFAB82;
-+ GPDR2 = 0x000F501f;
- #endif
- }
- #endif
-@@ -764,7 +1060,6 @@
-
- #if !defined(CONFIG_SABINAL_DISCOVERY)
- sharpsl_wakeup_check();
--
- FFMCR = sys_ctx.ffmcr;
- FFSPR = sys_ctx.ffspr;
- FFLCR = sys_ctx.fflcr;
-@@ -847,15 +1142,42 @@
- #endif
-
- #if !defined(CONFIG_SABINAL_DISCOVERY)
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ if ( sharpsl_alarm_flag ) {
-+ RCNR_buffer = RCNR;
-+ }
-+ DPRINTK("ac97&tc6393 up\n");
-+ tosa_ac97_init();
-+ pxa_ac97_get(&codec,&ac97_on); // initialize 'codec' pointer
-+ i2c_init(1);
-+ tc6393_resume();
-+
-+ sharpsl_request_dac_init(); // in sharpsl_battery.c
-+#else
- pxa_ssp_init();
-+#endif
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- if ( sharpsl_alarm_flag ) {
- RTAR_buffer2 = RTAR;
- RTAR = RTAR_buffer;
- DPRINTK("back the ALARM Time\n");
- }
-
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ if ( sharpsl_alarm_flag && ( RCNR_buffer == RTAR_buffer2 ) ) {
-+ //printk("RCNR_buffer=%d\n",RCNR_buffer);
-+ if(sharpsl_battery_charge_hook)
-+ sharpsl_battery_charge_hook(5);
-+#if 1
-+ if(tosa_check_charge_full(BATTERY_CHECK_TIME) < 0) {
-+ goto DO_SUSPEND;
-+ }
-+#else
-+ goto DO_SUSPEND;
-+#endif
-+ }
-+#else
- if ( sharpsl_alarm_flag && ( RCNR == RTAR_buffer2 ) ) {
- if ( sharpsl_off_charge_battery() ) {
- DPRINTK("charge timer \n");
-@@ -863,6 +1185,7 @@
- }
- }
- #endif
-+#endif
-
- /* ----- hardware resume ----- */
- if ( !sharpsl_wakeup_hook() ) {
-@@ -877,6 +1200,19 @@
- printk("return to suspend (fatal) ....\n");
- goto DO_SUSPEND;
- }
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+ if ( (GPLR(GPIO_AC_IN) & GPIO_bit(GPIO_AC_IN)) == 0){
-+ if(sharpsl_off_charge_battery() < 0){
-+ printk("return to suspend (no main batt) ....\n");
-+ goto DO_SUSPEND;
-+ }
-+ }
-+
-+ if ( ( (GPLR(GPIO_BAT_LOCKED) & GPIO_bit(GPIO_BAT_LOCKED)) == 0 )
-+ || ( !sharpsl_off_mode && chkFatalBatt() == 0 ) ) {
-+ printk("return to suspend (fatal) ....\n");
-+ goto DO_SUSPEND;
-+ }
- #else
- if ( ( (GPLR(GPIO_MAIN_BAT_LOW) & GPIO_bit(GPIO_MAIN_BAT_LOW)) == 0 )
- || ( chkFatalBatt() == 0 ) ) {
-@@ -888,7 +1224,7 @@
- #endif
-
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- PMCR = 0x01;
-
- if ( sharpsl_off_mode )
-@@ -896,24 +1232,33 @@
- #endif
-
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- if ( sharpsl_chg_freq == 0x0145 ) {
- cpu_xscale_sl_change_speed_145_without_lcd();
-+#if defined(CONFIG_ARCH_PXA_SHEPHERD) || defined(CONFIG_ARCH_PXA_TOSA)
- }
--#if defined(CONFIG_ARCH_PXA_SHEPHERD)
- else if ( sharpsl_chg_freq == 0x0161 ) {
- cpu_xscale_sl_change_speed_161();
-+#endif
-+#if defined(CONFIG_SL_CCCR_CHANGE)
- }
-+ else if ( sharpsl_chg_freq != 0x0 ){
-+ cccr_clkparam = (unsigned int)sharpsl_chg_freq;
-+ cpu_xscale_sl_change_speed_num();
- #endif
-+ }
-+
- cccr_reg = CCCR;
- printk("FCS : CCCR = %x\n",cccr_reg);
- #if defined(CONFIG_ARCH_PXA_SHEPHERD) && !defined(CONFIG_ARCH_SHARP_SL_J)
- sharpsl_off_charge = 1;
- #else
-+
- sharpsl_off_charge = 0;
- #endif
- #endif
-
-+
- #if 1 // ensure that OS Timer irq occurs
- OSMR0 = sys_ctx.oscr + LATCH;
- #else
-@@ -1004,16 +1349,14 @@
- int pm_do_suspend(void)
- {
- int retval;
--
-- DPRINTK("yea\n");
--
- retval = pm_send_all(PM_SUSPEND, (void *)2);
-- if (retval)
-+ if (retval)
- return retval;
-
- retval = pxa_suspend();
-
- retval = pm_send_all(PM_RESUME, (void *)0);
-+
- if (retval)
- return retval;
-
-@@ -1040,7 +1383,7 @@
-
-
-
--int pxa_fatal_suspend(void)
-+static int pxa_fatal_suspend(void)
- {
- unsigned long flags;
- unsigned long RTAR_buffer;
-@@ -1056,7 +1399,7 @@
- save_flags_cli(flags);
- clf();
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- if ( CCCR != 0x241 ) {
- cpu_xscale_sl_change_speed_241_without_lcd();
- }
-@@ -1092,6 +1435,8 @@
- PGSR1 &= ~GPIO_bit(GPIO43_BTTXD);
- }
- #endif
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+// non
- #endif
-
- #if defined(CONFIG_ARCH_PXA_POODLE)
-@@ -1145,6 +1490,7 @@
- PRER = R_WAKEUP_SRC & apm_wakeup_src_mask;
- PFER = F_WAKEUP_SRC & apm_wakeup_src_mask;
- PEDR = WAKEUP_SRC & apm_wakeup_src_mask;
-+
- for (i = 0; i <=15; i++) {
- if ( PRER & PFER & GPIO_bit(i) ) {
- if ( GPLR0 & GPIO_bit(i) )
-@@ -1154,14 +1500,14 @@
- }
- }
-
--
- /* Clear reset status */
- RCSR = RCSR_HWR | RCSR_WDR | RCSR_SMR | RCSR_GPR;
-
- /* Stop 3.6MHz and drive HIGH to PCMCIA and CS */
- PCFR = PCFR_OPDE;
-
--#ifdef CONFIG_ARCH_PXA_CORGI
-+
-+#if defined(CONFIG_ARCH_PXA_CORGI)
- /* GPIO Sleep Register */
- PGSR2 = (PGSR2 & ~GPIO_ALL_STROBE_BIT) | GPIO_STROBE_BIT(0);
-
-@@ -1172,6 +1518,19 @@
- #endif
- GPDR1 = 0x00FFAFC3;
- GPDR2 = 0x0001C004;
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+ /* GPIO Sleep Register */
-+ PGSR1 = (PGSR1 & ~GPIO_LOW_STROBE_BIT);
-+ PGSR2 = (PGSR2 & ~GPIO_HIGH_STROBE_BIT);
-+#ifdef LOGICAL_WAKEUP_SRC
-+ if (logical_wakeup_src_mask &
-+ (IDPM_WAKEUP_ADDRESSBOOK|IDPM_WAKEUP_CALENDAR|IDPM_WAKEUP_MENU|IDPM_WAKEUP_MAIL)) {
-+ PGSR1 |= GPIO_STROBE_BIT(4);
-+ }
-+#endif
-+ GPDR0 = 0xC3810940;
-+ GPDR1 = 0xFCFFAB82;
-+ GPDR2 = 0x000F501f;
- #endif
- }
- #endif
-@@ -1228,14 +1587,20 @@
- }
- #endif
-
--#if defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- #define SCP_INIT_DATA(adr,dat) (((adr)<<16)|(dat))
- #define SCP_INIT_DATA_END ((unsigned long)-1)
- void sharpsl_corgi_fataloff(void)
- {
- #ifdef CONFIG_PM
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ tc6393_fatal_off();
-+ tc6393_suspend();
-+ tosa_ac97_exit();
-+#else
- w100_fatal_off();
- #endif
-+#endif
-
- {
- static const unsigned long scp_init[] =
-@@ -1253,12 +1618,37 @@
- SCP_INIT_DATA(SCP_GPWR,SCP_IO_OUT), // 24
- SCP_INIT_DATA_END
- };
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ static const unsigned long scp_jc_init[] =
-+ {
-+ SCP_INIT_DATA(SCP_MCR,0x0140), // 00
-+ SCP_INIT_DATA(SCP_MCR,0x0100),
-+ SCP_INIT_DATA(SCP_CDR,0x0000), // 04
-+ SCP_INIT_DATA(SCP_CPR,0x0000), // 0C
-+ SCP_INIT_DATA(SCP_CCR,0x0000), // 10
-+ SCP_INIT_DATA(SCP_IMR,0x0000), // 18
-+ SCP_INIT_DATA(SCP_IRM,0x00FF), // 14
-+ SCP_INIT_DATA(SCP_ISR,0x0000), // 1C
-+ SCP_INIT_DATA(SCP_IRM,0x0000),
-+ SCP_INIT_DATA(SCP_GPCR,SCP_JC_IO_DIR), // 20
-+ SCP_INIT_DATA(SCP_GPWR,SCP_JC_IO_OUT), // 24
-+ SCP_INIT_DATA_END
-+ };
-+#endif
- int i;
- for(i=0; scp_init[i] != SCP_INIT_DATA_END; i++)
- {
- int adr = scp_init[i] >> 16;
- SCP_REG(adr) = scp_init[i] & 0xFFFF;
- }
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ for(i=0; scp_jc_init[i] != SCP_INIT_DATA_END; i++)
-+ {
-+ int adr = scp_jc_init[i] >> 16;
-+ SCP_JC_REG(adr) = scp_jc_init[i] & 0xFFFF;
-+ }
-+#endif
-+
- }
-
- }
-@@ -1267,6 +1657,10 @@
-
- void sharpsl_fataloff(void)
- {
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ return;
-+#endif
-+
- if ( PSSR & 0x02 ) {
-
- printk("PSSR = %8x\n",PSSR);
-@@ -1278,19 +1672,18 @@
- PSPR = 0x00;
- RCSR = 0xf;
-
-- printk("off\n");
- pxa_fatal_suspend();
-- printk("off 2\n");
- #endif
--#if defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- sharpsl_corgi_fataloff();
-
- PSPR = 0x00;
- RCSR = 0xf;
-
-- printk("off\n");
- pxa_fatal_suspend();
-- printk("off 2\n");
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ sharpsl_restart();
-+#endif
- #endif
- }
- }
-@@ -1308,15 +1701,14 @@
- interruptible_sleep_on(&wq_off);
- DPRINTK("start off sequence ! \n");
-
--#if !defined(CONFIG_ARCH_PXA_SHEPHERD)
-+#if !defined(CONFIG_ARCH_PXA_SHEPHERD) && !defined(CONFIG_ARCH_PXA_TOSA)
- sharpsl_off_mode = 1;
- #endif
--
- handle_scancode(SLKEY_OFF|KBDOWN , 1);
- mdelay(10);
- handle_scancode(SLKEY_OFF|KBUP , 0);
-
--#if !defined(CONFIG_ARCH_PXA_SHEPHERD)
-+#if !defined(CONFIG_ARCH_PXA_SHEPHERD) && !defined(CONFIG_ARCH_PXA_TOSA)
- // wait off signal
- // if can not recieve off siganl , so force off.
- time_cnt = jiffies;
-@@ -1333,7 +1725,50 @@
- return 0;
- }
-
--#if defined(CONFIG_ARCH_PXA_SHEPHERD)
-+#if defined(CONFIG_SL7X0_POWER_KEY_OFF)
-+static int key_suspend_thread(void* unused)
-+{
-+ int time_cnt = 0;
-+
-+ // daemonize();
-+ strcpy(current->comm, "off_thread");
-+ sigfillset(&current->blocked);
-+
-+ while(1) {
-+ sleep_on(&key_off);
-+ printk("start off sequence ! \n");
-+
-+ handle_scancode(SLKEY_OFF|KBDOWN , 1);
-+ mdelay(10);
-+ handle_scancode(SLKEY_OFF|KBUP , 0);
-+
-+ // wait off signal
-+ // if can not recieve off siganl , so force off.
-+// time_cnt = jiffies;
-+// while(1) {
-+// if ( ( jiffies - time_cnt ) > 500 ) break;
-+// schedule();
-+// }
-+
-+ // maybe apps is dead, so we have to restart.
-+ pm_do_suspend();
-+ }
-+ return 0;
-+}
-+
-+void slc7x0_key_suspend(void)
-+{
-+ apm_wakeup_src_mask = 0;
-+ wake_up(&key_off);
-+}
-+
-+EXPORT_SYMBOL(slc7x0_key_suspend);
-+
-+#endif
-+
-+
-+
-+#if defined(CONFIG_ARCH_PXA_SHEPHERD) || defined(CONFIG_ARCH_PXA_TOSA)
- static struct timer_list bat_switch_timer;
-
- void sharpsl_emerge_restart(void)
-@@ -1347,10 +1782,16 @@
- void sharpsl_emerge_off(int irq, void *dev_id, struct pt_regs *regs)
- {
-
-+ DPRINTK("DBG:sharpsl_emerge_off [non-battery]\n");
-+
- /* noise ? */
- mdelay(10);
-- if ( 0x1234ABCD != regs &&
-- GPLR(GPIO_MAIN_BAT_LOW) & GPIO_bit(GPIO_MAIN_BAT_LOW) ) {
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ if ( 0x1234ABCD != regs && GPLR(GPIO_BAT_LOCKED) & GPIO_bit(GPIO_BAT_LOCKED) )
-+#else
-+ if ( 0x1234ABCD != regs && GPLR(GPIO_MAIN_BAT_LOW) & GPIO_bit(GPIO_MAIN_BAT_LOW) )
-+#endif
-+ {
- #if defined(CONFIG_ARCH_PXA_SHEPHERD)
- sharpsl_battery_charge_hook(1); /* charge off */
- if (sharppda_kbd_resetcheck()) {
-@@ -1364,11 +1805,10 @@
- return;
- }
-
--#if defined(CONFIG_ARCH_PXA_CORGI) && !defined(CONFIG_ARCH_PXA_SHEPHERD)
-+#if (defined(CONFIG_ARCH_PXA_CORGI)) && !defined(CONFIG_ARCH_PXA_SHEPHERD) && !defined(CONFIG_ARCH_PXA_TOSA)
- if (!(GPLR(GPIO_MAIN_BAT_LOW) & GPIO_bit(GPIO_MAIN_BAT_LOW)))
- apm_wakeup_src_mask = 0;
- #endif
--
- wake_up(&wq_off);
-
- }
-@@ -1386,6 +1826,8 @@
- /* Set transition detect */
- #ifdef CONFIG_ARCH_PXA_SHEPHERD
- set_GPIO_IRQ_edge( GPIO_MAIN_BAT_LOW , GPIO_BOTH_EDGES );
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+ set_GPIO_IRQ_edge( GPIO_BAT_LOCKED , GPIO_BOTH_EDGES );
- #else
- set_GPIO_IRQ_edge( GPIO_MAIN_BAT_LOW , GPIO_FALLING_EDGE );
- #endif
-@@ -1394,17 +1836,29 @@
- /* this registration can be done in init/main.c. */
- if(1){
- int err;
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ err = request_irq(IRQ_GPIO_BAT_LOCKED,sharpsl_emerge_off , SA_INTERRUPT, "batok", NULL);
-+#else
- err = request_irq(IRQ_GPIO_MAIN_BAT_LOW,sharpsl_emerge_off , SA_INTERRUPT, "batok", NULL);
-+#endif
- if( err ){
- printk("batok install error %d\n",err);
- }else{
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ enable_irq(IRQ_GPIO_BAT_LOCKED);
-+#else
- enable_irq(IRQ_GPIO_MAIN_BAT_LOW);
-+#endif
- printk("batok installed\n");
- }
- }
-
- kernel_thread(sharpsl_off_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
--#if defined(CONFIG_ARCH_PXA_SHEPHERD)
-+#if defined(CONFIG_SL7X0_POWER_KEY_OFF)
-+ kernel_thread(key_suspend_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
-+#endif
-+#if defined(CONFIG_ARCH_PXA_SHEPHERD) || defined(CONFIG_ARCH_PXA_TOSA)
-+//#if defined(CONFIG_ARCH_PXA_SHEPHERD)
- init_timer(&bat_switch_timer);
- bat_switch_timer.function = sharpsl_emerge_restart;
- #endif
-@@ -1464,12 +1918,55 @@
-
- void set_apm_wakeup_src_mask(u32 SetValue)
- {
-+#ifdef LOGICAL_WAKEUP_SRC
-+ logical_wakeup_src_mask = 0;
-+ // RTC
-+ if (SetValue&IDPM_WAKEUP_RTC) {
-+ apm_wakeup_src_mask |= GPIO_bit(31);
-+ logical_wakeup_src_mask |= IDPM_WAKEUP_RTC;
-+ } else apm_wakeup_src_mask &= ~GPIO_bit(31);
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ // Sync key
-+ if (SetValue&IDPM_WAKEUP_SYNC) {
-+ apm_wakeup_src_mask |= GPIO_bit(GPIO_SYNC);
-+ logical_wakeup_src_mask |= IDPM_WAKEUP_SYNC;
-+ } else apm_wakeup_src_mask &= ~GPIO_bit(GPIO_SYNC);
-+ // Record key
-+ if (SetValue&IDPM_WAKEUP_REC) {
-+ apm_wakeup_src_mask |= GPIO_bit(GPIO_RECORD_BTN);
-+ logical_wakeup_src_mask |= IDPM_WAKEUP_REC;
-+ } else apm_wakeup_src_mask &= ~GPIO_bit(GPIO_RECORD_BTN);
-+ // USBD
-+ if (SetValue&IDPM_WAKEUP_USBD) {
-+ apm_wakeup_src_mask |= GPIO_bit(GPIO_USB_IN);
-+ logical_wakeup_src_mask |= IDPM_WAKEUP_USBD;
-+ } else apm_wakeup_src_mask &= ~GPIO_bit(GPIO_USB_IN);
-+ // only Logical
-+ if (SetValue&IDPM_WAKEUP_AC) logical_wakeup_src_mask |= IDPM_WAKEUP_AC;
-+ if (SetValue&IDPM_WAKEUP_JACKET) logical_wakeup_src_mask |= IDPM_WAKEUP_JACKET;
-+ if (SetValue&IDPM_WAKEUP_CALENDAR) logical_wakeup_src_mask |= IDPM_WAKEUP_CALENDAR;
-+ if (SetValue&IDPM_WAKEUP_ADDRESSBOOK) logical_wakeup_src_mask |= IDPM_WAKEUP_ADDRESSBOOK;
-+ if (SetValue&IDPM_WAKEUP_MAIL) logical_wakeup_src_mask |= IDPM_WAKEUP_MAIL;
-+ if (SetValue&IDPM_WAKEUP_MENU) logical_wakeup_src_mask |= IDPM_WAKEUP_MENU;
-+#ifdef WUPSRC_DEBUG
-+ printk("set_wakeup_src=%08x->%08x[%08x]\n",SetValue,logical_wakeup_src_mask,apm_wakeup_src_mask);
-+#endif
-+#endif
-+#else
- apm_wakeup_src_mask = SetValue;
-+#endif
- }
-
- u32 get_apm_wakeup_src_mask(void)
- {
-+#ifdef LOGICAL_WAKEUP_SRC
-+#ifdef WUPSRC_DEBUG
-+ printk("get_wakeup_src=%08x\n",logical_wakeup_src_mask);
-+#endif
-+ return (u32)logical_wakeup_src_mask;
-+#else
- return (u32)apm_wakeup_src_mask;
-+#endif
- }
-
- u32 get_apm_wakeup_factor(void)
-diff -Nur linux_c860_org/arch/arm/mach-pxa/sharpsl_suspend.S linux/arch/arm/mach-pxa/sharpsl_suspend.S
---- linux_c860_org/arch/arm/mach-pxa/sharpsl_suspend.S 2003-06-18 16:12:25.000000000 +0900
-+++ linux/arch/arm/mach-pxa/sharpsl_suspend.S 2004-06-10 21:09:10.000000000 +0900
-@@ -34,6 +34,7 @@
- * 12-Dec-2002 Lineo Japan, Inc.
- * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
- * 14-Mar-2003 Sharp for PXA255
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- #include <linux/linkage.h>
-@@ -59,10 +60,17 @@
-
- .global sleep_param
- .global sleep_param_p
-+#if defined(CONFIG_SL_CCCR_CHANGE)
-+ .global cccr_clkparam
-+#endif
-
- sleep_param: .word 0 @ virtual address of parameter array
- sleep_param_p: .word 0 @ physical address of parameter array
-
-+#if defined(CONFIG_SL_CCCR_CHANGE)
-+cccr_clkparam: .word 0
-+#endif
-+
- IC_BASE: .word io_p2v(0x40D00000)
-
-
-@@ -228,7 +236,7 @@
- str r1, [r0] @ turn off all GPIOs
- #endif
-
-- ldr r3, sleep_param
-+ ldr r3, sleep_param
- ldr r2, =Awake_address @ store Virtual return address
- str r2, [r3], #4
-
-@@ -1053,7 +1061,7 @@
- .align 5
- .text
-
--#if defined(CONFIG_ARCH_PXA_SHEPHERD)
-+#if defined(CONFIG_ARCH_PXA_SHEPHERD) || defined(CONFIG_ARCH_PXA_TOSA)
-
- ENTRY(cpu_xscale_sl_change_speed_161)
- stmfd sp!, {r0, r1, r2, r3, r4, lr}
-@@ -1081,3 +1089,30 @@
- .text
-
- #endif
-+
-+#if defined(CONFIG_SL_CCCR_CHANGE)
-+ENTRY(cpu_xscale_sl_change_speed_num)
-+ stmfd sp!, {r0, r1, r2, r3, r4, lr}
-+
-+ ldr r0, CMR_BASE
-+ ldr r1, cccr_clkparam
-+ str r1, [r0, #CMR_CCCR]
-+
-+ ldr r0, MD_BASE
-+ ldr r2, [r0, #MD_MDREFR]
-+
-+ bl CodeOnCache_num
-+
-+ .align 5
-+ .text
-+CodeOnCache_num:
-+ mov r1, #0x2
-+ mcr p14, 0, r1, c6, c0, 0
-+ str r2, [r0, #MD_MDREFR]
-+ ldr r2, [r0, #MD_MDREFR]
-+
-+ ldmfd sp!, {r0, r1, r2, r3, r4, pc}
-+
-+ .align 5
-+ .text
-+#endif
-diff -Nur linux_c860_org/arch/arm/mach-pxa/tosa.c linux/arch/arm/mach-pxa/tosa.c
---- linux_c860_org/arch/arm/mach-pxa/tosa.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/arch/arm/mach-pxa/tosa.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,483 @@
-+/*
-+ * arch/arm/mach-pxa/tosa.c
-+ *
-+ * Support for the SHARP Tosa Board.
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * Based on:
-+ * linux/arch/arm/mach-pxa/lubbock.c
-+ *
-+ * Support for the Intel DBPXA250 Development Platform.
-+ *
-+ * Author: Nicolas Pitre
-+ * Created: Jun 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Change Log
-+ * 26-Dec-2003 Sharp Corporation for Tosa
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/major.h>
-+#include <linux/fs.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+#include <linux/delay.h>
-+
-+#include <asm/types.h>
-+#include <asm/setup.h>
-+#include <asm/memory.h>
-+#include <asm/mach-types.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+
-+#include <asm/mach/arch.h>
-+#include <asm/mach/map.h>
-+#include <asm/mach/irq.h>
-+
-+#include <asm/arch/irq.h>
-+
-+#include "generic.h"
-+#include <linux/ac97_codec.h>
-+#include <linux/pm.h>
-+#ifdef CONFIG_PM
-+static struct pm_dev *ga_pm_dev;
-+extern int pxa_suspend(void);
-+#endif
-+
-+extern void sharpsl_get_param(void);
-+extern void sharpsl_charge_start(void);
-+//extern unsigned short chkFatalBatt(void);
-+extern void pxa_nssp_init(void);
-+extern void tosa_ac97_init(void);
-+extern void i2c_init(int reset);
-+
-+unsigned short reset_scoop_gpio(unsigned short);
-+
-+static void tc6393_IRQ_demux( int irq, void *dev_id, struct pt_regs *regs )
-+{
-+ int req, i;
-+
-+ while ( (req = (TC6393_SYS_REG(TC6393_SYS_ISR)
-+ & ~(TC6393_SYS_REG(TC6393_SYS_IMR)))) ) {
-+ for (i = 0; i <= 7; i++) {
-+ if ((req & (0x0001<<i))) {
-+ switch (TC6393_IRQ(i)) {
-+ case TC6393_IRQ_USBINT:
-+#if 0
-+ if (!(TC6393_USB_REG(TC6393_USB_SVPMCS) & TC6393_USB_PM_PMES))
-+ continue;
-+#endif
-+ break;
-+ }
-+ do_IRQ( TC6393_IRQ(i) , regs );
-+ }
-+ }
-+ break;
-+ }
-+}
-+
-+static struct irqaction tc6393_irq = {
-+ name: "TC6393",
-+ handler: tc6393_IRQ_demux,
-+ flags: SA_INTERRUPT
-+};
-+
-+static void tc6393_mask_and_ack_irq(unsigned int irq)
-+{
-+ TC6393_SYS_REG(TC6393_SYS_IMR) |= (0x0001 << (irq - TC6393_IRQ(0)));
-+ switch (irq) {
-+ case TC6393_IRQ_USBINT:
-+ TC6393_USB_REG(TC6393_USB_SVPMCS) |= TC6393_USB_PM_PMES;
-+ break;
-+ }
-+}
-+
-+static void tc6393_mask_irq(unsigned int irq)
-+{
-+ TC6393_SYS_REG(TC6393_SYS_IMR) |= (0x0001 << (irq - TC6393_IRQ(0)));
-+}
-+
-+static void tc6393_unmask_irq(unsigned int irq)
-+{
-+ TC6393_SYS_REG(TC6393_SYS_IMR) &= ~(0x0001 << (irq - TC6393_IRQ(0)));
-+}
-+
-+static void __init scoop_init(void)
-+{
-+
-+#define SCP_INIT_DATA(adr,dat) (((adr)<<16)|(dat))
-+#define SCP_INIT_DATA_END ((unsigned long)-1)
-+ static const unsigned long scp_init[] =
-+ {
-+ SCP_INIT_DATA(SCP_MCR,0x0140), // 00
-+ SCP_INIT_DATA(SCP_MCR,0x0100),
-+ SCP_INIT_DATA(SCP_CDR,0x0000), // 04
-+ SCP_INIT_DATA(SCP_CPR,0x0000), // 0C
-+ SCP_INIT_DATA(SCP_CCR,0x0000), // 10
-+ SCP_INIT_DATA(SCP_IMR,0x0000), // 18
-+ SCP_INIT_DATA(SCP_IRM,0x00FF), // 14
-+ SCP_INIT_DATA(SCP_ISR,0x0000), // 1C
-+ SCP_INIT_DATA(SCP_IRM,0x0000),
-+ SCP_INIT_DATA(SCP_GPCR,SCP_IO_DIR), // 20
-+ SCP_INIT_DATA(SCP_GPWR,SCP_IO_OUT), // 24
-+ SCP_INIT_DATA_END
-+ };
-+ int i;
-+ for(i=0; scp_init[i] != SCP_INIT_DATA_END; i++)
-+ {
-+ int adr = scp_init[i] >> 16;
-+ SCP_REG(adr) = scp_init[i] & 0xFFFF;
-+ }
-+}
-+
-+static spinlock_t scoop_lock = SPIN_LOCK_UNLOCKED;
-+
-+unsigned short set_scoop_gpio(unsigned short bit)
-+{
-+ unsigned short gpio_bit;
-+ unsigned long flag;
-+
-+ spin_lock_irqsave(&scoop_lock, flag);
-+ gpio_bit = SCP_REG_GPWR | bit;
-+ SCP_REG_GPWR = gpio_bit;
-+ spin_unlock_irqrestore(&scoop_lock, flag);
-+
-+ return gpio_bit;
-+}
-+EXPORT_SYMBOL(set_scoop_gpio);
-+
-+unsigned short reset_scoop_gpio(unsigned short bit)
-+{
-+ unsigned short gpio_bit;
-+ unsigned long flag;
-+
-+ spin_lock_irqsave(&scoop_lock, flag);
-+ gpio_bit = SCP_REG_GPWR & ~bit;
-+ SCP_REG_GPWR = gpio_bit;
-+ spin_unlock_irqrestore(&scoop_lock, flag);
-+
-+ return gpio_bit;
-+}
-+EXPORT_SYMBOL(reset_scoop_gpio);
-+
-+
-+static void __init scoop_jc_init(void)
-+{
-+ static const unsigned long scp_jc_init[] =
-+ {
-+ SCP_INIT_DATA(SCP_MCR,0x0140), // 00
-+ SCP_INIT_DATA(SCP_MCR,0x0100),
-+ SCP_INIT_DATA(SCP_CDR,0x0000), // 04
-+ SCP_INIT_DATA(SCP_CPR,0x0000), // 0C
-+ SCP_INIT_DATA(SCP_CCR,0x0000), // 10
-+ SCP_INIT_DATA(SCP_IMR,0x0000), // 18
-+ SCP_INIT_DATA(SCP_IRM,0x00FF), // 14
-+ SCP_INIT_DATA(SCP_ISR,0x0000), // 1C
-+ SCP_INIT_DATA(SCP_IRM,0x0000),
-+ SCP_INIT_DATA(SCP_GPCR,SCP_JC_IO_DIR), // 20
-+ SCP_INIT_DATA(SCP_GPWR,SCP_JC_IO_OUT), // 24
-+ SCP_INIT_DATA_END
-+ };
-+ int i;
-+ for(i=0; scp_jc_init[i] != SCP_INIT_DATA_END; i++) {
-+ int adr = scp_jc_init[i] >> 16;
-+ SCP_JC_REG(adr) = scp_jc_init[i] & 0xFFFF;
-+ }
-+
-+ reset_scoop_gpio(SCP_IR_POWERDWN);
-+}
-+
-+static spinlock_t scoop_jc_lock = SPIN_LOCK_UNLOCKED;
-+
-+unsigned short set_scoop_jc_gpio(unsigned short bit)
-+{
-+ unsigned short gpio_bit;
-+ unsigned long flag;
-+
-+ spin_lock_irqsave(&scoop_jc_lock, flag);
-+ gpio_bit = SCP_JC_REG_GPWR | bit;
-+ SCP_JC_REG_GPWR = gpio_bit;
-+ spin_unlock_irqrestore(&scoop_jc_lock, flag);
-+
-+ return gpio_bit;
-+}
-+EXPORT_SYMBOL(set_scoop_jc_gpio);
-+
-+unsigned short reset_scoop_jc_gpio(unsigned short bit)
-+{
-+ unsigned short gpio_bit;
-+ unsigned long flag;
-+
-+ spin_lock_irqsave(&scoop_jc_lock, flag);
-+ gpio_bit = SCP_JC_REG_GPWR & ~bit;
-+ SCP_JC_REG_GPWR = gpio_bit;
-+ spin_unlock_irqrestore(&scoop_jc_lock, flag);
-+
-+ return gpio_bit;
-+}
-+EXPORT_SYMBOL(reset_scoop_jc_gpio);
-+
-+static void tc6393_init(void)
-+{
-+ reset_scoop_jc_gpio(SCP_JC_TC3693_L3V_ON);
-+ reset_scoop_jc_gpio(SCP_JC_TC6393_SUSPEND);
-+ reset_scoop_gpio(SCP_TC6393_REST_IN);
-+ set_GPIO_mode(GPIO11_3_6MHz_MD);
-+ set_GPIO_mode(GPIO18_RDY_MD);
-+ mdelay(1);
-+ set_scoop_jc_gpio(SCP_JC_TC6393_SUSPEND);
-+ mdelay(10);
-+ set_scoop_gpio(SCP_TC6393_REST_IN);
-+ set_scoop_jc_gpio(SCP_JC_TC3693_L3V_ON);
-+
-+ printk("init TC6369 Revision %d\n", TC6393_SYS_REG(TC6393_SYS_RIDR));
-+ TC6393_SYS_REG(TC6393_SYS_FER) = 0;
-+
-+ /* clock setting */
-+ TC6393_SYS_REG(TC6393_SYS_PLL2CR) = 0x0cc1;
-+ //TC6393_SYS_REG(TC6393_SYS_ConfigCR) = 0x1;
-+ //TC6393_SYS_REG(TC6393_SYS_PLL1CR1) = 0xdf00;
-+ //TC6393_SYS_REG(TC6393_SYS_PLL1CR2) = 0x002c;
-+ //TC6393_SYS_REG(TC6393_SYS_ConfigCR) = 0x0;
-+ TC6393_SYS_REG(TC6393_SYS_CCR) = 0x1310;
-+
-+ TC6393_SYS_REG(TC6393_SYS_MCR) = 0x80AA;
-+
-+ /* GPIO */
-+ TC6393_SYS_REG(TC6393_SYS_GPER) = 0x3300; /* 15-0 GPO */
-+// TC6393_SYS_REG(TC6393_SYS_GPOOECR1) = TC6393_GPO_OE;
-+// TC6393_SYS_REG(TC6393_SYS_GPODSR1) = TC6393_CARD_VCC_ON;/* 15-0 GPO set */
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) = TC6393_CARD_VCC_ON | TC6393_CHARGE_OFF_JC;/* 15-0 GPO set */
-+ TC6393_SYS_REG(TC6393_SYS_GPOOECR1) = TC6393_GPO_OE;
-+
-+}
-+
-+void tc6393_resume(void)
-+{
-+ tc6393_init();
-+}
-+EXPORT_SYMBOL(tc6393_resume);
-+
-+void tc6393_suspend(void)
-+{
-+ reset_scoop_jc_gpio(SCP_JC_TC3693_L3V_ON);
-+ reset_scoop_gpio(SCP_TC6393_REST_IN);
-+ reset_scoop_jc_gpio(SCP_JC_TC6393_SUSPEND);
-+ set_GPIO_mode(GPIO11_3_6MHz|GPIO_OUT);
-+ GPSR0 = GPIO_bit(GPIO11_3_6MHz);
-+}
-+EXPORT_SYMBOL(tc6393_suspend);
-+
-+#ifdef CONFIG_PM
-+static int ga_pm_callback(struct pm_dev* pm_dev, pm_request_t req, void *data)
-+{
-+ switch (req) {
-+ case PM_SUSPEND:
-+ break;
-+ case PM_RESUME:
-+ break;
-+ }
-+ return 0;
-+}
-+#endif
-+
-+void resume_init(void)
-+{
-+// MSC0 = 0x02da02da; //msc0
-+// MSC1 = 0x7FFC7FFC; //msc1
-+// MSC2 = 0x7FF47FFC; //msc2
-+
-+// GPDR0=0xDB828000;
-+// GPDR1=0xFFB6A887;
-+// GPDR2=0x0001FFFF;
-+
-+// PGSR0 = 0x01008000; //Sleep State
-+// PGSR1 = 0x00160802; //Sleep State
-+// PGSR2 = 0x0001C000; //Sleep State
-+
-+#if 0
-+ GRER0 = (GRER0 | 1); //raising
-+ GFER0 = (GFER0 | 1); //failing
-+
-+ ICLR = 0;
-+
-+ ICMR |= (1 << 10); //bit10, gpio02_80 enable
-+ ICMR |= (1 << 8); //bit8, gpio00 enable
-+
-+ ICCR = 1; //Only enabled and unmasked will bring the Cotulla out of IDLE mode.
-+#endif
-+
-+ CKEN |= 0x03;
-+ CKEN |= CKEN3_SSP;
-+ CKEN |= CKEN1_PWM1;
-+}
-+
-+static int __init tosa_hw_init(void)
-+{
-+
-+ /* scoop initialize */
-+ scoop_init();
-+ scoop_jc_init();
-+
-+ /* initialize I2C */
-+ i2c_init(1);
-+
-+ /* TC6393 initialize */
-+ tc6393_init();
-+
-+ /* initialize SSP & CS */
-+ pxa_nssp_init();
-+
-+ /* initialize AC97 */
-+ tosa_ac97_init();
-+
-+ return 0;
-+}
-+
-+static void __init tosa_init_irq(void)
-+{
-+ int irq;
-+
-+ pxa_init_irq();
-+
-+ /* setup extra tosa irqs */
-+ TC6393_SYS_REG(TC6393_SYS_IRR) = 0;
-+ TC6393_SYS_REG(TC6393_SYS_IMR) = 0xbf;
-+ for (irq = TC6393_IRQ(0); irq <= TC6393_IRQ(7); irq++) {
-+ irq_desc[irq].valid = 1;
-+ irq_desc[irq].probe_ok = 1;
-+ irq_desc[irq].mask_ack = tc6393_mask_and_ack_irq;
-+ irq_desc[irq].mask = tc6393_mask_irq;
-+ irq_desc[irq].unmask = tc6393_unmask_irq;
-+ }
-+ GPDR(GPIO_TC6393_INT) &= ~GPIO_bit(GPIO_TC6393_INT);
-+ set_GPIO_IRQ_edge( GPIO_TC6393_INT, GPIO_FALLING_EDGE );
-+ setup_arm_irq( IRQ_GPIO_TC6393_INT, &tc6393_irq );
-+
-+ tosa_hw_init();
-+}
-+
-+static int __init tosa_init(void)
-+{
-+#ifdef CONFIG_PM
-+ extern u32 sharpsl_emergency_off;
-+#endif
-+
-+ // enable batt_fault
-+ PMCR = 0x01;
-+
-+ /* charge check */
-+ if ((GPLR(GPIO_AC_IN) & GPIO_bit(GPIO_AC_IN)) == 0) {
-+ sharpsl_charge_start();
-+ }
-+
-+ //sharpsl_kick_jacket_check_queue();
-+
-+ printk("RCSR = %d\n",RCSR);
-+
-+#ifdef CONFIG_PM
-+ /* fatal check */
-+#ifndef CONFIG_ARCH_PXA_TOSA_SKIP
-+ if ( !(GPLR(GPIO_MAIN_BAT_LOW) & GPIO_bit(GPIO_MAIN_BAT_LOW)) ) {
-+ printk("corgi.c : main batt low\n");
-+ sharpsl_emergency_off = 1;
-+ pxa_suspend();
-+ }
-+#endif /* CONFIG_ARCH_PXA_TOSA_SKIP */
-+
-+ if ( RCSR == 0x01 || RCSR == 0x6) {
-+ printk("full reset !\n");
-+ sharpsl_emergency_off = 1;
-+ }
-+
-+ ga_pm_dev = pm_register(PM_SYS_DEV, 0, ga_pm_callback);
-+#endif
-+
-+ return 0;
-+}
-+
-+__initcall(tosa_init);
-+
-+static void __init fixup_tosa(struct machine_desc *desc,
-+ struct param_struct *params,
-+ char **cmdline, struct meminfo *mi)
-+{
-+ SET_BANK (0, 0xa0000000, 64*1024*1024);
-+ mi->nr_banks = 1;
-+#if defined(CONFIG_BLK_DEV_INITRD)
-+ setup_ramdisk (1, 0, 0, 8192);
-+ setup_initrd (__phys_to_virt(0xa1000000), 4*1024*1024);
-+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
-+#elif defined(CONFIG_MTD)
-+ ROOT_DEV = MKDEV(31, 0); /* /dev/mtdblock0 */
-+#endif
-+
-+#ifdef CONFIG_SHARPSL_BOOTLDR_PARAMS
-+ if (params->u1.s.page_size != PAGE_SIZE) {
-+ params->u1.s.page_size = PAGE_SIZE;
-+ params->u1.s.nr_pages = 32 * 1024 * 1024 / PAGE_SIZE;
-+ params->u1.s.ramdisk_size = 0;
-+ params->u1.s.flags = FLAG_READONLY | FLAG_RDLOAD | FLAG_RDPROMPT;
-+ params->u1.s.rootdev = ROOT_DEV;
-+ params->u1.s.initrd_start = 0;
-+ params->u1.s.initrd_size = 0;
-+ params->u1.s.rd_start = 0;
-+ params->u1.s.system_rev = 0;
-+ params->u1.s.system_serial_low = 0;
-+ params->u1.s.system_serial_high = 0;
-+ strcpy(params->commandline, CONFIG_CMDLINE);
-+ }
-+#endif
-+
-+ sharpsl_get_param();
-+}
-+
-+static struct map_desc tosa_io_desc[] __initdata = {
-+ /* virtual physical length domain r w c b */
-+ /* TC6393 (LCDC, USBC, NANDC) */
-+ { 0xf1000000, TOSA_LCDC_PHYS, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 },
-+ /* SCOOP2 for internel CF */
-+ { 0xf2000000, TOSA_CF_PHYS, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
-+ /* SCOOP2 for Jacket CF */
-+ { 0xf2200000, TOSA_SCOOP_PHYS, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
-+ /* Nor Flash */
-+ { 0xef000000, 0x00000000, 0x00800000, DOMAIN_IO, 1, 1, 1, 0 },
-+ LAST_DESC
-+};
-+
-+static void __init tosa_map_io(void)
-+{
-+ pxa_map_io();
-+ iotable_init(tosa_io_desc);
-+
-+ set_GPIO_mode(GPIO_ON_RESET | GPIO_IN);
-+
-+ /* setup sleep mode values */
-+ PWER = 0x00000002;
-+ PFER = 0x00000000;
-+ PRER = 0x00000002;
-+ PGSR0 = 0x00000000;
-+ PGSR1 = 0x00FF0002;
-+ PGSR2 = 0x00014000;
-+ PCFR |= PCFR_OPDE;
-+}
-+
-+MACHINE_START(TOSA, "SHARP Tosa")
-+ MAINTAINER("Lineo uSolutions, Inc.")
-+ BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000))
-+#ifdef CONFIG_SHARPSL_BOOTLDR_PARAMS
-+ BOOT_PARAMS(0xa0000100)
-+#endif
-+ FIXUP(fixup_tosa)
-+ MAPIO(tosa_map_io)
-+ INITIRQ(tosa_init_irq)
-+MACHINE_END
-+
-diff -Nur linux_c860_org/arch/arm/mach-pxa/tosa_ac97.c linux/arch/arm/mach-pxa/tosa_ac97.c
---- linux_c860_org/arch/arm/mach-pxa/tosa_ac97.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/arch/arm/mach-pxa/tosa_ac97.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,587 @@
-+/*
-+ * linux/asm/arch/mach-pxa/tosa_ac97.c
-+ *
-+ * AC97 interface for the Tosa chip
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * Based on:
-+ * linux/drivers/sound/pxa-ac97.c -- AC97 interface for the Cotula chip
-+ * Author: Nicolas Pitre
-+ * Created: Aug 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * linux/drivers/sound/ac97_codec.c -- Generic AC97 mixer/modem module
-+ * Derived from ac97 mixer in maestro and trident driver.
-+ * Copyright 2000 Silicon Integrated System Corporation
-+ *
-+ * ChangeLong:
-+ * 1-Nov-2003 Sharp Corporation for Tosa
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/bitops.h>
-+#include <linux/slab.h>
-+#include <linux/pci.h>
-+#include <linux/completion.h>
-+#include <linux/delay.h>
-+#include <linux/poll.h>
-+#include <linux/sound.h>
-+#include <linux/soundcard.h>
-+#include <linux/ac97_codec.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+#include <asm/semaphore.h>
-+#include <asm/dma.h>
-+
-+#include <asm/arch/tosa_wm9712.h>
-+
-+#ifdef CONFIG_PM
-+#include <asm/sharp_apm.h>
-+#endif
-+
-+#define CODEC_ID_BUFSZ 14
-+
-+typedef struct {
-+ unsigned short ctl_val, pdown_val;
-+} power_mode_t;
-+
-+static power_mode_t pwr_values[] = {
-+ { 0x6F00, 0x7FFF }, // Off
-+ { 0x4600, 0x73FF }, // Rec with no HP
-+ { 0x4100, 0x1F77 }, // Play with no HP
-+ { 0x4600, 0x73FF }, // Rec with Stereo HP
-+ { 0x0100, 0x1CEF }, // Play with Stereo HP
-+ { 0x4600, 0x73FF }, // Rec with Mic HP
-+ { 0x0100, 0x1EEF }, // Play with Mic HP
-+ { 0x4700, 0x7FFF }, // Tablet (waiting for pen-down)
-+ { 0x4700, 0x7FFF }, // Tablet (continuous conversion)
-+ { 0x4700, 0x7BFF }, // Enable MICBIAS for detecting Mic HP
-+ { 0x0000, 0x0000 }, // Full power
-+};
-+static const int num_of_pwr_values = sizeof(pwr_values)/sizeof(pwr_values[0]);
-+
-+static power_mode_t power_mode_status[NUM_OF_WM9712_DEV];
-+static power_mode_t cur_power_status;
-+
-+struct ac97_codec *codec;
-+
-+static struct completion CAR_completion;
-+static DECLARE_MUTEX(CAR_mutex);
-+
-+/************************************************************
-+ * Debug
-+ ************************************************************/
-+#define DBG_LEVEL 0
-+#define DBG_L1 1
-+#define DBG_L2 2
-+#define DBG_L3 3
-+#define DEBUG(level, x, args...) \
-+ if ( level <= DBG_LEVEL ) printk("%s: " x,__FUNCTION__ ,##args)
-+
-+/************************************************************
-+ * AC97 Sequense
-+ ************************************************************/
-+typedef struct {
-+ u16 val;
-+ u8 seq;
-+} ac97_seq_t;
-+static volatile u32 *ac97_addr = NULL;
-+static ac97_seq_t ac97_seq;
-+
-+#define AC97_SEQ_READ1 0x01
-+#define AC97_SEQ_READ2 0x02
-+#define AC97_SEQ_READ_DONE 0x03
-+#define AC97_SEQ_WRITE_DONE 0x04
-+
-+/************************************************************
-+ * AC97 IDs
-+ ************************************************************/
-+typedef struct {
-+ u32 id;
-+ char *name;
-+ struct ac97_ops *ops;
-+ int flags;
-+} ac97_ids_t;
-+
-+static struct ac97_ops null_ops = { NULL, NULL, NULL };
-+
-+static ac97_ids_t ac97_ids[] = {
-+ { 0x574D4C12, "Wolfson WM9711/WM9712", &null_ops },
-+};
-+
-+/************************************************************
-+ * Timer interrupt for AC97 lost interrupt
-+ ************************************************************/
-+static unsigned char ac97_timer_on = 0;
-+static struct timer_list ac97_timer;
-+static void ac97_timer_set(unsigned long);
-+static void ac97_timer_clear(void);
-+
-+static void ac97_timer_func(unsigned long data)
-+{
-+ ac97_timer_on = 0;
-+ if ( (ac97_seq.seq == AC97_SEQ_READ_DONE) ||
-+ (ac97_seq.seq == AC97_SEQ_WRITE_DONE) ) {
-+ DEBUG(DBG_L2, "CAR_completion\n");
-+ complete(&CAR_completion);
-+ ac97_timer_set(data);
-+ } else {
-+ printk(KERN_WARNING "AC97: lost interrupt(%08lx)\n", data);
-+ ac97_timer_set(data);
-+ }
-+}
-+
-+static void ac97_timer_clear(void)
-+{
-+ if ( ac97_timer_on )
-+ del_timer(&ac97_timer);
-+ ac97_timer_on = 0;
-+}
-+
-+static void ac97_timer_set(unsigned long val)
-+{
-+ ac97_timer_clear();
-+ init_timer(&ac97_timer);
-+ ac97_timer.data = val;
-+ ac97_timer.function = ac97_timer_func;
-+ ac97_timer.expires = jiffies + HZ;
-+ add_timer(&ac97_timer);
-+ ac97_timer_on = 1;
-+}
-+
-+/************************************************************
-+ * AC97 functions
-+ ************************************************************/
-+#define AC97_TIMEOUT_VAL 0x10000
-+static u16 pxa_ac97_read(struct ac97_codec *codec, u8 reg)
-+{
-+ down(&CAR_mutex);
-+ lock_FCS(LOCK_FCS_AC97_SUB, 1);
-+ if ( !(CAR & CAR_CAIP) ) {
-+ ac97_addr = (volatile u32 *)&PAC_REG_BASE + (reg >> 1);
-+#ifdef USE_AC97_INTERRUPT
-+ ac97_seq.val = -1;
-+ ac97_seq.seq = AC97_SEQ_READ1;
-+
-+ init_completion(&CAR_completion);
-+
-+ ac97_timer_set(ac97_seq.seq);
-+
-+ (void)*ac97_addr;
-+ wait_for_completion(&CAR_completion);
-+
-+ ac97_timer_clear();
-+#else
-+ {
-+ u16 data=0;
-+ int timeout;
-+ // dummy
-+ GSR |= GSR_RDCS;
-+ GSR |= GSR_SDONE;
-+ data = *ac97_addr;
-+ timeout = 0;
-+ while((GSR & GSR_SDONE)==0 && timeout++<AC97_TIMEOUT_VAL);
-+ if ((GSR & GSR_RDCS)!=0 || timeout>=AC97_TIMEOUT_VAL) {
-+ GSR |= GSR_RDCS;
-+ printk(KERN_CRIT __FUNCTION__": AC97 is busy.\n");
-+ lock_FCS(LOCK_FCS_AC97_SUB, 0);
-+ up(&CAR_mutex);
-+ return data;
-+ }
-+
-+ // actual read
-+ GSR |= GSR_SDONE;
-+ data = *ac97_addr;
-+ timeout = 0;
-+ while((GSR & GSR_SDONE)==0 && timeout++<AC97_TIMEOUT_VAL);
-+ if ((GSR & GSR_RDCS)!=0 || timeout>=AC97_TIMEOUT_VAL) {
-+ GSR |= GSR_RDCS;
-+ printk(KERN_CRIT __FUNCTION__": AC97 is busy.\n");
-+ }
-+ lock_FCS(LOCK_FCS_AC97_SUB, 0);
-+ up(&CAR_mutex);
-+ return data;
-+ }
-+#endif // end USE_AC97_INTERRUPT
-+ } else {
-+ printk(KERN_CRIT __FUNCTION__": CAR_CAIP already set\n");
-+ }
-+ lock_FCS(LOCK_FCS_AC97_SUB, 0);
-+ up(&CAR_mutex);
-+ return ac97_seq.val;
-+}
-+
-+static void pxa_ac97_write(struct ac97_codec *codec, u8 reg, u16 val)
-+{
-+ down(&CAR_mutex);
-+ lock_FCS(LOCK_FCS_AC97_SUB, 1);
-+ if ( !(CAR & CAR_CAIP) ) {
-+ ac97_addr = (volatile u32 *)&PAC_REG_BASE + (reg >> 1);
-+#ifdef USE_AC97_INTERRUPT
-+ ac97_seq.val = val;
-+ ac97_seq.seq = AC97_SEQ_WRITE_DONE;
-+ init_completion(&CAR_completion);
-+
-+ ac97_timer_set(ac97_seq.seq);
-+
-+ *ac97_addr = ac97_seq.val;
-+ wait_for_completion(&CAR_completion);
-+
-+ ac97_timer_clear();
-+#else
-+ {
-+ int timeout=0;
-+ GSR |= GSR_CDONE;
-+ *ac97_addr = val;
-+ while((GSR & GSR_CDONE)==0 && timeout++<AC97_TIMEOUT_VAL);
-+ if (timeout>=AC97_TIMEOUT_VAL) {
-+ printk(KERN_CRIT __FUNCTION__": AC97 is busy.\n");
-+ }
-+ }
-+#endif // end USE_AC97_INTERRUPT
-+ } else {
-+ printk(KERN_CRIT __FUNCTION__": CAR_CAIP already set\n");
-+ }
-+ lock_FCS(LOCK_FCS_AC97_SUB, 0);
-+ up(&CAR_mutex);
-+}
-+
-+static void pxa_ac97_bit_clear(struct ac97_codec *codec, u8 reg, u16 val)
-+{
-+ unsigned short dat = codec->codec_read(codec, reg);
-+ dat &= ~val;
-+ codec->codec_write(codec, reg, dat);
-+}
-+
-+static void pxa_ac97_bit_set(struct ac97_codec *codec, u8 reg, u16 val)
-+{
-+ unsigned short dat = codec->codec_read(codec, reg);
-+ dat |= val;
-+ codec->codec_write(codec, reg, dat);
-+}
-+
-+static void pxa_ac97_irq(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ if (GSR & (GSR_SDONE|GSR_CDONE)) {
-+ GSR = GSR_SDONE|GSR_CDONE;
-+
-+ ac97_timer_set(ac97_seq.seq);
-+
-+ switch ( ac97_seq.seq ) {
-+ case AC97_SEQ_READ1:
-+ ac97_seq.seq = AC97_SEQ_READ2;
-+ (void)*ac97_addr;
-+ break;
-+ case AC97_SEQ_READ2:
-+ ac97_seq.seq = AC97_SEQ_READ_DONE;
-+ if ( GSR & GSR_RDCS ) {
-+ GSR |= GSR_RDCS;
-+ printk(KERN_CRIT __FUNCTION__": read codec register timeout.\n");
-+ }
-+ ac97_seq.val = *ac97_addr;
-+ break;
-+ case AC97_SEQ_READ_DONE:
-+ udelay(20);
-+ complete(&CAR_completion);
-+ break;
-+ case AC97_SEQ_WRITE_DONE:
-+ complete(&CAR_completion);
-+ break;
-+ }
-+ }
-+}
-+
-+static struct ac97_codec pxa_ac97_codec = {
-+ codec_read: pxa_ac97_read,
-+ codec_write: pxa_ac97_write,
-+ codec_bit_clear: pxa_ac97_bit_clear,
-+ codec_bit_set: pxa_ac97_bit_set,
-+};
-+
-+static DECLARE_MUTEX(pxa_ac97_mutex);
-+static int pxa_ac97_refcount = 0;
-+
-+static char *codec_id(u16 id1, u16 id2, char *buf)
-+{
-+ if(id1&0x8080) {
-+ snprintf(buf, CODEC_ID_BUFSZ, "0x%04x:0x%04x", id1, id2);
-+ } else {
-+ buf[0] = (id1 >> 8);
-+ buf[1] = (id1 & 0xFF);
-+ buf[2] = (id2 >> 8);
-+ snprintf(buf+3, CODEC_ID_BUFSZ - 3, "%d", id2&0xFF);
-+ }
-+ return buf;
-+}
-+
-+static int ac97_check_modem(struct ac97_codec *codec)
-+{
-+ /* Check for an AC97 1.0 soft modem (ID1) */
-+ if(codec->codec_read(codec, AC97_RESET) & 2)
-+ return 1;
-+ /* Check for an AC97 2.x soft modem */
-+ codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0L);
-+ if(codec->codec_read(codec, AC97_EXTENDED_MODEM_ID) & 1)
-+ return 1;
-+ return 0;
-+}
-+
-+static int ac97_probe(struct ac97_codec *codec)
-+{
-+ u16 id1, id2;
-+ u16 audio;
-+ int i;
-+ char cidbuf[CODEC_ID_BUFSZ];
-+
-+ codec->codec_write(codec, AC97_RESET, 0L);
-+
-+ /* also according to spec, we wait for codec-ready state */
-+ if ( codec->codec_wait ) codec->codec_wait(codec);
-+ else udelay(10);
-+
-+ if ( (audio = codec->codec_read(codec, AC97_RESET)) & 0x8000 ) {
-+ printk(KERN_ERR "ac97_codec: %s ac97 codec not present\n",
-+ (codec->id & 0x2) ? (codec->id&1 ? "4th" : "Tertiary")
-+ : (codec->id&1 ? "Secondary": "Primary"));
-+ return 0;
-+ }
-+
-+ /* probe for Modem Codec */
-+ codec->modem = ac97_check_modem(codec);
-+ codec->name = NULL;
-+ codec->codec_ops = &null_ops;
-+
-+ id1 = codec->codec_read(codec, AC97_VENDOR_ID1);
-+ id2 = codec->codec_read(codec, AC97_VENDOR_ID2);
-+ for (i = 0; i < ARRAY_SIZE(ac97_ids); i++) {
-+ if (ac97_ids[i].id == ((id1 << 16) | id2)) {
-+ codec->type = ac97_ids[i].id;
-+ codec->name = ac97_ids[i].name;
-+ codec->codec_ops = ac97_ids[i].ops;
-+ codec->flags = ac97_ids[i].flags;
-+ break;
-+ }
-+ }
-+
-+ /* A device which thinks its a modem but isnt */
-+ if ( codec->flags & AC97_DELUDED_MODEM )
-+ codec->modem = 0;
-+
-+ if ( codec->name == NULL )
-+ codec->name = "Unknown";
-+ printk(KERN_INFO "ac97_codec: AC97 %s codec, id: %s (%s)\n",
-+ codec->modem ? "Modem" : (audio ? "Audio" : ""),
-+ codec_id(id1, id2, cidbuf), codec->name);
-+ return 1;
-+}
-+
-+int pxa_ac97_get(struct ac97_codec **codec, unsigned char *ac97_on)
-+{
-+ if ( *ac97_on != 0 ) return 0;
-+
-+ *codec = NULL;
-+ down(&pxa_ac97_mutex);
-+
-+ DEBUG(DBG_L1, "count(%d)\n", pxa_ac97_refcount);
-+ pxa_ac97_refcount++;
-+ up(&pxa_ac97_mutex);
-+ *codec = &pxa_ac97_codec;
-+ *ac97_on = 1;
-+
-+ return 0;
-+}
-+
-+void pxa_ac97_put(unsigned char *ac97_on)
-+{
-+ if ( *ac97_on == 0 ) return;
-+ down(&pxa_ac97_mutex);
-+ pxa_ac97_refcount--;
-+ DEBUG(DBG_L1, "count(%d)\n", pxa_ac97_refcount);
-+ up(&pxa_ac97_mutex);
-+ *ac97_on = 0;
-+}
-+
-+unsigned int ac97_set_dac_rate(struct ac97_codec *codec, unsigned int rate)
-+{
-+ unsigned int new_rate = rate;
-+ u32 dacp;
-+ u32 mast_vol, phone_vol, mono_vol, pcm_vol;
-+ u32 mute_vol = 0x8000; /* The mute volume? */
-+
-+ if( rate != codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE) ) {
-+ /* Mute several registers */
-+ mast_vol = codec->codec_read(codec, AC97_MASTER_VOL_STEREO);
-+ mono_vol = codec->codec_read(codec, AC97_MASTER_VOL_MONO);
-+ phone_vol = codec->codec_read(codec, AC97_HEADPHONE_VOL);
-+ pcm_vol = codec->codec_read(codec, AC97_PCMOUT_VOL);
-+ codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mute_vol);
-+ codec->codec_write(codec, AC97_MASTER_VOL_MONO, mute_vol);
-+ codec->codec_write(codec, AC97_HEADPHONE_VOL, mute_vol);
-+ codec->codec_write(codec, AC97_PCMOUT_VOL, mute_vol);
-+
-+ /* Power down the DAC */
-+ dacp=codec->codec_read(codec, AC97_POWER_CONTROL);
-+ codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0200);
-+ /* Load the rate and read the effective rate */
-+ codec->codec_write(codec, AC97_PCM_FRONT_DAC_RATE, rate);
-+ new_rate=codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE);
-+ /* Power it back up */
-+ codec->codec_write(codec, AC97_POWER_CONTROL, dacp);
-+
-+ /* Restore volumes */
-+ codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mast_vol);
-+ codec->codec_write(codec, AC97_MASTER_VOL_MONO, mono_vol);
-+ codec->codec_write(codec, AC97_HEADPHONE_VOL, phone_vol);
-+ codec->codec_write(codec, AC97_PCMOUT_VOL, pcm_vol);
-+ }
-+ return new_rate;
-+}
-+
-+unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate)
-+{
-+ unsigned int new_rate = rate;
-+ u32 dacp;
-+ if( rate != codec->codec_read(codec, AC97_PCM_LR_ADC_RATE) ) {
-+ /* Power "Up" the ADC */
-+ dacp=codec->codec_read(codec, AC97_POWER_CONTROL);
-+ dacp &= ~(0x1<<8);
-+ codec->codec_write(codec, AC97_POWER_CONTROL, dacp);
-+
-+ codec->codec_write(codec, AC97_PCM_LR_ADC_RATE, rate);
-+ new_rate=codec->codec_read(codec, AC97_PCM_LR_ADC_RATE);
-+
-+ /* Power it back up */
-+ codec->codec_write(codec, AC97_POWER_CONTROL, dacp);
-+ }
-+ return new_rate;
-+}
-+
-+void wm9712_power_mode(int dev, int mode)
-+{
-+ int i;
-+ power_mode_t new_power_status;
-+ dev %= NUM_OF_WM9712_DEV;
-+ mode %= num_of_pwr_values;
-+ // printk("wm9712_power_mode(%d,%d)\n",dev,mode);
-+ power_mode_status[dev] = pwr_values[mode];
-+ // create new state
-+ new_power_status = power_mode_status[0];
-+ for (i=1; i<NUM_OF_WM9712_DEV; i++) {
-+ new_power_status.ctl_val &= power_mode_status[i].ctl_val;
-+ new_power_status.pdown_val &= power_mode_status[i].pdown_val;
-+ }
-+ // compare with current state
-+ if (new_power_status.pdown_val != cur_power_status.pdown_val) {
-+ ac97_write(AC97_POWERDOWN, new_power_status.pdown_val);
-+ cur_power_status.pdown_val = new_power_status.pdown_val;
-+ // printk("change status PWDOWN = %04X\n", cur_power_status.pdown_val);
-+ }
-+ if (new_power_status.ctl_val != cur_power_status.ctl_val) {
-+ ac97_write(AC97_POWER_CONTROL, new_power_status.ctl_val);
-+ cur_power_status.ctl_val = new_power_status.ctl_val;
-+ // printk("change status PW_CTRL = %04X\n", cur_power_status.ctl_val);
-+ }
-+
-+}
-+
-+void tosa_ac97_init(void)
-+{
-+ int i;
-+ int ret,timeo;
-+
-+ lock_FCS(LOCK_FCS_AC97, 1);
-+ codec = NULL;
-+ pxa_ac97_refcount = 0;
-+ set_GPIO_mode(GPIO31_SYNC_AC97_MD);
-+ set_GPIO_mode(GPIO30_SDATA_OUT_AC97_MD);
-+ set_GPIO_mode(GPIO28_BITCLK_AC97_MD);
-+ set_GPIO_mode(GPIO29_SDATA_IN_AC97_MD);
-+ set_GPIO_mode(GPIO20_DREQ0_MD);
-+
-+ for (i=0; i<NUM_OF_WM9712_DEV; i++) {
-+ power_mode_status[i].ctl_val = pwr_values[WM9712_PWR_OFF].ctl_val;
-+ power_mode_status[i].pdown_val = pwr_values[WM9712_PWR_OFF].pdown_val;
-+ }
-+ memset(&cur_power_status,0,sizeof(cur_power_status));
-+
-+#if 1 // move from ac97_get
-+ CKEN |= CKEN2_AC97;
-+ /* AC97 power on sequense */
-+ while ( 1 ) {
-+ GCR = 0;
-+ udelay(100);
-+ GCR |= GCR_COLD_RST;
-+ udelay(5);
-+ GCR |= GCR_WARM_RST;
-+ udelay(5);
-+ for ( timeo = 0x10000; timeo > 0; timeo-- ) {
-+ if ( GSR & GSR_PCR ) break;
-+ //X schedule();
-+ mdelay(5);
-+ }
-+ if( timeo > 0 ) break;
-+ printk(KERN_WARNING "AC97 power on retry!!\n");
-+ }
-+
-+#ifdef USE_AC97_INTERRUPT
-+ if( (ret = request_irq(IRQ_AC97, pxa_ac97_irq, 0, "AC97", NULL)) ) {
-+ lock_FCS(LOCK_FCS_AC97, 0);
-+ return ret;
-+ }
-+ }
-+#endif
-+
-+ if ( (ret = ac97_probe(&pxa_ac97_codec)) != 1 ) {
-+#ifdef USE_AC97_INTERRUPT
-+ free_irq(IRQ_AC97, NULL);
-+#endif
-+ GCR = GCR_ACLINK_OFF;
-+ CKEN &= ~CKEN2_AC97;
-+ lock_FCS(LOCK_FCS_AC97, 0);
-+ return ret;
-+ }
-+ pxa_ac97_write(&pxa_ac97_codec, AC97_EXTENDED_STATUS, 1);
-+ /*
-+ * Setting AC97 GPIO
-+ * i/o function
-+ * GPIO1: input EAR_IN signal
-+ * GPIO2: output IRQ signal
-+ * GPIO3: output PENDOWN signal
-+ * GPIO4: input MASK signal
-+ * GPIO5: input DETECT MIC signal
-+ */
-+ pxa_ac97_bit_clear(&pxa_ac97_codec, AC97_GPIO_FUNC,
-+ ((1<<2)|(1<<3)|(1<<4)|(1<<5)));
-+ pxa_ac97_bit_clear(&pxa_ac97_codec, AC97_GPIO_CONFIG,(1<<2)|(1<<3));
-+ pxa_ac97_bit_set(&pxa_ac97_codec, AC97_GPIO_CONFIG, (1<<1)|(1<<4)|(1<<5));
-+#endif
-+ codec = &pxa_ac97_codec;
-+ lock_FCS(LOCK_FCS_AC97, 0);
-+}
-+
-+void tosa_ac97_exit(void)
-+{
-+#if 1 // move from ac97_put
-+ GCR = GCR_ACLINK_OFF;
-+ CKEN &= ~CKEN2_AC97;
-+#ifdef USE_AC97_INTERRUPT
-+ free_irq(IRQ_AC97, NULL);
-+#endif
-+ pxa_ac97_refcount = 0;
-+#endif
-+}
-+
-+EXPORT_SYMBOL(ac97_set_dac_rate);
-+EXPORT_SYMBOL(ac97_set_adc_rate);
-+EXPORT_SYMBOL(pxa_ac97_get);
-+EXPORT_SYMBOL(pxa_ac97_put);
-+EXPORT_SYMBOL(wm9712_power_mode);
-diff -Nur linux_c860_org/arch/arm/mach-pxa/tosa_battery.c linux/arch/arm/mach-pxa/tosa_battery.c
---- linux_c860_org/arch/arm/mach-pxa/tosa_battery.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/arch/arm/mach-pxa/tosa_battery.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,2603 @@
-+/*
-+ * linux/arch/arm/mach-pxa/tosa_battery.c
-+ *
-+ * Based on
-+ * linux/arch/arm/mach-sa1100/collie_battery.c
-+ * linux/arch/arm/mach-pxa/sharpsl_battery.c
-+ *
-+ * Battery routines for tosa (SHARP)
-+ *
-+ * Copyright (C) 2004 SHARP
-+ *
-+ * 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.
-+ *
-+ * ChangeLog:
-+ *
-+ */
-+
-+
-+/* this driver support the following functions
-+ * - apm_get_power_status
-+ * - charge proc
-+ */
-+
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/poll.h>
-+#include <linux/types.h>
-+#include <linux/stddef.h>
-+#include <linux/timer.h>
-+#include <linux/fcntl.h>
-+#include <linux/slab.h>
-+#include <linux/stat.h>
-+#include <linux/proc_fs.h>
-+#include <linux/miscdevice.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/pm.h>
-+#include <linux/kernel.h>
-+#include <linux/smp_lock.h>
-+#include <linux/apm_bios.h>
-+#include <linux/delay.h>
-+
-+#include <asm/io.h>
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/mach/irq.h>
-+#include <asm/hardirq.h>
-+
-+#include <asm/sharp_char.h>
-+#include <asm/sharp_keycode.h>
-+#include <linux/ac97_codec.h>
-+#include <asm/arch/tosa_wm9712.h>
-+#include <asm/arch/keyboard_tosa.h>
-+#include <asm/arch/tosa.h>
-+#include <video/tosa_backlight.h>
-+#include <asm/arch/sharpsl_battery.h>
-+
-+#define TOSA_BATTERY_FAILSAFE_LOWBAT
-+#define TOSA_BATTERY_AD_OFFSET (0)
-+
-+#define TOSA_OFF_CHARGE_FAILSAFE
-+
-+#define TOSA_FOR_ENGLISH
-+
-+#ifdef DEBUG
-+#define DPRINTK(x, args...) printk(x,##args)
-+#else
-+#define DPRINTK(x, args...) if ( msglevel & 1 ) printk(x,##args);
-+#endif
-+
-+#ifdef DEBUG2
-+#define DPRINTK2(x, args...) printk( x,##args)
-+#else
-+#define DPRINTK2(x, args...) if ( msglevel & 2 ) printk(x,##args);
-+#endif
-+
-+#ifdef DEBUG3
-+#define DPRINTK3(x, args...) printk( x,##args)
-+#else
-+#define DPRINTK3(x, args...) if ( msglevel & 4 ) printk(x,##args);
-+#endif
-+
-+#ifdef DEBUG4
-+#define DPRINTK4(x, args...) printk( x,##args)
-+#else
-+#define DPRINTK4(x, args...) if ( msglevel & 8 ) printk(x,##args);
-+#endif
-+
-+#ifdef TOSA_FOR_ENGLISH
-+#ifdef DEBUG5
-+#define DPRINTK5(x, args...) printk( x,##args)
-+#else
-+#define DPRINTK5(x, args...) if ( msglevel & 16 ) printk("[CHKCHGFULL]: "x,##args);
-+#endif
-+#endif // TOSA_FOR_ENGLISH
-+
-+#define CHECK_LOG (0) // for DEBUG
-+#if CHECK_LOG
-+int gStartTime = 0;
-+#endif
-+
-+/*
-+ * The battery device is one of the misc char devices.
-+ * This is its minor number.
-+ */
-+#define BATTERY_MINOR_DEV 215
-+
-+#define SEL_MAIN 0
-+#define SEL_JACKET 1
-+#define SEL_BU 2
-+
-+static void tosa_charge_on_off(int,int);
-+
-+#define CHARGE_ON() ( { CHARGE_0_ON(); CHARGE_1_ON(); } )
-+#define CHARGE_OFF() ( { CHARGE_0_OFF(); CHARGE_1_OFF(); } )
-+
-+#define CHARGE_0_ON() tosa_charge_on_off(SEL_MAIN, 1)
-+#define CHARGE_0_OFF() tosa_charge_on_off(SEL_MAIN, 0)
-+
-+#define CHARGE_1_ON() tosa_charge_on_off(SEL_JACKET, 1)
-+#define CHARGE_1_OFF() tosa_charge_on_off(SEL_JACKET, 0)
-+
-+extern void sharpsl_charge_err_off(void);
-+#define CHARGE_LED_ON() set_led_status(SHARP_LED_CHARGER,LED_CHARGER_CHARGING)
-+#define CHARGE_LED_OFF() set_led_status(SHARP_LED_CHARGER,LED_CHARGER_OFF)
-+#define CHARGE_LED_ERR() set_led_status(SHARP_LED_CHARGER,LED_CHARGER_ERROR)
-+#define CHARGE_LED_ERR_OFF() sharpsl_charge_err_off()
-+
-+#define SHARPSL_BATTERY_STATUS_HIGH APM_BATTERY_STATUS_HIGH
-+#define SHARPSL_BATTERY_STATUS_LOW APM_BATTERY_STATUS_LOW
-+#define SHARPSL_BATTERY_STATUS_VERYLOW APM_BATTERY_STATUS_VERY_LOW
-+#define SHARPSL_BATTERY_STATUS_CRITICAL APM_BATTERY_STATUS_CRITICAL
-+
-+#define APM_BATL_CLOSE 0
-+#define APM_BATL_OPEN 1
-+#define SHARPSL_BAT_LOCKED_STATUS \
-+ (( GPLR(GPIO_BAT_LOCKED) & GPIO_bit(GPIO_BAT_LOCKED) ) ? APM_BATL_CLOSE : APM_BATL_OPEN)
-+
-+static int tosa_ac_line_status(int);
-+#define SHARPSL_AC_LINE_STATUS tosa_ac_line_status(20 /* msec */)
-+
-+#define SHARPSL_MAIN_BATT_FATAL \
-+ (( GPLR(GPIO_BAT0_LOW) & GPIO_bit(GPIO_BAT0_LOW) ) ? 0 : 1 )
-+
-+#define SHARPSL_JACKET_BATT_FATAL \
-+ (( GPLR(GPIO_BAT1_LOW) & GPIO_bit(GPIO_BAT1_LOW) ) ? 0 : 1 )
-+
-+#define SHARPSL_MAIN_BATT_FULL \
-+ (( GPLR(GPIO_BAT0_CRG) & GPIO_bit(GPIO_BAT0_CRG) ) ? 1 : 0 )
-+
-+#define SHARPSL_JACKET_BATT_FULL \
-+ (( GPLR(GPIO_BAT1_CRG) & GPIO_bit(GPIO_BAT1_CRG) ) ? 1 : 0 )
-+
-+
-+#define SHARPSL_APO_DEFAULT ( ( 3 * 60 ) * SHARPSL_PM_TICK ) // 3 min
-+#define SHARPSL_LPO_DEFAULT ( 20 * SHARPSL_PM_TICK ) // 20 sec
-+
-+
-+#define SHARPSL_PM_TICK ( HZ ) // 1 sec
-+#define SHARPSL_BATCHK_TIME ( SHARPSL_PM_TICK ) // 1 sec
-+#define SHARPSL_MAIN_GOOD_COUNT ( HZ / SHARPSL_PM_TICK ) // 1 sec
-+#define SHARPSL_MAIN_NOGOOD_COUNT ( HZ / SHARPSL_PM_TICK ) // 1 sec
-+
-+#define SHARPSL_BATTERY_CK_TIME ( 10*60*1*100 ) // 10min ( base jiffies )
-+#define TOSA_TEMP_READ_WAIT_TIME (5) // 5msec [Fix]
-+#define TOSA_BATTERY_READ_WAIT_TIME (5) // 5msec [Fix]
-+#define TOSA_DISCHARGE_WAIT_TIME (10) // 10msec
-+
-+#define TOSA_MAIN_BATTERY_EXIST_THRESH (3600) // 2.9V [Fix]
-+#define TOSA_JACKET_BATTERY_EXIST_THRESH (3600) // 2.9V [Fix]
-+
-+#define TOSA_MAIN_BATTERY_ERR_THRESH (1200) // 2.9V [Fix]
-+#define TOSA_JACKET_BATTERY_ERR_THRESH (1200) // 2.9V [Fix]
-+
-+
-+#define TOSA_MAIN_BATT_FATAL_ACIN_VOLT (1572+TOSA_BATTERY_AD_OFFSET) // 3.80V [Fix]
-+#define TOSA_JACKET_BATT_FATAL_ACIN_VOLT (1572+TOSA_BATTERY_AD_OFFSET) // 3.80V [Fix]
-+#define TOSA_MAIN_BATT_FATAL_NOACIN_VOLT (1551+TOSA_BATTERY_AD_OFFSET) // 3.75V [Fix]
-+#define TOSA_JACKET_BATT_FATAL_NOACIN_VOLT (1551+TOSA_BATTERY_AD_OFFSET) // 3.75V [Fix]
-+
-+
-+#define TOSA_JC_CHECK_WAIT_TIME 10 // 10*10mS Jacket Check [Fix]
-+#define TOSA_JC_CHECK_TIMES 5 // 5 times
-+
-+#define SHARPSL_TOSA_WAIT_CO_TIME 20 // 20 Sec
-+ //NOTICE !! you want to change this value , so you must change
-+ // alarm check mirgin time ( +30 ) in the sharpsl_power.c.
-+
-+#define SHARPSL_CAUTION_CONTRAST TOSA_BL_CAUTION_CONTRAST
-+#define SHARPSL_RESET_CONTRAST TOSA_BL_RESET_CONTRAST
-+#define SHARPSL_LIMIT_CONTRAST(x) tosa_bl_set_limit_contrast(x)
-+
-+#define CHARGE_STEP1 1
-+#define CHARGE_STEP2 2
-+#define CHARGE_STEP3 3
-+#define CHARGE_STEP4 4
-+#define CHARGE_STEP5 5
-+#define CHARGE_STEP6 6
-+#define CHARGE_STEP7 7
-+#define CHARGE_STEP_END 10
-+#define CHARGE_STEP_EXIT 11
-+#define CHARGE_STEP_ERROR 12
-+#define SHARPSL_CHARGE_RETRY_CNT 1 // 10 min
-+#define SHARPSL_AFTER_CHARGE_CNT 0 // 0
-+
-+#define SHARPSL_CNV_VALUE_NUM 10
-+#define SHARPSL_CNV_TEMP_NUM 10
-+
-+
-+typedef struct BatteryThresh {
-+ int voltage;
-+ int percentage;
-+ int status;
-+} BATTERY_THRESH;
-+
-+/*** prototype *********************************************************************/
-+static int tosa_get_jacket_status(void);
-+static void tosa_request_off(void);
-+static int tosa_battery_thread_main(void);
-+static int tosa_get_sel_battery(int); //[Fix]
-+static int tosa_read_battery(int); //[Fix]
-+static int tosa_read_temp(int); //[Fix]
-+static int tosa_read_battery_avg(int);
-+static int tosa_read_temp_avg(int); //[Fix]
-+static int tosa_check_battery_error(int,int);
-+static int tosa_check_battery_exist(int,int); //[Fix]
-+static int tosa_check_main_battery_error(void);
-+static int tosa_check_jacket_battery_error(void);
-+static int tosa_check_main_battery_not_exist(void); //[Fix]
-+static int tosa_check_jacket_battery_not_exist(void); //[Fix]
-+static int tosa_read_main_battery(void);
-+static int tosa_read_jacket_battery(void);
-+static int tosa_read_backup_battery(void);
-+static int tosa_check_main_batt_fatal(void);
-+static int tosa_check_jacket_batt_fatal(void);
-+static void tosa_charge_start(void); //[Fix]
-+static void tosa_charge_stop(void); //[Fix]
-+static void tosa_reset_battery_info(void);
-+static void tosa_jacket_kick_timer(void);
-+static void tosa_jacket_interrupt(int,void *,struct pt_regs *);
-+static void tosa_ac_interrupt(int,void *,struct pt_regs *);
-+static void tosa_main_batt_fatal_interrupt(int,void *,struct pt_regs *);
-+static void tosa_jacket_batt_fatal_interrupt(int,void *,struct pt_regs *);
-+static int tosa_cnv_battery(int,int);
-+static void tosa_get_all_battery(void); //[Fix]
-+static int tosa_get_sel_charge_percent(int,int);
-+static BATTERY_THRESH *tosa_get_sel_level(int,int);
-+static int tosa_get_dac_value(int); //[Fix]
-+static int get_select_val(int *);
-+static int tosa_get_jacket_status_for_on(void);
-+static void tosa_off_jc_card_limit(void);
-+
-+
-+/* thread */
-+static int tosa_charge_on(void*);
-+static int tosa_charge_off(void*);
-+static int tosa_battery_thread(void*);
-+static int tosa_fatal_check(void*);
-+static int tosa_jacket_check(void*);
-+
-+
-+/*** extern ***********************************************************************/
-+extern u32 apm_wakeup_src_mask;
-+extern int counter_step_contrast;
-+extern void handle_scancode(unsigned char,int);
-+extern unsigned long ssp_get_dac_val(unsigned long,int);
-+extern int sharpsl_is_power_mode_sensitive_battery(void);
-+extern int ac97_ad_input(int,unsigned short *);
-+extern int set_led_status(int,int);
-+extern unsigned short set_scoop_jc_gpio(unsigned short);
-+extern unsigned short reset_scoop_jc_gpio(unsigned short);
-+
-+#ifdef CONFIG_PM
-+extern int pass_charge_flag;
-+//extern int counter_step_save;
-+#endif
-+
-+/*** variables ********************************************************************/
-+
-+/* BL 5-3 */
-+BATTERY_THRESH sharpsl_main_battery_thresh_fl[] = {
-+ { 1663, 100, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 1605, 75, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 1564, 50, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 1510, 25, SHARPSL_BATTERY_STATUS_LOW},
-+ { 1435, 5, SHARPSL_BATTERY_STATUS_VERYLOW},
-+ { 0, 0, SHARPSL_BATTERY_STATUS_CRITICAL},
-+};
-+
-+/* BL 2-0 */
-+BATTERY_THRESH sharpsl_main_battery_thresh_nofl[] = {
-+ { 1679, 100, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 1617, 75, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 1576, 50, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 1530, 25, SHARPSL_BATTERY_STATUS_LOW},
-+ { 1448, 5, SHARPSL_BATTERY_STATUS_VERYLOW},
-+ { 0, 0, SHARPSL_BATTERY_STATUS_CRITICAL},
-+};
-+
-+/* BL 5-3 */
-+BATTERY_THRESH sharpsl_jacket_battery_thresh_fl[] = {
-+ { 1663, 100, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 1605, 75, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 1564, 50, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 1510, 25, SHARPSL_BATTERY_STATUS_LOW},
-+ { 1435, 5, SHARPSL_BATTERY_STATUS_VERYLOW},
-+ { 0, 0, SHARPSL_BATTERY_STATUS_CRITICAL},
-+};
-+
-+/* BL 2-0 */
-+BATTERY_THRESH sharpsl_jacket_battery_thresh_nofl[] = {
-+ { 1679, 100, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 1617, 75, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 1576, 50, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 1530, 25, SHARPSL_BATTERY_STATUS_LOW},
-+ { 1448, 5, SHARPSL_BATTERY_STATUS_VERYLOW},
-+ { 0, 0, SHARPSL_BATTERY_STATUS_CRITICAL},
-+};
-+
-+BATTERY_THRESH sharpsl_bu_battery_thresh_fl[] = {
-+ { 3226, 100, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 0, 0, SHARPSL_BATTERY_STATUS_VERYLOW},
-+};
-+
-+BATTERY_THRESH sharpsl_bu_battery_thresh_nofl[] = {
-+ { 3226, 100, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 0, 0, SHARPSL_BATTERY_STATUS_VERYLOW},
-+};
-+
-+
-+#if 1
-+static struct file_operations sharpsl_battery_fops = {
-+};
-+#else
-+static struct file_operations sharpsl_battery_fops = {
-+ owner: THIS_MODULE,
-+ read: do_read,
-+ poll: do_poll,
-+ ioctl: do_ioctl,
-+ open: do_open,
-+ release: do_release,
-+};
-+#endif
-+
-+static struct miscdevice battery_device = {
-+ BATTERY_MINOR_DEV,
-+ "battery",
-+ &sharpsl_battery_fops
-+};
-+
-+
-+int charge_status = 0; /* charge status 1 : charge 0: not charge */
-+int sharpsl_off_charge = 0; /* 0: on , 1 : off */
-+
-+unsigned int APOCnt = SHARPSL_APO_DEFAULT;
-+unsigned int APOCntWk = 0;
-+unsigned int LPOCnt = SHARPSL_LPO_DEFAULT;
-+unsigned int LPOCntWk = 0;
-+static DECLARE_WAIT_QUEUE_HEAD(battery_queue);
-+static int msglevel;
-+
-+int sharpsl_main_battery = SHARPSL_BATTERY_STATUS_HIGH;
-+int sharpsl_main_battery_percentage = 100;
-+int sharpsl_jacket_battery = SHARPSL_BATTERY_STATUS_HIGH;
-+int sharpsl_jacket_battery_percentage = 100;
-+int sharpsl_bu_battery = SHARPSL_BATTERY_STATUS_HIGH;
-+int sharpsl_bu_battery_percentage = 100;
-+
-+int sharpsl_bat_locked = 0;
-+
-+int sharpsl_jacket_exist = 0;
-+int sharpsl_jacket_batt_exist = 0;
-+static int tosa_jacket_status_change = 0;
-+static int tosa_jacket_check_only = 0;
-+static int tosa_cardslot_error = 0;
-+#define ERR_CARDSLOT_CF1 (0x1<<0)
-+#define ERR_CARDSLOT_CF2 (0x1<<1)
-+#define ERR_CARDSLOT_SD (0x1<<2)
-+
-+int sharpsl_ac_status = APM_AC_OFFLINE;
-+
-+static int MainCntWk = SHARPSL_MAIN_GOOD_COUNT;
-+static int MainCnt = SHARPSL_MAIN_NOGOOD_COUNT;
-+static int back_ac_status = -1;
-+
-+static int back_battery_status = -1;
-+static int back_jacket_battery_status = -1;
-+static int back_bu_battery_status = -1;
-+static int sharpsl_check_time = SHARPSL_BATCHK_TIME;
-+
-+static int sharpsl_main_status_bk = SHARPSL_BATTERY_STATUS_HIGH;
-+static int sharpsl_main_percent_bk = 100;
-+static int sharpsl_jacket_status_bk = SHARPSL_BATTERY_STATUS_HIGH;
-+static int sharpsl_jacket_percent_bk = 100;
-+static int sharpsl_bu_status_bk = SHARPSL_BATTERY_STATUS_HIGH;
-+static int sharpsl_bu_percent_bk = 100;
-+
-+int sharpsl_main_bk_flag = 0;
-+
-+static struct timer_list ac_kick_timer;
-+static struct timer_list jacket_kick_timer;
-+
-+#ifdef CONFIG_PM
-+static struct pm_dev *battery_pm_dev; /* registered PM device */
-+#endif
-+
-+static int battery_off_flag = 0; /* charge : suspend while get adc */
-+static int is_ac_adaptor = 0; /* AC adaptor in/out */
-+
-+static DECLARE_WAIT_QUEUE_HEAD(charge_on_queue);
-+static DECLARE_WAIT_QUEUE_HEAD(charge_off_queue);
-+static DECLARE_WAIT_QUEUE_HEAD(battery_waitqueue);
-+static DECLARE_WAIT_QUEUE_HEAD(fatal_chk_queue);
-+static DECLARE_WAIT_QUEUE_HEAD(jacket_chk_queue);
-+
-+static int is_enabled_off = 1;
-+
-+int sharpsl_charge_cnt = 0;
-+int sharpsl_charge_dummy_cnt = 1;
-+
-+static int sharpsl_ad_main[SHARPSL_CNV_VALUE_NUM+1];
-+static int sharpsl_ad_index_main = 0;
-+static int sharpsl_ad_jacket[SHARPSL_CNV_VALUE_NUM+1];
-+static int sharpsl_ad_index_jacket = 0;
-+static int sharpsl_ad_bu[SHARPSL_CNV_VALUE_NUM+1];
-+static int sharpsl_ad_index_bu = 0;
-+
-+static int tosa_jacket_check_count = 0;
-+static unsigned int tosa_jacket_state = 0;
-+static int tosa_dac_init = 0;
-+
-+
-+static int sharpsl_change_battery_status = 0;
-+
-+static int tosa_jc_card_limit_sel = 0;
-+
-+static int tosa_off_main_batt_full = 0;
-+static int tosa_off_jacket_batt_full = 0;
-+
-+static int tosa_off_check_jacket_req = 0;
-+
-+// for DEBUG
-+static int sharpsl_debug_flag = 0;
-+
-+#ifdef TOSA_OFF_CHARGE_FAILSAFE
-+#define TOSA_CHARGE_FULL_MAX_TIME (4*60*60) // 4H
-+#define TOSA_CHARGE_FULL_DIFF_VOLT (20) // about 50mV
-+static int tosa_charge_full_enable = 0;
-+static int tosa_charge_full_counter = 0;
-+static int tosa_charge_full_main_batt = 0;
-+static int tosa_charge_full_jacket_batt = 0;
-+#endif //TOSA_OFF_CHARGE_FAILSAFE
-+
-+#ifdef TOSA_FOR_ENGLISH
-+static int tosa_charge_full_state = 0;
-+static int tosa_decide_charge_full_counter = 0;
-+int logo_lang = 0; // (default): En , (1): Jp
-+#define TOSA_DECIDE_CHARGE_FULL_COUNTER ( 60*100 ) // 1min ( base jiffies )
-+#define DISCONNECT_AC (0)
-+#define CONNECT_AC (1)
-+#define DETECT_CHARGE_FULL (2)
-+#define DECIDE_CHARGE_FULL (3)
-+#define GET_CHARGE_FULL_STATE() tosa_charge_full_state
-+#define SET_CHARGE_FULL_STATE(state) (tosa_charge_full_state = state)
-+#define IS_ENGLISH_MODEL() (logo_lang != 1)
-+#endif // TOSA_FOR_ENGLISH
-+
-+void set_jacketslot_error( int on )
-+{
-+ if (on) {
-+ if (!(tosa_cardslot_error&ERR_CARDSLOT_CF2)) {
-+ tosa_cardslot_error |= ERR_CARDSLOT_CF2;
-+ sharpsl_change_battery_status = 1;
-+ wake_up_interruptible(&battery_waitqueue);
-+ }
-+ } else {
-+ if (tosa_cardslot_error&ERR_CARDSLOT_CF2) {
-+ tosa_cardslot_error &= ~ERR_CARDSLOT_CF2;
-+ sharpsl_change_battery_status = 1;
-+ wake_up_interruptible(&battery_waitqueue);
-+ }
-+ }
-+}
-+
-+int current_cardslot_error( int num )
-+{
-+ if (num==0) {
-+ return (tosa_cardslot_error & ERR_CARDSLOT_CF1)?1:0;
-+ } else { // slot 1
-+ return (tosa_cardslot_error & ERR_CARDSLOT_CF2)?1:0;
-+ }
-+}
-+
-+/*** apm subroutines ***********************************************************/
-+static int tosa_get_jacket_status(void)
-+{
-+ if (tosa_jacket_check_count == 0){
-+ tosa_jacket_state = GPLR(GPIO_JACKET_DETECT) & GPIO_bit(GPIO_JACKET_DETECT);
-+ tosa_jacket_check_count++;
-+ return 0;
-+ }
-+
-+ if (tosa_jacket_state == (GPLR(GPIO_JACKET_DETECT) & GPIO_bit(GPIO_JACKET_DETECT))){
-+ if (tosa_jacket_check_count++ >= TOSA_JC_CHECK_TIMES){
-+ if (tosa_jacket_state){
-+ sharpsl_jacket_exist = 0; // non-exsistent (unit)
-+ sharpsl_jacket_batt_exist = 0; // non-exststent (battery)
-+ DPRINTK2("[BATT] jacket was removed.\n");
-+ }else{
-+ sharpsl_jacket_exist = 1; // exsistent (unit)
-+ DPRINTK2("JACKET STATUS [ EXIST ]\n");
-+ if(!tosa_check_jacket_battery_not_exist()){
-+ sharpsl_jacket_batt_exist = 1; // exsistent (battery)
-+ DPRINTK2("JACKET BATTERY STATUS [ EXIST ]\n");
-+ }else{
-+ sharpsl_jacket_batt_exist = 0; // non-exststent (battery)
-+ DPRINTK2("JACKET BATTERY STATUS [ NOT EXIST ]\n");
-+ }
-+ }
-+ // jacket battery charge control.
-+ if(sharpsl_jacket_batt_exist){
-+ CHARGE_1_ON();
-+ }else{
-+ CHARGE_1_OFF();
-+ }
-+
-+ tosa_jacket_status_change = 1; // jacket status is changed.
-+
-+ if(!tosa_jacket_check_only){
-+ sharpsl_change_battery_status = 1; // change status
-+ wake_up_interruptible(&battery_waitqueue);
-+ }
-+
-+ tosa_jacket_check_count = 0;
-+ return 1;
-+ }
-+ }else{
-+ tosa_jacket_check_count = 0;
-+ }
-+ return 0;
-+}
-+
-+static int tosa_get_jacket_status_for_on(void)
-+{
-+ tosa_jacket_check_count = 0;
-+ tosa_jacket_check_only = 1;
-+ while(1){
-+ if(tosa_get_jacket_status()){
-+ mdelay(TOSA_JC_CHECK_WAIT_TIME*10);
-+ break;
-+ }
-+ mdelay(TOSA_JC_CHECK_WAIT_TIME*10);
-+ }
-+ tosa_jacket_check_only = 0;
-+ return 0;
-+}
-+
-+int sharpsl_apm_get_power_status(u_char *ac_line_status,
-+ u_char *battery_main_status,
-+ u_char *battery_jacket_status,
-+ u_char *battery_bu_status,
-+ u_char *battery_flag,
-+ u_char *battery_main_percentage,
-+ u_char *battery_jacket_percentage,
-+ u_char *battery_bu_percentage,
-+ u_short *battery_main_life,
-+ u_short *battery_jacket_life,
-+ u_short *battery_bu_life)
-+
-+{
-+ // set ac status
-+ *ac_line_status = sharpsl_ac_status;
-+
-+ // set battery_status main
-+ *battery_main_status = sharpsl_main_battery;
-+ *battery_jacket_status = sharpsl_jacket_battery;
-+ *battery_bu_status = sharpsl_bu_battery;
-+
-+ // set battery percentage
-+ *battery_main_percentage = sharpsl_main_battery_percentage;
-+ *battery_jacket_percentage = sharpsl_jacket_battery_percentage;
-+ *battery_bu_percentage = sharpsl_bu_battery_percentage;
-+
-+ if ( *ac_line_status == APM_AC_ONLINE ){
-+ *battery_main_percentage = 100;
-+ *battery_jacket_percentage = 100;
-+ *battery_bu_percentage = 100;
-+ }
-+
-+ // set battery_flag
-+ if ( *battery_main_status == SHARPSL_BATTERY_STATUS_VERYLOW ){
-+ *battery_flag = (1 << 5);
-+ }else{
-+ *battery_flag = (1 << *battery_main_status);
-+ }
-+
-+ // chk charge status
-+#ifdef TOSA_FOR_ENGLISH
-+ if ( charge_status && (!IS_ENGLISH_MODEL() || (GET_CHARGE_FULL_STATE() != DECIDE_CHARGE_FULL))) {
-+#else
-+ if ( charge_status ) {
-+#endif // TOSA_FOR_ENGLISH
-+ *battery_main_status = APM_BATTERY_STATUS_CHARGING;
-+ *battery_jacket_status = APM_BATTERY_STATUS_CHARGING;
-+ *battery_bu_status = APM_BATTERY_STATUS_CHARGING;
-+ *battery_flag = (1 << 3);
-+ // charging now, so can not get battery percentage.
-+ *battery_main_percentage = -1;
-+ *battery_jacket_percentage = -1;
-+ *battery_bu_percentage = -1;
-+ }
-+
-+ // set battery life
-+ *battery_main_life = APM_BATTERY_LIFE_UNKNOWN;
-+ *battery_jacket_life = APM_BATTERY_LIFE_UNKNOWN;
-+ *battery_bu_life = APM_BATTERY_LIFE_UNKNOWN;
-+
-+ return APM_SUCCESS;
-+}
-+
-+
-+int sharpsl_apm_get_bp_status(u_char *ac_line_status,
-+ u_char *battery_status,
-+ u_char *battery_flag,
-+ u_char *battery_percentage,
-+ u_short *battery_life)
-+{
-+ *ac_line_status = APM_AC_OFFLINE;//collie_ac_status;
-+
-+ if ( sharpsl_jacket_batt_exist ){
-+ /* In charging stage ,battery status */
-+ if ( charge_status ){
-+#ifdef TOSA_FOR_ENGLISH
-+ if ( IS_ENGLISH_MODEL() && (GET_CHARGE_FULL_STATE() == DECIDE_CHARGE_FULL) ) {
-+ *battery_status = SHARPSL_BATTERY_STATUS_HIGH;
-+ *battery_percentage = 100;
-+ *battery_flag = (1 << SHARPSL_BATTERY_STATUS_HIGH);
-+ }else{
-+#endif // TOSA_FOR_ENGLISH
-+ *battery_status = APM_BATTERY_STATUS_CHARGING;
-+ *battery_flag = (1 << 3);//0x08;
-+ /* set battery percentage */
-+ *battery_percentage = -1;
-+#ifdef TOSA_FOR_ENGLISH
-+ }
-+#endif // TOSA_FOR_ENGLISH
-+ }else{
-+ *battery_status = sharpsl_jacket_battery;
-+ if( !(*battery_status) ){
-+ *battery_flag = 0x01;
-+ }else if(*battery_status == APM_BATTERY_STATUS_VERY_LOW){
-+ *battery_flag = 0x20;
-+ }else{
-+ *battery_flag = *battery_status << 1;
-+ }
-+ /* set battery percentage */
-+ *battery_percentage = sharpsl_jacket_battery_percentage;
-+ }
-+ }else{
-+ *battery_status = APM_BATTERY_STATUS_FAULT;
-+ *battery_flag = APM_BATTERY_STATUS_FAULT << 1;
-+ /* set battery percentage */
-+ *battery_percentage = 0;
-+ }
-+
-+ /* set battery life */
-+ *battery_life = APM_BATTERY_LIFE_UNKNOWN;
-+
-+ return APM_SUCCESS;
-+}
-+
-+
-+/*** battery main thread ***********************************************************/
-+// waitms : waitms*10 msec wait
-+// flag : 0 : check battery w/o reflcting battery status.
-+// 1 : check battery w/ reflcting battery status.
-+// 2 : check battery w/ refresh battery status.
-+void sharpsl_kick_battery_check(int before_waitms,int after_waitms,int flag)
-+{
-+ MainCntWk = MainCnt + 1;
-+
-+ // before check battery
-+ mdelay(before_waitms*10);
-+
-+ switch (flag) {
-+ case 0:
-+ tosa_battery_thread_main();
-+ break;
-+ case 1:
-+ if ( sharpsl_main_bk_flag == 0 ) {
-+ sharpsl_main_bk_flag = 1;
-+ tosa_battery_thread_main();
-+ sharpsl_main_bk_flag = 0;
-+ } else {
-+ tosa_battery_thread_main();
-+ }
-+ break;
-+ case 2:
-+ back_battery_status = -1;
-+ back_jacket_battery_status = -1;
-+ back_bu_battery_status = -1;
-+ tosa_battery_thread_main();
-+ break;
-+ }
-+
-+ // after check battery
-+ mdelay(after_waitms*10);
-+}
-+
-+static void tosa_request_off(void)
-+{
-+ is_enabled_off = 0;
-+ handle_scancode(SLKEY_OFF|KBDOWN , 1);
-+ mdelay(10);
-+ handle_scancode(SLKEY_OFF|KBUP , 0);
-+}
-+
-+static int tosa_battery_thread_main(void)
-+{
-+ // start battery check
-+ if ((jiffies > SHARPSL_BATTERY_CK_TIME) && (sharpsl_main_bk_flag == 0)) {
-+ sharpsl_main_bk_flag = 1;
-+ DPRINTK2("start check battery ! \n");
-+ }
-+
-+ // get ac status. if change ac status , chk main battery.
-+ sharpsl_ac_status = SHARPSL_AC_LINE_STATUS;
-+ if ( back_ac_status != sharpsl_ac_status ) {
-+ MainCntWk = MainCnt + 1; // chk battery
-+ sharpsl_change_battery_status = 1; // change status
-+ wake_up_interruptible(&battery_waitqueue);
-+ }
-+ back_ac_status = sharpsl_ac_status;
-+
-+ // get battery status.
-+ tosa_get_all_battery();
-+
-+ if ( sharpsl_ac_status == APM_AC_ONLINE ){
-+ set_scoop_jc_gpio(SCP_JC_CARD_LIMIT_SEL); // non-limited
-+ tosa_jc_card_limit_sel = 0;
-+ }else if( !sharpsl_jacket_batt_exist ){
-+ reset_scoop_jc_gpio(SCP_JC_CARD_LIMIT_SEL); // limited
-+ tosa_jc_card_limit_sel = 1;
-+ }else if(!sharpsl_main_bk_flag){
-+ //default.
-+ set_scoop_jc_gpio(SCP_JC_CARD_LIMIT_SEL); // non-limited
-+ tosa_jc_card_limit_sel = 0;
-+ }else if (sharpsl_jacket_battery == SHARPSL_BATTERY_STATUS_VERYLOW ||
-+ sharpsl_jacket_battery == SHARPSL_BATTERY_STATUS_CRITICAL){
-+ reset_scoop_jc_gpio(SCP_JC_CARD_LIMIT_SEL); // limited
-+ tosa_jc_card_limit_sel = 1;
-+ }else {
-+ set_scoop_jc_gpio(SCP_JC_CARD_LIMIT_SEL); // non-limited
-+ tosa_jc_card_limit_sel = 0;
-+ }
-+
-+ // if battery is low , backlight driver become to save power.
-+ if ( ( ( sharpsl_main_battery == SHARPSL_BATTERY_STATUS_VERYLOW ) ||
-+ ( sharpsl_main_battery == SHARPSL_BATTERY_STATUS_CRITICAL ) ) &&
-+ ( (sharpsl_main_battery != back_battery_status) || (sharpsl_jacket_battery != back_jacket_battery_status) ) &&
-+ ( sharpsl_main_bk_flag ) &&
-+ ( ( !sharpsl_jacket_batt_exist ) || ( tosa_jc_card_limit_sel ) ) ) {
-+ SHARPSL_LIMIT_CONTRAST(SHARPSL_CAUTION_CONTRAST);
-+ } else if ( (sharpsl_main_battery != back_battery_status) ||
-+ (sharpsl_jacket_battery != back_jacket_battery_status) ) {
-+ SHARPSL_LIMIT_CONTRAST(SHARPSL_RESET_CONTRAST);
-+ }
-+
-+ back_battery_status = sharpsl_main_battery;
-+ back_jacket_battery_status = sharpsl_jacket_battery;
-+ back_bu_battery_status = sharpsl_bu_battery;
-+
-+ // good or ac in --> GOOD_COUNT
-+ // low or very low --> NOGOOD_COUNT
-+ if ( ( sharpsl_main_battery == SHARPSL_BATTERY_STATUS_HIGH ) || ( sharpsl_ac_status == APM_AC_ONLINE ) )
-+ MainCnt = SHARPSL_MAIN_GOOD_COUNT;
-+ else
-+ MainCnt = SHARPSL_MAIN_NOGOOD_COUNT;
-+ DPRINTK("[BATT] MainCnt = %d\n",MainCnt);
-+
-+ if(tosa_jacket_status_change && sharpsl_main_bk_flag){
-+ int battlow = 1;
-+
-+ tosa_jacket_status_change = 0; // status clear.
-+
-+ // main battery low irq control.
-+ if(tosa_check_main_batt_fatal()){
-+ DPRINTK2("[BATT] IRQ: Disable BAT0\n");
-+ disable_irq(IRQ_GPIO_BAT0_LOW);
-+ }else{
-+ DPRINTK2("[BATT] IRQ: Enable BAT0\n");
-+ enable_irq(IRQ_GPIO_BAT0_LOW);
-+ battlow = 0;
-+ }
-+
-+ // jacket battery low irq control.
-+ if(sharpsl_jacket_batt_exist){
-+ if(tosa_check_jacket_batt_fatal()){
-+ // jacket battery is fatal.
-+ DPRINTK2("[BATT] IRQ: Disable BAT1 (jacket battery fatal)\n");
-+ disable_irq(IRQ_GPIO_BAT1_LOW);
-+ }else{
-+ DPRINTK2("[BATT] IRQ: Enable BAT1 (status change)\n");
-+ enable_irq(IRQ_GPIO_BAT1_LOW);
-+ battlow = 0;
-+ }
-+ }else{
-+ // no jacket.
-+ DPRINTK2("[BATT] IRQ: Disable BAT1 (no jacket battery)\n");
-+ disable_irq(IRQ_GPIO_BAT1_LOW);
-+ }
-+ if(battlow)
-+ tosa_request_off();
-+ }
-+
-+#ifdef TOSA_BATTERY_FAILSAFE_LOWBAT
-+ // check critical ( check fatal )
-+ if ( ( sharpsl_main_battery == SHARPSL_BATTERY_STATUS_CRITICAL ) &&
-+ is_enabled_off && sharpsl_main_bk_flag ) {
-+
-+ if( !sharpsl_jacket_batt_exist ){
-+ tosa_request_off();
-+ DPRINTK2("[BATT] <* Fail-Safe *> Fatal Off by ADC \n");
-+ }else{
-+ if( sharpsl_jacket_battery == SHARPSL_BATTERY_STATUS_CRITICAL ){
-+ tosa_request_off();
-+ DPRINTK2("[BATT] <* Fail-Safe *>Fatal Off by ADC \n");
-+ }
-+ }
-+ }
-+#endif
-+
-+ DPRINTK("[BATT] LOWBAT0=%d\n",tosa_check_main_batt_fatal());
-+ DPRINTK("[BATT] LOWBAT1=%d\n",tosa_check_jacket_batt_fatal());
-+
-+#ifdef TOSA_BATTERY_FAILSAFE
-+ if( sharpsl_jacket_batt_exist ){
-+ // jacket battery exists. (main battery always exists.)
-+ if( sharpsl_main_bk_flag && is_enabled_off &&
-+ tosa_check_main_batt_fatal() && tosa_check_jacket_batt_fatal() ){
-+
-+ tosa_request_off();
-+ DPRINTK("Fatal Off by DETECTOR\n");
-+ }
-+ }else{
-+ if( sharpsl_main_bk_flag && is_enabled_off &&
-+ ( ( GPLR(GPIO_BAT0_LOW) & GPIO_bit(GPIO_BAT0_LOW) ) == 0 ) ){
-+ tosa_request_off();
-+ DPRINTK("Fatal Off by DETECTOR\n");
-+ }
-+ }
-+#endif
-+
-+ if(TC6393_SYS_REG(TC6393_SYS_GPODSR1) & TC6393_CHARGE_OFF){
-+ CHARGE_0_ON();
-+ }else{
-+ }
-+
-+#ifdef TOSA_FOR_ENGLISH
-+ if(IS_ENGLISH_MODEL() && sharpsl_main_bk_flag){
-+
-+ int detected_charge_full = 0;
-+
-+ // In other than the Japanese version,
-+ // the following processings are performed.
-+ // Charging LED is switched off on a full charge.
-+
-+ switch(GET_CHARGE_FULL_STATE()){
-+ case DISCONNECT_AC:
-+ DPRINTK5("DISCONNECT_AC\n");
-+ if( sharpsl_ac_status == APM_AC_ONLINE ){
-+ DPRINTK5("* (%d) ac in !\n",tosa_charge_full_state);
-+ SET_CHARGE_FULL_STATE(CONNECT_AC);
-+ }
-+ break;
-+ case CONNECT_AC:
-+ DPRINTK5("CONNECT_AC\n");
-+ if( sharpsl_ac_status == APM_AC_OFFLINE ){
-+ DPRINTK5("* (%d) ac out !\n",tosa_charge_full_state);
-+ SET_CHARGE_FULL_STATE(DISCONNECT_AC);
-+ break;
-+ }
-+
-+ DPRINTK5("* (%d) ac in !\n",tosa_charge_full_state);
-+ DPRINTK5("* TC6393_SYS_GPOOECR1 = %08x\n",TC6393_SYS_REG(TC6393_SYS_GPOOECR1));
-+ DPRINTK5("* TC6393_SYS_GPODSR1 = %08x\n",TC6393_SYS_REG(TC6393_SYS_GPODSR1));
-+ tosa_decide_charge_full_counter = 0;
-+ detected_charge_full = SHARPSL_MAIN_BATT_FULL;
-+ DPRINTK5("* (%d) main charge full = %d!\n",tosa_charge_full_state,detected_charge_full);
-+ if( detected_charge_full && sharpsl_jacket_exist && sharpsl_jacket_batt_exist ){
-+ detected_charge_full = SHARPSL_JACKET_BATT_FULL;
-+ DPRINTK5("* (%d) jacket charge full = %d!\n",tosa_charge_full_state,detected_charge_full);
-+ }
-+ if( detected_charge_full ){
-+ SET_CHARGE_FULL_STATE(DETECT_CHARGE_FULL);
-+ tosa_decide_charge_full_counter = jiffies;
-+ break;
-+ }
-+ break;
-+ case DETECT_CHARGE_FULL:
-+ DPRINTK5("DETECT_CHARGE_FULL !\n",tosa_charge_full_state);
-+ DPRINTK5("* TC6393_SYS_GPOOECR1 = %08x\n",TC6393_SYS_REG(TC6393_SYS_GPOOECR1));
-+ DPRINTK5("* TC6393_SYS_GPODSR1 = %08x\n",TC6393_SYS_REG(TC6393_SYS_GPODSR1));
-+ if( sharpsl_ac_status == APM_AC_OFFLINE ){
-+ DPRINTK5("* (%d) ac out !\n",tosa_charge_full_state);
-+ SET_CHARGE_FULL_STATE(DISCONNECT_AC);
-+ break;
-+ }
-+ DPRINTK5("* (%d) c = %d \n",tosa_charge_full_state,(jiffies - tosa_decide_charge_full_counter));
-+ detected_charge_full = SHARPSL_MAIN_BATT_FULL;
-+ DPRINTK5("* (%d) main charge full = %d!\n",tosa_charge_full_state,detected_charge_full);
-+ if( detected_charge_full && sharpsl_jacket_exist && sharpsl_jacket_batt_exist ){
-+ detected_charge_full = SHARPSL_JACKET_BATT_FULL;
-+ DPRINTK5("* (%d) jacket charge full = %d!\n",tosa_charge_full_state,detected_charge_full);
-+ }
-+ if( !detected_charge_full ){
-+ DPRINTK5("* (%d) canceled charge full !\n",tosa_charge_full_state);
-+ SET_CHARGE_FULL_STATE(CONNECT_AC);
-+ break;
-+ }
-+
-+ if((jiffies - tosa_decide_charge_full_counter) > TOSA_DECIDE_CHARGE_FULL_COUNTER){
-+ DPRINTK5("* (%d) fixed charge full !\n",tosa_charge_full_state);
-+ CHARGE_LED_OFF();
-+ SET_CHARGE_FULL_STATE(DECIDE_CHARGE_FULL);
-+ sharpsl_change_battery_status = 1;
-+ wake_up_interruptible(&battery_waitqueue);
-+ break;
-+ }
-+ break;
-+ case DECIDE_CHARGE_FULL:
-+ DPRINTK5("DECIDE_CHARGE_FULL !\n",tosa_charge_full_state);
-+ if( sharpsl_ac_status == APM_AC_OFFLINE ){
-+ DPRINTK5("* (%d)ac out !\n",tosa_charge_full_state);
-+ CHARGE_LED_OFF();
-+ SET_CHARGE_FULL_STATE(DISCONNECT_AC);
-+ break;
-+ }
-+ detected_charge_full = SHARPSL_MAIN_BATT_FULL;
-+ DPRINTK5("* (%d) main charge full = %d!\n",tosa_charge_full_state,detected_charge_full);
-+ if( detected_charge_full && sharpsl_jacket_exist && sharpsl_jacket_batt_exist ){
-+ detected_charge_full = SHARPSL_JACKET_BATT_FULL;
-+ DPRINTK5("* (%d) jacket charge full = %d!\n",tosa_charge_full_state,detected_charge_full);
-+ }
-+ if( !detected_charge_full ){
-+ DPRINTK5("* (%d)canceled charge full !\n",tosa_charge_full_state);
-+ CHARGE_LED_ON();
-+ SET_CHARGE_FULL_STATE(CONNECT_AC);
-+ sharpsl_change_battery_status = 1;
-+ wake_up_interruptible(&battery_waitqueue);
-+ break;
-+ }
-+ break;
-+ default:
-+ DPRINTK5("* (%d)error state !\n",tosa_charge_full_state);
-+ SET_CHARGE_FULL_STATE(DISCONNECT_AC);
-+ sharpsl_change_battery_status = 1;
-+ wake_up_interruptible(&battery_waitqueue);
-+ break;
-+ }
-+ }
-+#endif // TOSA_FOR_ENGLISH
-+ return 0;
-+}
-+
-+
-+static int tosa_battery_thread(void* unused)
-+{
-+ strcpy(current->comm, "sharpsl_bat");
-+ sharpsl_check_time = SHARPSL_BATCHK_TIME;
-+
-+ while(1) {
-+ interruptible_sleep_on_timeout((wait_queue_head_t*)&battery_queue, sharpsl_check_time );
-+
-+ // AC adapter is inserted , but charging not start.
-+ // SW can not confirm inserted AC adapter, so kick !
-+ if ( ( charge_status == 0 ) && ( sharpsl_ac_status == APM_AC_ONLINE )) {
-+ wake_up(&charge_on_queue);
-+ } else if ( ( charge_status == 1 ) && ( sharpsl_ac_status == APM_AC_OFFLINE )) {
-+ wake_up(&charge_off_queue);
-+ }
-+
-+ /* check battery ! */
-+ tosa_battery_thread_main();
-+ }
-+ return 0;
-+}
-+
-+
-+
-+// TOSA-FUNCTIONS
-+
-+static void tosa_charge_on_off(int nsel,int on)
-+{
-+ switch(nsel) {
-+ case SEL_MAIN:
-+ TC6393_SYS_REG(TC6393_SYS_GPOOECR1) |= TC6393_CHARGE_OFF;
-+ if(on){
-+ if((TC6393_SYS_REG(TC6393_SYS_GPODSR1) & TC6393_CHARGE_OFF) != TC6393_CHARGE_OFF){
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) |= TC6393_CHARGE_OFF;
-+ mdelay(1);
-+ }
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) &= ~TC6393_CHARGE_OFF;
-+ mdelay(1);
-+ }else{
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) |= TC6393_CHARGE_OFF;
-+ }
-+ break;
-+ case SEL_JACKET:
-+ TC6393_SYS_REG(TC6393_SYS_GPOOECR1) |= TC6393_CHARGE_OFF_JC;
-+ if(on){
-+ if((TC6393_SYS_REG(TC6393_SYS_GPODSR1) & TC6393_CHARGE_OFF_JC) != TC6393_CHARGE_OFF_JC){
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) |= TC6393_CHARGE_OFF_JC;
-+ mdelay(1);
-+ }
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) &= ~TC6393_CHARGE_OFF_JC;
-+ mdelay(1);
-+ }else{
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) |= TC6393_CHARGE_OFF_JC;
-+ }
-+ break;
-+ default:
-+ printk("%s: parameter error !\n",__func__);
-+ break;
-+ }
-+}
-+
-+//
-+// 0:main 1:jacket 2:backup
-+//
-+static int tosa_get_sel_battery(int nsel) //[Fix]
-+{
-+ int i = 0;
-+ BATTERY_THRESH *thresh;
-+ int voltage;
-+
-+ while(1) {
-+ voltage = tosa_read_battery(nsel);
-+ if ( voltage > 0 ) break;
-+ if ( i++ > 5 ) {
-+ switch(nsel) {
-+ case SEL_MAIN:
-+ voltage = sharpsl_main_battery_thresh_fl[0].voltage + TOSA_BATTERY_AD_OFFSET;
-+ break;
-+ case SEL_JACKET:
-+ voltage = sharpsl_jacket_battery_thresh_fl[0].voltage + TOSA_BATTERY_AD_OFFSET;
-+ break;
-+ case SEL_BU:
-+ voltage = sharpsl_bu_battery_thresh_fl[0].voltage + TOSA_BATTERY_AD_OFFSET;
-+ break;
-+ }
-+ printk("please fix me! can not read battery[%d] \n",nsel);
-+ break;
-+ }
-+ }
-+
-+ voltage = tosa_cnv_battery(nsel,voltage);
-+ thresh = tosa_get_sel_level(nsel,voltage);
-+
-+ switch(nsel) {
-+ case SEL_MAIN:
-+ if ( sharpsl_main_bk_flag == 0 ) {
-+ return sharpsl_main_battery;
-+ }
-+ sharpsl_main_battery = thresh->status;
-+ sharpsl_main_battery_percentage = thresh->percentage;
-+ break;
-+ case SEL_JACKET:
-+ if ( sharpsl_main_bk_flag == 0 ) {
-+ return sharpsl_jacket_battery;
-+ }
-+ sharpsl_jacket_battery = thresh->status;
-+ sharpsl_jacket_battery_percentage = thresh->percentage;
-+ break;
-+ case SEL_BU:
-+ sharpsl_bu_battery = thresh->status;
-+ sharpsl_bu_battery_percentage = thresh->percentage;
-+ break;
-+ }
-+
-+ // Value is kept until it will operate OFF and AC, once low AD comes out.
-+ switch(nsel){
-+ case SEL_MAIN:
-+ if ( sharpsl_main_battery_percentage < sharpsl_main_percent_bk ) {
-+ sharpsl_main_status_bk = sharpsl_main_battery;
-+ sharpsl_main_percent_bk = sharpsl_main_battery_percentage;
-+
-+ sharpsl_change_battery_status = 1;
-+ wake_up_interruptible(&battery_waitqueue);
-+ } else {
-+ sharpsl_main_battery = sharpsl_main_status_bk;
-+ sharpsl_main_battery_percentage = sharpsl_main_percent_bk;
-+ }
-+ return sharpsl_main_battery;
-+ break;
-+ case SEL_JACKET:
-+ if ( sharpsl_jacket_battery_percentage < sharpsl_jacket_percent_bk) {
-+ sharpsl_jacket_status_bk = sharpsl_jacket_battery;
-+ sharpsl_jacket_percent_bk = sharpsl_jacket_battery_percentage;
-+
-+ sharpsl_change_battery_status = 1;
-+ wake_up_interruptible(&battery_waitqueue);
-+ } else {
-+ sharpsl_jacket_battery = sharpsl_jacket_status_bk;
-+ sharpsl_jacket_battery_percentage = sharpsl_jacket_percent_bk;
-+ }
-+ return sharpsl_jacket_battery;
-+ break;
-+ case SEL_BU:
-+ if ( sharpsl_bu_battery_percentage < sharpsl_bu_percent_bk ) {
-+ sharpsl_bu_status_bk = sharpsl_bu_battery;
-+ sharpsl_bu_percent_bk = sharpsl_bu_battery_percentage;
-+
-+ sharpsl_change_battery_status = 1;
-+ wake_up_interruptible(&battery_waitqueue);
-+ } else {
-+ sharpsl_bu_battery = sharpsl_bu_status_bk;
-+ sharpsl_bu_battery_percentage = sharpsl_bu_percent_bk;
-+ }
-+ return sharpsl_bu_battery;
-+ break;
-+ }
-+ return sharpsl_main_battery;
-+}
-+
-+// 0:main 1:jacket 2:backup
-+static int tosa_read_battery(int nsel) //[Fix]
-+{
-+ int voltage = -1;
-+
-+ switch (nsel){
-+ case SEL_MAIN:
-+ TC6393_SYS_REG(TC6393_SYS_GPOOECR1) |= (TC6393_BAT0_V_ON | TC6393_BAT1_V_ON | TC6393_BAT_SW_ON);
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) &= ~(TC6393_BAT1_V_ON | TC6393_BAT_SW_ON);
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) |= TC6393_BAT0_V_ON;
-+ mdelay(TOSA_BATTERY_READ_WAIT_TIME);
-+ voltage = tosa_get_dac_value(BATT_V);
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) &= ~(TC6393_BAT0_V_ON | TC6393_BAT1_V_ON | TC6393_BAT_SW_ON);
-+ DPRINTK("[BATT] main voltage = %d \n",voltage);
-+ break;
-+ case SEL_JACKET:
-+ TC6393_SYS_REG(TC6393_SYS_GPOOECR1) |= (TC6393_BAT0_V_ON | TC6393_BAT1_V_ON | TC6393_BAT_SW_ON);
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) &= ~(TC6393_BAT0_V_ON | TC6393_BAT_SW_ON);
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) |= TC6393_BAT1_V_ON;
-+ mdelay(TOSA_BATTERY_READ_WAIT_TIME);
-+ voltage = tosa_get_dac_value(BATT_V);
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) &= ~(TC6393_BAT0_V_ON | TC6393_BAT1_V_ON | TC6393_BAT_SW_ON);
-+ DPRINTK("[BATT] jacket voltage = %d \n",voltage);
-+ break;
-+ case SEL_BU:
-+ TC6393_SYS_REG(TC6393_SYS_GPOOECR1) |= (TC6393_BU_CHRG_ON);
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) |= (TC6393_BU_CHRG_ON);
-+ mdelay(TOSA_BATTERY_READ_WAIT_TIME);
-+ voltage = tosa_get_dac_value(BU_V);
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) &= ~TC6393_BU_CHRG_ON;
-+ DPRINTK("[BATT] backup voltage = %d \n",voltage);
-+ break;
-+ default:
-+ printk("%s: parameter error !\n",__func__);
-+ break;
-+ }
-+ return voltage;
-+}
-+
-+static int tosa_read_temp(int nsel) //[Fix]
-+{
-+ int temp = -1;
-+
-+ switch (nsel){
-+ case SEL_MAIN:
-+ TC6393_SYS_REG(TC6393_SYS_GPOOECR1) |= TC6393_BAT0_TH_ON | TC6393_BAT1_TH_ON;
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) &= ~TC6393_BAT0_TH_ON;
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) |= TC6393_BAT1_TH_ON;
-+ mdelay(TOSA_TEMP_READ_WAIT_TIME);
-+ temp = tosa_get_dac_value(BATT_TH);
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) &= ~(TC6393_BAT0_TH_ON|TC6393_BAT1_TH_ON);
-+ break;
-+ case SEL_JACKET:
-+ TC6393_SYS_REG(TC6393_SYS_GPOOECR1) |= TC6393_BAT0_TH_ON | TC6393_BAT1_TH_ON;
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) &= ~TC6393_BAT1_TH_ON;
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) |= TC6393_BAT0_TH_ON;
-+ mdelay(TOSA_TEMP_READ_WAIT_TIME);
-+ temp = tosa_get_dac_value(BATT_TH);
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) &= ~(TC6393_BAT0_TH_ON|TC6393_BAT1_TH_ON);
-+ break;
-+ default:
-+ printk("%s: parameter error !\n",__func__);
-+ break;
-+ }
-+ return temp;
-+}
-+
-+static int tosa_read_battery_avg(int nsel)
-+{
-+ int temp,i;
-+ int buff[5];
-+
-+ for(i=0;i<5;i++) {
-+ buff[i] = tosa_read_battery(nsel);
-+ }
-+ temp = get_select_val(buff);
-+ return temp;
-+}
-+
-+static int tosa_read_temp_avg(int nsel) //[Fix]
-+{
-+ int temp,i;
-+ int buff[5];
-+
-+ for(i=0;i<5;i++) {
-+ buff[i] = tosa_read_temp(nsel);
-+ }
-+ temp = get_select_val(buff);
-+ return temp;
-+}
-+
-+static int tosa_check_battery_error(int nsel,int thresh)
-+{
-+ int temp;
-+
-+ if ( in_interrupt() ) {
-+ printk("%s: call in interrupt.\n",__func__);
-+ return 1;
-+ }
-+ temp = tosa_read_battery_avg(nsel);
-+
-+ if ( temp < thresh ) return 1; // (1) battery error!
-+
-+ return 0; // (0) battery ok!
-+}
-+
-+static int tosa_check_battery_exist(int nsel,int thresh) //[Fix]
-+{
-+ int temp;
-+
-+ if ( in_interrupt() ) {
-+ printk("%s: call in interrupt.<nsel:%d>\n",__func__,nsel);
-+ return 1;
-+ }
-+ temp = tosa_read_temp_avg(nsel);
-+ DPRINTK3("[BATT] batt exist check <nsel = %d, temp = %d>\n",nsel,temp);
-+
-+ if ( temp > thresh ) return 1; // (1) not exist
-+
-+ return 0; // (0) exist
-+}
-+
-+static int tosa_check_main_battery_error(void)
-+{
-+ // 0: not error , 1: error
-+ return tosa_check_battery_error(SEL_MAIN, TOSA_MAIN_BATTERY_ERR_THRESH);
-+}
-+
-+static int tosa_check_jacket_battery_error(void)
-+{
-+ // 0: not error , 1: error
-+ return tosa_check_battery_error(SEL_JACKET, TOSA_JACKET_BATTERY_ERR_THRESH);
-+}
-+
-+static int tosa_check_main_battery_not_exist(void) //[Fix]
-+{
-+#ifdef TOSA_BATTERY_SKIP
-+ return 0;
-+#endif //TOSA_BATTERY_SKIP
-+
-+ // 0: exist , 1: not exist
-+ return tosa_check_battery_exist(SEL_MAIN, TOSA_MAIN_BATTERY_EXIST_THRESH);
-+}
-+
-+static int tosa_check_jacket_battery_not_exist(void) //[Fix]
-+{
-+ // 0: exist , 1: not exist
-+ return tosa_check_battery_exist(SEL_JACKET, TOSA_JACKET_BATTERY_EXIST_THRESH);
-+}
-+
-+static int tosa_read_main_battery(void)
-+{
-+ return tosa_get_sel_battery(SEL_MAIN);
-+}
-+
-+static int tosa_read_jacket_battery(void)
-+{
-+ return tosa_get_sel_battery(SEL_JACKET);
-+}
-+
-+static int tosa_read_backup_battery(void)
-+{
-+ return tosa_get_sel_battery(SEL_BU);
-+}
-+
-+static int tosa_check_main_batt_fatal(void)
-+{
-+ int i;
-+ for(i=0;i<2;i++){
-+ udelay(1);
-+ if(!SHARPSL_MAIN_BATT_FATAL) return 0;
-+ }
-+ return 1; // (1) fatal
-+}
-+
-+static int tosa_check_jacket_batt_fatal(void)
-+{
-+ int i;
-+ for(i=0;i<2;i++){
-+ udelay(1);
-+ if(!SHARPSL_JACKET_BATT_FATAL) return 0;
-+ }
-+ return 1; // (1) fatal
-+}
-+
-+static void tosa_charge_start(void) //[Fix]
-+{
-+ if ( tosa_check_main_battery_not_exist() ) {
-+
-+ /* error led on */
-+ CHARGE_LED_ERR();
-+
-+ /* charge status flag reset */
-+ charge_status = 0;
-+
-+ } else {
-+
-+ /* led on */
-+ CHARGE_LED_OFF();
-+ CHARGE_LED_ON();
-+
-+ /* charge status flag set */
-+ charge_status = 1;
-+ }
-+ sharpsl_change_battery_status = 1;
-+ wake_up_interruptible(&battery_waitqueue);
-+}
-+
-+static void tosa_charge_stop(void) //[Fix]
-+{
-+ if ( tosa_check_main_battery_not_exist() ){
-+
-+ /* error led on */
-+ CHARGE_LED_ERR();
-+
-+ /* charge status flag reset */
-+ charge_status = 0;
-+
-+ }else{
-+ /* led off */
-+ CHARGE_LED_OFF();
-+
-+ /* charge status flag reset */
-+ charge_status = 0;
-+ }
-+ sharpsl_change_battery_status = 1;
-+ wake_up_interruptible(&battery_waitqueue);
-+}
-+
-+
-+static void tosa_reset_battery_info(void)
-+{
-+ sharpsl_main_status_bk = SHARPSL_BATTERY_STATUS_HIGH;
-+ sharpsl_main_percent_bk = 100;
-+ sharpsl_jacket_status_bk = SHARPSL_BATTERY_STATUS_HIGH;
-+ sharpsl_jacket_percent_bk = 100;
-+ sharpsl_bu_status_bk = SHARPSL_BATTERY_STATUS_HIGH;
-+ sharpsl_bu_percent_bk = 100;
-+
-+ sharpsl_ad_index_main = 0;
-+ sharpsl_ad_index_jacket = 0;
-+ sharpsl_ad_index_bu = 0;
-+}
-+
-+static int tosa_ac_line_status(int m_sec)
-+{
-+ int ac_status=(( GPLR(GPIO_AC_IN) & GPIO_bit(GPIO_AC_IN) ) ? APM_AC_OFFLINE : APM_AC_ONLINE);
-+ int counter=0;
-+ if(m_sec == 0) return ac_status;
-+ while(1){
-+ mdelay(1);
-+ if(ac_status == (( GPLR(GPIO_AC_IN) & GPIO_bit(GPIO_AC_IN) ) ? APM_AC_OFFLINE : APM_AC_ONLINE)){
-+ counter++;
-+ }else{
-+ ac_status = (( GPLR(GPIO_AC_IN) & GPIO_bit(GPIO_AC_IN) ) ? APM_AC_OFFLINE : APM_AC_ONLINE);
-+ counter=0;
-+ }
-+ if(counter>m_sec) break;
-+ }
-+ return ac_status;
-+}
-+
-+//////////////////////
-+
-+void sharpsl_kick_battery_check_queue(void)
-+{
-+ MainCntWk = MainCnt + 1;
-+ wake_up(&battery_queue);
-+}
-+
-+void sharpsl_kick_jacket_check_queue(void)
-+{
-+ wake_up_interruptible(&jacket_chk_queue);
-+}
-+
-+void sharpsl_charge_start(void)
-+{
-+ tosa_charge_start();
-+}
-+
-+int sharpsl_get_main_battery(void)
-+{
-+ return tosa_read_main_battery();
-+}
-+
-+void sharpsl_request_dac_init(void)
-+{
-+ tosa_dac_init = 0;
-+}
-+
-+static int tosa_charge_on(void* unused)
-+{
-+
-+ // daemonize();
-+ strcpy(current->comm, "battchrgon");
-+ sigfillset(&current->blocked);
-+
-+ while(1) {
-+ interruptible_sleep_on(&charge_on_queue);
-+
-+ if (SHARPSL_AC_LINE_STATUS == APM_AC_OFFLINE) continue;
-+
-+ // flag clear
-+ tosa_reset_battery_info();
-+
-+ is_ac_adaptor = 1;
-+
-+ tosa_charge_start();
-+ }
-+ return 0;
-+}
-+
-+
-+static int tosa_charge_off(void* unused)
-+{
-+ // daemonize();
-+ strcpy(current->comm, "battchrgoff");
-+ sigfillset(&current->blocked);
-+
-+ while(1) {
-+ interruptible_sleep_on(&charge_off_queue);
-+
-+ if (SHARPSL_AC_LINE_STATUS == APM_AC_ONLINE) continue;
-+
-+ tosa_reset_battery_info();
-+
-+ is_ac_adaptor = 0;
-+
-+ tosa_charge_stop();
-+ }
-+ return 0;
-+}
-+
-+static int tosa_fatal_check(void* unused)
-+{
-+ int is_fatal;
-+
-+ // daemonize();
-+ strcpy(current->comm, "fatalchk");
-+ sigfillset(&current->blocked);
-+
-+ while(1) {
-+ interruptible_sleep_on(&fatal_chk_queue);
-+
-+ is_fatal=0;
-+
-+ DPRINTK2("[BATT] BAT0LOW OR BAT1LOW IRQ \n");
-+ if(tosa_check_main_batt_fatal()){
-+ disable_irq(IRQ_GPIO_BAT0_LOW);
-+ DPRINTK2("[BATT] IRQ: Disable BAT0\n");
-+ is_fatal = 1;
-+ }
-+ if(sharpsl_jacket_exist && sharpsl_jacket_batt_exist){
-+ if(tosa_check_jacket_batt_fatal()){
-+ disable_irq(IRQ_GPIO_BAT1_LOW);
-+ DPRINTK2("[BATT] IRQ: Disable BAT1\n");
-+ }else{
-+ is_fatal = 0;
-+ }
-+ }
-+
-+ if(is_fatal){
-+ DPRINTK2("[BATT] FATAL OFF !!!\n");
-+ tosa_request_off();
-+ }else{
-+ DPRINTK2("[BATT] FATAL OFF CANCEL !\n");
-+ }
-+ }
-+ return 0;
-+}
-+
-+static int tosa_jacket_check(void* unused)
-+{
-+ int sts;
-+
-+ // daemonize();
-+ strcpy(current->comm, "jacketchk");
-+ sigfillset(&current->blocked);
-+
-+ while(1) {
-+ interruptible_sleep_on(&jacket_chk_queue);
-+
-+ sts = tosa_get_jacket_status();
-+ if (sts == 0){
-+ mod_timer(&jacket_kick_timer,
-+ jiffies + HZ / 100 * TOSA_JC_CHECK_WAIT_TIME);
-+ }else{
-+ sharpsl_kick_battery_check_queue();
-+ }
-+ }
-+ return 0;
-+}
-+
-+// card error ( System must eject the card )
-+// RET = 0:no error, bit0:pcmcia slot0, bit1:pcmcia slot1, bit2:sdslot0
-+int sharpsl_get_cardslot_error(void)
-+{
-+ int cardslot_err = tosa_cardslot_error;
-+ //printk("%s:\n",__func__);
-+ tosa_cardslot_error = 0; // clear
-+ return cardslot_err;
-+}
-+
-+/*** Int ***********************************************************************/
-+
-+static void tosa_jacket_kick_timer(void)
-+{
-+ sharpsl_kick_jacket_check_queue();
-+}
-+
-+static void sharpsl_ac_kick_timer(void)
-+{
-+ int level = tosa_ac_line_status(0);
-+ int match = 0;
-+ int err = 0;
-+
-+ while(1) {
-+ if ( level == tosa_ac_line_status(0) ) {
-+ match++;
-+ } else {
-+ level = tosa_ac_line_status(0);
-+ match = 0;
-+ err++;
-+ }
-+ if ( match > 1 ) break;
-+ if ( err > 50 ) {
-+ // if ac port is not stable , so use last port data.
-+ level = tosa_ac_line_status(0);
-+ printk("err : ac port\n");
-+ break;
-+ }
-+ }
-+
-+#if 1 // Hardware Issue.
-+ if ( charge_status == 1 && level == APM_AC_OFFLINE ){
-+ // AC IN -> OUT
-+ wake_up(&charge_off_queue);
-+ }else if ( charge_status == 0 && level == APM_AC_ONLINE ){
-+ // AC OUT -> IN
-+ wake_up(&charge_on_queue);
-+ }
-+#else
-+ if ( level == APM_AC_OFFLINE ) {
-+ /* High->Low : desert */
-+ wake_up(&charge_off_queue);
-+ } else {
-+ /* Low->High : assert */
-+ wake_up(&charge_on_queue);
-+ }
-+#endif
-+
-+ sharpsl_kick_battery_check_queue();
-+}
-+
-+static void tosa_jacket_interrupt(int irq, void *dummy, struct pt_regs *fp)
-+{
-+ mod_timer(&jacket_kick_timer, jiffies + HZ / 100);
-+}
-+
-+static void tosa_ac_interrupt(int irq, void *dummy, struct pt_regs *fp)
-+{
-+ mod_timer(&ac_kick_timer, jiffies + HZ / 100);
-+}
-+
-+static void tosa_main_batt_fatal_interrupt(int irq, void *dummy, struct pt_regs *fp)
-+{
-+ wake_up_interruptible(&fatal_chk_queue);
-+}
-+
-+static void tosa_jacket_batt_fatal_interrupt(int irq, void *dummy, struct pt_regs *fp)
-+{
-+ wake_up_interruptible(&fatal_chk_queue);
-+}
-+
-+/*** get adc *********************************************************************/
-+
-+static int tosa_cnv_battery(int nsel,int ad)
-+{
-+ int ad_val = 0;
-+ int ret = -1,i;
-+
-+ switch(nsel){
-+ case SEL_MAIN:
-+ if ( sharpsl_main_battery != SHARPSL_BATTERY_STATUS_HIGH ) {
-+ sharpsl_ad_index_main = 0;
-+ return ad;
-+ }
-+ sharpsl_ad_main[sharpsl_ad_index_main] = ad;
-+ sharpsl_ad_index_main++;
-+ if ( sharpsl_ad_index_main >= SHARPSL_CNV_VALUE_NUM ) {
-+ for(i=0;i<(SHARPSL_CNV_VALUE_NUM-1);i++)
-+ sharpsl_ad_main[i] = sharpsl_ad_main[i+1];
-+ sharpsl_ad_index_main = SHARPSL_CNV_VALUE_NUM -1;
-+ }
-+ for(i=0;i<sharpsl_ad_index_main;i++)
-+ ad_val += sharpsl_ad_main[i];
-+ ret = ( ad_val / sharpsl_ad_index_main );
-+ break;
-+ case SEL_JACKET:
-+ if ( sharpsl_jacket_battery != SHARPSL_BATTERY_STATUS_HIGH ) {
-+ sharpsl_ad_index_jacket = 0;
-+ return ad;
-+ }
-+ sharpsl_ad_jacket[sharpsl_ad_index_jacket] = ad;
-+ sharpsl_ad_index_jacket++;
-+ if ( sharpsl_ad_index_jacket >= SHARPSL_CNV_VALUE_NUM ) {
-+ for(i=0;i<(SHARPSL_CNV_VALUE_NUM-1);i++)
-+ sharpsl_ad_jacket[i] = sharpsl_ad_jacket[i+1];
-+ sharpsl_ad_index_jacket = SHARPSL_CNV_VALUE_NUM -1;
-+ }
-+ for(i=0;i<sharpsl_ad_index_jacket;i++)
-+ ad_val += sharpsl_ad_jacket[i];
-+ ret = ( ad_val / sharpsl_ad_index_jacket );
-+ break;
-+ case SEL_BU:
-+ if ( sharpsl_bu_battery != SHARPSL_BATTERY_STATUS_HIGH ) {
-+ sharpsl_ad_index_bu = 0;
-+ return ad;
-+ }
-+ sharpsl_ad_bu[sharpsl_ad_index_bu] = ad;
-+ sharpsl_ad_index_bu++;
-+ if ( sharpsl_ad_index_bu >= SHARPSL_CNV_VALUE_NUM ) {
-+ for(i=0;i<(SHARPSL_CNV_VALUE_NUM-1);i++)
-+ sharpsl_ad_bu[i] = sharpsl_ad_bu[i+1];
-+ sharpsl_ad_index_bu = SHARPSL_CNV_VALUE_NUM -1;
-+ }
-+ for(i=0;i<sharpsl_ad_index_bu;i++)
-+ ad_val += sharpsl_ad_bu[i];
-+ ret = ( ad_val / sharpsl_ad_index_bu );
-+ break;
-+ default:
-+ printk("%s: parameter error !\n",__func__);
-+ break;
-+ }
-+ return ret;
-+}
-+
-+static void tosa_get_all_battery(void) //[Fix]
-+{
-+ MainCntWk++;
-+
-+ if ( MainCntWk > MainCnt ) {
-+
-+ MainCntWk = 0;
-+
-+ // check main battery status.
-+ tosa_read_main_battery();
-+
-+ // check backup battery status.
-+ tosa_read_backup_battery();
-+
-+ if (sharpsl_jacket_exist && sharpsl_jacket_batt_exist){
-+ // jacket exists , and jacket's battery exists.
-+ // check jacket battery status.
-+ tosa_read_jacket_battery();
-+ DPRINTK3("[BATT] jacket-unit is existend, and battery is existent therein.\n");
-+ }else{
-+ if(!sharpsl_jacket_exist){
-+ DPRINTK3("[BATT] jacket-unit is non-existent.\n");
-+ }else{
-+ DPRINTK3("[BATT] jacket-unit is existent, but battery is non-existent therein.\n");
-+ }
-+ }
-+
-+ }else{
-+ DPRINTK("[BATT] MainCntWk = %d\n",MainCntWk);
-+ }
-+}
-+
-+static BATTERY_THRESH *tosa_get_sel_level(int nsel, int Volt )
-+{
-+ int i;
-+ BATTERY_THRESH *thresh;
-+
-+ //DPRINTK(" volt = %d \n",Volt);
-+
-+ switch(nsel){
-+ case SEL_MAIN:
-+ if (counter_step_contrast > 2)
-+ thresh = sharpsl_main_battery_thresh_fl;
-+ else
-+ thresh = sharpsl_main_battery_thresh_nofl;
-+ break;
-+ case SEL_JACKET:
-+ if (counter_step_contrast > 2)
-+ thresh = sharpsl_jacket_battery_thresh_fl;
-+ else
-+ thresh = sharpsl_jacket_battery_thresh_nofl;
-+ break;
-+ case SEL_BU:
-+ if (counter_step_contrast > 2)
-+ thresh = sharpsl_bu_battery_thresh_fl;
-+ else
-+ thresh = sharpsl_bu_battery_thresh_nofl;
-+ break;
-+ default:
-+ printk("%s: parameter error !\n",__func__);
-+ thresh = sharpsl_main_battery_thresh_fl;
-+ break;
-+ }
-+ for (i = 0; thresh[i].voltage > 0; i++) {
-+ if (Volt >= (thresh[i].voltage + TOSA_BATTERY_AD_OFFSET))
-+ return &thresh[i];
-+ }
-+ return &thresh[i];
-+}
-+
-+/*
-+ * Translate Analog signal to Digital data
-+ */
-+static int tosa_get_dac_value(int channel) //[Fix]
-+{
-+ unsigned short indata;
-+ int voltage;
-+
-+
-+ lock_FCS(POWER_MODE_BATTERY, 1);
-+
-+ battery_off_flag = 0;
-+
-+ if (tosa_dac_init == 0){
-+ ac97_write(AC97_TS_REG2, 0xc009);
-+ ac97_write(AC97_TS_REG1, 0x0030);
-+ //ac97_bit_set(AC97_ADITFUNC1, (1<<1));
-+ set_GPIO_mode(GPIO32_SDATA_IN1_AC97_MD);
-+ tosa_dac_init = 1;
-+ }
-+
-+ wm9712_power_mode_ts(WM9712_PWR_TP_CONV);
-+ if ((voltage = ac97_ad_input(channel,&indata)) == 0){
-+ voltage = (int)(indata & 0xfff);
-+ }
-+ wm9712_power_mode_ts(WM9712_PWR_TP_WAIT);
-+
-+#ifdef TOSA_BATTERY_SKIP
-+ voltage = 0xfff; // for TEST
-+#endif //TOSA_BATTERY_SKIP
-+
-+ lock_FCS(POWER_MODE_BATTERY, 0);
-+
-+ if ( battery_off_flag )
-+ voltage = -1;
-+
-+ return voltage;
-+}
-+
-+
-+static int get_select_val(int *val)
-+{
-+ int i,j,k,temp,sum = 0;
-+
-+ // Get MAX
-+ temp = val[0];
-+ j=0;
-+ for(i=1;i<5;i++) {
-+ if ( temp < val[i] ) { temp = val[i]; j = i; }
-+ }
-+
-+ // Get MIN
-+ temp = val[4];
-+ k=4;
-+ for(i=3;i>=0;i--) {
-+ if ( temp > val[i] ) { temp = val[i]; k = i; }
-+ }
-+
-+ for(i=0;i<5;i++) {
-+ if ( i == j || i == k ) continue;
-+ sum += val[i];
-+ }
-+ return ( sum / 3 );
-+}
-+
-+
-+/*** PM *************************************************************************/
-+
-+#ifdef CONFIG_PM
-+static int Sharpsl_battery_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data)
-+{
-+ switch (req) {
-+ case PM_SUSPEND:
-+
-+ disable_irq(IRQ_GPIO_AC_IN);
-+ disable_irq(IRQ_GPIO_JACKET_DETECT);
-+#ifndef TOSA_BATTERY_SKIP
-+ disable_irq(IRQ_GPIO_BAT0_LOW);
-+ disable_irq(IRQ_GPIO_BAT1_LOW);
-+#endif
-+
-+ // flag clear
-+ tosa_reset_battery_info();
-+
-+ tosa_off_main_batt_full = 0;
-+ tosa_off_jacket_batt_full = 0;
-+ tosa_off_check_jacket_req = 0;
-+
-+ if ( !sharpsl_main_bk_flag )
-+ sharpsl_main_battery = SHARPSL_BATTERY_STATUS_HIGH;
-+
-+ battery_off_flag = 1;
-+
-+ CHARGE_LED_OFF();
-+ charge_status = 0;
-+ pass_charge_flag = 0;
-+
-+ apm_wakeup_src_mask |= ( GPIO_bit(GPIO_AC_IN) |
-+ GPIO_bit(GPIO_JACKET_DETECT) );
-+ apm_wakeup_src_mask &= ~( GPIO_bit(GPIO_BAT0_CRG) | GPIO_bit(GPIO_BAT1_CRG) );
-+
-+ // wake up by key
-+ apm_wakeup_src_mask |= GPIO_bit(0);
-+
-+#ifdef TOSA_OFF_CHARGE_FAILSAFE
-+ tosa_charge_full_enable = 0;
-+ tosa_charge_full_counter = 0;
-+ tosa_charge_full_main_batt = 0;
-+ tosa_charge_full_jacket_batt = 0;
-+#endif //TOSA_OFF_CHARGE_FAILSAFE
-+ break;
-+
-+ case PM_RESUME:
-+ is_enabled_off = 1;
-+ MainCntWk = MainCnt + 1; // chk battery
-+ back_battery_status = -1;
-+ back_jacket_battery_status = -1;
-+ back_bu_battery_status = -1;
-+ back_ac_status = -1;
-+ tosa_dac_init = 0;
-+ sharpsl_ad_index_main = 0;
-+ sharpsl_ad_index_jacket = 0;
-+ sharpsl_ad_index_bu = 0;
-+ tosa_off_check_jacket_req = 0;
-+#ifdef TOSA_FOR_ENGLISH
-+ if(IS_ENGLISH_MODEL()){
-+ SET_CHARGE_FULL_STATE(DISCONNECT_AC);
-+ tosa_decide_charge_full_counter = 0;
-+ }
-+#endif // TOSA_FOR_ENGLISH
-+
-+ DPRINTK("[BATT] kick ac check!\n");
-+ // AC insert , so kick the charging
-+ if (SHARPSL_AC_LINE_STATUS != APM_AC_OFFLINE) {
-+ wake_up(&charge_on_queue);
-+ } else {
-+ wake_up(&charge_off_queue);
-+ }
-+
-+ DPRINTK2("[BATT] kick jacket check!\n");
-+ tosa_get_jacket_status_for_on();
-+ tosa_off_jc_card_limit();
-+
-+ CHARGE_0_ON();
-+
-+ DPRINTK("[BATT] kick battery check!\n");
-+ sharpsl_kick_battery_check_queue();
-+
-+ DPRINTK("[BATT] enabled all irq!\n");
-+#ifndef TOSA_BATTERY_SKIP
-+ disable_irq(IRQ_GPIO_BAT1_LOW);
-+ disable_irq(IRQ_GPIO_BAT0_LOW);
-+#endif
-+ enable_irq(IRQ_GPIO_JACKET_DETECT);
-+ enable_irq(IRQ_GPIO_AC_IN);
-+ break;
-+ }
-+ return 0;
-+}
-+#endif
-+
-+/*** check fatal battery ************************************************/
-+// Fatal : 0
-+// OK : 1
-+unsigned short chkFatalBatt(void)
-+{
-+ int volt,thresh_mbat,thresh_jbat;
-+ int charge_value;
-+
-+ DPRINTK("[BATT] check fatal battery\n");
-+
-+ if (SHARPSL_AC_LINE_STATUS != APM_AC_OFFLINE ) {
-+ thresh_mbat = TOSA_MAIN_BATT_FATAL_ACIN_VOLT;
-+ thresh_jbat = TOSA_JACKET_BATT_FATAL_ACIN_VOLT;
-+ }else{
-+ thresh_mbat = TOSA_MAIN_BATT_FATAL_NOACIN_VOLT;
-+ thresh_jbat = TOSA_JACKET_BATT_FATAL_NOACIN_VOLT;
-+ }
-+
-+ charge_value = TC6393_SYS_REG(TC6393_SYS_GPODSR1) & TC6393_CHARGE_OFF; //Main
-+ CHARGE_0_OFF(); //Main
-+ TC6393_SYS_REG(TC6393_SYS_GPOOECR1) |= TC6393_BAT_SW_ON;
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) |= TC6393_BAT_SW_ON;
-+ mdelay(TOSA_DISCHARGE_WAIT_TIME);
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) &= ~TC6393_BAT_SW_ON;
-+
-+ volt = tosa_read_battery_avg(SEL_MAIN);
-+
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) |= charge_value;
-+ charge_value=0;
-+ mdelay(1);
-+
-+ DPRINTK3("[BATT] check batt exist(1)\n");
-+ if(tosa_check_jacket_battery_not_exist()){
-+ if( volt < thresh_mbat ){
-+ DPRINTK("[BATT] main fatal battery (no jacket)\n");
-+ return 0; // MAIN BATTERY FATAL
-+ }
-+ }else{
-+ if( volt < thresh_mbat ){
-+
-+ charge_value = TC6393_SYS_REG(TC6393_SYS_GPODSR1) & TC6393_CHARGE_OFF_JC; //Jacket
-+ CHARGE_1_OFF(); //Jacket
-+ TC6393_SYS_REG(TC6393_SYS_GPOOECR1) |= TC6393_BAT_SW_ON;
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) |= TC6393_BAT_SW_ON;
-+ mdelay(TOSA_DISCHARGE_WAIT_TIME);
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) &= ~TC6393_BAT_SW_ON;
-+
-+ volt = tosa_read_battery_avg(SEL_JACKET);
-+
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) |= charge_value;
-+ mdelay(1);
-+
-+ if( volt < thresh_jbat ){
-+ DPRINTK("[BATT] main & jacket fatal battery\n");
-+ return 0; // MAIN & JACKET BATTERY FATAL
-+ }
-+ }
-+ }
-+ DPRINTK("[BATT] not fatal\n");
-+
-+ return 1; // OK
-+}
-+
-+
-+/*** for suspend hook ***********************************************************/
-+#ifdef CONFIG_PM
-+int sharpsl_off_charge_battery(void)
-+{
-+ if ( tosa_check_main_battery_not_exist() ) {
-+
-+ DPRINTK("No main battery !\n");
-+
-+ // battery error!
-+ CHARGE_LED_ERR_OFF();
-+ CHARGE_LED_ERR();
-+ charge_status = 0; /* charge status flag reset */
-+
-+ // if error is occured , so led is blinking continue...
-+ while(1) {
-+ if (SHARPSL_AC_LINE_STATUS == APM_AC_OFFLINE) break;
-+ }
-+
-+ CHARGE_LED_OFF();
-+ return -1;
-+
-+ } else {
-+
-+ // charge start!
-+ CHARGE_LED_OFF();
-+ CHARGE_LED_ON(); /* led on */
-+ charge_status = 1; /* charge status flag set */
-+
-+ }
-+ return 0;
-+}
-+
-+static void tosa_off_jc_card_limit(void)
-+{
-+ if(SHARPSL_AC_LINE_STATUS != APM_AC_OFFLINE){
-+ // ac-in.
-+ set_scoop_jc_gpio(SCP_JC_CARD_LIMIT_SEL); // non-limited
-+ tosa_jc_card_limit_sel = 0;
-+ }else if(sharpsl_jacket_exist && sharpsl_jacket_batt_exist){
-+ // ac-out, and jacket exist.
-+ int volt = tosa_read_battery_avg(SEL_JACKET);
-+ if(volt > TOSA_JACKET_BATT_FATAL_NOACIN_VOLT){
-+ set_scoop_jc_gpio(SCP_JC_CARD_LIMIT_SEL); // non-limited
-+ tosa_jc_card_limit_sel = 0;
-+ }else{
-+ reset_scoop_jc_gpio(SCP_JC_CARD_LIMIT_SEL); // limited
-+ tosa_jc_card_limit_sel = 1;
-+ }
-+ }else{
-+ reset_scoop_jc_gpio(SCP_JC_CARD_LIMIT_SEL); // limited
-+ tosa_jc_card_limit_sel = 1;
-+ }
-+}
-+
-+int tosa_check_charge_full(int cktime)
-+{
-+ int time;
-+ unsigned int ret;
-+ int is_all_battery_full;
-+ int jacket_state, batt_sw_state;
-+ extern int sharpsl_wakeup_check_charge(void);
-+ time = RCNR;
-+
-+ jacket_state = (GPLR(GPIO_JACKET_DETECT) & GPIO_bit(GPIO_JACKET_DETECT));
-+ batt_sw_state = SHARPSL_BAT_LOCKED_STATUS;
-+
-+#if CHECK_LOG
-+ printk("*** CHG_CHK_START: time=%d(%08x) ***\n",RCNR-gStartTime,RCNR);
-+ printk(" MAIN AD: %08x JACKET AD %08x\n",tosa_read_battery(SEL_MAIN),tosa_read_battery(SEL_JACKET));
-+ printk(" TC6393_SYS_GPODSR1=%x\n",TC6393_SYS_REG(TC6393_SYS_GPODSR1));
-+#endif
-+
-+ if(TC6393_SYS_REG(TC6393_SYS_GPODSR1) & TC6393_CHARGE_OFF_JC /*Jacket*/){
-+ if(sharpsl_jacket_batt_exist){
-+#if CHECK_LOG
-+ printk(" jacket battery charge on !\n");
-+#endif
-+ CHARGE_1_ON();
-+ }
-+#if CHECK_LOG
-+ printk(" TC6393_SYS_GPODSR1=%x\n",TC6393_SYS_REG(TC6393_SYS_GPODSR1));
-+#endif
-+ }
-+
-+#ifdef TOSA_OFF_CHARGE_FAILSAFE
-+ if(!tosa_charge_full_enable){
-+ tosa_charge_full_enable = 1; // @ Start!!
-+ tosa_charge_full_counter = RCNR; // @ Reset Failsafe Counter.
-+ tosa_charge_full_main_batt = tosa_read_battery(SEL_MAIN);
-+ if(sharpsl_jacket_batt_exist)
-+ tosa_charge_full_jacket_batt = tosa_read_battery(SEL_JACKET);
-+#if CHECK_LOG
-+ printk("*** CHG_FAILSAFE_COUNTER_START: time=%d(%08x) ***\n",RCNR-tosa_charge_full_counter,RCNR);
-+#endif
-+ }
-+#endif //TOSA_OFF_CHARGE_FAILSAFE
-+
-+ while(1){
-+ int jacket_batt_exist_now = 0;
-+
-+ // ac out ?
-+ if ( SHARPSL_AC_LINE_STATUS == APM_AC_OFFLINE ) {
-+ charge_status = 0;
-+ CHARGE_LED_OFF();
-+ //printk("%s: [go off] ac out !\n",__func__);
-+#ifdef TOSA_OFF_CHARGE_FAILSAFE
-+ tosa_charge_full_enable = 0; // @ Stop!!
-+#endif
-+ ret = -1;
-+ break;
-+ }
-+
-+ // check wakeup interrupt.
-+ if ( ( ret = sharpsl_wakeup_check_charge() ) != 1 ) {
-+ break;
-+ }
-+
-+ // timeout ?
-+ if ( ( RCNR - time ) > SHARPSL_TOSA_WAIT_CO_TIME ) {
-+ //printk("%s: [go off] finished! not full !\n",__func__);
-+ ret = -1;
-+ break;
-+ }
-+
-+ // battery switch status change ?
-+ if(batt_sw_state != SHARPSL_BAT_LOCKED_STATUS){
-+ //printk("%s: [go off] battery switch status is changed !\n",__func__);
-+ ret = -1;
-+ break;
-+ }
-+
-+ // jacket detect status change ?
-+ if(jacket_state != (GPLR(GPIO_JACKET_DETECT) & GPIO_bit(GPIO_JACKET_DETECT))) {
-+ tosa_get_jacket_status_for_on();
-+#ifdef TOSA_OFF_CHARGE_FAILSAFE
-+ tosa_charge_full_enable = 0; // @ Stop!!
-+#endif
-+ //printk("%s: [go off] jacket status is changed !\n",__func__);
-+ ret = -1;
-+ break;
-+ }
-+
-+ // battery full ?
-+ tosa_off_main_batt_full = SHARPSL_MAIN_BATT_FULL;
-+ tosa_off_jacket_batt_full = 0;
-+ if(sharpsl_jacket_exist && sharpsl_jacket_batt_exist){
-+ tosa_off_jacket_batt_full = SHARPSL_JACKET_BATT_FULL;
-+ }
-+ is_all_battery_full = 0;
-+
-+#ifdef TOSA_OFF_CHARGE_FAILSAFE
-+ if(tosa_charge_full_enable){
-+ if((RCNR - tosa_charge_full_counter) > (TOSA_CHARGE_FULL_MAX_TIME-cktime)){
-+#if CHECK_LOG
-+ printk("*** ALL BATTERY is FULL by FAILSAFE.***\n");
-+ printk(" CHG_FAILSAFE_COUNTER: time=%d\n",RCNR - tosa_charge_full_counter);
-+#endif
-+ is_all_battery_full = 1;
-+ }
-+ }
-+#endif //TOSA_OFF_CHARGE_FAILSAFE
-+
-+ if(charge_status && tosa_off_main_batt_full){
-+ // main battery full !
-+#if CHECK_LOG
-+ printk("\n");
-+ printk(" MAIN BATTERY is FULL.\n");
-+#endif
-+ if(sharpsl_jacket_batt_exist){
-+ if(tosa_off_jacket_batt_full){
-+ // all battery full !
-+ is_all_battery_full = 1;
-+#if CHECK_LOG
-+ printk(" JACKET BATTERY is FULL.\n");
-+#endif
-+ }
-+ }else{
-+ // all battery full ! (non-jacket)
-+ is_all_battery_full = 1;
-+#if CHECK_LOG
-+ printk(" JACKET BATTERY is NON.\n");
-+#endif
-+ }
-+ }
-+#if CHECK_LOG
-+ else{
-+ printk(".");
-+ }
-+#endif
-+ if(is_all_battery_full){
-+
-+ // ac out ?
-+ if ( SHARPSL_AC_LINE_STATUS == APM_AC_OFFLINE ) {
-+ continue;
-+ }
-+
-+ // all battery full !!!!
-+ //printk("%s: [go off] all battery full !\n",__func__);
-+#if CHECK_LOG
-+ printk("\n");
-+ printk(" CHG_FAILSAFE_COUNTER: time=%d\n",RCNR - tosa_charge_full_counter);
-+ printk("*** CHG_CHK_END: t=%d (%08x) ***\n",RCNR-gStartTime,RCNR);
-+ printk("*** ALL BATTERY is FULL!! ***\n");
-+#endif
-+ CHARGE_LED_OFF(); // led off
-+ charge_status = 0;
-+ pass_charge_flag = 1;
-+ ret = -1; // go off.
-+ return ret;
-+ }
-+ }
-+
-+#ifdef TOSA_OFF_CHARGE_FAILSAFE
-+ if(tosa_charge_full_enable){
-+ int batt_now;
-+
-+#if CHECK_LOG
-+ printk("\n");
-+ printk(" MAIN VOLTAGE CHECK: ");
-+#endif
-+ batt_now = tosa_read_battery(SEL_MAIN);
-+ if((tosa_charge_full_main_batt - batt_now) >= TOSA_CHARGE_FULL_DIFF_VOLT){
-+#if CHECK_LOG
-+ printk("[NG] (%d->%d)\n",tosa_charge_full_main_batt,batt_now);
-+ printk(" * RESTART: time=%d \n",RCNR);
-+#endif
-+ tosa_charge_full_counter = RCNR; // @ Reset Failsafe Counter.
-+ }
-+#if CHECK_LOG
-+ else{
-+ printk("[OK] (%d->%d)\n",tosa_charge_full_main_batt,batt_now);
-+ }
-+#endif
-+ tosa_charge_full_main_batt = batt_now;
-+
-+#if CHECK_LOG
-+ printk(" JACKET VOLTAGE CHECK: ");
-+#endif
-+ if(sharpsl_jacket_batt_exist){
-+ batt_now = tosa_read_battery(SEL_JACKET);
-+ if((tosa_charge_full_jacket_batt - batt_now) >= TOSA_CHARGE_FULL_DIFF_VOLT){
-+ tosa_charge_full_counter = RCNR; // @ Reset Failsafe Counter.
-+#if CHECK_LOG
-+ printk("[NG] (%d->%d)\n",tosa_charge_full_main_batt,batt_now);
-+ printk(" * RESTART: time=%d ***\n",RCNR);
-+#endif
-+ }
-+#if CHECK_LOG
-+ else{
-+ printk("[OK] (%d->%d)\n",tosa_charge_full_jacket_batt,batt_now);
-+ }
-+#endif
-+ tosa_charge_full_jacket_batt = batt_now;
-+ }
-+#if CHECK_LOG
-+ else{
-+ printk("[OK] (NON-JACKET)\n");
-+ }
-+#endif
-+ }
-+#endif //TOSA_OFF_CHARGE_FAILSAFE
-+
-+#ifdef TOSA_OFF_CHARGE_FAILSAFE
-+#if CHECK_LOG
-+ if(tosa_charge_full_enable){
-+ printk(" CHG_FAILSAFE_COUNTER: time=%d\n",RCNR - tosa_charge_full_counter);
-+ }
-+#endif
-+#endif
-+
-+#if CHECK_LOG
-+ printk("*** CHG_CHK_END: time=%d(%08x) ***\n",RCNR-gStartTime,RCNR);
-+ printk("\n");
-+#endif
-+
-+ pass_charge_flag = 0;
-+ return ret;
-+}
-+
-+void tosa_check_ac_and_jacket_state(void)
-+{
-+ int is_all_battery_full = 0;
-+
-+ if(!pass_charge_flag){
-+ if(SHARPSL_AC_LINE_STATUS != APM_AC_OFFLINE){
-+ sharpsl_off_charge_battery();
-+ charge_status = 1;
-+ CHARGE_LED_ON();
-+ }else{
-+ charge_status = 0;
-+ CHARGE_LED_OFF();
-+ }
-+ }
-+ if(!tosa_off_check_jacket_req){
-+ return;
-+ }
-+ tosa_off_check_jacket_req = 0;
-+ // restart charge.
-+ CHARGE_ON();
-+
-+ // check jacket.
-+ tosa_get_jacket_status_for_on();
-+ mdelay(100);
-+
-+ tosa_off_main_batt_full = 0;
-+ tosa_off_jacket_batt_full = 0;
-+ charge_status = 0;
-+
-+ if(SHARPSL_AC_LINE_STATUS != APM_AC_OFFLINE){
-+ // ac in.
-+ tosa_off_main_batt_full = SHARPSL_MAIN_BATT_FULL;
-+ if(sharpsl_jacket_exist && sharpsl_jacket_batt_exist){
-+ tosa_off_jacket_batt_full = SHARPSL_JACKET_BATT_FULL;
-+ }
-+ //sharpsl_off_charge_battery();
-+ charge_status = 1;
-+ CHARGE_LED_ON();
-+#if CHECK_LOG
-+ printk("*** CHG_START: time=0(%08x) ***\n",RCNR);
-+ gStartTime = RCNR;
-+ printk(" MAIN AD: %d JACKET AD %d\n",tosa_read_battery(SEL_MAIN),tosa_read_battery(SEL_JACKET));
-+#endif
-+ }else{
-+ // ac out.
-+ charge_status = 0;
-+ CHARGE_LED_OFF();
-+ }
-+
-+ tosa_off_jc_card_limit();
-+
-+ DPRINTK4("[BATT]sharpsl_jacket_exist = %d\n",sharpsl_jacket_exist);
-+ DPRINTK4("[BATT]sharpsl_jacket_batt_exist = %d\n",sharpsl_jacket_batt_exist);
-+ DPRINTK4("[BATT]charge_status = %d\n",charge_status);
-+ DPRINTK4("[BATT]main_batt_full = %d\n",tosa_off_main_batt_full);
-+ DPRINTK4("[BATT]jacket_batt_full = %d\n",tosa_off_jacket_batt_full);
-+
-+ pass_charge_flag = 0;
-+ return;
-+}
-+
-+void sharpsl_battery_charge_hook(int mode)
-+{
-+ switch (mode){
-+ case 0: // Main Battery Full
-+ DPRINTK4("[IRQ]main battery full.\n");
-+ break;
-+ case 1: // Charge Off
-+ DPRINTK4("[IRQ]ac out.\n");
-+ break;
-+ case 2: // Charge On
-+ DPRINTK4("[IRQ]ac in.\n");
-+ break;
-+ case 3: // Jacket Battery Full
-+ DPRINTK4("[IRQ]jacket battery full.\n");
-+ break;
-+ case 4: // Jacket Detect
-+ DPRINTK4("[IRQ]check jacket.\n");
-+ break;
-+ case 5:
-+ DPRINTK4("[IRQ]timer.(%d)\n",RCNR);
-+ tosa_check_ac_and_jacket_state();
-+ tosa_off_check_jacket_req = 0;
-+ return;
-+ break;
-+ default:
-+ return;
-+ break;
-+ }
-+#ifdef TOSA_OFF_CHARGE_FAILSAFE
-+ if(tosa_charge_full_enable){
-+ tosa_charge_full_enable = 0;
-+ }
-+#endif //TOSA_OFF_CHARGE_FAILSAFE
-+ tosa_off_check_jacket_req = 1;
-+ return;
-+}
-+
-+#endif /* CONFIG_PM */
-+
-+
-+/*** Config & Setup **********************************************************/
-+void battery_init(void)
-+{
-+ int err;
-+
-+ init_timer(&ac_kick_timer);
-+ ac_kick_timer.function = (void*)sharpsl_ac_kick_timer;
-+
-+ init_timer(&jacket_kick_timer);
-+ jacket_kick_timer.function = (void*)tosa_jacket_kick_timer;
-+
-+ GPDR(GPIO_AC_IN) &= ~GPIO_bit(GPIO_AC_IN);
-+ GPDR(GPIO_BAT0_CRG) &= ~GPIO_bit(GPIO_BAT0_CRG);
-+ GPDR(GPIO_BAT1_CRG) &= ~GPIO_bit(GPIO_BAT1_CRG);
-+
-+ GPDR(GPIO_BAT0_LOW) &= ~GPIO_bit(GPIO_BAT0_LOW);
-+ GPDR(GPIO_BAT1_LOW) &= ~GPIO_bit(GPIO_BAT1_LOW);
-+
-+ printk("SHARPSL_AC_LINE_STATUS=%x\n",SHARPSL_AC_LINE_STATUS);
-+
-+ /* Set transition detect */
-+ set_GPIO_IRQ_edge( GPIO_AC_IN , GPIO_BOTH_EDGES ); /* AC IN */
-+ set_GPIO_IRQ_edge( GPIO_JACKET_DETECT , GPIO_BOTH_EDGES );
-+#ifndef TOSA_BATTERY_SKIP
-+ set_GPIO_IRQ_edge( GPIO_BAT0_LOW , GPIO_FALLING_EDGE );
-+ set_GPIO_IRQ_edge( GPIO_BAT1_LOW , GPIO_FALLING_EDGE );
-+#endif
-+
-+ /* Register interrupt handler. */
-+ if ((err = request_irq(IRQ_GPIO_AC_IN, tosa_ac_interrupt,
-+ SA_INTERRUPT, "ACIN", tosa_ac_interrupt))) {
-+ printk("Could not get irq %d.\n", IRQ_GPIO_AC_IN);
-+ return;
-+ }
-+ if ((err = request_irq(IRQ_GPIO_JACKET_DETECT, tosa_jacket_interrupt,
-+ SA_INTERRUPT, "JACKET_DETECT", tosa_jacket_interrupt))) {
-+ printk("Could not get irq %d.\n", IRQ_GPIO_JACKET_DETECT);
-+ return;
-+ }
-+
-+#ifndef TOSA_BATTERY_SKIP
-+ if ((err = request_irq(IRQ_GPIO_BAT0_LOW, tosa_main_batt_fatal_interrupt,
-+ SA_INTERRUPT, "MAIN_FATAL", tosa_main_batt_fatal_interrupt))) {
-+ printk("Could not get irq %d.\n", IRQ_GPIO_BAT0_LOW);
-+ return;
-+ }
-+ disable_irq(IRQ_GPIO_BAT0_LOW);
-+
-+ if ((err = request_irq(IRQ_GPIO_BAT1_LOW, tosa_jacket_batt_fatal_interrupt,
-+ SA_INTERRUPT, "JACKET_FATAL", tosa_jacket_batt_fatal_interrupt))) {
-+ printk("Could not get irq %d.\n", IRQ_GPIO_BAT1_LOW);
-+ return;
-+ }
-+ disable_irq(IRQ_GPIO_BAT1_LOW);
-+#endif
-+
-+ /* regist to Misc driver */
-+ misc_register(&battery_device);
-+
-+ /* Make threads */
-+ kernel_thread(tosa_charge_on, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
-+ kernel_thread(tosa_charge_off, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
-+ kernel_thread(tosa_battery_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
-+ kernel_thread(tosa_fatal_check, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
-+ kernel_thread(tosa_jacket_check, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
-+
-+ tosa_get_jacket_status_for_on();
-+}
-+
-+
-+
-+#ifdef CONFIG_PROC_FS
-+struct proc_dir_entry *proc_batt;
-+
-+typedef struct sharpsl_battery_entry {
-+ int* addr;
-+ int def_value;
-+ char* name;
-+ char* description;
-+ unsigned short low_ino;
-+} sharpsl_battery_entry_t;
-+
-+static sharpsl_battery_entry_t sharpsl_battery_params[] = {
-+/* { addr, def_value, name, description }*/
-+ { &msglevel, 0, "msglevel", "debug message output level" },
-+ { &sharpsl_debug_flag , 0 , "dflag", "debug flag" },
-+ { &sharpsl_change_battery_status , 0 , "chg_status", "Change status" }
-+};
-+#define NUM_OF_BATTERY_ENTRY (sizeof(sharpsl_battery_params)/sizeof(sharpsl_battery_entry_t))
-+
-+static ssize_t sharpsl_battery_read_params(struct file *file, char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ int i_ino = (file->f_dentry->d_inode)->i_ino;
-+ char outputbuf[15];
-+ int count;
-+ int i;
-+ sharpsl_battery_entry_t *current_param = NULL;
-+
-+ if (*ppos>0) /* Assume reading completed in previous read*/
-+ return 0;
-+ for (i=0; i<NUM_OF_BATTERY_ENTRY; i++) {
-+ if (sharpsl_battery_params[i].low_ino==i_ino) {
-+ current_param = &sharpsl_battery_params[i];
-+ break;
-+ }
-+ }
-+ if (current_param==NULL) {
-+ return -EINVAL;
-+ }
-+ count = sprintf(outputbuf, "0x%08X\n",
-+ *((volatile Word *) current_param->addr));
-+ *ppos += count;
-+ if (count>nbytes) /* Assume output can be read at one time */
-+ return -EINVAL;
-+ if (copy_to_user(buf, outputbuf, count))
-+ return -EFAULT;
-+ return count;
-+}
-+
-+static ssize_t sharpsl_battery_write_params(struct file *file, const char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ int i_ino = (file->f_dentry->d_inode)->i_ino;
-+ sharpsl_battery_entry_t *current_param = NULL;
-+ int i;
-+ unsigned long param;
-+ char *endp;
-+
-+ for (i=0; i<NUM_OF_BATTERY_ENTRY; i++) {
-+ if(sharpsl_battery_params[i].low_ino==i_ino) {
-+ current_param = &sharpsl_battery_params[i];
-+ break;
-+ }
-+ }
-+ if (current_param==NULL) {
-+ return -EINVAL;
-+ }
-+
-+ param = simple_strtoul(buf,&endp,0);
-+ if (param == -1) {
-+ *current_param->addr = current_param->def_value;
-+ } else {
-+ *current_param->addr = param;
-+ }
-+ return nbytes+endp-buf;
-+}
-+
-+static unsigned int sharpsl_battery_poll(struct file *fp, poll_table * wait)
-+{
-+ poll_wait(fp, &battery_waitqueue, wait);
-+ if ( sharpsl_change_battery_status ) {
-+ sharpsl_change_battery_status = 0;
-+ return POLLIN | POLLRDNORM;
-+ } else {
-+ return 0;
-+ }
-+}
-+
-+static struct file_operations proc_params_operations = {
-+ read: sharpsl_battery_read_params,
-+ write: sharpsl_battery_write_params,
-+ poll: sharpsl_battery_poll,
-+};
-+#endif
-+
-+int __init Sharpsl_battery_init(void)
-+{
-+#ifdef CONFIG_PM
-+ battery_pm_dev = pm_register(PM_SYS_DEV, 0, Sharpsl_battery_pm_callback);
-+#endif
-+
-+ battery_init();
-+
-+#ifdef CONFIG_PROC_FS
-+ {
-+ int i;
-+ struct proc_dir_entry *entry;
-+
-+ proc_batt = proc_mkdir("driver/battery", NULL);
-+ if (proc_batt == NULL) {
-+ free_irq(IRQ_GPIO_AC_IN, tosa_ac_interrupt);
-+ free_irq(IRQ_GPIO_JACKET_DETECT, tosa_jacket_interrupt);
-+#ifndef TOSA_BATTERY_SKIP
-+ free_irq(IRQ_GPIO_BAT0_LOW, tosa_main_batt_fatal_interrupt);
-+ free_irq(IRQ_GPIO_BAT1_LOW, tosa_jacket_batt_fatal_interrupt);
-+#endif
-+ misc_deregister(&battery_device);
-+ printk(KERN_ERR "can't create /proc/driver/battery\n");
-+ return -ENOMEM;
-+ }
-+ for (i=0; i<NUM_OF_BATTERY_ENTRY; i++) {
-+ entry = create_proc_entry(sharpsl_battery_params[i].name,
-+ S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH,
-+ proc_batt);
-+ if (entry) {
-+ sharpsl_battery_params[i].low_ino = entry->low_ino;
-+ entry->proc_fops = &proc_params_operations;
-+ } else {
-+ int j;
-+ for (j=0; j<i; j++) {
-+ remove_proc_entry(sharpsl_battery_params[i].name, proc_batt);
-+ }
-+ remove_proc_entry("driver/battery", &proc_root);
-+ proc_batt = 0;
-+ free_irq(IRQ_GPIO_AC_IN, tosa_ac_interrupt);
-+ free_irq(IRQ_GPIO_JACKET_DETECT, tosa_jacket_interrupt);
-+#ifndef TOSA_BATTERY_SKIP
-+ free_irq(IRQ_GPIO_BAT0_LOW, tosa_main_batt_fatal_interrupt);
-+ free_irq(IRQ_GPIO_BAT1_LOW, tosa_jacket_batt_fatal_interrupt);
-+#endif
-+ misc_deregister(&battery_device);
-+ printk(KERN_ERR "battery: can't create /proc/driver/battery\n");
-+ return -ENOMEM;
-+ }
-+ }
-+ }
-+#endif
-+ return 0;
-+}
-+
-+module_init(Sharpsl_battery_init);
-+
-+
-+
-+#ifdef MODULE
-+int init_module(void)
-+{
-+ Sharpsl_battery_init();
-+ return 0;
-+}
-+
-+void cleanup_module(void)
-+{
-+ free_irq(IRQ_GPIO_AC_IN, tosa_ac_interrupt);
-+ free_irq(IRQ_GPIO_JACKET_DETECT, tosa_jacket_interrupt);
-+#ifndef TOSA_BATTERY_SKIP
-+ free_irq(IRQ_GPIO_BAT0_LOW, tosa_main_batt_fatal_interrupt);
-+ free_irq(IRQ_GPIO_BAT1_LOW, tosa_jacket_batt_fatal_interrupt);
-+#endif
-+
-+#ifdef CONFIG_PROC_FS
-+ {
-+ int i;
-+ for (i=0; i<NUM_OF_BATTERY_ENTRY; i++) {
-+ remove_proc_entry(sharpsl_battery_params[i].name, proc_batt);
-+ }
-+ remove_proc_entry("driver/battery", NULL);
-+ proc_batt = 0;
-+ }
-+#endif
-+
-+ misc_deregister(&battery_device);
-+}
-+#endif /* MODULE */
-+
-diff -Nur linux_c860_org/arch/arm/mach-pxa/tosa_buzzer.c linux/arch/arm/mach-pxa/tosa_buzzer.c
---- linux_c860_org/arch/arm/mach-pxa/tosa_buzzer.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/arch/arm/mach-pxa/tosa_buzzer.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,279 @@
-+/*
-+ * arch/arm/mach-pxa/tosa_buzzer.c
-+ *
-+ * PXA buzzer ctrl for Tosa (SHARP)
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * Based on collie_buzzer
-+ *
-+ *
-+ * 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.
-+ *
-+ * ChangeLog:
-+ * 16-Jan-2003 SHARP sleep_on -> interruptible_sleep_on
-+ * 1-Nov-2003 Sharp Corporation for Tosa
-+ *
-+ */
-+#include <linux/module.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/poll.h>
-+#include <linux/major.h>
-+#include <linux/config.h>
-+#include <linux/fcntl.h>
-+#include <linux/errno.h>
-+#include <linux/mm.h>
-+#include <linux/malloc.h>
-+#include <linux/sound.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+
-+#ifdef CONFIG_PM
-+#include <linux/pm.h>
-+#endif /* CONFIG_PM */
-+
-+#include <asm/system.h>
-+#include <asm/irq.h>
-+#include <asm/pgtable.h>
-+#include <asm/uaccess.h>
-+#include <asm/io.h>
-+#include <linux/soundcard.h>
-+#include <asm/proc/cache.h>
-+
-+#include <asm/sharp_char.h>
-+#include <asm/arch/tosa_wm9712.h>
-+
-+#undef DEBUG
-+//#define DEBUG
-+#ifdef DEBUG
-+#define DPRINTK( x... ) printk( ##x )
-+#else
-+#define DPRINTK( x... )
-+#endif
-+
-+/*** sound data *********************************************************/
-+#include "poodle_key.h"
-+#include "poodle_tap.h"
-+#include "poodle_alarm.h"
-+
-+/*** Some declarations ***********************************************/
-+static DECLARE_WAIT_QUEUE_HEAD(buzzer_proc);
-+static int now_playing = 0 ;
-+static int buzzer_soundid = 0;
-+static int repeat_sound = 0;
-+
-+
-+// following functions include tosa audio driver.
-+int audio_buzzer_write(const char *,int);
-+int audio_buzzer_intmode(const short *,int,int);
-+int audio_buzzer_release(void);
-+int audio_buzzer_open(int);
-+
-+/*** buzzer ******************************************************************/
-+int tosa_buz_buffer_init()
-+{
-+ return 0;
-+}
-+
-+int tosa_play_sound_by_id(int soundid,int volume)
-+{
-+
-+ switch( soundid ){
-+
-+ case SHARP_BUZ_TOUCHSOUND:
-+ if ( wm9712_busy() && !repeat_sound ) {
-+ } else {
-+ while (buzzer_soundid) schedule();
-+ buzzer_soundid = soundid;
-+ wake_up(&buzzer_proc);
-+ }
-+ break;
-+
-+ case SHARP_BUZ_KEYSOUND:
-+ if ( wm9712_busy() && !repeat_sound ) {
-+ } else {
-+ while (buzzer_soundid) schedule();
-+ buzzer_soundid = soundid;
-+ wake_up(&buzzer_proc);
-+ }
-+ break;
-+
-+ case SHARP_BUZ_SCHEDULE_ALARM:
-+ if ( wm9712_busy() ) {
-+ buzzer_soundid = soundid;
-+ wake_up(&buzzer_proc);
-+ } else {
-+ while (buzzer_soundid) schedule();
-+ buzzer_soundid = soundid;
-+ wake_up(&buzzer_proc);
-+ }
-+ break;
-+
-+ case SHARP_PDA_WARNSOUND:
-+ break;
-+
-+ case SHARP_BUZ_GOT_MAIL:
-+ case SHARP_BUZ_DAILY_ALARM:
-+ case SHARP_PDA_ERRORSOUND:
-+ case SHARP_PDA_CRITICALSOUND:
-+ break;
-+
-+ default:
-+ return -EINVAL;
-+ break;
-+ }
-+
-+ return 0;
-+}
-+int tosa_buzzer_supported(int which)
-+{
-+ switch( which ){
-+ case SHARP_BUZ_TOUCHSOUND:
-+ case SHARP_BUZ_KEYSOUND:
-+ case SHARP_BUZ_SCHEDULE_ALARM:
-+ case SHARP_BUZ_DAILY_ALARM:
-+ case SHARP_BUZ_GOT_MAIL:
-+ case SHARP_PDA_WARNSOUND:
-+ case SHARP_PDA_ERRORSOUND:
-+ case SHARP_PDA_CRITICALSOUND:
-+ break;
-+ default:
-+ return -EINVAL;
-+ break;
-+ }
-+ return 4;
-+}
-+
-+int tosa_play_sound_by_hz(unsigned int hz,unsigned int msecs,int volume)
-+{
-+ return 0;
-+}
-+
-+int current_freq;
-+static void change_freq( int new_freq )
-+{
-+ if (current_freq!=new_freq) {
-+ audio_buzzer_release();
-+ audio_buzzer_open(new_freq);
-+ current_freq = new_freq;
-+ }
-+}
-+
-+static void tosa_buzzer_thread(void)
-+{
-+ // daemonize();
-+ strcpy(current->comm, "buzzer");
-+ sigfillset(&current->blocked);
-+
-+ while(1) {
-+ if (buzzer_soundid==0) {
-+ //while(buzzer_soundid==0)
-+ interruptible_sleep_on(&buzzer_proc);
-+ } else {
-+ if (wm9712_busy()) {
-+ if (buzzer_soundid==SHARP_BUZ_SCHEDULE_ALARM) {
-+ //audio_buzzer_intmode(alarm_data,sizeof(alarm_data),44100);
-+ audio_buzzer_intmode(alarm_data,sizeof(alarm_data),8000);
-+ }
-+ buzzer_soundid=0;
-+ continue;
-+ }
-+ now_playing = 1;
-+ current_freq = key_freq;
-+ audio_buzzer_open(current_freq);
-+ while ( buzzer_soundid!=0 ) {
-+ int tmpid = buzzer_soundid;
-+ buzzer_soundid=0;
-+
-+ switch( tmpid ) {
-+
-+ case SHARP_BUZ_TOUCHSOUND:
-+ repeat_sound = 1;
-+ change_freq(tap_freq);
-+ audio_buzzer_write(tap_data, sizeof(tap_data));
-+ audio_buzzer_sync();
-+ break;
-+
-+ case SHARP_BUZ_KEYSOUND:
-+ repeat_sound = 1;
-+ change_freq(key_freq);
-+ audio_buzzer_write(key_data, sizeof(key_data));
-+ audio_buzzer_sync();
-+ break;
-+
-+ case SHARP_BUZ_SCHEDULE_ALARM:
-+ {
-+ int alarm_data_size = sizeof(alarm_data);
-+ unsigned char *alarm_data0 = alarm_data;
-+ int cnt;
-+
-+ repeat_sound = 0;
-+ //change_freq(44100);
-+ change_freq(8000);
-+ while(1) {
-+ cnt = audio_buzzer_write(alarm_data0,alarm_data_size);
-+ audio_buzzer_sync();
-+ if ( cnt <= 0 ) break;
-+ alarm_data_size -= cnt;
-+ alarm_data0 += cnt;
-+ }
-+ break;
-+ }
-+
-+ case SHARP_PDA_WARNSOUND:
-+ case SHARP_BUZ_GOT_MAIL:
-+ case SHARP_BUZ_DAILY_ALARM:
-+ case SHARP_PDA_ERRORSOUND:
-+ case SHARP_PDA_CRITICALSOUND:
-+ repeat_sound = 0;
-+ break;
-+
-+ default:
-+ repeat_sound = 0;
-+ break;
-+ } // switch
-+ } // while loop
-+ audio_buzzer_release();
-+ repeat_sound = 0;
-+ now_playing = 0;
-+ }
-+ } // while(1) loop
-+}
-+
-+
-+int tosa_buzzer_dev_init(void)
-+{
-+ kernel_thread(tosa_buzzer_thread, NULL,
-+ CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
-+ return 0;
-+}
-+
-+int tosa_suspend_buzzer(void)
-+{
-+#if 0
-+ printk("tosa_suspend_buzzer\n");
-+ while ( now_playing ) {
-+ schedule();
-+ }
-+#endif
-+ return 0;
-+}
-+
-+int tosa_resume_buzzer(void)
-+{
-+ return 0;
-+}
-+
-+void tosa_stop_sound()
-+{
-+ return;
-+}
-diff -Nur linux_c860_org/arch/arm/mm/fault-armv.c linux/arch/arm/mm/fault-armv.c
---- linux_c860_org/arch/arm/mm/fault-armv.c 2003-06-18 16:12:26.000000000 +0900
-+++ linux/arch/arm/mm/fault-armv.c 2004-06-10 21:09:10.000000000 +0900
-@@ -11,6 +11,7 @@
- * Change Log
- * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
- * 04-Apr-2003 Sharp for ARM FCSE
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- *
- */
- #include <linux/config.h>
-@@ -126,12 +127,14 @@
- }
- #endif
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
-+#ifdef CONFIG_PM
- {
- extern sharpsl_fataloff(void);
- sharpsl_fataloff();
- }
- #endif
-+#endif
-
- if (!inf->fn(addr, error_code, regs))
- return;
-diff -Nur linux_c860_org/arch/arm/mm/proc-xscale.S linux/arch/arm/mm/proc-xscale.S
---- linux_c860_org/arch/arm/mm/proc-xscale.S 2003-10-15 16:42:00.000000000 +0900
-+++ linux/arch/arm/mm/proc-xscale.S 2004-06-10 21:09:10.000000000 +0900
-@@ -25,6 +25,7 @@
- * 20-Mar-2003 SHARP supported PXA255
- * 04-Apr-2003 Sharp for ARM FCSE
- * 15-Oct-2003 Sharp fix icache flush
-+ * 16-Jul-2003 Sharp Corporation
- */
-
- #include <linux/config.h>
-diff -Nur linux_c860_org/arch/arm/tools/getconstants.c linux/arch/arm/tools/getconstants.c
---- linux_c860_org/arch/arm/tools/getconstants.c 2002-08-26 14:39:51.000000000 +0900
-+++ linux/arch/arm/tools/getconstants.c 2004-06-10 21:09:10.000000000 +0900
-@@ -13,6 +13,7 @@
-
- #include <asm/pgtable.h>
- #include <asm/uaccess.h>
-+#include <asm/hardirq.h>
-
- /*
- * Make sure that the compiler and target are compatible.
-@@ -39,6 +40,11 @@
- DEFN("TSS_SAVE", OFF_TSK(thread.save));
- DEFN("TSS_FPESAVE", OFF_TSK(thread.fpstate.soft.save));
-
-+#ifdef CONFIG_PREEMPT
-+DEFN("TSK_PREEMPT", OFF_TSK(preempt_count));
-+DEFN("IRQSTAT_BH_COUNT", (unsigned long)&(((irq_cpustat_t *)0)->__local_bh_count));
-+#endif
-+
- #ifdef CONFIG_CPU_32
- DEFN("TSS_DOMAIN", OFF_TSK(thread.domain));
-
-diff -Nur linux_c860_org/arch/arm/tools/mach-types linux/arch/arm/tools/mach-types
---- linux_c860_org/arch/arm/tools/mach-types 2002-08-29 12:27:22.000000000 +0900
-+++ linux/arch/arm/tools/mach-types 2004-06-10 21:09:10.000000000 +0900
-@@ -205,3 +205,4 @@
- discovery SABINAL_DISCOVERY DISCOVERY 194
- poodle ARCH_PXA_POODLE POODLE 195
- corgi ARCH_PXA_CORGI CORGI 196
-+tosa ARCH_PXA_TOSA TOSA 197
-diff -Nur linux_c860_org/arch/cris/drivers/ds1302.c linux/arch/cris/drivers/ds1302.c
---- linux_c860_org/arch/cris/drivers/ds1302.c 2002-08-26 14:39:59.000000000 +0900
-+++ linux/arch/cris/drivers/ds1302.c 2004-06-10 21:09:10.000000000 +0900
-@@ -357,6 +357,7 @@
- {
- struct rtc_time rtc_tm;
-
-+ memset(&rtc_tm, 0, sizeof (struct rtc_time));
- get_rtc_time(&rtc_tm);
- if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time)))
- return -EFAULT;
-diff -Nur linux_c860_org/arch/i386/config.in linux/arch/i386/config.in
---- linux_c860_org/arch/i386/config.in 2002-08-26 14:45:20.000000000 +0900
-+++ linux/arch/i386/config.in 2004-06-10 21:09:10.000000000 +0900
-@@ -186,6 +186,10 @@
- bool 'Math emulation' CONFIG_MATH_EMULATION
- bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
- bool 'Symmetric multi-processing support' CONFIG_SMP
-+bool 'Preemptible Kernel' CONFIG_PREEMPT
-+if [ "$CONFIG_PREEMPT" = "y" ]; then
-+ bool 'Break selected locks' CONFIG_LOCK_BREAK
-+fi
- if [ "$CONFIG_SMP" != "y" ]; then
- bool 'Local APIC support on uniprocessors' CONFIG_X86_UP_APIC
- dep_bool 'IO-APIC support on uniprocessors' CONFIG_X86_UP_IOAPIC $CONFIG_X86_UP_APIC
-@@ -199,9 +203,12 @@
- bool 'Multiquad NUMA system' CONFIG_MULTIQUAD
- fi
-
--if [ "$CONFIG_SMP" = "y" -a "$CONFIG_X86_CMPXCHG" = "y" ]; then
-- define_bool CONFIG_HAVE_DEC_LOCK y
-+if [ "$CONFIG_SMP" = "y" -o "$CONFIG_PREEMPT" = "y" ]; then
-+ if [ "$CONFIG_X86_CMPXCHG" = "y" ]; then
-+ define_bool CONFIG_HAVE_DEC_LOCK y
-+ fi
- fi
-+
- endmenu
-
- mainmenu_option next_comment
-diff -Nur linux_c860_org/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
---- linux_c860_org/arch/i386/kernel/entry.S 2002-08-26 14:39:33.000000000 +0900
-+++ linux/arch/i386/kernel/entry.S 2004-06-10 21:09:10.000000000 +0900
-@@ -71,7 +71,7 @@
- * these are offsets into the task-struct.
- */
- state = 0
--flags = 4
-+preempt_count = 4
- sigpending = 8
- addr_limit = 12
- exec_domain = 16
-@@ -79,8 +79,28 @@
- tsk_ptrace = 24
- processor = 52
-
-+/* These are offsets into the irq_stat structure
-+ * There is one per cpu and it is aligned to 32
-+ * byte boundry (we put that here as a shift count)
-+ */
-+irq_array_shift = CONFIG_X86_L1_CACHE_SHIFT
-+
-+irq_stat_local_irq_count = 4
-+irq_stat_local_bh_count = 8
-+
- ENOSYS = 38
-
-+#ifdef CONFIG_SMP
-+#define GET_CPU_INDX movl processor(%ebx),%eax; \
-+ shll $irq_array_shift,%eax
-+#define GET_CURRENT_CPU_INDX GET_CURRENT(%ebx); \
-+ GET_CPU_INDX
-+#define CPU_INDX (,%eax)
-+#else
-+#define GET_CPU_INDX
-+#define GET_CURRENT_CPU_INDX GET_CURRENT(%ebx)
-+#define CPU_INDX
-+#endif
-
- #define SAVE_ALL \
- cld; \
-@@ -247,12 +267,30 @@
- ALIGN
- ENTRY(ret_from_intr)
- GET_CURRENT(%ebx)
-+#ifdef CONFIG_PREEMPT
-+ cli
-+ decl preempt_count(%ebx)
-+#endif
- ret_from_exception:
- movl EFLAGS(%esp),%eax # mix EFLAGS and CS
- movb CS(%esp),%al
- testl $(VM_MASK | 3),%eax # return to VM86 mode or non-supervisor?
- jne ret_from_sys_call
-+#ifdef CONFIG_PREEMPT
-+ cmpl $0,preempt_count(%ebx)
-+ jnz restore_all
-+ cmpl $0,need_resched(%ebx)
-+ jz restore_all
-+ movl SYMBOL_NAME(irq_stat)+irq_stat_local_bh_count CPU_INDX,%ecx
-+ addl SYMBOL_NAME(irq_stat)+irq_stat_local_irq_count CPU_INDX,%ecx
-+ jnz restore_all
-+ incl preempt_count(%ebx)
-+ sti
-+ call SYMBOL_NAME(preempt_schedule)
-+ jmp ret_from_intr
-+#else
- jmp restore_all
-+#endif
-
- ALIGN
- reschedule:
-@@ -289,6 +327,9 @@
- GET_CURRENT(%ebx)
- call *%edi
- addl $8,%esp
-+#ifdef CONFIG_PREEMPT
-+ cli
-+#endif
- jmp ret_from_exception
-
- ENTRY(coprocessor_error)
-@@ -308,12 +349,18 @@
- movl %cr0,%eax
- testl $0x4,%eax # EM (math emulation bit)
- jne device_not_available_emulate
-+#ifdef CONFIG_PREEMPT
-+ cli
-+#endif
- call SYMBOL_NAME(math_state_restore)
- jmp ret_from_exception
- device_not_available_emulate:
- pushl $0 # temporary storage for ORIG_EIP
- call SYMBOL_NAME(math_emulate)
- addl $4,%esp
-+#ifdef CONFIG_PREEMPT
-+ cli
-+#endif
- jmp ret_from_exception
-
- ENTRY(debug)
-diff -Nur linux_c860_org/arch/i386/kernel/i387.c linux/arch/i386/kernel/i387.c
---- linux_c860_org/arch/i386/kernel/i387.c 2002-08-26 14:39:33.000000000 +0900
-+++ linux/arch/i386/kernel/i387.c 2004-06-10 21:09:10.000000000 +0900
-@@ -10,6 +10,7 @@
-
- #include <linux/config.h>
- #include <linux/sched.h>
-+#include <linux/spinlock.h>
- #include <asm/processor.h>
- #include <asm/i387.h>
- #include <asm/math_emu.h>
-@@ -65,6 +66,8 @@
- {
- struct task_struct *tsk = current;
-
-+ preempt_disable();
-+
- if (tsk->flags & PF_USEDFPU) {
- __save_init_fpu(tsk);
- return;
-diff -Nur linux_c860_org/arch/i386/kernel/process.c linux/arch/i386/kernel/process.c
---- linux_c860_org/arch/i386/kernel/process.c 2002-08-26 14:39:33.000000000 +0900
-+++ linux/arch/i386/kernel/process.c 2004-06-10 21:09:10.000000000 +0900
-@@ -485,7 +485,7 @@
- /*
- * Create a kernel thread
- */
--int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
- {
- long retval, d0;
-
-@@ -508,6 +508,7 @@
- "r" (arg), "r" (fn),
- "b" (flags | CLONE_VM)
- : "memory");
-+
- return retval;
- }
-
-diff -Nur linux_c860_org/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c
---- linux_c860_org/arch/i386/kernel/smp.c 2002-08-26 14:39:33.000000000 +0900
-+++ linux/arch/i386/kernel/smp.c 2004-06-10 21:09:10.000000000 +0900
-@@ -354,10 +354,13 @@
-
- asmlinkage void smp_invalidate_interrupt (void)
- {
-- unsigned long cpu = smp_processor_id();
-+ unsigned long cpu;
-+
-+ preempt_disable();
-
-+ cpu = smp_processor_id();
- if (!test_bit(cpu, &flush_cpumask))
-- return;
-+ goto out;
- /*
- * This was a BUG() but until someone can quote me the
- * line from the intel manual that guarantees an IPI to
-@@ -378,6 +381,8 @@
- }
- ack_APIC_irq();
- clear_bit(cpu, &flush_cpumask);
-+out:
-+ preempt_enable();
- }
-
- static void flush_tlb_others (unsigned long cpumask, struct mm_struct *mm,
-@@ -427,17 +432,22 @@
- void flush_tlb_current_task(void)
- {
- struct mm_struct *mm = current->mm;
-- unsigned long cpu_mask = mm->cpu_vm_mask & ~(1 << smp_processor_id());
-+ unsigned long cpu_mask;
-
-+ preempt_disable();
-+ cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id());
- local_flush_tlb();
- if (cpu_mask)
- flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
-+ preempt_enable();
- }
-
- void flush_tlb_mm (struct mm_struct * mm)
- {
-- unsigned long cpu_mask = mm->cpu_vm_mask & ~(1 << smp_processor_id());
-+ unsigned long cpu_mask;
-
-+ preempt_disable();
-+ cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id());
- if (current->active_mm == mm) {
- if (current->mm)
- local_flush_tlb();
-@@ -446,13 +456,16 @@
- }
- if (cpu_mask)
- flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
-+ preempt_enable();
- }
-
- void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
- {
- struct mm_struct *mm = vma->vm_mm;
-- unsigned long cpu_mask = mm->cpu_vm_mask & ~(1 << smp_processor_id());
-+ unsigned long cpu_mask;
-
-+ preempt_disable();
-+ cpu_mask = mm->cpu_vm_mask & ~(1UL << smp_processor_id());
- if (current->active_mm == mm) {
- if(current->mm)
- __flush_tlb_one(va);
-@@ -462,6 +475,7 @@
-
- if (cpu_mask)
- flush_tlb_others(cpu_mask, mm, va);
-+ preempt_enable();
- }
-
- static inline void do_flush_tlb_all_local(void)
-diff -Nur linux_c860_org/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c
---- linux_c860_org/arch/i386/kernel/traps.c 2002-08-26 14:39:33.000000000 +0900
-+++ linux/arch/i386/kernel/traps.c 2004-06-10 21:09:10.000000000 +0900
-@@ -694,6 +694,8 @@
- *
- * Careful.. There are problems with IBM-designed IRQ13 behaviour.
- * Don't touch unless you *really* know how it works.
-+ *
-+ * Must be called with kernel preemption disabled.
- */
- asmlinkage void math_state_restore(struct pt_regs regs)
- {
-diff -Nur linux_c860_org/arch/i386/lib/dec_and_lock.c linux/arch/i386/lib/dec_and_lock.c
---- linux_c860_org/arch/i386/lib/dec_and_lock.c 2002-08-26 14:39:33.000000000 +0900
-+++ linux/arch/i386/lib/dec_and_lock.c 2004-06-10 21:09:10.000000000 +0900
-@@ -8,6 +8,7 @@
- */
-
- #include <linux/spinlock.h>
-+#include <linux/sched.h>
- #include <asm/atomic.h>
-
- int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock)
-diff -Nur linux_c860_org/arch/ia64/kernel/process.c linux/arch/ia64/kernel/process.c
---- linux_c860_org/arch/ia64/kernel/process.c 2002-08-26 14:39:53.000000000 +0900
-+++ linux/arch/ia64/kernel/process.c 2004-06-10 21:09:10.000000000 +0900
-@@ -182,7 +182,7 @@
- * | | <-- sp (lowest addr)
- * +---------------------+
- *
-- * Note: if we get called through kernel_thread() then the memory
-+ * Note: if we get called through arch_kernel_thread() then the memory
- * above "(highest addr)" is valid kernel stack memory that needs to
- * be copied as well.
- *
-@@ -415,7 +415,7 @@
- }
-
- pid_t
--kernel_thread (int (*fn)(void *), void *arg, unsigned long flags)
-+arch_kernel_thread (int (*fn)(void *), void *arg, unsigned long flags)
- {
- struct task_struct *parent = current;
- int result, tid;
-diff -Nur linux_c860_org/arch/m68k/bvme6000/rtc.c linux/arch/m68k/bvme6000/rtc.c
---- linux_c860_org/arch/m68k/bvme6000/rtc.c 2002-08-26 14:39:46.000000000 +0900
-+++ linux/arch/m68k/bvme6000/rtc.c 2004-06-10 21:09:10.000000000 +0900
-@@ -54,6 +54,7 @@
- /* Ensure clock and real-time-mode-register are accessible */
- msr = rtc->msr & 0xc0;
- rtc->msr = 0x40;
-+ memset(&wtime, 0, sizeof(struct rtc_time));
- do {
- wtime.tm_sec = BCD2BIN(rtc->bcd_sec);
- wtime.tm_min = BCD2BIN(rtc->bcd_min);
-diff -Nur linux_c860_org/arch/m68k/kernel/process.c linux/arch/m68k/kernel/process.c
---- linux_c860_org/arch/m68k/kernel/process.c 2002-08-26 14:39:45.000000000 +0900
-+++ linux/arch/m68k/kernel/process.c 2004-06-10 21:09:10.000000000 +0900
-@@ -124,7 +124,7 @@
- /*
- * Create a kernel thread
- */
--int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
- {
- int pid;
- mm_segment_t fs;
-diff -Nur linux_c860_org/arch/m68k/mvme16x/rtc.c linux/arch/m68k/mvme16x/rtc.c
---- linux_c860_org/arch/m68k/mvme16x/rtc.c 2002-08-26 14:39:47.000000000 +0900
-+++ linux/arch/m68k/mvme16x/rtc.c 2004-06-10 21:09:10.000000000 +0900
-@@ -52,6 +52,7 @@
- cli();
- /* Ensure clock and real-time-mode-register are accessible */
- rtc->ctrl = RTC_READ;
-+ memset(&wtime, 0, sizeof(struct rtc_time));
- wtime.tm_sec = BCD2BIN(rtc->bcd_sec);
- wtime.tm_min = BCD2BIN(rtc->bcd_min);
- wtime.tm_hour = BCD2BIN(rtc->bcd_hr);
-diff -Nur linux_c860_org/arch/mips/kernel/process.c linux/arch/mips/kernel/process.c
---- linux_c860_org/arch/mips/kernel/process.c 2002-08-26 14:39:37.000000000 +0900
-+++ linux/arch/mips/kernel/process.c 2004-06-10 21:09:10.000000000 +0900
-@@ -154,7 +154,7 @@
- /*
- * Create a kernel thread
- */
--int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
- {
- long retval;
-
-diff -Nur linux_c860_org/arch/mips64/kernel/process.c linux/arch/mips64/kernel/process.c
---- linux_c860_org/arch/mips64/kernel/process.c 2002-08-26 14:39:55.000000000 +0900
-+++ linux/arch/mips64/kernel/process.c 2004-06-10 21:09:10.000000000 +0900
-@@ -150,7 +150,7 @@
- /*
- * Create a kernel thread
- */
--int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-+int arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
- {
- int retval;
-
-diff -Nur linux_c860_org/arch/parisc/kernel/process.c linux/arch/parisc/kernel/process.c
---- linux_c860_org/arch/parisc/kernel/process.c 2002-08-26 14:39:58.000000000 +0900
-+++ linux/arch/parisc/kernel/process.c 2004-06-10 21:09:10.000000000 +0900
-@@ -118,7 +118,7 @@
- */
-
- extern pid_t __kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
--pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
-+pid_t arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
- {
-
- /*
-diff -Nur linux_c860_org/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S
---- linux_c860_org/arch/ppc/kernel/misc.S 2002-08-26 14:39:39.000000000 +0900
-+++ linux/arch/ppc/kernel/misc.S 2004-06-10 21:09:10.000000000 +0900
-@@ -860,9 +860,9 @@
-
- /*
- * Create a kernel thread
-- * kernel_thread(fn, arg, flags)
-+ * arch_kernel_thread(fn, arg, flags)
- */
--_GLOBAL(kernel_thread)
-+_GLOBAL(arch_kernel_thread)
- mr r6,r3 /* function */
- ori r3,r5,CLONE_VM /* flags */
- li r0,__NR_clone
-diff -Nur linux_c860_org/arch/s390/kernel/process.c linux/arch/s390/kernel/process.c
---- linux_c860_org/arch/s390/kernel/process.c 2002-08-26 14:39:56.000000000 +0900
-+++ linux/arch/s390/kernel/process.c 2004-06-10 21:09:10.000000000 +0900
-@@ -93,7 +93,7 @@
- show_trace((unsigned long *) regs->gprs[15]);
- }
-
--int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
- {
- int clone_arg = flags | CLONE_VM;
- int retval;
-diff -Nur linux_c860_org/arch/s390x/kernel/process.c linux/arch/s390x/kernel/process.c
---- linux_c860_org/arch/s390x/kernel/process.c 2002-08-26 14:39:59.000000000 +0900
-+++ linux/arch/s390x/kernel/process.c 2004-06-10 21:09:10.000000000 +0900
-@@ -93,7 +93,7 @@
- show_trace((unsigned long *) regs->gprs[15]);
- }
-
--int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
- {
- int clone_arg = flags | CLONE_VM;
- int retval;
-diff -Nur linux_c860_org/arch/sh/config.in linux/arch/sh/config.in
---- linux_c860_org/arch/sh/config.in 2002-08-26 14:45:40.000000000 +0900
-+++ linux/arch/sh/config.in 2004-06-10 21:09:10.000000000 +0900
-@@ -125,6 +125,8 @@
- hex 'Physical memory start address' CONFIG_MEMORY_START 08000000
- hex 'Physical memory size' CONFIG_MEMORY_SIZE 00400000
- fi
-+bool 'Preemptible Kernel' CONFIG_PREEMPT
-+dep_bool 'Break selected locks' CONFIG_LOCK_BREAK $CONFIG_PREEMPT
- endmenu
-
- if [ "$CONFIG_SH_HP690" = "y" ]; then
-diff -Nur linux_c860_org/arch/sh/kernel/entry.S linux/arch/sh/kernel/entry.S
---- linux_c860_org/arch/sh/kernel/entry.S 2002-08-26 14:39:52.000000000 +0900
-+++ linux/arch/sh/kernel/entry.S 2004-06-10 21:09:10.000000000 +0900
-@@ -60,10 +60,18 @@
- /*
- * These are offsets into the task-struct.
- */
--flags = 4
-+preempt_count = 4
- sigpending = 8
- need_resched = 20
- tsk_ptrace = 24
-+flags = 84
-+
-+/*
-+ * These offsets are into irq_stat.
-+ * (Find irq_cpustat_t in asm-sh/hardirq.h)
-+ */
-+local_irq_count = 8
-+local_bh_count = 12
-
- PT_TRACESYS = 0x00000002
- PF_USEDFPU = 0x00100000
-@@ -143,7 +151,7 @@
- mov.l __INV_IMASK, r11; \
- stc sr, r10; \
- and r11, r10; \
-- stc k_g_imask, r11; \
-+ stc k_g_imask, r11; \
- or r11, r10; \
- ldc r10, sr
-
-@@ -304,8 +312,8 @@
- mov.l @(tsk_ptrace,r0), r0 ! Is current PTRACE_SYSCALL'd?
- mov #PT_TRACESYS, r1
- tst r1, r0
-- bt ret_from_syscall
-- bra syscall_ret_trace
-+ bf syscall_ret_trace
-+ bra ret_from_syscall
- nop
-
- .align 2
-@@ -505,8 +513,6 @@
- .long syscall_ret_trace
- __syscall_ret:
- .long syscall_ret
--__INV_IMASK:
-- .long 0xffffff0f ! ~(IMASK)
-
-
- .align 2
-@@ -518,7 +524,84 @@
- .align 2
- 1: .long SYMBOL_NAME(schedule)
-
-+#ifdef CONFIG_PREEMPT
-+ !
-+ ! Returning from interrupt during kernel mode: check if
-+ ! preempt_schedule should be called. If need_resched flag
-+ ! is set, preempt_count is zero, and we're not currently
-+ ! in an interrupt handler (local irq or bottom half) then
-+ ! call preempt_schedule.
-+ !
-+ ! Increment preempt_count to prevent a nested interrupt
-+ ! from reentering preempt_schedule, then decrement after
-+ ! and drop through to regular interrupt return which will
-+ ! jump back and check again in case such an interrupt did
-+ ! come in (and didn't preempt due to preempt_count).
-+ !
-+ ! NOTE: because we just checked that preempt_count was
-+ ! zero before getting to the call, can't we use immediate
-+ ! values (1 and 0) rather than inc/dec? Also, rather than
-+ ! drop through to ret_from_irq, we already know this thread
-+ ! is kernel mode, can't we go direct to ret_from_kirq? In
-+ ! fact, with proper interrupt nesting and so forth could
-+ ! the loop simply be on the need_resched w/o checking the
-+ ! other stuff again? Optimize later...
-+ !
-+ .align 2
-+ret_from_kirq:
-+ ! Nonzero preempt_count prevents scheduling
-+ stc k_current, r1
-+ mov.l @(preempt_count,r1), r0
-+ cmp/eq #0, r0
-+ bf restore_all
-+ ! Zero need_resched prevents scheduling
-+ mov.l @(need_resched,r1), r0
-+ cmp/eq #0, r0
-+ bt restore_all
-+ ! If in_interrupt(), don't schedule
-+ mov.l __irq_stat, r1
-+ mov.l @(local_irq_count,r1), r0
-+ mov.l @(local_bh_count,r1), r1
-+ or r1, r0
-+ cmp/eq #0, r0
-+ bf restore_all
-+ ! Allow scheduling using preempt_schedule
-+ ! Adjust preempt_count and SR as needed.
-+ stc k_current, r1
-+ mov.l @(preempt_count,r1), r0 ! Could replace this ...
-+ add #1, r0 ! ... and this w/mov #1?
-+ mov.l r0, @(preempt_count,r1)
-+ STI()
-+ mov.l __preempt_schedule, r0
-+ jsr @r0
-+ nop
-+ /* CLI */
-+ stc sr, r0
-+ or #0xf0, r0
-+ ldc r0, sr
-+ !
-+ stc k_current, r1
-+ mov.l @(preempt_count,r1), r0 ! Could replace this ...
-+ add #-1, r0 ! ... and this w/mov #0?
-+ mov.l r0, @(preempt_count,r1)
-+ ! Maybe should bra ret_from_kirq, or loop over need_resched?
-+ ! For now, fall through to ret_from_irq again...
-+#endif /* CONFIG_PREEMPT */
-+
- ret_from_irq:
-+ mov #OFF_SR, r0
-+ mov.l @(r0,r15), r0 ! get status register
-+ shll r0
-+ shll r0 ! kernel space?
-+#ifndef CONFIG_PREEMPT
-+ bt restore_all ! Yes, it's from kernel, go back soon
-+#else /* CONFIG_PREEMPT */
-+ bt ret_from_kirq ! From kernel: maybe preempt_schedule
-+#endif /* CONFIG_PREEMPT */
-+ !
-+ bra ret_from_syscall
-+ nop
-+
- ret_from_exception:
- mov #OFF_SR, r0
- mov.l @(r0,r15), r0 ! get status register
-@@ -564,6 +647,13 @@
- .long SYMBOL_NAME(do_signal)
- __irq_stat:
- .long SYMBOL_NAME(irq_stat)
-+#ifdef CONFIG_PREEMPT
-+__preempt_schedule:
-+ .long SYMBOL_NAME(preempt_schedule)
-+#endif /* CONFIG_PREEMPT */
-+__INV_IMASK:
-+ .long 0xffffff0f ! ~(IMASK)
-+
-
- .align 2
- restore_all:
-@@ -679,7 +769,7 @@
- __fpu_prepare_fd:
- .long SYMBOL_NAME(fpu_prepare_fd)
- __init_task_flags:
-- .long SYMBOL_NAME(init_task_union)+4
-+ .long SYMBOL_NAME(init_task_union)+flags
- __PF_USEDFPU:
- .long PF_USEDFPU
- #endif
-diff -Nur linux_c860_org/arch/sh/kernel/irq.c linux/arch/sh/kernel/irq.c
---- linux_c860_org/arch/sh/kernel/irq.c 2002-08-26 14:39:52.000000000 +0900
-+++ linux/arch/sh/kernel/irq.c 2004-06-10 21:09:10.000000000 +0900
-@@ -229,6 +229,14 @@
- struct irqaction * action;
- unsigned int status;
-
-+ /*
-+ * At this point we're now about to actually call handlers,
-+ * and interrupts might get reenabled during them... bump
-+ * preempt_count to prevent any preemption while the handler
-+ * called here is pending...
-+ */
-+ preempt_disable();
-+
- /* Get IRQ number */
- asm volatile("stc r2_bank, %0\n\t"
- "shlr2 %0\n\t"
-@@ -298,8 +306,17 @@
- desc->handler->end(irq);
- spin_unlock(&desc->lock);
-
-+
- if (softirq_pending(cpu))
- do_softirq();
-+
-+ /*
-+ * We're done with the handlers, interrupts should be
-+ * currently disabled; decrement preempt_count now so
-+ * as we return preemption may be allowed...
-+ */
-+ preempt_enable_no_resched();
-+
- return 1;
- }
-
-diff -Nur linux_c860_org/arch/sh/kernel/process.c linux/arch/sh/kernel/process.c
---- linux_c860_org/arch/sh/kernel/process.c 2002-08-26 14:39:52.000000000 +0900
-+++ linux/arch/sh/kernel/process.c 2004-06-10 21:09:10.000000000 +0900
-@@ -118,7 +118,7 @@
- * This is the mechanism for creating a new kernel thread.
- *
- */
--int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
- { /* Don't use this in BL=1(cli). Or else, CPU resets! */
- register unsigned long __sc0 __asm__ ("r0");
- register unsigned long __sc3 __asm__ ("r3") = __NR_clone;
-diff -Nur linux_c860_org/arch/sparc/kernel/process.c linux/arch/sparc/kernel/process.c
---- linux_c860_org/arch/sparc/kernel/process.c 2002-08-26 14:39:35.000000000 +0900
-+++ linux/arch/sparc/kernel/process.c 2004-06-10 21:09:10.000000000 +0900
-@@ -657,7 +657,7 @@
- * a system call from a "real" process, but the process memory space will
- * not be free'd until both the parent and the child have exited.
- */
--pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-+pid_t arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
- {
- long retval;
-
-diff -Nur linux_c860_org/arch/sparc64/kernel/process.c linux/arch/sparc64/kernel/process.c
---- linux_c860_org/arch/sparc64/kernel/process.c 2002-08-26 14:39:47.000000000 +0900
-+++ linux/arch/sparc64/kernel/process.c 2004-06-10 21:09:10.000000000 +0900
-@@ -661,7 +661,7 @@
- * a system call from a "real" process, but the process memory space will
- * not be free'd until both the parent and the child have exited.
- */
--pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-+pid_t arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
- {
- long retval;
-
-diff -Nur linux_c860_org/drivers/acorn/char/i2c.c linux/drivers/acorn/char/i2c.c
---- linux_c860_org/drivers/acorn/char/i2c.c 2002-08-26 14:45:01.000000000 +0900
-+++ linux/drivers/acorn/char/i2c.c 2004-06-10 21:09:10.000000000 +0900
-@@ -166,6 +166,7 @@
- break;
-
- case RTC_RD_TIME:
-+ memset(&rtctm, 0, sizeof(struct rtc_time));
- get_rtc_time(&rtc_raw, &year);
- rtctm.tm_sec = rtc_raw.secs;
- rtctm.tm_min = rtc_raw.mins;
-diff -Nur linux_c860_org/drivers/block/Config.in linux/drivers/block/Config.in
---- linux_c860_org/drivers/block/Config.in 2003-11-07 11:46:57.000000000 +0900
-+++ linux/drivers/block/Config.in 2004-06-10 21:09:10.000000000 +0900
-@@ -37,7 +37,6 @@
- dep_tristate 'Compaq Smart Array 5xxx support' CONFIG_BLK_CPQ_CISS_DA $CONFIG_PCI
- dep_tristate 'Mylex DAC960/DAC1100 PCI RAID Controller support' CONFIG_BLK_DEV_DAC960 $CONFIG_PCI
-
--
- tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
- dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
-
-diff -Nur linux_c860_org/drivers/char/Config.in linux/drivers/char/Config.in
---- linux_c860_org/drivers/char/Config.in 2002-08-29 12:25:54.000000000 +0900
-+++ linux/drivers/char/Config.in 2004-06-10 21:09:10.000000000 +0900
-@@ -17,10 +17,26 @@
- fi
- if [ "$CONFIG_SABINAL_DISCOVERY" = "y" -o \
- "$CONFIG_ARCH_PXA_POODLE" = "y" -o \
-- "$CONFIG_ARCH_PXA_CORGI" = "y" ]; then
-+ "$CONFIG_ARCH_PXA_CORGI" = "y" -o \
-+ "$CONFIG_ARCH_PXA_TOSA" = "y" ]; then
- bool ' SL-series serial port support' CONFIG_SERIAL_SL_SERIES
- fi
-+ if [ "$CONFIG_SABINAL_DISCOVERY" = "y" -o \
-+ "$CONFIG_ARCH_PXA_POODLE" = "y" -o \
-+ "$CONFIG_ARCH_PXA_CORGI" = "y" ]; then
-+ bool ' SL-series touchscreen pressure value read (EXPERIMENTAL)' CONFIG_SL_TS_PRESSURE
-+ dep_bool ' Boot On touchscreen pressure value read' CONFIG_BOOT_PRESSURE_ON $CONFIG_SL_TS_PRESSURE
-+ bool ' SL-C Series power key suspend (EXPERIMENTAL)' CONFIG_SL7X0_POWER_KEY_OFF
-+ dep_bool ' Boot On power key suspend' CONFIG_BOOT_POWER_KEY_OFF $CONFIG_SL7X0_POWER_KEY_OFF
-+ bool ' SL-C Series 3 Button touch screen (EXPERIMENTAL)' CONFIG_SL_3BUTTON_PATCH
-+ dep_bool ' Boot On 3 Button touch screen' CONFIG_BOOT_3BUTTON_PATCH_ON $CONFIG_SL_3BUTTON_PATCH
-+ bool ' SL-series write ts data (EXPERIMENTAL)' CONFIG_SL_WRITE_TS
-+ fi
-+ if [ "$CONFIG_SERIAL_SL_SERIES" = "y" ]; then
-+ bool ' SL-series Bluetooth support' CONFIG_BLUETOOTH_SL
-+ fi
- fi
-+bool 'Use Keyboard device file (EXPERIMENTAL)' CONFIG_KBD_DEV_FILE
- if [ "$CONFIG_SA1100_COLLIE" = "y" ]; then
- bool 'COLLIE serial port support' CONFIG_SERIAL_COLLIE
- dep_bool ' Console on COLLIE serial port' CONFIG_SERIAL_COLLIE_CONSOLE $CONFIG_SERIAL_COLLIE
-@@ -216,6 +232,7 @@
- if [ "$CONFIG_ARCH_SHARP_SL" = "y" ]; then
- tristate 'Cotulla Real Time Clock' CONFIG_COTULLA_RTC
- tristate 'ADS7846 Touch Pannel' CONFIG_ADS7846_TS
-+ tristate 'Tosa Touch Pannel' CONFIG_TOSA_TS
- fi
- if [ "$CONFIG_SABINAL_DISCOVERY" = "y" ]; then
- tristate 'Discovery LED ' CONFIG_DISCOVERY_LED $(CONFIG_SABINAL_DISCOVERY)
-diff -Nur linux_c860_org/drivers/char/Makefile linux/drivers/char/Makefile
---- linux_c860_org/drivers/char/Makefile 2002-10-11 21:13:44.000000000 +0900
-+++ linux/drivers/char/Makefile 2004-06-10 21:09:10.000000000 +0900
-@@ -12,7 +12,8 @@
- #
- # This file contains the font map for the default (hardware) font
- #
--FONTMAPFILE = cp437.uni
-+#FONTMAPFILE = cp437.uni
-+FONTMAPFILE = direct.uni
-
- O_TARGET := char.o
-
-@@ -114,6 +115,11 @@
- KEYMAP := corgi_keymap.o
- # SERIAL =
- endif
-+ ifeq ($(CONFIG_ARCH_PXA_TOSA),y)
-+ KEYBD := tosa_keyb.o tosa_logkey.o
-+ KEYMAP := tosa_keymap.o
-+# SERIAL =
-+ endif
- endif
-
- ifeq ($(ARCH),sh)
-@@ -232,6 +238,9 @@
- obj-$(CONFIG_DISCOVERY_LED) += sharp_led.o discovery_led.o
- obj-$(CONFIG_ARCH_PXA_POODLE) += sharp_led.o sharp_kbdctl.o sharpsl_led.o sharp_buzzer.o
- obj-$(CONFIG_ARCH_PXA_CORGI) += sharp_led.o sharpsl_led.o sharp_kbdctl.o corgi_rc.o sharp_buzzer.o
-+obj-$(CONFIG_ARCH_PXA_TOSA) += sharp_led.o sharpsl_led.o sharp_kbdctl.o
-+obj-$(CONFIG_BUZZER_TOSA) += sharp_buzzer.o
-+
- obj-$(CONFIG_BUSMOUSE) += busmouse.o
- obj-$(CONFIG_DTLK) += dtlk.o
- obj-$(CONFIG_R3964) += n_r3964.o
-@@ -248,6 +257,7 @@
- obj-$(CONFIG_SA1100_RTC) += sa1100-rtc.o
- obj-$(CONFIG_COTULLA_RTC) += cotulla-rtc.o
- obj-$(CONFIG_ADS7846_TS) += ads7846_ts.o
-+obj-$(CONFIG_TOSA_TS) += tosa_ts.o
- ifeq ($(CONFIG_PPC),)
- obj-$(CONFIG_NVRAM) += nvram.o
- endif
-@@ -340,3 +350,7 @@
-
- corgi_keymap.c: corgi_keymap.map
- set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@
-+
-+tosa_keymap.c: tosa_keymap.map
-+ set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@
-+
-diff -Nur linux_c860_org/drivers/char/ads7846_ts.c linux/drivers/char/ads7846_ts.c
---- linux_c860_org/drivers/char/ads7846_ts.c 2003-06-18 16:12:26.000000000 +0900
-+++ linux/drivers/char/ads7846_ts.c 2004-06-10 21:09:10.000000000 +0900
-@@ -14,6 +14,7 @@
- * 31-Jul-2002 Lineo Japan, Inc. for ARCH_PXA
- * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
- * 27-Feb-2003 Sharp modified for Poodle
-+ * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
- *
- */
-
-@@ -85,7 +86,56 @@
- static DECLARE_WAIT_QUEUE_HEAD(queue);
- static int head, tail, sample;
- static char pendown = 0;
--unsigned long Pressure;
-+static unsigned long Pressure;
-+#if defined(CONFIG_SL_TS_PRESSURE) || defined(CONFIG_SL7X0_POWER_KEY_OFF) || \
-+ defined(CONFIG_SL_3BUTTON_PATCH) || defined(CONFIG_SL_WRITE_TS)
-+#include <linux/proc_fs.h>
-+#endif
-+
-+#if defined(CONFIG_SL_TS_PRESSURE)
-+static unsigned long tsPressure;
-+#if defined(CONFIG_BOOT_PRESSURE_ON)
-+static unsigned int tspressure_mode = 1;
-+#else
-+static unsigned int tspressure_mode = 0;
-+#endif
-+
-+static ssize_t tspressure_read_params(struct file *file, char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ char outputbuf[32];
-+ int count;
-+
-+ if (*ppos>0) /* Assume reading completed in previous read*/
-+ return 0;
-+ count = sprintf(outputbuf, "%d\n", (unsigned int)tspressure_mode);
-+ count++;
-+ *ppos += count;
-+ if (count>nbytes) /* Assume output can be read at one time */
-+ return -EINVAL;
-+ if (copy_to_user(buf, outputbuf, count+1))
-+ return -EFAULT;
-+ return count;
-+}
-+
-+static ssize_t tspressure_write_params(struct file *file, const char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ unsigned int param=0;
-+
-+ sscanf(buf,"%d",&param);
-+ if (tspressure_mode != param) {
-+ tspressure_mode = param;
-+ printk("tspressure = %d\n", tspressure_mode);
-+ }
-+ return nbytes;
-+}
-+
-+static struct file_operations proc_tspressure_operations = {
-+ read: tspressure_read_params,
-+ write: tspressure_write_params,
-+};
-+#endif
- #if defined(CONFIG_ARCH_PXA_CORGI)
- static char ispass = 1;
- #endif
-@@ -97,6 +147,88 @@
- static char PowerDownMode = PMPD_MODE_ACTIVE;
- #endif // CONFIG_PM
- #endif
-+
-+#if defined(CONFIG_SL7X0_POWER_KEY_OFF)
-+extern unsigned int power_key_off_mode;
-+
-+static ssize_t power_key_off_read_params(struct file *file, char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ char outputbuf[32];
-+ int count;
-+
-+ if (*ppos>0) /* Assume reading completed in previous read*/
-+ return 0;
-+ count = sprintf(outputbuf, "%d\n", (unsigned int)power_key_off_mode);
-+ count++;
-+ *ppos += count;
-+ if (count>nbytes) /* Assume output can be read at one time */
-+ return -EINVAL;
-+ if (copy_to_user(buf, outputbuf, count+1))
-+ return -EFAULT;
-+ return count;
-+}
-+
-+static ssize_t power_key_off_write_params(struct file *file, const char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ unsigned int param=0;
-+
-+ sscanf(buf,"%d",&param);
-+ if (power_key_off_mode != param) {
-+ power_key_off_mode = param;
-+ printk("power_key_off = %d\n", power_key_off_mode);
-+ }
-+ return nbytes;
-+}
-+
-+static struct file_operations proc_power_key_off_operations = {
-+ read: power_key_off_read_params,
-+ write: power_key_off_write_params,
-+};
-+#endif
-+
-+#if defined(CONFIG_SL_3BUTTON_PATCH)
-+extern int pressure_alt;
-+extern unsigned int three_button_mode;
-+
-+static ssize_t three_button_read_params(struct file *file, char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ char outputbuf[32];
-+ int count;
-+
-+ if (*ppos>0) /* Assume reading completed in previous read*/
-+ return 0;
-+ count = sprintf(outputbuf, "%d\n", (unsigned int)three_button_mode);
-+ count++;
-+ *ppos += count;
-+ if (count>nbytes) /* Assume output can be read at one time */
-+ return -EINVAL;
-+ if (copy_to_user(buf, outputbuf, count+1))
-+ return -EFAULT;
-+ return count;
-+}
-+
-+static ssize_t three_button_write_params(struct file *file, const char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ unsigned int param=0;
-+
-+ sscanf(buf,"%d",&param);
-+ if (three_button_mode != param) {
-+ three_button_mode = param;
-+ printk("three_button = %d\n", three_button_mode);
-+ }
-+ return nbytes;
-+}
-+
-+static struct file_operations proc_three_button_operations = {
-+ read: three_button_read_params,
-+ write: three_button_write_params,
-+};
-+#endif
-+
- //extern unsigned short touch_panel_intr;
-
- #if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-@@ -147,7 +279,7 @@
-
- //#define WAIT_AFTER_SYNC_HS 151 /* 41us */
- //#define WAIT_AFTER_SYNC_HS 142 /* 38.5us */
--static unsigned long wait_after_sync_hs = 0;
-+static long wait_after_sync_hs = 0;
- #define WAIT_AFTER_SYNC_HS wait_after_sync_hs
- #define SyncHS() while((GPLR(GPIO_HSYNC) & GPIO_bit(GPIO_HSYNC)) == 0);\
- while((GPLR(GPIO_HSYNC) & GPIO_bit(GPIO_HSYNC)) != 0);
-@@ -157,20 +289,35 @@
- #if 1
- #define WAIT_HS_333_VGA 5791 // 17.995us
- #define WAIT_HS_400_VGA 7013 // 17.615us
-+#define WAIT_HS_471_VGA 8257 // 17.615us
-+#define WAIT_HS_400_VGA_FASTSYSCLK 5260 // 17.615us
-+#define WAIT_HS_471_VGA_FASTSYSCLK 6192 // 17.615us
-+
-+#define WAIT_HS_400_VGA640 21376 // 17.615us
-+#define WAIT_HS_471_VGA640 25170 // 17.615us
-+#define WAIT_HS_400_VGA640_FASTSYSCLK 16032 // 17.615us
-+#define WAIT_HS_471_VGA640_FASTSYSCLK 18878 // 17.615us
-+
-+
- #define WAIT_HS_333_QVGA 13969 // 42.100us
- #define WAIT_HS_400_QVGA 16621 // 41.750us
-+#define WAIT_HS_471_QVGA 19571 // 41.750us
-+
- #else
- #define WAIT_HS_333_VGA 6403 // 19.3us
- #define WAIT_HS_400_VGA 7683 // 19.3us
- #define WAIT_HS_333_QVGA 13935 // 42.0us
- #define WAIT_HS_400_QVGA 16720 // 42.0us
-+
- #endif
- #define LCD_MODE_480 0
- #define LCD_MODE_320 1
- #define LCD_MODE_240 2
-+#define LCD_MODE_640 3
- extern int w100fb_lcdMode;
- extern int w100fb_isblank;
- extern unsigned long cccr_reg;
-+extern int fastsysclk_mode;
-
- static int sync_receive_data_send_cmd(int doRecive,int doSend,int sCmd)
- {
-@@ -195,21 +342,54 @@
- // 332MHz
- if (w100fb_lcdMode == LCD_MODE_480) {
- wait_time = WAIT_HS_333_VGA - wait_after_sync_hs;
-- }
-- else {
-+ }else {
- wait_time = WAIT_HS_333_QVGA - wait_after_sync_hs;
- }
-- }
-- else {
-- // 400MHz
-- if (w100fb_lcdMode == LCD_MODE_480) {
-- wait_time = WAIT_HS_400_VGA - wait_after_sync_hs;
-+ }else if(cccr_reg == 0x242 || cccr_reg == 0x162) {
-+
-+ // 471MHz
-+ if (fastsysclk_mode == 100 ){
-+ if (w100fb_lcdMode == LCD_MODE_480) {
-+ wait_time = WAIT_HS_471_VGA_FASTSYSCLK - wait_after_sync_hs;
-+ }else if(w100fb_lcdMode == LCD_MODE_640){
-+ wait_time = WAIT_HS_471_VGA640_FASTSYSCLK - wait_after_sync_hs;
-+ }else {
-+ wait_time = WAIT_HS_471_QVGA - wait_after_sync_hs;
-+ }
-+ }else {
-+ if (w100fb_lcdMode == LCD_MODE_480) {
-+ wait_time = WAIT_HS_471_VGA - wait_after_sync_hs;
-+ }else if(w100fb_lcdMode == LCD_MODE_640){
-+ wait_time = WAIT_HS_471_VGA640 - wait_after_sync_hs;
-+ }else {
-+ wait_time = WAIT_HS_471_QVGA - wait_after_sync_hs;
-+ }
- }
-- else {
-- wait_time = WAIT_HS_400_QVGA - wait_after_sync_hs;
-+
-+ }else {
-+
-+ // 400MHz
-+ if (fastsysclk_mode == 100 ){
-+ if (w100fb_lcdMode == LCD_MODE_480) {
-+ wait_time = WAIT_HS_400_VGA_FASTSYSCLK - wait_after_sync_hs;
-+ }else if(w100fb_lcdMode == LCD_MODE_640){
-+ wait_time = WAIT_HS_400_VGA640_FASTSYSCLK - wait_after_sync_hs;
-+ }else {
-+ wait_time = WAIT_HS_400_QVGA - wait_after_sync_hs;
-+ }
-+ }else {
-+ if (w100fb_lcdMode == LCD_MODE_480) {
-+ wait_time = WAIT_HS_400_VGA - wait_after_sync_hs;
-+ }else if(w100fb_lcdMode == LCD_MODE_640){
-+ wait_time = WAIT_HS_400_VGA640 - wait_after_sync_hs;
-+ }else {
-+ wait_time = WAIT_HS_400_QVGA - wait_after_sync_hs;
-+ }
- }
- }
-
-+
-+
- CCNT_ON();
-
- /* polling HSync */
-@@ -229,7 +409,7 @@
-
- /* Wait after HSync */
- CCNT(timer2);
-- if (w100fb_lcdMode != LCD_MODE_480) {
-+ if ((w100fb_lcdMode != LCD_MODE_480) && (w100fb_lcdMode != LCD_MODE_640)) {
- while((timer2-timer1) < wait_time){
- CCNT(timer2);
- }
-@@ -324,7 +504,11 @@
- ((int)((x)-(y))<(int)(d)) && \
- ((int)((y)-(x))<(int)(d)) )
- unsigned long cmd;
-+#if defined(CONFIG_SL_TS_PRESSURE)
-+ unsigned int t,x,y,z[2],z2,dummy;
-+#else
- unsigned int t,x,y,z[2];
-+#endif
- int i,j,k;
- int d = 8, c = 10;
- int err = 0;
-@@ -335,7 +519,18 @@
- (3u << ADSCTRL_ADR_SH) | (1u << ADSCTRL_STS_SH);
- t = ads7846_rw(cmd);
- z[i] = ads7846_rw(cmd);
--
-+
-+#if defined(CONFIG_SL_TS_PRESSURE)
-+ if (tspressure_mode) {
-+ /* Z2 */
-+ cmd = (1u << ADSCTRL_PD0_SH) | (1u << ADSCTRL_PD1_SH) |
-+ (4u << ADSCTRL_ADR_SH) | (1u << ADSCTRL_STS_SH);
-+ dummy = ads7846_rw(cmd);
-+ udelay(1);
-+ z2 = ads7846_rw(cmd);
-+ }
-+#endif
-+
- if( i ) break;
-
- /* X-axis */
-@@ -369,6 +564,10 @@
- }
- }
- Pressure = 1;
-+#if defined(CONFIG_SL_TS_PRESSURE)
-+ if (tspressure_mode)
-+ if (z[1]) tsPressure = (15000 - x * (z2 - z[1]) / z[1]) >> 4;
-+#endif
- for(i=0;i<2;i++){
- if( !z[i] )
- Pressure = 0;
-@@ -482,12 +681,19 @@
-
- // printk("x=%d,y=%d\n",tp->xd,tp->yd);
-
-- if (z1 != 0)
-+ if (z1 != 0) {
- Pressure = Rx * (tp->xd) * ((10*z2/z1) - 1*10) >> 10;
-- else
-+#if defined(CONFIG_SL_TS_PRESSURE)
-+ if (tspressure_mode)
-+ tsPressure = (15000 - x[3] * (z2 - z1) / z1) >> 4;
-+ }
-+#endif
-+ else
-+#if defined(CONFIG_SL_TS_PRESSURE)
-+ tsPressure = Pressure = 0;
-+#else
- Pressure = 0;
--
--
-+#endif
- cmd = (1u << ADSCTRL_PD0_SH) | (1u << ADSCTRL_PD1_SH) |
- (4u << ADSCTRL_ADR_SH) | (1u << ADSCTRL_STS_SH);
- /* Power-Down Enable */
-@@ -566,11 +772,25 @@
- // printk("fail %d\n", fail);
-
- if (fail == TOUCH_PANEL_AVERAGE) {
-+#if defined(CONFIG_SL_TS_PRESSURE)
-+ tsPressure = Pressure = 0;
-+#else
- Pressure = 0;
-+#endif
- // printk("pen up\n");
- }
- else {
-+#if defined(CONFIG_SL_TS_PRESSURE)
-+ if (tspressure_mode) {
-+ if (z1) {
-+ tsPressure = Pressure = (15000 - x * (z2 - z1) / z1) >> 4;
-+ } else
-+ tsPressure = Pressure = 0;
-+ } else
-+ tsPressure = Pressure = 1;
-+#else
- Pressure = 1;
-+#endif
- tp->xd = tx / (TOUCH_PANEL_AVERAGE - fail);
- tp->yd = ty / (TOUCH_PANEL_AVERAGE - fail);
- // printk("pen position (%d,%d)\n", tx, ty);
-@@ -742,7 +962,11 @@
-
- static void new_data(void)
- {
-+#if !defined(CONFIG_ARCH_PXA_CORGI) && !defined(CONFIG_ARCH_PXA_POODLE)
-+#if !defined(CONFIG_POODLE_TR0)
- int diff0, diff1, diff2, diff3;
-+#endif
-+#endif
-
- #ifdef CONFIG_PM
- if( PowerDownMode != PMPD_MODE_ACTIVE )
-@@ -862,6 +1086,25 @@
- }
- #endif
-
-+/// write ts data
-+#if defined(CONFIG_SL_WRITE_TS)
-+static void write_new_data(TS_EVENT write_data)
-+{
-+ write_data.millisecs = jiffies;
-+ tbuf[head++] = write_data;
-+
-+ if (head >= BUFSIZE) { head = 0; }
-+
-+ if (head == tail && ++tail >= BUFSIZE) { tail = 0; }
-+
-+ if (fasync)
-+ kill_fasync(&fasync, SIGIO, POLL_IN);
-+
-+ wake_up_interruptible(&queue);
-+}
-+#endif
-+
-+
- static void cotulla_main_ts_timer(unsigned long irq)
- {
- // ts_interrupt(irq, NULL, NULL);
-@@ -896,6 +1139,7 @@
- // printk("!(%d,%d)",pos_dt.xd,pos_dt.yd);
- tc.x = pos_dt.xd;
- tc.y = pos_dt.yd;
-+
- #if defined(CONFIG_ARCH_PXA_POODLE)
- lock_FCS(POWER_MODE_TOUCH, 1); // not enter FCS mode.
- #if defined(CONFIG_POODLE_TR0)
-@@ -907,11 +1151,53 @@
- tc.pressure = 500;
- #elif defined(CONFIG_ARCH_PXA_CORGI)
- if( pos_dt.xd && pos_dt.yd && Pressure ) {
-+#if defined(CONFIG_SL_3BUTTON_PATCH)
-+ if (three_button_mode) {
-+ switch (pressure_alt) {
-+ case 0x00:
-+ tc.pressure = 500;
-+ break;
-+ case 0x01:
-+ tc.pressure = 1000;
-+ break;
-+ case 0x02:
-+ tc.pressure = 2000;
-+ break;
-+ default:
-+#if defined(CONFIG_SL_TS_PRESSURE)
-+ if (tspressure_mode)
-+ tc.pressure = Pressure;
-+ else
-+ tc.pressure = 500;
-+#else
-+ tc.pressure = 500;
-+#endif
-+ break;
-+ }
-+
-+ /* printk("pressure = %d \n",tc.pressure); */
-+ } else
-+#endif
-+#if defined(CONFIG_SL_TS_PRESSURE)
-+ if (tspressure_mode)
-+ tc.pressure = Pressure;
-+ else
-+ tc.pressure = 500;
-+#else
- tc.pressure = 500;
-+#endif
-+
- #else
- if( pos_dt.xd && pos_dt.yd ){
-+#if defined(CONFIG_SL_TS_PRESSURE)
-+ if (tspressure_mode)
-+ tc.pressure = Pressure;
-+ else
-+ tc.pressure = 1;
-+#else
- tc.pressure = 1;
- #endif
-+#endif
- before_data = tc;
- pendown = 1;
- new_data();
-@@ -956,7 +1242,37 @@
- static void ts_hardware_init(void)
- {
- unsigned int dummy;
-+
-+#if defined(CONFIG_SL_TS_PRESSURE)
-+ struct proc_dir_entry *tspressure_proc;
-+#endif
-+
-+#if defined(CONFIG_SL_3BUTTON_PATCH)
-+ struct proc_dir_entry *three_button_proc;
-+#endif
-+
-+#if defined(CONFIG_SL7X0_POWER_KEY_OFF)
-+ struct proc_dir_entry *power_key_off_proc;
-+#endif
-+
-+#if defined(CONFIG_SL_TS_PRESSURE)
-+ tspressure_proc = create_proc_entry("tspressure", 0, NULL);
-+ if (tspressure_proc)
-+ tspressure_proc->proc_fops = &proc_tspressure_operations;
-+#endif
-
-+#if defined(CONFIG_SL_3BUTTON_PATCH)
-+ three_button_proc = create_proc_entry("three_button", 0, NULL);
-+ if (three_button_proc)
-+ three_button_proc->proc_fops = &proc_three_button_operations;
-+#endif
-+
-+#if defined(CONFIG_SL7X0_POWER_KEY_OFF)
-+ power_key_off_proc = create_proc_entry("power_key_off", 0, NULL);
-+ if (power_key_off_proc)
-+ power_key_off_proc->proc_fops = &proc_power_key_off_operations;
-+#endif
-+
- #if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
- pxa_ssp_init();
- #else
-@@ -1043,6 +1359,7 @@
- y_rev = 0;
- xyswap = 1;
- #else
-+#ifdef CONFIG_FBCON_ROTATE_R
- res_x = 480;
- res_y = 640;
-
-@@ -1050,7 +1367,17 @@
- x_rev = 1;
- y_rev = 0;
- xyswap = 1;
-+#else
-+ res_x = 640;
-+ res_y = 480;
-+
-+ cal_ok = 1;
-+ x_rev = 0;
-+ y_rev = 0;
-+ xyswap = 0;
-+#endif
- #endif
-+
- #else
- #ifdef USE_SL5500_QT
- res_x = 240;
-@@ -1170,7 +1497,6 @@
-
- r.pressure = t.pressure;
- r.millisecs = t.millisecs;
-- //printk("ts:ts_read(x, y, p) = (%d, %d, %d)\n", (unsigned int)r.x, (unsigned int)r.y, (unsigned int)r.pressure);
-
- copy_to_user(buffer,&r,sizeof(TS_EVENT));
- }
-@@ -1180,10 +1506,54 @@
- static ssize_t ts_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
- {
- #if defined(CONFIG_ARCH_PXA_CORGI)
-- unsigned long param;
- char *endp;
-- wait_after_sync_hs = simple_strtoul(buffer, &endp, 0);
-+#if defined(CONFIG_SL_WRITE_TS)
-+
-+ static TS_EVENT data, raw_data;
-+ char tmp[50];
-+ int len;
-+ len=49;
-+ if(len>count) len=count;
-+ copy_from_user(tmp,buffer,len);
-+ tmp[len]='\0';
-+
-+ if (sscanf(tmp,"%d %d %d %d",&data.pressure, &data.x, &data.y, &data.millisecs) == 4) {
-+// printk("pressure= %d : x= %d : y= %d : millosecs= %d\n", data.pressure, data.x, data.y, data.millisecs);
-+
-+ if (cal_ok) {
-+ raw_data.x = (x_rev) ? raw_max_x - ((raw_max_x - raw_min_x) * data.x) / res_x
-+ : raw_min_x + ((raw_max_x - raw_min_x) * data.x) / res_x;
-+
-+ raw_data.y = (y_rev) ? raw_max_y - ((raw_max_y - raw_min_y) * data.y) / res_y
-+ : raw_min_y + ((raw_max_y - raw_min_y) * data.y) / res_y;
-+
-+ } else {
-+ raw_data.x = data.x;
-+ raw_data.y = data.y;
-+ }
-+
-+ if (xyswap) {
-+ short tmp = raw_data.x;
-+ raw_data.x = raw_data.y;
-+ raw_data.y = tmp;
-+ }
-+
-+ raw_data.pressure = data.pressure;
-+ raw_data.millisecs = data.millisecs;
-+
-+ write_new_data(raw_data);
-+ return count;
-+
-+ }else {
-+#endif
-+ wait_after_sync_hs = simple_strtol(buffer, &endp, 0);
-+ printk("Wait_after_sync_hs: %d\n",(int) wait_after_sync_hs);
- return count+endp-buffer;
-+
-+#if defined(CONFIG_SL_WRITE_TS)
-+ }
-+#endif
-+
- #else
- return 0;
- #endif
-@@ -1234,6 +1604,13 @@
- case 17: /* Clear all buffer data */
- print_par();
- break;
-+#if defined(CONFIG_SL_TS_PRESSURE)
-+ case 64: /* read Pressure */
-+ if (tspressure_mode) {
-+ copy_to_user((void *)arg, &tsPressure, sizeof(tsPressure));
-+ break;
-+ }
-+#endif
- default:
- return -EINVAL;
- }
-diff -Nur linux_c860_org/drivers/char/console.c linux/drivers/char/console.c
---- linux_c860_org/drivers/char/console.c 2002-12-18 19:27:56.000000000 +0900
-+++ linux/drivers/char/console.c 2004-06-10 21:09:10.000000000 +0900
-@@ -94,6 +94,11 @@
- #include <linux/slab.h>
- #include <linux/major.h>
- #include <linux/mm.h>
-+
-+#ifdef CONFIG_UNICON
-+#include <linux/fb_doublebyte.h>
-+#endif
-+
- #include <linux/console.h>
- #include <linux/init.h>
- #include <linux/devfs_fs_kernel.h>
-@@ -118,7 +123,10 @@
-
- #include "console_macros.h"
-
--
-+#ifdef CONFIG_UNICON
-+#define video_erase_char_ext ((video_erase_char)&0xff)
-+extern unsigned short translations[][256];
-+#endif
- const struct consw *conswitchp;
-
- /* A bitmap for codes <32. A bit of 1 indicates that the code
-@@ -244,6 +252,20 @@
- p = sw->con_screen_pos(vc_cons[currcons].d, offset);
- return p;
- }
-+#ifdef CONFIG_UNICON
-+static inline unsigned short *screenpos_ext(int currcons, int offset, int viewed)
-+{
-+ unsigned short *p;
-+
-+ if (!viewed)
-+ p = (unsigned short *)(origin + offset + screenbuf_size);
-+ else if (!sw->con_screen_pos)
-+ p = (unsigned short *)(visible_origin + offset + screenbuf_size);
-+ else
-+ p = sw->con_screen_pos(vc_cons[currcons].d, -offset-1);
-+ return p;
-+}
-+#endif
-
- static inline void scrolldelta(int lines)
- {
-@@ -270,6 +292,14 @@
- s = (unsigned short *) (origin+video_size_row*(t+nr));
- scr_memcpyw(d, s, (b-t-nr) * video_size_row);
- scr_memsetw(d + (b-t-nr) * video_num_columns, video_erase_char, video_size_row*nr);
-+
-+#ifdef CONFIG_UNICON
-+ d += (screenbuf_size>>1);
-+ s += (screenbuf_size>>1);
-+ scr_memcpyw(d, s, (b-t-nr) * video_size_row);
-+ scr_memsetw(d + (b-t-nr) * video_num_columns, video_erase_char_ext, video_size_row*nr);
-+#endif
-+
- }
-
- static void
-@@ -288,6 +318,11 @@
- step = video_num_columns * nr;
- scr_memmovew(s + step, s, (b-t-nr)*video_size_row);
- scr_memsetw(s, video_erase_char, 2*step);
-+#ifdef CONFIG_UNICON
-+ s += (screenbuf_size>>1);
-+ scr_memmovew(s + step, s, (b-t-nr)*video_size_row);
-+ scr_memsetw(s, video_erase_char_ext, 2*step);
-+#endif
- }
-
- static void do_update_region(int currcons, unsigned long start, int count)
-@@ -311,6 +346,10 @@
- int startx = xx;
- u16 *q = p;
- while (xx < video_num_columns && count) {
-+#ifdef CONFIG_UNICON
-+ //line by line, so the following putcs will be assured to
-+ //handle only in-line string.
-+#endif
- if (attrib != (scr_readw(p) & 0xff00)) {
- if (p > q)
- sw->con_putcs(vc_cons[currcons].d, q, p-q, yy, startx);
-@@ -440,6 +479,39 @@
- }
-
- /* used by selection: complement pointer position */
-+#ifdef CONFIG_UNICON
-+void complement_pos(int currcons, int offset)
-+{
-+ static unsigned short *p = NULL;
-+ static unsigned short old = 0;
-+ static unsigned short oldx = 0, oldy = 0;
-+ static unsigned short *p_ext = NULL;
-+ static unsigned short old_ext = 0;
-+
-+ if (p) {
-+ scr_writew(old, p);
-+ //scr_writew(old_ext, p_ext);
-+ if (DO_UPDATE)
-+ sw->con_putc(vc_cons[currcons].d, (old_ext<<16)| old, oldy, oldx);
-+ }
-+ if (offset == -1)
-+ p = NULL;
-+ else {
-+ unsigned short new;
-+ p = screenpos(currcons, offset, 1);
-+ p_ext = screenpos_ext(currcons, offset, 1);
-+ old = scr_readw(p);
-+ old_ext = scr_readw(p_ext);
-+ new = old ^ complement_mask;
-+ scr_writew(new, p);
-+ if (DO_UPDATE) {
-+ oldx = (offset >> 1) % video_num_columns;
-+ oldy = (offset >> 1) / video_num_columns;
-+ sw->con_putc(vc_cons[currcons].d, (old_ext<<16) | new, oldy, oldx);
-+ }
-+ }
-+}
-+#else
- void complement_pos(int currcons, int offset)
- {
- static unsigned short *p;
-@@ -466,15 +538,23 @@
- }
- }
- }
--
-+#endif
- static void insert_char(int currcons, unsigned int nr)
- {
- unsigned short *p, *q = (unsigned short *) pos;
-
- p = q + video_num_columns - nr - x;
-- while (--p >= q)
-+ while (--p >= q) {
- scr_writew(scr_readw(p), p + nr);
-+#ifdef CONFIG_UNICON
-+ scr_writew(scr_readw(p+(screenbuf_size>>1)),p+(screenbuf_size>>1)+nr);
-+#endif
-+ }
- scr_memsetw(q, video_erase_char, nr*2);
-+#ifdef CONFIG_UNICON
-+ scr_memsetw(q+(screenbuf_size>>1),video_erase_char_ext,nr*2);
-+#endif
-+
- need_wrap = 0;
- if (DO_UPDATE) {
- unsigned short oldattr = attr;
-@@ -482,8 +562,9 @@
- video_num_columns-x-nr);
- attr = video_erase_char >> 8;
- while (nr--)
-- sw->con_putc(vc_cons[currcons].d,
-+ sw->con_putc(vc_cons[currcons].d,
- video_erase_char,y,x+nr);
-+
- attr = oldattr;
- }
- }
-@@ -492,12 +573,17 @@
- {
- unsigned int i = x;
- unsigned short *p = (unsigned short *) pos;
--
- while (++i <= video_num_columns - nr) {
- scr_writew(scr_readw(p+nr), p);
-+#ifdef CONFIG_UNICON
-+ scr_writew(scr_readw(p+nr+(screenbuf_size>>1)),p+(screenbuf_size>>1));
-+#endif
- p++;
- }
- scr_memsetw(p, video_erase_char, nr*2);
-+#ifdef CONFIG_UNICON
-+ scr_memsetw(p+(screenbuf_size>>1), video_erase_char_ext, nr*2);
-+#endif
- need_wrap = 0;
- if (DO_UPDATE) {
- unsigned short oldattr = attr;
-@@ -506,8 +592,8 @@
- attr = video_erase_char >> 8;
- while (nr--)
- sw->con_putc(vc_cons[currcons].d,
-- video_erase_char, y,
-- video_num_columns-1-nr);
-+ video_erase_char, y,
-+ video_num_columns-1-nr);
- attr = oldattr;
- }
- }
-@@ -528,7 +614,11 @@
- if ((type & 0x40) && ((i & 0x700) == ((i & 0x7000) >> 4))) i ^= 0x0700;
- scr_writew(i, (u16 *) pos);
- if (DO_UPDATE)
-+#ifndef CONFIG_UNICON
- sw->con_putc(vc_cons[currcons].d, i, y, x);
-+#else
-+ sw->con_putc(vc_cons[currcons].d, scr_readw((u16 *) pos+ (screenbuf_size>>1))<<16 | (i & 0xffff), y, x);
-+#endif
- }
-
- static void hide_cursor(int currcons)
-@@ -538,7 +628,11 @@
- if (softcursor_original != -1) {
- scr_writew(softcursor_original,(u16 *) pos);
- if (DO_UPDATE)
-+#ifndef CONFIG_UNICON
- sw->con_putc(vc_cons[currcons].d, softcursor_original, y, x);
-+#else
-+ sw->con_putc(vc_cons[currcons].d, scr_readw((u16 *) pos+ (screenbuf_size>>1))<<16 | softcursor_original, y, x);
-+#endif
- softcursor_original = -1;
- }
- sw->con_cursor(vc_cons[currcons].d,CM_ERASE);
-@@ -685,7 +779,11 @@
- visual_init(currcons, 1);
- if (!*vc_cons[currcons].d->vc_uni_pagedir_loc)
- con_set_default_unimap(currcons);
-+#ifndef CONFIG_UNICON
- q = (long)kmalloc(screenbuf_size, GFP_KERNEL);
-+#else
-+ q = (long)kmalloc(screenbuf_size*2,GFP_KERNEL);
-+#endif
- if (!q) {
- kfree((char *) p);
- vc_cons[currcons].d = NULL;
-@@ -727,7 +825,11 @@
- (cc == video_num_columns && ll == video_num_lines))
- newscreens[currcons] = NULL;
- else {
-+#ifndef CONFIG_UNICON
- unsigned short *p = (unsigned short *) kmalloc(ss, GFP_USER);
-+#else
-+ unsigned short *p = (unsigned short *) kmalloc(ss*2, GFP_USER);
-+#endif
- if (!p) {
- for (i = first; i< currcons; i++)
- if (newscreens[i])
-@@ -769,13 +871,23 @@
-
- while (ol < scr_end) {
- scr_memcpyw((unsigned short *) nl, (unsigned short *) ol, rlth);
-+#ifdef CONFIG_UNICON
-+ scr_memcpyw((unsigned short *) (nl + ss), (unsigned short*) (ol + oss), rlth);
-+#endif
- if (rrem)
- scr_memsetw((void *)(nl + rlth), video_erase_char, rrem);
-+#ifdef CONFIG_UNICON
-+ if (rrem)
-+ scr_memsetw((void *)(nl + rlth + ss), video_erase_char_ext, rrem);
-+#endif
- ol += osr;
- nl += sr;
- }
- if (nlend > nl)
- scr_memsetw((void *) nl, video_erase_char, nlend - nl);
-+#ifdef CONFIG_UNICON
-+ scr_memsetw((void *) (nl + ss), video_erase_char_ext, nlend - nl);
-+#endif
- if (kmalloced)
- kfree(screenbuf);
- screenbuf = newscreens[currcons];
-@@ -998,6 +1110,9 @@
- return;
- }
- scr_memsetw(start, video_erase_char, 2*count);
-+#ifdef CONFIG_UNICON
-+ scr_memsetw(start + (screenbuf_size>>1), video_erase_char_ext, 2*count);
-+#endif
- need_wrap = 0;
- }
-
-@@ -1032,6 +1147,9 @@
- return;
- }
- scr_memsetw(start, video_erase_char, 2 * count);
-+#ifdef CONFIG_UNICON
-+ scr_memsetw(start + (screenbuf_size>>1), video_erase_char_ext, 2*count);
-+#endif
- need_wrap = 0;
- }
-
-@@ -1044,6 +1162,9 @@
- count = (vpar > video_num_columns-x) ? (video_num_columns-x) : vpar;
-
- scr_memsetw((unsigned short *) pos, video_erase_char, 2 * count);
-+#ifdef CONFIG_UNICON
-+ scr_memsetw((unsigned short *) pos + (screenbuf_size>>1), video_erase_char_ext, 2*count);
-+#endif
- if (DO_UPDATE)
- sw->con_clear(vc_cons[currcons].d, y, x, 1, count);
- need_wrap = 0;
-@@ -1720,7 +1841,12 @@
- if (ques) {
- clear_selection();
- if (par[0])
-+#ifndef CONFIG_UNICON
- complement_mask = par[0]<<8 | par[1];
-+#else
-+ // force the low byte to be zero
-+ complement_mask = par[0]<<8;
-+#endif
- else
- complement_mask = s_complement_mask;
- return 0;
-@@ -1966,6 +2092,11 @@
- const unsigned char *orig_buf;
- int orig_count;
-
-+#ifdef CONFIG_UNICON
-+#define GB_LEFT 0x8000
-+#define GB_RIGHT 0xc000
-+#endif
-+
- if (in_interrupt())
- return count;
-
-@@ -2076,6 +2207,56 @@
- ((attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
- (attr << 8) + tc,
- (u16 *) pos);
-+#ifdef CONFIG_UNICON
-+#define HIGH_WORD ((u16 *) ((long)pos + screenbuf_size))
-+#define HIGH_WORD_PREV ((u16 *) ((long)pos - 2 + screenbuf_size))
-+#define HIGH_WORD_NEXT ((u16 *) ((long)pos + 2 + screenbuf_size))
-+ /*
-+ * following condiction we do not tread the char as
-+ * double byte.
-+ * 1. default encoding is NULL. The encode module not
-+ * install yet.
-+ * 2. Current char set is not the default one. We are
-+ * possible drawing a table lines right now.
-+ * -Chris
-+ */
-+
-+ if (doublebyte_default && translate == translations[0]
-+ && (pos==origin||!(scr_readw(HIGH_WORD_PREV)&DB_HALF_MASK))
-+ && doublebyte_default->is_left(tc)){
-+ /*possible the left char of the Double Byte
-+ , but we don't know yet, because the right
-+ char is unknow right now. So mark it as
-+ Half char, the possible candidate
-+ -Chris
-+ */
-+ scr_writew(DB_HALF_MASK,HIGH_WORD);
-+
-+ } else if(doublebyte_default&& translate == translations
-+ && scr_readw(HIGH_WORD_PREV)==DB_HALF_MASK
-+ && doublebyte_default->is_right(tc)) {
-+ scr_writew(DB_LEFT|(tc & 0xff),HIGH_WORD_PREV);
-+ scr_writew(DB_RIGHT|(scr_readw((u16*)(pos-2))&0xff),HIGH_WORD);
-+ if (DO_UPDATE && draw_x < 0) {
-+ draw_from = pos-2 ;
-+ if (x>0) {
-+ draw_x = x-1;
-+ } else {
-+ draw_to = pos;
-+ draw_x = video_num_columns -1;
-+ y--;
-+ FLUSH
-+ y++;
-+ draw_x = 0;
-+ draw_from = pos;
-+ }
-+ }
-+ } else {
-+ /*normal ASCII or table lines, clean hight byte*/
-+ scr_writew(0,HIGH_WORD);
-+ }
-+
-+#endif
- if (DO_UPDATE && draw_x < 0) {
- draw_x = x;
- draw_from = pos;
-@@ -2234,6 +2415,9 @@
- continue;
- }
- scr_writew((attr << 8) + c, (unsigned short *) pos);
-+#ifdef CONFIG_UNICON
-+ scr_writew(0,(unsigned short *) pos + (screenbuf_size>>1));
-+#endif
- cnt++;
- if (myx == video_num_columns - 1) {
- need_wrap = 1;
-@@ -2591,7 +2775,11 @@
- vt_cons[currcons] = (struct vt_struct *)
- alloc_bootmem(sizeof(struct vt_struct));
- visual_init(currcons, 1);
-+#ifdef CONFIG_UNICON
-+ screenbuf = (unsigned short *) alloc_bootmem(screenbuf_size * 2);
-+#else
- screenbuf = (unsigned short *) alloc_bootmem(screenbuf_size);
-+#endif
- kmalloced = 0;
- vc_init(currcons, video_num_lines, video_num_columns,
- currcons || !sw->con_save_screen);
-@@ -3064,7 +3252,12 @@
- gotoxy(currcons, p[0], p[1]);
- set_cursor(currcons);
- }
--
-+#ifdef CONFIG_UNICON
-+/*
-+Now, the unicon doesn't support vcs!
-+To support it, first change the vc_screen.c!
-+*/
-+#endif
- u16 vcs_scr_readw(int currcons, const u16 *org)
- {
- if ((unsigned long)org == pos && softcursor_original != -1)
-@@ -3106,6 +3299,15 @@
- /*
- * Visible symbols for modules
- */
-+#ifdef CONFIG_UNICON
-+int (*Unicon_fnKeyHook)
-+ (struct tty_struct *tty, unsigned char ch, char flag) = NULL;
-+int (*Unicon_fnLowerKeyHook) (unsigned char ch) = NULL;
-+
-+EXPORT_SYMBOL(Unicon_fnLowerKeyHook);
-+EXPORT_SYMBOL(Unicon_fnKeyHook);
-+EXPORT_SYMBOL(vc_cons);
-+#endif
-
- EXPORT_SYMBOL(color_table);
- EXPORT_SYMBOL(default_red);
-diff -Nur linux_c860_org/drivers/char/consolemap.c linux/drivers/char/consolemap.c
---- linux_c860_org/drivers/char/consolemap.c 2002-08-26 14:38:30.000000000 +0900
-+++ linux/drivers/char/consolemap.c 2004-06-10 21:09:10.000000000 +0900
-@@ -22,7 +22,11 @@
- #include <linux/console_struct.h>
- #include <linux/vt_kern.h>
-
-+#ifndef CONFIG_UNICON
- static unsigned short translations[][256] = {
-+#else
-+unsigned short translations[][256] = {
-+#endif
- /* 8-bit Latin-1 mapped to Unicode -- trivial mapping */
- {
- 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
-diff -Nur linux_c860_org/drivers/char/corgi_logkey.c linux/drivers/char/corgi_logkey.c
---- linux_c860_org/drivers/char/corgi_logkey.c 2003-06-18 16:12:26.000000000 +0900
-+++ linux/drivers/char/corgi_logkey.c 2004-06-10 21:09:10.000000000 +0900
-@@ -605,6 +605,7 @@
-
- #if CHECK_ROLLOVER
- #define MAX_KEY_PRESS (6)
-+#define MAX_KEY_PRESS_THRESHOLD (6 + 1)
- #endif
-
- void sharppda_scan_key_gpio(void* dummy)
-@@ -707,8 +708,8 @@
- if (ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_FUNCTION)) {
- rollover_count--;
- }
-- if ((rollover_count > 3) ||
-- ((rollover_count == 3) &&
-+ if ((rollover_count > MAX_KEY_PRESS_THRESHOLD) ||
-+ ((rollover_count == MAX_KEY_PRESS_THRESHOLD) &&
- (!ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_TAB) ||
- ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_DIRECT_ON)) &&
- (!ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_VERTICAL) ||
-diff -Nur linux_c860_org/drivers/char/direct.uni linux/drivers/char/direct.uni
---- linux_c860_org/drivers/char/direct.uni 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/char/direct.uni 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,259 @@
-+0x00 U+0000
-+0x20 U+0020
-+0x21 U+0021
-+0x22 U+0022
-+0x23 U+0023
-+0x24 U+0024
-+0x25 U+0025
-+0x26 U+0026
-+0x27 U+0027
-+0x28 U+0028
-+0x29 U+0029
-+0x2a U+002a
-+0x2b U+002b
-+0x2c U+002c
-+0x2d U+002d
-+0x2e U+002e
-+0x2f U+002f
-+0x30 U+0030
-+0x31 U+0031
-+0x32 U+0032
-+0x33 U+0033
-+0x34 U+0034
-+0x35 U+0035
-+0x36 U+0036
-+0x37 U+0037
-+0x38 U+0038
-+0x39 U+0039
-+0x3a U+003a
-+0x3b U+003b
-+0x3c U+003c
-+0x3d U+003d
-+0x3e U+003e
-+0x3f U+003f
-+0x40 U+0040
-+0x41 U+0041
-+0x42 U+0042
-+0x43 U+0043
-+0x44 U+0044
-+0x45 U+0045
-+0x46 U+0046
-+0x47 U+0047
-+0x48 U+0048
-+0x49 U+0049
-+0x4a U+004a
-+0x4b U+004b
-+0x4c U+004c
-+0x4d U+004d
-+0x4e U+004e
-+0x4f U+004f
-+0x50 U+0050
-+0x51 U+0051
-+0x52 U+0052
-+0x53 U+0053
-+0x54 U+0054
-+0x55 U+0055
-+0x56 U+0056
-+0x57 U+0057
-+0x58 U+0058
-+0x59 U+0059
-+0x5a U+005a
-+0x5b U+005b
-+0x5c U+005c
-+0x5d U+005d
-+0x5e U+005e
-+0x5f U+005f
-+0x60 U+0060
-+0x61 U+0061
-+0x62 U+0062
-+0x63 U+0063
-+0x64 U+0064
-+0x65 U+0065
-+0x66 U+0066
-+0x67 U+0067
-+0x68 U+0068
-+0x69 U+0069
-+0x6a U+006a
-+0x6b U+006b
-+0x6c U+006c
-+0x6d U+006d
-+0x6e U+006e
-+0x6f U+006f
-+0x70 U+0070
-+0x71 U+0071
-+0x72 U+0072
-+0x73 U+0073
-+0x74 U+0074
-+0x75 U+0075
-+0x76 U+0076
-+0x77 U+0077
-+0x78 U+0078
-+0x79 U+0079
-+0x7a U+007a
-+0x7b U+007b
-+0x7c U+007c
-+0x7d U+007d
-+0x7e U+007e
-+0x7f U+007f
-+0x80 U+0080
-+0x81 U+0081
-+0x82 U+0082
-+0x83 U+0083
-+0x84 U+0084
-+0x85 U+0085
-+0x86 U+0086
-+0x87 U+0087
-+0x88 U+0088
-+0x89 U+0089
-+0x8a U+008a
-+0x8b U+008b
-+0x8c U+008c
-+0x8d U+008d
-+0x8e U+008e
-+0x8f U+008f
-+0x90 U+0090
-+0x91 U+0091
-+0x92 U+0092
-+0x93 U+0093
-+0x94 U+0094
-+0x95 U+0095
-+0x96 U+0096
-+0x97 U+0097
-+0x98 U+0098
-+0x99 U+0099
-+0x9a U+009a
-+0x9b U+009b
-+0x9c U+009c
-+0x9d U+009d
-+0x9e U+009e
-+0x9f U+009f
-+0xa0 U+00a0
-+0xa1 U+00a1
-+0xa2 U+00a2
-+0xa3 U+00a3
-+0xa4 U+00a4
-+0xa5 U+00a5
-+0xa6 U+00a6
-+0xa7 U+00a7
-+0xa8 U+00a8
-+0xa9 U+00a9
-+0xaa U+00aa
-+0xab U+00ab
-+0xac U+00ac
-+0xad U+00ad
-+0xae U+00ae
-+0xaf U+00af
-+0xb0 U+00b0
-+0xb1 U+00b1
-+0xb2 U+00b2
-+0xb3 U+00b3
-+0xb4 U+00b4
-+0xb5 U+00b5
-+0xb6 U+00b6
-+0xb7 U+00b7
-+0xb8 U+00b8
-+0xb9 U+00b9
-+0xba U+00ba
-+0xbb U+00bb
-+0xbc U+00bc
-+0xbd U+00bd
-+0xbe U+00be
-+0xbf U+00bf
-+0xc0 U+00c0
-+0xc1 U+00c1
-+0xc2 U+00c2
-+0xc3 U+00c3
-+0xc4 U+00c4
-+0xc5 U+00c5
-+0xc6 U+00c6
-+0xc7 U+00c7
-+0xc8 U+00c8
-+0xc9 U+00c9
-+0xca U+00ca
-+0xcb U+00cb
-+0xcc U+00cc
-+0xcd U+00cd
-+0xce U+00ce
-+0xcf U+00cf
-+0xd0 U+00d0
-+0xd1 U+00d1
-+0xd2 U+00d2
-+0xd3 U+00d3
-+0xd4 U+00d4
-+0xd5 U+00d5
-+0xd6 U+00d6
-+0xd7 U+00d7
-+0xd8 U+00d8
-+0xd9 U+00d9
-+0xda U+00da
-+0xdb U+00db
-+0xdc U+00dc
-+0xdd U+00dd
-+0xde U+00de
-+0xdf U+00df
-+0xe0 U+00e0
-+0xe1 U+00e1
-+0xe2 U+00e2
-+0xe3 U+00e3
-+0xe4 U+00e4
-+0xe5 U+00e5
-+0xe6 U+00e6
-+0xe7 U+00e7
-+0xe8 U+00e8
-+0xe9 U+00e9
-+0xea U+00ea
-+0xeb U+00eb
-+0xec U+00ec
-+0xed U+00ed
-+0xee U+00ee
-+0xef U+00ef
-+0xf0 U+00f0
-+0xf1 U+00f1
-+0xf2 U+00f2
-+0xf3 U+00f3
-+0xf4 U+00f4
-+0xf5 U+00f5
-+0xf6 U+00f6
-+0xf7 U+00f7
-+0xf8 U+00f8
-+0xf9 U+00f9
-+0xfa U+00fa
-+0xfb U+00fb
-+0xfc U+00fc
-+0xfd U+00fd
-+0xfe U+00fe
-+0xff U+00ff
-+0x07 U+2022
-+0x13 U+203c
-+0x4b U+212a
-+0x1b U+2190
-+0x18 U+2191
-+0x1a U+2192
-+0x19 U+2193
-+0x1d U+2194
-+0x12 U+2195
-+0x17 U+21a8
-+0x1c U+221f
-+0x16 U+25ac
-+0x1e U+25b2
-+0x10 U+25b6
-+0x10 U+25ba
-+0x1f U+25bc
-+0x11 U+25c0
-+0x11 U+25c4
-+0x04 U+25c6
-+0x09 U+25cb
-+0x08 U+25d8
-+0x0a U+25d9
-+0x01 U+263a
-+0x02 U+263b
-+0x0f U+263c
-+0x0c U+2640
-+0x0b U+2642
-+0x06 U+2660
-+0x05 U+2663
-+0x03 U+2665
-+0x04 U+2666
-+0x0d U+266a
-+0x0e U+266b
-+0x5f U+f804
-diff -Nur linux_c860_org/drivers/char/efirtc.c linux/drivers/char/efirtc.c
---- linux_c860_org/drivers/char/efirtc.c 2002-08-26 14:38:31.000000000 +0900
-+++ linux/drivers/char/efirtc.c 2004-06-10 21:09:10.000000000 +0900
-@@ -118,6 +118,7 @@
- static void
- convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime)
- {
-+ memset(wtime, 0, sizeof(struct rtc_time));
- wtime->tm_sec = eft->second;
- wtime->tm_min = eft->minute;
- wtime->tm_hour = eft->hour;
-diff -Nur linux_c860_org/drivers/char/keyboard.c linux/drivers/char/keyboard.c
---- linux_c860_org/drivers/char/keyboard.c 2002-12-18 19:27:58.000000000 +0900
-+++ linux/drivers/char/keyboard.c 2004-06-10 21:09:10.000000000 +0900
-@@ -40,6 +40,7 @@
-
- #include <asm/keyboard.h>
- #include <asm/bitops.h>
-+#include <asm/uaccess.h>
-
- #include <linux/kbd_kern.h>
- #include <linux/kbd_diacr.h>
-@@ -118,6 +119,23 @@
- static struct kbd_struct * kbd = kbd_table;
- static struct tty_struct * tty;
-
-+#if defined(CONFIG_SL7X0_POWER_KEY_OFF)
-+#if defined(CONFIG_BOOT_POWER_KEY_OFF)
-+unsigned int power_key_off_mode = 1;
-+#else
-+unsigned int power_key_off_mode = 0;
-+#endif
-+#endif
-+
-+#if defined(CONFIG_SL_3BUTTON_PATCH)
-+#if defined(CONFIG_BOOT_3BUTTON_PATCH_ON)
-+unsigned int three_button_mode = 1;
-+#else
-+unsigned int three_button_mode = 0;
-+#endif
-+int pressure_alt;
-+#endif
-+
- static void kbd_processkeycode(unsigned char scancode, char up_flag, int autorepeat);
- void compute_shiftstate(void);
-
-@@ -179,6 +197,8 @@
-
- static struct pm_dev *pm_kbd;
-
-+
-+
- /*
- * Many other routines do put_queue, but I think either
- * they produce ASCII, or they produce some user-assigned
-@@ -224,6 +244,55 @@
-
- void handle_scancode(unsigned char scancode, int down)
- {
-+
-+#if defined(CONFIG_SL7X0_POWER_KEY_OFF)
-+ /* printk("scancode = %x down = %x \n",scancode,down); */
-+ /* SL-C700 side power 0x6d */
-+ if ( power_key_off_mode && ( scancode == 0x6d ) && ( down == 0x01 ) ){
-+
-+ printk("power button\n");
-+ slc7x0_key_suspend();
-+
-+
-+ /* SL-C700 Calender down 0x58 */
-+ } else
-+#endif
-+#if defined(CONFIG_SL_3BUTTON_PATCH)
-+ if ( three_button_mode && ( scancode == 0x59 ) && ( down == 0x01 ) ){
-+
-+ pressure_alt=0x01;
-+ handle_scancode_main ( scancode, down );
-+
-+ /* SL-C700 Calender up 0xd8 */
-+ } else if ( three_button_mode && ( scancode == 0xd9 ) && ( down == 0x00 ) ){
-+
-+ pressure_alt=0x00;
-+ handle_scancode_main ( scancode, down );
-+
-+ /* SL-C700 Address down 0x59 */
-+ } else if ( three_button_mode && ( scancode == 0x28 ) && ( down == 0x01 ) ){
-+
-+ pressure_alt=0x02;
-+ handle_scancode_main ( scancode, down );
-+
-+ /* SL-C700 Address up 0xd9 */
-+ } else if ( three_button_mode && ( scancode == 0xa8 ) && ( down == 0x00 ) ){
-+
-+ pressure_alt=0x00;
-+ handle_scancode_main ( scancode, down );
-+ } else
-+#endif
-+#if defined(CONFIG_SL7X0_POWER_KEY_OFF) || defined(CONFIG_SL_3BUTTON_PATCH)
-+ {
-+
-+ handle_scancode_main ( scancode, down );
-+
-+ }
-+}
-+
-+void handle_scancode_main(unsigned char scancode, int down)
-+{
-+#endif
- unsigned char keycode;
- char up_flag = down ? 0 : 0200;
- char raw_mode;
-@@ -274,8 +343,8 @@
- static void
- kbd_processkeycode(unsigned char keycode, char up_flag, int autorepeat)
- {
-- char raw_mode = (kbd->kbdmode == VC_RAW);
-
-+ char raw_mode = (kbd->kbdmode == VC_RAW);
- if (up_flag) {
- rep = 0;
- if(!test_and_clear_bit(keycode, key_down))
-@@ -1020,12 +1089,35 @@
-
- pm_callback pm_kbd_request_override = NULL;
-
-+#if defined(CONFIG_KBD_DEV_FILE)
-+#define KBD_MAJOR 241
-+struct fasync_struct *fasync_kbd;
-+
-+static int kbd_open(struct inode *, struct file *);
-+static int kbd_release(struct inode *, struct file *);
-+static int kbd_fasync(int fd, struct file *filp, int on);
-+static ssize_t kbd_read(struct file *, char *, size_t, loff_t *);
-+static ssize_t kbd_write(struct file *, const char *, size_t, loff_t *);
-+
-+struct file_operations kbd_fops = {
-+ open: kbd_open,
-+ release: kbd_release,
-+ fasync: kbd_fasync,
-+ read: kbd_read,
-+ write: kbd_write,
-+};
-+#endif
-+
- int __init kbd_init(void)
- {
- int i;
- struct kbd_struct kbd0;
- extern struct tty_driver console_driver;
-
-+#if defined(CONFIG_KBD_DEV_FILE)
-+ if ( register_chrdev(KBD_MAJOR,"kbd",&kbd_fops) )
-+ printk("unable to get major %d for keyboard\n", KBD_MAJOR);
-+#endif
- kbd0.ledflagstate = kbd0.default_ledflagstate = KBD_DEFLEDS;
- kbd0.ledmode = LED_SHOW_FLAGS;
- kbd0.lockstate = KBD_DEFLOCK;
-@@ -1047,3 +1139,56 @@
-
- return 0;
- }
-+
-+#if defined(CONFIG_KBD_DEV_FILE)
-+static int kbd_open(struct inode *inode, struct file *file)
-+{
-+ kdev_t dev = inode->i_rdev;
-+
-+ return 0;
-+}
-+
-+
-+static int kbd_release(struct inode *inode, struct file *file)
-+{
-+ kbd_fasync(-1, file, 0);
-+ return 0;
-+}
-+
-+static int kbd_fasync(int fd, struct file *filp, int on)
-+{
-+ int retval;
-+
-+ retval = fasync_helper(fd, filp, on, &fasync_kbd);
-+ if (retval < 0)
-+ return retval;
-+ return 0;
-+}
-+
-+static ssize_t kbd_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
-+{
-+// printk("kbd read\n");
-+ return 0;
-+}
-+
-+static ssize_t kbd_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
-+{
-+ char tmp[50];
-+ int len;
-+ int kbd_scancode,kbd_down;
-+
-+ len=49;
-+
-+ if(len>count) len=count;
-+ copy_from_user(tmp,buffer,len);
-+ tmp[len]='\0';
-+
-+ if (sscanf(tmp,"%d %d",&kbd_scancode, &kbd_down) == 2) {
-+// printk("kbd write %02x %02x\n",kbd_scancode,kbd_down);
-+ handle_scancode(kbd_scancode,kbd_down);
-+ }
-+
-+// printk("kbd write\n");
-+ return count;
-+}
-+#endif
-diff -Nur linux_c860_org/drivers/char/mem.c linux/drivers/char/mem.c
---- linux_c860_org/drivers/char/mem.c 2002-08-26 14:44:15.000000000 +0900
-+++ linux/drivers/char/mem.c 2004-06-10 21:09:10.000000000 +0900
-@@ -397,7 +397,7 @@
- if (count > size)
- count = size;
-
-- zap_page_range(mm, addr, count);
-+ zap_page_range(mm, addr, count, ZPR_NORMAL);
- zeromap_page_range(addr, count, PAGE_COPY);
-
- size -= count;
-diff -Nur linux_c860_org/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c
---- linux_c860_org/drivers/char/pc_keyb.c 2002-08-26 14:38:31.000000000 +0900
-+++ linux/drivers/char/pc_keyb.c 2004-06-10 21:09:10.000000000 +0900
-@@ -464,14 +464,36 @@
-
- static unsigned char kbd_exists = 1;
-
--static inline void handle_keyboard_event(unsigned char scancode)
-+#ifdef CONFIG_UNICON
-+extern int (*Unicon_fnLowerKeyHook) (unsigned char ch);
-+extern int (*Unicon_fnKeyHook) (struct tty_struct *tty, \
-+ unsigned char ch, char flag);
-+#endif
-+static inline int handle_keyboard_event(unsigned char scancode)
- {
- #ifdef CONFIG_VT
- kbd_exists = 1;
-- if (do_acknowledge(scancode))
-- handle_scancode(scancode, !(scancode & 0x80));
-+ if (do_acknowledge(scancode)){
-+#ifdef CONFIG_UNICON
-+ if (Unicon_fnLowerKeyHook != NULL){
-+ /* return 1 ==> processed by kernel
-+ return 0 ==> processed by app */
-+ if (scancode == 0x58){ /* F12 kill unicode */
-+ Unicon_fnKeyHook = NULL;
-+ Unicon_fnLowerKeyHook = NULL;
-+ return 1;
-+ }
-+ if ((*Unicon_fnLowerKeyHook) (scancode) == 1)
-+ return 1;
-+ else
-+ handle_scancode(scancode,!(scancode & 0x80));
-+ } else
-+#endif
-+ handle_scancode(scancode, !(scancode & 0x80));
-+ }
- #endif
- tasklet_schedule(&keyboard_tasklet);
-+ return 0;
- }
-
- /*
-@@ -501,7 +523,8 @@
- if (status & KBD_STAT_MOUSE_OBF)
- handle_mouse_event(scancode);
- else
-- handle_keyboard_event(scancode);
-+ if(handle_keyboard_event(scancode))
-+ return status;
- }
-
- status = kbd_read_status();
-diff -Nur linux_c860_org/drivers/char/pcmcia/Config.in linux/drivers/char/pcmcia/Config.in
---- linux_c860_org/drivers/char/pcmcia/Config.in 2002-08-26 14:44:23.000000000 +0900
-+++ linux/drivers/char/pcmcia/Config.in 2004-06-10 21:09:10.000000000 +0900
-@@ -5,13 +5,7 @@
- mainmenu_option next_comment
- comment 'PCMCIA character devices'
-
--if [ "$CONFIG_SERIAL" = "y" -o "$CONFIG_SERIAL_8250" = "y" ]; then
-- dep_tristate 'PCMCIA serial device support' CONFIG_PCMCIA_SERIAL_CS y
--else
-- if [ "$CONFIG_SERIAL" = "m" -o "$CONFIG_SERIAL_8250" = "m" ]; then
-- dep_tristate 'PCMCIA serial device support' CONFIG_PCMCIA_SERIAL_CS m
-- fi
--fi
-+dep_tristate 'PCMCIA serial device support' CONFIG_PCMCIA_SERIAL_CS $CONFIG_SERIAL
- if [ "$CONFIG_PCMCIA_SERIAL_CS" = "y" ]; then
- define_bool CONFIG_PCMCIA_CHRDEV y
- fi
-diff -Nur linux_c860_org/drivers/char/rtc.c linux/drivers/char/rtc.c
---- linux_c860_org/drivers/char/rtc.c 2002-08-26 14:38:31.000000000 +0900
-+++ linux/drivers/char/rtc.c 2004-06-10 21:09:10.000000000 +0900
-@@ -326,7 +326,7 @@
- * means "don't care" or "match all". Only the tm_hour,
- * tm_min, and tm_sec values are filled in.
- */
--
-+ memset(&wtime, 0, sizeof(struct rtc_time));
- get_rtc_alm_time(&wtime);
- break;
- }
-@@ -374,6 +374,7 @@
- }
- case RTC_RD_TIME: /* Read the time/date from RTC */
- {
-+ memset(&wtime, 0, sizeof(struct rtc_time));
- get_rtc_time(&wtime);
- break;
- }
-diff -Nur linux_c860_org/drivers/char/serial.c linux/drivers/char/serial.c
---- linux_c860_org/drivers/char/serial.c 2003-01-14 12:07:55.000000000 +0900
-+++ linux/drivers/char/serial.c 2004-06-10 21:09:10.000000000 +0900
-@@ -61,6 +61,7 @@
- * 30-Jul-2002 Lineo Japan, Inc. for 2.4.18
- * 31-Jul-2002 Lineo Japan, Inc. for ARCH_PXA
- * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- static char *serial_version = "5.05c";
-@@ -98,11 +99,14 @@
-
- #include <linux/config.h>
- #include <linux/version.h>
-+
- #if defined(CONFIG_SABINAL_DISCOVERY) || \
- defined(CONFIG_ARCH_PXA_POODLE) || \
-- defined(CONFIG_ARCH_PXA_CORGI)
-+ defined(CONFIG_ARCH_PXA_CORGI) || \
-+ defined(CONFIG_ARCH_PXA_TOSA)
- #undef CONFIG_SERIAL_CONSOLE
- #endif
-+
- #if defined(CONFIG_SABINAL_DISCOVERY)
- #define CONFIG_REDEFINE_IO8BIT
- #endif
-@@ -259,7 +263,8 @@
- #elif defined(CONFIG_SA1100_COLLIE) || \
- defined(CONFIG_SABINAL_DISCOVERY) || \
- defined(CONFIG_ARCH_PXA_POODLE) || \
-- defined(CONFIG_ARCH_PXA_CORGI)
-+ defined(CONFIG_ARCH_PXA_CORGI) || \
-+ defined(CONFIG_ARCH_PXA_TOSA)
- #define SERIAL_DEV_OFFSET 3
- #else
- #define SERIAL_DEV_OFFSET 0
-@@ -1332,7 +1337,7 @@
- #ifdef CONFIG_ARCH_PXA
- if (state->type == PORT_PXA) {
- switch ((long)state->iomem_base) {
--#if defined(CONFIG_ARCH_SHARP_SL) && !defined(CONFIG_SABINAL_DISCOVERY)
-+#if defined(CONFIG_PM) && defined(CONFIG_ARCH_SHARP_SL) && !defined(CONFIG_SABINAL_DISCOVERY)
- case (long)&FFUART: lock_FCS(LOCK_FCS_FFUART, 1); CKEN |= CKEN6_FFUART; break;
- case (long)&BTUART: lock_FCS(LOCK_FCS_BTUART, 1); CKEN |= CKEN7_BTUART; break;
- case (long)&STUART: lock_FCS(LOCK_FCS_STUART, 1); CKEN |= CKEN5_STUART; break;
-@@ -1615,7 +1620,7 @@
- #ifdef CONFIG_ARCH_PXA
- if (state->type == PORT_PXA) {
- switch ((long)state->iomem_base) {
--#if defined(CONFIG_ARCH_SHARP_SL) && !defined(CONFIG_SABINAL_DISCOVERY)
-+#if defined(CONFIG_PM) && defined(CONFIG_ARCH_SHARP_SL) && !defined(CONFIG_SABINAL_DISCOVERY)
- case (long)&FFUART: CKEN &= ~CKEN6_FFUART; lock_FCS(LOCK_FCS_FFUART, 0); break;
- case (long)&BTUART: CKEN &= ~CKEN7_BTUART; lock_FCS(LOCK_FCS_BTUART, 0); break;
- case (long)&STUART: CKEN &= ~CKEN5_STUART; lock_FCS(LOCK_FCS_STUART, 0); break;
-@@ -6103,7 +6108,7 @@
- {
- register_console(&sercons);
- }
--#endif
-+#endif /* CONFIG_SERIAL_CONSOLE */
-
- /*
- Local variables:
-diff -Nur linux_c860_org/drivers/char/serial_pxa200.c linux/drivers/char/serial_pxa200.c
---- linux_c860_org/drivers/char/serial_pxa200.c 2003-01-29 16:14:45.000000000 +0900
-+++ linux/drivers/char/serial_pxa200.c 2004-06-10 21:09:10.000000000 +0900
-@@ -59,6 +59,8 @@
- *
- * Change Log
- * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
-+ * 1-Nov-2003 Sharp Corporation for Tosa
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- static char *serial_version = "5.05c";
-@@ -228,8 +230,9 @@
- #endif
- #ifdef CONFIG_PM
- #include <linux/pm.h>
--#include <linux/apm_bios.h>
- #endif
-+#include <linux/apm_bios.h>
-+#include <asm/sharp_char.h>
-
- /*
- * All of the compatibilty code so we can compile serial.c against
-@@ -414,7 +417,7 @@
-
- #define CONFIG_DISCOVERY_DVT
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- #define CONFIG_SHARPSL_PXA
- #endif
-
-@@ -439,17 +442,24 @@
- #define XPA210_DISCOVERY_IRDA_LINE 1
- #define xpa210_discovery_is_irda_line(line) ((line) == XPA210_DISCOVERY_IRDA_LINE)
-
--void clr_discovery_irda(u8 x){
-+static void clr_discovery_irda(u8 x){
- #if defined(CONFIG_SABINAL_DISCOVERY)
- ASIC3_GPIO_PIOD_B &= ~(0x1000);
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+ reset_scoop_gpio(SCP_IR_POWERDWN);
-+ set_GPIO_mode(GPIO47_STTXD|GPIO_OUT);
-+ GPCR(GPIO47_STTXD) = GPIO_bit(GPIO47_STTXD);
- #elif defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
- GPSR(GPIO_IR_ON) = GPIO_bit(GPIO_IR_ON);
- #endif
- //printk("discovery_irda power on\n");
-- }
--void set_discovery_irda(u8 x){
-+}
-+static void set_discovery_irda(u8 x){
- #if defined(CONFIG_SABINAL_DISCOVERY)
- ASIC3_GPIO_PIOD_B |= 0x1000;
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+ set_GPIO_mode(GPIO47_STTXD_MD);
-+ set_scoop_gpio(SCP_IR_POWERDWN);
- #elif defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
- GPCR(GPIO_IR_ON) = GPIO_bit(GPIO_IR_ON);
- #endif
-@@ -470,14 +480,53 @@
-
- #endif
-
-+#if defined(CONFIG_BLUETOOTH_SL)
-+#define PXA_BLUETOOTH_LINE 2
-+#define pxa_is_bluetooth_line(line) ((line) == PXA_BLUETOOTH_LINE)
-+
-+static int has_bluetooth = -1;
-+static int bluetooth_open = 0;
-+struct async_struct *bluetooth_info = 0;
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+#define AVOID_ROLLBACK
-+#ifdef AVOID_ROLLBACK
-+extern int rollback_cancel;
-+#endif
-+#endif
-+static int pxa_check_bluetooth_unit()
-+{
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ set_GPIO_mode(GPIO42_BTRXD|GPIO_IN);
-+ set_GPIO_mode(GPIO43_BTTXD|GPIO_IN);
-+ set_GPIO_mode(GPIO44_BTCTS|GPIO_IN);
-+ set_GPIO_mode(GPIO45_BTRTS|GPIO_IN);
-+ set_scoop_gpio(SCP_BT_PWR_EN);
-+ mdelay(5);
-+ if ( (GPLR(GPIO42_BTRXD) & GPIO_bit(GPIO42_BTRXD))==0 &&
-+ (GPLR(GPIO44_BTCTS) & GPIO_bit(GPIO44_BTCTS))==0) {
-+ reset_scoop_gpio(SCP_BT_PWR_EN);
-+ has_bluetooth=0;
-+ return 0; // no bluetooth
-+ }
-+ reset_scoop_gpio(SCP_BT_PWR_EN);
-+ has_bluetooth=1;
-+ return 1;
-+#else
-+ return 0;
-+#endif
-+}
-+#endif // end CONFIG_BLUETOOTH_SL
-+
- #ifdef CONFIG_PM
- static struct pm_dev *serial_pm_dev;
- #endif
-
-
--#if (defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI))
-+#if (defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA))
-+#ifdef CONFIG_PM
- extern int change_power_mode(unsigned long,int);
- #endif
-+#endif
-
- /*
- * tmp_buf is used as a temporary buffer by serial_write. We need to
-@@ -544,6 +593,7 @@
- read &= ~UART_MSR_CTS;
- else
- read |= UART_MSR_CTS;
-+
- if ( read & UART_MSR_DSR )
- read &= ~UART_MSR_DSR;
- else
-@@ -633,9 +683,10 @@
- #define STUART_MCR *(volatile unsigned char*)(&STUART + UART_MCR*4)
- #define STUART_ISR *(volatile unsigned char*)(&STUART + 8*4)
-
-+#ifdef CONFIG_PM
- void xpa210_discovery_irda_resume (void) {
-
--#if (defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI))
-+#if (defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA))
- if ( !change_power_mode(LOCK_FCS_STUART, 1) ) return;
- #endif
-
-@@ -652,14 +703,17 @@
- //printk("xpa210_discovery_irda_resume\n");
-
- }
-+#endif
-
- int xpa210_discovery_irda_enable(struct async_struct * info, u8 x){
-
- if (x == 0) {
- CKEN &= ~(0x20); //stuart
-
--#if (defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI))
-+#if (defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA))
-+#ifdef CONFIG_PM
- change_power_mode(LOCK_FCS_STUART, 0);
-+#endif /* CONFIG_PM */
- #endif
-
- info->IER &= ~(UART_IER_UUE);
-@@ -675,8 +729,10 @@
-
- //printk("xpa210_discovery_irda_disable\n");
- } else {
--#if (defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI))
-+#if (defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA))
-+#ifdef CONFIG_PM
- if ( !change_power_mode(LOCK_FCS_STUART, 1) ) return 1;
-+#endif /* CONFIG_PM */
- #endif
-
- CKEN |= 0x20; //stuart
-@@ -696,9 +752,91 @@
- }
- return 0;
- }
-+#endif
-+
-+#if defined(CONFIG_BLUETOOTH_SL)
-+static int pxa_bluetooth_enable(struct async_struct * info, u8 x)
-+{
-+ if (has_bluetooth==0) return -ENODEV;
-+ if (x==0) { // off
-+ set_scoop_gpio(SCP_BT_RESET);
-+ CKEN &= ~(0x1<<7); //btuart
-+ set_GPIO_mode(GPIO42_BTRXD|GPIO_IN);
-+ set_GPIO_mode(GPIO43_BTTXD|GPIO_IN);
-+ set_GPIO_mode(GPIO44_BTCTS|GPIO_IN);
-+ set_GPIO_mode(GPIO45_BTRTS|GPIO_IN);
-+ mdelay(10); // wait 10ms
-+ reset_scoop_gpio(SCP_BT_RESET);
-+ reset_scoop_gpio(SCP_BT_PWR_EN);
-+ set_led_status(SHARP_LED_BLUETOOTH,0); // turn off BT LED
-+
-+ ICMR &= ~(1 << 21); //btuart
-+
-+ info->IER &= ~(UART_IER_UUE);
-+ serial_out(info, UART_IER, info->IER);
-+
-+ info->MCR = 0x0;
-+ serial_out(info, UART_MCR, info->MCR);
-+
-+ info->IER |= UART_IER_UUE; /* enable UUE */
-+ serial_out(info, UART_IER, info->IER);
-+
-+#ifdef CONFIG_PM
-+ change_power_mode(LOCK_FCS_BTUART, 0);
-+#endif /* CONFIG_PM */
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+#ifdef AVOID_ROLLBACK
-+ rollback_cancel = 0;
-+#endif
-+#endif
-+ // printk("bluetooth close success.\n");
-+ } else { // on
-+#ifdef CONFIG_PM
-+ if ( !change_power_mode(LOCK_FCS_BTUART, 1) ) return 1;
-+#endif /* CONFIG_PM */
-+ ICMR &= ~(1 << 21); //btuart
-+ reset_scoop_gpio(SCP_BT_RESET);
-+ set_scoop_gpio(SCP_BT_PWR_EN);
-+
-+ set_GPIO_mode(GPIO42_BTRXD_MD);
-+ set_GPIO_mode(GPIO43_BTTXD_MD);
-+ set_GPIO_mode(GPIO44_BTCTS_MD);
-+ set_GPIO_mode(GPIO45_BTRTS_MD);
-+
-+ CKEN |= (0x1<<7); //btuart
-
-+ info->IER &= ~(UART_IER_UUE);
-+ serial_out(info, UART_IER, info->IER);
-+
-+ info->MCR = UART_MCR_OUT2;
-+ serial_out(info, UART_MCR, info->MCR);
-+
-+ info->tty->termios->c_cflag &= ~CBAUD;
-+ info->tty->termios->c_cflag |= (17 & CBAUD); // set 115.2k
-+ change_speed(info, 0);
-+
-+ info->IER = UART_IER_UUE|UART_IER_RDI|UART_IER_MSI|UART_IER_RTOIE; /* enable UUE */
-+ serial_out(info, UART_IER, info->IER);
-+ serial_inp(info, UART_RX); // reset DR
-+
-+ ICMR |= (1 << 21); //btuart
-+
-+ set_scoop_gpio(SCP_BT_RESET);
-+ mdelay(20); // wait 20ms
-+ reset_scoop_gpio(SCP_BT_RESET);
-+ set_led_status(SHARP_LED_BLUETOOTH,1); // BT LED on
-+
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+#ifdef AVOID_ROLLBACK
-+ rollback_cancel = 1;
-+#endif
- #endif
-
-+ // printk("bluetooth open success.\n");
-+ }
-+ return 0;
-+}
-+#endif
-
- /*
- * For the 16C950
-@@ -824,11 +962,25 @@
-
- icount = &info->state->icount;
-
-+#if defined(CONFIG_BLUETOOTH_SL)
-+ if (xpa2X0_is_st_uart(info->iomem_base) || xpa2X0_is_bt_uart(info->iomem_base)) {
-+#else
- if (xpa2X0_is_st_uart(info->iomem_base)) {
-+#endif
- *status = serial_inp(info, UART_LSR);
- while (!(*status & UART_LSR_DR)) {
- printk("WoWWWW!\n");
- }
-+#if 1 //
-+ if (xpa2X0_is_bt_uart(info->iomem_base)) {
-+ if (*status & UART_LSR_OE) {
-+ printk("ERROR: Bluetooth Overrun!!\n");
-+ }
-+ if (*status & (UART_LSR_PE|UART_LSR_FE|0x80) ) {
-+ printk("ERROR: Bluetooth Error!!\n");
-+ }
-+ }
-+#endif
- }
-
- do {
-@@ -838,7 +990,11 @@
- return; // if TTY_DONT_FLIP is set
- }
-
-+#if defined(CONFIG_BLUETOOTH_SL)
-+ if (xpa2X0_is_st_uart(info->iomem_base) || xpa2X0_is_bt_uart(info->iomem_base)) {
-+#else
- if (xpa2X0_is_st_uart(info->iomem_base)) {
-+#endif
- while (!(*status & UART_LSR_DR))
- ;
- }
-@@ -851,7 +1007,11 @@
- #ifdef SERIAL_DEBUG_INTR
- printk("DR%02x:%02x...", ch, *status);
- #endif
-+#if defined(CONFIG_BLUETOOTH_SL)
-+ if (xpa2X0_is_st_uart(info->iomem_base) || xpa2X0_is_bt_uart(info->iomem_base)) {
-+#else
- if (xpa2X0_is_st_uart(info->iomem_base)) {
-+#endif
- goto IRDA_SKIP;
- }
- *tty->flip.flag_buf_ptr = 0;
-@@ -894,7 +1054,11 @@
- *status &= info->read_status_mask;
-
- #ifdef CONFIG_SERIAL_CONSOLE
-+#if defined(CONFIG_BLUETOOTH_SL)
-+ if (!xpa2X0_is_st_uart(info->iomem_base) && !xpa2X0_is_bt_uart(info->iomem_base)) {
-+#else
- if (!xpa2X0_is_st_uart(info->iomem_base)) {
-+#endif
- if (info->line == sercons.index) {
- /* Recover the break flag from console xmit */
- *status |= lsr_break_flag;
-@@ -996,7 +1160,19 @@
- // udelay(800);
-
- serial_outp(info, XPA2X0_UART_ISR, XPA210_DISCOVERY_IR_RECV);
--
-+#if defined(CONFIG_BLUETOOTH_SL)
-+ } else if (xpa2X0_is_bt_uart(info->iomem_base)) {
-+
-+ while (!(serial_inp(info, UART_LSR) & UART_LSR_TEMT))
-+ ;
-+
-+ info->IER &= ~UART_IER_THRI;
-+ serial_out(info, UART_IER, info->IER);
-+ status0 = serial_inp(info, UART_IIR);
-+
-+ if (intr_done)
-+ *intr_done = 0;
-+#endif
- } else {
- info->IER &= ~UART_IER_THRI;
- serial_out(info, UART_IER, info->IER);
-@@ -1008,7 +1184,11 @@
- if( info->io_type == SERIAL_IO_MEM ){
- count = info->xmit_fifo_size / 2;
-
-+#if defined(CONFIG_BLUETOOTH_SL)
-+ if (xpa2X0_is_st_uart(info->iomem_base) || xpa2X0_is_bt_uart(info->iomem_base)) {
-+#else
- if (xpa2X0_is_st_uart(info->iomem_base)) {
-+#endif
- count = info->xmit_fifo_size ;
- }
- } else count = info->xmit_fifo_size;
-@@ -1039,7 +1219,6 @@
- } else {
- do {
- serial_out(info, UART_TX, info->xmit.buf[info->xmit.tail]);
--
- info->xmit.tail = (info->xmit.tail + 1) & (SERIAL_XMIT_SIZE-1);
- info->state->icount.tx++;
- if (info->xmit.head == info->xmit.tail)
-@@ -1064,6 +1243,10 @@
- // while (!(serial_inp(info, UART_LSR) & UART_LSR_TEMT))
- // ;
-
-+#if defined(CONFIG_BLUETOOTH_SL)
-+ } else if (xpa2X0_is_bt_uart(info->iomem_base)) {
-+
-+#endif
- } else {
- info->IER &= ~UART_IER_THRI;
- serial_out(info, UART_IER, info->IER);
-@@ -1091,7 +1274,11 @@
-
- status = serial_in(info, UART_MSR);
-
-+#if defined(CONFIG_BLUETOOTH_SL)
-+ if (xpa2X0_is_st_uart(info->iomem_base) || xpa2X0_is_bt_uart(info->iomem_base)) {
-+#else
- if (xpa2X0_is_st_uart(info->iomem_base)) {
-+#endif
- // printk("check_modem_status: do nothing\n");
- return;
- }
-@@ -1325,12 +1512,21 @@
- goto IRDA_INTR_DONE;
- }
-
--
- do {
- status = serial_inp(info, UART_LSR);
- #ifdef SERIAL_DEBUG_INTR
- printk("status = %x...", status);
- #endif
-+#if 1 //
-+ if (xpa2X0_is_bt_uart(info->iomem_base)) {
-+ if (status & UART_LSR_OE) {
-+ printk("ERROR: Bluetooth Overrun!\n");
-+ }
-+ if (status & (UART_LSR_PE|UART_LSR_FE|0x80) ) {
-+ printk("ERROR: Bluetooth Error!\n");
-+ }
-+ }
-+#endif
- if (status & UART_LSR_DR)
- receive_chars(info, &status, regs);
-
-@@ -2230,6 +2426,35 @@
-
- return;
- }
-+#if defined(CONFIG_BLUETOOTH_SL)
-+ if (xpa2X0_is_bt_uart(info->iomem_base)) {
-+ cval = UART_LCR_WLEN8;
-+#if 1 // for BCSP unit
-+ if (cflag & PARENB) {
-+ cval |= UART_LCR_PARITY;
-+ printk("set even parity enable\n");
-+ }
-+ if (!(cflag & PARODD)) {
-+ cval |= UART_LCR_EPAR;
-+ }
-+#endif
-+ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |UART_FCR_CLEAR_XMIT | UART_FCR_TRIGGER_8;
-+
-+ save_flags(flags); cli();
-+ quot = 0x0008; // 115.2kbps
-+
-+ serial_outp(info, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */
-+ serial_outp(info, UART_DLL, quot & 0xff); /* LS of divisor */
-+ serial_outp(info, UART_DLM, quot >> 8); /* MS of divisor */
-+ serial_outp(info, UART_LCR, cval); /* reset DLAB */
-+ info->LCR = cval; /* Save LCR */
-+ serial_outp(info, UART_FCR, fcr); /* set fcr */
-+
-+ restore_flags(flags);
-+
-+ return;
-+ }
-+#endif
-
- /* Set up FIFO's */
- if (uart_config[info->state->type].flags & UART_USE_FIFO) {
-@@ -2448,7 +2673,11 @@
-
- #if defined(CONFIG_ARCH_SHARP_SL)
- if(info->io_type == SERIAL_IO_MEM){
-+#if defined(CONFIG_BLUETOOTH_SL)
-+ if (xpa2X0_is_st_uart(info->iomem_base) || xpa2X0_is_bt_uart(info->iomem_base)) {
-+#else
- if (xpa2X0_is_st_uart(info->iomem_base)) {
-+#endif
-
- info->IER |= UART_IER_THRI;
- serial_out(info, UART_IER, info->IER);
-@@ -3508,9 +3737,10 @@
-
-
- //close IR
-+#ifdef CONFIG_PM
- #if defined(CONFIG_ARCH_SHARP_SL)&& (CONFIG_IRDA)
- if (xpa2X0_is_st_uart(info->iomem_base)) {
-- ICMR &= ~(1 << 20); //btuart
-+ ICMR &= ~(1 << 20); //stuart
- xpa210_discovery_irda_power_off();
- xpa210_discovery_irda_enable(info, 0);
- irda_open = 0; irda_info = 0;
-@@ -3519,6 +3749,13 @@
- #endif
- }
- #endif
-+#if defined(CONFIG_BLUETOOTH_SL)
-+ if (xpa2X0_is_bt_uart(info->iomem_base)) {
-+ pxa_bluetooth_enable(info, 0);
-+ bluetooth_open = 0; bluetooth_info = 0;
-+ }
-+#endif // end CONFIG_BLUETOOTH_SL
-+#endif /* CONFIG_PM */
-
- shutdown(info);
- if (tty->driver.flush_buffer)
-@@ -3540,12 +3777,14 @@
- wake_up_interruptible(&info->close_wait);
- MOD_DEC_USE_COUNT;
-
--#if (defined(CONFIG_SABINAL_DISCOVERY) && (CONFIG_DISCOVERY_EVT2)) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if (defined(CONFIG_SABINAL_DISCOVERY) && (CONFIG_DISCOVERY_EVT2)) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
-+#ifdef CONFIG_PM
- xpa210_discovery_serial_power_off();
- if (xpa2X0_is_ff_uart(info->iomem_base)) {
- CKEN &= ~CKEN6_FFUART;
- change_power_mode(LOCK_FCS_FFUART, 0);
- }
-+#endif /* CONFIG_PM */
- #endif
-
- }
-@@ -3906,12 +4145,14 @@
- #endif
- }
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
-+#ifdef CONFIG_PM
- xpa210_discovery_serial_power_on();
- if (xpa2X0_is_ff_uart(info->iomem_base)) {
-- CKEN |= CKEN6_FFUART;
- if ( !change_power_mode(LOCK_FCS_FFUART, 1) ) return -EAGAIN;
-+ CKEN |= CKEN6_FFUART;
- }
-+#endif /* CONFIG_PM */
- #endif
-
- /*
-@@ -3964,7 +4205,7 @@
- info->IER = 0x01;
- if ( xpa210_discovery_irda_enable(info, 1) ) return -EAGAIN;
- xpa210_discovery_irda_power_on();
-- ICMR |= (1 << 20); //btuart
-+ ICMR |= (1 << 20); //stuart
- irda_open = 1;
- irda_info = info;
- #if defined(CONFIG_SABINAL_DISCOVERY)
-@@ -3973,6 +4214,15 @@
- }
- #endif
-
-+#if defined(CONFIG_BLUETOOTH_SL)
-+ if (pxa_is_bluetooth_line(line)) {
-+ int ret;
-+ if ( (ret = pxa_bluetooth_enable(info, 1))!=0 ) return ret;
-+ bluetooth_open = 1;
-+ bluetooth_info = info;
-+ }
-+#endif // end CONFIG_BLUETOOTH_SL
-+
- #ifdef SERIAL_DEBUG_OPEN
- printk("\nrs_open ttys%d successful...", info->line);
- #endif
-@@ -6161,24 +6411,29 @@
-
- void cotulla_serial_suspend(void) {
-
--#if (defined(CONFIG_SABINAL_DISCOVERY) && (CONFIG_DISCOVERY_EVT2)) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if (defined(CONFIG_SABINAL_DISCOVERY) && (CONFIG_DISCOVERY_EVT2)) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- xpa210_discovery_serial_power_off();
- #endif
-
- #ifdef CONFIG_IRDA
- if ( irda_open == 1 ) {
-- ICMR &= ~(1 << 20); //btuart
-+ ICMR &= ~(1 << 20); //stuart
- xpa210_discovery_irda_power_off();
- xpa210_discovery_irda_enable(irda_info, 0);
-
- }
- #endif
-
-+#if defined(CONFIG_BLUETOOTH_SL)
-+ if ( bluetooth_open ) {
-+ pxa_bluetooth_enable(bluetooth_info, 0);
-+ }
-+#endif // end CONFIG_BLUETOOTH_SL
- }
-
- void cotulla_serial_resume(void) {
-
--#if (defined(CONFIG_SABINAL_DISCOVERY) && (CONFIG_DISCOVERY_EVT2)) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if (defined(CONFIG_SABINAL_DISCOVERY) && (CONFIG_DISCOVERY_EVT2)) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- xpa210_discovery_serial_power_on();
- #endif
-
-@@ -6192,7 +6447,7 @@
- #else
- #if defined(CONFIG_SABINAL_DISCOVERY)
- BTUART_MCR |= UART_MCR_OUT2;
--#elif defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#elif defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- FFUART_MCR |= UART_MCR_OUT2;
- #endif
- STUART_MCR |= UART_MCR_OUT2;
-@@ -6202,10 +6457,16 @@
- change_speed(irda_info, 0);
- if ( xpa210_discovery_irda_enable(irda_info, 1) ) return;
- xpa210_discovery_irda_power_on();
-- ICMR |= (1 << 20); //btuart
-+ ICMR |= (1 << 20); //stuart
- }
- #endif
-
-+#if defined(CONFIG_BLUETOOTH_SL)
-+ if ( bluetooth_open == 1 ) {
-+ change_speed(bluetooth_info, 0);
-+ if ( pxa_bluetooth_enable(bluetooth_info, 1) ) return;
-+ }
-+#endif // end CONFIG_BLUETOOTH_SL
- #endif
-
- }
-@@ -6226,7 +6487,7 @@
-
- return 0;
- }
--#endif
-+#endif /* CONFIG_PM */
-
- /*
- * The serial driver boot-time initialization code!
-@@ -6289,7 +6550,7 @@
- serial_driver.subtype = SERIAL_TYPE_NORMAL;
- serial_driver.init_termios = tty_std_termios;
- serial_driver.init_termios.c_cflag =
-- B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-+ B9600 | CS8 | CREAD | HUPCL | CLOCAL;
- serial_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS;
- serial_driver.refcount = &serial_refcount;
- serial_driver.table = serial_table;
-@@ -6368,6 +6629,9 @@
- if (state->flags & ASYNC_BOOT_AUTOCONF)
- autoconfig(state);
- }
-+#if defined(CONFIG_BLUETOOTH_SL)
-+ pxa_check_bluetooth_unit();
-+#endif
- for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
- if (state->type == PORT_UNKNOWN)
- continue;
-@@ -6384,6 +6648,16 @@
- state->iomem_base, state->irq,
- uart_config[state->type].name);
- printk(", using IRDA\n");
-+#if defined(CONFIG_BLUETOOTH_SL)
-+ } else if (xpa2X0_is_bt_uart(state->iomem_base)) {
-+ printk(KERN_INFO"ttyS%02d%s at 0x%px (irq = %d) is a %s",
-+ state->line + SERIAL_DEV_OFFSET,
-+ (state->flags & ASYNC_FOURPORT) ? " FourPort" : "",
-+ state->iomem_base, state->irq,
-+ uart_config[state->type].name);
-+ if (has_bluetooth==1) printk(", using Bluetooth\n");
-+ else printk("\n");
-+#endif // end CONFIG_BLUETOOTH_SL
- } else {
- printk(KERN_INFO"ttyS%02d%s at 0x%px (irq = %d) is a %s\n",
- state->line + SERIAL_DEV_OFFSET,
-@@ -6418,7 +6692,7 @@
- probe_serial_pnp();
- #endif
-
--#if (defined(CONFIG_SABINAL_DISCOVERY) && (CONFIG_DISCOVERY_EVT2)) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if (defined(CONFIG_SABINAL_DISCOVERY) && (CONFIG_DISCOVERY_EVT2)) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- xpa210_discovery_serial_power_off();
- #endif
-
-@@ -6435,9 +6709,23 @@
- v2 |= 0x00008000;
- GPDR1 = v2;
-
--#if !defined(CONFIG_SABINAL_DISCOVERY)
-+#if !defined(CONFIG_SABINAL_DISCOVERY) && !defined(CONFIG_ARCH_PXA_TOSA)
- GPDR(GPIO_IR_ON) |= GPIO_bit(GPIO_IR_ON);
- #endif
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ SCP_REG_GPCR |= SCP_IR_POWERDWN;
-+ set_GPIO_mode(GPIO47_STTXD|GPIO_OUT);
-+ GPCR(GPIO47_STTXD) = GPIO_bit(GPIO47_STTXD);
-+ set_GPIO_mode(GPIO46_STRXD_MD);
-+
-+#endif
-+
-+#if defined(CONFIG_BLUETOOTH_SL)
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ SCP_REG_GPCR |= SCP_BT_RESET;
-+ SCP_REG_GPCR |= SCP_BT_PWR_EN;
-+#endif
-+#endif // end CONFIG_BLUETOOTH_SL
- #endif
-
- #ifdef CONFIG_PM
-diff -Nur linux_c860_org/drivers/char/sharp_buzzer.c linux/drivers/char/sharp_buzzer.c
---- linux_c860_org/drivers/char/sharp_buzzer.c 2003-01-14 12:07:55.000000000 +0900
-+++ linux/drivers/char/sharp_buzzer.c 2004-06-10 21:09:10.000000000 +0900
-@@ -18,6 +18,7 @@
- * ChangeLog:
- * 04-16-2001 Lineo Japan, Inc. ...
- * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- #include <linux/config.h>
-@@ -52,7 +53,7 @@
- # define SHARP_BUZZER_MAJOR 227 /* number of bare sharp_buzzer driver */
- #endif
-
--#if !defined(CONFIG_SA1100_COLLIE) && !defined(CONFIG_ARCH_PXA_POODLE) && !defined(CONFIG_ARCH_PXA_CORGI)
-+#if !defined(CONFIG_SA1100_COLLIE) && !defined(CONFIG_ARCH_PXA_POODLE) && !defined(CONFIG_ARCH_PXA_CORGI) && !defined(CONFIG_ARCH_PXA_TOSA)
- #define USE_IMELODY_FORMAT
- #endif
-
-@@ -122,6 +123,22 @@
- #define resume_buzzer_arch() poodle_resume_buzzer()
- #endif
-
-+#if defined (CONFIG_ARCH_PXA_TOSA)
-+extern int tosa_play_sound_by_id(int soundid,int volume);
-+extern int tosa_play_sound_by_hz(unsigned int hz,unsigned int msecs,int volume);
-+extern int tosa_buzzer_dev_init(void);
-+extern int tosa_buzzer_supported(int which); /* return -EINVAL if unspoorted , otherwise return >= 0 value */
-+extern int tosa_suspend_buzzer(void);
-+extern int tosa_resume_buzzer(void);
-+#define play_sound_by_id(id,vol) tosa_play_sound_by_id((id),(vol))
-+#define stop_sound() tosa_stop_sound()
-+#define stop_sound_by_id(id) tosa_stop_sound()
-+#define play_sound_by_hz(hz,msecs,vol) tosa_play_sound_by_hz((hz),(msecs),(vol))
-+#define buzzer_dev_init() tosa_buzzer_dev_init()
-+#define buzzer_supported_arch(w) tosa_buzzer_supported((w))
-+#define suspend_buzzer_arch() tosa_suspend_buzzer()
-+#define resume_buzzer_arch() tosa_resume_buzzer()
-+#endif /* CONFIG_ARCH_PXA_TOSA */
-
- /*
- * logical level drivers
-@@ -498,7 +515,7 @@
- if( minor != SHARP_BUZZER_MINOR ) return -ENODEV;
- if( ! device_initialized ){
- int i;
--#if !defined(CONFIG_SA1100_COLLIE) && !defined(CONFIG_ARCH_PXA_POODLE) && !defined(CONFIG_ARCH_PXA_CORGI)
-+#if !defined(CONFIG_SA1100_COLLIE) && !defined(CONFIG_ARCH_PXA_POODLE) && !defined(CONFIG_ARCH_PXA_CORGI) && !defined(CONFIG_ARCH_PXA_TOSA)
- buzzer_dev_init();
- #endif
- for(i=0;i<=SHARP_BUZ_WHICH_MAX;i++){
-@@ -750,7 +767,7 @@
- #endif
-
-
--#if defined(CONFIG_SA1100_COLLIE) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_SA1100_COLLIE) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- buzzer_dev_init();
- #endif
-
-diff -Nur linux_c860_org/drivers/char/sharp_kbdctl.c linux/drivers/char/sharp_kbdctl.c
---- linux_c860_org/drivers/char/sharp_kbdctl.c 2003-01-14 12:07:55.000000000 +0900
-+++ linux/drivers/char/sharp_kbdctl.c 2004-06-10 21:09:10.000000000 +0900
-@@ -18,6 +18,7 @@
- * Change Log
- * 30-Jul-2002 Lineo Japan, Inc. for 2.4.18
- * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
-+ * 1-Nov-2003 Sharp Corporation for Tosa
- */
-
- #include <linux/config.h>
-@@ -67,9 +68,10 @@
- extern int restore_all_holdkey_info(void);
- extern int customize_del_holdkey_info(int hardcode);
- extern int customize_restore_holdkey_info(int hardcode);
--
--
--
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+extern int set_port_key_setting( int num, int val );
-+extern int get_port_key_setting( int num );
-+#endif
-
- /*
- * operations....
-@@ -157,7 +159,11 @@
- break;
- case SHARP_EXTMODIF_NUMLOCK:
- sharppda_kbd_extmodif_togglestatus(c);
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ c = 32; f = 3; // numlock keycode
-+#else
- c = SLKEY_NUMLOCK; f = 3;
-+#endif
- break;
- default:
- return -EINVAL;
-@@ -195,6 +201,18 @@
- error = sharppda_kbd_extmodif_togglestatus(arg);
- if( error ) return error;
- }
-+ case SHARP_KBDCTL_SETMODIFSTAT:
-+ {
-+ int error;
-+ int val;
-+ sharp_kbdctl_modifstat* puser = (sharp_kbdctl_modifstat*)arg;
-+ if( ! puser ) return -EINVAL;
-+ val = sharppda_kbd_extmodif_showstatus(puser->which);
-+ if (puser->stat!=val) {
-+ error = sharppda_kbd_extmodif_togglestatus(puser->which);
-+ if( error ) return error;
-+ }
-+ }
- break;
- case SHARP_KBDCTL_SETHOLDTH:
- {
-@@ -311,6 +329,20 @@
- if( error ) return error;
- }
- break;
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ case SHARP_KBDCTL_SETSWKEY:
-+ {
-+ sharp_kbdctl_swkey* puser = (sharp_kbdctl_swkey*)arg;
-+ if( ! puser ) return -EINVAL;
-+ return set_port_key_setting(puser->key,puser->mode);
-+ }
-+ break;
-+ case SHARP_KBDCTL_GETSWKEY:
-+ {
-+ return get_port_key_setting(arg);
-+ }
-+ break;
-+#endif
- default:
- return -EINVAL;
- }
-diff -Nur linux_c860_org/drivers/char/sharp_led.c linux/drivers/char/sharp_led.c
---- linux_c860_org/drivers/char/sharp_led.c 2002-12-18 19:28:00.000000000 +0900
-+++ linux/drivers/char/sharp_led.c 2004-06-10 21:09:10.000000000 +0900
-@@ -19,6 +19,7 @@
- * 30-Jul-2002 Lineo Japan, Inc. for 2.4.18
- * 27-AUG-2002 Edward Chen, Steve Lin for Discovery
- * 12-Dec-2002 Lineo Japan, Inc.
-+ * 1-Nov-2003 Sharp Corporation for Tosa
- *
- */
- #include <linux/config.h>
-@@ -72,7 +73,7 @@
- #define suspend_led_arch() collie_suspend_led()
- #define resume_led_arch() collie_resume_led()
- #define standby_led_arch() (0)
--#elif defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#elif defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- extern int sharpsl_led_supported(int which); /* return -EINVAL if unspoorted , otherwise return >= 0 value */
- extern int sharpsl_turn_led_status(int which,int status); /* set LED status to directed value. */
- extern int sharpsl_init_led(void);
-@@ -209,33 +210,33 @@
- {
- switch (req) {
- case PM_STANDBY:
--#if defined(CONFIG_SA1100_COLLIE) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_SA1100_COLLIE) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- set_led_status(SHARP_LED_PDA,LED_PDA_SUSPENDED);
- standby_led_arch();
- #endif
- break;
-
- case PM_BLANK:
--#if defined(CONFIG_SA1100_COLLIE) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_SA1100_COLLIE) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- set_led_status(SHARP_LED_PDA,LED_PDA_SUSPENDED);
- #endif
- break;
-
- case PM_UNBLANK:
--#if defined(CONFIG_SA1100_COLLIE) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_SA1100_COLLIE) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- set_led_status(SHARP_LED_PDA,LED_PDA_RUNNING);
- #endif
- break;
-
- case PM_SUSPEND:
--#if defined(CONFIG_SA1100_COLLIE) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_SA1100_COLLIE) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- set_led_status(SHARP_LED_PDA,LED_PDA_OFF);
- suspend_led_arch();
- #endif
- break;
-
- case PM_RESUME:
--#if defined(CONFIG_SA1100_COLLIE) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_SA1100_COLLIE) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- set_led_status(SHARP_LED_PDA,LED_PDA_RUNNING);
- resume_led_arch();
- #endif
-diff -Nur linux_c860_org/drivers/char/sharpsl_led.c linux/drivers/char/sharpsl_led.c
---- linux_c860_org/drivers/char/sharpsl_led.c 2003-01-14 12:07:55.000000000 +0900
-+++ linux/drivers/char/sharpsl_led.c 2004-06-10 21:09:10.000000000 +0900
-@@ -18,6 +18,7 @@
- * ChangeLog:
- * based on collie_led.c Aug. 26 2002 LINEO
- * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
-+ * 1-Nov-2003 Sharp Corporation for Tosa
- *
- */
-
-@@ -47,6 +48,9 @@
- #if defined(CONFIG_ARCH_PXA_CORGI)
- #include <asm/arch/corgi.h>
- #endif
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+#include <asm/arch/tosa.h>
-+#endif
- #include <asm/arch/hardware.h>
-
- #include <linux/timer.h>
-@@ -69,7 +73,8 @@
- {
- set_led_status(SHARP_LED_CHARGER,LED_CHARGER_ERROR);
- }
--#elif defined(CONFIG_ARCH_PXA_CORGI)
-+#elif defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
-+static int led_suspended=0;
- void sharpsl_charge_wait_ms(void)
- {
- unsigned long time = OSCR;
-@@ -88,6 +93,18 @@
- }
- }
-
-+#if defined (CONFIG_ARCH_PXA_TOSA)
-+void sharpsl_charge_err_off(void)
-+{
-+ while(1) {
-+ set_scoop_jc_gpio(SCP_LED_ORANGE);
-+ sharpsl_charge_wait( 250 );
-+ reset_scoop_jc_gpio(SCP_LED_ORANGE);
-+ sharpsl_charge_wait( 250 );
-+ if ((GPLR(GPIO_AC_IN) & GPIO_bit(GPIO_AC_IN))!=0) break;
-+ }
-+}
-+#else // for Corgi
- void sharpsl_charge_err_off(void)
- {
- while(1) {
-@@ -99,6 +116,7 @@
- }
- }
- #endif
-+#endif
-
- #if defined(CONFIG_ARCH_PXA_POODLE)
- #define LED_ONOFF_MASK (LCM_LPT_TOFL|LCM_LPT_TOFH)
-@@ -109,7 +127,7 @@
- #define LED_BLNK(REG,X,Y) ((REG)=((REG)&~LED_BLNK_MASK)|LED_BLNK_VAL(X,Y))
- #endif
-
--#if defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- struct timer_list orange_led_blink_timer;
- struct st_orange_blink {
- int blink_switch;
-@@ -120,16 +138,76 @@
- #define BLINK_SLOW 2
- #define ORANGE_LED_SW 1
- #define GREEN_LED_SW 2
-+#if defined (CONFIG_ARCH_PXA_TOSA)
-+#define BLUE_LED_SW 3
-+#define WLAN_LED_SW 4
-+#define LED_NUM 4
-+
-+static int get_ledport( int sw )
-+{
-+ int port=-1;
-+ switch(sw) {
-+ case ORANGE_LED_SW:
-+ port = SCP_LED_ORANGE;
-+ break;
-+ case GREEN_LED_SW:
-+ port = SCP_LED_GREEN;
-+ break;
-+ case BLUE_LED_SW:
-+ port = SCP_LED_BLUE;
-+ break;
-+ case WLAN_LED_SW:
-+ port = SCP_LED_WLAN;
-+ break;
-+ }
-+ return port;
-+}
-+
-+static void set_led( int sw, int on )
-+{
-+ int port=get_ledport(sw);
-+ if (port==-1) {
-+ printk(__FUNCTION__ ": unknown LED %d\n",sw);
-+ return;
-+ }
-+ if (on) set_scoop_jc_gpio(port);
-+ else reset_scoop_jc_gpio(port);
-+ // printk("setled(%d,%d)\n",sw,on);
-+}
-+
-+static int get_led( int sw )
-+{
-+ int port=get_ledport(sw);
-+ if (port==-1) {
-+ printk(__FUNCTION__ ": unknown LED %d\n",sw);
-+ return;
-+ }
-+ return (SCP_JC_REG_GPWR&port)?1:0;
-+}
-+
-+#define LED_OFF(n) set_led(n,0)
-+#define LED_ON(n) set_led(n,1)
-+#define LED_STATUS(n) get_led(n)
-+static int led_resume_buffer=0;
-+#endif
-
- static void blink_orange_led(unsigned long data)
- {
- struct st_orange_blink *orange = (struct st_orange_blink *)data;
-
- if (orange->blink_switch == 0) {
-+#if defined (CONFIG_ARCH_PXA_TOSA)
-+ LED_ON(ORANGE_LED_SW);
-+#else
- GPSR(GPIO_LED_ORANGE) = GPIO_bit(GPIO_LED_ORANGE);
-+#endif
- orange->blink_switch = 1;
- } else {
-+#if defined (CONFIG_ARCH_PXA_TOSA)
-+ LED_OFF(ORANGE_LED_SW);
-+#else
- GPCR(GPIO_LED_ORANGE) = GPIO_bit(GPIO_LED_ORANGE);
-+#endif
- orange->blink_switch = 0;
- }
-
-@@ -165,9 +243,11 @@
- del_timer(&orange_led_blink_timer);
- }
-
-+#if ! defined(CONFIG_ARCH_PXA_TOSA)
- #define LED_OFF(n) ( (n == ORANGE_LED_SW) ? (GPCR(GPIO_LED_ORANGE) = GPIO_bit(GPIO_LED_ORANGE)) : (reset_scoop_gpio(SCP_LED_GREEN)) )
-
- #define LED_ON(n) ( (n == ORANGE_LED_SW) ? (GPSR(GPIO_LED_ORANGE) = GPIO_bit(GPIO_LED_ORANGE)) : (set_scoop_gpio(SCP_LED_GREEN)) )
-+#endif
-
- #define LED_BLNK(n) orange_led_start_blink(n)
- #endif /* CONFIG_ARCH_PXA_CORGI */
-@@ -178,7 +258,7 @@
- {
- #if defined(CONFIG_ARCH_PXA_POODLE)
- LED_OFF(LCM_LPT0);
--#elif defined(CONFIG_ARCH_PXA_CORGI)
-+#elif defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- LED_OFF(ORANGE_LED_SW);
- orange_led_stop_blink();
- #endif
-@@ -188,7 +268,7 @@
- {
- #if defined(CONFIG_ARCH_PXA_POODLE)
- LED_ON(LCM_LPT0);
--#elif defined(CONFIG_ARCH_PXA_CORGI)
-+#elif defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- LED_ON(ORANGE_LED_SW);
- #endif
- }
-@@ -198,7 +278,7 @@
- led0_off();
- #if defined(CONFIG_ARCH_PXA_POODLE)
- LED_BLNK(LCM_LPT0,2,2);
--#elif defined(CONFIG_ARCH_PXA_CORGI)
-+#elif defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- LED_BLNK(BLINK_FAST);
- #endif
- }
-@@ -208,7 +288,7 @@
- led0_off();
- #if defined(CONFIG_ARCH_PXA_POODLE)
- LED_BLNK(LCM_LPT0,7,7);
--#elif defined(CONFIG_ARCH_PXA_CORGI)
-+#elif defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- LED_BLNK(BLINK_SLOW);
- #endif
- }
-@@ -219,7 +299,7 @@
- {
- #if defined(CONFIG_ARCH_PXA_POODLE)
- LED_OFF(LCM_LPT1);
--#elif defined(CONFIG_ARCH_PXA_CORGI)
-+#elif defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- LED_OFF(GREEN_LED_SW);
- #endif
- }
-@@ -228,7 +308,7 @@
- {
- #if defined(CONFIG_ARCH_PXA_POODLE)
- LED_ON(LCM_LPT1);
--#elif defined(CONFIG_ARCH_PXA_CORGI)
-+#elif defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- LED_ON(GREEN_LED_SW);
- #endif
- }
-@@ -376,7 +456,7 @@
- expires: -1,
- next: -1
- }
--#elif defined(CONFIG_ARCH_PXA_CORGI)
-+#elif defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- {
- ledstate: SHARPSLLED_ON ,
- expires: (HZ/10 + HZ/50),
-@@ -397,7 +477,7 @@
- expires: -1,
- next: -1
- }
--#elif defined(CONFIG_ARCH_PXA_CORGI)
-+#elif defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- {
- ledstate: SHARPSLLED_ON ,
- expires: ((4*HZ)/5 + (2*HZ)/25),
-@@ -418,7 +498,7 @@
- expires: -1,
- next: -1
- }
--#elif defined(CONFIG_ARCH_PXA_CORGI)
-+#elif defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- {
- ledstate: SHARPSLLED_ON ,
- expires: (HZ/10 + HZ/50),
-@@ -439,7 +519,7 @@
- expires: -1,
- next: -1
- }
--#elif defined(CONFIG_ARCH_PXA_CORGI)
-+#elif defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- {
- ledstate: SHARPSLLED_ON ,
- expires: HZ/4,
-@@ -460,7 +540,7 @@
- expires: -1,
- next: -1
- }
--#elif defined(CONFIG_ARCH_PXA_CORGI)
-+#elif defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- {
- ledstate: SHARPSLLED_ON ,
- expires: HZ/2,
-@@ -481,7 +561,7 @@
- expires: -1,
- next: -1
- }
--#elif defined(CONFIG_ARCH_PXA_CORGI)
-+#elif defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- {
- ledstate: SHARPSLLED_ON ,
- expires: ((4*HZ)/5 + (2*HZ)/25),
-@@ -610,6 +690,98 @@
- led0_off();
- }
-
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+typedef struct {
-+ int status;
-+ int blink_switch;
-+ long blink_interval;
-+ struct timer_list timer;
-+} LED_BLINK;
-+static LED_BLINK st_led_status[LED_NUM+1];
-+static int led_status_initialized=0;
-+
-+static void led_on(int led)
-+{
-+ del_timer(&st_led_status[led].timer);
-+ st_led_status[led].status=1;
-+ LED_ON(led);
-+}
-+static void led_off(int led)
-+{
-+ del_timer(&st_led_status[led].timer);
-+ st_led_status[led].status=0;
-+ LED_OFF(led);
-+}
-+
-+static void led_blink_func(unsigned long data)
-+{
-+ int led = data;
-+ if (st_led_status[led].blink_switch==0 && led_suspended==0 ) {
-+ LED_ON(led);
-+ st_led_status[led].blink_switch=1;
-+ } else {
-+ LED_OFF(led);
-+ st_led_status[led].blink_switch=0;
-+ }
-+ init_timer(&st_led_status[led].timer);
-+ st_led_status[led].timer.function = led_blink_func;
-+ st_led_status[led].timer.expires = jiffies + st_led_status[led].blink_interval;
-+ st_led_status[led].timer.data = led;
-+ add_timer(&st_led_status[led].timer);
-+}
-+
-+static void led_start_blink(int led, int interval)
-+{
-+ del_timer(&st_led_status[led].timer);
-+ switch (interval) {
-+ case BLINK_SLOW:
-+ st_led_status[led].blink_interval = (4*HZ)/5 + (2*HZ)/25;
-+ st_led_status[led].status = 2;
-+ break;
-+ case BLINK_FAST:
-+ st_led_status[led].blink_interval = HZ / 4;
-+ st_led_status[led].status = 3;
-+ break;
-+ default :
-+ return;
-+ }
-+
-+ st_led_status[led].blink_switch=0;
-+ led_blink_func(led);
-+}
-+
-+static void sharpsl_led_process_ex(int led_sw)
-+{
-+ int *leds = sharpslled_internal_logical;
-+ int status=-1;
-+ switch(led_sw) {
-+ case BLUE_LED_SW:
-+ status = leds[SHARP_LED_BLUETOOTH];
-+ break;
-+ case WLAN_LED_SW:
-+ status = leds[SHARP_LED_WLAN];
-+ break;
-+ }
-+ if ( status == -1 || status == st_led_status[led_sw].status ) return;
-+ if (led_suspended) status=0; // force off
-+ switch(status) {
-+ case 0: // off
-+ led_off(led_sw);
-+ return;
-+ case 1: // on
-+ led_on(led_sw);
-+ return;
-+ case 2: // blink
-+ led_start_blink(led_sw,BLINK_SLOW);
-+ return;
-+ case 3: // blink fast
-+ led_start_blink(led_sw,BLINK_FAST);
-+ return;
-+ }
-+ led_off(led_sw);
-+}
-+#endif
-+
- static sharpled_pattern_item* decide_physical_led(void)
- {
- int *leds = sharpslled_internal_logical;
-@@ -632,7 +804,7 @@
- sharpslled_internal_logical[15]));
-
- /******* 1st: controlled *******/
--#if defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- if( (leds[SHARP_LED_COLLIE_1] > LED_COLLIE_1_ON) &&
- (leds[SHARP_LED_PDA] == LED_PDA_OFF) )
- return NULL;
-@@ -662,10 +834,10 @@
- sharpsl_ledpat_softflash : NULL;
- }
-
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- /* A3-1:R:SHARP_LED_CHARGER=LED_CHARGER_ERROR */
-
--#if defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- /* A3-non-spec:G:turn off */
- if( leds[SHARP_LED_PDA] == LED_PDA_OFF )
- return NULL;
-@@ -777,6 +949,14 @@
- if( which < 0 || which > SHARP_LED_WHICH_MAX ) return -EINVAL;
- sharpslled_internal_logical[which] = status;
- sharpsl_led0_process();
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ {
-+ int i;
-+ for (i=3; i<=LED_NUM; i++) {
-+ sharpsl_led_process_ex(i);
-+ }
-+ }
-+#endif
- if( curpat ) sharpled_pattern_end(&sharpsl_led1_player);
- if( ( pat = decide_physical_led() ) != NULL ){
- sharpled_pattern_start(&sharpsl_led1_player,pat);
-@@ -787,13 +967,44 @@
-
- int sharpsl_init_led(void)
- {
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ if (!led_status_initialized) {
-+ memset(&st_led_status,0,sizeof(st_led_status));
-+ led_status_initialized=1;
-+ }
-+#endif
- return 0;
- }
- int sharpsl_suspend_led(void)
- {
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ led_suspended=1;
-+ {
-+ int i;
-+ led_resume_buffer = 0;
-+ for (i=1; i<=LED_NUM; i++) {
-+ if (LED_STATUS(i)) {
-+ led_resume_buffer |= 0x1<<i;
-+ LED_OFF(i);
-+ }
-+ }
-+ }
-+#endif
- return 0;
- }
- int sharpsl_resume_led(void)
- {
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ led_suspended=0;
-+ {
-+ int i;
-+ for (i=1; i<=LED_NUM; i++) {
-+ if (led_resume_buffer & (0x1<<i)) {
-+ LED_ON(i);
-+ }
-+ }
-+ led_resume_buffer = 0;
-+ }
-+#endif
- return 0;
- }
-diff -Nur linux_c860_org/drivers/char/tosa_keyb.c linux/drivers/char/tosa_keyb.c
---- linux_c860_org/drivers/char/tosa_keyb.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/char/tosa_keyb.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,234 @@
-+/*
-+ * linux/drivers/char/tosa_keyb.c
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ *
-+ * Based on:
-+ * drivers/char/corgi_keyb.c
-+ * drivers/char/collie_keyb.c
-+ * drivers/char/iris_keyb.c
-+ * drivers/char/kbd_linkup.c - Keyboard Driver for Linkup-7200
-+ * Copyright (C) Roger Gammans 1998
-+ * Written for Linkup 7200 by Xuejun Tao, ISDcorp
-+ * Refer to kbd_7110.c (Cirrus Logic 7110 Keyboard driver)
-+ *
-+ * ChangeLong:
-+ * 04-25-2001 Lineo Japan, Inc.
-+ * 30-Jul-2002 Lineo Japan, Inc. for 2.4.18
-+ * 12-Dec-2002 Sharp Corporation
-+ * 1-Nov-2003 Sharp Corporation for Tosa
-+ */
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/poll.h>
-+#include <linux/wait.h>
-+#include <asm/arch/keyboard.h>
-+#include <asm/uaccess.h>
-+#include <linux/tqueue.h>
-+#include <linux/kbd_ll.h>
-+#include <linux/delay.h>
-+#include <asm/arch/pxa-regs.h>
-+
-+#ifdef USE_KBD_IRQ // could be defined in asm/arch/keyboard.h
-+#include <asm/irq.h> // for linkup keyboard interrupt
-+#endif
-+
-+#include <asm/arch/irqs.h>
-+
-+#ifndef TOSA_KBD_MAJOR
-+# define TOSA_KBD_MAJOR 61
-+#endif
-+
-+#ifdef CONFIG_PM
-+#include <linux/pm.h>
-+static struct pm_dev *corgi_kbd_pm_dev;
-+#endif
-+
-+/*
-+ * common logical driver definition
-+ */
-+extern void sharppda_kbd_press(int keycode);
-+extern void sharppda_kbd_release(int keycode);
-+extern void sharppda_scan_logdriver_init(void);
-+extern void sharppda_scan_key_gpio(void* dummy);
-+#define tosa_kbd_tick sharppda_scan_key_gpio
-+
-+/*
-+ * physical driver depending on TOSA target.
-+ */
-+void tosa_kbd_discharge_all(void)
-+{
-+ // STROBE All HiZ
-+ GPCR1 = GPIO_HIGH_STROBE_BIT;
-+ GPDR1 &= ~GPIO_HIGH_STROBE_BIT;
-+ GPCR2 = GPIO_LOW_STROBE_BIT;
-+ GPDR2 &= ~GPIO_LOW_STROBE_BIT;
-+}
-+
-+void tosa_kbd_charge_all(void)
-+{
-+}
-+
-+void tosa_kbd_activate_all(void)
-+{
-+ // STROBE ALL -> High
-+ GPSR1 = GPIO_HIGH_STROBE_BIT;
-+ GPDR1 |= GPIO_HIGH_STROBE_BIT;
-+ GPSR2 = GPIO_LOW_STROBE_BIT;
-+ GPDR2 |= GPIO_LOW_STROBE_BIT;
-+
-+ udelay(KB_DISCHARGE_DELAY);
-+
-+ // STATE CLEAR
-+ GEDR2 |= GPIO_ALL_SENSE_BIT;
-+}
-+
-+void tosa_kbd_activate_col(int col)
-+{
-+ if (col<=5) {
-+ // STROBE col -> High, not col -> HiZ
-+ GPSR1 = GPIO_STROBE_BIT(col);
-+ GPDR1 = (GPDR1 & ~GPIO_HIGH_STROBE_BIT) | GPIO_STROBE_BIT(col);
-+ } else {
-+ // STROBE col -> High, not col -> HiZ
-+ GPSR2 = GPIO_STROBE_BIT(col);
-+ GPDR2 = (GPDR2 & ~GPIO_LOW_STROBE_BIT) | GPIO_STROBE_BIT(col);
-+ }
-+}
-+
-+void tosa_kbd_reset_col(int col)
-+{
-+ if (col<=5) {
-+ // STROBE col -> Low
-+ GPCR1 = GPIO_STROBE_BIT(col);
-+ // STROBE col -> out, not col -> HiZ
-+ GPDR1 = (GPDR1 & ~GPIO_HIGH_STROBE_BIT) | GPIO_STROBE_BIT(col);
-+ } else {
-+ // STROBE col -> Low
-+ GPCR2 = GPIO_STROBE_BIT(col);
-+ // STROBE col -> out, not col -> HiZ
-+ GPDR2 = (GPDR2 & ~GPIO_LOW_STROBE_BIT) | GPIO_STROBE_BIT(col);
-+
-+ }
-+}
-+
-+
-+#ifdef USE_KBD_IRQ
-+
-+static void tosa_kbd_irq(int irq,void *dev_id,struct pt_regs *regs)
-+{
-+#ifdef CONFIG_APM
-+ extern int autoPowerCancel;
-+ extern int autoLightCancel;
-+#endif
-+ tosa_kbd_tick(NULL);
-+
-+#if CONFIG_APM // auto power/light cancel
-+ autoPowerCancel = 0;
-+ autoLightCancel = 0;
-+#endif
-+
-+}
-+#endif
-+
-+
-+#ifdef CONFIG_PM
-+extern void sharppda_scan_logdriver_suspend(void);
-+extern void sharppda_scan_logdriver_resume(void);
-+
-+extern int tosa_initial_keypress;
-+
-+static int tosa_kbd_pm_callback(struct pm_dev *pm_dev,
-+ pm_request_t req, void *data)
-+{
-+ int i;
-+
-+ switch (req) {
-+ case PM_SUSPEND:
-+ for (i = 0; i < KEY_SENSE_NUM; i++) {
-+ disable_irq(IRQ_GPIO_KEY_SENSE(i));
-+ }
-+ disable_irq(IRQ_GPIO_ON_KEY);
-+ disable_irq(IRQ_GPIO_RECORD_BTN);
-+ disable_irq(IRQ_GPIO_SYNC);
-+ sharppda_scan_logdriver_suspend();
-+ break;
-+ case PM_RESUME:
-+ // STROBE ALL -> High
-+ GPSR1 = GPIO_HIGH_STROBE_BIT;
-+ GPSR2 = GPIO_LOW_STROBE_BIT;
-+ GPDR1 |= GPIO_HIGH_STROBE_BIT;
-+ GPDR2 |= GPIO_LOW_STROBE_BIT;
-+ for (i = 0; i < KEY_SENSE_NUM; i++) {
-+ enable_irq(IRQ_GPIO_KEY_SENSE(i));
-+ }
-+ enable_irq(IRQ_GPIO_ON_KEY);
-+ enable_irq(IRQ_GPIO_RECORD_BTN);
-+ enable_irq(IRQ_GPIO_SYNC);
-+ sharppda_scan_logdriver_resume();
-+ tosa_initial_keypress = -1;
-+ break;
-+ }
-+ return 0;
-+}
-+#endif
-+
-+void tosa_kbd_hw_init(void)
-+{
-+ int i;
-+
-+ sharppda_scan_logdriver_init();
-+
-+ // STROBE ALL -> High
-+ // SENSE ALL -> In
-+ GPSR1 = GPIO_HIGH_STROBE_BIT;
-+ GPSR2 = GPIO_LOW_STROBE_BIT;
-+ GPDR2 &= ~GPIO_ALL_SENSE_BIT;
-+ GPDR1 |= GPIO_HIGH_STROBE_BIT;
-+ GPDR2 |= GPIO_LOW_STROBE_BIT;
-+ GEDR2 |= GPIO_ALL_SENSE_BIT;
-+ GAFR1_U &= ~GAFR_HIGH_STROBE_BIT;
-+ GAFR2_L &= ~(GAFR_LOW_STROBE_BIT | GAFR_ALL_SENSE_BIT);
-+
-+ /* SENSE:RisingEdge */
-+ for (i = 0; i < KEY_SENSE_NUM; i++) {
-+ set_GPIO_IRQ_edge(GPIO_KEY_SENSE(i), GPIO_RISING_EDGE);
-+ if (request_irq(IRQ_GPIO_KEY_SENSE(i), tosa_kbd_irq,
-+ SA_INTERRUPT, "keyboard", NULL)) {
-+ printk("Could not allocate KEYBD IRQ%d!\n", i);
-+ }
-+ }
-+ // Power&Rec Button
-+ set_GPIO_IRQ_edge(GPIO_ON_KEY, GPIO_FALLING_EDGE);
-+ set_GPIO_IRQ_edge(GPIO_RECORD_BTN, GPIO_FALLING_EDGE);
-+ set_GPIO_IRQ_edge(GPIO_SYNC, GPIO_FALLING_EDGE);
-+ if (request_irq(IRQ_GPIO_ON_KEY, tosa_kbd_irq, SA_INTERRUPT, "On key", NULL) ||
-+ request_irq(IRQ_GPIO_RECORD_BTN, tosa_kbd_irq, SA_INTERRUPT, "Record key", NULL) ||
-+ request_irq(IRQ_GPIO_SYNC, tosa_kbd_irq, SA_INTERRUPT, "Sync key", NULL)) {
-+ printk("Could not allocate KEYBD IRQ%d!\n", i);
-+ }
-+
-+
-+#ifdef CONFIG_PM
-+ corgi_kbd_pm_dev = pm_register(PM_SYS_DEV, 0, tosa_kbd_pm_callback);
-+#endif
-+
-+ printk("keyboard initilaized.\n");
-+}
-+
-+int tosa_kbd_translate(unsigned char scancode, unsigned char *keycode_p)
-+{
-+
-+ /*
-+ * We do this strangley to be more independent of
-+ * our headers..
-+ */
-+
-+ *keycode_p = scancode & ~(KBDOWN | KBUP);
-+
-+ return 1;
-+}
-+
-diff -Nur linux_c860_org/drivers/char/tosa_keymap.c linux/drivers/char/tosa_keymap.c
---- linux_c860_org/drivers/char/tosa_keymap.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/char/tosa_keymap.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,466 @@
-+
-+/* Do not edit this file! It was automatically generated by */
-+/* loadkeys --mktable defkeymap.map > defkeymap.c */
-+
-+#include <linux/types.h>
-+#include <linux/keyboard.h>
-+#include <linux/kd.h>
-+
-+u_short plain_map[] = {
-+ 0xf200, 0xfb61, 0xfb62, 0xfb63, 0xfb64, 0xfb65, 0xfb66, 0xfb67,
-+ 0xfb68, 0xfb69, 0xfb6a, 0xfb6b, 0xfb6c, 0xfb6d, 0xfb6e, 0xfb6f,
-+ 0xfb70, 0xfb71, 0xfb72, 0xfb73, 0xfb74, 0xfb75, 0xfb76, 0xfb77,
-+ 0xfb78, 0xfb79, 0xfb7a, 0xf700, 0xf201, 0xf101, 0xf703, 0xf008,
-+ 0xf208, 0xf200, 0xf01b, 0xf601, 0xf603, 0xf600, 0xf602, 0xf201,
-+ 0xf200, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
-+ 0xf038, 0xf039, 0xf030, 0xf02d, 0xf05e, 0xf05c, 0xf05b, 0xf040,
-+ 0xf702, 0xf703, 0xf702, 0xf02b, 0xfa00, 0xf040, 0xf03f, 0xf02c,
-+ 0xf02e, 0xf009, 0xf104, 0xf105, 0xf106, 0xf02f, 0xf027, 0xf301,
-+ 0xf302, 0xf303, 0xf304, 0xf305, 0xf306, 0xf307, 0xf308, 0xf309,
-+ 0xf300, 0xf07f, 0xf30d, 0xf30c, 0xf200, 0xf30b, 0xf30a, 0xf30e,
-+ 0xf702, 0xf703, 0xf01b, 0xf020, 0xf020, 0xf310, 0xf200, 0xf03b,
-+ 0xf03a, 0xf05d, 0xf02c, 0xf02e, 0xf02f, 0xf05f, 0xf200, 0xf700,
-+ 0xf114, 0xf117, 0xf118, 0xf119, 0xf701, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf200, 0xf200,
-+ 0xf702, 0xf703, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+};
-+
-+u_short shift_map[] = {
-+ 0xf200, 0xfb41, 0xfb42, 0xfb43, 0xfb44, 0xfb45, 0xfb46, 0xfb47,
-+ 0xfb48, 0xfb49, 0xfb4a, 0xfb4b, 0xfb4c, 0xfb4d, 0xfb4e, 0xfb4f,
-+ 0xfb50, 0xfb51, 0xfb52, 0xfb53, 0xfb54, 0xfb55, 0xfb56, 0xfb57,
-+ 0xfb58, 0xfb59, 0xfb5a, 0xf700, 0xf201, 0xf101, 0xf702, 0xf008,
-+ 0xf208, 0xf200, 0xf01b, 0xf601, 0xf603, 0xf600, 0xf602, 0xf201,
-+ 0xf200, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
-+ 0xf028, 0xf029, 0xf07e, 0xf03d, 0xf07e, 0xf07c, 0xf07b, 0xf060,
-+ 0xf702, 0xf703, 0xf702, 0xf02b, 0xfa00, 0xf040, 0xf03f, 0xf03b,
-+ 0xf03a, 0xf009, 0xf104, 0xf105, 0xf106, 0xf03f, 0xf022, 0xf301,
-+ 0xf302, 0xf303, 0xf304, 0xf305, 0xf306, 0xf307, 0xf308, 0xf309,
-+ 0xf300, 0xf07f, 0xf30d, 0xf30c, 0xf200, 0xf30b, 0xf30a, 0xf30e,
-+ 0xf702, 0xf703, 0xf01b, 0xf020, 0xf020, 0xf310, 0xf200, 0xf02b,
-+ 0xf02a, 0xf07d, 0xf03c, 0xf03e, 0xf03f, 0xf05f, 0xf200, 0xf700,
-+ 0xf114, 0xf117, 0xf20b, 0xf20a, 0xf701, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf200, 0xf200,
-+ 0xf702, 0xf703, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+};
-+
-+u_short ctrl_map[] = {
-+ 0xf200, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007,
-+ 0xf008, 0xf009, 0xf00a, 0xf00b, 0xf00c, 0xf00d, 0xf00e, 0xf00f,
-+ 0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017,
-+ 0xf018, 0xf019, 0xf01a, 0xf700, 0xf201, 0xf101, 0xf200, 0xf008,
-+ 0xf208, 0xf200, 0xf01b, 0xf601, 0xf603, 0xf600, 0xf602, 0xf201,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf702, 0xf703, 0xf702, 0xf02b, 0xfa00, 0xf040, 0xf03f, 0xf200,
-+ 0xf200, 0xf009, 0xf104, 0xf105, 0xf106, 0xf200, 0xf200, 0xf301,
-+ 0xf302, 0xf303, 0xf304, 0xf305, 0xf306, 0xf307, 0xf308, 0xf309,
-+ 0xf300, 0xf07f, 0xf30d, 0xf30c, 0xf200, 0xf30b, 0xf30a, 0xf30e,
-+ 0xf702, 0xf703, 0xf01b, 0xf020, 0xf000, 0xf310, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf700,
-+ 0xf114, 0xf117, 0xf118, 0xf119, 0xf701, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf200, 0xf200,
-+ 0xf702, 0xf703, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+};
-+
-+u_short shift_ctrl_map[] = {
-+ 0xf200, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007,
-+ 0xf008, 0xf009, 0xf00a, 0xf00b, 0xf00c, 0xf00d, 0xf00e, 0xf00f,
-+ 0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017,
-+ 0xf018, 0xf019, 0xf01a, 0xf700, 0xf201, 0xf101, 0xf200, 0xf008,
-+ 0xf208, 0xf200, 0xf01b, 0xf601, 0xf603, 0xf600, 0xf602, 0xf201,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf702, 0xf703, 0xf702, 0xf02b, 0xfa00, 0xf040, 0xf03f, 0xf200,
-+ 0xf200, 0xf009, 0xf104, 0xf105, 0xf106, 0xf200, 0xf200, 0xf301,
-+ 0xf302, 0xf303, 0xf304, 0xf305, 0xf306, 0xf307, 0xf308, 0xf309,
-+ 0xf300, 0xf07f, 0xf30d, 0xf30c, 0xf200, 0xf30b, 0xf30a, 0xf30e,
-+ 0xf702, 0xf703, 0xf01b, 0xf020, 0xf020, 0xf310, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf700,
-+ 0xf114, 0xf117, 0xf118, 0xf119, 0xf701, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf200, 0xf200,
-+ 0xf702, 0xf703, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+};
-+
-+u_short alt_map[] = {
-+ 0xf200, 0xf021, 0xf02d, 0xf863, 0xf023, 0xf033, 0xf024, 0xf025,
-+ 0xf05f, 0xf038, 0xf026, 0xf02a, 0xf028, 0xf03d, 0xf02b, 0xf039,
-+ 0xf030, 0xf031, 0xf034, 0xf040, 0xf035, 0xf037, 0xf876, 0xf032,
-+ 0xf878, 0xf036, 0xf87a, 0xf700, 0xf201, 0xf101, 0xf200, 0xf07f,
-+ 0xf208, 0xf200, 0xf01b, 0xf601, 0xf603, 0xf600, 0xf602, 0xf07d,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf702, 0xf703, 0xf702, 0xf02b, 0xfa00, 0xf040, 0xf03f, 0xf029,
-+ 0xf03c, 0xf207, 0xf104, 0xf105, 0xf106, 0xf200, 0xf07e, 0xf301,
-+ 0xf302, 0xf303, 0xf304, 0xf305, 0xf306, 0xf307, 0xf308, 0xf309,
-+ 0xf300, 0xf07f, 0xf30d, 0xf30c, 0xf200, 0xf30b, 0xf30a, 0xf30e,
-+ 0xf702, 0xf703, 0xf01b, 0xf000, 0xf020, 0xf310, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf700,
-+ 0xf114, 0xf117, 0xf118, 0xf119, 0xf701, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf200, 0xf200,
-+ 0xf702, 0xf703, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+};
-+
-+ushort *key_maps[MAX_NR_KEYMAPS] = {
-+ plain_map, shift_map, 0, 0,
-+ ctrl_map, shift_ctrl_map, 0, 0,
-+ alt_map, 0
-+};
-+
-+unsigned int keymap_count = 5;
-+
-+
-+/*
-+ * Philosophy: most people do not define more strings, but they who do
-+ * often want quite a lot of string space. So, we statically allocate
-+ * the default and allocate dynamically in chunks of 512 bytes.
-+ */
-+
-+char func_buf[] = {
-+ '\033', '[', '[', 'A', 0,
-+ '\033', '[', '[', 'B', 0,
-+ '\033', '[', '[', 'C', 0,
-+ '\033', '[', '[', 'D', 0,
-+ '\033', '[', '[', 'E', 0,
-+ '\033', '[', '1', '7', '~', 0,
-+ '\033', '[', '1', '8', '~', 0,
-+ '\033', '[', '1', '9', '~', 0,
-+ '\033', '[', '2', '0', '~', 0,
-+ '\033', '[', '2', '1', '~', 0,
-+ '\033', '[', '2', '3', '~', 0,
-+ '\033', '[', '2', '4', '~', 0,
-+ '\033', '[', '2', '5', '~', 0,
-+ '\033', '[', '2', '6', '~', 0,
-+ '\033', '[', '2', '8', '~', 0,
-+ '\033', '[', '2', '9', '~', 0,
-+ '\033', '[', '3', '1', '~', 0,
-+ '\033', '[', '3', '2', '~', 0,
-+ '\033', '[', '3', '3', '~', 0,
-+ '\033', '[', '3', '4', '~', 0,
-+ '\033', '[', '1', '~', 0,
-+ '\033', '[', '2', '~', 0,
-+ '\033', '[', '3', '~', 0,
-+ '\033', '[', '4', '~', 0,
-+ '\033', '[', '5', '~', 0,
-+ '\033', '[', '6', '~', 0,
-+ '\033', '[', 'M', 0,
-+ '\033', '[', 'P', 0,
-+};
-+
-+
-+char *funcbufptr = func_buf;
-+int funcbufsize = sizeof(func_buf);
-+int funcbufleft = 0; /* space left */
-+
-+char *func_table[MAX_NR_FUNC] = {
-+ func_buf + 0,
-+ func_buf + 5,
-+ func_buf + 10,
-+ func_buf + 15,
-+ func_buf + 20,
-+ func_buf + 25,
-+ func_buf + 31,
-+ func_buf + 37,
-+ func_buf + 43,
-+ func_buf + 49,
-+ func_buf + 55,
-+ func_buf + 61,
-+ func_buf + 67,
-+ func_buf + 73,
-+ func_buf + 79,
-+ func_buf + 85,
-+ func_buf + 91,
-+ func_buf + 97,
-+ func_buf + 103,
-+ func_buf + 109,
-+ func_buf + 115,
-+ func_buf + 120,
-+ func_buf + 125,
-+ func_buf + 130,
-+ func_buf + 135,
-+ func_buf + 140,
-+ func_buf + 145,
-+ 0,
-+ 0,
-+ func_buf + 149,
-+ 0,
-+};
-+
-+struct kbdiacr accent_table[MAX_DIACR] = {
-+ {'`', 'A', '\300'}, {'`', 'a', '\340'},
-+ {'\'', 'A', '\301'}, {'\'', 'a', '\341'},
-+ {'^', 'A', '\302'}, {'^', 'a', '\342'},
-+ {'~', 'A', '\303'}, {'~', 'a', '\343'},
-+ {'"', 'A', '\304'}, {'"', 'a', '\344'},
-+ {'O', 'A', '\305'}, {'o', 'a', '\345'},
-+ {'0', 'A', '\305'}, {'0', 'a', '\345'},
-+ {'A', 'A', '\305'}, {'a', 'a', '\345'},
-+ {'A', 'E', '\306'}, {'a', 'e', '\346'},
-+ {',', 'C', '\307'}, {',', 'c', '\347'},
-+ {'`', 'E', '\310'}, {'`', 'e', '\350'},
-+ {'\'', 'E', '\311'}, {'\'', 'e', '\351'},
-+ {'^', 'E', '\312'}, {'^', 'e', '\352'},
-+ {'"', 'E', '\313'}, {'"', 'e', '\353'},
-+ {'`', 'I', '\314'}, {'`', 'i', '\354'},
-+ {'\'', 'I', '\315'}, {'\'', 'i', '\355'},
-+ {'^', 'I', '\316'}, {'^', 'i', '\356'},
-+ {'"', 'I', '\317'}, {'"', 'i', '\357'},
-+ {'-', 'D', '\320'}, {'-', 'd', '\360'},
-+ {'~', 'N', '\321'}, {'~', 'n', '\361'},
-+ {'`', 'O', '\322'}, {'`', 'o', '\362'},
-+ {'\'', 'O', '\323'}, {'\'', 'o', '\363'},
-+ {'^', 'O', '\324'}, {'^', 'o', '\364'},
-+ {'~', 'O', '\325'}, {'~', 'o', '\365'},
-+ {'"', 'O', '\326'}, {'"', 'o', '\366'},
-+ {'/', 'O', '\330'}, {'/', 'o', '\370'},
-+ {'`', 'U', '\331'}, {'`', 'u', '\371'},
-+ {'\'', 'U', '\332'}, {'\'', 'u', '\372'},
-+ {'^', 'U', '\333'}, {'^', 'u', '\373'},
-+ {'"', 'U', '\334'}, {'"', 'u', '\374'},
-+ {'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
-+ {'T', 'H', '\336'}, {'t', 'h', '\376'},
-+ {'s', 's', '\337'}, {'"', 'y', '\377'},
-+ {'s', 'z', '\337'}, {'i', 'j', '\377'},
-+};
-+
-+unsigned int accent_table_size = 68;
-diff -Nur linux_c860_org/drivers/char/tosa_keymap.map linux/drivers/char/tosa_keymap.map
---- linux_c860_org/drivers/char/tosa_keymap.map 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/char/tosa_keymap.map 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,277 @@
-+# =======================================================
-+# Iris-1 Default Kernel Keymap for Console Driver
-+# =======================================================
-+#
-+# Default kernel keymap. This uses 7 modifier combinations.
-+#
-+# 0 for no modifier
-+# 1 for [SHIFT]
-+# 4 for [CTRL] , to symbol input for debug
-+# 5 for [CTRL] [SHIFT] , to symbol input for debug
-+# 8 for [ALT]
-+#
-+keymaps 0,1,4,5,8
-+#
-+# loadkeys --mktable iris_keymap.map
-+#
-+# !!!!!! CAUTION !!!!!!
-+# This Keymap Defines Conversion to Console-Key from Soft-Keycode.
-+# Soft-Keycode is created from Hard-Keycode , using iris_rawkey_conv.c
-+#
-+#
-+keycode 1 = a
-+ alt keycode 1 = exclam
-+keycode 2 = b
-+ alt keycode 2 = minus
-+keycode 3 = c
-+keycode 4 = d
-+ alt keycode 4 = numbersign
-+keycode 5 = e
-+ alt keycode 5 = three
-+keycode 6 = f
-+ alt keycode 6 = dollar
-+keycode 7 = g
-+ alt keycode 7 = percent
-+keycode 8 = h
-+ alt keycode 8 = underscore
-+keycode 9 = i
-+ alt keycode 9 = eight
-+keycode 10 = j
-+ alt keycode 10 = ampersand
-+keycode 11 = k
-+ alt keycode 11 = asterisk
-+keycode 12 = l
-+ alt keycode 12 = parenleft
-+keycode 13 = m
-+ alt keycode 13 = equal
-+keycode 14 = n
-+ alt keycode 14 = plus
-+keycode 15 = o
-+ alt keycode 15 = nine
-+keycode 16 = p
-+ alt keycode 16 = zero
-+keycode 17 = q
-+ alt keycode 17 = one
-+keycode 18 = r
-+ alt keycode 18 = four
-+keycode 19 = s
-+ alt keycode 19 = at
-+keycode 20 = t
-+ alt keycode 20 = five
-+keycode 21 = u
-+ alt keycode 21 = seven
-+keycode 22 = v
-+keycode 23 = w
-+ alt keycode 23 = two
-+keycode 24 = x
-+keycode 25 = y
-+ alt keycode 25 = six
-+keycode 26 = z
-+keycode 27 = Shift
-+keycode 28 = Return
-+keycode 29 = F2
-+keycode 30 = Alt Control
-+keycode 31 = BackSpace
-+ alt keycode 31 = Delete
-+keycode 32 = Num_Lock
-+keycode 33 =
-+# (Cancel:34) F9 -> Escape
-+keycode 34 = Escape
-+keycode 35 = Left
-+keycode 36 = Up
-+keycode 37 = Down
-+keycode 38 = Right
-+# (OK:39) F4 -> Return
-+keycode 39 = Return
-+ alt keycode 39 = braceright
-+keycode 40 =
-+keycode 41 = one exclam
-+keycode 42 = two quotedbl
-+keycode 43 = three numbersign
-+keycode 44 = four dollar
-+keycode 45 = five percent
-+keycode 46 = six ampersand
-+keycode 47 = seven apostrophe
-+keycode 48 = eight parenleft
-+keycode 49 = nine parenright
-+keycode 50 = zero asciitilde
-+keycode 51 = minus equal
-+keycode 52 = asciicircum asciitilde
-+keycode 53 = backslash bar
-+keycode 54 = bracketleft braceleft
-+keycode 55 = at grave
-+keycode 56 = Control
-+keycode 57 = Alt
-+keycode 58 = Control
-+keycode 59 = plus
-+keycode 60 = Shift_Lock
-+keycode 61 = at
-+keycode 62 = question
-+keycode 63 = comma semicolon
-+ alt keycode 63 = parenright
-+keycode 64 = period colon
-+ alt keycode 64 = less
-+keycode 65 = Tab
-+ alt keycode 65 = Caps_Lock
-+keycode 66 = F5
-+keycode 67 = F6
-+keycode 68 = F7
-+keycode 69 = slash question
-+keycode 70 = apostrophe quotedbl
-+ alt keycode 70 = asciitilde
-+keycode 71 = KP_1
-+keycode 72 = KP_2
-+keycode 73 = KP_3
-+keycode 74 = KP_4
-+keycode 75 = KP_5
-+keycode 76 = KP_6
-+keycode 77 = KP_7
-+keycode 78 = KP_8
-+keycode 79 = KP_9
-+keycode 80 = KP_0
-+keycode 81 = Delete
-+keycode 82 = KP_Divide
-+keycode 83 = KP_Multiply
-+keycode 84 =
-+keycode 85 = KP_Subtract
-+keycode 86 = KP_Add
-+keycode 87 = KP_Enter
-+# (Activity:88) -> Ctrl
-+keycode 88 = Control
-+# (Contacts:89) -> Alt
-+keycode 89 = Alt
-+keycode 90 = Escape
-+# (select:91) F11 -> space
-+keycode 91 = space
-+ alt keycode 91 = nul
-+keycode 92 = space
-+ control keycode 92 = nul
-+keycode 93 = KP_Period
-+keycode 94 =
-+keycode 95 = semicolon plus
-+keycode 96 = colon asterisk
-+keycode 97 = bracketright braceright
-+keycode 98 = comma less
-+keycode 99 = period greater
-+keycode 100 = slash question
-+keycode 101 = underscore underscore
-+keycode 102 =
-+keycode 103 = Shift
-+keycode 104 = Find
-+keycode 105 = Select
-+keycode 106 = Prior
-+ shift keycode 106 = Scroll_Backward
-+keycode 107 = Next
-+ shift keycode 107 = Scroll_Forward
-+keycode 108 = AltGr
-+keycode 109 =
-+keycode 110 =
-+keycode 111 =
-+keycode 112 =
-+keycode 113 =
-+keycode 114 =
-+keycode 115 =
-+keycode 116 =
-+keycode 117 = Control
-+keycode 118 =
-+keycode 119 =
-+keycode 120 = Control
-+keycode 121 = Alt
-+
-+
-+string F1 = "\033[[A"
-+string F2 = "\033[[B"
-+string F3 = "\033[[C"
-+string F4 = "\033[[D"
-+string F5 = "\033[[E"
-+string F6 = "\033[17~"
-+string F7 = "\033[18~"
-+string F8 = "\033[19~"
-+string F9 = "\033[20~"
-+string F10 = "\033[21~"
-+string F11 = "\033[23~"
-+string F12 = "\033[24~"
-+string F13 = "\033[25~"
-+string F14 = "\033[26~"
-+string F15 = "\033[28~"
-+string F16 = "\033[29~"
-+string F17 = "\033[31~"
-+string F18 = "\033[32~"
-+string F19 = "\033[33~"
-+string F20 = "\033[34~"
-+string Find = "\033[1~"
-+string Insert = "\033[2~"
-+string Remove = "\033[3~"
-+string Select = "\033[4~"
-+string Prior = "\033[5~"
-+string Next = "\033[6~"
-+string Macro = "\033[M"
-+string Pause = "\033[P"
-+compose '`' 'A' to 'À'
-+compose '`' 'a' to 'à'
-+compose '\'' 'A' to 'Á'
-+compose '\'' 'a' to 'á'
-+compose '^' 'A' to 'Â'
-+compose '^' 'a' to 'â'
-+compose '~' 'A' to 'Ã'
-+compose '~' 'a' to 'ã'
-+compose '"' 'A' to 'Ä'
-+compose '"' 'a' to 'ä'
-+compose 'O' 'A' to 'Å'
-+compose 'o' 'a' to 'å'
-+compose '0' 'A' to 'Å'
-+compose '0' 'a' to 'å'
-+compose 'A' 'A' to 'Å'
-+compose 'a' 'a' to 'å'
-+compose 'A' 'E' to 'Æ'
-+compose 'a' 'e' to 'æ'
-+compose ',' 'C' to 'Ç'
-+compose ',' 'c' to 'ç'
-+compose '`' 'E' to 'È'
-+compose '`' 'e' to 'è'
-+compose '\'' 'E' to 'É'
-+compose '\'' 'e' to 'é'
-+compose '^' 'E' to 'Ê'
-+compose '^' 'e' to 'ê'
-+compose '"' 'E' to 'Ë'
-+compose '"' 'e' to 'ë'
-+compose '`' 'I' to 'Ì'
-+compose '`' 'i' to 'ì'
-+compose '\'' 'I' to 'Í'
-+compose '\'' 'i' to 'í'
-+compose '^' 'I' to 'Î'
-+compose '^' 'i' to 'î'
-+compose '"' 'I' to 'Ï'
-+compose '"' 'i' to 'ï'
-+compose '-' 'D' to 'Ð'
-+compose '-' 'd' to 'ð'
-+compose '~' 'N' to 'Ñ'
-+compose '~' 'n' to 'ñ'
-+compose '`' 'O' to 'Ò'
-+compose '`' 'o' to 'ò'
-+compose '\'' 'O' to 'Ó'
-+compose '\'' 'o' to 'ó'
-+compose '^' 'O' to 'Ô'
-+compose '^' 'o' to 'ô'
-+compose '~' 'O' to 'Õ'
-+compose '~' 'o' to 'õ'
-+compose '"' 'O' to 'Ö'
-+compose '"' 'o' to 'ö'
-+compose '/' 'O' to 'Ø'
-+compose '/' 'o' to 'ø'
-+compose '`' 'U' to 'Ù'
-+compose '`' 'u' to 'ù'
-+compose '\'' 'U' to 'Ú'
-+compose '\'' 'u' to 'ú'
-+compose '^' 'U' to 'Û'
-+compose '^' 'u' to 'û'
-+compose '"' 'U' to 'Ü'
-+compose '"' 'u' to 'ü'
-+compose '\'' 'Y' to 'Ý'
-+compose '\'' 'y' to 'ý'
-+compose 'T' 'H' to 'Þ'
-+compose 't' 'h' to 'þ'
-+compose 's' 's' to 'ß'
-+compose '"' 'y' to 'ÿ'
-+compose 's' 'z' to 'ß'
-+compose 'i' 'j' to 'ÿ'
-diff -Nur linux_c860_org/drivers/char/tosa_logkey.c linux/drivers/char/tosa_logkey.c
---- linux_c860_org/drivers/char/tosa_logkey.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/char/tosa_logkey.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,1617 @@
-+/*
-+ * linux/drivers/char/tosa_logkey.c
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * Based on:
-+ * linux/drivers/char/corgi_logkey.c
-+ *
-+ * Based on:
-+ * linux/drivers/char/poodle_logkey.c
-+ * linux/drivers/char/collie_logkey.c
-+ * linux/drivers/char/sharp_logkey.c
-+ *
-+ * Logical GPIO Keyboard driver includeing
-+ * Hard-Key to Soft-Key Mapper for SHARP PDA
-+ *
-+ * Copyright (C) 2001 SHARP
-+ *
-+ * 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.
-+ *
-+ * ChangeLog:
-+ * 04-16-2001 Lineo Japan, Inc.
-+ * 30-Jul-2002 Lineo Japan, Inc. for 2.4.18
-+ * 12-Dec-2002 Sharp Corporation
-+ */
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/poll.h>
-+#include <linux/wait.h>
-+#include <asm/arch/keyboard_tosa.h>
-+#include <asm/uaccess.h>
-+#include <linux/tqueue.h>
-+#include <linux/kbd_ll.h>
-+#include <linux/slab.h>
-+//#include <linux/spinlock.h>
-+#include <linux/delay.h>
-+
-+#define DEBUGPRINT(s) /* printk s */
-+#define CUS_DPRINTK(x, args...) /* printk(__FUNCTION__ ": " x,##args) */
-+
-+#ifdef LOGICAL_WAKEUP_SRC
-+#include <asm/arch/sharpsl_wakeup.h>
-+#endif
-+#define KEYMASK_ON (0x1<<0)
-+#define KEYMASK_REC (0x1<<1)
-+#define KEYMASK_SYNC (0x1<<2)
-+#define KEYMASK_ADDRESS (0x1<<3)
-+#define KEYMASK_CALENDAR (0x1<<4)
-+#define KEYMASK_MENU (0x1<<5)
-+#define KEYMASK_MAIL (0x1<<6)
-+
-+#ifndef USE_KBD_IRQ
-+# warning "this is not tested."
-+#endif
-+
-+#ifdef USE_KBD_IRQ // could be defined in asm/arch/keyboard.h
-+# include <asm/irq.h> /* for linkup keyboard interrupt */
-+#endif
-+
-+/*
-+ * physical driver definition
-+ */
-+# define WAIT_CHATTERING_DELAY udelay(100)
-+extern void tosa_kbd_discharge_all(void);
-+extern void tosa_kbd_charge_all(void);
-+extern void tosa_kbd_activate_col(int col);
-+extern void tosa_kbd_reset_col(int col);
-+extern void tosa_kbd_activate_all(void);
-+# define DISCHARGE_ALL tosa_kbd_discharge_all()
-+# define CHARGE_ALL tosa_kbd_charge_all()
-+# define WAIT_DISCHARGE_DELAY udelay(KB_DISCHARGE_DELAY)
-+# define ACTIVATE_COL(c) tosa_kbd_activate_col((c))
-+# define RESET_COL(c) tosa_kbd_reset_col((c))
-+# define WAIT_ACTIVATE_DELAY udelay(KB_ACTIVATE_DELAY)
-+# define GET_ROWS_STATUS(c) ((GPLR2 & GPIO_ALL_SENSE_BIT) >> GPIO_ALL_SENSE_RSHIFT)
-+# define DRIVE_ALL_COLS tosa_kbd_activate_all()
-+# define GET_REAL_COL_FROM_COL(c) (c)
-+# define RAW_MAP "tosa_rawmap.h"
-+# define RAW_MAP_ROLLOVER "tosa_rawmap_rollover.h"
-+
-+
-+static int isBrb = 0;
-+static int checkBrb(void)
-+{
-+ int rowd;
-+
-+ DISCHARGE_ALL;
-+ WAIT_DISCHARGE_DELAY;
-+
-+ rowd = GET_ROWS_STATUS(1);
-+ if (rowd!=0) return 1;
-+ else return 0;
-+}
-+
-+
-+#if ! defined(KB_COLS) || ! defined(KB_ROWS)
-+#error "KB_COLS or KB_ROWS not defined"
-+#endif
-+
-+/*
-+ * keyboard scancode mapper.
-+ */
-+#include <asm/sharp_keycode.h>
-+
-+#define CHECK_ROLLOVER 1
-+
-+#define CHECK_CHUTTER_BOUNCE 1
-+
-+/*
-+ sharppda_kbdstate.in - state
-+ 0 - not pressed
-+ PRESSING1 - pressing (check chutter)
-+ : - pressing (check chutter)
-+ CHECK_CHUTTER - pressing (check chutter)
-+ JUST_PRESSED - just pressed (throw key down)
-+ PRESSED - pressed
-+ RELEASING1 - releasing (check bounce)
-+ : - releasing (check bounce)
-+ PRESSED + CHECK_BOUNCE - releasing (check bounce)
-+ JUST_RELEASED - just released (throw key up)
-+*/
-+#define CHECK_CHUTTER (2) /* * 10ms */
-+#define CHECK_BOUNCE (4) /* * 10ms */
-+#define NOTPRESSED (0)
-+#define PRESSING1 (1)
-+#define JUST_PRESSED (CHECK_CHUTTER+1)
-+#define PRESSED (CHECK_CHUTTER+2)
-+#define RELEASING1 (CHECK_CHUTTER+3)
-+#define JUST_RELEASED (CHECK_CHUTTER+CHECK_BOUNCE+3)
-+#define ROLLOVERERROR (CHECK_CHUTTER+CHECK_BOUNCE+4)
-+#define IS_PRESSING(a) (((a) >= PRESSING1) && ((a) <= CHECK_CHUTTER))
-+#define IS_RELEASING(a) (((a) >= RELEASING1) && ((a) <= PRESSED + CHECK_BOUNCE))
-+#define CHUTTER_BOUNCE_LOG 0
-+
-+#include RAW_MAP
-+#if CHECK_ROLLOVER
-+#include RAW_MAP_ROLLOVER
-+#endif
-+
-+/*
-+ * This is the mapper for Hard-Key to Soft-Key conversion
-+ */
-+
-+int sharp_cur_keycode[(NR_KEYCODES+1)];
-+int sharp_cur_status;
-+int tosa_initial_keypress = -1;
-+
-+kbd_keyinfo sharppda_kbdstate[(NR_KEYCODES+1)]; /* this map is expoted... */
-+
-+static int keysdown = 0;
-+static struct tq_struct kbdhw_task;
-+
-+/*
-+ * for panel-touch sound
-+ */
-+extern void sharpbuz_make_keytouch_sound(void);
-+extern void sharpkbdctl_stat_changed(void);
-+
-+/*
-+ * Keyboard mapping routine.
-+ */
-+
-+int keypress_map(int hardkey)
-+{
-+ int softkey;
-+ unsigned char* pmodmap;
-+ int modif_ref = DOWN_NOP;
-+ int next_status = sharp_cur_status;
-+
-+ /* ======== get soft keycode ========= */
-+ pmodmap = state_to_keymap[sharp_cur_status];
-+ softkey = pmodmap[hardkey];
-+ sharp_cur_keycode[hardkey] = softkey;
-+
-+ /* ======== check automaton-map ======== */
-+ modif_ref = down_modifs_ref[hardkey];
-+ if( modif_ref != DOWN_NOP && modif_ref < DOWN_TABLES_SIZE ){
-+ /* ======== need to check state machine ========= */
-+ unsigned char* statemap;
-+ statemap = down_tables[modif_ref];
-+ next_status = statemap[sharp_cur_status];
-+ }
-+
-+ if( sharp_cur_status != next_status ){
-+ sharp_cur_status = next_status;
-+ sharpkbdctl_stat_changed();
-+ }else{
-+ sharp_cur_status = next_status;
-+ }
-+ return softkey;
-+}
-+
-+int keyrelease_map(int hardkey)
-+{
-+ int softkey;
-+ int modif_ref = UP_NOP;
-+ int next_status = sharp_cur_status;
-+
-+ /* ======== get soft keycode ========= */
-+ softkey = sharp_cur_keycode[hardkey];
-+ sharp_cur_keycode[hardkey] = KEY_IGN;
-+
-+ /* ======== check automaton-map ======== */
-+ modif_ref = up_modifs_ref[hardkey];
-+ if( modif_ref != UP_NOP && modif_ref < UP_TABLES_SIZE ){
-+ /* ======== need to check state machine ========= */
-+ unsigned char* statemap;
-+ statemap = up_tables[modif_ref];
-+ next_status = statemap[sharp_cur_status];
-+ }
-+
-+ if( sharp_cur_status != next_status ){
-+ sharp_cur_status = next_status;
-+ sharpkbdctl_stat_changed();
-+ }else{
-+ sharp_cur_status = next_status;
-+ }
-+ return softkey;
-+}
-+
-+/*
-+ * Keyboard Repeat , including key-mapping
-+ */
-+#include <linux/kd.h>
-+
-+int (*mach_kbdrate) (struct kbd_repeat *);
-+
-+
-+#define DEFAULT_KEYB_REP_DELAY (HZ*2)
-+#define DEFAULT_KEYB_REP_RATE (HZ)
-+
-+static void sharppda_kbd_rep( unsigned long ignore );
-+static unsigned char rep_scancode = 0;
-+static unsigned int key_repeat_delay = DEFAULT_KEYB_REP_DELAY;
-+static unsigned int key_repeat_rate = DEFAULT_KEYB_REP_RATE;
-+
-+static struct timer_list sharppda_kbd_rep_timer = { function: sharppda_kbd_rep };
-+
-+static void sharppda_kbd_rep( unsigned long ignore )
-+{
-+ unsigned long flags;
-+ /* Disable keyboard for the time we call handle_scancode(), else a race
-+ * in the keyboard tty queue may happen */
-+ //DEBUGPRINT(("?"));
-+ save_flags(flags); cli();
-+ del_timer( &sharppda_kbd_rep_timer );
-+ /* A keyboard int may have come in before we disabled the irq, so
-+ * double-check whether rep_scancode is still != 0 */
-+ if (rep_scancode) {
-+ init_timer(&sharppda_kbd_rep_timer);
-+ sharppda_kbd_rep_timer.expires = jiffies + key_repeat_rate;
-+ add_timer( &sharppda_kbd_rep_timer );
-+ DEBUGPRINT(("kbdrep_down %d (%x)\n",rep_scancode,rep_scancode));
-+ }
-+ restore_flags(flags);
-+ //DEBUGPRINT(("!"));
-+}
-+
-+static int sharppda_kbd_kbdrate( struct kbd_repeat *k )
-+{
-+ DEBUGPRINT(("sharppda_kbd_kbdrate\n"));
-+ if (k->delay > 0) {
-+ /* convert from msec to jiffies */
-+ key_repeat_delay = (k->delay * HZ + 500) / 1000;
-+ if (key_repeat_delay < 1)
-+ key_repeat_delay = 1;
-+ }
-+ if (k->rate > 0) {
-+ key_repeat_rate = (k->rate * HZ + 500) / 1000;
-+ if (key_repeat_rate < 1)
-+ key_repeat_rate = 1;
-+ }
-+ k->delay = key_repeat_delay * 1000 / HZ;
-+ k->rate = key_repeat_rate * 1000 / HZ;
-+ return( 0 );
-+}
-+
-+/*
-+ * Keyboard Press/Release function , including key-mapping , for HOLD-modified Key
-+ */
-+
-+static unsigned long key_hold_delay = 120 * HZ / 100;
-+
-+static unsigned char holdkey_pending = 0;
-+static int holdkey_pendinghardkey = 0;
-+static int holdkey_pendingmappedkey = 0;
-+static void sharppda_kbd_hold( unsigned long ignore );
-+static struct timer_list sharppda_kbd_hold_timer = { function: sharppda_kbd_hold };
-+
-+static shappda_holdkey_info **custom_holdkey_info = NULL;
-+
-+#if CHECK_ROLLOVER
-+// rollover_state
-+// 0 .. not detected roll over error in previous key scan
-+// 1 .. detected roll over error in previous key scan
-+static int rollover_state = 0;
-+
-+static unsigned char rep_hardkey = 0;
-+#endif
-+
-+static void sharppda_kbd_hold( unsigned long ignore )
-+{
-+ int hold_keycode;
-+ unsigned long flags;
-+ shappda_holdkey_info *hold_infop = NULL;
-+ save_flags(flags); cli();
-+ del_timer(&sharppda_kbd_hold_timer);
-+ DEBUGPRINT(("sharppda_kbd_hold\n"));
-+ CUS_DPRINTK("enter\n");
-+ if( holdkey_pending && holdkey_info ){
-+ CUS_DPRINTK("pending exists\n");
-+ if( holdkey_pendinghardkey ){
-+ CUS_DPRINTK("holdkey_pendinghardkey\n");
-+ hold_infop = holdkey_info[holdkey_pendinghardkey];
-+ if( custom_holdkey_info ){ /* use Customozed HoldKey */
-+ CUS_DPRINTK("customized holdkey\n");
-+ hold_infop = custom_holdkey_info[holdkey_pendinghardkey];
-+ }
-+ if( ! hold_infop ){
-+ DEBUGPRINT(("NO VALID INFO found for %x\n",holdkey_pendinghardkey));
-+ }else if( hold_infop->type == HOLDKEYTYPE_CHAR ){
-+ DEBUGPRINT(("HOLD eventtype is HOLDKEYTYPE_CHAR for %x\n",holdkey_pendinghardkey));
-+ hold_keycode = hold_infop->character;
-+ DEBUGPRINT(("Pending Key Exists for Hard-Key %x.\n",holdkey_pendinghardkey));
-+ DEBUGPRINT(("Current Keycode is %x , %x\n",
-+ holdkey_pendingmappedkey,sharp_cur_keycode[holdkey_pendinghardkey]));
-+ DEBUGPRINT(("Changing to HOLD-KEY %x\n",hold_keycode));
-+ sharp_cur_keycode[holdkey_pendinghardkey] = hold_keycode;
-+ DEBUGPRINT(("kbdhold %d (%x)\n",KBSCANCDE(hold_keycode,KBDOWN),KBSCANCDE(hold_keycode,KBDOWN)));
-+ handle_scancode(KBSCANCDE(hold_keycode,KBDOWN), 1);
-+ del_timer(&sharppda_kbd_rep_timer);
-+ init_timer(&sharppda_kbd_rep_timer);
-+ sharppda_kbd_rep_timer.expires = jiffies + key_repeat_delay;
-+/* 2001.09.05 Nami. delete hold-key repeat */
-+/* delete hold-key repeat on Iris , too. */
-+ rep_scancode = KBSCANCDE(hold_keycode,KBDOWN);
-+#if CHECK_ROLLOVER
-+ rep_hardkey = holdkey_pendinghardkey;
-+#endif
-+ }else if( hold_infop->type == HOLDKEYTYPE_FUNC ){
-+ DEBUGPRINT(("HOLD eventtype is HOLDKEYTYPE_FUNC for %x\n",holdkey_pendinghardkey));
-+ if( hold_infop->func ){
-+ DEBUGPRINT(("Executing FUNC\n"));
-+ (*(hold_infop->func))();
-+ }
-+ }else{
-+ DEBUGPRINT(("NO VALID TYPE found for %x\n",holdkey_pendinghardkey));
-+ }
-+ }
-+ }
-+ holdkey_pending = 0;
-+ holdkey_pendinghardkey = 0;
-+ holdkey_pendingmappedkey = 0;
-+ DEBUGPRINT(("Pending Key Released.\n"));
-+ restore_flags(flags);
-+}
-+
-+
-+
-+/*
-+ * Keyboard Press/Release function , including key-mapping
-+ */
-+
-+void sharppda_kbd_press(int keycode)
-+{
-+ unsigned long flags;
-+ unsigned char newpress = 0;
-+ int keycode_mapped = keycode;
-+
-+// printk("kbd_press=%d\n",keycode);
-+
-+ spin_lock_irqsave(&kbd_spinlock,flags);
-+#if CHECK_CHUTTER_BOUNCE
-+ if (IS_RELEASING(sharppda_kbdstate[keycode].in)) {
-+ // detected bounce ?
-+ sharppda_kbdstate[keycode].in = PRESSED;
-+#if CHUTTER_BOUNCE_LOG
-+ printk("BOUNCE? keycode %d state %d\n", keycode, sharppda_kbdstate[keycode].in);
-+#endif
-+ }
-+ else if (IS_PRESSING(sharppda_kbdstate[keycode].in) ||
-+ (sharppda_kbdstate[keycode].in == NOTPRESSED)) {
-+ // pressing
-+ sharppda_kbdstate[keycode].in++;
-+#if CHUTTER_BOUNCE_LOG
-+ printk("PRESSING keycode %d state %d\n", keycode, sharppda_kbdstate[keycode].in);
-+#endif
-+ }
-+ if (sharppda_kbdstate[keycode].in == JUST_PRESSED) {
-+ keysdown++;
-+ newpress = 1;
-+ sharppda_kbdstate[keycode].in = PRESSED;
-+#if CHUTTER_BOUNCE_LOG
-+ printk("JUST_PRESSED keycode %d state %d\n", keycode, sharppda_kbdstate[keycode].in);
-+#endif
-+ }
-+#else
-+ if (!sharppda_kbdstate[keycode].in) {
-+ keysdown++;
-+ newpress = 1;
-+#if CHECK_ROLLOVER
-+ sharppda_kbdstate[keycode].in=1;
-+#endif
-+ }
-+#endif
-+
-+ /*
-+ * We approximate a retriggable monostable
-+ * action.
-+ */
-+
-+#if !CHECK_ROLLOVER
-+ sharppda_kbdstate[keycode].in=1;
-+#endif
-+ spin_unlock_irqrestore(&kbd_spinlock,flags);
-+
-+ /* We only need to ensure keysdown consistent */
-+
-+ /* Map Keycode */
-+ if( newpress ){
-+ keycode_mapped = keypress_map(keycode);
-+ }
-+
-+ /* put into upper layer */
-+ if (newpress){
-+ shappda_holdkey_info **use_holdkey_info;
-+ use_holdkey_info = holdkey_info;
-+ if( custom_holdkey_info ){
-+ CUS_DPRINTK("customized holdkey\n");
-+ use_holdkey_info = custom_holdkey_info;
-+ }
-+ if( use_holdkey_info && use_holdkey_info[keycode] ){
-+ CUS_DPRINTK("keycode found\n");
-+ if( ! holdkey_pending ){
-+ DEBUGPRINT(("HOLD keyinfo found for %x. mapped=%x\n",keycode,keycode_mapped));
-+ holdkey_pendinghardkey = keycode;
-+ holdkey_pendingmappedkey = keycode_mapped;
-+ holdkey_pending = 1;
-+ del_timer(&sharppda_kbd_hold_timer);
-+ init_timer(&sharppda_kbd_hold_timer);
-+#ifdef HOLDKEY_INFO_HAS_TIMEOUT
-+ if( use_holdkey_info[keycode]->timeout )
-+ {
-+ unsigned long diff = use_holdkey_info[keycode]->timeout * HZ / 1000;
-+ CUS_DPRINTK("has timeout %d\n",use_holdkey_info[keycode]->timeout);
-+ sharppda_kbd_hold_timer.expires = jiffies + diff;
-+ }
-+ else{ /* set default value */
-+ CUS_DPRINTK("default timeout\n");
-+ sharppda_kbd_hold_timer.expires = jiffies + key_hold_delay;
-+ }
-+#else
-+ sharppda_kbd_hold_timer.expires = jiffies + key_hold_delay;
-+#endif
-+ add_timer( &sharppda_kbd_hold_timer );
-+ DEBUGPRINT(("holding...\n"));
-+ return;
-+ }else{
-+ DEBUGPRINT(("HOLD keyinfo found for %d but already pending...\n",keycode));
-+ }
-+ }
-+ DEBUGPRINT(("kbdpress %d (%x)\n",KBSCANCDE(keycode_mapped,KBDOWN),KBSCANCDE(keycode_mapped,KBDOWN)));
-+ handle_scancode(KBSCANCDE(keycode_mapped,KBDOWN), 1);
-+ // printk("handle_scankey=%x\n",KBSCANCDE(keycode_mapped,KBDOWN));
-+ del_timer(&sharppda_kbd_rep_timer);
-+ init_timer(&sharppda_kbd_rep_timer);
-+ sharppda_kbd_rep_timer.expires = jiffies + key_repeat_delay;
-+ add_timer( &sharppda_kbd_rep_timer );
-+ rep_scancode = KBSCANCDE(keycode_mapped,KBDOWN);
-+#if CHECK_ROLLOVER
-+ rep_hardkey = keycode;
-+#endif
-+ }
-+}
-+
-+#if CHECK_ROLLOVER
-+void sharppda_kbd_press_rollover(int keycode)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&kbd_spinlock,flags);
-+#if CHECK_CHUTTER_BOUNCE
-+ if (sharppda_kbdstate[keycode].in == NOTPRESSED) {
-+ keysdown++;
-+ sharppda_kbdstate[keycode].in=ROLLOVERERROR;
-+#if CHUTTER_BOUNCE_LOG
-+ printk("ROLLOVERERROR keycode %d state %d\n", keycode, sharppda_kbdstate[keycode].in);
-+#endif
-+ }
-+#else
-+ if (!sharppda_kbdstate[keycode].in) {
-+ keysdown++;
-+ sharppda_kbdstate[keycode].in=2;
-+ }
-+#endif
-+ // key is down but not handle_scancode()
-+ spin_unlock_irqrestore(&kbd_spinlock,flags);
-+}
-+
-+void sharppda_kbd_press_force_rollover(int keycode)
-+{
-+ unsigned long flags;
-+
-+ spin_lock_irqsave(&kbd_spinlock,flags);
-+#if CHECK_CHUTTER_BOUNCE
-+ if ((sharppda_kbdstate[keycode].in != PRESSED) &&
-+ (sharppda_kbdstate[keycode].in != ROLLOVERERROR)) {
-+ keysdown++;
-+ }
-+ sharppda_kbdstate[keycode].in=ROLLOVERERROR;
-+#if CHUTTER_BOUNCE_LOG
-+ printk("force ROLLOVERERROR keycode %d state %d\n", keycode, sharppda_kbdstate[keycode].in);
-+#endif
-+#else
-+ if (!sharppda_kbdstate[keycode].in) {
-+ keysdown++;
-+ }
-+ sharppda_kbdstate[keycode].in=2;
-+#endif
-+ // key is down but not handle_scancode()
-+ spin_unlock_irqrestore(&kbd_spinlock,flags);
-+}
-+#endif
-+
-+void sharppda_kbd_release(int keycode)
-+{
-+ unsigned long flags;
-+ unsigned char newrelease = 0;
-+ int keycode_mapped = keycode;
-+
-+//printk("kbd_release=%d\n",keycode);
-+ spin_lock_irqsave(&kbd_spinlock,flags);
-+#if CHECK_CHUTTER_BOUNCE
-+ if (IS_PRESSING(sharppda_kbdstate[keycode].in)) {
-+ // detected chutter ?
-+ sharppda_kbdstate[keycode].in = NOTPRESSED;
-+#if CHUTTER_BOUNCE_LOG
-+ printk("CHUTTER? keycode %d state %d\n", keycode, sharppda_kbdstate[keycode].in);
-+#endif
-+ }
-+ else if (IS_RELEASING(sharppda_kbdstate[keycode].in) ||
-+ (sharppda_kbdstate[keycode].in == PRESSED)) {
-+ // releasing
-+ sharppda_kbdstate[keycode].in++;
-+#if CHUTTER_BOUNCE_LOG
-+ printk("RELEASING keycode %d state %d\n", keycode, sharppda_kbdstate[keycode].in);
-+#endif
-+ }
-+ else if (sharppda_kbdstate[keycode].in == ROLLOVERERROR) {
-+ keysdown--;
-+ sharppda_kbdstate[keycode].in = NOTPRESSED;
-+#if CHUTTER_BOUNCE_LOG
-+ printk("was ROLLOVERERROR keycode %d state %d\n", keycode, sharppda_kbdstate[keycode].in);
-+#endif
-+ }
-+ if (sharppda_kbdstate[keycode].in == JUST_RELEASED) {
-+ keysdown--;
-+ newrelease = 1;
-+ sharppda_kbdstate[keycode].in = NOTPRESSED;
-+#if CHUTTER_BOUNCE_LOG
-+ printk("JUST_RELEASED keycode %d state %d\n", keycode, sharppda_kbdstate[keycode].in);
-+#endif
-+ }
-+#else
-+ if (sharppda_kbdstate[keycode].in) {
-+ keysdown--;
-+#if CHECK_ROLLOVER
-+ if (sharppda_kbdstate[keycode].in==1) {
-+#endif
-+ newrelease = 1;
-+#if CHECK_ROLLOVER
-+ }
-+#endif
-+ }
-+#endif
-+
-+#if !CHECK_CHUTTER_BOUNCE
-+ sharppda_kbdstate[keycode].in=0;
-+#endif
-+ spin_unlock_irqrestore(&kbd_spinlock,flags);
-+
-+ /* We only need to ensure keysdown consistent */
-+
-+
-+ /* Map Keycode */
-+ if( newrelease ){
-+ keycode_mapped = keyrelease_map(keycode);
-+ }
-+
-+ if (newrelease){
-+ if( holdkey_pending ){
-+ DEBUGPRINT(("HOLD pending.\n"));
-+ if( holdkey_pendinghardkey == keycode ){
-+ DEBUGPRINT(("HOLDed key is same as pending-key. %x\n",keycode));
-+ DEBUGPRINT(("Current MappedKey is %x.\n",holdkey_pendingmappedkey));
-+ DEBUGPRINT(("kbdrel hold %d (%x)\n",KBSCANCDE(holdkey_pendingmappedkey,KBDOWN),KBSCANCDE(holdkey_pendingmappedkey,KBDOWN)));
-+ handle_scancode(KBSCANCDE(holdkey_pendingmappedkey,KBDOWN), 1);
-+ del_timer(&sharppda_kbd_hold_timer);
-+ holdkey_pending = 0;
-+ holdkey_pendinghardkey = 0;
-+ holdkey_pendingmappedkey = 0;
-+ DEBUGPRINT(("HOLDed key is released.\n"));
-+ }
-+ }
-+ DEBUGPRINT(("kbdrel nom %d (%x)\n",KBSCANCDE(keycode_mapped,KBUP),KBSCANCDE(keycode_mapped,KBUP)));
-+ handle_scancode(KBSCANCDE(keycode_mapped,KBUP), 0);
-+ // printk("handle_scankey=%x\n",KBSCANCDE(keycode_mapped,KBUP));
-+ if( rep_scancode == KBSCANCDE(keycode_mapped,KBDOWN) ){
-+ rep_scancode = 0;
-+#if CHECK_ROLLOVER
-+ rep_hardkey = 0;
-+#endif
-+ //DEBUGPRINT(("%%"));
-+ del_timer( &sharppda_kbd_rep_timer );
-+ }
-+ }
-+
-+}
-+
-+/*
-+ * Keyboard Scan routine , using GPIO
-+ */
-+
-+
-+#if CHECK_ROLLOVER
-+#define MAX_KEY_PRESS (6)
-+#endif
-+
-+static void port_key_delay_proc( unsigned long port_key );
-+#define PORT_KEY_NUM 3
-+#define IDPORT_ON 0
-+#define IDPORT_REC 1
-+#define IDPORT_SYNC 2
-+static int port_key_setting[PORT_KEY_NUM] = { 30, 90, 5 }; // -1:disable, 0~: x10ms wait for detect
-+static int port_key_delay_state[PORT_KEY_NUM] = {NOTPRESSED,NOTPRESSED,NOTPRESSED};
-+static struct timer_list port_key_delay_timer = { function: port_key_delay_proc };
-+static int port_key_pending = 0;
-+
-+static void reset_port_key_delay(void)
-+{
-+ int i;
-+ del_timer(&port_key_delay_timer);
-+ for (i=0; i<PORT_KEY_NUM; i++) port_key_delay_state[i]=NOTPRESSED;
-+ port_key_pending = 0;
-+}
-+
-+// num = 0:On key, 1:Rec key, 2:Sync key
-+// val = -1:disable, 0~: x10ms wait for detect
-+int set_port_key_setting( int num, int val )
-+{
-+ if (num<0 || num>=PORT_KEY_NUM) return -1;
-+ port_key_setting[num] = val;
-+ port_key_delay_state[num] = NOTPRESSED;
-+ port_key_pending = 0;
-+ return 0;
-+}
-+int get_port_key_setting( int num )
-+{
-+ if (num<0 || num>=PORT_KEY_NUM) return -1;
-+ return port_key_setting[num];
-+}
-+
-+static int read_port_key_status_raw(void)
-+{
-+ int val=0;
-+ // Power
-+ if ((GPLR0 & GPIO_bit(GPIO_ON_KEY))==0) val |= KEYMASK_ON;
-+ // Record
-+ if ((GPLR0 & GPIO_bit(GPIO_RECORD_BTN))==0) val |= KEYMASK_REC;
-+ // Sync
-+ if ((GPLR0 & GPIO_bit(GPIO_SYNC))==0) val |= KEYMASK_SYNC;
-+ return val;
-+}
-+
-+static void port_key_delay_proc( unsigned long port_key )
-+{
-+ int val=read_port_key_status_raw();
-+
-+ switch( port_key ) {
-+ case IDPORT_ON:
-+ if (port_key_delay_state[IDPORT_ON]!=PRESSING1 || (val&KEYMASK_ON) ) {
-+ port_key_delay_state[IDPORT_ON] = PRESSED;
-+ } else {
-+ port_key_delay_state[IDPORT_ON] = NOTPRESSED;
-+ }
-+ break;
-+ case IDPORT_REC:
-+ if (port_key_delay_state[IDPORT_REC]!=PRESSING1 || (val&KEYMASK_REC) ) {
-+ port_key_delay_state[IDPORT_REC] = PRESSED;
-+ } else {
-+ port_key_delay_state[IDPORT_REC] = NOTPRESSED;
-+ }
-+ break;
-+ case IDPORT_SYNC:
-+ if (port_key_delay_state[IDPORT_SYNC]!=PRESSING1 || (val&KEYMASK_SYNC) ) {
-+ port_key_delay_state[IDPORT_SYNC] = PRESSED;
-+ } else {
-+ port_key_delay_state[IDPORT_SYNC] = NOTPRESSED;
-+ }
-+ break;
-+ }
-+ port_key_pending = 0;
-+}
-+
-+static int read_port_key_status(void)
-+{
-+ int ret=0,val=read_port_key_status_raw();
-+
-+ // Power
-+ if (val & KEYMASK_ON) { // press
-+ if (port_key_setting[IDPORT_ON]==0) { // normal key
-+ ret |= KEYMASK_ON;
-+ } else if (port_key_setting[IDPORT_ON]>0) { // delay key
-+ if (port_key_delay_state[IDPORT_ON]==PRESSED) { // already detected
-+ ret |= KEYMASK_ON;
-+ } else if (port_key_delay_state[IDPORT_ON]==NOTPRESSED) { // start timer
-+ reset_port_key_delay();
-+ port_key_delay_state[IDPORT_ON]=PRESSING1;
-+ init_timer(&port_key_delay_timer);
-+ port_key_delay_timer.expires = jiffies + port_key_setting[IDPORT_ON];
-+ port_key_delay_timer.data = IDPORT_ON;
-+ add_timer(&port_key_delay_timer);
-+ port_key_pending = 1;
-+ return ret; // ignore following key
-+ }
-+ }
-+ } else { // release
-+ if (port_key_delay_state[IDPORT_ON]!=NOTPRESSED && port_key_setting[IDPORT_ON]>0) {
-+ del_timer(&port_key_delay_timer);
-+ port_key_pending = 0;
-+ port_key_delay_state[IDPORT_ON]=NOTPRESSED;
-+ }
-+ }
-+
-+
-+ // Record
-+ if (val & KEYMASK_REC) { // press
-+ if (port_key_setting[IDPORT_REC]==0) { // normal key
-+ ret |= KEYMASK_REC;
-+ } else if (port_key_setting[IDPORT_REC]>0) { // delay key
-+ if (port_key_delay_state[IDPORT_REC]==PRESSED) { // already detected
-+ ret |= KEYMASK_REC;
-+ } else if (port_key_delay_state[IDPORT_REC]==NOTPRESSED) { // start timer
-+ reset_port_key_delay();
-+ port_key_delay_state[IDPORT_REC]=PRESSING1;
-+ init_timer(&port_key_delay_timer);
-+ port_key_delay_timer.expires = jiffies + port_key_setting[IDPORT_REC];
-+ port_key_delay_timer.data = IDPORT_REC;
-+ add_timer(&port_key_delay_timer);
-+ port_key_pending = 1;
-+ return ret; // ignore following key
-+ }
-+ }
-+ } else { // release
-+ if (port_key_delay_state[IDPORT_REC]!=NOTPRESSED && port_key_setting[IDPORT_REC]>0) {
-+ del_timer(&port_key_delay_timer);
-+ port_key_pending = 0;
-+ port_key_delay_state[IDPORT_REC]=NOTPRESSED;
-+ }
-+ }
-+
-+ // Sync
-+ if (val & KEYMASK_SYNC) { // press
-+ if (port_key_setting[IDPORT_SYNC]==0) { // normal key
-+ ret |= KEYMASK_SYNC;
-+ } else if (port_key_setting[IDPORT_SYNC]>0) { // delay key
-+ if (port_key_delay_state[IDPORT_SYNC]==PRESSED) { // already detected
-+ ret |= KEYMASK_SYNC;
-+ } else if (port_key_delay_state[IDPORT_SYNC]==NOTPRESSED) { // start timer
-+ reset_port_key_delay();
-+ port_key_delay_state[IDPORT_SYNC]=PRESSING1;
-+ init_timer(&port_key_delay_timer);
-+ port_key_delay_timer.expires = jiffies + port_key_setting[IDPORT_SYNC];
-+ port_key_delay_timer.data = IDPORT_SYNC;
-+ add_timer(&port_key_delay_timer);
-+ port_key_pending = 1;
-+ return ret; // ignore following key
-+ }
-+ }
-+ } else { // release
-+ if (port_key_delay_state[IDPORT_SYNC]!=NOTPRESSED && port_key_setting[IDPORT_SYNC]>0) {
-+ del_timer(&port_key_delay_timer);
-+ port_key_pending = 0;
-+ port_key_delay_state[IDPORT_SYNC]=NOTPRESSED;
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+void sharppda_scan_key_gpio(void* dummy)
-+{
-+ int col,row;
-+ int rowd;
-+ unsigned long flags;
-+ int real_col;
-+ int count = 0;
-+#if CHECK_ROLLOVER
-+ int pressed_key[MAX_KEY_PRESS + 1];
-+ int i, rollover_count = 0, rollover_error = 0;
-+ unsigned long rollover_flag = 0;
-+#endif
-+#if CHECK_CHUTTER
-+ int loop;
-+#endif
-+
-+ WAIT_CHATTERING_DELAY;
-+
-+ spin_lock_irqsave(&kbd_spinlock,flags);
-+
-+ CHARGE_ALL;
-+
-+ for(col=0;col<KB_COLS+1;col++){
-+ real_col = GET_REAL_COL_FROM_COL(col);
-+ /*
-+ * Discharge the output driver capacitatance
-+ * in the keyboard matrix. (Yes it is significant..)
-+ */
-+ if (real_col<KB_COLS) { // matrix key
-+ DISCHARGE_ALL;
-+ WAIT_DISCHARGE_DELAY;
-+ ACTIVATE_COL(real_col);
-+
-+ WAIT_ACTIVATE_DELAY;
-+ rowd = GET_ROWS_STATUS(real_col);
-+
-+#if 1 // for BRB
-+ if (isBrb) {
-+ rowd &= 0x0000000f;
-+ }
-+#endif
-+ } else { // GPIO port key
-+ rowd = read_port_key_status();
-+ }
-+ for( row = 0 ; row < KB_ROWS ; row++ ){
-+
-+ if( rowd & KB_ROWMASK(row) ){
-+#if CHECK_ROLLOVER
-+ if ((rawkeytable_table_NormalLower[KEYCODE(row, col)] != KEY_IGN)) {
-+ pressed_key[count] = KEYCODE(row, col);
-+ rollover_flag |= rollover_flag_table[KEYCODE(row, col)];
-+ if (count < MAX_KEY_PRESS) {
-+ count++;
-+ }
-+ else {
-+ sharppda_kbd_press_rollover(KEYCODE(row,col));
-+ }
-+ }
-+#else
-+ sharppda_kbd_press(KEYCODE(row,col));
-+ count++;
-+#endif
-+ }
-+ else{
-+ if( sharppda_kbdstate[KEYCODE(row, col)].in ){
-+ sharppda_kbd_release(KEYCODE(row,col));
-+ }
-+ }
-+ }
-+ if (real_col<KB_COLS) {
-+ RESET_COL(real_col);
-+ }
-+ } /* end of for */
-+
-+#if CHECK_ROLLOVER
-+ if (count >= MAX_KEY_PRESS) {
-+ rollover_error = 1;
-+ }
-+ else {
-+ rollover_count = count;
-+ if (ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_LSHIFT)) {
-+ rollover_count--;
-+ }
-+ if (ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_RSHIFT)) {
-+ rollover_count--;
-+ }
-+ if (ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_FUNCTION)) {
-+ rollover_count--;
-+ }
-+ if ((rollover_count > 3) ||
-+ ((rollover_count == 3) &&
-+ (!ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_TAB) ||
-+ ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_DIRECT_ON)) &&
-+ (!ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_VERTICAL) ||
-+ !ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_HORIZONTAL) ||
-+ !ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_ENTQUESPC)))) {
-+ rollover_error = 1;
-+ }
-+ }
-+ // printk("count=%d,rollover_count=%d,rollover_error=%d\n",count,rollover_count,rollover_error);
-+ if (rollover_error == 0) {
-+#if 0
-+ if (ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_VERTICAL) &&
-+ ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_HORIZONTAL) &&
-+ ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_ENTQUESPC)) {
-+ printk("keyboard : vertical and horizontal and [Enter, ?, Space] pressed\n");
-+ }
-+#endif
-+ for (i = 0; i < count; i++) {
-+ sharppda_kbd_press(pressed_key[i]);
-+ }
-+ rollover_state = 0;
-+ }
-+ else {
-+ if (rollover_state == 0) {
-+#if 0
-+ printk("keyboard : roll over error!\n");
-+ if (count >= MAX_KEY_PRESS) {
-+ printk("keyboard : %d key pressed\n", count);
-+ }
-+ else if (rollover_count > 3) {
-+ printk("keyboard : %d rollover key pressed\n", rollover_count);
-+ }
-+ else if (ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_TAB) &&
-+ ROLLOVER_CHECK_FLAG(rollover_flag, ROLLOVER_DIRECT_ON)) {
-+ printk("keyboard : TAB and direct ON key pressed\n");
-+ }
-+#endif
-+ // stop repeat
-+ if (rep_hardkey) {
-+#if CHECK_CHUTTER_BOUNCE
-+ for (loop = 0; loop <= CHECK_BOUNCE; loop++) {
-+ sharppda_kbd_release(rep_hardkey);
-+ }
-+#else
-+ sharppda_kbd_release(rep_hardkey);
-+#endif
-+ sharppda_kbd_press_rollover(rep_hardkey);
-+ }
-+ }
-+ for (i = 0; i < count; i++) {
-+ sharppda_kbd_press_rollover(pressed_key[i]);
-+ }
-+ rollover_state = 1;
-+ }
-+#endif
-+
-+#ifdef USE_KBD_IRQ
-+ /*
-+ * drive all for next interrupts
-+ */
-+ DRIVE_ALL_COLS;
-+#endif
-+
-+ // press OK key to erase flash
-+ if (tosa_initial_keypress<0) {
-+#if CHECK_CHUTTER_BOUNCE
-+ if ((sharppda_kbdstate[0x38].in==PRESSED) ||
-+ IS_PRESSING(sharppda_kbdstate[0x38].in)) {
-+#else
-+#if CHECK_ROLLOVER
-+ if (sharppda_kbdstate[0x38].in==1) {
-+#else
-+ if (sharppda_kbdstate[0x38].in) {
-+#endif
-+#endif
-+ tosa_initial_keypress = 1;
-+ } else {
-+ tosa_initial_keypress = 0;
-+ }
-+ }
-+
-+
-+ /*
-+ * Re-queue ourselves
-+ */
-+#if CHECK_CHUTTER_BOUNCE
-+ for (loop = 0; loop < NR_KEYS; loop++) {
-+ if (port_key_pending) {
-+ queue_task(&kbdhw_task,&tq_timer);
-+ break;
-+ }
-+ if (sharppda_kbdstate[loop].in != NOTPRESSED) {
-+ queue_task(&kbdhw_task,&tq_timer);
-+ break;
-+ }
-+ }
-+#else
-+#ifdef USE_KBD_IRQ
-+ if ( count > 0 )
-+#endif
-+ queue_task(&kbdhw_task,&tq_timer);
-+#endif
-+ spin_unlock_irqrestore(&kbd_spinlock,flags);
-+}
-+
-+/*
-+ * Logical Keyboard Driver initialization
-+ */
-+
-+void sharppda_scan_logdriver_init(void)
-+{
-+ int ni;
-+ kbdhw_task.routine = sharppda_scan_key_gpio;
-+ kbdhw_task.sync = 0;
-+ mach_kbdrate = sharppda_kbd_kbdrate;
-+#ifndef USE_KBD_IRQ
-+ queue_task(&kbdhw_task,&tq_timer);
-+#endif
-+ for (ni=0;ni<NR_KEYCODES;ni++){
-+ sharppda_kbdstate[ni].in=0;
-+ }
-+ isBrb = checkBrb();
-+ init_timer(&port_key_delay_timer);
-+}
-+
-+void sharppda_scan_logdriver_suspend(void)
-+{
-+ del_timer( &sharppda_kbd_rep_timer );
-+ del_timer( &sharppda_kbd_hold_timer );
-+ rep_scancode = 0;
-+#if CHECK_ROLLOVER
-+ rep_hardkey = 0;
-+#endif
-+ holdkey_pending = 0;
-+ holdkey_pendinghardkey = 0;
-+ holdkey_pendingmappedkey = 0;
-+}
-+
-+void sharppda_scan_logdriver_resume(void)
-+{
-+ queue_task(&kbdhw_task,&tq_timer);
-+}
-+
-+
-+
-+/*
-+ * External Modifier Status Functions
-+ */
-+
-+int sharppda_kbd_extmodif_showstatus(int which)
-+{
-+#ifdef EXTMODIF_SHOWSTAT_KEYMAX
-+ unsigned char* pmodmap;
-+ if( which >= EXTMODIF_SHOWSTAT_KEYMAX ) return -EINVAL;
-+ if( ! extmodif_status_tables ) return -EINVAL;
-+ if( ! ( pmodmap = extmodif_status_tables[which] ) ) return -EINVAL;
-+ return(pmodmap[sharp_cur_status]);
-+#else /* ! EXTMODIF_SHOWSTAT_KEYMAX */
-+ return -EINVAL; /* not supported on this arch. */
-+#endif /* ! EXTMODIF_SHOWSTAT_KEYMAX */
-+}
-+
-+int sharppda_kbd_extmodif_togglestatus(int which)
-+{
-+#ifdef EXTMODIF_MOVESTAT_KEYMAX
-+ unsigned char* pmodmap;
-+ if( which >= EXTMODIF_MOVESTAT_KEYMAX ) return -EINVAL;
-+ if( ! extmodif_move_tables ) return -EINVAL;
-+ if( ! ( pmodmap = extmodif_move_tables[which] ) ) return -EINVAL;
-+ DEBUGPRINT(("moving from %d to %d\n",sharp_cur_status,pmodmap[sharp_cur_status]));
-+ if( sharp_cur_status != pmodmap[sharp_cur_status] ){
-+ sharp_cur_status = pmodmap[sharp_cur_status];
-+ sharpkbdctl_stat_changed();
-+ }else{
-+ sharp_cur_status = pmodmap[sharp_cur_status];
-+ }
-+ return 0;
-+#else /* ! EXTMODIF_MOVESTAT_KEYMAX */
-+ return -EINVAL; /* not supported on this arch. */
-+#endif /* ! EXTMODIF_MOVESTAT_KEYMAX */
-+}
-+
-+unsigned long sharppda_kbd_extmodif_packstatus(void)
-+{
-+#ifdef EXTMODIF_SHOWSTAT_KEYMAX
-+ unsigned long val = 0;
-+ return val;
-+#else /* ! EXTMODIF_SHOWSTAT_KEYMAX */
-+ return 0;
-+#endif /* ! EXTMODIF_SHOWSTAT_KEYMAX */
-+}
-+
-+/*
-+ * SL-Keycode Search Functions
-+ */
-+
-+static int find_hardcode_from_slcode(int stateno,unsigned char sl_char)
-+{
-+ int i;
-+ unsigned char* pmodmap;
-+ if( stateno < 0 || stateno >= STATE_NUMS_TOTAL ) return -EINVAL;
-+ pmodmap = state_to_keymap[stateno];
-+ for(i=0;i<(NR_KEYCODES+1);i++){
-+ if( pmodmap[i] == sl_char ) return i;
-+ }
-+ return -EINVAL;
-+}
-+
-+
-+/*
-+ * HoldKey Customizing Functions
-+ */
-+
-+static void delete_custom_holdkey_info(void)
-+{
-+ CUS_DPRINTK("\n");
-+ if( custom_holdkey_info ){
-+ int i;
-+ for(i=0;i<(NR_KEYCODES+1);i++){
-+ if( custom_holdkey_info[i] ){
-+ kfree(custom_holdkey_info[i]);
-+ custom_holdkey_info[i] = NULL;
-+ }
-+ }
-+ kfree(custom_holdkey_info);
-+ custom_holdkey_info = NULL;
-+ }
-+}
-+
-+static int duplicate_holdkey_info(void)
-+{
-+ int i;
-+ CUS_DPRINTK("\n");
-+ if( ! custom_holdkey_info ){
-+ custom_holdkey_info = (shappda_holdkey_info**)kmalloc(sizeof(shappda_holdkey_info*)*(NR_KEYCODES+1),GFP_KERNEL);
-+ if( ! custom_holdkey_info ) goto FAIL_SAFE;
-+ memset(custom_holdkey_info,0,sizeof(shappda_holdkey_info*)*(NR_KEYCODES+1));
-+ }
-+ for(i=0;i<(NR_KEYCODES+1);i++){
-+ if( holdkey_info[i] ){
-+ if( ! custom_holdkey_info[i] ){
-+ custom_holdkey_info[i] = (shappda_holdkey_info*)kmalloc(sizeof(shappda_holdkey_info),GFP_KERNEL);
-+ if( ! custom_holdkey_info[i] ) goto FAIL_SAFE;
-+ }
-+ memcpy(custom_holdkey_info[i],holdkey_info[i],sizeof(shappda_holdkey_info));
-+ }else{
-+ if( custom_holdkey_info[i] ){
-+ memset(custom_holdkey_info[i],0,sizeof(shappda_holdkey_info));
-+ kfree(custom_holdkey_info[i]);
-+ custom_holdkey_info[i] = NULL;
-+ }
-+ }
-+ }
-+ return 0;
-+FAIL_SAFE:
-+ delete_custom_holdkey_info();
-+ return -ENOMEM;
-+}
-+
-+static int add_custom_holdkey_info(int i)
-+{
-+ int error;
-+ CUS_DPRINTK(" %d(%x)\n",i,i);
-+ if( i < 0 || i >= (NR_KEYCODES+1) ) return -EINVAL;
-+ if( ! custom_holdkey_info ){
-+ if( ( error = duplicate_holdkey_info() ) ) return error;
-+ }
-+ if( ! custom_holdkey_info[i] ){
-+ custom_holdkey_info[i] = (shappda_holdkey_info*)kmalloc(sizeof(shappda_holdkey_info),GFP_KERNEL);
-+ if( ! custom_holdkey_info[i] ) goto FAIL_SAFE;
-+ if( holdkey_info[i] )
-+ memcpy(custom_holdkey_info[i],holdkey_info[i],sizeof(shappda_holdkey_info));
-+ else
-+ memset(custom_holdkey_info[i],0,sizeof(shappda_holdkey_info));
-+ }
-+ return 0;
-+FAIL_SAFE:
-+ return -ENOMEM;
-+}
-+
-+static int del_custom_holdkey_info(int i)
-+{
-+ int error;
-+ CUS_DPRINTK(" %d(%x)\n",i,i);
-+ if( i < 0 || i >= (NR_KEYCODES+1) ) return -EINVAL;
-+ if( ! custom_holdkey_info ){
-+ if( ( error = duplicate_holdkey_info() ) ) return error;
-+ }
-+ if( custom_holdkey_info[i] ){
-+ memset(custom_holdkey_info[i],0,sizeof(shappda_holdkey_info));
-+ kfree(custom_holdkey_info[i]);
-+ custom_holdkey_info[i] = NULL;
-+ }
-+ return 0;
-+FAIL_SAFE:
-+ return -ENOMEM;
-+}
-+
-+static int restore_one_holdkey_info(int i)
-+{
-+ int error;
-+ CUS_DPRINTK(" %d(%x)\n",i,i);
-+ if( i < 0 || i >= (NR_KEYCODES+1) ) return -EINVAL;
-+ if( ! custom_holdkey_info ) return 0;
-+ if( holdkey_info[i] ){
-+ if( ( error = add_custom_holdkey_info(i) ) ) return error;
-+ memcpy(custom_holdkey_info[i],holdkey_info[i],sizeof(shappda_holdkey_info));
-+ }else{
-+ if( ( error = del_custom_holdkey_info(i) ) ) return error;
-+ }
-+ return 0;
-+}
-+
-+int restore_all_holdkey_info(void)
-+{
-+ CUS_DPRINTK("\n");
-+ if( ! custom_holdkey_info ) return 0;
-+ delete_custom_holdkey_info();
-+ return 0;
-+}
-+
-+int customize_holdkey_char_info(int hardcode,int sl_char)
-+{
-+ int error;
-+ CUS_DPRINTK(" %d(%x) %d(%x)\n",hardcode,hardcode,sl_char,sl_char);
-+ if( ! custom_holdkey_info ){
-+ if( ( error = duplicate_holdkey_info() ) ) return error;
-+ }
-+ if( ( error = add_custom_holdkey_info(hardcode) ) ) return error;
-+ custom_holdkey_info[hardcode]->type = HOLDKEYTYPE_CHAR;
-+ custom_holdkey_info[hardcode]->character = sl_char;
-+ return 0;
-+}
-+
-+int customize_holdkey_char_info_by_slkey(unsigned char slcode,int sl_char)
-+{
-+ int hardcode;
-+ CUS_DPRINTK(" %d(%x) %d(%x)\n",slcode,slcode,sl_char,sl_char);
-+ hardcode = find_hardcode_from_slcode(0,slcode);
-+ if( hardcode < 0 ) return -EINVAL;
-+ return customize_holdkey_char_info(hardcode,sl_char);
-+}
-+
-+int customize_del_holdkey_info(int hardcode)
-+{
-+ CUS_DPRINTK(" %d(%x)\n",hardcode,hardcode);
-+ return del_custom_holdkey_info(hardcode);
-+}
-+
-+int customize_del_holdkey_info_by_slkey(int slcode)
-+{
-+ int hardcode;
-+ CUS_DPRINTK(" %d(%x)\n",slcode,slcode);
-+ hardcode = find_hardcode_from_slcode(0,slcode);
-+ if( hardcode < 0 ) return -EINVAL;
-+ return del_custom_holdkey_info(hardcode);
-+}
-+
-+int customize_restore_holdkey_info(int hardcode)
-+{
-+ CUS_DPRINTK(" %d(%x)\n",hardcode,hardcode);
-+ return restore_one_holdkey_info(hardcode);
-+}
-+
-+int customize_restore_holdkey_info_by_slkey(int slcode)
-+{
-+ int hardcode;
-+ CUS_DPRINTK(" %d(%x)\n",slcode,slcode);
-+ hardcode = find_hardcode_from_slcode(0,slcode);
-+ if( hardcode < 0 ) return -EINVAL;
-+ return restore_one_holdkey_info(hardcode);
-+}
-+
-+
-+int sharppda_kbd_set_hold_threshold(int msecs)
-+{
-+ if( holdkey_info ){
-+ key_hold_delay = (unsigned long)msecs * HZ / 1000;
-+#ifdef HOLDKEY_INFO_HAS_TIMEOUT
-+ if( ! custom_holdkey_info ) duplicate_holdkey_info();
-+ if( custom_holdkey_info ){
-+ int i;
-+ for(i=0;i<=NR_KEYCODES;i++){
-+ if( custom_holdkey_info[i] ){
-+ custom_holdkey_info[i]->timeout = msecs;
-+ }
-+ }
-+ }else{
-+ int i;
-+ for(i=0;i<=NR_KEYCODES;i++){
-+ if( holdkey_info[i] ){
-+ holdkey_info[i]->timeout = msecs;
-+ }
-+ }
-+ }
-+#endif
-+ return 0;
-+ }else{
-+ return -EINVAL; /* not supported on this architecture */
-+ }
-+}
-+
-+int sharppda_kbd_set_hold_threshold_group(int group,int msecs)
-+{
-+#ifdef HOLDKEY_INFO_HAS_TIMEOUT
-+ if( ! custom_holdkey_info ) duplicate_holdkey_info();
-+ if( custom_holdkey_info ){
-+ int i;
-+ for(i=0;i<=NR_KEYCODES;i++){
-+ if( custom_holdkey_info[i] && custom_holdkey_info[i]->setgroup == group ){
-+ custom_holdkey_info[i]->timeout = msecs;
-+ }
-+ }
-+ return 0;
-+ }else if( holdkey_info ){
-+ int i;
-+ for(i=0;i<=NR_KEYCODES;i++){
-+ if( holdkey_info[i] && holdkey_info[i]->setgroup == group ){
-+ holdkey_info[i]->timeout = msecs;
-+ }
-+ }
-+ return 0;
-+ }else{
-+ return -EINVAL; /* not supported on this architecture */
-+ }
-+#endif
-+ return -EINVAL; /* not supported on this architecture */
-+}
-+
-+#if 0
-+static int sharppda_kbd_keyscan(void)
-+{
-+ unsigned long flags;
-+ int row, col, rowd, press_row, press_col, real_col;
-+
-+ WAIT_CHATTERING_DELAY;
-+
-+ spin_lock_irqsave(&kbd_spinlock,flags);
-+
-+ press_col = -1;
-+ press_row = -1;
-+ CHARGE_ALL;
-+ for (col = 0; col < KB_COLS; col++) {
-+ real_col = (GET_REAL_COL_FROM_COL(col));
-+ DISCHARGE_ALL;
-+ WAIT_DISCHARGE_DELAY;
-+ ACTIVATE_COL(real_col);
-+
-+ WAIT_ACTIVATE_DELAY;
-+ rowd = GET_ROWS_STATUS(real_col);
-+ for (row = 0; row < KB_ROWS; row++) {
-+ if (rowd & KB_ROWMASK(row)) {
-+ if (press_row >= 0) {
-+ press_row = -1;
-+ col = KB_COLS;
-+ break;
-+ }
-+ press_row = row;
-+ press_col = col;
-+ }
-+ }
-+ RESET_COL(real_col);
-+ }
-+
-+ if (press_col != 0)
-+ press_row = -1;
-+
-+#ifdef USE_KBD_IRQ
-+ DRIVE_ALL_COLS;
-+#endif
-+
-+ spin_unlock_irqrestore(&kbd_spinlock,flags);
-+
-+ return press_row;
-+}
-+
-+static int sharppda_kbd_keycheck(int row, int col)
-+{
-+ unsigned long flags;
-+ int press, real_col;
-+
-+ WAIT_CHATTERING_DELAY;
-+
-+ spin_lock_irqsave(&kbd_spinlock,flags);
-+
-+ CHARGE_ALL;
-+ real_col = (GET_REAL_COL_FROM_COL(col));
-+ DISCHARGE_ALL;
-+ WAIT_DISCHARGE_DELAY;
-+ ACTIVATE_COL(real_col);
-+
-+ WAIT_ACTIVATE_DELAY;
-+ if (GET_ROWS_STATUS(real_col) & KB_ROWMASK(row))
-+ press = 1;
-+ else
-+ press = 0;
-+ RESET_COL(real_col);
-+
-+#ifdef USE_KBD_IRQ
-+ DRIVE_ALL_COLS;
-+#endif
-+
-+ spin_unlock_irqrestore(&kbd_spinlock,flags);
-+
-+ return press;
-+}
-+
-+#define KEYBOARD_WAKEUP_WAIT 300
-+
-+static void sharppda_kbd_holdkeycheck(int row, int col)
-+{
-+ int count;
-+
-+ for (count = 0; count < KEYBOARD_WAKEUP_WAIT; count++) {
-+ if (!sharppda_kbd_keycheck(row, col))
-+ break;
-+ mdelay(1);
-+ }
-+ if (row != 7) /* Power key */
-+ sharppda_kbd_press(KEYCODE(row, col));
-+ if (count >= KEYBOARD_WAKEUP_WAIT) {
-+ sharppda_kbd_press(KEYCODE(row, col));
-+ sharppda_kbd_hold(0);
-+ }
-+}
-+#endif
-+
-+static void sharppda_kbd_press_repeat( int code )
-+{
-+ int i;
-+ for (i=0; i<JUST_PRESSED; i++) sharppda_kbd_press(code);
-+}
-+static void sharppda_kbd_release_repeat( int code )
-+{
-+ int i;
-+ for (i=0; i<JUST_RELEASED-PRESSED; i++) sharppda_kbd_release(code);
-+}
-+
-+int sharppda_kbd_is_wakeup(void)
-+{
-+ unsigned long flags;
-+ int count = 0, err = 0;
-+ int cur_portkey,last_portkey=0;
-+ int cur_matrixkey,last_matrixkey=0;
-+ const int strobe_num = 4;
-+ const int success_count = 10;
-+
-+ while( !(count>success_count || err>50) ) {
-+ // read GPIO(On,Rec,Sync) key
-+ cur_portkey = read_port_key_status_raw();
-+
-+ // read Strobe4(Address,Calendar,Menu,Mail) key
-+ spin_lock_irqsave(&kbd_spinlock,flags);
-+ DISCHARGE_ALL;
-+ WAIT_DISCHARGE_DELAY;
-+ ACTIVATE_COL(strobe_num);
-+ WAIT_ACTIVATE_DELAY;
-+ cur_matrixkey = GET_ROWS_STATUS(strobe_num);
-+ spin_unlock_irqrestore(&kbd_spinlock,flags);
-+ // compare with last state
-+ if (cur_portkey != last_portkey ||
-+ cur_matrixkey != last_matrixkey) {
-+ count = 0;
-+ err++;
-+ last_portkey = cur_portkey;
-+ last_matrixkey = cur_matrixkey;
-+ } else {
-+ count++;
-+ }
-+ mdelay(10);
-+ }
-+ if (count>success_count) {
-+ printk("key interrupt on (%04x,%04x)\n",last_portkey,last_matrixkey);
-+ if (last_portkey & KEYMASK_ON) { // On ... only status change
-+ sharppda_kbdstate[KEYCODE(0, KB_COLS)].in = PRESSED;
-+ port_key_delay_state[IDPORT_ON]=PRESSED;
-+ }
-+ if (last_portkey & KEYMASK_REC) { // Rec
-+ if (logical_wakeup_src_mask&IDPM_WAKEUP_REC) {
-+ if (port_key_setting[IDPORT_REC]>=0) {
-+ sharppda_kbd_press_repeat(KEYCODE(1, KB_COLS));
-+ sharppda_kbd_release_repeat(KEYCODE(1, KB_COLS));
-+ }
-+ } else last_portkey &= ~KEYMASK_REC;
-+ }
-+ if (last_portkey & KEYMASK_SYNC) { // Sync
-+ if (logical_wakeup_src_mask&IDPM_WAKEUP_SYNC) {
-+ if (port_key_setting[IDPORT_SYNC]>=0) {
-+ sharppda_kbd_press_repeat(KEYCODE(2, KB_COLS));
-+ sharppda_kbd_release_repeat(KEYCODE(2, KB_COLS));
-+ }
-+ } else last_portkey &= ~KEYMASK_SYNC;
-+ }
-+ if (last_matrixkey & KEYMASK_ADDRESS) { // Address
-+ if (logical_wakeup_src_mask&IDPM_WAKEUP_ADDRESSBOOK) {
-+ sharppda_kbd_press_repeat(KEYCODE(3, strobe_num));
-+ sharppda_kbd_release_repeat(KEYCODE(3, strobe_num));
-+ } else last_matrixkey &= ~KEYMASK_ADDRESS;
-+ }
-+ if (last_matrixkey & KEYMASK_CALENDAR) { // Calendar
-+ if (logical_wakeup_src_mask&IDPM_WAKEUP_CALENDAR) {
-+ sharppda_kbd_press_repeat(KEYCODE(4, strobe_num));
-+ sharppda_kbd_release_repeat(KEYCODE(4, strobe_num));
-+ } else last_matrixkey &= ~KEYMASK_CALENDAR;
-+ }
-+ if (last_matrixkey & KEYMASK_MENU) { // Menu
-+ if (logical_wakeup_src_mask&IDPM_WAKEUP_MENU) {
-+ sharppda_kbd_press_repeat(KEYCODE(5, strobe_num));
-+ sharppda_kbd_release_repeat(KEYCODE(5, strobe_num));
-+ } else last_matrixkey &= ~KEYMASK_MENU;
-+ }
-+ if (last_matrixkey & KEYMASK_MAIL) { // Mail (Holdkey event)
-+ if (logical_wakeup_src_mask&IDPM_WAKEUP_MAIL) {
-+ sharppda_kbd_press_repeat(KEYCODE(6, strobe_num));
-+ sharppda_kbd_hold(0);
-+ } else last_matrixkey &= ~KEYMASK_MAIL;
-+ }
-+ return (last_portkey || last_matrixkey)?1:0;
-+ }
-+ return 0;
-+}
-+
-+#define MAX_RESET_KEY_COMBINATION 3
-+
-+#define RESET_KEY_NONE (0)
-+#define RESET_KEY_FUNC (KEYCODE(5, 10))
-+#define RESET_KEY_HOME (KEYCODE(4, 5))
-+#define RESET_KEY_A (KEYCODE(2, 0))
-+#define RESET_KEY_B (KEYCODE(4, 2))
-+#define RESET_KEY_C (KEYCODE(3, 2))
-+#define RESET_KEY_D (KEYCODE(2, 2))
-+#define RESET_KEY_K (KEYCODE(0, 5))
-+#define RESET_KEY_M (KEYCODE(5, 3))
-+#define RESET_KEY_P (KEYCODE(0, 7))
-+#define RESET_KEY_Q (KEYCODE(1, 0))
-+#define RESET_KEY_R (KEYCODE(4, 1))
-+#define RESET_KEY_T (KEYCODE(1, 2))
-+#define RESET_KEY_Z (KEYCODE(3, 0))
-+
-+static int reset_key_combination[][MAX_RESET_KEY_COMBINATION] = {
-+ {RESET_KEY_FUNC, RESET_KEY_HOME, RESET_KEY_NONE}, /* Fn + Home */
-+ {RESET_KEY_P, RESET_KEY_D, RESET_KEY_NONE}, /* P + D */
-+ {RESET_KEY_M, RESET_KEY_D, RESET_KEY_NONE}, /* M + D */
-+ {RESET_KEY_R, RESET_KEY_D, RESET_KEY_NONE}, /* R + D */
-+ {RESET_KEY_FUNC, RESET_KEY_P, RESET_KEY_D}, /* Fn + P + D */
-+ {RESET_KEY_FUNC, RESET_KEY_M, RESET_KEY_D}, /* Fn + M + D */
-+ {RESET_KEY_Q, RESET_KEY_T, RESET_KEY_NONE}, /* Q + T */
-+ {RESET_KEY_C, RESET_KEY_D, RESET_KEY_NONE}, /* C + D */
-+ {RESET_KEY_Z, RESET_KEY_D, RESET_KEY_NONE}, /* Z + D */
-+ {RESET_KEY_K, RESET_KEY_D, RESET_KEY_NONE}, /* K + D */
-+ {RESET_KEY_A, RESET_KEY_B, RESET_KEY_NONE}, /* A + B */
-+ {RESET_KEY_B, RESET_KEY_D, RESET_KEY_NONE}, /* B + D */
-+ {RESET_KEY_A, RESET_KEY_D, RESET_KEY_NONE}, /* A + D */
-+ {RESET_KEY_NONE, RESET_KEY_NONE, RESET_KEY_NONE} /* End Mark */
-+};
-+
-+static int sharppda_kbd_resetcheck_one(void)
-+{
-+ unsigned long flags;
-+ int row, col, rowd, real_col, i, j, k, press_num = 0, pressed, set_num;
-+ int press_key[MAX_RESET_KEY_COMBINATION] = {0, 0, 0};
-+
-+ WAIT_CHATTERING_DELAY;
-+ spin_lock_irqsave(&kbd_spinlock,flags);
-+ CHARGE_ALL;
-+ for (col = 0; col < KB_COLS; col++) {
-+ real_col = (GET_REAL_COL_FROM_COL(col));
-+ DISCHARGE_ALL;
-+ WAIT_DISCHARGE_DELAY;
-+ ACTIVATE_COL(real_col);
-+ WAIT_ACTIVATE_DELAY;
-+ rowd = GET_ROWS_STATUS(real_col);
-+ for (row = 0; row < KB_ROWS; row++) {
-+ if (rowd & KB_ROWMASK(row)) {
-+ if (press_num >= MAX_RESET_KEY_COMBINATION) {
-+ return 0; /* too many keys are pressed */
-+ }
-+ press_key[press_num++] = KEYCODE(row, col);
-+ }
-+ }
-+ RESET_COL(real_col);
-+ }
-+
-+#ifdef USE_KBD_IRQ
-+ DRIVE_ALL_COLS;
-+#endif
-+
-+ spin_unlock_irqrestore(&kbd_spinlock,flags);
-+
-+ for (i = 0; reset_key_combination[i][0] != 0; i++) {
-+ set_num = 0;
-+ for (j = 0; j < MAX_RESET_KEY_COMBINATION; j++) {
-+ if (reset_key_combination[i][j] == RESET_KEY_NONE) continue;
-+ set_num++;
-+ pressed = 0;
-+ for (k = 0; k < press_num; k++) {
-+ if (press_key[k] == reset_key_combination[i][j]) {
-+ pressed = 1;
-+ break;
-+ }
-+ }
-+ if (!pressed) break;
-+ }
-+ if ((j == MAX_RESET_KEY_COMBINATION) && (set_num == press_num)) {
-+ return i + 1;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+int sharppda_kbd_resetcheck(void)
-+{
-+ int state, i;
-+
-+ state = sharppda_kbd_resetcheck_one();
-+#if CHECK_CHUTTER_BOUNCE
-+ if (!state) return 0;
-+ for (i = 0; i < CHECK_CHUTTER; i++) {
-+ mdelay(5);
-+ if (sharppda_kbd_resetcheck_one() != state) return 0;
-+ }
-+#endif
-+ return state;
-+}
-+/*
-+ * end of source
-+ */
-diff -Nur linux_c860_org/drivers/char/tosa_rawmap.h linux/drivers/char/tosa_rawmap.h
---- linux_c860_org/drivers/char/tosa_rawmap.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/char/tosa_rawmap.h 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,340 @@
-+#ifndef __KEYTABLE_H_INCLUDED__
-+#define __KEYTABLE_H_INCLUDED__
-+
-+
-+#ifndef NR_KEYS
-+#define NR_KEYS 128
-+#endif /* ! NR_KEYS */
-+
-+
-+#ifndef NR_KEYCODES
-+#define NR_KEYCODES 128
-+#endif /* ! NR_KEYCODES */
-+
-+
-+#define MODIF_2ND 0x01
-+#define MODIF_CAPS 0x02
-+#define MODIF_NUM 0x03
-+
-+#ifndef KEY_IGN
-+#define KEY_IGN 0
-+#endif /* ! KEY_IGN */
-+
-+
-+static unsigned char rawkeytable_table_NormalLower[(NR_KEYCODES+1)] = {
-+KEY_IGN,KEY_IGN,SLKEY_W,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_K,SLKEY_BACK_SPACE,SLKEY_P,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_OFF,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Q,SLKEY_E,SLKEY_T,SLKEY_Y,KEY_IGN,SLKEY_O,SLKEY_I,SLKEY_COMMA,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_RECORDER,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_A,SLKEY_D,SLKEY_G,SLKEY_U,KEY_IGN,SLKEY_L,SLKEY_ENTER,SLKEY_PERIOD,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_SYNCSTART,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Z,SLKEY_C,SLKEY_V,SLKEY_J,SLKEY_CONTACTS,SLKEY_F9,SLKEY_F11,SLKEY_F4,SLKEY_LSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_S,SLKEY_R,SLKEY_B,SLKEY_N,SLKEY_ACTIVITY,SLKEY_HOME,SLKEY_MINUS,SLKEY_FRONTLIGHT,KEY_IGN,SLKEY_RSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_TAB,SLKEY_SLASH,SLKEY_H,SLKEY_M,SLKEY_F2,KEY_IGN,SLKEY_UP,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_2ND,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_X,SLKEY_F,SLKEY_SPACE,SLKEY_APOSTROPHE,SLKEY_MAIL,SLKEY_LEFT,SLKEY_DOWN,SLKEY_RIGHT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN};
-+
-+static unsigned char rawkeytable_table_NormalUpper[(NR_KEYCODES+1)] = {
-+KEY_IGN,KEY_IGN,SLKEY_W,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_K,SLKEY_BACK_SPACE,SLKEY_P,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_OFF,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Q,SLKEY_E,SLKEY_T,SLKEY_Y,KEY_IGN,SLKEY_O,SLKEY_I,SLKEY_COMMA,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_RECORDER,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_A,SLKEY_D,SLKEY_G,SLKEY_U,KEY_IGN,SLKEY_L,SLKEY_ENTER,SLKEY_PERIOD,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_SYNCSTART,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Z,SLKEY_C,SLKEY_V,SLKEY_J,SLKEY_CONTACTS,SLKEY_F9,SLKEY_F11,SLKEY_F4,SLKEY_LSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_S,SLKEY_R,SLKEY_B,SLKEY_N,SLKEY_ACTIVITY,SLKEY_HOME,SLKEY_MINUS,SLKEY_FRONTLIGHT,KEY_IGN,SLKEY_RSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_TAB,SLKEY_SLASH,SLKEY_H,SLKEY_M,SLKEY_F2,KEY_IGN,SLKEY_UP,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_2ND,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_X,SLKEY_F,SLKEY_SPACE,SLKEY_APOSTROPHE,SLKEY_MAIL,SLKEY_LEFT,SLKEY_DOWN,SLKEY_RIGHT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN};
-+
-+static unsigned char rawkeytable_table_2ndLower[(NR_KEYCODES+1)] = {
-+KEY_IGN,KEY_IGN,SLKEY_W,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_K,SLKEY_BACK_SPACE,SLKEY_P,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_OFF,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Q,SLKEY_E,SLKEY_T,SLKEY_Y,KEY_IGN,SLKEY_O,SLKEY_I,SLKEY_COMMA,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_RECORDER,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_A,SLKEY_D,SLKEY_G,SLKEY_U,KEY_IGN,SLKEY_L,SLKEY_ENTER,SLKEY_PERIOD,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_SYNCSTART,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Z,SLKEY_C,SLKEY_V,SLKEY_J,SLKEY_CONTACTS,SLKEY_F9,SLKEY_F11,SLKEY_F4,SLKEY_LSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_S,SLKEY_R,SLKEY_B,SLKEY_N,SLKEY_ACTIVITY,SLKEY_HOME,SLKEY_MINUS,SLKEY_FRONTLIGHT,KEY_IGN,SLKEY_RSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_TAB,SLKEY_SLASH,SLKEY_H,SLKEY_M,SLKEY_F2,KEY_IGN,SLKEY_UP,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_2ND,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_X,SLKEY_F,SLKEY_SPACE,SLKEY_APOSTROPHE,SLKEY_MAIL,SLKEY_LEFT,SLKEY_DOWN,SLKEY_RIGHT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN};
-+
-+static unsigned char rawkeytable_table_2ndUpper[(NR_KEYCODES+1)] = {
-+KEY_IGN,KEY_IGN,SLKEY_W,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_K,SLKEY_BACK_SPACE,SLKEY_P,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_OFF,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Q,SLKEY_E,SLKEY_T,SLKEY_Y,KEY_IGN,SLKEY_O,SLKEY_I,SLKEY_COMMA,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_RECORDER,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_A,SLKEY_D,SLKEY_G,SLKEY_U,KEY_IGN,SLKEY_L,SLKEY_ENTER,SLKEY_PERIOD,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_SYNCSTART,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Z,SLKEY_PRINTSCREEN,SLKEY_V,SLKEY_J,SLKEY_CONTACTS,SLKEY_F9,SLKEY_F11,SLKEY_F4,SLKEY_LSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_S,SLKEY_R,SLKEY_B,SLKEY_N,SLKEY_ACTIVITY,SLKEY_HOME,SLKEY_MINUS,SLKEY_FRONTLIGHT,KEY_IGN,SLKEY_RSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_TAB,SLKEY_SLASH,SLKEY_H,SLKEY_M,SLKEY_F2,KEY_IGN,SLKEY_UP,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_2ND,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_X,SLKEY_F,SLKEY_SPACE,SLKEY_APOSTROPHE,SLKEY_MAIL,SLKEY_LEFT,SLKEY_DOWN,SLKEY_RIGHT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN};
-+
-+static unsigned char rawkeytable_table_NumlockLower[(NR_KEYCODES+1)] = {
-+KEY_IGN,KEY_IGN,SLKEY_W,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_K,SLKEY_BACK_SPACE,SLKEY_P,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_OFF,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Q,SLKEY_E,SLKEY_T,SLKEY_Y,KEY_IGN,SLKEY_O,SLKEY_I,SLKEY_COMMA,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_RECORDER,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_A,SLKEY_D,SLKEY_G,SLKEY_U,KEY_IGN,SLKEY_L,SLKEY_ENTER,SLKEY_PERIOD,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_SYNCSTART,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Z,SLKEY_C,SLKEY_V,SLKEY_J,SLKEY_CONTACTS,SLKEY_F9,SLKEY_F11,SLKEY_F4,SLKEY_LSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_S,SLKEY_R,SLKEY_B,SLKEY_N,SLKEY_ACTIVITY,SLKEY_HOME,SLKEY_MINUS,SLKEY_FRONTLIGHT,KEY_IGN,SLKEY_RSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_TAB,SLKEY_SLASH,SLKEY_H,SLKEY_M,SLKEY_F2,KEY_IGN,SLKEY_UP,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_2ND,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_X,SLKEY_F,SLKEY_SPACE,SLKEY_APOSTROPHE,SLKEY_MAIL,SLKEY_LEFT,SLKEY_DOWN,SLKEY_RIGHT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN};
-+
-+static unsigned char rawkeytable_table_NumlockUpper[(NR_KEYCODES+1)] = {
-+KEY_IGN,KEY_IGN,SLKEY_W,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_K,SLKEY_BACK_SPACE,SLKEY_P,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_OFF,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Q,SLKEY_E,SLKEY_T,SLKEY_Y,KEY_IGN,SLKEY_O,SLKEY_I,SLKEY_COMMA,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_RECORDER,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_A,SLKEY_D,SLKEY_G,SLKEY_U,KEY_IGN,SLKEY_L,SLKEY_ENTER,SLKEY_PERIOD,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_SYNCSTART,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Z,SLKEY_C,SLKEY_V,SLKEY_J,SLKEY_CONTACTS,SLKEY_F9,SLKEY_F11,SLKEY_F4,SLKEY_LSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_S,SLKEY_R,SLKEY_B,SLKEY_N,SLKEY_ACTIVITY,SLKEY_HOME,SLKEY_MINUS,SLKEY_FRONTLIGHT,KEY_IGN,SLKEY_RSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_TAB,SLKEY_SLASH,SLKEY_H,SLKEY_M,SLKEY_F2,KEY_IGN,SLKEY_UP,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_2ND,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_X,SLKEY_F,SLKEY_SPACE,SLKEY_APOSTROPHE,SLKEY_MAIL,SLKEY_LEFT,SLKEY_DOWN,SLKEY_RIGHT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN};
-+
-+static unsigned char rawkeytable_table_Num2ndLower[(NR_KEYCODES+1)] = {
-+KEY_IGN,KEY_IGN,SLKEY_W,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_K,SLKEY_BACK_SPACE,SLKEY_P,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_OFF,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Q,SLKEY_E,SLKEY_T,SLKEY_Y,KEY_IGN,SLKEY_O,SLKEY_I,SLKEY_COMMA,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_RECORDER,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_A,SLKEY_D,SLKEY_G,SLKEY_U,KEY_IGN,SLKEY_L,SLKEY_ENTER,SLKEY_PERIOD,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_SYNCSTART,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Z,SLKEY_C,SLKEY_V,SLKEY_J,SLKEY_CONTACTS,SLKEY_F9,SLKEY_F11,SLKEY_F4,SLKEY_LSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_S,SLKEY_R,SLKEY_B,SLKEY_N,SLKEY_ACTIVITY,SLKEY_HOME,SLKEY_MINUS,SLKEY_FRONTLIGHT,KEY_IGN,SLKEY_RSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_TAB,SLKEY_SLASH,SLKEY_H,SLKEY_M,SLKEY_F2,KEY_IGN,SLKEY_UP,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_2ND,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_X,SLKEY_F,SLKEY_SPACE,SLKEY_APOSTROPHE,SLKEY_MAIL,SLKEY_LEFT,SLKEY_DOWN,SLKEY_RIGHT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN};
-+
-+static unsigned char rawkeytable_table_Num2ndUpper[(NR_KEYCODES+1)] = {
-+KEY_IGN,KEY_IGN,SLKEY_W,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_K,SLKEY_BACK_SPACE,SLKEY_P,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_OFF,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Q,SLKEY_E,SLKEY_T,SLKEY_Y,KEY_IGN,SLKEY_O,SLKEY_I,SLKEY_COMMA,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_RECORDER,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_A,SLKEY_D,SLKEY_G,SLKEY_U,KEY_IGN,SLKEY_L,SLKEY_ENTER,SLKEY_PERIOD,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_SYNCSTART,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Z,SLKEY_PRINTSCREEN,SLKEY_V,SLKEY_J,SLKEY_CONTACTS,SLKEY_F9,SLKEY_F11,SLKEY_F4,SLKEY_LSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_S,SLKEY_R,SLKEY_B,SLKEY_N,SLKEY_ACTIVITY,SLKEY_HOME,SLKEY_MINUS,SLKEY_FRONTLIGHT,KEY_IGN,SLKEY_RSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_TAB,SLKEY_SLASH,SLKEY_H,SLKEY_M,SLKEY_F2,KEY_IGN,SLKEY_UP,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_2ND,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_X,SLKEY_F,SLKEY_SPACE,SLKEY_APOSTROPHE,SLKEY_MAIL,SLKEY_LEFT,SLKEY_DOWN,SLKEY_RIGHT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN};
-+
-+
-+
-+#define STATE_S0 0
-+#define STATE_S1 1
-+#define STATE_S2 2
-+#define STATE_S3 3
-+#define STATE_S4 4
-+#define STATE_S5 5
-+#define STATE_S6 6
-+#define STATE_S7 7
-+#define STATE_S8 8
-+#define STATE_S9 9
-+#define STATE_S10 10
-+#define STATE_S11 11
-+#define STATE_S12 12
-+#define STATE_S13 13
-+#define STATE_S14 14
-+#define STATE_S15 15
-+#define STATE_S16 16
-+#define STATE_S17 17
-+#define STATE_S18 18
-+#define STATE_S19 19
-+#define STATE_S20 20
-+#define STATE_S21 21
-+#define STATE_S22 22
-+#define STATE_S23 23
-+#define STATE_S24 24
-+#define STATE_S25 25
-+#define STATE_S26 26
-+#define STATE_S27 27
-+#define STATE_S28 28
-+#define STATE_S29 29
-+#define STATE_S30 30
-+#define STATE_S31 31
-+#define STATE_S32 32
-+#define STATE_S33 33
-+#define STATE_S34 34
-+#define STATE_S35 35
-+#define STATE_S36 36
-+#define STATE_S37 37
-+#define STATE_S38 38
-+#define STATE_S39 39
-+#define STATE_S40 40
-+#define STATE_S41 41
-+#define STATE_S42 42
-+#define STATE_S43 43
-+#define STATE_S44 44
-+#define STATE_S45 45
-+#define STATE_S46 46
-+#define STATE_S47 47
-+#define STATE_S48 48
-+#define STATE_S49 49
-+#define STATE_S50 50
-+#define STATE_S51 51
-+#define STATE_S52 52
-+#define STATE_S53 53
-+#define STATE_S54 54
-+#define STATE_S55 55
-+#define STATE_S56 56
-+#define STATE_S57 57
-+#define STATE_S58 58
-+#define STATE_S59 59
-+#define STATE_S60 60
-+#define STATE_S61 61
-+#define STATE_S62 62
-+#define STATE_S63 63
-+#define STATE_S64 64
-+#define STATE_S65 65
-+#define STATE_S66 66
-+#define STATE_S67 67
-+#define STATE_S68 68
-+#define STATE_S69 69
-+#define STATE_S70 70
-+#define STATE_S71 71
-+#define STATE_S72 72
-+#define STATE_S73 73
-+#define STATE_S74 74
-+#define STATE_S75 75
-+#define STATE_S76 76
-+#define STATE_S77 77
-+#define STATE_S78 78
-+#define STATE_S79 79
-+
-+
-+#define STATE_NUMS_TOTAL 80
-+
-+
-+#ifdef RAWKEY_MAP_DEBUG
-+static char *state_names[STATE_NUMS_TOTAL] = {
-+ "S0",
-+ "S1",
-+ "S2",
-+ "S3",
-+ "S4",
-+ "S5",
-+ "S6",
-+ "S7",
-+ "S8",
-+ "S9",
-+ "S10",
-+ "S11",
-+ "S12",
-+ "S13",
-+ "S14",
-+ "S15",
-+ "S16",
-+ "S17",
-+ "S18",
-+ "S19",
-+ "S20",
-+ "S21",
-+ "S22",
-+ "S23",
-+ "S24",
-+ "S25",
-+ "S26",
-+ "S27",
-+ "S28",
-+ "S29",
-+ "S30",
-+ "S31",
-+ "S32",
-+ "S33",
-+ "S34",
-+ "S35",
-+ "S36",
-+ "S37",
-+ "S38",
-+ "S39",
-+ "S40",
-+ "S41",
-+ "S42",
-+ "S43",
-+ "S44",
-+ "S45",
-+ "S46",
-+ "S47",
-+ "S48",
-+ "S49",
-+ "S50",
-+ "S51",
-+ "S52",
-+ "S53",
-+ "S54",
-+ "S55",
-+ "S56",
-+ "S57",
-+ "S58",
-+ "S59",
-+ "S60",
-+ "S61",
-+ "S62",
-+ "S63",
-+ "S64",
-+ "S65",
-+ "S66",
-+ "S67",
-+ "S68",
-+ "S69",
-+ "S70",
-+ "S71",
-+ "S72",
-+ "S73",
-+ "S74",
-+ "S75",
-+ "S76",
-+ "S77",
-+ "S78",
-+ "S79"
-+};
-+#endif /* RAWKEY_MAP_DEBUG */
-+
-+
-+static unsigned char state_table_LSHIFT_up[STATE_NUMS_TOTAL] = {
-+STATE_S0,STATE_S0,STATE_S2,STATE_S2,STATE_S4,STATE_S4,STATE_S6,STATE_S6,STATE_S8,STATE_S8,STATE_S10,STATE_S10,STATE_S12,STATE_S12,STATE_S14,STATE_S14,STATE_S16,STATE_S16,STATE_S18,STATE_S18,STATE_S20,STATE_S20,STATE_S22,STATE_S22,STATE_S24,STATE_S24,STATE_S26,STATE_S26,STATE_S28,STATE_S28,STATE_S30,STATE_S30,STATE_S32,STATE_S32,STATE_S34,STATE_S34,STATE_S36,STATE_S36,STATE_S38,STATE_S38,STATE_S40,STATE_S40,STATE_S42,STATE_S42,STATE_S44,STATE_S44,STATE_S46,STATE_S46,STATE_S48,STATE_S48,STATE_S50,STATE_S50,STATE_S52,STATE_S52,STATE_S54,STATE_S54,STATE_S56,STATE_S56,STATE_S58,STATE_S58,STATE_S60,STATE_S60,STATE_S62,STATE_S62,STATE_S64,STATE_S64,STATE_S66,STATE_S66,STATE_S68,STATE_S68,STATE_S70,STATE_S70,STATE_S72,STATE_S72,STATE_S74,STATE_S74,STATE_S76,STATE_S76,STATE_S78,STATE_S78};
-+
-+static unsigned char state_table_RSHIFT_up[STATE_NUMS_TOTAL] = {
-+STATE_S0,STATE_S1,STATE_S2,STATE_S3,STATE_S4,STATE_S5,STATE_S6,STATE_S7,STATE_S8,STATE_S9,STATE_S10,STATE_S11,STATE_S12,STATE_S13,STATE_S14,STATE_S15,STATE_S16,STATE_S17,STATE_S18,STATE_S19,STATE_S20,STATE_S21,STATE_S22,STATE_S23,STATE_S24,STATE_S25,STATE_S26,STATE_S27,STATE_S28,STATE_S29,STATE_S30,STATE_S31,STATE_S32,STATE_S33,STATE_S34,STATE_S35,STATE_S36,STATE_S37,STATE_S38,STATE_S39,STATE_S0,STATE_S1,STATE_S2,STATE_S3,STATE_S4,STATE_S5,STATE_S6,STATE_S7,STATE_S8,STATE_S9,STATE_S10,STATE_S11,STATE_S12,STATE_S13,STATE_S14,STATE_S15,STATE_S16,STATE_S17,STATE_S18,STATE_S19,STATE_S20,STATE_S21,STATE_S22,STATE_S23,STATE_S24,STATE_S25,STATE_S26,STATE_S27,STATE_S28,STATE_S29,STATE_S30,STATE_S31,STATE_S32,STATE_S33,STATE_S34,STATE_S35,STATE_S36,STATE_S37,STATE_S38,STATE_S39};
-+
-+static unsigned char state_table_2nd_up[STATE_NUMS_TOTAL] = {
-+STATE_S0,STATE_S1,STATE_S6,STATE_S7,STATE_S0,STATE_S1,STATE_S6,STATE_S7,STATE_S0,STATE_S1,STATE_S10,STATE_S11,STATE_S16,STATE_S17,STATE_S10,STATE_S11,STATE_S16,STATE_S17,STATE_S10,STATE_S11,STATE_S20,STATE_S21,STATE_S26,STATE_S27,STATE_S20,STATE_S21,STATE_S26,STATE_S27,STATE_S20,STATE_S21,STATE_S30,STATE_S31,STATE_S36,STATE_S37,STATE_S30,STATE_S31,STATE_S36,STATE_S37,STATE_S30,STATE_S31,STATE_S40,STATE_S41,STATE_S46,STATE_S47,STATE_S40,STATE_S41,STATE_S46,STATE_S47,STATE_S40,STATE_S41,STATE_S50,STATE_S51,STATE_S56,STATE_S57,STATE_S50,STATE_S51,STATE_S56,STATE_S57,STATE_S50,STATE_S51,STATE_S60,STATE_S61,STATE_S66,STATE_S67,STATE_S60,STATE_S61,STATE_S66,STATE_S67,STATE_S60,STATE_S61,STATE_S70,STATE_S71,STATE_S76,STATE_S77,STATE_S70,STATE_S71,STATE_S76,STATE_S77,STATE_S70,STATE_S71};
-+
-+
-+
-+#define UP_TABLES_SIZE 3
-+
-+
-+static unsigned char *up_tables[UP_TABLES_SIZE] = {
-+ state_table_LSHIFT_up,state_table_RSHIFT_up,state_table_2nd_up
-+};
-+
-+
-+#define SEE_LSHIFT_UP 0
-+#define SEE_RSHIFT_UP 1
-+#define SEE_2nd_UP 2
-+#define UP_NOP -1
-+
-+
-+static char up_modifs_ref[(NR_KEYCODES+1)] = {
-+UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,SEE_LSHIFT_UP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,SEE_RSHIFT_UP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,SEE_2nd_UP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP,UP_NOP};
-+
-+
-+static unsigned char state_table_LSHIFT_down[STATE_NUMS_TOTAL] = {
-+STATE_S1,STATE_S1,STATE_S3,STATE_S3,STATE_S5,STATE_S5,STATE_S7,STATE_S7,STATE_S9,STATE_S9,STATE_S11,STATE_S11,STATE_S13,STATE_S13,STATE_S15,STATE_S15,STATE_S17,STATE_S17,STATE_S19,STATE_S19,STATE_S21,STATE_S21,STATE_S23,STATE_S23,STATE_S25,STATE_S25,STATE_S27,STATE_S27,STATE_S29,STATE_S29,STATE_S31,STATE_S31,STATE_S33,STATE_S33,STATE_S35,STATE_S35,STATE_S37,STATE_S37,STATE_S39,STATE_S39,STATE_S41,STATE_S41,STATE_S43,STATE_S43,STATE_S45,STATE_S45,STATE_S47,STATE_S47,STATE_S49,STATE_S49,STATE_S51,STATE_S51,STATE_S53,STATE_S53,STATE_S55,STATE_S55,STATE_S57,STATE_S57,STATE_S59,STATE_S59,STATE_S61,STATE_S61,STATE_S63,STATE_S63,STATE_S65,STATE_S65,STATE_S67,STATE_S67,STATE_S69,STATE_S69,STATE_S71,STATE_S71,STATE_S73,STATE_S73,STATE_S75,STATE_S75,STATE_S77,STATE_S77,STATE_S79,STATE_S79};
-+
-+static unsigned char state_table_RSHIFT_down[STATE_NUMS_TOTAL] = {
-+STATE_S40,STATE_S41,STATE_S42,STATE_S43,STATE_S44,STATE_S45,STATE_S46,STATE_S47,STATE_S48,STATE_S49,STATE_S50,STATE_S51,STATE_S52,STATE_S53,STATE_S54,STATE_S55,STATE_S56,STATE_S57,STATE_S58,STATE_S59,STATE_S60,STATE_S61,STATE_S62,STATE_S63,STATE_S64,STATE_S65,STATE_S66,STATE_S67,STATE_S68,STATE_S69,STATE_S70,STATE_S71,STATE_S72,STATE_S73,STATE_S74,STATE_S75,STATE_S76,STATE_S77,STATE_S78,STATE_S79,STATE_S40,STATE_S41,STATE_S42,STATE_S43,STATE_S44,STATE_S45,STATE_S46,STATE_S47,STATE_S48,STATE_S49,STATE_S50,STATE_S51,STATE_S52,STATE_S53,STATE_S54,STATE_S55,STATE_S56,STATE_S57,STATE_S58,STATE_S59,STATE_S60,STATE_S61,STATE_S62,STATE_S63,STATE_S64,STATE_S65,STATE_S66,STATE_S67,STATE_S68,STATE_S69,STATE_S70,STATE_S71,STATE_S72,STATE_S73,STATE_S74,STATE_S75,STATE_S76,STATE_S77,STATE_S78,STATE_S79};
-+
-+static unsigned char state_table_2nd_down[STATE_NUMS_TOTAL] = {
-+STATE_S2,STATE_S3,STATE_S2,STATE_S3,STATE_S4,STATE_S5,STATE_S8,STATE_S9,STATE_S8,STATE_S9,STATE_S12,STATE_S13,STATE_S12,STATE_S13,STATE_S14,STATE_S15,STATE_S18,STATE_S19,STATE_S18,STATE_S19,STATE_S22,STATE_S23,STATE_S22,STATE_S23,STATE_S24,STATE_S25,STATE_S28,STATE_S29,STATE_S28,STATE_S29,STATE_S32,STATE_S33,STATE_S32,STATE_S33,STATE_S34,STATE_S35,STATE_S38,STATE_S39,STATE_S38,STATE_S39,STATE_S42,STATE_S43,STATE_S42,STATE_S43,STATE_S44,STATE_S45,STATE_S48,STATE_S49,STATE_S48,STATE_S49,STATE_S52,STATE_S53,STATE_S52,STATE_S53,STATE_S54,STATE_S55,STATE_S58,STATE_S59,STATE_S58,STATE_S59,STATE_S62,STATE_S63,STATE_S62,STATE_S63,STATE_S64,STATE_S65,STATE_S68,STATE_S69,STATE_S68,STATE_S69,STATE_S72,STATE_S73,STATE_S72,STATE_S73,STATE_S74,STATE_S75,STATE_S78,STATE_S79,STATE_S78,STATE_S79};
-+
-+static unsigned char state_table_caps_down[STATE_NUMS_TOTAL] = {
-+STATE_S0,STATE_S1,STATE_S14,STATE_S15,STATE_S14,STATE_S15,STATE_S10,STATE_S11,STATE_S14,STATE_S15,STATE_S10,STATE_S11,STATE_S4,STATE_S5,STATE_S4,STATE_S5,STATE_S0,STATE_S1,STATE_S4,STATE_S5,STATE_S20,STATE_S21,STATE_S34,STATE_S35,STATE_S34,STATE_S35,STATE_S30,STATE_S31,STATE_S34,STATE_S35,STATE_S30,STATE_S31,STATE_S24,STATE_S25,STATE_S24,STATE_S25,STATE_S20,STATE_S21,STATE_S24,STATE_S25,STATE_S40,STATE_S41,STATE_S54,STATE_S55,STATE_S54,STATE_S55,STATE_S50,STATE_S51,STATE_S54,STATE_S55,STATE_S50,STATE_S51,STATE_S44,STATE_S45,STATE_S44,STATE_S45,STATE_S40,STATE_S41,STATE_S44,STATE_S45,STATE_S60,STATE_S61,STATE_S74,STATE_S75,STATE_S74,STATE_S75,STATE_S70,STATE_S71,STATE_S74,STATE_S75,STATE_S70,STATE_S71,STATE_S64,STATE_S65,STATE_S64,STATE_S65,STATE_S60,STATE_S61,STATE_S64,STATE_S65};
-+
-+static unsigned char state_table_num_down[STATE_NUMS_TOTAL] = {
-+STATE_S0,STATE_S1,STATE_S24,STATE_S25,STATE_S24,STATE_S25,STATE_S20,STATE_S21,STATE_S24,STATE_S25,STATE_S10,STATE_S11,STATE_S34,STATE_S35,STATE_S34,STATE_S35,STATE_S30,STATE_S31,STATE_S34,STATE_S35,STATE_S20,STATE_S21,STATE_S4,STATE_S5,STATE_S4,STATE_S5,STATE_S0,STATE_S1,STATE_S4,STATE_S5,STATE_S30,STATE_S31,STATE_S14,STATE_S15,STATE_S14,STATE_S15,STATE_S10,STATE_S11,STATE_S14,STATE_S15,STATE_S40,STATE_S41,STATE_S64,STATE_S65,STATE_S64,STATE_S65,STATE_S60,STATE_S61,STATE_S64,STATE_S65,STATE_S50,STATE_S51,STATE_S74,STATE_S75,STATE_S74,STATE_S75,STATE_S70,STATE_S71,STATE_S74,STATE_S75,STATE_S60,STATE_S61,STATE_S44,STATE_S45,STATE_S44,STATE_S45,STATE_S40,STATE_S41,STATE_S44,STATE_S45,STATE_S70,STATE_S71,STATE_S54,STATE_S55,STATE_S54,STATE_S55,STATE_S50,STATE_S51,STATE_S54,STATE_S55};
-+
-+static unsigned char state_table_ANY_OTHER_down[STATE_NUMS_TOTAL] = {
-+STATE_S0,STATE_S1,STATE_S4,STATE_S5,STATE_S4,STATE_S5,STATE_S0,STATE_S1,STATE_S4,STATE_S5,STATE_S10,STATE_S11,STATE_S14,STATE_S15,STATE_S14,STATE_S15,STATE_S10,STATE_S11,STATE_S14,STATE_S15,STATE_S20,STATE_S21,STATE_S24,STATE_S25,STATE_S24,STATE_S25,STATE_S20,STATE_S21,STATE_S24,STATE_S25,STATE_S30,STATE_S31,STATE_S34,STATE_S35,STATE_S34,STATE_S35,STATE_S30,STATE_S31,STATE_S34,STATE_S35,STATE_S40,STATE_S41,STATE_S44,STATE_S45,STATE_S44,STATE_S45,STATE_S40,STATE_S41,STATE_S44,STATE_S45,STATE_S50,STATE_S51,STATE_S54,STATE_S55,STATE_S54,STATE_S55,STATE_S50,STATE_S51,STATE_S54,STATE_S55,STATE_S60,STATE_S61,STATE_S64,STATE_S65,STATE_S64,STATE_S65,STATE_S60,STATE_S61,STATE_S64,STATE_S65,STATE_S70,STATE_S71,STATE_S74,STATE_S75,STATE_S74,STATE_S75,STATE_S70,STATE_S71,STATE_S74,STATE_S75};
-+
-+
-+
-+#define DOWN_TABLES_SIZE 6
-+
-+
-+static unsigned char *down_tables[DOWN_TABLES_SIZE] = {
-+ state_table_LSHIFT_down,state_table_RSHIFT_down,state_table_2nd_down,state_table_caps_down,state_table_num_down,state_table_ANY_OTHER_down
-+};
-+
-+
-+#define SEE_LSHIFT_DOWN 0
-+#define SEE_RSHIFT_DOWN 1
-+#define SEE_2nd_DOWN 2
-+#define SEE_caps_DOWN 3
-+#define SEE_num_DOWN 4
-+#define SEE_ANY_OTHER_DOWN 5
-+#define DOWN_NOP -1
-+
-+
-+static char down_modifs_ref[(NR_KEYCODES+1)] = {
-+DOWN_NOP,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_LSHIFT_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_RSHIFT_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_2nd_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_caps_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_num_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN,SEE_ANY_OTHER_DOWN};
-+
-+
-+static unsigned char extmodif_map_2nd[STATE_NUMS_TOTAL] = {0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1};
-+static unsigned char extmodif_map_CAPS[STATE_NUMS_TOTAL] = {0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1};
-+static unsigned char extmodif_map_NUM[STATE_NUMS_TOTAL] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
-+
-+#define EXTMODIF_SHOWSTAT_KEYMAX 4
-+
-+static unsigned char *extmodif_status_tables[EXTMODIF_SHOWSTAT_KEYMAX] = {
-+NULL,extmodif_map_2nd,extmodif_map_CAPS,extmodif_map_NUM};
-+
-+
-+static unsigned char extmove_map_2nd[STATE_NUMS_TOTAL] = {STATE_S6,STATE_S7,STATE_S2,STATE_S3,STATE_S4,STATE_S5,STATE_S0,STATE_S1,STATE_S8,STATE_S9,STATE_S16,STATE_S17,STATE_S12,STATE_S13,STATE_S14,STATE_S15,STATE_S10,STATE_S11,STATE_S18,STATE_S19,STATE_S26,STATE_S27,STATE_S22,STATE_S23,STATE_S24,STATE_S25,STATE_S20,STATE_S21,STATE_S28,STATE_S29,STATE_S36,STATE_S37,STATE_S32,STATE_S33,STATE_S34,STATE_S35,STATE_S30,STATE_S31,STATE_S38,STATE_S39,STATE_S46,STATE_S47,STATE_S42,STATE_S43,STATE_S44,STATE_S45,STATE_S40,STATE_S41,STATE_S48,STATE_S49,STATE_S56,STATE_S57,STATE_S52,STATE_S53,STATE_S54,STATE_S55,STATE_S50,STATE_S51,STATE_S58,STATE_S59,STATE_S66,STATE_S67,STATE_S62,STATE_S63,STATE_S64,STATE_S65,STATE_S60,STATE_S61,STATE_S68,STATE_S69,STATE_S76,STATE_S77,STATE_S72,STATE_S73,STATE_S74,STATE_S75,STATE_S70,STATE_S71,STATE_S78,STATE_S79};
-+static unsigned char extmove_map_CAPS[STATE_NUMS_TOTAL] = {STATE_S10,STATE_S11,STATE_S12,STATE_S13,STATE_S14,STATE_S15,STATE_S16,STATE_S17,STATE_S18,STATE_S19,STATE_S0,STATE_S1,STATE_S2,STATE_S3,STATE_S4,STATE_S5,STATE_S6,STATE_S7,STATE_S8,STATE_S9,STATE_S30,STATE_S31,STATE_S32,STATE_S33,STATE_S34,STATE_S35,STATE_S36,STATE_S37,STATE_S38,STATE_S39,STATE_S20,STATE_S21,STATE_S22,STATE_S23,STATE_S24,STATE_S25,STATE_S26,STATE_S27,STATE_S28,STATE_S29,STATE_S50,STATE_S51,STATE_S52,STATE_S53,STATE_S54,STATE_S55,STATE_S56,STATE_S57,STATE_S58,STATE_S59,STATE_S40,STATE_S41,STATE_S42,STATE_S43,STATE_S44,STATE_S45,STATE_S46,STATE_S47,STATE_S48,STATE_S49,STATE_S70,STATE_S71,STATE_S72,STATE_S73,STATE_S74,STATE_S75,STATE_S76,STATE_S77,STATE_S78,STATE_S79,STATE_S60,STATE_S61,STATE_S62,STATE_S63,STATE_S64,STATE_S65,STATE_S66,STATE_S67,STATE_S68,STATE_S69};
-+static unsigned char extmove_map_NUM[STATE_NUMS_TOTAL] = {STATE_S20,STATE_S21,STATE_S22,STATE_S23,STATE_S24,STATE_S25,STATE_S26,STATE_S27,STATE_S28,STATE_S29,STATE_S30,STATE_S31,STATE_S32,STATE_S33,STATE_S34,STATE_S35,STATE_S36,STATE_S37,STATE_S38,STATE_S39,STATE_S0,STATE_S1,STATE_S2,STATE_S3,STATE_S4,STATE_S5,STATE_S6,STATE_S7,STATE_S8,STATE_S9,STATE_S10,STATE_S11,STATE_S12,STATE_S13,STATE_S14,STATE_S15,STATE_S16,STATE_S17,STATE_S18,STATE_S19,STATE_S60,STATE_S61,STATE_S62,STATE_S63,STATE_S64,STATE_S65,STATE_S66,STATE_S67,STATE_S68,STATE_S69,STATE_S70,STATE_S71,STATE_S72,STATE_S73,STATE_S74,STATE_S75,STATE_S76,STATE_S77,STATE_S78,STATE_S79,STATE_S40,STATE_S41,STATE_S42,STATE_S43,STATE_S44,STATE_S45,STATE_S46,STATE_S47,STATE_S48,STATE_S49,STATE_S50,STATE_S51,STATE_S52,STATE_S53,STATE_S54,STATE_S55,STATE_S56,STATE_S57,STATE_S58,STATE_S59};
-+
-+#define EXTMODIF_MOVESTAT_KEYMAX 4
-+
-+static unsigned char *extmodif_move_tables[EXTMODIF_MOVESTAT_KEYMAX] = {
-+NULL,extmove_map_2nd,extmove_map_CAPS,extmove_map_NUM};
-+
-+
-+
-+typedef struct shappda_holdkey_info {
-+ int type;
-+ int character;
-+ void (*func)(void);
-+} shappda_holdkey_info;
-+
-+#define HOLDKEYTYPE_CHAR 1
-+#define HOLDKEYTYPE_FUNC 2
-+
-+static shappda_holdkey_info shappda_holdkey_UserDef = {
-+ type: HOLDKEYTYPE_CHAR,
-+ character: SLKEY_EXCLAM,
-+ func: NULL
-+};
-+static shappda_holdkey_info shappda_holdkey_Mail = {
-+ type: HOLDKEYTYPE_CHAR,
-+ character: SLKEY_MAIL2,
-+ func: NULL
-+};
-+
-+static shappda_holdkey_info *holdkey_info[(NR_KEYCODES+1)] = {
-+NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&shappda_holdkey_UserDef,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&shappda_holdkey_Mail,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
-+
-+
-+static unsigned char *state_to_keymap[STATE_NUMS_TOTAL] = {
-+rawkeytable_table_NormalLower,rawkeytable_table_NormalUpper,rawkeytable_table_2ndLower,rawkeytable_table_2ndUpper,rawkeytable_table_2ndLower,rawkeytable_table_2ndUpper,rawkeytable_table_2ndLower,rawkeytable_table_2ndUpper,rawkeytable_table_2ndLower,rawkeytable_table_2ndUpper,rawkeytable_table_NormalLower,rawkeytable_table_NormalUpper,rawkeytable_table_2ndLower,rawkeytable_table_2ndUpper,rawkeytable_table_2ndLower,rawkeytable_table_2ndUpper,rawkeytable_table_2ndLower,rawkeytable_table_2ndUpper,rawkeytable_table_2ndLower,rawkeytable_table_2ndUpper,rawkeytable_table_NumlockLower,rawkeytable_table_NumlockUpper,rawkeytable_table_Num2ndLower,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndLower,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndLower,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndLower,rawkeytable_table_Num2ndUpper,rawkeytable_table_NumlockLower,rawkeytable_table_NumlockUpper,rawkeytable_table_Num2ndLower,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndLower,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndLower,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndLower,rawkeytable_table_Num2ndUpper,rawkeytable_table_NormalUpper,rawkeytable_table_NormalUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_NormalUpper,rawkeytable_table_NormalUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_NumlockUpper,rawkeytable_table_NumlockUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_NumlockUpper,rawkeytable_table_NumlockUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper};
-+
-+
-+#endif /* ! __KEYTABLE_H_INCLUDED__ */
-diff -Nur linux_c860_org/drivers/char/tosa_rawmap_rollover.h linux/drivers/char/tosa_rawmap_rollover.h
---- linux_c860_org/drivers/char/tosa_rawmap_rollover.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/char/tosa_rawmap_rollover.h 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,27 @@
-+#ifndef __TOSA_RAWMAP_ROLLOVER_H__
-+#define __TOSA_RAWMAP_ROLLOVER_H__
-+
-+#define ROLLOVER_NO_FLAG 0x00
-+#define ROLLOVER_TAB 0x01
-+#define ROLLOVER_DIRECT_ON 0x02
-+#define ROLLOVER_HORIZONTAL 0x04
-+#define ROLLOVER_VERTICAL 0x08
-+#define ROLLOVER_ENTQUESPC 0x10
-+#define ROLLOVER_LSHIFT 0x20
-+#define ROLLOVER_RSHIFT 0x40
-+#define ROLLOVER_FUNCTION 0x80
-+
-+#define ROLLOVER_CHECK_FLAG(a, b) (((a) & (b)) != 0)
-+
-+static unsigned int rollover_flag_table[(NR_KEYCODES+1)] = {
-+ ROLLOVER_NO_FLAG,
-+ /*0*/ ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG,
-+ /*1*/ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG,
-+ /*2*/ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_ENTQUESPC/**/, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG,
-+ /*3*/ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_DIRECT_ON/**/, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_LSHIFT/**/, ROLLOVER_RSHIFT, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG,
-+ /*4*/ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_DIRECT_ON/**/, ROLLOVER_DIRECT_ON/**/, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_RSHIFT/**/, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG,
-+ /*5*/ROLLOVER_TAB/**/, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_DIRECT_ON/**/, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_VERTICAL/**/, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_FUNCTION/**/, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG,
-+ /*6*/ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_ENTQUESPC/**/, ROLLOVER_DIRECT_ON/**/, ROLLOVER_NO_FLAG, ROLLOVER_HORIZONTAL/**/, ROLLOVER_VERTICAL/**/, ROLLOVER_HORIZONTAL/**/, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG,
-+ /*7*/ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG, ROLLOVER_NO_FLAG
-+};
-+#endif // end __TOSA_RAWMAP_ROLLOVER_H__
-diff -Nur linux_c860_org/drivers/char/tosa_ts.c linux/drivers/char/tosa_ts.c
---- linux_c860_org/drivers/char/tosa_ts.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/char/tosa_ts.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,807 @@
-+/*
-+ * drivers/char/tosa_ts.c
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ *
-+ * Based on:
-+ * cotulla_ts.c
-+ *
-+ */
-+
-+/***************************************************************************/
-+
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/poll.h>
-+#include <linux/delay.h>
-+#include <linux/ioctl.h>
-+#include <linux/ac97_codec.h>
-+#include <linux/sched.h>
-+#include <linux/tqueue.h>
-+#include <linux/module.h>
-+#include <linux/proc_fs.h>
-+
-+#include <asm/segment.h>
-+#include <asm/uaccess.h>
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/irqs.h>
-+#include <asm/arch/tosa_wm9712.h>
-+#include <asm/sharp_apm.h>
-+
-+#define TS_MAJOR 11
-+#define ADD_TS_TIMER (HZ / 120)
-+/* AC97 Touch Screen channel */
-+#define ADCH_TPX 0x01
-+#define ADCH_TPY 0x02
-+/* AC97 Touch Screen bits */
-+#define TSR1_POLL (1<<15)
-+#define TSR1_COO (1<<11)
-+#define TSR1_CTC (1<<10)
-+#define TSR1_SLEN (1<< 3)
-+#define TSR2_RPR (1<<13)
-+#define TSR2_45W (1<<12)
-+#define TSR2_PDEN (1<<11)
-+#define TSR2_WAIT (1<< 9)
-+#define TSR2_PIL (1<< 8)
-+#define CODEC_PENDOWN (1<< 3)
-+
-+#define TS_REG1_POLL 0x8000
-+#define TS_REG1_DEFVAL 0x0000
-+#define TS_REG2_DEFVAL 0xe030
-+
-+#define DBG_LEVEL 0
-+
-+#define DBG_L1 1
-+#define DBG_L2 2
-+#define DBG_L3 3
-+
-+#define DEBUG(level, x, args...) \
-+ if( level <= DBG_LEVEL ) printk("%s: " x, __FUNCTION__ , ## args)
-+
-+#define DEV_NAME "ts"
-+
-+int ts_type = 0;
-+
-+static DECLARE_WAIT_QUEUE_HEAD(ts_proc);
-+
-+static DECLARE_WAIT_QUEUE_HEAD(pd_mloop);
-+
-+static struct timer_list tp_main_timer;
-+static unsigned char tp_timer_on = 0;
-+static unsigned char ac97_on = 0;
-+static unsigned char penup_irq = 1;
-+
-+int ac97_ad_input(int, unsigned short *);
-+static void ts_interrupt(int, void*, struct pt_regs*);
-+
-+#define BUFSIZE 128
-+
-+typedef struct {
-+ unsigned short xd;
-+ unsigned short yd;
-+ unsigned char pressure;
-+} ts_pos_t;
-+
-+typedef struct {
-+ short pressure;
-+ short x;
-+ short y;
-+ short millisecs;
-+} TS_EVENT;
-+
-+static DECLARE_WAIT_QUEUE_HEAD(queue);
-+struct fasync_struct *fasync;
-+static TS_EVENT tbuf[BUFSIZE], tc;
-+static int raw_max_x, raw_max_y;
-+static int res_x, res_y;
-+static int raw_min_x, raw_min_y;
-+static int cal_ok, x_rev, y_rev, xyswap;
-+static int head = 0, tail = 0;
-+
-+#ifdef CONFIG_PM
-+static int tp_suspend = 0;
-+#endif /* CONFIG_PM */
-+
-+#define REMOVE_TP_NOISE_BY_SW
-+/* #define REMOVE_TP_NOISE_BY_HW */
-+
-+#if 1 // 2003/9/4 Noise reduction
-+#define TOUCH_PANEL_AVERAGE 5
-+#define DEFAULT_TP_WAIT_VGA 25
-+#define DEFAULT_TP_WAIT_QVGA 44
-+#define SIMPLE_AVERAGE
-+
-+#define CCNT(a) asm("mrc p14, 0, %0, C1, C0, 0" : "=r"(a))
-+#define CCNT_ON() {int pmnc = 1;asm("mcr p14, 0, %0, C0, C0, 0" : : "r"(pmnc));}
-+#define CCNT_OFF() {int pmnc = 0;asm("mcr p14, 0, %0, C0, C0, 0" : : "r"(pmnc));}
-+static unsigned long g_TpWaitVga = DEFAULT_TP_WAIT_VGA;
-+static unsigned long g_TpWaitQvga = DEFAULT_TP_WAIT_QVGA;
-+static unsigned short XBuf[TOUCH_PANEL_AVERAGE];
-+static unsigned short YBuf[TOUCH_PANEL_AVERAGE];
-+static int TpBufIdx = -1;
-+extern int tc6393fb_isblank; // no H-Sync while blanking
-+
-+#define PROC_DIRNAME "ts"
-+
-+struct proc_dir_entry *proc_ts = NULL;
-+typedef struct tosa_ts_entry {
-+ unsigned long* addr;
-+ unsigned long def_value;
-+ char* name;
-+ char* description;
-+ unsigned short low_ino;
-+} tosa_ts_entry_t;
-+static tosa_ts_entry_t tosa_ts_params[] = {
-+/* { addr, def_value, name, description }*/
-+ { &g_TpWaitVga, DEFAULT_TP_WAIT_VGA, "wait_vga","pen wait for VGA Screen" },
-+ { &g_TpWaitQvga, DEFAULT_TP_WAIT_QVGA, "wait_qvga","pen wait for QVGA Screen"}
-+};
-+#define NUM_OF_TOSA_TS_ENTRY (sizeof(tosa_ts_params)/sizeof(tosa_ts_entry_t))
-+
-+static ssize_t tosa_ts_read_params(struct file *file, char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ int i_ino = (file->f_dentry->d_inode)->i_ino;
-+ char outputbuf[15];
-+ int count;
-+ int i;
-+ tosa_ts_entry_t *current_param = NULL;
-+ if (*ppos>0) /* Assume reading completed in previous read*/
-+ return 0;
-+ for (i=0; i<NUM_OF_TOSA_TS_ENTRY; i++) {
-+ if (tosa_ts_params[i].low_ino==i_ino) {
-+ current_param = &tosa_ts_params[i];
-+ break;
-+ }
-+ }
-+ if (current_param==NULL) {
-+ return -EINVAL;
-+ }
-+ count = sprintf(outputbuf, "%d\n",
-+ *((volatile unsigned long *) current_param->addr));
-+ *ppos += count;
-+ if (count>nbytes) /* Assume output can be read at one time */
-+ return -EINVAL;
-+ if (copy_to_user(buf, outputbuf, count))
-+ return -EFAULT;
-+ return count;
-+}
-+
-+static ssize_t tosa_ts_write_params(struct file *file, const char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ int i_ino = (file->f_dentry->d_inode)->i_ino;
-+ tosa_ts_entry_t *current_param = NULL;
-+ int i;
-+ unsigned long param;
-+ char *endp;
-+
-+ for (i=0; i<NUM_OF_TOSA_TS_ENTRY; i++) {
-+ if(tosa_ts_params[i].low_ino==i_ino) {
-+ current_param = &tosa_ts_params[i];
-+ break;
-+ }
-+ }
-+ if (current_param==NULL) {
-+ return -EINVAL;
-+ }
-+
-+ param = simple_strtoul(buf,&endp,0);
-+ if (param == -1) {
-+ *current_param->addr = current_param->def_value;
-+ } else {
-+ *current_param->addr = param;
-+ }
-+ return nbytes+endp-buf;
-+}
-+
-+static struct file_operations proc_params_operations = {
-+ read: tosa_ts_read_params,
-+ write: tosa_ts_write_params,
-+};
-+
-+static int init_procinfo(void)
-+{
-+ int i;
-+ struct proc_dir_entry *entry;
-+
-+ proc_ts = proc_mkdir("driver/ts", NULL);
-+ if (proc_ts == NULL) {
-+ printk(KERN_ERR "ts: can't create /proc/driver/ts\n");
-+ return -ENOMEM;
-+ }
-+ for (i=0; i<NUM_OF_TOSA_TS_ENTRY; i++) {
-+ entry = create_proc_entry(tosa_ts_params[i].name,
-+ S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH,
-+ proc_ts);
-+ if (entry) {
-+ tosa_ts_params[i].low_ino = entry->low_ino;
-+ entry->proc_fops = &proc_params_operations;
-+ } else {
-+ int j;
-+ for (j=0; j<i; j++) {
-+ remove_proc_entry(tosa_ts_params[i].name,
-+ proc_ts);
-+ }
-+ remove_proc_entry("driver/ts", &proc_root);
-+ proc_ts = 0;
-+ return -ENOMEM;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static void cleanup_procinfo(void)
-+{
-+ int i;
-+ for (i=0; i<NUM_OF_TOSA_TS_ENTRY; i++) {
-+ remove_proc_entry(tosa_ts_params[i].name, proc_ts);
-+ }
-+ remove_proc_entry("driver/ts", NULL);
-+ proc_ts = 0;
-+}
-+#endif
-+
-+static int read_xydata(ts_pos_t *tp)
-+{
-+#if defined(REMOVE_TP_NOISE_BY_SW) || defined(REMOVE_TP_NOISE_BY_HW)
-+ unsigned short dx, dy;
-+ unsigned long tx, ty;
-+ int i, ret = 0, penstate = 0;
-+
-+ if (TpBufIdx<0) {
-+ for (i=0; i<TOUCH_PANEL_AVERAGE; i++) {
-+ if( (ret = ac97_ad_input(ADCH_TPX, &dx)) < 0 ) return ret;
-+ XBuf[i] = dx & 0x0fff;
-+ if( (ret = ac97_ad_input(ADCH_TPY, &dy)) < 0 ) return ret;
-+ YBuf[i] = dy & 0x0fff;
-+ }
-+ TpBufIdx = 0;
-+ } else {
-+ if( (ret = ac97_ad_input(ADCH_TPX, &dx)) < 0 ) return ret;
-+ XBuf[TpBufIdx] = dx & 0x0fff;
-+ if( (ret = ac97_ad_input(ADCH_TPY, &dy)) < 0 ) return ret;
-+ YBuf[TpBufIdx] = dy & 0x0fff;
-+ if (++TpBufIdx>=TOUCH_PANEL_AVERAGE) TpBufIdx = 0;
-+ }
-+
-+ /* If pen Up or Down */
-+ penstate = (dy & 0x8000)?1:0;
-+
-+#if TOUCH_PANEL_AVERAGE<3
-+#define SIMPLE_AVERAGE
-+#endif
-+ {
-+#ifndef SIMPLE_AVERAGE
-+ unsigned short max_dx=0,max_dy=0;
-+ unsigned short min_dx=0x0fff,min_dy=0x0fff;
-+#endif
-+
-+ for(i = 0, ty = 0, tx = 0; i < (TOUCH_PANEL_AVERAGE); i++) {
-+ dx = XBuf[i];
-+ dy = YBuf[i];
-+#ifndef SIMPLE_AVERAGE
-+ if(dx > max_dx) max_dx = dx;
-+ if(dx < min_dx) min_dx = dx;
-+ if(dy > max_dy) max_dy = dy;
-+ if(dy < min_dy) min_dy = dy;
-+#endif
-+ tx += dx;
-+ ty += dy;
-+ }
-+#ifndef SIMPLE_AVERAGE
-+ tp->xd = (tx - max_dx - min_dx)/ (TOUCH_PANEL_AVERAGE-2);
-+ tp->yd = (ty - max_dy - min_dy)/ (TOUCH_PANEL_AVERAGE-2);
-+#else
-+ tp->xd = tx/ TOUCH_PANEL_AVERAGE;
-+ tp->yd = ty/ TOUCH_PANEL_AVERAGE;
-+#endif
-+ }
-+#else
-+ unsigned short dx, dy, tx, ty;
-+ int i, ret = 0;
-+
-+ for(i = 0, ty = 0, tx = 0; i < TOUCH_PANEL_AVERAGE; i++) {
-+ /* X */
-+ if( (ret = ac97_ad_input(ADCH_TPX, &dx)) < 0 ) return ret;
-+ /* Y */
-+ if( (ret = ac97_ad_input(ADCH_TPY, &dy)) < 0 ) return ret;
-+
-+ tx += (dx & 0x0fff);
-+ ty += (dy & 0x0fff);
-+ }
-+
-+ /* If pen Up or Down */
-+ penstate = (dy & 0x8000)?1:0;
-+
-+ tp->xd = tx / TOUCH_PANEL_AVERAGE;
-+ tp->yd = ty / TOUCH_PANEL_AVERAGE;
-+#endif
-+ return penstate;
-+}
-+
-+static void print_par(void)
-+{
-+ printk(" Kernel ==> cal_ok = %d\n",cal_ok);
-+ printk(" Kernel ==> raw_max_x = %d\n",raw_max_x);
-+ printk(" Kernel ==> raw_max_y = %d\n",raw_max_y);
-+ printk(" Kernel ==> res_x = %d\n",res_x);
-+ printk(" Kernel ==> res_y = %d\n",res_y);
-+ printk(" Kernel ==> raw_min_x = %d\n",raw_min_x);
-+ printk(" Kernel ==> raw_min_y = %d\n",raw_min_y);
-+ printk(" Kernel ==> xyswap = %d\n",xyswap);
-+ printk(" Kernel ==> x_rev = %d\n",x_rev);
-+ printk(" Kernel ==> y_rev = %d\n",y_rev);
-+}
-+
-+void ts_clear(void)
-+{
-+ int i;
-+
-+ for (i = 0; i < BUFSIZE; i++) {
-+ tbuf[i].pressure = 0;
-+ tbuf[i].x = 0;
-+ tbuf[i].y = 0;
-+ tbuf[i].millisecs = 0;
-+ }
-+ head = tail = 0;
-+}
-+
-+static TS_EVENT get_data(void)
-+{
-+ int last = tail;
-+ if (++tail == BUFSIZE) { tail = 0; }
-+ return tbuf[last];
-+}
-+
-+static void new_data(void)
-+{
-+ tc.millisecs = jiffies;
-+ tbuf[head++] = tc;
-+ if( head >= BUFSIZE )
-+ head = 0;
-+ if( head == tail && ++tail >= BUFSIZE )
-+ tail = 0;
-+ if( fasync )
-+ kill_fasync(&fasync, SIGIO, POLL_IN);
-+ wake_up_interruptible(&queue);
-+}
-+
-+static void ts_timer(unsigned long irq);
-+
-+static void ts_timer_clear(void)
-+{
-+ if ( tp_timer_on )
-+ del_timer(&tp_main_timer);
-+ tp_timer_on = 0;
-+}
-+
-+static void ts_timer_set(void)
-+{
-+ ts_timer_clear();
-+ init_timer(&tp_main_timer);
-+ tp_main_timer.data = IRQ_GPIO_TP_INT;
-+ tp_main_timer.function = ts_timer;
-+ tp_main_timer.expires = jiffies + ADD_TS_TIMER;
-+ add_timer(&tp_main_timer);
-+ tp_timer_on = 1;
-+}
-+
-+static void ts_timer(unsigned long irq)
-+{
-+ wake_up(&ts_proc);
-+}
-+
-+static int ts_pendown(void *unuse)
-+{
-+ int penstate;
-+ ts_pos_t pos_dt;
-+
-+ while ( 1 ) {
-+ interruptible_sleep_on(&pd_mloop);
-+
-+#ifdef CONFIG_PM
-+ lock_FCS(POWER_MODE_TOUCH, 1); // not enter FCS mode.
-+#endif /* CONFIG_PM */
-+ wm9712_power_mode_ts(WM9712_PWR_TP_CONV);
-+ while ( 1 ) {
-+#ifdef CONFIG_PM
-+ if ( !tp_suspend )
-+#endif /* CONFIG_PM */
-+ {
-+ if ( (penstate = read_xydata(&pos_dt)) >= 0 ) {
-+ if ( !penstate ) //penup
-+ penup_irq = 1;
-+ tc.x = pos_dt.xd;
-+ tc.y = pos_dt.yd;
-+ tc.pressure = 1;
-+ new_data();
-+ DEBUG(DBG_L3, "pen position (%d,%d,%d)\n",
-+ (int)tc.y, (int)tc.x, tc.pressure);
-+ }
-+ /* wait */
-+ if ( !penup_irq ) {
-+ ts_timer_set();
-+ interruptible_sleep_on(&ts_proc);
-+ }
-+ if ( penup_irq ){
-+ ts_timer_clear();
-+ /* setting interrupt edge */
-+ set_GPIO_IRQ_edge(GPIO_TP_INT, GPIO_RISING_EDGE);
-+ GEDR(GPIO_TP_INT) = GPIO_bit(GPIO_TP_INT); //Clear detect
-+#ifdef CONFIG_PM
-+ lock_FCS(POWER_MODE_TOUCH, 0); // not enter FCS mode.
-+#endif /* CONFIG_PM */
-+ wm9712_power_mode_ts(WM9712_PWR_TP_WAIT);
-+ TpBufIdx = -1;
-+ if ( tc.pressure ){
-+ tc.pressure = 0;
-+ new_data();
-+ }
-+ break;
-+ }
-+ }
-+#ifdef CONFIG_PM
-+ else {
-+ DEBUG(DBG_L1, "suspend...\n");
-+#ifdef CONFIG_PM
-+ lock_FCS(POWER_MODE_TOUCH, 0); // enter FCS mode.
-+#endif /* CONFIG_PM */
-+ break;
-+ }
-+#endif
-+ }
-+ }
-+
-+}
-+
-+static void ts_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ if( (GPLR(GPIO_TP_INT) & GPIO_bit(GPIO_TP_INT)) == GPIO_bit(GPIO_TP_INT) ) {
-+ /* pen down irq */
-+ penup_irq = 0;
-+
-+ /* setting interrupt edge */
-+ set_GPIO_IRQ_edge(GPIO_TP_INT, GPIO_FALLING_EDGE);
-+ GEDR(GPIO_TP_INT) = GPIO_bit(GPIO_TP_INT); //Clear detect
-+ wake_up(&pd_mloop);
-+ } else {
-+ /* setting interrupt edge */
-+ set_GPIO_IRQ_edge(GPIO_TP_INT, GPIO_RISING_EDGE);
-+ GEDR(GPIO_TP_INT) = GPIO_bit(GPIO_TP_INT); //Clear detect
-+ /* pen up irq */
-+ penup_irq = 1;
-+ wake_up(&ts_proc);
-+ }
-+ return;
-+}
-+
-+static int ts_open(struct inode *, struct file *);
-+static int ts_release(struct inode *, struct file *);
-+static int ts_fasync(int fd, struct file *filp, int on);
-+static ssize_t ts_read(struct file *, char *, size_t, loff_t *);
-+static unsigned int ts_poll(struct file *, poll_table *);
-+static int ts_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
-+struct file_operations ts_fops = {
-+ open: ts_open,
-+ release: ts_release,
-+ fasync: ts_fasync,
-+ read: ts_read,
-+ poll: ts_poll,
-+ ioctl: ts_ioctl,
-+};
-+
-+static void ts_exit(void)
-+{
-+ ts_timer_clear();
-+ ts_clear();
-+ free_irq(IRQ_GPIO_TP_INT, NULL);
-+ wm9712_power_mode_ts(WM9712_PWR_OFF);
-+
-+ pxa_ac97_put(&ac97_on);
-+}
-+
-+#ifdef MODULE
-+static void __exit ac97_ts_cleanup(void)
-+{
-+ ts_exit();
-+ unregister_chrdev(TS_MAJOR, "ts");
-+}
-+module_exit(ac97_ts_cleanup);
-+#endif /* MODULE */
-+
-+extern int tc6393fb_lcdMode;
-+
-+int ac97_ad_input(int ch, unsigned short *dat)
-+{
-+ unsigned short val = 0;
-+ unsigned short adsel = (ch << 12) & 0x7000;
-+ unsigned long timeo;
-+ volatile unsigned long t1=0,t2=0;
-+ volatile int isVga=(tc6393fb_lcdMode==1)?1:0;
-+ volatile unsigned long tpwait=200;
-+
-+
-+ if (ch >= 4){
-+ /* Conversion start */
-+ ac97_write(AC97_TS_REG1, (adsel | TS_REG1_DEFVAL|TS_REG1_POLL));
-+
-+ for(timeo = 0x10000; timeo > 0; timeo--) {
-+ val = ac97_read(AC97_TS_REG1);
-+ //udelay(100);
-+ if( val & TS_REG1_POLL ) continue;
-+ val = ac97_read(AC97_TS_READBACK);
-+ if( (val & 0x7000) == adsel ) break;
-+ }
-+ if( !timeo ) return -EBUSY;
-+
-+ // *dat = val & 0xfff;
-+ *dat = val;
-+ return 0;
-+ }
-+
-+
-+#if defined(REMOVE_TP_NOISE_BY_SW) || defined(REMOVE_TP_NOISE_BY_HW)
-+
-+#ifndef REMOVE_TP_NOISE_BY_HW
-+ tpwait *= (isVga)?g_TpWaitVga:g_TpWaitQvga;
-+ CCNT_ON();
-+ if (!tc6393fb_isblank) {
-+ /* Sync */
-+ while((GPLR(GPIO_VGA_LINE) & GPIO_bit(GPIO_VGA_LINE)) == 0)
-+ ;
-+ while((GPLR(GPIO_VGA_LINE) & GPIO_bit(GPIO_VGA_LINE)) != 0)
-+ ;
-+ }
-+ if (tpwait>0) {
-+ CCNT(t1);
-+ CCNT(t2);
-+ while((t2-t1)<tpwait) {
-+ CCNT(t2);
-+ }
-+ }
-+#endif
-+
-+ /* Conversion start */
-+ ac97_write(AC97_TS_REG1, (adsel | TS_REG1_DEFVAL|TS_REG1_POLL));
-+
-+#ifndef REMOVE_TP_NOISE_BY_HW
-+ CCNT_OFF();
-+#endif
-+
-+ /* Busy wait */
-+ for(timeo = 0x10000; timeo > 0; timeo--) {
-+ val = ac97_read(AC97_TS_REG1);
-+ if((val & TS_REG1_POLL) == 0) break;
-+ }
-+ if( !timeo ) return -EBUSY;
-+
-+ /* Read AD */
-+ val = ac97_read(AC97_TS_READBACK);
-+
-+ if( (val & 0x8000) == 0) return -EBUSY;
-+
-+ if( (val & 0x7000) == adsel ) {
-+ *dat = val;
-+ return 0;
-+ }
-+ return -EBUSY;
-+#else
-+ /* Conversion start */
-+ ac97_write(AC97_TS_REG1, (adsel | TS_REG1_DEFVAL|TS_REG1_POLL));
-+
-+ for(timeo = 0x10000; timeo > 0; timeo--) {
-+ val = ac97_read(AC97_TS_REG1);
-+ //udelay(100);
-+ if( val & TS_REG1_POLL ) continue;
-+ val = ac97_read(AC97_TS_READBACK);
-+ if( (val & 0x7000) == adsel ) break;
-+ }
-+ if( !timeo ) return -EBUSY;
-+
-+ *dat = val;
-+ return 0;
-+#endif
-+}
-+
-+static int ts_init(void)
-+{
-+ pxa_ac97_get(&codec, &ac97_on);
-+
-+ wm9712_power_mode_ts(WM9712_PWR_TP_WAIT);
-+ /* Touch Screen Initialize */
-+#ifdef REMOVE_TP_NOISE_BY_HW
-+ ac97_write(AC97_TS_REG2, 0xe0f0);
-+#else
-+ ac97_write(AC97_TS_REG2, TS_REG2_DEFVAL);
-+#endif
-+ ac97_write(AC97_TS_REG1, TS_REG1_DEFVAL);
-+ ac97_bit_set(AC97_ADITFUNC1, (1<<1));
-+
-+ /* GPIO3/PENDOWN wakeup */
-+ ac97_bit_set(AC97_GPIO_WAKE_UP, CODEC_PENDOWN);
-+
-+ ts_clear();
-+
-+ /* Init queue */
-+ //X kernel_thread(ts_pendown, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
-+
-+ /* Interrupt setting */
-+ set_GPIO_mode(GPIO32_SDATA_IN1_AC97_MD);
-+ set_GPIO_IRQ_edge(GPIO_TP_INT, GPIO_RISING_EDGE);
-+ GEDR(GPIO_TP_INT) = GPIO_bit(GPIO_TP_INT);
-+ if( request_irq(IRQ_GPIO_TP_INT, ts_interrupt, SA_INTERRUPT, "ts", NULL) ) {
-+ DEBUG(DBG_L1, "IRQ error %d\n", IRQ_GPIO_TP_INT);
-+ return -EBUSY;
-+ }
-+
-+ // printk(KERN_INFO "Tosa Touch Screen driver initialized\n");
-+
-+ return 0;
-+}
-+
-+static int __init ac97_ts_init(void)
-+{
-+ ac97_on = 0;
-+
-+ raw_max_x = 1024;
-+ raw_max_y = 1024;
-+ raw_min_x = 0;
-+ raw_min_y = 0;
-+ res_x = 480;
-+ res_y = 640;
-+ cal_ok = 0;
-+ x_rev = 0;
-+ y_rev = 0;
-+ xyswap = 0;
-+
-+ ts_clear();
-+
-+ if( register_chrdev(TS_MAJOR,DEV_NAME, &ts_fops) ) {
-+ printk("unable to get major %d for touch screen\n", TS_MAJOR);
-+ ts_exit();
-+ }
-+
-+ init_procinfo();
-+
-+ kernel_thread(ts_pendown, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
-+
-+ return 0;
-+}
-+
-+module_init(ac97_ts_init);
-+
-+/*
-+ * Driver functions
-+ */
-+static int ts_open(struct inode *inode, struct file *file)
-+{
-+ if( ts_init() < 0 ) {
-+ ts_exit();
-+ return -EINVAL;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+ return 0;
-+}
-+
-+
-+static int ts_release(struct inode *inode, struct file *file)
-+{
-+ ts_exit();
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static int ts_fasync(int fd, struct file *filp, int on)
-+{
-+ int retval;
-+
-+ retval = fasync_helper(fd, filp, on, &fasync);
-+ if( retval < 0 ) return retval;
-+ return 0;
-+}
-+
-+static ssize_t ts_read(struct file *file, char *buffer,
-+ size_t count, loff_t *ppos)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ TS_EVENT t, r;
-+ int i;
-+
-+ if( head == tail ) {
-+ if( file->f_flags & O_NONBLOCK )
-+ return -EAGAIN;
-+ add_wait_queue(&queue, &wait);
-+ current->state = TASK_INTERRUPTIBLE;
-+ while( (head == tail)&& !signal_pending(current) ) {
-+ schedule();
-+ current->state = TASK_INTERRUPTIBLE;
-+ }
-+ current->state = TASK_RUNNING;
-+ remove_wait_queue(&queue, &wait);
-+ }
-+
-+ for(i = count ; i >= sizeof(TS_EVENT);
-+ i -= sizeof(TS_EVENT), buffer += sizeof(TS_EVENT)) {
-+ if( head == tail ) break;
-+ t = get_data();
-+ if( xyswap ) {
-+ short tmp = t.x;
-+ t.x = t.y;
-+ t.y = tmp;
-+ }
-+ if( cal_ok ) {
-+ r.x = (x_rev) ?
-+ ((raw_max_x - t.x) * res_x) / (raw_max_x - raw_min_x) :
-+ ((t.x - raw_min_x) * res_x) / (raw_max_x - raw_min_x);
-+ r.y = (y_rev) ?
-+ ((raw_max_y - t.y) * res_y) / (raw_max_y - raw_min_y) :
-+ ((t.y - raw_min_y) * res_y) / (raw_max_y - raw_min_y);
-+ } else {
-+ r.x = t.x;
-+ r.y = t.y;
-+ }
-+
-+ r.pressure = t.pressure;
-+ r.millisecs = t.millisecs;
-+ DEBUG(DBG_L2, "ts_read(x, y, p) = (%d, %d, %d)\n",
-+ (unsigned int)r.x, (unsigned int)r.y, (unsigned int)r.pressure);
-+
-+ copy_to_user(buffer,&r,sizeof(TS_EVENT));
-+ }
-+ return count - i;
-+}
-+
-+static unsigned int ts_poll(struct file *filp, poll_table *wait)
-+{
-+ poll_wait(filp, &queue, wait);
-+ if( head != tail )
-+ return POLLIN | POLLRDNORM;
-+ return 0;
-+}
-+
-+static int ts_ioctl(struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ switch(cmd) {
-+ case 3: raw_max_x = arg; break;
-+ case 4: raw_max_y = arg; break;
-+ case 5: res_x = arg; break;
-+ case 6: res_y = arg; break;
-+ case 10: raw_min_x = arg; break;
-+ case 11: raw_min_y = arg; break;
-+ case 12: xyswap = arg; //New attribute for portrait modes
-+ case 13: cal_ok = arg; //0 = Enable calibration ; 1 = Calibration OK
-+ case 14: ts_clear(); break; //Clear all buffer data
-+ case 15: x_rev = arg; break; //X axis reversed setting
-+ case 16: y_rev = arg; break; //Y axis reversed setting
-+ case 17: print_par(); break;
-+ default: return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_PM
-+void tosa_ts_suspend(void)
-+{
-+ DEBUG(DBG_L1, "in\n");
-+ tp_suspend = 1;
-+ ts_exit();
-+ DEBUG(DBG_L1, "out\n");
-+}
-+
-+void tosa_ts_resume(void)
-+{
-+ DEBUG(DBG_L1, "in\n");
-+ tp_suspend = 0;
-+ ts_init();
-+ DEBUG(DBG_L1, "out\n");
-+}
-+#endif /* CONFIG_PM */
-diff -Nur linux_c860_org/drivers/char/tty_io.c linux/drivers/char/tty_io.c
---- linux_c860_org/drivers/char/tty_io.c 2002-08-29 12:25:52.000000000 +0900
-+++ linux/drivers/char/tty_io.c 2004-06-10 21:09:10.000000000 +0900
-@@ -730,6 +730,7 @@
- ret = -ERESTARTSYS;
- if (signal_pending(current))
- break;
-+ debug_lock_break(551);
- if (current->need_resched)
- schedule();
- }
-diff -Nur linux_c860_org/drivers/ide/ide-cs.c linux/drivers/ide/ide-cs.c
---- linux_c860_org/drivers/ide/ide-cs.c 2002-08-29 12:26:32.000000000 +0900
-+++ linux/drivers/ide/ide-cs.c 2004-06-10 21:09:10.000000000 +0900
-@@ -32,6 +32,7 @@
- Change Log
- 12-Nov-2001 Lineo Japan, Inc.
- 30-Jul-2002 Lineo Japan, Inc. for 2.4.18
-+ 26-Feb-2004 Lineo Solutions, Inc. 2 slot support
-
- ======================================================================*/
-
-@@ -72,7 +73,7 @@
- #endif
-
- #ifdef CONFIG_ARCH_SHARP_SL
--extern int ide_resume_handling;
-+extern int ide_resume_handling[];
- #endif
-
- /*====================================================================*/
-@@ -468,11 +469,11 @@
- mod_timer(&link->release, jiffies + HZ/20);
- break;
- case CS_EVENT_CARD_INSERTION:
--#ifdef CONFIG_ARCH_SHARP_SL
-- ide_resume_handling = 0;
--#endif
- link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
- ide_config(link);
-+#ifdef CONFIG_ARCH_SHARP_SL
-+ ide_resume_handling[sharpsl_pcmcia_irq_to_sock(link->irq.AssignedIRQ)] = 0;
-+#endif
- break;
- case CS_EVENT_PM_SUSPEND:
- link->state |= DEV_SUSPEND;
-diff -Nur linux_c860_org/drivers/ide/ide-disk.c linux/drivers/ide/ide-disk.c
---- linux_c860_org/drivers/ide/ide-disk.c 2002-08-29 12:26:32.000000000 +0900
-+++ linux/drivers/ide/ide-disk.c 2004-06-10 21:09:10.000000000 +0900
-@@ -31,6 +31,7 @@
- * Change Log
- * 12-Nov-2001 Lineo Japan, Inc.
- * 30-Jul-2002 Lineo Japan, Inc. for 2.4.18
-+ * 26-Feb-2004 Lineo Solutions, Inc. 2 slot support
- */
-
- #define IDEDISK_VERSION "1.10"
-@@ -372,7 +373,8 @@
- static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block)
- {
- #if defined(CONFIG_ARCH_SHARP_SL) && defined(CONFIG_PCMCIA)
-- if (!is_pcmcia_card_present(0)) {
-+ ide_hwif_t *hwif = HWIF(drive);
-+ if (!is_pcmcia_card_present(hwif->irq)) {
- ide_end_request(0, HWGROUP(drive));
- return ide_stopped;
- }
-diff -Nur linux_c860_org/drivers/ide/ide-proc.c linux/drivers/ide/ide-proc.c
---- linux_c860_org/drivers/ide/ide-proc.c 2002-08-29 12:26:32.000000000 +0900
-+++ linux/drivers/ide/ide-proc.c 2004-06-10 21:09:10.000000000 +0900
-@@ -57,6 +57,7 @@
- * Change Log
- * 12-Nov-2001 Lineo Japan, Inc.
- * 30-Jul-2002 Lineo Japan, Inc. for 2.4.18
-+ * 26-Feb-2004 Lineo Solutions, Inc. 2 slot support
- *
- */
-
-@@ -456,8 +457,8 @@
- }
-
- #ifdef CONFIG_ARCH_SHARP_SL
--static ide_drive_t *drive_save = NULL;
--static u8 ide_info_buf[SECTOR_WORDS * 4 + 4];
-+static ide_drive_t *drive_save[2] = { NULL, NULL };
-+static u8 ide_info_buf[2][SECTOR_WORDS * 4 + 4];
- #endif
-
- static int proc_ide_read_identify
-@@ -470,8 +471,8 @@
- unsigned short *val = ((unsigned short *)page) + 2;
- char *out = ((char *)val) + (SECTOR_WORDS * 4);
- #ifdef CONFIG_ARCH_SHARP_SL
-- drive_save = drive;
-- memcpy(ide_info_buf, page, SECTOR_WORDS * 4);
-+ drive_save[sharpsl_pcmcia_irq_to_sock(HWIF(drive)->irq)] = drive;
-+ memcpy(ide_info_buf[sharpsl_pcmcia_irq_to_sock(HWIF(drive)->irq)], page, SECTOR_WORDS * 4);
- #endif
- page = out;
- do {
-@@ -487,13 +488,15 @@
-
- #ifdef CONFIG_ARCH_SHARP_SL
-
--int proc_ide_verify_identify()
-+int proc_ide_verify_identify(int sock)
- {
- u8 buf[SECTOR_WORDS * 4 + 4];
-+ int ret;
-
-- if (drive_save == NULL || proc_ide_get_identify(drive_save, buf))
-+ if (drive_save[sock] == NULL || proc_ide_get_identify(drive_save[sock], buf))
- return 0;
-- return memcmp(ide_info_buf, buf, SECTOR_WORDS * 4);
-+ ret = memcmp(ide_info_buf[sock], buf, SECTOR_WORDS * 4);
-+ return ret;
- }
-
- #endif
-@@ -777,7 +780,8 @@
- drive->proc = NULL;
- }
- #ifdef CONFIG_ARCH_SHARP_SL
-- drive_save = NULL;
-+ for (d = 0; d < 2; d++)
-+ drive_save[d] = NULL;
- #endif
- }
-
-diff -Nur linux_c860_org/drivers/ide/ide.c linux/drivers/ide/ide.c
---- linux_c860_org/drivers/ide/ide.c 2002-08-29 12:26:33.000000000 +0900
-+++ linux/drivers/ide/ide.c 2004-06-10 21:09:10.000000000 +0900
-@@ -122,6 +122,7 @@
- * Change Log
- * 12-Nov-2001 Lineo Japan, Inc.
- * 30-Jul-2002 Lineo Japan, Inc. for 2.4.18
-+ * 26-Feb-2004 Lineo Solutions, Inc. 2 slot support
- *
- */
-
-@@ -201,7 +202,7 @@
- ide_hwif_t ide_hwifs[MAX_HWIFS]; /* master data repository */
-
- #if defined(CONFIG_ARCH_SHARP_SL) && defined(CONFIG_PCMCIA)
--extern int ide_resume_handling;
-+extern int ide_resume_handling[];
- #endif
-
- #if (DISK_RECOVERY_TIME > 0)
-@@ -548,7 +549,7 @@
- {
- byte stat = 0;
- #if defined(CONFIG_ARCH_SHARP_SL) && defined(CONFIG_PCMCIA)
-- if (ide_resume_handling == 2)
-+ if (ide_resume_handling[sharpsl_pcmcia_irq_to_sock(HWIF(drive)->irq)] == 2)
- return 0;
- #endif
- if (drive->waiting_for_dma)
-@@ -712,11 +713,11 @@
- byte tmp;
-
- #if defined(CONFIG_ARCH_SHARP_SL) && defined(CONFIG_PCMCIA)
-- if (!is_pcmcia_card_present(0)) {
-+ if (!is_pcmcia_card_present(hwif->irq)) {
- hwgroup->poll_timeout = 0; /* done polling */
- return ide_stopped;
- }
-- if (ide_resume_handling == 2) {
-+ if (ide_resume_handling[sharpsl_pcmcia_irq_to_sock(hwif->irq)] == 2) {
- hwgroup->poll_timeout = 0; /* done polling */
- return ide_stopped;
- }
-@@ -1244,9 +1245,9 @@
- ide_hwif_t *hwif = HWIF(drive);
-
- #if defined(CONFIG_ARCH_SHARP_SL) && defined(CONFIG_PCMCIA)
-- if (!is_pcmcia_card_present(0))
-+ if (!is_pcmcia_card_present(hwif->irq))
- goto kill_rq;
-- if (ide_resume_handling == 2)
-+ if (ide_resume_handling[sharpsl_pcmcia_irq_to_sock(hwif->irq)] == 2)
- goto kill_rq;
- #endif
-
-@@ -1625,7 +1626,7 @@
- if (hwgroup->poll_timeout != 0) {
- startstop = handler(drive);
- #if defined(CONFIG_ARCH_SHARP_SL) && defined(CONFIG_PCMCIA)
-- } else if (!ide_resume_handling &&
-+ } else if (!ide_resume_handling[sharpsl_pcmcia_irq_to_sock(hwif->irq)] &&
- drive_is_ready(drive)) {
- #else
- } else if (drive_is_ready(drive)) {
-diff -Nur linux_c860_org/drivers/ieee1394/csr.c linux/drivers/ieee1394/csr.c
---- linux_c860_org/drivers/ieee1394/csr.c 2002-08-26 14:39:22.000000000 +0900
-+++ linux/drivers/ieee1394/csr.c 2004-06-10 21:09:10.000000000 +0900
-@@ -10,6 +10,7 @@
- */
-
- #include <linux/string.h>
-+#include <linux/sched.h>
-
- #include "ieee1394_types.h"
- #include "hosts.h"
-diff -Nur linux_c860_org/drivers/input/keybdev.c linux/drivers/input/keybdev.c
---- linux_c860_org/drivers/input/keybdev.c 2002-08-26 14:39:30.000000000 +0900
-+++ linux/drivers/input/keybdev.c 2004-06-10 21:09:10.000000000 +0900
-@@ -26,6 +26,9 @@
- * Should you need to contact me, the author, you can do so either by
- * e-mail - mail your message to <vojtech@suse.cz>, or by paper mail:
- * Vojtech Pavlik, Ucitelska 1576, Prague 8, 182 00 Czech Republic
-+ *
-+ * ChangeLog:
-+ * 29-Aug-2003 SHARP Supported USB keybord for Tosa
- */
-
- #include <linux/config.h>
-@@ -107,6 +110,15 @@
- }
- #endif /* CONFIG_MAC_ADBKEYCODES || CONFIG_ADB_KEYBOARD */
-
-+#ifdef CONFIG_ARCH_SHARP_SL
-+ if (keycode > 255 || !keycode)
-+ return -1;
-+
-+ handle_scancode(keycode & 0x7f, down);
-+
-+ return 0;
-+#endif // end CONFIG_ARCH_SHARP_SL
-+
- if (keycode > 255 || !x86_keycodes[keycode])
- return -1;
-
-diff -Nur linux_c860_org/drivers/macintosh/rtc.c linux/drivers/macintosh/rtc.c
---- linux_c860_org/drivers/macintosh/rtc.c 2002-08-26 14:39:13.000000000 +0900
-+++ linux/drivers/macintosh/rtc.c 2004-06-10 21:09:10.000000000 +0900
-@@ -64,6 +64,7 @@
- case RTC_RD_TIME:
- if (ppc_md.get_rtc_time)
- {
-+ memset(&rtc_tm, 0, sizeof(struct rtc_time));
- get_rtc_time(&rtc_tm);
-
- if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time)))
-diff -Nur linux_c860_org/drivers/mtd/maps/sharpsl-flash.c linux/drivers/mtd/maps/sharpsl-flash.c
---- linux_c860_org/drivers/mtd/maps/sharpsl-flash.c 2002-08-26 15:19:16.000000000 +0900
-+++ linux/drivers/mtd/maps/sharpsl-flash.c 2004-06-10 21:09:10.000000000 +0900
-@@ -23,6 +23,7 @@
- * GNU General Public License for more details.
- *
- * ChangeLog:
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- *
- */
-
-@@ -34,7 +35,6 @@
- #include <linux/mtd/map.h>
- #include <linux/mtd/partitions.h>
-
--
- #define WINDOW_ADDR 0x00000000
- #define WINDOW_SIZE 0x01000000
- #define BUS_WIDTH 2
-@@ -122,6 +122,14 @@
- }
- };
-
-+static struct mtd_partition tosa_partitions[1] = {
-+ {
-+ name: "Filesystem",
-+ size: 0x006A0000,
-+ offset: 0x00160000
-+ }
-+};
-+
- #define NB_OF(x) (sizeof(x)/sizeof(x[0]))
-
-
-@@ -133,7 +141,6 @@
-
- printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n", WINDOW_SIZE, WINDOW_ADDR);
- sharpsl_map.map_priv_1 = (unsigned long)ioremap(WINDOW_ADDR, WINDOW_SIZE);
--
- if (!sharpsl_map.map_priv_1) {
- printk("Failed to ioremap\n");
- return -EIO;
-@@ -155,7 +162,10 @@
- #elif CONFIG_ARCH_PXA_CORGI
- parts = corgi_partitions;
- nb_parts = NB_OF(corgi_partitions);
--#endif
-+#elif CONFIG_ARCH_PXA_TOSA
-+ parts = tosa_partitions;
-+ nb_parts = NB_OF(tosa_partitions);
-+#endif /* CONFIG_ARCH_PXA_TOSA */
-
- printk(KERN_NOTICE "Using %s partision definition\n", part_type);
- add_mtd_partitions(mymtd, parts, nb_parts);
-diff -Nur linux_c860_org/drivers/mtd/nand/Config.in linux/drivers/mtd/nand/Config.in
---- linux_c860_org/drivers/mtd/nand/Config.in 2003-01-14 16:51:07.000000000 +0900
-+++ linux/drivers/mtd/nand/Config.in 2004-06-10 21:09:10.000000000 +0900
-@@ -29,10 +29,21 @@
- fi
-
- if [ "$CONFIG_ARCH_PXA_POODLE" = "y" ]; then
-- dep_tristate ' NAND Flash device on Sharp poodle' CONFIG_MTD_NAND_SHARP_SL $CONFIG_MTD_NAND
-+ dep_tristate ' NAND Flash device on Sharp poodle' CONFIG_MTD_NAND_SHARP_SL_POODLE $CONFIG_MTD_NAND
- fi
- if [ "$CONFIG_ARCH_PXA_CORGI" = "y" ]; then
-- dep_tristate ' NAND Flash device on Sharp corgi' CONFIG_MTD_NAND_SHARP_SL $CONFIG_MTD_NAND
-+ dep_tristate ' NAND Flash device on Sharp corgi' CONFIG_MTD_NAND_SHARP_SL_CORGI $CONFIG_MTD_NAND
-+fi
-+
-+if [ "$CONFIG_MTD_NAND_SHARP_SL_POODLE" = "y" -o "$CONFIG_MTD_NAND_SHARP_SL_CORGI" = "y" ]; then
-+ define_tristate CONFIG_MTD_NAND_SHARP_SL y
-+else
-+ if [ "$CONFIG_MTD_NAND_SHARP_SL_POODLE" = "m" -o "$CONFIG_MTD_NAND_SHARP_SL_CORGI" = "m" ]; then
-+ define_tristate CONFIG_MTD_NAND_SHARP_SL m
-+ fi
-+fi
-+if [ "$CONFIG_ARCH_PXA_TOSA" = "y" ]; then
-+ dep_tristate ' NAND Flash device on Sharp tosa' CONFIG_MTD_NAND_SHARP_SL_TC6393 $CONFIG_MTD_NAND
- fi
-
- endmenu
-diff -Nur linux_c860_org/drivers/mtd/nand/Makefile linux/drivers/mtd/nand/Makefile
---- linux_c860_org/drivers/mtd/nand/Makefile 2002-10-09 10:29:15.000000000 +0900
-+++ linux/drivers/mtd/nand/Makefile 2004-06-10 21:09:10.000000000 +0900
-@@ -17,6 +17,7 @@
- obj-$(CONFIG_MTD_NAND_AUTCPU12) += autcpu12.o
- obj-$(CONFIG_MTD_NAND_EDB7312) += edb7312.o
- obj-$(CONFIG_MTD_NAND_SHARP_SL) += sharp_sl.o
-+obj-$(CONFIG_MTD_NAND_SHARP_SL_TC6393) += sharp_sl_tc6393.o
- obj-$(CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS) += sharp_sl_logical.o
-
- include $(TOPDIR)/Rules.make
-diff -Nur linux_c860_org/drivers/mtd/nand/nand.c linux/drivers/mtd/nand/nand.c
---- linux_c860_org/drivers/mtd/nand/nand.c 2003-06-18 16:12:26.000000000 +0900
-+++ linux/drivers/mtd/nand/nand.c 2004-06-10 21:09:10.000000000 +0900
-@@ -102,7 +102,7 @@
- *
- * 09-04-2002 tglx: fixed write_verify (John Hall (john.hall@optionexist.co.uk))
- *
-- * $Id$
-+ * $Id$
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
-@@ -121,7 +121,7 @@
- * add erase-by-force mode
- * 18-Sep-2002 Lineo Japan, Inc. add dev_ready() call after read
- * 17-Sep-2002 Lineo Japan, Inc. add code for post-badblock
-- * 14-Mar-2003 Sharp wait for ready in read_oob()
-+ * 09-Sep-2003 SHARP support TC6393XB controller for Tosa
- */
-
- #include <linux/delay.h>
-@@ -371,6 +371,10 @@
- int eccmode = oobsel ? this->eccmode : NAND_ECC_NONE;
- int *oob_config = oobconfigs[oobsel];
- int ecc_ret = 0;
-+#ifdef CONFIG_MTD_NAND_SHARP_SL_TC6393
-+ unsigned short data_w;
-+ u_char data_b;
-+#endif
-
- START_MEASUREMENT(nand_write_page);
- COUNTER_INC(nand_write_nr_pages);
-@@ -428,10 +432,17 @@
- /* No ecc and software ecc 3/256, write all */
- case NAND_ECC_NONE:
- case NAND_ECC_SOFT:
-+#ifdef CONFIG_MTD_NAND_SHARP_SL_TC6393
-+ for (i = 0; i < mtd->oobblock; i+=2) {
-+ writew ( (this->data_poi[i+1] << 8) | this->data_poi[i] , this->IO_ADDR_W);
-+ }
-+ break;
-+#else
- for (i = 0; i < mtd->oobblock; i++)
- writeb ( this->data_poi[i] , this->IO_ADDR_W);
- break;
--
-+#endif
-+
- /* Hardware ecc 3 byte / 256 data, write first half, get ecc, then second, if 512 byte pagesize */
- case NAND_ECC_HW3_256:
- this->enable_hwecc (NAND_ECC_WRITE); /* enable hardware ecc logic for write */
-@@ -465,8 +476,14 @@
- /* Hardware ecc 6 byte / 512 byte data, write full page */
- case NAND_ECC_HW6_512:
- this->enable_hwecc (NAND_ECC_WRITE); /* enable hardware ecc logic */
-+#ifdef CONFIG_MTD_NAND_SHARP_SL_TC6393
-+ for (i = 0; i < mtd->oobblock; i+=2) {
-+ writew ( (this->data_poi[i+1] << 8) | this->data_poi[i] , this->IO_ADDR_W);
-+ }
-+#else
- for (i = 0; i < mtd->oobblock; i++)
- writeb ( this->data_poi[i] , this->IO_ADDR_W);
-+#endif
- ecc_ret = this->calculate_ecc (NULL, &(ecc_code[0]));
- for (i = 0; i < 6; i++)
- oob_data[oob_config[i]] = ecc_code[i];
-@@ -484,8 +501,15 @@
- }
-
- /* Write out OOB data */
-+#ifdef CONFIG_MTD_NAND_SHARP_SL_TC6393
-+
-+ for (i = 0; i < mtd->oobsize; i+=2) {
-+ writew ( (oob_data[i+1] << 8) | oob_data[i] , this->IO_ADDR_W);
-+ }
-+#else
- for (i = 0; i < mtd->oobsize; i++)
- writeb ( oob_data[i] , this->IO_ADDR_W);
-+#endif
-
- /* Send command to actually program the data */
- this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1);
-@@ -526,23 +550,55 @@
- }
- /* Loop through and verify the data */
- for (i = col; i < last; i++) {
-+#ifdef CONFIG_MTD_NAND_SHARP_SL_TC6393
-+ if((i-col) & 1){
-+ data_b = data_w >> 8;
-+ }else{
-+ data_w = readw (this->IO_ADDR_W);
-+ data_b = data_w & 0xff;
-+
-+ }
-+ if (this->data_poi[i] != data_b) {
-+ printk (KERN_WARNING "%s: Failed write verify, %d at page 0x%08x, col=%d last=%d\n", __func__, i, page, col, last);
-+ ACCUMULATE_ELAPSED_TIME(nand_write_verify);
-+ ACCUMULATE_ELAPSED_TIME(nand_write_page);
-+ return -EIO;
-+ }
-+#else
- if (this->data_poi[i] != readb (this->IO_ADDR_R)) {
- printk (KERN_WARNING "%s: Failed write verify, %d at page 0x%08x, col=%d last=%d\n", __func__, i, page, col, last);
- ACCUMULATE_ELAPSED_TIME(nand_write_verify);
- ACCUMULATE_ELAPSED_TIME(nand_write_page);
- return -EIO;
- }
-+#endif
- }
-
- /* check, if we have a fs-supplied oob-buffer */
- if (oob_buf) {
- for (i = 0; i < mtd->oobsize; i++) {
-+#ifdef CONFIG_MTD_NAND_SHARP_SL_TC6393
-+ if(i & 1){
-+ data_b = data_w >> 8;
-+ }else{
-+ data_w = readw (this->IO_ADDR_W);
-+ data_b = data_w & 0xff;
-+
-+ }
-+ if (oob_data[i] != data_b) {
-+ printk (KERN_WARNING "%s: Failed write verify, oob %d of page 0x%08x\n", __func__, i, page);
-+ ACCUMULATE_ELAPSED_TIME(nand_write_verify);
-+ ACCUMULATE_ELAPSED_TIME(nand_write_page);
-+ return -EIO;
-+ }
-+#else
- if (oob_data[i] != readb (this->IO_ADDR_R)) {
- printk (KERN_WARNING "%s: Failed write verify, oob %d of page 0x%08x\n", __func__, i, page);
- ACCUMULATE_ELAPSED_TIME(nand_write_verify);
- ACCUMULATE_ELAPSED_TIME(nand_write_page);
- return -EIO;
- }
-+#endif
- }
- } else {
- if (eccmode != NAND_ECC_NONE && !col && last == mtd->oobblock) {
-@@ -555,8 +611,19 @@
- case NAND_ECC_HW6_512: ecc_bytes = 6; break;
- }
-
-+#ifdef CONFIG_MTD_NAND_SHARP_SL_TC6393
-+ for (i = 0; i < mtd->oobsize; i++) {
-+ if(i & 1){
-+ oob_data[i] = data_w >> 8;
-+ }else{
-+ data_w = readw (this->IO_ADDR_R);
-+ oob_data[i] = data_w;
-+ }
-+ }
-+#else
- for (i = 0; i < mtd->oobsize; i++)
- oob_data[i] = readb (this->IO_ADDR_R);
-+#endif
-
- for (i = 0; i < ecc_bytes; i++) {
- if (oob_data[oob_config[i]] != ecc_code[i]) {
-@@ -826,7 +893,17 @@
- * oob data, let the device transfer the data !
- */
- for (i = 0; i < tmp_len; i++) {
-+#ifdef CONFIG_MTD_NAND_SHARP_SL_TC6393
-+ unsigned short data;
-+ if(i & 1){
-+ buf[i] = data >> 8;
-+ }else{
-+ data = readw (this->IO_ADDR_R);
-+ buf[i] = data;
-+ }
-+#else
- buf[i] = readb (this->IO_ADDR_R);
-+#endif
- if ((col++ & (mtd->oobsize - 1)) == (mtd->oobsize - 1))
- udelay (this->chip_delay);
- }
-@@ -972,6 +1049,10 @@
- {
- int i, column, page, status, ret = 0;
- struct nand_chip *this = mtd->priv;
-+#ifdef CONFIG_MTD_NAND_SHARP_SL_TC6393
-+ unsigned short tmp_buf[32]; // mtd->oobsize
-+ u_char *p_tmp_buf;
-+#endif
-
- DEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);
-
-@@ -1010,6 +1091,17 @@
-
- /* Write out desired data */
- this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page);
-+
-+#ifdef CONFIG_MTD_NAND_SHARP_SL_TC6393
-+ memset(tmp_buf,0xff,mtd->oobsize);
-+ p_tmp_buf = (u_char *)tmp_buf;
-+
-+ for (i = 0; i < len; i++)
-+ p_tmp_buf[i+column] = buf[i];
-+
-+ for (i = 0; i < mtd->oobsize; i++)
-+ writew (tmp_buf[i], this->IO_ADDR_W);
-+#else
- /* prepad 0xff for partial programming */
- for (i = 0; i < column; i++)
- writeb (0xff, this->IO_ADDR_W);
-@@ -1019,7 +1111,7 @@
- /* postpad 0xff for partial programming */
- for (i = len + column; i < mtd->oobsize; i++)
- writeb (0xff, this->IO_ADDR_W);
--
-+#endif
- /* Send command to program the OOB data */
- this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1);
-
-@@ -1040,11 +1132,29 @@
-
- /* Loop through and verify the data */
- for (i = 0; i < len; i++) {
-+#ifdef CONFIG_MTD_NAND_SHARP_SL_TC6393
-+ unsigned short data;
-+ if(i & 1){
-+ if (buf[i] != (data >> 8)){
-+ DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
-+ ret = -EIO;
-+ goto out;
-+ }
-+ }else{
-+ data = readw (this->IO_ADDR_R);
-+ if (buf[i] != (data & 0xff)){
-+ DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
-+ ret = -EIO;
-+ goto out;
-+ }
-+ }
-+#else
- if (buf[i] != readb (this->IO_ADDR_R)) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
- ret = -EIO;
- goto out;
- }
-+#endif
- }
- #endif
-
-@@ -1256,6 +1366,7 @@
- /* Check the WP bit */
- this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1);
- if (!(readb (this->IO_ADDR_R) & 0x80)) {
-+
- DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Device is write protected!!!\n");
- instr->state = MTD_ERASE_FAILED;
- goto erase_exit;
-@@ -1437,8 +1548,14 @@
- this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);
-
- /* Read manufacturer and device IDs */
-+#ifdef CONFIG_MTD_NAND_SHARP_SL_TC6393
-+ nand_maf_id = readw (this->IO_ADDR_R);
-+ nand_dev_id = nand_maf_id >> 8;
-+ nand_maf_id = nand_maf_id & 0xff;
-+#else
- nand_maf_id = readb (this->IO_ADDR_R);
- nand_dev_id = readb (this->IO_ADDR_R);
-+#endif
-
- /* Print and store flash device information */
- for (i = 0; nand_flash_ids[i].name != NULL; i++) {
-@@ -1473,7 +1590,9 @@
- this->eccsize = 256; /* set default eccsize */
-
- switch (this->eccmode) {
--
-+#ifdef CONFIG_ARCH_SHARP_SL
-+ case NAND_ECC_HW6_512:
-+#endif
- case NAND_ECC_HW3_512:
- if (mtd->oobblock == 256) {
- printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC \n");
-diff -Nur linux_c860_org/drivers/mtd/nand/sharp_sl_tc6393.c linux/drivers/mtd/nand/sharp_sl_tc6393.c
---- linux_c860_org/drivers/mtd/nand/sharp_sl_tc6393.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/mtd/nand/sharp_sl_tc6393.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,1236 @@
-+/*
-+ * drivers/mtd/nand/sharp_sl_tc6393.c
-+ *
-+ * Copyright (C) 2004 SHARP
-+ *
-+ * $Id$
-+ *
-+ * Based on:
-+ *
-+ * drivers/mtd/nand/sharp_sl.c
-+ *
-+ * Copyright (C) 2002 Lineo Japan, Inc.
-+ *
-+ * drivers/mtd/nand/spia.c
-+ *
-+ * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
-+ *
-+ *
-+ * 10-29-2001 TG change to support hardwarespecific access
-+ * to controllines (due to change in nand.c)
-+ * page_cache added
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Overview:
-+ * This is a device driver for the NAND flash device found on the
-+ * SPIA board which utilizes the Toshiba TC58V64AFT part. This is
-+ * a 64Mibit (8MiB x 8 bits) NAND flash device.
-+ *
-+ * ChangLog:
-+ * 09-Sep-2003 SHARP support the Toshiba TC6393XB NAND flash controller.
-+ */
-+
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/mtd/nand.h>
-+#include <linux/mtd/nand_ecc.h>
-+#include <linux/mtd/partitions.h>
-+#include <asm/io.h>
-+#include <asm/hardware.h>
-+#ifdef CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS
-+#include <asm-arm/sharp_nand_logical.h>
-+#endif
-+
-+#undef DEBUG_PROC
-+#ifdef DEBUG_PROC
-+#include <linux/proc_fs.h>
-+#endif
-+#include "measure.h"
-+#include <asm/sharp_tc6393.h>
-+
-+#define MAX_ECC_RETRY 3
-+#define MAX_WRITE_RETRIES 32
-+#define MAX_COPIES 100
-+
-+#ifdef CONFIG_ARCH_SHARP_SL
-+#define FAILURECOUNTER_POS NAND_POSTBADBLOCK_POS
-+#else
-+#define FAILURECOUNTER_POS NAND_BADBLOCK_POS
-+#endif
-+
-+#define HWECC_MODE_DISABLE 0
-+#define HWECC_MODE_READ 1
-+#define HWECC_MODE_WRITE 2
-+static int hwecc_mode = HWECC_MODE_DISABLE;
-+
-+static TC6393XB_SysConfig *sysconfig = TC6393XB_SYSCONFIG_BASE;
-+static TC6393XB_NandConfig *nandconfig = TC6393XB_NANDCONFIG_BASE;
-+static TC6393XB_NandCtrl *nandctrl = TC6393XB_NANDCTRL_BASE;
-+
-+/*
-+ * NAND low-level MTD interface functions
-+ */
-+static int tc6393_nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t * retlen, u_char * buf);
-+static int tc6393_nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
-+ size_t * retlen, u_char * buf, u_char * eccbuf, int oobsel);
-+static int tc6393_nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char * buf);
-+static int tc6393_nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
-+ size_t * retlen, const u_char * buf, u_char * eccbuf, int oobsel);
-+static int tc6393_nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t * retlen, const u_char *buf);
-+static int tc6393_nand_writev (struct mtd_info *mtd, const struct iovec *vecs,
-+ unsigned long count, loff_t to, size_t * retlen);
-+static int tc6393_nand_writev_ecc (struct mtd_info *mtd, const struct iovec *vecs,
-+ unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, int oobsel);
-+/*
-+ * MTD structure for Poodle
-+ */
-+static struct mtd_info *sharp_sl_mtd = NULL;
-+
-+/*
-+ * original nand_* functions pointer
-+ */
-+static int (*orig_read_ecc)(struct mtd_info*, loff_t, size_t, size_t*, u_char*, u_char*, int);
-+static int (*orig_write_ecc)(struct mtd_info*, loff_t, size_t, size_t*, const u_char*, u_char*, int);
-+static int (*orig_writev_ecc)(struct mtd_info*, const struct iovec*, unsigned long, loff_t, size_t*, u_char*, int);
-+static int (*orig_write_oob)(struct mtd_info*, loff_t, size_t, size_t*, const u_char*);
-+
-+
-+/*
-+ * out of band configuration for different filesystems
-+ */
-+static int oobconfigs[][6] = {
-+ { 0,0,0,0,0,0},
-+
-+ { NAND_JFFS2_OOB_ECCPOS0, NAND_JFFS2_OOB_ECCPOS1, NAND_JFFS2_OOB_ECCPOS2,
-+ NAND_JFFS2_OOB_ECCPOS3, NAND_JFFS2_OOB_ECCPOS4, NAND_JFFS2_OOB_ECCPOS5 },
-+
-+ { NAND_YAFFS_OOB_ECCPOS0, NAND_YAFFS_OOB_ECCPOS1, NAND_YAFFS_OOB_ECCPOS2,
-+ NAND_YAFFS_OOB_ECCPOS3, NAND_YAFFS_OOB_ECCPOS4, NAND_YAFFS_OOB_ECCPOS5 }
-+};
-+
-+/*
-+ * Macros for low-level register control
-+ */
-+#define nand_select() this->hwcontrol(NAND_CTL_SETNCE);
-+
-+#define nand_deselect() this->hwcontrol(NAND_CTL_CLRNCE);
-+
-+
-+/*
-+ * Define partitions for flash device
-+ */
-+#define DEFAULT_NUM_PARTITIONS 3
-+static struct mtd_info** sharp_sl_nand_part_mtdp;
-+static int nr_partitions;
-+static struct mtd_partition sharp_sl_nand_default_partition_info[] = {
-+ {
-+ .name = "NAND flash partition 0",
-+ .offset = 0,
-+ .size = 7 * 1024 * 1024,
-+ },
-+ {
-+ .name = "NAND flash partition 1",
-+ .offset = 7 * 1024 * 1024,
-+ .size = 30 * 1024 * 1024,
-+ },
-+ {
-+ .name = "NAND flash partition 2",
-+ .offset = 37 * 1024 * 1024,
-+ .size = (64 - 37) * 1024 * 1024,
-+ },
-+};
-+static struct mtd_partition* sharp_sl_nand_partition_info;
-+
-+
-+/*
-+ * hardware specific access to control-lines
-+ */
-+static void
-+tc6393_nand_hwcontrol(int cmd)
-+{
-+ switch (cmd) {
-+ case NAND_CTL_SETCLE:
-+ nandctrl->smode |= SMODE_CLE;
-+ break;
-+ case NAND_CTL_CLRCLE:
-+ nandctrl->smode &= ~SMODE_CLE;
-+ break;
-+ case NAND_CTL_SETALE:
-+ nandctrl->smode |= SMODE_ALE;
-+ break;
-+ case NAND_CTL_CLRALE:
-+ nandctrl->smode &= ~SMODE_ALE;
-+ break;
-+ case NAND_CTL_SETNCE:
-+ nandctrl->smode = SMODE_SELECT;
-+ break;
-+ case NAND_CTL_CLRNCE:
-+ nandctrl->smode = SMODE_DESELECT;
-+ default:
-+ break;
-+ }
-+}
-+
-+
-+/*
-+ *
-+ */
-+static int
-+tc6393_nand_command_1(struct mtd_info* mtd,
-+ unsigned command,
-+ int column,
-+ int page_addr)
-+{
-+ register struct nand_chip *this = mtd->priv;
-+ register unsigned long NAND_IO_ADDR = this->IO_ADDR_W;
-+ int i;
-+
-+#ifdef CONFIG_ARCH_SHARP_SL
-+ if (command != NAND_CMD_RESET &&
-+ command != NAND_CMD_STATUS) {
-+ for (i = 0; i < NAND_BUSY_TIMEOUT; i++)
-+ if (this->dev_ready())
-+ break;
-+ if (i == NAND_BUSY_TIMEOUT)
-+ return -EIO;
-+ }
-+#endif
-+ this->hwcontrol (NAND_CTL_SETCLE);
-+
-+ /*
-+ * Write out the command to the device.
-+ */
-+ if (command != NAND_CMD_SEQIN)
-+ writeb (command, NAND_IO_ADDR);
-+ else {
-+ if (mtd->oobblock == 256 && column >= 256) {
-+ column -= 256;
-+ writeb (NAND_CMD_READOOB, NAND_IO_ADDR);
-+ writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
-+ } else if (mtd->oobblock == 512 && column >= 256) {
-+ if (column < 512) {
-+ column -= 256;
-+ writeb (NAND_CMD_READ1, NAND_IO_ADDR);
-+ writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
-+ } else {
-+ column -= 512;
-+ writeb (NAND_CMD_READOOB, NAND_IO_ADDR);
-+ writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
-+ }
-+ } else {
-+ writeb (NAND_CMD_READ0, NAND_IO_ADDR);
-+ writeb (NAND_CMD_SEQIN, NAND_IO_ADDR);
-+ }
-+ }
-+
-+ /* Set ALE and clear CLE to start address cycle */
-+ this->hwcontrol (NAND_CTL_CLRCLE);
-+
-+ if (column != -1 || page_addr != -1) {
-+ this->hwcontrol (NAND_CTL_SETALE);
-+
-+ /* Serially input address */
-+ if (column != -1)
-+ writeb (column, NAND_IO_ADDR);
-+ if (page_addr != -1) {
-+ writeb ((unsigned char) (page_addr & 0xff), NAND_IO_ADDR);
-+ writeb ((unsigned char) ((page_addr >> 8) & 0xff), NAND_IO_ADDR);
-+ /* One more address cycle for higher density devices */
-+ if (mtd->size & 0x0c000000)
-+ writeb ((unsigned char) ((page_addr >> 16) & 0x0f), NAND_IO_ADDR);
-+ }
-+ /* Latch in address */
-+ this->hwcontrol (NAND_CTL_CLRALE);
-+ }
-+
-+ /*
-+ * program and erase have their own busy handlers
-+ * status and sequential in needs no delay
-+ */
-+ switch (command) {
-+ case NAND_CMD_PAGEPROG: /* wait in this->waitfunc() */
-+ case NAND_CMD_ERASE1:
-+ case NAND_CMD_ERASE2: /* wait in this->waitfunc() */
-+ case NAND_CMD_SEQIN:
-+/* case NAND_CMD_STATUS: */
-+ return 0;
-+
-+ case NAND_CMD_RESET:
-+ break;
-+ }
-+
-+ /* wait until command is processed */
-+ for (i = 0; i < NAND_BUSY_TIMEOUT; i++)
-+ if (this->dev_ready())
-+ return 0;
-+ return -EIO;
-+}
-+
-+
-+/*
-+ *
-+ */
-+static int
-+tc6393_nand_command(struct mtd_info* mtd,
-+ unsigned command,
-+ int column,
-+ int page_addr)
-+{
-+ if (command == NAND_CMD_SEQIN)
-+ /* ignore Ready/Busy error */
-+ tc6393_nand_command_1(mtd, NAND_CMD_READ0, column, page_addr);
-+ return tc6393_nand_command_1(mtd, command, column, page_addr);
-+}
-+
-+
-+/*
-+ * Get chip for selected access
-+ * (copy from nand.c)
-+ */
-+static inline void
-+nand_get_chip(struct nand_chip *this,
-+ struct mtd_info *mtd,
-+ int new_state)
-+{
-+
-+ DECLARE_WAITQUEUE (wait, current);
-+
-+ /*
-+ * Grab the lock and see if the device is available
-+ * For erasing, we keep the spinlock until the
-+ * erase command is written.
-+ */
-+ retry:
-+ spin_lock_bh (&this->chip_lock);
-+
-+ if (this->state == FL_READY) {
-+ this->state = new_state;
-+ if (new_state != FL_ERASING)
-+ spin_unlock_bh (&this->chip_lock);
-+ return;
-+ }
-+
-+#if 0
-+ if (this->state == FL_ERASING) {
-+ if (new_state != FL_ERASING) {
-+ this->state = new_state;
-+ spin_unlock_bh (&this->chip_lock);
-+ nand_select (); /* select in any case */
-+ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
-+ return;
-+ }
-+ }
-+#endif
-+
-+ set_current_state (TASK_UNINTERRUPTIBLE);
-+ add_wait_queue (&this->wq, &wait);
-+ spin_unlock_bh (&this->chip_lock);
-+ schedule ();
-+ remove_wait_queue (&this->wq, &wait);
-+ goto retry;
-+}
-+
-+
-+static inline void
-+tc6393_nand_read_page(struct mtd_info* mtd,
-+ struct nand_chip* this,
-+ u_char* data_poi,
-+ u_char* oob_data,
-+ u_char* ecc_calc,
-+ int ecc,
-+ int end)
-+{
-+ int j = 0;
-+
-+ START_MEASUREMENT(nand_read_page);
-+
-+ this->enable_hwecc (NAND_ECC_READ);
-+
-+ while (j < ecc){
-+ unsigned short data = readw (this->IO_ADDR_R);
-+ data_poi[j++] = data;
-+ data_poi[j++] = data >> 8;
-+ }
-+
-+ this->calculate_ecc (&data_poi[0], &ecc_calc[0]); /* read from hardware */
-+
-+ for (j = 0; j < mtd->oobsize; j+=2) {
-+ unsigned short data = readw (this->IO_ADDR_R);
-+ oob_data[j] = data;
-+ oob_data[j+1] = data >> 8;
-+ }
-+ ACCUMULATE_ELAPSED_TIME(nand_read_page);
-+ COUNTER_INC(nand_read_nr_pages);
-+}
-+
-+
-+/*
-+ * this function is registered only if eccmode == NAND_ECC_HW6_512 &&
-+ * oobblock == 512
-+ */
-+static int
-+tc6393_nand_read_ecc(struct mtd_info* mtd,
-+ loff_t from,
-+ size_t len,
-+ size_t* retlen,
-+ u_char* buf,
-+ u_char* oob_buf,
-+ int oobsel)
-+{
-+ int col, page, end, ecc;
-+ int read, ecc_failed, ret;
-+ struct nand_chip *this;
-+ u_char *oob_data;
-+ int *oob_config;
-+ u_char* data_poi = 0;
-+
-+ if (oob_buf || ! oobsel)
-+ return orig_read_ecc(mtd, from, len, retlen, buf, oob_buf, oobsel);
-+
-+ DEBUG (MTD_DEBUG_LEVEL3, "%s: from = 0x%08x, len = %i\n",
-+ __func__, (unsigned int) from, (int) len);
-+
-+ /* Do not allow reads past end of device */
-+ if ((from + len) > mtd->size) {
-+ DEBUG (MTD_DEBUG_LEVEL0, "%s: Attempt read beyond end of device\n", __func__);
-+ *retlen = 0;
-+ return -EINVAL;
-+ }
-+
-+ /* Grab the lock and see if the device is available */
-+ this = mtd->priv;
-+ nand_get_chip (this, mtd ,FL_READING);
-+
-+ /* Select the NAND device */
-+ nand_select ();
-+
-+ oob_config = oobconfigs[oobsel];
-+ page = from >> this->page_shift;
-+ col = from & (mtd->oobblock - 1);
-+ end = mtd->oobblock;
-+ ecc = mtd->eccsize;
-+ oob_data = &this->data_buf[end];
-+ read = 0;
-+ ecc_failed = 0;
-+ ret = 0;
-+
-+ /* Send the read command */
-+ if (this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page)) {
-+ printk(KERN_WARNING "%s: Failed in NAND_CMD_READ0 command, page 0x%08x\n",
-+ __func__, page);
-+ ret = -EIO;
-+ goto nand_read_ecc_exit;
-+ }
-+
-+ /* Loop until all data read */
-+ while (read < len) {
-+ int j;
-+ int ecc_status;
-+ int ecc_retry_counter = 0;
-+ u_char ecc_calc[6];
-+ u_char ecc_code[6];
-+
-+ /*
-+ * If the read is not page aligned, we have to read into data buffer
-+ * due to ecc, else we read into return buffer direct
-+ */
-+ if (!col && (len - read) >= end)
-+ data_poi = &buf[read];
-+ else
-+ data_poi = this->data_buf;
-+
-+#ifdef CONFIG_MTD_NAND_PAGE_CACHE
-+ if (page == this->cache_page) {
-+ memcpy(data_poi, this->data_cache, end);
-+
-+ if (this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page + 1)) {
-+ printk(KERN_WARNING "%s: Failed in NAND_CMD_READ0 command,"
-+ " page 0x%08x\n", __func__, page);
-+ ret = -EIO;
-+ goto nand_read_ecc_exit;
-+ }
-+
-+ goto loop_next;
-+ }
-+#endif
-+
-+ ecc_retry:
-+ tc6393_nand_read_page(mtd, this, data_poi, oob_data, ecc_calc, ecc, end);
-+
-+ /* Pick the ECC bytes out of the oob data */
-+ for (j = 0; j < 6; j++)
-+ ecc_code[j] = oob_data[oob_config[j]];
-+
-+ /* If we have consequent page reads, apply delay or wait for ready/busy pin */
-+ for (j = 0; j < NAND_BUSY_TIMEOUT; j++)
-+ if (this->dev_ready())
-+ break;
-+ if (j == NAND_BUSY_TIMEOUT) {
-+ ret = -EIO;
-+ goto nand_read_ecc_exit;
-+ }
-+
-+ /* correct data, if neccecary */
-+ ecc_status = this->correct_data (&data_poi[0], &ecc_code[0], &ecc_calc[0]);
-+ if (ecc_status == -1) {
-+ if (ecc_retry_counter++ < MAX_ECC_RETRY) {
-+ this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1);
-+ if (this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page)) {
-+ printk(KERN_WARNING
-+ "%s: Failed in NAND_CMD_READ0 command, page 0x%08x\n",
-+ __func__, page);
-+ ret = -EIO;
-+ goto nand_read_ecc_exit;
-+ }
-+ goto ecc_retry;
-+ }
-+ else {
-+ printk (KERN_WARNING "%s: Failed ECC read, page 0x%08x\n",
-+ __func__, page);
-+ ecc_failed++;
-+ }
-+ }
-+
-+ ecc_status = this->correct_data (&data_poi[256], &ecc_code[3], &ecc_calc[3]);
-+ if (ecc_status == -1) {
-+ if (ecc_retry_counter++ < MAX_ECC_RETRY) {
-+ this->cmdfunc (mtd, NAND_CMD_RESET, -1, -1);
-+ if (this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page)) {
-+ printk(KERN_WARNING
-+ "%s: Failed in NAND_CMD_READ0 command, page 0x%08x\n",
-+ __func__, page);
-+ ret = -EIO;
-+ goto nand_read_ecc_exit;
-+ }
-+ goto ecc_retry;
-+ }
-+ else {
-+ printk (KERN_WARNING "%s: Failed ECC read, page 0x%08x\n",
-+ __func__, page);
-+ ecc_failed++;
-+ }
-+ }
-+
-+#ifdef CONFIG_MTD_NAND_PAGE_CACHE
-+ loop_next:
-+#endif
-+ if (col || (len - read) < end) {
-+ for (j = col; j < end && read < len; j++)
-+ buf[read++] = data_poi[j];
-+ } else
-+ read += mtd->oobblock;
-+ /* For subsequent reads align to page boundary. */
-+ col = 0;
-+ /* Increment page address */
-+ page++;
-+ }
-+
-+ nand_read_ecc_exit:
-+ ret = (ret == 0) ? (ecc_failed ? -EIO : 0) : ret;
-+ if (ret == -EIO)
-+ this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
-+#ifdef CONFIG_MTD_NAND_PAGE_CACHE
-+ else if (page - 1 != this->cache_page && data_poi) {
-+ memcpy(this->data_cache, data_poi, end);
-+ this->cache_page = page - 1;
-+ }
-+#endif
-+
-+ /* De-select the NAND device */
-+ nand_deselect ();
-+
-+ /* Wake up anyone waiting on the device */
-+ spin_lock_bh (&this->chip_lock);
-+ this->state = FL_READY;
-+ wake_up (&this->wq);
-+ spin_unlock_bh (&this->chip_lock);
-+
-+ /*
-+ * Return success, if no ECC failures, else -EIO
-+ * fs driver will take care of that, because
-+ * retlen == desired len and result == -EIO
-+ */
-+ *retlen = read;
-+ return ret;
-+}
-+
-+
-+static int
-+tc6393_nand_read(struct mtd_info* mtd,
-+ loff_t from,
-+ size_t len,
-+ size_t* retlen,
-+ u_char* buf)
-+{
-+ return tc6393_nand_read_ecc(mtd, from, len, retlen, buf, NULL, NAND_JFFS2_OOB);
-+}
-+
-+
-+/* same as sharp_sl.c */
-+static inline int jffs2_hamming_distance(unsigned int a, unsigned int b)
-+{
-+#ifdef __ARM_ARCH_5TE__
-+ unsigned int n;
-+ a ^= b;
-+ asm (
-+ "clz %0, %1\n"
-+ : "=r" (n)
-+ : "r" (a)
-+ );
-+ return (a << (n + 1)) == 0;
-+#else
-+ unsigned int n;
-+ a ^= b;
-+ for (n = 0; n < 8; n++)
-+ if (! (a & ~(1 << n)))
-+ return 1;
-+ return 0;
-+#endif
-+}
-+
-+/* same as sharp_sl.c */
-+static inline void
-+jffs2_correct_badblock_val(u_char* oob)
-+{
-+#ifdef CONFIG_MTD_NAND_POST_BADBLOCK
-+ if (jffs2_hamming_distance(oob[NAND_POSTBADBLOCK_POS], 0xff))
-+ oob[NAND_POSTBADBLOCK_POS] = 0xff;
-+#endif
-+ if (jffs2_hamming_distance(oob[NAND_BADBLOCK_POS], 0xff))
-+ oob[NAND_BADBLOCK_POS] = 0xff;
-+}
-+
-+/* same as sharp_sl.c */
-+static inline void
-+jffs2_correct_failedblock_val(u_char* oob)
-+{
-+ if (jffs2_hamming_distance(oob[FAILURECOUNTER_POS], 0xff))
-+ oob[FAILURECOUNTER_POS] = 0xff;
-+}
-+
-+/* same as sharp_sl.c */
-+static inline void
-+jffs2_correct_cleanmarker(u_char* oob,
-+ u_char* correct_data,
-+ int len)
-+{
-+ int i;
-+ for (i = 0; i < len; i++)
-+ if (jffs2_hamming_distance(oob[i], correct_data[i]))
-+ oob[i] = correct_data[i];
-+}
-+
-+/* same as sharp_sl.c */
-+static int
-+tc6393_nand_prepare_rewrite(struct mtd_info* mtd,
-+ loff_t to,
-+ int oobsel)
-+{
-+ int i;
-+ loff_t block_addr = to & ~(mtd->erasesize - 1);
-+ size_t len = to & (mtd->erasesize - 1);
-+ int nr_oobpages = 2; // JFFS2 only (JFFS2 uses only 2 oobpages)
-+ int fsdata_pos = (mtd->oobblock == 256)
-+ ? NAND_JFFS2_OOB8_FSDAPOS : NAND_JFFS2_OOB16_FSDAPOS;
-+ int fsdata_len = (mtd->oobblock == 256)
-+ ? NAND_JFFS2_OOB8_FSDALEN : NAND_JFFS2_OOB16_FSDALEN;
-+ u_char* block_buf;
-+ u_char* oob_buf;
-+ int ret;
-+ int retlen;
-+ struct erase_info instr;
-+
-+ block_buf = kmalloc(len, GFP_KERNEL);
-+ if (! block_buf) {
-+ printk("Unable to allocate NAND block buffer (%u)\n", len);
-+ return -EIO;
-+ }
-+ oob_buf = kmalloc(mtd->oobsize * nr_oobpages, GFP_KERNEL);
-+ if (! oob_buf) {
-+ printk("Unable to allocate NAND oob buffer\n");
-+ kfree(block_buf);
-+ return -EIO;
-+ }
-+
-+ ret = mtd->read_ecc(mtd, block_addr, len, &retlen, block_buf, NULL, NAND_JFFS2_OOB);
-+ if (ret || retlen != len) {
-+ DEBUG(MTD_DEBUG_LEVEL0, "%s: read_ecc failed (%d)\n", __func__, ret);
-+ kfree(block_buf);
-+ kfree(oob_buf);
-+ return ret ? ret : -EIO;
-+ }
-+
-+ ret = mtd->read_oob(mtd, block_addr, mtd->oobsize * nr_oobpages, &retlen, oob_buf);
-+ if (ret || retlen != mtd->oobsize * nr_oobpages) {
-+ DEBUG(MTD_DEBUG_LEVEL0, "%s: read_oob failed (%d)\n", __func__, ret);
-+ kfree(block_buf);
-+ kfree(oob_buf);
-+ return ret ? ret : -EIO;
-+ }
-+#if 1 /* FIXME */
-+ {
-+ struct {
-+ /* All start like this */
-+ uint16_t magic;
-+ uint16_t nodetype;
-+ uint32_t totlen; /* So we can skip over nodes we don't grok */
-+ } __attribute__((packed)) n = {
-+ .magic = 0x1985,
-+ .nodetype = 0x2003,
-+ .totlen = 8,
-+ };
-+ u_char* p;
-+
-+ p = (u_char*)&n;
-+
-+ jffs2_correct_badblock_val(oob_buf);
-+ jffs2_correct_failedblock_val(&oob_buf[mtd->oobsize]);
-+ jffs2_correct_cleanmarker(&oob_buf[fsdata_pos], p, fsdata_len);
-+ }
-+#endif
-+
-+ for (i = 0; i < MAX_COPIES; i++) {
-+ int j;
-+
-+ memset(&instr, 0, sizeof instr);
-+ instr.mtd = mtd;
-+ instr.addr = block_addr;
-+ instr.len = mtd->erasesize;
-+ ret = mtd->erase(mtd, &instr);
-+ if (ret) {
-+ DEBUG(MTD_DEBUG_LEVEL0, "%s: erase failed (%d)\n", __func__, ret);
-+ continue;
-+ }
-+
-+ ret = orig_write_ecc(mtd, block_addr, len, &retlen, block_buf, NULL,
-+ NAND_JFFS2_OOB);
-+ if (ret || retlen != len) {
-+ DEBUG(MTD_DEBUG_LEVEL0, "%s: write_ecc failed (%d)\n", __func__, ret);
-+ continue;
-+ }
-+
-+ for (j = 0; j < nr_oobpages; j++) {
-+ loff_t addr = block_addr + mtd->oobblock * j;
-+
-+#ifdef CONFIG_MTD_NAND_POST_BADBLOCK
-+ ret = orig_write_oob(mtd, addr + NAND_POSTBADBLOCK_POS, 1, &retlen,
-+ oob_buf + mtd->oobsize * j + NAND_POSTBADBLOCK_POS);
-+ if (ret || retlen != 1) {
-+ DEBUG(MTD_DEBUG_LEVEL0, "%s: write_oob post_badblock(%d) failed (%d)\n",
-+ __func__, j, ret);
-+ break;
-+ }
-+#endif
-+
-+ ret = orig_write_oob(mtd, addr + NAND_BADBLOCK_POS, 1, &retlen,
-+ oob_buf + mtd->oobsize * j + NAND_BADBLOCK_POS);
-+ if (ret || retlen != 1) {
-+ DEBUG(MTD_DEBUG_LEVEL0, "%s: write_oob badblock(%d) failed (%d)\n",
-+ __func__, j, ret);
-+ break;
-+ }
-+
-+ ret = orig_write_oob(mtd, addr + fsdata_pos, fsdata_len, &retlen,
-+ oob_buf + mtd->oobsize * j + fsdata_pos);
-+ if (ret || retlen != fsdata_len) {
-+ DEBUG(MTD_DEBUG_LEVEL0, "%s: write_oob fsdata(%d) failed (%d)\n",
-+ __func__, j, ret);
-+ break;
-+ }
-+ }
-+ if (j < nr_oobpages)
-+ continue;
-+
-+ break;
-+ }
-+
-+ kfree(block_buf);
-+ kfree(oob_buf);
-+ DEBUG(MTD_DEBUG_LEVEL0,
-+ "%s: %d\n", __func__, (i < MAX_COPIES) ? 0 : (ret ? ret : -EIO));
-+ return (i < MAX_COPIES) ? 0 : (ret ? ret : -EIO);
-+}
-+
-+/* same as sharp_sl.c */
-+static int
-+tc6393_nand_write_ecc(struct mtd_info* mtd,
-+ loff_t to,
-+ size_t len,
-+ size_t* retlen,
-+ const u_char* buf,
-+ u_char* eccbuf,
-+ int oobsel)
-+{
-+ int i;
-+ int ret;
-+
-+ for (i = 0; i < MAX_WRITE_RETRIES; i++) {
-+ ret = orig_write_ecc(mtd, to, len, retlen, buf, eccbuf, oobsel);
-+ if (ret != -EIO){
-+ return ret;
-+ }
-+
-+ ret = tc6393_nand_prepare_rewrite(mtd, to, oobsel);
-+ if (ret)
-+ return ret;
-+ }
-+ return -EIO;
-+}
-+
-+
-+/* same as sharp_sl.c */
-+static int
-+tc6393_nand_write(struct mtd_info* mtd,
-+ loff_t to,
-+ size_t len,
-+ size_t* retlen,
-+ const u_char* buf)
-+{
-+ return tc6393_nand_write_ecc(mtd, to, len, retlen, buf, NULL, NAND_JFFS2_OOB);
-+}
-+
-+/* same as sharp_sl.c */
-+static int
-+tc6393_nand_writev_ecc(struct mtd_info* mtd,
-+ const struct iovec* vecs,
-+ unsigned long count,
-+ loff_t to,
-+ size_t* retlen,
-+ u_char* eccbuf,
-+ int oobsel)
-+{
-+ int i;
-+ int ret;
-+
-+ for (i = 0; i < MAX_WRITE_RETRIES; i++) {
-+ ret = orig_writev_ecc(mtd, vecs, count, to, retlen, eccbuf, oobsel);
-+ if (ret != -EIO)
-+ return ret;
-+
-+ ret = tc6393_nand_prepare_rewrite(mtd, to, oobsel);
-+ if (ret)
-+ return ret;
-+ }
-+ return -EIO;
-+}
-+
-+/* same as sharp_sl.c */
-+static int
-+tc6393_nand_writev(struct mtd_info* mtd,
-+ const struct iovec* vecs,
-+ unsigned long count,
-+ loff_t to,
-+ size_t* retlen)
-+{
-+ return tc6393_nand_writev_ecc(mtd, vecs, count, to, retlen, NULL, NAND_JFFS2_OOB);
-+}
-+
-+
-+/* same as sharp_sl.c */
-+static int
-+tc6393_nand_write_oob(struct mtd_info* mtd,
-+ loff_t to,
-+ size_t len,
-+ size_t* retlen,
-+ const u_char* buf)
-+{
-+ int i;
-+ int ret;
-+
-+ for (i = 0; i < MAX_WRITE_RETRIES; i++) {
-+ ret = orig_write_oob(mtd, to, len, retlen, buf);
-+ if (ret != -EIO)
-+ return ret;
-+
-+ ret = tc6393_nand_prepare_rewrite(mtd, to & ~(mtd->erasesize - 1), // JFFS2 only (JFFS2 calls write_oob only after erasing)
-+ NAND_JFFS2_OOB);
-+ if (ret)
-+ return ret;
-+ }
-+ return -EIO;
-+}
-+
-+
-+/* same as sharp_sl.c */
-+static int
-+tc6393_nand_flash_busy(void)
-+{
-+ return (nandctrl->sustus & SUSTUS_BUSY) == SUSTUS_BUSY;
-+}
-+
-+
-+/*
-+ *
-+ */
-+/* same as sharp_sl.c */
-+static int
-+tc6393_nand_dev_ready(void)
-+{
-+ int i;
-+ for (i = 0; i < 5; i++)
-+ tc6393_nand_flash_busy();
-+ return ! tc6393_nand_flash_busy();
-+}
-+
-+
-+/*
-+ *
-+ */
-+/* same as sharp_sl.c */
-+static int
-+tc6393_nand_suspend(struct mtd_info* mtd)
-+{
-+ int i;
-+ printk("%s", __func__);
-+ for (i = 0; i < nr_partitions; i++) {
-+ invalidate_device(MKDEV(MTD_BLOCK_MAJOR, sharp_sl_nand_part_mtdp[i]->index), 1);
-+ }
-+ mtd->sync(mtd);
-+
-+ printk("\n");
-+ return 0;
-+}
-+
-+/*
-+ *
-+ */
-+/* same as sharp_sl.c */
-+static void
-+tc6393_nand_resume(struct mtd_info* mtd)
-+{
-+ printk("%s\n", __func__);
-+ tc6393_nand_hw_init();
-+}
-+
-+
-+#ifdef CONFIG_MTD_NAND_ECC
-+/*
-+ *
-+ */
-+static void
-+tc6393_nand_enable_hwecc(int mode)
-+{
-+ volatile unsigned char dummy_read;
-+
-+ if(mode == NAND_ECC_WRITE){
-+ /* Hard_ECC Reset_Mode(Read) */
-+ nandctrl->smode = SMODE_HWECC_WRITE_RESET_ECC;
-+ /* Read dummy data (1byte) */
-+ dummy_read = nandctrl->sdata.data8.sdata0;
-+ /* Hard_ECC CALC_Mode(Read) */
-+ nandctrl->smode = SMODE_HWECC_WRITE_ECCCALC;
-+
-+ hwecc_mode = HWECC_MODE_WRITE;
-+ return;
-+ }else{
-+ /* Hard_ECC Reset_Mode(Write) */
-+ nandctrl->smode = SMODE_HWECC_READ_RESET_ECC;
-+ /* Read dummy data (1byte) */
-+ dummy_read = nandctrl->sdata.data8.sdata0;
-+ /* Hard_ECC CALC_Mode(Read) */
-+ nandctrl->smode = SMODE_HWECC_READ_ECCCALC;
-+
-+ hwecc_mode = HWECC_MODE_READ;
-+ return;
-+ }
-+}
-+
-+
-+/*
-+ *
-+ */
-+static int
-+tc6393_nand_calculate_ecc(const u_char* dat,
-+ u_char* ecc_code)
-+{
-+ unsigned short ecc1,ecc2,ecc3;
-+
-+ if(hwecc_mode == HWECC_MODE_READ){
-+ nandctrl->smode = SMODE_HWECC_READ_CALC_RESULT;
-+ }else if(hwecc_mode == HWECC_MODE_WRITE){
-+ nandctrl->smode = SMODE_HWECC_WRITE_CALC_RESULT;
-+ }else{
-+ printk("Unable to calcutate NAND ecc.");
-+ return -EIO;
-+ }
-+
-+ ecc1 = nandctrl->sdata.data16.sdata0_1;
-+ ecc2 = nandctrl->sdata.data16.sdata0_1;
-+ ecc3 = nandctrl->sdata.data16.sdata0_1;
-+
-+ ecc_code[0] = ecc1 >> 8; // 000-255 LP15-8
-+ ecc_code[1] = ecc1 >> 0; // 000-255 LP7-0
-+ ecc_code[2] = ecc2 >> 0; // 000-255 CP5-0,11b
-+ ecc_code[3] = ecc3 >> 0; // 256-511 LP15-8
-+ ecc_code[4] = ecc2 >> 8; // 256-511 LP7-0
-+ ecc_code[5] = ecc3 >> 8; // 256-511 CP5-0,11b
-+
-+ if(hwecc_mode == HWECC_MODE_READ){
-+ nandctrl->smode = SMODE_READ_DATAREAD;
-+ }else{
-+ nandctrl->smode = SMODE_WRITE_DATAWRITE;
-+ }
-+
-+ hwecc_mode = HWECC_MODE_DISABLE;
-+ return 0;
-+}
-+#endif
-+
-+
-+static void tc6393_nand_hw_init(void)
-+{
-+ /* (89h) SMD Buffer ON By TC6393XB SystemConfig */
-+ sysconfig->gpibfc1 = 0xff;
-+
-+ /* (4Ch) CLKRUN Enable 1st */
-+ nandconfig->spcrunc = 0x81;
-+
-+ /* (10h)BaseAddress 0x1000 */
-+ nandconfig->spba.spba2 = TC6393XB_NANDCTRL_OFFSET;
-+
-+ /* (04h)Command Register I/O */
-+ nandconfig->spcmd = 0x02;
-+
-+ /* (62h) Power Supply Control */
-+ /* HardPowerOFF - SuspendOFF - PowerSupplyWait_4MS */
-+ nandconfig->ssmpwc = 0x02;
-+
-+ /* (63h) Detect Control */
-+ nandconfig->ssmdtc = 0x02;
-+
-+ /* Interrupt status register clear */
-+ nandctrl->sintst = 0x0f;
-+
-+ /* After power supply, Media are reset */
-+ nandctrl->smode = SMODE_POWER_ON;
-+ nandctrl->smode = SMODE_READ_COMMAND;
-+ nandctrl->sdata.data8.sdata0 = NAND_CMD_RESET;
-+
-+ /* Stanby Mode */
-+ nandctrl->smode = SMODE_STANDBY;
-+
-+ mdelay(100);
-+
-+ return;
-+}
-+
-+/* same as sharp_sl.c */
-+#ifdef DEBUG_PROC
-+DEFINE_MEASUREMENT_VAR(nand_read_page);
-+DEFINE_COUNTER_VAR(nand_read_nr_pages);
-+DEFINE_MEASUREMENT_VAR(nand_write_page);
-+DEFINE_MEASUREMENT_VAR(nand_write_verify);
-+DEFINE_COUNTER_VAR(nand_write_nr_pages);
-+static int
-+sharp_sl_nand_read_proc(char* buf,
-+ char** start,
-+ off_t offset,
-+ int count,
-+ int* eof,
-+ void* data)
-+{
-+ int len = 0;
-+ PRINT_ELAPSED_TIME(nand_read_page, buf, len);
-+ len += sprintf(buf + len, "nand_read_nr_pages %d\n", nand_read_nr_pages);
-+ PRINT_ELAPSED_TIME(nand_write_page, buf, len);
-+ PRINT_ELAPSED_TIME(nand_write_verify, buf, len);
-+ len += sprintf(buf + len, "nand_write_nr_pages %d\n", nand_write_nr_pages);
-+ *eof = 1;
-+ return len;
-+}
-+
-+
-+static int sharp_sl_nand_write_proc(struct file* file,
-+ const char* buffer,
-+ unsigned long count,
-+ void* data)
-+{
-+ CLEAR_TIME_VER(nand_read_page);
-+ CLEAR_TIME_VER(nand_write_page);
-+ CLEAR_TIME_VER(nand_write_verify);
-+ nand_read_nr_pages = 0;
-+ nand_write_nr_pages = 0;
-+ return count;
-+}
-+#endif
-+
-+
-+/*
-+ * Main initialization routine
-+ */
-+int __init
-+tc6393_nand_init (void)
-+{
-+ extern int parse_cmdline_partitions(struct mtd_info *, struct mtd_partition **,
-+ const char *);
-+ struct nand_chip *this;
-+ int i;
-+
-+ //printk("**** %s:\n",__func__);
-+
-+ /* Allocate memory for MTD device structure and private data */
-+ sharp_sl_mtd = kmalloc (sizeof(struct mtd_info) + sizeof (struct nand_chip),
-+ GFP_KERNEL);
-+ if (!sharp_sl_mtd) {
-+ printk ("Unable to allocate Poodle NAND MTD device structure.\n");
-+ return -ENOMEM;
-+ }
-+
-+ /* Initialize NAND flash controller on TC6393XB */
-+ tc6393_nand_hw_init();
-+
-+ /* Get pointer to private data */
-+ this = (struct nand_chip *) (&sharp_sl_mtd[1]);
-+
-+ /* Initialize structures */
-+ memset((char *) sharp_sl_mtd, 0, sizeof(struct mtd_info));
-+ memset((char *) this, 0, sizeof(struct nand_chip));
-+
-+ /* Link the private data with the MTD structure */
-+ sharp_sl_mtd->priv = this;
-+
-+ /*
-+ * PXA initialize
-+ */
-+
-+ /* Set address of NAND IO lines */
-+ this->IO_ADDR_R = (unsigned long)&nandctrl->sdata.data8.sdata0;
-+ this->IO_ADDR_W = (unsigned long)&nandctrl->sdata.data8.sdata0;
-+
-+ /* Set address of hardware control function */
-+ this->hwcontrol = tc6393_nand_hwcontrol;
-+ this->dev_ready = tc6393_nand_dev_ready;
-+ this->cmdfunc = tc6393_nand_command;
-+
-+ /* 15 us command delay time */
-+ this->chip_delay = 15;
-+
-+ /* set eccmode using hardware ECC */
-+#ifdef CONFIG_MTD_NAND_ECC
-+ this->eccmode = NAND_ECC_HW6_512;
-+ this->enable_hwecc = tc6393_nand_enable_hwecc;
-+ this->calculate_ecc = tc6393_nand_calculate_ecc;
-+ this->correct_data = nand_correct_data;
-+#endif
-+
-+ /* Scan to find existence of the device */
-+ if (nand_scan (sharp_sl_mtd)) {
-+ kfree (sharp_sl_mtd);
-+ return -ENXIO;
-+ }
-+
-+#if 1
-+ sharp_sl_mtd->eccsize = this->eccsize;
-+#endif
-+
-+ if (this->eccmode == NAND_ECC_HW6_512 && sharp_sl_mtd->oobblock == 512) {
-+ orig_read_ecc = sharp_sl_mtd->read_ecc;
-+ sharp_sl_mtd->read = tc6393_nand_read;
-+ sharp_sl_mtd->read_ecc = tc6393_nand_read_ecc;
-+
-+ orig_write_ecc = sharp_sl_mtd->write_ecc;
-+ sharp_sl_mtd->write = tc6393_nand_write;
-+ sharp_sl_mtd->write_ecc = tc6393_nand_write_ecc;
-+
-+ orig_writev_ecc = sharp_sl_mtd->writev_ecc;
-+ sharp_sl_mtd->writev = tc6393_nand_writev;
-+ sharp_sl_mtd->writev_ecc = tc6393_nand_writev_ecc;
-+
-+ orig_write_oob = sharp_sl_mtd->write_oob;
-+ sharp_sl_mtd->write_oob = tc6393_nand_write_oob;
-+ }
-+ sharp_sl_mtd->suspend = tc6393_nand_suspend;
-+ sharp_sl_mtd->resume = tc6393_nand_resume;
-+#ifdef CONFIG_MTD_NAND_LOGICAL_ADDRESS_ACCESS
-+ sharp_sl_mtd->cleanup_laddr = sharp_sl_nand_cleanup_laddr;
-+ sharp_sl_mtd->read_laddr = sharp_sl_nand_read_laddr;
-+ sharp_sl_mtd->write_laddr = sharp_sl_nand_write_laddr;
-+#endif
-+
-+ /* Allocate memory for internal data buffer */
-+ this->data_buf = kmalloc (sizeof(u_char) * (sharp_sl_mtd->oobblock + sharp_sl_mtd->oobsize), GFP_KERNEL);
-+ if (!this->data_buf) {
-+ printk ("Unable to allocate NAND data buffer for Poodle.\n");
-+ kfree (sharp_sl_mtd);
-+ return -ENOMEM;
-+ }
-+
-+ /* Allocate memory for internal data buffer */
-+ this->data_cache = kmalloc (sizeof(u_char) * (sharp_sl_mtd->oobblock + sharp_sl_mtd->oobsize), GFP_KERNEL);
-+ if (!this->data_cache) {
-+ printk ("Unable to allocate NAND data cache for Poodle.\n");
-+ kfree (this->data_buf);
-+ kfree (sharp_sl_mtd);
-+ return -ENOMEM;
-+ }
-+
-+ /* Register the partitions */
-+ nr_partitions = parse_cmdline_partitions(sharp_sl_mtd,
-+ &sharp_sl_nand_partition_info,
-+ "sharpsl-nand");
-+ if (nr_partitions <= 0) {
-+ nr_partitions = DEFAULT_NUM_PARTITIONS;
-+ sharp_sl_nand_partition_info = sharp_sl_nand_default_partition_info;
-+ }
-+ sharp_sl_nand_part_mtdp = kmalloc(sizeof (struct mtd_info*) * nr_partitions,
-+ GFP_KERNEL);
-+ if (! sharp_sl_nand_part_mtdp) {
-+ printk("Unable to allocate memory for sharp_sl_nand_part_mtdp\n");
-+ kfree(this->data_buf);
-+ kfree(this->data_cache);
-+ kfree(sharp_sl_mtd);
-+ return -ENOMEM;
-+ }
-+ for (i = 0; i < nr_partitions; i++)
-+ sharp_sl_nand_partition_info[i].mtdp = &sharp_sl_nand_part_mtdp[i];
-+ add_mtd_partitions(sharp_sl_mtd, sharp_sl_nand_partition_info, nr_partitions);
-+
-+ for (i = 0; i < nr_partitions; i++)
-+ add_mtd_device(sharp_sl_nand_part_mtdp[i]);
-+
-+#ifdef DEBUG_PROC
-+ struct proc_dir_entry* res = create_proc_read_entry("mtd-debug", 0, NULL, sharp_sl_nand_read_proc, NULL);
-+ res->write_proc = sharp_sl_nand_write_proc;
-+#endif
-+
-+ /* Return happy */
-+ return 0;
-+}
-+module_init(tc6393_nand_init);
-+
-+/*
-+ * Clean up routine
-+ */
-+#ifdef MODULE
-+static void __exit sharp_sl_nand_cleanup (void)
-+{
-+ struct nand_chip *this = (struct nand_chip *) &sharp_sl_mtd[1];
-+
-+ /* Unregister the device */
-+ del_mtd_partitions (sharp_sl_mtd);
-+ int i;
-+ for (i = 0; i < NUM_PARTITIONS)
-+ del_mtd_device (sharp_sl_nand_part_mtdp[i]);
-+
-+ /* Free internal data buffer */
-+ kfree (this->data_buf);
-+ kfree (this->data_cache);
-+ kfree (this->page_cache);
-+
-+ /* Free the MTD device structure */
-+ kfree (sharp_sl_nand_part_mtdp);
-+ if (sharp_sl_nand_partition_info != sharp_sl_nand_default_partition_info)
-+ kfree (sharp_sl_nand_partition_info);
-+ kfree (sharp_sl_mtd);
-+}
-+module_exit(sharp_sl_nand_cleanup);
-+#endif
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("SHARP, Inc.");
-+MODULE_DESCRIPTION("Board-specific glue layer for NAND flash on Tosa");
-diff -Nur linux_c860_org/drivers/net/Config.in linux/drivers/net/Config.in
---- linux_c860_org/drivers/net/Config.in 2002-08-26 15:00:07.000000000 +0900
-+++ linux/drivers/net/Config.in 2004-06-10 21:09:10.000000000 +0900
-@@ -280,6 +280,7 @@
- dep_tristate ' PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP
- dep_tristate ' PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP
- dep_tristate ' PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP $CONFIG_PPP
-+ dep_tristate ' Microsoft PPP encryption (MPPE)' CONFIG_PPP_MPPE $CONFIG_PPP
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- dep_tristate ' PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP
- fi
-diff -Nur linux_c860_org/drivers/net/Makefile linux/drivers/net/Makefile
---- linux_c860_org/drivers/net/Makefile 2002-08-26 14:43:55.000000000 +0900
-+++ linux/drivers/net/Makefile 2004-06-10 21:09:10.000000000 +0900
-@@ -137,6 +137,14 @@
- obj-$(CONFIG_PPP_BSDCOMP) += bsd_comp.o
- obj-$(CONFIG_PPPOE) += pppox.o pppoe.o
-
-+ifeq ($(CONFIG_PPP_MPPE),y)
-+ obj-y += ppp_mppe.o
-+else
-+ ifeq ($(CONFIG_PPP_MPPE),m)
-+ obj-m += ppp_mppe.o
-+ endif
-+endif
-+
- obj-$(CONFIG_SLIP) += slip.o
- ifeq ($(CONFIG_SLIP_COMPRESSED),y)
- obj-$(CONFIG_SLIP) += slhc.o
-diff -Nur linux_c860_org/drivers/net/md32_common.h linux/drivers/net/md32_common.h
---- linux_c860_org/drivers/net/md32_common.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/net/md32_common.h 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,607 @@
-+/* crypto/md32_common.h */
-+/* ====================================================================
-+ * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ *
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ *
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in
-+ * the documentation and/or other materials provided with the
-+ * distribution.
-+ *
-+ * 3. All advertising materials mentioning features or use of this
-+ * software must display the following acknowledgment:
-+ * "This product includes software developed by the OpenSSL Project
-+ * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
-+ *
-+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
-+ * endorse or promote products derived from this software without
-+ * prior written permission. For written permission, please contact
-+ * licensing@OpenSSL.org.
-+ *
-+ * 5. Products derived from this software may not be called "OpenSSL"
-+ * nor may "OpenSSL" appear in their names without prior written
-+ * permission of the OpenSSL Project.
-+ *
-+ * 6. Redistributions of any form whatsoever must retain the following
-+ * acknowledgment:
-+ * "This product includes software developed by the OpenSSL Project
-+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
-+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
-+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ * ====================================================================
-+ *
-+ * This product includes cryptographic software written by Eric Young
-+ * (eay@cryptsoft.com). This product includes software written by Tim
-+ * Hudson (tjh@cryptsoft.com).
-+ *
-+ */
-+
-+/*
-+ * This is a generic 32 bit "collector" for message digest algorithms.
-+ * Whenever needed it collects input character stream into chunks of
-+ * 32 bit values and invokes a block function that performs actual hash
-+ * calculations.
-+ *
-+ * Porting guide.
-+ *
-+ * Obligatory macros:
-+ *
-+ * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
-+ * this macro defines byte order of input stream.
-+ * HASH_CBLOCK
-+ * size of a unit chunk HASH_BLOCK operates on.
-+ * HASH_LONG
-+ * has to be at lest 32 bit wide, if it's wider, then
-+ * HASH_LONG_LOG2 *has to* be defined along
-+ * HASH_CTX
-+ * context structure that at least contains following
-+ * members:
-+ * typedef struct {
-+ * ...
-+ * HASH_LONG Nl,Nh;
-+ * HASH_LONG data[HASH_LBLOCK];
-+ * int num;
-+ * ...
-+ * } HASH_CTX;
-+ * HASH_UPDATE
-+ * name of "Update" function, implemented here.
-+ * HASH_TRANSFORM
-+ * name of "Transform" function, implemented here.
-+ * HASH_FINAL
-+ * name of "Final" function, implemented here.
-+ * HASH_BLOCK_HOST_ORDER
-+ * name of "block" function treating *aligned* input message
-+ * in host byte order, implemented externally.
-+ * HASH_BLOCK_DATA_ORDER
-+ * name of "block" function treating *unaligned* input message
-+ * in original (data) byte order, implemented externally (it
-+ * actually is optional if data and host are of the same
-+ * "endianess").
-+ * HASH_MAKE_STRING
-+ * macro convering context variables to an ASCII hash string.
-+ *
-+ * Optional macros:
-+ *
-+ * B_ENDIAN or L_ENDIAN
-+ * defines host byte-order.
-+ * HASH_LONG_LOG2
-+ * defaults to 2 if not states otherwise.
-+ * HASH_LBLOCK
-+ * assumed to be HASH_CBLOCK/4 if not stated otherwise.
-+ * HASH_BLOCK_DATA_ORDER_ALIGNED
-+ * alternative "block" function capable of treating
-+ * aligned input message in original (data) order,
-+ * implemented externally.
-+ *
-+ * MD5 example:
-+ *
-+ * #define DATA_ORDER_IS_LITTLE_ENDIAN
-+ *
-+ * #define HASH_LONG MD5_LONG
-+ * #define HASH_LONG_LOG2 MD5_LONG_LOG2
-+ * #define HASH_CTX MD5_CTX
-+ * #define HASH_CBLOCK MD5_CBLOCK
-+ * #define HASH_LBLOCK MD5_LBLOCK
-+ * #define HASH_UPDATE MD5_Update
-+ * #define HASH_TRANSFORM MD5_Transform
-+ * #define HASH_FINAL MD5_Final
-+ * #define HASH_BLOCK_HOST_ORDER md5_block_host_order
-+ * #define HASH_BLOCK_DATA_ORDER md5_block_data_order
-+ *
-+ * <appro@fy.chalmers.se>
-+ */
-+
-+#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-+#error "DATA_ORDER must be defined!"
-+#endif
-+
-+#ifndef HASH_CBLOCK
-+#error "HASH_CBLOCK must be defined!"
-+#endif
-+#ifndef HASH_LONG
-+#error "HASH_LONG must be defined!"
-+#endif
-+#ifndef HASH_CTX
-+#error "HASH_CTX must be defined!"
-+#endif
-+
-+#ifndef HASH_UPDATE
-+#error "HASH_UPDATE must be defined!"
-+#endif
-+#ifndef HASH_TRANSFORM
-+#error "HASH_TRANSFORM must be defined!"
-+#endif
-+#ifndef HASH_FINAL
-+#error "HASH_FINAL must be defined!"
-+#endif
-+
-+#ifndef HASH_BLOCK_HOST_ORDER
-+#error "HASH_BLOCK_HOST_ORDER must be defined!"
-+#endif
-+
-+#if 0
-+/*
-+ * Moved below as it's required only if HASH_BLOCK_DATA_ORDER_ALIGNED
-+ * isn't defined.
-+ */
-+#ifndef HASH_BLOCK_DATA_ORDER
-+#error "HASH_BLOCK_DATA_ORDER must be defined!"
-+#endif
-+#endif
-+
-+#ifndef HASH_LBLOCK
-+#define HASH_LBLOCK (HASH_CBLOCK/4)
-+#endif
-+
-+#ifndef HASH_LONG_LOG2
-+#define HASH_LONG_LOG2 2
-+#endif
-+
-+/*
-+ * Engage compiler specific rotate intrinsic function if available.
-+ */
-+#undef ROTATE
-+#ifndef PEDANTIC
-+# if defined(_MSC_VER)
-+# define ROTATE(a,n) _lrotl(a,n)
-+# elif defined(__MWERKS__)
-+# if defined(__POWERPC__)
-+# define ROTATE(a,n) __rlwinm(a,n,0,31)
-+# elif defined(__MC68K__)
-+ /* Motorola specific tweak. <appro@fy.chalmers.se> */
-+# define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) )
-+# else
-+# define ROTATE(a,n) __rol(a,n)
-+# endif
-+# elif defined(__GNUC__) && __GNUC__>=2 && !defined(NO_ASM) && !defined(NO_INLINE_ASM)
-+ /*
-+ * Some GNU C inline assembler templates. Note that these are
-+ * rotates by *constant* number of bits! But that's exactly
-+ * what we need here...
-+ *
-+ * <appro@fy.chalmers.se>
-+ */
-+# if defined(__i386)
-+# define ROTATE(a,n) ({ register unsigned int ret; \
-+ asm ( \
-+ "roll %1,%0" \
-+ : "=r"(ret) \
-+ : "I"(n), "0"(a) \
-+ : "cc"); \
-+ ret; \
-+ })
-+# elif defined(__powerpc) || defined(__ppc)
-+# define ROTATE(a,n) ({ register unsigned int ret; \
-+ asm ( \
-+ "rlwinm %0,%1,%2,0,31" \
-+ : "=r"(ret) \
-+ : "r"(a), "I"(n)); \
-+ ret; \
-+ })
-+# endif
-+# endif
-+
-+/*
-+ * Engage compiler specific "fetch in reverse byte order"
-+ * intrinsic function if available.
-+ */
-+# if defined(__GNUC__) && __GNUC__>=2 && !defined(NO_ASM) && !defined(NO_INLINE_ASM)
-+ /* some GNU C inline assembler templates by <appro@fy.chalmers.se> */
-+# if defined(__i386) && !defined(I386_ONLY)
-+# define BE_FETCH32(a) ({ register unsigned int l=(a);\
-+ asm ( \
-+ "bswapl %0" \
-+ : "=r"(l) : "0"(l)); \
-+ l; \
-+ })
-+# elif defined(__powerpc)
-+# define LE_FETCH32(a) ({ register unsigned int l; \
-+ asm ( \
-+ "lwbrx %0,0,%1" \
-+ : "=r"(l) \
-+ : "r"(a)); \
-+ l; \
-+ })
-+
-+# elif defined(__sparc) && defined(ULTRASPARC)
-+# define LE_FETCH32(a) ({ register unsigned int l; \
-+ asm ( \
-+ "lda [%1]#ASI_PRIMARY_LITTLE,%0"\
-+ : "=r"(l) \
-+ : "r"(a)); \
-+ l; \
-+ })
-+# endif
-+# endif
-+#endif /* PEDANTIC */
-+
-+#if HASH_LONG_LOG2==2 /* Engage only if sizeof(HASH_LONG)== 4 */
-+/* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */
-+#ifdef ROTATE
-+/* 5 instructions with rotate instruction, else 9 */
-+#define REVERSE_FETCH32(a,l) ( \
-+ l=*(const HASH_LONG *)(a), \
-+ ((ROTATE(l,8)&0x00FF00FF)|(ROTATE((l&0x00FF00FF),24))) \
-+ )
-+#else
-+/* 6 instructions with rotate instruction, else 8 */
-+#define REVERSE_FETCH32(a,l) ( \
-+ l=*(const HASH_LONG *)(a), \
-+ l=(((l>>8)&0x00FF00FF)|((l&0x00FF00FF)<<8)), \
-+ ROTATE(l,16) \
-+ )
-+/*
-+ * Originally the middle line started with l=(((l&0xFF00FF00)>>8)|...
-+ * It's rewritten as above for two reasons:
-+ * - RISCs aren't good at long constants and have to explicitely
-+ * compose 'em with several (well, usually 2) instructions in a
-+ * register before performing the actual operation and (as you
-+ * already realized:-) having same constant should inspire the
-+ * compiler to permanently allocate the only register for it;
-+ * - most modern CPUs have two ALUs, but usually only one has
-+ * circuitry for shifts:-( this minor tweak inspires compiler
-+ * to schedule shift instructions in a better way...
-+ *
-+ * <appro@fy.chalmers.se>
-+ */
-+#endif
-+#endif
-+
-+#ifndef ROTATE
-+#define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
-+#endif
-+
-+/*
-+ * Make some obvious choices. E.g., HASH_BLOCK_DATA_ORDER_ALIGNED
-+ * and HASH_BLOCK_HOST_ORDER ought to be the same if input data
-+ * and host are of the same "endianess". It's possible to mask
-+ * this with blank #define HASH_BLOCK_DATA_ORDER though...
-+ *
-+ * <appro@fy.chalmers.se>
-+ */
-+#if defined(B_ENDIAN)
-+# if defined(DATA_ORDER_IS_BIG_ENDIAN)
-+# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2
-+# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER
-+# endif
-+# elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-+# ifndef HOST_FETCH32
-+# ifdef LE_FETCH32
-+# define HOST_FETCH32(p,l) LE_FETCH32(p)
-+# elif defined(REVERSE_FETCH32)
-+# define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l)
-+# endif
-+# endif
-+# endif
-+#elif defined(L_ENDIAN)
-+# if defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-+# if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED) && HASH_LONG_LOG2==2
-+# define HASH_BLOCK_DATA_ORDER_ALIGNED HASH_BLOCK_HOST_ORDER
-+# endif
-+# elif defined(DATA_ORDER_IS_BIG_ENDIAN)
-+# ifndef HOST_FETCH32
-+# ifdef BE_FETCH32
-+# define HOST_FETCH32(p,l) BE_FETCH32(p)
-+# elif defined(REVERSE_FETCH32)
-+# define HOST_FETCH32(p,l) REVERSE_FETCH32(p,l)
-+# endif
-+# endif
-+# endif
-+#endif
-+
-+#if !defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
-+#ifndef HASH_BLOCK_DATA_ORDER
-+#error "HASH_BLOCK_DATA_ORDER must be defined!"
-+#endif
-+#endif
-+
-+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
-+
-+#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \
-+ l|=(((unsigned long)(*((c)++)))<<16), \
-+ l|=(((unsigned long)(*((c)++)))<< 8), \
-+ l|=(((unsigned long)(*((c)++))) ), \
-+ l)
-+#define HOST_p_c2l(c,l,n) { \
-+ switch (n) { \
-+ case 0: l =((unsigned long)(*((c)++)))<<24; \
-+ case 1: l|=((unsigned long)(*((c)++)))<<16; \
-+ case 2: l|=((unsigned long)(*((c)++)))<< 8; \
-+ case 3: l|=((unsigned long)(*((c)++))); \
-+ } }
-+#define HOST_p_c2l_p(c,l,sc,len) { \
-+ switch (sc) { \
-+ case 0: l =((unsigned long)(*((c)++)))<<24; \
-+ if (--len == 0) break; \
-+ case 1: l|=((unsigned long)(*((c)++)))<<16; \
-+ if (--len == 0) break; \
-+ case 2: l|=((unsigned long)(*((c)++)))<< 8; \
-+ } }
-+/* NOTE the pointer is not incremented at the end of this */
-+#define HOST_c2l_p(c,l,n) { \
-+ l=0; (c)+=n; \
-+ switch (n) { \
-+ case 3: l =((unsigned long)(*(--(c))))<< 8; \
-+ case 2: l|=((unsigned long)(*(--(c))))<<16; \
-+ case 1: l|=((unsigned long)(*(--(c))))<<24; \
-+ } }
-+#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
-+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
-+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
-+ *((c)++)=(unsigned char)(((l) )&0xff), \
-+ l)
-+
-+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-+
-+#define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \
-+ l|=(((unsigned long)(*((c)++)))<< 8), \
-+ l|=(((unsigned long)(*((c)++)))<<16), \
-+ l|=(((unsigned long)(*((c)++)))<<24), \
-+ l)
-+#define HOST_p_c2l(c,l,n) { \
-+ switch (n) { \
-+ case 0: l =((unsigned long)(*((c)++))); \
-+ case 1: l|=((unsigned long)(*((c)++)))<< 8; \
-+ case 2: l|=((unsigned long)(*((c)++)))<<16; \
-+ case 3: l|=((unsigned long)(*((c)++)))<<24; \
-+ } }
-+#define HOST_p_c2l_p(c,l,sc,len) { \
-+ switch (sc) { \
-+ case 0: l =((unsigned long)(*((c)++))); \
-+ if (--len == 0) break; \
-+ case 1: l|=((unsigned long)(*((c)++)))<< 8; \
-+ if (--len == 0) break; \
-+ case 2: l|=((unsigned long)(*((c)++)))<<16; \
-+ } }
-+/* NOTE the pointer is not incremented at the end of this */
-+#define HOST_c2l_p(c,l,n) { \
-+ l=0; (c)+=n; \
-+ switch (n) { \
-+ case 3: l =((unsigned long)(*(--(c))))<<16; \
-+ case 2: l|=((unsigned long)(*(--(c))))<< 8; \
-+ case 1: l|=((unsigned long)(*(--(c)))); \
-+ } }
-+#define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \
-+ *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
-+ *((c)++)=(unsigned char)(((l)>>16)&0xff), \
-+ *((c)++)=(unsigned char)(((l)>>24)&0xff), \
-+ l)
-+
-+#endif
-+
-+/*
-+ * Time for some action:-)
-+ */
-+
-+void HASH_UPDATE (HASH_CTX *c, const void *data_, unsigned long len)
-+ {
-+ const unsigned char *data=data_;
-+ register HASH_LONG * p;
-+ register unsigned long l;
-+ int sw,sc,ew,ec;
-+
-+ if (len==0) return;
-+
-+ l=(c->Nl+(len<<3))&0xffffffffL;
-+ /* 95-05-24 eay Fixed a bug with the overflow handling, thanks to
-+ * Wei Dai <weidai@eskimo.com> for pointing it out. */
-+ if (l < c->Nl) /* overflow */
-+ c->Nh++;
-+ c->Nh+=(len>>29);
-+ c->Nl=l;
-+
-+ if (c->num != 0)
-+ {
-+ p=c->data;
-+ sw=c->num>>2;
-+ sc=c->num&0x03;
-+
-+ if ((c->num+len) >= HASH_CBLOCK)
-+ {
-+ l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l;
-+ for (; sw<HASH_LBLOCK; sw++)
-+ {
-+ HOST_c2l(data,l); p[sw]=l;
-+ }
-+ HASH_BLOCK_HOST_ORDER (c,p,1);
-+ len-=(HASH_CBLOCK-c->num);
-+ c->num=0;
-+ /* drop through and do the rest */
-+ }
-+ else
-+ {
-+ c->num+=len;
-+ if ((sc+len) < 4) /* ugly, add char's to a word */
-+ {
-+ l=p[sw]; HOST_p_c2l_p(data,l,sc,len); p[sw]=l;
-+ }
-+ else
-+ {
-+ ew=(c->num>>2);
-+ ec=(c->num&0x03);
-+ l=p[sw]; HOST_p_c2l(data,l,sc); p[sw++]=l;
-+ for (; sw < ew; sw++)
-+ {
-+ HOST_c2l(data,l); p[sw]=l;
-+ }
-+ if (ec)
-+ {
-+ HOST_c2l_p(data,l,ec); p[sw]=l;
-+ }
-+ }
-+ return;
-+ }
-+ }
-+
-+ sw=len/HASH_CBLOCK;
-+ if (sw > 0)
-+ {
-+#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
-+ /*
-+ * Note that HASH_BLOCK_DATA_ORDER_ALIGNED gets defined
-+ * only if sizeof(HASH_LONG)==4.
-+ */
-+ if ((((unsigned long)data)%4) == 0)
-+ {
-+ /* data is properly aligned so that we can cast it: */
-+ HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,sw);
-+ sw*=HASH_CBLOCK;
-+ data+=sw;
-+ len-=sw;
-+ }
-+ else
-+#if !defined(HASH_BLOCK_DATA_ORDER)
-+ while (sw--)
-+ {
-+ memcpy (p=c->data,data,HASH_CBLOCK);
-+ HASH_BLOCK_DATA_ORDER_ALIGNED(c,p,1);
-+ data+=HASH_CBLOCK;
-+ len-=HASH_CBLOCK;
-+ }
-+#endif
-+#endif
-+#if defined(HASH_BLOCK_DATA_ORDER)
-+ {
-+ HASH_BLOCK_DATA_ORDER(c,data,sw);
-+ sw*=HASH_CBLOCK;
-+ data+=sw;
-+ len-=sw;
-+ }
-+#endif
-+ }
-+
-+ if (len!=0)
-+ {
-+ p = c->data;
-+ c->num = len;
-+ ew=len>>2; /* words to copy */
-+ ec=len&0x03;
-+ for (; ew; ew--,p++)
-+ {
-+ HOST_c2l(data,l); *p=l;
-+ }
-+ HOST_c2l_p(data,l,ec);
-+ *p=l;
-+ }
-+ }
-+
-+
-+void HASH_TRANSFORM (HASH_CTX *c, const unsigned char *data)
-+ {
-+#if defined(HASH_BLOCK_DATA_ORDER_ALIGNED)
-+ if ((((unsigned long)data)%4) == 0)
-+ /* data is properly aligned so that we can cast it: */
-+ HASH_BLOCK_DATA_ORDER_ALIGNED (c,(HASH_LONG *)data,1);
-+ else
-+#if !defined(HASH_BLOCK_DATA_ORDER)
-+ {
-+ memcpy (c->data,data,HASH_CBLOCK);
-+ HASH_BLOCK_DATA_ORDER_ALIGNED (c,c->data,1);
-+ }
-+#endif
-+#endif
-+#if defined(HASH_BLOCK_DATA_ORDER)
-+ HASH_BLOCK_DATA_ORDER (c,data,1);
-+#endif
-+ }
-+
-+
-+void HASH_FINAL (unsigned char *md, HASH_CTX *c)
-+ {
-+ register HASH_LONG *p;
-+ register unsigned long l;
-+ register int i,j;
-+ static const unsigned char end[4]={0x80,0x00,0x00,0x00};
-+ const unsigned char *cp=end;
-+
-+ /* c->num should definitly have room for at least one more byte. */
-+ p=c->data;
-+ i=c->num>>2;
-+ j=c->num&0x03;
-+
-+#if 0
-+ /* purify often complains about the following line as an
-+ * Uninitialized Memory Read. While this can be true, the
-+ * following p_c2l macro will reset l when that case is true.
-+ * This is because j&0x03 contains the number of 'valid' bytes
-+ * already in p[i]. If and only if j&0x03 == 0, the UMR will
-+ * occur but this is also the only time p_c2l will do
-+ * l= *(cp++) instead of l|= *(cp++)
-+ * Many thanks to Alex Tang <altitude@cic.net> for pickup this
-+ * 'potential bug' */
-+#ifdef PURIFY
-+ if (j==0) p[i]=0; /* Yeah, but that's not the way to fix it:-) */
-+#endif
-+ l=p[i];
-+#else
-+ l = (j==0) ? 0 : p[i];
-+#endif
-+ HOST_p_c2l(cp,l,j); p[i++]=l; /* i is the next 'undefined word' */
-+
-+ if (i>(HASH_LBLOCK-2)) /* save room for Nl and Nh */
-+ {
-+ if (i<HASH_LBLOCK) p[i]=0;
-+ HASH_BLOCK_HOST_ORDER (c,p,1);
-+ i=0;
-+ }
-+ for (; i<(HASH_LBLOCK-2); i++)
-+ p[i]=0;
-+
-+#if defined(DATA_ORDER_IS_BIG_ENDIAN)
-+ p[HASH_LBLOCK-2]=c->Nh;
-+ p[HASH_LBLOCK-1]=c->Nl;
-+#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
-+ p[HASH_LBLOCK-2]=c->Nl;
-+ p[HASH_LBLOCK-1]=c->Nh;
-+#endif
-+ HASH_BLOCK_HOST_ORDER (c,p,1);
-+
-+#ifndef HASH_MAKE_STRING
-+#error "HASH_MAKE_STRING must be defined!"
-+#else
-+ HASH_MAKE_STRING(c,md);
-+#endif
-+
-+ c->num=0;
-+ /* clear stuff, HASH_BLOCK may be leaving some stuff on the stack
-+ * but I'm not worried :-)
-+ memset((void *)c,0,sizeof(HASH_CTX));
-+ */
-+ }
-diff -Nur linux_c860_org/drivers/net/mppe.h linux/drivers/net/mppe.h
---- linux_c860_org/drivers/net/mppe.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/net/mppe.h 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,46 @@
-+#ifndef MPPE_H
-+#define MPPE_H
-+
-+typedef struct mppe_state {
-+ int us_unit; /* Interface unit number */
-+ u_char us_id; /* Current id */
-+ u_char us_allowed;
-+ int us_type;
-+ char *us_number; /* Telefone Number */
-+} mppe_state;
-+
-+
-+extern struct protent mppe_protent;
-+
-+#define MPPE_CONFOPTION 18
-+#define MPPC 0x01
-+#define MPPE_40BIT 0x20
-+#define MPPE_128BIT 0x40
-+
-+#define PPP_MPPE 0x00FD
-+#define PPP_MPPC PPP_MPPE
-+
-+#define MPPE_BIT_A 0x80
-+#define MPPE_BIT_B 0x40
-+#define MPPE_BIT_C 0x20
-+#define MPPE_BIT_D 0x10
-+#define MPPE_BIT_FLUSHED MPPE_BIT_A
-+#define MPPE_BIT_ENCRYPTED MPPE_BIT_D
-+#define MPPE_CCOUNT 0x0FFF
-+
-+#define MPPC_BIT_RESET MPPE_BIT_A
-+#define MPPC_BIT_FLUSH MPPE_BIT_B
-+#define MPPC_BIT_COMP MPPC_BIT_C
-+
-+#define MPPE_40_SALT0 0xD1
-+#define MPPE_40_SALT1 0x26
-+#define MPPE_40_SALT2 0x9E
-+
-+#define MPPE_MINLEN 4
-+
-+#define MPPE_REQ 1
-+#define MPPE_RESP 2
-+#define MPPE_ACK 3
-+
-+#endif
-+/*==FILEVERSION 970728==*/
-diff -Nur linux_c860_org/drivers/net/ppp_generic.c linux/drivers/net/ppp_generic.c
---- linux_c860_org/drivers/net/ppp_generic.c 2002-08-29 12:25:24.000000000 +0900
-+++ linux/drivers/net/ppp_generic.c 2004-06-10 21:09:10.000000000 +0900
-@@ -1014,7 +1014,10 @@
- /* try to do packet compression */
- if ((ppp->xstate & SC_COMP_RUN) && ppp->xc_state != 0
- && proto != PPP_LCP && proto != PPP_CCP) {
-- new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len,
-+ int comp_overhead = (ppp->xcomp->compress_proto == CI_MPPE) ?
-+ 4 : 0;
-+ new_skb = alloc_skb(ppp->dev->mtu + ppp->dev->hard_header_len
-+ + comp_overhead,
- GFP_ATOMIC);
- if (new_skb == 0) {
- printk(KERN_ERR "PPP: no memory (comp pkt)\n");
-@@ -1027,7 +1030,8 @@
- /* compressor still expects A/C bytes in hdr */
- len = ppp->xcomp->compress(ppp->xc_state, skb->data - 2,
- new_skb->data, skb->len + 2,
-- ppp->dev->mtu + PPP_HDRLEN);
-+ ppp->dev->mtu + PPP_HDRLEN +
-+ comp_overhead);
- if (len > 0 && (ppp->flags & SC_CCP_UP)) {
- kfree_skb(skb);
- skb = new_skb;
-diff -Nur linux_c860_org/drivers/net/ppp_mppe.c linux/drivers/net/ppp_mppe.c
---- linux_c860_org/drivers/net/ppp_mppe.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/net/ppp_mppe.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,669 @@
-+/*
-+ * ==FILEVERSION 9906180==
-+ *
-+ * ppp_mppe.c - MPPE "compressor/decompressor" module.
-+ *
-+ * Copyright (c) 1994 ª¡rp«¡d Magos«¡nyi <mag@bunuel.tii.matav.hu>
-+ * All rights reserved.
-+ * Copyright (c) 1999 Tim Hockin, Cobalt Networks Inc. <thockin@cobaltnet.com>
-+ *
-+ * Permission to use, copy, modify, and distribute this software and its
-+ * documentation is hereby granted, provided that the above copyright
-+ * notice appears in all copies. This software is provided without any
-+ * warranty, express or implied. The Australian National University
-+ * makes no representations about the suitability of this software for
-+ * any purpose.
-+ *
-+ * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
-+ * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
-+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
-+ * THE AUSTRALIAN NATIONAL UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY
-+ * OF SUCH DAMAGE.
-+ *
-+ * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
-+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
-+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
-+ * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
-+ * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
-+ * OR MODIFICATIONS.
-+ *
-+ * From: deflate.c,v 1.1 1996/01/18 03:17:48 paulus Exp
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/types.h>
-+#include <linux/fcntl.h>
-+#include <linux/interrupt.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/in.h>
-+#include <linux/malloc.h>
-+
-+#undef VERSION
-+/* a nice define to generate linux version numbers */
-+#define VERSION(major,minor,patch) (((((major)<<8)+(minor))<<8)+(patch))
-+
-+#if LINUX_VERSION_CODE >= VERSION(2,1,4)
-+#include <linux/vmalloc.h>
-+#endif
-+#include <linux/errno.h>
-+#include <linux/sched.h> /* to get the struct task_struct */
-+#include <linux/string.h> /* used in new tty drivers */
-+#include <linux/signal.h> /* used in new tty drivers */
-+
-+#include <asm/system.h>
-+
-+#include <linux/netdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/inet.h>
-+#include <linux/ioctl.h>
-+
-+#include <linux/ppp_defs.h>
-+#include <linux/ppp-comp.h>
-+#include "rc4_enc.c"
-+#include "rc4_skey.c"
-+#include "sha1dgst.c"
-+#include "mppe.h"
-+
-+/*
-+ * State for a mppe "(de)compressor".
-+ */
-+struct ppp_mppe_state {
-+ unsigned int ccount; /*coherency count */
-+ RC4_KEY RC4_send_key; /* chap-ms-v2 dictates 2 keys */
-+ RC4_KEY RC4_recv_key;
-+ unsigned char session_send_key[16];
-+ unsigned char session_recv_key[16];
-+ unsigned char master_send_key[16];
-+ unsigned char master_recv_key[16];
-+ int keylen;
-+ int stateless;
-+ int decomp_error;
-+ unsigned int bits;
-+ int unit;
-+ int debug;
-+ int mru;
-+ struct compstat stats;
-+};
-+
-+#define MPPE_CCOUNT_FROM_PACKET(ibuf) ((((ibuf)[4] & 0x0f) << 8) + (ibuf)[5])
-+#define MPPE_BITS(ibuf) ((ibuf)[4] & 0xf0 )
-+#define MPPE_CTRLHI(state) ((((state)->ccount & 0xf00)>>8)|((state)->bits))
-+#define MPPE_CTRLLO(state) ((state)->ccount & 0xff)
-+
-+#define MPPE_OVHD 4
-+
-+/* Procedures from the MPPE draft */
-+
-+/*
-+ * Pads used in key derivation
-+ */
-+static unsigned char SHAPad1[40] =
-+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
-+static unsigned char SHAPad2[40] =
-+ {0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
-+ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
-+ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
-+ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2};
-+
-+/*
-+ * SHAInit(), SHAUpdate() and SHAFinal() functions are an
-+ * implementation of Secure Hash Algorithm (SHA-1) [7]. These are
-+ * available in public domain or can be licensed from
-+ * RSA Data Security, Inc.
-+ *
-+ * 1) H is 8 bytes long for 40 bit session keys.
-+ * 2) H is 16 bytes long for 128 bit session keys.
-+ * 3) H' is same as H when this routine is called for the first time
-+ * for the session.
-+ * 4) The generated key is returned in H'. This is the "current" key.
-+ */
-+static void
-+GetNewKeyFromSHA(StartKey, SessionKey, SessionKeyLength, InterimKey)
-+ unsigned char *StartKey;
-+ unsigned char *SessionKey;
-+ unsigned long SessionKeyLength;
-+ unsigned char *InterimKey;
-+{
-+ SHA_CTX Context;
-+ unsigned char Digest[SHA_DIGEST_LENGTH];
-+
-+ SHA1_Init(&Context);
-+ SHA1_Update(&Context, StartKey, SessionKeyLength);
-+ SHA1_Update(&Context, SHAPad1, 40);
-+ SHA1_Update(&Context, SessionKey, SessionKeyLength);
-+ SHA1_Update(&Context, SHAPad2, 40);
-+ SHA1_Final(Digest,&Context);
-+ memcpy(InterimKey, Digest, SessionKeyLength);
-+}
-+
-+static void
-+mppe_synchronize_key(struct ppp_mppe_state *state)
-+{
-+ /* get new keys and flag our state as such */
-+ RC4_set_key(&(state->RC4_send_key),state->keylen,state->session_send_key);
-+ RC4_set_key(&(state->RC4_recv_key),state->keylen,state->session_recv_key);
-+
-+ state->bits=MPPE_BIT_FLUSHED|MPPE_BIT_ENCRYPTED;
-+}
-+
-+
-+static void
-+mppe_initialize_key(struct ppp_mppe_state *state)
-+{
-+ /* generate new session keys */
-+ GetNewKeyFromSHA(state->master_send_key, state->master_send_key,
-+ state->keylen, state->session_send_key);
-+ GetNewKeyFromSHA(state->master_recv_key, state->master_recv_key,
-+ state->keylen, state->session_recv_key);
-+
-+ if(state->keylen == 8) {
-+ /* cripple them from 64bit->40bit */
-+ state->session_send_key[0]=state->session_recv_key[0] = MPPE_40_SALT0;
-+ state->session_send_key[1]=state->session_recv_key[1] = MPPE_40_SALT1;
-+ state->session_send_key[2]=state->session_recv_key[2] = MPPE_40_SALT2;
-+ }
-+
-+ mppe_synchronize_key(state);
-+}
-+
-+
-+static void
-+mppe_change_key(struct ppp_mppe_state *state)
-+{
-+ unsigned char InterimSendKey[16];
-+ unsigned char InterimRecvKey[16];
-+
-+ /* get temp keys */
-+ GetNewKeyFromSHA(state->master_send_key, state->session_send_key,
-+ state->keylen, InterimSendKey);
-+ GetNewKeyFromSHA(state->master_recv_key, state->session_recv_key,
-+ state->keylen, InterimRecvKey);
-+
-+ /* build RC4 keys from the temp keys */
-+ RC4_set_key(&(state->RC4_send_key), state->keylen, InterimSendKey);
-+ RC4_set_key(&(state->RC4_recv_key), state->keylen, InterimRecvKey);
-+
-+ /* make new session keys */
-+ RC4(&(state->RC4_send_key), state->keylen, InterimSendKey,
-+ state->session_send_key);
-+ RC4(&(state->RC4_recv_key), state->keylen, InterimRecvKey,
-+ state->session_recv_key);
-+
-+ if(state->keylen == 8)
-+ {
-+ /* cripple them from 64->40 bits*/
-+ state->session_send_key[0]=state->session_recv_key[0] = MPPE_40_SALT0;
-+ state->session_send_key[1]=state->session_recv_key[1] = MPPE_40_SALT1;
-+ state->session_send_key[2]=state->session_recv_key[2] = MPPE_40_SALT2;
-+ }
-+
-+ /* make the final rc4 keys */
-+ RC4_set_key(&(state->RC4_send_key), state->keylen, state->session_send_key);
-+ RC4_set_key(&(state->RC4_recv_key), state->keylen, state->session_recv_key);
-+
-+ state->bits |= MPPE_BIT_FLUSHED;
-+}
-+
-+
-+#ifdef DEBUG
-+/* Utility procedures to print a buffer in hex/ascii */
-+static void
-+ppp_print_hex (register __u8 *out, const __u8 *in, int count)
-+{
-+ register __u8 next_ch;
-+ static char hex[] = "0123456789ABCDEF";
-+
-+ while (count-- > 0) {
-+ next_ch = *in++;
-+ *out++ = hex[(next_ch >> 4) & 0x0F];
-+ *out++ = hex[next_ch & 0x0F];
-+ ++out;
-+ }
-+}
-+
-+
-+static void
-+ppp_print_char (register __u8 *out, const __u8 *in, int count)
-+{
-+ register __u8 next_ch;
-+
-+ while (count-- > 0) {
-+ next_ch = *in++;
-+
-+ if (next_ch < 0x20 || next_ch > 0x7e)
-+ *out++ = '.';
-+ else {
-+ *out++ = next_ch;
-+ if (next_ch == '%') /* printk/syslogd has a bug !! */
-+ *out++ = '%';
-+ }
-+ }
-+ *out = '\0';
-+}
-+
-+
-+static void
-+ppp_print_buffer (const __u8 *name, const __u8 *buf, int count)
-+{
-+ __u8 line[44];
-+
-+ if (name != (__u8 *) NULL)
-+ printk (KERN_DEBUG "ppp: %s, count = %d\n", name, count);
-+
-+ while (count > 8) {
-+ memset (line, 32, 44);
-+ ppp_print_hex (line, buf, 8);
-+ ppp_print_char (&line[8 * 3], buf, 8);
-+ printk (KERN_DEBUG "%s\n", line);
-+ count -= 8;
-+ buf += 8;
-+ }
-+
-+ if (count > 0) {
-+ memset (line, 32, 44);
-+ ppp_print_hex (line, buf, count);
-+ ppp_print_char (&line[8 * 3], buf, count);
-+ printk (KERN_DEBUG "%s\n", line);
-+ }
-+}
-+#endif
-+
-+/* our 'compressor' proper */
-+static void *mppe_comp_alloc __P((unsigned char *, int));
-+static void mppe_comp_free __P((void *));
-+static int mppe_comp_init __P((void *, unsigned char *,
-+ int, int, int, int));
-+static int mppe_decomp_init __P((void *, unsigned char *,
-+ int, int, int, int, int));
-+static int mppe_compress __P((void *, unsigned char *,
-+ unsigned char *, int, int));
-+static void mppe_incomp __P((void *, unsigned char *, int));
-+static int mppe_decompress __P((void *, unsigned char *,
-+ int, unsigned char *, int));
-+static void mppe_comp_reset __P((void *));
-+static void mppe_comp_stats __P((void *, struct compstat *));
-+
-+
-+/* cleanup the compressor */
-+static void
-+mppe_comp_free(void *arg)
-+{
-+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
-+
-+ if (state) {
-+ kfree(state);
-+ MOD_DEC_USE_COUNT;
-+ }
-+}
-+
-+
-+/* allocate space for a compressor. */
-+static void *
-+mppe_comp_alloc(unsigned char *options, int opt_len)
-+{
-+ struct ppp_mppe_state *state;
-+
-+ if (((2*8)+3 != opt_len && (2*16)+3 != opt_len) /* 2 keys + 3 */
-+ || options[0] != CI_MPPE || options[1] != CILEN_MPPE) {
-+ printk(KERN_DEBUG "compress rejected: opt_len=%u,o[0]=%x,o[1]=%x\n",
-+ opt_len,options[0],options[1]);
-+ return NULL;
-+ }
-+
-+ state = (struct ppp_mppe_state *)kmalloc(sizeof(*state), GFP_KERNEL);
-+ if (state == NULL)
-+ return NULL;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ memset (state, 0, sizeof (struct ppp_mppe_state));
-+
-+ /* write the data in options to the right places */
-+ memcpy(&state->stateless,options+2,1);
-+
-+ state->keylen = (opt_len-3)/2;
-+ memcpy(state->master_send_key,options+3,state->keylen);
-+ memcpy(state->master_recv_key,options+3+state->keylen,state->keylen);
-+
-+ mppe_initialize_key(state);
-+
-+ return (void *) state;
-+}
-+
-+
-+static int
-+mppe_comp_init(void *arg, unsigned char *options, int opt_len, int unit,
-+ int hdrlen, int debug)
-+{
-+ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
-+
-+ if (options[0] != CI_MPPE || options[1] != CILEN_MPPE) {
-+ printk(KERN_DEBUG "compress rejected: opt_len=%u,o[0]=%x,o[1]=%x\n",
-+ opt_len,options[0],options[1]);
-+ return 0;
-+ }
-+
-+ state->ccount = 0;
-+ state->unit = unit;
-+ state->debug = debug;
-+
-+ /* 19 is the min (2*keylen) + 3 */
-+ if(opt_len >= 19) {
-+ memcpy(&state->stateless,options+2,1);
-+
-+ state->keylen = (opt_len-3)/2;
-+ memcpy(state->master_send_key,options+3,state->keylen);
-+ memcpy(state->master_recv_key,options+3+state->keylen,state->keylen);
-+
-+ mppe_initialize_key(state);
-+ }
-+
-+ return 1;
-+}
-+
-+
-+static int
-+mppe_decomp_init(void *arg, unsigned char *options, int opt_len, int unit,
-+ int hdrlen, int mru, int debug)
-+{
-+ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
-+
-+ if (options[0] != CI_MPPE || options[1] != CILEN_MPPE) {
-+ printk(KERN_DEBUG"options are bad: %x %x\n",options[0],options[1]);
-+ return 0;
-+ }
-+
-+ state->ccount = 0;
-+ state->unit = unit;
-+ state->debug = debug;
-+ state->mru = mru;
-+
-+ /* 19 is the min (2*keylen)+3 */
-+ if(opt_len >= 19) {
-+ memcpy(&state->stateless,options+2,1);
-+
-+ state->keylen = (opt_len-3)/2;
-+ memcpy(state->master_send_key,options+3,state->keylen);
-+ memcpy(state->master_recv_key,options+3+state->keylen,state->keylen);
-+
-+ mppe_initialize_key(state);
-+ }
-+
-+ return 1;
-+}
-+
-+
-+static void
-+mppe_comp_reset(void *arg)
-+{
-+ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
-+
-+ printk(KERN_DEBUG "mppe_comp_reset\n");
-+
-+ (state->stats).in_count = 0;
-+ (state->stats).bytes_out = 0;
-+ (state->stats).ratio = 0;
-+
-+ mppe_synchronize_key(state);
-+}
-+
-+
-+static void
-+mppe_update_count(struct ppp_mppe_state *state)
-+{
-+ if(!state->stateless)
-+ {
-+ if ( 0xff == (state->ccount&0xff)){
-+ /* time to change keys */
-+ if ( 0xfff == (state->ccount&0xfff)){
-+ state->ccount = 0;
-+ } else {
-+ (state->ccount)++;
-+ }
-+ mppe_change_key(state);
-+ } else {
-+ state->ccount++;
-+ }
-+ } else {
-+ if ( 0xFFF == (state->ccount & 0xFFF)) {
-+ state->ccount = 0;
-+ } else {
-+ (state->ccount)++;
-+ }
-+ mppe_change_key(state);
-+ }
-+}
-+
-+
-+/* the big nasty */
-+int
-+mppe_compress(void *arg, unsigned char *rptr, unsigned char *obuf,
-+ int isize, int osize)
-+{
-+ struct ppp_mppe_state *state = (struct ppp_mppe_state *) arg;
-+ int proto, olen;
-+ unsigned char *wptr;
-+
-+#ifdef DEBUG
-+ ppp_print_buffer("mppe_encrypt",rptr,isize);
-+#endif
-+
-+ if(osize < isize+MPPE_OVHD) {
-+ printk(KERN_DEBUG "Not enough space to encrypt packet: %d<%d+%d!\n",
-+ isize, osize, MPPE_OVHD);
-+ return 0;
-+ }
-+
-+ /* Check that the protocol is in the range we handle. */
-+ proto = PPP_PROTOCOL(rptr);
-+ if (proto < 0x0021 || proto > 0x00FA )
-+ return 0;
-+
-+ wptr = obuf;
-+
-+ /* Copy over the PPP header and store the 2-byte sequence number. */
-+ wptr[0] = PPP_ADDRESS(rptr);
-+ wptr[1] = PPP_CONTROL(rptr);
-+ wptr[2] = PPP_MPPE >>8;
-+ wptr[3] = PPP_MPPE;
-+ wptr += PPP_HDRLEN;
-+ wptr[0] = MPPE_CTRLHI(state);
-+ wptr[1] = MPPE_CTRLLO(state);
-+ wptr += 2;
-+
-+ state->bits=MPPE_BIT_ENCRYPTED;
-+ mppe_update_count(state);
-+
-+ /* read from rptr, write to wptr adjust for PPP_HDRLEN */
-+ RC4(&(state->RC4_send_key),isize-2,rptr+2,wptr);
-+ olen=isize+MPPE_OVHD;
-+
-+ (state->stats).comp_bytes += isize;
-+ (state->stats).comp_packets++;
-+
-+#ifdef DEBUG
-+ ppp_print_buffer("mppe_encrypt out",obuf,olen);
-+#endif
-+
-+ return olen;
-+}
-+
-+
-+static void
-+mppe_comp_stats(void *arg, struct compstat *stats)
-+{
-+ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
-+
-+ /* since we don't REALLY compress at all, this should be OK */
-+ (state->stats).in_count = (state->stats).unc_bytes;
-+ (state->stats).bytes_out = (state->stats).comp_bytes;
-+
-+ /* this _SHOULD_ always be 1 */
-+ (state->stats).ratio = 1.0;
-+// printk(" in count : %d , out bytes %d \n;",(state->stats).in_count,(state->stats).bytes_out);
-+
-+ *stats = state->stats;
-+
-+}
-+
-+
-+/* the other big nasty */
-+int
-+mppe_decompress(void *arg, unsigned char *ibuf, int isize,
-+ unsigned char *obuf, int osize)
-+{
-+ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
-+ int seq;
-+
-+ if (isize <= PPP_HDRLEN + MPPE_OVHD) {
-+ if (state->debug) {
-+ printk(KERN_DEBUG "mppe_decompress%d: short packet (len=%d)\n",
-+ state->unit, isize);
-+ }
-+
-+ return DECOMP_ERROR;
-+ }
-+
-+ /* Check the sequence number. */
-+ seq = MPPE_CCOUNT_FROM_PACKET(ibuf);
-+
-+ if(!state->stateless && (MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED)) {
-+ state->decomp_error = 0;
-+ state->ccount = seq;
-+ }
-+
-+ if(state->decomp_error) {
-+ return DECOMP_ERROR;
-+ }
-+
-+ if (seq != state->ccount) {
-+ if (state->debug) {
-+ printk(KERN_DEBUG "mppe_decompress%d: bad seq # %d, expected %d\n",
-+ state->unit, seq, state->ccount);
-+ }
-+
-+ while(state->ccount != seq) {
-+ mppe_update_count(state);
-+ }
-+
-+ /*
-+ * Packets with bad sequence numbers can still be decrypted
-+ * successfully when stateless compression is in use.
-+ */
-+ if (!state->stateless) {
-+ mppe_update_count(state);
-+
-+ return DECOMP_ERROR;
-+ }
-+ }
-+
-+ /*
-+ * Fill in the first part of the PPP header. The protocol field
-+ * comes from the decompressed data.
-+ */
-+ obuf[0] = PPP_ADDRESS(ibuf);
-+ obuf[1] = PPP_CONTROL(ibuf);
-+ obuf += 2;
-+
-+ if(!(MPPE_BITS(ibuf) & MPPE_BIT_ENCRYPTED)) {
-+ printk(KERN_DEBUG"ERROR: not an encrypted packet");
-+ mppe_synchronize_key(state);
-+ return DECOMP_ERROR;
-+ } else {
-+ if(!state->stateless && (MPPE_BITS(ibuf) & MPPE_BIT_FLUSHED))
-+ mppe_synchronize_key(state);
-+ mppe_update_count(state);
-+
-+ /* decrypt - adjust for PPP_HDRLEN + MPPE_OVHD - mru should be OK */
-+ RC4(&(state->RC4_recv_key),isize-6,ibuf+6,obuf);
-+
-+ (state->stats).unc_bytes += (isize-MPPE_OVHD);
-+ (state->stats).unc_packets ++;
-+
-+ return isize-MPPE_OVHD;
-+ }
-+}
-+
-+
-+/* Incompressible data has arrived - add it to the history. */
-+static void
-+mppe_incomp(void *arg, unsigned char *ibuf, int icnt)
-+{
-+ struct ppp_mppe_state *state = (struct ppp_mppe_state *)arg;
-+
-+ (state->stats).inc_bytes += icnt;
-+ (state->stats).inc_packets++;
-+}
-+
-+/*
-+ * Help for Alpha users who have problems with undefined symbols on
-+ * module load
-+ */
-+#ifdef ALPHA
-+#include "../../arch/s390/kernel/floatlib.c"
-+#endif
-+
-+
-+/*************************************************************
-+ * Module interface table
-+ *************************************************************/
-+
-+/* These are in ppp.c */
-+extern int ppp_register_compressor (struct compressor *cp);
-+extern void ppp_unregister_compressor (struct compressor *cp);
-+
-+/*
-+ * Procedures exported to if_ppp.c.
-+ */
-+struct compressor ppp_mppe = {
-+ CI_MPPE, /* compress_proto */
-+ mppe_comp_alloc, /* comp_alloc */
-+ mppe_comp_free, /* comp_free */
-+ mppe_comp_init, /* comp_init */
-+ mppe_comp_reset, /* comp_reset */
-+ mppe_compress, /* compress */
-+ mppe_comp_stats, /* comp_stat */
-+ mppe_comp_alloc, /* decomp_alloc */
-+ mppe_comp_free, /* decomp_free */
-+ mppe_decomp_init, /* decomp_init */
-+ mppe_comp_reset, /* decomp_reset */
-+ mppe_decompress, /* decompress */
-+ mppe_incomp, /* incomp */
-+ mppe_comp_stats, /* decomp_stat */
-+};
-+
-+
-+#ifdef MODULE
-+/*************************************************************
-+ * Module support routines
-+ *************************************************************/
-+
-+int
-+init_module(void)
-+{
-+ int answer = ppp_register_compressor(&ppp_mppe);
-+ if (answer == 0) {
-+ printk(KERN_INFO "PPP MPPE compression module registered\n");
-+ }
-+ return answer;
-+}
-+
-+
-+void
-+cleanup_module(void)
-+{
-+ if (MOD_IN_USE) {
-+ printk (KERN_INFO "MPPE module busy, remove delayed\n");
-+ } else {
-+ ppp_unregister_compressor (&ppp_mppe);
-+ printk(KERN_INFO "PPP MPPE compression module unregistered\n");
-+ }
-+}
-+#endif /* MODULE */
-diff -Nur linux_c860_org/drivers/net/rc4_enc.c linux/drivers/net/rc4_enc.c
---- linux_c860_org/drivers/net/rc4_enc.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/net/rc4_enc.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,315 @@
-+/* crypto/rc4/rc4_enc.c */
-+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+#include <openssl/rc4.h>
-+#include "rc4_locl.h"
-+
-+/* RC4 as implemented from a posting from
-+ * Newsgroups: sci.crypt
-+ * From: sterndark@netcom.com (David Sterndark)
-+ * Subject: RC4 Algorithm revealed.
-+ * Message-ID: <sternCvKL4B.Hyy@netcom.com>
-+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
-+ */
-+
-+void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
-+ unsigned char *outdata)
-+ {
-+ register RC4_INT *d;
-+ register RC4_INT x,y,tx,ty;
-+ int i;
-+
-+ x=key->x;
-+ y=key->y;
-+ d=key->data;
-+
-+#if defined(RC4_CHUNK)
-+ /*
-+ * The original reason for implementing this(*) was the fact that
-+ * pre-21164a Alpha CPUs don't have byte load/store instructions
-+ * and e.g. a byte store has to be done with 64-bit load, shift,
-+ * and, or and finally 64-bit store. Peaking data and operating
-+ * at natural word size made it possible to reduce amount of
-+ * instructions as well as to perform early read-ahead without
-+ * suffering from RAW (read-after-write) hazard. This resulted
-+ * in ~40%(**) performance improvement on 21064 box with gcc.
-+ * But it's not only Alpha users who win here:-) Thanks to the
-+ * early-n-wide read-ahead this implementation also exhibits
-+ * >40% speed-up on SPARC and 20-30% on 64-bit MIPS (depending
-+ * on sizeof(RC4_INT)).
-+ *
-+ * (*) "this" means code which recognizes the case when input
-+ * and output pointers appear to be aligned at natural CPU
-+ * word boundary
-+ * (**) i.e. according to 'apps/openssl speed rc4' benchmark,
-+ * crypto/rc4/rc4speed.c exhibits almost 70% speed-up...
-+ *
-+ * Cavets.
-+ *
-+ * - RC4_CHUNK="unsigned long long" should be a #1 choice for
-+ * UltraSPARC. Unfortunately gcc generates very slow code
-+ * (2.5-3 times slower than one generated by Sun's WorkShop
-+ * C) and therefore gcc (at least 2.95 and earlier) should
-+ * always be told that RC4_CHUNK="unsigned long".
-+ *
-+ * <appro@fy.chalmers.se>
-+ */
-+
-+# define RC4_STEP ( \
-+ x=(x+1) &0xff, \
-+ tx=d[x], \
-+ y=(tx+y)&0xff, \
-+ ty=d[y], \
-+ d[y]=tx, \
-+ d[x]=ty, \
-+ (RC4_CHUNK)d[(tx+ty)&0xff]\
-+ )
-+
-+ if ( ( ((unsigned long)indata & (sizeof(RC4_CHUNK)-1)) |
-+ ((unsigned long)outdata & (sizeof(RC4_CHUNK)-1)) ) == 0 )
-+ {
-+ RC4_CHUNK ichunk,otp;
-+ const union { long one; char little; } is_endian = {1};
-+
-+ /*
-+ * I reckon we can afford to implement both endian
-+ * cases and to decide which way to take at run-time
-+ * because the machine code appears to be very compact
-+ * and redundant 1-2KB is perfectly tolerable (i.e.
-+ * in case the compiler fails to eliminate it:-). By
-+ * suggestion from Terrel Larson <terr@terralogic.net>
-+ * who also stands for the is_endian union:-)
-+ *
-+ * Special notes.
-+ *
-+ * - is_endian is declared automatic as doing otherwise
-+ * (declaring static) prevents gcc from eliminating
-+ * the redundant code;
-+ * - compilers (those I've tried) don't seem to have
-+ * problems eliminating either the operators guarded
-+ * by "if (sizeof(RC4_CHUNK)==8)" or the condition
-+ * expressions themselves so I've got 'em to replace
-+ * corresponding #ifdefs from the previous version;
-+ * - I chose to let the redundant switch cases when
-+ * sizeof(RC4_CHUNK)!=8 be (were also #ifdefed
-+ * before);
-+ * - in case you wonder "&(sizeof(RC4_CHUNK)*8-1)" in
-+ * [LB]ESHFT guards against "shift is out of range"
-+ * warnings when sizeof(RC4_CHUNK)!=8
-+ *
-+ * <appro@fy.chalmers.se>
-+ */
-+ if (!is_endian.little)
-+ { /* BIG-ENDIAN CASE */
-+# define BESHFT(c) (((sizeof(RC4_CHUNK)-(c)-1)*8)&(sizeof(RC4_CHUNK)*8-1))
-+ for (;len&-sizeof(RC4_CHUNK);len-=sizeof(RC4_CHUNK))
-+ {
-+ ichunk = *(RC4_CHUNK *)indata;
-+ otp = RC4_STEP<<BESHFT(0);
-+ otp |= RC4_STEP<<BESHFT(1);
-+ otp |= RC4_STEP<<BESHFT(2);
-+ otp |= RC4_STEP<<BESHFT(3);
-+ if (sizeof(RC4_CHUNK)==8)
-+ {
-+ otp |= RC4_STEP<<BESHFT(4);
-+ otp |= RC4_STEP<<BESHFT(5);
-+ otp |= RC4_STEP<<BESHFT(6);
-+ otp |= RC4_STEP<<BESHFT(7);
-+ }
-+ *(RC4_CHUNK *)outdata = otp^ichunk;
-+ indata += sizeof(RC4_CHUNK);
-+ outdata += sizeof(RC4_CHUNK);
-+ }
-+ if (len)
-+ {
-+ RC4_CHUNK mask=(RC4_CHUNK)-1, ochunk;
-+
-+ ichunk = *(RC4_CHUNK *)indata;
-+ ochunk = *(RC4_CHUNK *)outdata;
-+ otp = 0;
-+ i = BESHFT(0);
-+ mask <<= (sizeof(RC4_CHUNK)-len)<<3;
-+ switch (len&(sizeof(RC4_CHUNK)-1))
-+ {
-+ case 7: otp = RC4_STEP<<i, i-=8;
-+ case 6: otp |= RC4_STEP<<i, i-=8;
-+ case 5: otp |= RC4_STEP<<i, i-=8;
-+ case 4: otp |= RC4_STEP<<i, i-=8;
-+ case 3: otp |= RC4_STEP<<i, i-=8;
-+ case 2: otp |= RC4_STEP<<i, i-=8;
-+ case 1: otp |= RC4_STEP<<i, i-=8;
-+ case 0: ; /*
-+ * it's never the case,
-+ * but it has to be here
-+ * for ultrix?
-+ */
-+ }
-+ ochunk &= ~mask;
-+ ochunk |= (otp^ichunk) & mask;
-+ *(RC4_CHUNK *)outdata = ochunk;
-+ }
-+ key->x=x;
-+ key->y=y;
-+ return;
-+ }
-+ else
-+ { /* LITTLE-ENDIAN CASE */
-+# define LESHFT(c) (((c)*8)&(sizeof(RC4_CHUNK)*8-1))
-+ for (;len&-sizeof(RC4_CHUNK);len-=sizeof(RC4_CHUNK))
-+ {
-+ ichunk = *(RC4_CHUNK *)indata;
-+ otp = RC4_STEP;
-+ otp |= RC4_STEP<<8;
-+ otp |= RC4_STEP<<16;
-+ otp |= RC4_STEP<<24;
-+ if (sizeof(RC4_CHUNK)==8)
-+ {
-+ otp |= RC4_STEP<<LESHFT(4);
-+ otp |= RC4_STEP<<LESHFT(5);
-+ otp |= RC4_STEP<<LESHFT(6);
-+ otp |= RC4_STEP<<LESHFT(7);
-+ }
-+ *(RC4_CHUNK *)outdata = otp^ichunk;
-+ indata += sizeof(RC4_CHUNK);
-+ outdata += sizeof(RC4_CHUNK);
-+ }
-+ if (len)
-+ {
-+ RC4_CHUNK mask=(RC4_CHUNK)-1, ochunk;
-+
-+ ichunk = *(RC4_CHUNK *)indata;
-+ ochunk = *(RC4_CHUNK *)outdata;
-+ otp = 0;
-+ i = 0;
-+ mask >>= (sizeof(RC4_CHUNK)-len)<<3;
-+ switch (len&(sizeof(RC4_CHUNK)-1))
-+ {
-+ case 7: otp = RC4_STEP, i+=8;
-+ case 6: otp |= RC4_STEP<<i, i+=8;
-+ case 5: otp |= RC4_STEP<<i, i+=8;
-+ case 4: otp |= RC4_STEP<<i, i+=8;
-+ case 3: otp |= RC4_STEP<<i, i+=8;
-+ case 2: otp |= RC4_STEP<<i, i+=8;
-+ case 1: otp |= RC4_STEP<<i, i+=8;
-+ case 0: ; /*
-+ * it's never the case,
-+ * but it has to be here
-+ * for ultrix?
-+ */
-+ }
-+ ochunk &= ~mask;
-+ ochunk |= (otp^ichunk) & mask;
-+ *(RC4_CHUNK *)outdata = ochunk;
-+ }
-+ key->x=x;
-+ key->y=y;
-+ return;
-+ }
-+ }
-+#endif
-+#define LOOP(in,out) \
-+ x=((x+1)&0xff); \
-+ tx=d[x]; \
-+ y=(tx+y)&0xff; \
-+ d[x]=ty=d[y]; \
-+ d[y]=tx; \
-+ (out) = d[(tx+ty)&0xff]^ (in);
-+
-+#ifndef RC4_INDEX
-+#define RC4_LOOP(a,b,i) LOOP(*((a)++),*((b)++))
-+#else
-+#define RC4_LOOP(a,b,i) LOOP(a[i],b[i])
-+#endif
-+
-+ i=(int)(len>>3L);
-+ if (i)
-+ {
-+ for (;;)
-+ {
-+ RC4_LOOP(indata,outdata,0);
-+ RC4_LOOP(indata,outdata,1);
-+ RC4_LOOP(indata,outdata,2);
-+ RC4_LOOP(indata,outdata,3);
-+ RC4_LOOP(indata,outdata,4);
-+ RC4_LOOP(indata,outdata,5);
-+ RC4_LOOP(indata,outdata,6);
-+ RC4_LOOP(indata,outdata,7);
-+#ifdef RC4_INDEX
-+ indata+=8;
-+ outdata+=8;
-+#endif
-+ if (--i == 0) break;
-+ }
-+ }
-+ i=(int)len&0x07;
-+ if (i)
-+ {
-+ for (;;)
-+ {
-+ RC4_LOOP(indata,outdata,0); if (--i == 0) break;
-+ RC4_LOOP(indata,outdata,1); if (--i == 0) break;
-+ RC4_LOOP(indata,outdata,2); if (--i == 0) break;
-+ RC4_LOOP(indata,outdata,3); if (--i == 0) break;
-+ RC4_LOOP(indata,outdata,4); if (--i == 0) break;
-+ RC4_LOOP(indata,outdata,5); if (--i == 0) break;
-+ RC4_LOOP(indata,outdata,6); if (--i == 0) break;
-+ }
-+ }
-+ key->x=x;
-+ key->y=y;
-+ }
-diff -Nur linux_c860_org/drivers/net/rc4_locl.h linux/drivers/net/rc4_locl.h
---- linux_c860_org/drivers/net/rc4_locl.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/net/rc4_locl.h 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,4 @@
-+#ifndef HEADER_RC4_LOCL_H
-+#define HEADER_RC4_LOCL_H
-+#include <openssl/opensslconf.h>
-+#endif
-diff -Nur linux_c860_org/drivers/net/rc4_skey.c linux/drivers/net/rc4_skey.c
---- linux_c860_org/drivers/net/rc4_skey.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/net/rc4_skey.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,117 @@
-+/* crypto/rc4/rc4_skey.c */
-+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+#include <openssl/rc4.h>
-+#include "rc4_locl.h"
-+#include <openssl/opensslv.h>
-+
-+const char *RC4_version="RC4" OPENSSL_VERSION_PTEXT;
-+
-+const char *RC4_options(void)
-+ {
-+#ifdef RC4_INDEX
-+ if (sizeof(RC4_INT) == 1)
-+ return("rc4(idx,char)");
-+ else
-+ return("rc4(idx,int)");
-+#else
-+ if (sizeof(RC4_INT) == 1)
-+ return("rc4(ptr,char)");
-+ else
-+ return("rc4(ptr,int)");
-+#endif
-+ }
-+
-+/* RC4 as implemented from a posting from
-+ * Newsgroups: sci.crypt
-+ * From: sterndark@netcom.com (David Sterndark)
-+ * Subject: RC4 Algorithm revealed.
-+ * Message-ID: <sternCvKL4B.Hyy@netcom.com>
-+ * Date: Wed, 14 Sep 1994 06:35:31 GMT
-+ */
-+
-+void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data)
-+ {
-+ register RC4_INT tmp;
-+ register int id1,id2;
-+ register RC4_INT *d;
-+ unsigned int i;
-+
-+ d= &(key->data[0]);
-+ for (i=0; i<256; i++)
-+ d[i]=i;
-+ key->x = 0;
-+ key->y = 0;
-+ id1=id2=0;
-+
-+#define SK_LOOP(n) { \
-+ tmp=d[(n)]; \
-+ id2 = (data[id1] + tmp + id2) & 0xff; \
-+ if (++id1 == len) id1=0; \
-+ d[(n)]=d[id2]; \
-+ d[id2]=tmp; }
-+
-+ for (i=0; i < 256; i+=4)
-+ {
-+ SK_LOOP(i+0);
-+ SK_LOOP(i+1);
-+ SK_LOOP(i+2);
-+ SK_LOOP(i+3);
-+ }
-+ }
-+
-diff -Nur linux_c860_org/drivers/net/sha1dgst.c linux/drivers/net/sha1dgst.c
---- linux_c860_org/drivers/net/sha1dgst.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/net/sha1dgst.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,73 @@
-+/* crypto/sha/sha1dgst.c */
-+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+#if !defined(NO_SHA1) && !defined(NO_SHA)
-+
-+#undef SHA_0
-+#define SHA_1
-+
-+#include <openssl/opensslv.h>
-+
-+const char *SHA1_version="SHA1" OPENSSL_VERSION_PTEXT;
-+
-+/* The implementation is in ../md32_common.h */
-+
-+#include "sha_locl.h"
-+
-+#endif
-+
-diff -Nur linux_c860_org/drivers/net/sha_locl.h linux/drivers/net/sha_locl.h
---- linux_c860_org/drivers/net/sha_locl.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/net/sha_locl.h 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,473 @@
-+/* crypto/sha/sha_locl.h */
-+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+#ifndef __KERNEL__
-+#include <stdlib.h>
-+#include <string.h>
-+#endif
-+
-+#include <openssl/opensslconf.h>
-+#include <openssl/sha.h>
-+
-+#ifndef SHA_LONG_LOG2
-+#define SHA_LONG_LOG2 2 /* default to 32 bits */
-+#endif
-+
-+#define DATA_ORDER_IS_BIG_ENDIAN
-+
-+#define HASH_LONG SHA_LONG
-+#define HASH_LONG_LOG2 SHA_LONG_LOG2
-+#define HASH_CTX SHA_CTX
-+#define HASH_CBLOCK SHA_CBLOCK
-+#define HASH_LBLOCK SHA_LBLOCK
-+#define HASH_MAKE_STRING(c,s) do { \
-+ unsigned long ll; \
-+ ll=(c)->h0; HOST_l2c(ll,(s)); \
-+ ll=(c)->h1; HOST_l2c(ll,(s)); \
-+ ll=(c)->h2; HOST_l2c(ll,(s)); \
-+ ll=(c)->h3; HOST_l2c(ll,(s)); \
-+ ll=(c)->h4; HOST_l2c(ll,(s)); \
-+ } while (0)
-+
-+#if defined(SHA_0)
-+
-+# define HASH_UPDATE SHA_Update
-+# define HASH_TRANSFORM SHA_Transform
-+# define HASH_FINAL SHA_Final
-+# define HASH_INIT SHA_Init
-+# define HASH_BLOCK_HOST_ORDER sha_block_host_order
-+# define HASH_BLOCK_DATA_ORDER sha_block_data_order
-+# define Xupdate(a,ix,ia,ib,ic,id) (ix=(a)=(ia^ib^ic^id))
-+
-+ void sha_block_host_order (SHA_CTX *c, const void *p,int num);
-+ void sha_block_data_order (SHA_CTX *c, const void *p,int num);
-+
-+#elif defined(SHA_1)
-+
-+# define HASH_UPDATE SHA1_Update
-+# define HASH_TRANSFORM SHA1_Transform
-+# define HASH_FINAL SHA1_Final
-+# define HASH_INIT SHA1_Init
-+# define HASH_BLOCK_HOST_ORDER sha1_block_host_order
-+# define HASH_BLOCK_DATA_ORDER sha1_block_data_order
-+# if defined(__MWERKS__) && defined(__MC68K__)
-+ /* Metrowerks for Motorola fails otherwise:-( <appro@fy.chalmers.se> */
-+# define Xupdate(a,ix,ia,ib,ic,id) do { (a)=(ia^ib^ic^id); \
-+ ix=(a)=ROTATE((a),1); \
-+ } while (0)
-+# else
-+# define Xupdate(a,ix,ia,ib,ic,id) ( (a)=(ia^ib^ic^id), \
-+ ix=(a)=ROTATE((a),1) \
-+ )
-+# endif
-+
-+# ifdef SHA1_ASM
-+# if defined(__i386) || defined(_M_IX86) || defined(__INTEL__)
-+# define sha1_block_host_order sha1_block_asm_host_order
-+# define DONT_IMPLEMENT_BLOCK_HOST_ORDER
-+# define sha1_block_data_order sha1_block_asm_data_order
-+# define DONT_IMPLEMENT_BLOCK_DATA_ORDER
-+# define HASH_BLOCK_DATA_ORDER_ALIGNED sha1_block_asm_data_order
-+# endif
-+# endif
-+ void sha1_block_host_order (SHA_CTX *c, const void *p,int num);
-+ void sha1_block_data_order (SHA_CTX *c, const void *p,int num);
-+
-+#else
-+# error "Either SHA_0 or SHA_1 must be defined."
-+#endif
-+
-+#include "md32_common.h"
-+
-+#define INIT_DATA_h0 0x67452301UL
-+#define INIT_DATA_h1 0xefcdab89UL
-+#define INIT_DATA_h2 0x98badcfeUL
-+#define INIT_DATA_h3 0x10325476UL
-+#define INIT_DATA_h4 0xc3d2e1f0UL
-+
-+void HASH_INIT (SHA_CTX *c)
-+ {
-+ c->h0=INIT_DATA_h0;
-+ c->h1=INIT_DATA_h1;
-+ c->h2=INIT_DATA_h2;
-+ c->h3=INIT_DATA_h3;
-+ c->h4=INIT_DATA_h4;
-+ c->Nl=0;
-+ c->Nh=0;
-+ c->num=0;
-+ }
-+
-+#define K_00_19 0x5a827999UL
-+#define K_20_39 0x6ed9eba1UL
-+#define K_40_59 0x8f1bbcdcUL
-+#define K_60_79 0xca62c1d6UL
-+
-+/* As pointed out by Wei Dai <weidai@eskimo.com>, F() below can be
-+ * simplified to the code in F_00_19. Wei attributes these optimisations
-+ * to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
-+ * #define F(x,y,z) (((x) & (y)) | ((~(x)) & (z)))
-+ * I've just become aware of another tweak to be made, again from Wei Dai,
-+ * in F_40_59, (x&a)|(y&a) -> (x|y)&a
-+ */
-+#define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d))
-+#define F_20_39(b,c,d) ((b) ^ (c) ^ (d))
-+#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d)))
-+#define F_60_79(b,c,d) F_20_39(b,c,d)
-+
-+#define BODY_00_15(i,a,b,c,d,e,f,xi) \
-+ (f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
-+ (b)=ROTATE((b),30);
-+
-+#define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
-+ Xupdate(f,xi,xa,xb,xc,xd); \
-+ (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \
-+ (b)=ROTATE((b),30);
-+
-+#define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \
-+ Xupdate(f,xi,xa,xb,xc,xd); \
-+ (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
-+ (b)=ROTATE((b),30);
-+
-+#define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \
-+ Xupdate(f,xa,xa,xb,xc,xd); \
-+ (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \
-+ (b)=ROTATE((b),30);
-+
-+#define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \
-+ Xupdate(f,xa,xa,xb,xc,xd); \
-+ (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \
-+ (b)=ROTATE((b),30);
-+
-+#define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \
-+ Xupdate(f,xa,xa,xb,xc,xd); \
-+ (f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \
-+ (b)=ROTATE((b),30);
-+
-+#ifdef X
-+#undef X
-+#endif
-+#ifndef MD32_XARRAY
-+ /*
-+ * Originally X was an array. As it's automatic it's natural
-+ * to expect RISC compiler to accomodate at least part of it in
-+ * the register bank, isn't it? Unfortunately not all compilers
-+ * "find" this expectation reasonable:-( On order to make such
-+ * compilers generate better code I replace X[] with a bunch of
-+ * X0, X1, etc. See the function body below...
-+ * <appro@fy.chalmers.se>
-+ */
-+# define X(i) XX##i
-+#else
-+ /*
-+ * However! Some compilers (most notably HP C) get overwhelmed by
-+ * that many local variables so that we have to have the way to
-+ * fall down to the original behavior.
-+ */
-+# define X(i) XX[i]
-+#endif
-+
-+#ifndef DONT_IMPLEMENT_BLOCK_HOST_ORDER
-+void HASH_BLOCK_HOST_ORDER (SHA_CTX *c, const void *d, int num)
-+ {
-+ const SHA_LONG *W=d;
-+ register unsigned long A,B,C,D,E,T;
-+#ifndef MD32_XARRAY
-+ unsigned long XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
-+ XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
-+#else
-+ SHA_LONG XX[16];
-+#endif
-+
-+ A=c->h0;
-+ B=c->h1;
-+ C=c->h2;
-+ D=c->h3;
-+ E=c->h4;
-+
-+ for (;;)
-+ {
-+ BODY_00_15( 0,A,B,C,D,E,T,W[ 0]);
-+ BODY_00_15( 1,T,A,B,C,D,E,W[ 1]);
-+ BODY_00_15( 2,E,T,A,B,C,D,W[ 2]);
-+ BODY_00_15( 3,D,E,T,A,B,C,W[ 3]);
-+ BODY_00_15( 4,C,D,E,T,A,B,W[ 4]);
-+ BODY_00_15( 5,B,C,D,E,T,A,W[ 5]);
-+ BODY_00_15( 6,A,B,C,D,E,T,W[ 6]);
-+ BODY_00_15( 7,T,A,B,C,D,E,W[ 7]);
-+ BODY_00_15( 8,E,T,A,B,C,D,W[ 8]);
-+ BODY_00_15( 9,D,E,T,A,B,C,W[ 9]);
-+ BODY_00_15(10,C,D,E,T,A,B,W[10]);
-+ BODY_00_15(11,B,C,D,E,T,A,W[11]);
-+ BODY_00_15(12,A,B,C,D,E,T,W[12]);
-+ BODY_00_15(13,T,A,B,C,D,E,W[13]);
-+ BODY_00_15(14,E,T,A,B,C,D,W[14]);
-+ BODY_00_15(15,D,E,T,A,B,C,W[15]);
-+
-+ BODY_16_19(16,C,D,E,T,A,B,X( 0),W[ 0],W[ 2],W[ 8],W[13]);
-+ BODY_16_19(17,B,C,D,E,T,A,X( 1),W[ 1],W[ 3],W[ 9],W[14]);
-+ BODY_16_19(18,A,B,C,D,E,T,X( 2),W[ 2],W[ 4],W[10],W[15]);
-+ BODY_16_19(19,T,A,B,C,D,E,X( 3),W[ 3],W[ 5],W[11],X( 0));
-+
-+ BODY_20_31(20,E,T,A,B,C,D,X( 4),W[ 4],W[ 6],W[12],X( 1));
-+ BODY_20_31(21,D,E,T,A,B,C,X( 5),W[ 5],W[ 7],W[13],X( 2));
-+ BODY_20_31(22,C,D,E,T,A,B,X( 6),W[ 6],W[ 8],W[14],X( 3));
-+ BODY_20_31(23,B,C,D,E,T,A,X( 7),W[ 7],W[ 9],W[15],X( 4));
-+ BODY_20_31(24,A,B,C,D,E,T,X( 8),W[ 8],W[10],X( 0),X( 5));
-+ BODY_20_31(25,T,A,B,C,D,E,X( 9),W[ 9],W[11],X( 1),X( 6));
-+ BODY_20_31(26,E,T,A,B,C,D,X(10),W[10],W[12],X( 2),X( 7));
-+ BODY_20_31(27,D,E,T,A,B,C,X(11),W[11],W[13],X( 3),X( 8));
-+ BODY_20_31(28,C,D,E,T,A,B,X(12),W[12],W[14],X( 4),X( 9));
-+ BODY_20_31(29,B,C,D,E,T,A,X(13),W[13],W[15],X( 5),X(10));
-+ BODY_20_31(30,A,B,C,D,E,T,X(14),W[14],X( 0),X( 6),X(11));
-+ BODY_20_31(31,T,A,B,C,D,E,X(15),W[15],X( 1),X( 7),X(12));
-+
-+ BODY_32_39(32,E,T,A,B,C,D,X( 0),X( 2),X( 8),X(13));
-+ BODY_32_39(33,D,E,T,A,B,C,X( 1),X( 3),X( 9),X(14));
-+ BODY_32_39(34,C,D,E,T,A,B,X( 2),X( 4),X(10),X(15));
-+ BODY_32_39(35,B,C,D,E,T,A,X( 3),X( 5),X(11),X( 0));
-+ BODY_32_39(36,A,B,C,D,E,T,X( 4),X( 6),X(12),X( 1));
-+ BODY_32_39(37,T,A,B,C,D,E,X( 5),X( 7),X(13),X( 2));
-+ BODY_32_39(38,E,T,A,B,C,D,X( 6),X( 8),X(14),X( 3));
-+ BODY_32_39(39,D,E,T,A,B,C,X( 7),X( 9),X(15),X( 4));
-+
-+ BODY_40_59(40,C,D,E,T,A,B,X( 8),X(10),X( 0),X( 5));
-+ BODY_40_59(41,B,C,D,E,T,A,X( 9),X(11),X( 1),X( 6));
-+ BODY_40_59(42,A,B,C,D,E,T,X(10),X(12),X( 2),X( 7));
-+ BODY_40_59(43,T,A,B,C,D,E,X(11),X(13),X( 3),X( 8));
-+ BODY_40_59(44,E,T,A,B,C,D,X(12),X(14),X( 4),X( 9));
-+ BODY_40_59(45,D,E,T,A,B,C,X(13),X(15),X( 5),X(10));
-+ BODY_40_59(46,C,D,E,T,A,B,X(14),X( 0),X( 6),X(11));
-+ BODY_40_59(47,B,C,D,E,T,A,X(15),X( 1),X( 7),X(12));
-+ BODY_40_59(48,A,B,C,D,E,T,X( 0),X( 2),X( 8),X(13));
-+ BODY_40_59(49,T,A,B,C,D,E,X( 1),X( 3),X( 9),X(14));
-+ BODY_40_59(50,E,T,A,B,C,D,X( 2),X( 4),X(10),X(15));
-+ BODY_40_59(51,D,E,T,A,B,C,X( 3),X( 5),X(11),X( 0));
-+ BODY_40_59(52,C,D,E,T,A,B,X( 4),X( 6),X(12),X( 1));
-+ BODY_40_59(53,B,C,D,E,T,A,X( 5),X( 7),X(13),X( 2));
-+ BODY_40_59(54,A,B,C,D,E,T,X( 6),X( 8),X(14),X( 3));
-+ BODY_40_59(55,T,A,B,C,D,E,X( 7),X( 9),X(15),X( 4));
-+ BODY_40_59(56,E,T,A,B,C,D,X( 8),X(10),X( 0),X( 5));
-+ BODY_40_59(57,D,E,T,A,B,C,X( 9),X(11),X( 1),X( 6));
-+ BODY_40_59(58,C,D,E,T,A,B,X(10),X(12),X( 2),X( 7));
-+ BODY_40_59(59,B,C,D,E,T,A,X(11),X(13),X( 3),X( 8));
-+
-+ BODY_60_79(60,A,B,C,D,E,T,X(12),X(14),X( 4),X( 9));
-+ BODY_60_79(61,T,A,B,C,D,E,X(13),X(15),X( 5),X(10));
-+ BODY_60_79(62,E,T,A,B,C,D,X(14),X( 0),X( 6),X(11));
-+ BODY_60_79(63,D,E,T,A,B,C,X(15),X( 1),X( 7),X(12));
-+ BODY_60_79(64,C,D,E,T,A,B,X( 0),X( 2),X( 8),X(13));
-+ BODY_60_79(65,B,C,D,E,T,A,X( 1),X( 3),X( 9),X(14));
-+ BODY_60_79(66,A,B,C,D,E,T,X( 2),X( 4),X(10),X(15));
-+ BODY_60_79(67,T,A,B,C,D,E,X( 3),X( 5),X(11),X( 0));
-+ BODY_60_79(68,E,T,A,B,C,D,X( 4),X( 6),X(12),X( 1));
-+ BODY_60_79(69,D,E,T,A,B,C,X( 5),X( 7),X(13),X( 2));
-+ BODY_60_79(70,C,D,E,T,A,B,X( 6),X( 8),X(14),X( 3));
-+ BODY_60_79(71,B,C,D,E,T,A,X( 7),X( 9),X(15),X( 4));
-+ BODY_60_79(72,A,B,C,D,E,T,X( 8),X(10),X( 0),X( 5));
-+ BODY_60_79(73,T,A,B,C,D,E,X( 9),X(11),X( 1),X( 6));
-+ BODY_60_79(74,E,T,A,B,C,D,X(10),X(12),X( 2),X( 7));
-+ BODY_60_79(75,D,E,T,A,B,C,X(11),X(13),X( 3),X( 8));
-+ BODY_60_79(76,C,D,E,T,A,B,X(12),X(14),X( 4),X( 9));
-+ BODY_60_79(77,B,C,D,E,T,A,X(13),X(15),X( 5),X(10));
-+ BODY_60_79(78,A,B,C,D,E,T,X(14),X( 0),X( 6),X(11));
-+ BODY_60_79(79,T,A,B,C,D,E,X(15),X( 1),X( 7),X(12));
-+
-+ c->h0=(c->h0+E)&0xffffffffL;
-+ c->h1=(c->h1+T)&0xffffffffL;
-+ c->h2=(c->h2+A)&0xffffffffL;
-+ c->h3=(c->h3+B)&0xffffffffL;
-+ c->h4=(c->h4+C)&0xffffffffL;
-+
-+ if (--num <= 0) break;
-+
-+ A=c->h0;
-+ B=c->h1;
-+ C=c->h2;
-+ D=c->h3;
-+ E=c->h4;
-+
-+ W+=SHA_LBLOCK;
-+ }
-+ }
-+#endif
-+
-+#ifndef DONT_IMPLEMENT_BLOCK_DATA_ORDER
-+void HASH_BLOCK_DATA_ORDER (SHA_CTX *c, const void *p, int num)
-+ {
-+ const unsigned char *data=p;
-+ register unsigned long A,B,C,D,E,T,l;
-+#ifndef MD32_XARRAY
-+ unsigned long XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7,
-+ XX8, XX9,XX10,XX11,XX12,XX13,XX14,XX15;
-+#else
-+ SHA_LONG XX[16];
-+#endif
-+
-+ A=c->h0;
-+ B=c->h1;
-+ C=c->h2;
-+ D=c->h3;
-+ E=c->h4;
-+
-+ for (;;)
-+ {
-+
-+ HOST_c2l(data,l); X( 0)=l; HOST_c2l(data,l); X( 1)=l;
-+ BODY_00_15( 0,A,B,C,D,E,T,X( 0)); HOST_c2l(data,l); X( 2)=l;
-+ BODY_00_15( 1,T,A,B,C,D,E,X( 1)); HOST_c2l(data,l); X( 3)=l;
-+ BODY_00_15( 2,E,T,A,B,C,D,X( 2)); HOST_c2l(data,l); X( 4)=l;
-+ BODY_00_15( 3,D,E,T,A,B,C,X( 3)); HOST_c2l(data,l); X( 5)=l;
-+ BODY_00_15( 4,C,D,E,T,A,B,X( 4)); HOST_c2l(data,l); X( 6)=l;
-+ BODY_00_15( 5,B,C,D,E,T,A,X( 5)); HOST_c2l(data,l); X( 7)=l;
-+ BODY_00_15( 6,A,B,C,D,E,T,X( 6)); HOST_c2l(data,l); X( 8)=l;
-+ BODY_00_15( 7,T,A,B,C,D,E,X( 7)); HOST_c2l(data,l); X( 9)=l;
-+ BODY_00_15( 8,E,T,A,B,C,D,X( 8)); HOST_c2l(data,l); X(10)=l;
-+ BODY_00_15( 9,D,E,T,A,B,C,X( 9)); HOST_c2l(data,l); X(11)=l;
-+ BODY_00_15(10,C,D,E,T,A,B,X(10)); HOST_c2l(data,l); X(12)=l;
-+ BODY_00_15(11,B,C,D,E,T,A,X(11)); HOST_c2l(data,l); X(13)=l;
-+ BODY_00_15(12,A,B,C,D,E,T,X(12)); HOST_c2l(data,l); X(14)=l;
-+ BODY_00_15(13,T,A,B,C,D,E,X(13)); HOST_c2l(data,l); X(15)=l;
-+ BODY_00_15(14,E,T,A,B,C,D,X(14));
-+ BODY_00_15(15,D,E,T,A,B,C,X(15));
-+
-+ BODY_16_19(16,C,D,E,T,A,B,X( 0),X( 0),X( 2),X( 8),X(13));
-+ BODY_16_19(17,B,C,D,E,T,A,X( 1),X( 1),X( 3),X( 9),X(14));
-+ BODY_16_19(18,A,B,C,D,E,T,X( 2),X( 2),X( 4),X(10),X(15));
-+ BODY_16_19(19,T,A,B,C,D,E,X( 3),X( 3),X( 5),X(11),X( 0));
-+
-+ BODY_20_31(20,E,T,A,B,C,D,X( 4),X( 4),X( 6),X(12),X( 1));
-+ BODY_20_31(21,D,E,T,A,B,C,X( 5),X( 5),X( 7),X(13),X( 2));
-+ BODY_20_31(22,C,D,E,T,A,B,X( 6),X( 6),X( 8),X(14),X( 3));
-+ BODY_20_31(23,B,C,D,E,T,A,X( 7),X( 7),X( 9),X(15),X( 4));
-+ BODY_20_31(24,A,B,C,D,E,T,X( 8),X( 8),X(10),X( 0),X( 5));
-+ BODY_20_31(25,T,A,B,C,D,E,X( 9),X( 9),X(11),X( 1),X( 6));
-+ BODY_20_31(26,E,T,A,B,C,D,X(10),X(10),X(12),X( 2),X( 7));
-+ BODY_20_31(27,D,E,T,A,B,C,X(11),X(11),X(13),X( 3),X( 8));
-+ BODY_20_31(28,C,D,E,T,A,B,X(12),X(12),X(14),X( 4),X( 9));
-+ BODY_20_31(29,B,C,D,E,T,A,X(13),X(13),X(15),X( 5),X(10));
-+ BODY_20_31(30,A,B,C,D,E,T,X(14),X(14),X( 0),X( 6),X(11));
-+ BODY_20_31(31,T,A,B,C,D,E,X(15),X(15),X( 1),X( 7),X(12));
-+
-+ BODY_32_39(32,E,T,A,B,C,D,X( 0),X( 2),X( 8),X(13));
-+ BODY_32_39(33,D,E,T,A,B,C,X( 1),X( 3),X( 9),X(14));
-+ BODY_32_39(34,C,D,E,T,A,B,X( 2),X( 4),X(10),X(15));
-+ BODY_32_39(35,B,C,D,E,T,A,X( 3),X( 5),X(11),X( 0));
-+ BODY_32_39(36,A,B,C,D,E,T,X( 4),X( 6),X(12),X( 1));
-+ BODY_32_39(37,T,A,B,C,D,E,X( 5),X( 7),X(13),X( 2));
-+ BODY_32_39(38,E,T,A,B,C,D,X( 6),X( 8),X(14),X( 3));
-+ BODY_32_39(39,D,E,T,A,B,C,X( 7),X( 9),X(15),X( 4));
-+
-+ BODY_40_59(40,C,D,E,T,A,B,X( 8),X(10),X( 0),X( 5));
-+ BODY_40_59(41,B,C,D,E,T,A,X( 9),X(11),X( 1),X( 6));
-+ BODY_40_59(42,A,B,C,D,E,T,X(10),X(12),X( 2),X( 7));
-+ BODY_40_59(43,T,A,B,C,D,E,X(11),X(13),X( 3),X( 8));
-+ BODY_40_59(44,E,T,A,B,C,D,X(12),X(14),X( 4),X( 9));
-+ BODY_40_59(45,D,E,T,A,B,C,X(13),X(15),X( 5),X(10));
-+ BODY_40_59(46,C,D,E,T,A,B,X(14),X( 0),X( 6),X(11));
-+ BODY_40_59(47,B,C,D,E,T,A,X(15),X( 1),X( 7),X(12));
-+ BODY_40_59(48,A,B,C,D,E,T,X( 0),X( 2),X( 8),X(13));
-+ BODY_40_59(49,T,A,B,C,D,E,X( 1),X( 3),X( 9),X(14));
-+ BODY_40_59(50,E,T,A,B,C,D,X( 2),X( 4),X(10),X(15));
-+ BODY_40_59(51,D,E,T,A,B,C,X( 3),X( 5),X(11),X( 0));
-+ BODY_40_59(52,C,D,E,T,A,B,X( 4),X( 6),X(12),X( 1));
-+ BODY_40_59(53,B,C,D,E,T,A,X( 5),X( 7),X(13),X( 2));
-+ BODY_40_59(54,A,B,C,D,E,T,X( 6),X( 8),X(14),X( 3));
-+ BODY_40_59(55,T,A,B,C,D,E,X( 7),X( 9),X(15),X( 4));
-+ BODY_40_59(56,E,T,A,B,C,D,X( 8),X(10),X( 0),X( 5));
-+ BODY_40_59(57,D,E,T,A,B,C,X( 9),X(11),X( 1),X( 6));
-+ BODY_40_59(58,C,D,E,T,A,B,X(10),X(12),X( 2),X( 7));
-+ BODY_40_59(59,B,C,D,E,T,A,X(11),X(13),X( 3),X( 8));
-+
-+ BODY_60_79(60,A,B,C,D,E,T,X(12),X(14),X( 4),X( 9));
-+ BODY_60_79(61,T,A,B,C,D,E,X(13),X(15),X( 5),X(10));
-+ BODY_60_79(62,E,T,A,B,C,D,X(14),X( 0),X( 6),X(11));
-+ BODY_60_79(63,D,E,T,A,B,C,X(15),X( 1),X( 7),X(12));
-+ BODY_60_79(64,C,D,E,T,A,B,X( 0),X( 2),X( 8),X(13));
-+ BODY_60_79(65,B,C,D,E,T,A,X( 1),X( 3),X( 9),X(14));
-+ BODY_60_79(66,A,B,C,D,E,T,X( 2),X( 4),X(10),X(15));
-+ BODY_60_79(67,T,A,B,C,D,E,X( 3),X( 5),X(11),X( 0));
-+ BODY_60_79(68,E,T,A,B,C,D,X( 4),X( 6),X(12),X( 1));
-+ BODY_60_79(69,D,E,T,A,B,C,X( 5),X( 7),X(13),X( 2));
-+ BODY_60_79(70,C,D,E,T,A,B,X( 6),X( 8),X(14),X( 3));
-+ BODY_60_79(71,B,C,D,E,T,A,X( 7),X( 9),X(15),X( 4));
-+ BODY_60_79(72,A,B,C,D,E,T,X( 8),X(10),X( 0),X( 5));
-+ BODY_60_79(73,T,A,B,C,D,E,X( 9),X(11),X( 1),X( 6));
-+ BODY_60_79(74,E,T,A,B,C,D,X(10),X(12),X( 2),X( 7));
-+ BODY_60_79(75,D,E,T,A,B,C,X(11),X(13),X( 3),X( 8));
-+ BODY_60_79(76,C,D,E,T,A,B,X(12),X(14),X( 4),X( 9));
-+ BODY_60_79(77,B,C,D,E,T,A,X(13),X(15),X( 5),X(10));
-+ BODY_60_79(78,A,B,C,D,E,T,X(14),X( 0),X( 6),X(11));
-+ BODY_60_79(79,T,A,B,C,D,E,X(15),X( 1),X( 7),X(12));
-+
-+ c->h0=(c->h0+E)&0xffffffffL;
-+ c->h1=(c->h1+T)&0xffffffffL;
-+ c->h2=(c->h2+A)&0xffffffffL;
-+ c->h3=(c->h3+B)&0xffffffffL;
-+ c->h4=(c->h4+C)&0xffffffffL;
-+
-+ if (--num <= 0) break;
-+
-+ A=c->h0;
-+ B=c->h1;
-+ C=c->h2;
-+ D=c->h3;
-+ E=c->h4;
-+
-+ }
-+ }
-+#endif
-diff -Nur linux_c860_org/drivers/pcmcia/cs.c linux/drivers/pcmcia/cs.c
---- linux_c860_org/drivers/pcmcia/cs.c 2003-02-27 13:28:33.000000000 +0900
-+++ linux/drivers/pcmcia/cs.c 2004-06-10 21:09:10.000000000 +0900
-@@ -35,6 +35,8 @@
- 30-Jul-2002 Lineo Japan, Inc. for 2.4.18
- 12-Dec-2002 Sharp Corporation for Poodle and Corgi
- 07-Feb-2003 Sharp Corporation
-+ 08-Jan-2004 Sharp Corporation for Tosa
-+ 26-Feb-2004 Lineo Solutions, Inc. 2 slot support
-
- ======================================================================*/
-
-@@ -73,6 +75,8 @@
- #include <asm/arch/keyboard_poodle.h>
- #elif defined(CONFIG_ARCH_PXA_CORGI)
- #include <asm/arch/keyboard_corgi.h>
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+#include <asm/arch/keyboard_tosa.h>
- #endif
- #include <asm/sharp_char.h>
- #include <asm/sharp_keycode.h>
-@@ -124,7 +128,11 @@
- INT_MODULE_PARM(shutdown_delay, 3); /* centiseconds */
- #ifdef CONFIG_ARCH_SHARP_SL
- //INT_MODULE_PARM(vcc_settle, 2); /* SL-5600@2 */
-+#if defined (CONFIG_ARCH_PXA_TOSA)
-+INT_MODULE_PARM(vcc_settle, 30); /* SL-6000 */
-+#else
- INT_MODULE_PARM(vcc_settle, 10); /* SL-C700+GW-CF11H@10 */
-+#endif
- INT_MODULE_PARM(reset_time, 1000);
- INT_MODULE_PARM(unreset_delay, 3);
- INT_MODULE_PARM(unreset_check, 1);
-@@ -490,6 +498,15 @@
- schedule_timeout( (n_cs * HZ + 99) / 100);
- }
-
-+#if defined (CONFIG_ARCH_PXA_TOSA)
-+static void cs_sleep2(unsigned int n_cs)
-+{
-+ current->state = TASK_UNINTERRUPTIBLE;
-+ schedule_timeout( (n_cs * HZ + 99) / 100);
-+}
-+
-+#endif
-+
- static void shutdown_socket(socket_info_t *s)
- {
- client_t **c;
-@@ -582,16 +599,45 @@
- #endif /* CONFIG_SABINAL_DISCOVERY */
-
-
--#if defined (CONFIG_ARCH_PXA_POODLE) || defined (CONFIG_ARCH_PXA_CORGI)
-+#if defined (CONFIG_ARCH_PXA_POODLE) || defined (CONFIG_ARCH_PXA_CORGI) || defined (CONFIG_ARCH_PXA_TOSA)
- {
- extern int sharpsl_main_battery;
- extern int sharpsl_main_bk_flag;
-+#if defined (CONFIG_ARCH_PXA_TOSA)
-+ extern int sharpsl_jacket_exist;
-+ extern int sharpsl_jacket_batt_exist;
-+ extern int sharpsl_jacket_battery;
-+#endif
-
- sharpsl_kick_battery_check(0,1,1); // check battery and wait 10msec
-
- if ( ( sharpsl_main_battery == 0x7F ) || ( sharpsl_main_battery == 0x02 ) ) {
- printk(KERN_ERR "cs: Main battery is critical low."
- " (%d)\n", sharpsl_main_battery);
-+#if defined (CONFIG_ARCH_PXA_TOSA)
-+ {
-+ int do_off = 0;
-+
-+ if(sharpsl_jacket_exist && sharpsl_jacket_batt_exist){
-+ if( sharpsl_jacket_battery == 0x7F || sharpsl_jacket_battery == 0x02 ){
-+ printk(KERN_ERR "cs: Jacket battery is critical low."
-+ " (%d)\n", sharpsl_jacket_battery);
-+ do_off = 1;
-+ }
-+ }else{
-+ do_off = 1;
-+ }
-+ if(do_off){
-+ if ( sharpsl_main_bk_flag ) {
-+ handle_scancode(SLKEY_OFF|KBDOWN , 1);
-+ mdelay(30);
-+ handle_scancode(SLKEY_OFF|KBUP , 0);
-+ }
-+ ret = 0;
-+ goto out;
-+ }
-+ }
-+#else
- if ( sharpsl_main_bk_flag ) {
- handle_scancode(SLKEY_OFF|KBDOWN , 1);
- mdelay(30);
-@@ -599,6 +645,7 @@
- }
- ret = 0;
- goto out;
-+#endif
- }
- }
- #endif
-@@ -644,17 +691,52 @@
- printk(KERN_NOTICE "cs: unsupported card type detected!\n");
- #endif
- }
-+
- set_socket(s, &s->socket);
-+#if defined (CONFIG_ARCH_PXA_TOSA)
-+ //printk(":start %d %d\n",jiffies,vcc_settle);
-+ cs_sleep2(vcc_settle);
-+ //cs_sleep(vcc_settle);
-+ //printk(":end %d\n",jiffies);
-+#else
- cs_sleep(vcc_settle);
-+#endif
- reset_socket(s);
-
--#if defined (CONFIG_ARCH_PXA_POODLE) || defined (CONFIG_ARCH_PXA_CORGI)
-+#if defined (CONFIG_ARCH_PXA_POODLE) || defined (CONFIG_ARCH_PXA_CORGI) || defined (CONFIG_ARCH_PXA_TOSA)
- {
- extern int sharpsl_main_battery;
- extern int sharpsl_main_bk_flag;
-+#if defined (CONFIG_ARCH_PXA_TOSA)
-+ extern int sharpsl_jacket_exist;
-+ extern int sharpsl_jacket_batt_exist;
-+ extern int sharpsl_jacket_battery;
-+#endif
-
- sharpsl_kick_battery_check(0,0,1); // check battery and wait 10msec
-
-+#if defined (CONFIG_ARCH_PXA_TOSA)
-+ if ( sharpsl_main_bk_flag && ( ( sharpsl_main_battery == 0x7F ) || ( sharpsl_main_battery == 0x02 ) ) ) {
-+ int do_remove = 0;
-+ if ( sharpsl_jacket_exist && sharpsl_jacket_batt_exist ) {
-+ if( sharpsl_jacket_battery == 0x7F || sharpsl_jacket_battery == 0x02 ){
-+ do_remove = 1;
-+ }
-+ }else{
-+ do_remove = 1;
-+ }
-+ if(do_remove){
-+ s->socket.Vcc = s->socket.Vpp = 0;
-+ s->state &= ~SOCKET_PRESENT;
-+ set_socket(s, &s->socket);
-+ cs_sleep(vcc_settle);
-+ reset_socket(s);
-+ send_event(s, CS_EVENT_CARD_REMOVAL, CS_EVENT_PRI_HIGH);
-+ ret = 0;
-+ goto out;
-+ }
-+ }
-+#else
- if ( sharpsl_main_bk_flag && ( ( sharpsl_main_battery == 0x7F ) || ( sharpsl_main_battery == 0x02 ) ) ) {
- s->socket.Vcc = s->socket.Vpp = 0;
- s->state &= ~SOCKET_PRESENT;
-@@ -665,6 +747,7 @@
- ret = 0;
- goto out;
- }
-+#endif
- }
- #endif
- ret = 1;
-@@ -701,8 +784,8 @@
- (SOCKET_SETUP_PENDING|SOCKET_SUSPEND|SOCKET_RESET_PENDING)
-
- #ifdef CONFIG_ARCH_SHARP_SL
--int ide_resume_handling = 0;
--int pcmcia_resume_handling = 0;
-+int ide_resume_handling[2] = { 0, 0 };
-+static int pcmcia_resume_handling = 0;
- #endif
-
- static void unreset_socket(socket_info_t *s)
-@@ -731,21 +814,21 @@
- s->state &= ~EVENT_MASK;
- #ifdef CONFIG_ARCH_SHARP_SL
- if (verify_cis_cache(s) != 0) {
-- if (is_pcmcia_card_present(0))
-- ide_resume_handling = 2;
-+ if (is_pcmcia_card_present(s->cap.pci_irq))
-+ ide_resume_handling[s->sock] = 2;
- parse_events(s, SS_DETECT);
- } else {
- cisparse_t parse;
- send_event(s, CS_EVENT_PM_RESUME, CS_EVENT_PRI_LOW);
- read_tuple(s->clients, CISTPL_FUNCID, &parse);
- #ifdef CONFIG_IDE
-- ide_resume_handling = 1;
-+ ide_resume_handling[s->sock] = 1;
- if (parse.funcid.func == CISTPL_FUNCID_FIXED &&
-- proc_ide_verify_identify() != 0) {
-- ide_resume_handling = 2;
-+ proc_ide_verify_identify(s->sock) != 0) {
-+ ide_resume_handling[s->sock] = 2;
- parse_events(s, SS_DETECT);
- } else {
-- ide_resume_handling = 0;
-+ ide_resume_handling[s->sock] = 0;
- }
- #endif
- /* power off serial card */
-@@ -854,7 +937,7 @@
- s->socket.flags |= SS_DEBOUNCED;
- if (setup_socket(s) == 0){
- s->state &= ~SOCKET_SETUP_PENDING;
--#if defined(CONFIG_SABINAL_DISCOVERY) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_POODLE)
-+#if defined(CONFIG_SABINAL_DISCOVERY) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_TOSA)
- /* If power-on failed in resume, then card eject. */
- if( s->state & SOCKET_SUSPEND )
- do_shutdown(s);
-@@ -960,6 +1043,19 @@
- return 0;
- } /* handle_pm_event */
-
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+void force_cardslot_suspend( int num )
-+{
-+ int i;
-+ socket_info_t *s;
-+ s = socket_table [num];
-+ if (s && !s->use_bus_pm) {
-+ //pcmcia_suspend_socket (socket_table [num]);
-+ suspend_socket (socket_table [num]);
-+ }
-+}
-+#endif
-+
- /*======================================================================
-
- Special stuff for managing IO windows, because they are scarce.
-@@ -2001,6 +2097,12 @@
- if (!req)
- return CS_UNSUPPORTED_MODE;
- c = CONFIG(handle);
-+#ifdef CONFIG_ARCH_SHARP_SL
-+ if(c == NULL) {
-+ printk("%s: c is NULL\n",__func__);
-+ return CS_BAD_SOCKET;
-+ }
-+#endif
- if (c->state & CONFIG_LOCKED)
- return CS_CONFIGURATION_LOCKED;
- if (c->state & CONFIG_IO_REQ)
-@@ -2272,7 +2374,7 @@
- return CS_IN_USE;
-
- DEBUG(1, "cs: waking up socket %d\n", i);
--#if defined(CONFIG_SABINAL_DISCOVERY) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_POODLE)
-+#if defined(CONFIG_SABINAL_DISCOVERY) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_TOSA)
- /* If power-on failed, then card eject. */
- if( setup_socket(s) == 0 )
- do_shutdown(s);
-diff -Nur linux_c860_org/drivers/pcmcia/pxa/Makefile linux/drivers/pcmcia/pxa/Makefile
---- linux_c860_org/drivers/pcmcia/pxa/Makefile 2002-08-29 12:26:51.000000000 +0900
-+++ linux/drivers/pcmcia/pxa/Makefile 2004-06-10 21:09:10.000000000 +0900
-@@ -16,6 +16,7 @@
- pxa_cs-objs-$(CONFIG_SABINAL_DISCOVERY) += pxa_sharpsl.o
- pxa_cs-objs-$(CONFIG_ARCH_PXA_POODLE) += pxa_sharpsl.o
- pxa_cs-objs-$(CONFIG_ARCH_PXA_CORGI) += pxa_sharpsl.o
-+pxa_cs-objs-$(CONFIG_ARCH_PXA_TOSA) += pxa_sharpsl.o
-
- obj-$(CONFIG_PCMCIA_PXA) += $(pxa_cs-objs-y)
-
-diff -Nur linux_c860_org/drivers/pcmcia/pxa/pxa.c linux/drivers/pcmcia/pxa/pxa.c
---- linux_c860_org/drivers/pcmcia/pxa/pxa.c 2003-01-14 12:07:55.000000000 +0900
-+++ linux/drivers/pcmcia/pxa/pxa.c 2004-06-10 21:09:10.000000000 +0900
-@@ -14,6 +14,7 @@
- * ChangLog:
- * 12-Dec-2002 Lineo Japan, Inc.
- * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
-+ * 26-Feb-2004 Lineo Solutions, Inc. Tosa and 2 slot support
- */
-
- /*======================================================================
-@@ -170,7 +171,7 @@
- #endif
-
- #ifdef CONFIG_ARCH_SHARP_SL
-- u8 first = 1;
-+ static u8 first[2] = {1, 1};
- u8 force_8bit_access_check_done = 0;
- #endif
-
-@@ -253,6 +254,8 @@
- pcmcia_low_level=&sharpsl_pcmcia_ops;
- } else if( machine_is_corgi()){
- pcmcia_low_level=&sharpsl_pcmcia_ops;
-+ } else if( machine_is_tosa() ) {
-+ pcmcia_low_level=&sharpsl_pcmcia_ops;
- }
-
- if (!pcmcia_low_level) {
-@@ -415,17 +418,20 @@
-
- #ifdef CONFIG_ARCH_SHARP_SL
- printk("pxa_pcmcia_init(%d)\n",sock);
-- if(!first){
-+ if(!first[sock]){
- socket_state_t state;
- pxa_pcmcia_get_socket(sock, &state);
- state.flags &= ~SS_OUTPUT_ENA;
- state.Vcc = state.Vpp = 0;
- pxa_pcmcia_set_socket(sock, &state);
- } else {
-- first = 0;
-+ first[sock] = 0;
- }
- set_GPIO_mode(GPIO53_nPCE_2_MD); // reset force 8bit access.
- force_8bit_access_check_done = 0;
-+
-+ if (pcmcia_low_level->socket_init)
-+ return pcmcia_low_level->socket_init(sock);
- #endif
- return 0;
- }
-diff -Nur linux_c860_org/drivers/pcmcia/pxa/pxa_sharpsl.c linux/drivers/pcmcia/pxa/pxa_sharpsl.c
---- linux_c860_org/drivers/pcmcia/pxa/pxa_sharpsl.c 2003-01-14 12:07:55.000000000 +0900
-+++ linux/drivers/pcmcia/pxa/pxa_sharpsl.c 2004-06-10 21:09:10.000000000 +0900
-@@ -16,6 +16,7 @@
- *
- * ChangLog:
- * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
-+ * 26-Feb-2004 Lineo Solutions, Inc. 2 slot support for Tosa
- */
- #include <linux/config.h>
- #include <linux/kernel.h>
-@@ -36,7 +37,11 @@
- #include <asm/sharp_apm.h>
-
- #include <linux/delay.h>
--
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+#include <asm/arch/keyboard_tosa.h>
-+#include <asm/sharp_char.h>
-+#include <asm/sharp_keycode.h>
-+#endif
- //#define SHARPSL_PCMCIA_DEBUG
-
- #ifdef CONFIG_SABINAL_DISCOVERY
-@@ -73,9 +78,15 @@
- #define RESET_DONE 0x0001
- #endif
-
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+extern void set_jacketslot_error( int ); // tosa_battery.c
-+extern int current_jacketslot_error(void);
-+extern void force_cardslot_suspend(int num); // ../cs.c
-+#endif
-+
- void sharpsl_pcmcia_init_reset(void)
- {
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- #define SCP_INIT_DATA(adr,dat) (((adr)<<16)|(dat))
- #define SCP_INIT_DATA_END ((unsigned long)-1)
- static const unsigned long scp_init[] =
-@@ -99,6 +110,15 @@
- keep_vs[0] = NO_KEEP_VS;
- keep_rd[0] = 0;
- #endif
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ for(i=0; scp_init[i] != SCP_INIT_DATA_END; i++)
-+ {
-+ int adr = scp_init[i] >> 16;
-+ SCP_JC_REG(adr) = scp_init[i] & 0xFFFF;
-+ }
-+ keep_vs[1] = NO_KEEP_VS;
-+ keep_rd[1] = 0;
-+#endif
- }
-
- static void sharpsl_cf_status_change(int irq, void *dev, struct pt_regs *regs){
-@@ -167,10 +187,16 @@
- /* set GPIO_CF_CD & GPIO_CF_IRQ as inputs */
- GPDR(GPIO_CF_CD) &= ~GPIO_bit(GPIO_CF_CD);
- GPDR(GPIO_CF_IRQ) &= ~GPIO_bit(GPIO_CF_IRQ);
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ GPDR(GPIO_JC_CF_IRQ) &= ~GPIO_bit(GPIO_JC_CF_IRQ);
-+#endif
-
- /* Set transition detect */
- set_GPIO_IRQ_edge( GPIO_CF_CD, GPIO_FALLING_EDGE );
- set_GPIO_IRQ_edge( GPIO_CF_IRQ, GPIO_FALLING_EDGE );
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ set_GPIO_IRQ_edge( GPIO_JC_CF_IRQ, GPIO_FALLING_EDGE );
-+#endif
-
- /* Register interrupts */
- irq = IRQ_GPIO_CF_CD;
-@@ -181,6 +207,10 @@
- /* enable interrupt */
- SCP_REG_IMR = 0x00C0;
- SCP_REG_MCR = 0x0101;
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ SCP_JC_REG_IMR = 0x00C0;
-+ SCP_JC_REG_MCR = 0x0101;
-+#endif
- keep_vs[0] = keep_vs[1] = NO_KEEP_VS;
-
- /* There's only one slot, but it's "Slot 0": */
-@@ -240,6 +270,20 @@
- is16 = (ASIC3_GPIO_PSTS_D & CF_IOIS) ? 0 : 1;
- #else
- cpr = SCP_REG_CPR;
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ if( (cpr & 0x0080) && ((cpr & 0x8040) != 0x8040) ){
-+ extern int sharpsl_main_bk_flag;
-+
-+ printk(KERN_ERR "%s(): CPR=%04X, Low voltage!\n",
-+ __FUNCTION__, cpr);
-+ if ( sharpsl_main_bk_flag ) {
-+ handle_scancode(SLKEY_OFF|KBDOWN , 1);
-+ mdelay(30);
-+ handle_scancode(SLKEY_OFF|KBUP , 0);
-+ mdelay(30);
-+ }
-+ }
-+#endif
- //SCP_REG_CDR = 0x0002;
- SCP_REG_IRM = 0x00FF;
- SCP_REG_ISR = 0x0000;
-@@ -277,9 +321,67 @@
- state_array->state[0].vs_Xv = (csr & 0x0080)? 0:1;
-
- if( (cpr & 0x0080) && ((cpr & 0x8040) != 0x8040) ){
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+#if 0
-+ if (!current_cardslot_error(0)) {
-+ force_cardslot_suspend(0);
-+ }
-+#endif
-+#else
- printk(KERN_ERR "%s(): CPR=%04X, Low voltage!\n",
- __FUNCTION__, cpr);
-+#endif
- }
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ cpr = SCP_JC_REG_CPR;
-+ //SCP_REG_CDR = 0x0002;
-+ SCP_JC_REG_IRM = 0x00FF;
-+ SCP_JC_REG_ISR = 0x0000;
-+ SCP_JC_REG_IRM = 0x0000;
-+ csr = SCP_JC_REG_CSR;
-+ if( csr & 0x0004 ){
-+ /* card eject */
-+ SCP_JC_REG_CDR = 0x0000;
-+ keep_vs[1] = NO_KEEP_VS;
-+ }
-+ else if( !(keep_vs[1] & NO_KEEP_VS) ){
-+ /* keep vs1,vs2 */
-+ SCP_JC_REG_CDR = 0x0000;
-+ csr |= keep_vs[1];
-+ }
-+ else if( cpr & 0x0003 ){
-+ /* power on */
-+ SCP_JC_REG_CDR = 0x0000;
-+ keep_vs[1] = (csr & 0x00C0);
-+ }
-+ else{ /* card detect */
-+ SCP_JC_REG_CDR = 0x0002;
-+ }
-+
-+#ifdef SHARPSL_PCMCIA_DEBUG
-+ printk("%s(): slot1 cpr=%04X, csr=%04X\n", __FUNCTION__, cpr, csr);
-+#endif
-+
-+ state_array->state[1].detect = (csr & 0x0004)? 0:1;
-+ state_array->state[1].ready = (csr & 0x0002)? 1:0;
-+ state_array->state[1].bvd1 = (csr & 0x0010)? 1:0;
-+ state_array->state[1].bvd2 = (csr & 0x0020)? 1:0;
-+ state_array->state[1].wrprot = (csr & 0x0008)? 1:0;
-+ state_array->state[1].vs_3v = (csr & 0x0040)? 0:1;
-+ state_array->state[1].vs_Xv = (csr & 0x0080)? 0:1;
-+
-+ if( (cpr & 0x0080) && ((cpr & 0x8040) != 0x8040) ){
-+#if 0
-+ printk(KERN_ERR "%s(): slot1 CPR=%04X, Low voltage!\n",
-+ __FUNCTION__, cpr);
-+#else
-+ if (!current_cardslot_error(1)) {
-+ force_cardslot_suspend(1);
-+ set_jacketslot_error(1);
-+ }
-+#endif
-+ }
-+#endif
- #endif
-
- return 1;
-@@ -296,6 +398,10 @@
- #else
- info->irq=IRQ_GPIO_CF_IRQ;
- #endif
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ } else if (info->sock == 1) {
-+ info->irq=IRQ_GPIO_JC_CF_IRQ;
-+#endif
- }
-
- return 0;
-@@ -313,8 +419,10 @@
- if (configure->sock > 1)
- return -1;
-
-+#if !defined(CONFIG_ARCH_PXA_TOSA)
- if (configure->sock != 0)
- return 0;
-+#endif
-
- #ifdef SHARPSL_PCMCIA_DEBUG
- printk("%s(): sk=%d, vc=%d, vp=%d, m=%04X, oe=%d, rs=%d, io=%d\n",
-@@ -419,88 +527,205 @@
-
- #else
-
-+#if defined(CONFIG_PM)
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ if (configure->sock == 1) { // for socket1(Jacket)
-+ switch( configure->vcc ){
-+ case 0: sharpsl_batt_err = change_power_mode(LOCK_FCS_PCMCIA2, 0); break;
-+ case 33: sharpsl_batt_err = change_power_mode(LOCK_FCS_PCMCIA2, 1); break;
-+ case 50: sharpsl_batt_err = change_power_mode(LOCK_FCS_PCMCIA2, 1); break;
-+ default:
-+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-+ __FUNCTION__, configure->vcc);
-+ return -1;
-+ }
-+ } else {
-+#endif
- switch( configure->vcc ){
- case 0: sharpsl_batt_err = change_power_mode(LOCK_FCS_PCMCIA, 0); break;
- case 33: sharpsl_batt_err = change_power_mode(LOCK_FCS_PCMCIA, 1); break;
-- case 50: sharpsl_batt_err = change_power_mode(LOCK_FCS_PCMCIA, 1); break;
-+ case 50:
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ if (configure->sock == 0) {
-+ printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
-+ __FUNCTION__, configure->vcc);
-+ return -1;
-+ }
-+#endif
-+ sharpsl_batt_err = change_power_mode(LOCK_FCS_PCMCIA, 1); break;
- default:
- printk(KERN_ERR "%s(): unrecognized Vcc %u\n",
- __FUNCTION__, configure->vcc);
- return -1;
- }
--
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ }
-+#endif
- if ( !sharpsl_batt_err )
-- return -1;
-+ return -1;
-+#endif
-
-- if( (configure->vpp!=configure->vcc) && (configure->vpp!=0) ){
-- printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n",
-- __FUNCTION__, configure->vpp);
-- return -1;
-- }
-+ if (configure->sock == 0) {
-+ if( (configure->vpp!=configure->vcc) && (configure->vpp!=0) ){
-+ printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n",
-+ __FUNCTION__, configure->vpp);
-+ return -1;
-+ }
-+ save_flags_cli(flags);
-
-- save_flags_cli(flags);
-+ nmcr = (mcr = SCP_REG_MCR) & ~0x0010;
-+ ncpr = (cpr = SCP_REG_CPR) & ~0x0083;
-+ nccr = (ccr = SCP_REG_CCR) & ~0x0080;
-+ nimr = (imr = SCP_REG_IMR) & ~0x003E;
-+
-+ ncpr |= (configure->vcc == 33) ? 0x0001:
-+ (configure->vcc == 50) ? 0x0002:
-+ 0;
-+ nmcr |= (configure->flags&SS_IOCARD)? 0x0010: 0;
-+ ncpr |= (configure->flags&SS_OUTPUT_ENA)? 0x0080: 0;
-+ nccr |= (configure->flags&SS_RESET)? 0x0080: 0;
-+ nimr |= ((configure->masks&SS_DETECT) ? 0x0004: 0)|
-+ ((configure->masks&SS_READY) ? 0x0002: 0)|
-+ ((configure->masks&SS_BATDEAD)? 0x0010: 0)|
-+ ((configure->masks&SS_BATWARN)? 0x0020: 0)|
-+ ((configure->masks&SS_STSCHG) ? 0x0010: 0)|
-+ ((configure->masks&SS_WRPROT) ? 0x0008: 0);
-+
-+ if( !(ncpr & 0x0003) )
-+ keep_rd[0] = 0;
-+ else if( !(keep_rd[0] & RESET_DONE) ){
-+ if( nccr & 0x0080 )
-+ keep_rd[0] |= RESET_DONE;
-+ else nccr |= 0x0080;
-+ }
-+
-+ if( mcr != nmcr )
-+ SCP_REG_MCR = nmcr;
-+ if( cpr != ncpr )
-+ SCP_REG_CPR = ncpr;
-+ if( ccr != nccr )
-+ SCP_REG_CCR = nccr;
-+ if( imr != nimr )
-+ SCP_REG_IMR = nimr;
-+
-+ restore_flags(flags);
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ } else if (configure->sock == 1) {
-+ if( (configure->vpp!=configure->vcc) && (configure->vpp!=0) ){
-+ printk(KERN_ERR "%s(): CF slot1 cannot support Vpp %u\n",
-+ __FUNCTION__, configure->vpp);
-+ return -1;
-+ }
-+ save_flags_cli(flags);
-
-- nmcr = (mcr = SCP_REG_MCR) & ~0x0010;
-- ncpr = (cpr = SCP_REG_CPR) & ~0x0083;
-- nccr = (ccr = SCP_REG_CCR) & ~0x0080;
-- nimr = (imr = SCP_REG_IMR) & ~0x003E;
--
-- ncpr |= (configure->vcc == 33) ? 0x0001:
-- (configure->vcc == 50) ? 0x0002:
-- 0;
-- nmcr |= (configure->flags&SS_IOCARD)? 0x0010: 0;
-- ncpr |= (configure->flags&SS_OUTPUT_ENA)? 0x0080: 0;
-- nccr |= (configure->flags&SS_RESET)? 0x0080: 0;
-- nimr |= ((configure->masks&SS_DETECT) ? 0x0004: 0)|
-- ((configure->masks&SS_READY) ? 0x0002: 0)|
-- ((configure->masks&SS_BATDEAD)? 0x0010: 0)|
-- ((configure->masks&SS_BATWARN)? 0x0020: 0)|
-- ((configure->masks&SS_STSCHG) ? 0x0010: 0)|
-- ((configure->masks&SS_WRPROT) ? 0x0008: 0);
--
-- if( !(ncpr & 0x0003) )
-- keep_rd[0] = 0;
-- else if( !(keep_rd[0] & RESET_DONE) ){
-- if( nccr & 0x0080 )
-- keep_rd[0] |= RESET_DONE;
-- else nccr |= 0x0080;
-- }
--
-- if( mcr != nmcr )
-- SCP_REG_MCR = nmcr;
-- if( cpr != ncpr )
-- SCP_REG_CPR = ncpr;
-- if( ccr != nccr )
-- SCP_REG_CCR = nccr;
-- if( imr != nimr )
-- SCP_REG_IMR = nimr;
-+ nmcr = (mcr = SCP_JC_REG_MCR) & ~0x0010;
-+ ncpr = (cpr = SCP_JC_REG_CPR) & ~0x0083;
-+ nccr = (ccr = SCP_JC_REG_CCR) & ~0x0080;
-+ nimr = (imr = SCP_JC_REG_IMR) & ~0x003E;
-+
-+ ncpr |= (configure->vcc == 33) ? 0x0001:
-+ (configure->vcc == 50) ? 0x0002:
-+ 0;
-+ nmcr |= (configure->flags&SS_IOCARD)? 0x0010: 0;
-+ ncpr |= (configure->flags&SS_OUTPUT_ENA)? 0x0080: 0;
-+ nccr |= (configure->flags&SS_RESET)? 0x0080: 0;
-+ nimr |= ((configure->masks&SS_DETECT) ? 0x0004: 0)|
-+ ((configure->masks&SS_READY) ? 0x0002: 0)|
-+ ((configure->masks&SS_BATDEAD)? 0x0010: 0)|
-+ ((configure->masks&SS_BATWARN)? 0x0020: 0)|
-+ ((configure->masks&SS_STSCHG) ? 0x0010: 0)|
-+ ((configure->masks&SS_WRPROT) ? 0x0008: 0);
-+
-+ if( !(ncpr & 0x0003) )
-+ keep_rd[1] = 0;
-+ else if( !(keep_rd[1] & RESET_DONE) ){
-+ if( nccr & 0x0080 )
-+ keep_rd[1] |= RESET_DONE;
-+ else nccr |= 0x0080;
-+ }
-+
-+ if( mcr != nmcr )
-+ SCP_JC_REG_MCR = nmcr;
-+ if( cpr != ncpr )
-+ SCP_JC_REG_CPR = ncpr;
-+ if( ccr != nccr )
-+ SCP_JC_REG_CCR = nccr;
-+ if( imr != nimr )
-+ SCP_JC_REG_IMR = nimr;
-
-- restore_flags(flags);
-+ restore_flags(flags);
-+#endif
-+ }
-
- #endif
-
- return 0;
- }
-
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+static int sharpsl_pcmcia_socket_init(int sock)
-+{
-+ /* enable interrupt */
-+ switch(sock) {
-+ case 0:
-+ SCP_REG_IMR = 0x00C0;
-+ SCP_REG_MCR = 0x0101;
-+ break;
-+ case 1:
-+ SCP_JC_REG_IMR = 0x00C0;
-+ SCP_JC_REG_MCR = 0x0101;
-+ break;
-+ default:
-+ return -1;
-+ }
-+ return 0;
-+}
-+#endif
-+
- struct pcmcia_low_level sharpsl_pcmcia_ops = {
- sharpsl_pcmcia_init,
- sharpsl_pcmcia_shutdown,
- sharpsl_pcmcia_socket_state,
- sharpsl_pcmcia_get_irq_info,
-- sharpsl_pcmcia_configure_socket
-+ sharpsl_pcmcia_configure_socket,
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ sharpsl_pcmcia_socket_init,
-+#endif
- };
-
--int is_pcmcia_card_present(int slot)
-+int is_pcmcia_card_present(int irq)
- {
- int detect;
- #ifdef CONFIG_SABINAL_DISCOVERY
- detect = ((ASIC3_GPIO_PSTS_D & CF_DETECT) ? 0 : 1);
-+ //printk("is_card_present: irq=%d detect=%d\n", irq, detect);
-+ return detect;
- #else
-- int active;
-- active = (SCP_REG_CPR & 0x0003)? 1:0;
-- detect = (SCP_REG_CSR & 0x0004)? 0:1;
-+ int active = 0;
-+ if (irq == IRQ_GPIO_CF_IRQ) {
-+ active = (SCP_REG_CPR & 0x0003)? 1:0;
-+ detect = (SCP_REG_CSR & 0x0004)? 0:1;
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ } else if (irq == IRQ_GPIO_JC_CF_IRQ) {
-+ active = (SCP_JC_REG_CPR & 0x0003)? 1:0;
-+ detect = (SCP_JC_REG_CSR & 0x0004)? 0:1;
- #endif
-- //printk("is_card_present: detect=%d\n", detect);
-- //return detect;
-+ } else {
-+ /* unknown IRQ : return TRUE */
-+ return 1;
-+ }
-+ //printk("is_card_present: irq=%d detect=%d active=%d\n", irq, detect, active);
- return detect & active;
-+#endif
-+}
-+
-+int sharpsl_pcmcia_irq_to_sock(int irq)
-+{
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+ if (irq == IRQ_GPIO_JC_CF_IRQ) {
-+ return 1;
-+ }
-+#endif
-+ return 0;
- }
-+
-diff -Nur linux_c860_org/drivers/sbus/char/rtc.c linux/drivers/sbus/char/rtc.c
---- linux_c860_org/drivers/sbus/char/rtc.c 2002-08-26 14:39:04.000000000 +0900
-+++ linux/drivers/sbus/char/rtc.c 2004-06-10 21:09:10.000000000 +0900
-@@ -89,6 +89,7 @@
- switch (cmd)
- {
- case RTCGET:
-+ memset(&rtc_tm, 0, sizeof(struct rtc_time));
- get_rtc_time(&rtc_tm);
-
- if (copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time)))
-diff -Nur linux_c860_org/drivers/sound/Config.in linux/drivers/sound/Config.in
---- linux_c860_org/drivers/sound/Config.in 2002-10-11 21:13:04.000000000 +0900
-+++ linux/drivers/sound/Config.in 2004-06-10 21:09:10.000000000 +0900
-@@ -224,6 +224,8 @@
- dep_tristate ' Intel PXA250/210 AC97 audio' CONFIG_SOUND_PXA_AC97 $CONFIG_ARCH_PXA $CONFIG_SOUND
- dep_tristate ' Poodle audio support' CONFIG_SOUND_POODLE $CONFIG_ARCH_PXA $CONFIG_SOUND
- dep_tristate ' Corgi audio support' CONFIG_SOUND_CORGI $CONFIG_ARCH_PXA $CONFIG_SOUND
-+ dep_tristate ' Tosa audio support' CONFIG_SOUND_TOSA $CONFIG_AC97_TOSA $CONFIG_SOUND
-+ dep_tristate ' Tosa buzzer support' CONFIG_BUZZER_TOSA $CONFIG_SOUND_TOSA
- fi
-
- dep_tristate ' TV card (bt848) mixer support' CONFIG_SOUND_TVMIXER $CONFIG_SOUND $CONFIG_I2C
-diff -Nur linux_c860_org/drivers/sound/Makefile linux/drivers/sound/Makefile
---- linux_c860_org/drivers/sound/Makefile 2002-10-11 21:13:04.000000000 +0900
-+++ linux/drivers/sound/Makefile 2004-06-10 21:09:10.000000000 +0900
-@@ -11,7 +11,7 @@
- msnd.o opl3.o sb_common.o sequencer_syms.o \
- sound_core.o sound_syms.o uart401.o \
- nm256_audio.o ac97.o ac97_codec.o aci.o \
-- sa1100-audio.o pxa-audio.o pxa-ac97.o
-+ sa1100-audio.o pxa-audio.o pxa-ac97.o pxa-ac97_tosa.o
-
- # Each configuration option enables a list of files.
-
-@@ -88,6 +88,7 @@
- obj-$(CONFIG_SOUND_DISCOVERY) += discovery_audio.o i2sc.o
- obj-$(CONFIG_SOUND_POODLE) += pxa-i2s.o poodle_i2sc.o poodle_wm8731.o
- obj-$(CONFIG_SOUND_CORGI) += pxa-i2s_corgi.o poodle_i2sc.o poodle_wm8731.o
-+obj-$(CONFIG_SOUND_TOSA) += pxa-ac97_tosa.o tosa_wm9712.o
-
- ifeq ($(CONFIG_MIDI_EMU10K1),y)
- obj-$(CONFIG_SOUND_EMU10K1) += sound.o
-diff -Nur linux_c860_org/drivers/sound/pxa-ac97_tosa.c linux/drivers/sound/pxa-ac97_tosa.c
---- linux_c860_org/drivers/sound/pxa-ac97_tosa.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/sound/pxa-ac97_tosa.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,2250 @@
-+/*
-+ * linux/drivers/sound/pxa-ac97_tosa.c
-+ *
-+ * AC97 interface for the Tosa chip
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * Based on:
-+ * linux/drivers/sound/pxa-ac97.c -- AC97 interface for the Cotula chip
-+ * Author: Nicolas Pitre
-+ * Created: Aug 15, 2001
-+ * Copyright: MontaVista Software Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/pci.h>
-+#include <linux/completion.h>
-+#include <linux/delay.h>
-+#include <linux/poll.h>
-+#include <linux/sound.h>
-+#include <linux/soundcard.h>
-+#include <linux/ac97_codec.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+#include <asm/semaphore.h>
-+#include <asm/dma.h>
-+
-+#include "pxa-audio.h"
-+
-+#include <asm/arch/tosa_wm9712.h>
-+
-+//struct ac97_codec *codec;
-+
-+/************************************************************
-+ * Debug
-+ ************************************************************/
-+#define DBG_LEVEL 0
-+
-+#define DBG_L0 0
-+#define DBG_L1 1
-+#define DBG_L2 2
-+#define DBG_L3 3
-+
-+#ifdef DBG_LEVEL
-+#define DEBUG(level, x, args...) \
-+ if ( level <= DBG_LEVEL ) printk("%s: " x,__FUNCTION__ ,##args)
-+#else
-+#define DEBUG(level, x, args...) \
-+ if ( !level ) printk("%s: " x,__FUNCTION__ ,##args)
-+#endif /* DBG_LEVEL */
-+
-+/************************************************************
-+ * Some declarations
-+ ************************************************************/
-+#define SND_DEV_STATUS 6 /* /dev/sndstat for Compatible for Collie */
-+
-+#define AUDIO_NBFRAGS_DEFAULT 8
-+#define AUDIO_FRAGSIZE_DEFAULT 8192
-+
-+#define MAX_DMA_SIZE 4096
-+#define DMA_DESC_SIZE sizeof(pxa_dma_desc)
-+
-+#define IOCTL_IN(arg, ret) \
-+ do { int error = get_user(ret, (int *)(arg)); \
-+ if (error) return error; \
-+ } while (0)
-+#define IOCTL_OUT(arg, ret) ioctl_return((int *)(arg), ret)
-+
-+#define DMA_NO_INITIALIZED 1
-+#define ALARM_NO_MALLOC 1
-+#ifdef CONFIG_BUZZER_TOSA
-+#define BUZZER_FORCE_CLOSE 1
-+#else
-+#undef BUZZER_FORCE_CLOSE
-+#endif /* CONFIG_BUZZER_TOSA */
-+
-+/************************************************************
-+ * Power maneagement
-+ ************************************************************/
-+#ifdef CONFIG_PM
-+#include <linux/pm.h>
-+static struct pm_dev* pxa_sound_pm_dev;
-+static int tosa_pm_callback(struct pm_dev *,pm_request_t, void *);
-+extern void tosa_ts_suspend(void);
-+extern void tosa_ts_resume(void);
-+#endif /* CONFIG_PM */
-+
-+/************************************************************
-+ * valiables
-+ ************************************************************/
-+static ssize_t (*ct_func)
-+ (const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL;
-+static ssize_t (*ct_read_func)
-+ (const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL;
-+
-+static int tosa_intmode = 0;
-+static int tosa_intmode_speed = 0;
-+static int tosa_intmode_direct = 0;
-+static short *int_data_org = NULL ;
-+#ifdef ALARM_NO_MALLOC
-+static int tosa_intmode_cur = 0;
-+static int tosa_intmode_step = 0;
-+#else /* ALARM_NO_MALLOC */
-+static short *int_data = NULL ;
-+#endif /* ALARM_NO_MALLOC */
-+
-+#if defined(BUZZER_FORCE_CLOSE) && defined(CONFIG_BUZZER_TOSA)
-+#define WAIT_BZ_RELEASE ( ( 2 * 1000 ) / 10 )
-+static int buzzer_open = 0;
-+static int buzzer_close = 0;
-+#endif /* BUZZER_FORCE_CLOSE */
-+
-+extern int wm9712_mono_out; // mix output data into mono
-+
-+/************************************************************
-+ * Prototype
-+ ************************************************************/
-+static int tosa_init(void);
-+static int tosa_set_volume(int);
-+static int tosa_set_stereo(int);
-+static int tosa_set_format(int);
-+static int tosa_set_gain(int);
-+static int tosa_get_gain(void);
-+static int tosa_get_volume(void);
-+static int tosa_set_freq(int);
-+static int mixer_ioctl
-+ (struct inode *, struct file *,unsigned int, unsigned long);
-+static void tosa_intmode_mix(unsigned char *,int);
-+
-+/************************************************************
-+ * Machine definitions
-+ ************************************************************/
-+typedef struct {
-+ ssize_t (*ct_ulaw)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-+ ssize_t (*ct_alaw)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-+ ssize_t (*ct_s8)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-+ ssize_t (*ct_u8)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-+ ssize_t (*ct_s16be)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-+ ssize_t (*ct_u16be)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-+ ssize_t (*ct_s16le)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-+ ssize_t (*ct_u16le)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-+} TRANS;
-+
-+typedef struct {
-+ int (*init)(void);
-+ void (*silence)(void);
-+ int (*setFormat)(int);
-+ int (*setVolume)(int);
-+ int (*getVolume)(void);
-+ int (*setStereo)(int);
-+ int (*setBass)(int);
-+ int (*setTreble)(int);
-+ int (*setGain)(int);
-+ int (*getGain)(void);
-+ int (*setFreq)(int);
-+ void (*play)(void);
-+} PLATFORM;
-+
-+static PLATFORM mach_tosa = {
-+ tosa_init, // void init(void)
-+ NULL, // void silence(void)
-+ tosa_set_format, // int setFormat(int)
-+ tosa_set_volume, // int setVolume(int)
-+ tosa_get_volume, // int getVolume(void)
-+ tosa_set_stereo, // int setStereo(int)
-+ NULL, // int setBass(int)
-+ NULL, // int setTreble(int)
-+ tosa_set_gain, // int setGain(int)
-+ tosa_get_gain, // int getGain(void)
-+ tosa_set_freq, // int setFreq(int)
-+ NULL, // void play(void)
-+};
-+
-+/************************************************************
-+ * /dev/setting
-+ ************************************************************/
-+struct sound_settings {
-+ PLATFORM mach; /* platform dependent things */
-+ TRANS *trans; /* supported translations */
-+ TRANS *trans_read; /* supported translations */
-+ unsigned short mode;
-+ int format; /* AFMT_* */
-+ int stereo; /* 0 = mono, 1 = stereo */
-+ int size; /* 8/16 bit*/
-+ int freq; /* freq */
-+ int volume_left; /* volume (range is 0 - 100%) */
-+ int volume_right;
-+ int gain_left; /* input gain (range is 0 - 100%) */
-+ int gain_right;
-+ int bass; /* tone (not support) */
-+ int treble;
-+ /* device independ */
-+ // int gain_shift; /* input gain shift */
-+ // int gain; /* input gain */
-+};
-+static struct sound_settings sound;
-+
-+/* /dev/sndstat */
-+struct sound_state {
-+ int dev_state;
-+ int busy;
-+ char buf[512];
-+ int len, ptr;
-+};
-+static struct sound_state tosa_sound_state;
-+
-+static audio_stream_t ac97_audio_out = {
-+ name: "AC97 audio out",
-+ dcmd: DCMD_TXPCDR,
-+ drcmr: &DRCMRTXPCDR,
-+ dev_addr: __PREG(PCDR),
-+};
-+
-+static audio_stream_t ac97_audio_in = {
-+ name: "AC97 audio in",
-+ dcmd: DCMD_RXPCDR,
-+ drcmr: &DRCMRRXPCDR,
-+ dev_addr: __PREG(PCDR),
-+};
-+
-+static audio_state_t ac97_audio_state = {
-+ output_stream: &ac97_audio_out,
-+ input_stream: &ac97_audio_in,
-+ sem: __MUTEX_INITIALIZER(ac97_audio_state.sem),
-+};
-+
-+#if 0
-+typedef struct {
-+ int shift;
-+ int gain;
-+} input_gain_t;
-+
-+static input_gain_t input_gain[7] = {
-+ { 2 , 0 },
-+ { 0 , 1 },
-+ { 1 , 1 },
-+ { 2 , 1 },
-+ { 3 , 1 },
-+ { 4 , 1 },
-+ { 5 , 1 }
-+};
-+#endif
-+
-+/************************************************************
-+ * data convert
-+ ************************************************************/
-+/* 16 bit mu-law */
-+static short ulaw2dma16[] = {
-+ -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
-+ -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
-+ -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
-+ -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
-+ -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
-+ -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
-+ -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
-+ -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
-+ -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
-+ -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
-+ -876, -844, -812, -780, -748, -716, -684, -652,
-+ -620, -588, -556, -524, -492, -460, -428, -396,
-+ -372, -356, -340, -324, -308, -292, -276, -260,
-+ -244, -228, -212, -196, -180, -164, -148, -132,
-+ -120, -112, -104, -96, -88, -80, -72, -64,
-+ -56, -48, -40, -32, -24, -16, -8, 0,
-+ 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
-+ 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
-+ 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
-+ 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
-+ 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
-+ 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
-+ 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
-+ 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
-+ 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
-+ 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
-+ 876, 844, 812, 780, 748, 716, 684, 652,
-+ 620, 588, 556, 524, 492, 460, 428, 396,
-+ 372, 356, 340, 324, 308, 292, 276, 260,
-+ 244, 228, 212, 196, 180, 164, 148, 132,
-+ 120, 112, 104, 96, 88, 80, 72, 64,
-+ 56, 48, 40, 32, 24, 16, 8, 0,
-+};
-+
-+/* 16 bit A-law */
-+static short alaw2dma16[] = {
-+ -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
-+ -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
-+ -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
-+ -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
-+ -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
-+ -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
-+ -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
-+ -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
-+ -344, -328, -376, -360, -280, -264, -312, -296,
-+ -472, -456, -504, -488, -408, -392, -440, -424,
-+ -88, -72, -120, -104, -24, -8, -56, -40,
-+ -216, -200, -248, -232, -152, -136, -184, -168,
-+ -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
-+ -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
-+ -688, -656, -752, -720, -560, -528, -624, -592,
-+ -944, -912, -1008, -976, -816, -784, -880, -848,
-+ 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
-+ 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
-+ 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
-+ 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
-+ 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
-+ 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
-+ 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
-+ 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
-+ 344, 328, 376, 360, 280, 264, 312, 296,
-+ 472, 456, 504, 488, 408, 392, 440, 424,
-+ 88, 72, 120, 104, 24, 8, 56, 40,
-+ 216, 200, 248, 232, 152, 136, 184, 168,
-+ 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
-+ 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
-+ 688, 656, 752, 720, 560, 528, 624, 592,
-+ 944, 912, 1008, 976, 816, 784, 880, 848,
-+};
-+
-+static ssize_t tosa_ct_law(const u_char *userPtr, size_t userCount,
-+ u_char frame[], ssize_t *frameUsed, ssize_t frameLeft)
-+{
-+ short *table = sound.format == AFMT_MU_LAW ? ulaw2dma16: alaw2dma16;
-+ ssize_t count, used;
-+ short *p = (short *) &frame[*frameUsed];
-+ int val, stereo = sound.stereo;
-+
-+ frameLeft >>= 2;
-+ if (stereo)
-+ userCount >>= 1;
-+ used = count = min(userCount, frameLeft);
-+ while (count > 0) {
-+ u_char data;
-+ if (get_user(data, userPtr++)) {
-+ return -EFAULT;
-+ }
-+ val = table[data];
-+ *p++ = val; /* Left Ch. */
-+ if (stereo) {
-+ if (get_user(data, userPtr++)) {
-+ return -EFAULT;
-+ }
-+ val = table[data];
-+ }
-+ *p++ = val; /* Right Ch. */
-+ count--;
-+ }
-+ *frameUsed += used * 4;
-+ return stereo? used * 2: used;
-+}
-+
-+static ssize_t tosa_ct_u8(const u_char *userPtr, size_t userCount,
-+ u_char frame[], ssize_t *frameUsed, ssize_t frameLeft)
-+{
-+ int ch = (sound.stereo)?2:1;
-+ unsigned char *src = (unsigned char *)userPtr;
-+ short *dstct = (short *)frame;
-+ short tmpval;
-+ int frameMax = frameLeft >> 2;
-+ int userMax = userCount >> (ch-1);
-+ int idx,samplingCount = min(frameMax,userMax);
-+
-+ if (!wm9712_mono_out || ch==1) {
-+ for (idx=0; idx<samplingCount; idx++) {
-+ if (get_user(tmpval,src)) {
-+ return -EFAULT;
-+ }
-+ *dstct++ = (tmpval-128)<<8;
-+ if (ch>1) src++;
-+ if (get_user(tmpval,src++)) {
-+ return -EFAULT;
-+ }
-+ *dstct++ = (tmpval-128)<<8;
-+ }
-+ } else {
-+ short vall,valr;
-+ for (idx=0; idx<samplingCount; idx++) {
-+ if (get_user(vall,src++) || get_user(valr,src++)) {
-+ return -EFAULT;
-+ }
-+ vall = (vall-128)<<8;
-+ valr = (valr-128)<<8;
-+ vall = vall/2+valr/2;
-+ *dstct++ = vall;
-+ *dstct++ = vall;
-+ }
-+ }
-+
-+ *frameUsed = samplingCount * 2 * 2; // dma is always stereo 16bit
-+ return samplingCount * ch;
-+}
-+
-+static ssize_t tosa_ct_s16(const u_char *userPtr, size_t userCount,
-+ u_char frame[], ssize_t *frameUsed, ssize_t frameLeft)
-+{
-+ int ch = (sound.stereo)?2:1;
-+ short *src = (short *)userPtr;
-+ short *dstct = (short *)frame;
-+ int frameMax = frameLeft >> 2;
-+ int userMax = userCount >> ch;
-+ int samplingCount = min(frameMax,userMax);
-+
-+ if ( ch > 1 ) { // stereo
-+ if (!wm9712_mono_out) {
-+ if (copy_from_user(dstct,src,samplingCount * ch * 2)) {
-+ return -EFAULT;
-+ }
-+ } else {
-+ int idx;
-+ short vall,valr;
-+ for (idx=0; idx<samplingCount; idx++) {
-+ if (get_user(vall,src++) || get_user(valr,src++)) {
-+ return -EFAULT;
-+ }
-+ vall = vall/2+valr/2;
-+ *dstct++ = vall;
-+ *dstct++ = vall;
-+ }
-+ }
-+ } else { // mono
-+ int idx;
-+ for (idx=0; idx<samplingCount; idx++) {
-+ if (get_user(*dstct++,src) || get_user(*dstct++,src++)) {
-+ return -EFAULT;
-+ }
-+ }
-+ }
-+
-+ *frameUsed = samplingCount * 2 * 2; // dma is always stereo 16bit
-+ return samplingCount * ch * 2;
-+}
-+
-+static TRANS trans_tosa = {
-+ tosa_ct_law,tosa_ct_law,0,tosa_ct_u8,0,0,tosa_ct_s16,0
-+};
-+
-+/* data convert for recording */
-+static ssize_t tosa_ct_read_u8(const u_char *userPtr, size_t userCount,
-+ u_char frame[], ssize_t *frameUsed, ssize_t frameLeft)
-+{
-+ int ch = (sound.stereo)?2:1;
-+ unsigned char *usrbuf = (unsigned char *)userPtr;
-+ short *dmabuf = (short *)frame;
-+ short tmpval;
-+ int dmaMax = frameLeft >> 2; // dma is always stereo
-+ int userMax = userCount >> ch;
-+ int ct,samplingCount = min(dmaMax,userMax);
-+
-+ for (ct=0; ct<samplingCount; ct++) {
-+ dmabuf++; // use right data
-+ tmpval = *dmabuf>>8;
-+ if (tmpval>127) tmpval = 127;
-+ else if (tmpval<-128) tmpval = -128;
-+ if (put_user((unsigned char)(tmpval+128),usrbuf++)) { // left channel
-+ return -EFAULT;
-+ }
-+ if (ch>1) { // right channel
-+ tmpval = *dmabuf>>8;
-+ if (tmpval>127) tmpval = 127;
-+ else if (tmpval<-128) tmpval = -128;
-+ if (put_user((unsigned char)(tmpval+128),usrbuf++)) {
-+ return -EFAULT;
-+ }
-+ }
-+ dmabuf++;
-+ }
-+ *frameUsed = samplingCount * 2 * 2; // dma is always stereo
-+ return samplingCount * ch;
-+}
-+
-+static ssize_t tosa_ct_read_s16(const u_char *userPtr, size_t userCount,
-+ u_char frame[], ssize_t *frameUsed, ssize_t frameLeft)
-+{
-+ int ch = (sound.stereo)?2:1;
-+ short *usrbuf = (short *)userPtr;
-+ short *dmabuf = (short *)frame;
-+ int dmaMax = frameLeft >> 2; // dma is always stereo
-+ int userMax = userCount >> ch;
-+ int ct,samplingCount = min(dmaMax,userMax);
-+
-+ for (ct=0; ct<samplingCount; ct++) {
-+ dmabuf++; // use right data
-+ if (put_user((*dmabuf),usrbuf++)) { // left channel
-+ return -EFAULT;
-+ }
-+ if (ch>1) { // right channel
-+ if (put_user(*dmabuf,usrbuf++)) {
-+ return -EFAULT;
-+ }
-+ }
-+ dmabuf++;
-+ }
-+ *frameUsed = samplingCount * 2 * 2; // dma is always stereo
-+ return samplingCount * ch * 2;
-+}
-+
-+static TRANS trans_r_tosa = {
-+ 0,0,0,tosa_ct_read_u8,0,0,tosa_ct_read_s16,0
-+};
-+
-+/************************************************************
-+ * Common stuff
-+ ************************************************************/
-+static inline int ioctl_return(int *addr, int value)
-+{
-+ if ( value < 0 ) return value;
-+ return put_user(value, addr) ? -EFAULT: 0;
-+}
-+
-+static inline void tosa_ac97_write(unsigned int data)
-+{
-+ while ( 1 ) {
-+ if ( (GPLR(GPIO31_SYNC) & GPIO_bit(GPIO31_SYNC)) == GPIO_bit(GPIO31_SYNC) )
-+ break;
-+ }
-+ PCDR = data;
-+}
-+
-+/************************************************************
-+ * This function frees all buffers
-+ ************************************************************/
-+
-+#define audio_clear_buf pxa_audio_clear_buf
-+
-+void pxa_audio_clear_buf(audio_stream_t * s)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ int frag;
-+
-+ if (!s->buffers)
-+ return;
-+
-+ /* Ensure DMA isn't running */
-+ set_current_state(TASK_UNINTERRUPTIBLE);
-+ add_wait_queue(&s->stop_wq, &wait);
-+ DCSR(s->dma_ch) = DCSR_STOPIRQEN;
-+ schedule();
-+ remove_wait_queue(&s->stop_wq, &wait);
-+
-+ /* free DMA buffers */
-+ for (frag = 0; frag < s->nbfrags; frag++) {
-+ audio_buf_t *b = &s->buffers[frag];
-+ if (!b->master)
-+ continue;
-+ consistent_free(b->data, b->master, b->dma_desc->dsadr);
-+ }
-+
-+ /* free descriptor ring */
-+ if (s->buffers->dma_desc)
-+ consistent_free(s->buffers->dma_desc,
-+ s->nbfrags * s->descs_per_frag * DMA_DESC_SIZE,
-+ s->dma_desc_phys);
-+
-+ /* free buffer structure array */
-+ kfree(s->buffers);
-+ s->buffers = NULL;
-+}
-+
-+/************************************************************
-+ * This function allocates the DMA descriptor array and buffer data space
-+ * according to the current number of fragments and fragment size.
-+ ************************************************************/
-+static int audio_setup_buf(audio_stream_t * s)
-+{
-+ pxa_dma_desc *dma_desc;
-+ dma_addr_t dma_desc_phys;
-+ int nb_desc, frag, i, buf_size = 0;
-+ char *dma_buf = NULL;
-+ dma_addr_t dma_buf_phys = 0;
-+
-+ DEBUG(DBG_L2, "Enter audio_setup buffer\n");
-+
-+ if (s->buffers)
-+ return -EBUSY;
-+
-+ /* Our buffer structure array */
-+ s->buffers = kmalloc(sizeof(audio_buf_t) * s->nbfrags, GFP_KERNEL);
-+ if (!s->buffers)
-+ goto err;
-+ memzero(s->buffers, sizeof(audio_buf_t) * s->nbfrags);
-+ /*
-+ * Our DMA descriptor array:
-+ * for Each fragment we have one checkpoint descriptor plus one
-+ * descriptor per MAX_DMA_SIZE byte data blocks.
-+ */
-+ nb_desc = (1 + (s->fragsize + MAX_DMA_SIZE - 1)/MAX_DMA_SIZE) * s->nbfrags;
-+ dma_desc = consistent_alloc(GFP_KERNEL,
-+ nb_desc * DMA_DESC_SIZE, &dma_desc_phys);
-+ if (!dma_desc)
-+ goto err;
-+ s->descs_per_frag = nb_desc / s->nbfrags;
-+ s->buffers->dma_desc = dma_desc;
-+ s->dma_desc_phys = dma_desc_phys;
-+ for (i = 0; i < nb_desc - 1; i++)
-+ dma_desc[i].ddadr = dma_desc_phys + (i + 1) * DMA_DESC_SIZE;
-+ dma_desc[i].ddadr = dma_desc_phys;
-+
-+ /* Our actual DMA buffers */
-+ for (frag = 0; frag < s->nbfrags; frag++) {
-+ audio_buf_t *b = &s->buffers[frag];
-+ /*
-+ * Let's allocate non-cached memory for DMA buffers.
-+ * We try to allocate all memory at once.
-+ * If this fails (a common reason is memory fragmentation),
-+ * then we'll try allocating smaller buffers.
-+ */
-+ if (!buf_size) {
-+ buf_size = (s->nbfrags - frag) * s->fragsize;
-+ do {
-+ dma_buf = consistent_alloc(GFP_KERNEL,
-+ buf_size,
-+ &dma_buf_phys);
-+ if (!dma_buf)
-+ buf_size -= s->fragsize;
-+ } while (!dma_buf && buf_size);
-+ if (!dma_buf)
-+ goto err;
-+ b->master = buf_size;
-+ memzero(dma_buf, buf_size);
-+ }
-+
-+ /*
-+ * is always zero, we'll abuse the dsadr and dtadr fields
-+ * just in case this one is picked up by the hardware.
-+ * while processing SOUND_DSP_GETPTR.
-+ */
-+ dma_desc->dsadr = dma_buf_phys;
-+ dma_desc->dtadr = dma_buf_phys;
-+ dma_desc->dcmd = DCMD_ENDIRQEN;
-+ if (s->output && !s->mapped)
-+ dma_desc->ddadr |= DDADR_STOP;
-+ b->dma_desc = dma_desc++;
-+
-+ /* set up the actual data descriptors */
-+ for (i = 0; (i * MAX_DMA_SIZE) < s->fragsize; i++) {
-+ dma_desc[i].dsadr = (s->output) ?
-+ (dma_buf_phys + i*MAX_DMA_SIZE) : s->dev_addr;
-+ dma_desc[i].dtadr = (s->output) ?
-+ s->dev_addr : (dma_buf_phys + i*MAX_DMA_SIZE);
-+ dma_desc[i].dcmd = s->dcmd |
-+ ((s->fragsize < MAX_DMA_SIZE) ?
-+ s->fragsize : MAX_DMA_SIZE);
-+
-+ DEBUG(DBG_L3, "dsadr[%8x],dtadr[%8x],dcmd[%8x]\n",
-+ dma_desc[i].dsadr,dma_desc[i].dtadr,dma_desc[i].dcmd);
-+
-+ }
-+ dma_desc += i;
-+
-+ /* handle buffer pointers */
-+ b->data = dma_buf;
-+ dma_buf += s->fragsize;
-+ dma_buf_phys += s->fragsize;
-+ buf_size -= s->fragsize;
-+ }
-+
-+ s->usr_frag = s->dma_frag = 0;
-+ s->bytecount = 0;
-+ s->fragcount = 0;
-+ sema_init(&s->sem, (s->output) ? s->nbfrags : 0);
-+ return 0;
-+
-+err:
-+ DEBUG(DBG_L0, "unable to allocate audio memory\n ");
-+ audio_clear_buf(s);
-+ return -ENOMEM;
-+}
-+
-+/************************************************************
-+ * Our DMA interrupt handler
-+ ************************************************************/
-+static void audio_dma_irq(int ch, void *dev_id, struct pt_regs *regs)
-+{
-+ audio_stream_t *s = dev_id;
-+ u_int dcsr;
-+
-+ dcsr = DCSR(ch);
-+ DCSR(ch) = dcsr & ~DCSR_STOPIRQEN;
-+
-+ DEBUG(DBG_L2, "dcsr(ch) = %8x(%d)\n",dcsr,ch);
-+
-+ if (!s->buffers) {
-+ DEBUG(DBG_L0, "DMA: wow... received IRQ for channel %d but no buffer exists\n", ch);
-+ return;
-+ }
-+
-+ if (dcsr & DCSR_BUSERR)
-+ DEBUG(DBG_L0, "DMA: bus error interrupt on channel %d\n", ch);
-+
-+ if (dcsr & DCSR_ENDINTR) {
-+ u_long cur_dma_desc;
-+ u_int cur_dma_frag;
-+
-+ /*
-+ * Find out which DMA desc is current. Note that DDADR
-+ * points to the next desc, not the current one.
-+ */
-+ cur_dma_desc = DDADR(ch) - s->dma_desc_phys - DMA_DESC_SIZE;
-+
-+ /*
-+ * Let the compiler nicely optimize constant divisors into
-+ * multiplications for the common cases which is much faster.
-+ * Common cases: x = 1 + (1 << y) for y = [0..3]
-+ */
-+ switch (s->descs_per_frag) {
-+ case 2: cur_dma_frag = cur_dma_desc / (2*DMA_DESC_SIZE); break;
-+ case 3: cur_dma_frag = cur_dma_desc / (3*DMA_DESC_SIZE); break;
-+ case 5: cur_dma_frag = cur_dma_desc / (5*DMA_DESC_SIZE); break;
-+ case 9: cur_dma_frag = cur_dma_desc / (9*DMA_DESC_SIZE); break;
-+ default: cur_dma_frag =
-+ cur_dma_desc / (s->descs_per_frag * DMA_DESC_SIZE);
-+ }
-+
-+ /* Account for possible wrap back of cur_dma_desc above */
-+ if (cur_dma_frag >= s->nbfrags)
-+ cur_dma_frag = s->nbfrags - 1;
-+
-+ while (s->dma_frag != cur_dma_frag) {
-+ if (!s->mapped) {
-+ /*
-+ * This fragment is done - set the checkpoint
-+ * descriptor to STOP until it is gets
-+ * processed by the read or write function.
-+ */
-+ s->buffers[s->dma_frag].dma_desc->ddadr |= DDADR_STOP;
-+ up(&s->sem);
-+ }
-+ if (++s->dma_frag >= s->nbfrags)
-+ s->dma_frag = 0;/* Accounting */
-+ s->bytecount += s->fragsize;
-+ s->fragcount++;
-+ }
-+
-+ /* ... and for polling processes */
-+ wake_up(&s->frag_wq);
-+ }
-+
-+ if ((dcsr & DCSR_STOPIRQEN) && (dcsr & DCSR_STOPSTATE))
-+ wake_up(&s->stop_wq);
-+}
-+
-+/************************************************************
-+ * Validate and sets up buffer fragments, etc.
-+ ************************************************************/
-+static int audio_set_fragments(audio_stream_t *s, int val)
-+{
-+ if (s->mapped || DCSR(s->dma_ch) & DCSR_RUN)
-+ return -EBUSY;
-+ if (s->buffers)
-+ audio_clear_buf(s);
-+ s->nbfrags = (val >> 16) & 0x7FFF;
-+ val &= 0xffff;
-+ if (val < 5)
-+ val = 5;
-+ if (val > 15)
-+ val = 15;
-+ s->fragsize = 1 << val;
-+ if (s->nbfrags < 2)
-+ s->nbfrags = 2;
-+ if (s->nbfrags * s->fragsize > 256 * 1024)
-+ s->nbfrags = 256 * 1024 / s->fragsize;
-+ if (audio_setup_buf(s))
-+ return -ENOMEM;
-+ return val|(s->nbfrags << 16);
-+}
-+
-+/************************************************************
-+ * Detect HP Jack
-+ ************************************************************/
-+static void tosa_hp_thread(void)
-+{
-+ while(1) {
-+ wm9712_checkjack_sleep();
-+ wm9712_update_jack_state();
-+ }
-+}
-+
-+/************************************************************
-+ * Prototype functions
-+ ************************************************************/
-+static int tosa_init(void)
-+{
-+ if ( wm9712_init() ) {
-+ DEBUG(DBG_L0, "Fail Init\n");
-+ }
-+
-+ /* Make threads */
-+ kernel_thread(tosa_hp_thread, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
-+}
-+
-+static int tosa_set_volume(int volume)
-+{
-+ sound.volume_left = volume & 0xff;
-+ if ( sound.volume_left > 100 ) sound.volume_left = 100;
-+ sound.volume_right = ( (volume & 0xff00) >> 8);
-+ if ( sound.volume_right > 100 ) sound.volume_right = 100;
-+
-+ wm9712_set_output_volume(sound.volume_left, sound.volume_right);
-+
-+ return 0;
-+}
-+
-+static int tosa_get_volume(void)
-+{
-+ return ( sound.volume_right << 8 | sound.volume_left );
-+}
-+
-+static int tosa_set_stereo(int stereo)
-+{
-+ if ( stereo < 0 ) return sound.stereo;
-+ stereo = !!stereo; /* should be 0 or 1 now */
-+ sound.stereo = stereo;
-+ return stereo;
-+}
-+
-+static int tosa_set_format(int format)
-+{
-+ int size;
-+
-+ switch ( format ) {
-+ case AFMT_QUERY:
-+ return sound.format;
-+ case AFMT_MU_LAW:
-+ size = 8;
-+ ct_func = sound.trans->ct_ulaw;
-+ break;
-+ case AFMT_A_LAW:
-+ size = 8;
-+ ct_func = sound.trans->ct_alaw;
-+ break;
-+#if 0 // unsupport
-+ case AFMT_S8:
-+ size = 8;
-+ ct_func = sound.trans->ct_s8;
-+ break;
-+ case AFMT_S16_BE:
-+ size = 16;
-+ ct_func = sound.trans->ct_s16be;
-+ break;
-+ case AFMT_U16_BE:
-+ size = 16;
-+ ct_func = sound.trans->ct_u16be;
-+ break;
-+ case AFMT_U16_LE:
-+ size = 16;
-+ ct_func = sound.trans->ct_u16le;
-+ break;
-+#endif
-+ case AFMT_U8:
-+ size = 8;
-+ ct_func = sound.trans->ct_u8;
-+ ct_read_func = sound.trans_read->ct_u8;
-+ break;
-+ case AFMT_S16_LE:
-+ size = 16;
-+ ct_func = sound.trans->ct_s16le;
-+ ct_read_func = sound.trans_read->ct_s16le;
-+ break;
-+ default: /* :-) */
-+ size = 16;
-+ format = AFMT_S16_LE;
-+ }
-+
-+ sound.format = format;
-+ sound.size = size;
-+ return format;
-+}
-+
-+static int tosa_set_gain(int gain)
-+{
-+ sound.gain_left = gain & 0xff;
-+ if ( sound.gain_left > 100 ) sound.gain_left = 100;
-+
-+ sound.gain_right = ( (gain & 0xff00) >> 8);
-+ if ( sound.gain_right > 100 ) sound.gain_right = 100;
-+
-+ wm9712_set_input_gain(sound.gain_left,sound.gain_right);
-+ return 1;
-+}
-+
-+static int tosa_get_gain(void)
-+{
-+ return ( sound.gain_right << 8 | sound.gain_left );
-+}
-+
-+static int tosa_set_freq(int speed)
-+{
-+ if ( speed < 0 ) return sound.freq;
-+ sound.freq = speed;
-+ if( wm9712_busy() ) {
-+ SOUND_SETTINGS setting;
-+ setting.mode = sound.mode;
-+ setting.frequency = sound.freq;
-+ wm9712_set_freq(&setting);
-+ }
-+ return sound.freq;
-+}
-+
-+/************************************************************
-+ * Audio stuff
-+ ************************************************************/
-+static int audio_open(struct inode *inode, struct file *file)
-+{
-+ audio_state_t *state = &ac97_audio_state;
-+ audio_stream_t *is = state->input_stream;
-+ audio_stream_t *os = state->output_stream;
-+ SOUND_SETTINGS settings;
-+ int ret = 0;
-+
-+ down(&state->sem);
-+ ret = -ENODEV;
-+ /* access control */
-+ if ( (file->f_mode & FMODE_WRITE) && !os )
-+ goto out;
-+ if ( (file->f_mode & FMODE_READ) && !is )
-+ goto out;
-+ ret = -EBUSY;
-+
-+ if ( state->wr_ref || state->rd_ref )
-+#ifdef BUZZER_FORCE_CLOSE
-+ {
-+ if( !buzzer_open ) {
-+ goto out;
-+ } else {
-+ int now;
-+
-+ // force close buzzer
-+ DEBUG(DBG_L1, "force a buzzer stop!\n");
-+ buzzer_close = 1;
-+ if ( DCSR(os->dma_ch) & DCSR_RUN ) {
-+ DCSR(os->dma_ch) &=
-+ (DCSR_RUN|DCSR_ENDINTR|DCSR_STARTINTR|DCSR_BUSERR);
-+ }
-+ now = jiffies;
-+ while ( 1 ) {
-+ if ( !buzzer_open ) break;
-+ schedule();
-+ if ( jiffies > ( now + WAIT_BZ_RELEASE ) ) break;
-+ }
-+ buzzer_close = 0;
-+ if( buzzer_open ) goto out;
-+ }
-+ }
-+#else
-+ goto out;
-+#endif /* BUZZER_FORCE_CLOSE */
-+ /* request DMA channels */
-+ if ( file->f_mode & FMODE_WRITE) {
-+ ret = pxa_request_dma(os->name, DMA_PRIO_LOW, audio_dma_irq, os);
-+ if ( ret < 0 )
-+ goto out;
-+ os->dma_ch = ret;
-+ }
-+ if ( file->f_mode & FMODE_READ ) {
-+ ret = pxa_request_dma(is->name, DMA_PRIO_LOW, audio_dma_irq, is);
-+ if ( ret < 0 ) {
-+ if ( file->f_mode & FMODE_WRITE ) {
-+ *os->drcmr = 0;
-+ pxa_free_dma(os->dma_ch);
-+ }
-+ goto out;
-+ }
-+ is->dma_ch = ret;
-+ }
-+ file->private_data = state;
-+
-+ sound.mode = 0;
-+ if ( file->f_mode & FMODE_WRITE ) {
-+ sound.mode |= SOUND_PLAY_MODE;
-+ state->wr_ref = 1;
-+ os->fragsize = AUDIO_FRAGSIZE_DEFAULT;
-+ os->nbfrags = AUDIO_NBFRAGS_DEFAULT;
-+ os->output = 1;
-+ os->mapped = 0;
-+ init_waitqueue_head(&os->frag_wq);
-+ init_waitqueue_head(&os->stop_wq);
-+ *os->drcmr = os->dma_ch | DRCMR_MAPVLD;
-+ }
-+ if ( file->f_mode & FMODE_READ ) {
-+ sound.mode |= SOUND_REC_MODE;
-+ state->rd_ref = 1;
-+ is->fragsize = AUDIO_FRAGSIZE_DEFAULT;
-+ is->nbfrags = AUDIO_NBFRAGS_DEFAULT;
-+ is->output = 0;
-+ is->mapped = 0;
-+ init_waitqueue_head(&is->frag_wq);
-+ init_waitqueue_head(&is->stop_wq);
-+ *is->drcmr = is->dma_ch | DRCMR_MAPVLD;
-+ }
-+
-+ if ( (MINOR(inode->i_rdev) & 0x0f) == SND_DEV_AUDIO ) {
-+ tosa_set_freq(8000);
-+ tosa_set_stereo(0);
-+ tosa_set_format(AFMT_MU_LAW);
-+ }
-+
-+ settings.mode = sound.mode;
-+ settings.output.left = sound.volume_left;
-+ settings.output.right = sound.volume_right;
-+ settings.input.left = sound.gain_left;
-+ settings.input.right = sound.gain_right;
-+ settings.frequency = sound.freq;
-+ if ( (ret = wm9712_open(&settings)) < 0 ) {
-+ DEBUG(DBG_L0, "Can not open wm9712\n");
-+ goto error;
-+ }
-+ ret = 0;
-+
-+out:
-+ up(&state->sem);
-+ return ret;
-+
-+error:
-+ up(&state->sem);
-+ if ( (file->f_mode & FMODE_WRITE) && (os->dma_ch >= 0) ) {
-+ *os->drcmr = 0;
-+ pxa_free_dma(os->dma_ch);
-+ }
-+ if ( (file->f_mode & FMODE_READ) && (is->dma_ch >= 0) ) {
-+ *is->drcmr = 0;
-+ pxa_free_dma(is->dma_ch);
-+ }
-+ state->wr_ref = 0;
-+ state->rd_ref = 0;
-+ return ret;
-+}
-+
-+static int audio_write(struct file *file, const char *buffer,
-+ size_t count, loff_t * ppos)
-+{
-+ const char *buffer0 = buffer;
-+ audio_state_t *state = (audio_state_t *)file->private_data;
-+ audio_stream_t *s = state->output_stream;
-+ int ret = 0;
-+ ssize_t uUsed, bUsed, bLeft = 0;
-+ u_char *dest;
-+
-+ DEBUG(DBG_L2, "Enter audio_write\n");\
-+
-+ // wait playing int sound.
-+ while ( tosa_intmode_direct )
-+ schedule();
-+
-+ if ( ppos != &file->f_pos )
-+ return -ESPIPE;
-+ if ( s->mapped )
-+ return -ENXIO;
-+ if ( !s->buffers && audio_setup_buf(s) )
-+ return -ENOMEM;
-+ while ( count > 0 ) {
-+ audio_buf_t *b = &s->buffers[s->usr_frag];
-+ DEBUG(DBG_L3, "audio_write count = %d\n",count);
-+
-+ /* Grab a fragment */
-+ if ( file->f_flags & O_NONBLOCK ) {
-+ ret = -EAGAIN;
-+ if ( down_trylock(&s->sem) )
-+ break;
-+ } else {
-+ ret = -ERESTARTSYS;
-+ if ( down_interruptible(&s->sem) )
-+ break;
-+ }
-+
-+ /* Feed the current buffer */
-+ dest = b->data + b->offset;
-+ bUsed = 0;
-+ bLeft = s->fragsize - b->offset;
-+
-+ if ( ct_func ) {
-+ uUsed = ct_func(buffer, count, dest, &bUsed, bLeft);
-+ } else {
-+ return -EFAULT;
-+ }
-+
-+ if ( tosa_intmode ) {
-+ tosa_intmode_mix(dest,bUsed);
-+ }
-+
-+ if ( uUsed < 0 ) {
-+ up(&s->sem);
-+ return -EFAULT;
-+ }
-+ b->offset += bUsed;
-+ buffer += uUsed;
-+ count -= uUsed;
-+
-+ if ( b->offset < s->fragsize ) {
-+ up(&s->sem);
-+ break;
-+ }
-+ /*
-+ * Activate DMA on current buffer.
-+ * We unlock this fragment's checkpoint descriptor and
-+ * kick DMA if it is idle. Using checkpoint descriptors
-+ * allows for control operations without the need for
-+ * stopping the DMA channel if it is already running.
-+ */
-+ b->offset = 0;
-+ b->dma_desc->ddadr &= ~DDADR_STOP;
-+#ifdef DMA_NO_INITIALIZED
-+ if ( (DCSR(s->dma_ch) & DCSR_STOPSTATE) || !(DCSR(s->dma_ch) & DCSR_RUN) ){
-+ DDADR(s->dma_ch) = b->dma_desc->ddadr;
-+ DCSR(s->dma_ch) = DCSR_RUN;
-+ }
-+#else
-+ if ( DCSR(s->dma_ch) & DCSR_STOPSTATE ) {
-+ DDADR(s->dma_ch) = b->dma_desc->ddadr;
-+ DCSR(s->dma_ch) = DCSR_RUN;
-+ }
-+#endif /* DMA_NO_INITIALIZED */
-+
-+ /* move the index to the next fragment */
-+ if ( ++s->usr_frag >= s->nbfrags )
-+ s->usr_frag = 0;
-+ }
-+
-+ if ( (buffer - buffer0) )
-+ ret = buffer - buffer0;
-+ return ret;
-+}
-+
-+static int audio_read(struct file *file, char *buffer,
-+ size_t count, loff_t * ppos)
-+{
-+ char *buffer0 = buffer;
-+ audio_state_t *state = file->private_data;
-+ audio_stream_t *s = state->input_stream;
-+ int ret = 0;
-+ ssize_t uUsed, bUsed, bLeft = 0;
-+ u_char *dest;
-+
-+ if ( ppos != &file->f_pos )
-+ return -ESPIPE;
-+ if ( s->mapped )
-+ return -ENXIO;
-+ if ( !s->buffers && audio_setup_buf(s) )
-+ return -ENOMEM;
-+
-+ while ( count > 0 ) {
-+ audio_buf_t *b = &s->buffers[s->usr_frag];
-+
-+ /* prime DMA */
-+#ifdef DMA_NO_INITIALIZED
-+ if ( (DCSR(s->dma_ch) & DCSR_STOPSTATE) || !(DCSR(s->dma_ch) & DCSR_RUN) ){
-+ DDADR(s->dma_ch) = s->buffers[s->dma_frag].dma_desc->ddadr;
-+ DCSR(s->dma_ch) = DCSR_RUN;
-+ }
-+#else
-+ if (DCSR(s->dma_ch) & DCSR_STOPSTATE) {
-+ DDADR(s->dma_ch) = s->buffers[s->dma_frag].dma_desc->ddadr;
-+ DCSR(s->dma_ch) = DCSR_RUN;
-+ }
-+#endif /* DMA_NO_INITIALIZED */
-+
-+ /* Wait for a buffer to become full */
-+ if (file->f_flags & O_NONBLOCK) {
-+ ret = -EAGAIN;
-+ if (down_trylock(&s->sem))
-+ break;
-+ } else {
-+ ret = -ERESTARTSYS;
-+ if (down_interruptible(&s->sem))
-+ break;
-+ }
-+
-+ /* Grab data from current buffer */
-+ dest = b->data + b->offset;
-+ bUsed = 0;
-+ bLeft = s->fragsize - b->offset;
-+
-+ if (ct_read_func) {
-+ uUsed = ct_read_func(buffer, count, dest, &bUsed, bLeft);
-+ } else {
-+ return -EFAULT;
-+ }
-+ if ( uUsed < 0 ) {
-+ up(&s->sem);
-+ return -EFAULT;
-+ }
-+ b->offset += bUsed;
-+ buffer += uUsed;
-+ count -= uUsed;
-+
-+ if (b->offset < s->fragsize) {
-+ up(&s->sem);
-+ break;
-+ }
-+
-+ /*
-+ * Make this buffer available for DMA again.
-+ * We unlock this fragment's checkpoint descriptor and
-+ * kick DMA if it is idle. Using checkpoint descriptors
-+ * allows for control operations without the need for
-+ * stopping the DMA channel if it is already running.
-+ */
-+ b->offset = 0;
-+ b->dma_desc->ddadr &= ~DDADR_STOP;
-+
-+ /* move the index to the next fragment */
-+ if (++s->usr_frag >= s->nbfrags)
-+ s->usr_frag = 0;
-+ }
-+
-+ if ((buffer - buffer0))
-+ ret = buffer - buffer0;
-+ return ret;
-+}
-+
-+static int audio_sync(struct file *file)
-+{
-+ audio_state_t *state = file->private_data;
-+ audio_stream_t *s = state->output_stream;
-+ audio_buf_t *b;
-+ pxa_dma_desc *final_desc;
-+ u_long dcmd_save = 0;
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+ if (!(file->f_mode & FMODE_WRITE) || !s->buffers || s->mapped)
-+ return 0;
-+
-+ /*
-+ * Send current buffer if it contains data. Be sure to send
-+ * a full sample count.
-+ */
-+ final_desc = NULL;
-+ b = &s->buffers[s->usr_frag];
-+ if (b->offset &= ~3) {
-+ final_desc = &b->dma_desc[1 + b->offset/MAX_DMA_SIZE];
-+ b->offset &= (MAX_DMA_SIZE-1);
-+ dcmd_save = final_desc->dcmd;
-+ final_desc->dcmd = b->offset | s->dcmd | DCMD_ENDIRQEN;
-+ final_desc->ddadr |= DDADR_STOP;
-+ b->offset = 0;
-+ b->dma_desc->ddadr &= ~DDADR_STOP;
-+
-+#ifdef DMA_NO_INITIALIZED
-+ if ((DCSR(s->dma_ch) & DCSR_STOPSTATE)||!(DCSR(s->dma_ch) & DCSR_RUN)){
-+ DDADR(s->dma_ch) = b->dma_desc->ddadr;
-+ DCSR(s->dma_ch) = DCSR_RUN;
-+ }
-+#else
-+ if (DCSR(s->dma_ch) & DCSR_STOPSTATE) {
-+ DDADR(s->dma_ch) = b->dma_desc->ddadr;
-+ DCSR(s->dma_ch) = DCSR_RUN;
-+ }
-+#endif /* DMA_NO_INITIALIZED */
-+ }
-+ /* Wait for DMA to complete. */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ add_wait_queue(&s->frag_wq, &wait);
-+ while ((DCSR(s->dma_ch) & DCSR_RUN) && !signal_pending(current)) {
-+ schedule();
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&s->frag_wq, &wait);
-+
-+ tosa_intmode = 0;
-+
-+ /* Restore the descriptor chain. */
-+ if (final_desc) {
-+ final_desc->dcmd = dcmd_save;
-+ final_desc->ddadr &= ~DDADR_STOP;
-+ b->dma_desc->ddadr |= DDADR_STOP;
-+ }
-+ return 0;
-+}
-+
-+static unsigned int audio_poll(struct file *file,
-+ struct poll_table_struct *wait)
-+{
-+ audio_state_t *state = file->private_data;
-+ audio_stream_t *is = state->input_stream;
-+ audio_stream_t *os = state->output_stream;
-+ unsigned int mask = 0;
-+
-+ if (file->f_mode & FMODE_READ) {
-+ /* Start audio input if not already active */
-+ if (!is->buffers && audio_setup_buf(is))
-+ return -ENOMEM;
-+#ifdef DMA_NO_INITIALIZED
-+ if ((DCSR(is->dma_ch) & DCSR_STOPSTATE)|| !(DCSR(is->dma_ch) & DCSR_RUN)){
-+ DDADR(is->dma_ch) = is->buffers[is->dma_frag].dma_desc->ddadr;
-+ DCSR(is->dma_ch) = DCSR_RUN;
-+ }
-+#else
-+ if (DCSR(is->dma_ch) & DCSR_STOPSTATE) {
-+ DDADR(is->dma_ch) = is->buffers[is->dma_frag].dma_desc->ddadr;
-+ DCSR(is->dma_ch) = DCSR_RUN;
-+ }
-+#endif /* DMA_NO_INITIALIZED */
-+ poll_wait(file, &is->frag_wq, wait);
-+ }
-+
-+ if (file->f_mode & FMODE_WRITE) {
-+ if (!os->buffers && audio_setup_buf(os))
-+ return -ENOMEM;
-+ poll_wait(file, &os->frag_wq, wait);
-+ }
-+
-+ if (file->f_mode & FMODE_READ)
-+ if (( is->mapped && is->bytecount > 0) ||
-+ (!is->mapped && atomic_read(&is->sem.count) > 0))
-+ mask |= POLLIN | POLLRDNORM;
-+
-+ if (file->f_mode & FMODE_WRITE)
-+ if (( os->mapped && os->bytecount > 0) ||
-+ (!os->mapped && atomic_read(&os->sem.count) > 0))
-+ mask |= POLLOUT | POLLWRNORM;
-+
-+ return mask;
-+}
-+
-+static int audio_ioctl(struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ audio_state_t *state = file->private_data;
-+ audio_stream_t *os = state->output_stream;
-+ audio_stream_t *is = state->input_stream;
-+ long val, fmt;
-+ int data;
-+
-+ switch(cmd) {
-+ case OSS_GETVERSION:
-+ return put_user(SOUND_VERSION, (int *)arg);
-+ case SNDCTL_DSP_GETBLKSIZE:
-+ if ( file->f_mode & FMODE_WRITE )
-+ return put_user(os->fragsize, (int *)arg);
-+ else
-+ return put_user(is->fragsize, (int *)arg);
-+ case SNDCTL_DSP_GETCAPS:
-+ val = DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP;
-+ if (is && os)
-+ val |= DSP_CAP_DUPLEX;
-+ return put_user(val, (int *)arg);
-+ case SNDCTL_DSP_SETFRAGMENT:
-+ if ( get_user(val, (long *) arg) )
-+ return -EFAULT;
-+ if ( file->f_mode & FMODE_READ ) {
-+ int ret = audio_set_fragments(is, val);
-+ if (ret < 0) return ret;
-+ if ( (ret = put_user(ret, (int *)arg)) )
-+ return ret;
-+ }
-+ if ( file->f_mode & FMODE_WRITE ) {
-+ int ret = audio_set_fragments(os, val);
-+ if (ret < 0) return ret;
-+ if ( (ret = put_user(ret, (int *)arg)) )
-+ return ret;
-+ }
-+ return 0;
-+ case SNDCTL_DSP_SYNC:
-+ return audio_sync(file);
-+ case SNDCTL_DSP_POST:
-+ return 0;
-+ case SNDCTL_DSP_GETTRIGGER:
-+ val = 0;
-+ if ( file->f_mode & FMODE_READ && DCSR(is->dma_ch) & DCSR_RUN )
-+ val |= PCM_ENABLE_INPUT;
-+ if ( file->f_mode & FMODE_WRITE && DCSR(os->dma_ch) & DCSR_RUN )
-+ val |= PCM_ENABLE_OUTPUT;
-+ return put_user(val, (int *)arg);
-+ case SNDCTL_DSP_SETTRIGGER:
-+ if ( get_user(val, (int *)arg) )
-+ return -EFAULT;
-+ if ( file->f_mode & FMODE_READ ) {
-+ if ( val & PCM_ENABLE_INPUT ) {
-+ if ( !is->buffers && audio_setup_buf(is) )
-+ return -ENOMEM;
-+ if ( !(DCSR(is->dma_ch) & DCSR_RUN) ) {
-+ audio_buf_t *b = &is->buffers[is->dma_frag];
-+ DDADR(is->dma_ch) = b->dma_desc->ddadr;
-+ DCSR(is->dma_ch) = DCSR_RUN;
-+ }
-+ } else {
-+ DCSR(is->dma_ch) = 0;
-+ }
-+ }
-+ if ( file->f_mode & FMODE_WRITE ) {
-+ if ( val & PCM_ENABLE_OUTPUT ) {
-+ if ( !os->buffers && audio_setup_buf(os) )
-+ return -ENOMEM;
-+ if ( !(DCSR(os->dma_ch) & DCSR_RUN) ) {
-+ audio_buf_t *b = &os->buffers[os->dma_frag];
-+ DDADR(os->dma_ch) = b->dma_desc->ddadr;
-+ DCSR(os->dma_ch) = DCSR_RUN;
-+ }
-+ } else {
-+ DCSR(os->dma_ch) = 0;
-+ }
-+ }
-+ return 0;
-+ case SNDCTL_DSP_GETOSPACE:
-+ {
-+ audio_buf_info inf = { 0, };
-+ audio_stream_t *s = os;
-+ int j,k;
-+ if ( (s == os && !(file->f_mode & FMODE_WRITE)) )
-+ return -EINVAL;
-+ if ( !s->buffers && audio_setup_buf(s) )
-+ return -ENOMEM;
-+ j = s->usr_frag;
-+ k = s->dma_frag;
-+ if ( atomic_read(&s->sem.count) > 0 ) {
-+ if ( j > k ) {
-+ inf.fragments = s->nbfrags - ( j - k );
-+ } else if ( j < k ) {
-+ inf.fragments = k - j;
-+ } else {
-+ inf.fragments = s->nbfrags;
-+ }
-+ }
-+ inf.bytes = s->fragsize * inf.fragments;
-+ inf.fragsize = s->fragsize;
-+ inf.fragstotal = s->nbfrags;
-+ return copy_to_user((void *)arg, &inf, sizeof(inf));
-+ }
-+ case SNDCTL_DSP_GETISPACE:
-+ {
-+ audio_buf_info inf = { 0, };
-+ audio_stream_t *s = is;
-+ int j,k;
-+
-+ if ( (s == is && !(file->f_mode & FMODE_READ)) )
-+ return -EINVAL;
-+ if (!s->buffers && audio_setup_buf(s))
-+ return -ENOMEM;
-+
-+ j = s->usr_frag;
-+ k = s->dma_frag;
-+ if ( atomic_read(&s->sem.count) <= 0 ) {
-+ inf.fragments = 0;
-+ } else {
-+ inf.fragments = atomic_read(&s->sem.count);
-+ }
-+ inf.bytes = s->fragsize * inf.fragments;
-+ inf.fragsize = s->fragsize;
-+ inf.fragstotal = s->nbfrags;
-+ return copy_to_user((void *)arg, &inf, sizeof(inf));
-+ }
-+ case SNDCTL_DSP_GETOPTR:
-+ case SNDCTL_DSP_GETIPTR:
-+ {
-+ count_info inf = { 0, };
-+ audio_stream_t *s = (cmd == SNDCTL_DSP_GETOPTR) ? os : is;
-+ dma_addr_t ptr;
-+ int bytecount, offset, flags;
-+ if ( (s == is && !(file->f_mode & FMODE_READ)) ||
-+ (s == os && !(file->f_mode & FMODE_WRITE)) )
-+ return -EINVAL;
-+ if ( DCSR(s->dma_ch) & DCSR_RUN ) {
-+ audio_buf_t *b;
-+ save_flags_cli(flags);
-+ ptr = (s->output) ? DSADR(s->dma_ch) : DTADR(s->dma_ch);
-+ b = &s->buffers[s->dma_frag];
-+ offset = ptr - b->dma_desc->dsadr;
-+ if ( offset >= s->fragsize )
-+ offset = s->fragsize - 4;
-+ } else {
-+ save_flags(flags);
-+ offset = 0;
-+ }
-+ inf.ptr = s->dma_frag * s->fragsize + offset;
-+ bytecount = s->bytecount + offset;
-+ s->bytecount = -offset;
-+ inf.blocks = s->fragcount;
-+ s->fragcount = 0;
-+ restore_flags(flags);
-+ if ( bytecount < 0 )
-+ bytecount = 0;
-+ inf.bytes = bytecount;
-+ return copy_to_user((void *)arg, &inf, sizeof(inf));
-+ }
-+ case SNDCTL_DSP_NONBLOCK:
-+ file->f_flags |= O_NONBLOCK;
-+ return 0;
-+ case SNDCTL_DSP_RESET:
-+ if ( file->f_mode & FMODE_WRITE )
-+ pxa_audio_clear_buf(os);
-+ if ( file->f_mode & FMODE_READ )
-+ pxa_audio_clear_buf(is);
-+ return 0;
-+ case SNDCTL_DSP_SPEED:
-+ audio_sync(file);
-+ IOCTL_IN(arg, data);
-+ return IOCTL_OUT(arg, (*sound.mach.setFreq)(data));
-+ case SNDCTL_DSP_STEREO:
-+ audio_sync(file);
-+ IOCTL_IN(arg, data);
-+ return IOCTL_OUT(arg, (*sound.mach.setStereo)(data));
-+ case SOUND_PCM_WRITE_CHANNELS:
-+ audio_sync(file);
-+ IOCTL_IN(arg, data);
-+ return IOCTL_OUT(arg, (*sound.mach.setStereo)(data-1)+1);
-+ case SNDCTL_DSP_SETFMT:
-+ audio_sync(file);
-+ IOCTL_IN(arg, data);
-+ return IOCTL_OUT(arg, (*sound.mach.setFormat)(data));
-+ case SNDCTL_DSP_GETFMTS:
-+ fmt = 0;
-+ if (sound.trans) {
-+ if (sound.trans->ct_ulaw)
-+ fmt |= AFMT_MU_LAW;
-+ if (sound.trans->ct_alaw)
-+ fmt |= AFMT_A_LAW;
-+ if (sound.trans->ct_s8)
-+ fmt |= AFMT_S8;
-+ if (sound.trans->ct_u8)
-+ fmt |= AFMT_U8;
-+ if (sound.trans->ct_s16be)
-+ fmt |= AFMT_S16_BE;
-+ if (sound.trans->ct_u16be)
-+ fmt |= AFMT_U16_BE;
-+ if (sound.trans->ct_s16le)
-+ fmt |= AFMT_S16_LE;
-+ if (sound.trans->ct_u16le)
-+ fmt |= AFMT_U16_LE;
-+ }
-+ return IOCTL_OUT(arg, fmt);
-+ default:
-+ return mixer_ioctl(inode, file, cmd, arg);
-+ }
-+ return 0;
-+}
-+
-+static int audio_mmap(struct file *file, struct vm_area_struct *vma)
-+{
-+ audio_state_t *state = file->private_data;
-+ audio_stream_t *s;
-+ unsigned long size, vma_addr;
-+ int i, ret;
-+
-+ if (vma->vm_pgoff != 0)
-+ return -EINVAL;
-+
-+ if (vma->vm_flags & VM_WRITE) {
-+ if (!state->wr_ref)
-+ return -EINVAL;;
-+ s = state->output_stream;
-+ } else if (vma->vm_flags & VM_READ) {
-+ if (!state->rd_ref)
-+ return -EINVAL;
-+ s = state->input_stream;
-+ } else return -EINVAL;
-+
-+ if (s->mapped)
-+ return -EINVAL;
-+ size = vma->vm_end - vma->vm_start;
-+ if (size != s->fragsize * s->nbfrags)
-+ return -EINVAL;
-+ if (!s->buffers && audio_setup_buf(s))
-+ return -ENOMEM;
-+ vma_addr = vma->vm_start;
-+ for (i = 0; i < s->nbfrags; i++) {
-+ audio_buf_t *buf = &s->buffers[i];
-+ if (!buf->master)
-+ continue;
-+ ret = remap_page_range(vma_addr, buf->dma_desc->dsadr,
-+ buf->master, vma->vm_page_prot);
-+ if (ret)
-+ return ret;
-+ vma_addr += buf->master;
-+ }
-+ for (i = 0; i < s->nbfrags; i++)
-+ s->buffers[i].dma_desc->ddadr &= ~DDADR_STOP;
-+ s->mapped = 1;
-+ return 0;
-+}
-+
-+static int audio_release(struct inode *inode, struct file *file)
-+{
-+ audio_state_t *state = file->private_data;
-+ int err;
-+
-+ down(&state->sem);
-+ if ( file->f_mode & FMODE_READ ) {
-+ pxa_audio_clear_buf(state->input_stream);
-+ *state->input_stream->drcmr = 0;
-+ pxa_free_dma(state->input_stream->dma_ch);
-+ state->rd_ref = 0;
-+ }
-+
-+ if ( file->f_mode & FMODE_WRITE ) {
-+ audio_sync(file);
-+ pxa_audio_clear_buf(state->output_stream);
-+ *state->output_stream->drcmr = 0;
-+ pxa_free_dma(state->output_stream->dma_ch);
-+ state->wr_ref = 0;
-+ }
-+
-+ // Close wm9712
-+ if( (err = wm9712_close()) ) {
-+ DEBUG(DBG_L0, "Can not close wm9712\n");
-+ return err;
-+ }
-+ sound.mode = 0;
-+ up(&state->sem);
-+ return 0;
-+}
-+
-+static struct file_operations ac97_audio_fops = {
-+ llseek: no_llseek,
-+ write: audio_write,
-+ read: audio_read,
-+ poll: audio_poll,
-+ ioctl: audio_ioctl,
-+ open: audio_open,
-+ release: audio_release,
-+ mmap: audio_mmap,
-+ owner: THIS_MODULE
-+};
-+
-+static void tosa_intmode_mix(unsigned char *dest,int bUsed)
-+#ifdef ALARM_NO_MALLOC
-+{
-+ int i;
-+ short *cdata = (short *)dest;
-+ int cnt = min(tosa_intmode, bUsed);
-+ int idx;
-+
-+ for ( i = 0; i < (cnt/4); i++ ) {
-+ idx = (tosa_intmode_cur>>8);
-+ *cdata++ = int_data_org[idx*2];
-+ *cdata++ = int_data_org[idx*2+1];
-+ tosa_intmode_cur += tosa_intmode_step;
-+ }
-+
-+ tosa_intmode -= cnt;
-+ if ( tosa_intmode <= 0 ) {
-+ tosa_intmode = 0;
-+ int_data_org = NULL;
-+ }
-+}
-+#else
-+{
-+ int i;
-+ short *cdata = (short *)dest;
-+ int cnt = min(tosa_intmode, bUsed);
-+
-+ for ( i = 0; i < (cnt/4); i++ ) {
-+ *cdata = *int_data;
-+ int_data++;
-+ cdata++;
-+ *cdata = *int_data;
-+ int_data++;
-+ cdata++;
-+ }
-+
-+ tosa_intmode -= cnt;
-+ if ( tosa_intmode <= 0 ) {
-+ tosa_intmode = 0;
-+ if ( int_data_org ) {
-+ kfree(int_data_org);
-+ int_data_org = NULL;
-+ }
-+ }
-+}
-+#endif /* ALARM_NO_MALLOC */
-+
-+/************************************************************
-+ * Buzzer
-+ ************************************************************/
-+#ifdef CONFIG_BUZZER_TOSA
-+
-+#ifdef ALARM_NO_MALLOC
-+int audio_buzzer_intmode(unsigned short *buffer,int count,int speed)
-+{
-+ int idx,i;
-+ unsigned long snddata;
-+ audio_state_t *state = &ac97_audio_state;
-+ audio_stream_t *os = state->output_stream;
-+ audio_stream_t *s = os;
-+
-+ int_data_org = buffer;
-+ tosa_intmode = (count * sound.freq / speed)&(~3);
-+ tosa_intmode_speed = speed;
-+ tosa_intmode_cur = 0;
-+ tosa_intmode_step = (speed << 8 ) / sound.freq; // fixed point (x256)
-+ tosa_intmode_direct = 1;
-+
-+ // pause during play or recording , so kick this place.
-+ if ( ((DCSR(s->dma_ch) & DCSR_STOPSTATE) && (state->wr_ref)) ||
-+ ((!state->wr_ref ) && ( state->rd_ref)) ) {
-+ for ( i = 0; i < (tosa_intmode/4) ; i++ ) {
-+ idx = (tosa_intmode_cur>>8);
-+ snddata = (buffer[idx*2]|(buffer[idx*2+1]<<16));
-+ tosa_intmode_cur += tosa_intmode_step;
-+ tosa_ac97_write(snddata);
-+ }
-+ tosa_intmode = 0;
-+ int_data_org = NULL;
-+ }
-+ tosa_intmode_direct = 0;
-+ return 1;
-+}
-+#else /* ALARM_NO_MALLOC */
-+int audio_buzzer_intmode(unsigned short *buffer,int count,int speed)
-+{
-+ int samplingCount = count * sound.hw_freq / speed;
-+ int idx,i ;
-+ int cur=0,step = (speed << 8 ) / sound.hw_freq; // fixed point (x256)
-+ unsigned short *dstct;
-+
-+ int_data = (unsigned short *)kmalloc(count * 6,GFP_KERNEL);
-+ if ( !int_data ) return 0;
-+ int_data_org = int_data;
-+
-+ samplingCount &= ~0x3;
-+
-+ dstct = int_data;
-+ for( i = 0; i < (samplingCount/4); i++ ) {
-+ idx = (cur>>8);
-+ *dstct++ = buffer[idx*2];
-+ *dstct++ = buffer[idx*2+1];
-+ cur += step;
-+ }
-+
-+ tosa_intmode = samplingCount;
-+ tosa_intmode_speed = speed;
-+ tosa_intmode_direct = 1;
-+
-+ {
-+ audio_state_t *state = &ac97_audio_state;
-+ audio_stream_t *os = state->output_stream;
-+ audio_stream_t *s = os;
-+
-+ // pause during play or recording , so kick this place.
-+ if ( ((DCSR(s->dma_ch) & DCSR_STOPSTATE) && (state->wr_ref)) ||
-+ ((!state->wr_ref) && (state->rd_ref)) ) {
-+ int i;
-+ for ( i = 0; i < (tosa_intmode/4); i++ ) {
-+ tosa_ac97_write(*(unsigned long *)int_data);
-+ int_data++;
-+ int_data++;
-+ }
-+ tosa_intmode = 0;
-+ kfree(int_data_org);
-+ int_data_org = NULL;
-+ }
-+ }
-+
-+ tosa_intmode_direct = 0;
-+ return 1;
-+}
-+#endif /* ALARM_NO_MALLOC */
-+
-+int audio_buzzer_write(const char *buffer,int count)
-+{
-+ const char *buffer0 = buffer;
-+ audio_state_t *state = &ac97_audio_state;
-+ audio_stream_t *s = state->output_stream;
-+ int chunksize, ret = 0;
-+
-+
-+ if (!s->buffers && audio_setup_buf(s))
-+ return -ENOMEM;
-+
-+ while ( count > 0 ) {
-+ audio_buf_t *b = &s->buffers[s->usr_frag];
-+
-+#ifdef BUZZER_FORCE_CLOSE
-+ if( buzzer_close ) break;
-+#endif
-+
-+ chunksize = s->fragsize - b->offset;
-+ if ( chunksize > count )
-+ chunksize = count;
-+ memcpy(b->data + b->offset, buffer, chunksize);
-+
-+ b->offset += chunksize;
-+ buffer += chunksize;
-+ count -= chunksize;
-+
-+ if ( b->offset < s->fragsize ) {
-+ up(&s->sem);
-+ break;
-+ }
-+
-+ b->offset = 0;
-+ b->dma_desc->ddadr &= ~DDADR_STOP;
-+#ifdef DMA_NO_INITIALIZED
-+ if ( (DCSR(s->dma_ch) & DCSR_STOPSTATE )|| !(DCSR(s->dma_ch) & DCSR_RUN) ){
-+ DDADR(s->dma_ch) = b->dma_desc->ddadr;
-+ DCSR(s->dma_ch) = DCSR_RUN;
-+ }
-+#else
-+ if ( DCSR(s->dma_ch) & DCSR_STOPSTATE ) {
-+ DDADR(s->dma_ch) = b->dma_desc->ddadr;
-+ DCSR(s->dma_ch) = DCSR_RUN;
-+ }
-+#endif
-+
-+ /* move the index to the next fragment */
-+ if ( ++s->usr_frag >= s->nbfrags )
-+ s->usr_frag = 0;
-+ }
-+
-+ if ( buffer - buffer0 )
-+ ret = buffer - buffer0;
-+
-+ return ret;
-+}
-+
-+void audio_buzzer_sync(void)
-+{
-+ audio_state_t *state = &ac97_audio_state;
-+ audio_stream_t *s = state->output_stream;
-+ audio_buf_t *b;
-+ pxa_dma_desc *final_desc;
-+ u_long dcmd_save = 0;
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+#ifdef BUZZER_FORCE_CLOSE
-+ if( buzzer_close ) goto sync_end;
-+#endif
-+
-+ //audio_sync(file);
-+
-+ /*
-+ * Send current buffer if it contains data. Be sure to send
-+ * a full sample count.
-+ */
-+ final_desc = NULL;
-+ b = &s->buffers[s->usr_frag];
-+ if ( b->offset &= ~3 ) {
-+ final_desc = &b->dma_desc[1 + b->offset/MAX_DMA_SIZE];
-+ b->offset &= (MAX_DMA_SIZE-1);
-+ dcmd_save = final_desc->dcmd;
-+ final_desc->dcmd = b->offset | s->dcmd | DCMD_ENDIRQEN;
-+ final_desc->ddadr |= DDADR_STOP;
-+ b->offset = 0;
-+ b->dma_desc->ddadr &= ~DDADR_STOP;
-+#ifdef DMA_NO_INITIALIZED
-+ if ( (DCSR(s->dma_ch) & DCSR_STOPSTATE) || !(DCSR(s->dma_ch) & DCSR_RUN) ) {
-+ DDADR(s->dma_ch) = b->dma_desc->ddadr;
-+ DCSR(s->dma_ch) = DCSR_RUN;
-+ }
-+#else
-+ if ( DCSR(s->dma_ch) & DCSR_STOPSTATE ) {
-+ DDADR(s->dma_ch) = b->dma_desc->ddadr;
-+ DCSR(s->dma_ch) = DCSR_RUN;
-+ }
-+#endif
-+ }
-+
-+#ifdef BUZZER_FORCE_CLOSE
-+sync_end:;
-+#endif
-+
-+ /* Wait for DMA to complete. */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ add_wait_queue(&s->frag_wq, &wait);
-+ while ( (DCSR(s->dma_ch) & DCSR_RUN) && !signal_pending(current) ) {
-+ schedule();
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ }
-+
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&s->frag_wq, &wait);
-+}
-+
-+int audio_buzzer_release(void)
-+{
-+ audio_state_t *state = &ac97_audio_state;
-+ audio_stream_t *s = state->output_stream;
-+ int err, ret = 0;
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+
-+ //audio_sync(file);
-+ /* Wait for DMA to complete. */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ add_wait_queue(&s->frag_wq, &wait);
-+ while ( (DCSR(s->dma_ch) & DCSR_RUN) && !signal_pending(current) ) {
-+ schedule();
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ }
-+
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&s->frag_wq, &wait);
-+
-+ audio_clear_buf(state->output_stream);
-+ *state->output_stream->drcmr = 0;
-+ pxa_free_dma(state->output_stream->dma_ch);
-+ state->wr_ref = 0;
-+
-+#ifdef ALARM_NO_MALLOC
-+ // wait playing int sound.
-+#ifdef BUZZER_FORCE_CLOSE
-+ while ( tosa_intmode_direct && !buzzer_close )
-+ schedule();
-+#else
-+ while ( tosa_intmode_direct )
-+ schedule();
-+#endif /* BUZZER_FORCE_CLOSE */
-+
-+ tosa_intmode = 0;
-+ int_data_org = NULL;
-+#else
-+ if ( int_data_org ) {
-+ kfree(int_data_org);
-+ int_data_org = NULL;
-+ }
-+#endif /* ALARM_NO_MALLOC */
-+ if( (err = wm9712_close()) < 0 ) {
-+ DEBUG(DBG_L0, "Can not close wm9712\n");
-+ ret = err;
-+ }
-+ state->wr_ref = 0;
-+#ifdef BUZZER_FORCE_CLOSE
-+ buzzer_open = 0;
-+#endif /* BUZZER_FORCE_CLOSE */
-+ return 0;
-+}
-+
-+int audio_buzzer_open(int speed)
-+{
-+ audio_state_t *state = &ac97_audio_state;
-+ audio_stream_t *os = state->output_stream;
-+ SOUND_SETTINGS settings;
-+ int err;
-+
-+ err = -EBUSY;
-+ if ( state->wr_ref || state->rd_ref )
-+ goto out;
-+
-+ state->wr_ref = 1;
-+
-+#ifdef BUZZER_FORCE_CLOSE
-+ buzzer_open = 1;
-+#endif /* BUZZER_FORCE_CLOSE */
-+
-+ /* request DMA channels */
-+ if ( (err = pxa_request_dma(os->name, DMA_PRIO_LOW, audio_dma_irq, os)) < 0 )
-+ goto error;
-+ os->dma_ch = err;
-+
-+ os->fragsize = AUDIO_FRAGSIZE_DEFAULT;
-+ os->nbfrags = AUDIO_NBFRAGS_DEFAULT;
-+ os->output = 1;
-+ os->mapped = 0;
-+ init_waitqueue_head(&os->frag_wq);
-+ init_waitqueue_head(&os->stop_wq);
-+ *os->drcmr = os->dma_ch | DRCMR_MAPVLD;
-+
-+ sound.mode = SOUND_PLAY_MODE;
-+ settings.mode = sound.mode;
-+ settings.output.left = sound.volume_left;
-+ settings.output.right = sound.volume_right;
-+ settings.input.left = sound.gain_left;
-+ settings.input.right = sound.gain_right;
-+ settings.frequency = speed;
-+
-+ if( (err = wm9712_open(&settings)) < 0 ) {
-+ DEBUG(DBG_L0, "Can not open wm9712\n");
-+ goto error;
-+ }
-+
-+ sound.freq = speed;
-+
-+ err = 0;
-+out:
-+#ifdef BUZZER_FORCE_CLOSE
-+ if( buzzer_close ){
-+ err = -EBUSY;
-+ goto error;
-+ }
-+#endif
-+ return err;
-+
-+error:
-+ *os->drcmr = 0;
-+ pxa_free_dma(os->dma_ch);
-+ state->wr_ref = 0;
-+ return err;
-+}
-+#endif /* CONFIG_BUZZER_TOSA */
-+
-+/************************************************************
-+ * /dev/sndstat
-+ * Audio Stat stuff
-+ ************************************************************/
-+static int state_open(struct inode *inode, struct file *file)
-+{
-+ char *buffer = tosa_sound_state.buf;
-+ int len = 0;
-+
-+ if ( tosa_sound_state.busy ) return -EBUSY;
-+
-+ MOD_INC_USE_COUNT;
-+ tosa_sound_state.ptr = 0;
-+ tosa_sound_state.busy = 1;
-+
-+ len += sprintf(buffer+len, " TOSA AC97 sound driver:\n");
-+ len += sprintf(buffer+len, "\tsound.speed = %dHz\n", sound.freq);
-+ len += sprintf(buffer+len, "\tsound.stereo = 0x%x (%s)\n",
-+ sound.stereo, sound.stereo ? "stereo" : "mono");
-+ tosa_sound_state.len = len;
-+ return 0;
-+}
-+
-+static int state_release(struct inode *inode, struct file *file)
-+{
-+ tosa_sound_state.busy = 0;
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static ssize_t state_read(struct file *file, char *buf, size_t count,
-+ loff_t *ppos)
-+{
-+ int n = tosa_sound_state.len - tosa_sound_state.ptr;
-+ if ( n > count ) n = count;
-+ if ( n <= 0 ) return 0;
-+ if ( copy_to_user(buf, &tosa_sound_state.buf[tosa_sound_state.ptr], n) )
-+ return -EFAULT;
-+ tosa_sound_state.ptr += n;
-+ return n;
-+}
-+
-+static struct file_operations state_fops =
-+{
-+ llseek: no_llseek,
-+ read: state_read,
-+ open: state_open,
-+ release: state_release,
-+};
-+
-+static void state_init(void)
-+{
-+ tosa_sound_state.dev_state =
-+ register_sound_special(&state_fops, SND_DEV_STATUS);
-+ if ( tosa_sound_state.dev_state < 0 ) return;
-+ tosa_sound_state.busy = 0;
-+}
-+
-+/************************************************************
-+ * /dev/mixer
-+ * Audio Mixer stuff
-+ ************************************************************/
-+static int mixer_ioctl( struct inode *inode, struct file *file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ int data;
-+
-+ switch (cmd) {
-+ case SOUND_MIXER_READ_DEVMASK:
-+ return IOCTL_OUT(arg, (SOUND_MASK_VOLUME|SOUND_MASK_MIC) );
-+ case SOUND_MIXER_READ_RECMASK:
-+ return IOCTL_OUT(arg, 0);
-+ case SOUND_MIXER_READ_STEREODEVS:
-+ return IOCTL_OUT(arg, SOUND_MASK_VOLUME);
-+ case SOUND_MIXER_READ_CAPS:
-+ return IOCTL_OUT(arg, 0);
-+ case SOUND_MIXER_WRITE_VOLUME:
-+ IOCTL_IN(arg, data);
-+ (*sound.mach.setVolume)(data);
-+ case SOUND_MIXER_READ_VOLUME:
-+ return IOCTL_OUT(arg, (*sound.mach.getVolume)());
-+ case SOUND_MIXER_READ_TREBLE:
-+ return IOCTL_OUT(arg, 0);
-+ case SOUND_MIXER_WRITE_TREBLE:
-+ return IOCTL_OUT(arg, 0);
-+ case SOUND_MIXER_READ_SPEAKER:
-+ return IOCTL_OUT(arg, 0);
-+ case SOUND_MIXER_WRITE_SPEAKER:
-+ return IOCTL_OUT(arg, 0);
-+ case SOUND_MIXER_WRITE_MIC:
-+ IOCTL_IN(arg, data);
-+ (*sound.mach.setGain)(data);
-+ case SOUND_MIXER_READ_MIC:
-+ return IOCTL_OUT(arg, (*sound.mach.getGain)());
-+ case SOUND_MIXER_AGC:
-+ IOCTL_IN(arg, data);
-+ return IOCTL_OUT(arg, wm9712_set_agc(data));
-+ }
-+ return -EINVAL;
-+}
-+
-+static int mixer_open(struct inode *inode, struct file *file)
-+{
-+ if ( codec->mixer_busy ) return -EBUSY;
-+ MOD_INC_USE_COUNT;
-+ codec->mixer_busy = 1;
-+ return 0;
-+}
-+
-+static int mixer_release(struct inode *inode, struct file *file)
-+{
-+ codec->mixer_busy = 0;
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static struct file_operations mixer_fops = {
-+ ioctl: mixer_ioctl,
-+ llseek: no_llseek,
-+ open: mixer_open,
-+ release: mixer_release,
-+ owner: THIS_MODULE
-+};
-+
-+static void mixer_init(void)
-+{
-+ codec->dev_mixer = register_sound_mixer(&mixer_fops, -1);
-+ if ( codec->dev_mixer < 0 ) return;
-+ codec->mixer_busy = 0;
-+}
-+
-+/************************************************************
-+ * /dev/dsp
-+ * Audio stuff
-+ ************************************************************/
-+static void sq_init(void)
-+{
-+ /* Regist /dev/dsp. */
-+ ac97_audio_state.dev_dsp = register_sound_dsp(&ac97_audio_fops, -1);
-+ if( ac97_audio_state.dev_dsp < 0 ) return;
-+
-+ ac97_audio_state.wr_ref = 0;
-+ ac97_audio_state.rd_ref = 0;
-+
-+ /* Set default settings */
-+ sound.format = AFMT_S16_LE;
-+ sound.stereo = 1;
-+ sound.freq = 48000;
-+ sound.size = 16;
-+ sound.trans = &trans_tosa;
-+ sound.trans_read = &trans_r_tosa;
-+ sound.volume_left = 80;
-+ sound.volume_right = 80;
-+ sound.gain_left = 40;
-+ sound.gain_right = 40;
-+
-+ /* Change Format */
-+ (*sound.mach.setFormat)(sound.format);
-+}
-+
-+static int __init pxa_ac97_init(void)
-+{
-+ sound.mach = mach_tosa;
-+
-+ if( (*sound.mach.init)() < 0 ) {
-+ wm9712_exit();
-+ return -EBUSY;
-+ }
-+ /* Set default settings. */
-+ sq_init();
-+ /* Set up /dev/sndstat. */
-+ state_init();
-+ /* Set up /dev/mixer. */
-+ mixer_init();
-+#ifdef CONFIG_PM
-+ pxa_sound_pm_dev = pm_register(PM_SYS_DEV, 0, tosa_pm_callback);
-+#endif /* CONFIG_PM */
-+
-+ printk(KERN_INFO "Tosa AC97 initialize\n");
-+
-+ return 0;
-+}
-+
-+static void __exit pxa_ac97_exit(void)
-+{
-+ if ( ac97_audio_state.dev_dsp >= 0 )
-+ unregister_sound_dsp(ac97_audio_state.dev_dsp);
-+ unregister_sound_mixer(codec->dev_mixer);
-+ if ( tosa_sound_state.dev_state >= 0 )
-+ unregister_sound_special(tosa_sound_state.dev_state);
-+ wm9712_exit();
-+}
-+
-+
-+module_init(pxa_ac97_init);
-+module_exit(pxa_ac97_exit);
-+
-+#ifdef CONFIG_PM
-+/************************************************************
-+ * Power Management
-+ ************************************************************/
-+static int tosa_pm_callback(struct pm_dev *pm_dev,pm_request_t req, void *data)
-+{
-+ int err;
-+ switch (req) {
-+ case PM_SUSPEND:
-+ DEBUG(DBG_L1, "PM_SUSPEND: start\n");
-+ wm9712_suspend();
-+#ifdef CONFIG_TOSA_TS
-+ tosa_ts_suspend();
-+#endif /* CONFIG_TOSA_TS */
-+ if ( ac97_audio_state.rd_ref != 0 ) {
-+ audio_clear_buf(ac97_audio_state.input_stream);
-+ *ac97_audio_state.input_stream->drcmr = 0;
-+ pxa_free_dma(ac97_audio_state.input_stream->dma_ch);
-+ }
-+
-+ if ( ac97_audio_state.wr_ref != 0 ) {
-+ audio_clear_buf(ac97_audio_state.output_stream);
-+ *ac97_audio_state.output_stream->drcmr = 0;
-+ pxa_free_dma(ac97_audio_state.output_stream->dma_ch);
-+ }
-+ DEBUG(DBG_L1, "PM_SUSPEND: done\n");
-+ break;
-+ case PM_RESUME:
-+ DEBUG(DBG_L1, "PM_RESUME: start\n");
-+ /* request DMA channels */
-+ if ( ac97_audio_state.wr_ref != 0 ) {
-+ init_waitqueue_head(&ac97_audio_state.output_stream->frag_wq);
-+ init_waitqueue_head(&ac97_audio_state.output_stream->stop_wq);
-+ *ac97_audio_state.output_stream->drcmr =
-+ ac97_audio_state.output_stream->dma_ch | DRCMR_MAPVLD;
-+ err = pxa_request_dma(ac97_audio_state.output_stream->name, DMA_PRIO_LOW,
-+ audio_dma_irq, ac97_audio_state.output_stream);
-+ if ( err < 0 ) {
-+ DEBUG(DBG_L0, "Can not get DMA\n");
-+ }
-+ ac97_audio_state.output_stream->dma_ch = err;
-+ }
-+ if ( ac97_audio_state.rd_ref != 0 ) {
-+ init_waitqueue_head(&ac97_audio_state.input_stream->frag_wq);
-+ init_waitqueue_head(&ac97_audio_state.input_stream->stop_wq);
-+ *ac97_audio_state.input_stream->drcmr =
-+ ac97_audio_state.input_stream->dma_ch | DRCMR_MAPVLD;
-+ err = pxa_request_dma(ac97_audio_state.input_stream->name, DMA_PRIO_LOW,
-+ audio_dma_irq, ac97_audio_state.input_stream);
-+ if ( err < 0 ) {
-+ DEBUG(DBG_L0, "Can not get DMA\n");
-+ }
-+ ac97_audio_state.input_stream->dma_ch = err;
-+ }
-+ wm9712_resume();
-+#ifdef CONFIG_TOSA_TS
-+ tosa_ts_resume();
-+#endif /* CONFIG_TOSA_TS */
-+ DEBUG(DBG_L1, "PM_RESUME: done\n");
-+ break;
-+ }
-+ return 0;
-+}
-+#endif /* CONFIG_PM */
-diff -Nur linux_c860_org/drivers/sound/pxa-audio.c linux/drivers/sound/pxa-audio.c
---- linux_c860_org/drivers/sound/pxa-audio.c 2002-08-26 15:00:56.000000000 +0900
-+++ linux/drivers/sound/pxa-audio.c 2004-06-10 21:09:10.000000000 +0900
-@@ -8,6 +8,9 @@
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-+ *
-+ * ChangeLog:
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- #include <linux/init.h>
-@@ -78,7 +81,11 @@
- * This function allocates the DMA descriptor array and buffer data space
- * according to the current number of fragments and fragment size.
- */
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+int audio_setup_buf(audio_stream_t * s)
-+#else
- static int audio_setup_buf(audio_stream_t * s)
-+#endif /* CONFIG_ARCH_PXA_TOSA */
- {
- pxa_dma_desc *dma_desc;
- dma_addr_t dma_desc_phys;
-@@ -258,7 +265,11 @@
- /*
- * Validate and sets up buffer fragments, etc.
- */
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+int audio_set_fragments(audio_stream_t *s, int val)
-+#else
- static int audio_set_fragments(audio_stream_t *s, int val)
-+#endif /* CONFIG_ARCH_PXA_TOSA */
- {
- if (s->mapped || DCSR(s->dma_ch) & DCSR_RUN)
- return -EBUSY;
-@@ -428,7 +439,11 @@
- }
-
-
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+int audio_sync(struct file *file)
-+#else
- static int audio_sync(struct file *file)
-+#endif /* CONFIG_ARCH_PXA_TOSA */
- {
- audio_state_t *state = file->private_data;
- audio_stream_t *s = state->output_stream;
-@@ -810,12 +825,16 @@
- }
-
- file->private_data = state;
-+#ifndef CONFIG_ARCH_PXA_TOSA
- file->f_op->release = audio_release;
-+#endif /* CONFIG_ARCH_PXA_TOSA */
- file->f_op->write = audio_write;
- file->f_op->read = audio_read;
- file->f_op->mmap = audio_mmap;
- file->f_op->poll = audio_poll;
-+#ifndef CONFIG_ARCH_PXA_TOSA
- file->f_op->ioctl = audio_ioctl;
-+#endif /* CONFIG_ARCH_PXA_TOSA */
- file->f_op->llseek = no_llseek;
-
- if ((file->f_mode & FMODE_WRITE)) {
-@@ -849,3 +868,8 @@
- EXPORT_SYMBOL(pxa_audio_attach);
- EXPORT_SYMBOL(pxa_audio_clear_buf);
-
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+EXPORT_SYMBOL(audio_set_fragments);
-+EXPORT_SYMBOL(audio_sync);
-+EXPORT_SYMBOL(audio_setup_buf);
-+#endif
-diff -Nur linux_c860_org/drivers/sound/sound_core.c linux/drivers/sound/sound_core.c
---- linux_c860_org/drivers/sound/sound_core.c 2002-08-26 14:38:55.000000000 +0900
-+++ linux/drivers/sound/sound_core.c 2004-06-10 21:09:10.000000000 +0900
-@@ -37,6 +37,7 @@
- #include <linux/config.h>
- #include <linux/module.h>
- #include <linux/init.h>
-+#include <linux/sched.h>
- #include <linux/slab.h>
- #include <linux/types.h>
- #include <linux/kernel.h>
-diff -Nur linux_c860_org/drivers/sound/tosa_wm9712.c linux/drivers/sound/tosa_wm9712.c
---- linux_c860_org/drivers/sound/tosa_wm9712.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/sound/tosa_wm9712.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,861 @@
-+/*
-+ * linux/drivers/sound/tosa_wm9712.c
-+ *
-+ * wm9712 ctrl funstions for PXA (SHARP)
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * Based on:
-+ * linux/drivers/sound/poodle_wm8731.c
-+ * wm8731 ctrl funstions for PXA (SHARP)
-+ * Copyright (C) 2002 SHARP
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ */
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/poll.h>
-+#include <linux/delay.h>
-+#include <linux/config.h>
-+#include <linux/init.h>
-+#include <linux/module.h>
-+#include <linux/ac97_codec.h>
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/irqs.h>
-+
-+#ifdef CONFIG_PM
-+#include <asm/sharp_apm.h>
-+#endif /* CONFIG_PM */
-+
-+#include <asm/arch/tosa_wm9712.h>
-+
-+/************************************************************
-+ * Debug
-+ ************************************************************/
-+#define DBG_LEVEL 0
-+
-+#define DBG_L0 0
-+#define DBG_L1 1
-+#define DBG_L2 2
-+#define DBG_L3 3
-+
-+#ifdef DBG_LEVEL
-+#define DEBUG(level, x, args...) \
-+ if ( level <= DBG_LEVEL ) printk("%s: " x,__FUNCTION__ ,##args)
-+#else
-+#define DEBUG(level, x, args...) \
-+ if ( !level ) printk("%s: " x,__FUNCTION__ ,##args)
-+#endif /* DBG_LEVEL */
-+
-+//X#define DISABLE_JACKCHECK_PLAYING
-+//X#define USE_HARDWARE_LMIX
-+
-+/*** Some valiables **************************************************/
-+typedef struct {
-+ unsigned char used; //used: open(1) close(0)
-+ unsigned char jack; //Jack: in(1) out(0)
-+ unsigned char mic; // Mic headPhone(1) no mic(0)
-+ unsigned char last_jack_state; // jack state
-+ unsigned char open_play;
-+ unsigned char open_rec;
-+ unsigned short mode; //Sound mode
-+ int out_left; //Volume out left
-+ int out_right; //Volume out right
-+ int in_left; //Volume in left
-+ int in_right; //Volume in right
-+ int rate; //Sampling rate
-+ int agc; //Agc: on(1) off(0)
-+ int vol0;
-+#ifdef DISABLE_JACKCHECK_PLAYING
-+ int need_after_check; // check jack after playing
-+#endif
-+#ifdef CONFIG_PM
-+ int suspend; //Suspend: on(1) off(0)
-+#endif /* CONFIG_PM */
-+} wm9712_stat_t;
-+
-+static wm9712_stat_t wm9712_stat;
-+static unsigned char ac97_on = 0;
-+int wm9712_mono_out = 0; // mix output data into mono
-+//static spinlock_t ear_in_lock = SPIN_LOCK_UNLOCKED;
-+//static struct tq_struct wm9712_queue;
-+static struct timer_list hp_wakeup_timer;
-+#define HP_WAKEUP_DELAY (HZ*3)
-+
-+static int wm9712_setup(SOUND_SETTINGS *);
-+static void wm9712_update_agc(int);
-+
-+#define MAKEJACKSTATE(jack,mic) ((jack)*2+(mic))
-+#define INVALID_JACKSTATE -1
-+#define DEV_OUTALL 0
-+#define DEV_SP 1
-+#define DEV_HP 2
-+#define DEV_HPL 3
-+#define DEV_MIC 4
-+
-+#define BIT_ZC (0x1<<7)
-+#define BIT_INV (0x1<<6)
-+#define VOLL_SHIFT 8
-+#define VOLL_MASK (0x3f<<VOLL_SHIFT)
-+#define VOLR_MASK (0x3f)
-+#define VOLL_MUTE (0x2000)
-+#define MASK_DACVOL (0x1f1f)
-+#define LDACVOLSHIFT 8
-+#define RDACVOLSHIFT 0
-+#define BOOSTSHIFT 14
-+#define MASK_BOOST (0x1<<BOOSTSHIFT)
-+#define MASK_RECVOL (0x3f3f)
-+#define RECVOLLSHIFT 8
-+#define RECVOLRSHIFT 0
-+#define DACVOL_MASK 0x1F1F
-+
-+#define RECSL_MASK 0x0707
-+#define RECSL_BITS_MIC 0x0000
-+#define RECSL_BITS_LINEIN 0x0304
-+#define D2H_BIT (0x1<<15)
-+#define D2S_BIT (0x1<<14)
-+#define AC97_GPIO1 (0x1<<1)
-+#define AC97_GPIO5 (0x1<<5)
-+#define ALCM_MASK 0x0c00
-+#define ALCM_MUTE 0x0c00
-+#define ALCM_HP 0x0800
-+#define ALC_MASK 0xc080
-+#define ALC_ON 0x4080
-+#define MS_MASK 0x0060
-+#define MS_MIC2 0x0040
-+#define MUTE_INPUT (0x1<<15)
-+#define BIT_VRA (0x1<<0)
-+
-+#define DEFAULT_OUT_VOLUME (75)
-+#define DEFAULT_IN_VOLUME (75)
-+#define DEFAULT_RATE (8000)
-+#define JACK_POLLING_WAIT (5)
-+
-+static DECLARE_WAIT_QUEUE_HEAD(hp_queue);
-+static DECLARE_WAIT_QUEUE_HEAD(hp_proc);
-+static int volume_table_initialized = FALSE;
-+static unsigned short SpVolToReal[101];
-+static unsigned short HpVolToReal[101];
-+static unsigned short MicVolToReal[101];
-+static unsigned short DacVolToReal[101];
-+static unsigned short VolCnvTbl[38][2] __initdata = {
-+ {8,31}, {8,31}, {8,30}, {8,29}, {8,28}, // 0 - 4
-+ {8,27}, {8,26}, {8,25}, {8,24}, {8,23}, // 5 - 9
-+ {8,22}, {8,21}, {8,20}, {8,19}, {8,18}, // 10 - 14
-+ {8,17}, {8,16}, {8,15}, {8,14}, {8,13}, // 15 - 19
-+ {8,12}, {8,11}, {8,10}, {8, 9}, {8, 8}, // 20 - 24
-+ {8, 7}, {8, 6}, {8, 5}, {8, 4}, {8, 3}, // 25 - 29
-+ {8, 2}, {8, 1}, {8, 0}, {7, 0}, {6, 0}, // 30 - 34
-+ {5, 0}, {4, 0}, {3, 0}, }; // 35 - 37
-+
-+static unsigned short VolInitTbl[101] __initdata = {
-+ 0, 1, 5, 9, 11, 13, 14, 15, 16, 17,
-+ 18, 19, 19, 20, 21, 21, 22, 22, 23, 23,
-+ 23, 24, 24, 25, 25, 25, 25, 26, 26, 26,
-+ 27, 27, 27, 27, 28, 28, 28, 28, 28, 29,
-+ 29, 29, 29, 29, 30, 30, 30, 30, 30, 30,
-+ 31, 31, 31, 31, 31, 31, 31, 32, 32, 32,
-+ 32, 32, 32, 32, 33, 33, 33, 33, 33, 33,
-+ 33, 33, 33, 34, 34, 34, 34, 34, 34, 34,
-+ 34, 34, 34, 35, 35, 35, 35, 35, 35, 35,
-+ 35, 35, 35, 35, 36 ,36, 36, 36, 36, 36,
-+ 37 };
-+
-+#ifdef CONFIG_PM
-+#define ADEV_MAIN 0
-+#define ADEV_HP 1
-+#define ADEV_VOL 2
-+#define ADEV_OFFON 3
-+#define ADEV_INIT 4
-+static int lockState = 0;
-+static void audioLockFCS( int dev, int bLock )
-+{
-+ int curLockState = lockState;
-+ int now,last;
-+ if (bLock) {
-+ curLockState |= 0x1<<dev;
-+ } else {
-+ curLockState &= ~(0x1<<dev);
-+ }
-+ if (curLockState!=lockState) {
-+ now = (curLockState!=0)?TRUE:FALSE;
-+ last = (lockState!=0)?TRUE:FALSE;
-+ if ( now != last ) {
-+ lock_FCS(LOCK_FCS_SOUND, (curLockState!=0)?TRUE:FALSE);
-+ }
-+ lockState = curLockState;
-+ }
-+}
-+#endif // end CONFIG_PM
-+
-+/************************************************************
-+ * Config & Setup
-+ ************************************************************/
-+int wm9712_busy(void)
-+{
-+ return wm9712_stat.used;
-+}
-+
-+void wm9712_checkjack_sleep(void)
-+{
-+ interruptible_sleep_on(&hp_proc);
-+}
-+
-+void wm9712_checkjack_wakeup(void)
-+{
-+ wake_up(&hp_proc);
-+}
-+
-+static int check_hp_jack(void)
-+{
-+ unsigned short gpio_status;
-+ int count = 0, err = 0;
-+ int state;
-+
-+ gpio_status = ac97_read(AC97_GPIO_STATUS);
-+ state = !(gpio_status & AC97_GPIO1); //Active L
-+
-+ while( !(count>10 || err>50) ) {
-+ if (wm9712_stat.suspend) mdelay(JACK_POLLING_WAIT);
-+ else interruptible_sleep_on_timeout((wait_queue_head_t*)&hp_queue, JACK_POLLING_WAIT ); // wait
-+
-+ gpio_status = ac97_read(AC97_GPIO_STATUS);
-+ if (state == !(gpio_status & AC97_GPIO1)) {
-+ count++;
-+ } else {
-+ err++;
-+ state = !(gpio_status & AC97_GPIO1);
-+ count=0;
-+ }
-+ }
-+
-+ if ( count > 10 ) {
-+ wm9712_stat.jack = (state)?TRUE:FALSE;
-+ } else { // error
-+ wm9712_stat.jack = FALSE;
-+ }
-+ return wm9712_stat.jack;
-+}
-+
-+static int check_hp_mic(void)
-+{
-+ unsigned short gpio_status;
-+ int count = 0, err = 0;
-+ volatile int state;
-+ int LchMute;
-+
-+ if (!wm9712_stat.jack) {
-+ wm9712_stat.mic = FALSE;
-+ return FALSE;
-+ }
-+#ifdef DISABLE_JACKCHECK_PLAYING
-+ if (wm9712_stat.open_play) { // cannot check mic while playing
-+ wm9712_stat.need_after_check=TRUE;
-+ return wm9712_stat.mic;
-+ }
-+ wm9712_stat.need_after_check=FALSE;
-+#endif
-+
-+ wm9712_power_mode_tmp(WM9712_PWR_ENMICBIAS); // MICBIAS on
-+ LchMute = !(TC6393_SYS_REG(TC6393_SYS_GPODSR1) & TC6393_L_MUTE);
-+ if (!LchMute) TC6393_SYS_REG(TC6393_SYS_GPODSR1) &= ~TC6393_L_MUTE; // set L_Mute
-+
-+ gpio_status = ac97_read(AC97_GPIO_STATUS);
-+ state = (gpio_status & AC97_GPIO5); //Active H
-+
-+ while( !(count>10 || err>50) ) {
-+ if (wm9712_stat.suspend) mdelay(JACK_POLLING_WAIT);
-+ else interruptible_sleep_on_timeout((wait_queue_head_t*)&hp_queue, JACK_POLLING_WAIT ); // wait
-+
-+ gpio_status = ac97_read(AC97_GPIO_STATUS);
-+ if (state == (gpio_status & AC97_GPIO5)) {
-+ count++;
-+ } else {
-+ err++;
-+ state = (gpio_status & AC97_GPIO5);
-+ count=0;
-+ }
-+ }
-+
-+ wm9712_power_mode_tmp(WM9712_PWR_OFF); // restore MICBIAS
-+ if (!LchMute) TC6393_SYS_REG(TC6393_SYS_GPODSR1) |= TC6393_L_MUTE; // restore L_Mute
-+
-+ if ( count > 10 ) {
-+ wm9712_stat.mic = (state)?TRUE:FALSE;
-+ } else { // error
-+ wm9712_stat.mic = FALSE;
-+ }
-+ return wm9712_stat.mic;
-+}
-+
-+static void set_mute_registers( int dev, int mute )
-+{
-+ unsigned short val,val2;
-+#ifdef USE_HARDWARE_LMIX
-+ unsigned short val3;
-+#endif
-+
-+ switch(dev) {
-+ case DEV_MIC:
-+ if (mute) {
-+ ac97_bit_set(AC97_RECORD_GAIN, MUTE_INPUT);
-+ } else {
-+ ac97_bit_clear(AC97_RECORD_GAIN, MUTE_INPUT);
-+ }
-+ break;
-+ case DEV_OUTALL:
-+ set_mute_registers(DEV_SP,mute);
-+ set_mute_registers(DEV_HP,mute);
-+ break;
-+ case DEV_SP: // speaker
-+ val = ac97_read(AC97_MASTER_VOL_STEREO);
-+ val2 = ac97_read(AC97_DAC_VOL);
-+ if (mute || wm9712_stat.vol0) {
-+ val |= AC97_MUTE;
-+ val2 |= D2S_BIT;
-+ } else {
-+ val &= ~AC97_MUTE;
-+ val2 &= ~D2S_BIT;
-+ }
-+ ac97_write(AC97_MASTER_VOL_STEREO,val);
-+ ac97_write(AC97_DAC_VOL,val2);
-+ break;
-+ case DEV_HP: // headphone
-+ val = ac97_read(AC97_HEADPHONE_VOL);
-+ val2 = ac97_read(AC97_DAC_VOL);
-+ if (mute || wm9712_stat.vol0) {
-+ val |= AC97_MUTE;
-+ val2 |= D2H_BIT;
-+ } else {
-+ val &= ~AC97_MUTE;
-+ val2 &= ~D2H_BIT;
-+ }
-+ ac97_write(AC97_HEADPHONE_VOL,val);
-+ ac97_write(AC97_DAC_VOL,val2);
-+ break;
-+ case DEV_HPL: // headphone Lch only
-+ val = ac97_read(AC97_HEADPHONE_VOL);
-+#ifdef USE_HARDWARE_LMIX
-+ val2 = ac97_read(AC97_SIDETONE);
-+ val3 = ac97_read(AC97_DAC_VOL);
-+#endif
-+ if (mute) {
-+ wm9712_mono_out=1;
-+ val |= VOLL_MUTE; // mute bit
-+#ifdef USE_HARDWARE_LMIX
-+ val2 &= ~ALCM_MASK; // SP Mix to Rch
-+ val2 |= ALCM_HP;
-+ val3 |= D2H_BIT;
-+ val3 &= ~D2S_BIT;
-+ if (!wm9712_stat.open_rec) set_mute_registers(DEV_MIC,FALSE);
-+#endif
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) &= ~TC6393_L_MUTE; // Mute Lch
-+ } else {
-+ wm9712_mono_out=0;
-+ val &= ~VOLL_MASK;
-+ val |= (val&VOLR_MASK)<<VOLL_SHIFT;
-+#ifdef USE_HARDWARE_LMIX
-+ val2 &= ~ALCM_MASK; // mute SP Mix
-+ val2 |= ALCM_MUTE;
-+ val3 &= ~D2H_BIT;
-+ val3 &= ~D2S_BIT;
-+ if (!wm9712_stat.open_rec) set_mute_registers(DEV_MIC,TRUE);
-+#endif
-+ TC6393_SYS_REG(TC6393_SYS_GPODSR1) |= TC6393_L_MUTE; // Mute Lch off
-+ }
-+ ac97_write(AC97_HEADPHONE_VOL,val);
-+#ifdef USE_HARDWARE_LMIX
-+ ac97_write(AC97_SIDETONE,val2)
-+ ac97_write(AC97_DAC_VOL,val3);
-+#endif
-+ break;
-+ }
-+}
-+
-+static void set_audio_registers( int jackmode )
-+{
-+ char play = wm9712_stat.open_play;
-+ char rec = wm9712_stat.open_rec;
-+ unsigned short val;
-+
-+ switch( jackmode ) {
-+ case MAKEJACKSTATE(0,0): // Speaker (no HP)
-+ case MAKEJACKSTATE(0,1):
-+ // record from OnBoard Mic
-+ val = ac97_read(AC97_RECORD_SELECT);
-+ val &= ~RECSL_MASK;
-+ val |= RECSL_BITS_MIC;
-+ ac97_write(AC97_RECORD_SELECT,val);
-+ // power down
-+ wm9712_power_mode_audio((play)?WM9712_PWR_PLAY:WM9712_PWR_OFF);
-+ wm9712_power_mode_audioin((rec)?WM9712_PWR_REC:WM9712_PWR_OFF);
-+ // mute
-+ set_mute_registers(DEV_HP,TRUE);
-+ set_mute_registers(DEV_HPL,FALSE);
-+ set_mute_registers(DEV_SP,FALSE);
-+ break;
-+ case MAKEJACKSTATE(1,0): // Stereo HP
-+ // record from OnBoard Mic
-+ val = ac97_read(AC97_RECORD_SELECT);
-+ val &= ~RECSL_MASK;
-+ val |= RECSL_BITS_MIC;
-+ ac97_write(AC97_RECORD_SELECT,val);
-+ // power down
-+ wm9712_power_mode_audio((play)?WM9712_PWR_PLAY_HP:WM9712_PWR_OFF);
-+ wm9712_power_mode_audioin((rec)?WM9712_PWR_REC_HP:WM9712_PWR_OFF);
-+ // mute
-+ set_mute_registers(DEV_SP,TRUE);
-+ set_mute_registers(DEV_HPL,FALSE);
-+ set_mute_registers(DEV_HP,FALSE);
-+ break;
-+ case MAKEJACKSTATE(1,1): // Mic HP
-+ // record from HP Mic
-+ val = ac97_read(AC97_RECORD_SELECT);
-+ val &= ~RECSL_MASK;
-+ val |= RECSL_BITS_LINEIN;
-+ ac97_write(AC97_RECORD_SELECT,val);
-+ // power down
-+ wm9712_power_mode_audio((play)?WM9712_PWR_PLAY_MIC:WM9712_PWR_OFF);
-+ wm9712_power_mode_audioin((rec)?WM9712_PWR_REC_MIC:WM9712_PWR_OFF);
-+ // mute
-+ set_mute_registers(DEV_SP,TRUE);
-+ set_mute_registers(DEV_HPL,TRUE);
-+ set_mute_registers(DEV_HP,FALSE);
-+ break;
-+ }
-+}
-+
-+void wm9712_update_jack_state()
-+{
-+ int cur_jack_state;
-+
-+#ifdef CONFIG_PM
-+ audioLockFCS( ADEV_HP, 1 );
-+#endif
-+ check_hp_jack();
-+ check_hp_mic();
-+ cur_jack_state = MAKEJACKSTATE(wm9712_stat.jack,wm9712_stat.mic);
-+ if (wm9712_stat.last_jack_state == cur_jack_state) {
-+#ifdef CONFIG_PM
-+ audioLockFCS( ADEV_HP, 0 );
-+#endif
-+ return;
-+ }
-+
-+ DEBUG(DBG_L0, "HP jack state changed (Jack=%d,Mic=%d)\r\n",wm9712_stat.jack,wm9712_stat.mic);
-+
-+ set_audio_registers(cur_jack_state);
-+ wm9712_stat.last_jack_state = cur_jack_state;
-+#ifdef CONFIG_PM
-+ audioLockFCS( ADEV_HP, 0 );
-+#endif
-+}
-+
-+static void wm9712_ear_in_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-+{
-+ wm9712_checkjack_wakeup();
-+}
-+
-+
-+void wm9712_exit(void)
-+{
-+ set_mute_registers(DEV_OUTALL,TRUE);
-+
-+ free_irq(IRQ_GPIO_EAR_IN, NULL);
-+
-+ wm9712_power_mode_audio(WM9712_PWR_OFF);
-+ wm9712_power_mode_audioin(WM9712_PWR_OFF);
-+ wm9712_power_mode_tmp(WM9712_PWR_OFF);
-+
-+ pxa_ac97_put(&ac97_on);
-+}
-+
-+
-+int wm9712_init(void)
-+{
-+ unsigned short val;
-+
-+ printk("w9712_init\n");
-+
-+#ifdef CONFIG_PM
-+ audioLockFCS( ADEV_INIT, 1 );
-+#endif
-+ if (!volume_table_initialized) {
-+ int i;
-+ // initialize status
-+ memset(&wm9712_stat,0,sizeof(wm9712_stat));
-+ wm9712_stat.out_left = DEFAULT_OUT_VOLUME;
-+ wm9712_stat.out_right = DEFAULT_OUT_VOLUME;
-+ wm9712_stat.in_left = DEFAULT_IN_VOLUME;
-+ wm9712_stat.in_right = DEFAULT_IN_VOLUME;
-+ wm9712_stat.rate = DEFAULT_RATE;
-+
-+ // set volume table
-+ // volume '90' is 0dB, max volume is 7.5dB
-+ for (i=0; i<=100; i++) {
-+ SpVolToReal[i] = VolCnvTbl[VolInitTbl[i]][1];
-+ HpVolToReal[i] = VolCnvTbl[VolInitTbl[i]][1];
-+ DacVolToReal[i] = VolCnvTbl[VolInitTbl[i]][0];
-+ MicVolToReal[i] = 0xf * i / 100;
-+ }
-+ volume_table_initialized=TRUE;
-+ }
-+ wm9712_stat.last_jack_state = INVALID_JACKSTATE;
-+ pxa_ac97_get(&codec, &ac97_on);
-+ wm9712_power_mode_audio(WM9712_PWR_OFF);
-+ wm9712_power_mode_audioin(WM9712_PWR_OFF);
-+ wm9712_power_mode_tmp(WM9712_PWR_OFF);
-+
-+
-+ // set default values in wm9712 registers
-+ // 0x02 MASTER_VOLUME ... ZC=1, INV=1
-+ val = ac97_read(AC97_MASTER_VOL_STEREO);
-+ val |= BIT_ZC|BIT_INV;
-+ ac97_write(AC97_MASTER_VOL_STEREO,val);
-+
-+ // 0x04 HEADPHONE_VOLUME ... ZC=1
-+ val = ac97_read(AC97_HEADPHONE_VOL);
-+ val |= BIT_ZC;
-+ ac97_write(AC97_HEADPHONE_VOL,val);
-+
-+ // 0x0E MIC VOLUME ... set MS
-+ val = ac97_read(AC97_MIC_VOL);
-+ val &= ~MS_MASK;
-+ val |= MS_MIC2;
-+ ac97_write(AC97_MIC_VOL,val);
-+
-+ // 0x1A RECORD_SELECT ... set BOOST
-+ val = ac97_read(AC97_RECORD_SELECT);
-+ val |= MASK_BOOST;
-+ ac97_write(AC97_RECORD_SELECT,val);
-+
-+ // 0x1C RECORD_GAIN ... set ZC=1
-+ val = ac97_read(AC97_RECORD_GAIN);
-+ val |= BIT_ZC;
-+ ac97_write(AC97_RECORD_GAIN,val);
-+
-+ // 0x2A AC97_EXTENDED_STATUS set VRA=1
-+ val = ac97_read(AC97_EXTENDED_STATUS);
-+ val |= BIT_VRA;
-+ ac97_write(AC97_EXTENDED_STATUS,val);
-+
-+ // set default volume
-+ wm9712_set_output_volume(wm9712_stat.out_left, wm9712_stat.out_right);
-+ wm9712_set_input_gain(wm9712_stat.in_left, wm9712_stat.in_right);
-+
-+ // set default rate
-+ ac97_set_dac_rate(codec, (unsigned int)wm9712_stat.rate);
-+ ac97_set_adc_rate(codec, (unsigned int)wm9712_stat.rate);
-+
-+ wm9712_update_jack_state();
-+ init_timer(&hp_wakeup_timer);
-+ hp_wakeup_timer.function = wm9712_checkjack_wakeup;
-+
-+#ifdef CONFIG_PM
-+ audioLockFCS( ADEV_INIT, 0 );
-+#endif
-+
-+ set_GPIO_IRQ_edge(GPIO_HP_IN, GPIO_BOTH_EDGES);
-+ if( request_irq(IRQ_GPIO_EAR_IN, wm9712_ear_in_interrupt, SA_INTERRUPT, "ear_in", NULL) ) {
-+ DEBUG(DBG_L0, "IRQ error %d\n", IRQ_GPIO_EAR_IN);
-+ return -EBUSY;
-+ }
-+
-+ return 0;
-+}
-+
-+/************************************************************
-+ * Open & Close
-+ ************************************************************/
-+int wm9712_open(SOUND_SETTINGS *settings)
-+{
-+ DEBUG(DBG_L2, "wm9712 open\n");
-+
-+ if ( wm9712_stat.used ) {
-+ DEBUG(DBG_L0, "wm9712 device is busy now !\n");
-+ return -EBUSY;
-+ }
-+
-+ wm9712_stat.used = TRUE;
-+
-+#ifdef CONFIG_PM
-+ audioLockFCS( ADEV_MAIN, 1 );
-+#endif /* CONFIG_PM */
-+
-+ if ( wm9712_setup(settings) < 0 ) {
-+ wm9712_close();
-+ wm9712_stat.used = FALSE;
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+int wm9712_close(void)
-+{
-+ DEBUG(DBG_L2 ,"wm9712 close\n");
-+
-+ // set_mute_registers(DEV_OUTALL,TRUE);
-+ set_mute_registers(DEV_MIC,TRUE);
-+
-+ wm9712_stat.used = FALSE;
-+ wm9712_stat.open_play = FALSE;
-+ wm9712_stat.open_rec = FALSE;
-+
-+ wm9712_power_mode_audio(WM9712_PWR_OFF);
-+ wm9712_power_mode_audioin(WM9712_PWR_OFF);
-+ wm9712_power_mode_tmp(WM9712_PWR_OFF);
-+
-+#ifdef CONFIG_PM
-+ audioLockFCS( ADEV_MAIN, 0 );
-+#endif /* CONFIG_PM */
-+
-+#ifdef DISABLE_JACKCHECK_PLAYING
-+ if (wm9712_stat.need_after_check) {
-+ wm9712_checkjack_wakeup();
-+ }
-+#endif
-+
-+ return 0;
-+}
-+
-+/************************************************************
-+ * Setup
-+ ************************************************************/
-+static int wm9712_setup(SOUND_SETTINGS *setting)
-+{
-+ int ret = 0;
-+
-+ if( setting == NULL ) return -1;
-+
-+ if ( !wm9712_stat.used ) {
-+ DEBUG(DBG_L0, "not opened !\n");
-+ return -EINVAL;
-+ }
-+
-+ wm9712_stat.mode = setting->mode & SOUND_MODE_MASK;
-+ if (wm9712_stat.mode & SOUND_PLAY_MODE) {
-+ DEBUG(DBG_L2, "Sound Play Setting\n");
-+ // wm9712_set_output_volume(setting->output.left, setting->output.right);
-+ wm9712_stat.open_play=TRUE;
-+ }
-+ if (wm9712_stat.mode & SOUND_REC_MODE) {
-+ DEBUG(DBG_L2, "Sound Rec Mode\n");
-+ set_mute_registers(DEV_MIC,FALSE);
-+ // wm9712_set_input_gain(setting->input.left, setting->input.right);
-+ wm9712_stat.open_rec=TRUE;
-+ }
-+ if (!wm9712_stat.open_play && !wm9712_stat.open_rec) {
-+ DEBUG(DBG_L0, "Sound mode(%x) is not supported !\n", wm9712_stat.mode);
-+ return -EINVAL;
-+ }
-+
-+ set_audio_registers(wm9712_stat.last_jack_state);
-+
-+ if ( (ret = wm9712_set_freq(setting)) < 0 ) return ret;
-+
-+ return 0;
-+}
-+
-+// for Freq.
-+int wm9712_set_freq(SOUND_SETTINGS *setting)
-+{
-+ int ret = 0;
-+ unsigned int actual_val;
-+ wm9712_stat.rate = setting->frequency;
-+ DEBUG(DBG_L2, "rate = %d\n", wm9712_stat.rate);
-+
-+ if ( !wm9712_stat.used ) {
-+ DEBUG(DBG_L0, "not opened !\n");
-+ return -EINVAL;
-+ }
-+ if ( wm9712_stat.rate < 8000 ) wm9712_stat.rate = 8000;
-+ else if ( wm9712_stat.rate > 48000 ) wm9712_stat.rate = 48000;
-+
-+ if (wm9712_stat.open_play) {
-+ actual_val = ac97_set_dac_rate(codec, (unsigned int)wm9712_stat.rate);
-+ if ( actual_val != wm9712_stat.rate) {
-+ DEBUG(DBG_L1,"Set DAC rate error: %d->%d\n",wm9712_stat.rate,actual_val);
-+ }
-+ }
-+ if (wm9712_stat.open_rec) {
-+ actual_val = ac97_set_adc_rate(codec, (unsigned int)wm9712_stat.rate);
-+ if ( actual_val != wm9712_stat.rate) {
-+ DEBUG(DBG_L1,"Set ADC rate error: %d->%d\n",wm9712_stat.rate,actual_val);
-+ }
-+ }
-+
-+ DEBUG(DBG_L2, "Sampling rate: %d\n", wm9712_stat.rate);
-+
-+ return ret;
-+}
-+
-+
-+/************************************************************
-+ * Volume
-+ ************************************************************/
-+
-+int wm9712_set_output_volume(int left, int right)
-+{
-+ unsigned short real_left_vol,real_right_vol,val;
-+
-+#ifdef CONFIG_PM
-+ audioLockFCS( ADEV_VOL, 1 );
-+#endif
-+ // speaker volume
-+ real_left_vol = SpVolToReal[left];
-+ real_right_vol = SpVolToReal[right];
-+
-+ val = ac97_read(AC97_MASTER_VOL_STEREO);
-+ val &= ~(VOLL_MASK|VOLR_MASK);
-+ val |= (real_left_vol << VOLL_SHIFT) | real_right_vol;
-+ ac97_write(AC97_MASTER_VOL_STEREO,val);
-+
-+ // head phone volume
-+ real_left_vol = HpVolToReal[left];
-+ real_right_vol = HpVolToReal[right];
-+
-+ val = ac97_read(AC97_HEADPHONE_VOL);
-+ val &= ~(VOLL_MASK|VOLR_MASK);
-+ if (wm9712_stat.mic) { // minimize Lch volume
-+ val |= VOLL_MASK | real_right_vol;
-+ } else {
-+ val |= (real_left_vol << VOLL_SHIFT) | real_right_vol;
-+ }
-+ ac97_write(AC97_HEADPHONE_VOL,val);
-+
-+ // pcm volume
-+ real_left_vol = DacVolToReal[left];
-+ real_right_vol = DacVolToReal[right];
-+
-+ val = ac97_read(AC97_DAC_VOL);
-+ val &= ~DACVOL_MASK;
-+ val |= (real_left_vol << VOLL_SHIFT) | real_right_vol;
-+ ac97_write(AC97_DAC_VOL,val);
-+
-+ wm9712_stat.out_left = left;
-+ wm9712_stat.out_right = right;
-+
-+ // volume 0 means mute
-+ if ( (left==0 && right==0) && wm9712_stat.vol0!=TRUE) {
-+ wm9712_stat.vol0 = TRUE;
-+ set_mute_registers(DEV_OUTALL,TRUE);
-+ }
-+ if ( (left>0 || right>0) && wm9712_stat.vol0==TRUE) {
-+ wm9712_stat.vol0 = FALSE;
-+ set_audio_registers(wm9712_stat.last_jack_state);
-+ }
-+
-+#ifdef CONFIG_PM
-+ audioLockFCS( ADEV_VOL, 0 );
-+#endif
-+ return 0;
-+}
-+
-+int wm9712_set_input_gain(int left, int right)
-+{
-+ unsigned short real_left_vol,real_right_vol,val;
-+
-+#ifdef CONFIG_PM
-+ audioLockFCS( ADEV_VOL, 1 );
-+#endif
-+
-+ real_left_vol = MicVolToReal[left];
-+ real_right_vol = MicVolToReal[left]; // Rch use left volume
-+
-+ val = ac97_read(AC97_RECORD_GAIN);
-+ val &= ~(VOLL_MASK|VOLR_MASK);
-+ val |= (real_left_vol << VOLL_SHIFT) | real_right_vol;
-+ ac97_write(AC97_RECORD_GAIN,val);
-+
-+ wm9712_stat.in_left = left;
-+ wm9712_stat.in_right = right;
-+
-+#ifdef CONFIG_PM
-+ audioLockFCS( ADEV_VOL, 0 );
-+#endif
-+
-+ return 0;
-+}
-+
-+/*
-+ * AGC
-+ */
-+static void wm9712_update_agc(int agc)
-+{
-+ unsigned short val;
-+#ifdef CONFIG_PM
-+ audioLockFCS( ADEV_VOL, 1 );
-+#endif
-+ if ( wm9712_stat.mode | SOUND_REC_MODE ) {
-+ val = ac97_read(AC97_NOISE_CTL);
-+ val &= ~ALC_MASK;
-+ if (agc) val |= ALC_ON;
-+ ac97_write(AC97_NOISE_CTL,val);
-+ }
-+#ifdef CONFIG_PM
-+ audioLockFCS( ADEV_VOL, 0 );
-+#endif
-+
-+}
-+
-+int wm9712_set_agc(int agc)
-+{
-+ if ( agc < 0 ) return wm9712_stat.agc;
-+ agc = !!agc; /* should be 0 or 1 now */
-+ if ( wm9712_stat.agc != agc ) {
-+ wm9712_stat.agc = agc;
-+ wm9712_update_agc(wm9712_stat.agc);
-+ }
-+ return agc;
-+}
-+
-+/*** Suspend/Resume ***********************************************************/
-+#ifdef CONFIG_PM
-+void wm9712_suspend(void)
-+{
-+ DEBUG(DBG_L2, "in\n");
-+#ifdef CONFIG_PM
-+ audioLockFCS( ADEV_OFFON, 1 );
-+#endif
-+ wm9712_stat.suspend = 1;
-+ wm9712_exit();
-+#ifdef CONFIG_PM
-+ audioLockFCS( ADEV_OFFON, 0 );
-+#endif
-+ DEBUG(DBG_L2, "out\n");
-+}
-+
-+void wm9712_resume(void)
-+{
-+ DEBUG(DBG_L2, "in\n");
-+#ifdef CONFIG_PM
-+ audioLockFCS( ADEV_OFFON, 1 );
-+#endif
-+ wm9712_init();
-+ if (wm9712_stat.open_play) {
-+ ac97_set_dac_rate(codec, (unsigned int)wm9712_stat.rate);
-+ }
-+ if (wm9712_stat.open_rec) {
-+ set_mute_registers(DEV_MIC,FALSE);
-+ ac97_set_adc_rate(codec, (unsigned int)wm9712_stat.rate);
-+ }
-+ wm9712_stat.suspend = 0;
-+ //X wm9712_checkjack_wakeup();
-+ hp_wakeup_timer.expires = jiffies + HP_WAKEUP_DELAY;
-+ add_timer(&hp_wakeup_timer);
-+#ifdef CONFIG_PM
-+ audioLockFCS( ADEV_OFFON, 0 );
-+#endif
-+ DEBUG(DBG_L2, "out\n");
-+}
-+#endif /* CONFIG_PM */
-diff -Nur linux_c860_org/drivers/usb/Config.in linux/drivers/usb/Config.in
---- linux_c860_org/drivers/usb/Config.in 2002-08-29 12:26:42.000000000 +0900
-+++ linux/drivers/usb/Config.in 2004-06-10 21:09:10.000000000 +0900
-@@ -36,6 +36,12 @@
- fi
- dep_tristate ' OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI $CONFIG_USB
- dep_tristate ' SA1111 OHCI-compatible host interface support' CONFIG_USB_OHCI_SA1111 $CONFIG_USB
-+dep_tristate ' TC6393 OHCI-compatible host interface support' CONFIG_USB_OHCI_TC6393 $CONFIG_USB
-+if [ "$CONFIG_USB_OHCI_TC6393" != "n" ]; then
-+ define_bool CONFIG_USB_USE_INTERNAL_MEMORY y
-+else
-+ define_bool CONFIG_USB_USE_INTERNAL_MEMORY n
-+fi
-
- comment 'USB Device Class drivers'
- dep_tristate ' USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND
-diff -Nur linux_c860_org/drivers/usb/Makefile linux/drivers/usb/Makefile
---- linux_c860_org/drivers/usb/Makefile 2002-08-29 12:26:42.000000000 +0900
-+++ linux/drivers/usb/Makefile 2004-06-10 21:09:10.000000000 +0900
-@@ -16,10 +16,11 @@
-
- # Multipart objects.
-
--list-multi := usbcore.o hid.o pwc.o
-+list-multi := usbcore.o hid.o pwc.o usb_ohci_tc6393.o
- usbcore-objs := usb.o usb-debug.o hub.o
- hid-objs := hid-core.o hid-input.o
- pwc-objs := pwc-if.o pwc-misc.o pwc-ctrl.o pwc-uncompress.o
-+ohci-tc6393-objs := usb-ohci.o usb-ohci-tc6393.o pcipool.o mem-onchip.o
-
-
- # Optional parts of multipart objects.
-@@ -48,6 +49,7 @@
- obj-$(CONFIG_USB_UHCI_ALT) += uhci.o
- obj-$(CONFIG_USB_OHCI) += usb-ohci.o usb-ohci-pci.o
- obj-$(CONFIG_USB_OHCI_SA1111) += usb-ohci.o usb-ohci-sa1111.o
-+obj-$(CONFIG_USB_OHCI_TC6393) += usbcore.o usb_ohci_tc6393.o
-
- obj-$(CONFIG_USB_MOUSE) += usbmouse.o
- obj-$(CONFIG_USB_HID) += hid.o
-@@ -105,3 +107,6 @@
-
- pwc.o: $(pwc-objs)
- $(LD) -r -o $@ $(pwc-objs)
-+
-+usb_ohci_tc6393.o: $(ohci-tc6393-objs)
-+ $(LD) -r -o $@ $(ohci-tc6393-objs)
-diff -Nur linux_c860_org/drivers/usb/device/bi/pxa.c linux/drivers/usb/device/bi/pxa.c
---- linux_c860_org/drivers/usb/device/bi/pxa.c 2003-11-07 11:35:45.000000000 +0900
-+++ linux/drivers/usb/device/bi/pxa.c 2004-06-10 21:09:10.000000000 +0900
-@@ -24,6 +24,8 @@
- * Change Log
- * 28-Nov-2003 Lineo Solutions, Inc. Add module parameter. 'shortpacket'
- * and 'recvpacket'.
-+ * ChangeLog:
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa (support cable gpio)
- *
- */
-
-@@ -912,6 +914,10 @@
- PXA_REGS(UDCCS0," <-- ep0");
- }
-
-+#ifdef USBD_CABLE_GPIO
-+static int udc_connect_state = 0;
-+#endif
-+
- /* ********************************************************************************************* */
- /* Interrupt Handler
- */
-@@ -975,10 +981,24 @@
- // uncommon interrupts
- if ((udccr = UDCCR) & (UDCCR_RSTIR | UDCCR_RESIR | UDCCR_SUSIR)) {
-
-+#ifdef USBD_CABLE_GPIO
-+ if (!udc_connect_state && (udccr & UDCCR_RSTIR)) {
-+ // printk("ignore UDC Reset\n");
-+ UDCCR |= UDCCR_RSTIR;
-+ udccr &= ~UDCCR_RSTIR;
-+ }
-+ if (!udc_connect_state && (udccr & UDCCR_RESIR)) {
-+ // printk("ignore UDC Resume\n");
-+ UDCCR |= UDCCR_RESIR;
-+ udccr &= ~UDCCR_RESIR;
-+ }
-+#endif
-+
- // UDC Reset
-- if (udccr & UDCCR_RSTIR) {
-+ if (udccr & UDCCR_RSTIR) {
- #if defined(CONFIG_ARCH_SHARP_SL) && defined(CONFIG_APM_CPU_IDLE)
- static int is1stReset = 1;
-+ // printk("UDC Reset\n");
- if (is1stReset) {
- is1stReset = 0;
- } else {
-@@ -995,7 +1015,8 @@
- }
-
- // UDC Resume
-- if (udccr & UDCCR_RESIR) {
-+ if (udccr & UDCCR_RESIR) {
-+ // printk("UDC Resume\n");
- PXA_CCR(udccr, "------------------------> Resume");
- if (udc_suspended) {
- #if defined(CONFIG_ARCH_SHARP_SL) && defined(CONFIG_APM_CPU_IDLE)
-@@ -1009,6 +1030,7 @@
-
- // UDC Suspend
- if (udccr & UDCCR_SUSIR) {
-+ // printk("UDC Suspend\n");
- PXA_CCR(udccr, "------------------------> Suspend");
- if (!udc_suspended) {
- #if defined(CONFIG_ARCH_SHARP_SL) && defined(CONFIG_APM_CPU_IDLE)
-@@ -1284,7 +1306,17 @@
- */
- int udc_connected ()
- {
-- return 1;
-+ int rc = 1;
-+#ifdef USBD_CABLE_GPIO
-+#ifdef USBD_CABLE_ACTIVE_HIGH
-+ rc = (GPLR(USBD_CABLE_GPIO) & GPIO_bit(USBD_CABLE_GPIO)) != 0;
-+ //dbg_udc (1, "udc_connected: ACTIVE_HIGH: %d", rc);
-+#else
-+ rc = (GPLR(USBD_CABLE_GPIO) & GPIO_bit(USBD_CABLE_GPIO)) == 0;
-+ //dbg_udc (1, "udc_connected: ACTIVE_LOW: %d", rc);
-+#endif
-+#endif
-+ return rc;
- }
-
- /**
-@@ -1294,6 +1326,9 @@
- */
- void udc_connect (void)
- {
-+#ifdef USBD_CABLE_GPIO
-+ udc_connect_state = 1;
-+#endif
- #ifdef CONFIG_SABINAL_DISCOVERY
- /* Set GPIO pin function to I/O */
- GAFR1_U &= ~(0x3 << ((USBD_CONNECT_GPIO & 0xF) << 1));
-@@ -1318,6 +1353,20 @@
- GPCR(USBD_CONNECT_GPIO) = GPIO_bit(USBD_CONNECT_GPIO);
- #endif
-
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+ if (!udc_connected()) {
-+ //printk("USB Cable not connected!!\n");
-+ return;
-+ }
-+ SCP_JC_REG_GPCR |= USBD_CONNECT_GPIO;
-+#if defined(USBD_CONNECT_HIGH)
-+ /* Set GPIO pin high to connect */
-+ set_scoop_jc_gpio(USBD_CONNECT_GPIO);
-+#else
-+ /* Set GPIO pin low to connect */
-+ reset_scoop_jc_gpio(USBD_CONNECT_GPIO);
-+#endif
-+
- #else
- #warning NO USB Device connect
- #endif
-@@ -1330,6 +1379,9 @@
- */
- void udc_disconnect (void)
- {
-+#ifdef USBD_CABLE_GPIO
-+ udc_connect_state = 0;
-+#endif
- #ifdef CONFIG_SABINAL_DISCOVERY
- /* Set GPIO pin function to I/O */
- GAFR1_U &= ~(0x3 << ((USBD_CONNECT_GPIO & 0xF) << 1));
-@@ -1354,18 +1406,35 @@
- GPSR(USBD_CONNECT_GPIO) = GPIO_bit(USBD_CONNECT_GPIO);
- #endif
-
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+ SCP_JC_REG_GPCR |= USBD_CONNECT_GPIO;
-+#if defined(USBD_CONNECT_HIGH)
-+ /* Set GPIO pin low to disconnect */
-+ reset_scoop_jc_gpio(USBD_CONNECT_GPIO);
-+#else
-+ /* Set GPIO pin high to disconnect */
-+ set_scoop_jc_gpio(USBD_CONNECT_GPIO);
-+#endif
-+
- #else
- #warning NO USB Device connect
- #endif
- }
-
--#if 0
-+#ifdef USBD_CABLE_GPIO
- /**
- * udc_int_hndlr_cable - interrupt handler for cable
- */
- static void udc_int_hndlr_cable (int irq, void *dev_id, struct pt_regs *regs)
- {
- // GPIOn interrupt
-+ //dbg_udc("udc_cradle_interrupt: ->%08x\n",GPLR(USBD_CABLE_GPIO));
-+ if (udc_connected()) {
-+ usbd_device_event(udc_device, DEVICE_HUB_RESET, 0);
-+ udc_cable_event ();
-+ } else {
-+ udc_disconnect();
-+ }
- }
- #endif
-
-@@ -1663,12 +1732,14 @@
- */
- int udc_request_cable_irq ()
- {
--#ifdef XXXX_CABLE_IRQ
-+#ifdef USBD_CABLE_GPIO
-+ set_GPIO_mode(USBD_CABLE_GPIO | GPIO_IN);
-+ set_GPIO_IRQ_edge(USBD_CABLE_GPIO, GPIO_BOTH_EDGES);
- // request IRQ and IO region
-- if (request_irq
-- (XXXX_CABLE_IRQ, int_hndlr, SA_INTERRUPT | SA_SAMPLE_RANDOM, UDC_NAME " Cable",
-- NULL) != 0) {
-- printk (KERN_INFO "usb_ctl: Couldn't request USB irq\n");
-+ if (request_irq (IRQ_GPIO(USBD_CABLE_GPIO), udc_int_hndlr_cable,
-+ SA_INTERRUPT | SA_SAMPLE_RANDOM, UDC_NAME " Cable", NULL) != 0)
-+ {
-+ printk (KERN_INFO "usb_ctl: Couldn't request USB cable irq\n");
- return -EINVAL;
- }
- #endif
-@@ -1921,8 +1992,8 @@
- */
- void udc_release_cable_irq ()
- {
--#ifdef XXXX_IRQ
-- free_irq (XXXX_CABLE_IRQ, NULL);
-+#ifdef USBD_CABLE_GPIO
-+ free_irq (IRQ_GPIO(USBD_CABLE_GPIO), NULL);
- #endif
- }
-
-diff -Nur linux_c860_org/drivers/usb/device/bi/pxa.h linux/drivers/usb/device/bi/pxa.h
---- linux_c860_org/drivers/usb/device/bi/pxa.h 2002-08-26 15:19:05.000000000 +0900
-+++ linux/drivers/usb/device/bi/pxa.h 2004-06-10 21:09:10.000000000 +0900
-@@ -21,6 +21,8 @@
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
-+ * ChangeLog:
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
-
-@@ -54,6 +56,15 @@
- #define USBD_CONNECT_HIGH 1
- #endif
-
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+/* SHARP SL-6000 specific GPIO assignments */
-+#define USBD_CONNECT_GPIO SCP_JC_USB_PULLUP
-+#define USBD_CONNECT_HIGH 1
-+#define USBD_CABLE_GPIO GPIO_USB_IN
-+// active low
-+//#define USBD_CABLE_ACTIVE_HIGH 1
-+#endif
-+
-
- /*
- * DMA Notes
-diff -Nur linux_c860_org/drivers/usb/device/usbd-arch.h linux/drivers/usb/device/usbd-arch.h
---- linux_c860_org/drivers/usb/device/usbd-arch.h 2003-10-16 13:59:01.000000000 +0900
-+++ linux/drivers/usb/device/usbd-arch.h 2004-06-10 21:09:10.000000000 +0900
-@@ -42,6 +42,9 @@
- * Typically during early development you will set these via the kernel
- * configuration and migrate the values into here once specific values
- * have been tested and will no longer change.
-+ *
-+ * Change Log
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
-
-@@ -442,13 +445,13 @@
- #define CONFIG_USBD_PRODUCT_NAME "SL-C750"
- #else
- #define CONFIG_USBD_PRODUCT_NAME "SL-7500"
--#endif
--#endif
--#endif
-+#endif // CONFIG_ARCH_SHARP_SL_J
-+#endif // CONFIG_ARCH_PXA_HUSKY
-+#endif // CONFIG_ARCH_PXA_SHEPHERD
-
- #ifdef CONFIG_ARCH_PXA_BOXER
-- #undef CONFIG_USBD_PRODUCT_NAME
-- #define CONFIG_USBD_PRODUCT_NAME "SL-C860"
-+ #undef CONFIG_USBD_PRODUCT_NAME
-+ #define CONFIG_USBD_PRODUCT_NAME "SL-C860"
- #endif
-
- #undef CONFIG_USBD_NET_CDC
-@@ -458,4 +461,38 @@
- #define CONFIG_USBD_NET_MDLM 1
- #define CONFIG_USBD_MAC_AS_SERIAL_NUMBER 1
-
--#endif
-+#endif // CONFIG_ARCH_PXA_CORGI
-+
-+
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+
-+ #warning CONFIGURING FOR TOSA
-+
-+ #undef CONFIG_USBD_VENDORID
-+ #define CONFIG_USBD_VENDORID 0x04dd
-+ #undef CONFIG_USBD_SERIAL_PRODUCT ID
-+ #define CONFIG_USBD_SERIAL_PRODUCT ID 0x9032
-+ #undef CONFIG_USBD_NET_PRODUCTID
-+ #define CONFIG_USBD_NET_PRODUCTID 0x9032
-+
-+ #undef CONFIG_USBD_SELFPOWERED
-+ #undef CONFIG_USBD_MANUFACTURER
-+ #undef CONFIG_USBD_PRODUCT_NAME
-+
-+ #define CONFIG_USBD_SELFPOWERED 1
-+ #define CONFIG_USBD_MANUFACTURER "Sharp"
-+#ifdef CONFIG_ARCH_SHARP_SL_J
-+ #define CONFIG_USBD_PRODUCT_NAME "SL-6000"
-+#else
-+ #define CONFIG_USBD_PRODUCT_NAME "SL-6000"
-+#endif // CONFIG_ARCH_SHARP_SL_J
-+
-+ #undef CONFIG_USBD_NET_CDC
-+ #undef CONFIG_USBD_NET_MDLM
-+ #undef CONFIG_USBD_NET_SAFE
-+
-+ #define CONFIG_USBD_NET_MDLM 1
-+ #define CONFIG_USBD_MAC_AS_SERIAL_NUMBER 1
-+
-+#endif // CONFIG_ARCH_PXA_TOSA
-+
-diff -Nur linux_c860_org/drivers/usb/device/usbd-monitor.c linux/drivers/usb/device/usbd-monitor.c
---- linux_c860_org/drivers/usb/device/usbd-monitor.c 2002-08-26 15:19:04.000000000 +0900
-+++ linux/drivers/usb/device/usbd-monitor.c 2004-06-10 21:09:10.000000000 +0900
-@@ -23,6 +23,8 @@
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
-+ * ChangeLog:
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
-
-@@ -62,7 +64,7 @@
- * Architecture specific includes
- */
-
--#if defined(CONFIG_ARCH_SA1100) || defined(CONFIG_SABINAL_DISCOVERY) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_SA1100) || defined(CONFIG_SABINAL_DISCOVERY) || defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
-
- #include <asm/irq.h>
- #include <asm/hardware.h>
-diff -Nur linux_c860_org/drivers/usb/inode.c linux/drivers/usb/inode.c
---- linux_c860_org/drivers/usb/inode.c 2002-08-26 14:39:15.000000000 +0900
-+++ linux/drivers/usb/inode.c 2004-06-10 21:09:10.000000000 +0900
-@@ -24,6 +24,9 @@
- *
- * History:
- * 0.1 04.01.2000 Created
-+ *
-+ * Change Log
-+ * 27-Dec-2003 SHARP fixed non-reentrant codes
- */
-
- /*****************************************************************************/
-@@ -628,6 +631,9 @@
- s->s_root = d_alloc_root(root_inode);
- if (!s->s_root)
- goto out_no_root;
-+#ifdef CONFIG_ARCH_SHARP_SL
-+ lock_kernel();
-+#endif
- list_add_tail(&s->u.usbdevfs_sb.slist, &superlist);
- for (i = 0; i < NRSPECIAL; i++) {
- if (!(inode = iget(s, IROOT+1+i)))
-@@ -646,6 +652,9 @@
- recurse_new_dev_inode(bus->root_hub, s);
- }
- up (&usb_bus_list_lock);
-+#ifdef CONFIG_ARCH_SHARP_SL
-+ unlock_kernel();
-+#endif
- return s;
-
- out_no_root:
-@@ -674,9 +683,15 @@
- struct list_head *slist;
-
- lock_kernel();
-+#ifdef CONFIG_ARCH_SHARP_SL
-+ down (&usb_bus_list_lock);
-+#endif
- for (slist = superlist.next; slist != &superlist; slist = slist->next)
- new_bus_inode(bus, list_entry(slist, struct super_block, u.usbdevfs_sb.slist));
- update_special_inodes();
-+#ifdef CONFIG_ARCH_SHARP_SL
-+ up (&usb_bus_list_lock);
-+#endif
- unlock_kernel();
- usbdevfs_conn_disc_event();
- }
-@@ -684,9 +699,15 @@
- void usbdevfs_remove_bus(struct usb_bus *bus)
- {
- lock_kernel();
-+#ifdef CONFIG_ARCH_SHARP_SL
-+ down (&usb_bus_list_lock);
-+#endif
- while (!list_empty(&bus->inodes))
- free_inode(list_entry(bus->inodes.next, struct inode, u.usbdev_i.dlist));
- update_special_inodes();
-+#ifdef CONFIG_ARCH_SHARP_SL
-+ up (&usb_bus_list_lock);
-+#endif
- unlock_kernel();
- usbdevfs_conn_disc_event();
- }
-@@ -696,9 +717,15 @@
- struct list_head *slist;
-
- lock_kernel();
-+#ifdef CONFIG_ARCH_SHARP_SL
-+ down (&usb_bus_list_lock);
-+#endif
- for (slist = superlist.next; slist != &superlist; slist = slist->next)
- new_dev_inode(dev, list_entry(slist, struct super_block, u.usbdevfs_sb.slist));
- update_special_inodes();
-+#ifdef CONFIG_ARCH_SHARP_SL
-+ up (&usb_bus_list_lock);
-+#endif
- unlock_kernel();
- usbdevfs_conn_disc_event();
- }
-@@ -709,6 +736,9 @@
- struct siginfo sinfo;
-
- lock_kernel();
-+#ifdef CONFIG_ARCH_SHARP_SL
-+ down (&usb_bus_list_lock);
-+#endif
- while (!list_empty(&dev->inodes))
- free_inode(list_entry(dev->inodes.next, struct inode, u.usbdev_i.dlist));
- while (!list_empty(&dev->filelist)) {
-@@ -728,6 +758,9 @@
- }
-
- update_special_inodes();
-+#ifdef CONFIG_ARCH_SHARP_SL
-+ up (&usb_bus_list_lock);
-+#endif
- unlock_kernel();
- usbdevfs_conn_disc_event();
- }
-diff -Nur linux_c860_org/drivers/usb/mem-onchip.c linux/drivers/usb/mem-onchip.c
---- linux_c860_org/drivers/usb/mem-onchip.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/usb/mem-onchip.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,364 @@
-+/*
-+ * linux/drivers/usb/mem-onchip.c
-+ *
-+ * memory allocate functions for RAM on chip
-+ *
-+ * Copyright (c) 2003 Lineo Solutions, Inc.
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file "COPYING" in the main directory of this archive
-+ * for more details.
-+ *
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/ioport.h>
-+#include <linux/interrupt.h>
-+#include <linux/slab.h>
-+#include <linux/usb.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/io.h>
-+
-+#include "mem-onchip.h"
-+
-+#if 0
-+#define dbg(format, arg...) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg)
-+#else
-+#define dbg(format, arg...) do {} while (0)
-+#endif
-+
-+
-+
-+//#define MALLOCK_BOUNDART_32BYTE
-+#define MALLOCK_BOUNDART_16BYTE
-+
-+#define MAKE_POINTER(p, offset) ((oc_mem_head *)((u32)(p) + offset))
-+
-+#define INIT_OC_MEM_HEAD(p, s) \
-+ {\
-+ INIT_LIST_HEAD(&(p)->free_list);\
-+ (p)->size = s;\
-+ (p)->flag = 0;\
-+ }
-+
-+#define IS_ALLOCATED_MEMORY(p) ((struct list_head *)(p) == (p)->free_list.next \
-+ && (p)->free_list.next == (p)->free_list.prev)
-+
-+/* memory block header */
-+typedef struct __oc_mem_head {
-+ struct list_head free_list;
-+ size_t size;
-+ u32 flag;
-+#ifdef MALLOCK_BOUNDART_32BYTE
-+ u32 dummy[4]; // for 32byte boundary
-+#endif
-+} oc_mem_head;
-+
-+
-+u32 OC_MEM_TOP = 0;
-+static u32 OC_MEM_BASE = 0;
-+static u32 OC_MEM_SIZE = 0;
-+static u32 OC_MEM_HCCA_BASE = 0;
-+#define OC_MEM_HCCA_SIZE 0x100
-+
-+static spinlock_t oc_mem_list_lock = SPIN_LOCK_UNLOCKED;
-+static int is_oc_hcca_allocated = 0;
-+
-+static void oc_mem_list_add(oc_mem_head *cp);
-+static void* oc_malloc(size_t size, int gfp);
-+static void oc_mfree(void* fp);
-+static size_t oc_mem_check(int verbose);
-+
-+
-+/* mem_base is 256byte boundary */
-+void oc_mem_init(unsigned int mem_base, size_t size)
-+{
-+ oc_mem_head *top, *cp;
-+
-+ if (OC_MEM_BASE) return;
-+
-+ OC_MEM_TOP = mem_base;
-+ OC_MEM_HCCA_BASE = mem_base;
-+ OC_MEM_BASE = mem_base + OC_MEM_HCCA_SIZE; /* 0x100 for HCCA */
-+ OC_MEM_SIZE = size - OC_MEM_HCCA_SIZE;
-+
-+ top = MAKE_POINTER(OC_MEM_BASE, 0);
-+ INIT_OC_MEM_HEAD(top, 0);
-+
-+ cp = MAKE_POINTER(top, sizeof(oc_mem_head) + top->size);
-+ INIT_OC_MEM_HEAD(cp, OC_MEM_SIZE
-+ - sizeof(oc_mem_head) - top->size
-+ - sizeof(oc_mem_head));
-+
-+ list_add(&cp->free_list, &top->free_list);
-+
-+#if 0
-+ // for test
-+ {
-+ char *a, *b, *c;
-+ a = oc_malloc(oc_mem_check(1), 0);
-+ oc_mem_check(1);
-+
-+ a = oc_malloc(256, 0);
-+ oc_mem_check(1);
-+ b = oc_malloc(256, 0);
-+ oc_mem_check(1);
-+ c = oc_malloc(256, 0);
-+ oc_mem_check(1);
-+ oc_mfree(b);
-+ oc_mem_check(1);
-+ b = oc_malloc(256, 0);
-+ oc_mem_check();
-+
-+ oc_mfree(a);
-+ oc_mem_check(1);
-+ oc_mfree(b);
-+ oc_mem_check(1);
-+ oc_mfree(c);
-+ oc_mem_check(1);
-+
-+ a = oc_malloc(256, 0);
-+ oc_mem_check(1);
-+ b = oc_malloc(256, 0);
-+ oc_mem_check(1);
-+ c = oc_malloc(256, 0);
-+ oc_mem_check(1);
-+ oc_mfree(a);
-+ oc_mem_check(1);
-+ oc_mfree(c);
-+ oc_mem_check(1);
-+ oc_mfree(b);
-+ oc_mem_check(1);
-+ }
-+#endif
-+}
-+
-+static void oc_mem_list_add(oc_mem_head *cp)
-+{
-+ oc_mem_head *top = (oc_mem_head *)OC_MEM_BASE;
-+ struct list_head *n;
-+
-+ /* address order */
-+ list_for_each(n, &top->free_list) {
-+ if ((u32)n > (u32)cp) {
-+ list_add_tail(&cp->free_list, n);
-+ return;
-+ }
-+ }
-+ list_add_tail(&cp->free_list, &top->free_list);
-+}
-+
-+static void* oc_malloc(size_t size, int gfp)
-+{
-+ oc_mem_head *top = (oc_mem_head *)OC_MEM_BASE;
-+ oc_mem_head *cp = NULL;
-+ struct list_head *n;
-+
-+ if (!top)
-+ panic("oc_malloc: not set OC_MEM_BASE.");
-+
-+ if (size == 0)
-+ return (void*)0;
-+
-+#if defined(MALLOCK_BOUNDART_32BYTE)
-+ size = ((size + 32 - 1) / 32) * 32; // for 32byte boundary
-+#elif defined(MALLOCK_BOUNDART_16BYTE)
-+ size = ((size + 16 - 1) / 16) * 16; // for 16byte boundary
-+#else
-+ size = ((size + sizeof(u32) - 1) / sizeof(u32)) * sizeof(u32);
-+#endif
-+
-+ list_for_each(n, &top->free_list) {
-+ if (((oc_mem_head *)n)->size >= size) {
-+ cp = (oc_mem_head *)n;
-+ break;
-+ }
-+ }
-+ if (!cp) {
-+ return (void*)0;
-+ }
-+
-+ if (cp->size > size + sizeof(oc_mem_head)) {
-+ oc_mem_head *fp;
-+ size_t alloc = size + sizeof(oc_mem_head);
-+ size_t new_size = cp->size - alloc;
-+
-+ list_del(&cp->free_list);
-+ INIT_OC_MEM_HEAD(cp, size);
-+
-+ fp = MAKE_POINTER(cp, alloc);
-+ INIT_OC_MEM_HEAD(fp, new_size);
-+ oc_mem_list_add(fp);
-+ dbg("separate %08x-%04x %08x-%04x\n", (u32)cp, cp->size, (u32)fp, fp->size);
-+ } else if (cp->free_list.next == cp->free_list.prev
-+ && cp->free_list.next == &top->free_list) {
-+ dbg("mallock error %08x-%04x\n", (u32)cp, cp->size);
-+ return (void*)0;
-+ } else {
-+ dbg("alloc this %08x-%04x\n", (u32)cp, cp->size);
-+ list_del_init(&cp->free_list);
-+ }
-+
-+ return (void *)(cp + 1);
-+}
-+
-+static void oc_mfree(void* fp)
-+{
-+ oc_mem_head *top = (oc_mem_head *)OC_MEM_BASE;
-+ oc_mem_head *cp = (oc_mem_head *)fp - 1;
-+ struct list_head *n;
-+
-+ if (fp == (void*)0)
-+ return;
-+ if (!IS_ALLOCATED_MEMORY(cp)) {
-+ dbg("%08x is not allocated memory. n=%08x p=%08x s=%04x\n",
-+ (u32)fp, (u32)cp->free_list.next, (u32)cp->free_list.prev, cp->size);
-+ return;
-+ }
-+
-+ list_for_each(n, &top->free_list) {
-+ /* cp is just previous of this free block */
-+ if (MAKE_POINTER(cp, cp->size + sizeof(oc_mem_head))
-+ == (oc_mem_head *)n) {
-+ oc_mem_head *pp = (oc_mem_head *)n->prev;
-+ dbg("P %08x-%04x merged to %08x-%04x\n", (u32)n, ((oc_mem_head *)n)->size, (u32)cp, cp->size);
-+ list_del(n);
-+ INIT_OC_MEM_HEAD(cp, cp->size
-+ + ((oc_mem_head *)n)->size
-+ + sizeof(oc_mem_head));
-+ /* cp merge to previous free block */
-+ if (cp == MAKE_POINTER(pp,
-+ pp->size + sizeof(oc_mem_head)) && pp != top) {
-+ dbg("P %08x-%04x merged to %08x-%04x\n", (u32)cp, cp->size, (u32)pp, pp->size);
-+ list_del(&pp->free_list);
-+ INIT_OC_MEM_HEAD(pp, pp->size
-+ + cp->size + sizeof(oc_mem_head));
-+ cp = pp;
-+ }
-+ break;
-+ }
-+ /* cp is just next of this free block */
-+ if (cp == MAKE_POINTER(n, ((oc_mem_head *)n)->size
-+ + sizeof(oc_mem_head))) {
-+ oc_mem_head *np = (oc_mem_head *)n->next;
-+ dbg("N %08x-%04x merged to %08x-%04x\n", (u32)cp, cp->size, (u32)n, ((oc_mem_head *)n)->size);
-+ list_del(n);
-+ INIT_OC_MEM_HEAD((oc_mem_head *)n,
-+ ((oc_mem_head *)n)->size
-+ + cp->size + sizeof(oc_mem_head));
-+ cp = (oc_mem_head *)n;
-+ if (np == MAKE_POINTER(cp,
-+ cp->size + sizeof(oc_mem_head))) {
-+ dbg("N %08x-%04x merged to %08x-%04x\n", (u32)np, np->size, (u32)cp, cp->size);
-+ list_del(&np->free_list);
-+ INIT_OC_MEM_HEAD(cp, cp->size
-+ + np->size + sizeof(oc_mem_head));
-+ }
-+ break;
-+ }
-+ }
-+
-+ oc_mem_list_add(cp);
-+}
-+
-+
-+static size_t oc_mem_check(int verbose)
-+{
-+ oc_mem_head *top = (oc_mem_head *)OC_MEM_BASE;
-+ oc_mem_head *nhp = top;
-+ int bc = 0;
-+ int alloc_bc = 0;
-+ int free_bc = 0;
-+ size_t alloc_size = 0;
-+ size_t free_size = 0;
-+ size_t total = 0;
-+
-+ if (verbose) {
-+ printk("[No.] A HEAD PREV NEXT SIZE\n");
-+ printk("-----+-+--------+--------+--------+----\n");
-+ }
-+ while ((u32)nhp < OC_MEM_BASE + OC_MEM_SIZE) {
-+ char *mark;
-+ if (IS_ALLOCATED_MEMORY(nhp)) {
-+ mark = "*";
-+ alloc_bc++;
-+ alloc_size += nhp->size + sizeof(oc_mem_head);
-+ } else {
-+ mark = " ";
-+ free_bc++;
-+ free_size += nhp->size + sizeof(oc_mem_head);
-+ }
-+ total += nhp->size + sizeof(oc_mem_head);
-+ if (verbose) {
-+ printk("[%03d] %s %08x : %08x %08x %04x\n",
-+ bc++, mark, (u32)nhp,
-+ (u32)nhp->free_list.prev,
-+ (u32)nhp->free_list.next, nhp->size);
-+ }
-+ nhp = MAKE_POINTER(nhp, nhp->size+sizeof(oc_mem_head));
-+ }
-+ if (verbose) {
-+ printk("-----+-+--------+--------+--------+----\n");
-+ }
-+ printk("alloc=%08x(%d) free=%08x(%d) total=%08x\n",
-+ alloc_size, alloc_bc, free_size, free_bc, total);
-+
-+ return free_size;
-+}
-+
-+#undef kmalloc
-+#undef kfree
-+
-+void KFREE(void* p)
-+{
-+ dbg("KFREE %08x\n", p);
-+ spin_lock(&oc_mem_list_lock);
-+ oc_mfree((void*)p);
-+ spin_unlock(&oc_mem_list_lock);
-+}
-+
-+void* KMALLOC(size_t s, int v)
-+{
-+ void *p;
-+ spin_lock(&oc_mem_list_lock);
-+ p = oc_malloc(s, v);
-+ spin_unlock(&oc_mem_list_lock);
-+
-+//oc_mem_check(0);
-+ dbg("KMALLOC %08x - %04x\n", p , s);
-+ if (s != 0 && p == NULL) {
-+ oc_mem_check(1);
-+ panic("oc_malloc: no more memory on chip RAM (%dbyts)", s);
-+ }
-+ return p;
-+}
-+
-+void* oc_hcca_alloc(struct pci_dev *hwdev, size_t size, dma_addr_t *handle)
-+{
-+ void *p;
-+
-+ if (!size)
-+ return (void *)0;
-+
-+ if (!OC_MEM_HCCA_BASE)
-+ panic("oc_malloc: not set OC_MEM_BASE.");
-+ if (is_oc_hcca_allocated)
-+ panic("oc_hcca_alloc: HCCA memory was alrady allocated.");
-+ if (size > OC_MEM_HCCA_SIZE)
-+ panic("oc_hcca_alloc: no more memory on RAM0 (size=%d)", size);
-+
-+ p = (void *)OC_MEM_HCCA_BASE; /* 256byte boundary */
-+ //*handle = (dma_addr_t)OC_MEM_VAR_TO_OFFSET(p);
-+ return p;
-+}
-+
-+void oc_hcca_free(struct pci_dev *hwdev, size_t size, void *vaddr,
-+ dma_addr_t dma_handle)
-+{
-+ is_oc_hcca_allocated = 0;
-+}
-+
-diff -Nur linux_c860_org/drivers/usb/mem-onchip.h linux/drivers/usb/mem-onchip.h
---- linux_c860_org/drivers/usb/mem-onchip.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/usb/mem-onchip.h 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,144 @@
-+/*
-+ * linux/drivers/usb/mem-onchip.h
-+ *
-+ * Copyright (c) 2003 Lineo Solutions, Inc.
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file "COPYING" in the main directory of this archive
-+ * for more details.
-+ *
-+ */
-+
-+#ifndef _MEM_ON_CHIP_H_
-+#define _MEM_ON_CHIP_H_ 1
-+
-+#include <linux/pci.h>
-+
-+#define OC_MEM_PCI_MAP_DEBUG
-+#define OC_MEM_PCI_MAP_USE_MEMCPY
-+
-+#define OC_MEM_VAR_TO_OFFSET(x) ((unsigned int)x - OC_MEM_TOP)
-+#define OC_MEM_OFFSET_TO_VAR(x) ((unsigned int)x + OC_MEM_TOP)
-+
-+#ifdef __LINUX_USB_H
-+#define pci_alloc_consistent(dev, size, dma_addr) \
-+ oc_hcca_alloc(dev, size, dma_addr)
-+#define pci_free_consistent(dev, size, var, dma_addr) \
-+ oc_hcca_free(dev, size, var, dma_addr)
-+#else
-+#define pci_alloc_consistent(dev, size, dma_addr) \
-+ PCI_ALLOC_CONSISTENT(dev, size, dma_addr)
-+#define pci_free_consistent(dev, size, var, dma_addr) \
-+ KFREE(var)
-+#endif
-+
-+#define pci_map_single(hwdev, ptr, size, direction) \
-+ PCI_MAP_SINGLE(hwdev, ptr, size, direction)
-+#define pci_unmap_single(hwdev, dma_addr, size, direction) \
-+ PCI_UNMAP_SINGLE(hwdev, dma_addr, size, direction)
-+
-+
-+extern u32 OC_MEM_TOP;
-+
-+void oc_mem_init(unsigned int top, size_t size);
-+void* KMALLOC(size_t s, int v);
-+void KFREE(void* p);
-+void* oc_hcca_alloc(struct pci_dev *hwdev, size_t size, dma_addr_t *handle);
-+void oc_hcca_free(struct pci_dev *hwdev,
-+ size_t size, void *vaddr, dma_addr_t dma_handle);
-+
-+
-+/*
-+ * replace PCI function
-+*/
-+static inline void* PCI_ALLOC_CONSISTENT(struct pci_dev *hwdev, size_t size, dma_addr_t *handle)
-+{
-+ void *p = KMALLOC(size, GFP_KERNEL | GFP_DMA);
-+ *handle = (dma_addr_t)OC_MEM_VAR_TO_OFFSET(p);
-+ return p;
-+}
-+
-+#ifdef OC_MEM_PCI_MAP_DEBUG
-+static inline char* PCI_DMA_FLAG_DESC(int direction)
-+{
-+ switch (direction) {
-+ case PCI_DMA_NONE: return "NONE";
-+ case PCI_DMA_FROMDEVICE: return "FROMDEVICE";
-+ case PCI_DMA_TODEVICE: return "TODEVICE";
-+ case PCI_DMA_BIDIRECTIONAL: return "BIDIRECTIONAL";
-+ }
-+ return "unknown";
-+}
-+#endif
-+
-+static inline dma_addr_t
-+PCI_MAP_SINGLE(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
-+{
-+#ifndef OC_MEM_PCI_MAP_USE_MEMCPY
-+ return (dma_addr_t)OC_MEM_VAR_TO_OFFSET(ptr);
-+#else
-+ void *p;
-+ size_t l = ((size + 3) / 4) * 4 + 4;
-+
-+ switch (direction) {
-+ case PCI_DMA_NONE:
-+ BUG();
-+ break;
-+ case PCI_DMA_FROMDEVICE: /* invalidate only */
-+ p = KMALLOC(l, GFP_KERNEL | GFP_DMA);
-+ break;
-+ case PCI_DMA_TODEVICE: /* writeback only */
-+ case PCI_DMA_BIDIRECTIONAL: /* writeback and invalidate */
-+ p = KMALLOC(l, GFP_KERNEL | GFP_DMA);
-+ memcpy(p, ptr, size);
-+ break;
-+ }
-+
-+ *((volatile unsigned int *)((unsigned int)p + l - 4))
-+ = (unsigned int)ptr;
-+#ifdef OC_MEM_PCI_MAP_DEBUG
-+#if 0
-+ printk("PCI_MAP_SINGLE: %s %08x - %04x , %08x - %04x\n",
-+ PCI_DMA_FLAG_DESC(direction),
-+ ptr, size, OC_MEM_VAR_TO_OFFSET(p), l);
-+#endif
-+#endif
-+ return (dma_addr_t)OC_MEM_VAR_TO_OFFSET(p);
-+#endif
-+}
-+
-+static inline void
-+PCI_UNMAP_SINGLE(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction)
-+{
-+#ifndef OC_MEM_PCI_MAP_USE_MEMCPY
-+ /* nothing to do */
-+#else
-+ void *p, *ptr;
-+ size_t l = ((size + 3) / 4) * 4 + 4;
-+ p = (void *)OC_MEM_OFFSET_TO_VAR(dma_addr);
-+ ptr = (void *)*((volatile unsigned int *)((unsigned int)p + l - 4));
-+
-+ switch (direction) {
-+ case PCI_DMA_NONE:
-+ BUG();
-+ break;
-+ case PCI_DMA_FROMDEVICE: /* invalidate only */
-+ case PCI_DMA_BIDIRECTIONAL: /* writeback and invalidate */
-+ memcpy(ptr, p, size);
-+ KFREE(p);
-+ break;
-+ case PCI_DMA_TODEVICE: /* writeback only */
-+ KFREE(p);
-+ break;
-+ }
-+#ifdef OC_MEM_PCI_MAP_DEBUG
-+#if 0
-+ printk("PCI_UNMAP_SINGLE: %s %08x - %04x , %08x\n",
-+ PCI_DMA_FLAG_DESC(direction), ptr, size, dma_addr);
-+#endif
-+#endif
-+#endif
-+}
-+
-+
-+#endif /* _MEM_ON_CHIP_H_ */
-diff -Nur linux_c860_org/drivers/usb/pcipool.c linux/drivers/usb/pcipool.c
---- linux_c860_org/drivers/usb/pcipool.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/usb/pcipool.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,401 @@
-+/*
-+ * linux/arch/arm/mach-pxa/pcipool.c
-+ *
-+ * Copyright (c) 2003 Lineo Solutions, Inc.
-+ *
-+ * Based on linux/arch/arm/mach-sa1100/pcipool.c
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ *
-+ */
-+/*
-+ NOTE:
-+
-+ this code was lifted straight out of drivers/pci/pci.c;
-+ when compiling for the Intel StrongARM SA-1110/SA-1111 the
-+ usb-ohci.c driver needs these routines even when the architecture
-+ has no pci bus...
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/pci.h>
-+#include <linux/string.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/spinlock.h>
-+#include <linux/bitops.h>
-+
-+#include <asm/page.h>
-+
-+#if defined(CONFIG_USB_USE_INTERNAL_MEMORY)
-+#include "mem-onchip.h"
-+#endif
-+
-+
-+struct pci_pool *pci_pool_create (const char *name, struct pci_dev *dev,
-+ size_t size, size_t align, size_t allocation, int flags);
-+void pci_pool_destroy (struct pci_pool *pool);
-+
-+void *pci_pool_alloc (struct pci_pool *pool, int flags, dma_addr_t *handle);
-+void pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t addr);
-+
-+
-+/*
-+ * Pool allocator ... wraps the pci_alloc_consistent page allocator, so
-+ * small blocks are easily used by drivers for bus mastering controllers.
-+ * This should probably be sharing the guts of the slab allocator.
-+ */
-+
-+struct pci_pool { /* the pool */
-+ struct list_head page_list;
-+ spinlock_t lock;
-+ size_t blocks_per_page;
-+ size_t size;
-+ int flags;
-+ struct pci_dev *dev;
-+ size_t allocation;
-+ char name [32];
-+ wait_queue_head_t waitq;
-+};
-+
-+struct pci_page { /* cacheable header for 'allocation' bytes */
-+ struct list_head page_list;
-+ void *vaddr;
-+ dma_addr_t dma;
-+ unsigned long bitmap [0];
-+};
-+
-+#define POOL_TIMEOUT_JIFFIES ((100 /* msec */ * HZ) / 1000)
-+#define POOL_POISON_BYTE 0xa7
-+
-+// #define CONFIG_PCIPOOL_DEBUG
-+
-+
-+/**
-+ * pci_pool_create - Creates a pool of pci consistent memory blocks, for dma.
-+ * @name: name of pool, for diagnostics
-+ * @pdev: pci device that will be doing the DMA
-+ * @size: size of the blocks in this pool.
-+ * @align: alignment requirement for blocks; must be a power of two
-+ * @allocation: returned blocks won't cross this boundary (or zero)
-+ * @flags: SLAB_* flags (not all are supported).
-+ *
-+ * Returns a pci allocation pool with the requested characteristics, or
-+ * null if one can't be created. Given one of these pools, pci_pool_alloc()
-+ * may be used to allocate memory. Such memory will all have "consistent"
-+ * DMA mappings, accessible by the device and its driver without using
-+ * cache flushing primitives. The actual size of blocks allocated may be
-+ * larger than requested because of alignment.
-+ *
-+ * If allocation is nonzero, objects returned from pci_pool_alloc() won't
-+ * cross that size boundary. This is useful for devices which have
-+ * addressing restrictions on individual DMA transfers, such as not crossing
-+ * boundaries of 4KBytes.
-+ */
-+struct pci_pool *
-+pci_pool_create (const char *name, struct pci_dev *pdev,
-+ size_t size, size_t align, size_t allocation, int flags)
-+{
-+ struct pci_pool *retval;
-+
-+ if (align == 0)
-+ align = 1;
-+ if (size == 0)
-+ return 0;
-+ else if (size < align)
-+ size = align;
-+ else if ((size % align) != 0) {
-+ size += align + 1;
-+ size &= ~(align - 1);
-+ }
-+
-+ if (allocation == 0) {
-+ if (PAGE_SIZE < size)
-+ allocation = size;
-+ else
-+ allocation = PAGE_SIZE;
-+ // FIXME: round up for less fragmentation
-+ } else if (allocation < size)
-+ return 0;
-+
-+ if (!(retval = kmalloc (sizeof *retval, flags)))
-+ return retval;
-+
-+#ifdef CONFIG_PCIPOOL_DEBUG
-+ flags |= SLAB_POISON;
-+#endif
-+
-+ strncpy (retval->name, name, sizeof retval->name);
-+ retval->name [sizeof retval->name - 1] = 0;
-+
-+ retval->dev = pdev;
-+ INIT_LIST_HEAD (&retval->page_list);
-+ spin_lock_init (&retval->lock);
-+ retval->size = size;
-+ retval->flags = flags;
-+ retval->allocation = allocation;
-+ retval->blocks_per_page = allocation / size;
-+ init_waitqueue_head (&retval->waitq);
-+
-+#ifdef CONFIG_PCIPOOL_DEBUG
-+ printk (KERN_DEBUG "pcipool create %s/%s size %d, %d/page (%d alloc)\n",
-+ pdev ? pdev->slot_name : NULL, retval->name, size,
-+ retval->blocks_per_page, allocation);
-+#endif
-+
-+ return retval;
-+}
-+
-+
-+static struct pci_page *
-+pool_alloc_page (struct pci_pool *pool, int mem_flags)
-+{
-+ struct pci_page *page;
-+ int mapsize;
-+
-+ mapsize = pool->blocks_per_page;
-+ mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG;
-+ mapsize *= sizeof (long);
-+
-+ page = (struct pci_page *) kmalloc (mapsize + sizeof *page, mem_flags);
-+ if (!page)
-+ return 0;
-+ page->vaddr = pci_alloc_consistent (pool->dev,
-+ pool->allocation, &page->dma);
-+ if (page->vaddr) {
-+ memset (page->bitmap, 0xff, mapsize); // bit set == free
-+ if (pool->flags & SLAB_POISON)
-+ memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
-+ list_add (&page->page_list, &pool->page_list);
-+ } else {
-+ kfree (page);
-+ page = 0;
-+ }
-+ return page;
-+}
-+
-+
-+static inline int
-+is_page_busy (int blocks, unsigned long *bitmap)
-+{
-+ while (blocks > 0) {
-+ if (*bitmap++ != ~0UL)
-+ return 1;
-+ blocks -= BITS_PER_LONG;
-+ }
-+ return 0;
-+}
-+
-+static void
-+pool_free_page (struct pci_pool *pool, struct pci_page *page)
-+{
-+ dma_addr_t dma = page->dma;
-+
-+ if (pool->flags & SLAB_POISON)
-+ memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
-+ pci_free_consistent (pool->dev, pool->allocation, page->vaddr, dma);
-+ list_del (&page->page_list);
-+ kfree (page);
-+}
-+
-+
-+/**
-+ * pci_pool_destroy - destroys a pool of pci memory blocks.
-+ * @pool: pci pool that will be destroyed
-+ *
-+ * Caller guarantees that no more memory from the pool is in use,
-+ * and that nothing will try to use the pool after this call.
-+ */
-+void
-+pci_pool_destroy (struct pci_pool *pool)
-+{
-+ unsigned long flags;
-+
-+#ifdef CONFIG_PCIPOOL_DEBUG
-+ printk (KERN_DEBUG "pcipool destroy %s/%s\n",
-+ pool->dev ? pool->dev->slot_name : NULL,
-+ pool->name);
-+#endif
-+
-+ spin_lock_irqsave (&pool->lock, flags);
-+ while (!list_empty (&pool->page_list)) {
-+ struct pci_page *page;
-+ page = list_entry (pool->page_list.next,
-+ struct pci_page, page_list);
-+ if (is_page_busy (pool->blocks_per_page, page->bitmap)) {
-+ printk (KERN_ERR "pci_pool_destroy %s/%s, %p busy\n",
-+ pool->dev ? pool->dev->slot_name : NULL,
-+ pool->name, page->vaddr);
-+ /* leak the still-in-use consistent memory */
-+ list_del (&page->page_list);
-+ kfree (page);
-+ } else
-+ pool_free_page (pool, page);
-+ }
-+ spin_unlock_irqrestore (&pool->lock, flags);
-+ kfree (pool);
-+}
-+
-+
-+/**
-+ * pci_pool_alloc - get a block of consistent memory
-+ * @pool: pci pool that will produce the block
-+ * @mem_flags: SLAB_KERNEL or SLAB_ATOMIC
-+ * @handle: pointer to dma address of block
-+ *
-+ * This returns the kernel virtual address of a currently unused block,
-+ * and reports its dma address through the handle.
-+ * If such a memory block can't be allocated, null is returned.
-+ */
-+void *
-+pci_pool_alloc (struct pci_pool *pool, int mem_flags, dma_addr_t *handle)
-+{
-+ unsigned long flags;
-+ struct list_head *entry;
-+ struct pci_page *page;
-+ int map, block;
-+ size_t offset;
-+ void *retval;
-+
-+restart:
-+ spin_lock_irqsave (&pool->lock, flags);
-+ list_for_each (entry, &pool->page_list) {
-+ int i;
-+ page = list_entry (entry, struct pci_page, page_list);
-+ /* only cachable accesses here ... */
-+ for (map = 0, i = 0;
-+ i < pool->blocks_per_page;
-+ i += BITS_PER_LONG, map++) {
-+ if (page->bitmap [map] == 0)
-+ continue;
-+ block = ffz (~ page->bitmap [map]);
-+ if ((i + block) < pool->blocks_per_page) {
-+ clear_bit (block, &page->bitmap [map]);
-+ offset = (BITS_PER_LONG * map) + block;
-+ offset *= pool->size;
-+ goto ready;
-+ }
-+ }
-+ }
-+ if (!(page = pool_alloc_page (pool, mem_flags))) {
-+ if (mem_flags == SLAB_KERNEL) {
-+ DECLARE_WAITQUEUE (wait, current);
-+
-+ current->state = TASK_INTERRUPTIBLE;
-+ add_wait_queue (&pool->waitq, &wait);
-+ spin_unlock_irqrestore (&pool->lock, flags);
-+
-+ schedule_timeout (POOL_TIMEOUT_JIFFIES);
-+
-+ current->state = TASK_RUNNING;
-+ remove_wait_queue (&pool->waitq, &wait);
-+ goto restart;
-+ }
-+ retval = 0;
-+ goto done;
-+ }
-+
-+ clear_bit (0, &page->bitmap [0]);
-+ offset = 0;
-+ready:
-+ retval = offset + page->vaddr;
-+ *handle = offset + page->dma;
-+done:
-+ spin_unlock_irqrestore (&pool->lock, flags);
-+ return retval;
-+}
-+
-+
-+static struct pci_page *
-+pool_find_page (struct pci_pool *pool, dma_addr_t dma)
-+{
-+ unsigned long flags;
-+ struct list_head *entry;
-+ struct pci_page *page;
-+
-+ spin_lock_irqsave (&pool->lock, flags);
-+ list_for_each (entry, &pool->page_list) {
-+ page = list_entry (entry, struct pci_page, page_list);
-+ if (dma < page->dma)
-+ continue;
-+ if (dma < (page->dma + pool->allocation))
-+ goto done;
-+ }
-+ page = 0;
-+done:
-+ spin_unlock_irqrestore (&pool->lock, flags);
-+ return page;
-+}
-+
-+
-+/**
-+ * pci_pool_free - put block back into pci pool
-+ * @pool: the pci pool holding the block
-+ * @vaddr: virtual address of block
-+ * @dma: dma address of block
-+ *
-+ * Caller promises neither device nor driver will again touch this block
-+ * unless it is first re-allocated.
-+ */
-+void
-+pci_pool_free (struct pci_pool *pool, void *vaddr, dma_addr_t dma)
-+{
-+ struct pci_page *page;
-+ unsigned long flags;
-+ int map, block;
-+
-+ if ((page = pool_find_page (pool, dma)) == 0) {
-+ printk (KERN_ERR "pci_pool_free %s/%s, %p/%x (bad dma)\n",
-+ pool->dev ? pool->dev->slot_name : NULL,
-+ pool->name, vaddr, dma);
-+ return;
-+ }
-+#ifdef CONFIG_PCIPOOL_DEBUG
-+ if (((dma - page->dma) + (void *)page->vaddr) != vaddr) {
-+ printk (KERN_ERR "pci_pool_free %s/%s, %p (bad vaddr)/%x\n",
-+ pool->dev ? pool->dev->slot_name : NULL,
-+ pool->name, vaddr, dma);
-+ return;
-+ }
-+#endif
-+
-+ block = dma - page->dma;
-+ block /= pool->size;
-+ map = block / BITS_PER_LONG;
-+ block %= BITS_PER_LONG;
-+
-+#ifdef CONFIG_PCIPOOL_DEBUG
-+ if (page->bitmap [map] & (1UL << block)) {
-+ printk (KERN_ERR "pci_pool_free %s/%s, dma %x already free\n",
-+ pool->dev ? pool->dev->slot_name : NULL,
-+ pool->name, dma);
-+ return;
-+ }
-+#endif
-+ if (pool->flags & SLAB_POISON)
-+ memset (vaddr, POOL_POISON_BYTE, pool->size);
-+
-+ spin_lock_irqsave (&pool->lock, flags);
-+ set_bit (block, &page->bitmap [map]);
-+ if (waitqueue_active (&pool->waitq))
-+ wake_up (&pool->waitq);
-+ /*
-+ * Resist a temptation to do
-+ * if (!is_page_busy(bpp, page->bitmap)) pool_free_page(pool, page);
-+ * it is not interrupt safe. Better have empty pages hang around.
-+ */
-+ spin_unlock_irqrestore (&pool->lock, flags);
-+}
-+
-+
-+/*
-+EXPORT_SYMBOL (pci_pool_create);
-+EXPORT_SYMBOL (pci_pool_destroy);
-+EXPORT_SYMBOL (pci_pool_alloc);
-+EXPORT_SYMBOL (pci_pool_free);
-+*/
-+
-diff -Nur linux_c860_org/drivers/usb/usb-ohci-tc6393.c linux/drivers/usb/usb-ohci-tc6393.c
---- linux_c860_org/drivers/usb/usb-ohci-tc6393.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/usb/usb-ohci-tc6393.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,516 @@
-+/*
-+ * linux/drivers/usb/usb-ohci-tc6393.c
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ *
-+ * Based on:
-+ *
-+ * linux/drivers/usb/usb-ohci-pci.c
-+ *
-+ * and
-+ *
-+ * linux/drivers/usb/usb-ohci-sa1111.c
-+ *
-+ * The outline of this code was taken from Brad Parkers <brad@heeltoe.com>
-+ * original OHCI driver modifications, and reworked into a cleaner form
-+ * by Russell King <rmk@arm.linux.org.uk>.
-+ */
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/ioport.h>
-+#include <linux/interrupt.h>
-+#include <linux/slab.h>
-+#include <linux/usb.h>
-+#include <linux/pm.h>
-+#include <linux/delay.h>
-+#include <linux/ioctl.h>
-+#include <linux/miscdevice.h>
-+#include <asm/uaccess.h>
-+
-+#include <asm/hardware.h>
-+#include <asm/irq.h>
-+#include <asm/io.h>
-+#include <asm/sharp_tc6393_usb.h>
-+
-+#include "usb-ohci.h"
-+
-+#define TC6393_OHCI_CTL_MINOR_DEV 222
-+
-+static int tc6393_usb_internal_port_enable = 0; // default is disable
-+static int tc6393_usb_external_port_enable = 1; // default is enable
-+
-+//#define THREAD_RESUME
-+#ifdef THREAD_RESUME
-+static int resume_thread_alive = 0;
-+static int tc6393_ohci_pm_resume(void);
-+#endif
-+
-+int __devinit
-+hc_add_ohci(struct pci_dev *dev, int irq, void *membase, unsigned long flags,
-+ ohci_t **ohci, const char *name, const char *slot_name);
-+extern void hc_remove_ohci(ohci_t *ohci);
-+
-+static ohci_t *tc6393_ohci;
-+
-+#ifdef CONFIG_PM
-+static int tc6393_ohci_pm_callback(
-+ struct pm_dev *pm_device, pm_request_t rqst, void *data);
-+#endif
-+
-+
-+static int do_ioctl(struct inode * inode,
-+ struct file *filp, u_int cmd, u_long arg)
-+{
-+ long val,res;
-+
-+#ifdef THREAD_RESUME
-+ while(resume_thread_alive) udelay(100);
-+#endif
-+ switch (cmd) {
-+ case TC6393_OHCI_IOC_PDOWN: /* Power Down */
-+ //printk("TC6393_OHCI_IOC_PDOWN: %d\n",arg);
-+ if (arg == 0) {
-+ TC6393_USB_REG(TC6393_USB_SVPMCS)
-+ |= TC6393_USB_PM_USPW1;
-+ tc6393_usb_external_port_enable = 0;
-+ } else if (arg == 1) {
-+ TC6393_USB_REG(TC6393_USB_SVPMCS)
-+ |= TC6393_USB_PM_USPW2;
-+ tc6393_usb_internal_port_enable = 0;
-+ } else
-+ return -EINVAL;
-+ return 0;
-+ case TC6393_OHCI_IOC_PON: /* Power On */
-+ //printk("TC6393_OHCI_IOC_PON: %d\n",arg);
-+ if (arg == 0) {
-+ TC6393_USB_REG(TC6393_USB_SVPMCS)
-+ &= ~TC6393_USB_PM_USPW1;
-+ tc6393_usb_external_port_enable = 1;
-+ } else if (arg == 1) {
-+ TC6393_USB_REG(TC6393_USB_SVPMCS)
-+ &= ~TC6393_USB_PM_USPW2;
-+ tc6393_usb_internal_port_enable = 1;
-+ } else
-+ return -EINVAL;
-+ return 0;
-+ case TC6393_OHCI_IOC_PCHECK: /* Check Power */
-+ if ( get_user(val, (long *) arg) )
-+ return -EFAULT;
-+ if (val == 0) {
-+ res = (TC6393_USB_REG(TC6393_USB_SVPMCS)&TC6393_USB_PM_USPW1)?0:1;
-+ } else if (val == 1) {
-+ res = (TC6393_USB_REG(TC6393_USB_SVPMCS)&TC6393_USB_PM_USPW2)?0:1;
-+ } else return -EINVAL;
-+ return put_user(res, (int *)arg);
-+ default:
-+ break;
-+ }
-+ return -EOPNOTSUPP;
-+}
-+
-+static struct file_operations tc6393_ohci_fops = {
-+ owner: THIS_MODULE,
-+ ioctl: do_ioctl
-+};
-+
-+static struct miscdevice tc6393_ohci_ctl_device = {
-+ TC6393_OHCI_CTL_MINOR_DEV,
-+ "tc6393_ohci_ctl",
-+ &tc6393_ohci_fops
-+};
-+
-+
-+static void tc6393_ohci_configure(void)
-+{
-+ u16 portval;
-+#if 0
-+printk("TC6393_SYS_PLL2CR: %04x\n", TC6393_SYS_REG(TC6393_SYS_PLL2CR));
-+TC6393_SYS_REG(TC6393_SYS_PLL2CR) = 0x0cc1;
-+#endif
-+
-+ TC6393_SYS_REG(TC6393_SYS_CCR) |= 2; /* clock enable */
-+ TC6393_SYS_REG(TC6393_SYS_FER) |= 1; /* USB enable */
-+
-+ //TC6393_USB_REG(TC6393_USB_SPPCNF) |= 1;
-+ TC6393_USB_REG(TC6393_USB_SPBA1)
-+ = TC6393_USB_OHCI_OP_REG_BASE & 0xffff; /* LW */
-+ TC6393_USB_REG(TC6393_USB_SPBA2)
-+ = TC6393_USB_OHCI_OP_REG_BASE >> 16; /* HW */
-+ TC6393_USB_REG(TC6393_USB_ILME) = 1;
-+
-+ portval = TC6393_USB_PM_PMES | TC6393_USB_PM_PMEE | TC6393_USB_PM_CKRNEN | TC6393_USB_PM_GCKEN;
-+ if (!tc6393_usb_external_port_enable) portval |= TC6393_USB_PM_USPW1;
-+ if (!tc6393_usb_internal_port_enable) portval |= TC6393_USB_PM_USPW2;
-+ TC6393_USB_REG(TC6393_USB_SVPMCS) = portval;
-+
-+ TC6393_USB_REG(TC6393_USB_INTC) = 2;
-+
-+#if 0
-+printk("TC6393_SYS_ConfigCR: %04x\n", TC6393_SYS_REG(TC6393_SYS_ConfigCR));
-+printk("TC6393_SYS_CCR: %04x\n", TC6393_SYS_REG(TC6393_SYS_CCR));
-+printk("TC6393_SYS_PLL2CR: %04x\n", TC6393_SYS_REG(TC6393_SYS_PLL2CR));
-+printk("TC6393_SYS_PLL1CR: %08x\n", (*(int *)(TC6393_SYS_BASE+TC6393_SYS_PLL1CR1)));
-+printk("TC6393_SYS_MCR: %04x\n", TC6393_SYS_REG(TC6393_SYS_MCR));
-+printk("TC6393_SYS_FER: %04x\n", TC6393_SYS_REG(TC6393_SYS_FER));
-+printk("TC6393_USB_Rev: %d\n", TC6393_USB_REG(TC6393_USB_SPRID));
-+printk("TC6393_USB_SPBA: %08x\n", (*(int *)(TC6393_USB_BASE+TC6393_USB_SPBA1)));
-+printk("TC6393_USB_ILME: %04x\n", TC6393_USB_REG(TC6393_USB_ILME));
-+printk("TC6393_USB_SVPMCS: %04x\n", TC6393_USB_REG(TC6393_USB_SVPMCS));
-+printk("TC6393_USB_INTC: %04x\n", TC6393_USB_REG(TC6393_USB_INTC));
-+printk("OHCI Rev: %08x\n", (*(int *)(TC6393_SYS_BASE+TC6393_USB_OHCI_OP_REG_BASE)));
-+#endif
-+#if 0
-+ {
-+ unsigned int top = TC6393_RAM0_BASE + 0x100;
-+ volatile unsigned int *ip = (volatile unsigned int *)(top);
-+ volatile unsigned short *sp = (volatile unsigned short *)(top+4);
-+ volatile unsigned char *cp = (volatile unsigned char *)(top+8);
-+ *ip = 0x12345678;
-+ printk("int %08x\n", *ip);
-+ sp[0] = 0x9876;
-+ sp[1] = 0x5432;
-+ printk("short %04x %04x\n", sp[0], sp[1]);
-+ cp[0] = 0x12;
-+ cp[1] = 0x23;
-+ cp[2] = 0x34;
-+ cp[3] = 0x45;
-+ printk("byte: %02x %02x %02x %02x\n", cp[0], cp[1], cp[2], cp[3]);
-+ }
-+#endif
-+}
-+
-+static int __init tc6393_ohci_init(void)
-+{
-+ int ret;
-+
-+ /*
-+ * Request memory resources.
-+ */
-+// if (!request_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT, "usb-ohci"))
-+// return -EBUSY;
-+
-+ tc6393_ohci_configure();
-+ oc_mem_init(TC6393_RAM0_BASE, TC6393_RAM0_SIZE);
-+
-+ /*
-+ * Initialise the generic OHCI driver.
-+ */
-+ ret = hc_add_ohci((struct pci_dev *)1, TC6393_IRQ_USBINT,
-+ (void *)(TC6393_SYS_BASE+TC6393_USB_OHCI_OP_REG_BASE),
-+ 0, &tc6393_ohci, "usb-ohci", "tc6393");
-+
-+#ifdef CONFIG_PM
-+ pm_register(PM_SYS_DEV, PM_SYS_UNKNOWN, tc6393_ohci_pm_callback);
-+#endif
-+
-+ if (misc_register(&tc6393_ohci_ctl_device))
-+ printk("failed to register tc6393_ohci_ctl_device\n");
-+
-+// if (ret)
-+// release_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT);
-+
-+ return ret;
-+}
-+
-+static void __exit tc6393_ohci_exit(void)
-+{
-+ misc_deregister(&tc6393_ohci_ctl_device);
-+
-+#ifdef CONFIG_PM
-+ pm_unregister_all(tc6393_ohci_pm_callback);
-+#endif
-+ hc_remove_ohci(tc6393_ohci);
-+
-+ /*
-+ * Put the USB host controller into reset.
-+ */
-+ TC6393_SYS_REG(TC6393_SYS_FER) &= ~1;
-+
-+ /*
-+ * Stop the USB clock.
-+ */
-+ TC6393_SYS_REG(TC6393_SYS_CCR) &= ~2;
-+
-+ /*
-+ * Release memory resources.
-+ */
-+// release_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT);
-+
-+}
-+
-+module_init(tc6393_ohci_init);
-+module_exit(tc6393_ohci_exit);
-+
-+
-+#ifdef CONFIG_PM
-+static void* tc6393_sram0_backup;
-+static dma_addr_t tc6393_sram0_backup_phys;
-+
-+/* usb-ohci.c */
-+#define OHCI_CONTROL_INIT \
-+ (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
-+extern spinlock_t usb_ed_lock;
-+
-+extern td_t * dl_reverse_done_list (ohci_t * ohci);
-+extern void dl_done_list (ohci_t * ohci, td_t * td_list);
-+extern int hc_start (ohci_t * ohci);
-+extern int hc_reset (ohci_t * ohci);
-+
-+
-+/* controller died; cleanup debris, then restart */
-+/* must not be called from interrupt context */
-+
-+static void hc_restart (ohci_t *ohci)
-+{
-+ int temp;
-+ int i;
-+
-+ ohci->disabled = 1;
-+ ohci->sleeping = 0;
-+ if (ohci->bus->root_hub)
-+ usb_disconnect (&ohci->bus->root_hub);
-+
-+ /* empty the interrupt branches */
-+ for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0;
-+ for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table[i] = 0;
-+
-+ /* no EDs to remove */
-+ ohci->ed_rm_list [0] = NULL;
-+ ohci->ed_rm_list [1] = NULL;
-+
-+ /* empty control and bulk lists */
-+ ohci->ed_isotail = NULL;
-+ ohci->ed_controltail = NULL;
-+ ohci->ed_bulktail = NULL;
-+
-+ if ((temp = hc_reset (ohci)) < 0 || (temp = hc_start (ohci)) < 0) {
-+ err ("can't restart usb-%s, %d", ohci->ohci_dev->slot_name, temp);
-+ } else
-+ dbg ("restart usb-%s completed", ohci->ohci_dev->slot_name);
-+}
-+
-+static unsigned int tc6393_usb_pm_uspw = 0;
-+
-+static int tc6393_ohci_pm_suspend(u32 state)
-+{
-+ ohci_t *ohci = tc6393_ohci;
-+ unsigned long flags;
-+
-+ /* bus suspend */
-+ if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) {
-+ dbg ("can't suspend usb-%s (state is %s)", ohci->slot_name,
-+ hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS));
-+ return -EIO;
-+ }
-+
-+ /* act as if usb suspend can always be used */
-+ info ("USB suspend: usb-%s", ohci->slot_name);
-+ ohci->sleeping = 1;
-+
-+ /* First stop processing */
-+ spin_lock_irqsave (&usb_ed_lock, flags);
-+ ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE);
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
-+ (void) readl (&ohci->regs->intrstatus);
-+ spin_unlock_irqrestore (&usb_ed_lock, flags);
-+
-+ /* Wait a frame or two */
-+ mdelay(1);
-+ if (!readl (&ohci->regs->intrstatus) & OHCI_INTR_SF)
-+ mdelay (1);
-+
-+ /* Enable remote wakeup */
-+ writel (readl(&ohci->regs->intrenable) | OHCI_INTR_RD, &ohci->regs->intrenable);
-+
-+ /* Suspend chip and let things settle down a bit */
-+ ohci->hc_control = OHCI_USB_SUSPEND;
-+ writel (ohci->hc_control, &ohci->regs->control);
-+#if 0
-+ (void) readl (&ohci->regs->control);
-+ mdelay (500); /* No schedule here ! */
-+ switch (readl (&ohci->regs->control) & OHCI_CTRL_HCFS) {
-+ case OHCI_USB_RESET:
-+ dbg("Bus in reset phase ???");
-+ break;
-+ case OHCI_USB_RESUME:
-+ dbg("Bus in resume phase ???");
-+ break;
-+ case OHCI_USB_OPER:
-+ dbg("Bus in operational phase ???");
-+ break;
-+ case OHCI_USB_SUSPEND:
-+ dbg("Bus suspended");
-+ break;
-+ }
-+ tc6393_usb_pm_uspw = TC6393_USB_REG(TC6393_USB_SVPMCS);
-+#else
-+ /* Power Down */
-+ tc6393_usb_pm_uspw = TC6393_USB_REG(TC6393_USB_SVPMCS);
-+ TC6393_USB_REG(TC6393_USB_SVPMCS) |= TC6393_USB_PM_USPW1;
-+ TC6393_USB_REG(TC6393_USB_SVPMCS) |= TC6393_USB_PM_USPW2;
-+#endif
-+
-+ /* store SRAM */
-+ tc6393_sram0_backup = consistent_alloc(GFP_KERNEL | GFP_DMA,
-+ TC6393_RAM0_SIZE, &tc6393_sram0_backup_phys);
-+ memcpy(tc6393_sram0_backup , TC6393_RAM0_BASE, TC6393_RAM0_SIZE);
-+//memset(TC6393_RAM0_BASE, 0xff, TC6393_RAM0_SIZE);
-+ /* device suspend */
-+ TC6393_SYS_REG(TC6393_SYS_FER) &= ~1;
-+ TC6393_SYS_REG(TC6393_SYS_CCR) &= ~2;
-+
-+ return 0;
-+}
-+
-+static int tc6393_ohci_pm_resume(void)
-+{
-+ ohci_t *ohci = tc6393_ohci;
-+ int temp;
-+ unsigned long flags;
-+ int ret = 0;
-+
-+#ifdef THREAD_RESUME
-+ resume_thread_alive = 1;
-+#endif
-+
-+ /* device resume */
-+ tc6393_ohci_configure();
-+
-+ /* restore SRAM */
-+ memcpy(TC6393_RAM0_BASE, tc6393_sram0_backup, TC6393_RAM0_SIZE);
-+ consistent_free(tc6393_sram0_backup,
-+ TC6393_RAM0_SIZE, tc6393_sram0_backup_phys);
-+
-+ /* Power On */
-+ if ( !(tc6393_usb_pm_uspw & TC6393_USB_PM_USPW1) )
-+ TC6393_USB_REG(TC6393_USB_SVPMCS) &= ~TC6393_USB_PM_USPW1;
-+ if ( !(tc6393_usb_pm_uspw & TC6393_USB_PM_USPW2) )
-+ TC6393_USB_REG(TC6393_USB_SVPMCS) &= ~TC6393_USB_PM_USPW2;
-+
-+ /* bus resume */
-+ /* guard against multiple resumes */
-+ atomic_inc (&ohci->resume_count);
-+ if (atomic_read (&ohci->resume_count) != 1) {
-+ err ("concurrent resumes for usb-%s", ohci->slot_name);
-+ atomic_dec (&ohci->resume_count);
-+#ifdef THREAD_RESUME
-+ resume_thread_alive = 0;
-+#endif
-+ return 0;
-+ }
-+
-+ /* did we suspend, or were we powered off? */
-+ ohci->hc_control = readl (&ohci->regs->control);
-+ temp = ohci->hc_control & OHCI_CTRL_HCFS;
-+
-+#ifdef DEBUG
-+ /* the registers may look crazy here */
-+ ohci_dump_status (ohci);
-+#endif
-+
-+ switch (temp) {
-+
-+ case OHCI_USB_RESET: // lost power
-+ info ("USB restart: usb-%s", ohci->slot_name);
-+ hc_restart (ohci);
-+ break;
-+
-+ case OHCI_USB_SUSPEND: // host wakeup
-+ case OHCI_USB_RESUME: // remote wakeup
-+ info ("USB continue: usb-%s from %s wakeup", ohci->slot_name,
-+ (temp == OHCI_USB_SUSPEND)
-+ ? "host" : "remote");
-+ ohci->hc_control = OHCI_USB_RESUME;
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ (void) readl (&ohci->regs->control);
-+ mdelay (20); /* no schedule here ! */
-+ /* Some controllers (lucent) need a longer delay here */
-+ mdelay (15);
-+ temp = readl (&ohci->regs->control);
-+ temp = ohci->hc_control & OHCI_CTRL_HCFS;
-+ if (temp != OHCI_USB_RESUME) {
-+ err ("controller usb-%s won't resume", ohci->slot_name);
-+ ohci->disabled = 1;
-+#ifdef THREAD_RESUME
-+ resume_thread_alive = 0;
-+#endif
-+ return -EIO;
-+ }
-+
-+ /* Some chips likes being resumed first */
-+ writel (OHCI_USB_OPER, &ohci->regs->control);
-+ (void) readl (&ohci->regs->control);
-+ mdelay (3);
-+
-+ /* Then re-enable operations */
-+ spin_lock_irqsave (&usb_ed_lock, flags);
-+ ohci->disabled = 0;
-+ ohci->sleeping = 0;
-+ ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
-+ if (!ohci->ed_rm_list[0] && !ohci->ed_rm_list[1]) {
-+ if (ohci->ed_controltail)
-+ ohci->hc_control |= OHCI_CTRL_CLE;
-+ if (ohci->ed_bulktail)
-+ ohci->hc_control |= OHCI_CTRL_BLE;
-+ }
-+ writel (ohci->hc_control, &ohci->regs->control);
-+ writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
-+ writel (OHCI_INTR_SF, &ohci->regs->intrenable);
-+ /* Check for a pending done list */
-+ writel (OHCI_INTR_WDH, &ohci->regs->intrdisable);
-+ (void) readl (&ohci->regs->intrdisable);
-+ spin_unlock_irqrestore (&usb_ed_lock, flags);
-+ if (ohci->hcca->done_head)
-+ dl_done_list (ohci, dl_reverse_done_list (ohci));
-+ writel (OHCI_INTR_WDH, &ohci->regs->intrenable);
-+ writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
-+ writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
-+ break;
-+
-+ default:
-+ warn ("odd resume for usb-%s", ohci->slot_name);
-+ }
-+
-+ /* controller is operational, extra resumes are harmless */
-+ atomic_dec (&ohci->resume_count);
-+
-+#ifdef THREAD_RESUME
-+ resume_thread_alive = 0;
-+#endif
-+ return ret;
-+}
-+
-+static int
-+tc6393_ohci_pm_callback(struct pm_dev *pm_device, pm_request_t rqst, void *data)
-+{
-+ int error = 0;
-+
-+ switch (rqst) {
-+ case PM_SAVE_STATE:
-+ break;
-+ case PM_SUSPEND:
-+#ifdef THREAD_RESUME
-+ while(resume_thread_alive) udelay(100);
-+#endif
-+ error = tc6393_ohci_pm_suspend((u32)data);
-+ break;
-+ case PM_RESUME:
-+#ifdef THREAD_RESUME
-+ kernel_thread(tc6393_ohci_pm_resume, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
-+ error = 0;
-+#else
-+ error = tc6393_ohci_pm_resume();
-+#endif
-+ break;
-+ default:
-+ break;
-+ }
-+ return error;
-+}
-+#endif
-diff -Nur linux_c860_org/drivers/usb/usb-ohci.c linux/drivers/usb/usb-ohci.c
---- linux_c860_org/drivers/usb/usb-ohci.c 2002-08-26 14:45:02.000000000 +0900
-+++ linux/drivers/usb/usb-ohci.c 2004-06-10 21:09:10.000000000 +0900
-@@ -12,6 +12,7 @@
- *
- * History:
- *
-+ * 2004/02/26 Lineo Solutions, Inc. for Tosa (SHARP)
- * 2001/09/19 USB_ZERO_PACKET support (Jean Tourrilhes)
- * 2001/07/17 power management and pmac cleanup (Benjamin Herrenschmidt)
- * 2001/03/24 td/ed hashing to remove bus_to_virt (Steve Longerbeam);
-@@ -89,7 +90,7 @@
- #define OHCI_UNLINK_TIMEOUT (HZ / 10)
-
- static LIST_HEAD (ohci_hcd_list);
--static spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED;
-+spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED;
-
-
- /*-------------------------------------------------------------------------*/
-@@ -1295,7 +1296,7 @@
- err("internal OHCI error: TD index > length");
- return;
- }
--if (data & (1 << 20)) panic("td_fill: A20 = 1: %08x\n", data);
-+//if (data & (1 << 20)) panic("td_fill: A20 = 1: %08x\n", data);
-
- /* use this td as the next dummy */
- td_pt = urb_priv->td [index];
-@@ -1509,7 +1510,7 @@
- /* replies to the request have to be on a FIFO basis so
- * we reverse the reversed done-list */
-
--static td_t * dl_reverse_done_list (ohci_t * ohci)
-+td_t * dl_reverse_done_list (ohci_t * ohci)
- {
- __u32 td_list_hc;
- td_t * td_rev = NULL;
-@@ -1657,7 +1658,7 @@
-
- /* td done list */
-
--static void dl_done_list (ohci_t * ohci, td_t * td_list)
-+void dl_done_list (ohci_t * ohci, td_t * td_list)
- {
- td_t * td_list_next = NULL;
- ed_t * ed;
-@@ -2126,7 +2127,7 @@
-
- /* reset the HC and BUS */
-
--static int hc_reset (ohci_t * ohci)
-+int hc_reset (ohci_t * ohci)
- {
- int timeout = 30;
- int smm_timeout = 50; /* 0,5 sec */
-@@ -2171,7 +2172,7 @@
- * enable interrupts
- * connect the virtual root hub */
-
--static int hc_start (ohci_t * ohci)
-+int hc_start (ohci_t * ohci)
- {
- __u32 mask;
- unsigned int fminterval;
-@@ -2418,7 +2419,8 @@
- ohci_mem_cleanup (ohci);
-
- /* unmap the IO address space */
-- iounmap (ohci->regs);
-+ if ((int)ohci->ohci_dev != 1)
-+ iounmap (ohci->regs);
-
- pci_free_consistent (ohci->ohci_dev, sizeof *ohci->hcca,
- ohci->hcca, ohci->hcca_dma);
-@@ -2432,7 +2434,7 @@
- */
- int __devinit
- hc_add_ohci(struct pci_dev *dev, int irq, void *mem_base, unsigned long flags,
-- ohci_t **ohci, const char *name, const char *slot_name)
-+ ohci_t **ohcip, const char *name, const char *slot_name)
- {
- char buf[8], *bufp = buf;
- ohci_t * ohci;
-@@ -2447,6 +2449,7 @@
- (unsigned long) mem_base, bufp);
-
- ohci = hc_alloc_ohci (dev, mem_base);
-+ *ohcip = ohci;
- if (!ohci) {
- return -ENOMEM;
- }
-diff -Nur linux_c860_org/drivers/usb/usb-ohci.h linux/drivers/usb/usb-ohci.h
---- linux_c860_org/drivers/usb/usb-ohci.h 2002-08-26 14:45:02.000000000 +0900
-+++ linux/drivers/usb/usb-ohci.h 2004-06-10 21:09:10.000000000 +0900
-@@ -5,8 +5,15 @@
- * (C) Copyright 2000-2001 David Brownell <dbrownell@users.sourceforge.net>
- *
- * usb-ohci.h
-+ *
-+ * ChangeLog:
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa (SHARP)
- */
-
-+#if defined(CONFIG_USB_USE_INTERNAL_MEMORY)
-+#include "mem-onchip.h"
-+#endif
-+
-
- static int cc_to_error[16] = {
-
-diff -Nur linux_c860_org/drivers/usb/usbkbd.c linux/drivers/usb/usbkbd.c
---- linux_c860_org/drivers/usb/usbkbd.c 2002-08-26 14:39:14.000000000 +0900
-+++ linux/drivers/usb/usbkbd.c 2004-06-10 21:09:10.000000000 +0900
-@@ -7,7 +7,11 @@
- *
- * Sponsored by SuSE
- */
--
-+/*
-+ * ChangeLog:
-+ * 1-Nov-2003 Sharp Corporation for Tosa
-+ *
-+ */
- /*
- * 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
-@@ -46,6 +50,26 @@
- MODULE_DESCRIPTION( DRIVER_DESC );
- MODULE_LICENSE("GPL");
-
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+static unsigned char usb_kbd_keycode[256] = {
-+ 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
-+ 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 41, 42,
-+ 43, 44, 45, 46, 47, 48, 49, 50, 28, 34, 31, 65, 92, 51, 52, 55,
-+ 54, 0, 97, 95, 96, 70, 98, 99,100, 60, 33, 58, 94, 39, 88, 89,
-+ 90,110,117,120, 30, 40,115, 0, 0, 0,104,106, 81,105,107, 124,
-+ 121,123,122, 32, 82, 83, 85, 86, 87, 71, 72, 73, 74, 75, 76, 77,
-+ 78, 79, 80, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0,101, 69, 53, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 56, 27, 57, 29,111,112,113,114, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+};
-+#else
- static unsigned char usb_kbd_keycode[256] = {
- 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
- 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
-@@ -64,6 +88,7 @@
- 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
- 150,158,159,128,136,177,178,176,142,152,173,140
- };
-+#endif
-
- struct usb_kbd {
- struct input_dev dev;
-@@ -84,6 +109,12 @@
-
- if (urb->status) return;
-
-+#if 0
-+ printk("kbd_irq[%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x]\n",
-+ kbd->new[0],kbd->new[1],kbd->new[2],kbd->new[3],kbd->new[4],
-+ kbd->new[5],kbd->new[6],kbd->new[7],kbd->new[8]);
-+#endif
-+
- for (i = 0; i < 8; i++)
- input_report_key(&kbd->dev, usb_kbd_keycode[i + 224], (kbd->new[0] >> i) & 1);
-
-@@ -200,7 +231,11 @@
-
- kbd->usbdev = dev;
-
-+#ifdef CONFIG_ARCH_SHARP_SL
-+ kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED);
-+#else
- kbd->dev.evbit[0] = BIT(EV_KEY) | BIT(EV_LED) | BIT(EV_REP);
-+#endif
- kbd->dev.ledbit[0] = BIT(LED_NUML) | BIT(LED_CAPSL) | BIT(LED_SCROLLL) | BIT(LED_COMPOSE) | BIT(LED_KANA);
-
- for (i = 0; i < 255; i++)
-diff -Nur linux_c860_org/drivers/video/Config.in linux/drivers/video/Config.in
---- linux_c860_org/drivers/video/Config.in 2002-09-11 12:02:37.000000000 +0900
-+++ linux/drivers/video/Config.in 2004-06-10 21:09:10.000000000 +0900
-@@ -10,6 +10,21 @@
- if [ "$CONFIG_FB" = "y" ]; then
- define_bool CONFIG_DUMMY_CONSOLE y
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-+ bool "UNICON Support(EXPERIMENTAL)" CONFIG_UNICON
-+ if [ "$CONFIG_UNICON" = "y" ]; then
-+ tristate "Double Byte GB encode (module only)" CONFIG_UNICON_GB
-+ if [ "$CONFIG_UNICON_GB" = "y" ]; then
-+ define_bool CONFIG_UNICON_GB m
-+ fi
-+ tristate "Double Byte SJIS encode (module only)" CONFIG_UNICON_SJIS
-+ if [ "$CONFIG_UNICON_SJIS" = "y" ]; then
-+ define_bool CONFIG_UNICON_SJIS m
-+ fi
-+ tristate "Double Byte EUCJP encode (module only)" CONFIG_UNICON_EUCJP
-+ if [ "$CONFIG_UNICON_EUCJP" = "y" ]; then
-+ define_bool CONFIG_UNICON_EUCJP m
-+ fi
-+ fi
- if [ "$CONFIG_PCI" = "y" ]; then
- tristate ' nVidia Riva support (EXPERIMENTAL)' CONFIG_FB_RIVA
- fi
-@@ -58,7 +73,9 @@
- dep_bool ' Cached FB support' CONFIG_POODLE_CONSISTENT_ALLOC $CONFIG_FB_POODLE
- fi
- dep_bool ' Corgi LCD support' CONFIG_FB_CORGI $CONFIG_ARCH_PXA_CORGI
-+ dep_bool ' Tosa LCD support' CONFIG_FB_TOSA $CONFIG_ARCH_PXA_TOSA
- dep_bool ' SHARP LOGO screen support' CONFIG_SHARP_LOGO_SCREEN $CONFIG_ARCH_SHARP_SL
-+ dep_bool ' Boot fastsysclk 100MHz. (EXPERIMENTAL)' CONFIG_SL_SYSCLK100 $CONFIG_ARCH_PXA_CORGI
- fi
- dep_tristate ' CyberPro 2000/2010/5000 support' CONFIG_FB_CYBER2000 $CONFIG_PCI
- if [ "$CONFIG_APOLLO" = "y" ]; then
-diff -Nur linux_c860_org/drivers/video/Makefile linux/drivers/video/Makefile
---- linux_c860_org/drivers/video/Makefile 2002-10-04 21:01:43.000000000 +0900
-+++ linux/drivers/video/Makefile 2004-06-10 21:09:10.000000000 +0900
-@@ -41,6 +41,10 @@
- obj-$(CONFIG_PPC) += macmodes.o
- endif
-
-+obj-$(CONFIG_UNICON_GB) += encode-gb.o
-+obj-$(CONFIG_UNICON_BIG5) += encode-big5.o
-+obj-$(CONFIG_UNICON_SJIS) += encode-sjis.o
-+obj-$(CONFIG_UNICON_EUCJP) += encode-eucjp.o
- obj-$(CONFIG_FB_ACORN) += acornfb.o
- obj-$(CONFIG_FB_AMIGA) += amifb.o
- obj-$(CONFIG_FB_PM2) += pm2fb.o fbgen.o
-@@ -91,7 +95,7 @@
- obj-$(CONFIG_FB_COTULLA) += cotulla_fb.o discovery_frontlight.o
- obj-$(CONFIG_FB_POODLE) += cotulla_fb.o poodle_frontlight.o
- obj-$(CONFIG_FB_CORGI) += w100fb.o fbgen.o corgi_backlight.o
--
-+obj-$(CONFIG_FB_TOSA) += tc6393fb.o fbgen.o tosa_backlight.o
-
- subdir-$(CONFIG_FB_MATROX) += matrox
- ifeq ($(CONFIG_FB_MATROX),y)
-diff -Nur linux_c860_org/drivers/video/encode-eucjp.c linux/drivers/video/encode-eucjp.c
---- linux_c860_org/drivers/video/encode-eucjp.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/video/encode-eucjp.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,67 @@
-+/*
-+ * linux/video/encode_eucjp.c
-+ *
-+ * Copyright (C) 2000 Kazuhide Takahashi
-+ * HOLON Inc.
-+ * Copyright (C) 1999 Christopher Li, Jim Chen
-+ * GNU/Linux Research Center
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file COPYING in the main directory of this archive
-+ * for more details.
-+ *
-+ *
-+ */
-+
-+
-+#include <linux/module.h>
-+#include <linux/fb_doublebyte.h>
-+#include "font_jis16.h"
-+#define min1 0xa1
-+#define max1 0xfe
-+
-+
-+int is_left(int c)
-+{
-+ return ( c >= min1 && c<=max1);
-+}
-+int is_right(int c)
-+{
-+ return ( c >= min1 && c<=max1);
-+}
-+int index_euc (int left, int right)
-+{
-+ if ( left == 0x8E )
-+ left = 0;
-+ else
-+ left &= 0x7F;
-+ right &= 0x7F;
-+
-+ if (left > 0x29)
-+ return ((right - 0x40 + (left - 0x25) * 96) << 5);
-+ else
-+ return ((right - 0x20 + (left - 0x20) * 96) << 5);
-+}
-+struct double_byte db_gb =
-+{
-+ 0,
-+ "EUCJP",
-+ is_left,
-+ is_right,
-+ index_euc,
-+ 16,16,
-+ max_jis16,
-+ font_jis16
-+};
-+
-+int init_module(void)
-+{
-+ if (doublebyte_default) return 1;
-+ doublebyte_default = &db_gb;
-+ return 0;
-+}
-+
-+void cleanup_module(void)
-+{
-+ doublebyte_default = (void*) 0;
-+}
-diff -Nur linux_c860_org/drivers/video/encode-gb.c linux/drivers/video/encode-gb.c
---- linux_c860_org/drivers/video/encode-gb.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/video/encode-gb.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,50 @@
-+/*
-+ * linux/video/encode_gb.c
-+ *
-+ * Copyright (C) 1999 Christopher Li, Jim Chen
-+ * GNU/Linux Research Center
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file COPYING in the main directory of this archive
-+ * for more details.
-+ *
-+ *
-+ */
-+
-+
-+#include <linux/module.h>
-+#include <linux/fb_doublebyte.h>
-+#include "font_gb16.h"
-+#define min1 0xa1
-+#define max1 0xfe
-+int index_gb(int left, int right)
-+{
-+ return ((left-min1)*94+right-min1) << 5;
-+}
-+int is_hz(int c)
-+{
-+ return ( c >= min1 && c<=max1);
-+}
-+struct double_byte db_gb =
-+{
-+ 0,
-+ "GB",
-+ is_hz,
-+ is_hz,
-+ index_gb,
-+ 16,16,
-+ max_gb16,
-+ font_gb16
-+};
-+
-+int init_module(void)
-+{
-+ if (doublebyte_default) return 1;
-+ doublebyte_default = &db_gb;
-+ return 0;
-+}
-+
-+void cleanup_module(void)
-+{
-+ doublebyte_default = (void*) 0;
-+}
-diff -Nur linux_c860_org/drivers/video/encode-sjis.c linux/drivers/video/encode-sjis.c
---- linux_c860_org/drivers/video/encode-sjis.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/video/encode-sjis.c 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,84 @@
-+/*
-+ * linux/video/encode_sjis.c
-+ *
-+ * Copyright (C) 2000 Kazuhide Takahashi
-+ * HOLON Inc.
-+ * Copyright (C) 1999 Christopher Li, Jim Chen
-+ * GNU/Linux Research Center
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file COPYING in the main directory of this archive
-+ * for more details.
-+ *
-+ *
-+ */
-+
-+
-+#include <linux/module.h>
-+#include <linux/fb_doublebyte.h>
-+#include "font_jis16.h"
-+#define min1 0x81
-+#define max1 0xfc
-+
-+
-+int is_left(int c)
-+{
-+ return ( (c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc) );
-+}
-+int is_right(int c)
-+{
-+ return ( (c >= 0x40 && c <= 0x7e) || (c >= 0x80 && c <= 0xfc) );
-+}
-+int index_sjis (int left, int right)
-+{
-+ int ch1, ch2;
-+
-+ if ( !is_left(left) || !is_right(right) ) return -512;
-+
-+ ch1 = left;
-+ ch2 = right;
-+
-+ if ( ch1 <= 0x9f )
-+ ch1 -= 0x71;
-+ else
-+ ch1 -= 0xb1;
-+ ch1 *= 2;
-+ ++ch1;
-+
-+ if ( ch2 >= 0x7f )
-+ --ch2;
-+ if ( ch2 >= 0x9e ) {
-+ ch2 -= 0x7d;
-+ ++ch1;
-+ } else {
-+ ch2 -= 0x1f;
-+ }
-+
-+ if (ch1 > 0x29)
-+ return ((ch2 - 0x40 + (ch1 - 0x25) * 96) << 5);
-+ else
-+ return ((ch2 - 0x20 + (ch1 - 0x20) * 96) << 5);
-+}
-+struct double_byte db_gb =
-+{
-+ 0,
-+ "SJIS",
-+ is_left,
-+ is_right,
-+ index_sjis,
-+ 16,16,
-+ max_jis16,
-+ font_jis16
-+};
-+
-+int init_module(void)
-+{
-+ if (doublebyte_default) return 1;
-+ doublebyte_default = &db_gb;
-+ return 0;
-+}
-+
-+void cleanup_module(void)
-+{
-+ doublebyte_default = (void*) 0;
-+}
-diff -Nur linux_c860_org/drivers/video/fbcon-cfb16.c linux/drivers/video/fbcon-cfb16.c
---- linux_c860_org/drivers/video/fbcon-cfb16.c 2003-01-14 14:43:43.000000000 +0900
-+++ linux/drivers/video/fbcon-cfb16.c 2004-06-10 21:09:10.000000000 +0900
-@@ -13,6 +13,7 @@
- * 30-Jul-2002 Lineo Japan, Inc. for 2.4.18
- * 31-Oct-2002 SHARP
- * added support for rotation logo screen on SHARP SL-C700
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- #include <linux/module.h>
-@@ -217,9 +218,11 @@
-
- width *= fontwidth(p)/4;
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+#if 0 /* c700 bug fix 0 */
- if (width * 8 == bytes)
- rectfill(dest, 1, lines * width * 4, bgx, bytes);
- else
-+#endif
- rectfill(dest, lines, width * 4, bgx, bytes);
- #else
- if (width * 8 == bytes)
-@@ -240,10 +243,17 @@
- u8 *dest, *cdat, bits;
- int bytes = p->next_line, rows;
- u32 eorx, fgx, bgx;
-+#ifdef CONFIG_UNICON
-+ u8 *temp;
-+#endif
-
- #if defined(CONFIG_FBCON_ROTATE_R)
- dest = p->screen_base +
-+#ifdef CONFIG_UNICON
-+ yy * fontwidth(p) * bytes + (p->var.xres - (xx+1) * fontheight(p) - 1) * 2;
-+#else
- yy * fontwidth(p) * bytes + (p->var.xres - xx * fontheight(p) - 1) * 2;
-+#endif
- #elif defined(CONFIG_FBCON_ROTATE_L)
- dest = p->screen_base +
- (p->var.yres - yy * fontwidth(p) - 1) * bytes + xx * fontheight(p) * 2;
-@@ -262,6 +272,32 @@
- case 8:
- cdat = p->fontdata + (c & p->charmask) * fontheight(p);
- #if defined(CONFIG_FBCON_ROTATE_R)
-+#ifdef CONFIG_UNICON
-+ rows = fontheight(p);
-+ temp = dest+rows*2;
-+ for (; rows--; dest += 2,temp -= 2) {
-+ bits = *cdat++;
-+ fb_writew((tab_cfb16[bits >> 7 & 1] & eorx) ^ bgx,
-+ temp);
-+ fb_writew((tab_cfb16[bits >> 6 & 1] & eorx) ^ bgx,
-+ temp+1*bytes);
-+ fb_writew((tab_cfb16[bits >> 5 & 1] & eorx) ^ bgx,
-+ temp+2*bytes);
-+ fb_writew((tab_cfb16[bits >> 4 & 1] & eorx) ^ bgx,
-+ temp+3*bytes);
-+ if (fontwidth(p) == 8) {
-+ fb_writew((tab_cfb16[bits >> 3 & 1] & eorx) ^ bgx,
-+ temp+4*bytes);
-+ fb_writew((tab_cfb16[bits >> 2 & 1] & eorx) ^ bgx,
-+ temp+5*bytes);
-+ fb_writew((tab_cfb16[bits >> 1 & 1] & eorx) ^ bgx,
-+ temp+6*bytes);
-+ fb_writew((tab_cfb16[bits & 1] & eorx) ^ bgx,
-+ temp+7*bytes);
-+ }
-+ }
-+ dest = temp;
-+#else
- for (rows = fontheight(p); rows--; dest += 2) {
- bits = *cdat++;
- fb_writew((tab_cfb16[bits >> 7 & 1] & eorx) ^ bgx,
-@@ -283,6 +319,7 @@
- dest+7*bytes);
- }
- }
-+#endif
- #elif defined(CONFIG_FBCON_ROTATE_L)
- for (rows = fontheight(p); rows--; dest += 2) {
- bits = *cdat++;
-@@ -734,6 +771,15 @@
- rectfill(p->screen_base +
- (p->var.xres - (p->var.xoffset + bottom_start) - 1) * 2,
- right_start, bottom_width, bgx, bytes);
-+#else
-+#ifdef CONFIG_FB_TOSA /* re_check */
-+ if (!bottom_only && (right_width = p->var.yres - right_start))
-+ rectfill(p->screen_base + right_start * bytes + (p->var.xres - 1) * 2,
-+ right_width, p->var.xres_virtual, bgx, bytes);
-+ if ((bottom_width = p->var.xres - bottom_start))
-+ rectfill(p->screen_base +
-+ (p->var.xres - (p->var.xoffset + bottom_start) - 1) * 2,
-+ right_start, bottom_width, bgx, bytes);
- #else // general R
- if (!bottom_only && (right_width = p->var.yres - right_start))
- rectfill(p->screen_base + right_start * bytes + (p->var.xres - 1) * 2,
-@@ -743,6 +789,7 @@
- (p->var.xres - (p->var.xoffset + bottom_start) - 1) * 2,
- right_start, bottom_width, bgx, bytes);
- #endif
-+#endif
- #elif defined(CONFIG_FBCON_ROTATE_L)
- #ifdef CONFIG_FB_CORGI
- if (!bottom_only && (right_width = p->var.yres - right_start))
-@@ -752,6 +799,15 @@
- rectfill(p->screen_base + (p->var.yres - 1) * bytes +
- (p->var.xoffset + bottom_start) * 2,
- right_start, bottom_width, bgx, bytes);
-+#else
-+#ifdef CONFIG_FB_TOSA /* re_check */
-+ if (!bottom_only && (right_width = p->var.yres - right_start))
-+ rectfill(p->screen_base + (p->var.yres - right_start - 1) * bytes,
-+ right_width, p->var.xres_virtual, bgx, bytes);
-+ if ((bottom_width = p->var.xres - bottom_start))
-+ rectfill(p->screen_base + (p->var.yres - 1) * bytes +
-+ (p->var.xoffset + bottom_start) * 2,
-+ right_start, bottom_width, bgx, bytes);
- #else // general L
- if (!bottom_only && (right_width = p->var.yres - right_start))
- rectfill(p->screen_base + (p->var.yres - right_start - 1) * bytes,
-@@ -761,6 +817,7 @@
- (p->var.xoffset + bottom_start) * 2,
- right_start, bottom_width, bgx, bytes);
- #endif
-+#endif
- #else
- if (!bottom_only && (right_width = p->var.xres-right_start))
- rectfill(p->screen_base+right_start*2, right_width,
-diff -Nur linux_c860_org/drivers/video/fbcon.c linux/drivers/video/fbcon.c
---- linux_c860_org/drivers/video/fbcon.c 2003-01-14 14:44:30.000000000 +0900
-+++ linux/drivers/video/fbcon.c 2004-06-10 21:09:10.000000000 +0900
-@@ -66,6 +66,7 @@
- * added support for rotation logo screen on SHARP SL-C700
- * 08-Nov-2002 SHARP
- * SHARP logo screen modification
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- #undef FBCONDEBUG
-@@ -78,6 +79,11 @@
- #include <linux/kernel.h>
- #include <linux/delay.h> /* MSch: for IRQ probe */
- #include <linux/tty.h>
-+
-+#ifdef CONFIG_UNICON
-+#include <linux/fb_doublebyte.h>
-+#endif
-+
- #include <linux/console.h>
- #include <linux/string.h>
- #include <linux/kd.h>
-@@ -668,7 +674,12 @@
- if (con == fg_console && p->type != FB_TYPE_TEXT) {
- if (fbcon_softback_size) {
- if (!softback_buf) {
-+#ifndef CONFIG_UNICON
- softback_buf = (unsigned long)kmalloc(fbcon_softback_size, GFP_KERNEL);
-+#else
-+ softback_buf = (unsigned long)kmalloc(fbcon_softback_size*2, GFP_KERNEL);
-+#endif
-+
- if (!softback_buf) {
- fbcon_softback_size = 0;
- softback_top = 0;
-@@ -816,11 +827,18 @@
- (p->var.yres_virtual % fontwidth(p) < p->var.yres % fontwidth(p)))
- p->vrows--;
- #else
-+#ifdef CONFIG_FB_TOSA /* re_check */
-+ p->vrows = p->var.yres_virtual / fontwidth(p);
-+ if ((p->var.yres % fontwidth(p)) &&
-+ (p->var.yres_virtual % fontwidth(p) < p->var.yres % fontwidth(p)))
-+ p->vrows--;
-+#else
- p->vrows = p->var.xres_virtual / fontheight(p);
- if ((p->var.xres % fontheight(p)) &&
- (p->var.xres_virtual % fontheight(p) < p->var.xres % fontheight(p)))
- p->vrows--;
- #endif
-+#endif
- #else
- p->vrows = p->var.yres_virtual/fontheight(p);
- if ((p->var.yres % fontheight(p)) &&
-@@ -916,6 +934,27 @@
- * restriction is simplicity & efficiency at the moment.
- */
-
-+#ifdef CONFIG_UNICON
-+static inline unsigned short * hibyte_pos(struct vc_data * conp,unsigned short* p)
-+{
-+ unsigned long pos=(long)p;
-+
-+ if (pos >= conp->vc_origin && pos < conp->vc_scr_end) {
-+ /* pos in the vc buffer - Chrisl 99.11.12*/
-+ return (unsigned short*)(pos+conp->vc_screenbuf_size);
-+ } else if (conp->vc_num == fg_console){
-+ /*&& softback_lines,because the scroll will first change
-+ softback_lines, then call this function, so it is ignored here
-+ -JimChen 99.11.12*/
-+ return (unsigned short*)(pos+fbcon_softback_size);
-+ } else {
-+ /* Should not happen */
-+ printk("Warnning, changing not active console\n");
-+ return p;
-+ }
-+}
-+#endif
-+
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
- static __inline__ int real_x(struct display *p, int xpos)
- {
-@@ -993,6 +1032,60 @@
- vbl_cursor_cnt = CURSOR_DRAW_DELAY;
- }
-
-+#ifdef CONFIG_UNICON
-+struct double_byte * doublebyte_default = NULL;
-+EXPORT_SYMBOL(doublebyte_default);
-+/* ypos is absolute y(relative to video buffer), not y in screen coordinate,
-+ and the validation is assured by the caller */
-+#if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+void fbcon_putc_tl(struct vc_data *conp, int c, int xpos, int ypos)
-+#else
-+void fbcon_putc_tl(struct vc_data *conp, int c, int ypos, int xpos)
-+#endif
-+{
-+ int unit = conp->vc_num;
-+ struct display *p = &fb_display[unit];
-+ int extendedchar;
-+ u_char * fontdata_save;
-+
-+ if (!doublebyte_default){
-+#if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+ p->dispsw->putc(conp, p, c&0xffff, xpos, ypos);
-+#else
-+ p->dispsw->putc(conp, p, c&0xffff, ypos, xpos);
-+#endif
-+ return;
-+ }
-+ extendedchar = c & (DB_VALIDATE<<16);
-+ fontdata_save = p -> fontdata;
-+ if (extendedchar) {
-+ int index;
-+ if ( c & (DB_RIGHT_MASK << 16)) {// right half
-+ index = doublebyte_default->font_index((c>>16)&0xff, (c&0xff)) + 16;
-+ } else {
-+ index = doublebyte_default->font_index((c&0xff),(c>>16)&0xff);
-+ }
-+ //printk("<6>%d %x",(unsigned long)p->fontdata-(unsigned long) font_gb16,c);
-+ if (index >=0 && index < doublebyte_default->charcount) {
-+ p->fontdata = doublebyte_default->font_data +index;
-+ c = (c & 0xff00);
-+ }else c = c & 0xffff;
-+ } else {
-+ c = c & 0xffff;
-+ }
-+
-+#if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+ p->dispsw->putc(conp, p, c, xpos, ypos);
-+#else
-+ p->dispsw->putc(conp, p, c, ypos, xpos);
-+#endif
-+
-+ if (extendedchar) {
-+ p->fontdata = fontdata_save;
-+ }
-+}
-+EXPORT_SYMBOL(fbcon_putc_tl);
-+#endif
-
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
- static void fbcon_putc(struct vc_data *conp, int c, int xpos, int ypos)
-@@ -1019,16 +1112,39 @@
- redraw_cursor = 1;
- }
-
-+#ifdef CONFIG_UNICON
-+#if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+ fbcon_putc_tl(conp, c, real_x(p, xpos), ypos);
-+#else
-+ fbcon_putc_tl(conp, c, real_y(p, ypos), xpos);
-+#endif
-+#else
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
- p->dispsw->putc(conp, p, c, real_x(p, xpos), ypos);
- #else
- p->dispsw->putc(conp, p, c, real_y(p, ypos), xpos);
- #endif
-+#endif
-
- if (redraw_cursor)
- vbl_cursor_cnt = CURSOR_DRAW_DELAY;
- }
-
-+#ifdef CONFIG_UNICON
-+//ypos is absolute pos.
-+static void fbcon_putcs_tl(struct vc_data *conp, const unsigned short *s, int count,
-+ int ypos, int xpos)
-+{
-+ const unsigned short *str=s;
-+
-+ while (count--) {
-+ fbcon_putc_tl(conp, (scr_readw(hibyte_pos(conp,(unsigned short *)str))<<16)|scr_readw(str),
-+ ypos, xpos);
-+ str++;
-+ xpos++;
-+ }
-+}
-+#endif
-
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
- static void fbcon_putcs(struct vc_data *conp, const unsigned short *s, int count, int xpos, int ypos)
-@@ -1057,11 +1173,19 @@
- cursor_undrawn();
- redraw_cursor = 1;
- }
-+#ifndef CONFIG_UNICON
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
- p->dispsw->putcs(conp, p, s, count, real_x(p, xpos), ypos);
- #else
- p->dispsw->putcs(conp, p, s, count, real_y(p, ypos), xpos);
- #endif
-+#else
-+#if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+ fbcon_putcs_tl(conp,s,count,real_x(p,xpos),ypos);
-+#else
-+ fbcon_putcs_tl(conp,s,count,real_y(p,ypos),xpos);
-+#endif
-+#endif
- if (redraw_cursor)
- vbl_cursor_cnt = CURSOR_DRAW_DELAY;
- }
-@@ -1362,6 +1486,9 @@
- unsigned short *start;
- unsigned short *le;
- unsigned short c;
-+#ifdef CONFIG_UNICON
-+ unsigned short c_ext;
-+#endif
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
- int y = 0;
- #else
-@@ -1373,30 +1500,53 @@
- le = advance_row(s, 1);
- do {
- c = scr_readw(s);
-+#ifdef CONFIG_UNICON
-+ c_ext = scr_readw(hibyte_pos(conp,s));
-+#endif
- if (attr != (c & 0xff00)) {
- attr = c & 0xff00;
- if (s > start) {
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+#ifndef CONFIG_UNICON
- p->dispsw->putcs(conp, p, start, s - start,
- real_x(p, line), y);
-+#else
-+ fbcon_putcs_tl(conp,start,s-start,real_x(p,line),y);
-+#endif
- y += s - start;
- #else
-- p->dispsw->putcs(conp, p, start, s - start,
-- real_y(p, line), x);
-+#ifndef CONFIG_UNICON
-+ p->dispsw->putcs(conp, p, start, s - start,
-+ real_y(p, line), x);
-+#else
-+ fbcon_putcs_tl(conp,start,s-start,real_y(p,line),x);
-+#endif
- x += s - start;
- #endif
- start = s;
- }
- }
-+#ifndef CONFIG_UNICON
- if (c == scr_readw(d)) {
-+#else
-+ if (c == scr_readw(d) && c_ext == scr_readw(hibyte_pos(conp,d))) {
-+#endif
- if (s > start) {
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+#ifndef CONFIG_UNICON
- p->dispsw->putcs(conp, p, start, s - start,
- real_x(p, line), y);
-+#else
-+ fbcon_putcs_tl(conp,start,s-start,real_x(p,line),y);
-+#endif
- y += s - start + 1;
- #else
-- p->dispsw->putcs(conp, p, start, s - start,
-- real_y(p, line), x);
-+#ifndef CONFIG_UNICON
-+ p->dispsw->putcs(conp, p, start, s - start,
-+ real_y(p, line), x);
-+#else
-+ fbcon_putcs_tl(conp,start,s-start,real_y(p,line),x);
-+#endif
- x += s - start + 1;
- #endif
- start = s + 1;
-@@ -1414,9 +1564,17 @@
- } while (s < le);
- if (s > start)
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+#ifndef CONFIG_UNICON
- p->dispsw->putcs(conp, p, start, s - start, real_x(p, line), y);
- #else
-+ fbcon_putcs_tl(conp,start,s-start,real_x(p,line),y);
-+#endif
-+#else
-+#ifndef CONFIG_UNICON
- p->dispsw->putcs(conp, p, start, s - start, real_y(p, line), x);
-+#else
-+ fbcon_putcs_tl(conp,start,s-start,real_y(p,line),x);
-+#endif
- #endif
- line++;
- if (d == (u16 *)softback_end)
-@@ -1441,6 +1599,9 @@
- unsigned short *start = s;
- unsigned short *le = advance_row(s, 1);
- unsigned short c;
-+#ifdef CONFIG_UNICON
-+ unsigned short c_ext;
-+#endif
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
- int y = 0;
- #else
-@@ -1450,30 +1611,53 @@
-
- do {
- c = scr_readw(s);
-+#ifdef CONFIG_UNICON
-+ c_ext = scr_readw(hibyte_pos(conp,s));
-+#endif
- if (attr != (c & 0xff00)) {
- attr = c & 0xff00;
- if (s > start) {
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+#ifndef CONFIG_UNICON
- p->dispsw->putcs(conp, p, start, s - start,
- real_x(p, line), y);
-+#else
-+ fbcon_putcs_tl(conp,start,s-start,real_x(p,line),y);
-+#endif
- y += s - start;
- #else
-+#ifndef CONFIG_UNICON
- p->dispsw->putcs(conp, p, start, s - start,
- real_y(p, line), x);
-+#else
-+ fbcon_putcs_tl(conp,start,s-start,real_y(p,line),x);
-+#endif
- x += s - start;
- #endif
- start = s;
- }
- }
-+#ifndef CONFIG_UNICON
- if (c == scr_readw(d)) {
-+#else
-+ if (c == scr_readw(d) && c_ext == scr_readw(hibyte_pos(conp,d))) {
-+#endif
- if (s > start) {
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+#ifndef CONFIG_UNICON
- p->dispsw->putcs(conp, p, start, s - start,
- real_x(p, line), y);
-+#else
-+ fbcon_putcs_tl(conp,start,s-start,real_x(p,line),y);
-+#endif
- y += s - start + 1;
- #else
-+#ifndef CONFIG_UNICON
- p->dispsw->putcs(conp, p, start, s - start,
- real_y(p, line), x);
-+#else
-+ fbcon_putcs_tl(conp,start,s-start,real_y(p,line),x);
-+#endif
- x += s - start + 1;
- #endif
- start = s + 1;
-@@ -1487,17 +1671,28 @@
- }
- }
- scr_writew(c, d);
-+#ifdef CONFIG_UNICON
-+ scr_writew(scr_readw(s+(conp->vc_screenbuf_size>>1)),d+(conp->vc_screenbuf_size>>1));
-+#endif
- console_conditional_schedule();
- s++;
- d++;
- } while (s < le);
- if (s > start)
-+#ifndef CONFIG_UNICON
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
- p->dispsw->putcs(conp, p, start, s - start, real_x(p, line), y);
- #else
- p->dispsw->putcs(conp, p, start, s - start, real_y(p, line), x);
- #endif
- console_conditional_schedule();
-+#else
-+#if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+ fbcon_putcs_tl(conp,start,s-start,real_x(p,line),y);
-+#else
-+ fbcon_putcs_tl(conp,start,s-start,real_y(p,line),x);
-+#endif
-+#endif
- if (offset > 0)
- line++;
- else {
-@@ -1603,10 +1798,18 @@
- attr = c & 0xff00;
- if (d > start) {
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+#ifndef CONFIG_UNICON
- p->dispsw->putcs(conp, p, start, d - start, dx, y);
-+#else
-+ fbcon_putcs_tl(conp,start,d-start,dx,y);
-+#endif
- y += d - start;
- #else
-- p->dispsw->putcs(conp, p, start, d - start, dy, x);
-+#ifndef CONFIG_UNICON
-+ p->dispsw->putcs(conp, p, start, d - start, dy, x);
-+#else
-+ fbcon_putcs_tl(conp,start,d-start,dy,x);
-+#endif
- x += d - start;
- #endif
- start = d;
-@@ -1615,10 +1818,18 @@
- if (s >= ls && s < le && c == scr_readw(s)) {
- if (d > start) {
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+#ifndef CONFIG_UNICON
- p->dispsw->putcs(conp, p, start, d - start, dx, y);
-+#else
-+ fbcon_putcs_tl(conp,start,d-start,dx,y);
-+#endif
- y += d - start + 1;
- #else
-+#ifndef CONFIG_UNICON
- p->dispsw->putcs(conp, p, start, d - start, dy, x);
-+#else
-+ fbcon_putcs_tl(conp,start,d-start,dy,x);
-+#endif
- x += d - start + 1;
- #endif
- start = d + 1;
-@@ -1636,9 +1847,17 @@
- } while (d < le);
- if (d > start)
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+#ifndef CONFIG_UNICON
- p->dispsw->putcs(conp, p, start, d - start, dx, y);
- #else
-+ fbcon_putcs_tl(conp,start,d-start,dx,y);
-+#endif
-+#else
-+#ifndef CONFIG_UNICON
- p->dispsw->putcs(conp, p, start, d - start, dy, x);
-+#else
-+ fbcon_putcs_tl(conp,start,d-start,dy,x);
-+#endif
- #endif
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
- sx++;
-@@ -1660,6 +1879,9 @@
-
- while (count) {
- scr_memcpyw((u16 *)softback_in, p, conp->vc_size_row);
-+#ifdef CONFIG_UNICON
-+ scr_memcpyw((u16 *)softback_in+(fbcon_softback_size>>1),p+(conp->vc_screenbuf_size>>1),conp->vc_size_row);
-+#endif
- count--;
- p = advance_row(p, 1);
- softback_in += conp->vc_size_row;
-@@ -1764,6 +1986,13 @@
- conp->vc_size_row * (b-count)),
- conp->vc_video_erase_char,
- conp->vc_size_row * count);
-+#ifdef CONFIG_UNICON
-+ scr_memsetw((unsigned short *)(conp->vc_origin +
-+ conp->vc_size_row * (b-count) +
-+ conp->vc_screenbuf_size),
-+ conp->vc_video_erase_char & 0xff,
-+ conp->vc_size_row * count);
-+#endif
- return 1;
- }
- #else
-@@ -1879,6 +2108,13 @@
- conp->vc_size_row * t),
- conp->vc_video_erase_char,
- conp->vc_size_row * count);
-+#ifdef CONFIG_UNICON
-+ scr_memsetw((unsigned short *)(conp->vc_origin +
-+ conp->vc_size_row * t +
-+ conp->vc_screenbuf_size),
-+ conp->vc_video_erase_char & 0xff,
-+ conp->vc_size_row * count);
-+#endif
- return 1;
- }
- #else
-@@ -2566,11 +2802,31 @@
- return p->fb_info->fbops->fb_set_cmap(&palette_cmap, 1, unit, p->fb_info);
- }
-
-+#ifdef CONFIG_UNICON
-+/*offset:relative to softback_curr if softback valid in this vc
-+The return pos may exists in buffer pointed by conp->vc_origin or softback_top.
-+I assume the offset is always >=0 in normal case and I use the -offset-1 to mean to get the pos of the second word
-+*/
-+#endif
-+
- static u16 *fbcon_screen_pos(struct vc_data *conp, int offset)
- {
- int line;
- unsigned long p;
--
-+#ifdef CONFIG_UNICON
-+ if (offset < 0) {
-+ offset = -offset - 1;
-+ if (conp->vc_num != fg_console || !softback_lines)
-+ return (u16 *)(conp->vc_origin + offset + conp->vc_screenbuf_size);
-+ line = offset / conp->vc_size_row;
-+ if (line >= softback_lines)
-+ return (u16 *)(conp->vc_origin + offset - softback_lines * conp->vc_size_row + conp->vc_screenbuf_size);
-+ p = softback_curr + offset;
-+ if (p >= softback_end)
-+ p += softback_buf - softback_end;
-+ return (u16 *)(p+fbcon_softback_size);
-+ }
-+#endif
- if (conp->vc_num != fg_console || !softback_lines)
- return (u16 *)(conp->vc_origin + offset);
- line = offset / conp->vc_size_row;
-@@ -2582,6 +2838,10 @@
- return (u16 *)p;
- }
-
-+#ifdef CONFIG_UNICON
-+// pos is a pointer either pointing into softback or (vc_origin--vc_scr_end),
-+// return the pointer to the start of next row ( no matter in vi_origin or softback!)
-+#endif
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
- static unsigned long fbcon_getxy(struct vc_data *conp, unsigned long pos, int *py, int *px)
- #else
-@@ -2684,6 +2944,11 @@
- p -= conp->vc_size_row;
- q -= conp->vc_size_row;
- scr_memcpyw((u16 *)q, (u16 *)p, conp->vc_size_row);
-+#ifdef CONFIG_UNICON
-+ scr_memcpyw((u16* )(q+conp->vc_screenbuf_size),
-+ (u16* )(p+fbcon_softback_size),
-+ conp->vc_size_row);
-+#endif
- }
- softback_in = p;
- update_region(unit, conp->vc_origin, logo_lines * conp->vc_cols);
-diff -Nur linux_c860_org/drivers/video/fbmem.c linux/drivers/video/fbmem.c
---- linux_c860_org/drivers/video/fbmem.c 2003-01-14 14:48:09.000000000 +0900
-+++ linux/drivers/video/fbmem.c 2004-06-10 21:09:10.000000000 +0900
-@@ -16,6 +16,8 @@
- * - Added support for ATI w100 on SHARP SL-C700
- * 11-Sep-2002 SHARP
- * - Allocated frame buffer to cache memory on SHARP SL-B500/5600
-+ * 24-Jul-2003 Lineo Solutions, Inc.
-+ * - Added support for TOSHIBA TC6393XB on SHARP SL-6
- */
-
- #include <linux/config.h>
-@@ -145,6 +147,8 @@
- extern int cotulla_fb_init(void);
- extern int w100fb_init(void);
- extern int w100fb_setup(char*);
-+extern int tc6393fb_init(void);
-+extern int tc6393fb_setup(char*);
-
- static struct {
- const char *name;
-@@ -322,6 +326,9 @@
- #ifdef CONFIG_FB_CORGI
- { "w100fb", w100fb_init, w100fb_setup },
- #endif
-+#ifdef CONFIG_FB_TOSA
-+ { "tc6393fb", tc6393fb_init, NULL },
-+#endif
-
- /*
- * Generic drivers that don't use resource management (yet)
-diff -Nur linux_c860_org/drivers/video/font_gb16.h linux/drivers/video/font_gb16.h
---- linux_c860_org/drivers/video/font_gb16.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/video/font_gb16.h 2004-06-10 21:09:10.000000000 +0900
-@@ -0,0 +1,8180 @@
-+#define max_gb16 261696
-+unsigned char font_gb16[max_gb16] = {
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60,0x30,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x50,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x8,0x8,0x4,0x4,0x2,0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x20,0x40,0x40,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0xc,0xc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x2,0x2,0x4,0x4,0x9,0x9,0x12,0x24,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x40,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x4,0x4,0x4,0x8,0x8,0x1f,0x20,0x40,0x0,0x8,0x4,0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf8,0x8,0x10,0x10,0x20,0x40,0x80,0x0,0xc0,0x40,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3f,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x63,0x63,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x4,0x8,0xc,0xc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x60,0x60,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x44,0x88,0x10,0x98,0x98,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x0,0x1,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x98,0x98,0x88,0x10,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x8,0x4,0x0,
-+0x0,0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x0,0x0,
-+0x0,0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x1,0x2,0x4,0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x12,0x24,0x48,0x90,0x20,0x40,0x80,0x40,0x20,0x90,0x48,0x24,0x12,0x8,0x4,
-+0x20,0x90,0x48,0x24,0x12,0x9,0x4,0x2,0x4,0x9,0x12,0x24,0x48,0x90,0x20,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x7,0x4,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x5,0x7,0x0,0x0,0x0,0xc0,0x40,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x7,0x4,0x7,0x0,0x0,0x0,0xc0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xc0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe,0x84,0x88,0x88,0x90,0x90,0x90,0x90,0x90,0x90,0x88,0x88,0x84,0xfe,0x0,
-+0x0,0xfe,0x42,0x22,0x22,0x12,0x12,0x12,0x12,0x12,0x12,0x22,0x22,0x42,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe,0xfc,0xf8,0xf0,0xf0,0xe0,0xe0,0xe0,0xe0,0xf0,0xf0,0xf8,0xfc,0xfe,0x0,
-+0x0,0xfe,0x7e,0x3e,0x1e,0x1e,0xe,0xe,0xe,0xe,0x1e,0x1e,0x3e,0x7e,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1,0x1,0x1,0xf,0x1,0x1,0x1,0x0,0xf,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x0,0x0,0x0,0x0,0xe0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x10,0x8,0x4,0x2,0x1,0x2,0x4,0x8,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x20,0x40,0x80,0x0,0x80,0x40,0x20,0x10,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x1f,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x3,0x3,0x0,0x0,0x0,0x3,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x2,0x2,0x4,0x4,0x8,0x8,0x10,0x10,0x20,0x20,0x20,0x40,0x40,0x0,0x0,0x0,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x8,0x8,0x8,0x4,0x4,0x0,
-+0x0,0x40,0x40,0x20,0x20,0x20,0x10,0x10,0x8,0x8,0x4,0x4,0x2,0x2,0x1,0x0,0x0,0x4,0x4,0x8,0x8,0x8,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x0,0x0,
-+0x0,0x7f,0x20,0x10,0x8,0x4,0x2,0x1,0x2,0x4,0x8,0x10,0x20,0x7f,0x0,0x0,0x0,0xfc,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x4,0xfc,0x0,0x0,
-+0x0,0x3f,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x78,0x0,0x0,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x3c,0x0,
-+0x0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x8,0x7,0x0,0x0,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x10,0x20,0xc0,0x0,
-+0x0,0x7,0x8,0x10,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0,0x0,0xc0,0x20,0x10,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x0,
-+0x0,0x7,0x18,0x20,0x20,0x40,0x40,0x7f,0x40,0x40,0x40,0x20,0x20,0x18,0x7,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,
-+0x0,0x0,0x0,0x18,0x18,0x0,0x0,0x0,0x0,0x0,0x18,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x30,0x0,0x0,0x0,0x0,0x0,0x30,0x30,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x41,0xa2,0x14,0x8,0x0,0x0,0x0,0x0,0x0,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,
-+0x2,0x2,0x2,0x2,0x2,0x2,0x4,0x4,0x4,0x4,0x4,0x9,0x9,0x9,0x9,0x9,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x2,0x4,0x8,0x10,0x20,0x7f,0x0,0x0,0x0,0x4,0x8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0xfc,0x0,0x0,
-+0x0,0x0,0x0,0x7,0x18,0x20,0x20,0x40,0x40,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x60,0x10,0x10,0x8,0x8,0x8,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x7,0x18,0x20,0x20,0x40,0x43,0x43,0x40,0x20,0x20,0x18,0x7,0x0,0x0,0x0,0x0,0x80,0x60,0x10,0x10,0x8,0x8,0x8,0x8,0x10,0x10,0x60,0x80,0x0,0x0,
-+0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x6,0x0,0x0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1,0x1,0x7,0x9,0x9,0xa,0xa,0x7,0x2,0x2,0x4,0x24,0x18,0x60,0x90,0x80,0x0,0x0,0x80,0x40,0x40,0x40,0x40,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x7f,0x0,0x7f,0x0,0x7f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc,0x0,0xfc,0x0,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x18,0x20,0x41,0x41,0x42,0x22,0x1c,0x0,0x7f,0x0,0x7f,0x0,0x0,0x0,0x0,0x0,0x70,0x88,0x4,0x4,0x4,0x8,0x30,0x0,0xfc,0x0,0xfc,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x38,0x47,0x0,0x38,0x47,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x8,0xf0,0x4,0x8,0xf0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x38,0x40,0x41,0x81,0x81,0x41,0x42,0x3c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x78,0x84,0x2,0x2,0x2,0x2,0x4,0x38,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x3c,0x42,0x41,0x81,0x81,0x41,0x42,0x3c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7e,0x80,0x0,0x0,0x0,0x0,0x80,0x7e,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x7f,0x0,0x1,0x2,0x7f,0x4,0x4,0x8,0x10,0x10,0x20,0x10,0x20,0x20,0x40,0x40,0xfc,0x80,0x0,0x0,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x4,0x4,0x5,0x6,0x1c,0x64,0x84,0x64,0x1c,0x6,0x5,0x4,0x4,0x0,0x0,0x0,0x18,0x60,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x60,0x18,0x0,0x0,
-+0x0,0x30,0xc,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0xc,0x30,0x0,0x0,0x0,0x40,0x40,0x40,0xc0,0x70,0x4c,0x42,0x4c,0x70,0xc0,0x40,0x40,0x40,0x0,0x0,
-+0x0,0x0,0x1,0x6,0x18,0x60,0x80,0x60,0x98,0x66,0x19,0x6,0x1,0x0,0x0,0x0,0x18,0x60,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x60,0x98,0x60,0x18,0x0,
-+0x30,0xc,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0xc,0x33,0xc,0x30,0x0,0x0,0x0,0x0,0xc0,0x30,0xc,0x2,0xc,0x32,0xcc,0x30,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x3c,0x42,0x81,0x81,0x81,0x42,0x3c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x78,0x84,0x2,0x2,0x2,0x84,0x78,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x30,0x30,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0x3,0x0,0x0,0x0,0x0,0x0,0x30,0x30,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x3,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x30,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x30,0x0,0x0,0x0,
-+0x0,0x1,0x3,0x5,0x9,0x11,0x1,0x1,0x1,0x1,0x3,0x4,0x4,0x4,0x3,0x0,0x0,0x0,0x80,0x40,0x20,0x10,0x0,0x0,0x0,0x0,0x80,0x40,0x40,0x40,0x80,0x0,
-+0x0,0x3,0x4,0x4,0x4,0x3,0x1,0x1,0x3f,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x80,0x40,0x40,0x40,0x80,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x30,0x48,0x48,0x30,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x1,0x2,0x2,0x2,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x2,0x2,0x2,0x4,0x4,0x4,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x20,0x20,0x40,0x40,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x20,0x53,0x24,0x8,0x8,0x10,0x10,0x10,0x10,0x10,0x10,0x8,0x8,0x4,0x3,0x0,0x0,0xf4,0xc,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x4,0x8,0xf0,0x0,
-+0x1,0xf,0x11,0x21,0x21,0x21,0x11,0xf,0x1,0x1,0x1,0x21,0x21,0x31,0x2f,0x1,0x0,0xe8,0x18,0x8,0x8,0x0,0x0,0x0,0xe0,0x10,0x8,0x8,0x8,0x10,0xe0,0x0,
-+0x0,0x40,0x27,0x18,0x10,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x18,0x27,0x40,0x0,0x0,0x2,0xe4,0x18,0x8,0x4,0x4,0x4,0x4,0x4,0x4,0x8,0x18,0xe4,0x2,0x0,
-+0x0,0x0,0xf,0x10,0x20,0x40,0x40,0x41,0x41,0x42,0x42,0x24,0x14,0xf,0x10,0x20,0x10,0x20,0xe8,0x58,0x48,0x80,0x80,0x0,0x0,0x0,0x0,0x8,0x10,0xe0,0x0,0x0,
-+0x1,0x2,0x2,0x2,0x2,0x2,0x3f,0x2,0x2,0x2,0x3a,0x46,0x42,0x45,0x38,0x0,0xc0,0x20,0x20,0x0,0x0,0x0,0xe0,0x0,0x0,0x0,0x0,0x0,0x4,0x4,0xf8,0x0,
-+0x0,0x30,0x48,0x48,0x48,0x49,0x32,0x4,0x8,0x11,0x22,0x42,0x82,0x2,0x1,0x0,0x8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x8c,0x52,0x52,0x52,0x52,0x8c,0x0,
-+0x7,0x8,0x8,0x4,0x2,0x3,0x4,0x8,0x8,0x5,0x2,0x1,0x4,0x8,0x8,0x7,0x80,0x40,0xc0,0x0,0x0,0x0,0x80,0x40,0x40,0x80,0x0,0x0,0x80,0x40,0x40,0x80,
-+0x60,0x21,0x31,0x31,0x29,0x29,0x29,0x29,0x25,0x25,0x25,0x25,0x23,0x23,0xa1,0x41,0x80,0x40,0x0,0x0,0x18,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x18,0x0,0x7e,0x0,
-+0x1,0x1,0x2,0x2,0x2,0x4,0xfc,0x40,0x30,0x8,0x8,0x11,0x16,0x18,0x20,0x0,0x0,0x0,0x80,0x80,0x80,0x40,0x7e,0x4,0x18,0x20,0x20,0x90,0x50,0x30,0x8,0x0,
-+0x1,0x1,0x3,0x3,0x3,0x7,0xff,0x3f,0x1f,0xf,0xf,0x1f,0x1e,0x18,0x20,0x0,0x0,0x0,0x80,0x80,0x80,0xc0,0xfe,0xf8,0xf0,0xe0,0xe0,0xf0,0xf0,0x30,0x8,0x0,
-+0x0,0x7,0x18,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x18,0x7,0x0,0x0,0x0,0xc0,0x30,0x8,0x8,0x4,0x4,0x4,0x4,0x4,0x8,0x8,0x30,0xc0,0x0,0x0,
-+0x0,0x7,0x1f,0x3f,0x3f,0x7f,0x7f,0x7f,0x7f,0x7f,0x3f,0x3f,0x1f,0x7,0x0,0x0,0x0,0xc0,0xf0,0xf8,0xf8,0xfc,0xfc,0xfc,0xfc,0xfc,0xf8,0xf8,0xf0,0xc0,0x0,0x0,
-+0x0,0x7,0x18,0x27,0x28,0x50,0x50,0x50,0x50,0x50,0x28,0x27,0x18,0x7,0x0,0x0,0x0,0xc0,0x30,0xc8,0x28,0x14,0x14,0x14,0x14,0x14,0x28,0xc8,0x30,0xc0,0x0,0x0,
-+0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x1,0x0,0x0,0x80,0x40,0x20,0x10,0x8,0x4,0x2,0x4,0x8,0x10,0x20,0x40,0x80,0x0,0x0,
-+0x1,0x3,0x7,0xf,0x1f,0x3f,0x7f,0xff,0x7f,0x3f,0x1f,0xf,0x7,0x3,0x1,0x0,0x0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xfc,0xf8,0xf0,0xe0,0xc0,0x80,0x0,0x0,
-+0x0,0x7f,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7f,0x0,0x0,0x0,0xfc,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0xfc,0x0,0x0,
-+0x0,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x0,0x0,0x0,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0x0,0x0,
-+0x0,0x1,0x2,0x4,0x4,0x8,0x8,0x10,0x10,0x20,0x20,0x40,0x40,0xff,0x0,0x0,0x0,0x0,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x8,0x8,0x4,0x4,0xfe,0x0,0x0,
-+0x0,0x1,0x3,0x7,0x7,0xf,0xf,0x1f,0x1f,0x3f,0x3f,0x7f,0x7f,0xff,0x0,0x0,0x0,0x0,0x80,0xc0,0xc0,0xe0,0xe0,0xf0,0xf0,0xf8,0xf8,0xfc,0xfc,0xfe,0x0,0x0,
-+0x0,0x43,0x23,0x10,0x8,0x4,0x2,0x61,0x62,0x4,0x8,0x10,0x23,0x43,0x80,0x0,0x0,0x4,0x8,0x10,0x20,0x40,0x80,0xc,0x8c,0x40,0x20,0x10,0x8,0x4,0x2,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x38,0xfe,0x38,0x20,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x8,0x38,0xff,0x38,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x3,0x3,0x7,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x80,0x80,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x7,0x3,0x3,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x80,0x80,0x0,0x0,
-+0x0,0x0,0x0,0xff,0xff,0xff,0x0,0x0,0x0,0xff,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe,0xfe,0xfe,0x0,0x0,0x0,0xfe,0xfe,0xfe,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x2,0x6,0xa,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x0,
-+0x0,0xf,0x10,0x10,0x0,0x0,0x0,0x1,0x6,0x8,0x10,0x10,0x10,0x10,0x1f,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x90,0x0,
-+0x0,0xf,0x10,0x10,0x0,0x0,0x1,0x6,0x1,0x0,0x0,0x10,0x10,0x10,0xf,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x10,0x0,
-+0x0,0x3,0x5,0x5,0x5,0x9,0x9,0x9,0x11,0x11,0x1f,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x0,0x0,0x8,0x0,
-+0x0,0x1f,0x10,0x10,0x10,0x10,0x10,0x17,0x18,0x10,0x0,0x0,0x10,0x10,0xf,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x10,0x0,
-+0x0,0xf,0x10,0x10,0x10,0x10,0x10,0x17,0x18,0x10,0x10,0x10,0x10,0x10,0xf,0x0,0x0,0x0,0x80,0x80,0x80,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x10,0x0,
-+0x0,0x1f,0x10,0x10,0x0,0x1,0x1,0x1,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0xc0,0x40,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x0,
-+0x0,0xf,0x10,0x10,0x10,0x10,0x9,0x6,0x9,0x10,0x10,0x10,0x10,0x10,0xf,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x10,0x0,
-+0x0,0xf,0x10,0x10,0x10,0x10,0x10,0x11,0xe,0x0,0x0,0x10,0x10,0x10,0xf,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x10,0x0,
-+0x0,0x23,0x64,0xa4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x23,0x0,0x0,0xc0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xc8,0x0,
-+0x0,0x20,0x61,0xa2,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x90,0x0,
-+0x0,0x23,0x64,0xa4,0x20,0x20,0x20,0x20,0x21,0x22,0x24,0x24,0x24,0x24,0x27,0x0,0x0,0xc0,0x20,0x20,0x20,0x20,0x20,0x40,0x80,0x0,0x0,0x0,0x20,0x20,0xe4,0x0,
-+0x0,0x23,0x64,0xa4,0x20,0x20,0x20,0x21,0x20,0x20,0x20,0x24,0x24,0x24,0x23,0x0,0x0,0xc0,0x20,0x20,0x20,0x20,0x40,0x80,0x40,0x20,0x20,0x20,0x20,0x20,0xc4,0x0,
-+0x0,0x20,0x61,0xa1,0x21,0x22,0x22,0x22,0x24,0x24,0x27,0x20,0x20,0x20,0x20,0x0,0x0,0xc0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xf0,0x40,0x40,0x40,0x48,0x0,
-+0x0,0x27,0x64,0xa4,0x24,0x24,0x24,0x25,0x26,0x24,0x20,0x20,0x24,0x24,0x23,0x0,0x0,0xe0,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x20,0x20,0x20,0x20,0x20,0xc4,0x0,
-+0x0,0x23,0x64,0xa4,0x24,0x24,0x24,0x25,0x26,0x24,0x24,0x24,0x24,0x24,0x23,0x0,0x0,0xc0,0x20,0x20,0x20,0x0,0x0,0xc0,0x20,0x20,0x20,0x20,0x20,0x20,0xc4,0x0,
-+0x0,0x27,0x64,0xa4,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0,0x0,0xf0,0x10,0x10,0x20,0x40,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x84,0x0,
-+0x0,0x23,0x64,0xa4,0x24,0x24,0x22,0x21,0x22,0x24,0x24,0x24,0x24,0x24,0x23,0x0,0x0,0xc0,0x20,0x20,0x20,0x20,0x40,0x80,0x40,0x20,0x20,0x20,0x20,0x20,0xc4,0x0,
-+0x0,0x23,0x64,0xa4,0x24,0x24,0x24,0x24,0x23,0x20,0x20,0x24,0x24,0x24,0x23,0x0,0x0,0xc0,0x20,0x20,0x20,0x20,0x20,0x60,0xa0,0x20,0x20,0x20,0x20,0x20,0xc4,0x0,
-+0x0,0x38,0x45,0x45,0x5,0x5,0x5,0x19,0x21,0x41,0x41,0x41,0x45,0x45,0x7c,0x0,0x0,0xe0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xe4,0x0,
-+0x0,0x40,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x81,0x40,0x0,0x0,0x4,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x4,0x0,
-+0x0,0x40,0x87,0x88,0x88,0x80,0x80,0x80,0x80,0x83,0x84,0x88,0x88,0x8f,0x40,0x0,0x0,0x4,0x82,0x42,0x42,0x42,0x42,0x42,0x82,0x2,0x2,0x42,0x42,0xc2,0x4,0x0,
-+0x0,0x40,0x87,0x88,0x88,0x80,0x80,0x83,0x80,0x80,0x80,0x88,0x88,0x87,0x40,0x0,0x0,0x4,0x82,0x42,0x42,0x42,0x82,0x2,0x82,0x42,0x42,0x42,0x42,0x82,0x4,0x0,
-+0x0,0x41,0x82,0x82,0x82,0x84,0x84,0x88,0x88,0x8f,0x80,0x80,0x80,0x80,0x40,0x0,0x0,0x84,0x82,0x82,0x82,0x82,0x82,0x82,0x82,0xe2,0x82,0x82,0x82,0x82,0x4,0x0,
-+0x0,0x40,0x8f,0x88,0x88,0x88,0x8b,0x8c,0x88,0x80,0x80,0x88,0x88,0x87,0x40,0x0,0x0,0x4,0xc2,0x2,0x2,0x2,0x82,0x42,0x42,0x42,0x42,0x42,0x42,0x82,0x4,0x0,
-+0x0,0x40,0x87,0x88,0x88,0x88,0x88,0x8b,0x8c,0x88,0x88,0x88,0x88,0x87,0x40,0x0,0x0,0x4,0x82,0x42,0x42,0x2,0x2,0x82,0x42,0x42,0x42,0x42,0x42,0x82,0x4,0x0,
-+0x0,0x40,0x8f,0x88,0x88,0x80,0x80,0x80,0x80,0x81,0x81,0x81,0x81,0x81,0x40,0x0,0x0,0x4,0xe2,0x22,0x22,0x42,0x82,0x82,0x82,0x2,0x2,0x2,0x2,0x2,0x4,0x0,
-+0x0,0x40,0x87,0x88,0x88,0x88,0x88,0x87,0x88,0x88,0x88,0x88,0x88,0x87,0x40,0x0,0x0,0x4,0x82,0x42,0x42,0x42,0x42,0x82,0x42,0x42,0x42,0x42,0x42,0x82,0x4,0x0,
-+0x0,0x40,0x87,0x88,0x88,0x88,0x88,0x88,0x87,0x80,0x80,0x88,0x88,0x87,0x40,0x0,0x0,0x4,0x82,0x42,0x42,0x42,0x42,0xc2,0x42,0x42,0x42,0x42,0x42,0x82,0x4,0x0,
-+0x0,0x40,0x88,0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x89,0x88,0x40,0x0,0x0,0x4,0xe2,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0xe2,0x4,0x0,
-+0x0,0x40,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x40,0x0,0x0,0x4,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x4,0x0,
-+0x0,0x40,0x91,0x92,0x92,0x90,0x90,0x90,0x90,0x91,0x92,0x92,0x92,0x93,0x40,0x0,0x0,0x4,0xe2,0x12,0x12,0x12,0x12,0x22,0xc2,0x2,0x2,0x12,0x12,0xf2,0x4,0x0,
-+0x0,0x40,0x91,0x92,0x92,0x90,0x90,0x90,0x90,0x90,0x90,0x92,0x92,0x91,0x40,0x0,0x0,0x4,0xe2,0x12,0x12,0x12,0x22,0xc2,0x22,0x12,0x12,0x12,0x12,0xe2,0x4,0x0,
-+0x0,0x40,0x90,0x90,0x90,0x90,0x91,0x91,0x92,0x92,0x93,0x90,0x90,0x90,0x40,0x0,0x0,0x4,0x62,0xa2,0xa2,0xa2,0x22,0x22,0x22,0x22,0xfa,0x22,0x22,0x22,0x4,0x0,
-+0x0,0x40,0x93,0x92,0x92,0x92,0x92,0x93,0x92,0x90,0x90,0x92,0x92,0x91,0x40,0x0,0x0,0x4,0xf2,0x2,0x2,0x2,0xe2,0x12,0x12,0x12,0x12,0x12,0x12,0xe2,0x4,0x0,
-+0x0,0x40,0x91,0x92,0x92,0x92,0x92,0x92,0x93,0x92,0x92,0x92,0x92,0x91,0x40,0x0,0x0,0x4,0xe2,0x12,0x12,0x2,0x2,0xe2,0x12,0x12,0x12,0x12,0x12,0xe2,0x4,0x0,
-+0x0,0x40,0x93,0x92,0x92,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x40,0x0,0x0,0x4,0xf2,0x12,0x12,0x22,0x42,0x42,0x42,0x82,0x82,0x82,0x82,0x82,0x4,0x0,
-+0x0,0x40,0x91,0x92,0x92,0x92,0x92,0x91,0x92,0x92,0x92,0x92,0x92,0x91,0x40,0x0,0x0,0x4,0xe2,0x12,0x12,0x12,0x12,0xe2,0x12,0x12,0x12,0x12,0x12,0xe2,0x4,0x0,
-+0x0,0x40,0x91,0x92,0x92,0x92,0x92,0x92,0x91,0x90,0x90,0x92,0x92,0x91,0x40,0x0,0x0,0x4,0xe2,0x12,0x12,0x12,0x12,0x32,0xd2,0x12,0x12,0x12,0x12,0xe2,0x4,0x0,
-+0x0,0x40,0x9c,0xa2,0xa2,0x82,0x82,0x84,0x88,0x90,0xa0,0xa2,0xa2,0xbe,0x40,0x0,0x0,0x4,0x72,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x8a,0x72,0x4,0x0,
-+0x7,0x18,0x20,0x41,0x41,0x81,0x81,0x81,0x81,0x81,0x41,0x41,0x20,0x18,0x7,0x0,0xc0,0x30,0x8,0x4,0x4,0x2,0x2,0x2,0x2,0x2,0x4,0x4,0x8,0x30,0xc0,0x0,
-+0x7,0x18,0x20,0x47,0x44,0x80,0x80,0x81,0x82,0x84,0x44,0x47,0x20,0x18,0x7,0x0,0xc0,0x30,0x8,0xc4,0x44,0x42,0x42,0x82,0x2,0x2,0x44,0xc4,0x8,0x30,0xc0,0x0,
-+0x7,0x18,0x20,0x47,0x44,0x80,0x80,0x83,0x80,0x80,0x44,0x47,0x20,0x18,0x7,0x0,0xc0,0x30,0x8,0xc4,0x44,0x42,0xc2,0x2,0xc2,0x42,0x44,0xc4,0x8,0x30,0xc0,0x0,
-+0x7,0x18,0x20,0x43,0x45,0x85,0x85,0x89,0x89,0x8f,0x41,0x41,0x20,0x18,0x7,0x0,0xc0,0x30,0x8,0x4,0x4,0x2,0x2,0x2,0x2,0xc2,0x4,0x4,0x8,0x30,0xc0,0x0,
-+0x7,0x18,0x20,0x47,0x44,0x84,0x84,0x87,0x80,0x80,0x44,0x47,0x20,0x18,0x7,0x0,0xc0,0x30,0x8,0xc4,0x4,0x2,0x2,0xc2,0x42,0x42,0x44,0xc4,0x8,0x30,0xc0,0x0,
-+0x7,0x18,0x20,0x47,0x44,0x84,0x84,0x87,0x84,0x84,0x44,0x47,0x20,0x18,0x7,0x0,0xc0,0x30,0x8,0xc4,0x44,0x2,0x2,0xc2,0x42,0x42,0x44,0xc4,0x8,0x30,0xc0,0x0,
-+0x7,0x18,0x20,0x47,0x44,0x80,0x80,0x80,0x81,0x81,0x41,0x41,0x20,0x18,0x7,0x0,0xc0,0x30,0x8,0xc4,0x44,0x42,0x82,0x82,0x2,0x2,0x4,0x4,0x8,0x30,0xc0,0x0,
-+0x7,0x18,0x20,0x47,0x44,0x84,0x84,0x83,0x84,0x84,0x44,0x47,0x20,0x18,0x7,0x0,0xc0,0x30,0x8,0xc4,0x44,0x42,0x42,0x82,0x42,0x42,0x44,0xc4,0x8,0x30,0xc0,0x0,
-+0x7,0x18,0x20,0x47,0x44,0x84,0x84,0x87,0x80,0x80,0x44,0x47,0x20,0x18,0x7,0x0,0xc0,0x30,0x8,0xc4,0x44,0x42,0x42,0xc2,0x42,0x42,0x44,0xc4,0x8,0x30,0xc0,0x0,
-+0x7,0x18,0x20,0x4b,0x4a,0x8a,0x8a,0x8a,0x8a,0x8a,0x4a,0x4b,0x20,0x18,0x7,0x0,0xc0,0x30,0x8,0xe4,0x24,0x22,0x22,0x22,0x22,0x22,0x24,0xe4,0x8,0x30,0xc0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x20,0x40,0x80,0x80,0x80,0x80,0xbf,0x80,0x80,0x80,0x80,0x80,0x40,0x20,0x0,0x0,0x8,0x4,0x2,0x2,0x2,0x12,0xfa,0x2,0x2,0x2,0x2,0x2,0x4,0x8,0x0,
-+0x0,0x20,0x40,0x80,0x9f,0x80,0x80,0x80,0x80,0x80,0xbf,0x80,0x80,0x40,0x20,0x0,0x0,0x8,0x4,0x22,0xf2,0x2,0x2,0x2,0x2,0x12,0xfa,0x2,0x2,0x4,0x8,0x0,
-+0x0,0x20,0x40,0x9f,0x80,0x80,0x80,0x8f,0x80,0x80,0x80,0xbf,0x80,0x40,0x20,0x0,0x0,0x8,0x24,0xf2,0x2,0x2,0x42,0xe2,0x2,0x2,0x12,0xfa,0x2,0x4,0x8,0x0,
-+0x0,0x20,0x40,0x80,0xbf,0xa4,0xa4,0xa4,0xa4,0xa4,0xbf,0x80,0x80,0x40,0x20,0x0,0x0,0x8,0x4,0x2,0xfa,0x4a,0x4a,0x4a,0x4a,0x4a,0xfa,0x2,0x2,0x4,0x8,0x0,
-+0x0,0x20,0x40,0x9f,0x82,0x82,0x82,0x9f,0x84,0x84,0x84,0x84,0xbf,0x40,0x20,0x0,0x0,0x8,0x24,0xf2,0x2,0x2,0x22,0xf2,0x22,0x22,0x22,0x22,0xfa,0x4,0x8,0x0,
-+0x0,0x20,0x40,0x82,0x81,0x80,0xbf,0x80,0x80,0x84,0x84,0x88,0x90,0x40,0x20,0x0,0x0,0x8,0x4,0x2,0x2,0x12,0xfa,0x2,0x2,0x42,0x22,0x12,0x12,0x4,0x8,0x0,
-+0x0,0x20,0x42,0x82,0x82,0x82,0x82,0x83,0xbe,0x82,0x82,0x82,0x82,0x41,0x20,0x0,0x0,0x8,0x4,0x2,0x2,0x12,0x7a,0x82,0x2,0x2,0x2,0x22,0x22,0xe4,0x8,0x0,
-+0x0,0x20,0x40,0x84,0x84,0x84,0x84,0x84,0x88,0x88,0x90,0xa0,0x80,0x40,0x20,0x0,0x0,0x8,0x84,0x82,0x82,0x82,0x82,0x82,0x42,0x22,0x1a,0x12,0x2,0x4,0x8,0x0,
-+0x0,0x20,0x42,0x82,0x82,0x9f,0x82,0x82,0x82,0x84,0x84,0x88,0x90,0x40,0x20,0x0,0x0,0x8,0x4,0x2,0x42,0xe2,0x42,0x42,0x42,0x42,0x4a,0x4a,0x3a,0x4,0x8,0x0,
-+0x0,0x20,0x41,0x81,0x81,0x81,0xbf,0x81,0x81,0x81,0x81,0x81,0x81,0x40,0x20,0x0,0x0,0x8,0x4,0x2,0x2,0x12,0xfa,0x2,0x2,0x2,0x2,0x2,0x2,0x4,0x8,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x3,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x3,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,
-+0x0,0xe,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0xe,0x0,0x0,0xe0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xe0,0x0,
-+0x0,0x3b,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x3b,0x0,0x0,0xb8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xb8,0x0,
-+0x0,0x77,0x22,0x22,0x22,0x21,0x21,0x21,0x21,0x20,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x1c,0x8,0x8,0x8,0x10,0x10,0x10,0x10,0xa0,0xa0,0xa0,0xa0,0x40,0x40,0x0,
-+0x0,0x70,0x20,0x10,0x10,0x8,0x8,0x8,0x4,0x4,0x4,0x2,0x2,0x1,0x1,0x0,0x0,0x1c,0x8,0x10,0x10,0x20,0x20,0x20,0x40,0x40,0x40,0x80,0x80,0x0,0x0,0x0,
-+0x0,0x71,0x20,0x20,0x20,0x11,0x11,0x11,0x11,0xa,0xa,0xa,0xa,0x4,0x4,0x0,0x0,0xdc,0x88,0x88,0x88,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x1c,0x0,
-+0x0,0xe3,0x41,0x41,0x41,0x22,0x22,0x22,0x22,0x14,0x14,0x14,0x14,0x8,0x8,0x0,0x0,0xfe,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x7e,0x0,
-+0x0,0xe3,0x41,0x41,0x41,0x22,0x22,0x22,0x22,0x14,0x14,0x14,0x14,0x8,0x8,0x0,0x0,0xfe,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0xfe,0x0,
-+0x0,0xee,0x44,0x42,0x42,0x41,0x40,0x40,0x40,0x40,0x41,0x41,0x42,0x44,0xee,0x0,0x0,0xe,0x4,0x8,0x8,0x10,0xa0,0x40,0xa0,0xa0,0x10,0x10,0x8,0x4,0xe,0x0,
-+0x0,0x70,0x20,0x10,0x8,0x4,0x2,0x1,0x2,0x2,0x4,0x8,0x10,0x20,0x70,0x0,0x0,0x1c,0x8,0x10,0x20,0x40,0x80,0x0,0x80,0x80,0x40,0x20,0x10,0x8,0x1c,0x0,
-+0x0,0xe0,0x40,0x20,0x11,0xa,0xa,0x4,0xa,0xa,0x11,0x11,0x20,0x40,0xe0,0x0,0x0,0xee,0x44,0x84,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x84,0x44,0xee,0x0,
-+0x0,0xe0,0x40,0x20,0x11,0xa,0xa,0x4,0xa,0xa,0x11,0x11,0x20,0x40,0xe0,0x0,0x0,0xfe,0x54,0x94,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x94,0x54,0xfe,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0x4,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x40,0x40,0x80,0x80,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x4,0x4,0x4,0x3f,0x4,0x4,0x4,0x4,0x3f,0x4,0x4,0x4,0x0,0x0,0x0,0x0,0x40,0x40,0x78,0xc0,0x40,0x40,0x40,0x78,0xc0,0x40,0x40,0x40,0x0,0x0,
-+0x0,0x38,0x10,0x8,0x4,0x2,0x2,0x1,0x1,0xf,0x1,0x1,0x1,0x1,0x3,0x0,0x0,0x38,0x10,0x20,0x40,0x80,0x80,0x0,0x0,0xe0,0x0,0x0,0x0,0x0,0x80,0x0,
-+0x0,0x18,0x24,0x24,0x24,0x24,0x24,0x19,0x2,0x4,0x8,0x10,0x20,0x40,0x0,0x0,0x0,0x4,0x8,0x10,0x20,0x40,0x80,0x0,0x0,0x60,0x90,0x90,0x90,0x90,0x90,0x60,
-+0x0,0xf,0x10,0x10,0x10,0x10,0xb,0x4,0x1c,0x22,0x41,0x40,0x40,0x21,0x1e,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x0,0x0,0x0,0x70,0x20,0xa0,0x44,0xa4,0x18,0x0,
-+0x10,0x10,0x10,0x20,0x20,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc,0x10,0x20,0x40,0x40,0x80,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x20,0x10,0xc,
-+0x60,0x10,0x8,0x4,0x4,0x2,0x2,0x2,0x2,0x2,0x2,0x4,0x4,0x8,0x10,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x1,0x1,0x21,0x11,0x9,0x5,0x1,0x2,0x4,0x8,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x10,0x20,0x40,0x0,0x80,0x40,0x20,0x10,0x0,0x0,0x0,
-+0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1f,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x30,0x10,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x30,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x2,0x4,0x8,0x10,0x20,0x0,0x0,0x0,0x0,0x4,0x8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x7,0x8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0xc0,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0xc0,0x0,
-+0x0,0x1,0x3,0x5,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,
-+0x0,0x7,0x8,0x10,0x10,0x0,0x0,0x0,0x3,0x4,0x8,0x10,0x10,0x10,0x1f,0x0,0x0,0xc0,0x20,0x10,0x10,0x10,0x10,0xe0,0x0,0x0,0x0,0x0,0x10,0x10,0xf0,0x0,
-+0x0,0xf,0x10,0x10,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x10,0x10,0xf,0x0,0x0,0xe0,0x10,0x10,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x10,0x10,0x20,0xc0,0x0,
-+0x0,0x1,0x2,0x2,0x2,0x4,0x4,0x8,0x8,0x10,0x20,0x3f,0x0,0x0,0x3,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xf0,0x80,0x80,0xe0,0x0,
-+0x0,0x1f,0x10,0x10,0x10,0x10,0x17,0x18,0x10,0x0,0x0,0x0,0x10,0x10,0xf,0x0,0x0,0xf0,0x0,0x0,0x0,0x0,0xc0,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0xc0,0x0,
-+0x0,0x7,0x8,0x10,0x10,0x10,0x10,0x17,0x18,0x10,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0xc0,0x20,0x10,0x10,0x0,0x0,0xc0,0x20,0x10,0x10,0x10,0x10,0x20,0xc0,0x0,
-+0x0,0x1f,0x10,0x10,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x2,0x2,0x2,0x0,0x0,0xf0,0x10,0x10,0x20,0x20,0x40,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x7,0x8,0x10,0x10,0x10,0x8,0x7,0x8,0x10,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0xc0,0x20,0x10,0x10,0x10,0x20,0xc0,0x20,0x10,0x10,0x10,0x10,0x20,0xc0,0x0,
-+0x0,0x7,0x8,0x10,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0x10,0x10,0x8,0x7,0x0,0x0,0xc0,0x20,0x10,0x10,0x10,0x10,0x30,0xd0,0x10,0x10,0x10,0x10,0x20,0xc0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x30,0x0,0x30,0x30,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x30,0x0,0x30,0x30,0x10,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x3,0xc,0x30,0x40,0x30,0xc,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0xc,0x30,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x30,0xc,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x1f,0x0,0x0,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,0x0,0xf0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x60,0x18,0x6,0x1,0x0,0x0,0x0,0x0,0x0,0x1,0x6,0x18,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x60,0x18,0x4,0x18,0x60,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x18,0x24,0x42,0x42,0x4,0x8,0x8,0x8,0x8,0x8,0x0,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x7,0x18,0x20,0x46,0x49,0x48,0x48,0x48,0x49,0x46,0x20,0x18,0x7,0x0,0x0,0x0,0xc0,0x20,0x10,0x90,0x88,0x88,0x88,0x88,0x90,0x90,0x64,0x8,0xf0,0x0,0x0,
-+0x0,0x1,0x2,0x2,0x4,0x4,0x8,0xf,0x10,0x10,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x40,0x40,0x20,0xe0,0x10,0x10,0x8,0x1c,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x7f,0x0,0x0,0x0,0x0,0x0,0xe0,0x10,0x10,0x10,0x20,0xc0,0x20,0x10,0x10,0x10,0xe0,0x0,0x0,0x0,0x0,
-+0x0,0xf,0x10,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0xf,0x0,0x0,0x0,0x0,0x0,0xe0,0x10,0x8,0x0,0x0,0x0,0x0,0x0,0x8,0x10,0xe0,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7f,0x0,0x0,0x0,0x0,0x0,0xe0,0x10,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x10,0xe0,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x7f,0x0,0x0,0x0,0x0,0x0,0xfc,0x4,0x4,0x0,0x20,0xe0,0x20,0x0,0x4,0x4,0xfc,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0xfc,0x4,0x4,0x0,0x20,0xe0,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1f,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x1f,0x0,0x0,0x0,0x0,0x0,0xd0,0x30,0x10,0x0,0x0,0x0,0x38,0x10,0x10,0x10,0xe0,0x0,0x0,0x0,0x0,
-+0x0,0x70,0x20,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0x1c,0x8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0x1c,0x0,0x0,0x0,0x0,
-+0x0,0x3,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x3,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x3,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x5,0x5,0x2,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x71,0x21,0x22,0x24,0x38,0x24,0x22,0x21,0x20,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x70,0x0,0x0,0x0,0x0,
-+0x0,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x8,0xf8,0x0,0x0,0x0,0x0,
-+0x0,0xc0,0x60,0x50,0x48,0x44,0x42,0x41,0x40,0x40,0x40,0xe0,0x0,0x0,0x0,0x0,0x0,0x6,0xc,0x14,0x24,0x44,0x84,0x4,0x4,0x4,0x4,0xe,0x0,0x0,0x0,0x0,
-+0x0,0x60,0x30,0x28,0x24,0x22,0x21,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0x1c,0x8,0x8,0x8,0x8,0x8,0x88,0x48,0x28,0x18,0x8,0x0,0x0,0x0,0x0,
-+0x0,0x7,0x8,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x10,0x8,0x8,0x8,0x8,0x8,0x10,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x10,0x10,0x20,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x7,0x8,0x10,0x20,0x20,0x20,0x20,0x20,0x11,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x10,0x8,0x8,0x8,0x8,0x8,0x90,0x60,0xc0,0x30,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x20,0x20,0x20,0x3f,0x24,0x22,0x21,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x10,0x10,0x20,0xc0,0x0,0x0,0x0,0x80,0x70,0x0,0x0,0x0,0x0,
-+0x0,0xf,0x10,0x20,0x20,0x10,0xf,0x0,0x0,0x20,0x30,0x2f,0x0,0x0,0x0,0x0,0x0,0xe8,0x18,0x8,0x0,0x0,0xe0,0x10,0x8,0x8,0x10,0xe0,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x41,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x3,0x0,0x0,0x0,0x0,0x0,0xfc,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0xf,0x0,0x0,0x0,0x0,0x0,0x1c,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x10,0xe0,0x0,0x0,0x0,0x0,
-+0x0,0x70,0x20,0x10,0x10,0x8,0x8,0x4,0x4,0x2,0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x1c,0x8,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0xe3,0x41,0x41,0x41,0x22,0x22,0x22,0x14,0x14,0x8,0x8,0x0,0x0,0x0,0x0,0x0,0x8e,0x4,0x4,0x4,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x0,0x0,0x0,0x0,
-+0x0,0x70,0x10,0x8,0x4,0x2,0x1,0x2,0x4,0x8,0x10,0x70,0x0,0x0,0x0,0x0,0x0,0x1c,0x10,0x20,0x40,0x80,0x0,0x80,0x40,0x20,0x10,0x1c,0x0,0x0,0x0,0x0,
-+0x0,0x70,0x20,0x10,0x8,0x4,0x2,0x1,0x1,0x1,0x1,0x3,0x0,0x0,0x0,0x0,0x0,0x1c,0x8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x3f,0x20,0x20,0x0,0x0,0x1,0x2,0x4,0x8,0x10,0x3f,0x0,0x0,0x0,0x0,0x0,0xf8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x8,0x8,0xf8,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0xe,0x0,0x0,
-+0x0,0x40,0x20,0x10,0x8,0x4,0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x20,0x10,0x8,0x4,0x0,0x0,
-+0x0,0xe0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x2,0x2,0x4,0x4,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x40,0x40,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x7f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x20,0x10,0x10,0x8,0x8,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0xf,0x10,0x0,0xf,0x10,0x10,0x10,0xf,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x40,0x40,0xc0,0x40,0x50,0xa0,0x0,0x0,0x0,0x0,
-+0x0,0x8,0x8,0x8,0x8,0xb,0xc,0x8,0x8,0x8,0xc,0xb,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x10,0x10,0x10,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x7,0x8,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x0,0x0,0x10,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x7,0x8,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x20,0x20,0x20,0x20,0xa0,0x60,0x20,0x20,0x20,0x60,0xa0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0xf,0x10,0x10,0x1f,0x10,0x10,0xf,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x40,0xc0,0x0,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x2,0x2,0x2,0x2,0xf,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x80,0x80,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x7,0x8,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0xa0,0x60,0x20,0x20,0x20,0x60,0xa0,0x20,0x20,0x40,0x80,0x0,
-+0x0,0x8,0x8,0x8,0x8,0xb,0xc,0x8,0x8,0x8,0x8,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x20,0x20,0x20,0x20,0x20,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x5,0x5,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x8,0x8,0x8,0x8,0x8,0x9,0xa,0xd,0x8,0x8,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x80,0x40,0x20,0x0,0x0,0x0,0x0,
-+0x0,0x3,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x1a,0xd,0x9,0x9,0x9,0x9,0x9,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x20,0x20,0x20,0x20,0x30,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x1b,0xc,0x8,0x8,0x8,0x8,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x7,0x8,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x40,0x40,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x1b,0xc,0x8,0x8,0x8,0xc,0xb,0x8,0x8,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x20,0x20,0x20,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x3,0x4,0x8,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xa0,0x60,0x20,0x20,0x20,0x60,0xa0,0x20,0x20,0x20,0x30,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x5,0x2,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x7,0x8,0x8,0x7,0x0,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x0,0x80,0x40,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x2,0x2,0x2,0xf,0x2,0x2,0x2,0x2,0x2,0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0xc,0x4,0x4,0x4,0x4,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x40,0x40,0x40,0x40,0xc0,0x60,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x8,0x8,0x4,0x4,0x2,0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x20,0x40,0x40,0x80,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x11,0x9,0x9,0xa,0xa,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x20,0x20,0xa0,0xa0,0x40,0x40,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x8,0x4,0x2,0x1,0x2,0x4,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x40,0x80,0x0,0x80,0x40,0x20,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x8,0x4,0x4,0x2,0x1,0x1,0x2,0x2,0x4,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x40,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0xf,0x8,0x0,0x1,0x2,0x4,0xf,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x40,0x80,0x0,0x0,0x40,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x8,0x8,0x8,0x8,0x8,0x10,0x20,0x10,0x8,0x8,0x8,0x8,0x8,0x4,0x0,
-+0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x40,0x20,0x20,0x20,0x20,0x20,0x10,0x8,0x10,0x20,0x20,0x20,0x20,0x20,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x4,0x4,0x25,0x1e,0x4,0x7,0xc,0x14,0x23,0x22,0x25,0x18,0x0,0x0,0x0,0x0,0x0,0x20,0xc0,0x0,0x80,0xe0,0x90,0x88,0x8,0x8,0x10,0x20,0xc0,
-+0x4,0x4,0x4,0x47,0x3c,0x4,0x4,0x1f,0x24,0x42,0x42,0x41,0x22,0x1c,0x0,0x0,0x0,0x0,0x60,0x80,0x0,0x40,0x40,0xf0,0x48,0x84,0x84,0x4,0x84,0x8,0x30,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x10,0x18,0x10,0x10,0x10,0x10,0x11,0xa,0x6,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x10,0x8,0x18,0x10,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x21,0x22,0x14,0xc,0x0,0x0,0x0,0x0,0x0,0x20,0x10,0x8,0x4,0x4,0xc,0x8,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0xf,0x1,0x2,0x0,0x11,0xe,0x0,0x0,0x0,0x0,0x1,0x2,0xc,0x0,0x0,0x0,0x80,0x80,0x0,0x0,0xc0,0x20,0x20,0x20,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0xf,0x0,0x1,0x0,0x21,0x1e,0x0,0x0,0x0,0x0,0x0,0x0,0x3,0xc,0x0,0x0,0x80,0x40,0x80,0x0,0xe0,0x10,0x10,0x10,0x10,0x20,0x20,0xc0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x7,0x0,0x1,0x0,0x3,0x1c,0x1,0x3,0x4,0x8,0x10,0x20,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0xc0,0x80,0x0,0x0,0x80,0x80,0x40,0x38,0x0,
-+0x0,0xf,0x0,0x1,0x0,0x3,0x3c,0x1,0x2,0x3,0x4,0x4,0x8,0x10,0x20,0x0,0x0,0x0,0x80,0x0,0x0,0xc0,0x80,0x0,0x0,0x80,0x80,0x80,0x80,0x40,0x3c,0x0,
-+0x0,0x0,0x0,0x4,0x4,0x4,0x3f,0x4,0x7,0x4,0xc,0x14,0x34,0x15,0x8,0x0,0x0,0x0,0x0,0x0,0x10,0x8,0x4,0x8,0xe0,0x10,0x8,0x8,0x8,0x30,0xc0,0x0,
-+0x0,0x4,0x4,0x7,0x3c,0x4,0x5,0x6,0xc,0x14,0x24,0x64,0x35,0xc,0x4,0x0,0x0,0x0,0x10,0x88,0x4,0x18,0xc0,0x20,0x10,0x8,0x8,0x8,0x10,0xe0,0x0,0x0,
-+0x0,0x2,0x2,0x2,0x2,0x43,0x3c,0x4,0x4,0x4,0x8,0x8,0x10,0x22,0x41,0x0,0x0,0x0,0x0,0x20,0x10,0xc8,0x44,0x54,0x4c,0x40,0x40,0x80,0x80,0x80,0x0,0x0,
-+0x0,0x4,0x4,0x4,0x4,0x87,0x78,0x8,0x8,0x8,0x10,0x11,0x21,0x45,0x82,0x0,0x8,0x4,0x12,0x48,0x24,0x90,0x88,0xa8,0x98,0x80,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x2,0x2,0x2,0x3,0x1d,0x0,0x3,0x1c,0x0,0x3,0x0,0x10,0x10,0x8,0x7,0x0,0x0,0x0,0x60,0x80,0x0,0xe0,0x80,0x40,0x40,0xe0,0x20,0x0,0x0,0x0,0xc0,0x0,
-+0x4,0x4,0x4,0x7,0x3a,0x1,0x7,0x38,0x0,0x7,0x0,0x20,0x20,0x10,0xf,0x0,0x0,0x8,0xc4,0x12,0x8,0xc4,0x0,0x80,0x80,0xc0,0x40,0x0,0x0,0x0,0x80,0x0,
-+0x0,0x1,0x0,0x0,0x1,0x2,0x4,0x8,0x10,0x8,0x4,0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x0,
-+0x0,0x2,0x1,0x1,0x2,0x4,0x8,0x10,0x20,0x10,0x8,0x4,0x2,0x1,0x1,0x0,0x0,0x8,0x4,0x22,0x10,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x10,0x10,0x20,0x20,0x27,0x40,0x40,0x40,0x50,0x50,0x20,0x20,0x1,0x0,0x0,0x80,0x40,0x40,0x40,0x78,0xc0,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x0,0x0,
-+0x0,0x0,0x10,0x10,0x20,0x20,0x27,0x40,0x40,0x40,0x50,0x50,0x20,0x20,0x1,0x0,0x8,0x84,0x52,0x48,0x44,0x70,0xc0,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x0,0x0,
-+0x0,0x0,0x10,0xf,0x0,0x3,0x4,0x0,0x20,0x20,0x20,0x10,0xf,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,
-+0x0,0x0,0x10,0xf,0x0,0x3,0x4,0x0,0x20,0x20,0x20,0x10,0xf,0x0,0x0,0x0,0x0,0x0,0x8,0xe4,0x82,0x10,0x8,0x4,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,
-+0x0,0x4,0x2,0x2,0x3f,0x1,0x0,0x0,0x1,0x8,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0x0,0x30,0xc0,0x0,0x0,0x80,0x40,0xe0,0x20,0x0,0x0,0x0,0x0,0xe0,0x0,
-+0x0,0x4,0x2,0x2,0x3f,0x1,0x0,0x0,0x1,0x8,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0x8,0x4,0xd2,0x8,0x4,0x80,0x40,0xe0,0x20,0x0,0x0,0x0,0x0,0xe0,0x0,
-+0x0,0x18,0xc,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x9,0x6,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x20,0x40,0x80,0x0,0x0,
-+0x0,0x18,0xc,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x9,0x6,0x0,0x0,0x10,0x8,0x24,0x10,0x8,0x0,0x0,0x0,0x0,0x10,0x20,0x40,0x80,0x0,0x0,
-+0x0,0x3,0x1,0x1,0x7f,0x1,0x7,0x9,0x9,0x9,0x6,0x0,0x1,0x1,0x2,0xc,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x0,0x0,0x0,0x0,
-+0x3,0x1,0x1,0x1,0x7f,0x1,0x7,0x9,0x9,0x9,0x6,0x0,0x1,0x1,0x2,0xc,0x8,0x4,0x12,0x8,0xf4,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x10,0x8,0x8,0xb,0x7c,0x8,0x8,0x8,0x9,0x8,0x8,0x8,0x7,0x0,0x0,0x80,0x40,0x40,0x40,0xfc,0x40,0x40,0x40,0x40,0x40,0x80,0x0,0x0,0xf0,0x0,
-+0x0,0x0,0x10,0x8,0x8,0xb,0x7c,0x8,0x8,0x8,0x9,0x8,0x8,0x8,0x7,0x0,0x8,0x84,0x52,0x48,0x44,0xf0,0x40,0x40,0x40,0x40,0x40,0x80,0x0,0x0,0xf0,0x0,
-+0x0,0x10,0xf,0x1,0x2,0x4,0x8,0x1f,0x22,0x44,0x4,0x4,0x2,0x1,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,0x0,
-+0x0,0x10,0xf,0x1,0x2,0x4,0x8,0x1f,0x22,0x44,0x4,0x4,0x2,0x1,0x0,0x0,0x8,0x24,0x92,0x8,0x0,0x10,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,0x0,
-+0x0,0x4,0x4,0x47,0x3c,0x9,0x8,0x8,0x10,0x10,0x12,0x22,0x21,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x30,0x40,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,
-+0x0,0x4,0x4,0x47,0x3c,0x9,0x8,0x8,0x10,0x10,0x12,0x22,0x21,0x40,0x0,0x0,0x8,0x4,0x12,0x8,0x4,0xe0,0x30,0x40,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,
-+0x0,0x2,0x2,0x2,0x3,0x7e,0x4,0x7,0x4,0xc,0x8,0x0,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x80,0xc0,0x0,0x0,0xc0,0x20,0x10,0x10,0x10,0x20,0x20,0xc0,0x0,
-+0x0,0x4,0x4,0x5,0x7,0x7c,0x8,0xb,0xc,0x18,0x10,0x0,0x0,0x0,0x0,0x3,0x0,0x8,0x4,0x12,0x88,0x4,0x0,0xc0,0x20,0x10,0x10,0x10,0x20,0x20,0xc0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1f,0x8,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x10,0x10,0x10,0x20,0x40,0x80,0x0,
-+0x0,0x0,0x0,0x1,0x6,0x78,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x7,0x0,0x0,0x0,0x0,0x0,0xe0,0x10,0x8,0x8,0x8,0x8,0x8,0x10,0x20,0xc0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x3,0xc,0xf0,0x40,0x0,0x0,0x0,0x0,0x0,0x1,0xe,0x0,0x0,0x8,0x4,0x12,0xc8,0x24,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x80,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x7f,0x21,0x2,0x4,0x4,0x4,0x4,0x4,0x2,0x1,0x0,0x0,0x0,0x0,0x8,0xfc,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x7f,0x21,0x2,0x4,0x4,0x4,0x4,0x4,0x2,0x1,0x0,0x0,0x0,0x0,0x8,0xfc,0xc0,0x8,0x4,0x12,0x8,0x4,0x0,0x0,0x0,0xf0,0x0,
-+0x0,0x0,0x2,0x1,0x1,0x1,0x1,0x1,0x6,0x8,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x60,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x0,
-+0x0,0x0,0x2,0x1,0x1,0x1,0x1,0x1,0x6,0x8,0x10,0x10,0x10,0x8,0x7,0x0,0x8,0x4,0x12,0x8,0x4,0x30,0x60,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x0,
-+0x0,0x0,0xc,0x4,0x7,0x7c,0x24,0x8,0x8,0x10,0x10,0x23,0x44,0x4,0x3,0x0,0x0,0x0,0x20,0x10,0x8,0x18,0x40,0x40,0x40,0x40,0x40,0xe0,0x50,0x48,0x84,0x0,
-+0x0,0x20,0x10,0x10,0x13,0x20,0x20,0x20,0x40,0x4a,0x4a,0x52,0x51,0x60,0x40,0x0,0x0,0x0,0x0,0x1c,0xe8,0x10,0x20,0x0,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,
-+0x0,0x2,0x1,0x21,0x11,0x17,0x19,0x11,0x31,0x4a,0x4a,0x44,0x44,0x4a,0x30,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x8,0x4,0x4,0x4,0x74,0x8c,0x94,0x62,0x0,0x0,
-+0x0,0x10,0x8,0x8,0x8,0x1e,0x69,0xa,0xc,0x18,0x28,0x48,0xa9,0x29,0x18,0x0,0x0,0x0,0x0,0x0,0x60,0x90,0x10,0x10,0x10,0x10,0x10,0xf0,0x18,0x24,0xc2,0x0,
-+0x0,0x0,0x0,0x7,0x19,0x21,0x42,0x42,0x42,0x44,0x44,0x28,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x30,0x8,0x4,0x4,0x4,0x4,0x8,0x8,0x10,0x20,0xc0,0x0,
-+0x0,0x20,0x10,0x10,0x10,0x27,0x20,0x20,0x40,0x48,0x48,0x53,0x54,0x64,0x43,0x0,0x0,0x80,0x40,0x50,0x78,0xc0,0x40,0x40,0x40,0x40,0x40,0xc0,0x70,0x48,0x84,0x0,
-+0x0,0x20,0x10,0x10,0x10,0x27,0x20,0x20,0x40,0x48,0x48,0x53,0x54,0x64,0x43,0x0,0x8,0x84,0x52,0x48,0x74,0xc0,0x40,0x40,0x40,0x40,0x40,0xc0,0x70,0x48,0x84,0x0,
-+0x0,0x20,0x10,0x10,0x10,0x27,0x20,0x20,0x40,0x48,0x48,0x53,0x54,0x64,0x43,0x0,0xc,0x92,0x52,0x4c,0x70,0xc0,0x40,0x40,0x40,0x40,0x40,0xc0,0x70,0x48,0x84,0x0,
-+0x0,0x0,0x2,0x3e,0x4,0x8,0x8,0x10,0x10,0x20,0x20,0x20,0x20,0x10,0xf,0x0,0x0,0x0,0x0,0x20,0x20,0x30,0x28,0x24,0x20,0x20,0x40,0x40,0x40,0x80,0x0,0x0,
-+0x0,0x0,0x2,0x3e,0x4,0x8,0x8,0x10,0x10,0x20,0x20,0x20,0x20,0x10,0xf,0x0,0x8,0x4,0x12,0x28,0x24,0x30,0x28,0x24,0x20,0x20,0x40,0x40,0x40,0x80,0x0,0x0,
-+0x0,0x0,0x2,0x3e,0x4,0x8,0x8,0x10,0x10,0x20,0x20,0x20,0x20,0x10,0xf,0x0,0xc,0x12,0x12,0x2c,0x20,0x30,0x28,0x24,0x20,0x20,0x40,0x40,0x40,0x80,0x0,0x0,
-+0x0,0x2,0x1,0x0,0x1,0x2,0x2,0x1,0x0,0x3,0x4,0x8,0x78,0x26,0x1,0x0,0x0,0x0,0x80,0xc0,0x0,0x0,0x0,0x0,0xe0,0x98,0x84,0x8c,0x90,0x80,0x0,0x0,
-+0x0,0x2,0x1,0x0,0x1,0x2,0x2,0x1,0x0,0x3,0x4,0x8,0x78,0x26,0x1,0x0,0x8,0x4,0x92,0xc8,0x4,0x0,0x0,0x0,0xe0,0x98,0x84,0x8c,0x90,0x80,0x0,0x0,
-+0x0,0x2,0x1,0x0,0x1,0x2,0x2,0x1,0x0,0x3,0x4,0x8,0x78,0x26,0x1,0x0,0xc,0x12,0x92,0xcc,0x0,0x0,0x0,0x0,0xe0,0x98,0x84,0x8c,0x90,0x80,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x7,0x8,0x10,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x20,0x18,0x6,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x7,0x8,0x10,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x4,0x12,0x8,0x84,0x40,0x20,0x18,0x6,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x7,0x8,0x10,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x18,0x24,0x24,0x18,0x80,0x40,0x20,0x18,0x6,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x20,0x17,0x10,0x10,0x20,0x27,0x20,0x40,0x48,0x48,0x51,0x52,0x62,0x41,0x0,0x0,0x70,0xc0,0x40,0x40,0x40,0xf8,0x40,0x40,0x40,0x40,0xc0,0x70,0x48,0x84,0x0,
-+0x0,0x20,0x17,0x10,0x10,0x20,0x27,0x20,0x40,0x48,0x48,0x51,0x52,0x62,0x41,0x0,0x8,0xe4,0x52,0x48,0x44,0x40,0xf8,0x40,0x40,0x40,0x40,0xc0,0x70,0x48,0x84,0x0,
-+0x0,0x20,0x17,0x10,0x10,0x20,0x27,0x20,0x40,0x48,0x48,0x51,0x52,0x62,0x41,0x0,0x0,0xec,0x52,0x52,0x4c,0x40,0xf0,0x40,0x40,0x40,0x40,0xc0,0x70,0x48,0x84,0x0,
-+0x0,0x1,0x1,0x1,0x3f,0x1,0x1,0x1f,0x1,0x1,0x1,0x1d,0x23,0x21,0x1e,0x0,0x0,0x0,0x0,0xf0,0x0,0x0,0xe0,0x0,0x0,0x0,0x0,0x0,0xc0,0x30,0x8,0x0,
-+0x0,0x0,0x13,0xc,0x0,0x1,0x1,0x1,0x2,0x1a,0x27,0x44,0x48,0x30,0x0,0x1,0x0,0x0,0x80,0x80,0x80,0x0,0x10,0x10,0x10,0x10,0xa0,0x70,0x28,0x44,0x80,0x0,
-+0x0,0x8,0x4,0x4,0x7,0x7c,0x4,0x1c,0x24,0x24,0x24,0x1c,0x8,0x8,0x7,0x0,0x0,0x0,0x0,0x90,0xc8,0x4,0xc,0x10,0x0,0x0,0x10,0x10,0x10,0x18,0xf0,0x0,
-+0x0,0x1,0x10,0x10,0x10,0x1f,0x11,0x29,0x45,0x42,0x45,0x48,0x30,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0xc0,0x20,0x10,0x8,0x8,0x8,0x10,0x10,0x20,0xc0,0x0,
-+0x2,0x2,0x2,0x2,0x23,0x1e,0x4,0x4,0x44,0x3f,0x4,0x4,0x4,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x10,0x8,0xc8,0x8,0x8,0x8,0x8,0x8,0xf0,0x0,
-+0x0,0x0,0x2,0x1,0x0,0x0,0x3,0x24,0x1f,0x2,0x2,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x30,0x48,0x88,0x8,0x8,0x70,0x0,0x80,0x80,0x40,
-+0x0,0x2,0x1,0x0,0x6,0x9,0x10,0x11,0x7e,0x8,0x8,0x4,0x2,0x2,0x1,0x0,0x0,0x0,0x80,0x40,0x40,0x80,0x30,0xc8,0x4,0x4,0x88,0x70,0x0,0x0,0x0,0x80,
-+0x0,0x0,0x0,0x1,0x0,0x0,0x11,0x12,0x14,0x14,0x18,0x1a,0x11,0x10,0x1,0x2,0x0,0x0,0x0,0x0,0x80,0x80,0xe0,0x90,0x88,0x88,0x88,0x88,0x90,0xe0,0x0,0x0,
-+0x0,0x0,0x10,0x10,0x10,0x11,0x22,0x24,0x24,0x24,0x28,0x2a,0x31,0x10,0x0,0x3,0x0,0x80,0x40,0x40,0xf8,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x58,0xe0,0x80,0x0,
-+0x0,0x0,0x0,0x2,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xf,0x11,0x11,0xe,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0xc0,0x0,0x0,0x0,0x0,0xc0,0x30,0x8,0x0,0x0,
-+0x0,0x2,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1f,0x21,0x41,0x42,0x3c,0x0,0x0,0x0,0x0,0x0,0x10,0x38,0xc0,0x0,0x0,0x0,0x0,0xc0,0x30,0x8,0x4,0x0,
-+0x0,0x1c,0x2,0x2,0x4,0x8,0x10,0x10,0x10,0x13,0x14,0x18,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x10,0x8,0x8,0x8,0x30,0xc0,0x0,
-+0x0,0x10,0x8,0x9,0xa,0xa,0x12,0x14,0x14,0x18,0x8,0x0,0x0,0x0,0x1,0x2,0x0,0x0,0x80,0x40,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80,0x80,0x0,0x0,
-+0x0,0x0,0xf,0x0,0x0,0x0,0x1,0x2,0x7,0x8,0x10,0x3,0x4,0x4,0x3,0x0,0x0,0x40,0xa0,0x20,0x40,0x80,0x0,0xf0,0x8,0x4,0x4,0x84,0x44,0x28,0xf0,0x0,
-+0x0,0x8,0x8,0x8,0xe,0x79,0xa,0xc,0x8,0x18,0x28,0x28,0x68,0x18,0x8,0x0,0x0,0x0,0x20,0x50,0x88,0x8,0x10,0x10,0x10,0x10,0x10,0x12,0x14,0x8,0x0,0x0,
-+0x0,0x3,0x1c,0x0,0x1,0x2,0x4,0xf,0x18,0x20,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0xc0,0x40,0x80,0x0,0x0,0xe0,0x10,0x8,0x8,0x8,0x10,0x10,0x60,0x80,0x0,
-+0x0,0x0,0x8,0x4,0x4,0x7,0x3c,0x7,0xc,0x14,0x24,0x34,0xc,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x8,0x8,0x8,0x8,0x10,0x20,0xc0,0x0,0x0,
-+0x0,0x10,0x8,0x8,0x4f,0x38,0xb,0xc,0x8,0x18,0x28,0x48,0x68,0x18,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x18,0x4,0x4,0x4,0x4,0x8,0x10,0x60,0x0,
-+0x0,0x0,0x3,0x1c,0x0,0x1,0x1,0x3,0xf,0x12,0x22,0x44,0x38,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x0,0x0,0xf0,0x8,0x4,0x4,0x64,0x94,0x88,0x70,0x0,
-+0x0,0xf,0x0,0x1,0x3,0x6,0x8,0x13,0x24,0x3,0x2,0x4,0x18,0x26,0x41,0x0,0x0,0xc0,0x80,0x0,0xe0,0x10,0x10,0x90,0xa0,0xc0,0x0,0x0,0x38,0x44,0x88,0x0,
-+0x0,0x2,0x1,0x1,0x1f,0x1,0x2,0x3,0x4,0x8,0x11,0x2,0x2,0x2,0x1,0x0,0x0,0x0,0x0,0xe0,0x0,0x8,0xc,0xd0,0x60,0xc0,0x40,0x40,0x40,0x0,0xf8,0x0,
-+0x0,0x2,0x1,0x1,0x1,0x2,0x2,0x2,0x3,0x2,0x4,0x4,0x4,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x40,0x22,0x22,0x24,0x24,0x18,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x1f,0x0,0x2,0x1,0x1,0x1,0x1,0x1,0x2,0x4,0x8,0x0,0x0,0x0,0x0,0x0,0xf0,0x10,0x60,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x3f,0x0,0x0,0x0,0x2,0x1,0x1,0x1,0x1,0x2,0x2,0x4,0x8,0x0,0x0,0x0,0xf8,0x8,0x10,0x20,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x3,0x5,0x9,0x11,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x40,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x1,0x3,0x5,0x9,0x11,0x21,0x1,0x1,0x1,0x1,0x1,0x0,0x40,0x40,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1,0x11,0x1f,0x10,0x10,0x10,0x0,0x0,0x0,0x0,0x3,0xc,0x0,0x0,0x0,0x0,0x0,0x10,0xf8,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x0,0x0,0x0,
-+0x0,0x0,0x1,0x21,0x3f,0x20,0x20,0x20,0x0,0x0,0x0,0x0,0x0,0x3,0xc,0x0,0x0,0x0,0x0,0x8,0xfc,0x8,0x8,0x10,0x10,0x20,0x20,0x40,0x80,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x1f,0x1,0x1,0x1,0x1,0x1,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0xf0,0x0,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x3f,0x1,0x1,0x1,0x1,0x1,0x1,0x7f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x1,0x1,0x1,0x3f,0x3,0x5,0x9,0x11,0x21,0x1,0x5,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x7f,0x0,0x1,0x2,0x4,0x8,0x10,0x20,0x42,0x1,0x0,0x0,0x80,0x80,0x80,0x88,0xfc,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x0,
-+0x0,0x2,0x2,0x2,0x3f,0x2,0x2,0x2,0x4,0x4,0x8,0x8,0x10,0x21,0x40,0x0,0x0,0x0,0x0,0x20,0xf0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80,0x0,
-+0x0,0x2,0x2,0x2,0x3f,0x2,0x2,0x2,0x4,0x4,0x8,0x8,0x10,0x21,0x40,0x0,0x8,0x4,0x12,0x8,0xe4,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80,0x0,
-+0x0,0x8,0x8,0x4,0x4,0x3f,0x2,0x1,0x1,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x0,0x0,0x0,0x70,0x80,0x80,0x40,0x40,0x20,0x20,0x0,
-+0x0,0x8,0x8,0x4,0x4,0x3f,0x2,0x1,0x1,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x4,0x12,0x8,0xe4,0x0,0x0,0x0,0x70,0x80,0x80,0x40,0x40,0x20,0x20,0x0,
-+0x0,0x2,0x2,0x2,0x3,0x4,0x4,0x8,0x10,0x20,0x0,0x1,0x2,0xc,0x30,0x0,0x0,0x0,0x0,0x10,0xf8,0x10,0x20,0x20,0x40,0x40,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x2,0x2,0x2,0x3,0x4,0x4,0x8,0x10,0x20,0x0,0x1,0x2,0xc,0x30,0x0,0x8,0x4,0x12,0x8,0xe4,0x20,0x20,0x40,0x40,0x80,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x8,0x8,0x8,0xf,0x10,0x20,0x41,0x1,0x2,0x2,0x4,0x8,0x10,0x20,0x0,0x0,0x0,0x0,0x10,0xf8,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x8,0x8,0x8,0xf,0x10,0x20,0x41,0x1,0x2,0x2,0x4,0x8,0x10,0x20,0x0,0x8,0x4,0x12,0x8,0xf4,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x1f,0x0,0x0,0x0,0x0,0x0,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0x20,0x20,0xf0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x0,0x0,0x8,0x4,0x12,0x8,0x24,0xf0,0x20,0x20,0x20,0x40,0xe0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x4,0x4,0x4,0x4,0x7f,0x4,0x4,0x4,0x4,0x4,0x0,0x0,0x1,0x0,0x0,0x40,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x0,0x0,
-+0x0,0x0,0x0,0x8,0x8,0x8,0x8,0x7f,0x8,0x8,0x8,0x8,0x9,0x1,0x2,0x0,0x8,0x4,0x92,0x88,0x84,0x80,0x88,0xfc,0x80,0x80,0x80,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x18,0x4,0x2,0x30,0x8,0x4,0x0,0x0,0x1,0x2,0x24,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x18,0x4,0x2,0x30,0x8,0x4,0x0,0x0,0x1,0x2,0x24,0x18,0x0,0x8,0x4,0x12,0x8,0x4,0x0,0x8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x0,0x1,0x3,0x4,0x8,0x10,0x20,0x0,0x0,0x0,0x0,0x0,0xe0,0x20,0x40,0x40,0x80,0x0,0x0,0x80,0x40,0x30,0x10,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x0,0x1,0x3,0x4,0x8,0x10,0x20,0x0,0x8,0x4,0x12,0x8,0xe4,0x20,0x40,0x40,0x80,0x0,0x80,0x40,0x20,0x18,0x8,0x0,
-+0x0,0x4,0x4,0x4,0x4,0x7,0x7c,0x4,0x4,0x4,0x4,0x4,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x20,0x40,0x80,0x0,0x0,0x0,0x20,0xf0,0x0,0x0,
-+0x0,0x0,0x4,0x4,0x4,0x4,0x7,0x7c,0x4,0x4,0x4,0x4,0x4,0x3,0x0,0x0,0x8,0x4,0x12,0x8,0x4,0x0,0xe0,0x20,0x40,0x80,0x0,0x0,0x20,0xf0,0x0,0x0,
-+0x0,0x0,0x0,0x20,0x10,0x8,0xc,0x4,0x0,0x0,0x0,0x1,0x2,0xc,0x30,0x0,0x0,0x0,0x20,0x10,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x40,0x20,0x10,0x18,0x8,0x0,0x0,0x1,0x2,0x4,0x18,0x60,0x8,0x4,0x12,0x48,0x24,0x20,0x20,0x40,0x40,0x80,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x4,0x4,0x7,0x4,0x8,0x8,0x10,0x24,0x2,0x1,0x2,0x4,0x18,0x60,0x0,0x0,0x0,0x20,0xf0,0x20,0x20,0x40,0x40,0x80,0x80,0x0,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x8,0x8,0xf,0x8,0x10,0x10,0x20,0x49,0x5,0x2,0x5,0x8,0x30,0xc0,0x0,0x8,0x4,0x52,0xe8,0x44,0x40,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x1,0x1f,0x1,0x1,0x7f,0x1,0x1,0x2,0x2,0x4,0x4,0x8,0x10,0x0,0x0,0x20,0xf0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x3,0x3e,0x2,0x2,0xff,0x2,0x2,0x4,0x4,0x8,0x8,0x10,0x20,0x8,0x4,0x52,0xe8,0x4,0x0,0x10,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x4,0x3,0x21,0x18,0x8,0x0,0x0,0x0,0x1,0x6,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x4,0x2,0x21,0x11,0x8,0x8,0x0,0x0,0x1,0x2,0x4,0x8,0x30,0x0,0x0,0x0,0x0,0x10,0x10,0x10,0x20,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x8,0x4,0x42,0x22,0x10,0x10,0x0,0x1,0x2,0x4,0x8,0x10,0x60,0x0,0x8,0x4,0x12,0x28,0x24,0x20,0x40,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x1f,0x0,0x0,0x0,0x7f,0x1,0x1,0x2,0x2,0x4,0x4,0x8,0x10,0x20,0x0,0x20,0xf0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0xff,0x2,0x2,0x4,0x4,0x8,0x8,0x10,0x20,0x8,0x4,0x92,0xc8,0x4,0x0,0x10,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x4,0x4,0x4,0x4,0x6,0x5,0x4,0x4,0x4,0x4,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x4,0x4,0x4,0x4,0x6,0x5,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x0,0x8,0x4,0x12,0x8,0x4,0x0,0x0,0x80,0x60,0x20,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x1,0x1,0x7f,0x1,0x1,0x1,0x1,0x2,0x2,0x4,0x4,0x8,0x0,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x1f,0x0,0x0,0x0,0x0,0x7f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0xf0,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x1f,0x0,0x0,0xc,0x2,0x1,0x0,0x0,0x1,0x2,0x4,0x8,0x30,0x0,0x0,0x10,0xf8,0x10,0x20,0x20,0x40,0x40,0x80,0xc0,0x30,0x10,0x0,0x0,0x0,0x0,
-+0x2,0x1,0x0,0x0,0x1f,0x0,0x1,0x3,0x5,0x9,0x11,0x21,0x1,0x1,0x1,0x0,0x0,0x80,0x80,0x0,0xc0,0x80,0x0,0x0,0x40,0x30,0x10,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x2,0x4,0x8,0x10,0x0,0x0,0x0,0x20,0x20,0x20,0x40,0x40,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x4,0x4,0x8,0x8,0x8,0x10,0x10,0x20,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x20,0x10,0x10,0x8,0x8,0xc,0x4,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x4,0x4,0x8,0x8,0x8,0x10,0x10,0x20,0x40,0x0,0x0,0x0,0x8,0x4,0x12,0x8,0x44,0x20,0x10,0x10,0x8,0x8,0xc,0x4,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x4,0x4,0x8,0x8,0x8,0x10,0x10,0x20,0x40,0x0,0x0,0x0,0x0,0xc,0x12,0x12,0x4c,0x20,0x10,0x10,0x8,0x8,0xc,0x4,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x8,0x8,0x8,0x8,0x9,0xe,0x8,0x8,0x8,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x60,0x80,0x0,0x0,0x0,0x0,0x20,0xf0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x20,0x20,0x21,0x21,0x26,0x38,0x20,0x20,0x20,0x20,0x1f,0x0,0x0,0x8,0x4,0x12,0x8,0x4,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x80,0xc0,0x0,0x0,
-+0x0,0x0,0x0,0x20,0x20,0x21,0x21,0x26,0x38,0x20,0x20,0x20,0x20,0x1f,0x0,0x0,0x0,0xc,0x12,0x12,0xc,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x80,0xc0,0x0,0x0,
-+0x0,0x0,0x0,0x7f,0x0,0x0,0x0,0x0,0x0,0x1,0x2,0x4,0x8,0x10,0x20,0x0,0x0,0x0,0x20,0xf0,0x20,0x40,0x40,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x7f,0x0,0x0,0x0,0x1,0x1,0x2,0x4,0x8,0x10,0x20,0x0,0x8,0x4,0x12,0x48,0xe4,0x40,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x7f,0x0,0x0,0x0,0x1,0x1,0x2,0x4,0x8,0x10,0x20,0x0,0x0,0xc,0x12,0x52,0xec,0x40,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x18,0x24,0x43,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x30,0xe,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x18,0x24,0x43,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x4,0x12,0x8,0x4,0x0,0x0,0x0,0xc0,0x30,0xe,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x18,0x24,0x43,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc,0x12,0x12,0xc,0x0,0x0,0x0,0xc0,0x30,0xe,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x1,0x1,0x7f,0x1,0x1,0x9,0x9,0x11,0x21,0x1,0x5,0x2,0x0,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x20,0x10,0x8,0x8,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x1,0x1,0x1,0x7f,0x1,0x1,0x9,0x9,0x11,0x21,0x5,0x2,0x0,0x8,0x4,0x12,0x8,0x4,0x8,0xfc,0x0,0x0,0x20,0x10,0x8,0x8,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x1,0x1,0x1,0x7f,0x1,0x1,0x9,0x9,0x11,0x21,0x5,0x2,0x0,0xc,0x12,0x12,0xc,0x0,0x8,0xfc,0x0,0x0,0x20,0x10,0x8,0x8,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x6,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0xf8,0x10,0x20,0x20,0x40,0x80,0x80,0x40,0x40,0x0,0x0,0x0,
-+0x0,0x0,0xe,0x1,0x0,0x0,0x1c,0x3,0x0,0x0,0x1c,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x60,0x20,0x0,0x0,0xc0,0x40,0x0,0x80,0x60,0x20,0x0,0x0,
-+0x0,0x2,0x2,0x2,0x2,0x4,0x4,0x4,0x4,0x8,0x8,0x10,0x10,0x3f,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x20,0x10,0xf8,0x8,0x8,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x4,0x2,0x1,0x0,0x1,0x2,0x4,0x8,0x10,0x60,0x0,0x0,0x0,0x20,0x10,0x20,0x20,0x40,0x80,0x80,0x60,0x20,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x3,0x3e,0x2,0x2,0x3,0x7e,0x2,0x2,0x2,0x2,0x2,0x1,0x0,0x0,0x0,0x40,0xe0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x8,0x4,0x5,0x3e,0x2,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf8,0x8,0x10,0x20,0x0,0x80,0x80,0x40,0x20,
-+0x0,0x10,0x8,0x8,0x4,0x5,0x7e,0x2,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf8,0x8,0x10,0x20,0x0,0x80,0x80,0x40,0x40,0x20,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0xf,0x0,0x0,0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0xf0,0x20,0x20,0x20,0x40,0x48,0xfc,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x7f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0x20,0x20,0x24,0xfe,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1f,0x0,0x0,0x1f,0x0,0x0,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0xf0,0x20,0x20,0xe0,0x20,0x20,0xe0,0x20,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x3f,0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,0x10,0x10,0xf0,0x10,0x0,0x0,0x0,0x0,
-+0x0,0x0,0xf,0x0,0x0,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x6,0x18,0x0,0x0,0x40,0xe0,0x0,0x10,0xf8,0x10,0x10,0x20,0x20,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x0,0x1,0x1,0x2,0x4,0x8,0x0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x4,0x4,0x4,0x4,0x4,0x8,0x8,0x10,0x20,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x84,0x88,0x90,0xa0,0xc0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x20,0x10,0x10,0x10,0x10,0x10,0x11,0x12,0x14,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x10,0x1f,0x10,0x10,0x10,0x10,0x10,0x10,0x1f,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0xf0,0x20,0x20,0x20,0x20,0x40,0x40,0xe0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x10,0x1f,0x10,0x10,0x0,0x0,0x0,0x0,0x1,0x2,0x4,0x0,0x0,0x0,0x0,0x0,0x20,0xf0,0x20,0x20,0x20,0x40,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x20,0x3f,0x20,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x2,0x4,0x0,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x1,0x1f,0x9,0x9,0x9,0x9,0x7f,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x40,0xe0,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1f,0x0,0x2,0x1,0x1,0x1,0x1,0x7f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x40,0x80,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1f,0x0,0x0,0x7f,0x0,0x0,0x0,0x0,0x0,0x1,0x2,0x4,0x0,0x0,0x0,0x10,0xf8,0x10,0x10,0xf8,0x20,0x20,0x40,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x10,0x8,0x6,0x2,0x0,0x0,0x0,0x1,0x2,0x24,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x2,0x2,0x22,0x3f,0x20,0x20,0x0,0x0,0x0,0x0,0x1,0x2,0x4,0x8,0x0,0x8,0x4,0x12,0x28,0xf4,0x20,0x20,0x20,0x40,0x40,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x1,0x1,0x1,0xf,0x1,0x1,0x2,0x2,0x2,0x5,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0xf0,0x20,0x20,0x20,0x20,0x20,0x40,0x80,0x0,0x0,0x0,
-+0x0,0x0,0x4,0x4,0x4,0x7,0x8,0x10,0x21,0x1,0x2,0x4,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0xe0,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x2,0x2,0x4,0x4,0x8,0xf,0x10,0x10,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x40,0x40,0x20,0xe0,0x10,0x10,0x8,0x1c,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x7f,0x0,0x0,0x0,0x0,0x0,0xe0,0x10,0x10,0x10,0x20,0xc0,0x20,0x10,0x10,0x10,0xe0,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0xf8,0x8,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x2,0x2,0x4,0x4,0x8,0x10,0x10,0x20,0x20,0x7f,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x40,0x40,0x20,0x10,0x10,0x8,0x8,0xfc,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x7f,0x0,0x0,0x0,0x0,0x0,0xf8,0x8,0x8,0x0,0x40,0xc0,0x40,0x0,0x8,0x8,0xf8,0x0,0x0,0x0,0x0,
-+0x0,0x3f,0x20,0x20,0x0,0x0,0x1,0x2,0x4,0x8,0x10,0x3f,0x0,0x0,0x0,0x0,0x0,0xf8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x8,0x8,0xf8,0x0,0x0,0x0,0x0,
-+0x0,0x70,0x20,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0x1c,0x8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0x1c,0x0,0x0,0x0,0x0,
-+0x0,0x7,0x8,0x10,0x20,0x28,0x2f,0x28,0x20,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x10,0x8,0x28,0xe8,0x28,0x8,0x10,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x3,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x3,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x71,0x21,0x22,0x24,0x28,0x38,0x24,0x22,0x21,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0xe0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x2,0x2,0x4,0x4,0x8,0x8,0x10,0x10,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x8,0x1c,0x0,0x0,0x0,0x0,
-+0x0,0x60,0x30,0x30,0x28,0x28,0x24,0x24,0x22,0x22,0x21,0x70,0x0,0x0,0x0,0x0,0x0,0xc,0x18,0x18,0x28,0x28,0x48,0x48,0x88,0x88,0x8,0x1c,0x0,0x0,0x0,0x0,
-+0x0,0x60,0x30,0x28,0x24,0x22,0x21,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0x1c,0x8,0x8,0x8,0x8,0x8,0x88,0x48,0x28,0x18,0xc,0x0,0x0,0x0,0x0,
-+0x0,0x1f,0x10,0x10,0x0,0x4,0x7,0x4,0x0,0x10,0x10,0x1f,0x0,0x0,0x0,0x0,0x0,0xf8,0x8,0x8,0x0,0x20,0xe0,0x20,0x0,0x8,0x8,0xf8,0x0,0x0,0x0,0x0,
-+0x0,0x7,0x8,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x10,0x8,0x8,0x8,0x8,0x8,0x10,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0xfc,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x1c,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0xe0,0x10,0x8,0x8,0x10,0xe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x10,0x8,0x4,0x2,0x4,0x8,0x10,0x20,0x7f,0x0,0x0,0x0,0x0,0x0,0xf8,0x8,0x8,0x0,0x0,0x0,0x0,0x0,0x8,0x8,0xf8,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x41,0x41,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x3,0x0,0x0,0x0,0x0,0x0,0xfc,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x6,0x9,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x3,0x0,0x0,0x0,0x0,0x0,0x40,0xa0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x3,0x1,0xf,0x11,0x21,0x21,0x21,0x11,0xf,0x1,0x3,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0xe0,0x10,0x8,0x8,0x8,0x10,0xe0,0x0,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x70,0x10,0x8,0x4,0x2,0x1,0x2,0x4,0x8,0x10,0x70,0x0,0x0,0x0,0x0,0x0,0x1c,0x10,0x20,0x40,0x80,0x0,0x80,0x40,0x20,0x10,0x1c,0x0,0x0,0x0,0x0,
-+0x0,0x43,0x21,0x11,0x11,0x11,0x11,0xf,0x1,0x1,0x1,0x3,0x0,0x0,0x0,0x0,0x0,0x84,0x8,0x10,0x10,0x10,0x10,0xe0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x7,0x8,0x10,0x20,0x20,0x20,0x20,0x10,0x48,0x44,0x7c,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x10,0x8,0x8,0x8,0x8,0x10,0x24,0x44,0x7c,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x7,0x8,0x10,0x10,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0xc0,0x40,0x40,0x40,0x40,0x40,0xd0,0x20,0x0,0x0,0x0,0x0,
-+0x0,0x7,0x8,0x8,0x8,0xf,0x8,0x8,0x8,0x8,0xc,0xb,0x8,0x8,0x8,0x0,0x0,0x80,0x40,0x40,0x80,0x0,0xc0,0x20,0x20,0x20,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0xc,0x12,0x22,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x3,0x4,0x2,0x1,0x2,0x4,0x8,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x0,0x0,0x80,0x40,0x20,0x20,0x20,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x3,0x4,0x4,0x2,0x1,0x2,0x4,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x0,0x0,0x80,0x0,0x0,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x2,0x4,0x4,0x3,0x2,0x4,0x8,0x8,0x8,0x4,0x3,0x0,0x0,0x3,0x0,0x0,0x0,0x40,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x20,0xc0,0x0,
-+0x0,0x0,0x0,0x1,0xa,0x14,0x4,0x4,0x4,0x4,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0,
-+0x0,0x3,0x4,0x8,0x8,0x8,0xf,0x8,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x20,0x20,0x20,0xe0,0x20,0x20,0x20,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x3,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x80,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x18,0x8,0x8,0xd,0xa,0x9,0x8,0x8,0x1c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x30,0x40,0x80,0x0,0x0,0x0,0x80,0x40,0x70,0x0,0x0,0x0,0x0,
-+0x4,0xa,0x2,0x1,0x1,0x1,0x3,0x2,0x2,0x4,0x4,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x50,0x50,0x20,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0xc,0xb,0x8,0x8,0x8,0x0,0x0,0x0,0x0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xd0,0x20,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x18,0x8,0x4,0x4,0x4,0x2,0x2,0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x10,0x20,0x20,0x20,0x40,0x40,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x4,0x8,0x7,0x8,0x8,0x7,0x4,0x8,0x8,0x8,0x7,0x0,0x2,0x1,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0xc0,0x20,0x20,0xc0,0x0,
-+0x0,0x0,0x0,0x7,0x8,0x10,0x10,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x20,0x20,0x20,0x20,0x20,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1f,0x24,0x4,0x4,0x4,0x4,0x4,0x8,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf8,0x40,0x40,0x40,0x40,0x40,0x40,0x50,0x20,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x7,0x8,0x10,0x10,0x10,0x10,0x18,0x14,0x13,0x10,0x10,0x10,0x0,0x0,0x0,0x0,0x80,0x40,0x20,0x20,0x20,0x20,0x20,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x7,0x8,0x10,0x10,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x40,0x20,0x20,0x20,0x20,0x20,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x7,0x9,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x8,0x14,0x4,0x4,0x4,0x4,0x4,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x7,0x9,0x11,0x11,0x11,0x11,0x11,0x9,0x7,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0xc0,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x8,0x14,0x4,0x2,0x2,0x1,0x1,0x2,0x4,0x8,0x8,0x10,0x0,0x0,0x0,0x0,0x10,0x20,0x20,0x40,0x80,0x0,0x0,0x80,0x80,0x40,0x50,0x20,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x11,0x29,0x9,0x9,0x9,0x9,0x9,0x9,0x7,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x40,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x4,0x8,0x11,0x11,0x11,0x11,0x11,0xa,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x20,0x10,0x10,0x10,0x10,0x10,0xa0,0x40,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x2,0x2,0x4,0x4,0x8,0xf,0x10,0x10,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x40,0x40,0x20,0xe0,0x10,0x10,0x8,0x1c,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x7f,0x0,0x0,0x0,0x0,0x0,0xf8,0x8,0x8,0x0,0x0,0xe0,0x10,0x8,0x8,0x10,0xe0,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x7f,0x0,0x0,0x0,0x0,0x0,0xe0,0x10,0x8,0x8,0x10,0xe0,0x10,0x8,0x8,0x10,0xe0,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0xf8,0x8,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1f,0x4,0x4,0x4,0x4,0x4,0x8,0x8,0x10,0x3f,0x20,0x0,0x0,0x0,0x0,0x0,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xf8,0x8,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x7f,0x0,0x0,0x0,0x0,0x0,0xf8,0x8,0x8,0x0,0x20,0xe0,0x20,0x0,0x8,0x8,0xf8,0x0,0x0,0x0,0x0,
-+0x8,0x0,0x7f,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x7f,0x0,0x0,0x0,0x0,0x20,0x0,0xf8,0x8,0x8,0x20,0xe0,0x20,0x0,0x8,0x8,0xf8,0x0,0x0,0x0,0x0,
-+0x0,0x33,0x49,0x9,0x5,0x3,0x5,0x9,0x9,0x11,0x11,0x63,0x0,0x0,0x0,0x0,0x0,0x98,0x24,0x20,0x40,0x80,0x40,0x20,0x20,0x10,0x10,0x8c,0x0,0x0,0x0,0x0,
-+0x0,0x17,0x18,0x10,0x0,0x0,0x1,0x0,0x20,0x20,0x10,0xf,0x0,0x0,0x0,0x0,0x0,0xe0,0x10,0x8,0x8,0x10,0xe0,0x10,0x8,0x8,0x10,0xe0,0x0,0x0,0x0,0x0,
-+0x0,0x70,0x20,0x20,0x20,0x20,0x23,0x24,0x28,0x30,0x20,0x60,0x0,0x0,0x0,0x0,0x0,0xc,0x8,0x18,0x28,0xc8,0x8,0x8,0x8,0x8,0x8,0x1c,0x0,0x0,0x0,0x0,
-+0x4,0x74,0x23,0x20,0x20,0x20,0x23,0x24,0x28,0x30,0x20,0x60,0x0,0x0,0x0,0x0,0x40,0x4c,0x88,0x18,0x28,0xc8,0x8,0x8,0x8,0x8,0x8,0x1c,0x0,0x0,0x0,0x0,
-+0x0,0x70,0x20,0x21,0x22,0x3c,0x22,0x21,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0x60,0x80,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x20,0x38,0x0,0x0,0x0,0x0,
-+0x0,0x1f,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x28,0x10,0x0,0x0,0x0,0x0,0x0,0xf0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,
-+0x0,0x70,0x20,0x30,0x28,0x28,0x24,0x24,0x22,0x21,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0x1c,0x8,0x18,0x28,0x28,0x48,0x48,0x88,0x8,0x8,0x1c,0x0,0x0,0x0,0x0,
-+0x0,0x70,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0x0,0x1c,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0x1c,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x7,0x8,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x10,0x8,0x8,0x8,0x8,0x8,0x10,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0xf0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x20,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,0x0,0xe0,0x10,0x8,0x8,0x10,0xe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0xf,0x10,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0xf,0x0,0x0,0x0,0x0,0x0,0xd0,0x30,0x10,0x0,0x0,0x0,0x0,0x0,0x8,0x10,0xe0,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x41,0x41,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x3,0x0,0x0,0x0,0x0,0x0,0xfc,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x1c,0x8,0x8,0x4,0x4,0x2,0x1,0x0,0x1,0x12,0xc,0x0,0x0,0x0,0x0,0x0,0x1c,0x8,0x8,0x10,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x70,0x10,0x8,0x4,0x2,0x1,0x2,0x4,0x8,0x10,0x70,0x0,0x0,0x0,0x0,0x0,0x1c,0x10,0x20,0x40,0x80,0x0,0x80,0x40,0x20,0x10,0x1c,0x0,0x0,0x0,0x0,
-+0x0,0x3,0x1,0x1f,0x21,0x41,0x41,0x41,0x21,0x1f,0x1,0x3,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0xf0,0x8,0x4,0x4,0x4,0x8,0xf0,0x0,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x3f,0x0,0x0,0x0,0x0,0x0,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xf8,0x4,0x4,0x0,0x0,
-+0x0,0x38,0x10,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x38,0x10,0x10,0x10,0x10,0x30,0xd0,0x10,0x10,0x10,0x38,0x0,0x0,0x0,0x0,
-+0x0,0x73,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x7f,0x0,0x0,0x0,0x0,0x0,0x9c,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0xfc,0x0,0x0,0x0,0x0,
-+0x0,0x73,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x7f,0x0,0x0,0x0,0x0,0x0,0x9c,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0xfc,0x4,0x4,0x0,0x0,
-+0x0,0x3e,0x24,0x4,0x4,0x7,0x4,0x4,0x4,0x4,0x4,0xf,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x8,0x4,0x4,0x4,0x8,0xf0,0x0,0x0,0x0,0x0,
-+0x0,0x70,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x20,0x7f,0x0,0x0,0x0,0x0,0x0,0x1c,0x8,0x8,0x8,0x8,0x88,0x48,0x48,0x48,0x88,0x1c,0x0,0x0,0x0,0x0,
-+0x0,0x1c,0x8,0x8,0x8,0xf,0x8,0x8,0x8,0x8,0x8,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x10,0x8,0x8,0x8,0x10,0xe0,0x0,0x0,0x0,0x0,
-+0x0,0x2f,0x30,0x20,0x0,0x0,0x1,0x0,0x0,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0xe0,0x10,0x8,0x4,0x4,0xfc,0x4,0x4,0x8,0x10,0xe0,0x0,0x0,0x0,0x0,
-+0x0,0x71,0x22,0x24,0x24,0x24,0x3c,0x24,0x24,0x24,0x22,0x71,0x0,0x0,0x0,0x0,0x0,0xf0,0x8,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x8,0xf0,0x0,0x0,0x0,0x0,
-+0x0,0x3,0x4,0x8,0x8,0x4,0x3,0x0,0x3,0x4,0x8,0x38,0x0,0x0,0x0,0x0,0x0,0xfc,0x8,0x8,0x8,0x8,0xf8,0x88,0x8,0x8,0x8,0x1c,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x7,0x8,0x0,0xf,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x40,0x40,0xc0,0x40,0x40,0xd0,0x20,0x0,0x0,0x0,0x0,
-+0x0,0x7,0x8,0x10,0x17,0x18,0x10,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x20,0xc0,0x0,0x0,0x80,0x40,0x20,0x20,0x20,0x20,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1f,0x8,0x8,0x8,0xf,0x8,0x8,0x8,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x40,0x40,0x80,0x40,0x40,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1f,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x1c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x7,0x2,0x2,0x2,0x2,0x4,0x4,0x8,0x1f,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xf0,0x10,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x7,0x8,0x10,0x10,0x1f,0x10,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x20,0x20,0xe0,0x0,0x0,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x4,0x0,0x7,0x8,0x10,0x10,0x1f,0x10,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x80,0x40,0x20,0x20,0xe0,0x0,0x0,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x33,0x9,0x9,0x5,0x7,0x9,0x9,0x11,0x23,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x98,0x20,0x20,0x40,0xc0,0x20,0x20,0x10,0x88,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0xb,0xc,0x8,0x0,0x1,0x0,0x0,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x20,0x20,0xc0,0x20,0x20,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x38,0x10,0x10,0x10,0x11,0x12,0x14,0x18,0x30,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70,0x20,0x60,0xa0,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,
-+0x0,0x4,0x3,0x38,0x10,0x10,0x10,0x11,0x12,0x14,0x18,0x30,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x70,0x20,0x60,0xa0,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1c,0x8,0x8,0x9,0xe,0x9,0x8,0x8,0x1c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x60,0x80,0x80,0x0,0x0,0x0,0x80,0x90,0x60,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0xf,0x4,0x4,0x4,0x4,0x4,0x14,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x38,0x10,0x18,0x14,0x12,0x12,0x11,0x10,0x38,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x38,0x10,0x30,0x50,0x90,0x90,0x10,0x10,0x38,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1c,0x8,0x8,0x8,0xf,0x8,0x8,0x8,0x1c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70,0x20,0x20,0x20,0xe0,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x3,0x4,0x8,0x8,0x8,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x20,0x20,0x20,0x20,0x20,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1f,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x1c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xe0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0xb,0x1c,0x8,0x8,0x8,0x8,0xc,0xb,0x8,0x8,0x8,0x1c,0x0,0x0,0x0,0x0,0x80,0x40,0x20,0x20,0x20,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x7,0x8,0x10,0x10,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x40,0x0,0x0,0x0,0x20,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1f,0x11,0x1,0x1,0x1,0x1,0x1,0x1,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1c,0x8,0x8,0x4,0x4,0x4,0x2,0x1,0x1,0x2,0x14,0x8,0x0,0x0,0x0,0x0,0x70,0x20,0x20,0x40,0x40,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x1,0xd,0x13,0x11,0x11,0x11,0x11,0x13,0xd,0x1,0x1,0x3,0x0,0x0,0x0,0x0,0x0,0x60,0x90,0x10,0x10,0x10,0x10,0x90,0x60,0x0,0x0,0x80,0x0,
-+0x0,0x0,0x0,0x1c,0x8,0x4,0x2,0x1,0x2,0x4,0x8,0x1c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70,0x20,0x40,0x80,0x0,0x80,0x40,0x20,0x70,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1c,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xf0,0x10,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1c,0x8,0x8,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x40,0x40,0x40,0xc0,0x40,0x40,0x40,0xe0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x3b,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xb8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xf8,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x3b,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xb8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xf8,0x8,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x3c,0x28,0x8,0x8,0xf,0x8,0x8,0x8,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x20,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x38,0x10,0x10,0x10,0x1f,0x10,0x10,0x10,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x38,0x10,0x10,0x10,0x10,0x90,0x90,0x90,0x38,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x1c,0x8,0x8,0x8,0xf,0x8,0x8,0x8,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x20,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x7,0x8,0x0,0x0,0x1,0x0,0x8,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x20,0x20,0xe0,0x20,0x20,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x38,0x11,0x12,0x12,0x1e,0x12,0x12,0x11,0x38,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x3,0x4,0x4,0x4,0x3,0x1,0x2,0xa,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x20,0x20,0x20,0xe0,0x20,0x20,0x20,0x70,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x7,0x0,0x0,0x7,0x8,0x8,0x8,0x8,0x8,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x0,0x40,0xc0,0x40,0x40,0x40,0x40,0xc0,0x60,0x0,0x0,0x0,
-+0x0,0x0,0x1,0x2,0x0,0x7,0x8,0x8,0x8,0x8,0x8,0x8,0x7,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x40,0xc0,0x40,0x40,0x40,0x40,0xc0,0x60,0x0,0x0,0x0,
-+0x0,0x4,0x2,0x1,0x0,0x7,0x8,0x8,0x8,0x8,0x8,0x8,0x7,0x0,0x0,0x0,0x0,0x40,0x80,0x0,0x0,0x40,0xc0,0x40,0x40,0x40,0x40,0xc0,0x60,0x0,0x0,0x0,
-+0x0,0x2,0x1,0x0,0x0,0x7,0x8,0x8,0x8,0x8,0x8,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x40,0xc0,0x40,0x40,0x40,0x40,0xc0,0x60,0x0,0x0,0x0,
-+0x0,0x0,0x7,0x0,0x0,0x3,0x4,0x8,0xf,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x0,0x80,0x40,0x20,0xe0,0x0,0x0,0x20,0xc0,0x0,0x0,0x0,
-+0x0,0x0,0x1,0x2,0x0,0x3,0x4,0x8,0xf,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x80,0x40,0x20,0xe0,0x0,0x0,0x40,0x80,0x0,0x0,0x0,
-+0x0,0x4,0x2,0x1,0x0,0x3,0x4,0x8,0xf,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x40,0x80,0x0,0x0,0x80,0x40,0x20,0xe0,0x0,0x0,0x20,0xc0,0x0,0x0,0x0,
-+0x0,0x2,0x1,0x0,0x0,0x3,0x4,0x8,0xf,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x80,0x40,0x20,0xe0,0x0,0x0,0x20,0xc0,0x0,0x0,0x0,
-+0x0,0x0,0x3,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x2,0x4,0x0,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x4,0x2,0x1,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x2,0x1,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x7,0x0,0x3,0x4,0x8,0x8,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0xc0,0x0,0x80,0x40,0x20,0x20,0x20,0x20,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x1,0x2,0x0,0x3,0x4,0x8,0x8,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x80,0x40,0x20,0x20,0x20,0x20,0x40,0x80,0x0,0x0,0x0,
-+0x0,0x4,0x2,0x1,0x0,0x3,0x4,0x8,0x8,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x40,0x80,0x0,0x0,0x80,0x40,0x20,0x20,0x20,0x20,0x40,0x80,0x0,0x0,0x0,
-+0x0,0x2,0x1,0x0,0x0,0x3,0x4,0x8,0x8,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x80,0x40,0x20,0x20,0x20,0x20,0x40,0x80,0x0,0x0,0x0,
-+0x0,0x0,0xf,0x0,0x0,0x8,0x8,0x8,0x8,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0xe0,0x0,0x0,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0xb0,0x0,0x0,0x0,
-+0x0,0x0,0x1,0x2,0x0,0x8,0x8,0x8,0x8,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0xb0,0x0,0x0,0x0,
-+0x0,0x8,0x5,0x2,0x0,0x10,0x10,0x10,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x40,0x40,0x40,0x40,0x40,0x40,0xc0,0x60,0x0,0x0,0x0,
-+0x0,0x2,0x1,0x0,0x0,0x8,0x8,0x8,0x8,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0xb0,0x0,0x0,0x0,
-+0x0,0xf,0x0,0x2,0x0,0x8,0x8,0x8,0x8,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0xe0,0x0,0x80,0x0,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0xb0,0x0,0x0,0x0,
-+0x0,0x1,0x2,0x0,0x2,0x8,0x8,0x8,0x8,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x80,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0xb0,0x0,0x0,0x0,
-+0x4,0x2,0x1,0x0,0x2,0x8,0x8,0x8,0x8,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x40,0x80,0x0,0x0,0x80,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0xb0,0x0,0x0,0x0,
-+0x2,0x1,0x0,0x0,0x2,0x8,0x8,0x8,0x8,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x80,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0xb0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x2,0x0,0x8,0x8,0x8,0x8,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0xb0,0x0,0x0,0x0,
-+0x0,0x1,0x2,0x4,0x0,0x3,0x4,0x8,0xf,0x8,0x8,0x4,0x3,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x0,0x80,0x40,0x20,0xe0,0x0,0x0,0x20,0xc0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x7,0x8,0x8,0x8,0x8,0x8,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0xc0,0x40,0x40,0x40,0x40,0xc0,0x60,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x7,0x8,0x8,0x8,0x8,0x8,0x7,0x0,0x0,0x8,0x7,0x0,0x0,0x0,0x0,0x0,0xa0,0x60,0x20,0x20,0x20,0x60,0xa0,0x20,0x20,0x40,0x80,0x0,
-+0x0,0x0,0x1,0x2,0x0,0x1a,0xd,0x9,0x9,0x9,0x9,0x9,0x9,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0xc0,0x20,0x20,0x20,0x20,0x20,0x20,0x30,0x0,0x0,0x0,
-+0x0,0x0,0x1,0x2,0x0,0xd,0x6,0x4,0x4,0x4,0x4,0x4,0x4,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x60,0x0,0x0,0x0,
-+0x0,0x4,0x2,0x1,0x0,0xd,0x6,0x4,0x4,0x4,0x4,0x4,0x4,0x0,0x0,0x0,0x0,0x40,0x80,0x0,0x0,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x60,0x0,0x0,0x0,
-+0x0,0x2,0x1,0x0,0x0,0xd,0x6,0x4,0x4,0x4,0x4,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x60,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x8,0x8,0x10,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0xf8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x10,0x10,0xa0,0x40,
-+0x0,0x4,0x4,0x8,0x1f,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x3,0xc,0x30,0x0,0x0,0x0,0x0,0x0,0xf8,0x8,0x8,0x10,0x10,0xa0,0x40,0xa0,0x10,0x10,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x3f,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x3f,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xf,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc,0x0,0x0,
-+0x0,0x4,0x4,0x8,0x1f,0x1,0x1,0x1,0x1,0x2,0x2,0x4,0x8,0x11,0x20,0x0,0x0,0x0,0x0,0x0,0xf8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x10,0x10,0xa0,0x40,
-+0x0,0x1,0x1,0x1,0x1,0x7f,0x1,0x1,0x2,0x2,0x4,0x8,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc,0x0,0x0,0x0,0x0,0x0,0x20,0xf0,0x8,0x0,0x0,
-+0x0,0x0,0x3f,0x0,0x0,0x1,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0xc0,0x40,0x80,0x0,0xf8,0x8,0x8,0x8,0x8,0x8,0x10,0x10,0xa0,0x40,
-+0x0,0x1,0x9,0x9,0x11,0x1f,0x1,0x1,0x1,0x2,0x2,0x4,0x4,0x8,0x10,0x20,0x0,0x0,0x0,0x0,0x0,0xf8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x10,0x50,0x20,
-+0x0,0x0,0x2,0x2,0x4,0x4,0x8,0x8,0x11,0x8,0x8,0x4,0x4,0x2,0x2,0x0,0x0,0x0,0x20,0x20,0x40,0x40,0x80,0x80,0x0,0x80,0x80,0x40,0x40,0x20,0x20,0x0,
-+0x0,0x0,0x7f,0x2,0x2,0x4,0x8,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc,0x0,0x0,0x0,0x0,0xf0,0x10,0x10,0x10,0x10,0x10,0x20,0xa0,0x40,
-+0x0,0x0,0x3f,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x80,0x0,0x0,0x0,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x4,0x4,0x4,0x4,0x4,0x4,0x8,0x9,0xe,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0xa0,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x0,0x0,0x0,0x0,0x1,0x1,0x2,0x4,0x2,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x40,0x40,0x0,
-+0x0,0x0,0x7f,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x11,0x11,0x11,0x11,0x11,0x11,0x1f,0x1,0x1,0x1,0x7f,0x0,0x0,0x0,0x0,0x0,0x10,0x10,0x10,0x10,0x10,0x10,0xf0,0x0,0x0,0x0,0xfc,0x0,0x0,
-+0x0,0x0,0x0,0x1,0x2,0x4,0x8,0x11,0x3,0x5,0x9,0x11,0x1,0x1,0x1,0x1,0x0,0x40,0x80,0x0,0x0,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x1f,0x0,0x0,0x0,0x1f,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x80,0x0,0x0,0xf8,0x8,0x8,0x8,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0xf,0x8,0x8,0x8,0xa,0x9,0x8,0x8,0x8,0x8,0x8,0xf,0x0,0x0,0x0,0x0,0xe0,0x20,0x20,0x20,0x20,0x20,0xa0,0x20,0x20,0x20,0x20,0xe0,0x0,0x0,
-+0x0,0x0,0x3f,0x4,0x4,0x4,0x4,0x4,0x4,0x5,0x4,0x4,0x4,0x4,0x4,0x4,0x0,0x0,0xf0,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0xc0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x2,0x2,0x2,0x7f,0x4,0x4,0x4,0xf,0x0,0x0,0x0,0x0,0x0,0x2,0x1,0x0,0x0,0x0,0x0,0xfc,0x0,0x0,0x0,0xf0,0x10,0x10,0x20,0x20,0x40,0x80,0x0,
-+0x0,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x4,0x4,0x8,0x10,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x20,0xf0,0x8,0x0,0x0,
-+0x0,0x10,0x8,0x4,0x2,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x7f,0x1,0x1,0x1,0xf,0x10,0x20,0x20,0x20,0x20,0x10,0xf,0x0,0x0,0x0,0x0,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x10,0xe0,0x0,0x0,
-+0x0,0x1,0x1,0x1,0x7f,0x1,0x1,0xf,0x10,0x20,0x20,0x20,0x20,0x10,0xf,0x0,0x0,0x0,0x0,0x0,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x10,0xe0,0x0,
-+0x0,0x0,0x8,0x8,0x8,0x7f,0x8,0x8,0x8,0x8,0x8,0x9,0x8,0x7,0x0,0x0,0x0,0x0,0x40,0x40,0x40,0xfc,0x40,0x40,0x40,0x80,0x80,0x0,0x0,0xf0,0x0,0x0,
-+0x0,0x0,0x7f,0x9,0x9,0x11,0x1f,0x1,0x1,0x1,0x2,0x2,0x4,0x8,0x10,0x0,0x0,0x0,0xfc,0x0,0x0,0x0,0xf8,0x8,0x8,0x8,0x8,0x8,0x10,0x10,0x20,0x0,
-+0x0,0x0,0x1c,0x4,0x4,0x4,0x2,0x2,0x2,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x20,0x18,0x0,
-+0x0,0x2,0x2,0x4,0x4,0x8,0x8,0x1f,0x1,0x2,0x4,0x8,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x20,0x40,0x40,0x80,0x0,0x0,0x40,0x20,0xf0,0x10,0x0,0x0,
-+0x0,0x0,0x0,0x1f,0x0,0x0,0x4,0x2,0x1,0x0,0x0,0x1,0x2,0x4,0x8,0x0,0x0,0x0,0x0,0xf0,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x40,0x20,0x0,0x0,0x0,
-+0x0,0x3f,0x8,0x8,0x8,0x10,0x10,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x20,0x20,0x20,0x40,0x40,0xf8,0x8,0x8,0x8,0x10,0x10,0x20,0x40,0x0,
-+0x0,0x8,0x8,0x8,0x8,0x10,0x10,0x10,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf8,0x8,0x8,0x8,0x10,0x10,0x20,0x0,
-+0x0,0x2,0x2,0x2,0x2,0x7f,0x2,0x2,0x2,0x4,0x4,0x4,0x8,0x10,0x60,0x0,0x0,0x0,0x0,0x0,0x0,0xfc,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x7c,0x0,
-+0x0,0x0,0x1,0x1,0x1,0x2,0x2,0x4,0x4,0x8,0x10,0x20,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,
-+0x0,0x0,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x8,0x8,0x10,0x60,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x84,0x84,0x7c,0x0,
-+0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x8,0x4,0x2,0x1,0x0,0x0,0x1,0x2,0x4,0x18,0x60,0x0,0x0,0x10,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x40,0x20,0x10,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x78,0x88,0x8,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x73,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x9c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x73,0x73,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x9c,0x9c,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x1,0x0,0x0,0x1,0x1,0x1,0x0,0x0,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1,0x1,0x1,0x0,0x0,0x1,0x1,0x1,0x0,0x0,0x1,0x1,0x1,0x0,0x0,0x0,0x80,0x80,0x80,0x0,0x0,0x80,0x80,0x80,0x0,0x0,0x80,0x80,0x80,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xee,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xee,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xee,0xee,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xee,0xee,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x0,0x1,0x1,0x1,0x0,0x1,0x1,0x1,0x0,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x0,0x1,0x1,0x1,0x0,0x1,0x1,0x1,0x0,0x1,0x1,0x1,0x0,0x80,0x80,0x80,0x0,0x80,0x80,0x80,0x0,0x80,0x80,0x80,0x0,0x80,0x80,0x80,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xff,0xff,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x3,0x3,0x3,0x3,0x3,0x3,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xff,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xff,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xff,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xff,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0xff,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x0,0x3,0x3,0x3,0x3,0x3,0x3,0x7f,0x7f,0x3,0x3,0x3,0x3,0x3,0x3,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xff,0xff,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xff,0xff,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x8,0x8,0x8,0x8,0x8,0x9,0x8,0xff,0x9,0x9,0x8,0x8,0x8,0x9,0xe,0x8,0x0,0x10,0x30,0x40,0x80,0x0,0x4,0xfe,0x0,0x0,0x80,0x40,0x20,0x1c,0x8,0x0,
-+0x20,0x20,0x20,0x27,0xfc,0x24,0x24,0x27,0x24,0x24,0x3c,0xe6,0x45,0x4,0x8,0x10,0x20,0x28,0x24,0xfe,0x20,0x20,0x24,0xa4,0xa8,0xa8,0x90,0x90,0x30,0x4a,0x8a,0x6,
-+0x0,0x7,0x8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0xc0,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0xc0,0x0,
-+0x0,0x1f,0x10,0x10,0x10,0x10,0x17,0x18,0x10,0x0,0x0,0x0,0x10,0x10,0xf,0x0,0x0,0xf0,0x0,0x0,0x0,0x0,0xc0,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0xc0,0x0,
-+0x0,0x7,0x8,0x10,0x10,0x0,0x0,0x0,0x3,0x4,0x8,0x10,0x10,0x10,0x1f,0x0,0x0,0xc0,0x20,0x10,0x10,0x10,0x10,0xe0,0x0,0x0,0x0,0x0,0x10,0x10,0xf0,0x0,
-+0x0,0x7,0x8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x8,0x7,0x0,0x0,0xc0,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0xc0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x2f,0xf9,0xa9,0xaa,0xaa,0xac,0xaa,0xaa,0xa9,0xe9,0xad,0xa,0x8,0x8,0x8,0x4,0x7e,0x4,0x4,0x14,0x7c,0x54,0x54,0x54,0x54,0x74,0x54,0x4,0x4,0x14,0xc,
-+0x0,0x7f,0x44,0x48,0x48,0x51,0x49,0x49,0x45,0x45,0x45,0x69,0x51,0x40,0x40,0x40,0x4,0xfe,0x8,0x8,0x28,0xf8,0x28,0x28,0x28,0x28,0x28,0xe8,0x28,0x8,0x28,0x10,
-+0x10,0x10,0x10,0x11,0x13,0xfc,0x11,0x11,0x12,0x10,0x17,0x1c,0xf0,0x40,0x1,0x6,0x40,0x40,0x90,0x8,0xfc,0x4,0x10,0xf8,0x40,0x44,0xfe,0x40,0xa0,0x90,0xe,0x4,
-+0x10,0x10,0x10,0x11,0xff,0x10,0x11,0x15,0x1a,0x30,0xd7,0x10,0x10,0x10,0x51,0x26,0x40,0x40,0x90,0x8,0xfc,0x4,0x10,0xf8,0x40,0x44,0xfe,0x40,0xa0,0x90,0xe,0x4,
-+0x0,0x0,0x8,0x7f,0x48,0x48,0x49,0x49,0x48,0x48,0x48,0x78,0x48,0x1,0x2,0x4,0x90,0x90,0x94,0xfe,0x90,0x90,0x8,0x8,0x90,0x90,0x60,0x40,0xa0,0x10,0xe,0x4,
-+0x0,0x0,0x8,0x7d,0x4b,0x48,0x49,0x49,0x4a,0x48,0x4f,0x78,0x48,0x0,0x1,0x6,0x40,0x40,0x90,0x8,0xfc,0x4,0x10,0xf8,0x40,0x44,0xfe,0x40,0xa0,0x90,0xe,0x4,
-+0x2,0x1,0xff,0x0,0x1f,0x10,0x10,0x10,0x1f,0x5,0xc,0x14,0x24,0xc5,0x6,0x4,0x0,0x4,0xfe,0x10,0xf8,0x10,0x10,0x10,0xf0,0x8,0x90,0x60,0x30,0xe,0x4,0x0,
-+0x10,0x10,0x25,0x7f,0x45,0x44,0x45,0x7c,0x44,0x45,0x45,0x45,0x7d,0x45,0x0,0x0,0x20,0x20,0x24,0x24,0xfc,0x0,0xfc,0x4,0x4,0xfc,0x4,0x0,0x2,0x2,0xfe,0x0,
-+0x0,0x0,0x1f,0x10,0x93,0x52,0x53,0x10,0x37,0x54,0xd7,0x10,0x24,0x24,0x47,0x4,0x80,0x44,0xfe,0x0,0xf8,0x8,0xf8,0x0,0xbc,0xa4,0xbc,0x40,0x44,0x44,0xfc,0x4,
-+0x8,0xff,0x8,0x43,0x32,0x13,0x2,0xf3,0x11,0x13,0x14,0x12,0x16,0x1a,0x13,0x0,0x24,0xfe,0x20,0xf8,0x8,0xf8,0x8,0xf8,0x4,0xfe,0x44,0x44,0xa4,0x4,0xd4,0x8,
-+0x20,0x21,0x28,0x3c,0x53,0x90,0x15,0xfe,0x10,0x17,0x10,0x29,0x24,0x44,0x81,0x6,0x18,0xe0,0x40,0x48,0xfc,0xe0,0x5c,0x48,0x40,0xfe,0x90,0x10,0xa0,0x60,0x98,0x8,
-+0x4,0x4,0xff,0x4,0x4,0x0,0x8,0x4,0x4,0x2,0x1,0x2,0x4,0x8,0x30,0xc0,0x40,0x44,0xfe,0x40,0x40,0x20,0x20,0x40,0x40,0x80,0x0,0x80,0x40,0x30,0xe,0x4,
-+0x0,0x5,0xff,0x11,0x11,0x21,0x24,0x7f,0xa4,0x27,0x25,0x24,0x3c,0x24,0x0,0x0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0xfc,0x10,0xfe,0x10,0x90,0x90,0x10,0x50,0x20,
-+0x0,0x3f,0x11,0x9,0x7f,0x42,0x82,0x7f,0x4,0x7,0xa,0x9,0x10,0x11,0x22,0xc,0x78,0x80,0x10,0x20,0xfe,0x2,0x4,0xf8,0x0,0xf0,0x20,0x40,0x80,0x60,0x1c,0x8,
-+0x4,0x7a,0x49,0x48,0x57,0x60,0x51,0x4a,0x4c,0x4b,0x6a,0x52,0x42,0x42,0x4f,0x40,0x4,0x8,0x10,0x4,0xfe,0xa0,0x10,0x8,0x8,0xfc,0xa8,0xa8,0xa8,0xa8,0xfe,0x0,
-+0x28,0x28,0xfe,0x29,0x39,0x12,0x7c,0x57,0x54,0x7c,0x11,0xfe,0x10,0x10,0x10,0x13,0x40,0x20,0x0,0xfe,0x2,0x44,0x40,0xfe,0x88,0x88,0x8,0x90,0x60,0x50,0x8c,0x4,
-+0x10,0x1f,0x20,0x5f,0x80,0x3f,0x2,0x3f,0x22,0x4,0xff,0x8,0x19,0x6,0x9,0x30,0x4,0xfe,0x0,0xf8,0x0,0xf8,0x8,0xe8,0x28,0x8,0xf8,0x88,0x8,0xa,0x8a,0x44,
-+0x2,0x1,0x7f,0x40,0x82,0x2,0x2,0xff,0x4,0x8,0x18,0x6,0x1,0x2,0xc,0x30,0x0,0x0,0xfe,0x2,0x4,0x0,0x4,0xfe,0x20,0x20,0x20,0x40,0x80,0x40,0x30,0x10,
-+0x8,0x8,0x8,0x17,0x10,0x31,0x52,0x94,0x1b,0x12,0x13,0x12,0x13,0x12,0x10,0x10,0x40,0x40,0x48,0xfc,0xa0,0x10,0x4e,0x44,0xf8,0x48,0xf8,0x48,0xf8,0x4a,0x42,0x3e,
-+0x10,0x10,0x10,0x13,0xfa,0x14,0x10,0x3f,0xd0,0x10,0x11,0x10,0x10,0x10,0x50,0x23,0x40,0x20,0x0,0xfe,0x2,0x44,0x40,0xfe,0x88,0x88,0x8,0x90,0x60,0x50,0x8c,0x4,
-+0x0,0x8,0x7f,0x48,0x49,0x48,0x4f,0x78,0x4b,0x4a,0x4a,0x4b,0x7a,0x4a,0x3,0x2,0x80,0x48,0xfc,0x0,0x10,0xa4,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x1,0x21,0x21,0x3f,0x0,0x3f,0x20,0x2f,0x20,0x20,0x3f,0x20,0x20,0x40,0x80,0x0,0x0,0x8,0x8,0xf8,0x0,0xfc,0x10,0xf8,0x80,0x88,0xfc,0x80,0x80,0x80,0x80,0x80,
-+0x4,0x3e,0x24,0x25,0x25,0x3e,0x24,0x27,0x24,0x3c,0x25,0x24,0x24,0x44,0x94,0x9,0x40,0x20,0x0,0xfe,0x2,0x44,0x40,0xfe,0x88,0x88,0x8,0x90,0x60,0x50,0x8c,0x4,
-+0x1,0x7f,0x41,0x82,0x7f,0x4,0xc,0x3,0x1c,0x1,0xff,0x5,0x9,0x11,0x61,0x1,0x0,0xfe,0x2,0x4,0xfc,0x20,0x40,0x80,0x70,0x4,0xfe,0x40,0x20,0x1c,0x8,0x0,
-+0x4,0x3e,0x24,0x27,0x24,0x3c,0x24,0x24,0x24,0x3c,0x24,0x24,0x24,0x45,0x96,0x8,0x40,0x20,0x4,0xfe,0x10,0xf8,0x90,0x90,0x90,0x90,0x90,0x90,0x92,0x12,0xe,0x0,
-+0x3f,0x20,0x3f,0x20,0x3f,0x0,0x6,0x78,0x40,0x40,0x40,0x46,0x58,0x60,0x0,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x0,0x4,0xfe,0x84,0x84,0x84,0xa4,0x94,0x88,0x80,0x80,
-+0x1,0x1,0x3f,0x21,0x21,0xff,0x2,0xc,0x30,0xc0,0x3f,0x24,0x24,0x24,0xff,0x0,0x0,0x8,0xfc,0x8,0x8,0xfe,0x80,0x60,0x1e,0x4,0xf8,0x48,0x48,0x48,0xfe,0x0,
-+0x0,0x0,0x7c,0x44,0x44,0x44,0x44,0x44,0x44,0x47,0x40,0x40,0x40,0x7f,0x40,0x0,0x0,0x4,0x7e,0x44,0x44,0x44,0x44,0x44,0x44,0xc4,0x4,0x4,0x4,0xfc,0x4,0x0,
-+0x8,0x8,0xa,0x7f,0x8,0x3f,0x8,0xff,0x10,0x1e,0x12,0x22,0x22,0x54,0x89,0x2,0x40,0x40,0x44,0x7e,0x88,0x8,0x48,0x48,0x48,0x50,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x8,0xa,0x7f,0x8,0x3e,0x9,0xfe,0x10,0x1e,0x22,0x4a,0x85,0x0,0x24,0x22,0x40,0x40,0x40,0x40,0x44,0xfe,0x8,0x48,0x50,0x20,0x50,0x8e,0x4,0x0,0x88,0x44,0x4,
-+0x10,0x20,0x7d,0x44,0x7c,0x45,0x7c,0x10,0xfe,0x28,0x55,0x92,0x7c,0x10,0x11,0x10,0x0,0x4,0xde,0x44,0x44,0x54,0xcc,0x44,0x44,0xcc,0x54,0x44,0x44,0x44,0x54,0x88,
-+0x20,0x10,0x13,0xfc,0x8,0x10,0x10,0x37,0x58,0x94,0x10,0x10,0x10,0x11,0x12,0x14,0x10,0x38,0xc0,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0xa0,0xa0,0x10,0xe,0x4,
-+0x12,0x12,0x12,0x2f,0x22,0x6f,0xa2,0x3f,0x24,0x27,0x24,0x24,0x28,0x33,0x20,0x20,0x10,0x10,0x10,0x94,0x3e,0xc4,0x24,0xa8,0x28,0xa8,0x90,0x90,0xa8,0x28,0x46,0x84,
-+0x2,0x4,0x1f,0x11,0x15,0x11,0x1f,0x11,0x15,0x11,0x1,0xff,0x2,0x4,0x18,0x60,0x0,0x10,0xf8,0x10,0x50,0x10,0xf0,0x10,0x50,0x10,0x4,0xfe,0x80,0x60,0x1c,0x8,
-+0x10,0x11,0x17,0x14,0x5d,0x54,0x57,0x94,0x15,0x14,0x10,0x1f,0x10,0x11,0x12,0x1c,0x80,0x4,0xfe,0x44,0x54,0x44,0xfc,0x44,0x54,0x4,0x40,0xfe,0xa0,0x10,0xe,0x4,
-+0x0,0x41,0x37,0x14,0x85,0x64,0x27,0xc,0x15,0x24,0xe0,0x2f,0x20,0x21,0x22,0x2c,0x80,0x4,0xfe,0x44,0x54,0x44,0xfc,0x44,0x54,0x4,0x40,0xfe,0xa0,0x10,0xe,0x4,
-+0x4,0x4,0xff,0x4,0x4,0x1f,0x11,0x11,0x11,0x1f,0x10,0x10,0x10,0x10,0xf,0x0,0x40,0x44,0xfe,0x40,0x50,0xf8,0x10,0x10,0x10,0xf0,0x10,0x0,0x4,0x4,0xfc,0x0,
-+0x10,0x13,0x12,0x12,0xfe,0x13,0x11,0x19,0x37,0xd1,0x11,0x12,0x12,0x15,0x58,0x20,0x44,0xe4,0x44,0x54,0x54,0xd4,0x14,0x54,0xf4,0x54,0x54,0x44,0x44,0x44,0x94,0x8,
-+0x10,0x10,0x11,0x11,0xfd,0x11,0x15,0x19,0x31,0xd1,0x12,0x12,0x12,0x14,0x58,0x20,0x0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x18,0xe,0x4,0x0,
-+0x0,0x0,0x9,0x7d,0x49,0x49,0x49,0x49,0x49,0x49,0x4a,0x7a,0x4a,0x4,0x8,0x10,0x0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x18,0xe,0x4,0x0,
-+0x0,0x8,0x7f,0x4a,0x4a,0x4a,0x4a,0x4a,0x4b,0x4a,0x4a,0x7a,0x4a,0x2,0x1,0x0,0x0,0x8,0xfc,0x48,0x48,0x48,0x48,0x48,0xf8,0x8,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x12,0x1f,0x28,0x45,0x80,0x3f,0x21,0x21,0x21,0x3f,0x20,0x20,0x20,0x20,0x1f,0x0,0x48,0x7c,0xa0,0x10,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x0,0x2,0x2,0xfe,0x0,
-+0x0,0x0,0x4,0x4,0x4,0x4,0x4,0x4,0x8,0x8,0x8,0x10,0x10,0x20,0x40,0x0,0x0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x20,0x10,0x8,0xe,0x4,0x0,
-+0x0,0x0,0x1f,0x10,0x90,0x57,0x54,0x14,0x34,0x57,0xd4,0x14,0x24,0x24,0x43,0x0,0x80,0x44,0xfe,0x0,0x4,0xfe,0x44,0x44,0x44,0xfc,0x4,0x0,0x2,0x2,0xfe,0x0,
-+0x0,0x0,0x3f,0x21,0x21,0x21,0x21,0x3f,0x20,0x20,0x20,0x20,0x20,0x20,0x1f,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x10,0x10,0xfc,0x13,0x10,0x14,0x19,0x31,0xd1,0x12,0x12,0x14,0x14,0x58,0x23,0xa0,0x90,0x90,0x84,0xfe,0x80,0x80,0xf8,0x8,0x8,0x90,0x60,0x20,0x50,0x8e,0x4,
-+0x4,0x7e,0x44,0x44,0x47,0x7c,0x10,0x11,0x5d,0x51,0x52,0x52,0x5c,0x74,0xc8,0x3,0xa0,0x90,0x90,0x84,0xfe,0x80,0x80,0xf8,0x8,0x8,0x90,0x60,0x20,0x50,0x8e,0x4,
-+0x28,0x28,0xff,0x29,0x39,0x11,0x7d,0x55,0x55,0x7d,0x11,0xff,0x11,0x11,0x10,0x10,0x0,0x4,0xfe,0x24,0x24,0x24,0x24,0xfc,0x4,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x10,0x11,0x11,0xfd,0x11,0x15,0x19,0x31,0xd1,0x11,0x11,0x11,0x11,0x50,0x20,0x0,0x4,0xfe,0x24,0x24,0x24,0x24,0xfc,0x4,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x10,0x15,0xff,0x11,0x7d,0x11,0xff,0x11,0x31,0x39,0x55,0x55,0x91,0x10,0x10,0x0,0x4,0xfe,0x24,0x24,0x24,0x24,0xfc,0x4,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x11,0x11,0x11,0x11,0xfd,0x11,0x11,0x11,0x11,0x1d,0xf1,0x40,0x0,0x0,0x3,0x4,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x50,0x48,0x86,0x2,
-+0x3f,0x1,0x7f,0x89,0x22,0x7f,0x22,0x3e,0x8,0x7f,0x49,0x7f,0x8,0x7f,0x8,0x9,0xf8,0x0,0xfe,0x24,0x8,0x7c,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0x88,0x18,
-+0x0,0x3f,0x24,0x24,0x3f,0x1,0x1,0x3f,0x1,0x1,0xff,0x2,0x4,0x8,0x1f,0x0,0x8,0xfc,0x48,0x48,0xf8,0x0,0x10,0xf8,0x0,0x4,0xfe,0x0,0x20,0x10,0xf8,0x8,
-+0x4,0x4,0xc,0x32,0x1,0x2,0xc,0x30,0xdf,0x11,0x11,0x1f,0x10,0x10,0x10,0xf,0x40,0x20,0x58,0x88,0x0,0x80,0x60,0x18,0xf6,0x10,0x10,0xf0,0x10,0x4,0x4,0xfc,
-+0x2,0x4,0x8,0x3f,0x20,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x3f,0x20,0x0,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,
-+0x10,0x10,0x10,0x10,0xfd,0x11,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x0,0x20,0x40,0x84,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0xff,0x1,0x2,0x4,0x1f,0x10,0x10,0x10,0x1f,0x10,0x10,0x10,0x10,0x1f,0x10,0x4,0xfe,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,0x10,0x10,0x10,0xf0,0x10,
-+0x10,0x17,0x14,0x14,0xff,0x14,0x10,0x1b,0x30,0xd0,0x1f,0x10,0x11,0x12,0x57,0x20,0x4,0xfe,0xa4,0xa4,0xfc,0x44,0x50,0xf8,0x40,0x44,0xfe,0x80,0x10,0x8,0xfc,0x4,
-+0x8,0x8,0xf,0x10,0x10,0x33,0x52,0x92,0x12,0x13,0x12,0x12,0x12,0x12,0x13,0x12,0x0,0x4,0xfe,0x40,0x88,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x4,0x7e,0x44,0x54,0x54,0x55,0x54,0x54,0x54,0x54,0x54,0x10,0x28,0x24,0x45,0x82,0x40,0x40,0x44,0x7e,0x88,0x8,0x48,0x48,0x48,0x50,0x50,0x20,0x50,0x8e,0x4,0x0,
-+0x4,0xe,0x78,0x8,0x8,0x7e,0x8,0x8,0xff,0x8,0x9,0x8,0x10,0x10,0x20,0x40,0x8,0xfc,0x20,0x28,0xfc,0x20,0x28,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x8,0x1c,0xf1,0x11,0x11,0xfd,0x11,0x39,0x35,0x50,0x51,0x97,0x10,0x10,0x10,0x10,0x20,0x44,0xfe,0x24,0x24,0xfc,0x24,0x44,0xfc,0xa0,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x0,0x12,0xf9,0x20,0x2f,0x20,0x24,0xfa,0x21,0x21,0x22,0x22,0x3c,0xe4,0x48,0x0,0x0,0x4,0x7e,0x10,0xd0,0x10,0x90,0xfc,0x10,0x10,0x90,0x50,0x50,0x14,0xfe,0x0,
-+0x1,0x9,0xfd,0x21,0x25,0x25,0x25,0xf5,0x25,0x29,0x21,0x22,0x3a,0xe2,0x44,0x8,0x0,0x4,0x7e,0x10,0x10,0x10,0x10,0x7c,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x0,
-+0x21,0x22,0x27,0x24,0xfe,0x25,0x24,0x2f,0x34,0xe6,0x25,0x24,0x24,0x28,0xb2,0x41,0x4,0x3e,0xa4,0xa4,0xa4,0xa4,0xc2,0xbc,0xa4,0xa4,0xa4,0x98,0x88,0x94,0xa4,0x42,
-+0x10,0x10,0x11,0x11,0xfd,0x11,0x11,0x15,0x19,0x31,0xd1,0x12,0x12,0x14,0x59,0x20,0x8,0x1c,0xe0,0x0,0x0,0xfc,0x4,0x48,0x48,0x50,0x30,0x20,0x50,0x8e,0x4,0x0,
-+0x8,0x12,0x3f,0x22,0x32,0x2a,0x22,0xfe,0x22,0x32,0x2a,0x22,0x22,0x22,0x4a,0x85,0x8,0x7c,0x48,0x48,0x48,0x86,0x0,0xfc,0x44,0x48,0x28,0x10,0x30,0x48,0x8e,0x4,
-+0x0,0x2b,0x28,0x24,0x45,0x43,0x85,0x7f,0x25,0x25,0x25,0x25,0x24,0x24,0x4c,0x83,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x50,0x48,0x86,0x2,
-+0x10,0x10,0x11,0x11,0xfd,0x11,0x31,0x39,0x55,0x51,0x91,0x12,0x12,0x14,0x19,0x10,0x8,0x1c,0xe0,0x0,0x0,0xfc,0x4,0x48,0x48,0x50,0x30,0x20,0x50,0x8e,0x4,0x0,
-+0x8,0x48,0x49,0x49,0x49,0x7d,0x41,0x41,0x79,0x49,0x49,0x4a,0x4a,0x4c,0x89,0x8,0x8,0x1c,0xe0,0x0,0x0,0xfc,0x4,0x48,0x48,0x50,0x30,0x20,0x50,0x8e,0x4,0x0,
-+0x10,0x10,0x10,0x10,0xfd,0x11,0x12,0x1c,0x33,0xd0,0x10,0x10,0x11,0x11,0x52,0x24,0x20,0xa0,0xa0,0x90,0x10,0xe,0x4,0x8,0xfc,0x88,0x88,0x88,0x8,0x8,0x28,0x10,
-+0x10,0x10,0x12,0x11,0xfc,0x13,0x14,0x18,0x30,0xd7,0x10,0x10,0x10,0x10,0x50,0x20,0x40,0x40,0x48,0x50,0x40,0xfc,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x8,0x8,0xa,0x11,0x10,0x37,0x30,0x50,0x90,0x1f,0x10,0x10,0x10,0x10,0x10,0x10,0x40,0x40,0x48,0x50,0x40,0xfc,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x40,0x20,0xf8,0x7,0x54,0x55,0xfd,0x25,0x25,0x25,0x3d,0xe5,0x26,0x4b,0x90,0x0,0x10,0x48,0xbe,0x40,0x54,0x54,0x7e,0x48,0x48,0x48,0x7e,0x48,0xa8,0x98,0x8,0x8,
-+0x1,0x21,0x19,0x9,0x1,0x3f,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x8,0x18,0x20,0x0,0xf8,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x2,0x2,0x2,0x2,0x3f,0x2,0x2,0x12,0x32,0x22,0x44,0x84,0x8,0x10,0x20,0x0,0x0,0x0,0x0,0x20,0xf0,0x20,0x20,0x30,0x2c,0x26,0x22,0x20,0x20,0xa0,0x40,0x0,
-+0x10,0x10,0x21,0x20,0x44,0xf8,0x11,0x20,0x40,0xfc,0x3,0x0,0x1c,0xe0,0x40,0x0,0x20,0x20,0x24,0xac,0xb0,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x8,0x8,0xa,0xff,0x8,0x8,0x7e,0x8,0xa,0xff,0x8,0x10,0x10,0x20,0x40,0x0,0x0,0x7c,0x44,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x8,0xa,0xff,0x8,0x7e,0x8,0xff,0x8,0x11,0x3f,0xd1,0x11,0x11,0x11,0x11,0x1,0x0,0x7c,0x48,0x50,0x58,0x44,0x64,0x58,0x50,0xf0,0x10,0x10,0x10,0x50,0x20,0x0,
-+0x11,0x11,0x11,0x17,0xf9,0x11,0x37,0x39,0x55,0x57,0x91,0x11,0x12,0x12,0x14,0x10,0x0,0x3e,0x22,0xe4,0x24,0x28,0xe4,0x24,0x22,0xe2,0x22,0x34,0x28,0x20,0x20,0x20,
-+0x10,0x10,0x11,0x10,0xfc,0x13,0x32,0x38,0x57,0x50,0x90,0x10,0x10,0x11,0x12,0x14,0x40,0x28,0xfc,0x88,0x50,0xfe,0x44,0x20,0xfe,0x80,0xf8,0x88,0x88,0x8,0x28,0x10,
-+0x8,0x7c,0x49,0x48,0x48,0x7b,0x4a,0x48,0x4f,0x78,0x48,0x48,0x48,0x48,0x89,0x1a,0x40,0x28,0xfc,0x88,0x50,0xfe,0x44,0x20,0xfe,0x80,0xf8,0x88,0x88,0x88,0x28,0x10,
-+0x11,0x11,0x21,0x27,0x49,0xf1,0x27,0x41,0xf9,0x47,0x1,0x19,0xe2,0x42,0x4,0x0,0x0,0x3e,0x22,0xe4,0x24,0x28,0xe4,0x24,0x22,0xe2,0x22,0x34,0x28,0x20,0x20,0x20,
-+0x10,0x10,0x17,0x10,0xfd,0x10,0x37,0x39,0x55,0x52,0x95,0x10,0x13,0x10,0x10,0x10,0x40,0x48,0xfc,0x40,0xf8,0x80,0xfe,0x20,0x50,0x4e,0xf4,0x40,0xf8,0x40,0x40,0x40,
-+0x0,0x8,0xfd,0x10,0x10,0x23,0x22,0x3c,0x67,0xa4,0x24,0x24,0x24,0x3c,0x25,0x2,0x40,0x28,0xfc,0x88,0x50,0xfe,0x44,0x20,0xfe,0x80,0xf8,0x88,0x88,0x88,0x28,0x10,
-+0x10,0x10,0x10,0x14,0x7f,0x54,0x54,0x55,0x54,0x7c,0x13,0x14,0x1c,0xe4,0x40,0x0,0x20,0x20,0x20,0x28,0xfc,0x20,0x28,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x10,0x10,0x11,0x1c,0x20,0x23,0x7e,0x90,0x13,0x7c,0x10,0x10,0x14,0x18,0x11,0x2,0x40,0x28,0xfc,0x88,0x50,0xfe,0x44,0x20,0xfe,0x80,0xf8,0x88,0x88,0x88,0x28,0x10,
-+0x8,0x8,0xb,0x11,0x10,0x37,0x54,0x90,0x1f,0x11,0x11,0x11,0x11,0x11,0x12,0x14,0x80,0x50,0xf8,0x10,0xa0,0xfc,0x88,0x40,0xfe,0x0,0xf0,0x10,0x10,0x10,0x50,0x20,
-+0x0,0x40,0x37,0x11,0x0,0xf,0xe8,0x20,0x2f,0x21,0x21,0x21,0x29,0x31,0x22,0x4,0x80,0x48,0xfc,0x10,0xa0,0xfe,0x84,0x40,0xfe,0x0,0xf0,0x10,0x10,0x10,0x50,0x20,
-+0x4,0x4,0xff,0x4,0x4,0xf,0x10,0x2f,0x48,0x8,0xf,0x8,0x8,0x8,0x7,0x0,0x40,0x44,0xfe,0x40,0x10,0xf8,0x10,0x90,0x90,0x90,0x90,0x30,0x4,0x4,0xfc,0x0,
-+0x4,0x3e,0x24,0x25,0x26,0x3d,0x25,0x25,0x25,0x3d,0x25,0x25,0x25,0x45,0x94,0x8,0x80,0x88,0xfc,0x8,0x28,0xf8,0x28,0x28,0x28,0xe8,0x28,0x10,0x2,0x2,0xfe,0x0,
-+0x4,0x4,0x4,0xf,0x10,0x20,0x5f,0x10,0x10,0x1f,0x10,0x10,0x10,0x10,0xf,0x0,0x0,0x0,0x10,0xf8,0x10,0x90,0xd0,0x90,0x90,0x90,0x90,0x30,0x4,0x4,0xfc,0x0,
-+0x2,0x1,0x7f,0x8,0x17,0x14,0x37,0x50,0x9f,0x12,0x14,0x5,0xc,0x14,0x66,0x4,0x0,0x8,0xfc,0x0,0xf0,0x10,0xf0,0x80,0xfc,0xa0,0x90,0x8,0xd0,0x20,0x5c,0x8,
-+0x1,0x7f,0x1,0x3f,0x1,0xff,0x8,0x49,0x29,0x2a,0x1c,0x2a,0xc9,0x8,0x28,0x10,0x4,0x84,0x4,0x24,0x24,0xa4,0x24,0x24,0x24,0x24,0x24,0x24,0x84,0x84,0x14,0x8,
-+0x8,0xff,0x8,0x47,0x20,0x27,0x84,0x4f,0x14,0x27,0xe4,0x20,0x2f,0x22,0x21,0x20,0x20,0xfe,0x50,0xfc,0x40,0xfc,0x44,0xfc,0x44,0xfc,0x44,0x10,0xfe,0x10,0x10,0x30,
-+0x1f,0x1,0x7f,0x41,0x9d,0x1,0x1d,0x8,0xf,0x10,0x2f,0x48,0xf,0x8,0x8,0x7,0xf0,0x0,0xfe,0x2,0x74,0x0,0x70,0x0,0xf0,0x90,0xd0,0x90,0x90,0xb4,0x4,0xfc,
-+0x8,0xb,0xa,0x12,0x12,0x33,0x32,0x50,0x9f,0x10,0x10,0x11,0x12,0x14,0x18,0x10,0x8,0xfc,0x8,0x8,0x8,0xf8,0x40,0x44,0xfe,0x40,0xe0,0x50,0x48,0x4e,0x44,0x40,
-+0x10,0x17,0x14,0x24,0x27,0x60,0xbf,0x21,0x22,0x2c,0x1,0x3f,0x1,0x1,0xff,0x0,0x10,0xf8,0x10,0x10,0xf0,0x80,0xfc,0xc0,0xa0,0x9c,0x80,0xf8,0x0,0x4,0xfe,0x0,
-+0x20,0x20,0x20,0x3c,0x25,0x4a,0x45,0xa1,0x21,0x21,0x21,0x25,0x29,0x31,0x20,0x0,0x80,0x80,0x84,0xfe,0x4,0x14,0xfc,0x14,0x14,0xf4,0x14,0x8,0x2,0x2,0xfe,0x0,
-+0x2,0x1,0x7f,0x40,0x80,0x0,0x3f,0x1,0x1,0x1f,0x1,0x1,0x1,0x1,0x7f,0x0,0x0,0x0,0xfe,0x2,0x4,0x10,0xf8,0x0,0x20,0xf0,0x0,0x60,0x20,0x8,0xfc,0x0,
-+0x10,0x10,0x10,0x10,0xfd,0x12,0x11,0x1d,0x31,0xd1,0x11,0x11,0x11,0x11,0x50,0x20,0x80,0x80,0x84,0xfe,0x4,0x14,0xfc,0x14,0x14,0xf4,0x14,0x8,0x2,0x2,0xfe,0x0,
-+0x10,0x11,0x11,0x11,0xfd,0x11,0x15,0x19,0x31,0xd1,0x11,0x11,0x11,0x11,0x51,0x21,0x8,0xfc,0x8,0x8,0x28,0x10,0x0,0xf8,0x8,0x90,0x50,0x20,0x50,0x8e,0x4,0x0,
-+0x1f,0x10,0x1f,0x10,0x1f,0x4,0x7f,0x4,0xff,0x4,0x9,0x35,0xc3,0x9,0x11,0x3,0xf0,0x10,0xf0,0x10,0xf0,0x40,0xfc,0x40,0xfe,0x40,0x20,0x5e,0x84,0x20,0x10,0x0,
-+0x8,0x10,0x22,0xd4,0x48,0x31,0x2a,0xcc,0x14,0x24,0xcc,0x14,0x64,0x4,0x28,0x10,0x40,0x40,0x40,0x44,0xfe,0x4,0x4,0x84,0x44,0x44,0x4,0x4,0x4,0x4,0x28,0x10,
-+0x8,0x8,0x1e,0x14,0x28,0x7f,0xaa,0x2a,0x3e,0x2a,0x2a,0x3e,0x0,0xe,0x70,0x20,0x40,0x40,0x44,0x7e,0x84,0x14,0xf4,0x94,0x94,0xf4,0x94,0x88,0x82,0x82,0x7e,0x0,
-+0x13,0x12,0x13,0x16,0x5b,0x51,0x57,0x91,0x1f,0x11,0x12,0x2d,0x28,0x41,0x82,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x10,0xfc,0x10,0xfe,0x10,0x48,0x56,0xe4,0x50,0x48,0xc0,
-+0x10,0x10,0x17,0x10,0xfc,0x10,0x30,0x38,0x55,0x52,0x94,0x18,0x10,0x10,0x10,0x10,0x0,0x4,0xfe,0x20,0x20,0x40,0x40,0xd0,0x48,0x46,0x42,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x8,0xfd,0x11,0x11,0x21,0x25,0x3f,0x65,0xa4,0x25,0x27,0x24,0x3c,0x24,0x0,0x20,0x44,0xfe,0x24,0x24,0xfc,0x24,0x44,0xfc,0xa0,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x4,0xfc,0x4,0x4,0x7c,0x4,0x4,0xfc,0x4,0x0,0x12,0x51,0x50,0x90,0xf,0x0,0x44,0x7e,0x40,0x48,0x7c,0x40,0x44,0x7e,0x40,0x0,0x0,0x84,0x92,0x12,0xf0,0x0,
-+0x1,0x2,0x1f,0x11,0x11,0x1f,0x11,0x12,0x1f,0x5,0x9,0xff,0x1,0x1,0x1,0x1,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,
-+0x4,0x4,0x4,0x4,0x4,0x7c,0x4,0x4,0x4,0x4,0x4,0x4,0x1c,0xe4,0x44,0x0,0x80,0x80,0x88,0x98,0xa0,0xc0,0x80,0x80,0x80,0x80,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x4,0x7c,0x4,0x7c,0x4,0x7c,0x6,0x4,0x3f,0x9,0x1f,0x1,0xff,0x1,0x1,0x1,0x88,0xfc,0x80,0xfc,0x80,0xfc,0x80,0x10,0xf8,0x0,0xf0,0x4,0xfe,0x0,0x0,0x0,
-+0x4,0x4,0x7c,0x4,0x1c,0xe4,0x40,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x10,0x10,0x40,0x44,0x78,0x42,0x42,0x3e,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0x10,0x50,0x20,
-+0x0,0x1f,0x10,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x12,0x2,0x4,0x8,0x30,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x40,0x20,0x18,0x8,
-+0x10,0x10,0x11,0x1d,0x21,0x41,0xbd,0x11,0x11,0xfd,0x11,0x11,0x14,0x18,0x11,0x2,0x0,0x4,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x6,0x2,
-+0x8,0x8,0xf,0x10,0x12,0x31,0x51,0x9f,0x10,0x13,0x12,0x12,0x12,0x12,0x13,0x12,0x80,0x48,0xfc,0x0,0x18,0x10,0x24,0xfe,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x4,0x44,0x29,0x11,0x29,0x49,0x89,0x9,0x19,0x29,0x49,0x89,0x8,0x8,0x51,0x22,0x0,0x4,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x50,0x88,0x6,0x2,
-+0x4,0x7,0x8,0x14,0x23,0x2,0xc,0x30,0xdf,0x11,0x11,0x1f,0x11,0x11,0x1f,0x10,0x0,0xf0,0x20,0x40,0x80,0x80,0x60,0x1e,0xf4,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x8,0xf,0x14,0x12,0x23,0xc,0x30,0xdf,0x11,0x1f,0x11,0x1f,0x2,0x29,0x28,0x47,0x0,0xe0,0x40,0x80,0x80,0x60,0x1e,0xf4,0x10,0xf0,0x10,0xf0,0x0,0x88,0x94,0xf4,
-+0x10,0x10,0x17,0x14,0x5a,0x51,0x51,0x9f,0x10,0x13,0x12,0x2a,0x26,0x46,0x83,0x2,0x80,0x48,0xfc,0x0,0x18,0x10,0x24,0xfe,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x20,0x10,0x10,0x5,0xfd,0x9,0x11,0x35,0x59,0x95,0x11,0x12,0x12,0x14,0x18,0x13,0x20,0x20,0x20,0xfe,0x22,0x24,0x20,0x20,0xfc,0x4,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x1,0x1,0x7f,0x2,0x5,0x9,0x37,0xc1,0x9,0x8,0x7f,0x8,0x8,0x8,0x10,0x20,0x0,0x8,0xfc,0x80,0x40,0x30,0xce,0x4,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x20,
-+0x4,0x4,0xff,0x4,0x1,0x1,0xff,0x3,0x5,0x9,0x11,0x2f,0xc1,0x1,0x1,0x1,0x40,0x44,0xfe,0x40,0x0,0x4,0xfe,0x80,0x40,0x20,0x10,0xee,0x4,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x7f,0x5,0x5,0x5,0x9,0x9,0x11,0x2f,0xc1,0x1,0x1,0x1,0x0,0x0,0x0,0x8,0xfc,0x40,0x40,0x40,0x20,0x20,0x10,0xee,0x4,0x0,0x0,0x0,
-+0x8,0xa,0x1f,0x28,0x45,0x1,0x7f,0x3,0x5,0x9,0x11,0x2f,0xc1,0x1,0x1,0x1,0x40,0x48,0x7c,0xa0,0x10,0x0,0xfc,0x80,0x40,0x20,0x10,0xee,0x4,0x0,0x0,0x0,
-+0x1,0x21,0x21,0x3f,0x0,0x3e,0x22,0x22,0x3e,0x22,0x22,0x3e,0x22,0x22,0x4a,0x85,0x0,0x8,0x8,0xf8,0x8,0xfc,0x88,0x88,0xf8,0x88,0x88,0xf8,0x88,0x88,0xa8,0x10,
-+0x10,0x17,0x24,0x24,0x44,0xff,0x14,0x24,0x44,0xff,0x44,0x4,0x1c,0xe4,0x4a,0x11,0x4,0xbe,0xa4,0xa4,0xa4,0xbc,0xa4,0xa4,0xa4,0xbc,0xa4,0xa4,0xa4,0xc4,0x94,0x8,
-+0x0,0xff,0x1,0x7,0x19,0xe1,0x3f,0x21,0x21,0x3f,0x21,0x21,0x3f,0x21,0x41,0x81,0x4,0xfe,0x0,0x60,0x18,0x4,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x28,0x10,
-+0x0,0xff,0x4,0x8,0x1f,0x28,0xc8,0xf,0x9,0x1,0x7d,0x5,0x9,0x11,0x61,0x3,0x4,0xfe,0x0,0x10,0xf8,0x10,0x10,0xf0,0x8,0x18,0xa0,0x40,0x20,0x1e,0x4,0x0,
-+0x0,0x7a,0x4a,0x4b,0x48,0x7b,0x12,0x12,0x13,0x5a,0x52,0x53,0x5a,0xe2,0x44,0x9,0x40,0x44,0x44,0xfc,0x4,0xbe,0xa4,0xa4,0xbc,0xa4,0xa4,0xbc,0xa4,0xa4,0xa4,0xcc,
-+0x4,0x42,0x21,0x2f,0x2,0x2,0xe2,0x2f,0x22,0x22,0x22,0x22,0x24,0x58,0x8f,0x0,0x10,0x20,0x40,0xf8,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x20,0x26,0xfc,0x0,
-+0x0,0x4f,0x20,0x27,0x4,0x4,0xe7,0x20,0x2f,0x28,0x2f,0x28,0x2f,0x50,0x8f,0x0,0x10,0xf8,0x0,0xf0,0x10,0x10,0xf0,0x0,0xf8,0x88,0xf8,0x88,0xf8,0x6,0xfc,0x0,
-+0x1,0x1f,0x12,0x11,0x10,0x1f,0x0,0x3f,0x21,0x3f,0x21,0x3f,0x0,0xff,0x4,0x18,0x10,0xf8,0x10,0x10,0x90,0xf0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfe,0x40,0x40,
-+0x0,0x20,0x20,0x20,0x20,0x24,0x3e,0x20,0x20,0x20,0x20,0x20,0x26,0x38,0x60,0x0,0x80,0x80,0x80,0x80,0x88,0x98,0xa0,0xc0,0x80,0x80,0x80,0x82,0x82,0x82,0x7e,0x0,
-+0x2,0x3f,0x22,0x22,0x3e,0x9,0xff,0x8,0x7f,0x41,0x5d,0x55,0x5d,0x41,0x7f,0x41,0x0,0x7c,0x44,0x44,0x48,0x48,0xd0,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x8,0xa,0x1f,0x28,0x45,0x0,0x7f,0x1,0x1,0x3f,0x1,0x1,0xff,0x1,0x1,0x0,0x20,0x28,0x7c,0xa0,0x10,0x7c,0x80,0x10,0x78,0x80,0x8,0x7c,0x80,0x2,0x2,0xfe,
-+0x8,0x8,0x10,0x13,0x22,0x4a,0x8a,0x12,0x33,0x52,0x93,0x12,0x14,0x14,0x19,0x16,0x40,0x40,0x40,0xfc,0x44,0x48,0x40,0x40,0xf8,0x8,0x10,0xa0,0x40,0xb0,0xe,0x4,
-+0x4,0xfe,0x11,0x7d,0x11,0x1f,0xf1,0x0,0x7f,0x4,0x8,0x1f,0x28,0xc8,0xf,0x8,0x40,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x8,0xfc,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,
-+0x8,0xff,0x9,0x2,0x3f,0x24,0x23,0x24,0x3f,0x0,0x20,0x3e,0x20,0x26,0x78,0x20,0x24,0xfe,0x20,0x10,0xf8,0x90,0x10,0x90,0xf0,0x0,0x88,0x98,0xa0,0xc4,0x84,0x7c,
-+0x4,0x4,0xff,0x4,0x49,0x2a,0xc,0x7f,0x49,0x49,0x5d,0x6b,0x49,0x49,0x41,0x43,0x40,0x44,0xfe,0x40,0x20,0x24,0x3e,0x44,0xa4,0x24,0x24,0x28,0x10,0x28,0x46,0x84,
-+0x20,0x20,0x20,0x3e,0x20,0x22,0x2c,0x70,0x21,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x80,0x80,0x98,0xe0,0x80,0x84,0x84,0x7c,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,
-+0x20,0x20,0x3e,0x20,0x2e,0x30,0x0,0xff,0x10,0x1e,0x22,0x52,0xc,0x8,0x10,0x60,0x80,0x98,0xe0,0x80,0x88,0x78,0x4,0xfe,0x80,0x88,0x98,0xa0,0xc0,0x84,0x84,0x7c,
-+0x0,0x20,0x24,0x3e,0x20,0x20,0x2e,0x30,0x4,0x12,0x50,0x51,0x96,0x18,0x67,0x0,0x80,0x88,0x98,0xa0,0xc0,0x84,0x84,0x7c,0x0,0x40,0x88,0x6,0x12,0x10,0xf0,0x0,
-+0x0,0x3,0x7d,0x1,0x1,0x3f,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x1,0x1,0x1,0x38,0xc0,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0x28,0x10,0x0,0x0,0x0,
-+0x1,0x0,0x3f,0x20,0x24,0x24,0x24,0x24,0x27,0x24,0x24,0x24,0x25,0x4e,0x84,0x0,0x0,0x88,0xfc,0x0,0x40,0x40,0x44,0x4c,0x50,0x60,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x1,0x0,0x3f,0x20,0xaf,0x68,0x2f,0x28,0x2f,0x60,0xbf,0x24,0x24,0x44,0x88,0x10,0x0,0x88,0xfc,0x0,0xf8,0x88,0xf8,0x88,0xf8,0x0,0xfe,0x10,0x10,0x10,0x10,0x10,
-+0x20,0x1b,0x8,0x40,0x40,0x5f,0x40,0x41,0x42,0x44,0x48,0x50,0x40,0x42,0x41,0x40,0x4,0xfe,0x4,0x84,0xa4,0xf4,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x14,0x8,
-+0x8,0x49,0x2b,0x2c,0x9,0x7f,0x49,0x49,0x5d,0x5b,0x69,0x49,0x49,0x4b,0x40,0x41,0x20,0x20,0x20,0x24,0x7e,0x84,0x44,0x44,0x44,0x48,0x28,0x10,0x28,0x48,0x86,0x4,
-+0x8,0x49,0x2a,0x8,0x7f,0x49,0x5d,0x6b,0x49,0x43,0x8,0xff,0x8,0x8,0x10,0x20,0x20,0x20,0x24,0x3e,0x44,0xc4,0x28,0x10,0x28,0x46,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x2,0x1,0x1,0x1,0x8,0x8,0x48,0x48,0x48,0x89,0xa,0xc,0x18,0x28,0x47,0x0,0x0,0x0,0x20,0x30,0x20,0x40,0x48,0x46,0x82,0x0,0x0,0x10,0x10,0x10,0xf0,0x0,
-+0x0,0x0,0x3e,0x23,0x22,0x22,0x3e,0x23,0x20,0x3e,0x23,0x62,0xa2,0x3e,0x20,0x0,0x40,0x20,0x8,0xfc,0x0,0x88,0x50,0xfe,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x20,
-+0x2,0x3f,0x22,0x22,0x3e,0x21,0x3e,0x62,0xa2,0x3e,0x20,0x1f,0x0,0x0,0x7f,0x0,0x20,0x14,0xfe,0x44,0x28,0xfe,0x10,0xfe,0x10,0x90,0x80,0xf8,0x80,0x84,0xfe,0x0,
-+0x2,0x3f,0x22,0x3e,0x21,0x3e,0x62,0xbe,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x20,0xfc,0x88,0x50,0xfe,0x20,0xf8,0x20,0x20,0xf0,0x10,0xf0,0x10,0xf0,0x10,0x30,
-+0x1,0x4f,0x29,0x9,0x9,0xf,0xe8,0x28,0x2f,0x39,0x29,0x29,0x2f,0x50,0x8f,0x0,0x20,0x90,0x14,0xfe,0x0,0x44,0x28,0xfe,0x10,0x10,0x7c,0x10,0x10,0x16,0xfc,0x0,
-+0x2,0x7a,0x4a,0x53,0x52,0x62,0x52,0x4b,0x48,0x48,0x68,0x53,0x40,0x40,0x4f,0x40,0x20,0x20,0x24,0xac,0x30,0x20,0xa4,0x1c,0x40,0x40,0x50,0xf8,0x40,0x44,0xfe,0x0,
-+0x28,0x28,0xfe,0x29,0x3b,0x15,0x7d,0x55,0x55,0x7d,0x11,0xff,0x11,0x11,0x11,0x11,0x84,0xfe,0x90,0x7c,0x54,0x54,0x7c,0x54,0x54,0x7c,0x10,0x50,0x20,0x30,0x4e,0x84,
-+0x0,0x20,0x10,0x10,0x7,0x0,0xf0,0x10,0x11,0x11,0x11,0x12,0x14,0x28,0x47,0x0,0x80,0x80,0x80,0x88,0xfc,0x88,0x88,0x88,0x8,0x8,0x8,0x50,0x20,0x6,0xfc,0x0,
-+0x10,0x10,0x23,0x22,0x4a,0xfb,0x12,0x22,0x43,0xf6,0x4a,0x3,0x1a,0xe2,0x42,0x2,0x80,0x48,0xfc,0x8,0x8,0xf8,0x0,0x4,0xfe,0x94,0x94,0xfc,0x94,0x94,0x94,0xc,
-+0x4,0x7e,0x45,0x54,0x54,0x54,0x55,0x54,0x54,0x54,0x54,0x10,0x28,0x47,0x82,0x0,0x8,0x1c,0xe0,0x0,0x40,0x20,0xfc,0x4,0x8,0x10,0x20,0x40,0x80,0x46,0x3c,0x0,
-+0x1,0x0,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x19,0x29,0x2f,0x49,0x89,0x9,0x8,0x0,0x88,0xfc,0x8,0x8,0xf8,0x0,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0x24,0xc,
-+0x10,0x17,0x10,0x10,0x27,0x24,0x67,0xa4,0x27,0x24,0x22,0x21,0x20,0x21,0x22,0x2c,0x4,0xfe,0x40,0x44,0xfe,0x44,0xfc,0x44,0xfc,0x44,0x40,0x40,0x80,0x60,0x1e,0x4,
-+0x2,0x1,0x7f,0x4,0x14,0x14,0x24,0x44,0x1f,0x8,0x4,0x2,0x1,0x2,0xc,0x30,0x0,0x8,0xfc,0x40,0x50,0x48,0x4c,0x44,0xf0,0x20,0x40,0x80,0x0,0xc0,0x3c,0x8,
-+0x2,0x1,0x1,0x0,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x40,0x20,0x10,0x10,0x0,0x0,0x0,0x0,0x0,
-+0x20,0x10,0x10,0x7c,0x8,0x2a,0x2a,0xfe,0x12,0x10,0xfc,0x11,0x11,0x12,0x24,0x40,0x10,0x88,0x88,0xbe,0x84,0x94,0x94,0xbe,0x88,0x88,0xbe,0x8,0x8,0x8,0x8,0x8,
-+0x20,0x12,0x11,0x7d,0x8,0x2f,0x29,0xfd,0x11,0x11,0xfd,0x11,0x11,0x11,0x21,0x40,0x20,0x10,0x10,0x7c,0x8,0x28,0x28,0x7e,0x10,0x10,0x7c,0x10,0x50,0x90,0x10,0x10,
-+0x20,0x10,0x10,0x7d,0x9,0x2b,0x28,0xfc,0x11,0x13,0xfc,0x10,0x10,0x13,0x20,0x40,0x10,0x88,0x88,0x3e,0x4,0xd4,0x54,0xbe,0x8,0xc8,0x3e,0x8,0xc8,0x8,0x8,0x8,
-+0x0,0x40,0x27,0x24,0x4,0x7,0xe4,0x27,0x26,0x26,0x2b,0x2a,0x32,0x50,0x8f,0x0,0x80,0x48,0xfc,0x8,0x8,0xf8,0x0,0xf8,0xa8,0xa8,0xf8,0xa8,0xa8,0x6,0xfc,0x0,
-+0x10,0x10,0x13,0x10,0xfc,0x10,0x37,0x38,0x54,0x51,0x91,0x12,0x14,0x10,0x11,0x10,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x40,0x40,0x50,0x48,0x4c,0x44,0x40,0x40,0x80,
-+0x5,0x7,0x4,0x3f,0x24,0x27,0x3c,0x27,0x20,0x2f,0x29,0x29,0x29,0x49,0x90,0x20,0x0,0x84,0xc,0xd0,0xa0,0x4,0x8c,0x90,0x20,0x44,0xc,0x10,0x22,0x42,0xfe,0x0,
-+0x0,0x7b,0x48,0x48,0x49,0x79,0x49,0x49,0x48,0x79,0x48,0x4b,0x48,0x49,0x4a,0x98,0x4,0xfe,0x50,0x54,0xfe,0x54,0x54,0xfc,0x0,0xfc,0x0,0xfe,0xa8,0x24,0x22,0x60,
-+0x1,0x1,0x7f,0x1,0x3f,0x1,0x1,0xff,0x2,0x5,0xc,0x34,0xc4,0x5,0x6,0x4,0x0,0x8,0xfc,0x0,0xf8,0x0,0x4,0xfe,0x0,0x10,0xa0,0x40,0x30,0xe,0x4,0x0,
-+0x8,0x2a,0x1c,0x7f,0x49,0x5d,0x6b,0x47,0x8,0x3f,0x51,0x1f,0x11,0x1f,0x0,0xff,0x20,0x24,0x3e,0x44,0xa8,0x10,0x2e,0xc4,0x90,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,
-+0x49,0x2a,0x8,0x7f,0x49,0x5d,0x6b,0x49,0x43,0x0,0x2a,0x29,0x28,0x48,0x7,0x0,0x20,0x20,0x24,0x3e,0x48,0xa8,0x10,0x2e,0x44,0x0,0x10,0x88,0xa4,0x24,0xe0,0x0,
-+0x1,0x3f,0x21,0x21,0x21,0x3f,0x28,0x9,0xff,0x9,0x9,0x11,0x11,0x25,0x42,0x0,0x4,0x84,0x4,0x24,0x24,0x24,0x24,0x24,0xa4,0x24,0x24,0x24,0x4,0x4,0x14,0x8,
-+0x0,0x3f,0x21,0xa7,0x64,0x27,0x24,0x27,0x64,0xa7,0x21,0x22,0x26,0x3b,0x42,0x81,0x84,0xfe,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x20,0x10,0x6e,0x84,0x8,0xf8,
-+0x10,0x10,0x10,0x10,0xff,0x10,0x31,0x39,0x52,0x52,0x94,0x10,0x10,0x10,0x10,0x10,0x80,0x82,0x82,0x84,0xe8,0x90,0x82,0xc2,0xa4,0x88,0x92,0x82,0x84,0x88,0x90,0xa0,
-+0x0,0x20,0x11,0x0,0xfc,0xb,0x48,0x28,0x29,0x11,0x29,0x25,0x45,0x81,0x3,0x0,0x10,0x10,0xf4,0x12,0x10,0xfe,0x10,0x50,0x50,0x70,0x50,0x48,0x48,0x6a,0x86,0x2,
-+0x2,0x42,0x2a,0x2b,0xa,0x8a,0x5f,0x2,0x2a,0x2a,0xd3,0x42,0x44,0x48,0x50,0x1,0x4,0xfe,0x10,0xa4,0x7e,0x44,0xd4,0x54,0x54,0xd4,0x54,0x54,0x10,0x28,0x46,0x82,
-+0x0,0x40,0x2f,0x28,0x10,0x83,0x52,0x13,0x12,0x22,0xe2,0x3f,0x20,0x23,0x22,0x24,0x80,0x40,0xfe,0x2,0x64,0x80,0x10,0xf8,0x20,0x20,0x24,0xfe,0x0,0x20,0x18,0x8,
-+0x2,0x1,0x3f,0x20,0x40,0xf,0x8,0xf,0x8,0x8,0x8,0xff,0x0,0xc,0x8,0x10,0x0,0x0,0xfc,0x4,0xe8,0x0,0x20,0xf0,0x40,0x40,0x44,0xfe,0x0,0x40,0x30,0x10,
-+0x10,0x10,0x17,0x14,0xfc,0x11,0x15,0x19,0x31,0xd1,0x11,0x1f,0x10,0x11,0x51,0x22,0x40,0x20,0xfe,0x2,0x34,0xc0,0x10,0xf8,0x10,0x10,0x14,0xfe,0x0,0x90,0xc,0x4,
-+0x0,0x0,0xf,0x8,0x8,0x8,0xf,0x8,0x8,0x8,0xff,0x0,0x4,0xc,0x10,0x20,0x20,0xf0,0x0,0x0,0x0,0x10,0xf8,0x40,0x40,0x44,0xfe,0x0,0x40,0x30,0x18,0x8,
-+0x0,0x40,0x30,0x10,0x0,0xf,0x11,0x12,0x22,0xe4,0x24,0x28,0x30,0x20,0x22,0x21,0x80,0x80,0x84,0x8c,0x90,0xa0,0xc0,0xc0,0xa0,0x90,0x88,0x8e,0x84,0x80,0x80,0x0,
-+0x10,0x10,0x17,0x10,0xfc,0x10,0x33,0x3a,0x56,0x52,0x92,0x13,0x12,0x12,0x12,0x12,0x0,0x4,0xfe,0x40,0x40,0x44,0xfe,0x44,0x44,0x64,0x9c,0xc,0x4,0x4,0x14,0x8,
-+0x0,0x0,0xff,0x1,0x1,0x1,0x3f,0x21,0x21,0x21,0x22,0x24,0x28,0x20,0x20,0x20,0x0,0x4,0xfe,0x0,0x0,0x8,0xfc,0x8,0x8,0x88,0x48,0x28,0x28,0x8,0x28,0x10,
-+0x0,0x3f,0x1,0x7f,0x1,0x3f,0x1,0xff,0x1,0x3f,0x3,0x5,0x9,0x11,0x61,0x1,0x78,0x80,0x8,0xfc,0x0,0xf0,0x14,0xfe,0x10,0xf0,0x80,0x40,0x30,0xe,0x4,0x0,
-+0x20,0x21,0x20,0x3c,0x47,0x48,0xa0,0x20,0x27,0x20,0x20,0x24,0x28,0x31,0x22,0x4,0x0,0x8,0x90,0x0,0xfc,0x90,0x90,0x94,0xfe,0x90,0x90,0x90,0x90,0x10,0x10,0x10,
-+0x0,0x20,0x2f,0x20,0x28,0xb0,0xa7,0xa4,0x24,0x24,0x24,0x25,0x54,0x4c,0x84,0x4,0x0,0x4,0xfe,0x40,0x40,0x44,0xfe,0x44,0x44,0x64,0x94,0x14,0x4,0x4,0x14,0x8,
-+0x0,0x0,0x1f,0x10,0x90,0x57,0x50,0x10,0x37,0x54,0x94,0x14,0x25,0x24,0x44,0x4,0x80,0x44,0xfe,0x0,0x8,0xfc,0x40,0x44,0xfe,0x44,0x44,0xa4,0x14,0x4,0x14,0x8,
-+0x10,0xc,0x4,0x3f,0x4,0x4,0x4,0x4,0xff,0x4,0x4,0x4,0x8,0x8,0x10,0x20,0x10,0x30,0x40,0xfc,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x0,0x8,0xfc,0x11,0x11,0x11,0x7d,0x11,0x11,0x11,0x1e,0xf2,0x42,0x4,0x8,0x3,0x20,0x20,0x20,0xfe,0x22,0x24,0x20,0xfc,0x4,0x88,0x48,0x50,0x20,0x50,0x8e,0x4,
-+0x8,0x8,0xff,0x8,0x20,0x13,0x92,0x42,0xa,0x12,0xe2,0x24,0x24,0x24,0x29,0x32,0x20,0x24,0xfe,0x20,0x20,0xfe,0x22,0x24,0xf8,0x88,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x10,0x13,0x10,0x12,0xfd,0x17,0x11,0x1a,0x34,0xd3,0x12,0x12,0x13,0x12,0x52,0x23,0x38,0xc0,0x44,0x4c,0x50,0xfe,0x50,0x4e,0x44,0xf8,0x48,0x48,0xf8,0x48,0x48,0xf8,
-+0x10,0x10,0x12,0x12,0xff,0x10,0x14,0x18,0x11,0x31,0xd2,0x12,0x14,0x18,0x51,0x22,0x40,0x50,0x48,0x40,0xfe,0x80,0x80,0xf8,0x8,0x90,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x20,0x20,0x20,0x38,0x47,0x80,0x78,0x20,0x21,0xfa,0x24,0x21,0x28,0x30,0x20,0x0,0x40,0x40,0x40,0x48,0xfc,0x40,0xe0,0xd0,0x48,0x4e,0x44,0xf0,0x40,0x40,0x40,0x40,
-+0x0,0x40,0x30,0x17,0x4,0x84,0x44,0xf,0x14,0x25,0xe4,0x24,0x28,0x29,0x32,0x24,0x40,0x40,0x40,0xfc,0x44,0x48,0x40,0xf8,0x8,0x10,0xa0,0x40,0xa0,0x10,0xe,0x4,
-+0x20,0x20,0x2f,0x20,0x27,0xfc,0x27,0x24,0x27,0x24,0x20,0x2f,0x22,0x21,0x20,0x20,0x50,0x48,0xfe,0x40,0xfc,0x44,0xfc,0x44,0xfc,0x44,0x10,0xfe,0x10,0x10,0x50,0x20,
-+0x8,0xa,0x7f,0x8,0x8,0x7f,0x41,0x82,0x3e,0x4,0x8,0x7e,0x8,0x8,0x29,0x12,0x20,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x44,0x44,0x44,0x84,0x84,0x28,0x10,
-+0x10,0x10,0x17,0x10,0xfb,0x12,0x13,0x1a,0x33,0xd2,0x10,0x1f,0x12,0x11,0x50,0x20,0x50,0x48,0xfc,0x40,0xf8,0x48,0xf8,0x48,0xf8,0x48,0x10,0xfe,0x10,0x10,0x50,0x20,
-+0x10,0x10,0x10,0x1d,0x21,0x21,0x7d,0x91,0x11,0x7d,0x11,0x11,0x15,0x19,0x11,0x0,0x40,0x40,0x84,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,0x0,
-+0x10,0x12,0x1f,0x28,0x45,0x20,0x10,0x83,0x42,0xa,0x13,0xe2,0x22,0x22,0x23,0x22,0x40,0x44,0x7e,0xa0,0x10,0x40,0x88,0xfc,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x8,0x8,0x8,0x11,0x11,0x31,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x40,0x40,0x84,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,0x0,
-+0x2,0x4,0x1f,0x10,0x1f,0x10,0x1f,0x11,0x1,0x3f,0x21,0x21,0x21,0x21,0x21,0x1,0x0,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x0,0x8,0xfc,0x8,0x8,0x8,0x28,0x10,0x0,
-+0x8,0x8,0x12,0x3f,0x22,0x32,0x2a,0x22,0xfe,0x22,0x32,0x2a,0x22,0x22,0x4a,0x84,0x20,0x20,0x44,0xfe,0x84,0x84,0x84,0x84,0xfc,0x84,0x84,0x84,0x84,0xfc,0x84,0x0,
-+0x8,0x7c,0x4b,0x48,0x4b,0x7a,0x4c,0x49,0x48,0x78,0x4f,0x48,0x48,0x48,0x49,0x98,0x40,0x48,0xfc,0x40,0xfc,0x4,0x8,0xf0,0x20,0x44,0xfe,0x40,0x40,0x40,0x40,0x80,
-+0x8,0x7c,0x4f,0x48,0x4b,0x7a,0x4b,0x4a,0x4b,0x7a,0x48,0x4f,0x4a,0x49,0x48,0x98,0x50,0x48,0xfe,0x40,0xf8,0x48,0xf8,0x48,0xf8,0x48,0x10,0xfe,0x10,0x10,0x50,0x20,
-+0x2,0x42,0x32,0x1f,0x82,0x5f,0x50,0xf,0x11,0x22,0xe3,0x2e,0x22,0x22,0x2a,0x25,0x10,0x10,0x90,0xd4,0x3e,0xd4,0x54,0x94,0x14,0x24,0xa4,0x24,0x44,0x44,0x94,0x8,
-+0x0,0x40,0x30,0x13,0x82,0x62,0x22,0xa,0x13,0x22,0xe2,0x22,0x22,0x23,0x22,0x20,0x40,0x40,0x88,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,
-+0x4,0x7f,0x4,0x24,0x24,0x24,0x24,0x25,0x3e,0x2,0x2,0x1e,0xe2,0x42,0xb,0x4,0x0,0x8,0x88,0x50,0x20,0x50,0x88,0x8,0x4,0x8c,0x50,0x20,0x50,0x8e,0x4,0x0,
-+0x20,0x20,0x20,0x2f,0xf8,0x27,0x24,0x2c,0x37,0xe4,0x24,0x27,0x24,0x24,0xa4,0x44,0x40,0x50,0x48,0xfe,0x44,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x44,0x44,0x54,0x8,
-+0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x0,0x0,0x0,0x0,0x0,0x80,0x60,0x30,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x10,0x78,0x57,0x50,0x57,0x54,0x54,0x57,0x54,0x54,0x77,0x54,0x4,0x4,0x4,0x40,0x50,0x48,0xfe,0x44,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x44,0x44,0x54,0x8,
-+0x10,0x8,0x8,0x2,0xfe,0x4,0x8,0xa,0x1c,0x2a,0x48,0x88,0x8,0x8,0x8,0x8,0x40,0x40,0x40,0x40,0x40,0x40,0x60,0x50,0x4c,0x44,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x20,0x21,0x23,0x22,0xfb,0x22,0x23,0x22,0x23,0x22,0x38,0xe7,0x40,0x0,0x0,0x0,0x80,0x8,0xfc,0x8,0xf8,0x0,0xf8,0x8,0xf8,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,
-+0x0,0xff,0x0,0x0,0x1,0x1,0x3,0x5,0x9,0x11,0x21,0x41,0x1,0x1,0x1,0x1,0x4,0xfe,0x80,0x80,0x0,0x0,0x40,0x20,0x18,0xc,0x4,0x0,0x0,0x0,0x0,0x0,
-+0x2,0x2,0x2,0xff,0x4,0x9,0x11,0x3f,0x51,0x91,0x11,0x11,0x11,0x11,0x1,0x1,0x0,0x0,0x8,0xfc,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x28,0x10,0x0,0x0,
-+0x1,0x9,0x9,0x9,0x9,0x9,0xff,0x1,0x9,0xd,0x11,0x21,0x0,0x3,0xc,0x70,0x0,0x0,0x10,0xf8,0x0,0x4,0xfe,0x0,0x10,0x18,0x20,0x20,0xc0,0x0,0x0,0x0,
-+0x10,0x3e,0x49,0x0,0x27,0x10,0x13,0x82,0x43,0xa,0x13,0xe2,0x2f,0x21,0x20,0x20,0x40,0xfc,0x20,0x48,0xfc,0x40,0xf8,0x48,0xf8,0x48,0xf8,0x48,0xfe,0x10,0x90,0x30,
-+0x10,0x8,0x2,0x7f,0x0,0x22,0x14,0xff,0x2,0x3f,0x22,0x22,0x22,0x3e,0x22,0x0,0x0,0x7c,0x44,0x44,0x48,0x48,0x50,0xc8,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x10,0x10,0x10,0x13,0x58,0x55,0x51,0x93,0x15,0x19,0x11,0x11,0x11,0x10,0x10,0x10,0x40,0x40,0x44,0xfe,0x80,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x2c,0x20,0x20,0x20,
-+0x20,0x20,0x2f,0x2a,0xfb,0x26,0x25,0x2b,0x32,0xe5,0x28,0x27,0x22,0x22,0xa5,0x40,0x80,0x40,0xfe,0x2,0xbc,0xa4,0x28,0x18,0x8,0xf6,0x0,0xfc,0x48,0x44,0x44,0x80,
-+0x0,0x48,0x2f,0x10,0x2b,0x48,0xf,0x18,0x2b,0x4a,0x8b,0xa,0xb,0xa,0x52,0x22,0x40,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x8,0x18,
-+0x4,0x4,0x3f,0x4,0xff,0x10,0x8,0x7f,0x8,0x11,0x3a,0x54,0x93,0x19,0x11,0x2,0x40,0x50,0x48,0x40,0xfe,0x40,0x44,0x44,0x48,0x48,0x50,0x20,0x60,0x92,0xa,0x6,
-+0x8,0x8,0x8,0x8,0xfe,0x8,0x18,0x1c,0x2a,0x28,0x48,0x89,0x8,0x8,0x8,0x8,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x30,0x30,0x50,0x90,0x10,0x10,0x10,0x50,0x20,
-+0x0,0x0,0x0,0x0,0xff,0x0,0x1,0x1,0x2,0x4,0x8,0x10,0x60,0x0,0x2,0x1,0x80,0x80,0x80,0x84,0xfe,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0,
-+0x4,0x7e,0x44,0x54,0x57,0x54,0x54,0x54,0x54,0x54,0x55,0x2a,0x24,0x44,0x80,0x0,0x10,0x10,0x10,0x14,0xfe,0x10,0x30,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x8,0x7f,0x48,0x4a,0x49,0x78,0x48,0x4f,0x48,0x78,0x48,0x49,0x4a,0x7c,0x48,0x0,0x1c,0xe0,0x88,0x48,0x50,0x0,0x44,0xfe,0x40,0xc0,0xe0,0x50,0x4e,0x44,0x40,0x40,
-+0x4,0x7f,0x44,0x45,0x44,0x7c,0x10,0x13,0x5c,0x50,0x50,0x50,0x5d,0xe2,0x40,0x0,0x1c,0xe0,0x44,0x26,0xa8,0x0,0x24,0xfe,0x20,0x60,0x70,0xa8,0x26,0x24,0x20,0x20,
-+0x0,0x0,0x7f,0x0,0x11,0x8,0x1,0x1,0xff,0x3,0x5,0x9,0x11,0x61,0x1,0x1,0x8,0x7c,0x80,0x8,0x18,0xa0,0x0,0x4,0xfe,0x80,0x40,0x30,0xe,0x4,0x0,0x0,
-+0x1,0xe,0xf1,0x49,0x2a,0x20,0x8,0xff,0x8,0x1c,0x1b,0x29,0x48,0x88,0x8,0x8,0x0,0x8,0x18,0x20,0x40,0x84,0xc,0x10,0x20,0x40,0x4,0xc,0x10,0x20,0x40,0x80,
-+0x4,0x4,0xff,0x4,0x0,0x3f,0x12,0x9,0x1,0xff,0x3,0x5,0x9,0x11,0x61,0x1,0x40,0x44,0xfe,0x40,0x38,0xc0,0x10,0x20,0x4,0xfe,0x80,0x40,0x30,0xe,0x4,0x0,
-+0x4,0x4,0xff,0x14,0x16,0x12,0x2c,0x68,0x17,0x20,0x5f,0x81,0x9,0x19,0x21,0x3,0x40,0x44,0xfe,0x40,0xf8,0x90,0x60,0x20,0xd0,0xe,0xf4,0x0,0x20,0x18,0x8,0x0,
-+0x10,0x1e,0x10,0x3e,0x44,0x29,0x12,0x65,0xf,0x38,0xcf,0x8,0xf,0xa,0x9,0xc,0x0,0xf8,0x88,0x50,0x20,0x50,0x8c,0x44,0xe0,0x3e,0xe4,0x20,0xe0,0x10,0xa0,0x78,
-+0x2,0x2,0x4,0x1f,0x2,0xff,0x4,0x8,0x13,0x2c,0xc1,0xe,0x0,0x1,0xe,0x70,0x0,0x40,0x20,0xf0,0x4,0xfe,0x40,0xa0,0x10,0x4e,0x84,0x10,0x60,0x80,0x0,0x0,
-+0x0,0x3f,0x1,0x1,0xff,0x2,0x5,0x9,0x3f,0xd1,0x11,0x1f,0x1,0x1,0x3f,0x0,0x10,0xf8,0x0,0x4,0xfe,0x80,0x40,0x20,0xfe,0x14,0x10,0xf0,0x0,0x10,0xf8,0x8,
-+0x0,0x4,0x7e,0x10,0x10,0x1f,0x22,0x22,0x65,0x94,0x8,0x8,0x10,0x20,0x43,0x80,0x40,0x50,0x48,0x40,0x7c,0xc0,0x48,0x7c,0xc0,0x48,0x50,0x20,0x60,0x92,0xa,0x6,
-+0x21,0x21,0x21,0x2f,0xb2,0xad,0xa5,0x2f,0x21,0x21,0x21,0x2f,0x25,0x21,0x21,0x21,0x0,0x6,0x38,0xe0,0x20,0x20,0x3e,0xe8,0x28,0x28,0xe8,0x28,0x48,0x48,0x88,0x8,
-+0x20,0x20,0x21,0x27,0xb0,0xaf,0xa1,0x22,0x24,0x39,0x22,0x20,0x23,0x20,0x20,0x27,0x80,0xa0,0x10,0xf8,0x80,0xfe,0x20,0x50,0x8e,0x24,0x40,0x88,0x10,0x20,0xc0,0x0,
-+0x10,0x10,0x10,0x14,0x54,0x59,0x51,0x91,0x11,0x11,0x11,0x29,0x25,0x45,0x81,0x1,0x20,0x20,0x20,0x20,0x20,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0xfc,0x4,
-+0x4,0x4,0xff,0x4,0x1,0x2,0x4,0x18,0x6f,0x88,0x8,0x8,0x8,0x8,0x7,0x0,0x40,0x44,0xfe,0x40,0x0,0x80,0x40,0x30,0xee,0x24,0xa0,0x40,0x10,0x10,0xf0,0x0,
-+0x8,0x10,0x3c,0x24,0x34,0x2d,0x26,0xfc,0x24,0x34,0x2c,0x24,0x24,0x24,0x54,0x88,0x20,0x20,0x50,0x50,0x88,0x6,0x4,0xf8,0x88,0x88,0xa8,0x90,0x80,0x84,0x84,0x7c,
-+0x1,0x1,0x2,0x2,0x4,0x8,0x30,0xcf,0x8,0x8,0x8,0x8,0x8,0x8,0x7,0x0,0x0,0x0,0x80,0x80,0x40,0x20,0x1e,0xe4,0x20,0x20,0xa0,0x40,0x8,0x8,0xf8,0x0,
-+0x0,0x40,0x31,0x11,0x82,0x44,0x48,0x13,0x12,0x22,0xe2,0x22,0x22,0x22,0x21,0x20,0x80,0x80,0x40,0x40,0x20,0x10,0xe,0xf4,0x10,0x10,0x50,0x20,0x4,0x4,0xfc,0x0,
-+0x4,0xff,0x4,0x4,0x5f,0x50,0x57,0x75,0x17,0x74,0x57,0x55,0x95,0x27,0x44,0x80,0x84,0xfe,0xa8,0xa4,0xfe,0x20,0xa0,0x24,0xa4,0xa4,0xa8,0x28,0x10,0xb2,0x4a,0x86,
-+0x10,0x11,0x11,0x11,0xfc,0x17,0x14,0x1f,0x30,0xd0,0x1f,0x10,0x11,0x12,0x54,0x20,0x10,0xf8,0x10,0xf0,0x4,0xbe,0xa4,0xbc,0x40,0x44,0xfe,0xe0,0x50,0x4e,0x44,0x40,
-+0x10,0x10,0x55,0x39,0x10,0xfc,0x10,0x33,0x39,0x55,0x91,0x11,0x11,0x12,0x14,0x10,0x10,0x50,0x50,0x7c,0x90,0x10,0xfe,0x4,0x7e,0x44,0x44,0x44,0x7c,0x80,0x7e,0x0,
-+0x10,0x10,0x17,0x10,0xff,0x12,0x33,0x3a,0x57,0x54,0x91,0x11,0x11,0x11,0x11,0x11,0x90,0x94,0xfe,0x90,0xfc,0x94,0xfc,0x94,0xfc,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,
-+0x4,0x4,0xff,0x4,0x3f,0x24,0x3f,0x24,0x3f,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x40,0x44,0xfe,0x48,0xfc,0x48,0xf8,0x48,0xf8,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,
-+0x8,0x8,0x7f,0x8,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x1,0xff,0x1,0x1,0x1,0x1,0x20,0x28,0xfc,0x20,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x0,0x0,0x0,0x0,
-+0x0,0x3f,0x20,0x2f,0x28,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x22,0x45,0x44,0x88,0x10,0x4,0xfe,0x0,0x84,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0x24,0x4,0x84,0x94,0x8,
-+0x10,0x3e,0x50,0x9,0x1,0xff,0x1,0x3f,0x21,0x23,0x25,0x5,0x9,0x11,0x61,0x1,0x20,0x7c,0xa0,0x10,0x4,0xfe,0x8,0xfc,0x8,0x88,0x58,0x20,0x10,0xe,0x4,0x0,
-+0x10,0x10,0x17,0x24,0x25,0x65,0xa5,0x25,0x25,0x25,0x25,0x21,0x22,0x24,0x28,0x20,0x0,0x44,0xe4,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x44,0x4,0x84,0x44,0x14,0x8,
-+0x2,0x1f,0x12,0x12,0x12,0x12,0x12,0xff,0x12,0x12,0x12,0x12,0x12,0x12,0x26,0x41,0x8,0x7c,0x48,0x48,0x48,0x48,0x48,0xfe,0x48,0x48,0x48,0x48,0x48,0x48,0xa8,0x10,
-+0x0,0x40,0x27,0x24,0x85,0x65,0x25,0xd,0x15,0x25,0xe5,0x21,0x22,0x24,0x28,0x20,0x0,0x44,0xe4,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x4,0x84,0x44,0x54,0x8,
-+0x0,0x1f,0x10,0x10,0x1f,0x10,0x10,0x17,0x10,0x10,0x1f,0x11,0x22,0x24,0x4f,0x80,0x4,0xfe,0x4,0x4,0xfc,0x0,0x10,0xf8,0x0,0x4,0xfe,0x0,0x10,0x8,0xfc,0x4,
-+0x0,0x8,0x7c,0x4b,0x4a,0x4a,0x7a,0x12,0x53,0x5c,0x51,0x51,0x5d,0xf1,0x41,0x1,0x88,0x50,0x0,0xfe,0x22,0xaa,0x72,0x22,0xfe,0x4,0xfe,0x4,0xfc,0x4,0xfc,0x4,
-+0x10,0x10,0x17,0x10,0xf8,0x17,0x10,0x19,0x36,0xd4,0x14,0x17,0x14,0x14,0x57,0x24,0x10,0x38,0xc0,0x40,0x44,0xfe,0x40,0x44,0x5e,0x44,0x44,0x5c,0x44,0x44,0xfc,0x4,
-+0x0,0x0,0x3f,0x0,0x12,0x11,0x9,0x4,0x4,0x2,0x1,0x2,0x4,0x8,0x30,0xc0,0x0,0x0,0xf8,0x8,0x8,0x10,0x10,0x20,0x40,0x80,0x0,0x80,0x40,0x30,0xe,0x4,
-+0x8,0x8,0xff,0xa,0x2,0xff,0x4,0x8,0x10,0x17,0x30,0x50,0x90,0x10,0x1f,0x10,0x20,0x24,0xfe,0x20,0x4,0xfe,0x0,0x40,0x48,0xfc,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x4,0x4,0xff,0x4,0x1,0x2,0x4,0x19,0x21,0xdf,0x1,0x9,0x19,0x21,0x5,0x2,0x40,0x44,0xfe,0x40,0x0,0x80,0x40,0x30,0xe,0xf4,0x0,0x20,0x18,0x8,0x0,0x0,
-+0x1,0x1,0xff,0x5,0x9,0x11,0x3f,0xd0,0x10,0x1f,0x10,0x10,0x1f,0x0,0xff,0x0,0x0,0x4,0xfe,0x40,0x20,0x10,0xfe,0x14,0x10,0xf0,0x10,0x10,0xf0,0x4,0xfe,0x0,
-+0x0,0x8,0xfc,0x17,0x10,0x21,0x22,0x7c,0xab,0x2a,0x2b,0x2a,0x2b,0x38,0x27,0x0,0x40,0x40,0x44,0xfe,0xe0,0x50,0x4e,0x44,0xf8,0x8,0xf8,0x8,0xf8,0x4,0xfe,0x0,
-+0x11,0x11,0x17,0x11,0xfc,0x10,0x15,0x1a,0x34,0xd3,0x10,0x12,0x12,0x14,0x51,0x20,0x10,0x10,0xfc,0x10,0x40,0xa0,0x10,0x4e,0x44,0xf8,0x40,0x50,0x4c,0x44,0x40,0x80,
-+0x2,0x1,0x7f,0x48,0x8e,0x12,0x2c,0x68,0x17,0x20,0x5f,0x81,0x9,0x11,0x25,0x2,0x0,0x0,0xfe,0x2,0xf4,0x90,0x60,0x20,0xd0,0xe,0xf4,0x0,0x20,0x18,0x8,0x0,
-+0x0,0x4,0x8,0x10,0x2f,0xc4,0x4,0x8,0x30,0x1,0x21,0x21,0x21,0x21,0x3f,0x20,0x80,0x40,0x20,0x10,0xee,0x24,0x20,0xa0,0x40,0x0,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x8,0x4,0x7f,0x1,0x1,0x3f,0x1,0x2,0xff,0x4,0x8,0x17,0x20,0x40,0x80,0x1f,0x20,0x48,0xfc,0x0,0x10,0xf8,0x0,0x4,0xfe,0x0,0x20,0xf0,0x80,0x80,0x88,0xfc,
-+0x0,0x40,0x37,0x14,0x0,0x0,0xf7,0x10,0x10,0x10,0x17,0x10,0x14,0x18,0x10,0x0,0x80,0x40,0xfe,0x2,0x24,0x70,0x80,0x80,0x88,0xfc,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x10,0x10,0x11,0x11,0xfd,0x11,0x11,0x1d,0x31,0xd1,0x11,0x11,0x11,0x12,0x54,0x20,0x8,0x1c,0xe0,0x0,0x0,0x4,0xfe,0x20,0x20,0x30,0x2c,0x24,0x20,0x20,0x20,0x20,
-+0x8,0x8,0x28,0x2e,0x28,0x28,0x2e,0x71,0x1,0xff,0x3,0x5,0x9,0x11,0x21,0x1,0x80,0x88,0x98,0xa0,0xc0,0x84,0x84,0x7c,0x0,0xff,0x80,0x40,0x20,0x1c,0x8,0x0,
-+0x4,0x8,0x12,0xea,0x2c,0x29,0x14,0xe6,0xa,0x12,0x66,0xa,0x13,0xe2,0x14,0x8,0x8,0x8,0x8,0x8,0x8,0xfe,0x8,0x18,0x18,0x28,0x48,0x88,0x8,0x8,0x28,0x10,
-+0x10,0x10,0x11,0x12,0xff,0x12,0x16,0x1b,0x30,0xd1,0x12,0x1c,0x10,0x11,0x50,0x20,0x40,0x80,0xf0,0x20,0xf8,0x48,0x48,0xf8,0xa0,0x22,0x1e,0xc0,0x30,0x80,0x60,0x10,
-+0x10,0x10,0x11,0x13,0xf8,0x17,0x10,0x19,0x32,0xd4,0x19,0x12,0x10,0x11,0x50,0x23,0x80,0xa0,0x10,0xf8,0x80,0xfe,0xa0,0x10,0x48,0x8e,0x24,0x40,0x90,0x20,0x40,0x80,
-+0x11,0x10,0x10,0x7d,0x55,0x55,0x55,0x55,0x7d,0x11,0x14,0x1f,0xe4,0x40,0x0,0x0,0x4,0x8c,0x50,0xfc,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0xfe,0x20,0x20,0x20,0x20,
-+0x20,0x20,0x20,0x39,0x4b,0x56,0x82,0x23,0x20,0x21,0x26,0x20,0x28,0x31,0x20,0x0,0x80,0x80,0xf0,0x20,0xf8,0x48,0x48,0xf8,0xa2,0x22,0x1e,0xc0,0x30,0x80,0x60,0x10,
-+0x1,0x21,0x11,0x12,0x7,0x2,0xf2,0x13,0x10,0x11,0x16,0x10,0x10,0x15,0x18,0x0,0x0,0x0,0xf0,0x20,0xf8,0x48,0x48,0xf8,0xa2,0x22,0x1e,0xc0,0x30,0x80,0x60,0x10,
-+0x10,0x10,0x27,0x24,0x4d,0xf5,0x25,0x45,0xfd,0x5,0x5,0x1c,0xe5,0x48,0x13,0x20,0x40,0x24,0xfe,0x0,0xfc,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0xfc,0x20,0xfe,0x0,
-+0x10,0x10,0x10,0x1d,0x20,0x20,0x7c,0x91,0x11,0xfd,0x11,0x11,0x15,0x19,0x12,0x4,0x20,0x10,0x4,0xfe,0x0,0x84,0x48,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x2,0x1,0x1,0x7f,0x8,0x4,0x4,0x1f,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x80,0x0,0x0,0x8,0xfc,0x10,0x20,0x48,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x20,0x17,0x50,0x44,0x42,0x4f,0x49,0x4f,0x49,0x4f,0x41,0x5f,0x41,0x41,0x41,0x40,0x4,0xfe,0x4,0x44,0x84,0xe4,0x24,0xe4,0x24,0xe4,0x4,0xf4,0x4,0x4,0x4,0xc,
-+0x8,0xff,0x0,0x7f,0x55,0x5d,0x55,0x7f,0x0,0x3e,0x32,0x2a,0x3e,0x0,0xff,0x0,0x4,0xfe,0x10,0x24,0x7e,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x10,0x28,0x46,0x82,
-+0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x0,0x3f,0x20,0x20,0x3f,0x20,0x20,0x3f,0x20,0xf0,0x10,0x10,0xf0,0x10,0x10,0xf0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x1,0x45,0x29,0x11,0x29,0x49,0x9,0x18,0x2b,0x4a,0x8a,0xb,0xa,0xa,0x53,0x22,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x4,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,
-+0x20,0x27,0x20,0x20,0xf8,0x21,0x27,0x21,0x21,0x21,0x3a,0xe2,0x44,0x8,0x11,0x0,0x0,0xf8,0x20,0x40,0x80,0x4,0xfe,0x24,0x24,0x24,0x24,0x44,0x44,0x84,0x28,0x10,
-+0x1,0x11,0x9,0x1,0x7f,0x40,0x80,0x1f,0x0,0x0,0x7f,0x2,0x4,0x8,0x1f,0x0,0x0,0x10,0x20,0x0,0xfe,0x2,0x24,0xf0,0x0,0x8,0xfc,0x0,0x40,0x20,0xf0,0x10,
-+0x1,0x11,0x9,0x7f,0x40,0x8f,0x8,0xf,0x1,0x1f,0x11,0x11,0x11,0x11,0x1,0x1,0x0,0x10,0x20,0xfe,0x2,0xe4,0x20,0xe0,0x10,0xf8,0x10,0x10,0x10,0x50,0x20,0x0,
-+0x8,0x8,0x8,0x8,0x8,0x9,0x8,0xff,0x9,0x9,0x8,0x8,0x8,0x9,0xe,0x8,0x0,0x10,0x30,0x40,0x80,0x0,0x4,0xfe,0x0,0x0,0x80,0x40,0x20,0x1c,0x8,0x0,
-+0x8,0xa,0x9,0x10,0x17,0x34,0x58,0x93,0x10,0x10,0x1f,0x10,0x10,0x11,0x13,0x10,0x40,0x48,0x50,0x40,0xfe,0x2,0x14,0xf8,0x0,0x4,0xfe,0x40,0x90,0x8,0xfc,0x4,
-+0x8,0x7f,0x48,0x48,0x48,0x79,0x4b,0x48,0x48,0x79,0x49,0x4a,0x4c,0x48,0x49,0x98,0x0,0xf8,0x20,0x40,0x80,0x4,0xfe,0x94,0x94,0x24,0x24,0x44,0x44,0x84,0x28,0x10,
-+0x0,0x0,0x1f,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x80,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x8,0x49,0x29,0x2a,0x8,0x7f,0x41,0x41,0x5d,0x55,0x55,0x55,0x5d,0x41,0x45,0x42,0x20,0x20,0x20,0x24,0x7e,0x84,0x44,0x44,0x48,0x28,0x28,0x10,0x28,0x28,0x46,0x84,
-+0x10,0x13,0x10,0x7c,0x54,0x55,0x57,0x7c,0x54,0x55,0x55,0x7e,0x54,0x10,0x11,0x10,0x0,0xf8,0x20,0x40,0x80,0x4,0xfe,0x94,0x94,0x24,0x24,0x44,0x44,0x84,0x28,0x10,
-+0x1,0x9,0x7d,0x49,0x49,0x49,0x49,0x48,0x4b,0x4a,0x7a,0x4b,0x2,0x2,0x3,0x2,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x4,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,
-+0x13,0x12,0x12,0x23,0x22,0x62,0xa3,0x20,0x27,0x24,0x24,0x27,0x24,0x24,0x27,0x24,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x4,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,
-+0x10,0x13,0x10,0x7c,0x10,0x10,0xfd,0x12,0x51,0x5d,0x51,0x51,0x71,0x48,0x87,0x0,0x8,0xfc,0x88,0x88,0x88,0xa8,0x10,0x0,0xf8,0x8,0x8,0x8,0xf8,0x6,0xfc,0x0,
-+0x10,0x10,0x10,0x10,0xfd,0x11,0x15,0x1a,0x32,0xd4,0x10,0x10,0x10,0x10,0x50,0x27,0x40,0x40,0x40,0x40,0x50,0x48,0x46,0x42,0x48,0x48,0x48,0x50,0x10,0x20,0xc0,0x0,
-+0x10,0x10,0x10,0x1c,0x21,0x21,0x7d,0x92,0x12,0x7c,0x10,0x10,0x14,0x18,0x10,0x7,0x40,0x40,0x40,0x40,0x50,0x48,0x46,0x42,0x48,0x48,0x48,0x50,0x10,0x20,0xc0,0x0,
-+0x8,0xa,0x7f,0x8,0x9,0x7f,0x41,0x7f,0x41,0x7f,0x48,0xa,0xff,0x8,0x8,0x9,0x4,0x7e,0x44,0x44,0x44,0xfc,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x44,0x94,0x8,
-+0x2,0x22,0xff,0xa2,0xa2,0xaf,0xa8,0xaf,0xa8,0xaf,0xaa,0xe2,0xbf,0x2,0x2,0x2,0x4,0x3e,0xa4,0x24,0xa4,0xfc,0xa4,0xa4,0xa4,0xbc,0x24,0xa4,0xe4,0x24,0x44,0x8c,
-+0x2,0x42,0x2f,0x22,0x2,0x8f,0x48,0x4f,0x8,0x1f,0x2a,0xe2,0x3f,0x22,0x22,0x22,0x4,0x3e,0xa4,0x24,0xa4,0xfc,0xa4,0xa4,0xa4,0xbc,0x24,0xa4,0xe4,0x24,0x44,0x8c,
-+0x11,0x11,0x22,0x11,0x3f,0x21,0x3f,0x21,0x3f,0x1,0xff,0x5,0x9,0x11,0x61,0x1,0x10,0x10,0x20,0x10,0xf8,0x8,0xf8,0x8,0xf8,0x4,0xfe,0x40,0x20,0x1c,0x8,0x0,
-+0x0,0x8,0x7c,0x48,0x49,0x49,0x49,0x4a,0x4a,0x4c,0x48,0x78,0x48,0x0,0x0,0x7,0x40,0x40,0x40,0x40,0x50,0x48,0x46,0x42,0x48,0x48,0x48,0x10,0x10,0x20,0xc0,0x0,
-+0x10,0x10,0x10,0x10,0x55,0x59,0x51,0x92,0x12,0x14,0x10,0x28,0x24,0x44,0x80,0x7,0x40,0x40,0x40,0x40,0x50,0x48,0x46,0x42,0x48,0x48,0x48,0x10,0x10,0x20,0xc0,0x0,
-+0x2,0x2,0x7f,0x4,0x9,0x11,0x21,0x3f,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x0,0x8,0xfc,0x0,0x0,0x0,0x20,0xf0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x10,0x10,0x10,0xfc,0x11,0x15,0x19,0x31,0xd1,0x11,0x11,0x11,0x17,0x50,0x20,0x20,0x20,0x20,0x20,0x20,0x28,0x3c,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,0x0,
-+0x22,0x21,0x2f,0x22,0xf4,0x2f,0x20,0x37,0x24,0xe7,0x24,0x27,0x24,0x24,0xa4,0x45,0x10,0x10,0xd0,0x14,0xbe,0xc4,0x24,0xa8,0xa8,0xa8,0x90,0x90,0xa8,0xa8,0xc6,0x84,
-+0x25,0x3f,0x44,0xbf,0x4,0x3f,0x24,0x25,0x0,0x3f,0x1,0x1f,0x1,0x7f,0x1,0x3,0x4,0x84,0x24,0xa4,0x24,0xa4,0xa4,0x8c,0x30,0xc0,0x0,0xf0,0x0,0xfc,0x0,0x0,
-+0x10,0x12,0x12,0x22,0x42,0x92,0x13,0x2e,0x62,0xa2,0x22,0x23,0x20,0x20,0x21,0x22,0x0,0x4,0xfe,0x24,0x24,0xa4,0xe4,0x24,0x24,0x64,0xa4,0x24,0x44,0x84,0x28,0x10,
-+0x2,0x41,0x2f,0x22,0x4,0x8f,0x40,0x47,0x14,0x27,0xe4,0x27,0x24,0x24,0x24,0x25,0x10,0x10,0xd0,0x14,0xbe,0xc4,0x24,0xa8,0xa8,0xa8,0x90,0x90,0xa8,0xa8,0xc6,0x84,
-+0x11,0x11,0x11,0x11,0xff,0x11,0x33,0x3b,0x55,0x55,0x99,0x11,0x11,0x11,0x11,0x11,0x0,0x3e,0x22,0x24,0xe4,0x28,0x28,0xa4,0x62,0x22,0x22,0x32,0x2a,0x24,0x20,0x20,
-+0x0,0x3f,0x21,0x21,0x21,0x3f,0x20,0x20,0x20,0x3f,0x21,0x21,0x21,0x21,0x3f,0x0,0x8,0xfc,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x8,0xfc,0x0,
-+0x0,0x3f,0x20,0x20,0x3f,0x20,0x20,0x3f,0x25,0x25,0x24,0x24,0x44,0x45,0x86,0x4,0x10,0xf8,0x0,0x20,0xf0,0x0,0x8,0xfc,0x0,0x10,0xa0,0x40,0x30,0xe,0x4,0x0,
-+0x1,0x1,0x5,0xd,0x11,0x21,0x41,0x0,0x1,0x1,0x7f,0x1,0x1,0x1,0xff,0x0,0x0,0x0,0x40,0x20,0x18,0xc,0x4,0x0,0x0,0x8,0xfc,0x0,0x0,0x4,0xfe,0x0,
-+0x1f,0x10,0x1f,0x10,0x1f,0x0,0x3f,0x20,0x2f,0x20,0x3f,0x25,0x44,0x44,0x87,0x4,0xf0,0x10,0xf0,0x10,0xf0,0x0,0xf8,0x0,0xf0,0x4,0xfe,0x8,0x90,0x60,0x1e,0x4,
-+0x10,0x10,0x10,0x10,0x53,0x5a,0x54,0x90,0x10,0x10,0x10,0x11,0x11,0x12,0x14,0x18,0x40,0x40,0x40,0x40,0xfc,0x44,0x48,0x40,0x40,0xa0,0xa0,0x20,0x22,0x22,0x1e,0x0,
-+0x0,0x40,0x37,0x14,0x84,0x68,0x21,0x9,0x11,0x21,0xe1,0x21,0x22,0x22,0x24,0x28,0x0,0x0,0xfc,0x4,0x8,0x20,0xf0,0x20,0x20,0x20,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x0,0x78,0x48,0x57,0x50,0x60,0x51,0x4a,0x4b,0x48,0x69,0x51,0x42,0x44,0x40,0x40,0x40,0x40,0x44,0xfe,0x80,0xa0,0x20,0x28,0xfc,0x20,0x28,0x24,0x26,0x22,0xa0,0x40,
-+0x10,0x10,0x10,0x7d,0x11,0x12,0xfc,0x11,0x10,0x5c,0x51,0x50,0x70,0x48,0x87,0x0,0x40,0x40,0xa0,0x10,0x28,0x6e,0x84,0x20,0x60,0x88,0x18,0x20,0x40,0x86,0xfc,0x0,
-+0x20,0x10,0x10,0x0,0xfc,0xb,0x10,0x34,0x59,0x94,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x90,0x90,0x10,0x10,0x10,0x50,0x20,
-+0x12,0x11,0x17,0x14,0xf9,0x11,0x11,0x18,0x37,0xd0,0x13,0x10,0x17,0x10,0x51,0x20,0x48,0x50,0xfe,0x2,0xf4,0x10,0xf0,0x18,0xe0,0x40,0xf8,0x40,0xfc,0x40,0x40,0x80,
-+0x4,0xe,0x78,0x8,0x9,0xfe,0x8,0x1c,0x1a,0x28,0x29,0x49,0x8a,0x8,0x8,0x8,0x40,0x40,0x80,0x80,0xfe,0x4,0x28,0x20,0xa8,0xa4,0x26,0x22,0x20,0x20,0xa0,0x40,
-+0x20,0x20,0x20,0x27,0xfc,0x24,0x24,0x27,0x24,0x24,0x3c,0xe6,0x45,0x4,0x8,0x10,0x20,0x28,0x24,0xfe,0x20,0x20,0x24,0xa4,0xa8,0xa8,0x90,0x90,0x30,0x4a,0x8a,0x6,
-+0x10,0x13,0x10,0x12,0xfd,0x12,0x37,0x38,0x57,0x52,0x92,0x13,0x11,0x10,0x1f,0x10,0x0,0xa8,0xb4,0xa8,0x10,0x8,0xfe,0x4,0xf8,0x8,0x8,0xf8,0x10,0xa0,0xfe,0x0,
-+0x0,0x0,0x0,0x3f,0x20,0x20,0x20,0x3e,0x22,0x22,0x22,0x2a,0x24,0x40,0x81,0x0,0x80,0xa0,0x90,0xfc,0x80,0x80,0x84,0x44,0x48,0x48,0x30,0x20,0x62,0x92,0xa,0x6,
-+0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x0,0x7f,0x1,0x1,0x3f,0x1,0x1,0xff,0x0,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,0x8,0xfc,0x0,0x10,0xf8,0x0,0x4,0xfe,0x0,
-+0x0,0x0,0x1f,0x1,0xff,0x5,0x3d,0x5,0xd,0x75,0x3,0x5,0x9,0x11,0x61,0x1,0x20,0xf0,0x0,0x4,0xfe,0x40,0x58,0x60,0x44,0x3c,0x80,0x40,0x30,0x1c,0x8,0x0,
-+0x8,0x1d,0xf1,0x11,0x11,0xff,0x11,0x38,0x37,0x54,0x50,0x91,0x10,0x10,0x17,0x10,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x0,0xfe,0x20,0x28,0xfc,0x20,0x24,0xfe,0x0,
-+0x10,0x1b,0x20,0x40,0x12,0x1a,0x32,0x52,0x97,0x10,0x2a,0x29,0x28,0x48,0x7,0x0,0x8,0xfc,0x40,0x50,0x78,0x40,0x40,0x48,0xfc,0x0,0x10,0x88,0xa4,0x24,0xe0,0x0,
-+0x0,0x47,0x31,0x15,0x82,0x44,0x4f,0x10,0x17,0x24,0xe4,0x27,0x22,0x21,0x3f,0x20,0x0,0x50,0x68,0x50,0x20,0x10,0xfe,0x4,0xf0,0x10,0x10,0xf0,0x20,0x44,0xfe,0x0,
-+0x0,0x40,0x20,0x27,0x4,0x4,0xe4,0x27,0x24,0x24,0x24,0x2e,0x35,0x24,0x8,0x10,0x20,0x28,0x24,0xfe,0x20,0x20,0x24,0xa4,0xa8,0xa8,0x90,0x90,0x30,0x4a,0x8a,0x6,
-+0x1f,0x0,0x1,0x1,0x79,0xf,0x9,0x11,0x17,0x21,0x21,0x4f,0x81,0x1,0x5,0x2,0xf0,0x20,0x40,0x84,0x2c,0xf0,0x20,0x10,0xd0,0x8,0x4e,0xe4,0x0,0x0,0x0,0x0,
-+0x0,0x47,0x24,0x24,0x7,0x0,0xef,0x20,0x20,0x27,0x20,0x20,0x2f,0x50,0x8f,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0xf8,0x80,0xa0,0xf0,0x80,0x90,0xf8,0x6,0xfc,0x0,
-+0x8,0xfc,0x9,0x49,0x49,0x49,0x49,0x48,0x7f,0x4,0x5,0x1c,0xe4,0x44,0x14,0x8,0x20,0x24,0xfe,0x24,0xfc,0x24,0xfc,0x4,0xfe,0x80,0xfc,0x4,0x4,0x4,0x28,0x10,
-+0x8,0x1c,0xf1,0x10,0x11,0xfc,0x10,0x38,0x37,0x54,0x50,0x90,0x10,0x10,0x10,0x10,0x0,0x8,0xfc,0x20,0x24,0xa4,0xa8,0x20,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x0,0x8,0x7c,0x48,0x49,0x4a,0x4d,0x48,0x48,0x48,0x48,0x79,0x4a,0x2,0x1,0x0,0x80,0x80,0x88,0xfc,0x0,0x0,0xf8,0x10,0x20,0x40,0x80,0x0,0x2,0x2,0xfe,0x0,
-+0x1,0x0,0x1f,0x12,0x92,0x53,0x55,0x19,0x31,0x5f,0xd1,0x11,0x12,0x22,0x44,0x8,0x0,0x84,0xfe,0x0,0x4,0xfe,0x24,0x24,0x24,0xe4,0x24,0x24,0xa4,0x7c,0x24,0x0,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x17,0x18,0x30,0xd7,0x12,0x11,0x11,0x10,0x50,0x20,0x40,0x40,0x50,0xf8,0x40,0x48,0xfc,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x2,0x3f,0x22,0x22,0x3e,0x22,0x3e,0x2,0xff,0x8,0x2a,0x2f,0x28,0x58,0x87,0x0,0x40,0x40,0x40,0x40,0x48,0x58,0x60,0x40,0x40,0x44,0x44,0x3c,0x0,0x6,0xfc,0x0,
-+0x0,0x40,0x32,0x12,0x82,0x63,0x2e,0x2,0x12,0x22,0xe2,0x22,0x22,0x22,0x21,0x20,0x40,0x40,0x40,0x48,0x7c,0xc8,0x48,0x48,0x48,0x48,0x68,0x50,0x42,0x2,0xfe,0x0,
-+0x0,0x43,0x22,0x22,0x2,0x3,0xe2,0x22,0x22,0x22,0x22,0x24,0x28,0x50,0x8f,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x80,0x80,0x40,0x20,0x1c,0x0,0x6,0xfc,0x0,
-+0x8,0x7c,0x9,0x9,0x9,0x79,0x41,0x47,0x41,0x79,0x9,0x9,0x9,0x9,0x50,0x20,0x20,0x20,0x20,0x20,0x24,0x3e,0xe4,0x24,0x24,0x24,0x34,0x28,0x22,0x2,0xfe,0x0,
-+0x8,0xfc,0x9,0x49,0x49,0x49,0x49,0x4b,0x7d,0x5,0x5,0x1d,0xe5,0x5,0x28,0x10,0x20,0x20,0x20,0x20,0x24,0x3e,0xe4,0x24,0x24,0x24,0x34,0x28,0x22,0x2,0xfe,0x0,
-+0x2,0xff,0x24,0x24,0x3c,0x24,0x24,0x3c,0x24,0x24,0x3f,0xe4,0x44,0x7,0x4,0x4,0x10,0x10,0x10,0x90,0x94,0x9e,0x90,0x90,0x90,0x90,0x90,0x90,0x94,0xfe,0x0,0x0,
-+0x1,0x11,0x11,0x11,0x11,0x11,0xff,0x0,0x21,0x21,0x22,0x24,0x28,0x20,0x3f,0x20,0x0,0x20,0xf0,0x0,0x0,0x4,0xfe,0x0,0x8,0x8,0x88,0x68,0x28,0x8,0xf8,0x8,
-+0x8,0x8,0x9,0x13,0x10,0x30,0x50,0x91,0x16,0x10,0x10,0x13,0x10,0x10,0x10,0x17,0x80,0xfc,0x8,0x10,0xa0,0x40,0x90,0x10,0x20,0x7e,0x84,0x48,0x30,0x20,0xc0,0x0,
-+0x0,0x1f,0x10,0x10,0x10,0x10,0x1f,0x14,0x14,0x12,0x11,0x10,0x20,0x20,0x40,0x80,0x10,0xf8,0x10,0x10,0x10,0x10,0xf0,0x10,0x0,0x0,0x0,0x80,0x40,0x30,0xe,0x4,
-+0x1,0x1,0x1,0x3f,0x1,0x1,0xff,0x4,0x4,0x14,0x14,0x24,0x48,0x88,0x11,0x20,0x0,0x0,0x10,0xf8,0x0,0x4,0xfe,0x40,0x40,0x50,0x48,0x46,0x42,0x40,0x40,0x80,
-+0x20,0x20,0x27,0xf8,0x24,0x22,0x70,0x50,0x52,0x54,0x50,0x52,0x21,0x50,0x4f,0x80,0x0,0x4,0xbe,0x84,0xa4,0x94,0x84,0x84,0x94,0xa4,0x84,0x94,0x8,0x6,0xfc,0x0,
-+0x0,0x0,0x3f,0x20,0x20,0x20,0x3f,0x20,0x20,0x23,0x20,0x20,0x40,0x40,0x80,0x0,0x10,0x78,0x80,0x0,0x0,0x8,0xfc,0x80,0x80,0x80,0xe0,0xb0,0x90,0x80,0x80,0x80,
-+0x10,0x10,0x11,0x15,0x59,0x51,0x51,0x91,0x11,0x11,0x10,0x28,0x25,0x42,0x84,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,0x90,0x88,0xc,0x4,0x0,
-+0x2,0x1,0x1,0xff,0x2,0x4,0x8,0x1f,0x4,0x4,0x4,0x4,0x8,0x8,0x10,0x60,0x0,0x0,0x4,0xfe,0x0,0x40,0x20,0xf0,0x50,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x0,0x40,0x20,0x20,0x7,0x14,0x14,0x14,0x24,0xe7,0x24,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0xfc,0x44,0x40,0x40,0x40,0x40,0x40,
-+0x1,0x1,0x1,0x1,0x3f,0x21,0x21,0x21,0x21,0x3f,0x21,0x1,0x1,0x1,0x7e,0x20,0x0,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,0x10,0x8,0xfc,0x4,0x0,
-+0x1,0x21,0x21,0x3f,0x22,0x1,0x7f,0x40,0x9f,0x0,0x7f,0x1,0x11,0x11,0x25,0x2,0x0,0x8,0x8,0xf8,0x8,0x0,0xfe,0x2,0xf4,0x0,0xfc,0x0,0x20,0x18,0x8,0x0,
-+0x2,0x1,0x7f,0x42,0x82,0x2,0x3f,0x2,0x2,0x4,0x4,0x8,0x9,0x12,0x20,0x40,0x0,0x0,0xfe,0x2,0x84,0x50,0xf8,0x80,0x90,0xb0,0xc0,0x80,0x82,0x82,0x7e,0x0,
-+0x10,0x10,0x10,0x10,0xfd,0x11,0x15,0x19,0x31,0xd1,0x11,0x11,0x11,0x11,0x51,0x21,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0x24,0xfc,0x4,
-+0x2,0xff,0x28,0x2a,0xff,0xaa,0xaa,0xaa,0xc6,0x82,0xfe,0x82,0x82,0xfe,0x83,0x2,0x44,0x44,0x54,0x54,0x54,0x54,0xfc,0x54,0x54,0x54,0x54,0x54,0x94,0x94,0x4,0x4,
-+0x0,0x4,0x7f,0x54,0x57,0x54,0x57,0x7c,0x54,0x57,0x55,0x55,0x7e,0x44,0x8,0x0,0x40,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x80,0x88,0xfe,0x8,0x48,0x28,0x8,0x28,0x10,
-+0x0,0x7c,0x47,0x44,0x47,0x44,0x7f,0x10,0x10,0x5f,0x51,0x51,0x5a,0xe4,0x48,0x0,0x40,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x80,0x88,0xfe,0x8,0x48,0x28,0x8,0x28,0x10,
-+0x8,0x1f,0xf2,0x12,0x12,0xfe,0x12,0x3a,0x36,0x52,0x52,0x92,0x12,0x12,0x14,0x18,0x0,0xfe,0x22,0x22,0xfa,0x22,0x22,0xfa,0x2,0xfa,0x8a,0x8a,0x8a,0xfa,0x8a,0x4,
-+0x4,0xe,0x78,0x8,0xfe,0x8,0x1d,0x2a,0x48,0x9,0x2,0x29,0x28,0x48,0x7,0x0,0x20,0x20,0x20,0xa4,0xac,0xb0,0x50,0x48,0x8e,0x4,0x0,0x90,0xac,0x24,0xe0,0x0,
-+0x10,0x1f,0x28,0x45,0x1,0x7f,0x2,0x3f,0x4,0xff,0x8,0x1f,0x24,0x42,0x2,0x0,0x40,0x7c,0xa0,0x10,0x0,0xfc,0x0,0xf8,0x0,0xfe,0x10,0xfc,0x10,0x10,0x50,0x20,
-+0x9,0x9,0x9,0x11,0x17,0x31,0x51,0x91,0x11,0x11,0x11,0x12,0x12,0x14,0x18,0x10,0x0,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x10,0x17,0x24,0x24,0x4d,0xfc,0x14,0x25,0x44,0xfd,0x5,0x5,0x1d,0xe5,0x48,0x10,0x4,0xfe,0x44,0x44,0xf4,0x44,0x44,0xf4,0x4,0xf4,0x14,0x14,0x14,0xf4,0x14,0x8,
-+0x0,0x9,0x7f,0x49,0x49,0x7f,0x49,0x4b,0x4b,0x7d,0x49,0x49,0x49,0x79,0x49,0x1,0x80,0xd0,0x10,0x12,0x56,0xb8,0x10,0x90,0x50,0x10,0x28,0x28,0x28,0x46,0x84,0x0,
-+0x0,0x3f,0x2,0x2,0x2,0x2,0x2,0x1f,0x4,0x4,0x4,0x4,0x4,0x4,0xff,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0xf0,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x0,
-+0x2,0x4,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x1f,0x1,0x1,0xff,0x2,0x4,0x18,0x60,0x0,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x20,0x14,0xfe,0x80,0x60,0x1c,0x8,
-+0x20,0x10,0x10,0x5,0xfc,0x8,0x10,0x34,0x58,0x94,0x10,0x10,0x10,0x11,0x12,0x14,0x0,0x0,0x4,0xfe,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x4,0x28,0x10,
-+0x1,0x1,0x21,0x21,0x21,0x21,0x3f,0x21,0x1,0x41,0x41,0x41,0x41,0x41,0x7f,0x40,0x0,0x0,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x20,0x27,0x24,0x24,0xff,0x24,0x75,0x6d,0xa5,0x25,0x24,0x25,0x25,0x2b,0x30,0x20,0x4,0xfe,0x0,0x44,0xe4,0x4,0xde,0x44,0x44,0xd4,0xc,0x44,0x44,0xe4,0x14,0x8,
-+0x0,0x3f,0x20,0x3f,0x20,0x2f,0x29,0x29,0x29,0x2f,0x20,0x29,0x2a,0x23,0x5c,0x80,0x4,0xfe,0x0,0x88,0x8,0x8,0xfe,0x8,0x8,0x48,0x28,0x8,0x8,0x88,0x28,0x10,
-+0x4,0x7f,0x44,0x44,0x47,0x7c,0x10,0x17,0x50,0x59,0x53,0x55,0x5d,0xf1,0x41,0x1,0x90,0xfe,0x90,0x48,0xf8,0x50,0x64,0xfe,0x80,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,
-+0x20,0x20,0x23,0x7a,0x82,0x2,0xfb,0x22,0x22,0xfb,0x22,0x22,0x2f,0x30,0x20,0x0,0x10,0x10,0xd0,0x54,0x7e,0x54,0xd4,0x54,0x54,0xd4,0x54,0x54,0xf4,0x24,0x54,0x88,
-+0x10,0x10,0x20,0x3c,0x45,0x8a,0x14,0xfe,0x4,0x4,0x7c,0x4,0x4,0xfc,0x4,0x0,0x40,0x50,0x94,0xfe,0x90,0x90,0xfc,0x90,0x90,0xfc,0x90,0x90,0x94,0xfe,0x80,0x80,
-+0x0,0x5e,0x32,0x34,0x14,0x95,0x5a,0x14,0x32,0x33,0xda,0x54,0x51,0x52,0x50,0x10,0x20,0x20,0x50,0x50,0x88,0x6,0xfc,0x20,0x24,0xfe,0x20,0xa8,0x26,0x22,0xa0,0x40,
-+0x0,0x78,0x48,0x50,0x51,0x62,0x55,0x48,0x48,0x4f,0x68,0x51,0x42,0x44,0x41,0x40,0x40,0x40,0xa0,0xa0,0x10,0xe,0xf4,0x40,0x50,0xfc,0x40,0x50,0x4c,0x44,0x40,0x80,
-+0x8,0x8,0x7e,0x8,0x1c,0x2a,0x48,0x3f,0x1,0x9,0x9,0x11,0x11,0x29,0x47,0x80,0x20,0x28,0xfc,0x20,0x78,0xa4,0x20,0xf8,0x10,0x40,0xe0,0x0,0x0,0x6,0xfc,0x0,
-+0x0,0x4,0xfe,0x11,0x11,0x21,0x25,0x7f,0xa4,0x25,0x25,0x25,0x25,0x3d,0x25,0x1,0x20,0x20,0x20,0x24,0x24,0x24,0x24,0xfc,0x20,0x24,0x24,0x24,0x24,0x24,0xfc,0x4,
-+0x10,0x10,0x18,0x25,0x24,0x60,0xbd,0x24,0x25,0x26,0x24,0x25,0x26,0x24,0x20,0x20,0x40,0x40,0x48,0xfc,0x50,0x64,0xfe,0x88,0xfc,0x88,0x88,0xf8,0x88,0x88,0xf8,0x88,
-+0x1,0x3f,0x1,0xf,0x8,0x9,0x9,0x7f,0x8,0x7e,0x8,0x3e,0x22,0x2a,0x2a,0xff,0x10,0xf8,0x0,0xe0,0x20,0x20,0x28,0xfc,0x20,0xfc,0x20,0xf8,0x88,0xa8,0xa8,0xfe,
-+0x10,0x10,0x1f,0x10,0xfd,0x13,0x10,0x18,0x33,0xd0,0x17,0x14,0x17,0x14,0x57,0x24,0x80,0x44,0xfe,0x80,0x10,0xf0,0x40,0x88,0xf8,0x4,0xfe,0x44,0xfc,0x44,0xfc,0x4,
-+0x20,0x20,0x3c,0x48,0x51,0xfd,0x55,0x55,0x7d,0x55,0x55,0x7d,0x54,0x54,0x55,0x8c,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0xfc,0x20,0x28,0x3c,0xe2,0x82,
-+0x0,0x10,0x10,0x10,0x1e,0x22,0x22,0x22,0x54,0x94,0x8,0x14,0x14,0x22,0x41,0x80,0x40,0x40,0x40,0x40,0x40,0x60,0x50,0x4c,0x44,0x40,0x40,0x40,0x40,0x6,0xfc,0x0,
-+0x10,0x10,0x12,0x12,0xfb,0x10,0x17,0x18,0x30,0xd7,0x14,0x14,0x14,0x14,0x54,0x24,0x40,0x40,0x48,0x48,0xf8,0x4,0xfe,0x40,0x84,0xfe,0xa4,0xa4,0xa4,0xa4,0xb4,0x8,
-+0x0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x0,0x4,0x4,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x4,0x4,0x4,
-+0x2,0x1,0x7f,0x44,0x88,0x0,0x3f,0x8,0x10,0x3f,0x1,0x2,0x4,0x18,0x61,0x0,0x0,0x0,0xfe,0x42,0x24,0x0,0xf8,0x40,0x48,0xfc,0x40,0x40,0x40,0x40,0x40,0x80,
-+0x10,0x10,0x10,0x11,0xfc,0x13,0x30,0x39,0x56,0x50,0x91,0x16,0x10,0x17,0x10,0x10,0x80,0xf8,0x88,0xf8,0x14,0xfe,0x80,0x44,0x6c,0xb0,0x30,0x68,0xa6,0x24,0xa0,0x40,
-+0x8,0x8,0x8,0x17,0x10,0x30,0x5f,0x90,0x11,0x13,0x10,0x11,0x10,0x10,0x10,0x10,0x40,0x40,0x48,0xfc,0x40,0x44,0xfe,0x80,0x0,0xfc,0x8,0x10,0xa0,0x40,0x60,0x20,
-+0x8,0x12,0x3f,0x22,0x32,0x2a,0x22,0x23,0xfe,0x22,0x32,0x2a,0x22,0x42,0x8a,0x4,0x8,0x7c,0x48,0x48,0x48,0x48,0x86,0x0,0x4,0xfe,0x84,0x84,0x84,0x84,0xfc,0x84,
-+0x0,0x8,0x7e,0x4a,0x4b,0x48,0x4f,0x48,0x48,0x4b,0x4a,0x4a,0x7a,0x4a,0x2,0x2,0x40,0x40,0x48,0x48,0xf8,0x4,0xfe,0x40,0x84,0xfe,0xa4,0xa4,0xa4,0xa4,0xb4,0x8,
-+0x1,0x1,0x3f,0x21,0x21,0x3f,0x1,0x1,0x7f,0x41,0x41,0x7f,0x41,0x1,0x1,0x1,0x0,0x8,0xfc,0x8,0x8,0xf8,0x0,0x4,0xfe,0x4,0x4,0xfc,0x4,0x0,0x0,0x0,
-+0x1,0x0,0x1f,0x10,0x91,0x52,0x54,0x1b,0x32,0x52,0xd2,0x12,0x22,0x22,0x41,0x0,0x0,0x84,0xfe,0x80,0x40,0x20,0x10,0xee,0x24,0x20,0xa0,0x40,0x8,0x8,0xf8,0x0,
-+0x2,0x1,0x7f,0x48,0x92,0x4,0x3f,0x22,0x23,0x24,0x2a,0x21,0x22,0x24,0x3f,0x20,0x0,0x0,0xfe,0x22,0x14,0x0,0xf8,0x8,0xc8,0x48,0x88,0x8,0x88,0x8,0xf8,0x8,
-+0x20,0x20,0x27,0xf9,0xa8,0xaf,0xa8,0xab,0xaa,0xab,0xaa,0xbb,0x20,0x23,0x20,0x2f,0x80,0x48,0xfc,0x10,0xa4,0xfe,0x8,0xfc,0x48,0xf8,0x48,0xf8,0x40,0xf8,0x40,0xfe,
-+0x1,0x0,0x3f,0x20,0x20,0x20,0x3f,0x20,0x21,0x21,0x22,0x24,0x48,0x50,0x80,0x0,0x0,0x84,0xfe,0x80,0x80,0x88,0xfc,0x80,0xc0,0xa0,0x90,0x88,0x8e,0x84,0x80,0x80,
-+0x20,0x17,0x50,0x40,0x4f,0x40,0x44,0x44,0x44,0x47,0x40,0x5f,0x40,0x40,0x40,0x40,0x4,0xfe,0x4,0x44,0xe4,0x44,0x44,0x44,0x44,0xf4,0x14,0xd4,0x14,0x54,0x24,0xc,
-+0x8,0x8,0x14,0x12,0x21,0x20,0x7e,0xa2,0x22,0x2a,0x24,0x20,0x21,0x21,0x1f,0x0,0x4,0x4,0x4,0x24,0xa4,0xa4,0x24,0x24,0x24,0x24,0x24,0x4,0x4,0x4,0x14,0x8,
-+0x0,0x8,0x7c,0x48,0x49,0x4a,0x48,0x48,0x48,0x48,0x48,0x78,0x49,0x2,0x4,0x8,0x80,0x80,0x80,0xfc,0x4,0x48,0x40,0x40,0x40,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,
-+0x10,0x10,0x10,0x10,0x55,0x5a,0x50,0x90,0x10,0x10,0x10,0x10,0x19,0x26,0x44,0x88,0x80,0x80,0x80,0xfc,0x4,0x48,0x40,0x40,0x40,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,
-+0x10,0x10,0x13,0x10,0xfc,0x17,0x11,0x19,0x37,0xd1,0x11,0x17,0x10,0x10,0x53,0x20,0x8,0x3c,0xc0,0x40,0x48,0xfc,0x50,0x54,0xfe,0x50,0x50,0xfc,0x40,0x50,0xf8,0x0,
-+0x10,0x10,0x13,0x1c,0x20,0x23,0x7d,0x91,0x17,0x79,0x11,0x13,0x14,0x18,0x13,0x0,0x8,0x3c,0xc0,0x40,0x48,0xfc,0x50,0x54,0xfe,0x50,0x50,0xfc,0x40,0x50,0xf8,0x0,
-+0x0,0x0,0x3f,0x1,0x1,0x7f,0x9,0x9,0xff,0x9,0x9,0x7f,0x1,0x1,0x3f,0x0,0x10,0x78,0x80,0x0,0x8,0xfc,0x20,0x24,0xfe,0x20,0x28,0xfc,0x0,0x10,0xf8,0x0,
-+0x1,0x7f,0x1,0x3f,0x2,0xff,0x4,0x8,0x1f,0x28,0xc8,0xf,0x8,0x8,0xf,0x8,0x0,0xfc,0x0,0xf8,0x0,0xfe,0x40,0x20,0xf0,0x2e,0x24,0xe0,0x20,0x20,0xe0,0x20,
-+0x10,0x17,0x10,0x13,0xfc,0x17,0x39,0x32,0x57,0x5a,0x92,0x13,0x12,0x12,0x13,0x12,0x40,0xfc,0x40,0xf8,0x80,0xfe,0x10,0x8,0xfe,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x4,0xfe,0x29,0x28,0xfe,0xaa,0xaa,0xae,0xc2,0x82,0x82,0xfe,0x83,0x82,0xfe,0x82,0x20,0x10,0xfe,0x4,0xfe,0x84,0xfc,0x0,0xfc,0x8,0x30,0x24,0xfe,0x20,0xa0,0x40,
-+0x0,0x3f,0x20,0x2f,0x20,0x3f,0x2a,0x29,0x28,0x2e,0x40,0x9f,0x10,0x10,0x1f,0x10,0x10,0xf8,0x0,0xf0,0x0,0xfc,0x10,0xa0,0x60,0x1e,0x4,0xf0,0x10,0x10,0xf0,0x10,
-+0x0,0x40,0x37,0x10,0x83,0x62,0x23,0x8,0x13,0x20,0xe0,0x2f,0x20,0x20,0x21,0x20,0x80,0x44,0xfe,0x0,0xf8,0x8,0xf8,0x0,0xf8,0x10,0x64,0xfe,0x40,0x40,0x40,0x80,
-+0x10,0x10,0x20,0x27,0x48,0xfa,0x12,0x22,0x42,0xfb,0x42,0x0,0x18,0xe0,0x40,0x0,0x40,0x40,0x44,0xfe,0x40,0x48,0x48,0x48,0x48,0xf8,0x48,0x40,0x42,0x42,0x3e,0x0,
-+0x1,0x7f,0x1,0x3f,0x2,0x7f,0x8,0x1f,0xe8,0xf,0x10,0x7c,0x54,0x7c,0x12,0xfe,0x8,0xfc,0x0,0xf8,0x0,0xfc,0x20,0xf0,0x2e,0xe4,0x20,0xf8,0xa8,0xf8,0x24,0xfc,
-+0x0,0xf7,0x52,0x31,0x52,0x94,0x10,0x14,0x3f,0x64,0xbf,0x24,0x3f,0x24,0x3f,0x20,0x20,0xa0,0xa8,0xa4,0xa0,0xae,0xf0,0x20,0xa4,0x24,0x18,0x10,0x30,0x4a,0x8a,0x4,
-+0x10,0x10,0x20,0x20,0x4b,0xfa,0x13,0x22,0x43,0xf8,0x40,0x7,0x18,0xe0,0x40,0x0,0x48,0x7c,0x40,0x48,0xfc,0x8,0xf8,0x8,0xf8,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,
-+0x1,0x0,0x1f,0x11,0x91,0x51,0x55,0x15,0x35,0x55,0xd5,0x15,0x25,0x25,0x4e,0x4,0x0,0x84,0xfe,0x20,0x20,0x20,0x24,0x2c,0xf0,0x20,0x20,0x20,0x22,0xe2,0x1e,0x0,
-+0x8,0x8,0xff,0x8,0x1,0x41,0x33,0x12,0x4,0x10,0xe0,0x20,0x21,0x21,0x22,0xc,0x20,0x24,0xfe,0x20,0x0,0x8,0xfc,0x8,0x90,0x80,0x80,0x80,0x40,0x30,0xe,0x4,
-+0x2,0x11,0xf8,0x27,0x21,0x41,0x42,0x77,0xd0,0x51,0x51,0x52,0x54,0x77,0x50,0x0,0x8,0x98,0xa0,0xfe,0x8,0x8,0x52,0xbc,0x84,0x8,0x8,0x10,0xa4,0xfe,0x42,0x0,
-+0x14,0x14,0x14,0x54,0x55,0x5e,0x54,0x54,0x54,0x54,0x54,0x54,0x5d,0xe6,0x44,0x0,0x50,0x50,0x84,0xfe,0x90,0x90,0xfc,0x90,0x90,0xfc,0x90,0x90,0x94,0xfe,0x80,0x80,
-+0x8,0x1c,0xf0,0x11,0x10,0x14,0xfe,0x10,0x15,0x7e,0x44,0x45,0x44,0x44,0x7c,0x44,0x40,0x20,0x28,0xfc,0x0,0x88,0x50,0x4,0xfe,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,
-+0x8,0x4,0xff,0x8,0x8,0x12,0x7c,0x8,0x12,0x7e,0x0,0xa,0x29,0x28,0x48,0x7,0x20,0x44,0xfe,0x20,0x20,0x44,0xf8,0x10,0x24,0xfc,0x0,0x0,0x88,0xa4,0x24,0xe0,
-+0x21,0x11,0x1,0xa,0x70,0x20,0x27,0x0,0xff,0x10,0x1f,0x10,0x13,0x10,0x16,0x38,0x0,0x8,0xfc,0x48,0x40,0xa0,0x1c,0x4,0xfe,0x0,0xe0,0x20,0x20,0xa4,0x24,0x1c,
-+0x20,0x13,0x10,0x0,0x7,0xf0,0x10,0x13,0x12,0x12,0x12,0x13,0x16,0x18,0x10,0x0,0x4,0xfe,0x4,0x24,0xf4,0x4,0x24,0xf4,0x24,0x24,0x24,0xe4,0x24,0x4,0x14,0x8,
-+0x4,0x4,0x4,0x24,0x24,0x24,0x27,0x24,0x24,0x24,0x24,0x24,0x27,0xf8,0x40,0x0,0x40,0x40,0x40,0x44,0x4c,0x50,0x60,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x8,0x8,0x9,0xff,0x8,0x7f,0x49,0x49,0x4b,0x18,0x1c,0x2b,0x49,0x88,0x8,0x8,0x4,0x4,0x4,0xa4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x4,0x4,0x14,0x8,
-+0x0,0x7d,0x45,0x55,0x55,0x55,0x55,0x54,0x55,0x56,0x54,0x11,0x2a,0x44,0x81,0x0,0x8,0xfc,0x8,0xf8,0x8,0x8,0xf8,0x84,0xfe,0x54,0x94,0x24,0x44,0x84,0x28,0x10,
-+0x0,0x40,0x30,0x11,0x1,0x2,0x8,0x10,0x20,0xe0,0x20,0x20,0x21,0x22,0x24,0x28,0x80,0x80,0x80,0x8,0xfc,0x8,0x50,0x40,0x40,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,
-+0x5,0xfe,0x24,0x24,0x3d,0x25,0x25,0x25,0x3d,0x25,0x24,0x24,0xfd,0x6,0x4,0x4,0x4,0xcc,0x50,0x4,0xfe,0x4,0x4,0x4,0xfc,0x44,0x20,0xa4,0x8a,0x8a,0x78,0x0,
-+0x4,0x4,0xff,0x14,0x1f,0x12,0x2e,0x25,0x48,0x11,0x2,0x4,0x52,0x51,0x90,0xf,0x40,0x44,0xfe,0x40,0xf8,0x48,0x48,0x88,0xc8,0x28,0x10,0x0,0x4,0x92,0x92,0xf0,
-+0x4,0x8,0x7f,0x44,0x44,0x47,0x44,0x48,0x54,0x42,0x41,0x42,0x44,0x48,0x7f,0x40,0x0,0x4,0xfe,0x4,0x4,0xe4,0x24,0x44,0x44,0x84,0x4,0x84,0x4,0x4,0xfc,0x4,
-+0x8,0x8,0x8,0x1f,0x12,0x22,0x4a,0x86,0x5,0x4,0x8,0x11,0x22,0x44,0x8,0x0,0x0,0x0,0x4,0xfe,0x44,0x44,0x44,0x44,0x44,0x84,0xc4,0x34,0x14,0x4,0x28,0x10,
-+0x0,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x14,0x12,0x21,0x21,0x42,0x84,0x0,0x20,0x20,0x20,0x20,0x20,0x20,0x50,0x50,0x50,0x50,0x88,0x88,0xc,0x6,0x4,
-+0x0,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x14,0x12,0x21,0x41,0x82,0x0,0xff,0x0,0x0,0x20,0x20,0x20,0x20,0x20,0x50,0x50,0x50,0x90,0x88,0xe,0x4,0x0,0xfe,0x0,
-+0x0,0x40,0x2f,0x20,0x7,0x1,0xf,0x12,0x24,0xeb,0x30,0x27,0x20,0x21,0x22,0x24,0x80,0x88,0xfc,0x80,0xf8,0x0,0xfc,0x20,0x10,0xee,0x84,0xf0,0x80,0x40,0x30,0x10,
-+0x8,0x8,0x4a,0x2a,0x1c,0x8,0xfe,0x8,0x1c,0x1a,0x28,0x48,0x88,0x8,0xb,0x8,0x0,0x8,0xfc,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0xfe,0x0,
-+0x2,0x7f,0x14,0x15,0x7f,0x55,0x55,0x55,0x55,0x63,0x41,0x7f,0x41,0x41,0x7f,0x41,0x28,0x28,0xfe,0x28,0xa8,0x28,0xfe,0x4,0x7e,0x44,0x44,0x7c,0x44,0x44,0x7c,0x44,
-+0x10,0x12,0x1f,0x24,0x42,0x10,0x8,0xff,0x10,0x1c,0x14,0x27,0x24,0x44,0x94,0xb,0x20,0x24,0x3e,0x48,0x84,0x80,0xfe,0x40,0x7c,0xa0,0x24,0xfe,0x20,0x50,0x8e,0x4,
-+0x8,0xb,0xa,0x12,0x12,0x33,0x50,0x90,0x12,0x12,0x12,0x12,0x15,0x18,0x10,0x10,0x8,0xfc,0x8,0x8,0x8,0xf8,0x40,0x40,0x48,0x7c,0x40,0x40,0x40,0xc6,0x7c,0x0,
-+0x0,0x78,0x4b,0x4a,0x4d,0x78,0x11,0x11,0x5d,0x50,0x53,0x52,0x5f,0xe2,0x40,0x0,0x40,0x20,0xfe,0x8a,0x24,0x20,0xfc,0x24,0xfc,0x20,0xfe,0x22,0xfe,0x22,0x20,0x20,
-+0x10,0x1f,0x28,0x5f,0x10,0x1f,0x10,0x1f,0x10,0x1f,0x4,0xff,0xa,0x32,0xc4,0xf,0x40,0x7c,0xa0,0xf0,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x20,0x9e,0x44,0xe0,
-+0x2,0x1,0x7f,0x44,0x99,0x1,0x3f,0x21,0x3f,0x1,0x7f,0x41,0x7f,0x41,0x1,0x1,0x0,0x0,0xfe,0x42,0x34,0x0,0xf8,0x8,0xf8,0x0,0xfc,0x4,0xfc,0x4,0x0,0x0,
-+0x10,0x11,0x11,0x11,0xfd,0x10,0x15,0x19,0x33,0xd5,0x11,0x11,0x11,0x11,0x51,0x21,0x20,0x24,0x24,0x24,0xfc,0xa0,0x14,0xfe,0x10,0xfc,0x10,0xfc,0x10,0x14,0xfe,0x0,
-+0x1,0x21,0x21,0x3f,0x28,0x11,0x10,0x3f,0x50,0x9f,0x10,0x1f,0x10,0x10,0x1f,0x10,0x0,0x8,0x8,0xf8,0x8,0x0,0x88,0xfc,0x80,0xf8,0x80,0xf8,0x80,0x84,0xfe,0x0,
-+0x8,0x9,0x9,0x11,0x11,0x30,0x51,0x93,0x15,0x19,0x11,0x11,0x11,0x11,0x11,0x11,0x20,0x24,0x24,0x24,0xfc,0xa0,0x14,0xfe,0x20,0xfc,0x20,0xfc,0x20,0x24,0xfe,0x0,
-+0x8,0x7c,0x48,0x49,0x4a,0x79,0x49,0x49,0x49,0x79,0x49,0x49,0x49,0x49,0x5a,0x84,0x80,0x80,0xf8,0x10,0x24,0xfe,0x0,0x78,0x48,0x48,0x68,0x50,0x42,0x42,0x3e,0x0,
-+0x1,0x0,0x1f,0x10,0x90,0x57,0x51,0x11,0x32,0x54,0xd0,0x1f,0x20,0x20,0x40,0x0,0x0,0x84,0xfe,0x80,0x48,0xfc,0x10,0x10,0xac,0x44,0x40,0xfe,0x40,0x40,0x40,0x40,
-+0x10,0x10,0x10,0x55,0x38,0x10,0xfe,0x11,0x38,0x34,0x53,0x90,0x10,0x10,0x10,0x10,0x40,0x20,0x28,0xfc,0x88,0x88,0x88,0x54,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x40,0x30,0x17,0x1,0x81,0x61,0x22,0x4,0x10,0x2f,0xe0,0x20,0x20,0x20,0x20,0x20,0x80,0x48,0xfc,0x10,0x10,0x10,0xac,0x44,0x40,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x3e,0x2,0x12,0xa,0x12,0x1,0x7f,0x8,0x14,0x22,0x1,0xff,0x1,0x1,0x1,0x1,0xf8,0x8,0x48,0x28,0x48,0x0,0xfc,0x20,0x50,0x88,0x0,0xfe,0x0,0x0,0x0,0x0,
-+0x10,0x10,0x10,0x14,0xff,0x10,0x30,0x38,0x54,0x54,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x90,0x50,0x50,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x2,0x2,0xff,0x4,0x8,0xb,0x10,0x10,0x30,0x5f,0x90,0x10,0x10,0x10,0x11,0x10,0x0,0x4,0xfe,0x0,0x0,0xf8,0x10,0x20,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x80,
-+0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x8,0x4,0x4,0x0,0x0,0x0,0x0,0x1,0x0,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,
-+0x0,0x4,0xfe,0x13,0x10,0x21,0x24,0x7f,0xa4,0x24,0x24,0x25,0x3d,0x22,0x4,0x0,0x88,0x4c,0x50,0xfe,0x20,0xfc,0x20,0xfe,0x40,0x88,0xfc,0x10,0x10,0x14,0xfe,0x0,
-+0x20,0x23,0x22,0x23,0xfa,0x23,0x20,0x2f,0x34,0xe7,0x24,0x27,0x24,0x2f,0xa0,0x40,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfe,0x80,0xfc,0x84,0xa8,0x90,0x90,0xae,0xc4,
-+0x11,0x10,0x10,0x17,0xfc,0x13,0x10,0x1f,0x30,0xd1,0x11,0x12,0x14,0x18,0x53,0x20,0x8,0x98,0xa0,0xfc,0x40,0xf8,0x40,0xfe,0x80,0x8,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x11,0x11,0x11,0x17,0xfd,0x11,0x17,0x18,0x33,0xd2,0x12,0x13,0x12,0x12,0x53,0x22,0x10,0x10,0x10,0xfc,0x10,0x14,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x12,0x12,0xfa,0x12,0x15,0x18,0x30,0xd0,0x17,0x10,0x10,0x10,0x5f,0x20,0x40,0x40,0x48,0x48,0x48,0x48,0x54,0xe2,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x0,
-+0x10,0x10,0x10,0x1f,0x20,0x20,0x7f,0x90,0x11,0x7d,0x11,0x11,0x15,0x19,0x11,0x1,0x90,0x90,0x90,0xfc,0x90,0x94,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x11,0x11,0x17,0x11,0xfc,0x10,0x11,0x1a,0x35,0xd0,0x13,0x12,0x12,0x12,0x53,0x22,0x10,0x10,0xfc,0x10,0x40,0xa0,0x10,0xe,0xf4,0x0,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x40,0x20,0x20,0x0,0xf,0xe0,0x21,0x21,0x22,0x22,0x24,0x28,0x50,0x8f,0x0,0x80,0x80,0x80,0x80,0x88,0xfc,0x80,0x0,0x40,0x20,0x10,0x18,0x8,0x6,0xfc,0x0,
-+0x10,0x12,0x1f,0x28,0x45,0x2,0x4,0x8,0x1f,0x20,0xcf,0x8,0x8,0x8,0xf,0x8,0x40,0x48,0x7c,0xa0,0x10,0x80,0x40,0x20,0xf8,0xe,0xe4,0x20,0x20,0x20,0xe0,0x20,
-+0x1,0x0,0x1f,0x92,0x52,0x5f,0x12,0x31,0x52,0xd7,0x18,0x17,0x24,0x24,0x47,0x4,0x0,0x84,0xfe,0x20,0x28,0xfc,0xa0,0x40,0x20,0xf0,0xe,0xf4,0x10,0x10,0xf0,0x10,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x14,0x18,0x30,0xd0,0x10,0x10,0x10,0x10,0x50,0x20,0x0,0x0,0x4,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x2,0x2,0x2,0x4,0x4,0x8,0x10,0x60,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x80,0x80,0x40,0x40,0x20,0x10,0xe,0x4,0x0,
-+0x0,0x1f,0x10,0x10,0x10,0x1f,0x11,0x1,0xff,0x1,0x3,0x5,0x9,0x11,0x61,0x1,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,0x4,0xfe,0x0,0x80,0x40,0x20,0x1c,0x8,0x0,
-+0x0,0xff,0x2,0x2,0x2,0x3,0x4,0xc,0xa,0x11,0x20,0x40,0x0,0x3,0xc,0x30,0x4,0xfe,0x0,0x0,0x0,0xf8,0x8,0x8,0x10,0x90,0xa0,0x40,0x80,0x0,0x0,0x0,
-+0x10,0x10,0x1f,0x20,0x2f,0x61,0xbf,0x22,0x24,0x2c,0x32,0x21,0x22,0x24,0x28,0x21,0x80,0x88,0xfc,0x80,0xf8,0x0,0xfe,0x20,0x90,0x9e,0xa4,0xc0,0xa0,0x98,0x88,0x80,
-+0x8,0x7f,0x8,0xff,0x0,0x7f,0x49,0x7f,0x49,0x7f,0x22,0x7f,0x22,0xff,0x22,0x41,0x50,0x48,0x44,0xfe,0x40,0x48,0x48,0x50,0x50,0x20,0x20,0x60,0x90,0x92,0xa,0x6,
-+0x9,0x9,0x7f,0x9,0x9,0x7f,0x41,0x81,0x1f,0x11,0x11,0x11,0x11,0x11,0x11,0x1,0x20,0x28,0xfc,0x20,0x20,0xfe,0x2,0x4,0xf0,0x10,0x10,0x10,0x10,0x50,0x20,0x0,
-+0x4,0xfe,0x20,0x20,0x3c,0x25,0x27,0x44,0xa5,0x15,0x9,0x9,0x11,0x21,0x41,0x0,0x20,0x20,0x40,0x40,0x88,0x4,0xfe,0x2,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,0x0,
-+0x8,0x8,0x8,0x10,0x10,0x30,0x5f,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x80,0xa0,0x90,0x90,0x84,0xfe,0x80,0x40,0x40,0x40,0x20,0x20,0x12,0x12,0xa,0x6,
-+0x8,0x8,0x10,0x37,0x50,0x90,0x10,0x1f,0x10,0x11,0x11,0x11,0x11,0x2,0xc,0x30,0xa0,0x90,0xbc,0xc0,0x42,0x32,0xe,0xf0,0x10,0x10,0x10,0x10,0x10,0xc0,0x30,0x10,
-+0x8,0x8,0x10,0x37,0xd0,0x10,0x12,0x11,0xff,0xa,0x9,0x18,0x28,0xc9,0xa,0xc,0xa0,0x90,0xfc,0x80,0x40,0x24,0x1c,0x0,0xfe,0x8,0x10,0xa0,0x40,0x30,0xe,0x4,
-+0x8,0x8,0x13,0x20,0x48,0x8,0x17,0x30,0x50,0x97,0x10,0x12,0x11,0x11,0x10,0x10,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x0,0x40,0x27,0x20,0xf,0x0,0xe7,0x20,0x24,0x22,0x24,0x28,0x22,0x51,0x8f,0x0,0x80,0x90,0xf8,0x90,0xfc,0x90,0xf0,0x80,0x90,0xa0,0x98,0x88,0x80,0x6,0xfc,0x0,
-+0x4,0x4,0x8,0x10,0x7f,0x0,0x3f,0x20,0x20,0x3f,0x2,0x11,0x50,0x50,0x8f,0x0,0x0,0x40,0x20,0x10,0xfc,0x0,0xf8,0x8,0x8,0xf8,0x0,0x80,0x94,0x12,0xf2,0x0,
-+0x4,0xfe,0x48,0x4b,0x7a,0x4c,0x48,0x48,0x78,0x48,0x48,0x4d,0xf9,0xa,0xc,0x8,0x40,0x40,0x44,0xfe,0x44,0x48,0x60,0x60,0xa0,0xa0,0xa0,0x20,0x22,0x22,0x1e,0x0,
-+0x10,0x10,0x13,0x12,0xfe,0x12,0x13,0x1e,0x32,0xd2,0x13,0x10,0x10,0x1f,0x50,0x20,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x0,0x4,0xfe,0x0,0x0,
-+0x0,0x1f,0x10,0x12,0x11,0x11,0x10,0xff,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x10,0xf8,0x10,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x10,0x8,0x4,0x3f,0x21,0x21,0x3f,0x21,0x21,0x3f,0x21,0x1,0xff,0x1,0x1,0x1,0x10,0x20,0x48,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x0,0x4,0xfe,0x0,0x0,0x0,
-+0x41,0x22,0x14,0x7f,0x49,0x49,0x7f,0x49,0x49,0x7f,0x8,0x8,0xff,0x8,0x8,0x8,0x0,0x7c,0x44,0x48,0x48,0x50,0x50,0x48,0x44,0x44,0x44,0x64,0xd4,0x48,0x40,0x40,
-+0x11,0x10,0x10,0x11,0xfd,0x11,0x15,0x19,0x31,0xd1,0x10,0x17,0x10,0x10,0x50,0x20,0x4,0x88,0x50,0xfc,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0xfe,0x20,0x20,0x20,0x20,
-+0x4,0x3e,0x24,0x24,0x24,0x3c,0x24,0x24,0x24,0x3c,0x24,0x24,0x24,0x25,0x54,0x88,0x0,0x4,0xfe,0x84,0x84,0x84,0xfc,0x84,0x84,0x84,0xfc,0x0,0x4,0xfe,0x0,0x0,
-+0x0,0x1f,0x10,0x10,0x10,0x10,0x1f,0x10,0x10,0x10,0x10,0x1f,0x10,0x0,0xff,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0xf0,0x10,0x10,0x10,0x10,0xf0,0x10,0x4,0xfe,0x0,
-+0x10,0x1f,0x10,0x3f,0x40,0xbf,0x12,0xa,0x5,0x38,0x2,0x12,0xa,0x5,0x8,0x70,0x8,0xfc,0x0,0xf8,0x0,0xf0,0x50,0x90,0x10,0xf0,0x10,0x50,0x90,0x12,0xca,0x24,
-+0x10,0x10,0x17,0x24,0x24,0x64,0xa7,0x24,0x24,0x24,0x27,0x20,0x20,0x3f,0x20,0x20,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x0,0x4,0xfe,0x0,0x0,
-+0x12,0x11,0x10,0x13,0x5a,0x56,0x53,0x92,0x12,0x13,0x10,0x1f,0x10,0x10,0x10,0x10,0x8,0x10,0xa0,0xf8,0x48,0x48,0xf8,0x48,0x48,0xf8,0x40,0xfe,0x40,0x40,0x40,0x40,
-+0x0,0x44,0x33,0x11,0x80,0x40,0x41,0xa,0x10,0x22,0xe1,0x20,0x20,0x21,0x22,0x2c,0x40,0x44,0x4c,0x50,0x40,0xa0,0x1c,0x48,0x40,0x48,0x58,0xa0,0x90,0x10,0xe,0x4,
-+0x0,0x40,0x2f,0x21,0x2,0x4,0xef,0x21,0x29,0x25,0x22,0x2a,0x33,0x24,0x8,0x10,0x8,0x1c,0x70,0x10,0x10,0x10,0x5c,0x50,0x50,0x50,0x50,0x7c,0x0,0x80,0x46,0x3c,
-+0xa,0x7d,0x8,0xb,0xa,0x7a,0x4b,0x42,0x42,0x7b,0x8,0xf,0x8,0x8,0x50,0x20,0x8,0x10,0xa0,0xf8,0x48,0x48,0xf8,0x48,0x48,0xf8,0x40,0xfe,0x40,0x40,0x40,0x40,
-+0x7f,0x1,0x9,0x9,0x9,0x15,0x23,0x41,0x1f,0x11,0x11,0x1f,0x11,0x1,0x7f,0x0,0xfc,0x8,0x20,0xf0,0x0,0x6,0xfc,0x10,0xf8,0x10,0x10,0xf0,0x0,0x10,0xf8,0x4,
-+0x1,0x21,0x19,0x9,0x1,0x1,0x7f,0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x7f,0x0,0x0,0x8,0x18,0x20,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x12,0x11,0xfd,0x10,0x17,0x18,0x30,0xd0,0x13,0x10,0x10,0x10,0x57,0x20,0x40,0x40,0x44,0x4c,0x50,0x44,0xfe,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x1,0x11,0xd,0x5,0x7f,0x40,0x8f,0x8,0x8,0x8,0xf,0x4,0x4,0x4,0x8,0x30,0x0,0x10,0x30,0x40,0xfe,0x22,0xf4,0x20,0x20,0x20,0xe0,0x80,0x80,0x84,0x84,0x7c,
-+0x8,0x8,0xff,0x8,0x47,0x30,0x10,0x81,0x47,0x11,0x21,0xe2,0x22,0x24,0x29,0x20,0x20,0x24,0xfe,0x20,0xf0,0x40,0x80,0x4,0xfe,0x24,0x24,0x44,0x44,0x84,0x28,0x10,
-+0x10,0x10,0x12,0x11,0xfd,0x10,0x37,0x38,0x54,0x50,0x93,0x10,0x10,0x10,0x17,0x10,0x40,0x40,0x44,0x4c,0x50,0x44,0xfe,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x0,0x7f,0x2,0x2,0x2,0x2,0x2,0x2,0x4,0x4,0x8,0x8,0x10,0x20,0x40,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x50,0x20,
-+0x10,0x10,0x11,0x11,0xfd,0x11,0x15,0x19,0x31,0xd1,0x10,0x14,0x14,0x17,0x50,0x20,0x40,0x88,0xfc,0x8,0x48,0x8,0x28,0x10,0x0,0xfe,0x82,0x92,0x92,0xf2,0xa,0x4,
-+0x4,0x7f,0x44,0x46,0x45,0x45,0x7c,0x13,0x12,0x5e,0x53,0x52,0x5e,0xf2,0x43,0x2,0x1c,0xe0,0x48,0x2c,0x28,0x10,0x44,0x9e,0x4,0x4,0x9c,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x1f,0x22,0x22,0x64,0xaf,0x21,0x21,0x2f,0x21,0x21,0x21,0x2f,0x24,0x20,0x4,0x44,0xe4,0x4,0x94,0x54,0xd4,0x14,0x14,0xd4,0x14,0x14,0xc4,0x4,0x14,0x8,
-+0x1,0x2,0xf,0x8,0xa,0x9,0x8,0x8,0xf,0x8,0x2,0x22,0x22,0x3f,0x20,0x0,0x0,0x20,0xf0,0x20,0x20,0x20,0x60,0x4,0xfe,0x4,0x4,0x24,0x24,0xe4,0x34,0x8,
-+0x20,0x10,0x13,0x0,0xfd,0x8,0x13,0x38,0x54,0x93,0x11,0x11,0x12,0x14,0x18,0x10,0x40,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x80,0x88,0xfe,0x8,0x48,0x28,0x8,0x28,0x10,
-+0x0,0x3f,0x20,0x20,0x3f,0x20,0x20,0x1f,0x0,0x0,0xff,0x0,0x8,0x4,0x0,0x0,0x10,0xf8,0x10,0x10,0xf0,0x14,0x4,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,0xa0,0x40,
-+0x1,0x7f,0x8,0x10,0x22,0x41,0x7f,0x8,0xa,0x7f,0x8,0x8,0x8,0xf,0xf8,0x0,0x4,0x84,0x4,0x24,0x24,0x24,0xa4,0xa4,0x24,0x24,0x24,0x24,0x4,0x84,0x14,0x8,
-+0x8,0x1f,0xf0,0x12,0x11,0xfd,0x10,0x3b,0x36,0x52,0x53,0x92,0x12,0x12,0x13,0x12,0x1c,0xe0,0x48,0x4c,0x48,0x10,0x44,0x9e,0x4,0x4,0x9c,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x10,0x5b,0x56,0x53,0x92,0x13,0x12,0x10,0x1f,0x10,0x10,0x10,0x10,0x48,0x7c,0x40,0x48,0xfc,0x8,0xf8,0x8,0xf8,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,
-+0x2,0x41,0x37,0x10,0x1,0x3,0xf2,0x13,0x12,0x12,0x13,0x12,0x12,0x2b,0x44,0x3,0x8,0x10,0xfc,0x80,0x8,0xfc,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x6,0xfc,
-+0x1,0x41,0x33,0x12,0x4,0x10,0x21,0xc6,0x40,0x1f,0x12,0x12,0x12,0x12,0xff,0x0,0x0,0x8,0xfc,0x48,0x40,0xa0,0x10,0xe,0x4,0xf0,0x90,0x90,0x90,0x94,0xfe,0x0,
-+0x10,0x10,0x2f,0x20,0x47,0x94,0x14,0x27,0x60,0xaf,0x20,0x21,0x25,0x25,0x28,0x20,0x40,0x44,0xfe,0x40,0xfc,0xa4,0xa4,0xfc,0x0,0xfe,0x40,0x20,0x24,0xa,0xfa,0x0,
-+0x8,0xb,0x12,0x13,0x22,0x4b,0x88,0x17,0x30,0x50,0x9f,0x12,0x11,0x11,0x10,0x10,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfc,0x10,0x14,0xfe,0x10,0x10,0x10,0x50,0x20,
-+0x10,0x10,0x22,0x7f,0x42,0x43,0x42,0x42,0x7e,0x42,0x42,0x42,0x42,0x7e,0x42,0x0,0x40,0x40,0x44,0x7e,0x84,0x4,0x4,0x84,0x64,0x24,0x4,0x4,0x4,0x4,0x28,0x10,
-+0x8,0x7f,0x48,0x4a,0x49,0x49,0x7b,0x14,0x13,0x5a,0x52,0x53,0x5d,0xe0,0x4f,0x0,0x20,0xa8,0xb0,0xa4,0x18,0x10,0xf8,0x6,0xf8,0x8,0x8,0xf8,0x10,0xa4,0xfe,0x0,
-+0x10,0x10,0x17,0x10,0x54,0x58,0x50,0x90,0x10,0x10,0x10,0x28,0x24,0x44,0x80,0x0,0x0,0x4,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x0,0x3e,0x2,0x12,0xc,0x8,0x1f,0x20,0xcf,0x8,0x8,0xf,0x4,0x2,0x7f,0x0,0x80,0x90,0xa0,0x48,0x50,0x20,0xf0,0x2e,0xf4,0x20,0x20,0xe0,0x40,0x88,0xfc,0x0,
-+0x10,0x14,0x3e,0x49,0x5,0x1,0x3f,0x1,0xff,0x0,0x0,0x3f,0x8,0x4,0x1,0x0,0x40,0x48,0xfc,0x20,0x10,0x0,0xf8,0x0,0xfe,0x40,0x50,0xf8,0x40,0x40,0x40,0x80,
-+0x8,0x7f,0x48,0x4a,0x49,0x79,0x4b,0x4c,0x4b,0x7a,0x4a,0x4b,0x49,0x78,0x4f,0x0,0x20,0xa8,0xb0,0xa4,0x18,0x8,0xfe,0x4,0xf8,0x8,0x8,0xf8,0x10,0xa4,0xfe,0x0,
-+0x3e,0x12,0xc,0xf,0x10,0x2f,0xc8,0xf,0x4,0x7f,0x0,0x7,0x4,0x4,0x8,0x30,0x90,0xa0,0x48,0xf0,0x10,0xee,0x24,0xe0,0x48,0xfc,0x40,0xe0,0x40,0x44,0x44,0x3c,
-+0x0,0xfe,0x2,0x42,0x24,0x24,0x18,0x8,0x18,0x14,0x24,0x22,0x42,0x80,0x0,0x0,0x0,0xfc,0x84,0x88,0x88,0x90,0xa0,0x98,0x84,0x84,0x84,0xc4,0xa8,0x90,0x80,0x80,
-+0x23,0x22,0x22,0x23,0xfa,0x22,0x23,0x20,0x2f,0x20,0x3a,0xe2,0x42,0x5,0x8,0x10,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x4,0xfe,0x40,0x50,0x78,0x40,0x40,0xc6,0x7c,
-+0x10,0x10,0x17,0x24,0x24,0x64,0xa4,0x27,0x24,0x24,0x24,0x24,0x25,0x26,0x24,0x20,0x8,0x3c,0xc0,0x40,0x40,0x40,0x44,0xfe,0x20,0x20,0x20,0x90,0x12,0x4a,0x2a,0x4,
-+0x0,0x40,0x2f,0x22,0x1,0x87,0x44,0x4d,0x14,0x25,0xe5,0x25,0x25,0x25,0x24,0x24,0x80,0x44,0xfe,0x8,0x14,0xfe,0x44,0xf4,0x44,0xf4,0x14,0x14,0xf4,0x4,0x14,0x8,
-+0x0,0x40,0x20,0x2f,0x8,0x8,0xe8,0x2f,0x28,0x28,0x28,0x2f,0x28,0x50,0x8f,0x0,0x80,0x80,0x88,0xfc,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0xf8,0x8,0x6,0xfc,0x0,
-+0x2,0x7,0x78,0x8,0x8,0xa,0xff,0x8,0xa,0x3f,0x22,0x22,0x22,0x3e,0x22,0x1,0x20,0x20,0x20,0x44,0x7e,0x88,0x48,0x48,0x48,0x48,0x50,0x50,0x20,0x50,0x8e,0x4,
-+0x10,0x12,0x1f,0x28,0x45,0x81,0x3f,0x21,0x21,0x21,0x3f,0x21,0x21,0x21,0x3f,0x20,0x40,0x44,0x7e,0xa0,0x10,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x4,0x44,0x28,0x10,0x29,0x49,0x89,0xa,0x18,0x28,0x48,0x88,0x9,0x9,0x52,0x24,0x40,0x40,0x40,0x44,0x4c,0x50,0x60,0x40,0x40,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,
-+0x1,0x41,0x31,0x13,0x84,0x60,0x20,0x9,0x12,0x24,0xeb,0x21,0x22,0x24,0x21,0x20,0x0,0x0,0xf8,0x10,0xa0,0x40,0xa0,0x10,0x4e,0x40,0xfc,0x50,0x4c,0x44,0x40,0x80,
-+0x0,0x7e,0x2,0x22,0x1a,0x12,0x23,0x8,0x1f,0x30,0x5f,0x90,0x1f,0x10,0x1f,0x10,0x8,0xfc,0x8,0x48,0x38,0x28,0x48,0x80,0xfc,0x80,0xf8,0x80,0xf8,0x80,0xfe,0x0,
-+0x10,0x10,0x13,0x10,0xfc,0x25,0x25,0x25,0x25,0x45,0x29,0x11,0x29,0x45,0x85,0x0,0x40,0x24,0xfe,0x88,0x54,0xfe,0x24,0xfc,0x24,0x74,0x54,0x54,0x74,0x4,0x14,0x8,
-+0x10,0x10,0x13,0x12,0xfe,0x12,0x16,0x1b,0x32,0xd2,0x12,0x12,0x12,0x13,0x52,0x20,0x8,0x3c,0xe0,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x50,0xd0,0x2a,0xa,0x4,
-+0x2,0x1,0x3f,0x20,0x20,0x2f,0x28,0x28,0x2f,0x28,0x28,0x28,0x4a,0x4d,0x88,0x0,0x0,0x4,0xfe,0x0,0x70,0x80,0x80,0x88,0xfc,0x80,0x80,0x40,0x40,0xa4,0x94,0xc,
-+0x0,0x20,0x22,0x22,0x22,0x22,0xfb,0x26,0x22,0x22,0x22,0x22,0x3a,0xe2,0x41,0x0,0x40,0x40,0x40,0x40,0x48,0x7c,0xc8,0x48,0x48,0x48,0x68,0x50,0x42,0x2,0xfe,0x0,
-+0x4,0x7f,0x4,0x1,0x3f,0x8,0x4,0x7f,0x41,0x81,0x1f,0x11,0x11,0x11,0x1,0x1,0x48,0xfc,0x40,0x10,0xf8,0x20,0x40,0xfe,0x2,0x14,0xf8,0x10,0x10,0x50,0x20,0x0,
-+0x10,0x14,0x3e,0x49,0xbf,0x1,0x1,0x3f,0x21,0x21,0x3f,0x3,0x5,0x19,0x61,0x1,0x80,0x88,0xfc,0x20,0xf8,0x8,0x8,0xf8,0x0,0x4,0xfe,0x4,0x4,0x24,0x18,0x0,
-+0x2,0x1,0x3f,0x8,0x4,0x7f,0x41,0x81,0x1f,0x11,0x11,0x11,0x11,0x11,0x1,0x1,0x0,0x10,0xf8,0x20,0x40,0xfe,0x2,0x14,0xf8,0x10,0x10,0x10,0x50,0x20,0x0,0x0,
-+0x8,0x6,0x2,0x7f,0x1,0x1,0x3f,0x21,0x21,0x3f,0x3,0x5,0x19,0x61,0x1,0x1,0x20,0x60,0x88,0xfc,0x8,0x8,0xf8,0x8,0x0,0xfc,0x4,0x4,0x14,0x8,0x0,0x0,
-+0x4,0x42,0x2f,0x20,0x0,0xf,0xe8,0x28,0x2f,0x21,0x22,0x24,0x28,0x50,0x88,0x7,0x10,0x28,0xfc,0x88,0x88,0xf8,0x80,0x88,0xfc,0x88,0x88,0xa8,0x90,0x80,0x86,0xfc,
-+0x10,0x10,0x27,0x21,0x48,0xff,0x14,0x28,0x43,0xfa,0x42,0x2,0x1a,0xe2,0x40,0x0,0x80,0x48,0xfc,0x10,0xa0,0xfe,0x42,0x44,0xf8,0x48,0x48,0x48,0x48,0x58,0x40,0x40,
-+0x10,0x15,0xfe,0x10,0x7c,0x44,0x7c,0x44,0x7c,0x44,0x7c,0x44,0xfe,0x0,0x28,0x45,0x4,0xfe,0x20,0x44,0xfe,0x84,0x94,0x94,0x94,0xa4,0xa4,0xa4,0x40,0x48,0x86,0x2,
-+0x10,0x10,0x10,0x13,0xfe,0x12,0x16,0x1a,0x32,0xd2,0x12,0x12,0x14,0x14,0x58,0x20,0x40,0x20,0x4,0xfe,0x20,0x24,0x3e,0x20,0x24,0xfe,0x84,0x84,0x84,0x84,0xfc,0x84,
-+0x0,0x40,0x37,0x10,0x83,0x62,0x23,0xa,0x13,0x22,0xe3,0x22,0x2f,0x21,0x23,0x24,0x40,0x48,0xfc,0x40,0xf8,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x8,0xfe,0x10,0xc,0x4,
-+0x0,0x4,0xfe,0x11,0x11,0x21,0x25,0x3f,0x65,0xa5,0x25,0x27,0x24,0x3c,0x25,0x2,0x50,0x50,0x54,0xfe,0x54,0x54,0x54,0xfc,0x54,0x54,0x54,0xfe,0x0,0x88,0x86,0x2,
-+0x2,0x2,0x2,0x3,0x2,0x2,0x3f,0x20,0x20,0x20,0x3f,0x0,0x29,0x24,0x44,0x80,0x0,0x0,0x8,0xfc,0x0,0x10,0xf8,0x10,0x10,0x10,0xf0,0x0,0x10,0xc8,0x44,0x4,
-+0x4,0x4,0x4,0x3f,0x24,0x24,0x24,0x3f,0x24,0x24,0x24,0xff,0x0,0x10,0x30,0x40,0x40,0x40,0x48,0xfc,0x48,0x48,0x48,0xf8,0x48,0x48,0x48,0xfe,0x0,0x10,0xc,0x4,
-+0x10,0x7c,0x11,0x7d,0x12,0xff,0x4,0x7e,0x44,0x7c,0x44,0x7c,0x44,0x45,0x56,0x48,0x40,0x20,0xfe,0x2,0x4,0xfe,0x20,0x20,0xa8,0xbc,0xa0,0xa0,0xa0,0x60,0x26,0x1c,
-+0x8,0x8,0x7e,0x8,0xa,0x1c,0x68,0x8,0x2b,0x11,0x1,0x7f,0x1,0x1,0xff,0x0,0x40,0x48,0xfc,0x48,0xc8,0x68,0x58,0x8a,0x6,0x0,0x8,0xfc,0x0,0x4,0xfe,0x0,
-+0x2,0x2,0x2,0x7f,0x42,0x42,0x7f,0x42,0x42,0x7f,0x42,0x2,0x2,0x2,0x1,0x0,0x0,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,0x0,0x4,0x4,0xfc,0x0,
-+0x10,0x10,0x10,0x27,0x24,0x64,0xa4,0x24,0x27,0x24,0x24,0x24,0x24,0x27,0x24,0x20,0x0,0x0,0x4,0xfe,0x44,0x44,0x44,0x44,0xfc,0x44,0x44,0x44,0x44,0xfc,0x4,0x0,
-+0x8,0x8,0x1f,0x20,0x40,0x80,0x3f,0x22,0x22,0x3f,0x22,0x22,0x3f,0x20,0x0,0x0,0x0,0x4,0xfe,0x4,0x4,0x24,0xf4,0x24,0x24,0xe4,0x24,0x24,0xe4,0x24,0x14,0x8,
-+0x1,0x0,0x3f,0x20,0x20,0x20,0x20,0x20,0x2f,0x28,0x28,0x28,0x48,0x48,0x8f,0x8,0x0,0x84,0xfe,0x80,0x88,0xfc,0x80,0x88,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x10,0x13,0x5a,0x56,0x52,0x92,0x12,0x12,0x12,0x12,0x14,0x14,0x18,0x10,0x40,0x20,0x4,0xfe,0x20,0x24,0x3e,0x20,0x24,0xfe,0x84,0x84,0x84,0x84,0xfc,0x84,
-+0x10,0x8,0x7f,0x4,0x1f,0x14,0x14,0x18,0x1f,0x10,0x1f,0x1,0xff,0x2,0x4,0x38,0x10,0x20,0xfc,0x50,0xf8,0x50,0x50,0x30,0xf0,0x10,0xf0,0x4,0xfe,0x80,0x78,0x10,
-+0x0,0x40,0x30,0x17,0x84,0x68,0x27,0x0,0x12,0x22,0xe2,0x22,0x22,0x25,0x28,0x20,0x80,0x40,0x40,0xfe,0x4,0x8,0xfc,0x40,0x48,0x7c,0x40,0x40,0x40,0x40,0xc6,0x7c,
-+0x0,0x7f,0x41,0x41,0x7f,0x40,0x52,0x7f,0x52,0x52,0x7f,0x40,0x52,0x51,0xa0,0x1,0x8,0x7c,0x48,0x48,0x48,0x48,0x86,0x0,0xfc,0x88,0x50,0x20,0x50,0x88,0x86,0x4,
-+0x8,0xfd,0x11,0x11,0x21,0x25,0x3f,0x65,0xa5,0x25,0x25,0x25,0x25,0x3d,0x22,0x4,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x4,0x74,0x54,0x54,0x74,0x4,0x14,0x8,
-+0x0,0x8,0x7d,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x49,0x7b,0x49,0x0,0x0,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x14,0x24,0x44,0x84,0x84,0x4,0x4,0x4,0x28,0x10,
-+0x1,0x7f,0x49,0x49,0x7f,0x49,0x49,0x7f,0x41,0x5d,0x55,0x55,0x5d,0x51,0x85,0x2,0x20,0xa8,0x40,0x7e,0xc8,0x48,0x7c,0x48,0x48,0x7c,0x48,0x48,0x48,0x7e,0x40,0x40,
-+0x0,0x7,0x44,0x24,0x25,0x4,0xc,0x17,0x24,0xe5,0x25,0x25,0x25,0x25,0x8,0x10,0x4,0xfe,0x44,0x44,0xf4,0x44,0x54,0xfc,0x4,0xf4,0x14,0x14,0xf4,0x4,0x14,0x8,
-+0x0,0x3f,0x0,0x0,0x0,0x0,0x0,0x1,0x2,0x4,0x8,0x10,0x30,0x0,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x48,0x88,0x8,0x8,0x8,0x8,0x8,0x8,0x50,0x20,0x0,
-+0x10,0x10,0x10,0x10,0xff,0x12,0x17,0x1a,0x33,0xd2,0x10,0x1f,0x10,0x10,0x50,0x20,0x48,0x7c,0x40,0x48,0xfc,0x8,0xf8,0x8,0xf8,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,
-+0x0,0x1f,0x10,0x10,0x10,0x1f,0x11,0x1,0x3f,0x21,0x21,0x21,0x21,0x21,0x1,0x1,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,0x8,0xfc,0x8,0x8,0x8,0x28,0x10,0x0,0x0,
-+0x10,0x10,0x10,0x1c,0x20,0x21,0x7c,0x90,0x10,0xfc,0x10,0x12,0x14,0x18,0x10,0x0,0x40,0x40,0x44,0x7e,0x84,0x4,0x4,0x84,0x64,0x24,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x40,0x27,0x24,0x4,0x5,0xe4,0x24,0x27,0x24,0x25,0x25,0x2d,0x35,0x25,0x8,0x10,0x4,0xfe,0x44,0x44,0xf4,0x44,0x54,0xfc,0x4,0xf4,0x14,0x14,0xf4,0x4,0x14,0x8,
-+0x4,0x7e,0x45,0x45,0x45,0x7d,0x52,0x10,0x13,0x5c,0x50,0x50,0x5e,0xf0,0x41,0x2,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x50,0x50,0x88,0x8c,0x6,0x4,
-+0x4,0x8,0x34,0x3,0x6,0x1a,0x67,0x8c,0x13,0x6,0x19,0x2,0xd,0x1,0x6,0x38,0x40,0x20,0x58,0x80,0xc0,0x30,0xce,0x44,0x80,0x80,0xf0,0x20,0x40,0x80,0x0,0x0,
-+0x0,0x9,0xfd,0x13,0x11,0x21,0x25,0x3f,0x65,0xa4,0x27,0x24,0x24,0x3d,0x22,0x0,0x50,0x50,0x54,0xfe,0x50,0x50,0x70,0x0,0xfc,0x20,0xfe,0x70,0xa8,0x26,0x24,0x20,
-+0x10,0x11,0x15,0x7f,0x55,0x55,0x55,0x55,0x7d,0x50,0x17,0x1c,0xf4,0x41,0x2,0x0,0x50,0x50,0x54,0xfe,0x50,0x50,0x70,0x0,0xfc,0x20,0xfe,0x70,0xa8,0x26,0x24,0x20,
-+0x0,0x42,0x32,0x13,0x2,0x4,0xf0,0x17,0x10,0x10,0x10,0x11,0x12,0x28,0x44,0x3,0x40,0x40,0x50,0xf8,0x40,0x40,0x48,0xfc,0x40,0x80,0xa0,0x18,0x8,0x0,0x6,0xfc,
-+0x0,0x41,0x31,0x17,0x1,0x1,0xf1,0x11,0x11,0x10,0x17,0x10,0x14,0x19,0x12,0x0,0x50,0x50,0x54,0xfe,0x50,0x50,0x70,0x0,0xfc,0x20,0xfe,0x70,0xa8,0x26,0x24,0x20,
-+0x1f,0x4,0x3,0x3e,0x14,0x8,0x76,0x0,0x7f,0x40,0x9f,0x10,0x1e,0x11,0x10,0xff,0xf0,0x40,0x80,0xf8,0x50,0x20,0xdc,0x0,0xfe,0x2,0xf4,0x10,0x10,0xf0,0x14,0xfe,
-+0x0,0x0,0x7f,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x5,0x2,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x78,0x4f,0x48,0x48,0x78,0x48,0x48,0x48,0x78,0x48,0x48,0x48,0x78,0x48,0x0,0x0,0x4,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x0,0x8,0x7f,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x78,0x48,0x0,0x0,0x0,0x0,0x4,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x10,0x10,0x13,0x1c,0x20,0x20,0x7c,0x90,0x10,0xfc,0x10,0x12,0x14,0x18,0x10,0x0,0x0,0x4,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x0,0xb,0xfc,0x10,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x50,0x20,0x3,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x40,0x58,0x84,0x2,
-+0xf,0x8,0xf,0x28,0x2f,0x28,0x2f,0x20,0x3e,0x2,0xfe,0x12,0x12,0x22,0xc2,0x2,0xe0,0x20,0xe0,0x28,0xe8,0x28,0xe8,0x8,0xf8,0x80,0xfc,0x84,0x84,0x84,0x84,0x80,
-+0x10,0x10,0x10,0x1d,0x21,0x22,0x7d,0x90,0x10,0x7d,0x11,0x11,0x15,0x1a,0x14,0x8,0x40,0x20,0x20,0xfe,0x2,0x4,0xfc,0x20,0x28,0x3c,0x20,0x20,0x20,0xa0,0x66,0x3c,
-+0x2,0x1,0x7f,0x40,0x80,0x1f,0x1,0x1,0x11,0x11,0x11,0x11,0x11,0x29,0x47,0x80,0x0,0x0,0xfe,0x2,0x24,0xf0,0x0,0x0,0x20,0xf0,0x0,0x0,0x0,0x6,0xfc,0x0,
-+0x0,0x40,0x27,0x20,0x0,0x0,0xf0,0x10,0x10,0x10,0x10,0x10,0x14,0x18,0x10,0x0,0x0,0x4,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x0,0x3f,0x1,0x1,0x1,0x3f,0x1,0x1,0x1,0xff,0x2,0x4,0x8,0x10,0x3f,0x0,0xf0,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x0,0x0,0x20,0x10,0xf8,0x8,
-+0x2,0x2,0x2,0xff,0x4,0x9,0x9,0x11,0x3f,0x1,0x9,0x9,0x11,0x21,0x45,0x2,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x10,0xf8,0x0,0x40,0x20,0x10,0x18,0x8,0x0,
-+0x4,0x4,0x7,0x8,0x14,0x22,0x1,0x2,0xc,0x30,0xc6,0x1,0x0,0x6,0x1,0x0,0x0,0x0,0xf0,0x20,0x40,0x80,0x0,0xc0,0x30,0xe,0x4,0x80,0x0,0x0,0x80,0x40,
-+0x4,0xff,0x4,0x3f,0x1,0xff,0x1,0x1f,0x11,0x1f,0x11,0x1f,0x1,0x3f,0x1,0x7f,0x44,0xfe,0x40,0xf8,0x0,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x0,0xf8,0x0,0xfc,
-+0x21,0x2f,0x21,0x27,0xb0,0xaf,0xa0,0x27,0x24,0x27,0x24,0x27,0x20,0x27,0x20,0x2f,0x14,0xfe,0x10,0xfc,0x40,0xfe,0x44,0xfe,0x44,0xfc,0x44,0xfc,0x40,0xfc,0x40,0xfe,
-+0x0,0x8,0x7c,0x0,0x5,0xfe,0x10,0x10,0x20,0x24,0x42,0xfe,0x41,0x1,0x2,0x4,0x40,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x4,0x4,0x28,0x10,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x38,0x35,0x53,0x50,0x91,0x11,0x12,0x14,0x10,0x10,0x40,0x40,0x48,0xfc,0x80,0x80,0xa0,0x24,0xfe,0x20,0x28,0x24,0x22,0x22,0xa0,0x40,
-+0x8,0xb,0xa,0x12,0x13,0x32,0x52,0x92,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x4,0xfe,0x4,0x14,0xfc,0x4,0x14,0xfc,0x94,0x94,0x94,0xf4,0x94,0x4,0x14,0x8,
-+0x10,0x13,0x12,0x12,0x5b,0x56,0x52,0x92,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x4,0xfe,0x4,0x14,0xfc,0x4,0x14,0xfc,0x94,0x94,0x94,0xf4,0x94,0x4,0x14,0x8,
-+0x0,0x40,0x23,0x10,0x10,0x1,0x1,0xb,0x10,0x60,0x20,0x21,0x22,0x24,0x20,0x0,0x40,0x48,0xfc,0x80,0x80,0x20,0x24,0xfe,0x20,0xa0,0xa8,0x24,0x22,0x22,0xa0,0x40,
-+0x0,0x43,0x32,0x12,0x83,0x42,0x4a,0x12,0x12,0x22,0xe2,0x22,0x22,0x22,0x22,0x22,0x4,0xfe,0x4,0x14,0xfc,0x4,0x14,0xfc,0x94,0x94,0x94,0xf4,0x94,0x4,0x14,0x8,
-+0x1,0xa,0x37,0x24,0x24,0x27,0x24,0x2c,0x37,0x20,0x4,0x4,0x4,0x8,0x10,0x60,0x0,0x8,0xdc,0x48,0x48,0xc8,0x48,0x48,0xd8,0x8,0x40,0x42,0x42,0x42,0x3e,0x0,
-+0x10,0x11,0x10,0x10,0xfc,0x11,0x14,0x18,0x30,0xd0,0x17,0x10,0x10,0x10,0x50,0x20,0x10,0x10,0xd0,0x50,0x10,0x10,0xd0,0x50,0x14,0x1e,0xf0,0x10,0x10,0x10,0x10,0x10,
-+0x0,0x8,0x6,0x2,0x10,0xc,0x4,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x44,0x7e,0xc0,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x78,0x48,0x53,0x50,0x60,0x57,0x48,0x4a,0x4a,0x6a,0x52,0x45,0x44,0x48,0x40,0x40,0x40,0x50,0xf8,0x40,0x48,0xfc,0x40,0x50,0x78,0x40,0x40,0x40,0xc6,0x3c,0x0,
-+0x0,0x7f,0x0,0x0,0x1f,0x10,0x10,0x10,0x10,0x1f,0x0,0x8,0x4,0x2,0xff,0x0,0x8,0xfc,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0xf0,0x0,0x20,0x40,0x84,0xfe,0x0,
-+0x0,0x47,0x20,0x20,0x3,0x2,0xf2,0x13,0x10,0x11,0x10,0x17,0x10,0x28,0x47,0x0,0x8,0xfc,0x0,0x8,0xfc,0x8,0x8,0xf8,0x0,0x10,0xa0,0xfc,0x0,0x6,0xfc,0x0,
-+0x1,0x0,0x1f,0x10,0x97,0x50,0x53,0x12,0x32,0x52,0xd3,0x10,0x21,0x20,0x4f,0x0,0x0,0x84,0xfe,0x0,0xfc,0x8,0xfc,0x8,0x8,0x8,0xf8,0x0,0x10,0xa4,0xfe,0x0,
-+0x10,0x12,0x7f,0x12,0x14,0xff,0x8,0x12,0x3f,0x62,0xa2,0x3e,0x22,0x22,0x3e,0x22,0x0,0x7c,0x44,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x8,0xe,0x8,0xff,0x28,0x2a,0x49,0x58,0x9f,0x10,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x0,0xfc,0x4,0x88,0x50,0x20,0x50,0x8e,0xf4,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x10,
-+0x1,0x3f,0x1,0x1f,0x1,0x7f,0x0,0x1f,0x12,0x11,0xff,0x22,0x21,0x3f,0x0,0x0,0x10,0xf8,0x0,0xf0,0x0,0xfc,0x0,0xf0,0x10,0x14,0xfe,0x10,0x10,0xf8,0x10,0x60,
-+0x10,0x10,0x51,0x50,0x7c,0x53,0x90,0x14,0x19,0x30,0xd7,0x10,0x10,0x10,0x10,0x13,0x20,0x28,0xfc,0x20,0x20,0xfe,0x92,0x54,0x10,0x94,0xfe,0x20,0x20,0x50,0x8c,0x4,
-+0x0,0x44,0x28,0x10,0x2b,0x4a,0x8a,0x1a,0x2a,0x4b,0xa,0x8,0x8,0x8,0x57,0x20,0x40,0x40,0x40,0x48,0xfc,0x48,0x48,0x48,0x48,0xf8,0x48,0x40,0x48,0x78,0x84,0x4,
-+0x0,0x20,0x13,0x10,0x0,0x7,0xf0,0x10,0x11,0x10,0x17,0x10,0x14,0x18,0x10,0x3,0x20,0x28,0xfc,0x20,0x20,0xfe,0x92,0x54,0x10,0x94,0xfe,0x20,0x20,0x50,0x8c,0x4,
-+0x10,0x10,0x10,0x11,0xfc,0x10,0x17,0x10,0x10,0x11,0x1e,0xe4,0x48,0x10,0x0,0x0,0x40,0x40,0x44,0xf8,0x48,0x50,0xfe,0x48,0xfc,0x88,0x88,0xf8,0x88,0x88,0xf8,0x88,
-+0x8,0x7c,0x48,0x49,0x48,0x78,0x4f,0x48,0x48,0x79,0x4a,0x4c,0x48,0x78,0x48,0x0,0x40,0x40,0x44,0xf8,0x48,0x50,0xfe,0x48,0xfc,0x88,0x88,0xf8,0x88,0x88,0xf8,0x88,
-+0x4,0x7e,0x44,0x55,0x54,0x54,0x57,0x54,0x54,0x55,0x56,0x54,0x10,0x28,0x44,0x84,0x40,0x40,0x44,0xf8,0x48,0x50,0xfe,0x48,0xfc,0x88,0x88,0xf8,0x88,0x88,0xf8,0x88,
-+0x10,0x10,0x10,0x14,0xfe,0x10,0x31,0x38,0x54,0x54,0x90,0x10,0x10,0x10,0x13,0x10,0x20,0x20,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x20,0x20,0x3b,0x42,0x82,0x7b,0x22,0x22,0xfa,0x23,0x22,0x2a,0x34,0x24,0x8,0x3,0x40,0x24,0xfe,0x50,0x50,0xfc,0x50,0x70,0x0,0xf8,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x4,0x3e,0x24,0x24,0x24,0x3c,0x25,0x24,0x24,0x3c,0x24,0x24,0x24,0x27,0x54,0x88,0x20,0x20,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,0x0,
-+0x1,0x0,0x3f,0x22,0x22,0x3f,0x22,0x23,0x20,0x2f,0x22,0x21,0x20,0x43,0x8c,0x30,0x0,0x84,0xfe,0x20,0x28,0xfc,0x20,0xe0,0x0,0xf0,0x20,0x40,0x80,0x60,0x1e,0x4,
-+0x0,0x40,0x37,0x14,0x84,0x67,0x24,0x4,0x14,0x25,0xe4,0x24,0x28,0x28,0x31,0x26,0x80,0x44,0xfe,0x90,0x94,0xfe,0x90,0xf0,0x0,0xf8,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x10,0x10,0x10,0x10,0xfd,0x25,0x25,0x25,0x25,0x45,0x29,0x11,0x2a,0x46,0x84,0x8,0x40,0x20,0x20,0x4,0xfe,0x4,0x4,0x4,0xfc,0x4,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x20,0x11,0x11,0xfd,0x1,0x48,0x4b,0x48,0x49,0x49,0x11,0x1d,0xe1,0x41,0x1,0x20,0x20,0x24,0x24,0x24,0xfc,0x0,0xfe,0x44,0xfe,0x54,0x54,0x54,0x54,0x4,0xc,
-+0x20,0x20,0x2b,0x3c,0x50,0x91,0x11,0x15,0xff,0x11,0x10,0x11,0x28,0x24,0x47,0x80,0x0,0x8,0xfc,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x0,0x8,0x90,0x94,0xfe,0x0,
-+0x21,0x26,0x3c,0x44,0x87,0x7c,0x24,0x27,0xfd,0x24,0x24,0x27,0x2c,0x34,0x25,0x6,0x88,0x7c,0x48,0x48,0x48,0x48,0x86,0x0,0xfc,0x88,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x0,0x6,0x38,0x20,0x24,0x3e,0x21,0x24,0x3e,0x20,0x20,0x3e,0xe0,0x20,0x20,0x23,0x8,0xfc,0x88,0x88,0x88,0x88,0x6,0x0,0xf8,0x88,0x90,0x50,0x20,0x50,0x8e,0x4,
-+0x4,0x44,0x64,0x55,0x4e,0x44,0x7f,0x44,0x4e,0x55,0x64,0x44,0x44,0x7f,0x40,0x1,0x0,0xc,0xf0,0x40,0x40,0x44,0x7e,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x88,0x8,
-+0x21,0x26,0x24,0x44,0x4f,0xf4,0x24,0x47,0x45,0xfc,0x4,0xf,0x34,0xc4,0x5,0x6,0x88,0x7c,0x48,0x48,0x48,0x48,0x86,0x0,0xfc,0x88,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x10,0x10,0x10,0x10,0x11,0xfd,0x13,0x15,0x11,0x11,0x1d,0xe1,0x41,0x1,0x1,0x1,0x80,0xa0,0x90,0x84,0xfe,0x10,0x10,0xfc,0x10,0x10,0xfc,0x10,0x10,0x14,0xfe,0x0,
-+0x10,0x8,0x4,0x1f,0x10,0x10,0x10,0x10,0x1f,0x14,0x4,0x4,0x8,0x8,0x10,0x60,0x10,0x20,0x50,0xf8,0x10,0x10,0x10,0x10,0xf0,0x50,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x0,0x7c,0x44,0x48,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x69,0x51,0x42,0x44,0x48,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xa0,0xa0,0xa0,0x10,0x10,0x8,0x6,0x4,
-+0x0,0x0,0x0,0xfc,0x7,0x4,0x48,0x29,0x10,0x10,0x28,0x24,0x44,0x80,0x0,0x0,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x90,0x90,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x24,0x22,0x3f,0x20,0x2f,0xf8,0x2f,0x20,0x2f,0x21,0x22,0x3f,0xe2,0x42,0xa,0x4,0x20,0xa0,0xe0,0x24,0xbe,0xc4,0xa4,0x24,0xa4,0x28,0x28,0x90,0x10,0x28,0x46,0x84,
-+0x0,0x8,0x7c,0x4f,0x48,0x48,0x4a,0x4a,0x4a,0x4a,0x4b,0x7a,0x48,0x0,0x0,0x0,0x40,0x40,0x48,0xfc,0x40,0x40,0x48,0x48,0x48,0x48,0xf8,0x48,0x40,0x42,0x42,0x3e,
-+0x8,0x7f,0x48,0x49,0x49,0x49,0x79,0x51,0x11,0x59,0x50,0x57,0x59,0xe0,0x40,0x0,0x88,0xfe,0x54,0xfe,0x54,0xdc,0x4,0xfc,0x4,0xfc,0x8,0xfe,0x8,0x88,0x28,0x10,
-+0x10,0xa,0xff,0x0,0x7e,0x43,0x42,0x7e,0x0,0x7e,0x4,0x8,0xfe,0x8,0x29,0x12,0x40,0x40,0x44,0x7e,0x88,0x8,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x10,0x11,0x14,0xfe,0x11,0x55,0x55,0x55,0x55,0x7d,0x55,0x11,0x14,0x18,0x10,0x3,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x20,0x50,0x8c,0x4,
-+0x0,0x7f,0x41,0x41,0x5f,0x41,0x49,0x49,0x49,0x4f,0x49,0x41,0x40,0x40,0x7f,0x40,0x4,0xfe,0x4,0x24,0xf4,0x4,0x24,0x24,0x24,0xe4,0x4,0x14,0xf4,0x4,0xfc,0x4,
-+0x10,0x10,0x1c,0x23,0x20,0x7d,0x91,0x11,0xfd,0x11,0x11,0x10,0x14,0x18,0x10,0x0,0x20,0x20,0x24,0xfe,0x20,0x24,0x24,0x24,0x24,0xfc,0x24,0x20,0x22,0x22,0x1e,0x0,
-+0x0,0x3f,0x20,0x20,0x3f,0x20,0x20,0x2f,0x28,0x2f,0x28,0x2f,0x48,0x48,0x8f,0x8,0x78,0x80,0x80,0x84,0xfe,0x80,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x0,0x47,0x24,0x24,0x7,0x4,0xe5,0x25,0x25,0x25,0x25,0x29,0x21,0x50,0x8f,0x0,0x38,0xc0,0x40,0x48,0xfc,0x40,0xf8,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x6,0xfc,0x0,
-+0x20,0x2f,0x24,0x25,0xfa,0x25,0x28,0x20,0x3f,0xe0,0x28,0x25,0x22,0x25,0xa8,0x50,0x0,0xfc,0xa4,0x28,0x10,0x28,0xc4,0x0,0xbc,0x84,0xc4,0x28,0x10,0x28,0xce,0x84,
-+0x0,0x8,0x7c,0x49,0x4a,0x48,0x48,0x49,0x4e,0x48,0x49,0x7a,0x48,0x0,0x1,0x6,0x40,0x40,0xfc,0x8,0x90,0x60,0x40,0xa0,0x7e,0x84,0x88,0x50,0x20,0x40,0x80,0x0,
-+0x2,0x2,0x7,0x8,0x18,0x25,0x2,0xc,0x71,0x2,0xc,0x12,0x21,0x1,0xe,0x70,0x0,0x0,0xf0,0x20,0x40,0x80,0x80,0x80,0xfc,0x8,0x10,0x20,0xc0,0x0,0x0,0x0,
-+0x1,0x1,0x7f,0x2,0x4,0x8,0x30,0xc0,0x0,0x7f,0x4,0x2,0x2,0x0,0x0,0x0,0x0,0x8,0xfc,0x80,0x40,0x30,0xe,0x24,0x20,0xfc,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x10,0x11,0x11,0x11,0xfd,0x11,0x16,0x10,0x1f,0x10,0x1c,0xf1,0x42,0x4,0x8,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x4c,0x40,0xfe,0xc0,0xe0,0x50,0x48,0x46,0x44,0x40,
-+0x8,0x10,0x3c,0x24,0x3c,0x24,0x3d,0x24,0xff,0x14,0x14,0x24,0x24,0x45,0x96,0x8,0x8,0xfc,0x88,0x88,0x88,0x88,0x26,0x24,0xfe,0x60,0x70,0xb0,0xa8,0x26,0x24,0x20,
-+0x0,0xf,0x8,0x8,0x8,0x8,0x31,0x1,0xff,0x3,0x3,0x5,0x9,0x11,0x61,0x1,0x20,0xf0,0x20,0x20,0x20,0x20,0x1c,0x0,0xfe,0x0,0x80,0x40,0x20,0x1c,0x8,0x0,
-+0x8,0x7d,0x49,0x49,0x49,0x49,0x7a,0x10,0x17,0x58,0x50,0x51,0x5d,0xe2,0x44,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0xc,0x40,0xfe,0xc0,0xe0,0x50,0x4e,0x44,0x40,0x40,
-+0x8,0x10,0x3c,0x25,0x35,0x2e,0x24,0xfc,0x24,0x34,0x2c,0x24,0x24,0x44,0x94,0x8,0x40,0x20,0x0,0xfe,0x2,0x4,0x80,0x88,0x90,0xa0,0xc0,0x80,0x84,0x84,0x7c,0x0,
-+0x2,0x3f,0x22,0x22,0x22,0x22,0x49,0x9,0xff,0x8,0x1c,0x2b,0x49,0x88,0x8,0x8,0x4,0x4,0x4,0x24,0x24,0x24,0xa4,0x24,0xa4,0x24,0x24,0x24,0x4,0x4,0x14,0x8,
-+0x10,0x10,0x17,0x11,0x59,0x56,0x53,0x94,0x19,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x80,0x84,0xfe,0x0,0xfc,0x20,0xfe,0x4,0xfe,0x4,0xfc,0x4,0xfc,0x4,0x14,0x8,
-+0x0,0x7b,0x48,0x49,0x52,0x4c,0x48,0x68,0x50,0x41,0x41,0x3f,0x1,0x1,0xff,0x0,0x44,0xfe,0x88,0xfc,0x88,0xf8,0x88,0xf8,0x88,0x98,0x0,0xf8,0x0,0x4,0xfe,0x0,
-+0x10,0x10,0x13,0x10,0x7c,0x57,0x54,0x54,0x54,0x57,0x7c,0x50,0x14,0x1c,0xf2,0x41,0x10,0xd4,0x92,0x90,0x90,0xfe,0x90,0x90,0xd4,0x98,0x90,0xa8,0xc8,0x8a,0x86,0x2,
-+0x10,0x10,0x13,0x54,0x54,0x57,0x54,0x54,0x54,0x57,0x54,0x54,0x5c,0x74,0x42,0x1,0x10,0xd0,0x94,0x92,0x90,0xfe,0x90,0x90,0xd4,0x98,0x90,0xa8,0xc8,0x8a,0x86,0x2,
-+0x8,0x38,0xec,0x2a,0x28,0xfe,0x28,0x28,0x38,0xea,0x2c,0x28,0x35,0x24,0xa5,0x42,0x20,0x48,0xfc,0x88,0xa8,0x88,0xa8,0x90,0x80,0xfe,0x2,0x12,0xfa,0x2,0x14,0x8,
-+0x8,0x9,0xf,0x11,0x11,0x3f,0x51,0x91,0x11,0x13,0x1d,0x11,0x11,0x11,0x15,0x12,0x20,0xa8,0x24,0x20,0x24,0xfe,0x20,0x20,0xa4,0x18,0x10,0x30,0x48,0x8a,0x6,0x2,
-+0x10,0x8,0x7f,0x41,0x92,0x1e,0x22,0x54,0x8,0x14,0x22,0x7f,0xa2,0x22,0x3e,0x20,0x4,0xfe,0x10,0x24,0x7e,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x10,0x28,0x46,0x82,
-+0x1,0x41,0x31,0x11,0x1,0x3,0xf5,0x19,0x11,0x11,0x11,0x11,0x15,0x19,0x11,0x1,0x20,0x20,0x20,0x24,0x2c,0x30,0x20,0x60,0xa0,0x20,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x10,0x10,0x13,0x10,0xfc,0x27,0x24,0x24,0x24,0x45,0x2a,0x10,0x28,0x44,0x86,0x1,0x10,0xd0,0x94,0x92,0x90,0xfe,0x90,0x90,0xd4,0x98,0x90,0xa8,0xc8,0x8a,0x86,0x2,
-+0x0,0x7f,0x4,0x24,0x14,0x14,0x4,0x4,0xff,0x0,0x2a,0x29,0x28,0x48,0x7,0x0,0x8,0xfc,0x40,0x48,0x58,0x60,0x40,0x44,0xfe,0x0,0x10,0x88,0xa4,0x24,0xe0,0x0,
-+0x0,0x3f,0x20,0x20,0x20,0x27,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x43,0x80,0x8,0xfc,0x0,0x0,0x20,0xf0,0x20,0x20,0x20,0xa0,0x40,0x0,0x4,0x4,0xfc,0x0,
-+0x10,0x10,0x13,0x12,0xfe,0x12,0x16,0x1a,0x32,0xd2,0x12,0x12,0x12,0x14,0x58,0x20,0x0,0x4,0xfe,0x0,0x8,0xfc,0x88,0x88,0x88,0xa8,0x90,0x80,0x82,0x82,0x7e,0x0,
-+0x0,0x47,0x24,0x27,0x4,0x7,0xe2,0x25,0x2c,0x34,0x25,0x24,0x27,0x50,0x8f,0x0,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x8,0xfc,0x88,0x88,0x48,0x28,0xd0,0x6,0xfc,0x0,
-+0x0,0x77,0x55,0x55,0x77,0x0,0x7f,0x0,0xff,0x10,0x22,0x3f,0x2,0x2,0x12,0xc,0x0,0x7c,0x44,0x44,0x48,0x48,0x50,0x48,0xc4,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x20,0x20,0x23,0x3c,0x24,0x4b,0x40,0xa0,0x20,0x21,0x22,0x20,0x28,0x30,0x22,0x1,0x10,0xd0,0x94,0x92,0x90,0xfe,0x90,0x90,0xd4,0x98,0x90,0xa8,0xc8,0x8a,0x86,0x2,
-+0x0,0x3f,0x21,0x21,0x2f,0x21,0x22,0x24,0x28,0x3f,0x20,0x2,0x51,0x50,0x90,0xf,0x8,0xfc,0x8,0x48,0xe8,0x8,0x88,0x68,0x28,0xf8,0x8,0x0,0x84,0x92,0x12,0xf0,
-+0x0,0xff,0x2,0x2,0x4,0x7f,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x40,0x4,0xfe,0x0,0x0,0x4,0xfe,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x54,0x8,
-+0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x8,0x8,0x10,0x20,0x40,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x42,0x3e,0x0,
-+0x0,0x7f,0x8,0x8,0xf,0x8,0x8,0xf,0x8,0x8,0x8,0xff,0x0,0x0,0x0,0x0,0x8,0xfc,0x20,0x20,0xe0,0x20,0x20,0xe0,0x20,0x24,0x3e,0xe0,0x20,0x20,0x20,0x20,
-+0x8,0xc,0x8,0x1f,0x20,0x41,0x81,0x1,0x9,0x9,0x11,0x11,0x21,0x1,0x5,0x2,0x0,0x0,0x8,0xfc,0x8,0x10,0x0,0x0,0x40,0x20,0x10,0x18,0x8,0x0,0x0,0x0,
-+0x20,0x23,0x21,0x3d,0x25,0x49,0x41,0xa1,0x21,0x21,0x27,0x20,0x28,0x30,0x20,0x0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0xfe,0x8,0x8,0x8,0x8,0x8,
-+0x0,0x47,0x32,0x12,0x83,0x62,0x22,0xb,0x12,0x22,0xe2,0x2f,0x20,0x20,0x20,0x20,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0x8,0xfe,0x8,0x8,0x8,0x8,
-+0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,
-+0x0,0x0,0xff,0x0,0x3f,0x0,0x7f,0x0,0x3f,0x20,0x24,0x24,0x24,0xa,0x11,0x60,0x28,0x24,0xfe,0x20,0xa0,0x20,0xe0,0x20,0xa0,0x90,0x90,0x90,0x92,0xa,0x8a,0x84,
-+0x1,0x11,0x11,0x21,0x7f,0x2,0x2,0x7,0x6,0xa,0x9,0x10,0x21,0x42,0x8c,0x30,0x0,0x20,0x10,0x4,0xfe,0x0,0x0,0xf0,0x10,0x20,0x40,0x80,0x40,0x30,0xe,0x4,
-+0x0,0x7f,0x44,0x44,0x7f,0x20,0x18,0x8,0x0,0xf0,0x10,0x12,0x14,0x18,0x10,0x0,0x4,0xfe,0x44,0x44,0xfc,0x0,0x8,0x88,0x88,0x88,0x88,0x88,0x88,0x8,0x28,0x10,
-+0x10,0x1f,0x28,0x45,0x0,0x8,0x8,0x10,0x37,0x50,0x90,0x10,0x10,0x10,0x13,0x10,0x40,0x7c,0xa0,0x10,0x80,0x90,0x88,0xfe,0x80,0x50,0x50,0x20,0x60,0x92,0xa,0x6,
-+0x8,0x8,0x8,0x10,0x10,0x30,0x57,0x90,0x10,0x10,0x10,0x10,0x10,0x11,0x16,0x10,0x80,0xa0,0x98,0x88,0x80,0xfc,0x80,0x88,0x88,0x50,0x60,0x40,0xa0,0x12,0xa,0x6,
-+0x0,0x0,0x7f,0x4,0x3,0x1,0x3f,0x0,0x0,0x1,0x6,0x8,0x30,0x48,0x7,0x0,0x10,0x78,0x80,0x0,0x0,0x0,0xf8,0x10,0x60,0x80,0x0,0x0,0x0,0x6,0xfc,0x0,
-+0x20,0x17,0x10,0x45,0x45,0x49,0x49,0x5f,0x69,0x48,0x48,0x49,0x4a,0x48,0x48,0x40,0x4,0xfe,0x4,0x44,0x24,0x4,0xf4,0x4,0x24,0xc4,0x84,0x44,0x54,0x34,0x4,0xc,
-+0x0,0x40,0x30,0x10,0x87,0x60,0x20,0x8,0x17,0x20,0xe0,0x20,0x21,0x22,0x27,0x20,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x40,0x40,0x80,0x10,0x8,0xfc,0x4,
-+0x0,0x10,0xf8,0x20,0x27,0x20,0x20,0xf8,0x2f,0x20,0x20,0x20,0x39,0xe2,0x47,0x0,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x40,0x40,0x80,0x8,0x4,0xfe,0x2,
-+0x8,0xff,0x8,0x4f,0x24,0x22,0x8f,0x62,0x2a,0x14,0x2f,0xe4,0x27,0x24,0x27,0x24,0x24,0xfe,0x20,0xf8,0x90,0xa0,0xfc,0xa0,0x90,0x8e,0xf4,0x90,0xf0,0x90,0xf0,0x10,
-+0x10,0x10,0x14,0x7e,0x54,0x54,0x54,0x54,0x54,0x54,0x5c,0x54,0x11,0x11,0x12,0x14,0x8,0xfc,0x88,0x88,0x88,0xc8,0xa8,0xa8,0x88,0x88,0x88,0x88,0xa,0xa,0x6,0x0,
-+0x0,0x3f,0x11,0xd,0x5,0xff,0x9,0x11,0x3f,0xd1,0x11,0x1f,0x11,0x11,0x1f,0x10,0x78,0x80,0x10,0x30,0x44,0xfe,0x20,0x10,0xfe,0x14,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0xe,0xf1,0x54,0x38,0xfe,0x11,0x54,0x92,0x7c,0x54,0x55,0x7c,0x54,0x54,0x7d,0x44,0x4,0xde,0x44,0x44,0x44,0x54,0xcc,0x44,0x44,0xcc,0x54,0x44,0x44,0x44,0x54,0x88,
-+0x10,0x14,0x12,0xfd,0x12,0x38,0x56,0x91,0x12,0x14,0x1,0xff,0x2,0x4,0x18,0x60,0x10,0x50,0x94,0x7e,0x90,0x38,0xd4,0x12,0x90,0x50,0x4,0xfe,0x80,0x40,0x3c,0x8,
-+0x8,0xfd,0x11,0x11,0x21,0x29,0x7d,0xa9,0x29,0x29,0x29,0x29,0x3a,0x2a,0x4,0x8,0x10,0xf8,0x10,0x10,0x10,0x90,0x50,0x50,0x10,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x10,0x11,0x3d,0x21,0x41,0xfd,0x11,0x11,0xfd,0x11,0x11,0x15,0x1a,0x12,0x4,0x8,0x10,0xf8,0x10,0x10,0x10,0x90,0x50,0x50,0x10,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x22,0x3f,0x40,0xbe,0x2a,0xff,0x2a,0x3e,0x2,0x1f,0x1,0x6,0x3f,0x9,0x19,0x22,0x20,0x24,0x7e,0xc4,0x28,0x90,0x2e,0xc4,0x20,0xc0,0x80,0x10,0xf8,0x20,0x18,0x8,
-+0x0,0xf,0x8,0x8,0x8,0xa,0x9,0x9,0x8,0x8,0x8,0x8,0x10,0x10,0x20,0x40,0x20,0xf0,0x20,0x20,0x20,0x20,0x20,0xa0,0xa0,0x20,0x20,0x22,0x22,0x22,0x1e,0x0,
-+0x10,0x13,0x10,0x14,0x59,0x51,0x51,0x91,0x11,0x11,0x11,0x29,0x24,0x44,0x81,0x2,0x4,0xfe,0x40,0x88,0xfc,0x8,0x28,0x28,0x28,0x48,0x48,0x48,0x80,0x90,0xc,0x4,
-+0x0,0x0,0x3f,0x20,0x20,0x3f,0x24,0x24,0x22,0x22,0x21,0x20,0x41,0x42,0x84,0x18,0x10,0x78,0x80,0x0,0x0,0xf8,0x8,0x10,0x10,0x20,0x40,0x80,0x40,0x30,0xe,0x4,
-+0x0,0x40,0x33,0x12,0x2,0x2,0xf2,0x12,0x12,0x12,0x12,0x14,0x15,0x28,0x44,0x3,0x8,0x1c,0xe0,0x0,0x0,0xf8,0x8,0x90,0x50,0x20,0x50,0x8c,0x4,0x0,0x6,0xfc,
-+0x8,0x8,0xff,0x8,0x20,0x1b,0x4a,0x22,0x22,0xa,0xf2,0x22,0x22,0x22,0x21,0x20,0x20,0x24,0xfe,0x20,0x10,0xf8,0x10,0x10,0x10,0x50,0x20,0x0,0x2,0x2,0xfe,0x0,
-+0x4,0x7e,0x45,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x11,0x2a,0x44,0x81,0x8,0x1c,0xe0,0x0,0x0,0xfc,0x4,0x48,0x48,0x50,0x30,0x20,0x50,0x48,0x8e,0x4,
-+0x2,0x44,0x29,0x11,0x29,0x49,0x89,0x9,0x19,0x29,0x49,0x89,0x9,0x9,0x50,0x20,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0x28,0x10,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x20,0x20,0x21,0x3d,0x25,0x49,0x41,0xa1,0x21,0x21,0x21,0x25,0x29,0x32,0x24,0x9,0x8,0x1c,0xe0,0x0,0x0,0xfc,0x4,0x48,0x48,0x50,0x30,0x20,0x50,0x48,0x8e,0x4,
-+0x0,0x40,0x37,0x10,0x80,0x40,0x47,0x10,0x10,0x20,0xe0,0x21,0x26,0x29,0x20,0x20,0x10,0x38,0xc0,0x80,0x40,0x40,0xfc,0x8,0x30,0x40,0x80,0x0,0x0,0x6,0xfc,0x0,
-+0x10,0x10,0x10,0x10,0x13,0xfc,0x10,0x10,0x10,0x10,0x1c,0xf0,0x41,0x1,0x2,0x4,0x80,0x40,0x40,0x4,0xfe,0x80,0x88,0xfc,0x88,0x88,0x88,0x88,0x8,0x8,0x50,0x20,
-+0x8,0x8,0xff,0x8,0xa,0x1,0xff,0x4,0x4,0x7,0x4,0x4,0x8,0x8,0x10,0x20,0x20,0x24,0xfe,0x20,0x20,0x4,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0xa0,0x40,
-+0x4,0x3,0x1,0x0,0xff,0x4,0x4,0x7,0x4,0x4,0x4,0x8,0x8,0x10,0x20,0x40,0x0,0x0,0x0,0x4,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0xa0,0x40,
-+0x4,0x3e,0x24,0x24,0x27,0x3c,0x24,0x24,0x24,0x3c,0x24,0x24,0x25,0x25,0x4e,0x84,0x80,0x40,0x40,0x4,0xfe,0x80,0x88,0xfc,0x88,0x88,0x88,0x88,0x8,0x8,0x50,0x20,
-+0x2,0x1,0x3f,0x20,0x3f,0x21,0x20,0x3f,0x22,0x22,0x23,0x22,0x44,0x44,0x88,0x10,0x0,0x8,0xfc,0x8,0xf8,0x0,0x84,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0xa0,0x40,
-+0x0,0x7c,0x44,0x48,0x4f,0x50,0x48,0x48,0x44,0x44,0x44,0x68,0x51,0x41,0x42,0x44,0x80,0x40,0x40,0x4,0xfe,0x80,0x88,0xfc,0x88,0x88,0x88,0x88,0x8,0x8,0x50,0x20,
-+0x10,0x10,0x10,0x10,0xff,0x24,0x24,0x24,0x24,0x44,0x28,0x10,0x29,0x45,0x82,0x4,0x80,0x40,0x40,0x4,0xfe,0x80,0x88,0xfc,0x88,0x88,0x88,0x88,0x8,0x8,0x50,0x20,
-+0x8,0x8,0x8,0x10,0x17,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x11,0x11,0x12,0x14,0x80,0x40,0x40,0x4,0xfe,0x80,0x88,0xfc,0x88,0x88,0x88,0x88,0x8,0x8,0x50,0x20,
-+0x0,0x20,0x10,0x10,0x7,0x0,0xf0,0x10,0x10,0x10,0x10,0x10,0x15,0x19,0x12,0x4,0x80,0x40,0x40,0x4,0xfe,0x80,0x88,0xfc,0x88,0x88,0x88,0x88,0x8,0x8,0x50,0x20,
-+0x10,0x10,0x20,0x20,0x47,0xfc,0x10,0x20,0x40,0xfc,0x40,0x0,0x1d,0xe1,0x42,0x4,0x80,0x40,0x40,0x4,0xfe,0x80,0x88,0xfc,0x88,0x88,0x88,0x88,0x8,0x8,0x50,0x20,
-+0x20,0x10,0x10,0x0,0xff,0x20,0x24,0x3e,0x24,0x24,0x24,0x24,0x44,0x54,0x89,0x2,0x40,0x40,0x40,0x84,0xfe,0x8,0x88,0x88,0x50,0x50,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x8,0x8,0xff,0x8,0x4,0x4,0x7c,0x4,0x4,0x7c,0x4,0x4,0xfc,0x4,0x4,0x4,0x20,0x24,0xfe,0x20,0x40,0x48,0x7c,0x40,0x48,0x7c,0x40,0x44,0x7e,0x40,0x40,0x40,
-+0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x7c,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x40,0x40,0x44,0x7e,0x40,0x40,0x48,0x7c,0x40,0x40,0x40,0x44,0x7e,0x40,0x40,0x40,
-+0x0,0x8,0x7c,0x4f,0x48,0x48,0x48,0x4f,0x48,0x48,0x48,0x78,0x4f,0x0,0x0,0x0,0x90,0x90,0x94,0x9e,0x90,0x90,0x94,0x9e,0x90,0x90,0x90,0x94,0x9e,0x90,0x90,0x90,
-+0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0xf0,0x20,0x24,0x2c,0x30,0x20,0x30,0x2c,0x24,0x20,0x20,0x10,0x12,0xa,0x4,
-+0x4,0x7f,0x45,0x45,0x45,0x7d,0x45,0x45,0x45,0x7d,0x45,0x45,0x45,0x45,0x54,0x88,0x4,0xfe,0x24,0x24,0x24,0x24,0x24,0xfc,0x4,0x0,0x0,0x2,0x2,0x2,0xfe,0x0,
-+0x0,0x7f,0x42,0x42,0x5e,0x42,0x42,0x5e,0x42,0x42,0x7e,0x42,0x42,0x42,0x7f,0x0,0x4,0xfe,0x40,0x50,0x78,0x40,0x50,0x78,0x40,0x48,0x7c,0x40,0x40,0x44,0xfe,0x0,
-+0x20,0x10,0x10,0x7,0x0,0xf0,0x10,0x13,0x10,0x10,0x10,0x17,0x14,0x18,0x10,0x0,0x90,0x90,0x94,0x9e,0x90,0x90,0x90,0x9c,0x90,0x90,0x94,0x9e,0x90,0x90,0x90,0x90,
-+0x0,0x8,0x7c,0x48,0x48,0x48,0x4f,0x48,0x48,0x48,0x49,0x79,0x4a,0x2,0x4,0x8,0x40,0x50,0x48,0x48,0x40,0x44,0xfe,0x40,0xa0,0xa0,0x10,0x10,0x8,0xe,0x4,0x0,
-+0x4,0x3e,0x24,0x27,0x24,0x3c,0x25,0x25,0x25,0x3d,0x25,0x25,0x25,0x24,0x54,0x88,0x20,0x20,0x24,0xfe,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x2c,0x20,0x20,0x20,
-+0x1,0x0,0x3f,0x20,0x24,0x24,0x2f,0x21,0x23,0x22,0x25,0x24,0x28,0x30,0x43,0x8c,0x0,0x88,0xfc,0x80,0x90,0x88,0xfe,0x0,0xf8,0x8,0x10,0xa0,0x40,0xb0,0xe,0x4,
-+0x1,0x41,0x2f,0x21,0x1,0x8f,0x49,0x9,0x1f,0x29,0xe1,0x21,0x22,0x22,0x24,0x28,0x20,0x24,0xfe,0x24,0x24,0xfc,0x24,0x20,0xfe,0x22,0x22,0x2a,0x24,0x20,0x20,0x20,
-+0x4,0x7f,0x4,0x7f,0x44,0x7f,0x4,0x8,0x3f,0xd0,0x11,0x11,0x11,0x2,0xc,0x30,0x48,0xfc,0x48,0xf8,0x40,0xfe,0x42,0x4a,0xf4,0x10,0x10,0x10,0x10,0xc0,0x30,0x8,
-+0x8,0x8,0xff,0x8,0x4,0x4,0x8,0x10,0x20,0xcf,0x4,0x4,0x4,0x8,0x10,0x20,0x20,0x24,0xfe,0x20,0x80,0x80,0x40,0x30,0xe,0xe4,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x4,0xfe,0x28,0x28,0xfe,0xaa,0xab,0xae,0xc2,0x82,0xfe,0x82,0x82,0xfe,0x82,0x1,0x8,0x48,0x48,0x48,0x84,0x84,0x2,0xfc,0x44,0x44,0x44,0x44,0x44,0x44,0x94,0x8,
-+0x0,0x8,0x7c,0x48,0x48,0x49,0x49,0x4a,0x4d,0x48,0x48,0x78,0x49,0x1,0x2,0x4,0x20,0xa0,0xa0,0x90,0x90,0x8,0xe,0x4,0xf8,0x88,0x88,0x88,0x8,0x8,0x28,0x10,
-+0x10,0x1f,0x10,0x2f,0x40,0xbf,0x1,0x9,0x8,0x10,0x3f,0x48,0x8,0x8,0x12,0x21,0x8,0xfc,0x0,0xf8,0x0,0xf8,0x8,0x8,0x88,0x48,0xb8,0xa8,0x88,0x8a,0x8a,0x4,
-+0x0,0x4,0x4,0x8,0x8,0x10,0x20,0x4f,0x84,0x4,0x4,0x4,0x4,0x8,0x11,0x20,0x80,0x80,0x40,0x40,0x20,0x10,0x8,0xee,0x24,0x20,0x20,0x20,0x20,0x20,0x40,0x80,
-+0x10,0x10,0x20,0x20,0x48,0xf9,0x11,0x22,0x45,0xf8,0x40,0x0,0x19,0xe1,0x42,0x4,0x20,0xa0,0xa0,0x90,0x90,0x8,0xe,0x4,0xf8,0x88,0x88,0x88,0x8,0x8,0x28,0x10,
-+0x10,0x10,0x10,0x10,0x13,0xfc,0x10,0x10,0x10,0x10,0x10,0x1c,0xf0,0x40,0x1,0x6,0x40,0x20,0x20,0x4,0xfe,0x88,0x88,0x88,0x88,0x48,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x8,0x8,0x8,0xfe,0x18,0x2c,0x4b,0x8,0x1,0x11,0x9,0xa,0x4,0x8,0x30,0xc0,0x20,0x20,0x24,0xfe,0x60,0xb8,0x24,0x20,0x10,0x30,0x40,0x80,0x40,0x30,0xe,0x4,
-+0x0,0x41,0x31,0x11,0x82,0x64,0x28,0x7,0x11,0x21,0xe1,0x21,0x22,0x22,0x24,0x28,0x20,0x20,0x20,0x10,0x10,0xe,0x4,0xf0,0x10,0x10,0x10,0x10,0x10,0x10,0xa0,0x40,
-+0x10,0x10,0x10,0x54,0x38,0x11,0xfd,0x12,0x39,0x34,0x50,0x90,0x11,0x11,0x12,0x14,0x20,0xa0,0xa0,0x90,0x90,0x8,0xe,0x4,0xf8,0x88,0x88,0x88,0x8,0x8,0x28,0x10,
-+0x1,0x1,0x1,0xff,0x2,0x4,0x8,0x30,0xdf,0x11,0x11,0x1f,0x11,0x11,0x1f,0x10,0x0,0x0,0x4,0xfe,0x80,0x40,0x20,0x1e,0xf4,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x8,0x9,0x9,0x11,0x12,0x32,0x54,0x9b,0x11,0x11,0x11,0x11,0x12,0x12,0x14,0x10,0x20,0x20,0x20,0x10,0x10,0xe,0x4,0xf0,0x10,0x10,0x10,0x10,0x10,0x10,0xa0,0x40,
-+0x0,0x4,0x4,0x8,0x1f,0x24,0xc4,0x9,0x30,0x0,0x2a,0x29,0x28,0x48,0x7,0x0,0x80,0x80,0x40,0x20,0xf0,0x2e,0x24,0x20,0xc0,0x0,0x10,0x88,0xa4,0x24,0xe0,0x0,
-+0x10,0x10,0x13,0x10,0x59,0x57,0x51,0x93,0x12,0x12,0x12,0x12,0x12,0x10,0x11,0x16,0x40,0x50,0xf8,0x40,0x54,0xfe,0x10,0xf8,0x8,0x48,0x48,0x48,0x48,0xa0,0x18,0x8,
-+0x11,0xd,0x5,0x7f,0x3,0x5,0x19,0x4,0x4,0x3f,0x4,0x4,0xff,0x8,0x18,0x20,0x10,0x30,0x40,0xfc,0x80,0x40,0x3c,0x48,0x40,0xf8,0x40,0x44,0xfe,0x20,0x18,0x8,
-+0x1,0x1,0x1,0x7f,0x1,0x1,0x1,0x3f,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x0,0x0,0x8,0xfc,0x0,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,
-+0x8,0x8,0xa,0x7f,0x8,0xa,0xff,0x8,0xa,0x7f,0x8,0x8,0xf,0x78,0x20,0x0,0x8,0x8,0x8,0x8,0x8,0xfe,0x8,0x8,0x48,0x28,0x28,0x8,0x8,0x8,0x28,0x10,
-+0x10,0x10,0x13,0x12,0xfe,0x12,0x3b,0x36,0x52,0x52,0x92,0x13,0x12,0x14,0x14,0x18,0x0,0x8,0xfc,0x8,0x8,0x8,0x18,0xa8,0x48,0x48,0xa8,0x18,0x8,0xa,0xa,0x6,
-+0x10,0x10,0x10,0x15,0x7e,0x54,0x54,0x57,0x54,0x7c,0x51,0x14,0x1d,0xe4,0x40,0x0,0x80,0x80,0xfc,0x88,0x50,0x20,0xde,0x24,0xf8,0x20,0xfc,0x20,0xfc,0x20,0x20,0x20,
-+0x10,0x10,0x10,0x11,0x56,0x54,0x54,0x57,0x54,0x54,0x55,0x5c,0x65,0x0,0x0,0x0,0x80,0x80,0xfc,0x88,0x50,0x20,0xde,0x24,0xf8,0x20,0xfc,0x20,0xfc,0x20,0x20,0x20,
-+0x10,0x10,0x10,0x1d,0x22,0x20,0x7c,0x93,0x10,0xfc,0x11,0x10,0x15,0x18,0x10,0x0,0x80,0x80,0xfc,0x88,0x50,0x20,0xde,0x24,0xf8,0x20,0xfc,0x20,0xfc,0x20,0x20,0x20,
-+0x0,0x3f,0x20,0x28,0x24,0x22,0x22,0x21,0x21,0x22,0x22,0x24,0x28,0x30,0x40,0x80,0x10,0xf8,0x10,0x50,0x50,0x90,0x90,0x10,0x10,0x90,0x90,0x50,0x50,0x12,0xa,0x6,
-+0x1,0x0,0x1f,0x10,0x97,0x54,0x56,0x15,0x34,0x54,0xd4,0x14,0x25,0x2a,0x48,0x10,0x0,0x84,0xfe,0x8,0xfc,0x8,0x18,0x18,0xa8,0x48,0x48,0xa8,0x18,0x1a,0xa,0x6,
-+0x10,0x10,0x10,0x15,0x5a,0x50,0x50,0x93,0x10,0x10,0x29,0x24,0x45,0x40,0x80,0x0,0x80,0x80,0xfc,0x88,0x50,0x20,0xde,0x24,0xf8,0x20,0xfc,0x20,0xfc,0x20,0x20,0x20,
-+0x0,0x41,0x23,0x24,0x0,0x1,0xee,0x20,0x27,0x20,0x23,0x20,0x27,0x20,0x50,0x8f,0x80,0xfc,0x8,0xb0,0x40,0xb0,0x4e,0x40,0xfc,0x40,0xf8,0x40,0xfc,0x40,0x46,0xfc,
-+0x0,0x47,0x30,0x12,0x2,0xa,0x12,0x12,0x23,0xe0,0x20,0x2f,0x20,0x20,0x20,0x20,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x4,0x24,0xf4,0x4,0x4,0x28,0x10,
-+0x10,0x10,0x24,0x23,0x4a,0xf8,0x17,0x22,0x42,0xfa,0x42,0x3,0x1a,0xe2,0x45,0x8,0x40,0x7c,0x88,0x50,0x20,0xd8,0x26,0xf8,0x20,0xf8,0x20,0xfc,0x20,0x20,0x26,0xfc,
-+0x0,0x47,0x24,0x24,0x6,0x5,0xe4,0x24,0x24,0x24,0x25,0x2e,0x34,0x24,0x8,0x10,0x8,0xfc,0x8,0x8,0x18,0x18,0xa8,0x48,0x48,0xa8,0x18,0x18,0x8,0xa,0xa,0x6,
-+0x1,0x1,0x7f,0x1,0x3f,0x2,0xff,0x4,0x9,0x31,0xcf,0x1,0x1f,0x1,0x1,0x1,0x0,0x8,0xfc,0x0,0xf8,0x0,0xfe,0x40,0x20,0x1e,0xe4,0x0,0xf0,0x0,0x0,0x0,
-+0x0,0x3f,0x20,0x20,0x2f,0x20,0x28,0x24,0x22,0x21,0x22,0x24,0x28,0x20,0x40,0x80,0x10,0xf8,0x10,0x10,0xf0,0x50,0x50,0x90,0x90,0x10,0x90,0xd0,0x50,0x12,0xa,0x6,
-+0x10,0x12,0x12,0x2f,0x22,0x62,0xaf,0x2a,0x2a,0x2f,0x22,0x22,0x22,0x24,0x28,0x20,0x40,0x40,0x48,0xfc,0x48,0x48,0xf8,0x40,0x44,0xfe,0x44,0x44,0x54,0x48,0x40,0x40,
-+0x0,0xff,0x0,0x1,0x3,0x5,0x9,0x31,0xc1,0x1f,0x10,0x10,0x10,0x10,0x1f,0x10,0x4,0xfe,0x80,0x0,0x0,0x60,0x18,0x6,0x12,0xf8,0x10,0x10,0x10,0x10,0xf0,0x10,
-+0x1,0x1,0x1,0x7f,0x1,0x1,0x1,0xff,0x1,0x2,0x2,0x4,0x4,0x8,0x10,0x60,0x0,0x0,0x8,0xfc,0x0,0x0,0x4,0xfe,0x0,0x80,0x80,0x40,0x40,0x30,0xe,0x4,
-+0x8,0xff,0x8,0x7f,0x49,0x7f,0x49,0x7f,0x49,0x8,0xff,0x10,0x1e,0x12,0x22,0x47,0x20,0xa0,0x20,0x24,0x7e,0x84,0x44,0x44,0x28,0x28,0x90,0x10,0x28,0x48,0x86,0x4,
-+0x4,0x3e,0x24,0x25,0x24,0x3c,0x24,0x27,0x24,0x3c,0x24,0x24,0x24,0x24,0x4d,0x86,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x50,0x50,0x88,0x88,0x6,0x4,
-+0x10,0x20,0x57,0x55,0x55,0x55,0x77,0x55,0x55,0x55,0x77,0x14,0x24,0x24,0x44,0x84,0xc,0xf0,0x2,0x54,0x54,0x0,0x7c,0x8,0x10,0x14,0xfe,0x10,0x10,0x10,0x50,0x20,
-+0x10,0x10,0x10,0x11,0xfc,0x10,0x14,0x1b,0x30,0xd0,0x10,0x10,0x10,0x10,0x51,0x26,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x50,0x50,0x88,0x88,0x6,0x4,
-+0x10,0x11,0x11,0x17,0xf9,0x11,0x17,0x1d,0x35,0xd7,0x11,0x11,0x11,0x12,0x54,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0xfc,0x24,0x20,0xfe,0x22,0x22,0x2a,0x24,0x20,0x20,
-+0x10,0x17,0x20,0xfb,0x22,0x52,0x53,0xf8,0x17,0x14,0xfc,0x17,0x14,0x14,0x17,0x14,0x8,0xfc,0x0,0xf8,0x8,0x8,0xf8,0x4,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x4,
-+0x10,0x11,0x14,0x7e,0x54,0x54,0x54,0x54,0x55,0x55,0x55,0x5d,0x11,0x11,0x11,0x11,0x8,0xfc,0x0,0xf8,0x88,0x88,0xf8,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x4,
-+0x10,0x1f,0x10,0x2f,0x40,0xbf,0xa,0x7f,0xa,0x7f,0x4a,0x7f,0xa,0xa,0x12,0x62,0x8,0xfc,0x0,0xf8,0x0,0xf8,0x8,0xc8,0x48,0xc8,0x8,0xe8,0x28,0xaa,0x4a,0x4,
-+0x10,0x12,0x1f,0x28,0x45,0x88,0x8,0x17,0x30,0x52,0x91,0x11,0x10,0x10,0x10,0x10,0x40,0x44,0x7e,0xa0,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x8,0x8,0x8,0x10,0x10,0x3f,0x50,0x90,0x10,0x10,0x10,0x11,0x11,0x12,0x14,0x18,0x40,0x40,0x50,0x4c,0x44,0xfe,0x40,0x40,0x40,0xa0,0xa0,0x10,0x10,0x8,0xe,0x4,
-+0x10,0x10,0x17,0x20,0x22,0x62,0xa0,0x27,0x20,0x20,0x2f,0x20,0x20,0x20,0x21,0x20,0x8,0x3c,0xc0,0x8,0x48,0x50,0x0,0xf8,0x20,0x44,0xfe,0x40,0x40,0x40,0x40,0x80,
-+0x2,0x3f,0x22,0x22,0x22,0x3e,0x22,0x22,0x22,0x3e,0x22,0x22,0x22,0x22,0x4a,0x84,0x8,0xfc,0x88,0x88,0x88,0x98,0x80,0xfc,0xa4,0xa4,0xa8,0x90,0xa8,0xa8,0xc6,0x84,
-+0x40,0x30,0x17,0x0,0x82,0x62,0x20,0xb,0x10,0x20,0xef,0x20,0x20,0x20,0x21,0x20,0x8,0x3c,0xc0,0x8,0x48,0x50,0x0,0xf8,0x20,0x44,0xfe,0x40,0x40,0x40,0x40,0x80,
-+0x40,0x30,0x17,0x0,0x81,0x60,0x20,0xf,0x10,0x23,0xe2,0x22,0x22,0x22,0x23,0x22,0x80,0x48,0xfc,0x0,0x10,0xa0,0x4,0xfe,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x20,0x17,0x10,0x3,0xfa,0xa,0x13,0x38,0x57,0x94,0x14,0x17,0x14,0x14,0x17,0x14,0x8,0xfc,0x0,0xf8,0x8,0x8,0xf8,0x4,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x4,
-+0x20,0x10,0x10,0x1,0xfd,0xb,0x15,0x31,0x55,0x99,0x15,0x11,0x11,0x11,0x11,0x11,0x90,0x90,0x94,0x12,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x28,0x28,0x46,0x84,0x0,
-+0x4,0x4,0x4,0x7f,0x4,0x4,0x7f,0x44,0x44,0x7f,0x44,0x4,0x8,0x30,0xc0,0x0,0x40,0x40,0x48,0xfc,0x48,0x48,0xf8,0x40,0x44,0xfe,0x44,0x44,0x54,0x48,0x40,0x40,
-+0x1,0x1,0xff,0x1,0x1,0x3f,0x21,0x21,0x3f,0x21,0x21,0x3f,0x21,0x21,0x21,0x20,0x20,0x14,0xfe,0x0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x10,0x10,0x17,0x10,0xfc,0x10,0x17,0x18,0x30,0xd0,0x10,0x11,0x11,0x12,0x54,0x28,0x0,0x8,0xfc,0x40,0x40,0x44,0xfe,0x40,0x40,0xa0,0xa0,0x20,0x22,0x22,0x1e,0x0,
-+0x10,0x10,0x15,0xfe,0x20,0x29,0x49,0x7f,0x9,0x9,0xf,0xf9,0x49,0x9,0x9,0x9,0x28,0x24,0xfe,0x20,0x24,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x24,0x24,0x24,0xc,
-+0x10,0x10,0x17,0x24,0x24,0x64,0xa5,0x25,0x27,0x25,0x25,0x25,0x29,0x29,0x31,0x21,0x80,0x44,0xfe,0x80,0x88,0x88,0x8,0xfe,0x8,0x48,0x28,0x28,0x8,0x8,0x28,0x10,
-+0x4,0x8,0x14,0x62,0x1,0xe,0x30,0xdf,0x1,0x1,0x3f,0x1,0x9,0x5,0x7f,0x0,0x40,0x20,0x50,0x8c,0x0,0xe0,0x1e,0xf4,0x0,0x10,0xf8,0x0,0x20,0x48,0xfc,0x0,
-+0x4,0x8,0x34,0x3,0xc,0x30,0xc0,0x1f,0x10,0x10,0x1f,0x10,0x10,0x20,0x40,0x0,0x40,0x20,0x58,0x80,0x60,0x1e,0xe4,0x0,0x0,0x10,0xf8,0x80,0x80,0x80,0x80,0x80,
-+0x0,0x3c,0x27,0x24,0x24,0x3d,0x25,0x25,0x25,0x3d,0x25,0x25,0x25,0x25,0x45,0x8d,0x28,0x24,0xfe,0x20,0x24,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x24,0x24,0x24,0xc,
-+0x8,0x7c,0x4b,0x4a,0x4a,0x7a,0x4a,0x4a,0x4b,0x7a,0x4a,0x4a,0x4a,0x5a,0x84,0x8,0x40,0x24,0xfe,0x40,0x44,0x44,0x84,0xfe,0x84,0xa4,0x94,0x94,0x84,0x84,0x94,0x88,
-+0x2,0x1,0x3f,0x22,0x22,0x22,0x24,0x27,0x2c,0x35,0x24,0x24,0x24,0x44,0x84,0x4,0x0,0x8,0xfc,0x0,0x10,0x10,0x14,0xfe,0x10,0x10,0x90,0x90,0x10,0x10,0x50,0x20,
-+0x1,0x0,0x3f,0x22,0x22,0x25,0x2c,0x34,0x24,0x2f,0x29,0x2a,0x48,0x49,0x8a,0x8,0x0,0x84,0xfe,0x10,0x14,0xfe,0x90,0x10,0xb4,0xfe,0x44,0xa4,0x84,0x44,0x34,0x8,
-+0x8,0x8,0xa,0x7f,0x8,0xa,0xff,0x8,0x28,0x2a,0x2f,0x28,0x28,0x58,0x88,0x7,0x40,0x40,0x40,0x40,0x40,0x60,0x50,0x4c,0x44,0x40,0x40,0x40,0x40,0x40,0x6,0xfc,
-+0x0,0xff,0x0,0x3f,0x20,0x20,0x3f,0x0,0x7f,0x44,0x44,0x7f,0x44,0x44,0x7f,0x40,0x44,0xe4,0x84,0xd4,0x94,0x94,0x94,0x54,0xf4,0x54,0x54,0xd4,0x44,0x44,0xd4,0x48,
-+0xff,0x4,0x3f,0x24,0x3f,0x12,0x23,0x4a,0x17,0x32,0x53,0x91,0x13,0x1d,0x10,0x17,0xfe,0x40,0xf8,0x48,0xf8,0x0,0xfc,0x0,0xf8,0x48,0xf8,0x0,0xf8,0x10,0xe2,0x1c,
-+0x4,0x7e,0x44,0x55,0x54,0x54,0x57,0x54,0x55,0x55,0x55,0x11,0x29,0x27,0x45,0x80,0x8,0x8,0x2c,0xfa,0x8,0x8,0xfe,0x48,0x48,0x78,0x48,0x48,0x78,0xca,0xa,0x4,
-+0x10,0x1f,0x20,0x2f,0x48,0x8f,0x8,0xf,0x4,0xf,0xc,0x12,0x21,0x42,0x4,0x38,0x8,0xfc,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x0,0xf0,0x20,0x40,0x80,0x40,0x30,0xe,
-+0x8,0x8,0xf,0x10,0x17,0x34,0x57,0x94,0x17,0x14,0x10,0x1f,0x12,0x11,0x10,0x10,0x50,0x48,0xfe,0x40,0xfc,0x44,0xfc,0x44,0xfc,0x44,0x10,0xfe,0x10,0x10,0x50,0x20,
-+0x8,0x8,0x8,0x10,0x10,0x37,0x50,0x90,0x11,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x90,0x90,0x10,0x10,0x10,0x50,0x20,
-+0x1,0x2,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x1f,0x11,0x1,0xff,0x1,0x1,0x1,0x0,0x10,0xf8,0x10,0xf0,0x0,0xf0,0x10,0x10,0xf0,0x0,0x4,0xfe,0x0,0x0,0x0,
-+0x4,0x8,0x10,0x20,0x40,0x8,0x4,0x4,0x2,0x2,0x1,0x2,0x4,0x8,0x30,0xc0,0x40,0x20,0x10,0xc,0x24,0x20,0x40,0x40,0x80,0x80,0x0,0x80,0x40,0x30,0xe,0x4,
-+0x9,0x7d,0x49,0x4b,0x4d,0x79,0x49,0x49,0x49,0x79,0x4a,0x4c,0x48,0x48,0x49,0x9e,0x4,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfc,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x4,0x4,0xf,0x10,0x20,0x5f,0x10,0x11,0x11,0x11,0x11,0x11,0x2,0x4,0x18,0x60,0x0,0x0,0xe0,0x40,0x90,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0xc0,0x30,0x18,0x8,
-+0x2,0x1,0x7f,0x40,0x9f,0x0,0x1f,0x10,0x1f,0x0,0x3f,0x21,0x3f,0x21,0x3f,0x20,0x0,0x0,0xfe,0x22,0xf4,0x0,0xf0,0x10,0xf0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,
-+0x0,0x20,0x18,0x8,0x0,0xf0,0x10,0x10,0x10,0x10,0x10,0x12,0x14,0x18,0x10,0x0,0x40,0x40,0x40,0x40,0x40,0x50,0x48,0x46,0x42,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x7c,0x44,0x49,0x49,0x53,0x4d,0x49,0x45,0x45,0x45,0x69,0x51,0x41,0x41,0x41,0x88,0x88,0x88,0x8,0x8,0xfe,0x8,0x8,0x48,0x28,0x28,0x8,0x8,0x8,0x28,0x10,
-+0x10,0x10,0x10,0x13,0xfc,0x24,0x24,0x24,0x25,0x48,0x28,0x10,0x28,0x47,0x84,0x0,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,0x0,
-+0x10,0x10,0x27,0x20,0x43,0xfa,0x13,0x22,0x43,0xfa,0x40,0x7,0x1a,0xe1,0x40,0x0,0x50,0x48,0xfc,0x40,0xf8,0x48,0xf8,0x48,0xf8,0x48,0x10,0xfe,0x10,0x10,0x10,0x20,
-+0x0,0x8,0x7c,0x49,0x49,0x4b,0x4d,0x49,0x49,0x49,0x49,0x79,0x49,0x1,0x1,0x1,0x88,0x88,0x88,0x8,0x8,0xfe,0x8,0x8,0x48,0x28,0x28,0x8,0x8,0x8,0x28,0x10,
-+0x1,0xf,0x79,0x4b,0x4a,0x4b,0x4a,0x4b,0x49,0x49,0x4a,0x7c,0x4a,0x2,0x3,0x0,0x10,0xfe,0x10,0xf8,0x8,0xf8,0x8,0xf8,0x4,0xfe,0x44,0x64,0x94,0x4,0xe4,0xc,
-+0x7,0x8,0x7f,0x4a,0x4b,0x4a,0x4b,0x4a,0x4b,0x49,0x49,0x7f,0x48,0x0,0x1,0xe,0xfc,0x80,0xf8,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x40,0x3e,0xc0,0xa0,0x42,0xb2,0xe,
-+0x1,0x40,0x2f,0x0,0x1,0x1,0xe2,0x27,0x20,0x20,0x20,0x25,0x2a,0x30,0x23,0xc,0x0,0x84,0xfe,0x80,0x0,0x10,0x10,0xe0,0x48,0x48,0x90,0x20,0x50,0x88,0x4,0x4,
-+0x0,0x4,0xfe,0x4,0x4,0x5,0x7e,0x44,0x40,0x40,0x40,0x40,0x4c,0x70,0x41,0x6,0x80,0x80,0x80,0x84,0xfe,0x8,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x10,0x10,0x17,0x14,0xfc,0x17,0x34,0x3c,0x57,0x54,0x95,0x15,0x16,0x14,0x10,0x10,0x0,0x84,0xfe,0x88,0x88,0xa8,0xa8,0xbe,0x88,0x10,0x18,0xa8,0xaa,0x4a,0x86,0x0,
-+0x10,0x13,0x10,0x1c,0x21,0x21,0x7d,0x91,0x11,0x7c,0x10,0x10,0x14,0x18,0x10,0x0,0x4,0xfe,0x20,0x28,0x3c,0x20,0x20,0x24,0xfe,0x4,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x8,0x4,0x7f,0x1,0x1,0x3f,0x1,0x1,0x7f,0x0,0x3f,0x24,0x24,0x24,0xff,0x0,0x20,0x48,0xfc,0x0,0x10,0xf8,0x0,0x8,0xfc,0x0,0xf8,0x48,0x48,0x48,0xfe,0x0,
-+0x41,0x2f,0x29,0x9,0x8f,0x49,0x49,0x1f,0x28,0x28,0xca,0x4b,0x4d,0x48,0x40,0x41,0x4,0xfe,0x10,0x10,0x50,0x50,0x54,0x7e,0x10,0x10,0x20,0x30,0x52,0x52,0x8e,0x0,
-+0x0,0x3f,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x10,0xf8,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x8,0x8,0x8,0x8,0xff,0x8,0x8,0x8,0x8,0xf,0x8,0x8,0x8,0x8,0xf,0x8,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0xe0,0x20,0x20,0x20,0x20,0xe0,0x20,
-+0x10,0x10,0x11,0x10,0xfc,0x10,0x30,0x3b,0x54,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x0,0x8,0xfc,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x11,0x11,0x11,0x11,0xff,0x11,0x39,0x35,0x51,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x8,0x8,0x8,0x8,0xfe,0x8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x12,0x1f,0x28,0x45,0x80,0x3f,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x40,0x44,0x7e,0xa0,0x10,0x0,0xf8,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x3d,0x24,0x24,0x24,0x3c,0x24,0x27,0x24,0x3c,0x24,0x24,0x24,0x44,0x94,0x8,0x8,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x8,0x8,0x9,0x7e,0x8,0x8,0xfe,0x9,0x28,0x28,0x2e,0x28,0x28,0x38,0x48,0x87,0x0,0x8,0xfc,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x6,0xfc,
-+0x0,0x0,0x7f,0x40,0x7f,0x40,0x5f,0x51,0x51,0x5f,0x90,0x2,0x29,0x28,0x48,0x7,0x50,0x48,0xfc,0x40,0xc0,0x48,0x48,0x50,0x22,0x52,0x8e,0x0,0x90,0xac,0x24,0xe0,
-+0x8,0x1d,0xf0,0x10,0x10,0xfc,0x10,0x3b,0x34,0x50,0x50,0x90,0x10,0x10,0x10,0x10,0x8,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x0,0x7c,0x4,0x8,0xff,0x24,0x24,0x3c,0x24,0x3c,0x24,0x24,0xfe,0x4,0x5,0x6,0x40,0x40,0x40,0x84,0xfe,0x8,0x88,0x88,0x50,0x50,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x10,0xfe,0x44,0x29,0xfe,0x1,0x7c,0x44,0x7d,0x44,0x7c,0x10,0xfe,0x10,0x10,0x11,0x40,0x78,0xd0,0x20,0x58,0x86,0xf8,0x20,0xfc,0x0,0xf8,0x88,0xa8,0xa8,0x58,0x84,
-+0x0,0x7f,0x40,0x40,0x48,0x44,0x42,0x41,0x42,0x44,0x48,0x50,0x40,0x40,0x40,0x40,0x4,0xfe,0x4,0x4,0x24,0x64,0x84,0x4,0x84,0x64,0x34,0x14,0x4,0x4,0x14,0x8,
-+0x1,0x7f,0x41,0x41,0x63,0x63,0x55,0x55,0x49,0x55,0x53,0x63,0x41,0x41,0x45,0x42,0x4,0x84,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x4,0x4,0x14,0x8,
-+0x10,0x13,0x12,0x1e,0x23,0x22,0x7e,0x92,0x12,0x7e,0x12,0x13,0x16,0x1a,0x12,0x2,0x4,0xfe,0x4,0x4,0xc,0x8c,0x54,0x24,0x24,0x54,0x8c,0xc,0x4,0x4,0x14,0x8,
-+0x20,0x22,0x3f,0x48,0x48,0x88,0x9,0xff,0x8,0x2a,0x2a,0x2a,0x2a,0x3e,0x23,0x2,0x0,0x0,0x8,0xfc,0x20,0x20,0x20,0xa0,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x4,0x3e,0x25,0x24,0x24,0x3c,0x24,0x24,0x24,0x3c,0x24,0x24,0x24,0x27,0x44,0x8c,0x0,0x8,0xfc,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,0x0,
-+0x20,0x23,0x22,0x4a,0x4b,0xf2,0x12,0x22,0x42,0xfa,0x42,0x3,0x1a,0xe2,0x42,0x2,0x4,0xfe,0x4,0x4,0xc,0x8c,0x54,0x24,0x24,0x54,0x8c,0xc,0x4,0x4,0x14,0x8,
-+0x1,0x41,0x41,0x7f,0x0,0x7f,0x40,0x48,0x44,0x42,0x41,0x42,0x44,0x48,0x50,0x40,0x0,0x4,0x4,0xfc,0x4,0xfe,0x4,0x24,0x44,0x84,0x4,0x84,0x44,0x34,0x14,0x8,
-+0x41,0x31,0x17,0x81,0x61,0x2f,0x1,0x12,0x27,0xea,0x22,0x23,0x22,0x22,0x21,0x20,0x10,0x10,0xfc,0x10,0x14,0xfe,0x20,0x10,0xfe,0x14,0x10,0xf0,0x4,0x4,0xfc,0x0,
-+0x10,0x10,0x10,0x11,0xfc,0x10,0x30,0x38,0x54,0x50,0x90,0x10,0x10,0x13,0x10,0x10,0x0,0x0,0x8,0xfc,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,0x0,
-+0x20,0x3e,0x50,0x81,0x7f,0x0,0x1f,0x10,0x1f,0x0,0x7f,0x40,0x4f,0x48,0x4f,0x40,0x40,0x7c,0x90,0x0,0xfc,0x0,0xf0,0x10,0xf0,0x4,0xfe,0x4,0xe4,0x24,0xe4,0xc,
-+0x2,0x4,0x1f,0x10,0x1f,0x10,0x1f,0x2,0xff,0x4,0x9,0x11,0x2f,0xc1,0x1,0x1,0x0,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x40,0x20,0x50,0xee,0x4,0x0,0x0,
-+0x2,0x1,0xff,0x0,0x1f,0x10,0x10,0x1f,0x0,0x7f,0x40,0x4f,0x48,0x48,0x4f,0x40,0x0,0x4,0xfe,0x0,0xf0,0x10,0x10,0xf0,0x4,0xfe,0x4,0xe4,0x24,0x24,0xe4,0xc,
-+0x1,0x7f,0x8,0xf,0x0,0x7f,0x48,0x8f,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x8,0xfc,0x20,0xe0,0x0,0xfe,0x22,0xe4,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x10,0x30,
-+0x10,0xc,0x4,0x7f,0x1,0x1,0x1,0x3f,0x1,0x1,0x1,0xff,0x20,0x24,0x22,0x40,0x10,0x30,0x40,0xfc,0x0,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x10,0x88,0x44,0x4,
-+0x11,0x10,0x92,0x55,0x38,0x10,0xfe,0x11,0x38,0x34,0x54,0x53,0x90,0x12,0x12,0x14,0x4,0x88,0x50,0xfc,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,0xa4,0x92,0x2,
-+0x10,0x10,0x1f,0x10,0xfb,0x12,0x12,0x1b,0x30,0xd7,0x14,0x15,0x15,0x15,0x54,0x24,0x80,0x44,0xfe,0x0,0xf8,0x8,0x8,0xf8,0x4,0xfe,0x4,0xf4,0x14,0xf4,0x4,0xc,
-+0x10,0x10,0x1f,0x20,0x21,0x7d,0x91,0x11,0x7c,0x13,0x12,0x12,0x16,0x1a,0x12,0x2,0x40,0x24,0xfe,0x0,0xf8,0x8,0x8,0xf8,0x4,0xfe,0x4,0xf4,0x94,0xf4,0x4,0xc,
-+0x8,0x1c,0xf3,0x10,0x11,0xfd,0x11,0x39,0x34,0x53,0x52,0x92,0x12,0x12,0x12,0x12,0x40,0x24,0xfe,0x0,0xf8,0x8,0x8,0xf8,0x4,0xfe,0x4,0xf4,0x94,0xf4,0x4,0xc,
-+0x1,0x11,0x11,0x1f,0x11,0x21,0x1,0xff,0x0,0x1f,0x10,0x10,0x10,0x10,0x1f,0x10,0x0,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x10,0xf8,0x10,0x10,0x10,0x10,0xf0,0x10,
-+0x7f,0x0,0x1f,0x10,0x10,0x1f,0x0,0xff,0x0,0x1f,0x10,0x10,0x1f,0x10,0x0,0x0,0xfc,0x10,0x90,0x90,0x90,0x90,0x14,0xfe,0x10,0x90,0x90,0x90,0x90,0x10,0x50,0x20,
-+0x2,0xff,0x2,0x7a,0x4a,0x4a,0x7b,0x2,0xff,0x2,0x7a,0x4a,0x4a,0x7a,0x4a,0x5,0x20,0x20,0x20,0x40,0x7c,0x84,0x28,0x20,0x20,0x20,0x20,0x20,0x50,0x50,0x8e,0x4,
-+0x10,0x14,0x12,0x10,0xfc,0x15,0x16,0x1c,0x34,0xd7,0x15,0x15,0x15,0x15,0x55,0x24,0x0,0x4,0xfe,0x44,0xf4,0x14,0xa4,0x44,0xa4,0x1c,0xf4,0x14,0x14,0xf4,0x14,0x8,
-+0x4,0x4,0x4,0x4,0x4,0xff,0x4,0x4,0x4,0x2,0x2,0x1,0x2,0xc,0x70,0x0,0x0,0x80,0x40,0x4,0xfe,0x0,0x0,0x20,0x30,0x40,0x80,0x0,0x80,0x44,0x34,0xc,
-+0x10,0x10,0x29,0x29,0x25,0x43,0x89,0x7d,0x1,0x7d,0x44,0x44,0x47,0x44,0x7c,0x40,0x20,0x48,0xfc,0x8,0x48,0x28,0x28,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x4,0x3e,0x24,0x24,0x24,0x3d,0x26,0x24,0x24,0x3d,0x26,0x24,0x24,0x44,0x94,0x8,0x40,0x40,0x7c,0x84,0x88,0x50,0x20,0x50,0x8e,0x4,0xf8,0x88,0x88,0x88,0xf8,0x88,
-+0x1,0x0,0x1f,0x12,0x92,0x53,0x54,0x18,0x37,0x50,0xd0,0x13,0x24,0x24,0x44,0x3,0x0,0x84,0xfe,0x0,0x10,0xf8,0x0,0x0,0xf0,0x20,0xc0,0x0,0x0,0x2,0x2,0xfe,
-+0x8,0x4,0x7f,0x44,0xbf,0x4,0x3f,0x4,0x7f,0x0,0x3f,0x20,0x20,0x20,0x3f,0x20,0x4,0x4,0xe4,0x54,0x94,0x14,0x94,0x14,0xd4,0x94,0xd4,0x94,0x84,0x84,0x94,0x88,
-+0x8,0x8,0x7f,0x8,0xf,0x1,0x3f,0x21,0x21,0x3f,0x1,0xff,0x1,0x1,0x1,0x1,0x20,0x28,0xfc,0x20,0xe0,0x8,0xfc,0x8,0x8,0xf8,0x4,0xfe,0x0,0x0,0x0,0x0,
-+0x4,0xff,0x4,0x1f,0x10,0x1f,0x10,0x1f,0x4,0xf,0x11,0x22,0x54,0x10,0x1f,0x0,0x44,0xfe,0x40,0xf0,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x4,0x84,0x44,0x4,0xd4,0x8,
-+0x11,0x11,0x11,0x12,0xff,0x14,0x38,0x34,0x51,0x52,0x97,0x1a,0x12,0x12,0x13,0x12,0x0,0x0,0xf8,0x8,0x10,0xa0,0x40,0xa0,0x10,0xe,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x14,0x7e,0x55,0x56,0x55,0x54,0x7c,0x51,0x11,0x15,0x1d,0xe5,0x41,0x1,0x20,0x20,0x50,0x88,0x6,0x4,0xfc,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x20,0x1b,0x4a,0x42,0x47,0x4c,0x52,0x41,0x46,0x58,0x60,0x4f,0x48,0x48,0x4f,0x40,0x4,0xfe,0x4,0x4,0xe4,0x44,0x84,0x4,0xc4,0x3c,0x14,0xe4,0x24,0x24,0xf4,0x8,
-+0x0,0x7f,0x48,0x53,0x52,0x62,0x53,0x48,0x4f,0x4d,0x6c,0x57,0x44,0x44,0x44,0x44,0x8,0xfc,0x0,0xf8,0x8,0x8,0xf8,0x4,0xfe,0x14,0xa4,0xfc,0x44,0x44,0x54,0x8,
-+0x10,0x10,0x1c,0x11,0x21,0x3e,0x50,0x90,0x7c,0x13,0x11,0x11,0x15,0x19,0x11,0x1,0x80,0x80,0xfc,0x4,0x88,0x50,0x20,0x50,0x8e,0x4,0xfe,0x4,0x4,0x4,0xfc,0x4,
-+0x1,0x1,0x2,0x4,0x8,0x11,0x21,0xc1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x80,0x40,0x20,0x10,0xe,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x4,0x4,0x7,0x8,0x14,0x22,0x1,0x6,0x18,0xe0,0xf,0x8,0x8,0x8,0xf,0x8,0x0,0x0,0xf0,0x10,0x20,0x40,0x80,0x60,0x1e,0x4,0xf0,0x10,0x10,0x10,0xf0,0x10,
-+0x10,0x10,0x20,0x20,0x49,0xfa,0x14,0x23,0x40,0xf8,0x43,0x2,0x1a,0xe2,0x43,0x2,0x40,0x40,0xa0,0xa0,0x10,0xe,0x4,0xf8,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x11,0x11,0x11,0xfd,0x11,0x39,0x35,0x55,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x44,0x48,0x30,0x20,0x10,0x4e,0x84,0x0,
-+0x0,0x7d,0x45,0x45,0x45,0x45,0x7d,0x11,0x51,0x5d,0x51,0x51,0x51,0x5d,0xe1,0x41,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x44,0x48,0x30,0x20,0x10,0x4e,0x84,0x0,
-+0x10,0x10,0x14,0xfe,0x11,0x7c,0x10,0xfe,0x13,0x38,0x34,0x54,0x51,0x91,0x12,0x10,0x88,0x88,0x88,0x88,0xfc,0x88,0x88,0x88,0xfe,0x88,0x88,0x88,0x8,0x8,0x8,0x8,
-+0x0,0xff,0x1,0x3f,0x21,0x21,0x3f,0x21,0x21,0x3f,0x29,0x5,0x2,0x5,0x18,0xe0,0x4,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x0,0x0,0x80,0x70,0xe,
-+0x1,0x0,0x3f,0x20,0x20,0x2f,0x20,0x3f,0x20,0x2f,0x20,0x21,0x41,0x42,0x84,0x18,0x0,0x84,0xfe,0x80,0x88,0xfc,0x88,0xfe,0x88,0xf8,0x88,0x40,0x40,0x30,0xe,0x4,
-+0x4,0x7f,0x1,0x3f,0x1,0xff,0x28,0x42,0x3f,0x1,0x1f,0x1,0xff,0x2,0xc,0x30,0x48,0xfc,0x0,0xf8,0x0,0xfe,0x28,0x84,0xf8,0x0,0xf0,0x4,0xfe,0x80,0x78,0x10,
-+0x20,0x2f,0x20,0x27,0xfc,0x24,0x27,0x24,0x24,0x27,0x3c,0xe3,0x40,0x1,0x6,0x18,0x4,0xfe,0x40,0xfc,0x44,0x44,0xfc,0x44,0x44,0xfc,0x44,0x40,0x80,0x60,0x1e,0x4,
-+0x2,0xff,0x24,0x24,0x3c,0x24,0x24,0x3d,0x24,0x24,0x24,0x3e,0xe4,0x44,0x7,0x4,0x20,0x20,0x20,0x20,0xa4,0xac,0xb0,0x20,0x20,0x20,0x20,0x50,0x50,0x8e,0x4,0x0,
-+0x10,0x1f,0x10,0x13,0xfe,0x12,0x33,0x3a,0x52,0x53,0x92,0x11,0x10,0x11,0x12,0x1c,0x4,0xfe,0x48,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x48,0x40,0x80,0x60,0x1e,0x4,
-+0x0,0x0,0x7f,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,
-+0x0,0x0,0x8,0xfd,0x11,0x12,0x14,0x11,0x11,0x11,0x10,0x1c,0xf0,0x41,0x2,0xc,0x80,0x80,0x80,0x8,0xfc,0x10,0x10,0x10,0x20,0x20,0xc0,0x40,0xa0,0x10,0xe,0x4,
-+0x0,0x0,0x8,0xfc,0x10,0x17,0x10,0x10,0x10,0x10,0x1d,0xf1,0x41,0x2,0x4,0x8,0x80,0x80,0x80,0x80,0x84,0xfe,0x84,0x84,0x84,0x84,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x8,0x8,0x7f,0x8,0x8,0xff,0x4,0x9,0x11,0x21,0xc9,0x9,0x11,0x21,0x5,0x2,0x20,0x28,0xfc,0x20,0x24,0xfe,0x40,0x20,0x10,0xe,0x24,0x90,0x48,0x8,0x0,0x0,
-+0x2,0x2,0xff,0x5,0x5,0x9,0x32,0xc8,0x8,0x3f,0x8,0x8,0xff,0x8,0x18,0x20,0x20,0x14,0xfe,0x0,0x64,0x84,0xfc,0x20,0x20,0xf8,0x20,0x24,0xfe,0x20,0x18,0x8,
-+0x12,0x12,0x12,0x22,0x2f,0x62,0xa2,0x22,0x22,0x3f,0x20,0x22,0x22,0x24,0x28,0x20,0x10,0x10,0x10,0x10,0xfc,0x10,0x10,0x10,0x14,0xfe,0x0,0x10,0x8,0xc,0x4,0x0,
-+0x8,0x12,0x3f,0x22,0x3e,0x22,0x3e,0x22,0x22,0xfe,0x6,0xa,0x12,0x22,0x4a,0x4,0x0,0x4,0xfe,0x4,0x4,0xfc,0x80,0x84,0xfe,0x4,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x0,0x0,0x4,0x4,0x8,0x8,0x11,0x21,0xc2,0x2,0x4,0x8,0x10,0x1f,0x0,0x0,0x0,0x80,0x80,0x40,0x40,0x20,0x10,0xe,0x4,0x0,0x0,0x40,0x20,0xf0,0x10,0x0,
-+0x2,0x1,0x7f,0x40,0x80,0xf,0x8,0x8,0xf,0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x0,0x0,0xfe,0x2,0x24,0xf0,0x20,0x20,0xe0,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,
-+0x0,0x7f,0x0,0x0,0x0,0x3f,0x20,0x20,0x40,0x7f,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0xf0,0x20,0x20,0x20,0xe0,0x20,0x0,0x8,0xfc,0x8,0x8,0x8,0x90,0x50,0x20,
-+0x0,0x9,0xfd,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x1d,0xf1,0x42,0x2,0x4,0x8,0x8,0xfc,0x8,0x8,0x8,0x8,0x48,0x28,0x28,0x8,0x8,0x8,0xa,0xa,0x6,0x0,
-+0x0,0x3f,0x1,0x1,0xff,0x0,0x1,0x1,0x7d,0x5,0x9,0x11,0x21,0xc1,0x5,0x2,0x10,0xf8,0x0,0x4,0xfe,0x0,0x8,0x18,0xa0,0x40,0x20,0x10,0xe,0x4,0x0,0x0,
-+0x11,0x11,0x11,0x11,0xfb,0x11,0x11,0x19,0x31,0xdf,0x10,0x11,0x11,0x12,0x54,0x20,0x10,0x10,0x10,0x10,0xfc,0x10,0x10,0x10,0x14,0xfe,0x0,0x10,0x8,0xc,0x4,0x0,
-+0x0,0x3f,0x1,0x1,0xff,0x0,0x1f,0x10,0x11,0x11,0x11,0x11,0x11,0x2,0xc,0x30,0x10,0xf8,0x0,0x4,0xfe,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0xc0,0x30,0x8,
-+0x8,0x8,0x8,0x8,0x7f,0x8,0x8,0x8,0x8,0x8,0xff,0x0,0x4,0xc,0x10,0x20,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,0x40,0x30,0x18,0x8,
-+0x10,0x10,0x10,0x1c,0x21,0x22,0x7c,0x90,0x10,0x7c,0x11,0x10,0x14,0x18,0x10,0x0,0x80,0x80,0x84,0xfe,0x4,0x4,0x44,0x44,0x84,0xa4,0xf4,0x14,0x4,0x4,0x28,0x10,
-+0x8,0x8,0x8,0xf,0x10,0x22,0x42,0x84,0x4,0x8,0x10,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0x84,0x44,0xc4,0x44,0x4,0x28,0x10,
-+0x2,0x42,0x32,0x13,0x84,0x68,0x20,0x1,0x9,0x12,0xe4,0x27,0x20,0x20,0x20,0x20,0x0,0x0,0x4,0xfe,0x4,0x84,0x84,0x4,0x4,0x44,0x24,0xe4,0x24,0x4,0x28,0x10,
-+0x8,0x8,0xff,0x8,0x10,0x1f,0x20,0x20,0x5f,0x90,0x10,0x10,0x1f,0x10,0x0,0x0,0x20,0x24,0xfe,0x20,0x8,0xfc,0x8,0x88,0xc8,0x88,0x88,0x88,0x88,0x8,0x50,0x20,
-+0x4,0x44,0x28,0x11,0x29,0x4a,0x8,0x9,0x19,0x29,0x49,0x89,0x9,0x8,0x50,0x20,0x80,0x80,0x84,0xfe,0x4,0x4,0x24,0xf4,0x24,0x24,0x24,0xe4,0x4,0x4,0x28,0x10,
-+0x10,0x13,0x12,0x12,0xfe,0x13,0x12,0x12,0x12,0x12,0x16,0x1a,0xe4,0x44,0x8,0x0,0xc,0xf0,0x0,0x0,0x4,0xfe,0x0,0x4,0xfe,0x84,0x84,0x84,0x84,0x84,0xfc,0x84,
-+0x10,0x10,0x10,0x10,0xfd,0x12,0x30,0x38,0x54,0x50,0x11,0x11,0x10,0x10,0x10,0x10,0x80,0x80,0x84,0xfe,0x4,0x4,0x44,0x44,0x84,0xa4,0x14,0xf4,0x14,0x4,0x28,0x10,
-+0x4,0x7e,0x44,0x54,0x55,0x56,0x54,0x54,0x54,0x54,0x55,0x55,0x10,0x28,0x44,0x84,0x80,0x80,0x84,0xfe,0x4,0x4,0x44,0x44,0x84,0xa4,0x14,0xf4,0x14,0x4,0x28,0x10,
-+0x20,0x20,0x22,0x3f,0x42,0x83,0x7a,0x4a,0x4a,0x4b,0x4a,0x7a,0x42,0xa,0x4,0x0,0x20,0x20,0x7c,0x44,0x88,0x50,0x20,0x50,0x9e,0x22,0x44,0xa8,0x10,0x20,0x40,0x80,
-+0x1,0xff,0x1,0x3f,0x20,0x3f,0x1,0x3f,0x8,0x4,0xff,0x1,0x3f,0x1,0x1,0x1,0x4,0xfe,0x0,0xf8,0x8,0xf8,0x0,0xf8,0x20,0x44,0xfe,0x0,0xf8,0x0,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x10,0x10,0xff,0x12,0x12,0x22,0x22,0x14,0x8,0x14,0x22,0x40,0x40,0x44,0xfe,0x40,0x20,0x24,0xfe,0x20,0x24,0xfe,0x84,0x84,0x84,0x84,0xfc,0x84,
-+0x0,0x8,0x7c,0x48,0x4f,0x48,0x48,0x48,0x4b,0x4a,0x4a,0x7a,0x4a,0x2,0x3,0x2,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x48,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x1f,0x28,0x45,0x90,0x13,0x12,0xfe,0x12,0x1a,0x32,0xd2,0x12,0x12,0x53,0x20,0x40,0x7e,0xa0,0x10,0x0,0xfc,0x20,0x28,0xfc,0xa8,0xa8,0xa8,0xb8,0x20,0xfe,0x0,
-+0x8,0x8,0x8,0x10,0x1f,0x30,0x50,0x90,0x13,0x12,0x12,0x12,0x12,0x12,0x13,0x12,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x48,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x40,0x30,0x10,0x87,0x60,0x20,0x8,0x13,0x22,0xe2,0x22,0x22,0x22,0x23,0x22,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x48,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x7c,0x7,0xa,0x12,0x12,0x16,0x1a,0x32,0xd2,0x12,0x12,0x14,0x15,0x58,0x20,0x8,0x3c,0xc0,0x10,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0xa8,0xee,0x24,0x0,
-+0x10,0x10,0x10,0x10,0x13,0xfc,0x24,0x24,0x45,0x25,0x19,0x11,0x29,0x45,0x81,0x1,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x24,0xfe,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x14,0xfe,0x11,0x7c,0x0,0x7d,0x44,0x44,0x7c,0x0,0x44,0x28,0xfe,0x40,0x3,0x20,0x20,0x24,0xfe,0x20,0x28,0xfc,0x88,0x88,0x88,0x50,0x20,0x50,0x48,0x8e,0x4,
-+0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1f,0x10,0x10,0x10,0x10,0x10,0x1f,0x10,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0xf0,0x10,
-+0x1,0x1,0x1f,0x11,0x11,0x1f,0x11,0x1,0x3f,0x0,0x3f,0x24,0x24,0x24,0xff,0x0,0x0,0x10,0xf8,0x10,0x10,0xf0,0x0,0x8,0xfc,0x4,0xf8,0x48,0x48,0x48,0xfe,0x0,
-+0x1f,0x10,0x1f,0x11,0x11,0x7f,0x40,0x9f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x10,0x10,0xf0,0x10,0x10,0x10,0x10,0xfe,0x2,0xf4,0x10,0xf0,0x10,0xf0,0x10,0x10,0x50,0x20,
-+0x8,0x8,0x10,0x21,0x41,0x2,0x4,0x8,0x30,0xc0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x40,0x30,0x18,0x8,0x0,0x80,0x40,0x30,0xe,0x4,0xf0,0x10,0x10,0x10,0xf0,0x10,
-+0x4,0x3e,0x24,0x24,0x24,0x3d,0x26,0x25,0x24,0x3c,0x24,0x24,0x24,0x24,0x4d,0x86,0x8,0xfc,0x88,0x88,0x88,0xe,0x0,0xfc,0x84,0x88,0x48,0x70,0x20,0x50,0x8e,0x4,
-+0x10,0x10,0x10,0x14,0xfe,0x11,0x12,0x10,0x7c,0x44,0x44,0x44,0x44,0x7c,0x44,0x3,0x40,0x40,0x40,0x44,0xfe,0x8,0x88,0x88,0x88,0x88,0x50,0x20,0x20,0x50,0x8e,0x4,
-+0x4,0x7f,0x40,0x40,0x5e,0x52,0x52,0x52,0x5a,0x54,0x50,0x52,0x54,0x58,0x80,0x1,0x4,0xfe,0x20,0x44,0xfe,0x84,0x94,0x94,0x94,0xa4,0xa4,0xa4,0x30,0x4c,0x86,0x2,
-+0x0,0x7f,0x41,0x41,0x5f,0x41,0x41,0x4f,0x48,0x48,0x48,0x4f,0x48,0x40,0x7f,0x40,0x4,0xfe,0x4,0x24,0xf4,0x4,0x24,0xf4,0x24,0x24,0x24,0xe4,0x24,0x4,0xfc,0x4,
-+0x2,0x1,0x3f,0x20,0x3f,0x22,0x22,0x27,0x24,0x2f,0x34,0x27,0x24,0x24,0x47,0x84,0x0,0x4,0xfe,0x4,0xfc,0x80,0x48,0xfc,0x40,0xf8,0x40,0xf8,0x40,0x48,0xfc,0x0,
-+0x1,0x7e,0x8,0x8,0x9,0xff,0x8,0x8,0x9,0x7f,0x41,0x41,0x41,0x41,0x7f,0x41,0x84,0x4,0x4,0x24,0x24,0xa4,0x24,0x24,0x24,0xa4,0x24,0x24,0x4,0x4,0x14,0x8,
-+0x0,0x1,0x3e,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x42,0x83,0x0,0x38,0xc0,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x10,0x88,0x68,0xa6,0x4,0x0,
-+0x0,0x3f,0x20,0x20,0x20,0x3f,0x24,0x4,0x7f,0x44,0x44,0x4a,0x51,0x40,0x41,0x40,0x84,0xc4,0x84,0x94,0x94,0x94,0x94,0x14,0xd4,0x54,0x54,0x54,0x44,0x44,0x54,0x88,
-+0x1,0x7f,0x40,0x9f,0x2,0xf,0xa,0x9,0x8,0x7f,0x4,0xf,0x32,0xc2,0x4,0x18,0x0,0xfe,0x22,0xf4,0x0,0xe0,0x20,0x20,0xa8,0xfc,0x40,0xe0,0x5e,0x44,0x40,0xc0,
-+0x10,0x10,0x10,0x17,0xfc,0x10,0x14,0x1f,0x30,0xd0,0x17,0x10,0x10,0x10,0x5f,0x20,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x0,
-+0x41,0x21,0x21,0x7,0xf1,0x11,0x2f,0x71,0xa1,0x37,0x21,0x21,0x21,0x2f,0x24,0x20,0x10,0x10,0x10,0xd0,0x10,0x10,0xf8,0x16,0x12,0xd0,0x10,0x10,0xf0,0x10,0x10,0x10,
-+0x0,0x1f,0x1,0x1,0xff,0x1,0x9,0x9,0x79,0x9,0x9,0x39,0xc9,0x1,0x1,0x1,0x70,0x80,0x0,0x4,0xfe,0x0,0x24,0x2c,0x30,0x20,0x22,0x22,0x1e,0x0,0x0,0x0,
-+0x10,0x11,0x11,0xfd,0x11,0x15,0x18,0x30,0xd3,0x10,0x10,0x10,0x11,0x11,0x52,0x24,0x8,0xfc,0x8,0x8,0x8,0xf8,0x80,0x84,0xfe,0x84,0x84,0x84,0x4,0x4,0x14,0x8,
-+0x10,0x17,0x12,0x11,0x58,0x54,0x50,0x93,0x1c,0x10,0x17,0x10,0x10,0x10,0x1f,0x10,0x8,0xfc,0x8,0x10,0xa0,0x40,0xb0,0xe,0x44,0x40,0xfc,0x40,0x40,0x44,0xfe,0x0,
-+0x10,0x10,0x13,0x12,0xfc,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x40,0x20,0xfe,0x2,0x4,0xfc,0x4,0x4,0xfc,0x0,0xfc,0x4,0x4,0x4,0xfc,0x0,
-+0x10,0x8,0x4,0x4,0x7f,0x1,0x1,0x1,0xff,0x1,0x2,0x2,0x4,0x8,0x30,0xc0,0x10,0x18,0x20,0x48,0xfc,0x0,0x0,0x4,0xfe,0x0,0x80,0x80,0x40,0x30,0xe,0x4,
-+0x2,0x1,0x7f,0x40,0x80,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x0,0x0,0xfe,0x2,0x14,0xf8,0x10,0x10,0xf0,0x0,0x10,0xf8,0x10,0x10,0xf0,0x0,
-+0x0,0x7f,0x40,0x84,0x3e,0x0,0x2,0x7f,0x14,0x14,0x14,0x14,0x24,0x24,0x43,0x80,0x0,0xfe,0x2,0xc,0x8,0x8,0xfe,0x8,0x48,0x28,0x8,0x28,0x12,0x2,0xfe,0x0,
-+0x0,0x1,0x7d,0x5,0x45,0x29,0x29,0x11,0x11,0x29,0x25,0x44,0x80,0x1,0x6,0x18,0x8,0xfc,0x8,0x28,0x28,0x28,0x28,0x48,0x48,0x48,0x68,0xa0,0xa0,0x22,0x22,0x1e,
-+0x10,0x1f,0x28,0x45,0x1,0x7f,0x40,0x9f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x1f,0x10,0x40,0x7c,0x90,0x8,0x0,0xfe,0x2,0xf4,0x10,0xf0,0x0,0xf0,0x10,0x10,0xf0,0x0,
-+0x20,0x20,0x23,0x3a,0x4c,0x51,0x81,0x21,0x21,0x21,0x21,0x25,0x29,0x31,0x21,0x1,0x80,0x40,0xfe,0x2,0x4,0xf8,0x8,0x8,0xf8,0x0,0xf8,0x8,0x8,0x8,0xf8,0x0,
-+0x20,0x23,0x3c,0x51,0x91,0x11,0xfe,0x10,0x55,0x56,0x54,0x54,0x54,0x7c,0x44,0x0,0x88,0xfe,0x88,0xdc,0x54,0xdc,0x90,0xfc,0x90,0xfc,0x90,0xfc,0x90,0x94,0xfe,0x80,
-+0x10,0x13,0x12,0x1f,0x5a,0x57,0x50,0x93,0x12,0x12,0x12,0x12,0x12,0x10,0x11,0x16,0x8,0xfc,0x48,0xfe,0x48,0xf8,0x0,0xf8,0x8,0x48,0x48,0x48,0x48,0xb0,0xc,0x4,
-+0x1,0x4f,0x31,0x17,0x84,0x67,0x22,0x3,0x16,0x2b,0xc2,0x43,0x42,0x42,0x43,0x42,0x10,0xfe,0x10,0xbc,0xa4,0xbc,0x20,0xfc,0x20,0xfc,0x20,0xfc,0x20,0x24,0xfe,0x0,
-+0x0,0x1f,0x11,0x11,0xff,0x11,0x1f,0x0,0x1f,0x10,0x11,0x11,0x11,0x2,0xc,0x30,0x10,0xf8,0x10,0x14,0xfe,0x10,0xf0,0x0,0xf0,0x10,0x10,0x10,0x10,0x60,0x18,0x8,
-+0x1,0x21,0x11,0x9,0x9,0x1,0xff,0x4,0x4,0x4,0x4,0x8,0x8,0x10,0x20,0x40,0x0,0x8,0xc,0x10,0x20,0x4,0xfe,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x1,0x0,0x3f,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80,0x0,0x0,0x84,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x40,0x29,0x27,0x2,0x6,0xea,0x22,0x26,0x2a,0x32,0x22,0x2b,0x24,0x50,0x8f,0x0,0x0,0x8,0xfc,0x20,0x20,0x20,0xf8,0x20,0x20,0x20,0x28,0xfc,0x0,0x6,0xfc,0x0,
-+0x0,0x11,0xfb,0x22,0x22,0x23,0xfa,0x22,0x23,0x22,0x20,0x39,0xe1,0x42,0x4,0x8,0x80,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x80,0xd0,0x68,0x78,0x42,0x42,0x3e,
-+0x10,0x10,0x11,0x11,0x7d,0x11,0x15,0xff,0x11,0x11,0x10,0x28,0x24,0x41,0x82,0x4,0x0,0x8,0xfc,0x28,0x28,0x28,0x28,0x48,0x48,0x48,0x40,0x90,0x90,0x12,0x12,0xe,
-+0x1,0x1,0x1,0x7f,0x1,0x1,0xff,0x1,0x1,0x1,0x7f,0x1,0x1,0x1,0xff,0x0,0x0,0x0,0x8,0xfc,0x0,0x4,0xfe,0x0,0x0,0x8,0xfc,0x0,0x0,0x4,0xfe,0x0,
-+0x0,0x4,0xfe,0x11,0x10,0x20,0x23,0x7c,0xa4,0x24,0x25,0x24,0x24,0x3c,0x27,0x0,0x20,0x20,0x28,0xfc,0x20,0x24,0xfe,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x4,0x4,0x25,0x24,0x24,0x24,0x24,0x25,0x24,0x24,0x24,0x4,0x8,0x13,0x60,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,0x0,
-+0x8,0x8,0x1f,0x10,0x20,0x7f,0xa1,0x21,0x3f,0x21,0x21,0x3f,0x21,0x1,0x1,0x0,0x0,0x0,0xe0,0x40,0x88,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0xa,0x2,0x2,0xfe,
-+0x20,0x1b,0x49,0x41,0x4f,0x41,0x41,0x5f,0x41,0x41,0x4f,0x41,0x41,0x5f,0x40,0x40,0x4,0xfe,0x4,0x44,0xe4,0x4,0x24,0xf4,0x4,0x44,0xe4,0x4,0x24,0xf4,0x4,0xc,
-+0x10,0x10,0x14,0xfe,0x21,0x28,0x48,0x7e,0x8,0x8,0x8,0xfe,0x8,0x8,0x9,0xa,0x40,0x40,0x40,0x48,0xfc,0x48,0x48,0x48,0x48,0x48,0x48,0x88,0x8a,0x8a,0x6,0x0,
-+0x2,0x4,0x3f,0x21,0x21,0x3f,0x21,0x21,0x3f,0x22,0x2,0x4,0x4,0x8,0x10,0x60,0x0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x88,0x80,0x90,0xa8,0xba,0x82,0x7e,
-+0x1,0x41,0x21,0x22,0x4,0xb,0xe2,0x22,0x22,0x22,0x22,0x26,0x2a,0x32,0x24,0x8,0x0,0x0,0xf0,0x20,0x44,0xfe,0x0,0xf8,0x88,0x88,0xa8,0x90,0x82,0x82,0x7e,0x0,
-+0x0,0x3e,0x2,0x24,0x18,0x10,0x20,0x4f,0x81,0x1,0x3f,0x1,0x2,0x4,0x18,0x60,0x80,0x90,0xa0,0x48,0x50,0x20,0x10,0xee,0x4,0x10,0xf8,0x0,0xc0,0x30,0x18,0x8,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x37,0x38,0x54,0x50,0x93,0x10,0x10,0x10,0x1f,0x10,0x40,0x40,0x48,0xfc,0x40,0x44,0xfe,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x0,
-+0x10,0x13,0x12,0x12,0xfe,0x13,0x32,0x3a,0x56,0x53,0x92,0x12,0x12,0x12,0x13,0x10,0x8,0xfc,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x4,0xfe,0x0,
-+0x4,0x7e,0x44,0x45,0x46,0x7d,0x51,0x11,0x51,0x5d,0x51,0x51,0x5d,0xf2,0x44,0x8,0x80,0x80,0xf8,0x10,0x24,0xfe,0x8,0x7c,0x48,0x48,0x68,0x50,0x42,0x42,0x3e,0x0,
-+0x1,0x1,0x3f,0x21,0x3f,0x1,0xff,0x0,0x1f,0x10,0x11,0x11,0x11,0x2,0xc,0x30,0x0,0x8,0xfc,0x8,0xf8,0x0,0xfe,0x10,0xf8,0x10,0x10,0x10,0x10,0xc0,0x30,0x8,
-+0x8,0x8,0x14,0x22,0x41,0xbe,0x0,0x2,0x7f,0x8,0x8,0x10,0x22,0x7f,0x1,0x0,0x4,0x4,0x4,0x24,0xa4,0xa4,0x24,0x24,0x24,0x24,0x24,0x24,0x4,0x4,0x14,0x8,
-+0x20,0x23,0x22,0xfe,0x43,0x42,0x92,0xff,0x12,0x12,0x1f,0xf2,0x52,0x12,0x13,0x10,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x24,0x2c,0xb0,0x20,0x22,0xa2,0x1e,0x0,
-+0x0,0x40,0x37,0x11,0x83,0x64,0x20,0x9,0x13,0x20,0xe1,0x23,0x25,0x29,0x21,0x21,0x80,0x48,0xfc,0x10,0x4c,0x44,0x80,0x10,0xf8,0x80,0x44,0x28,0x10,0x4e,0x84,0x0,
-+0x10,0x13,0x12,0x12,0xff,0x12,0x32,0x3b,0x56,0x52,0x93,0x12,0x12,0x12,0x13,0x10,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x24,0x2c,0xb0,0x20,0x22,0xa2,0x1e,0x0,
-+0x10,0x11,0x11,0x1d,0x21,0x21,0x7d,0x90,0x13,0xfe,0x12,0x12,0x17,0x1a,0x12,0x2,0x8,0xfc,0x8,0x8,0x8,0xf8,0x40,0x44,0xfe,0x44,0x64,0x9c,0xc,0x4,0x14,0x8,
-+0x8,0x4,0xff,0x0,0x3f,0x21,0x21,0x3f,0x0,0x7f,0x2,0x4,0xff,0x4,0x14,0x8,0x0,0x7c,0xc4,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x0,0x7f,0x40,0x5f,0x41,0x41,0x41,0x4f,0x41,0x41,0x41,0x41,0x5f,0x40,0x7f,0x40,0x4,0xfe,0x24,0xf4,0x4,0x4,0x44,0xe4,0x4,0x44,0x24,0x4,0xf4,0x4,0xfc,0x4,
-+0x0,0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x1,0xff,0x3,0x5,0x9,0x11,0x61,0x1,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x4,0xfe,0x80,0x40,0x20,0x1c,0x8,0x0,
-+0x1,0x7f,0x0,0x1f,0x11,0x1f,0x11,0x1f,0x1,0xff,0x9,0x35,0xc,0x14,0x65,0x6,0x0,0xfc,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x20,0x18,0xa0,0x40,0x3c,0x8,
-+0x0,0x40,0x20,0x17,0x0,0x0,0xf1,0x10,0x10,0x10,0x10,0x10,0x10,0x28,0x47,0x0,0x10,0x10,0x10,0xfc,0x10,0x10,0x10,0x90,0x90,0x10,0x10,0x50,0x20,0x6,0xfc,0x0,
-+0x0,0x0,0x8,0x7c,0x49,0x49,0x4a,0x4d,0x48,0x48,0x4b,0x7a,0x4a,0x2,0x3,0x2,0x40,0x40,0xa0,0xa0,0x10,0x8,0xe,0xf4,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x4,0x7e,0x44,0x77,0x54,0x54,0xfe,0x82,0x7c,0x44,0x7c,0x45,0x7c,0x44,0x54,0x4b,0x40,0x20,0x4,0xfe,0x20,0x20,0x44,0xfc,0x10,0x24,0x44,0x88,0x10,0x28,0xc6,0x2,
-+0x0,0xfc,0x4,0xb,0x10,0x10,0x15,0x1b,0x31,0xd0,0x10,0x11,0x16,0x10,0x51,0x26,0x80,0x40,0x4,0xfe,0x40,0x80,0x8,0xf8,0x10,0x24,0x4c,0x90,0x20,0x50,0x8c,0x4,
-+0x2,0x42,0x33,0x14,0x8b,0x62,0x22,0xa,0x1f,0x24,0xe4,0x24,0x27,0x20,0x20,0x20,0x0,0x8,0xfc,0x0,0xf8,0x88,0x48,0x8,0xfe,0x88,0x48,0x8,0xfc,0x8,0x28,0x10,
-+0x10,0x1f,0x10,0x2f,0x40,0xbf,0x2,0x3f,0x4,0x8,0x3f,0x2,0xc,0x31,0x46,0x18,0x8,0xfc,0x0,0xf8,0x0,0xf8,0x8,0xe8,0x8,0x88,0x8,0x8,0x88,0x8a,0x6a,0x24,
-+0x2,0x1,0x1,0xff,0x1,0x2,0x4,0x8,0x1f,0x2,0x4,0x8,0x31,0x6,0x18,0x60,0x0,0x0,0x4,0xfe,0x0,0x20,0x60,0x80,0x10,0x30,0x40,0xc0,0x20,0x10,0xc,0x4,
-+0x2,0x1,0x7f,0x41,0x9f,0x1,0x1f,0x1,0x7f,0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x0,0x0,0xfe,0x2,0xf4,0x0,0xf0,0x0,0xfc,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,
-+0x8,0xfc,0x8,0x4f,0x48,0x48,0x49,0x4b,0x7d,0x4,0x4,0x1d,0xe6,0x44,0x15,0xa,0x80,0x40,0x44,0xfe,0x40,0x80,0x8,0xf8,0x10,0x24,0x4c,0x90,0x20,0x58,0x8c,0x4,
-+0x1,0xff,0x14,0x14,0x7f,0x55,0x55,0x55,0x63,0x41,0x41,0x7f,0x41,0x41,0x7f,0x41,0x44,0xc4,0x44,0x44,0xfe,0x44,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x44,0x7c,0x44,
-+0x3e,0x4,0xff,0x22,0x3f,0x22,0x3e,0x22,0xff,0x2,0xa,0x29,0x28,0x48,0x7,0x0,0x40,0x44,0x7e,0x84,0x44,0x48,0x28,0x10,0x2e,0xc4,0x0,0x88,0xa4,0x24,0xe0,0x0,
-+0x22,0x22,0x22,0x22,0xff,0x22,0x22,0x22,0x3e,0x22,0x22,0x22,0x22,0x3e,0x22,0x0,0x0,0x7c,0x44,0x44,0xc8,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x8,0xa,0xff,0x8,0x8,0x7f,0x41,0x7f,0x41,0x7f,0x8,0x9,0xff,0x8,0x8,0x8,0x20,0x20,0x24,0xfe,0x20,0x28,0xfc,0x20,0x20,0xfe,0x22,0x22,0xaa,0x24,0x20,0x20,
-+0x1,0x1,0x2,0x4,0xa,0x11,0x20,0xdf,0x0,0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x0,0x0,0x80,0x40,0x20,0x90,0x8e,0xe4,0x40,0x90,0xf8,0x10,0x10,0x10,0xf0,0x10,
-+0x40,0x37,0x10,0x0,0x84,0x44,0x46,0xd,0x14,0x25,0xe6,0x24,0x25,0x24,0x27,0x24,0x0,0xfc,0x8,0x10,0x64,0x44,0x4c,0x54,0xe4,0x54,0x4c,0x44,0x44,0x84,0xfc,0x4,
-+0x2,0x1,0x7f,0x44,0x9f,0x4,0x1f,0x4,0x7f,0x4,0xb,0x10,0x20,0xc6,0x1,0x0,0x0,0x0,0xfe,0x42,0xf4,0x40,0xf0,0x40,0xfc,0x40,0x20,0x90,0x4e,0x4,0x80,0x40,
-+0x0,0x1f,0x0,0x0,0x41,0x51,0x49,0x45,0x41,0x45,0x49,0x51,0x45,0x42,0x7f,0x40,0x0,0xf0,0x20,0x40,0x84,0x14,0x34,0x44,0x4,0x44,0x34,0x14,0x4,0x4,0xfc,0x4,
-+0x0,0x10,0x78,0x57,0x54,0x57,0x54,0x55,0x55,0x55,0x55,0x75,0x45,0x8,0x11,0x20,0x10,0x18,0x14,0xfe,0x10,0xf0,0x14,0xd4,0x54,0x54,0x58,0xd0,0x28,0x4a,0x8a,0x4,
-+0x0,0x7f,0x40,0x84,0x8,0x0,0x3f,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x0,0xfe,0x2,0x44,0x20,0x0,0xf8,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x10,0x14,0xfe,0x11,0x7e,0x45,0x7c,0x45,0x7c,0x10,0xfe,0x11,0x10,0x11,0x10,0x20,0x20,0x50,0x88,0x6,0x4,0xdc,0x44,0x54,0xcc,0x44,0xcc,0x54,0x44,0x54,0x88,
-+0x10,0x10,0x10,0x17,0xfc,0x17,0x14,0x1d,0x35,0xd5,0x15,0x14,0x19,0x13,0x55,0x20,0x10,0x14,0x10,0xfe,0x10,0xf0,0x14,0xd4,0x58,0x52,0xea,0x6,0x40,0x24,0xa,0xf8,
-+0x13,0x12,0x12,0x13,0xfa,0x12,0x13,0x18,0x37,0xd0,0x10,0x1f,0x10,0x10,0x50,0x20,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x40,0xfc,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,
-+0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x0,0x3f,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0xf0,0x10,0x10,0xf0,0x10,0x10,0xf0,0x0,0xf8,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,
-+0x10,0x10,0x10,0x17,0x5c,0x57,0x54,0x95,0x15,0x15,0x15,0x14,0x19,0x13,0x15,0x10,0x10,0x14,0x10,0xfe,0x10,0xf0,0x14,0xd4,0x58,0x52,0xea,0x6,0x40,0x24,0xa,0xf8,
-+0x13,0x12,0x12,0x13,0x5a,0x56,0x53,0x90,0x17,0x10,0x10,0x1f,0x10,0x10,0x10,0x10,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x0,0xfc,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,
-+0x11,0x11,0x11,0x15,0x59,0x51,0x51,0x90,0x13,0x10,0x10,0x2b,0x24,0x44,0x80,0x0,0xfc,0x4,0x4,0xfc,0x4,0x4,0xfc,0x0,0xfe,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x0,0x47,0x30,0x10,0x80,0x60,0x20,0xf,0x10,0x20,0xe0,0x20,0x20,0x20,0x20,0x0,0x8,0xfc,0x40,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x40,0x37,0x10,0x82,0x62,0x22,0x9,0x11,0x20,0xe0,0x20,0x21,0x22,0x24,0x8,0x0,0x8,0xfc,0x8,0x8,0x8,0x10,0x10,0x20,0xa0,0x40,0xa0,0x10,0x8,0xe,0x4,
-+0x1,0x1,0x1,0x7f,0x2,0x4,0xa,0x32,0xc2,0x1f,0x2,0x2,0x2,0x4,0x8,0x30,0x0,0x0,0x8,0xfc,0x80,0x40,0x30,0xe,0x4,0xf0,0x10,0x10,0x10,0x10,0xa0,0x40,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x12,0x14,0x18,0x80,0x40,0x48,0xfc,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x8,0x10,0x3e,0x23,0x32,0x2a,0x22,0xfe,0x22,0x32,0x2a,0x22,0x22,0x22,0x4a,0x85,0x40,0x30,0x14,0xfe,0x0,0x8,0x7c,0x48,0x48,0x48,0x48,0x48,0x4a,0x4a,0x86,0x0,
-+0x20,0x23,0x20,0x21,0xf9,0x27,0x24,0x2b,0x20,0x23,0x20,0x3b,0xe0,0x47,0x0,0x0,0x40,0xfc,0x0,0xf8,0x8,0xfe,0x2,0xfc,0xc0,0x68,0xb0,0x28,0xe6,0x24,0xa0,0x40,
-+0x0,0x17,0xf8,0x91,0x91,0x97,0x94,0x9b,0x90,0x91,0x96,0xf1,0x96,0x1,0x6,0x0,0x48,0xfc,0x0,0xf0,0x10,0xfe,0x2,0xfc,0x80,0x48,0xf0,0x50,0xce,0x44,0x40,0xc0,
-+0x1,0x7f,0x0,0xf,0x8,0x7f,0x40,0x9f,0x6,0xb,0x35,0x9,0x33,0x5,0x39,0x3,0x8,0xfc,0x0,0xe0,0x20,0xfe,0x2,0xf4,0x10,0x20,0x40,0x80,0x60,0x1c,0x8,0x0,
-+0x1,0x7f,0x0,0xf,0x8,0xf,0x0,0x7f,0x40,0x9f,0x1,0xf,0x1,0x3f,0x1,0x0,0x8,0xfc,0x20,0xf0,0x20,0xe0,0x0,0xfe,0x2,0xf4,0x0,0xe0,0x0,0xf4,0x4,0xfc,
-+0x8,0x8,0xa,0x7f,0x8,0x9,0xff,0x14,0x14,0x56,0x55,0x95,0x24,0x24,0x4c,0x80,0x0,0x7c,0x44,0x44,0x48,0x48,0xd0,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x10,0x11,0x10,0x10,0xfc,0x24,0x24,0x27,0x24,0x44,0x28,0x10,0x28,0x44,0x84,0x0,0x0,0xfc,0x4,0x8,0x10,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x10,0x10,0x15,0xfe,0x10,0x7c,0x11,0xfe,0x10,0x38,0x35,0x54,0x50,0x90,0x10,0x10,0x8,0x3c,0xc0,0x40,0x50,0x78,0xc0,0x40,0x48,0x7c,0xc0,0x40,0x42,0x42,0x3e,0x0,
-+0x0,0x1f,0x10,0x10,0x10,0x1f,0x0,0xff,0x4,0x8,0x1f,0x0,0x0,0x0,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0xf0,0x4,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0xa0,0x40,
-+0x40,0x32,0x12,0x3,0x84,0x68,0x20,0xf,0x10,0x23,0xe2,0x22,0x22,0x22,0x23,0x22,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0xb,0x7c,0x48,0x48,0x4b,0x4a,0x4a,0x4a,0x4a,0x4b,0x7a,0x48,0x0,0x0,0x0,0x4,0xfe,0x8,0x8,0x48,0xe8,0x48,0x48,0x48,0x48,0xc8,0x48,0x8,0x8,0x28,0x10,
-+0x0,0xb,0x7e,0x4b,0x4a,0x4b,0x48,0x49,0x4a,0x4c,0x4a,0x7a,0x4a,0x3,0x0,0x0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x84,0xfe,0x4,0x44,0x44,0xa4,0x4,0xe4,0x14,0x8,
-+0x8,0x8,0xff,0x8,0x10,0x1f,0x10,0x30,0x53,0x92,0x12,0x12,0x13,0x12,0x10,0x10,0x20,0x24,0xfe,0x20,0x4,0xfe,0x8,0x48,0xe8,0x48,0x48,0x48,0xc8,0x8,0x28,0x10,
-+0x8,0x8,0xff,0x8,0x40,0x3f,0x10,0x80,0x63,0x22,0xa,0x12,0xe3,0x22,0x20,0x20,0x20,0x24,0xfe,0x20,0x4,0xfe,0x8,0x48,0xe8,0x48,0x48,0x48,0xc8,0x8,0x28,0x10,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x39,0x37,0x55,0x50,0x90,0x11,0x16,0x10,0x11,0x16,0x80,0x40,0x44,0xfe,0x40,0x80,0x8,0xf8,0x10,0x24,0x4c,0x90,0x20,0x50,0x8c,0x4,
-+0x0,0x0,0x3f,0x1,0x1,0x1,0xff,0x1,0x3,0x5,0x9,0x11,0x21,0x41,0x1,0x1,0x10,0x38,0xc0,0x0,0x0,0x4,0xfe,0x0,0x80,0x40,0x20,0x18,0xe,0x4,0x0,0x0,
-+0x2,0x7,0x78,0x8,0xa,0xff,0x8,0x18,0x1c,0x2a,0x2a,0x48,0x88,0x8,0x8,0x8,0x0,0x0,0x0,0x4,0xfe,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0xfc,0x84,0x0,0x0,
-+0x8,0x8,0xf,0x10,0x10,0x33,0x52,0x92,0x12,0x12,0x13,0x12,0x10,0x10,0x10,0x10,0x0,0x4,0xfe,0x8,0x48,0xe8,0x48,0x48,0x48,0x48,0xc8,0x48,0x8,0x8,0x28,0x10,
-+0x1,0x1,0x2,0x4,0x8,0x10,0x2f,0xc0,0x0,0x1f,0x10,0x10,0x10,0x10,0x1f,0x10,0x0,0x0,0x80,0x40,0x20,0x10,0xee,0x4,0x10,0xf8,0x10,0x10,0x10,0x10,0xf0,0x10,
-+0x1,0x2,0x4,0xf,0x10,0x2f,0xc8,0x8,0xf,0x0,0x1f,0x12,0x12,0x12,0xff,0x0,0x0,0x80,0x40,0xe0,0x10,0xee,0x24,0x20,0xe0,0x10,0xf8,0x90,0x90,0x94,0xfe,0x0,
-+0x8,0x10,0x24,0x54,0x89,0x52,0x28,0x4c,0x94,0x27,0x4c,0x94,0x24,0x44,0x14,0x8,0x40,0x40,0x7c,0x84,0x88,0x50,0x20,0x50,0x88,0xe,0xfc,0x88,0x88,0x88,0xf8,0x88,
-+0x20,0x1b,0x48,0x42,0x41,0x5f,0x41,0x42,0x44,0x4f,0x42,0x44,0x49,0x52,0x44,0x40,0x4,0xfe,0x4,0x4,0x24,0xf4,0x4,0x44,0x84,0x24,0x44,0x84,0x84,0x64,0x24,0xc,
-+0x40,0x3f,0x10,0x0,0x80,0x67,0x24,0xc,0x14,0x24,0xe7,0x24,0x20,0x20,0x20,0x20,0x4,0xfe,0x8,0x8,0x48,0xe8,0x48,0x48,0x48,0x48,0xc8,0x48,0x8,0x8,0x28,0x10,
-+0x40,0x37,0x14,0x4,0x87,0x64,0x24,0xd,0x15,0x25,0xe5,0x25,0x25,0x24,0x27,0x24,0x4,0xfe,0x44,0x54,0xfc,0x44,0x54,0xfc,0x14,0x14,0x14,0xf4,0x14,0x4,0xfc,0x4,
-+0x8,0x8,0x7e,0x8,0x8,0xff,0x14,0x14,0x36,0x75,0x94,0x14,0x14,0x14,0x24,0x4d,0x20,0x28,0xfc,0x20,0x24,0xfe,0x50,0x50,0xd8,0x56,0x52,0x50,0x50,0x50,0x90,0x30,
-+0x40,0x23,0x22,0x3,0xfa,0x13,0x21,0x6b,0xb4,0x28,0x22,0x22,0x22,0x23,0x20,0x20,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x4,0xfe,0x4,0x44,0x44,0xa4,0x4,0xe4,0x14,0x8,
-+0x8,0x8,0x7f,0x52,0x90,0x28,0x7e,0xa8,0x3e,0x28,0x3e,0x28,0x29,0x3e,0x20,0x20,0x20,0x48,0xfc,0x88,0xa8,0x88,0xa8,0x90,0x84,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x10,0x10,0x7f,0x11,0x11,0x25,0x42,0x9f,0x10,0x11,0x11,0x11,0x11,0x2,0xc,0x30,0x0,0x4,0x7e,0x44,0x44,0x7c,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0xc0,0x30,0x8,
-+0x0,0xb,0x7e,0x4b,0x4a,0x4a,0x4a,0x4b,0x48,0x4b,0x48,0x4f,0x78,0x4a,0x2,0x4,0x8,0xfc,0x48,0x58,0xe8,0x48,0x48,0xf8,0x40,0xf8,0x40,0xfe,0x0,0xa8,0xa4,0x4,
-+0x0,0x3f,0x21,0x31,0x2d,0x25,0x21,0x3f,0x1,0x7f,0x1,0xff,0x0,0x28,0x24,0x44,0x8,0xfc,0x8,0x28,0x38,0x48,0x8,0xf8,0x0,0xfc,0x0,0xfe,0x0,0x90,0x4c,0x44,
-+0x1,0x0,0x1f,0x10,0x97,0x54,0x57,0x14,0x37,0x54,0xd4,0x14,0x24,0x25,0x46,0x4,0x0,0x84,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x84,0x8c,0x50,0x20,0x10,0xe,0x4,
-+0x8,0xb,0x12,0x12,0x23,0x4a,0x8a,0x13,0x32,0x52,0x92,0x12,0x12,0x12,0x13,0x12,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x84,0x8c,0x50,0x20,0x10,0x88,0xe,0x4,
-+0x0,0x8b,0x5a,0x22,0x53,0x8a,0xa,0x1b,0x2a,0x4a,0x8a,0xa,0xa,0xa,0x53,0x22,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x84,0x8c,0x50,0x20,0x10,0x88,0xe,0x4,
-+0x10,0x13,0x12,0x12,0x5b,0x56,0x52,0x93,0x12,0x12,0x12,0x12,0x12,0x12,0x13,0x12,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x84,0x8c,0x50,0x20,0x10,0x88,0xe,0x4,
-+0x0,0x8,0x7f,0x48,0x49,0x49,0x49,0x49,0x48,0x4b,0x48,0x78,0x48,0x0,0x0,0x0,0x40,0x24,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x0,0xfc,0x8,0x30,0x20,0x20,0xa0,0x40,
-+0x2,0x1,0xff,0x0,0x1f,0x10,0x10,0x1f,0x0,0x3f,0x0,0x1,0x1,0x1,0x5,0x3,0x0,0x4,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x0,0xf8,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x11,0x11,0x17,0x11,0xfd,0x17,0x30,0x3b,0x56,0x53,0x92,0x13,0x10,0x11,0x13,0x14,0x10,0x10,0xfc,0x10,0x14,0xfe,0x48,0xfc,0x48,0xf8,0x48,0xf8,0x0,0x10,0xc,0x4,
-+0x12,0x13,0x24,0x49,0x9f,0x19,0x2f,0x69,0xaf,0x21,0x21,0x3f,0x22,0x24,0x28,0x20,0x0,0xc4,0x9e,0x0,0xe0,0x20,0xfe,0x24,0xe4,0x4,0x24,0xf4,0x84,0x44,0x54,0x8,
-+0x10,0x17,0x10,0x10,0x5b,0x56,0x52,0x93,0x12,0x12,0x13,0x10,0x10,0x1f,0x10,0x10,0x8,0xfc,0x0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x0,0x4,0xfe,0x0,0x0,
-+0x2,0x7f,0x8,0x11,0x3f,0x1,0xff,0x1,0x1,0x7e,0x22,0x14,0x8,0x14,0x22,0xc1,0x8,0xfc,0x0,0x0,0xf8,0x0,0xfe,0x0,0x0,0xfc,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x0,0x8,0x7c,0x48,0x4b,0x48,0x48,0x48,0x48,0x48,0x4f,0x78,0x48,0x0,0x1,0x2,0x90,0x90,0x90,0x90,0xfc,0x90,0x90,0x90,0x90,0x94,0xfe,0x0,0x90,0x88,0xc,0x4,
-+0x10,0x10,0x10,0x10,0x57,0x58,0x50,0x90,0x10,0x10,0x17,0x28,0x24,0x44,0x81,0x2,0x90,0x90,0x90,0x90,0xfc,0x90,0x90,0x90,0x90,0x94,0xfe,0x0,0x90,0x88,0xc,0x4,
-+0x10,0x10,0x15,0x7e,0x54,0x54,0x54,0x54,0x7c,0x50,0x10,0x14,0x1e,0xe2,0x47,0x0,0x0,0x8,0xfc,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x40,0x30,0x10,0x2,0x9f,0x64,0x24,0x4,0x14,0x14,0xe7,0x3c,0x29,0x20,0x20,0x20,0x20,0x48,0xfc,0x88,0xa8,0x88,0xa8,0x90,0x84,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x42,0x32,0x12,0x2,0x8f,0x62,0x22,0xa,0x12,0x3f,0xe0,0x22,0x22,0x24,0x24,0x28,0x10,0x10,0x10,0x10,0xfc,0x10,0x10,0x10,0x14,0xfe,0x0,0x20,0x10,0x8,0xc,0x4,
-+0x2,0x1,0x7f,0x40,0x82,0x2,0xff,0x4,0x4,0x8,0x9,0x11,0x12,0x24,0x4f,0x0,0x0,0x0,0xfc,0x4,0x8,0x0,0xfe,0x0,0x80,0x80,0x0,0x0,0x20,0x10,0xf8,0x8,
-+0x4,0xfe,0x4,0x4,0x4,0x7c,0x40,0x40,0x44,0x7e,0x4,0x4,0x5,0x45,0x2b,0x10,0x20,0x20,0x20,0x20,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x90,0x8,0x4,0xfc,0x4,
-+0x10,0x10,0x23,0x20,0x44,0xf8,0x10,0x20,0x40,0xfc,0x40,0x0,0x1c,0xe0,0x47,0x0,0x0,0x8,0xfc,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x1,0x9,0x7d,0x4a,0x4a,0x4e,0x4a,0x4a,0x4a,0x4a,0x4b,0x7a,0x4a,0x2,0x2,0x2,0x8,0x7c,0x8,0x8,0xfe,0x0,0x40,0x7e,0x90,0x14,0xfe,0x10,0x20,0x28,0x46,0x82,
-+0x8,0xb,0x8,0x10,0x17,0x32,0x52,0x93,0x14,0x10,0x1f,0x10,0x10,0x10,0x11,0x16,0x10,0xf8,0x10,0x10,0xfc,0x0,0x8,0xfc,0x40,0x44,0xfe,0x40,0xa0,0x90,0xe,0x4,
-+0x5,0x89,0x51,0x22,0x53,0x96,0x1a,0x12,0x33,0x52,0x93,0x12,0x12,0x12,0x52,0x23,0x8,0xfc,0x8,0x8,0xfe,0x0,0x88,0xfc,0x20,0x24,0xfe,0x20,0x20,0x50,0x8e,0x4,
-+0x0,0x7,0x78,0x48,0x49,0x49,0x49,0x49,0x49,0x4f,0x49,0x79,0x49,0x1,0x5,0x2,0x10,0xd0,0x50,0x90,0x10,0x10,0x10,0x50,0x90,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x0,0x3f,0x20,0x2f,0x28,0x2f,0x28,0x2f,0x20,0x2f,0x20,0x20,0x5f,0x40,0x82,0x1,0x8,0xfc,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xf8,0x40,0x84,0xfe,0x80,0x80,0x0,
-+0x10,0x13,0x20,0x28,0x6f,0xa9,0x29,0x2b,0x2c,0x28,0x2f,0x28,0x28,0x21,0x22,0x24,0x10,0xf8,0x10,0x14,0xfe,0x0,0x8,0xfc,0x40,0x44,0xfe,0x40,0xa0,0x10,0xe,0x4,
-+0x0,0x0,0x3f,0x20,0x20,0x3f,0x20,0x20,0x27,0x24,0x24,0x24,0x44,0x44,0x87,0x4,0x10,0x78,0x80,0x0,0x4,0xfe,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x8,0x7f,0x48,0x4a,0x49,0x49,0x48,0x4f,0x48,0x48,0x78,0x48,0x0,0x1,0x0,0x8,0x1c,0xe0,0x40,0x48,0x58,0x60,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x80,
-+0x0,0x3f,0x1,0x1,0x11,0xd,0x5,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x5,0x2,0x78,0x80,0x0,0x0,0x10,0x30,0x40,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x8,0x8,0xf,0x12,0x12,0x22,0x44,0x4,0x9,0x12,0x2,0x29,0x28,0x48,0x7,0x0,0x0,0x8,0xfc,0x48,0x48,0x48,0x88,0x88,0x28,0x10,0x0,0x88,0xa4,0x24,0xe0,0x0,
-+0x1,0x11,0xf9,0x27,0x21,0x21,0xf9,0x27,0x24,0x24,0x24,0x3c,0xe7,0x44,0x0,0x1,0x4,0x3e,0x24,0xe4,0x24,0x3c,0x24,0xa4,0xa4,0xbc,0xa4,0xa4,0xa4,0x44,0x94,0x8,
-+0x1,0x1,0x7f,0x1,0x3f,0x1,0x7f,0x44,0x84,0x24,0x14,0xc,0x4,0x4,0x7f,0x0,0x0,0x8,0xfc,0x0,0xf8,0x0,0xfe,0x44,0x40,0x48,0x58,0x60,0x40,0x48,0xfc,0x0,
-+0x4,0x4,0xff,0x4,0x8,0x9,0x7f,0x8,0xa,0x3f,0x22,0x22,0x22,0x3e,0x22,0x1,0x40,0x44,0xfe,0x40,0x7c,0x44,0xc4,0x7c,0x44,0x44,0x7c,0x44,0x44,0x44,0x94,0x8,
-+0x8,0x8,0x8,0x9,0xff,0x8,0x8,0xa,0x3f,0x22,0x22,0x22,0x22,0x3e,0x22,0x1,0x4,0x7e,0x44,0x44,0xc4,0x7c,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x44,0x94,0x8,
-+0x21,0x21,0x21,0x21,0xf9,0xaf,0xa9,0xa9,0xab,0xfa,0xa2,0x2a,0x3b,0xea,0x0,0x1,0x4,0x3e,0x24,0x24,0x24,0xfc,0x24,0x24,0xa4,0xbc,0xa4,0xa4,0xa4,0x44,0x94,0x8,
-+0x0,0x88,0x53,0x22,0x52,0x92,0x12,0x12,0x32,0x52,0x92,0x12,0x14,0x15,0x58,0x20,0x8,0x1c,0xe0,0x8,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0xa8,0x94,0xf6,0x4,0x0,
-+0x11,0x11,0x55,0x39,0x17,0x11,0xfd,0x33,0x3a,0x56,0x52,0x93,0x12,0x10,0x10,0x11,0x4,0x3e,0x24,0x24,0xe4,0x3c,0x24,0xa4,0xa4,0xbc,0xa4,0xa4,0x24,0x44,0x94,0x8,
-+0x42,0x32,0x12,0x2,0x9f,0x62,0x22,0xf,0x18,0x28,0xc8,0x48,0x48,0x4f,0x48,0x40,0x4,0x3e,0x24,0x24,0xe4,0x3c,0xa4,0xe4,0xa4,0xbc,0xa4,0xa4,0xa4,0xa4,0x54,0x88,
-+0x0,0xf8,0xb,0xa,0xa,0x7a,0x42,0x42,0x42,0x7a,0xa,0xa,0xa,0xa,0x54,0x28,0x8,0x1c,0xe8,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0xa8,0x94,0xf6,0x4,
-+0x1,0x1,0x1,0x3f,0x22,0x22,0x3f,0x22,0x21,0x20,0x27,0x24,0x24,0x24,0x48,0x90,0x20,0xf0,0x0,0xfc,0x4,0x68,0x80,0x8,0xf8,0x40,0xe0,0x40,0x40,0x44,0x44,0x3c,
-+0x0,0x8,0x7c,0x4b,0x4a,0x4a,0x4b,0x4a,0x4a,0x4a,0x4a,0x7a,0x4c,0x8,0x11,0x6,0x48,0x7c,0x40,0xfe,0x42,0x5c,0xe0,0x44,0x3c,0x10,0xf8,0x90,0x90,0x92,0x12,0xe,
-+0x10,0x10,0x10,0x13,0xfe,0x12,0x16,0x1b,0x32,0xd2,0x12,0x12,0x12,0x14,0x54,0x28,0x80,0x60,0x24,0xfe,0x4,0x4,0x4,0xfc,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x8,0x8,0xf,0x8,0x8,0x8,0x8,0x10,0x1f,0x0,0x0,0x0,0xff,0x0,0x8,0xfc,0x0,0x20,0xf0,0x20,0x20,0x20,0x20,0x20,0xe0,0x20,0x20,0x24,0xfe,0x0,
-+0x0,0x40,0x30,0x13,0x82,0x62,0x22,0xb,0x12,0x12,0xe2,0x22,0x22,0x24,0x24,0x28,0x80,0x60,0x24,0xfe,0x4,0x4,0x4,0xfc,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x0,0x0,0x3f,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80,0x0,0x80,0x84,0xfe,0x4,0x4,0x4,0xfc,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x8,0x8,0xff,0x8,0x8,0x8,0x10,0x10,0x30,0x50,0x90,0x11,0x12,0x14,0x10,0x10,0x20,0x24,0xfe,0x20,0x20,0x80,0x88,0x98,0xa0,0xc0,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x0,0x8,0x7d,0x49,0x4b,0x4d,0x49,0x49,0x49,0x48,0x4f,0x78,0x48,0x0,0x0,0x0,0xa0,0xa4,0x2c,0x30,0x60,0x22,0x22,0x1e,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x4,0x4,0x8,0x8,0x18,0x29,0x4a,0x8,0x9,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x40,0x48,0x58,0x60,0xc0,0x40,0x44,0x44,0x3c,0x0,0xfe,0x0,0x0,0x0,0x0,0x0,
-+0x83,0x4a,0x2b,0x12,0x32,0x57,0x94,0x1b,0x32,0x53,0x92,0x13,0x12,0x12,0xa2,0x42,0xf8,0x8,0xc8,0x48,0x48,0xfe,0x2,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x43,0x32,0x13,0x2,0x82,0x4f,0x48,0x13,0x12,0x23,0xe2,0x23,0x22,0x22,0x22,0x22,0xf8,0x8,0xc8,0x48,0x48,0xfe,0x2,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x0,0x7f,0x0,0x1f,0x11,0x51,0x51,0x5f,0x51,0x51,0x51,0x5f,0x50,0x40,0x7f,0x40,0x8,0xfc,0x10,0xf8,0x10,0x14,0x14,0xf4,0x14,0x14,0x14,0xf4,0x14,0x4,0xfc,0x4,
-+0x10,0x14,0x12,0x10,0x13,0xfc,0x10,0x10,0x11,0xb,0xc,0x8,0x14,0x24,0x42,0x1,0x4,0x4,0x4,0x24,0xa4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x4,0x84,0x94,0x88,
-+0x8,0x8,0x8,0x10,0x10,0x30,0x50,0x90,0x11,0x12,0x14,0x10,0x10,0x10,0x10,0x10,0x80,0x80,0x80,0x88,0x98,0xa0,0xc0,0x80,0x80,0x80,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x0,0x40,0x33,0x10,0x0,0x0,0xf7,0x10,0x10,0x13,0x12,0x12,0x16,0x1a,0x13,0x2,0x10,0x38,0xc0,0x40,0x40,0x44,0xfe,0x40,0x48,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x13,0x12,0xfe,0x13,0x3a,0x36,0x53,0x52,0x90,0x11,0x11,0x12,0x14,0x18,0x40,0x88,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x80,0xc8,0x54,0x5c,0x42,0x42,0x3e,
-+0x8,0x8,0x13,0x12,0x22,0x4a,0x8a,0x12,0x32,0x52,0x92,0x12,0x12,0x13,0x12,0x10,0x0,0x4,0xfe,0x4,0x4,0xf4,0x94,0x94,0x94,0x94,0xf4,0x4,0x4,0xfc,0x4,0x0,
-+0x10,0x10,0x17,0x10,0x58,0x54,0x50,0x90,0x11,0x12,0x14,0x18,0x10,0x10,0x10,0x10,0x0,0x4,0xfe,0x20,0x20,0x40,0x40,0xd0,0x4c,0x46,0x42,0x40,0x40,0x40,0x40,0x40,
-+0x41,0x31,0x11,0x3,0x86,0x6a,0x23,0xa,0x12,0x23,0xe2,0x22,0x22,0x23,0x22,0x22,0x40,0x20,0x4,0xfe,0x20,0x28,0xfc,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,0x0,
-+0x20,0x20,0x2f,0x20,0xf8,0x20,0x20,0x20,0x21,0x2a,0x34,0xe8,0x40,0x0,0x0,0x0,0x0,0x4,0xfe,0x20,0x20,0x40,0x40,0xd0,0x4c,0x46,0x42,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x0,0xfc,0x4,0x45,0x46,0x28,0x28,0x10,0x28,0x24,0x44,0x81,0x1,0x2,0xc,0x80,0x80,0x80,0xfc,0x4,0x48,0x40,0x40,0x40,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,
-+0x10,0xf8,0x27,0x20,0x20,0x20,0xf8,0x20,0x21,0x22,0x24,0x20,0x38,0xe0,0x40,0x0,0x0,0x4,0xfe,0x20,0x20,0x40,0x40,0xd0,0x4c,0x46,0x42,0x40,0x40,0x40,0x40,0x40,
-+0x10,0x10,0x17,0x10,0xff,0x12,0x3a,0x36,0x53,0x52,0x92,0x12,0x13,0x10,0x1f,0x10,0x0,0x8,0xfc,0x0,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x4,0xfe,0x0,
-+0x0,0x40,0x2f,0x20,0x0,0xe0,0x20,0x21,0x22,0x24,0x28,0x20,0x20,0x50,0x8f,0x0,0x0,0x4,0xfe,0x40,0x40,0x80,0x80,0xa0,0x98,0x8c,0x84,0x80,0x80,0x6,0xfc,0x0,
-+0x10,0x13,0x22,0x21,0x44,0xfb,0x10,0x27,0x40,0xfc,0x1,0x1,0x1a,0xe4,0x49,0x2,0xc,0xf0,0x48,0x50,0x20,0xfc,0x40,0xfe,0x80,0xfc,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x10,0x10,0x11,0x12,0xfc,0x13,0x12,0x1e,0x32,0xd2,0x1f,0x10,0x10,0x11,0x52,0x2c,0x80,0x80,0xf0,0x20,0x48,0xfc,0x48,0x48,0x48,0x48,0xfe,0x40,0xa0,0x10,0xe,0x4,
-+0x1,0x3f,0x21,0x21,0x3f,0x1,0x7f,0x41,0x41,0x7f,0x41,0x2,0x29,0x28,0x48,0x7,0x8,0xfc,0x8,0x8,0xf8,0x4,0xfe,0x4,0x4,0xfc,0x4,0x0,0x90,0xac,0x24,0xe0,
-+0x0,0x8,0x7c,0x49,0x4a,0x49,0x49,0x49,0x49,0x49,0x4f,0x78,0x48,0x0,0x1,0x6,0x40,0x40,0xf8,0x10,0x24,0xfe,0x24,0x24,0x24,0x24,0xfe,0x20,0x50,0x88,0x6,0x4,
-+0x1,0x0,0x1f,0x11,0x51,0x32,0x14,0x33,0x52,0xd2,0x12,0x1f,0x20,0x21,0x42,0xc,0x0,0x84,0xfe,0x0,0xf0,0x20,0x48,0xfc,0x48,0x48,0x48,0xfe,0xa0,0x10,0xe,0x4,
-+0x9,0x5,0x7f,0x2,0xff,0x4,0xf,0x12,0x25,0xda,0x4,0x19,0x62,0xc,0x72,0x1,0x20,0x48,0xfc,0x0,0xfe,0x40,0xe0,0x10,0x1e,0xa4,0xc0,0xa0,0x98,0x88,0x80,0x0,
-+0x10,0x10,0x10,0x15,0x5a,0x51,0x51,0x91,0x11,0x11,0x17,0x28,0x24,0x40,0x81,0x6,0x40,0x40,0xf8,0x10,0x24,0xfe,0x24,0x24,0x24,0x24,0xfe,0x20,0x50,0x88,0x6,0x4,
-+0x40,0x30,0x11,0x2,0x84,0x63,0x22,0xa,0x12,0x12,0xef,0x20,0x20,0x21,0x22,0x2c,0x80,0x80,0xf0,0x20,0x48,0xfc,0x48,0x48,0x48,0x48,0xfe,0x40,0xa0,0x10,0xe,0x4,
-+0x2,0x1,0x7f,0x40,0x9f,0x11,0x11,0x1f,0x10,0x10,0x1f,0x11,0x11,0x11,0x1f,0x10,0x0,0x0,0xfe,0x2,0xf4,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x0,0x10,0xf8,0x0,
-+0x8,0x8,0xb,0x10,0x10,0x20,0x42,0xfe,0x4,0x8,0x10,0x20,0x42,0xff,0x1,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x4,0x4,0x7f,0x4,0x1,0xff,0x10,0x10,0x1f,0x0,0x11,0x11,0x11,0x11,0x21,0x41,0x40,0x48,0xfc,0x40,0x4,0xfe,0x0,0x20,0xf0,0x0,0x10,0x10,0x10,0x12,0x12,0xe,
-+0x11,0x11,0x1f,0x11,0x58,0x57,0x52,0x92,0x13,0x10,0x12,0x12,0x12,0x12,0x14,0x18,0x10,0x14,0xfe,0x10,0x44,0xfe,0x0,0x8,0xfc,0x0,0x48,0x48,0x48,0x4a,0x4a,0x46,
-+0x4,0x4,0x3f,0x4,0x4,0xff,0x1,0x1f,0x11,0x1f,0x11,0x1f,0x10,0x4,0x18,0x60,0x40,0x50,0xf8,0x40,0x44,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x0,0x60,0x18,0x4,
-+0x0,0x8,0xfd,0x10,0x10,0x23,0x3c,0x65,0xa5,0x25,0x25,0x25,0x3c,0x24,0x1,0x6,0x88,0x88,0xfc,0x88,0x88,0xfe,0x24,0xfe,0x24,0xfc,0x24,0xfc,0x0,0x88,0x6,0x2,
-+0x10,0x10,0x11,0x15,0x7f,0x55,0x55,0x54,0x57,0x7c,0x50,0x15,0x1c,0xf4,0x43,0x0,0x20,0x44,0xfe,0x4,0xfc,0x4,0xfc,0x4,0xfe,0x20,0x28,0xfc,0x20,0x24,0xfe,0x0,
-+0x10,0x1f,0x28,0x45,0x4,0x7f,0x4,0xff,0x1,0x1f,0x11,0x1f,0x11,0x1f,0xc,0x30,0x40,0x7c,0xa0,0x50,0x40,0xfc,0x40,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x60,0x18,
-+0x2,0x4,0x3f,0x20,0x3f,0x20,0x3f,0x0,0x7f,0x1,0x1,0x3f,0x1,0x1,0xff,0x0,0x0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfc,0x0,0x10,0xf8,0x0,0x4,0xfe,0x0,
-+0x0,0x3f,0x22,0x2f,0x28,0x2f,0x28,0x2f,0x20,0x2f,0x21,0x27,0x21,0x5f,0x40,0x80,0x8,0xfc,0x8,0xe8,0x28,0xe8,0x28,0xe8,0x8,0xe8,0x8,0xc8,0xa,0xfa,0xa,0x4,
-+0x10,0x10,0x13,0x12,0x5b,0x56,0x53,0x90,0x17,0x10,0x10,0x13,0x10,0x10,0x1f,0x10,0x40,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfc,0x40,0x50,0xf8,0x40,0x44,0xfe,0x0,
-+0x10,0x10,0x13,0x16,0x5b,0x52,0x53,0x90,0x17,0x10,0x10,0x13,0x28,0x44,0x8f,0x0,0x40,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfc,0x40,0x50,0xf8,0x40,0x44,0xfe,0x0,
-+0x0,0x3f,0x20,0x3f,0x20,0x3f,0x1,0x11,0x9,0xff,0x4,0x4,0x4,0x8,0x10,0x60,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0x10,0x24,0xfe,0x40,0x40,0x40,0x42,0x42,0x3e,
-+0x10,0x11,0x15,0x7f,0x55,0x55,0x54,0x55,0x54,0x54,0x57,0x5c,0x10,0x11,0x11,0x16,0x4,0xfe,0x4,0xfc,0x4,0xfc,0x20,0x24,0xac,0x30,0xfe,0x90,0x90,0x12,0x12,0xe,
-+0x10,0x10,0x12,0x11,0x59,0x54,0x57,0x90,0x10,0x10,0x11,0x11,0x11,0x12,0x12,0x1c,0x40,0x40,0x44,0x4c,0x50,0x44,0xfe,0xa0,0xa0,0xa0,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x1,0x41,0x2f,0x21,0x0,0xf,0xe2,0x22,0x23,0x20,0x22,0x22,0x2a,0x32,0x24,0x8,0x10,0x14,0xfe,0x10,0x44,0xfe,0x0,0x8,0xfc,0x0,0x48,0x48,0x48,0x4a,0x4a,0x46,
-+0x4,0x4,0x4,0xff,0x4,0x8,0x8,0xc,0x12,0x10,0x21,0x41,0x82,0x2,0x4,0x18,0x0,0x0,0x4,0xfe,0x80,0x80,0x88,0x98,0xa0,0x80,0x40,0x40,0x20,0x10,0xe,0x4,
-+0x10,0x13,0x12,0x14,0xfb,0x10,0x11,0x1a,0x33,0xd0,0x10,0x17,0x10,0x10,0x50,0x20,0x0,0xfe,0x44,0x48,0xfc,0x80,0x20,0x28,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x10,0x11,0x95,0x56,0x38,0x11,0xfe,0x29,0x29,0x28,0x28,0x2b,0x4c,0x48,0x80,0x0,0x0,0xfe,0x4,0x40,0x48,0xfc,0x80,0x20,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x12,0x12,0x2a,0x2a,0x4f,0x90,0x1f,0x24,0x6f,0xa2,0x25,0x2f,0x22,0x2a,0x32,0x26,0x10,0x10,0x90,0x90,0xbe,0x44,0x84,0xa4,0x24,0x24,0x28,0x98,0x10,0xa8,0x46,0x84,
-+0x10,0x10,0x10,0x17,0x58,0x55,0x51,0x91,0x12,0x12,0x12,0x14,0x14,0x18,0x10,0x13,0x80,0x80,0x84,0xfe,0x80,0x20,0x20,0x24,0xac,0x70,0x20,0x20,0x50,0x50,0x8e,0x4,
-+0x10,0x10,0x11,0x11,0x7d,0x55,0x55,0x55,0x55,0x7d,0x11,0x11,0x15,0xfd,0x5,0x1,0x0,0x4,0xfe,0x4,0x4,0x74,0x54,0x54,0x54,0x54,0x54,0x74,0x4,0x4,0xfc,0x4,
-+0x0,0x0,0x7f,0x40,0x40,0x47,0x44,0x44,0x44,0x44,0x47,0x44,0x40,0x7f,0x40,0x0,0x0,0x4,0xfe,0x4,0x44,0xe4,0x44,0x44,0x44,0x44,0xc4,0x44,0x4,0xfc,0x4,0x0,
-+0x10,0x66,0x42,0x42,0x66,0x42,0x43,0x7e,0x1,0x7e,0x8,0x8,0xe,0xf8,0x40,0x3,0x8,0xfc,0x88,0x88,0x88,0x88,0x6,0x0,0xfc,0x88,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x11,0x11,0x11,0x1a,0x55,0x51,0x51,0x91,0x1f,0x12,0x12,0x12,0x13,0x10,0x10,0x10,0x0,0x8,0xfc,0x0,0xf8,0x8,0x48,0x28,0xfe,0x8,0x88,0x48,0xfc,0x8,0x28,0x10,
-+0x8,0x7e,0x8,0x3e,0x8,0x7e,0x8,0x3f,0x0,0xff,0x0,0x3f,0x9,0x28,0x48,0x7,0x20,0xfc,0x20,0xf8,0x20,0xfc,0x20,0xf8,0x8,0xfe,0x8,0xf8,0x0,0xa8,0x24,0xe0,
-+0x1,0x1,0x1,0x7f,0x1,0x9,0x9,0x8,0xff,0x8,0x8,0x8,0x8,0x10,0x20,0x0,0x0,0x0,0x8,0xfc,0x0,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x1,0x1,0xff,0x1,0x3f,0x21,0x3f,0x21,0x3f,0x1,0x7f,0x2,0x29,0x28,0x48,0x7,0x0,0x4,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x10,0xf8,0x4,0x90,0x8c,0x24,0xe0,
-+0x1,0x1,0x79,0x4a,0x4d,0x49,0x49,0x79,0x4f,0x4a,0x4a,0x4a,0x7b,0x48,0x0,0x0,0x0,0x8,0xfc,0x0,0xf8,0x8,0x48,0x28,0xfe,0x8,0x88,0x48,0xfc,0x8,0x50,0x20,
-+0x4,0x7e,0x44,0x57,0x54,0x54,0x55,0x56,0x54,0x54,0x54,0x54,0x28,0x24,0x44,0x80,0x20,0x20,0x24,0xfe,0x40,0x84,0xfe,0x84,0x84,0xfc,0x84,0x84,0xfc,0x84,0x94,0x88,
-+0x8,0x1c,0xf1,0x11,0x11,0xfd,0x11,0x38,0x34,0x51,0x52,0x90,0x10,0x10,0x10,0x17,0x20,0x20,0x24,0x24,0x24,0xfc,0x44,0x40,0xfe,0x4,0x84,0x48,0x30,0x20,0xc0,0x0,
-+0x1,0x1,0x2,0x4,0x8,0x10,0x2f,0xc0,0x0,0x3f,0x2,0x2,0x4,0x8,0x1f,0x0,0x0,0x0,0x80,0x40,0x20,0x10,0xee,0x4,0x10,0xf8,0x0,0x0,0x40,0x20,0xf0,0x10,
-+0x10,0x10,0x10,0x14,0x59,0x52,0x55,0x90,0x10,0x17,0x10,0x28,0x24,0x41,0x83,0x0,0x40,0x40,0xa0,0x90,0x8,0x26,0xf4,0x0,0x4,0xfe,0x40,0x40,0x90,0x8,0xfc,0x4,
-+0x0,0x40,0x37,0x14,0x4,0x84,0x64,0x24,0xc,0x14,0xe4,0x24,0x24,0x24,0x27,0x20,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x0,0x40,0x2f,0x20,0x0,0x7,0xe0,0x20,0x2f,0x20,0x20,0x24,0x28,0x30,0x20,0x0,0x40,0x44,0xfe,0x40,0x48,0xfc,0x40,0x44,0xfe,0x44,0x44,0x44,0x54,0x48,0x40,0x40,
-+0x1,0x41,0x31,0x12,0x5,0x1,0xf1,0x11,0x17,0x12,0x12,0x12,0x17,0x18,0x10,0x0,0x0,0x8,0xfc,0x0,0xf8,0x8,0x48,0x28,0xfe,0x8,0x88,0x48,0xfc,0x8,0x28,0x10,
-+0x10,0x10,0x20,0x20,0x49,0xfa,0x15,0x20,0x40,0xfb,0x0,0x0,0x18,0xe1,0x43,0x0,0x40,0x40,0xa0,0xa0,0x10,0xe,0xf4,0x0,0x8,0xfc,0x40,0x40,0x90,0x8,0xfc,0x4,
-+0x4,0x4,0x7f,0x4,0x7f,0x42,0x82,0x3f,0x5,0x9,0x1f,0x1,0xff,0x1,0x1,0x1,0x40,0x48,0xfc,0x40,0xfe,0x4,0x8,0xf8,0x0,0x20,0xf0,0x4,0xfe,0x0,0x0,0x0,
-+0x0,0x3f,0x21,0x21,0x3f,0x20,0x28,0x30,0x20,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x78,0x80,0x0,0x10,0xf8,0x80,0x42,0x32,0xe,0xf0,0x10,0x10,0xf0,0x10,0x10,0xf0,
-+0x10,0x11,0x11,0x11,0xfd,0x25,0x25,0x25,0x24,0x45,0x29,0x11,0x29,0x45,0x85,0x1,0xc,0xf0,0x20,0x24,0xfe,0x10,0x50,0x8a,0x6,0xfc,0x4,0x4,0xfc,0x4,0x4,0xfc,
-+0x0,0x11,0x7b,0x2,0xa,0xff,0x22,0x22,0x23,0x42,0x48,0xfd,0x5,0x2,0x4,0x8,0x80,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x80,0xc8,0x48,0x54,0x5c,0x42,0x3e,
-+0x40,0x27,0x24,0x8,0x81,0x67,0x21,0xa,0x14,0x27,0xe0,0x20,0x2f,0x20,0x20,0x20,0x0,0xfe,0x84,0x88,0x0,0xfc,0x40,0x40,0x48,0xfc,0x40,0x44,0xfe,0x40,0x40,0x40,
-+0x40,0x37,0x14,0x4,0x87,0x64,0x24,0xf,0x10,0x24,0xe7,0x24,0x24,0x24,0x25,0x26,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x40,0x48,0x58,0x60,0x40,0xc2,0x42,0x3e,
-+0x20,0x10,0xfe,0x92,0x7d,0x10,0x7c,0x10,0xfe,0x11,0x7c,0x44,0x44,0x44,0x7c,0x44,0x0,0x50,0x48,0x84,0x20,0x20,0x50,0x48,0x86,0xfc,0x88,0x88,0x88,0x88,0xf8,0x88,
-+0x40,0x30,0x17,0x0,0x80,0x60,0x2f,0x8,0x10,0x23,0xe2,0x22,0x22,0x22,0x23,0x22,0x10,0x38,0xc0,0x40,0x40,0x44,0xfe,0x40,0x48,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x8,0x8,0x8,0x10,0x12,0x32,0x52,0x94,0x10,0x10,0x10,0x11,0x11,0x12,0x14,0x18,0x40,0x40,0x40,0x40,0x44,0x4c,0x50,0x60,0x40,0xa0,0xa0,0x10,0x10,0x8,0xe,0x4,
-+0x1,0x1,0x1,0x1,0x11,0x11,0x11,0x21,0x42,0x2,0x4,0x4,0x8,0x10,0x20,0x40,0x0,0x0,0x0,0x0,0x8,0x18,0x20,0x40,0x80,0x80,0x40,0x40,0x20,0x10,0xe,0x4,
-+0x4,0x4,0xff,0x4,0x24,0x18,0x10,0x2b,0x48,0x8,0x18,0x28,0xc8,0x8,0x29,0x12,0x40,0x44,0xfe,0x40,0x28,0x24,0x20,0xfe,0x20,0x20,0x20,0x50,0x50,0x88,0x6,0x4,
-+0x0,0x0,0x0,0xff,0x0,0x2,0x3f,0x22,0x22,0x22,0x3e,0x20,0x7,0x78,0x0,0x3,0x50,0x48,0x40,0xfe,0x40,0x40,0x48,0x48,0x48,0x50,0x50,0x20,0x22,0x52,0x8a,0x4,
-+0x0,0x0,0xff,0x0,0x3e,0x22,0x3e,0x20,0xe,0x70,0x0,0x2,0x29,0x28,0x48,0x7,0xa0,0x94,0xfe,0x80,0x88,0x88,0x50,0x50,0x22,0x52,0x8e,0x0,0x90,0xac,0x24,0xe0,
-+0x3f,0x1,0x7f,0x41,0x9d,0x1,0x1d,0x8,0x1f,0x30,0x57,0x90,0x17,0x10,0x1f,0x10,0xf8,0x0,0xfe,0x2,0x74,0x0,0x70,0x80,0xfc,0x80,0xf8,0x80,0xf8,0x80,0xfe,0x0,
-+0x8,0x8,0x10,0x30,0x57,0x90,0x10,0x10,0x1f,0x10,0x11,0x11,0x11,0x2,0xc,0x30,0x80,0x88,0x98,0xe0,0x82,0x82,0x7e,0x10,0xf8,0x10,0x10,0x10,0x10,0xc0,0x30,0x8,
-+0x40,0x23,0x22,0x2,0xfa,0x13,0x20,0x70,0xaf,0x24,0x24,0x24,0x25,0x24,0x24,0x24,0x8,0xfc,0x8,0x8,0x8,0xf8,0x40,0x44,0xfe,0x44,0x44,0xb4,0x14,0x4,0x14,0x8,
-+0x1,0x1,0x1,0x7f,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x21,0x21,0x21,0x3f,0x20,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x17,0x11,0x11,0x11,0xfd,0x11,0x11,0x11,0x11,0x1e,0xf2,0x44,0x4,0x9,0x12,0x8,0xfc,0x8,0x8,0x10,0x10,0x3c,0x84,0x88,0x48,0x50,0x20,0x50,0x90,0xe,0x4,
-+0x8,0x8,0x7f,0x8,0xf,0x8,0xf,0x8,0xff,0x4,0x9,0x31,0xcf,0x1,0x1,0x3f,0x20,0x28,0xfc,0x20,0xe0,0x20,0xe0,0x24,0xfe,0x40,0x30,0x4e,0xe4,0x0,0x10,0xf8,
-+0x10,0x10,0x11,0x11,0xfd,0x11,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x12,0x14,0x18,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x0,0x4,0x7f,0x54,0x54,0x54,0x7f,0x54,0x55,0x55,0x7d,0x45,0x1,0x1,0x0,0x0,0x20,0x28,0xfc,0x20,0x50,0x88,0xfe,0x8,0xe8,0x28,0x28,0x28,0xe8,0x8,0x28,0x10,
-+0x8,0x1c,0xf3,0x10,0x10,0xfd,0x13,0x31,0x39,0x55,0x50,0x91,0x11,0x11,0x11,0x11,0x50,0x48,0xfc,0xa0,0xa2,0x3e,0x0,0xf0,0x4,0xfc,0x0,0xf8,0x8,0xf8,0x8,0xf8,
-+0x4,0xe,0x78,0x8,0x8,0xfe,0x8,0x18,0x1c,0x2a,0x28,0x48,0x88,0x9,0xa,0x8,0x0,0x4,0xfe,0x84,0x84,0x84,0x84,0x84,0xfc,0x84,0x0,0x88,0xc4,0x6,0x2,0x0,
-+0x12,0x1f,0x28,0x45,0x88,0x3f,0x8,0xf,0x8,0xf,0x8,0xff,0x0,0x8,0x18,0x20,0x44,0x7e,0xa0,0x10,0x20,0xf8,0x20,0xe0,0x20,0xe0,0x24,0xfe,0x0,0x20,0x18,0x8,
-+0x4,0x3e,0x24,0x24,0x24,0x3c,0x24,0x24,0x24,0x3c,0x24,0x24,0x24,0x24,0x4d,0x86,0x0,0x8,0xfc,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x8a,0x8a,0x6,0x0,
-+0x20,0x20,0x21,0x3d,0x25,0x49,0x41,0xa1,0x21,0x21,0x21,0x25,0x29,0x32,0x24,0x8,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x1,0x40,0x20,0x2f,0x1,0x1,0xe5,0x25,0x25,0x29,0x21,0x21,0x22,0x50,0x8f,0x0,0x0,0xc0,0x48,0xfc,0x20,0x20,0x28,0x24,0x24,0x24,0x20,0x20,0x60,0x6,0xfc,0x0,
-+0x2,0x44,0x2f,0x28,0xf,0x88,0x4f,0x42,0x1f,0x24,0xc7,0x44,0x44,0x48,0x4a,0x51,0x10,0x90,0xd0,0x94,0xbe,0xc4,0xa4,0x28,0xa8,0x28,0x90,0x90,0xa8,0xa8,0xc6,0x84,
-+0x0,0x20,0x11,0x11,0x1,0xf1,0x11,0x11,0x11,0x11,0x11,0x15,0x19,0x12,0x4,0x8,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x0,0x0,0x1,0xfd,0x5,0x49,0x29,0x11,0x11,0x29,0x24,0x40,0x87,0x0,0x0,0x0,0x40,0x88,0xfc,0x8,0x48,0x8,0x28,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x10,0x11,0x11,0x11,0xfd,0x25,0x25,0x25,0x25,0x45,0x29,0x11,0x29,0x45,0x85,0x0,0x4,0xfe,0x10,0x10,0x14,0x7e,0x44,0x44,0x44,0x44,0x7c,0x10,0x10,0x14,0xfe,0x0,
-+0x10,0x10,0x27,0x20,0x49,0xf8,0x17,0x20,0x43,0xfa,0x2,0x2,0x1a,0xe0,0x41,0x6,0x40,0x48,0xfc,0x40,0xf0,0x40,0xfe,0x8,0xfc,0x8,0x48,0x48,0x48,0x90,0xc,0x4,
-+0x10,0x11,0x21,0x21,0x49,0xf8,0x17,0x21,0x41,0xf9,0x1,0x1,0x19,0xe7,0x40,0x0,0x8,0xfc,0x8,0x8,0xf8,0x4,0xfe,0x8,0xf8,0x8,0xf8,0x8,0x8,0xfe,0x8,0x8,
-+0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x3f,0x0,0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x0,0x0,0x4,0xfe,0x0,0x0,0x10,0xf8,0x0,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,
-+0x10,0x17,0x11,0x11,0xfd,0x11,0x31,0x39,0x55,0x51,0x92,0x12,0x12,0x14,0x19,0x12,0x8,0xfc,0x8,0x8,0x10,0x10,0x3c,0x84,0x88,0x48,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x10,0x14,0xfe,0x10,0x14,0x7e,0x54,0x54,0x54,0x54,0x38,0x54,0x93,0x12,0x10,0x10,0x20,0x24,0xfe,0x20,0x28,0xfc,0xa8,0xa8,0xa8,0xa8,0x70,0xa8,0x26,0x24,0x20,0x20,
-+0x10,0x11,0x11,0xfd,0x21,0x28,0x4b,0x7d,0x9,0x9,0xf,0xf9,0x49,0xf,0x8,0x8,0x8,0xfc,0x8,0x8,0xf8,0x4,0xfe,0x8,0xf8,0x8,0xf8,0x8,0x8,0xfe,0x8,0x8,
-+0x10,0x14,0x3e,0x49,0x90,0x7d,0x10,0x7c,0x13,0xfe,0x11,0x39,0x55,0x91,0x11,0x11,0x40,0x48,0xfc,0x20,0x90,0xfc,0x90,0x94,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,
-+0x9,0x8,0x1f,0x31,0x5f,0x91,0x1f,0x11,0x1f,0x11,0xff,0x5,0x9,0x11,0x61,0x1,0x0,0x90,0xf8,0x0,0xf0,0x0,0xf0,0x0,0xf8,0x0,0xfe,0x40,0x20,0x1c,0x8,0x0,
-+0x0,0x7f,0x8,0x8,0x8,0x8,0x8,0x8,0x14,0x12,0x11,0x20,0x21,0x42,0x84,0x8,0x0,0xf0,0x20,0x20,0x40,0x40,0xf8,0x8,0x10,0x20,0x40,0x80,0x40,0x30,0xe,0x4,
-+0x4,0x4,0xf,0x8,0x10,0x3f,0x40,0x1f,0x0,0x3f,0x2,0x51,0x50,0x90,0xf,0x0,0x0,0x0,0xe0,0x40,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x0,0x84,0x92,0x12,0xf0,0x0,
-+0x1,0x0,0x1f,0x12,0x92,0x53,0x54,0x18,0x30,0x5f,0xd0,0x10,0x20,0x21,0x42,0xc,0x0,0x84,0xfe,0x0,0x8,0xfc,0x40,0x40,0x44,0xfe,0x40,0xa0,0xa0,0x10,0xe,0x4,
-+0x40,0x37,0x11,0x1,0x81,0x61,0x25,0x9,0x11,0x21,0xe2,0x22,0x22,0x24,0x29,0x22,0x8,0xfc,0x8,0x8,0x10,0x10,0x3c,0x84,0x88,0x48,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x0,0x7e,0x42,0x42,0x7e,0x42,0x42,0x7e,0x40,0x44,0x44,0x4a,0x72,0x40,0x0,0x0,0x4,0xfe,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0xa4,0x94,0x88,0x80,0x80,0x80,0x80,
-+0x20,0x20,0x21,0x21,0xf9,0x4d,0x4b,0x49,0x49,0x8b,0x55,0x51,0x22,0x52,0x8c,0x8,0x20,0x14,0xfe,0x40,0x48,0x7c,0x50,0x90,0x14,0xfe,0x10,0x10,0x20,0x28,0x46,0x82,
-+0x10,0x17,0x21,0x21,0x49,0xf9,0x11,0x21,0x41,0xf9,0x2,0x2,0x1a,0xe4,0x49,0x2,0x8,0xfc,0x8,0x8,0x10,0x10,0x3c,0x84,0x88,0x48,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x10,0x10,0x17,0x10,0xfd,0x10,0x14,0x19,0x36,0xd1,0x11,0x11,0x11,0x11,0x52,0x24,0x80,0x48,0xfc,0x8,0x10,0xa0,0x40,0xb0,0xe,0x14,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x0,0xf,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x10,0x20,0x40,0x40,0xe0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x1,0x21,0x11,0xa,0x12,0x24,0x8,0x1f,0x28,0xcf,0x8,0xf,0x8,0x8,0x8,0x8,0x0,0x8,0x10,0xa0,0x98,0x48,0x20,0xf0,0x2e,0xe4,0x20,0xe0,0x20,0x20,0xa0,0x40,
-+0x0,0x0,0x7f,0x0,0x0,0x0,0x0,0x3f,0x20,0x20,0x20,0x20,0x20,0x20,0x1f,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0xf0,0x10,0x0,0x0,0x0,0x4,0x4,0xfc,0x0,
-+0x4,0x4,0xff,0x4,0x8,0x1f,0x22,0x7f,0x24,0x3f,0x24,0x3f,0x20,0x3,0x7c,0x0,0x40,0x44,0xfe,0x40,0x4,0x24,0x24,0xa4,0xa4,0xa4,0xa4,0xa4,0x4,0x84,0x14,0x8,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x10,0x13,0x1a,0x31,0xd1,0x10,0x10,0x10,0x51,0x26,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0xf8,0x8,0x10,0x10,0xa0,0x40,0xb0,0xe,0x4,
-+0x2,0x7e,0x2,0xfe,0x0,0x3f,0x21,0x3f,0x21,0x3f,0x4,0x3f,0x4,0xff,0x10,0x60,0x80,0xf8,0x82,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x40,0xf8,0x40,0xfe,0x10,0xc,
-+0x0,0x1f,0x1,0x1,0x7f,0x5,0x9,0x11,0x6f,0x0,0x0,0xff,0x1,0x1,0x5,0x2,0xe0,0x0,0x0,0x8,0xfc,0x40,0x20,0x1c,0xe8,0x40,0x84,0xfe,0x0,0x0,0x0,0x0,
-+0x8,0x8,0x8,0x17,0x10,0x30,0x50,0x93,0x12,0x11,0x11,0x10,0x10,0x10,0x11,0x16,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0xf8,0x8,0x10,0x10,0xa0,0x40,0xb0,0xe,0x4,
-+0x10,0x10,0x1e,0x22,0x52,0xcc,0x28,0x17,0x20,0xc0,0x1f,0x1,0x9,0x11,0x25,0x2,0x0,0x0,0xfc,0x88,0x50,0x20,0x20,0xd0,0xe,0x24,0xf0,0x0,0x40,0x30,0x10,0x0,
-+0x8,0x4,0x7f,0x11,0xa,0x4,0xa,0x31,0xd1,0x11,0x11,0x11,0x11,0x21,0x41,0x0,0x4,0x84,0xc4,0x24,0x24,0x24,0x24,0xa4,0x64,0x24,0x24,0x24,0x4,0x4,0x14,0x8,
-+0x10,0x13,0x10,0x18,0x57,0x50,0x51,0x92,0x15,0x10,0x10,0x1f,0x10,0x10,0x11,0x10,0x38,0xc0,0x40,0x48,0xfc,0xe0,0x50,0x4e,0xf4,0x20,0x44,0xfe,0x40,0x40,0x40,0x80,
-+0x0,0x40,0x37,0x11,0x80,0x60,0x21,0xe,0x11,0x21,0xe1,0x21,0x21,0x22,0x24,0x20,0x80,0x44,0xfe,0x10,0xa0,0x40,0xb0,0xe,0x14,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x2,0x1,0x7f,0x41,0x81,0x1f,0x2,0x4,0xff,0x0,0x1f,0x10,0x10,0x1f,0x10,0x0,0x0,0x0,0xfe,0x2,0x24,0xf0,0x80,0x44,0xfe,0x10,0x90,0x90,0x90,0x90,0x50,0x20,
-+0x2,0x1,0x7f,0x40,0x88,0xe,0x8,0x8,0xff,0x8,0x2c,0x2b,0x49,0x88,0x28,0x13,0x0,0x0,0xfe,0x2,0x4,0xf8,0x8,0x88,0x88,0x50,0x50,0x20,0x20,0x50,0x8e,0x4,
-+0x0,0x20,0x10,0x10,0x0,0x0,0xf7,0x10,0x10,0x10,0x10,0x12,0x14,0x18,0x10,0x0,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x20,0x17,0x10,0x0,0x0,0xf0,0x13,0x12,0x12,0x12,0x12,0x16,0x1a,0x11,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x2,0x2,0x2,0xfe,0x0,
-+0x0,0x7d,0x44,0x44,0x7d,0x45,0x45,0x45,0x7c,0x40,0x48,0x44,0x5c,0x60,0x41,0x6,0x8,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x50,0x50,0x92,0x92,0xe,0x0,
-+0x0,0x7f,0x0,0x0,0x3f,0x20,0x20,0x20,0x1f,0x0,0x52,0x51,0x50,0x90,0xf,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x4,0x4,0xfc,0x0,0x4,0x82,0x92,0x12,0xf0,0x0,
-+0x0,0x7d,0x44,0x48,0x48,0x50,0x4b,0x48,0x44,0x44,0x44,0x69,0x52,0x40,0x40,0x40,0x8,0xfc,0x0,0x0,0x0,0x4,0xfe,0x20,0x20,0xa8,0xa4,0x22,0x22,0x20,0xa0,0x40,
-+0x10,0x10,0x10,0x13,0xfc,0x24,0x24,0x25,0x25,0x44,0x28,0x10,0x28,0x44,0x84,0x3,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0xfc,0x4,0x88,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x10,0x12,0x22,0x23,0x4a,0xfa,0x12,0x23,0x42,0xfa,0x42,0x3,0x1a,0xe2,0x43,0x0,0x20,0x20,0x20,0x24,0xac,0x70,0x20,0xfc,0x20,0x70,0xac,0x24,0x20,0x24,0xfe,0x0,
-+0x8,0x8,0x13,0x10,0x24,0xfc,0x8,0x11,0x21,0xfd,0x41,0x1,0x1d,0xe1,0x40,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x1,0x7f,0x1,0x3f,0x0,0x1f,0x10,0x1f,0x4,0xff,0x10,0x7e,0x12,0x12,0x2a,0x44,0x8,0xfc,0x0,0xf8,0x0,0xf0,0x10,0xf0,0x44,0xfe,0x8,0xfc,0x88,0x88,0xf8,0x88,
-+0x12,0x12,0x12,0x12,0xfe,0x17,0x32,0x3a,0x56,0x52,0x92,0x12,0x14,0x15,0x18,0x10,0x0,0x0,0x0,0x4,0x1e,0xd4,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x5c,0x94,0x0,
-+0x1,0x1,0x1,0x7f,0x1,0x11,0x9,0x1,0xff,0x1,0x2,0x2,0x4,0x8,0x30,0xc0,0x0,0x0,0x8,0xfc,0x0,0x10,0x20,0x4,0xfe,0x0,0x80,0x80,0x40,0x30,0xe,0x4,
-+0x8,0x8,0x8,0x17,0x10,0x30,0x5f,0x90,0x10,0x10,0x17,0x10,0x10,0x10,0x1f,0x10,0x40,0x40,0x48,0xfc,0x40,0x44,0xfe,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x0,
-+0x2,0x1,0x7f,0x40,0x80,0x3f,0x4,0x1a,0x63,0x5,0x19,0x63,0x5,0x19,0x65,0x2,0x0,0x0,0xfe,0x2,0x4,0xf8,0x0,0x10,0x30,0x40,0x80,0x40,0x30,0xe,0x4,0x0,
-+0x10,0x10,0x10,0x12,0xff,0x12,0x12,0x12,0x12,0x22,0x22,0x22,0x22,0x4a,0x84,0x0,0x0,0x0,0x4,0x7e,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x7c,0x44,0x0,
-+0x4,0x4,0xff,0x4,0x1,0x7f,0x1,0x9,0x5,0xff,0x1,0x2,0x4,0x8,0x30,0xc0,0x40,0x44,0xfe,0x40,0x8,0xfc,0x0,0x20,0x44,0xfe,0x0,0x80,0x40,0x30,0xe,0x4,
-+0x10,0x13,0x10,0xfe,0x11,0x55,0x39,0x11,0xff,0x11,0x11,0x29,0x25,0x44,0x81,0x2,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x44,0x54,0x8c,0x4,0x2,
-+0x0,0xff,0x4,0x7f,0x44,0x44,0x7f,0x0,0x1f,0x10,0x11,0x11,0x11,0x2,0xc,0x30,0x4,0xfe,0x40,0xfc,0x44,0x44,0xfc,0x10,0xf8,0x10,0x10,0x10,0x10,0x60,0x18,0x8,
-+0x0,0x3f,0x21,0x21,0x21,0x3f,0x21,0x21,0x21,0x3f,0x21,0x1,0x1,0x1,0x1,0x1,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x10,0x11,0x1d,0x21,0x21,0x7d,0x91,0x11,0xfd,0x11,0x11,0x14,0x18,0x10,0x0,0x0,0x4,0xfe,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0xfc,0x24,0x20,0x20,0x20,0x20,
-+0x10,0x17,0x14,0x24,0x24,0x67,0xa4,0x24,0x27,0x24,0x24,0x27,0x24,0x24,0x25,0x26,0x4,0xbe,0x84,0x84,0x84,0xbc,0x0,0x7c,0x84,0x88,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x8,0x1c,0xf3,0x12,0x10,0xfd,0x10,0x39,0x36,0x54,0x51,0x92,0x14,0x11,0x12,0x10,0x40,0x20,0xfe,0x2,0x4,0xfc,0x80,0x44,0x6c,0xb0,0x30,0x68,0xa8,0x26,0xa4,0x40,
-+0x8,0x8,0x8,0x10,0x11,0x32,0x54,0x99,0x11,0x11,0x11,0x11,0x11,0x11,0x12,0x14,0x40,0x40,0x40,0xa0,0x10,0x8,0x6,0x14,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x10,0x10,0x7e,0x12,0x12,0x12,0x2a,0x44,0x1,0xff,0x3,0x5,0x9,0x11,0x61,0x1,0x0,0x8,0xfc,0x88,0x88,0x88,0xf8,0x80,0x4,0xfe,0x80,0x40,0x20,0x1c,0x8,0x0,
-+0x10,0x10,0x7f,0x11,0x11,0x25,0x42,0x9f,0x0,0x8,0x8,0xf,0x0,0x7f,0x0,0x0,0x0,0x4,0x7e,0x44,0x44,0x7c,0x44,0xe0,0x20,0x20,0x24,0xfe,0x4,0xc4,0x14,0x8,
-+0x10,0x10,0x13,0x12,0xfc,0x25,0x24,0x25,0x26,0x44,0x29,0x12,0x28,0x45,0x84,0x0,0x40,0x20,0xfe,0x2,0x4,0xfc,0x80,0x44,0x6c,0xb0,0x30,0x68,0xa8,0x26,0xa4,0x40,
-+0x4,0x7e,0x11,0x10,0x10,0x3e,0x22,0x63,0x92,0xc,0x4,0x8,0x10,0x20,0x40,0x0,0x8,0x1c,0xe0,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x4,0x4,0x24,0x24,0x24,0x25,0x24,0x24,0x4,0x3f,0x24,0x24,0x24,0x24,0xff,0x0,0x40,0x40,0x48,0x7c,0xa0,0x18,0x8,0x0,0x8,0xfc,0x48,0x48,0x48,0x48,0xfe,0x0,
-+0x4,0x25,0x25,0x24,0x24,0x24,0x24,0x24,0x27,0x5,0x1,0x3f,0x1,0x1,0xff,0x0,0x0,0xf8,0x8,0x90,0x90,0x60,0x20,0xd0,0xe,0x4,0x10,0xf8,0x0,0x4,0xfe,0x0,
-+0x1,0x1,0x9,0xd,0x11,0x21,0x0,0x1,0xff,0x1,0x2,0x2,0x4,0x8,0x30,0xc0,0x0,0x0,0x20,0x10,0x18,0x8,0x0,0x4,0xfe,0x0,0x80,0x80,0x40,0x30,0xe,0x4,
-+0x10,0x14,0x3e,0x48,0x2,0x2,0x7f,0x2,0x1,0x7f,0x1,0x1,0x0,0x7,0x38,0x0,0x40,0x48,0xfc,0x20,0x80,0x50,0xf8,0x0,0x4,0xfe,0x10,0x20,0xc0,0x44,0x24,0x1c,
-+0x20,0x1b,0x8,0x40,0x4f,0x48,0x48,0x48,0x4f,0x48,0x48,0x48,0x4f,0x48,0x40,0x40,0x4,0xfe,0x4,0x24,0xf4,0x24,0x24,0x24,0xe4,0x24,0x24,0x24,0xe4,0x24,0x14,0x8,
-+0x8,0x4,0xff,0x2,0x3f,0x22,0x3e,0x22,0x3e,0x22,0x22,0x26,0x0,0x24,0x22,0x40,0x20,0x44,0xfe,0x0,0x8,0x48,0x48,0x48,0x48,0x48,0x8,0x18,0x0,0x90,0x4c,0x4,
-+0x10,0x8,0x7f,0x4,0x3f,0x4,0x4,0xff,0x4,0x4,0x3f,0xc,0x14,0x24,0xc4,0x4,0x20,0x48,0xfc,0x90,0xf8,0x90,0x94,0xfe,0x90,0x90,0xf0,0xc0,0xb0,0x8e,0x84,0x80,
-+0x2,0x1,0x1f,0x10,0x10,0x1f,0x10,0x17,0x14,0x17,0x14,0x27,0x24,0x44,0x84,0x4,0x0,0x8,0xfc,0x8,0x8,0xf8,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x0,0x1,0x7d,0x5,0x45,0x29,0x29,0x11,0x11,0x29,0x29,0x45,0x85,0x1,0x1,0x1,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x44,0x4c,0x30,0x20,0x10,0x4e,0x84,0x0,
-+0x10,0x11,0x10,0x14,0xfe,0x24,0x24,0x27,0x24,0x44,0x28,0x10,0x28,0x44,0x84,0x0,0x8,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x10,0x10,0x20,0x27,0x44,0xfc,0x15,0x24,0x45,0xfd,0x45,0x5,0x1d,0xe5,0x48,0x10,0x10,0x18,0x14,0xfe,0x10,0x10,0xd0,0x14,0xd4,0x54,0x54,0x58,0xd0,0x2a,0x46,0x82,
-+0x8,0x8,0xff,0x8,0x9,0x1,0x3f,0x21,0x21,0x21,0x3f,0x21,0x1,0x1,0x7f,0x0,0x20,0x24,0xfe,0x20,0x20,0x8,0xfc,0x8,0x8,0x8,0xf8,0x0,0x10,0xf8,0x4,0x4,
-+0x10,0x10,0x10,0x10,0xfd,0x12,0x35,0x30,0x58,0x56,0x91,0x11,0x11,0x10,0x1f,0x10,0x40,0x40,0xa0,0xa0,0x10,0xe,0xf4,0x0,0x40,0x48,0x4c,0x48,0x50,0x4,0xfe,0x0,
-+0x1,0x1,0xff,0x1,0x3f,0x21,0x29,0x25,0x21,0x3f,0x23,0x5,0x9,0x31,0xc1,0x1,0x0,0x4,0xfe,0x8,0xfc,0x8,0x28,0x48,0x8,0xf8,0x88,0x40,0x30,0xe,0x4,0x0,
-+0x0,0x10,0xf8,0x27,0x24,0x44,0x55,0x7c,0xd5,0x55,0x55,0x55,0x55,0x75,0x48,0x10,0x10,0x18,0x14,0xfe,0x10,0x10,0xd0,0x14,0xd4,0x54,0x54,0x58,0xd0,0x2a,0x46,0x82,
-+0x0,0x8,0xfc,0x10,0x11,0x22,0x2d,0x78,0xa8,0x2a,0x29,0x29,0x29,0x38,0x27,0x0,0x40,0x40,0xa0,0xa0,0x10,0xe,0xf4,0x0,0x40,0x48,0x4c,0x48,0x50,0x4,0xfe,0x0,
-+0x10,0x10,0x13,0x10,0xfc,0x13,0x11,0x1e,0x33,0xd0,0x10,0x10,0x11,0x12,0x54,0x20,0x40,0x44,0xfe,0x80,0x80,0xe0,0x20,0x24,0xfe,0x20,0x20,0xa8,0x24,0x22,0xa2,0x40,
-+0x10,0x10,0x10,0x10,0xfd,0x12,0x15,0x18,0x30,0xd2,0x11,0x11,0x11,0x10,0x57,0x20,0x40,0x40,0xa0,0xa0,0x10,0xe,0xf4,0x0,0x40,0x48,0x4c,0x48,0x50,0x4,0xfe,0x0,
-+0x12,0x1f,0x28,0x45,0x90,0x2b,0x20,0x27,0x24,0x24,0x27,0x24,0x24,0x27,0x20,0x20,0x44,0x7e,0xa0,0x10,0x8,0xfc,0x8,0xc8,0x48,0x48,0xc8,0x48,0x48,0xc8,0x28,0x10,
-+0x8,0x8,0x8,0x10,0x11,0x32,0x55,0x98,0x10,0x12,0x11,0x11,0x11,0x10,0x1f,0x10,0x40,0x40,0xa0,0xa0,0x10,0x8,0xf6,0x4,0x40,0x48,0x4c,0x48,0x50,0x4,0xfe,0x0,
-+0x8,0x4,0xff,0x2,0x3f,0x22,0x3e,0x22,0x3e,0x22,0x26,0x7f,0x4,0x4,0x18,0x60,0x20,0x44,0xfe,0x0,0x48,0x48,0x48,0x48,0x48,0x18,0x8,0xfc,0x8,0x8,0x28,0x10,
-+0x0,0x40,0x30,0x17,0x4,0x4,0xd,0x14,0x25,0xe5,0x25,0x25,0x25,0x25,0x8,0x10,0x10,0x18,0x14,0xfe,0x10,0x10,0xd0,0x14,0xd4,0x54,0x54,0x58,0xd0,0x2a,0x46,0x82,
-+0x8,0x8,0xff,0xa,0x2,0x7f,0x4,0xb,0x10,0x10,0x3f,0x50,0x90,0x10,0x11,0x10,0x20,0x24,0xfe,0x20,0x8,0xfc,0x0,0xf0,0x20,0x44,0xfe,0x40,0x40,0x40,0x40,0x80,
-+0x10,0x10,0x12,0x12,0xfe,0x12,0x32,0x38,0x54,0x53,0x92,0x12,0x12,0x12,0x1f,0x10,0x80,0x90,0x94,0xbe,0xd0,0x8c,0x84,0x80,0x8,0xfc,0xa8,0xa8,0xa8,0xa8,0xfe,0x0,
-+0x4,0x24,0x24,0x25,0x26,0x25,0x1,0x6,0x18,0x6f,0x81,0x1f,0x9,0x5,0x7f,0x0,0x40,0x48,0xfc,0x40,0x30,0x10,0x0,0xc0,0x30,0xee,0x4,0xf0,0x20,0x48,0xfc,0x0,
-+0x4,0x7e,0x44,0x44,0x44,0x7d,0x10,0x10,0x53,0x5c,0x50,0x50,0x5c,0x70,0xc3,0x0,0x40,0x50,0x48,0x40,0x7c,0xc0,0x48,0x7c,0xc0,0x48,0x50,0x20,0x60,0x92,0xa,0x6,
-+0x4,0x7e,0x44,0x54,0x54,0x55,0x54,0x54,0x57,0x54,0x54,0x54,0x10,0x28,0x47,0x84,0x40,0x50,0x48,0x40,0x7c,0xc0,0x48,0x7c,0xc0,0x48,0x50,0x20,0x60,0x92,0xa,0x6,
-+0x0,0x1f,0x10,0x11,0x11,0x11,0x11,0x11,0x11,0x12,0x12,0x4,0x4,0x8,0x30,0xc0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x80,0x82,0x82,0x7e,0x0,
-+0x20,0x27,0x39,0x41,0x82,0x7a,0x24,0x27,0xf9,0x21,0x25,0x22,0x2a,0x35,0x28,0x0,0x10,0x10,0x7c,0x14,0xfe,0x14,0x7c,0x10,0x7c,0x10,0x14,0xfe,0x10,0x10,0x96,0x7c,
-+0x10,0x1e,0x28,0x45,0x8,0x4,0xff,0x2,0x3f,0x22,0x3e,0x22,0x3e,0x22,0x2a,0x24,0x40,0x7c,0x90,0x8,0x20,0x44,0xfe,0x8,0x8,0x48,0x48,0x48,0x48,0x48,0x8,0x18,
-+0x10,0x10,0x12,0x22,0x23,0x64,0xa4,0x28,0x20,0x3f,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x10,0x10,0x10,0x2e,0x23,0x62,0xa4,0x28,0x2f,0x22,0x32,0x2d,0x24,0x2a,0x31,0x20,0x20,0x20,0xfc,0x24,0xfe,0x24,0xfc,0x20,0xfe,0x20,0x24,0xfe,0x20,0x20,0x26,0xfc,
-+0x8,0x10,0x3e,0x22,0x22,0x32,0x2a,0x22,0xfe,0x22,0x32,0x2a,0x22,0x22,0x4a,0x85,0x0,0x4,0xfe,0x84,0x94,0x94,0x94,0x94,0xa4,0xa4,0x20,0x50,0x50,0x52,0x92,0xe,
-+0x4,0x4,0xa,0x11,0x20,0x42,0xbf,0x0,0x24,0x14,0x15,0x15,0x3,0x7c,0x20,0x0,0x4,0x4,0x4,0x24,0xa4,0x64,0x24,0x24,0xa4,0xa4,0x24,0x24,0x84,0x4,0x14,0x8,
-+0x20,0x20,0x20,0x3c,0x24,0x4b,0x40,0xa0,0x23,0x20,0x20,0x24,0x28,0x30,0x23,0x0,0x40,0x50,0x48,0x40,0x7c,0xc0,0x48,0x7c,0xc0,0x48,0x50,0x20,0x60,0x92,0xa,0x6,
-+0x2,0x42,0x22,0x2f,0x4,0x85,0x69,0x2f,0x11,0x21,0xe1,0x3f,0x29,0x21,0x21,0x21,0x0,0xc,0x30,0xe0,0x20,0x24,0x3e,0xe8,0x28,0x28,0xe8,0x28,0x28,0x48,0x88,0x8,
-+0x0,0x40,0x2f,0x28,0xa,0x8a,0x4a,0x4a,0x1a,0x2a,0xca,0x4a,0x42,0x45,0x48,0x50,0x20,0x20,0xa4,0xae,0xf0,0xa0,0xae,0xf0,0xa4,0xa4,0xa8,0x90,0x30,0x4a,0x8a,0x6,
-+0x2,0x41,0x34,0x14,0x84,0x65,0x25,0xd,0x15,0x25,0xe5,0x25,0x25,0x24,0x24,0x24,0x4,0xbe,0x84,0x4,0x4,0xf4,0x14,0x14,0xf4,0x14,0x14,0xf4,0x14,0x4,0x14,0x8,
-+0x0,0x0,0xfb,0x8,0x17,0x10,0x3b,0x8,0x8b,0x50,0x50,0x37,0x20,0x50,0x88,0x7,0x40,0x48,0xfc,0x48,0xfe,0x48,0xf8,0x40,0xf8,0x40,0x48,0xfc,0x40,0x40,0x46,0xfc,
-+0x10,0x1f,0x10,0x27,0x24,0x67,0xa4,0x2f,0x20,0x27,0x24,0x27,0x24,0x27,0x20,0x2f,0x4,0xfe,0x0,0xfc,0x44,0xfc,0x44,0xfe,0x0,0xfc,0x44,0xfc,0x44,0xfc,0x0,0xfe,
-+0x8,0x4,0x7f,0x1,0x3f,0x1,0x7f,0x2,0x2,0xff,0x4,0x8,0x6,0x1,0x6,0x38,0x20,0x48,0xfc,0x0,0xf8,0x0,0xfc,0x0,0x4,0xfe,0x20,0x20,0xc0,0x80,0x60,0x10,
-+0x10,0x10,0x11,0x91,0x73,0x34,0x10,0x10,0x1f,0x30,0x52,0xd1,0x10,0x10,0x10,0x10,0x80,0x80,0xf8,0x8,0x10,0xa0,0x40,0x94,0xfe,0x10,0x10,0x90,0x90,0x10,0x50,0x20,
-+0x4,0x44,0x24,0x4,0x15,0x24,0x64,0x5,0x1,0x7d,0x5,0x9,0x9,0x11,0x65,0x2,0x40,0x40,0x7c,0x84,0x48,0x30,0x20,0x40,0x8,0x98,0x60,0x20,0x10,0xe,0x4,0x0,
-+0x40,0x30,0x17,0x0,0x80,0x60,0x20,0x8,0x10,0x20,0xe0,0x20,0x20,0x2f,0x20,0x20,0x0,0x8,0xfc,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,0x0,
-+0x0,0xff,0x4,0x5,0x7d,0x45,0x41,0x43,0x7c,0x25,0x75,0x25,0x35,0xc5,0x14,0xb,0x4,0xfe,0x0,0xfc,0x24,0xfc,0x24,0xfe,0x0,0xfc,0x24,0xfc,0x24,0xfc,0x0,0xfe,
-+0x4,0x4,0xff,0x4,0x4,0x8,0x49,0x2a,0x28,0x8,0x1f,0x28,0x49,0x88,0x8,0x8,0x40,0x44,0xfe,0x40,0x40,0xf8,0x8,0xb0,0x50,0x94,0xfe,0x10,0x10,0x90,0x10,0x30,
-+0x4,0x44,0x24,0x4,0x15,0x24,0x64,0x5,0x1,0xff,0x5,0x9,0x11,0x21,0xc1,0x1,0x40,0x40,0x7c,0x84,0x48,0x30,0x20,0x40,0x4,0xfe,0x40,0x20,0x10,0xe,0x4,0x0,
-+0x4,0x44,0x24,0x4,0x15,0x24,0x64,0x4,0x1,0xff,0x1,0x2,0x4,0x8,0x30,0xc0,0x40,0x40,0x7c,0x84,0x48,0x30,0x20,0x40,0x4,0xfe,0x0,0x80,0x40,0x30,0xe,0x4,
-+0x1,0x21,0x11,0x17,0x1,0x1,0xf1,0x11,0x1f,0x11,0x11,0x15,0x19,0x11,0x2,0x0,0x10,0x10,0x10,0xfc,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x0,0x7f,0x40,0x40,0x4f,0x48,0x48,0x4f,0x48,0x48,0x48,0x50,0x60,0x40,0x7f,0x0,0x8,0xfc,0x20,0x70,0x80,0x0,0x10,0xf8,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x4,0x44,0x24,0xd,0x16,0x64,0x4,0xff,0x4,0x3f,0x24,0x38,0x27,0x20,0x3f,0x20,0x80,0xf8,0x88,0x90,0x60,0x40,0x84,0xfe,0x40,0xf8,0x48,0x38,0xc8,0x8,0xf8,0x8,
-+0x0,0x7c,0x45,0x4a,0x48,0x50,0x49,0x4a,0x44,0x45,0x45,0x69,0x53,0x40,0x40,0x40,0x80,0x80,0xf8,0x10,0xa0,0x40,0xb0,0x4e,0x44,0xf0,0x40,0x48,0xfc,0x40,0x40,0x40,
-+0x8,0x8,0xff,0x9,0x8,0x1f,0x10,0x3f,0x50,0x1f,0x10,0x1f,0x10,0x24,0x22,0x40,0x20,0x24,0xfe,0x20,0x88,0xfc,0x80,0xf8,0x80,0xf8,0x80,0xfc,0x0,0x48,0x26,0x2,
-+0x22,0x22,0x22,0x23,0xfa,0x22,0x7f,0x6a,0xa2,0x27,0x2a,0x32,0x22,0x2a,0x24,0x21,0x0,0x0,0x7c,0xc4,0x44,0x24,0x28,0x28,0x28,0x10,0x90,0x28,0x28,0x46,0x84,0x0,
-+0x1,0x9,0xfd,0x11,0x13,0x25,0x21,0x79,0xa9,0x29,0x29,0x29,0x29,0x3a,0x22,0x4,0x20,0x14,0xfe,0x10,0x10,0xfc,0x10,0x10,0xfc,0x10,0x14,0xfe,0x0,0xa4,0x92,0x2,
-+0x9,0x8,0xf,0x10,0x10,0x3f,0x50,0x90,0x1f,0x10,0x10,0x1f,0x10,0x24,0x22,0x40,0x0,0x88,0xfc,0x80,0x90,0xf8,0x80,0x90,0xf8,0x80,0x84,0xfe,0x0,0x90,0x4c,0x4,
-+0x4,0x3e,0x24,0x27,0x24,0x3c,0x25,0x26,0x24,0x3c,0x24,0x24,0x24,0x44,0x95,0xa,0x40,0x20,0x24,0xfe,0x0,0x88,0x6,0x2,0x88,0x50,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x2,0x1,0x1,0xff,0x8,0x8,0x10,0x28,0x44,0x2,0x1,0x2,0x4,0x8,0x30,0xc0,0x0,0x0,0x4,0xfe,0x20,0x10,0xc,0x24,0x40,0x80,0x0,0x80,0x40,0x30,0xe,0x4,
-+0x10,0x8,0x9,0xff,0x0,0x14,0x22,0x41,0xa2,0x14,0x8,0x14,0x12,0x22,0x40,0x0,0x0,0x7c,0x44,0xc4,0x48,0x48,0x50,0x48,0xc4,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x41,0x31,0x10,0x7,0x80,0x60,0x20,0xb,0x10,0x27,0xe1,0x21,0x21,0x21,0x22,0x2c,0x0,0x8,0xfc,0x80,0xa0,0x44,0xa4,0x1c,0x0,0xfc,0x20,0x20,0x20,0x22,0x22,0x1e,
-+0x8,0xfd,0x8,0x48,0x4b,0x48,0x48,0x49,0x7e,0x4,0x1c,0xe4,0x44,0x14,0x9,0x2,0xc,0xf0,0x20,0x24,0xfe,0x50,0x88,0x6,0x8c,0x88,0x88,0x88,0x88,0x88,0x8,0x8,
-+0x10,0x13,0x10,0x10,0xfc,0x27,0x24,0x25,0x27,0x45,0x29,0x11,0x29,0x45,0x82,0x4,0x18,0xe0,0x40,0x40,0x44,0xfe,0xa0,0x10,0x1e,0x14,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x0,0xf,0x2,0xef,0xa9,0xaf,0xa0,0xaf,0xa8,0xaf,0xa8,0xaf,0xe8,0x89,0xf,0x0,0x1c,0xe0,0x48,0xfc,0x24,0xfc,0x0,0x88,0x88,0xfe,0x88,0xa8,0x28,0x8,0xa8,0x10,
-+0x12,0x11,0x11,0x17,0xfc,0x14,0x13,0x1a,0x32,0xd2,0x12,0x12,0x12,0x10,0x51,0x26,0x44,0x24,0x28,0xfe,0x2,0x4,0xf8,0x8,0x48,0x48,0x48,0x48,0x48,0xa2,0x22,0x1e,
-+0x10,0x10,0x10,0x1f,0x20,0x20,0x7d,0x92,0x10,0x7c,0x10,0x10,0x14,0x18,0x11,0x2,0x40,0x20,0x24,0xfe,0x0,0x88,0x6,0x2,0x88,0x50,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x20,0x23,0x28,0x3c,0x50,0x97,0x10,0xfd,0x13,0x15,0x11,0x29,0x25,0x41,0x82,0x4,0x18,0xe0,0x40,0x40,0x44,0xfe,0xa0,0x10,0x1e,0x14,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x9,0x9,0x8,0x17,0x10,0x30,0x50,0x93,0x10,0x17,0x11,0x11,0x11,0x11,0x12,0x1c,0x0,0x8,0xfc,0x80,0xa0,0x44,0xa4,0x1c,0x0,0xfc,0x20,0x20,0x20,0x22,0x22,0x1e,
-+0x9,0x7d,0x49,0x4f,0x49,0x79,0x49,0x4f,0x49,0x79,0x4a,0x4a,0x4f,0x48,0x88,0x18,0x0,0x4,0x3e,0xe4,0x24,0x24,0x24,0xe4,0x24,0x24,0x24,0xb4,0xe8,0x60,0x20,0x20,
-+0x8,0x88,0x50,0x27,0x50,0x89,0xa,0x1c,0x29,0x48,0x88,0x8,0x8,0x9,0x52,0x24,0x80,0x40,0x44,0xfe,0x0,0x10,0xc,0x4,0x10,0xa0,0x40,0xa0,0xa0,0x10,0xe,0x4,
-+0x8,0xf,0x10,0x20,0x5f,0x91,0x11,0x1f,0x11,0x11,0x1f,0x11,0x11,0x21,0x41,0x80,0x0,0xe0,0x40,0x88,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0x8,0x28,0x10,
-+0x20,0x20,0x20,0x3f,0x24,0x48,0x41,0xa2,0x20,0x20,0x20,0x24,0x28,0x30,0x21,0x2,0x40,0x20,0x24,0xfe,0x0,0x88,0x6,0x2,0x88,0x50,0x20,0x50,0x50,0x88,0x6,0x4,
-+0x22,0x24,0x2f,0x48,0x4f,0xf8,0x1f,0x22,0x5f,0x84,0xf7,0x4,0x34,0xc8,0x49,0x10,0x10,0x90,0xd0,0x94,0xbe,0xc4,0xa4,0x28,0xe8,0x28,0x90,0x90,0xa8,0xa8,0xc6,0x84,
-+0x10,0x10,0x20,0x23,0x44,0xf8,0x11,0x22,0x40,0xfc,0x0,0x0,0x1c,0xe0,0x41,0x2,0x40,0x20,0x24,0xfe,0x0,0x88,0x6,0x2,0x88,0x50,0x20,0x50,0x50,0x88,0x6,0x4,
-+0x24,0x24,0x49,0x24,0x3f,0x24,0x3f,0x24,0x3f,0x4,0xff,0x15,0x14,0x24,0x44,0x4,0x84,0x84,0x24,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0x24,0xe4,0x24,0x84,0x84,0x14,0x8,
-+0x8,0x8,0x7f,0x9,0xa,0xff,0x8,0x1f,0x22,0xcc,0x8,0xe,0x78,0x8,0x29,0x12,0x40,0x40,0x40,0x44,0x7e,0x88,0x8,0x48,0x50,0x50,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x2,0xff,0x28,0x28,0xfe,0xab,0xaa,0xaa,0xc7,0x82,0x83,0xfe,0x82,0x82,0xfe,0x82,0x20,0x24,0xfc,0x28,0x28,0xfe,0x10,0x20,0xfc,0x88,0x10,0xfe,0x10,0x10,0x50,0x20,
-+0x10,0x13,0x20,0xfc,0x20,0x57,0x50,0xfd,0x13,0x15,0x1d,0xf1,0x51,0x11,0x12,0x14,0xc,0xf0,0x40,0x40,0x44,0xfe,0x90,0x18,0x1e,0x14,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x10,0x10,0x20,0xff,0x20,0x50,0x51,0xfe,0x10,0x10,0x1e,0xf0,0x50,0x10,0x11,0x12,0x40,0x20,0x24,0xfe,0x0,0x88,0x6,0x2,0x88,0x50,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x0,0x4,0x7e,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x7c,0x44,0x0,0x0,0x0,0x4,0x4,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x9c,0xe4,0x84,0x4,0x4,0x4,
-+0x2,0x1,0x7f,0x48,0x91,0x9,0xf,0x11,0x1,0xff,0x0,0x1f,0x10,0x10,0x1f,0x10,0x0,0x0,0xfe,0x22,0x14,0x0,0xf0,0x0,0x4,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x10,
-+0x10,0x13,0x12,0x13,0xfe,0x13,0x14,0x19,0x33,0xd4,0x1c,0x14,0x15,0x17,0x50,0x20,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x80,0x4,0xfe,0x44,0x44,0xa4,0x14,0xe4,0x28,0x10,
-+0x10,0x10,0x17,0x10,0xfd,0x10,0x17,0x18,0x30,0xdf,0x10,0x11,0x10,0x10,0x50,0x23,0x80,0x48,0xfc,0x0,0x10,0xa0,0xfc,0x80,0x84,0xfe,0x90,0x10,0xa0,0x60,0x98,0x8,
-+0x20,0x24,0x3e,0x20,0x20,0x26,0x78,0x2,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x80,0x88,0x98,0xe0,0x82,0x82,0x7e,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x4,0xe,0x78,0xb,0x8,0xfe,0x8,0x19,0x1c,0x2a,0x29,0x49,0x89,0x9,0x9,0x9,0x20,0x20,0x24,0xfe,0x20,0x20,0x28,0xfc,0x0,0x4,0xfe,0x4,0x4,0x4,0xfc,0x4,
-+0x12,0x12,0x22,0x4f,0x82,0x12,0x1f,0x22,0x62,0xaf,0x22,0x22,0x23,0x3e,0x28,0x20,0x0,0x8,0x7c,0x80,0x0,0x4,0xfe,0x8,0x8,0x88,0x8,0x8,0xc8,0x8,0x28,0x10,
-+0x0,0x78,0x48,0x50,0x51,0x62,0x55,0x49,0x49,0x49,0x69,0x51,0x41,0x41,0x42,0x44,0x40,0x40,0xa0,0xa0,0x10,0xe,0x14,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x4,0x4,0x7f,0x4,0xff,0x10,0x15,0x3f,0x64,0xbf,0x24,0x3f,0x24,0x24,0x3f,0x20,0x40,0x50,0x48,0x40,0xfe,0x40,0x40,0xa0,0x24,0x28,0x30,0x20,0x52,0x92,0x8a,0x4,
-+0x8,0x8,0xa,0x7f,0x8,0x8,0x9,0xff,0x10,0x10,0x20,0x24,0x42,0x7e,0x1,0x2,0x20,0x20,0x20,0x20,0x24,0xfe,0x24,0xa4,0x24,0x44,0x44,0x44,0x84,0x84,0x28,0x10,
-+0x4,0x4,0xff,0x4,0x4,0x7f,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x40,0x44,0xfe,0x40,0x48,0xfc,0x8,0x8,0x8,0x8,0x48,0x28,0x10,0x0,0x0,0x0,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x31,0x38,0x54,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x20,0x20,0x24,0xfe,0x20,0x28,0xfc,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x1,0x1,0x1,0xff,0x3,0x5,0x9,0x11,0x21,0xc1,0x1,0x0,0x24,0x22,0x22,0x40,0x0,0x0,0x4,0xfe,0x80,0x40,0x20,0x10,0xe,0x4,0x0,0x0,0x90,0x48,0x44,0x4,
-+0x10,0x10,0x17,0x10,0xfb,0x10,0x17,0x18,0x33,0xd0,0x12,0x12,0x12,0x13,0x54,0x28,0x40,0x48,0xfc,0x40,0xf8,0x48,0xfe,0x48,0xf8,0x40,0x48,0x7c,0x40,0x40,0xc6,0x3c,
-+0x0,0x0,0x7f,0x48,0x4b,0x48,0x7f,0x48,0x4b,0x78,0x4a,0x4a,0x4a,0x7b,0x44,0x8,0x40,0x48,0xfc,0x40,0xf8,0x48,0xfe,0x48,0xf8,0x40,0x48,0x7c,0x40,0x40,0xc6,0x3c,
-+0x20,0x13,0x12,0xff,0x2,0x4b,0x48,0x49,0x4a,0x54,0x12,0x1e,0xe2,0x43,0x0,0x0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x80,0x4,0xfe,0x44,0x44,0xa4,0x4,0xe4,0x28,0x10,
-+0x0,0x40,0x30,0x17,0x0,0x80,0x67,0x20,0x8,0x13,0xe2,0x22,0x22,0x22,0x23,0x22,0x40,0x40,0x44,0xfe,0x40,0x48,0xfc,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x8,0x8,0x10,0x23,0x44,0x78,0x9,0x10,0x20,0x7d,0x1,0x1,0xd,0x71,0x21,0x1,0x20,0x20,0x24,0xfe,0x20,0x20,0xfc,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x11,0x3e,0x24,0x48,0xbe,0x2b,0x2a,0x3e,0x2a,0x2a,0x3f,0x2a,0x2a,0x42,0x86,0x4,0xfe,0x44,0x44,0x54,0x88,0x10,0x50,0x7c,0x90,0x14,0xfe,0x10,0x10,0x10,0x10,
-+0x10,0x11,0x11,0x15,0xff,0x25,0x25,0x25,0x25,0x45,0x29,0x11,0x29,0x45,0x87,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0xfe,0x0,
-+0x0,0x0,0x0,0xff,0x0,0x12,0x12,0x12,0x7f,0x12,0x12,0x12,0x12,0x22,0x41,0x2,0x40,0x50,0x48,0xfe,0x40,0x40,0x44,0x44,0x48,0x48,0x50,0x20,0x62,0x92,0xa,0x4,
-+0x4,0xff,0x4,0x10,0x7f,0x10,0x7c,0x13,0x7c,0x11,0x39,0x35,0x51,0x91,0x11,0x11,0x44,0xfe,0x40,0x90,0xfc,0x90,0x94,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,
-+0x8,0x8,0xff,0x8,0x9,0x2,0x4,0x8,0x14,0x24,0xc4,0x4,0x4,0x8,0x10,0x20,0x20,0x24,0xfe,0x20,0x20,0x80,0x40,0x20,0x50,0x4e,0x44,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x2,0x4,0xc,0x34,0xc4,0x4,0x8,0x10,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x80,0x60,0x50,0x4e,0x44,0x40,0x40,0x40,
-+0x9,0x9,0x9,0x17,0x11,0x31,0x5f,0x90,0x13,0x12,0x12,0x13,0x12,0x12,0x13,0x12,0x10,0x10,0x10,0xfc,0x10,0x14,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x1,0x1,0x2,0x4,0x8,0x10,0x24,0xc4,0x4,0x4,0x4,0x8,0x8,0x10,0x20,0x0,0x0,0x0,0x80,0x40,0x20,0x10,0x4e,0x44,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x0,0x1f,0x10,0x90,0x50,0x51,0x12,0x3d,0x51,0xd1,0x11,0x22,0x22,0x44,0x0,0x80,0x44,0xfe,0x40,0x40,0xa0,0x10,0xe,0x14,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x0,0x40,0x20,0x2f,0x0,0xe5,0x25,0x25,0x2f,0x25,0x25,0x2d,0x35,0x24,0x9,0x0,0x20,0x28,0x24,0xfe,0x20,0x20,0x24,0x24,0xe8,0x28,0x30,0x20,0x60,0x92,0xa,0x4,
-+0x0,0x3f,0x20,0x20,0x3f,0x20,0x20,0x20,0x2f,0x28,0x28,0x2f,0x28,0x48,0x8f,0x8,0x8,0xfc,0x8,0x8,0xf8,0x80,0x80,0x88,0xfc,0x88,0x88,0xf8,0x88,0x88,0xf8,0x8,
-+0x1,0x1,0x1,0x3f,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x1,0x1,0x1,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x28,0x10,0x0,0x0,0x0,
-+0x10,0x14,0x3e,0x49,0x80,0x3e,0x22,0x23,0x3e,0x22,0x22,0x3e,0x22,0x22,0x4a,0x85,0x40,0x48,0xfc,0x10,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0x44,0x44,0x94,0x8,
-+0x0,0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x0,0x10,0x38,0xc0,0x0,0x0,0x4,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x1,0x1,0x2,0x4,0x8,0x10,0x2f,0xc1,0x1,0x1f,0x1,0x11,0x9,0x5,0x7f,0x0,0x0,0x0,0x80,0x40,0x20,0x50,0xee,0x4,0x0,0xf0,0x0,0x10,0x20,0x48,0xfc,0x0,
-+0x1,0x1,0x2,0x4,0x8,0x12,0x21,0xc0,0x0,0x1f,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x80,0x40,0x20,0x10,0x8e,0x84,0x0,0xf0,0x10,0x20,0x20,0x40,0x80,0x0,
-+0x0,0x40,0x37,0x10,0xf,0x80,0x67,0x20,0x8,0x17,0xe0,0x20,0x2f,0x20,0x20,0x20,0x80,0x88,0xfc,0x88,0xfe,0x88,0xf8,0x80,0x90,0xf8,0x80,0x88,0xfc,0x80,0x80,0x80,
-+0x41,0x31,0x17,0x1,0xfb,0xd,0x11,0x29,0x73,0xa8,0x2f,0x20,0x21,0x22,0x24,0x20,0x10,0x10,0xfc,0x10,0xb8,0x56,0x10,0x10,0xf8,0x0,0xfe,0x40,0x50,0x4c,0x44,0xc0,
-+0x4,0x25,0x25,0x24,0x24,0x24,0x7,0x4,0x1f,0x1,0x2,0x7f,0x1,0x9,0x11,0x63,0x0,0xf8,0x10,0xa0,0x40,0xb0,0xe,0x24,0xc0,0x0,0x10,0xf8,0x8,0x20,0x18,0x8,
-+0x20,0x20,0x3b,0x42,0x83,0x7a,0x23,0x20,0xff,0x24,0x24,0x24,0x2c,0x30,0x20,0x0,0x40,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x40,0xfc,0x44,0x44,0x44,0x54,0x48,0x40,0x40,
-+0x8,0x8,0xb,0x10,0x11,0x31,0x51,0x91,0x10,0x10,0x10,0x10,0x10,0x10,0x11,0x16,0x0,0x4,0xfe,0x4,0x4,0x4,0x8,0x8,0x88,0x90,0x50,0x20,0x50,0x88,0x6,0x4,
-+0x41,0x21,0x2f,0x1,0x1,0xe0,0x27,0x24,0x27,0x20,0x27,0x20,0x2b,0x30,0x2f,0x0,0x10,0x14,0xfe,0x10,0xf0,0x44,0xfe,0x44,0xfc,0x40,0xfc,0x40,0xf8,0x40,0xfe,0x0,
-+0x2,0x42,0x22,0x2f,0x2,0x2,0xe2,0x22,0x2f,0x22,0x22,0x22,0x24,0x50,0x8f,0x0,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x26,0xfc,0x0,
-+0x22,0x22,0xff,0x22,0x3e,0x8,0x7f,0x49,0x49,0x7f,0x8,0xff,0x8,0x8,0x9,0x8,0x2,0x6,0xf8,0x40,0x40,0x44,0x7e,0x48,0x48,0x48,0x48,0xc8,0x48,0x88,0x8,0x8,
-+0x0,0x7f,0x4,0x24,0x14,0x4,0xff,0x0,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x8,0xfc,0x40,0x48,0x50,0x44,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x8,0x8,0x7e,0x18,0x2c,0x4b,0x88,0x0,0x3f,0x0,0xff,0x1,0x9,0x11,0x25,0x2,0x20,0x28,0xfc,0x70,0xa8,0x24,0x22,0x0,0xf8,0x0,0xfe,0x0,0x20,0x18,0x8,0x0,
-+0x0,0x40,0x33,0x12,0x2,0x2,0xf3,0x12,0x12,0x12,0x12,0x14,0x10,0x28,0x44,0x3,0x8,0x1c,0xe0,0x0,0x0,0x8,0xfc,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x6,0xfc,
-+0x10,0x11,0x11,0x15,0x59,0x51,0x51,0x92,0x12,0x14,0x10,0x10,0x28,0x44,0x84,0x0,0x8,0xfc,0x8,0x8,0xf8,0x28,0x20,0x10,0xe,0xc4,0x20,0x10,0xc0,0x30,0x8,0x0,
-+0x40,0x33,0x10,0x1,0x80,0x63,0x20,0x7,0x14,0x29,0xe1,0x20,0x20,0x20,0x23,0x2c,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfe,0x2,0xf4,0x10,0xa0,0x40,0xb0,0xe,0x4,
-+0x0,0x1f,0x10,0x10,0x1f,0x11,0x10,0x10,0x10,0x16,0x21,0x40,0x86,0x1,0x0,0x0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x80,0x80,0x40,0x20,0x90,0xe,0x4,0x80,0xc0,0x40,
-+0x0,0xff,0x2,0x4,0xc,0x12,0x21,0x40,0xfe,0x8,0x8,0x8,0xf,0x71,0x22,0x0,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x84,0x4,0x28,0x10,
-+0x12,0x12,0xff,0x12,0x0,0x7f,0x12,0x12,0xff,0x12,0x12,0x12,0x12,0x22,0x42,0x2,0x4,0x84,0xc4,0x24,0x24,0xa4,0x24,0xa4,0xe4,0x24,0x24,0x24,0x24,0x4,0x14,0x8,
-+0x8,0x8,0x8,0xfe,0x8,0x7e,0x42,0x42,0x42,0x7e,0x14,0x15,0x16,0x24,0x41,0x82,0x20,0x20,0x24,0xfe,0x20,0xfc,0x84,0x84,0x84,0xfc,0x50,0x50,0x50,0x92,0x12,0xe,
-+0x4,0x4,0xff,0x4,0x0,0x3f,0x0,0x1,0xe,0x70,0x1f,0x1,0x1,0x1,0xff,0x0,0x40,0x44,0xfe,0x40,0x0,0xf8,0x20,0xc0,0x38,0x6,0xf0,0x0,0x0,0x4,0xfe,0x0,
-+0x0,0x8,0x7f,0x48,0x4b,0x48,0x7f,0x48,0x4b,0x7a,0x4b,0x4a,0x4b,0x7a,0x4a,0x2,0x40,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x28,0x10,
-+0xf,0x8,0x8,0xf,0x8,0x8,0xf,0x8,0x7e,0x42,0x42,0x7e,0x42,0x42,0x7e,0x42,0xe0,0x20,0x20,0xe0,0x20,0x20,0xe0,0x24,0xfe,0x84,0x84,0xfc,0x84,0x84,0xfc,0x84,
-+0x10,0x10,0x1e,0x25,0x48,0xbe,0x2a,0x2a,0x3e,0x2a,0x2a,0x3e,0x0,0xf,0x70,0x20,0x40,0x20,0x24,0xfe,0x8,0xfc,0x88,0x88,0x88,0xf8,0x20,0x70,0xac,0x24,0xa0,0x40,
-+0x2,0x1,0x1,0xff,0x0,0x1f,0x10,0x10,0x10,0x1f,0x1,0x9,0x9,0x11,0x25,0x2,0x0,0x0,0x4,0xfe,0x10,0xf8,0x10,0x10,0x10,0xf0,0x0,0x40,0x30,0x18,0x8,0x0,
-+0x10,0x10,0x17,0x10,0x58,0x57,0x52,0x92,0x12,0x13,0x10,0x11,0x12,0x14,0x11,0x10,0x80,0x44,0xfe,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x40,0x50,0x4c,0x44,0x40,0x80,
-+0x10,0x10,0x93,0x54,0x19,0xfc,0x13,0x10,0x39,0x35,0x51,0x91,0x11,0x11,0x11,0x11,0x20,0x24,0xfe,0x20,0xfc,0x20,0xfe,0x4,0xfe,0x4,0xfc,0x4,0xfc,0x4,0x4,0xc,
-+0x10,0x13,0x92,0x54,0x19,0xfd,0x11,0x31,0x39,0x55,0x90,0x10,0x10,0x10,0x11,0x16,0x4,0xfe,0x20,0x24,0xfe,0x24,0xfc,0x24,0xfc,0x24,0xa0,0x40,0x60,0x90,0xe,0x4,
-+0x10,0x13,0x20,0x20,0x44,0xfc,0x8,0x13,0x20,0x41,0xfc,0x0,0x1c,0xe0,0x47,0x0,0x0,0xfc,0x8,0x10,0x30,0x48,0x86,0x2,0x0,0xfc,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x8,0x8,0x8,0x8,0x7f,0x8,0x8,0x8,0x8,0xff,0x8,0x8,0x8,0x8,0x10,0x20,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x14,0x7f,0x10,0x3f,0x55,0x1d,0x3,0xff,0x0,0x1f,0x0,0x1f,0x0,0x1f,0x10,0x1f,0x40,0x7c,0xc8,0x28,0x10,0x6e,0x4,0xfe,0x0,0xf0,0x0,0xf0,0x0,0xf0,0x10,0xf0,
-+0x1f,0x10,0x1f,0x10,0x1f,0x1,0xff,0x0,0x1f,0x10,0x10,0x1f,0x9,0x11,0x65,0x2,0xf0,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x20,0x18,0x8,0x0,
-+0x0,0xfd,0x4,0x8,0x18,0x26,0xc2,0x0,0x7c,0x10,0x10,0x10,0x1e,0xe0,0x40,0x3,0x4,0xfe,0x10,0x24,0xfe,0x84,0x94,0x94,0x94,0xa4,0xa4,0xa4,0x20,0x58,0x84,0x2,
-+0x8,0x8,0x7e,0x9,0x3e,0x8,0xff,0x0,0x3f,0x22,0x3e,0x22,0x3e,0x22,0x22,0x26,0x40,0x40,0xf8,0x10,0x24,0xfe,0x24,0x24,0xfe,0x24,0x24,0xfc,0x24,0x20,0xa0,0x40,
-+0x20,0x20,0x27,0x21,0x20,0xff,0x20,0x23,0x22,0x23,0x22,0x3b,0xe1,0x41,0x2,0xc,0x80,0x48,0xfc,0x10,0xa4,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x20,0x22,0x22,0x1e,
-+0x12,0x12,0xff,0x12,0x20,0x3f,0x41,0xbd,0x25,0x25,0x25,0x25,0x3d,0x21,0x5,0x2,0x20,0x20,0xa0,0x24,0x7e,0x84,0x44,0x44,0x48,0x28,0x28,0x10,0x28,0x28,0x46,0x84,
-+0x20,0x20,0x27,0x79,0x40,0x87,0x78,0x23,0x22,0xfb,0x22,0x23,0x29,0x31,0x22,0xc,0x80,0x48,0xfc,0x10,0xa4,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x20,0x22,0x22,0x1e,
-+0x8,0xb,0x10,0x20,0x40,0x8,0x11,0x36,0x50,0x93,0x10,0x10,0x10,0x10,0x17,0x10,0x0,0xf8,0x10,0x20,0x60,0x98,0xe,0x2,0x0,0xf8,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x0,0x0,0x1f,0x10,0x57,0x30,0x10,0x13,0x3c,0x50,0x97,0x10,0x20,0x20,0x4f,0x80,0x80,0x44,0xfe,0x0,0xf8,0x30,0xc0,0x38,0x6,0x0,0xf8,0x40,0x40,0x44,0xfe,0x0,
-+0x20,0x10,0x13,0xfc,0x3,0x48,0x4f,0x48,0x4b,0x12,0x13,0x1e,0xe3,0x42,0x2,0x2,0x40,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x28,0x10,
-+0x2,0x1,0x3f,0x8,0x4,0xff,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x14,0x4,0x8,0x70,0x0,0x10,0xf8,0x20,0x44,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x50,0x42,0x42,0x3e,
-+0x2,0x1,0x3f,0x8,0x4,0xff,0x0,0x1f,0x10,0x10,0x1f,0x14,0x4,0x4,0x8,0x70,0x0,0x10,0xf8,0x20,0x44,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x50,0x40,0x42,0x42,0x3e,
-+0x1,0x1,0x83,0x64,0x28,0x7,0x10,0x20,0x3f,0xe0,0x20,0x2f,0x20,0x20,0x22,0x21,0x0,0x0,0xf0,0x20,0x48,0xfc,0x88,0x88,0xfe,0x88,0x88,0xf8,0x88,0x80,0x80,0x0,
-+0x10,0x10,0x13,0x12,0x56,0x5a,0x52,0x92,0x12,0x12,0x12,0x12,0x2a,0x46,0x82,0x2,0x0,0x4,0xfe,0x4,0x4,0xf4,0x94,0x94,0x94,0x94,0x94,0xf4,0x94,0x4,0x14,0x8,
-+0x2,0x1,0x7f,0x44,0x88,0x3f,0x4,0xff,0x4,0x3f,0x8,0xf,0x18,0x28,0xcf,0x8,0x0,0x0,0xfe,0x42,0x24,0xf0,0x14,0xfe,0x10,0xf0,0x0,0xf8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x17,0x11,0xf9,0x17,0x11,0x1b,0x33,0xd5,0x19,0x11,0x11,0x11,0x51,0x21,0x10,0xd0,0x10,0x12,0x54,0xb8,0x10,0x10,0x90,0x50,0x10,0x10,0x28,0x46,0x84,0x0,
-+0x2,0x1,0x7f,0x44,0x88,0x12,0x2,0x3f,0x2,0x2,0x4,0x4,0x8,0x8,0x10,0x60,0x0,0x0,0xfe,0x42,0x34,0x10,0x20,0xf0,0x20,0x20,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x10,0x10,0x20,0x21,0x45,0xfd,0x9,0x11,0x21,0xfd,0x41,0x0,0x1c,0xe0,0x40,0x0,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x78,0x88,0x8,0x8,0x8,0x8,0x8,
-+0x0,0x4,0xfe,0x10,0x11,0x11,0xfe,0x10,0x10,0x10,0x1e,0xf0,0x40,0x1,0x2,0xc,0x40,0x40,0x88,0xfc,0x8,0x8,0x10,0x10,0x20,0x20,0x50,0x50,0x88,0xe,0x4,0x0,
-+0x4,0x4,0x7c,0x4,0x4,0x4,0x7c,0x4,0x4,0x4,0x7c,0x4,0x4,0x4,0xff,0x0,0x40,0x48,0x7c,0x40,0x40,0x48,0x7c,0x40,0x40,0x48,0x7c,0x40,0x40,0x44,0xfe,0x0,
-+0x4,0x4,0x7,0x8,0x8,0x10,0x20,0x0,0x1,0x1,0x2,0x4,0x8,0x30,0xc0,0x0,0x0,0x40,0xe0,0x40,0x40,0x80,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0xe,0x4,0x0,
-+0x4,0x7,0x8,0x10,0x21,0x2,0xc,0x11,0x69,0x9,0x9,0x11,0x2,0x4,0x18,0xe0,0x20,0xf0,0x20,0x40,0x80,0x60,0x10,0xc,0x24,0x30,0x20,0x40,0x0,0x40,0x30,0xe,
-+0x4,0x4,0x4,0x4,0xff,0x4,0x4,0x4,0x4,0x4,0x8,0x8,0x10,0x10,0x20,0xc0,0x0,0x0,0x0,0x20,0xf0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x40,0x2f,0x20,0x0,0x87,0x64,0x24,0xc,0x15,0x26,0xe4,0x25,0x24,0x24,0x27,0x24,0x4,0xfe,0xa0,0xa4,0xfe,0xa4,0xa4,0xa4,0x1c,0x4,0x4,0xf4,0x4,0x4,0xfc,0x4,
-+0x0,0x3f,0x20,0x2f,0x29,0x29,0x2f,0x29,0x29,0x2f,0x2a,0x29,0x2e,0x48,0x41,0x82,0x4,0xfe,0x0,0x7c,0x10,0x50,0x50,0x54,0x7e,0x20,0x30,0x50,0xd2,0x92,0xe,0x0,
-+0x10,0x14,0x12,0x10,0xfe,0x11,0x92,0x54,0x18,0x30,0x54,0xd2,0x10,0x10,0x50,0x23,0x40,0x40,0x40,0x44,0xfe,0x8,0x88,0x88,0x90,0x50,0x50,0x20,0x50,0x50,0x8e,0x4,
-+0x0,0x20,0x23,0x22,0x22,0x22,0x22,0x23,0x22,0x22,0x22,0x22,0x22,0x23,0x22,0x20,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,0x0,
-+0x0,0x1,0x6,0x78,0x40,0x40,0x40,0x44,0x7e,0x40,0x40,0x40,0x40,0x40,0x7f,0x40,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x3e,0x20,0x3c,0x20,0x3f,0x0,0x1f,0x11,0x1f,0x11,0x1f,0x1,0x7f,0x2,0xc,0x70,0x78,0x8,0x78,0x8,0xf8,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x0,0xf8,0x8,0x48,0x30,
-+0x10,0x10,0x1f,0x21,0x62,0x14,0x8,0x14,0x23,0xc0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x40,0x40,0x40,0x50,0x4c,0x44,0x40,0x46,0xfc,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,
-+0x10,0x8,0x2,0xff,0x0,0x3f,0x22,0x22,0x22,0x3e,0x8,0x2a,0x49,0x88,0x29,0x12,0x40,0x50,0x48,0x40,0x44,0xfe,0x40,0x50,0x50,0x50,0x50,0x50,0x52,0x92,0xe,0x0,
-+0x1,0x0,0x1f,0x11,0x91,0x51,0x52,0x14,0x30,0x50,0xd0,0x11,0x22,0x24,0x48,0x10,0x0,0x84,0xfe,0x0,0x0,0xf8,0x10,0x20,0x20,0x40,0xc0,0x20,0x10,0x8,0xe,0x4,
-+0x28,0x28,0xfe,0x29,0x3a,0x11,0x7c,0x54,0x57,0x7c,0x10,0xfe,0x11,0x12,0x10,0x10,0x80,0x84,0xfe,0x4,0x44,0x54,0xe4,0x44,0xfc,0x44,0xe4,0xd4,0x54,0x44,0x54,0x48,
-+0x10,0x10,0x11,0x11,0xfe,0x14,0x11,0x1d,0x31,0xd1,0x11,0x11,0x11,0x11,0x50,0x20,0x80,0x80,0x4,0xfe,0x4,0x24,0xf4,0x24,0x24,0x24,0x24,0x24,0xe4,0x4,0x14,0x8,
-+0x0,0x45,0x2d,0x11,0x29,0x49,0x89,0x19,0x29,0x49,0x89,0x9,0x9,0x9,0x57,0x20,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0xfe,0x0,
-+0x1,0x0,0x1f,0x10,0x93,0x52,0x12,0x13,0x32,0x52,0xd3,0x12,0x12,0x22,0x2f,0x40,0x0,0x84,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0x8,0xfe,0x0,
-+0x0,0x3f,0x20,0x20,0x3f,0x20,0x20,0x3f,0x20,0x20,0x2f,0x28,0x48,0x48,0x8f,0x8,0x8,0xfc,0x8,0x8,0xf8,0x80,0x84,0xfe,0x80,0x88,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x8,0xfc,0x9,0x49,0x4a,0x4c,0x49,0x49,0x49,0x7d,0x5,0x1d,0xe5,0x4,0x28,0x10,0x80,0x80,0x4,0xfe,0x4,0x24,0xf4,0x24,0x24,0x24,0x24,0xe4,0x24,0x4,0x14,0x8,
-+0x8,0x8,0xff,0x8,0x10,0x1f,0x22,0x52,0x8a,0x7f,0x6,0xb,0xa,0x12,0x22,0x2,0x20,0x24,0xfe,0x20,0x4,0xfe,0x4,0x44,0x84,0xf4,0x4,0x84,0xc4,0x44,0x14,0x8,
-+0x0,0x3f,0x20,0x20,0x3f,0x20,0x20,0x3f,0x20,0x27,0x24,0x24,0x27,0x24,0x40,0x80,0x8,0xfc,0x8,0x8,0xf8,0x0,0x4,0xfe,0x4,0xe4,0x24,0x24,0xe4,0x4,0x14,0x8,
-+0x0,0x9,0x7d,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x79,0x49,0x1,0xf,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0xfe,0x0,
-+0x20,0x23,0x2a,0x3e,0x52,0x93,0x12,0xfe,0x12,0x12,0x13,0x2a,0x26,0x42,0x83,0x0,0x8,0xfc,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,0x4,0xfe,0x0,
-+0x22,0x19,0x9,0x0,0xff,0x4,0x9,0x11,0x2f,0xc1,0x1,0x3f,0x1,0x1,0x1,0x1,0x8,0x18,0x20,0x44,0xfe,0x40,0x20,0x10,0xee,0x4,0x10,0xf8,0x0,0x0,0x0,0x0,
-+0x40,0x33,0x12,0x2,0x82,0x63,0x22,0xa,0x12,0x23,0xe2,0x22,0x22,0x22,0x3f,0x20,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,0x10,0x10,0xf0,0x10,0x10,0x10,0x14,0xfe,0x0,
-+0xff,0x22,0x3e,0x22,0x3e,0x22,0xff,0x2,0x3f,0x5,0x9,0x33,0x5,0x9,0x71,0x1,0x80,0xfe,0x44,0x28,0x10,0x28,0xc6,0x70,0x88,0x18,0xa0,0x40,0x30,0xe,0x4,0x0,
-+0x10,0x13,0x12,0x12,0xfe,0x13,0x16,0x1a,0x32,0xd2,0x13,0x12,0x12,0x12,0x53,0x20,0x8,0xfc,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,0x4,0xfe,0x0,
-+0x10,0x13,0x12,0x12,0xff,0x12,0x16,0x1b,0x32,0xd2,0x13,0x15,0x15,0x15,0x59,0x21,0x4,0xfe,0x4,0x4,0xfc,0x20,0x24,0xfe,0x20,0x24,0xfe,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x3f,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x3f,0x0,0x10,0xf8,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,0x0,0x0,0x8,0xfc,0x0,
-+0x0,0xf,0x8,0x8,0xf,0x8,0xf,0x8,0xf,0x8,0x8,0xff,0x4,0xc,0x10,0x20,0x20,0xf0,0x20,0x20,0xe0,0x20,0xe0,0x20,0xe0,0x20,0x24,0xfe,0x40,0x20,0x18,0x8,
-+0x0,0x7d,0x45,0x45,0x45,0x7d,0x11,0x11,0x51,0x5d,0x51,0x51,0x5d,0xf1,0x41,0x0,0x8,0xfc,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x4,0xfe,0x0,
-+0x0,0x7d,0x45,0x45,0x45,0x7d,0x11,0x11,0x51,0x5d,0x51,0x52,0x5e,0xe4,0x48,0x0,0x4,0xfe,0x4,0x4,0xfc,0x20,0x24,0xfe,0x20,0x24,0xfe,0x84,0x84,0x84,0xfc,0x84,
-+0x20,0x21,0x3d,0x41,0x81,0x7d,0x21,0x21,0xfd,0x21,0x25,0x2a,0x32,0x24,0x8,0x0,0x4,0xfe,0x4,0x4,0xfc,0x20,0x24,0xfe,0x20,0x24,0xfe,0x84,0x84,0x84,0xfc,0x84,
-+0x8,0xb,0xa,0x12,0x13,0x32,0x53,0x92,0x13,0x12,0x12,0x1f,0x10,0x11,0x13,0x14,0x8,0xfc,0x8,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x8,0x8,0xfe,0x0,0x10,0xc,0x4,
-+0x4,0x4,0x8,0xf,0x10,0x20,0x4f,0x8,0x8,0x8,0x8,0xf,0x8,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x4,0x44,0xe4,0x44,0x44,0x44,0x44,0xc4,0x44,0x4,0x28,0x10,
-+0x10,0x13,0x12,0x12,0x5b,0x56,0x53,0x92,0x13,0x12,0x12,0x1f,0x10,0x11,0x13,0x14,0x8,0xfc,0x8,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x8,0x8,0xfe,0x0,0x10,0xc,0x4,
-+0x10,0x11,0x11,0x15,0x59,0x51,0x51,0x91,0x11,0x11,0x11,0x29,0x25,0x45,0x81,0x0,0x8,0xfc,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0xfc,0x4,0x0,0x0,0x4,0xfe,0x0,
-+0x0,0x3f,0x20,0x20,0x3f,0x24,0x25,0x3f,0x24,0x24,0x3f,0x50,0x50,0x50,0x9f,0x10,0x84,0xc4,0xa4,0xa4,0xa4,0x24,0x24,0xa4,0x24,0xa4,0xe4,0xa4,0x84,0x84,0x94,0x88,
-+0x10,0x11,0x11,0x11,0xfd,0x10,0x15,0x19,0x31,0xd1,0x11,0x11,0x11,0x11,0x51,0x21,0x4,0xfe,0x4,0x4,0xfc,0x0,0xfc,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x4,0xc,
-+0x2,0x7f,0x42,0x42,0x7e,0x0,0x7e,0x42,0x42,0x7e,0x42,0x42,0x7f,0x42,0x4a,0x44,0x20,0x44,0xfe,0x84,0xa4,0x84,0x94,0x88,0x80,0xfe,0x2,0x12,0xfa,0x2,0x14,0x8,
-+0x10,0x11,0x11,0x11,0xfd,0x24,0x25,0x25,0x25,0x45,0x29,0x11,0x29,0x45,0x81,0x1,0x4,0xfe,0x4,0x4,0xfc,0x0,0xfc,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x14,0x8,
-+0x8,0xa,0x9,0x10,0x17,0x30,0x5f,0x91,0x12,0x15,0x19,0x11,0x11,0x11,0x11,0x10,0x40,0x48,0x50,0x40,0xfc,0xa0,0xfe,0x10,0x8,0xf6,0x14,0x10,0x50,0x24,0x4,0xfc,
-+0x1,0x11,0x9,0x7f,0x2,0xff,0x4,0x8,0x1f,0x28,0xcf,0x8,0xf,0x8,0xf,0x8,0x0,0x10,0x20,0xfc,0x0,0xfe,0x40,0x20,0xf0,0x2e,0xe4,0x20,0xe0,0x20,0xe0,0x20,
-+0x1,0x11,0x9,0x1,0x7f,0x2,0xff,0x4,0x8,0x1f,0x28,0xc8,0x9,0x8,0x8,0x7,0x0,0x10,0x20,0x8,0xfc,0x80,0xfe,0x40,0x20,0xf0,0x2e,0x24,0x20,0xc8,0x8,0xf8,
-+0x8,0x9,0x11,0x21,0x45,0xfc,0x9,0x11,0x21,0xfd,0x41,0x1,0x1d,0xe1,0x41,0x1,0x4,0xfe,0x4,0x4,0xfc,0x0,0xfc,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x14,0x8,
-+0x20,0x2f,0x28,0x2a,0xf9,0x2f,0x38,0x6a,0xaa,0x2a,0x2b,0x2a,0x28,0x31,0xa1,0x42,0x4,0xfe,0x8,0x28,0x4e,0xf2,0xa0,0xa8,0xa8,0xa8,0xe8,0x94,0x94,0x24,0x22,0x40,
-+0x27,0x26,0x25,0x24,0xff,0x20,0x23,0x26,0x3b,0xe2,0x22,0x20,0x23,0x20,0xa0,0x47,0xbc,0xb4,0xac,0xa4,0xbc,0x40,0xfc,0x40,0xf8,0x40,0x7c,0x0,0xf8,0x90,0x60,0x9e,
-+0x10,0x10,0x10,0x10,0xff,0x10,0x14,0x18,0x30,0xd7,0x10,0x11,0x11,0x12,0x54,0x28,0x80,0x80,0x80,0x88,0xfc,0x88,0x88,0x88,0x88,0xfe,0x80,0x40,0x20,0x10,0xe,0x4,
-+0x20,0x27,0x24,0x24,0xff,0x24,0x25,0x2d,0x35,0xe5,0x24,0x25,0x25,0x29,0xb1,0x41,0x4,0xfe,0x4,0x4,0xfc,0x20,0x24,0x24,0x24,0xfc,0x20,0x24,0x24,0x24,0xfc,0x4,
-+0x10,0x17,0x14,0x24,0x27,0x64,0xa5,0x25,0x25,0x25,0x24,0x25,0x25,0x29,0x31,0x21,0x4,0xfe,0x4,0x4,0xfc,0x20,0x24,0x24,0x24,0xfc,0x20,0x24,0x24,0x24,0xfc,0x4,
-+0x0,0x7f,0x11,0x9,0x7f,0x44,0x7f,0x0,0x7e,0x43,0x7e,0x42,0x7e,0x44,0x7e,0x2,0x38,0xd0,0x10,0x24,0xfe,0x44,0xfc,0x8,0x8,0xfe,0x8,0x88,0x48,0x8,0x28,0x10,
-+0x12,0x9,0x9,0x7f,0x40,0x80,0x1f,0x10,0x11,0x11,0x11,0x12,0x12,0x4,0x8,0x70,0x10,0x10,0x20,0xfe,0x2,0x14,0xf8,0x10,0x10,0x10,0x90,0x90,0x90,0x84,0x84,0x7c,
-+0x0,0x40,0x30,0x10,0x7,0x8,0x10,0x10,0x20,0xef,0x20,0x21,0x21,0x22,0x24,0x28,0x80,0x80,0x80,0x88,0xfc,0x88,0x88,0x88,0x88,0xfe,0x80,0x40,0x20,0x10,0xe,0x4,
-+0x0,0x40,0x30,0x10,0x7,0x0,0xf0,0x10,0x10,0x1f,0x10,0x15,0x19,0x12,0x4,0x8,0x80,0x80,0x80,0x88,0xfc,0x88,0x88,0x88,0x88,0xfe,0x80,0x40,0x20,0x10,0xe,0x4,
-+0x10,0x10,0x10,0x20,0x45,0xff,0x9,0x11,0x21,0xfd,0x41,0x1,0x1d,0xe1,0x41,0x0,0x40,0x40,0x78,0x90,0x24,0xfe,0x24,0x24,0x24,0xfc,0x4,0x0,0x0,0x2,0x2,0xfe,
-+0x10,0x10,0x10,0x10,0x11,0xfd,0x12,0x10,0x10,0x10,0x10,0x1d,0xf0,0x40,0x0,0x0,0x80,0x80,0x84,0xfe,0x4,0x4,0x84,0x44,0x14,0x24,0x44,0x84,0x84,0x4,0x28,0x10,
-+0x8,0x8,0xff,0x8,0x7f,0x40,0x41,0x4f,0x41,0x7f,0x45,0x49,0x51,0x41,0x7f,0x40,0x20,0x24,0xfe,0x20,0xfc,0x44,0xe4,0x4,0x24,0xf4,0x44,0x34,0x14,0x4,0xfc,0x4,
-+0x10,0x10,0x14,0x1e,0x21,0x41,0xbe,0x10,0x10,0x7c,0x10,0x11,0x14,0x18,0x10,0x0,0x80,0x80,0x84,0xfe,0x4,0x4,0x84,0x44,0x14,0x24,0x44,0x84,0x84,0x4,0x28,0x10,
-+0x0,0x7f,0x42,0x82,0x3f,0x4,0x9,0x11,0x3f,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x0,0xfe,0x2,0x14,0xf8,0x0,0x0,0x10,0xf8,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,
-+0x0,0x3f,0x4,0x4,0xff,0x4,0x4,0x3f,0x8,0x8,0x1f,0x18,0x28,0x48,0x8f,0x8,0x10,0xf8,0x10,0x14,0xfe,0x10,0x10,0xf0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x10,0x11,0x57,0x54,0x55,0x56,0x54,0x55,0x56,0x7c,0x44,0x0,0x1,0x6,0x40,0x40,0x90,0x8,0xfc,0x90,0xc,0x84,0xf8,0x88,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x8,0x8,0x8,0x11,0x17,0x31,0x52,0x95,0x11,0x12,0x13,0x14,0x18,0x10,0x11,0x16,0x40,0x40,0x90,0x8,0xfc,0x10,0xc,0x4,0xf0,0x10,0x10,0xa0,0x40,0xb0,0xe,0x4,
-+0x0,0x40,0x30,0x10,0xff,0x0,0x49,0x4a,0x48,0x49,0x51,0x12,0x1c,0xe0,0x40,0x3,0x20,0x20,0x48,0x84,0xfe,0x88,0x6,0x82,0xf8,0x8,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x40,0x30,0x10,0x1,0x87,0x61,0x22,0x5,0x11,0x22,0xe3,0x24,0x28,0x20,0x21,0x26,0x40,0x40,0x90,0x8,0xfc,0x10,0xc,0x4,0xf0,0x10,0x10,0xa0,0x40,0xb0,0xe,0x4,
-+0x0,0x7f,0x11,0x11,0xff,0x11,0x11,0x7f,0x20,0x41,0xbf,0x21,0x21,0x21,0x3f,0x21,0x0,0x7c,0x44,0x44,0xc8,0x48,0x50,0x48,0x44,0x42,0xc2,0x62,0x54,0x48,0x40,0x40,
-+0x8,0xfc,0x8,0x48,0x4b,0x48,0x49,0x4a,0x48,0x7d,0x6,0x4,0x34,0xc4,0x14,0xb,0x20,0x20,0x48,0x84,0xfe,0x88,0x6,0x82,0xf8,0x8,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x0,0x0,0xf7,0x94,0x98,0x91,0x92,0x90,0x91,0x9e,0x93,0xf2,0x92,0x2,0x3,0x2,0x80,0x40,0xfe,0x82,0xf4,0x10,0xa0,0x40,0xb0,0xe,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x4,0x4,0x74,0x54,0x5f,0x54,0x54,0x54,0x54,0x54,0x54,0x74,0x48,0xa,0x11,0x20,0x0,0x0,0x4,0xbe,0xe4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xbc,0x24,0x0,
-+0x2,0x2,0x3,0x2,0x2,0x2,0xff,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x0,0x20,0xf0,0x0,0x0,0x4,0xfe,0x0,0x0,0x80,0x60,0x30,0x10,0x0,0x0,0x0,
-+0x0,0x8,0x7c,0x49,0x4b,0x4c,0x48,0x48,0x49,0x4e,0x49,0x79,0x49,0x1,0x1,0x1,0x80,0x80,0xf8,0x8,0x10,0xa0,0x40,0xb0,0xe,0x4,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x7f,0x8,0x8,0x8,0x8,0x8,0xff,0x8,0x8,0x8,0x8,0x10,0x10,0x20,0x40,0x8,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x10,0x12,0x12,0x13,0xfe,0x12,0x17,0x1a,0x30,0xd3,0x12,0x12,0x13,0x12,0x52,0x23,0x20,0x20,0x24,0xac,0x30,0xa2,0x22,0x1e,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,
-+0x10,0x12,0x12,0x13,0xfe,0x12,0x3b,0x36,0x50,0x53,0x92,0x12,0x13,0x12,0x12,0x13,0x20,0x20,0x24,0xac,0x30,0xa2,0x22,0x5e,0x88,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,
-+0x8,0x49,0x49,0x49,0x7f,0x2,0xff,0x2,0x2,0x7e,0x42,0x40,0x46,0x58,0x61,0x2,0x8,0x7c,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x8a,0x8a,0x6,0x0,
-+0x20,0x27,0x24,0x24,0xb7,0xac,0xa4,0x27,0x24,0x24,0x25,0x24,0x27,0x24,0x20,0x21,0x4,0xbe,0x88,0xa8,0xa8,0xa8,0xa8,0xbe,0x8,0x10,0x18,0xa8,0xaa,0x4a,0x86,0x0,
-+0x1,0x3f,0x4,0x4,0x4,0x4,0x4,0xff,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x84,0x4,0x24,0x24,0x24,0xa4,0xe4,0x24,0x24,0x24,0x24,0x4,0x4,0x14,0x8,
-+0x11,0x11,0x17,0x11,0xfd,0x11,0x11,0x11,0x11,0x1f,0x12,0x1e,0xf3,0x42,0x3,0x0,0x10,0x10,0xfc,0x10,0xf0,0x10,0xf0,0x10,0x14,0xfe,0x0,0x90,0x8,0x0,0xfc,0x0,
-+0x22,0x22,0x7f,0x22,0x3e,0x22,0x3e,0x22,0x22,0xff,0x54,0x62,0x40,0x7e,0x1,0x2,0x20,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0xa4,0x24,0x44,0x44,0x84,0x14,0x8,
-+0x10,0x10,0x10,0x10,0xfd,0x12,0x14,0x10,0x10,0x10,0x10,0x1c,0xe1,0x42,0x4,0x8,0x80,0x80,0x80,0xfc,0x4,0x8,0x40,0x40,0x40,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,
-+0x0,0x4,0xfe,0x10,0x11,0x22,0x24,0x7e,0xa4,0x24,0x24,0x24,0x25,0x3e,0x24,0x8,0x80,0x80,0x80,0xfc,0x4,0x8,0x40,0x40,0x40,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,
-+0x0,0x7f,0x2,0x7f,0x4,0xff,0x8,0x1f,0x30,0x5f,0x90,0x1f,0x10,0x10,0x1f,0x10,0x70,0x80,0x10,0xf8,0x0,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x1,0x0,0x3f,0x20,0x2f,0x20,0x3f,0x20,0x2f,0x28,0x24,0x22,0x44,0x48,0x92,0x1,0x0,0x84,0xfe,0x80,0xf8,0x88,0xfe,0x88,0xf8,0x80,0xc4,0xa8,0x90,0x8e,0x84,0x0,
-+0x20,0x20,0x27,0x24,0xb7,0xac,0xa7,0xa4,0x27,0x24,0x25,0x24,0x25,0x2a,0x30,0x20,0x80,0x44,0xfe,0x40,0xfc,0x44,0xfe,0x44,0xfc,0x48,0x50,0xe0,0x50,0x4e,0x44,0xc0,
-+0x20,0x20,0x27,0xac,0x77,0x24,0xff,0x24,0x77,0x6c,0xa5,0x24,0x25,0x2a,0x30,0x20,0x80,0x44,0xfe,0x40,0xfc,0x44,0xfe,0x44,0xfc,0x48,0x50,0xe0,0x50,0x4e,0x44,0xc0,
-+0x10,0x10,0x17,0x10,0xfc,0x10,0x14,0x18,0x30,0xd0,0x10,0x10,0x10,0x1f,0x50,0x20,0x0,0x8,0xfc,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,0x0,
-+0x10,0x10,0x10,0x17,0xfc,0x10,0x15,0x19,0x31,0xd1,0x11,0x11,0x11,0x12,0x52,0x24,0x80,0x40,0x44,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x2,0x1,0x1,0xff,0x0,0x0,0xf,0x8,0x8,0x8,0x8,0x8,0x10,0x10,0x20,0x40,0x0,0x0,0x4,0xfe,0x0,0x20,0xf0,0x20,0x20,0x20,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x10,0x10,0x10,0x17,0x54,0x58,0x51,0x91,0x11,0x11,0x11,0x29,0x25,0x42,0x82,0x4,0x80,0x40,0x44,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x2,0x2,0x3f,0x2,0x2,0xff,0x2,0x4,0xf,0x12,0x27,0x40,0x80,0x2,0x1,0x0,0x0,0x10,0xe0,0x40,0x84,0xfe,0x0,0x10,0xf8,0x0,0xf0,0x10,0x10,0x20,0x20,0xc0,
-+0x10,0x10,0x13,0x10,0xfc,0x17,0x10,0x19,0x33,0xd4,0x19,0x10,0x10,0x11,0x50,0x20,0x80,0x88,0xf8,0x90,0xa4,0xfe,0x80,0x8,0xfc,0x80,0xf8,0x8,0x8,0x10,0x90,0x60,
-+0x10,0x10,0x13,0x54,0x58,0x53,0x90,0x11,0x13,0x14,0x19,0x28,0x24,0x45,0x80,0x0,0x80,0x88,0xf8,0x90,0xa4,0xfe,0x80,0x8,0xfc,0x80,0xf8,0x8,0x8,0x10,0x90,0x60,
-+0x11,0x1f,0x21,0xff,0x0,0x1f,0x10,0x1f,0x2,0x7e,0x2,0x3e,0x2,0x7e,0x2,0x2,0x20,0xf0,0x4,0xfe,0x0,0xf0,0x10,0xf0,0x80,0xfc,0x80,0xf8,0x80,0xfc,0x80,0x80,
-+0x10,0x10,0x17,0x10,0x10,0xfd,0x11,0x11,0x11,0x11,0x11,0x1d,0xf1,0x40,0x0,0x0,0x0,0x4,0xfe,0x8,0x8,0xe8,0x28,0x28,0x28,0x28,0x28,0xe8,0x28,0x8,0x28,0x10,
-+0x8,0x8,0x7f,0x8,0x0,0xff,0x0,0x1,0x1f,0x11,0x11,0x11,0x1f,0x11,0x0,0x0,0x20,0x28,0xfc,0x20,0x4,0xfe,0x20,0x20,0xa0,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x10,0x10,0x17,0x10,0xfc,0x11,0x39,0x35,0x51,0x51,0x91,0x11,0x11,0x10,0x10,0x10,0x0,0x4,0xfe,0x8,0x8,0xe8,0x28,0x28,0x28,0x28,0x28,0xe8,0x28,0x8,0x28,0x10,
-+0x10,0x13,0x12,0x12,0xff,0x12,0x3a,0x37,0x50,0x5f,0x90,0x10,0x11,0x12,0x1c,0x10,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x40,0xfe,0x40,0xe0,0x50,0x4e,0x44,0x40,
-+0x0,0x4,0xff,0x10,0x10,0x21,0x20,0x7c,0xa5,0x24,0x25,0x25,0x25,0x3d,0x23,0x0,0x20,0x28,0xfc,0x20,0x24,0xfe,0x40,0x88,0xfc,0x0,0xfc,0x54,0x54,0x54,0xfe,0x0,
-+0x0,0x7f,0x54,0x54,0x7d,0x55,0x55,0x7d,0x11,0xff,0x31,0x39,0x55,0x54,0x90,0x13,0x4,0xfe,0x40,0x84,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x50,0x8c,0x4,
-+0x4,0xe,0xf8,0x8,0x8,0xfe,0x8,0x1c,0x1a,0x29,0x28,0x48,0x88,0x8,0x8,0x8,0x10,0x10,0x90,0x50,0x10,0x90,0x50,0x14,0x1e,0xf0,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x1,0x1,0x7f,0x1,0x3f,0x0,0x7f,0x40,0x8f,0x8,0x8,0x8,0x8,0x8,0x10,0x60,0x0,0x8,0xfc,0x0,0xf8,0x0,0xfe,0x22,0xf4,0x20,0x20,0x20,0x24,0x24,0x1c,0x0,
-+0x0,0x0,0x8,0x7f,0x48,0x48,0x49,0x4b,0x48,0x48,0x48,0x79,0x4e,0x0,0x1,0x6,0x80,0x40,0x44,0xfe,0x40,0x80,0x8,0xf8,0x10,0x24,0x4c,0x90,0x20,0x50,0x8c,0x4,
-+0x0,0xff,0x0,0x0,0x1f,0x10,0x10,0x10,0x10,0x10,0x1f,0x10,0x0,0x0,0x0,0x0,0x4,0xfe,0x10,0x90,0xd0,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x10,0x10,0x50,0x20,
-+0x0,0x47,0x34,0x17,0x84,0x67,0x22,0x3,0x14,0x24,0xe8,0x35,0x24,0x27,0x20,0x20,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x4,0xfe,0x44,0x44,0xa4,0x14,0x4,0xe4,0x14,0x8,
-+0x1,0x1,0xff,0x1,0x1,0x1f,0x10,0x10,0x10,0x1f,0x14,0x4,0x4,0x8,0x10,0x60,0x0,0x4,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0xf0,0x50,0x40,0x40,0x42,0x42,0x3e,
-+0x8,0x4,0x4,0xff,0x4,0x8,0x10,0x7f,0x2,0x4,0x9,0x72,0x6,0x19,0xe0,0x0,0x4,0x4,0x84,0xc4,0x4,0xa4,0xa4,0x24,0x24,0xa4,0x24,0x24,0x4,0x84,0x94,0x8,
-+0x2,0x1,0x7f,0x48,0x8f,0x8,0x14,0x23,0xc,0x30,0xcf,0x8,0x8,0x8,0xf,0x8,0x0,0x0,0xfe,0x2,0xf4,0x20,0x40,0x80,0x60,0x1e,0xe4,0x20,0x20,0x20,0xe0,0x20,
-+0x0,0x43,0x22,0x22,0x3,0x2,0xe2,0x23,0x20,0x2f,0x20,0x29,0x32,0x24,0x8,0x0,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x40,0xfe,0xe0,0x50,0x48,0x4e,0x44,0x40,
-+0x1,0x9,0x9,0x9,0x9,0xff,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x10,0x10,0x0,0x10,0xf8,0x0,0x4,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0x10,0x50,0x20,
-+0x0,0x9,0x7d,0x49,0x49,0x4f,0x48,0x4b,0x4a,0x4b,0x4a,0x7b,0x4a,0x2,0x2,0x2,0x40,0x48,0x7c,0x40,0x44,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x0,0x3f,0x20,0x3f,0x20,0x3f,0x22,0x21,0x24,0x38,0x1,0x7f,0x1,0x1,0xff,0x0,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x8,0x90,0x60,0x1c,0x8,0xfc,0x0,0x4,0xfe,0x0,
-+0x0,0x3f,0x20,0x3f,0x20,0x3f,0x22,0x21,0x24,0x38,0x2,0x51,0x50,0x90,0xf,0x0,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x8,0x90,0x60,0x1c,0x8,0x84,0x92,0x12,0xf0,0x0,
-+0x10,0x10,0x10,0x17,0xfc,0x10,0x11,0x11,0x11,0x11,0x1d,0xf1,0x41,0x2,0x2,0x4,0x80,0x40,0x44,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x0,0x8,0x7c,0x4f,0x48,0x48,0x49,0x49,0x49,0x49,0x49,0x79,0x49,0x2,0x2,0x4,0x80,0x40,0x44,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x2,0x1,0x7f,0x40,0x84,0xc,0x10,0x20,0x0,0x3f,0x1,0x1,0x1,0x1,0xff,0x0,0x0,0x0,0xfe,0x2,0x44,0x30,0x18,0x8,0x0,0xf8,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x4,0xfe,0x10,0x10,0x10,0x10,0x1e,0xf1,0x42,0x0,0x52,0x51,0x50,0x90,0xf,0x0,0x10,0xf8,0x90,0x90,0xd0,0xb0,0x92,0x12,0xe,0x0,0x4,0x82,0x92,0x12,0xf0,0x0,
-+0x0,0x7f,0x21,0x2,0xc,0x8,0x8,0xb,0x1c,0xe8,0x8,0x8,0x8,0x8,0x28,0x10,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x10,0x10,0x13,0x12,0xfc,0x10,0x15,0x18,0x30,0xd3,0x10,0x10,0x10,0x10,0x57,0x20,0x40,0x20,0xfe,0x2,0x54,0x88,0x4,0x0,0x8,0xfc,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x13,0x12,0x13,0xfe,0x12,0x16,0x1a,0x32,0xd2,0x12,0x13,0x12,0x12,0x53,0x20,0x8,0xfc,0x0,0x8,0x88,0x50,0x50,0x20,0x20,0x50,0x98,0x8,0x0,0x4,0xfe,0x0,
-+0x0,0x0,0x3f,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3f,0x20,0x0,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,
-+0x8,0x8,0x8,0x8,0xfe,0x8,0x8,0xa,0xc,0x18,0xe8,0x8,0x8,0x8,0x28,0x10,0x0,0x0,0x0,0x4,0xfe,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0xfc,0x84,0x0,0x0,
-+0x2,0x1,0x7f,0x40,0x84,0x3e,0x0,0x1,0x7f,0x14,0x14,0x14,0x25,0x26,0x44,0x83,0x0,0x0,0xfe,0x42,0x74,0x40,0x40,0xf0,0x10,0xa0,0x40,0xa0,0x18,0xa,0x2,0xfe,
-+0x10,0x10,0x10,0x10,0xff,0x10,0x38,0x34,0x55,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x24,0xfe,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x2,0x3f,0x22,0x22,0x22,0x3e,0x22,0x1,0x1,0xff,0x1,0x2,0x4,0x8,0x30,0xc0,0x8,0xfc,0x88,0x88,0x88,0xf8,0x88,0x40,0x24,0xfe,0x0,0x80,0x40,0x30,0xe,0x4,
-+0x2,0x1,0x7f,0x44,0x88,0x1f,0x10,0x1f,0x10,0x14,0x17,0x10,0x28,0x28,0x4f,0x88,0x0,0x0,0xfe,0x42,0x24,0xf8,0x8,0xf8,0x80,0x90,0xf0,0x80,0x88,0x88,0xf8,0x8,
-+0x8,0x8,0x7f,0x8,0x9,0x1,0xff,0x1,0x1,0x1f,0x10,0x10,0x10,0x10,0x1f,0x10,0x20,0x28,0xfc,0x20,0x20,0x4,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0xf0,0x10,
-+0x1,0xff,0x14,0x14,0x7f,0x55,0x55,0x57,0x61,0x41,0x41,0x7f,0x41,0x41,0x7f,0x41,0x10,0x90,0x50,0x7c,0x50,0x90,0x10,0xfe,0x4,0x7e,0x44,0x44,0x44,0x44,0x7c,0x44,
-+0x1,0x0,0x3f,0x21,0x21,0x3f,0x22,0x24,0x28,0x2f,0x20,0x20,0x3f,0x40,0x40,0x80,0x0,0x88,0xfc,0x0,0x8,0xfc,0x0,0x80,0x90,0xf8,0x80,0x84,0xfe,0x80,0x80,0x80,
-+0x40,0x30,0x13,0x2,0xfe,0xb,0x12,0x37,0x5b,0x96,0x12,0x13,0x12,0x14,0x18,0x10,0x40,0x24,0xfe,0x40,0x48,0xfc,0x80,0x28,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x1,0x1,0x7f,0x2,0x4,0x18,0xe7,0x0,0x3f,0x4,0xf,0x0,0x0,0x4,0x2,0x1,0x0,0x8,0xfc,0x80,0x40,0x30,0xce,0x4,0xf8,0x0,0xe0,0x20,0x20,0x20,0x40,0x80,
-+0x20,0x20,0x20,0x27,0xf8,0x21,0x22,0x25,0x28,0x23,0x38,0xe1,0x40,0x0,0x0,0x0,0x40,0x40,0x48,0xfc,0xa0,0x10,0xe,0xf4,0x0,0xfc,0x80,0xf8,0x8,0x8,0x90,0x60,
-+0x10,0x10,0x10,0x17,0xf8,0x11,0x1a,0x35,0xd0,0x17,0x10,0x11,0x10,0x10,0x50,0x20,0x40,0x40,0x48,0xfc,0xa0,0x10,0xe,0xf4,0x0,0xfc,0x80,0xf8,0x8,0x8,0x90,0x60,
-+0x4,0x7e,0x44,0x47,0x44,0x7d,0x12,0x15,0x5c,0x53,0x50,0x51,0x5c,0xf0,0x40,0x0,0x40,0x40,0x48,0xfc,0xa0,0x10,0xe,0xf4,0x0,0xfc,0x80,0xf8,0x8,0x8,0x90,0x60,
-+0x0,0x78,0x48,0x4f,0x48,0x79,0x4a,0x4d,0x48,0x7b,0x48,0x49,0x48,0x48,0x48,0x98,0x40,0x40,0x48,0xfc,0xa0,0x10,0xe,0xf4,0x0,0xfc,0x80,0xf8,0x8,0x8,0x90,0x60,
-+0x10,0x10,0x10,0x10,0x13,0xfc,0x10,0x10,0x10,0x17,0x1c,0xf1,0x41,0x2,0x4,0x8,0x80,0x80,0x80,0x88,0xfc,0x88,0x88,0x88,0x88,0xfe,0x80,0x40,0x20,0x10,0xe,0x4,
-+0x12,0x1f,0x28,0x45,0x90,0x10,0x13,0x58,0x54,0x50,0x97,0x10,0x10,0x11,0x12,0x1c,0x44,0x7e,0xa0,0x10,0x40,0x48,0xfc,0x48,0x48,0x48,0xfe,0x40,0xa0,0x10,0xe,0x4,
-+0x10,0x10,0x11,0x21,0x22,0x64,0xa8,0x33,0x20,0x20,0x2f,0x21,0x21,0x22,0x27,0x20,0x80,0x80,0x40,0x40,0x20,0x10,0x4e,0xe4,0x0,0x8,0xfc,0x0,0x20,0x10,0xf8,0x8,
-+0x10,0x10,0x10,0x10,0x5b,0x54,0x50,0x90,0x10,0x1f,0x10,0x11,0x11,0x12,0x14,0x18,0x80,0x80,0x80,0x88,0xfc,0x88,0x88,0x88,0x88,0xfe,0x80,0x40,0x20,0x10,0xe,0x4,
-+0x2,0x1,0x7f,0x44,0x84,0x7f,0x4,0x1f,0x10,0x11,0x11,0x11,0x12,0x4,0x8,0x70,0x0,0x0,0xfe,0x42,0x44,0xfc,0x50,0xf8,0x10,0x10,0x10,0x90,0x90,0x82,0x82,0x7e,
-+0x8,0x9,0xff,0x8,0xa,0x7f,0x0,0x7f,0x0,0xff,0x8,0x2a,0x49,0x88,0x29,0x12,0x20,0x20,0xa0,0x7e,0x82,0x4,0x28,0x20,0x20,0xa0,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x0,0x7f,0x40,0x5f,0x41,0x41,0x41,0x4f,0x41,0x41,0x41,0x5f,0x40,0x40,0x7f,0x0,0x8,0xfc,0x0,0xf0,0x0,0x0,0x40,0xe0,0x0,0x0,0x20,0xf0,0x0,0x4,0xfe,0x0,
-+0x12,0x1f,0x28,0x45,0xbf,0x20,0x2f,0x20,0x20,0x27,0x20,0x20,0x2f,0x20,0x3f,0x0,0x48,0x7c,0xa0,0x10,0xfc,0x0,0xf8,0x80,0xa0,0xf0,0x80,0x90,0xf8,0x0,0xfc,0x0,
-+0x82,0x47,0x28,0x10,0x28,0x48,0x88,0x9,0x18,0x28,0x48,0x88,0x8,0x8,0x57,0x20,0x4,0xfe,0x20,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x13,0x12,0x12,0xfe,0x12,0x3a,0x36,0x52,0x52,0x92,0x12,0x13,0x12,0x13,0x10,0x8,0xfc,0x0,0xf8,0x20,0x20,0x20,0xf8,0x20,0x20,0x20,0x28,0xfc,0x0,0xfe,0x0,
-+0x0,0x4,0xfe,0x11,0x11,0x21,0x25,0x3f,0x65,0xa5,0x25,0x25,0x3d,0x22,0x4,0x8,0x40,0x20,0x24,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0xb,0x7e,0x4a,0x4a,0x4a,0x7a,0x4a,0x4a,0x7a,0x4a,0x4a,0x4b,0x7a,0x4b,0x0,0x8,0xfc,0x0,0xf8,0x20,0x20,0x20,0xf8,0x20,0x20,0x20,0x28,0xfc,0x0,0xfe,0x0,
-+0x0,0x8,0x7c,0x4b,0x4a,0x4a,0x7a,0x4a,0x4a,0x4a,0x4a,0x7a,0x44,0x4,0x8,0x10,0x40,0x20,0x24,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x47,0x34,0x14,0x4,0x4,0xf,0x12,0x22,0xe2,0x22,0x22,0x24,0x24,0x28,0x30,0x10,0xf8,0x10,0x10,0x10,0x10,0xf0,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x0,0x3f,0x0,0x0,0x0,0xff,0x4,0x4,0x8,0xf,0x0,0x0,0x0,0x2,0x1,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x20,0xc0,
-+0x2,0x2,0xff,0x4,0x4,0xa,0x9,0x11,0x22,0x44,0x3f,0x24,0x24,0x24,0xff,0x0,0x0,0x4,0xfe,0x80,0x90,0xa0,0x40,0x20,0x1c,0x8,0xf8,0x48,0x48,0x48,0xfe,0x0,
-+0x1,0x21,0x21,0x3f,0x20,0x8,0x4f,0x48,0x48,0x4b,0x48,0x50,0x10,0x27,0x40,0x80,0x0,0x8,0x8,0xf8,0x8,0x4,0xfe,0x4,0x4,0xfc,0x4,0x4,0x4,0xfc,0x4,0x0,
-+0x2,0x1,0x7f,0x44,0x88,0x8,0x3e,0x8,0x8,0x7e,0x8,0x8,0x14,0x12,0x20,0x43,0x0,0x0,0xfe,0x42,0x24,0xf8,0x88,0xa8,0xa8,0xa8,0xa8,0x30,0x52,0x52,0x8e,0x0,
-+0x8,0x8,0xff,0x8,0x3e,0x22,0x14,0x8,0x3f,0xc1,0x1,0x3f,0x1,0x2,0xc,0x30,0x20,0x24,0xfe,0x20,0xa0,0x48,0x30,0x10,0xee,0x4,0x10,0xf8,0x0,0xc0,0x30,0x8,
-+0x1,0x1,0xff,0x4,0x9,0x11,0x2f,0xc1,0x3f,0x1,0x1,0x1f,0x1,0x1,0x7f,0x0,0x0,0x4,0xfe,0x40,0x20,0x10,0xee,0x4,0xf8,0x0,0x20,0xf0,0x0,0x8,0xfc,0x0,
-+0x10,0x20,0x7f,0x49,0x49,0x7f,0x49,0x49,0x7f,0x49,0xc,0x15,0x15,0x27,0x44,0x83,0x0,0x8,0x48,0x28,0x8,0x48,0x28,0x8,0xe,0xf8,0x8,0x8,0x48,0xc8,0x2,0xfe,
-+0x10,0x11,0x17,0x24,0x24,0x67,0xa4,0x24,0x27,0x24,0x20,0x21,0x21,0x22,0x24,0x28,0x80,0x8,0xfc,0x48,0x48,0xf8,0x48,0x88,0xf8,0x88,0x90,0x50,0x68,0x7a,0x42,0x3e,
-+0x20,0x20,0x23,0x3a,0x4b,0x50,0x8f,0x20,0x23,0x22,0x22,0x22,0x2a,0x30,0x21,0x6,0x40,0x48,0xfc,0x48,0xf8,0x40,0xfe,0x8,0xfc,0x8,0x48,0x48,0x48,0xb0,0xc,0x4,
-+0x10,0x11,0x13,0x12,0x5a,0x57,0x52,0x92,0x13,0x12,0x10,0x11,0x11,0x12,0x14,0x18,0x80,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x80,0xc8,0x48,0x54,0x5e,0x42,0x3e,
-+0x0,0x40,0x33,0x12,0x83,0x60,0x2f,0x8,0x13,0x22,0xe2,0x22,0x22,0x20,0x21,0x26,0x40,0x48,0xfc,0x48,0xf8,0x40,0xfe,0x8,0xfc,0x8,0x48,0x48,0x48,0xb0,0xc,0x4,
-+0x20,0x20,0x20,0x27,0xfc,0x24,0x24,0x27,0x24,0x24,0x3c,0xe7,0x44,0x0,0x0,0x0,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0xfc,0x44,0x44,0x44,0xfc,0x44,0x40,0x40,0x40,
-+0x0,0x3f,0x20,0x20,0x3f,0x20,0x20,0x3f,0x0,0x20,0x24,0x3e,0x20,0x20,0x2e,0x70,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x80,0x84,0x98,0xe0,0x80,0x82,0x82,0x7e,
-+0x10,0x17,0x14,0x14,0xfc,0x17,0x14,0x1c,0x34,0xd5,0x16,0x14,0x14,0x14,0x57,0x24,0x4,0xfe,0x44,0x44,0x44,0xfc,0x44,0xc4,0xe4,0x5c,0x4c,0x44,0x44,0x4,0xfc,0x4,
-+0x0,0x7f,0x41,0x41,0x41,0x5f,0x41,0x43,0x43,0x45,0x49,0x51,0x41,0x41,0x7f,0x40,0x4,0xfe,0x4,0x4,0x24,0xf4,0x4,0x4,0x84,0x64,0x34,0x14,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x13,0x10,0xfc,0x10,0x17,0x18,0x30,0xd3,0x12,0x12,0x12,0x12,0x53,0x22,0x8,0x3c,0xc0,0x40,0x40,0x44,0xfe,0x40,0x48,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x10,0x13,0xfe,0x12,0x16,0x1a,0x32,0xd2,0x12,0x12,0x12,0x14,0x54,0x28,0x40,0x20,0x24,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x3f,0x22,0x3f,0x20,0x2f,0x28,0x2f,0x20,0x3f,0x21,0x22,0x5f,0x42,0x8a,0x4,0x84,0xfe,0x0,0xc0,0x3e,0xa2,0xa4,0xa8,0x24,0xa2,0x22,0x32,0xac,0x20,0x20,0x20,
-+0x10,0xd,0x44,0x50,0x4b,0x40,0x60,0x57,0x40,0x48,0x53,0x72,0x52,0x53,0x52,0x40,0x4,0xfe,0x4,0x64,0x84,0x84,0xa4,0xf4,0x84,0xa4,0xf4,0x24,0x24,0xe4,0x14,0x8,
-+0x10,0x10,0x10,0x13,0x10,0xfd,0x11,0x11,0x10,0x10,0x10,0x1c,0xe0,0x40,0x7,0x0,0x80,0x40,0x48,0xfc,0x0,0x8,0x8,0x8,0x90,0x90,0x90,0xa0,0x20,0x44,0xfe,0x0,
-+0x10,0x10,0x10,0x13,0xfc,0x11,0x15,0x19,0x30,0xd0,0x10,0x10,0x10,0x10,0x57,0x20,0x80,0x40,0x48,0xfc,0x0,0x8,0x8,0x8,0x90,0x90,0x90,0xa0,0x20,0x44,0xfe,0x0,
-+0x1,0x11,0x7f,0x51,0x51,0x57,0x55,0x55,0x55,0x57,0x51,0x73,0x45,0x9,0x1,0x1,0x4,0x44,0xe4,0x4,0x54,0xf4,0x54,0x54,0x54,0xd4,0x14,0x84,0x44,0x4,0x14,0x8,
-+0x10,0x10,0x10,0x13,0x7c,0x54,0x57,0x54,0x55,0x7d,0x51,0x15,0x1d,0xf5,0x41,0x1,0x90,0x90,0x90,0xfc,0x90,0x94,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x8,0x7c,0x48,0x4b,0x48,0x78,0x4f,0x48,0x49,0x79,0x49,0x49,0x49,0x49,0x89,0x19,0x90,0x90,0x90,0xfc,0x90,0x94,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x20,0x10,0x13,0xfe,0x44,0x29,0x29,0xff,0x11,0x15,0xfe,0x10,0x11,0x12,0x20,0x40,0x20,0x24,0xfe,0x20,0x24,0xfe,0x24,0x24,0xfc,0x24,0x70,0xa8,0x2e,0x24,0x20,0x20,
-+0x2,0x2,0x72,0x5f,0x52,0x52,0x52,0x53,0x52,0x5e,0x52,0x72,0x52,0x2,0xb,0x4,0x20,0x10,0x14,0xfe,0x0,0x44,0xc4,0x44,0x44,0x48,0x28,0x28,0x28,0x0,0xfe,0x0,
-+0x8,0x8,0xff,0x9,0x1,0x7f,0x1,0x9,0x5,0xff,0x3,0x5,0x9,0x31,0xc1,0x1,0x20,0x24,0xfe,0x20,0x8,0xfc,0x0,0x20,0x44,0xfe,0x80,0x40,0x30,0xe,0x4,0x0,
-+0x1,0x1,0x1,0x7f,0x1,0x21,0x19,0x9,0xff,0x3,0x5,0x9,0x31,0xc1,0x1,0x1,0x0,0x0,0x8,0xfc,0x0,0x10,0x30,0x44,0xfe,0x80,0x40,0x30,0x1e,0x4,0x0,0x0,
-+0x10,0x14,0xfe,0x10,0x7d,0x56,0x54,0x54,0x7c,0x10,0x38,0x34,0x54,0x90,0x10,0x13,0x20,0x20,0x7c,0x88,0x14,0xfe,0x84,0x94,0x94,0x94,0xa4,0xa4,0x20,0x58,0x84,0x2,
-+0x8,0x8,0xff,0x8,0x4,0x24,0x25,0x26,0x24,0x4,0x3f,0x24,0x24,0x24,0xff,0x0,0x20,0x24,0xfe,0x20,0x90,0xf8,0x0,0x40,0x20,0x8,0xfc,0x48,0x48,0x48,0xfe,0x0,
-+0x8,0x8,0x7e,0x8,0x1c,0x2a,0x49,0xa,0x2,0xff,0x4,0x8,0x4,0x3,0x4,0x18,0x20,0x28,0xfc,0x20,0x70,0xac,0x24,0x20,0x4,0xfe,0x20,0x20,0x40,0x80,0x60,0x10,
-+0x10,0x12,0x11,0x10,0xff,0x10,0x30,0x38,0x57,0x50,0x90,0x10,0x10,0x10,0x1f,0x10,0x0,0x8,0x10,0xa4,0xfe,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x10,0x12,0x11,0x10,0xff,0x10,0x14,0x18,0x33,0xd0,0x10,0x10,0x10,0x10,0x5f,0x20,0x0,0x8,0x10,0xa4,0xfe,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x12,0x1f,0x28,0x45,0x84,0x24,0x25,0x26,0x24,0x4,0x3f,0x24,0x24,0x24,0xff,0x0,0x48,0x7c,0xa0,0x10,0x80,0xfc,0x40,0x20,0x20,0x8,0xfc,0x48,0x48,0x48,0xfe,0x0,
-+0x20,0x1b,0x49,0x41,0x7f,0x41,0x5f,0x59,0x55,0x51,0x5f,0x43,0x45,0x49,0x51,0x41,0x4,0xfe,0x4,0x14,0xfc,0x4,0xf4,0x34,0x54,0x14,0xf4,0x84,0x44,0x34,0x14,0xc,
-+0x10,0x8,0x4,0x7f,0x0,0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x10,0x20,0x48,0xfc,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x42,0x31,0x15,0x4,0x87,0x64,0x25,0xd,0x15,0x25,0xe5,0x24,0x25,0x26,0x24,0x24,0x4,0x7e,0x4,0x54,0xfc,0x44,0xf4,0x54,0xf4,0x54,0xf4,0xe4,0x54,0x4c,0x44,0xc,
-+0x2,0x41,0x25,0x24,0x7,0x4,0xe5,0x25,0x25,0x25,0x25,0x24,0x2d,0x36,0x24,0x4,0x4,0x7e,0x4,0x54,0xfc,0x44,0xf4,0x54,0xf4,0x54,0xf4,0xe4,0x54,0x4c,0x44,0xc,
-+0x10,0x12,0x12,0x12,0xfe,0x12,0x14,0x1b,0x32,0xd2,0x12,0x12,0x12,0x10,0x51,0x26,0x90,0x94,0x9e,0xa8,0xc4,0x84,0x88,0xfc,0x8,0x48,0x48,0x68,0xa8,0xa2,0x22,0x1e,
-+0x8,0x48,0x48,0x49,0x4a,0x48,0x1f,0x10,0x11,0x11,0x11,0x11,0x12,0x4,0x18,0xe0,0x80,0x84,0xfe,0x20,0x10,0x10,0xf8,0x10,0x10,0x10,0x10,0x90,0x90,0x82,0x82,0x7e,
-+0x22,0x22,0x3f,0x22,0xaf,0xaa,0xaa,0xaa,0x2f,0x22,0x27,0x2a,0x32,0x22,0x22,0x22,0x10,0x10,0xdc,0x24,0xc8,0xbe,0xa2,0xaa,0xaa,0x2a,0x2a,0xaa,0x2a,0x8,0x14,0x62,
-+0x10,0x12,0x22,0x22,0x42,0xfe,0x8,0x13,0x22,0xfe,0x2,0x2,0x1c,0xe0,0x41,0xe,0x90,0x90,0x9e,0xa8,0xc4,0x84,0x88,0xfc,0x8,0x48,0x48,0x68,0xa0,0xa2,0x22,0x1e,
-+0x10,0x11,0x10,0x54,0x58,0x57,0x50,0x90,0x10,0x13,0x10,0x28,0x24,0x40,0x8f,0x0,0x0,0x8,0x90,0xa0,0x4,0xfe,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x1,0x41,0x35,0x15,0x85,0x65,0x25,0x1,0x10,0x27,0xe5,0x25,0x25,0x25,0x3f,0x20,0x20,0x20,0x24,0x3e,0x50,0x88,0x8,0x0,0x8,0xfc,0x28,0x28,0x28,0x28,0xfe,0x0,
-+0x0,0x8,0xff,0x12,0x12,0x13,0x12,0xfe,0x13,0x12,0x12,0x12,0x1e,0xf2,0x43,0x2,0x80,0x48,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x84,0x48,0x30,0x10,0x8e,0x4,0x0,
-+0x22,0x21,0x20,0x27,0xfc,0x24,0x77,0x6c,0xa4,0x27,0x24,0x25,0x25,0x26,0x24,0x20,0x0,0x0,0x3e,0xa2,0xa4,0xa4,0xa8,0xa4,0xa4,0xa2,0x22,0x22,0xb4,0xa8,0x20,0x20,
-+0x0,0x44,0x2b,0x12,0x2a,0x4b,0x8a,0xa,0x1b,0x2a,0x4a,0x8a,0xa,0xa,0x53,0x22,0x80,0x48,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x84,0x48,0x30,0x10,0x8e,0x4,0x0,
-+0x0,0x3f,0x24,0x22,0x2f,0x28,0x2f,0x28,0x2f,0x28,0x29,0x2b,0x4c,0x48,0x80,0x0,0x84,0xfe,0x0,0x0,0xbe,0xa2,0xa4,0xa8,0xa4,0x22,0x22,0xa2,0xb4,0x28,0x20,0x20,
-+0x8,0x5,0x3f,0x21,0x21,0x3f,0x21,0x21,0x3f,0x21,0x20,0x24,0x26,0x79,0x20,0x0,0x0,0x0,0xfc,0x44,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,0x40,
-+0x8,0x5,0x3f,0x21,0x21,0x3f,0x21,0x21,0x3f,0x21,0x20,0x24,0x26,0x79,0x21,0x2,0x4,0x7e,0xc4,0x44,0x44,0x7c,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x84,0x14,0x8,
-+0x0,0x40,0x33,0x12,0x82,0x63,0x26,0xa,0x13,0x22,0xe2,0x22,0x22,0x22,0x23,0x22,0x80,0x48,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x84,0x48,0x30,0x10,0x8e,0x4,0x0,
-+0x11,0x11,0x17,0x11,0xf8,0x17,0x14,0x18,0x33,0xd0,0x10,0x10,0x10,0x11,0x51,0x2e,0x10,0x10,0xfc,0x10,0x0,0xfe,0x82,0x84,0xf8,0x88,0x88,0x88,0x88,0x8,0x28,0x10,
-+0x4,0x4,0x7f,0x4,0x4,0x7f,0x42,0x82,0x1f,0x4,0x4,0x4,0x8,0x8,0x10,0x20,0x40,0x48,0xfc,0x40,0x40,0xfe,0x2,0x14,0xf8,0x10,0x10,0x10,0x10,0x10,0xa0,0x40,
-+0x2,0x1,0x7f,0x41,0x91,0x11,0x1f,0x11,0x21,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0xfe,0x2,0x4,0x20,0xf0,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,
-+0x2,0x2,0x2,0x3f,0x2,0x2,0xff,0x1,0x2,0x4,0xc,0x14,0x27,0x44,0x84,0x3,0x0,0x0,0x88,0xd8,0x20,0x44,0xfe,0x0,0x0,0x10,0x30,0xc0,0x0,0x4,0x4,0xfc,
-+0x8,0x8,0x8,0x17,0x10,0x30,0x50,0x9f,0x11,0x13,0x15,0x19,0x11,0x11,0x10,0x10,0x80,0x80,0x84,0xec,0x90,0xa0,0xc4,0xfe,0x0,0x8,0x30,0xc0,0x4,0x4,0xfc,0x0,
-+0x20,0x20,0x20,0x27,0xf8,0x48,0x48,0x4f,0x49,0x8b,0x55,0x21,0x51,0x49,0x80,0x0,0x80,0x80,0x84,0xec,0x90,0xa0,0xc4,0xfe,0x0,0x8,0x30,0xc0,0x4,0x4,0xfc,0x0,
-+0x1,0xff,0x14,0x14,0x7f,0x55,0x55,0x55,0x55,0x55,0x63,0x41,0x7f,0x41,0x7f,0x41,0x20,0xa0,0x3c,0x44,0xc4,0x28,0x10,0x28,0xc6,0x4,0x7e,0x44,0x44,0x44,0x7c,0x44,
-+0x10,0x10,0x10,0x15,0x59,0x52,0x50,0x90,0x11,0x16,0x11,0x11,0x29,0x25,0x41,0x81,0x80,0x80,0xfc,0x4,0x88,0x50,0x20,0x50,0x8e,0x4,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x41,0x31,0x17,0x81,0x60,0x2f,0x8,0x10,0x10,0x27,0xe0,0x21,0x21,0x22,0x24,0x28,0x10,0x10,0xfc,0x10,0x0,0xfe,0x2,0x84,0x88,0xfc,0x88,0x8,0x8,0x8,0x50,0x20,
-+0x22,0x22,0xff,0x22,0x22,0x3e,0x8,0x7f,0x49,0x49,0x7f,0x8,0xff,0x8,0x9,0xa,0x20,0x20,0xa0,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x44,0x44,0xc4,0x84,0x14,0x8,
-+0x0,0x0,0x1f,0x10,0x11,0x11,0x21,0x7f,0x1,0x1,0x9,0x9,0x11,0x21,0x45,0x2,0x20,0xf0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x20,0x10,0x8,0xc,0x4,0x0,
-+0x0,0x3f,0x1,0x7f,0x41,0x9d,0x1,0x1d,0x1,0x3f,0x21,0x21,0x3f,0x21,0x21,0x3f,0x10,0xf8,0x0,0xfe,0x2,0x74,0x0,0x70,0x0,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,
-+0x20,0x23,0x38,0x47,0x84,0x7b,0x20,0x23,0xf8,0x27,0x24,0x24,0x2f,0x34,0x24,0x7,0x8,0xfc,0x40,0xfe,0x42,0x58,0x40,0x58,0x40,0xfc,0x44,0x44,0xfc,0x44,0x44,0xfc,
-+0x4,0x7f,0x4,0x3f,0x1,0x7f,0x41,0x9d,0x1,0x1d,0x1,0x3f,0x21,0x3f,0x21,0x3f,0x48,0xfc,0x40,0xf8,0x0,0xfe,0x2,0x74,0x0,0x70,0x0,0xf8,0x8,0xf8,0x8,0xf8,
-+0x3f,0x4,0x8,0x1f,0x28,0x48,0x8f,0x4,0xfe,0x10,0x20,0x7e,0xa3,0x22,0x3e,0x20,0xf8,0x0,0x10,0xf8,0x10,0x10,0xf0,0x4,0xfe,0x20,0x44,0xfe,0x44,0x44,0x7c,0x40,
-+0x0,0x3f,0x21,0x3f,0x21,0x3f,0x22,0x4,0x3f,0x2,0x4,0x3f,0x9,0x11,0x65,0x2,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x20,0xc0,0x10,0x8,0xf8,0x20,0x18,0x8,0x0,
-+0x13,0x12,0x12,0x23,0x22,0x62,0xa3,0x20,0x2f,0x2a,0x2a,0x2f,0x2a,0x2a,0x2f,0x28,0xf8,0x48,0x48,0xf8,0x48,0x48,0xf8,0x0,0xbe,0xaa,0xaa,0xbe,0xaa,0xaa,0xbe,0xa2,
-+0x1,0x2,0x4,0x8,0x3f,0x8,0x10,0x24,0x7e,0x1,0x1,0x3f,0x1,0x1,0xff,0x0,0x0,0x0,0x20,0x10,0xf8,0x10,0x20,0x48,0xfc,0x0,0x10,0xf8,0x0,0x4,0xfe,0x0,
-+0x20,0x23,0x20,0x27,0xfc,0x2b,0x20,0x2b,0x30,0xe7,0x24,0x24,0x27,0x24,0xa4,0x47,0x8,0xfc,0x40,0xfe,0x42,0x5c,0x40,0x58,0x0,0xfc,0x44,0x44,0xfc,0x44,0x44,0xfc,
-+0x2,0x3f,0x22,0x22,0x22,0x3f,0x22,0x22,0x22,0x3e,0x22,0x22,0x22,0x22,0x4b,0x84,0x40,0x40,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x84,0x28,0x10,
-+0x1,0x11,0x9,0x1,0x7f,0x1,0x5,0x9,0x11,0x1,0xff,0x2,0x4,0x8,0x10,0x60,0x0,0x10,0x20,0x8,0xfc,0x0,0x40,0x30,0x10,0x4,0xfe,0x80,0x40,0x20,0x1c,0x8,
-+0x0,0x47,0x34,0x14,0x4,0x87,0x64,0x24,0xc,0x17,0xe4,0x24,0x24,0x24,0x27,0x24,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x13,0x10,0xfc,0x17,0x39,0x36,0x54,0x51,0x91,0x12,0x14,0x10,0x11,0x16,0x40,0x50,0xf8,0x40,0x44,0xfe,0x10,0x8c,0xf4,0x10,0x10,0xa0,0x40,0xb0,0xe,0x4,
-+0x10,0x13,0x12,0x12,0xfe,0x13,0x30,0x38,0x57,0x54,0x90,0x10,0x11,0x11,0x12,0x14,0x4,0xfe,0x94,0x94,0x94,0xfc,0x40,0x24,0xfe,0x80,0xf8,0x88,0x8,0x8,0x28,0x10,
-+0x0,0x40,0x31,0x12,0x4,0x9,0x10,0x10,0x27,0xe0,0x20,0x20,0x22,0x21,0x20,0x0,0x80,0x80,0x40,0x20,0x10,0x8,0x8e,0x84,0xf0,0x10,0x20,0x40,0x80,0x0,0xc0,0x40,
-+0x0,0x3f,0x20,0x2f,0x28,0x28,0x2f,0x28,0x28,0x2f,0x20,0x2f,0x20,0x20,0x5f,0x80,0x4,0xfe,0x8,0xfc,0x88,0x88,0xf8,0x88,0x88,0xf8,0x80,0xf8,0x80,0x84,0xfe,0x0,
-+0x3,0x3c,0x4,0x7f,0x4,0xe,0x15,0x64,0x5,0x1,0xff,0x3,0x5,0x19,0x61,0x1,0x8,0x8,0x48,0xc8,0x48,0x48,0x48,0x8,0x18,0x4,0xfe,0x80,0x40,0x3c,0x8,0x0,
-+0x3,0x3c,0x4,0x7f,0x4,0xe,0x15,0x65,0x11,0x1f,0x21,0x1,0xff,0x1,0x1,0x1,0x8,0x8,0x48,0xc8,0x48,0x48,0x48,0x18,0x0,0xf8,0x0,0x4,0xfe,0x0,0x0,0x0,
-+0x6,0x78,0x8,0xfe,0x9,0x1c,0x2a,0x49,0x2,0xc,0x31,0xc9,0x5,0x9,0x11,0x3,0x40,0x44,0x7e,0xa4,0x24,0x44,0x94,0x8,0x80,0x60,0x1e,0x24,0x40,0x30,0x10,0x0,
-+0x12,0x1f,0x28,0x45,0x1,0xff,0x14,0x13,0x14,0x1f,0x1,0x3f,0x22,0x27,0x20,0x20,0x48,0x7c,0xa0,0x10,0x4,0xfe,0x50,0x90,0x50,0xf0,0x8,0xfc,0x48,0xe8,0x28,0x10,
-+0x4,0x44,0x2b,0x12,0x2a,0x4b,0x8a,0xa,0x1b,0x28,0x48,0x8b,0x8,0x8,0x57,0x20,0x0,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x40,0x50,0xf8,0x40,0x44,0xfe,0x0,
-+0x2,0x1,0xff,0x4,0x12,0x11,0x12,0x14,0x1f,0x1,0x7f,0x42,0x44,0x4f,0x40,0x40,0x0,0x4,0xfe,0x40,0x90,0x10,0x90,0x50,0xf0,0x4,0xfe,0x4,0x44,0xe4,0x14,0x8,
-+0x0,0x40,0x2f,0x10,0x85,0x64,0x25,0x7,0x10,0x2f,0xe8,0x29,0x2b,0x28,0x28,0x28,0x80,0x48,0xfc,0x0,0x28,0xc8,0x28,0xf8,0x84,0xfe,0x84,0x24,0xf4,0x4,0x14,0x8,
-+0x0,0x13,0xfa,0x22,0x23,0x22,0xfa,0x23,0x20,0x20,0x23,0x3c,0xe0,0x40,0xf,0x0,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x40,0x50,0xf8,0x40,0x40,0x44,0xfe,0x0,
-+0x1,0x1,0x7f,0x1,0x5,0x9,0x31,0xc1,0xf,0x0,0x1,0x7f,0x1,0x1,0x5,0x2,0x0,0x8,0xfc,0x0,0x40,0x30,0xe,0x4,0xe0,0x40,0x88,0xfc,0x0,0x0,0x0,0x0,
-+0x0,0x3f,0x21,0x21,0x3f,0x21,0x21,0x21,0x3f,0x1,0x1,0x7f,0x1,0x1,0xff,0x0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x0,0x8,0xfc,0x0,0x4,0xfe,0x0,
-+0x20,0x20,0x3d,0x49,0x95,0x7f,0x55,0x55,0x7d,0x54,0x54,0x7d,0x0,0x1c,0xe3,0x40,0x0,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0x28,0xfc,0x20,0x24,0xfe,0x0,
-+0x20,0x18,0x8,0x0,0xfe,0x4,0x8,0x1c,0x2a,0x4a,0x88,0x8,0x8,0x8,0x8,0x8,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x8,0x8,0xff,0x8,0x6,0x78,0x8,0x8,0xff,0x8,0x1c,0x1a,0x2a,0x48,0x88,0x8,0x20,0x24,0xfe,0x20,0x8,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x8,0x28,0x10,
-+0x8,0xff,0xa,0x2,0x1f,0x4,0x4,0x8,0x10,0x10,0x7e,0x12,0x12,0x22,0x4a,0x85,0x20,0xfe,0x20,0x0,0xf0,0x10,0x90,0x60,0x20,0x24,0xfe,0x24,0x24,0x44,0x94,0x8,
-+0x1,0x1,0x1,0xff,0x1,0x3f,0x21,0x21,0x21,0x3f,0x29,0x5,0x2,0x5,0x18,0x60,0x0,0x0,0x4,0xfe,0x0,0xf8,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x80,0x70,0xe,
-+0x0,0xff,0x4,0x3f,0x24,0x24,0x3f,0x1,0x1,0xff,0x3,0x3,0x5,0x19,0x61,0x1,0x4,0xfe,0x48,0xfc,0x48,0x48,0xf8,0x0,0x4,0xfe,0x80,0x40,0x30,0xe,0x4,0x0,
-+0x0,0xff,0x0,0x0,0x3e,0x22,0x22,0x22,0x32,0x2a,0x22,0x22,0x22,0x22,0x2a,0x24,0x4,0xfe,0x0,0x8,0xfc,0x88,0x88,0x88,0xc8,0xa8,0x88,0x88,0x88,0x88,0xa8,0x90,
-+0x0,0x3f,0x20,0x20,0x3f,0x22,0x22,0x23,0x22,0x22,0x22,0x22,0x44,0x44,0x88,0x10,0x8,0xfc,0x0,0x4,0xfe,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0x88,0x50,0x20,
-+0x1,0x7f,0x40,0x41,0x7f,0x48,0x49,0x4f,0x49,0x49,0x49,0x49,0x55,0x52,0xa0,0x1,0x20,0xa0,0x20,0x20,0xa4,0x7e,0x24,0xa4,0x24,0x24,0x24,0x44,0x44,0x84,0xa8,0x10,
-+0x0,0x8,0xfd,0x11,0x11,0x21,0x25,0x7f,0xa4,0x24,0x24,0x25,0x3d,0x22,0x4,0x0,0x8,0x1c,0xe0,0x0,0x20,0x20,0x24,0xfe,0x20,0x20,0xa8,0x24,0x22,0x22,0xa0,0x40,
-+0x0,0x3f,0x21,0x21,0x21,0x21,0x3f,0x21,0x21,0x21,0x21,0x22,0x42,0x44,0x88,0x10,0x8,0xfc,0x0,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x1,0x7,0x7c,0x4,0x4,0x5,0xff,0xc,0xe,0x15,0x14,0x24,0x44,0x4,0x4,0x4,0x4,0x84,0x4,0x24,0x24,0x24,0xa4,0x24,0x24,0xa4,0xa4,0x24,0x4,0x4,0x14,0x8,
-+0x10,0x1f,0x10,0x27,0x24,0x64,0xa4,0x27,0x20,0x20,0x2f,0x20,0x21,0x22,0x2c,0x20,0x4,0xfe,0xa4,0xfe,0xa4,0xa4,0xa4,0xfc,0x40,0x44,0xfe,0xe0,0x50,0x4e,0x44,0x40,
-+0x10,0x10,0x1f,0x22,0x22,0x67,0xa4,0x28,0x34,0x22,0x21,0x22,0x24,0x28,0x20,0x20,0x4,0x44,0xe4,0x4,0x14,0xd4,0x54,0x54,0x94,0x94,0x14,0x4,0x4,0x4,0x14,0x8,
-+0x10,0x11,0x1f,0x21,0x21,0x7f,0xa1,0x23,0x23,0x25,0x25,0x29,0x31,0x21,0x21,0x21,0x84,0xc4,0x4,0x4,0x14,0xf4,0x14,0x14,0x94,0x54,0x54,0x4,0x4,0x4,0x14,0x8,
-+0x1,0x0,0x1f,0x10,0x97,0x51,0x51,0x1f,0x31,0x53,0xd3,0x15,0x29,0x21,0x41,0x1,0x0,0x84,0xfe,0x44,0x84,0x14,0x54,0xf4,0x14,0x94,0x54,0x54,0x4,0x4,0x14,0x8,
-+0x2,0x1,0x1,0x0,0x7f,0x0,0x0,0x10,0x8,0x8,0x4,0x4,0x4,0x0,0xff,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x4,0xfe,0x0,
-+0x10,0x10,0x10,0x54,0x3b,0x10,0xfd,0x11,0x38,0x34,0x54,0x90,0x10,0x10,0x17,0x10,0x80,0x40,0x40,0x8,0xfc,0x0,0x8,0x8,0x90,0x90,0x90,0xa0,0xa0,0x24,0xfe,0x0,
-+0x0,0x47,0x34,0x14,0x4,0x84,0x67,0x24,0xc,0x14,0xe4,0x24,0x24,0x28,0x29,0x32,0x4,0xfe,0x40,0x40,0x44,0x44,0xfe,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x14,0x8,
-+0x1,0x3f,0x1,0x1,0xff,0x1,0x1,0x3f,0x21,0x11,0xd,0x9,0x31,0xc1,0x5,0x2,0x10,0xf8,0x10,0x14,0xfe,0x10,0x10,0xf0,0x8,0x98,0x60,0x20,0x18,0xe,0x4,0x0,
-+0x2,0x2,0x2,0x2,0x7f,0x2,0x2,0x2,0x2,0x2,0x2,0x4,0x4,0x8,0x8,0x70,0x0,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x88,0x50,0x20,
-+0x0,0x10,0xff,0x20,0x22,0x22,0xfb,0x23,0x20,0x27,0x24,0x3c,0xe5,0x44,0x4,0x4,0x40,0x24,0xfe,0x90,0x64,0x94,0xc,0xfc,0x40,0xfe,0x42,0x92,0xfa,0x2,0xa,0x4,
-+0x0,0xb,0x7e,0x4a,0x4b,0x4a,0x4a,0x4b,0x48,0x48,0x4b,0x78,0x48,0x0,0xf,0x0,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x40,0x50,0xf8,0x40,0x40,0x44,0xfe,0x0,
-+0x10,0x10,0x1f,0x21,0x21,0x6f,0xa9,0x29,0x29,0x29,0x2a,0x2c,0x28,0x28,0x28,0x28,0x0,0x4,0xfe,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xd4,0x8c,0x4,0x4,0x14,0x8,
-+0x1,0xfe,0x24,0x24,0x3d,0x24,0x24,0x24,0x3f,0x24,0x24,0x24,0x3e,0xe4,0x5,0x6,0x4,0xcc,0x50,0x0,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x4,0x4,0xff,0x24,0x10,0x17,0x1,0x71,0x13,0x10,0x10,0x17,0x10,0x28,0x47,0x0,0x40,0x44,0xfe,0x40,0x90,0xf8,0x0,0x50,0xf8,0x40,0x48,0xfc,0x40,0x46,0xfc,0x0,
-+0x0,0x40,0x2f,0x21,0x1,0x2,0xe7,0x20,0x20,0x20,0x2f,0x20,0x20,0x50,0x8f,0x0,0x80,0x88,0xfc,0x0,0x40,0x50,0xf8,0x40,0x40,0x48,0xfc,0x40,0x40,0x46,0xfc,0x0,
-+0x20,0x27,0x25,0x3f,0x44,0x85,0x7c,0x27,0x24,0xfd,0x24,0x25,0x2d,0x36,0x28,0x0,0x44,0xfe,0x8,0xfe,0x90,0xfc,0x94,0xfe,0x94,0xfc,0x94,0x98,0x98,0x96,0x90,0x90,
-+0x1,0x3f,0x24,0x22,0x3f,0x22,0x2f,0x22,0x3f,0x22,0x2f,0x26,0x4a,0x52,0xa2,0x2,0x8,0xfc,0x20,0x48,0xfc,0x40,0xf8,0x48,0xfe,0x48,0xf8,0x68,0x50,0x4e,0x44,0x40,
-+0x10,0x10,0x10,0x18,0x55,0x52,0x54,0x98,0x10,0x13,0x10,0x10,0x10,0x10,0x10,0x10,0x40,0x40,0xa0,0xa0,0x10,0x88,0x4e,0x44,0x0,0xf8,0x8,0x10,0xa0,0x40,0x20,0x20,
-+0x0,0x88,0x65,0x24,0x0,0x81,0x6d,0x24,0xc,0x14,0xe7,0x24,0x24,0x2a,0x31,0x20,0x20,0x28,0xfc,0x40,0xa0,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x26,0xfc,0x0,
-+0x2,0x1,0x7f,0x40,0x89,0x11,0x21,0x1f,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x1,0x0,0x0,0xfe,0x2,0x24,0x10,0x8,0xf0,0x10,0x10,0x10,0x10,0x10,0x50,0x20,0x0,
-+0x8,0x8,0x14,0x13,0x21,0x40,0xbe,0x0,0x11,0x49,0x2a,0x2a,0x2a,0x7,0x78,0x21,0x20,0x20,0x20,0x24,0x7e,0x84,0x44,0x44,0x48,0x28,0x28,0x10,0x28,0x28,0x46,0x84,
-+0x8,0x7c,0x48,0x48,0x49,0x7a,0x4d,0x48,0x4a,0x7a,0x49,0x49,0x49,0x48,0x4f,0x98,0x40,0x40,0xa0,0xa0,0x10,0xe,0xf4,0x0,0x88,0x48,0x48,0x50,0x50,0x24,0xfe,0x0,
-+0x20,0x24,0x3a,0x42,0x40,0xf8,0x26,0x22,0xfa,0x22,0x23,0x2a,0x32,0x25,0x8,0x0,0x10,0x14,0xfe,0x20,0x50,0x94,0xfe,0x10,0x10,0x14,0xfe,0x10,0x10,0x16,0xfc,0x0,
-+0x2,0x1,0xff,0x4,0xc,0xc,0x14,0x24,0x44,0x2,0x29,0x29,0x28,0x48,0x7,0x0,0x0,0x4,0xfe,0x40,0x60,0x58,0x4c,0x44,0x40,0x0,0x10,0x28,0x24,0x24,0xe0,0x0,
-+0x10,0x10,0x17,0x14,0x58,0x57,0x51,0x91,0x12,0x13,0x10,0x28,0x25,0x42,0x84,0x0,0x40,0x48,0xfc,0x80,0xa0,0xf0,0x20,0x20,0x24,0xfe,0x20,0xa8,0x26,0x22,0xa0,0x40,
-+0x10,0x10,0x27,0x40,0x48,0xfb,0x11,0x21,0x42,0xfb,0x0,0x0,0x39,0xc2,0x44,0x0,0x40,0x48,0xfc,0x80,0xa0,0xf0,0x20,0x20,0x24,0xfe,0x20,0xa8,0x26,0x22,0xa0,0x40,
-+0x10,0x10,0x57,0x3a,0x12,0xff,0x12,0x32,0x3b,0x56,0x52,0x92,0x12,0x12,0x13,0x12,0x40,0x28,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x84,0x48,0x30,0x10,0x8e,0x4,0x0,
-+0x0,0x40,0x2f,0x10,0x3,0x2,0xa,0x12,0x23,0xe2,0x20,0x21,0x22,0x24,0x29,0x0,0x80,0x44,0xfe,0x8,0xfc,0x8,0x8,0x8,0xf8,0x48,0x40,0x50,0x4c,0x44,0x40,0x80,
-+0x10,0xb,0x40,0x22,0xa,0x54,0x21,0x22,0x25,0x1,0xff,0x5,0x9,0x11,0x61,0x1,0x8,0xfc,0x88,0x8c,0x8a,0x88,0x8,0x28,0x10,0x4,0xfe,0x40,0x20,0x1c,0x8,0x0,
-+0x10,0xb,0x40,0x22,0xa,0x55,0x22,0x21,0x9,0x5,0xff,0x5,0x9,0x11,0x61,0x1,0x8,0xfc,0x88,0x8c,0x8a,0x28,0x10,0x0,0x20,0x44,0xfe,0x40,0x20,0x1c,0x8,0x0,
-+0x2,0x1,0x3f,0x20,0x20,0x3f,0x20,0x20,0x3f,0x24,0x24,0x22,0x21,0x28,0x30,0x20,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf8,0x10,0x20,0x40,0x80,0x60,0x1c,0x8,
-+0x0,0xff,0x4,0x4,0x7f,0x44,0x44,0x44,0x44,0x44,0x4a,0x51,0x62,0x40,0x40,0x40,0x4,0xfe,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0x44,0xa4,0x1c,0xc,0x4,0x14,0x8,
-+0x10,0x13,0xfc,0x20,0x33,0x52,0x52,0xfe,0x12,0x12,0x1f,0xf2,0x52,0x12,0x12,0x12,0x4,0xfe,0x90,0x94,0xfe,0x94,0x94,0x94,0x94,0x94,0x54,0x2c,0x4,0x4,0x14,0x8,
-+0x0,0x1f,0x10,0x1f,0x10,0xff,0x0,0x1f,0x11,0x1f,0x11,0x1f,0x1,0x1f,0x1,0x7f,0x10,0xf8,0x10,0xf0,0x14,0xfe,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x0,0xf0,0x0,0xfc,
-+0x0,0x0,0x78,0x4f,0x48,0x4b,0x4a,0x7a,0x4a,0x4b,0x48,0x49,0x7a,0x44,0x9,0x0,0x80,0x40,0x44,0xfe,0x8,0xfc,0x8,0x8,0x8,0xf8,0x40,0x50,0x4c,0x44,0x40,0x80,
-+0x1,0x7f,0x0,0x1f,0x10,0x10,0x1f,0x0,0x7f,0x40,0x8f,0x8,0x8,0x8,0x10,0x60,0x8,0xfc,0x10,0xf8,0x10,0x10,0xf0,0x0,0xfe,0x22,0xf4,0x20,0x20,0x22,0x22,0x1e,
-+0x0,0x40,0x2f,0x20,0x3,0x2,0xe2,0x22,0x23,0x20,0x24,0x29,0x32,0x24,0x9,0x0,0x80,0x44,0xfe,0x8,0xfc,0x8,0x8,0x8,0xf8,0x40,0x40,0x50,0x4c,0x46,0x42,0x80,
-+0x10,0x10,0x1f,0x10,0xfd,0x12,0x17,0x1a,0x33,0xd2,0x13,0x10,0x11,0x12,0x55,0x20,0x40,0x44,0xfe,0xa0,0x14,0x8,0xfe,0x8,0xf8,0x8,0xf8,0x40,0x50,0x4c,0x44,0x80,
-+0x8,0xfd,0x4a,0x4a,0x4a,0x7a,0x4a,0x4a,0x4a,0x7a,0x4b,0x4a,0xfc,0x8,0x9,0xa,0x80,0x4,0x3e,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xb4,0xa8,0xa0,0x20,0x20,
-+0x10,0x10,0x1f,0x21,0x2a,0x64,0xaf,0x34,0x27,0x24,0x27,0x20,0x22,0x24,0x2a,0x21,0x80,0x88,0xfc,0x40,0x28,0x10,0xfe,0x14,0xf0,0x10,0xf0,0x80,0xa0,0x98,0x88,0x0,
-+0x1,0x0,0x1f,0x10,0x90,0x57,0x50,0x10,0x30,0x50,0xd0,0x10,0x20,0x22,0x41,0x0,0x0,0x84,0xfe,0x0,0x0,0xf8,0x10,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,
-+0x10,0x10,0x17,0x10,0x56,0x59,0x53,0x96,0x1b,0x12,0x13,0x28,0x25,0x42,0x84,0x0,0x40,0x44,0xfe,0x40,0xa8,0x10,0xf8,0xe,0xf8,0x8,0xf8,0x40,0x50,0x4c,0x44,0xc0,
-+0x1,0x7f,0x40,0xbc,0x24,0x14,0x25,0x6,0x8,0x33,0xcc,0x1,0xe,0x0,0x3,0x1c,0x0,0xfe,0x2,0xfc,0x48,0x28,0x48,0x88,0x40,0x30,0x4e,0x84,0x20,0xc0,0x0,0x0,
-+0x40,0x37,0x10,0x0,0x0,0x70,0x10,0x10,0x10,0x10,0x10,0x11,0x10,0x28,0x47,0x0,0x0,0xfc,0x8,0x10,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x6,0xfc,0x0,
-+0x0,0x40,0x2f,0x10,0x82,0x61,0x23,0xe,0x13,0x22,0xe3,0x20,0x21,0x22,0x25,0x20,0x40,0x44,0xfe,0x40,0xa8,0x10,0xf8,0xe,0xf8,0x8,0xf8,0x40,0x50,0x4c,0x44,0x80,
-+0x0,0x7f,0x0,0x0,0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x5,0x2,0x0,0xf8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x13,0x12,0x13,0xfe,0x13,0x14,0x19,0x33,0xd0,0x13,0x1f,0x12,0x12,0x53,0x22,0x8,0xfc,0x48,0xf8,0x48,0xf8,0x80,0xf8,0x10,0xe0,0x18,0xfe,0x8,0x8,0xf8,0x8,
-+0x20,0x20,0x3f,0x40,0x82,0x79,0x23,0x26,0xfb,0x22,0x23,0x20,0x29,0x32,0x25,0x0,0x40,0x44,0xfe,0x40,0xa8,0x10,0xf8,0xe,0xf8,0x8,0xf8,0x40,0x50,0x4c,0x44,0x80,
-+0x0,0x3f,0x20,0x3f,0x29,0x25,0x29,0x23,0x2c,0x31,0x26,0x21,0x46,0x40,0x83,0xc,0x88,0xfc,0x0,0x78,0x48,0x28,0xc8,0x60,0x5e,0x84,0x40,0x90,0x20,0xc0,0x0,0x0,
-+0x8,0x49,0x2a,0x2c,0x8,0xff,0x8,0x18,0x1c,0x2b,0x2a,0x48,0x88,0x8,0x8,0x8,0x8,0x8,0x48,0x28,0x8,0x48,0x28,0x28,0xe,0xf8,0x8,0x8,0x8,0x8,0x8,0x8,
-+0x1,0x7f,0x10,0x10,0x1f,0x21,0x21,0x52,0x8a,0x4,0x4,0x8,0x10,0x20,0x40,0x0,0x4,0x84,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x4,0x4,0x14,0x8,
-+0x1,0xff,0x10,0x1f,0x31,0x4a,0x4,0x39,0x1,0xff,0x2,0x4,0xc,0x15,0x66,0x4,0x4,0x84,0x24,0x24,0x24,0x24,0x24,0xc,0x4,0xfe,0x8,0x90,0x60,0x30,0xe,0x4,
-+0x1,0x7f,0x10,0x10,0x1f,0x21,0x21,0x52,0xc,0x8,0x30,0x40,0x28,0x24,0x44,0x80,0x4,0x84,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x4,0xc,0x0,0x90,0x4c,0x46,0x2,
-+0x1,0x9,0x9,0x11,0x21,0x41,0x6,0x19,0xe1,0x1f,0x1,0x2,0x2,0x4,0x8,0x30,0x0,0x20,0x18,0xc,0x34,0xc0,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x50,0x20,
-+0x0,0x44,0x2c,0x13,0x28,0x48,0x8f,0x8,0x19,0x29,0x49,0x89,0x9,0x9,0x51,0x21,0x90,0x90,0x90,0xfc,0x90,0x94,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x2,0x12,0xfa,0x22,0x2f,0x22,0xfa,0x27,0x26,0x2a,0x3a,0xe2,0x42,0x2,0x2,0x2,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x38,0xb8,0x54,0x54,0x92,0x10,0x10,0x10,0x10,
-+0x8,0x8,0x8,0x8,0xfe,0x8,0x18,0x1c,0x2a,0x28,0x49,0x8a,0x8,0x8,0x8,0x8,0x20,0x20,0x20,0x24,0xfe,0x20,0x60,0x70,0xa8,0xae,0x24,0x20,0x20,0x20,0x20,0x20,
-+0x8,0xfd,0x10,0x13,0x20,0x20,0x7d,0xa6,0x24,0x25,0x26,0x25,0x24,0x3d,0x22,0x0,0x20,0x24,0xa8,0xfe,0x70,0xa8,0x26,0xa4,0xa4,0xde,0x54,0x54,0xbe,0x4,0x4,0x4,
-+0x1f,0x1,0x7f,0x41,0x9d,0x1,0x1d,0x8,0x8,0x7e,0x8,0x1c,0x2a,0x49,0x8,0x8,0xf0,0x0,0xfe,0x2,0x74,0x0,0x70,0x20,0x28,0xfc,0x20,0x70,0xae,0x24,0x20,0x20,
-+0x10,0x10,0x51,0x51,0x52,0x54,0x58,0x50,0x57,0x54,0x54,0x54,0x54,0x14,0x17,0x14,0x80,0x80,0x4,0xfe,0x0,0x80,0x60,0x24,0xfe,0x44,0x44,0x44,0x44,0x44,0xfc,0x4,
-+0x8,0x8,0x14,0x12,0x21,0x50,0x88,0x0,0x7f,0x1,0x2,0x14,0x8,0x4,0x4,0x0,0x0,0x7c,0x44,0x44,0xc8,0xc8,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x20,0x21,0x3c,0x4b,0x90,0x7c,0x55,0x56,0x7c,0x55,0x56,0x7d,0x0,0x1d,0xe2,0x40,0x20,0x24,0xa8,0xfe,0x70,0xa8,0x26,0xa4,0x84,0xde,0x54,0x54,0xbe,0x4,0x4,0x4,
-+0x2,0x42,0x22,0x22,0x1f,0x82,0x42,0x47,0x16,0x2a,0xea,0x32,0x22,0x22,0x22,0x22,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x38,0xb8,0x54,0x54,0x92,0x10,0x10,0x10,0x10,
-+0x0,0x9f,0x60,0x2f,0xa,0xb,0x1a,0x1f,0x20,0xe7,0x20,0x3f,0x24,0x28,0x32,0x1,0x80,0xfc,0x8,0xfc,0x28,0xe8,0x28,0xf8,0x0,0xf0,0x0,0xfc,0x90,0x8c,0x84,0x0,
-+0x8,0x17,0x30,0x5f,0x90,0x17,0x0,0x1f,0x10,0x11,0x11,0x11,0x11,0x2,0xc,0x30,0x18,0xe0,0x44,0xfe,0x40,0xfc,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0xc0,0x30,0x8,
-+0x2,0x1,0x7f,0x4,0x2,0x1,0x6,0x18,0xe0,0x1f,0x10,0x10,0x10,0x10,0x1f,0x10,0x0,0x8,0xfc,0x40,0x80,0x0,0xc0,0x30,0xe,0xf4,0x10,0x10,0x10,0x10,0xf0,0x10,
-+0x10,0x10,0x10,0x10,0xfd,0x12,0x14,0x18,0x30,0xd3,0x10,0x10,0x10,0x10,0x50,0x20,0x40,0x40,0xa0,0xa0,0x10,0x88,0x4e,0x44,0x0,0xf8,0x8,0x10,0xa0,0x40,0x20,0x20,
-+0x0,0x10,0xf8,0x20,0x21,0x22,0xfc,0x28,0x20,0x23,0x20,0x38,0xc0,0x0,0x0,0x0,0x40,0x40,0xa0,0xa0,0x10,0x88,0x4e,0x44,0x0,0xf8,0x8,0x10,0xa0,0x40,0x20,0x20,
-+0x8,0xff,0x9,0x1,0x3f,0x1,0xff,0x8,0xa,0x13,0x24,0xc,0x12,0x1,0xe,0x70,0x24,0xfe,0x20,0x0,0xf8,0x0,0xfe,0x20,0x18,0xe8,0x20,0x20,0x40,0x80,0x70,0xe,
-+0x1f,0x1,0x7f,0x41,0x9d,0x1,0x1d,0x2,0xc,0x32,0xc1,0xf,0x0,0x2,0x1,0x0,0xf0,0x0,0xfe,0x2,0x74,0x0,0x70,0x80,0x60,0x18,0x6,0xe0,0x40,0x80,0x0,0x80,
-+0x8,0x28,0x28,0x2f,0x28,0x29,0xff,0x0,0x49,0x49,0x49,0x55,0x63,0x41,0x7f,0x41,0x20,0x20,0x50,0x50,0x88,0x4e,0x24,0x20,0x0,0xfc,0x4,0x8,0x50,0x20,0x10,0x10,
-+0x10,0x10,0x10,0x1c,0x21,0x22,0x7c,0x90,0x10,0x7d,0x10,0x10,0x14,0x18,0x10,0x0,0x40,0x40,0xa0,0xa0,0x10,0x88,0x4e,0x44,0x0,0xf8,0x8,0x10,0xa0,0x40,0x20,0x20,
-+0x8,0x8,0x8,0x10,0x11,0x32,0x54,0x98,0x10,0x13,0x10,0x10,0x10,0x10,0x10,0x10,0x40,0x40,0xa0,0xa0,0x10,0x88,0x4e,0x44,0x0,0xf8,0x8,0x10,0xa0,0x40,0x20,0x20,
-+0x0,0x44,0x28,0xfe,0x11,0x12,0x7c,0x10,0x10,0x13,0xfc,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0xa0,0xa0,0x10,0x8e,0x44,0x40,0x0,0xf8,0x8,0x10,0xa0,0x40,0x20,0x20,
-+0x0,0x40,0x37,0x10,0x0,0xf,0x9,0x12,0x24,0xe1,0x23,0x24,0x28,0x20,0x23,0xc,0x40,0x48,0xfc,0x40,0x44,0xfe,0x10,0x8c,0xf4,0x10,0x10,0xa0,0x40,0xa0,0x1e,0x4,
-+0x0,0x7f,0x0,0x3f,0x0,0x7f,0x1,0x1,0x21,0x19,0xa,0x2,0x4,0x8,0x30,0xc0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x0,0x8,0x18,0xa0,0x80,0x40,0x30,0xe,0x4,
-+0x0,0x7c,0x45,0x48,0x48,0x53,0x48,0x49,0x46,0x44,0x45,0x6a,0x50,0x40,0x41,0x46,0x20,0x28,0xfc,0x20,0x24,0xfe,0x88,0x44,0x7a,0x88,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x10,0x10,0x10,0x10,0x54,0x55,0x56,0x54,0x54,0x55,0x54,0x5c,0x74,0x44,0x0,0x0,0x20,0x20,0x50,0x50,0x88,0x4e,0x24,0x20,0x0,0xfc,0x4,0x8,0x50,0x20,0x10,0x10,
-+0x10,0x13,0x28,0x24,0x43,0xa1,0x11,0x1,0xff,0x3,0x5,0x29,0x10,0x8,0x8,0x3,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x50,0x48,0x86,0x2,
-+0x0,0x1f,0x10,0x10,0x10,0x1f,0x12,0x2,0x7f,0x2,0x2,0x4,0x4,0x8,0x10,0x60,0x10,0xf8,0x10,0x10,0x10,0xf0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x88,0x50,0x20,
-+0x1,0x1,0x2,0x4,0xa,0x11,0x21,0xc0,0x1f,0x0,0x0,0x4,0x2,0x1,0x0,0x0,0x0,0x0,0x80,0x40,0x20,0x10,0xe,0x4,0xf0,0x10,0x20,0x40,0x80,0x0,0x80,0x80,
-+0x0,0x47,0x34,0x15,0x84,0x65,0x26,0x8,0x17,0x24,0xe4,0x27,0x24,0x24,0x27,0x24,0x84,0x7e,0x24,0x24,0xa4,0x24,0x54,0x88,0xfc,0x44,0x44,0xfc,0x44,0x44,0xfc,0x4,
-+0x0,0x8,0xff,0x10,0x10,0x11,0x7f,0x10,0x11,0x11,0x1d,0xf1,0x41,0x1,0x2,0x4,0x80,0x48,0xfc,0x40,0x90,0x8,0xfc,0x4,0x50,0x50,0x50,0x50,0x52,0x52,0x4e,0x40,
-+0x20,0x27,0x24,0x25,0xfc,0x25,0x66,0x70,0xaf,0x24,0x24,0x27,0x24,0x24,0x27,0x24,0x84,0x7e,0x24,0x24,0xa4,0x24,0x54,0x88,0xfc,0x44,0x44,0xfc,0x44,0x44,0xfc,0x4,
-+0x0,0x8,0xff,0x10,0x10,0x21,0x23,0x3c,0x65,0xa5,0x25,0x25,0x25,0x3d,0x22,0x4,0x80,0x48,0xfc,0x40,0x90,0x8,0xfc,0x4,0x50,0x50,0x50,0x50,0x52,0x52,0x4e,0x40,
-+0x20,0x27,0x24,0x3d,0x4c,0x55,0x86,0x20,0x27,0x24,0x24,0x27,0x2c,0x34,0x27,0x4,0x84,0x7e,0x24,0x24,0xa4,0x24,0x54,0x88,0xfc,0x44,0x44,0xfc,0x44,0x44,0xfc,0x4,
-+0x2,0x7c,0x40,0x48,0x46,0x4a,0xf0,0x1,0x3f,0x21,0x21,0x3f,0x21,0x21,0x3f,0x20,0x4,0xfe,0x44,0x44,0x44,0x44,0x94,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x20,0x18,0x9,0xff,0x2,0x42,0x22,0x14,0x14,0x8,0x8,0x14,0x22,0x43,0x81,0x0,0x4,0x4,0x24,0xa4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x4,0x4,0x14,0x8,
-+0x0,0x1f,0x10,0x97,0x54,0x55,0x15,0x16,0x30,0x57,0xd4,0x14,0x27,0x24,0x44,0x7,0x84,0xfe,0x80,0x7c,0x24,0x24,0xa4,0x4c,0x80,0xfc,0x44,0x44,0xfc,0x44,0x44,0xfc,
-+0x0,0x40,0x37,0x10,0x80,0x61,0x27,0x8,0x11,0x21,0xe1,0x21,0x21,0x21,0x22,0x24,0x80,0x48,0xfc,0x40,0x90,0x8,0xfc,0x4,0x50,0x50,0x50,0x50,0x52,0x52,0x4e,0x40,
-+0x20,0x27,0x24,0x24,0xfc,0x24,0x64,0x74,0xac,0x25,0x26,0x24,0x20,0x21,0x22,0x24,0x84,0x3e,0x24,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xb4,0xa8,0x20,0x20,0x20,
-+0x0,0x4,0x2,0x3,0x1,0xff,0x0,0x0,0x4,0xc,0x8,0x10,0x10,0x20,0x40,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x40,0x20,0x10,0x18,0xc,0xc,0x4,0x0,
-+0x2,0x2,0x2,0x2,0xff,0x2,0x2,0x4,0x4,0x4,0x8,0x8,0x11,0x16,0x20,0x40,0x0,0x40,0x20,0x4,0xfe,0x80,0x88,0x88,0x90,0xa0,0xc0,0x82,0x82,0x82,0x7e,0x0,
-+0x2,0x2,0xff,0x2,0x4,0x18,0x23,0x7f,0x8,0xf,0x8,0xf,0x8,0xff,0x0,0x0,0x40,0x24,0xfe,0xa0,0xc4,0xfc,0x0,0xfc,0x20,0xe0,0x20,0xe0,0x24,0xfe,0x20,0x20,
-+0x0,0x8,0x7c,0x48,0x4f,0x48,0x48,0x48,0x49,0x49,0x49,0x7a,0x42,0x4,0xb,0x10,0x80,0xa0,0x90,0x84,0xfe,0xa0,0xa4,0xa4,0x28,0x28,0x30,0x20,0x62,0xa2,0x1e,0x0,
-+0x10,0x1f,0x28,0x45,0x2,0x2,0xff,0x2,0x2,0x4,0x4,0x8,0x8,0x11,0x26,0x40,0x40,0x7c,0xa0,0x10,0x40,0x24,0xfe,0x80,0x90,0x90,0xa0,0xc2,0x82,0x82,0x7e,0x0,
-+0x1,0x7f,0x48,0x91,0x79,0x4a,0x54,0x61,0x56,0x49,0x4a,0x6b,0x54,0x43,0x40,0x4f,0x0,0xfe,0x22,0x14,0xf0,0xa0,0x40,0xb0,0xe,0xf4,0x40,0xf8,0x40,0xf8,0x40,0xfc,
-+0x0,0x7c,0x45,0x4a,0x48,0x50,0x4b,0x48,0x44,0x45,0x45,0x6a,0x51,0x40,0x47,0x40,0x80,0xfc,0x88,0x50,0x20,0xd8,0x6,0xf8,0x20,0x28,0xfc,0x20,0xfc,0x20,0xfe,0x0,
-+0x2,0x2,0xff,0x5,0x5,0x9,0x11,0x27,0xc0,0x1,0x1,0x7f,0x1,0x1,0xff,0x0,0x80,0x44,0xfe,0x0,0x10,0x20,0xc4,0x4,0xfc,0x0,0x8,0xfc,0x0,0x4,0xfe,0x0,
-+0x10,0x10,0x10,0x10,0xfc,0x13,0x14,0x18,0x31,0xd1,0x11,0x12,0x12,0x14,0x54,0x28,0x80,0xa0,0x90,0x90,0x84,0xfe,0xa0,0xa0,0x24,0x24,0x28,0x32,0x22,0x62,0x9e,0x0,
-+0x0,0x7c,0x44,0x48,0x48,0x57,0x48,0x48,0x45,0x45,0x65,0x5a,0x42,0x44,0x44,0x48,0x80,0xa0,0x90,0x90,0x84,0xfe,0xa0,0xa0,0x24,0x24,0x28,0x32,0x22,0x62,0x9e,0x0,
-+0x10,0x12,0x11,0x10,0xff,0x11,0x3a,0x34,0x50,0x5f,0x91,0x12,0x11,0x10,0x11,0x16,0x40,0x48,0x50,0x44,0xfe,0x50,0x4c,0x44,0x80,0xfe,0x8,0x8,0xb0,0x40,0xb0,0x8,
-+0x11,0xd,0x5,0x7f,0x5,0xd,0x11,0x21,0x2,0xff,0x4,0x8,0x6,0x1,0x6,0x38,0x10,0x30,0x40,0xfc,0x40,0x20,0x1c,0x8,0x0,0xfe,0x20,0x20,0x40,0x80,0x60,0x10,
-+0x10,0x12,0x11,0x10,0xff,0x11,0x12,0x1c,0x30,0xd7,0x11,0x12,0x11,0x10,0x51,0x26,0x40,0x48,0x50,0x44,0xfe,0x50,0x4c,0x44,0x80,0xfe,0x8,0x8,0xb0,0x40,0xb0,0x8,
-+0x10,0x1f,0x28,0x45,0x9,0x5,0x7f,0x5,0x9,0x11,0xff,0x4,0xc,0x3,0x4,0x38,0x40,0x7c,0xa0,0x10,0x20,0x48,0xfc,0x40,0x20,0x14,0xfe,0x20,0x40,0x80,0x60,0x10,
-+0x40,0x2f,0x28,0x8,0x8f,0x68,0x2f,0x8,0x2f,0x4c,0xd5,0x54,0x55,0x64,0x44,0x44,0x4,0xfe,0x4,0x4,0xfc,0x0,0xfe,0x4,0xfe,0x44,0x54,0x44,0x54,0x44,0x54,0x48,
-+0x0,0x7b,0x48,0x50,0x52,0x62,0x52,0x4a,0x4a,0x4a,0x6a,0x52,0x42,0x42,0x43,0x40,0x4,0xfe,0x20,0x24,0xfe,0xa4,0xa4,0xa4,0xd4,0xcc,0x84,0x94,0x88,0x0,0xfe,0x0,
-+0x8,0x8,0xff,0x8,0x1,0x3f,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x40,0x40,0x80,0x20,0x24,0xfe,0x20,0x8,0xfc,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x3f,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x40,0x80,0x0,0x4,0xfe,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x15,0x1e,0x10,0x12,0x7f,0x42,0x42,0x42,0x7e,0x42,0x40,0x40,0x40,0x80,0x3,0x4,0xfe,0x20,0x44,0xfe,0x84,0x94,0x94,0x94,0xa4,0xa4,0xa4,0x50,0x48,0x86,0x2,
-+0x1,0x0,0x3f,0x21,0x20,0x27,0x24,0x24,0x24,0x27,0x24,0x24,0x44,0x44,0x88,0x10,0x0,0x84,0xfe,0x0,0x88,0xfc,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x10,0x12,0x15,0x59,0x51,0x51,0x91,0x11,0x11,0x11,0x11,0x29,0x45,0x82,0x4,0x40,0x20,0x24,0xfe,0x4,0x4,0x4,0xfc,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x10,0x10,0x13,0xfe,0x12,0x17,0x1a,0x32,0xd2,0x13,0x12,0x12,0x14,0x54,0x29,0x48,0x7c,0x40,0xfe,0x44,0x70,0xc4,0x7c,0x0,0x44,0xfe,0x44,0x44,0x84,0x94,0x8,
-+0x1,0x1,0x1,0x1,0x3f,0x20,0x28,0x24,0x22,0x21,0x21,0x22,0x24,0x28,0x3f,0x20,0x4,0xfe,0x0,0x8,0xfc,0x8,0x28,0x68,0x88,0x8,0x88,0x48,0x28,0x18,0xf8,0x8,
-+0x1,0x1,0x1,0x3f,0x21,0x21,0x2f,0x21,0x20,0x21,0x2f,0x21,0x41,0x41,0x82,0x1c,0x10,0xf8,0x0,0xfe,0x2,0xf4,0x0,0x8,0xf8,0x0,0xf8,0x8,0x8,0x8,0x28,0x10,
-+0x4,0xf,0x10,0x3f,0xe1,0x3f,0x21,0x3f,0x0,0xff,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x0,0xe0,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,
-+0x8,0x8,0xff,0x1c,0x2a,0x49,0x3f,0x22,0x3f,0x22,0x3f,0x28,0x2f,0x28,0x4f,0x88,0x20,0x24,0xfe,0x70,0xae,0x24,0xfc,0x40,0xf8,0x48,0xf8,0x48,0x50,0x62,0x42,0x3e,
-+0x8,0xff,0x10,0x11,0x20,0x23,0x3c,0x64,0xa5,0x24,0x24,0x24,0x25,0x3e,0x20,0x0,0x8,0xfc,0x8,0xf8,0x8,0xfe,0x20,0x24,0x2c,0xb0,0x20,0xb0,0x2e,0x24,0xa0,0x40,
-+0x3f,0x1,0x7f,0x49,0x85,0x9,0x3e,0x22,0x22,0x3f,0x8,0x2e,0x29,0x2e,0x70,0x20,0xf8,0x0,0xfe,0x22,0x44,0x20,0x40,0x78,0x88,0x50,0x20,0x50,0xfe,0x88,0x88,0xf8,
-+0x4,0x7e,0x44,0x45,0x46,0x44,0x7c,0x50,0x13,0x5d,0x51,0x51,0x51,0x5d,0xe1,0x1,0x40,0x40,0xfc,0x88,0x50,0x20,0x50,0x8e,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x4,0x7e,0x44,0x55,0x56,0x54,0x54,0x54,0x57,0x55,0x55,0x55,0x29,0x25,0x45,0x81,0x40,0x40,0xfc,0x88,0x50,0x20,0x50,0x8e,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x1,0x0,0x3f,0x22,0x22,0x3f,0x22,0x22,0x3f,0x28,0x28,0x2f,0x48,0x49,0x8a,0xc,0x0,0x84,0xfe,0x40,0x48,0xfc,0x48,0x48,0xf8,0x40,0x48,0x58,0x60,0x42,0x42,0x3e,
-+0x40,0x2f,0x28,0x8,0x88,0x4f,0x4a,0x2,0x1a,0x2b,0xca,0x4a,0x4a,0x4b,0x5c,0x8,0x20,0xa0,0xbc,0xc4,0xc4,0xa8,0x90,0x28,0x46,0x84,0x7c,0x44,0x44,0xc4,0x7c,0x44,
-+0x20,0x13,0x10,0x1,0xf8,0xb,0x10,0x38,0x56,0x91,0x10,0x11,0x12,0x14,0x11,0x10,0x8,0xfc,0x8,0xf8,0x8,0xfe,0x40,0x44,0x68,0x70,0xd0,0x48,0x4e,0x44,0x40,0x80,
-+0x0,0x3f,0x0,0x0,0x1f,0x0,0x0,0xff,0x1,0x11,0x9,0x5,0x9,0x11,0x65,0x2,0x10,0xf8,0x10,0x10,0xf0,0x10,0x14,0xfe,0x8,0x10,0xa0,0x40,0x20,0x1e,0x4,0x0,
-+0x0,0x7c,0x44,0x49,0x48,0x50,0x48,0x4b,0x44,0x45,0x45,0x69,0x51,0x41,0x41,0x41,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x24,0x24,0x24,0x24,0x24,0xfc,0x4,
-+0x1,0xf7,0x11,0x55,0x33,0x55,0x9,0x14,0x2b,0xd1,0x24,0x48,0x12,0x24,0x9,0x10,0x20,0xa8,0x24,0x20,0x3e,0xe0,0x20,0x24,0x24,0x28,0x10,0x30,0x52,0x8a,0xa,0x4,
-+0x8,0xfc,0x9,0x49,0x49,0x49,0x49,0x49,0x7d,0x5,0x5,0x1d,0xe5,0x5,0x2a,0x14,0x40,0x24,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x0,0x0,0x3f,0x20,0x20,0x20,0x20,0x3f,0x20,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x11,0x1d,0x21,0x21,0x7d,0x91,0x10,0x7c,0x13,0x12,0x12,0x16,0x1a,0x13,0x2,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x8,0xb,0xa,0x12,0x12,0x33,0x50,0x90,0x17,0x14,0x14,0x14,0x14,0x14,0x17,0x14,0x8,0xfc,0x8,0x8,0x8,0xf8,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x20,0x10,0x10,0xfd,0x22,0x20,0x3d,0x25,0x25,0x25,0x25,0x25,0x25,0x45,0x95,0x9,0x80,0x80,0x88,0xfc,0x10,0x60,0x84,0x4c,0x50,0x20,0x20,0x10,0x10,0x4e,0x84,0x0,
-+0x3f,0x20,0x3f,0x25,0x29,0x32,0x25,0x29,0x39,0x29,0x29,0x29,0x4b,0x4c,0x88,0xb,0xfc,0x4,0xfc,0x0,0xfc,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xf8,0x90,0x60,0x9c,
-+0x3f,0x20,0x3f,0x24,0x22,0x3f,0x22,0x24,0x28,0x21,0x3f,0x22,0x46,0x41,0x82,0xc,0xfc,0x4,0xfc,0x90,0xa4,0xfe,0xa0,0x98,0x88,0x0,0xfe,0x10,0x20,0xc0,0x30,0x8,
-+0x10,0x12,0x21,0x20,0x47,0xf9,0x12,0x24,0x40,0xff,0x1,0x2,0x19,0xe0,0x41,0x6,0x40,0x48,0x50,0x40,0xfe,0x50,0x4c,0x44,0x80,0xfe,0x8,0x8,0xb0,0x40,0xb0,0x8,
-+0x1,0x1,0x1,0x3f,0x21,0x21,0x2f,0x21,0x20,0x20,0x20,0x2a,0x4a,0x52,0x81,0x0,0x10,0xf8,0x0,0xfe,0x2,0xf4,0x0,0x8,0xf8,0x0,0x80,0x48,0x46,0x12,0xf0,0x0,
-+0x10,0x1f,0x10,0x2f,0x40,0xbf,0x0,0x3f,0x0,0x1f,0x0,0xff,0x12,0xa,0x32,0x6,0x8,0xfc,0x0,0xf8,0x0,0xf8,0x48,0xe8,0x48,0xc8,0x48,0xf8,0x48,0x8a,0x6a,0x4,
-+0x8,0x8,0x13,0x10,0x27,0x48,0x8b,0x10,0x30,0x57,0x90,0x10,0x1f,0x10,0x10,0x10,0x40,0x48,0xfc,0x48,0xfe,0x48,0xf8,0x40,0x48,0xfc,0x40,0x44,0xfe,0x40,0x40,0x40,
-+0x2,0x1,0x7f,0x1,0x42,0x27,0x11,0x22,0x4f,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x0,0x8,0xfc,0x0,0x44,0x88,0x10,0x48,0xe4,0x20,0x4,0xfe,0x0,0x0,0x0,0x0,
-+0x0,0x40,0x20,0x2f,0x8,0x88,0x5f,0x48,0x18,0x28,0xc9,0x4b,0x4d,0x51,0x50,0x60,0x90,0xf8,0x80,0xfe,0x82,0xf4,0x80,0x88,0x78,0x0,0x40,0x24,0x2a,0xa,0xf8,0x0,
-+0x10,0x13,0x20,0x21,0x44,0xff,0x10,0x22,0x41,0xf9,0x0,0x1,0x1a,0xe4,0x41,0x0,0x8,0xfc,0x8,0xf8,0x8,0xfe,0x40,0x44,0x4c,0x50,0xe0,0x50,0x48,0x4e,0x44,0x80,
-+0x2,0x1,0xff,0x4,0x14,0x14,0x24,0x24,0x44,0x1,0x21,0x21,0x21,0x21,0x3f,0x20,0x0,0x4,0xfe,0x40,0x50,0x48,0x44,0x44,0x40,0x0,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x2,0x1,0xff,0x4,0x14,0x34,0x44,0x3f,0x1,0x1f,0x1,0xff,0x1,0x1,0x5,0x2,0x0,0x4,0xfe,0x40,0x50,0x4c,0x74,0x80,0x0,0xf0,0x4,0xfe,0x0,0x0,0x0,0x0,
-+0x2,0x1,0xff,0x4,0x14,0x24,0x44,0x1f,0x0,0x1,0xff,0x1,0x1,0x1,0x5,0x2,0x0,0x4,0xfe,0x40,0x50,0x4c,0x44,0xe0,0x80,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x40,0x3f,0x22,0x6,0x8a,0x52,0x42,0x10,0x2f,0xc1,0x42,0x44,0x48,0x50,0x40,0x0,0x84,0xfe,0x20,0x30,0x2c,0x24,0xa0,0x84,0xfe,0xc0,0xa0,0x90,0x8e,0x84,0x80,
-+0xc,0x70,0x44,0x44,0x64,0x54,0x54,0x44,0x44,0x5c,0xe4,0x4,0x8,0x10,0x60,0x0,0x4,0xfe,0x84,0x84,0xa4,0x94,0x94,0x84,0x84,0xc4,0xa8,0x90,0x80,0x80,0x80,0x80,
-+0x2,0x7,0x78,0x8,0x8,0x9,0xff,0x8,0xa,0x3f,0x22,0x22,0x22,0x22,0x3e,0x22,0x40,0x40,0x40,0x40,0x40,0x40,0xc0,0x40,0x40,0x40,0x40,0x42,0x42,0x42,0x3e,0x0,
-+0x10,0x10,0x17,0x10,0xfc,0x13,0x16,0x1a,0x32,0xd3,0x10,0x11,0x12,0x14,0x51,0x20,0x80,0x44,0xfe,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x40,0x50,0x4c,0x44,0x40,0x80,
-+0x0,0x4,0x7e,0x55,0x56,0x54,0x7c,0x54,0x55,0x57,0x55,0x7d,0x41,0x1,0x1,0x1,0x80,0x80,0xfc,0x88,0x50,0x20,0x50,0x8e,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x10,0xfd,0x11,0x12,0x1d,0x31,0xd1,0x11,0x11,0x11,0x11,0x50,0x20,0x40,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,0x10,0x30,0xc0,0x0,0x4,0x4,0xfc,0x0,
-+0x10,0x10,0x20,0xfc,0x21,0x51,0x52,0xfd,0x11,0x11,0x1d,0xf1,0x51,0x11,0x10,0x10,0x40,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,0x10,0x30,0xc0,0x0,0x4,0x4,0xfc,0x0,
-+0x8,0x8,0x8,0x10,0x11,0x32,0x54,0x99,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x10,0x40,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,0x10,0x30,0xc0,0x0,0x4,0x4,0xfc,0x0,
-+0x1,0x1,0x2,0x2,0x4,0x8,0x30,0xc8,0x8,0x9,0xe,0x8,0x8,0x8,0x7,0x0,0x0,0x0,0x80,0x80,0x40,0x30,0x1e,0x24,0x60,0x80,0x0,0x0,0x8,0x8,0xf8,0x0,
-+0x0,0x40,0x30,0x10,0x1,0x82,0x64,0x29,0x11,0x11,0xe1,0x21,0x21,0x21,0x20,0x20,0x40,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,0x10,0x30,0xc0,0x0,0x4,0x4,0xfc,0x0,
-+0x10,0x10,0x10,0x20,0x25,0x7e,0x4,0x9,0x11,0x7d,0x1,0x1,0xd,0x71,0x20,0x0,0x40,0x40,0xa0,0xa0,0x10,0xe,0x4,0x0,0x10,0x30,0xc0,0x0,0x4,0x4,0xfc,0x0,
-+0x0,0x40,0x30,0x10,0x1,0x2,0xf4,0x11,0x11,0x11,0x11,0x11,0x15,0x19,0x10,0x0,0x40,0x40,0xa0,0xa0,0x10,0xe,0x4,0x0,0x10,0x30,0xc0,0x0,0x4,0x4,0xfc,0x0,
-+0x4,0x4,0xff,0x4,0x3f,0x24,0x24,0x3f,0x2,0x7,0x18,0x64,0x2,0x1,0x6,0x78,0x40,0x44,0xfe,0x48,0xfc,0x48,0x48,0xf8,0x0,0xf8,0x8,0x10,0x60,0x80,0x0,0x0,
-+0x10,0x11,0x11,0x15,0x7f,0x55,0x54,0x54,0x55,0x7c,0x51,0x14,0x1c,0xe5,0x42,0x0,0x4,0xfe,0x24,0xfc,0x24,0xfc,0x20,0x48,0xf0,0x24,0xfc,0x20,0xa8,0x26,0xa2,0x40,
-+0x0,0x7f,0x44,0x44,0x44,0x7f,0x42,0x2,0x7,0x8,0x14,0x62,0x1,0x6,0x18,0xe0,0x4,0xfe,0x44,0x44,0x44,0xfc,0x4,0x0,0xf0,0x10,0x20,0xc0,0x0,0x0,0x0,0x0,
-+0x0,0x4f,0x29,0x29,0xf,0x8,0xe1,0x23,0x26,0x29,0x20,0x20,0x27,0x50,0x8f,0x0,0x4,0xfe,0x24,0x24,0xfc,0x84,0x0,0xf8,0x8,0x10,0xa0,0xc0,0x0,0x6,0xfc,0x0,
-+0x10,0x13,0x22,0x3e,0x42,0x83,0x7e,0x10,0x10,0x7d,0x13,0x10,0x14,0x18,0x11,0x6,0x4,0xfe,0x94,0x94,0x94,0xfc,0x44,0x80,0xfc,0x4,0x8,0x90,0x60,0x40,0x80,0x0,
-+0x22,0x3f,0x50,0x89,0x7f,0x44,0x44,0x7f,0x44,0xf,0x10,0x28,0x4,0x3,0xe,0x70,0x44,0x7e,0xa0,0x14,0xfe,0x44,0x44,0xfc,0x4,0xf0,0x10,0x20,0x40,0x80,0x0,0x0,
-+0x8,0xfd,0x9,0x49,0x49,0x49,0x48,0x48,0x7d,0x4,0x5,0x1c,0xe4,0x45,0x16,0x8,0x4,0xfe,0x24,0xfc,0x24,0xfc,0x20,0x48,0xf0,0x24,0xfc,0x20,0xa8,0x26,0xa2,0x40,
-+0x40,0x33,0x12,0x2,0xfb,0xa,0x12,0x33,0x58,0x97,0x18,0x11,0x12,0x1c,0x10,0x10,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x40,0xfe,0xe0,0x50,0x4e,0x44,0x40,0x40,
-+0x8,0x8,0xff,0x9,0x41,0x23,0x24,0x80,0x49,0x12,0x2f,0xe2,0x22,0x22,0x23,0x22,0x20,0x24,0xfe,0x20,0xf8,0x10,0xa0,0x40,0xb0,0xe,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x1,0x41,0x31,0x13,0x84,0x60,0x20,0x9,0x12,0x27,0xea,0x22,0x22,0x22,0x23,0x22,0x0,0x0,0xf8,0x10,0xa0,0x40,0xa0,0x10,0xe,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x8,0xfc,0x8,0x49,0x4a,0x48,0x48,0x48,0x7d,0x7,0x5,0x1d,0xe5,0x45,0x15,0x9,0x80,0x80,0xfc,0x4,0x88,0x50,0x20,0x50,0x8e,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x20,0x21,0x4a,0xf8,0x10,0x20,0x41,0xfb,0x5,0x1,0x19,0xe1,0x41,0x1,0x80,0x80,0xfc,0x4,0x88,0x50,0x20,0x50,0x8e,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x13,0x10,0x11,0xfd,0x25,0x25,0x25,0x25,0x44,0x28,0x13,0x28,0x44,0x84,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x4,0x24,0xf4,0x4,0x4,0x28,0x10,
-+0x2,0x1,0x7f,0x44,0x44,0x44,0x7f,0x44,0x4e,0x4d,0x54,0x54,0x65,0x44,0x84,0x4,0x0,0x8,0xfc,0x20,0x20,0x24,0xfe,0x20,0x70,0x68,0xae,0xa4,0x20,0x20,0x20,0x20,
-+0x0,0xb,0xfc,0x11,0x11,0x11,0x7d,0x11,0x11,0x10,0x1c,0xf3,0x40,0x0,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x4,0x24,0xf4,0x4,0x4,0x14,0x8,
-+0x8,0xff,0x10,0x11,0x21,0x25,0x3f,0x65,0xa5,0x24,0x24,0x27,0x24,0x3c,0x24,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x4,0x24,0xf4,0x4,0x4,0x14,0x8,
-+0x10,0x13,0x10,0x7d,0x55,0x55,0x55,0x55,0x55,0x7c,0x10,0x17,0x1c,0xe4,0x40,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0xfc,0x4,0x24,0xf4,0x4,0x4,0x14,0x8,
-+0x0,0x3f,0x0,0x8,0x8,0x8,0x8,0x8,0xf,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x20,0xf0,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x4,0x24,0xf4,0x4,0x4,0x28,0x10,
-+0x7e,0x42,0x42,0x7e,0x0,0x3f,0x0,0x8,0x8,0x8,0xf,0x0,0x0,0xff,0x0,0x0,0xfc,0x84,0x84,0xfc,0x20,0xf0,0x20,0x20,0x20,0x24,0xfe,0x4,0x24,0xf4,0x14,0x8,
-+0x0,0x20,0xff,0xa9,0xa9,0xa9,0xaf,0xa9,0xab,0xab,0xad,0xe9,0x89,0x11,0x21,0x1,0x80,0x44,0xfe,0x10,0x10,0x14,0xfe,0x10,0x30,0xb8,0x56,0x54,0x90,0x10,0x10,0x10,
-+0x0,0xb,0x7c,0x49,0x49,0x49,0x49,0x49,0x49,0x48,0x48,0x7f,0x48,0x0,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x4,0x24,0xf4,0x4,0x4,0x14,0x8,
-+0x20,0x27,0x24,0x24,0xff,0x24,0x24,0x24,0x27,0x20,0x38,0xe7,0x40,0x0,0x1f,0x0,0x4,0xfe,0x44,0x44,0xfc,0x44,0x44,0x44,0xfc,0x40,0x48,0xfc,0x40,0x44,0xfe,0x0,
-+0x0,0x7f,0x0,0x8,0x6,0x2,0x20,0x19,0x9,0xff,0x2,0x2,0x4,0x8,0x30,0xc0,0x0,0xfc,0x84,0x88,0x80,0x80,0x80,0x0,0x4,0xfe,0x0,0xc0,0x30,0x18,0xc,0x4,
-+0x1,0x1,0x7f,0x1,0x3f,0x1,0x1,0xff,0x4,0xf,0xa,0x11,0x20,0x43,0xc,0x30,0x0,0x8,0xfc,0x0,0xf8,0x0,0x4,0xfe,0x0,0xf0,0x20,0x40,0x80,0x40,0x30,0xe,
-+0x1,0x1,0x3f,0x1,0x1,0x7f,0x8,0x6,0x22,0x18,0x8,0xff,0x1,0x2,0xc,0x30,0x0,0x10,0xf8,0x0,0x0,0xfc,0x4,0x88,0x80,0x80,0x84,0xfe,0x40,0x30,0x18,0x8,
-+0x0,0x47,0x31,0x11,0x1,0x1,0xf1,0x11,0x11,0x11,0x12,0x14,0x10,0x28,0x47,0x0,0x4,0xfe,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0x8,0x50,0x20,0x6,0xfc,0x0,
-+0x8,0x7c,0x48,0x4b,0x48,0x78,0x4f,0x48,0x49,0x79,0x4a,0x4a,0x4c,0x48,0x49,0x98,0x80,0x40,0x0,0xc4,0x4c,0x50,0xe0,0xe0,0x50,0x50,0x48,0x4e,0x44,0x40,0x40,0x80,
-+0x1,0x79,0x4f,0x49,0x48,0x7f,0x48,0x48,0x4b,0x7a,0x4a,0x4b,0x4a,0x7a,0x4a,0x2,0x10,0x14,0xfe,0x10,0x4,0xfe,0x90,0x94,0xfe,0x94,0x94,0x6c,0x4,0x4,0x14,0x8,
-+0x23,0x22,0x23,0x3a,0x2b,0x48,0x57,0x84,0x27,0x20,0x23,0x21,0x28,0x30,0x21,0x6,0xfc,0x4,0xfc,0x4,0xfc,0x0,0xfe,0x92,0xfe,0x0,0xfc,0x8,0x90,0x60,0x9e,0x4,
-+0x2,0x1,0xff,0x4,0x14,0x24,0x45,0x1,0x1f,0x11,0x11,0x1f,0x1,0x1,0x7f,0x0,0x0,0x4,0xfe,0x40,0x50,0x4c,0x44,0x10,0xf8,0x10,0x10,0xf0,0x0,0x8,0xfc,0x8,
-+0x41,0x31,0x1f,0x1,0x80,0x6f,0x21,0x1,0x1f,0x29,0xe9,0x2a,0x2c,0x28,0x28,0x28,0x20,0x24,0xfe,0x20,0x8,0xfc,0x20,0x24,0xfe,0x24,0x24,0xd4,0xc,0x4,0x14,0x8,
-+0x8,0xff,0x8,0x1f,0x11,0x1f,0x0,0x7f,0x44,0x7f,0x40,0x1f,0x4,0x3,0xc,0x70,0x24,0xfe,0x20,0xf0,0x10,0xf0,0x4,0xfe,0x44,0xfc,0x4,0xf0,0x40,0x80,0x60,0x1c,
-+0x1f,0x10,0x1f,0x10,0x1f,0x0,0x7f,0x44,0x44,0x7f,0x40,0x1f,0x4,0x3,0xc,0x70,0xf0,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x44,0x44,0xfc,0x4,0xf0,0x40,0x80,0x60,0x1c,
-+0x13,0x12,0x13,0x5a,0x57,0x50,0x97,0x14,0x14,0x17,0x10,0x13,0x11,0x10,0x11,0x16,0xf8,0x8,0xf8,0x8,0xf8,0x4,0xfe,0xa4,0xa4,0xfc,0x0,0xf8,0x10,0xe0,0x18,0x6,
-+0x47,0x34,0x17,0x4,0x87,0x60,0x2f,0x9,0x19,0x2f,0xe0,0x27,0x22,0x21,0x26,0x38,0xf8,0x8,0xf8,0x8,0xf8,0x4,0xfe,0x24,0x24,0xfc,0x0,0xf0,0x20,0xc0,0x30,0xe,
-+0x47,0x24,0x27,0x4,0x7,0xe0,0x2f,0x29,0x2f,0x28,0x23,0x22,0x29,0x30,0x23,0xc,0xf8,0x8,0xf8,0x8,0xf8,0x4,0xfe,0x24,0xfc,0x4,0xf0,0x10,0x20,0xc0,0x30,0xe,
-+0x8,0x8,0xff,0x8,0x8,0x2,0x1,0xff,0x10,0x10,0x10,0x10,0x10,0x10,0x1f,0x0,0x20,0x24,0xfe,0x20,0x20,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x10,0xf8,0x0,
-+0x8,0x8,0xff,0x8,0x20,0x10,0x90,0x47,0x41,0x9,0x11,0xe1,0x21,0x21,0x21,0x20,0x20,0x24,0xfe,0x20,0x0,0x80,0x44,0xfe,0x0,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,
-+0x2,0x1,0xff,0x10,0x10,0x10,0x1f,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x0,0x4,0xfe,0x0,0x0,0x10,0xf8,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x10,
-+0x20,0x13,0x12,0x2,0xfe,0x43,0x42,0x42,0x43,0x42,0x42,0x4a,0x7e,0x2,0x3,0x2,0x8,0xfc,0x8,0x8,0x8,0xf8,0x40,0x44,0xfe,0x40,0x20,0x20,0x10,0x92,0xa,0x6,
-+0x10,0x10,0x10,0x10,0x5f,0x5a,0x52,0x92,0x12,0x12,0x12,0x12,0x12,0x13,0x10,0x10,0x80,0x60,0x20,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x5,0x2,0xff,0x4,0x8,0x34,0xc4,0x3f,0x4,0x4,0x8,0x30,0x40,0x44,0xfe,0x40,0x50,0x8,0xfe,0x40,0x30,0x4e,0x44,0xf8,0x40,0x40,0x40,0x40,
-+0x1,0x89,0x51,0x2f,0x51,0x91,0x17,0x14,0x34,0x54,0x97,0x14,0x14,0x14,0x57,0x24,0x10,0x10,0x14,0xfe,0x10,0x14,0xfe,0x44,0x44,0x44,0xfc,0x44,0x44,0x44,0xfc,0x4,
-+0x4,0x4,0xff,0x4,0x1f,0x0,0x1,0x0,0xff,0x1,0x2,0x4,0x8,0x10,0x22,0x1,0x40,0x44,0xfe,0x40,0xf0,0x20,0x40,0x80,0xfe,0x82,0x84,0x80,0x80,0x80,0x80,0x0,
-+0x21,0x21,0x39,0x27,0x41,0x79,0xa7,0x24,0xfc,0x24,0x27,0x24,0x2c,0x34,0x27,0x4,0x10,0x10,0x14,0xfe,0x10,0x14,0xfe,0x44,0x44,0x44,0xfc,0x44,0x44,0x44,0xfc,0x4,
-+0x0,0x0,0x3f,0x2,0x2,0x3,0x3e,0x2,0x3,0xfe,0x2,0x2,0x2,0x2,0x1,0x0,0x10,0x78,0x80,0x0,0x20,0xf0,0x0,0x8,0xfc,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x0,0x1f,0x0,0x2,0x1,0x0,0xff,0x1,0x2,0x4,0x8,0x10,0x20,0x40,0x2,0x1,0x0,0xf0,0x20,0x40,0x80,0x80,0xfe,0x84,0x88,0x80,0x80,0x80,0x80,0x80,0x80,0x0,
-+0x21,0x26,0x3c,0x44,0x84,0x7c,0x24,0x24,0xfd,0x26,0x24,0x20,0x29,0x31,0x22,0x4,0x4,0x3e,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xb4,0xa8,0xa0,0x20,0x20,0x20,0x20,
-+0x4,0xe,0x30,0x22,0x22,0x22,0x22,0x22,0x22,0x2e,0x32,0x2,0x4,0x18,0x60,0x0,0x0,0x4,0x7e,0x44,0x44,0x44,0x44,0x44,0x44,0x64,0x54,0x48,0x40,0x40,0x40,0x40,
-+0x8,0x8,0xff,0x8,0x9,0x1,0x3f,0x21,0x20,0x20,0x20,0x20,0x20,0x23,0x4c,0x80,0x40,0x44,0xfe,0x40,0x20,0x10,0xfc,0x0,0x88,0x88,0x50,0x60,0xa0,0x12,0xa,0x6,
-+0x0,0x7f,0x40,0x5f,0x40,0x5f,0x40,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x1f,0x10,0x4,0xfe,0x4,0xf4,0x4,0xf4,0x4,0xf0,0x10,0xf0,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x20,0x23,0x22,0xfa,0xaa,0xaa,0xa8,0xa9,0xa9,0xa9,0xa9,0xb9,0x21,0x21,0x21,0x21,0x4,0xfe,0x4,0xf4,0x4,0xf4,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x4,0x8,0x35,0xd5,0x49,0x39,0x25,0xcd,0x15,0x65,0xc,0x14,0x64,0x4,0x29,0x12,0x40,0x84,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x54,0x50,0x50,0x92,0x92,0xe,0x0,
-+0x6,0x78,0x40,0x48,0x4e,0x72,0xc1,0x1f,0x10,0x11,0x11,0x11,0x11,0x2,0xc,0x70,0x4,0xfe,0x44,0x44,0x54,0x88,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0xc0,0x38,0x8,
-+0x1,0x1,0x2,0x2,0x4,0x8,0x10,0x21,0x41,0x2,0x4,0x8,0x10,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x40,0x80,0x0,0x0,0x0,0x20,0x10,0x8,0xfc,0x4,0x0,
-+0x0,0x8,0xfc,0x10,0x10,0x11,0x12,0x7c,0x10,0x10,0x10,0x10,0x1c,0xe0,0x41,0x6,0x40,0x40,0x40,0x84,0xfe,0x8,0x88,0x88,0x88,0x90,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x10,0x10,0x10,0x10,0xfc,0x11,0x32,0x38,0x54,0x50,0x90,0x10,0x10,0x10,0x11,0x16,0x40,0x40,0x40,0x84,0xfe,0x8,0x88,0x88,0x88,0x90,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x12,0x12,0x13,0x14,0xff,0x12,0x32,0x3a,0x57,0x52,0x94,0x14,0x17,0x10,0x10,0x10,0x0,0x8,0xfc,0x0,0xf8,0x8,0x88,0x48,0xfe,0x8,0x88,0x48,0xfc,0x8,0x28,0x10,
-+0x2,0xff,0x28,0x2a,0xff,0xaa,0xaa,0xae,0xc2,0x83,0x82,0xfe,0x82,0x82,0xfe,0x82,0x40,0x44,0x7e,0x80,0x4,0x7e,0x44,0x64,0x54,0xfe,0x84,0xa4,0x94,0xfc,0x4,0x18,
-+0x1f,0x1,0x7f,0x49,0x85,0x9,0x10,0x1f,0x20,0x5f,0x12,0xff,0x20,0x3f,0x0,0x0,0xf0,0x0,0xfe,0x22,0x44,0x20,0x0,0xf8,0x0,0xf0,0x14,0xfe,0x90,0xf8,0x10,0x30,
-+0x11,0x11,0x11,0x17,0x55,0x59,0x51,0x91,0x10,0x1f,0x10,0x10,0x29,0x46,0x84,0x0,0x10,0x10,0x14,0xfe,0x10,0xf0,0x10,0xf0,0x44,0xfe,0x40,0xe0,0x50,0x4e,0x44,0x40,
-+0x40,0x31,0x11,0x1,0x81,0x62,0x24,0x3,0x12,0x21,0xe1,0x20,0x20,0x20,0x23,0x2c,0x10,0xf8,0x10,0x10,0x10,0xe,0x0,0xf8,0x8,0x10,0x10,0xa0,0x40,0xa0,0x1e,0x8,
-+0x0,0x3f,0x21,0x21,0x3f,0x20,0x2f,0x28,0x28,0x2f,0x28,0x2f,0x28,0x48,0x8f,0x8,0x8,0xfc,0x8,0x8,0xf8,0x8,0xfc,0x8,0x8,0xf8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x21,0x21,0x21,0x27,0xf9,0x49,0x49,0x49,0x48,0x8f,0x50,0x20,0x51,0x4a,0x84,0x0,0x10,0x10,0x10,0xfc,0x10,0xf0,0x10,0xf0,0x44,0xfe,0x40,0xe0,0x50,0x4e,0x44,0x40,
-+0x21,0x20,0x3f,0x20,0x43,0x78,0xa0,0x27,0xf8,0x20,0x2f,0x20,0x28,0x31,0x22,0xc,0x10,0xa0,0xfc,0x40,0xf8,0x40,0x48,0xfc,0x40,0x44,0xfe,0x40,0xa0,0x10,0xe,0x4,
-+0x10,0x10,0x1f,0x20,0x5f,0x12,0x11,0x10,0xff,0x12,0x21,0x20,0x3f,0x0,0x0,0x0,0x0,0x8,0xfc,0x10,0xf8,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0xf8,0x20,0xa0,0x40,
-+0x8,0x6,0x2,0x7f,0x1,0x3f,0x1,0xff,0x1,0x1,0x7f,0x1,0x2,0x4,0x18,0xe0,0x20,0x60,0x88,0xfc,0x0,0xf8,0x0,0xfe,0x0,0x8,0xfc,0x0,0x80,0x60,0x1e,0x4,
-+0x0,0x8,0x7c,0x4b,0x48,0x48,0x48,0x7f,0x48,0x48,0x48,0x49,0x7a,0x44,0x8,0x0,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x40,0xe0,0xd0,0x48,0x4e,0x44,0x40,0x40,
-+0x2,0x1,0x7f,0x40,0xa4,0x24,0x25,0x3c,0x4,0xff,0x24,0x24,0x24,0x25,0x46,0x4,0x0,0x0,0xfe,0x2,0x24,0x20,0xfc,0x20,0x24,0xfe,0x20,0x70,0xa8,0x2e,0x24,0x20,
-+0x20,0x20,0x20,0x23,0xf8,0x48,0x48,0x4f,0x48,0x88,0x50,0x21,0x52,0x4c,0x88,0x0,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x40,0xe0,0xd0,0x48,0x4e,0x44,0x40,0x40,
-+0x10,0x11,0x11,0x11,0xfd,0x25,0x25,0x25,0x25,0x45,0x29,0x11,0x29,0x46,0x84,0x0,0x4,0xfe,0x24,0x24,0xfc,0x0,0x7c,0x44,0x44,0x7c,0x44,0x7c,0x44,0x44,0x7c,0x44,
-+0x20,0x1b,0x48,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x14,0x8,
-+0x20,0x1b,0x48,0x42,0x41,0x44,0x54,0x54,0x64,0x44,0x44,0x43,0x40,0x40,0x40,0x40,0x4,0xfe,0x4,0x4,0x4,0x84,0x94,0xc,0xc,0x24,0x24,0xe4,0x4,0x4,0x14,0x8,
-+0x10,0x12,0x11,0x24,0x24,0x64,0xa4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x0,0x4,0x7e,0x84,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x14,0x8,
-+0x8,0x8,0xff,0x8,0x7c,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x7d,0x41,0x2,0xc,0x20,0x24,0xfe,0x28,0xfc,0x88,0x88,0xf8,0x88,0x88,0xf8,0x88,0x8,0x8,0x28,0x10,
-+0x4,0x7f,0x4,0x7f,0x40,0x8f,0x0,0x7f,0x6,0x3b,0x5,0x1a,0x64,0x18,0x62,0x1,0x48,0xfc,0x40,0xfe,0x2,0xe4,0x0,0xfc,0x10,0x30,0xc0,0xa0,0x90,0x8e,0x84,0x0,
-+0x10,0x10,0x17,0x10,0xff,0x14,0x39,0x34,0x53,0x50,0x97,0x10,0x13,0x10,0x17,0x10,0x90,0x94,0xfe,0x90,0xfe,0x2,0xf4,0x0,0xfc,0xc0,0x68,0xb0,0x68,0xae,0x24,0x60,
-+0x3e,0x22,0x22,0x3e,0x22,0x22,0x3e,0x21,0x2,0x4,0x3f,0x24,0x24,0x24,0xff,0x0,0xf8,0x88,0x88,0xf8,0x88,0x88,0xf8,0x8,0x28,0x10,0xf8,0x48,0x48,0x48,0xfe,0x0,
-+0x20,0x23,0x38,0x40,0x80,0x7b,0x20,0x21,0xf8,0x23,0x22,0x22,0x2a,0x32,0x2f,0x0,0x0,0xf8,0x10,0x60,0x48,0xfc,0x40,0x40,0x88,0xfc,0xa8,0xa8,0xa8,0xa8,0xfe,0x0,
-+0x0,0x8b,0x50,0x20,0x50,0x97,0x10,0x11,0x30,0x53,0x92,0x12,0x12,0x12,0xaf,0x40,0x0,0xf8,0x10,0x60,0x48,0xfc,0x40,0x40,0x88,0xfc,0xa8,0xa8,0xa8,0xa8,0xfe,0x0,
-+0x8,0x8,0xff,0x8,0x1c,0x2a,0x49,0x8c,0x7,0xc,0x14,0x22,0x1,0x1,0xe,0x70,0x20,0x24,0xfe,0x20,0x70,0xae,0x24,0x20,0xf8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,
-+0x0,0x1f,0x0,0x0,0x1,0xff,0x1,0x5,0x2,0x3f,0x24,0x24,0x24,0x24,0xff,0x0,0x0,0xf0,0x20,0xc0,0x4,0xfe,0x0,0x0,0x8,0xfc,0x48,0x48,0x48,0x48,0xfe,0x0,
-+0x8,0x7c,0x4a,0x49,0x49,0x78,0x4f,0x48,0x78,0x48,0x49,0x49,0x7a,0x44,0x0,0x0,0x40,0x40,0x44,0x4c,0x50,0x44,0xfe,0x40,0xe0,0xe0,0x50,0x48,0x4e,0x44,0x40,0x40,
-+0x2,0xff,0x28,0x29,0xfe,0xaa,0xaa,0xaf,0xc2,0x82,0x82,0xfe,0x82,0x82,0xff,0x82,0x10,0x10,0x52,0x34,0xb8,0x10,0x7e,0x90,0xb0,0xb8,0xd6,0x92,0x90,0x90,0x46,0x3c,
-+0x1,0x0,0x7f,0x44,0x5f,0x4e,0x55,0x64,0x41,0x5f,0x41,0x4f,0x41,0x5f,0x81,0x1,0x0,0x84,0xfe,0x10,0x7c,0x38,0x54,0x92,0x40,0x7c,0x40,0x78,0x40,0x7c,0x40,0x40,
-+0x1,0x0,0x7f,0x44,0x5f,0x4e,0x55,0x64,0x44,0x42,0x7f,0x41,0x42,0x4c,0xb0,0x0,0x0,0x84,0xfe,0x10,0x7c,0x38,0x54,0x92,0x90,0xa4,0xfe,0xc0,0xb0,0x8e,0x84,0x80,
-+0x0,0x40,0x32,0x11,0x0,0x0,0xf7,0x10,0x11,0x11,0x12,0x14,0x10,0x28,0x44,0x83,0x40,0x40,0x48,0x50,0x40,0x44,0xfe,0x40,0x60,0x50,0x48,0x48,0x40,0x40,0x6,0xfc,
-+0x0,0x40,0x29,0x24,0x4,0x0,0xe3,0x2c,0x24,0x24,0x24,0x2d,0x34,0x24,0xa,0x11,0x20,0x20,0x24,0xa8,0x20,0x24,0xfe,0x20,0x70,0x68,0xa4,0x24,0x20,0x20,0x6,0xfc,
-+0x8,0xfc,0x8,0x8,0x9,0x79,0x4a,0x40,0x48,0x7c,0x9,0xa,0x8,0x8,0x50,0x20,0x80,0x80,0x80,0xfe,0x2,0x4,0x20,0x20,0xa8,0xa4,0x26,0x22,0x20,0x20,0xa0,0x40,
-+0x1,0x21,0x19,0xd,0x5,0x1,0xff,0x3,0x3,0x5,0x9,0x11,0x21,0xc1,0x1,0x1,0x0,0x8,0x18,0x20,0x40,0x4,0xfe,0x0,0x80,0x40,0x20,0x10,0xe,0x4,0x0,0x0,
-+0x8,0x1c,0xf0,0x10,0x11,0xfd,0x11,0x39,0x35,0x55,0x55,0x99,0x13,0x15,0x18,0x10,0x0,0x80,0x60,0x2c,0x8,0x10,0x10,0x20,0x28,0x44,0x86,0x2,0x8,0x8,0xf8,0x0,
-+0x0,0x7f,0x11,0x9,0x0,0x1f,0x10,0x11,0x11,0x11,0x11,0x12,0x2,0x4,0x18,0x60,0xfc,0x0,0x10,0x20,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x90,0x80,0x82,0x82,0x7e,
-+0x40,0x30,0x10,0x0,0x81,0x61,0x21,0x9,0x15,0x25,0xe5,0x29,0x23,0x25,0x28,0x20,0x0,0x80,0x60,0x2c,0x8,0x10,0x10,0x20,0x28,0x44,0x86,0x2,0x8,0x8,0xf8,0x0,
-+0x2,0x1,0x7f,0x42,0x89,0x28,0x4b,0xc,0x77,0x1,0x3f,0x21,0x3f,0x1,0x7f,0x20,0x0,0x0,0xfe,0x2,0x24,0xc8,0x4,0x10,0xf0,0x0,0xf8,0x8,0xf8,0x4,0xfc,0x4,
-+0x2,0x1,0x7f,0x42,0x89,0x28,0x4b,0xc,0x77,0x1,0x21,0x21,0x21,0x21,0x3f,0x20,0x0,0x0,0xfe,0x2,0x24,0xc8,0x4,0x10,0xf0,0x0,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x7f,0x40,0x9f,0x10,0x1f,0x10,0x1f,0x0,0xff,0x9,0x1f,0x29,0xc9,0x9,0x1,0x0,0xfe,0x2,0xf4,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x20,0xf0,0x2e,0x24,0x60,0x0,
-+0x10,0x10,0x13,0x12,0xff,0x12,0x33,0x38,0x57,0x54,0x94,0x14,0x14,0x14,0x10,0x10,0x40,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x44,0xfe,0x44,0x44,0x44,0x54,0x48,0x40,0x40,
-+0x0,0x7b,0x4a,0x4a,0x4a,0x7b,0x4a,0x4a,0x4b,0x7a,0x4a,0x4a,0x4a,0x7a,0x4b,0x2,0x8,0xfc,0x8,0x8,0x8,0xf8,0x40,0x44,0xfe,0x40,0x20,0x20,0x10,0x92,0xa,0x6,
-+0x10,0x10,0x23,0x22,0x4b,0xfa,0x13,0x20,0x47,0xfc,0x4,0x4,0x1c,0xe4,0x40,0x0,0x40,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x44,0xfe,0x44,0x44,0x44,0x54,0x48,0x40,0x40,
-+0x7f,0x40,0x5f,0x40,0x5f,0x8,0xf,0x10,0x1f,0x31,0x51,0x9f,0x12,0x4,0x18,0x60,0xfc,0x4,0xf4,0x4,0xf4,0x0,0xe0,0x48,0xfc,0x8,0x8,0xf8,0x88,0x82,0x82,0x7e,
-+0x8,0x8,0x1f,0x10,0x20,0x7f,0xa1,0x21,0x21,0x3f,0x22,0x2,0x4,0x8,0x30,0xc0,0x0,0x0,0xe0,0x40,0x88,0xfc,0x8,0x8,0x8,0xf8,0x88,0x80,0x80,0x82,0x82,0x7e,
-+0x10,0x10,0x3e,0x24,0x48,0xff,0x49,0x49,0x7f,0x55,0x14,0x24,0x25,0x44,0x83,0x0,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x44,0x44,0x94,0xa,0x2,0xfe,0x0,
-+0x10,0x10,0x10,0x11,0xfe,0x25,0x25,0x25,0x25,0x45,0x28,0x10,0x28,0x45,0x82,0x4,0x80,0x80,0xf8,0x10,0x24,0xfe,0x24,0x24,0xfc,0x54,0x50,0x90,0x92,0x12,0xe,0x0,
-+0x10,0x17,0x20,0x20,0x4b,0xfa,0x12,0x22,0x42,0xfa,0x2,0x2,0x1a,0xe2,0x43,0x2,0x4,0xfe,0x40,0x84,0xfe,0x94,0x94,0xf4,0x94,0x94,0xf4,0x94,0x94,0x94,0xfc,0x4,
-+0x0,0xff,0x2,0x4,0x7f,0x44,0x44,0x47,0x44,0x44,0x44,0x47,0x44,0x44,0x7f,0x40,0x4,0xfe,0x0,0x4,0xfe,0x44,0x44,0xc4,0x44,0x44,0x44,0xc4,0x44,0x44,0xfc,0x4,
-+0x4,0x4,0xff,0x4,0x4,0x0,0x3f,0x21,0x21,0x21,0x3f,0x21,0x21,0x21,0x3f,0x20,0x40,0x44,0xfe,0x40,0x40,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x21,0x21,0x21,0x2f,0xf9,0x21,0x27,0x2c,0x34,0xe4,0x27,0x24,0x24,0x24,0xa7,0x44,0x10,0x10,0x14,0xfe,0x10,0x14,0xfe,0x44,0x44,0x44,0xfc,0x44,0x44,0x44,0xfc,0x4,
-+0x9,0x7d,0x49,0x4f,0x49,0x79,0x4b,0x4a,0x4a,0x7a,0x4b,0x4a,0x4a,0x7a,0x4b,0x2,0x10,0x10,0x14,0xfe,0x10,0x14,0xfe,0x44,0x44,0x44,0xfc,0x44,0x44,0x44,0xfc,0x4,
-+0x8,0xff,0xa,0xc,0x12,0x6b,0x2d,0x31,0xc9,0x15,0x24,0xcc,0x14,0xe4,0x29,0x12,0x24,0xfe,0x20,0x20,0x44,0xfe,0x4,0xfc,0x4,0xfc,0x90,0x90,0x92,0x92,0xe,0x0,
-+0x4,0xe,0x78,0x8,0x8,0xfe,0x8,0x1d,0x1a,0x28,0x28,0x48,0x88,0x8,0x8,0xb,0x20,0x20,0x20,0x20,0xa8,0xa6,0xa2,0x20,0x24,0x24,0x28,0x10,0x20,0x40,0x80,0x0,
-+0x80,0x61,0x2f,0x9,0x9,0x8f,0x69,0x29,0x9,0x1f,0x29,0xc9,0x4f,0x48,0x41,0x46,0x10,0x10,0x90,0x10,0x10,0x54,0x52,0x52,0x90,0x14,0x14,0x8,0x10,0x60,0x80,0x0,
-+0x1,0x0,0x3f,0x20,0x20,0x20,0x2f,0x28,0x28,0x28,0x2f,0x28,0x48,0x48,0x8f,0x8,0x0,0x84,0xfe,0x0,0x80,0x88,0xfc,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0xf8,0x8,
-+0x10,0x10,0x10,0x10,0xfc,0x24,0x24,0x25,0x24,0x44,0x28,0x10,0x28,0x44,0x80,0x3,0x20,0x20,0x20,0x20,0xa8,0xa6,0xa2,0x20,0x24,0x24,0x28,0x10,0x20,0x40,0x80,0x0,
-+0x4,0xff,0x4,0x3f,0x24,0x24,0x3f,0x1,0x3f,0x21,0x21,0x28,0x24,0x40,0x41,0x8e,0x44,0xfe,0x40,0xf8,0x48,0x48,0xf8,0x20,0xfc,0x0,0x8,0x90,0xa0,0x42,0xa2,0x1e,
-+0x0,0xff,0x1,0x1,0x11,0x11,0x11,0x21,0x2,0x2,0x4,0x4,0x8,0x10,0x60,0x0,0x4,0xfe,0x0,0x0,0x8,0x18,0x20,0x40,0x80,0x80,0x40,0x20,0x10,0xe,0x4,0x0,
-+0x0,0x7f,0x40,0x40,0x40,0x7f,0x42,0x42,0x7f,0x42,0x41,0x41,0x48,0x50,0x60,0x40,0x10,0xf8,0x10,0x10,0x10,0xf0,0x0,0x8,0xfc,0x0,0x0,0x0,0x80,0x42,0x32,0xe,
-+0x10,0x13,0x12,0x12,0xfe,0x13,0x16,0x1a,0x33,0xd2,0x12,0x12,0x12,0x12,0x53,0x22,0x8,0xfc,0x8,0x8,0x8,0xf8,0x40,0x44,0xfe,0x40,0x20,0x20,0x10,0x92,0xa,0x6,
-+0x0,0x0,0x3f,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0xff,0x0,0x0,0x0,0x8,0xfc,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0xfe,0x0,0x0,
-+0x10,0x11,0x3f,0x20,0x7f,0xa9,0x25,0x21,0xff,0x29,0x45,0x41,0x7f,0x1,0xa,0x4,0x20,0x20,0xa0,0x24,0x7e,0x84,0x44,0x44,0xc8,0x28,0x28,0x10,0xa8,0x28,0x46,0x84,
-+0x12,0x11,0x10,0x12,0x5a,0x57,0x52,0x92,0x12,0x12,0x12,0x13,0x12,0x12,0x12,0x12,0x4,0x7e,0x4,0x44,0x24,0xfc,0x94,0x54,0x54,0x24,0x54,0x8c,0x4,0x4,0x14,0x8,
-+0x20,0x1b,0x48,0x41,0x41,0x4f,0x49,0x49,0x49,0x4f,0x49,0x41,0x41,0x5f,0x40,0x40,0x4,0xfe,0x4,0x4,0x24,0xf4,0x24,0x24,0x24,0xe4,0x4,0x24,0xf4,0x14,0x14,0x8,
-+0x0,0x4,0x7e,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x7c,0x44,0x1,0x1,0x2,0x4,0x4,0xfe,0x84,0x84,0x84,0xfc,0x84,0x84,0x84,0xfc,0x84,0x84,0x4,0x4,0x14,0x8,
-+0x10,0x13,0x12,0x14,0x7d,0x55,0x55,0x55,0x7d,0x54,0x10,0x17,0x1c,0xe4,0x41,0x2,0x0,0xfe,0x2,0x4,0xfe,0x4,0xfc,0x4,0xfc,0x40,0x24,0xfe,0x0,0x88,0x6,0x2,
-+0x0,0x8,0x7d,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x78,0x48,0x7,0x0,0x0,0x0,0x40,0x88,0xfc,0x8,0x48,0x8,0x28,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x10,0x10,0x1e,0x20,0x21,0x7e,0x90,0x10,0x7c,0x11,0x12,0x10,0x14,0x18,0x10,0x0,0x40,0x40,0xfc,0x84,0x88,0x50,0x20,0x40,0x84,0xfe,0x84,0x84,0x84,0x84,0xfc,0x84,
-+0x2,0x2,0x7,0x4,0xc,0x12,0x1,0x6,0x18,0xef,0x8,0x8,0x8,0x8,0xf,0x8,0x0,0x0,0xf0,0x10,0x20,0x40,0x80,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x1,0x1,0x2,0x4,0x8,0x3f,0xc0,0x3e,0x22,0x22,0x22,0x22,0x3e,0x22,0x0,0x0,0x0,0x0,0x80,0x40,0x30,0xfe,0x8,0xfc,0x88,0x88,0x88,0xc8,0xa8,0x90,0x80,0x80,
-+0x0,0x4f,0x24,0x22,0x4,0xe0,0x21,0x22,0x2c,0x21,0x22,0x20,0x2b,0x30,0x20,0x3,0x84,0xfe,0xa4,0x94,0xa4,0xc4,0x20,0x50,0x8e,0x24,0x40,0x90,0x20,0x40,0x80,0x0,
-+0x11,0x11,0x1f,0x11,0xfd,0x13,0x16,0x1b,0x32,0xd3,0x10,0x1f,0x10,0x10,0x51,0x26,0x10,0x14,0xfe,0x10,0x18,0xfc,0x8,0xf8,0x8,0xf8,0x40,0xfe,0x40,0xa0,0x1c,0x8,
-+0x8,0xff,0x8,0x3f,0x21,0x3f,0x2,0xff,0x4,0x1f,0x21,0xdf,0x1,0x3f,0x1,0x3,0x24,0xfe,0x20,0xf8,0x8,0xf8,0x0,0xfe,0x40,0xf0,0x8,0xf6,0x0,0xf8,0x0,0x0,
-+0x8,0xff,0x9,0x7f,0x44,0x7f,0x4c,0x56,0x65,0x7f,0x42,0x44,0x4f,0x74,0x84,0x7,0x24,0xfe,0x20,0xfc,0x20,0xfc,0x70,0xae,0x24,0xfc,0x0,0x8,0xfc,0x8,0x8,0xf8,
-+0x11,0x11,0x1f,0x11,0xfd,0x13,0x32,0x3b,0x56,0x53,0x90,0x1f,0x10,0x10,0x11,0x16,0x10,0x14,0xfe,0x10,0x18,0xfc,0x8,0xf8,0x8,0xf8,0x40,0xfe,0x40,0xb0,0xe,0x4,
-+0x1,0x79,0x4f,0x49,0x49,0x7b,0x4a,0x4b,0x4a,0x7b,0x48,0x4f,0x48,0x48,0x49,0x9e,0x10,0x14,0xfe,0x10,0x18,0xfc,0x8,0xf8,0x8,0xf8,0x40,0xfe,0x40,0xb0,0xe,0x4,
-+0x1,0x7f,0x44,0x44,0x7f,0x4e,0x55,0x64,0x7f,0x42,0x44,0x4f,0x54,0x64,0x87,0x4,0x4,0xfe,0x20,0x24,0xfe,0x70,0xa8,0x24,0xfe,0x0,0x8,0xfc,0x8,0x8,0xf8,0x8,
-+0x1,0x7f,0x44,0x44,0x7f,0x4e,0x55,0x64,0x5f,0x41,0x4f,0x41,0x7f,0x41,0x85,0x2,0x8,0xfc,0x20,0x20,0xfc,0x70,0xae,0x24,0xf0,0x0,0xf0,0x0,0xfc,0x0,0x0,0x0,
-+0x0,0x3f,0x22,0x3f,0x26,0x2b,0x32,0x2f,0x28,0x2f,0x28,0x2f,0x49,0x42,0x8c,0x30,0x84,0xfe,0x20,0xfc,0x30,0x6e,0xa4,0xf8,0x88,0xf8,0x88,0xf8,0x40,0x52,0x42,0x3e,
-+0x10,0x10,0x10,0x17,0xfc,0x10,0x13,0x1c,0x30,0xd0,0x11,0x12,0x14,0x10,0x50,0x20,0x40,0x40,0x44,0xfe,0x40,0x48,0xfc,0x40,0xe0,0xd0,0x48,0x4e,0x44,0x40,0x40,0x40,
-+0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x7f,0x3,0x3,0x5,0x9,0x11,0x61,0x1,0x1,0x0,0x0,0x4,0xfe,0x0,0x0,0x8,0xfc,0x80,0x40,0x20,0x18,0xe,0x4,0x0,0x0,
-+0x4,0x4,0x7f,0x4,0x4,0x1f,0x10,0x1f,0x10,0x1f,0x1,0xff,0x1,0x2,0xc,0x70,0x40,0x48,0xfc,0x40,0x50,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x0,0x80,0x60,0x1c,
-+0x0,0x3f,0x29,0x25,0x3f,0x1,0x3f,0x1,0x7f,0x24,0x42,0x81,0x3f,0x1,0x1,0x7f,0x8,0xfc,0x28,0x48,0xf8,0x0,0xf8,0x0,0xfc,0x48,0x26,0x12,0xf8,0x0,0x8,0xfc,
-+0x1,0x7f,0x49,0x6b,0x5d,0x7f,0x8,0x7f,0x8,0xf,0x78,0x5,0x55,0x54,0x91,0x2,0x20,0xb0,0x28,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x0,0x40,0x30,0x1f,0x80,0x60,0x27,0x8,0x10,0x20,0xe1,0x22,0x24,0x20,0x20,0x20,0x40,0x40,0x44,0xfe,0x40,0x48,0xfc,0x40,0xe0,0xd0,0x48,0x4e,0x44,0x40,0x40,0x40,
-+0x1,0x41,0x2f,0x11,0x81,0x63,0x22,0xb,0x12,0x23,0xe0,0x3f,0x20,0x20,0x23,0x2c,0x10,0x14,0xfe,0x10,0x18,0xfc,0x8,0xf8,0x8,0xf8,0x40,0xfe,0x40,0xb0,0xe,0x4,
-+0x1,0x7f,0x44,0x84,0x3f,0x4,0x1f,0x10,0x1f,0x10,0x1f,0x1,0xff,0x2,0xc,0x30,0x0,0xfe,0x42,0x54,0xf8,0x40,0xf0,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x80,0x60,0x1c,
-+0x0,0x7f,0x44,0x48,0x48,0x51,0x49,0x49,0x45,0x45,0x45,0x69,0x51,0x41,0x41,0x41,0x4,0xfe,0x20,0x20,0x44,0xfe,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x2,0x42,0x3f,0x12,0x3,0x2,0xf2,0x13,0x10,0x1f,0x10,0x10,0x15,0x1a,0x14,0x0,0x8,0x8,0xfe,0x8,0xf8,0x8,0x8,0xf8,0x44,0xfe,0x40,0xe0,0x50,0x4e,0x44,0x40,
-+0x1,0x2,0x4,0x8,0x3f,0x1,0x11,0x1f,0x21,0x41,0x1,0xff,0x1,0x1,0x1,0x1,0x0,0x0,0x20,0x10,0xf8,0x8,0x10,0xf8,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,
-+0x8,0x8,0x7f,0x8,0xf,0x8,0x8,0xf,0x1,0xff,0x1,0x3,0x5,0x19,0x61,0x1,0x20,0x28,0xfc,0x20,0xe0,0x20,0x20,0xe0,0x4,0xfe,0x0,0x80,0x60,0x1c,0x8,0x0,
-+0x10,0x13,0x12,0x12,0xfe,0x12,0x12,0x1f,0x34,0xd4,0x14,0x14,0x17,0x10,0x50,0x20,0x8,0xfc,0x8,0x88,0x48,0x8,0x8,0xfe,0x8,0x88,0x48,0x8,0xfc,0x8,0x50,0x20,
-+0x8,0x8,0x48,0x4a,0x7f,0x48,0x89,0x8,0x8,0xe,0x18,0xe8,0x8,0x8,0xb,0x8,0x20,0x20,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x2,0x1,0xff,0x0,0x0,0x3f,0x21,0x21,0x21,0x3f,0x21,0x21,0x21,0x21,0x3f,0x20,0x0,0x4,0xfe,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x10,0x10,0xfc,0x24,0x24,0x27,0x25,0x45,0x29,0x11,0x29,0x44,0x84,0x0,0x4,0xfe,0x84,0xa4,0x94,0x84,0x84,0xfe,0x4,0x24,0x14,0x4,0xfe,0x4,0x28,0x10,
-+0x0,0x1f,0x10,0x12,0x11,0x10,0x10,0xff,0x20,0x22,0x21,0x20,0x3f,0x0,0x0,0x0,0x10,0xf8,0x10,0x10,0x90,0x90,0x14,0xfe,0x10,0x10,0x90,0x90,0xf8,0x10,0xa0,0x40,
-+0x4,0x7f,0x4,0x1f,0x10,0x1f,0x10,0x1f,0x2,0xff,0x4,0x9,0x37,0xc1,0x1,0x1f,0x48,0xfc,0x50,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x40,0x30,0xce,0x4,0x20,0xf0,
-+0x4,0x7f,0x4,0x1f,0x10,0x1f,0x10,0x1f,0x4,0xff,0x8,0x1f,0x28,0xcf,0x8,0xf,0x48,0xfc,0x50,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x20,0xf0,0x28,0xe6,0x20,0xe0,
-+0x4,0x7f,0x4,0x1f,0x10,0x1f,0x10,0x1f,0x4,0xff,0x11,0x3f,0xd1,0x11,0x11,0x1,0x48,0xfc,0x50,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x10,0xfe,0x14,0x50,0x20,0x0,
-+0x4,0x7f,0x4,0x1f,0x10,0x1f,0x10,0x1f,0x4,0xff,0x12,0x22,0xdf,0x4,0x8,0x30,0x48,0xfc,0x50,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x10,0xe,0xe4,0x20,0xa0,0x40,
-+0x4,0x7f,0x4,0x1f,0x10,0x1f,0x10,0x1f,0x4,0xff,0x12,0x22,0xcb,0x12,0x22,0x6,0x48,0xfc,0x50,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x10,0xe,0x24,0x90,0x90,0x0,
-+0x1,0x1,0x1,0x1,0xff,0x1,0x3,0x3,0x5,0x9,0x11,0x21,0xc1,0x1,0x1,0x1,0x0,0x0,0x0,0x4,0xfe,0x0,0x80,0x40,0x20,0x10,0x8,0xe,0x4,0x0,0x0,0x0,
-+0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x10,0x10,0x1f,0x10,0x10,0x10,0x1f,0x10,0x0,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,0x10,0x10,0xf0,0x10,0x10,0x10,0xf0,0x10,0x0,
-+0x8,0x7c,0x4b,0x48,0x48,0x78,0x4f,0x49,0x4a,0x7c,0x4b,0x48,0x48,0x78,0x4f,0x0,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x10,0x4c,0x44,0xf8,0x40,0x40,0x44,0xfe,0x0,
-+0x8,0x8,0x48,0x48,0x7e,0x49,0x8a,0x8,0xe,0x18,0xe8,0x8,0x8,0x8,0x9,0xe,0x40,0x40,0x40,0x84,0xfe,0x8,0x88,0x88,0x88,0x90,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x8,0x1c,0xf3,0x12,0x13,0xfe,0x33,0x39,0x52,0x54,0x53,0x90,0x13,0x10,0x10,0x17,0x40,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x50,0x64,0x42,0x90,0x20,0xc8,0x10,0x60,0x80,
-+0x1,0x2,0xc,0x37,0xc0,0x1f,0x10,0x1f,0x0,0x3f,0x1,0x1f,0x1,0x7f,0x1,0x3,0x0,0x80,0x60,0xde,0x4,0xf0,0x10,0xf0,0x30,0xc0,0x0,0xf0,0x0,0xfc,0x0,0x0,
-+0x0,0xf,0x72,0x52,0x5f,0x52,0x52,0x52,0x5f,0x52,0x52,0x74,0x54,0x9,0x10,0x0,0x0,0xde,0x52,0x54,0xd4,0x54,0x58,0x54,0xd2,0x52,0x52,0x52,0x5a,0x54,0x90,0x10,
-+0x0,0x8,0x7c,0x4b,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4b,0x4a,0x7a,0x4a,0x2,0x2,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0xa4,0x94,0x14,0x4,0x4,0x4,0x14,0x8,
-+0x20,0x20,0x38,0x23,0x42,0x7a,0xa2,0x22,0xfa,0x22,0x23,0x22,0x2a,0x32,0x22,0x2,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0xa4,0x94,0x14,0x4,0x4,0x4,0x14,0x8,
-+0x0,0x7f,0x9,0x9,0x7f,0x9,0x9,0x9,0x7f,0x9,0x9,0x11,0x11,0x25,0x42,0x0,0x4,0x7e,0x44,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x20,0x27,0x22,0x22,0xfa,0x4f,0x4a,0x4a,0x8a,0x57,0x22,0x52,0x4d,0x84,0x8,0x0,0x0,0xde,0x52,0x52,0x54,0xd4,0x58,0x54,0x54,0xd2,0x52,0x5a,0x54,0x90,0x10,0x10,
-+0x10,0x10,0x20,0x23,0x4a,0xfa,0x12,0x22,0x42,0xfa,0x3,0x2,0x1a,0xe2,0x42,0x2,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0xa4,0x94,0x14,0x4,0x4,0x4,0x14,0x8,
-+0x10,0x1f,0x10,0x2f,0x40,0x9f,0x0,0x7f,0x8,0x8,0x9,0x8,0x10,0x10,0x21,0x40,0x8,0xfc,0x0,0xf8,0x0,0xf8,0x88,0xc8,0x88,0x88,0xe8,0x28,0x2a,0x2a,0x4a,0x84,
-+0x0,0x7f,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x10,0x10,0x10,0x20,0x40,0x80,0x0,0x10,0xf8,0x10,0x10,0x20,0x44,0xfe,0x4,0x4,0x4,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x10,0x17,0x10,0x10,0xfc,0x24,0x24,0x24,0x24,0x49,0x29,0x11,0x2a,0x4a,0x84,0x8,0x8,0xfc,0x88,0x88,0x88,0x90,0x94,0xbe,0x84,0x4,0x4,0x4,0x4,0x4,0x28,0x10,
-+0x1,0xff,0x8,0x8,0x10,0x7f,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x43,0x0,0x8,0x88,0x8,0x8,0xfe,0x8,0x8,0x88,0x68,0x28,0x8,0x8,0x8,0x8,0x28,0x10,
-+0x1,0x1,0x7f,0x2,0x4,0x8,0x10,0xef,0x0,0x0,0x3f,0x1,0x9,0x11,0x65,0x2,0x0,0x8,0xfc,0x80,0x40,0x30,0x4e,0xe4,0x0,0x10,0xf8,0x0,0x20,0x18,0x8,0x0,
-+0x1,0x1,0xff,0x1,0x1,0x7f,0x48,0x44,0x5f,0x41,0x41,0x5f,0x41,0x41,0x41,0x40,0x0,0x4,0xfe,0x0,0x4,0xfe,0x24,0x44,0xf4,0x4,0x4,0xf4,0x4,0x4,0x14,0x8,
-+0x0,0x3f,0x21,0x21,0x3f,0x21,0x21,0x3f,0x21,0x1,0xff,0x2,0x2,0x4,0x18,0x60,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x0,0x4,0xfe,0x4,0x4,0x4,0x28,0x10,
-+0x0,0x4,0xfe,0x4,0x44,0x45,0x2a,0x28,0x10,0x10,0x28,0x24,0x44,0x80,0x0,0x0,0x60,0x50,0x44,0xfe,0x90,0x90,0xfc,0x90,0x90,0xfc,0x90,0x90,0x94,0xfe,0x80,0x80,
-+0x1,0x3f,0x9,0x7f,0x52,0x9e,0x4,0x7f,0x4,0x3f,0x4,0x7f,0xc,0x14,0x65,0x6,0x10,0xf8,0x20,0xfe,0x92,0xf4,0x40,0xfc,0x40,0xf8,0x40,0xfc,0x90,0x60,0x1c,0x8,
-+0x10,0x10,0x10,0x17,0xfc,0x10,0x10,0x1f,0x30,0xd7,0x11,0x11,0x11,0x11,0x52,0x2c,0x80,0x88,0xfc,0x80,0x48,0x32,0xd2,0xe,0x8,0xfc,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x8,0x7c,0x48,0x4f,0x48,0x7a,0x4b,0x4a,0x4a,0x7a,0x4a,0x4b,0x4a,0x4a,0x4b,0x9a,0x80,0x40,0x4,0xfe,0x0,0x14,0x14,0xa4,0xa4,0x44,0xa4,0x1c,0xc,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x17,0x58,0x52,0x53,0x92,0x12,0x12,0x12,0x13,0x12,0x12,0x13,0x12,0x80,0x40,0x4,0xfe,0x0,0x14,0x14,0xa4,0xa4,0x44,0xa4,0x1c,0xc,0x4,0xfc,0x4,
-+0x40,0x37,0x10,0x42,0x41,0x5f,0x41,0x41,0x4f,0x49,0x49,0x49,0x49,0x41,0x41,0x40,0x4,0xfe,0x4,0x4,0x24,0xf4,0x4,0x24,0xf4,0x24,0x24,0x24,0x64,0x4,0x14,0x8,
-+0x40,0x30,0x10,0x0,0x87,0x64,0x27,0xc,0x17,0x20,0xe0,0x3f,0x20,0x20,0x20,0x20,0x88,0xfc,0x80,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x80,0x84,0xfe,0x80,0x80,0x80,0x80,
-+0x0,0xb,0x7e,0x4a,0x4a,0x4b,0x4a,0x4a,0x4a,0x4a,0x4a,0x7c,0x44,0x8,0x10,0x20,0x8,0xfc,0x8,0x8,0x8,0xf8,0x0,0x88,0x98,0xa0,0xc0,0x80,0x82,0x82,0x7e,0x0,
-+0x20,0x27,0x20,0x3a,0x49,0x51,0x80,0x20,0x2f,0x21,0x22,0x21,0x28,0x30,0x21,0x6,0x1c,0xe0,0x0,0x44,0x24,0x28,0x80,0x84,0xfe,0x8,0x8,0x10,0xa0,0xe0,0x18,0x8,
-+0x1,0x1,0x1,0x1,0x7f,0x41,0x41,0x42,0x42,0x44,0x48,0x50,0x40,0x40,0x40,0x40,0x0,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x84,0x64,0x34,0x14,0x4,0x4,0x14,0x8,
-+0x21,0x21,0x2f,0x21,0xf1,0x57,0x55,0x55,0x55,0x97,0x53,0x23,0x55,0x49,0x81,0x1,0x10,0x50,0xf4,0x1e,0x24,0xd4,0x54,0x54,0x54,0xd4,0x14,0x88,0x54,0x14,0x24,0x42,
-+0x10,0x10,0x24,0x44,0xfe,0x2,0x7c,0x44,0x7c,0x44,0x44,0x7c,0x44,0x44,0x54,0x48,0x80,0x88,0x98,0xa0,0xc0,0x84,0x84,0x7c,0x0,0x88,0x98,0xa0,0xc0,0x82,0x82,0x7e,
-+0x10,0x11,0x11,0x11,0xfd,0x25,0x25,0x25,0x25,0x49,0x29,0x12,0x2a,0x46,0x84,0x8,0x4,0xfe,0x4,0x4,0x4,0xfc,0x0,0x40,0x44,0x4c,0x50,0x60,0x42,0x42,0x3e,0x0,
-+0x1f,0x1,0x7f,0x49,0x85,0x9,0x2,0x3c,0x20,0x3e,0x20,0x3f,0x24,0x4,0x18,0x60,0xf0,0x0,0xfe,0x22,0x44,0x20,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x48,0x42,0x42,0x3e,
-+0x8,0x8,0xb,0x12,0x12,0x33,0x52,0x92,0x13,0x12,0x10,0x10,0x11,0x11,0x12,0x14,0x40,0x84,0x3e,0x4,0x4,0xbc,0x4,0x4,0xfc,0x94,0x90,0x90,0x12,0x12,0xe,0x0,
-+0x40,0x37,0x14,0x4,0x84,0x67,0x25,0xd,0x15,0x25,0xe5,0x25,0x25,0x29,0x28,0x10,0x8,0xfc,0x8,0x8,0x8,0xf8,0x0,0x8,0x18,0x20,0x40,0x80,0x2,0x2,0xfe,0x0,
-+0x0,0x3f,0x20,0x20,0x20,0x3f,0x24,0x24,0x24,0x24,0x27,0x24,0x24,0x44,0x43,0x80,0x8,0xfc,0x8,0x8,0x8,0xf8,0x0,0x10,0x30,0xc0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x10,0x10,0x12,0xfe,0x12,0x16,0x1a,0x32,0xd2,0x12,0x12,0x13,0x12,0x50,0x20,0x0,0x8,0x88,0x48,0x68,0x28,0x8,0x8,0x8,0x8,0x48,0x88,0x14,0x22,0x42,0x80,
-+0x11,0x11,0x11,0x23,0x22,0x64,0xa8,0x20,0x21,0x21,0x22,0x24,0x20,0x20,0x21,0x20,0x0,0x0,0x0,0xfc,0x4,0x8,0x40,0x40,0x50,0x48,0x4c,0x44,0x40,0x40,0x40,0x80,
-+0x0,0x7f,0x44,0x44,0x7f,0x44,0x41,0x7f,0x42,0x47,0x4c,0x54,0x47,0x40,0x7f,0x0,0x8,0xfc,0x40,0x50,0xf8,0x40,0x8,0xfc,0x0,0xf0,0x10,0x10,0xf0,0x8,0xfc,0x0,
-+0x0,0x78,0x4f,0x48,0x4b,0x78,0x4f,0x48,0x4b,0x7a,0x4a,0x4a,0x4a,0x4a,0x49,0x9a,0x14,0x10,0xfe,0x10,0xd0,0x10,0xf0,0x10,0xe8,0x28,0xa8,0xa8,0xaa,0xaa,0x4a,0x24,
-+0x2,0x41,0x30,0x17,0x0,0x2,0xf2,0x12,0x12,0x13,0x12,0x10,0x10,0x29,0x47,0x0,0x8,0x10,0xa0,0xfc,0x40,0x48,0x48,0x48,0x48,0xf8,0x48,0x40,0x80,0x6,0xfc,0x0,
-+0x0,0x47,0x30,0x10,0x87,0x64,0x24,0xf,0x10,0x24,0xe2,0x22,0x24,0x20,0x22,0x21,0x0,0xbc,0x84,0x84,0xbc,0x20,0x24,0xbe,0x84,0xa4,0x94,0x94,0xa4,0x84,0x94,0x8,
-+0x8,0xff,0x8,0x3f,0x1,0x9,0x9,0xff,0x10,0x1f,0x10,0x1f,0x29,0x24,0x44,0x0,0x24,0xfe,0x20,0xf8,0x0,0xf0,0x4,0xfe,0x0,0xf8,0x0,0xfc,0x24,0x94,0x94,0xc,
-+0x10,0x10,0x10,0x10,0xfc,0x10,0x14,0x18,0x33,0xd2,0x12,0x12,0x12,0x12,0x53,0x22,0x40,0x40,0x44,0x7e,0x40,0x40,0x40,0x44,0xfe,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x8,0x8,0x1f,0x11,0x21,0x41,0x1f,0x11,0x11,0x11,0xff,0x1,0x1,0x1,0x1,0x1,0x0,0x8,0xfc,0x0,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,
-+0x0,0xb,0xfe,0x12,0x13,0x22,0x2b,0x7e,0xaa,0x2b,0x2a,0x2a,0x3c,0x24,0x8,0x0,0x4,0xfe,0x4,0x4,0xfc,0x50,0xfc,0x50,0x54,0xfe,0xc4,0xa8,0x90,0x8e,0xc4,0x80,
-+0x21,0x21,0x27,0x21,0xff,0x21,0x22,0x3c,0x67,0xa1,0x22,0x27,0x20,0x3f,0xa0,0x40,0x10,0x10,0xfc,0x10,0xfe,0x10,0xae,0x84,0xf8,0x0,0x40,0xf8,0x40,0xfe,0x40,0x40,
-+0x10,0x10,0x10,0x10,0xfd,0x12,0x14,0x18,0x33,0xd0,0x10,0x12,0x16,0x1a,0x52,0x21,0x40,0x40,0xa0,0xa0,0x10,0x8e,0x44,0x0,0xf8,0x10,0x20,0x80,0x64,0x22,0x8,0xf8,
-+0x1,0x2,0x4,0x8,0x12,0x21,0xc1,0x1f,0x0,0x0,0x4,0x13,0x51,0x50,0x8f,0x0,0x0,0x80,0x40,0x20,0x10,0xe,0x4,0xf8,0x20,0x40,0x0,0x0,0x14,0x12,0xf2,0x0,
-+0x10,0x10,0x11,0x11,0xfd,0x25,0x25,0x25,0x25,0x45,0x29,0x11,0x29,0x45,0x85,0x1,0x40,0x28,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x44,0x48,0x30,0x10,0x4e,0x84,0x0,
-+0x1,0xff,0x14,0x14,0x7f,0x55,0x55,0x57,0x61,0x41,0x41,0x7f,0x41,0x41,0x7f,0x41,0x20,0x94,0x7e,0x44,0x44,0x7c,0x44,0x44,0x7c,0x60,0x52,0x54,0x48,0x48,0x64,0x42,
-+0x2,0x4,0x1f,0x10,0x14,0x12,0x12,0x10,0x10,0x1f,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x20,0xf0,0x20,0x20,0x20,0x20,0xa0,0x44,0xfe,0x4,0x24,0xf4,0x4,0x28,0x10,
-+0x0,0x3f,0x20,0x20,0x3f,0x20,0x20,0x2e,0x22,0x22,0x24,0x24,0x48,0x50,0x82,0x1,0x4,0xfe,0x4,0x4,0xfc,0x84,0x80,0xa4,0xa8,0xb0,0xa0,0x90,0x8e,0x84,0x80,0x0,
-+0x10,0x13,0x12,0x12,0xff,0x12,0x16,0x1b,0x30,0xd0,0x17,0x10,0x10,0x10,0x5f,0x20,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x0,
-+0x0,0x7f,0x8,0xf,0x8,0xf,0x8,0x7f,0x0,0x7e,0x2,0x24,0x14,0x8,0x16,0x62,0x8,0xfc,0x20,0xe0,0x20,0xe0,0x28,0xfc,0x20,0xfc,0x4,0x48,0x28,0x10,0x2e,0xc4,
-+0x4,0xff,0x10,0x7e,0x42,0x7e,0x41,0x7e,0x42,0x7e,0x40,0xf,0x0,0x7f,0x1,0x3,0x44,0xfe,0x20,0xf8,0x50,0x50,0xfc,0x20,0xf8,0x20,0x20,0xe0,0x88,0xfc,0x0,0x0,
-+0x0,0x8,0x7d,0x49,0x49,0x49,0x4f,0x48,0x4a,0x4a,0x4a,0x4a,0x7b,0x4a,0x3,0x2,0x40,0x48,0x7c,0x40,0x40,0x44,0xfe,0x0,0x44,0x44,0x44,0xb4,0x14,0x4,0xfc,0x4,
-+0x23,0x21,0x39,0x41,0x81,0x79,0x27,0x20,0xff,0x24,0x22,0x22,0x29,0x32,0x22,0xc,0xfc,0x8,0xf8,0x8,0xf8,0x8,0xfe,0x8,0xfe,0x62,0x94,0x94,0x8,0x98,0xa4,0x42,
-+0x20,0x21,0x3b,0x42,0x83,0x7a,0x23,0x22,0xfb,0x20,0x2f,0x20,0x29,0x32,0x24,0x0,0x80,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x44,0xfe,0xe0,0x50,0x4e,0x44,0x40,
-+0x40,0x37,0x14,0x4,0x87,0x64,0x24,0xf,0x10,0x20,0xe7,0x20,0x20,0x20,0x2f,0x20,0x4,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x0,
-+0x9,0x9,0x13,0x12,0x34,0x59,0x91,0x12,0x14,0x11,0x10,0x2,0x51,0x50,0x90,0xf,0x0,0x0,0xfc,0x4,0x48,0x40,0x50,0x4c,0x44,0x40,0x80,0x0,0x84,0x92,0x12,0xf0,
-+0x10,0x10,0x10,0x13,0xfe,0x14,0x30,0x3b,0x54,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x40,0x20,0x20,0xfe,0x2,0x4,0x0,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x0,0x44,0x2c,0x13,0x2a,0x4c,0x88,0xb,0x18,0x28,0x48,0x88,0x8,0x8,0x50,0x20,0x40,0x20,0x20,0xfe,0x2,0x4,0x0,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x8,0x89,0x6e,0x28,0x8,0x7,0x28,0x2f,0x32,0xc2,0x5f,0x42,0x45,0x44,0x48,0x11,0x0,0x7c,0x4,0x28,0x90,0x88,0x7e,0x82,0x14,0x50,0xdc,0x50,0x70,0xd0,0x8e,0x4,
-+0x2,0x1,0x7f,0x40,0x80,0x0,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x5,0x2,0x0,0x0,0xfe,0x2,0x4,0x0,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x10,0x10,0x13,0xfa,0x14,0x10,0x1b,0x30,0xd0,0x10,0x10,0x10,0x10,0x50,0x20,0x40,0x20,0x20,0xfe,0x2,0x4,0x0,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x40,0x30,0x10,0x7,0x84,0x68,0x20,0xf,0x10,0x20,0xe0,0x20,0x20,0x20,0x21,0x20,0x80,0x40,0x40,0xfe,0x2,0x4,0x0,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,
-+0x1,0x11,0x11,0x1f,0x21,0x21,0x41,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x13,0x10,0x10,0xfc,0x10,0x14,0x1b,0x30,0xd0,0x10,0x10,0x10,0x10,0x57,0x20,0x8,0xfc,0x88,0x88,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x88,0x88,0x88,0xfe,0x0,
-+0x20,0x27,0x39,0x41,0x81,0x79,0x21,0x27,0xf9,0x21,0x21,0x29,0x31,0x21,0xf,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0x8,0x8,0xfe,0x0,
-+0x10,0x17,0x21,0x21,0x49,0xf9,0x11,0x27,0x41,0xf9,0x1,0x1,0x19,0xe1,0x47,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0x8,0x8,0xfe,0x0,
-+0x8,0x7c,0x4b,0x4a,0x4c,0x78,0x48,0x49,0x4b,0x7d,0x49,0x49,0x49,0x49,0x49,0x99,0x40,0x40,0xfc,0x44,0x48,0x80,0x84,0x4c,0x50,0x20,0x20,0x10,0xe,0x44,0x80,0x0,
-+0x40,0x30,0x17,0x4,0x88,0x60,0x20,0x9,0x13,0x25,0xe9,0x21,0x21,0x21,0x21,0x21,0x40,0x40,0xfc,0x44,0x48,0x80,0x84,0x4c,0x50,0x20,0x20,0x10,0xe,0x44,0x80,0x0,
-+0x1,0x1,0x7f,0x41,0x81,0x2,0x2,0x5,0x9,0x18,0x28,0x48,0x88,0xa,0xc,0x8,0x0,0x0,0xfe,0x2,0x4,0x0,0x8,0x18,0x20,0xc0,0x80,0x40,0x30,0xe,0x4,0x0,
-+0x0,0x7f,0x1,0x1,0x3f,0x1,0x1,0x7f,0x4,0x4,0xff,0x4,0x8,0x8,0x10,0x60,0x8,0xfc,0x0,0x10,0xf8,0x0,0x8,0xfc,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x10,0x10,0x11,0x10,0xfe,0x22,0x22,0x22,0x42,0x24,0x14,0x8,0x14,0x22,0x41,0x6,0x0,0x0,0xfc,0x4,0x84,0x84,0x88,0x88,0x48,0x50,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x10,0x10,0xfe,0x22,0x24,0x64,0x18,0x14,0x62,0x2,0x3f,0x2,0x4,0x4,0x18,0x60,0x0,0x0,0xfc,0x84,0x48,0x30,0x20,0x50,0x8e,0x4,0xf0,0x10,0x10,0x10,0x50,0x20,
-+0x10,0x10,0xfe,0x22,0x24,0x64,0x18,0x14,0x62,0x0,0x12,0x51,0x50,0x90,0xf,0x0,0x0,0x0,0xfc,0x84,0x48,0x30,0x20,0x50,0x8e,0x4,0x0,0x84,0x92,0x12,0xf0,0x0,
-+0x2,0x2,0x2,0x2,0x2,0xff,0x4,0x4,0x8,0x10,0xc,0x2,0x1,0x6,0x18,0x60,0x0,0x0,0x0,0x0,0x4,0xfe,0x20,0x20,0x20,0x20,0x40,0x80,0x80,0x60,0x18,0x8,
-+0x0,0xb,0x7c,0x4a,0x49,0x4b,0x48,0x7f,0x48,0x48,0x49,0x49,0x7a,0x44,0x8,0x3,0xc,0xf0,0x84,0x4c,0x50,0xfc,0x80,0xfe,0x80,0xf8,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x1,0x1,0x1,0x3f,0x21,0x21,0x3f,0x21,0x20,0x20,0x27,0x24,0x3f,0x24,0x47,0x80,0x10,0xf8,0x0,0xfc,0x4,0xe8,0x0,0x8,0xf8,0x0,0xf0,0x4,0xfe,0x0,0xf8,0x0,
-+0x1,0x0,0x1f,0x10,0x90,0x53,0x52,0x12,0x32,0x5f,0xd2,0x12,0x22,0x22,0x43,0x0,0x0,0x84,0xfe,0x0,0x8,0xfc,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x8,0xfc,0x0,
-+0x10,0x17,0x12,0x12,0xfa,0x17,0x12,0x1a,0x32,0xd7,0x12,0x12,0x14,0x19,0x50,0x20,0x0,0xde,0x52,0x54,0x54,0xd4,0x58,0x58,0x54,0xd2,0x52,0x52,0x5a,0x54,0x90,0x10,
-+0x20,0x27,0x20,0x2f,0xba,0xa9,0xa2,0x20,0x2f,0x20,0x27,0x24,0x24,0x24,0x24,0x24,0x8,0xfc,0x40,0xfe,0x4a,0x50,0x48,0x40,0xfc,0x80,0xfc,0xa4,0xa4,0xa4,0xa4,0xc,
-+0x10,0x11,0x54,0x3b,0x12,0xfc,0x10,0x30,0x3b,0x54,0x53,0x92,0x12,0x12,0x12,0x12,0x8,0xfc,0x20,0xfe,0xaa,0x70,0xa8,0x20,0xfe,0x40,0xfe,0x52,0x52,0x52,0x52,0x6,
-+0x1,0x41,0x37,0x11,0x1,0x0,0xef,0x20,0x21,0x23,0x2d,0x21,0x29,0x31,0x21,0x1,0x10,0x10,0xfc,0x10,0x50,0x44,0xfe,0x80,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x8,0x7f,0x49,0x49,0x4f,0x49,0x49,0x49,0x49,0x4f,0x49,0x79,0x41,0x5,0x2,0x20,0xb0,0x28,0x20,0x24,0xfe,0x20,0x20,0x20,0xd4,0x18,0x10,0x30,0x4a,0x8a,0x6,
-+0x4,0x7e,0x40,0x42,0x62,0x55,0x54,0x48,0x54,0x52,0x62,0x40,0x44,0x7e,0x1,0x2,0x40,0x40,0x40,0x7e,0x82,0x24,0x20,0x20,0x20,0x20,0x50,0x50,0x88,0x8e,0x4,0x0,
-+0x4,0x7e,0x40,0x42,0x62,0x54,0x54,0x48,0x54,0x52,0x62,0x40,0x45,0x7e,0x0,0x0,0x10,0x24,0xfe,0x84,0xa4,0x84,0x94,0x88,0x80,0xfe,0x2,0x12,0xfa,0x2,0x14,0x8,
-+0x4,0x7e,0x40,0x42,0x62,0x54,0x55,0x48,0x55,0x52,0x62,0x40,0x44,0x7e,0x0,0x3,0x8,0xfc,0x88,0x88,0x88,0x88,0x6,0x0,0xfc,0x4,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x4,0x4,0xff,0x14,0x11,0x7d,0x11,0x7d,0x11,0xfc,0x13,0x3a,0x56,0x92,0x12,0x12,0x40,0x44,0xfe,0x40,0xfc,0x24,0xfc,0x24,0xfc,0x20,0xfe,0x22,0x2a,0xfa,0xa,0x4,
-+0x0,0xb,0x7e,0x4b,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x7b,0x4a,0x3,0x0,0x8,0xfc,0x0,0x8,0x88,0x50,0x50,0x20,0x20,0x50,0x50,0x88,0x8,0x4,0xfe,0x0,
-+0x10,0x17,0x14,0x24,0x27,0x64,0xa4,0x27,0x20,0x2f,0x28,0x28,0x2b,0x28,0x28,0x28,0x4,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x40,0xfe,0x42,0x4a,0xfa,0x2,0xa,0x4,
-+0x0,0x43,0x32,0x13,0x82,0x62,0x22,0xa,0x12,0x22,0xe2,0x22,0x23,0x22,0x23,0x20,0x8,0xfc,0x0,0x8,0x88,0x50,0x50,0x20,0x20,0x50,0x50,0x88,0x8,0x4,0xfe,0x0,
-+0x2,0x12,0x7a,0x5f,0x52,0x52,0x52,0x52,0x53,0x5e,0x52,0x72,0x52,0x2,0xa,0x4,0x10,0x10,0x24,0xfe,0x44,0x44,0x44,0xc4,0x7c,0x44,0x44,0x44,0x44,0x44,0x7c,0x44,
-+0x4,0x7e,0x44,0x44,0x44,0x7c,0x10,0x10,0x5c,0x51,0x51,0x51,0x5e,0xe2,0x44,0x8,0x10,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x10,0x10,0x10,0x8,0xe,0x4,0x0,
-+0x7,0x78,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x52,0x52,0x51,0x90,0x10,0x0,0x4,0xfe,0x24,0x24,0x24,0x24,0xfc,0x0,0x2,0x2,0xfe,0x0,0x6,0xfc,0x0,
-+0x10,0x10,0x10,0x7d,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x5d,0x11,0x11,0x11,0x20,0x20,0x44,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x11,0x59,0x55,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x20,0x20,0x44,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x4,0x7e,0x8,0x3e,0x8,0x7e,0x0,0x3f,0x21,0x21,0x3f,0x20,0x20,0x20,0x1f,0x0,0x8,0xfc,0x20,0xf8,0x20,0xfc,0x8,0xfc,0x8,0x8,0xf8,0x8,0x2,0x2,0xfe,0x0,
-+0x10,0x10,0x10,0x11,0xfd,0x11,0x15,0x19,0x31,0xd1,0x11,0x11,0x11,0x11,0x51,0x21,0x20,0x20,0x44,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x17,0xfc,0x10,0x14,0x1b,0x30,0xd0,0x10,0x1f,0x10,0x10,0x50,0x20,0xa0,0xa0,0xa4,0xbe,0xa0,0xa0,0xa8,0xbc,0xa0,0xa0,0xa4,0xbe,0xa0,0xa0,0xa0,0xa0,
-+0x8,0x48,0x49,0x49,0x49,0x7d,0x41,0x41,0x79,0x48,0x49,0x4f,0x48,0x48,0x88,0x8,0x40,0x84,0xfe,0x24,0x24,0xfc,0x24,0x44,0xfc,0xa0,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x8,0x8,0x10,0x2f,0x40,0x88,0x8,0x17,0x30,0x50,0x90,0x1f,0x10,0x10,0x10,0x10,0xa0,0xa0,0xa4,0xbe,0xa0,0xa0,0xa8,0xbc,0xa0,0xa0,0xa4,0xbe,0xa0,0xa0,0xa0,0xa0,
-+0x40,0x3f,0x12,0x2,0x82,0x6f,0x22,0xa,0x12,0x22,0xef,0x22,0x22,0x24,0x24,0x28,0x88,0x7c,0x10,0x10,0x7c,0x90,0x10,0x7c,0x10,0x10,0x94,0xfe,0x10,0x10,0x10,0x10,
-+0x40,0x37,0x14,0x4,0x85,0x65,0x25,0xd,0x15,0x25,0xe5,0x25,0x25,0x29,0x29,0x11,0x1c,0xe0,0x8,0x3c,0xc0,0x40,0x40,0x24,0x2c,0x30,0x20,0x10,0x10,0x4e,0x84,0x0,
-+0x22,0x21,0xfa,0x22,0x71,0xaa,0x22,0xff,0x4,0xf,0x31,0xcf,0x1,0x3f,0x1,0x3,0x88,0x8,0xbe,0x88,0x1c,0xaa,0x8,0xfe,0x40,0xe0,0x18,0xe6,0x0,0xf8,0x0,0x0,
-+0x0,0x47,0x32,0x11,0x8f,0x61,0x22,0xc,0x17,0x24,0xe4,0x27,0x24,0x24,0x27,0x24,0x3c,0xc0,0x48,0x50,0xfe,0x50,0x48,0x44,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x4,
-+0x2,0x1f,0x10,0x12,0x11,0xff,0x10,0x12,0x21,0x40,0x3f,0x24,0x24,0x24,0xff,0x0,0x10,0xf8,0x10,0x10,0x14,0xfe,0x10,0x10,0x50,0x20,0xf8,0x48,0x48,0x48,0xfe,0x0,
-+0x10,0x3e,0x22,0x2a,0xff,0x22,0x2a,0x22,0x46,0xff,0x4,0xf,0x18,0x68,0xf,0x8,0x78,0x48,0x48,0x86,0x78,0x48,0x30,0x4e,0x84,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x10,
-+0x0,0x8,0x7c,0x49,0x49,0x7a,0x4a,0x4d,0x48,0x78,0x48,0x48,0x49,0x79,0x42,0x4,0x20,0xa0,0xa0,0x10,0x10,0x8,0xe,0xf4,0x90,0x90,0x90,0x90,0x10,0x10,0x50,0x20,
-+0x0,0x4,0x7f,0x54,0x54,0x54,0x55,0x7c,0x54,0x54,0x57,0x54,0x7c,0x44,0x0,0x0,0x20,0x20,0x24,0xa8,0xa8,0x20,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x4,0x44,0x34,0x15,0x4,0x7f,0x4,0x4,0x5,0xff,0x4,0x8,0x8,0x10,0x20,0x0,0x4,0x44,0xc4,0x24,0x24,0xa4,0x24,0x24,0x24,0xa4,0x24,0x24,0x4,0x4,0x14,0x8,
-+0x10,0x10,0x93,0x55,0x39,0x11,0x7d,0x11,0x11,0xfd,0x11,0x11,0x22,0x22,0x44,0x89,0x8,0x1c,0xe0,0x0,0x0,0x0,0xf8,0x8,0x88,0x48,0x50,0x20,0x50,0x48,0x8e,0x4,
-+0x0,0xf,0x8,0x8,0x8,0xf,0x8,0x8,0x8,0x8,0xff,0x0,0x0,0x0,0x0,0x0,0x30,0xc0,0x0,0x0,0x10,0xf8,0x20,0x20,0x20,0x24,0xfe,0x0,0x40,0x30,0x18,0x8,
-+0x2,0x1,0x7f,0x42,0x42,0x42,0x7f,0x42,0x42,0x44,0x44,0x44,0x48,0x4b,0x90,0x20,0x0,0x4,0xfe,0x0,0x40,0x28,0xfc,0x80,0x80,0x88,0x90,0xa0,0xc2,0x82,0x82,0x7e,
-+0x2,0x1,0x7f,0x8,0x4,0x7f,0x42,0x81,0x7f,0x4,0x7,0x4,0x8,0x8,0x10,0x60,0x0,0x8,0xfc,0x20,0x40,0xfe,0x2,0x4,0xfc,0x0,0xf0,0x10,0x10,0x10,0xa0,0x40,
-+0x10,0x10,0x13,0xfc,0x10,0x7f,0x12,0xfc,0x13,0x38,0x34,0x50,0x90,0x11,0x12,0x14,0x40,0x24,0xfe,0x88,0x50,0xfe,0x42,0x24,0xfe,0x80,0xf8,0x88,0x88,0x8,0x28,0x10,
-+0x0,0x78,0x4c,0x4a,0x49,0x78,0x4f,0x48,0x48,0x78,0x4f,0x48,0x48,0x48,0x48,0x98,0x40,0x40,0x44,0x48,0x50,0x40,0xfc,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x12,0x12,0x12,0x12,0xfe,0x17,0x12,0x1a,0x32,0xd2,0x12,0x12,0x12,0x12,0x54,0x28,0x20,0x20,0x20,0x24,0x7e,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xd4,0x8a,0x82,0x7e,0x0,
-+0x0,0x8,0x7c,0x49,0x49,0x4b,0x4d,0x49,0x49,0x49,0x49,0x79,0x49,0x1,0x0,0x0,0x80,0x84,0xfe,0x4,0x24,0xf4,0x24,0x24,0x24,0xe4,0x14,0x8,0x2,0x2,0xfe,0x0,
-+0x10,0x11,0x1f,0x21,0x21,0x7d,0xa5,0x25,0x25,0x3d,0x25,0x22,0x20,0x20,0x1f,0x0,0x4,0x4,0xa4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x84,0x84,0x94,0x8,
-+0x10,0x10,0x10,0x15,0x59,0x53,0x55,0x91,0x11,0x11,0x11,0x29,0x25,0x45,0x80,0x0,0x80,0x84,0xfe,0x4,0x24,0xf4,0x24,0x24,0x24,0xe4,0x14,0x8,0x2,0x2,0xfe,0x0,
-+0x20,0x10,0x10,0x1,0xf9,0xb,0x11,0x35,0x59,0x95,0x11,0x11,0x11,0x11,0x10,0x10,0x80,0x84,0xfe,0x4,0x24,0xf4,0x24,0x24,0x24,0xe4,0x14,0x8,0x2,0x2,0xfe,0x0,
-+0x4,0x7e,0x44,0x45,0x45,0x7f,0x15,0x11,0x5d,0x51,0x51,0x51,0x5d,0xe1,0x40,0x0,0x80,0x84,0xfe,0x4,0x24,0xf4,0x24,0x24,0x24,0xe4,0x14,0x8,0x2,0x2,0xfe,0x0,
-+0x1,0x41,0x31,0x12,0x82,0x67,0x2a,0x2,0xa,0x13,0xe2,0x22,0x22,0x22,0x21,0x20,0x0,0x4,0xfe,0x4,0x24,0xf4,0x24,0x24,0x24,0xe4,0x14,0x8,0x2,0x2,0xfe,0x0,
-+0x0,0x7,0x78,0x48,0x48,0x48,0x48,0x49,0x49,0x4a,0x4c,0x78,0x48,0x0,0xf,0x0,0x8,0xfc,0x20,0x20,0x40,0xc0,0xc0,0x50,0x4c,0x46,0x42,0x40,0x40,0x44,0xfe,0x0,
-+0x8,0x7f,0x48,0x48,0x48,0x78,0x48,0x49,0x49,0x7a,0x4c,0x48,0x48,0x48,0x4f,0x98,0x8,0xfc,0x20,0x20,0x40,0xc0,0xc0,0x50,0x4c,0x46,0x42,0x40,0x40,0x44,0xfe,0x0,
-+0x20,0x20,0x27,0x20,0x21,0xf8,0x20,0x2f,0x20,0x23,0x22,0x22,0x3a,0xe2,0x43,0x2,0x80,0x48,0xfc,0x0,0x10,0xa0,0x4,0xfe,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x2,0x2,0x7e,0x2,0x3e,0x2,0x7e,0x2,0x1,0xff,0x2,0x4,0xc,0x35,0xc6,0x4,0x80,0x88,0xfc,0x80,0xf8,0x80,0xfc,0x80,0x4,0xfe,0x80,0x88,0x50,0x30,0xe,0x4,
-+0x0,0x7c,0x45,0x54,0x54,0x54,0x54,0x57,0x54,0x55,0x55,0x55,0x11,0x29,0x45,0x81,0x40,0x20,0xfc,0x0,0x88,0x50,0x4,0xfe,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x78,0x4f,0x50,0x51,0x50,0x60,0x57,0x48,0x4b,0x6a,0x52,0x42,0x42,0x43,0x42,0x80,0x48,0xfc,0x0,0x10,0xa0,0x4,0xfe,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x1,0xff,0x14,0x14,0x7f,0x55,0x55,0x55,0x55,0x63,0x41,0x7f,0x41,0x41,0x7f,0x41,0x4,0xfe,0x4,0x4,0x4,0x4,0x7c,0x44,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x10,0x1f,0x28,0x2f,0x68,0xa8,0x2b,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x28,0x30,0x20,0x8,0xfc,0x8,0xf8,0x88,0xa8,0xf8,0xa8,0xa8,0xa8,0xa8,0xa8,0xea,0x8a,0x86,0x80,
-+0x0,0x40,0x20,0x2f,0x80,0x60,0x27,0xc,0x14,0x24,0xe4,0x24,0x24,0x20,0x20,0x20,0x40,0x40,0x44,0xfe,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0x54,0x48,0x40,0x40,0x40,
-+0x0,0xb,0x7c,0x49,0x4f,0x49,0x48,0x4b,0x4a,0x4a,0x4a,0x7a,0x4a,0x0,0x1,0x6,0x48,0xfc,0x40,0x14,0xfe,0x10,0x8,0xfc,0x8,0x48,0x48,0x48,0x48,0x90,0xc,0x4,
-+0x0,0x4,0x8,0x10,0x2f,0xc4,0x4,0x9,0x30,0x0,0x3f,0x24,0x24,0x24,0xff,0x0,0x80,0x80,0x40,0x20,0xd0,0x4e,0x44,0x40,0x80,0x8,0xfc,0x48,0x48,0x48,0xfe,0x0,
-+0x4,0xff,0x10,0x10,0x21,0x24,0x3e,0x64,0xa7,0x24,0x24,0x24,0x24,0x3c,0x24,0x0,0x8,0xfc,0x20,0x20,0x24,0xa8,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x10,0x11,0x10,0x10,0xfd,0x10,0x14,0x18,0x33,0xd0,0x10,0x10,0x10,0x10,0x50,0x20,0x8,0xfc,0x20,0x20,0x24,0xa8,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x1,0xff,0x0,0x1f,0x10,0x10,0x1f,0x0,0x3f,0x0,0x1,0x5,0x3,0x48,0x44,0x84,0x4,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x0,0xf0,0x40,0x80,0x0,0x0,0x48,0x24,0x24,
-+0x41,0x21,0x2f,0x1,0x87,0x60,0x27,0xc,0x14,0x27,0xe0,0x24,0x22,0x20,0x2f,0x0,0x0,0x42,0xe6,0x8,0xd0,0x2,0xc6,0x48,0x50,0xc0,0x2,0x46,0x88,0xf0,0x20,0x40,
-+0x8,0x9,0xff,0x8,0x7f,0x0,0x7f,0x41,0x41,0x7f,0x0,0x22,0x14,0xf,0xf0,0x40,0x4,0xc,0x90,0x20,0x40,0x4,0xc,0x10,0x20,0x42,0x6,0x8,0x10,0x20,0x40,0x80,
-+0x4,0xff,0x5,0x41,0x33,0x14,0x1,0xf6,0x1b,0x10,0x13,0x10,0x17,0x10,0x28,0x47,0x44,0xfe,0x40,0xf8,0x10,0xe0,0x18,0x46,0xf8,0x40,0xf8,0x40,0xfc,0x40,0x46,0xfc,
-+0x20,0x27,0x24,0x24,0xfc,0x27,0x64,0x74,0xac,0x27,0x24,0x24,0x24,0x24,0x25,0x28,0x4,0xbe,0xa4,0xa4,0xa4,0xbc,0xa4,0xa4,0xa4,0xbc,0xa4,0xa4,0xa4,0xa4,0xa4,0x4c,
-+0x10,0xff,0x24,0x24,0x44,0x47,0x74,0xd4,0x54,0x57,0x54,0x54,0x54,0x74,0x45,0x8,0x4,0xbe,0xa4,0xa4,0xa4,0xbc,0xa4,0xa4,0xa4,0xbc,0xa4,0xa4,0xa4,0xa4,0xa4,0x4c,
-+0x10,0x3e,0x49,0x81,0x43,0x24,0x1,0xf6,0x1b,0x10,0x13,0x10,0x17,0x10,0x28,0x47,0x40,0xfc,0x20,0xf8,0x10,0xe0,0x18,0x46,0xf8,0x40,0xf8,0x40,0xfc,0x40,0x46,0xfc,
-+0x0,0x78,0x4f,0x48,0x4b,0x78,0x4b,0x4a,0x4a,0x7b,0x48,0x4a,0x49,0x4f,0x48,0x98,0x80,0xa2,0xf2,0x84,0xe8,0x12,0xe2,0x24,0x28,0xf0,0x2,0x22,0x44,0xe8,0x10,0x60,
-+0x2,0x3f,0x22,0x22,0x22,0x3e,0x22,0x22,0x22,0x3e,0x22,0x22,0x22,0x4a,0x44,0x81,0x4,0x7e,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x84,0x94,0x8,
-+0x0,0x77,0x55,0x55,0x55,0x77,0x55,0x55,0x55,0x77,0x55,0x55,0x55,0x55,0x8b,0x0,0x10,0x24,0x7e,0x44,0x54,0x44,0x54,0x48,0x40,0x7e,0x2,0xa,0xfe,0x2,0xa,0x4,
-+0x10,0x10,0x17,0xfc,0x13,0x10,0x17,0x18,0x31,0xd2,0x1d,0x10,0x17,0x10,0x50,0x20,0x40,0x48,0xfc,0x40,0xf8,0x80,0xfe,0xa0,0x50,0x4e,0xf4,0x40,0xfc,0x40,0x40,0x40,
-+0x1,0x8,0xfc,0x20,0x23,0x40,0x48,0x7c,0xca,0x4a,0x4a,0x48,0x48,0x78,0x47,0x0,0x8,0x88,0x90,0x8,0xfc,0x90,0x90,0x92,0x96,0x94,0x98,0x90,0x90,0x94,0xfe,0x0,
-+0x10,0x10,0x13,0x10,0x10,0xfc,0x10,0x10,0x10,0x11,0x12,0x1c,0xf0,0x40,0x7,0x0,0x0,0x4,0xfe,0x10,0x10,0x20,0x20,0x68,0xa4,0x22,0x22,0x20,0x20,0x24,0xfe,0x0,
-+0x0,0x5,0xff,0x11,0x11,0x21,0x25,0x3f,0x65,0xa5,0x25,0x25,0x25,0x3d,0x25,0x0,0x10,0x10,0x10,0x10,0x12,0x16,0xd8,0x10,0x10,0x10,0x10,0x10,0x12,0x52,0x8e,0x0,
-+0x1f,0x1,0x7f,0x51,0x8d,0x11,0x3e,0x23,0x22,0x3e,0x21,0x3e,0x62,0xa2,0x3e,0x20,0xf0,0x0,0xfe,0x12,0x64,0x10,0x20,0xfc,0x88,0x50,0xfe,0x20,0xfc,0x20,0x20,0x20,
-+0x12,0x12,0x12,0x12,0xfe,0x12,0x13,0x1a,0x32,0xd2,0x12,0x12,0x12,0x13,0x52,0x20,0x20,0x20,0x20,0x20,0x24,0x2c,0xb0,0x20,0x20,0x20,0x20,0x20,0xa4,0x24,0x1c,0x0,
-+0x10,0x10,0x10,0x13,0xfe,0x12,0x16,0x1b,0x32,0xd2,0x12,0x12,0x12,0x14,0x54,0x29,0x20,0x20,0x20,0xfe,0x22,0x24,0x20,0xf8,0x88,0x88,0x50,0x20,0x50,0x48,0x8e,0x4,
-+0x0,0x3e,0x23,0x22,0x3e,0x21,0x3e,0x62,0xa2,0x3e,0x0,0x7f,0x4,0x4,0x8,0x30,0x40,0x20,0xfc,0x88,0x50,0xfe,0x20,0xf8,0x20,0x20,0x8,0xfc,0x8,0x8,0x50,0x20,
-+0x4,0x7e,0x8,0x8,0x3e,0x8,0x8,0x7e,0x0,0x20,0x24,0x3e,0x20,0x20,0x2e,0x30,0x8,0xfc,0x20,0x20,0xf8,0x20,0x28,0xfc,0x0,0x80,0x98,0xe0,0x80,0x82,0x82,0x7e,
-+0x0,0x5,0x7f,0x55,0x55,0x55,0x55,0x7d,0x55,0x55,0x55,0x55,0x7d,0x45,0x1,0x0,0x10,0x10,0x10,0x10,0x10,0x12,0xdc,0x10,0x10,0x10,0x10,0x10,0x52,0x92,0xe,0x0,
-+0x0,0x8,0x7f,0x4a,0x4a,0x4b,0x4a,0x4a,0x4b,0x48,0x49,0x4f,0x78,0x48,0x0,0x0,0x40,0x88,0xfc,0x48,0x48,0xf8,0x48,0x88,0xf8,0x80,0x44,0xfe,0x40,0x40,0x40,0x40,
-+0x4,0x3e,0x25,0x25,0x25,0x3d,0x25,0x25,0x25,0x3c,0x24,0x27,0x24,0x24,0x54,0x88,0x20,0x44,0xfe,0x24,0x24,0xfc,0x24,0x44,0xfc,0x40,0xa4,0xfe,0x20,0x20,0x20,0x20,
-+0x1,0x0,0x1f,0x90,0x50,0x57,0x14,0x14,0x37,0x54,0xd5,0x14,0x24,0x24,0x49,0x12,0x0,0x84,0xfe,0x40,0x40,0xfc,0x44,0x40,0xf8,0x8,0x10,0xa0,0x40,0xb0,0xe,0x4,
-+0x0,0x0,0x0,0x3f,0x20,0x20,0x20,0x2f,0x20,0x24,0x22,0x21,0x20,0x41,0x46,0x98,0x80,0x80,0x80,0xfc,0x84,0x88,0x80,0xf8,0x8,0x10,0x20,0x40,0x80,0x60,0x1e,0x4,
-+0x0,0x0,0x7f,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x48,0x50,0x40,0x7f,0x0,0x0,0x8,0xfc,0x40,0x40,0x40,0x40,0x40,0x40,0x44,0x44,0x3c,0x0,0x4,0xfe,0x0,
-+0x1,0x0,0x1f,0x90,0x57,0x50,0x10,0x10,0x31,0x56,0xdb,0x12,0x22,0x22,0x43,0x2,0x0,0x84,0xfe,0x8,0xfc,0x20,0x40,0xd8,0x46,0x42,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x1f,0x29,0x29,0x69,0xaf,0x28,0x28,0x2f,0x29,0x39,0x29,0x2f,0x28,0x20,0x20,0x10,0x14,0xfe,0x44,0x28,0x10,0xfe,0x10,0x10,0xfe,0x10,0x10,0x10,0x10,0x10,
-+0x0,0x3f,0x20,0x20,0x3f,0x20,0x28,0x28,0x2a,0x2f,0x28,0x28,0x29,0x4e,0x48,0x80,0x8,0xfc,0x8,0x8,0xf8,0x48,0x40,0x40,0x4c,0x70,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x3f,0x21,0x3f,0x20,0x7f,0xa1,0x3f,0x21,0x7f,0x0,0x3f,0x0,0x0,0x1f,0x10,0x1f,0x10,0x7c,0x28,0xfe,0x10,0x7c,0x10,0x14,0xfe,0x0,0x0,0xf8,0x0,0xf0,0x10,0xf0,
-+0x12,0x1f,0x28,0x45,0x80,0x3f,0x20,0x3f,0x20,0x3f,0x32,0x52,0x5f,0x52,0x92,0x10,0x44,0x7e,0xa0,0x10,0x80,0xf8,0x8,0xf8,0x4,0xfe,0x24,0x24,0xfc,0x24,0x34,0x8,
-+0x10,0x10,0x17,0x24,0x24,0x67,0xa4,0x24,0x27,0x26,0x2a,0x2b,0x2a,0x32,0x22,0x22,0x80,0x44,0xfe,0x4,0x4,0xfc,0x0,0x4,0xfe,0x94,0x94,0xfc,0x94,0x94,0x94,0xc,
-+0x0,0x20,0x20,0x20,0x20,0x3f,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x20,0x40,0x80,0x80,0x80,0x80,0x80,0x84,0xfe,0x0,0x0,0xc0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x10,0xf8,0x13,0x52,0x52,0x53,0x52,0x52,0x7b,0xa,0xa,0x3b,0xce,0xa,0x2a,0x12,0x40,0x28,0xfc,0x8,0x8,0xf8,0x0,0x4,0xfe,0x94,0x94,0xfc,0x94,0x94,0x94,0xc,
-+0x4,0xfe,0x28,0xfe,0xaa,0xaa,0xfe,0x0,0x7c,0x0,0xfe,0x10,0x58,0x55,0x92,0x34,0x8,0xfc,0x88,0x88,0x88,0xd8,0xd8,0xa8,0xa8,0xd8,0xd8,0x88,0x8a,0xa,0x6,0x0,
-+0x40,0x3f,0x10,0x7,0x84,0x64,0x27,0x8,0x13,0x20,0xef,0x20,0x22,0x24,0x29,0x20,0x4,0xfe,0xa0,0xfc,0xa4,0xa4,0xfc,0x0,0xf8,0x0,0xfe,0x40,0x50,0x4c,0x44,0x80,
-+0x4,0xfe,0x28,0xfe,0xaa,0xaa,0xfe,0x0,0x7c,0x0,0xfe,0x10,0x59,0x55,0x92,0x30,0x4,0xf8,0x80,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa4,0x24,0x52,0x78,0x0,
-+0x0,0x7f,0x4,0x3f,0x24,0x24,0x3f,0x0,0x1f,0x0,0xff,0x1,0x11,0x21,0x45,0x2,0x8,0xfc,0x40,0xf8,0x48,0x48,0xf8,0x0,0xf0,0x4,0xfe,0x0,0x20,0x18,0x8,0x0,
-+0x22,0x22,0x2a,0x27,0xf2,0x2f,0x2a,0x2a,0x3a,0xef,0x2e,0x2a,0x2a,0x29,0xa8,0x40,0x10,0x10,0x90,0x24,0x3e,0xc4,0xa4,0xa4,0xa8,0xa8,0x90,0x90,0xa8,0xa8,0x46,0x84,
-+0x8,0x49,0x2a,0x7f,0x49,0x5d,0x6b,0x49,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x20,0x20,0x7e,0xc4,0x28,0x10,0x2e,0x44,0xf0,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x10,
-+0x12,0x11,0x10,0x13,0xfd,0x11,0x15,0x19,0x37,0xd1,0x11,0x11,0x11,0x11,0x52,0x24,0x8,0x18,0xa0,0xfc,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x10,0x13,0x54,0x5e,0x51,0x55,0xff,0x11,0x55,0x55,0x55,0x95,0x8,0x10,0x20,0x43,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x20,0x50,0x8c,0x4,
-+0x0,0x4,0x8,0x1f,0x24,0xc4,0x9,0x30,0x1f,0x10,0x11,0x11,0x11,0x2,0xc,0x30,0x40,0x40,0x20,0xd0,0x4e,0x44,0x40,0x90,0xf8,0x10,0x10,0x10,0x10,0xc0,0x30,0x8,
-+0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x2,0x7f,0x42,0x42,0x42,0x42,0x42,0x7e,0x42,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,0x4,0xfe,0x84,0x84,0x84,0x84,0x84,0xfc,0x84,
-+0x8,0xfc,0x4b,0x4a,0x7b,0x4a,0x4b,0x78,0x4f,0x48,0x5c,0xe9,0x48,0x8,0x8,0x8,0x40,0x48,0xfc,0x48,0xf8,0x48,0xf8,0x0,0xfe,0x80,0x80,0xf8,0x8,0x8,0x50,0x20,
-+0x0,0xf,0x8,0x8,0x8,0xf,0x8,0x8,0x8,0x8,0xff,0x0,0x2,0x6,0x8,0x10,0x30,0xc0,0x0,0x0,0x8,0xfc,0x20,0x20,0x20,0x24,0xfe,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x17,0x10,0x10,0x12,0xfd,0x11,0x11,0x10,0x1f,0x10,0x1c,0xe0,0x40,0x0,0x0,0x8,0xfc,0x40,0x40,0x48,0x48,0x50,0x50,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x4,0x4,0xff,0x4,0x0,0x7f,0x1,0x11,0x9,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x40,0x44,0xfe,0x40,0x8,0xfc,0x0,0x10,0x20,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x20,0x17,0x80,0x4a,0x11,0x20,0xef,0x20,0x20,0x20,0x20,0x20,0x40,0x44,0xfe,0x40,0x8,0xfc,0x40,0x48,0x50,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x7f,0x1,0x11,0x11,0x9,0x9,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x8,0xfc,0x0,0x10,0x10,0x20,0x20,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x8,0xb,0x10,0x10,0x37,0x50,0x90,0x13,0x10,0x7,0x4,0x4,0x4,0x4,0x8,0x30,0x30,0xc0,0x40,0x48,0xfc,0x40,0x50,0xf8,0x20,0xf0,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x42,0x25,0x28,0xfe,0x24,0x24,0x24,0x24,0xff,0x24,0x24,0x25,0x25,0x45,0x85,0x4,0x4,0xfe,0x80,0x88,0xfc,0x88,0x88,0xc8,0xa8,0xa8,0x88,0x8,0x28,0xca,0xa,0x6,
-+0x0,0x47,0x30,0x10,0x4,0x3,0xf1,0x10,0x1f,0x10,0x10,0x10,0x14,0x18,0x10,0x0,0x8,0xfc,0x40,0x40,0x44,0x4c,0x50,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x3f,0x20,0x20,0x3f,0x22,0x21,0x2f,0x22,0x22,0x3f,0x22,0x22,0x42,0x84,0x8,0x8,0xfc,0x8,0x8,0xf8,0x20,0x48,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x10,0x10,0x10,0x13,0xfe,0x12,0x12,0x13,0x12,0x12,0x1e,0xe2,0x42,0x4,0x8,0x13,0x20,0x20,0x20,0xfe,0x22,0x24,0x20,0xfc,0x84,0x88,0x48,0x50,0x20,0x50,0x8e,0x4,
-+0x0,0x42,0x32,0x14,0x87,0x60,0x20,0x9,0x11,0x23,0xe2,0x24,0x28,0x20,0x21,0x26,0x40,0x50,0x48,0x40,0xfe,0x80,0x80,0xf8,0x8,0x10,0x90,0xa0,0x40,0xb0,0xe,0x4,
-+0x8,0x9,0x8,0x7f,0x49,0x4a,0x48,0x7e,0x42,0x54,0x54,0x48,0x54,0x52,0xa2,0x1,0x4,0xfe,0x20,0x44,0xfe,0x84,0x94,0x94,0x94,0xa4,0xa4,0xa4,0x20,0x50,0x8c,0x4,
-+0x20,0x1b,0x4a,0x22,0x3,0x12,0x22,0x64,0x28,0x22,0xff,0x8,0x4,0x3,0xc,0x30,0x20,0xfe,0x22,0x24,0xf8,0x88,0x50,0x20,0x50,0x8c,0xfe,0x20,0x40,0x80,0x60,0x10,
-+0x0,0x8,0xfc,0x13,0x12,0x22,0x22,0x7b,0xaa,0x2a,0x2a,0x2a,0x3c,0x24,0x8,0x13,0x20,0x20,0x20,0xfe,0x22,0x24,0x20,0xfc,0x84,0x88,0x48,0x50,0x20,0x50,0x8e,0x4,
-+0x0,0x10,0x23,0x7a,0x4a,0x4b,0x4a,0x7a,0x4b,0x48,0x48,0x49,0x79,0x42,0x4,0x8,0x40,0x88,0xfc,0x48,0x48,0xf8,0x48,0x88,0xf8,0x80,0xd0,0x54,0x7c,0x42,0x42,0x3e,
-+0x0,0x40,0x33,0x12,0x2,0x2,0xf3,0x12,0x12,0x12,0x12,0x13,0x12,0x28,0x47,0x0,0x40,0x88,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0xf8,0x0,0x6,0xfc,0x0,
-+0x10,0x10,0x54,0x39,0x11,0xff,0x11,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x11,0x11,0x20,0x20,0x44,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x8,0x4,0x7f,0x21,0x11,0x12,0xff,0x1,0x3f,0x21,0x21,0x21,0x21,0x3f,0x21,0x0,0x4,0x4,0x84,0x24,0x24,0x24,0xe4,0x24,0xa4,0x24,0x24,0x24,0x4,0x4,0x14,0x8,
-+0x8,0x8,0x8,0xa,0x7f,0x8,0xa,0xc,0x18,0x68,0x8,0x8,0x8,0x8,0x28,0x10,0x40,0x40,0x40,0x40,0x40,0x50,0x4c,0x46,0x42,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x10,0x10,0x1c,0x23,0x20,0x7d,0x91,0x11,0x7d,0x11,0x11,0x11,0x15,0x19,0x11,0x1,0x20,0x28,0x24,0xfe,0x20,0xfc,0x24,0x24,0xfc,0x24,0x24,0xfc,0x24,0x24,0x34,0x28,
-+0x4,0x4,0x4,0x8,0x8,0x10,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x80,0x80,0x80,0x80,0x80,0xa0,0x98,0x8c,0x84,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x4,0x4,0x7f,0x4,0x5,0x1,0xff,0x1,0x1f,0x11,0x1f,0x11,0x1f,0x11,0x11,0x11,0x40,0x48,0xfc,0x40,0x50,0x8,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0x50,0x20,
-+0x8,0x8,0xff,0x8,0x1f,0x21,0x7f,0x81,0x1f,0x11,0x1f,0x11,0x1f,0x11,0x11,0x11,0x20,0x24,0xfe,0x20,0xfc,0x44,0xfc,0x4,0xf4,0x14,0xf4,0x14,0xf4,0x14,0x34,0xc,
-+0x4,0x4,0xff,0x4,0x1,0x3f,0x8,0x4,0xff,0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x40,0x44,0xfe,0x40,0x10,0xf8,0x20,0x44,0xfe,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,
-+0x4,0x4,0xff,0x4,0x40,0x2f,0x0,0x87,0x54,0x17,0x24,0xe7,0x24,0x24,0x24,0x24,0x40,0x44,0xfe,0x50,0x48,0xfe,0x44,0xfe,0x44,0xfc,0x44,0xfc,0x44,0x44,0x54,0x48,
-+0x20,0x20,0x20,0x2f,0xf8,0x27,0x24,0x24,0x27,0x24,0x3c,0xe7,0x44,0x4,0x4,0x4,0x40,0x50,0x48,0xfe,0x40,0xfc,0x44,0x44,0xfc,0x44,0x44,0xfc,0x44,0x44,0x54,0x48,
-+0x10,0x10,0x10,0x14,0xfe,0x10,0x30,0x38,0x54,0x54,0x90,0x10,0x10,0x10,0x10,0x10,0x40,0x40,0x40,0x40,0x40,0x60,0x58,0x4c,0x44,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x7f,0x41,0x41,0x5f,0x41,0x4f,0x49,0x4f,0x49,0x4f,0x49,0x49,0x40,0x7f,0x40,0x4,0xfe,0x4,0x44,0xf4,0x4,0xe4,0x24,0xe4,0x24,0xe4,0x24,0x64,0x4,0xfc,0x4,
-+0x8,0x4,0x7f,0x4,0x24,0x14,0x4,0xff,0x0,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x20,0x48,0xfc,0x40,0x48,0x50,0x44,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,
-+0x0,0x40,0x30,0x1f,0x80,0x67,0x24,0x4,0x17,0x24,0xe4,0x27,0x24,0x24,0x24,0x24,0x40,0x50,0x48,0xfe,0x40,0xfc,0x44,0x44,0xfc,0x44,0x44,0xfc,0x44,0x44,0x54,0x48,
-+0x1,0x40,0x27,0x20,0x2,0x1,0xef,0x20,0x23,0x22,0x22,0x23,0x2a,0x32,0x23,0x2,0x10,0xa0,0xfc,0xa0,0xa8,0xb0,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x3,0xa,0x7f,0x4a,0x4b,0x49,0x7b,0x49,0x4f,0x49,0x4a,0x7d,0x48,0x1,0x2,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x10,0xf8,0x10,0xfe,0x10,0x48,0x56,0xe0,0x58,0x48,0xc0,
-+0x3,0x42,0x33,0x12,0x83,0x61,0x27,0x1,0x1f,0x21,0xe2,0x25,0x28,0x21,0x22,0x20,0xf8,0x8,0xf8,0x8,0xf8,0x10,0xfc,0x10,0xfe,0x10,0x48,0x56,0xe0,0x58,0x48,0xc0,
-+0x22,0x22,0x22,0x7f,0x22,0x3e,0x22,0x3e,0x22,0x22,0xff,0x0,0x24,0x22,0x41,0x82,0x4,0x7e,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x7c,0xc4,0x44,0x44,0x84,0x14,0x8,
-+0x22,0x22,0x22,0x7f,0x22,0x3e,0x23,0x3e,0x22,0x22,0xff,0x0,0x24,0x22,0x41,0x82,0x40,0x40,0x40,0x7c,0x44,0x88,0x20,0x20,0x20,0x20,0xd0,0x50,0x50,0x88,0xe,0x4,
-+0x20,0x20,0x2f,0x20,0xf8,0x27,0x64,0x74,0xac,0x24,0x24,0x25,0x26,0x24,0x27,0x24,0x0,0x4,0xfe,0xa0,0xa4,0xfe,0xa4,0xa4,0xa4,0xa4,0xa4,0x1c,0x4,0x4,0xfc,0x4,
-+0x0,0x0,0x0,0x3f,0x22,0x23,0x22,0x22,0x3f,0x22,0x2b,0x2a,0x32,0x42,0x8a,0x4,0x20,0x28,0x24,0xfe,0x20,0xa0,0x24,0xa4,0xe8,0x28,0x10,0x90,0x30,0x4a,0x8a,0x6,
-+0x1,0x7f,0x1,0x3f,0x1,0xff,0x1,0x3f,0x1,0xff,0x4,0x8,0x6,0x1,0x6,0x18,0x8,0xfc,0x0,0xf0,0x14,0xfe,0x10,0xf0,0x4,0xfe,0x20,0x20,0x40,0x80,0x60,0x10,
-+0x2,0x2,0x2,0x2,0x2,0x2,0x3,0xfe,0x2,0x2,0x2,0x2,0x2,0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x4,0x4,0x4,0xfc,0x0,
-+0x0,0x8f,0x60,0x27,0x0,0x1f,0x0,0x17,0x20,0xe1,0x3f,0x22,0x26,0x21,0x22,0xc,0x88,0xfc,0x80,0xf8,0x88,0xfe,0x88,0xf8,0x80,0x4,0xfe,0x20,0x20,0xc0,0x30,0x8,
-+0x0,0x40,0x37,0x11,0x81,0x62,0x24,0x1,0x12,0x2c,0xe2,0x21,0x22,0x24,0x21,0x20,0x40,0x48,0xfc,0x50,0x4c,0x44,0xa0,0x10,0x4e,0x44,0x48,0x50,0x4c,0x44,0x40,0x80,
-+0x20,0x10,0x40,0x20,0xf,0x10,0x60,0x20,0x21,0xff,0x5,0x5,0x9,0x11,0x61,0x1,0x80,0x80,0x88,0xfc,0x80,0x88,0x88,0x78,0x4,0xfe,0x40,0x20,0x10,0x1c,0x8,0x0,
-+0x44,0x34,0x14,0x4,0x85,0x5f,0x44,0x4,0x14,0x24,0xe5,0x26,0x24,0x20,0x21,0x22,0x0,0x4,0xfe,0x24,0x24,0xa4,0x24,0x24,0x24,0x24,0x44,0x44,0x44,0x84,0x14,0x8,
-+0x8,0x8,0x3f,0x8,0x8,0xf,0x8,0x8,0xf,0x8,0x8,0xff,0x0,0x8,0x18,0x20,0x20,0x20,0xf8,0x20,0x20,0xe0,0x20,0x20,0xe0,0x20,0x24,0xfe,0x0,0x20,0x18,0x8,
-+0x11,0x11,0x13,0x11,0xfd,0x11,0x31,0x39,0x55,0x51,0x91,0x17,0x10,0x11,0x13,0x14,0x8,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0xfe,0x0,0x8,0x6,0x2,
-+0x1,0x1,0x3f,0x2,0x4,0x8,0xff,0x0,0x0,0x1f,0x10,0x10,0x1f,0x10,0x0,0x0,0x0,0x10,0xf8,0x80,0x60,0x24,0xfe,0x10,0x90,0xd0,0x90,0x90,0x90,0x90,0x50,0x20,
-+0x10,0x10,0x10,0x17,0x50,0x5c,0x53,0x52,0x51,0x51,0x50,0x5c,0xe0,0x41,0x6,0x18,0x40,0x40,0x48,0xfc,0x40,0x40,0xf8,0x8,0x10,0x10,0xa0,0x40,0xa0,0x10,0xe,0x4,
-+0x0,0x4,0x7e,0x55,0x54,0x54,0x54,0x7f,0x54,0x54,0x54,0x55,0x7c,0x44,0x0,0x3,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,
-+0x10,0x10,0x13,0x54,0x54,0x55,0x57,0x54,0x55,0x55,0x55,0x55,0x7d,0x45,0x0,0x0,0x40,0x48,0xfc,0x40,0xa0,0x14,0xfe,0x8,0xe8,0x28,0x28,0x28,0xe8,0x8,0x28,0x10,
-+0x0,0x78,0x4f,0x49,0x48,0x78,0x48,0x49,0x4e,0x79,0x49,0x49,0x49,0x4a,0x8c,0x18,0x80,0x48,0xfc,0x10,0xa0,0x40,0xb0,0xe,0x14,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x2,0x1,0x7f,0x8,0x4,0x2,0x1,0x6,0x18,0x20,0xc8,0x8,0x8,0x8,0x10,0x20,0x0,0x8,0xfc,0x20,0x40,0x80,0x0,0xc0,0x30,0x2e,0x24,0x20,0x20,0x20,0x20,0x20,
-+0x20,0x10,0x10,0xff,0x22,0x21,0x3c,0x24,0x24,0x24,0x24,0x27,0x24,0x34,0x49,0x82,0x80,0x84,0xfe,0x0,0x88,0xfc,0x88,0xf8,0x88,0xf8,0x88,0xfe,0x0,0x88,0x86,0x2,
-+0x20,0x10,0x11,0xfd,0x5,0x9,0x11,0x39,0x55,0x91,0x11,0x11,0x11,0x12,0x14,0x10,0x0,0xc,0xf0,0x0,0x0,0x4,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x10,0x8,0x8,0xfe,0x2,0x4,0x8,0x1c,0x2a,0x48,0x88,0x8,0x8,0x8,0x8,0x8,0x0,0xf8,0x88,0x88,0x90,0x90,0xa0,0x90,0x88,0x84,0x84,0xc4,0xa8,0x90,0x80,0x80,
-+0x8,0xfc,0xb,0x48,0x48,0x49,0x4f,0x48,0x7d,0x5,0x5,0x1d,0xe5,0x45,0x14,0x8,0x40,0x48,0xfc,0x40,0xb0,0x14,0xfe,0x8,0xe8,0x28,0x28,0x28,0xe8,0x8,0x28,0x10,
-+0x8,0x8,0x8,0x7e,0x8,0x8,0xfe,0x8,0x28,0x2e,0x28,0x28,0x28,0x58,0x8f,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x88,0x80,0x84,0x84,0x7c,0x0,0x6,0xfc,0x0,
-+0x1,0x21,0x21,0x21,0x3f,0x0,0x7f,0x0,0x0,0x0,0x3f,0x20,0x20,0x20,0x20,0x1f,0x0,0x8,0x8,0x8,0xf8,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,0x0,0x2,0x2,0xfe,
-+0x8,0x8,0x10,0x1f,0x20,0x40,0x9f,0x0,0x1,0x6,0x8,0x10,0x10,0x10,0x10,0xf,0x0,0x0,0x8,0xfc,0x0,0x0,0xe0,0x40,0x80,0x0,0x0,0x0,0x0,0x2,0x2,0xfe,
-+0x1,0x1,0x2,0x4,0x9,0x11,0x21,0xc9,0x9,0x9,0x9,0x9,0x9,0x9,0xff,0x0,0x0,0x0,0x80,0x40,0x20,0x10,0xe,0x24,0xf0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x1,0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x10,0x1f,0x18,0x28,0x28,0x48,0x8f,0x8,0x0,0x84,0xfe,0x4,0x4,0x4,0xfc,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x8,0xa,0x7f,0x8,0x3e,0x8,0x7f,0x8,0x9,0x1,0xff,0x1,0x2,0x4,0x18,0x60,0x0,0x4,0x7e,0x24,0x24,0x24,0x44,0x54,0x88,0x0,0xfe,0x0,0x80,0x60,0x1c,0x8,
-+0x1,0x9,0xfd,0x11,0x11,0x21,0x27,0x79,0xa9,0x29,0x29,0x29,0x29,0x38,0x20,0x1,0x0,0x4,0x7e,0x24,0x24,0xe4,0x24,0x24,0x24,0x24,0x64,0xa4,0x24,0x44,0x94,0x8,
-+0x3e,0x22,0x22,0x22,0x3e,0x1,0x1,0xff,0x2,0xc,0x30,0xfe,0x22,0x22,0x22,0x3e,0xf8,0x88,0x88,0x88,0xf8,0x20,0x14,0xfe,0x80,0x60,0x18,0xfe,0x88,0x88,0x88,0xf8,
-+0x10,0x10,0x1f,0x20,0x2f,0x40,0xbf,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,0xf0,0x0,0xe0,0x20,0x20,0x20,0x20,0x20,0x22,0x12,0xa,0x4,
-+0x1,0x41,0x31,0x12,0x4,0x1,0xf0,0x10,0x11,0x12,0x12,0x12,0x11,0x10,0x28,0x47,0x0,0x8,0xfc,0x0,0x0,0xf8,0x10,0x60,0x80,0x0,0x4,0x4,0xfc,0x0,0x6,0xfc,
-+0x2,0x1,0x7f,0x2,0x4,0x8,0x1f,0x4,0x4,0xff,0x4,0x4,0x4,0x8,0x30,0x0,0x0,0x8,0xfc,0x0,0x40,0x20,0xf0,0x50,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x2,0x42,0x33,0x14,0x87,0x68,0x27,0x0,0x10,0x20,0xe0,0x20,0x20,0x20,0x20,0x20,0x0,0x8,0xfc,0x0,0xf8,0x0,0xf0,0x10,0x10,0x10,0x10,0x10,0x10,0xa,0xa,0x6,
-+0x0,0x40,0x30,0x17,0x0,0x82,0x42,0x4a,0x12,0x21,0xe1,0x21,0x21,0x20,0x2f,0x20,0x80,0x40,0x48,0xfc,0x0,0x8,0x8,0x8,0x10,0x10,0x10,0x20,0x20,0x44,0xfe,0x0,
-+0x1,0x41,0x21,0x22,0x2,0x4,0xeb,0x20,0x20,0x20,0x20,0x21,0x2a,0x32,0x21,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0xf0,0x10,0x20,0x40,0x80,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x10,0x11,0x12,0xfc,0x10,0x17,0x1a,0x32,0xd2,0x13,0x12,0x12,0x12,0x53,0x22,0x80,0x80,0xfc,0x8,0x10,0xa4,0x1e,0x4,0x4,0x4,0xbc,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x10,0x59,0x56,0x54,0x9b,0x10,0x10,0x13,0x12,0x12,0x12,0x13,0x12,0x40,0x40,0xa0,0xa0,0x10,0xe,0x4,0xf8,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x40,0x30,0x10,0x81,0x62,0x2c,0x3,0x10,0x20,0xe3,0x22,0x22,0x22,0x23,0x22,0x40,0x40,0xa0,0xa0,0x10,0xe,0x4,0xf8,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x1,0x1,0x3f,0x2,0x4,0x8,0x7f,0x49,0x89,0x1f,0x21,0x1,0x7f,0x1,0x1,0x1,0x0,0x10,0xf8,0x80,0x60,0x20,0xfe,0x2,0x24,0xf0,0x0,0x8,0xfc,0x0,0x0,0x0,
-+0x10,0x10,0x13,0x10,0xfc,0x10,0x14,0x1f,0x30,0xd0,0x10,0x10,0x10,0x10,0x50,0x20,0x10,0x38,0xc0,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x10,0x10,0x11,0x1c,0x20,0x40,0xbc,0x13,0x10,0xfc,0x10,0x10,0x14,0x18,0x10,0x0,0x8,0x1c,0xe0,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x10,0x10,0x10,0x1c,0x20,0x40,0xbd,0x12,0x10,0xfd,0x11,0x11,0x15,0x19,0x11,0x1,0x8,0xfc,0x88,0x88,0x88,0x88,0x6,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x0,0x3f,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x20,0xf0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x40,0x33,0x10,0x0,0x0,0xf7,0x10,0x10,0x10,0x10,0x10,0x10,0x28,0x47,0x0,0x10,0x38,0xc0,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0x40,0x40,0x40,0x6,0xfc,0x0,
-+0x10,0x12,0x1f,0x28,0x45,0x2,0x4,0x8,0x30,0xcf,0x0,0x12,0x9,0x9,0x0,0x3f,0x40,0x48,0x7c,0xa0,0x10,0x80,0x40,0x30,0x4e,0xe4,0x0,0x10,0x10,0x20,0x40,0xf8,
-+0x8,0x8,0xb,0x10,0x10,0x30,0x50,0x9f,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0xc0,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x42,0x21,0x2f,0x1,0x7,0xe1,0x21,0x3f,0x21,0x21,0x27,0x29,0x33,0x25,0x9,0x1,0x10,0x20,0xfc,0x20,0xf8,0x28,0x28,0xfe,0x28,0x28,0xf8,0x20,0x30,0x2e,0x24,0x20,
-+0x10,0x14,0xfe,0x10,0x10,0x7d,0x46,0x7c,0x44,0x7c,0x10,0x14,0xfe,0x10,0x10,0x10,0x40,0x40,0x44,0x7e,0x80,0x0,0xf8,0x10,0x20,0x40,0x40,0x80,0x82,0x82,0x7e,0x0,
-+0x1,0x7f,0x49,0x6b,0x5d,0x49,0x7f,0x8,0x7f,0x8,0x7f,0x0,0x55,0x55,0x94,0x0,0x10,0x90,0x28,0x28,0x44,0x86,0x20,0x10,0x0,0x7c,0x4,0x4,0x8,0x8,0x90,0x0,
-+0x10,0x10,0x10,0x3c,0x43,0x80,0x3c,0x10,0x13,0xfc,0x10,0x10,0x14,0x18,0x11,0x0,0x40,0x50,0x48,0x7c,0xc0,0x40,0x44,0x7e,0xc0,0x44,0x4c,0x30,0x20,0x52,0x8a,0x6,
-+0x10,0x10,0x10,0x1c,0x23,0x40,0xbc,0x10,0x10,0xfc,0x10,0x10,0x14,0x18,0x10,0x0,0x88,0x88,0x88,0x88,0xfe,0x88,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x88,0xf8,0x88,
-+0x10,0xc,0x4,0xff,0x0,0x3e,0x22,0x22,0x3e,0x22,0x22,0x3e,0x22,0x22,0x2a,0x24,0x10,0x30,0x44,0xfe,0x0,0x8,0x48,0x48,0x48,0x48,0x48,0x48,0x8,0x8,0x28,0x10,
-+0x42,0x22,0x2f,0x82,0x62,0x2f,0x2,0x15,0x28,0xe7,0x24,0x24,0x27,0x24,0x24,0x27,0x10,0x10,0xbc,0x10,0x10,0xfe,0x10,0x28,0xc6,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,
-+0x0,0x43,0x32,0x13,0x0,0xf,0xf0,0x13,0x12,0x13,0x12,0x13,0x12,0x13,0x2a,0x47,0x48,0xfc,0x48,0xf8,0x40,0xfe,0x0,0xf8,0x8,0xf8,0x0,0xf8,0x8,0xf8,0x6,0xfc,
-+0x40,0x30,0x10,0x0,0x87,0x60,0x20,0x8,0x17,0x20,0xe0,0x20,0x20,0x23,0x2c,0x20,0x80,0xa0,0x90,0xfc,0x80,0x80,0x88,0xfc,0x80,0x90,0xa0,0x40,0xc0,0x24,0x14,0xc,
-+0x40,0x21,0x29,0x5,0x0,0xef,0x24,0x25,0x25,0x25,0x25,0x2d,0x35,0x25,0xa,0x11,0x20,0xfc,0x24,0xfc,0x20,0xfe,0x0,0xfc,0x4,0xfc,0x0,0xfc,0x4,0xfc,0x0,0xfe,
-+0x10,0xfe,0x20,0x28,0x7e,0x8,0xf,0xf9,0x4a,0x9,0x1,0x3f,0x1,0x1,0xff,0x0,0xc,0xf0,0x80,0x84,0xfe,0x90,0x90,0x10,0x10,0x10,0x0,0xf8,0x0,0x4,0xfe,0x0,
-+0x1,0x21,0x21,0x3f,0x22,0x22,0xff,0x22,0x22,0x22,0x3e,0x22,0x22,0x22,0x3e,0x21,0x0,0x8,0x8,0xf8,0x28,0x20,0x7c,0x44,0xa8,0x20,0x20,0x20,0x50,0x48,0x8e,0x4,
-+0x8,0x8,0x8,0x1f,0x10,0x21,0x41,0x81,0x2,0x2,0x4,0x4,0x8,0x10,0x20,0xc0,0x0,0x0,0x0,0xfc,0x4,0x8,0x10,0x0,0x80,0x80,0x40,0x40,0x20,0x10,0xe,0x4,
-+0x22,0x14,0xff,0x14,0x7f,0x15,0x15,0xff,0x15,0x15,0x7f,0x14,0x36,0x55,0x94,0x15,0x20,0x20,0xa0,0x3e,0x42,0x94,0x10,0xd0,0x10,0x10,0x28,0x28,0x48,0x4c,0x86,0x4,
-+0x10,0x10,0x10,0x10,0xfd,0x12,0x35,0x39,0x55,0x51,0x91,0x11,0x11,0x11,0x10,0x10,0x40,0x40,0xa0,0xa0,0x10,0xe,0xf4,0x10,0x10,0x10,0x50,0x20,0x4,0x4,0xfc,0x0,
-+0x0,0x8,0x7c,0x48,0x49,0x4a,0x4d,0x49,0x49,0x49,0x49,0x79,0x49,0x1,0x0,0x0,0x40,0x40,0xa0,0xa0,0x10,0xe,0xf4,0x10,0x10,0x10,0x50,0x20,0x4,0x4,0xfc,0x0,
-+0x8,0x7c,0x4b,0x4a,0x4c,0x79,0x4a,0x4c,0x48,0x7b,0x48,0x48,0x48,0x48,0x4f,0x98,0x80,0x40,0xfe,0x2,0x4,0x10,0x8,0x4,0x0,0xf8,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x8,0x4,0x7f,0x1,0x1,0x3f,0x1,0x1,0xff,0x2,0x2,0x2,0x4,0x8,0x10,0x60,0x20,0x48,0xfc,0x0,0x10,0xf8,0x0,0x4,0xfe,0x80,0x80,0x80,0x80,0x82,0x82,0x7e,
-+0x20,0x20,0x27,0x20,0xfa,0x21,0x2f,0x20,0x23,0x22,0x3a,0xe2,0x42,0x2,0x3,0x2,0x40,0x48,0xfc,0x40,0x48,0x50,0xfe,0x8,0xfc,0x8,0xe8,0xa8,0xe8,0x8,0xf8,0x8,
-+0x8,0x7f,0x9,0x1,0x7f,0x9,0x5,0xff,0x0,0x1f,0x10,0x17,0x14,0x17,0x10,0x1f,0x28,0xfc,0x20,0x8,0xfc,0x20,0x44,0xfe,0x10,0xf8,0x10,0xd0,0x50,0xd0,0x10,0xf0,
-+0x8,0xfd,0x9,0x9,0x9,0x79,0x48,0x43,0x42,0x7a,0xb,0xa,0x8,0x88,0x53,0x20,0x4,0xfe,0x4,0x4,0xfc,0x24,0x20,0xfe,0x22,0x22,0xfe,0x22,0x20,0x24,0xfe,0x2,
-+0x10,0x10,0x10,0x10,0xfd,0x12,0x15,0x19,0x31,0xd1,0x11,0x11,0x11,0x11,0x50,0x20,0x40,0x40,0xa0,0xa0,0x10,0xe,0xf4,0x10,0x10,0x10,0x50,0x20,0x4,0x4,0xfc,0x0,
-+0x13,0x10,0x11,0x10,0xff,0x10,0x30,0x38,0x57,0x51,0x97,0x11,0x1f,0x11,0x11,0x11,0xf8,0x40,0xf0,0x40,0xf8,0x42,0x7e,0x0,0xbc,0x10,0xbc,0x10,0xbe,0x10,0x52,0x8e,
-+0x20,0x27,0x39,0x41,0x41,0xff,0x21,0x23,0xfb,0x25,0x29,0x21,0x29,0x31,0x21,0x1,0xd0,0x10,0x10,0x52,0x34,0xd8,0x10,0x10,0x90,0x50,0x28,0x28,0x44,0x44,0x82,0x0,
-+0x10,0x9,0xff,0x0,0x3e,0x22,0x3e,0x0,0x7f,0x41,0x5d,0x55,0x5d,0x41,0x45,0x42,0x10,0x10,0x94,0x1e,0x10,0x10,0xfc,0x4,0x44,0x44,0x28,0x28,0x10,0x28,0x4e,0x84,
-+0x10,0x12,0x11,0x11,0x58,0x57,0x52,0x92,0x13,0x12,0x12,0x13,0x12,0x12,0x12,0x12,0x40,0x44,0x48,0x50,0x48,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x10,0x13,0x10,0x10,0xfc,0x17,0x31,0x39,0x56,0x55,0x99,0x11,0x11,0x12,0x14,0x10,0x38,0xc0,0x40,0x40,0x84,0xfe,0x20,0x10,0xe,0x14,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x9,0x7d,0x49,0x4b,0x4d,0x79,0x49,0x49,0x49,0x79,0x49,0x49,0x49,0x7a,0x42,0x4,0x40,0x28,0xfc,0x20,0x20,0xf8,0x20,0x20,0xf8,0x20,0x28,0xfc,0x0,0xa8,0xa6,0x2,
-+0x0,0x1f,0x2,0x2,0xff,0x4,0x4,0x8,0x34,0xc4,0x4,0x4,0x8,0x8,0x10,0x0,0xf0,0x0,0x0,0x4,0xfe,0x40,0x20,0x50,0x4e,0x44,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x8,0xb,0x8,0x10,0x10,0x3f,0x51,0x91,0x12,0x15,0x19,0x11,0x11,0x12,0x14,0x10,0x38,0xc0,0x40,0x40,0x84,0xfe,0x20,0x10,0xe,0x14,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x0,0xb,0xfc,0x10,0x10,0x10,0x10,0x11,0x10,0x10,0x1e,0xf0,0x40,0x0,0x0,0x0,0x4,0xfe,0x40,0x40,0x40,0x80,0x84,0xfe,0x4,0x4,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x44,0x45,0xfe,0x44,0x7c,0x11,0x7d,0x55,0x55,0x55,0x7d,0x11,0xff,0x11,0x11,0x11,0x20,0x24,0xa4,0xa8,0x24,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x4,0x14,0x8,
-+0x13,0x10,0x11,0x10,0xff,0x10,0x14,0x18,0x37,0xd1,0x17,0x11,0x1f,0x11,0x51,0x21,0xf8,0x40,0xf0,0x40,0xf8,0x42,0x7e,0x0,0xbc,0x10,0xbc,0x10,0xbe,0x10,0x52,0x8e,
-+0x20,0x21,0xfe,0x28,0x11,0x2a,0xc6,0x0,0xfd,0x2a,0x28,0x29,0x28,0x28,0x47,0x80,0x4,0xde,0x44,0x44,0x54,0xcc,0x44,0xcc,0x54,0x64,0x44,0x54,0x88,0x2,0xfe,0x0,
-+0x10,0x11,0x10,0x54,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x7d,0x45,0x1,0x1,0x20,0x24,0xa8,0x24,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x4,0x4,0x14,0x8,
-+0x8,0x9,0x8,0x10,0x11,0x31,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x20,0x24,0xa8,0x24,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x4,0x4,0x14,0x8,
-+0x2,0x1,0x7f,0x44,0x88,0x10,0x3,0x7e,0x8,0x9,0x8,0x8,0xe,0x78,0x20,0x0,0x0,0x0,0xfe,0x42,0x34,0x10,0xfc,0x80,0x88,0xfc,0x8,0x8,0x8,0x88,0x50,0x20,
-+0x10,0x10,0x11,0x10,0x14,0x1e,0xf0,0x10,0x10,0x12,0x14,0x18,0x10,0x1,0x2,0xc,0x0,0x4,0xfe,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x4,0x28,0x10,
-+0x4,0x4,0xff,0x4,0x14,0x12,0xff,0x12,0x12,0x12,0x12,0x12,0x22,0x22,0x4a,0x84,0x40,0x44,0xfe,0x40,0x40,0x4,0x7e,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x7c,0x44,
-+0x0,0xf,0x8,0x8,0x8,0xf,0x8,0x8,0x8,0xf,0x8,0x8,0x8,0x8,0xff,0x0,0x20,0xf0,0x20,0x20,0x20,0xe0,0x20,0x20,0x20,0xe0,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x10,0x10,0x10,0x5b,0x54,0x50,0x90,0x17,0x10,0x10,0x10,0x11,0x12,0x17,0x10,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x40,0x80,0x80,0x10,0x8,0xfc,0x4,
-+0x2,0x1,0x7f,0x44,0x88,0x10,0x0,0x11,0x14,0xfe,0x10,0x10,0x14,0x18,0x11,0x2,0x0,0x0,0xfe,0x42,0x34,0x10,0x4,0xfe,0x44,0x44,0x44,0x44,0x84,0x84,0x28,0x10,
-+0x10,0x10,0x10,0x1c,0x20,0x21,0x7e,0x90,0x10,0xfc,0x10,0x12,0x14,0x18,0x11,0x2,0x40,0x40,0x40,0x7c,0x84,0x8,0x20,0x20,0x20,0x20,0x50,0x50,0x88,0x8e,0x4,0x0,
-+0x8,0xb,0x8,0x13,0x10,0x33,0x50,0x97,0x14,0x19,0x11,0x10,0x10,0x10,0x11,0x16,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfe,0x2,0xf4,0x10,0xa0,0x40,0xb0,0xe,0x4,
-+0x2,0x1,0x7f,0x8,0x4,0x2,0xff,0x1,0x1,0x7f,0x1,0x9,0x19,0x21,0x45,0x2,0x0,0x8,0xfc,0x20,0x40,0x84,0xfe,0x0,0x8,0xfc,0x0,0x20,0x18,0xc,0x4,0x0,
-+0x1,0x7f,0x1,0x3f,0x2,0xff,0x4,0x8,0x37,0xc1,0x1f,0x1,0x5,0x9,0x31,0x1,0x8,0xfc,0x0,0xf8,0x0,0xfe,0x40,0xe0,0x1e,0x24,0xf0,0x0,0x60,0x18,0x8,0x0,
-+0x4,0x7e,0x8,0x3e,0x8,0x7e,0x1,0x2,0xc,0x32,0xc1,0xf,0x0,0x0,0x0,0x1,0x8,0xfc,0x20,0xf8,0x20,0xfc,0x0,0x80,0x60,0x1e,0x4,0xe0,0x20,0x40,0x80,0x0,
-+0x22,0xff,0x22,0x3e,0x8,0x7f,0x49,0x49,0x7f,0x8,0x7f,0x8,0x3e,0x8,0xff,0x1,0x20,0xa0,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x94,0x8,
-+0x8,0x8,0xff,0x8,0x0,0x1f,0x10,0x10,0x1f,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x20,0x20,0xfe,0x20,0x18,0xe0,0x0,0x4,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x10,0x10,0x11,0x12,0xfd,0x10,0x12,0x1a,0x33,0xd0,0x17,0x14,0x14,0x15,0x54,0x24,0x40,0xa0,0x10,0x48,0xf6,0xa4,0x48,0xa8,0xf8,0x44,0xfe,0x84,0xa4,0xf4,0x4,0xc,
-+0x1,0x2,0x6,0x8,0x3f,0xc4,0x13,0x14,0x1f,0x1,0x3f,0x22,0x24,0x2f,0x20,0x20,0x0,0x80,0x40,0x30,0xfe,0x44,0x90,0x50,0xf0,0x8,0xfc,0x8,0x48,0xe8,0x8,0x18,
-+0x1,0x7f,0x40,0x97,0x10,0x97,0x50,0x57,0x10,0x37,0x58,0x93,0x11,0x10,0x11,0x16,0x0,0xfe,0x2,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfc,0x4,0xf0,0x20,0xc0,0x20,0x1c,
-+0x20,0x18,0x8,0x80,0x61,0x21,0x1,0x15,0x25,0x25,0xe9,0x29,0x21,0x21,0x20,0x20,0x0,0x80,0x40,0x60,0x20,0x20,0x0,0x8,0x4,0x6,0x2,0x8,0x8,0x8,0xf8,0x0,
-+0x1,0x1,0x7f,0x1,0x3f,0x1,0xff,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x10,0x0,0x8,0xfc,0x0,0xf8,0x0,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0x50,0x20,
-+0x10,0x11,0x14,0xfe,0x20,0x28,0x4b,0x7c,0x8,0x9,0xe,0xf8,0x48,0x8,0xb,0x8,0x0,0xfc,0x8,0x10,0x38,0xcc,0x2,0x0,0x8,0xfc,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x1f,0x10,0x2f,0x40,0xbf,0x0,0x3f,0x2,0xd,0x70,0x1f,0x2,0x2,0x7f,0x0,0x8,0xfc,0x0,0xf8,0x10,0xf8,0x10,0x90,0x10,0x90,0x70,0xd0,0x10,0x52,0xea,0x6,
-+0x10,0x13,0x10,0x28,0x29,0x69,0xaf,0x29,0x29,0x29,0x2b,0x2d,0x28,0x20,0x20,0x23,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x50,0x4c,0x86,0x2,
-+0x8,0x77,0x44,0x54,0x54,0x57,0x54,0x54,0x54,0x57,0x74,0x55,0x14,0x25,0x46,0x80,0x4,0xbe,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0x24,0x34,0xa8,0xa0,0x20,0x20,
-+0x0,0x40,0x37,0x10,0x83,0x60,0x2f,0x8,0x13,0x22,0xe3,0x22,0x23,0x22,0x22,0x22,0x40,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x28,0x10,
-+0x24,0xff,0x24,0x3f,0x41,0xbd,0x25,0x3d,0x2,0x3f,0x1,0x1f,0x1,0xff,0x1,0x3,0x20,0x24,0x3e,0x44,0xa8,0x10,0x2e,0x44,0x70,0x80,0x0,0xf0,0x4,0xfe,0x0,0x0,
-+0x0,0x8,0x7f,0x48,0x4b,0x48,0x4f,0x78,0x4b,0x4a,0x4b,0x4a,0x7b,0x4a,0x2,0x2,0x40,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x28,0x10,
-+0x10,0x1f,0x10,0x2f,0x40,0xbf,0x4,0x3f,0x4,0x3f,0x4,0x7f,0x0,0x9,0x6,0x2,0x8,0xfc,0x0,0xf8,0x10,0xf8,0x10,0x90,0x10,0x90,0x10,0xd0,0x90,0x12,0xa,0x6,
-+0x10,0x17,0x10,0x13,0x58,0x57,0x50,0x93,0x12,0x13,0x12,0x13,0x12,0x12,0x12,0x12,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x0,0x4f,0x40,0x40,0x53,0x7a,0x42,0x42,0x42,0x4a,0x52,0x62,0x40,0x1,0x2,0xc,0x4,0xfe,0x40,0x88,0xfc,0x8,0x48,0x48,0x48,0x48,0x48,0x88,0xa0,0x18,0xc,0x4,
-+0x0,0x47,0x20,0x23,0x0,0xef,0x20,0x23,0x22,0x23,0x22,0x23,0x2a,0x32,0x22,0x2,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x1,0x0,0x3f,0x20,0x20,0x20,0x3f,0x20,0x20,0x21,0x21,0x22,0x22,0x44,0x88,0x30,0x0,0x88,0xfc,0x80,0x80,0x88,0xfc,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0xe,0x4,
-+0x0,0x10,0xf8,0x27,0x20,0x23,0xfa,0x22,0x22,0x23,0x20,0x39,0xe3,0x44,0x1,0x0,0x80,0x40,0x4,0xfe,0x8,0xfc,0x8,0x8,0x8,0xf8,0x40,0x50,0x4c,0x44,0x40,0x80,
-+0x2,0x1,0x7f,0x40,0x84,0xc,0x12,0x2,0x3f,0x2,0x2,0x4,0x4,0x8,0x10,0x20,0x0,0x0,0xfe,0x2,0x44,0x30,0x10,0x8,0xfc,0x8,0x8,0x8,0x8,0x88,0x50,0x20,
-+0x8,0x1c,0xf0,0x10,0x11,0xfd,0x11,0x32,0x38,0x54,0x50,0x91,0x11,0x12,0x14,0x18,0x40,0x40,0x40,0x40,0x44,0x4c,0x50,0x40,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,0x0,
-+0x0,0x0,0x1,0xe,0x8,0x8,0x8,0xf,0x8,0x8,0x8,0x8,0x8,0x8,0xff,0x0,0x20,0x70,0x80,0x0,0x0,0x0,0x10,0xf8,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x2,0x6,0x38,0x20,0x20,0x21,0x3f,0x22,0x22,0x22,0x22,0x22,0x3f,0xe0,0x40,0x0,0x0,0x7c,0x44,0x44,0x48,0x48,0xd0,0x48,0x44,0x42,0x42,0x62,0xd4,0x48,0x40,0x40,
-+0x0,0x8,0xfc,0x13,0x10,0x12,0x7d,0x11,0x10,0x10,0x11,0x1e,0xe4,0x0,0x1,0x0,0x40,0x50,0x48,0xfe,0x40,0x44,0x4c,0x50,0x60,0xd0,0x50,0x4e,0x44,0x40,0x40,0x80,
-+0x1,0x1,0x1,0x7f,0x1,0x21,0x19,0x9,0x3,0x5,0x9,0x11,0x61,0x1,0x5,0x2,0x0,0x40,0x28,0xfc,0x0,0x8,0x18,0xa0,0x40,0x40,0x30,0xe,0x4,0x0,0x0,0x0,
-+0x0,0x7f,0x40,0x41,0x41,0x41,0x41,0x42,0x42,0x44,0x44,0x48,0x50,0x40,0x7f,0x40,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0x84,0x84,0x44,0x24,0x3c,0x14,0x4,0xfc,0x4,
-+0x10,0xc,0x4,0xff,0x4,0x4,0x3f,0x24,0x24,0x38,0x20,0x2f,0x20,0x20,0x3f,0x20,0x10,0x30,0x44,0xfe,0x40,0x48,0xfc,0x48,0x48,0x38,0x8,0xe8,0x8,0x8,0xf8,0x8,
-+0x40,0x37,0x14,0x4,0x84,0x44,0x54,0x14,0x14,0x24,0xe4,0x25,0x26,0x24,0x27,0x24,0x4,0xfe,0x4,0x44,0x44,0x44,0x44,0xa4,0xa4,0xa4,0x94,0x1c,0x4,0x4,0xfc,0x4,
-+0x8,0x8,0x8,0x7e,0x9,0x8,0xff,0x8,0x28,0x2e,0x28,0x28,0x29,0x58,0x88,0x7,0x40,0x40,0x78,0x88,0x10,0x24,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x0,0x6,0xfc,
-+0x0,0x3f,0x20,0x28,0x24,0x22,0x21,0x20,0x21,0x22,0x24,0x28,0x20,0x20,0x3f,0x0,0x8,0xfc,0x0,0x8,0x18,0x20,0x40,0x80,0x40,0x30,0x18,0x8,0x0,0x4,0xfe,0x0,
-+0x10,0x11,0x15,0x7f,0x55,0x55,0x55,0x55,0x55,0x7d,0x51,0x15,0x1d,0xf5,0x47,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xfe,0x0,
-+0x4,0x4,0x4,0x4,0x7f,0x44,0x44,0x44,0x44,0x7f,0x44,0x44,0x44,0x44,0x7f,0x40,0x40,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0xfc,0x44,0x44,0x44,0x44,0xfc,0x4,
-+0x8,0x11,0x7d,0x45,0x7d,0x45,0x7d,0x45,0x45,0xfd,0x15,0x25,0x45,0x85,0x15,0x8,0x4,0xfe,0x0,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x84,0x0,0xfe,0x0,
-+0x0,0x3f,0x20,0x20,0x3f,0x20,0x28,0x28,0x28,0x2f,0x20,0x30,0x50,0x50,0x9f,0x10,0x4,0xfe,0x4,0x4,0xfc,0x80,0x88,0x88,0x88,0xf8,0x80,0x84,0x84,0x84,0xfc,0x4,
-+0x8,0xfd,0x9,0x49,0x49,0x49,0x49,0x49,0x7d,0x5,0x5,0x1d,0xe5,0x45,0x15,0x8,0x4,0xfe,0x0,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x84,0x0,0xfe,0x0,
-+0x23,0x12,0x43,0x22,0xa,0x13,0x62,0x23,0x20,0x0,0xff,0x5,0x9,0x11,0x61,0x1,0xfc,0x0,0xf8,0x8,0x8,0xf8,0x0,0xfc,0x0,0x4,0xfe,0x40,0x20,0x1c,0x8,0x0,
-+0x1,0xff,0x22,0x23,0x3e,0x22,0x22,0x3e,0x22,0x22,0x22,0x3e,0xe2,0x42,0x3,0x2,0x0,0x80,0x0,0xfc,0x4,0x84,0x88,0x88,0x48,0x50,0x20,0x50,0x48,0x8e,0x4,0x0,
-+0x0,0x7f,0x22,0x3e,0x22,0x3e,0x22,0xff,0x2,0x1,0xff,0x4,0xc,0x2,0x1,0xe,0x0,0x0,0xfc,0x44,0x48,0x28,0x10,0x2e,0x44,0x0,0xfe,0x20,0x20,0x40,0x80,0x70,
-+0x10,0x13,0x10,0x5d,0x51,0x51,0xfd,0x0,0x55,0x55,0x55,0x6d,0x45,0x7d,0x45,0x1,0xc,0xf0,0x24,0xfe,0x24,0x24,0xfc,0x20,0xfc,0x24,0x24,0x54,0x74,0x4,0x14,0x8,
-+0x10,0x17,0x12,0x7e,0x13,0x12,0xfe,0x13,0x52,0x5e,0x52,0x57,0x70,0x50,0x8f,0x0,0x40,0xe0,0x40,0x7c,0xc4,0x54,0x54,0xd4,0x48,0x54,0x52,0xe2,0x40,0x46,0xfc,0x0,
-+0x1,0x1,0x1,0x7f,0x1,0x1,0x1,0x1,0xff,0x2,0x2,0x4,0x8,0x10,0x3f,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x40,0x20,0x10,0xf8,0x8,
-+0x0,0x7f,0x49,0x45,0x5f,0x42,0x7f,0x44,0x4f,0x74,0x45,0x44,0x43,0x40,0x7f,0x40,0x4,0xfe,0x24,0x44,0xf4,0x4,0xfc,0x44,0xe4,0x5c,0x84,0x24,0xe4,0x4,0xfc,0x4,
-+0x22,0x22,0xff,0x22,0x77,0x55,0x77,0x24,0x3f,0x64,0xbf,0x24,0x3f,0x24,0x3f,0x20,0x4,0xfe,0x90,0x24,0x7e,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x10,0x28,0x46,0x82,
-+0x10,0x10,0x13,0x10,0xfe,0x12,0x31,0x39,0x55,0x50,0x90,0x10,0x11,0x12,0x14,0x10,0x0,0x0,0xf8,0x8,0x8,0x8,0x8,0x10,0x10,0xa0,0x40,0xa0,0x10,0xe,0x4,0x0,
-+0x4,0xfe,0x2b,0x28,0xfe,0xaa,0xaa,0xab,0xc6,0x82,0xfe,0x82,0x82,0xfe,0x83,0x0,0x88,0x88,0xfe,0x88,0x20,0x50,0x8e,0x4,0xf8,0x20,0x20,0xf8,0x20,0x24,0xfe,0x0,
-+0x2,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x1,0x7d,0x5,0x9,0x11,0x21,0xc5,0x2,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x4,0x8c,0x50,0x20,0x10,0xe,0x4,0x0,
-+0x1,0x1,0x2,0x4,0x8,0x10,0x2f,0xc1,0x1,0x1,0xf,0x1,0x1,0x1,0x7f,0x0,0x0,0x0,0x80,0x40,0x20,0x50,0xee,0x4,0x0,0x40,0xe0,0x0,0x0,0x8,0xfc,0x0,
-+0x0,0x0,0x1f,0x10,0x90,0x51,0x52,0x1d,0x30,0x50,0xd3,0x10,0x20,0x20,0x4f,0x0,0x80,0x44,0xfe,0x40,0xa0,0x10,0xe,0xf4,0x40,0x50,0xf8,0x40,0x40,0x44,0xfe,0x0,
-+0x1,0x9,0x5,0x7f,0x2,0xff,0x4,0x9,0x1f,0x21,0xcf,0x1,0x3f,0x1,0x5,0x2,0x0,0x20,0x48,0xfc,0x0,0xfe,0x40,0xe0,0x10,0xe,0xe4,0x0,0xf8,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x2,0x2,0x4,0x4,0x8,0x10,0x60,0x0,0x0,0x40,0x30,0x10,0x4,0xfe,0x0,0x0,0x80,0x80,0x40,0x20,0x10,0xe,0x4,0x0,
-+0x1,0x9,0x5,0x7f,0x2,0xff,0x4,0x8,0x1f,0x22,0xc2,0x4,0x4,0x8,0x10,0x20,0x0,0x20,0x48,0xfc,0x0,0xfe,0x40,0x20,0xf0,0x2e,0x24,0x20,0x20,0x20,0xa0,0x40,
-+0x0,0x0,0x7e,0x2,0x23,0x22,0x14,0x14,0x8,0x14,0x14,0x22,0x42,0x81,0x2,0x4,0x40,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x4,0x28,0x10,
-+0x20,0x20,0x24,0x3e,0x51,0x90,0x14,0xfe,0x13,0x54,0x54,0x54,0x54,0x7d,0x46,0x4,0x40,0x40,0x40,0x48,0xfc,0x48,0x48,0x48,0xfe,0x40,0x40,0xa0,0xa0,0x10,0xe,0x4,
-+0x10,0x10,0x12,0x56,0x59,0x50,0x90,0x10,0x17,0x28,0x28,0x24,0x44,0x41,0x82,0x4,0x40,0x40,0x40,0x48,0xfc,0x48,0x48,0x48,0xfe,0x40,0x40,0xa0,0xa0,0x10,0xe,0x4,
-+0x0,0x1f,0x12,0x9f,0x52,0x52,0x12,0x15,0x38,0x57,0xd4,0x15,0x24,0x24,0x45,0x4,0x84,0xfe,0x0,0xbc,0xa4,0xa4,0xa4,0xbc,0x44,0xfe,0x44,0xb4,0x44,0xa4,0x14,0x8,
-+0x8,0x8,0xa,0x7f,0x8,0x8,0x9,0xff,0x8,0x10,0x10,0x24,0x22,0x7f,0x1,0x0,0x0,0x4,0x7e,0x44,0x44,0x44,0x44,0xc4,0x44,0x44,0x64,0x54,0x48,0x40,0x40,0x40,
-+0x24,0x24,0x24,0x7e,0x24,0x24,0xff,0x0,0x7e,0x42,0x42,0x7e,0x43,0x42,0x7e,0x42,0x20,0x48,0xfc,0x88,0xa8,0x88,0xa8,0x90,0x84,0xfe,0x4,0x14,0xfc,0x4,0x14,0x8,
-+0x10,0x10,0x13,0x12,0xfc,0x11,0x31,0x3b,0x55,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x40,0x40,0xfe,0xa2,0xa4,0xfe,0x20,0x28,0xfc,0x20,0x28,0xfc,0x20,0x24,0xfe,0x0,
-+0x0,0x4,0xfe,0x10,0x11,0x23,0x25,0x7d,0xa5,0x25,0x25,0x25,0x25,0x3d,0x22,0x4,0x40,0x40,0x78,0x90,0x24,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x24,0x24,0x24,0xc,
-+0x1,0x9,0xd,0x11,0x21,0x3,0xc,0x30,0xdf,0x10,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x0,0x20,0x18,0x4c,0x84,0x0,0x0,0x88,0xfc,0x80,0xf8,0x80,0xf8,0x80,0xfe,0x0,
-+0x20,0x11,0x10,0x0,0xfb,0x8,0x10,0x35,0x58,0x95,0x11,0x12,0x14,0x10,0x10,0x10,0x4,0xfe,0x84,0x84,0xfe,0x84,0x84,0xfc,0x80,0x4,0xfe,0x84,0x84,0x84,0xfc,0x84,
-+0x2,0x7f,0x22,0x22,0xff,0x22,0x22,0x7e,0x20,0x42,0xbf,0x22,0x22,0x22,0x3e,0x22,0x82,0x44,0x28,0xfe,0x10,0x10,0x14,0xfe,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,
-+0x10,0x10,0x10,0x1e,0x22,0x33,0x4a,0xa4,0x14,0x8,0x11,0x22,0x40,0x24,0x24,0x40,0x20,0x20,0x28,0x24,0x20,0xfe,0x20,0x50,0x50,0x88,0xe,0x4,0x0,0x48,0x46,0x2,
-+0x11,0x11,0x11,0x15,0x5a,0x53,0x54,0x9a,0x11,0x12,0x20,0x28,0x44,0x42,0x82,0x4,0x10,0x18,0xd4,0x50,0x7e,0x50,0x90,0x90,0x28,0x28,0x46,0x84,0x0,0xa8,0xa4,0x4,
-+0x1,0x1,0x1,0x3f,0x21,0x21,0x3f,0x21,0x21,0xff,0x20,0x20,0x20,0x20,0x20,0x20,0x0,0x0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xfe,0x8,0x8,0x8,0x8,0x28,0x10,
-+0x20,0x10,0x43,0x20,0x8,0x51,0x22,0x25,0x1,0xff,0x3,0x5,0x9,0x11,0x61,0x1,0x80,0x90,0xf8,0x90,0x90,0x12,0x12,0xe,0x0,0xfe,0x80,0x40,0x20,0x1c,0x8,0x0,
-+0x10,0xfe,0x0,0xee,0xaa,0xee,0x28,0xfe,0x28,0x7c,0x28,0xfe,0x24,0x68,0xa5,0x32,0x8,0x1c,0xe0,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa4,0xaa,0x38,0x0,
-+0x20,0x27,0x20,0x23,0xfa,0x23,0x21,0x27,0x21,0x23,0x39,0xef,0x41,0x3,0xd,0x1,0x44,0xfe,0x0,0xb8,0xa8,0xb8,0x10,0xfc,0x10,0xf8,0x10,0xfe,0x48,0x30,0xe,0x84,
-+0x10,0x17,0x10,0x13,0xfe,0x13,0x11,0x1f,0x31,0xd3,0x11,0x1f,0x11,0x13,0x55,0x21,0x44,0xfe,0x0,0xb8,0xa8,0xb8,0x10,0xfc,0x10,0xf8,0x10,0xfe,0x48,0x30,0xe,0x84,
-+0x0,0xf,0x70,0x53,0x52,0x53,0x51,0x57,0x51,0x53,0x51,0x5f,0x71,0x43,0xd,0x1,0x44,0xfe,0x0,0xb8,0xa8,0xb8,0x10,0xfc,0x10,0xf8,0x10,0xfe,0x48,0x30,0xe,0x84,
-+0x0,0x40,0x30,0x10,0x0,0x0,0xf0,0x10,0x10,0x10,0x10,0x12,0x14,0x18,0x17,0x0,0x40,0x40,0x40,0x40,0x48,0x7c,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x20,0x20,0x20,0x38,0x4f,0x50,0x80,0x20,0x27,0x20,0x27,0x21,0x29,0x31,0x22,0xc,0x80,0x80,0x88,0xfc,0x80,0x50,0x22,0xd2,0xe,0x8,0xfc,0x20,0x20,0x22,0x22,0x1e,
-+0x10,0x10,0x10,0x10,0xfc,0x13,0x14,0x18,0x30,0xd0,0x10,0x10,0x11,0x11,0x52,0x24,0x40,0x50,0x48,0x40,0x44,0xfe,0x40,0x60,0xa0,0xa0,0xa0,0xa0,0x22,0x22,0x1e,0x0,
-+0x10,0x10,0x20,0x20,0x47,0xf8,0x10,0x20,0x47,0xf8,0x7,0x1,0x19,0xe1,0x42,0xc,0x80,0x80,0x88,0xfc,0x80,0x50,0x22,0xd2,0xe,0x8,0xfc,0x20,0x20,0x22,0x22,0x1e,
-+0x8,0x8,0x7f,0xa,0x2,0xff,0x4,0xf,0x18,0x28,0xcf,0x2,0x29,0x28,0x48,0x7,0x20,0x28,0xfc,0x20,0x4,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x0,0x88,0x84,0x14,0xf0,
-+0x8,0x8,0x8,0x7f,0x8,0xa,0x1c,0x68,0x8,0x8,0x29,0x12,0x0,0x48,0x44,0x84,0x40,0x40,0x48,0xfc,0x48,0x48,0xc8,0x48,0xa8,0x8a,0xa,0x4,0x0,0x88,0x46,0x42,
-+0x0,0x0,0x3f,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x3f,0x0,0x10,0x78,0x80,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x10,0xf8,0x0,
-+0x8,0x8,0x8,0x17,0x10,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x1f,0x10,0x10,0x10,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x2,0x2,0x2,0x4,0x4,0x8,0x10,0x20,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x40,0x40,0x20,0x10,0xe,0x4,
-+0x0,0x7f,0x2,0x12,0x12,0x22,0x4,0x18,0x60,0x0,0x4,0x13,0x51,0x50,0x8f,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x50,0x20,0x0,0x0,0x0,0x14,0x12,0xf2,0x0,
-+0x10,0x10,0x15,0xfe,0x10,0x10,0x7c,0x10,0x11,0xfe,0x12,0x12,0x1a,0x14,0x10,0x13,0x0,0x4,0xfe,0x24,0x24,0xa4,0xa4,0xa4,0x24,0x24,0x24,0x44,0x44,0x84,0x94,0x8,
-+0x8,0x8,0xb,0x10,0x10,0x30,0x50,0x9f,0x10,0x10,0x10,0x10,0x10,0x17,0x10,0x10,0x0,0x18,0xe0,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x48,0xfc,0x0,0x0,
-+0x0,0x40,0x30,0x10,0x0,0x0,0xf0,0x10,0x10,0x11,0x11,0x15,0x1a,0x12,0x4,0x8,0x40,0x40,0x40,0x40,0x40,0x40,0xa0,0xa0,0xa0,0x10,0x10,0x10,0x8,0x8,0x6,0x4,
-+0x0,0x7f,0x1,0x1,0x1,0x9,0x9,0x11,0x21,0x1,0x2,0x2,0x4,0x8,0x10,0x60,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x10,0x10,0x11,0x10,0xfc,0x24,0x24,0x27,0x24,0x44,0x28,0x10,0x28,0x44,0x85,0x0,0x8,0x3c,0xe0,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x28,0xfc,0x0,
-+0x10,0x10,0x23,0x20,0x44,0xf9,0x11,0x22,0x40,0xfc,0x0,0x0,0x1c,0xe1,0x42,0x4,0x0,0x4,0xfe,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x84,0x4,0x28,0x10,
-+0x10,0x10,0x17,0x10,0xfc,0x10,0x14,0x18,0x30,0xd0,0x11,0x11,0x11,0x12,0x54,0x28,0x0,0x8,0xfc,0x88,0x88,0x90,0x94,0xbe,0x84,0x84,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x10,0x10,0x1f,0x21,0x21,0x61,0xa1,0x21,0x21,0x21,0x22,0x22,0x22,0x24,0x28,0x30,0x0,0x8,0xfc,0x8,0x8,0x8,0x10,0x14,0x3e,0x4,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x0,0x1f,0x10,0x10,0x10,0x10,0x10,0x1f,0x10,0x10,0x10,0x10,0x10,0x1f,0x10,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0xf0,0x10,0x10,0x10,0x10,0x10,0xf0,0x10,0x0,
-+0x0,0x0,0x0,0xff,0x0,0x8,0x8,0x8,0x7e,0x8,0x8,0x10,0x11,0x22,0x4c,0x0,0x80,0xa0,0x94,0xfe,0x80,0x80,0x88,0x88,0x90,0x60,0x40,0xc0,0x20,0x12,0xa,0x6,
-+0x4,0x4,0xff,0x4,0x0,0x7f,0x8,0xf,0x8,0xf,0x8,0x8,0x7f,0x0,0x0,0x0,0x40,0x44,0xfe,0x40,0x8,0xfc,0x20,0xe0,0x20,0xe0,0x28,0x3c,0xe0,0x20,0x20,0x20,
-+0x8,0x8,0xff,0x8,0x1,0x7f,0x40,0x89,0x12,0x4,0x1f,0x28,0xc8,0x8,0xf,0x8,0x20,0x24,0xfe,0x20,0x0,0xfe,0x2,0x24,0x90,0x40,0xf0,0x2e,0x24,0x20,0xe0,0x20,
-+0x4,0x4,0xff,0x4,0x0,0x7f,0x41,0x81,0x1,0x7f,0x3,0x5,0x9,0x11,0x61,0x1,0x40,0x44,0xfe,0x40,0x0,0xfe,0x2,0x4,0x0,0xfc,0x80,0x40,0x20,0x1c,0x8,0x0,
-+0x2,0x7f,0x0,0x3e,0x22,0x22,0x3e,0x0,0x7f,0x63,0x55,0x7f,0x49,0x49,0x49,0x43,0x10,0x10,0x10,0x14,0x7e,0x54,0x54,0x54,0x54,0x7c,0x54,0x10,0x10,0x14,0xfe,0x2,
-+0x10,0x10,0x17,0x14,0x59,0x52,0x54,0x91,0x12,0x14,0x1b,0x12,0x2a,0x26,0x43,0x82,0x80,0x40,0xfe,0x2,0x14,0x48,0xa4,0x10,0xe,0x4,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x40,0x30,0x17,0x4,0x89,0x62,0x24,0x1,0x12,0x24,0xeb,0x22,0x22,0x22,0x23,0x22,0x80,0x40,0xfe,0x2,0x14,0x48,0xa4,0x10,0xe,0x4,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x2,0x1,0x7f,0x40,0x84,0x9,0x12,0x4,0x8,0x10,0x2f,0xc8,0x8,0x8,0xf,0x8,0x0,0x0,0xfe,0x2,0x44,0x30,0x90,0x40,0x20,0x10,0xee,0x24,0x20,0x20,0xe0,0x20,
-+0x10,0x10,0x20,0x27,0x44,0xf9,0x11,0x21,0x47,0xf9,0x1,0x1,0x1a,0xe2,0x45,0x0,0x20,0x30,0x28,0xfe,0x20,0x24,0x24,0x28,0xe8,0x28,0x30,0x20,0x50,0x92,0xa,0x6,
-+0x0,0x0,0x7f,0x40,0x80,0xf,0x8,0x8,0x8,0x8,0x8,0x8,0x10,0x10,0x20,0x40,0x0,0x0,0xfe,0x2,0x44,0xe0,0x40,0x40,0x40,0x40,0x40,0x40,0x44,0x44,0x3c,0x0,
-+0x10,0x13,0x10,0x10,0xfb,0x10,0x11,0x1a,0x30,0xd7,0x10,0x11,0x11,0x12,0x54,0x20,0x0,0xf8,0x90,0x60,0xfc,0xa8,0x20,0x60,0x44,0xfe,0xe0,0x50,0x48,0x4e,0x44,0x40,
-+0x0,0x1f,0x2,0x1,0x7f,0x2,0x4,0x19,0x1,0xff,0x3,0x5,0x9,0x11,0x61,0x1,0x0,0xe0,0x40,0x80,0xfc,0x88,0x90,0x80,0x4,0xfe,0x80,0x40,0x20,0x1c,0x8,0x0,
-+0x1,0x1,0x1,0x7f,0x41,0x41,0x42,0x44,0x49,0x41,0x42,0x44,0x48,0x40,0x40,0x40,0x0,0x0,0x4,0xfe,0x4,0x4,0x84,0x64,0x24,0x4,0x84,0x64,0x24,0x4,0x14,0x8,
-+0x4,0x4,0xff,0x4,0x14,0x10,0xfe,0x22,0x22,0x22,0x42,0x24,0x14,0x8,0x14,0x62,0x40,0x44,0xfe,0x40,0x40,0x4,0xfe,0x84,0x84,0x84,0x84,0x84,0x84,0xfc,0x84,0x0,
-+0x20,0x23,0x20,0x27,0xfd,0xac,0xa9,0xa8,0xaf,0xf8,0xa3,0x22,0x2a,0xfa,0x4a,0x2,0x10,0xf8,0x40,0xfe,0x52,0xe4,0x50,0x40,0xfc,0x88,0xfc,0xa8,0xa8,0xa8,0xa8,0x18,
-+0x10,0x13,0x10,0x27,0x25,0x68,0xa1,0x20,0x2f,0x20,0x27,0x24,0x24,0x24,0x24,0x24,0x10,0xf8,0x40,0xfe,0x52,0xe4,0x50,0x44,0xfe,0x84,0xfe,0xa4,0xa4,0xa4,0xa4,0xc,
-+0x0,0xfb,0x8,0x17,0x25,0x28,0x21,0x28,0x37,0xe0,0x27,0x24,0x24,0x24,0xa4,0x44,0x10,0xf8,0x40,0xfe,0x52,0xe4,0x50,0x44,0xfe,0x84,0xfe,0xa4,0xa4,0xa4,0xa4,0xc,
-+0x10,0x10,0x10,0x10,0xfe,0x22,0x22,0x22,0x22,0x42,0x24,0x14,0x8,0x14,0x22,0x40,0x0,0x0,0x0,0x4,0xfe,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0xfc,0x84,0x0,
-+0x0,0x3f,0x20,0x2f,0x20,0x3f,0x29,0x28,0x4a,0x8c,0x0,0xff,0x4,0x2,0x0,0x0,0x10,0xf8,0x0,0xf0,0x0,0xfc,0x10,0xa0,0x60,0x1c,0x20,0xfe,0x20,0x20,0xa0,0x40,
-+0x2,0xf,0x70,0x29,0x2a,0x7f,0x2,0xc,0x8,0xb,0xc,0x38,0xc8,0x8,0x28,0x10,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x42,0x3e,0x0,
-+0x20,0x18,0x8,0x80,0x60,0x2f,0x1,0x9,0x12,0x24,0xe2,0x21,0x20,0x21,0x22,0x2c,0x80,0x80,0x80,0x80,0x84,0xfe,0x8,0x8,0x8,0x10,0x10,0x20,0xc0,0x20,0x18,0x8,
-+0x4,0x2,0x1,0x1,0x1,0x2,0x2,0x2,0x4,0x4,0x8,0x8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0xe,0x4,
-+0x20,0x13,0x12,0x3,0xfe,0xb,0x12,0x36,0x5a,0x94,0x10,0x17,0x11,0x10,0x10,0x10,0x8,0xfc,0x0,0xfc,0x0,0xfe,0xc4,0xa8,0x90,0xce,0x8,0xfe,0x8,0x88,0x28,0x10,
-+0x10,0x10,0x14,0xfe,0x20,0x29,0x48,0x7e,0x8,0x8,0xe,0xf8,0x48,0x8,0x9,0xa,0x40,0x40,0x40,0x7c,0x84,0x8,0x20,0x20,0x20,0x20,0x50,0x50,0x88,0x88,0x6,0x4,
-+0x0,0x7d,0x44,0x48,0x48,0x53,0x48,0x48,0x44,0x44,0x44,0x68,0x51,0x41,0x42,0x44,0x8,0xfc,0x0,0x0,0x4,0xfe,0x90,0x90,0x90,0x90,0x90,0x90,0x12,0x12,0xe,0x0,
-+0x8,0x8,0xff,0x8,0x2,0x29,0x29,0x48,0x7,0x10,0x8,0x20,0x66,0xa5,0x3c,0x0,0x20,0x24,0xfe,0x20,0x0,0x8,0x24,0x24,0xe0,0x20,0x10,0x40,0xcc,0x4a,0x78,0x0,
-+0x0,0x14,0xfc,0x24,0x24,0x27,0x20,0xff,0x20,0x27,0x24,0x24,0x3c,0xe4,0x44,0x4,0x40,0x44,0x44,0x44,0x44,0xfc,0x0,0xfe,0x84,0xfe,0xa4,0xa4,0xa4,0xa4,0xa4,0xc,
-+0x11,0x10,0x10,0x1c,0x21,0x21,0x7d,0x91,0x11,0x7c,0x10,0x10,0x15,0x19,0x12,0x4,0x4,0x88,0x50,0x4,0xfe,0x4,0x4,0x4,0xfc,0x90,0x90,0x90,0x12,0x12,0xe,0x0,
-+0x20,0x1b,0x8,0x40,0x5f,0x41,0x41,0x41,0x4f,0x41,0x41,0x41,0x5f,0x40,0x40,0x40,0x4,0xfe,0x4,0x24,0xf4,0x4,0x4,0x44,0xe4,0x4,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x4,0x43,0x31,0x14,0x85,0x44,0x44,0x14,0x15,0x24,0xe4,0x24,0x25,0x24,0x24,0x24,0x4,0x7e,0x4,0x24,0xf4,0x44,0x44,0x44,0xf4,0x44,0x44,0x44,0xf4,0x4,0x14,0x8,
-+0x8,0x8,0x7f,0x8,0xa,0x2,0xff,0x4,0x8,0x1f,0x28,0x48,0x88,0x8,0xf,0x8,0x20,0x28,0xfc,0x20,0x20,0x4,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0xf0,0x10,
-+0x0,0x7e,0x2,0x2,0x7e,0x40,0x40,0x7e,0x22,0x12,0x6,0x1a,0x62,0x22,0x2,0x4,0x4,0xfe,0x4,0x4,0xfc,0x80,0x84,0xfe,0x44,0x24,0xc,0x34,0xc4,0x44,0x14,0x8,
-+0x22,0x22,0x27,0x22,0xfa,0x2f,0x20,0x2f,0x34,0xe7,0x24,0x27,0x24,0x24,0xa5,0x44,0x90,0x90,0xd4,0x9e,0xa4,0xf4,0x14,0xd4,0x54,0xd4,0x48,0xc8,0x54,0x54,0x62,0x80,
-+0x0,0x40,0x3f,0x10,0x0,0x87,0x44,0x4c,0x14,0x24,0xe5,0x26,0x24,0x24,0x27,0x24,0x0,0x4,0xfe,0xa0,0xa4,0xfe,0xa4,0xa4,0xa4,0xa4,0x1c,0x4,0x4,0x4,0xfc,0x4,
-+0x4,0x4,0xff,0x4,0x7c,0x45,0x48,0x50,0x49,0x45,0x45,0x65,0x59,0x41,0x42,0x44,0x40,0x44,0xfe,0x40,0x20,0xfc,0x88,0x50,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x8,0x7d,0x49,0x49,0x49,0x79,0x49,0x49,0x49,0x78,0x48,0x4a,0x4a,0x4c,0x48,0x98,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x4,0x0,0x40,0xa4,0xa2,0x8a,0x88,0x78,
-+0x20,0x21,0x7d,0x89,0x11,0x7d,0x55,0x55,0x7d,0x54,0x54,0x7e,0x2,0x1c,0xe0,0x40,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x4,0x0,0x40,0xa4,0xa2,0x8a,0x88,0x78,
-+0x2,0x1,0x7f,0x44,0x9f,0x4,0x1f,0x4,0x7f,0x5,0x19,0x67,0x81,0x1,0x7f,0x0,0x0,0x0,0xfe,0x42,0xf4,0x40,0xf0,0x40,0xfc,0x40,0x30,0xce,0x4,0x10,0xf8,0x0,
-+0x1,0x7f,0x44,0x9f,0x4,0x1f,0x4,0x7f,0x8,0x1f,0x28,0xc9,0x9,0x1,0x6,0x18,0x0,0xfe,0x42,0xf4,0x40,0xf0,0x40,0xfc,0x20,0xf0,0x2e,0x24,0x20,0x0,0xc0,0x30,
-+0x0,0x0,0x7f,0x0,0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,
-+0x2,0x4,0x8,0x3f,0x2,0x2,0xff,0x4,0xf,0x10,0x20,0xcf,0x0,0x0,0x3f,0x0,0x0,0x40,0x20,0xf0,0x10,0x4,0xfe,0x40,0xe0,0x10,0x4e,0xe4,0x0,0x10,0xf8,0x0,
-+0x1,0x1,0x2,0x4,0x9,0x11,0x21,0xd1,0xd,0x5,0xff,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x80,0x40,0x20,0x10,0xe,0x14,0x30,0x44,0xfe,0x0,0x0,0x0,0x0,0x0,
-+0x24,0x24,0x7e,0x24,0x24,0xff,0x2,0x7f,0x42,0x7e,0x42,0x7e,0x42,0x42,0x4a,0x45,0x40,0x40,0x40,0x84,0xfe,0x8,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x48,0x8e,0x4,
-+0x1f,0x8,0x4,0x3,0x4,0x8,0x7f,0x24,0x18,0x66,0x1,0xff,0x5,0x19,0x61,0x1,0xf0,0x20,0x40,0x80,0x40,0x20,0xfc,0x48,0x30,0xcc,0x0,0xfe,0x40,0x30,0xc,0x0,
-+0x3,0x11,0xf8,0x91,0x92,0x97,0x94,0x93,0x94,0x90,0x9f,0x90,0xf1,0x92,0xc,0x0,0xf8,0x10,0xe0,0x10,0x8,0xbc,0xa4,0x18,0xa4,0x40,0xfe,0xe0,0x50,0x4e,0x44,0x40,
-+0x1,0x1,0x3f,0x1,0x11,0xd,0x5,0xff,0x10,0x12,0x11,0x10,0x10,0x14,0x18,0x10,0x0,0x10,0xf8,0x0,0x10,0x30,0x44,0xfe,0x10,0x20,0x40,0x80,0x40,0x30,0xe,0x4,
-+0x10,0x17,0x10,0x11,0xfc,0x11,0x16,0x18,0x33,0xd2,0x12,0x13,0x12,0x10,0x57,0x20,0x0,0xfc,0x48,0x10,0xe0,0x10,0x4e,0x48,0xfc,0x48,0x48,0xf8,0x40,0x48,0xfc,0x4,
-+0x8,0xff,0x9,0x48,0x48,0x48,0x4b,0x48,0x7d,0x5,0x1d,0xe5,0x45,0x4,0x15,0x8,0x0,0xfc,0x24,0x88,0x70,0x88,0x26,0x24,0xfe,0x24,0x24,0xfc,0x20,0x28,0xfc,0x4,
-+0x10,0x10,0x13,0x10,0xfc,0x10,0x14,0x19,0x30,0xd0,0x10,0x10,0x10,0x13,0x50,0x20,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,0x0,
-+0x10,0x11,0x11,0x11,0xfd,0x25,0x25,0x25,0x24,0x45,0x28,0x10,0x28,0x44,0x84,0x3,0xa0,0x2c,0x24,0x24,0xac,0x24,0x24,0xfc,0x20,0xfc,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x4,0x7e,0x8,0x8,0x3e,0x8,0x8,0x7e,0x2,0x1,0x11,0x50,0x51,0x96,0x18,0x6f,0x8,0xfc,0x20,0x20,0xf8,0x20,0x28,0xfc,0x0,0x20,0x40,0x84,0x2,0xa,0x8,0xf8,
-+0x4,0x4,0x7,0x8,0x8,0x1f,0x28,0x48,0x8,0xf,0x8,0x8,0x8,0x8,0x7,0x0,0x0,0x0,0xf0,0x20,0x48,0xfc,0x88,0x88,0x88,0xf8,0x8,0x0,0x2,0x2,0xfe,0x0,
-+0x20,0x1b,0x8,0x81,0x62,0x20,0x9,0x12,0x24,0xe2,0x22,0x22,0x22,0x22,0x2f,0x20,0x4,0xfe,0x44,0x44,0x44,0x84,0x14,0x8,0x40,0x48,0x7c,0x40,0x40,0x44,0xfe,0x0,
-+0x1,0x1,0x3f,0x3,0x5,0x19,0x61,0x9,0x8,0x7e,0x8,0x1c,0x2a,0xc9,0x8,0x8,0x0,0x8,0xfc,0x80,0x60,0x1c,0x8,0x20,0x28,0xfc,0x20,0x70,0xae,0x24,0x20,0x20,
-+0x12,0x11,0x17,0x24,0x25,0x64,0xa7,0x20,0x23,0x22,0x22,0x23,0x22,0x22,0x23,0x22,0x8,0x14,0xfe,0x44,0x54,0x44,0xfc,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x8,0x8,0xff,0x8,0x20,0x10,0x81,0x49,0x12,0x24,0xe0,0x20,0x20,0x20,0x23,0x2c,0x20,0x24,0xfe,0x20,0x40,0x40,0x48,0x46,0x42,0x48,0x50,0x20,0x40,0x80,0x0,0x0,
-+0x0,0x4,0xfe,0x10,0x10,0x20,0x20,0x3d,0x64,0xa4,0x24,0x24,0x24,0x3c,0x23,0xc,0x20,0x20,0x20,0x20,0xa8,0xa6,0xa2,0x20,0x24,0x28,0x10,0x20,0x40,0x80,0x0,0x0,
-+0x10,0x8,0x6,0x1,0x2,0xc,0x31,0x1,0xff,0x3,0x5,0x9,0x11,0x61,0x5,0x2,0x10,0x30,0xc0,0x0,0xc0,0x30,0x8,0x0,0xfe,0x80,0x40,0x20,0x1c,0x8,0x0,0x0,
-+0x20,0x11,0xa,0x4,0xa,0x11,0x64,0x4,0xff,0x4,0x15,0x14,0x24,0x44,0x14,0x8,0x84,0x84,0x24,0x24,0x24,0xa4,0xa4,0x24,0xe4,0x24,0x24,0x84,0x84,0x4,0x14,0x8,
-+0x0,0x20,0x18,0x8,0x81,0x61,0x22,0xa,0x14,0x20,0xe0,0x20,0x20,0x20,0x23,0x2c,0x40,0x40,0x40,0x40,0x50,0x48,0x46,0x42,0x48,0x48,0x50,0x20,0x40,0x80,0x0,0x0,
-+0x10,0x10,0x20,0x20,0x49,0xf9,0x12,0x22,0x44,0xf8,0x0,0x0,0x18,0xe0,0x43,0xc,0x40,0x40,0x40,0x40,0x50,0x48,0x46,0x42,0x48,0x48,0x50,0x20,0x40,0x80,0x0,0x0,
-+0x10,0x11,0x17,0x25,0x24,0x65,0xa7,0x22,0x25,0x29,0x23,0x24,0x28,0x20,0x23,0x2c,0x80,0x4,0xfe,0x14,0xe4,0x14,0xfc,0x8,0x6,0xfa,0x8,0x90,0x60,0x90,0xe,0x4,
-+0x0,0x8,0x7c,0x49,0x4b,0x4c,0x48,0x4f,0x48,0x48,0x4b,0x7a,0x4a,0x2,0x3,0x2,0x40,0x40,0xa0,0x10,0xfe,0x44,0x40,0xfc,0x40,0x48,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x1e,0x24,0x48,0xff,0x1,0x1,0x7f,0x1,0x1,0x7f,0x0,0x44,0x42,0x80,0x20,0x24,0x3e,0x44,0xa4,0x24,0x24,0x28,0x10,0x28,0x46,0x84,0x0,0x88,0x46,0x2,
-+0x12,0x1f,0x28,0x45,0x8,0x4b,0x48,0x49,0x49,0x49,0x49,0x49,0x11,0x11,0x20,0x40,0x48,0x7c,0xa0,0x10,0x4,0xfe,0x20,0xfc,0x24,0x24,0x24,0x24,0x34,0x28,0x20,0x20,
-+0x0,0x7,0x78,0x48,0x4b,0x4a,0x4a,0x7a,0x4a,0x4a,0x4a,0x4b,0x7a,0x4a,0x3,0x2,0x4,0xfe,0x90,0x94,0xfe,0x94,0x94,0x94,0x94,0x94,0x9c,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x17,0xfc,0x24,0x24,0x24,0xfc,0x2f,0x24,0x24,0x3c,0xe4,0x44,0x5,0x8,0x10,0x4,0xbe,0xa4,0xa4,0xa4,0xa4,0xa4,0xfe,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0x44,0x8c,
-+0x8,0x8,0xff,0x8,0x9,0x1,0x1,0x1,0x1,0x1f,0x10,0x10,0x10,0x10,0x1f,0x10,0x20,0x24,0xfe,0x20,0x20,0x8,0xfc,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x8,0x8,0x8,0x8,0xfe,0x8,0x18,0x1c,0x2a,0x2a,0x48,0x88,0x8,0x8,0x8,0x9,0x4,0x8,0x10,0x20,0xc0,0x4,0x8,0x10,0x20,0xc0,0x2,0x4,0x8,0x10,0x60,0x80,
-+0x1,0x1,0x1,0x1,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x7f,0x40,0x0,0x0,0x0,0x0,0x0,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,0x0,
-+0x0,0x7b,0x4a,0x4a,0x4a,0x4a,0x4a,0xff,0x4a,0x4a,0x4a,0x4a,0x4a,0x5a,0x42,0x84,0x44,0xe4,0x44,0x54,0x54,0x54,0x54,0xf4,0x54,0x54,0x54,0x54,0x44,0x44,0x54,0xc8,
-+0x10,0x10,0x13,0x16,0x5a,0x53,0x52,0x92,0x13,0x12,0x13,0x2a,0x25,0x44,0x89,0x0,0x40,0x24,0xfe,0x4,0x4,0xfc,0x0,0x44,0xfe,0x44,0x54,0xcc,0x54,0x44,0x54,0x88,
-+0x10,0x8,0x8,0xfe,0x2,0x4,0x8,0xa,0x1c,0x2a,0x48,0x8,0x8,0x8,0x8,0x9,0x4,0x8,0x10,0x20,0xc0,0x4,0x8,0x10,0x20,0xc0,0x2,0x4,0x8,0x10,0x60,0x80,
-+0x20,0x1b,0x8,0x40,0x41,0x41,0x41,0x41,0x42,0x42,0x44,0x48,0x40,0x40,0x40,0x40,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0x4,0x84,0x44,0x24,0x24,0x4,0x4,0x14,0x8,
-+0x0,0x78,0x48,0x57,0x50,0x62,0x51,0x48,0x4f,0x48,0x68,0x50,0x41,0x42,0x44,0x48,0x40,0x40,0x48,0xfc,0x40,0x48,0x50,0x44,0xfe,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,
-+0x10,0x17,0x10,0x13,0xfe,0x12,0x16,0x1b,0x30,0xd1,0x11,0x11,0x11,0x11,0x50,0x27,0x40,0xfe,0x0,0xfc,0x94,0xf4,0x94,0xfc,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xfe,
-+0x0,0x7c,0x45,0x57,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x2a,0x44,0x88,0x80,0xfc,0x8,0xfe,0x44,0x92,0xfe,0x0,0x7c,0x0,0x7c,0x0,0x7c,0x44,0x44,0x7c,
-+0x2,0x79,0x4f,0x48,0x4b,0x78,0x4f,0x4a,0x49,0x7f,0x48,0x4b,0x4a,0x4a,0x4b,0x9a,0x8,0x10,0xfc,0x40,0xf8,0x40,0xfc,0x48,0x50,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,
-+0x8,0x4,0x7f,0x1,0x3f,0x1,0x7f,0x9,0x5,0xff,0x0,0x1f,0x10,0x10,0x1f,0x10,0x20,0x48,0xfc,0x0,0xf8,0x0,0xfc,0x20,0x44,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x10,
-+0x0,0x40,0x30,0x10,0x84,0x64,0x24,0xc,0x14,0x24,0xe4,0x24,0x24,0x24,0x27,0x24,0x40,0x40,0x40,0x40,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0xfc,0x4,
-+0x2,0x1,0x3f,0x20,0x20,0x3f,0x20,0x20,0x3f,0x21,0x29,0x25,0x29,0x51,0x85,0x2,0x0,0x8,0xfc,0x8,0x8,0xf8,0x0,0x4,0x7e,0x4,0x24,0x14,0x24,0x44,0x14,0x8,
-+0x12,0x11,0x27,0x20,0x4b,0xf8,0x17,0x22,0x41,0xff,0x40,0x3,0x1a,0xe2,0x43,0x2,0x8,0x10,0xfc,0x40,0xf8,0x40,0xfc,0x48,0x50,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x17,0x11,0xfc,0x13,0x12,0x12,0x13,0x12,0x1e,0xf2,0x42,0x2,0x2,0x2,0x40,0x24,0xfe,0x8,0x94,0xfe,0x4,0x94,0xc,0xf4,0x94,0x94,0xf4,0x4,0x14,0x8,
-+0x9,0x9,0xa,0x13,0x14,0x38,0x50,0x97,0x10,0x10,0x10,0x11,0x11,0x12,0x14,0x18,0x0,0x0,0x4,0xfe,0x80,0x80,0x88,0xfc,0x88,0x88,0x88,0x8,0x8,0x8,0x50,0x20,
-+0x2,0x1,0xff,0x8,0x4,0x3f,0x20,0x24,0x28,0x37,0x24,0x24,0x24,0x27,0x20,0x20,0x0,0x4,0xfe,0x20,0x48,0xfc,0x8,0x48,0x28,0xd8,0x48,0x48,0x48,0xc8,0x28,0x10,
-+0x1,0x11,0x9,0x7f,0x40,0x8f,0x8,0xf,0x0,0x1f,0x10,0x11,0x11,0x2,0xc,0x30,0x0,0x10,0x20,0xfe,0x2,0xe4,0x20,0xe0,0x10,0xf8,0x10,0x10,0x10,0xc0,0x30,0x8,
-+0x0,0x8,0x7c,0x4b,0x4a,0x4a,0x4a,0x7a,0x4a,0x4a,0x4a,0x4a,0x7a,0x4a,0x2,0x2,0x20,0x40,0x84,0xfe,0x4,0x14,0xfc,0x94,0x94,0x94,0x94,0xf4,0x94,0x4,0x14,0x8,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x0,0x0,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x1,0x21,0x19,0x9,0x1,0x7f,0x40,0x40,0x4f,0x48,0x48,0x48,0x4f,0x48,0x40,0x40,0x0,0x8,0x18,0x20,0x4,0xfe,0x4,0x24,0xf4,0x24,0x24,0x24,0xe4,0x24,0x14,0x8,
-+0x1,0x9,0x5,0x7f,0x40,0x8f,0x8,0xf,0x1,0x7f,0x5,0xc,0x14,0x25,0x46,0x4,0x0,0x20,0x40,0xfe,0x2,0xe4,0x20,0xe0,0x8,0xfc,0x10,0xa0,0x40,0x20,0x1c,0x8,
-+0x10,0x11,0x10,0x10,0xfc,0x11,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11,0x11,0x20,0x24,0xa4,0xa8,0x24,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x4,0x14,0x8,
-+0x10,0x11,0x10,0x10,0xfc,0x11,0x15,0x19,0x11,0x31,0xd1,0x11,0x11,0x11,0x51,0x21,0x20,0x24,0xa4,0xa8,0x24,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x4,0x14,0x8,
-+0x8,0x1d,0xf0,0x10,0x10,0xfd,0x11,0x39,0x35,0x51,0x51,0x91,0x11,0x11,0x11,0x11,0x20,0x24,0xa4,0xa8,0x24,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x4,0x14,0x8,
-+0x10,0x10,0x10,0x14,0x5f,0x50,0x50,0x90,0x17,0x10,0x17,0x29,0x25,0x45,0x82,0xc,0x80,0x80,0x88,0xfc,0x80,0x50,0x22,0xd2,0xe,0x8,0xfc,0x20,0x20,0x22,0x22,0x1e,
-+0x4,0x4,0xff,0x4,0x10,0x1f,0x10,0x20,0x24,0x43,0x81,0x0,0x0,0x0,0x0,0x0,0x40,0x44,0xfe,0x40,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x50,0x20,
-+0x10,0x10,0x10,0x3f,0x20,0x40,0x80,0x4,0x2,0x3,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x10,0x8,0x7f,0x0,0x22,0x14,0xff,0x2,0x3f,0x22,0x22,0x3e,0x22,0x22,0x3e,0x22,0x4,0xfe,0x24,0x24,0x24,0x44,0x54,0x88,0x4,0xfe,0x84,0x84,0x84,0x84,0xfc,0x84,
-+0x1,0x1,0x1,0x9,0x9,0x11,0x11,0x21,0x41,0x1,0x1,0x0,0x1,0x2,0xc,0x70,0x0,0x0,0x0,0x20,0x10,0xc,0x4,0x10,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x0,0x9,0x7c,0x48,0x48,0x49,0x49,0x49,0x49,0x49,0x49,0x79,0x49,0x1,0x1,0x1,0x20,0x24,0xa4,0xa8,0x24,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x4,0x14,0x8,
-+0x2,0xff,0x22,0x22,0x22,0x42,0x4a,0x84,0x2,0x7f,0x42,0x42,0x42,0x7e,0x42,0x0,0x0,0xfc,0x84,0x84,0x88,0x88,0x90,0x88,0x84,0x82,0xc2,0xa2,0x94,0x88,0x80,0x80,
-+0x10,0x13,0x20,0x20,0x44,0xf9,0x11,0x22,0x44,0xfc,0x1,0x1,0x1d,0xe1,0x41,0x1,0x4,0xfe,0x84,0x84,0x84,0x4,0x4,0x14,0x8,0x4,0xfe,0x4,0x4,0x4,0xfc,0x4,
-+0x2,0x2,0xff,0x4,0xa,0x32,0xcf,0x2,0x7f,0x4,0xf,0x38,0xcf,0x8,0xf,0x8,0x0,0x8,0xfc,0x40,0x20,0x5e,0xe4,0x80,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,
-+0x4,0x7e,0x44,0x54,0x55,0x56,0x54,0x54,0x57,0x54,0x54,0x10,0x29,0x26,0x44,0x80,0x20,0x20,0x50,0x88,0x6,0xf8,0x0,0x4,0xfe,0x20,0x20,0xa8,0xa6,0x22,0xa0,0x40,
-+0x10,0x10,0x10,0x11,0x7d,0x56,0x54,0x54,0x54,0x7c,0x50,0x14,0x1c,0xe4,0x40,0x0,0x40,0x20,0x20,0xfe,0x2,0x4,0x80,0x88,0x98,0xa0,0xc0,0x80,0x82,0x82,0x7e,0x0,
-+0x0,0x0,0x1f,0x1,0x1,0xff,0x1,0x1,0x1,0x1f,0x10,0x10,0x10,0x10,0x1f,0x10,0x20,0xf0,0x0,0x0,0x4,0xfe,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0xf0,0x10,
-+0x1,0x1,0x2,0x4,0x8,0x37,0xc1,0x1,0x3f,0x1,0x1,0x1f,0x10,0x10,0x1f,0x10,0x0,0x0,0x80,0x40,0x30,0xce,0x4,0x10,0xf8,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,
-+0x8,0x8,0xa,0x7f,0x8,0xa,0xff,0x14,0x14,0x56,0x55,0x94,0x14,0x24,0x44,0x8c,0x20,0x20,0x20,0x24,0x7e,0x84,0x44,0x44,0x48,0x28,0x28,0x10,0x28,0x28,0x46,0x84,
-+0x10,0x13,0x11,0x11,0xfd,0x11,0x15,0x1b,0x30,0xd7,0x14,0x12,0x11,0x12,0x54,0x28,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0xfe,0x8,0xbc,0xa4,0xa8,0x10,0xa8,0x46,0x4,
-+0x8,0x12,0x3f,0x22,0x22,0x3f,0x22,0x3e,0x22,0x22,0xfe,0xa,0x12,0x22,0xca,0x4,0x8,0x8,0x8,0x8,0x8,0xfe,0x8,0x8,0x88,0x48,0x48,0x8,0x8,0x8,0x28,0x10,
-+0x10,0x13,0x11,0x59,0x55,0x51,0x91,0x17,0x10,0x17,0x14,0x12,0x11,0x12,0x14,0x18,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0xfe,0x8,0xbc,0xa4,0xa8,0x10,0xa8,0x46,0x4,
-+0x0,0x40,0x32,0x12,0x82,0x62,0x2f,0x8,0x10,0x22,0xe2,0x24,0x20,0x20,0x23,0x2c,0x40,0x48,0x7c,0x40,0x40,0x44,0xfe,0x40,0x44,0x44,0x48,0x50,0x20,0xc0,0x0,0x0,
-+0x20,0x10,0x10,0x0,0xfc,0xb,0x10,0x38,0x54,0x90,0x10,0x10,0x10,0x17,0x10,0x10,0x40,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,0x0,
-+0x1,0x21,0x11,0x11,0x1,0x2,0xf4,0x13,0x11,0x11,0x10,0x10,0x14,0x18,0x13,0xc,0xf0,0x10,0x10,0x10,0x10,0xe,0x0,0xf8,0x8,0x10,0x90,0xa0,0x40,0xb0,0xe,0x4,
-+0x0,0x4,0xfe,0x11,0x11,0x21,0x25,0x7f,0xa5,0x25,0x25,0x25,0x3d,0x24,0x0,0x0,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0xfc,0x24,0x20,0x20,0x20,
-+0x1,0x1,0x1,0x3f,0x21,0x21,0x21,0x3f,0x21,0x21,0x21,0x3f,0x21,0x1,0x1,0x1,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,
-+0x0,0x0,0x8,0x7d,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x79,0x49,0x0,0x0,0x0,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0xfc,0x24,0x20,0x20,0x20,
-+0x8,0x8,0x8,0x17,0x14,0x34,0x54,0x97,0x14,0x14,0x14,0x17,0x14,0x10,0x10,0x10,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0xfc,0x44,0x44,0x44,0xfc,0x44,0x40,0x40,0x40,
-+0x1,0x2,0xf,0x8,0xf,0x8,0xf,0x8,0x8,0x7f,0x0,0x0,0x3,0x1c,0xe0,0x0,0x0,0x10,0xf8,0x10,0xf0,0x10,0xf2,0x14,0x18,0xf0,0x50,0x90,0x10,0x10,0x50,0x20,
-+0x0,0x47,0x34,0x18,0x81,0x62,0x20,0x8,0x17,0x20,0xe1,0x22,0x2c,0x20,0x20,0x20,0x0,0xfe,0x2,0xa4,0x10,0x48,0x40,0x44,0xfe,0xe0,0x50,0x4e,0x44,0x40,0x40,0x40,
-+0x10,0x11,0x11,0x11,0xfd,0x25,0x25,0x25,0x25,0x45,0x29,0x12,0x2a,0x44,0x88,0x0,0x4,0xfe,0x0,0x8,0x7c,0x0,0x4,0xfe,0x54,0x58,0x50,0x48,0x48,0x56,0x64,0x40,
-+0x10,0x10,0x20,0x21,0x45,0xf9,0x11,0x21,0x41,0xfd,0x1,0x1,0x1d,0xe0,0x40,0x0,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0xfc,0x24,0x20,0x20,0x20,
-+0x20,0x10,0x10,0xfd,0x9,0x11,0x39,0x55,0x91,0x11,0x11,0x11,0x11,0x10,0x10,0x10,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0xfc,0x24,0x20,0x20,0x20,
-+0x0,0x40,0x30,0x17,0x84,0x68,0x20,0x9,0x11,0x21,0xe1,0x22,0x22,0x24,0x28,0x30,0x80,0x80,0x80,0xfc,0x84,0x88,0xc0,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x2,0x1,0x7f,0x41,0x81,0x3f,0x21,0x21,0x3f,0x21,0x21,0x3f,0x21,0x1,0x1,0x1,0x0,0x0,0xfe,0x2,0x4,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,
-+0x10,0x10,0x13,0x12,0xfc,0x25,0x25,0x25,0x25,0x45,0x29,0x11,0x29,0x44,0x80,0x0,0x40,0x20,0xfe,0x22,0x20,0xfc,0x24,0x24,0xfc,0x24,0x24,0xfc,0x24,0x20,0x20,0x20,
-+0x8,0x8,0xff,0x8,0xf,0x8,0xf,0x8,0x8,0xff,0x10,0x12,0x14,0x10,0x1f,0x0,0x20,0x28,0xfc,0x20,0xe0,0x20,0xe0,0x20,0x24,0xfe,0x0,0x20,0x10,0x0,0xf8,0x0,
-+0x8,0x4b,0x49,0x48,0x48,0x48,0x49,0x4a,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x10,0x0,0xf8,0x10,0xa0,0x40,0xa0,0x10,0xe,0xf4,0x10,0xf0,0x10,0xf0,0x10,0x50,0x20,
-+0x10,0x10,0x17,0x10,0x5b,0x56,0x53,0x92,0x13,0x12,0x13,0x12,0x1f,0x11,0x12,0x14,0x40,0x48,0xfc,0x40,0xf8,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x8,0xfe,0x10,0xc,0x4,
-+0x40,0x31,0x12,0x7,0x80,0x6f,0x21,0xa,0x14,0x29,0xe2,0x20,0x23,0x20,0x21,0x26,0x80,0x20,0x10,0xf8,0x80,0xfc,0x20,0x50,0x8e,0x24,0x40,0x90,0x20,0x40,0x80,0x0,
-+0x1,0x1,0xff,0x1,0x7f,0x0,0x3f,0x21,0x21,0x3f,0x20,0x20,0x20,0x40,0x40,0x80,0x0,0x4,0xfe,0x0,0xfc,0x8,0xfc,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x11,0x11,0x11,0x3f,0x21,0x41,0x41,0x81,0x3f,0x1,0x1,0x1,0x1,0xff,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x10,0x11,0x51,0x51,0x7d,0x91,0x11,0x11,0x7c,0x13,0x10,0x10,0x1c,0xf0,0x41,0x2,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x40,0xfc,0x44,0x44,0x84,0x84,0x28,0x10,
-+0x8,0x28,0x29,0x29,0x3f,0x4a,0x8c,0xa,0xd,0x38,0xc8,0x8,0x8,0xb,0x8,0x8,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x24,0xfe,0x0,0x0,
-+0x1,0x7,0x7c,0x4,0x4,0x4,0x4,0xff,0x4,0x4,0x4,0x8,0x8,0x10,0x20,0x0,0x20,0xa0,0x20,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x10,0x13,0x22,0x22,0x4b,0xf8,0x17,0x24,0x44,0xff,0x44,0x4,0x1f,0xe4,0x40,0x0,0x8,0xfc,0x8,0x8,0xf8,0x44,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x40,0x42,0x3e,
-+0x1,0x9,0x9,0x11,0x11,0x20,0x3,0xc,0x3f,0xc8,0xf,0x8,0xf,0x8,0xf,0x8,0x0,0x20,0x10,0xc,0x24,0xc0,0x0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x8,
-+0x0,0x0,0x3f,0x20,0x20,0x3e,0x22,0x22,0x4a,0x44,0x80,0x1f,0x12,0x12,0xff,0x0,0xa0,0x90,0xfc,0x80,0x88,0x88,0x50,0x50,0x22,0xd2,0xe,0xf0,0x90,0x94,0xfe,0x0,
-+0x3,0x3c,0x4,0xff,0x4,0x15,0x75,0x15,0x75,0xc,0x16,0x25,0x44,0x4,0x4,0x4,0x84,0x4,0x84,0xd4,0x14,0x14,0xd4,0x14,0xd4,0x14,0x14,0x94,0x84,0x4,0x14,0x8,
-+0x8,0x7c,0x49,0x49,0x49,0x79,0x4a,0x4c,0x48,0x79,0x48,0x48,0x48,0x48,0x4b,0x98,0x20,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x0,0x3f,0x10,0xc,0x2,0x1,0x2,0xc,0x31,0xc1,0x1f,0x1,0x1,0x1,0xff,0x0,0x0,0xf8,0x10,0x60,0x80,0x0,0xc0,0x30,0xe,0x24,0xf0,0x0,0x0,0x4,0xfe,0x0,
-+0x8,0xb,0x48,0x48,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x11,0x11,0x20,0x40,0x4,0xfe,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x34,0x28,0x20,0x20,
-+0x1,0x11,0x11,0x11,0x1f,0x21,0x41,0x1,0xff,0x1,0x2,0x2,0x4,0x8,0x10,0x60,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x0,0x80,0x80,0x40,0x30,0xe,0x4,
-+0x1,0x89,0x51,0x25,0x55,0x95,0x15,0x15,0x35,0x55,0x95,0x15,0x11,0x12,0x54,0x20,0x4,0xfe,0x10,0x10,0x7c,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x5c,0x10,0x10,
-+0x20,0x10,0x14,0xfe,0x21,0x22,0x3d,0x25,0x25,0x27,0x25,0x25,0x25,0x45,0x94,0x8,0x80,0x80,0x84,0xfe,0x20,0x20,0x24,0x3e,0xe4,0x24,0x34,0x28,0x22,0x2,0xfe,0x0,
-+0x0,0x47,0x34,0x14,0x87,0x64,0x24,0xf,0x11,0x21,0xe9,0x25,0x23,0x21,0x3f,0x20,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x20,0x20,0x24,0x28,0x30,0x24,0xfe,0x0,
-+0x0,0x20,0x13,0x10,0x0,0x7,0xf0,0x10,0x17,0x10,0x11,0x10,0x14,0x18,0x10,0x0,0x40,0x48,0xfc,0x40,0x44,0xfe,0x10,0x14,0xfe,0x10,0x10,0x90,0x10,0x10,0x50,0x20,
-+0x0,0x3f,0x20,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x0,0x3,0x7c,0x4,0x3f,0x24,0x24,0x24,0x3f,0x4,0x4,0x7,0x7c,0x20,0x10,0xf8,0x90,0xd0,0x10,0x90,0xd0,0x90,0x90,0x90,0x90,0x10,0x92,0xca,0x46,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0xff,0x2,0x2,0x4,0x4,0x8,0x1f,0x28,0x48,0x88,0x8,0x8,0xf,0x8,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x10,0x10,0xfd,0x12,0x15,0x1c,0x30,0xd3,0x12,0x12,0x12,0x12,0x53,0x22,0x40,0x40,0xa0,0xa0,0x10,0x8,0xf6,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x4,0x7e,0x44,0x47,0x44,0x44,0x7c,0x44,0x44,0x44,0x44,0x7c,0x44,0x0,0x0,0x8,0x8,0x8,0x8,0xfe,0x8,0x8,0x88,0x48,0x48,0x8,0x8,0x8,0x48,0x28,0x10,
-+0x8,0x8,0x8,0x10,0x10,0x30,0x5f,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x1,0x2,0x4,0xa,0x31,0xdf,0x10,0x1f,0x10,0x1f,0x10,0x13,0x10,0x14,0x18,0x10,0x0,0x80,0x40,0x30,0xe,0xf4,0x10,0xf0,0x10,0xf8,0x10,0x20,0xc0,0x30,0x18,0x8,
-+0x20,0x20,0x20,0x3d,0x25,0x49,0x41,0xa1,0x21,0x21,0x21,0x24,0x28,0x30,0x23,0x1,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0xfc,0x24,0x20,0x24,0x3e,0xc2,0x0,
-+0x2,0x1,0x7f,0x48,0x86,0x2,0x10,0xc,0x4,0xff,0x1,0x1,0x2,0x4,0x18,0x60,0x0,0x0,0xfe,0x2,0x84,0x80,0x80,0x80,0x84,0xfe,0x0,0x40,0x20,0x10,0xc,0x4,
-+0x20,0x13,0x12,0x2,0x2,0xf2,0x12,0x12,0x13,0x12,0x10,0x15,0x19,0x12,0x4,0x8,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,0x20,0x10,0x8,0x4,0x4,
-+0x1,0x1,0x1,0x3f,0x21,0x21,0x21,0x3f,0x21,0x9,0x5,0x2,0x5,0x8,0x30,0xc0,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,0x80,0x60,0x1e,0x4,
-+0x10,0x10,0x10,0x1f,0x11,0x21,0x41,0x1,0xff,0x1,0x2,0x2,0x4,0x8,0x10,0x60,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x4,0xfe,0x0,0x80,0x80,0x40,0x20,0x1c,0x8,
-+0x10,0x10,0x1f,0x20,0x27,0x64,0xa4,0x24,0x27,0x24,0x22,0x21,0x20,0x21,0x26,0x28,0x40,0x44,0xfe,0x40,0xfc,0x44,0x44,0x44,0xfc,0x44,0x40,0x80,0xc0,0x30,0xe,0x4,
-+0x0,0x3f,0x20,0x20,0x3f,0x20,0x24,0x22,0x3f,0x20,0x21,0x22,0x44,0x48,0x90,0x0,0x4,0xfe,0x4,0x4,0xfc,0x84,0x90,0xa4,0xfe,0x80,0xc0,0xa0,0x90,0x8e,0x84,0x80,
-+0x8,0xfc,0x8,0x49,0x49,0x49,0x49,0x49,0x7d,0x4,0x4,0x1c,0xe4,0x44,0x15,0xa,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xfc,0x20,0xa0,0x40,0x60,0x90,0xe,0x4,
-+0x10,0x10,0x10,0x10,0xfc,0x25,0x27,0x24,0x24,0x49,0x29,0x11,0x29,0x45,0x85,0x1,0x40,0x40,0x40,0x80,0x88,0x4,0xfe,0x2,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x3e,0x8,0x8,0x8,0x9,0xe,0x70,0x20,0x0,0x80,0xa0,0x90,0x84,0xfe,0x80,0x80,0x80,0x80,0x40,0x40,0x20,0x22,0x12,0xa,0x4,
-+0x0,0x3f,0x0,0x0,0x0,0x0,0xff,0x1,0x1,0x9,0x19,0x21,0x41,0x1,0x5,0x2,0x10,0xf8,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x20,0x18,0xc,0x4,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0xf8,0x0,
-+0x1,0x11,0x11,0x11,0x11,0xff,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x10,0x1f,0x0,0x10,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0xf0,0x10,0x0,0x8,0xfc,0x0,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x11,0x10,0x10,0x40,0x20,0x4,0xfe,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x34,0x28,0x20,0x20,
-+0x1,0x1,0xff,0x1,0x3f,0x21,0x3f,0x1,0x3f,0x1,0xff,0x1,0x3f,0x1,0x5,0x2,0x0,0x4,0xfe,0x0,0xf8,0x8,0xf8,0x0,0xf8,0x8,0xfe,0x8,0xf8,0x8,0x0,0x0,
-+0x10,0x10,0x10,0x10,0xff,0x10,0x14,0x1b,0x31,0xd1,0x11,0x11,0x11,0x17,0x52,0x20,0x20,0x28,0x24,0x20,0xfe,0x20,0x20,0xe0,0x20,0x10,0x10,0x10,0xd2,0x12,0xa,0x4,
-+0x8,0x7e,0x8,0x1c,0x68,0xa,0x19,0xff,0x0,0x3f,0x0,0x3f,0x0,0x1f,0x10,0x1f,0x8,0xf0,0x80,0xfc,0x90,0x90,0x14,0xfe,0x0,0xf8,0x0,0xf8,0x0,0xf0,0x10,0xf0,
-+0x2,0x42,0x22,0x2f,0x2,0x2,0xe3,0x26,0x2a,0x22,0x22,0x2b,0x24,0x50,0x8f,0x0,0x4,0x78,0x40,0xc0,0x40,0x7e,0x48,0x48,0x48,0x48,0x88,0x8,0x8,0x6,0xfc,0x0,
-+0x8,0x8,0x7d,0x8,0x1c,0xe9,0x8,0x29,0x12,0x2,0x7f,0x2,0x4,0x8,0x10,0x60,0x40,0x48,0xfc,0x48,0x48,0x88,0xca,0x2a,0x6,0x0,0xf8,0x8,0x8,0x88,0x50,0x20,
-+0xf,0x8,0x8,0xf,0x8,0x8,0xf,0x0,0xff,0x1,0x9,0x9,0x9,0x15,0x23,0x40,0xe0,0x20,0x20,0xe0,0x20,0x20,0xe0,0x4,0xfe,0x0,0x20,0xf0,0x0,0x0,0x6,0xfc,
-+0x0,0x0,0x7b,0x48,0x4f,0x48,0x49,0x4a,0x4c,0x48,0x4b,0x7a,0x4b,0x2,0x3,0x2,0x80,0x88,0xf0,0xa4,0xfe,0x80,0xf0,0x82,0x7e,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,
-+0x2,0x2,0x7b,0x4d,0x48,0x48,0x4f,0x48,0x4a,0x4a,0x4a,0x7d,0x48,0x0,0xf,0x0,0x10,0x10,0xde,0x28,0x84,0x0,0xfc,0x40,0x48,0x48,0x48,0x54,0xe2,0x40,0xfe,0x0,
-+0x0,0x47,0x30,0x10,0xf,0x0,0xf0,0x13,0x12,0x12,0x12,0x13,0x12,0x28,0x47,0x0,0x38,0xc0,0x40,0x44,0xfe,0x40,0x48,0xfc,0x8,0x8,0x8,0xf8,0x8,0x6,0xfc,0x0,
-+0x8,0x8,0x8,0x10,0x10,0x3f,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x17,0x10,0x10,0x40,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x48,0xfc,0x0,0x0,
-+0x8,0x8,0x8,0x17,0x10,0x30,0x5f,0x90,0x10,0x17,0x10,0x12,0x11,0x11,0x10,0x10,0x40,0x40,0x48,0xfc,0x40,0x44,0xfe,0x10,0x10,0xfc,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x4,0xf9,0x10,0x54,0x38,0x10,0xfe,0x13,0x30,0x39,0x54,0x50,0x93,0x10,0x10,0x10,0x0,0xfc,0x88,0x50,0x20,0x50,0x8e,0x24,0x20,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,
-+0x20,0x20,0x20,0x3c,0x25,0x4a,0x41,0xa1,0x21,0x21,0x21,0x25,0x29,0x31,0x20,0x0,0x80,0x80,0x84,0xfe,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x34,0x28,0x20,0x20,
-+0x0,0x20,0x3f,0x21,0x21,0x21,0x21,0x3f,0x20,0x20,0x20,0x24,0x28,0x30,0x60,0x0,0x20,0xf0,0x0,0x0,0x0,0x0,0x8,0xfc,0x80,0x80,0x40,0x40,0x22,0x12,0xa,0x6,
-+0x2,0x1,0x0,0xff,0x1,0x1,0x3f,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x1,0x1,0x0,0x0,0x4,0xfe,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0x28,0x10,0x0,0x0,
-+0x10,0x10,0x10,0x13,0x58,0x54,0x57,0x90,0x10,0x17,0x10,0x12,0x11,0x11,0x10,0x10,0x40,0x40,0x48,0xfc,0x40,0x44,0xfe,0x10,0x10,0xfc,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x2,0x1,0x7f,0x40,0x80,0x3f,0x4,0x8,0x1f,0x1,0x1,0x1f,0x1,0x1,0x7f,0x0,0x0,0x0,0xfe,0x2,0x14,0xf8,0x0,0x20,0xf0,0x10,0x0,0xf0,0x0,0x8,0xfc,0x0,
-+0x20,0x13,0x12,0x2,0xfe,0xa,0x12,0x32,0x5a,0x96,0x12,0x10,0x11,0x11,0x12,0x14,0x8,0xfc,0x8,0x48,0x48,0x48,0x48,0x48,0x48,0x68,0xa8,0xa0,0x22,0x22,0x1e,0x0,
-+0x0,0x40,0x20,0x20,0xf,0x0,0xe0,0x27,0x21,0x21,0x21,0x21,0x29,0x37,0x22,0x0,0x20,0x28,0x24,0x20,0xfe,0x20,0x20,0xe0,0x20,0x10,0x10,0x10,0xd2,0x12,0xa,0x4,
-+0x8,0x8,0x8,0x48,0x48,0x49,0x49,0x4a,0x48,0x58,0x68,0x48,0x8,0x8,0x9,0xe,0x80,0x80,0x80,0x84,0xfe,0x8,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x0,0x0,0x7f,0x1,0x1,0x3f,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x5,0x2,0x10,0xf8,0x0,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x8,0x4,0xff,0x1,0x2,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x20,0x44,0xfe,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x2,0x1,0x7f,0x40,0x80,0x0,0x0,0x7f,0x0,0x8,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0xfe,0x2,0x24,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x2,0x2,0x7f,0x2,0x3f,0x4,0xff,0x8,0x8,0x17,0x10,0x22,0x41,0x81,0x0,0x0,0x0,0x8,0xfc,0x0,0xf8,0x0,0xfe,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x10,0x13,0x10,0x11,0xfc,0x13,0x12,0x1c,0x31,0xd1,0x10,0x10,0x10,0x10,0x51,0x26,0xc,0xf0,0x0,0x24,0xa8,0xfe,0x2,0x4,0xfc,0x4,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x9,0x8,0xf,0x10,0x3f,0x50,0x9f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x10,0x1f,0x10,0x0,0x88,0xfc,0x80,0xf8,0x80,0xf8,0x80,0xfe,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x3f,0x11,0x9,0x9,0x7f,0x40,0x80,0x1f,0x8,0x4,0x2,0x1,0x6,0x18,0x60,0x78,0x80,0x10,0x10,0x20,0xfe,0x2,0x4,0xf0,0x20,0x40,0x80,0x0,0xc0,0x3c,0x8,
-+0x1,0x0,0x3f,0x22,0xac,0x68,0x2e,0x28,0x2f,0x60,0xaf,0x22,0x21,0x40,0x83,0x1c,0x0,0x88,0xfc,0x80,0xb8,0x88,0xb8,0x88,0xf8,0x80,0xf0,0x20,0x40,0x80,0x60,0x1c,
-+0x8,0x4,0x3f,0x21,0x3f,0x21,0x3f,0x0,0xff,0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x20,0x48,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfe,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,
-+0x4,0x4,0xff,0x4,0x0,0xfd,0x8,0x10,0x51,0x5c,0x50,0x50,0x5e,0xf0,0x41,0x2,0x40,0x44,0xfe,0x40,0x24,0xfe,0x40,0x88,0xfc,0x0,0xa8,0xa8,0xaa,0xaa,0x26,0x0,
-+0x10,0x13,0x12,0x12,0xfe,0x12,0x32,0x3a,0x56,0x52,0x92,0x12,0x12,0x12,0x13,0x10,0x8,0xfc,0x0,0x8,0x88,0x50,0x50,0x20,0x20,0x50,0x48,0x88,0x0,0x4,0xfe,0x0,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x30,0x39,0x54,0x50,0x90,0x10,0x10,0x11,0x12,0x14,0x40,0x20,0x24,0xfe,0x20,0x40,0x88,0xfc,0x0,0xa8,0xa8,0xa8,0xaa,0x2a,0x26,0x20,
-+0x0,0xa,0xfe,0x23,0x22,0x3c,0x48,0x4f,0x48,0xb0,0x11,0x22,0x44,0x88,0x0,0x0,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0xc0,0xe0,0x50,0x4e,0x44,0x40,0x40,0x40,
-+0x10,0x13,0x10,0x10,0xfc,0x10,0x17,0x18,0x30,0xd0,0x10,0x10,0x10,0x10,0x51,0x20,0x0,0xf8,0x10,0xa0,0x40,0x40,0xfe,0x42,0x44,0x40,0x40,0x40,0x40,0x40,0x40,0x80,
-+0x20,0x20,0x28,0xfd,0x22,0x45,0x50,0x93,0xfa,0x13,0x3a,0xd3,0x12,0x12,0x12,0x12,0x40,0xa0,0xa0,0x10,0xe,0xf4,0x0,0xc4,0x54,0xd4,0x54,0xd4,0x54,0x44,0x44,0xcc,
-+0x8,0xa,0xf,0x8,0x8,0xa,0xff,0x8,0x8,0x2c,0x2b,0x49,0x48,0x88,0x29,0x12,0x0,0x0,0x0,0xfc,0x84,0x84,0x48,0x48,0x48,0x50,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x8,0x8,0x14,0x22,0x41,0xbe,0x9,0x8,0x7f,0xa,0x3f,0x22,0x22,0x22,0x3e,0x22,0x0,0xfc,0x4,0x48,0x28,0x10,0xfe,0x12,0x14,0x10,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x2,0x42,0x33,0x12,0x82,0x62,0x2f,0xa,0x12,0x27,0xea,0x32,0x22,0x2a,0x24,0x21,0x0,0x0,0x80,0x7c,0x44,0x44,0xc4,0x44,0x28,0x28,0x90,0x10,0x28,0x46,0x84,0x0,
-+0x0,0x0,0x3c,0xb,0x10,0x10,0x10,0x5d,0x50,0x50,0x50,0x50,0x5c,0xf1,0x42,0x4,0x40,0x20,0x24,0xfe,0x20,0x40,0x88,0xfc,0x0,0xa8,0xa8,0xa8,0xaa,0x2a,0x26,0x20,
-+0x2,0x2,0x2,0x7f,0x2,0x2,0x2,0x2,0xff,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x0,0x10,0xc,0xe4,0x20,0x20,0x20,0x20,0xfc,0x4,0x4,0x4,0x4,0x28,0x10,0x0,
-+0x4,0x7e,0x45,0x54,0x54,0x57,0x54,0x54,0x55,0x54,0x54,0x55,0x28,0x24,0x44,0x83,0x20,0x28,0xfc,0x20,0x20,0xfe,0x82,0x54,0x10,0x90,0x14,0xfe,0x20,0x50,0x8c,0x4,
-+0x10,0xa,0xff,0x0,0x7f,0x42,0x7e,0x0,0x7e,0x4,0x8,0x1e,0xe8,0x9,0x2a,0x14,0x40,0x40,0x40,0x48,0xfc,0x48,0x48,0x48,0xc8,0x68,0x58,0x88,0x89,0x9,0x3,0x0,
-+0x8,0xff,0x0,0x7e,0x42,0x7e,0x0,0x7e,0x4,0x8,0x7c,0x9,0x1a,0x44,0x42,0x82,0x40,0x40,0x48,0xfc,0x48,0x48,0xc8,0x48,0xa8,0x8a,0x8a,0x6,0x0,0x88,0x46,0x42,
-+0x4,0xff,0x4,0x3f,0x24,0x3f,0x2,0x3f,0x2,0xff,0xc,0x1f,0x30,0xdf,0x10,0x1f,0x44,0xfe,0x40,0xf8,0x48,0xf8,0x20,0xf0,0x84,0xfe,0x0,0xf8,0x8,0xf8,0x8,0xf8,
-+0x1f,0x10,0x1f,0x10,0x1f,0x2,0x3f,0x2,0xff,0x4,0xf,0x38,0xcf,0x8,0xf,0x8,0xf0,0x10,0xf0,0x14,0xf8,0x20,0xf0,0x84,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,
-+0x0,0xb,0x7e,0x4a,0x4b,0x48,0x4b,0x78,0x4f,0x48,0x49,0x49,0x7b,0x4d,0x1,0x1,0x4,0xfe,0x94,0x94,0xfc,0x48,0xfc,0x50,0xfe,0x40,0xfc,0x4,0xfc,0x4,0xfc,0x4,
-+0x3f,0x24,0x24,0x3f,0x2,0x3f,0x2,0xff,0x3,0xc,0x3f,0xc8,0xf,0x8,0xf,0x8,0xf8,0x48,0x48,0xf8,0x20,0xf0,0x44,0xfe,0x0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,
-+0x0,0x3f,0x24,0x24,0x3f,0x10,0x3f,0x42,0xbf,0x22,0x22,0x3f,0x2,0x3,0x7e,0x20,0x8,0xfc,0x48,0x48,0xf8,0x4,0xfe,0x4,0xe4,0x24,0x24,0xe4,0x24,0xf4,0x14,0x8,
-+0x0,0x3f,0x1,0xff,0x5,0x9,0x32,0x4,0x9,0x39,0xc5,0x3,0xd,0x31,0x5,0x2,0xf0,0x0,0x4,0xfe,0x40,0x30,0x90,0x40,0x30,0x2e,0x44,0x80,0x60,0x18,0x8,0x0,
-+0xc,0x71,0x40,0x7c,0x40,0x7f,0x2,0x52,0x4a,0x42,0x52,0x4a,0x42,0x73,0xc6,0x0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0x90,0x50,0x10,0x90,0x50,0x10,0x8a,0xa,0x6,
-+0x3f,0x20,0x3f,0x20,0x2f,0x20,0x2f,0x28,0x2f,0x20,0x3f,0x50,0x50,0x57,0x90,0x10,0xf8,0x8,0xf8,0x0,0xf8,0x80,0xf8,0x88,0xf8,0x84,0xfe,0x84,0x94,0xf4,0x14,0x8,
-+0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x3,0x5,0x9,0x11,0x21,0xc1,0x1,0x1,0x1,0x0,0x40,0x30,0x10,0x4,0xfe,0x0,0x80,0x40,0x20,0x10,0xe,0x4,0x0,0x0,0x0,
-+0x0,0x40,0x20,0x20,0xf,0x0,0xe1,0x22,0x24,0x28,0x20,0x20,0x20,0x50,0x8f,0x0,0x80,0xa0,0x90,0x80,0xfc,0x80,0xc0,0xa0,0x98,0x88,0x80,0x80,0x80,0x6,0xfc,0x0,
-+0x10,0x10,0x10,0x17,0xfc,0x14,0x32,0x3a,0x51,0x51,0x92,0x12,0x14,0x18,0x10,0x10,0x8,0x8,0x8,0xc8,0x7e,0x48,0x88,0xa8,0x18,0x8,0x88,0x48,0x48,0x8,0x28,0x10,
-+0x1,0x1,0xff,0x1,0x1,0x3f,0x21,0x21,0x21,0x3f,0x23,0x5,0x9,0x31,0xc1,0x1,0x0,0x4,0xfe,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x88,0x40,0x30,0xe,0x4,0x0,
-+0x0,0x0,0x0,0x3f,0x20,0x20,0x20,0x28,0x26,0x22,0x20,0x20,0x20,0x21,0x42,0x84,0x80,0xa0,0x90,0xfc,0x80,0x80,0x88,0x48,0x50,0x50,0x20,0x60,0x90,0x12,0xa,0x6,
-+0x4,0x25,0x25,0x24,0x24,0x24,0x24,0x24,0x7,0x1,0x3f,0x8,0x8,0x4,0xff,0x0,0x0,0xfc,0x4,0x88,0x50,0x20,0x50,0x8e,0x4,0x10,0xf8,0x20,0x20,0x44,0xfe,0x0,
-+0x7f,0x49,0x7f,0x49,0x7f,0x8,0x7f,0x8,0xf,0x79,0x1,0x3f,0x1,0x1,0xff,0x0,0x7c,0x4,0x28,0x10,0xfe,0x12,0x14,0x10,0x50,0x20,0x0,0xf8,0x0,0x4,0xfe,0x0,
-+0x1,0x0,0x3f,0x20,0x22,0x22,0x3f,0x22,0x22,0x22,0x23,0x22,0x40,0x4a,0x89,0x11,0x0,0x84,0xfe,0x0,0x20,0x24,0xfe,0x20,0x20,0x20,0xe0,0x20,0x0,0x48,0x26,0x22,
-+0x8,0x49,0x2a,0x8,0xff,0x19,0x2c,0x4a,0x10,0xfe,0x22,0x22,0x14,0x18,0x25,0x42,0x40,0x40,0x40,0x84,0xfe,0x8,0x88,0x88,0x88,0x90,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x2,0x42,0x3f,0x22,0x82,0x4f,0x4a,0xa,0x1f,0x22,0xe7,0x2a,0x32,0x22,0x22,0x23,0x10,0x90,0xd0,0x10,0xbe,0xc2,0x94,0x90,0x90,0x10,0x10,0xa8,0x28,0x48,0x86,0x4,
-+0x10,0x10,0x10,0xfe,0x22,0x22,0x14,0x8,0x14,0x62,0x0,0x2a,0x29,0x28,0x48,0x7,0x0,0x0,0x8,0xfc,0x88,0x88,0x88,0x88,0xf8,0x88,0x0,0x10,0x88,0xa4,0x24,0xe0,
-+0x0,0x3f,0x20,0x20,0x3f,0x22,0x22,0x3f,0x32,0x32,0x52,0x52,0x53,0x92,0x2,0x2,0x44,0xe4,0x44,0x54,0xd4,0x14,0x54,0xf4,0x54,0x54,0x54,0x54,0x44,0x84,0x14,0x8,
-+0x0,0x7f,0x2,0x3f,0x24,0x24,0x24,0x22,0x2,0xff,0x4,0x8,0x4,0x3,0xc,0x30,0x8,0xfc,0x0,0xf8,0x48,0x48,0x48,0x18,0x4,0xfe,0x20,0x20,0x40,0x80,0x60,0x10,
-+0x10,0x10,0x13,0x10,0xfc,0x12,0x15,0x1a,0x30,0xd0,0x17,0x10,0x10,0x10,0x50,0x20,0x40,0x24,0xfe,0x20,0x48,0xf2,0x24,0x52,0xf8,0x20,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x2,0x1,0x7f,0x0,0x1f,0x10,0xff,0x10,0x1f,0x4,0x9,0x18,0x28,0x4a,0x8c,0x8,0x0,0x8,0xfc,0x0,0xf0,0x14,0xfe,0x10,0xf0,0x8,0x10,0xa0,0x40,0x30,0xe,0x4,
-+0x0,0x3f,0x21,0x21,0x21,0x3f,0x21,0x21,0x21,0x3f,0x21,0x21,0x21,0x21,0x41,0x80,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x28,0x12,0x2,0xfe,
-+0x8,0x8,0x48,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x9,0x11,0x11,0x20,0x40,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x34,0x28,0x20,0x20,
-+0x10,0x10,0x10,0x11,0xfe,0x14,0x33,0x38,0x54,0x50,0x97,0x10,0x10,0x10,0x1f,0x10,0x40,0x40,0xa0,0x10,0xe,0x4,0xf8,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x0,
-+0x10,0x10,0x10,0x11,0xfe,0x14,0x13,0x1c,0x30,0xd0,0x17,0x10,0x10,0x10,0x5f,0x20,0x40,0x40,0xa0,0x10,0xe,0x4,0xf8,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x0,
-+0x1f,0x1,0x7f,0x41,0x9d,0x1,0x1d,0x8,0x8,0x7e,0x8,0x1c,0x2a,0x48,0x8,0x8,0xf0,0x0,0xfe,0x2,0x74,0x0,0x70,0x4,0xfe,0x84,0xfc,0x84,0xfc,0x84,0xfc,0x84,
-+0x0,0x0,0xfd,0x4,0x44,0x44,0x28,0x28,0x10,0x10,0x28,0x28,0x44,0x44,0x81,0x6,0x0,0x4,0xfe,0x84,0x84,0x84,0x88,0x48,0x48,0x50,0x20,0x30,0x50,0x88,0xe,0x4,
-+0x1,0x1,0xff,0x1,0x29,0x11,0x29,0x1,0x29,0x11,0x29,0x2,0x4,0x8,0x30,0xc0,0x0,0x4,0xfe,0x0,0x28,0x10,0x28,0x0,0x28,0x10,0x28,0x80,0x40,0x30,0xe,0x4,
-+0x0,0x20,0x11,0x11,0x3,0x5,0xf1,0x11,0x11,0x11,0x11,0x11,0x15,0x19,0x11,0x1,0x80,0xa0,0x14,0xfe,0x10,0x10,0xfc,0x10,0x10,0xfc,0x10,0x10,0x14,0xfe,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x7d,0x5,0x5,0x9,0x9,0x11,0x21,0x41,0x81,0x5,0x2,0x0,0x0,0x0,0x8,0x18,0x20,0xc0,0x80,0x40,0x20,0x10,0xe,0x4,0x0,0x0,0x0,
-+0x0,0x8,0x7b,0x48,0x48,0x4f,0x79,0x49,0x4f,0x79,0x49,0x49,0x4f,0x78,0x48,0x3,0x0,0x18,0xe0,0x40,0x48,0xfc,0x50,0x54,0xfe,0x50,0x50,0x50,0xfc,0x40,0x50,0xf8,
-+0x8,0x1d,0xf0,0x10,0x11,0xfd,0x11,0x39,0x35,0x51,0x90,0x10,0x10,0x10,0x11,0x12,0x0,0x4,0x88,0x50,0xfc,0x4,0x4,0x4,0xfc,0x54,0x50,0x50,0x92,0x92,0xe,0x0,
-+0x0,0x8,0x7c,0x48,0x49,0x4b,0x48,0x48,0x48,0x48,0x49,0x79,0x4a,0x2,0x4,0x8,0x40,0x40,0x80,0x80,0x8,0xfc,0x94,0x90,0x90,0x90,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x0,0x8,0x7f,0x49,0x48,0x4b,0x7a,0x4d,0x49,0x7a,0x4d,0x48,0x48,0x79,0x4a,0x0,0x8,0x3c,0xc0,0x24,0xa8,0xfe,0x2,0x4,0xde,0x44,0x54,0x94,0xbe,0x4,0x4,0x4,
-+0x0,0x47,0x54,0x54,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0x44,0x84,0x3,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x20,0x58,0x84,0x2,
-+0x0,0x3f,0x11,0x9,0x7f,0x48,0x88,0x1e,0x12,0x22,0x54,0xd,0x8,0x10,0x20,0x40,0x78,0x80,0x10,0x20,0xfe,0x22,0x24,0xf8,0x20,0xa0,0xa8,0xfc,0x20,0x20,0x20,0x20,
-+0x0,0x22,0x11,0x10,0x3,0x2,0xf2,0x12,0x13,0x12,0x10,0x10,0x15,0x19,0x12,0x4,0x0,0x8,0x10,0xa0,0xf8,0x8,0x8,0x8,0xf8,0xa8,0xa0,0xa0,0x22,0x22,0x1e,0x0,
-+0x8,0xfd,0x10,0x10,0x21,0x25,0x3f,0x65,0xa5,0x25,0x25,0x25,0x3c,0x24,0x0,0x3,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x20,0x58,0x84,0x2,
-+0x41,0x22,0x14,0xff,0x8,0x49,0x49,0x49,0x49,0x49,0x7f,0x9,0x8,0x10,0x21,0x42,0x4,0x7e,0x44,0xc4,0x44,0x7c,0x44,0x44,0x44,0x7c,0x44,0x44,0x84,0x84,0x14,0x8,
-+0x10,0x10,0x13,0x16,0x5a,0x52,0x52,0x93,0x10,0x10,0x10,0x29,0x26,0x44,0x80,0x0,0x8,0x1c,0xe0,0x0,0x20,0x20,0x24,0xfe,0x20,0x20,0xa8,0x24,0x22,0x22,0xa0,0x40,
-+0x22,0x22,0x7f,0x22,0x22,0x3e,0x22,0x22,0x3e,0x22,0x22,0xff,0x0,0x15,0x22,0x40,0x8,0x1c,0x60,0x40,0x40,0x40,0x7e,0x48,0x48,0x48,0x48,0x48,0x88,0x8,0x8,0x8,
-+0x24,0x24,0x2f,0x24,0xfc,0x27,0x2c,0x34,0x27,0xe4,0x24,0x3f,0x20,0x24,0xa8,0x40,0x80,0x8c,0xf0,0xa0,0xa0,0xa4,0xbe,0xa8,0xa8,0xa8,0xa8,0xe8,0x28,0xa8,0x48,0x8,
-+0x4,0x14,0x7f,0x54,0x54,0x57,0x54,0x54,0x57,0x54,0x54,0x7f,0x50,0x4,0x8,0x0,0x80,0x8c,0xf0,0xa0,0xa0,0xa4,0xbe,0xa8,0xa8,0xa8,0xa8,0xe8,0x28,0xa8,0x48,0x8,
-+0x0,0x3f,0x21,0x21,0x21,0x3f,0x21,0x21,0x21,0x3f,0x20,0x2,0x51,0x50,0x90,0xf,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x0,0x88,0x96,0x12,0xf0,
-+0x4,0xe,0xf8,0x8,0xa,0xff,0x8,0x1c,0x1a,0x28,0x48,0x89,0x9,0xb,0x8,0x8,0x20,0x20,0x20,0x20,0x40,0x40,0x40,0x40,0x80,0x80,0x80,0x8,0x4,0xfe,0x2,0x0,
-+0x0,0x3f,0x0,0x0,0xff,0x0,0x0,0x3f,0x20,0x20,0x20,0x20,0x3f,0x20,0x0,0x0,0x8,0xfc,0x8,0x48,0xe8,0x8,0x88,0xc8,0x88,0x88,0x88,0x88,0x88,0x88,0x28,0x10,
-+0x8,0x8,0x8,0x10,0x10,0x22,0x7e,0x4,0x8,0x10,0x20,0x7e,0x0,0x0,0xff,0x0,0x10,0x10,0x10,0x20,0x20,0x44,0xfc,0x8,0x10,0x20,0x40,0xfc,0x0,0x4,0xfe,0x0,
-+0x0,0xff,0x8,0x8,0x10,0x1f,0x21,0x21,0x62,0x92,0xc,0x4,0x8,0x10,0x20,0x40,0x4,0xfe,0x40,0x40,0x40,0x44,0x4c,0x50,0x60,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x4,0x3e,0x21,0x24,0x3f,0x20,0x25,0x3e,0x20,0x21,0xff,0x10,0x25,0x7e,0x2,0x0,0x20,0x20,0xfc,0x24,0xfe,0x24,0xfc,0x20,0x28,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,
-+0x1,0x1,0x7f,0x1,0x1,0x1,0xff,0x0,0x0,0x7f,0x8,0x4,0x4,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x4,0xfe,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x2,0x3f,0x22,0x22,0x3e,0x0,0x7f,0x55,0x55,0x55,0x7f,0x55,0x55,0x55,0x55,0x43,0x4,0x7e,0x4,0x4,0xfc,0x4,0x74,0x54,0x54,0x54,0x54,0x54,0x74,0x4,0x14,0x8,
-+0x0,0x0,0x7f,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x48,0x50,0x40,0x7f,0x40,0x0,0x0,0x4,0xfe,0x44,0x44,0x44,0x44,0x44,0x44,0x3c,0x4,0x4,0x4,0xfc,0x4,0x0,
-+0x8,0xb,0x8,0x10,0x17,0x30,0x50,0x93,0x12,0x12,0x12,0x12,0x13,0x12,0x10,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x24,0xf4,0x24,0x24,0x24,0x24,0xe4,0x4,0x14,0x8,
-+0x10,0x11,0x10,0x20,0x24,0x64,0xa4,0x24,0x24,0x24,0x24,0x25,0x26,0x24,0x20,0x21,0x0,0x8,0x88,0x48,0x48,0x8,0x8,0x8,0x8,0x10,0x90,0x20,0x28,0x46,0x82,0x0,
-+0x20,0x23,0x20,0x3c,0x27,0x48,0x40,0xa3,0x22,0x22,0x22,0x26,0x2b,0x32,0x20,0x0,0x4,0xfe,0x4,0x24,0xf4,0x4,0x4,0xf4,0x24,0x24,0x24,0x24,0xe4,0x4,0x14,0x8,
-+0x0,0x7f,0x40,0x40,0x40,0x40,0x7f,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x3f,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x10,0x10,0x10,0xfd,0x11,0x39,0x36,0x54,0x50,0x90,0x10,0x11,0x13,0x10,0x10,0x10,0x90,0x90,0x90,0x8,0x8,0x4,0x42,0x40,0x40,0x80,0x88,0x4,0xfc,0x4,0x0,
-+0x8,0x8,0x18,0x24,0x43,0x82,0x7f,0x10,0x1f,0x10,0x1f,0x10,0x10,0xff,0x0,0x0,0x20,0x20,0x50,0x88,0x6,0x0,0xfc,0x10,0xf0,0x10,0xf0,0x14,0xfe,0x10,0x10,0x10,
-+0x8,0x8,0x8,0x8,0x14,0x14,0x22,0x22,0x41,0x80,0x2a,0x29,0x28,0x48,0x7,0x0,0x20,0x20,0x20,0x20,0x50,0x50,0x88,0x8e,0x4,0x0,0x10,0x88,0xa4,0x24,0xe0,0x0,
-+0x0,0x2b,0x28,0x28,0x45,0x53,0x91,0x11,0x21,0x21,0x29,0x45,0x7c,0x4,0x0,0x3,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x20,0x58,0x84,0x2,
-+0x2,0x41,0x30,0x17,0x0,0x0,0xf0,0x1f,0x10,0x10,0x10,0x10,0x11,0x2a,0x44,0x3,0x8,0x10,0xa0,0xfc,0x40,0x40,0x44,0xfe,0x40,0x40,0x80,0xa0,0x18,0x8,0x6,0xfc,
-+0x2,0x1,0x7f,0x40,0x81,0x1,0x1,0xff,0x3,0x5,0x9,0x11,0x21,0x41,0x1,0x1,0x0,0x0,0xfe,0x2,0x4,0x0,0x4,0xfe,0x80,0x40,0x30,0xe,0x4,0x0,0x0,0x0,
-+0x0,0x40,0x31,0x11,0x1,0x2,0xf2,0x14,0x18,0x10,0x10,0x10,0x15,0x1b,0x10,0x0,0x40,0x20,0x20,0x20,0x10,0x8,0xe,0x44,0x40,0x40,0x80,0x90,0x8,0xf8,0x8,0x0,
-+0x0,0x47,0x20,0x20,0x0,0x7,0xe4,0x24,0x27,0x24,0x24,0x27,0x2c,0x34,0x24,0x4,0x0,0xf8,0x10,0xa0,0x44,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x44,0x44,0x54,0x48,
-+0x10,0x10,0x11,0x11,0xfd,0x11,0x15,0x19,0x30,0xd3,0x10,0x10,0x10,0x10,0x50,0x23,0x24,0xae,0x24,0x24,0xac,0x24,0x24,0xfc,0x20,0xfc,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x8,0x10,0x3d,0x25,0x35,0x2d,0x25,0x25,0xfc,0x27,0x34,0x2c,0x44,0x44,0x94,0xb,0x24,0xae,0x24,0x24,0xac,0x24,0x24,0xfc,0x20,0xfc,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x22,0x2a,0x27,0x22,0xff,0x22,0x37,0x2a,0x62,0xbf,0x24,0x28,0x25,0x22,0xa5,0x48,0x10,0x90,0x10,0x14,0xbe,0x44,0x24,0xa4,0x28,0xe8,0x90,0x90,0x28,0x28,0x46,0x84,
-+0x2,0x22,0xff,0xa2,0xa2,0xaf,0xaa,0xaa,0xaf,0xa2,0xa7,0xea,0x92,0x2,0x2,0x3,0x10,0x90,0xd0,0x10,0xbe,0xc2,0x94,0x90,0x90,0x10,0x10,0xa8,0x28,0x48,0x86,0x4,
-+0x8,0x8,0xff,0x8,0xa,0x2,0x3f,0x2,0x2,0x22,0x24,0x44,0x8,0x10,0x20,0x40,0x20,0x24,0xfe,0x20,0x20,0x10,0xf8,0x10,0x10,0x18,0x16,0x12,0x10,0x10,0x50,0x20,
-+0x4,0xfe,0x29,0x28,0xfe,0xaa,0xab,0xaa,0xae,0xc2,0x82,0xff,0x82,0xfe,0x82,0x0,0x8,0x1c,0xe0,0x20,0x20,0x24,0xfe,0x20,0x70,0x68,0xae,0x24,0x20,0x20,0x20,0x20,
-+0x10,0x11,0x11,0x22,0x24,0x60,0xa1,0x22,0x24,0x2b,0x22,0x22,0x22,0x22,0x23,0x22,0x0,0x10,0xc,0x44,0x40,0xa0,0x10,0xe,0x4,0xf8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x1,0x1,0x7f,0x1,0x3f,0x1,0xff,0x4,0x1f,0x1,0x2,0x1f,0x1,0x9,0x15,0x22,0x0,0x8,0xfc,0x0,0xf8,0x0,0xfe,0x20,0xc0,0x0,0x20,0xf0,0x0,0x20,0x18,0x8,
-+0x0,0x40,0x37,0x10,0x7,0x4,0xf4,0x17,0x14,0x10,0x11,0x12,0x14,0x28,0x47,0x0,0x40,0x44,0xfe,0x40,0xfc,0x44,0x44,0xfc,0x44,0xe0,0x58,0x48,0x40,0x46,0xfc,0x0,
-+0x0,0x7f,0x4,0x3f,0x24,0x24,0x3f,0x1,0x11,0x9,0xff,0x5,0x9,0x31,0xc1,0x1,0x8,0xfc,0x40,0xf8,0x48,0x48,0xf8,0x0,0x10,0x24,0xfe,0x40,0x30,0xe,0x4,0x0,
-+0x10,0x1f,0x10,0x27,0x24,0x64,0xa7,0x20,0x22,0x21,0x2f,0x21,0x22,0x24,0x28,0x20,0x4,0xfe,0xa0,0xfc,0xa4,0xa4,0xfc,0x40,0x48,0x50,0xfe,0x50,0x48,0x46,0x44,0x40,
-+0x22,0x14,0xff,0x8,0x2a,0x2a,0x2a,0x3e,0x8,0x11,0x21,0x7f,0x1,0x1,0xff,0x0,0x4,0x7e,0xc4,0x7c,0x44,0x7c,0x44,0x44,0x94,0x8,0x0,0xfc,0x0,0x4,0xfe,0x0,
-+0x48,0x25,0x20,0x1f,0x82,0x4a,0x4a,0xa,0x1a,0x2a,0xef,0x22,0x22,0x24,0x28,0x21,0x84,0x3e,0x24,0xe4,0x24,0xbc,0xa4,0xa4,0xa4,0xbc,0xa4,0xa4,0x44,0x44,0x94,0x8,
-+0x2,0x1,0x7f,0x40,0x88,0xf,0x8,0x10,0x13,0x32,0x52,0x93,0x12,0x12,0x13,0x12,0x0,0x0,0xfe,0x2,0x4,0xfe,0x40,0x88,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x0,0x43,0x32,0x12,0x2,0x2,0xf3,0x12,0x12,0x12,0x12,0x16,0x1a,0x14,0x8,0x0,0x1c,0xe0,0x0,0x0,0x0,0x4,0xfe,0x20,0x20,0x20,0x60,0x30,0x2c,0x24,0x20,0x20,
-+0x1,0x1,0x3f,0x1,0xff,0x1,0x3f,0x1,0x21,0x25,0x25,0x25,0x29,0x21,0x41,0x81,0x0,0x8,0xfc,0x8,0xfe,0x8,0xf8,0x0,0x8,0x48,0x48,0x28,0x28,0x8,0x8,0x8,
-+0x4,0xfe,0x28,0x28,0xff,0xaa,0xaa,0xab,0xae,0xc2,0x83,0xfe,0x82,0xfe,0x82,0x1,0x20,0x20,0x40,0x84,0xfe,0x48,0x86,0x42,0x78,0x88,0x48,0x50,0x20,0x50,0x8e,0x4,
-+0x8,0x8,0xff,0x8,0x4,0x7e,0x0,0x4,0xfe,0x8,0x2c,0x2a,0x48,0x89,0x28,0x10,0x20,0x24,0xfe,0x20,0x8,0xfc,0x0,0x4,0xfe,0x10,0x58,0x56,0x92,0x10,0x50,0x20,
-+0x20,0x3e,0x49,0x9f,0x10,0x1f,0x10,0x1f,0x10,0x1f,0x8,0xff,0x8,0x8,0x10,0x20,0x80,0xfc,0x20,0xf0,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x0,0x1f,0x10,0x10,0x1f,0x1,0x1,0x3f,0x21,0x21,0x3f,0x1,0x1,0x1,0x7f,0x0,0x10,0xf8,0x10,0x10,0xf0,0x0,0x8,0xfc,0x8,0x8,0xf8,0x0,0x10,0xfc,0x4,0x0,
-+0x0,0x78,0x4f,0x51,0x51,0x62,0x55,0x48,0x4b,0x4a,0x6b,0x52,0x43,0x42,0x42,0x42,0x80,0x84,0xfe,0x0,0xf8,0x40,0xfc,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x28,0x10,
-+0x0,0x78,0x4a,0x51,0x51,0x60,0x57,0x49,0x49,0x49,0x69,0x51,0x41,0x41,0x42,0x44,0x20,0x24,0xfe,0x20,0x44,0xfe,0x44,0x7c,0x44,0x7c,0x44,0x44,0x54,0x48,0x80,0x7e,
-+0x10,0x17,0x20,0x22,0x41,0xf8,0x10,0x2f,0x41,0xf9,0x42,0x1,0x18,0xe0,0x41,0x6,0x1c,0xe0,0x0,0x48,0x50,0x20,0x84,0xfe,0x8,0x8,0x10,0x10,0xa0,0x40,0xb0,0x8,
-+0x0,0x7d,0x44,0x76,0x55,0x55,0xfe,0x83,0x7d,0x45,0x7d,0x45,0x7d,0x45,0x56,0x48,0x20,0xfe,0x40,0x7c,0x90,0x7c,0x0,0x7c,0x44,0x7c,0x44,0x7c,0x44,0x4c,0x80,0x7e,
-+0x0,0x8,0xfd,0x10,0x10,0x21,0x22,0x7c,0xa4,0x27,0x24,0x24,0x24,0x3c,0x20,0x0,0x40,0x20,0xfc,0x88,0x88,0x54,0x22,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x1,0x21,0x21,0x21,0x3f,0x24,0x4,0xf,0x10,0x24,0x42,0x1,0x1,0x3,0x1c,0xe0,0x0,0x8,0x8,0x8,0xf8,0x8,0x0,0xfc,0x8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,
-+0x8,0x1c,0xf3,0x10,0x11,0xff,0x11,0x31,0x39,0x54,0x51,0x90,0x12,0x12,0x14,0x10,0x20,0x24,0xfe,0x20,0xfc,0x24,0xfc,0x24,0xfc,0x28,0xfc,0x40,0xa4,0xa2,0x8a,0x78,
-+0x2,0x81,0x60,0x2f,0x1,0x2,0xe4,0x29,0x22,0x24,0x29,0x22,0x25,0x50,0x8f,0x0,0x10,0x20,0x48,0xfc,0x0,0x88,0xd0,0x60,0x40,0xe0,0x58,0x48,0x40,0x86,0xfc,0x0,
-+0x0,0x78,0x49,0x54,0x52,0x60,0x50,0x4e,0x4a,0x4a,0x6a,0x52,0x42,0x45,0x48,0x40,0x44,0x28,0xfe,0x20,0x40,0xa4,0x38,0x50,0x98,0x34,0x54,0x90,0x30,0x6,0xfc,0x0,
-+0x1,0x21,0x21,0x3f,0x1,0x41,0x7f,0x0,0x3f,0x0,0x0,0xff,0x9,0x11,0x25,0x2,0x0,0x8,0x8,0xf8,0x0,0x4,0xfc,0x0,0xf8,0x0,0x4,0xfe,0x20,0x18,0x8,0x0,
-+0x0,0x7e,0x2,0x4,0x8,0xa,0xc,0x39,0xc9,0xa,0xc,0x8,0x8,0x8,0x28,0x10,0x20,0x20,0x20,0x20,0x20,0xb0,0xa8,0x24,0x26,0x22,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x10,0x11,0x11,0x11,0xfd,0x10,0x15,0x19,0x31,0xd1,0x11,0x11,0x11,0x10,0x50,0x23,0x4,0xfe,0x4,0x4,0xfc,0x0,0xfc,0x4,0x24,0x24,0x24,0x24,0x24,0x50,0x8c,0x4,
-+0x10,0x12,0x1f,0x28,0x45,0xbf,0x4,0x4,0xff,0x4,0x4,0x3f,0x4,0x8,0x10,0x60,0x40,0x44,0x7e,0xa0,0x10,0xf0,0x10,0x14,0xfe,0x10,0x10,0xf0,0x10,0x0,0x0,0x0,
-+0x8,0x8,0xff,0x9,0x7f,0x0,0x1f,0x10,0xff,0x10,0x1f,0x9,0x18,0x2a,0xcc,0x8,0x20,0x24,0xfe,0x20,0xfc,0x0,0xf0,0x14,0xfe,0x10,0xf0,0x8,0x90,0x60,0x1c,0x8,
-+0x10,0x10,0x11,0x13,0xfc,0x10,0x31,0x3a,0x54,0x51,0x92,0x14,0x10,0x10,0x11,0x16,0x40,0x90,0x8,0xfc,0x4,0x88,0x6,0x82,0xf8,0x8,0x90,0x50,0x20,0x50,0x8e,0x4,
-+0x0,0x8,0x7d,0x4b,0x48,0x48,0x49,0x4a,0x48,0x49,0x4a,0x7c,0x48,0x0,0x1,0x6,0x40,0x90,0x8,0xfc,0x4,0x88,0x6,0x82,0xf8,0x8,0x90,0x50,0x20,0x50,0x8e,0x4,
-+0x20,0x20,0x27,0x44,0x49,0xf1,0x12,0x26,0x4a,0xfa,0x42,0x2,0x1a,0xe2,0x42,0x2,0x40,0x20,0xfe,0x2,0x4,0xfe,0x20,0x44,0xfe,0x84,0x84,0xfc,0x84,0x84,0xfc,0x84,
-+0x0,0x9,0xfc,0x10,0x10,0x11,0x11,0x7d,0x11,0x11,0x11,0x1d,0xf0,0x40,0x1,0x6,0x20,0x24,0xa4,0xa8,0x24,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x20,0x58,0x84,0x2,
-+0x1,0x1,0x3f,0x1,0x7f,0x42,0x84,0xf,0x1,0x2,0x3f,0x1,0x9,0x11,0x25,0x2,0x0,0x10,0xf8,0x0,0xfe,0x2,0x24,0xc0,0x0,0x10,0xf8,0x8,0x20,0x18,0x8,0x0,
-+0x10,0x11,0x10,0x1c,0x20,0x21,0x7d,0x91,0x11,0x7d,0x11,0x11,0x14,0x18,0x11,0x6,0x20,0x24,0xa4,0xa8,0x24,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x20,0x58,0x84,0x2,
-+0x2,0x7,0x38,0x20,0x20,0x3e,0x22,0x22,0x22,0x3e,0x22,0x20,0x21,0x42,0x84,0x0,0x8,0x1c,0xe0,0x80,0x80,0x84,0xfe,0x88,0x88,0x88,0x88,0x88,0x8,0x8,0x8,0x8,
-+0x20,0x23,0x22,0x23,0x22,0xfb,0x20,0x27,0x20,0x24,0x22,0x39,0xe2,0x44,0x2,0x1,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x4,0xbe,0x84,0xa4,0x94,0x8c,0x94,0xa4,0x94,0x8,
-+0x8,0x8,0x8,0x10,0x12,0x32,0x53,0x9e,0x12,0x12,0x12,0x12,0x12,0x12,0x11,0x10,0x40,0x40,0x40,0x40,0x48,0x7c,0xc8,0x48,0x48,0x68,0x50,0x40,0x42,0x2,0xfe,0x0,
-+0x2,0x1,0x7f,0x40,0x80,0x8,0x8,0x8,0x9,0xe,0x8,0x8,0x8,0x8,0x7,0x0,0x0,0x0,0xfe,0x2,0x4,0x0,0x20,0x60,0x80,0x0,0x0,0x0,0x8,0x8,0xf8,0x0,
-+0x10,0x10,0x10,0x10,0xfd,0x25,0x25,0x27,0x25,0x45,0x29,0x11,0x29,0x45,0x84,0x0,0x20,0x20,0x20,0x20,0x24,0x3e,0xe4,0x24,0x24,0x34,0x28,0x20,0x22,0x2,0xfe,0x0,
-+0x21,0x21,0x27,0x21,0x20,0xf8,0x21,0x22,0x2d,0x20,0x23,0x3a,0xe2,0x42,0x3,0x2,0x10,0x10,0xfc,0x10,0x40,0xa0,0x10,0xe,0xf4,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x8a,0x52,0x2f,0x62,0xaf,0x2a,0x2a,0x6a,0xaf,0x22,0x27,0x2a,0x32,0x22,0xa2,0x42,0x10,0x10,0x9c,0x24,0xc8,0xbe,0xa2,0xaa,0xaa,0x2a,0x2a,0xaa,0x8,0x14,0x22,0x42,
-+0x10,0x12,0x11,0x11,0xfc,0x10,0x17,0x19,0x31,0xd1,0x11,0x11,0x11,0x12,0x54,0x20,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x28,0x28,0x46,0x84,0x0,0x86,0x7c,0x0,
-+0x0,0x7d,0x45,0x45,0x45,0x7d,0x10,0x13,0x5c,0x51,0x50,0x51,0x5e,0xf0,0x41,0x0,0x4,0xfe,0x4,0xfc,0x4,0xfc,0x0,0xdc,0x44,0x54,0xcc,0x54,0x64,0x44,0x54,0x88,
-+0x0,0x7d,0x44,0x44,0x44,0x7d,0x12,0x10,0x5d,0x51,0x51,0x51,0x5d,0xf1,0x41,0x1,0x20,0x24,0xa8,0x70,0xa8,0x26,0x24,0x60,0xfc,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,
-+0x4,0x3e,0x24,0x24,0x24,0x3d,0x27,0x24,0x24,0x3d,0x25,0x25,0x25,0x45,0x95,0x9,0x20,0x20,0x40,0x40,0x88,0x4,0xfe,0x2,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x8,0x8,0xff,0x8,0x2,0x4,0x8,0x3f,0x0,0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x20,0x24,0xfe,0x20,0x0,0x20,0x10,0xf8,0x8,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,
-+0x10,0x10,0x10,0x10,0xfc,0x11,0x17,0x18,0x30,0xd1,0x11,0x11,0x11,0x11,0x51,0x21,0x20,0x20,0x40,0x40,0x88,0x4,0xfe,0x2,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x2,0x2,0x4,0x8,0x10,0x20,0x7f,0x0,0x0,0x1f,0x10,0x10,0x10,0x10,0x1f,0x10,0x0,0x0,0x0,0x20,0x10,0x8,0xfc,0x4,0x10,0xf8,0x10,0x10,0x10,0x10,0xf0,0x10,
-+0x1,0x1,0x7f,0x1,0x3f,0x2,0xff,0x4,0x9,0x39,0xc5,0x3,0xd,0x11,0x5,0x2,0x0,0x8,0xfc,0x0,0xf8,0x0,0xfe,0x40,0x20,0x30,0x4e,0x84,0x60,0x10,0x0,0x0,
-+0x1,0xff,0x14,0x14,0x7f,0x55,0x55,0x55,0x57,0x61,0x41,0x7f,0x41,0x41,0x7f,0x41,0x10,0x90,0x10,0x10,0x14,0xfe,0x10,0x10,0x28,0x28,0x28,0x28,0x44,0x54,0x82,0x0,
-+0x1,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x2,0x2,0x4,0x6,0x9,0x31,0xc0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x80,0x80,0x40,0x40,0x30,0xe,0x4,0x0,
-+0x1,0x1,0xff,0x1,0x2,0x4,0xa,0x31,0xc0,0x2,0x29,0x29,0x28,0x48,0x7,0x0,0x0,0x4,0xfe,0x0,0x80,0x40,0x30,0xe,0x4,0x0,0x10,0x8,0x24,0x24,0xe0,0x0,
-+0x0,0x40,0x30,0x10,0x87,0x60,0x20,0x8,0x10,0x20,0xe1,0x21,0x22,0x24,0x28,0x20,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0xa0,0xa0,0x10,0x90,0x48,0x4e,0x4,0x0,
-+0x20,0x23,0x22,0x22,0x22,0xfa,0x22,0x22,0x2f,0x22,0x22,0x3a,0xe2,0x44,0x4,0x8,0x8,0xfc,0x8,0x8,0x88,0x48,0x48,0x8,0xfe,0x8,0x8,0x8,0x8,0x8,0x28,0x10,
-+0x20,0x20,0x20,0x2e,0xf3,0x2a,0x2a,0x3a,0x6a,0xa4,0x2a,0x29,0x31,0x20,0xa0,0x40,0x40,0x50,0x44,0xfe,0x90,0x90,0xfc,0x90,0x90,0xfc,0x90,0x90,0x94,0xfe,0x80,0x80,
-+0x1,0x2,0x6,0x9,0x37,0xc0,0x0,0x1f,0x10,0x11,0x11,0x11,0x12,0x4,0x8,0x30,0x0,0x80,0x40,0x30,0xce,0x44,0x90,0xf8,0x10,0x10,0x10,0x10,0x10,0xc0,0x30,0x8,
-+0x0,0x0,0x1f,0x10,0x90,0x5f,0x51,0x19,0x35,0x52,0x92,0x15,0x25,0x28,0x40,0x0,0x80,0x44,0xfe,0x20,0x28,0x7e,0x48,0xc8,0x7e,0x48,0x48,0x7e,0x48,0x48,0x7e,0x40,
-+0x0,0x40,0x30,0x1f,0x81,0x69,0x29,0x6,0x12,0x25,0xe9,0x30,0x20,0x20,0x20,0x20,0x20,0x28,0x20,0x7e,0x48,0xc8,0x7c,0x48,0x48,0x7c,0x48,0x48,0x48,0x7e,0x40,0x40,
-+0x10,0x10,0x13,0x10,0x10,0xfc,0x17,0x10,0x10,0x10,0x10,0x1d,0xf1,0x43,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x4,0xfe,0x40,0x40,0x80,0x90,0x8,0x4,0xfc,0x4,0x0,
-+0x10,0x17,0x10,0x17,0xfd,0x15,0x3d,0x37,0x50,0x53,0x92,0x13,0x12,0x13,0x10,0x1f,0x40,0xfe,0x0,0xfc,0x14,0xf4,0x14,0xfc,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xfe,
-+0x1,0x0,0x1f,0x10,0x92,0x51,0x50,0x11,0x36,0x50,0x92,0x11,0x20,0x21,0x42,0xc,0x0,0x84,0xfe,0x40,0x48,0x50,0xa0,0x10,0x4c,0x40,0x48,0x50,0xa0,0x10,0xe,0x4,
-+0x40,0x3f,0x10,0x7,0x84,0x67,0x20,0xb,0x12,0x23,0xe2,0x23,0x20,0x2f,0x20,0x20,0x4,0xfe,0xa0,0xfc,0xa4,0xfc,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x40,0xfe,0x40,0x40,
-+0x40,0x2f,0x20,0x7,0x4,0xe7,0x20,0x23,0x22,0x23,0x22,0x23,0x28,0x37,0x20,0x0,0x4,0xfe,0xa0,0xfc,0xa4,0xfc,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x40,0xfe,0x40,0x40,
-+0x0,0x40,0x32,0x11,0x0,0x0,0xf1,0x16,0x10,0x12,0x11,0x10,0x14,0x19,0x12,0x4,0x40,0x40,0x48,0x50,0xa0,0x90,0xe,0x44,0x40,0x48,0x50,0xa0,0xa0,0x10,0xe,0x4,
-+0x10,0x10,0x11,0x11,0x11,0xfd,0x11,0x11,0x11,0x11,0x11,0x1d,0xf1,0x40,0xf,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0xfc,0x4,0x0,0xfe,0x0,
-+0x4,0xe,0xf0,0x11,0x10,0x7c,0x11,0x10,0xfe,0x10,0x11,0x10,0x10,0x13,0x10,0xf,0x20,0xa4,0xa8,0x30,0x50,0x8c,0x24,0x20,0xa8,0xb0,0x20,0x50,0x8c,0x6,0x2,0xfe,
-+0x20,0x10,0x11,0x1,0xfd,0x9,0x11,0x35,0x59,0x95,0x11,0x11,0x11,0x10,0x17,0x10,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0xfc,0x4,0x0,0xfe,0x0,
-+0x0,0x8,0xfd,0x11,0x11,0x20,0x23,0x7c,0xa4,0x25,0x25,0x26,0x24,0x3c,0x25,0x2,0x20,0x20,0x24,0x24,0xfc,0x80,0xfe,0x80,0xa0,0x24,0xa8,0x50,0x50,0x88,0xe,0x4,
-+0x10,0x13,0x12,0x14,0xfc,0x11,0x14,0x18,0x33,0xd0,0x10,0x10,0x11,0x12,0x50,0x20,0x0,0xfe,0x2,0x54,0x88,0x4,0x20,0x24,0xfe,0x20,0x70,0xa8,0x26,0x24,0x20,0x20,
-+0x0,0x8,0x7f,0x4a,0x4a,0x49,0x49,0x48,0x48,0x48,0x48,0x78,0x49,0x2,0x4,0x18,0x0,0x0,0xf8,0x8,0x8,0x10,0x10,0xa0,0xa0,0x40,0xa0,0xa0,0x10,0x10,0xe,0x4,
-+0x1,0x21,0x21,0x3f,0x8,0xff,0x9,0x9,0x15,0x15,0x2a,0x22,0x44,0x84,0x8,0x30,0x0,0x8,0x8,0xf8,0x4,0xfe,0x0,0x10,0x30,0x40,0x80,0x80,0x40,0x20,0x1c,0x8,
-+0x0,0x23,0x18,0x8,0x80,0x60,0x23,0x8,0x10,0x21,0xe1,0x22,0x24,0x29,0x22,0x20,0x0,0xf8,0x10,0x20,0x40,0x84,0xfe,0xa4,0xa4,0x24,0x44,0x44,0x84,0x4,0x28,0x10,
-+0x10,0x10,0x13,0x12,0x13,0xfe,0x13,0x12,0x13,0x12,0x13,0x1d,0xf5,0x45,0x9,0x1,0x40,0x24,0xfe,0x20,0xfc,0x24,0xfe,0x24,0xfc,0x20,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x13,0x12,0xff,0x12,0x17,0x1a,0x33,0xd2,0x13,0x15,0x15,0x15,0x59,0x21,0x40,0x24,0xfe,0x20,0xfc,0x24,0xfe,0x24,0xfc,0x20,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x1,0x11,0x9,0x7f,0x40,0x9f,0x10,0x10,0x1f,0x1,0x1,0x7f,0x1,0x1,0xff,0x0,0x0,0x10,0x20,0xfe,0x2,0xf4,0x10,0x10,0xf0,0x0,0x8,0xfc,0x0,0x4,0xfe,0x0,
-+0x1,0x9,0x5,0x7f,0x40,0x8f,0x8,0x8,0xf,0x1,0xff,0x3,0x5,0x19,0x61,0x1,0x0,0x20,0x40,0xfe,0x2,0xe4,0x20,0x20,0xe0,0x4,0xfe,0x80,0x60,0x1c,0x8,0x0,
-+0x8,0x7d,0x48,0x4b,0x4a,0x7d,0x49,0x49,0x49,0x78,0x48,0x49,0x48,0x48,0x8b,0x18,0x20,0x24,0xa8,0xfe,0x2,0xfc,0x4,0x4,0xfc,0x20,0x28,0xfc,0x20,0x24,0xfe,0x0,
-+0x1,0x0,0x3f,0x20,0x2f,0x20,0x3f,0x20,0x2f,0x20,0x2f,0x28,0x48,0x48,0x8f,0x8,0x0,0x88,0xfc,0x80,0xf8,0x88,0xfe,0x88,0xf8,0x80,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x57,0x3a,0x13,0xfe,0x13,0x32,0x3b,0x56,0x53,0x93,0x15,0x15,0x19,0x11,0x40,0x24,0xfe,0x20,0xfc,0x24,0xfe,0x24,0xfc,0x20,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x8,0xa,0x9,0x11,0x10,0x37,0x54,0x94,0x15,0x15,0x15,0x15,0x15,0x15,0x14,0x14,0x40,0x48,0x48,0x50,0x44,0xfe,0x4,0x4,0xf4,0x14,0x14,0x14,0xf4,0x4,0x14,0x8,
-+0x10,0x22,0x79,0x49,0x48,0x7b,0x4a,0x7a,0x4a,0x4a,0xfa,0x2a,0x4a,0x8a,0x2a,0x12,0x40,0x48,0x48,0x50,0x44,0xfe,0x4,0x4,0xf4,0x94,0x94,0x94,0xf4,0x84,0x14,0x8,
-+0x0,0x42,0x31,0x11,0x80,0x67,0x24,0xc,0x15,0x25,0xe5,0x25,0x25,0x25,0x24,0x24,0x40,0x48,0x48,0x50,0x44,0xfe,0x4,0x4,0xf4,0x14,0x14,0x14,0xf4,0x4,0x14,0x8,
-+0x10,0x12,0x11,0x7d,0x10,0x13,0xfe,0x12,0x52,0x5e,0x52,0x72,0x52,0x48,0x87,0x0,0x40,0x48,0x48,0x50,0x44,0xfe,0x4,0xf4,0x94,0x94,0x94,0xf4,0xc,0x6,0xfc,0x0,
-+0x23,0x10,0x40,0x23,0x9,0x71,0x11,0x12,0x14,0x1,0x9,0xa,0x12,0x4,0x18,0x60,0xf0,0x40,0x84,0xfe,0x24,0x24,0x24,0x54,0x88,0x0,0x10,0xa0,0x80,0x60,0x1c,0x8,
-+0x11,0x11,0x11,0x13,0xfc,0x12,0x13,0x1c,0x30,0xd3,0x10,0x12,0x12,0x13,0x50,0x20,0x0,0x0,0x4,0xfe,0x4,0x44,0xe4,0x84,0xa4,0xf4,0x84,0xa4,0xa4,0xe4,0x14,0x8,
-+0x0,0x40,0x37,0x10,0x83,0x60,0x2f,0x9,0x11,0x23,0xe2,0x25,0x28,0x30,0x20,0x20,0x80,0x88,0xfc,0x80,0xf8,0x80,0xfe,0x8,0x8,0xfe,0x8,0x8,0x88,0x88,0x28,0x10,
-+0x40,0x30,0x17,0x0,0x82,0x61,0x20,0xf,0x14,0x24,0xe7,0x24,0x24,0x24,0x27,0x24,0x8,0x3c,0xc0,0x4,0x4c,0x50,0x84,0x3e,0x4,0x4,0xbc,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x21,0x23,0x4c,0xf8,0x10,0x21,0x46,0xf8,0x47,0x0,0x19,0xe2,0x45,0x0,0x80,0x80,0xf8,0x10,0xa0,0x40,0xa0,0x10,0x4e,0x44,0xfc,0x40,0x50,0x4c,0x44,0x80,
-+0x4,0x4,0xff,0x14,0x1f,0x28,0x4f,0x11,0x21,0xff,0x1,0x11,0x11,0x1f,0x0,0x0,0x40,0x44,0xfe,0x40,0xfc,0x4,0xf4,0x4,0x14,0xfc,0x4,0x14,0x14,0xf4,0x14,0x8,
-+0x10,0x10,0x10,0x10,0xfc,0x12,0x39,0x34,0x51,0x52,0x94,0x11,0x11,0x12,0x14,0x18,0xa0,0xa0,0xa0,0xa0,0xa4,0xac,0xb0,0xa0,0xb0,0xa8,0xa8,0x20,0x22,0x22,0x1e,0x0,
-+0x1,0x41,0x29,0x25,0x5,0x1,0xe3,0x25,0x29,0x21,0x22,0x24,0x28,0x50,0x88,0x7,0x40,0x40,0x48,0x58,0x60,0x40,0x60,0x50,0x50,0x40,0x44,0x44,0x3c,0x0,0x6,0xfc,
-+0x42,0x32,0x13,0x5,0x89,0x63,0x24,0x0,0x1f,0x20,0xe4,0x24,0x27,0x20,0x20,0x20,0x0,0x4,0xfe,0x4,0x24,0xf4,0x84,0x94,0xfc,0x84,0x94,0x94,0xf4,0x4,0x14,0x8,
-+0x1,0x79,0x49,0x52,0x55,0x61,0x52,0x48,0x4f,0x48,0x69,0x51,0x41,0x40,0x40,0x40,0x0,0x4,0xfe,0x4,0x24,0xf4,0x44,0x54,0xfc,0x44,0x54,0x54,0xf4,0x4,0x14,0x8,
-+0x0,0x40,0x30,0x10,0x7,0x0,0xf0,0x11,0x10,0x10,0x10,0x10,0x14,0x18,0x10,0x0,0x8,0x8,0x8,0x8,0xfe,0x8,0x8,0x8,0x88,0x88,0x8,0x8,0x8,0x8,0x28,0x10,
-+0x1,0x1,0xff,0x2,0x4,0xf,0x18,0x2f,0xc8,0xf,0x8,0xff,0x4,0x8,0x1f,0x0,0x0,0x4,0xfe,0x80,0x40,0xe0,0x10,0xee,0x4,0xe0,0x4,0xfe,0x0,0x20,0xf0,0x10,
-+0x10,0x10,0x50,0x53,0x7c,0x90,0x17,0x18,0x30,0xd7,0x11,0x10,0x10,0x10,0x10,0x10,0x40,0x40,0x48,0xfc,0x40,0x44,0xfe,0x10,0x14,0xfe,0x10,0x90,0x90,0x10,0x50,0x20,
-+0x4,0x4,0xff,0x4,0x7a,0x49,0x4b,0x78,0x4f,0x49,0x7a,0x4d,0x48,0x49,0x8a,0x18,0x20,0x24,0xfe,0x20,0x48,0x50,0xfc,0x80,0xfe,0x10,0x4e,0x54,0xe0,0x58,0x48,0xc0,
-+0x0,0x7a,0x49,0x4b,0x48,0x7f,0x49,0x4a,0x4d,0x78,0x49,0x49,0x48,0x4f,0x88,0x18,0x40,0x48,0x50,0xfc,0x80,0xfe,0x10,0xe,0xf4,0x10,0x14,0xfe,0x4,0xe4,0x14,0x8,
-+0x1,0x0,0x1f,0x11,0x91,0x53,0x55,0x10,0x30,0x50,0x93,0x2c,0x20,0x40,0x80,0x0,0x0,0x84,0xfe,0x0,0x0,0xf8,0x10,0xa0,0x40,0xb0,0x8e,0x64,0x20,0x80,0x60,0x20,
-+0x11,0x9,0x7f,0x2,0xff,0x4,0x9,0x3f,0xc0,0x1f,0x0,0x1f,0x0,0x1f,0x10,0x1f,0x10,0x20,0xfc,0x0,0xfe,0x40,0x20,0xfe,0x4,0xf0,0x0,0xf0,0x0,0xf0,0x10,0xf0,
-+0x12,0x11,0x10,0x13,0xfc,0x10,0x33,0x3a,0x56,0x53,0x90,0x11,0x12,0x14,0x18,0x10,0x8,0x10,0xa0,0xf8,0x48,0x48,0xf8,0x40,0x44,0xfe,0xc4,0x44,0x54,0x48,0x40,0x40,
-+0x1,0x3f,0x21,0x21,0x3f,0x21,0x21,0x3f,0x10,0x3f,0x54,0x94,0x14,0x24,0x4a,0x11,0x4,0x84,0x24,0x24,0x24,0x24,0x24,0x24,0xa4,0xe4,0xa4,0x84,0x84,0x84,0x94,0x8,
-+0x0,0x7d,0x45,0x45,0x45,0x7d,0x11,0x11,0x5c,0x51,0x52,0x54,0x5c,0xf1,0x42,0x0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x84,0xfe,0xa4,0xa4,0xa4,0x24,0x54,0x88,
-+0x22,0x21,0x38,0x43,0x80,0x78,0x23,0x22,0xfa,0x23,0x20,0x29,0x32,0x24,0x8,0x0,0x8,0x10,0xa0,0xf8,0x48,0x48,0xf8,0x40,0x44,0xfe,0xc4,0x44,0x54,0x48,0x40,0x40,
-+0x10,0x11,0x11,0x11,0xfd,0x11,0x15,0x19,0x30,0xd7,0x10,0x11,0x11,0x11,0x52,0x24,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x0,0xfe,0x20,0x28,0x3c,0x20,0xa6,0x7c,
-+0x3e,0x23,0x22,0x3e,0x22,0x22,0x3e,0x0,0xff,0x8,0x2a,0x2f,0x28,0x58,0x49,0x87,0x4,0xfe,0x20,0x44,0xfe,0x84,0x94,0x94,0x94,0xa4,0xa4,0x20,0x58,0x84,0x6,0xfc,
-+0x0,0x7c,0x45,0x44,0x44,0x7f,0x12,0x14,0x5d,0x51,0x51,0x51,0x5d,0xf1,0x40,0x0,0x40,0x20,0xfc,0x88,0x50,0xfe,0x22,0x24,0xfe,0x24,0x24,0x24,0x24,0x2c,0x20,0x20,
-+0x0,0x8,0x7d,0x48,0x48,0x4b,0x4a,0x4c,0x49,0x49,0x49,0x79,0x49,0x1,0x0,0x0,0x40,0x20,0xfc,0x88,0x50,0xfe,0x22,0x24,0xfe,0x24,0x24,0x24,0x24,0x2c,0x20,0x20,
-+0x10,0x10,0x10,0x20,0x2f,0x62,0xa2,0x24,0x24,0x28,0x2b,0x30,0x20,0x20,0x20,0x20,0x80,0x80,0x80,0x88,0xfc,0xa0,0xa0,0x90,0x90,0x88,0xee,0x84,0x80,0x80,0x80,0x80,
-+0x8,0x8,0x7e,0x8,0xfe,0x8,0x14,0x22,0xdf,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x20,0x28,0xfc,0x20,0xfe,0x20,0x50,0x8e,0xf4,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x0,0x13,0x78,0x57,0x54,0x5b,0x52,0x53,0x52,0x53,0x50,0x77,0x52,0x3,0x4,0x8,0x50,0xf8,0x40,0xfe,0x2,0xfc,0x48,0xf8,0x48,0xf8,0x0,0xfc,0x44,0x70,0xc0,0x7e,
-+0x10,0x11,0x11,0x11,0x59,0x55,0x51,0x91,0x10,0x11,0x12,0x14,0x10,0x11,0x12,0x10,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x84,0xfe,0xa4,0xa4,0xa4,0x24,0x54,0x88,
-+0x2,0x41,0x30,0x17,0x80,0x60,0x27,0xc,0x14,0x27,0xe0,0x21,0x22,0x24,0x28,0x20,0x8,0x10,0xa0,0xf8,0x48,0x48,0xf8,0x40,0x44,0xfe,0xc4,0x44,0x54,0x48,0x40,0x40,
-+0x41,0x22,0x14,0x7f,0x9,0x9,0x7f,0x48,0x49,0x7f,0x19,0x29,0x4d,0x8a,0x8,0x8,0x4,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0xa4,0x24,0x24,0x24,0x4,0x14,0x8,
-+0x0,0x3f,0x20,0x20,0x3f,0x20,0x24,0x24,0x3f,0x24,0x24,0x24,0x24,0x44,0x87,0x0,0x8,0xfc,0x8,0x8,0xf8,0x90,0x90,0x94,0xfe,0x90,0x90,0xf0,0x0,0x8,0xfc,0x0,
-+0x0,0x7f,0x1,0x1,0x1,0x1,0xff,0x1,0x2,0x2,0x4,0x4,0x8,0x10,0x20,0xc0,0x8,0xfc,0x0,0x0,0x0,0x4,0xfe,0x0,0x80,0x80,0x40,0x40,0x20,0x10,0xe,0x4,
-+0x40,0x37,0x10,0x0,0x8f,0x61,0x21,0xa,0x14,0x28,0xe2,0x22,0x24,0x20,0x22,0x21,0x8,0xfc,0x80,0x84,0xfe,0x20,0x10,0x90,0x8e,0x84,0xd0,0xa8,0xa8,0x88,0x80,0x0,
-+0x10,0x10,0x17,0x10,0x13,0xfe,0x13,0x12,0x13,0x12,0x1f,0xf2,0x4f,0x1,0x3,0x4,0x40,0x44,0xfe,0x48,0xfc,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x8,0xfe,0x10,0xc,0x4,
-+0x0,0x3f,0x21,0x21,0x21,0x21,0x21,0x3f,0x21,0x21,0x21,0x21,0x21,0x3f,0x20,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,
-+0x4,0xe,0xf8,0x8,0xb,0x8,0xff,0x8,0xa,0x3f,0x22,0x22,0x22,0x3e,0x22,0x0,0x88,0x88,0x88,0x88,0xfe,0x88,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x88,0xf8,0x88,
-+0x10,0x10,0x17,0x10,0x58,0x54,0x57,0x90,0x10,0x13,0x12,0x12,0x12,0x12,0x13,0x12,0x10,0x78,0xc0,0x40,0x40,0x44,0xfe,0x40,0x48,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0xc,0xf3,0x10,0x10,0x13,0xfe,0x10,0x11,0x7d,0x46,0x45,0x45,0x46,0x7c,0x45,0x0,0x8,0xfc,0x40,0x44,0xfe,0x90,0x88,0x48,0x46,0x44,0x48,0x64,0x54,0x54,0x40,0x80,
-+0x8,0x7c,0x48,0x4b,0x4a,0x7a,0x4a,0x4b,0x4a,0x7a,0x4a,0x4f,0x48,0x49,0x8b,0x1c,0x90,0x90,0x94,0xfe,0x94,0x94,0x94,0xfc,0x94,0x94,0x94,0xfe,0x0,0x10,0xc,0x4,
-+0x10,0x10,0x10,0x10,0xfc,0x12,0x15,0x18,0x31,0xd2,0x14,0x11,0x11,0x12,0x54,0x28,0xa0,0xa0,0xa0,0xa0,0xa4,0xac,0xb0,0xa0,0xb0,0xa8,0xa8,0x20,0x22,0x22,0x1e,0x0,
-+0x8,0xf,0x18,0x24,0x43,0xc,0x30,0xc1,0x1,0x3f,0x1,0x9,0x11,0x21,0x5,0x2,0x0,0xf0,0x20,0x40,0x80,0x60,0x1e,0x4,0x10,0xf8,0x0,0x20,0x18,0x8,0x0,0x0,
-+0x0,0x47,0x31,0x11,0x1,0x2,0xf4,0x1b,0x12,0x12,0x12,0x13,0x12,0x28,0x47,0x0,0x8,0xfc,0x8,0x8,0x8,0x28,0x10,0xf8,0x8,0x8,0x8,0xf8,0x8,0x6,0xfc,0x0,
-+0x8,0x7c,0x48,0x48,0x48,0x7a,0x49,0x48,0x49,0x7a,0x4c,0x49,0x49,0x7a,0x44,0x8,0xa0,0xa0,0xa0,0xa0,0xa4,0xac,0xb0,0xa0,0xb0,0xa8,0xa8,0x20,0x22,0x22,0x1e,0x0,
-+0x4,0x7e,0x44,0x44,0x44,0x7e,0x11,0x10,0x5d,0x52,0x54,0x51,0x5d,0xf2,0x44,0x8,0xa0,0xa0,0xa0,0xa0,0xa4,0xac,0xb0,0xa0,0xb0,0xa8,0xa8,0x20,0x22,0x22,0x1e,0x0,
-+0x4,0x7e,0x44,0x54,0x54,0x54,0x54,0x55,0x55,0x55,0x55,0x55,0x11,0x29,0x45,0x81,0x40,0x40,0x44,0x7e,0x40,0x40,0x44,0xfe,0x4,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x11,0x11,0x1d,0x21,0x22,0x7c,0x93,0x10,0x7c,0x10,0x10,0x15,0x19,0x12,0x4,0x40,0x40,0x50,0xf8,0x40,0x40,0x48,0xfc,0x40,0x40,0xa0,0xa0,0x10,0x10,0xe,0x4,
-+0x10,0x10,0x14,0x7e,0x54,0x54,0x54,0x55,0x55,0x55,0x55,0x55,0x5d,0x11,0x11,0x11,0x40,0x40,0x44,0x7e,0x40,0x40,0x44,0xfe,0x4,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x3f,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x82,0x1,0x8,0xfc,0x0,0x0,0x4,0xfe,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0,
-+0x0,0x8,0x7d,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x4a,0x7a,0x44,0x8,0x0,0x10,0x38,0xc0,0x0,0x0,0x4,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x10,0x13,0x10,0x14,0x58,0x50,0x51,0x96,0x10,0x11,0x10,0x28,0x24,0x40,0x87,0x0,0x0,0xfc,0x8,0x10,0x20,0x58,0x86,0x2,0x8,0xfc,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x40,0x30,0x17,0x0,0x80,0x60,0x20,0x8,0x10,0x20,0xe0,0x20,0x20,0x20,0x21,0x20,0x0,0x4,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,
-+0x0,0x0,0xfb,0x8,0x10,0x20,0x47,0x78,0x8,0x8,0x48,0x2b,0x10,0x28,0x47,0x80,0x10,0x38,0xc0,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0x50,0xf8,0x0,0x6,0xfc,0x0,
-+0x10,0x10,0x17,0x20,0x23,0x62,0xa3,0x20,0x2f,0x28,0x33,0x20,0x20,0x20,0x21,0x20,0x80,0x48,0xfc,0x0,0xf8,0x8,0xf8,0x0,0xfe,0x2,0xf4,0x40,0x40,0x40,0x40,0x80,
-+0x2,0x1,0x7f,0x0,0x1f,0x10,0x1f,0x0,0x7f,0x40,0x9f,0x1,0x1,0x1,0x5,0x2,0x0,0x8,0xfc,0x10,0xf8,0x10,0xf0,0x0,0xfe,0x2,0xf4,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x0,0x3f,0x20,0x3f,0x22,0x24,0x28,0x2f,0x21,0x21,0x2a,0x44,0x4a,0x91,0x20,0x0,0x88,0xfc,0x0,0x1c,0x70,0x10,0x14,0xfe,0x10,0x10,0x10,0x7c,0x0,0x6,0xfc,
-+0x20,0x20,0x2f,0x21,0xf2,0x24,0x28,0x2f,0x31,0xe1,0x29,0x25,0x22,0x25,0xa8,0x50,0x0,0xc,0x70,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x7c,0x0,0x0,0x86,0x7c,
-+0x10,0x20,0x7f,0x48,0x49,0x6a,0x5c,0x4f,0xf8,0x48,0x48,0x6c,0x5a,0x49,0x8a,0x1c,0x0,0xc,0xf0,0x90,0x10,0x14,0x7e,0x90,0x90,0x90,0x90,0xfc,0x80,0x0,0x86,0x7c,
-+0x3,0x40,0x30,0x10,0x3,0x2,0xf2,0x13,0x12,0x12,0x13,0x12,0x12,0x2a,0x44,0x3,0xf8,0x10,0xa0,0x48,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x48,0x68,0x50,0x6,0xfc,
-+0x10,0x13,0x12,0x12,0xfe,0x12,0x32,0x3a,0x56,0x52,0x92,0x12,0x12,0x12,0x12,0x12,0x4,0xfe,0x4,0x4,0xf4,0x4,0x4,0xf4,0x94,0x94,0x94,0xf4,0x4,0x4,0x14,0x8,
-+0x4,0xfe,0x28,0x28,0xfe,0xaa,0xaa,0xae,0xc2,0x82,0x82,0xfe,0x82,0x82,0xfe,0x82,0x0,0xfe,0x82,0x82,0xfe,0x82,0x82,0xba,0xaa,0xaa,0xaa,0xba,0x82,0x82,0x8a,0x84,
-+0x0,0x0,0x7b,0x49,0x48,0x4f,0x78,0x4b,0x4a,0x7b,0x4a,0x4b,0x48,0x7b,0x40,0xf,0x80,0x48,0xfc,0x10,0xa4,0xfe,0x0,0xf8,0x48,0xf8,0x48,0xf8,0x40,0xf8,0x40,0xfe,
-+0x0,0x7f,0x40,0x40,0x5f,0x40,0x40,0x4f,0x48,0x48,0x48,0x48,0x4f,0x48,0x40,0x40,0x4,0xfe,0x4,0x24,0xf4,0x4,0x24,0xf4,0x24,0x24,0x24,0x24,0xe4,0x24,0x14,0x8,
-+0x20,0x23,0x3e,0x42,0x82,0x7a,0x22,0x22,0xfa,0x22,0x22,0x26,0x2a,0x32,0x22,0x2,0x4,0xfe,0x4,0x4,0xf4,0x4,0x4,0xf4,0x94,0x94,0x94,0xf4,0x4,0x4,0x14,0x8,
-+0x2,0x3f,0x22,0x22,0x32,0x2a,0x2a,0x22,0xff,0x22,0x22,0x22,0x22,0x42,0x4a,0x85,0x4,0xc,0x10,0x20,0x40,0x84,0xc,0x10,0xa0,0x42,0x6,0x8,0x10,0x20,0x40,0x80,
-+0x2,0x1,0x3f,0x8,0x4,0xff,0x0,0x1f,0x11,0x1f,0x11,0x1f,0x1,0x3f,0x1,0x7f,0x0,0x10,0xf8,0x20,0x44,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x0,0xf8,0x0,0xfc,
-+0x20,0x27,0x20,0x20,0xf8,0x27,0x74,0x6c,0xa7,0x24,0x24,0x27,0x24,0x24,0x24,0x24,0x0,0xf8,0x10,0xa0,0x44,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x44,0x44,0x54,0x48,
-+0x20,0x27,0x20,0x20,0xf8,0x27,0x24,0x2c,0x37,0xe4,0x24,0x27,0x24,0x24,0xa4,0x44,0x0,0xf8,0x10,0xa0,0x44,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x44,0x44,0x54,0x48,
-+0x10,0x14,0x3e,0x49,0x84,0x3f,0x20,0x2f,0x20,0x27,0x24,0x24,0x24,0x27,0x20,0x20,0x40,0x44,0xfe,0x20,0x10,0xf8,0x8,0xe8,0x8,0xc8,0x48,0x48,0x48,0xc8,0x28,0x10,
-+0x10,0x10,0x20,0x27,0x48,0xf9,0x12,0x27,0x41,0xf9,0x41,0x1,0x1a,0xe2,0x44,0x8,0x80,0x40,0x48,0xfc,0x80,0x10,0x8,0xfc,0x24,0x20,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x1,0x0,0x1f,0x10,0x97,0x50,0x50,0x17,0x34,0x57,0xd4,0x17,0x24,0x24,0x44,0x4,0x0,0x84,0xfe,0x0,0xf8,0xa0,0x44,0xfe,0x44,0xfc,0x44,0xfc,0x44,0x44,0x54,0x48,
-+0x10,0x10,0x11,0x22,0x24,0x6b,0xb0,0x27,0x24,0x27,0x24,0x27,0x24,0x24,0x24,0x25,0x80,0x80,0x40,0x20,0x10,0xee,0x4,0x88,0xa8,0xa8,0xa8,0xa8,0xa8,0x88,0xa8,0x90,
-+0x10,0x11,0x11,0x11,0xfd,0x11,0x15,0x1a,0x33,0xd0,0x11,0x10,0x10,0x10,0x51,0x26,0x10,0xf8,0x10,0x10,0x10,0x14,0xe,0x0,0xf8,0x8,0x10,0xa0,0x40,0xb0,0xe,0x4,
-+0x0,0x0,0x8,0x6,0x22,0x18,0x8,0x0,0xff,0x0,0x1,0x1,0x2,0x4,0x18,0x60,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x84,0xfe,0x80,0x0,0x60,0x10,0x8,0xc,0x4,
-+0x0,0x43,0x30,0x17,0x0,0x1,0xf2,0x17,0x11,0x11,0x12,0x12,0x14,0x28,0x44,0x3,0x18,0xe0,0x40,0xfc,0xe0,0x50,0x4e,0xf4,0x10,0x38,0x8,0x8,0x50,0x20,0x6,0xfc,
-+0x0,0xf,0x8,0x8,0x8,0x8,0x8,0x78,0x40,0x40,0x40,0x40,0x40,0x40,0x7f,0x40,0x20,0xf0,0x20,0x20,0x20,0x20,0x24,0x3e,0x4,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x3f,0x1,0x1,0xff,0x5,0x9,0x11,0x27,0x44,0x4,0x4,0x8,0x8,0x10,0x60,0xf0,0x0,0x0,0x4,0xfe,0x40,0x20,0x10,0xce,0x44,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x2,0x1,0x7f,0x44,0x88,0x11,0x1,0x1,0xff,0x1,0x2,0x2,0x4,0x8,0x30,0xc0,0x0,0x0,0xfe,0x42,0x34,0x10,0x40,0x24,0xfe,0x0,0x80,0x80,0x40,0x30,0xe,0x4,
-+0x0,0x7f,0x44,0x47,0x4c,0x52,0x41,0x42,0x46,0x49,0x70,0x46,0x41,0x40,0x7f,0x40,0x4,0xfe,0x4,0xe4,0x44,0x84,0x4,0x84,0x44,0x3c,0x94,0x4,0x4,0x84,0xfc,0x4,
-+0x8,0x8,0x10,0x27,0x48,0x8,0x17,0x30,0x52,0x92,0x12,0x12,0x15,0x14,0x18,0x10,0x40,0x40,0x48,0xfc,0x40,0x44,0xfe,0x40,0x48,0x7c,0x40,0x40,0x40,0xc6,0x7c,0x0,
-+0x0,0x40,0x30,0x11,0x2,0x5,0xf0,0x10,0x17,0x10,0x11,0x12,0x14,0x29,0x44,0x3,0x40,0x40,0xa0,0x10,0xe,0xf4,0x40,0x48,0xfc,0x40,0x50,0x4c,0x44,0x40,0x86,0xfc,
-+0x0,0x40,0x31,0x12,0x84,0x48,0x57,0x0,0x10,0x2f,0xe0,0x22,0x24,0x28,0x22,0x21,0x80,0x80,0x40,0x20,0x10,0x2e,0xf4,0x80,0x88,0xfc,0x80,0xa0,0x98,0x88,0x80,0x0,
-+0x0,0x3f,0x20,0x3f,0x21,0x2f,0x21,0x3f,0x21,0x22,0x27,0x2c,0x57,0x64,0x87,0x4,0x8,0xfc,0x8,0xf8,0x10,0xe0,0x44,0xfe,0x0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x7f,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x0,0x8,0x7c,0x48,0x48,0x48,0x4f,0x48,0x48,0x48,0x78,0x48,0x0,0x0,0xf,0x0,0x40,0x40,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x8,0xf,0x10,0x20,0x7f,0xa1,0x21,0x21,0x3f,0x22,0x2,0x4,0x4,0x8,0x10,0x60,0x0,0xe0,0x40,0x88,0xfc,0x8,0x8,0x8,0xf8,0x88,0xa0,0x90,0x92,0x82,0x7e,0x0,
-+0x0,0x44,0x34,0x14,0x87,0x40,0x4f,0x8,0x17,0x24,0xe4,0x24,0x24,0x24,0x24,0x24,0x40,0x44,0x44,0x44,0xfc,0x0,0xfe,0x84,0xfe,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xc,
-+0x0,0x7f,0x40,0x40,0x40,0x7f,0x41,0x42,0x44,0x48,0x50,0x60,0x42,0x41,0x7f,0x40,0x4,0xfe,0x84,0x84,0x94,0xfc,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x11,0xfd,0x13,0x15,0x19,0x31,0xd1,0x11,0x11,0x11,0x11,0x51,0x21,0xa0,0x90,0x84,0xfe,0x10,0x10,0xfc,0x10,0x10,0xfc,0x10,0x10,0x14,0xff,0x0,0x0,
-+0xc,0xf1,0x10,0x14,0xfe,0x10,0x38,0x56,0x92,0x38,0x28,0x28,0x2a,0x4c,0x48,0x81,0x4,0xfe,0x20,0x44,0xfe,0x84,0x94,0x94,0x94,0xa4,0xa4,0x20,0x58,0x44,0x82,0x2,
-+0x0,0x78,0x4c,0x4a,0x48,0x78,0x4e,0x4a,0x4a,0x7a,0x4a,0x4a,0x4a,0x4d,0x88,0x18,0x8,0xfc,0x88,0x88,0xf8,0x88,0x88,0xf8,0x84,0xa8,0x90,0x8c,0xc4,0x80,0x86,0x7c,
-+0x10,0x11,0x10,0x14,0x7f,0x55,0x55,0x55,0x55,0x7c,0x50,0x14,0x1d,0xf5,0x42,0x4,0x0,0x8,0x90,0x8,0xfc,0x8,0x8,0x8,0xf8,0x90,0x90,0x90,0x12,0x12,0xe,0x0,
-+0x40,0x34,0x13,0x1,0xfc,0x8,0x17,0x39,0x55,0x91,0x11,0x11,0x11,0x12,0x14,0x10,0x4,0x7e,0x44,0x44,0x7c,0x44,0x44,0x7c,0x42,0x54,0x48,0x66,0x42,0x80,0x46,0x3c,
-+0x3,0x42,0x32,0x13,0x2,0x2,0xf3,0x12,0x12,0x12,0x12,0x13,0x12,0x28,0x44,0x3,0xf8,0x8,0x8,0xf8,0x8,0x8,0xfc,0x8,0xd0,0x20,0x90,0xc,0x4,0x0,0x6,0xfc,
-+0x0,0x3f,0x2,0x2,0xff,0x4,0x4,0x8,0x10,0x2f,0x48,0x88,0x8,0x8,0xf,0x8,0x10,0xf8,0x0,0x4,0xfe,0x40,0x40,0x20,0x10,0xee,0x24,0x20,0x20,0x20,0xe0,0x20,
-+0x1,0x1,0x1,0xff,0x1,0x21,0x21,0x21,0x21,0x21,0x3f,0x21,0x1,0x1,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,0x2,0x2,0xfe,0x0,
-+0x7f,0x41,0x7f,0x52,0x7f,0x52,0x7f,0x52,0xa1,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x78,0x48,0x4c,0x80,0xfc,0x48,0x30,0x4e,0x84,0xf0,0x10,0xf0,0x10,0xf0,0x10,0x30,
-+0x10,0x10,0x10,0x10,0xfd,0x12,0x11,0x1d,0x31,0xd7,0x11,0x11,0x11,0x11,0x50,0x20,0x80,0x80,0x84,0xfe,0x20,0x20,0x24,0x3e,0xe4,0x24,0x34,0x28,0x22,0x2,0xfe,0x0,
-+0x10,0x10,0x17,0x10,0xfc,0x10,0x14,0x18,0x37,0xd0,0x10,0x10,0x10,0x10,0x50,0x20,0x10,0x38,0xc0,0x40,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x8,0x7d,0x48,0x48,0x4b,0x7a,0x4a,0x4a,0x4b,0x7a,0x48,0x48,0x49,0x49,0x8a,0x1c,0x0,0x10,0xa0,0x8,0xfc,0x8,0x8,0x8,0xf8,0xa8,0xa0,0xa0,0x20,0x22,0x22,0x1e,
-+0x10,0x20,0x7c,0x45,0x55,0x46,0x54,0x48,0x40,0x7e,0x2,0x12,0xfa,0x2,0x14,0x8,0x40,0x20,0x0,0xfe,0x2,0x4,0x80,0x88,0x90,0xe0,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x0,0x7c,0x44,0x49,0x49,0x52,0x48,0x48,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40,0x40,0x20,0x0,0xfe,0x2,0x4,0x80,0x88,0x90,0xe0,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x4,0x7e,0x4,0x24,0x24,0x27,0x24,0x24,0x3e,0x2,0x2,0x1a,0xe2,0x42,0x15,0xa,0x20,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x50,0x50,0x50,0x90,0x88,0xe,0x4,
-+0x4,0x7e,0x4,0x25,0x25,0x26,0x24,0x24,0x3e,0x2,0x2,0x1a,0xe2,0x42,0x14,0x8,0x40,0x20,0x0,0xfe,0x2,0x4,0x80,0x88,0x90,0xe0,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x20,0x27,0x24,0x25,0xfd,0x26,0x75,0x6d,0xa4,0x24,0x26,0x25,0x24,0x24,0x24,0x24,0x10,0x90,0x94,0x7e,0x10,0x24,0x7e,0xa4,0xa4,0xbc,0xa4,0x24,0x3c,0x24,0x24,0x2c,
-+0x0,0x3f,0x2,0x11,0xd,0x4,0x2,0x2,0xff,0x4,0x8,0x18,0x6,0x1,0x6,0x18,0x78,0x80,0x8,0x18,0x20,0x40,0x0,0x4,0xfe,0x10,0x10,0x20,0x40,0x80,0x60,0x10,
-+0x10,0x10,0x13,0x10,0xfc,0x11,0x15,0x19,0x33,0xd5,0x19,0x11,0x11,0x11,0x51,0x21,0x0,0x4,0xfe,0x80,0x80,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0xb,0x7c,0x48,0x4f,0x49,0x49,0x49,0x4f,0x49,0x49,0x79,0x4f,0x0,0x0,0x7,0x38,0xc0,0x40,0x44,0xfe,0x50,0x50,0x54,0xfe,0x50,0x50,0x54,0xfe,0x40,0x48,0xfc,
-+0x10,0x10,0x10,0x13,0xfa,0x14,0x11,0x1a,0x31,0xd0,0x10,0x11,0x12,0x12,0x52,0x21,0x40,0x20,0x0,0xfe,0x2,0x94,0x8,0x4,0xf8,0x10,0x60,0x80,0x0,0x2,0x2,0xfe,
-+0x0,0x8,0x7c,0x4b,0x48,0x48,0x4f,0x48,0x48,0x48,0x4f,0x78,0x48,0x0,0xf,0x0,0x40,0x40,0x48,0xfc,0x40,0x44,0xfe,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x0,
-+0x10,0x10,0x10,0x11,0x7c,0x54,0x57,0x54,0x54,0x7c,0x51,0x14,0x1c,0xf4,0x43,0x0,0x20,0x20,0x28,0xfc,0x20,0x24,0xfe,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x0,0x40,0x30,0x17,0x80,0x60,0x2f,0x8,0x10,0x20,0xe7,0x20,0x20,0x20,0x2f,0x20,0x40,0x40,0x48,0xfc,0x40,0x44,0xfe,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x0,
-+0x10,0x10,0x10,0x11,0xfc,0x24,0x27,0x24,0x24,0x44,0x29,0x10,0x28,0x44,0x87,0x0,0x20,0x20,0x28,0xfc,0x20,0x24,0xfe,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x0,0x7f,0x8,0x8,0xf,0x8,0x8,0xa,0x11,0x11,0x10,0x24,0x28,0x30,0x60,0x0,0x8,0xfc,0x0,0x20,0xf0,0x20,0x20,0x20,0x20,0x20,0x20,0x22,0x22,0x22,0x1e,0x0,
-+0x40,0x30,0x10,0x7,0xfc,0x8,0x10,0x37,0x58,0x94,0x11,0x11,0x12,0x14,0x10,0x10,0x40,0x40,0x44,0xfe,0x40,0x40,0x48,0xfc,0xe0,0xd0,0x48,0x4e,0x44,0x40,0x40,0x40,
-+0x0,0x7f,0x3,0x5,0x19,0x61,0x1,0x7f,0x1,0x9,0x9,0x9,0x9,0x9,0xff,0x0,0x8,0xfc,0x0,0x60,0x18,0x8,0x0,0xfc,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x0,
-+0x8,0x8,0x8,0x10,0x1f,0x21,0x21,0x62,0x92,0xa,0x4,0x8,0x10,0x20,0x40,0x0,0x40,0x40,0x40,0x40,0x40,0x60,0x50,0x48,0x46,0x42,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x8,0xfc,0x3,0x2,0x7d,0x49,0x49,0x49,0x7a,0x2,0x4d,0x48,0x10,0xf9,0x2,0x4,0x40,0x20,0xfe,0x2,0x4,0xde,0x54,0x54,0x54,0x54,0x5c,0x94,0x90,0x12,0xe,0x0,
-+0x1,0xff,0x4,0x14,0x34,0x44,0x3f,0x0,0x1f,0x10,0x1f,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x40,0x50,0x4c,0x44,0xf0,0x10,0xf0,0x0,0xf8,0x8,0x8,0x88,0x50,0x20,
-+0x40,0x3f,0x10,0x2,0x86,0x68,0x27,0x8,0x17,0x24,0xe7,0x20,0x20,0x20,0x20,0x20,0x44,0xfe,0xa0,0xa8,0xa6,0xa2,0xf8,0x8,0xf8,0x0,0xfc,0x4,0x4,0x44,0x28,0x10,
-+0x8,0xfd,0x10,0x10,0x10,0x13,0x7c,0x10,0x10,0x10,0x10,0x1c,0xf1,0x41,0x2,0x4,0x8,0xfc,0x0,0x0,0x4,0xfe,0x90,0x90,0x90,0x90,0x90,0x90,0x12,0x12,0xe,0x0,
-+0x8,0x7d,0x0,0x0,0x4,0xfe,0x28,0x28,0x28,0x28,0x28,0x2a,0x2c,0x48,0x80,0x1,0x4,0xfe,0x10,0x24,0xfe,0x84,0x94,0x94,0x94,0xa4,0xa4,0xa4,0x58,0x44,0x82,0x2,
-+0x2,0x2,0x2,0x2,0x7f,0x2,0x2,0xe,0x2,0x5,0x4,0x4,0x8,0x8,0x30,0xc0,0x0,0x0,0x0,0x20,0xf0,0x20,0x20,0x20,0x20,0x20,0xa0,0xa2,0x22,0x22,0x1e,0x0,
-+0x10,0x10,0x13,0x16,0x5a,0x51,0x50,0x90,0x13,0x10,0x10,0x28,0x25,0x45,0x82,0x4,0x40,0x20,0xfe,0x2,0x14,0xf8,0x0,0x8,0xfc,0x90,0x90,0x90,0x12,0x12,0xe,0x0,
-+0x2,0x1,0x7f,0x40,0x80,0x1f,0x0,0x0,0x7f,0x4,0x4,0x4,0x8,0x8,0x10,0x60,0x0,0x0,0xfe,0x2,0x24,0xf0,0x0,0x8,0xfc,0x80,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x0,0x8,0xff,0x12,0x15,0x21,0x21,0x79,0xaa,0x2a,0x2d,0x28,0x28,0x39,0x22,0x4,0x40,0x20,0xfe,0x2,0x4,0xde,0x54,0x54,0x54,0x54,0x5c,0x94,0x90,0x12,0xe,0x0,
-+0x10,0x10,0x11,0x12,0xfc,0x13,0x12,0x1a,0x32,0xd3,0x12,0x10,0x10,0x11,0x52,0x24,0x80,0x80,0xf8,0x10,0x24,0xfe,0x44,0x44,0x44,0xfc,0x64,0xa0,0xa2,0x22,0x1e,0x0,
-+0x0,0x8,0x7d,0x4a,0x4c,0x4b,0x4a,0x7a,0x4a,0x4b,0x4a,0x48,0x78,0x49,0x2,0x4,0x80,0x80,0xf8,0x10,0x24,0xfe,0x44,0x44,0x44,0xfc,0x64,0xa0,0xa2,0x22,0x1e,0x0,
-+0x10,0x10,0x21,0x7d,0x46,0x44,0x44,0x7c,0x47,0x44,0x44,0x44,0x7d,0x45,0x2,0x4,0x40,0x20,0xfe,0x2,0x14,0xf8,0x0,0x4,0xfe,0x90,0x90,0x90,0x12,0x12,0xe,0x0,
-+0x20,0x20,0x27,0x34,0xaa,0xa2,0xa3,0xa4,0x24,0x24,0x2a,0x21,0x21,0x22,0x24,0x28,0x80,0x40,0xfe,0x2,0x4,0x0,0xbc,0xa4,0xa4,0xb4,0xa8,0x20,0x22,0x22,0x1e,0x0,
-+0x2,0x1,0x7f,0x40,0x90,0x1e,0x12,0x12,0x22,0x32,0x4a,0x4,0x8,0x10,0x20,0x40,0x0,0x0,0xfe,0x2,0x4,0xf8,0x88,0x88,0x88,0xa8,0x90,0x80,0x82,0x82,0x7e,0x0,
-+0x20,0x20,0x23,0x22,0xfd,0x49,0x49,0x49,0x4a,0x92,0x55,0x20,0x50,0x49,0x82,0x4,0x40,0x20,0xfe,0x2,0x4,0xde,0x54,0x54,0x54,0x5c,0x54,0x90,0x92,0x12,0xe,0x0,
-+0x0,0x0,0xff,0x2,0x2,0x2,0x3,0x2,0x2,0x4,0x4,0x4,0x8,0x10,0x20,0x40,0x0,0x4,0xfe,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xa0,0x40,
-+0x8,0x7c,0x4b,0x4a,0x4d,0x79,0x49,0x49,0x4a,0x7a,0x4d,0x48,0x48,0x49,0x4a,0x9c,0x40,0x20,0xfe,0x2,0x4,0xdc,0x54,0x54,0x54,0x54,0x5c,0x94,0x90,0x12,0xe,0x0,
-+0x0,0x40,0x37,0x10,0x80,0x60,0x20,0xb,0x10,0x20,0xe0,0x20,0x20,0x20,0x2f,0x20,0x0,0x8,0xfc,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x0,0x7f,0x1,0x1,0x1,0x1,0x1,0x7f,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x2,0x1,0x1,0x0,0xff,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xf,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,
-+0x10,0x10,0x17,0x10,0xfc,0x10,0x30,0x38,0x57,0x50,0x90,0x10,0x10,0x10,0x1f,0x10,0x0,0x8,0xfc,0x40,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x0,0x7f,0x40,0x42,0x62,0x54,0x54,0x48,0x48,0x54,0x52,0x62,0x61,0x42,0x40,0x40,0x4,0xfe,0x4,0xc,0x8c,0x54,0x54,0x24,0x24,0x54,0x4c,0x8c,0x4,0x4,0x14,0x8,
-+0x8,0x8,0x10,0x27,0x40,0x8,0x8,0x10,0x37,0x50,0x90,0x10,0x10,0x10,0x1f,0x10,0x80,0x40,0x8,0xfc,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x0,0x0,0x7,0x78,0x48,0x48,0x48,0x78,0x4f,0x48,0x48,0x48,0x78,0x40,0xf,0x0,0x0,0x8,0xfc,0x40,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x10,0xa,0xff,0x20,0x20,0x26,0x38,0x20,0x0,0x3f,0x1,0x1f,0x1,0x1,0xff,0x0,0x4,0x7e,0x44,0x7c,0x44,0x7c,0x44,0x8c,0x0,0xf8,0x0,0xf0,0x0,0x4,0xfe,0x0,
-+0x2,0x1,0xff,0x10,0x10,0x10,0x10,0x1f,0x0,0x2,0x11,0x50,0x50,0x90,0xf,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x84,0x92,0x12,0xf0,0x0,
-+0x2,0x1,0x7f,0x10,0x10,0x10,0x1f,0x2,0x2,0xff,0x4,0x8,0x4,0x3,0x4,0x38,0x0,0x8,0xfc,0x0,0x0,0x20,0xf0,0x0,0x4,0xfe,0x20,0x20,0x40,0x80,0x60,0x10,
-+0x0,0x0,0x0,0x3f,0x20,0x3f,0x24,0x24,0x3f,0x29,0x31,0x2a,0x24,0x4a,0x91,0x2,0x80,0xa0,0x90,0xfc,0x80,0x80,0x84,0x44,0xc8,0x48,0x30,0x20,0x60,0x92,0xa,0x6,
-+0x1,0x21,0x3f,0x0,0x7c,0x11,0xff,0x39,0x55,0x11,0xfd,0x24,0x48,0x30,0x29,0x46,0x0,0x8,0xf8,0x20,0x44,0xfe,0x24,0xfc,0x24,0xfc,0x44,0x60,0xa8,0xa2,0x22,0x1e,
-+0x12,0x12,0x2a,0x4a,0x8a,0x1f,0x20,0x7f,0xa0,0x2f,0x29,0x29,0x29,0x29,0x30,0x20,0x10,0x10,0x90,0xa4,0xbe,0xc4,0x24,0xa8,0x28,0x28,0x10,0x50,0xa8,0x28,0x46,0x84,
-+0x8,0xf,0x10,0x20,0x5f,0x10,0x10,0x13,0x12,0x12,0x12,0x12,0x22,0x22,0x41,0x80,0x0,0xe0,0x40,0x88,0xfc,0x0,0x10,0xf8,0x10,0x10,0x50,0x20,0x2,0x2,0xfe,0x0,
-+0x1,0x1,0x1,0xff,0x1,0x1,0x3f,0x1,0x1,0x7f,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x4,0xfe,0x0,0x10,0xf8,0x0,0x4,0xfe,0x4,0x4,0x4,0x28,0x10,0x0,
-+0x0,0x40,0x2f,0x20,0x0,0x7,0xe0,0x20,0x2f,0x20,0x20,0x20,0x20,0x50,0x8f,0x0,0x80,0x88,0xfc,0x80,0x90,0xf8,0x80,0x88,0xfc,0x88,0x88,0xa8,0x90,0x86,0xfc,0x0,
-+0x10,0x10,0x11,0x12,0xff,0x12,0x32,0x3a,0x56,0x52,0x92,0x12,0x12,0x14,0x14,0x18,0x80,0xf8,0x10,0x24,0xfe,0x0,0x8,0xfc,0x88,0x88,0xa8,0x90,0x82,0x82,0x7e,0x0,
-+0x0,0x7f,0x41,0x41,0x5f,0x41,0x4f,0x41,0x5f,0x41,0x41,0x41,0x41,0x41,0x7f,0x40,0x4,0xfe,0x4,0x24,0xf4,0x4,0xe4,0x4,0xf4,0x14,0x14,0x54,0x24,0x4,0xfc,0x4,
-+0x0,0x8,0x7c,0x49,0x49,0x4b,0x4d,0x49,0x49,0x49,0x49,0x79,0x49,0x1,0x1,0x1,0x80,0xa0,0x94,0xfe,0x10,0x10,0xfc,0x10,0x10,0xfc,0x10,0x10,0x14,0xfe,0x0,0x0,
-+0x10,0x10,0x10,0x11,0x59,0x57,0x55,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x80,0xa0,0x94,0xfe,0x10,0x10,0xfc,0x10,0x10,0xfc,0x10,0x10,0x14,0xfe,0x0,0x0,
-+0x0,0x10,0xc,0x4,0x0,0xff,0x1,0x1,0x2,0x2,0x4,0x8,0x10,0x20,0x40,0x0,0x80,0x80,0x80,0x80,0x84,0xfe,0x4,0x4,0x4,0x84,0x64,0x24,0x4,0x4,0x28,0x10,
-+0x0,0x44,0x24,0x24,0x88,0x5f,0x42,0x4,0x28,0x5f,0xc0,0x40,0x43,0x5c,0x48,0x40,0x40,0x50,0x44,0xfe,0x90,0x90,0xfc,0x90,0x90,0xfc,0x90,0x90,0x94,0xfe,0x80,0x80,
-+0x10,0x10,0x20,0x21,0x49,0xfb,0x15,0x21,0x41,0xfd,0x1,0x1,0x1d,0xe1,0x41,0x1,0x80,0xa0,0x94,0xfe,0x10,0x10,0xfc,0x10,0x10,0xfc,0x10,0x10,0x14,0xfe,0x0,0x0,
-+0x8,0x8,0xff,0x9,0x1,0x7f,0x1,0x3f,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x20,0x24,0xfe,0x20,0x8,0xfc,0x0,0xf8,0x0,0xfc,0x4,0x4,0x4,0x28,0x10,0x0,
-+0x4,0x4,0xff,0x4,0x1f,0x1,0x7f,0x5,0x19,0x2,0xff,0x4,0x8,0x7,0x4,0x18,0x40,0x44,0xfe,0x40,0xf0,0x0,0xfc,0x40,0x30,0x4,0xfe,0x20,0x40,0x80,0x60,0x10,
-+0x0,0x3f,0x1,0x1,0xff,0x5,0x9,0x31,0x5,0xff,0x4,0x8,0x4,0x3,0xc,0x30,0x30,0xc0,0x0,0x4,0xfe,0x40,0x38,0x10,0x4,0xfe,0x20,0x20,0x40,0x80,0x60,0x10,
-+0x8,0x8,0x8,0x17,0x10,0x30,0x57,0x90,0x10,0x1f,0x10,0x10,0x10,0x10,0x10,0x10,0x40,0x40,0x44,0xfe,0x40,0x48,0xfc,0x40,0x44,0xfe,0x44,0x44,0x54,0x48,0x40,0x40,
-+0x8,0xa,0x9,0x10,0x17,0x30,0x50,0x90,0x10,0x10,0x11,0x11,0x12,0x14,0x18,0x10,0x40,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0xc4,0xa4,0x14,0x4,0x4,0x4,0x28,0x10,
-+0x0,0x3f,0x20,0x20,0x3f,0x20,0x2f,0x21,0x21,0x2f,0x21,0x21,0x5f,0x41,0x81,0x0,0x8,0xfc,0x8,0x8,0xf8,0x20,0xf0,0x8,0xfc,0x0,0x8,0xfc,0x0,0x2,0x2,0xfe,
-+0x10,0x10,0x20,0x27,0x48,0xf8,0x17,0x20,0x40,0xff,0x0,0x0,0x1c,0xe0,0x40,0x0,0x40,0x40,0x44,0xfe,0x40,0x48,0xfc,0x40,0x44,0xfe,0x44,0x44,0x54,0x48,0x40,0x40,
-+0x1,0x1,0x1,0x7f,0x1,0x1,0x1,0xff,0x3,0x5,0x9,0x11,0x21,0x41,0x1,0x1,0x0,0x0,0x8,0xfc,0x0,0x0,0x4,0xfe,0x80,0x40,0x20,0x10,0xe,0x4,0x0,0x0,
-+0x8,0x8,0xff,0x8,0x3f,0x21,0x3f,0x20,0x3f,0x20,0x3f,0x44,0x56,0x95,0x24,0xc,0x20,0x24,0xfe,0x20,0x8,0x8,0x8,0xfe,0x8,0x48,0x28,0x28,0x8,0x8,0x28,0x10,
-+0x0,0x8,0x7c,0x4b,0x48,0x48,0x48,0x4f,0x48,0x48,0x49,0x7a,0x44,0x8,0x0,0x0,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x40,0xe0,0x50,0x50,0x4e,0x44,0x40,0x40,
-+0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x0,0xff,0x10,0x12,0x11,0x10,0x14,0x18,0x10,0xf0,0x10,0x10,0xf0,0x10,0x10,0xf0,0x4,0xfe,0x0,0x20,0x40,0x80,0x60,0x1c,0x8,
-+0x0,0x3f,0x21,0x3f,0x21,0x3f,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x10,0x10,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0x10,0x50,0x20,
-+0x0,0xb,0x7e,0x4a,0x4b,0x4a,0x4a,0x4b,0x48,0x4f,0x4a,0x7a,0x4a,0x2,0x3,0x2,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x0,0xfe,0x88,0x50,0x20,0x90,0xe,0x4,
-+0x6,0xf8,0x11,0x11,0xff,0x39,0x55,0x91,0x11,0xfe,0x24,0x44,0x28,0x11,0x2a,0x44,0x40,0x84,0xfe,0x24,0x24,0xfc,0x24,0x44,0xfc,0x40,0x60,0xa0,0xa8,0x22,0x22,0x1e,
-+0x8,0x8,0x8,0x10,0x17,0x30,0x52,0x92,0x11,0x11,0x10,0x10,0x10,0x1f,0x10,0x10,0x80,0x40,0x40,0x8,0xfc,0x0,0x8,0x8,0x10,0x10,0x90,0xa0,0x24,0xfe,0x0,0x0,
-+0x0,0x47,0x34,0x17,0x84,0x67,0x20,0xb,0x12,0x23,0xe2,0x23,0x22,0x22,0x22,0x22,0x4,0xfe,0x44,0xfc,0x44,0xfc,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x0,0x47,0x24,0x27,0x4,0x7,0xe0,0x23,0x22,0x23,0x22,0x23,0x2a,0x32,0x22,0x2,0x4,0xfe,0x44,0xfc,0x44,0xfc,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x1,0x3f,0x21,0x21,0x3f,0x20,0x3f,0x20,0x3f,0x24,0x24,0x55,0x54,0xa4,0x14,0x8,0x8,0x88,0x8,0x8,0x8,0xfe,0x8,0x48,0x28,0x28,0x8,0x8,0x88,0x8,0x28,0x10,
-+0x3f,0x21,0x3f,0x20,0x3f,0x20,0x3f,0x24,0x56,0x95,0x2c,0x2,0x51,0x50,0x90,0xf,0x8,0x8,0x8,0xfe,0x8,0x48,0x28,0x28,0x8,0x28,0x10,0x0,0x84,0x92,0x12,0xf0,
-+0x0,0x0,0x7f,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0xff,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0x8,0x28,0x10,0x0,0x0,0x4,0xfe,0x0,
-+0x1,0x0,0x1f,0x10,0x93,0x52,0x53,0x12,0x33,0x50,0xd7,0x14,0x24,0x24,0x4f,0x0,0x0,0x84,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfc,0xa4,0xa4,0xa4,0xfe,0x0,
-+0x0,0x43,0x32,0x12,0x83,0x62,0x22,0xb,0x10,0x27,0xe4,0x24,0x24,0x24,0x2f,0x20,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x0,0xfc,0xa4,0xa4,0xa4,0xa4,0xfe,0x0,
-+0x10,0x10,0x10,0x14,0x7f,0x54,0x54,0x54,0x54,0x7c,0x50,0x14,0x1e,0xe2,0x41,0x2,0x40,0x20,0x20,0x4,0xfe,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x2,0x1,0x1,0xff,0x10,0x8,0x8,0x4,0x4,0x2,0x1,0x2,0x4,0x8,0x30,0xc0,0x0,0x0,0x4,0xfe,0x10,0x10,0x20,0x20,0x40,0x80,0x0,0x80,0x60,0x10,0xe,0x4,
-+0x20,0x1b,0x48,0x40,0x5f,0x44,0x47,0x44,0x47,0x44,0x44,0x5f,0x40,0x40,0x40,0x40,0x4,0xfe,0x4,0x24,0xf4,0x44,0xc4,0x44,0xc4,0x44,0x44,0xf4,0x44,0x44,0x54,0x8,
-+0x10,0x10,0x20,0x20,0x4f,0xfa,0x11,0x21,0x40,0xfc,0x0,0x0,0x1c,0xe1,0x42,0x4,0x80,0x40,0x40,0x4,0xfe,0x8,0x10,0x10,0xa0,0xa0,0x40,0xa0,0xa0,0x10,0xe,0x4,
-+0x1,0x9,0x7d,0x49,0x4a,0x4c,0x48,0x48,0x49,0x49,0x49,0x7a,0x4c,0x1,0x2,0x0,0x0,0x0,0x4,0xfe,0xa4,0xa4,0xa4,0xa4,0x24,0x24,0x44,0x44,0x84,0x4,0x28,0x10,
-+0x8,0x1c,0xf0,0x11,0x12,0xff,0x10,0x33,0x38,0x57,0x50,0x95,0x15,0x19,0x10,0x10,0x40,0x40,0xf8,0x10,0x24,0xfe,0x4,0xfc,0x4,0xfc,0x40,0x24,0x22,0xa,0xf8,0x0,
-+0x2,0x1,0x7f,0x8,0x4,0x3,0x1c,0xe2,0x1f,0x1,0x2,0x3f,0x9,0x11,0x25,0x2,0x0,0x8,0xfc,0x20,0x40,0x80,0x70,0x4e,0x80,0x20,0x10,0xf0,0x20,0x18,0x8,0x0,
-+0x20,0x1b,0x8,0x40,0x40,0x4f,0x48,0x48,0x48,0x48,0x48,0x4f,0x48,0x40,0x40,0x40,0x4,0xfe,0x4,0x4,0x24,0xf4,0x24,0x24,0x24,0x24,0x24,0xe4,0x24,0x4,0x14,0x8,
-+0x0,0x10,0x79,0x52,0x54,0x59,0x53,0x50,0x57,0x50,0x54,0x72,0x54,0x0,0x2,0x1,0x20,0xa0,0x10,0x48,0x86,0x14,0xf8,0x0,0xbc,0x84,0xa4,0x94,0xa4,0x84,0x94,0x8,
-+0x4,0x4,0x9,0x12,0xe4,0xf,0x0,0x3e,0x2,0x22,0x12,0xa,0x12,0x22,0xa,0x4,0x40,0x40,0x20,0x10,0x4e,0xe0,0x8,0xfc,0x8,0x88,0x48,0x28,0x48,0x88,0x28,0x10,
-+0x4,0x4,0x9,0x12,0xe4,0xf,0x0,0x7f,0x8,0x8,0xf,0x9,0x8,0xb,0x1c,0x0,0x40,0x40,0x20,0x10,0x4e,0xe0,0x8,0xfc,0x0,0x20,0xf0,0x20,0xa0,0x22,0x22,0x1e,
-+0x10,0x10,0x14,0x12,0xf8,0x10,0x16,0x1a,0x32,0xd2,0x12,0x12,0x12,0x15,0x58,0x20,0x8,0x8,0x8,0x8,0xfe,0x8,0x8,0x48,0x28,0x28,0x8,0x8,0x28,0x16,0xfc,0x0,
-+0x10,0x10,0x10,0x14,0x7e,0x54,0x54,0x55,0x7d,0x55,0x11,0x15,0x1d,0xe5,0x41,0x1,0x8,0xfc,0x88,0x88,0x88,0xf8,0x24,0xfe,0x24,0x24,0x54,0x8c,0x4,0x4,0x14,0x8,
-+0x0,0x43,0x32,0x12,0x82,0x63,0x20,0xf,0x14,0x24,0xe4,0x24,0x25,0x24,0x24,0x24,0x8,0xfc,0x8,0x8,0x8,0xf8,0x44,0xfe,0x44,0x44,0x44,0xa4,0x14,0x4,0x14,0x8,
-+0x2,0x1,0x7f,0x44,0x88,0x1f,0x28,0x8,0xf,0x1,0x3f,0x21,0x22,0x2c,0x20,0x20,0x0,0x0,0xfe,0x42,0x24,0xf0,0x28,0x20,0xe0,0x8,0xfc,0x8,0x88,0x68,0x28,0x10,
-+0x4,0xe,0x78,0x8,0x8,0xff,0x8,0x8,0xa,0xc,0x18,0x68,0x9,0xa,0x28,0x10,0x80,0xa0,0x90,0x90,0x84,0xfe,0x80,0x90,0x90,0x60,0x40,0xa0,0x20,0x14,0x14,0xc,
-+0x10,0x14,0xfe,0x10,0x7c,0x45,0x7e,0x44,0x7d,0x10,0xfe,0x11,0x10,0x10,0x10,0x10,0x20,0x20,0x50,0x50,0x88,0x16,0x94,0x50,0x10,0x94,0x1e,0xf0,0x10,0x10,0x10,0x10,
-+0x2,0x7f,0x48,0x48,0x48,0x7e,0x42,0x42,0x42,0x7e,0x48,0x48,0x4a,0x7f,0x0,0x0,0x40,0x40,0x40,0x40,0x40,0x60,0x50,0x48,0x44,0x44,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x10,0x13,0x12,0x12,0xff,0x12,0x17,0x1a,0x32,0xd3,0x12,0x12,0x14,0x14,0x5b,0x20,0x8,0xfc,0x8,0x8,0xf8,0x0,0xfc,0x40,0x88,0xfc,0x20,0xf8,0x20,0x24,0xfe,0x0,
-+0x0,0x40,0x37,0x10,0x80,0x60,0x2f,0x8,0x10,0x20,0xe0,0x20,0x21,0x22,0x24,0x28,0x8,0x3c,0xc0,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,
-+0x0,0x0,0x7f,0x1,0x11,0x11,0x11,0x11,0x29,0x29,0x45,0x85,0x1,0x1,0xff,0x0,0x0,0x8,0xfc,0x0,0x10,0x10,0x10,0x10,0x28,0x28,0x44,0x84,0x0,0x4,0xfe,0x0,
-+0x0,0x8,0x7d,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x48,0x78,0x47,0x0,0x0,0x0,0x40,0x88,0xfc,0x8,0x8,0x8,0x28,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x10,0x10,0x11,0x1d,0x21,0x21,0x7d,0x91,0x11,0x7d,0x10,0x10,0x17,0x18,0x10,0x0,0x40,0x88,0xfc,0x8,0x8,0x8,0x28,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x2,0x4,0x1f,0x10,0x10,0x10,0x10,0x10,0x10,0x1f,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x20,0xf0,0x20,0x20,0x20,0xa0,0x40,0x4,0xfe,0x4,0x24,0xf4,0x4,0x28,0x10,
-+0x0,0x23,0x18,0x8,0x80,0x6f,0x21,0x9,0x11,0x23,0xe0,0x20,0x20,0x20,0x20,0x20,0x8,0xfc,0x0,0x0,0x4,0xfe,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x88,0x50,0x20,
-+0x40,0x37,0x10,0x0,0x2,0xe2,0x22,0x22,0x25,0x29,0x20,0x28,0x30,0x20,0x1f,0x0,0x8,0xfc,0x40,0x40,0x48,0x48,0x48,0x48,0x54,0x64,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x0,0x3f,0x20,0x3f,0x20,0x2f,0x21,0x22,0x27,0x20,0x20,0x3f,0x40,0x40,0xbf,0x0,0x8,0xfc,0x8,0xf8,0x0,0xfc,0x0,0x20,0xf0,0x80,0x88,0xfc,0x80,0x84,0xfe,0x0,
-+0x0,0x3f,0x2,0x2,0x2,0x2,0x7f,0x2,0x2,0x4,0x4,0x8,0x8,0x10,0x20,0x40,0x20,0xf0,0x0,0x0,0x0,0x8,0xfc,0x80,0x80,0x80,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x4,0x4,0xff,0x4,0x0,0x3f,0x2,0x2,0x7f,0x2,0x2,0x4,0x4,0x8,0x10,0x60,0x40,0x44,0xfe,0x40,0x0,0xf0,0x0,0x8,0xfc,0x80,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x10,0x13,0x10,0x10,0xfd,0x10,0x39,0x35,0x57,0x50,0x91,0x11,0x11,0x11,0x11,0x11,0x8,0xfc,0x80,0x88,0xfc,0x88,0x8,0x8,0xfe,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x7f,0x4,0x4,0x3f,0x8,0x8,0xff,0x0,0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x8,0xfc,0x0,0x20,0xf0,0x20,0x24,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,
-+0x0,0x1f,0x10,0x10,0x1f,0x0,0x0,0x3f,0x1,0x1,0xff,0x2,0x2,0x4,0x18,0x60,0x10,0xf8,0x10,0x10,0xf0,0x0,0x10,0xf8,0x0,0x4,0xfe,0x80,0x40,0x20,0x1c,0x8,
-+0x0,0x1f,0x11,0x11,0x11,0x11,0x11,0xff,0x11,0x11,0x22,0x22,0x3f,0x8,0x10,0x20,0x10,0xf8,0x10,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0xfc,0x10,0x50,0x20,
-+0x0,0x2,0x3f,0x0,0x0,0xff,0x4,0x4,0x27,0x24,0x24,0x24,0x27,0xf8,0x40,0x0,0x40,0x50,0x48,0x48,0x40,0xfe,0x40,0x40,0x40,0x40,0x20,0x20,0xa0,0x12,0xa,0x6,
-+0x0,0x0,0x7f,0x2,0x2,0x2,0x2,0x3f,0x4,0x4,0x4,0x8,0x8,0x8,0xff,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x10,0xfc,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x0,
-+0x10,0x13,0x10,0x10,0xfd,0x10,0x15,0x19,0x37,0xd0,0x11,0x11,0x11,0x11,0x51,0x21,0x8,0xfc,0x80,0x88,0xfc,0x88,0x8,0x8,0xfe,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x8,0x8,0xf,0x11,0x11,0x21,0x41,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x10,0xf8,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x20,0x3f,0x52,0x92,0x7f,0x12,0x12,0xff,0x10,0x1e,0x22,0x52,0xd,0x18,0xe0,0x0,0x8,0xfc,0x90,0x90,0xfc,0x90,0x94,0xfe,0x10,0xfc,0x90,0x94,0xfe,0x10,0x10,0x10,
-+0x10,0x10,0x17,0x20,0x20,0x60,0xa0,0x27,0x21,0x21,0x21,0x22,0x22,0x22,0x3f,0x20,0x0,0x8,0xfc,0x80,0x80,0x80,0x88,0xfc,0x8,0x8,0x8,0x8,0x8,0x8,0xfe,0x0,
-+0x9,0x9,0x9,0x12,0x15,0x31,0x51,0x91,0x1f,0x12,0x12,0x12,0x13,0x10,0x10,0x10,0x0,0x8,0xfc,0x0,0xf8,0x48,0x28,0x8,0xfe,0x48,0x28,0x8,0xfc,0x8,0x28,0x10,
-+0x10,0x10,0x11,0x11,0x11,0xfd,0x11,0x11,0x11,0x11,0x10,0x1c,0xf3,0x40,0x0,0x0,0x40,0x88,0xfc,0x8,0x8,0x8,0x28,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x0,0x0,0x0,0x3f,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x83,0x0,0x80,0xa0,0x90,0xfc,0x80,0x80,0x84,0x44,0x48,0x48,0x30,0x20,0x60,0x92,0xa,0x6,
-+0x3f,0x1,0x7f,0x51,0x89,0x14,0x7,0xc,0x13,0xc,0xf2,0xf,0x2,0x4,0x8,0x30,0xf8,0x0,0xfe,0x12,0x24,0x10,0xe0,0x40,0x80,0x60,0x1e,0xe4,0x20,0x20,0xa0,0x40,
-+0x0,0xb,0x7c,0x48,0x49,0x48,0x49,0x79,0x4f,0x48,0x49,0x49,0x79,0x49,0x1,0x1,0x8,0xfc,0x80,0x88,0xfc,0x88,0x8,0x8,0xfe,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x11,0x11,0x51,0x51,0x7b,0x54,0x90,0x1c,0x31,0xd1,0x12,0x12,0x14,0x10,0x11,0x10,0x0,0x0,0x0,0x4,0xfe,0xa4,0xa4,0xa4,0x24,0x44,0x44,0x44,0x84,0x84,0x28,0x10,
-+0x10,0x10,0x10,0x1f,0x24,0x44,0x84,0x8,0x8,0x8,0x10,0x11,0x21,0x42,0x4,0x8,0x0,0x0,0x4,0xfe,0x44,0x44,0x44,0x44,0x84,0x84,0x84,0x4,0x4,0x4,0x28,0x10,
-+0x8,0x8,0xf,0x18,0x26,0x41,0x6,0x1a,0xe2,0x1f,0x2,0x2,0x4,0x4,0x8,0x30,0x0,0x0,0xf0,0x20,0xc0,0x0,0xc0,0x30,0xe,0xf4,0x10,0x10,0x10,0x10,0xa0,0x40,
-+0x10,0x13,0x10,0x10,0x59,0x54,0x51,0x91,0x17,0x10,0x11,0x11,0x11,0x11,0x11,0x11,0x8,0xfc,0x80,0x88,0xfc,0x88,0x8,0x8,0xfe,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x43,0x32,0x12,0x3,0x0,0xe7,0x20,0x20,0x2f,0x20,0x20,0x28,0x31,0x22,0x4,0x8,0xfc,0x8,0x8,0xf8,0x0,0xfc,0x40,0x44,0xfe,0x40,0xa0,0xa0,0x10,0xe,0x4,
-+0x4,0x4,0x3f,0x4,0x4,0x4,0xff,0x0,0xf,0x8,0x8,0xf,0x8,0x8,0xf,0x8,0x40,0x50,0xf8,0x40,0x40,0x44,0xfe,0x20,0xf0,0x20,0x20,0xe0,0x20,0x20,0xe0,0x20,
-+0x2,0x7f,0x44,0x44,0x5f,0x51,0x51,0x5f,0x44,0x44,0x7f,0x0,0x24,0x22,0x42,0x80,0x4,0x7e,0x44,0x44,0x44,0x7c,0x40,0x40,0x44,0x44,0x3c,0x0,0x88,0x44,0x42,0x2,
-+0x10,0x10,0x11,0x11,0xfd,0x11,0x31,0x39,0x55,0x51,0x91,0x11,0x12,0x12,0x14,0x10,0x8,0x1c,0xe0,0x0,0x0,0x4,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x0,0x0,0xff,0x4,0x4,0x4,0x7f,0x44,0x44,0x44,0x44,0x48,0x50,0x40,0x7f,0x40,0x0,0x4,0xfe,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0x34,0x4,0x4,0xfc,0x4,
-+0x0,0xb,0xfc,0x10,0x10,0x21,0x25,0x7f,0xa5,0x25,0x25,0x25,0x25,0x3d,0x25,0x1,0x4,0xfe,0x50,0x50,0x54,0xfe,0x54,0x54,0x54,0x54,0x5c,0x84,0x4,0x4,0xfc,0x4,
-+0x0,0x4,0xfe,0x10,0x10,0x20,0x20,0x7d,0xa6,0x24,0x24,0x24,0x24,0x3c,0x24,0x1,0x40,0x40,0x40,0x7e,0x42,0x82,0x84,0x44,0x24,0x18,0x8,0x10,0x20,0x40,0x80,0x0,
-+0x1,0x9,0x7d,0x49,0x4f,0x49,0x4b,0x7b,0x4d,0x49,0x49,0x49,0x79,0x49,0x1,0x1,0x0,0x6,0x38,0x20,0xe0,0x20,0xbe,0x68,0x28,0x28,0x28,0x28,0x48,0x48,0x88,0x8,
-+0x0,0x8,0x7f,0x48,0x4b,0x48,0x4b,0x4a,0x4b,0x49,0x4f,0x78,0x4b,0x2,0x2,0x3,0x40,0x48,0xfc,0x40,0xf8,0x0,0xf8,0x8,0xf8,0x10,0xfe,0x8,0xfc,0x8,0x8,0xf8,
-+0x0,0x7,0x7a,0x4a,0x4a,0x4a,0x4b,0x4a,0x4a,0x4a,0x4a,0x7a,0x4c,0x8,0x11,0x2,0x8,0xfc,0x8,0x8,0x10,0x20,0x3c,0x84,0x88,0x48,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x10,0x11,0x11,0x1d,0x21,0x21,0x7d,0x91,0x11,0x7d,0x12,0x10,0x15,0x1a,0x10,0x0,0x8,0xfc,0x8,0xf8,0x8,0x8,0xf8,0x4,0xfe,0x54,0x54,0xa4,0x24,0x44,0xa8,0x10,
-+0x10,0x10,0x57,0x50,0x7c,0x50,0x97,0x1a,0x32,0xd2,0x12,0x12,0x13,0x12,0x13,0x12,0x0,0x4,0xfe,0x90,0x90,0x94,0xfe,0x94,0x94,0x94,0x94,0x8c,0x4,0x4,0xfc,0x4,
-+0x9,0x1c,0xf0,0x10,0x11,0xfc,0x13,0x38,0x35,0x51,0x53,0x95,0x11,0x10,0x10,0x10,0x4,0xd8,0x20,0xd8,0x4,0x80,0xfe,0xa0,0x24,0xfe,0x24,0x24,0x34,0x28,0x20,0x20,
-+0x2,0x4,0x1f,0x10,0x10,0x1f,0x10,0x1f,0x10,0x10,0x1f,0x2,0x51,0x50,0x90,0xf,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0xf0,0x10,0x10,0xf0,0x0,0x84,0x92,0x12,0xf0,
-+0x8,0x6,0x1,0x6,0x3a,0x2,0xff,0x4,0x8,0x1f,0x28,0xc8,0x8,0x8,0x0,0x0,0x30,0xc0,0x0,0xc0,0x38,0x0,0xfe,0x80,0x88,0xfc,0x88,0x88,0xa8,0x90,0x80,0x80,
-+0x0,0x3f,0x11,0x9,0x5,0xff,0x3,0x5,0x9,0x31,0x0,0x12,0x51,0x50,0x90,0xf,0xf8,0x0,0x10,0x20,0x44,0xfe,0x80,0x60,0x1c,0x8,0x0,0x0,0x84,0x92,0x12,0xf0,
-+0x0,0x78,0x4f,0x48,0x49,0x7a,0x48,0x49,0x4e,0x7a,0x49,0x48,0x49,0x4a,0x48,0x98,0x40,0x44,0xfe,0xe0,0x58,0x48,0xa0,0x10,0x4e,0x48,0x50,0xe0,0x58,0x48,0x40,0xc0,
-+0x2,0x2,0x2,0x7,0x4,0x8,0x10,0x24,0x43,0x1,0x0,0x1,0x2,0x4,0x18,0x60,0x0,0x0,0x8,0xfc,0x8,0x8,0x10,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,
-+0x11,0x11,0x17,0x11,0x59,0x55,0x5f,0x90,0x13,0x12,0x12,0x13,0x12,0x12,0x13,0x12,0x10,0x10,0xfc,0x10,0x10,0x14,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x13,0x12,0x56,0x5b,0x52,0x93,0x12,0x12,0x13,0x28,0x2a,0x46,0x8a,0x1,0x40,0x88,0xfc,0x8,0x8,0xf8,0x8,0xf8,0x8,0x8,0xf8,0x80,0x60,0x2c,0xa,0xf8,
-+0x11,0x10,0x10,0x14,0x59,0x50,0x57,0x90,0x11,0x11,0x13,0x2d,0x29,0x45,0x80,0x0,0x4,0xd8,0x20,0xd8,0x4,0x80,0xfe,0xa0,0x24,0xfe,0x24,0x24,0x34,0x28,0x20,0x20,
-+0x40,0x37,0x12,0x1,0x80,0x61,0x23,0x8,0x10,0x27,0xe0,0x3f,0x20,0x21,0x22,0x2c,0x1c,0xe0,0x48,0x50,0x80,0x10,0xf8,0x40,0x84,0xfc,0x40,0xfe,0xa0,0x10,0xe,0x4,
-+0x20,0x18,0x8,0x0,0x81,0x61,0x22,0xb,0x14,0x20,0xe0,0x20,0x20,0x21,0x22,0x2c,0x80,0x80,0x84,0xfe,0x4,0x4,0x4,0x8,0xc8,0x50,0x20,0x40,0x80,0x0,0x0,0x0,
-+0x0,0x3f,0x20,0x3f,0x24,0x22,0x24,0x28,0x24,0x27,0x28,0x3f,0x40,0x40,0x80,0x0,0x8,0xfc,0x8,0xf8,0x90,0xa0,0x98,0x88,0x80,0xf0,0x84,0xfe,0x80,0x80,0x80,0x80,
-+0x21,0x22,0x27,0x24,0xff,0x24,0x77,0x62,0xbf,0x24,0x27,0x24,0x24,0x2a,0x31,0x20,0x10,0x10,0x90,0x94,0xbe,0xc4,0xa4,0x28,0xe8,0x28,0x90,0x90,0xa8,0xa8,0x46,0x84,
-+0x2,0x2,0x7f,0x4,0x4,0xb,0x10,0x22,0x1,0xff,0x5,0x9,0x38,0xca,0xc,0x8,0x40,0x28,0xfc,0x80,0xf0,0x84,0x7c,0x0,0x4,0xfe,0x8,0x10,0xa0,0x60,0x1c,0x8,
-+0x1,0x0,0x3f,0x22,0x22,0x3f,0x22,0x22,0x23,0x20,0x2f,0x28,0x48,0x48,0x88,0x0,0x0,0x88,0xfc,0x20,0x24,0xfe,0x20,0x20,0xe0,0x88,0xfc,0x88,0x88,0xa8,0x90,0x80,
-+0x0,0x0,0xff,0x0,0x8,0x4,0x2,0x2,0x0,0x3,0xc,0x30,0x10,0x0,0x0,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0x24,0xc4,0x4,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x10,0x10,0x11,0x11,0xfd,0x25,0x25,0x25,0x25,0x45,0x29,0x10,0x29,0x47,0x85,0x0,0x40,0x84,0xfe,0x4,0x4,0xfc,0x4,0xfc,0x4,0x4,0xfc,0x40,0x20,0x2c,0xa,0xf8,
-+0x1,0x7f,0x1,0x3f,0x0,0x1f,0x10,0x1f,0x4,0xff,0x0,0x1f,0x10,0x10,0x1f,0x10,0x8,0xfc,0x0,0xf8,0x0,0xf0,0x10,0xf0,0x44,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x10,
-+0x10,0x11,0x11,0x1d,0x21,0x22,0x7c,0x93,0x10,0x7c,0x10,0x10,0x14,0x19,0x12,0x4,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x50,0x50,0x50,0x90,0x92,0x12,0xe,0x0,
-+0x0,0x42,0x32,0x13,0x82,0x64,0x20,0xf,0x10,0x20,0xe0,0x21,0x21,0x22,0x24,0x28,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0xa0,0xa0,0xa0,0x20,0x22,0x22,0x1e,0x0,
-+0x0,0x7f,0x4,0x4,0x8,0x3f,0x1,0x2,0x4,0x3f,0x1,0x9,0x9,0x11,0x25,0x2,0x38,0xc0,0x0,0x10,0x20,0xc0,0x0,0x20,0x10,0xf8,0x8,0x20,0x10,0x8,0x8,0x0,
-+0x0,0x79,0x4b,0x54,0x50,0x63,0x52,0x4b,0x4a,0x4b,0x68,0x51,0x42,0x44,0x41,0x40,0x40,0x50,0x4c,0x44,0x40,0xf8,0x8,0xf8,0x8,0xf8,0x40,0x50,0x4c,0x44,0x40,0x80,
-+0x0,0x0,0x7e,0x2,0x43,0x24,0x14,0x14,0x8,0x14,0x12,0x22,0x40,0x80,0x1,0x2,0x40,0x50,0x48,0x40,0xfe,0x40,0x44,0x44,0x48,0x48,0x50,0x20,0x60,0x92,0xa,0x6,
-+0x10,0x10,0x21,0x21,0x45,0xf9,0x11,0x21,0x41,0xfd,0x1,0x1,0x1d,0xe1,0x41,0x1,0x0,0x4,0xfe,0x24,0x24,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0x24,0x24,0xfc,0x4,
-+0x0,0x0,0x7b,0x4a,0x4d,0x78,0x48,0x48,0x7f,0x48,0x49,0x49,0x79,0x49,0x1,0x1,0x40,0x20,0xfe,0x22,0xfc,0x20,0xf8,0x20,0xfe,0x20,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x13,0x14,0x7e,0x54,0x54,0x54,0x54,0x7c,0x50,0x14,0x1e,0xf2,0x40,0x0,0x0,0x4,0xfe,0x20,0x20,0x20,0x30,0x28,0x24,0x24,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x0,0x7f,0x40,0x5f,0x51,0x51,0x5f,0x51,0x51,0x5f,0x51,0x41,0x41,0x41,0x7f,0x0,0x8,0xfc,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,0x0,0x0,0x4,0xfe,0x0,
-+0x1f,0x1,0x7f,0x51,0x8d,0x11,0x3e,0x22,0x3e,0x20,0x3e,0x20,0x3e,0x20,0x20,0x23,0xf0,0x0,0xfe,0x12,0x64,0x10,0xf8,0x8,0xf8,0x0,0xf8,0x88,0x50,0x20,0xde,0x4,
-+0x10,0x10,0x23,0xfe,0x25,0x50,0x51,0xfc,0x13,0x10,0x1d,0xf1,0x51,0x11,0x11,0x11,0x40,0x20,0xfe,0x22,0xfc,0x20,0xf8,0x20,0xfe,0x4,0xfe,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x17,0x7c,0x54,0x54,0x57,0x54,0x74,0x57,0x54,0x54,0x57,0x74,0x54,0x4,0x4,0x4,0xbe,0x84,0x84,0x84,0xbc,0x0,0x7c,0xc4,0x44,0x28,0x90,0x28,0x28,0x46,0x84,
-+0x10,0x10,0x10,0x55,0x54,0x55,0x54,0x54,0x57,0x54,0x54,0x7c,0x4,0x0,0x1,0x6,0x20,0x20,0x28,0xfc,0x20,0x24,0xa8,0x20,0xfe,0x20,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x8,0x8,0x8,0x17,0x10,0x32,0x51,0x90,0x1f,0x10,0x10,0x10,0x11,0x12,0x14,0x18,0x40,0x40,0x48,0xfc,0x40,0x48,0x50,0x44,0xfe,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,
-+0x0,0x44,0x2c,0x11,0x28,0x49,0x88,0x8,0x1b,0x28,0x48,0x88,0x8,0x8,0x51,0x26,0x20,0x20,0x28,0xfc,0x20,0x24,0xa8,0x20,0xfe,0x20,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x0,0xff,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x4,0xfe,0x0,0x0,0x0,0x80,0x40,0x30,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x3f,0x20,0x3f,0x22,0x27,0x24,0x27,0x24,0x27,0x24,0x27,0x22,0x47,0x4a,0x81,0x1e,0xfe,0x0,0xfe,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xf0,0x20,0xc0,0x3e,
-+0x7f,0x2,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x1f,0x8,0xf,0x14,0x22,0x41,0x6,0x38,0xfc,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x0,0xf0,0x20,0x40,0x80,0x60,0x1c,
-+0x0,0xf,0x7c,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x78,0x48,0x0,0x0,0x0,0x4,0xfe,0x40,0x40,0x40,0x40,0x50,0x48,0x44,0x44,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x20,0x20,0x27,0x24,0xfc,0x24,0x27,0x2d,0x35,0xe5,0x25,0x25,0x25,0x29,0xa1,0x40,0x10,0x90,0x10,0x20,0x3e,0x42,0x94,0x10,0x10,0x10,0x28,0x28,0x28,0x44,0x44,0x82,
-+0x20,0x20,0x27,0x3c,0x44,0x84,0x7f,0x25,0x25,0xfd,0x25,0x25,0x2d,0x35,0x29,0x0,0x10,0x90,0x10,0x20,0x3e,0x42,0x94,0x10,0x10,0x10,0x28,0x28,0x28,0x44,0x44,0x82,
-+0x1,0x11,0x11,0x1f,0x11,0x21,0x1,0xff,0x4,0x4,0x4,0x8,0x8,0x10,0x20,0x40,0x0,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x80,0x80,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x10,0x10,0x10,0x20,0x24,0x64,0xa4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x27,0x24,0x40,0x40,0x40,0x40,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0xfc,0x4,
-+0x11,0x10,0x1e,0x25,0x28,0x7e,0xaa,0x2b,0x3e,0x2a,0x2a,0x3f,0x0,0xe,0xf0,0x40,0x4,0x88,0x54,0xfe,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x8,0x8,0x11,0x10,0x22,0x7e,0x8,0x13,0x20,0x7e,0x0,0x0,0x1e,0xe0,0x40,0x0,0x8,0x1c,0xe0,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x0,0x0,0x0,0x3f,0x20,0x20,0x3f,0x20,0x2f,0x29,0x29,0x29,0x4f,0x48,0x83,0x0,0x80,0xa0,0x90,0xfc,0x80,0x80,0x84,0x44,0x48,0x48,0x30,0x20,0x60,0x92,0xa,0x6,
-+0x8,0x4b,0x49,0x48,0x48,0x48,0x4b,0x1f,0x10,0x11,0x11,0x11,0x12,0x2,0xc,0x30,0x0,0xf8,0x10,0xa0,0x40,0xa0,0x1e,0xf4,0x10,0x10,0x10,0x10,0x10,0xc0,0x30,0x8,
-+0x9,0x9,0x11,0x23,0x42,0xc,0x13,0x31,0x51,0x97,0x11,0x11,0x11,0x11,0x10,0x10,0x4,0x3e,0x0,0xc0,0x4,0x7e,0x88,0x8,0x8,0xc8,0x8,0x48,0x88,0x8,0x28,0x10,
-+0x8,0x12,0x3f,0x23,0x32,0x2a,0x22,0xfe,0x22,0x32,0x2a,0x22,0x22,0x43,0x8a,0x4,0x40,0x20,0x4,0xfe,0x20,0x20,0x40,0x84,0xf8,0x10,0x20,0x40,0x88,0xfc,0x4,0x0,
-+0x20,0x1b,0x48,0x41,0x41,0x41,0x5f,0x41,0x43,0x45,0x49,0x51,0x41,0x41,0x40,0x40,0x4,0xfe,0x4,0x4,0x4,0x24,0xf4,0x4,0x84,0x44,0x34,0x14,0x4,0x4,0x14,0x8,
-+0x40,0x20,0x2f,0x1,0x82,0x42,0x44,0x7,0x11,0x29,0xe6,0x22,0x25,0x24,0x28,0x30,0x0,0xc,0x70,0x10,0x10,0x50,0x5c,0x50,0x50,0x50,0x54,0xfe,0x0,0x80,0x7e,0x0,
-+0x0,0xf8,0x8,0xf,0x8,0x78,0x40,0x41,0x41,0x78,0x8,0x8,0x9,0xb,0x50,0x20,0x80,0x40,0x4,0xfe,0x40,0x40,0x80,0x8,0xf0,0x20,0x40,0x80,0x8,0xfc,0x4,0x0,
-+0x21,0x20,0x2f,0x20,0xfb,0x48,0x4f,0x48,0x4b,0x88,0x51,0x22,0x52,0x4c,0x88,0x0,0x10,0xa4,0xfe,0xa0,0xf8,0xa8,0xfe,0xa8,0xf8,0xa0,0xb0,0xa8,0xa8,0xa6,0xa0,0xa0,
-+0x0,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x14,0x44,0x34,0x14,0x4,0x4,0xff,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x50,0x44,0x4c,0x50,0x40,0x44,0xfe,0x0,
-+0x0,0x78,0x48,0x51,0x52,0x65,0x50,0x4a,0x4a,0x49,0x69,0x51,0x41,0x40,0x4f,0x40,0x40,0x40,0xa0,0x10,0x2e,0xf4,0x0,0x48,0x48,0x48,0x48,0x50,0x50,0x24,0xfe,0x0,
-+0x0,0x9,0xfd,0x11,0x11,0x11,0x11,0x7d,0x11,0x11,0x10,0x1c,0xf0,0x41,0x2,0xc,0x8,0xfc,0x8,0x28,0x28,0x28,0x28,0x48,0x48,0x48,0x40,0xa0,0xa0,0x22,0x22,0x1e,
-+0x8,0x8,0x9,0xff,0x8,0x9,0x7f,0x55,0x55,0x7f,0x49,0x7f,0x49,0x49,0x43,0x41,0x10,0x10,0x18,0x94,0x10,0x14,0xfe,0x10,0x10,0x10,0x28,0x28,0x28,0x44,0x44,0x82,
-+0x0,0xf,0x8,0x8,0xf,0x8,0x8,0xf,0x8,0x8,0xff,0x4,0x8,0x10,0x3f,0x0,0x20,0xf0,0x20,0x20,0xe0,0x20,0x20,0xe0,0x20,0x24,0xfe,0x0,0x20,0x10,0xf8,0x8,
-+0x8,0x7c,0x4b,0x4a,0x4b,0x7a,0x4b,0x48,0x48,0x7f,0x49,0x49,0x4a,0x4c,0x49,0x98,0x40,0x88,0xfc,0x8,0xf8,0x8,0xfc,0x48,0x50,0xe0,0x60,0x50,0x4e,0x44,0x40,0x80,
-+0x20,0x20,0x20,0x3d,0x26,0x48,0x41,0xa2,0x22,0x22,0x23,0x26,0x2a,0x32,0x23,0x2,0x80,0x80,0xf8,0x8,0x10,0x24,0x9e,0x4,0x4,0x4,0x9c,0x4,0x4,0x4,0xfc,0x4,
-+0x4,0x2,0x7f,0x1,0x3f,0x1,0xff,0x0,0x44,0x29,0x12,0x20,0x60,0x20,0x23,0x2c,0x40,0x88,0xfc,0x0,0xf8,0x0,0xfe,0x80,0xfc,0x4,0x48,0x40,0xa0,0x90,0xe,0x4,
-+0x2,0x1,0x7f,0x49,0x89,0xf,0x11,0x21,0xff,0x2,0x2,0x2,0x4,0x4,0x18,0x60,0x0,0x0,0xfe,0x2,0x24,0xf0,0x0,0x4,0xfe,0x80,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x0,0x78,0x48,0x51,0x52,0x64,0x51,0x4a,0x4a,0x4a,0x6b,0x52,0x42,0x42,0x43,0x42,0x80,0x80,0xf8,0x8,0x10,0x24,0x9e,0x4,0x4,0x4,0x9c,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x7d,0x45,0x49,0x49,0x51,0x49,0x49,0x45,0x45,0x45,0x69,0x51,0x41,0x41,0x41,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x4,0x88,0x50,0x20,0x10,0x4e,0x84,0x0,
-+0x8,0x8,0x10,0x10,0x22,0x7f,0x8,0x10,0x23,0x7c,0x0,0x0,0x1c,0xe0,0x43,0x0,0x40,0x50,0x48,0x40,0x7c,0xc0,0x44,0x7e,0xc0,0x48,0x50,0x20,0x60,0x92,0xa,0x6,
-+0x10,0x11,0x11,0x11,0xfd,0x11,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x4,0xfe,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x3f,0x22,0x22,0x22,0x3f,0x22,0x26,0x27,0x2a,0x2a,0x32,0x42,0x42,0x82,0x2,0x4,0xfe,0x0,0x4,0x7e,0xc4,0x44,0x7c,0x44,0xc4,0x7c,0x44,0x44,0x44,0x7c,0x44,
-+0x20,0x27,0x38,0x43,0x82,0x7b,0x21,0x27,0xf9,0x23,0x21,0x2f,0x29,0x33,0x2d,0x1,0x40,0xfc,0x0,0xb8,0xa8,0xb8,0x10,0xfc,0x10,0xf8,0x10,0xfe,0x48,0x30,0x8e,0x4,
-+0x0,0x3f,0x1,0x1,0xff,0x5,0x9,0x31,0xcf,0x8,0x8,0xf,0x8,0x8,0xf,0x8,0x30,0xc0,0x0,0x4,0xfe,0x40,0x30,0xe,0xe4,0x20,0x20,0xe0,0x20,0x20,0xe0,0x20,
-+0x12,0x1f,0x28,0x45,0x8,0x8,0xfe,0x8,0x18,0x1c,0x2a,0x28,0x48,0x88,0x8,0x8,0x44,0x7e,0xa0,0x10,0x4,0xfe,0x84,0x84,0xfc,0x84,0x84,0xfc,0x84,0x84,0xfc,0x84,
-+0x1,0xff,0x0,0x3e,0x22,0x3e,0x4,0x7f,0x4,0x3f,0x4,0xff,0x9,0x18,0x6c,0x8,0x4,0xfe,0x0,0xf8,0x88,0xf8,0x40,0xfc,0x40,0xf8,0x40,0xfe,0x10,0xa0,0x70,0xe,
-+0x2,0x42,0x32,0x12,0x8f,0x62,0x26,0x7,0x1a,0x2a,0xf2,0x22,0x22,0x22,0x22,0x22,0x0,0x4,0x7e,0x44,0xc4,0x44,0x7c,0x44,0xc4,0x44,0x7c,0x44,0x44,0x44,0x7c,0x44,
-+0x2,0x2,0x4,0x8,0x10,0x3f,0x1,0x2,0x4,0x3f,0x0,0x0,0x0,0x3,0xc,0x70,0x0,0x0,0x20,0x20,0x40,0x80,0x0,0x8,0x8,0xf0,0x20,0x40,0x80,0x0,0x0,0x0,
-+0x82,0x44,0x29,0xfe,0x10,0x11,0x7c,0x10,0x10,0xfe,0x11,0x12,0x10,0x20,0x21,0x40,0x0,0x4,0xde,0x44,0x44,0x54,0xcc,0x44,0x44,0xcc,0x54,0x64,0x44,0x44,0x54,0x88,
-+0x22,0x11,0x10,0xff,0x8,0x10,0x3b,0x54,0x90,0x10,0x1f,0x10,0x10,0x10,0x10,0x10,0x8,0x10,0xa0,0xfc,0x40,0x50,0xf8,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x2,0x41,0x30,0x17,0x0,0x0,0xf3,0x10,0x10,0x10,0x1f,0x10,0x14,0x18,0x10,0x0,0x8,0x10,0xa0,0xfc,0x40,0x50,0xf8,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x10,0x11,0x11,0xff,0x11,0x31,0x39,0x55,0x91,0x11,0x0,0x12,0x51,0x50,0x90,0xf,0x8,0xfc,0x8,0x8,0xf8,0x8,0xf8,0x8,0x8,0xf8,0x0,0x0,0x84,0x92,0x12,0xf0,
-+0x0,0x8,0x7c,0x4b,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x7a,0x4a,0x2,0x2,0x2,0x20,0x40,0x84,0xfe,0x4,0x4,0xf4,0x94,0x94,0x94,0x94,0xf4,0x4,0x4,0x14,0x8,
-+0x2,0x1,0x7f,0x0,0x1f,0x10,0x1f,0x0,0x3f,0x0,0x1,0xff,0x1,0x1,0x5,0x2,0x0,0x8,0xfc,0x0,0xf0,0x10,0xf0,0x0,0xf8,0x40,0x84,0xfe,0x0,0x0,0x0,0x0,
-+0x0,0xb,0xfc,0x10,0x11,0x11,0x11,0x11,0x11,0x11,0x1d,0xf1,0x41,0x0,0x0,0x3,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x58,0x84,0x2,
-+0x8,0x8,0x7f,0x8,0x8,0xff,0x4,0x8,0x1f,0x28,0xc8,0xf,0x8,0x8,0x8,0x7,0x20,0x28,0xfc,0x20,0x24,0xfe,0x40,0x20,0xf0,0x2e,0x24,0xe0,0x20,0x8,0x8,0xf8,
-+0x11,0x11,0x12,0x17,0xfc,0x17,0x30,0x39,0x56,0x51,0x96,0x10,0x11,0x16,0x10,0x10,0x0,0xf0,0x24,0xfe,0x44,0xfc,0x80,0x44,0x68,0xb0,0x30,0x68,0xa6,0x20,0xa0,0x40,
-+0x9,0x9,0xa,0x17,0x1c,0x37,0x50,0x91,0x16,0x10,0x17,0x10,0x11,0x16,0x10,0x10,0x0,0xf0,0x24,0xfe,0x44,0xfc,0x80,0x44,0x68,0xb0,0x30,0x68,0xa6,0x20,0xa0,0x40,
-+0x2,0x4,0x8,0x7f,0x40,0x40,0x4f,0x48,0x48,0x48,0x48,0x4f,0x48,0x40,0x40,0x40,0x0,0x0,0x4,0xfe,0x4,0x24,0xf4,0x24,0x24,0x24,0x24,0xe4,0x24,0x4,0x14,0x8,
-+0x8,0xf,0x10,0x3f,0x61,0xa1,0x3f,0x6,0x19,0x62,0xc,0x31,0x6,0x18,0x62,0x1,0x0,0xe0,0x48,0xfc,0x8,0x8,0xf8,0x10,0x20,0xc0,0xc0,0xa0,0x90,0x8e,0x84,0x0,
-+0x8,0xff,0x9,0x3f,0x1,0xff,0x1,0x3f,0x1,0x21,0x25,0x25,0x25,0x29,0x41,0x1,0x24,0xfe,0x20,0xf8,0x8,0xfe,0x8,0xf8,0x0,0x8,0x48,0x28,0x28,0x28,0x8,0x8,
-+0x0,0x5,0xfe,0x10,0x11,0x21,0x25,0x7f,0xa5,0x25,0x25,0x25,0x25,0x3d,0x25,0x1,0x20,0x24,0xa8,0x24,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x4,0x4,0x14,0x8,
-+0x1f,0x1,0x7f,0x51,0x89,0x11,0x5,0x3,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x10,0xf0,0x0,0xfe,0x12,0x24,0x10,0x40,0x90,0xf8,0x10,0xf0,0x10,0xf0,0x10,0x50,0x20,
-+0x8,0x49,0x2a,0x9,0x7f,0x41,0x41,0x7f,0x41,0x41,0x7f,0x41,0x41,0x41,0x45,0x42,0x4,0x4,0x4,0x24,0xa4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x4,0x4,0x14,0x8,
-+0x0,0x8,0x7f,0x48,0x48,0x4f,0x48,0x49,0x4a,0x4c,0x4b,0x48,0x78,0x48,0x0,0x0,0x40,0x44,0xf8,0x50,0x64,0xfe,0x80,0xf8,0x10,0x24,0xfe,0x20,0x20,0x20,0xa0,0x40,
-+0x3e,0x22,0x3e,0x0,0xff,0x2,0x1f,0x10,0x11,0x12,0x4,0x78,0x0,0x3e,0x22,0x3e,0xf8,0x88,0xf8,0x4,0xfe,0x0,0xf0,0x10,0x10,0x90,0x40,0x3c,0x0,0xf8,0x88,0xf8,
-+0x10,0x11,0x10,0x3c,0x21,0x41,0xbd,0x11,0x11,0xfd,0x11,0x11,0x15,0x19,0x11,0x1,0x20,0x24,0xa8,0x24,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x4,0x4,0x14,0x8,
-+0x0,0x42,0x31,0x10,0x83,0x62,0x22,0xb,0x12,0x22,0xe3,0x22,0x22,0x22,0x22,0x22,0x40,0x48,0x50,0x48,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0x8,0x28,0x10,
-+0x2,0x1,0x7f,0x41,0x89,0x5,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x10,0x10,0x0,0x0,0xfe,0x2,0x24,0x50,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,0x50,0x20,
-+0x2,0x41,0x30,0x11,0x82,0x6f,0x20,0x9,0x13,0x25,0xe9,0x21,0x21,0x21,0x21,0x21,0x8,0xb0,0x40,0xb0,0x48,0xfe,0x80,0xf8,0x8,0xf8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x0,0x8,0x7c,0x4f,0x48,0x48,0x78,0x4b,0x48,0x4b,0x48,0x78,0x49,0x1,0x2,0xc,0x80,0x88,0xfc,0x80,0x50,0x22,0xd2,0xe,0x0,0xfc,0xa0,0xa0,0x22,0x22,0x1e,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x5,0x5,0x9,0x9,0x11,0x21,0x41,0x1,0x1,0x5,0x2,0x0,0x0,0x0,0x0,0x0,0x40,0x20,0x10,0x8,0x4,0x4,0x0,0x0,0x0,0x0,0x0,
-+0x2,0x2,0x3f,0x2,0x2,0xff,0x2,0x4,0x3f,0x10,0x21,0x5f,0x81,0x1,0x5,0x2,0x0,0x10,0xe0,0x40,0x84,0xfe,0x0,0x0,0xe0,0x80,0x8,0xfc,0x0,0x0,0x0,0x0,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x31,0x3a,0x54,0x50,0x90,0x10,0x10,0x10,0x13,0x1c,0x40,0x20,0x4,0xfe,0x0,0x88,0x6,0x8a,0x88,0x50,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x1,0x11,0x9,0x5,0x1,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x10,0x10,0x10,0x0,0x10,0x20,0x40,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,0x10,0x50,0x20,
-+0x0,0x0,0x7b,0x48,0x4f,0x48,0x4b,0x48,0x4a,0x4a,0x4a,0x7b,0x42,0x4,0x8,0x0,0x40,0x48,0xfc,0x48,0xfe,0x48,0xf8,0x40,0x48,0xe8,0xd8,0x58,0x48,0x48,0x48,0x40,
-+0x10,0x12,0x1f,0x28,0x45,0x0,0x3f,0x1,0x1,0xff,0x2,0x2,0x4,0x8,0x10,0x60,0x40,0x48,0x7c,0xa0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x0,0x80,0x40,0x30,0xe,0x4,
-+0x10,0x8,0x2,0xff,0x24,0x22,0x41,0xa4,0x14,0x8,0x14,0x24,0x22,0x42,0x80,0x1,0x20,0x20,0x20,0x24,0x7e,0x84,0x44,0x44,0x48,0x28,0x28,0x10,0x28,0x28,0x46,0x84,
-+0x21,0x21,0x27,0x21,0xff,0x21,0x77,0x69,0xa1,0x20,0x2f,0x20,0x20,0x20,0x23,0x2c,0x0,0x4,0xfe,0x14,0xd4,0x14,0xd4,0x24,0x4c,0x44,0xfe,0x40,0xa0,0x90,0xe,0x4,
-+0x4,0x4,0x24,0x27,0x24,0x24,0x24,0x27,0xfc,0x0,0x0,0x1f,0x0,0x0,0x7f,0x0,0x40,0x40,0x40,0x4c,0x70,0x40,0x42,0x42,0x3e,0x0,0x20,0xf0,0x0,0x8,0xfc,0x0,
-+0x1,0x3f,0x21,0x3f,0x21,0x3f,0x10,0x10,0x3f,0x48,0xc8,0x54,0x40,0x7c,0x5,0x2,0x20,0xa0,0x20,0x3e,0x42,0x94,0x10,0x90,0xd0,0x90,0x90,0xa8,0xa8,0xa4,0x44,0x82,
-+0x10,0x11,0x11,0x15,0x7f,0x55,0x54,0x54,0x55,0x7e,0x51,0x15,0x1d,0xf5,0x40,0x0,0x4,0xfe,0x4,0xfc,0x4,0xfc,0x80,0x80,0xfe,0x22,0x22,0x52,0x2,0xfa,0xa,0x4,
-+0x28,0x28,0xfe,0x29,0x38,0x10,0x7f,0x54,0x54,0x7c,0x11,0xfe,0x10,0x10,0x13,0x10,0x20,0x20,0x28,0xfc,0x20,0x24,0xfe,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x20,0x20,0x20,0x20,0xfb,0x20,0x20,0x24,0x24,0x24,0x29,0x21,0x21,0x22,0x24,0x20,0x80,0x80,0x80,0x88,0xfc,0x88,0x88,0x8c,0x8a,0x8a,0x8,0x8,0x8,0x8,0x28,0x10,
-+0x10,0x10,0x10,0x17,0xf8,0x12,0x11,0x18,0x37,0xd0,0x10,0x10,0x11,0x11,0x52,0x24,0x40,0x40,0x48,0xfc,0x40,0x48,0x50,0x44,0xfe,0x40,0xa0,0xa0,0x10,0x10,0xe,0x4,
-+0x12,0x12,0x13,0x16,0xfb,0x12,0x13,0x1a,0x33,0xd2,0x17,0x11,0x11,0x11,0x52,0x24,0x80,0x48,0xfc,0x40,0xf8,0x40,0xf8,0x40,0xfc,0x0,0xf8,0x10,0x3c,0x4,0x14,0x8,
-+0x2,0x7f,0x4,0x24,0x24,0x45,0x7f,0xc,0xc,0x14,0x24,0x44,0x84,0x4,0x14,0x8,0x0,0x7c,0x44,0x44,0x48,0x48,0xd0,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x8,0x8,0x14,0x22,0x41,0xbe,0x8,0x8,0x7f,0x8,0x2a,0x29,0x49,0x8,0x28,0x10,0x8,0x8,0x8,0x48,0x28,0x8,0x48,0x28,0xe,0xf8,0x8,0x8,0x8,0x8,0x8,0x8,
-+0x8,0x7c,0x48,0x48,0x4b,0x78,0x48,0x4a,0x4a,0x7a,0x4d,0x49,0x49,0x4a,0x4c,0x98,0x80,0x80,0x80,0x88,0xfc,0x88,0x88,0x8c,0x8a,0x8a,0x8,0x8,0x8,0x8,0x28,0x10,
-+0x4,0x24,0x17,0x14,0x4,0x5,0xf6,0x10,0x13,0x12,0x12,0x13,0x16,0x1a,0x13,0x2,0x20,0x24,0xa8,0x30,0x22,0xa2,0x5e,0x88,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x0,0x7f,0x40,0x88,0x8,0xf,0x8,0x8,0xf,0x0,0x0,0x7f,0x0,0x0,0x0,0x0,0x0,0xfe,0x2,0x4,0x20,0xf0,0x0,0x8,0xfc,0x8,0x48,0xe8,0x8,0x8,0x50,0x20,
-+0x10,0x10,0x10,0x17,0xfc,0x12,0x32,0x3a,0x57,0x52,0x92,0x12,0x14,0x18,0x10,0x13,0x20,0x28,0x24,0xfe,0x20,0xa0,0xa0,0xa4,0xe4,0xa8,0xa8,0x90,0xb0,0x52,0x8a,0x6,
-+0x20,0x22,0x3f,0x48,0x88,0xa,0xff,0x8,0x28,0x2e,0x28,0x28,0x2f,0xf8,0x40,0x0,0x0,0x4,0x7e,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x64,0x54,0x48,0x40,0x40,
-+0x20,0x3e,0x44,0xbe,0x2a,0x3e,0x2a,0x3f,0x2a,0x41,0x9f,0x11,0x1f,0x1,0x7f,0x20,0x0,0xfc,0x24,0x4c,0xd0,0x7c,0x90,0xfe,0x10,0x10,0xf8,0x10,0xf0,0x8,0xfc,0x4,
-+0x22,0x22,0x27,0x29,0xbf,0xaa,0xaa,0x2f,0x2a,0x2a,0x2f,0x2a,0x2a,0x2a,0x31,0x20,0x4,0x7e,0xa4,0x24,0xa4,0xc8,0xa8,0xbe,0xc8,0x88,0xfe,0x88,0x88,0x88,0x88,0x8,
-+0x2,0x42,0x32,0x12,0x82,0x62,0x2f,0xa,0x12,0x22,0xe2,0x22,0x22,0x22,0x23,0x20,0x48,0x48,0x48,0x48,0x48,0x48,0xfe,0x48,0x48,0x48,0x48,0x78,0x40,0x8,0xfc,0x0,
-+0x40,0x27,0x24,0x9,0x81,0x61,0x21,0x9,0x11,0x20,0xe0,0x2f,0x20,0x20,0x20,0x20,0x0,0xfe,0x2,0x4,0x0,0xfc,0x0,0x4,0xfe,0x4,0x24,0xf4,0x4,0x4,0x14,0x8,
-+0x2,0x44,0x2f,0x28,0xf,0x8,0xef,0x28,0x28,0x3f,0x21,0x2a,0x34,0x28,0x12,0x1,0x8,0x88,0xc8,0x88,0x88,0xfe,0x88,0x88,0xc8,0xa8,0xa8,0x88,0x88,0x88,0xa8,0x10,
-+0x3f,0x20,0x3f,0x20,0x24,0x22,0x2f,0x28,0x28,0x2f,0x28,0x28,0x4f,0x48,0x88,0x8,0xf8,0x8,0xf8,0x80,0x90,0xa8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x28,0x10,
-+0x4,0xff,0x14,0x8,0x7f,0x22,0x14,0xff,0x8,0xa,0x7f,0x2a,0x49,0x88,0x29,0x10,0x40,0xfe,0x40,0x6,0x78,0x40,0x44,0xfe,0x48,0x48,0x48,0x48,0x88,0x88,0x8,0x8,
-+0x8,0x8,0xff,0x8,0x8,0x0,0x2,0x1,0x50,0x50,0x50,0x90,0x10,0x10,0xf,0x0,0x20,0x24,0xfe,0x20,0x20,0x0,0x0,0x0,0x84,0x82,0x2,0x2,0x8,0x8,0xf8,0x0,
-+0x10,0x10,0x1d,0x20,0x20,0x7c,0x93,0x10,0x7c,0x10,0x11,0x10,0x14,0x18,0x10,0x0,0x40,0x20,0xfc,0x0,0x88,0x50,0xfe,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x20,
-+0x2,0x7,0x38,0x20,0x20,0x20,0x3f,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x85,0x2,0x40,0x40,0x40,0x40,0x7e,0x82,0x24,0x20,0x20,0x20,0x50,0x50,0x88,0x88,0x6,0x4,
-+0x2,0x1,0x3f,0x8,0x4,0x4,0xff,0x1,0x1,0x1,0x7f,0x1,0x1,0x1,0x1,0x1,0x0,0x10,0xf8,0x20,0x20,0x44,0xfe,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,
-+0x10,0xa,0x7f,0x0,0x22,0x14,0xff,0xa,0x7f,0x8,0xa,0x29,0x48,0x89,0x28,0x10,0x8,0x1c,0x60,0x40,0x40,0x44,0xfe,0x48,0x48,0x48,0x48,0x88,0x88,0x8,0x8,0x8,
-+0x10,0x10,0x11,0x11,0x59,0x55,0x51,0x91,0x11,0x11,0x11,0x12,0x12,0x14,0x18,0x10,0x8,0x1c,0xe0,0x0,0x0,0x4,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x2,0x1,0x0,0x0,0x8,0x8,0x28,0x28,0x28,0x48,0x88,0x8,0x8,0x8,0x7,0x0,0x0,0x0,0x80,0xc0,0x80,0x0,0x8,0x4,0x2,0x2,0x2,0x0,0x10,0x10,0xf0,0x0,
-+0x8,0x8,0xf,0x10,0x10,0x37,0x50,0x90,0x17,0x10,0x13,0x12,0x12,0x12,0x13,0x12,0x80,0x44,0xfe,0x0,0x8,0xfc,0x0,0x8,0xfc,0x0,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x4,0x8,0x10,0x7f,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x57,0xf8,0x40,0x0,0x0,0x10,0x92,0x54,0x54,0x10,0xfe,0x10,0x10,0x14,0xfe,0x10,0x90,0x10,0x10,0x10,0x10,
-+0x0,0x3f,0x20,0x3f,0x20,0x3f,0x1,0x21,0x3f,0x21,0x41,0xbf,0x1,0x1,0xff,0x0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0x8,0xfc,0x0,0x10,0xf8,0x0,0x4,0xfe,0x0,
-+0x0,0x7b,0x4a,0x4b,0x4a,0x7b,0x48,0x4a,0x4b,0x7c,0x48,0x4b,0x48,0x48,0x8f,0x18,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x40,0x48,0xfc,0x40,0x50,0xf8,0x40,0x44,0xfe,0x0,
-+0x2,0x45,0x29,0x11,0x29,0x49,0x88,0x9,0x19,0x2a,0x4c,0x89,0x8,0x8,0x57,0x20,0x4,0xfe,0x4,0xfc,0x4,0xfc,0x20,0x24,0xfe,0x20,0x28,0xfc,0x20,0x24,0xfe,0x0,
-+0x10,0x13,0x12,0x13,0x5a,0x57,0x50,0x92,0x13,0x14,0x18,0x13,0x10,0x10,0x1f,0x10,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x40,0x48,0xfc,0x40,0x50,0xf8,0x40,0x44,0xfe,0x0,
-+0x2,0x2,0x21,0x11,0x19,0x9,0x0,0x0,0xff,0x0,0x0,0x4,0xc,0x10,0x20,0x40,0x0,0x8,0x8,0x10,0x10,0x20,0x20,0x44,0xfe,0x0,0x0,0x40,0x20,0x18,0xc,0x4,
-+0x0,0x7f,0x11,0x11,0x11,0x11,0x11,0xff,0x11,0x11,0x11,0x11,0x21,0x21,0x41,0x1,0x84,0xc4,0x4,0x24,0x24,0x24,0x24,0xe4,0x24,0x24,0x24,0x24,0x4,0x4,0x14,0x8,
-+0x1,0x7f,0x12,0x12,0x12,0xff,0x12,0x12,0x12,0x23,0x41,0x7f,0x1,0x1,0xff,0x0,0x4,0x84,0x24,0x24,0x24,0xa4,0x24,0x24,0x4,0x14,0x8,0xfc,0x0,0x4,0xfe,0x0,
-+0x0,0x7f,0x11,0x11,0x11,0x11,0x11,0xff,0x11,0x11,0x11,0x11,0x21,0x21,0x41,0x1,0x80,0xc4,0xc,0x10,0x20,0x44,0xc,0xd0,0x20,0x42,0x6,0x8,0x10,0x20,0x40,0x80,
-+0x0,0x7f,0x12,0x12,0x12,0x12,0x12,0xff,0x12,0x12,0x12,0x12,0x22,0x22,0x42,0x2,0x0,0x7c,0x44,0x44,0x48,0x48,0x50,0xc8,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x8,0xb,0x10,0x20,0x40,0x8,0x17,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x8,0xfc,0x0,0x0,0x0,0x4,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x4,0xfe,0x28,0x28,0xfe,0xaa,0xaa,0xae,0xc2,0x83,0x82,0xfe,0x82,0x82,0xff,0x82,0x4,0xfe,0x84,0xfc,0x84,0xfc,0x20,0xa0,0xfc,0x20,0x20,0xfc,0x20,0x24,0xfe,0x0,
-+0x1,0x1,0x3f,0x1,0x1,0xff,0x8,0x4,0x3f,0x1,0x1,0x7f,0x1,0x1,0x1,0x1,0x0,0x10,0xf8,0x0,0x4,0xfe,0x20,0x50,0xf8,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0xff,0x3,0x5,0x9,0x31,0xc1,0x1f,0x10,0x10,0x10,0x10,0x1f,0x10,0x0,0x0,0x4,0xfe,0x80,0x40,0x30,0xe,0x4,0xf0,0x10,0x10,0x10,0x10,0xf0,0x10,
-+0x10,0x10,0x12,0x12,0x5b,0x54,0x54,0x98,0x10,0x13,0x10,0x10,0x10,0x10,0x1f,0x10,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0x50,0xf8,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x10,0x10,0x11,0x11,0xfd,0x25,0x26,0x24,0x24,0x45,0x28,0x10,0x28,0x44,0x87,0x0,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x0,0x1f,0x10,0x10,0x10,0x10,0x1f,0x14,0x4,0x4,0x4,0x8,0x8,0x10,0x20,0x40,0x10,0xf8,0x10,0x10,0x10,0x10,0xf0,0x50,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x0,0x0,0x20,0x50,0x48,0x44,0x42,0x41,0x42,0x44,0x48,0x50,0x40,0x7f,0x40,0x0,0x0,0x10,0x10,0x24,0x24,0x44,0x84,0x4,0x84,0x44,0x34,0x14,0x4,0xfc,0x4,0x0,
-+0x8,0x7c,0x49,0x49,0x4a,0x7c,0x49,0x4a,0x4a,0x7a,0x4b,0x4a,0x4b,0x4a,0x88,0x18,0x80,0x80,0x0,0xfe,0x2,0x2,0x12,0xaa,0x4a,0xaa,0x1a,0xa,0xfa,0x2,0x14,0x8,
-+0x8,0x8,0x10,0x1f,0x20,0x40,0x90,0x28,0x25,0x22,0x25,0x28,0x20,0x3f,0x20,0x0,0x0,0x0,0x4,0xfe,0x4,0x4,0x44,0xa4,0x24,0x24,0x24,0xa4,0x24,0xe4,0x14,0x8,
-+0x0,0x42,0x31,0x14,0x84,0x64,0x24,0xc,0x14,0x25,0xe5,0x26,0x24,0x27,0x24,0x20,0x0,0x8,0x10,0x94,0xa4,0x44,0x44,0xa4,0xa4,0x14,0xc,0xc,0x4,0xfc,0x4,0x0,
-+0x10,0x10,0x10,0xfd,0x11,0x13,0x25,0x21,0x51,0x51,0x91,0x25,0x45,0x7d,0x1,0x1,0x40,0xa0,0x88,0xfc,0x20,0x28,0xfc,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,0x0,
-+0x10,0x10,0x22,0x7f,0x0,0x3e,0x22,0x3e,0x22,0x3e,0x22,0x26,0x0,0x48,0x44,0x80,0x80,0x98,0xe0,0x84,0x84,0x7c,0x80,0x98,0xe0,0x84,0x84,0x7c,0x0,0x88,0x46,0x2,
-+0x8,0x8,0x8,0x10,0x17,0x30,0x50,0x90,0x11,0x11,0x12,0x14,0x18,0x10,0x10,0x10,0x40,0x40,0x40,0x44,0xfe,0x40,0xe0,0xe0,0x50,0x50,0x48,0x46,0x44,0x40,0x40,0x40,
-+0x11,0x11,0x11,0x21,0x2a,0x6c,0xa9,0x2e,0x28,0x2b,0x28,0x28,0x23,0x20,0x21,0x26,0x0,0x0,0xf8,0x10,0xa0,0x40,0xb0,0x2e,0xc0,0x10,0x60,0x88,0x10,0x60,0x80,0x0,
-+0x8,0x4,0x2,0x7f,0x1,0x3f,0x2,0xff,0x4,0xf,0x11,0x2f,0x42,0x84,0x3f,0x0,0x20,0x40,0x88,0xfc,0x0,0xf8,0x0,0xfe,0x10,0xf8,0x10,0xf0,0x10,0x14,0xfe,0x0,
-+0x10,0x10,0x17,0x10,0xfc,0x10,0x31,0x39,0x54,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x0,0x4,0xfe,0x80,0x80,0x80,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0x88,0x50,0x20,
-+0x0,0x8,0x7f,0x4a,0x4b,0x4a,0x4b,0x4a,0x4b,0x48,0x48,0x7f,0x48,0x1,0x2,0xc,0x40,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x50,0x48,0xfe,0xa0,0x10,0xe,0x4,
-+0x10,0x13,0x1c,0x20,0x27,0x7c,0x91,0x12,0x7d,0x10,0x10,0x10,0x15,0x19,0x12,0x4,0x18,0xe0,0x40,0x48,0xfc,0xe0,0x50,0x4e,0xf8,0x88,0x90,0x9c,0x4,0x4,0x28,0x10,
-+0x0,0x3f,0x1,0x1,0x7f,0x5,0x9,0x31,0xcf,0x4,0x4,0x4,0x8,0x8,0x10,0x20,0x78,0x80,0x0,0x8,0xfc,0x40,0x30,0xe,0xe4,0x20,0x40,0x70,0x10,0x10,0xa0,0x40,
-+0x20,0x10,0x10,0x0,0xfd,0x9,0x11,0x35,0x59,0x95,0x11,0x11,0x11,0x11,0x11,0x11,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0x24,0xfc,0x4,
-+0x10,0x13,0x20,0x20,0x4f,0xf8,0x11,0x22,0x45,0xf8,0x0,0x0,0x19,0xe1,0x42,0x4,0x18,0xe0,0x40,0x48,0xfc,0xe0,0x50,0x4e,0xf8,0x88,0x90,0x9c,0x4,0x4,0x28,0x10,
-+0x20,0x20,0x20,0x27,0xfc,0x24,0x27,0x24,0x24,0x24,0x3e,0xe5,0x48,0x8,0x17,0x20,0x88,0xfc,0x80,0xfe,0x82,0xf0,0x84,0xfc,0x0,0xa0,0xa8,0xb0,0xa0,0xa4,0xfe,0x0,
-+0x0,0x0,0x0,0x3f,0x20,0x20,0x20,0x24,0x3e,0x20,0x20,0x20,0x40,0x40,0x83,0x0,0x80,0xa0,0x90,0xfc,0x80,0x80,0x84,0x44,0x48,0x48,0x30,0x20,0x60,0x92,0xa,0x6,
-+0x1f,0x1,0x7f,0x51,0x8d,0x11,0x1,0xff,0x2,0x4,0x3f,0x24,0x24,0x24,0x24,0x20,0xf0,0x0,0xfe,0x12,0x64,0x10,0x4,0xfe,0x0,0x8,0xfc,0x88,0x88,0x88,0xa8,0x10,
-+0x2,0x3,0x2,0x3f,0x22,0x23,0x3e,0x23,0x20,0x22,0x32,0x2a,0x4a,0x42,0xbf,0x0,0x10,0xf8,0x0,0xfe,0x2,0xe4,0x8,0xf8,0x0,0x40,0x48,0x58,0x60,0x40,0xfe,0x0,
-+0x0,0x8,0x7c,0x4b,0x4a,0x4a,0x4b,0x4a,0x4a,0x4a,0x4b,0x7a,0x4c,0x4,0xb,0x0,0x48,0x7c,0x40,0xfe,0x42,0x70,0xc4,0x7c,0x0,0x50,0x54,0xd8,0x50,0x54,0xfe,0x0,
-+0x4,0xb,0x10,0x20,0x41,0x5,0x9,0x11,0x21,0x41,0x5,0x9,0x11,0x20,0x40,0x3,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x58,0x86,0x2,
-+0x8,0x8,0x10,0x21,0x42,0xc,0x13,0x30,0x50,0x97,0x10,0x11,0x12,0x14,0x11,0x10,0x40,0x40,0xa0,0x10,0xe,0x4,0xf8,0x40,0x48,0xfc,0x40,0x50,0x4c,0x44,0x40,0x80,
-+0x2,0x42,0x33,0x12,0x4,0x0,0xf0,0x1f,0x10,0x10,0x10,0x12,0x14,0x18,0x10,0x0,0x0,0x8,0xfc,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x8,0x7f,0x9,0x7f,0x2,0x4,0x1f,0x1,0x2,0x3f,0x0,0x1f,0x11,0x1f,0x11,0x1f,0x20,0xfc,0x20,0xfc,0x0,0x10,0xe0,0x0,0x8,0xf8,0x0,0xf0,0x10,0xf0,0x10,0xf0,
-+0x4,0xfe,0x28,0x28,0xfe,0xaa,0xaa,0xae,0xa2,0xc2,0x82,0xfe,0x82,0x82,0xfe,0x82,0x0,0x0,0x44,0x44,0xaa,0xaa,0xaa,0x92,0x92,0xaa,0xaa,0xa6,0xc6,0x82,0xfe,0x82,
-+0x8,0x8,0x14,0x12,0x21,0x5e,0x88,0x8,0x7e,0x8,0x2c,0x2a,0x4a,0x8,0x29,0x12,0x0,0x0,0x8,0xfc,0x8,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x10,0x10,0x10,0x10,0xfe,0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x22,0x22,0x41,0x80,0x0,0x8,0xfc,0x88,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x88,0xfa,0x2,0xfe,0x0,
-+0x1,0x0,0x3f,0x20,0x2f,0x20,0x21,0x20,0x2f,0x20,0x20,0x20,0x40,0x40,0x82,0x1,0x0,0x88,0xfc,0x0,0xf8,0x20,0x40,0x80,0xfc,0x88,0x90,0x80,0x80,0x80,0x80,0x0,
-+0x2,0x1,0xff,0x2,0x4,0x1f,0x1,0x2,0x3f,0x0,0x1f,0x11,0x1f,0x11,0x1f,0x10,0x0,0x4,0xfe,0x0,0x10,0xe0,0x0,0x8,0xf8,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x10,
-+0x10,0x10,0x11,0x13,0x5a,0x56,0x52,0x92,0x12,0x12,0x12,0x12,0x12,0x1f,0x10,0x10,0x80,0x80,0x8,0xfc,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xfe,0x0,0x0,
-+0x10,0xfe,0x22,0x64,0x18,0x14,0x62,0x4,0x1f,0x3,0xc,0x3f,0x1,0x11,0x65,0x2,0x4,0xfe,0x84,0x84,0x84,0xfc,0x84,0x20,0xc0,0x0,0x10,0xf8,0x0,0x30,0x8,0x0,
-+0x10,0x13,0x10,0x11,0xfd,0x25,0x26,0x24,0x25,0x45,0x29,0x11,0x29,0x45,0x85,0x1,0x0,0xfe,0x42,0x70,0x40,0x40,0xfe,0x4,0xfe,0x4,0xfc,0x4,0xfc,0x4,0x4,0xc,
-+0x10,0x10,0x23,0x20,0x48,0xf8,0x17,0x21,0x43,0xfd,0x9,0x1,0x1d,0xe1,0x41,0x1,0x40,0x44,0xf8,0x50,0x60,0x44,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x23,0x20,0x48,0xff,0x11,0x20,0x42,0xf9,0x7,0x0,0x1c,0xe0,0x41,0x2,0x40,0x50,0xf8,0x40,0x40,0xfc,0x24,0xa8,0x20,0x24,0xfe,0x40,0x60,0x90,0xc,0x4,
-+0x10,0x11,0x14,0xfe,0x20,0x28,0x48,0x7f,0x8,0x8,0xe,0xf8,0x48,0x8,0x8,0x8,0x8,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x0,0x0,0x7b,0x4a,0x4c,0x4b,0x48,0x4b,0x4a,0x4b,0x4a,0x7b,0x48,0x0,0x7,0x0,0x40,0x20,0xfe,0x2,0x4,0xfc,0x0,0xfc,0x4,0xfc,0x4,0xfc,0x0,0x4,0xfe,0x0,
-+0x2,0x1,0x7f,0x40,0x80,0x3f,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x0,0xff,0x0,0x0,0x0,0xfe,0x2,0x14,0xf8,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x10,0x4,0xfe,0x0,
-+0x1f,0x10,0x1f,0x10,0x1f,0x10,0xff,0x4,0x8,0x1f,0x2,0x51,0x50,0x90,0xf,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x14,0xfe,0x0,0x20,0xf0,0x10,0x84,0x82,0x12,0xf0,0x0,
-+0x20,0x10,0x14,0xfe,0x21,0x22,0x3c,0x24,0x24,0x24,0x24,0x24,0x44,0x55,0x8a,0x4,0x80,0x84,0xfe,0x80,0x0,0xfe,0x22,0x24,0xa0,0xa8,0xbc,0xa0,0xa0,0x60,0x26,0x1c,
-+0x2,0x1,0x1,0xff,0x2,0x2,0x4,0x8,0x3f,0x1,0x2,0x4,0x8,0x10,0x3f,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x10,0x20,0xc0,0x0,0x0,0x0,0x10,0x10,0xf8,0x8,
-+0x0,0x42,0x32,0x13,0x2,0x4,0xf7,0x10,0x10,0x10,0x11,0x11,0x12,0x2c,0x44,0x3,0x40,0x40,0x48,0xfc,0x40,0x44,0xfe,0xa0,0xa0,0xa0,0x22,0x22,0x1e,0x0,0x6,0xfc,
-+0x1,0x0,0x3f,0x24,0xa4,0x6f,0x32,0x2f,0x6a,0xaf,0x2a,0x2f,0x40,0x43,0x9c,0x8,0x0,0x84,0xfe,0x44,0x28,0x7c,0x10,0x90,0xfc,0x90,0x94,0xfe,0x10,0x90,0x10,0x10,
-+0x0,0x8,0x7c,0x4f,0x48,0x48,0x79,0x4a,0x4b,0x78,0x48,0x49,0x4a,0x7b,0x48,0x0,0x80,0x40,0x44,0xfe,0x40,0x80,0x8,0x10,0xe0,0x40,0x80,0x0,0x8,0xfc,0x4,0x0,
-+0x10,0x10,0x20,0x20,0x45,0xfa,0x11,0x21,0x41,0xfd,0x1,0x1,0x1d,0xe0,0x40,0x0,0x80,0x80,0x84,0xfe,0x4,0x4,0xf4,0x14,0x14,0xf4,0x14,0x14,0xf4,0x4,0x14,0x8,
-+0x28,0x28,0xfe,0x29,0x29,0x3b,0x15,0x7d,0x55,0x55,0x7d,0x11,0xff,0x11,0x11,0x11,0xa0,0xa0,0xa0,0x20,0x24,0x28,0x30,0x20,0x60,0xa0,0x20,0x22,0x22,0x22,0x1e,0x0,
-+0x8,0x8,0xff,0x8,0x20,0x7c,0x45,0x44,0x7c,0x43,0x7c,0x44,0x45,0x7c,0x40,0x0,0x20,0x24,0xfe,0x20,0x40,0x28,0xfc,0x88,0x50,0xfe,0x20,0x28,0xfc,0x20,0x20,0x20,
-+0x22,0x11,0x11,0x0,0x7f,0x40,0x80,0x1f,0x0,0x1,0xff,0x1,0x1,0x1,0x5,0x2,0x8,0x8,0x10,0x20,0xfe,0x2,0x4,0xe0,0x40,0x84,0xfe,0x0,0x0,0x0,0x0,0x0,
-+0x2,0x1,0x1,0x7f,0x40,0x80,0x4,0x4,0x4,0x8,0x8,0x10,0x10,0x20,0x40,0x0,0x0,0x0,0x0,0xfe,0x2,0x84,0x80,0x80,0x40,0x40,0x40,0x20,0x10,0xe,0x4,0x0,
-+0x1f,0x1,0x7f,0x41,0x9d,0x1,0x1d,0x1,0x3f,0x0,0x0,0x1f,0x0,0x0,0x3f,0x0,0xf0,0x0,0xfe,0x2,0x74,0x0,0x70,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x0,0x1,0x1,0x2,0x3f,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0xff,0x0,0x0,0x0,0x0,0x8,0xfc,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0xfe,0x0,
-+0x2,0x3f,0x22,0x22,0x3e,0x0,0x7f,0x41,0x49,0x49,0x49,0x49,0x49,0x14,0x23,0xc1,0x20,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x94,0x8,
-+0x0,0x3f,0x1,0xff,0x1,0x3f,0x29,0x25,0x3f,0x1,0x3f,0x1,0x7f,0x24,0x22,0x40,0x38,0xc0,0x4,0xfe,0x0,0xf8,0x28,0x48,0xf8,0x0,0xf8,0x0,0xfc,0x48,0x24,0x4,
-+0x10,0x17,0x24,0x24,0x47,0x94,0x25,0x65,0xa5,0x25,0x25,0x25,0x29,0x29,0x31,0x21,0x1c,0xe0,0x20,0x24,0xfe,0x20,0xfc,0x4,0x4,0xfc,0x4,0xfc,0x4,0x4,0xfc,0x4,
-+0x8,0x8,0xf,0x10,0x10,0x2f,0x48,0x88,0xf,0x8,0x8,0xf,0x8,0x0,0x0,0x0,0x0,0x4,0xfe,0x4,0x24,0xf4,0x24,0x24,0xe4,0x24,0x24,0xe4,0x24,0x4,0x28,0x10,
-+0x2,0x42,0x33,0x14,0x4,0x9,0xf1,0x11,0x11,0x11,0x11,0x13,0x15,0x18,0x10,0x0,0x0,0x4,0xfe,0x4,0x4,0xf4,0x14,0x14,0xf4,0x14,0x14,0xf4,0x14,0x4,0x14,0x8,
-+0x0,0x3f,0x0,0x0,0x1f,0x0,0x0,0x3f,0x0,0x0,0xff,0x8,0x4,0x4,0x0,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x20,0x24,0xfe,0x20,0x20,0x20,0xa0,0x40,
-+0x9,0xfd,0x9,0x49,0x49,0x49,0x49,0x49,0x7d,0x5,0x1d,0xe5,0x45,0x15,0xa,0x4,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x4,0x4,
-+0x0,0x41,0x31,0x12,0x2,0x4,0xf9,0x14,0x12,0x12,0x11,0x11,0x11,0x28,0x44,0x3,0x0,0x24,0x24,0x48,0x48,0x90,0x20,0x90,0x48,0x48,0x24,0x24,0x24,0x0,0x6,0xfc,
-+0x0,0x4,0xfe,0x21,0x21,0x3f,0x45,0x45,0xa5,0x19,0x9,0x11,0x21,0x40,0x80,0x0,0x80,0x84,0xfe,0x4,0x4,0xf4,0x14,0x14,0xf4,0x14,0x14,0xf4,0x14,0x4,0x14,0x8,
-+0x0,0x47,0x30,0x11,0x81,0x61,0x21,0x9,0x17,0x21,0xe1,0x21,0x21,0x21,0x21,0x21,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x50,0xf0,0x10,0x10,0x10,0xa,0xa,0x6,0x0,
-+0x1,0x41,0x31,0x11,0x1,0x1,0xf1,0x11,0x11,0x11,0x11,0x11,0x16,0x1a,0x14,0x8,0x4,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x4,0x4,0x4,
-+0x0,0x47,0x30,0x11,0x1,0x1,0xf1,0x11,0x17,0x11,0x11,0x11,0x15,0x19,0x11,0x1,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x50,0xf0,0x10,0x10,0x10,0xa,0xa,0x6,0x0,
-+0x0,0x40,0x3f,0x21,0x2,0x4,0xe4,0x27,0x3c,0x24,0x25,0x24,0x2c,0x54,0x88,0x7,0x10,0x10,0x10,0x10,0x10,0x10,0x58,0x54,0x94,0x92,0x12,0x50,0x20,0x0,0x6,0xfc,
-+0x0,0x47,0x30,0x11,0x1,0x1,0xf7,0x11,0x11,0x11,0x11,0x11,0x11,0x29,0x44,0x3,0x10,0xf8,0x10,0x10,0x10,0x50,0xf0,0x10,0x10,0x10,0x12,0xa,0x6,0x0,0x6,0xfc,
-+0x0,0x3f,0x20,0x20,0x20,0x20,0x20,0x2f,0x20,0x20,0x20,0x20,0x40,0x40,0x9f,0x0,0x8,0xfc,0x80,0x80,0x80,0x80,0x88,0xfc,0x80,0xa0,0x98,0x88,0x80,0x84,0xfe,0x0,
-+0x10,0x11,0x11,0x11,0xfd,0x11,0x15,0x19,0x31,0xd1,0x11,0x10,0x10,0x10,0x50,0x20,0x4,0xfe,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0xfc,0x24,0x20,0x20,0x20,0x20,0x20,
-+0x4,0xfe,0x9,0x29,0x29,0x49,0xff,0x9,0x19,0x29,0x48,0x88,0xb,0x8,0x28,0x10,0x40,0x88,0xfc,0x8,0x48,0x8,0x28,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x2,0xff,0x92,0x92,0x92,0xfe,0x92,0x92,0x92,0xfe,0x92,0x10,0x11,0x10,0x10,0x10,0x20,0x44,0xfe,0x84,0xa4,0x84,0x94,0x88,0x80,0xfe,0x2,0x12,0xfa,0x2,0xa,0x4,
-+0x0,0xb,0x7c,0x48,0x48,0x49,0x49,0x4b,0x48,0x48,0x48,0x79,0x46,0x0,0x0,0x0,0x8,0xfc,0x10,0x90,0x90,0x10,0x14,0xfe,0x10,0x30,0x50,0x90,0x10,0x10,0x50,0x20,
-+0x0,0x20,0x10,0xc,0x4,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x10,0x30,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x8,0x8,0xff,0x8,0x0,0x3f,0x8,0x8,0x10,0x3f,0x0,0x3,0xc,0x30,0xc0,0x0,0x40,0x44,0xfe,0x40,0x10,0xf8,0x20,0x20,0x24,0xfe,0xa0,0x20,0x20,0x20,0xa0,0x40,
-+0x0,0x7f,0x0,0x10,0x10,0x20,0x20,0x7f,0x1,0x2,0x4,0x8,0x30,0xc0,0x1,0x0,0x8,0xfc,0x40,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,
-+0x10,0x11,0x14,0x7e,0x54,0x55,0x55,0x57,0x7c,0x10,0x14,0x1c,0xf4,0x41,0x2,0x0,0x8,0xfc,0x8,0x88,0x88,0x8,0x8,0xfe,0x28,0x28,0x48,0x48,0x88,0x8,0x28,0x10,
-+0x1,0x21,0x21,0x3f,0x0,0x3f,0x20,0x2f,0x20,0x3f,0x20,0x20,0x2f,0x40,0x5f,0x80,0x0,0x8,0x8,0xf8,0x0,0xfc,0x80,0xf8,0x80,0xfe,0x80,0x80,0xf8,0x80,0xfe,0x0,
-+0x10,0x1f,0x22,0x42,0x8f,0x14,0x24,0x7f,0xa0,0x2f,0x28,0x28,0x28,0x2f,0x28,0x20,0x80,0xc4,0x3e,0x0,0x84,0xfe,0x88,0xe8,0x48,0xe8,0x48,0x48,0x48,0xc8,0x28,0x10,
-+0x0,0x43,0x32,0x12,0x83,0x62,0x22,0xb,0x12,0x22,0xe3,0x22,0x24,0x24,0x2b,0x30,0x8,0xfc,0x20,0x28,0xfc,0x20,0x24,0xfe,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x2,0x7f,0x4,0x24,0x24,0x45,0xfe,0x4,0xc,0x14,0x24,0x44,0x84,0x4,0x14,0x8,0x40,0x50,0x54,0xfe,0x90,0x90,0xfc,0x90,0x90,0xfc,0x90,0x90,0x94,0xfe,0x80,0x80,
-+0x0,0xb,0x7c,0x48,0x48,0x48,0x4c,0x4a,0x4a,0x49,0x48,0x78,0x48,0x0,0x7,0x0,0x8,0xfc,0x90,0x90,0x90,0x90,0x92,0x94,0x94,0x98,0x90,0x90,0x90,0x94,0xfe,0x0,
-+0x0,0x7f,0x4,0x4,0x4,0x4,0x44,0x24,0x24,0x14,0x14,0x4,0x4,0x4,0xff,0x0,0x8,0xfc,0x40,0x40,0x40,0x40,0x48,0x4c,0x50,0x50,0x60,0x40,0x40,0x44,0xfe,0x0,
-+0x0,0x47,0x20,0x22,0x2,0x4,0xef,0x20,0x20,0x20,0x24,0x29,0x32,0x24,0x8,0x0,0x8,0xfc,0x10,0x10,0x10,0x14,0xfe,0x10,0x30,0x50,0x90,0x10,0x10,0x10,0x50,0x20,
-+0x0,0x7f,0x1,0x11,0x11,0x11,0xff,0x10,0x1f,0x10,0x1f,0x0,0x29,0x24,0x40,0x0,0x8,0xfc,0x0,0xf0,0x0,0x4,0xfe,0x0,0xf0,0x4,0xfe,0x4,0x24,0x94,0x14,0x8,
-+0x0,0x17,0x7c,0x54,0x54,0x54,0x57,0x54,0x54,0x54,0x54,0x75,0x56,0x4,0x7,0x4,0x4,0xfe,0x4,0x44,0x44,0x44,0xfc,0x44,0x44,0xa4,0x94,0xc,0xc,0x4,0xfc,0x4,
-+0x20,0x1b,0x49,0x41,0x5f,0x42,0x44,0x49,0x5f,0x69,0x4f,0x49,0x4f,0x41,0x40,0x40,0x4,0xfe,0x4,0x24,0xf4,0x84,0x44,0x24,0xfc,0x24,0xe4,0x24,0xe4,0x14,0xf4,0x8,
-+0x20,0x27,0x24,0x24,0x2c,0xb4,0xa7,0xa4,0x24,0x24,0x24,0x25,0x56,0x4c,0x87,0x4,0x4,0xfe,0x4,0x44,0x44,0x44,0xfc,0x44,0x44,0xa4,0x94,0xc,0xc,0x4,0xfc,0x4,
-+0x0,0x40,0x37,0x10,0x81,0x62,0x27,0xa,0x12,0x23,0xe2,0x22,0x23,0x20,0x20,0x20,0x40,0x48,0xfc,0xa0,0x10,0x8,0xfe,0x48,0x48,0xf8,0x48,0x48,0xf8,0x42,0x42,0x3e,
-+0x8,0x8,0x8,0x7f,0x8,0x8,0xf,0x78,0x0,0x3f,0x24,0x24,0x24,0x24,0xff,0x0,0x40,0x40,0x40,0x50,0x48,0x44,0x44,0x40,0x8,0xfc,0x48,0x48,0x48,0x48,0xfe,0x0,
-+0x0,0x7f,0x2,0x12,0xa,0x2,0x3f,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x80,0x8,0xfc,0x40,0x48,0x50,0x44,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x8,0xfd,0x10,0x10,0x20,0x20,0x7c,0xa7,0x24,0x24,0x24,0x25,0x3d,0x22,0x4,0x0,0x8,0xfc,0x88,0x88,0x88,0x88,0x88,0xfe,0x88,0x88,0x88,0x8,0x8,0x8,0x8,0x8,
-+0x20,0x20,0x27,0x20,0xf9,0xa9,0xaa,0xaf,0xa8,0xf8,0x22,0x29,0x39,0xea,0x44,0x8,0x0,0x6,0xb8,0x88,0x8,0x8,0x2e,0xa8,0xa8,0xa8,0xa8,0x3e,0x0,0x86,0x7c,0x0,
-+0x1,0x21,0x21,0x21,0x3f,0x0,0xff,0x2,0x4,0xf,0x18,0x28,0x48,0x8,0xf,0x8,0x0,0x8,0x8,0x8,0xf8,0x0,0xfe,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x0,0x7d,0x4,0x8,0x11,0x21,0x7d,0x5,0x5,0x49,0x29,0x10,0x28,0x47,0x80,0x8,0x1c,0xe0,0x20,0x20,0x28,0x3c,0x20,0x20,0x20,0x28,0xfc,0x0,0x6,0xfc,0x0,
-+0x2,0x1,0xff,0x0,0x0,0x1f,0x0,0x1f,0x0,0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x0,0x4,0xfe,0x0,0x20,0xf0,0x0,0xf0,0x0,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,
-+0x10,0x9,0x7f,0x22,0x14,0x7f,0x44,0x48,0x52,0x44,0x48,0x52,0x44,0x48,0x90,0x21,0x4,0xfe,0x20,0x44,0xfe,0x84,0x94,0x94,0x94,0xa4,0xa4,0xa4,0xa4,0x48,0x86,0x2,
-+0x20,0x1b,0x4a,0x42,0x47,0x48,0x51,0x4e,0x48,0x48,0x4e,0x48,0x48,0x4f,0x40,0x40,0x4,0xfe,0x4,0x4,0xc4,0x84,0x24,0xf4,0x24,0x24,0xe4,0x24,0x24,0xe4,0x14,0x8,
-+0x1,0x1,0x11,0x11,0x22,0x4,0x19,0x61,0x1,0x11,0x11,0x22,0x2,0x4,0x18,0x60,0x0,0x8,0x18,0x20,0xc0,0x30,0xc,0x4,0x10,0x30,0x40,0x80,0x40,0x30,0xe,0x4,
-+0x0,0x41,0x31,0x11,0x81,0x61,0x22,0xc,0x10,0x23,0xe2,0x22,0x22,0x22,0x23,0x22,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0xe,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x1,0x1,0x7f,0x2,0xc,0x31,0xdf,0x11,0x11,0x1f,0x11,0x11,0x1f,0x11,0x1,0x0,0x0,0x8,0xfc,0x80,0x60,0x1e,0xf4,0x10,0x10,0xf0,0x10,0x10,0xf0,0x14,0x4,0xfc,
-+0x10,0x10,0x10,0x13,0xfc,0x11,0x13,0x1e,0x32,0xd3,0x12,0x12,0x13,0x10,0x50,0x20,0x40,0x40,0x48,0xfc,0xa0,0x50,0xf8,0x4e,0x48,0xf8,0x48,0x48,0xf8,0x42,0x42,0x3e,
-+0x0,0xb,0x7e,0x4a,0x4b,0x4a,0x7a,0x4b,0x4a,0x7a,0x4a,0x4a,0x4a,0x7a,0x4b,0x2,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x84,0x88,0x50,0x20,0x10,0x8e,0x4,0x0,
-+0x10,0x14,0x23,0x41,0x80,0x14,0x23,0x61,0xa0,0x21,0x22,0x2e,0x22,0x22,0x22,0x22,0x8,0x7c,0x0,0x0,0x0,0x4,0x7e,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x28,0x10,
-+0x40,0x20,0x2f,0x8,0x90,0x67,0x20,0xf,0x14,0x27,0xe4,0x27,0x20,0x21,0x23,0x24,0x80,0x40,0xfe,0x2,0x4,0xfc,0x40,0xfc,0x44,0xfc,0x44,0xfc,0x0,0x10,0xc,0x4,
-+0x10,0x10,0x10,0xff,0x11,0x13,0x7d,0x11,0x11,0xff,0x11,0x11,0x11,0x11,0x10,0x10,0x40,0x40,0xf8,0x10,0x24,0xfe,0x24,0x24,0x24,0xfc,0x4,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x13,0x12,0x12,0x12,0xfe,0x12,0x12,0x12,0x13,0x1e,0xf2,0x42,0x2,0x3,0x0,0x8,0xfc,0x0,0xfc,0x84,0xfc,0x84,0xfc,0x20,0xfe,0x48,0xc8,0x30,0x48,0xfe,0x0,
-+0x4,0x4,0xff,0x4,0x14,0x17,0xf0,0x17,0x14,0x14,0x34,0xc7,0x0,0x48,0x44,0x80,0x40,0x44,0xfe,0x40,0x50,0xd0,0x12,0xdc,0x50,0x52,0x52,0xce,0x0,0x88,0x46,0x2,
-+0x0,0x3f,0x20,0x20,0x20,0x20,0x3f,0x20,0x20,0x21,0x21,0x22,0x42,0x44,0x88,0x10,0x8,0xfc,0x80,0xa0,0x90,0x94,0xfe,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0xe,0x4,
-+0x4,0x7f,0x11,0x11,0x21,0x25,0x7f,0xa5,0x25,0x25,0x24,0x24,0x3c,0x25,0x2,0x4,0x8,0xfc,0x8,0x28,0x28,0x28,0x48,0x48,0x48,0x48,0x60,0xa0,0xa2,0x22,0x1e,0x0,
-+0x0,0x3f,0x24,0x24,0x29,0x29,0x3b,0x2d,0x29,0x29,0x29,0x29,0x49,0x49,0x89,0x9,0x8,0xfc,0x80,0xa0,0x14,0xfe,0x10,0x10,0xfc,0x10,0x10,0xfc,0x10,0x14,0xfe,0x0,
-+0x0,0x8,0x7f,0x48,0x48,0x4b,0x48,0x4b,0x48,0x48,0x4b,0x7a,0x4a,0x2,0x3,0x2,0x40,0x24,0xfe,0x0,0x8,0xfc,0x0,0xfc,0x0,0x4,0xfe,0x4,0x4,0x4,0xfc,0x4,
-+0x2,0x1,0x3f,0x8,0x4,0x3f,0x20,0x20,0x23,0x2c,0x20,0x23,0x4c,0x40,0x83,0x1c,0x0,0x10,0xf8,0x20,0x44,0xfe,0x20,0xc0,0x10,0x20,0xc0,0x8,0x10,0x60,0x80,0x0,
-+0x10,0x10,0x10,0x15,0x5a,0x50,0x53,0x92,0x12,0x12,0x13,0x2a,0x26,0x46,0x83,0x2,0x80,0x80,0xfc,0x8,0x10,0x84,0x3e,0x4,0x4,0x4,0xbc,0x4,0x4,0x4,0xfc,0x4,
-+0x2,0x1,0x7f,0x40,0x9f,0x10,0x1f,0x10,0x1f,0x2,0xff,0x4,0xc,0x3,0xc,0x30,0x0,0x0,0xfe,0x2,0xf4,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x20,0x40,0x80,0x60,0x18,
-+0x0,0x40,0x33,0x10,0x0,0x3,0xf2,0x12,0x12,0x12,0x12,0x12,0x16,0x1a,0x14,0x9,0x40,0x24,0xfe,0x88,0x50,0xfe,0x10,0x20,0x48,0x90,0x24,0x44,0x88,0x10,0x60,0x80,
-+0x8,0xfc,0x8,0x48,0x49,0x4a,0x4d,0x48,0x7c,0x6,0x5,0x1d,0xe5,0x44,0x17,0x8,0x40,0x40,0xa0,0xa0,0x10,0xe,0xf4,0x0,0x48,0x48,0x48,0x50,0x10,0x24,0xfe,0x0,
-+0x4,0xfe,0x20,0x21,0x3d,0x25,0x25,0x45,0x65,0x9b,0x8,0x10,0x20,0x40,0x81,0x2,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0xfe,0x20,0x50,0x50,0x88,0x6,0x4,
-+0x1,0x1,0x1,0x1f,0x11,0x11,0x11,0x11,0x11,0xff,0x1,0x2,0x2,0x4,0x8,0x30,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x14,0xfe,0x0,0x80,0x80,0x60,0x1c,0x8,
-+0x1,0x1f,0x11,0x11,0xff,0x4,0xa,0x3f,0xca,0x8,0x8,0xf,0x0,0x7f,0x0,0x0,0x10,0xf8,0x10,0x14,0xfe,0x40,0x30,0xee,0x24,0xa0,0x44,0xfe,0x4,0xc4,0x14,0x8,
-+0x8,0x1c,0xf0,0x11,0x15,0xff,0x11,0x39,0x35,0x53,0x50,0x90,0x10,0x10,0x11,0x12,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0xfe,0x20,0x50,0x50,0x88,0x6,0x4,
-+0x10,0x13,0x10,0x10,0xfc,0x10,0x33,0x38,0x54,0x50,0x91,0x11,0x12,0x14,0x11,0x10,0x0,0xf8,0x10,0x20,0x40,0x84,0xfe,0xa4,0xa4,0xa4,0x24,0x44,0x44,0x84,0x28,0x10,
-+0x10,0x13,0x10,0x10,0xfc,0x10,0x17,0x18,0x30,0xd0,0x11,0x11,0x12,0x14,0x51,0x20,0x0,0xf8,0x10,0x20,0x40,0x84,0xfe,0xa4,0xa4,0xa4,0x24,0x44,0x44,0x84,0x28,0x10,
-+0xa,0x9,0x8,0x17,0x10,0x30,0x53,0x90,0x10,0x10,0x1f,0x10,0x10,0x10,0x10,0x10,0x8,0x10,0xa0,0xfc,0x40,0x50,0xf8,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x1,0x0,0x1f,0x10,0x97,0x50,0x50,0x11,0x37,0x51,0xd1,0x12,0x22,0x24,0x49,0x0,0x0,0x84,0xfe,0x0,0xf0,0x40,0x80,0x4,0xfe,0x24,0x24,0x44,0x44,0x84,0x28,0x10,
-+0x8,0x4,0x2,0x7f,0x1,0x1,0x1,0x3f,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x20,0x40,0x88,0xfc,0x0,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,
-+0x2,0x41,0x30,0x17,0x80,0x60,0x23,0x8,0x10,0x20,0xef,0x20,0x20,0x20,0x20,0x20,0x8,0x10,0xa0,0xfc,0x40,0x40,0xf8,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x7d,0x45,0x49,0x49,0x51,0x49,0x49,0x45,0x45,0x45,0x69,0x51,0x41,0x41,0x41,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x1f,0x20,0x2f,0x40,0xbf,0x8,0x5,0x3f,0x2,0x1f,0x2,0x7f,0x2,0x2,0x2,0x0,0xfc,0x0,0xf8,0x0,0xf8,0x88,0x8,0xe8,0x8,0xc8,0x8,0xfa,0xa,0x4,0x0,
-+0x10,0x11,0x12,0x24,0x24,0x64,0xa4,0x24,0x24,0x24,0x25,0x26,0x24,0x20,0x20,0x20,0x80,0x4,0x7e,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x40,0x40,0x40,
-+0x1,0x0,0x1f,0x11,0x90,0x5f,0x50,0x10,0x37,0x50,0xd0,0x1f,0x20,0x20,0x40,0x0,0x0,0x84,0xfe,0x10,0xa4,0xfe,0x40,0x48,0xfc,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,
-+0x8,0x4,0x2,0x7f,0x1,0x3f,0x1,0xff,0x4,0x8,0x34,0xc4,0x4,0x4,0x8,0x10,0x20,0x40,0x88,0xfc,0x0,0xf8,0x0,0xfe,0x40,0x30,0x4e,0x44,0x40,0x40,0x40,0x40,
-+0x12,0x11,0x10,0x17,0xfc,0x10,0x3b,0x34,0x50,0x50,0x9f,0x10,0x10,0x10,0x10,0x10,0x8,0x10,0xa0,0xfc,0x40,0x50,0xf8,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x1,0x40,0x3f,0x10,0x87,0x60,0x2f,0x8,0x10,0x23,0xe0,0x27,0x21,0x22,0x2d,0x20,0x10,0xa4,0xfe,0x40,0xfc,0x40,0xfe,0x80,0x40,0xc8,0x50,0x60,0x50,0x4e,0x44,0x80,
-+0x2,0x44,0x2f,0x28,0xf,0x8,0xef,0x22,0x3f,0x24,0x27,0x24,0x28,0x52,0x89,0x7,0x10,0x10,0x94,0xbe,0xc4,0xa4,0xa4,0x28,0xa8,0x10,0x90,0xa8,0xa4,0xc4,0x6,0xfc,
-+0x8,0x7f,0x48,0x4b,0x4a,0x7a,0x4b,0x48,0x48,0x7f,0x48,0x49,0x48,0x48,0x88,0x1b,0x4,0xfe,0x90,0xfc,0x94,0x94,0xfc,0x40,0x40,0xfe,0x88,0x8,0x90,0x60,0x98,0x4,
-+0x10,0x10,0x11,0x10,0xfc,0x24,0x24,0x27,0x24,0x44,0x28,0x10,0x28,0x45,0x82,0x4,0x8,0x1c,0xe0,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x50,0x50,0x88,0x8,0x6,0x4,
-+0x8,0xfd,0x10,0x11,0x10,0x10,0x7d,0x11,0x12,0x14,0x13,0x1c,0xf1,0x41,0x1,0x1,0x1c,0xe0,0x0,0x24,0xa4,0xa8,0x0,0xfc,0x20,0x24,0xfe,0x20,0x24,0x24,0xfc,0x4,
-+0x10,0x10,0x17,0x12,0xfd,0x11,0x16,0x1b,0x34,0xd0,0x1f,0x10,0x12,0x12,0x53,0x22,0x8,0x3c,0xc0,0x48,0x48,0x50,0x0,0xfc,0x40,0x44,0xfe,0x40,0x48,0x48,0xf8,0x8,
-+0x4,0x4,0x3,0x7e,0x1,0x0,0x7,0x38,0x0,0x7f,0x2,0x2,0x4,0x4,0x8,0x70,0x0,0x8,0xfc,0x20,0x40,0x84,0x64,0x1c,0x8,0xfc,0x40,0x40,0x40,0x42,0x42,0x3e,
-+0x0,0x47,0x32,0x11,0x2,0x3,0xf4,0x10,0x1f,0x10,0x12,0x13,0x12,0x28,0x47,0x0,0x38,0xc0,0x48,0x50,0x40,0xf8,0x40,0x44,0xfe,0x40,0x48,0xf8,0x8,0x6,0xfc,0x0,
-+0x2,0x1,0x7f,0x48,0x90,0x28,0xf,0x11,0x21,0xff,0x1,0x21,0x21,0x21,0x3f,0x20,0x0,0x0,0xfe,0x22,0x14,0x8,0xf0,0x0,0x4,0xfe,0x0,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x40,0x27,0x22,0x1,0x1,0xe2,0x23,0x24,0x20,0x2f,0x20,0x2a,0x32,0x23,0x2,0x8,0x3c,0xc0,0x48,0x48,0x50,0x0,0xfc,0x40,0x44,0xfe,0x40,0x48,0x48,0xf8,0x8,
-+0x10,0x10,0x10,0x12,0xfd,0x25,0x24,0x24,0x24,0x45,0x2a,0x10,0x28,0x45,0x82,0x4,0x50,0x50,0x50,0x52,0x54,0x58,0x50,0x50,0xd8,0x54,0x54,0x90,0x92,0x12,0xe,0x0,
-+0x0,0x8,0x7c,0x4f,0x48,0x49,0x4a,0x4d,0x49,0x48,0x48,0x48,0x78,0x49,0x2,0xc,0x80,0x40,0x44,0xfe,0x0,0x10,0x8,0x14,0x10,0xa0,0xa0,0x40,0xa0,0x10,0xe,0x4,
-+0x0,0x0,0x7f,0x2,0x21,0x11,0x11,0x4,0x38,0x20,0x20,0x3e,0x20,0x20,0x3f,0x20,0x10,0x78,0x80,0x8,0x8,0x10,0x20,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x4,0x4,0xff,0x4,0x8,0x10,0x22,0x7c,0x9,0x10,0x7e,0x0,0xe,0x70,0x20,0x0,0x40,0x44,0xfe,0x40,0x40,0x44,0x7e,0x84,0x4,0x44,0x24,0x24,0x4,0x4,0x28,0x10,
-+0x0,0x7f,0x4,0x3f,0x24,0x24,0x3f,0x2,0x2,0xff,0x4,0x8,0x6,0x1,0x6,0x38,0x8,0xfc,0x40,0xf8,0x48,0x48,0xf8,0x0,0x4,0xfe,0x20,0x20,0x40,0x80,0x60,0x10,
-+0x10,0x13,0x11,0x54,0x39,0x10,0xfd,0x29,0x2b,0x2d,0x29,0x2b,0x2d,0x49,0x81,0x1,0x0,0xfc,0x54,0xcc,0x54,0x44,0x20,0xfe,0x20,0xfc,0x20,0xfc,0x20,0x24,0xfe,0x0,
-+0x10,0x17,0x12,0x12,0xfe,0x13,0x3a,0x36,0x53,0x52,0x92,0x13,0x1e,0x10,0x10,0x10,0x0,0xfe,0x52,0x54,0x54,0xd8,0x54,0x52,0xd2,0x52,0x5a,0xd4,0x50,0x50,0x50,0x50,
-+0x0,0x17,0x78,0x53,0x50,0x57,0x54,0x5b,0x50,0x53,0x52,0x73,0x41,0x0,0xf,0x0,0x48,0xfc,0x40,0xf8,0x0,0xfe,0x2,0xfc,0x0,0xf8,0x8,0xf8,0x10,0xa4,0xfe,0x0,
-+0x2,0x7f,0x22,0x22,0x3e,0x22,0x22,0x3e,0x22,0x22,0x27,0xfa,0x42,0x2,0x2,0x2,0x0,0x7c,0x44,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x64,0x58,0x40,0x40,0x40,
-+0x4,0x8,0x14,0x2,0x1,0x6,0x18,0xe0,0x1f,0x2,0x2,0x2,0x2,0x2,0x2,0x2,0x40,0x20,0x50,0x80,0x0,0xc0,0x30,0xe,0xf0,0x10,0x10,0x10,0x50,0x20,0x0,0x0,
-+0x0,0x7f,0x49,0x49,0x7f,0x49,0x49,0x7f,0x8,0xa,0x7f,0x8,0x8,0xf,0xf8,0x40,0x0,0x7c,0x4,0x28,0x10,0x10,0xfe,0x12,0x14,0x10,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x0,0x40,0x30,0x10,0x1,0x2,0xf,0x10,0x20,0xe3,0x22,0x22,0x22,0x22,0x23,0x2,0x40,0x40,0x80,0x80,0x10,0x8,0xfc,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x1,0x1,0x1,0x11,0x11,0x11,0x1f,0xf1,0x11,0x11,0x11,0x11,0x10,0x10,0xf,0x0,0x0,0x0,0x0,0x0,0x30,0xd0,0x10,0x10,0x10,0x50,0x20,0x2,0x2,0x2,0xfe,0x0,
-+0x0,0xff,0x2,0x4,0x1f,0x10,0x11,0x11,0x11,0x11,0x11,0x11,0x12,0x4,0x8,0x30,0x4,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x60,0x18,0x8,
-+0x10,0x10,0x17,0x10,0xf9,0x11,0x12,0x1a,0x36,0xdb,0x12,0x12,0x12,0x12,0x53,0x22,0x80,0x44,0xfe,0x20,0x20,0x3c,0x44,0x64,0x98,0x48,0x50,0x20,0x50,0x8e,0x4,0x0,
-+0x4,0x4,0x4,0x4,0x44,0x24,0x24,0x14,0x14,0x14,0x14,0x4,0x4,0x4,0xff,0x0,0x40,0x40,0x40,0x40,0x44,0x44,0x48,0x48,0x50,0x50,0x60,0x40,0x40,0x44,0xfe,0x0,
-+0x0,0x8,0x7c,0x48,0x48,0x48,0x4f,0x48,0x48,0x48,0x48,0x78,0x48,0x0,0x0,0x0,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x2,0x2,0x3f,0x22,0x22,0x3f,0x22,0x22,0x3f,0x22,0x1,0x1,0x6,0x18,0xe0,0x0,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,0x20,0xc0,0x80,0x44,0x34,0xc,
-+0x0,0x78,0x4f,0x48,0x49,0x79,0x4a,0x4a,0x4e,0x7b,0x4a,0x4a,0x4a,0x4a,0x8b,0x1a,0x80,0x44,0xfe,0x20,0x20,0x3c,0x44,0x64,0x98,0x48,0x50,0x20,0x50,0x8e,0x4,0x0,
-+0x2,0x1,0xff,0x8,0x8,0x10,0x11,0x32,0x56,0x99,0x10,0x10,0x10,0x11,0x12,0x1c,0x0,0x4,0xfe,0x80,0x80,0xf8,0x8,0x88,0x50,0x10,0xa0,0x40,0xa0,0x10,0xe,0x4,
-+0x0,0x40,0x37,0x10,0x81,0x61,0x22,0xa,0x16,0x2b,0xe2,0x22,0x22,0x22,0x23,0x22,0x80,0x44,0xfe,0x20,0x20,0x3c,0x44,0x64,0x98,0x48,0x50,0x20,0x50,0x8e,0x4,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x7f,0x1,0x3f,0x0,0x7f,0x40,0x9f,0x0,0x1f,0x10,0x10,0x1f,0x4,0xff,0x0,0x8,0xfc,0x0,0xf8,0x0,0xfe,0x2,0xf4,0x0,0xf0,0x10,0x10,0xf0,0x44,0xfe,0x0,
-+0x0,0x7f,0x44,0x44,0x4f,0x50,0x40,0x5f,0x40,0x41,0x41,0x42,0x4c,0x40,0x7f,0x0,0x8,0xfc,0x0,0x10,0xf8,0x80,0x88,0xfc,0x80,0x40,0x30,0x18,0x8,0x0,0xfc,0x0,
-+0x10,0x11,0x11,0x11,0xfd,0x10,0x17,0x19,0x31,0xd1,0x11,0x11,0x11,0x17,0x50,0x20,0x8,0xfc,0x8,0x8,0xf8,0x0,0xfe,0x8,0xf8,0x8,0xf8,0x8,0xe,0xf8,0x8,0x8,
-+0x10,0x10,0x10,0x1f,0x20,0x20,0x7c,0x90,0x11,0x7e,0x14,0x10,0x14,0x18,0x10,0x0,0x40,0x20,0x24,0xfe,0x40,0x40,0xa0,0xa4,0xa8,0x90,0x90,0x88,0x8e,0xa4,0xc0,0x80,
-+0x8,0x8,0x8,0x17,0x10,0x30,0x50,0x90,0x11,0x12,0x14,0x10,0x10,0x10,0x10,0x10,0x40,0x20,0x24,0xfe,0x40,0x40,0xa0,0xa4,0xa8,0x90,0x90,0x88,0x8e,0xa4,0xc0,0x80,
-+0x8,0xb,0x8,0x10,0x10,0x3f,0x50,0x90,0x10,0x13,0x10,0x10,0x11,0x11,0x12,0x14,0x8,0xfc,0x88,0x88,0x88,0xfe,0x88,0x88,0x88,0xf8,0x88,0x80,0x0,0x0,0x0,0x0,
-+0x2,0x1,0x1,0xff,0x2,0x2,0x5,0x5,0xc,0x14,0x24,0xc4,0x4,0x5,0x6,0x4,0x0,0x0,0x4,0xfe,0x0,0x8,0x18,0x20,0xc0,0x80,0x40,0x20,0x18,0xe,0x4,0x0,
-+0x4,0x7f,0x48,0x48,0x48,0x5e,0x52,0x52,0x52,0x5e,0x48,0x48,0x48,0x48,0x7e,0x1,0x4,0xfe,0x20,0x44,0xfe,0x84,0x94,0x94,0x94,0x94,0xa4,0xa4,0xa4,0x58,0x86,0x2,
-+0x1,0x1,0xff,0x1,0x3f,0x1,0x1,0x3f,0x21,0x21,0x3f,0x1,0x2,0xc,0x30,0xc0,0x0,0x4,0xfe,0x0,0xf8,0x8,0x8,0xf8,0x8,0x0,0xfc,0x4,0x94,0x48,0x30,0xe,
-+0x0,0x43,0x32,0x13,0x0,0xf,0xf0,0x13,0x12,0x12,0x12,0x10,0x11,0x2a,0x44,0x3,0x48,0xfc,0x48,0xf8,0x40,0xfe,0x8,0xfc,0x8,0x48,0x48,0xa0,0x18,0x8,0x6,0xfc,
-+0x8,0x1c,0xf0,0x11,0x12,0xfc,0x10,0x39,0x34,0x54,0x90,0x11,0x10,0x10,0x10,0x17,0x40,0x40,0xfc,0x84,0x48,0x30,0x60,0xa0,0x3e,0x42,0xc4,0x24,0x18,0x30,0xc0,0x0,
-+0x8,0x8,0x8,0x12,0x12,0x32,0x51,0x91,0x10,0x10,0x10,0x10,0x11,0x12,0x14,0x18,0x0,0x80,0x64,0x24,0x4,0x8,0x8,0x10,0x90,0xa0,0x40,0xa0,0x10,0x8,0xe,0x4,
-+0x0,0x78,0x4f,0x48,0x4b,0x78,0x4b,0x4a,0x4a,0x7b,0x48,0x48,0x48,0x48,0x89,0x1e,0x40,0x44,0xfe,0x40,0xf8,0x48,0xf8,0x48,0x40,0xfe,0x42,0x4a,0xa4,0x90,0xe,0x4,
-+0x20,0x26,0x38,0x22,0x1e,0x21,0x3e,0x48,0x8,0xfe,0x8,0x8,0x14,0x22,0x41,0x2,0x0,0xfc,0x8,0x50,0x20,0xfe,0x22,0x24,0xa0,0xb8,0xa0,0xa0,0xe0,0xa0,0x1e,0x4,
-+0x0,0x40,0x33,0x12,0x82,0x62,0x23,0xa,0x12,0x22,0xe2,0x22,0x24,0x24,0x28,0x20,0x8,0x3c,0xc0,0x0,0x0,0x4,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x2,0x1,0x7f,0x40,0x80,0xf,0x8,0x8,0xf,0x8,0x8,0xf,0x8,0x8,0xff,0x0,0x0,0x0,0xfe,0x2,0x24,0xf0,0x20,0x20,0xe0,0x20,0x20,0xe0,0x20,0x24,0xfe,0x0,
-+0x20,0x20,0x2f,0x20,0xfb,0x48,0x4b,0x4a,0x4a,0x93,0x50,0x20,0x50,0x48,0x81,0x6,0x40,0x44,0xfe,0x40,0xf8,0x48,0xf8,0x48,0x40,0xfe,0x42,0x4a,0xa4,0x90,0xe,0x4,
-+0x8,0xf,0x10,0x1f,0x0,0xff,0x49,0x2a,0x7f,0x1c,0x2a,0x48,0xff,0x8,0x10,0x60,0x20,0xf0,0x20,0xe0,0x24,0xfe,0x20,0x78,0x24,0xfe,0x54,0x92,0xfe,0x10,0x10,0x10,
-+0x10,0x10,0x17,0x10,0xfc,0x11,0x37,0x38,0x57,0x52,0x92,0x12,0x13,0x12,0x10,0x10,0x40,0x48,0xfc,0x40,0xa0,0x14,0xfe,0x8,0xe8,0x28,0x28,0x28,0xe8,0x8,0x28,0x10,
-+0x10,0x10,0x10,0x12,0x7e,0x55,0x55,0x55,0x54,0x7c,0x10,0x14,0x1c,0xf5,0x42,0xc,0x0,0x80,0x64,0x24,0x4,0x8,0x8,0x10,0x90,0xa0,0x40,0xa0,0x90,0x8,0xe,0x4,
-+0x8,0x8,0xf,0x10,0x10,0x31,0x5f,0x90,0x13,0x12,0x12,0x12,0x13,0x12,0x10,0x10,0x40,0x48,0xfc,0x40,0xa0,0x14,0xfe,0x8,0xe8,0x28,0x28,0x28,0xe8,0x8,0x28,0x10,
-+0x0,0x7f,0x0,0x0,0x20,0x20,0x3f,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x1f,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0xf0,0x10,0x0,0x0,0x0,0x4,0x4,0x4,0xfc,0x0,
-+0x0,0x0,0x7f,0x0,0x0,0x1,0x2,0x4,0x8,0x10,0x10,0x20,0x20,0x20,0x1f,0x0,0x0,0x0,0xe0,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x4,0x4,0xfc,0x0,
-+0x2,0x4,0x8,0x10,0x3f,0x8,0x8,0x1f,0x21,0x1,0xff,0x2,0x4,0x8,0x10,0x60,0x0,0x0,0x20,0x10,0xf8,0x8,0x10,0xf8,0x0,0x4,0xfe,0x80,0x40,0x30,0x1c,0x8,
-+0x0,0x4,0x42,0x43,0x41,0x40,0x40,0x40,0x41,0x42,0x44,0x48,0x50,0x60,0x1,0x6,0x0,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x10,0x10,0x10,0x20,0x30,0x48,0x84,0x4,
-+0x4,0x4,0xff,0x4,0x0,0x3f,0x0,0x1,0x2,0x4,0x8,0x10,0x20,0x20,0x20,0x1f,0x40,0x44,0xfe,0x40,0x0,0xc0,0x80,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0x2,0xfe,
-+0x10,0x10,0x13,0x12,0xfe,0x12,0x16,0x1a,0x32,0xd2,0x12,0x13,0x12,0x10,0x50,0x20,0x40,0x84,0x3e,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0xa4,0x34,0x28,0x20,0x20,0x20,
-+0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x8,0x1f,0x24,0x44,0x88,0x10,0x21,0x2,0x4,0xf0,0x10,0x10,0xf0,0x10,0x10,0xf0,0x4,0xfe,0x44,0x44,0x84,0x84,0x4,0x28,0x10,
-+0x1f,0x10,0x10,0x1f,0x0,0x3f,0x21,0x21,0x21,0x3f,0x20,0x20,0x20,0x20,0x1f,0x0,0xf0,0x10,0x10,0xf0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x0,0x4,0x4,0xfc,0x0,
-+0x10,0x10,0x10,0x10,0x55,0x56,0x55,0x54,0x54,0x54,0x54,0x55,0x7d,0x45,0x0,0x0,0x80,0x80,0x88,0xfc,0x0,0x0,0xf8,0x10,0x20,0x40,0x80,0x0,0x2,0x2,0xfe,0x0,
-+0x8,0x8,0xb,0x10,0x10,0x30,0x50,0x91,0x12,0x12,0x14,0x14,0x14,0x14,0x13,0x10,0x0,0x0,0xf8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x8,0x9,0x11,0x21,0x41,0xa,0x14,0x33,0x51,0x91,0x10,0x10,0x10,0x10,0x13,0x1c,0x10,0xf8,0x10,0x10,0x10,0xe,0x0,0xf8,0x8,0x10,0x90,0xe0,0x40,0xb0,0xe,0x4,
-+0x0,0x7b,0x49,0x48,0x4f,0x78,0x4b,0x4a,0x4b,0x7a,0x4b,0x48,0x4b,0x4b,0x8d,0x18,0x40,0xf8,0x10,0xa4,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x80,0x68,0x26,0xa,0xf8,
-+0x2,0x43,0x24,0x28,0x1f,0x8,0xe8,0x2f,0x20,0x21,0x21,0x22,0x24,0x58,0x88,0x7,0x0,0xe0,0x20,0x48,0xfc,0x88,0x88,0xf8,0x80,0x40,0x54,0x44,0x3c,0x0,0x6,0xfc,
-+0x40,0x4c,0x71,0x40,0x47,0x3c,0x41,0x7c,0x91,0x10,0xfe,0x13,0x28,0x24,0x44,0x80,0x20,0x20,0xfc,0x24,0xfe,0x24,0xfc,0x20,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x0,0x0,0x1f,0x10,0x91,0x51,0x51,0x12,0x34,0x53,0xd1,0x10,0x20,0x21,0x46,0x18,0x80,0x44,0xfe,0x0,0xf0,0x10,0x10,0xc,0x0,0xf8,0x10,0xa0,0x40,0xb0,0xe,0x4,
-+0x2,0x1,0x1,0xff,0x4,0x4,0x4,0x14,0x14,0x24,0x44,0x4,0x8,0x8,0x11,0x0,0x0,0x0,0x4,0xfe,0x40,0x40,0x40,0x50,0x48,0x44,0x44,0x40,0x40,0x40,0x40,0x80,
-+0x2,0x1,0xff,0x5,0xc,0x34,0xc5,0x6,0x3f,0x24,0x28,0x37,0x24,0x24,0x27,0x20,0x0,0x4,0xfe,0x10,0xa0,0x60,0x1c,0x8,0xfc,0x48,0x28,0xd8,0x48,0x48,0xc8,0x18,
-+0x1,0x3f,0x8,0x4,0xff,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x2,0x51,0x50,0x90,0xf,0x10,0xf8,0x20,0x44,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x0,0x84,0x92,0x12,0xf0,
-+0x10,0x8,0x7f,0x22,0x14,0xff,0x20,0x52,0x9c,0x28,0x4c,0x1b,0x29,0xc8,0x28,0x11,0x8,0x7c,0x48,0x48,0x48,0x86,0x0,0xf8,0x48,0x48,0x48,0x30,0x20,0x50,0x8e,0x4,
-+0x10,0x10,0x13,0x10,0x58,0x54,0x50,0x91,0x12,0x12,0x14,0x14,0x14,0x14,0x13,0x10,0x0,0x0,0xf8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x0,0x2,0x21,0x21,0x10,0x10,0x8,0x8,0x4,0x2,0x1,0x2,0x4,0x8,0x10,0x60,0x0,0x8,0x8,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x0,0x80,0x60,0x18,0xe,0x4,
-+0x8,0x4,0x0,0x7f,0x0,0x4,0x8,0x10,0x0,0x3f,0x24,0x24,0x24,0x24,0xff,0x0,0x20,0x40,0x8,0xfc,0x0,0x40,0x30,0x10,0x0,0xf8,0x48,0x48,0x48,0x48,0xfe,0x0,
-+0x2,0x41,0x30,0x17,0x80,0x61,0x22,0xc,0x10,0x27,0xe5,0x25,0x25,0x25,0x3f,0x20,0x10,0x20,0x8,0xfc,0x0,0x20,0x18,0x8,0x0,0xf8,0x28,0x28,0x28,0x28,0xfe,0x0,
-+0x2,0x42,0x33,0x12,0x2,0x1,0xf0,0x10,0x13,0x12,0x12,0x13,0x16,0x1a,0x13,0x2,0x0,0x38,0xc0,0x2,0x2,0xfe,0x0,0x4,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,
-+0x0,0x40,0x30,0x12,0x2,0x2,0xf1,0x11,0x10,0x10,0x10,0x14,0x19,0x12,0x4,0x8,0x0,0x80,0x44,0x44,0x4,0x8,0x8,0x10,0x90,0xa0,0x40,0xa0,0x10,0x8,0xe,0x4,
-+0x0,0x40,0x2f,0x28,0x10,0x3,0xe2,0x22,0x23,0x22,0x22,0x23,0x2a,0x32,0x2f,0x0,0x80,0x40,0xfe,0x2,0x4,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0xfe,0x0,
-+0x0,0x47,0x22,0x21,0x0,0x0,0xe3,0x2c,0x20,0x23,0x20,0x24,0x2f,0x30,0x20,0x0,0x0,0xfc,0x8,0xb0,0x40,0xa0,0x1e,0x44,0x50,0xf8,0x40,0x48,0xfc,0x40,0x40,0x40,
-+0x0,0x3f,0x20,0x20,0x3f,0x20,0x20,0x1f,0x8,0x8,0xff,0x8,0x8,0x8,0x10,0x20,0x10,0xf8,0x10,0x10,0xf0,0x4,0x4,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x7e,0x22,0x1a,0x22,0x2,0x1f,0x11,0x1f,0x11,0x1f,0x4,0x3f,0x4,0xff,0x8,0x30,0xf8,0x88,0x68,0x88,0x8,0xf0,0x10,0xf0,0x10,0xf0,0x40,0xf8,0x40,0xfe,0x20,0x10,
-+0x0,0x7e,0x22,0x12,0x6,0x1a,0x62,0x1,0x1,0x7f,0x0,0x8,0x4,0x4,0xff,0x0,0x4,0xfe,0x44,0x24,0xc,0x34,0xc4,0x0,0x8,0xfc,0x20,0x20,0x40,0x44,0xfe,0x0,
-+0x10,0x11,0x20,0x20,0x44,0xf8,0x10,0x23,0x40,0xfd,0x0,0x0,0x1d,0xe0,0x40,0x0,0x0,0xfc,0x88,0x50,0x20,0x50,0x8e,0x24,0x20,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,
-+0x4,0x4,0xff,0x4,0x3f,0x21,0x21,0x2f,0x21,0x22,0x22,0x24,0x28,0x20,0x3f,0x20,0x40,0x44,0xfe,0x40,0xf8,0x8,0x8,0xe8,0x8,0x88,0x88,0x48,0x28,0x8,0xf8,0x8,
-+0x8,0x8,0xff,0x8,0x7c,0x44,0x48,0x50,0x48,0x44,0x44,0x64,0x59,0x41,0x42,0x44,0x20,0x24,0xfe,0x20,0xfc,0x84,0x84,0xfc,0x84,0x84,0xfc,0x84,0x4,0x4,0x14,0x8,
-+0x0,0x7f,0x41,0x41,0x41,0x5f,0x41,0x41,0x42,0x42,0x44,0x48,0x50,0x40,0x7f,0x40,0x4,0xfe,0x4,0x4,0x24,0xf4,0x4,0x4,0x84,0x84,0x44,0x34,0x14,0x4,0xfc,0x4,
-+0xc,0x70,0x44,0x7e,0x44,0x7d,0x46,0x7d,0x40,0x7c,0x44,0x44,0x44,0x54,0x48,0x83,0x8,0xfc,0x88,0x88,0x88,0x6,0x0,0xfc,0x88,0x88,0x50,0x20,0x50,0x50,0x8e,0x4,
-+0x2,0x1,0x3f,0x8,0x4,0x4,0xff,0x0,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x0,0x10,0xf8,0x20,0x20,0x44,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x0,0x7c,0x44,0x48,0x48,0x50,0x48,0x48,0x44,0x44,0x44,0x68,0x51,0x41,0x42,0x44,0x4,0xfe,0x84,0x84,0x84,0xfc,0x84,0x84,0x84,0xfc,0x84,0x84,0x4,0x4,0x14,0x8,
-+0x10,0x11,0x11,0x11,0xfd,0x25,0x25,0x25,0x25,0x45,0x29,0x11,0x29,0x45,0x85,0x1,0x4,0xfe,0x24,0x24,0x24,0xfc,0x24,0x24,0x54,0x54,0x54,0x8c,0x4,0x4,0xfc,0x4,
-+0x0,0x8,0x7c,0x48,0x49,0x49,0x4a,0x4c,0x48,0x4b,0x48,0x78,0x48,0x0,0x0,0x0,0x40,0x40,0xa0,0xa0,0x10,0x10,0x8e,0x44,0x40,0xf8,0x8,0x10,0x10,0x20,0x40,0x80,
-+0x10,0x11,0x11,0x3d,0x21,0x21,0x7d,0x91,0x11,0xfd,0x11,0x13,0x15,0x19,0x11,0x1,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x4,0x8c,0x50,0x20,0x10,0x4e,0x84,0x0,
-+0x40,0x30,0x17,0x0,0x84,0x62,0x22,0x7,0x10,0x20,0xef,0x20,0x20,0x20,0x27,0x20,0x8,0x3c,0xc0,0x4,0x84,0x48,0x10,0xfc,0x40,0x44,0xfe,0x40,0x40,0x48,0xfc,0x0,
-+0x2,0x1,0x7f,0x40,0x80,0x3f,0x1,0x3f,0x21,0x3f,0x21,0x3f,0x0,0xc,0x30,0x40,0x0,0x0,0xfe,0x2,0x14,0xf8,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x0,0x60,0x18,0x4,
-+0x10,0x10,0x10,0x10,0x1e,0x22,0x25,0x50,0x90,0x10,0x10,0x12,0x14,0x18,0x11,0x2,0x20,0x20,0x20,0x40,0x7e,0x82,0x24,0x20,0x20,0x20,0x50,0x50,0x90,0x88,0xe,0x4,
-+0x0,0x0,0x3f,0x4,0x4,0xff,0x4,0x4,0x3f,0x4,0x4,0x8,0x8,0x10,0x20,0x40,0x0,0x10,0xf8,0x10,0x14,0xfe,0x10,0x10,0xf0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x7f,0x1,0x1,0x1,0x3f,0x20,0x20,0x41,0x7f,0x1,0x1,0x1,0x11,0xa,0x4,0x8,0x88,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x88,0x8,0x8,0x8,0x8,0x8,0x8,
-+0x0,0x78,0x48,0x51,0x52,0x67,0x50,0x4b,0x48,0x4b,0x68,0x52,0x42,0x46,0x4a,0x41,0x80,0x80,0xf0,0x10,0x24,0xfe,0x4,0xfc,0x4,0xfc,0x4,0x80,0x60,0x2c,0xa,0xf8,
-+0x6,0x78,0x40,0x40,0x40,0x44,0x7e,0x40,0x40,0x40,0x40,0x4e,0x70,0x0,0x0,0x0,0x4,0xfe,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0xa8,0x90,0x80,0x80,0x80,
-+0x8,0x8,0x7f,0x8,0x1,0x1f,0x11,0x11,0x11,0xff,0x1,0x2,0x2,0x4,0x18,0x60,0x20,0x28,0xfc,0x20,0x10,0xf8,0x10,0x10,0x14,0xfe,0x0,0x80,0x80,0x60,0x1c,0x8,
-+0x10,0x17,0x14,0x15,0xfd,0x16,0x3b,0x34,0x50,0x5f,0x90,0x11,0x10,0x10,0x11,0x16,0x0,0xbc,0xa4,0xac,0xac,0xb4,0x18,0xa4,0x80,0xfe,0x90,0x10,0xa0,0x40,0xb0,0x8,
-+0x0,0x3e,0x22,0x2a,0x2a,0x2a,0x14,0x62,0x2,0xff,0x4,0x8,0x4,0x3,0x4,0x38,0x8,0xfc,0x88,0xa8,0xa8,0xa8,0x50,0x88,0x4,0xfe,0x20,0x20,0x40,0x80,0x60,0x10,
-+0x0,0x3f,0x22,0x24,0x2c,0x35,0x24,0x24,0x21,0x27,0x24,0x24,0x47,0x40,0x9f,0x0,0x80,0xfe,0x50,0x7c,0xd0,0x7c,0x50,0x5c,0x0,0xf0,0x90,0x20,0xfc,0x4,0xe4,0xc,
-+0x1,0x0,0x3f,0x20,0x21,0x28,0x24,0x24,0x22,0x22,0x22,0x22,0x40,0x40,0x9f,0x0,0x0,0x84,0xfe,0x0,0x4,0x84,0x84,0x48,0x48,0x48,0x10,0x10,0x20,0x44,0xfe,0x0,
-+0x10,0x17,0x24,0x25,0x45,0xfe,0x13,0x24,0x40,0xff,0x0,0x1,0x1c,0xe0,0x41,0x6,0x0,0xbc,0xa4,0xac,0xac,0xb4,0x18,0xa4,0x80,0xfe,0x90,0x10,0xa0,0x40,0xb0,0x8,
-+0x4,0x4,0x7f,0x4,0x4,0x7f,0x40,0xbf,0x1,0x1,0x3f,0x1,0x1,0x1,0xff,0x0,0x40,0x48,0xfc,0x40,0x40,0xfe,0x2,0xf4,0x0,0x10,0xf8,0x0,0x40,0x24,0xfe,0x0,
-+0x4,0x4,0x7f,0x4,0x4,0x7f,0x41,0x81,0x1f,0x11,0x11,0x1f,0x1,0x1,0x3f,0x0,0x40,0x48,0xfc,0x40,0x40,0xfe,0x2,0x14,0xf8,0x10,0x10,0xf0,0x0,0x10,0xf8,0x8,
-+0x4,0x4,0x7f,0x4,0x7f,0x40,0x8f,0x8,0x8,0xf,0x0,0x1f,0x10,0x10,0x1f,0x10,0x40,0x48,0xfc,0x40,0xfe,0x2,0xe4,0x20,0x20,0xe0,0x0,0xf0,0x10,0x10,0xf0,0x10,
-+0x4,0x4,0x7f,0x4,0x4,0x7f,0x41,0x81,0x9,0x9,0x11,0x2,0x2,0x4,0x18,0x60,0x40,0x48,0xfc,0x40,0x40,0xfe,0x2,0x14,0x30,0x40,0x0,0x80,0x40,0x30,0xe,0x4,
-+0x10,0x10,0x14,0x7e,0x54,0x54,0x55,0x55,0x55,0x7d,0x11,0x15,0x1d,0xf4,0x40,0x0,0x8,0xfc,0x88,0x88,0xf8,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0x22,0x1e,
-+0x0,0x41,0x26,0x14,0x4,0x4,0xf4,0x14,0x15,0x16,0x14,0x10,0x10,0x28,0x47,0x0,0x0,0x84,0x7e,0x44,0x44,0x44,0x44,0xc4,0x44,0x54,0x48,0x40,0x40,0x46,0xfc,0x0,
-+0x1,0xff,0x10,0x1f,0x0,0x1f,0x10,0x1f,0x0,0x77,0x54,0x75,0x55,0x71,0x52,0xb4,0x0,0xfe,0x0,0xf0,0x0,0xf0,0x10,0xf0,0x0,0xdc,0x54,0x54,0x5c,0x14,0x96,0x62,
-+0x0,0x7f,0x10,0x17,0x14,0x12,0x21,0x22,0x44,0x0,0x3f,0x24,0x24,0x24,0xff,0x0,0x10,0xf8,0x10,0xd0,0x7c,0x84,0x4,0xd4,0x48,0x0,0xf8,0x48,0x48,0x48,0xfe,0x0,
-+0x0,0x3f,0x20,0x3f,0x20,0x3f,0x4,0xff,0x0,0x3f,0x20,0x3f,0x15,0x24,0x54,0x8,0x84,0xc4,0x88,0x90,0xa0,0x84,0x4,0xe8,0x10,0xa2,0x82,0x84,0x8,0x90,0xa0,0x40,
-+0x40,0x4b,0x70,0x40,0x45,0x3d,0x1,0x1d,0xf1,0x15,0xff,0x11,0x38,0x54,0x91,0x16,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x20,0x58,0x84,0x2,
-+0x4,0xff,0x10,0x10,0x21,0x25,0x7f,0xa5,0x25,0x25,0x25,0x24,0x3d,0x24,0x0,0x3,0x4,0xfe,0x20,0x24,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0xa0,0x60,0x9e,0x4,
-+0x0,0x8,0x7c,0x4b,0x4a,0x4a,0x4a,0x7a,0x4a,0x4f,0x48,0x48,0x78,0x49,0x2,0xc,0x40,0x40,0x48,0xfc,0x48,0x48,0x48,0x48,0x48,0xfe,0x40,0xa0,0xa0,0x10,0xe,0x4,
-+0x0,0x11,0x79,0x52,0x52,0x54,0x5f,0x52,0x54,0x5f,0x50,0x71,0x4e,0x4,0x0,0x0,0x20,0x20,0x24,0x3e,0x44,0x84,0x4,0x44,0x24,0xa4,0x4,0x84,0x4,0x44,0x28,0x10,
-+0x20,0x27,0x24,0x24,0xfc,0x27,0x2c,0x34,0x64,0xa7,0x24,0x24,0x28,0x28,0xb0,0x40,0x4,0xfe,0x44,0x44,0x44,0xfc,0x44,0x44,0x44,0xfc,0x44,0x44,0x44,0x44,0x54,0x8,
-+0x10,0x17,0x14,0x24,0x24,0x67,0xa4,0x24,0x24,0x27,0x24,0x24,0x28,0x28,0x30,0x20,0x4,0xfe,0x44,0x44,0x44,0xfc,0x44,0x44,0x44,0xfc,0x44,0x44,0x44,0x44,0x54,0x8,
-+0x0,0x78,0x4f,0x49,0x4a,0x7a,0x4f,0x49,0x4a,0x7c,0x4f,0x48,0x48,0x49,0x4a,0x9c,0x40,0x24,0xfe,0x10,0x28,0xbe,0x68,0x28,0xbe,0xa8,0xa8,0xbe,0xa8,0x28,0x3e,0x20,
-+0x0,0x0,0x1f,0x10,0x97,0x54,0x54,0x17,0x34,0x54,0xd7,0x14,0x24,0x24,0x48,0x10,0x80,0x44,0xfe,0x0,0xfc,0x44,0x44,0xfc,0x44,0x44,0xfc,0x44,0x44,0x44,0x54,0x8,
-+0x0,0x3f,0x20,0x2f,0x20,0x3f,0x20,0x2f,0x20,0x2f,0x28,0x2f,0x48,0x4f,0x88,0x8,0x84,0xfe,0x80,0xf8,0x88,0xfe,0x88,0xf8,0x80,0xf8,0x88,0xf8,0x88,0xf8,0x88,0x98,
-+0x1,0x0,0xff,0x8,0x10,0x21,0x49,0xfb,0x11,0x25,0x45,0xf9,0x9,0x11,0x21,0x41,0x0,0x84,0xfe,0xa0,0x94,0xfe,0x10,0x10,0xfc,0x10,0x10,0xfc,0x10,0x14,0xfe,0x0,
-+0x0,0x7d,0x44,0x44,0x44,0x7d,0x11,0x11,0x5d,0x51,0x51,0x51,0x5d,0xf1,0x41,0x1,0x0,0xfc,0x8,0x50,0x24,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x24,0x24,0x24,0xc,
-+0x10,0x11,0x10,0x14,0x7e,0x55,0x55,0x55,0x55,0x7d,0x51,0x15,0x1d,0xf5,0x41,0x1,0x0,0xfc,0x8,0x50,0x24,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x24,0x24,0x24,0xc,
-+0x0,0x8,0x7c,0x4b,0x48,0x48,0x4f,0x48,0x49,0x49,0x4a,0x7a,0x44,0x8,0x1,0x0,0x80,0x40,0x0,0xc0,0x44,0x4c,0xf0,0xe0,0x50,0x50,0x48,0x4e,0x44,0x40,0x40,0x80,
-+0x0,0x40,0x30,0x13,0x80,0x60,0x27,0x8,0x11,0x21,0xe2,0x22,0x24,0x28,0x21,0x20,0x80,0x40,0x0,0xc0,0x44,0x4c,0xf0,0xe0,0x50,0x50,0x48,0x4e,0x44,0x40,0x40,0x80,
-+0x0,0x47,0x30,0x10,0x80,0x67,0x24,0xc,0x17,0x24,0xe4,0x27,0x24,0x24,0x24,0x24,0x0,0xf8,0x10,0xa0,0x44,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x44,0x44,0x54,0x8,
-+0x2,0x1,0x0,0x1f,0x1,0x1,0x7d,0x5,0x5,0x9,0x9,0x11,0x21,0x41,0x5,0x2,0x0,0x0,0x0,0x0,0x8,0x18,0xa0,0x40,0x40,0x20,0x20,0x10,0xe,0x4,0x0,0x0,
-+0x3f,0x2,0x1,0x3f,0x21,0x3f,0x21,0x3f,0x21,0x21,0x2,0x51,0x50,0x90,0xf,0x0,0xf0,0x40,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x18,0x0,0x84,0x92,0x12,0xf0,0x0,
-+0x3f,0x2,0x1,0x3f,0x21,0x3f,0x21,0x3f,0x21,0x21,0x7f,0x2,0x2,0x4,0x18,0x60,0xf0,0x40,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x10,0xf8,0x8,0x8,0x8,0x50,0x20,
-+0x0,0x3f,0x21,0x21,0x21,0x3f,0x21,0x21,0x21,0x3f,0x21,0x21,0x21,0x41,0x41,0x80,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0x28,0x10,
-+0x1,0x1,0x9,0x49,0x49,0x51,0x53,0x7d,0x45,0x49,0x55,0x7f,0x43,0x41,0x7f,0x40,0x0,0x0,0x20,0x24,0x24,0x44,0x4c,0xf4,0x14,0x24,0x54,0xfc,0xc,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x20,0x20,0x7f,0xa1,0x21,0x21,0x22,0x22,0x22,0x24,0x24,0x28,0x30,0x80,0xa0,0x90,0x90,0x84,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x8,0x8,0x10,0x15,0x36,0x54,0x94,0x14,0x14,0x11,0x2,0x51,0x50,0x90,0xf,0x0,0x80,0x84,0xfe,0x8,0x88,0x50,0x20,0x50,0x8e,0x4,0x0,0x84,0x92,0x12,0xf0,0x0,
-+0x10,0x10,0x10,0x10,0x58,0x57,0x51,0x91,0x11,0x11,0x12,0x12,0x12,0x14,0x14,0x18,0x80,0xa0,0x90,0x90,0x84,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x1,0x1,0x1,0x1,0x1,0xff,0x2,0x2,0x2,0x4,0x4,0x8,0x8,0x10,0x20,0x40,0x0,0x40,0x20,0x20,0x4,0xfe,0x80,0x80,0x80,0x80,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x1,0x1,0x1,0x1,0x7f,0x41,0x41,0x41,0x41,0x7f,0x41,0x41,0x41,0x41,0x7f,0x40,0x0,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x8,0x8,0x9,0x7f,0x49,0x49,0x49,0x49,0x7f,0x49,0x49,0x49,0x49,0x7f,0x41,0x0,0x0,0x0,0x7c,0xc4,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x10,0x10,0x10,0x1d,0x21,0x21,0x7d,0x91,0x11,0x7d,0x11,0x11,0x15,0x19,0x11,0x0,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0x24,0xfc,0x4,0x0,
-+0x0,0x44,0x2c,0x10,0x28,0x4f,0x89,0x9,0x19,0x29,0x49,0x8a,0xa,0xa,0x54,0x28,0x80,0xa0,0x90,0x90,0x84,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x0,0x40,0x30,0x10,0x87,0x64,0x24,0xc,0x14,0x27,0xe4,0x24,0x24,0x24,0x27,0x24,0x40,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0xfc,0x44,0x44,0x44,0x44,0xfc,0x4,
-+0x2,0x41,0x20,0x2f,0x82,0x62,0x23,0x2,0x12,0x22,0xe2,0x24,0x24,0x28,0x31,0x20,0x10,0x14,0x1e,0xe0,0x40,0x3e,0x84,0x88,0x88,0xfe,0x88,0x88,0x88,0x88,0xa8,0x10,
-+0x0,0xff,0x4,0x4,0x3f,0x24,0x24,0x24,0x24,0x28,0x30,0x2f,0x20,0x20,0x3f,0x20,0x4,0xfe,0x40,0x48,0xfc,0x48,0x48,0x48,0x78,0x8,0x48,0xe8,0x8,0x8,0xf8,0x8,
-+0x2,0x2,0xff,0x4,0x4,0xf,0x8,0x18,0x2f,0x48,0x88,0xf,0x8,0x8,0x8,0x8,0x0,0x4,0xfe,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,0x10,0x50,0x20,
-+0x4,0x4,0x4,0xff,0x4,0x4,0xf,0x8,0x14,0x12,0x21,0x40,0x81,0x6,0x18,0x60,0x0,0x0,0x4,0xfe,0x0,0x0,0xf0,0x10,0x20,0x20,0x40,0x80,0x40,0x30,0xe,0x4,
-+0x2,0x2,0x2,0xff,0x4,0x4,0x8,0x8,0x1f,0x28,0x48,0x88,0x8,0x8,0xf,0x8,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x8,0x8,0x8,0x10,0x1f,0x31,0x51,0x92,0x13,0x15,0x19,0x11,0x11,0x11,0x11,0x11,0x80,0x80,0x80,0x84,0xfe,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x4,0xe,0xf0,0x12,0x57,0x39,0x11,0xff,0x11,0x39,0x35,0x55,0x91,0x11,0x11,0x11,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0x24,0xfc,0x4,
-+0x0,0x47,0x20,0x20,0xf,0x1,0xe2,0x24,0x2b,0x21,0x21,0x21,0x2a,0x32,0x24,0x8,0x38,0xc0,0x40,0x44,0xfe,0x60,0x50,0x4e,0xf4,0x10,0x20,0x3c,0x4,0x4,0x28,0x10,
-+0x0,0x7f,0x10,0x10,0x10,0x8,0x8,0x4,0x4,0x2,0x1,0x2,0x4,0x8,0x30,0xc0,0x0,0xf0,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x0,0x80,0x40,0x30,0xe,0x4,
-+0x0,0x10,0x10,0x10,0x20,0x25,0x44,0xf8,0x10,0x10,0x20,0x48,0xfc,0x45,0x2,0x4,0x40,0x40,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x4,0x28,0x10,
-+0x0,0x43,0x30,0x10,0x0,0x7,0xf0,0x10,0x10,0x10,0x10,0x11,0x10,0x28,0x47,0x0,0x10,0xf8,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x6,0xfc,0x0,
-+0x4,0x42,0x22,0x3f,0x84,0x44,0x47,0xd,0x15,0x25,0xe5,0x25,0x25,0x29,0x35,0x22,0x10,0x10,0x90,0xd0,0x28,0x28,0x44,0x82,0x20,0x18,0x8,0x0,0x20,0x18,0xc,0x4,
-+0x0,0x3f,0x1,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x5,0x2,0x10,0xf8,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x3f,0x1,0x1,0xff,0x1,0x1,0x5,0x2,0x3f,0x24,0x24,0x24,0x24,0xff,0x0,0x10,0xf8,0x0,0x4,0xfe,0x0,0x0,0x0,0x8,0xfc,0x48,0x48,0x48,0x48,0xfe,0x0,
-+0x10,0x10,0x10,0x11,0xfe,0x14,0x33,0x3a,0x56,0x53,0x92,0x12,0x13,0x12,0x12,0x12,0x40,0x60,0x90,0x8,0xf6,0x0,0xc4,0x54,0x54,0xd4,0x54,0x54,0xc4,0x44,0x54,0xc8,
-+0x1,0x1,0x3f,0x20,0x2f,0x20,0x27,0x24,0x27,0x20,0x2f,0x20,0x5f,0x41,0x86,0x18,0xf8,0x0,0xfe,0x84,0xf0,0x84,0xfc,0x10,0xf0,0x80,0xf8,0x80,0xfe,0x40,0x30,0xc,
-+0x0,0x1f,0x11,0x1f,0x11,0x1f,0x1,0x3f,0x21,0x22,0x27,0x22,0x51,0x50,0x90,0xf,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x8,0xfc,0x8,0x48,0xe8,0x10,0x84,0x92,0x12,0xf0,
-+0x1,0x9,0x31,0x27,0x22,0x3d,0x27,0x21,0x39,0x27,0x21,0xff,0x0,0x10,0x30,0x40,0x0,0x8,0x3c,0xc8,0x8,0x38,0xc8,0x8,0x38,0xc8,0x8,0xfe,0x0,0x10,0xc,0x4,
-+0x1,0x1,0x2,0x4,0x8,0x10,0x2f,0xc1,0x1,0x3f,0x1,0x9,0x19,0x21,0x45,0x2,0x0,0x0,0x80,0x40,0x20,0x10,0xee,0x4,0x10,0xf8,0x0,0x20,0x18,0xc,0x4,0x0,
-+0x1,0x2,0x4,0x8,0x37,0xc0,0x3e,0x22,0x22,0x3e,0x22,0x22,0x3e,0x22,0x22,0x26,0x0,0x80,0x40,0x30,0xce,0x4,0x8,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x8,0x18,
-+0x0,0x41,0x22,0x24,0xb,0x10,0xe7,0x24,0x27,0x24,0x27,0x24,0x25,0x50,0x8f,0x0,0x80,0x40,0x20,0x10,0xee,0x4,0x88,0xa8,0xa8,0xa8,0xa8,0x88,0x98,0x6,0xfc,0x0,
-+0x4,0x4,0xf,0x10,0x20,0x7f,0xa1,0x21,0x3f,0x21,0x21,0x3f,0x20,0x0,0xff,0x0,0x0,0x0,0xe0,0x40,0x88,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x4,0xfe,0x0,
-+0x20,0x20,0x21,0x22,0xb5,0xa8,0xa7,0x24,0x24,0x27,0x24,0x24,0x27,0x24,0x24,0x25,0x40,0xc0,0x20,0x10,0xee,0x4,0x88,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0x88,0xa8,0x90,
-+0x0,0x40,0x31,0x12,0x85,0x68,0x27,0xc,0x14,0x27,0xe4,0x24,0x27,0x24,0x24,0x25,0x40,0xc0,0x20,0x10,0xee,0x4,0x88,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0x88,0xa8,0x90,
-+0x1,0x41,0x31,0x12,0x84,0x6f,0x24,0xc,0x17,0x24,0xe4,0x27,0x24,0x20,0x2f,0x20,0x0,0x0,0xf8,0x10,0x24,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x4,0x0,0xfe,0x0,
-+0x0,0x7b,0x4a,0x52,0x53,0x62,0x52,0x4b,0x48,0x4f,0x6c,0x54,0x45,0x44,0x44,0x44,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x44,0xfe,0x44,0x54,0xf4,0x84,0x14,0x8,
-+0x0,0x3f,0x0,0x2,0x1,0x0,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x5,0x2,0x0,0xf0,0x40,0x80,0x0,0x80,0xfc,0x4,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x11,0x11,0x11,0xfd,0x25,0x24,0x25,0x24,0x44,0x2f,0x10,0x28,0x45,0x82,0x4,0x8,0xfc,0x8,0x8,0xf8,0x8,0x0,0xf8,0x40,0x44,0xfe,0x40,0xa0,0x10,0xe,0x4,
-+0x0,0xff,0x1,0x1,0x3f,0x21,0x21,0x29,0x25,0x21,0x21,0x29,0x25,0x21,0x21,0x20,0x4,0xfe,0x0,0x8,0xfc,0x8,0x8,0x48,0x28,0x8,0x8,0x48,0x28,0x8,0x28,0x10,
-+0x10,0x10,0x10,0x1f,0x10,0x10,0x10,0x1f,0x0,0x0,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x8,0xfc,0x8,0x8,0x48,0xe8,0x8,0x8,0x50,0x20,
-+0x10,0x10,0x10,0x10,0x54,0x54,0x54,0x54,0x54,0x54,0x57,0x7c,0x44,0x0,0x0,0x0,0x80,0x80,0x88,0xfc,0x80,0x80,0x84,0xfe,0x4,0x24,0xf4,0x4,0x4,0x4,0x28,0x10,
-+0x0,0x0,0x7f,0x1,0x3f,0x21,0x21,0x3f,0x1,0x7f,0x41,0x41,0x5f,0x48,0x40,0x40,0x10,0x78,0x80,0x8,0xfc,0x8,0x8,0xf8,0x4,0xfe,0x4,0x44,0xe4,0x24,0x4,0xc,
-+0x2,0x1,0x7f,0x40,0x80,0x1f,0x1,0x1,0x7f,0x1,0x1,0x1,0x1,0x1,0x5,0x2,0x0,0x0,0xfe,0x2,0x24,0xf0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x4f,0x21,0x21,0x7,0x2,0xe2,0x3f,0x20,0x20,0x27,0x24,0x2c,0x34,0x27,0x4,0x8,0xfc,0x0,0x10,0xf8,0x10,0x14,0xfe,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x7e,0x2,0x2,0x22,0x12,0x12,0x2,0xa,0x12,0x62,0x22,0x2,0x2,0x14,0x8,0x4,0xfe,0x4,0x4,0x44,0x24,0x24,0x4,0x14,0x24,0xc4,0x44,0x4,0x4,0x28,0x10,
-+0x0,0x7f,0x1,0x1,0x1,0x1,0x1,0x3f,0x1,0x1,0x1,0x1,0x1,0x1,0xff,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x40,0x30,0x10,0x4,0xfe,0x0,
-+0x20,0x20,0x20,0x27,0xf8,0x20,0x27,0x24,0x24,0x24,0x3f,0xe0,0x43,0xc,0x0,0x1,0x20,0x28,0x24,0xfe,0x20,0xa0,0xe0,0xa4,0xa4,0xa8,0x90,0x10,0xaa,0x4a,0x86,0x0,
-+0x8,0x8,0xff,0x8,0x0,0x3f,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x5,0x2,0x20,0x24,0xfe,0x20,0x10,0xf8,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x11,0xff,0x20,0x22,0x7f,0x62,0xa2,0x3e,0x22,0x22,0x3e,0x22,0x22,0x2a,0x24,0x0,0x7c,0xc4,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x0,0xb,0x7c,0x48,0x48,0x48,0x4f,0x48,0x48,0x48,0x48,0x78,0x48,0x0,0x1,0x0,0x8,0xfc,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,
-+0x0,0x47,0x24,0x27,0x4,0x7,0xe0,0x2f,0x28,0x28,0x2b,0x28,0x28,0x50,0x88,0x7,0x8,0xfc,0x88,0xf8,0x88,0xf8,0x84,0xfe,0x84,0xa4,0xf4,0x4,0x14,0x8,0x6,0xfc,
-+0x0,0x10,0x79,0x52,0x55,0x58,0x57,0x54,0x54,0x57,0x54,0x74,0x57,0x4,0x4,0x5,0x40,0xc0,0x20,0x10,0xee,0x4,0x88,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0x88,0xa8,0x90,
-+0x10,0x10,0x10,0x55,0x54,0x54,0x54,0x55,0x56,0x55,0x55,0x7d,0x45,0x1,0x1,0x1,0x50,0x50,0x88,0x24,0x50,0x50,0x88,0x6,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x14,0x14,0x27,0x4a,0x82,0x12,0x2f,0x62,0xaa,0x2b,0x2a,0x2a,0x2b,0x3c,0x28,0x20,0x0,0x4,0xbe,0x24,0x24,0xa4,0xe4,0x24,0x24,0xa4,0x24,0x34,0xa8,0x20,0x20,0x20,
-+0x1,0x2,0x4,0xf,0x30,0xde,0x12,0x1e,0x12,0x1e,0x12,0x16,0x29,0x28,0x48,0x7,0x0,0x80,0x40,0xf0,0xe,0x14,0x90,0x90,0x90,0x90,0x10,0x30,0x4,0x92,0x12,0xf0,
-+0x28,0x28,0x44,0x92,0x10,0x29,0x46,0x82,0x7c,0x44,0x44,0x44,0x44,0x7c,0x45,0x2,0x40,0x40,0x40,0x7c,0x84,0x28,0x20,0x20,0x20,0x20,0x50,0x50,0x90,0x88,0xe,0x4,
-+0x4,0x88,0x54,0x22,0x52,0x91,0x1e,0x12,0x32,0x52,0x92,0x13,0x12,0x10,0xa1,0x42,0x20,0x20,0x30,0x28,0x20,0xfe,0x20,0x20,0x20,0x20,0xd0,0x50,0x88,0x88,0x6,0x4,
-+0x2,0x1,0xff,0x4,0x8,0x3f,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x10,0x10,0x0,0x4,0xfe,0x0,0x10,0xf8,0x8,0xf0,0x10,0xf0,0x10,0xf0,0x10,0x10,0x50,0x20,
-+0x22,0x11,0x9,0xff,0x4,0x9,0x1f,0x20,0xdf,0x0,0x1f,0x0,0x1f,0x10,0x1f,0x10,0x8,0x10,0x24,0xfe,0x40,0x20,0xf0,0xe,0xf4,0x0,0xf0,0x0,0xf0,0x10,0xf0,0x10,
-+0x1,0x41,0x32,0x14,0x80,0x60,0x20,0x9,0x12,0x27,0xea,0x22,0x22,0x22,0x23,0x22,0x10,0x10,0x8,0x44,0x40,0xa0,0xa0,0x10,0x8,0xfe,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x2,0x1,0x7f,0x40,0x9f,0x11,0x1f,0x11,0x1f,0x1,0x3f,0x21,0x21,0x2f,0x20,0x20,0x0,0x0,0xfe,0x2,0xf4,0x10,0xf0,0x10,0xf0,0x8,0xfc,0x8,0x28,0xe8,0x28,0x10,
-+0x21,0x11,0x12,0xfc,0x8,0x10,0x10,0x35,0x5a,0x97,0x12,0x12,0x12,0x12,0x13,0x12,0x10,0x10,0x8,0x44,0x40,0xa0,0xa0,0x10,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x7d,0x4,0x8,0x29,0x11,0xff,0x15,0x11,0x11,0x11,0x11,0x11,0x10,0x50,0x23,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x58,0x84,0x2,
-+0x0,0x7c,0x4,0x9,0x2b,0x11,0xff,0x15,0x10,0x11,0x12,0x11,0x16,0x10,0x53,0x20,0x40,0x78,0x90,0x24,0xfe,0x24,0x44,0xfc,0x84,0x48,0xb0,0x30,0x68,0xa6,0x24,0x60,
-+0x4,0x7e,0x5,0x24,0x24,0x24,0x24,0x24,0x3e,0x2,0x2,0x1e,0xe2,0x42,0x14,0xb,0x0,0x0,0xfc,0x4,0x4,0x84,0x84,0x88,0x88,0x50,0x20,0x50,0x50,0x88,0x8e,0x4,
-+0x10,0x1e,0x22,0x52,0x14,0x8,0x12,0xef,0xa,0x8,0x8,0xf,0x0,0x7f,0x0,0x0,0x8,0xfc,0x88,0xa8,0x98,0x82,0x7e,0xe0,0x20,0xa0,0x48,0xfc,0x8,0xe8,0x8,0x18,
-+0x0,0x44,0x36,0x15,0x85,0x64,0x27,0x4,0xc,0x14,0x25,0xe5,0x26,0x24,0x28,0x30,0x4,0x44,0x4c,0x54,0x64,0x44,0xfc,0x44,0xc4,0xe4,0x5c,0x4c,0x44,0x44,0x44,0x4,
-+0x0,0x7f,0x44,0x87,0x8,0x10,0x3f,0x51,0x11,0x1f,0x12,0x2,0x4,0x8,0x10,0x60,0x0,0xfe,0x2,0xe4,0x40,0x90,0xf8,0x10,0x10,0xf0,0x90,0x80,0xa2,0x92,0x7e,0x0,
-+0x0,0x3f,0x0,0x0,0x0,0xff,0x4,0x4,0x4,0x4,0x4,0x8,0x8,0x10,0x20,0xc0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x10,0x13,0x10,0x10,0xfd,0x11,0x11,0x11,0x11,0x11,0x11,0x1d,0xf1,0x40,0x7,0x0,0x4,0xfe,0x0,0x4,0xfe,0x4,0x4,0xfc,0x4,0x4,0x4,0xfc,0x4,0x0,0xfe,0x0,
-+0x1,0x1,0x3f,0x1,0xff,0x0,0x1f,0x10,0x10,0x1f,0x5,0x8,0x18,0xea,0xc,0x8,0x0,0x10,0xf8,0x0,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x8,0x90,0x60,0x30,0xe,0x4,
-+0x0,0x3f,0x21,0x21,0x22,0x2f,0x28,0x2f,0x28,0x2f,0x20,0x24,0x44,0x48,0x92,0x1,0x8,0xfc,0x0,0x0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x80,0x90,0x88,0x84,0x84,0x0,
-+0x10,0x17,0x12,0x11,0xff,0x10,0x10,0x1f,0x30,0xd1,0x11,0x12,0x12,0x14,0x59,0x22,0x1c,0xe8,0x48,0x50,0xfc,0x80,0x84,0xfe,0x80,0xf8,0x8,0x90,0x60,0x90,0xe,0x4,
-+0x10,0x10,0x23,0xfc,0x27,0x40,0x93,0xfe,0x12,0x13,0x1d,0xf1,0x53,0x15,0x11,0x11,0x40,0x48,0xfc,0x40,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x44,0x28,0x10,0x4e,0x84,0x0,
-+0x0,0x7f,0x40,0x4f,0x40,0x40,0x5f,0x44,0x44,0x44,0x44,0x48,0x50,0x40,0x7f,0x40,0x4,0xfe,0x44,0xe4,0x4,0x24,0xf4,0x84,0x84,0x84,0x94,0x94,0x74,0x4,0xfc,0x4,
-+0x0,0x1f,0x10,0x10,0x1f,0x0,0x3f,0x20,0x21,0x21,0x21,0x21,0x22,0x4,0x18,0x60,0x10,0xf8,0x10,0x10,0xf0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0x8,0x60,0x18,0x4,
-+0x0,0x7f,0x40,0x4f,0x48,0x4f,0x40,0x5f,0x50,0x51,0x51,0x52,0x44,0x48,0x7f,0x40,0x4,0xfe,0x4,0xe4,0x24,0xe4,0x4,0xf4,0x14,0x14,0x14,0x94,0x44,0x24,0xfc,0x4,
-+0x2,0x44,0x2b,0x10,0x2f,0x48,0x8b,0xa,0x1a,0x2b,0x49,0x89,0xb,0xd,0x51,0x21,0x40,0x48,0xfc,0x40,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x44,0x28,0x10,0x4e,0x84,0x0,
-+0x0,0x47,0x34,0x14,0x84,0x65,0x25,0xd,0x15,0x25,0xe4,0x24,0x29,0x2a,0x30,0x20,0x4,0xfe,0x20,0x20,0x44,0xfe,0x4,0xfc,0x4,0xfc,0x20,0xa8,0xa6,0x22,0xa0,0x40,
-+0x10,0x10,0x21,0x23,0x48,0xff,0x10,0x21,0x42,0xfc,0x1,0x2,0x1c,0xe1,0x46,0x0,0x80,0xf8,0x8,0xf0,0x14,0xfe,0x80,0x88,0x50,0xe0,0x60,0x50,0xc8,0x4e,0x44,0xc0,
-+0x0,0x43,0x30,0x10,0x0,0x7,0xf1,0x11,0x11,0x11,0x12,0x12,0x14,0x28,0x47,0x0,0x10,0xf8,0x0,0x0,0x8,0xfc,0x20,0x20,0x20,0x24,0x24,0x1c,0x0,0x6,0xfc,0x0,
-+0x4,0x4,0xff,0x4,0x10,0x1e,0x12,0x22,0x22,0x64,0x94,0x8,0x8,0x10,0x20,0x40,0x40,0x44,0xfe,0x40,0x8,0xfc,0x88,0x88,0x88,0x88,0xa8,0x90,0x82,0x82,0x7e,0x0,
-+0x0,0x3f,0x21,0x22,0x2f,0x28,0x2f,0x28,0x2f,0x20,0x44,0x89,0x9,0x28,0x28,0x47,0x8,0xfc,0x0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x80,0x90,0x88,0x0,0x94,0x12,0xf2,
-+0x10,0x1e,0x12,0x22,0x22,0x54,0x8c,0x8,0x10,0x20,0x42,0x11,0x51,0x50,0x8f,0x0,0x8,0xfc,0x88,0x88,0x88,0xa8,0x90,0x84,0x84,0x7c,0x0,0x0,0x14,0x12,0xf2,0x0,
-+0x0,0x78,0x4f,0x54,0x58,0x63,0x50,0x48,0x4f,0x48,0x68,0x50,0x41,0x41,0x42,0x4c,0x80,0x40,0xfe,0x2,0x14,0xf8,0x0,0x8,0xfc,0xa0,0xa0,0xa0,0x22,0x22,0x1e,0x0,
-+0x0,0x0,0x7f,0x40,0x40,0x40,0x40,0x7f,0x40,0x40,0x40,0x40,0x7f,0x40,0x0,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,0x0,0x0,
-+0x10,0x10,0x20,0x21,0x45,0xfa,0x14,0x20,0x40,0xfc,0x0,0x0,0x1c,0xe0,0x40,0x0,0x80,0x80,0x80,0x4,0xfe,0x4,0x4,0x84,0x64,0x24,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x10,0x10,0x10,0x7d,0x11,0x11,0xff,0x11,0x51,0x5d,0x51,0x50,0x70,0x49,0x44,0x83,0x20,0x28,0x28,0xfc,0x20,0x20,0x28,0x28,0x70,0xa0,0x24,0x54,0x8c,0x0,0x6,0xfc,
-+0x0,0x7c,0x47,0x44,0x44,0x7c,0x10,0x13,0x5c,0x50,0x50,0x51,0x5d,0xf2,0x44,0x8,0x8,0x1c,0xe0,0x40,0x40,0x40,0x44,0xfe,0x40,0xa0,0xa0,0x10,0x10,0x8,0xe,0x4,
-+0x10,0x11,0x11,0x1d,0x21,0x21,0x7d,0x91,0x11,0xfd,0x11,0x11,0x15,0x19,0x12,0x4,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0x28,0x10,
-+0x0,0x1f,0x10,0x10,0x1f,0x10,0x10,0x10,0xff,0x1,0x11,0x11,0x11,0x11,0x1f,0x10,0xf0,0x0,0x0,0x10,0xf8,0x80,0x80,0x84,0xfe,0x0,0x10,0x10,0x10,0x10,0xf0,0x10,
-+0x2,0x1f,0x15,0x11,0x1f,0x11,0x15,0x1f,0x0,0xff,0x4,0xf,0x0,0x0,0x0,0x0,0x10,0xf8,0x50,0x10,0xf0,0x10,0x50,0xf0,0x4,0xfe,0x0,0xf0,0x10,0x10,0xa0,0x40,
-+0x0,0xf,0x8,0x8,0x8,0xf,0x8,0x8,0x8,0xf,0x8,0x8,0x10,0x10,0x20,0x40,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,0x10,0x10,0xf0,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x12,0x11,0x10,0x13,0x5a,0x56,0x52,0x92,0x13,0x11,0x11,0x11,0x12,0x12,0x14,0x18,0x8,0x18,0xa0,0xf8,0x8,0x8,0x8,0x8,0xf8,0x20,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x20,0x17,0x50,0x44,0x42,0x4f,0x48,0x48,0x4f,0x4a,0x42,0x42,0x44,0x48,0x50,0x40,0x4,0xfe,0x4,0x44,0x84,0xe4,0x24,0x24,0xe4,0xa4,0x84,0x94,0x94,0x74,0x4,0xc,
-+0x8,0x8,0x7e,0x8,0x8,0x7e,0x9,0x8,0xfe,0x18,0x1c,0x2a,0x28,0x49,0x8,0x8,0x0,0x8,0xfc,0x0,0x0,0x4,0xfe,0x20,0x20,0x40,0x40,0x88,0x84,0xfc,0x4,0x0,
-+0x0,0x0,0x1f,0x0,0x0,0x0,0xff,0x2,0x2,0x4,0x4,0x8,0x8,0x10,0x3f,0x0,0x0,0x20,0xf0,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x20,0x10,0xf8,0x8,
-+0x2,0x3f,0x22,0x22,0x3e,0x1,0x7f,0x41,0x49,0x49,0x49,0x49,0x14,0x12,0x21,0x41,0x0,0x7c,0x44,0x48,0x48,0x50,0xc8,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,0x40,
-+0x8,0x8,0xf,0x10,0x10,0x26,0x43,0x81,0x0,0x0,0x3,0x1c,0x8,0x0,0x0,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0x24,0xc4,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x0,0x7c,0x44,0x48,0x48,0x50,0x49,0x49,0x45,0x45,0x45,0x69,0x50,0x40,0x40,0x43,0x8,0xfc,0x88,0x88,0xf8,0x4,0xfe,0x4,0x24,0x24,0x24,0x24,0x50,0x48,0x84,0x4,
-+0x2,0x2,0x4,0x8,0x10,0x7f,0x4,0x4,0x4,0x4,0x8,0x8,0x10,0x10,0x20,0xc0,0x0,0x0,0x40,0x20,0x10,0xf8,0x88,0x80,0x80,0x80,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x0,0x43,0x30,0x10,0x0,0x7,0xf0,0x10,0x11,0x11,0x12,0x17,0x10,0x28,0x47,0x0,0x10,0xf8,0x0,0x0,0x8,0xfc,0x80,0x80,0x0,0x20,0x10,0xf8,0x8,0x6,0xfc,0x0,
-+0x4,0x4,0xff,0x4,0x11,0x21,0x45,0x79,0x11,0x20,0x7f,0x2,0x1e,0xe2,0x47,0x0,0x40,0x44,0xfe,0x48,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfc,0x94,0x94,0x94,0xfe,0x0,
-+0x1,0xff,0x14,0x14,0x7f,0x55,0x55,0x55,0x53,0x61,0x41,0x7f,0x41,0x41,0x7f,0x41,0x0,0x88,0x7c,0x0,0x0,0x4,0xfe,0x10,0x10,0x10,0x20,0x20,0x44,0xfe,0x2,0x0,
-+0x1f,0x10,0x1f,0x10,0x1f,0x0,0x7f,0x42,0x9f,0x4,0x9,0x1f,0x1,0x7f,0x1,0x1,0xf0,0x10,0xf0,0x10,0xf0,0x0,0xfe,0x2,0xf4,0x0,0x0,0xf0,0x0,0xfc,0x0,0x0,
-+0x10,0x8,0x7f,0x0,0x22,0x14,0xff,0x2,0x3f,0x22,0x22,0x3e,0x22,0x22,0x3e,0x22,0x20,0x20,0x24,0x7e,0x84,0x4,0x44,0x24,0x24,0xc,0x34,0xc4,0x4,0x4,0x28,0x10,
-+0x0,0x3f,0x8,0x8,0x8,0x10,0x1f,0x20,0x40,0x1,0xff,0x1,0x1,0x1,0x5,0x2,0x20,0xf0,0x20,0x24,0x7e,0x4,0xc4,0x54,0x88,0x0,0xfe,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x3f,0x20,0x20,0x20,0x2f,0x28,0x28,0x28,0x28,0x28,0x28,0x20,0x20,0x3f,0x0,0x8,0xfc,0x80,0x80,0x88,0xfc,0x88,0x88,0x88,0x88,0xa8,0x90,0x80,0x84,0xfe,0x0,
-+0x8,0xfd,0x11,0x11,0x21,0x25,0x7f,0xa5,0x25,0x25,0x25,0x25,0x3d,0x25,0x1,0x0,0x4,0xfe,0x10,0x10,0x7c,0x54,0x54,0x54,0x54,0x54,0x54,0x5c,0x10,0x14,0xfe,0x0,
-+0x4,0x4,0x3f,0x4,0x4,0x8,0x8,0x11,0x21,0x1,0xff,0x1,0x9,0x11,0x25,0x2,0x0,0x20,0xf0,0x20,0x20,0x24,0x24,0x1c,0x0,0x4,0xfe,0x0,0x20,0x18,0x8,0x0,
-+0x8,0xa,0x7f,0x8,0x8,0xff,0x8,0xa,0x7f,0x8,0x1c,0x1a,0x2a,0x48,0x89,0xa,0x40,0x50,0x48,0x48,0x40,0xfe,0x40,0x40,0x48,0x48,0x30,0x20,0x60,0x92,0xa,0x6,
-+0x8,0x8,0xa,0x7f,0x8,0x8,0xff,0x2,0x3f,0x22,0x22,0x22,0x22,0x3e,0x21,0x2,0x40,0x60,0x58,0x48,0x40,0x44,0xfe,0x40,0x48,0x48,0x30,0x20,0x60,0x92,0xa,0x6,
-+0x2,0x1,0x7f,0x40,0x81,0x1,0x11,0x11,0x11,0x21,0x2,0x2,0x4,0x8,0x10,0x60,0x0,0x0,0xfe,0x2,0x4,0x0,0x10,0x18,0x20,0x40,0x80,0x80,0x40,0x30,0xe,0x4,
-+0x2,0x1,0x7f,0x42,0x81,0x3f,0x8,0x4,0x2,0xff,0x1,0x1,0x3f,0x1,0x1,0x1,0x0,0x0,0xfe,0x2,0x14,0xf8,0x20,0x40,0x84,0xfe,0x0,0x10,0xf8,0x0,0x0,0x0,
-+0x8,0xa,0x7f,0x8,0x8,0xff,0x10,0xff,0x20,0x28,0x7e,0x8,0xf,0xf8,0x9,0xa,0x40,0x50,0x48,0x48,0x40,0xfe,0x40,0x40,0x48,0x48,0x30,0x20,0x60,0x92,0xa,0x6,
-+0x0,0x7f,0x1,0x1,0x1f,0x11,0x11,0x1f,0x11,0x11,0xff,0x10,0x10,0x10,0x10,0x10,0x8,0xfc,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x14,0xfe,0x10,0x10,0x10,0x50,0x20,
-+0x2,0x2,0x2,0xff,0x4,0x4,0x8,0x8,0x13,0x30,0x50,0x90,0x10,0x10,0x17,0x10,0x0,0x0,0x4,0xfe,0x0,0x40,0x40,0x50,0xf8,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x0,0x8,0x7d,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x79,0x49,0x1,0x1,0x1,0x20,0x44,0xfe,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x22,0x2a,0x2f,0x32,0xff,0x25,0x25,0x29,0x33,0xe2,0x22,0x22,0x22,0x20,0xa3,0x4c,0x8,0x28,0xbe,0x48,0xfe,0x14,0x14,0xa6,0xf8,0x8,0x48,0x48,0x48,0xa0,0x18,0x4,
-+0x10,0x7e,0x10,0x28,0x7e,0x8,0xfe,0x9,0xa,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0xc,0xf0,0x80,0x84,0xfe,0x90,0x90,0x10,0x10,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,
-+0x8,0x28,0x3e,0x48,0xff,0x14,0x16,0x24,0x40,0x1f,0x10,0x11,0x11,0x12,0xc,0x30,0x10,0x50,0x7c,0x90,0xfe,0x28,0x28,0x4a,0x86,0xf0,0x10,0x10,0x10,0x90,0x60,0x18,
-+0x4,0x7e,0x45,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x29,0x45,0x82,0x20,0x14,0xfe,0x0,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x0,
-+0x4,0x3e,0x25,0x25,0x25,0x3d,0x25,0x25,0x25,0x3d,0x25,0x25,0x25,0x45,0x95,0xa,0x20,0x14,0xfe,0x0,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x0,
-+0x4,0xff,0x4,0x7f,0x10,0x1e,0x22,0x54,0x8,0x70,0x4,0xff,0x4,0x4,0x8,0x10,0x44,0xfe,0x40,0xfc,0x80,0x98,0xe0,0x84,0x84,0x7c,0x40,0xfe,0x40,0x40,0x40,0x40,
-+0x0,0x4f,0x30,0x17,0x4,0x7,0xf4,0x17,0x10,0x13,0x12,0x13,0x12,0x13,0x28,0x47,0xa4,0xfe,0xa0,0xfc,0xa4,0xfc,0xa4,0xfc,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x6,0xfc,
-+0x20,0x20,0xaf,0x70,0x27,0x24,0xff,0x24,0x77,0x68,0xa3,0x22,0x23,0x22,0x23,0x22,0xa0,0xa4,0xfe,0xa0,0xfc,0xa4,0xfc,0xa4,0xfc,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,
-+0x4,0x24,0x14,0x4,0xff,0x0,0x4,0x22,0x2f,0x21,0x21,0x2f,0x21,0x21,0x3f,0x20,0x40,0x48,0x50,0x44,0xfe,0x0,0x40,0x88,0xe8,0x8,0x48,0xe8,0x8,0x8,0xf8,0x8,
-+0x4,0xff,0x4,0x23,0x1a,0x8b,0x40,0x4f,0x14,0x27,0xe0,0x2f,0x20,0x21,0x22,0x24,0x44,0xfe,0x40,0xf8,0x8,0xf8,0x0,0xbc,0xa4,0xbc,0x40,0xfe,0xe0,0x50,0x4e,0x44,
-+0x1,0x1,0xff,0x1,0x3f,0x21,0x23,0x25,0x9,0x30,0xc7,0x0,0x0,0xe,0x1,0x0,0x0,0x4,0xfe,0x0,0xf8,0x8,0x88,0x50,0x30,0xe,0x4,0xc0,0x40,0x0,0xc0,0x40,
-+0x0,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x11,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,
-+0x3,0x42,0x32,0x13,0x80,0x67,0x24,0xc,0x17,0x20,0xef,0x20,0x21,0x22,0x24,0x28,0xf8,0x8,0x8,0xf8,0x0,0xbc,0xa4,0xa4,0xbc,0x40,0xfe,0xe0,0x50,0x4e,0x44,0x40,
-+0x3f,0x0,0x11,0x9,0x4,0x3,0xd,0x11,0x7f,0x91,0x11,0x1f,0x1,0x1,0x3f,0x10,0xf8,0x8,0x10,0x20,0x40,0x80,0x60,0x10,0xfe,0x14,0x10,0xf0,0x20,0xf0,0x8,0x8,
-+0x4,0x7e,0x44,0x44,0x44,0x7d,0x11,0x51,0x5d,0x50,0x53,0x50,0x5c,0xf1,0x42,0x0,0xf8,0x88,0x88,0xf8,0x0,0xdc,0x54,0x54,0xdc,0x20,0xfe,0x70,0xa8,0x2e,0x24,0x20,
-+0x3,0x12,0x7a,0x53,0x50,0x57,0x54,0x54,0x57,0x50,0x5f,0x70,0x51,0x2,0x4,0x0,0xf8,0x8,0x8,0xf8,0x0,0xbc,0xa4,0xa4,0xbc,0x40,0xfe,0xe0,0x50,0x4e,0x44,0x40,
-+0x0,0x42,0x32,0x13,0x4,0x0,0xf7,0x10,0x13,0x12,0x12,0x12,0x13,0x28,0x47,0x0,0x40,0x40,0x50,0xf8,0x40,0x44,0xfe,0x8,0xfc,0x8,0x8,0x8,0xf8,0x6,0xfc,0x0,
-+0x2,0x4,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x1,0x1,0xff,0x1,0x1,0x1,0x0,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x4,0xfe,0x0,0x0,0x4,0x4,0xfc,
-+0x10,0x10,0x10,0x12,0x54,0x58,0x53,0x90,0x10,0x10,0x10,0x28,0x24,0x44,0x87,0x0,0x40,0x40,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x10,0x10,0x10,0x12,0x54,0x59,0x51,0x91,0x11,0x10,0x13,0x28,0x24,0x45,0x82,0x0,0xf8,0x88,0x88,0xf8,0x0,0xdc,0x54,0x54,0xdc,0x20,0xfe,0x70,0xa8,0x2e,0x24,0x20,
-+0x1,0x1,0x3f,0x1,0x1f,0x1,0xff,0x0,0x1f,0x10,0x11,0x11,0x12,0x2,0xc,0x30,0x0,0x10,0xf8,0x0,0xf0,0x4,0xfe,0x10,0xf8,0x10,0x10,0x10,0x10,0xc0,0x30,0x8,
-+0x10,0x13,0x11,0x10,0xfc,0x10,0x15,0x1a,0x35,0xd0,0x10,0x17,0x10,0x10,0x50,0x20,0x0,0xf8,0x10,0xa0,0x40,0xa0,0x10,0x4e,0xf4,0x40,0x48,0xfc,0x40,0x40,0x40,0x40,
-+0x1,0x7f,0x41,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x14,0x12,0x21,0xc1,0x4,0x84,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x4,0x4,0x4,0x14,0x8,
-+0x40,0x33,0x11,0x0,0x80,0x60,0x21,0xa,0x15,0x20,0xe0,0x27,0x20,0x20,0x20,0x20,0x0,0xf8,0x10,0xa0,0x40,0xa0,0x10,0x4e,0xf4,0x40,0x40,0xfc,0x40,0x40,0x40,0x40,
-+0x4,0x7e,0x44,0x54,0x57,0x54,0x54,0x54,0x57,0x54,0x54,0x54,0x29,0x25,0x42,0x84,0x20,0x28,0x24,0x20,0xfe,0xa0,0xa0,0x94,0xf4,0x98,0x98,0x90,0x28,0x2a,0x4a,0x86,
-+0x8,0x8,0xf,0x14,0x24,0x47,0x4,0x4,0x7,0x4,0x4,0x52,0x51,0x90,0xf,0x0,0x0,0x8,0xfc,0x0,0x20,0xf0,0x0,0x20,0xf0,0x0,0x0,0x4,0x92,0x92,0xf0,0x0,
-+0x22,0x21,0x20,0x20,0x27,0xfc,0x25,0x24,0x27,0x20,0x3b,0xe2,0x43,0x2,0x3,0x2,0x8,0x10,0xa0,0x4,0xfe,0x44,0x54,0x44,0xfc,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,
-+0x12,0x11,0x10,0x10,0x5f,0x54,0x55,0x94,0x17,0x10,0x13,0x12,0x13,0x12,0x13,0x12,0x8,0x10,0xa0,0x4,0xfe,0x44,0x54,0x44,0xfc,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,
-+0x10,0x8,0x4,0x0,0x3f,0x21,0x29,0x21,0x3f,0x0,0xf,0x8,0xf,0x8,0xf,0x8,0x10,0x20,0x40,0x8,0xfc,0x8,0x28,0x8,0xf8,0x20,0xf0,0x20,0xe0,0x20,0xe0,0x20,
-+0x1,0x7c,0x44,0x54,0x55,0x55,0x55,0x55,0x55,0x54,0x54,0x54,0x20,0x28,0x44,0x80,0x4,0x88,0x50,0x4,0xfe,0x24,0xac,0x24,0xfc,0x8,0xfc,0x88,0xf8,0x88,0xf8,0x88,
-+0x8,0x8,0x8,0xa,0xff,0x8,0xa,0xc,0x38,0xc8,0x8,0x8,0x8,0x8,0x28,0x10,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x0,0x8,0x7c,0x4f,0x48,0x49,0x4a,0x4c,0x4b,0x4a,0x4b,0x7a,0x4b,0x0,0xf,0x0,0x40,0x40,0x48,0xfc,0xe0,0x50,0x4e,0x44,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xfe,0x0,
-+0x0,0x40,0x30,0x17,0x80,0x61,0x22,0xc,0x13,0x22,0xe3,0x22,0x23,0x20,0x2f,0x20,0x40,0x40,0x48,0xfc,0xe0,0x50,0x4e,0x44,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xfe,0x0,
-+0x8,0x8,0x8,0x8,0xff,0x8,0x18,0x1c,0x2a,0x28,0x48,0x8,0x8,0x8,0x8,0x8,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x10,0x10,0x12,0xff,0x20,0x28,0x4a,0x7f,0x8,0x8,0xf,0xf8,0x48,0x8,0x8,0x8,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x20,0x27,0x3c,0x45,0x85,0x7d,0x25,0x25,0xfd,0x25,0x25,0x21,0x2a,0x32,0x24,0x8,0x44,0xe4,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x14,0x84,0x44,0x54,0x8,
-+0x20,0x1b,0x48,0x40,0x4f,0x49,0x49,0x4f,0x49,0x49,0x4f,0x49,0x41,0x41,0x41,0x40,0x4,0xfe,0x4,0x24,0xf4,0x24,0x24,0xe4,0x24,0x24,0xe4,0x24,0x4,0x4,0x14,0x8,
-+0x8,0x7c,0x4b,0x48,0x48,0x78,0x4b,0x48,0x48,0x78,0x48,0x49,0x4e,0x7d,0x48,0x0,0xc,0x30,0xc0,0x80,0x40,0x40,0xf8,0x10,0x20,0x40,0x80,0x0,0x0,0x6,0xfc,0x0,
-+0x20,0x27,0x24,0x24,0xfc,0x24,0x74,0x6f,0xa4,0x24,0x24,0x24,0x24,0x29,0x30,0x20,0x4,0xbe,0xa4,0xa4,0xa4,0xa4,0xa4,0xfe,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0x54,0x88,
-+0x10,0x10,0x13,0x12,0xfd,0x10,0x38,0x35,0x52,0x54,0x90,0x10,0x10,0x10,0x10,0x10,0x40,0x20,0xfe,0x8a,0x4,0x40,0xfe,0x80,0x88,0xfc,0x80,0x84,0xfe,0x80,0x80,0x80,
-+0x1,0x9,0x7d,0x49,0x4a,0x4a,0x4c,0x48,0x48,0x48,0x48,0x78,0x48,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x80,0x80,0x88,0xfc,0x80,0x80,0x84,0xfe,0x80,0x80,0x80,0x80,
-+0x8,0x8,0xf,0x12,0x12,0x22,0x43,0x82,0x2,0x2,0x3,0x2,0x2,0x2,0x2,0x2,0x0,0x4,0xfe,0x0,0x0,0x10,0xf8,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,
-+0x11,0x11,0x11,0x15,0x5a,0x52,0x54,0x90,0x10,0x10,0x10,0x28,0x24,0x44,0x80,0x0,0x0,0x0,0x4,0xfe,0x80,0x80,0x88,0xfc,0x80,0x80,0x84,0xfe,0x80,0x80,0x80,0x80,
-+0x1,0x41,0x31,0x11,0x2,0x2,0xf4,0x10,0x10,0x10,0x10,0x10,0x14,0x18,0x10,0x0,0x0,0x0,0x4,0xfe,0x80,0x80,0x88,0xfc,0x80,0x80,0x84,0xfe,0x80,0x80,0x80,0x80,
-+0x10,0x10,0x17,0x11,0xf8,0x17,0x14,0x1c,0x37,0xd4,0x15,0x15,0x15,0x15,0x55,0x24,0x80,0x44,0xfe,0x10,0xa4,0xfe,0x44,0x44,0xfc,0x44,0xf4,0x14,0x14,0xf4,0x14,0x8,
-+0x2,0x1,0xff,0x8,0x4,0x3,0x1c,0xe0,0x1f,0x2,0x4,0x3f,0x24,0x24,0x24,0x20,0x0,0x4,0xfe,0x20,0x40,0x80,0x70,0xe,0xf0,0x0,0x8,0xfc,0x48,0x48,0x48,0x18,
-+0x2,0x1,0x7f,0x40,0x80,0x3,0x3e,0x2,0x3,0x7e,0x2,0x2,0x2,0x2,0x1,0x0,0x0,0x0,0xfe,0x2,0x34,0xc0,0x0,0x8,0xfc,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x2,0x1,0x7f,0x48,0x94,0x4,0xb,0x12,0x22,0x43,0x2,0x2,0x3,0x2,0x2,0x2,0x0,0x0,0xfe,0x22,0x14,0x0,0xfc,0x0,0x20,0xf0,0x0,0x10,0xf8,0x0,0x0,0x0,
-+0x8,0xf,0x8,0x13,0x10,0x3f,0x50,0x93,0x12,0x12,0x12,0x12,0x12,0x10,0x11,0x16,0x40,0xfc,0x40,0xf8,0x40,0xfe,0x8,0xfc,0x8,0x48,0x48,0x48,0x48,0xb0,0x8,0x4,
-+0x2,0x1,0x7f,0x44,0xbf,0x4,0x1f,0x4,0xff,0x4,0x9,0x3f,0xc5,0x9,0x15,0x2,0x0,0x0,0xfe,0x42,0xfc,0x40,0xf0,0x44,0xfe,0x40,0x20,0xf8,0x46,0x30,0x10,0x0,
-+0x8,0x7c,0x49,0x4b,0x4a,0x7b,0x4b,0x4a,0x4a,0x7a,0x4a,0x4a,0x4a,0x7a,0x44,0x8,0x80,0xf8,0x10,0xfe,0x88,0x24,0xfe,0x0,0xfc,0x0,0xfc,0x0,0xfc,0x84,0xfc,0x84,
-+0x4,0xe,0xf0,0x10,0x14,0x1e,0x70,0x14,0x1f,0xf1,0x11,0x11,0x11,0x11,0xf,0x0,0x40,0x40,0x40,0x48,0x7c,0x40,0x40,0x48,0xfc,0x8,0x8,0x8,0xfa,0xa,0xfe,0x0,
-+0x10,0x1f,0x20,0x7f,0xa5,0x28,0x3f,0x20,0x27,0x20,0x27,0x20,0x47,0x44,0x87,0x4,0x0,0xf0,0x44,0xfe,0x10,0x88,0xfe,0x0,0xf8,0x0,0xf8,0x8,0xfc,0x8,0xf8,0x8,
-+0x8,0x8,0x49,0x2a,0x8,0xff,0x8,0x18,0x1d,0x2b,0x29,0x49,0x89,0x9,0x9,0x8,0x20,0x20,0x24,0x3e,0x20,0x20,0x20,0x24,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x0,
-+0x0,0x40,0x30,0x10,0x80,0x60,0x20,0xf,0x14,0x24,0xe4,0x24,0x24,0x24,0x27,0x24,0x80,0x80,0x84,0xfe,0x80,0x80,0x88,0xfc,0x8,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x2,0x2,0x3,0x7e,0x3,0x7e,0x1,0x1,0xe,0x70,0x3f,0x24,0x24,0x24,0xff,0x0,0x40,0x20,0xf8,0x0,0xfc,0x20,0x40,0x82,0x62,0x1e,0xf8,0x48,0x48,0x48,0xfe,0x0,
-+0x10,0x10,0x14,0xfe,0x20,0x28,0x48,0x7e,0x8,0x8,0xe,0xf8,0x49,0x9,0xa,0x8,0x8,0x1c,0xe0,0x80,0x80,0x84,0xfe,0x90,0x90,0x90,0x90,0x90,0x10,0x10,0x10,0x10,
-+0x20,0x23,0x2a,0xff,0x42,0x52,0x93,0xfe,0x12,0x13,0x1e,0xf2,0x54,0x14,0x18,0x10,0x4,0xfe,0x4,0xfc,0x50,0x50,0xfc,0x50,0x54,0xfe,0xa4,0xa8,0x90,0x88,0xce,0x84,
-+0x1,0x21,0x3f,0x10,0x14,0xfe,0x20,0x48,0x7e,0x8,0xe,0xf8,0x49,0x9,0xa,0x8,0x0,0x8,0xf8,0x0,0x1c,0xe0,0x80,0x84,0xfe,0x90,0x90,0x90,0x10,0x10,0x10,0x10,
-+0x0,0x3f,0x20,0x3f,0x22,0x22,0x2f,0x22,0x22,0x3f,0x24,0x24,0x24,0x45,0x86,0x4,0x8,0xfc,0x8,0xf8,0x20,0x20,0xf8,0x20,0x24,0xfe,0x88,0x50,0x30,0xe,0x4,0x0,
-+0x8,0xff,0x8,0xfe,0x28,0x29,0x7e,0x54,0x54,0x54,0x6c,0x44,0x7c,0x45,0x7d,0x46,0x20,0xfe,0x20,0x90,0x90,0xfe,0x90,0xfc,0x90,0xfc,0x90,0xfe,0x0,0x54,0x52,0x2,
-+0x10,0x10,0x10,0x10,0xfc,0x13,0x30,0x38,0x57,0x50,0x10,0x10,0x10,0x11,0x16,0x10,0x80,0x90,0x88,0x80,0xf8,0x80,0x88,0xfc,0x80,0x48,0x50,0x20,0x60,0x92,0xa,0x6,
-+0x2,0x2,0x2,0x3,0x2,0x2,0x2,0x3f,0x20,0x20,0x20,0x20,0x20,0x20,0x3f,0x20,0x0,0x0,0x8,0xfc,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0xf0,0x10,
-+0x10,0x10,0x12,0x1f,0x10,0x13,0x10,0x7e,0x42,0x42,0x42,0x42,0x42,0x7e,0x41,0x2,0x40,0x50,0x48,0x48,0x7e,0xc0,0x40,0x40,0x48,0x28,0x30,0x20,0x50,0x92,0xa,0x6,
-+0x0,0x20,0x10,0x10,0xfe,0x0,0x44,0x44,0x25,0x25,0x29,0x9,0x1f,0xe1,0x41,0x1,0x40,0x40,0x44,0x7e,0x40,0x40,0x40,0x44,0xfe,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x1,0x41,0x37,0x11,0x81,0x61,0x21,0x9,0x11,0x2f,0xe4,0x25,0x26,0x24,0x27,0x20,0x10,0x10,0xfc,0x10,0xf0,0x10,0xf0,0x10,0x14,0xfe,0xa0,0x18,0x8,0x0,0xfc,0x0,
-+0x10,0x10,0x23,0x22,0x44,0xf8,0x13,0x20,0x40,0xfc,0x40,0x1,0x1d,0xe2,0x44,0x0,0x40,0x20,0xfe,0x2,0x4,0x0,0xfe,0x20,0xa8,0xbc,0xa0,0x20,0xa0,0x66,0x1c,0x0,
-+0x10,0x17,0x11,0x10,0xff,0x10,0x33,0x3a,0x57,0x52,0x93,0x10,0x1f,0x10,0x10,0x10,0x48,0xfc,0x10,0xa4,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x40,0xfe,0x40,0x40,0x40,
-+0x1,0x3f,0x8,0x4,0xff,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x1,0xff,0x1,0x1,0x1,0x0,0xf8,0x20,0x44,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x0,0x0,0x0,
-+0x4,0x7f,0x11,0xa,0xff,0x0,0x3f,0x20,0x3f,0x20,0x3f,0x4,0xff,0x4,0x4,0x4,0x4,0xc4,0x8,0x10,0xe0,0x84,0xc4,0x88,0x90,0xa2,0x82,0x4,0xe8,0x10,0x20,0xc0,
-+0x0,0x47,0x31,0x10,0x8f,0x60,0x23,0xa,0x13,0x22,0xe3,0x20,0x2f,0x20,0x20,0x20,0x40,0xfc,0x10,0xa4,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x40,0xfe,0x40,0x40,0x40,
-+0x9,0xfd,0x9,0x9,0x9,0x79,0x41,0x47,0x41,0x79,0x9,0x9,0x9,0x9,0x51,0x21,0x0,0x8,0x8,0x10,0x20,0x40,0x4,0xfe,0x40,0x40,0x20,0x20,0x10,0x4e,0x84,0x0,
-+0x11,0x9,0x7f,0x40,0x9f,0x10,0x1f,0x0,0x7f,0x1,0x3f,0x1,0xff,0x1,0x5,0x2,0x10,0x20,0xfe,0x2,0xf4,0x10,0xf0,0x38,0xc0,0x0,0xf8,0x0,0xfe,0x0,0x0,0x0,
-+0x40,0x2f,0x21,0x1,0x81,0x4f,0x48,0x8,0x18,0x2f,0xe1,0x21,0x21,0x21,0x2a,0x24,0x40,0x40,0x44,0x44,0x48,0x50,0x44,0xfe,0x50,0x50,0x50,0x48,0x48,0x44,0x62,0x40,
-+0x10,0x10,0x10,0x10,0xff,0x10,0x31,0x39,0x54,0x50,0x90,0x10,0x10,0x10,0x11,0x16,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0xa0,0xa0,0xa0,0x40,0x60,0x90,0xe,0x4,
-+0x0,0x0,0x0,0x0,0xff,0x0,0x8,0x8,0x4,0x4,0x2,0x1,0x2,0x4,0x18,0xe0,0x80,0x80,0x80,0x84,0xfe,0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x80,0x60,0x1e,0x4,
-+0x10,0x10,0x14,0x7e,0x54,0x54,0x54,0x57,0x54,0x54,0x54,0x5c,0x10,0x10,0x10,0x10,0x80,0x84,0x84,0x88,0x90,0xa0,0x84,0xfe,0xa0,0xa0,0x90,0x90,0x88,0x8e,0xc4,0x80,
-+0x4,0x7e,0x44,0x54,0x54,0x54,0x54,0x57,0x54,0x54,0x54,0x54,0x10,0x28,0x44,0x80,0x80,0x84,0x84,0x88,0x90,0xa0,0x84,0xfe,0xa0,0xa0,0x90,0x90,0x88,0x8e,0xc4,0x80,
-+0x8,0x8,0x8,0x10,0x17,0x30,0x51,0x91,0x10,0x10,0x10,0x10,0x10,0x10,0x11,0x16,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0xa0,0xa0,0xa0,0x40,0x60,0x90,0xe,0x4,
-+0x4,0x3e,0x24,0x24,0x24,0x3c,0x24,0x27,0x24,0x3c,0x24,0x24,0x24,0x44,0x94,0x8,0x80,0x84,0x84,0x88,0x90,0xa0,0x84,0xfe,0xa0,0xa0,0x90,0x90,0x88,0x8e,0xc4,0x80,
-+0x0,0x1f,0x10,0x97,0x51,0x5f,0x10,0x17,0x34,0x57,0x94,0x17,0x20,0x2f,0x40,0x0,0x80,0xfe,0x40,0xfc,0x10,0xfe,0x0,0xfc,0x4,0xfc,0x4,0xfc,0x40,0xfe,0x40,0x40,
-+0x0,0x7b,0x49,0x50,0x57,0x60,0x53,0x4a,0x4b,0x4a,0x6b,0x50,0x4f,0x40,0x40,0x40,0x40,0xf8,0x10,0xa4,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x40,0xfe,0x40,0x40,0x40,
-+0x10,0x13,0x10,0x10,0xfc,0x10,0x15,0x19,0x32,0xd5,0x11,0x11,0x11,0x11,0x51,0x21,0x4,0xfe,0x84,0x84,0x84,0x84,0x14,0x8,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0xb,0x7c,0x48,0x48,0x48,0x49,0x79,0x4a,0x4d,0x49,0x49,0x79,0x49,0x1,0x1,0x4,0xfe,0x84,0x84,0x84,0x84,0x14,0x8,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x10,0xfc,0x13,0x10,0x1c,0x30,0xd0,0x10,0x10,0x11,0x12,0x54,0x20,0x80,0xa0,0x90,0x84,0x9e,0xe0,0x80,0x88,0x50,0x60,0x40,0xc0,0x20,0x12,0xa,0x6,
-+0x40,0x33,0x10,0x0,0x80,0x60,0x21,0x9,0x12,0x25,0xe1,0x21,0x21,0x21,0x21,0x21,0x4,0xfe,0x84,0x84,0x84,0x84,0x14,0x8,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x8,0x8,0x8,0x7e,0x8,0xa,0xff,0x8,0x28,0x2e,0x28,0x39,0x48,0x44,0x83,0x0,0x0,0x8,0x88,0x88,0x50,0x50,0x20,0x20,0x50,0x48,0x8c,0x4,0x0,0x6,0xfc,0x0,
-+0x0,0x7d,0x44,0x44,0x44,0x44,0x7d,0x44,0x44,0x44,0x44,0x7c,0x0,0x24,0x62,0x82,0x4,0xfe,0x44,0x44,0x84,0x94,0x8,0xfc,0x84,0x84,0x84,0xfc,0x0,0x88,0x46,0x42,
-+0x7f,0x44,0x7f,0x1,0x1,0x1,0x3f,0x20,0x3f,0x20,0x3f,0x1,0xff,0x1,0x1,0x1,0xfc,0x44,0xfc,0x0,0xfc,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xfe,0x0,0x0,0x0,
-+0x4,0x4,0x4,0x24,0x14,0x14,0x4,0x4,0x1c,0x64,0x4,0x8,0x8,0x10,0x20,0x40,0x80,0x80,0x80,0x90,0xa0,0xc0,0x80,0xc0,0xb0,0x90,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x8,0x3e,0x22,0x3e,0x21,0x5f,0x81,0xff,0x1,0x1f,0x1,0x3f,0x1,0xff,0x1,0x1,0x44,0x7e,0xa8,0x10,0x6e,0xf0,0x14,0xfe,0x10,0xf0,0x0,0xf8,0x0,0xfe,0x0,0x0,
-+0x0,0x3f,0x4,0x4,0x4,0x8,0x8,0x10,0x3f,0x50,0x10,0x10,0x10,0x10,0x1f,0x10,0x8,0xfc,0x8,0x8,0x8,0x28,0x10,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x40,0x27,0x24,0x4,0x7,0xe4,0x24,0x24,0x24,0x25,0x29,0x32,0x50,0x88,0x7,0x40,0x20,0xfc,0x90,0x94,0xfe,0x90,0x90,0xf0,0x0,0x54,0x52,0x52,0x0,0x6,0xfc,
-+0x10,0x10,0x11,0x11,0xfd,0x11,0x15,0x19,0x31,0xd1,0x11,0x11,0x12,0x12,0x54,0x20,0x8,0x3c,0xc0,0x0,0x0,0x4,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x8,0x8,0xfe,0x8,0xe,0x78,0x9,0x9,0x2a,0x10,0x1f,0x10,0x10,0x10,0x1f,0x10,0xc,0xf0,0x80,0x84,0xfe,0x90,0x10,0x10,0x10,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,
-+0x8,0x8,0xff,0x8,0xe,0x78,0x8,0x29,0x11,0x1f,0x11,0x11,0x1f,0x1,0x7f,0x0,0x40,0x48,0xfc,0x48,0xc8,0x48,0x6a,0x8a,0x6,0xf0,0x10,0x10,0xf0,0x4,0xfc,0x4,
-+0x22,0x21,0x27,0xfa,0x24,0x57,0x50,0xff,0x14,0x17,0x1c,0xf7,0x54,0x14,0x14,0x15,0x20,0x20,0xe4,0x3e,0xc4,0xa4,0xa4,0xa4,0xa4,0xa8,0x90,0x90,0xa8,0xa8,0xc6,0x84,
-+0x2,0x2,0x3f,0x2,0x2,0xff,0x2,0x4,0xf,0x18,0x28,0x4f,0x88,0x8,0xf,0x8,0x0,0x10,0xe0,0x40,0x84,0xfe,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x10,0x10,0x13,0x1c,0x20,0x23,0x7c,0x91,0x13,0xfd,0x11,0x11,0x15,0x19,0x11,0x1,0x40,0x44,0xf8,0x50,0x64,0xfe,0x80,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x8,0x8,0xff,0x9,0x0,0x3f,0x22,0x22,0x3f,0x22,0x22,0x23,0x40,0x49,0x89,0x10,0x20,0x24,0xfe,0x20,0x88,0xfc,0x20,0x28,0xfc,0x20,0x20,0xe0,0x0,0x24,0x22,0x2,
-+0x0,0x40,0x30,0x17,0x0,0x2,0xf1,0x10,0x10,0x10,0x10,0x11,0x12,0x28,0x47,0x0,0x80,0x40,0x48,0xfc,0x10,0x10,0x20,0xa0,0x40,0x40,0xa0,0x10,0x10,0x6,0xfc,0x0,
-+0x2,0x42,0x32,0x12,0x8f,0x62,0x22,0xa,0x13,0x2e,0xe2,0x22,0x22,0x22,0x2b,0x24,0x0,0xc,0x70,0x40,0xc0,0x44,0x7e,0xc8,0x48,0x48,0x48,0x48,0x48,0x88,0x8,0x8,
-+0x0,0x8,0xfc,0x10,0x11,0x12,0x14,0x7d,0x10,0x10,0x11,0x1c,0xf0,0x40,0x0,0x3,0x40,0x40,0xa0,0xa0,0x10,0x2e,0x44,0x80,0x10,0x60,0x84,0x8,0x10,0x20,0xc0,0x0,
-+0x22,0x22,0x7f,0x22,0x3e,0x22,0x3e,0x22,0x22,0xff,0x40,0x54,0x62,0x40,0x7f,0x0,0x8,0x8,0x48,0x28,0x8,0x88,0x48,0x8,0x8,0x8e,0xf8,0x8,0x8,0x8,0x8,0x8,
-+0x1,0x1,0x7f,0x1,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x1f,0x10,0xff,0x8,0x10,0x20,0x0,0x8,0xfc,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x14,0xfe,0x20,0x18,0x8,
-+0x2,0xff,0x14,0x15,0x7f,0x55,0x55,0x7f,0x49,0x8,0x7f,0x8,0x8,0xf,0x78,0x20,0x4,0xfe,0x40,0x40,0xc8,0x7c,0x48,0x48,0x68,0x58,0x58,0x88,0x88,0xaa,0xca,0x6,
-+0x4,0xfe,0x10,0x10,0x20,0x24,0x7e,0xa5,0x25,0x25,0x25,0x25,0x3d,0x25,0x1,0x1,0x40,0x40,0x44,0x7e,0x40,0x40,0x44,0xfe,0x4,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x8,0xfc,0x23,0x20,0x4b,0xfc,0x27,0x21,0xfa,0x25,0x20,0x3b,0xe1,0x42,0x4,0x0,0x40,0x48,0xfc,0x40,0xf8,0x80,0xfe,0x10,0xe,0xf4,0x40,0xf8,0x50,0x4c,0x44,0x40,
-+0x1,0x1,0x1,0x1,0x1,0x1f,0x10,0x11,0x11,0x11,0x11,0x11,0x2,0x4,0x18,0x60,0x0,0x8,0xfc,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0x40,0x30,0x8,0x4,
-+0x10,0x10,0x10,0x1e,0x20,0x20,0x7d,0x90,0x10,0xfe,0x10,0x12,0x14,0x18,0x10,0x0,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x8,0x8,0x8,0x10,0x10,0x37,0x54,0x94,0x14,0x14,0x14,0x14,0x10,0x11,0x16,0x18,0x40,0x44,0x7e,0x40,0x44,0xfe,0x4,0x44,0x44,0x44,0x44,0x44,0x90,0xc,0x6,0x2,
-+0x10,0x10,0x10,0x13,0xfe,0x14,0x30,0x38,0x54,0x50,0x90,0x10,0x11,0x11,0x12,0x14,0x40,0x40,0x40,0xfc,0x44,0x48,0x40,0x60,0x60,0xa0,0xa0,0xa0,0x22,0x22,0x1e,0x0,
-+0x1,0x0,0x1f,0x10,0x90,0x51,0x52,0x14,0x39,0x52,0xd4,0x11,0x22,0x20,0x43,0xc,0x0,0x88,0xfc,0x80,0x80,0x40,0x30,0x8e,0x24,0x40,0x80,0x10,0x20,0xc0,0x0,0x0,
-+0x0,0x40,0x20,0x21,0x2,0x4,0xe8,0x20,0x23,0x20,0x20,0x23,0x28,0x30,0x23,0xc,0x40,0x40,0xa0,0x20,0x10,0x2e,0x44,0x90,0x20,0x40,0x88,0x10,0x20,0xc0,0x0,0x0,
-+0x1f,0x1,0x7f,0x51,0x8d,0x11,0x3f,0x20,0x2f,0x20,0x3f,0x2a,0x29,0x48,0x8c,0x8,0xf0,0x0,0xfe,0x12,0x64,0x10,0xf8,0x0,0xf0,0x0,0xf8,0x10,0x20,0xc0,0x30,0xc,
-+0x10,0x13,0x12,0x12,0xff,0x12,0x16,0x1b,0x32,0xd2,0x12,0x12,0x14,0x14,0x58,0x20,0x4,0xfe,0x0,0x8,0xfc,0x0,0x4,0xfe,0xa0,0xa2,0xa4,0x98,0x90,0x8e,0xc4,0x80,
-+0x10,0x10,0x13,0x1c,0x21,0x21,0x7d,0x91,0x11,0xfd,0x11,0x11,0x17,0x18,0x11,0x2,0x20,0x24,0xfe,0x20,0xfc,0x4,0xfc,0x4,0xfc,0x4,0xfc,0x4,0xfe,0x88,0x6,0x2,
-+0x0,0x78,0x4f,0x50,0x50,0x61,0x51,0x4b,0x48,0x48,0x68,0x57,0x40,0x40,0x40,0x40,0x80,0x84,0xfe,0x80,0xa0,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x8,0x8,0xff,0x8,0x1f,0x0,0x3d,0x5,0x5,0x9,0x35,0xc2,0xf,0x20,0x24,0x42,0x20,0x24,0xfe,0x20,0xe0,0x48,0x98,0x20,0x40,0x30,0xe,0x4,0xe0,0x10,0x8c,0x44,
-+0x10,0x10,0x11,0x12,0xfc,0x13,0x14,0x18,0x37,0xd0,0x10,0x13,0x10,0x10,0x51,0x20,0x80,0x80,0xf8,0x10,0x20,0xf8,0x48,0x48,0xfe,0x48,0x48,0xf8,0x48,0x40,0x40,0x80,
-+0x8,0x7c,0x49,0x4a,0x48,0x7b,0x48,0x48,0x4f,0x78,0x48,0x4b,0x48,0x78,0x49,0x0,0x80,0x80,0xf8,0x10,0x20,0xf8,0x48,0x48,0xfe,0x48,0x48,0xf8,0x48,0x40,0x40,0x80,
-+0x8,0xb,0x10,0x10,0x20,0x48,0x88,0x12,0x32,0x52,0x92,0x12,0x12,0x12,0x1f,0x10,0x8,0xfc,0x40,0x40,0x40,0x40,0x48,0x7c,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x2,0x44,0x29,0x12,0x28,0x4b,0x88,0x8,0x1f,0x28,0x48,0x8b,0x8,0x8,0x29,0x10,0x80,0x80,0xf8,0x10,0x20,0xf8,0x48,0x48,0xfe,0x48,0x48,0xf8,0x48,0x40,0x40,0x80,
-+0x8,0xf,0x8,0x10,0x3f,0x41,0x1,0xff,0x1,0x1,0x3f,0x1,0x1,0x1,0x5,0x2,0x0,0xe0,0x40,0x90,0xf8,0x10,0x14,0xfe,0x10,0x10,0xf0,0x10,0x0,0x0,0x0,0x0,
-+0x10,0x17,0x10,0x10,0x58,0x54,0x50,0x92,0x12,0x12,0x12,0x12,0x12,0x12,0x1f,0x10,0x8,0xfc,0x40,0x40,0x40,0x40,0x48,0x7c,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x8,0x7f,0x8,0x7f,0x49,0x7f,0x1c,0x2a,0xc8,0x3f,0x1,0x9,0x9,0x9,0xff,0x0,0x40,0x44,0x7e,0x88,0x48,0x50,0x20,0x50,0x8e,0xf8,0x0,0xf0,0x0,0x4,0xfe,0x0,
-+0x10,0x13,0x10,0x10,0xfc,0x13,0x15,0x19,0x31,0xd2,0x14,0x10,0x11,0x10,0x5f,0x20,0x0,0xf8,0x10,0x20,0x44,0x48,0x70,0x50,0x50,0x4e,0x44,0x40,0x40,0x84,0xfe,0x0,
-+0x0,0x7f,0x1,0x1,0x1,0x1,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0xff,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x0,0x4,0xfe,0x10,0x10,0x11,0x5e,0x50,0x50,0x50,0x50,0x5e,0xf0,0x40,0x1,0x2,0x40,0x40,0x44,0xfe,0x88,0x8,0x88,0x88,0x50,0x50,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x10,0x10,0x10,0x7c,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x5d,0x11,0x10,0x10,0x13,0x20,0x24,0x3e,0x20,0xfc,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x58,0x84,0x2,
-+0x0,0x0,0x1f,0x10,0x90,0x57,0x50,0x10,0x32,0x52,0xd2,0x12,0x22,0x22,0x5f,0x0,0x80,0x48,0xfc,0x0,0x8,0xfc,0x40,0x40,0x48,0x7c,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x41,0x22,0x14,0x7f,0x8,0x8,0x9,0xff,0x8,0x8,0x8,0x14,0x12,0x22,0x40,0x0,0x0,0x7c,0x44,0x44,0x48,0x48,0x50,0xc8,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x20,0x17,0x10,0x0,0x0,0xf0,0x11,0x11,0x11,0x11,0x11,0x11,0x15,0x19,0x17,0x0,0x4,0xfe,0x20,0x20,0x20,0x20,0x24,0x3e,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x8,0x8,0xff,0x8,0x2,0x1,0x3f,0x0,0x0,0x3,0xc,0x10,0x60,0x90,0xf,0x0,0x20,0x24,0xfe,0x20,0x0,0x0,0xf0,0x20,0xc0,0x0,0x0,0x0,0x0,0x6,0xfc,0x0,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x31,0x39,0x54,0x50,0x90,0x10,0x10,0x10,0x11,0x16,0x20,0x20,0x24,0xfe,0x20,0x20,0xfc,0x4,0x88,0x88,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x1,0x1,0x1,0xff,0x1,0x1,0x3f,0x8,0x8,0x4,0x2,0x1,0x2,0xc,0x30,0xc0,0x0,0x0,0x4,0xfe,0x0,0x0,0xf0,0x20,0x20,0x40,0x80,0x0,0x80,0x60,0x1e,0x4,
-+0x0,0x8,0x7c,0x4b,0x48,0x48,0x49,0x49,0x48,0x48,0x48,0x78,0x48,0x0,0x1,0x6,0x20,0x20,0x24,0xfe,0x20,0x20,0xfc,0x4,0x88,0x88,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x22,0x22,0x22,0xfb,0xad,0xa9,0xa9,0xaf,0xf9,0xa1,0x29,0x39,0xea,0x42,0x4,0x8,0x0,0x0,0x4,0xfe,0x24,0x24,0x24,0xe4,0x24,0x24,0x24,0x24,0xbc,0x64,0x40,0x0,
-+0x20,0x20,0x22,0x3f,0x28,0x48,0x88,0x9,0xff,0x8,0x8,0x14,0x12,0x22,0x40,0x80,0x0,0x0,0x4,0x7e,0x44,0x44,0x44,0x44,0xc4,0x44,0x44,0x44,0x44,0x7c,0x44,0x0,
-+0x4,0x3e,0x24,0x27,0x24,0x3c,0x25,0x25,0x24,0x3c,0x24,0x24,0x24,0x44,0x95,0xa,0x20,0x20,0x24,0xfe,0x20,0x20,0xfc,0x4,0x88,0x88,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x5,0x3f,0x25,0x25,0x25,0x3d,0x24,0x24,0x25,0x3d,0x25,0x25,0x25,0x45,0x95,0x9,0x0,0x8,0x1c,0xe0,0x2,0x2,0xfe,0x4,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,
-+0x0,0x40,0x30,0x10,0x80,0x60,0x27,0x8,0x10,0x20,0xe0,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x2,0x1,0x1,0x0,0x7f,0x0,0x0,0x0,0x0,0x1,0x2,0xc,0x30,0x48,0x7,0x0,0x0,0x0,0x0,0x0,0xf8,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x6,0xfc,0x0,
-+0x10,0x10,0x21,0x21,0x45,0xf9,0x11,0x21,0x41,0xfd,0x40,0x0,0x1c,0xe0,0x41,0x2,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,0x0,0x50,0x48,0x84,0x2,0x2,
-+0x4,0xfe,0x24,0x24,0x3c,0x24,0x24,0x3c,0x24,0x24,0x27,0xfc,0x44,0x4,0x5,0x4,0x0,0x4,0xfe,0x84,0x84,0x84,0x84,0x84,0xfc,0x84,0x48,0x48,0x84,0x86,0x2,0x0,
-+0x1,0x1,0x7f,0x1,0x1,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0xff,0x0,0x0,0x8,0xfc,0x0,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x10,0x14,0xfe,0x0,
-+0x10,0x10,0x17,0x10,0xfc,0x13,0x32,0x3b,0x56,0x53,0x92,0x13,0x12,0x12,0x1f,0x10,0x40,0x48,0xfc,0x40,0x48,0xfc,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x8,0x8,0xfe,0x0,
-+0x4,0xfe,0x13,0x10,0x10,0x3d,0x25,0x45,0xa5,0x19,0x9,0x11,0x21,0x41,0x87,0x0,0x20,0x24,0xfe,0x20,0x24,0xfe,0x4,0xfc,0x4,0xfc,0x4,0xfc,0x4,0x4,0xfe,0x0,
-+0x10,0x10,0x10,0x10,0xff,0x10,0x14,0x18,0x31,0xd0,0x11,0x11,0x11,0x12,0x54,0x28,0x80,0x80,0x80,0x90,0xf8,0x90,0x90,0x90,0x90,0x90,0x50,0x52,0x12,0x12,0xe,0x0,
-+0x8,0x8,0xf,0x10,0x10,0x33,0x52,0x93,0x12,0x13,0x12,0x13,0x12,0x12,0x1f,0x10,0x40,0x48,0xfc,0x40,0x48,0xfc,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x8,0x8,0xfe,0x0,
-+0x8,0x8,0xf,0x10,0x11,0x32,0x57,0x90,0x10,0x10,0x17,0x10,0x10,0x10,0x1f,0x10,0x0,0x8,0xfc,0x80,0x0,0x8,0xfc,0x44,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x0,
-+0x10,0x10,0x10,0x15,0xff,0x11,0x11,0x11,0x11,0x11,0x11,0x13,0x1d,0xf1,0x47,0x0,0x20,0x20,0x20,0x20,0x24,0x3e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x11,0x11,0x11,0x11,0xfd,0x11,0x14,0x18,0x31,0xd1,0x11,0x11,0x11,0x11,0x51,0x21,0x0,0x8,0x1c,0xe0,0x2,0x2,0xfe,0x4,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,
-+0x1,0x1,0x1,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x4,0x7e,0x44,0x44,0x45,0x7d,0x11,0x51,0x5d,0x51,0x51,0x51,0x5d,0xf1,0x47,0x0,0x20,0x20,0x20,0x20,0x28,0x3c,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x0,0x0,0x1f,0x10,0x10,0x10,0x10,0x10,0x1f,0x10,0x0,0x4,0xc,0x10,0x20,0x40,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0xf0,0x10,0x0,0x40,0x20,0x18,0xc,0x4,
-+0x20,0x20,0x21,0x3e,0x20,0x20,0x1f,0x0,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x0,0x18,0xe0,0x0,0x4,0x4,0xfc,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x10,0x10,0x23,0x22,0x46,0xfa,0x12,0x23,0x42,0xfe,0x2,0x2,0x1e,0xe2,0x43,0x2,0x0,0x3c,0xe0,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x10,0x92,0xa,0x6,
-+0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x3f,0x0,0x2,0x11,0x50,0x50,0x90,0xf,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x10,0xf8,0x0,0x0,0x80,0x84,0x12,0x12,0xf0,0x0,
-+0x8,0x8,0x7e,0x8,0xe,0xf8,0x48,0x19,0x3f,0x1,0x1f,0x1,0xff,0x1,0x1,0x3,0x40,0x48,0xfc,0x48,0xc8,0x68,0x8a,0x36,0xc0,0x0,0xf0,0x4,0xfe,0x0,0x0,0x0,
-+0x28,0x25,0x20,0x2f,0xf2,0x22,0x22,0x2a,0x3f,0xe2,0x22,0x25,0x24,0x28,0xb0,0x40,0x80,0x7c,0x44,0xc4,0x48,0x48,0x50,0x48,0xc4,0x42,0x42,0x62,0xd4,0x48,0x40,0x40,
-+0x0,0x7f,0x2,0x4,0x8,0x10,0x3f,0x1,0x1,0x1,0x3f,0x1,0x1,0x1,0xff,0x0,0x8,0xfc,0x0,0x0,0x20,0x10,0xf8,0x8,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x0,
-+0x4,0xfe,0x10,0x10,0x20,0x45,0xfe,0x10,0x10,0x7c,0x10,0x10,0x1e,0xf0,0x41,0x6,0x40,0x40,0x40,0x44,0xfe,0x8,0x88,0x88,0x88,0x90,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x3f,0x24,0x3f,0x1,0x7f,0x1,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x1f,0x10,0xff,0x0,0xf8,0x48,0xf8,0x0,0xfc,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x14,0xfe,0x0,
-+0x10,0x10,0x15,0x7f,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0x5c,0x10,0x10,0x11,0x12,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,0x0,0x50,0x48,0x84,0x6,0x2,
-+0x10,0x10,0x11,0x54,0x54,0x57,0x54,0x54,0x57,0x54,0x54,0x54,0x7c,0x44,0x0,0x0,0x20,0x28,0xfc,0x20,0x24,0xfe,0x8,0x8,0xfe,0x8,0x88,0x48,0x48,0x8,0x28,0x10,
-+0x4,0x24,0x25,0x3f,0x24,0x44,0xff,0x4,0x3f,0x24,0x24,0x24,0x26,0x25,0x4,0x4,0x4,0x4,0x4,0xa4,0x24,0xa4,0xe4,0x24,0xa4,0xa4,0xa4,0x84,0x84,0x4,0x14,0x8,
-+0x20,0x22,0x3f,0x48,0x8,0xff,0x10,0x14,0x22,0x42,0x9f,0x10,0x1f,0x10,0x1f,0x10,0x0,0x4,0x7e,0x44,0x44,0xc4,0x44,0x7c,0x44,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,
-+0x8,0x1c,0xf2,0x12,0x13,0xfe,0x14,0x30,0x3b,0x54,0x50,0x90,0x11,0x11,0x12,0x1c,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x40,0xa0,0xa0,0x10,0x10,0xe,0x4,
-+0x8,0x1c,0xf0,0x11,0x13,0xfd,0x11,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x11,0x11,0xa0,0x90,0x84,0xfe,0x20,0x28,0xfc,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,0x0,
-+0x0,0x3f,0x20,0x20,0x3f,0x20,0x20,0x2f,0x28,0x28,0x28,0x28,0x49,0x42,0x8c,0x30,0x78,0x80,0x80,0x84,0xfe,0x80,0x88,0xfc,0x8,0x88,0x88,0x88,0x8,0x70,0xc,0x4,
-+0x4,0x4,0xf,0x11,0x28,0x44,0x3,0xc,0x71,0x9,0x9,0x12,0x4,0x8,0x30,0xc0,0x0,0x0,0xf8,0x10,0xa0,0xc0,0x0,0x0,0x10,0x30,0x40,0x80,0x40,0x30,0xe,0x4,
-+0x1,0x0,0x1f,0x10,0x90,0x57,0x50,0x10,0x3f,0x50,0xd7,0x12,0x21,0x21,0x40,0x0,0x0,0x88,0xfc,0x80,0x90,0xf8,0x80,0x84,0xfe,0x10,0xfc,0x10,0x10,0x10,0x50,0x20,
-+0x2,0x42,0x2f,0x22,0x80,0x67,0x24,0x8,0x13,0x22,0xe2,0x22,0x22,0x22,0x20,0x20,0x48,0x48,0xfe,0x48,0x0,0xfe,0x42,0x44,0xf8,0x48,0x48,0x48,0x48,0x58,0x40,0x40,
-+0x0,0x40,0x31,0x11,0x82,0x67,0x20,0x8,0x13,0x22,0xe2,0x22,0x22,0x22,0x23,0x22,0x80,0x80,0x0,0x10,0x8,0xfc,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x2,0x1,0x7f,0x44,0x88,0x3f,0x2,0x4,0x1f,0x1,0x1,0x7f,0x1,0x1,0xff,0x0,0x0,0x0,0xfe,0x42,0x24,0xf8,0x0,0x20,0xf0,0x0,0x8,0xfc,0x0,0x4,0xfe,0x0,
-+0x1,0x1,0x1,0x7f,0x41,0x41,0x41,0x41,0x7f,0x41,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x3f,0x21,0x21,0x21,0x3f,0x21,0x1,0x1,0x3f,0x24,0x24,0x24,0xff,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x0,0x8,0xfc,0x48,0x48,0x48,0xfe,0x0,
-+0x1,0x1,0x3f,0x21,0x21,0x21,0x3f,0x21,0x1,0x1,0x12,0x51,0x51,0x90,0xf,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,0x4,0x12,0x12,0xf0,0x0,
-+0x10,0x10,0x10,0x1c,0x21,0x21,0x7d,0x91,0x11,0xfd,0x11,0x10,0x14,0x18,0x10,0x0,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xfc,0x24,0x20,0x20,0x20,0x20,0x20,
-+0x2,0x1,0xff,0x1,0x1f,0x11,0x11,0x1f,0x11,0x5,0x8,0x18,0x28,0xca,0xc,0x8,0x0,0x4,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x8,0x18,0xa0,0x40,0x30,0xe,0x4,0x0,
-+0x10,0x10,0x20,0x21,0x45,0xfa,0x10,0x20,0x40,0xfd,0x2,0x0,0x1c,0xe0,0x40,0x0,0x80,0x80,0xfc,0x8,0x90,0x50,0x20,0x50,0x88,0xe,0x64,0x10,0x8,0xc0,0x30,0x8,
-+0x8,0x1c,0xf0,0x10,0x11,0xff,0x11,0x39,0x35,0x55,0x51,0x90,0x10,0x10,0x10,0x10,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xfc,0x24,0x20,0x20,0x20,0x20,0x20,
-+0x4,0x3e,0x24,0x24,0x25,0x3d,0x25,0x25,0x25,0x3d,0x25,0x24,0x24,0x44,0x94,0x8,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xfc,0x24,0x20,0x20,0x20,0x20,0x20,
-+0x0,0x3f,0x1,0xff,0x1,0x1f,0x11,0x1f,0x11,0x1f,0x1,0x3f,0x1,0x1,0xff,0x0,0x38,0xc0,0x4,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x0,0xf8,0x0,0x4,0xfe,0x0,
-+0x8,0x8,0x8,0x10,0x17,0x34,0x54,0x94,0x14,0x17,0x14,0x10,0x10,0x10,0x10,0x10,0x40,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0xfc,0x44,0x40,0x40,0x40,0x40,0x40,
-+0x1,0x1,0x1,0x2,0x4,0x8,0x30,0x0,0x8,0x8,0x14,0x12,0x22,0x41,0x82,0x0,0x0,0x0,0x0,0x80,0x40,0x38,0x10,0x0,0x20,0x20,0x50,0x50,0x88,0xe,0x4,0x0,
-+0x2,0x4,0x1f,0x10,0x12,0x11,0x11,0xff,0x10,0x12,0x11,0x11,0x10,0x20,0x40,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x0,0x3f,0x21,0x21,0x2f,0x21,0x21,0x3f,0x20,0x27,0x24,0x24,0x24,0x47,0x84,0x0,0x8,0xfc,0x8,0x48,0xe8,0x8,0x28,0xf8,0x48,0xe8,0x48,0x48,0x48,0xc8,0x28,0x10,
-+0x10,0x10,0x10,0x10,0x54,0x52,0x52,0x90,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x0,0x4,0x84,0x84,0x84,0xa4,0x94,0x94,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x4,0x4,
-+0x1,0x41,0x31,0x11,0x81,0x65,0x23,0xb,0x11,0x21,0xe1,0x21,0x22,0x22,0x24,0x20,0x4,0x4,0x24,0x24,0x24,0xb4,0x6c,0x6c,0x24,0x24,0x24,0x24,0x24,0x24,0x4,0x4,
-+0x1,0x41,0x21,0x22,0x4,0x8,0xe7,0x20,0x20,0x20,0x23,0x20,0x28,0x30,0x27,0x0,0x0,0x0,0xf8,0x10,0x20,0x44,0xfe,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x9,0xfd,0x9,0x9,0xd,0x7b,0x41,0x47,0x41,0x79,0xb,0xd,0x9,0x89,0x51,0x21,0x4,0x3e,0x4,0x4,0x44,0xbc,0x20,0xe0,0x24,0x3e,0x84,0x44,0x4,0x4,0x28,0x10,
-+0x10,0x10,0x14,0xfe,0x21,0x21,0x49,0x7f,0x9,0x9,0xf,0xf9,0x49,0x9,0x9,0x8,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0x24,0xfc,0x4,0x0,
-+0x4,0x3e,0x24,0x24,0x24,0x3d,0x24,0x24,0x24,0x3c,0x24,0x24,0x24,0x44,0x94,0x8,0x8,0x8,0x8,0x8,0x8,0xfe,0x8,0x8,0x88,0x48,0x48,0x8,0x8,0x8,0x28,0x10,
-+0x0,0x3f,0x0,0x1f,0x0,0x3f,0x1,0x7f,0x41,0x9f,0x11,0x11,0x11,0x11,0x1,0x1,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x0,0xfe,0x2,0xf4,0x10,0x10,0x50,0x20,0x0,0x0,
-+0x4,0x7e,0x44,0x44,0x44,0x7c,0x0,0xf,0x8,0x8,0x8,0x8,0x8,0x10,0x20,0x40,0x8,0xfc,0x88,0x88,0x88,0xf8,0x40,0xe0,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x10,0x10,0x1e,0x22,0xc4,0x8,0x7e,0x2,0x2,0x7e,0x2,0x2,0x7f,0x1,0x2,0x0,0x10,0x10,0x10,0xfe,0x92,0x94,0x90,0xfc,0x84,0xc4,0xa8,0xa8,0x10,0x28,0x4e,0x84,
-+0x2,0x1,0x7f,0x40,0x81,0x1,0x3f,0x21,0x21,0x21,0x3f,0x21,0x21,0x21,0x3f,0x20,0x0,0x0,0xfe,0x2,0x4,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x1f,0x10,0x10,0x1f,0x10,0x10,0x20,0x3f,0x50,0x9f,0x10,0x1f,0x0,0x7f,0x0,0x10,0xf8,0x10,0x10,0xf0,0x90,0x40,0x20,0xfe,0x14,0xf0,0x10,0xf0,0x0,0xfc,0x0,
-+0x10,0xff,0x12,0x53,0x52,0x53,0x52,0x57,0x78,0xb,0x8,0x3b,0xc8,0x9,0x2e,0x10,0x0,0xfc,0x44,0xd4,0x48,0xd4,0x62,0xd8,0x60,0xa4,0x68,0xb0,0x68,0xa6,0x20,0x20,
-+0x0,0x9,0xfd,0x11,0x11,0x12,0x7c,0x13,0x10,0x10,0x1c,0xf0,0x41,0x2,0x4,0x0,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x60,0x70,0xb0,0xa8,0x2e,0x24,0x20,0x20,
-+0x10,0x11,0x11,0x11,0xfd,0x12,0x30,0x3b,0x54,0x50,0x90,0x10,0x11,0x12,0x14,0x10,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x60,0x70,0xb0,0xa8,0x2e,0x24,0x20,0x20,
-+0x10,0x11,0x11,0x11,0x7d,0x56,0x54,0x57,0x54,0x7c,0x10,0x14,0x1d,0xf6,0x44,0x0,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x60,0x70,0xb0,0xa8,0x2e,0x24,0x20,0x20,
-+0x1,0x11,0x11,0x1f,0x11,0x21,0x1,0xff,0x3,0x5,0x9,0x11,0x21,0xc1,0x1,0x1,0x0,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x0,0x80,0x40,0x30,0xe,0x4,0x0,0x0,
-+0x2,0x44,0x2b,0x10,0x28,0x4b,0x88,0x9,0x1b,0x2d,0x49,0x89,0x9,0x9,0x29,0x11,0x40,0x44,0xf8,0x50,0x64,0xfe,0x80,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x0,0x20,0x1b,0x8,0x0,0x7,0xf0,0x11,0x13,0x15,0x19,0x11,0x15,0x19,0x11,0x1,0x40,0x44,0xf8,0x50,0x64,0xfe,0x80,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x0,0x42,0x22,0x23,0x2,0x4,0xe0,0x2f,0x20,0x20,0x21,0x29,0x32,0x24,0x8,0x0,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0xc0,0xe0,0x60,0x50,0x4e,0x44,0x40,0x40,
-+0x0,0x4f,0x20,0x21,0x3,0xc,0xe1,0x22,0x2c,0x21,0x22,0x2c,0x21,0x50,0x8f,0x0,0x8,0xfc,0x80,0x0,0x88,0xd8,0x60,0x40,0xe0,0x50,0x48,0x48,0x40,0x86,0xfc,0x0,
-+0x10,0x10,0x10,0x12,0x1f,0x28,0x49,0x8a,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x40,0x40,0x40,0x44,0x7e,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x10,0x10,0x10,0x12,0x55,0x59,0x51,0x91,0x11,0x11,0x11,0x28,0x24,0x44,0x83,0x1,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xfc,0x24,0x20,0x24,0x3c,0xe2,0x2,
-+0x2,0x2,0x3f,0x2,0xff,0x2,0xf,0x38,0xc8,0xf,0x8,0x8,0xf,0x20,0x24,0x42,0x0,0x20,0xf0,0x84,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x8,0x84,0x44,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x14,0x18,0x31,0xd0,0x10,0x10,0x10,0x10,0x57,0x20,0x40,0x20,0x4,0xfe,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x0,0x7,0x74,0x57,0x54,0x75,0x54,0x55,0x75,0x55,0x54,0x77,0x4a,0x12,0x22,0x2,0x4,0xfe,0x4,0xfc,0x0,0xfc,0x20,0xfc,0x24,0xfc,0x20,0xfe,0x22,0x2a,0xfa,0x6,
-+0x0,0x7,0x74,0x57,0x54,0x55,0x54,0x55,0x55,0x55,0x54,0x77,0x4a,0x12,0x22,0x2,0x4,0xfe,0x4,0xfc,0x0,0xfc,0x20,0xfc,0x24,0xfc,0x20,0xfe,0x22,0x2a,0xfa,0x6,
-+0x2,0x1,0x1,0x7f,0x1,0x1,0x1,0x1,0x3f,0x1,0x1,0x1,0x1,0x1,0xff,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x8,0x8,0xff,0x9,0x1,0x1f,0x1,0xff,0x1,0x2,0xf,0x18,0x2f,0xc8,0xf,0x8,0x20,0x24,0xfe,0x20,0x10,0xe0,0x44,0xfe,0x0,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x30,0x38,0x55,0x50,0x90,0x10,0x10,0x10,0x17,0x10,0x40,0x20,0x24,0xfe,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x2,0x3f,0x22,0x22,0x23,0x3e,0x22,0x22,0x3e,0x22,0x22,0x22,0x2f,0xf0,0x41,0x2,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x44,0x84,0x28,0x10,
-+0x10,0x10,0x10,0x15,0x7e,0x54,0x54,0x54,0x55,0x7c,0x54,0x10,0x14,0xfc,0x47,0x0,0x40,0x20,0x24,0xfe,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x4,0x7e,0x44,0x54,0x55,0x55,0x56,0x54,0x54,0x54,0x54,0x54,0x10,0x2b,0x44,0x84,0x40,0x20,0x20,0x0,0xfe,0x2,0x4,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,
-+0x10,0x10,0x13,0x1c,0x20,0x23,0x7c,0x90,0x13,0xfd,0x12,0x15,0x10,0x14,0x18,0x0,0x40,0x48,0xfc,0x40,0x48,0xfc,0x80,0x84,0xfe,0x8,0x8,0xfe,0x8,0x88,0x48,0x18,
-+0x10,0x12,0x1f,0x28,0x45,0x80,0x8,0x7d,0x11,0x11,0x11,0x11,0x1d,0xf2,0x44,0x8,0x40,0x44,0x7e,0xa0,0x10,0x0,0x10,0xf8,0x10,0x10,0x90,0x50,0x52,0x12,0xe,0x0,
-+0x8,0x8,0x8,0x17,0x10,0x30,0x50,0x90,0x17,0x10,0x10,0x10,0x10,0x10,0x1f,0x10,0x80,0x40,0x44,0xfe,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x0,0x40,0x30,0x17,0x80,0x60,0x20,0x8,0x17,0x20,0xe0,0x20,0x20,0x20,0x2f,0x20,0x80,0x40,0x44,0xfe,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x20,0x13,0x12,0x2,0xfe,0xa,0x12,0x3b,0x56,0x90,0x10,0x11,0x11,0x12,0x14,0x18,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0xa8,0xa0,0xa0,0x20,0x22,0x22,0x1e,0x0,
-+0x8,0xfc,0x8,0x4b,0x48,0x48,0x48,0x48,0x7d,0x4,0x4,0x1c,0xe4,0x44,0x17,0x8,0x40,0x20,0x24,0xfe,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x10,0x13,0x12,0xfe,0x12,0x16,0x1a,0x32,0xd2,0x12,0x12,0x14,0x14,0x58,0x20,0x8,0x1c,0xe0,0x50,0x50,0x50,0x50,0x50,0x50,0x48,0x48,0x48,0x44,0x44,0x42,0x40,
-+0x0,0x0,0x1f,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x21,0x21,0x41,0x81,0x1,0x10,0x78,0x80,0x20,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x10,0x8,0xe,0x4,0x0,
-+0x10,0x10,0x10,0x13,0xfe,0x12,0x17,0x1a,0x32,0xd3,0x12,0x10,0x10,0x10,0x57,0x20,0x40,0x40,0x48,0xfc,0x48,0x48,0xf8,0x48,0x48,0xfc,0x48,0x50,0x20,0xd2,0xa,0x6,
-+0x1,0x1,0x1,0x3f,0x2,0x2,0xff,0x4,0x4,0xf,0x0,0x0,0x0,0x6,0x1,0x0,0x0,0x0,0x10,0xf8,0x0,0x4,0xfe,0x0,0x0,0xf8,0x10,0x20,0x40,0x80,0x80,0x40,
-+0x0,0x4,0xfe,0x11,0x10,0x20,0x23,0x7c,0xa4,0x25,0x24,0x24,0x24,0x3c,0x24,0x0,0x40,0x40,0x48,0xfc,0x40,0x44,0xfe,0x80,0x80,0xfc,0x8,0x10,0x90,0x60,0x20,0x10,
-+0x10,0x10,0x10,0xfd,0x20,0x28,0x4b,0x7c,0x8,0x9,0x1c,0xe8,0x48,0x8,0x8,0x8,0x40,0x40,0x48,0xfc,0x40,0x44,0xfe,0x80,0x80,0xfc,0x8,0x10,0x90,0x60,0x20,0x10,
-+0x10,0x17,0x14,0x14,0xff,0x14,0x13,0x19,0x31,0xd7,0x11,0x11,0x1f,0x11,0x52,0x24,0x4,0xbe,0xa4,0xa4,0xbc,0x62,0xde,0x10,0x10,0xfc,0x10,0x14,0xfe,0x10,0xc,0x4,
-+0x0,0x7c,0x47,0x54,0x55,0x54,0x54,0x57,0x54,0x54,0x55,0x54,0x10,0x29,0x46,0x80,0x88,0x50,0xfe,0x50,0xfc,0x54,0x54,0xfe,0x54,0x54,0xfc,0x50,0xd8,0x56,0x54,0x50,
-+0x10,0x1e,0x28,0x4f,0x8,0x1f,0x0,0xff,0x2,0xd,0x71,0x6,0x39,0x6,0x78,0x3,0x40,0x7c,0xa0,0xc0,0x40,0x80,0x84,0xfe,0x10,0x20,0xc0,0xa0,0x90,0x8e,0x84,0x0,
-+0x10,0x10,0x10,0x13,0xfe,0x12,0x32,0x3a,0x57,0x52,0x92,0x12,0x14,0x14,0x1b,0x10,0x40,0x20,0x24,0xfe,0x0,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x1,0x0,0x0,0x3f,0x20,0x20,0x20,0x20,0x2f,0x20,0x20,0x20,0x40,0x40,0xbf,0x0,0x0,0x80,0x88,0xfc,0x0,0x80,0x80,0x88,0xfc,0x80,0x80,0x80,0x80,0x84,0xfe,0x0,
-+0x8,0x48,0x2b,0x8,0x18,0x29,0x4a,0x9,0xff,0x2,0x4,0xc,0x14,0x65,0x6,0x4,0x40,0x48,0xfc,0x40,0x50,0xf8,0x0,0x4,0xfe,0x8,0x90,0xa0,0x40,0x30,0xe,0x4,
-+0x8,0x8,0x8,0x48,0x28,0x2f,0x9,0x9,0x19,0x2a,0x49,0xc8,0x8,0x8,0x9,0xa,0x40,0x40,0x40,0x80,0x84,0xfe,0x8,0x8,0x8,0x8,0x10,0xa0,0x40,0xb0,0xc,0x4,
-+0x10,0x17,0x11,0x10,0xff,0x10,0x17,0x1a,0x33,0xd2,0x13,0x10,0x17,0x10,0x5f,0x20,0x40,0xfc,0x10,0xa4,0xfe,0x8,0xfc,0x48,0xf8,0x48,0xf8,0x40,0xfc,0x40,0xfe,0x0,
-+0x10,0x10,0x10,0x90,0x50,0x50,0x1f,0x10,0x30,0x50,0xd0,0x10,0x10,0x17,0x10,0x10,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x48,0xfc,0x0,0x0,
-+0x8,0x8,0x8,0x48,0x28,0x2f,0x8,0x8,0x18,0x28,0x49,0xc9,0x9,0xa,0xc,0x8,0x40,0x50,0x48,0x40,0x44,0xfe,0x40,0x40,0xa0,0xa0,0x10,0x10,0x8,0xe,0x4,0x0,
-+0x10,0x10,0x10,0x11,0xfd,0x13,0x35,0x39,0x55,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0xa0,0xa0,0x84,0xfe,0x20,0x28,0xfc,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,0x0,
-+0x10,0x10,0x10,0x1d,0x21,0x23,0x7d,0x91,0x11,0xfd,0x11,0x11,0x15,0x19,0x11,0x1,0xa0,0xa0,0x84,0xfe,0x20,0x28,0xfc,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,0x0,
-+0x0,0x40,0x33,0x12,0x2,0x3,0xf2,0x12,0x13,0x12,0x12,0x12,0x13,0x2a,0x47,0x0,0x40,0x90,0xf8,0x10,0x10,0xf0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x6,0xfc,0x0,
-+0x8,0x7f,0x8,0x3e,0x8,0xff,0x10,0x1e,0x22,0xcc,0x1f,0x10,0x11,0x11,0x6,0x38,0x40,0x44,0x7e,0x84,0xc4,0x28,0x10,0x28,0x46,0x90,0xf8,0x10,0x10,0x10,0xc0,0x38,
-+0x0,0x7c,0x44,0x48,0x50,0x48,0x45,0x65,0x5a,0x44,0x41,0x5f,0x1,0x1,0xff,0x0,0x40,0x40,0x40,0xa0,0xa0,0xa0,0x10,0x8,0xe,0x4,0x0,0xf0,0x0,0x0,0xfe,0x0,
-+0x10,0x17,0x24,0x22,0x41,0xfa,0x12,0x24,0x47,0xfc,0x4,0x2,0x19,0xe2,0x44,0x8,0x0,0xbc,0xa4,0xa8,0x10,0xa8,0xa6,0x40,0xbc,0xa4,0xa4,0xa8,0x10,0xa8,0x46,0x4,
-+0x0,0x4f,0x30,0x13,0x2,0x2,0xf3,0x10,0x13,0x10,0x10,0x17,0x14,0x18,0x11,0x0,0x44,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x0,0xf8,0x20,0x44,0xfe,0x40,0x40,0x40,0x80,
-+0x1,0x41,0x31,0x13,0x2,0x16,0x1b,0x12,0x22,0xe3,0x22,0x22,0x22,0x23,0x22,0x2,0x40,0x20,0x24,0xfe,0x20,0x28,0xfc,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,0x0,
-+0x10,0x13,0x12,0x12,0xfe,0x12,0x17,0x1a,0x30,0xd2,0x12,0x12,0x13,0x14,0x58,0x20,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x48,0x40,0x48,0x7c,0x40,0x40,0xc6,0x7c,0x0,
-+0x10,0x10,0x12,0x12,0xfe,0x12,0x17,0x18,0x30,0xd4,0x14,0x14,0x14,0x14,0x57,0x20,0x40,0x40,0x48,0x48,0x48,0x48,0xf8,0x48,0x40,0x44,0x44,0x44,0x44,0x44,0xfc,0x4,
-+0x1,0x1,0x1,0x1,0x1f,0x10,0x1f,0x10,0x1f,0x11,0x1,0xff,0x1,0x1,0x1,0x1,0x8,0xfc,0x0,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0x4,0xfe,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x1f,0x10,0x1f,0x10,0x1f,0x1,0xff,0x3,0x5,0x9,0x31,0x1,0x8,0xfc,0x0,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x80,0x60,0x1c,0x8,0x0,
-+0x0,0x17,0xf8,0x20,0x21,0x22,0x26,0xf9,0x22,0x24,0x20,0x21,0x3a,0xe4,0x41,0x0,0x4,0xfe,0x40,0x80,0x84,0x4c,0xb0,0x20,0xb0,0x68,0xa8,0x24,0x22,0x20,0x40,0x80,
-+0x8,0x8,0xff,0x8,0x1,0x21,0x21,0x21,0x3f,0x1,0x41,0x41,0x41,0x41,0x7f,0x40,0x20,0x24,0xfe,0x20,0x0,0x8,0x8,0x8,0xf8,0x0,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x1,0xff,0x14,0x14,0x7f,0x55,0x55,0x55,0x55,0x63,0x41,0x7f,0x41,0x41,0x7f,0x41,0x20,0xa0,0x20,0x24,0x7e,0x84,0x4,0x44,0x24,0x24,0x4,0x4,0x4,0x4,0x28,0x10,
-+0x0,0xb,0x7c,0x48,0x49,0x4a,0x4e,0x49,0x4a,0x4c,0x48,0x79,0x4a,0x4,0x1,0x0,0x4,0xfe,0x40,0x80,0x84,0x4c,0xb0,0x20,0xb0,0x68,0xa8,0x24,0x22,0x20,0x40,0x80,
-+0x8,0x4,0x7f,0x1,0x3f,0x2,0xff,0x4,0xf,0x18,0x2f,0xc8,0xf,0x8,0xf,0x8,0x20,0x48,0xfc,0x0,0xf8,0x0,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x10,
-+0x10,0x10,0x10,0x12,0x54,0x59,0x52,0x90,0x10,0x10,0x10,0x28,0x24,0x44,0x80,0x0,0x40,0x40,0x40,0x44,0xfe,0x4,0x4,0x84,0x44,0x44,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x0,0x40,0x30,0x10,0x87,0x64,0x24,0xc,0x14,0x27,0xe4,0x20,0x20,0x20,0x2f,0x24,0x40,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0xfc,0x44,0x50,0x48,0x7c,0xc4,0x4,
-+0x10,0xc,0x4,0x0,0xff,0x10,0x10,0x22,0x24,0x78,0x8,0x10,0x14,0x22,0x7e,0x2,0x10,0x30,0x40,0x4,0xfe,0x20,0x20,0x44,0x48,0xf0,0x10,0x20,0x28,0x44,0xfc,0x4,
-+0x41,0x31,0x11,0x2,0xa,0xf4,0x20,0x20,0x21,0x26,0x1f,0x10,0x10,0x10,0x1f,0x10,0x0,0x0,0xfc,0x4,0x48,0x40,0xa0,0x90,0xe,0x4,0xf0,0x10,0x10,0x10,0xf0,0x10,
-+0x41,0x21,0x21,0xa,0x34,0xe0,0x21,0x26,0x1f,0x10,0x11,0x11,0x11,0x2,0xc,0x30,0x0,0x0,0xfc,0x44,0x48,0xa0,0x10,0xe,0xf4,0x10,0x10,0x10,0x10,0xc0,0x30,0x8,
-+0x20,0x10,0x10,0x5,0xa,0x70,0x10,0x13,0x12,0xff,0x4,0x8,0x4,0x3,0x4,0x38,0x80,0xfc,0x84,0x28,0x20,0x50,0x8e,0x4,0x0,0xfe,0x20,0x20,0x40,0x80,0x60,0x10,
-+0x44,0x22,0x21,0xf,0x82,0x42,0x44,0x14,0x1f,0x21,0xe2,0x24,0x29,0x2f,0x21,0x20,0x8,0x10,0x24,0xfe,0x10,0x10,0x20,0xa4,0x78,0x8,0x10,0x20,0x44,0x7c,0x4,0x0,
-+0x2,0x42,0x24,0x29,0x84,0x62,0x22,0x8,0x17,0x24,0xe4,0x27,0x24,0x24,0x27,0x24,0x48,0x48,0x90,0x20,0x90,0x48,0x48,0x4,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x4,
-+0x0,0x0,0xfe,0x4,0x8,0x11,0x15,0x1a,0xf0,0x50,0x10,0x10,0x10,0x10,0x51,0x26,0x80,0x80,0x80,0x84,0xfe,0x8,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x8,0x28,0x2e,0x28,0x2e,0xf8,0x42,0x4,0x3f,0x1,0x2,0x3f,0x1,0x9,0x11,0x23,0x80,0x80,0x98,0xe2,0x82,0x7e,0x0,0x10,0xe0,0x0,0x10,0xf8,0x8,0x20,0x18,0x8,
-+0x8,0xb,0x8,0x10,0x10,0x30,0x50,0x9f,0x10,0x10,0x10,0x10,0x10,0x10,0x11,0x10,0x0,0xf8,0x8,0x10,0x20,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,
-+0x10,0x11,0x52,0x34,0x18,0xfe,0x10,0x33,0x38,0x54,0x54,0x90,0x10,0x10,0x10,0x10,0x0,0xfc,0x4,0x8,0x10,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x0,0x40,0x37,0x14,0x88,0x67,0x20,0x9,0x10,0x2f,0xe0,0x20,0x27,0x20,0x20,0x20,0x80,0x40,0xfe,0x2,0x44,0xfc,0x0,0x10,0xa4,0xfe,0x40,0x48,0xfc,0x40,0x40,0x40,
-+0x0,0x3f,0x0,0x0,0x0,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x5,0x2,0x0,0xf0,0x10,0x20,0x40,0x80,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x2,0x4,0x1f,0x10,0x10,0x1f,0x10,0x10,0x10,0x1f,0x10,0x10,0x10,0x1f,0x10,0x0,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0x10,0xf0,0x10,0x10,0x10,0xf0,0x10,
-+0x0,0x47,0x30,0x13,0x80,0x6f,0x20,0xb,0x12,0x22,0xe2,0x22,0x22,0x20,0x23,0x2c,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x8,0xfc,0x8,0x48,0x48,0x48,0x48,0xb0,0xc,0x4,
-+0x2,0x1,0x3f,0x20,0x40,0x1f,0x0,0x0,0x1,0xff,0x1,0x1,0x1,0x1,0x5,0x2,0x0,0x0,0xfc,0x4,0x8,0xe0,0x40,0x80,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x13,0x1c,0x10,0x7f,0x14,0x3e,0x1,0x7f,0x40,0x9f,0x0,0x7f,0x9,0x11,0x23,0x4,0x18,0x64,0x18,0x64,0x18,0x60,0x0,0xfe,0x2,0xf4,0x0,0xfc,0x20,0x18,0x8,
-+0x10,0x10,0x13,0x12,0xfc,0x11,0x30,0x38,0x57,0x50,0x90,0x11,0x11,0x12,0x10,0x10,0x40,0x20,0xfe,0x2,0x4,0xfc,0x0,0x4,0xfe,0x20,0xa8,0x24,0x22,0x22,0xa0,0x40,
-+0x0,0x78,0x4b,0x4a,0x4c,0x79,0x50,0x10,0x13,0x5c,0x50,0x51,0x5d,0xf2,0x40,0x0,0x40,0x20,0xfe,0x2,0x4,0xfc,0x0,0x4,0xfe,0x20,0xa8,0x24,0x22,0x22,0xa0,0x40,
-+0x2,0x1,0x7f,0x40,0x80,0x1f,0x0,0x0,0xff,0x1,0x9,0x9,0x11,0x21,0x5,0x2,0x0,0x0,0xfe,0x2,0x24,0xf0,0x0,0x4,0xfe,0x0,0x20,0x10,0x8,0x8,0x0,0x0,
-+0x10,0x10,0x23,0x22,0x44,0xf9,0x10,0x20,0x43,0xf8,0x0,0x1,0x19,0xe2,0x40,0x0,0x40,0x20,0xfe,0x2,0x4,0xfc,0x0,0x4,0xfe,0x20,0xa8,0x24,0x22,0x22,0xa0,0x40,
-+0x10,0x8,0x4,0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x2,0x51,0x50,0x90,0xf,0x0,0x10,0x20,0x40,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,0x0,0x84,0x92,0x12,0xf0,0x0,
-+0x11,0x11,0x21,0x21,0x45,0xf9,0x11,0x21,0x41,0xfd,0x42,0x2,0x1c,0xe4,0x48,0x11,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xa8,0xa8,0x48,0x44,0x82,0x0,
-+0x10,0x10,0x10,0x3f,0x42,0x84,0x7f,0x1,0x1,0x3f,0x1,0x1,0x7f,0x1,0x0,0x0,0x0,0x7c,0x44,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x1,0x1,0x1,0x3f,0x1,0x1,0xff,0x1,0x9,0x9,0x9,0x9,0x9,0x15,0x23,0x40,0x0,0x0,0x10,0xf8,0x0,0x4,0xfe,0x0,0x0,0x10,0xf8,0x0,0x0,0x6,0xfc,0x0,
-+0x1,0x1,0x7f,0x1,0x3f,0x2,0xff,0x4,0x8,0x37,0xc1,0x1f,0x1,0x2,0x4,0x38,0x0,0x8,0xfc,0x0,0xf8,0x0,0xfe,0x40,0x30,0xce,0x4,0xf0,0x0,0xc0,0x30,0x8,
-+0x10,0x10,0x17,0x10,0xfb,0x10,0x17,0x19,0x32,0xdd,0x10,0x17,0x10,0x10,0x51,0x26,0x40,0x48,0xfc,0x40,0xf8,0x80,0xfe,0x10,0xe,0xf4,0x40,0xfc,0x40,0xb0,0xc,0x4,
-+0x8,0x1c,0xf1,0x11,0x15,0xff,0x11,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x1f,0x10,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xfe,0x0,
-+0x0,0x1f,0x10,0x10,0x10,0x10,0x1f,0x11,0x1,0x11,0x11,0x11,0x11,0x29,0x47,0x80,0x10,0xf8,0x10,0x10,0x10,0x10,0xf0,0x10,0x0,0x10,0xf8,0x0,0x0,0x6,0xfc,0x0,
-+0x2,0x1,0x7f,0x8,0x8,0x8,0x14,0x22,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x0,0x8,0xfc,0x20,0x20,0x20,0x50,0x88,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,
-+0x20,0x18,0x8,0x0,0xfe,0x21,0x20,0x3c,0x24,0x25,0x27,0x24,0x44,0x44,0x94,0x9,0x40,0x40,0x48,0x7c,0x80,0x48,0x7c,0xa0,0xa0,0x24,0xfe,0x20,0x50,0x50,0x8e,0x4,
-+0x20,0x10,0x11,0x1,0xfd,0x9,0x11,0x39,0x55,0x91,0x11,0x11,0x11,0x11,0x17,0x10,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xfe,0x0,
-+0x40,0x30,0x11,0x1,0x1,0xf1,0x11,0x11,0x11,0x11,0x11,0x13,0x15,0x19,0x17,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xfe,0x0,
-+0x0,0x7c,0x45,0x49,0x49,0x51,0x49,0x49,0x45,0x45,0x45,0x69,0x51,0x41,0x47,0x40,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xfe,0x0,
-+0x10,0x10,0x21,0x21,0x45,0xf9,0x11,0x21,0x41,0xfd,0x41,0x1,0x1d,0xe1,0x47,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xfe,0x0,
-+0x10,0x10,0x10,0x1e,0x20,0x20,0x7c,0x91,0x11,0xff,0x11,0x13,0x15,0x19,0x11,0x1,0x20,0x20,0x24,0x3e,0x20,0x20,0x24,0xfe,0x4,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x20,0x3e,0x48,0x9f,0x12,0x10,0x1f,0x8,0xff,0x14,0x2f,0x41,0x9f,0x5,0x9,0x13,0x40,0x7e,0x90,0xf0,0x10,0x90,0xf0,0x4,0xfe,0x50,0x88,0x2e,0xe4,0x40,0x30,0x10,
-+0x1,0x5,0x75,0x55,0x55,0x5f,0x51,0x52,0x57,0x5a,0x53,0x72,0x43,0x2,0x4,0x8,0x20,0x20,0xe6,0x38,0xe2,0x1e,0xf0,0x28,0xfc,0x48,0xf8,0x48,0xf8,0x48,0x48,0x58,
-+0x4,0xfe,0x29,0x28,0xfe,0xaa,0xaa,0xab,0xa6,0xc2,0x83,0xfe,0x82,0x82,0xfe,0x82,0x20,0x24,0xfe,0x0,0x88,0x88,0x88,0x54,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x1f,0x10,0x1f,0x10,0x1f,0x0,0xff,0x22,0x3f,0x22,0x3e,0x22,0x3e,0xe2,0x2,0x3,0xf0,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x0,0xfc,0x84,0x88,0x50,0x20,0x58,0x8e,0x4,
-+0x0,0x7f,0x44,0x44,0x7f,0x0,0x4,0xfc,0x4,0x4,0x7c,0x4,0x4,0xfc,0x4,0x4,0x4,0xfe,0x44,0x44,0xfc,0x0,0x44,0x7e,0x40,0x48,0x7c,0x40,0x44,0x7e,0x40,0x40,
-+0x8,0x7f,0x4,0x3f,0x24,0x24,0x28,0x3f,0x20,0x3f,0x0,0xff,0x8,0x4,0x4,0x0,0x40,0xfc,0x80,0xf8,0x88,0xe8,0x8,0xf8,0x8,0xf8,0x20,0xfe,0x20,0x20,0xa0,0x40,
-+0x2,0x5f,0x21,0x2f,0x9,0xa,0xe8,0x2b,0x28,0x2f,0x20,0x3f,0x24,0x22,0x50,0x8f,0x20,0xfc,0x40,0xf8,0x48,0x38,0x8,0xe8,0x8,0xf8,0x20,0xfe,0x20,0xa0,0x46,0xfc,
-+0x1,0x9,0x7d,0x49,0x4a,0x4c,0x48,0x78,0x48,0x48,0x48,0x48,0x78,0x48,0x0,0x0,0x0,0x0,0x4,0xfe,0x80,0x80,0x90,0xf8,0x80,0x80,0x88,0xfc,0x80,0x80,0x80,0x80,
-+0x2,0x2,0x2,0xff,0x4,0x4,0x4,0x8,0xf,0x10,0x10,0x20,0x40,0x80,0x7f,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x10,0xf8,0x80,0x80,0x80,0x80,0x84,0xfe,0x0,
-+0x8,0x8,0x8,0x17,0x10,0x30,0x51,0x91,0x11,0x12,0x14,0x18,0x10,0x10,0x17,0x10,0x80,0x80,0x84,0xfe,0x80,0x80,0x0,0x8,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x11,0x11,0x11,0x11,0xfe,0x14,0x30,0x38,0x54,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x0,0x0,0x4,0xfe,0x80,0x80,0x90,0xf8,0x80,0x80,0x88,0xfc,0x80,0x80,0x80,0x80,
-+0x10,0x12,0x12,0x22,0x3f,0x62,0xa2,0x22,0x2f,0x28,0x28,0x28,0x28,0x2f,0x28,0x20,0x20,0x20,0x20,0x24,0xfe,0x84,0x44,0x44,0xc8,0xa8,0xa8,0x90,0xa8,0xa8,0x46,0x84,
-+0x9,0x9,0x9,0x11,0x12,0x32,0x54,0x98,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x0,0x0,0x4,0xfe,0x80,0x80,0x90,0xf8,0x80,0x80,0x88,0xfc,0x80,0x80,0x80,0x80,
-+0x1,0x1,0x11,0x11,0x11,0x29,0x25,0x45,0x81,0x1,0x3f,0x1,0x1,0x1,0xff,0x0,0x0,0x0,0x10,0x10,0x10,0x28,0x24,0x44,0x80,0x10,0xf8,0x0,0x0,0x4,0xfe,0x0,
-+0x1,0x0,0x3f,0x20,0x24,0x24,0x24,0x2a,0x29,0x31,0x20,0x2f,0x40,0x40,0xbf,0x0,0x0,0x84,0xfe,0x80,0x90,0x90,0x90,0xa8,0xa4,0xc4,0x90,0xf8,0x80,0x84,0xfe,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x3f,0x0,0x0,0x0,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x5,0x2,0x8,0xfc,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0xff,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x8,0x8,0x10,0x20,0x4,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x0,0xff,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x8,0x8,0x10,0x20,0x40,0x4,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x0,0xff,0x1,0x1,0x21,0x21,0x21,0x21,0x3f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x0,0x8,0x8,0x8,0x8,0xff,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0xf,0x8,0x0,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xe0,0x20,
-+0x10,0x11,0x11,0x11,0x11,0x11,0x11,0xff,0x11,0x11,0x11,0x11,0x11,0x21,0x20,0x40,0x10,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x0,0x7f,0x0,0x0,0x1,0x3,0x5,0x9,0x11,0x21,0x41,0x1,0x1,0x1,0xff,0x0,0x8,0xfc,0x80,0x80,0x0,0x0,0x60,0x10,0x8,0x4,0x4,0x0,0x0,0x4,0xfe,0x0,
-+0x0,0x7f,0x0,0x0,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x0,0x0,0xff,0x0,0x8,0xfc,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,0x0,0x4,0xfe,0x0,
-+0x0,0x3f,0x0,0x0,0x1,0x7d,0x5,0x9,0x9,0x11,0x11,0x21,0x45,0x2,0xff,0x0,0x20,0xf0,0x40,0x80,0x8,0x18,0xa0,0x40,0x20,0x10,0xe,0x4,0x0,0x4,0xfe,0x0,
-+0x0,0xff,0x0,0x1f,0x10,0x10,0x1f,0x0,0x7f,0x44,0x42,0x5f,0x41,0x41,0x41,0x40,0x4,0xfe,0x0,0xf0,0x10,0x10,0xf0,0x4,0xfe,0x44,0x84,0xf4,0x4,0x4,0x14,0x8,
-+0x0,0x7f,0x3,0x5,0x19,0x61,0x10,0x10,0xfe,0x22,0x22,0x23,0x14,0x8,0x14,0x62,0x8,0xfc,0x0,0x60,0x18,0x4,0x0,0xf8,0x8,0x10,0x24,0xfe,0x20,0x20,0xa0,0x40,
-+0x0,0xff,0x1,0x3d,0x25,0x3d,0x1,0x7f,0x1,0x3d,0x25,0x25,0x3d,0x1,0xff,0x0,0x4,0xfe,0x0,0x78,0x48,0x78,0x0,0xfc,0x0,0x78,0x48,0x48,0x78,0x4,0xfe,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x1,0x7f,0x41,0x41,0x4f,0x40,0x40,0x40,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x4,0xfe,0x4,0x24,0xe4,0x24,0x14,0x8,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x2,0x2,0x4,0x8,0x10,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x10,0x10,0x10,0x10,0x11,0x12,0x14,0x18,0x10,0x10,0x10,0x10,0x10,0xf,0x0,0x0,0x0,0x20,0x60,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x4,0xfc,0x0,
-+0x0,0x3,0x7e,0x2,0x2,0x2,0x2,0x3,0xfe,0x2,0x2,0x2,0x2,0x2,0x2,0x1,0x10,0xf8,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,0x2,0x2,0xfe,
-+0x0,0x1,0x3f,0x1,0x1,0x1,0x1,0xff,0x1,0x2,0x2,0x4,0x4,0x8,0x30,0xc0,0x10,0xf8,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x80,0x80,0x40,0x20,0x10,0xe,0x4,
-+0x0,0x10,0xc,0x2,0x1,0x2,0xc,0x70,0x8,0x4,0x2,0x1,0x2,0xc,0x30,0xc0,0x10,0x30,0x40,0x80,0x0,0xc0,0x30,0x28,0x40,0x40,0x80,0x0,0x80,0x60,0x1e,0x4,
-+0x0,0x1,0x3e,0x20,0x3f,0x20,0x20,0x27,0x24,0x24,0x24,0x24,0x44,0x44,0x84,0x3,0x10,0xf8,0x0,0x4,0xfe,0x0,0x10,0xf8,0x10,0x10,0x90,0x50,0x20,0x2,0x2,0xfe,
-+0x0,0x0,0x3f,0x20,0x20,0x20,0x3f,0x20,0x20,0x20,0x22,0x24,0x28,0x33,0x20,0x0,0x10,0xf8,0x80,0x80,0x80,0x84,0xfe,0x80,0x80,0x40,0x40,0x20,0x20,0x12,0x8a,0x6,
-+0x2,0x2,0x4,0x3f,0x20,0x28,0x24,0x22,0x21,0x22,0x24,0x28,0x30,0x20,0x3f,0x20,0x0,0x0,0x8,0xfc,0x8,0x28,0x48,0x88,0x8,0x88,0x48,0x28,0x18,0x8,0xf8,0x8,
-+0x1,0x12,0x14,0x1f,0x11,0x12,0x1f,0x10,0x17,0x14,0x17,0x24,0x27,0x44,0x85,0x4,0x0,0x10,0x50,0x90,0x10,0x50,0xf0,0x10,0xd0,0x50,0xd0,0x50,0xd2,0x52,0x4e,0x80,
-+0x10,0x10,0x10,0x13,0xfc,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x24,0x24,0x43,0x80,0x0,0x88,0x50,0xfe,0x20,0xf8,0x88,0xf8,0x88,0xf8,0x88,0xf8,0x8a,0x2,0xfe,0x0,
-+0x20,0x20,0x24,0x7f,0x80,0x7c,0x44,0x55,0x44,0xfe,0x44,0x54,0x44,0x7e,0x5,0x1a,0x40,0x20,0x24,0xfe,0x40,0x50,0x88,0xfc,0x0,0xa8,0xa8,0xa8,0xaa,0xaa,0x2e,0x0,
-+0x4,0x8,0x3f,0x24,0x3f,0x1,0x1f,0x1,0xff,0x4,0x1f,0x1,0x7f,0x1,0x1,0x1,0x0,0x8,0xfc,0x48,0xf8,0x0,0xf0,0x4,0xfe,0x40,0xf0,0x0,0xfc,0x0,0x0,0x0,
-+0x12,0xa,0x12,0x2,0x3c,0x8,0x7e,0x9,0xff,0x0,0x3e,0x22,0x3e,0x14,0x7e,0x1,0x48,0x50,0x48,0x44,0x3c,0x20,0x28,0xfc,0x20,0xf8,0x88,0x88,0x50,0x20,0x50,0x8e,
-+0x0,0x0,0x0,0x0,0x0,0x4,0x2,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x40,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x0,0x0,0x1,0x3d,0x25,0x25,0x25,0x25,0x25,0x3d,0x1,0x2,0xff,0x0,0x20,0xf0,0x40,0x80,0x8,0x7c,0x8,0x48,0x30,0x10,0x28,0x48,0x0,0x4,0xfe,0x0,
-+0x7f,0x10,0x17,0x14,0x27,0x24,0x57,0x94,0x17,0x10,0x1e,0x2,0x7e,0x12,0x12,0x62,0xf0,0x10,0xd4,0x5e,0xc4,0x44,0xd4,0x5c,0xd0,0x10,0xf0,0x80,0xf8,0x88,0x88,0x88,
-+0x0,0x8,0x8,0x8,0x8,0x9,0xe,0x18,0x68,0x8,0x8,0x8,0x8,0x8,0x7,0x0,0x0,0x0,0x0,0x20,0x70,0xa0,0x20,0x20,0x20,0x20,0xa0,0x44,0x4,0x4,0xfc,0x0,
-+0x10,0x10,0x12,0x1f,0x10,0x10,0x10,0x12,0x7f,0x42,0x42,0x42,0x42,0x42,0x7e,0x42,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x42,0x3e,0x0,
-+0x0,0x3f,0x0,0x0,0x0,0xff,0x4,0x4,0x4,0x4,0x4,0x4,0x8,0x8,0x10,0x20,0x10,0xf8,0x0,0x0,0x4,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x1,0x9,0x9,0x79,0x9,0x9,0x9,0x7f,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x0,0x20,0x28,0x3c,0x20,0x20,0x28,0xfc,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x7f,0x1,0x41,0x7f,0x40,0x9f,0x0,0x1,0x1,0xff,0x1,0x1,0x5,0x2,0x0,0x8,0xfc,0x0,0x0,0xfe,0x2,0xe4,0x40,0x80,0x4,0xfe,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x7f,0x1,0x9,0x5,0xff,0x0,0x3f,0x20,0x27,0x24,0x27,0x20,0x3f,0x20,0x0,0x8,0xfc,0x0,0x20,0x44,0xfe,0x0,0xf8,0x8,0xc8,0x48,0xc8,0x8,0xf8,0x8,
-+0x20,0x27,0x24,0xfc,0x24,0x27,0x24,0x74,0x57,0x54,0x54,0x57,0x74,0x54,0x4,0x4,0x4,0xbe,0x84,0x84,0x84,0xbc,0x84,0x0,0xbc,0x4,0x24,0xa8,0x10,0x28,0x2e,0xc4,
-+0x0,0x3f,0x20,0x20,0x20,0x20,0x20,0x20,0x21,0x21,0x22,0x22,0x44,0x48,0x90,0x20,0x8,0xfc,0x0,0x80,0x80,0x80,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0xe,0x4,
-+0x0,0x3f,0x21,0x21,0x2f,0x22,0x22,0x24,0x2f,0x20,0x20,0x3f,0x40,0x40,0x80,0x0,0x8,0xfc,0x0,0x8,0xfc,0x40,0x40,0x50,0xf8,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,
-+0x0,0x3f,0x22,0x22,0x2f,0x22,0x3f,0x20,0x27,0x24,0x24,0x27,0x44,0x44,0x87,0x4,0x8,0xfc,0x20,0x28,0xfc,0x20,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x0,0x3f,0x20,0x20,0x2f,0x21,0x3e,0x20,0x2f,0x28,0x2f,0x28,0x4f,0x48,0x80,0x0,0x8,0xfc,0xa0,0x90,0xfc,0x40,0x3c,0x8,0xfc,0x88,0xf8,0x88,0xf8,0x88,0x80,0x80,
-+0x0,0x3f,0x20,0x28,0x25,0x3f,0x22,0x2a,0x2a,0x2a,0x2f,0x22,0x42,0x44,0x88,0x10,0x8,0xfc,0x20,0xa0,0x20,0xbe,0x22,0xd4,0x90,0x90,0x90,0x90,0x28,0x28,0x44,0x82,
-+0x0,0x3f,0x29,0x29,0x3f,0x29,0x2f,0x29,0x2f,0x29,0x29,0x3f,0x42,0x49,0x90,0x1,0x8,0xfc,0x0,0xc,0xf0,0x40,0x44,0x7e,0x48,0x48,0x48,0xc8,0x48,0x48,0x88,0x8,
-+0x0,0x3f,0x20,0x2f,0x21,0x26,0x38,0x2f,0x20,0x2f,0x29,0x29,0x49,0x49,0x89,0xf,0x8,0xfc,0xa0,0xfc,0x40,0x30,0xe,0xfc,0x80,0xfc,0x24,0xe4,0x24,0xe4,0x24,0xfc,
-+0x0,0x3f,0x22,0x24,0x2d,0x36,0x24,0x24,0x24,0x2f,0x28,0x28,0x48,0x41,0x86,0x18,0x8,0xfc,0x50,0xfc,0x90,0xfc,0x90,0x9e,0x80,0xf8,0x8,0x88,0x88,0x60,0x18,0x4,
-+0x0,0x7f,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7f,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x0,0x7f,0x40,0x40,0x47,0x44,0x44,0x44,0x44,0x44,0x47,0x44,0x40,0x40,0x7f,0x0,0x8,0xfc,0x0,0x20,0xf0,0x20,0x20,0x20,0x20,0x20,0xe0,0x20,0x0,0x4,0xfe,0x0,
-+0x0,0x7f,0x48,0x4a,0x7f,0x50,0x54,0x7f,0x44,0x44,0x7f,0x44,0x44,0x45,0x7f,0x0,0x8,0xfc,0x40,0x40,0x50,0xf8,0x50,0x50,0x50,0x50,0x54,0x54,0x8c,0x0,0xfe,0x0,
-+0x0,0x7f,0x40,0x4f,0x48,0x4f,0x40,0x7f,0x40,0x4f,0x48,0x48,0x43,0x4c,0x7f,0x0,0x8,0xfc,0x80,0xf8,0x88,0xf8,0x80,0xfc,0x8,0xfc,0x88,0x88,0x60,0x18,0xfe,0x0,
-+0x0,0x7f,0x40,0x4f,0x48,0x4f,0x48,0x4f,0x59,0x69,0x4f,0x49,0x49,0x48,0x7f,0x0,0x8,0xfc,0x80,0xf8,0x8,0xf8,0x0,0xfc,0x24,0x24,0xfc,0x24,0x2c,0x4,0xfe,0x0,
-+0x0,0x4,0x7f,0x48,0x49,0x48,0x5f,0x54,0x55,0x55,0x5d,0x49,0x49,0x48,0x7e,0x1,0x20,0x24,0xfe,0x20,0xfc,0x20,0xfe,0x4,0xfe,0x4,0x24,0x24,0x24,0x50,0x4c,0x84,
-+0x8,0x8,0xa,0x7f,0x8,0x9,0xff,0x8,0xa,0x7f,0x8,0x8,0xf,0x78,0x20,0x0,0x40,0x40,0x40,0x40,0x40,0x60,0xd0,0x48,0x44,0x44,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x1,0x1,0x1,0x1,0x1,0x3f,0x20,0x20,0x3f,0x20,0x20,0x3f,0x20,0x20,0x3f,0x20,0x0,0x8,0xfc,0x0,0x8,0xfc,0x8,0x88,0xc8,0x88,0x88,0x88,0x88,0x8,0xf8,0x8,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x4,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x4,0x4,0x4,0x14,0x8,
-+0x0,0x41,0x21,0x11,0x12,0xa,0xa,0x4,0x4,0xa,0x9,0x11,0x10,0x20,0x40,0x0,0x4,0x4,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x4,0x84,0x84,0x14,0x8,
-+0x20,0x20,0x20,0x3f,0x2a,0x4a,0x4a,0x8a,0x12,0x14,0x14,0x24,0x48,0x12,0x1,0x0,0x4,0x4,0xa4,0xe4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0x84,0x84,0x14,0x8,
-+0x0,0x7f,0x1,0x2,0x4,0xb,0x30,0xc0,0x3f,0x4,0x4,0x4,0x7,0x7c,0x20,0x0,0x4,0x84,0x4,0x24,0x24,0x24,0xa4,0x24,0xa4,0x24,0x24,0x4,0x84,0x4,0x14,0x8,
-+0x8,0x9,0xff,0x14,0x12,0x21,0xde,0x0,0xff,0x10,0x3f,0x1,0x1,0x11,0xa,0x4,0x4,0x4,0x84,0x24,0x24,0xa4,0xa4,0x24,0xa4,0x24,0x24,0x4,0x4,0x4,0x14,0x8,
-+0x4,0x4,0x24,0x24,0x3f,0x8,0x8,0xf,0x10,0x11,0x31,0x4a,0x4,0x8,0x10,0x60,0x4,0x4,0x84,0xa4,0xa4,0xa4,0x24,0xa4,0xa4,0x24,0x24,0x4,0x4,0x4,0x14,0x8,
-+0x8,0x8,0x49,0x49,0x7f,0x0,0x7f,0x1,0x1,0x3f,0x21,0x20,0x21,0x26,0x38,0x0,0x4,0x4,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x4,0x84,0x4,0x14,0x8,
-+0x8,0x9,0xff,0x8,0x9,0x7f,0x49,0x49,0x7f,0x59,0x1c,0x2a,0x29,0x49,0x88,0x8,0x4,0x4,0x84,0x24,0x24,0xa4,0x24,0x24,0x24,0x24,0x24,0x4,0x4,0x4,0x14,0x8,
-+0x8,0x9,0xff,0x8,0x14,0x22,0xff,0x1,0x3d,0x25,0x25,0x25,0x3d,0x21,0x5,0x2,0x4,0x4,0x84,0x24,0x24,0xa4,0xe4,0x24,0x24,0x24,0x24,0x4,0x4,0x4,0x14,0x8,
-+0x8,0x49,0x29,0x2a,0x8,0x16,0x21,0xc8,0x8,0x29,0x2a,0x48,0x16,0x21,0xc0,0x0,0x4,0x4,0x4,0x24,0x24,0x24,0xa4,0xa4,0x24,0x24,0x24,0x4,0x4,0x84,0x94,0x8,
-+0x8,0x44,0x7f,0x40,0xa0,0x3b,0x2a,0x4a,0x6a,0x93,0x12,0x22,0x22,0x42,0x83,0x0,0x4,0x4,0xc4,0x54,0x94,0xd4,0x94,0x94,0x94,0x94,0x14,0x4,0x44,0x84,0x14,0x8,
-+0x11,0x11,0xff,0x11,0x7b,0x4a,0x4a,0x7b,0x4a,0x4a,0x7b,0x4a,0x4a,0x4a,0x9c,0x8,0x4,0x44,0xe4,0x14,0xd4,0x54,0x54,0xd4,0x54,0x54,0xd4,0x44,0x44,0x44,0xd4,0x48,
-+0x0,0xff,0xa,0xa,0x7f,0x4a,0x4a,0x7f,0x0,0x7f,0x0,0xff,0x15,0x24,0x44,0xc,0x84,0xc4,0x4,0x54,0xf4,0x54,0x54,0xd4,0x14,0xd4,0x14,0xe4,0x4,0xc4,0x54,0x8,
-+0x0,0x7f,0x40,0x51,0x4a,0x7f,0x44,0x55,0x55,0x55,0x5f,0x44,0x44,0x48,0x91,0x22,0x22,0xf2,0x2,0x4a,0x4a,0x7a,0x9a,0xa,0x4a,0x4a,0x4a,0x4a,0xa2,0x92,0x16,0x2,
-+0x4,0x25,0x3f,0x24,0x25,0x7f,0xa4,0x25,0x3f,0x24,0x25,0x3f,0x20,0x54,0x4a,0x8a,0x4,0x4,0x84,0x24,0x24,0xa4,0x24,0x24,0xa4,0x24,0x24,0x84,0x4,0x84,0x54,0x48,
-+0x11,0x7f,0x11,0x12,0x3f,0x52,0x1f,0x12,0x13,0x10,0x3f,0x11,0xa,0x4,0x1b,0x60,0x4,0xc4,0x4,0x24,0xa4,0x24,0xa4,0x24,0xa4,0x24,0xa4,0x4,0x4,0x4,0x14,0x88,
-+0x4,0x3f,0x28,0x24,0x3f,0x0,0x7f,0x44,0x7f,0x44,0x7f,0x0,0xff,0x11,0x11,0x21,0x4,0x84,0x84,0x94,0x94,0x14,0xd4,0x54,0xd4,0x54,0xd4,0x4,0xc4,0x4,0x14,0x8,
-+0x0,0x7f,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x14,0x8,
-+0x0,0x7f,0x48,0x44,0x42,0x5f,0x42,0x41,0x5f,0x48,0x48,0x48,0x4f,0x40,0x40,0x40,0x4,0xfe,0x24,0x44,0x84,0xf4,0x4,0x24,0xf4,0x4,0x4,0x44,0xe4,0x4,0x14,0x8,
-+0x8,0x8,0x8,0x10,0x10,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x8,0x8,0xb,0x10,0x10,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x11,0x10,0x10,0x0,0x4,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x8,0x8,0x9,0x11,0x11,0x31,0x51,0x91,0x11,0x11,0x11,0x11,0x12,0x12,0x14,0x18,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x8,0x8,0x8,0x10,0x17,0x30,0x50,0x90,0x10,0x10,0x11,0x11,0x11,0x12,0x14,0x18,0x80,0x80,0x80,0x84,0xfe,0x84,0x84,0x84,0x84,0x84,0x4,0x4,0x4,0x48,0x28,0x10,
-+0x8,0x8,0xb,0x10,0x10,0x30,0x50,0x93,0x10,0x10,0x10,0x10,0x10,0x17,0x10,0x10,0x0,0x8,0xfc,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,
-+0x9,0x9,0x9,0x12,0x12,0x37,0x58,0x90,0x10,0x10,0x11,0x12,0x12,0x12,0x11,0x10,0x0,0x8,0xfc,0x0,0x0,0xf8,0x10,0x20,0x40,0x80,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x8,0x8,0x8,0x10,0x10,0x30,0x51,0x92,0x14,0x18,0x11,0x12,0x14,0x17,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0xa0,0x20,0x40,0x40,0x80,0x0,0x10,0x8,0xfc,0x4,0x0,
-+0x8,0x8,0xf,0x10,0x10,0x32,0x52,0x92,0x12,0x14,0x10,0x11,0x11,0x12,0x14,0x18,0x0,0x4,0xfe,0x44,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x4,0x4,0x4,0x28,0x10,
-+0x8,0x8,0xb,0x12,0x12,0x32,0x52,0x92,0x12,0x12,0x12,0x12,0x13,0x12,0x13,0x10,0x0,0x8,0xfc,0x0,0x8,0x88,0x50,0x50,0x20,0x20,0x50,0x88,0x8,0x4,0xfe,0x0,
-+0x8,0xa,0xa,0x12,0x12,0x32,0x53,0x92,0x12,0x12,0x12,0x12,0x12,0x13,0x12,0x10,0x20,0x20,0x20,0x20,0x22,0x24,0xb8,0x20,0x20,0x20,0x20,0x20,0x20,0xa2,0x22,0x1e,
-+0x8,0x8,0xb,0x10,0x11,0x31,0x53,0x90,0x10,0x10,0x10,0x11,0x12,0x14,0x10,0x10,0x0,0x8,0xfc,0x10,0x10,0x14,0xfe,0x30,0x30,0x50,0x90,0x10,0x10,0x10,0x50,0x20,
-+0x8,0x8,0xf,0x11,0x11,0x31,0x51,0x91,0x11,0x12,0x12,0x12,0x13,0x16,0x10,0x10,0x0,0x4,0xfe,0x0,0x10,0xf8,0x10,0x10,0x90,0x50,0x30,0x10,0xd2,0x12,0xe,0x0,
-+0x9,0x9,0xa,0x13,0x14,0x38,0x50,0x90,0x1f,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x0,0x0,0x8,0xfc,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x9,0x9,0x9,0x11,0x11,0x31,0x51,0x9f,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x0,0x8,0x10,0x20,0x40,0x80,0x4,0xfe,0x40,0x40,0x20,0x10,0x8,0x46,0x84,0x0,
-+0x8,0x8,0x8,0x10,0x11,0x32,0x54,0x99,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x10,0x40,0x40,0xa0,0xa0,0x10,0xe,0x4,0xf0,0x10,0x10,0x50,0x20,0x4,0x4,0xfc,0x0,
-+0x8,0x8,0x8,0x17,0x10,0x30,0x51,0x91,0x11,0x11,0x11,0x11,0x12,0x12,0x14,0x18,0x80,0x40,0x44,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x8,0x8,0x8,0x13,0x12,0x34,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x1f,0x10,0x10,0x80,0x40,0x40,0xfc,0x4,0x8,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,
-+0x8,0xb,0x8,0x10,0x17,0x30,0x50,0x9f,0x11,0x11,0x12,0x11,0x10,0x10,0x11,0x16,0x10,0xf8,0x0,0x8,0xfc,0x80,0x84,0xfe,0x10,0x10,0x10,0xa0,0x40,0xa0,0x18,0x4,
-+0x8,0x8,0x8,0x10,0x10,0x30,0x50,0x9f,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x80,0x80,0x90,0xf8,0x80,0x80,0x84,0xfe,0x80,0xc0,0xa0,0x98,0x88,0x80,0x80,0x80,
-+0x8,0x8,0x8,0x10,0x15,0x35,0x56,0x94,0x14,0x14,0x14,0x14,0x14,0x10,0x11,0x16,0x80,0x80,0x80,0x84,0xfe,0x8,0x88,0x88,0x88,0x50,0x50,0x20,0x50,0x90,0xe,0x4,
-+0x8,0x8,0xa,0x12,0x13,0x34,0x58,0x90,0x1f,0x10,0x10,0x10,0x11,0x11,0x12,0x14,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x40,0xa0,0xa0,0x10,0x10,0xe,0x4,
-+0x9,0x9,0x9,0x13,0x12,0x34,0x5b,0x92,0x12,0x12,0x12,0x13,0x12,0x10,0x10,0x10,0x0,0x0,0x4,0xfe,0x4,0x24,0xf4,0x24,0x24,0x24,0x24,0xe4,0x24,0x44,0x28,0x10,
-+0x9,0x9,0x9,0x12,0x15,0x38,0x50,0x90,0x11,0x12,0x1c,0x10,0x11,0x10,0x10,0x10,0x0,0x0,0xf8,0x8,0x10,0xa0,0x40,0xa0,0x10,0x8e,0x64,0x20,0x80,0x60,0x30,0x10,
-+0x8,0x8,0x8,0x13,0x12,0x35,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x10,0x80,0x40,0x40,0xfc,0x4,0x8,0x0,0x10,0x30,0x40,0x80,0x0,0x4,0x4,0xfc,0x0,
-+0x8,0xb,0xa,0x12,0x12,0x33,0x52,0x92,0x12,0x12,0x12,0x12,0x14,0x14,0x18,0x10,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x80,0x88,0x98,0xa0,0xc0,0x82,0x82,0x7e,0x0,
-+0x14,0x14,0x14,0x24,0x3f,0x64,0xa4,0x24,0x24,0x24,0x24,0x24,0x28,0x28,0x32,0x21,0x0,0x0,0x4,0xbe,0xe4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xbc,0xa4,0x0,
-+0x8,0x8,0x8,0x1f,0x10,0x30,0x57,0x90,0x10,0x13,0x12,0x12,0x12,0x12,0x13,0x12,0x40,0x40,0x44,0xfe,0x40,0x48,0xfc,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x8,0xf,0x9,0x11,0x11,0x31,0x51,0x91,0x11,0x11,0x11,0x17,0x10,0x10,0x10,0x10,0x4,0xfe,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0x7e,0x88,0x8,0x8,0x8,0x8,
-+0x8,0x8,0x8,0x17,0x11,0x31,0x53,0x95,0x19,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x80,0x80,0x84,0xfe,0x0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x28,0x10,
-+0x8,0x8,0x8,0x1f,0x10,0x31,0x52,0x9c,0x13,0x11,0x11,0x10,0x10,0x10,0x10,0x10,0x40,0x40,0x44,0xfe,0xa0,0x10,0xee,0x4,0xf8,0x0,0xf8,0x8,0x8,0x90,0x50,0x20,
-+0x8,0xb,0xa,0x12,0x12,0x33,0x50,0x92,0x12,0x12,0x12,0x12,0x12,0x14,0x18,0x10,0x8,0xfc,0x8,0x8,0x8,0xf8,0x0,0x48,0x48,0x48,0x48,0x48,0x4a,0x4a,0x4e,0x0,
-+0x8,0xa,0xa,0x13,0x14,0x38,0x50,0x9f,0x10,0x10,0x11,0x12,0x14,0x18,0x10,0x10,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0xc0,0xe0,0x50,0x48,0x4e,0x44,0x40,0x40,
-+0x8,0x9,0x9,0x12,0x14,0x3b,0x52,0x92,0x13,0x12,0x12,0x13,0x12,0x12,0x12,0x12,0x40,0x40,0x20,0x10,0xe,0xf4,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,0x10,0x50,0x20,
-+0x8,0x8,0x8,0x14,0x12,0x32,0x50,0x91,0x12,0x14,0x10,0x11,0x11,0x12,0x14,0x18,0xa0,0xa0,0xa0,0xa4,0xac,0xb0,0xa0,0xb0,0xac,0xa4,0xa0,0x20,0x22,0x22,0x1e,0x0,
-+0x8,0x8,0xf,0x11,0x10,0x30,0x50,0x93,0x1d,0x11,0x11,0x11,0x11,0x11,0x12,0x14,0x40,0x28,0xfc,0x10,0xa0,0x40,0xb0,0xe,0x14,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x8,0x8,0x8,0x17,0x11,0x31,0x52,0x95,0x11,0x10,0x10,0x10,0x10,0x11,0x12,0x1c,0x80,0x40,0x48,0xfc,0x20,0x10,0xc,0x14,0x10,0xa0,0x40,0xa0,0xa0,0x10,0xe,0x4,
-+0x8,0x8,0x8,0x17,0x14,0x38,0x51,0x91,0x13,0x15,0x19,0x11,0x11,0x11,0x11,0x11,0x40,0x40,0x40,0xfe,0x82,0x84,0x40,0x48,0x30,0x20,0x10,0x10,0x8,0x4e,0x84,0x0,
-+0x8,0x8,0x9,0x12,0x17,0x32,0x52,0x93,0x14,0x10,0x1f,0x10,0x10,0x10,0x10,0x10,0x80,0x80,0x10,0x8,0xfc,0x44,0x50,0xf8,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x8,0x8,0xf,0x10,0x17,0x31,0x5f,0x91,0x12,0x13,0x15,0x18,0x10,0x10,0x10,0x10,0x80,0x88,0xfc,0x80,0xf8,0x0,0xfe,0x10,0x14,0xfe,0x10,0x90,0x90,0x10,0x50,0x20,
-+0x8,0xf,0x8,0x14,0x12,0x30,0x57,0x94,0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x18,0x8,0xfc,0xa0,0xa4,0xa8,0xa0,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x8,0x8,0xf,0x10,0x10,0x37,0x54,0x94,0x16,0x15,0x14,0x14,0x14,0x14,0x14,0x15,0x0,0x4,0xfe,0x0,0x4,0xbe,0xa4,0xa4,0xb4,0xac,0xa4,0xa4,0xa4,0xa4,0xa4,0xac,
-+0x8,0x8,0x8,0x10,0x17,0x30,0x54,0x92,0x12,0x10,0x11,0x12,0x14,0x10,0x11,0x10,0x40,0x50,0x48,0x48,0xfe,0x40,0x48,0x50,0x60,0xd0,0x50,0x48,0x4e,0x44,0x40,0x80,
-+0x8,0x8,0xf,0x14,0x14,0x37,0x54,0x94,0x17,0x14,0x10,0x17,0x10,0x10,0x1f,0x10,0x0,0x4,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x44,0x40,0xfc,0x40,0x44,0xfe,0x0,
-+0x8,0xb,0xa,0x12,0x12,0x33,0x50,0x97,0x10,0x10,0x1f,0x10,0x10,0x11,0x12,0x1c,0x8,0xfc,0x8,0x8,0x8,0xf8,0x0,0xfc,0x40,0x44,0xfe,0xa0,0xa0,0x10,0xe,0x4,
-+0x8,0x8,0xb,0x12,0x13,0x32,0x53,0x90,0x1f,0x11,0x11,0x10,0x10,0x10,0x10,0x10,0x40,0x48,0xfc,0x48,0xf8,0x48,0xf8,0x0,0xfe,0x0,0xf8,0x8,0x8,0x88,0x50,0x20,
-+0x8,0xb,0x8,0x10,0x10,0x37,0x54,0x94,0x17,0x14,0x14,0x17,0x14,0x14,0x14,0x14,0x0,0xf8,0x10,0xa0,0x44,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x44,0x44,0x54,0x8,
-+0x8,0x8,0x9,0x12,0x17,0x31,0x51,0x91,0x12,0x14,0x1f,0x10,0x10,0x10,0x11,0x16,0x80,0x80,0x10,0x8,0xfc,0x4,0x0,0xf8,0x40,0x44,0xfe,0x40,0xa0,0x90,0xe,0x4,
-+0x8,0x8,0xf,0x10,0x13,0x30,0x5f,0x91,0x12,0x15,0x18,0x10,0x17,0x10,0x10,0x10,0x40,0x48,0xfc,0x40,0xf8,0x80,0xfe,0x10,0x48,0xfe,0x44,0x40,0xfc,0x40,0x40,0x40,
-+0x8,0x8,0xf,0x10,0x13,0x30,0x5f,0x90,0x13,0x12,0x13,0x12,0x13,0x12,0x12,0x12,0x40,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x28,0x10,
-+0x9,0x9,0xf,0x11,0x11,0x30,0x5f,0x91,0x11,0x12,0x13,0x16,0x1a,0x12,0x13,0x12,0x10,0x10,0xfc,0x10,0x90,0x84,0xfe,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x8,0x8,0x8,0x17,0x10,0x30,0x50,0x97,0x10,0x10,0x10,0x1f,0x10,0x10,0x10,0x10,0xa0,0xa0,0xa4,0xbe,0xa0,0xa0,0xa8,0xbc,0xa0,0xa0,0xa4,0xbe,0xa0,0xa0,0xa0,0xa0,
-+0x8,0x8,0x8,0x10,0x13,0x32,0x53,0x92,0x13,0x12,0x10,0x1f,0x10,0x10,0x10,0x10,0x40,0x48,0x7c,0x40,0xf8,0x8,0xf8,0x8,0xf8,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,
-+0x11,0x11,0x11,0x29,0x2a,0x6c,0xa8,0x29,0x2e,0x28,0x2f,0x28,0x20,0x20,0x21,0x26,0x0,0x8,0xfc,0x10,0xa0,0x40,0xb0,0x4e,0x50,0x48,0xfc,0x40,0xa0,0x90,0xe,0x4,
-+0x8,0xf,0xc,0x14,0x17,0x34,0x54,0x97,0x14,0x10,0x1f,0x10,0x11,0x12,0x1c,0x10,0x4,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x44,0x40,0xfe,0xe0,0x50,0x4e,0x44,0x40,
-+0x8,0xb,0x8,0x10,0x17,0x31,0x52,0x94,0x10,0x1f,0x11,0x12,0x11,0x10,0x11,0x16,0x18,0xe0,0x40,0x48,0xfc,0x50,0x48,0x46,0x80,0xfe,0x10,0x10,0xa0,0x40,0xb0,0x8,
-+0x8,0x9,0xb,0x12,0x12,0x33,0x52,0x92,0x13,0x10,0x11,0x1f,0x10,0x10,0x10,0x10,0x80,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0xa0,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x8,0xf,0xc,0x14,0x17,0x34,0x54,0x95,0x14,0x15,0x15,0x15,0x15,0x14,0x14,0x18,0x4,0xfe,0x44,0x54,0xfc,0x44,0x44,0xf4,0x4,0xf4,0x14,0x14,0xf4,0x4,0x14,0x8,
-+0x8,0x8,0xb,0x12,0x14,0x33,0x52,0x92,0x13,0x12,0x13,0x12,0x12,0x12,0x13,0x12,0x80,0x40,0xfe,0x2,0x4,0xf8,0x8,0x8,0xf8,0x0,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x8,0x8,0x8,0x17,0x14,0x39,0x52,0x94,0x10,0x13,0x10,0x10,0x10,0x10,0x1f,0x10,0x80,0x40,0x40,0xfe,0x2,0x14,0x8,0x4,0x10,0xf8,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x8,0xb,0xa,0x12,0x13,0x32,0x52,0x93,0x12,0x12,0x13,0x13,0x15,0x15,0x19,0x11,0x4,0xfe,0x4,0x4,0xfc,0x24,0x20,0xfe,0x20,0x24,0xfe,0x4,0x4,0x4,0xfc,0x4,
-+0x8,0x8,0xf,0x10,0x11,0x3f,0x51,0x90,0x13,0x12,0x12,0x12,0x12,0x10,0x11,0x16,0x40,0x48,0xfc,0x40,0x54,0xfe,0x10,0x8,0xfc,0x8,0x48,0x48,0x48,0xb0,0xc,0x4,
-+0x8,0xf,0xc,0x15,0x15,0x35,0x55,0x95,0x14,0x17,0x14,0x14,0x14,0x14,0x17,0x10,0x4,0xfe,0x0,0xfc,0x4,0xfc,0x4,0xfc,0x40,0xfe,0x48,0x90,0x70,0x88,0xfe,0x0,
-+0xa,0xa,0xb,0x12,0x12,0x33,0x56,0x90,0x13,0x12,0x12,0x13,0x12,0x12,0x13,0x12,0x20,0x24,0xac,0x30,0xa2,0x22,0x5e,0x88,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x8,0xb,0xa,0x13,0x12,0x33,0x51,0x91,0x13,0x14,0x1a,0x12,0x12,0x13,0x10,0x10,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0x4,0xfe,0x44,0x44,0xa4,0x4,0xe4,0x14,0x8,
-+0x8,0xb,0xa,0x12,0x13,0x32,0x52,0x93,0x10,0x1f,0x12,0x12,0x12,0x12,0x13,0x12,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x4,0xfe,0x88,0x50,0x20,0x90,0xe,0x4,
-+0x9,0x9,0x9,0x12,0x13,0x34,0x59,0x92,0x14,0x11,0x10,0x15,0x15,0x19,0x10,0x10,0x0,0x4,0xfe,0xa4,0xa4,0xf4,0x2c,0x44,0x94,0x8,0x40,0x24,0x22,0xa,0xf8,0x0,
-+0x8,0xa,0x9,0x10,0x17,0x30,0x51,0x92,0x10,0x1f,0x11,0x12,0x11,0x10,0x11,0x16,0x40,0x48,0x50,0x40,0xfc,0xe0,0x50,0x4c,0x80,0xfe,0x10,0x10,0x20,0xc0,0x30,0x8,
-+0x10,0x14,0x12,0x20,0x2f,0x68,0xb7,0x24,0x24,0x24,0x27,0x25,0x21,0x21,0x22,0x2c,0x80,0x90,0xa0,0x80,0xfc,0x4,0xf8,0x10,0x10,0x10,0xf0,0x50,0x40,0x44,0x44,0x3c,
-+0x8,0x8,0xb,0x12,0x14,0x31,0x51,0x91,0x11,0x11,0x11,0x1f,0x10,0x10,0x11,0x16,0x80,0x40,0xfe,0x2,0x34,0xc0,0x8,0xfc,0x10,0x10,0x14,0xfe,0x0,0x90,0xc,0x4,
-+0x10,0x10,0x10,0x2f,0x21,0x71,0xaa,0x2a,0x24,0x24,0x2a,0x29,0x31,0x20,0x20,0x20,0x20,0x30,0x28,0x7e,0x48,0xc8,0x7e,0x48,0x48,0x7e,0x48,0x48,0x48,0x7e,0x40,0x40,
-+0xa,0xa,0xb,0x14,0x1a,0x35,0x53,0x92,0x14,0x18,0x17,0x11,0x12,0x14,0x11,0x10,0x0,0x20,0xbc,0xa4,0xa8,0x10,0x10,0xe8,0x6,0x0,0xfc,0x50,0x4c,0x44,0x40,0x80,
-+0x8,0xf,0x8,0x13,0x10,0x33,0x52,0x93,0x11,0x1f,0x10,0x13,0x12,0x12,0x13,0x12,0x48,0xfc,0x40,0xf8,0x0,0xf8,0x8,0xf8,0x10,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,
-+0x15,0x15,0x1f,0x25,0x25,0x68,0xaf,0x28,0x30,0x2e,0x2a,0x2a,0x2e,0x20,0x22,0x21,0x20,0x20,0xa0,0x24,0x7e,0x84,0xc4,0xc4,0xa8,0xa8,0xa8,0x90,0xa8,0xa8,0xc6,0x4,
-+0x11,0x1f,0x1a,0x2a,0x2f,0x62,0xa6,0x2a,0x33,0x20,0x27,0x24,0x27,0x24,0x27,0x24,0x4,0xbe,0x28,0x28,0xbe,0x8,0x18,0xaa,0x4e,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,
-+0x9,0x9,0x9,0x12,0x16,0x3b,0x52,0x92,0x13,0x12,0x12,0x13,0x12,0x15,0x14,0x18,0x40,0x24,0xfe,0x20,0x28,0xfc,0x20,0x28,0xfc,0x20,0x24,0xfe,0x0,0x24,0x92,0x2,
-+0x14,0x12,0x12,0x3f,0x20,0x6f,0xa8,0x28,0x28,0x2f,0x22,0x2b,0x2a,0x32,0x26,0x20,0x10,0x10,0x98,0xd4,0x10,0xfe,0x90,0x90,0x98,0x98,0x28,0x28,0xa8,0xca,0x4a,0x86,
-+0x8,0xf,0x9,0x10,0x1f,0x30,0x57,0x94,0x17,0x14,0x17,0x10,0x17,0x10,0x1f,0x10,0x40,0xfc,0x10,0xa4,0xfe,0x0,0xfc,0x44,0xfc,0x44,0xfc,0x40,0xfc,0x40,0xfe,0x0,
-+0x8,0xf,0xc,0x14,0x17,0x30,0x5f,0x90,0x13,0x12,0x13,0x10,0x11,0x13,0x1d,0x11,0x4,0xfe,0xa4,0xa4,0xfc,0x0,0xfe,0x8,0xfc,0x8,0xf8,0xc4,0x28,0x10,0x8e,0x4,
-+0x9,0x9,0xa,0x17,0x14,0x35,0x57,0x94,0x15,0x14,0x15,0x14,0x15,0x15,0x19,0x11,0x0,0xf8,0x10,0xfe,0x88,0x24,0xfe,0x0,0xfc,0x0,0xfc,0x0,0xfc,0x4,0xfc,0x4,
-+0x1,0x1,0x2,0x4,0x8,0x10,0x20,0xc0,0x1f,0x1,0x1,0x1,0x1,0x1,0x7f,0x0,0x0,0x0,0x80,0x40,0x20,0x10,0xe,0x24,0xf0,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,
-+0x1,0x1,0x2,0x4,0x9,0x31,0xc1,0x3d,0x5,0x9,0x9,0x11,0x21,0x41,0x5,0x2,0x0,0x0,0x80,0x40,0x30,0xe,0x4,0x90,0x60,0x40,0x20,0x10,0xe,0x4,0x0,0x0,
-+0x1,0x1,0x2,0x4,0x8,0x30,0xcf,0x0,0x0,0x7f,0x1,0x9,0x19,0x21,0x45,0x2,0x0,0x0,0x80,0x40,0x30,0x4e,0xe4,0x0,0x8,0xfc,0x0,0x20,0x18,0xc,0x4,0x0,
-+0x1,0x1,0x2,0x4,0x8,0x10,0x2f,0xc0,0x12,0x9,0x9,0x9,0x8,0x0,0xff,0x0,0x0,0x0,0x80,0x40,0x20,0x50,0xee,0x4,0x10,0x10,0x20,0x20,0x40,0x84,0xfe,0x0,
-+0x10,0x11,0x11,0x29,0x29,0x45,0x95,0x11,0x11,0x29,0x29,0x45,0x45,0x81,0xf,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0xfe,0x0,
-+0x1,0x1,0x2,0xc,0x37,0xc0,0x3b,0x2a,0x3b,0x0,0x3f,0x24,0x3f,0x24,0x24,0x20,0x0,0x0,0x80,0x60,0xd8,0x6,0xb8,0xa8,0xb8,0x0,0xf8,0x48,0xf8,0x48,0x48,0x18,
-+0x6,0x1,0x2,0xc,0x31,0xc1,0x1,0x3d,0x5,0x9,0x9,0x11,0x21,0x41,0x5,0x2,0x0,0x0,0x80,0x60,0x18,0x6,0x0,0x90,0x60,0x40,0x20,0x10,0xe,0x4,0x0,0x0,
-+0x6,0x1,0x2,0xc,0x31,0xc1,0x11,0x9,0x1,0x7f,0x3,0x5,0x9,0x11,0x61,0x1,0x0,0x0,0x80,0x60,0x18,0x6,0x10,0x20,0x8,0xfc,0x80,0x40,0x20,0x1c,0x8,0x0,
-+0x4,0x4,0x8,0x8,0x10,0x20,0x5f,0x88,0x8,0x1f,0x0,0x0,0x0,0x2,0x1,0x0,0x40,0x40,0x20,0x20,0x10,0x58,0xee,0x4,0x20,0xf0,0x20,0x20,0x20,0x20,0x40,0x80,
-+0x0,0x3e,0x22,0x22,0x3e,0x20,0x22,0x1e,0x4,0x3f,0x4,0x4,0xff,0x4,0x18,0x20,0x8,0xfc,0x88,0x88,0xf8,0x80,0x84,0x7c,0x40,0xf8,0x40,0x44,0xfe,0x40,0x30,0x8,
-+0x22,0x11,0x7f,0x44,0x9f,0x4,0xff,0x1,0x1f,0x11,0x1f,0x11,0x1f,0x4,0x18,0x20,0x8,0x10,0xfe,0x42,0xf4,0x40,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x40,0x30,0x8,
-+0x0,0x44,0x28,0xff,0x10,0x20,0x7d,0x45,0x45,0x7d,0x45,0x7c,0x44,0x47,0x7c,0x44,0x10,0x18,0x14,0xfe,0x10,0x10,0xd4,0x54,0x54,0x54,0xd4,0x18,0xd2,0x2a,0x46,0x82,
-+0x44,0x25,0x29,0x7d,0x55,0x55,0x7d,0x55,0x55,0x7d,0x12,0xfe,0x12,0x14,0x18,0x10,0x4,0xfe,0x4,0x4,0xfc,0x48,0xfc,0x48,0x48,0xfe,0xa4,0xa8,0x90,0x88,0xc6,0x80,
-+0x4,0xff,0x1,0x17,0x54,0x5f,0x54,0x57,0x5c,0xe7,0x14,0x27,0x4c,0x13,0xc,0x70,0x40,0xfe,0x0,0xdc,0x54,0xd4,0x5c,0xd0,0x52,0xce,0x10,0xc8,0x44,0x80,0x60,0x1c,
-+0x10,0x10,0x1f,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x10,0x10,0x1f,0x22,0x42,0xbf,0x2,0x3f,0x22,0x3f,0x22,0x3f,0x22,0x22,0x22,0x0,0x0,0x4,0xfe,0x84,0x44,0xf4,0x4,0xe4,0x24,0xe4,0x24,0xe4,0x24,0x64,0x34,0x8,
-+0x10,0x10,0x1f,0x24,0x42,0xbf,0x0,0x1f,0x0,0x1f,0x0,0x1f,0x10,0x10,0x1f,0x0,0x0,0x4,0xfe,0x4,0x44,0xe4,0x4,0xc4,0x4,0xc4,0x4,0xc4,0x44,0x44,0xd4,0x8,
-+0x10,0x10,0x1f,0x20,0x7f,0x80,0x1f,0x10,0x1f,0x0,0x3f,0x22,0x3f,0x22,0x3f,0x0,0x0,0x4,0xfe,0x44,0xe4,0x4,0xc4,0x44,0xc4,0x4,0xe4,0x24,0xe4,0x24,0xf4,0x8,
-+0x2,0x4,0x3f,0x20,0x24,0x22,0x20,0x3f,0x0,0xf,0x8,0x8,0x8,0x10,0x20,0xc0,0x0,0x20,0xf0,0x20,0x20,0xa0,0x48,0xfc,0x8,0xa8,0x90,0x80,0x80,0x82,0x82,0x7e,
-+0x0,0x3f,0x20,0x20,0x2f,0x22,0x22,0x27,0x24,0x2c,0x32,0x21,0x22,0x44,0x48,0x80,0x10,0xf8,0x10,0x90,0xd0,0x10,0x10,0xd0,0x50,0x50,0x90,0x10,0x12,0x12,0xa,0x4,
-+0x0,0x3c,0x24,0x24,0x27,0x20,0x20,0x3f,0x24,0x4,0x4,0x4,0x8,0x10,0x20,0x40,0x8,0x7c,0x48,0x48,0xc8,0x8,0x8,0xf8,0x48,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x0,0x0,0x0,0x0,0x2,0x1,0x1,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x2,0x1,0xff,0x8,0x12,0x22,0x44,0x8,0x1f,0x4,0x4,0x4,0x4,0x8,0x10,0x60,0x0,0x4,0xfe,0x20,0x18,0xc,0x44,0x20,0xf0,0x90,0x80,0x80,0x84,0x84,0x7c,0x0,
-+0x1,0xff,0x0,0x1f,0x10,0x1f,0x40,0x7f,0x40,0x9f,0x1,0x1,0x3f,0x1,0x1,0x0,0x0,0xfe,0x0,0xf0,0x10,0xf0,0x0,0xfe,0x12,0xe4,0x0,0xf8,0x0,0x4,0x4,0xfc,
-+0x2,0x1,0xff,0x8,0x12,0x22,0x44,0x1f,0x2,0x6,0xd,0x14,0x24,0xc5,0x6,0x4,0x0,0x4,0xfe,0x20,0x18,0x4c,0x24,0xf0,0x0,0x18,0x10,0xa0,0x40,0x30,0xe,0x4,
-+0x1,0xff,0x0,0x1f,0x2,0x1,0x7f,0x4,0x8,0x32,0x1,0x2,0xc,0x15,0x66,0x4,0x0,0xfe,0x0,0xf0,0x40,0x80,0xfc,0x84,0x88,0x80,0x10,0xa0,0x40,0x30,0xe,0x4,
-+0x1,0xff,0x8,0x8,0x7e,0x8,0xe,0x78,0x9,0x1a,0x1,0x2,0xc,0x15,0x66,0x4,0x0,0xfe,0x40,0x48,0xfc,0x48,0xc8,0xa8,0xa,0x6,0x10,0xa0,0x40,0x30,0xe,0x4,
-+0x1,0xff,0x4,0x14,0x24,0x45,0x1,0x3f,0x22,0x24,0x29,0x22,0x24,0x28,0x20,0x20,0x0,0xfe,0x40,0x50,0x4c,0x44,0x0,0xf8,0x88,0x68,0x28,0x88,0x68,0x28,0x28,0x10,
-+0x1,0xff,0x2,0x1c,0x10,0x10,0x1c,0x10,0x10,0x1f,0x5,0x8,0x18,0x2a,0xcc,0x8,0x0,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x8,0x90,0x60,0x30,0xe,0x4,
-+0x1,0xff,0x0,0x3f,0x24,0x27,0x24,0x3f,0x0,0x3f,0x0,0xff,0x9,0x11,0x21,0x3,0x0,0xfe,0x8,0xfc,0x48,0xc8,0x48,0xf8,0x0,0xf8,0x0,0xfe,0x20,0x18,0x8,0x0,
-+0x1,0xff,0x20,0x3f,0x0,0x1f,0x10,0x1f,0x79,0x49,0x7f,0x4a,0x7a,0x49,0x4e,0x98,0x0,0xfe,0x0,0xf8,0x0,0xf0,0x10,0xf0,0x38,0x28,0xe8,0xb8,0xa8,0x2a,0xea,0x46,
-+0x1,0xff,0x20,0x3f,0x0,0x1f,0x10,0x1f,0x71,0x57,0x75,0x57,0x71,0x51,0x57,0xb0,0x0,0xfe,0x0,0xf8,0x0,0xf0,0x10,0xf0,0x1c,0xd4,0x54,0xdc,0x14,0x54,0xd4,0x22,
-+0x1,0xff,0x20,0x3f,0x0,0x1f,0x10,0x1f,0x7a,0x4f,0x79,0x4f,0x79,0x4f,0x49,0x99,0x0,0xfe,0x0,0xf8,0x0,0xf0,0x10,0xf0,0xb8,0xe8,0x28,0xe8,0x38,0xea,0x2a,0x46,
-+0x0,0x40,0x20,0x10,0x10,0x0,0x0,0x10,0x20,0x20,0xe0,0x20,0x20,0x20,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x4f,0x22,0x12,0x12,0x3,0x2,0x12,0x22,0x22,0xe7,0x20,0x20,0x20,0x2f,0x0,0x8,0xfc,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0xf0,0x20,0x20,0x44,0xfe,0x0,
-+0x0,0x4f,0x22,0x12,0x13,0x2,0x14,0x14,0x26,0x29,0xe0,0x21,0x22,0x24,0x28,0x0,0x44,0xe4,0x4,0x14,0xd4,0x54,0x54,0x54,0x54,0x94,0x94,0x14,0x4,0x4,0x14,0x8,
-+0x0,0x42,0x22,0x13,0x12,0x4,0x0,0x17,0x21,0x21,0xe1,0x21,0x22,0x22,0x24,0x8,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x20,0x20,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x2,0x42,0x22,0x22,0x1f,0x2,0x26,0x27,0x2a,0x4a,0xd2,0x42,0x42,0x42,0x42,0x2,0x0,0x28,0x28,0x28,0xc4,0x44,0x92,0x10,0x90,0xa0,0x20,0x48,0x44,0xfe,0x2,0x0,
-+0x0,0x0,0x0,0x0,0x40,0x7f,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe,0x2,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x7f,0x40,0x80,0x3f,0x6,0x9,0x1a,0x74,0xb,0x16,0x64,0x8,0x10,0x62,0x1,0x0,0xfe,0x2,0x24,0xf0,0x0,0x8,0x90,0xe0,0xa0,0xa0,0x90,0x8e,0x84,0x80,0x0,
-+0x40,0x7f,0x40,0x80,0x1f,0x10,0x1f,0x10,0x1f,0x12,0x1,0xff,0x0,0x8,0x10,0x20,0x0,0xfe,0x2,0x14,0xf8,0x10,0xf0,0x10,0xf0,0x10,0x4,0xfe,0x0,0x20,0x18,0x8,
-+0x0,0x40,0x30,0x10,0x0,0x0,0xf0,0x10,0x10,0x10,0x10,0x10,0x14,0x18,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x47,0x30,0x10,0x0,0x0,0xf0,0x17,0x10,0x10,0x10,0x10,0x14,0x18,0x10,0x0,0x8,0xfc,0x40,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x40,0x37,0x10,0x0,0x0,0xf0,0x10,0x10,0x10,0x10,0x12,0x14,0x1f,0x10,0x0,0x0,0x8,0xfc,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,0x0,
-+0x0,0x40,0x20,0x20,0x4,0x4,0xe4,0x24,0x24,0x24,0x24,0x24,0x2c,0x37,0x20,0x0,0x40,0x40,0x40,0x40,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0xfc,0x4,0x0,
-+0x0,0x47,0x24,0x24,0x5,0x4,0xe4,0x24,0x24,0x24,0x25,0x26,0x2c,0x34,0x27,0x0,0x8,0xfc,0x0,0x4,0x4,0x88,0x50,0x20,0x50,0x88,0xc,0x4,0x0,0x4,0xfe,0x0,
-+0x0,0x43,0x32,0x12,0x2,0x3,0xf2,0x12,0x12,0x13,0x12,0x12,0x16,0x1a,0x13,0x0,0x8,0xfc,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x4,0xfe,0x0,
-+0x0,0x40,0x20,0x20,0x7,0x4,0xe4,0x24,0x24,0x24,0x25,0x25,0x2e,0x34,0x24,0x4,0x40,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0xa4,0xa4,0x14,0x14,0xc,0x4,0x14,0x8,
-+0x0,0x40,0x30,0x10,0x7,0x0,0xf0,0x10,0x13,0x12,0x12,0x12,0x16,0x1a,0x13,0x2,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x48,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x40,0x37,0x10,0x0,0x3,0xf2,0x12,0x12,0x12,0x13,0x10,0x14,0x18,0x10,0x0,0x0,0x4,0xfe,0x8,0x48,0xe8,0x48,0x48,0x48,0x48,0xc8,0x8,0x8,0x8,0x28,0x10,
-+0x0,0x40,0x27,0x24,0x4,0x4,0xe7,0x24,0x24,0x24,0x24,0x24,0x2d,0x36,0x24,0x0,0x10,0x78,0xc0,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0x20,0xa0,0x12,0x92,0x4a,0x6,
-+0x0,0x47,0x30,0x10,0x0,0x1,0xf1,0x12,0x14,0x11,0x11,0x11,0x15,0x19,0x11,0x1,0x4,0xfe,0x84,0x84,0x84,0x4,0x14,0x8,0x0,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x40,0x22,0x22,0x2,0x2,0xe2,0x23,0x20,0x24,0x24,0x24,0x2c,0x34,0x27,0x0,0x40,0x40,0x48,0x48,0x48,0x48,0x48,0xf8,0x40,0x44,0x44,0x44,0x44,0x44,0xfc,0x4,
-+0x0,0x40,0x30,0x11,0x2,0x7,0xf0,0x10,0x13,0x12,0x12,0x12,0x16,0x1a,0x13,0x2,0x40,0x40,0x80,0x8,0x4,0xfe,0x2,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x43,0x32,0x12,0x3,0x2,0xf2,0x12,0x12,0x12,0x12,0x13,0x16,0x1a,0x13,0x0,0x8,0xfc,0x0,0x8,0xfc,0x20,0x20,0xf8,0x20,0x20,0x28,0xfc,0x0,0x4,0xfe,0x0,
-+0x0,0x40,0x37,0x10,0x0,0x3,0xf0,0x10,0x1f,0x10,0x10,0x15,0x19,0x12,0x4,0x0,0x40,0x48,0xfc,0x40,0x50,0xf8,0x40,0x44,0xfe,0xc0,0xe0,0x50,0x48,0x4e,0x44,0x40,
-+0x0,0x40,0x33,0x10,0x0,0x0,0xf7,0x10,0x10,0x10,0x13,0x10,0x14,0x18,0x17,0x0,0x40,0x50,0xf8,0x40,0x40,0x48,0xfc,0x0,0x40,0x50,0xf8,0x40,0x40,0x44,0xfe,0x0,
-+0x0,0x40,0x30,0x1f,0x0,0x0,0xf7,0x10,0x10,0x13,0x12,0x12,0x16,0x1a,0x13,0x2,0x40,0x40,0x44,0xfe,0x40,0x48,0xfc,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x40,0x30,0x17,0x1,0x1,0xf1,0x12,0x12,0x14,0x19,0x10,0x14,0x18,0x11,0x2,0x80,0x80,0x84,0xfe,0x0,0x20,0x20,0xa4,0xac,0xb0,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x0,0x42,0x32,0x13,0x4,0x0,0xf0,0x1f,0x11,0x11,0x11,0x15,0x1a,0x12,0x4,0x8,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x10,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x0,0x40,0x33,0x12,0x2,0x3,0xf2,0x12,0x12,0x12,0x12,0x16,0x1a,0x12,0x4,0x8,0x8,0x1c,0xe0,0x0,0x4,0xfe,0x0,0x4,0xfe,0x84,0x84,0x84,0x84,0x84,0xfc,0x84,
-+0x0,0x40,0x30,0x11,0x2,0xc,0xf3,0x10,0x10,0x10,0x13,0x10,0x14,0x18,0x17,0x0,0x40,0x40,0xa0,0x10,0xe,0x4,0xf8,0x40,0x40,0x50,0xf8,0x40,0x40,0x48,0xfc,0x0,
-+0x1,0x41,0x31,0x12,0x4,0xb,0xf0,0x10,0x1f,0x10,0x10,0x13,0x14,0x18,0x11,0x0,0x0,0x0,0xf0,0x20,0x48,0xfc,0x48,0x48,0xfe,0x48,0x48,0xf8,0x48,0x40,0x40,0x80,
-+0x0,0x47,0x34,0x18,0x7,0x1,0xf1,0x12,0x17,0x10,0x10,0x1f,0x10,0x14,0x18,0x0,0x0,0xfc,0x84,0x88,0xfc,0x0,0x40,0x48,0xfc,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,
-+0x0,0x40,0x37,0x10,0x0,0x4,0xf2,0x12,0x10,0x11,0x16,0x10,0x14,0x18,0x12,0x1,0x0,0x4,0xbe,0x84,0x84,0xa4,0x94,0x94,0x84,0x8c,0xb4,0x84,0x84,0x84,0x94,0x8,
-+0x0,0x42,0x31,0x11,0x0,0x3,0xf2,0x12,0x13,0x12,0x12,0x13,0x16,0x1a,0x12,0x2,0x40,0x48,0x58,0x60,0x48,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x0,0x42,0x32,0x13,0x4,0x8,0xf7,0x10,0x10,0x13,0x12,0x12,0x16,0x1a,0x13,0x2,0x40,0x40,0x48,0xfc,0x40,0x44,0xfe,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x8,0x45,0x32,0x15,0x9,0x1,0xf1,0x13,0x15,0x19,0x11,0x11,0x15,0x19,0x15,0x2,0x80,0x4,0xfe,0x10,0x10,0x10,0x10,0x10,0x7c,0x10,0x10,0x10,0x10,0x14,0xfe,0x0,
-+0x0,0x40,0x31,0x12,0x7,0x1,0xf1,0x11,0x12,0x10,0x1f,0x10,0x14,0x18,0x11,0x6,0x80,0x80,0x10,0x8,0xfc,0x4,0x10,0xf8,0x40,0x44,0xfe,0x40,0xa0,0x90,0xe,0x4,
-+0x0,0x5f,0x24,0x24,0x7,0x4,0xe4,0x27,0x24,0x24,0x24,0x2f,0x28,0x30,0x20,0x0,0x4,0xfe,0x80,0x80,0xbe,0x82,0xa2,0x94,0x94,0x94,0x88,0xc8,0x94,0x94,0xa2,0xc0,
-+0x0,0x4f,0x20,0x21,0x3,0x4,0xe8,0x25,0x22,0x26,0x29,0x21,0x2a,0x34,0x21,0x0,0x4,0xfe,0x80,0x0,0x4,0x8c,0xd0,0x60,0x60,0x50,0xd0,0x48,0x4e,0x44,0x40,0x80,
-+0x0,0x43,0x30,0x10,0x7,0x1,0xf2,0x14,0x10,0x1f,0x11,0x11,0x14,0x18,0x11,0x6,0x3c,0xc0,0x40,0x48,0xfc,0x50,0x4e,0x44,0x80,0xfe,0x10,0x10,0xa0,0x60,0x98,0x4,
-+0x0,0x41,0x36,0x14,0x4,0x7,0xf4,0x14,0x17,0x14,0x10,0x10,0x15,0x19,0x12,0xc,0x40,0x44,0x5e,0x44,0x44,0x5c,0x44,0x44,0xfc,0x44,0xa0,0xa0,0x10,0x8,0xe,0x4,
-+0x0,0x40,0x20,0x21,0x2,0x4,0xe8,0x23,0x20,0x20,0x21,0x2d,0x35,0x25,0x9,0x0,0x40,0x40,0xa0,0x10,0x88,0x46,0x4,0xf0,0x10,0x20,0x0,0x48,0x24,0x4,0x10,0xf0,
-+0x0,0x40,0x30,0x11,0x2,0x4,0xf0,0x13,0x12,0x12,0x13,0x12,0x16,0x1a,0x13,0x2,0x80,0x80,0xfc,0x8,0x10,0x20,0x84,0x3e,0x4,0x4,0xbc,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x40,0x37,0x11,0x1,0x1,0xf2,0x14,0x10,0x1f,0x10,0x10,0x14,0x18,0x10,0x0,0x80,0x48,0xfc,0x10,0x10,0x10,0xa8,0x44,0x40,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x1,0x41,0x37,0x11,0x1,0x1,0xf1,0x11,0x11,0x1f,0x12,0x12,0x17,0x1a,0x13,0x0,0x10,0x10,0xfc,0x10,0xf0,0x10,0xf0,0x10,0x14,0xfe,0x0,0x90,0x8,0x0,0xfc,0x0,
-+0x0,0x40,0x2f,0x20,0x7,0x4,0xe5,0x24,0x24,0x27,0x21,0x29,0x32,0x24,0x8,0x0,0x40,0x44,0xfe,0x40,0xfc,0x44,0x54,0xe4,0x44,0xfc,0x60,0x50,0x48,0x4e,0x44,0x40,
-+0x0,0x40,0x20,0x27,0x4,0x4,0xe7,0x24,0x24,0x24,0x25,0x2d,0x37,0x29,0x9,0x10,0x48,0x7c,0x40,0xfe,0x42,0x7c,0xc0,0x44,0x7c,0x0,0xfc,0x0,0xfe,0x0,0xfc,0x0,
-+0x0,0x43,0x22,0x23,0x2,0x3,0xe1,0x23,0x24,0x28,0x22,0x23,0x2a,0x33,0x20,0x0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x4,0xfe,0x44,0x44,0xb4,0x14,0x4,0xf4,0x14,0x8,
-+0x0,0x47,0x24,0x24,0x7,0x0,0xe3,0x20,0x2f,0x21,0x21,0x24,0x28,0x30,0x20,0x0,0x4,0xbe,0xa4,0xa4,0xbc,0x0,0xf8,0x0,0xfe,0x0,0xf8,0x8,0x8,0x88,0x50,0x20,
-+0x0,0x40,0x21,0x22,0x4,0xb,0xf0,0x27,0x24,0x27,0x24,0x27,0x2c,0x34,0x24,0x5,0x80,0x80,0x40,0x20,0x10,0xee,0x4,0x88,0xa8,0xa8,0xa8,0xa8,0xa8,0x88,0xa8,0x90,
-+0x0,0x47,0x20,0x22,0x1,0xf,0xe0,0x20,0x2f,0x21,0x21,0x2b,0x32,0x24,0x8,0x3,0x3c,0xc0,0x88,0x48,0x50,0xfc,0x80,0x84,0xfe,0x0,0xf0,0x10,0xa0,0x40,0xb0,0xc,
-+0x0,0x40,0x37,0x12,0x1,0x0,0xf7,0x10,0x13,0x12,0x12,0x13,0x16,0x1a,0x13,0x2,0x80,0x48,0xfc,0x10,0x10,0xa4,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x0,0x40,0x37,0x11,0x0,0x7,0xf4,0x18,0x13,0x12,0x12,0x12,0x16,0x1a,0x10,0x0,0x80,0x48,0xfc,0x10,0xa0,0xfe,0x42,0x44,0xf8,0x48,0x48,0x48,0x48,0x58,0x40,0x40,
-+0x0,0x48,0x24,0x24,0x1,0x6,0xe8,0x30,0x21,0x22,0x27,0x22,0x2a,0x32,0x23,0x2,0x80,0x80,0x80,0xfc,0x4,0x48,0x40,0xa0,0x10,0xe,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x40,0x27,0x24,0x4,0x7,0xe4,0x24,0x27,0x24,0x2c,0x37,0x24,0x2c,0x34,0x4,0x80,0x48,0xfc,0x8,0x8,0xf8,0x0,0x4,0xfe,0xa4,0xa4,0xfc,0xa4,0xa4,0xb4,0x8,
-+0x1,0x41,0x37,0x11,0x0,0x3,0xf2,0x13,0x12,0x13,0x10,0x1f,0x10,0x19,0x12,0xc,0x10,0x14,0xfe,0x10,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x44,0xfe,0xa0,0x10,0xe,0x4,
-+0x0,0x42,0x21,0x2f,0x8,0x13,0xe2,0x22,0x22,0x23,0x20,0x21,0x29,0x32,0x24,0x8,0x40,0x48,0x50,0xfe,0x2,0xfc,0x8,0x8,0x8,0xf8,0xa0,0x20,0x22,0x22,0x1e,0x0,
-+0x0,0x47,0x24,0x27,0x4,0x7,0xe2,0x25,0x29,0x22,0x25,0x20,0x28,0x30,0x23,0xc,0x4,0xfe,0x44,0xfc,0x44,0xfc,0x8,0x4,0xfa,0x8,0x10,0xa0,0x40,0xb0,0xe,0x4,
-+0x4,0x42,0x21,0x2f,0x0,0x1,0xe2,0x24,0x23,0x22,0x22,0x22,0x2a,0x32,0x2f,0x0,0x4,0x8,0x10,0xfe,0x0,0x10,0xc,0x4,0xf8,0xa8,0xa8,0xa8,0xa8,0xa8,0xfe,0x0,
-+0x1,0x40,0x30,0x15,0x5,0x9,0xf1,0x12,0x14,0x13,0x12,0x12,0x16,0x1a,0x17,0x0,0x0,0xc8,0x48,0x14,0x22,0x42,0x88,0xf8,0x0,0xf8,0xa8,0xa8,0xa8,0xa8,0xfe,0x0,
-+0x0,0x40,0x2f,0x21,0x0,0x7,0xe4,0x24,0x27,0x24,0x25,0x25,0x2d,0x35,0x25,0x4,0x80,0x44,0xfe,0x10,0xa4,0xfe,0x44,0x54,0xfc,0x44,0xf4,0x14,0x14,0xf4,0x14,0x8,
-+0x1,0x40,0x37,0x10,0x3,0x2,0xf3,0x12,0x13,0x12,0x10,0x13,0x14,0x18,0x11,0x6,0x8,0x90,0xfe,0x0,0xd4,0x54,0xd4,0x54,0xc4,0x4c,0x0,0xfc,0x84,0x84,0x14,0x8,
-+0x2,0x4f,0x22,0x2a,0xf,0x2,0xe6,0x2b,0x32,0x20,0x23,0x22,0x2b,0x32,0x23,0x2,0x4,0xbe,0x8,0x28,0xbe,0x8,0x98,0x2a,0x4e,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,
-+0x1,0x41,0x23,0x22,0x6,0xb,0xe2,0x22,0x23,0x22,0x22,0x23,0x2a,0x35,0x24,0x8,0x40,0x24,0xfe,0x20,0x28,0xfc,0x20,0x28,0xfc,0x20,0x24,0xfe,0x0,0x24,0x92,0x2,
-+0x0,0x47,0x20,0x20,0xf,0x1,0xe2,0x2c,0x27,0x24,0x27,0x25,0x2d,0x35,0x24,0x4,0x0,0xf8,0x90,0x60,0xfe,0x44,0x40,0xc4,0xfe,0xa4,0x1c,0xf4,0x14,0xf4,0x14,0x8,
-+0x1,0x41,0x21,0x2f,0x1,0x1,0xef,0x2a,0x2a,0x2f,0x29,0x2f,0x29,0x39,0x28,0x0,0x8,0x8,0x4c,0xe8,0x3e,0x8,0xe8,0xa8,0xa8,0xe8,0x28,0xe8,0x28,0x74,0x24,0x42,
-+0x1,0x41,0x22,0x27,0xc,0x5,0xe7,0x24,0x25,0x24,0x25,0x2c,0x35,0x25,0x9,0x1,0x0,0xf8,0x10,0xfe,0x88,0x24,0xfe,0x0,0xfc,0x0,0xfc,0x0,0xfc,0x4,0xfc,0x4,
-+0x0,0x44,0x24,0x2b,0x0,0x1f,0xe2,0x2e,0x22,0x2e,0x22,0x2e,0x2a,0x32,0x2f,0x0,0x10,0x90,0x98,0x54,0x10,0xfe,0x90,0xf0,0x94,0xf4,0x94,0xe8,0x9a,0xaa,0xe6,0x2,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x3c,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x34,0x28,0x20,0x20,0x20,0x20,
-+0x1f,0x0,0x1,0x3d,0x5,0x9,0x33,0xc1,0x3f,0x0,0x1f,0x10,0x10,0x10,0x10,0xf,0xf0,0x40,0x88,0xb0,0x40,0x30,0xe,0x4,0xf8,0x10,0xf8,0x10,0x90,0x64,0x4,0xfc,
-+0x0,0x78,0x48,0x48,0x50,0x50,0x60,0x50,0x50,0x48,0x48,0x68,0x50,0x40,0x40,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x78,0x4f,0x49,0x51,0x51,0x61,0x51,0x51,0x49,0x49,0x69,0x52,0x42,0x44,0x48,0x0,0x4,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x0,0x7c,0x45,0x48,0x48,0x50,0x48,0x4b,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40,0x8,0x1c,0xe0,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x1,0x79,0x49,0x49,0x57,0x51,0x61,0x51,0x51,0x4f,0x49,0x69,0x51,0x42,0x42,0x44,0x10,0x10,0x10,0x10,0xfc,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x0,0x78,0x4b,0x4a,0x52,0x53,0x62,0x52,0x52,0x4a,0x4a,0x6a,0x54,0x44,0x49,0x42,0x8,0x3c,0xc0,0x0,0x8,0xfc,0x8,0x88,0x88,0x90,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x0,0x7c,0x44,0x48,0x48,0x50,0x48,0x49,0x45,0x45,0x45,0x69,0x51,0x41,0x41,0x41,0x40,0x40,0x44,0x7e,0x40,0x40,0x44,0xfe,0x4,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x1,0x7d,0x45,0x49,0x4a,0x52,0x4c,0x48,0x44,0x44,0x44,0x68,0x50,0x40,0x40,0x40,0x0,0x0,0x4,0xfe,0x80,0x80,0x88,0xfc,0x80,0x80,0x88,0xfc,0x80,0x80,0x80,0x80,
-+0x0,0x78,0x48,0x4b,0x52,0x52,0x62,0x53,0x52,0x4a,0x4a,0x6a,0x54,0x44,0x49,0x42,0x20,0x20,0x20,0xfe,0x22,0x24,0x20,0xf8,0x88,0x88,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x0,0x7b,0x48,0x48,0x50,0x50,0x61,0x56,0x50,0x4b,0x48,0x68,0x50,0x40,0x4f,0x40,0x0,0xf8,0x10,0x20,0x40,0xb0,0xc,0x4,0x10,0xf8,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x0,0x78,0x48,0x4f,0x50,0x50,0x61,0x53,0x51,0x48,0x48,0x6b,0x50,0x40,0x43,0x4c,0x80,0x40,0x44,0xfe,0x80,0x90,0x10,0xe0,0x28,0x48,0x90,0x10,0x20,0xd8,0x6,0x2,
-+0x0,0x78,0x49,0x49,0x51,0x51,0x67,0x50,0x51,0x49,0x4a,0x68,0x50,0x40,0x43,0x4c,0x40,0x48,0x7c,0x40,0x40,0x44,0xfe,0x40,0x48,0x48,0x50,0x60,0x40,0x80,0x0,0x0,
-+0x0,0x7b,0x4a,0x4a,0x53,0x52,0x62,0x53,0x52,0x48,0x4b,0x68,0x50,0x40,0x4f,0x40,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x48,0x40,0xf8,0x40,0x40,0x44,0xfe,0x0,
-+0x0,0x70,0x5f,0x54,0x54,0x57,0x64,0x54,0x57,0x54,0x54,0x5f,0x70,0x40,0x40,0x40,0x0,0x40,0xe0,0x80,0xbc,0x84,0xa4,0xa8,0xa8,0x90,0x90,0xe8,0xa8,0xc6,0x80,0x80,
-+0x0,0x78,0x4f,0x48,0x50,0x5f,0x61,0x51,0x57,0x49,0x49,0x6f,0x50,0x40,0x47,0x40,0x8,0x3c,0xc0,0x40,0x44,0xfe,0x50,0x50,0xfc,0x50,0x54,0xfe,0x40,0x48,0xfc,0x0,
-+0x0,0x79,0x4b,0x4a,0x52,0x53,0x62,0x52,0x53,0x48,0x49,0x6f,0x50,0x40,0x40,0x40,0x80,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0xa0,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x0,0x7b,0x4a,0x4a,0x53,0x52,0x62,0x53,0x50,0x4f,0x4a,0x6a,0x52,0x42,0x43,0x42,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x4,0xfe,0x88,0x50,0x20,0x90,0xe,0x4,
-+0x0,0x78,0x4b,0x4a,0x53,0x52,0x63,0x50,0x57,0x48,0x48,0x6b,0x50,0x40,0x4f,0x40,0x40,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfc,0x40,0x50,0xf8,0x40,0x44,0xfe,0x0,
-+0x0,0x78,0x4b,0x4a,0x52,0x53,0x62,0x52,0x4b,0x48,0x68,0x51,0x41,0x42,0x44,0x48,0x40,0x88,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x80,0xc8,0x54,0x5c,0x42,0x42,0x3e,
-+0x0,0x7b,0x4a,0x4b,0x52,0x53,0x61,0x52,0x57,0x49,0x4a,0x6f,0x50,0x45,0x44,0x48,0x4,0xfe,0x4,0xfc,0x4,0xfc,0x8,0x10,0xbe,0x8,0x94,0xbe,0x0,0x24,0x92,0x2,
-+0x2,0x7f,0x8,0x8,0x8,0x9,0xff,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x0,0x7c,0x44,0x44,0x48,0x48,0xd0,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x0,0x2,0x7f,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0xf,0xf8,0x40,0x0,0x0,0x0,0x7c,0x44,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x4,0x2,0x3f,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80,0x0,0x0,0x7c,0xc4,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x10,0x8,0x9,0xff,0x20,0x20,0x20,0x20,0x20,0x20,0x22,0x3f,0x0,0x0,0x0,0x0,0x0,0x7c,0x44,0xc4,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x8,0x12,0x3f,0x22,0x22,0x22,0x2a,0x24,0x20,0x3f,0x0,0x4,0xfe,0x0,0x2,0x1,0x0,0x3c,0x24,0x24,0x28,0x28,0x30,0x28,0xa4,0xe2,0xa2,0xa2,0xb4,0xa8,0xa0,0x20,
-+0x10,0x8,0x9,0xff,0x10,0x12,0x1f,0x12,0x12,0x12,0x12,0x22,0x22,0x4a,0x84,0x0,0x0,0x7c,0x44,0xc4,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x1,0xff,0x8,0x8,0x9,0x7f,0x49,0x49,0x49,0x55,0x63,0x41,0x41,0x45,0x42,0x0,0x0,0xfc,0x44,0x44,0x48,0xc8,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x1,0xff,0x4,0x8,0x18,0x1c,0x2a,0x29,0x49,0x88,0x8,0x8,0xf,0xf8,0x40,0x0,0x0,0xfc,0x44,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x14,0x14,0x14,0x14,0x15,0xf7,0x14,0x14,0x14,0x14,0x14,0x35,0xd6,0x14,0x0,0x0,0x0,0x7c,0x44,0x44,0x48,0xc8,0x50,0x48,0x44,0x42,0xc2,0x62,0x54,0x48,0x40,0x40,
-+0x14,0x14,0x14,0x14,0x94,0x54,0x55,0x35,0x36,0x14,0x14,0x17,0xf8,0x40,0x0,0x0,0x0,0x7c,0x44,0x44,0xc8,0xc8,0x50,0x48,0x44,0x42,0x42,0xe2,0x54,0x48,0x40,0x40,
-+0x2,0x7,0x78,0x48,0x48,0x4a,0x7f,0x48,0x48,0x48,0x44,0x44,0x52,0x69,0x44,0x0,0x0,0x3c,0x24,0x24,0x28,0x28,0x30,0x28,0x24,0x22,0x22,0xa2,0xb4,0xa8,0x20,0x20,
-+0x10,0x10,0x20,0x24,0x42,0xff,0x0,0x2,0x7f,0x42,0x42,0x42,0x42,0x7e,0x42,0x0,0x0,0x7c,0x44,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x8,0x8,0x9,0xff,0x8,0x49,0x29,0x2a,0xff,0x8,0x8,0x14,0x12,0x23,0xc1,0x0,0x0,0x7c,0x44,0xc4,0x48,0x48,0x50,0x48,0xc4,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x2,0xff,0x10,0x10,0x22,0x41,0x7f,0x8,0x8,0x7f,0x8,0x8,0xf,0xf8,0x40,0x0,0x0,0x7c,0x44,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0xd4,0x48,0x40,0x40,
-+0x8,0x8,0x4a,0x7f,0x48,0x88,0x9,0xff,0x8,0x1c,0x1c,0x2a,0x29,0x48,0x88,0x8,0x0,0x7c,0x44,0x44,0x48,0x48,0x50,0xc8,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x8,0x8,0x14,0x12,0x21,0x20,0x7f,0x80,0x1,0xff,0x10,0x14,0x22,0x7f,0x21,0x0,0x0,0x7c,0x44,0x44,0x48,0x48,0xd0,0x48,0x44,0xc2,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x41,0x22,0x14,0x8,0x14,0x63,0x10,0xff,0x10,0x24,0x28,0x48,0x92,0x3f,0x1,0x0,0x0,0x7c,0x44,0x44,0x48,0x48,0x50,0xc8,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x20,0x21,0x3f,0x41,0x41,0xbd,0x25,0x25,0x3d,0x25,0x25,0x3d,0x25,0x1,0xa,0x4,0x0,0x7c,0xc4,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x0,0x7f,0x50,0x91,0x3f,0x10,0x14,0x25,0x7f,0x4,0x4,0x7,0xfc,0x44,0x4,0x4,0x0,0xfc,0xc4,0x44,0x48,0x48,0x50,0x48,0xc4,0x42,0x42,0xe2,0x54,0x48,0x40,0x40,
-+0x0,0xff,0x0,0x0,0x7b,0x4a,0x4a,0x4a,0x6b,0x5a,0x4a,0x4a,0x4a,0x4a,0x5a,0x0,0x40,0xfe,0x12,0x52,0xf4,0x54,0x58,0x54,0x54,0xd2,0x52,0x5a,0x54,0x50,0xd0,0x10,
-+0x2,0x3f,0x22,0x22,0x22,0x3e,0x0,0xff,0x8,0xa,0x7f,0x8,0xf,0xf8,0x40,0x0,0x0,0x7c,0x44,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0xd4,0x48,0x40,0x40,
-+0x8,0x28,0x2a,0x3f,0x48,0x88,0x9,0xff,0x0,0x7f,0x41,0x41,0x41,0x7f,0x41,0x0,0x0,0x7c,0x44,0x44,0x48,0x48,0x50,0xc8,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x20,0x11,0xe,0x11,0x28,0x8,0xff,0x14,0x24,0x7f,0xa4,0x24,0x24,0x25,0x24,0x4,0x80,0x3c,0x24,0x24,0xa8,0x28,0xf0,0x28,0xa4,0xe2,0xa2,0xa2,0xb4,0xa8,0xa0,0x20,
-+0x1,0x3,0xfc,0x49,0x29,0x2,0x7f,0x2,0xc,0x8,0xff,0x48,0x8,0x8,0x28,0x10,0x0,0xfc,0x44,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x8,0x11,0x7f,0x49,0x49,0x7f,0x49,0x51,0x7f,0x10,0x29,0xff,0x8,0x8,0x8,0x8,0x0,0x7c,0xc4,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0xe2,0x54,0x48,0x40,0x40,
-+0x8,0x29,0x2a,0x4c,0x94,0x12,0x21,0xc8,0x8,0x29,0x2a,0x54,0x12,0x21,0xc1,0x0,0x0,0x7c,0x44,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x1,0x7f,0x40,0x5f,0x51,0x5f,0x51,0x5f,0x48,0x7f,0x49,0x52,0x4e,0x51,0x7f,0x0,0x0,0xbc,0x24,0x24,0x28,0x28,0x30,0x28,0x24,0xe2,0x22,0x22,0x34,0x28,0xa0,0x20,
-+0x1,0xff,0x14,0x15,0x7f,0x55,0x55,0x55,0x7f,0x49,0x8,0x7f,0x8,0xf,0xf8,0x40,0x0,0xfc,0x44,0x44,0xc8,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x1,0x7f,0x4,0x17,0x14,0xff,0x20,0x3f,0x20,0x3f,0x0,0xaa,0xaa,0x0,0x2,0x1,0x0,0xbc,0x24,0xa4,0x28,0xe8,0x30,0x28,0x24,0xa2,0xa2,0xa2,0xb4,0xa8,0xa0,0x20,
-+0x22,0xff,0x22,0x3e,0x8,0x7f,0x49,0x7f,0x8,0x7f,0x8,0x3e,0x8,0xf,0x78,0x20,0x0,0xfc,0x44,0x44,0x48,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x8,0x7f,0x22,0x14,0xff,0x0,0x7f,0x41,0x7f,0x41,0x7f,0x8,0xff,0x8,0x8,0x8,0x0,0x7c,0x44,0x44,0xc8,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0xd4,0x48,0x40,0x40,
-+0x3,0x7c,0x24,0x15,0x7f,0xc,0x15,0x24,0xff,0x24,0x24,0x3f,0x24,0x24,0x3f,0x20,0x80,0x3c,0xa4,0x24,0xe8,0x28,0x30,0xa8,0xe4,0xa2,0xa2,0xa2,0xb4,0xa8,0xa0,0xa0,
-+0x11,0xa,0x7f,0x4,0x3f,0x4,0x7f,0x24,0x15,0xff,0x0,0x3f,0x20,0x20,0x3f,0x20,0x0,0x3c,0xe4,0x24,0xa8,0x28,0xf0,0xa8,0x24,0xe2,0x22,0xa2,0xb4,0xa8,0xa0,0xa0,
-+0xff,0x48,0x7b,0x4a,0x7a,0x49,0xfa,0x8,0x7f,0x14,0x25,0x4e,0x15,0x24,0xc4,0x4,0x80,0x3c,0xa4,0xa4,0xa8,0x28,0xb0,0x28,0x24,0xa2,0x22,0x22,0xb4,0xa8,0x20,0x20,
-+0x2,0x7f,0x8,0x7f,0x48,0xaa,0x8,0x2a,0x0,0x7f,0x55,0x55,0x55,0x55,0x7f,0x0,0x0,0x7c,0x44,0xc4,0xc8,0x48,0x50,0x48,0x44,0x42,0x42,0x62,0x54,0x48,0x40,0x40,
-+0x2a,0x7f,0xaa,0xff,0xaa,0xff,0xaa,0xff,0x0,0xff,0x1,0x7f,0x41,0x7f,0x22,0xff,0x0,0x3c,0xa4,0xa4,0xa8,0xa8,0xb0,0xa8,0x24,0xa2,0x22,0xa2,0x34,0x28,0x20,0xa0,
-+0x8,0x8,0xf,0x10,0x10,0x20,0x5f,0x80,0x0,0x0,0x1f,0x0,0x0,0x0,0x3f,0x0,0x0,0x20,0xf0,0x20,0x40,0x88,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x8,0x8,0xf,0x10,0x10,0x20,0x5f,0x11,0x11,0x11,0xff,0x1,0x2,0x4,0x18,0x60,0x0,0x0,0xe0,0x20,0x40,0x90,0xf8,0x10,0x10,0x14,0xfe,0x0,0x80,0x60,0x1c,0x8,
-+0x0,0x1,0xff,0x10,0x10,0x12,0x1f,0x12,0x12,0x12,0x12,0x22,0x22,0x4a,0x84,0x1,0x20,0x20,0xa0,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x44,0x84,0xa8,0x10,
-+0x20,0x22,0x3f,0x42,0x42,0x8a,0x7e,0x4a,0x4a,0x4a,0x4a,0x7a,0x42,0xa,0x4,0x1,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x44,0x84,0xa8,0x10,
-+0x2,0xff,0x22,0x22,0x22,0x2a,0x44,0x80,0x7e,0x42,0x42,0x42,0x42,0x7e,0x42,0x1,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x44,0x84,0xa8,0x10,
-+0x10,0x9,0xff,0x10,0x12,0x22,0x24,0x7c,0x8,0xa,0x12,0x24,0x4c,0x92,0x20,0x1,0x20,0x20,0xa0,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x44,0x84,0xa8,0x10,
-+0x8,0x8,0x7f,0x9,0x11,0x15,0x62,0x0,0xff,0x0,0x1f,0x10,0x10,0x1f,0x10,0x0,0x0,0x4,0x7e,0x44,0x44,0x44,0x7c,0x0,0xfe,0x10,0x90,0x90,0x90,0x90,0x50,0x20,
-+0x0,0x7f,0x2,0x4,0x7e,0x4,0x14,0x8,0x7f,0x55,0x55,0x55,0x55,0xff,0x0,0x1,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x44,0x84,0xa8,0x10,
-+0x1,0xff,0x81,0xbd,0x81,0xbd,0x0,0x7e,0x42,0x7e,0x42,0x7e,0x42,0x7e,0x42,0x1,0x20,0xa0,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x44,0x84,0xa8,0x10,
-+0x10,0x12,0x7f,0x12,0x12,0x2a,0x44,0x0,0x44,0xff,0x55,0x55,0x55,0x55,0x99,0x33,0x0,0xfe,0x92,0x92,0xfe,0x92,0x92,0xfe,0x82,0x20,0x10,0x50,0xc2,0xc6,0x44,0x3c,
-+0x5,0x39,0x21,0x21,0x3d,0x21,0x21,0x3f,0x1,0x7f,0x8,0x6,0x1,0x6,0x18,0xe0,0x8,0x7c,0x8,0x8,0x78,0x8,0x8,0xf8,0x0,0xf0,0x20,0xc0,0x0,0xc0,0x30,0xe,
-+0x21,0x2f,0x20,0xaf,0x70,0x2f,0x20,0x27,0x54,0x87,0x0,0x1f,0x4,0x3,0xc,0x70,0x8,0xe8,0x8,0xea,0x1c,0xe8,0x8,0xc8,0x54,0xc2,0x0,0xe0,0x40,0x80,0x60,0x1c,
-+0x3e,0x32,0x2a,0x26,0x3e,0x8,0x1f,0x28,0x4f,0x8,0x8,0x1f,0x4,0x3,0x1c,0xe0,0xf8,0xc8,0xa8,0x98,0xf8,0x80,0xf8,0x80,0xf0,0x84,0x7c,0xe0,0x40,0x80,0x70,0xe,
-+0x0,0x0,0xf8,0x8,0x10,0x20,0x40,0x78,0x8,0x88,0x50,0x30,0x20,0x50,0x88,0x7,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0xfc,
-+0x0,0x0,0x0,0x0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7f,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,0x0,
-+0x1,0x1,0x1,0x41,0x41,0x5f,0x43,0x45,0x45,0x49,0x51,0x61,0x45,0x42,0x7f,0x0,0x0,0x0,0x0,0x14,0x34,0x44,0x84,0x44,0x44,0x24,0x24,0x1c,0x4,0x4,0xfc,0x4,
-+0x9,0x4,0x22,0x29,0x22,0x24,0x29,0x20,0x3f,0x28,0x8,0x9,0xe,0x8,0x7,0x0,0x20,0x40,0x88,0x28,0x88,0x48,0x28,0x8,0xf8,0x8,0x60,0x80,0x0,0x4,0xfc,0x0,
-+0x0,0x0,0x1,0x1,0x1,0x2,0x2,0x4,0x4,0x8,0x8,0x10,0x20,0x7f,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x10,0x8,0xfc,0x4,0x0,
-+0x1,0x1,0x2,0x4,0x1f,0x0,0x4,0x4,0xff,0x4,0x4,0x4,0x8,0x8,0x10,0x20,0x0,0x0,0x0,0x20,0xf0,0x10,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x2,0x4,0x8,0x1f,0x2,0xff,0x4,0x8,0x3f,0xd1,0x11,0x1f,0x11,0x11,0x1f,0x10,0x0,0x40,0x20,0xf0,0x4,0xfe,0x40,0x20,0xf8,0x16,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x0,0x0,0xfb,0x8,0x10,0x2d,0xc3,0x8,0x7d,0x11,0x11,0x11,0x1d,0xf2,0x44,0x8,0x80,0x44,0xfe,0x80,0x80,0x8,0xfc,0x4,0x50,0x50,0x50,0x50,0x52,0x52,0x4e,0x0,
-+0x1,0x4,0x4,0x8,0x10,0x2f,0xc4,0x4,0x8,0x31,0x1,0x3f,0x1,0x1,0xff,0x0,0x80,0x80,0x40,0x20,0x10,0xee,0x24,0x20,0xa0,0x40,0x10,0xf8,0x0,0x4,0xfe,0x0,
-+0x0,0x7f,0x2,0x22,0x1a,0xa,0x2,0xff,0x1,0x1,0x3f,0x1,0x1,0x1,0xff,0x0,0x8,0xfc,0x80,0x88,0x98,0xa0,0x84,0xfe,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x0,
-+0x9,0x9,0x9,0x11,0x1f,0x30,0x50,0x90,0x11,0x17,0x1,0x3f,0x1,0x1,0xff,0x0,0x20,0x10,0x0,0xfc,0x0,0x90,0xa0,0x44,0xa4,0x1c,0x0,0xf8,0x0,0x4,0xfe,0x0,
-+0x8,0xff,0x0,0x3e,0x22,0x3e,0x0,0x7e,0x4,0x7e,0x9,0x19,0x7f,0x1,0x1,0xff,0x20,0xa0,0x28,0xfc,0x28,0x68,0x28,0x58,0x48,0x8a,0x6,0x10,0xfc,0x0,0x4,0xfe,
-+0x8,0xff,0x8,0x7f,0x49,0x7f,0x49,0x7f,0x8,0xff,0x49,0x7f,0x1,0x3f,0x1,0xff,0x8,0x7c,0x48,0x48,0x86,0x7c,0x44,0x44,0x28,0x90,0x28,0xc6,0x0,0xf8,0x0,0xfe,
-+0x1,0xff,0x10,0x14,0x25,0x7a,0x10,0x24,0x7c,0x8,0x11,0x61,0x3f,0x1,0x1,0xff,0x0,0xfe,0x90,0xfe,0x90,0xfc,0x90,0xfc,0x90,0xfe,0x80,0x10,0xf8,0x0,0x4,0xfe,
-+0x8,0xf,0x48,0x7f,0x40,0xbf,0x8,0x55,0x3e,0xe3,0x22,0x3e,0x1,0x3f,0x1,0xff,0x0,0x0,0x7c,0x84,0xc4,0x28,0x28,0x10,0x28,0xa8,0x46,0x0,0x10,0xf8,0x0,0xfe,
-+0x10,0x10,0x11,0x10,0x14,0xfe,0x10,0x13,0x10,0x10,0x1e,0xf0,0x40,0x0,0x0,0x0,0x0,0x8,0xfc,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x10,0x10,0x11,0x10,0x14,0xfe,0x13,0x10,0x10,0x11,0x1e,0xf0,0x40,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,0x0,0x4,0xfe,0x80,0x88,0xfc,0x8,0x8,0x8,0x88,0x50,0x20,
-+0x10,0x10,0x10,0x10,0x15,0xfe,0x11,0x10,0x10,0x10,0x1e,0xf1,0x41,0x1,0x0,0x0,0x80,0x80,0x84,0xfe,0x0,0x0,0xf8,0x10,0x20,0x40,0x80,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x11,0x11,0x11,0x15,0xff,0x11,0x11,0x11,0x11,0x1d,0xf1,0x42,0x2,0x4,0x0,0x4,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x4,0x4,0x4,
-+0x10,0x10,0x10,0x13,0x12,0xfe,0x12,0x12,0x12,0x12,0x1e,0xf2,0x44,0x4,0x8,0x10,0x40,0x20,0x24,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x10,0x13,0x10,0x14,0xfe,0x10,0x13,0x12,0x12,0x1e,0xf2,0x42,0x2,0x1,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x10,0x13,0x12,0x12,0xfe,0x12,0x13,0x12,0x12,0x1e,0xf2,0x42,0x2,0x1,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x10,0x13,0x12,0x12,0xfe,0x13,0x12,0x12,0x12,0x1e,0xf2,0x44,0x4,0x9,0x12,0x0,0x4,0xfe,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x28,0x10,
-+0x10,0x10,0x11,0x11,0x15,0xff,0x11,0x11,0x11,0x11,0x1d,0xf1,0x42,0x2,0x4,0x8,0x8,0x1c,0xe0,0x0,0x0,0x4,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x10,0x10,0x11,0x11,0x11,0xfd,0x11,0x11,0x11,0x11,0x1d,0xf2,0x42,0x4,0x9,0x12,0x8,0x1c,0xe0,0x0,0x0,0xfc,0x4,0x88,0x48,0x50,0x30,0x20,0x50,0x88,0xe,0x4,
-+0x11,0x11,0x11,0x11,0x17,0xfd,0x11,0x11,0x11,0x11,0x1d,0xf1,0x41,0x1,0x1,0x1,0x8,0x8,0x8,0xa,0xfe,0x8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x10,0x10,0x17,0xfc,0x10,0x10,0x10,0x11,0x1d,0xf1,0x42,0x2,0x4,0x8,0x80,0xa0,0x90,0x94,0xfe,0xa0,0xa0,0xa4,0xa4,0x28,0x28,0x30,0x62,0xa2,0x1e,0x0,
-+0x10,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x13,0x12,0x12,0x1e,0xf2,0x42,0x3,0x2,0x40,0x40,0x44,0x7e,0x40,0x40,0x40,0x48,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x10,0x10,0x10,0xff,0x12,0x12,0x12,0x13,0x1e,0xf2,0x44,0x4,0x8,0x10,0x40,0x44,0x7e,0x40,0x48,0xfc,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x10,0x11,0x11,0x11,0xfd,0x11,0x11,0x11,0x11,0x1d,0xf1,0x42,0x2,0x4,0x0,0x8,0x1c,0xe0,0x0,0x0,0x4,0xfe,0x10,0x10,0x50,0x30,0x18,0x14,0x10,0x10,0x10,
-+0x10,0x10,0x13,0x12,0x12,0xfe,0x13,0x12,0x12,0x12,0x1e,0xf2,0x42,0x3,0x6,0x0,0x8,0x3c,0xe0,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x10,0x90,0x52,0x2a,0x6,
-+0x10,0x10,0x10,0x13,0x12,0xfc,0x11,0x11,0x11,0x11,0x1d,0xf1,0x41,0x1,0x0,0x0,0x40,0x20,0x20,0xfe,0x2,0x4,0x0,0x10,0x30,0x40,0x80,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x13,0x12,0x12,0x12,0xff,0x12,0x12,0x12,0x12,0x1e,0xf2,0x44,0x4,0x8,0x10,0x8,0xfc,0x8,0x8,0x8,0xf8,0x0,0x80,0x88,0x98,0xa0,0xc0,0x82,0x82,0x7e,0x0,
-+0x10,0x11,0x11,0x11,0x11,0xfd,0x11,0x17,0x12,0x12,0x1e,0xf2,0x43,0x0,0x0,0x0,0x8,0xfc,0x8,0x48,0x28,0x28,0xa,0xfe,0x8,0x88,0x48,0x48,0xfc,0x8,0x50,0x20,
-+0x10,0x11,0x11,0x12,0x12,0xfc,0x17,0x11,0x12,0x14,0x17,0x1c,0xf0,0x40,0x0,0x1,0x20,0x20,0x20,0x24,0x7e,0xa4,0xa4,0x24,0x24,0xa4,0xa4,0x24,0x44,0x44,0x94,0x8,
-+0x10,0x17,0x10,0x10,0x10,0xfc,0x14,0x12,0x12,0x12,0x1c,0xf0,0x40,0x0,0xf,0x0,0x8,0xfc,0xa0,0xa0,0xa0,0xa4,0xa4,0xa4,0xa8,0xa8,0xa0,0xa0,0xa0,0xa4,0xfe,0x0,
-+0x10,0x17,0x10,0x10,0x11,0xfd,0x13,0x10,0x10,0x10,0x13,0x1c,0xf0,0x40,0xf,0x0,0x8,0xfc,0x80,0x80,0x10,0x8,0xfc,0x0,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x0,
-+0x10,0x13,0x12,0x12,0x12,0xfe,0x12,0x12,0x12,0x12,0x1e,0xf2,0x42,0x2,0x2,0x2,0x4,0xfe,0x4,0x4,0xf4,0x4,0x4,0xf4,0x94,0x94,0x94,0xf4,0x4,0x4,0x14,0x8,
-+0x10,0x10,0x14,0x14,0x17,0xfc,0x10,0x13,0x10,0x10,0x13,0x1e,0xf2,0x42,0x2,0x1,0x40,0x40,0x44,0x44,0xfc,0x4,0x8,0xfc,0x8,0x8,0xf8,0x8,0x0,0x2,0x2,0xfe,
-+0x20,0x20,0x2f,0x21,0x22,0xfa,0x24,0x2f,0x21,0x29,0x25,0x3a,0xe2,0x5,0x8,0x10,0x4,0xc,0x70,0x10,0x10,0x50,0x5c,0x50,0x50,0x50,0x50,0x50,0x7c,0x0,0x86,0x7c,
-+0x10,0x10,0x10,0x13,0x12,0xfe,0x12,0x12,0x12,0x12,0x1e,0xf2,0x42,0x2,0x2,0x2,0x40,0x40,0x84,0xfe,0x4,0x4,0xf4,0x94,0x94,0x94,0x94,0xf4,0x4,0x4,0x14,0x8,
-+0x20,0x20,0x20,0x2f,0x20,0xf8,0x25,0x24,0x24,0x24,0x24,0x3c,0xe5,0x44,0x7,0x4,0x80,0x40,0x44,0xfe,0x0,0x10,0x14,0xa4,0xa4,0x44,0xa4,0x94,0x14,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x17,0x10,0xfc,0x11,0x13,0x11,0x10,0x1c,0xf1,0x46,0x0,0x3,0xc,0x80,0x40,0x44,0xfe,0x80,0x90,0x10,0xe0,0x28,0x48,0x90,0x10,0x20,0xd8,0x6,0x2,
-+0x10,0x13,0x12,0x12,0x13,0xfe,0x12,0x13,0x12,0x12,0x1e,0xf2,0x42,0x2,0x3,0x2,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x84,0x88,0x50,0x20,0x10,0x8e,0x4,0x0,
-+0x10,0x11,0x11,0x11,0x11,0xfd,0x11,0x10,0x13,0x10,0x10,0x1d,0xf0,0x40,0x7,0x0,0x4,0xfe,0x4,0x4,0x4,0xfc,0x4,0x0,0xfe,0x20,0x20,0xfc,0x20,0x24,0xfe,0x0,
-+0x20,0x20,0x27,0x24,0x24,0xfc,0x24,0x27,0x24,0x24,0x24,0x3c,0xe7,0x44,0x0,0x0,0x8,0x88,0xc8,0x88,0x8a,0xfe,0x88,0x88,0xc8,0xa8,0xa8,0x88,0x88,0x88,0x28,0x10,
-+0x10,0x11,0x11,0x11,0x11,0xfd,0x10,0x13,0x12,0x12,0x1e,0xf2,0x43,0x2,0x2,0x2,0x8,0xfc,0x8,0x8,0xf8,0x48,0x44,0xfe,0x44,0x44,0x44,0xb4,0x14,0x4,0x14,0x8,
-+0x10,0x11,0x11,0x11,0x11,0xfc,0x13,0x12,0x12,0x12,0x1e,0xf2,0x42,0x0,0x3,0xc,0x8,0xfc,0x8,0x8,0xf8,0x4,0xfe,0x4,0x24,0x24,0x24,0x44,0x44,0x98,0x4,0x2,
-+0x10,0x10,0x17,0x10,0x12,0xfd,0x10,0x10,0x17,0x11,0x10,0x1c,0xf0,0x40,0x0,0x0,0x8,0x3c,0xc0,0x44,0x24,0x28,0x10,0x14,0xfe,0x10,0x90,0x90,0x10,0x10,0x50,0x20,
-+0x10,0x10,0x13,0x12,0x14,0xfd,0x10,0x10,0x17,0x10,0x1c,0xf0,0x41,0x1,0x2,0xc,0x80,0x40,0xfe,0x2,0x24,0xf0,0x0,0x4,0xfe,0xa0,0xa0,0xa0,0x22,0x22,0x1e,0x0,
-+0x10,0x10,0x17,0x10,0x10,0xff,0x12,0x13,0x12,0x13,0x1e,0xf3,0x42,0x2,0xf,0x0,0x40,0x48,0xfc,0x40,0x48,0xfc,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x8,0xa,0xfe,0x0,
-+0x10,0x10,0x10,0x17,0x11,0xfd,0x13,0x16,0x1a,0x13,0x1e,0xf2,0x43,0x2,0x0,0x0,0x80,0x80,0x84,0xfe,0x10,0x50,0xf8,0x4e,0x48,0xf8,0x48,0x48,0xf8,0x4a,0x42,0x3e,
-+0x10,0x13,0x12,0x13,0x12,0xff,0x11,0x11,0x13,0x14,0x10,0x1d,0xf1,0x42,0x4,0x1,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0x4,0xfe,0xa4,0xa4,0x24,0x44,0x44,0x94,0x8,
-+0x10,0x10,0x13,0x12,0x12,0xff,0x12,0x12,0x13,0x10,0x1d,0xf7,0x40,0x0,0x0,0x0,0x40,0x84,0xfe,0x24,0x24,0xfc,0x44,0x44,0xfc,0xa0,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x10,0x10,0x10,0x10,0x11,0xfe,0x14,0x13,0x10,0x10,0x1c,0xf0,0x45,0x5,0x9,0x0,0x40,0x40,0xa0,0xa0,0x10,0x8e,0x44,0xf8,0x10,0x20,0x80,0x40,0x44,0x12,0x12,0xf0,
-+0x20,0x27,0x24,0x24,0x24,0xff,0x24,0x24,0x24,0x27,0x3c,0xe4,0x44,0x8,0x9,0x10,0x4,0xbe,0xa4,0xa4,0xa4,0xbc,0xa4,0xa4,0xa4,0xbc,0xa4,0xa4,0xa4,0xa4,0xd4,0x88,
-+0x10,0x10,0x10,0x11,0x12,0xff,0x12,0x12,0x12,0x13,0x1e,0xf0,0x40,0x1,0x6,0x18,0x80,0x80,0xf8,0x10,0x24,0xfe,0x24,0x24,0x44,0xfc,0x44,0xa0,0xb0,0x2a,0x22,0x1e,
-+0x20,0x23,0x20,0x21,0x28,0xfb,0x20,0x27,0x24,0x2b,0x3a,0xe2,0x42,0x2,0x0,0x0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfe,0x42,0xfc,0x48,0x48,0x48,0x58,0x40,0x40,
-+0x10,0x10,0x13,0x10,0x10,0xff,0x10,0x10,0x13,0x10,0x1e,0xf1,0x42,0xc,0x1,0x0,0x40,0x48,0xfc,0x48,0x4a,0xfe,0x48,0x48,0xf8,0x40,0x48,0x50,0x50,0x4e,0x44,0x80,
-+0x10,0x13,0x12,0x12,0x13,0xfe,0x12,0x12,0x12,0x12,0x1e,0xf3,0x45,0x5,0x9,0x10,0x4,0xfe,0x4,0x4,0xfc,0x20,0xa8,0xa8,0xa8,0xf8,0x20,0x24,0x24,0x24,0xfc,0x4,
-+0x10,0x12,0x12,0x17,0x12,0xfe,0x12,0x12,0x13,0x10,0x1f,0xf0,0x41,0x2,0xc,0x0,0x90,0x90,0x94,0xfe,0x90,0x90,0xf0,0x0,0xfc,0x40,0xfe,0xe0,0x50,0x4e,0x44,0x40,
-+0x10,0x17,0x10,0x10,0x17,0xfc,0x14,0x14,0x17,0x10,0x1c,0xf7,0x40,0x0,0xf,0x0,0x4,0xfe,0xa0,0xa4,0xfe,0xa4,0xa4,0xa4,0xfc,0x40,0x48,0xfc,0x40,0x44,0xfe,0x0,
-+0x10,0x13,0x12,0x12,0x12,0xff,0x12,0x10,0x17,0x10,0x1c,0xf0,0x41,0x1,0x2,0xc,0x4,0xfe,0x94,0x94,0x94,0xfc,0x44,0x20,0xfe,0x80,0xf8,0x88,0x8,0x8,0x28,0x10,
-+0x11,0x11,0x11,0x12,0x13,0xfe,0x16,0x1a,0x13,0x12,0x1f,0xf2,0x42,0x2,0x2,0x3,0x0,0x78,0x8,0x12,0xfe,0x0,0x88,0xfc,0x20,0x24,0xfe,0x20,0x20,0x50,0x8e,0x4,
-+0x10,0x17,0x10,0x13,0x12,0xfe,0x13,0x10,0x17,0x15,0x1c,0xf5,0x44,0x4,0x4,0x4,0x8,0xfc,0x0,0xf8,0x8,0x8,0xf8,0x4,0xfe,0x14,0xa4,0xf4,0x44,0x44,0x54,0x8,
-+0x10,0x13,0x12,0x12,0x12,0xfe,0x12,0x12,0x12,0x12,0x1e,0xf2,0x44,0x5,0xa,0x0,0x4,0xfe,0x20,0x44,0xfe,0x84,0x84,0xfc,0x84,0x84,0xfc,0x20,0xa8,0x26,0x22,0x60,
-+0x13,0x12,0x13,0x12,0x13,0xfc,0x17,0x14,0x14,0x17,0x1c,0xf3,0x41,0x0,0x3,0xc,0xf8,0x8,0xf8,0x8,0xf8,0x4,0xfe,0xa4,0xa4,0xfc,0x0,0xf8,0x10,0xe0,0x18,0x6,
-+0x20,0x27,0x24,0x25,0x24,0xff,0x24,0x25,0x24,0x25,0x3d,0xe5,0x49,0x9,0x11,0x1,0x20,0xfe,0x20,0xfc,0x24,0xfe,0x24,0xfc,0x20,0xfc,0x24,0xfc,0x24,0xfc,0x24,0x2c,
-+0x24,0x22,0x28,0x24,0x21,0xfc,0x24,0x29,0x20,0x2f,0x38,0xe0,0x41,0x2,0xc,0x0,0x8,0xfc,0x48,0xc8,0x48,0x88,0xa8,0x10,0x44,0xfe,0x40,0xe0,0x50,0x4e,0x44,0x40,
-+0x20,0x27,0x24,0x27,0x24,0xfd,0x24,0x25,0x24,0x25,0x3e,0xe4,0x47,0x8,0x10,0x0,0x4,0xfe,0x4,0xfc,0x20,0x24,0xa8,0x24,0xa0,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,
-+0x8,0x7f,0x8,0x7f,0x49,0x7f,0x40,0x4f,0x81,0x3f,0x5,0xf,0x18,0x2f,0x8,0xf,0x78,0x48,0x4c,0x80,0x7c,0x28,0x10,0xee,0x0,0xf8,0x0,0xf0,0x1c,0xf0,0x10,0xf0,
-+0x8,0x7f,0x8,0xff,0x22,0x3e,0x14,0x7f,0x2,0x1f,0x11,0x1f,0x12,0xff,0x1,0x1,0x10,0x10,0xfe,0x10,0x7c,0x28,0x10,0x6e,0x0,0xf0,0x10,0xf0,0x14,0xfe,0x0,0x0,
-+0x10,0xfe,0x11,0x7c,0x0,0xfe,0x82,0x7c,0x1,0x7c,0x44,0x44,0x7d,0x29,0xfe,0x0,0x20,0x20,0x20,0xbe,0x42,0x14,0x50,0x98,0x26,0x42,0x20,0x10,0x54,0x42,0x4a,0x38,
-+0x4,0x4,0xff,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x44,0xfe,0x40,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x6,0x2,0x2,0x7f,0x2,0x4,0x4,0x4,0x8,0x8,0x10,0x60,0x40,0x44,0xfe,0x40,0x40,0x0,0x20,0xf0,0x20,0x20,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x4,0x4,0xff,0x4,0x4,0x3f,0x4,0x4,0x4,0x8,0x8,0x8,0x10,0x10,0x20,0x40,0x40,0x44,0xfe,0x40,0x40,0xf0,0x10,0x20,0x48,0xfc,0x8,0x8,0x8,0x88,0x50,0x20,
-+0x4,0x4,0xff,0x4,0x4,0x1,0x1,0x1,0x7f,0x1,0x1,0x1,0x1,0x1,0xff,0x0,0x40,0x44,0xfe,0x40,0x40,0x0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x4,0x4,0xff,0x4,0x4,0x0,0x3f,0x1,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x40,0x44,0xfe,0x40,0x50,0xf8,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x4,0x3f,0x8,0x8,0xc,0x12,0x12,0x11,0x20,0x20,0x43,0xc,0x40,0x44,0xfe,0x40,0x40,0xf0,0x20,0x40,0xf0,0x10,0x20,0x20,0xc0,0xb0,0xe,0x4,
-+0x4,0x4,0xff,0x4,0x6,0x2,0x3f,0x2,0x1a,0x4,0x6,0x5,0x8,0x8,0x10,0x60,0x40,0x44,0xfe,0x40,0x40,0x20,0xf0,0x20,0x20,0x20,0x20,0x20,0xa2,0x22,0x1e,0x0,
-+0x4,0x4,0xff,0x4,0x4,0x3f,0x0,0x0,0x1f,0x10,0x20,0x3f,0x0,0x0,0x0,0x0,0x40,0x44,0xfe,0x40,0x50,0xf8,0x10,0x10,0xf0,0x0,0x8,0xfc,0x8,0x8,0x50,0x20,
-+0x4,0x4,0xff,0x4,0x4,0x3f,0x0,0x0,0x1f,0x10,0x10,0x10,0x10,0x10,0xf,0x0,0x40,0x44,0xfe,0x40,0x50,0xf8,0x10,0x10,0xf0,0x10,0x0,0x0,0x4,0x4,0xfc,0x0,
-+0x4,0x4,0xff,0x4,0x2,0x4,0x1f,0x0,0x3,0xc,0x3f,0x0,0x0,0x1,0xe,0x70,0x40,0x44,0xfe,0x40,0x0,0x20,0xc0,0x80,0x20,0x20,0xc0,0x40,0x80,0x0,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x5,0x1,0x3f,0x1,0x1,0xff,0x2,0x2,0x4,0x8,0x30,0xc0,0x40,0x44,0xfe,0x40,0x40,0x10,0xf8,0x0,0x4,0xfe,0x80,0x80,0x40,0x30,0xe,0x4,
-+0x4,0x4,0xff,0x4,0x0,0x3f,0x0,0x0,0xff,0x4,0x4,0x4,0x8,0x8,0x10,0x60,0x40,0x44,0xfe,0x40,0x10,0xf8,0x0,0x4,0xfe,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x4,0x4,0xff,0x4,0x4,0x0,0x3f,0x0,0x0,0xff,0x2,0x2,0x4,0x8,0x1f,0x0,0x40,0x44,0xfe,0x40,0x40,0x10,0xf8,0x0,0x4,0xfe,0x0,0x0,0x40,0x20,0xf0,0x10,
-+0x4,0x4,0xff,0x4,0x1,0xff,0x1,0x1,0x1f,0x11,0x11,0x11,0x11,0x11,0x1,0x1,0x40,0x44,0xfe,0x40,0x4,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0x50,0x20,0x0,0x0,
-+0x4,0x4,0xff,0x5,0x1,0xff,0x1,0x1,0x3f,0x8,0x4,0x2,0x1,0x6,0x18,0xe0,0x40,0x44,0xfe,0x40,0x4,0xfe,0x0,0x0,0xf0,0x20,0x40,0x80,0x0,0xc0,0x30,0xe,
-+0x4,0x4,0xff,0x4,0x4,0x3f,0x21,0x21,0x2f,0x21,0x21,0x22,0x42,0x44,0x88,0x10,0x40,0x44,0xfe,0x40,0x48,0xfc,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0x50,0x20,
-+0x4,0x4,0xff,0x4,0x4,0x1f,0x10,0x10,0x17,0x14,0x14,0x24,0x24,0x44,0x84,0x3,0x40,0x44,0xfe,0x40,0x48,0xfc,0x0,0x20,0xf0,0x20,0x20,0xa0,0x40,0x4,0x4,0xfc,
-+0x4,0x4,0xff,0x4,0x3f,0x20,0x20,0x3f,0x20,0x20,0x3f,0x20,0x20,0x20,0x3f,0x0,0x40,0x44,0xfe,0x40,0xf8,0x0,0x20,0xf0,0x20,0x20,0xe0,0x20,0x0,0x8,0xfc,0x0,
-+0x4,0x4,0xff,0x4,0x4,0x20,0x20,0x24,0x3e,0x20,0x20,0x20,0x26,0x38,0x20,0x0,0x40,0x44,0xfe,0x40,0x40,0x80,0x88,0x98,0xa0,0xc0,0x80,0x80,0x84,0x84,0x7c,0x0,
-+0x4,0x4,0xff,0x4,0x5,0x1,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0x9,0xff,0x0,0x40,0x44,0xfe,0x40,0x40,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x4,0x4,0xff,0x4,0x5,0x1,0x3f,0x21,0x21,0x22,0x22,0x24,0x28,0x20,0x20,0x20,0x40,0x44,0xfe,0x40,0x40,0x8,0xfc,0x8,0x8,0x88,0x48,0x68,0x28,0x8,0x28,0x10,
-+0x4,0x4,0xff,0x4,0x0,0x1f,0x10,0x11,0x11,0x11,0x12,0x12,0x4,0x8,0x30,0xc0,0x40,0x44,0xfe,0x40,0x10,0xf8,0x10,0x10,0x10,0x90,0x90,0x90,0x80,0x84,0x84,0x7c,
-+0x4,0x4,0xff,0x4,0x8,0x8,0xb,0x8,0xff,0xa,0x9,0x8,0x8,0xa,0xc,0x8,0x40,0x44,0xfe,0x40,0x20,0xc0,0x0,0x4,0xfe,0x0,0x0,0x80,0x40,0x20,0x1c,0x8,
-+0x4,0x4,0xff,0x4,0x4,0x8,0x8,0x8,0x8,0x8,0x8,0x14,0x12,0x20,0x41,0x2,0x40,0x44,0xfe,0x40,0x40,0x20,0x20,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x4,0x2,
-+0x4,0x4,0xff,0x5,0x2,0x4,0x8,0x33,0xc0,0x0,0x1f,0x0,0x0,0x0,0x0,0x1,0x40,0x44,0xfe,0x40,0x80,0x40,0x30,0xe,0x84,0x20,0xf0,0x20,0x40,0x40,0x80,0x0,
-+0x4,0x4,0xff,0x4,0x8,0x8,0xf,0x12,0x22,0x44,0x4,0x8,0x11,0x22,0x4,0x0,0x40,0x44,0xfe,0x40,0x0,0x8,0xfc,0x48,0x48,0x48,0x88,0x88,0x8,0x8,0x50,0x20,
-+0x4,0x4,0xff,0x4,0xc,0x8,0xf,0x11,0x11,0x21,0x2,0x2,0x4,0x8,0x10,0x60,0x40,0x44,0xfe,0x40,0x40,0x0,0xf8,0x10,0x20,0x0,0x80,0x80,0x40,0x30,0xe,0x4,
-+0x4,0x4,0xff,0x4,0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x10,0x10,0x14,0x18,0x10,0x40,0x44,0xfe,0x40,0xf8,0x80,0x80,0x80,0x88,0xfc,0x80,0x40,0x40,0x22,0x12,0xe,
-+0x4,0x4,0xff,0x4,0x0,0x7,0x4,0x8,0x30,0xf,0x4,0x2,0x1,0x2,0xc,0x70,0x40,0x44,0xfe,0x40,0x0,0xc0,0x48,0x7c,0x0,0xe0,0x40,0x80,0x0,0x80,0x60,0x1c,
-+0x4,0x4,0xff,0x4,0x6,0x1,0xff,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x40,0x44,0xfe,0x40,0x40,0x4,0xfe,0x0,0x0,0x40,0x30,0x10,0x0,0x0,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x6,0x41,0x7f,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x7f,0x0,0x40,0x44,0xfe,0x40,0x40,0x0,0xfe,0x2,0x4,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,
-+0x4,0x4,0xff,0x4,0x0,0x7f,0x2,0xc,0x8,0xf,0xf8,0x48,0x8,0x8,0x28,0x10,0x40,0x44,0xfe,0x40,0x0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x4,0x4,0xff,0x4,0x0,0x24,0x22,0x21,0x21,0x20,0x20,0x24,0x28,0x30,0x1,0x6,0x40,0x44,0xfe,0x40,0x8,0x8,0x8,0x10,0x10,0x10,0x20,0x20,0x50,0x8c,0x4,0x0,
-+0x4,0x4,0xff,0x5,0x1,0xff,0x1,0x1,0x7f,0x3,0x5,0x9,0x31,0xc1,0x1,0x1,0x40,0x44,0xfe,0x40,0x4,0xfe,0x0,0x8,0xfc,0x80,0x40,0x30,0xe,0x4,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x8,0x8,0xff,0x8,0x8,0x8,0xf,0x8,0x8,0x8,0xf,0x8,0x40,0x44,0xfe,0x40,0x20,0x24,0xfe,0x20,0x20,0x20,0xe0,0x20,0x20,0x20,0xe0,0x20,
-+0x4,0x4,0xff,0x4,0x0,0x7f,0x0,0x1,0x3,0x5,0x19,0x61,0x1,0x1,0xff,0x0,0x40,0x44,0xfe,0x40,0x4,0xfe,0x80,0x0,0x0,0x60,0x18,0x4,0x0,0x4,0xfe,0x0,
-+0x4,0x4,0xff,0x4,0x2,0x2,0xff,0x2,0x2,0x4,0x4,0x8,0x8,0x11,0x26,0x40,0x40,0x44,0xfe,0x40,0x20,0x14,0xfe,0x80,0x88,0x98,0xa0,0xc0,0x82,0x82,0x7e,0x0,
-+0x4,0x4,0xff,0x4,0x2,0x2,0xff,0x4,0x4,0x7,0xa,0x9,0x10,0x21,0x46,0x18,0x40,0x44,0xfe,0x40,0x40,0x24,0xfe,0x0,0x0,0xf0,0x20,0x40,0x80,0x60,0x1c,0x8,
-+0x4,0x4,0xff,0x4,0x0,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x40,0x44,0xfe,0x40,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x4,0x4,0xff,0x4,0x0,0xf,0x8,0x8,0xf,0x8,0x8,0xf,0x8,0x8,0xff,0x0,0x40,0x44,0xfe,0x40,0x20,0xf0,0x20,0x20,0xe0,0x20,0x20,0xe0,0x20,0x24,0xfe,0x0,
-+0x4,0x4,0xff,0x4,0x1,0x1f,0x11,0x11,0x1f,0x11,0x11,0xff,0x10,0x10,0x10,0x10,0x40,0x44,0xfe,0x40,0x10,0xf8,0x10,0x10,0xf0,0x10,0x14,0xfe,0x10,0x10,0x50,0x20,
-+0x4,0x4,0xff,0x4,0x0,0x3f,0x20,0x20,0x27,0x24,0x24,0x24,0x27,0x24,0x20,0x20,0x40,0x44,0xfe,0x40,0x8,0xfc,0x8,0x48,0xe8,0x48,0x48,0x48,0xc8,0x48,0x28,0x10,
-+0x4,0x4,0xff,0x4,0x8,0x8,0x10,0x1f,0x30,0x50,0x90,0x10,0x10,0x17,0x10,0x10,0x20,0x24,0xfe,0x20,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x48,0xfc,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x8,0x8,0x10,0x17,0x30,0x51,0x90,0x10,0x10,0x10,0x10,0x10,0x40,0x44,0xfe,0x40,0x10,0x10,0x14,0xfe,0x10,0x10,0x90,0x90,0x10,0x10,0x50,0x20,
-+0x4,0x4,0xff,0x5,0x2,0x4,0xa,0x31,0xc1,0x3f,0x0,0x0,0xc,0x3,0x0,0x0,0x40,0x44,0xfe,0x40,0x80,0x40,0x30,0xe,0x4,0xf0,0x20,0x40,0x80,0x0,0xc0,0x40,
-+0x4,0x4,0xff,0x5,0x2,0xf,0x8,0xa,0x9,0x8,0xf,0x0,0xff,0x0,0x0,0x0,0x40,0x44,0xfe,0x40,0x20,0xf0,0x20,0x20,0x60,0x8,0xfc,0x8,0xc8,0x8,0x50,0x20,
-+0x4,0x4,0xff,0x4,0x6,0x38,0x20,0x20,0x3e,0x20,0x20,0x26,0x38,0x20,0x0,0x0,0x40,0x44,0xfe,0x40,0x8,0xfc,0x88,0x88,0x88,0x88,0x88,0xa8,0x90,0x80,0x80,0x80,
-+0x4,0x4,0xff,0x4,0x6,0x38,0x22,0x22,0x22,0x22,0x22,0x3c,0x24,0x8,0x10,0x60,0x40,0x44,0xfe,0x40,0x8,0xfc,0x88,0x88,0x88,0x88,0xc8,0xa8,0x90,0x80,0x80,0x80,
-+0x4,0x4,0xff,0x4,0x0,0x7f,0x41,0x81,0x1,0x3f,0x1,0x1,0x1,0x1,0x7f,0x0,0x40,0x44,0xfe,0x40,0x0,0xfe,0x2,0x4,0x10,0xf8,0x0,0x0,0x0,0x8,0xfc,0x0,
-+0x4,0x4,0xff,0x4,0x0,0x7f,0x40,0x9f,0x4,0x5,0x3f,0x4,0x4,0x4,0x4,0x4,0x40,0x44,0xfe,0x40,0x0,0xfe,0x2,0xe4,0x20,0x20,0xa0,0x20,0x20,0x24,0x14,0x8,
-+0x4,0x4,0xff,0x4,0x3f,0x20,0x20,0x3f,0x20,0x20,0x3f,0x20,0x20,0x28,0x30,0x20,0x40,0x44,0xfe,0x40,0xf8,0x8,0x8,0xf8,0x80,0x88,0xfc,0x40,0x40,0x22,0x12,0xe,
-+0x4,0x4,0xff,0x4,0x3f,0x4,0x4,0x8,0x10,0x60,0x1f,0x10,0x10,0x10,0x1f,0x10,0x40,0x44,0xfe,0x40,0xf8,0x8,0x8,0x8,0x50,0x20,0xf0,0x10,0x10,0x10,0xf0,0x10,
-+0x4,0x4,0xff,0x4,0x0,0xff,0x4,0x4,0x3f,0x24,0x24,0x28,0x30,0x20,0x3f,0x20,0x40,0x44,0xfe,0x40,0x4,0xfe,0x40,0x48,0xfc,0x48,0x48,0x38,0x8,0x8,0xf8,0x8,
-+0x4,0x4,0xff,0x4,0x1,0xff,0x1,0x3f,0x1,0x3f,0x21,0x3f,0x2,0xc,0x30,0xc0,0x40,0x44,0xfe,0x40,0x4,0xfe,0x0,0xf8,0x8,0xf8,0x0,0xfc,0x84,0x4c,0x30,0xe,
-+0x4,0x4,0xff,0x4,0x1,0x1,0x7f,0x1,0x3,0x3c,0x0,0x7f,0x4,0x4,0x8,0x70,0x40,0x44,0xfe,0x40,0x0,0xf8,0x20,0x44,0x84,0x7c,0x10,0xf8,0x80,0x82,0x82,0x7e,
-+0x4,0x4,0xff,0x4,0x20,0x20,0x3e,0x20,0x26,0x39,0x1,0xff,0x1,0x1,0x1,0x1,0x40,0x44,0xfe,0x40,0x80,0x98,0xe0,0x80,0x84,0x7c,0x0,0xfe,0x0,0x0,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x0,0x4,0x24,0x27,0x24,0x24,0x24,0x24,0x27,0xf8,0x40,0x0,0x40,0x44,0xfe,0x40,0x0,0x40,0x44,0x4c,0x50,0x60,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x4,0x4,0xff,0x4,0x1f,0x10,0x10,0x10,0x1f,0x0,0x3f,0x20,0x20,0x20,0x3f,0x20,0x40,0x44,0xfe,0x40,0xf0,0x10,0x10,0x10,0xf0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x4,0x4,0xff,0x4,0x3f,0x20,0x2f,0x20,0x27,0x24,0x24,0x24,0x27,0x20,0x20,0x20,0x40,0x44,0xfe,0x40,0xf8,0x8,0xe8,0x8,0xc8,0x48,0x48,0x48,0xc8,0x8,0x28,0x10,
-+0x4,0x4,0xff,0x4,0x0,0x3f,0x20,0x20,0x27,0x24,0x24,0x27,0x20,0x20,0x3f,0x20,0x40,0x44,0xfe,0x40,0x8,0xfc,0x8,0x48,0xe8,0x48,0x48,0xc8,0x8,0x8,0xf8,0x8,
-+0x4,0x4,0xff,0x4,0x11,0x11,0x1f,0x21,0x1,0xff,0x3,0x5,0x9,0x11,0x61,0x1,0x40,0x44,0xfe,0x40,0x0,0x20,0xf0,0x0,0x4,0xfe,0x80,0x40,0x20,0x1c,0x8,0x0,
-+0x4,0x4,0xff,0x4,0x0,0x7d,0x4,0x8,0x13,0x3c,0x4,0x24,0x19,0xc,0x32,0xc1,0x40,0x44,0xfe,0x40,0x1c,0xe0,0x20,0x24,0xfe,0x20,0x20,0x28,0xfc,0x0,0x6,0xfc,
-+0x4,0x4,0xff,0x4,0x1,0x3e,0x2,0xff,0x4,0x8,0x34,0xc4,0x4,0x4,0x8,0x10,0x40,0x44,0xfe,0x40,0xf0,0x0,0x4,0xfe,0x40,0x30,0x4e,0x44,0x40,0x40,0x40,0x40,
-+0x4,0x4,0xff,0x4,0x8,0x8,0x10,0x1f,0x30,0x50,0x90,0x10,0x11,0x12,0x14,0x18,0x40,0x44,0xfe,0x40,0x50,0x48,0x40,0xfe,0x40,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,
-+0x4,0x4,0xff,0x4,0x8,0x8,0x17,0x10,0x30,0x50,0x9f,0x10,0x10,0x10,0x17,0x10,0x40,0x44,0xfe,0x40,0x8,0x3c,0xc0,0x40,0x40,0x44,0xfe,0x40,0x40,0x48,0xfc,0x0,
-+0x4,0x4,0xff,0x4,0x4,0x9,0x10,0x64,0xb,0x18,0x28,0xc8,0x8,0x8,0x8,0x8,0x40,0x44,0xfe,0x40,0x8,0xfc,0x0,0x4,0xfe,0x10,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x4,0x4,0xff,0x5,0x2,0x4,0x8,0x30,0xdf,0x1,0x1,0x1f,0x1,0x1,0x7f,0x0,0x40,0x44,0xfe,0x40,0x80,0x40,0x30,0xe,0xf4,0x0,0x20,0xf0,0x0,0x8,0xfc,0x0,
-+0x4,0x4,0xff,0x5,0x2,0x4,0x8,0x30,0xcf,0x0,0x3f,0x2,0x4,0x8,0x1f,0x0,0x40,0x44,0xfe,0x40,0x80,0x40,0x30,0x4e,0xe4,0x0,0xf8,0x0,0x40,0x20,0xf0,0x10,
-+0x4,0x4,0xff,0x14,0x10,0x3f,0x20,0x5f,0x90,0x10,0x1f,0x10,0x10,0x1f,0x10,0x0,0x40,0x44,0xfe,0x40,0x8,0xfc,0x8,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xa8,0x10,
-+0x4,0x4,0xff,0x4,0x2,0x7,0x8,0x14,0x23,0x4,0xf,0x38,0xc8,0x8,0xf,0x8,0x40,0x44,0xfe,0x40,0x0,0xf0,0x20,0xc0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x4,0x4,0xff,0x4,0x1,0x7f,0x8,0x6,0x1,0x2,0xc,0x34,0xc4,0x4,0x8,0x10,0x40,0x44,0xfe,0x40,0x8,0xfc,0x20,0xc0,0x0,0xc0,0x70,0x4e,0x44,0x40,0x40,0x40,
-+0x4,0x4,0xff,0x4,0x1,0x7f,0x8,0x8,0x14,0x24,0x42,0x1,0x2,0x4,0x18,0x60,0x40,0x44,0xfe,0x40,0x8,0xfc,0x0,0x10,0x4c,0x44,0x80,0x0,0x80,0x60,0x1c,0x8,
-+0x4,0x4,0xff,0x4,0x1,0xff,0x2,0x4,0x8,0x1f,0x4,0x4,0x4,0x8,0x10,0x60,0x40,0x44,0xfe,0x40,0x4,0xfe,0x0,0x40,0x20,0xf0,0x90,0x80,0x80,0x84,0x84,0x7c,
-+0x4,0x4,0xff,0x4,0x20,0x18,0xb,0x40,0x20,0x28,0x10,0x20,0x60,0x20,0x2f,0x20,0x40,0x44,0xfe,0x40,0x0,0x8,0xfc,0x40,0x40,0x40,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x4,0x4,0xff,0x4,0x40,0x7f,0x41,0x89,0xf,0x11,0x21,0x7f,0x1,0x1,0x1,0x1,0x40,0x44,0xfe,0x40,0x0,0xfe,0x2,0x24,0xf0,0x0,0x8,0xfc,0x0,0x0,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x40,0x7f,0x41,0x41,0xbd,0x5,0x9,0x9,0x11,0x61,0x5,0x2,0x40,0x44,0xfe,0x40,0x0,0xfe,0x2,0x14,0x20,0xc0,0x40,0x20,0x20,0x1c,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x1f,0x0,0xf,0x0,0x1f,0x0,0xff,0x8,0x4,0x4,0x0,0x0,0x40,0x44,0xfe,0x40,0xf0,0x10,0xf0,0x10,0xf0,0x24,0xfe,0x20,0x20,0x20,0xa0,0x40,
-+0x4,0x4,0xff,0x4,0x1f,0x10,0x1f,0x10,0x1f,0x14,0x12,0x11,0x10,0x14,0x18,0x10,0x40,0x44,0xfe,0x40,0xf0,0x10,0xf0,0x10,0xf8,0x10,0x20,0x40,0x80,0x60,0x1c,0x8,
-+0x4,0x4,0xff,0x4,0x1f,0x10,0x10,0x1f,0x10,0x12,0x11,0x20,0x20,0x43,0x80,0x0,0x40,0x44,0xfe,0x40,0xf0,0x10,0x10,0xf0,0x40,0x20,0x90,0x8e,0x4,0x0,0xc0,0x20,
-+0x4,0x4,0xff,0x4,0x0,0x3f,0x0,0xc,0x2,0x18,0x4,0xff,0x1,0x2,0xc,0x30,0x40,0x44,0xfe,0x40,0x0,0xf8,0x8,0x90,0x80,0x80,0x84,0xfe,0x0,0x60,0x18,0x4,
-+0x4,0x4,0xff,0x4,0x0,0x7e,0x4,0x8,0xe,0x38,0xc9,0x9,0xa,0x8,0x28,0x10,0x40,0x44,0xfe,0x40,0x20,0x20,0x20,0xa0,0xa8,0xa4,0x24,0x22,0x22,0x20,0xa0,0x40,
-+0x4,0x4,0xff,0x4,0x10,0x10,0x23,0x7c,0x8,0x10,0x26,0x78,0x20,0xe,0x73,0x20,0x40,0x44,0xfe,0x40,0x0,0x8,0xfc,0x20,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x4,0x4,0xff,0x4,0x10,0x10,0x22,0x7d,0x8,0x10,0x26,0x78,0x0,0xe,0x70,0x20,0x40,0x44,0xfe,0x40,0x8,0x8,0x8,0xfe,0x8,0x88,0x48,0x48,0x8,0x8,0x28,0x10,
-+0x4,0x4,0xff,0x4,0x10,0x10,0x10,0xfd,0x12,0x10,0x10,0x10,0x1c,0xe1,0x42,0x4,0x40,0x44,0xfe,0x40,0x80,0x84,0xfe,0x4,0x48,0x40,0x40,0xa0,0xa0,0x10,0xe,0x4,
-+0x4,0x4,0xff,0x5,0x1,0x3f,0x1,0x7f,0x40,0x9f,0x0,0x1,0x7f,0x1,0x5,0x2,0x40,0x44,0xfe,0x40,0x10,0xf8,0x0,0xfe,0x2,0xe4,0x80,0x8,0xfc,0x0,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x0,0x7c,0x44,0x47,0x44,0x7c,0x44,0x44,0x44,0x7c,0x44,0x0,0x40,0x44,0xfe,0x40,0x10,0x10,0x14,0xfe,0x10,0x90,0x50,0x50,0x10,0x10,0x50,0x20,
-+0x4,0x4,0xff,0x4,0xf,0x8,0x8,0xf,0x1,0x3f,0x21,0x21,0x22,0x2c,0x20,0x20,0x40,0x44,0xfe,0x40,0xe0,0x20,0x20,0xe0,0x8,0xfc,0x8,0x8,0xc8,0x48,0x28,0x10,
-+0x4,0x4,0xff,0x4,0x1,0x3f,0x1,0x7f,0x5,0x9,0x3f,0xc4,0x4,0x4,0x8,0x30,0x40,0x44,0xfe,0x40,0xf0,0x0,0x4,0xfe,0x40,0x30,0xce,0x44,0xf0,0x10,0x50,0x20,
-+0x4,0x4,0xff,0x4,0x6,0x3c,0x4,0xff,0x4,0x5,0x6,0x1c,0x64,0x4,0x15,0x8,0x40,0x44,0xfe,0x40,0x60,0x50,0x44,0xfe,0x40,0x48,0x48,0x30,0x20,0x52,0x8a,0x6,
-+0x4,0x4,0xff,0x14,0x10,0x1f,0x20,0x5f,0x12,0x11,0xff,0x22,0x21,0x3f,0x0,0x0,0x40,0x44,0xfe,0x40,0x10,0xf8,0x0,0xf0,0x10,0x14,0xfe,0x10,0x10,0xfc,0x50,0x20,
-+0x4,0x4,0xff,0x4,0x8,0x8,0x14,0x15,0x36,0x54,0x94,0x14,0x14,0x10,0x11,0x12,0x40,0x44,0xfe,0x40,0x80,0x84,0xfe,0x88,0x88,0x50,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x4,0x4,0xff,0x4,0x8,0x8,0x10,0x17,0x30,0x52,0x91,0x11,0x11,0x10,0x1f,0x10,0x40,0x44,0xfe,0x40,0x80,0x40,0x48,0xfc,0x0,0x18,0x10,0x10,0x20,0x24,0xfe,0x0,
-+0x4,0x4,0xff,0x5,0x2,0x4,0x8,0x3f,0xc1,0x1,0x3f,0x1,0x9,0x11,0x25,0x2,0x40,0x44,0xfe,0x40,0x80,0x40,0x30,0xee,0x4,0x10,0xf8,0x0,0x20,0x18,0x8,0x0,
-+0x4,0x4,0xff,0x5,0x2,0x4,0x8,0x3f,0xc0,0x2,0x11,0x9,0x9,0x0,0x7f,0x0,0x40,0x44,0xfe,0x40,0x80,0x40,0x30,0xee,0x4,0x10,0x10,0x20,0x20,0x48,0xfc,0x0,
-+0x4,0x4,0xff,0x4,0x0,0x7f,0x11,0x9,0x3f,0x0,0x1,0x1,0xff,0x1,0x5,0x2,0x40,0x44,0xfe,0x40,0xf8,0x10,0x10,0x20,0xf0,0x40,0x80,0x4,0xfe,0x0,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x0,0x3f,0x11,0x9,0x2,0xff,0x4,0x8,0x6,0x1,0x6,0x38,0x40,0x44,0xfe,0x40,0xf8,0x10,0x10,0x20,0x4,0xfe,0x20,0x20,0x40,0x80,0x60,0x10,
-+0x4,0x4,0xff,0x4,0x20,0x14,0xb,0x14,0x64,0xc,0x14,0x24,0xc5,0x5,0x2a,0x14,0x40,0x44,0xfe,0x40,0x50,0x48,0xfe,0x40,0x60,0xa0,0xa0,0xa0,0x22,0x22,0x1e,0x0,
-+0x4,0x4,0xff,0x4,0x20,0x14,0x8,0x14,0x64,0xd,0x14,0x24,0xc4,0x4,0x29,0x12,0x40,0x44,0xfe,0x40,0x20,0x20,0xa4,0xa4,0xa8,0x20,0x50,0x50,0x90,0x88,0xe,0x4,
-+0x4,0x4,0xff,0x4,0x1,0x3f,0x8,0x4,0x4,0xff,0x1,0x1,0x3f,0x1,0x1,0x1,0x40,0x44,0xfe,0x40,0x10,0xf8,0x20,0x40,0x84,0xfe,0x0,0x10,0xf8,0x0,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x1,0x7f,0x40,0x9f,0x0,0x7f,0x4,0x4,0x4,0x8,0x10,0x60,0x40,0x44,0xfe,0x40,0x0,0xfe,0x2,0xf4,0x0,0xfc,0x80,0x80,0x80,0x84,0x84,0x7c,
-+0x4,0x4,0xff,0x4,0x1,0x1f,0x10,0x1f,0x10,0x1f,0x12,0x11,0x10,0x14,0x18,0x10,0x40,0x44,0xfe,0x40,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0x20,0xc0,0x60,0x1e,0x4,
-+0x4,0x4,0xff,0x4,0x7f,0x42,0x8f,0x8,0xb,0x8,0x8,0xf,0x0,0x7f,0x0,0x0,0x40,0x44,0xfe,0x40,0xfe,0x2,0xe4,0x20,0x20,0xa0,0x48,0xfc,0x8,0xc8,0x28,0x10,
-+0x4,0x4,0xff,0x4,0x10,0x17,0x20,0x7e,0xa,0x12,0x23,0x7c,0x0,0xe,0x70,0x20,0x40,0x44,0xfe,0x40,0x48,0xfc,0x40,0x48,0x48,0x48,0xf8,0x48,0x40,0x42,0x42,0x3e,
-+0x4,0xff,0x5,0x3f,0x1,0x1f,0x1,0xff,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x40,0xfe,0x40,0xf8,0x0,0xf0,0x4,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0x30,
-+0x4,0x4,0xff,0x4,0x8,0x7f,0x8,0xf,0x8,0xf,0x8,0x8,0xff,0x4,0x8,0x30,0x40,0x44,0xfe,0x40,0x28,0xfc,0x20,0xe0,0x20,0xe0,0x20,0x24,0xfe,0x40,0x30,0x8,
-+0x4,0x4,0xff,0x4,0x8,0x8,0xfe,0x8,0x1c,0x1a,0x28,0x48,0x89,0x9,0xa,0x8,0x40,0x44,0xfe,0x40,0x1c,0xe0,0x80,0x84,0xfe,0x90,0x90,0x90,0x10,0x10,0x10,0x10,
-+0x4,0x4,0x7f,0x4,0x8,0xa,0x7f,0x8,0x1c,0x1a,0x29,0x48,0x88,0x8,0x9,0x8,0x40,0x44,0xfe,0x40,0x0,0x50,0x50,0x50,0x88,0xae,0x24,0x40,0x50,0x88,0xfc,0x4,
-+0x8,0x8,0xff,0x8,0xf,0x1,0x3f,0x21,0x3f,0x1,0x7f,0x1,0x3f,0x1,0xff,0x0,0x20,0x24,0xfe,0x20,0xe0,0x8,0xfc,0x8,0xf8,0x0,0xfc,0x0,0xf8,0x0,0xfe,0x0,
-+0x4,0x4,0xff,0x5,0x1,0x7f,0x2,0x4,0xf,0x30,0xdf,0x1,0x9,0x11,0x25,0x2,0x40,0x44,0xfe,0x40,0x8,0xfc,0x80,0x40,0xf0,0xe,0xf4,0x0,0x20,0x18,0x8,0x0,
-+0x4,0xff,0x5,0x7f,0x1,0x3f,0x1,0xff,0x1,0x3f,0x2,0xff,0x4,0x8,0x7,0x38,0x40,0xfe,0x40,0xfc,0x0,0xf0,0x14,0xfe,0x10,0xf0,0x4,0xfe,0x40,0x80,0x80,0x78,
-+0x4,0x4,0xff,0x4,0x10,0x10,0xff,0x11,0x11,0x1d,0xf2,0x52,0x14,0x18,0x50,0x23,0x40,0x44,0xfe,0x40,0x90,0x88,0xfe,0x0,0xf8,0x88,0x90,0x50,0x20,0x50,0x8e,0x4,
-+0x4,0x4,0xff,0x4,0x8,0xf,0x8,0xa,0xff,0x8,0x2c,0x2b,0x49,0x88,0x28,0x11,0x40,0x44,0xfe,0x40,0x0,0x7c,0x4,0x44,0x44,0x28,0x28,0x10,0x28,0x48,0x86,0x4,
-+0x4,0x4,0xff,0x4,0x1f,0x10,0x1f,0x10,0x1f,0x0,0x3f,0x20,0x3f,0x20,0x3f,0x20,0x40,0x44,0xfe,0x40,0xf0,0x10,0xf0,0x10,0xf0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,
-+0x4,0x4,0xff,0x4,0x10,0x10,0x7c,0x54,0x54,0x55,0x55,0x55,0x5d,0x11,0x11,0x11,0x40,0x44,0xfe,0x40,0x20,0x24,0x3e,0x20,0x24,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x4,0x4,0xff,0x4,0xd,0x31,0x21,0x21,0x3d,0x21,0x21,0x3f,0x2,0x4,0x18,0x60,0x40,0x44,0xfe,0x40,0x8,0x7c,0x8,0x8,0x78,0x8,0x8,0xf8,0x80,0x60,0x1c,0x8,
-+0x4,0xff,0x4,0x9,0x8,0x1f,0x10,0x30,0x5f,0x90,0x10,0x1f,0x10,0x10,0x1f,0x10,0x40,0xfe,0x40,0x0,0x88,0xfc,0x80,0x90,0xf8,0x80,0x90,0xf8,0x80,0x88,0xfc,0x0,
-+0x4,0x4,0xff,0x5,0x2,0x3f,0x21,0x3f,0x22,0x3f,0x5,0x9,0xff,0x1,0x1,0x1,0x40,0x44,0xfe,0x40,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0x4,0xfe,0x0,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x3d,0x25,0x25,0x3d,0x25,0x25,0x3d,0x25,0x25,0x45,0x55,0x89,0x40,0x44,0xfe,0x40,0xf8,0x8,0x48,0x30,0x0,0xf8,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x4,0x4,0xff,0x4,0xf,0x8,0x10,0x3f,0x51,0x11,0x1f,0x12,0x2,0x4,0x18,0x60,0x40,0x44,0xfe,0x40,0xe0,0x20,0x48,0xfc,0x8,0x8,0xf8,0x80,0xa0,0x94,0x84,0x7c,
-+0x4,0x4,0xff,0x4,0x8,0xf,0x10,0x26,0x78,0xa0,0x24,0x3e,0x20,0x20,0x3f,0x20,0x40,0x44,0xfe,0x40,0x0,0xf0,0x20,0x48,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x4,0x4,0xff,0x4,0x1,0x7f,0x8,0x8,0x14,0x22,0x1,0xff,0x1,0x1,0x1,0x1,0x40,0x44,0xfe,0x40,0x8,0xfc,0x20,0x20,0x50,0x88,0x0,0xfe,0x0,0x0,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x10,0x8,0xff,0x10,0x1e,0x13,0x12,0x22,0x22,0x42,0x8a,0x4,0x40,0x44,0xfe,0x40,0x20,0x20,0x50,0x50,0x8e,0x4,0x60,0x10,0x0,0xc0,0x30,0x8,
-+0x4,0x4,0xff,0x4,0x40,0x33,0x12,0x82,0x4b,0x12,0x22,0xe3,0x22,0x22,0x3f,0x20,0x40,0x44,0xfe,0x40,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,0x14,0xfe,0x0,
-+0x4,0xff,0x4,0x41,0x7f,0x40,0x80,0x7f,0x4,0x4,0xf,0x18,0x28,0x48,0xf,0x8,0x40,0xfe,0x40,0x0,0xfe,0x2,0x4,0xfc,0x0,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,
-+0x4,0xff,0x4,0x41,0x7f,0x40,0x8f,0x8,0x8,0xf,0x8,0xf,0x8,0x8,0xf,0x8,0x40,0xfe,0x40,0x0,0xfe,0x2,0xe4,0x20,0x20,0xe0,0x0,0xf0,0x10,0x10,0xf0,0x0,
-+0x4,0x4,0xff,0x4,0x41,0x7f,0x50,0x9e,0x12,0x22,0x52,0xc,0x4,0x8,0x30,0x40,0x40,0x44,0xfe,0x40,0x0,0xfe,0x2,0xfc,0x88,0x88,0x88,0xa8,0x92,0x82,0x7e,0x0,
-+0x4,0x4,0xff,0x4,0x40,0x7f,0x42,0x84,0x1f,0x1,0x2,0x1f,0x9,0x9,0x31,0x3,0x40,0x44,0xfe,0x40,0x0,0xfe,0x2,0x24,0xc0,0x0,0x20,0xf0,0x20,0x18,0x8,0x0,
-+0x4,0x4,0xff,0x4,0x7c,0x9,0x11,0x11,0x15,0x39,0xd2,0x12,0x12,0x14,0x58,0x20,0x40,0x44,0xfe,0x40,0x1c,0xe0,0x50,0x50,0x50,0x50,0x50,0x48,0x48,0x54,0xf6,0x0,
-+0x4,0x4,0xff,0x4,0x1f,0x0,0x40,0x51,0x49,0x45,0x45,0x49,0x53,0x41,0x7f,0x40,0x40,0x44,0xfe,0x40,0xe0,0x20,0x44,0x94,0x24,0x44,0x44,0x34,0x14,0x4,0xfc,0x4,
-+0x4,0xff,0x4,0x8,0x7e,0x8,0x3e,0x8,0x7e,0x9,0x1,0xff,0x2,0x4,0x18,0x60,0x40,0xfe,0x40,0x8,0xfc,0x48,0x48,0x48,0xa8,0x10,0x4,0xfe,0x80,0x40,0x30,0xc,
-+0x4,0x4,0xff,0x4,0x8,0x7f,0x8,0x8,0x7f,0x0,0x8,0x7f,0x8,0xf,0x78,0x20,0x40,0x44,0xfe,0x40,0x8,0x8,0xfe,0x8,0x48,0x28,0x28,0x8,0x8,0x8,0x28,0x10,
-+0x4,0xff,0x4,0x8,0x3f,0x8,0xf,0x8,0xf,0x8,0xff,0x12,0x14,0x10,0x1f,0x0,0x40,0xfe,0x40,0x20,0xf8,0x20,0xe0,0x20,0xe0,0x24,0xfe,0x80,0x40,0x10,0xf8,0x0,
-+0x4,0x4,0xff,0x4,0x8,0x8,0x7e,0x8,0x18,0x1c,0x2a,0x28,0x48,0x88,0x8,0x8,0x40,0x44,0xfe,0x40,0x4,0xfe,0x84,0x84,0xfc,0x84,0x84,0xfc,0x84,0x84,0xfc,0x84,
-+0x4,0x4,0xff,0x4,0x0,0x3f,0x20,0x3f,0x24,0x3f,0x25,0x29,0x2a,0x44,0x5b,0x80,0x40,0x44,0xfe,0x50,0x48,0xfc,0x40,0xc8,0x48,0xd0,0x20,0x20,0x60,0xa2,0x12,0xe,
-+0x4,0x4,0xff,0x4,0x0,0x3f,0x20,0x2f,0x28,0x2a,0x2a,0x2a,0x2a,0x45,0x44,0x98,0x40,0x44,0xfe,0x50,0x28,0xfc,0x20,0xa0,0xa4,0xa4,0xa8,0xa8,0x90,0x32,0xca,0x86,
-+0x4,0x4,0xff,0x4,0x20,0x3e,0x20,0x2e,0x72,0x4,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x40,0x44,0xfe,0x40,0x80,0x98,0xe0,0x84,0x7c,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,
-+0x4,0xff,0x4,0xf,0x8,0xf,0x0,0xff,0x8,0xf,0x8,0xf,0x8,0x7f,0x0,0x0,0x44,0xfe,0x40,0xe0,0x20,0xe0,0x4,0xfe,0x20,0xe0,0x20,0xe0,0x28,0xfc,0x20,0x20,
-+0x4,0xff,0x5,0x1f,0x11,0x1f,0x1,0xff,0x0,0x1f,0x10,0x11,0x11,0x12,0xc,0x30,0x40,0xfe,0x40,0xf0,0x10,0xf0,0x4,0xfe,0x10,0xf8,0x10,0x10,0x10,0x90,0x60,0x1c,
-+0x4,0x4,0xff,0x4,0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x2,0x29,0x29,0x48,0x7,0x40,0x44,0xfe,0x40,0xf0,0x10,0x10,0xf0,0x10,0x10,0xf0,0x0,0x8,0x24,0x24,0xe0,
-+0x4,0xff,0x4,0x3e,0x22,0x3e,0x0,0x1f,0x0,0xff,0x8,0xf,0x0,0x0,0x0,0x0,0x40,0xfe,0x40,0xf8,0x88,0xf8,0x0,0xf0,0x4,0xfe,0x0,0xf0,0x10,0x10,0xa0,0x40,
-+0x4,0x4,0xff,0x4,0xb,0xa,0x12,0x13,0x30,0x5f,0x90,0x10,0x11,0x12,0x14,0x10,0x40,0x44,0xfe,0x40,0xf8,0x8,0x8,0xf8,0x40,0xfe,0x40,0xe0,0x50,0x4e,0x44,0x40,
-+0x4,0x4,0xff,0x14,0x20,0x7d,0x45,0x45,0x45,0x7d,0x45,0x45,0x45,0x7d,0x44,0x0,0x40,0x44,0xfe,0x40,0x4,0xfe,0x24,0x24,0x24,0x24,0xfc,0x4,0x0,0x2,0xfe,0x0,
-+0x4,0xff,0x5,0x7f,0x0,0x1f,0x10,0x1f,0x40,0x7f,0x40,0x9f,0x1,0x1,0x5,0x2,0x40,0xfe,0x40,0xfc,0x0,0xf0,0x10,0xf0,0x0,0xfe,0x2,0xf4,0x0,0x0,0x0,0x0,
-+0x4,0x4,0xff,0x4,0x11,0x9,0x7f,0x5,0x39,0x2,0xff,0x4,0xc,0x3,0x6,0x38,0x40,0x44,0xfe,0x40,0x10,0x20,0xfc,0x40,0x38,0x0,0xfe,0x40,0x40,0x80,0x60,0x18,
-+0x4,0x4,0xff,0x4,0x20,0x1b,0x4a,0x22,0xa,0x12,0x22,0x64,0x24,0x24,0x28,0x30,0x40,0x44,0xfe,0x40,0x1c,0xe0,0xc,0xf0,0xa4,0xa8,0x90,0x90,0x90,0xa8,0xce,0x84,
-+0x4,0xff,0x4,0x41,0x7f,0x40,0x9f,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x0,0xff,0x0,0x40,0xfe,0x40,0x0,0xfe,0x2,0xf4,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x0,
-+0x4,0x4,0xff,0x4,0x7e,0x42,0x42,0x7e,0x40,0x49,0x7c,0x40,0x44,0x7e,0x41,0x46,0x40,0x44,0xfe,0x40,0xfc,0x4,0x4,0xfc,0x0,0xfc,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x4,0xff,0x5,0x7f,0x1,0x1f,0x2,0xff,0x4,0xf,0x31,0xdf,0x5,0x9,0x31,0x1,0x40,0xfe,0x40,0xfc,0x0,0xf0,0x4,0xfe,0x40,0xf0,0xe,0xf4,0x40,0x30,0x8,0x0,
-+0x4,0xff,0x5,0x3f,0x1,0xff,0x1,0x7,0x1c,0x67,0x0,0xf,0x8,0xf,0x8,0xf,0x40,0xfe,0x40,0xd0,0x24,0xfe,0x0,0xe8,0x8,0xf8,0x0,0xe0,0x20,0xe0,0x20,0xe0,
-+0x4,0xff,0x4,0x3f,0x20,0x2f,0x20,0x3f,0x29,0x2a,0x2c,0x20,0x5f,0x44,0x82,0x0,0x40,0xfe,0x40,0xfc,0x0,0xf0,0x4,0xfe,0x10,0xe0,0x1e,0x20,0xfc,0x20,0x20,0x60,
-+0x4,0xff,0x4,0x1f,0x10,0x1f,0x10,0xff,0x8,0x3f,0xc0,0x8,0xf,0x0,0x3f,0x0,0x40,0xfe,0x40,0xf0,0x10,0xf0,0x14,0xfe,0x20,0xf8,0x26,0x20,0xf8,0x8,0xc8,0x30,
-+0x4,0x4,0xff,0x4,0x1f,0x11,0x11,0x1f,0x11,0x12,0x14,0x1f,0x29,0x28,0x48,0x7,0x40,0x44,0xfe,0x40,0xf0,0x10,0x10,0xf0,0x10,0x90,0x50,0xf0,0x8,0x84,0x24,0xe0,
-+0x4,0x4,0xff,0x4,0x8,0xf,0x10,0x11,0x30,0x5f,0x90,0x13,0x12,0x12,0x13,0x12,0x40,0x44,0xfe,0x80,0x48,0xfc,0x0,0x10,0xa4,0xfe,0x0,0xf8,0x8,0x8,0xf8,0x8,
-+0x4,0xff,0x4,0x5,0xa,0x14,0xef,0x0,0x7e,0x2,0x12,0x6,0x1a,0x63,0xa,0x4,0x40,0xfe,0x40,0x40,0x20,0x50,0xee,0x4,0xf8,0x8,0x48,0x18,0x68,0x88,0x28,0x10,
-+0x4,0xff,0x5,0x7f,0x0,0x1f,0x10,0x1f,0x0,0x7f,0x40,0x4f,0x48,0x4f,0x40,0x40,0x40,0xfe,0x40,0xfc,0x0,0xf0,0x10,0xf0,0x4,0xfe,0x4,0xe4,0x24,0xe4,0x14,0x8,
-+0x4,0x4,0x7f,0x5,0x1f,0x92,0x52,0x13,0x34,0x50,0x9f,0x10,0x20,0x21,0x42,0xc,0x40,0x44,0xfe,0x40,0xfc,0x0,0x10,0xf8,0x40,0x44,0xfe,0xa0,0xa0,0x10,0xe,0x4,
-+0x4,0xff,0x4,0x1,0xff,0x14,0x13,0x14,0x1f,0x1,0x7f,0x42,0x44,0x4f,0x40,0x40,0x40,0xfe,0x40,0x4,0xfe,0x50,0x90,0x50,0xf0,0x4,0xfe,0x4,0x24,0xf4,0x14,0x8,
-+0x4,0xff,0x4,0x1,0x3f,0x4,0x7f,0x42,0x81,0x3f,0x4,0x7,0x8,0x8,0x10,0x60,0x40,0xfe,0x40,0x10,0xf8,0x40,0xfe,0x2,0x14,0xf8,0x0,0xe0,0x20,0x20,0xa0,0x40,
-+0x4,0xff,0x14,0x8,0x7f,0x4,0x3f,0x4,0xff,0x4,0x3f,0xc,0x14,0x24,0xc4,0x4,0x40,0xfe,0x50,0x20,0xfc,0x40,0xf8,0x48,0xfe,0x48,0xf8,0x60,0x50,0x4e,0x44,0x40,
-+0x4,0x4,0xff,0x4,0x22,0x14,0xff,0x8,0x49,0x49,0x7f,0x9,0x8,0x8,0x10,0x21,0x40,0x44,0xfe,0x40,0x7c,0x44,0xc4,0x7c,0x44,0x44,0x7c,0x44,0x44,0x84,0x94,0x8,
-+0x4,0x4,0xff,0x4,0x20,0x1b,0xa,0x43,0x26,0xb,0x12,0x72,0x12,0x12,0x13,0x12,0x40,0x44,0xfe,0x80,0x48,0xfc,0x8,0xf8,0x8,0xf8,0x88,0x50,0x20,0x90,0xe,0x4,
-+0x4,0x4,0xff,0x4,0x7f,0x41,0x82,0xc,0x37,0xc1,0x1f,0x1,0x9,0x5,0x7f,0x0,0x40,0x44,0xfe,0x40,0xfe,0x2,0x84,0x60,0xde,0x4,0xf0,0x0,0x20,0x48,0xfc,0x0,
-+0x4,0x4,0xff,0x4,0x7d,0x4,0x28,0x11,0xfd,0x15,0x11,0x11,0x11,0x10,0x50,0x23,0x40,0x44,0xfe,0x40,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x44,0x58,0x84,0x2,
-+0x4,0x4,0xff,0x4,0x9,0xff,0x8,0x7f,0x49,0x49,0x7f,0x18,0x1c,0x2a,0xc8,0x9,0x40,0x44,0xfe,0x40,0x20,0xa4,0x7e,0x44,0xa8,0x20,0x20,0x20,0x50,0x48,0x8e,0x4,
-+0x4,0xff,0x4,0x3f,0x24,0x3f,0x40,0x7f,0x40,0x9f,0x4,0x7,0xa,0x9,0x1f,0x0,0x40,0xfe,0x40,0xf8,0x48,0xf8,0x0,0xfe,0x22,0xf4,0x0,0xc0,0x40,0x44,0xc4,0x3c,
-+0x4,0x4,0xff,0x5,0xa,0x37,0x24,0x27,0x24,0x2f,0x30,0x4,0x4,0x8,0x30,0xc0,0x40,0x44,0xfe,0x40,0x8,0xfc,0x48,0xc8,0x48,0xc8,0x38,0x40,0x40,0x42,0x42,0x3e,
-+0x4,0x4,0xff,0x4,0x8,0x11,0x25,0x49,0x17,0x30,0x52,0x92,0x13,0x12,0x14,0x18,0x40,0x44,0xfe,0x40,0x48,0x7c,0x40,0x44,0xfe,0x40,0x48,0x7c,0x40,0xc0,0x3e,0x8,
-+0x4,0x4,0xff,0x4,0x8,0x14,0x22,0x41,0xbe,0x0,0x49,0x29,0x2a,0x7,0x78,0x20,0x40,0x44,0xfe,0x40,0x20,0x24,0x3e,0x44,0xa4,0x24,0x24,0x28,0x10,0x28,0x46,0x84,
-+0x4,0x4,0xff,0x4,0x11,0x11,0xfe,0x24,0x20,0x3c,0x25,0x27,0x24,0x44,0x54,0x89,0x40,0x44,0xfe,0x40,0x4,0xfe,0x0,0x88,0xfc,0xa0,0x24,0xfe,0x50,0x50,0x8e,0x4,
-+0x4,0x4,0xff,0x4,0x17,0x45,0x44,0x4f,0x58,0x6f,0x48,0x4f,0x48,0x4f,0x48,0x40,0x40,0x44,0xfe,0x40,0xfc,0x4,0xa4,0xf4,0x84,0xe4,0x84,0xe4,0x84,0xf4,0x14,0x8,
-+0x4,0xff,0x24,0x13,0x42,0x2b,0x12,0x63,0x22,0x23,0x1,0xff,0x5,0x19,0x61,0x1,0x40,0xfe,0x40,0xfc,0x0,0xf8,0x8,0xf8,0x0,0xfc,0x0,0xfe,0x40,0x30,0xc,0x0,
-+0x4,0xff,0x4,0x1,0x7f,0x40,0x84,0x3e,0x0,0xff,0x14,0x14,0x14,0x25,0x44,0x83,0x40,0xfe,0x40,0x0,0xfe,0x42,0x74,0x40,0xf8,0x8,0x50,0x20,0x50,0x8a,0x2,0xfe,
-+0x4,0xff,0x4,0x1,0x7f,0x48,0x88,0x17,0x30,0x53,0x92,0x13,0x12,0x12,0x13,0x12,0x40,0xfe,0x40,0x0,0xfe,0x2,0x8,0xfc,0x40,0xf8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x4,0xff,0x4,0x3e,0x12,0xa,0x13,0x22,0xc,0x31,0xc6,0x18,0x7,0x18,0x3,0x3c,0x40,0xfe,0x40,0xf8,0x48,0x28,0x48,0x88,0x60,0x98,0x6,0xc0,0x18,0x60,0x80,0x0,
-+0x4,0xff,0x5,0x7f,0x1,0x1f,0x11,0x1f,0x11,0x1f,0x1,0x7f,0x12,0x51,0x50,0x8f,0x40,0xfe,0x40,0xfc,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x8,0xfc,0x0,0x14,0x12,0xf2,
-+0x4,0xff,0x4,0x7f,0x4,0x3f,0x24,0x3f,0x10,0x1f,0x10,0x1f,0x1,0xff,0x1,0x1,0x40,0xfe,0x40,0xfc,0x40,0xf8,0x48,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x0,0x0,
-+0x4,0xff,0x4,0x3f,0x28,0x25,0x3f,0x22,0x2a,0x2a,0x2a,0x2f,0x42,0x42,0x84,0x8,0x40,0xfe,0x40,0xfc,0xa0,0x20,0xbe,0x42,0x94,0x90,0x90,0xa8,0xa8,0x28,0x46,0x84,
-+0x4,0xff,0x4,0xff,0x10,0x31,0x4a,0x96,0x25,0x4d,0x15,0x25,0x44,0x84,0x28,0x10,0x40,0xfe,0x40,0x10,0x50,0x7c,0x90,0x10,0x7c,0x10,0x14,0xfe,0x80,0x40,0x3e,0xc,
-+0x4,0xff,0x4,0x1f,0x10,0x1f,0x10,0xff,0x21,0x3f,0x21,0x3f,0x21,0xff,0x1,0x1,0x40,0xfe,0x40,0xf0,0x10,0xf0,0x14,0xfe,0x0,0x7c,0x44,0x28,0x10,0xa8,0x4e,0x84,
-+0x4,0xff,0x4,0x3e,0x22,0x3e,0x0,0xff,0x22,0x3e,0x22,0x3e,0x22,0xff,0x2,0x2,0x40,0xfe,0x40,0x10,0x48,0x48,0x40,0xfe,0x40,0x48,0x48,0x30,0x20,0x52,0x8a,0x4,
-+0x4,0xff,0x4,0x3f,0x24,0x3f,0x0,0x7f,0x40,0x9f,0x10,0x1f,0x10,0x1f,0x10,0x1f,0x40,0xfe,0x40,0xf8,0x48,0xf8,0x0,0xfe,0x2,0xf4,0x10,0xf0,0x10,0xf0,0x10,0xf0,
-+0x4,0xff,0x4,0x3f,0x9,0x5,0xff,0x5,0x9,0x31,0xdf,0x11,0x1f,0x11,0x1f,0x10,0x40,0xfe,0x40,0xf8,0x20,0x44,0xfe,0x40,0x20,0x18,0xf6,0x10,0xf0,0x10,0xf0,0x10,
-+0x4,0xff,0x4,0x22,0x14,0x7f,0x49,0x7f,0x49,0x7f,0x8,0xff,0x8,0x8,0x9,0x8,0x40,0xfe,0x40,0xc,0x70,0x40,0x40,0x7e,0x48,0x48,0x48,0x48,0x88,0x88,0x8,0x8,
-+0x4,0x4,0xff,0x4,0x3e,0x20,0x3d,0x20,0x3c,0x20,0xff,0x10,0x24,0x24,0x7d,0x2,0x40,0x44,0xfe,0x40,0x90,0x90,0xfc,0x90,0x90,0x94,0xfe,0x0,0x90,0x88,0x4,0x4,
-+0x4,0xff,0x4,0x0,0x7e,0x11,0x10,0x1c,0x25,0x54,0x8,0x9,0x10,0x20,0x43,0x0,0x20,0xfe,0x20,0x50,0x50,0xdc,0x50,0x50,0xdc,0x50,0x50,0xdc,0x50,0x54,0xfe,0x0,
-+0x4,0xff,0x4,0x3f,0x24,0x3f,0x0,0x7f,0x40,0x9f,0x8,0x1e,0x32,0x4c,0x8,0x70,0x40,0xfe,0x40,0xf8,0x48,0xf8,0x0,0xfe,0x2,0xf4,0x80,0x90,0xa0,0xc4,0x84,0x7c,
-+0x4,0xff,0x4,0x12,0x1a,0x2a,0x4f,0x90,0x2f,0x60,0xa7,0x25,0x25,0x29,0x28,0x30,0x40,0xfe,0x40,0x20,0xa4,0xbe,0xc4,0x24,0xa4,0x28,0x28,0x10,0x90,0x28,0x46,0x84,
-+0x4,0xff,0x5,0x3f,0x8,0xff,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x9,0x28,0x28,0x47,0x40,0xfe,0x40,0xf8,0x20,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x0,0x88,0x24,0xe4,
-+0x4,0x4,0xff,0x5,0xff,0x10,0x14,0x25,0x7a,0x10,0x24,0x7c,0x4,0x8,0x10,0x60,0x40,0x40,0xfe,0x40,0xfe,0xa0,0x94,0xfe,0x90,0xfc,0x90,0xfc,0x90,0x94,0xfe,0x80,
-+0x4,0x4,0xff,0x4,0x49,0x2a,0xff,0x2a,0x49,0x10,0xff,0x22,0x64,0x18,0x26,0x41,0x40,0x44,0xfe,0x40,0x20,0x24,0x7e,0x84,0x44,0x48,0x48,0x30,0x20,0x50,0x8e,0x4,
-+0x4,0x4,0xff,0x4,0x3e,0x23,0x22,0x3e,0x21,0x20,0x3e,0x53,0x52,0x92,0x1e,0x10,0x40,0x44,0xfe,0x40,0x20,0xfc,0x88,0x50,0xfe,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,
-+0x4,0xff,0x24,0x23,0x22,0xfa,0x4a,0x4b,0x4a,0x92,0x52,0x22,0x55,0x4c,0x88,0x10,0x40,0xfe,0x40,0xfc,0x0,0xf8,0x0,0xfe,0xa8,0x90,0xce,0x8,0xfe,0x88,0x48,0x18,
-+0x4,0xff,0x8,0x3f,0xa,0x9,0x48,0x7f,0x40,0x9f,0x4,0xf,0x1,0x1f,0x1,0x7f,0x40,0xfe,0x20,0xf8,0x20,0x20,0xa0,0xfe,0x2,0xf4,0x40,0xe0,0x0,0xf0,0x0,0xfc,
-+0x4,0xff,0x4,0x7f,0x1,0x7f,0x51,0x8d,0x11,0x7f,0x2,0x3f,0x24,0x24,0x24,0x20,0x40,0xfe,0x40,0xfc,0x0,0xfe,0x12,0x64,0x10,0xfc,0x0,0xf8,0x48,0x48,0x48,0x18,
-+0x4,0xff,0x4,0x3f,0x1,0xff,0x1,0x3f,0x25,0x3f,0x1,0x3f,0x1,0x7f,0x24,0x42,0x40,0xfe,0x40,0xf8,0x0,0xfe,0x0,0xf8,0x48,0xf8,0x0,0xf8,0x0,0xfc,0x88,0x44,
-+0x4,0xff,0x14,0x10,0x3e,0x44,0x88,0x7f,0x49,0x7f,0x49,0x7f,0x0,0xf,0xf0,0x0,0x40,0xfe,0x40,0x44,0x28,0xfe,0x10,0x10,0x7c,0x10,0x10,0xfe,0x10,0x10,0x10,0x10,
-+0x4,0xff,0x5,0x7f,0x9,0x8,0x7f,0x40,0x4f,0x48,0x4f,0x1,0xff,0x5,0x19,0x61,0x40,0xfe,0x40,0xfc,0x20,0xa0,0xfc,0x4,0xe4,0x24,0xec,0x0,0xfe,0x40,0x30,0xc,
-+0x4,0xff,0x4,0x3e,0x8,0x7e,0x18,0x2d,0x4a,0x4,0x19,0xe9,0x5,0x9,0x15,0x2,0x40,0xfe,0x40,0x44,0x7e,0x94,0x24,0x44,0x98,0x40,0x30,0x2e,0x40,0x20,0x10,0x0,
-+0x4,0xff,0x4,0x3f,0x1,0x7f,0x51,0x8d,0x10,0x1f,0x30,0x5f,0x90,0x1f,0x10,0x1f,0x40,0xfe,0x40,0xf8,0x0,0xfe,0x12,0x64,0x90,0xfc,0x80,0xf8,0x80,0xf8,0x80,0xfc,
-+0x4,0xff,0x4,0x40,0x30,0x17,0x4,0x5,0xf4,0x15,0x16,0x15,0x14,0x19,0x28,0x47,0x40,0xfe,0x40,0x78,0x40,0xfc,0x44,0xf0,0x44,0x3c,0xa8,0x68,0xa8,0x24,0x40,0xfe,
-+0x4,0xff,0x4,0x12,0x13,0x24,0x4f,0x95,0x27,0x65,0xa7,0x21,0x2f,0x21,0x22,0x2c,0x40,0xfe,0x40,0x0,0xdc,0x80,0xc0,0x7e,0xc8,0x48,0xc8,0x8,0xe8,0x8,0x88,0x58,
-+0x4,0xff,0x24,0x3f,0x40,0xbf,0x29,0xff,0x25,0x3f,0x2,0xf,0x2,0x1f,0x5,0x39,0x40,0xfe,0x20,0xa4,0x7e,0x84,0x24,0xa8,0x10,0x2e,0x44,0xe0,0x20,0xf0,0x40,0x38,
-+0x4,0xff,0x14,0x3f,0x62,0x3e,0x21,0x3e,0x23,0x3e,0x1,0xff,0x5,0x19,0x61,0x1,0x40,0xfe,0x20,0xfc,0x88,0x50,0xfc,0x20,0xfc,0x20,0x24,0xfe,0x40,0x30,0xc,0x0,
-+0x2,0x7f,0x2,0x3f,0x22,0x3f,0x2b,0x32,0x21,0x2f,0x21,0x2f,0x41,0x5f,0x81,0x1,0x20,0xfe,0xa0,0xfc,0x10,0xfe,0x54,0x92,0x20,0x3c,0x20,0x3c,0x20,0x3e,0x20,0x20,
-+0x0,0x0,0x0,0x0,0x4,0x4,0x4,0x4,0x4,0xff,0x4,0x4,0x8,0x8,0x10,0x20,0x0,0x0,0x0,0x0,0x40,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x2,0x1,0x7f,0x4,0x14,0x24,0x48,0x10,0x4,0x4,0xff,0x4,0x4,0x8,0x10,0x20,0x0,0x8,0xfc,0x40,0x50,0x4c,0xc4,0x0,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x1,0x1,0xff,0x2,0x4,0x8,0x30,0xc9,0x9,0x9,0x9,0x9,0x11,0x11,0x21,0x0,0x0,0x4,0xfe,0x80,0x40,0x30,0xe,0x24,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x1,0x1,0xff,0x2,0x4,0x8,0x3f,0xd0,0x14,0x12,0x11,0x12,0x14,0x18,0x1f,0x0,0x0,0x4,0xfe,0x80,0x40,0x20,0xf8,0x26,0x40,0x80,0x0,0x80,0x60,0x20,0xf8,0x0,
-+0x1,0x1,0xff,0x2,0x4,0x8,0x3f,0xc8,0xf,0x8,0xf,0x8,0x8,0x7f,0x0,0x0,0x0,0x4,0xfe,0x80,0x40,0x20,0xf8,0x26,0xe0,0x20,0xe0,0x28,0xfc,0x20,0x20,0x20,
-+0x2,0x1,0x7f,0x4,0x14,0x24,0x48,0x11,0x1,0xff,0x2,0x2,0x4,0x8,0x30,0xc0,0x0,0x8,0xfc,0x40,0x50,0x4c,0xc4,0x0,0x4,0xfe,0x80,0x80,0x40,0x30,0xe,0x4,
-+0x0,0x7f,0x22,0x11,0x12,0x4,0x1f,0x2,0x4,0x1f,0x1,0xff,0x1,0x2,0xc,0x70,0x3c,0xc8,0x8,0x10,0x40,0x20,0xf0,0x0,0x20,0xf0,0x4,0xfe,0x0,0x80,0x60,0x1c,
-+0x4,0x24,0x24,0x3d,0x4,0x7c,0x24,0x25,0x44,0x1,0xff,0x1,0x2,0x4,0x18,0x60,0x20,0x20,0x28,0xfc,0x20,0x20,0x28,0xfc,0x0,0x4,0xfe,0x0,0x80,0x40,0x30,0xe,
-+0x10,0x10,0x10,0xfe,0x29,0x46,0xfd,0x1,0xff,0x21,0x3d,0x5,0x5,0x5,0x28,0x10,0x80,0x80,0x88,0xfc,0x8,0x8,0xe8,0x28,0x28,0xe8,0x28,0x10,0x2,0x2,0xfe,0x0,
-+0x2,0x2,0x2,0x2,0xff,0x2,0x2,0x2,0x2,0x4,0x4,0x4,0x8,0x10,0x20,0x40,0x0,0x0,0x0,0x4,0xfe,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x84,0x84,0x7c,0x0,
-+0x20,0x20,0x20,0x20,0xfd,0x29,0x2a,0x28,0x28,0x28,0x28,0x28,0x28,0x48,0x47,0x80,0x80,0x80,0x88,0xfc,0x8,0x8,0x88,0x48,0x48,0x8,0x8,0x88,0x52,0x22,0xfe,0x0,
-+0x20,0x20,0x20,0x20,0xfd,0x2a,0x2c,0x28,0x28,0x28,0x29,0x29,0x2a,0x48,0x47,0x80,0x20,0x20,0x50,0x90,0x8,0x6,0x94,0x90,0x90,0x90,0x10,0x10,0x12,0x2,0xfe,0x0,
-+0x20,0x22,0x22,0x22,0xfe,0x2a,0x28,0x28,0x2b,0x2a,0x2a,0x2a,0x2f,0x48,0x47,0x80,0x90,0x90,0xa0,0xfc,0x80,0x90,0x88,0x80,0xf8,0xa8,0xa8,0xa8,0xfe,0x2,0xfe,0x0,
-+0x10,0x10,0x10,0x10,0xfc,0x10,0x10,0x14,0x18,0x30,0xd0,0x10,0x10,0x10,0x50,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x12,0x11,0x12,0xfe,0x12,0x12,0x16,0x1a,0x32,0xd2,0x12,0x12,0x12,0x52,0x20,0x0,0x4,0x7e,0x84,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x14,0x8,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x17,0x14,0x18,0x31,0xd0,0x13,0x10,0x10,0x50,0x20,0x40,0x40,0x48,0xfc,0x40,0x44,0xfe,0x80,0x80,0xf8,0x8,0x10,0xd0,0x20,0x10,0x8,
-+0x10,0x10,0x10,0x10,0xfb,0x12,0x12,0x1b,0x32,0xd2,0x13,0x12,0x10,0x10,0x50,0x20,0x40,0x40,0x40,0x44,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x44,0x40,0x40,0x40,0x40,
-+0x10,0x10,0x10,0x11,0xfd,0x13,0x15,0x15,0x19,0x31,0xd1,0x11,0x11,0x11,0x51,0x21,0x88,0x88,0x88,0x8,0x8,0xfe,0x8,0x48,0x28,0x28,0x8,0x8,0x8,0x8,0x28,0x10,
-+0x10,0x10,0x10,0x11,0xff,0x10,0x11,0x15,0x19,0x37,0xd1,0x11,0x11,0x11,0x52,0x24,0x40,0x40,0x90,0x8,0xfc,0x4,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x10,0x11,0x11,0x12,0xfa,0x14,0x1f,0x11,0x1a,0x32,0xd4,0x1f,0x10,0x10,0x50,0x21,0x20,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xa4,0xa4,0x44,0x44,0x94,0x8,
-+0x10,0x10,0x10,0x10,0xff,0x10,0x10,0x17,0x18,0x30,0xd3,0x12,0x12,0x12,0x53,0x22,0x40,0x40,0x40,0x44,0xfe,0x40,0x48,0xfc,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x17,0x10,0xfc,0x17,0x10,0x15,0x1a,0x35,0xd9,0x11,0x11,0x12,0x52,0x24,0x8,0x3c,0xc0,0x40,0x84,0xfe,0xa0,0x10,0x8,0x16,0x14,0x10,0x10,0x10,0x10,0x10,
-+0x11,0x11,0x12,0x11,0xfd,0x10,0x10,0x14,0x19,0x31,0xd2,0x14,0x10,0x10,0x50,0x23,0x24,0x24,0x48,0x24,0x24,0x80,0x84,0xfe,0x4,0x84,0x48,0x28,0x10,0x20,0xc0,0x0,
-+0x10,0x11,0x11,0x11,0xfd,0x10,0x13,0x16,0x1a,0x32,0xd3,0x12,0x12,0x12,0x52,0x21,0x8,0xfc,0x8,0x8,0xf8,0x4,0xfe,0x44,0x44,0x44,0xfc,0x4,0x0,0x2,0x2,0xfe,
-+0x10,0x10,0x17,0x12,0xfd,0x11,0x10,0x14,0x1b,0x30,0xd1,0x10,0x10,0x10,0x50,0x20,0x8,0x7c,0x80,0x48,0x48,0x50,0x20,0x8,0xfe,0x8,0x8,0x88,0x88,0x8,0x28,0x10,
-+0x10,0x17,0x11,0x11,0xff,0x11,0x11,0x17,0x19,0x32,0xd3,0x15,0x15,0x19,0x51,0x21,0x8,0xfc,0x8,0x8,0xfe,0x8,0x8,0xf8,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x13,0x10,0x10,0xfc,0x17,0x10,0x15,0x1a,0x34,0xd9,0x11,0x12,0x14,0x51,0x20,0x8,0xfc,0x40,0x40,0x84,0xfe,0xa0,0x10,0x4e,0x44,0x68,0x54,0x54,0x44,0x40,0x80,
-+0x20,0x2f,0x24,0x24,0xfc,0x27,0x24,0x24,0x2f,0x34,0xe4,0x24,0x2f,0x20,0xa0,0x40,0x0,0xfc,0xa4,0xa4,0xa4,0xa8,0xa4,0xa4,0xa2,0xa2,0xa2,0xb4,0xe8,0xa0,0xa0,0xa0,
-+0x10,0x13,0x12,0x12,0xff,0x12,0x12,0x17,0x1a,0x32,0xd3,0x12,0x14,0x14,0x5b,0x20,0x4,0xfe,0x20,0x28,0xfc,0x20,0x24,0xfe,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x10,0x10,0x17,0xf8,0x11,0x12,0x15,0x18,0x30,0xd7,0x10,0x12,0x12,0x55,0x20,0x40,0x40,0x48,0xfc,0xa0,0x10,0x8,0xf6,0x4,0x8,0xfc,0x40,0x50,0x4c,0x44,0x80,
-+0x10,0x10,0x17,0x10,0xfc,0x11,0x17,0x10,0x18,0x33,0xd2,0x12,0x13,0x10,0x50,0x20,0x40,0x48,0xfc,0x40,0xa0,0x14,0xfe,0x8,0x8,0xc8,0x48,0x48,0xc8,0x8,0x28,0x10,
-+0x20,0x27,0x24,0x24,0xfd,0x24,0x24,0x25,0x2c,0x34,0xe4,0x27,0x24,0x24,0xa7,0x44,0x4,0xfe,0x4,0x4,0xf4,0x44,0x44,0xf4,0x44,0x54,0x44,0xfc,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x13,0x12,0xfe,0x13,0x12,0x16,0x1b,0x30,0xd1,0x1f,0x10,0x10,0x50,0x20,0x40,0x84,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0xa0,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x11,0x11,0x11,0x13,0xfe,0x14,0x12,0x10,0x1b,0x30,0xd1,0x12,0x14,0x10,0x50,0x20,0x0,0x0,0x4,0xfe,0x84,0x94,0xa4,0x84,0xf4,0x84,0xc4,0xb4,0x94,0x84,0x14,0x8,
-+0x10,0x10,0x10,0x17,0xfc,0x11,0x10,0x17,0x18,0x30,0xd3,0x12,0x12,0x12,0x53,0x22,0x80,0x40,0x48,0xfc,0x0,0x10,0xa4,0xfe,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x13,0x12,0xfe,0x13,0x12,0x16,0x1a,0x33,0xd2,0x12,0x14,0x14,0x59,0x22,0x40,0x24,0xfe,0x4,0x4,0xfc,0x20,0x28,0x24,0xfe,0x50,0x50,0x88,0x88,0x6,0x4,
-+0x10,0x10,0x13,0x12,0xfe,0x13,0x12,0x16,0x1a,0x32,0xd2,0x12,0x14,0x14,0x58,0x20,0x40,0x24,0xfe,0x4,0x4,0xfc,0x0,0xfc,0x84,0xfc,0x84,0xfc,0x84,0x84,0x94,0x88,
-+0x10,0x13,0x12,0x17,0xfa,0x12,0x13,0x10,0x1b,0x32,0xd2,0x12,0x12,0x10,0x51,0x26,0x8,0xfc,0x48,0xfe,0x48,0x48,0xf8,0x0,0xf8,0x8,0x48,0x48,0x48,0xb0,0x8,0x4,
-+0x10,0x12,0x12,0x17,0xfa,0x12,0x12,0x16,0x1b,0x30,0xd7,0x10,0x11,0x12,0x54,0x20,0x90,0x90,0x94,0xfe,0x90,0x90,0xf0,0x0,0xfc,0x40,0xfe,0xe0,0x50,0x4e,0x44,0x40,
-+0x10,0x10,0x17,0x10,0xfc,0x11,0x12,0x14,0x1b,0x32,0xd3,0x12,0x13,0x10,0x5f,0x20,0x40,0x48,0xfc,0x40,0xe0,0x50,0x4e,0x44,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xfe,0x0,
-+0x10,0x17,0x14,0x15,0xfd,0x15,0x15,0x15,0x1c,0x37,0xd4,0x15,0x14,0x14,0x57,0x20,0x8,0xfc,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x40,0xfe,0x88,0x90,0x60,0x98,0xfe,0x0,
-+0x20,0x24,0x24,0x27,0xf4,0x28,0x37,0x22,0x32,0x2f,0xe2,0x22,0x23,0x22,0xa0,0x41,0x20,0x20,0x20,0xa4,0x3e,0x44,0xa8,0x20,0x20,0xa0,0x20,0x50,0x50,0x88,0x8e,0x4,
-+0x10,0x10,0x10,0x11,0xfe,0x15,0x18,0x13,0x1a,0x33,0xd2,0x13,0x12,0x12,0x52,0x22,0x40,0x40,0xa0,0x10,0x8,0xf6,0x0,0xc4,0x54,0xd4,0x54,0xd4,0x54,0x44,0x54,0xc8,
-+0x10,0x10,0x17,0x10,0xfd,0x10,0x1f,0x14,0x1b,0x32,0xd2,0x13,0x12,0x12,0x53,0x22,0x80,0x48,0xfc,0x0,0x10,0xa4,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x10,0x14,0x17,0x14,0xfc,0x13,0x10,0x13,0x1a,0x33,0xd2,0x13,0x12,0x10,0x57,0x20,0x80,0x40,0xfe,0x2,0x8,0xfc,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x8,0x4,0xfe,0x0,
-+0x20,0x27,0x24,0x24,0xff,0x25,0x24,0x27,0x2c,0x34,0xe7,0x24,0x28,0x28,0xb1,0x42,0x4,0xfe,0x4,0x4,0xfc,0x8,0x90,0xfc,0x90,0x94,0xfe,0x90,0x90,0x90,0x10,0x10,
-+0x10,0x17,0x10,0x14,0xfb,0x11,0x12,0x13,0x1c,0x30,0xd7,0x10,0x10,0x11,0x52,0x24,0x20,0xa8,0xb0,0xa4,0x28,0x10,0x8,0xf6,0x44,0x40,0xfc,0x80,0xa0,0x10,0x8,0x4,
-+0x10,0x10,0x10,0x11,0xfd,0x10,0x17,0x14,0x19,0x36,0xd1,0x16,0x11,0x16,0x50,0x20,0x80,0x80,0xf8,0x8,0xf0,0x14,0xfe,0x88,0x50,0xa0,0x30,0x68,0xae,0x24,0xa0,0x40,
-+0x10,0x10,0x10,0x13,0xfe,0x12,0x13,0x16,0x1a,0x32,0xd2,0x14,0x1a,0x12,0x54,0x20,0x48,0x7c,0x40,0xfc,0x44,0x48,0xf8,0x40,0x44,0x3c,0x0,0xa0,0x94,0x82,0x8a,0x78,
-+0x10,0x13,0x12,0x12,0xff,0x12,0x12,0x17,0x1a,0x33,0xd0,0x11,0x15,0x15,0x59,0x20,0x8,0xfc,0x48,0x48,0xf8,0x48,0xa8,0x18,0x8,0xf8,0x0,0x40,0x44,0x12,0x12,0xf0,
-+0x10,0x10,0x17,0x14,0xfc,0x15,0x15,0x15,0x1d,0x35,0xd5,0x15,0x15,0x16,0x58,0x23,0x8,0x7c,0xa0,0x3c,0x20,0xfe,0x22,0xf8,0x24,0x3c,0x0,0x78,0x48,0x4a,0x8a,0x6,
-+0x12,0x11,0x10,0x17,0xf8,0x10,0x17,0x10,0x1f,0x30,0xd7,0x11,0x12,0x14,0x58,0x20,0x8,0x10,0xa4,0xfe,0xa0,0xa4,0xfe,0xa4,0xfe,0xa4,0xfc,0xb0,0xa8,0xa6,0xa4,0xa0,
-+0x20,0x28,0x25,0x20,0xff,0x22,0x2a,0x2a,0x2a,0x3a,0xef,0x22,0x22,0x24,0xa8,0x51,0x4,0xbe,0x24,0x24,0xe4,0x3c,0xa4,0xa4,0xa4,0xbc,0xa4,0xa4,0x44,0x44,0x94,0x8,
-+0x10,0x13,0x12,0x12,0xff,0x12,0x12,0x17,0x1a,0x32,0xd3,0x15,0x15,0x15,0x59,0x21,0x4,0xfe,0x4,0x4,0xfc,0x94,0x90,0xfc,0x90,0x94,0xfe,0x40,0x28,0x10,0x8e,0x4,
-+0x10,0x17,0x10,0x10,0xff,0x14,0x14,0x17,0x18,0x34,0xd2,0x12,0x14,0x10,0x52,0x21,0x4,0xbe,0x84,0x84,0xbc,0x20,0x24,0xbe,0x84,0xa4,0x94,0x94,0xa4,0x84,0x94,0x8,
-+0x10,0x13,0x11,0x10,0xfb,0x10,0x17,0x14,0x1b,0x34,0xd0,0x1f,0x11,0x12,0x54,0x20,0x0,0xf8,0x10,0xe0,0x18,0x0,0xbc,0xa4,0x18,0xa4,0x40,0xfe,0x50,0x48,0x46,0x40,
-+0x10,0x17,0x14,0x17,0xfc,0x17,0x14,0x11,0x1b,0x30,0xd0,0x17,0x11,0x12,0x54,0x20,0x4,0xfe,0x44,0xfc,0x44,0xfc,0x84,0x10,0xe0,0x40,0x88,0xfc,0x50,0x4c,0x44,0xc0,
-+0x10,0x17,0x14,0x15,0xfd,0x16,0x13,0x14,0x18,0x37,0xd1,0x12,0x11,0x10,0x51,0x26,0x0,0xbc,0xa4,0xac,0xac,0x34,0x18,0xa4,0x80,0xfe,0x10,0x10,0x20,0xe0,0x98,0x4,
-+0x10,0x10,0x13,0x12,0xfe,0x12,0x13,0x16,0x1a,0x32,0xd4,0x14,0x15,0x15,0x5a,0x20,0x40,0x24,0xfe,0x88,0x88,0x88,0xfe,0x88,0x88,0xf8,0x88,0x0,0x54,0x52,0x52,0x0,
-+0x20,0x20,0x27,0x21,0xfa,0x2f,0x24,0x27,0x2c,0x37,0xe4,0x24,0x3f,0x20,0xa0,0x40,0x0,0x10,0x90,0x24,0x3e,0xc4,0xa4,0xa8,0xa8,0xa8,0x90,0xd0,0xa8,0xa8,0xc6,0x84,
-+0x10,0x17,0x10,0x14,0xfa,0x12,0x14,0x10,0x1b,0x32,0xd2,0x13,0x12,0x12,0x53,0x22,0x4,0xbe,0x84,0xa4,0x94,0x94,0xa4,0x48,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x10,0x12,0x12,0x12,0xff,0x12,0x12,0x17,0x18,0x37,0xd5,0x15,0x15,0x17,0x50,0x21,0x0,0x4,0x7e,0x10,0xa4,0x7e,0x44,0xd4,0x54,0x54,0x54,0x54,0x54,0x20,0x4c,0x82,
-+0x11,0x13,0x14,0x17,0xfc,0x17,0x14,0x17,0x18,0x37,0xd0,0x13,0x12,0x13,0x52,0x23,0x0,0xf0,0x24,0xfe,0x44,0xfc,0x44,0xfc,0x0,0xfe,0x0,0xf8,0x8,0xf8,0x8,0xf8,
-+0x12,0x11,0x17,0x10,0xfb,0x12,0x13,0x12,0x1a,0x33,0xd0,0x1f,0x12,0x11,0x50,0x20,0x8,0x10,0xfc,0xa8,0xfc,0xa8,0x18,0xe8,0x8,0xf8,0x14,0xfe,0x10,0x10,0x50,0x20,
-+0x10,0x10,0x17,0x15,0xfa,0x14,0x13,0x12,0x1b,0x30,0xd7,0x14,0x17,0x10,0x50,0x20,0x80,0x40,0xfe,0x12,0x48,0x44,0xf8,0x48,0xf8,0x40,0xfc,0x44,0xfc,0x40,0x40,0x40,
-+0x22,0x22,0x22,0x2f,0xf2,0x2f,0x28,0x2f,0x38,0xef,0x22,0x2f,0x22,0x22,0xa2,0x42,0x10,0x10,0x28,0xa8,0x44,0x82,0xfc,0x90,0x90,0x94,0x7e,0x90,0x10,0x10,0x10,0x10,
-+0x10,0x17,0x14,0x14,0xff,0x10,0x17,0x10,0x1b,0x32,0xd3,0x11,0x13,0x15,0x59,0x21,0x4,0xfe,0xa4,0xa4,0xfc,0x0,0xfe,0x0,0xf8,0x8,0xf8,0x44,0x28,0x10,0x8e,0x4,
-+0x20,0x20,0x27,0x24,0xf4,0x27,0x24,0x34,0x27,0xe6,0x26,0x2a,0x2a,0x33,0xa2,0x40,0x10,0x8,0xc8,0x7e,0x40,0xd4,0x14,0x3e,0xc8,0x48,0x7e,0x48,0x48,0xc8,0x48,0x8,
-+0x10,0x13,0x12,0x12,0xfb,0x10,0x17,0x14,0x1f,0x34,0xd7,0x10,0x1f,0x11,0x51,0x26,0x80,0xf8,0x88,0x48,0xf8,0x0,0xfc,0x44,0xfc,0x44,0xfc,0x0,0xfe,0x10,0x10,0x10,
-+0x10,0x17,0x10,0x12,0xf8,0x12,0x11,0x11,0x1a,0x37,0xda,0x13,0x12,0x12,0x53,0x22,0x0,0xbc,0x84,0x94,0x84,0x94,0x20,0xfe,0x20,0xfc,0x20,0xfc,0x20,0x24,0xfe,0x0,
-+0x20,0x27,0x20,0x2f,0xfa,0x21,0x22,0x28,0x37,0xe4,0x2f,0x34,0x27,0x24,0xa7,0x44,0x8,0xfc,0x40,0xfe,0x4a,0x50,0x48,0x40,0xfc,0x40,0xf8,0x40,0xf8,0x40,0xfe,0x0,
-+0x12,0x13,0x15,0x13,0xfe,0x12,0x13,0x18,0x17,0x31,0xd2,0x1d,0x10,0x13,0x51,0x26,0x10,0xde,0x28,0xf8,0x88,0x48,0xf8,0x80,0xfe,0x50,0x98,0xe6,0x90,0xf8,0x50,0x4c,
-+0x20,0x27,0x20,0x23,0xf2,0x2f,0x29,0x27,0x21,0x33,0xe1,0x27,0x21,0x23,0xad,0x41,0x40,0xfc,0x40,0xf8,0x48,0xfe,0x12,0xfc,0x10,0xf8,0x10,0xfc,0x48,0x30,0x8e,0x4,
-+0x2,0x2,0x2,0x2,0x3,0xfe,0x2,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x40,0x20,0x24,0xfe,0x0,0x0,0x0,0x0,0x0,0x80,0x80,0x44,0x24,0x1c,0x0,
-+0x0,0x0,0x0,0x0,0xff,0x0,0x8,0x4,0x14,0x54,0x50,0x50,0x91,0x11,0xf,0x0,0x80,0xa0,0x94,0xfe,0x80,0x40,0x40,0x40,0x20,0xa0,0x60,0x50,0x12,0xa,0xa,0x4,
-+0x0,0x0,0x0,0x0,0xff,0x22,0x22,0xff,0x22,0x22,0x3e,0x22,0x22,0x3e,0x22,0x0,0x80,0xa0,0x94,0xfe,0x80,0x40,0x40,0xc0,0x40,0x40,0x20,0x20,0x12,0x12,0xa,0x4,
-+0x0,0x22,0x14,0xb,0x14,0x62,0x8,0x9,0xfe,0x8,0x2c,0x2a,0x48,0xb,0x28,0x10,0x20,0x28,0x24,0xfe,0x20,0x20,0x20,0xd0,0x90,0x90,0x90,0x90,0xf2,0x8a,0xa,0x4,
-+0x0,0x0,0x8,0x7c,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x78,0x48,0x0,0x0,0x0,0x80,0x80,0x80,0x80,0x80,0xa0,0x98,0x8c,0x84,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
-+0x0,0x8,0x7c,0x48,0x48,0x48,0x48,0x49,0x4a,0x4c,0x48,0x78,0x48,0x0,0x0,0x0,0x80,0x80,0x88,0x98,0xa0,0xc0,0x80,0x80,0x80,0x80,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x0,0x9,0x7d,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x79,0x4a,0x2,0x4,0x8,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x0,0x8,0x7c,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x78,0x48,0x0,0x0,0x0,0x8,0xfc,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xc8,0xa8,0x90,0x80,0x80,0x80,
-+0x0,0x8,0x7d,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x79,0x49,0x2,0x4,0x8,0x0,0x4,0xfe,0x44,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x4,0x4,0x4,0x28,0x10,
-+0x0,0x8,0x7c,0x48,0x4b,0x48,0x48,0x48,0x48,0x48,0x48,0x79,0x49,0x2,0x4,0x8,0x40,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0x84,0x84,0x4,0x4,0x4,0x28,0x10,
-+0x0,0x8,0x7d,0x48,0x48,0x48,0x48,0x4f,0x48,0x48,0x48,0x78,0x48,0x0,0x0,0x0,0x8,0x1c,0xe0,0x40,0x40,0x44,0x7e,0xc0,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x0,0xa,0x7d,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x78,0x48,0x0,0x0,0x0,0x0,0x4,0xc,0x90,0xa0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x8,0x7c,0x48,0x48,0x49,0x4b,0x48,0x48,0x48,0x48,0x78,0x49,0x2,0x3,0x0,0x40,0x40,0x40,0x80,0x84,0x4,0xf8,0x8,0x10,0x20,0x40,0x80,0x8,0x4,0xfe,0x2,
-+0x0,0x8,0x7c,0x4b,0x48,0x48,0x48,0x4f,0x48,0x48,0x48,0x79,0x49,0x2,0x4,0x8,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x40,0xa0,0xa0,0x10,0x10,0x8,0xe,0x4,
-+0x0,0xb,0x7c,0x48,0x48,0x48,0x4f,0x48,0x48,0x48,0x49,0x79,0x4a,0x2,0x4,0x8,0x8,0xfc,0x80,0x80,0x80,0x84,0xfe,0xa0,0xa0,0xa0,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x0,0x0,0x7b,0x48,0x48,0x4b,0x48,0x48,0x48,0x48,0x49,0x7a,0x4a,0x2,0x1,0x0,0x90,0x94,0xfe,0x90,0x0,0xf8,0x10,0x20,0x40,0x80,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x0,0x8,0x7c,0x48,0x4f,0x48,0x48,0x48,0x48,0x48,0x49,0x79,0x4a,0x4,0x8,0x10,0x40,0x40,0x40,0x44,0xfe,0x40,0xa0,0xa0,0xa0,0xa0,0x10,0x90,0x48,0x48,0x6,0x4,
-+0x0,0xb,0x7e,0x4a,0x4a,0x4b,0x4a,0x4a,0x4a,0x4a,0x4a,0x7a,0x44,0x4,0x9,0x12,0x4,0xfe,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x28,0x10,
-+0x0,0xb,0x7e,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x7a,0x44,0x4,0x8,0x10,0x4,0xfe,0x0,0x8,0xfc,0x88,0x88,0x88,0x88,0xa8,0x90,0x80,0x82,0x82,0x7e,0x0,
-+0x0,0x2,0xa,0x7e,0x4a,0x4a,0x4b,0x4a,0x4a,0x4a,0x4a,0x7a,0x4a,0x3,0x2,0x0,0x20,0x20,0x20,0x20,0x24,0x28,0xb0,0x20,0x20,0x20,0x20,0x20,0xa2,0x22,0x1e,0x0,
-+0x0,0x9,0x7d,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x79,0x48,0x0,0x1,0x2,0x4,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x40,0x98,0x6,0x2,
-+0x0,0x1f,0x10,0x10,0x10,0x1f,0x11,0x1,0x7f,0x42,0x42,0x44,0x48,0x40,0x40,0x40,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,0x4,0xfe,0x84,0x44,0x24,0x24,0x4,0x14,0x8,
-+0x0,0x0,0x8,0x7c,0x48,0x48,0x4a,0x4a,0x4a,0x4a,0x4a,0x7a,0x44,0x0,0x0,0x0,0x40,0x20,0x20,0x20,0xa0,0x80,0x88,0x84,0x82,0x82,0x82,0x8a,0x8a,0x88,0x78,0x0,
-+0x0,0xb,0x7c,0x48,0x48,0x4b,0x4a,0x4a,0x4a,0x4b,0x48,0x78,0x48,0x2,0x1,0x0,0x24,0xf4,0x24,0x24,0x24,0xe4,0x4,0x4,0x24,0xf4,0x24,0x24,0x24,0x24,0x44,0x84,
-+0x0,0x3,0x7a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x7a,0x4a,0x2,0x3,0x0,0x8,0xfc,0x20,0x28,0xfc,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xb8,0x20,0x24,0xfe,0x0,
-+0x0,0x0,0x8,0x7c,0x48,0x48,0x48,0x4f,0x48,0x48,0x48,0x78,0x48,0x0,0x0,0x0,0x80,0x80,0x88,0xfc,0x80,0x80,0x84,0xfe,0x80,0xa0,0x90,0x88,0x88,0x80,0x80,0x80,
-+0x0,0x9,0x7d,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x79,0x48,0x0,0x0,0x0,0x0,0x4,0xfe,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0xfc,0x24,0x20,0x20,0x20,0x20,0x20,
-+0x0,0x0,0x7b,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x7a,0x44,0x5,0x9,0x10,0x8,0x1c,0xe0,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0xa4,0x14,0xf2,0x0,
-+0x0,0x0,0x8,0x7c,0x49,0x4a,0x4c,0x48,0x48,0x4b,0x48,0x79,0x48,0x0,0x0,0x0,0x40,0x40,0xa0,0xa0,0x10,0x8e,0x64,0x20,0x0,0xf8,0x8,0x10,0xa0,0x40,0x20,0x20,
-+0x0,0x8,0x7c,0x49,0x49,0x4a,0x48,0x48,0x49,0x4a,0x4c,0x78,0x49,0x0,0x0,0x0,0x80,0x80,0xf8,0x8,0x10,0xa0,0x40,0xa0,0x10,0x8e,0x64,0x20,0x80,0x60,0x10,0x0,
-+0x0,0x8,0x7c,0x4b,0x4a,0x4a,0x48,0x4b,0x48,0x48,0x48,0x78,0x48,0x0,0x0,0x0,0x40,0x20,0x20,0xfe,0x2,0x4,0x0,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x0,0x8,0x7d,0x49,0x49,0x49,0x49,0x48,0x48,0x49,0x49,0x79,0x49,0x1,0x1,0x0,0x20,0x20,0x24,0x24,0x24,0x24,0xfc,0x24,0x20,0x24,0x24,0x24,0x24,0x24,0xfc,0x4,
-+0x2,0x12,0x7a,0x52,0x5f,0x52,0x52,0x52,0x54,0x54,0x55,0x72,0x55,0x8,0x10,0x0,0x0,0x0,0x8,0x7c,0x88,0x88,0xa8,0xa8,0xa8,0x90,0x10,0x28,0x28,0xc4,0x44,0x82,
-+0x0,0x11,0x79,0x51,0x52,0x54,0x5f,0x51,0x52,0x52,0x54,0x7f,0x54,0x0,0x1,0x2,0x20,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xa4,0xc4,0x44,0x84,0x28,0x10,
-+0x0,0x11,0x79,0x51,0x52,0x52,0x57,0x51,0x52,0x52,0x54,0x77,0x50,0x0,0xf,0x0,0x0,0x8,0x8,0x8,0x10,0x94,0xbc,0x8,0x10,0x10,0x20,0xbc,0x0,0x4,0xfe,0x0,
-+0x0,0xb,0x7e,0x4a,0x4b,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x7b,0x4a,0x2,0x3,0x0,0x8,0xfc,0x0,0x8,0xfc,0x20,0x20,0xf8,0x20,0x20,0x28,0xfc,0x0,0x4,0xfe,0x0,
-+0x0,0x8,0x7c,0x4b,0x48,0x48,0x49,0x48,0x48,0x49,0x49,0x79,0x49,0x1,0x1,0x1,0x20,0x20,0x24,0xfe,0x20,0x20,0xfc,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x7,0x8,0x7c,0x48,0x4b,0x4a,0x4a,0x4a,0x4a,0x4a,0x7b,0x4a,0x2,0x3,0x2,0x4,0xfe,0x90,0x90,0x94,0xfe,0x94,0x94,0x94,0x94,0x9c,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x0,0x8,0x7f,0x48,0x48,0x49,0x49,0x4a,0x4c,0x49,0x78,0x48,0x0,0x1,0x2,0x80,0x80,0x84,0xfe,0x80,0xa0,0x20,0x24,0xac,0xb0,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x0,0x0,0x70,0x54,0x52,0x52,0x50,0x5e,0x52,0x52,0x52,0x72,0x53,0x6,0x9,0x0,0x20,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x50,0x48,0x8c,0x4,0x0,0x6,0xfc,
-+0x0,0x7,0x9,0x7d,0x49,0x4a,0x4a,0x4a,0x4d,0x48,0x48,0x79,0x49,0x2,0x4,0x8,0x44,0xe4,0x4,0x4,0xd4,0x54,0x54,0x54,0x54,0x94,0x94,0x14,0x4,0x4,0x14,0x8,
-+0x0,0x0,0x7b,0x48,0x4b,0x48,0x48,0x4b,0x4a,0x4a,0x7b,0x48,0x0,0x1,0x2,0xc,0x40,0x48,0xfc,0x40,0xf8,0x48,0x48,0xf8,0x40,0x44,0xfe,0x44,0xac,0x10,0x8,0x6,
-+0x0,0x8,0x7c,0x4b,0x48,0x48,0x48,0x4b,0x48,0x4f,0x49,0x79,0x49,0x2,0x4,0x18,0x80,0x88,0xfc,0x80,0x48,0x50,0x62,0x92,0xe,0xf8,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x2,0x2,0x7a,0x4b,0x4a,0x4a,0x4a,0x4b,0x48,0x48,0x4f,0x78,0x48,0x0,0x0,0x0,0x20,0x20,0x24,0xa8,0x30,0x24,0xa4,0x1c,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x8,0x7c,0x48,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x7a,0x4a,0x3,0xc,0x0,0x90,0x90,0x90,0x90,0x92,0x94,0xf8,0x90,0x90,0x90,0x90,0xb0,0xd2,0x12,0xe,0x0,
-+0x0,0x0,0x7a,0x49,0x49,0x49,0x48,0x4f,0x49,0x49,0x49,0x79,0x4a,0x2,0x4,0x8,0x40,0x40,0x48,0x4c,0x50,0x50,0x44,0xfe,0x20,0x20,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x0,0x8,0x7d,0x49,0x49,0x49,0x48,0x48,0x48,0x49,0x4a,0x78,0x48,0x0,0x1,0x6,0x20,0x20,0x24,0x24,0x24,0xfc,0x44,0x40,0xfc,0x84,0x44,0x28,0x10,0x60,0x80,0x0,
-+0x1,0x1,0x11,0x7a,0x52,0x57,0x5a,0x52,0x52,0x52,0x52,0x72,0x53,0x2,0x2,0x2,0x20,0x20,0x20,0x20,0x24,0xfe,0x20,0x70,0x68,0xa8,0xa8,0xa6,0x24,0x20,0x20,0x20,
-+0x1,0x1,0x11,0x7a,0x52,0x56,0x5b,0x52,0x52,0x52,0x53,0x72,0x52,0x2,0x2,0x3,0x0,0x4,0xfe,0x44,0x44,0x44,0xfe,0x44,0x44,0x44,0xfc,0x44,0x40,0x40,0x80,0x0,
-+0x0,0x0,0x7b,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x4a,0x7a,0x44,0x4,0x8,0x0,0x8,0x3c,0xc0,0x4,0x18,0xe0,0xa0,0xa4,0xa8,0x90,0x90,0x90,0x88,0xae,0xc4,0x80,
-+0x0,0x0,0x8,0x7c,0x49,0x4a,0x4d,0x48,0x48,0x4f,0x48,0x78,0x49,0x2,0x7,0x0,0x40,0x40,0xa0,0xa0,0x10,0x8,0xf6,0x0,0x4,0xfe,0x80,0x80,0x10,0x8,0xfc,0x4,
-+0x0,0x1,0x9,0x7d,0x49,0x49,0x4a,0x48,0x4f,0x48,0x48,0x78,0x49,0x2,0xc,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x4c,0x40,0xfe,0x40,0xe0,0xd0,0x48,0x4e,0x44,0x40,
-+0x0,0x0,0x78,0x4b,0x49,0x48,0x48,0x48,0x49,0x4e,0x48,0x78,0x48,0x1,0x2,0x4,0x80,0x40,0x24,0xfe,0x8,0x90,0x60,0x90,0xe,0x94,0x90,0x90,0x90,0x10,0x10,0x10,
-+0x2,0x9,0x7c,0x4b,0x48,0x48,0x48,0x4b,0x48,0x48,0x48,0x7f,0x48,0x0,0x0,0x0,0x8,0x10,0xa0,0xfc,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,
-+0x0,0x8,0x7c,0x4a,0x49,0x48,0x4f,0x48,0x48,0x48,0x49,0x79,0x4a,0x4,0x8,0x0,0x40,0x40,0x44,0x48,0x50,0x44,0xfe,0x40,0xe0,0xd0,0x50,0x48,0x46,0x44,0x40,0x40,
-+0x0,0x0,0x7b,0x4a,0x4c,0x48,0x4b,0x48,0x48,0x4f,0x48,0x78,0x48,0x0,0x0,0x0,0x80,0x40,0xfe,0x2,0x4,0x38,0xc0,0x44,0x7e,0xc0,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x0,0x8,0x7c,0x49,0x49,0x4a,0x48,0x48,0x48,0x49,0x49,0x7a,0x44,0x8,0x0,0x0,0x20,0x20,0x20,0xfe,0x42,0x44,0x40,0xa0,0xa4,0x28,0x90,0x90,0x88,0xae,0xc4,0x80,
-+0x0,0x9,0x7d,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x79,0x49,0x1,0x1,0x1,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x44,0x48,0x30,0x20,0x10,0x4e,0x84,0x0,
-+0x0,0x0,0x8,0x7d,0x4b,0x48,0x49,0x49,0x49,0x4a,0x48,0x7b,0x48,0x0,0x0,0x0,0x20,0x40,0x88,0x4,0xfe,0x22,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x0,0x0,0x7b,0x48,0x4b,0x48,0x4f,0x48,0x49,0x49,0x49,0x7a,0x44,0x0,0x3,0xc,0x40,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x80,0xf8,0x8,0x10,0xa0,0x40,0xb0,0xe,0x4,
-+0x0,0x0,0x7b,0x48,0x48,0x48,0x4f,0x48,0x4a,0x4a,0x7a,0x45,0x9,0x2,0x4,0x0,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0xa0,0xa8,0xa4,0xa4,0x24,0x20,0x20,0xa0,0x40,
-+0x0,0x0,0x7b,0x48,0x48,0x4b,0x4a,0x4c,0x4b,0x48,0x48,0x78,0x49,0x2,0x4,0x8,0x90,0x94,0xfe,0x90,0x90,0xfe,0x42,0x44,0xf8,0x48,0x88,0x88,0x8,0x8,0x50,0x20,
-+0x0,0x3,0x78,0x48,0x4b,0x4a,0x4a,0x4b,0x4a,0x4a,0x4b,0x7a,0x49,0x0,0x3,0xc,0x8,0xfc,0x40,0x48,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x40,0x40,0xc0,0x30,0xe,
-+0x0,0x3,0x8,0x7c,0x4b,0x49,0x49,0x49,0x4f,0x48,0x4b,0x7a,0x4a,0x2,0x3,0x2,0x10,0xf8,0x80,0x90,0xf8,0x10,0x10,0x14,0xfe,0x0,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x2,0x2,0x72,0x5f,0x52,0x52,0x52,0x52,0x53,0x5e,0x52,0x72,0x52,0x2,0xb,0x4,0x0,0xc,0x70,0xc0,0x40,0x44,0x7e,0xc8,0x48,0x48,0x48,0x48,0x88,0x88,0x8,0x8,
-+0x0,0x2,0x9,0x7d,0x48,0x4b,0x4a,0x4a,0x4a,0x4a,0x4a,0x7a,0x4a,0x0,0x1,0x6,0x40,0x44,0x4c,0x50,0x48,0xfc,0x8,0x48,0x48,0x48,0x48,0x48,0xa8,0x90,0xc,0x4,
-+0x0,0x0,0x7b,0x4a,0x4a,0x4b,0x4a,0x4a,0x4b,0x4a,0x78,0x40,0xf,0x0,0x0,0x0,0x40,0x88,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x40,0x44,0x7e,0xc0,0x44,0x44,0x3c,
-+0x1,0x8,0x7c,0x48,0x49,0x48,0x4f,0x48,0x49,0x4b,0x4d,0x79,0x49,0x1,0x0,0x0,0x8,0xd0,0x20,0x58,0x84,0x40,0xfe,0xa0,0x24,0xfe,0x24,0x24,0x34,0x28,0x20,0x20,
-+0x0,0x0,0x2,0x7a,0x4a,0x4a,0x4d,0x48,0x48,0x48,0x4b,0x78,0x48,0x0,0xf,0x0,0x40,0x40,0x48,0x48,0x48,0x48,0x54,0xe2,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x0,
-+0x0,0x7,0x74,0x54,0x57,0x54,0x54,0x57,0x54,0x54,0x55,0x74,0x55,0x6,0x0,0x0,0x80,0xc4,0xbe,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0x24,0x24,0xb4,0x28,0x20,0x20,0x20,
-+0x0,0x8,0x7f,0x48,0x4b,0x48,0x4f,0x48,0x49,0x4b,0x4c,0x78,0x47,0x0,0x0,0x0,0x40,0x44,0xfe,0x40,0xfc,0x40,0xfe,0xa0,0x50,0xf8,0x46,0x40,0xfc,0x40,0x40,0x40,
-+0x0,0x8,0x7f,0x48,0x4b,0x48,0x4f,0x48,0x4b,0x4a,0x4a,0x7a,0x4a,0x0,0x1,0x6,0x40,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x8,0xfc,0x8,0x48,0x48,0x48,0xb0,0xc,0x4,
-+0x1,0x9,0x7f,0x49,0x48,0x48,0x4f,0x48,0x48,0x49,0x49,0x7b,0x45,0x9,0x1,0x1,0x10,0x10,0xfc,0x10,0x40,0x44,0xfe,0x80,0x88,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x1,0x11,0x7f,0x51,0x51,0x50,0x57,0x54,0x54,0x54,0x57,0x74,0x54,0x4,0x7,0x4,0x10,0x14,0xfe,0x10,0x10,0x4,0xfe,0x44,0x44,0x44,0xfc,0x44,0x44,0x44,0xfc,0x4,
-+0x1,0x11,0x79,0x51,0x5f,0x51,0x53,0x53,0x55,0x55,0x55,0x79,0x51,0x1,0x1,0x1,0x10,0x10,0x10,0x14,0xfe,0x10,0x30,0xb8,0x58,0x54,0x54,0x92,0x10,0x10,0x10,0x10,
-+0x1,0x11,0x79,0x57,0x52,0x52,0x55,0x55,0x5f,0x51,0x51,0x73,0x4d,0x1,0x1,0x1,0x10,0x10,0x14,0xfe,0x10,0x14,0x7e,0x10,0x90,0x20,0x7e,0x84,0x28,0x10,0xc,0x4,
-+0x0,0x9,0x7d,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x49,0x79,0x4a,0x2,0x4,0x8,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x4,0x74,0x54,0x54,0x74,0x4,0x14,0x8,
-+0x2,0x12,0x7b,0x54,0x5a,0x53,0x54,0x50,0x5f,0x50,0x54,0x74,0x57,0x0,0x0,0x0,0x0,0x4,0xfe,0x4,0x24,0xf4,0x84,0x94,0xfc,0x84,0x94,0x94,0xf4,0x4,0x14,0x8,
-+0x1,0x9,0x7d,0x4a,0x4a,0x4c,0x49,0x49,0x4a,0x48,0x49,0x7d,0x45,0x9,0x0,0x0,0x0,0x4,0xfe,0x94,0x94,0x94,0x24,0x24,0x54,0x8,0x40,0x24,0x22,0xa,0xf8,0x0,
-+0x0,0x8,0x7f,0x49,0x49,0x49,0x4a,0x4a,0x4c,0x48,0x4f,0x78,0x48,0x0,0x0,0x0,0x80,0x48,0xfc,0x10,0x10,0x10,0xa8,0x44,0x44,0x40,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x0,0xb,0x7c,0x49,0x48,0x4f,0x48,0x48,0x4f,0x49,0x7a,0x49,0x0,0x1,0x6,0x80,0x50,0xf8,0x0,0x10,0xa0,0xfc,0x80,0x84,0xfe,0x10,0x10,0x20,0xc0,0x30,0x8,
-+0x0,0x8,0x7f,0x48,0x49,0x4b,0x48,0x49,0x49,0x49,0x49,0x79,0x49,0x1,0x1,0x1,0x80,0x44,0xfe,0x80,0x8,0xfc,0x4,0xf8,0x8,0xf8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x0,0x8,0x7d,0x49,0x4a,0x48,0x49,0x4a,0x48,0x49,0x49,0x7a,0x48,0x0,0x3,0xc,0x40,0x40,0x48,0x50,0x40,0xa0,0x10,0xc,0x40,0x48,0x50,0x40,0xa0,0x90,0xe,0x4,
-+0x0,0x4,0x72,0x52,0x58,0x54,0x50,0x52,0x52,0x54,0x5c,0x74,0x55,0x5,0x6,0x4,0x10,0x10,0x10,0xfe,0x92,0x94,0x90,0xfc,0xa4,0xa4,0xa8,0x90,0x28,0x28,0x46,0x84,
-+0x0,0x8,0x7c,0x4b,0x4a,0x4c,0x48,0x4b,0x48,0x49,0x49,0x79,0x49,0x2,0x4,0x8,0x40,0x20,0x20,0xfe,0x2,0x4,0x0,0xfe,0x20,0x20,0x3c,0x20,0x20,0xa0,0x60,0x1e,
-+0x2,0x1,0x17,0x7c,0x54,0x57,0x54,0x54,0x57,0x54,0x54,0x75,0x54,0x5,0x6,0x0,0x0,0x0,0xbc,0xa4,0xa8,0xa8,0xb0,0xa8,0xa4,0x24,0x24,0x24,0xb4,0xa8,0x20,0x20,
-+0x0,0x8,0x7f,0x4a,0x4a,0x4b,0x4a,0x4a,0x4a,0x4b,0x4a,0x7a,0x44,0x4,0x9,0x2,0x40,0x24,0xfe,0x4,0x4,0xfc,0x20,0x28,0x24,0xfe,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x0,0x17,0x7c,0x54,0x57,0x55,0x55,0x57,0x55,0x75,0x4d,0x15,0x15,0x25,0x1,0x1,0x4,0xc4,0x54,0x54,0xd4,0x14,0x14,0xd4,0x54,0x54,0x54,0x44,0x44,0xc4,0x14,0x8,
-+0x0,0xf,0x4,0x75,0x52,0x55,0x58,0x50,0x5f,0x50,0x55,0x75,0x52,0x5,0x8,0x10,0x0,0xfc,0xa4,0x28,0x10,0x28,0xc4,0x0,0xfc,0x84,0x28,0x28,0x10,0x28,0xc6,0x84,
-+0x0,0x2,0x12,0x7f,0x52,0x52,0x52,0x52,0x53,0x50,0x5f,0x70,0x51,0x2,0xc,0x0,0x90,0x90,0x94,0xfe,0x90,0x90,0xf0,0x0,0xfc,0x40,0xfe,0xe0,0x50,0x4e,0x44,0x40,
-+0x1,0x1,0xf,0x79,0x48,0x48,0x49,0x4a,0x4d,0x48,0x4b,0x7a,0x4a,0x2,0x3,0x2,0x10,0x14,0xfe,0x50,0x40,0xa0,0x10,0xe,0xf4,0x0,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x0,0xf,0x70,0x50,0x57,0x55,0x54,0x55,0x54,0x54,0x77,0x54,0x4,0x4,0x4,0x40,0x44,0xfe,0x40,0x44,0xfe,0x14,0xa4,0xf4,0x44,0x44,0xfc,0x44,0x44,0x54,0x8,
-+0x0,0x17,0x7c,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0x74,0x49,0x8,0x10,0x3,0x4,0xfe,0x0,0xfc,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0x28,0xfc,0x20,0x24,0xfe,
-+0x0,0x0,0x0,0x77,0x50,0x51,0x53,0x5c,0x53,0x50,0x50,0x77,0x50,0x0,0xf,0x0,0x40,0x40,0x44,0xfe,0xa0,0x50,0xf8,0x46,0xf8,0x40,0x48,0xfc,0x40,0x44,0xfe,0x0,
-+0x2,0x2,0x7b,0x4a,0x4a,0x4a,0x4b,0x48,0x49,0x49,0x79,0x49,0x1,0x1,0x1,0x1,0x20,0x24,0xa8,0x30,0x22,0xa2,0x5e,0x88,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x0,0x13,0x7a,0x52,0x53,0x52,0x52,0x53,0x50,0x57,0x74,0x54,0x5,0x4,0x4,0x4,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x44,0xfe,0x44,0x54,0xf4,0x4,0x14,0x8,
-+0x0,0x7,0x74,0x57,0x54,0x57,0x50,0x53,0x52,0x53,0x72,0x53,0x2,0x2,0x2,0x2,0x4,0xfe,0x44,0xfc,0x44,0xfc,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x0,0x1,0x77,0x51,0x51,0x51,0x57,0x51,0x53,0x53,0x55,0x75,0x49,0x11,0x1,0x1,0x90,0xd0,0x10,0x52,0x34,0x38,0xd0,0x10,0x90,0x50,0x28,0x28,0x28,0x44,0x44,0x82,
-+0x0,0x1,0x7a,0x4a,0x4a,0x4b,0x4a,0x4a,0x4b,0x48,0x7b,0x49,0x0,0x0,0x1,0xe,0x40,0x48,0x5c,0x48,0x48,0x58,0x48,0x48,0xf8,0x40,0xf8,0x10,0xa0,0x40,0xb0,0xe,
-+0x0,0x0,0x7,0x78,0x49,0x48,0x4f,0x48,0x4b,0x4a,0x4a,0x7b,0x4a,0x2,0x3,0x2,0x80,0x48,0xfc,0x0,0x10,0xa4,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x1,0x3f,0x8,0x4,0x7f,0x41,0x9f,0x11,0x11,0x11,0x1,0x1f,0x10,0x10,0x1f,0x10,0x0,0xf8,0x20,0x40,0xfe,0x2,0xf4,0x10,0x10,0x30,0x0,0xf0,0x10,0x10,0xf0,0x10,
-+0x0,0x9,0x7c,0x4b,0x48,0x49,0x48,0x4f,0x48,0x48,0x49,0x7a,0x44,0x8,0x13,0x0,0x8,0x8,0x90,0xfc,0x40,0xf8,0x40,0xfe,0x80,0x88,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x0,0xa,0x7d,0x48,0x4f,0x48,0x49,0x4a,0x48,0x4f,0x49,0x7a,0x49,0x0,0x1,0x6,0x40,0x48,0x50,0x40,0xfc,0x40,0x50,0x48,0x80,0xfe,0x10,0x10,0x20,0xc0,0x30,0x8,
-+0x22,0x11,0x0,0x7f,0x41,0x91,0x1f,0x21,0xff,0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x8,0x10,0x20,0xfe,0x2,0x24,0xf0,0x4,0xfe,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,
-+0x0,0x3,0x7a,0x4a,0x4b,0x4a,0x4b,0x4a,0x4a,0x4a,0x7a,0x42,0x4,0x4,0xb,0x10,0x4,0xfe,0x4,0x4,0xfc,0x0,0xfc,0x40,0x88,0xfc,0x20,0xfc,0x20,0x24,0xfe,0x0,
-+0x1,0x1,0x7a,0x4b,0x48,0x4f,0x49,0x49,0x4a,0x4c,0x79,0x46,0x1,0xe,0x1,0x0,0x0,0xf0,0x10,0xf0,0x24,0xfe,0x0,0x88,0x50,0xe0,0x50,0xd0,0x4e,0x44,0x40,0x80,
-+0x0,0x0,0xb,0x7c,0x4b,0x48,0x4f,0x48,0x49,0x4b,0x4c,0x7b,0x48,0x1,0x6,0x0,0x40,0x48,0xfc,0x40,0xf8,0x80,0xfe,0xa0,0x10,0xf8,0x46,0xf8,0xc0,0x70,0x48,0x40,
-+0x1,0x1,0x17,0x79,0x57,0x51,0x5f,0x52,0x53,0x52,0x52,0x74,0x44,0x9,0x10,0x0,0x10,0x10,0xd0,0x14,0xfe,0x24,0xe4,0x28,0xa8,0xa8,0x90,0x90,0xa8,0xa8,0x46,0x84,
-+0x0,0x0,0x7,0x78,0x4b,0x48,0x4f,0x48,0x48,0x4b,0x48,0x7b,0x49,0x2,0x4,0x0,0x40,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x40,0x90,0xe0,0x48,0xf8,0x50,0x4c,0x44,0x40,
-+0x2,0x12,0x7f,0x52,0x52,0x5f,0x52,0x57,0x5c,0x54,0x57,0x74,0x54,0x7,0x4,0x0,0x0,0x3c,0xa4,0x24,0xa4,0xe8,0x24,0xa4,0xa2,0xa2,0xa2,0xb4,0xa8,0xa0,0xa0,0x20,
-+0x0,0x0,0xb,0x7c,0x48,0x4f,0x48,0x49,0x4b,0x48,0x4b,0x7a,0x4a,0x2,0xf,0x0,0x40,0x48,0xfc,0x40,0x44,0xfe,0x80,0x10,0xf8,0x0,0xf8,0xa8,0xa8,0xa8,0xfe,0x0,
-+0x0,0xf,0x72,0x53,0x52,0x53,0x52,0x5f,0x50,0x5f,0x50,0x74,0x55,0x2,0x5,0x8,0x8,0xfc,0x10,0xf0,0x10,0xf0,0x14,0xfe,0x10,0xbc,0x84,0xa4,0x28,0x10,0x28,0xc6,
-+0x1,0x1,0x17,0x79,0x51,0x53,0x52,0x56,0x5a,0x52,0x52,0x72,0x52,0x2,0x2,0x2,0x20,0x28,0xfc,0x20,0x4,0xfe,0x8,0x8,0xe8,0xa8,0xa8,0xe8,0x8,0x8,0x28,0x10,
-+0x0,0x0,0x7,0x78,0x4b,0x4a,0x4b,0x4a,0x4b,0x4a,0x4b,0x7a,0x4f,0x1,0x2,0x4,0x40,0x44,0xfe,0x40,0xf8,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x8,0xfe,0x10,0xc,0x4,
-+0x0,0x0,0x17,0x78,0x57,0x54,0x58,0x53,0x50,0x50,0x57,0x71,0x52,0x4,0x1,0x0,0x40,0x48,0xfc,0x40,0xfe,0x42,0x94,0xf0,0x40,0x88,0xfc,0x50,0x4c,0x44,0x40,0x80,
-+0x0,0x7,0x10,0x7b,0x52,0x52,0x53,0x50,0x57,0x55,0x54,0x75,0x54,0x4,0x4,0x4,0x4,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x4,0xfe,0x14,0xa4,0xf4,0x44,0x44,0x54,0x8,
-+0x0,0x7,0x0,0x7b,0x4a,0x4b,0x4a,0x4b,0x4a,0x4b,0x49,0x79,0x4a,0x4,0x8,0x3,0x4,0xfe,0x40,0xf8,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xf8,0x90,0x60,0x90,0xe,
-+0x0,0x3,0x7a,0x4a,0x4b,0x4a,0x4a,0x4b,0x4a,0x4b,0x78,0x45,0x5,0x9,0x0,0x0,0x8,0xfc,0x48,0x48,0xf8,0x48,0xa8,0x18,0x8,0xf8,0x0,0x44,0x22,0xa,0xf8,0x0,
-+0x0,0x0,0x7b,0x4a,0x4b,0x4a,0x4b,0x48,0x4f,0x48,0x49,0x7a,0x45,0x8,0x0,0x0,0x40,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x84,0xfe,0xa0,0x50,0x48,0xfe,0x44,0x40,0x40,
-+0x0,0x1,0xa,0x7c,0x49,0x4e,0x48,0x4b,0x48,0x4b,0x48,0x7b,0x48,0x0,0x0,0x7,0x90,0x18,0xa4,0x40,0xb0,0x4e,0xf0,0x90,0x60,0xa0,0x78,0x88,0x90,0x60,0xc0,0x0,
-+0x0,0x10,0x7b,0x52,0x51,0x57,0x54,0x58,0x57,0x51,0x51,0x73,0x52,0x4,0x8,0x3,0x10,0x78,0x80,0x48,0x50,0xfe,0x82,0x84,0xfc,0x0,0xf0,0x10,0xa0,0x40,0xb0,0xc,
-+0x0,0x2,0x1,0x78,0x4f,0x48,0x49,0x4a,0x48,0x4b,0x4a,0x7a,0x4a,0x2,0xf,0x0,0x0,0x8,0x10,0x4,0xfe,0xa0,0x18,0x8,0x0,0xf8,0xa8,0xa8,0xa8,0xa8,0xfe,0x0,
-+0x8,0x4,0x12,0x7f,0x51,0x55,0x55,0x55,0x55,0x55,0x57,0x71,0x51,0x2,0x4,0x8,0x24,0x5e,0x94,0xf4,0x14,0x5c,0x54,0x54,0x54,0x5c,0xd4,0x54,0x24,0x24,0x54,0x88,
-+0x0,0x8,0x75,0x51,0x53,0x59,0x55,0x51,0x57,0x55,0x55,0x75,0x59,0x9,0x8,0x0,0x80,0x88,0xfc,0x0,0xf8,0x8,0x48,0x28,0xfe,0x8,0x48,0x28,0x8,0xfc,0x8,0x30,
-+0x1,0x8,0x74,0x54,0x51,0x51,0x5d,0x55,0x55,0x55,0x55,0x75,0x55,0xa,0x11,0x0,0xfc,0x8,0x50,0x24,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x24,0x2c,0x6,0xfc,0x0,
-+0x0,0x2,0x7a,0x4b,0x48,0x4f,0x48,0x48,0x4b,0x4a,0x4a,0x7b,0x4a,0x0,0x7,0x0,0x40,0x48,0x48,0xf8,0x40,0xfe,0x40,0x48,0xfc,0x48,0x48,0xf8,0x40,0x48,0xfc,0x4,
-+0x11,0x11,0x27,0x22,0x7d,0x17,0x21,0x79,0x7,0xf9,0x1,0x1f,0x10,0x10,0x1f,0x10,0x8,0x8,0xd0,0x10,0x3c,0xc8,0x10,0x3c,0xc0,0x3e,0x10,0xf8,0x10,0x10,0xf0,0x10,
-+0x2,0x12,0x7f,0x52,0x53,0x51,0x57,0x55,0x55,0x57,0x51,0x5f,0x71,0x1,0x1,0x1,0x90,0x90,0xf0,0x94,0xbe,0x14,0xd4,0x54,0x54,0xd4,0x14,0xf4,0x24,0x24,0x54,0x88,
-+0x0,0x0,0xf,0x70,0x57,0x54,0x57,0x54,0x57,0x50,0x53,0x72,0x53,0x2,0x3,0x2,0xa0,0xa4,0xfe,0xa0,0xfc,0xa4,0xfc,0xa4,0xfc,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x8,
-+0x0,0x7,0x70,0x50,0x57,0x54,0x54,0x57,0x50,0x57,0x50,0x7f,0x51,0x2,0x5,0x0,0x4,0xfe,0xa0,0xa4,0xfe,0xa4,0xa4,0xfc,0x0,0xfc,0x0,0xfe,0x50,0x4c,0x44,0x80,
-+0x0,0x0,0x77,0x54,0x55,0x55,0x55,0x55,0x57,0x55,0x55,0x7b,0x4d,0x11,0x23,0x0,0x28,0x24,0xfe,0x20,0x20,0xe4,0x24,0x24,0xe8,0x28,0x28,0x90,0x50,0x2a,0x4a,0x84,
-+0x7,0x14,0x7d,0x55,0x56,0x56,0x55,0x58,0x50,0x5f,0x51,0x72,0x51,0x0,0x1,0x6,0xbc,0xa4,0xac,0xac,0xb4,0xb4,0x28,0xc4,0x80,0xfe,0x10,0x10,0x20,0xc0,0x30,0x8,
-+0x0,0x14,0x7c,0x57,0x50,0x57,0x54,0x54,0x57,0x54,0x54,0x77,0x54,0x8,0xa,0x11,0x40,0x44,0x44,0xfc,0x4,0xbe,0xa4,0xa4,0xbc,0xa4,0xa4,0xbc,0xa4,0xa4,0xd4,0x8,
-+0x4,0x2,0x72,0x5f,0x54,0x54,0x57,0x55,0x55,0x55,0x55,0x75,0x49,0xb,0x10,0x0,0x20,0x24,0x3e,0x40,0xa0,0x24,0x3e,0x50,0x14,0xfe,0x10,0x10,0x28,0x28,0x44,0x82,
-+0x0,0x10,0x7f,0x51,0x50,0x57,0x54,0x54,0x57,0x54,0x55,0x75,0x55,0x5,0x4,0x4,0x80,0x44,0xfe,0x10,0xa4,0xfe,0x44,0x44,0xfc,0x44,0xf4,0x14,0x14,0xf4,0x14,0x8,
-+0x0,0x0,0x7,0x74,0x58,0x51,0x55,0x55,0x59,0x52,0x5c,0x72,0x52,0x2,0x3,0x0,0x80,0x40,0xfe,0x2,0x94,0x50,0x24,0x4a,0x8a,0xf8,0x40,0x48,0x48,0x48,0xf8,0x8,
-+0x1,0x1,0xf,0x71,0x57,0x50,0x57,0x54,0x54,0x57,0x50,0x74,0x52,0xf,0x0,0x0,0x4,0x44,0xe4,0x8,0xc8,0x10,0xc4,0x44,0x48,0xd2,0x2,0x44,0x84,0xe8,0x10,0x20,
-+0x0,0x7,0x74,0x56,0x55,0x57,0x54,0x56,0x56,0x56,0x7b,0x48,0x8,0x11,0x22,0x0,0x4,0xfe,0x8,0x28,0x4e,0xf2,0x84,0xa8,0xa8,0xa8,0xe8,0xa8,0x88,0x14,0x24,0x42,
-+0x0,0x8,0x7f,0x48,0x4a,0x49,0x4b,0x4e,0x4b,0x4a,0x4b,0x78,0x49,0x2,0x5,0x0,0x40,0x44,0xfe,0x40,0xa8,0x10,0xf8,0xe,0xf8,0x8,0xf8,0x40,0x50,0x4c,0x44,0x80,
-+0x0,0x2,0x79,0x48,0x4f,0x49,0x48,0x4b,0x48,0x4b,0x48,0x7f,0x48,0x1,0x1,0x6,0xa0,0xa8,0xb0,0xa4,0xfe,0x10,0xa0,0xf8,0x40,0xf8,0x40,0xfe,0xa0,0x10,0x10,0xc,
-+0x1,0x9,0x7d,0x49,0x49,0x48,0x4f,0x4a,0x4b,0x4a,0x4b,0x7a,0x43,0xe,0x4,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xfe,0x40,0xfc,0x44,0xe8,0x68,0xd0,0x68,0x46,0x40,
-+0x0,0x8,0x7d,0x49,0x4b,0x4d,0x49,0x49,0x49,0x49,0x49,0x79,0x49,0x2,0x2,0x4,0xa0,0x90,0xfc,0x20,0x28,0xfc,0x20,0x28,0xfc,0x20,0x24,0xfe,0x0,0xa8,0xa4,0x4,
-+0x0,0x1,0x77,0x54,0x55,0x54,0x57,0x54,0x55,0x56,0x70,0x4f,0x0,0x1,0x2,0xc,0x80,0x4,0xfe,0x44,0x54,0x44,0xfc,0xc4,0x74,0x4c,0x40,0xfe,0xa0,0x10,0x8,0x6,
-+0x0,0x0,0x10,0x79,0x52,0x55,0x58,0x52,0x52,0x53,0x50,0x77,0x54,0x5,0x4,0x4,0x40,0x40,0xa0,0x10,0x48,0xf6,0xa0,0x48,0xa8,0xf8,0x44,0xfe,0x94,0xf4,0x4,0xc,
-+0x1,0x11,0x7a,0x57,0x5c,0x57,0x54,0x57,0x50,0x5f,0x50,0x73,0x52,0x3,0x2,0x3,0x0,0xf0,0x20,0xfc,0x44,0xfc,0x44,0xfc,0x0,0xfe,0x0,0xf8,0x8,0xf8,0x8,0xf8,
-+0x2,0x11,0x78,0x57,0x54,0x55,0x54,0x57,0x50,0x53,0x52,0x72,0x53,0x2,0x2,0x3,0x8,0x10,0xa4,0xfe,0x44,0x54,0x44,0xfc,0x0,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,
-+0x0,0x7,0x71,0x55,0x52,0x53,0x54,0x5b,0x52,0x52,0x53,0x70,0x52,0x1,0x1f,0x0,0x40,0x48,0x30,0x24,0x18,0xf0,0x8,0xf6,0x10,0x10,0xf0,0x0,0x10,0x24,0xfe,0x0,
-+0x1,0xf,0x71,0x50,0x57,0x50,0x53,0x52,0x53,0x50,0x57,0x74,0x55,0x5,0x5,0x4,0x10,0xfe,0x10,0x44,0xfe,0x0,0xf8,0x8,0xf8,0x4,0xfe,0x4,0xf4,0x14,0xf4,0xc,
-+0x1,0x11,0x7f,0x51,0x53,0x55,0x59,0x51,0x57,0x50,0x5f,0x70,0x52,0x4,0x9,0x0,0x10,0x14,0xfe,0x10,0xb8,0x54,0x12,0x10,0xfc,0x0,0xfe,0x40,0x48,0x46,0x42,0x80,
-+0x0,0x10,0x78,0x57,0x54,0x57,0x54,0x54,0x57,0x54,0x55,0x7a,0x49,0x10,0x23,0x0,0x48,0x7c,0x40,0xfe,0x42,0xf8,0x40,0x38,0xfe,0x80,0x48,0xb0,0x70,0xae,0x24,0x60,
-+0x0,0x0,0x77,0x52,0x51,0x5f,0x50,0x53,0x52,0x53,0x52,0x73,0x54,0x5,0x9,0x1,0x80,0x40,0xfc,0x8,0x10,0xfe,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x44,0x42,0x12,0xf0,
-+0x0,0x0,0x77,0x55,0x5b,0x51,0x53,0x51,0x5f,0x51,0x52,0x75,0x48,0x0,0x7,0x0,0x80,0x40,0xfe,0x12,0xfc,0x10,0xf8,0x10,0xfe,0x50,0x48,0xf6,0x40,0x48,0xfc,0x0,
-+0x0,0x7,0x74,0x54,0x54,0x57,0x54,0x54,0x57,0x56,0x76,0x4a,0xa,0x13,0x22,0x0,0x10,0xc8,0x7e,0x40,0x54,0xd4,0x3e,0x8,0xc8,0x48,0x7e,0x48,0x48,0xc8,0x48,0x8,
-+0x0,0x7,0x70,0x57,0x54,0x5b,0x50,0x53,0x50,0x5f,0x50,0x77,0x54,0x4,0x4,0x4,0x8,0xfc,0x40,0xfe,0x42,0x5c,0x40,0x58,0x4,0xfe,0x80,0xfc,0xa4,0xa4,0xa4,0xc,
-+0x0,0x0,0x77,0x55,0x59,0x52,0x56,0x51,0x53,0x54,0x5b,0x70,0x51,0x2,0x5,0x0,0x80,0x40,0xfe,0x2,0xbc,0xa8,0xb0,0x10,0xf8,0x6,0xf8,0x40,0x50,0x4c,0x44,0x80,
-+0x0,0x7,0x70,0x57,0x55,0x58,0x51,0x51,0x53,0x56,0x5b,0x72,0x53,0x2,0x3,0x2,0x8,0xfc,0x40,0xfe,0x52,0xe4,0x50,0x20,0xfc,0x20,0xfc,0x20,0xfc,0x20,0xfe,0x0,
-+0x0,0x17,0x78,0x53,0x52,0x57,0x55,0x5b,0x51,0x57,0x51,0x7f,0x51,0x3,0xd,0x1,0x48,0xfc,0x40,0xf8,0x8,0xfe,0x12,0xfc,0x10,0xfc,0x10,0xfe,0x48,0x30,0x9e,0x4,
-+0x0,0x7f,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7f,0x40,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x7f,0x40,0x4f,0x40,0x40,0x41,0x5f,0x41,0x41,0x41,0x41,0x43,0x40,0x7f,0x40,0x4,0xfe,0x4,0xe4,0x44,0x84,0x24,0xf4,0x4,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x7f,0x42,0x42,0x42,0x7f,0x44,0x44,0x48,0x44,0x43,0x42,0x44,0x48,0x7f,0x40,0x4,0xfe,0x4,0x4,0x14,0xfc,0x44,0x44,0x44,0x44,0x84,0x84,0x64,0x14,0xfc,0x4,
-+0x0,0x7f,0x41,0x41,0x42,0x44,0x48,0x54,0x64,0x45,0x46,0x44,0x43,0x40,0x7f,0x40,0x4,0xfe,0x4,0x4,0x84,0x44,0x24,0x5c,0x84,0x4,0x4,0x24,0xe4,0x4,0xfc,0x4,
-+0x0,0x7f,0x48,0x48,0x4f,0x54,0x54,0x64,0x48,0x49,0x51,0x62,0x44,0x40,0x7f,0x40,0x4,0xfe,0x4,0x14,0xfc,0x94,0x94,0x94,0x94,0x14,0x14,0x54,0x24,0x4,0xfc,0x4,
-+0x0,0x7f,0x41,0x41,0x42,0x44,0x4a,0x51,0x6f,0x40,0x44,0x42,0x41,0x40,0x7f,0x40,0x4,0xfe,0x4,0x4,0x84,0x44,0x24,0x1c,0xe4,0x24,0x44,0x84,0x4,0x84,0xfc,0x4,
-+0x0,0x7f,0x42,0x42,0x7f,0x44,0x47,0x4c,0x57,0x64,0x47,0x44,0x44,0x44,0x7f,0x40,0x4,0xfe,0x4,0x14,0xfc,0x4,0xe4,0x24,0xe4,0x24,0xe4,0x24,0xa4,0x44,0xfc,0x4,
-+0x0,0x7f,0x40,0x5f,0x42,0x4f,0x44,0x7f,0x40,0x4f,0x48,0x48,0x4f,0x40,0x7f,0x40,0x4,0xfe,0x4,0xf4,0x4,0xe4,0x24,0xfc,0x4,0xe4,0x24,0x24,0xe4,0x4,0xfc,0x4,
-+0x0,0x7f,0x41,0x41,0x5f,0x41,0x4f,0x41,0x5f,0x40,0x44,0x42,0x41,0x40,0x7f,0x40,0x4,0xfe,0x4,0x4,0xf4,0x4,0xe4,0x4,0xf4,0x24,0x44,0x84,0x4,0x84,0xfc,0x4,
-+0x0,0x7f,0x41,0x41,0x5f,0x41,0x7f,0x44,0x42,0x4f,0x41,0x5f,0x41,0x41,0x7f,0x40,0x4,0xfe,0x4,0x24,0xf4,0x4,0xfc,0x44,0x84,0xe4,0x4,0xf4,0x4,0x4,0xfc,0x4,
-+0x0,0x7f,0x40,0x5f,0x52,0x5f,0x40,0x7f,0x48,0x4f,0x45,0x4c,0x56,0x44,0x7f,0x40,0x4,0xfe,0x4,0xf4,0x94,0xf4,0x4,0xfc,0x24,0xe4,0x44,0x84,0x74,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x7f,0x54,0x54,0x55,0x54,0x54,0x57,0x5c,0x54,0x10,0x10,0x10,0x10,0x20,0x20,0x24,0xfe,0x20,0x28,0xfc,0x20,0x20,0xfe,0x22,0x22,0x2a,0x24,0x20,0x20,
-+0x10,0x10,0x11,0x7d,0x55,0x55,0x56,0x54,0x57,0x54,0x5c,0x54,0x10,0x10,0x11,0x16,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x24,0xfe,0x20,0x50,0x50,0x88,0x88,0x4,0x2,
-+0x10,0x10,0x10,0x7d,0x55,0x55,0x55,0x55,0x55,0x55,0x5d,0x55,0x12,0x12,0x14,0x13,0x20,0x20,0x20,0xfe,0x22,0x24,0x20,0xf8,0x8,0x48,0x50,0x50,0x20,0x50,0x8e,0x4,
-+0x8,0x8,0xfe,0x12,0x32,0xc,0x12,0x61,0x1,0x1f,0x11,0x11,0x11,0x11,0x1,0x1,0x0,0x0,0xfc,0x44,0x28,0x10,0x28,0x46,0x10,0xf8,0x10,0x10,0x50,0x20,0x0,0x0,
-+0x10,0x10,0x13,0x7c,0x55,0x54,0x57,0x54,0x54,0x55,0x5d,0x52,0x14,0x10,0x10,0x10,0x40,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x88,0x88,0xfe,0x8,0x88,0x48,0x8,0x28,0x10,
-+0x10,0x10,0x11,0x7c,0x55,0x54,0x57,0x54,0x55,0x55,0x5d,0x55,0x11,0x10,0x10,0x13,0x20,0x28,0xfc,0x20,0xfc,0x20,0xfe,0x0,0xfc,0x4,0x24,0x24,0x20,0x58,0x86,0x2,
-+0x10,0x11,0x11,0x7d,0x55,0x55,0x55,0x55,0x55,0x55,0x5d,0x55,0x11,0x11,0x11,0x11,0x4,0xfe,0x4,0xfc,0x24,0x24,0xfc,0x24,0x34,0x2c,0x24,0xfc,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x7d,0x55,0x57,0x55,0x55,0x55,0x55,0x55,0x5d,0x11,0x11,0x11,0x11,0x80,0xa0,0x94,0xfe,0x10,0x10,0xfc,0x10,0x10,0xfc,0x10,0x10,0x14,0xfe,0x0,0x0,
-+0x10,0x11,0x11,0x7d,0x55,0x55,0x55,0x55,0x55,0x55,0x5d,0x56,0x12,0x14,0x19,0x10,0x4,0xfe,0x4,0x4,0xfc,0x0,0xfc,0x20,0x48,0xfc,0x20,0xfc,0x20,0x24,0xfe,0x0,
-+0x21,0x21,0x21,0xf9,0xa9,0xa8,0xab,0xaa,0xab,0xa8,0xab,0xb9,0x20,0x20,0x21,0x2e,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xfc,0x94,0xfc,0x0,0xf8,0x10,0xa0,0x40,0xb0,0xe,
-+0x10,0x11,0x10,0x7c,0x57,0x54,0x55,0x55,0x55,0x55,0x5d,0x54,0x13,0x10,0x10,0x10,0x20,0xfc,0x88,0x50,0xfe,0x0,0xfc,0x4,0xfc,0x4,0xfc,0x20,0xfe,0x20,0x20,0x20,
-+0x10,0x11,0x10,0x7c,0x57,0x54,0x54,0x55,0x54,0x55,0x5c,0x57,0x10,0x10,0x10,0x13,0x50,0x54,0xd8,0x50,0xfe,0x88,0x50,0xfc,0x20,0xfc,0x20,0xfe,0x20,0x50,0x88,0x6,
-+0x10,0x10,0x13,0x7d,0x54,0x57,0x54,0x54,0x57,0x54,0x5d,0x55,0x11,0x11,0x11,0x11,0x8,0x1c,0xe0,0x24,0xa8,0xfe,0x70,0xa8,0x26,0x24,0xfe,0x24,0xfc,0x24,0xfc,0x4,
-+0x1,0x21,0x21,0x3f,0x0,0x3f,0x8,0x8,0x8,0x14,0x12,0x21,0x20,0x41,0x86,0x18,0x0,0x8,0x8,0xf8,0x0,0xf0,0x20,0x40,0x80,0xf0,0x10,0x20,0xc0,0x40,0x30,0xe,
-+0x10,0x10,0x11,0x10,0x54,0x54,0x55,0x55,0x55,0x55,0x55,0x55,0x7d,0x5,0x0,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0xfc,0x4,0x0,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x10,0x13,0x10,0x54,0x54,0x54,0x57,0x54,0x54,0x54,0x54,0x7d,0x5,0x2,0x4,0x0,0x4,0xfe,0x88,0x88,0x88,0x88,0xfe,0x88,0x88,0x88,0x88,0x8,0x8,0x8,0x8,
-+0x10,0x10,0x10,0x13,0x54,0x54,0x54,0x55,0x54,0x54,0x54,0x54,0x7c,0x4,0x1,0x6,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0xfc,0x84,0x88,0x50,0x50,0x20,0x50,0x8e,0x4,
-+0x10,0x11,0x11,0x11,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x7d,0x5,0x1,0x0,0x4,0xfe,0x0,0x4,0x44,0x28,0x28,0x10,0x10,0x28,0x24,0x44,0x80,0x0,0xfe,0x0,
-+0x10,0x10,0x11,0x10,0x55,0x55,0x55,0x54,0x54,0x54,0x54,0x55,0x7e,0x4,0x0,0x0,0x0,0x8,0xfc,0x10,0x10,0x14,0xfe,0x10,0x30,0x50,0x90,0x10,0x10,0x10,0x50,0x20,
-+0x10,0x11,0x11,0x11,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0x54,0x7d,0x5,0x2,0xc,0x8,0xfc,0x8,0x48,0x48,0x48,0x48,0x48,0x48,0x68,0xa0,0xa0,0x22,0x22,0x1e,0x0,
-+0x0,0x0,0x3f,0x2,0x2,0xff,0x4,0x8,0x31,0xc1,0x11,0x11,0x11,0x11,0x1f,0x0,0x10,0x38,0xc0,0x0,0x4,0xfe,0x40,0x30,0xe,0x4,0x10,0x10,0x10,0x10,0xf0,0x10,
-+0x1,0x21,0x21,0x3f,0x21,0x2,0x4,0xa,0x31,0xc0,0xf,0x0,0x0,0x0,0x0,0x1,0x0,0x8,0x8,0xf8,0x8,0x80,0x40,0x30,0xe,0x4,0xf0,0x10,0x20,0x40,0x80,0x0,
-+0x1,0x21,0x21,0x3f,0x0,0x1f,0x10,0x10,0x14,0x12,0x11,0x12,0x24,0x28,0x40,0x80,0x0,0x8,0x8,0xf8,0x0,0xf0,0x10,0x10,0x50,0x90,0x10,0x90,0x50,0x52,0xa,0x4,
-+0x1,0x21,0x21,0x3f,0x0,0x3f,0x21,0x21,0x21,0x3f,0x20,0x20,0x20,0x20,0x1f,0x0,0x0,0x8,0x8,0xf8,0x0,0xf8,0x8,0x8,0x8,0xf8,0x8,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x10,0x10,0x10,0x55,0x54,0x54,0x54,0x54,0x55,0x55,0x55,0x7d,0x5,0x1,0x1,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x24,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x1,0x21,0x21,0x3f,0x0,0xff,0x0,0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x0,0x0,0x0,0x8,0x8,0xf8,0x4,0xfe,0x10,0x90,0xd0,0x90,0x90,0x90,0x90,0x10,0x50,0x20,
-+0x1,0x21,0x21,0x3f,0x2,0x2,0xff,0x4,0x4,0x8,0x1f,0x0,0x8,0x10,0x62,0x1,0x0,0x8,0x8,0xf8,0x0,0x4,0xfe,0x0,0x80,0x90,0xf8,0x80,0x90,0x8c,0x84,0x0,
-+0x10,0x10,0x11,0x11,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x7c,0x4,0x0,0x0,0x0,0x4,0xfe,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0xfc,0x24,0x20,0x20,0x20,0x20,
-+0x10,0x10,0x10,0x10,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x7d,0x5,0x1,0x1,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0x24,0xfc,0x4,
-+0x9,0x9,0x11,0x11,0x3f,0x50,0x90,0x10,0x11,0x1,0x21,0x21,0x21,0x21,0x3f,0x0,0x0,0x40,0x24,0xfe,0x0,0x80,0x84,0x44,0x3c,0x0,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x10,0x10,0x55,0x56,0x55,0x55,0x55,0x55,0x55,0x55,0x7d,0x4,0x0,0x0,0x80,0x80,0x84,0xfe,0x4,0x24,0xf4,0x24,0x24,0x24,0x24,0xe4,0x24,0x4,0x28,0x10,
-+0x1,0x21,0x21,0x3f,0x4,0x78,0x42,0x42,0x42,0x42,0x4e,0x72,0x4,0x4,0x18,0x60,0x0,0x8,0x8,0xf8,0x4,0xfe,0x84,0x84,0x84,0x84,0x84,0xa4,0x98,0x80,0x80,0x80,
-+0x10,0x11,0x11,0x11,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x7d,0x5,0x1,0x0,0x4,0xfe,0x4,0x4,0xfc,0x20,0x20,0x24,0xfe,0x10,0x10,0x10,0x8,0x4a,0x86,0x2,
-+0x10,0x13,0x10,0x10,0x54,0x54,0x57,0x54,0x55,0x54,0x54,0x57,0x7c,0x4,0x0,0x0,0x0,0xfc,0x88,0x50,0x20,0xd8,0x6,0x20,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x10,0x11,0x11,0x11,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x7d,0x5,0x1,0x1,0x4,0xfe,0x4,0x14,0xfc,0x4,0x4,0x74,0x54,0x54,0x54,0x74,0x54,0x4,0x14,0x8,
-+0x20,0x20,0x23,0x20,0xa8,0xaf,0xa8,0xa9,0xa9,0xab,0xad,0xa9,0xf9,0x9,0x2,0x4,0x8,0x3c,0xc0,0x40,0x44,0xfe,0xa0,0x10,0x18,0x16,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x10,0x10,0x10,0x10,0x55,0x56,0x55,0x55,0x55,0x55,0x55,0x55,0x7d,0x5,0x0,0x0,0x80,0x80,0x84,0xfe,0x4,0x24,0xf4,0x24,0x24,0xe4,0x24,0x24,0xe4,0x4,0x28,0x10,
-+0x10,0x10,0x10,0x11,0x56,0x55,0x54,0x54,0x57,0x54,0x54,0x55,0x7c,0x4,0x0,0x0,0x40,0x40,0xf8,0x10,0x24,0xfe,0x24,0x24,0xfe,0x24,0x24,0xfc,0x24,0x20,0xa0,0x40,
-+0x10,0x10,0x17,0x10,0x54,0x57,0x56,0x54,0x55,0x54,0x54,0x54,0x7c,0x4,0x1,0x2,0x90,0x94,0xfe,0x90,0x0,0xfe,0x42,0x44,0xf8,0x48,0x48,0x48,0x88,0x88,0x28,0x10,
-+0x10,0x10,0x10,0x13,0x54,0x55,0x54,0x54,0x57,0x54,0x54,0x54,0x7c,0x5,0x2,0x0,0x20,0x20,0x24,0xfe,0x20,0x24,0xa8,0x20,0xfe,0x20,0x70,0xa8,0xa8,0x24,0x22,0x20,
-+0x1,0x21,0x21,0x3f,0x8,0x8,0x8,0x7e,0x9,0x1d,0x2a,0x28,0x48,0x89,0x9,0x8,0x0,0x8,0x8,0xf8,0x0,0x10,0x90,0x90,0x8,0x48,0x46,0x80,0x90,0x8,0xfc,0x4,
-+0x10,0x10,0x10,0x13,0x54,0x54,0x55,0x57,0x55,0x55,0x55,0x55,0x7d,0x4,0x0,0x0,0x20,0x20,0x24,0xfe,0x50,0xa8,0xfc,0x26,0x24,0xfc,0x24,0x24,0xfc,0x20,0x22,0x1e,
-+0x1,0x21,0x21,0x3f,0x0,0x3f,0x21,0x2f,0x21,0x27,0x24,0x24,0x27,0x20,0x3f,0x20,0x0,0x8,0x8,0xf8,0x0,0xf8,0x8,0xe8,0x8,0xc8,0x48,0x48,0xc8,0x8,0xf8,0x8,
-+0x11,0x10,0x10,0x10,0x55,0x54,0x57,0x54,0x54,0x55,0x56,0x54,0x7c,0x4,0x0,0x0,0x8,0x90,0x60,0x90,0x48,0x40,0xfe,0x80,0xf8,0x88,0xf8,0x88,0xf8,0x88,0xa8,0x90,
-+0x10,0x10,0x13,0x10,0x55,0x55,0x55,0x54,0x55,0x54,0x54,0x57,0x7c,0x4,0x1,0x0,0x80,0x48,0xfc,0x0,0xf8,0x8,0xf8,0x0,0xf8,0x10,0x60,0xfe,0x40,0x40,0x40,0x80,
-+0x10,0x10,0x10,0x11,0x55,0x56,0x54,0x55,0x54,0x55,0x54,0x54,0x7c,0x4,0x3,0x0,0x40,0x20,0x20,0xfe,0x2,0x54,0x88,0x4,0x0,0xfc,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x11,0x11,0x11,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x7d,0x2,0x4,0x8,0x0,0x4,0xfe,0x4,0x4,0xfc,0x10,0x54,0x54,0x54,0x7c,0x10,0x12,0x92,0x92,0xfe,0x2,
-+0x10,0x10,0x13,0x10,0x54,0x55,0x55,0x56,0x54,0x55,0x54,0x54,0x7c,0x5,0x2,0x0,0x88,0x88,0xfe,0x88,0x0,0xfe,0x2,0x24,0x20,0xfe,0x20,0x70,0xa8,0x26,0x24,0x20,
-+0x10,0x13,0x10,0x10,0x55,0x55,0x55,0x55,0x54,0x54,0x57,0x54,0x7c,0x4,0x0,0x3,0x4,0xfe,0x50,0x54,0xfe,0x54,0x54,0xfc,0x40,0x44,0xfe,0x88,0x90,0x60,0x98,0x4,
-+0x1,0x21,0x21,0x3f,0x0,0x3f,0x20,0x3f,0x24,0x3f,0x24,0x29,0x46,0x45,0x98,0x0,0x0,0x8,0x8,0xf8,0x50,0xfe,0x40,0xc4,0x44,0xc8,0xa8,0x30,0x20,0x52,0x8a,0x6,
-+0x1,0x21,0x21,0x3f,0x0,0x1f,0x11,0x1f,0x11,0x1f,0x2,0x51,0x51,0x90,0xf,0x0,0x0,0x8,0x8,0xf8,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x0,0x8,0x6,0x12,0xf0,0x0,
-+0x1,0x21,0x21,0x3f,0x0,0x1f,0x11,0x1f,0x11,0x1f,0x12,0x2,0x4,0x8,0x30,0x40,0x0,0x8,0x8,0xf8,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x90,0xa8,0xba,0x82,0x7e,0x0,
-+0x1,0x21,0x21,0x3f,0x1,0x6,0x38,0xcf,0x0,0x3e,0x22,0x3e,0x22,0x3e,0x22,0x26,0x0,0x8,0x8,0xf8,0x0,0xc0,0x30,0xee,0x8,0x48,0x48,0x48,0x48,0x48,0x48,0x18,
-+0x11,0x10,0x10,0x13,0x54,0x55,0x54,0x57,0x54,0x54,0x55,0x55,0x7e,0x4,0xb,0x0,0x8,0x90,0xa0,0xfe,0x40,0xfc,0x40,0xfe,0x80,0x88,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x11,0x10,0x54,0x57,0x54,0x54,0x55,0x54,0x57,0x54,0x55,0x7c,0x4,0x0,0x3,0x20,0x24,0xa8,0x20,0xfe,0x20,0xa8,0x24,0x40,0xfe,0x88,0x8,0x90,0x60,0x98,0x4,
-+0x11,0x10,0x10,0x13,0x54,0x54,0x55,0x55,0x57,0x54,0x55,0x55,0x7e,0x3,0x0,0x0,0x4,0x88,0x0,0xfe,0x88,0x88,0x10,0x54,0xb8,0x88,0x10,0x14,0xa4,0xfc,0x84,0x0,
-+0x10,0x11,0x11,0x11,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x7d,0x2,0x4,0x0,0x4,0xfe,0x24,0x24,0xfc,0x0,0x4,0x7e,0x44,0x7c,0x44,0x7c,0x44,0x44,0x7c,0x44,
-+0x20,0x20,0x27,0x20,0xaf,0xa8,0xa9,0xaf,0xa9,0xaf,0xa8,0xa9,0xf9,0xa,0x4,0x0,0x8,0x3c,0xc0,0x44,0xfe,0x40,0x50,0x5c,0x50,0x5c,0xe0,0x50,0x48,0x4e,0x44,0x40,
-+0x1,0x21,0x3f,0x1,0xff,0x0,0x1f,0x10,0x1f,0x0,0x3f,0x20,0x2f,0x28,0x2f,0x20,0x0,0x8,0xf8,0x0,0xfe,0x0,0xf0,0x10,0xf0,0x0,0xf8,0x8,0xe8,0x28,0xe8,0x18,
-+0x20,0x22,0x21,0xaa,0xa8,0xa9,0xab,0xad,0xa9,0xa9,0xa9,0xa9,0xf9,0x9,0x1,0x1,0x40,0x48,0x50,0x48,0xa0,0x10,0xfe,0x14,0x10,0xf0,0x10,0x10,0xf0,0x10,0x50,0x20,
-+0x10,0x13,0x10,0x54,0x57,0x54,0x55,0x55,0x55,0x55,0x55,0x54,0x7f,0x4,0x0,0x0,0x20,0xfe,0x88,0x50,0xfe,0x0,0xfc,0x4,0xfc,0x4,0xfc,0x20,0xfe,0x20,0x20,0x20,
-+0x20,0x22,0x21,0x20,0xaf,0xa9,0xaa,0xac,0xaa,0xab,0xac,0xaa,0xf9,0x9,0x2,0x4,0x40,0x48,0x50,0x44,0xfe,0x50,0x48,0x44,0x8,0xbc,0xa8,0xa8,0x7e,0x8,0x8,0x8,
-+0x20,0x27,0x20,0x22,0xa9,0xa9,0xaa,0xac,0xab,0xaa,0xaa,0xab,0xf9,0x8,0x7,0x0,0x20,0xa8,0xb0,0xa4,0x18,0xf0,0xe,0x4,0xf8,0x8,0x8,0xf8,0x10,0xa4,0xfe,0x0,
-+0x1,0x1,0x45,0x7f,0x51,0x59,0x6b,0x5d,0x69,0x5d,0x6b,0x49,0x59,0x41,0x7f,0x40,0x0,0x0,0x14,0xfc,0x44,0x64,0xac,0x74,0xa4,0x74,0xac,0x24,0x64,0x4,0xfc,0x4,
-+0x1,0x21,0x3f,0x0,0x26,0x38,0x21,0x1f,0x20,0x3e,0x48,0xa,0xff,0x14,0x22,0x41,0x0,0x8,0xf8,0x0,0xfc,0x8,0x30,0x10,0xfe,0x14,0x50,0x5c,0x50,0xb0,0x90,0xe,
-+0x1,0x21,0x3f,0x8,0xff,0x8,0x3e,0x22,0x2a,0x2a,0x2a,0x2a,0xff,0x8,0x14,0x62,0x0,0x8,0xf8,0x0,0xfe,0x20,0x7c,0x44,0x54,0x54,0x54,0x54,0x54,0x28,0x26,0xc2,
-+0x0,0x0,0x1,0x2,0x4,0x8,0x10,0x1,0x3,0x5,0x9,0x31,0x1,0x1,0x1,0x1,0x80,0x80,0x0,0x0,0x40,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x8,0x8,0x10,0x27,0x40,0x8,0x10,0x20,0x50,0x90,0x11,0x11,0x12,0x14,0x18,0x10,0x80,0x40,0x44,0xfe,0x80,0x88,0xfc,0x88,0x88,0x88,0x8,0x8,0x8,0x8,0x50,0x20,
-+0x8,0x8,0x11,0x21,0x49,0x9,0x11,0x31,0x51,0x91,0x11,0x11,0x11,0x11,0x1f,0x10,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xfe,0x0,
-+0x8,0x8,0x10,0x20,0x49,0xa,0x11,0x31,0x51,0x91,0x11,0x11,0x11,0x11,0x10,0x10,0x80,0x80,0x84,0xfe,0x4,0x24,0xf4,0x24,0x24,0xe4,0x24,0x24,0xe4,0x4,0x28,0x10,
-+0xa,0x9,0x10,0x20,0x4b,0x8,0x10,0x37,0x50,0x90,0x1f,0x10,0x10,0x10,0x10,0x10,0x8,0x10,0xa0,0x8,0xfc,0x40,0x48,0xfc,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x8,0x8,0x10,0x21,0x4b,0x8,0x10,0x37,0x51,0x91,0x12,0x15,0x10,0x10,0x11,0x16,0x40,0x40,0x88,0x10,0xe0,0x40,0x88,0xfc,0x0,0xf8,0x8,0x10,0xa0,0x40,0xb0,0xe,
-+0x8,0x8,0x10,0x27,0x48,0xa,0x11,0x37,0x50,0x90,0x11,0x12,0x14,0x18,0x10,0x10,0x40,0x40,0x48,0xfc,0x40,0x48,0x50,0xfe,0x40,0xe0,0x50,0x48,0x4e,0x44,0x40,0x40,
-+0x8,0x8,0x12,0x22,0x4a,0xa,0x17,0x30,0x50,0x92,0x12,0x12,0x13,0x14,0x14,0x18,0x40,0x40,0x48,0x7c,0x40,0x44,0xfe,0x40,0x40,0x48,0x7c,0x40,0x40,0xc0,0x66,0x1c,
-+0x8,0x8,0x12,0x21,0x49,0x8,0x17,0x34,0x54,0x95,0x15,0x15,0x15,0x14,0x14,0x14,0x40,0x48,0x4c,0x48,0x50,0x44,0xfe,0x4,0x4,0xf4,0x14,0x14,0xf4,0x4,0x14,0x8,
-+0x8,0x8,0x13,0x22,0x4b,0xa,0x13,0x30,0x57,0x90,0x10,0x13,0x10,0x10,0x1f,0x10,0x40,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfc,0x40,0x48,0xfc,0x40,0x44,0xfe,0x0,
-+0x8,0x8,0x17,0x22,0x49,0x9,0x12,0x33,0x54,0x90,0x1f,0x10,0x12,0x12,0x13,0x10,0x8,0x7c,0x80,0x48,0x48,0x50,0x0,0xfc,0x40,0x44,0xfe,0x40,0x48,0x48,0xf8,0x8,
-+0x12,0x12,0x2a,0x4a,0x8f,0x10,0x2f,0x60,0xaf,0x22,0x2f,0x22,0x23,0x2e,0x20,0x21,0x10,0x10,0x90,0xa4,0xbe,0x44,0xa4,0x28,0xa8,0x10,0x90,0x28,0xa8,0x44,0x86,0x0,
-+0x12,0x14,0x2f,0x48,0x8f,0x18,0x2f,0x62,0xbf,0x24,0x27,0x24,0x28,0x2b,0x30,0x21,0x10,0x10,0x90,0xa4,0xbe,0xc4,0xa4,0x28,0xa8,0x10,0x90,0xa8,0xa8,0x44,0x86,0x0,
-+0xe,0x1a,0x2e,0x4a,0x8e,0x1a,0x2e,0x64,0xa7,0x2c,0x37,0x24,0x27,0x24,0x27,0x24,0xe0,0xa4,0xfe,0xa0,0xe0,0xa0,0xfe,0x84,0xe4,0x84,0xe4,0x84,0xe4,0x84,0xf4,0x8,
-+0x0,0x0,0x8,0x10,0x20,0x40,0x8,0x10,0x20,0x40,0x8,0x10,0x20,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x4,0x88,0x50,0x20,0x50,0x88,0x8,0x18,0x28,0x48,0x88,0x8,0x8,0x8,0x50,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x4,0x88,0x50,0x20,0x57,0x88,0x8,0x18,0x28,0x49,0x89,0x9,0xa,0xa,0x54,0x28,0x80,0x80,0x80,0x90,0xf8,0x90,0x90,0x90,0x90,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x4,0x8b,0x50,0x20,0x50,0x88,0xf,0x18,0x28,0x48,0x88,0x8,0x8,0x8,0x50,0x20,0x10,0xf8,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x4,0x88,0x50,0x21,0x51,0x89,0x9,0x19,0x29,0x49,0x89,0x9,0xa,0xa,0x54,0x28,0x40,0x20,0x24,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x4,0x8b,0x50,0x21,0x51,0x89,0x9,0x19,0x29,0x48,0x88,0xf,0x8,0x8,0x50,0x20,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x4,0x24,0xf4,0x4,0x4,0x28,0x10,
-+0x4,0x88,0x53,0x20,0x50,0x88,0x8,0x18,0x2b,0x48,0x88,0x8,0x8,0x8,0x57,0x20,0x0,0x8,0xfc,0x88,0x88,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x88,0x88,0xfe,0x0,
-+0x4,0x88,0x50,0x20,0x51,0x8a,0xb,0x18,0x28,0x48,0x88,0x8,0x9,0x9,0x52,0x24,0x40,0x40,0x40,0x90,0x8,0x4,0xfe,0x90,0x90,0x90,0x90,0x90,0x12,0x12,0xe,0x0,
-+0x4,0x88,0x51,0x21,0x51,0x89,0x9,0x19,0x29,0x49,0x89,0x9,0x8,0x8,0x50,0x20,0x0,0x4,0xfe,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0xfc,0x24,0x20,0x20,0x20,0x20,
-+0x5,0x89,0x51,0x22,0x52,0x8d,0x9,0x19,0x29,0x49,0x89,0x9,0x9,0x9,0x50,0x20,0x0,0x4,0xfe,0x4,0x24,0xf4,0x24,0x24,0x24,0xe4,0x28,0x10,0x2,0x2,0xfe,0x0,
-+0x4,0x88,0x50,0x27,0x50,0x88,0xb,0x1a,0x2a,0x4b,0x88,0x8,0x9,0x9,0x52,0x24,0xa0,0xa0,0xa8,0xfc,0xa8,0xa8,0xf8,0xa0,0xa4,0xfe,0xa4,0xa4,0x34,0x28,0x20,0x20,
-+0x4,0x88,0x50,0x20,0x57,0x88,0x9,0x19,0x2f,0x49,0x89,0x9,0x9,0xa,0x50,0x20,0x20,0x28,0x24,0x20,0xfe,0x20,0x20,0x28,0xe8,0x28,0x28,0x10,0x12,0x2a,0xc6,0x2,
-+0x4,0x88,0x50,0x21,0x52,0x8c,0x9,0x18,0x28,0x4f,0x88,0x8,0x9,0xa,0x53,0x20,0x40,0x40,0xa0,0x10,0xe,0x24,0xf0,0x0,0x4,0xfe,0x40,0x80,0x10,0x8,0xfc,0x4,
-+0x4,0x88,0x53,0x22,0x54,0x88,0x8,0x1f,0x28,0x49,0x88,0x8,0x8,0x8,0x50,0x20,0x40,0x20,0xfe,0x2,0x14,0x10,0x14,0xfe,0x10,0x10,0x90,0x90,0x10,0x10,0x50,0x20,
-+0x0,0x88,0x57,0x20,0x51,0x92,0x12,0x33,0x56,0x9a,0x12,0x12,0x12,0x1a,0xa4,0x40,0x10,0x10,0x90,0x90,0x10,0x10,0xd8,0x54,0x54,0x52,0x92,0x10,0x10,0x10,0x50,0x20,
-+0x4,0x8a,0x52,0x22,0x53,0x8a,0xa,0x1a,0x2b,0x48,0x88,0xb,0x8,0x8,0x57,0x20,0x0,0x20,0x24,0x28,0xb0,0x20,0x22,0xa2,0x1e,0x40,0x48,0xfc,0x40,0x44,0xfe,0x0,
-+0x4,0x89,0x51,0x21,0x51,0x88,0xb,0x1a,0x2a,0x4b,0x8a,0xa,0xb,0xa,0x52,0x22,0x8,0xfc,0x8,0x8,0xf8,0x4,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x14,0x8,
-+0x4,0x88,0x57,0x21,0x51,0x91,0x1f,0x31,0x53,0x93,0x15,0x15,0x19,0x11,0xa1,0x41,0x4,0xc4,0x4,0x14,0x14,0x54,0xf4,0x14,0x14,0x94,0x54,0x14,0x4,0x4,0x14,0x8,
-+0x4,0x88,0x50,0x21,0x52,0x8d,0x8,0x18,0x2f,0x48,0x89,0x9,0xa,0xc,0x51,0x20,0x40,0x40,0xa0,0x10,0x8,0xf6,0x40,0x48,0xfc,0x40,0x50,0x48,0x44,0x44,0x40,0x80,
-+0x4,0x88,0x50,0x21,0x52,0x8c,0xb,0x18,0x28,0x4a,0x89,0x9,0x9,0x8,0x57,0x20,0x40,0x40,0xa0,0x10,0x8,0x6,0xf8,0x0,0x8,0x48,0x48,0x50,0x50,0x4,0xfe,0x0,
-+0x4,0x88,0x57,0x20,0x50,0x8b,0x8,0x1b,0x28,0x48,0x8b,0xa,0xa,0xa,0x53,0x22,0x80,0x44,0xfe,0x0,0x0,0xfc,0x0,0xfc,0x0,0x4,0xfe,0x4,0x4,0x4,0xfc,0x4,
-+0x4,0x88,0x51,0x22,0x57,0x91,0x12,0x35,0x51,0x91,0x13,0x14,0x10,0x10,0xa1,0x46,0x40,0x80,0x10,0x8,0xfc,0x10,0x8,0x4,0xf8,0x8,0x10,0xa0,0x40,0xb0,0xe,0x4,
-+0x4,0x88,0x57,0x20,0x50,0x89,0xf,0x18,0x2b,0x4a,0x8a,0xa,0xb,0xa,0x50,0x20,0x40,0x44,0xfe,0x40,0xa0,0x14,0xfe,0x8,0xc8,0x48,0x48,0x48,0xc8,0x8,0x28,0x10,
-+0x4,0x8b,0x52,0x22,0x53,0x8a,0xa,0x1b,0x28,0x4f,0x88,0x8,0x9,0xa,0x54,0x20,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x40,0xfe,0x40,0xe0,0x50,0x4e,0x44,0x40,
-+0x4,0x8f,0x54,0x24,0x54,0x97,0x14,0x10,0x31,0x52,0x95,0x10,0x10,0x10,0xa1,0x46,0x4,0xfe,0xa4,0xa4,0xa4,0xfc,0x84,0x80,0xf8,0x8,0x8,0x90,0x60,0x40,0x80,0x0,
-+0x4,0x88,0x53,0x22,0x52,0x8b,0xa,0x1a,0x2b,0x4a,0x88,0x8,0x8,0x9,0x52,0x24,0x0,0x44,0x9e,0x4,0x4,0x9c,0x4,0x4,0xfc,0x94,0x90,0x90,0x90,0x12,0x12,0xe,
-+0x4,0x88,0x50,0x21,0x52,0x95,0x18,0x30,0x57,0x90,0x13,0x12,0x12,0x12,0xa3,0x42,0x40,0x40,0xa0,0x10,0x8,0xf6,0x40,0x48,0xfc,0x40,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x4,0x88,0x57,0x21,0x51,0x89,0xa,0x1c,0x28,0x4f,0x88,0x8,0x8,0x8,0x50,0x20,0x80,0x48,0xfc,0x10,0x10,0x10,0xa8,0x44,0x40,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x8,0x8f,0x51,0x21,0x51,0x97,0x14,0x34,0x54,0x97,0x11,0x11,0x11,0x11,0xaa,0x44,0x20,0x20,0x20,0x40,0x7e,0x82,0x14,0x10,0x54,0x54,0x52,0x52,0x92,0x10,0x50,0x20,
-+0x5,0x89,0x51,0x21,0x5f,0x91,0x11,0x31,0x57,0x94,0x14,0x14,0x17,0x14,0xa0,0x41,0x4,0x3e,0x24,0x24,0xe4,0x3c,0x24,0x24,0xa4,0xbc,0xa4,0xa4,0xa4,0x44,0x94,0x8,
-+0x4,0x88,0x57,0x20,0x51,0x92,0x14,0x3b,0x52,0x93,0x12,0x13,0x12,0x10,0xaf,0x40,0x40,0x48,0xfc,0xe0,0x50,0x48,0x46,0xf8,0x8,0xf8,0x8,0xf8,0x8,0x0,0xfe,0x0,
-+0x4,0x8b,0x52,0x22,0x53,0x92,0x12,0x33,0x50,0x9f,0x12,0x12,0x12,0x12,0xa3,0x42,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x0,0xfe,0x40,0x48,0x30,0x90,0xe,0x4,
-+0x0,0x8f,0x54,0x27,0x54,0x97,0x10,0x33,0x52,0x93,0x12,0x13,0x12,0x12,0xa2,0x42,0x4,0xfe,0x44,0xfc,0x44,0xfc,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x4,0x8b,0x52,0x22,0x53,0x8a,0xa,0x1a,0x2a,0x4a,0x8a,0xa,0xa,0xa,0x54,0x28,0x4,0xfe,0x24,0x24,0xfc,0x0,0xfc,0x84,0xfc,0x84,0x84,0xfc,0x84,0x84,0xfc,0x84,
-+0x4,0x8b,0x50,0x20,0x57,0x88,0x9,0xa,0x18,0x2f,0x48,0x88,0x9,0xa,0x54,0x20,0x0,0xf8,0x90,0x60,0xfc,0xc4,0x48,0xc0,0x44,0xfe,0x40,0xe0,0x50,0x4e,0x44,0x40,
-+0x4,0x8f,0x51,0x20,0x5f,0x88,0xb,0x1a,0x2b,0x4a,0x8b,0x8,0xf,0x8,0x50,0x20,0x40,0xfc,0x10,0xa4,0xfe,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x40,0xfe,0x40,0x40,0x40,
-+0x4,0x8f,0x51,0x20,0x5f,0x88,0xb,0x1a,0x2b,0x4a,0x8b,0x8,0x8,0x9,0x52,0x2c,0x40,0xfc,0x10,0xa4,0xfe,0x0,0xfc,0x4,0xfc,0x4,0xfc,0xa0,0xa0,0x22,0x22,0x1e,
-+0x0,0x8f,0x58,0x2a,0x69,0xaf,0x28,0x2a,0x6a,0xaa,0x2b,0x28,0x28,0x29,0xb2,0x44,0x4,0xfe,0x0,0x28,0x48,0xee,0x92,0xa4,0xa8,0xa8,0xe8,0x88,0x94,0x14,0x24,0x42,
-+0x4,0x88,0x57,0x20,0x52,0x91,0x13,0x36,0x5b,0x92,0x13,0x10,0x12,0x14,0xa9,0x40,0x40,0x44,0xfe,0x40,0xa8,0x10,0xf8,0xe,0xf8,0x8,0xf8,0x40,0x50,0x4c,0x44,0x80,
-+0x2,0x8a,0x53,0x24,0x59,0x97,0x15,0x35,0x57,0x95,0x15,0x17,0x15,0x15,0xa8,0x40,0x4,0x3e,0x94,0x94,0x14,0xec,0x40,0x58,0xde,0x68,0x48,0xfe,0x48,0x48,0xc8,0x8,
-+0x0,0x8b,0x50,0x2f,0x50,0x97,0x15,0x34,0x57,0x90,0x17,0x10,0x1f,0x15,0xa4,0x48,0x38,0xc0,0x44,0xfe,0x40,0xfc,0x54,0xe4,0xfc,0x40,0xfc,0x40,0xfe,0x24,0x92,0x2,
-+0x1,0x8f,0x51,0x27,0x54,0x97,0x11,0x32,0x57,0x9a,0x13,0x12,0x13,0x12,0xa3,0x42,0x10,0xfe,0x10,0xbc,0xa4,0xbc,0x40,0x24,0xfe,0x20,0xfc,0x20,0xfc,0x20,0xfe,0x0,
-+0x0,0x10,0x10,0x10,0x1f,0x22,0x22,0x22,0x54,0x8c,0x8,0x8,0x10,0x20,0xc0,0x0,0x10,0x10,0x10,0x10,0xfc,0x10,0x90,0x90,0x90,0x94,0xfe,0x10,0x10,0x10,0x10,0x10,
-+0x1,0x7f,0x49,0x49,0x7f,0x49,0x49,0x7f,0x8,0xff,0x8,0x1c,0x2a,0x49,0x88,0x8,0x20,0xa0,0x3c,0x44,0xa8,0x10,0x20,0x60,0xbe,0x22,0x44,0xa4,0x18,0x10,0x20,0xc0,
-+0x20,0x20,0x20,0x21,0x3a,0x4c,0x4b,0x4a,0xab,0x12,0x13,0x22,0x22,0x42,0x83,0x2,0x40,0x40,0xa0,0x10,0x8e,0x44,0xf8,0x8,0xf8,0x8,0xf8,0x48,0x30,0x90,0xc,0x4,
-+0x4,0xf,0x32,0x7,0x59,0x7f,0x40,0x9f,0x1,0x1f,0x11,0x1f,0x11,0x1f,0x8,0x30,0x0,0xf0,0x60,0x80,0x0,0xfe,0x2,0xf4,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x20,0x18,
-+0x2,0x2,0x7,0x4,0xa,0x11,0x6,0x18,0xe0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xe0,0x40,0x80,0x0,0xc0,0x30,0xe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x10,0x10,0x1e,0x24,0x28,0x40,0x90,0x10,0x10,0x10,0x12,0x14,0x18,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x20,0x23,0x20,0x3c,0x44,0x89,0x23,0x20,0x20,0x20,0x21,0x25,0x2a,0x32,0x24,0x0,0x0,0xf8,0x20,0x40,0x80,0x4,0xfe,0x94,0x94,0x94,0x24,0x24,0x44,0x44,0xa8,0x10,
-+0x20,0x20,0x20,0x3f,0x44,0x8a,0x22,0x22,0x22,0x22,0x23,0x20,0x28,0x30,0x20,0x0,0x40,0x40,0x44,0xfe,0x40,0x48,0x48,0x48,0x48,0x48,0xf8,0x48,0x40,0x42,0x42,0x3e,
-+0x21,0x21,0x21,0x3d,0x46,0x89,0x20,0x23,0x20,0x20,0x20,0x24,0x28,0x30,0x20,0x0,0x0,0x0,0x4,0xfe,0x0,0xf8,0x0,0xf8,0x8,0x8,0x8,0x8,0x8,0xa,0xa,0x6,
-+0x20,0x20,0x23,0x3c,0x44,0x88,0x20,0x20,0x2f,0x20,0x20,0x24,0x28,0x30,0x27,0x0,0x8,0x3c,0xc0,0x40,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x48,0xfc,0x0,
-+0x20,0x20,0x23,0x3c,0x44,0x88,0x20,0x2f,0x20,0x20,0x20,0x24,0x29,0x31,0x22,0xc,0x8,0x3c,0xc0,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,
-+0x20,0x20,0x21,0x3d,0x46,0x88,0x23,0x20,0x20,0x20,0x20,0x24,0x28,0x30,0x21,0x6,0x80,0x84,0xfe,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x28,0x10,
-+0x20,0x20,0x20,0x3c,0x45,0x8a,0x27,0x20,0x20,0x23,0x22,0x26,0x2a,0x32,0x23,0x2,0x40,0x40,0x80,0x80,0x10,0x8,0xfc,0x4,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x20,0x20,0x20,0x3f,0x46,0x8a,0x22,0x22,0x22,0x22,0x22,0x26,0x2a,0x32,0x22,0x2,0x40,0x40,0x84,0xfe,0x4,0x4,0xf4,0x94,0x94,0x94,0x94,0xf4,0x4,0x4,0x14,0x8,
-+0x20,0x20,0x23,0x3c,0x44,0x8b,0x22,0x24,0x21,0x20,0x20,0x27,0x28,0x30,0x21,0x0,0x40,0x48,0xfc,0x40,0x40,0xfc,0x4,0x8,0xf0,0x20,0x44,0xfe,0x40,0x40,0x40,0x80,
-+0x20,0x20,0x20,0x3c,0x45,0x8a,0x25,0x20,0x20,0x27,0x20,0x21,0x2a,0x34,0x21,0x0,0x40,0x40,0xa0,0xa0,0x10,0x8,0xf6,0x40,0x48,0xfc,0x40,0x50,0x4c,0x44,0x40,0x80,
-+0x20,0x23,0x22,0x3e,0x47,0x8a,0x22,0x23,0x22,0x22,0x23,0x26,0x2a,0x32,0x23,0x0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x20,0x24,0xa8,0x30,0x22,0xa2,0x1e,0x0,
-+0x20,0x20,0x27,0x3c,0x45,0x8a,0x24,0x2b,0x22,0x23,0x22,0x23,0x2a,0x30,0x27,0x0,0x40,0x48,0xfc,0xe0,0x50,0x48,0x46,0xf8,0x8,0xf8,0x8,0xf8,0x8,0x0,0xfc,0x0,
-+0x20,0x20,0x21,0x3d,0x45,0x89,0x21,0x21,0x21,0x20,0x23,0x20,0x28,0x30,0x20,0x7,0x20,0xa4,0x2e,0x24,0x24,0xac,0x24,0x24,0xfc,0x20,0xfc,0x88,0x50,0x20,0xd8,0x6,
-+0x21,0x21,0x27,0x39,0x49,0x93,0x2,0x23,0x22,0x23,0x20,0x27,0x28,0x31,0x22,0xc,0x10,0x14,0xfe,0x10,0x10,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xfe,0xa0,0x10,0xe,0x4,
-+0x21,0x20,0x27,0x38,0x4b,0x90,0xf,0x20,0x21,0x21,0x22,0x2b,0x34,0x28,0x17,0x0,0x10,0xa0,0xfc,0x40,0xfc,0x40,0xfe,0x88,0xfc,0x48,0x48,0xf8,0x88,0x88,0xfe,0x0,
-+0x21,0x21,0x27,0x39,0x49,0x90,0x3,0x22,0x23,0x20,0x27,0x20,0x2b,0x30,0x2f,0x0,0x10,0x14,0xfe,0x10,0xf0,0x40,0xf8,0x48,0xf8,0x40,0xfc,0x40,0xf8,0x40,0xfe,0x0,
-+0x22,0x22,0x22,0x3f,0x4a,0x92,0xf,0x20,0x27,0x24,0x27,0x24,0x2f,0x34,0x25,0x4,0x88,0x88,0x88,0xd0,0x9e,0xa4,0xf4,0x14,0xd4,0x54,0xc8,0x48,0xd4,0x54,0x64,0x82,
-+0x20,0x27,0x24,0x3c,0x4f,0x94,0x4,0x27,0x21,0x27,0x21,0x21,0x2f,0x31,0x22,0x4,0x4,0xbe,0xa4,0xa4,0xbc,0x20,0xa4,0xbc,0x10,0xfc,0x10,0x14,0xfe,0x10,0xc,0x4,
-+0x20,0x2f,0x20,0x3b,0x4a,0x97,0x5,0x2b,0x21,0x23,0x21,0x27,0x29,0x33,0x2d,0x1,0x40,0xfe,0x40,0xf8,0x48,0xfe,0x12,0xfc,0x10,0xf8,0x10,0xfe,0x48,0x30,0x8e,0x4,
-+0x1,0x0,0x3f,0x20,0x24,0x24,0x24,0x24,0x24,0x27,0x24,0x24,0x44,0x44,0x83,0x0,0x0,0x88,0xfc,0x0,0x0,0x0,0x8,0x30,0xc0,0x0,0x0,0x0,0x4,0x4,0xfc,0x0,
-+0x1,0x0,0x3f,0x20,0x20,0x2f,0x20,0x20,0x3f,0x21,0x21,0x21,0x42,0x42,0x84,0x18,0x0,0x88,0xfc,0x0,0x10,0xf8,0x80,0x84,0xfe,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,
-+0x1,0x0,0x3f,0x20,0x20,0x3f,0x20,0x20,0x2f,0x24,0x22,0x21,0x40,0x41,0x86,0x18,0x0,0x88,0xfc,0x80,0x84,0xfe,0x80,0x80,0xf8,0x10,0x20,0x40,0x80,0x60,0x1e,0x4,
-+0x1,0x0,0x3f,0x24,0x24,0x27,0x28,0x30,0x27,0x24,0x24,0x27,0x44,0x44,0x84,0x3,0x0,0x88,0xfc,0x0,0x8,0xfc,0x8,0x48,0xe8,0x48,0x48,0xc8,0x28,0x12,0x2,0xfe,
-+0x1,0x0,0x3f,0x20,0x22,0x24,0x24,0x2f,0x34,0x24,0x24,0x24,0x45,0x46,0x84,0x4,0x0,0x88,0xfc,0x0,0x20,0x20,0x24,0xfe,0x60,0x70,0xa8,0xa8,0x26,0x24,0x20,0x20,
-+0x1,0x0,0x3f,0x24,0x22,0x3f,0x20,0x20,0x2f,0x20,0x20,0x3f,0x40,0x40,0x80,0x0,0x0,0x88,0xfc,0x10,0x20,0xfc,0x80,0x90,0xf8,0x80,0x84,0xfe,0x80,0x80,0x80,0x80,
-+0x1,0x0,0x3f,0x22,0x3f,0x22,0x23,0x20,0x27,0x24,0x27,0x24,0x44,0x48,0x88,0x10,0x0,0x88,0xfc,0x20,0xfc,0x20,0xe0,0x0,0xf0,0x10,0xf0,0x80,0x40,0x30,0xe,0x4,
-+0x1,0x0,0x3f,0x20,0x2f,0x21,0x22,0x24,0x2f,0x34,0x27,0x24,0x47,0x44,0x80,0x0,0x0,0x88,0xfc,0x80,0xfc,0x40,0xa0,0x90,0xfe,0x94,0xf0,0x90,0xf0,0x92,0x82,0x7e,
-+0x1,0x0,0x3f,0x22,0x2c,0x28,0x28,0x2e,0x28,0x28,0x2f,0x29,0x42,0x44,0x88,0x30,0x0,0x88,0xfc,0x80,0xb8,0x88,0x88,0xb8,0x88,0x88,0xf8,0x48,0x20,0x10,0xe,0x4,
-+0x1,0x0,0x3f,0x21,0x2f,0x28,0x2f,0x28,0x2f,0x21,0x22,0x3f,0x40,0x40,0x80,0x0,0x0,0x88,0xfc,0x0,0xf8,0x88,0xf8,0x88,0xf8,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,
-+0x0,0x3f,0x20,0x2f,0x20,0x3f,0x21,0x2f,0x22,0x27,0x2c,0x34,0x24,0x41,0x42,0x8c,0x80,0xfe,0x80,0xf8,0x88,0xfe,0x8,0xf8,0x20,0xf0,0x1e,0x94,0x90,0x40,0x30,0x8,
-+0x1,0x0,0x3f,0x22,0x2f,0x22,0x2f,0x22,0x3f,0x24,0x27,0x24,0x44,0x4a,0x91,0x0,0x0,0x88,0xfc,0x20,0xa4,0x3e,0xa8,0x48,0xa8,0x28,0xa8,0x90,0x90,0xa8,0x44,0x82,
-+0x0,0x3f,0x24,0x3f,0x24,0x27,0x20,0x2f,0x28,0x2f,0x20,0x2f,0x20,0x4f,0x40,0xbf,0x80,0xfe,0x10,0xfc,0x10,0xf0,0x80,0xf8,0x88,0xf8,0x80,0xf8,0x80,0xf8,0x80,0xfe,
-+0x0,0x3f,0x20,0x2f,0x28,0x2f,0x28,0x2f,0x20,0x2f,0x20,0x3f,0x24,0x4b,0x40,0xbf,0x80,0xfe,0x0,0xf8,0x88,0xf8,0x88,0xf8,0x80,0xf8,0x80,0xfe,0x90,0xe8,0x80,0xfe,
-+0x0,0x3f,0x24,0x27,0x29,0x2a,0x3f,0x2a,0x2f,0x2a,0x2f,0x2a,0x2a,0x4a,0x51,0x80,0x80,0xfe,0x0,0xfc,0x24,0x24,0xac,0xc8,0xa8,0xbe,0xc8,0x88,0xfe,0x88,0x88,0x8,
-+0x0,0x3f,0x20,0x3f,0x20,0x2f,0x2a,0x2b,0x2a,0x2f,0x20,0x27,0x20,0x5f,0x42,0x8c,0x80,0xfe,0x80,0xfe,0x0,0xf8,0x28,0xe8,0x28,0xf8,0x0,0xf0,0x0,0xfc,0xa0,0x98,
-+0x0,0x3f,0x22,0x24,0x2d,0x36,0x24,0x24,0x27,0x24,0x27,0x24,0x27,0x44,0x44,0x84,0x80,0xfe,0x50,0xfc,0x90,0xfc,0x90,0x9c,0xf0,0x10,0xf0,0x10,0xf0,0x10,0x50,0x20,
-+0x10,0x10,0x10,0x10,0x58,0x54,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x10,0x17,0x10,0x58,0x54,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x11,0x12,0x14,0x0,0x4,0xfe,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x84,0x4,0x28,0x10,
-+0x10,0x10,0x10,0x10,0x5b,0x54,0x50,0x91,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x90,0x90,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x10,0x10,0x13,0x10,0x58,0x54,0x50,0x97,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x8,0x1c,0xe0,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x10,0x10,0x17,0x10,0x58,0x54,0x5f,0x90,0x10,0x10,0x10,0x10,0x11,0x11,0x12,0x14,0x0,0x8,0xfc,0x40,0x40,0x44,0xfe,0x40,0x60,0xa0,0xa0,0xa0,0x22,0x22,0x1e,0x0,
-+0x10,0x10,0x10,0x17,0x58,0x54,0x50,0x93,0x12,0x11,0x10,0x10,0x10,0x11,0x12,0x1c,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0xf8,0x8,0x10,0xa0,0x40,0xa0,0x10,0xe,0x4,
-+0x10,0x13,0x12,0x12,0x5a,0x56,0x52,0x92,0x12,0x12,0x12,0x12,0x13,0x12,0x13,0x10,0x8,0xfc,0x0,0x4,0x84,0x48,0x48,0x30,0x10,0x28,0x48,0x84,0x4,0x0,0xfe,0x0,
-+0x20,0x20,0x20,0x20,0xb7,0xac,0xa4,0xa4,0x24,0x27,0x24,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0xfc,0x44,0x40,0x40,0x40,0x40,0x40,
-+0x10,0x10,0x10,0x10,0x59,0x56,0x50,0x90,0x17,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x80,0x80,0x88,0xfc,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x11,0x11,0x11,0x12,0x5b,0x54,0x53,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x0,0x4,0xfe,0x0,0xf8,0x0,0xf0,0x10,0x10,0x10,0x10,0x10,0x12,0xa,0x6,0x2,
-+0x11,0x11,0x11,0x11,0x59,0x55,0x51,0x9f,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x0,0x8,0x10,0x20,0x40,0x80,0x4,0xfe,0x40,0x40,0x20,0x20,0x10,0x4e,0x84,0x0,
-+0x10,0x10,0x10,0x10,0x59,0x56,0x54,0x91,0x11,0x11,0x11,0x11,0x11,0x11,0x10,0x10,0x40,0x40,0xa0,0x90,0x8,0xe,0x4,0xf0,0x10,0x10,0x50,0x20,0x4,0x4,0xfc,0x0,
-+0x10,0x10,0x10,0x10,0x59,0x55,0x52,0x94,0x10,0x10,0x10,0x11,0x12,0x13,0x10,0x10,0x0,0x20,0xa0,0x90,0x10,0x8,0xe,0x44,0x40,0x80,0x80,0x10,0x8,0xfc,0x4,0x0,
-+0x10,0x10,0x10,0x17,0x58,0x54,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x80,0x40,0x4,0xfe,0x40,0x40,0x60,0x50,0x4c,0x44,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x10,0x10,0x13,0x10,0x58,0x54,0x50,0x93,0x10,0x10,0x10,0x10,0x10,0x10,0x17,0x10,0x0,0x8,0xfc,0x88,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x88,0x88,0x88,0xfe,0x0,
-+0x10,0x10,0x10,0x10,0x5f,0x54,0x50,0x90,0x13,0x12,0x12,0x12,0x12,0x12,0x13,0x12,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x48,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x10,0x10,0x5b,0x54,0x50,0x90,0x11,0x11,0x12,0x14,0x18,0x10,0x10,0x10,0x40,0x50,0x48,0x40,0xfe,0x40,0xc0,0xe0,0x50,0x50,0x48,0x4e,0x44,0x40,0x40,0x40,
-+0x10,0x17,0x10,0x12,0x59,0x55,0x51,0x90,0x1f,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x8,0xfc,0x40,0x48,0x48,0x48,0x50,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x10,0x10,0x13,0x12,0x5a,0x56,0x53,0x92,0x12,0x12,0x13,0x12,0x10,0x10,0x1f,0x10,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x0,0x4,0xfe,0x0,
-+0x10,0x10,0x10,0x13,0x5a,0x56,0x52,0x92,0x12,0x1f,0x10,0x10,0x10,0x11,0x12,0x14,0x40,0x40,0x48,0xfc,0x48,0x48,0x48,0x48,0x48,0xfe,0x40,0xa0,0xa0,0x10,0xe,0x4,
-+0x11,0x11,0x11,0x11,0x5a,0x54,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x0,0x0,0x4,0xfe,0x80,0x80,0x88,0xfc,0x80,0x80,0x88,0xfc,0x80,0x80,0x80,0x80,
-+0x10,0x13,0x12,0x12,0x5b,0x56,0x52,0x92,0x12,0x12,0x12,0x12,0x14,0x14,0x18,0x10,0x4,0xfe,0x4,0x4,0xfc,0x0,0x80,0x84,0x88,0x90,0xa0,0xc0,0x82,0x82,0x7e,0x0,
-+0x10,0x10,0x10,0x17,0x58,0x54,0x57,0x94,0x14,0x17,0x10,0x10,0x11,0x11,0x12,0x14,0xa0,0xa0,0xa4,0xfe,0xa4,0xa4,0xfc,0xa4,0xa0,0xfe,0xa2,0xa2,0x2a,0x24,0x20,0x20,
-+0x10,0x10,0x13,0x10,0x58,0x54,0x51,0x92,0x14,0x13,0x12,0x12,0x12,0x12,0x13,0x12,0x0,0x4,0xfe,0x84,0x84,0x84,0x14,0x8,0x0,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x13,0x11,0x10,0x58,0x54,0x51,0x92,0x15,0x10,0x10,0x17,0x10,0x10,0x10,0x10,0x0,0xf8,0x10,0xa0,0x40,0xa0,0x50,0x4e,0xf4,0x40,0x48,0xfc,0x40,0x40,0x40,0x40,
-+0x10,0x10,0x10,0x18,0x55,0x52,0x57,0x90,0x10,0x13,0x12,0x12,0x12,0x12,0x13,0x12,0x40,0x40,0x80,0x80,0x10,0x8,0xfc,0x4,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x20,0x21,0x2f,0x30,0xa8,0xa0,0xbf,0xa2,0x22,0x24,0x25,0x28,0x2f,0x20,0x20,0x21,0x10,0x10,0x90,0x14,0x7e,0x14,0xd4,0x14,0x14,0x14,0x24,0xa4,0xa4,0x44,0x94,0x8,
-+0x20,0x27,0x24,0x24,0xb4,0xac,0xa7,0xa4,0x24,0x24,0x24,0x24,0x28,0x29,0x31,0x26,0x4,0xfe,0x40,0x50,0x48,0x40,0xfe,0x40,0x40,0x40,0xa0,0xa0,0xa0,0x10,0xe,0x4,
-+0x20,0x27,0x24,0x24,0xb5,0xad,0xa5,0xa5,0x25,0x25,0x25,0x21,0x22,0x22,0x24,0x28,0x44,0xe4,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x4,0x84,0x44,0x54,0x8,
-+0x10,0x12,0x12,0x12,0x5b,0x54,0x53,0x90,0x10,0x13,0x12,0x12,0x12,0x12,0x11,0x10,0x40,0x48,0x48,0x48,0xf8,0x0,0xf8,0x8,0x8,0xf8,0x8,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x10,0x10,0x11,0x5a,0x54,0x53,0x92,0x12,0x13,0x12,0x12,0x13,0x12,0x10,0x10,0x80,0x80,0x84,0xfe,0x4,0x24,0xf4,0x24,0x24,0xe4,0x24,0x24,0xe4,0x4,0x28,0x10,
-+0x10,0x10,0x11,0x11,0x5a,0x54,0x50,0x91,0x12,0x14,0x1b,0x12,0x12,0x12,0x13,0x12,0x80,0x80,0xf8,0x10,0xa0,0x40,0xa0,0x10,0xe,0x0,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x20,0x27,0x24,0x28,0xb7,0xa9,0xa1,0xa2,0x27,0x20,0x20,0x2f,0x20,0x20,0x20,0x20,0x0,0xfe,0x82,0x84,0xf8,0x0,0x40,0x48,0xfc,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,
-+0x10,0x10,0x17,0x10,0x58,0x57,0x54,0x98,0x13,0x10,0x10,0x17,0x10,0x10,0x11,0x10,0x40,0x48,0xfc,0x40,0x40,0xfe,0x2,0x4,0xf8,0x10,0x24,0xfe,0x40,0x40,0x40,0x80,
-+0x10,0x10,0x17,0x10,0x58,0x57,0x54,0x94,0x17,0x14,0x10,0x11,0x12,0x14,0x18,0x10,0x40,0x44,0xfe,0x40,0x44,0xfe,0x44,0x44,0xfc,0x44,0xe0,0x50,0x48,0x46,0x44,0x40,
-+0x21,0x25,0x25,0x25,0xb5,0xad,0xa5,0xa5,0x25,0x20,0x20,0x2f,0x20,0x20,0x3f,0x20,0x0,0x0,0xfc,0x4,0x28,0x10,0x28,0x46,0x80,0x80,0x90,0xf8,0x80,0x84,0xfe,0x0,
-+0x10,0x10,0x17,0x14,0x5c,0x57,0x54,0x94,0x17,0x10,0x10,0x17,0x10,0x10,0x1f,0x10,0x0,0x4,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x40,0x48,0xfc,0x40,0x44,0xfe,0x0,
-+0x10,0x17,0x14,0x14,0x5c,0x57,0x54,0x94,0x14,0x15,0x16,0x14,0x14,0x14,0x17,0x14,0x4,0xfe,0x44,0x44,0x54,0xfc,0x44,0xc4,0xe4,0x5c,0x4c,0x44,0x44,0x4,0xfc,0x4,
-+0x10,0x13,0x12,0x12,0x5b,0x54,0x57,0x94,0x14,0x14,0x17,0x14,0x14,0x14,0x13,0x10,0x8,0xfc,0x8,0x8,0xf8,0x4,0xfe,0x44,0x44,0x44,0xfc,0x0,0x2,0x2,0xfe,0x0,
-+0x12,0x11,0x10,0x13,0x58,0x50,0x57,0x94,0x14,0x17,0x10,0x11,0x12,0x14,0x10,0x10,0x8,0x10,0xa0,0xf8,0x48,0x48,0xf8,0x40,0x44,0xfe,0xc4,0x44,0x54,0x48,0x40,0x40,
-+0x10,0x10,0x11,0x1a,0x57,0x51,0x52,0x94,0x11,0x12,0x15,0x10,0x10,0x10,0x13,0x14,0x40,0x80,0x10,0x8,0xfc,0x10,0x8c,0x84,0xf8,0x8,0x10,0xa0,0x40,0xb0,0xe,0x4,
-+0x10,0x17,0x14,0x14,0x5d,0x54,0x54,0x94,0x17,0x14,0x14,0x14,0x14,0x15,0x17,0x10,0x8,0xfc,0x20,0x28,0xfc,0x20,0xa8,0x20,0xfe,0x20,0x50,0x50,0x88,0x4,0xfe,0x0,
-+0x10,0x10,0x17,0x10,0x58,0x57,0x52,0x91,0x10,0x17,0x10,0x10,0x1f,0x10,0x10,0x10,0x40,0x48,0xfc,0x40,0x44,0xfe,0x8,0x10,0xa0,0xfc,0x40,0x44,0xfe,0x40,0x40,0x40,
-+0x10,0x10,0x10,0x17,0x58,0x54,0x50,0x97,0x10,0x10,0x10,0x1f,0x10,0x10,0x10,0x10,0xa0,0xa0,0xa8,0xbc,0xa0,0xa0,0xa0,0xbc,0xa0,0xa0,0xa4,0xbe,0xa0,0xa0,0xa0,0xa0,
-+0x10,0x14,0x12,0x11,0x58,0x57,0x54,0x94,0x15,0x15,0x15,0x15,0x15,0x14,0x14,0x14,0x40,0x44,0x48,0x50,0x44,0xfe,0x4,0x4,0xf4,0x14,0x14,0x14,0xf4,0x4,0x14,0x8,
-+0x10,0x17,0x14,0x15,0x5c,0x57,0x54,0x94,0x17,0x15,0x15,0x15,0x15,0x14,0x14,0x14,0x4,0xfe,0x4,0x14,0xa4,0xfc,0x44,0x54,0xfc,0x4,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x10,0x17,0x14,0x14,0x5d,0x54,0x54,0x97,0x14,0x15,0x15,0x15,0x15,0x15,0x18,0x10,0x4,0xfe,0x44,0x44,0xf4,0x44,0x54,0xfc,0x4,0xf4,0x14,0x14,0xf4,0x4,0x14,0x8,
-+0x11,0x11,0x11,0x12,0x5c,0x55,0x51,0x92,0x14,0x11,0x11,0x15,0x15,0x19,0x10,0x10,0x0,0x4,0xfe,0xa4,0xa4,0x24,0x44,0x54,0x88,0x40,0x20,0x24,0xa,0xa,0xf8,0x0,
-+0x10,0x10,0x17,0x11,0x59,0x55,0x52,0x94,0x10,0x1f,0x10,0x10,0x10,0x10,0x10,0x10,0x80,0x48,0xfc,0x10,0x10,0x10,0xa8,0x44,0x40,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x20,0x27,0x24,0x24,0xb7,0xac,0xa4,0xa7,0x20,0x2f,0x29,0x29,0x29,0x29,0x3f,0x20,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x0,0xfc,0x24,0x24,0x24,0x24,0xfe,0x0,
-+0x10,0x10,0x13,0x1a,0x53,0x50,0x5f,0x90,0x13,0x12,0x12,0x12,0x12,0x10,0x11,0x16,0x40,0x48,0xfc,0x48,0xf8,0x40,0xfe,0x8,0xfc,0x8,0x48,0x48,0x48,0xb0,0x8,0x4,
-+0x10,0x17,0x14,0x14,0x5f,0x54,0x53,0x90,0x1f,0x11,0x13,0x10,0x10,0x10,0x10,0x10,0x4,0xbe,0xa4,0xa4,0xbc,0x0,0xf8,0x0,0xfe,0x0,0xf8,0x8,0x8,0x88,0x50,0x20,
-+0x10,0x17,0x14,0x14,0x5f,0x54,0x50,0x9f,0x10,0x10,0x10,0x10,0x11,0x11,0x12,0x14,0x4,0xfe,0xa4,0xa4,0xfc,0x80,0x44,0xfe,0x80,0x88,0xfc,0x88,0x8,0x8,0x28,0x10,
-+0x10,0x12,0x12,0x12,0x5b,0x54,0x50,0x97,0x10,0x10,0x17,0x14,0x14,0x14,0x14,0x14,0x40,0x48,0x48,0x48,0xf8,0x0,0x4,0xfe,0x40,0x84,0xfe,0xa4,0xa4,0xa4,0xa4,0xc,
-+0x10,0x11,0x17,0x11,0x59,0x55,0x57,0x91,0x13,0x13,0x15,0x15,0x19,0x11,0x11,0x11,0x90,0xd0,0x10,0x10,0x52,0x34,0xd8,0x10,0x10,0x90,0x50,0x28,0x28,0x44,0x82,0x0,
-+0x11,0x11,0x11,0x1a,0x55,0x51,0x51,0x91,0x11,0x11,0x11,0x13,0x14,0x10,0x11,0x16,0x0,0x4,0xfe,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xf8,0x10,0xa0,0x40,0xb0,0xe,
-+0x10,0x10,0x17,0x18,0x57,0x50,0x5f,0x90,0x11,0x13,0x10,0x17,0x11,0x12,0x14,0x10,0x40,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x80,0x10,0xe0,0x48,0xfc,0x50,0x4c,0x44,0xc0,
-+0x22,0x21,0x2f,0x21,0xb7,0xa9,0xa1,0xbf,0x21,0x21,0x27,0x21,0x23,0x25,0x29,0x21,0x10,0x24,0xfe,0x20,0xfc,0x24,0x24,0xfe,0x24,0x24,0xfc,0x20,0x30,0x2e,0x24,0x20,
-+0x10,0x13,0x12,0x13,0x5a,0x57,0x52,0x93,0x12,0x13,0x13,0x13,0x15,0x15,0x19,0x11,0x20,0xfe,0x20,0xfc,0x24,0xfe,0x24,0xfc,0x20,0xfc,0x24,0xfc,0x24,0xfc,0x24,0x2c,
-+0x10,0x13,0x12,0x13,0x5a,0x57,0x50,0x9f,0x10,0x13,0x12,0x13,0x11,0x12,0x14,0x10,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x40,0xfe,0x0,0xf8,0x8,0xf8,0x50,0x4c,0x44,0xc0,
-+0x11,0x11,0x11,0x1a,0x56,0x5b,0x52,0x92,0x13,0x12,0x12,0x13,0x12,0x12,0x12,0x14,0x40,0x24,0xfe,0x20,0x20,0xfc,0x20,0x20,0xfc,0x20,0x20,0xfe,0x0,0x94,0x4a,0x2,
-+0x10,0x17,0x11,0x10,0x5f,0x54,0x53,0x92,0x13,0x12,0x13,0x10,0x17,0x10,0x1f,0x10,0x40,0xfc,0x10,0xa4,0xfe,0x0,0xf8,0x48,0xf8,0x48,0xf8,0x40,0xfc,0x40,0xfe,0x0,
-+0x11,0x11,0x1f,0x11,0x5b,0x55,0x51,0x97,0x10,0x12,0x12,0x12,0x13,0x12,0x14,0x18,0x10,0x14,0xfe,0x10,0xb8,0x54,0x10,0xfc,0x48,0x40,0x7c,0x40,0x40,0xc0,0x46,0x3c,
-+0x10,0x1f,0x10,0x17,0x5d,0x55,0x55,0x97,0x10,0x13,0x10,0x1f,0x11,0x12,0x14,0x10,0x40,0xfe,0x0,0xfc,0x14,0xf4,0x14,0xfc,0x0,0xf8,0x0,0xfe,0x50,0x4c,0x44,0xc0,
-+0x21,0x2f,0x21,0x23,0xb2,0xab,0xa0,0xaf,0x28,0x33,0x22,0x23,0x22,0x23,0x22,0x23,0x10,0xfe,0x10,0xf8,0xa8,0xf8,0x0,0xfe,0x2,0xfc,0x8,0xf8,0x8,0xf8,0x8,0xf8,
-+0x0,0x3f,0x2,0x2,0xff,0x4,0x4,0x8,0x12,0x22,0xcb,0xa,0x12,0x22,0xa,0x4,0x10,0xf8,0x0,0x4,0xfe,0x80,0x40,0x20,0x10,0xe,0x24,0x90,0x48,0x48,0x0,0x0,
-+0x3c,0x27,0x24,0x29,0x26,0x24,0x34,0x28,0x21,0x26,0x18,0xe1,0x9,0x11,0x25,0x2,0x40,0xfc,0x80,0xf8,0x88,0xf8,0x88,0xf8,0x88,0xc0,0x30,0xe,0x50,0x28,0x28,0x0,
-+0x20,0x17,0x40,0x40,0x40,0x40,0x40,0x5f,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x4,0xfe,0x4,0x4,0x4,0x4,0x24,0xf4,0x4,0x4,0x4,0x4,0x4,0x4,0x14,0x8,
-+0x20,0x17,0x40,0x40,0x5f,0x40,0x40,0x40,0x4f,0x40,0x40,0x40,0x5f,0x40,0x40,0x40,0x4,0xfe,0x4,0x24,0xf4,0x4,0x4,0x44,0xe4,0x4,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x20,0x17,0x41,0x41,0x5f,0x41,0x41,0x4f,0x41,0x41,0x5f,0x41,0x41,0x41,0x41,0x41,0x4,0xfe,0x4,0x24,0xf4,0x4,0x44,0xe4,0x4,0x14,0xfc,0x14,0x54,0x24,0xc,0x4,
-+0x20,0x17,0x42,0x42,0x42,0x5f,0x42,0x44,0x45,0x49,0x4a,0x52,0x67,0x40,0x40,0x40,0x4,0xfe,0x4,0x4,0x24,0xf4,0x4,0x84,0x4,0x4,0x44,0x24,0xe4,0x4,0x14,0x8,
-+0x20,0x17,0x40,0x42,0x41,0x5f,0x40,0x44,0x42,0x41,0x42,0x44,0x48,0x40,0x40,0x40,0x4,0xfe,0x4,0x4,0x24,0xf4,0x44,0x44,0x84,0x4,0x84,0x64,0x24,0x4,0x14,0x8,
-+0x20,0x17,0x40,0x42,0x41,0x5f,0x40,0x47,0x44,0x44,0x44,0x44,0x48,0x50,0x40,0x40,0x4,0xfe,0x4,0x4,0x24,0xf4,0x4,0xc4,0x44,0x44,0x44,0x54,0x74,0x4,0x14,0x8,
-+0x20,0x17,0x40,0x50,0x48,0x47,0x40,0x58,0x49,0x49,0x4a,0x4c,0x53,0x60,0x40,0x40,0x4,0xfe,0x4,0x84,0xa4,0xf4,0x84,0x84,0x44,0x34,0x14,0x4,0xfc,0x4,0x14,0x8,
-+0x20,0x17,0x40,0x40,0x47,0x44,0x44,0x47,0x40,0x4f,0x48,0x48,0x48,0x4f,0x48,0x40,0x4,0xfe,0x4,0x44,0xe4,0x44,0x44,0xc4,0x4,0xe4,0x24,0x24,0x24,0xe4,0x14,0x8,
-+0x20,0x17,0x40,0x40,0x5f,0x51,0x51,0x5f,0x51,0x53,0x55,0x59,0x51,0x5f,0x50,0x40,0x4,0xfe,0x4,0x4,0xf4,0x14,0x54,0xf4,0x14,0x94,0x54,0x34,0x14,0xf4,0x14,0x8,
-+0x20,0x17,0x42,0x47,0x48,0x51,0x4f,0x49,0x4f,0x49,0x4f,0x41,0x41,0x40,0x40,0x40,0x4,0xfe,0x4,0xc4,0x84,0x24,0xf4,0x24,0xe4,0x24,0xe4,0x4,0x14,0xf4,0x4,0xc,
-+0x20,0x17,0x42,0x41,0x4f,0x48,0x4f,0x48,0x4f,0x4a,0x49,0x48,0x4a,0x4c,0x48,0x40,0x4,0xfe,0x4,0x24,0xf4,0x24,0xe4,0x24,0xe4,0x14,0x24,0xc4,0x44,0x34,0x4,0xc,
-+0x20,0x17,0x40,0x40,0x7f,0x40,0x5e,0x52,0x52,0x52,0x5e,0x40,0x7e,0x41,0x42,0x40,0x4,0xfe,0xa4,0x94,0xfc,0x84,0x84,0x94,0x54,0x64,0x44,0x54,0xb4,0x14,0x4,0xc,
-+0x20,0x17,0x40,0x4f,0x48,0x4f,0x48,0x4f,0x40,0x5f,0x50,0x5f,0x50,0x5f,0x40,0x40,0x4,0xfe,0x4,0xe4,0x24,0xe4,0x24,0xe4,0x4,0xf4,0x14,0xf4,0x14,0xf4,0x14,0x8,
-+0x20,0x17,0x40,0x42,0x4c,0x48,0x4e,0x48,0x4f,0x42,0x42,0x44,0x44,0x48,0x50,0x40,0x4,0xfe,0x4,0x24,0xf4,0x24,0xe4,0x24,0xe4,0x84,0x84,0x94,0x94,0x74,0x4,0xc,
-+0x20,0x17,0x40,0x40,0x5f,0x49,0x45,0x5f,0x50,0x67,0x44,0x42,0x41,0x46,0x58,0x40,0x4,0xfe,0x24,0xf4,0x4,0x24,0x44,0xfc,0xc,0xd4,0x44,0x84,0x4,0xc4,0x34,0x8,
-+0x20,0x17,0x40,0x4f,0x49,0x4f,0x48,0x4a,0x4c,0x40,0x4f,0x48,0x4f,0x48,0x4f,0x40,0x4,0xfe,0x4,0xe4,0x4,0xf4,0x84,0x54,0x34,0x4,0xe4,0x24,0xe4,0x24,0xf4,0x8,
-+0x20,0x17,0x48,0x44,0x44,0x7f,0x48,0x49,0x4e,0x4a,0x4a,0x52,0x52,0x66,0x40,0x40,0x4,0xfe,0x4,0x44,0x44,0xa4,0xa4,0x14,0x8c,0x64,0x24,0x4,0x84,0x64,0x24,0xc,
-+0x20,0x17,0x40,0x4f,0x48,0x4f,0x48,0x4f,0x48,0x4f,0x41,0x7f,0x41,0x46,0x58,0x40,0x4,0xfe,0x4,0xe4,0x24,0xe4,0x24,0xe4,0x24,0xe4,0x44,0xfc,0x4,0xc4,0x34,0xc,
-+0x20,0x17,0x40,0x5e,0x52,0x4a,0x44,0x4f,0x71,0x41,0x5f,0x41,0x42,0x44,0x58,0x40,0x4,0xfe,0x84,0xa4,0xcc,0x94,0x64,0xe4,0x1c,0x4,0xf4,0x4,0xc4,0x34,0x14,0x8,
-+0x20,0x17,0x41,0x4f,0x41,0x5f,0x42,0x44,0x4f,0x40,0x4f,0x4a,0x4a,0x4a,0x5f,0x40,0x4,0xfe,0x4,0xe4,0x4,0xf4,0x4,0x44,0xe4,0x4,0xe4,0xa4,0xa4,0xa4,0xf4,0x8,
-+0x20,0x17,0x41,0x5f,0x41,0x4f,0x48,0x4f,0x48,0x4f,0x48,0x4f,0x48,0x7f,0x44,0x48,0x4,0xfe,0x4,0xf4,0x4,0xe4,0x24,0xe4,0x24,0xe4,0x24,0xe4,0x24,0xfc,0x44,0x2c,
-+0x20,0x17,0x40,0x51,0x4a,0x7f,0x44,0x55,0x55,0x5f,0x54,0x44,0x48,0x51,0x40,0x40,0x4,0xfe,0x4,0x44,0x44,0xfc,0x94,0x44,0x44,0x44,0x44,0xa4,0xa4,0x14,0x14,0x8,
-+0x20,0x17,0x40,0x5c,0x44,0x7e,0x53,0x5e,0x52,0x5e,0x52,0x7e,0x43,0x42,0x42,0x40,0x4,0xfe,0x4,0x44,0x44,0xfc,0x14,0x94,0xa4,0xa4,0x44,0xa4,0x1c,0x4,0x14,0x8,
-+0x10,0x10,0x10,0x90,0x50,0x50,0x10,0x10,0x10,0x30,0x50,0x90,0x10,0x10,0x10,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x8,0x8,0x8,0x8,0xf,0x0,0x0,0x7f,0x8,0x8,0x8,0x8,0x10,0x60,0x0,0x20,0x20,0x20,0x20,0x20,0xe0,0x20,0x20,0xe0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x4,0x24,0x24,0x24,0x24,0x3c,0x7,0x4,0xfc,0x24,0x24,0x24,0x24,0x44,0x85,0x4,0x40,0x50,0x48,0x40,0x44,0x7e,0xc0,0x40,0x48,0x48,0x50,0x20,0x60,0x92,0xa,0x4,
-+0x0,0x40,0x30,0x10,0x80,0x48,0x48,0x10,0x10,0x20,0xe0,0x20,0x20,0x20,0x20,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x41,0x31,0x11,0x82,0x4c,0x4b,0x10,0x10,0x20,0xe0,0x21,0x22,0x22,0x21,0x20,0x0,0x0,0x4,0xfe,0x0,0x0,0xf0,0x10,0x20,0x40,0x80,0x0,0x2,0x2,0xfe,0x0,
-+0x0,0x40,0x33,0x12,0x82,0x4a,0x4a,0x13,0x12,0x22,0xe2,0x22,0x22,0x22,0x21,0x20,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x0,0x40,0x37,0x10,0x82,0x4a,0x49,0x11,0x10,0x20,0xe0,0x20,0x20,0x21,0x22,0x2c,0x0,0x0,0xfc,0x8,0x88,0x50,0x50,0x10,0xa0,0xa0,0x40,0xa0,0xa0,0x10,0xe,0x4,
-+0x0,0x40,0x30,0x17,0x80,0x48,0x4b,0x10,0x10,0x20,0xef,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x48,0xfc,0x40,0x50,0xf8,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x47,0x30,0x10,0x80,0x4f,0x49,0x11,0x11,0x21,0xe1,0x22,0x22,0x24,0x28,0x30,0x8,0xfc,0x0,0x0,0x4,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x0,0x40,0x30,0x10,0x87,0x48,0x48,0x11,0x11,0x22,0xe2,0x24,0x28,0x20,0x20,0x20,0x40,0x40,0x40,0x44,0xfe,0x40,0xe0,0x50,0x50,0x48,0x48,0x44,0x46,0x40,0x40,0x40,
-+0x0,0x4f,0x30,0x10,0x82,0x4a,0x4a,0x12,0x12,0x23,0xe0,0x20,0x20,0x20,0x20,0x20,0x4,0xfe,0x40,0x40,0x44,0x7e,0x44,0x44,0x44,0xfc,0x4,0x4,0x4,0x4,0x28,0x10,
-+0x0,0x40,0x20,0x2f,0x80,0x44,0x4c,0x14,0x14,0x27,0xe0,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x44,0xfe,0x40,0x44,0x44,0x44,0x44,0xfc,0x44,0x40,0x42,0x42,0x3e,0x0,
-+0x0,0x40,0x33,0x12,0x82,0x4a,0x4a,0x12,0x13,0x22,0xe2,0x22,0x22,0x22,0x23,0x22,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x40,0x30,0x17,0x84,0x44,0x4c,0x14,0x17,0x24,0xe4,0x24,0x24,0x27,0x24,0x20,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,0x0,
-+0x1,0x40,0x30,0x10,0x8f,0x40,0x48,0x10,0x10,0x20,0xe0,0x20,0x20,0x20,0x20,0x20,0x0,0x80,0x80,0x4,0xfe,0x80,0x80,0xa0,0x90,0x8c,0x84,0x80,0x80,0x80,0x80,0x80,
-+0x0,0x40,0x30,0x17,0x80,0x4a,0x4a,0x11,0x11,0x20,0xe0,0x20,0x21,0x22,0x24,0x28,0x80,0x40,0x44,0xfe,0x8,0x8,0x8,0x10,0x10,0xa0,0x40,0xa0,0x10,0x8,0xe,0x4,
-+0x0,0x40,0x30,0x17,0x80,0x48,0x49,0x11,0x11,0x21,0xe1,0x21,0x22,0x22,0x24,0x28,0x80,0x40,0x44,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x0,0x40,0x34,0x13,0x81,0x4f,0x48,0x10,0x10,0x20,0xe1,0x21,0x22,0x22,0x24,0x28,0x40,0x40,0x40,0x40,0x44,0xfe,0x84,0x84,0x84,0xc4,0x34,0x14,0x4,0x44,0x28,0x10,
-+0x0,0x4f,0x39,0x1a,0x8a,0x4c,0x4a,0x19,0x19,0x29,0xed,0x2a,0x28,0x28,0x29,0x2a,0x20,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x44,0x44,0x84,0x28,0x10,
-+0x2,0x42,0x22,0x22,0x9f,0x42,0x4a,0x12,0x12,0x23,0xe2,0x22,0x22,0x22,0x23,0x22,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0xf0,0x10,0x10,0x10,0x10,0xf0,0x10,
-+0x0,0x40,0x30,0x10,0x87,0x48,0x48,0x11,0x11,0x22,0xe2,0x24,0x28,0x20,0x20,0x20,0x40,0x50,0x4c,0x44,0xfe,0x40,0xe0,0x50,0x50,0x48,0x48,0x44,0x46,0x40,0x40,0x40,
-+0x1,0x41,0x31,0x11,0x8f,0x49,0x49,0x11,0x11,0x22,0xe2,0x22,0x24,0x25,0x28,0x30,0x0,0x20,0x10,0x4,0xfe,0x40,0x48,0x48,0x50,0x50,0x60,0x40,0xc2,0x42,0x3e,0x0,
-+0x0,0x40,0x30,0x10,0x80,0x4b,0x4a,0x12,0x12,0x23,0xe2,0x22,0x22,0x24,0x24,0x28,0x40,0x44,0x7e,0x40,0x44,0xfe,0x4,0x4,0x4,0xfc,0x4,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x40,0x30,0x13,0x82,0x4a,0x4a,0x12,0x12,0x2f,0xe0,0x20,0x20,0x21,0x22,0x2c,0x40,0x40,0x48,0xfc,0x48,0x48,0x48,0x48,0x48,0xfe,0x40,0xa0,0xa0,0x10,0xe,0x4,
-+0x0,0x40,0x30,0x1f,0x89,0x49,0x59,0x19,0x29,0x29,0xca,0x4c,0x48,0x4f,0x48,0x40,0x0,0x0,0x4,0xfe,0x24,0x24,0x24,0x24,0x24,0x24,0x1c,0x4,0x4,0xfc,0x4,0x0,
-+0x1,0x41,0x31,0x12,0x84,0x42,0x4a,0x13,0x16,0x22,0xe2,0x22,0x22,0x22,0x21,0x20,0x0,0x8,0xfc,0x40,0x40,0x48,0x7c,0xc8,0x48,0x48,0x68,0x50,0x42,0x2,0xfe,0x0,
-+0x0,0x40,0x30,0x11,0x81,0x4a,0x4c,0x10,0x17,0x20,0xe0,0x21,0x20,0x20,0x20,0x20,0x40,0x40,0xa0,0x10,0x10,0x88,0x46,0x40,0xf8,0x8,0x10,0x20,0xc0,0x40,0x30,0x10,
-+0x0,0x41,0x36,0x14,0x84,0x44,0x4c,0x14,0x15,0x26,0xe0,0x21,0x21,0x22,0x24,0x28,0x80,0x4,0x3e,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xb4,0xa8,0x20,0x20,0x20,0x20,0x20,
-+0x0,0x40,0x37,0x14,0x84,0x44,0x44,0x17,0x10,0x20,0xe1,0x22,0x24,0x28,0x21,0x20,0x8,0x7c,0x80,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x50,0x48,0x46,0x42,0x40,0x80,
-+0x0,0x40,0x30,0x17,0x80,0x40,0x49,0x12,0x17,0x20,0xe0,0x21,0x22,0x24,0x27,0x20,0x80,0x40,0x44,0xfe,0x80,0x80,0x8,0x18,0xe0,0x40,0x80,0x0,0x10,0x8,0xfc,0x4,
-+0x0,0x44,0x33,0x11,0x80,0x47,0x48,0x10,0x10,0x2f,0xe0,0x20,0x20,0x20,0x20,0x20,0x40,0x44,0x4c,0x50,0x40,0xfc,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x40,0x30,0x17,0x84,0x48,0x42,0x12,0x12,0x22,0xe3,0x22,0x22,0x22,0x21,0x20,0x80,0x40,0x40,0xfc,0x4,0x4,0x10,0x30,0x40,0x80,0x0,0x0,0x4,0x4,0xfc,0x0,
-+0x0,0x4f,0x30,0x10,0x80,0x47,0x4c,0x14,0x14,0x27,0xe0,0x20,0x20,0x21,0x25,0x22,0x0,0x90,0x90,0x90,0x90,0x90,0x10,0x20,0x20,0xa0,0xa0,0xa8,0xa4,0x42,0x7e,0x0,
-+0x0,0x47,0x34,0x14,0x84,0x47,0x4c,0x14,0x14,0x27,0xe4,0x24,0x24,0x25,0x26,0x24,0x8,0xfc,0x8,0x8,0x8,0xf8,0x40,0x40,0x44,0xfe,0x40,0x20,0x20,0x12,0xa,0x4,
-+0x0,0x40,0x37,0x10,0x80,0x48,0x49,0x12,0x14,0x27,0xe0,0x20,0x20,0x20,0x2f,0x20,0x0,0x10,0xf8,0x10,0x20,0xc0,0x18,0x6,0x2,0xfc,0x40,0x40,0x40,0x44,0xfe,0x0,
-+0x0,0x47,0x30,0x10,0x83,0x4a,0x4a,0x13,0x12,0x22,0xe2,0x23,0x22,0x20,0x2f,0x20,0x8,0xfc,0x0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x0,0xfe,0x0,
-+0x0,0x40,0x37,0x10,0x81,0x49,0x4b,0x15,0x11,0x21,0xe1,0x21,0x21,0x21,0x21,0x21,0x80,0x84,0xfe,0x80,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x0,0x40,0x37,0x12,0x82,0x43,0x42,0x14,0x16,0x29,0xe0,0x20,0x21,0x21,0x22,0x24,0x4,0x44,0xe4,0x4,0x14,0xd4,0x54,0x54,0x54,0x94,0x94,0x94,0x4,0x4,0x14,0x8,
-+0x0,0x40,0x30,0x17,0x80,0x4a,0x49,0x10,0x1f,0x20,0xe0,0x20,0x21,0x21,0x22,0x2c,0x40,0x40,0x48,0xfc,0x40,0x48,0x50,0x44,0xfe,0x40,0xa0,0xa0,0x10,0x8,0xe,0x4,
-+0x0,0x40,0x30,0x10,0x80,0x4b,0x4a,0x12,0x12,0x22,0xe2,0x22,0x20,0x20,0x21,0x26,0x40,0x44,0x7e,0x40,0x48,0xfc,0x8,0x48,0x48,0x48,0x48,0x48,0xa0,0x90,0xc,0x4,
-+0x0,0x47,0x34,0x14,0x84,0x4f,0x4c,0x14,0x14,0x24,0xe4,0x25,0x26,0x24,0x27,0x24,0x4,0xfe,0x44,0x44,0x54,0xfc,0x44,0x44,0xa4,0xa4,0xa4,0x14,0xc,0x4,0xfc,0x4,
-+0x0,0x4f,0x28,0x18,0x89,0x49,0x49,0x19,0x19,0x29,0xe9,0x29,0x28,0x28,0x2f,0x28,0x4,0xfe,0x4,0x24,0xf4,0x24,0x24,0x24,0x24,0x24,0xe4,0x24,0x4,0x4,0xfc,0x4,
-+0x0,0x42,0x32,0x13,0x84,0x48,0x48,0x17,0x10,0x21,0xe1,0x22,0x24,0x28,0x20,0x20,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0xe0,0x50,0x50,0x48,0x4e,0x44,0x40,0x40,
-+0x0,0x40,0x33,0x12,0x82,0x4a,0x4b,0x12,0x12,0x22,0xe3,0x22,0x22,0x22,0x23,0x22,0x40,0x88,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x40,0x30,0x11,0x87,0x45,0x4d,0x15,0x15,0x25,0xe5,0x25,0x25,0x25,0x3f,0x20,0x40,0x40,0x80,0x8,0xfc,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0xfe,0x0,
-+0x0,0x40,0x30,0x11,0x82,0x4c,0x49,0x10,0x10,0x2f,0xe0,0x20,0x21,0x22,0x27,0x20,0x40,0x40,0xa0,0x10,0x8,0xe,0xf4,0x0,0x4,0xfe,0x40,0x80,0x10,0x8,0xfc,0x4,
-+0x0,0x40,0x30,0x14,0x82,0x4a,0x48,0x11,0x12,0x24,0xe0,0x21,0x21,0x22,0x24,0x28,0xa0,0xa0,0xa0,0xa4,0xac,0xb0,0xa0,0xb0,0xac,0xa4,0xa0,0x20,0x22,0x22,0x1e,0x0,
-+0x1,0x41,0x31,0x11,0x82,0x4c,0x4b,0x12,0x12,0x23,0xe2,0x22,0x23,0x22,0x20,0x20,0x0,0x0,0x4,0xfe,0x4,0x24,0xf4,0x24,0x24,0xe4,0x24,0x24,0xe4,0x4,0x28,0x10,
-+0x1,0x41,0x31,0x13,0x84,0x40,0x49,0x16,0x10,0x23,0xe2,0x22,0x27,0x20,0x20,0x20,0x0,0x0,0xf8,0x10,0xa0,0x40,0xb0,0x4e,0x40,0xf8,0x40,0x44,0xfe,0x40,0x40,0x40,
-+0x2,0x41,0x31,0x1f,0x80,0x44,0x42,0x12,0x11,0x21,0xe2,0x22,0x24,0x28,0x20,0x20,0x4,0x4,0x14,0xf4,0x54,0x54,0x94,0x94,0x14,0x14,0x94,0x94,0x44,0x44,0x14,0x8,
-+0x0,0x48,0x24,0x24,0x80,0x51,0x5c,0x14,0x25,0x24,0xe4,0x25,0x26,0x24,0x20,0x20,0x40,0x40,0x48,0xfc,0xa0,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x0,0x47,0x30,0x10,0x83,0x48,0x48,0x13,0x10,0x2f,0xe2,0x21,0x21,0x20,0x20,0x20,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x14,0xfe,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x4,0x44,0x24,0x24,0x9f,0x44,0x44,0x14,0x14,0x28,0xe5,0x22,0x25,0x24,0x28,0x30,0x0,0x0,0x0,0x4,0xbe,0xa4,0xa4,0xa4,0xa4,0xa4,0x24,0x24,0x24,0xbc,0xa4,0x0,
-+0x0,0x40,0x37,0x10,0x80,0x4b,0x4a,0x12,0x12,0x23,0xe0,0x21,0x22,0x2c,0x20,0x20,0x40,0x44,0xfe,0x40,0x48,0xfc,0x48,0x48,0x48,0xf8,0xe0,0x50,0x4e,0x44,0x40,0x40,
-+0x0,0x47,0x30,0x10,0x87,0x49,0x49,0x11,0x1f,0x20,0xe3,0x22,0x22,0x22,0x23,0x22,0x8,0xfc,0x80,0x90,0xf8,0x10,0x10,0x14,0xfe,0x0,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x40,0x30,0x17,0x80,0x42,0x49,0x10,0x17,0x20,0xe1,0x22,0x24,0x28,0x20,0x20,0x40,0x40,0x48,0xfc,0x40,0x48,0x50,0x44,0xfe,0xd0,0x50,0x48,0x4e,0x44,0x40,0x40,
-+0x0,0x47,0x34,0x14,0x87,0x4c,0x4d,0x14,0x17,0x24,0xe4,0x24,0x24,0x24,0x27,0x24,0x4,0xfe,0x44,0x54,0xfc,0x44,0xf4,0x44,0xf4,0x54,0x54,0x74,0x44,0x44,0xfc,0x4,
-+0x0,0x43,0x32,0x12,0x82,0x4b,0x48,0x10,0x12,0x22,0xe2,0x22,0x23,0x22,0x24,0x28,0x8,0xfc,0x8,0x8,0x8,0xf8,0x40,0x40,0x48,0x7c,0x40,0x40,0x40,0xc0,0x30,0xe,
-+0x0,0x41,0x31,0x11,0x81,0x48,0x4b,0x12,0x12,0x23,0xe2,0x22,0x23,0x22,0x22,0x22,0x8,0xfc,0x8,0x8,0xf8,0x0,0xfc,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x14,0x8,
-+0x0,0x40,0x34,0x14,0x87,0x40,0x48,0x11,0x12,0x24,0xeb,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x44,0x44,0xfc,0x44,0xa0,0x10,0x4e,0x4,0xf8,0x8,0x10,0x20,0x40,0x80,
-+0x0,0x40,0x33,0x12,0x82,0x43,0x42,0x12,0x12,0x22,0xef,0x20,0x21,0x22,0x24,0x28,0x8,0x1c,0xe0,0x0,0x0,0xfc,0x10,0x10,0x10,0x14,0xfe,0x0,0x20,0x10,0xc,0x4,
-+0x2,0x41,0x30,0x11,0x82,0x40,0x4f,0x11,0x12,0x27,0xea,0x22,0x22,0x22,0x20,0x0,0x8,0xb0,0x40,0xb0,0x48,0x80,0xfe,0x40,0x48,0xfc,0x48,0x48,0x48,0x58,0x40,0x40,
-+0x1,0x41,0x31,0x12,0x84,0x47,0x4c,0x14,0x14,0x27,0xe4,0x20,0x21,0x21,0x22,0x2c,0x0,0x0,0xf8,0x10,0x24,0xfe,0x44,0x44,0x44,0xfc,0xa4,0xa0,0x20,0x22,0x22,0x1e,
-+0x0,0x44,0x37,0x14,0x88,0x43,0x48,0x10,0x17,0x21,0xe1,0x21,0x21,0x22,0x24,0x28,0x80,0x40,0xfe,0x2,0x24,0xf0,0x0,0x8,0xfc,0x20,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x0,0x40,0x27,0x10,0x80,0x4f,0x48,0x10,0x13,0x22,0xe6,0x2b,0x32,0x22,0x23,0x22,0x80,0x88,0xf8,0x90,0xa4,0xfe,0x40,0x88,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x2,0x42,0x37,0x12,0x82,0x4b,0x4a,0x12,0x13,0x22,0xe2,0x3f,0x20,0x22,0x24,0x28,0x10,0x10,0xfc,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,0x14,0xfe,0x0,0x10,0xc,0x4,
-+0x2,0x42,0x32,0x12,0x8f,0x42,0x56,0x17,0x2a,0x2a,0xf2,0x22,0x22,0x22,0x23,0x22,0x0,0xc,0x70,0x40,0xc0,0x44,0x7e,0x48,0xc8,0x48,0x48,0x48,0x88,0x88,0x8,0x8,
-+0x2,0x42,0x32,0x12,0x8f,0x42,0x56,0x17,0x2a,0x2a,0xf2,0x22,0x22,0x22,0x22,0x22,0x0,0x10,0x50,0x50,0xd0,0x48,0x88,0x26,0xa0,0x20,0x40,0x48,0x44,0xfc,0x4,0x0,
-+0x0,0x40,0x37,0x10,0x80,0x4f,0x41,0x10,0x12,0x21,0xe0,0x2f,0x20,0x20,0x21,0x26,0x40,0x48,0xfc,0x40,0x40,0xfe,0x22,0xa4,0x60,0x20,0xa4,0xfe,0x40,0x50,0x8c,0x4,
-+0x0,0x4f,0x30,0x11,0x86,0x40,0x55,0x12,0x16,0x29,0xe2,0x24,0x28,0x20,0x21,0x20,0x4,0xfe,0x80,0x0,0x88,0xd0,0x60,0x60,0xd0,0x50,0x48,0x4e,0x44,0x40,0x40,0x80,
-+0x0,0x47,0x34,0x14,0x87,0x54,0x54,0x17,0x10,0x2f,0xe1,0x21,0x21,0x22,0x24,0x28,0x4,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x0,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x0,0x43,0x32,0x12,0x83,0x48,0x4f,0x14,0x14,0x27,0xe4,0x24,0x27,0x20,0x20,0x20,0x8,0xfc,0x8,0x8,0xf8,0x40,0xfc,0x44,0x44,0xfc,0x44,0x44,0xfc,0x40,0x42,0x3e,
-+0x0,0x40,0x30,0x11,0x82,0x4d,0x48,0x10,0x17,0x20,0xe2,0x21,0x21,0x20,0x2f,0x20,0x40,0x40,0xa0,0x10,0xe,0xf4,0x40,0x48,0xfc,0x40,0x44,0x48,0x50,0x40,0xfe,0x0,
-+0x0,0x4f,0x29,0x29,0x89,0x4f,0x59,0x19,0x29,0x2f,0xe9,0x29,0x29,0x29,0x2b,0x10,0x4,0x7e,0x54,0x54,0x54,0x54,0x54,0x54,0x7c,0x44,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x0,0x40,0x37,0x14,0x88,0x43,0x48,0x10,0x17,0x20,0xe1,0x22,0x24,0x28,0x21,0x20,0x80,0x40,0xfe,0x2,0x14,0xf8,0x0,0x4,0xfe,0x40,0x50,0x48,0x44,0x44,0x40,0x80,
-+0x0,0x40,0x37,0x14,0x88,0x47,0x44,0x14,0x17,0x24,0xe4,0x27,0x24,0x20,0x20,0x20,0x80,0x40,0xfe,0x42,0x40,0xfc,0x44,0x44,0xfc,0x44,0x44,0xfc,0x44,0x40,0x40,0x40,
-+0x0,0x40,0x37,0x14,0x88,0x43,0x4a,0x12,0x13,0x22,0xe3,0x22,0x22,0x22,0x23,0x22,0x80,0x40,0xfe,0x2,0x4,0xf8,0x8,0x8,0xf8,0x0,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x0,0x43,0x30,0x10,0x83,0x48,0x48,0x17,0x10,0x24,0xe2,0x21,0x22,0x2c,0x21,0x20,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xfe,0x40,0x44,0xe8,0x50,0x48,0x4e,0x44,0x80,
-+0x0,0x47,0x34,0x14,0x87,0x45,0x4d,0x17,0x15,0x2d,0xed,0x35,0x25,0x25,0x21,0x21,0x44,0xe4,0x44,0x54,0xd4,0x14,0x54,0xf4,0x54,0x54,0x54,0x54,0x44,0xc4,0x14,0x8,
-+0x0,0x42,0x32,0x17,0x82,0x4a,0x4a,0x12,0x13,0x20,0xe7,0x20,0x21,0x22,0x2c,0x20,0x90,0x90,0x94,0xfe,0x90,0x90,0xf0,0x0,0xfc,0x40,0xfc,0xe0,0x50,0x4e,0x44,0x40,
-+0x0,0x47,0x30,0x10,0x87,0x44,0x4c,0x14,0x17,0x24,0xe0,0x27,0x20,0x20,0x2f,0x20,0x4,0xfe,0xa0,0xa4,0xfe,0xa4,0xa4,0xa4,0xfc,0x44,0x40,0xfc,0x40,0x44,0xfe,0x0,
-+0x0,0x40,0x37,0x10,0x81,0x4f,0x49,0x19,0x19,0x29,0xe9,0x29,0x29,0x29,0x2f,0x28,0x0,0x4,0xfe,0x80,0x4,0xfe,0x24,0x24,0xe4,0x24,0x24,0xe4,0x24,0x24,0xfc,0x4,
-+0x0,0x41,0x36,0x12,0x82,0x5f,0x42,0x16,0x17,0x2a,0xea,0x32,0x22,0x22,0x22,0x23,0x10,0x90,0x10,0x10,0x92,0xd4,0x38,0x10,0x10,0x90,0x28,0x28,0x48,0x48,0x84,0x2,
-+0x0,0x41,0x36,0x14,0x87,0x44,0x4c,0x17,0x10,0x27,0xe2,0x21,0x20,0x20,0x23,0x2c,0x40,0x44,0x5e,0x44,0x5c,0x44,0x44,0xfc,0x40,0xfc,0x8,0x10,0xe0,0xa0,0x10,0xe,
-+0x0,0x41,0x33,0x12,0x83,0x4a,0x4b,0x10,0x17,0x20,0xe0,0x27,0x20,0x20,0x2f,0x20,0x80,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfc,0x40,0x48,0xfc,0x40,0x44,0xfe,0x0,
-+0x2,0x42,0x35,0x14,0x88,0x57,0x42,0x12,0x1f,0x22,0xe7,0x2a,0x32,0x22,0x2a,0x24,0x0,0x0,0x4,0xfe,0x44,0x44,0x44,0x28,0xa8,0x28,0x10,0x90,0x28,0x28,0x44,0x82,
-+0x0,0x41,0x31,0x12,0x87,0x49,0x41,0x12,0x14,0x27,0xe5,0x25,0x25,0x25,0x3f,0x20,0x20,0x20,0x20,0x10,0xfe,0x14,0x10,0x50,0x20,0xf8,0x28,0x28,0x28,0x28,0xfe,0x0,
-+0x4,0x42,0x31,0x1f,0x80,0x47,0x44,0x14,0x17,0x24,0xe4,0x27,0x24,0x24,0x25,0x24,0x8,0x10,0x24,0xfe,0x0,0x88,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0x88,0x88,0xa8,0x90,
-+0x0,0x40,0x37,0x14,0x89,0x40,0x4b,0x12,0x12,0x23,0xe2,0x22,0x23,0x20,0x2f,0x20,0x80,0x40,0xfe,0x2,0xf4,0x0,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x0,0xfe,0x0,
-+0x0,0x47,0x34,0x14,0x87,0x4c,0x4d,0x14,0x14,0x25,0xe4,0x25,0x28,0x28,0x33,0x20,0x4,0xfe,0x4,0x4,0xfc,0x0,0xfc,0x40,0x88,0xfc,0x20,0xfc,0x20,0x24,0xfe,0x0,
-+0x0,0x47,0x34,0x14,0x87,0x44,0x4d,0x15,0x15,0x25,0xe5,0x25,0x25,0x29,0x29,0x31,0x4,0xfe,0x44,0x44,0xfc,0x0,0xfc,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x4,0xfc,
-+0x2,0x42,0x22,0x2f,0x82,0x42,0x4f,0x12,0x12,0x22,0xef,0x22,0x22,0x22,0x22,0x22,0x20,0x20,0x3c,0x48,0x94,0x7e,0xd4,0x54,0x54,0x54,0xfc,0x40,0x42,0x42,0x3e,0x0,
-+0x0,0x40,0x37,0x10,0x87,0x40,0x4f,0x11,0x12,0x25,0xe8,0x23,0x20,0x21,0x26,0x20,0x40,0x44,0xfe,0x40,0xfc,0x80,0xfe,0x10,0x8,0xfe,0x44,0xf8,0xe0,0x50,0x4c,0x40,
-+0x0,0x40,0x37,0x10,0x80,0x4f,0x48,0x11,0x13,0x20,0xe7,0x24,0x24,0x24,0x2f,0x20,0x40,0x48,0xfc,0x40,0x44,0xfe,0x80,0x10,0xf8,0x0,0xfc,0xa4,0xa4,0xa4,0xfe,0x0,
-+0x0,0x4f,0x32,0x13,0x82,0x4b,0x4a,0x1f,0x10,0x2f,0xe8,0x25,0x22,0x25,0x28,0x30,0x8,0xfc,0x10,0xf0,0x10,0xf0,0x14,0xfe,0x10,0xfc,0x84,0x28,0x10,0x28,0xc6,0x84,
-+0x1,0x41,0x3f,0x11,0x80,0x4f,0x40,0x11,0x12,0x2d,0xe1,0x27,0x21,0x21,0x22,0x24,0x10,0x10,0xfe,0x10,0x48,0xfe,0xa0,0x10,0xe,0x14,0x10,0xfc,0x10,0x10,0x10,0x10,
-+0x1,0x41,0x3f,0x11,0x8f,0x48,0x48,0x17,0x10,0x20,0xe3,0x20,0x20,0x20,0x2f,0x20,0x10,0x14,0xfe,0x10,0xfe,0x2,0x4,0xfc,0x40,0x50,0xf8,0x40,0x50,0x48,0xfe,0x0,
-+0x0,0x40,0x37,0x10,0x87,0x44,0x4f,0x14,0x17,0x24,0xe0,0x2f,0x21,0x20,0x20,0x20,0x50,0x48,0xfe,0x40,0xfc,0x44,0xfc,0x44,0xfc,0x44,0x40,0xfe,0x8,0x88,0x28,0x10,
-+0x0,0x47,0x30,0x10,0x87,0x44,0x44,0x17,0x10,0x20,0xef,0x20,0x21,0x22,0x2c,0x20,0x4,0xfe,0xa0,0xa4,0xfe,0xa4,0xa4,0xfc,0x40,0x44,0xfe,0xe0,0x50,0x4e,0x44,0x40,
-+0x0,0x47,0x34,0x15,0x84,0x47,0x4d,0x15,0x15,0x29,0xe0,0x2f,0x22,0x21,0x20,0x20,0x8,0xfc,0x0,0xf8,0x0,0xfc,0x44,0x28,0x90,0xe,0x10,0xfe,0x10,0x10,0x50,0x20,
-+0x0,0x47,0x34,0x17,0x84,0x4f,0x48,0x17,0x10,0x24,0xe3,0x22,0x24,0x20,0x22,0x21,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x4,0xbe,0x84,0xa4,0x9c,0x94,0xa4,0x84,0x94,0x8,
-+0x0,0x47,0x34,0x17,0x84,0x45,0x4e,0x14,0x17,0x24,0xe7,0x24,0x25,0x24,0x27,0x24,0x4,0xfe,0x4,0xfc,0x84,0x8c,0x54,0xe4,0x44,0xe4,0x5c,0x4c,0x44,0x84,0xfc,0x4,
-+0x2,0x42,0x33,0x15,0x88,0x40,0x4f,0x10,0x17,0x20,0xe0,0x2f,0x20,0x20,0x20,0x20,0x20,0x24,0xbe,0x50,0x88,0x3c,0xc0,0x90,0xf8,0x80,0x84,0xfe,0x80,0x84,0x84,0x7c,
-+0x0,0x41,0x37,0x14,0x87,0x44,0x47,0x14,0x17,0x20,0xe0,0x3f,0x21,0x21,0x22,0x2c,0x80,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0xf8,0xa0,0x94,0xfe,0x40,0x20,0x10,0xe,
-+0x1,0x42,0x35,0x10,0x80,0x49,0x4e,0x13,0x10,0x20,0xe7,0x22,0x21,0x20,0x2f,0x20,0x10,0xc,0x14,0xa0,0x40,0xb0,0xe,0xf8,0x40,0x40,0xfc,0x48,0x50,0x44,0xfe,0x0,
-+0x0,0x40,0x37,0x14,0x85,0x44,0x57,0x14,0x25,0x24,0xe5,0x25,0x25,0x29,0x29,0x31,0x40,0x24,0xfe,0x20,0xfc,0x24,0xfe,0x24,0xfc,0x20,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x40,0x37,0x11,0x80,0x4f,0x48,0x10,0x1f,0x21,0xe1,0x21,0x21,0x21,0x22,0x24,0x80,0x48,0xfc,0x10,0xa0,0xfe,0x82,0x44,0xfe,0x10,0xf8,0x10,0x10,0x10,0x50,0x20,
-+0x0,0x4f,0x28,0x10,0x83,0x4a,0x4b,0x12,0x13,0x20,0xe0,0x2f,0x20,0x21,0x22,0x24,0x0,0xfe,0x2,0x4,0xf8,0x8,0xf8,0x8,0xf8,0x80,0x44,0xfe,0x0,0x10,0xc,0x4,
-+0x1,0x41,0x37,0x11,0x81,0x4f,0x48,0x17,0x14,0x27,0xe4,0x27,0x24,0x21,0x22,0x24,0x10,0x10,0xfc,0x10,0x14,0xfe,0x40,0xfc,0x44,0xfc,0x44,0xfc,0x4,0x10,0xc,0x4,
-+0x1,0x41,0x2f,0x11,0x87,0x44,0x49,0x13,0x10,0x21,0xe7,0x20,0x22,0x24,0x29,0x20,0x10,0x14,0xfe,0x10,0xfe,0x82,0x14,0xe0,0x80,0x8,0xfc,0x44,0x50,0x4c,0x44,0x80,
-+0x1,0x4f,0x31,0x10,0x87,0x40,0x4f,0x10,0x17,0x20,0xe4,0x25,0x25,0x26,0x28,0x30,0x10,0xfe,0x10,0x40,0xfc,0x44,0xfe,0x44,0xfc,0x40,0x44,0x64,0x54,0x54,0x44,0x44,
-+0x2,0x42,0x2f,0x12,0x87,0x4a,0x52,0x12,0x10,0x2f,0xe1,0x22,0x21,0x20,0x23,0x2c,0x10,0x10,0xfc,0x10,0x38,0xd4,0x12,0x90,0x84,0xfe,0x10,0x10,0x20,0xc0,0x30,0x8,
-+0x1,0x41,0x3f,0x11,0x8f,0x49,0x4f,0x19,0x2f,0x20,0xe7,0x24,0x27,0x24,0x27,0x24,0x20,0x24,0xfe,0x20,0xfc,0x24,0xfc,0x24,0xfc,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x8,
-+0x0,0x40,0x30,0x17,0x84,0x45,0x44,0x14,0x14,0x25,0xe5,0x24,0x2b,0x28,0x30,0x20,0x48,0x7c,0x40,0xfe,0x44,0xf0,0x44,0x3c,0x8,0xf0,0x24,0xa8,0xfe,0x20,0xa0,0x40,
-+0x0,0x47,0x34,0x17,0x84,0x47,0x44,0x11,0x17,0x20,0xe1,0x27,0x22,0x24,0x29,0x20,0x4,0xfe,0x44,0xfc,0x44,0xfc,0x84,0x8,0xf0,0x80,0x8,0xfc,0x50,0x4c,0x44,0x80,
-+0x0,0x40,0x37,0x14,0x84,0x47,0x40,0x17,0x14,0x24,0xe7,0x20,0x2a,0x2a,0x32,0x21,0x40,0x44,0xfe,0x44,0x44,0xfc,0x40,0xfc,0x44,0x44,0xfc,0x40,0x88,0x46,0xa,0xf8,
-+0x2,0x42,0x35,0x14,0x88,0x57,0x40,0x1a,0x1a,0x2a,0xea,0x21,0x23,0x3c,0x28,0x21,0x10,0x10,0x10,0xa4,0x7e,0xa4,0x24,0xa4,0xa8,0xa8,0x90,0x10,0xa8,0x28,0x44,0x82,
-+0x0,0x48,0x25,0x12,0x86,0x4a,0x4b,0x12,0x16,0x2b,0xf2,0x22,0x22,0x22,0x2a,0x24,0x20,0xa0,0x24,0xfc,0x28,0x30,0xfe,0x40,0xfc,0x44,0x44,0x7c,0x44,0x44,0x7c,0x44,
-+0x1,0x49,0x25,0x12,0x86,0x4a,0x53,0x12,0x26,0x2a,0xf2,0x22,0x22,0x22,0x2a,0x24,0x20,0x28,0xfc,0x20,0x50,0x88,0xfe,0x4,0xf4,0x94,0x94,0x94,0xf4,0x4,0x14,0x8,
-+0x0,0x40,0x37,0x14,0x84,0x4f,0x4c,0x14,0x17,0x25,0xe5,0x25,0x29,0x29,0x31,0x21,0x80,0x44,0xfe,0xa0,0xa4,0xfe,0xa4,0xa4,0xfc,0x20,0x24,0xe8,0x30,0x62,0xa2,0x1e,
-+0x4,0x42,0x32,0x1f,0x84,0x44,0x4f,0x15,0x15,0x25,0xe5,0x29,0x29,0x2d,0x32,0x21,0x20,0x20,0x24,0xfe,0x80,0x0,0x7e,0x12,0x14,0x50,0x5c,0x50,0x50,0x70,0x98,0x6,
-+0x0,0x47,0x30,0x11,0x8f,0x44,0x4c,0x17,0x14,0x24,0xe7,0x24,0x24,0x3f,0x20,0x20,0x10,0x90,0x90,0x24,0xfe,0xa4,0xa4,0xa4,0xa8,0xa8,0x90,0x90,0xa8,0xa8,0xc4,0x82,
-+0x2,0x42,0x2f,0x22,0x8f,0x50,0x1f,0x28,0x28,0x4f,0xc0,0x48,0x45,0x5f,0x40,0x40,0x8,0x88,0xc8,0x8,0xbe,0x8,0x88,0xa8,0x98,0x88,0x8,0x88,0x8,0xc8,0x28,0x10,
-+0x9,0x49,0x29,0x1f,0x89,0x49,0x5f,0x19,0x2f,0x29,0xe9,0x3f,0x24,0x29,0x30,0x21,0x0,0xc,0x70,0xc0,0x40,0x44,0x7e,0x48,0x48,0x48,0x48,0xc8,0x48,0x48,0x88,0x8,
-+0x2,0x42,0x2f,0x12,0x87,0x4a,0x42,0x17,0x14,0x27,0xe4,0x24,0x27,0x24,0x24,0x24,0x10,0x10,0xfc,0x10,0x38,0xd6,0x10,0xf8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x28,0x10,
-+0x0,0x41,0x2e,0x12,0x82,0x5f,0x42,0x16,0x17,0x2a,0xea,0x32,0x22,0x22,0x22,0x22,0x10,0x90,0x54,0x38,0x10,0xfc,0x44,0x44,0x7c,0xc4,0x44,0x7c,0x44,0x44,0x54,0x48,
-+0x0,0x47,0x31,0x10,0x8f,0x40,0x47,0x14,0x17,0x24,0xe7,0x20,0x27,0x20,0x2f,0x20,0x40,0xfc,0x10,0xa4,0xfe,0x0,0xfc,0x44,0xfc,0x44,0xfc,0x40,0xfc,0x40,0xfe,0x0,
-+0x7,0x44,0x37,0x14,0x85,0x44,0x4f,0x14,0x14,0x27,0xe4,0x25,0x2b,0x29,0x31,0x23,0xfc,0x4,0xfc,0x0,0xf8,0x10,0xfe,0x20,0x64,0xde,0x84,0x8,0xfe,0x8,0x8,0x18,
-+0x4,0x44,0x3f,0x24,0x84,0x5f,0x15,0x55,0x5f,0x44,0xcc,0x4e,0x55,0x64,0x44,0x44,0x20,0x20,0x7c,0x88,0x10,0x7c,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x28,0x46,0x82,
-+0x0,0x40,0x2f,0x29,0x89,0x49,0x5f,0x19,0x29,0x2f,0xe9,0x29,0x29,0x2f,0x29,0x20,0x20,0x30,0x48,0x7e,0xc8,0x48,0x7e,0x48,0x48,0x7e,0x48,0x48,0x48,0x7e,0x40,0x40,
-+0x0,0x40,0x37,0x14,0x87,0x44,0x57,0x10,0x27,0x20,0xe3,0x22,0x23,0x21,0x20,0x2f,0xa0,0xa4,0xfe,0xa4,0xfc,0xa4,0xfc,0x0,0xfc,0x0,0xf8,0x8,0xf8,0x10,0xa0,0xfe,
-+0x0,0x41,0x32,0x17,0x84,0x45,0x57,0x14,0x25,0x24,0xe5,0x24,0x29,0x29,0x31,0x21,0x80,0xf0,0x24,0xfe,0x88,0x24,0xfe,0x0,0xfc,0x0,0xfc,0x0,0xfc,0x4,0x4,0xfc,
-+0x0,0x4f,0x20,0x27,0x85,0x45,0x45,0x17,0x10,0x23,0xe2,0x23,0x22,0x23,0x20,0x2f,0x40,0xfe,0x0,0xfc,0x14,0xf4,0x14,0xfc,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xfe,
-+0x0,0x40,0x37,0x15,0x87,0x4c,0x4f,0x14,0x17,0x24,0xe7,0x24,0x29,0x2a,0x34,0x20,0x40,0x24,0xfe,0x8,0xfc,0x90,0xfc,0x94,0xfe,0x94,0xfc,0x90,0x98,0x94,0x92,0x90,
-+0x0,0x47,0x20,0x2f,0x88,0x53,0x40,0x13,0x10,0x2f,0xe0,0x27,0x24,0x24,0x24,0x24,0x8,0xfc,0x40,0xfe,0x42,0x58,0x40,0x58,0x40,0xfe,0x80,0xfc,0xa4,0xa4,0xa4,0xc,
-+0x2,0x43,0x22,0x24,0x8f,0x54,0x44,0x17,0x14,0x25,0xe4,0x27,0x24,0x24,0x24,0x27,0x50,0x54,0xd8,0x50,0xfe,0x88,0x50,0xfe,0x20,0xfc,0x20,0xfe,0x20,0x50,0x8e,0x4,
-+0x0,0x43,0x32,0x12,0x83,0x48,0x4f,0x14,0x17,0x24,0xe7,0x20,0x2f,0x21,0x21,0x22,0x80,0xf8,0x88,0x48,0xf8,0x0,0xfc,0x44,0xfc,0x44,0xfc,0x0,0xfe,0x10,0x10,0x10,
-+0x0,0x4f,0x30,0x13,0x82,0x4f,0x48,0x13,0x10,0x23,0xec,0x23,0x2c,0x23,0x2d,0x20,0x40,0xfe,0x0,0xf8,0x8,0xfe,0x2,0xfc,0x80,0x48,0x50,0x60,0xd0,0x4e,0x44,0x80,
-+0x0,0x4f,0x34,0x12,0x82,0x44,0x41,0x11,0x13,0x26,0xeb,0x22,0x23,0x22,0x23,0x22,0x0,0xbc,0xa4,0x94,0x94,0xa4,0x0,0x24,0xfe,0x20,0xfc,0x20,0xfc,0x20,0xfe,0x0,
-+0x4,0x44,0x3f,0x4,0x9f,0x51,0x11,0x3f,0x51,0x51,0xdf,0x44,0x7f,0x44,0x44,0x44,0x10,0x10,0xa8,0x28,0x44,0x82,0xfc,0x24,0xb4,0x6c,0x6c,0xb4,0x24,0x24,0xb4,0x48,
-+0x2,0x43,0x32,0x17,0x84,0x4a,0x41,0x12,0x17,0x20,0xe7,0x20,0x27,0x20,0x2f,0x20,0x0,0xbc,0x24,0xa8,0x90,0xa8,0x46,0xa0,0xbc,0xa0,0xbc,0xa0,0xbc,0xa0,0xfe,0x0,
-+0x0,0x5f,0x24,0x27,0x80,0x47,0x4c,0x17,0x10,0x2e,0xeb,0x2e,0x2b,0x2f,0x2a,0x37,0x80,0xfe,0x0,0xf8,0x0,0xf8,0x8,0xf8,0x80,0x9c,0xf4,0x9c,0x54,0x54,0x96,0x62,
-+0x0,0x41,0x22,0x24,0x8b,0x50,0x4f,0x19,0x2f,0x20,0xef,0x29,0x29,0x2f,0x29,0x28,0x80,0x40,0x20,0x10,0xee,0x4,0xfc,0x24,0xfc,0x0,0xfc,0x24,0x24,0xfc,0x24,0xc,
-+0x0,0x42,0x2f,0x21,0x82,0x4f,0x44,0x17,0x14,0x27,0xe1,0x27,0x21,0x2f,0x22,0x24,0x40,0x48,0xfe,0x50,0x48,0xfe,0x44,0xfc,0x44,0xfc,0x10,0xfc,0x10,0xfe,0x8,0x4,
-+0x40,0x3f,0x31,0x9f,0x51,0x5f,0x4,0x3f,0x20,0x5f,0xd1,0x5f,0x44,0x55,0x64,0x4c,0x4,0x7e,0x10,0x24,0x7e,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x20,0x28,0x46,0x82,
-+0x47,0x20,0x2f,0xa,0x95,0x4f,0x45,0x17,0x12,0x2f,0xea,0x2f,0x22,0x3f,0x22,0x22,0xfc,0x40,0xfe,0x4a,0x40,0xbc,0x24,0x24,0x3c,0xa4,0xa4,0xbc,0x24,0xe4,0x54,0x88,
-+0x0,0x0,0x0,0x2,0x1,0x1,0x7f,0x40,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xfe,0x2,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x2,0x1,0x7f,0x42,0x82,0x2,0x3f,0x2,0x2,0x2,0x4,0x4,0x8,0x10,0x20,0x40,0x0,0x0,0xfe,0x2,0x4,0x20,0xf0,0x20,0x20,0x20,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x2,0x1,0x7f,0x40,0x80,0xff,0x4,0x4,0x8,0xf,0x18,0x28,0x48,0x8,0xf,0x8,0x0,0x0,0xfe,0x2,0x4,0xfe,0x0,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0xf0,0x10,
-+0x2,0x1,0x7f,0x40,0x82,0x1,0x9,0x8,0x28,0x28,0x29,0x4a,0xc,0x18,0x67,0x0,0x0,0x0,0xfe,0x2,0x4,0x10,0x10,0x20,0x48,0x84,0x4,0x4,0x10,0x10,0xf0,0x0,
-+0x2,0x1,0x7f,0x42,0x82,0xff,0x4,0xf,0x18,0x2f,0xc8,0xf,0x8,0x8,0x8,0x8,0x0,0x0,0xfe,0x2,0x4,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0x10,0x50,0x20,
-+0x2,0x1,0x7f,0x40,0x9f,0x10,0x17,0x10,0x1f,0x15,0x25,0x24,0x24,0x45,0x86,0x4,0x0,0x0,0xfe,0x2,0xf4,0x0,0xe0,0x8,0xfc,0x0,0x10,0xa0,0x40,0x30,0xe,0x4,
-+0x2,0x1,0x7f,0x42,0xa9,0x28,0x47,0x0,0x3f,0x21,0x3f,0x21,0x3f,0x21,0x21,0x21,0x0,0x0,0xfe,0x2,0x14,0x28,0xe4,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x8,0x28,0x10,
-+0x1,0x7f,0x44,0x9f,0x4,0x1f,0x4,0xff,0x8,0x1f,0xe4,0x4,0x7,0x0,0x3f,0x0,0x0,0xfe,0x42,0xf4,0x40,0xf0,0x44,0xfe,0x20,0xd0,0x4e,0x40,0xf8,0x8,0xe8,0x10,
-+0x1,0x7f,0x44,0x9f,0x4,0x1f,0x4,0xff,0x8,0x17,0x21,0xcf,0x1,0x3f,0x1,0x3,0x0,0xfe,0x42,0xf4,0x40,0xf0,0x44,0xfe,0x20,0xd0,0xe,0xe4,0x0,0xf8,0x0,0x0,
-+0x2,0x1,0x7f,0x40,0xa5,0x24,0x25,0x3c,0x4,0xff,0x24,0x25,0x25,0x25,0x45,0x5,0x0,0x0,0xfe,0x2,0xfc,0x40,0xf8,0x88,0x88,0xfe,0x0,0xfc,0x4,0x4,0xfc,0x4,
-+0x1,0x7f,0x41,0xbf,0x1,0xa,0x4,0x1f,0x30,0xdf,0x10,0x1f,0x9,0x11,0x25,0x2,0x0,0xfe,0x2,0xf8,0x0,0xa0,0x40,0xf0,0x1e,0xf4,0x10,0xf0,0x20,0x18,0x8,0x0,
-+0x1,0x7f,0x44,0x9f,0x4,0x1f,0x4,0xff,0x9,0x1f,0x22,0xc4,0xc,0x35,0x6,0x4,0x0,0xfe,0x42,0xf4,0x40,0xf0,0x44,0xfe,0x20,0xf0,0x1e,0xa4,0x40,0x20,0x1c,0x8,
-+0x1,0x7f,0x40,0xbf,0x24,0x3f,0x0,0xff,0x0,0x1f,0x10,0x1f,0x4,0xc,0x75,0x6,0x0,0xfe,0x2,0xfc,0x48,0xf8,0x0,0xfe,0x0,0xf0,0x10,0xf0,0x88,0x50,0x20,0x1c,
-+0x1,0x7f,0x44,0x9f,0x4,0x1f,0x4,0xff,0x8,0x1f,0x28,0xcf,0x9,0xd,0x13,0x20,0x0,0xfe,0x42,0xf4,0x40,0xf0,0x44,0xfe,0x20,0xf0,0x2e,0xe4,0x0,0xe0,0x0,0xf8,
-+0x1,0x7f,0x44,0x9f,0x4,0x1f,0x4,0xff,0x9,0x1f,0x27,0xc0,0xf,0x8,0x8,0xf,0x0,0xfe,0x42,0xf4,0x40,0xf0,0x44,0xfe,0x20,0xf0,0x8,0xe6,0xe0,0x20,0x20,0xe0,
-+0x0,0x40,0x30,0x10,0x0,0x0,0xf0,0x10,0x10,0x10,0x10,0x10,0x10,0x28,0x47,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x6,0xfc,0x0,
-+0x0,0x40,0x37,0x10,0x2,0x2,0xf7,0x10,0x10,0x10,0x11,0x12,0x14,0x28,0x47,0x0,0x0,0x8,0xfc,0x10,0x10,0x14,0xfe,0x50,0x50,0x90,0x10,0x10,0x50,0x26,0xfc,0x0,
-+0x1,0x41,0x31,0x12,0x4,0x0,0xf0,0x1f,0x10,0x10,0x10,0x10,0x10,0x28,0x47,0x0,0x0,0x8,0xfc,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x46,0xfc,0x0,
-+0x0,0x40,0x27,0x24,0x4,0x5,0xe5,0x25,0x25,0x25,0x25,0x24,0x24,0x50,0x8f,0x0,0x0,0x8,0xfc,0x8,0x8,0xe8,0x28,0x28,0x28,0xe8,0x28,0x8,0x18,0x6,0xfc,0x0,
-+0x1,0x41,0x31,0x11,0x2,0x4,0xf0,0x10,0x10,0x10,0x10,0x10,0x10,0x28,0x47,0x0,0x0,0x0,0x8,0xfc,0x80,0x90,0xf8,0x80,0x90,0xf8,0x80,0x80,0x80,0x86,0xfc,0x0,
-+0x2,0x42,0x33,0x14,0x8,0x2,0xf3,0x16,0x12,0x12,0x12,0x11,0x10,0x28,0x47,0x0,0x0,0x8,0xfc,0x40,0x48,0x7c,0xc8,0x48,0x68,0x50,0x4,0xfc,0x0,0x6,0xfc,0x0,
-+0x1,0x41,0x21,0x21,0x2,0x4,0xf0,0x11,0x11,0x12,0x14,0x11,0x20,0x48,0x87,0x0,0x0,0x0,0x8,0xfc,0x8,0x10,0x40,0x50,0x48,0x44,0x44,0x40,0x80,0x6,0xfc,0x0,
-+0x4,0x44,0x2f,0x24,0x4,0x4,0xe4,0x24,0x24,0x24,0x28,0x32,0x21,0x50,0x8f,0x0,0x0,0x4,0xbe,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xbc,0x20,0x6,0xfc,0x0,
-+0x0,0x43,0x30,0x10,0x1,0x6,0xf0,0x13,0x10,0x10,0x10,0x17,0x10,0x28,0x47,0x0,0x0,0xf8,0x10,0x60,0x98,0x4,0x10,0xf8,0x40,0x40,0x48,0xfc,0x0,0x6,0xfc,0x0,
-+0x0,0x40,0x31,0x12,0x4,0x7,0xf0,0x13,0x12,0x12,0x12,0x13,0x12,0x28,0x47,0x0,0x80,0x80,0x10,0x8,0x4,0xfc,0x0,0xf8,0x8,0x8,0x8,0xf8,0x8,0x6,0xfc,0x0,
-+0x0,0x40,0x27,0x24,0x4,0x7,0xe4,0x24,0x25,0x29,0x29,0x31,0x21,0x50,0x8f,0x0,0x0,0x18,0xe0,0x0,0x8,0xfc,0x0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x6,0xfc,0x0,
-+0x1,0x41,0x31,0x12,0x4,0x1,0xf6,0x10,0x13,0x12,0x12,0x17,0x10,0x28,0x47,0x0,0x0,0xf8,0x10,0xa0,0x40,0xb0,0x4e,0x40,0xf8,0x40,0x48,0xfc,0x40,0x46,0xfc,0x0,
-+0x0,0x40,0x2f,0x20,0xf,0x8,0xe8,0x2f,0x28,0x28,0x2f,0x28,0x28,0x50,0x8f,0x0,0xa0,0x90,0xfc,0x80,0xf8,0x88,0x88,0xf8,0x88,0x88,0xf8,0x88,0x98,0x6,0xfc,0x0,
-+0x0,0x4f,0x30,0x17,0x4,0x4,0xf6,0x15,0x14,0x14,0x14,0x15,0x14,0x28,0x47,0x0,0x4,0xfe,0x0,0xbc,0xa4,0xa4,0xb4,0xac,0xa4,0xa4,0xa4,0xac,0xa4,0x2,0xfc,0x0,
-+0x0,0x40,0x30,0x17,0x0,0x2,0xf1,0x10,0x11,0x16,0x10,0x11,0x10,0x28,0x47,0x0,0x40,0x50,0x48,0xfc,0x40,0x48,0x50,0x40,0x50,0x4c,0x44,0x40,0x80,0x6,0xfc,0x0,
-+0x0,0x42,0x31,0x10,0x3,0x2,0xf2,0x13,0x12,0x12,0x13,0x12,0x12,0x28,0x47,0x0,0x40,0x48,0x50,0x40,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x18,0x6,0xfc,0x0,
-+0x0,0x48,0x25,0x22,0x5,0x9,0xe3,0x25,0x29,0x31,0x21,0x25,0x22,0x50,0x8f,0x0,0x10,0x90,0x10,0x10,0x52,0x54,0x58,0x90,0x28,0x28,0x28,0x44,0x82,0x6,0xfc,0x0,
-+0x0,0x41,0x32,0x17,0x1,0x2,0xf5,0x11,0x11,0x12,0x14,0x10,0x13,0x28,0x47,0x0,0x80,0x10,0x8,0xfc,0x10,0xc,0x4,0xf0,0x10,0xa0,0x40,0xa0,0x1c,0x6,0xfc,0x0,
-+0x0,0x40,0x37,0x10,0x0,0xf,0xf1,0x16,0x10,0x17,0x10,0x10,0x17,0x28,0x47,0x0,0x40,0x48,0xfc,0x40,0x44,0xfe,0x10,0x4c,0x40,0xfc,0x40,0x44,0xfe,0x0,0xfe,0x0,
-+0x0,0x43,0x30,0x17,0x0,0x1,0xf6,0x10,0x1f,0x11,0x13,0x10,0x11,0x2a,0x47,0x0,0x18,0xe0,0x48,0xfc,0xe0,0x50,0x4e,0x84,0xfe,0x10,0x10,0xe0,0x10,0x8,0xfe,0x0,
-+0x0,0x40,0x2f,0x28,0x13,0x2,0xe2,0x23,0x22,0x23,0x22,0x22,0x23,0x52,0x8f,0x0,0x80,0x40,0xfe,0x2,0xf4,0x10,0x10,0xf0,0x0,0xf8,0x8,0x8,0xf8,0x6,0xfc,0x0,
-+0x0,0x47,0x20,0x13,0x0,0xf,0xf0,0x12,0x11,0x11,0x12,0x14,0x11,0x28,0x47,0x0,0x8,0xfc,0x8,0xf8,0x8,0xfe,0x40,0x44,0x68,0x50,0x48,0x44,0x40,0x86,0xfc,0x0,
-+0x0,0x42,0x32,0x12,0x3,0x0,0xf7,0x10,0x17,0x14,0x14,0x14,0x14,0x28,0x47,0x0,0x40,0x48,0x48,0x48,0xf8,0x0,0xfe,0x80,0xfc,0xa4,0xa4,0xa4,0xac,0x2,0xfc,0x0,
-+0x0,0x40,0x33,0x12,0x3,0x2,0xf3,0x10,0x17,0x10,0x13,0x10,0x17,0x28,0x47,0x0,0x40,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xfc,0x40,0xf8,0x40,0xfc,0x0,0xfe,0x0,
-+0x1,0x40,0x37,0x10,0x7,0x4,0xf4,0x14,0x15,0x16,0x15,0x14,0x17,0x28,0x47,0x0,0x10,0xa4,0xfe,0xa0,0xfc,0xa4,0xa4,0xa4,0x1c,0x4,0xf4,0x4,0xfc,0x0,0xfe,0x0,
-+0x0,0x47,0x34,0x14,0x7,0x4,0xf4,0x17,0x14,0x14,0x17,0x14,0x14,0x28,0x47,0x0,0x4,0xbe,0x84,0x84,0xbc,0x4,0x0,0x7c,0x44,0x44,0xa8,0x10,0x28,0x44,0xfe,0x0,
-+0x2,0x42,0x2f,0x22,0xf,0x2,0xff,0x24,0x27,0x24,0x24,0x28,0x29,0x50,0x8f,0x0,0x10,0x10,0x94,0x3e,0xa4,0x44,0xe4,0x14,0x94,0x88,0x94,0x94,0xa2,0x42,0xfe,0x0,
-+0x1,0x47,0x31,0x17,0x1,0xf,0xf0,0x13,0x12,0x13,0x12,0x1f,0x12,0x2a,0x47,0x0,0x10,0xfc,0x10,0xfc,0x10,0xfe,0x40,0xf8,0x48,0xf8,0x48,0xfe,0x8,0x18,0xfe,0x0,
-+0x3,0x42,0x33,0x12,0x3,0x0,0xf7,0x10,0x14,0x12,0x12,0x14,0x11,0x28,0x47,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xbc,0x84,0xa4,0x94,0x94,0xa4,0x8c,0x86,0xfc,0x0,
-+0x1,0x46,0x34,0x15,0x6,0x4,0xf3,0x12,0x12,0x13,0x12,0x12,0x13,0x28,0x47,0x0,0x4,0xfe,0x24,0x24,0x54,0x88,0xf8,0x48,0x48,0xf8,0x48,0x48,0xf8,0x6,0xfc,0x0,
-+0x7,0x44,0x27,0x24,0x7,0x2,0xe7,0x2c,0x37,0x24,0x27,0x24,0x27,0x54,0x8f,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x40,0xfc,0x40,0xf8,0x40,0xf8,0x40,0xfc,0x0,0xfe,0x0,
-+0x0,0x42,0x31,0x17,0x0,0x1,0xf6,0x12,0x13,0x14,0x1a,0x11,0x12,0x2c,0x47,0x0,0x40,0x48,0x50,0xfc,0xe0,0x50,0x4c,0x8,0xfe,0xa8,0xa8,0x3e,0x8,0x8,0xfe,0x0,
-+0x0,0x40,0x20,0x27,0x4,0x7,0xe4,0x25,0x26,0x25,0x2a,0x28,0x33,0x50,0x8f,0x0,0x48,0x7c,0x40,0xfc,0x84,0xf0,0x84,0x78,0xa0,0x30,0x68,0xa4,0x24,0x60,0xfe,0x0,
-+0x4,0x47,0x29,0x32,0xf,0xa,0xea,0x2f,0x2a,0x2a,0x2f,0x2a,0x2a,0x51,0x8f,0x0,0x4,0xfe,0x24,0x24,0xac,0xc4,0xa8,0xbe,0xc8,0x88,0xfe,0x88,0x88,0x88,0xfe,0x0,
-+0x0,0x43,0x3c,0x2a,0x5,0x6,0xeb,0x25,0x39,0x23,0x25,0x39,0x25,0x52,0x8f,0x0,0x90,0x24,0xfe,0xc4,0x44,0x7c,0x44,0x44,0x7c,0x28,0x28,0x2a,0x4e,0x80,0xfe,0x0,
-+0x0,0x40,0x2f,0x29,0x12,0x1,0xef,0x21,0x2e,0x21,0x2e,0x21,0x2e,0x50,0x8f,0x0,0x80,0x40,0xfe,0x12,0xc,0x10,0xfc,0x88,0x50,0xe0,0x50,0xce,0x40,0xc6,0xfc,0x0,
-+0x2,0x44,0x22,0x2f,0x9,0x8,0xe9,0x2f,0x24,0x26,0x24,0x26,0x24,0x56,0x88,0x7,0x48,0x90,0x48,0xfc,0x24,0xc4,0x24,0xfc,0x90,0xd0,0x90,0xd4,0x94,0xdc,0x0,0xfe,
-+0x0,0x0,0x0,0x7f,0x0,0x0,0x0,0x3f,0x0,0x0,0x0,0x0,0x7f,0x0,0x0,0x0,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,
-+0x10,0x14,0xfe,0x10,0x7c,0x10,0xfe,0x10,0x7f,0x0,0x0,0x3f,0x0,0x0,0x7f,0x0,0x10,0x14,0xfe,0x10,0x7c,0x10,0xfe,0x10,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x4,0x7,0x8,0x1f,0x0,0xff,0x2,0x5,0x19,0x62,0x4,0x19,0x62,0xc,0x72,0x1,0x0,0xf0,0x10,0xe0,0x44,0xfe,0x8,0x10,0xa0,0xc0,0xa0,0x90,0x8e,0x84,0x80,0x0,
-+0x4,0x7,0x8,0x1f,0x0,0xff,0x2,0x22,0x27,0x39,0x21,0x2f,0x29,0x32,0x24,0x8,0x0,0xf0,0x20,0xe0,0x44,0xfe,0x0,0x20,0xe4,0x28,0x30,0xe0,0x22,0xa2,0x5e,0x0,
-+0x0,0x3f,0x20,0x20,0x3f,0x22,0x22,0x22,0x3f,0x22,0x22,0x22,0x44,0x44,0x88,0x10,0x8,0xfc,0x8,0x8,0xf8,0x8,0x0,0x20,0xf0,0x20,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x2,0x3f,0x22,0x22,0x22,0x22,0x3e,0x28,0x28,0x24,0x24,0x22,0x41,0x40,0x80,0x0,0x4,0x7e,0x44,0x44,0x44,0x44,0x7c,0x0,0x28,0x24,0x46,0x82,0x80,0x60,0x1e,0x4,
-+0x0,0x3f,0x20,0x3f,0x22,0x24,0x29,0x32,0x24,0x2d,0x34,0x24,0x44,0x44,0x84,0x5,0x4,0xfe,0x4,0xfc,0x20,0x28,0xfc,0x20,0x20,0xf8,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x0,0x3f,0x20,0x3f,0x20,0x2f,0x2a,0x2a,0x2c,0x2a,0x2a,0x2e,0x4a,0x48,0x88,0x8,0x4,0xfe,0x4,0xfc,0x0,0xfe,0x8,0xe8,0xa8,0xa8,0xa8,0xa8,0xe8,0x8,0x28,0x10,
-+0x3f,0x20,0x3f,0x20,0x27,0x20,0x2f,0x20,0x21,0x3f,0x22,0x24,0x5f,0x44,0x84,0xc,0xfc,0x4,0xfc,0x0,0xe0,0x48,0xfc,0x80,0x80,0x7c,0x8,0x10,0x7e,0x10,0x10,0x30,
-+0x0,0x3f,0x20,0x3f,0x22,0x24,0x28,0x32,0x25,0x2c,0x34,0x24,0x44,0x45,0x86,0x4,0x4,0xfe,0x4,0xfc,0x20,0xbc,0xa0,0xa8,0xfc,0x20,0xa8,0xbc,0xa0,0x60,0x3e,0x0,
-+0x0,0x3f,0x20,0x3f,0x22,0x24,0x28,0x33,0x24,0x2d,0x34,0x27,0x44,0x44,0x84,0x5,0x4,0xfe,0x4,0xfc,0x20,0xa8,0x20,0xfc,0xa8,0x24,0x40,0xfe,0x88,0x70,0x48,0x84,
-+0x3f,0x20,0x3f,0x22,0x2f,0x20,0x27,0x20,0x3f,0x2a,0x3f,0x24,0x5f,0x44,0xbf,0x4,0xfc,0x4,0xfc,0x20,0xf8,0x80,0xf0,0x80,0xfc,0xa8,0x7c,0x10,0x7c,0x10,0xfe,0x10,
-+0x0,0x7d,0x4,0x4,0x4,0x7c,0x43,0x40,0x41,0x7c,0x4,0x4,0x4,0x4,0x2b,0x10,0x8,0xfc,0x8,0x30,0x58,0x86,0x2,0x8,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x8,0x7e,0x12,0x22,0x1c,0x14,0x62,0x3f,0x0,0x1f,0x10,0x1f,0x0,0x0,0x0,0x0,0x0,0xfc,0x44,0x48,0x30,0x48,0x86,0xf0,0x10,0xf0,0x0,0xf8,0x8,0x8,0x50,0x20,
-+0x0,0x7f,0x5,0x5,0x5,0x7d,0x41,0x41,0x41,0x7d,0x7,0x4,0x4,0x4,0x28,0x10,0x4,0xfe,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0xfe,0x8,0x8,0x8,0x8,0x8,
-+0x14,0x14,0x7f,0x15,0x15,0x7f,0x54,0x54,0x54,0x7f,0x15,0x15,0x15,0x27,0x24,0x44,0x20,0x20,0x3c,0x48,0x90,0x7c,0x54,0x54,0x54,0x7c,0x44,0x40,0x42,0x42,0x3e,0x0,
-+0x0,0xf0,0x1f,0x12,0x12,0x77,0x44,0x44,0x44,0x77,0x14,0x14,0x14,0x17,0xa4,0x40,0x4,0xbe,0xc4,0x4,0x4,0xbc,0xa0,0xa0,0xa4,0xbe,0x84,0x84,0x84,0x84,0xa8,0x10,
-+0x79,0xd,0x79,0x47,0x79,0xd,0x31,0xff,0x0,0xf,0x8,0x3f,0x24,0x2f,0x21,0x21,0x3c,0x44,0x3c,0xe0,0x3c,0x44,0x18,0xfe,0x0,0xe0,0x20,0xf8,0x48,0xe8,0x8,0x18,
-+0x1,0x11,0x11,0x11,0x11,0x1f,0x11,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x10,0x10,0x10,0x10,0xf0,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x10,0x10,0x10,0xfd,0x26,0x24,0x24,0x24,0x44,0x28,0x10,0x28,0x44,0x84,0x0,0x80,0x80,0x84,0xfe,0x4,0x4,0x4,0x84,0x44,0x44,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x10,0x10,0x11,0x10,0xfc,0x24,0x25,0x25,0x25,0x45,0x29,0x11,0x29,0x45,0x84,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x17,0x10,0x10,0xfc,0x24,0x24,0x27,0x24,0x44,0x28,0x10,0x28,0x44,0x81,0x2,0x4,0xfe,0x88,0x88,0x88,0x88,0x88,0xfe,0x88,0x88,0x88,0x88,0x88,0x88,0x8,0x8,
-+0x10,0x11,0x10,0x10,0xfc,0x24,0x27,0x24,0x24,0x44,0x28,0x10,0x28,0x45,0x82,0x4,0x8,0xfc,0x40,0x40,0x40,0x44,0xfe,0x50,0x50,0x50,0x90,0x90,0x92,0x12,0xe,0x0,
-+0x10,0x11,0x11,0x11,0xfd,0x25,0x25,0x25,0x25,0x45,0x29,0x11,0x29,0x45,0x85,0x0,0x4,0xfe,0x0,0x4,0x84,0x48,0x28,0x10,0x10,0x28,0x44,0x84,0x0,0x4,0xfe,0x0,
-+0x11,0x11,0x11,0x11,0xfd,0x25,0x25,0x25,0x25,0x45,0x29,0x11,0x29,0x45,0x85,0x0,0x20,0x20,0x20,0x24,0x2c,0xf0,0x20,0x20,0x20,0x20,0x20,0x20,0x62,0xa2,0x1e,0x0,
-+0x10,0x10,0x10,0x10,0xfd,0x25,0x26,0x24,0x24,0x45,0x28,0x10,0x28,0x44,0x84,0x0,0x40,0x40,0xa0,0xa0,0x10,0xe,0x44,0x20,0x0,0xf8,0x8,0x10,0x10,0x20,0x40,0x80,
-+0x10,0x10,0x10,0x11,0xfd,0x25,0x25,0x25,0x24,0x44,0x28,0x10,0x29,0x46,0x80,0x0,0x20,0x28,0x3c,0xe0,0x20,0x20,0x20,0xfe,0x22,0x62,0x6a,0xa4,0x20,0x20,0x20,0x20,
-+0x10,0x12,0x11,0x11,0xfc,0x27,0x24,0x24,0x24,0x44,0x28,0x10,0x29,0x45,0x82,0x4,0x40,0x40,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0xa4,0x94,0x4,0x4,0x28,0x10,
-+0x10,0x13,0x10,0x10,0xfc,0x24,0x24,0x25,0x24,0x44,0x28,0x10,0x28,0x44,0x87,0x0,0x8,0xfc,0x88,0x88,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x88,0x88,0x88,0xfe,0x0,
-+0x10,0x11,0x10,0x10,0xfc,0x24,0x27,0x24,0x24,0x44,0x28,0x10,0x28,0x44,0x84,0x0,0x0,0xf8,0x8,0x50,0x20,0x20,0xfe,0x22,0x24,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x10,0x10,0x11,0x11,0xfd,0x25,0x25,0x25,0x25,0x45,0x29,0x11,0x29,0x44,0x84,0x0,0x0,0x8,0x48,0x28,0x28,0x28,0x8,0x8,0x8,0x8,0x48,0x90,0x10,0x28,0x46,0x82,
-+0x10,0x11,0x11,0x11,0xfd,0x25,0x25,0x25,0x25,0x45,0x29,0x11,0x28,0x44,0x87,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0xf8,0x0,0x4,0xfe,0x0,
-+0x10,0x10,0x10,0x10,0xfd,0x25,0x25,0x25,0x25,0x45,0x29,0x11,0x29,0x45,0x85,0x1,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0x24,0xfc,0x4,
-+0x10,0x11,0x11,0x11,0xfd,0x25,0x25,0x27,0x25,0x45,0x29,0x11,0x29,0x45,0x82,0x4,0x4,0xde,0x54,0x54,0x54,0x54,0x54,0xfe,0x54,0x54,0x54,0x54,0x54,0x54,0xec,0x44,
-+0x2,0x1,0x7f,0x0,0x8,0x4,0xff,0x1,0x2,0xff,0x4,0x8,0x6,0x1,0x6,0x38,0x0,0x8,0xfc,0x0,0x20,0x44,0xfe,0x0,0x4,0xfe,0x20,0x20,0x40,0x80,0x60,0x18,
-+0x10,0x10,0x17,0x10,0xfc,0x24,0x24,0x26,0x25,0x44,0x28,0x10,0x28,0x44,0x87,0x0,0x0,0x4,0xfe,0x90,0x90,0x90,0x92,0x94,0x98,0x90,0x90,0x90,0x90,0x94,0xfe,0x0,
-+0x10,0x10,0x10,0x13,0xfc,0x24,0x24,0x27,0x24,0x47,0x28,0x10,0x28,0x44,0x81,0x6,0x40,0x40,0x5c,0xe0,0x48,0x52,0x62,0x9e,0x0,0xf8,0x90,0x90,0x90,0x92,0x12,0xe,
-+0x10,0x11,0x11,0x11,0xfd,0x26,0x24,0x27,0x24,0x44,0x28,0x10,0x29,0x46,0x84,0x0,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x70,0xa8,0xa8,0x24,0x22,0x20,0x20,
-+0x2,0x1,0x7f,0x4,0x14,0x24,0x44,0x5,0x2,0xff,0x4,0x8,0x6,0x1,0x6,0x38,0x0,0x8,0xfc,0x40,0x50,0x4c,0x44,0x40,0x4,0xfe,0x20,0x20,0x40,0x80,0x60,0x18,
-+0x10,0x10,0x10,0x13,0xfc,0x24,0x25,0x26,0x24,0x44,0x28,0x10,0x28,0x44,0x81,0x6,0x40,0x20,0x4,0xfe,0x0,0x88,0x6,0x8a,0x88,0x50,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x11,0x10,0x10,0x13,0xfc,0x24,0x24,0x24,0x27,0x44,0x28,0x10,0x28,0x44,0x81,0x2,0x4,0x88,0x0,0xfe,0x88,0x88,0x88,0x88,0xfe,0x88,0x88,0x88,0x88,0x88,0x8,0x8,
-+0x10,0x10,0x13,0x12,0xfc,0x24,0x25,0x24,0x24,0x47,0x28,0x10,0x28,0x44,0x84,0x0,0x40,0x20,0xfe,0x2,0x4,0x38,0xc0,0x40,0x44,0xfe,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x10,0x10,0x11,0x11,0xfd,0x25,0x25,0x25,0x25,0x44,0x28,0x11,0x28,0x44,0x87,0x0,0x0,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0x28,0xfc,0x20,0x24,0xfe,0x0,
-+0x10,0x10,0x11,0x11,0xfd,0x25,0x25,0x24,0x27,0x44,0x28,0x10,0x28,0x44,0x84,0x0,0x20,0x24,0xfe,0x24,0xfc,0x24,0xfc,0x0,0xfe,0x80,0xfc,0x4,0x4,0x44,0x28,0x10,
-+0x10,0x11,0x11,0x11,0xfd,0x25,0x25,0x24,0x27,0x4a,0x2a,0x12,0x2a,0x46,0x82,0x2,0x4,0xfe,0x4,0x4,0x4,0xfc,0x24,0x20,0xfe,0x22,0x22,0x52,0x8a,0x2,0xa,0x4,
-+0x11,0x10,0x10,0x11,0xfd,0x25,0x25,0x25,0x25,0x45,0x29,0x11,0x29,0x45,0x85,0x1,0x4,0xbe,0x84,0x24,0x24,0x24,0xfc,0x24,0x74,0x6c,0xac,0x24,0x24,0x4,0x14,0x8,
-+0x10,0x8,0x41,0x25,0x9,0x72,0x10,0x17,0x1,0xff,0x4,0x8,0x6,0x1,0x6,0x38,0x40,0x40,0x50,0x4c,0x44,0x50,0xe0,0x0,0x4,0xfe,0x20,0x20,0x40,0x80,0x60,0x18,
-+0x10,0x10,0x10,0x11,0xfc,0x24,0x25,0x25,0x25,0x45,0x28,0x10,0x28,0x45,0x82,0x0,0x88,0x48,0x10,0xfc,0x24,0x24,0xfc,0x20,0x20,0xfe,0x62,0x62,0xaa,0x24,0x20,0x20,
-+0x10,0x11,0x11,0x11,0xfd,0x25,0x25,0x25,0x25,0x45,0x29,0x11,0x29,0x45,0x82,0x4,0x4,0xfe,0x4,0x4,0xfc,0x0,0xc,0xf0,0x20,0xfc,0x20,0xfe,0x20,0x22,0x22,0x1e,
-+0x20,0x27,0x24,0x25,0xf5,0x56,0x55,0x55,0x55,0x95,0x55,0x27,0x25,0x54,0x94,0x4,0x0,0x84,0xfe,0x4,0x4,0x74,0x54,0x54,0x54,0x54,0x54,0x74,0x4,0x4,0x14,0x8,
-+0x10,0x10,0x13,0x10,0xfd,0x24,0x27,0x24,0x25,0x45,0x29,0x11,0x29,0x45,0x85,0x1,0x20,0x24,0xfe,0x20,0xfc,0x20,0xfe,0x0,0xfc,0x4,0xfc,0x4,0xfc,0x4,0x14,0x8,
-+0x10,0x10,0x13,0x10,0xfc,0x25,0x24,0x24,0x27,0x44,0x28,0x11,0x2a,0x44,0x80,0x0,0x20,0x24,0xfe,0x20,0x20,0xfc,0x20,0x24,0xfe,0x40,0xa4,0xa8,0x90,0x88,0xc6,0x80,
-+0x20,0x20,0x27,0x20,0xfb,0x48,0x4f,0x48,0x4b,0x90,0x52,0x22,0x23,0x52,0x84,0x8,0x40,0x48,0xfc,0x40,0xf8,0x48,0xfe,0x48,0xf8,0x40,0x48,0x7c,0x40,0xc0,0x60,0x1e,
-+0x10,0x11,0x11,0x11,0xfd,0x25,0x25,0x24,0x27,0x4a,0x2a,0x13,0x2a,0x46,0x83,0x2,0x8,0xfc,0x8,0xf8,0x8,0x8,0xf8,0x4,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x11,0x11,0xfd,0x25,0x25,0x25,0x25,0x44,0x28,0x13,0x28,0x44,0x80,0x0,0x20,0x44,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x50,0x94,0xfe,0x10,0x10,0x10,0x10,
-+0x11,0x10,0x10,0x11,0xfd,0x25,0x25,0x25,0x25,0x45,0x28,0x13,0x28,0x44,0x84,0x0,0x4,0x88,0x50,0xfc,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0xfe,0x20,0x20,0x20,0x20,
-+0x10,0x10,0xfe,0x12,0x34,0xc,0x32,0xc1,0x3f,0x21,0x22,0x24,0x21,0x22,0x24,0x20,0x0,0x0,0xfc,0x8,0x50,0x20,0xd8,0x6,0xf8,0x8,0x88,0x48,0x8,0x88,0x48,0x18,
-+0x20,0x23,0x22,0x22,0xfb,0x4a,0x4a,0x4b,0x48,0x97,0x54,0x24,0x24,0x54,0x8f,0x0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x0,0xfc,0xa4,0xa4,0xa4,0xa4,0xfe,0x0,
-+0x10,0x10,0x13,0x11,0xfc,0x25,0x24,0x27,0x24,0x44,0x28,0x11,0x2a,0x44,0x84,0x3,0x8,0x1c,0xe0,0x24,0xa8,0xfc,0x40,0xfe,0x80,0xfc,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x10,0x10,0x13,0x10,0xfd,0x25,0x25,0x24,0x27,0x4a,0x29,0x10,0x28,0x44,0x84,0x0,0x40,0x24,0xfe,0x0,0xfc,0x4,0xfc,0x0,0xfe,0x2,0xfc,0x20,0x20,0x20,0xa0,0x40,
-+0x0,0x7f,0x12,0xc,0x7f,0x15,0x24,0x4c,0x2,0xff,0x4,0x8,0x4,0x3,0x4,0x38,0x40,0x44,0x7e,0x88,0x50,0x20,0x50,0x8e,0x4,0xfe,0x20,0x20,0x40,0x80,0x60,0x10,
-+0x10,0x10,0x13,0x10,0xfd,0x24,0x27,0x24,0x25,0x45,0x29,0x11,0x2b,0x45,0x85,0x1,0x88,0x88,0xfe,0x88,0xfc,0x88,0xfe,0x20,0xfc,0x24,0xfc,0x24,0xfe,0x4,0x14,0x8,
-+0x10,0x10,0x13,0x10,0xfc,0x25,0x25,0x25,0x25,0x45,0x28,0x13,0x28,0x44,0x84,0x3,0x88,0x88,0xfe,0x88,0x88,0xfc,0x4,0xfc,0x4,0xfc,0x20,0xfe,0x20,0x50,0x8e,0x4,
-+0x10,0x10,0x11,0x11,0xfd,0x25,0x25,0x25,0x25,0x45,0x29,0x11,0x29,0x45,0x81,0x0,0x20,0x44,0xfe,0x54,0x24,0x54,0x4,0xfc,0x10,0x12,0xd4,0x18,0x12,0x52,0x8e,0x0,
-+0x20,0x23,0x21,0x20,0xfb,0x4a,0x4c,0x4b,0x48,0x88,0x51,0x22,0x24,0x50,0x88,0x3,0x1c,0xe0,0x24,0xa8,0xfe,0x42,0x44,0xfe,0x80,0x80,0xfc,0x88,0x50,0x20,0xd8,0x6,
-+0x10,0x10,0x13,0x12,0xfc,0x24,0x24,0x24,0x24,0x44,0x28,0x13,0x28,0x44,0x85,0x2,0x40,0x20,0xfe,0x2,0x1c,0xe0,0x80,0xfc,0x88,0x88,0x88,0xfe,0x0,0x88,0x6,0x2,
-+0x10,0x11,0x11,0x11,0xfc,0x27,0x24,0x24,0x25,0x45,0x29,0x11,0x28,0x44,0x85,0x0,0x20,0x24,0x24,0xfc,0x20,0xfe,0x0,0x24,0xfe,0x24,0x24,0xfc,0x20,0x24,0xfe,0x2,
-+0x4,0x3f,0x4,0x7f,0xe,0x15,0x24,0x3f,0x21,0x21,0x3f,0x22,0x26,0x41,0x46,0x98,0x20,0x24,0x3e,0xe8,0x10,0x28,0x44,0xfe,0x0,0x4,0xfe,0x10,0x20,0xc0,0x30,0x8,
-+0x20,0x23,0x20,0x21,0xf9,0x4f,0x49,0x49,0x49,0x89,0x51,0x20,0x22,0x52,0x88,0x0,0x8,0xfc,0x20,0x3c,0x20,0xfe,0x0,0x8,0xfc,0x0,0xfe,0x2,0xaa,0xaa,0x2,0xc,
-+0x10,0x10,0x11,0x10,0xfd,0x24,0x27,0x24,0x25,0x45,0x29,0x11,0x29,0x45,0x85,0x1,0x20,0x28,0xfc,0x20,0x24,0xa8,0xfe,0x0,0xfc,0x4,0x74,0x54,0x74,0x4,0xfc,0x4,
-+0x10,0x13,0x10,0x10,0xfd,0x25,0x25,0x25,0x24,0x45,0x28,0x13,0x28,0x45,0x82,0x0,0x4,0xfe,0x50,0x54,0xfe,0x54,0x54,0xfc,0x0,0xfc,0x0,0xfe,0xa8,0x24,0x22,0x20,
-+0x10,0x11,0x10,0x13,0xfe,0x24,0x24,0x24,0x24,0x44,0x29,0x11,0x29,0x45,0x84,0x0,0x20,0x24,0xa8,0xfe,0x2,0xfc,0x88,0x88,0xf8,0x20,0xfc,0x24,0x24,0x2c,0x20,0x20,
-+0x10,0x11,0x11,0x11,0xfd,0x25,0x24,0x24,0x25,0x44,0x28,0x11,0x28,0x45,0x86,0x0,0x4,0xfe,0x24,0xfc,0x24,0xfc,0x40,0x84,0xf8,0x20,0x48,0xfc,0xa8,0x26,0x22,0x60,
-+0x10,0x11,0x10,0x10,0xff,0x24,0x25,0x25,0x25,0x45,0x29,0x10,0x2b,0x44,0x84,0x0,0x20,0xfc,0x88,0x50,0xfe,0x0,0xfc,0x4,0xfc,0x4,0xfc,0x20,0xfe,0x20,0x20,0x20,
-+0x10,0x13,0x10,0x11,0xfc,0x25,0x25,0x25,0x24,0x47,0x28,0x11,0x29,0x45,0x85,0x1,0x20,0xfe,0x20,0xfc,0x0,0xfc,0x4,0xfc,0x88,0xfe,0x0,0xfc,0x4,0x4,0xfc,0x4,
-+0x10,0x13,0x10,0x11,0xfd,0x25,0x25,0x25,0x24,0x45,0x29,0x11,0x29,0x45,0x84,0x3,0x20,0xfe,0x0,0xfc,0x54,0x74,0x54,0xfc,0x0,0xfc,0x4,0xfc,0x4,0xfc,0x0,0xfe,
-+0x0,0x3e,0x23,0x3e,0x20,0x3f,0x52,0x52,0x9e,0x1,0xff,0x4,0xc,0x3,0x4,0x18,0x40,0x20,0xfc,0x88,0x50,0xfc,0x20,0xf8,0x20,0x20,0xfe,0x20,0x40,0x80,0x60,0x10,
-+0x2,0xfa,0xaa,0xaa,0xff,0xaa,0xaa,0xfa,0x22,0xfa,0x2a,0x2a,0x49,0x4a,0xac,0x10,0x0,0x3e,0x2a,0xaa,0xfe,0xaa,0xaa,0xbe,0x88,0xbe,0x8a,0x8a,0x12,0x92,0x6a,0x4,
-+0x40,0x40,0x47,0x44,0xf4,0x57,0x54,0x55,0x56,0x94,0x54,0x25,0x24,0x54,0x89,0x10,0x40,0x24,0xfe,0x88,0x88,0xfe,0x88,0xdc,0xaa,0x40,0x90,0x20,0x48,0x84,0xfc,0x4,
-+0x20,0x21,0x20,0x23,0xfa,0x4c,0x49,0x49,0x4f,0x89,0x53,0x23,0x25,0x55,0x89,0x1,0x8,0xfc,0x20,0xfe,0xaa,0x70,0xa8,0x20,0xfc,0x24,0x3c,0xa4,0x7c,0x24,0x3c,0x24,
-+0x0,0x3f,0x4,0x4,0x4,0x8,0x8,0x11,0x21,0x49,0x89,0x11,0x11,0x21,0x5,0x2,0x0,0xf0,0x10,0x24,0x7e,0x4,0x4,0x14,0x8,0x0,0x20,0x10,0x10,0xc,0x4,0x0,
-+0x1,0x9,0x9,0x11,0x23,0x0,0x1,0xff,0x2,0xc,0x31,0xc9,0x9,0x11,0x25,0x2,0x0,0x20,0x10,0x8,0x8,0x0,0x4,0xfe,0x80,0x60,0x1e,0x24,0x20,0x18,0x8,0x0,
-+0x0,0x0,0x3f,0x0,0x11,0x9,0x3f,0x0,0x0,0x1,0xff,0x1,0x1,0x1,0x5,0x2,0x10,0x78,0x80,0x10,0x10,0x20,0xf0,0x40,0x80,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x10,0xfe,0x12,0x34,0xc,0x32,0xc1,0x1f,0x0,0x1,0xff,0x1,0x1,0x5,0x2,0x0,0x8,0xfc,0x8,0x50,0x20,0xd8,0x6,0xe0,0x40,0x84,0xfe,0x0,0x0,0x0,0x0,
-+0x4,0xff,0x8,0x12,0x3c,0x8,0x14,0x3e,0x0,0x1f,0x0,0x1,0xff,0x1,0x5,0x2,0x40,0xfe,0x20,0x48,0xf0,0x20,0x50,0xf8,0x0,0xe0,0x40,0x84,0xfe,0x0,0x0,0x0,
-+0x0,0x3f,0x0,0x0,0x1,0x1,0x1,0x1,0x7,0x19,0x61,0x1,0x1,0x1,0x5,0x2,0x0,0xf0,0x20,0x40,0x80,0xc,0x30,0xc0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x3f,0x0,0x0,0x11,0x9,0x5,0x3,0x1,0x1,0x1,0x1,0x1,0x1,0x5,0x2,0x0,0xf0,0x20,0x40,0x80,0x0,0x0,0x0,0x0,0x80,0x40,0x30,0xc,0x0,0x0,0x0,
-+0x0,0x0,0xfc,0x5,0xa,0x10,0x13,0x1e,0x32,0xd3,0x12,0x12,0x12,0x12,0x51,0x20,0x80,0x80,0x88,0xfc,0x8,0x8,0xe8,0x28,0x28,0xe8,0x8,0x28,0x12,0x2,0xfe,0x0,
-+0x8,0xfd,0x9,0x49,0x49,0x49,0x49,0x49,0x7d,0x5,0x5,0x1d,0xe5,0x5,0x17,0x8,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0xfe,0x0,
-+0x8,0xfc,0x9,0x49,0x49,0x49,0x49,0x49,0x7d,0x5,0x5,0x1d,0xe5,0x5,0x15,0x8,0x0,0x4,0xfe,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x9c,0x4,0x4,0xfc,0x4,0x0,
-+0x8,0xfc,0x8,0x49,0x49,0x4b,0x4d,0x49,0x7d,0x5,0x5,0x1d,0xe5,0x5,0x15,0x9,0x88,0x88,0x88,0x8,0x8,0xfe,0x8,0x48,0x28,0x28,0x8,0x8,0x8,0x8,0x28,0x10,
-+0x8,0xfc,0x8,0x49,0x4a,0x48,0x4b,0x48,0x7c,0x4,0x5,0x1c,0xe4,0x4,0x17,0x8,0x80,0x80,0xf8,0x8,0x10,0x24,0xfe,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x8,0xfd,0x8,0x48,0x48,0x48,0x48,0x4b,0x7c,0x5,0x4,0x1c,0xe7,0x4,0x14,0x8,0x0,0xfc,0x88,0x50,0x20,0x50,0x8e,0x24,0x20,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,
-+0x10,0x10,0xfe,0x12,0x34,0xc,0x32,0xc1,0x1f,0x0,0x8,0xf,0x0,0x7f,0x0,0x0,0x0,0x0,0xfc,0x8,0x50,0x20,0xd8,0x6,0xe0,0x20,0x24,0xfe,0x4,0xf4,0x14,0x8,
-+0x8,0xfc,0x8,0x48,0x49,0x4b,0x48,0x48,0x7d,0x5,0x5,0x1d,0xe5,0x5,0x15,0x9,0x20,0x20,0x40,0x88,0x4,0xfe,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x8,0xfc,0x8,0x4b,0x48,0x48,0x48,0x4b,0x7c,0x7,0x4,0x1c,0xe4,0x5,0x15,0xa,0x80,0x80,0xbc,0xc0,0x50,0x24,0xd4,0xc,0x0,0xfc,0x90,0x90,0x90,0x12,0x12,0xe,
-+0x8,0xfc,0x9,0x49,0x4b,0x4d,0x49,0x49,0x7d,0x4,0x7,0x1c,0xe4,0x4,0x14,0x8,0xa0,0xa0,0x24,0x28,0x30,0x60,0xa2,0x1e,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x9,0xfc,0x8,0x4b,0x48,0x48,0x48,0x48,0x7f,0x4,0x4,0x1c,0xe4,0x4,0x15,0xa,0x4,0x88,0x50,0xfe,0x88,0x88,0x88,0x88,0xfe,0x88,0x88,0x88,0x88,0x88,0x8,0x8,
-+0x0,0xfb,0x8,0x48,0x49,0x49,0x49,0x49,0x7d,0x5,0x5,0x1d,0xe5,0x5,0x15,0x8,0x4,0xfe,0x0,0x0,0xdc,0x54,0x54,0x54,0xdc,0x54,0x54,0x54,0x54,0x54,0x54,0x0,
-+0x8,0xfc,0xb,0x48,0x48,0x48,0x48,0x48,0x7c,0x4,0x4,0x1f,0xe4,0x4,0x15,0xa,0x88,0x88,0xfe,0x88,0x88,0xf8,0x88,0x88,0xf8,0x88,0x88,0xfe,0x0,0x88,0x6,0x2,
-+0x8,0xfd,0x9,0x49,0x49,0x49,0x49,0x49,0x7c,0x7,0x4,0x1c,0xe5,0x6,0x14,0x8,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0xfe,0x70,0xa8,0x2e,0x24,0x20,0x20,
-+0x8,0xfc,0x9,0x49,0x4b,0x4d,0x49,0x49,0x7d,0x5,0x5,0x1d,0xe5,0x5,0x15,0x9,0xa0,0x90,0x4,0xfe,0x10,0x10,0xfc,0x10,0x10,0xfc,0x10,0x10,0x14,0xfe,0x0,0x0,
-+0x8,0xfc,0x9,0x4b,0x48,0x4f,0x48,0x49,0x7e,0x5,0x4,0x1c,0xe5,0x4,0x14,0xb,0x40,0x80,0x8,0xfc,0x44,0xfe,0x90,0x28,0x46,0x90,0x20,0x44,0x88,0x30,0xc0,0x0,
-+0x0,0x79,0x49,0x57,0x48,0x69,0x56,0x41,0x5f,0x0,0x8,0xf,0x0,0x7f,0x0,0x0,0x40,0x7c,0x40,0xfe,0x48,0x50,0x60,0x80,0xe0,0x20,0x24,0xfe,0x4,0xf4,0x14,0x8,
-+0x0,0xfe,0x14,0x8,0xfe,0x1a,0x28,0x49,0x1f,0x0,0x8,0xf,0x0,0x7f,0x0,0x0,0x80,0x88,0xfc,0x88,0x50,0x20,0xd0,0xe,0xe0,0x20,0x24,0xfe,0x4,0xf4,0x14,0x8,
-+0x8,0x7e,0x8,0x7e,0x8,0xff,0x10,0x3e,0x42,0x9f,0x0,0x8,0xf,0x0,0x7f,0x0,0x40,0x44,0xfe,0x88,0x50,0x20,0x58,0x86,0x0,0xf0,0x10,0x14,0xfe,0x4,0xf4,0x8,
-+0x8,0xff,0xa,0x4a,0x4a,0x4b,0x4a,0x48,0x7d,0x5,0x5,0x1d,0xe5,0x5,0x15,0x9,0x40,0xbe,0x12,0x12,0x92,0x2a,0x44,0x0,0xfc,0x24,0x24,0xfc,0x24,0x24,0xfc,0x4,
-+0x8,0xfc,0x9,0x49,0x49,0x49,0x49,0x49,0x7d,0x5,0x5,0x1d,0xe5,0x5,0x16,0x8,0x20,0x10,0xfe,0x2,0xfe,0x0,0xee,0x22,0x22,0xaa,0x66,0x66,0xaa,0x22,0xaa,0x44,
-+0x8,0xfd,0x8,0x48,0x49,0x49,0x49,0x49,0x7c,0x5,0x4,0x1f,0xe4,0x5,0x16,0x8,0x4,0xfe,0x50,0x54,0xfe,0x54,0x54,0xfc,0x0,0xfc,0x0,0xfe,0xa8,0x26,0x22,0x60,
-+0x8,0xfc,0x9,0x49,0x49,0x49,0x49,0x49,0x7d,0x5,0x4,0x1c,0xe5,0x6,0x14,0x8,0x20,0x44,0xfe,0x44,0x74,0x54,0xb4,0x24,0x44,0xfc,0x0,0xa0,0xa4,0x8a,0x88,0x78,
-+0x13,0xfa,0x13,0x52,0x52,0x52,0x53,0x52,0x7a,0xb,0xa,0x3a,0xcb,0xa,0x2c,0x11,0xfc,0x4,0xfc,0x0,0xf8,0x10,0xfe,0x20,0x60,0xdc,0x44,0x88,0xfe,0x88,0x88,0x98,
-+0x8,0xfd,0x8,0x4b,0x48,0x49,0x49,0x49,0x7d,0x5,0x4,0x1d,0xe4,0x7,0x14,0x9,0x50,0xdc,0x50,0xde,0x0,0xfc,0x24,0xfc,0x24,0xfc,0x88,0xfc,0x88,0xfe,0x88,0x4,
-+0x10,0xff,0x10,0x57,0x54,0x57,0x51,0x53,0x79,0xb,0x9,0x3f,0xc9,0xb,0x2d,0x11,0x40,0xfe,0x0,0xbc,0xa4,0xbc,0x10,0xf8,0x10,0xf8,0x10,0xfe,0x48,0x30,0x8e,0x4,
-+0x8,0x8,0x10,0x12,0x24,0x7c,0x8,0x10,0x20,0x7e,0x20,0x0,0xe,0x70,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x8,0x8,0x10,0x11,0x22,0x7e,0x8,0x13,0x20,0x7e,0x20,0x0,0xe,0x70,0x20,0x0,0x0,0x8,0xfc,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x8,0x8,0x10,0x12,0x24,0x7d,0x8,0x10,0x20,0x7e,0x20,0x0,0xe,0x70,0x20,0x0,0x8,0x8,0x8,0x8,0x8,0xfe,0x8,0x8,0x88,0x48,0x48,0x8,0x8,0x8,0x28,0x10,
-+0x8,0x8,0x10,0x12,0x25,0x7c,0x9,0x10,0x20,0x7e,0x20,0x0,0xf,0x71,0x20,0x0,0x80,0x80,0x84,0xfe,0x0,0x0,0xf8,0x8,0x10,0x20,0x40,0x80,0x2,0x2,0xfe,0x0,
-+0x8,0x8,0x10,0x12,0x25,0x7c,0x8,0x11,0x20,0x7e,0x20,0x0,0xe,0x71,0x21,0x2,0x40,0x40,0x40,0x48,0xfc,0x48,0x48,0x48,0xc8,0x48,0xa8,0x88,0x8a,0xa,0xa,0x4,
-+0x8,0x8,0x10,0x13,0x25,0x7d,0x9,0x11,0x21,0x7d,0x21,0x1,0xe,0x72,0x24,0x8,0x40,0x20,0x24,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x8,0x8,0x11,0x12,0x24,0x7c,0xb,0x10,0x20,0x7e,0x20,0x0,0xe,0x71,0x21,0x0,0x0,0x8,0xfc,0x0,0x0,0x4,0xfe,0x40,0x40,0x40,0x80,0x80,0x88,0x4,0xfc,0x4,
-+0x9,0x9,0x11,0x13,0x25,0x7d,0x9,0x11,0x21,0x7f,0x21,0x1,0xf,0x71,0x21,0x0,0x20,0x20,0x20,0x20,0x24,0x2c,0xf0,0x20,0x20,0x20,0x20,0x20,0x62,0xa2,0x1e,0x0,
-+0x8,0x9,0x10,0x10,0x24,0x7c,0x9,0x10,0x20,0x7e,0x20,0x0,0xe,0x70,0x20,0x0,0x8,0xfc,0x8,0x50,0x20,0x10,0xfe,0x22,0x24,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x8,0x8,0x10,0x12,0x27,0x7c,0x8,0x10,0x20,0x7e,0x20,0x0,0xe,0x70,0x20,0x0,0x88,0x88,0x88,0x88,0xfe,0x88,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x88,0xf8,0x88,
-+0x10,0x11,0x21,0x25,0x49,0xff,0x11,0x21,0x41,0xfd,0x41,0x1,0x1d,0xe1,0x41,0x0,0x48,0x48,0x48,0x48,0x48,0xfe,0x48,0x48,0x48,0x48,0x48,0x78,0x0,0x0,0xfc,0x0,
-+0x10,0x10,0x20,0x24,0x4f,0xf8,0x10,0x21,0x41,0xfd,0x42,0x2,0x1c,0xe4,0x48,0x13,0xa0,0x90,0x90,0x84,0xfe,0x80,0x80,0xf8,0x8,0x8,0x90,0x60,0x20,0x50,0x8e,0x4,
-+0x10,0x10,0x20,0x25,0x4a,0xf8,0x13,0x20,0x40,0xfc,0x41,0x0,0x1c,0xe0,0x43,0x0,0x80,0x80,0xf8,0x8,0x10,0x24,0xfe,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x20,0x27,0x48,0xf8,0x13,0x22,0x46,0xfb,0x40,0x0,0x1c,0xe1,0x41,0x2,0x90,0x90,0x94,0xfe,0x94,0x94,0xfc,0x90,0x90,0xfe,0x92,0x92,0x9a,0x14,0x10,0x10,
-+0x8,0x8,0x11,0x11,0x25,0x7d,0x9,0x10,0x21,0x7d,0x21,0x1,0xd,0x71,0x20,0x0,0x20,0x20,0x24,0x24,0x24,0x24,0xfc,0x20,0x24,0x24,0x24,0x24,0x24,0xfc,0x4,0x0,
-+0x10,0x10,0x20,0x20,0x48,0xf9,0x13,0x20,0x40,0xfd,0x41,0x1,0x1d,0xe1,0x41,0x1,0x20,0x20,0x40,0x40,0x88,0x4,0xfe,0x2,0x0,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x27,0x24,0x48,0xf9,0x13,0x24,0x43,0xfd,0x41,0x0,0x1c,0xe0,0x40,0x0,0x40,0x44,0xfe,0xa0,0xa0,0x10,0xf8,0x6,0xfc,0x0,0xf8,0x8,0x8,0x88,0x50,0x20,
-+0x10,0x10,0x21,0x25,0x7f,0xf8,0x11,0x23,0x45,0xf9,0x41,0x1,0x1d,0xe1,0x41,0x1,0x80,0x88,0x7c,0x0,0xff,0x84,0xfe,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x28,0x10,
-+0x11,0x11,0x23,0x24,0x40,0xf8,0x11,0x26,0x43,0xfa,0x42,0x7,0x18,0xe0,0x40,0x0,0x0,0xf8,0x10,0xa0,0x40,0xa0,0x58,0x46,0xf8,0x40,0x48,0xfc,0x40,0x40,0x40,0x40,
-+0x10,0x17,0x20,0x23,0x4a,0xfa,0x13,0x22,0x42,0xfb,0x42,0x1,0x18,0xe1,0x42,0x4,0x4,0xfe,0x40,0xf8,0x48,0x48,0xf8,0x48,0x48,0xf8,0x40,0x40,0x80,0x60,0x1e,0x4,
-+0x8,0x9,0x10,0x10,0x24,0x7d,0x9,0x11,0x21,0x7f,0x21,0x1,0xf,0x71,0x21,0x1,0x20,0x24,0xa8,0xb0,0x24,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x4,0x14,0x8,
-+0x12,0x11,0x20,0x27,0x48,0xf8,0x13,0x22,0x42,0xfb,0x40,0x4,0x19,0xe2,0x44,0x8,0x8,0x10,0xa0,0xf8,0x48,0x48,0xf8,0x40,0x44,0xfe,0xc4,0xc4,0x54,0x48,0x40,0x40,
-+0x10,0x10,0x21,0x24,0x48,0xfb,0x10,0x21,0x42,0xfc,0x40,0x1,0x1c,0xe0,0x41,0x6,0x20,0x28,0xfc,0x20,0x24,0xfe,0x88,0x46,0x7a,0x88,0x90,0x50,0x20,0x50,0x8e,0x4,
-+0x10,0x10,0x27,0x20,0x48,0xf9,0x17,0x20,0x43,0xfa,0x42,0x2,0x1b,0xe2,0x40,0x0,0x40,0x48,0xfc,0x40,0xb0,0x14,0xfe,0x8,0xc8,0x48,0x48,0x48,0xc8,0x8,0x28,0x10,
-+0x10,0x10,0x20,0x23,0x48,0xf8,0x10,0x23,0x40,0xfc,0x40,0x3,0x1c,0xe0,0x40,0x0,0x50,0x50,0x54,0xde,0x50,0x50,0x54,0xde,0x50,0x50,0x54,0xde,0x50,0x50,0x50,0x50,
-+0x10,0x12,0x21,0x21,0x48,0xff,0x14,0x24,0x45,0xfd,0x45,0x5,0x1d,0xe4,0x44,0x4,0x40,0x48,0x48,0x50,0x44,0xfe,0x4,0x4,0xf4,0x14,0x14,0x14,0xf4,0x4,0x14,0x8,
-+0x8,0x9,0x11,0x13,0x25,0x7d,0x9,0x11,0x20,0x7d,0x21,0x1,0xd,0x71,0x21,0x1,0x4,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x10,0x12,0x16,0xd8,0x10,0x52,0x92,0xe,
-+0x10,0x13,0x20,0x2f,0x49,0xf9,0x11,0x27,0x41,0xf9,0x41,0x7,0x18,0xe0,0x47,0x0,0x18,0xe0,0x44,0xfe,0x50,0x50,0x50,0xfc,0x50,0x50,0x54,0xfe,0x40,0x48,0xfc,0x0,
-+0x10,0x17,0x20,0x22,0x41,0xf7,0x14,0x28,0x41,0xfc,0x41,0x0,0x1c,0xe0,0x41,0x6,0x1c,0xe0,0x0,0x48,0x50,0xfe,0x2,0x4,0xf0,0x10,0x10,0xa0,0x40,0xa0,0x1e,0x4,
-+0x11,0x11,0x21,0x25,0x4a,0xfb,0x14,0x21,0x42,0xfc,0x41,0x1,0x1d,0xe1,0x41,0x1,0x10,0x10,0xd0,0x58,0x56,0x52,0x90,0x50,0x3e,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x12,0x21,0x20,0x47,0xf8,0x1f,0x20,0x41,0xfb,0x45,0x1,0x1d,0xe1,0x41,0x0,0x40,0x48,0x50,0x40,0xfc,0x40,0xfe,0xa0,0x10,0xfe,0x14,0x10,0x50,0x24,0x4,0xfc,
-+0x10,0x10,0x24,0x27,0x4c,0xf3,0x12,0x22,0x43,0xfe,0x43,0x2,0x1e,0xe2,0x43,0x2,0x80,0x40,0x40,0xfe,0x2,0xf8,0x8,0x8,0xf8,0x0,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x11,0x11,0x22,0x24,0x4a,0xf9,0x11,0x20,0x47,0xfc,0x44,0x7,0x1c,0xe4,0x47,0x4,0x24,0x24,0x48,0x90,0x48,0x24,0x24,0x4,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0x4,
-+0x11,0x11,0x2f,0x21,0x49,0xf8,0x13,0x22,0x42,0xfb,0x40,0x7,0x18,0xe0,0x40,0x0,0x10,0x14,0xfe,0x10,0xf0,0x40,0xf8,0x48,0x48,0xf8,0x40,0xfe,0x40,0x40,0x40,0x40,
-+0x11,0x11,0x21,0x21,0x4f,0xf9,0x13,0x23,0x45,0xfd,0x49,0x1,0x1d,0xe1,0x41,0x1,0x0,0x4,0x3e,0x24,0xe4,0x24,0x3c,0xa4,0x64,0x24,0x3c,0x24,0x24,0x24,0x3c,0x24,
-+0x13,0x12,0x22,0x23,0x4a,0xfa,0x13,0x20,0x47,0xf8,0x2,0x2,0x1a,0xe3,0x44,0x18,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x0,0xfe,0x40,0x48,0x7c,0x40,0x40,0xc6,0x3c,
-+0x10,0x10,0x27,0x24,0x4c,0xfc,0x17,0x24,0x44,0xff,0x44,0x4,0x1c,0xe7,0x44,0x1,0x10,0x90,0xd0,0x90,0xb8,0xb6,0xd2,0x90,0x94,0x94,0x98,0x88,0x90,0xa0,0x40,0x80,
-+0x10,0x10,0x23,0x22,0x4b,0xf8,0x17,0x20,0x43,0xfa,0x42,0x2,0x1a,0xe0,0x41,0x6,0x40,0x48,0xfc,0x48,0xf8,0x40,0xfe,0x0,0xf8,0x8,0x48,0x48,0x88,0xb0,0xc,0x4,
-+0x10,0x10,0x23,0x22,0x4a,0xfb,0x12,0x22,0x43,0xf8,0x41,0x5,0x1d,0xe5,0x48,0x0,0x0,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x80,0x40,0x24,0x2,0xa,0xf8,0x0,
-+0x12,0x13,0x22,0x25,0x4d,0xf5,0x15,0x25,0x45,0xfd,0x44,0x4,0x1c,0xe4,0x44,0x7,0x4,0xfe,0x20,0xfc,0x24,0x24,0xfc,0x24,0x24,0xfc,0xa0,0xa0,0x40,0x60,0x98,0x6,
-+0x11,0x11,0x21,0x22,0x4b,0xf6,0x1a,0x22,0x43,0xfa,0x43,0x2,0x1a,0xe2,0x42,0x3,0x8,0x7c,0x8,0x8,0xfe,0x40,0x48,0xfc,0x20,0x24,0xfe,0x20,0x20,0x50,0x8e,0x4,
-+0x10,0x14,0x22,0x22,0x48,0xf8,0x16,0x22,0x42,0xfa,0x42,0x2,0x1a,0xe5,0x48,0x0,0x20,0x48,0xfc,0x88,0x88,0x88,0xf8,0x80,0xf8,0x88,0x88,0x88,0xf8,0x0,0x86,0x7c,
-+0x10,0x13,0x22,0x27,0x4a,0xfb,0x12,0x22,0x43,0xfd,0x41,0x1,0x1d,0xe1,0x41,0x1,0x8,0xfc,0x8,0xf8,0x40,0xfc,0x20,0x92,0xe,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,
-+0x10,0x13,0x20,0x22,0x49,0xf8,0x17,0x20,0x41,0xfd,0x41,0x1,0x1d,0xe1,0x41,0x1,0x8,0xfc,0x90,0x94,0x98,0x90,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x27,0x20,0x4b,0xfa,0x13,0x22,0x43,0xfa,0x43,0x2,0x1f,0xe1,0x42,0x4,0x40,0x48,0xfc,0x40,0xf8,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x8,0xfe,0x10,0xc,0x4,
-+0x10,0x17,0x24,0x25,0x4c,0xf7,0x15,0x25,0x45,0xfc,0x47,0x4,0x1c,0xe4,0x48,0x0,0x4,0xfe,0x0,0xf8,0x0,0xfe,0x48,0x30,0x8e,0x10,0xfe,0x90,0x50,0x10,0x50,0x20,
-+0x10,0x10,0x27,0x20,0x49,0xf9,0x11,0x20,0x43,0xfa,0x42,0x2,0x1a,0xe2,0x42,0x2,0x40,0x24,0xfe,0x0,0xf8,0x8,0xf8,0x4,0xfe,0x4,0xf4,0x94,0x94,0xf4,0x14,0x8,
-+0x10,0x10,0x2f,0x21,0x4a,0xfa,0x12,0x23,0x40,0xff,0x44,0x4,0x1d,0xe4,0x44,0x4,0x80,0x44,0xfe,0x10,0xa8,0x48,0xa8,0xf8,0x44,0xfe,0x44,0x94,0xf4,0x4,0x14,0x8,
-+0x10,0x12,0x21,0x20,0x4b,0xf8,0x11,0x22,0x44,0xfb,0x42,0x2,0x1a,0xe2,0x4f,0x0,0x0,0x8,0x10,0x0,0xfc,0x0,0x10,0x8,0x4,0xf8,0xa8,0xa8,0xa8,0xa8,0xfe,0x0,
-+0x11,0x10,0x2f,0x20,0x4b,0xf8,0x17,0x20,0x40,0xfb,0x40,0x1,0x1a,0xe4,0x48,0x0,0x10,0xa4,0xfe,0xa0,0xf8,0xa8,0xfe,0xa8,0xa8,0xf8,0xa0,0xb0,0xa8,0xae,0xa4,0xa0,
-+0x10,0x10,0x27,0x24,0x48,0xf9,0x11,0x21,0x41,0xf9,0x41,0x7,0x18,0xe1,0x42,0x4,0x40,0x20,0xfe,0x2,0x34,0xc0,0x8,0xfc,0x10,0x10,0x14,0xfe,0x0,0x10,0xc,0x4,
-+0x10,0x17,0x20,0x28,0x4f,0xf4,0x14,0x27,0x40,0xfb,0x40,0xf,0x19,0xe2,0x45,0x0,0x8,0xfc,0xa0,0xa4,0xfe,0xa4,0xa4,0xfc,0x0,0xf8,0x0,0xfe,0x50,0x4c,0x44,0x80,
-+0x13,0x12,0x23,0x22,0x4b,0xf8,0x17,0x24,0x47,0xf8,0x43,0x2,0x19,0xe0,0x43,0xc,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xfc,0xa4,0xfc,0x0,0xf8,0x8,0xb0,0x40,0xb0,0xe,
-+0x10,0x17,0x24,0x2f,0x54,0xf7,0x14,0x21,0x43,0xf8,0x40,0x7,0x19,0xe2,0x45,0x0,0x4,0xfe,0x44,0xfc,0x44,0xfc,0x84,0x10,0xe0,0x40,0x88,0xfc,0x50,0x4c,0x44,0x80,
-+0x10,0x17,0x24,0x22,0x4a,0xf4,0x10,0x20,0x41,0xfa,0x45,0x0,0x19,0xe0,0x40,0x7,0x4,0xbe,0xa4,0x94,0x94,0xa4,0x50,0x88,0x24,0x42,0x90,0x60,0x88,0x30,0xc0,0x0,
-+0x12,0x12,0x24,0x22,0x4a,0xf7,0x14,0x27,0x44,0xf7,0x40,0xf,0x18,0xe1,0x46,0x0,0x48,0x48,0x90,0x48,0x48,0xfc,0x44,0xfc,0x44,0xfc,0x40,0xfe,0xe0,0x50,0x4e,0x40,
-+0x12,0x12,0x22,0x2f,0x42,0xfa,0x17,0x20,0x47,0xfd,0x45,0x5,0x1d,0xe7,0x40,0x0,0x4,0xfe,0x10,0xa4,0x7e,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x28,0x26,0xc2,
-+0x10,0x10,0x2f,0x20,0x4a,0xf9,0x13,0x22,0x43,0xfa,0x43,0x1,0x1a,0xe4,0x41,0x0,0x40,0x44,0xfe,0xa0,0xa8,0x10,0xfe,0xc,0xf8,0x8,0xf8,0x50,0x4c,0x44,0x40,0x80,
-+0x12,0x11,0x27,0x24,0x4d,0xfc,0x17,0x24,0x43,0xfa,0x42,0x3,0x1a,0xe2,0x43,0x2,0x8,0x10,0xfc,0x44,0x54,0x44,0xfc,0x4,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x10,0x1f,0x20,0x27,0x4c,0xff,0x14,0x27,0x40,0xff,0x44,0x7,0x1c,0xe7,0x40,0xf,0x4,0xfe,0x0,0xfc,0x44,0xfc,0x44,0xfc,0x0,0xfe,0x44,0xfc,0x44,0xfc,0x0,0xfe,
-+0x10,0x11,0x25,0x23,0x4a,0xf9,0x10,0x2e,0x42,0xfa,0x42,0x2,0x1a,0xe5,0x48,0x0,0x24,0xfe,0x24,0xfc,0x20,0xfe,0x0,0xf8,0x88,0xf8,0x80,0xf8,0x88,0xf8,0x86,0x7c,
-+0x10,0x11,0x21,0x25,0x49,0xf8,0x17,0x24,0x44,0xff,0x40,0x7,0x18,0xe1,0x46,0x0,0x10,0xf8,0x10,0x10,0xf0,0x0,0xbc,0xa4,0xa4,0xbc,0x40,0xfe,0xe0,0x50,0x4e,0x40,
-+0x10,0x13,0x22,0x26,0x4b,0xf8,0x17,0x20,0x43,0xfa,0x43,0x1,0x1b,0xe5,0x49,0x1,0x8,0xfc,0xa8,0xa8,0xf8,0x4,0xfe,0x0,0xf8,0x8,0xf8,0x44,0x48,0x30,0x8e,0x4,
-+0x11,0x15,0x27,0x29,0x47,0xfb,0x15,0x29,0x43,0xfa,0x42,0x2,0x1a,0xe0,0x41,0x6,0x8,0x28,0xbc,0x48,0xbe,0x18,0x2a,0x4e,0xf8,0x8,0x48,0x48,0x48,0xb0,0xc,0x4,
-+0x0,0x2,0x2,0x4,0x4,0x8,0x10,0x3f,0x0,0x1,0x2,0x4,0x8,0x10,0x3f,0x0,0x0,0x0,0x0,0x0,0x10,0x10,0x20,0xc0,0x80,0x0,0x0,0x0,0x20,0x10,0xf8,0x8,
-+0x11,0x25,0x79,0x11,0x29,0x7d,0x1,0xff,0x0,0x7f,0x49,0x7f,0x49,0x7f,0x40,0x3,0x10,0x24,0x78,0x10,0x28,0x7c,0x10,0xfe,0x80,0x88,0x48,0x50,0x50,0x22,0xd2,0xe,
-+0x0,0x0,0x4,0x4,0x4,0x9,0x9,0x12,0x9,0x9,0x4,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x90,0x90,0x90,0x20,0x20,0x40,0x20,0x20,0x90,0x90,0x90,0x0,0x0,0x0,
-+0x11,0x11,0x22,0x44,0x22,0x11,0x11,0x0,0x3f,0x21,0x21,0x3f,0x21,0x21,0x3f,0x20,0x10,0x10,0x20,0x40,0x20,0x10,0x10,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x10,0x21,0x42,0x21,0x10,0x1f,0x10,0x1f,0x0,0x3f,0x21,0x21,0x3f,0x20,0x20,0x1f,0x84,0x8,0x10,0x8,0x88,0xf0,0x10,0xf0,0x8,0xfc,0x8,0x8,0xf8,0xa,0x2,0xfe,
-+0x0,0x8,0x7d,0x10,0x10,0x10,0x7c,0x10,0x10,0x10,0x10,0x1c,0x70,0x21,0x0,0x0,0x0,0x4,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x0,0x9,0x7d,0x11,0x11,0x11,0x7d,0x11,0x11,0x11,0x11,0x1e,0x72,0x24,0x8,0x10,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x12,0x12,0xe,0x0,
-+0x0,0x8,0x7c,0x13,0x10,0x10,0x7d,0x10,0x10,0x17,0x10,0x1c,0x70,0x20,0x0,0x0,0x40,0x40,0x44,0xfe,0x40,0x48,0xfc,0x40,0x44,0xfe,0x44,0x44,0x44,0x54,0x48,0x40,
-+0x0,0x8,0x7c,0x10,0x11,0x12,0x7c,0x13,0x10,0x10,0x10,0x1c,0x71,0x21,0x2,0x4,0x10,0x90,0x90,0x90,0x8,0x4,0x2,0xf8,0x88,0x88,0x88,0x88,0x8,0x8,0x50,0x20,
-+0x0,0x8,0x7c,0x17,0x10,0x11,0x7d,0x11,0x10,0x10,0x10,0x1c,0x71,0x22,0x4,0x8,0x80,0x40,0x24,0xfe,0x8,0x8,0x8,0x10,0x90,0xa0,0x40,0xa0,0x10,0x8,0xe,0x4,
-+0x0,0xb,0x7c,0x10,0x10,0x10,0x7c,0x13,0x10,0x10,0x10,0x10,0x1c,0x70,0x27,0x0,0x8,0xfc,0x40,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x50,0x48,0x48,0x40,0xfe,0x0,
-+0x0,0x8,0x7f,0x10,0x10,0x11,0x11,0x7d,0x11,0x11,0x11,0x1d,0x70,0x20,0x0,0x0,0x0,0x4,0xfe,0x8,0x8,0xe8,0x28,0x28,0x28,0x28,0xe8,0x8,0x8,0x8,0x28,0x10,
-+0x0,0x8,0x7c,0x10,0x17,0x10,0x7c,0x10,0x11,0x11,0x11,0x1e,0x72,0x24,0x8,0x10,0x80,0xa0,0x98,0x88,0xfe,0xa0,0xa0,0xa4,0x24,0x28,0x30,0x20,0x62,0xa2,0x1e,0x0,
-+0x0,0x8,0x7c,0x10,0x10,0x10,0x7c,0x10,0x11,0x11,0x11,0x1d,0x71,0x21,0x1,0x1,0x40,0x40,0x44,0x7e,0x40,0x40,0x40,0x44,0xfe,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x8,0xfc,0x21,0x21,0x23,0xfd,0x21,0x21,0x21,0x25,0x39,0xe1,0x41,0x1,0x1,0xa0,0xa8,0xa4,0x24,0x20,0x3e,0xe0,0x20,0x20,0x20,0x10,0x10,0x12,0xa,0xa,0x4,
-+0x0,0x8,0x7c,0x11,0x11,0x11,0x7d,0x11,0x11,0x11,0x11,0x11,0x1d,0x71,0x21,0x1,0x20,0x20,0x44,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x9,0x7d,0x11,0x11,0x11,0x7d,0x11,0x11,0x11,0x11,0x11,0x1d,0x71,0x21,0x1,0x4,0xfe,0x4,0x4,0xfc,0x24,0x20,0x24,0xfe,0x20,0x20,0x10,0x10,0x4a,0x8a,0x6,
-+0x2,0x12,0xfa,0x2f,0x22,0x22,0xfa,0x22,0x22,0x22,0x22,0x3a,0xe4,0x4a,0x11,0x0,0x0,0x0,0x4,0xbe,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xbc,0xa4,0x0,0x0,
-+0x0,0xb,0x7d,0x11,0x11,0x11,0x7d,0x11,0x11,0x11,0x11,0x1d,0x73,0x20,0x0,0x0,0x4,0xfe,0x8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0xe,0xf8,0x8,0x8,0x8,
-+0x1,0x11,0xf9,0x21,0x27,0x21,0xf9,0x21,0x21,0x21,0x2f,0x20,0x39,0xe2,0x44,0x8,0x10,0x10,0x10,0x10,0xfc,0x10,0x10,0x10,0x10,0x14,0xfe,0x0,0x10,0x8,0x4,0x4,
-+0x0,0xb,0x7c,0x10,0x11,0x11,0x7d,0x11,0x11,0x11,0x11,0x1d,0x70,0x20,0x0,0x3,0x4,0xfe,0x20,0x40,0xfc,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x50,0x48,0x86,0x2,
-+0x0,0x17,0xf8,0x22,0x22,0x24,0xf7,0x21,0x21,0x22,0x2a,0x34,0xe4,0x4a,0x1,0x0,0x0,0xc0,0xbe,0xa2,0xa4,0xa4,0xe8,0xa4,0xa4,0xa2,0xa2,0xa2,0xb4,0xa8,0x20,0x20,
-+0x1,0x11,0xfa,0x24,0x29,0x21,0xfa,0x26,0x2a,0x22,0x22,0x3a,0xe2,0x42,0x2,0x2,0x0,0x8,0x7c,0x0,0x0,0x4,0xfe,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x28,0x10,
-+0x1,0x11,0xf9,0x25,0x23,0x21,0xf9,0x21,0x23,0x2d,0x21,0x39,0xe2,0x42,0x4,0x18,0x20,0x20,0x24,0x2c,0x30,0x20,0x20,0x30,0x2c,0x24,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x1,0x11,0xf9,0x22,0x25,0x20,0xf8,0x20,0x23,0x2c,0x23,0x3a,0xe2,0x42,0x3,0x2,0x0,0x0,0xfc,0x8,0x10,0xa0,0x40,0xa0,0x18,0x6,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x8,0x8,0x1f,0x21,0x49,0x11,0x23,0x0,0x7f,0x1,0x1,0x3f,0x1,0x1,0xff,0x0,0x0,0x8,0xfc,0x8,0x20,0x18,0x8,0x0,0xfc,0x0,0x10,0xf8,0x40,0x24,0xfe,0x0,
-+0x0,0x13,0xfa,0x24,0x23,0x20,0xf8,0x21,0x23,0x20,0x28,0x37,0xe0,0x40,0x0,0x0,0x0,0xfe,0x42,0x44,0xfc,0x80,0xa0,0x28,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x0,0x14,0xfa,0x21,0x20,0x26,0xfa,0x22,0x22,0x22,0x22,0x3a,0xe2,0x45,0x8,0x0,0x20,0x20,0x24,0xfe,0x40,0x50,0x90,0xfc,0x10,0x14,0xfe,0x10,0x10,0x16,0xfc,0x0,
-+0x1,0x9,0x7f,0x11,0x11,0x11,0x7d,0x11,0x11,0x11,0x11,0x17,0x1c,0x71,0x22,0x4,0x10,0x10,0xfc,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,0x14,0xfe,0x0,0x10,0xc,0x4,
-+0x1,0x11,0xff,0x21,0x20,0x23,0xfa,0x22,0x22,0x22,0x27,0x38,0xe0,0x41,0x2,0xc,0x10,0x14,0xfe,0x10,0x40,0xf8,0x48,0x48,0x48,0x48,0xfe,0x40,0xa0,0x10,0xe,0x4,
-+0x0,0x10,0xfb,0x20,0x20,0x21,0xfb,0x20,0x23,0x22,0x22,0x3a,0xe3,0x42,0x0,0x0,0x40,0x48,0xfc,0x40,0xa0,0x14,0xfe,0x8,0xc8,0x48,0x48,0x48,0xc8,0x8,0x28,0x10,
-+0x0,0x10,0xf8,0x23,0x22,0x22,0xfb,0x22,0x22,0x22,0x22,0x3a,0xe2,0x44,0x9,0x2,0x48,0x7c,0x40,0xfe,0x42,0x78,0xc4,0x7c,0x0,0xf0,0x90,0x90,0x90,0x92,0x12,0xe,
-+0x0,0xb,0x7e,0x12,0x13,0x12,0x7e,0x13,0x12,0x12,0x13,0x1e,0x72,0x22,0x3,0x2,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x20,0x24,0xa8,0x30,0x20,0xa2,0x22,0x1e,
-+0x0,0x8,0x7d,0x11,0x12,0x10,0x7c,0x11,0x12,0x11,0x11,0x1e,0x70,0x21,0x2,0xc,0x40,0x40,0x48,0x50,0x40,0xa0,0x98,0x48,0x44,0x48,0x50,0xa0,0xa0,0x10,0xe,0x4,
-+0x0,0x14,0xff,0x24,0x28,0x23,0xf8,0x20,0x27,0x20,0x21,0x39,0xe2,0x44,0x1,0x0,0x80,0x40,0xfe,0x2,0x14,0xf8,0x0,0x4,0xfe,0x40,0x50,0x48,0x44,0x44,0x40,0x80,
-+0x0,0x14,0xff,0x24,0x2a,0x23,0xfa,0x24,0x24,0x2a,0x21,0x39,0xe2,0x44,0x8,0x10,0x80,0x40,0xfe,0x2,0x4,0xbc,0xa4,0xa4,0xa4,0xa4,0x34,0x28,0x22,0x22,0x1e,0x0,
-+0x0,0x17,0xfc,0x28,0x21,0x22,0xf8,0x20,0x2f,0x20,0x20,0x39,0xe2,0x44,0x8,0x0,0x0,0xfe,0x2,0xa4,0x18,0x8,0x40,0x44,0xfe,0x40,0xe0,0x50,0x48,0x4e,0x44,0x40,
-+0x0,0x13,0xfa,0x22,0x23,0x22,0xfa,0x23,0x22,0x22,0x23,0x3d,0xe5,0x49,0x11,0x1,0x4,0xfe,0x4,0x4,0xfc,0x20,0x24,0xfe,0x20,0x24,0xfe,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x7,0xfc,0x25,0x24,0x25,0xf8,0x20,0x23,0x22,0x23,0x3a,0xe3,0x42,0x3,0x2,0x4,0xfe,0x4,0xf4,0x4,0xf4,0x0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x8,
-+0x0,0x10,0xf9,0x22,0x25,0x28,0xff,0x24,0x24,0x27,0x24,0x3c,0xe7,0x44,0x4,0x5,0x40,0xc0,0x20,0x10,0xe8,0x6,0x88,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0x88,0xa8,0x90,
-+0x0,0x17,0xfa,0x21,0x20,0x23,0xf8,0x27,0x21,0x21,0x22,0x3a,0xe4,0x48,0x1,0x6,0x1c,0xe0,0x48,0x50,0x20,0xfc,0x80,0xfe,0x0,0xf8,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x0,0x17,0xfc,0x24,0x24,0x27,0xfc,0x24,0x27,0x24,0x24,0x3f,0xe4,0x44,0x4,0x4,0x4,0xbe,0x84,0x84,0x84,0xbc,0x4,0x0,0xbc,0x4,0x24,0xa8,0x10,0x28,0x46,0x84,
-+0x1,0x11,0xfa,0x21,0x21,0x20,0xf8,0x23,0x22,0x22,0x22,0x3a,0xe3,0x42,0x3,0x2,0x24,0x24,0x48,0x24,0x24,0x40,0x84,0xfe,0x4,0x94,0x64,0x94,0xc,0x4,0xfc,0x4,
-+0x0,0x17,0xfa,0x21,0x27,0x24,0xf8,0x27,0x21,0x21,0x22,0x3a,0xe4,0x48,0x1,0x6,0x38,0xc0,0x48,0x50,0xfe,0x82,0x84,0xfe,0x0,0xf0,0x10,0xa0,0x40,0xa0,0x1e,0x4,
-+0x0,0x10,0xfb,0x22,0x22,0x22,0xfb,0x22,0x22,0x22,0x23,0x3d,0xe5,0x49,0x11,0x1,0x40,0x24,0xfe,0x20,0xfc,0x24,0xfe,0x24,0xfc,0x20,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x1,0x11,0xff,0x21,0x21,0x20,0xff,0x24,0x27,0x20,0x27,0x38,0xe7,0x40,0xf,0x0,0x10,0x14,0xfe,0x10,0xf0,0x44,0xfe,0x44,0xfc,0x40,0xfc,0x40,0xfc,0x40,0xfe,0x0,
-+0x1,0x11,0xff,0x21,0x21,0x2f,0xf8,0x23,0x22,0x23,0x22,0x3b,0xe0,0x41,0x2,0x4,0x10,0x10,0xfc,0x10,0x14,0xfe,0x40,0xf8,0x48,0xf8,0x48,0xf8,0x0,0x10,0xc,0x4,
-+0x0,0x17,0xfd,0x25,0x26,0x26,0xfb,0x24,0x20,0x2f,0x20,0x39,0xe0,0x40,0x1,0x6,0x0,0xbc,0xac,0xac,0xb4,0xb4,0x18,0xa4,0x40,0xfe,0x90,0x10,0xa0,0x40,0xb0,0xc,
-+0x0,0x14,0xfc,0x27,0x21,0x21,0xfb,0x22,0x27,0x2a,0x23,0x3a,0xe2,0x43,0x2,0x2,0x40,0x44,0x44,0xfc,0x44,0x20,0xfe,0x20,0xfc,0x20,0xfc,0x20,0x24,0xfe,0x0,0x0,
-+0x0,0x10,0xfb,0x22,0x22,0x22,0xfa,0x23,0x22,0x22,0x23,0x38,0xe5,0x45,0x9,0x0,0x40,0x84,0xfe,0x44,0x74,0x94,0xd4,0x24,0x44,0x84,0xfc,0x40,0x24,0x2a,0xa,0xf8,
-+0x4,0x2,0xf2,0x2f,0x24,0x24,0xf7,0x25,0x25,0x25,0x35,0xe9,0x49,0x15,0x22,0x1,0x40,0x40,0x44,0xfe,0x80,0x0,0x7e,0x12,0x54,0x50,0x5e,0x50,0x50,0xb0,0x90,0xe,
-+0x0,0x17,0xf9,0x20,0x2f,0x20,0xfb,0x22,0x23,0x22,0x23,0x38,0xef,0x40,0x0,0x0,0x40,0xfc,0x10,0xa0,0xfe,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x40,0xfe,0x40,0x40,0x40,
-+0x0,0x14,0xfa,0x20,0x2f,0x21,0xf8,0x27,0x20,0x23,0x20,0x3f,0xe0,0x40,0x3,0xc,0xa0,0xa4,0xa8,0xa0,0xfe,0x10,0xa0,0xfc,0x40,0xf8,0x40,0xfe,0x40,0xa0,0x18,0x6,
-+0x2,0x13,0xfa,0x27,0x28,0x25,0xfa,0x24,0x2a,0x21,0x27,0x38,0xe1,0x42,0xc,0x0,0x0,0xbc,0x4,0xa8,0x90,0x28,0x46,0x40,0x48,0x50,0xfe,0xe0,0x50,0x4e,0x44,0x40,
-+0x0,0x10,0xff,0x24,0x24,0x27,0xfc,0x24,0x27,0x24,0x27,0x3c,0xe7,0x48,0x13,0x0,0x78,0x40,0xfe,0x82,0xf4,0x88,0xf8,0x0,0xfe,0xc0,0x68,0xb0,0x68,0xa6,0x24,0x40,
-+0x0,0xf,0xf8,0x28,0x28,0x2f,0xf2,0x22,0x2b,0x2a,0x2a,0x3a,0xcb,0x5e,0x0,0x0,0x20,0xa0,0xbe,0xc4,0xa4,0xa8,0x10,0x28,0xc4,0x82,0x7c,0x44,0xc4,0x44,0x7c,0x44,
-+0x3e,0x23,0x3e,0x20,0x3f,0x22,0x62,0xbe,0x0,0x7f,0x1,0x3f,0x1,0x1,0xff,0x0,0x20,0xfc,0x88,0x50,0xfe,0x20,0xf8,0x20,0x20,0xfc,0x0,0xf8,0x40,0x24,0xfe,0x0,
-+0x1,0x5,0xf7,0x29,0x2f,0x23,0xf5,0x29,0x23,0x22,0x22,0x3a,0xe2,0x40,0x1,0x6,0x8,0x28,0xbc,0x48,0xbe,0x18,0xaa,0x4e,0xf8,0x8,0x48,0x48,0x48,0xb0,0xc,0x4,
-+0xf,0x78,0x4b,0x68,0x4b,0x6a,0x4b,0x48,0xff,0x80,0x3f,0x1,0x1f,0x1,0x1,0xff,0xe4,0x3e,0xa4,0x2c,0xa4,0xac,0xa4,0x24,0xfe,0x2,0xf8,0x0,0xf0,0x40,0x24,0xfe,
-+0x0,0x3e,0x22,0x3e,0x22,0x3e,0x0,0xff,0x9,0x28,0x2f,0x28,0x38,0x48,0x84,0x3,0x20,0x28,0xfc,0x20,0x28,0xfc,0x20,0x24,0xfe,0x24,0x24,0x34,0x28,0x20,0x26,0xfc,
-+0x20,0x23,0x22,0xfa,0x23,0x22,0xfa,0x23,0x20,0xfb,0x2a,0x2a,0x3a,0x22,0x2f,0x20,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x0,0xf8,0xa8,0xa8,0xa8,0xa8,0xfe,0x0,
-+0x20,0x20,0x27,0xfa,0x21,0x21,0xf8,0x23,0x22,0xfa,0x2b,0x2a,0x3a,0x22,0x23,0x22,0x8,0x3c,0xc0,0x48,0x48,0x50,0x84,0x3e,0x4,0x4,0xbc,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x17,0x10,0xfc,0x10,0x30,0x38,0x54,0x50,0x90,0x11,0x11,0x12,0x14,0x18,0x0,0x4,0xfe,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x10,0x12,0x12,0xe,0x0,
-+0x10,0x10,0x10,0x10,0xfd,0x12,0x30,0x38,0x54,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x80,0x80,0x80,0x84,0xfe,0x4,0x4,0x84,0x44,0x44,0x4,0x4,0x4,0x4,0x28,0x10,
-+0x10,0x10,0x13,0x10,0xfc,0x10,0x30,0x3b,0x56,0x52,0x92,0x12,0x12,0x12,0x11,0x10,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x10,0x13,0x10,0xfc,0x12,0x31,0x39,0x54,0x50,0x90,0x10,0x11,0x12,0x14,0x18,0x0,0x8,0xfc,0x8,0x88,0x50,0x50,0x10,0xa0,0xa0,0x40,0xa0,0x20,0x18,0xe,0x4,
-+0x10,0x10,0x13,0x10,0xfd,0x11,0x31,0x39,0x55,0x51,0x90,0x10,0x17,0x10,0x10,0x10,0x0,0x10,0xf8,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x10,0x10,0x13,0x12,0xfe,0x12,0x33,0x3a,0x56,0x52,0x92,0x12,0x14,0x14,0x19,0x12,0x0,0x4,0xfe,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0x44,0x84,0x84,0x28,0x10,
-+0x10,0x12,0x12,0x12,0xfe,0x12,0x33,0x3a,0x56,0x52,0x92,0x12,0x12,0x13,0x12,0x10,0x20,0x20,0x20,0x20,0x24,0x2c,0xb0,0x20,0x20,0x20,0x20,0x22,0xa2,0x22,0x1e,0x0,
-+0x10,0x10,0x10,0x10,0xfd,0x11,0x32,0x3a,0x54,0x50,0x90,0x10,0x10,0x10,0x13,0x1c,0x40,0x40,0x40,0x40,0x50,0x48,0x46,0x42,0x48,0x48,0x50,0x50,0x20,0xc0,0x0,0x0,
-+0x1,0x1,0x1,0xff,0x3,0x5,0x9,0x31,0xdf,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x0,0x0,0x4,0xfe,0x80,0x40,0x30,0xe,0xf4,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x10,0x10,0x10,0x10,0xff,0x12,0x32,0x3a,0x56,0x52,0x92,0x13,0x12,0x12,0x12,0x12,0x40,0x40,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0xa4,0x9c,0xc,0x4,0x4,0x14,0x8,
-+0x10,0x11,0x11,0x11,0xfd,0x11,0x31,0x39,0x55,0x51,0x90,0x10,0x10,0x11,0x12,0x14,0x8,0xfc,0x8,0x28,0x28,0x28,0x28,0x28,0x48,0x48,0x60,0xa0,0xa2,0x22,0x1e,0x0,
-+0x10,0x10,0x10,0x10,0xfd,0x11,0x32,0x38,0x57,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x80,0x80,0x88,0xfc,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x11,0x11,0x11,0x11,0xfd,0x11,0x31,0x3b,0x55,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x0,0x8,0x18,0x20,0x40,0x80,0x4,0xfe,0x40,0x20,0x20,0x10,0x10,0x4e,0x84,0x0,
-+0x10,0x11,0x11,0x11,0xfd,0x11,0x31,0x39,0x55,0x52,0x92,0x14,0x14,0x18,0x11,0x10,0x0,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xa8,0xa8,0x48,0x44,0x84,0x2,0x0,
-+0x2,0x4,0x1f,0x10,0x12,0x11,0x10,0x1f,0x1,0x1,0x7f,0x3,0x5,0x19,0x61,0x1,0x0,0x10,0xf8,0x10,0x10,0x60,0x4,0xfe,0x4,0x4,0xf4,0x94,0x48,0x30,0xe,0x0,
-+0x10,0x10,0x10,0x10,0xff,0x10,0x30,0x38,0x54,0x50,0x90,0x10,0x11,0x11,0x12,0x14,0x80,0x40,0x40,0x4,0xfe,0x80,0x88,0xfc,0x88,0x88,0x88,0x88,0x8,0x8,0x50,0x20,
-+0x10,0x10,0x13,0x12,0xfe,0x12,0x32,0x3a,0x57,0x52,0x92,0x12,0x12,0x12,0x11,0x10,0x0,0x8,0xfc,0x48,0x48,0x48,0x48,0x48,0xf8,0x8,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x11,0x10,0x10,0xfc,0x10,0x33,0x38,0x54,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x0,0xfc,0x8,0x90,0x60,0x20,0xfe,0x22,0x24,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x1,0x1,0x7f,0x5,0x9,0x11,0x20,0xdf,0x0,0x0,0x7f,0x1,0x9,0x11,0x25,0x2,0x0,0x8,0xfc,0x40,0x30,0xe,0x24,0xf0,0x0,0x8,0xfc,0x0,0x20,0x18,0x8,0x0,
-+0x11,0x11,0x11,0x17,0xfd,0x10,0x33,0x38,0x54,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x14,0xfe,0x10,0x8,0xfc,0x88,0x88,0x88,0x88,0xa8,0x90,0x80,0x80,0x80,
-+0x10,0x10,0x17,0x10,0xfc,0x10,0x31,0x39,0x55,0x53,0x95,0x19,0x11,0x11,0x11,0x11,0x0,0x4,0xfe,0x80,0x80,0x80,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x10,0xff,0x10,0x30,0x38,0x54,0x50,0x91,0x11,0x12,0x12,0x14,0x18,0x80,0xa0,0x90,0x94,0xfe,0xa0,0xa0,0xa4,0xa4,0xa8,0x28,0x30,0x62,0xa2,0x1e,0x0,
-+0x10,0x13,0x12,0x12,0xfe,0x12,0x32,0x3b,0x56,0x52,0x92,0x12,0x13,0x12,0x13,0x10,0x8,0xfc,0x0,0x40,0x40,0x78,0x88,0x10,0x20,0x20,0x50,0x8c,0x4,0x0,0xfe,0x0,
-+0x10,0x10,0x13,0x10,0xfc,0x12,0x31,0x38,0x57,0x50,0x90,0x10,0x10,0x10,0x10,0x10,0x0,0x8,0xfc,0x40,0x40,0x48,0x50,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x10,0x10,0x10,0x10,0xfc,0x13,0x32,0x3a,0x56,0x53,0x92,0x12,0x12,0x14,0x14,0x18,0x40,0x44,0x7e,0x40,0x44,0xfe,0x4,0x4,0x4,0xfc,0x4,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x10,0x11,0x11,0xfd,0x11,0x31,0x39,0x55,0x51,0x91,0x11,0x10,0x10,0x10,0x10,0x0,0x4,0xfe,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0xfc,0x24,0x20,0x20,0x20,0x20,
-+0x10,0x11,0x11,0x11,0xfd,0x11,0x30,0x3b,0x54,0x50,0x91,0x10,0x10,0x10,0x10,0x10,0x8,0xfc,0x8,0x8,0x8,0xf8,0x0,0xfe,0x80,0x88,0xfc,0x8,0x8,0x88,0x50,0x20,
-+0x10,0x10,0x10,0x10,0xfd,0x11,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0x24,0xfc,0x4,
-+0x10,0x10,0x13,0x12,0xfe,0x12,0x32,0x3a,0x57,0x52,0x91,0x11,0x12,0x12,0x14,0x10,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,0x10,0x10,0x8,0x4,0x4,0x0,
-+0x10,0x10,0x13,0x12,0xfe,0x12,0x33,0x3a,0x56,0x52,0x92,0x12,0x14,0x14,0x18,0x10,0x8,0x1c,0xe0,0x0,0x0,0x4,0xfe,0x20,0x60,0x20,0x30,0x2c,0x24,0x20,0x20,0x20,
-+0x10,0x10,0x13,0x12,0xfe,0x13,0x32,0x3a,0x56,0x52,0x92,0x12,0x14,0x14,0x18,0x10,0x8,0x1c,0xe0,0x0,0x8,0xfc,0x0,0xf8,0x88,0x88,0xa8,0x90,0x82,0x82,0x7e,0x0,
-+0x10,0x10,0x10,0x10,0xfd,0x12,0x34,0x38,0x54,0x53,0x90,0x10,0x10,0x10,0x10,0x10,0x40,0x40,0xa0,0xa0,0x10,0x8e,0x44,0x40,0x0,0xf8,0x8,0x10,0x10,0xa0,0x40,0x20,
-+0x10,0x10,0x10,0x11,0xfd,0x12,0x35,0x39,0x55,0x51,0x91,0x11,0x11,0x10,0x10,0x10,0x80,0x80,0x84,0xfe,0x4,0x24,0xf4,0x24,0x24,0x24,0x24,0xe4,0x24,0x4,0x28,0x10,
-+0x10,0x10,0x13,0x12,0xfe,0x12,0x33,0x3a,0x56,0x52,0x92,0x12,0x12,0x13,0x12,0x10,0x8,0x1c,0xe0,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x10,0x52,0x8a,0x26,0x12,0x0,
-+0x10,0x10,0x13,0x12,0xfe,0x12,0x32,0x3b,0x54,0x50,0x90,0x11,0x12,0x14,0x10,0x10,0x8,0x1c,0xe0,0x0,0x20,0x20,0x24,0xfe,0x20,0x20,0xa8,0x24,0x22,0x22,0xa0,0x40,
-+0x10,0x10,0x10,0x13,0xfe,0x14,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x11,0x10,0x10,0x40,0x20,0x20,0xfe,0x2,0x4,0x0,0x10,0x30,0x40,0x80,0x0,0x4,0x4,0xfc,0x0,
-+0x10,0x13,0x12,0x11,0xfc,0x10,0x30,0x3b,0x54,0x50,0x93,0x10,0x10,0x10,0x17,0x10,0x0,0xf8,0x8,0x10,0xa0,0x40,0xb0,0xe,0x44,0x50,0xf8,0x40,0x40,0x48,0xfc,0x0,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x37,0x38,0x55,0x52,0x94,0x18,0x10,0x10,0x10,0x10,0x40,0x40,0x48,0xf8,0x50,0x64,0xfe,0x80,0xfc,0x40,0x88,0xfc,0x8,0x8,0x28,0x10,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x37,0x38,0x54,0x51,0x92,0x14,0x18,0x10,0x10,0x10,0x40,0x40,0x44,0xf8,0x50,0x64,0xfe,0x40,0x88,0x98,0xa0,0xc0,0x84,0x84,0x7c,0x0,
-+0x10,0x10,0x13,0x10,0xfc,0x10,0x32,0x3a,0x55,0x50,0x90,0x10,0x10,0x10,0x17,0x10,0x0,0x8,0xfc,0x90,0x90,0x90,0x94,0x94,0x94,0x98,0x90,0x90,0x90,0x94,0xfe,0x0,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x30,0x39,0x54,0x53,0x90,0x10,0x10,0x11,0x12,0x14,0x80,0x80,0x9c,0xe0,0x50,0x20,0x52,0x8e,0x0,0xfc,0x90,0x90,0x90,0x12,0x12,0xe,
-+0x10,0x10,0x17,0x10,0xfc,0x11,0x32,0x3b,0x54,0x50,0x97,0x10,0x10,0x10,0x1f,0x10,0x0,0x4,0xfe,0x40,0x80,0x10,0x8,0xfc,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x0,
-+0x10,0x10,0x10,0x10,0xfc,0x13,0x32,0x3a,0x56,0x52,0x92,0x12,0x10,0x10,0x11,0x16,0x40,0x44,0x7e,0x40,0x48,0xfc,0x8,0x48,0x48,0x48,0x48,0x48,0x80,0xb0,0xc,0x4,
-+0x10,0x10,0x14,0x12,0xfd,0x10,0x37,0x38,0x54,0x50,0x90,0x10,0x11,0x11,0x12,0x14,0x40,0x40,0x44,0x48,0x50,0x44,0xfe,0xa0,0xa0,0xa0,0xa0,0xa0,0x22,0x22,0x1e,0x0,
-+0x10,0x10,0x12,0x12,0xff,0x10,0x33,0x38,0x54,0x53,0x92,0x12,0x12,0x12,0x11,0x10,0x40,0x40,0x48,0x48,0xf8,0x0,0xf8,0x8,0x8,0xf8,0x8,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x10,0x17,0x11,0xfd,0x12,0x3a,0x37,0x51,0x51,0x95,0x15,0x12,0x15,0x18,0x10,0x0,0xc,0x70,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x7c,0x0,0x6,0xfc,0x0,
-+0x10,0x10,0x13,0x10,0xfc,0x10,0x37,0x38,0x54,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x8,0x3c,0xe0,0x20,0x20,0x24,0xfe,0x20,0x24,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x11,0xfe,0x12,0x32,0x3a,0x57,0x52,0x92,0x12,0x12,0x12,0x13,0x12,0x0,0x40,0xc0,0x4,0x3e,0x4,0x4,0x4,0xbc,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x11,0xfd,0x13,0x35,0x39,0x55,0x50,0x97,0x10,0x10,0x10,0x10,0x10,0xa0,0xa0,0xa4,0x28,0x30,0x60,0xa4,0x1c,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x10,0x10,0x11,0x12,0xfe,0x14,0x31,0x39,0x53,0x55,0x91,0x11,0x11,0x11,0x11,0x11,0x80,0x88,0x7c,0x0,0x80,0x84,0x7e,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0x28,0x10,
-+0x10,0x10,0x10,0x11,0xfe,0x14,0x31,0x38,0x54,0x57,0x90,0x10,0x11,0x12,0x17,0x10,0x40,0x40,0xa0,0x10,0xe,0x24,0xf0,0x0,0x8,0xfc,0x80,0x80,0x10,0x8,0xfc,0x4,
-+0x10,0x10,0x1e,0x22,0x24,0x54,0x8,0x11,0x21,0xff,0x3,0x5,0x9,0x11,0x61,0x1,0x10,0x10,0xfc,0x10,0x50,0x90,0xfc,0x10,0x14,0xfe,0x80,0x40,0x30,0xe,0x4,0x0,
-+0x2,0x1,0x7f,0x4,0x14,0x14,0x24,0x45,0x1,0xff,0x3,0x5,0x9,0x11,0x61,0x1,0x0,0x8,0xfc,0x40,0x50,0x48,0x44,0x44,0x0,0xfe,0x80,0x40,0x30,0xe,0x4,0x0,
-+0x1,0x11,0x9,0x3f,0x2,0x7f,0x4,0x8,0x31,0xc1,0x3f,0x1,0x9,0x11,0x25,0x2,0x0,0x10,0x20,0xf8,0x0,0xfc,0x40,0x30,0xe,0x4,0xf8,0x0,0x20,0x18,0x8,0x0,
-+0x10,0x10,0x12,0x13,0xfe,0x14,0x30,0x38,0x57,0x50,0x91,0x10,0x10,0x10,0x11,0x12,0x40,0x20,0x20,0xfe,0x2,0x44,0x40,0x84,0xfe,0x88,0x8,0x90,0x60,0x90,0xc,0x4,
-+0x10,0x10,0x17,0x10,0xfc,0x12,0x32,0x38,0x54,0x51,0x96,0x10,0x10,0x10,0x12,0x11,0x0,0x4,0xbe,0x84,0x84,0xa4,0x94,0x94,0x84,0x8c,0xb4,0x84,0x84,0x84,0x94,0x8,
-+0x8,0x8,0x8,0xfe,0x1c,0x2a,0x49,0x0,0xf,0x8,0xa,0x9,0x8,0x10,0x10,0x60,0x20,0x20,0x24,0xfe,0x70,0xa8,0x26,0x20,0xf0,0x20,0x20,0xa0,0xa0,0x22,0x22,0x1e,
-+0x10,0x11,0x11,0x11,0xfd,0x12,0x30,0x3b,0x54,0x51,0x91,0x11,0x11,0x11,0x11,0x11,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x17,0x12,0xfd,0x11,0x33,0x38,0x54,0x50,0x97,0x10,0x10,0x10,0x11,0x10,0x8,0x3c,0xc0,0x48,0x48,0x50,0xf8,0x10,0x60,0x44,0xfe,0x40,0x40,0x40,0x40,0x80,
-+0x10,0x10,0x10,0x11,0xfe,0x11,0x31,0x39,0x55,0x51,0x91,0x11,0x11,0x12,0x12,0x14,0x40,0x40,0xf8,0x10,0x24,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x24,0x24,0x34,0x28,
-+0x10,0x10,0x10,0x17,0xfc,0x11,0x30,0x3f,0x54,0x50,0x90,0x17,0x10,0x10,0x10,0x10,0x80,0x40,0x48,0xfc,0x0,0x10,0xa4,0xfe,0x40,0x40,0x48,0xfc,0x40,0x40,0x40,0x40,
-+0x10,0x12,0x11,0x11,0xfc,0x12,0x32,0x38,0x55,0x51,0x92,0x16,0x12,0x12,0x10,0x13,0x10,0x10,0x10,0x10,0x54,0x52,0x90,0x14,0x14,0x18,0x8,0x10,0x20,0x40,0x80,0x0,
-+0x10,0x13,0x10,0x10,0xfd,0x10,0x30,0x3b,0x54,0x51,0x91,0x12,0x10,0x10,0x11,0x16,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x40,0x48,0x48,0x50,0xa0,0x90,0xe,0x4,
-+0x10,0x10,0x10,0x13,0xfc,0x10,0x37,0x38,0x55,0x53,0x95,0x19,0x11,0x11,0x11,0x11,0x40,0x40,0x44,0xf8,0x50,0x64,0xfe,0x80,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x8,0x8,0x7e,0x8,0x1c,0x2a,0x49,0x4,0x8,0x10,0x2f,0xc4,0x4,0x4,0x8,0x10,0x20,0x28,0xfc,0x20,0x70,0xac,0x20,0xc0,0x20,0x10,0xee,0x24,0x20,0x20,0xa0,0x40,
-+0x10,0x10,0x13,0x10,0xfc,0x13,0x31,0x38,0x56,0x51,0x90,0x17,0x10,0x10,0x11,0x16,0x40,0x48,0xfc,0x40,0x40,0xfe,0x22,0xa4,0x20,0x20,0x24,0xfe,0x40,0x58,0x86,0x2,
-+0x8,0xa,0x7f,0x14,0x14,0x3f,0x4,0x7f,0x4,0x5,0xff,0x3,0x5,0x19,0x61,0x1,0x8,0xc,0x70,0x40,0x44,0x7e,0x48,0x48,0x88,0x8,0xfe,0x80,0x40,0x30,0xe,0x0,
-+0x10,0x10,0x10,0x10,0xff,0x12,0x33,0x3a,0x57,0x52,0x90,0x1f,0x10,0x10,0x10,0x10,0x44,0x7e,0x40,0x48,0xfc,0x8,0xf8,0x8,0xf8,0x48,0x44,0xfe,0x40,0x40,0x40,0x40,
-+0x10,0x13,0x12,0x12,0xfe,0x13,0x30,0x38,0x55,0x51,0x92,0x14,0x10,0x10,0x13,0x1c,0x4,0xfe,0x94,0x94,0x94,0xfc,0x80,0x88,0xfc,0x8,0x88,0x50,0x20,0xc0,0x0,0x0,
-+0x10,0x10,0x17,0x10,0xff,0x12,0x32,0x3a,0x57,0x52,0x92,0x1f,0x10,0x10,0x17,0x10,0x10,0x38,0xc0,0x44,0xfe,0x48,0x48,0x48,0xfc,0x48,0x48,0xfe,0x40,0x48,0xfc,0x0,
-+0x10,0x10,0x10,0x17,0xf8,0x10,0x33,0x3a,0x56,0x52,0x93,0x10,0x12,0x14,0x19,0x10,0x80,0x40,0x44,0xfe,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x40,0x48,0x46,0x42,0x80,
-+0x10,0x10,0x17,0x10,0xff,0x12,0x32,0x3b,0x54,0x53,0x90,0x1f,0x10,0x10,0x11,0x10,0x80,0x48,0xfc,0x0,0xf8,0x8,0x8,0xf8,0x0,0xf8,0x10,0xfe,0x40,0x40,0x40,0x80,
-+0x10,0x10,0x17,0x11,0xfd,0x12,0x37,0x39,0x55,0x51,0x95,0x15,0x12,0x15,0x18,0x10,0x10,0x14,0x7e,0x14,0xfe,0x14,0x7c,0x10,0x7c,0x10,0xfe,0x10,0x10,0x16,0xfc,0x0,
-+0x10,0x10,0x13,0x10,0xfc,0x13,0x30,0x38,0x57,0x52,0x91,0x10,0x11,0x16,0x11,0x10,0x40,0x48,0xfc,0x48,0x48,0xfe,0x48,0x48,0xf8,0x48,0x50,0xe0,0x50,0x4e,0x44,0x80,
-+0x10,0x13,0x12,0x12,0xff,0x12,0x32,0x3b,0x56,0x52,0x93,0x13,0x15,0x15,0x19,0x11,0x4,0xfe,0x4,0x4,0xfc,0x20,0x24,0xfe,0x20,0x24,0xfe,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x13,0x10,0xfd,0x10,0x37,0x39,0x56,0x55,0x98,0x13,0x10,0x10,0x11,0x16,0x40,0x48,0xfc,0x40,0xf8,0x80,0xfc,0x10,0x8,0xf6,0x40,0xf8,0x40,0xb0,0xc,0x4,
-+0x11,0x11,0x13,0x11,0xfd,0x11,0x31,0x39,0x55,0x51,0x9f,0x12,0x12,0x12,0x13,0x10,0x10,0x10,0xfc,0x10,0xf0,0x10,0x10,0xf0,0x10,0x14,0xfe,0x50,0x88,0x0,0xfc,0x0,
-+0x20,0x20,0x20,0x2f,0xf8,0x20,0x37,0x6d,0x64,0xa5,0x24,0x24,0x27,0x24,0x24,0x24,0x40,0x40,0x44,0xfe,0x40,0x44,0xfe,0x14,0xa4,0xf4,0x44,0x44,0xfc,0x44,0x54,0x8,
-+0x10,0x10,0x10,0x17,0xfc,0x11,0x32,0x3c,0x57,0x52,0x93,0x12,0x13,0x10,0x1f,0x10,0x40,0x40,0x48,0xfc,0xe0,0x50,0x4e,0x44,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xfe,0x0,
-+0x10,0x10,0x17,0x10,0xff,0x12,0x33,0x3a,0x56,0x53,0x90,0x10,0x11,0x12,0x14,0x10,0x40,0x44,0xfe,0x40,0xf8,0x48,0x58,0xe8,0x48,0xf8,0xc0,0xe0,0x50,0x4e,0x44,0x40,
-+0x11,0x15,0x15,0x15,0xfd,0x15,0x30,0x3b,0x56,0x52,0x92,0x12,0x12,0x10,0x11,0x16,0x20,0x20,0x24,0x3e,0x50,0x88,0x8,0xfc,0x8,0x48,0x48,0x48,0xa8,0xa2,0x22,0x1e,
-+0x10,0x13,0x12,0x12,0xfb,0x10,0x37,0x3a,0x57,0x52,0x93,0x12,0x12,0x1f,0x10,0x10,0x8,0xfc,0x8,0x8,0xf8,0x0,0xfe,0x8,0xf8,0x8,0xf8,0x8,0xe,0xf8,0x8,0x8,
-+0x10,0x10,0x13,0x12,0xfe,0x12,0x33,0x38,0x54,0x57,0x94,0x14,0x14,0x14,0x17,0x14,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x0,0x4,0xbe,0xa4,0xa4,0xa4,0xa4,0xbc,0xa4,
-+0x10,0x10,0x3e,0x48,0x8,0x7e,0x14,0x22,0x41,0x1,0xff,0x3,0x5,0x39,0xc1,0x1,0x8,0xfc,0x80,0xf8,0x88,0xf8,0x80,0xfc,0x0,0x4,0xfe,0x80,0x40,0x30,0xe,0x0,
-+0x10,0x10,0x17,0x11,0xf9,0x17,0x31,0x3b,0x53,0x55,0x95,0x19,0x11,0x11,0x11,0x11,0x10,0xd0,0x10,0x10,0x54,0xd4,0x38,0x90,0x50,0x28,0x28,0x28,0x28,0x44,0x82,0x0,
-+0x10,0x10,0x13,0x12,0xfe,0x13,0x32,0x3a,0x57,0x52,0x92,0x13,0x1e,0x12,0x12,0x13,0x40,0xbc,0x24,0x24,0x24,0xa6,0x40,0x3c,0x84,0x24,0x28,0xa8,0x10,0x28,0x46,0x84,
-+0x10,0x14,0x12,0x12,0xfc,0x10,0x36,0x3a,0x56,0x52,0x92,0x12,0x12,0x15,0x18,0x10,0x20,0x44,0xfe,0x84,0x84,0xfc,0x80,0xfc,0x84,0x84,0x84,0xfc,0x80,0x6,0xfc,0x0,
-+0x10,0x10,0x17,0x10,0xfd,0x10,0x37,0x38,0x54,0x57,0x90,0x11,0x12,0x14,0x11,0x10,0x80,0x48,0xfc,0x0,0x10,0xa4,0xfe,0x40,0x48,0xfc,0x40,0x50,0x4c,0x44,0x40,0x80,
-+0x10,0x14,0x12,0x14,0xfc,0x15,0x35,0x3d,0x55,0x54,0x95,0x15,0x15,0x15,0x14,0x14,0x0,0x4,0xfe,0x4,0x4,0xf4,0x14,0x14,0xf4,0x4,0xf4,0x14,0x14,0xf4,0x14,0x8,
-+0x11,0x10,0x13,0x10,0xfc,0x13,0x30,0x38,0x57,0x50,0x91,0x12,0x14,0x18,0x13,0x10,0x8,0x90,0xfc,0x40,0x50,0xf8,0x40,0x44,0xfe,0x80,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x14,0x12,0x10,0xfc,0x17,0x30,0x39,0x56,0x55,0x98,0x13,0x10,0x10,0x10,0x10,0x80,0x44,0x48,0x10,0x4,0xfe,0xa0,0x10,0x48,0xf6,0x40,0xf8,0x40,0x40,0x40,0x40,
-+0x10,0x14,0x17,0x14,0xf8,0x13,0x30,0x3b,0x56,0x53,0x92,0x13,0x12,0x10,0x1f,0x10,0x80,0x40,0xfe,0x2,0x14,0xf8,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x8,0x0,0xfe,0x0,
-+0x10,0x13,0x12,0x12,0xff,0x12,0x32,0x3a,0x56,0x52,0x92,0x12,0x14,0x14,0x18,0x10,0x4,0xfe,0x24,0x24,0xfc,0x0,0xfc,0x84,0x84,0xfc,0x84,0xfc,0x84,0x84,0xfc,0x84,
-+0x10,0x17,0x11,0x11,0xfd,0x12,0x3a,0x35,0x54,0x5b,0x92,0x12,0x12,0x12,0x1f,0x10,0x0,0xf8,0x10,0x1c,0xe4,0xa4,0x44,0xb4,0x8,0xfc,0xa8,0xa8,0xa8,0xa8,0xfe,0x0,
-+0x10,0x10,0x17,0x10,0xff,0x10,0x37,0x39,0x52,0x55,0x98,0x17,0x10,0x11,0x16,0x10,0x40,0x48,0xfc,0x40,0xf8,0x80,0xfe,0x10,0x38,0xce,0x44,0xfc,0xe0,0x58,0x44,0x40,
-+0x10,0x13,0x12,0x12,0xff,0x12,0x32,0x3b,0x56,0x52,0x93,0x12,0x12,0x12,0x13,0x10,0x8,0xfc,0x50,0x50,0xdc,0x50,0x50,0xdc,0x50,0x50,0xdc,0x50,0x50,0x54,0xfe,0x0,
-+0x10,0x13,0x12,0x13,0xfe,0x13,0x38,0x37,0x50,0x54,0x92,0x11,0x16,0x10,0x12,0x11,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x4,0xbe,0x84,0xa4,0x94,0x8c,0xb4,0x84,0x94,0x8,
-+0x11,0x11,0x11,0xfa,0x17,0x32,0x3b,0x56,0x53,0x92,0x10,0x17,0x10,0x10,0x10,0x10,0x40,0x24,0xfe,0x20,0xfc,0x20,0xfc,0x20,0xfe,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x10,0x11,0x13,0x12,0xff,0x12,0x3b,0x36,0x52,0x57,0x90,0x11,0x12,0x14,0x11,0x10,0x84,0x4,0xc4,0x44,0xc4,0x7e,0xc4,0x64,0x54,0xd4,0xc4,0x44,0x44,0x44,0x54,0x88,
-+0x10,0x10,0x13,0x12,0xff,0x12,0x33,0x38,0x57,0x51,0x92,0x14,0x1b,0x10,0x10,0x10,0x40,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x80,0xfe,0x10,0x48,0x46,0xf8,0x40,0x40,0x40,
-+0x10,0x10,0x17,0x10,0xfd,0x11,0x37,0x39,0x55,0x50,0x91,0x13,0x15,0x19,0x11,0x11,0x40,0x24,0xfe,0x0,0xf8,0x8,0xfe,0x8,0xf8,0x84,0x48,0x30,0x10,0x4e,0x84,0x0,
-+0x10,0x10,0x17,0x10,0xfb,0x12,0x33,0x38,0x57,0x54,0x95,0x15,0x15,0x15,0x14,0x14,0x80,0x44,0xfe,0x0,0xf8,0x8,0xf8,0x0,0xfc,0x4,0xf4,0x14,0x14,0xf4,0x14,0x8,
-+0x22,0x14,0xff,0x8,0x49,0x49,0x7f,0x8,0x11,0x21,0xff,0x3,0xd,0x31,0xc1,0x1,0x4,0x7e,0xc4,0x7c,0x44,0x7c,0x44,0x94,0x8,0x0,0xfe,0x80,0x40,0x30,0xe,0x0,
-+0x10,0x10,0x17,0x14,0xf8,0x11,0x31,0x39,0x55,0x51,0x91,0x1f,0x10,0x11,0x12,0x14,0x80,0x40,0xfe,0x2,0x34,0xc0,0x8,0xfc,0x10,0x10,0x14,0xfe,0x0,0x10,0xc,0x4,
-+0x10,0x10,0x17,0x14,0xf8,0x11,0x32,0x38,0x55,0x52,0x97,0x1a,0x12,0x12,0x13,0x12,0x80,0x40,0xfe,0x2,0xa4,0x10,0x48,0xa0,0x10,0x8,0xfe,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x14,0x12,0x12,0xf8,0x16,0x33,0x3a,0x56,0x53,0x92,0x12,0x12,0x13,0x12,0x10,0x20,0x20,0x24,0xfc,0x28,0x30,0xfe,0x40,0xfc,0x44,0x44,0x7c,0xc4,0x44,0x7c,0x44,
-+0x10,0x13,0x12,0x12,0xff,0x12,0x33,0x3a,0x57,0x53,0x95,0x15,0x15,0x15,0x19,0x11,0x4,0xfe,0x4,0x4,0xfc,0x20,0x24,0xa8,0xfc,0x4,0xfc,0x4,0xfc,0x4,0x14,0x8,
-+0x11,0x11,0x1f,0x11,0xfd,0x10,0x37,0x3c,0x57,0x50,0x97,0x10,0x13,0x10,0x1f,0x10,0x10,0x14,0xfe,0x10,0xf0,0x44,0xfe,0x44,0xfc,0x40,0xfc,0x40,0xf8,0x40,0xfe,0x0,
-+0x10,0x10,0x17,0x10,0xfa,0x11,0x37,0x38,0x57,0x54,0x95,0x15,0x15,0x14,0x17,0x14,0x40,0x48,0xfc,0x40,0x48,0x50,0xfe,0x0,0xfc,0x4,0xf4,0x14,0xf4,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x13,0xfe,0x12,0x32,0x3a,0x57,0x52,0x93,0x12,0x14,0x15,0x18,0x10,0x10,0x18,0x14,0xfe,0x10,0x90,0xd2,0x92,0xf4,0x94,0xd8,0xa8,0x9a,0xaa,0xc6,0x4,
-+0x10,0x13,0x10,0x17,0xfd,0x14,0x31,0x38,0x57,0x50,0x9f,0x11,0x11,0x10,0x10,0x10,0x10,0xf8,0x40,0xfe,0x52,0xe4,0x50,0x40,0xfc,0x0,0xfe,0x0,0xf8,0x8,0x48,0x30,
-+0x10,0x12,0x11,0x14,0xff,0x14,0x31,0x39,0x55,0x51,0x90,0x17,0x10,0x10,0x17,0x10,0x40,0x48,0x50,0x40,0xfe,0x2,0xf4,0x10,0x10,0xf0,0x40,0xfc,0x40,0x44,0xfe,0x0,
-+0x44,0x29,0x10,0x2f,0x48,0x19,0x2b,0x4d,0x9,0x29,0x11,0xff,0x5,0x19,0x61,0x1,0x48,0xf0,0x54,0xfe,0x80,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xfe,0x40,0x30,0xe,0x0,
-+0x22,0x22,0x23,0x24,0xff,0x25,0x75,0x6f,0x65,0xa5,0x27,0x25,0x25,0x25,0x29,0x30,0x4,0x4,0xd4,0x8c,0xcc,0x64,0x54,0xd4,0x46,0x7c,0xc4,0x44,0x44,0x44,0x44,0x84,
-+0x10,0x13,0x10,0x11,0xff,0x12,0x32,0x3b,0x56,0x53,0x92,0x12,0x17,0x10,0x10,0x10,0x8,0xc8,0x88,0x10,0xfe,0x64,0x54,0xd4,0x54,0xd4,0x48,0x68,0xc8,0x54,0x52,0x60,
-+0x22,0x22,0x22,0x2f,0xf2,0x22,0x7f,0x6a,0xa2,0x2b,0x2a,0x2a,0x2e,0x2a,0x31,0x20,0x10,0x18,0x14,0x94,0x7e,0x50,0xd0,0x54,0x54,0xc8,0x6a,0x56,0x20,0x6,0xfc,0x0,
-+0x14,0xff,0x14,0x3f,0x41,0xbd,0x25,0x3d,0x2,0x1,0xff,0x3,0xd,0x31,0xc1,0x1,0x20,0x24,0x3e,0x44,0xa4,0x28,0x10,0x28,0x46,0x0,0xfe,0x80,0x40,0x30,0xe,0x0,
-+0x1,0x3f,0x9,0x7f,0x40,0x9f,0x8,0x1f,0x68,0xf,0x1,0xff,0x5,0x19,0x61,0x1,0x0,0xf8,0x20,0xfe,0x2,0xf4,0x0,0xf0,0x10,0xf0,0x4,0xfe,0x40,0x30,0xe,0x0,
-+0x20,0x20,0x2f,0x28,0xfa,0x29,0x6f,0x78,0x6a,0xaa,0x2b,0x28,0x28,0x28,0x29,0x32,0x0,0x4,0xfe,0x8,0x28,0x48,0xee,0x92,0xa4,0xa8,0xe8,0xa8,0x88,0x94,0x14,0x22,
-+0x10,0x10,0x10,0x11,0xfd,0x13,0x35,0x39,0x55,0x51,0x91,0x11,0x11,0x12,0x12,0x14,0xa0,0x90,0x84,0xfe,0x10,0x10,0xfc,0x10,0xfc,0x10,0x14,0xfe,0x0,0xa8,0xa6,0x2,
-+0x10,0x10,0x11,0x12,0xfd,0x10,0x3a,0x36,0x53,0x50,0x97,0x14,0x14,0x15,0x14,0x14,0x40,0xa0,0x10,0x48,0xf6,0xa0,0x48,0xa8,0xf8,0x44,0xfe,0x44,0xa4,0xf4,0x14,0x8,
-+0x11,0x11,0x12,0x17,0xfc,0x17,0x3c,0x37,0x50,0x5f,0x90,0x13,0x12,0x13,0x12,0x13,0x0,0xf0,0x24,0xfe,0x44,0xfc,0x44,0xfc,0x0,0xfe,0x0,0xf8,0x8,0xf8,0x8,0xf8,
-+0x11,0x10,0x17,0x10,0xff,0x12,0x33,0x3a,0x56,0x52,0x93,0x10,0x1f,0x12,0x11,0x10,0x10,0xa0,0xfc,0xa0,0xf8,0xa8,0x38,0x8,0xe8,0x8,0xf8,0x10,0xfe,0x10,0x50,0x20,
-+0x10,0x13,0x12,0x13,0xfe,0x13,0x32,0x3b,0x56,0x52,0x92,0x12,0x13,0x14,0x18,0x10,0x4,0xfe,0x4,0xfc,0x20,0xac,0x70,0xac,0x20,0xa8,0xfc,0x20,0xfe,0x20,0x20,0x20,
-+0x10,0x13,0x10,0x10,0xff,0x10,0x33,0x38,0x57,0x54,0x95,0x17,0x15,0x15,0x14,0x14,0x0,0xf8,0x90,0x60,0xfe,0xc4,0x48,0x44,0xfe,0xa4,0x14,0xfc,0x14,0xf4,0x14,0x8,
-+0x20,0x22,0x22,0x22,0xf4,0x2f,0x32,0x6c,0x64,0xaf,0x20,0x23,0x2c,0x20,0x21,0x20,0x40,0x78,0x48,0x48,0xf8,0x8,0xfe,0x20,0x54,0xb8,0x50,0xb8,0x54,0x92,0x10,0x30,
-+0x10,0x13,0x10,0x17,0xfd,0x14,0x31,0x38,0x57,0x52,0x92,0x13,0x12,0x12,0x13,0x12,0x10,0xf8,0x40,0xfe,0x52,0xe4,0x50,0x40,0xf8,0x48,0x48,0xf8,0x48,0x48,0xf8,0x8,
-+0x10,0x10,0x11,0x13,0xfe,0x13,0x33,0x3a,0x56,0x52,0x92,0x12,0x14,0x14,0x18,0x10,0x80,0xf8,0x10,0xfe,0x88,0x24,0xfe,0x0,0xfc,0x0,0xfc,0x0,0xfc,0x84,0xfc,0x84,
-+0x10,0x1f,0x10,0x17,0xfd,0x15,0x35,0x3f,0x50,0x53,0x90,0x1f,0x11,0x12,0x15,0x10,0x40,0xfe,0x0,0xfc,0x14,0xf4,0x14,0xfc,0x0,0xf8,0x0,0xfe,0x50,0x4c,0x44,0x80,
-+0x0,0x3e,0x23,0x3e,0x20,0x3f,0x62,0xa2,0x3e,0x1,0xff,0x3,0xd,0x31,0xc1,0x1,0x20,0x28,0xfc,0x88,0x50,0xfe,0x20,0xf8,0x20,0x24,0xfe,0x80,0x40,0x30,0xe,0x0,
-+0x10,0x14,0x17,0x15,0xf9,0x12,0x35,0x3b,0x52,0x54,0x9b,0x10,0x11,0x12,0x14,0x10,0x80,0x40,0xfe,0x2,0xbc,0xa8,0xb0,0x10,0xe8,0x6,0xf8,0x40,0x50,0x4c,0x44,0xc0,
-+0x0,0x22,0x14,0xff,0x14,0x7f,0x55,0x55,0x67,0x41,0x7f,0x41,0x41,0x7f,0x40,0x1,0x20,0x28,0x24,0xa4,0x20,0xfe,0x20,0x20,0x20,0x20,0x20,0x50,0x50,0x88,0x8e,0x4,
-+0x8,0x7f,0x8,0x3e,0x8,0x7f,0x10,0x1e,0x22,0x4a,0x5,0xff,0x1,0x2,0xc,0x70,0x40,0x44,0x7e,0x48,0x88,0x28,0x10,0x28,0x46,0x90,0x8,0xfe,0x0,0x80,0x70,0xe,
-+0x0,0x4,0xfe,0x20,0x20,0x3d,0x26,0x45,0x64,0x98,0x8,0x10,0x10,0x20,0x41,0x6,0x8,0xfc,0x88,0x88,0x88,0xe,0x0,0xf8,0x8,0x88,0x50,0x20,0x50,0x90,0xe,0x4,
-+0x0,0x5,0xff,0x21,0x21,0x3d,0x25,0x45,0x65,0x99,0x9,0x11,0x11,0x21,0x47,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0xf8,0x8,0x8,0x8,0x8,0xfe,0x0,
-+0x0,0x4,0xfe,0x21,0x22,0x3c,0x24,0x45,0x64,0x98,0x9,0x11,0x12,0x24,0x41,0x0,0x80,0x84,0xfe,0x0,0xf8,0x10,0x24,0xfe,0x94,0x94,0x24,0x24,0x44,0x84,0x28,0x10,
-+0x0,0x4,0xfe,0x20,0x21,0x3e,0x24,0x44,0x67,0x98,0x8,0x11,0x10,0x20,0x41,0x6,0x40,0x40,0xa0,0xa0,0x18,0x26,0x40,0x88,0x10,0x20,0x44,0x88,0x10,0x60,0x80,0x0,
-+0x0,0x5,0xff,0x21,0x21,0x3c,0x25,0x45,0x65,0x99,0x9,0x11,0x11,0x20,0x40,0x3,0x4,0xfe,0x4,0x4,0xfc,0x0,0xfc,0x4,0x24,0x24,0x24,0x24,0x24,0x50,0x8c,0x4,
-+0x0,0x4,0xfe,0x20,0x21,0x3e,0x25,0x44,0x64,0x99,0x9,0x11,0x11,0x20,0x47,0x0,0x20,0x20,0x50,0x88,0x4,0xa,0xfc,0x0,0x44,0x24,0x24,0x28,0x28,0x10,0xfe,0x0,
-+0x0,0x5,0xfe,0x21,0x20,0x3c,0x25,0x44,0x64,0x98,0xb,0x10,0x10,0x20,0x40,0x0,0x1c,0xe0,0x0,0x24,0xa8,0x0,0xfc,0x8,0x30,0x24,0xfe,0x20,0x20,0x20,0xa0,0x40,
-+0x1,0x4,0xfe,0x21,0x21,0x3d,0x25,0x45,0x65,0x99,0x8,0x10,0x13,0x20,0x40,0x0,0x4,0x88,0x10,0xfc,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,
-+0x0,0x5,0xfe,0x20,0x20,0x3b,0x2a,0x4a,0x6a,0x9a,0xb,0x12,0x10,0x20,0x4f,0x0,0x0,0xfc,0x8,0x10,0x20,0xbe,0xa2,0xb4,0xb4,0xa8,0xb6,0x22,0xa0,0x44,0xfe,0x0,
-+0x0,0x4,0xff,0x22,0x24,0x3d,0x25,0x45,0x65,0x99,0x9,0x17,0x10,0x21,0x42,0x4,0x80,0x40,0xfe,0x2,0x34,0xc0,0x8,0xfc,0x10,0x10,0x14,0xfe,0x0,0x10,0xc,0x4,
-+0x0,0xb,0xfc,0x21,0x20,0x3b,0x2a,0x4d,0x68,0x99,0x9,0x11,0x10,0x20,0x47,0x0,0x20,0xfe,0x20,0xfc,0x0,0xfe,0x2,0xfc,0x0,0xfc,0x4,0xfc,0x88,0x50,0xfe,0x0,
-+0x10,0x10,0x15,0xfe,0x20,0x28,0x48,0x7e,0x9,0x8,0xe,0xf8,0x48,0x8,0x9,0x8,0x0,0x4,0xfe,0x24,0x24,0xa4,0xa4,0xa4,0x24,0x24,0x24,0x44,0x44,0x84,0x28,0x10,
-+0x20,0x21,0x29,0xfd,0x41,0x51,0x91,0xfd,0x11,0x11,0x1d,0xf2,0x52,0x14,0x18,0x10,0x4,0xfe,0x0,0x0,0x4,0x7e,0x44,0x44,0x44,0x54,0x48,0x40,0x42,0x42,0x3e,0x0,
-+0x10,0x10,0x14,0xfe,0x23,0x28,0x48,0x7e,0x9,0x9,0xf,0xf9,0x49,0x9,0x9,0x9,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x24,0xfe,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x15,0xfe,0x20,0x29,0x49,0x7f,0x9,0x9,0xf,0xf9,0x48,0x8,0x8,0x8,0x0,0x4,0xfe,0x8,0x8,0xe8,0x28,0x28,0x28,0x28,0xe8,0x28,0x8,0x8,0x28,0x10,
-+0x10,0x10,0x14,0xfe,0x20,0x29,0x49,0x7f,0x9,0x9,0xf,0xf9,0x49,0xa,0xa,0xc,0x20,0x24,0x3e,0x20,0x24,0xfe,0x4,0x4,0xfc,0x4,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x10,0x14,0xfe,0x20,0x28,0x48,0x7e,0x8,0x8,0xe,0xf8,0x48,0x8,0x9,0xa,0x0,0x4,0xfe,0x84,0x84,0x84,0x84,0x84,0xfc,0x84,0x0,0x48,0x48,0x84,0x6,0x2,
-+0x10,0x10,0x14,0xfe,0x20,0x29,0x48,0x7e,0x9,0x8,0xe,0xf8,0x48,0x8,0x8,0xb,0x20,0xa0,0xa0,0xa8,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x50,0x50,0x88,0x8e,0x4,
-+0x20,0x20,0x28,0xfc,0x41,0x52,0x94,0xfc,0x11,0x10,0x18,0xf1,0x50,0x10,0x11,0x16,0x40,0x40,0xa0,0xa0,0x18,0x26,0x40,0x80,0x10,0x20,0x40,0x88,0x10,0x60,0x80,0x0,
-+0x10,0x10,0x15,0xfe,0x20,0x29,0x48,0x7e,0x8,0x9,0xe,0xf8,0x48,0x8,0x8,0x8,0x8,0x1c,0xe0,0x20,0x24,0x24,0xa8,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x10,0x10,0x15,0xff,0x21,0x29,0x49,0x7f,0x9,0x8,0xe,0xf8,0x49,0xa,0x8,0x8,0x8,0x1c,0xe0,0x0,0x20,0x20,0x20,0x24,0xfe,0x20,0xa8,0xa4,0x26,0x22,0xa0,0x40,
-+0x10,0x11,0x14,0xfe,0x20,0x28,0x48,0x7e,0x9,0x8,0xe,0xf8,0x48,0x8,0x8,0x8,0x4,0xfe,0x44,0x44,0x44,0x44,0x94,0x88,0x4,0xfe,0x84,0x84,0x84,0x84,0xfc,0x84,
-+0x10,0x10,0x14,0xfe,0x21,0x28,0x48,0x7d,0x8,0x8,0xe,0xf8,0x4b,0x8,0x8,0x8,0x10,0x18,0x14,0x14,0xfe,0x10,0x10,0xf0,0x90,0x90,0x90,0xf0,0x88,0xa,0x6,0x2,
-+0x10,0x13,0x14,0xfe,0x20,0x29,0x49,0x7e,0x8,0x8,0xf,0xf8,0x48,0x8,0xb,0x8,0x4,0xfe,0x40,0x40,0x88,0x4,0xfe,0x22,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x10,0x14,0xfe,0x20,0x29,0x4a,0x7e,0x8,0x8,0xe,0xf8,0x48,0x8,0xb,0x8,0x20,0x20,0x50,0x50,0x88,0x4,0xfa,0x20,0x20,0x20,0xf8,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x10,0x14,0xff,0x21,0x2a,0x48,0x7e,0x8,0x9,0xf,0xf9,0x49,0x9,0x9,0x9,0x80,0x80,0xfc,0x4,0x88,0x50,0x20,0x50,0x88,0x6,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x13,0x15,0xff,0x21,0x29,0x49,0x7f,0x9,0x9,0xf,0xf9,0x4b,0x9,0x8,0x8,0x4,0xfe,0x20,0x28,0xe8,0x28,0x28,0x28,0xe8,0x28,0x28,0x3a,0xea,0x2e,0x20,0x20,
-+0x8,0x8,0x7e,0x8,0x7e,0x14,0x22,0x42,0x3f,0x5,0x9,0x1f,0x1,0xff,0x1,0x1,0x20,0x20,0xfc,0x20,0xfc,0x50,0x88,0x6,0xf8,0x0,0x20,0xf0,0x4,0xfe,0x0,0x0,
-+0x20,0x20,0x2b,0xfe,0x42,0x52,0x93,0xfe,0x12,0x13,0x1e,0xf2,0x52,0x12,0x12,0x12,0x0,0x4,0xfe,0x4,0x94,0x94,0xfc,0x44,0x24,0xfc,0x84,0x84,0xf4,0x4,0x14,0x8,
-+0x20,0x2f,0x24,0xfd,0x42,0x55,0x90,0xf8,0x17,0x10,0x18,0xf5,0x52,0x15,0x18,0x10,0x0,0xfc,0xa4,0x28,0x10,0x28,0xc4,0x0,0xbc,0x84,0xc4,0x28,0x10,0x28,0xce,0x84,
-+0x20,0x21,0x29,0xfe,0x42,0x51,0x91,0xfc,0x11,0x11,0x1d,0xf1,0x51,0x11,0x11,0x11,0x0,0x24,0x24,0x48,0x48,0x24,0x24,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x4,
-+0x10,0x10,0x13,0xfe,0x21,0x28,0x4b,0x7e,0x8,0x9,0xe,0xf9,0x48,0x8,0x8,0xb,0x20,0x24,0xfe,0x20,0xfc,0x20,0xfe,0x50,0x88,0xfc,0x22,0xfc,0x20,0x58,0x86,0x2,
-+0x20,0x20,0x2b,0xfe,0x42,0x53,0x92,0xfe,0x13,0x12,0x1e,0xf2,0x52,0x12,0x14,0x10,0x40,0x24,0xfe,0x50,0x54,0xfe,0x54,0x54,0xfc,0x92,0x94,0xf8,0x90,0xb2,0xd2,0x8e,
-+0x20,0x22,0x29,0xff,0x41,0x52,0x94,0xfa,0x13,0x12,0x1a,0xf5,0x51,0x11,0x12,0x14,0x40,0x48,0x50,0xfe,0x50,0x4c,0x44,0x8,0xbe,0x88,0xa8,0xa8,0x3e,0x8,0x8,0x8,
-+0x1,0x7f,0x1,0x3f,0x21,0x3f,0x21,0x3f,0x1,0xff,0x1,0x1f,0x10,0x10,0x1f,0x10,0x0,0xfc,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x10,
-+0x4,0x4,0x4,0x4,0x7f,0x4,0x2,0x2,0xff,0x1,0x1,0x0,0x1,0x6,0x38,0x0,0x0,0x80,0x48,0xfc,0x0,0x0,0x4,0xfe,0x0,0x10,0x20,0xc0,0x80,0x44,0x24,0x1c,
-+0x8,0x8,0x14,0x13,0x21,0x40,0xbf,0x22,0x22,0x2a,0x24,0x20,0x22,0x22,0x1e,0x0,0x40,0x50,0x48,0x48,0x40,0x7e,0xc0,0x24,0x24,0x28,0x28,0x10,0x12,0x2a,0x4a,0x84,
-+0x0,0x7f,0x1,0xf,0x8,0xf,0x8,0xf,0x8,0xf,0x1,0xff,0x1,0x0,0x7,0x38,0x8,0xfc,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x44,0xfe,0x20,0xc4,0x44,0x3c,
-+0x8,0x9,0xff,0x8,0x9,0x7f,0x41,0x7f,0x41,0x7f,0x8,0x9,0xff,0x8,0x8,0x9,0x20,0x28,0xa4,0x24,0x20,0xfe,0x20,0x20,0x24,0x24,0x28,0x10,0xb2,0x4a,0x8a,0x4,
-+0x1,0x3f,0x21,0x3f,0x0,0xff,0x21,0x3f,0x21,0x3f,0x21,0x21,0xff,0x41,0x1,0x1,0x20,0xa8,0x24,0x24,0x20,0xfe,0x20,0x20,0x24,0x24,0x28,0x10,0xb2,0x4a,0x8a,0x4,
-+0x22,0x22,0xff,0x22,0x3e,0x22,0x3e,0x22,0x22,0xff,0x54,0x53,0x61,0x40,0x7f,0x1,0x20,0x28,0xa4,0x24,0x20,0xfe,0x20,0x20,0x24,0xa4,0x28,0x10,0x32,0x4a,0x8a,0x4,
-+0x1,0x7f,0x41,0x7f,0x41,0x7f,0x28,0x2a,0x3f,0x48,0xbe,0x8,0xf,0xf8,0x40,0x1,0x20,0xa8,0x24,0x24,0x20,0xfe,0x20,0x20,0x24,0x24,0x28,0x10,0x32,0x4a,0x8a,0x4,
-+0x1,0xff,0x21,0x22,0x3d,0x55,0x49,0x55,0x82,0x7f,0x55,0x55,0x55,0xff,0x0,0x1,0x20,0xa8,0x24,0x24,0x20,0xfe,0x20,0x20,0x24,0x24,0x28,0x10,0x32,0xca,0x8a,0x4,
-+0x2,0x7f,0x14,0x55,0x36,0x14,0xff,0x0,0x3e,0x22,0x22,0x3e,0x22,0x22,0x3e,0x1,0x20,0x28,0x24,0x24,0x20,0xfe,0x20,0x20,0x24,0x24,0x28,0x10,0x32,0x4a,0x8a,0x4,
-+0x0,0x0,0x1f,0x50,0x57,0x55,0x75,0x17,0xf4,0x54,0x57,0x95,0x25,0x27,0x40,0x80,0x28,0x24,0xfe,0x20,0xa0,0x20,0x24,0xa4,0xa8,0xa8,0x90,0x10,0x12,0xaa,0x4a,0x84,
-+0x0,0x3,0x7e,0x40,0x62,0x52,0x54,0x48,0x48,0x54,0x52,0x62,0x40,0x44,0x7e,0x0,0x4,0xfe,0x80,0x88,0xfc,0x88,0xc8,0xa8,0xa8,0x88,0x88,0x88,0xaa,0xca,0x86,0x2,
-+0x8,0xb,0x14,0x14,0x22,0x51,0x88,0x0,0x7e,0x2,0x24,0x14,0x8,0x4,0x4,0x0,0x4,0xfe,0x80,0x88,0xfc,0x88,0xc8,0xa8,0xa8,0x88,0x88,0x88,0xaa,0xca,0x86,0x2,
-+0x40,0x23,0xfe,0x0,0x44,0x28,0xfe,0x0,0x4,0x7e,0x44,0x44,0x44,0x44,0x7c,0x44,0x4,0xfe,0x80,0x88,0xfc,0x88,0xc8,0xa8,0xa8,0x88,0x88,0x88,0xaa,0xca,0x86,0x2,
-+0x8,0x7f,0x8,0x7f,0x22,0x3e,0x14,0x7f,0x0,0xff,0x8,0xf,0x9,0x8,0xe,0x10,0x4,0x8,0x74,0x8,0x74,0x8,0x10,0x60,0x4,0xfe,0x0,0xe0,0x20,0xa4,0x24,0x1c,
-+0x44,0x29,0xfe,0x92,0xd6,0xba,0x92,0xfe,0x4,0x7e,0x44,0x7c,0x44,0x44,0x7c,0x0,0x4,0xfe,0x80,0x88,0xfc,0x88,0xc8,0xa8,0xa8,0x88,0x88,0x88,0xaa,0xca,0x86,0x2,
-+0x0,0x7f,0x42,0x7e,0x41,0x7e,0x62,0xbe,0x0,0xff,0x8,0xf,0x9,0x8,0xe,0x10,0x20,0xfc,0x88,0x50,0xfe,0x0,0xf8,0x20,0x24,0xfe,0x0,0xe0,0x20,0xa4,0x24,0x1c,
-+0x1,0x1,0x1,0x1,0x1,0x3f,0x0,0x8,0x8,0x4,0x2,0x1,0x2,0xc,0x30,0xc0,0x0,0x8,0xfc,0x0,0x0,0xf0,0x10,0x20,0x20,0x40,0x80,0x0,0xc0,0x30,0xe,0x4,
-+0x2,0x2,0x7f,0x4,0x4,0x8,0x10,0x20,0xdf,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x0,0x20,0xf0,0x20,0x20,0x22,0x22,0x1e,0xf0,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x0,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x2,0x2,0x7f,0x4,0x4,0x8,0x10,0x60,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x0,0x20,0xf0,0x20,0x22,0x22,0x1e,0x0,
-+0x0,0x4,0x7f,0x44,0x44,0x44,0x44,0x7c,0x47,0x44,0x44,0x44,0x7c,0x44,0x0,0x0,0x0,0x8,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x0,0x1f,0x10,0x1f,0x10,0x1f,0x0,0x3f,0x1,0x1,0xff,0x1,0x2,0x4,0x18,0x60,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x0,0xf8,0x0,0x4,0xfe,0x0,0x80,0x60,0x1c,0x8,
-+0x0,0x1f,0x10,0x1f,0x10,0x1f,0x0,0x3f,0x0,0x0,0xff,0x2,0x4,0x8,0x1f,0x0,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x0,0xf8,0x0,0x4,0xfe,0x0,0x40,0x20,0xf0,0x10,
-+0x0,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x1,0x1,0xff,0x3,0x5,0x19,0x61,0x1,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x0,0x4,0xfe,0x80,0x60,0x1c,0x8,0x0,
-+0x0,0x1f,0x10,0x1f,0x10,0x1f,0x0,0x3f,0x20,0x20,0x21,0x21,0x42,0x44,0x88,0x10,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x80,0x80,0x40,0x40,0x20,0x10,0xe,0x4,
-+0x0,0x4,0x7f,0x45,0x45,0x45,0x45,0x7d,0x45,0x45,0x45,0x45,0x7d,0x41,0x2,0x4,0x8,0x1c,0xe0,0x0,0x0,0x4,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x0,0x4,0x7e,0x44,0x45,0x46,0x44,0x7c,0x44,0x44,0x45,0x44,0x7c,0x44,0x0,0x0,0x80,0x80,0x84,0xfe,0x4,0x84,0x44,0x44,0x14,0x64,0x84,0x4,0x4,0x44,0x28,0x10,
-+0x0,0x1f,0x10,0x1f,0x10,0x1f,0x1,0x1,0x9,0xa,0x12,0x24,0x4,0x8,0x10,0x60,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x0,0x8,0x18,0xa0,0xc0,0x40,0x20,0x10,0xe,0x4,
-+0x0,0x1f,0x10,0x1f,0x10,0x1f,0x8,0x1f,0x21,0x61,0xa2,0x24,0x20,0x3f,0x0,0x0,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x4,0x4,0xc4,0x44,0x4,0xc4,0x28,0x10,
-+0x10,0x1e,0x22,0x34,0x48,0x16,0x21,0x40,0x9f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x40,0x40,0x60,0x58,0x40,0x46,0xfc,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x0,0x3f,0x20,0x3f,0x20,0x3f,0x4,0x78,0x42,0x42,0x4e,0x72,0x2,0x4,0x18,0x60,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x4,0xfe,0x84,0x84,0x84,0xa4,0x98,0x80,0x80,0x80,
-+0x0,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x2,0x1,0x7f,0x8,0x4,0x4,0xff,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x0,0x8,0xfc,0x20,0x20,0x44,0xfe,0x0,
-+0x10,0xc,0x0,0x3c,0x4,0x5,0x7e,0x16,0x15,0x15,0x24,0x24,0x44,0x84,0x14,0x8,0x0,0x4,0x7e,0x44,0xc4,0x44,0x7c,0x44,0x44,0x44,0xfc,0x84,0x40,0x30,0xe,0x4,
-+0x0,0x5,0x7f,0x45,0x45,0x45,0x45,0x7d,0x45,0x45,0x45,0x45,0x7e,0x42,0x4,0x8,0x4,0xfe,0x4,0x4,0xfc,0x4,0x40,0x44,0x4c,0x50,0x60,0x40,0x42,0x42,0x3e,0x0,
-+0x2,0x3f,0x2,0xff,0x1,0xa,0xf,0x38,0xc7,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0xe0,0x44,0xfe,0x0,0x70,0x84,0x4,0xfc,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,
-+0x0,0x3f,0x20,0x3f,0x20,0x3f,0x0,0x3f,0x20,0x3e,0x22,0x22,0x2a,0x44,0x41,0x80,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x90,0xfc,0x80,0x88,0x50,0x60,0x40,0xa2,0x12,0xe,
-+0x0,0x8,0x7d,0x49,0x4b,0x4d,0x49,0x79,0x49,0x48,0x4f,0x48,0x78,0x48,0x0,0x0,0xa0,0xa4,0x2c,0x30,0x20,0x62,0xa2,0x1e,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x0,0x3f,0x20,0x3f,0x20,0x3f,0x2,0x22,0x12,0x16,0xa,0x72,0x2,0x4,0x18,0x60,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x80,0x90,0xa0,0xc0,0xa0,0x98,0x8a,0x82,0x7e,0x0,
-+0x0,0x1f,0x10,0x1f,0x10,0x1f,0x1,0x3f,0x22,0x42,0xff,0x4,0xc,0x3,0x4,0x18,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x0,0xfc,0x4,0x8,0xfe,0x20,0x40,0x80,0x60,0x10,
-+0x0,0x3,0x7a,0x4a,0x48,0x4b,0x48,0x79,0x4b,0x48,0x48,0x4b,0x78,0x48,0x0,0x0,0x0,0xfe,0x2,0x44,0x40,0xfc,0x80,0x28,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x0,0x0,0x78,0x4f,0x48,0x4b,0x4a,0x7a,0x4b,0x4a,0x4a,0x4b,0x7a,0x4a,0x2,0x2,0x50,0x48,0x40,0xfe,0x48,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x48,0x48,0x68,0x50,
-+0x0,0x8,0x7c,0x48,0x49,0x4a,0x4c,0x7b,0x48,0x48,0x4b,0x4a,0x7a,0x4a,0x3,0x2,0x40,0x40,0xa0,0xa0,0x90,0x4e,0x4,0xf0,0x20,0x48,0xfc,0x8,0x8,0x8,0xf8,0x8,
-+0x1f,0x10,0x1f,0x10,0x1f,0x8,0x1f,0x22,0xd4,0x8,0x37,0xc0,0x1f,0x10,0x10,0x1f,0xf0,0x10,0xf0,0x10,0xf0,0x40,0x60,0x58,0x40,0x46,0xfc,0x8,0xfc,0x8,0x8,0xf8,
-+0x0,0x8,0x7f,0x4c,0x4b,0x48,0x4b,0x7a,0x4a,0x4b,0x4a,0x4a,0x7b,0x40,0xf,0x0,0x80,0x40,0xfe,0x2,0xfc,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x0,0xfe,0x0,
-+0x0,0xb,0x7c,0x4a,0x49,0x49,0x4a,0x7d,0x48,0x48,0x4f,0x48,0x78,0x49,0x2,0x4,0x20,0xa8,0xb4,0xa8,0x10,0x10,0xe,0xf4,0x40,0x44,0xfe,0x40,0xa0,0x10,0xc,0x4,
-+0x0,0xb,0x7d,0x48,0x4f,0x4c,0x48,0x7b,0x48,0x48,0x49,0x49,0x7a,0x4c,0x1,0x6,0x1c,0xe0,0x24,0xa8,0xfe,0x42,0x44,0xfe,0x80,0xf8,0x8,0x50,0x20,0x50,0x8e,0x4,
-+0x0,0x3,0x7a,0x4c,0x4b,0x4a,0x4b,0x7a,0x4b,0x48,0x48,0x4f,0x78,0x49,0x2,0x4,0x0,0xfc,0x4,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x80,0x44,0xfe,0x0,0x10,0xc,0x4,
-+0x2,0x11,0x7f,0x50,0x57,0x54,0x54,0x77,0x50,0x5f,0x50,0x51,0x7f,0x51,0x5,0x2,0x10,0x10,0xd4,0x1e,0xa4,0xc4,0xa4,0xa4,0x24,0xa8,0x90,0x50,0xa8,0x28,0x44,0x82,
-+0x0,0x7,0x70,0x5f,0x50,0x57,0x55,0x75,0x57,0x50,0x57,0x50,0x7f,0x55,0x4,0x8,0x1c,0xe0,0x44,0xfe,0x40,0xfc,0x54,0x54,0xfc,0x40,0xfc,0x40,0xfe,0x24,0x92,0x92,
-+0x0,0x7,0x78,0x4a,0x49,0x4a,0x48,0x79,0x49,0x4b,0x4d,0x49,0x79,0x49,0x1,0x1,0x84,0xbe,0x84,0x94,0x8c,0x94,0xa4,0x10,0xfe,0x10,0xfc,0x10,0xfc,0x10,0xfe,0x0,
-+0x1,0x7,0x78,0x4b,0x48,0x4f,0x48,0x7b,0x49,0x4f,0x4d,0x4f,0x7a,0x4b,0x0,0x1,0x10,0xfc,0x40,0xf8,0x40,0xfc,0x10,0xd8,0x14,0xfe,0x10,0x94,0x8,0x9a,0xaa,0x84,
-+0x3f,0x20,0x3f,0x20,0x3f,0x1,0xff,0x4,0x3f,0x4,0x3f,0x4,0x7f,0xd,0x74,0x6,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xfe,0x40,0xf8,0x40,0xf8,0x40,0xfc,0x10,0xe0,0x1e,
-+0x1,0x1,0x3f,0x1,0x8,0xff,0x8,0x8,0x1f,0x10,0x11,0x11,0x11,0x2,0x4,0x38,0x0,0x10,0xf8,0x0,0x24,0xfe,0x20,0x20,0xf0,0x10,0x10,0x10,0x10,0xc0,0x20,0x18,
-+0x12,0x12,0xff,0x12,0x13,0x10,0x1f,0x0,0x1f,0x10,0x11,0x11,0x11,0x2,0x4,0x38,0x20,0x24,0xfe,0x20,0xe0,0x0,0xf8,0x0,0xf0,0x10,0x10,0x10,0x10,0xc0,0x20,0x18,
-+0x0,0x7d,0x45,0x55,0x55,0x55,0x55,0x55,0x54,0x54,0x54,0x10,0x28,0x25,0x42,0x84,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x90,0x90,0x90,0x90,0x92,0x12,0x12,0x1e,
-+0x4,0x7e,0x44,0x54,0x55,0x57,0x54,0x54,0x55,0x55,0x55,0x11,0x29,0x25,0x45,0x81,0x20,0x20,0x40,0x88,0x4,0xfe,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0xfd,0x10,0x1d,0xf0,0x11,0x62,0x1f,0x10,0x11,0x11,0x11,0x2,0xc,0x30,0x40,0x48,0xfc,0x48,0xc8,0xa8,0xa,0x6,0xf0,0x10,0x10,0x10,0x10,0xc0,0x30,0x8,
-+0x8,0x8,0x2e,0x28,0x28,0x2e,0xf0,0x0,0x1f,0x10,0x11,0x11,0x11,0x2,0x4,0x38,0x80,0x84,0x98,0xe0,0x82,0x82,0x7e,0x10,0xf8,0x10,0x10,0x10,0x10,0xc0,0x30,0x8,
-+0x4,0x7e,0x44,0x57,0x54,0x54,0x54,0x55,0x54,0x54,0x54,0x11,0x28,0x24,0x44,0x81,0x40,0x20,0x4,0xfe,0x40,0x44,0x88,0xf4,0x24,0x48,0x88,0x10,0x28,0x44,0x82,0x2,
-+0x4,0x7e,0x44,0x54,0x54,0x54,0x54,0x55,0x55,0x56,0x54,0x10,0x28,0x24,0x44,0x80,0x4,0xfe,0x84,0x84,0xfc,0xa0,0x90,0x8,0x4e,0x24,0x20,0x0,0xc0,0x30,0x18,0x8,
-+0x0,0x7d,0x45,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x11,0x2a,0x24,0x48,0x80,0x4,0xfe,0x0,0x0,0x7c,0x0,0x0,0xfe,0x52,0x54,0x48,0x48,0x44,0x54,0x62,0x40,
-+0x1,0x1,0x7f,0x9,0x5,0xff,0x5,0x9,0x3f,0xd0,0x11,0x11,0x11,0x12,0x4,0x38,0x0,0x8,0xfc,0x20,0x44,0xfe,0x40,0x20,0xf8,0x16,0x10,0x10,0x10,0xc0,0x20,0x18,
-+0x4,0x7e,0x44,0x57,0x54,0x55,0x54,0x54,0x54,0x54,0x54,0x13,0x28,0x24,0x44,0x80,0x20,0x28,0x24,0xfe,0x20,0x24,0xa8,0xb0,0x30,0x68,0xa8,0x24,0x22,0x20,0xa0,0x40,
-+0x1,0x1,0x7f,0x9,0x9,0x15,0x7f,0x40,0x9f,0x10,0x11,0x11,0x11,0x2,0x4,0x38,0x0,0x8,0xfc,0x20,0x20,0x50,0xfe,0x2,0xf4,0x10,0x10,0x10,0x10,0xc0,0x20,0x18,
-+0x4,0x7e,0x44,0x54,0x55,0x54,0x54,0x55,0x54,0x54,0x54,0x11,0x28,0x24,0x44,0x83,0x20,0x24,0xac,0xb0,0x20,0x50,0x4c,0xa4,0x20,0xa4,0xa8,0x30,0x50,0x48,0x8e,0x4,
-+0x0,0x7c,0x47,0x54,0x55,0x55,0x55,0x55,0x55,0x55,0x54,0x13,0x29,0x24,0x44,0x80,0x30,0x28,0xfe,0x20,0xfc,0x24,0xfc,0x24,0xfc,0x24,0x8,0xfe,0x8,0x88,0xa8,0x10,
-+0x10,0x11,0x15,0x1f,0x11,0x11,0x15,0x7f,0x45,0x45,0x45,0x44,0x7c,0x44,0x1,0x6,0x4,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x34,0x50,0x50,0x92,0x12,0xe,
-+0x8,0x49,0x49,0x49,0x7f,0x0,0x7f,0x1,0x1,0x3f,0x21,0x20,0x23,0x2c,0x30,0x3,0x4,0x7e,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x18,0x28,0x28,0x4a,0x8a,0x6,
-+0x0,0x1,0xff,0x8,0x8,0x2a,0x2a,0x2a,0x5d,0x88,0x8,0xf,0xf8,0x40,0x0,0x3,0x4,0x7e,0xc4,0x54,0x54,0x54,0x54,0x54,0x54,0xd4,0x18,0xa8,0x28,0x4a,0x8a,0x6,
-+0x8,0xa,0x7f,0x8,0x8,0xff,0x25,0x14,0x64,0x14,0xff,0x4,0x8,0xc,0x12,0x61,0x4,0x7e,0x44,0x54,0x54,0xd4,0x54,0x54,0x54,0x54,0x18,0x28,0x28,0x4a,0x8a,0x6,
-+0x8,0x8,0x14,0x14,0x22,0x7f,0x80,0x71,0x55,0x75,0x55,0x75,0x51,0x55,0x52,0x3,0x4,0x7e,0x44,0x54,0x54,0x54,0xd4,0x54,0x54,0x54,0x18,0x28,0x28,0x4a,0x8a,0x6,
-+0x14,0x14,0x7f,0x14,0x7f,0x14,0xff,0x8,0x7f,0x49,0x7f,0x49,0xff,0x41,0x45,0x43,0x4,0x7e,0x44,0x54,0x54,0x54,0xd4,0x54,0x54,0x54,0x18,0x28,0xa8,0x4a,0x8a,0x6,
-+0x22,0x22,0xff,0x22,0x3e,0x8,0x7f,0x49,0x7f,0x8,0x7f,0x8,0x7f,0x8,0xff,0x1,0x4,0x7e,0xc4,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x18,0x28,0x28,0x4a,0x8a,0x6,
-+0xa,0xf,0x8,0x7f,0x49,0x4e,0x79,0x4f,0x40,0x4a,0x6a,0x5b,0x4a,0x4a,0xbf,0x1,0x4,0x7e,0x44,0xd4,0x54,0x54,0x54,0x54,0x54,0x54,0x98,0x28,0x28,0x4a,0x8a,0x6,
-+0x8,0x8,0x8,0x17,0x30,0x50,0x91,0x19,0x9,0xf,0x11,0x21,0xff,0x1,0x1,0x1,0xa0,0x94,0x9e,0xe0,0x80,0x44,0x34,0xc,0x20,0xf0,0x0,0x4,0xfe,0x0,0x0,0x0,
-+0x7d,0x5,0x7d,0x44,0x41,0x7d,0x5,0x28,0x13,0x11,0x1f,0x21,0xff,0x1,0x1,0x1,0xfc,0x4,0xfc,0x20,0xfc,0x24,0xfc,0x28,0xfc,0x2,0xf8,0x0,0xfe,0x0,0x0,0x0,
-+0x8,0x8,0x28,0x28,0x3e,0x48,0x48,0x88,0xe,0x18,0x68,0x8,0x8,0x8,0x8,0x8,0x80,0x80,0x80,0x84,0x8c,0x90,0xa0,0xc0,0x80,0x80,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x8,0x8,0x2b,0x28,0x3e,0x48,0x49,0x88,0xe,0x18,0x6b,0x8,0x8,0x8,0x8,0x8,0x8,0x1c,0xe0,0x40,0x40,0x5c,0xe0,0x40,0x44,0x7e,0xc0,0x40,0x42,0x42,0x3e,0x0,
-+0x8,0x8,0x28,0x28,0x3e,0x4b,0x48,0x88,0xe,0x19,0x69,0x9,0x9,0x9,0x9,0x9,0x20,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x24,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x8,0xb,0x28,0x28,0x3f,0x48,0x48,0x88,0xf,0x18,0x69,0x9,0x9,0x9,0x9,0x9,0x8,0xfc,0x40,0x48,0xfc,0x88,0x88,0x88,0xfe,0x0,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x8,0x8,0x28,0x28,0x3e,0x49,0x48,0x8b,0xe,0x18,0x69,0x9,0x9,0x9,0x9,0x9,0x20,0x20,0xa0,0xa8,0xfc,0x20,0x24,0xfe,0x0,0x4,0xfe,0x4,0x4,0x4,0xfc,0x4,
-+0x8,0x8,0x2b,0x28,0x3e,0x49,0x4f,0x88,0xd,0x19,0x69,0x9,0x9,0x8,0x8,0x8,0x40,0x48,0xfc,0xa0,0x98,0x8,0xfe,0x8,0xe8,0x28,0x28,0x28,0xe8,0x8,0x28,0x10,
-+0x8,0x9,0x29,0x29,0x3f,0x49,0x4b,0x8d,0x9,0x19,0x6f,0x8,0x9,0x9,0xa,0xc,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x8,0x8,0xfe,0x0,0x10,0x8,0x4,0x4,
-+0x10,0x10,0x57,0x51,0x7d,0x92,0x14,0x17,0x19,0x35,0xd5,0x12,0x13,0x12,0x14,0x18,0x10,0x10,0x7c,0x14,0xfe,0x14,0x7c,0x10,0x7c,0x10,0xfe,0x10,0x10,0x96,0x7c,0x0,
-+0x10,0x10,0x53,0x52,0x7e,0x93,0x12,0x12,0x1f,0x33,0xd3,0x15,0x15,0x19,0x11,0x11,0x40,0x24,0xfe,0x4,0x4,0xfc,0x0,0x4,0xfe,0x54,0x54,0xfc,0x54,0x54,0x54,0xc,
-+0x10,0x10,0x5f,0x50,0x7b,0x92,0x13,0x10,0x1f,0x34,0xd5,0x15,0x15,0x15,0x14,0x14,0x80,0x44,0xfe,0x0,0xf8,0x8,0xf8,0x0,0xfc,0x4,0xf4,0x14,0x14,0xf4,0x14,0x8,
-+0x8,0x7f,0x8,0x3e,0x8,0x7e,0x9,0x0,0x7f,0x1,0x3f,0x1,0xff,0x1,0x5,0x2,0x4,0xfe,0x44,0x44,0x44,0x94,0x8,0xf0,0x0,0x10,0xf8,0x0,0xfe,0x0,0x0,0x0,
-+0x10,0x9,0x41,0x26,0x8,0x70,0x23,0xc,0x7f,0x1,0x3f,0x1,0xff,0x1,0x5,0x2,0x40,0x50,0x4c,0x54,0x60,0xc0,0x0,0xf0,0x0,0x10,0xf8,0x0,0xfe,0x0,0x0,0x0,
-+0x0,0xc,0xf2,0x12,0x14,0x78,0x17,0x12,0x1e,0xf2,0x12,0x14,0x24,0x29,0x40,0x0,0x0,0x86,0xb8,0x88,0x48,0x3e,0x88,0x88,0x88,0xfe,0x88,0x88,0x88,0x88,0x28,0x10,
-+0x0,0xd,0xf1,0x12,0x14,0x78,0x17,0x10,0x17,0xfc,0x14,0x14,0x24,0x27,0x20,0x40,0x0,0x6,0x38,0x88,0x48,0x3e,0xc8,0x8,0xc8,0x7e,0x48,0x48,0x48,0xc8,0x28,0x10,
-+0x0,0x3e,0x23,0x3e,0x21,0x3e,0x62,0xbe,0x0,0x3f,0x1,0x1f,0x1,0xff,0x1,0x3,0x40,0x28,0xfc,0x50,0xfe,0x20,0xf8,0x20,0x20,0xf8,0x0,0xf0,0x4,0xfe,0x0,0x0,
-+0x2,0x3f,0x2,0xff,0x2,0xf,0x34,0xc7,0x0,0x3f,0x2,0x1f,0x2,0xff,0x2,0x1,0x20,0xc0,0x84,0xfe,0x0,0xe0,0x8,0xf8,0x30,0xc0,0x0,0xf0,0x0,0xfa,0x2,0xfe,
-+0x4,0x1e,0xf0,0x10,0x11,0x10,0x7d,0x11,0x11,0x1e,0xf3,0x10,0x10,0x10,0xf,0x0,0x40,0x40,0x88,0x84,0xfc,0x20,0x28,0xfc,0x20,0x24,0xfe,0x20,0x22,0x22,0xfe,0x0,
-+0x3f,0x1,0x1f,0x1,0x7f,0x1,0x0,0x4,0x79,0x10,0x7c,0x10,0xff,0x10,0x14,0x18,0xf8,0x0,0xf0,0x0,0xf8,0x2,0xfe,0x0,0xf8,0x40,0xf8,0x40,0xfc,0x40,0x42,0x3e,
-+0x0,0x18,0xe0,0x2e,0x23,0x24,0xf4,0x2e,0x22,0x22,0xfb,0x24,0x2a,0x31,0x20,0x1f,0x20,0x28,0xfc,0x28,0xfe,0x28,0xf8,0x20,0xf8,0x20,0xfc,0x20,0x22,0xfe,0x2,0xfe,
-+0x10,0x10,0x25,0x7e,0x10,0xff,0x28,0x4c,0x92,0x24,0x49,0x12,0x64,0x8,0x30,0xc0,0x8,0x3c,0xe0,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x22,0x22,0x1e,
-+0x8,0x8,0x15,0x22,0x7f,0x80,0x71,0x55,0x55,0x75,0x55,0x55,0x75,0x51,0x55,0x52,0x8,0x3c,0xe0,0x20,0x20,0xa8,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x22,0x22,0x1e,
-+0x8,0x49,0x2a,0x7f,0x41,0x5d,0x55,0x5d,0x41,0x3f,0x2,0x1f,0x2,0xff,0x2,0x1,0x20,0x20,0x24,0x7e,0xa8,0x10,0x28,0xc6,0x30,0xc0,0x0,0xf0,0x0,0xfa,0x2,0xfe,
-+0x1,0x39,0xe2,0x27,0x2a,0x23,0xf2,0x2f,0x20,0x23,0xfa,0x23,0x22,0x23,0x20,0x1f,0x0,0xf0,0x20,0xf8,0x48,0xf8,0x48,0xfe,0x0,0xf8,0x8,0xf8,0x8,0xfa,0x2,0xfe,
-+0x2,0x39,0xe7,0x21,0x25,0x23,0xf1,0x2f,0x20,0x23,0xfa,0x23,0x22,0x23,0x20,0x1f,0x10,0x20,0xfc,0x20,0x28,0x30,0x24,0xfe,0x0,0xf0,0x10,0xf0,0x10,0xf2,0x2,0xfe,
-+0x77,0x55,0x77,0x55,0x77,0x55,0x77,0x24,0x3f,0x64,0x7f,0xa4,0x3f,0x24,0x3f,0x20,0x8,0x3c,0xe0,0x20,0x20,0x28,0xfc,0x20,0xa0,0x24,0xfe,0x20,0x20,0x22,0xa2,0x1e,
-+0x10,0x1f,0x20,0x2f,0x40,0xbf,0x0,0x2,0x2,0x2,0x2,0x2,0x4,0x4,0x8,0x10,0x4,0xfe,0x0,0xf8,0x0,0xf8,0x8,0x8,0x8,0x8,0x8,0x8,0x8,0xa,0xa,0x4,
-+0x10,0x1f,0x20,0x2f,0x40,0xbf,0x0,0x8,0x8,0x8,0x8,0x8,0x10,0x10,0x20,0x40,0x4,0xfe,0x0,0xf8,0x0,0xf8,0x8,0x88,0x88,0x88,0x88,0x88,0x88,0x8a,0x8a,0x84,
-+0x10,0x1f,0x20,0x2f,0x40,0xbf,0x2,0x2,0x22,0x22,0x22,0x22,0x22,0x3f,0x0,0x0,0x4,0xfe,0x0,0xf8,0x0,0xf8,0x8,0x8,0x28,0x28,0x28,0x28,0x28,0xea,0x2a,0x4,
-+0x10,0x1f,0x20,0x2f,0x40,0xbf,0x0,0x12,0x12,0x12,0x12,0x12,0x12,0x22,0x22,0x40,0x4,0xfe,0x0,0xf8,0x0,0xf8,0x8,0x48,0x48,0x48,0x48,0x48,0x48,0x4a,0x4a,0x44,
-+0x10,0x1f,0x20,0x2f,0x40,0xbf,0x4,0xf,0x10,0x6d,0x2,0xd,0x76,0x1,0xc,0x3,0x4,0xfe,0x0,0xf8,0x0,0xf8,0x8,0xc8,0x88,0x8,0x8,0x88,0x78,0xa,0xa,0x4,
-+0x10,0x1f,0x20,0x2f,0x40,0xbf,0x0,0x7f,0x9,0x49,0x29,0x29,0x9,0x9,0xff,0x0,0x4,0xfe,0x0,0xf8,0x0,0xf8,0x8,0xe8,0x8,0x28,0x48,0x88,0x8,0xa,0xfa,0x4,
-+0x10,0x1f,0x20,0x2f,0x40,0xbf,0x0,0x3f,0x22,0x22,0x2f,0x22,0x25,0x28,0x3f,0x20,0x4,0xfe,0x0,0xf8,0x0,0xf8,0x8,0xe8,0x28,0x28,0xa8,0x28,0x28,0xaa,0xea,0x24,
-+0x10,0x1f,0x20,0x2f,0x40,0xbf,0x4,0x7f,0x4,0x3f,0x20,0x3f,0xa,0xa,0x12,0x61,0x4,0xfe,0x0,0xf8,0x0,0xf8,0x8,0xe8,0x8,0x88,0x88,0x88,0x8,0x2a,0x2a,0xe4,
-+0x10,0x1f,0x20,0x2f,0x40,0xbf,0x0,0x3f,0x26,0x3f,0x0,0x7f,0x49,0x49,0xff,0x0,0x4,0xfe,0x0,0xf8,0x0,0xf8,0x8,0xc8,0x48,0xc8,0x8,0xe8,0x28,0x2a,0xfa,0x4,
-+0x10,0x10,0x11,0x1f,0x22,0x42,0x12,0x12,0x12,0x14,0x14,0x8,0x14,0x22,0x43,0x81,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,
-+0x8,0x8,0xa,0xff,0x8,0x7f,0x49,0x49,0x7f,0x49,0x1c,0x2b,0x49,0x88,0x9,0xa,0x40,0x40,0x44,0x7e,0x48,0x88,0x48,0x48,0x48,0x50,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x8,0x10,0x7e,0x42,0x7e,0x42,0x7f,0x10,0xa,0xff,0x10,0x1e,0x22,0x22,0x4b,0x86,0x40,0x40,0x44,0x7e,0x88,0x88,0x48,0x48,0x48,0x50,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x8,0x48,0x4b,0x48,0x4b,0x7c,0x41,0x40,0x7a,0x49,0x48,0x4f,0x48,0x48,0x88,0x3,0x40,0x48,0xfc,0x40,0xfe,0x2,0x24,0xa0,0x20,0x20,0x24,0xfe,0x40,0x50,0x8c,0x4,
-+0x9,0x49,0x4f,0x49,0x49,0x7d,0x41,0x41,0x78,0x48,0x4b,0x48,0x48,0x49,0x8a,0x8,0x48,0x48,0xfe,0x48,0x48,0x78,0x0,0xfc,0x20,0x24,0xfe,0x70,0xa8,0x2e,0x24,0x20,
-+0x10,0x50,0x57,0x54,0x57,0x7c,0x47,0x44,0x75,0x55,0x55,0x55,0x55,0x55,0x99,0x11,0x40,0x24,0xfe,0x4,0xfc,0x28,0xfe,0x20,0xfc,0x24,0xfc,0x24,0xfc,0x24,0x24,0x2c,
-+0x0,0x0,0x3f,0x11,0x9,0x9,0x7f,0x2,0xff,0x4,0x7,0xa,0x11,0x20,0x43,0x1c,0x10,0x78,0x80,0x10,0x10,0x20,0xfc,0x0,0xfe,0x0,0xf0,0x20,0x40,0x80,0x60,0x1e,
-+0x4,0xe,0xf0,0x3,0x93,0x55,0x1,0x9,0xff,0x9,0x49,0x29,0x9,0xa,0x2c,0x11,0x24,0x3e,0x20,0xfe,0x22,0xf8,0x24,0x3c,0x0,0x78,0x48,0x48,0x48,0x4a,0x8a,0x6,
-+0x2,0x3f,0x22,0x22,0x22,0x3e,0x22,0x22,0x22,0x3e,0x22,0x22,0x42,0x42,0x8a,0x4,0x8,0x8,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x8,0x8,0x28,0x10,
-+0x4,0x3e,0x24,0x24,0x24,0x3f,0x24,0x24,0x24,0x3c,0x24,0x24,0x44,0x44,0x94,0x8,0x8,0xfc,0x0,0x0,0x4,0xfe,0x80,0x80,0x84,0xfe,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x2,0x3f,0x22,0x22,0x22,0x3e,0x22,0x22,0x22,0x3e,0x22,0x22,0x42,0x42,0x8a,0x4,0x8,0x18,0x20,0x40,0x84,0xc,0x10,0x20,0x40,0x80,0x4,0xc,0x10,0x20,0x40,0x80,
-+0x2,0x1,0xff,0x10,0x10,0x1f,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x10,0x10,0x0,0x4,0xfe,0x0,0x10,0xf8,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x10,0x10,0x50,0x20,
-+0x4,0x3e,0x24,0x24,0x25,0x3c,0x24,0x24,0x27,0x3c,0x24,0x24,0x44,0x45,0x95,0xa,0x88,0x88,0x88,0x88,0xfe,0x88,0x88,0x88,0xfe,0x88,0x88,0x88,0x88,0x8,0x8,0x8,
-+0x4,0x3f,0x24,0x24,0x24,0x3c,0x27,0x24,0x24,0x3c,0x24,0x24,0x44,0x45,0x96,0x8,0x8,0xfc,0x0,0x0,0x0,0x4,0xfe,0x90,0x90,0x90,0x90,0x90,0x92,0x12,0xe,0x0,
-+0x4,0x3e,0x24,0x24,0x24,0x3f,0x24,0x24,0x24,0x3c,0x24,0x24,0x44,0x44,0x95,0xa,0x20,0x20,0x20,0x20,0x24,0xfe,0x20,0x50,0x50,0x50,0x50,0x88,0xc8,0xa8,0x6,0x4,
-+0x4,0x3e,0x24,0x24,0x27,0x3c,0x24,0x24,0x24,0x3d,0x25,0x26,0x44,0x44,0x95,0x8,0x40,0x40,0x40,0x44,0xfe,0x80,0x80,0xa0,0xa0,0x20,0x40,0x50,0x48,0x84,0xfc,0x4,
-+0x4,0x3e,0x24,0x27,0x24,0x3d,0x25,0x25,0x25,0x3d,0x24,0x24,0x44,0x44,0x94,0x8,0x20,0x20,0x24,0xfe,0x20,0x24,0x24,0x24,0x24,0xfc,0x24,0x20,0x22,0x22,0x1e,0x0,
-+0x4,0x3e,0x24,0x24,0x25,0x3d,0x25,0x25,0x25,0x3d,0x25,0x25,0x45,0x45,0x95,0x9,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x54,0x4c,0x8c,0x4,0x4,0x14,0x8,
-+0x10,0xc,0x3,0xc,0x12,0xff,0x4,0x8,0x1f,0x28,0xcf,0x8,0xf,0x8,0x8,0x8,0x10,0x70,0x80,0x60,0x14,0xfe,0x0,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0x50,0x20,
-+0x4,0x3e,0x24,0x24,0x24,0x3d,0x26,0x24,0x24,0x3c,0x24,0x24,0x44,0x44,0x95,0xa,0x80,0x80,0x80,0xfe,0x82,0x24,0x20,0x20,0x20,0x20,0x50,0x50,0x88,0x88,0x6,0x4,
-+0x4,0x3e,0x24,0x24,0x27,0x3c,0x24,0x24,0x24,0x3c,0x24,0x24,0x45,0x45,0x96,0x8,0x80,0xa0,0x90,0x94,0xfe,0xa0,0xa4,0xa4,0xa8,0xa8,0xb0,0xa0,0x62,0x22,0x1e,0x0,
-+0x4,0x3e,0x24,0x27,0x24,0x3c,0x25,0x25,0x27,0x3c,0x24,0x24,0x45,0x46,0x94,0x8,0x40,0x40,0x44,0xfe,0x80,0xa0,0x20,0x24,0xfe,0x20,0xa8,0xa4,0x26,0x22,0xa0,0x40,
-+0x4,0x3e,0x24,0x24,0x24,0x3c,0x24,0x27,0x24,0x3c,0x24,0x24,0x44,0x44,0x94,0x8,0x40,0x40,0x48,0x7c,0x40,0x40,0x44,0xfe,0x40,0x40,0x60,0x50,0x4c,0x44,0x40,0x40,
-+0x4,0x3e,0x24,0x24,0x25,0x3d,0x25,0x25,0x25,0x3d,0x25,0x25,0x45,0x45,0x95,0xa,0x24,0x3e,0x20,0x24,0xfe,0x4,0x4,0x4,0xfc,0x4,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x3d,0x25,0x25,0x25,0x3d,0x25,0x25,0x25,0x3d,0x25,0x24,0x44,0x44,0x94,0x8,0x4,0xfe,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0xfc,0x24,0x20,0x20,0x20,0x20,0x20,
-+0x0,0x3c,0x24,0x25,0x25,0x3d,0x25,0x25,0x25,0x3d,0x25,0x25,0x45,0x44,0x94,0x8,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0xfc,0x24,0x20,0x20,0x20,
-+0x1,0x1,0x3f,0x21,0x3f,0x21,0x3f,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x10,0x0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x10,0x50,0x20,
-+0x4,0x3e,0x24,0x24,0x25,0x3d,0x26,0x24,0x24,0x3c,0x24,0x24,0x44,0x44,0x94,0x8,0x80,0x80,0x84,0xfe,0x40,0x40,0x48,0x7c,0x40,0x48,0x7c,0x40,0x40,0x40,0x40,0x40,
-+0x4,0x3e,0x25,0x25,0x25,0x3d,0x25,0x25,0x25,0x3d,0x25,0x25,0x45,0x45,0x96,0x8,0x8,0x1c,0xe0,0x10,0x50,0x50,0x50,0x50,0x48,0x48,0x48,0x44,0x54,0x54,0x72,0x0,
-+0x4,0x3e,0x24,0x24,0x25,0x3e,0x24,0x24,0x25,0x3c,0x24,0x25,0x44,0x44,0x94,0xb,0x40,0x40,0xa0,0xa0,0x18,0x36,0x40,0x88,0x10,0x20,0x44,0x88,0x10,0x20,0xc0,0x0,
-+0x4,0x3e,0x24,0x24,0x25,0x3e,0x24,0x24,0x24,0x3c,0x24,0x24,0x44,0x44,0x94,0x8,0x80,0x80,0x84,0xfe,0x4,0x4,0xf4,0x94,0x94,0x94,0x94,0xf4,0x84,0x4,0x14,0x8,
-+0x4,0x3e,0x25,0x25,0x25,0x3d,0x25,0x25,0x25,0x3d,0x25,0x25,0x45,0x45,0x95,0x9,0x8,0x1c,0xe0,0x20,0x20,0x20,0x24,0xfe,0x20,0x10,0x10,0x10,0x2a,0x4a,0xa6,0x12,
-+0x4,0x3f,0x24,0x24,0x24,0x3c,0x24,0x27,0x24,0x3d,0x24,0x24,0x44,0x44,0x97,0x8,0x0,0xfc,0x8,0x10,0x20,0x58,0x86,0x2,0x0,0xfc,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x4,0x3e,0x25,0x24,0x24,0x3c,0x27,0x24,0x24,0x3c,0x24,0x24,0x44,0x45,0x96,0x8,0x20,0x20,0x24,0xac,0xb0,0x24,0xfe,0x50,0x50,0x50,0x50,0x90,0x92,0x12,0xe,0x0,
-+0x0,0x3d,0x25,0x25,0x25,0x3d,0x25,0x25,0x25,0x3d,0x25,0x25,0x45,0x45,0x95,0x9,0x4,0xfe,0x4,0x14,0xfc,0x4,0x4,0x74,0x54,0x54,0x54,0x74,0x4,0x4,0x14,0x8,
-+0x0,0x3d,0x25,0x25,0x25,0x3d,0x25,0x25,0x25,0x3d,0x25,0x25,0x45,0x45,0x95,0x9,0x4,0xfe,0x4,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0x54,0x4c,0x8c,0x4,0xfc,0x4,
-+0x4,0x3e,0x24,0x24,0x25,0x3e,0x24,0x24,0x24,0x3f,0x24,0x24,0x44,0x44,0x95,0x8,0x20,0x20,0x50,0x88,0x6,0x10,0xf8,0x0,0x4,0xfe,0x40,0x40,0x48,0x84,0xfc,0x4,
-+0x0,0x3d,0x24,0x24,0x24,0x3c,0x25,0x24,0x27,0x3c,0x24,0x25,0x46,0x44,0x94,0x8,0x0,0x8,0x90,0x60,0x50,0x8c,0x24,0x20,0xfe,0x20,0xa8,0x26,0x22,0x20,0xa0,0x40,
-+0x4,0x3e,0x24,0x27,0x24,0x3c,0x24,0x25,0x24,0x3c,0x24,0x25,0x44,0x44,0x94,0x9,0x40,0x20,0x4,0xfe,0x40,0x48,0x88,0xf4,0x24,0x48,0x88,0x10,0x28,0x44,0x82,0x2,
-+0x5,0x3e,0x24,0x27,0x24,0x3c,0x24,0x24,0x27,0x3c,0x24,0x24,0x45,0x45,0x96,0x8,0x8,0x90,0x0,0xfc,0x90,0x90,0x90,0x94,0xfe,0x90,0x90,0x90,0x10,0x10,0x10,0x10,
-+0x4,0x3e,0x24,0x24,0x25,0x3c,0x24,0x24,0x27,0x3c,0x24,0x24,0x44,0x44,0x95,0xa,0x0,0x88,0x50,0x0,0xfc,0x20,0x20,0x24,0xfe,0x20,0x50,0x50,0x88,0x88,0x4,0x2,
-+0x4,0x3e,0x25,0x24,0x24,0x3c,0x27,0x24,0x24,0x3c,0x24,0x24,0x45,0x46,0x94,0x8,0x20,0x20,0x24,0xa4,0xa8,0x20,0xfe,0x20,0x60,0x70,0xa8,0xa8,0x26,0x24,0x20,0x20,
-+0x0,0x3c,0x27,0x24,0x24,0x3d,0x26,0x24,0x25,0x3e,0x24,0x25,0x46,0x44,0x94,0x8,0x0,0x4,0xfe,0x40,0x84,0x4c,0x70,0xa0,0x30,0x70,0xa8,0x28,0x26,0x24,0xa0,0x40,
-+0x0,0x3d,0x25,0x25,0x25,0x3d,0x24,0x24,0x25,0x3d,0x25,0x25,0x45,0x45,0x95,0x9,0x4,0xfe,0x4,0x4,0x4,0xfc,0x20,0x24,0xfe,0x24,0x24,0x54,0x8c,0x4,0x14,0x8,
-+0x4,0x3e,0x24,0x24,0x24,0x3d,0x26,0x24,0x24,0x3d,0x24,0x24,0x44,0x44,0x97,0x8,0x20,0x20,0xa8,0xa8,0xa8,0x74,0x22,0x20,0x28,0xfc,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x4,0x3e,0x25,0x25,0x24,0x3c,0x25,0x24,0x24,0x3c,0x27,0x24,0x44,0x44,0x94,0x8,0x8,0x1c,0xe0,0x4,0xa4,0xa8,0xfc,0x10,0x20,0x24,0xfe,0x20,0x20,0x20,0xa0,0x40,
-+0x4,0x3e,0x25,0x25,0x26,0x3c,0x24,0x24,0x27,0x3c,0x24,0x24,0x44,0x45,0x96,0x8,0x40,0x20,0xfe,0x2,0x14,0xf8,0x0,0x4,0xfe,0x90,0x90,0x90,0x92,0x12,0xe,0x0,
-+0x0,0x7b,0x4a,0x4a,0x4b,0x7a,0x4a,0x4b,0x4a,0x7a,0x4a,0x4a,0x4b,0x4a,0xac,0x10,0x4,0xfe,0x4,0x4,0xfc,0x20,0x24,0xa8,0xb0,0xa8,0xa8,0xa4,0x24,0x22,0xa0,0x40,
-+0x4,0x3e,0x27,0x24,0x25,0x3c,0x27,0x24,0x25,0x3d,0x25,0x25,0x45,0x45,0x95,0x9,0x20,0x24,0xfe,0x20,0xfc,0x20,0xfe,0x0,0xfc,0x4,0xfc,0x4,0xfc,0x4,0x14,0x8,
-+0x8,0x7c,0x48,0x4f,0x48,0x79,0x4a,0x4f,0x4a,0x7b,0x4a,0x4b,0x4a,0x48,0xa8,0x10,0x40,0x40,0x44,0xfe,0xa0,0x10,0x48,0xfe,0x48,0xf8,0x48,0xf8,0x48,0x40,0x44,0x3c,
-+0x4,0x3e,0x24,0x27,0x24,0x3c,0x24,0x27,0x24,0x3c,0x24,0x27,0x44,0x44,0x94,0x8,0x50,0x50,0x54,0xde,0x50,0x50,0x54,0xde,0x50,0x50,0x54,0xde,0x50,0x50,0x50,0x50,
-+0x4,0x3e,0x25,0x25,0x25,0x3d,0x25,0x25,0x25,0x3d,0x24,0x24,0x44,0x45,0x96,0x8,0x20,0xa4,0x2e,0x24,0x24,0xac,0x24,0x24,0xfc,0x24,0x50,0x50,0x88,0x6,0x4,0x0,
-+0x0,0x7a,0x4b,0x4a,0x4c,0x79,0x48,0x48,0x4b,0x78,0x49,0x49,0x49,0x4a,0xa8,0x10,0x40,0x20,0xfe,0x2,0x4,0xfc,0x0,0x4,0xfe,0x20,0x20,0x28,0x26,0x22,0xa0,0x40,
-+0x0,0x78,0x4b,0x4a,0x4c,0x78,0x4b,0x48,0x48,0x79,0x49,0x49,0x49,0x4a,0xac,0x10,0x40,0x20,0xfe,0x2,0x4,0x0,0xfe,0x20,0x20,0x28,0x3c,0x20,0x20,0xa6,0x7c,0x0,
-+0x0,0x78,0x4f,0x49,0x49,0x79,0x4a,0x4f,0x49,0x79,0x4d,0x4b,0x49,0x4a,0xac,0x10,0x10,0x10,0x7c,0x14,0xfe,0x14,0x7c,0x10,0x7c,0x10,0xfe,0x10,0x10,0x96,0x7c,0x0,
-+0x8,0x7c,0x4b,0x48,0x4b,0x78,0x4f,0x48,0x49,0x7b,0x4c,0x4b,0x48,0x48,0xa8,0x13,0x40,0x48,0xfc,0x40,0xfc,0x40,0xfe,0xa0,0x10,0xf8,0x46,0xf8,0x40,0xa0,0x98,0x8,
-+0x0,0x3c,0x27,0x24,0x24,0x3d,0x25,0x25,0x25,0x3d,0x25,0x25,0x45,0x45,0x95,0x9,0x20,0x24,0xfe,0x20,0x24,0xfe,0x4,0x54,0xfc,0x24,0x24,0xfc,0x24,0x24,0x24,0xc,
-+0x8,0x7c,0x4b,0x48,0x48,0x7b,0x4a,0x4a,0x4a,0x7a,0x4a,0x4a,0x4a,0x4a,0xab,0x12,0x0,0x4,0xfe,0x40,0x84,0xfe,0x94,0x94,0xf4,0x94,0x94,0xf4,0x94,0x94,0xfc,0x4,
-+0x8,0x7d,0x49,0x49,0x49,0x79,0x49,0x49,0x48,0x7b,0x4a,0x4a,0x4a,0x4a,0xaf,0x10,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x0,0xfc,0x94,0x94,0x94,0x94,0xfe,0x0,
-+0x0,0x7b,0x4a,0x4a,0x4b,0x78,0x4b,0x48,0x4f,0x79,0x49,0x48,0x48,0x48,0xa8,0x10,0x8,0xbc,0xa8,0xa8,0xb8,0x0,0xf8,0x0,0xfe,0x0,0xf8,0x8,0x8,0x88,0x50,0x20,
-+0x8,0x7c,0x48,0x49,0x4b,0x7c,0x4b,0x4a,0x4a,0x7b,0x4a,0x4a,0x4b,0x4a,0xaa,0x12,0x40,0x40,0xa0,0x10,0xf8,0x6,0xc4,0x54,0x54,0xd4,0x54,0x54,0xd4,0x44,0x54,0xc8,
-+0x0,0x7a,0x49,0x48,0x4b,0x78,0x4f,0x48,0x49,0x7a,0x4c,0x4b,0x48,0x48,0xab,0x10,0x40,0x48,0x50,0x40,0xfc,0x40,0xfe,0xa0,0x10,0x4e,0x44,0xf8,0x40,0x48,0xfc,0x0,
-+0x0,0x7a,0x49,0x4b,0x48,0x7f,0x48,0x49,0x4a,0x7c,0x4f,0x48,0x49,0x48,0xa9,0x16,0x40,0x48,0x50,0xfc,0x40,0xfe,0xa0,0x10,0x4e,0x44,0xfe,0x90,0x10,0xe0,0x18,0x4,
-+0x0,0x7b,0x48,0x49,0x49,0x79,0x49,0x48,0x4b,0x7a,0x4a,0x4b,0x4a,0x4a,0xaa,0x12,0x4,0xfe,0x0,0xfc,0x4,0x4,0xfc,0x0,0xfe,0x8a,0x52,0xfe,0x22,0x22,0x2a,0x4,
-+0x10,0x8,0xfe,0x11,0x1e,0x22,0x2a,0x44,0x9f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x10,0x40,0x44,0xfe,0x18,0xe4,0xa8,0x90,0xc8,0xf6,0x10,0xf0,0x10,0xf0,0x10,0x50,0x20,
-+0x8,0x7c,0x4b,0x4a,0x4c,0x79,0x49,0x49,0x49,0x79,0x49,0x4f,0x48,0x48,0xa9,0x12,0x40,0x20,0xfe,0x2,0x34,0xc0,0x8,0xfc,0x10,0x10,0x14,0xfe,0x0,0x90,0xc,0x4,
-+0x0,0x7a,0x49,0x48,0x4f,0x78,0x4f,0x48,0x49,0x7a,0x4d,0x49,0x48,0x49,0xaa,0x10,0x40,0x48,0x50,0x40,0xfc,0x40,0xfe,0xa0,0x10,0x4e,0x54,0x50,0xe0,0x50,0x4c,0xc0,
-+0x0,0x78,0x4b,0x4a,0x4d,0x78,0x4b,0x48,0x48,0x79,0x48,0x49,0x48,0x48,0xab,0x10,0x40,0x20,0xfe,0x52,0x8c,0x0,0xfe,0x40,0x88,0xfc,0x20,0xfc,0x20,0x24,0xfe,0x0,
-+0x8,0x7d,0x48,0x48,0x4b,0x7a,0x4d,0x49,0x49,0x79,0x48,0x49,0x49,0x49,0xa9,0x11,0x20,0xfc,0x88,0x50,0xfe,0x22,0xfc,0x24,0x24,0x2c,0x20,0xfc,0x4,0x4,0xfc,0x4,
-+0x1,0x79,0x4f,0x49,0x4b,0x78,0x4b,0x4a,0x4a,0x7a,0x4b,0x48,0x4a,0x49,0xae,0x10,0x8,0x8,0xc8,0x3e,0x88,0x8,0xbe,0xa2,0xa2,0x94,0x94,0x8,0x88,0xd4,0x14,0x62,
-+0x8,0x7f,0x48,0x4b,0x4a,0x7c,0x48,0x4b,0x48,0x79,0x4a,0x49,0x4a,0x49,0xaa,0x10,0x88,0xfe,0x88,0xfe,0x2,0xf8,0x0,0xfe,0x80,0x44,0xa8,0x70,0xa8,0x26,0xa4,0x40,
-+0x9,0x7d,0x49,0x49,0x48,0x7b,0x4a,0x4a,0x4b,0x78,0x4f,0x48,0x48,0x49,0xaa,0x10,0xfc,0x4,0x4,0xfc,0x0,0xde,0x52,0x52,0xde,0x20,0xfe,0x70,0xa8,0x2e,0x24,0x20,
-+0x8,0x7f,0x48,0x4b,0x4a,0x7a,0x4a,0x4b,0x48,0x7b,0x4a,0x4b,0x4a,0x4b,0xa8,0x17,0x40,0xfe,0x0,0xfc,0x94,0xf4,0x94,0xfc,0x0,0xfc,0x4,0xfc,0x4,0xfc,0x0,0xfe,
-+0x8,0x7c,0x4b,0x4a,0x4b,0x7a,0x4b,0x4a,0x4b,0x7a,0x4b,0x4a,0x4a,0x4a,0xad,0x10,0x40,0x24,0xfe,0x88,0xfe,0x50,0xfc,0x54,0xfe,0x54,0xfc,0x50,0xd8,0xd4,0x52,0x50,
-+0x0,0x7a,0x49,0x4f,0x48,0x79,0x4a,0x4a,0x4b,0x7a,0x4c,0x4b,0x49,0x4a,0xac,0x10,0x40,0x48,0x50,0xfc,0xe0,0x50,0x48,0x8,0xbe,0xa8,0xa8,0x28,0x7e,0x8,0x8,0x8,
-+0x0,0x20,0x24,0x3e,0x20,0x21,0x22,0x3f,0x2,0x2,0x1a,0xe2,0x2,0x14,0x9,0x2,0x40,0x40,0x40,0x7e,0x82,0x24,0x20,0x20,0x20,0x20,0x20,0x50,0x50,0x88,0x6,0x4,
-+0x42,0x24,0x18,0x24,0x42,0x1,0xff,0x28,0x3e,0x6a,0xaa,0x2a,0x2a,0x2e,0x9,0xa,0x40,0x40,0x40,0x7e,0x82,0x24,0x20,0x20,0x20,0x20,0x20,0x50,0x50,0x88,0x6,0x4,
-+0x10,0x12,0xff,0x10,0x28,0x45,0xff,0x2,0x7a,0x4a,0x4a,0x4a,0x7a,0x2,0xb,0x6,0x40,0x40,0x40,0x7e,0x82,0x24,0x20,0x20,0x20,0x20,0x20,0x50,0x50,0x88,0x6,0x4,
-+0x2,0xf,0x78,0x8,0x8,0xff,0x28,0x4b,0x49,0x49,0x6b,0x49,0x49,0x7f,0x41,0x2,0x40,0x40,0x40,0x7e,0x82,0x24,0x20,0x20,0x20,0x20,0x20,0x50,0x50,0x88,0x6,0x4,
-+0x10,0xa,0x7f,0x0,0x22,0x15,0xff,0x0,0x3e,0x22,0x22,0x3e,0x22,0x22,0x3f,0x22,0x40,0x40,0x40,0x7e,0x82,0x24,0xa0,0x20,0x20,0x20,0x20,0x50,0x50,0x88,0x6,0x4,
-+0x8,0x14,0x22,0x7f,0x80,0x3e,0x23,0x3e,0x0,0x77,0x11,0x55,0x33,0x55,0x11,0x33,0x40,0x40,0x40,0x7e,0x42,0x84,0x20,0x20,0x20,0x20,0x20,0x50,0x50,0x88,0x6,0x4,
-+0x4,0x7e,0x44,0x45,0x46,0x6d,0x6d,0x55,0x55,0x55,0x6d,0x6d,0x44,0x44,0x43,0x80,0x80,0x88,0xfc,0x8,0x8,0xe8,0x28,0x28,0xe8,0x28,0x10,0x4,0xfe,0x2,0xfe,0x0,
-+0x0,0x23,0x12,0x12,0xff,0x2,0x4a,0x4a,0x4a,0x52,0x52,0x1e,0xf3,0x44,0x4,0x18,0x8,0xfc,0x8,0x8,0x18,0x98,0xa8,0xa8,0x48,0x48,0xa8,0x98,0x1a,0xa,0xa,0x4,
-+0x4,0x7e,0x44,0x44,0x44,0x6c,0x6c,0x54,0x54,0x54,0x6f,0x6c,0x44,0x44,0x43,0x80,0x8,0xfc,0x88,0xf8,0x88,0xf8,0x88,0xf8,0x88,0x88,0xfe,0x50,0x8a,0x2,0xfe,0x0,
-+0x0,0x7d,0x45,0x45,0x45,0x6d,0x6d,0x54,0x55,0x54,0x6c,0x6c,0x44,0x44,0x43,0x80,0x20,0xac,0x24,0xac,0x24,0x24,0xfc,0x20,0xfc,0x88,0x50,0x20,0x52,0x8a,0xfe,0x0,
-+0x10,0x18,0x14,0xfe,0x10,0x28,0x44,0x82,0x24,0x36,0xff,0x24,0x24,0x5a,0x49,0x92,0x8,0xfc,0x88,0x88,0x88,0xd8,0xd8,0xa8,0xa8,0xa8,0xd8,0xd8,0x8a,0x8a,0xa,0x4,
-+0x4,0x7e,0x44,0x44,0x45,0x6c,0x6d,0x54,0x56,0x55,0x6c,0x6d,0x46,0x44,0x43,0x80,0x20,0x20,0xa4,0xa8,0x50,0x88,0x6,0x88,0xaa,0xdc,0x88,0x54,0x22,0x2,0xfe,0x0,
-+0x2,0x3f,0x22,0x22,0x22,0x22,0x41,0x80,0x7f,0x21,0x22,0x14,0x8,0x14,0x23,0xc1,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x80,0x0,
-+0x10,0xfe,0x10,0x7c,0x0,0xfe,0x83,0xbe,0x1,0x7c,0x4,0x7c,0x40,0x7c,0x4,0x1b,0x8,0xfc,0x88,0x88,0x88,0x88,0x6,0x0,0xfc,0x84,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x8,0x7f,0x8,0x3e,0x0,0xff,0x91,0x92,0x7f,0x28,0x28,0x7e,0x8,0xff,0x8,0xb,0x8,0x7c,0x48,0x48,0x48,0x48,0x86,0x0,0xfc,0x84,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x8,0x7f,0x8,0x3e,0x0,0xff,0x91,0x9c,0x25,0x7e,0xaa,0x3e,0x2a,0x3e,0x4a,0x8b,0x8,0xfc,0x88,0x88,0x88,0x88,0x6,0x0,0xfc,0x84,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x2,0x2,0x7e,0x2,0x3e,0x2,0x7e,0x2,0x1,0xff,0x8,0x4,0x3,0x2,0xc,0x70,0x80,0x88,0xfc,0x80,0xf8,0x80,0xfc,0x80,0x4,0xfe,0x20,0x40,0x80,0x80,0x60,0x1c,
-+0x1,0xff,0x18,0x6,0x1,0xe,0xf2,0x2e,0x22,0x2e,0x22,0x2e,0x22,0x3f,0x20,0x40,0x0,0xfe,0x30,0xc0,0x0,0xe0,0x9e,0xe8,0x88,0xe8,0x88,0xe8,0x88,0xf8,0x8,0x8,
-+0x4,0x42,0x20,0x4,0xff,0x14,0x55,0x25,0x25,0x55,0x55,0x4c,0x8d,0x6,0x4,0x4,0x4,0xfe,0x44,0x54,0xfc,0x44,0xf4,0x54,0xf4,0x54,0xf4,0xe4,0x54,0x4c,0x54,0x48,
-+0x20,0x18,0x8,0x0,0xfe,0x20,0x25,0x3e,0x24,0x24,0x24,0x24,0x44,0x44,0x94,0x8,0x20,0x20,0x50,0x50,0x88,0x88,0x6,0x44,0x30,0x10,0x80,0x40,0x30,0x18,0x8,0x0,
-+0x20,0x18,0x8,0x1,0xfe,0x20,0x25,0x3e,0x25,0x25,0x25,0x25,0x45,0x45,0x94,0x8,0x80,0x80,0x84,0xfe,0x20,0x24,0xfe,0x20,0xfc,0x24,0x24,0x24,0x34,0x28,0x20,0x20,
-+0x20,0x18,0x8,0x1,0xfe,0x21,0x24,0x3e,0x25,0x24,0x24,0x27,0x44,0x44,0x94,0x8,0x80,0x84,0xfe,0x0,0x18,0xe0,0x28,0x3c,0xe0,0x24,0x3e,0xe0,0x20,0x22,0x22,0x1e,
-+0x21,0x19,0x9,0xfe,0x24,0x21,0x3d,0x25,0x25,0x27,0x25,0x25,0x45,0x45,0x95,0xa,0x0,0x4,0xfe,0x0,0x8,0xfc,0x8,0x48,0x28,0xfe,0x8,0x8,0x8,0x8,0x28,0x10,
-+0x20,0x18,0x8,0x1,0xfe,0x21,0x21,0x3d,0x26,0x24,0x25,0x24,0x44,0x44,0x97,0x8,0x80,0x80,0x84,0xfe,0x20,0x20,0x28,0xfc,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x20,0x18,0x8,0x0,0xfd,0x22,0x20,0x3c,0x24,0x24,0x24,0x24,0x44,0x45,0x95,0xa,0x80,0x80,0x84,0xfe,0x0,0xfc,0x84,0x84,0xfc,0x80,0xa4,0xa8,0xb0,0x22,0x22,0x1e,
-+0x20,0x18,0x8,0x1,0xfe,0x23,0x20,0x3c,0x25,0x24,0x24,0x24,0x44,0x45,0x95,0xa,0x80,0x84,0xfe,0x40,0x24,0xfe,0x40,0x88,0xfc,0x0,0xa8,0xa8,0xa8,0x2a,0x2a,0x26,
-+0x20,0x18,0x9,0x2,0xfe,0x20,0x20,0x3c,0x27,0x24,0x25,0x25,0x45,0x45,0x94,0x8,0x80,0x84,0xfe,0x20,0xf8,0x20,0x50,0x88,0xfe,0x8,0xe8,0x28,0x28,0xe8,0x8,0x18,
-+0x10,0x13,0x10,0x14,0x54,0x58,0x53,0x90,0x10,0x10,0x19,0x25,0x22,0x44,0x81,0x0,0x0,0xf8,0x10,0x20,0x40,0x84,0xfe,0xa4,0xa4,0xa4,0x24,0x44,0x44,0x84,0x28,0x10,
-+0x10,0x10,0x10,0x17,0x54,0x58,0x53,0x90,0x10,0x17,0x10,0x28,0x24,0x44,0x80,0x0,0x40,0x40,0x44,0xfe,0x40,0x48,0xfc,0x40,0x44,0xfe,0x44,0x44,0x54,0x48,0x40,0x40,
-+0x10,0x10,0x10,0x17,0x54,0x5a,0x52,0x92,0x12,0x13,0x10,0x28,0x24,0x44,0x80,0x0,0x40,0x40,0x44,0xfe,0x40,0x48,0x48,0x48,0x48,0xf8,0x48,0x40,0x42,0x42,0x3e,0x0,
-+0x10,0x10,0x10,0x14,0x55,0x59,0x52,0x95,0x19,0x11,0x11,0x29,0x25,0x45,0x80,0x0,0x40,0x40,0xa0,0xa0,0x10,0x10,0xe,0xf4,0x10,0x10,0x10,0x50,0x24,0x4,0xfc,0x0,
-+0x10,0x10,0x17,0x10,0x54,0x54,0x58,0x91,0x13,0x15,0x11,0x29,0x25,0x45,0x41,0x81,0x0,0x4,0xfe,0x40,0x40,0x80,0x80,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x13,0x10,0x55,0x54,0x58,0x90,0x17,0x10,0x10,0x28,0x24,0x44,0x40,0x80,0x8,0x1c,0xe0,0x20,0x24,0xac,0xb0,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x10,0x10,0x10,0x13,0x54,0x54,0x58,0x90,0x11,0x10,0x10,0x28,0x24,0x44,0x43,0x80,0x40,0x20,0x24,0xfe,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x10,0x10,0x17,0x54,0x58,0x50,0x91,0x13,0x10,0x10,0x28,0x25,0x42,0x47,0x80,0x40,0x20,0x4,0xfe,0x40,0x40,0x80,0x8,0xf0,0x20,0x40,0x80,0x8,0x4,0xfc,0x4,
-+0x1,0x2,0x4,0x8,0x3f,0x0,0x1f,0x10,0x10,0x1f,0x1,0x11,0x11,0x22,0xc,0x70,0x0,0x0,0x20,0x10,0xf8,0x0,0xf0,0x10,0x10,0xf0,0x8,0x10,0x20,0x80,0x60,0x1c,
-+0x10,0x10,0x10,0x15,0x55,0x59,0x53,0x95,0x11,0x10,0x17,0x28,0x24,0x44,0x40,0x80,0xa0,0xa0,0xa0,0x24,0x28,0x30,0x64,0x1c,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x12,0x11,0x10,0x14,0x57,0x58,0x50,0x93,0x10,0x10,0x17,0x28,0x24,0x44,0x40,0x80,0x8,0x10,0xa0,0x8,0xfc,0x40,0x48,0xfc,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x10,0x13,0x10,0x14,0x57,0x59,0x51,0x91,0x17,0x10,0x11,0x29,0x25,0x45,0x41,0x81,0x8,0xfc,0x80,0x88,0xfc,0x8,0x8,0x8,0xfe,0x0,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x14,0x55,0x59,0x52,0x95,0x18,0x10,0x13,0x2a,0x26,0x46,0x43,0x82,0x40,0x40,0xa0,0xa0,0x10,0x90,0x48,0xf6,0x14,0x20,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x24,0x22,0x20,0x24,0xac,0xb4,0xa4,0x24,0x25,0x26,0x24,0x24,0x54,0x4c,0x84,0x4,0x4,0xfe,0x4,0x4,0x44,0x24,0xa4,0x84,0x94,0xac,0xa4,0xe4,0x4,0x4,0x14,0x8,
-+0x10,0x10,0x10,0x14,0x57,0x5a,0x53,0x92,0x13,0x10,0x10,0x2b,0x24,0x44,0x40,0x80,0x48,0x7c,0x40,0x40,0xf8,0x8,0xf8,0x8,0xf8,0x40,0x44,0xfe,0x40,0x40,0x40,0x40,
-+0x1,0x11,0x11,0x11,0x22,0xc,0x30,0xc8,0x8,0x2a,0x2a,0x4d,0x14,0x12,0x20,0xc1,0x0,0x10,0x30,0x40,0x80,0x60,0x1e,0x24,0x20,0xa4,0xa8,0x30,0x50,0x48,0x8e,0x4,
-+0x21,0x21,0x21,0x2f,0xa9,0xb1,0xa1,0x27,0x24,0x24,0x24,0x24,0x57,0x48,0x80,0x1,0x4,0x3e,0x24,0xe4,0x24,0x3c,0x24,0xa4,0xa4,0xbc,0xa4,0xa4,0xa4,0x44,0x94,0x8,
-+0x10,0x13,0x12,0x12,0x57,0x5a,0x52,0x93,0x10,0x10,0x13,0x29,0x24,0x40,0x47,0x80,0x4,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x40,0x20,0xfc,0x8,0x88,0x90,0xfe,0x0,
-+0x10,0x13,0x12,0x12,0x57,0x5a,0x52,0x93,0x10,0x1f,0x12,0x12,0x2a,0x26,0x43,0x82,0x8,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x0,0xfe,0x88,0x50,0x20,0x90,0xe,0x4,
-+0x10,0x13,0x12,0x12,0x57,0x5a,0x52,0x93,0x12,0x12,0x12,0x17,0x2a,0x2a,0x42,0x82,0x44,0xbe,0x24,0x24,0xa4,0x42,0x0,0xbc,0x4,0x24,0x28,0x90,0x10,0x28,0x4e,0x84,
-+0x8,0xb,0xa,0x13,0x30,0x5f,0x90,0x11,0x16,0x11,0x9,0x9,0x12,0x4,0x18,0x60,0x8,0xfc,0x8,0xf8,0x40,0xfe,0xe0,0x50,0x4e,0x40,0x10,0x20,0xc0,0x40,0x30,0xe,
-+0x10,0x10,0x17,0x14,0x54,0x5b,0x50,0x93,0x12,0x13,0x12,0x2b,0x24,0x40,0x47,0x80,0x80,0x40,0xfe,0x2,0x4,0xf8,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x0,0x4,0xfe,0x0,
-+0x10,0x10,0x13,0x12,0x56,0x5b,0x52,0x92,0x13,0x15,0x15,0x29,0x25,0x45,0x41,0x81,0x40,0x24,0xfe,0x4,0x4,0xfc,0x0,0x4,0xfe,0x54,0x54,0xfc,0x54,0x54,0x54,0xc,
-+0x10,0x10,0x14,0x12,0x56,0x58,0x50,0x96,0x12,0x12,0x12,0x2a,0x26,0x45,0x88,0x0,0x8,0xfc,0x88,0x88,0xf8,0x88,0x88,0xf8,0xa4,0xa8,0x90,0xc8,0x84,0x6,0xfc,0x0,
-+0x20,0x27,0x24,0x25,0xac,0xb5,0xa6,0x20,0x27,0x24,0x24,0x27,0x54,0x4c,0x87,0x4,0x84,0x7e,0x24,0x24,0xa4,0xa4,0x54,0x88,0xfc,0x44,0x44,0xfc,0x44,0x44,0xfc,0x4,
-+0x11,0x11,0x11,0x15,0x55,0x58,0x53,0x92,0x13,0x10,0x13,0x29,0x24,0x44,0x41,0x86,0xf8,0x8,0xf8,0x8,0xf8,0x0,0xfc,0x94,0xfc,0x0,0xfc,0x8,0x90,0x60,0x90,0xe,
-+0x20,0x20,0x2f,0x21,0xa8,0xb7,0xa4,0x25,0x26,0x25,0x25,0x25,0x55,0x4c,0x84,0x4,0x80,0x44,0xfe,0x10,0xa4,0xfe,0xa4,0x14,0xc,0xf4,0x14,0x14,0xf4,0x4,0x14,0x8,
-+0x0,0x3f,0x21,0x3f,0x20,0x3f,0x40,0x7f,0x95,0x24,0xd,0x11,0x11,0x22,0xc,0x70,0x8,0x8,0x8,0x8,0x7e,0x8,0x28,0xa8,0x8,0xa8,0x10,0x10,0x20,0x80,0x60,0x1c,
-+0x20,0x2f,0x24,0x22,0xa8,0xb2,0xa4,0x20,0x23,0x22,0x22,0x23,0x52,0x4a,0x83,0x2,0x84,0xfe,0xa4,0x94,0x84,0x94,0xa4,0x48,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x20,0x20,0x27,0x24,0xad,0xb4,0xa7,0x24,0x25,0x26,0x24,0x2f,0x50,0x49,0x86,0x18,0x40,0x84,0xfe,0x44,0x54,0x44,0xfc,0x44,0x54,0x4c,0x44,0xfe,0xa0,0x10,0xe,0x4,
-+0x10,0x17,0x12,0x11,0x57,0x59,0x52,0x94,0x1b,0x12,0x12,0x13,0x2a,0x26,0x43,0x82,0x1c,0xe0,0x48,0x50,0xfe,0x50,0x48,0x4e,0xfc,0x48,0x48,0xf8,0x48,0x48,0xf8,0x8,
-+0x21,0x28,0x24,0x23,0xa8,0xb0,0xad,0x26,0x24,0x27,0x24,0x27,0x54,0x4a,0x91,0x0,0x4,0x88,0x0,0xfe,0x40,0xc0,0x24,0x68,0xb0,0x70,0xa8,0x26,0xa0,0x46,0xfc,0x0,
-+0x4,0xfe,0x10,0x32,0xdc,0x28,0xdc,0x2a,0xd9,0x1,0x9,0x9,0x12,0x4,0x18,0xe0,0x4,0xfe,0x10,0x32,0xdc,0x28,0xdc,0x2a,0xd8,0x0,0x10,0x20,0x80,0x40,0x30,0xe,
-+0x27,0x22,0x21,0x27,0xac,0xb7,0xa0,0x27,0x24,0x27,0x24,0x27,0x55,0x4d,0x86,0x4,0xfc,0x48,0x50,0xfc,0xa4,0xfc,0x0,0x88,0x88,0xfe,0x88,0xc8,0x28,0x8,0xa8,0x10,
-+0x11,0x9,0x7f,0x48,0xbe,0x1c,0x2a,0x9,0x7f,0x2,0xd,0x39,0xc5,0x2,0x4,0x18,0x10,0x20,0xfe,0x22,0xfc,0x70,0xa8,0x20,0xfc,0x80,0x60,0x38,0x46,0x80,0x40,0x38,
-+0x0,0x0,0x0,0x0,0x0,0x0,0x48,0x44,0x44,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x88,0x44,0x42,0x2,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x2,0x2,0x7f,0x2,0x3f,0x4,0xff,0x8,0x1f,0x24,0x42,0x80,0x0,0x24,0x22,0x42,0x0,0x8,0xfc,0x0,0xf8,0x0,0xfe,0x20,0xfc,0x20,0x20,0xa0,0x40,0x88,0x44,0x44,
-+0x0,0x78,0x48,0x49,0x4a,0x79,0x49,0x49,0x49,0x79,0x49,0x0,0x28,0x24,0x44,0x80,0x80,0x84,0xfe,0x4,0x24,0xf4,0x24,0x24,0x24,0xe4,0x14,0x8,0x90,0x48,0x46,0x2,
-+0x1,0x7f,0x1,0x3f,0x0,0x1f,0x10,0x1f,0x4,0xff,0x0,0x1f,0x10,0x1f,0x24,0x42,0x0,0xfc,0x0,0xf8,0x0,0xf0,0x10,0xf0,0x44,0xfe,0x0,0xf0,0x10,0xf0,0x88,0x44,
-+0x2,0x1,0x3f,0x20,0x20,0x3f,0x21,0x21,0x3f,0x21,0x21,0x22,0x42,0x44,0x88,0x30,0x0,0x8,0xfc,0x8,0x8,0xf8,0x40,0x24,0xfe,0x0,0x0,0x80,0x80,0x60,0x1c,0x8,
-+0x2,0x1,0x3f,0x20,0x20,0x3f,0x24,0x23,0x29,0x26,0x22,0x3f,0x40,0x40,0x80,0x0,0x0,0x8,0xfc,0x8,0x8,0xf8,0x20,0x20,0x20,0x24,0x3e,0xe0,0x20,0x20,0x20,0x20,
-+0x2,0x1,0x3f,0x20,0x20,0x3f,0x20,0x2f,0x28,0x28,0x2b,0x2a,0x4a,0x4b,0x88,0x8,0x0,0x8,0xfc,0x8,0x8,0xf8,0x4,0xfe,0x4,0x4,0xf4,0x14,0x14,0xf4,0x4,0x8,
-+0x1,0x0,0x3f,0x20,0x3f,0x20,0x2f,0x28,0x2f,0x20,0x2f,0x28,0x4f,0x48,0x88,0x7,0x0,0x88,0xfc,0x8,0xf8,0x0,0xf0,0x10,0xf0,0x0,0xf8,0x88,0xf8,0x2,0x2,0xfe,
-+0x1,0x0,0x3f,0x20,0x3f,0x22,0x22,0x3e,0x22,0x22,0x3e,0x22,0x42,0x5e,0x82,0x2,0x0,0x88,0xfc,0x8,0xf8,0x40,0x48,0x7c,0x40,0x50,0x78,0x40,0x48,0x7c,0x40,0x40,
-+0x2,0x1,0x0,0x1f,0x0,0x1,0x1,0x3,0x5,0x9,0x11,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0xc0,0x80,0x0,0x0,0x80,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x20,0x13,0x2,0xfe,0xa,0x12,0x12,0x3b,0x56,0x92,0x12,0x12,0x12,0x12,0x11,0x10,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x20,0x10,0x3,0xfc,0x8,0x10,0x10,0x3b,0x54,0x90,0x10,0x11,0x11,0x12,0x14,0x18,0x8,0x7c,0xc0,0x40,0x40,0x40,0x44,0xfe,0x40,0xa0,0xa0,0x10,0x10,0x8,0xe,0x4,
-+0x20,0x10,0x0,0xfd,0x9,0x11,0x11,0x39,0x55,0x91,0x11,0x11,0x11,0x11,0x17,0x10,0x20,0x20,0x20,0x20,0x24,0x3e,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x20,0x10,0x0,0xfc,0xb,0x10,0x10,0x38,0x57,0x90,0x10,0x10,0x11,0x12,0x17,0x10,0x40,0x40,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x40,0x40,0x80,0x10,0x8,0xfc,0x4,
-+0x20,0x10,0x0,0xfb,0x8,0x10,0x10,0x38,0x57,0x92,0x12,0x12,0x12,0x12,0x13,0x12,0x40,0x40,0x44,0xfe,0x40,0x40,0x40,0x48,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x20,0x10,0x0,0xfb,0x8,0x10,0x10,0x39,0x55,0x91,0x12,0x12,0x14,0x18,0x11,0x12,0xa0,0x90,0x84,0xfe,0x80,0x80,0xf8,0x8,0x88,0x50,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x21,0x11,0x1,0xfd,0xa,0x14,0x10,0x38,0x54,0x90,0x10,0x10,0x10,0x10,0x10,0x10,0x0,0x0,0x4,0xfe,0x80,0x80,0x88,0xfc,0x80,0x80,0x88,0xfc,0x80,0x80,0x80,0x80,
-+0x20,0x10,0x0,0xfc,0x9,0x12,0x10,0x38,0x54,0x90,0x11,0x11,0x12,0x10,0x10,0x10,0x80,0x80,0x80,0xfe,0x2,0x4,0x20,0x20,0xa8,0xa4,0x24,0x22,0x22,0x20,0xa0,0x40,
-+0x20,0x10,0x3,0xfa,0xa,0x12,0x13,0x3a,0x56,0x92,0x12,0x12,0x12,0x13,0x12,0x10,0x8,0x3c,0xe0,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x50,0x90,0x4a,0x2a,0x4,
-+0x20,0x13,0x0,0xfc,0xb,0x10,0x10,0x3b,0x56,0x92,0x12,0x13,0x12,0x10,0x10,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x24,0xf4,0x24,0x24,0x24,0xe4,0x24,0x4,0x14,0x8,
-+0x20,0x10,0x0,0xfc,0xb,0x12,0x12,0x3a,0x56,0x92,0x12,0x12,0x10,0x10,0x11,0x16,0x40,0x48,0x7c,0x40,0xf8,0x8,0x48,0x48,0x48,0x48,0x48,0x48,0xa0,0x98,0xc,0x4,
-+0x20,0x10,0x0,0xfc,0xa,0x11,0x10,0x38,0x55,0x92,0x14,0x10,0x11,0x11,0x12,0x14,0x20,0xa0,0xa0,0xa4,0xac,0xb0,0xa0,0xa0,0xb0,0xac,0xa4,0xa0,0x22,0x22,0x1e,0x0,
-+0x21,0x11,0x7,0xf9,0x9,0x11,0x11,0x39,0x55,0x91,0x11,0x1f,0x10,0x11,0x12,0x14,0x10,0x10,0xfc,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,0x14,0xfe,0x0,0x10,0xc,0x4,
-+0x21,0x10,0x0,0xfd,0x9,0x11,0x11,0x39,0x55,0x91,0x10,0x17,0x10,0x10,0x10,0x10,0x4,0x88,0x50,0xfc,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0xfe,0x20,0x20,0x20,0x20,
-+0x21,0x11,0x7,0xf9,0x17,0x11,0x17,0x39,0x55,0x90,0x17,0x10,0x10,0x10,0x13,0x14,0x0,0x4,0xfe,0x14,0xd4,0x14,0xd4,0x24,0x4c,0x40,0xfe,0x40,0x40,0xa0,0x1e,0x4,
-+0x21,0x10,0x0,0xfb,0x8,0x10,0x11,0x38,0x54,0x90,0x13,0x10,0x12,0x12,0x14,0x10,0x4,0x88,0x50,0xfe,0x20,0x20,0xfc,0x20,0x20,0x24,0xfe,0x0,0xa4,0x52,0x52,0x0,
-+0x20,0x17,0x0,0xff,0x8,0x13,0x1a,0x37,0x51,0x9f,0x10,0x13,0x12,0x12,0x13,0x12,0x40,0xfe,0x40,0xfc,0x0,0xf8,0x8,0xf8,0x10,0xfe,0x0,0xf8,0x8,0x8,0xf8,0x8,
-+0x20,0x17,0x0,0xff,0xc,0x17,0x11,0x3b,0x55,0x93,0x11,0x1f,0x11,0x13,0x1d,0x11,0x40,0xfe,0x0,0xbc,0xa4,0xbc,0x10,0xf8,0x10,0xf8,0x10,0xfe,0x48,0x30,0x8e,0x4,
-+0x0,0x7f,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0xa,0x29,0x28,0x48,0x88,0x7,0x0,0x4,0xfe,0x0,0x80,0x60,0x30,0x10,0x0,0x0,0x0,0x88,0x84,0x12,0x12,0xf0,0x0,
-+0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x7f,0x0,0xa,0x29,0x28,0x48,0x88,0x7,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x0,0x0,0x88,0x84,0x12,0x12,0xf0,0x0,
-+0x0,0x0,0x7e,0x3,0x24,0x14,0x8,0x14,0x22,0x40,0x2a,0x29,0x48,0x88,0x7,0x0,0x10,0x10,0x14,0xfe,0x10,0x90,0x50,0x10,0x50,0x20,0x8,0x84,0x92,0x12,0xf0,0x0,
-+0x8,0x8,0x7f,0x8,0x3e,0x8,0x7f,0x8,0x8,0x0,0x2a,0x29,0x48,0x88,0x7,0x0,0x0,0x4,0x7e,0x24,0x24,0x24,0x44,0x54,0x88,0x0,0x8,0x84,0x92,0x12,0xf0,0x0,
-+0x1,0x1,0x3f,0x1,0xff,0x1,0x3f,0x1,0xff,0x0,0x2a,0x29,0x48,0x88,0x7,0x0,0x0,0x10,0xf8,0x0,0xfe,0x0,0xf8,0x0,0xfe,0x0,0x8,0x84,0x92,0x12,0xf0,0x0,
-+0x0,0xff,0x2,0x4,0x3f,0x24,0x24,0x24,0x24,0x0,0x2a,0x29,0x48,0x88,0x7,0x0,0x4,0xfe,0x0,0x8,0xfc,0x48,0x48,0x48,0x58,0x0,0x8,0x84,0x92,0x12,0xf0,0x0,
-+0x8,0x8,0x17,0x10,0x30,0x5f,0x90,0x10,0x17,0x10,0x2a,0x29,0x48,0x88,0x7,0x0,0x8,0x1c,0xe0,0x40,0x44,0xfe,0x40,0x48,0xfc,0x0,0x8,0x84,0x92,0x12,0xf0,0x0,
-+0x8,0x4,0x7f,0x1,0x1,0x3f,0x1,0x1,0xff,0x0,0x2a,0x29,0x48,0x88,0x7,0x0,0x20,0x48,0xfc,0x0,0x10,0xf8,0x0,0x4,0xfe,0x0,0x8,0x84,0x92,0x12,0xf0,0x0,
-+0x40,0x30,0x10,0x5,0xa,0x10,0xe0,0x21,0x26,0x0,0x2a,0x29,0x48,0x88,0x7,0x0,0x80,0x80,0xfc,0x4,0x48,0x40,0xa0,0x10,0xe,0x0,0x8,0x84,0x92,0x12,0xf0,0x0,
-+0x1,0x7f,0x1,0x3f,0x0,0x7f,0x40,0x8f,0x8,0x8,0x30,0xa,0x29,0x48,0x88,0x7,0x8,0xfc,0x0,0xf8,0x0,0xfe,0x2,0xe4,0x20,0x28,0x38,0x0,0x84,0x92,0x12,0xf0,
-+0x8,0x12,0x21,0x4c,0x12,0x30,0x51,0x96,0x12,0x10,0xa,0x29,0x28,0x48,0x88,0x7,0x8,0x7c,0x0,0x4,0xfe,0x88,0x8,0x8,0x28,0x10,0x0,0x88,0x84,0x12,0x12,0xf0,
-+0x0,0x7e,0x42,0x7e,0x49,0x7e,0x48,0x49,0x65,0x42,0x0,0x2a,0x29,0x48,0x88,0x7,0x40,0x40,0x44,0xfe,0x48,0x28,0x10,0x28,0x4e,0x84,0x0,0x8,0x84,0x92,0x12,0xf0,
-+0x3f,0x22,0x2f,0x22,0x3f,0x22,0x27,0x2a,0x23,0x20,0x3f,0xa,0x29,0x48,0x88,0x7,0xfc,0x20,0xf8,0xa0,0xfc,0x0,0xf0,0x10,0xf0,0x0,0xfc,0x0,0x84,0x92,0x12,0xf0,
-+0xe,0x78,0x8,0xff,0x8,0x3e,0x22,0x22,0x22,0x3e,0x0,0x2a,0x29,0x48,0x88,0x7,0x20,0x24,0xfe,0x84,0xfc,0x84,0xfc,0x84,0xfc,0x84,0x0,0x8,0x84,0x92,0x12,0xf0,
-+0x8,0xff,0x0,0x7e,0x43,0x7e,0x0,0x7f,0x4,0xff,0x8,0x1a,0x51,0x50,0x90,0xf,0x40,0x40,0x44,0xfe,0x4,0x44,0x28,0x10,0x28,0x46,0x84,0x0,0x84,0x92,0x12,0xf0,
-+0x10,0x17,0x12,0xf9,0x17,0x39,0x33,0x55,0x91,0x13,0x0,0x2a,0x29,0x48,0x88,0x7,0x10,0xd0,0x94,0x7e,0xd0,0x58,0x34,0x52,0x90,0x10,0x0,0x8,0x84,0x92,0x12,0xf0,
-+0x41,0x2f,0x11,0x87,0x61,0x2f,0x15,0x26,0xe4,0x24,0x0,0x2a,0x29,0x48,0x88,0x7,0x10,0xfe,0x10,0xfc,0x10,0xfc,0x14,0xac,0x44,0xc,0x0,0x8,0x84,0x92,0x12,0xf0,
-+0x8,0xff,0x14,0xff,0x22,0x3e,0x22,0x3e,0x8,0x7f,0x8,0xa,0x51,0x50,0x90,0xf,0x40,0x7e,0xa8,0x10,0xee,0x0,0x7c,0x44,0x54,0x54,0x28,0x44,0x84,0x92,0x12,0xf0,
-+0x1,0x1,0x3f,0x1,0xff,0x1,0x3f,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x8,0xfc,0x8,0xfe,0x8,0xf8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x3f,0x1,0xff,0x1,0x3f,0x1,0x7f,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x0,0x8,0xfc,0x8,0xfe,0x8,0xf8,0x0,0xfc,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,
-+0x1,0x1,0x7d,0x5,0x9,0x11,0x25,0xc2,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x0,0x8,0x18,0xa0,0x40,0x30,0xe,0x4,0xf0,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x22,0x11,0x9,0x0,0x7f,0x41,0x81,0x1,0x3d,0x5,0x9,0x11,0x21,0xc1,0x5,0x2,0x8,0x18,0x20,0x40,0xfe,0x2,0x4,0x10,0xa0,0x40,0x20,0x10,0xe,0x4,0x0,0x0,
-+0x1,0x1,0x7d,0x5,0x9,0x11,0x25,0x42,0x8,0x9,0xfa,0x1c,0x2c,0xcb,0x28,0x10,0x8,0x10,0xa0,0xc0,0x40,0x30,0xe,0x4,0x20,0x24,0xe8,0x70,0xa8,0x26,0xa4,0x40,
-+0x4,0xfe,0x10,0x10,0x20,0x24,0x3e,0x64,0xa4,0x24,0x24,0x24,0x25,0x3d,0x22,0x4,0x8,0xfc,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0xa,0xa,0x6,0x0,
-+0x4,0xfd,0x10,0x10,0x20,0x20,0x3c,0x67,0xa4,0x24,0x24,0x24,0x24,0x3c,0x20,0x0,0x8,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x0,0x1,0xfe,0x10,0x20,0x20,0x21,0x7c,0xa4,0x24,0x24,0x24,0x25,0x3d,0x22,0x0,0x0,0xf8,0x10,0x20,0x40,0x84,0xfe,0x54,0x54,0x54,0x94,0xa4,0x24,0x44,0x54,0x88,
-+0x1,0x7f,0x1,0x3f,0x1,0x7f,0x1,0xff,0x4,0x4,0xf,0x18,0x28,0xc8,0xf,0x8,0x0,0xfc,0x0,0xf8,0x0,0xfc,0x0,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,
-+0x4,0xfe,0x13,0x10,0x20,0x21,0x3d,0x67,0xa4,0x24,0x24,0x27,0x24,0x3c,0x20,0x0,0x40,0x48,0xfc,0x80,0xa0,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x4,0xfe,0x11,0x10,0x21,0x21,0x3d,0x65,0xa5,0x25,0x25,0x24,0x24,0x3c,0x20,0x0,0x20,0x24,0xfe,0x20,0x24,0x24,0x24,0x24,0x24,0x24,0xfc,0x24,0x20,0x22,0x1e,0x0,
-+0x4,0xfe,0x10,0x10,0x20,0x21,0x3d,0x64,0xa4,0x24,0x24,0x24,0x25,0x3e,0x24,0x0,0x4,0xfe,0x8,0x88,0x88,0x8,0xfe,0x28,0x28,0x48,0x48,0x88,0x8,0x8,0x28,0x10,
-+0x4,0xfe,0x11,0x11,0x21,0x21,0x3d,0x65,0xa5,0x25,0x25,0x25,0x3d,0x21,0x2,0x4,0x0,0x1c,0xe0,0x0,0x0,0x4,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x4,0xfe,0x13,0x10,0x20,0x24,0x3f,0x64,0xa4,0x24,0x24,0x24,0x25,0x3f,0x22,0x0,0x8,0x3c,0xc0,0x40,0x20,0x20,0xfc,0x8,0x10,0x20,0x40,0x80,0x0,0x0,0x86,0x7c,
-+0x4,0xff,0x12,0x12,0x23,0x22,0x3a,0x6a,0xaa,0x2a,0x2a,0x2a,0x3b,0x24,0x8,0x10,0x8,0xfc,0x8,0x8,0x18,0x98,0xa8,0xa8,0x48,0x48,0xa8,0x98,0x1a,0xa,0xa,0x4,
-+0x4,0xfe,0x10,0x11,0x20,0x20,0x3c,0x67,0xa4,0x24,0x24,0x24,0x25,0x3d,0x20,0x0,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x40,0x80,0x8,0xfc,0x4,0x0,
-+0x4,0xfe,0x13,0x10,0x20,0x20,0x3d,0x65,0xa4,0x24,0x24,0x24,0x24,0x3c,0x21,0x6,0x88,0x88,0xfe,0x88,0x88,0x0,0x4,0x4,0x88,0x88,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x8,0xff,0x12,0x12,0x23,0x22,0x3a,0x6a,0xaa,0x2a,0x2a,0x2a,0x3a,0x24,0x9,0x12,0x8,0xfc,0x0,0x4,0xfe,0x40,0x44,0x7e,0x44,0x44,0x44,0x84,0x84,0x84,0x28,0x10,
-+0x4,0x4,0x7f,0x5,0x5,0x9,0x37,0xc1,0x0,0xff,0x4,0xf,0x18,0x28,0xcf,0x8,0x40,0x28,0xfc,0x0,0x30,0xc4,0x4,0xfc,0x4,0xfe,0x10,0xf8,0x10,0x10,0xf0,0x10,
-+0x4,0xfe,0x10,0x10,0x21,0x22,0x3c,0x64,0xa4,0x24,0x24,0x24,0x24,0x3c,0x20,0x0,0x80,0x80,0x84,0xfe,0x40,0x40,0x48,0x7c,0x40,0x40,0x48,0x7c,0x40,0x40,0x40,0x40,
-+0x4,0xfe,0x10,0x10,0x20,0x25,0x3e,0x64,0xa5,0x24,0x24,0x24,0x24,0x3c,0x23,0x0,0x20,0x20,0x50,0x50,0x88,0x4,0x2,0x8,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x4,0xfe,0x11,0x11,0x21,0x21,0x3d,0x65,0xa5,0x25,0x25,0x25,0x25,0x3d,0x21,0x0,0x8,0x1c,0xe0,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x10,0x50,0x4a,0xaa,0x4,
-+0x4,0xfe,0x10,0x13,0x20,0x20,0x3d,0x65,0xa4,0x24,0x24,0x24,0x24,0x3c,0x27,0x0,0x40,0x20,0x24,0xfe,0x0,0x8,0x8,0x8,0x90,0x90,0x90,0x90,0x20,0x24,0xfe,0x0,
-+0x4,0xfe,0x10,0x13,0x22,0x24,0x3e,0x64,0xa4,0x24,0x24,0x24,0x24,0x3c,0x20,0x0,0x40,0x20,0x20,0xfe,0x2,0x84,0x80,0x88,0x98,0xa0,0xc0,0x80,0x82,0x82,0x7e,0x0,
-+0x0,0x0,0xfc,0x13,0x20,0x20,0x23,0x7a,0xaa,0x2b,0x28,0x28,0x28,0x38,0x1,0x2,0x90,0x90,0x94,0xfe,0x94,0x94,0xfc,0x90,0x90,0xfe,0x92,0x92,0x9a,0x94,0x10,0x10,
-+0x8,0xff,0x12,0x12,0x22,0x22,0x3a,0x6f,0xaa,0x2a,0x2a,0x2a,0x3a,0x22,0x4,0x8,0x44,0xe4,0x44,0x54,0x54,0x54,0x54,0xf4,0x54,0x54,0x54,0x54,0x44,0x44,0x54,0x48,
-+0x4,0xfe,0x13,0x10,0x20,0x20,0x3c,0x67,0xa5,0x25,0x25,0x25,0x25,0x3d,0x20,0x0,0x88,0x88,0xfe,0x88,0x88,0x20,0x24,0xfe,0x0,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,
-+0x8,0xfc,0x17,0x10,0x22,0x21,0x39,0x68,0xaf,0x28,0x28,0x29,0x29,0x3a,0x24,0x8,0x40,0x48,0xfc,0x40,0x48,0x48,0x50,0x44,0xfe,0xa0,0xa0,0x10,0x10,0x8,0xe,0x4,
-+0x4,0xfe,0x10,0x13,0x20,0x20,0x3c,0x65,0xa4,0x27,0x24,0x24,0x24,0x3d,0x21,0x6,0x40,0x48,0x7c,0xc0,0x28,0x12,0x6a,0x86,0x0,0xfc,0x90,0x90,0x90,0x12,0x12,0xe,
-+0x4,0x4,0x27,0x24,0x24,0x3f,0xe0,0x0,0x7f,0x4,0x8,0x1f,0x28,0xc8,0xf,0x8,0x40,0x40,0x4c,0x70,0x42,0x42,0x3e,0x0,0xfc,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,
-+0x8,0xff,0x12,0x12,0x22,0x22,0x3a,0x6a,0xaa,0x2a,0x2a,0x2a,0x2a,0x3a,0x22,0x2,0x4,0xfe,0x4,0x4,0xf4,0x4,0x4,0xf4,0x94,0x94,0x94,0xf4,0x94,0x4,0x14,0x8,
-+0x4,0xfe,0x10,0x11,0x21,0x21,0x3d,0x65,0xa5,0x25,0x25,0x25,0x25,0x3d,0x21,0x1,0x20,0x20,0x44,0xfe,0x4,0x8c,0x54,0x54,0x24,0x54,0x4c,0x8c,0x4,0x4,0xfc,0x4,
-+0x0,0x4,0xfe,0x11,0x21,0x22,0x20,0x7c,0xa4,0x25,0x27,0x25,0x25,0x3d,0x21,0x1,0x80,0x88,0xfc,0x8,0x88,0x50,0x20,0x50,0x8e,0x4,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x4,0xfe,0x13,0x10,0x20,0x23,0x3c,0x64,0xa4,0x24,0x27,0x24,0x24,0x3c,0x22,0x1,0x10,0x58,0x94,0x94,0x90,0xfe,0x90,0x90,0xb4,0xd4,0x98,0x90,0xaa,0xca,0x8a,0x4,
-+0x8,0xfc,0x13,0x10,0x21,0x24,0x3f,0x64,0xa5,0x25,0x25,0x25,0x25,0x3c,0x20,0x3,0x20,0x24,0xfe,0x20,0xfc,0x20,0xfe,0x0,0xfc,0x4,0x24,0x24,0x24,0x58,0x84,0x2,
-+0x4,0xfe,0x10,0x10,0x20,0x25,0x3e,0x64,0xa4,0x24,0x24,0x24,0x24,0x3c,0x20,0x0,0x60,0x50,0x44,0xfe,0x90,0x90,0x90,0xfc,0x90,0x90,0xfc,0x90,0x90,0x94,0xfe,0x80,
-+0x4,0xfe,0x13,0x10,0x21,0x20,0x3c,0x67,0xa4,0x25,0x25,0x25,0x25,0x3d,0x21,0x1,0x40,0x28,0xfc,0x0,0x8,0x90,0x4,0xfe,0x0,0xf8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x4,0xfe,0x13,0x12,0x24,0x21,0x3c,0x64,0xa5,0x25,0x25,0x25,0x25,0x3d,0x22,0x4,0x40,0x20,0xfe,0x2,0x4,0xfc,0x20,0x20,0x20,0x24,0x3e,0x20,0x20,0x20,0xa6,0x7c,
-+0x8,0xfc,0x11,0x13,0x20,0x27,0x38,0x69,0xaa,0x2d,0x28,0x28,0x2b,0x38,0x20,0x3,0x40,0x90,0x8,0xfc,0x40,0xfe,0x90,0x28,0x46,0x94,0x20,0xc8,0x10,0x20,0xc0,0x0,
-+0x4,0xff,0x10,0x11,0x20,0x23,0x3c,0x65,0xa5,0x25,0x27,0x25,0x25,0x3d,0x20,0x0,0x20,0xfc,0x20,0xfc,0x20,0xfe,0x0,0xfc,0x44,0x24,0xfe,0x44,0x24,0xfe,0x4,0x18,
-+0x8,0xfd,0x11,0x11,0x21,0x29,0x3d,0x69,0xaa,0x2c,0x2a,0x2b,0x2a,0x3b,0x20,0x0,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x4,0xfe,0x44,0x44,0xb4,0x14,0x4,0xfc,0x4,0x8,
-+0x4,0xfe,0x11,0x10,0x20,0x23,0x3e,0x64,0xa5,0x25,0x25,0x25,0x25,0x3c,0x20,0x0,0x40,0x24,0xfe,0x88,0x50,0xfe,0x22,0x24,0xfe,0x24,0x24,0x34,0x28,0x20,0x20,0x20,
-+0x4,0xfe,0x13,0x12,0x24,0x21,0x3c,0x65,0xa5,0x25,0x25,0x25,0x24,0x3c,0x23,0x0,0x40,0x20,0xfe,0x2,0x4,0xfc,0x0,0xfc,0x4,0xfc,0x4,0xfc,0x0,0x4,0xfe,0x0,
-+0x8,0xfc,0x13,0x12,0x22,0x23,0x3a,0x6a,0xab,0x2b,0x2b,0x2d,0x29,0x39,0x21,0x1,0x40,0x24,0xfe,0x4,0x4,0xfc,0x0,0x4,0xfe,0x54,0x54,0xfc,0x54,0x54,0x54,0xc,
-+0x9,0xfd,0x11,0x12,0x26,0x21,0x39,0x6a,0xa8,0x2f,0x28,0x28,0x29,0x3a,0x2c,0x0,0x8,0x8,0xfc,0x48,0xa8,0x3e,0x8,0x48,0x44,0xfe,0xc0,0xe0,0x50,0x4e,0x44,0x40,
-+0x8,0xfc,0x17,0x11,0x22,0x24,0x39,0x6b,0xa8,0x28,0x29,0x2b,0x2d,0x39,0x21,0x1,0x40,0x24,0xfe,0x8,0x46,0x92,0x8,0xfc,0x80,0x88,0x50,0x20,0x10,0x48,0x8e,0x4,
-+0x5,0xfe,0x10,0x10,0x21,0x23,0x3d,0x64,0xa5,0x24,0x27,0x24,0x24,0x3d,0x22,0x0,0xfc,0x88,0x70,0x88,0x6,0xfc,0x54,0x88,0x54,0x22,0xfe,0x70,0xa8,0x26,0x20,0x20,
-+0x8,0x7f,0x8,0x3e,0x0,0x7f,0x49,0x7f,0x40,0x40,0xbf,0x4,0xf,0x18,0x68,0xf,0x78,0x48,0x48,0x48,0x86,0x78,0x48,0x30,0x48,0x86,0xfc,0x0,0xf0,0x10,0x10,0xf0,
-+0xa,0xff,0x11,0x14,0x22,0x20,0x39,0x6a,0xaa,0x28,0x2f,0x28,0x29,0x3a,0x24,0x0,0x4,0x7e,0x40,0x7c,0x44,0xfc,0x40,0x7e,0x40,0x44,0xfe,0xe0,0x50,0x4e,0x44,0x40,
-+0x9,0xfd,0x17,0x10,0x27,0x24,0x3f,0x68,0xaf,0x28,0x29,0x29,0x2f,0x39,0x25,0x2,0x10,0x10,0xd0,0x1e,0xe4,0x44,0xd4,0x14,0xd4,0x94,0x8,0xc8,0x14,0x14,0x22,0x40,
-+0x8,0xff,0x10,0x12,0x21,0x21,0x3b,0x6c,0xab,0x2a,0x2a,0x2b,0x29,0x38,0x27,0x0,0x20,0xa8,0xb0,0xa4,0x18,0x10,0xf8,0x6,0xf8,0x8,0x8,0xf8,0x10,0xa4,0xfe,0x0,
-+0xb,0xfc,0x11,0x11,0x21,0x25,0x3f,0x64,0xa5,0x25,0x25,0x25,0x25,0x3c,0x23,0x0,0xfe,0x0,0xfc,0x24,0xfc,0x24,0xfe,0x0,0xfc,0x24,0xfc,0x24,0xfc,0x0,0xfe,0x0,
-+0x1,0xff,0x21,0x22,0x23,0x44,0x7b,0xd6,0x55,0x58,0x57,0x50,0x51,0x72,0x44,0x0,0x10,0xfe,0x10,0x20,0xbc,0xa4,0x18,0x8,0xf4,0x2,0xfc,0x40,0x50,0x4c,0x44,0xc0,
-+0x1,0xff,0x21,0x27,0x24,0x49,0x70,0xd7,0x50,0x51,0x56,0x50,0x57,0x70,0x47,0x0,0x10,0xfe,0x10,0xfe,0x2,0xf4,0x0,0xfc,0x80,0x48,0x70,0xb0,0x68,0xa6,0x20,0x60,
-+0x1,0xff,0x21,0x2b,0x24,0x41,0x79,0xd5,0x55,0x51,0x55,0x57,0x54,0x78,0x48,0x0,0x10,0xfe,0x28,0xfe,0x20,0xfc,0x24,0xfc,0x24,0xfc,0x24,0xfe,0x88,0x48,0x8,0x18,
-+0x1,0x2,0xc,0x3f,0xc0,0x1f,0x10,0x1f,0x2,0xff,0x2,0x4,0x4,0x9,0x12,0x60,0x0,0x80,0x60,0xf8,0x6,0xf0,0x10,0xf0,0x24,0xfe,0x80,0xa0,0xc0,0x84,0x84,0x7c,
-+0x4,0x24,0x14,0x4,0xff,0x9,0x5,0x3f,0x21,0x21,0x23,0x25,0x29,0x21,0x21,0x21,0x40,0x48,0x50,0x44,0xfe,0x20,0x48,0xfc,0x8,0x8,0x88,0x68,0x28,0x8,0x28,0x10,
-+0x14,0x55,0x36,0x14,0xff,0x49,0x2a,0x7f,0x49,0x49,0x5d,0x6b,0x49,0x49,0x49,0x43,0x20,0x28,0x24,0x24,0xfe,0x20,0x20,0x3c,0x54,0x54,0x54,0x48,0x54,0x94,0x24,0x42,
-+0x28,0xaa,0x6c,0x29,0xfe,0x54,0x39,0x7d,0x55,0x55,0x7d,0x55,0x55,0x55,0x55,0x45,0x20,0x28,0x24,0xfe,0x20,0x24,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x24,0x24,0x2c,
-+0x0,0x5,0x7e,0x44,0x44,0x7c,0x44,0x47,0x7c,0x44,0x44,0x44,0x7c,0x44,0x0,0x0,0x8,0xfc,0x20,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x0,0x3,0x7c,0x45,0x45,0x7d,0x45,0x45,0x7d,0x44,0x44,0x44,0x7c,0x44,0x0,0x0,0x4,0xfe,0x20,0x20,0x24,0x3e,0x24,0x24,0xfc,0x4,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x0,0x1,0x7d,0x45,0x45,0x7d,0x45,0x45,0x7d,0x45,0x45,0x45,0x7d,0x45,0x1,0x0,0x4,0xfe,0x0,0x4,0x84,0x48,0x28,0x10,0x28,0x28,0x44,0x84,0x0,0x4,0xfe,0x0,
-+0x0,0x0,0x78,0x4f,0x48,0x7a,0x4a,0x4a,0x7a,0x4a,0x4b,0x48,0x78,0x48,0x0,0x0,0x40,0x40,0x44,0xfe,0x40,0x48,0x48,0x48,0x48,0x48,0xf8,0x48,0x42,0x42,0x3e,0x0,
-+0x0,0x8,0x7c,0x48,0x49,0x79,0x4a,0x4a,0x7c,0x48,0x48,0x48,0x78,0x48,0x3,0xc,0x40,0x40,0x40,0x40,0x50,0x48,0x46,0x4a,0x48,0x50,0x50,0x20,0x40,0x80,0x0,0x0,
-+0x0,0x8,0x7c,0x4b,0x4a,0x7c,0x48,0x48,0x78,0x48,0x48,0x48,0x79,0x49,0x2,0xc,0x40,0x40,0x40,0xfe,0x42,0x44,0x40,0x40,0x60,0xa0,0xa0,0xa0,0x22,0x22,0x1e,0x0,
-+0x11,0x11,0x1f,0x21,0x5f,0x1,0xff,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x0,0x10,0xf8,0x0,0xf0,0x4,0xfe,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x10,
-+0x10,0x1e,0x12,0x32,0x4a,0x4,0x8,0x30,0xdf,0x10,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x8,0xfc,0x88,0x88,0xa8,0x90,0x82,0x7e,0xf0,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x10,
-+0x0,0x4,0x7e,0x44,0x44,0x7d,0x47,0x44,0x7c,0x45,0x45,0x45,0x7d,0x45,0x1,0x1,0x20,0x20,0x40,0x40,0x88,0x4,0xfe,0x2,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0x0,0x7d,0x44,0x44,0x7c,0x47,0x44,0x7c,0x44,0x45,0x44,0x7c,0x44,0x3,0x0,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x0,0x8,0x7c,0x48,0x4a,0x7a,0x4a,0x4a,0x7a,0x4a,0x4a,0x4a,0x7a,0x4b,0x6,0x0,0x10,0x90,0x90,0x90,0x90,0x92,0xf6,0x98,0x90,0x90,0x90,0x90,0xf2,0x92,0x1e,0x0,
-+0x0,0x4,0x7e,0x45,0x46,0x7c,0x44,0x44,0x7f,0x44,0x44,0x45,0x7c,0x44,0x0,0x3,0x40,0x40,0xfc,0x8,0x90,0x60,0x40,0xa0,0x3e,0x42,0x84,0x44,0x28,0x10,0x60,0x80,
-+0x0,0x8,0x7c,0x49,0x4b,0x78,0x49,0x49,0x7a,0x48,0x4f,0x48,0x78,0x48,0x0,0x0,0x40,0x40,0x90,0x8,0xfc,0x20,0x28,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x0,0x0,0x78,0x4f,0x48,0x7a,0x49,0x48,0x7f,0x48,0x48,0x49,0x79,0x4a,0x4,0x0,0x40,0x40,0x48,0xfc,0x40,0x48,0x50,0x64,0xfe,0xc0,0xe0,0x50,0x48,0x4e,0x44,0x40,
-+0x0,0x8,0x7c,0x49,0x4a,0x7c,0x49,0x48,0x7a,0x4a,0x49,0x49,0x79,0x48,0x7,0x0,0x40,0x40,0xa0,0x10,0xe,0x24,0xf0,0x0,0x48,0x48,0x48,0x50,0x50,0x24,0xfe,0x0,
-+0x2,0x9,0x7c,0x4b,0x48,0x78,0x4b,0x4a,0x7a,0x4b,0x48,0x49,0x7a,0x44,0x0,0x0,0x8,0x10,0xa0,0xf8,0x48,0x48,0xf8,0x40,0x44,0xfe,0xc4,0x44,0x54,0x48,0x40,0x40,
-+0x0,0x8,0x7c,0x49,0x4b,0x78,0x49,0x4a,0x78,0x49,0x49,0x4a,0x7c,0x48,0x1,0x6,0x40,0x40,0x90,0x8,0xfc,0x90,0xc,0x84,0xf8,0x8,0x10,0xa0,0x40,0xa0,0x18,0x6,
-+0x0,0xb,0x7e,0x4a,0x4a,0x7a,0x4a,0x4b,0x7a,0x4a,0x4a,0x4a,0x7a,0x42,0x5,0x8,0x4,0xfe,0x20,0x20,0xf8,0x20,0x20,0xfc,0x20,0x20,0xf8,0x20,0x20,0x24,0xfe,0x0,
-+0x0,0x7d,0x45,0x45,0x45,0x7d,0x45,0x45,0x7d,0x44,0x44,0x44,0x7c,0x41,0x2,0xc,0x44,0x9e,0x4,0x4,0xdc,0x4,0x4,0xfc,0x54,0x50,0x50,0x90,0x92,0x12,0xe,0x0,
-+0x0,0x8,0x7c,0x49,0x49,0x7b,0x4d,0x49,0x79,0x49,0x49,0x49,0x79,0x49,0x1,0x1,0xc0,0xa0,0x84,0xfe,0x20,0x28,0xfc,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,0x0,
-+0x0,0x8,0x7f,0x4a,0x4a,0x7b,0x4a,0x4a,0x7b,0x48,0x49,0x4f,0x78,0x48,0x0,0x0,0x40,0x84,0xfe,0x44,0x44,0xfc,0x44,0x44,0xfc,0xa0,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x1,0x1,0x41,0x7f,0x40,0x9f,0x9,0x32,0xc,0x3f,0xd0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0xf8,0x0,0xfe,0x2,0xf4,0x20,0x98,0x60,0xf0,0x1e,0xf0,0x10,0xf0,0x10,0xf0,
-+0x0,0x7d,0x45,0x45,0x45,0x7d,0x45,0x45,0x7c,0x47,0x44,0x44,0x7c,0x44,0x1,0x6,0x24,0xae,0x24,0x24,0xac,0x24,0x24,0xfc,0x20,0xfc,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x0,0x3,0x78,0x4a,0x49,0x79,0x4a,0x4d,0x78,0x48,0x4b,0x48,0x78,0x48,0x1,0x6,0x28,0xb0,0xa4,0xa8,0x10,0x8,0xe,0xf4,0x40,0x48,0xfc,0x40,0xa0,0xa0,0x1c,0x8,
-+0x7e,0x24,0x18,0xfe,0x2b,0x28,0x48,0x89,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x40,0x44,0x7e,0x88,0x50,0x20,0x50,0x8e,0xf0,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x10,
-+0x0,0x0,0x7b,0x48,0x4f,0x78,0x49,0x4b,0x78,0x4b,0x4a,0x4a,0x7a,0x4a,0x7,0x0,0x40,0x48,0xfc,0x40,0xfe,0x80,0x10,0xf8,0x0,0xfc,0x94,0x94,0x94,0x94,0xfe,0x0,
-+0x0,0x7b,0x4a,0x4c,0x49,0x79,0x49,0x49,0x79,0x48,0x48,0x4f,0x78,0x48,0x1,0x2,0x0,0xfe,0x2,0x4,0xf8,0x8,0xf8,0x8,0xf8,0x40,0x24,0xfe,0x0,0x88,0x6,0x2,
-+0x0,0x7,0x78,0x48,0x4b,0x7a,0x4a,0x4b,0x78,0x49,0x48,0x4f,0x79,0x4a,0x4,0x0,0x4,0xfe,0x90,0x94,0xfe,0x94,0x94,0xfc,0x0,0xf8,0x0,0xfe,0x50,0x4c,0x44,0xc0,
-+0x0,0x9,0x7c,0x48,0x4b,0x7a,0x4d,0x49,0x79,0x49,0x48,0x49,0x78,0x48,0x3,0x0,0x20,0x24,0xa8,0x20,0xfe,0x2,0xfc,0x4,0x4,0xfc,0x20,0xfc,0x20,0x24,0xfe,0x0,
-+0x0,0xb,0x7c,0x48,0x4f,0x7a,0x4a,0x4b,0x7a,0x4a,0x4b,0x4a,0x7a,0x4f,0x0,0x0,0x10,0x90,0x90,0x9e,0xe4,0x54,0x54,0xd4,0x54,0x4c,0xc8,0x54,0xf4,0x54,0x62,0x40,
-+0x0,0x2,0x79,0x4f,0x49,0x7a,0x4c,0x4a,0x7b,0x4a,0x4a,0x4d,0x79,0x42,0x4,0x0,0x40,0x48,0x50,0xfe,0x50,0x48,0x46,0x8,0xbc,0xa8,0xa8,0x28,0x7e,0x8,0x8,0x8,
-+0x8,0xff,0x8,0x7f,0x22,0x3e,0x14,0x1f,0xf0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x1f,0x10,0xfe,0x10,0x7c,0x44,0x28,0x10,0x28,0x46,0xf0,0x10,0xf0,0x10,0xf0,0x10,0xf0,
-+0x0,0x3,0x7c,0x54,0x54,0x54,0x54,0x7c,0x54,0x54,0x54,0x54,0x7c,0x44,0x0,0x0,0x4,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x0,0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x0,0xff,0x8,0x8,0x8,0x8,0x10,0x20,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x4,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x0,0x4,0x7e,0x54,0x54,0x57,0x54,0x7c,0x54,0x54,0x54,0x55,0x7d,0x42,0x4,0x8,0x40,0x60,0x50,0x50,0x44,0xfe,0x40,0x40,0x40,0xa0,0xa0,0x10,0x10,0x8,0xe,0x4,
-+0x0,0x4,0x7e,0x54,0x54,0x55,0x56,0x7c,0x54,0x54,0x54,0x54,0x7c,0x44,0x1,0x2,0x40,0x40,0x40,0x84,0xfe,0x8,0x88,0x88,0x50,0x50,0x20,0x50,0x50,0x88,0x6,0x4,
-+0x0,0x4,0x7f,0x55,0x55,0x55,0x55,0x7d,0x55,0x55,0x55,0x55,0x7e,0x42,0x4,0x1,0x8,0x1c,0xe0,0x0,0x0,0xfc,0x4,0x44,0x48,0x28,0x28,0x10,0x28,0x28,0x44,0x82,
-+0x0,0x4,0x7e,0x54,0x55,0x56,0x54,0x7c,0x57,0x54,0x54,0x55,0x7c,0x44,0x0,0x3,0x40,0x40,0xa0,0xa0,0x18,0x16,0x20,0xc8,0x10,0x20,0x44,0x88,0x10,0x20,0xc0,0x0,
-+0x1,0x2,0xc,0x17,0xe0,0x1f,0x9,0x11,0x25,0x2,0x1f,0x11,0x1f,0x11,0x1f,0x10,0x0,0x80,0x60,0xd0,0xe,0xf0,0x20,0x18,0x8,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x10,
-+0x0,0x4,0x7f,0x56,0x55,0x55,0x55,0x7d,0x55,0x56,0x54,0x54,0x7c,0x45,0x2,0x4,0x40,0x20,0xfe,0x2,0x4,0xde,0x54,0x54,0x54,0xd4,0x5c,0x94,0x90,0x12,0xe,0x0,
-+0x0,0x5,0x7e,0x54,0x57,0x54,0x55,0x7d,0x55,0x55,0x55,0x54,0x7d,0x44,0x3,0x0,0x20,0xfc,0x88,0x50,0xfe,0x0,0xfc,0x24,0xfc,0x24,0xfc,0x20,0xfc,0x20,0xfe,0x0,
-+0x0,0x3f,0x24,0x24,0x24,0x3f,0x0,0xff,0x0,0x1,0x3,0x5,0x19,0x61,0x1,0x1,0x8,0xfc,0x48,0x48,0x48,0xf8,0x4,0xfe,0x80,0x0,0x0,0x60,0x18,0x4,0x0,0x0,
-+0x0,0x3f,0x24,0x24,0x24,0x3f,0x0,0x3f,0x1,0x11,0x11,0x11,0x11,0x11,0xff,0x0,0x8,0xfc,0x48,0x48,0x48,0xf8,0x0,0xfc,0x0,0x10,0xf8,0x0,0x0,0x4,0xfe,0x0,
-+0x0,0x7f,0x44,0x44,0x7f,0x1,0x1,0xff,0x1,0x1,0x1f,0x10,0x10,0x10,0x1f,0x10,0x4,0xfe,0x44,0x44,0xfc,0x0,0x4,0xfe,0x0,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,
-+0x0,0x7f,0x44,0x44,0x7f,0x1,0xff,0x0,0x3f,0x0,0x3f,0x0,0x1f,0x10,0x10,0x1f,0x4,0xfe,0x44,0x44,0xfc,0x0,0xfe,0x0,0xf8,0x0,0xf8,0x0,0xf0,0x10,0x10,0xf0,
-+0x0,0x7f,0x44,0x44,0x7f,0x2,0xff,0x4,0x9,0x3f,0xd1,0x1f,0x11,0x1f,0x1,0x0,0x4,0xfe,0x44,0x44,0xfc,0x0,0xfe,0x40,0x20,0xf8,0x16,0xf0,0x10,0xf4,0x4,0xfc,
-+0x0,0x7f,0x44,0x44,0x7f,0x1,0x3f,0x1,0xff,0x2,0x4,0x1f,0x0,0x24,0x22,0x42,0x4,0xfe,0x44,0x44,0xfc,0x0,0xf8,0x0,0xfe,0x0,0x20,0xf0,0x0,0x88,0x44,0x44,
-+0x0,0x7f,0x44,0x44,0x7f,0x1,0xff,0x1,0x3f,0x24,0x2f,0x21,0x3f,0x21,0x21,0x20,0x4,0xfe,0x44,0x44,0xfc,0x0,0xfe,0x8,0xfc,0x48,0xe8,0x8,0xf8,0x8,0x28,0x10,
-+0x0,0x7f,0x44,0x44,0x7f,0x11,0x11,0x5b,0x52,0x97,0x1a,0x13,0x12,0x12,0x13,0x12,0x4,0xfe,0x44,0x44,0xfc,0x40,0x24,0xfe,0x20,0xfc,0x20,0xfc,0x20,0x24,0xfe,0x0,
-+0x0,0x7f,0x44,0x7f,0x22,0xff,0x22,0x3e,0x8,0x7f,0x49,0x7f,0x8,0xff,0x8,0x8,0x4,0xfe,0x44,0xfc,0x0,0xf8,0x8,0x48,0x48,0x48,0x7c,0x4,0xf4,0x4,0x14,0x8,
-+0x0,0x3f,0x24,0x3f,0x8,0x7f,0x51,0x49,0x7f,0x40,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x8,0xfc,0x48,0xf8,0x20,0xfc,0x14,0x24,0xfc,0x4,0xf0,0x10,0xf0,0x10,0xf0,0x10,
-+0x1,0x1,0x3f,0x1,0x1,0x7f,0x4,0x8,0x1f,0x0,0x3f,0x24,0x24,0x24,0xff,0x0,0x0,0x10,0xf8,0x0,0x8,0xfc,0x0,0x20,0xf0,0x8,0xfc,0x48,0x48,0x48,0xfe,0x0,
-+0x9,0x71,0x4d,0x45,0x75,0x49,0x41,0x75,0x42,0x3f,0x24,0x24,0x24,0x24,0xff,0x0,0x4,0x3e,0xc4,0x84,0x5c,0x44,0x24,0x1c,0x4,0xf8,0x48,0x48,0x48,0x48,0xfe,0x0,
-+0x0,0x45,0x29,0xff,0x1,0x28,0x44,0x1,0x7f,0x45,0x65,0x55,0x4c,0x44,0xff,0x0,0x4,0xfe,0x54,0x54,0xfc,0x84,0xfe,0x44,0xf4,0x54,0x54,0xf4,0x54,0x74,0x94,0x8,
-+0x10,0x14,0x1e,0x20,0x20,0x7c,0x90,0x14,0xfe,0x10,0x10,0x12,0x14,0x18,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x14,0x1e,0x20,0x20,0x7c,0x90,0x14,0xfe,0x10,0x10,0x12,0x14,0x18,0x10,0x0,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x82,0x82,0x82,0x7e,0x0,
-+0x10,0x14,0x1e,0x20,0x20,0x7c,0x90,0x14,0xfe,0x10,0x10,0x11,0x15,0x19,0x10,0x0,0x0,0x0,0xfc,0x8,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x14,0x1e,0x20,0x20,0x7c,0x90,0x14,0xfe,0x10,0x10,0x12,0x14,0x18,0x10,0x0,0x40,0x40,0x40,0x40,0x40,0x60,0x50,0x48,0x44,0x44,0x40,0x40,0x40,0x40,0x40,0x40,
-+0x10,0x12,0x1f,0x20,0x24,0x7e,0x90,0x12,0xff,0x10,0x10,0x12,0x14,0x18,0x10,0x0,0x4,0x4,0x4,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x4,0x4,0x14,0x8,
-+0x10,0x14,0x1e,0x20,0x20,0x7c,0x90,0x14,0xfe,0x10,0x10,0x12,0x14,0x18,0x10,0x0,0x0,0x0,0xfc,0x4,0x8,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x10,0x14,0x1e,0x20,0x20,0x7c,0x91,0x14,0xfe,0x10,0x10,0x12,0x14,0x18,0x13,0x0,0x20,0x20,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x15,0x1f,0x21,0x21,0x7d,0x91,0x15,0xff,0x11,0x11,0x13,0x15,0x19,0x12,0x4,0x4,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x4,0x4,
-+0x10,0x12,0x1f,0x20,0x24,0x7e,0x90,0x12,0xff,0x10,0x10,0x12,0x14,0x18,0x11,0x6,0x4,0xc,0x10,0x20,0x40,0x84,0xc,0x10,0x20,0x42,0x6,0x8,0x10,0x60,0x80,0x0,
-+0x12,0x11,0x1c,0x22,0x22,0x7e,0x92,0x12,0xfe,0x12,0x12,0x12,0x16,0x1a,0x12,0x2,0x4,0x7e,0x84,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x14,0x8,
-+0x10,0x14,0x1e,0x20,0x21,0x7c,0x90,0x14,0xfe,0x10,0x10,0x12,0x14,0x18,0x11,0x6,0x0,0x4,0xfe,0x4,0x44,0xa8,0xa8,0x48,0x50,0x20,0x50,0x50,0x88,0x88,0x6,0x4,
-+0x10,0x14,0x1e,0x20,0x20,0x7f,0x90,0x14,0xfe,0x11,0x10,0x12,0x14,0x18,0x11,0x6,0x40,0x40,0x40,0x40,0x44,0xfe,0x88,0x88,0x88,0x8,0x88,0x50,0x20,0x50,0x8c,0x4,
-+0x10,0x14,0x1f,0x20,0x20,0x7c,0x90,0x14,0xfe,0x11,0x12,0x10,0x14,0x18,0x10,0x0,0x0,0x4,0xfe,0x10,0x10,0x20,0x20,0x60,0xa8,0x26,0x22,0x20,0x20,0x20,0x20,0x20,
-+0x10,0x14,0x1e,0x20,0x20,0x7f,0x90,0x14,0xfe,0x10,0x10,0x15,0x19,0x12,0x4,0x8,0x40,0x40,0x40,0x40,0x44,0xfe,0x40,0x40,0xa0,0xa0,0x90,0x10,0x88,0x48,0x46,0x4,
-+0x10,0x15,0x1f,0x21,0x21,0x7d,0x91,0x15,0xff,0x11,0x11,0x11,0x15,0x19,0x11,0x0,0x8,0xfc,0x0,0x0,0x8,0xfc,0x8,0x8,0x8,0xf8,0x0,0x0,0x0,0x4,0xfe,0x0,
-+0x10,0x14,0x1f,0x21,0x21,0x7d,0x91,0x15,0xff,0x11,0x11,0x11,0x15,0x1a,0x12,0x5,0x8,0x1c,0xe0,0x0,0x0,0xfc,0x4,0x44,0x48,0x48,0x30,0x10,0x28,0x48,0x86,0x4,
-+0x10,0x14,0x1e,0x20,0x21,0x7e,0x94,0x10,0xfe,0x11,0x10,0x12,0x14,0x18,0x10,0x0,0x40,0x40,0xa0,0xa0,0x10,0x8e,0x44,0x40,0x0,0xf8,0x8,0x10,0x10,0x20,0x40,0x80,
-+0x10,0x14,0x1e,0x21,0x20,0x7c,0x90,0x14,0xfe,0x10,0x10,0x10,0x15,0x19,0x12,0x4,0x40,0x20,0x24,0xfe,0x40,0x44,0x7e,0x44,0x44,0x44,0x84,0x84,0x4,0x4,0x28,0x10,
-+0x10,0x14,0x1e,0x21,0x20,0x7c,0x90,0x14,0xfe,0x10,0x10,0x12,0x15,0x19,0x12,0x4,0x40,0x20,0x4,0xfe,0x0,0x10,0xf8,0x90,0x90,0x90,0x90,0x90,0x12,0x12,0xe,0x0,
-+0x10,0x14,0x1e,0x20,0x24,0x7e,0x90,0x14,0xfe,0x10,0x13,0x10,0x14,0x18,0x10,0x0,0x8,0x88,0x48,0x48,0x8,0x88,0x48,0x48,0xe,0x78,0x88,0x8,0x8,0x8,0x8,0x8,
-+0x10,0x14,0x1e,0x20,0x20,0x7c,0x90,0x11,0xfe,0x10,0x10,0x12,0x14,0x18,0x11,0x2,0x20,0x20,0x20,0x20,0xa4,0xac,0xb0,0x20,0x20,0x50,0x50,0x50,0x88,0x88,0x6,0x4,
-+0x10,0x15,0x1f,0x21,0x21,0x7d,0x91,0x11,0xff,0x11,0x11,0x13,0x15,0x19,0x10,0x0,0x4,0xfe,0x24,0x24,0x24,0x24,0x24,0xfc,0x4,0x0,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x15,0x1e,0x20,0x20,0x7c,0x90,0x11,0xfe,0x10,0x10,0x12,0x14,0x18,0x13,0x0,0x4,0xfe,0x20,0x20,0x20,0x20,0x28,0xfc,0x20,0x30,0x28,0x28,0x20,0x24,0xfe,0x0,
-+0x10,0x13,0x1e,0x20,0x20,0x7c,0x91,0x11,0xfd,0x11,0x11,0x11,0x15,0x19,0x17,0x0,0x4,0xfe,0x20,0x20,0x20,0x20,0x24,0x3e,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x14,0x1e,0x20,0x23,0x7c,0x90,0x10,0xfd,0x11,0x11,0x11,0x15,0x19,0x11,0x1,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x24,0xfe,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x14,0x1f,0x20,0x20,0x7d,0x91,0x11,0xff,0x11,0x11,0x11,0x14,0x18,0x10,0x0,0x0,0x4,0xfe,0x8,0x8,0xe8,0x28,0x28,0x28,0x28,0xe8,0x8,0x8,0x8,0x28,0x10,
-+0x10,0x15,0x1f,0x21,0x21,0x7d,0x91,0x11,0xff,0x11,0x11,0x11,0x15,0x19,0x11,0x0,0x4,0xfe,0x0,0x8,0x7c,0x48,0x48,0x48,0x48,0x48,0x78,0x48,0x0,0x4,0xfe,0x0,
-+0x10,0x10,0x1e,0x23,0x20,0x7c,0x91,0x13,0xfd,0x11,0x11,0x11,0x15,0x19,0x10,0x0,0x40,0x40,0x44,0xfe,0x80,0xa0,0x24,0xfe,0x24,0x24,0x24,0x24,0x34,0x28,0x20,0x20,
-+0x10,0x14,0x1e,0x20,0x23,0x7c,0x90,0x14,0xfe,0x10,0x10,0x13,0x15,0x19,0x12,0x4,0x40,0x50,0x48,0x48,0xfe,0x40,0x40,0xfc,0x84,0xa4,0xa8,0x28,0x10,0x28,0x46,0x84,
-+0x10,0x14,0x1e,0x20,0x21,0x7d,0x91,0x15,0xff,0x11,0x11,0x13,0x15,0x19,0x10,0x0,0x20,0x28,0x24,0x20,0xfe,0x20,0x20,0x24,0x24,0x24,0x18,0x50,0x92,0x2a,0x4a,0x84,
-+0x10,0x15,0x1f,0x21,0x21,0x7d,0x91,0x11,0xff,0x11,0x11,0x13,0x15,0x19,0x11,0x1,0x4,0xfe,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x14,0x1f,0x21,0x21,0x7d,0x91,0x11,0xff,0x11,0x11,0x11,0x14,0x18,0x13,0x0,0x0,0x4,0xfe,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0xfc,0x4,0x0,0x0,0xfe,0x0,
-+0x10,0x14,0x1f,0x21,0x21,0x7d,0x91,0x11,0xfd,0x11,0x11,0x11,0x15,0x19,0x11,0x1,0x0,0x4,0xfe,0x24,0x24,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0x24,0x24,0xfc,0x4,
-+0x10,0x10,0x1d,0x21,0x21,0x7d,0x91,0x15,0xfe,0x10,0x10,0x10,0x15,0x1a,0x10,0x0,0x8,0x1c,0xe0,0x0,0x20,0x20,0x24,0xfe,0x20,0x20,0xa8,0xa4,0x26,0x22,0xa0,0x40,
-+0x10,0x10,0x1e,0x23,0x20,0x7c,0x91,0x15,0xff,0x11,0x11,0x11,0x15,0x19,0x10,0x0,0x40,0x20,0x24,0xfe,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x24,0x2c,0x20,0x20,
-+0x10,0x10,0x1e,0x23,0x20,0x7c,0x90,0x11,0xfd,0x10,0x10,0x12,0x14,0x19,0x13,0x0,0x40,0x20,0x24,0xfe,0x40,0x40,0x88,0x8,0xf0,0x20,0x40,0x40,0x88,0x4,0xfc,0x4,
-+0x10,0x10,0x1e,0x23,0x22,0x7c,0x90,0x14,0xfc,0x10,0x10,0x10,0x14,0x18,0x10,0x0,0x40,0x20,0x20,0xfe,0x2,0x84,0x80,0x90,0xb0,0xc0,0x80,0x80,0x82,0x82,0x7e,0x0,
-+0x10,0x14,0x1e,0x20,0x20,0x7c,0x90,0x12,0xfe,0x12,0x14,0x10,0x15,0x1a,0x14,0x0,0x0,0x44,0x24,0x28,0x88,0x90,0x90,0xa4,0xa2,0xc2,0x82,0x80,0x84,0x84,0x7c,0x0,
-+0x10,0x15,0x1f,0x21,0x21,0x7d,0x91,0x15,0xff,0x11,0x11,0x11,0x15,0x19,0x12,0x4,0x4,0xfe,0x4,0x4,0xfc,0x0,0x40,0x44,0x4c,0x50,0x60,0x40,0x42,0x42,0x3e,0x0,
-+0x10,0x14,0x1e,0x21,0x21,0x7d,0x91,0x15,0xff,0x11,0x11,0x11,0x15,0x1a,0x12,0x5,0x20,0x20,0x20,0xfe,0x22,0x24,0x20,0xfc,0x8,0x48,0x50,0x20,0x50,0x48,0x8e,0x4,
-+0x10,0x15,0x1e,0x20,0x20,0x7c,0x90,0x13,0xfe,0x10,0x10,0x11,0x14,0x18,0x10,0x0,0x0,0xfc,0x88,0x50,0x20,0x50,0x8e,0x24,0xf8,0x20,0x28,0xfc,0x20,0x20,0x20,0x20,
-+0x10,0x14,0x1f,0x20,0x24,0x7f,0x90,0x10,0xfd,0x12,0x14,0x12,0x14,0x18,0x10,0x0,0x40,0x44,0xf8,0x50,0x64,0xfe,0x40,0x88,0xfc,0x40,0x7c,0x4,0x4,0x44,0x28,0x10,
-+0x10,0x10,0x1d,0x20,0x20,0x7c,0x93,0x10,0xfd,0x12,0x14,0x10,0x14,0x18,0x10,0x0,0x40,0x44,0xfc,0x48,0x50,0x64,0xfe,0x80,0x88,0x98,0xa0,0xc0,0x84,0x84,0x7c,0x0,
-+0x10,0x17,0x1d,0x21,0x21,0x7d,0x91,0x11,0xfd,0x11,0x11,0x11,0x17,0x18,0x10,0x0,0x4,0xfe,0x8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0x3e,0xc8,0x8,0x8,0x8,
-+0x10,0x14,0x1f,0x20,0x21,0x7d,0x93,0x15,0xfd,0x11,0x11,0x11,0x15,0x19,0x11,0x1,0x80,0x84,0xfe,0x80,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x10,0x10,0x1c,0x23,0x22,0x7e,0x92,0x13,0xfe,0x12,0x12,0x17,0x1a,0x12,0x4,0x8,0x10,0x18,0x14,0xfe,0x10,0x10,0x10,0xd4,0x54,0x54,0x54,0x58,0x88,0xa,0xa,0x6,
-+0x10,0x10,0x1e,0x23,0x20,0x7e,0x91,0x10,0xff,0x10,0x10,0x10,0x15,0x19,0x12,0xc,0x40,0x40,0x48,0xfc,0x40,0x48,0x50,0x44,0xfe,0x40,0xa0,0xa0,0x10,0x10,0xe,0x4,
-+0x10,0x10,0x1e,0x23,0x20,0x7c,0x91,0x14,0xff,0x10,0x10,0x10,0x15,0x19,0x12,0x4,0x40,0x40,0x5c,0xe0,0x28,0x32,0xce,0x0,0xfc,0x90,0x90,0x90,0x12,0x12,0xe,0x0,
-+0x20,0x2f,0x38,0x22,0x42,0x7c,0xa4,0x27,0xf9,0x21,0x22,0x2a,0x34,0x24,0xa,0x1,0x0,0xfc,0xa4,0xa4,0xa4,0xa8,0xa4,0xe4,0xa2,0xa2,0xa2,0xb4,0xa8,0xa0,0xa0,0x20,
-+0x10,0x15,0x1e,0x20,0x20,0x7c,0x93,0x10,0xfe,0x10,0x11,0x10,0x14,0x18,0x13,0x0,0x20,0x24,0xa4,0xa8,0xb0,0x24,0xfe,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x20,0x23,0x3a,0x22,0x43,0x78,0xa0,0x27,0xfc,0x24,0x24,0x24,0x2c,0x34,0x20,0x0,0x8,0xfc,0x8,0x8,0xf8,0x40,0x44,0xfe,0x44,0x44,0x44,0x44,0x54,0x48,0x40,0x40,
-+0x20,0x27,0x3c,0x24,0x44,0x7c,0xa7,0x24,0xfc,0x24,0x24,0x25,0x2c,0x34,0x27,0x4,0x4,0xfe,0x4,0x44,0x44,0x54,0xfc,0x44,0x44,0xa4,0x94,0x14,0x4,0x4,0xfc,0x4,
-+0x10,0x15,0x1f,0x21,0x21,0x7c,0x91,0x14,0xfe,0x11,0x11,0x11,0x15,0x19,0x10,0x0,0x20,0x24,0x24,0x24,0xfc,0x0,0xfc,0x4,0x4,0xfc,0x4,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x11,0x1d,0x21,0x22,0x7e,0x90,0x13,0xfc,0x10,0x10,0x14,0x19,0x12,0x4,0x0,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x60,0x70,0xa8,0xa8,0x24,0x26,0x20,0x20,
-+0x10,0x10,0x1c,0x27,0x20,0x7d,0x92,0x13,0xfc,0x10,0x14,0x12,0x15,0x19,0x12,0x4,0x0,0xc,0x70,0x90,0x90,0x14,0x7e,0x90,0x90,0x90,0x94,0xfe,0x0,0x80,0x46,0x3c,
-+0x10,0x10,0x1d,0x20,0x20,0x7d,0x90,0x10,0xfc,0x13,0x10,0x12,0x14,0x19,0x13,0x0,0x8,0x3c,0xe0,0x20,0x20,0xfc,0x20,0x20,0x24,0xfe,0x40,0x40,0x90,0x8,0xfc,0x4,
-+0x10,0x10,0x1c,0x20,0x21,0x7e,0x94,0x10,0xfc,0x10,0x13,0x10,0x14,0x18,0x10,0x0,0x50,0x50,0x94,0x98,0x90,0xb0,0xd2,0x8e,0xa0,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x10,0x10,0x1c,0x21,0x22,0x7f,0x90,0x10,0xfc,0x13,0x10,0x10,0x14,0x18,0x17,0x0,0x40,0x40,0xa0,0x10,0x8,0xfe,0x44,0x40,0x40,0xf8,0x40,0x40,0x40,0x48,0xfc,0x0,
-+0x10,0x10,0x1e,0x20,0x21,0x7e,0x91,0x10,0xfe,0x11,0x11,0x11,0x15,0x19,0x11,0x1,0x20,0x20,0x50,0x88,0x4,0x2,0xfc,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x11,0x14,0x1e,0x20,0x20,0x7c,0x91,0x10,0xfd,0x10,0x10,0x12,0x15,0x1a,0x10,0x0,0x4,0x8c,0x50,0x20,0x50,0x8c,0x24,0x20,0xfe,0x20,0xa8,0xa4,0x22,0x22,0xa0,0x40,
-+0x10,0x14,0x1e,0x20,0x24,0x7e,0x91,0x10,0xfc,0x11,0x16,0x10,0x15,0x19,0x12,0x4,0x20,0xa0,0xa0,0xa0,0xa4,0xac,0xb0,0xa0,0xa0,0xb0,0xa8,0xa8,0x22,0x22,0x1e,0x0,
-+0x10,0x14,0x1e,0x21,0x20,0x7d,0x90,0x10,0xfd,0x10,0x10,0x11,0x14,0x18,0x10,0x0,0x40,0x40,0xf8,0x10,0x24,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x24,0x20,0xa0,0x40,
-+0x10,0x14,0x1e,0x21,0x22,0x7d,0x91,0x15,0xff,0x11,0x11,0x13,0x15,0x19,0x10,0x0,0x80,0x80,0xf8,0x10,0x24,0xfe,0x24,0x24,0x24,0xfc,0x4,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x14,0x1e,0x23,0x20,0x7c,0x90,0x15,0xfe,0x10,0x10,0x12,0x14,0x19,0x12,0x0,0x40,0x20,0x24,0xfe,0x40,0x88,0x84,0xfc,0x90,0x90,0x90,0x90,0x92,0x12,0xe,0x0,
-+0x20,0x24,0x3b,0x41,0x40,0x74,0xa2,0x22,0xf8,0x21,0x22,0x22,0x2c,0x35,0x22,0x0,0x0,0xfc,0x8,0x10,0x20,0x44,0xfe,0x54,0x54,0x54,0x54,0x94,0xa4,0x24,0x54,0x88,
-+0x10,0x10,0x1e,0x23,0x22,0x7c,0x90,0x17,0xfc,0x10,0x11,0x10,0x14,0x18,0x11,0x2,0x40,0x20,0x20,0xfe,0x2,0x44,0x40,0xfe,0x88,0x88,0x8,0x90,0x60,0x90,0xc,0x4,
-+0x11,0x11,0x1d,0x27,0x21,0x7d,0x91,0x11,0xfd,0x12,0x11,0x14,0x19,0x12,0x4,0x0,0x0,0x0,0x4,0xde,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x94,0x54,0x5c,0x14,0x0,
-+0x10,0x10,0x1f,0x20,0x20,0x7b,0x92,0x12,0xfd,0x10,0x10,0x10,0x14,0x18,0x11,0x2,0x88,0x88,0xfe,0x88,0x88,0xfe,0x42,0x44,0xfe,0x44,0x44,0x44,0x84,0x84,0x28,0x10,
-+0x20,0x20,0x3b,0x40,0x42,0x79,0xa0,0x27,0xf8,0x20,0x21,0x21,0x2a,0x34,0x28,0x0,0x40,0x40,0xfc,0x40,0x48,0x50,0x44,0xfe,0x40,0xe0,0x50,0x50,0x48,0x46,0x44,0x40,
-+0x20,0x20,0x38,0x47,0x40,0x7a,0xa1,0x20,0xfa,0x22,0x26,0x2a,0x2a,0x32,0x21,0x0,0x20,0x28,0x24,0xfe,0x20,0x20,0xa0,0xa0,0x10,0x90,0x50,0x50,0x90,0x8a,0x86,0x2,
-+0x20,0x22,0x3a,0x42,0x42,0x7a,0xa2,0x22,0xf8,0x20,0x20,0x25,0x28,0x30,0x23,0x0,0x80,0xfc,0xa4,0xa8,0x90,0xa8,0xa6,0xc4,0x80,0xa0,0x28,0xfc,0x20,0x24,0xfe,0x0,
-+0x10,0x15,0x1f,0x21,0x21,0x7d,0x90,0x13,0xfc,0x10,0x11,0x10,0x14,0x18,0x13,0x0,0x4,0xfe,0x4,0x4,0x4,0xfc,0x0,0xfe,0x20,0x20,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x15,0x1f,0x21,0x21,0x7d,0x91,0x11,0xff,0x10,0x11,0x10,0x14,0x18,0x13,0x0,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x24,0x20,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x10,0x1c,0x21,0x21,0x7e,0x90,0x13,0xfc,0x11,0x11,0x11,0x15,0x19,0x11,0x1,0x20,0xa0,0xa4,0xfe,0x20,0x20,0x24,0xfe,0x0,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x1c,0x23,0x20,0x7f,0x90,0x10,0xfc,0x11,0x12,0x10,0x14,0x18,0x12,0x1,0x10,0x58,0x94,0x90,0x90,0xfe,0x90,0x94,0xd4,0x98,0x90,0xb0,0xd2,0x92,0x8a,0x4,
-+0x10,0x14,0x1e,0x21,0x21,0x7d,0x91,0x12,0xfc,0x10,0x11,0x10,0x14,0x18,0x13,0x0,0x20,0x20,0x20,0x24,0x24,0x28,0xac,0x72,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x14,0x1f,0x20,0x21,0x7c,0x90,0x10,0xfd,0x10,0x11,0x10,0x14,0x18,0x10,0x0,0x8,0x1c,0xe0,0x44,0x24,0xa8,0x90,0x8,0xfe,0x8,0x8,0x88,0x88,0x8,0x28,0x10,
-+0x10,0x14,0x1f,0x20,0x20,0x7d,0x93,0x10,0xfd,0x11,0x11,0x11,0x15,0x19,0x12,0x4,0x40,0x24,0xfe,0x80,0x90,0x8,0xfc,0x4,0x50,0x50,0x50,0x50,0x52,0x52,0x4e,0x0,
-+0x12,0x11,0x1c,0x22,0x22,0x7f,0x92,0x12,0xfe,0x13,0x12,0x12,0x16,0x1b,0x12,0x2,0x4,0x7e,0x84,0x4,0x4,0xfc,0x94,0x94,0x94,0xfc,0x94,0x94,0x94,0x14,0x4,0xc,
-+0x12,0x11,0x1c,0x22,0x22,0x7e,0x92,0x12,0xfe,0x12,0x12,0x12,0x16,0x1a,0x12,0x2,0x4,0x7e,0x84,0x4,0x4,0xf4,0x94,0x94,0xf4,0x94,0x94,0xf4,0x94,0x4,0x14,0x8,
-+0x10,0x14,0x1f,0x21,0x21,0x7d,0x91,0x11,0xfd,0x11,0x11,0x13,0x15,0x19,0x11,0x1,0x40,0x28,0xfc,0x8,0x8,0xf8,0x8,0x8,0xfc,0x48,0x50,0x20,0x10,0x48,0x86,0x0,
-+0x10,0x11,0x1e,0x20,0x20,0x7d,0x90,0x13,0xfe,0x14,0x10,0x12,0x14,0x18,0x10,0x3,0x4,0xfe,0x4,0xfc,0x4,0xfc,0x0,0xfe,0x2,0xfc,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x10,0x13,0x1e,0x22,0x23,0x7e,0x92,0x13,0xfe,0x12,0x12,0x16,0x1a,0x12,0x4,0x8,0x4,0xfe,0x4,0x4,0xfc,0x0,0x4,0xfe,0x4,0xf4,0x94,0x94,0xf4,0x4,0x14,0x8,
-+0x20,0x27,0x3d,0x45,0x45,0x7e,0xa5,0x25,0xfd,0x25,0x27,0x25,0x2c,0x34,0x24,0x4,0x0,0x4,0xfe,0x4,0x4,0x74,0x54,0x54,0x54,0x54,0x54,0x74,0x44,0x4,0x14,0x8,
-+0x10,0x14,0x1f,0x20,0x21,0x7c,0x93,0x10,0xfd,0x11,0x11,0x11,0x15,0x19,0x11,0x1,0x20,0x24,0xfe,0x20,0xfc,0x20,0xfe,0x0,0xfc,0x4,0xfc,0x4,0xfc,0x4,0x14,0x8,
-+0x10,0x10,0x1f,0x20,0x20,0x7c,0x97,0x10,0xfc,0x11,0x13,0x15,0x11,0x19,0x11,0x1,0x88,0x88,0xfe,0x88,0x40,0x44,0xfe,0x80,0x84,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x1f,0x20,0x21,0x7e,0x95,0x10,0xfd,0x11,0x1f,0x11,0x15,0x19,0x12,0x4,0x40,0x44,0xfe,0xa0,0x10,0x4e,0xf4,0x40,0x50,0x14,0xfe,0x10,0x10,0x10,0x10,0x10,
-+0x10,0x15,0x1f,0x21,0x21,0x7d,0x90,0x15,0xfe,0x10,0x13,0x10,0x14,0x18,0x10,0x0,0x4,0xfe,0x4,0xfc,0x4,0xfc,0x0,0xfc,0x8,0x8,0xfe,0x88,0x48,0x8,0x28,0x10,
-+0x10,0x15,0x1f,0x21,0x21,0x7d,0x91,0x11,0xfc,0x13,0x10,0x10,0x14,0x19,0x12,0x0,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0xfe,0x20,0x70,0xa8,0x26,0x24,0x20,
-+0x10,0x15,0x1f,0x21,0x21,0x7d,0x91,0x11,0xfe,0x11,0x11,0x13,0x15,0x19,0x11,0x0,0x4,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x10,0x14,0xd8,0x10,0x12,0x52,0x8e,0x0,
-+0x10,0x15,0x1f,0x21,0x21,0x7d,0x91,0x11,0xff,0x11,0x11,0x13,0x15,0x19,0x11,0x1,0x4,0xfe,0x4,0x24,0x24,0xfc,0x24,0x24,0x74,0x54,0x54,0x74,0x54,0x4,0xfc,0x4,
-+0x11,0x11,0x1d,0x22,0x22,0x7c,0x91,0x11,0xfe,0x10,0x13,0x13,0x15,0x19,0x10,0x0,0x0,0x4,0xfe,0x94,0x94,0xa4,0x24,0x54,0x8,0x40,0x28,0x26,0xa,0x8,0xf8,0x0,
-+0x10,0x14,0x1f,0x20,0x21,0x7c,0x90,0x13,0xfc,0x11,0x11,0x11,0x15,0x19,0x11,0x1,0x40,0x28,0xfc,0x0,0x8,0x90,0x4,0xfe,0x0,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x12,0x1d,0x20,0x23,0x7c,0x97,0x10,0xfd,0x13,0x15,0x11,0x15,0x19,0x11,0x0,0x40,0x48,0x50,0x40,0xfc,0x40,0xfe,0xa0,0x10,0xf8,0x16,0x10,0x50,0x24,0x4,0xfc,
-+0x10,0x14,0x1e,0x20,0x21,0x7c,0x90,0x13,0xfe,0x10,0x10,0x11,0x14,0x18,0x10,0x3,0x20,0x24,0xac,0xb0,0x20,0x58,0x86,0x22,0x20,0xa4,0xac,0x30,0x50,0x50,0x8e,0x4,
-+0x21,0x21,0x3a,0x44,0x42,0x79,0xa1,0x27,0xfc,0x24,0x27,0x24,0x2c,0x34,0x27,0x4,0x24,0x24,0x48,0x90,0x48,0x24,0x24,0xfe,0x44,0x44,0xfc,0x44,0x44,0x44,0xfc,0x4,
-+0x21,0x21,0x3f,0x41,0x47,0x79,0xa7,0x21,0xf9,0x20,0x27,0x20,0x28,0x30,0x21,0x6,0x0,0x4,0xfe,0x14,0xd4,0x14,0xd4,0x24,0x4c,0x40,0xfe,0x40,0xa0,0x90,0xe,0x4,
-+0x10,0x12,0x1f,0x22,0x22,0x7e,0x93,0x10,0xfd,0x11,0x11,0x11,0x15,0x19,0x11,0x1,0x20,0x24,0xa8,0x30,0x22,0xa2,0x5e,0x88,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x10,0x11,0x1d,0x21,0x21,0x7d,0x91,0x11,0xfd,0x10,0x12,0x12,0x14,0x18,0x10,0x0,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x4,0x40,0xa8,0xa4,0x8a,0x8a,0x78,0x0,
-+0x10,0x15,0x1f,0x21,0x21,0x7c,0x91,0x10,0xff,0x10,0x10,0x10,0x14,0x18,0x10,0x0,0x0,0xdc,0x54,0x54,0xdc,0x8,0xfc,0x0,0xfe,0x80,0xf8,0x8,0x8,0x8,0x50,0x20,
-+0x20,0x20,0x3b,0x40,0x48,0x7f,0xa0,0x21,0xfe,0x24,0x24,0x27,0x2c,0x34,0x27,0x4,0x8,0x7c,0xc0,0x40,0x44,0xfe,0x40,0x44,0x5e,0x44,0x44,0x5c,0x44,0x44,0xfc,0x4,
-+0x10,0x10,0x1d,0x21,0x21,0x7d,0x91,0x11,0xfe,0x11,0x10,0x12,0x14,0x18,0x11,0x6,0x20,0xac,0x24,0x24,0xac,0x24,0x24,0xfc,0x20,0xfc,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x10,0x13,0x1c,0x21,0x20,0x7d,0x90,0x13,0xfc,0x10,0x11,0x11,0x16,0x1a,0x14,0x1,0x3c,0xc0,0x24,0x24,0xa8,0xfc,0x40,0xfe,0x80,0xfc,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x10,0x14,0x1f,0x20,0x21,0x7d,0x91,0x11,0xfe,0x10,0x10,0x10,0x15,0x1a,0x14,0x0,0x40,0x24,0xfe,0x0,0xfc,0x4,0x4,0xfc,0x40,0x44,0xa8,0x90,0x90,0xa8,0xc6,0x84,
-+0x10,0x11,0x1c,0x20,0x23,0x7c,0x90,0x11,0xfc,0x13,0x10,0x11,0x14,0x18,0x10,0x3,0x20,0x24,0xa8,0x20,0xfe,0x70,0xa8,0x26,0x40,0xfe,0x88,0x8,0xd0,0x30,0xcc,0x4,
-+0x21,0x21,0x39,0x45,0x43,0x79,0xa1,0x21,0xfb,0x25,0x29,0x21,0x29,0x31,0x21,0x1,0x20,0x20,0x3c,0x44,0xa8,0x10,0x28,0x48,0xfe,0x8,0x48,0x28,0x28,0x8,0x28,0x10,
-+0x21,0x21,0x3f,0x41,0x47,0x7d,0xa7,0x21,0xfb,0x22,0x22,0x22,0x2a,0x30,0x21,0x6,0x10,0x14,0xfe,0x14,0xfc,0x10,0xfe,0x12,0xfe,0x8,0x48,0x48,0x48,0xb0,0xc,0x4,
-+0x10,0x15,0x1f,0x21,0x21,0x7d,0x91,0x11,0xfe,0x12,0x12,0x16,0x1a,0x12,0x4,0x8,0x4,0xfe,0x24,0x24,0xfc,0x0,0xfc,0x84,0x84,0xfc,0x84,0xfc,0x84,0x84,0xfc,0x84,
-+0x11,0x11,0x1f,0x21,0x23,0x7e,0x93,0x12,0xff,0x10,0x10,0x17,0x14,0x18,0x11,0x6,0x10,0x14,0xfe,0x10,0xf8,0x8,0xf8,0x8,0xf8,0x40,0x44,0xfe,0x40,0xa0,0x1c,0x8,
-+0x20,0x27,0x38,0x43,0x42,0x7a,0xa3,0x20,0xff,0x25,0x24,0x27,0x2c,0x34,0x24,0x4,0x8,0xfc,0x0,0xf8,0x8,0x8,0xf8,0x4,0xfe,0x14,0xa4,0xfc,0x44,0x44,0x54,0x8,
-+0x10,0x10,0x1d,0x21,0x23,0x7d,0x91,0x11,0xfd,0x11,0x13,0x10,0x14,0x19,0x12,0x4,0xa0,0xa8,0xfc,0x20,0xf8,0x20,0xf8,0x20,0xfe,0x0,0xf8,0x88,0x9c,0x4,0x28,0x10,
-+0x20,0x20,0x39,0x43,0x44,0x7b,0xa2,0x23,0xf8,0x27,0x20,0x23,0x28,0x37,0x20,0x0,0x40,0xa0,0x10,0xf8,0x6,0xf8,0x8,0xf8,0x1c,0xe0,0x40,0xf8,0x40,0xfe,0x40,0xc0,
-+0x20,0x27,0x3c,0x44,0x45,0x7d,0xa6,0x20,0xff,0x24,0x24,0x27,0x2c,0x34,0x27,0x4,0x84,0x7e,0x24,0x24,0x24,0xa4,0x54,0x88,0xfc,0x44,0x44,0xfc,0x44,0x44,0xfc,0x4,
-+0x10,0x14,0x1e,0x20,0x23,0x7c,0x90,0x15,0xfe,0x11,0x11,0x11,0x15,0x19,0x13,0x0,0x0,0x88,0x50,0x4,0xfe,0x50,0x8c,0x4,0x0,0xfc,0x54,0x54,0x54,0x54,0xfe,0x0,
-+0x10,0x12,0x1f,0x22,0x24,0x7f,0x90,0x10,0xff,0x10,0x13,0x10,0x14,0x1b,0x10,0x0,0x40,0x20,0xfe,0x2,0x4,0xfe,0x40,0xc4,0x68,0xb0,0x30,0x68,0xa8,0x26,0xa4,0x40,
-+0x10,0x12,0x1f,0x22,0x24,0x7d,0x91,0x11,0xfd,0x11,0x11,0x17,0x14,0x19,0x12,0x4,0x40,0x20,0xfe,0x2,0x34,0xc0,0x8,0xfc,0x10,0x10,0x14,0xfe,0x0,0x10,0xc,0x4,
-+0x10,0x13,0x1c,0x20,0x21,0x7d,0x91,0x15,0xfe,0x11,0x10,0x13,0x14,0x19,0x12,0x0,0x4,0xfe,0x50,0x54,0xfe,0x54,0x54,0xfc,0x0,0xfc,0x0,0xfe,0xa8,0x26,0x22,0x60,
-+0x20,0x22,0x39,0x40,0x47,0x7c,0xa9,0x21,0xf9,0x21,0x20,0x23,0x28,0x30,0x2f,0x0,0x40,0x48,0x50,0x40,0xfe,0x2,0xf4,0x10,0x10,0xf0,0x40,0xf8,0x40,0x44,0xfe,0x0,
-+0x20,0x23,0x3a,0x43,0x42,0x7b,0xa0,0x27,0xfc,0x27,0x20,0x23,0x29,0x30,0x23,0xc,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x4,0xfe,0xa4,0xfc,0x0,0xf8,0x10,0xe0,0x10,0xe,
-+0x20,0x27,0x3c,0x47,0x44,0x7f,0xa0,0x21,0xfb,0x20,0x20,0x27,0x29,0x32,0x24,0x0,0x4,0xfe,0x44,0xfc,0x44,0xfc,0x80,0x8,0xf0,0x20,0x48,0xfc,0x50,0x4c,0x44,0xc0,
-+0x20,0x27,0x3c,0x45,0x44,0x7f,0xa4,0x25,0xfc,0x25,0x25,0x25,0x2d,0x35,0x29,0x11,0x20,0xfe,0x20,0xfc,0x24,0xfe,0x24,0xfc,0x20,0xfc,0x24,0xfc,0x24,0xfc,0x24,0x2c,
-+0x22,0x21,0x39,0x47,0x42,0x7a,0xa3,0x22,0xfa,0x22,0x22,0x22,0x2c,0x34,0x29,0x0,0x20,0x20,0x24,0xfe,0x40,0x20,0xbc,0xd0,0x94,0xfe,0x90,0x90,0xa8,0xa6,0xc2,0x0,
-+0x24,0x22,0x38,0x4f,0x44,0x7c,0xa7,0x25,0xfd,0x25,0x25,0x2d,0x35,0x25,0xb,0x11,0x40,0x40,0x44,0xfe,0x80,0x0,0x7e,0x14,0x10,0x54,0x5e,0x50,0x50,0x70,0x9e,0x4,
-+0x20,0x28,0x3f,0x41,0x40,0x7f,0xa4,0x24,0xff,0x24,0x25,0x25,0x2d,0x35,0x24,0x4,0x80,0x44,0xfe,0x10,0xa4,0xfe,0x44,0x54,0xfc,0x44,0xf4,0x14,0x14,0xf4,0x4,0xc,
-+0x10,0x13,0x1c,0x21,0x21,0x7d,0x90,0x15,0xff,0x11,0x11,0x11,0x14,0x1b,0x10,0x0,0x4,0xfe,0x50,0xfc,0x54,0xfc,0x0,0xfc,0x4,0xfc,0x4,0xfc,0x20,0xfe,0x20,0x20,
-+0x20,0x2f,0x38,0x4a,0x49,0x7f,0xa8,0x2a,0xfa,0x2a,0x2b,0x28,0x38,0x29,0x12,0x24,0x4,0xfe,0x8,0x28,0x48,0xee,0x92,0xa4,0xa8,0xa8,0xe8,0xa8,0x94,0x14,0x24,0x42,
-+0x20,0x24,0x3a,0x40,0x4f,0x79,0xa0,0x27,0xf8,0x23,0x20,0x27,0x28,0x30,0x21,0x6,0xa0,0xa4,0xa8,0xa0,0xfe,0x10,0xa0,0xfc,0x40,0xf8,0x40,0xfc,0x40,0xa0,0x1c,0x8,
-+0x10,0x10,0x1d,0x23,0x21,0x7d,0x91,0x11,0xfc,0x13,0x10,0x11,0x15,0x19,0x11,0x1,0x80,0xf8,0x10,0xfc,0x24,0xfc,0x24,0xfc,0x0,0xfe,0x0,0xfc,0x4,0xfc,0x4,0xfc,
-+0x22,0x21,0x3f,0x40,0x47,0x7c,0xa4,0x27,0xf8,0x27,0x20,0x21,0x2f,0x31,0x25,0x2,0x10,0x10,0xf4,0x1e,0xe4,0x54,0x54,0xd4,0x14,0xc8,0x88,0xd4,0x14,0x24,0x22,0x40,
-+0x24,0x22,0x39,0x44,0x47,0x7c,0xa5,0x25,0xfd,0x25,0x25,0x24,0x2d,0x36,0x24,0x4,0x4,0xfe,0x44,0x54,0xfc,0x44,0xf4,0x54,0xf4,0x54,0xf4,0xe4,0x54,0x4c,0x44,0x4c,
-+0x11,0x10,0x1f,0x20,0x22,0x7d,0x90,0x17,0xfc,0x11,0x11,0x11,0x15,0x19,0x11,0x1,0x8,0x90,0xfc,0x90,0x94,0x98,0x90,0xfe,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,
-+0x20,0x20,0x3f,0x45,0x4a,0x78,0xa3,0x22,0xfb,0x20,0x23,0x22,0x2b,0x32,0x20,0x0,0x80,0x40,0xfe,0x12,0x4c,0x40,0xf8,0x48,0xf8,0x40,0xf8,0x48,0xf8,0x48,0x40,0x40,
-+0x20,0x27,0x39,0x41,0x41,0x7f,0xa4,0x24,0xfc,0x27,0x21,0x21,0x29,0x31,0x2a,0x4,0x4,0x7e,0x44,0x44,0x7c,0x10,0xfe,0x92,0x92,0x92,0xfe,0x10,0x10,0x14,0xfe,0x42,
-+0x20,0x23,0x38,0x42,0x41,0x7b,0xa4,0x23,0xfa,0x22,0x23,0x20,0x29,0x30,0x2f,0x0,0x28,0xb0,0xa4,0x98,0x10,0xf8,0x4,0xfa,0x8,0x8,0xf8,0x0,0x10,0xa4,0xfe,0x0,
-+0x21,0x27,0x39,0x41,0x42,0x7f,0xa2,0x23,0xfa,0x23,0x22,0x23,0x29,0x30,0x23,0xc,0x8,0xfe,0x28,0xfe,0x20,0xfc,0x20,0xfc,0x20,0xfe,0x0,0xf8,0x10,0xe0,0x18,0x6,
-+0x20,0x27,0x3c,0x44,0x47,0x79,0xa3,0x24,0xf8,0x27,0x24,0x27,0x28,0x30,0x27,0x0,0x4,0xfe,0xa4,0xa4,0xfc,0x0,0xfc,0x84,0x84,0xf4,0x94,0xf4,0x84,0xa4,0xf4,0x8,
-+0x20,0x28,0x3f,0x41,0x48,0x7f,0xa0,0x23,0xfe,0x23,0x22,0x2b,0x30,0x25,0x9,0x0,0x80,0x48,0xfc,0x10,0xa4,0xfe,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x40,0x24,0xa,0xf8,
-+0x20,0x20,0x3f,0x45,0x41,0x7a,0xa7,0x2d,0xf3,0x24,0x2b,0x20,0x29,0x32,0x24,0x0,0x80,0x40,0xfe,0x2,0xbc,0xa4,0xa8,0x10,0xf8,0x6,0xf8,0x40,0x50,0x4c,0x44,0xc0,
-+0x20,0x20,0x3f,0x44,0x47,0x7c,0xa7,0x25,0xfd,0x25,0x25,0x2d,0x34,0x25,0x9,0x12,0x40,0x24,0xfe,0x90,0xfc,0x94,0xfc,0x10,0xd4,0x18,0x52,0x8e,0x0,0x54,0x52,0x2,
-+0x20,0x20,0x3b,0x40,0x4f,0x78,0xa3,0x2a,0xff,0x22,0x23,0x20,0x2b,0x30,0x2f,0x0,0x8,0x1c,0xe0,0x44,0xfe,0x40,0xf8,0x48,0xf8,0x48,0xf8,0x40,0xf8,0x40,0xfe,0x0,
-+0x20,0x23,0x20,0x3c,0x50,0x93,0x12,0xfe,0x12,0x13,0x10,0x28,0x24,0x44,0x81,0x0,0x44,0xe4,0x44,0x44,0x44,0xc4,0x44,0x4,0x24,0xf4,0x24,0x24,0x24,0x24,0x44,0x84,
-+0x20,0x20,0x22,0x3e,0x52,0x92,0x15,0xfc,0x10,0x10,0x13,0x28,0x24,0x40,0x8f,0x0,0x40,0x40,0x48,0x48,0x48,0x48,0x54,0xe2,0x40,0x48,0xfc,0x40,0x40,0x44,0xfe,0x0,
-+0x20,0x20,0x20,0x3d,0x51,0x93,0x15,0xfd,0x11,0x11,0x11,0x29,0x25,0x45,0x81,0x1,0x80,0xa0,0x94,0xfe,0x20,0x28,0xfc,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,0x0,
-+0x0,0xe,0xf2,0x12,0x12,0xfe,0x13,0x32,0x3a,0x56,0x52,0x92,0x12,0x13,0x12,0x10,0x20,0x20,0x20,0x20,0x20,0x24,0xac,0x30,0x20,0x20,0x20,0x20,0xa2,0x22,0x1e,0x0,
-+0x0,0xc,0xf0,0x13,0x12,0xfe,0x12,0x33,0x38,0x54,0x51,0x92,0x14,0x10,0x10,0x10,0x40,0x50,0x78,0xc0,0x40,0x40,0x44,0xfe,0x44,0xc4,0x44,0x54,0x48,0x40,0x40,0x40,
-+0x0,0xc,0xf0,0x17,0x10,0xfc,0x13,0x30,0x38,0x55,0x51,0x92,0x14,0x10,0x10,0x10,0x40,0x40,0x44,0xfe,0x40,0x48,0xfc,0xc0,0xe0,0x50,0x50,0x48,0x4e,0x44,0x40,0x40,
-+0x0,0xc,0xf0,0x10,0x17,0xfc,0x10,0x30,0x38,0x55,0x51,0x91,0x12,0x14,0x18,0x10,0x40,0x50,0x48,0x48,0xfe,0x40,0x40,0xc0,0xe0,0x50,0x50,0x48,0x4e,0x44,0x40,0x40,
-+0x0,0xd,0xf1,0x11,0x11,0xfd,0x11,0x30,0x38,0x57,0x52,0x92,0x12,0x12,0x13,0x12,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x0,0xc,0xf0,0x17,0x10,0xfc,0x11,0x31,0x3a,0x54,0x50,0x92,0x12,0x12,0x13,0x10,0x80,0xa0,0x94,0xfe,0xa0,0xa0,0x22,0x22,0x1e,0x40,0x40,0x48,0x48,0x48,0xf8,0x8,
-+0x8,0xc,0xf7,0x12,0x11,0xfc,0x13,0x30,0x38,0x54,0x57,0x90,0x10,0x10,0x11,0x10,0x8,0x3c,0xc0,0x48,0x50,0x0,0xf8,0x10,0x60,0x44,0xfe,0x40,0x40,0x40,0x40,0x80,
-+0x0,0xc,0xf3,0x12,0x12,0xff,0x12,0x32,0x3b,0x56,0x52,0x92,0x12,0x12,0x13,0x12,0x80,0x48,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x84,0x4c,0x50,0x20,0x90,0xe,0x4,
-+0x4,0xf,0xf1,0x11,0x15,0xff,0x11,0x31,0x38,0x57,0x50,0x90,0x10,0x11,0x12,0x10,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0xfe,0x20,0x70,0xa8,0x26,0x24,0x20,
-+0x0,0xc,0xf0,0x10,0x11,0xfe,0x14,0x31,0x38,0x54,0x50,0x95,0x15,0x19,0x10,0x10,0x40,0x40,0xa0,0xa0,0x10,0x8e,0x44,0xf0,0x10,0xa0,0x40,0x44,0x12,0x12,0xf0,0x0,
-+0x0,0xc,0xf7,0x10,0x13,0xfe,0x13,0x32,0x3b,0x56,0x53,0x92,0x1f,0x11,0x12,0x14,0x40,0x48,0xfc,0x40,0xf8,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x8,0xfe,0x10,0xc,0x4,
-+0x0,0xd,0xf1,0x11,0x11,0xfd,0x11,0x31,0x39,0x56,0x50,0x91,0x12,0x10,0x11,0x16,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x44,0x7a,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x0,0xc,0xf7,0x10,0x12,0xf9,0x17,0x30,0x3f,0x54,0x55,0x95,0x15,0x14,0x17,0x14,0x40,0x48,0xfc,0x40,0x48,0x50,0xfe,0x4,0xfe,0x4,0xf4,0x14,0xf4,0x4,0xfc,0x4,
-+0x0,0x6,0x78,0x9,0xff,0x1c,0x2a,0x48,0x14,0x2a,0x6b,0x9c,0x1a,0x69,0x8,0x18,0x20,0x20,0x24,0x3e,0xa0,0x20,0x24,0xfe,0x84,0x84,0x84,0x84,0x84,0x84,0xfc,0x84,
-+0x4,0xe,0xf1,0x12,0xfe,0x10,0x38,0x56,0x92,0x7c,0x44,0x7d,0x46,0x7c,0x44,0x1,0x84,0xfe,0x0,0xfc,0x84,0xfc,0x84,0xfc,0x40,0xfc,0x84,0x88,0x50,0x20,0x50,0x8e,
-+0x4,0xb,0xf0,0x17,0x14,0xff,0x11,0x37,0x39,0x57,0x51,0x9f,0x11,0x13,0x1d,0x11,0x40,0xfe,0x0,0xbc,0xa4,0xbc,0x10,0xfc,0x10,0xf8,0x10,0xfe,0x48,0x30,0x8e,0x4,
-+0x10,0x10,0x21,0x7d,0x45,0x45,0x45,0x7d,0x45,0x45,0x45,0x45,0x7e,0x42,0x4,0xb,0x8,0x1c,0xe0,0x0,0x0,0x0,0xfc,0x4,0x84,0x88,0x48,0x50,0x20,0x50,0x8e,0x4,
-+0x10,0x10,0x20,0x7f,0x48,0x49,0x4a,0x4d,0x79,0x48,0x48,0x48,0x48,0x79,0x42,0xc,0x80,0x40,0x44,0xfe,0x0,0x10,0xc,0x14,0x10,0xa0,0x40,0xa0,0xa0,0x10,0xe,0x4,
-+0x10,0x11,0x21,0x79,0x49,0x4a,0x48,0x4f,0x78,0x49,0x49,0x49,0x49,0x79,0x49,0x1,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x8,0x8,0xfe,0x8,0x1c,0x2a,0x48,0x89,0xa,0x1f,0x10,0x1f,0x10,0x10,0x1f,0x10,0xc,0xf0,0x80,0x84,0xfe,0x90,0x90,0x10,0x10,0xf8,0x10,0xf0,0x10,0x10,0xf0,0x10,
-+0x10,0x17,0x20,0x7a,0x4f,0x48,0x49,0x4a,0x7f,0x4a,0x4a,0x4b,0x4a,0x7a,0x4b,0x2,0x38,0xc0,0x48,0x54,0xfe,0xe0,0x50,0x48,0xfe,0x48,0x48,0xf8,0x48,0x48,0xf8,0x8,
-+0x2,0x7,0x7a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x2a,0x29,0x2a,0x5e,0x40,0x80,0x10,0x10,0x50,0x54,0x7e,0x90,0x14,0xfe,0x10,0x28,0x26,0x42,0x80,0x40,0x3e,0x4,
-+0x10,0x12,0xff,0x28,0x26,0x42,0xbc,0x0,0xfe,0x20,0x7c,0x4,0x4,0x44,0x29,0x12,0x0,0xc,0xf8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xc8,0xd4,0x74,0x2,
-+0x0,0x7f,0x4,0x2,0x1,0x3f,0x21,0x21,0x3f,0x21,0x21,0x3f,0x21,0x21,0x21,0x20,0x10,0xf8,0x20,0xc0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x20,0x20,0x21,0x29,0xfd,0x29,0x29,0x29,0x29,0x29,0x28,0x2a,0x4d,0x48,0x80,0x0,0x20,0x48,0xfc,0x8,0x48,0x8,0x28,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x4,0x4,0x2,0xff,0x0,0x4,0x1f,0x14,0x12,0x10,0x10,0x1f,0x0,0x7f,0x0,0x0,0x80,0x44,0x7e,0x80,0x82,0x62,0xfe,0x20,0x20,0xa0,0x44,0xfe,0x4,0xe4,0x14,0x8,
-+0x0,0x40,0x49,0x59,0x61,0x45,0x45,0x3d,0x11,0x11,0xfe,0x10,0x13,0x10,0x10,0x10,0x20,0x48,0xfc,0x8,0x48,0x8,0x28,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x10,0x10,0x11,0x51,0x7f,0x53,0x95,0x11,0x11,0x29,0x28,0x2a,0x4d,0x48,0x80,0x0,0x20,0x48,0xfc,0x8,0x48,0x8,0x28,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x10,0x10,0x11,0x15,0xff,0x11,0x11,0x11,0x7d,0x45,0x44,0x44,0x47,0x7c,0x44,0x0,0x20,0x48,0xfc,0x8,0x48,0x8,0x28,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x10,0x10,0x15,0xff,0x21,0x51,0x95,0xff,0x11,0x39,0x34,0x54,0x93,0x10,0x50,0x20,0x20,0x48,0xfc,0x8,0x48,0x8,0x28,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x10,0x14,0x1f,0x11,0x15,0x7f,0x45,0x45,0x7d,0x45,0x40,0x40,0x43,0x40,0x80,0x0,0x20,0x48,0xfc,0x8,0x48,0x8,0x28,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x20,0x20,0x25,0x7f,0x85,0x5,0x75,0x55,0x55,0x55,0x74,0x54,0x5,0x8,0x28,0x10,0x20,0x48,0xfc,0x8,0x48,0x8,0x28,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x0,0x6,0x79,0x51,0x51,0x55,0x7f,0x49,0x49,0x49,0x48,0x44,0x45,0x54,0x6a,0x1,0x20,0x48,0xfc,0x8,0x48,0x8,0x28,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x94,0x8,
-+0x8,0x8,0x32,0xc,0x10,0x3e,0x0,0xff,0x2,0x1f,0x12,0x11,0x1f,0x0,0x7f,0x0,0x20,0x20,0xc8,0x30,0x40,0xf8,0x4,0xfe,0x0,0xf0,0x10,0x24,0xfe,0x4,0xe4,0xc,
-+0x0,0x1,0xff,0x8,0x10,0x7f,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x41,0x43,0x0,0x10,0x24,0xfe,0x44,0x54,0x44,0x54,0x48,0x40,0x7e,0x2,0x12,0xfa,0x2,0xa,0x4,
-+0x8,0x8,0xfe,0x8,0xe,0x78,0x9,0x1a,0x1f,0x12,0x11,0x1f,0x0,0x7f,0x0,0x0,0x40,0x48,0xfc,0x48,0xc8,0xaa,0xa,0x6,0xe0,0x20,0x44,0xfe,0x4,0xf4,0x4,0x18,
-+0x0,0xc,0x71,0x11,0x11,0x15,0xff,0x11,0x15,0x7f,0x44,0x44,0x47,0x7c,0x44,0x0,0x20,0x48,0xfc,0x8,0x48,0x8,0x28,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x12,0x12,0x12,0x22,0x3f,0x62,0xa6,0x27,0x2a,0x2a,0x32,0x22,0x22,0x22,0x22,0x22,0x10,0x24,0x7e,0x44,0xd4,0x44,0x54,0x48,0xc0,0x7e,0x2,0x12,0xfa,0x2,0xa,0x4,
-+0x2,0x1,0xff,0x4,0x14,0x25,0x46,0x1f,0x12,0x11,0x10,0x1f,0x0,0x7f,0x0,0x0,0x0,0x4,0xfe,0x40,0x50,0x4c,0x44,0xe0,0x20,0x20,0x44,0xfe,0x4,0xf4,0x4,0x18,
-+0x8,0xa,0x7f,0x8,0x48,0x7f,0x41,0x82,0x3e,0x4,0x8,0xfe,0xb,0x8,0x28,0x10,0x20,0x48,0xfc,0x88,0xa8,0x88,0xa8,0x90,0x84,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x0,0x1,0xff,0x0,0x0,0x77,0x55,0x55,0x55,0x77,0x55,0x55,0x55,0x55,0x55,0x0,0x10,0x24,0xfe,0x44,0x54,0x44,0x54,0x48,0x40,0x7e,0x2,0x12,0xfa,0x2,0xa,0x4,
-+0x8,0x28,0x2a,0x3f,0x48,0x88,0xa,0xff,0x0,0x3e,0x22,0x22,0x23,0x22,0x3e,0x22,0x20,0x48,0xfc,0x88,0xa8,0x88,0xa8,0x90,0x84,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x0,0x28,0x45,0x93,0x11,0x29,0x45,0x83,0x7d,0x45,0x44,0x44,0x47,0x7c,0x44,0x0,0x20,0x48,0xfc,0x8,0x48,0x8,0x28,0x10,0x4,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x40,0x2f,0x11,0x49,0x49,0x7f,0x49,0x59,0x5d,0x5b,0x69,0x49,0x49,0x41,0x45,0x42,0x10,0x24,0x7e,0x44,0x54,0x44,0x54,0x48,0x40,0x7e,0x2,0x12,0xfa,0x2,0xa,0x4,
-+0x22,0x14,0x7f,0x9,0x9,0x7f,0x48,0x48,0x7f,0x9,0x19,0x1d,0x2a,0xc8,0x8,0x8,0x10,0x24,0x7e,0x44,0x54,0x44,0x54,0x48,0x40,0x7e,0x2,0x12,0xfa,0x2,0xa,0x4,
-+0x4,0x6,0x7d,0x4,0x4,0xff,0x14,0x54,0x5c,0x54,0x52,0x52,0x5e,0xf1,0x40,0x0,0x10,0x24,0x7e,0x44,0x54,0x44,0x54,0x48,0x40,0x7e,0x2,0x12,0xfa,0x82,0x8a,0x4,
-+0x22,0x22,0xff,0x22,0x22,0x0,0x7f,0x49,0x49,0x49,0x7f,0x49,0x49,0x49,0x7f,0x41,0x10,0x24,0xfe,0x44,0x54,0x44,0x54,0x48,0x40,0x7e,0x2,0x12,0xfa,0x2,0xa,0x4,
-+0x8,0x9,0xff,0x14,0x12,0x29,0x7f,0xc9,0x7f,0x49,0x49,0x7f,0x8,0xa,0xc,0x8,0x10,0x24,0xfe,0x44,0x54,0x44,0xd4,0x48,0x40,0x7e,0x2,0x12,0xfa,0x2,0xa,0x4,
-+0x8,0x11,0x7f,0x49,0x49,0x7f,0x49,0x51,0x7f,0x10,0x29,0xff,0x8,0x8,0x8,0x8,0x10,0x24,0xfe,0x44,0x54,0x44,0x54,0x48,0x40,0x7e,0x2,0x92,0xfa,0x2,0xa,0x4,
-+0x10,0xa,0xff,0x0,0x3e,0x22,0x22,0x3e,0x0,0x7e,0x4,0xff,0x9,0x8,0x28,0x10,0x20,0x48,0xfc,0x88,0xa8,0x88,0xa8,0x90,0x84,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x20,0x27,0x25,0xfd,0x25,0x27,0x25,0x75,0x55,0x57,0x55,0x55,0x75,0x49,0x13,0x0,0x10,0x24,0x7e,0x44,0x54,0x44,0x54,0x48,0x40,0x7e,0x2,0x12,0xfa,0x2,0xa,0x4,
-+0x0,0x77,0x55,0x55,0x77,0x0,0x7f,0x0,0xff,0x20,0x3e,0x2,0x2,0x2,0x14,0x8,0x10,0x24,0x7e,0x44,0x54,0x44,0x54,0x48,0xc0,0x7e,0x2,0x12,0xfa,0x2,0xa,0x4,
-+0x0,0x41,0x22,0x0,0xff,0x0,0x22,0x22,0x55,0xff,0x22,0x22,0x55,0xff,0x11,0x0,0x10,0x24,0x7e,0x44,0xd4,0x44,0x54,0x48,0x40,0x7e,0x2,0x12,0xfa,0x2,0xa,0x4,
-+0x1,0x7f,0x49,0x49,0x7f,0x40,0x5f,0x51,0x51,0x5f,0x51,0x5f,0x51,0x51,0x9f,0x11,0x10,0xa4,0x7e,0x44,0x54,0x44,0x54,0x48,0x40,0x7e,0x2,0x12,0xfa,0x2,0xa,0x4,
-+0x7c,0x8,0xff,0x32,0x54,0x91,0x32,0x1f,0x12,0x11,0x10,0x1f,0x0,0x7f,0x0,0x0,0x80,0xfe,0x88,0x50,0x20,0x50,0x8e,0xe0,0x20,0x20,0x44,0xfe,0x4,0xf4,0x4,0x18,
-+0x2,0x7,0xf8,0x41,0x2a,0x2a,0x40,0x7e,0x88,0x9,0xff,0x8,0x49,0x49,0x7f,0x1,0x10,0x24,0x7e,0x44,0x54,0x44,0x54,0x48,0x40,0x7e,0x82,0x12,0xfa,0x2,0xa,0x4,
-+0x22,0x14,0x7f,0x14,0x7f,0x15,0xff,0x15,0x7f,0x14,0x36,0x55,0x94,0x14,0x14,0x14,0x10,0x24,0x7e,0x44,0x54,0x44,0xd4,0x48,0x40,0x7e,0x2,0x12,0xfa,0x2,0xa,0x4,
-+0x0,0x77,0x55,0x55,0x55,0x55,0x22,0x55,0x10,0xff,0x22,0x22,0x14,0x8,0x16,0x61,0x10,0x24,0x7e,0x44,0x54,0x44,0x54,0x48,0x40,0xfe,0x2,0x12,0xfa,0x2,0xa,0x4,
-+0x8,0x5,0x7f,0x52,0x52,0x52,0x7f,0x52,0x52,0x5e,0x40,0x52,0x52,0x6d,0x80,0x0,0x10,0x24,0xfe,0x44,0x54,0x44,0xd4,0x48,0x40,0x7e,0x2,0x12,0xfa,0x2,0xa,0x4,
-+0x0,0xee,0x22,0xaa,0x66,0xaa,0x32,0x10,0x28,0x46,0x9a,0x60,0x19,0x64,0x8,0x70,0x20,0x48,0xfc,0x88,0xa8,0x88,0xa8,0x90,0x84,0xfe,0x4,0x24,0xf4,0x4,0x14,0x8,
-+0x8,0x9,0xff,0x55,0x22,0x41,0xbe,0x22,0x3e,0x22,0x3e,0x8,0x2a,0x49,0x88,0x18,0x10,0x24,0xfe,0x44,0x54,0x44,0xd4,0x48,0x40,0x7e,0x2,0x12,0xfa,0x2,0x8a,0x4,
-+0x14,0x14,0x3f,0x24,0x64,0xbf,0x24,0x24,0x3f,0x24,0x24,0x3f,0x20,0x55,0x54,0x80,0x10,0x24,0x7e,0x44,0x54,0x44,0x54,0x48,0x40,0x7e,0x2,0x12,0xfa,0x2,0x8a,0x84,
-+0x8,0xff,0x22,0x3e,0x2a,0x49,0x9a,0x1f,0x12,0x11,0x10,0x1f,0x0,0x7f,0x0,0x0,0x28,0xa4,0xfe,0x20,0x52,0x92,0xe,0xe0,0x20,0x20,0x44,0xfe,0x4,0xe4,0x14,0x8,
-+0x2,0x7f,0x14,0x8,0xff,0x1a,0x28,0x49,0x7f,0x55,0x63,0x5d,0x55,0x5d,0x41,0x43,0x10,0x24,0x7e,0x44,0x54,0x44,0x54,0x48,0xc0,0x7e,0x2,0x12,0xfa,0x2,0xa,0x4,
-+0x10,0x23,0x7c,0x45,0x57,0x45,0x55,0x49,0x41,0x7f,0x2,0x12,0xfa,0x2,0xa,0x5,0x88,0xfe,0xa8,0xfc,0x20,0xfc,0x20,0xfc,0x20,0xfe,0x0,0xf8,0x48,0x30,0x48,0x86,
-+0x0,0x7c,0x45,0x7c,0x10,0x5d,0x50,0xfe,0x4,0x1f,0x12,0x11,0x1f,0x0,0x7f,0x0,0x80,0xf8,0x50,0x20,0x50,0xfe,0x88,0xf8,0x0,0xe0,0x20,0x44,0xfe,0x4,0xe4,0x18,
-+0x22,0xff,0x22,0x77,0x55,0x77,0x24,0x3f,0x64,0xbf,0x24,0x3f,0x24,0x24,0x3f,0x20,0x10,0xa4,0x7e,0x44,0x54,0x44,0x54,0x48,0x40,0x7e,0x2,0x12,0xfa,0x2,0x8a,0x4,
-+0x0,0x0,0x1f,0x10,0x90,0x50,0x50,0x10,0x30,0x50,0xd0,0x10,0x20,0x20,0x40,0x0,0x80,0x44,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x0,0x0,0x1f,0x10,0x90,0x5f,0x50,0x10,0x30,0x50,0xd0,0x10,0x20,0x20,0x41,0x0,0x80,0x44,0xfe,0x0,0x4,0xfe,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,
-+0x0,0x0,0x1f,0x10,0x90,0x57,0x50,0x10,0x30,0x50,0xd0,0x10,0x20,0x20,0x40,0x0,0x80,0x44,0xfe,0x0,0x4,0xfe,0x84,0x84,0x84,0x84,0xa4,0x94,0x88,0x80,0x80,0x80,
-+0x0,0x0,0x1f,0x10,0x90,0x5f,0x51,0x11,0x31,0x51,0xd1,0x12,0x22,0x24,0x48,0x10,0x80,0x44,0xfe,0x0,0x4,0xfe,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0x50,0x20,
-+0x0,0x0,0x1f,0x10,0x90,0x50,0x54,0x14,0x34,0x54,0xd4,0x14,0x24,0x27,0x40,0x0,0x80,0x44,0xfe,0x0,0x40,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0xfc,0x4,0x4,
-+0x0,0x0,0x1f,0x10,0x97,0x54,0x54,0x14,0x35,0x54,0xd4,0x14,0x28,0x28,0x51,0x2,0x80,0x44,0xfe,0x0,0xfc,0x0,0x40,0x44,0xfe,0x44,0x44,0x44,0x84,0x84,0x28,0x10,
-+0x0,0x0,0x1f,0x10,0x90,0x50,0x5f,0x10,0x30,0x51,0xd1,0x11,0x22,0x22,0x44,0x8,0x80,0x44,0xfe,0x80,0xa0,0x94,0xfe,0xa0,0xa0,0x20,0x20,0x20,0x22,0x22,0x1e,0x0,
-+0x0,0x0,0x1f,0x12,0x92,0x52,0x5f,0x12,0x32,0x52,0xd3,0x12,0x22,0x22,0x43,0x2,0x80,0x44,0xfe,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0xf0,0x10,0x10,0x10,0xf0,0x10,
-+0x0,0x0,0x1f,0x10,0x90,0x5f,0x50,0x10,0x33,0x52,0xd2,0x12,0x23,0x20,0x40,0x0,0x80,0x44,0xfe,0x0,0x4,0xfe,0x8,0x8,0xc8,0x48,0x48,0x48,0xc8,0x8,0x28,0x10,
-+0x0,0x0,0x1f,0x10,0x90,0x53,0x52,0x12,0x33,0x52,0xd2,0x13,0x22,0x20,0x4f,0x0,0x80,0x44,0xfe,0x0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x0,0xfe,0x0,
-+0x0,0x0,0x1f,0x11,0x91,0x51,0x52,0x12,0x34,0x58,0xd0,0x10,0x20,0x20,0x40,0x0,0x80,0x44,0xfe,0x0,0x8,0xfc,0x80,0x90,0xf8,0x80,0x88,0xfc,0x80,0x80,0x80,0x80,
-+0x0,0x0,0x1f,0x12,0x92,0x53,0x54,0x1b,0x32,0x52,0xd3,0x12,0x22,0x22,0x41,0x0,0x80,0x44,0xfe,0x0,0x8,0xfc,0x8,0xc8,0x48,0x48,0xc8,0x28,0x12,0x2,0xfe,0x0,
-+0x0,0x0,0x1f,0x10,0x90,0x50,0x57,0x10,0x30,0x50,0xd3,0x10,0x20,0x20,0x4f,0x0,0x80,0x44,0xfe,0x0,0x80,0x48,0xfc,0x40,0x40,0x50,0xf8,0x40,0x40,0x44,0xfe,0x0,
-+0x0,0x0,0x1f,0x10,0x90,0x5f,0x50,0x11,0x32,0x57,0xd0,0x10,0x21,0x22,0x47,0x0,0x80,0x44,0xfe,0x80,0x44,0xfe,0x80,0x0,0x10,0xe0,0x40,0x80,0x10,0x8,0xfc,0x4,
-+0x0,0x0,0x1f,0x12,0x92,0x52,0x5f,0x12,0x32,0x52,0xd2,0x12,0x24,0x24,0x4a,0x11,0x80,0x44,0xfe,0x0,0x0,0x4,0xbe,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xa4,0xbc,0x24,
-+0x0,0x0,0x1f,0x10,0x9f,0x51,0x51,0x19,0x35,0x55,0xd5,0x15,0x21,0x21,0x5f,0x0,0x80,0x44,0xfe,0x0,0xfc,0x20,0x20,0x24,0x24,0x28,0x28,0x30,0x20,0x24,0xfe,0x0,
-+0x1,0x0,0x3f,0x20,0xbf,0x60,0x2f,0x20,0x6f,0xa8,0x2f,0x20,0x41,0x41,0x86,0x18,0x0,0x84,0xfe,0x80,0xfe,0x80,0xf8,0x88,0xf8,0x80,0xfc,0x84,0x54,0x48,0x20,0x1c,
-+0x0,0x0,0x1f,0x10,0x90,0x5f,0x50,0x10,0x37,0x50,0xd0,0x15,0x25,0x29,0x40,0x0,0x80,0x44,0xfe,0x40,0x44,0xfe,0x40,0x48,0xfc,0x0,0x80,0x64,0x2a,0xa,0xf8,0x0,
-+0x0,0x0,0x1f,0x11,0x97,0x51,0x51,0x17,0x34,0x58,0xd3,0x10,0x20,0x21,0x42,0xc,0x80,0x44,0xfe,0x10,0xfc,0x10,0x10,0xfe,0x82,0x84,0xf8,0x88,0x88,0x8,0x28,0x10,
-+0x0,0x0,0x1f,0x10,0x97,0x50,0x53,0x11,0x31,0x5f,0xd0,0x13,0x22,0x22,0x43,0x2,0x80,0x44,0xfe,0x0,0xfc,0x80,0xf0,0x10,0x14,0xfe,0x0,0xf8,0x8,0x8,0xf8,0x8,
-+0x0,0x0,0x1f,0x10,0x92,0x52,0x52,0x15,0x38,0x50,0xd7,0x10,0x20,0x20,0x4f,0x0,0x80,0x44,0xfe,0x40,0x48,0x48,0x48,0x54,0xe2,0x48,0xfc,0x40,0x40,0x44,0xfe,0x0,
-+0x0,0x0,0x1f,0x12,0x91,0x55,0x54,0x17,0x34,0x54,0xd4,0x15,0x26,0x24,0x44,0x4,0x80,0x44,0xfe,0x0,0xfc,0x44,0x44,0xf4,0x44,0xc4,0xe4,0x54,0x4c,0x44,0x54,0x8,
-+0x0,0x0,0x1f,0x10,0x94,0x52,0x52,0x18,0x35,0x50,0xd2,0x14,0x2c,0x24,0x44,0x3,0x80,0x44,0xfe,0x20,0x20,0xa8,0xa4,0xa2,0x2a,0x28,0x30,0x10,0x20,0x40,0x80,0x0,
-+0x0,0x0,0x1f,0x10,0x9f,0x50,0x53,0x1c,0x35,0x52,0xdd,0x11,0x22,0x2c,0x41,0x0,0x80,0x44,0xfe,0x0,0xfc,0x80,0x8,0x98,0x60,0x40,0xe0,0x50,0x4e,0x44,0x40,0x80,
-+0x0,0x0,0x1f,0x11,0x91,0x5f,0x51,0x11,0x3f,0x51,0xd1,0x1f,0x21,0x21,0x41,0x1,0x80,0x44,0xfe,0x20,0x24,0x3e,0x20,0x28,0x3c,0x20,0x24,0x3e,0x20,0x20,0x20,0x20,
-+0x0,0x0,0x1f,0x10,0x97,0x54,0x54,0x17,0x34,0x55,0xd5,0x15,0x25,0x24,0x47,0x4,0x80,0x44,0xfe,0x0,0xfc,0x44,0x44,0xfc,0x44,0xf4,0x14,0x14,0xf4,0x4,0xfc,0x4,
-+0x0,0x0,0x1f,0x10,0x93,0x50,0x5f,0x11,0x36,0x50,0xdf,0x11,0x23,0x20,0x41,0x6,0x80,0x44,0xfe,0x0,0xf8,0x40,0xfe,0x50,0x4c,0x80,0xfe,0x10,0x20,0xc0,0x30,0x8,
-+0x1,0x0,0x3f,0x22,0xac,0x68,0x28,0x2e,0x68,0xa8,0x2f,0x28,0x41,0x42,0x8c,0x30,0x0,0x84,0xfe,0x80,0xb8,0x88,0x88,0xb8,0x88,0x88,0xf8,0x88,0x40,0x20,0x1e,0x4,
-+0x0,0x0,0x1f,0x14,0x92,0x50,0x5f,0x12,0x33,0x52,0xd2,0x14,0x24,0x2a,0x51,0x0,0x80,0x44,0xfe,0x0,0x10,0x10,0xe8,0x28,0xa4,0xc6,0xb0,0x88,0xa0,0x98,0x8,0x0,
-+0x1,0x0,0x3f,0x24,0xa2,0x6f,0x28,0x2f,0x68,0xaf,0x20,0x3f,0x40,0x40,0x80,0x0,0x0,0x84,0xfe,0x10,0x20,0xf8,0x88,0xf8,0x88,0xf8,0x80,0xfe,0x80,0x80,0x80,0x80,
-+0x0,0x0,0x1f,0x11,0x9f,0x51,0x57,0x15,0x35,0x57,0xd1,0x13,0x25,0x29,0x41,0x1,0x80,0x44,0xfe,0x0,0xe4,0x4,0xd4,0x54,0x54,0xd4,0x14,0x94,0x54,0x44,0x14,0x8,
-+0x1,0x0,0x3f,0x20,0xaf,0x64,0x22,0x3f,0x62,0xa4,0x28,0x37,0x40,0x40,0x9f,0x0,0x0,0x84,0xfe,0x80,0xf8,0x90,0xa4,0xfe,0x20,0x90,0x8e,0xf4,0x80,0x88,0xfc,0x0,
-+0x0,0x0,0x1f,0x12,0x92,0x54,0x55,0x1c,0x34,0x55,0xd4,0x17,0x24,0x24,0x44,0x7,0x80,0x44,0xfe,0x0,0xf8,0x8,0xfe,0x40,0xfc,0x20,0x24,0xfe,0x20,0x50,0x8e,0x4,
-+0x0,0x0,0x1f,0x11,0x9f,0x50,0x57,0x10,0x3f,0x51,0xd2,0x17,0x28,0x30,0x47,0x0,0x80,0x44,0xfe,0x20,0xfc,0x80,0xf8,0x80,0xfe,0x0,0x8,0xfc,0x40,0x44,0xfe,0x0,
-+0x0,0x0,0x1f,0x10,0x92,0x51,0x57,0x11,0x36,0x50,0xdf,0x11,0x23,0x20,0x41,0x6,0x80,0x44,0xfe,0x40,0x48,0x50,0xfc,0x50,0x4c,0x80,0xfe,0x10,0x20,0xc0,0x30,0x8,
-+0x0,0x0,0x1f,0x10,0x97,0x54,0x54,0x17,0x34,0x57,0xd4,0x14,0x27,0x24,0x44,0x5,0x80,0x44,0xfe,0x0,0xbc,0x84,0x84,0xbc,0x0,0xfc,0x24,0x28,0x90,0x28,0x46,0x84,
-+0x1,0x0,0x3f,0x20,0xaf,0x64,0x22,0x21,0x62,0xbc,0x27,0x24,0x47,0x40,0x9f,0x0,0x0,0x84,0xfe,0x0,0xf8,0x90,0x20,0xc0,0x20,0x9e,0xf4,0x90,0xf0,0x88,0xfc,0x4,
-+0x0,0x0,0x1f,0x12,0x9f,0x52,0x5f,0x12,0x3f,0x52,0xd1,0x12,0x2a,0x2a,0x51,0x0,0x80,0x44,0xfe,0x0,0xfc,0x24,0xa4,0x24,0xd4,0x88,0x0,0xc0,0x54,0x12,0xf2,0x0,
-+0x1,0x0,0x3f,0x22,0xbf,0x62,0x2f,0x28,0x6f,0xa8,0x2f,0x20,0x5f,0x41,0x86,0x18,0x0,0x84,0xfe,0x20,0xfc,0x20,0xf8,0x8,0xf8,0x8,0xf8,0x80,0xfe,0x40,0x20,0x1c,
-+0x1,0x0,0x3f,0x24,0xaf,0x69,0x2d,0x2b,0x7f,0xa9,0x2d,0x2b,0x49,0x49,0x93,0x20,0x0,0x84,0xfe,0x0,0x78,0x48,0x48,0x46,0x80,0x78,0x48,0x28,0x10,0x28,0x46,0x84,
-+0x1,0x0,0x3f,0x28,0xa4,0x69,0x22,0x24,0x6f,0xb4,0x27,0x24,0x47,0x44,0x84,0x4,0x0,0x84,0xfe,0x88,0x90,0x48,0x20,0x10,0xfe,0x14,0xf0,0x10,0xf0,0x10,0x50,0x20,
-+0x1,0x0,0x3f,0x22,0xaf,0x62,0x3f,0x20,0x6f,0xa8,0x2f,0x28,0x4f,0x42,0x84,0x8,0x0,0x84,0xfe,0x20,0xf8,0x20,0xfe,0x88,0xf8,0x88,0xf8,0x88,0xf8,0x20,0x18,0x8,
-+0x0,0x3f,0x20,0x3f,0xa1,0x6f,0x29,0x2f,0x60,0xaf,0x20,0x3f,0x44,0x48,0x92,0x1,0x80,0xfe,0x0,0xfc,0x40,0xf8,0x48,0xf8,0x0,0xf8,0x0,0xfe,0x90,0x8c,0x84,0x0,
-+0x0,0x3f,0x20,0x2f,0xa8,0x6f,0x28,0x2f,0x61,0xaf,0x21,0x2f,0x44,0x48,0x92,0x1,0x80,0xfe,0x8,0xfc,0x88,0xf8,0x88,0xf8,0x10,0xe0,0x8,0xfc,0x90,0x8c,0x84,0x0,
-+0x0,0x3f,0x20,0x2f,0xa9,0x6b,0x2b,0x26,0x69,0xa1,0x3f,0x22,0x46,0x41,0x82,0xc,0x80,0xfe,0x0,0x78,0x48,0x58,0x58,0x30,0x48,0x0,0xfe,0x20,0x40,0xc0,0x30,0x10,
-+0x0,0x3f,0x24,0x27,0xa9,0x75,0x2a,0x24,0x6b,0xb0,0x2f,0x20,0x44,0x44,0x8a,0x1,0x80,0xfe,0x40,0x78,0x48,0x50,0x20,0x18,0xe6,0x0,0xf8,0x80,0x90,0x8c,0x84,0x0,
-+0x0,0x3f,0x20,0x2f,0xa9,0x6a,0x2c,0x2a,0x69,0xa9,0x2d,0x2a,0x48,0x48,0x89,0x8,0x80,0xfe,0x20,0x3c,0x68,0x90,0x28,0xc6,0x38,0x50,0x7c,0x90,0x7c,0x10,0xfe,0x0,
-+0x0,0x3f,0x20,0x2e,0xaa,0x6a,0x2c,0x2a,0x69,0xa9,0x2d,0x2a,0x49,0x49,0x8a,0x8,0x80,0xfe,0x40,0x78,0x90,0xfc,0x4,0xfc,0x4,0xfc,0x20,0x10,0x44,0x4a,0x4a,0x38,
-+0x0,0x3f,0x20,0xaf,0x69,0x25,0x25,0x69,0xa6,0x28,0x37,0x20,0x47,0x40,0x80,0xf,0x80,0xfc,0x0,0x78,0x48,0x28,0xa8,0x48,0x70,0x8e,0x24,0x40,0x90,0x20,0xc0,0x0,
-+0x0,0x3f,0x21,0x20,0xbc,0x6b,0x28,0x29,0x69,0xbd,0x28,0x29,0x4a,0x4e,0xb8,0x0,0x80,0xfe,0x0,0x80,0x1e,0xe8,0x48,0x48,0x48,0x5c,0x88,0x48,0x28,0x8,0x3e,0x0,
-+0x0,0x3f,0x22,0x22,0xaf,0x62,0x2f,0x2a,0x6a,0xaf,0x22,0x27,0x4a,0x52,0x82,0x2,0x80,0xfe,0x20,0x3c,0xa4,0x48,0xbe,0xa2,0xaa,0xaa,0x2a,0x2a,0xaa,0x10,0x14,0x22,
-+0x0,0x3f,0x20,0x2f,0xa2,0x7f,0x20,0x2f,0x68,0xaf,0x28,0x2f,0x40,0x4a,0x92,0x21,0x80,0xfe,0x80,0xf8,0x20,0xfe,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x80,0x44,0x14,0xf0,
-+0x0,0x3f,0x20,0x2f,0xa8,0x6f,0x28,0x2a,0x6f,0xaa,0x2a,0x2f,0x50,0x52,0xa4,0x0,0x80,0xfe,0x0,0xdc,0x54,0xd4,0x14,0xa6,0xc0,0xbc,0x94,0xd4,0x8,0x94,0x62,0x0,
-+0x1,0x0,0x3f,0x20,0xaf,0x69,0x29,0x2f,0x68,0xaf,0x39,0x29,0x49,0x4f,0x89,0x0,0x0,0x84,0xfe,0x20,0x14,0xfe,0x4,0x8,0xfe,0x10,0x10,0x7c,0x10,0x10,0x10,0x10,
-+0x0,0x3f,0x22,0xbf,0x62,0x2f,0x28,0x6f,0xa8,0x2f,0x28,0x2f,0x48,0x5f,0x85,0x8,0x80,0xfe,0x0,0xfe,0x10,0xbe,0xa2,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xd0,0x14,0xa2,
-+0x0,0x3f,0x20,0x2f,0xad,0x6b,0x2f,0x22,0x67,0xac,0x37,0x24,0x47,0x44,0x87,0x4,0x80,0xfe,0x0,0x78,0x68,0x58,0x78,0x40,0xfc,0x40,0xf8,0x40,0xf8,0x40,0xfc,0x0,
-+0x20,0x10,0x13,0x0,0xfe,0x1,0x5,0x44,0x24,0x29,0x2a,0x8,0x16,0xf8,0x1,0x0,0x0,0x4,0xfe,0x44,0x64,0x54,0x54,0x44,0xcc,0x54,0x64,0x44,0x44,0x44,0x54,0x88,
-+0x20,0x10,0x13,0x0,0xfe,0x1,0x5,0x45,0x25,0x29,0x28,0x8,0x16,0xf9,0x2,0x0,0x20,0x24,0xfe,0x20,0x24,0xfe,0x24,0x24,0x24,0xfc,0x20,0x70,0xa8,0x26,0x24,0x20,
-+0x2,0x41,0x7f,0x40,0x88,0x12,0x22,0x7,0x8,0x14,0x22,0x1,0x1,0x6,0x18,0x60,0x0,0x0,0xfe,0x2,0x24,0x10,0x8,0xf0,0x10,0x20,0x40,0x80,0x0,0x0,0x0,0x0,
-+0x2,0x41,0x7f,0x48,0x90,0x2f,0x0,0x0,0x1f,0x10,0x10,0x1f,0x0,0x0,0x0,0x0,0x0,0x0,0xfe,0x22,0x14,0xf8,0x10,0x10,0xf0,0x0,0x8,0xfc,0x8,0x8,0x50,0x20,
-+0x2,0x41,0x7f,0x48,0x91,0x1,0xff,0x1,0x11,0x11,0x11,0x1f,0x1,0x1,0x1,0x0,0x0,0x0,0xfe,0x22,0x14,0x0,0xfe,0x0,0x10,0x10,0x10,0xf0,0x10,0x2,0x2,0xfe,
-+0x2,0x41,0x7f,0x48,0x90,0x0,0x1f,0x2,0x1,0x3f,0x0,0x1,0xe,0x30,0x48,0x7,0x0,0x0,0xfe,0x22,0x14,0x70,0x80,0x0,0x20,0xf0,0x40,0x80,0x0,0x0,0x6,0xfc,
-+0x2,0x41,0x7f,0x48,0x90,0x4,0x8,0x11,0x7e,0x4,0x8,0x14,0x22,0x7e,0x1,0x2,0x0,0x0,0xfe,0x22,0x14,0x40,0x48,0xfc,0x48,0x48,0x48,0x48,0x88,0x88,0x28,0x10,
-+0x2,0x41,0x7f,0x48,0x92,0x2,0x22,0x12,0x16,0xa,0x12,0x62,0x4,0x4,0x18,0x60,0x0,0x0,0xfe,0x22,0x94,0x80,0x90,0x98,0xa0,0xc0,0xa0,0x98,0x8a,0x82,0x7e,0x0,
-+0x41,0x7f,0x48,0x91,0x2f,0x1,0x3f,0x8,0x4,0x12,0x8,0xff,0x1,0x2,0xc,0x30,0x0,0xfe,0x22,0x14,0xe8,0x0,0xfc,0x84,0x88,0x80,0x84,0xfe,0x40,0x30,0x18,0x8,
-+0x41,0x7f,0x48,0x90,0x3f,0x11,0x1f,0x11,0x1f,0x1,0xff,0x3,0x5,0x19,0x61,0x1,0x0,0xfe,0x22,0x14,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x80,0x60,0x1e,0x8,0x0,
-+0x41,0x7f,0x48,0x91,0x22,0x4,0xf,0x30,0xde,0x12,0x1e,0x12,0x1e,0x12,0x12,0x16,0x0,0xfe,0x22,0x14,0x88,0x40,0xf0,0xe,0x14,0x90,0x90,0x90,0x90,0x90,0x10,0x30,
-+0x41,0x7f,0x48,0x92,0x1,0x3f,0x8,0x4,0xff,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x0,0xfe,0x22,0x14,0x0,0xf8,0x20,0x44,0xfe,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x10,
-+0x41,0x7f,0x49,0x91,0x29,0x5,0x7f,0x9,0x31,0x2,0xff,0x4,0xe,0x1,0x6,0x38,0x0,0xfe,0x22,0x14,0x28,0x40,0xfc,0x20,0x18,0x4,0xfe,0x20,0x40,0x80,0x70,0x8,
-+0x41,0x7f,0x48,0x90,0x26,0x38,0x2c,0x2c,0x2a,0x2a,0x29,0x29,0x34,0x5d,0x81,0x2,0x0,0xfe,0x22,0x14,0x18,0xe8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa4,0x54,0x72,0x0,
-+0x20,0x10,0x10,0x0,0xfc,0x8,0x10,0x34,0x58,0x94,0x10,0x10,0x10,0x10,0x10,0x10,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x20,0x10,0x13,0x0,0xfd,0x8,0x10,0x34,0x58,0x94,0x10,0x10,0x10,0x11,0x12,0x14,0x0,0x4,0xfe,0x4,0x44,0xa8,0xa8,0x88,0x50,0x50,0x20,0x50,0x90,0x8,0x6,0x4,
-+0x20,0x10,0x10,0x0,0xfd,0x9,0x11,0x35,0x59,0x95,0x11,0x11,0x11,0x11,0x11,0x11,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x54,0x4c,0x8c,0x4,0x4,0x4,0x14,0x8,
-+0x20,0x10,0x13,0x0,0xfc,0x8,0x10,0x35,0x58,0x94,0x10,0x10,0x10,0x10,0x13,0x10,0x8,0x1c,0xe0,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x20,0x10,0x10,0x0,0xfd,0xa,0x14,0x30,0x54,0x9b,0x14,0x10,0x10,0x10,0x10,0x10,0x40,0x40,0xa0,0xa0,0x10,0x8e,0x64,0x20,0x0,0xf8,0x8,0x10,0x10,0x20,0x40,0x80,
-+0x20,0x10,0x10,0x0,0xfd,0x8,0x10,0x34,0x5b,0x94,0x10,0x10,0x10,0x11,0x12,0x14,0x40,0x40,0x40,0x48,0xfc,0x48,0x48,0x48,0xfe,0x40,0x40,0xa0,0xa0,0x10,0xe,0x4,
-+0x20,0x10,0x11,0x0,0xfc,0x8,0x11,0x34,0x58,0x94,0x13,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x24,0xac,0xb0,0x20,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x20,0x10,0x11,0x0,0xfc,0x8,0x11,0x34,0x58,0x94,0x11,0x10,0x10,0x10,0x13,0x10,0x20,0x20,0x24,0xac,0xb0,0x24,0xfe,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0xfc,0x4,
-+0x20,0x10,0x10,0x0,0xfd,0xa,0x15,0x30,0x54,0x99,0x15,0x11,0x11,0x11,0x11,0x11,0x40,0x40,0xa0,0x90,0x8,0xe,0xf4,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x20,0x10,0x10,0x1,0xfd,0xa,0x10,0x34,0x5b,0x95,0x11,0x11,0x11,0x11,0x11,0x11,0x80,0x88,0xfc,0x88,0x50,0x20,0x50,0x88,0x6,0xf8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x20,0x11,0x11,0x1,0xfd,0x9,0x11,0x35,0x59,0x95,0x11,0x11,0x11,0x11,0x11,0x11,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x44,0x48,0x30,0x20,0x10,0x4e,0x84,0x0,
-+0x40,0x24,0x22,0x2,0xf8,0x10,0x26,0x2a,0x72,0xaa,0x22,0x22,0x22,0x25,0x28,0x20,0x20,0x20,0x28,0xfc,0x40,0x50,0x90,0xfc,0x10,0x14,0xfe,0x10,0x10,0x16,0xfc,0x0,
-+0x20,0x11,0x11,0x1,0xfd,0x9,0x10,0x35,0x58,0x94,0x11,0x10,0x10,0x10,0x17,0x10,0x4,0xfe,0x4,0x4,0x4,0xfc,0x0,0xfc,0x20,0x20,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x20,0x10,0x10,0x1,0xfd,0xa,0x15,0x34,0x5a,0x95,0x11,0x11,0x11,0x10,0x17,0x10,0x40,0x40,0xa0,0x10,0x10,0x28,0xf6,0x0,0x48,0x48,0x48,0x50,0x50,0x24,0xfe,0x0,
-+0x22,0x11,0x10,0x2,0xfe,0xa,0x12,0x36,0x5a,0x96,0x12,0x12,0x12,0x12,0x12,0x12,0x4,0xbe,0x84,0x4,0x4,0xf4,0x94,0x94,0xf4,0x94,0x94,0xf4,0x4,0x4,0x14,0x8,
-+0x20,0x10,0x10,0x3,0xfc,0x9,0x10,0x37,0x58,0x94,0x11,0x13,0x15,0x11,0x11,0x11,0x40,0x40,0x48,0xfc,0x40,0xf8,0x40,0xfe,0x44,0xa8,0x30,0x20,0x10,0x48,0x8e,0x4,
-+0x20,0x10,0x10,0x3,0xfc,0x8,0x13,0x34,0x59,0x95,0x13,0x15,0x19,0x11,0x11,0x11,0x80,0x80,0x88,0xf8,0x90,0xa4,0xfe,0x40,0xf8,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x20,0x11,0x11,0x1,0xfd,0x9,0x11,0x34,0x58,0x95,0x12,0x14,0x11,0x12,0x10,0x11,0x8,0xfc,0x8,0xf8,0x8,0x8,0xf8,0x84,0xfe,0x54,0x94,0xa4,0x24,0x44,0xa8,0x10,
-+0x20,0x10,0x11,0x1,0xfd,0x9,0x11,0x35,0x59,0x94,0x11,0x17,0x10,0x10,0x10,0x10,0x20,0x44,0xfe,0x24,0x24,0xfc,0x24,0x44,0xfc,0xa0,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x20,0x11,0x11,0x1,0xfd,0x9,0x11,0x35,0x59,0x95,0x11,0x12,0x12,0x14,0x18,0x10,0x4,0xfe,0x4,0x4,0xfc,0x20,0x24,0xfe,0x20,0x24,0xfe,0x84,0x84,0x84,0xfc,0x84,
-+0x40,0x2f,0x20,0x5,0xfa,0x15,0x20,0x68,0xb7,0x28,0x24,0x25,0x22,0x25,0x28,0x30,0x0,0xfc,0x84,0x28,0x10,0x28,0xc4,0x0,0xbc,0x84,0xc4,0x28,0x10,0x28,0xce,0x84,
-+0x21,0x11,0x17,0x1,0xfc,0x8,0x11,0x3a,0x55,0x98,0x13,0x12,0x12,0x12,0x13,0x12,0x10,0x14,0xfe,0x10,0x40,0xa0,0x10,0x8,0xf6,0x0,0xf8,0x8,0x8,0x8,0xf8,0x8,
-+0x20,0x10,0x13,0x0,0xfc,0xb,0x10,0x35,0x59,0x95,0x11,0x11,0x11,0x11,0x11,0x11,0x90,0x94,0x98,0x90,0x92,0x8e,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x8,0x28,0x10,
-+0x21,0x11,0x11,0x1,0xfa,0xa,0x16,0x3a,0x52,0x9a,0x12,0x12,0x12,0x12,0x12,0x12,0x4,0x7e,0x44,0x44,0x44,0x7c,0x10,0x10,0xfe,0x10,0x38,0x54,0x54,0x92,0x10,0x10,
-+0x20,0x12,0x11,0x0,0xff,0x9,0x12,0x34,0x58,0x97,0x19,0x12,0x11,0x10,0x11,0x16,0x40,0x48,0x50,0x44,0xfe,0x50,0x48,0x46,0x80,0xfe,0x10,0x10,0xa0,0x40,0xb0,0xc,
-+0x40,0x20,0x27,0x4,0xfc,0x17,0x24,0x6c,0xb7,0x2e,0x26,0x2b,0x2a,0x32,0x22,0x22,0x80,0x44,0xfe,0x4,0x4,0xfc,0x0,0x4,0xfe,0x94,0x94,0xfc,0x94,0x94,0x94,0x8,
-+0x20,0x12,0x12,0x2,0xfe,0xa,0x12,0x34,0x58,0x97,0x12,0x12,0x12,0x12,0x17,0x10,0x90,0x90,0x94,0xbe,0xa0,0xd0,0x88,0x80,0x4,0xfe,0x94,0x94,0x94,0x94,0xfe,0x0,
-+0x40,0x27,0x24,0x4,0xfd,0x15,0x25,0x6d,0xb5,0x2d,0x25,0x25,0x29,0x2a,0x34,0x21,0x3c,0xe0,0x3c,0x20,0xfe,0x22,0xf8,0x24,0x1c,0x0,0x78,0x48,0x48,0x4a,0x8a,0x6,
-+0x40,0x2f,0x20,0x4,0xfa,0x12,0x24,0x68,0xb3,0x2a,0x22,0x23,0x22,0x22,0x23,0x22,0x4,0xbe,0x84,0xa4,0x94,0x94,0xa4,0x48,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,
-+0x40,0x2f,0x21,0x1,0xf9,0x17,0x24,0x6c,0xb7,0x29,0x21,0x21,0x21,0x21,0x2a,0x24,0x4,0x7e,0x44,0x44,0x44,0x7c,0x10,0x7c,0x54,0x54,0x54,0x7c,0x10,0x14,0xfe,0x2,
-+0x43,0x20,0x2f,0x8,0xfb,0x10,0x23,0x68,0xb7,0x28,0x27,0x24,0x24,0x24,0x24,0x24,0xf8,0x40,0xfe,0x42,0x5c,0x40,0x58,0x44,0xfe,0x80,0xfc,0xa4,0xa4,0xa4,0xb4,0x8,
-+0x42,0x22,0x2f,0x2,0xf7,0x2a,0x22,0x77,0xa1,0x33,0x24,0x29,0x20,0x27,0x20,0x20,0xa8,0x48,0xbe,0xa8,0x5c,0xaa,0x8,0xfe,0x10,0xf8,0x44,0xf2,0x40,0xfc,0x40,0xc0,
-+0x0,0x0,0x7f,0x1,0x1,0x9,0x9,0x9,0x9,0x11,0x11,0x19,0x25,0x23,0x41,0x80,0x0,0x8,0xfc,0x8,0x10,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x0,0x0,0x86,0x7c,
-+0x7f,0x1,0x9,0x9,0x9,0x15,0x23,0xc0,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x10,0xfc,0x8,0x0,0xf0,0x0,0x6,0xfc,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0x50,0x20,
-+0x0,0x7f,0x52,0x91,0x7d,0x11,0x29,0x29,0x7d,0x9,0x9,0xfd,0xa,0xa,0xd,0xa,0x20,0x20,0x20,0xfe,0x22,0x24,0x20,0xfc,0x88,0x50,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x10,0x10,0x28,0x45,0xfd,0x45,0xa3,0x3d,0x25,0x45,0xa9,0x11,0x2a,0x44,0x89,0x2,0x20,0x20,0x20,0xfe,0x22,0x24,0x20,0xf8,0x88,0x50,0x20,0x50,0x50,0x88,0xe,0x4,
-+0x0,0x7e,0x2,0x24,0x18,0x9,0xfe,0xa,0x18,0x19,0x28,0x48,0x88,0x8,0x28,0x10,0x20,0x20,0x50,0x50,0x88,0x46,0x24,0x20,0x8,0xfc,0x8,0x8,0x10,0x10,0x20,0x40,
-+0x1,0x1,0x7f,0x1,0x1,0x3f,0x1,0x1,0xff,0x3,0x5,0x9,0x11,0x21,0x41,0x1,0x0,0x8,0xfc,0x0,0x0,0xf8,0x0,0x4,0xfe,0x80,0x40,0x20,0x10,0xe,0x4,0x0,
-+0x10,0x10,0x15,0xfe,0x10,0x7c,0x10,0xfe,0x33,0x38,0x54,0x50,0x90,0x10,0x10,0x10,0x0,0x8,0xfc,0x8,0x10,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x10,0x10,0x14,0xfe,0x10,0x10,0x7c,0x11,0xfd,0x30,0x38,0x54,0x50,0x90,0x11,0x16,0x20,0x20,0x20,0x20,0xa8,0xa4,0xa2,0x22,0x28,0x2c,0x10,0x20,0x40,0x80,0x0,0x0,
-+0x10,0x11,0x15,0xff,0x11,0x7d,0x11,0xff,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x14,0xfe,0x11,0x7e,0x11,0xfe,0x30,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x40,0x40,0xa0,0x90,0x8,0x2e,0xf4,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x13,0xfc,0x10,0x7f,0x12,0xfc,0x30,0x3b,0x54,0x54,0x91,0x11,0x12,0x14,0x88,0x88,0xfe,0x88,0x88,0xfe,0x2,0x84,0x80,0xf8,0x88,0x88,0x8,0x8,0x28,0x10,
-+0x10,0x12,0x11,0xfd,0x11,0x7c,0x13,0xfe,0x32,0x3a,0x56,0x56,0x92,0x12,0x12,0x12,0x40,0x48,0x4c,0x48,0x50,0x44,0xfe,0x4,0xf4,0x94,0x94,0x94,0xf4,0x4,0x14,0x8,
-+0x10,0x11,0x15,0xff,0x11,0x7d,0x11,0xfd,0x30,0x3b,0x56,0x56,0x92,0x12,0x12,0x12,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0xfe,0x22,0x2a,0xfa,0x2,0xa,0x4,
-+0x10,0x12,0x11,0xfc,0x13,0x7d,0x12,0xfc,0x38,0x37,0x51,0x52,0x91,0x10,0x11,0x16,0x40,0x48,0x50,0x44,0xfe,0x50,0x4c,0x44,0x80,0xfe,0x10,0x10,0xa0,0x40,0xb0,0xc,
-+0x11,0x11,0x17,0xf9,0x13,0x79,0x17,0xf8,0x33,0x3a,0x57,0x52,0x9f,0x12,0x12,0x12,0x10,0x10,0xfc,0x10,0xf8,0x10,0xfe,0x40,0xf8,0x48,0xf8,0x48,0xfe,0x8,0x28,0x10,
-+0x10,0x13,0x12,0xff,0x12,0x7f,0x12,0xfe,0x32,0x32,0x52,0x53,0x94,0x14,0x18,0x10,0x8,0xfc,0x0,0xf8,0x0,0xfe,0xa4,0x98,0xae,0xc4,0x8,0xfe,0x88,0x88,0x28,0x10,
-+0x10,0x10,0x13,0xfe,0x13,0x7e,0x12,0xff,0x32,0x3b,0x56,0x52,0x92,0x15,0x1a,0x10,0x40,0x24,0xfe,0x48,0xfe,0x58,0xec,0x4a,0x48,0xfe,0x40,0xfc,0x84,0x84,0xfc,0x84,
-+0x1,0x1f,0x1,0xff,0x4,0x1b,0x68,0x7,0x0,0x7f,0x10,0x3f,0x1,0x1f,0x1,0xff,0x20,0xc0,0x4,0xfe,0x0,0xe0,0x8,0xf8,0x0,0xfc,0x10,0xf8,0x4,0xf0,0x4,0xfe,
-+0x2,0xff,0x25,0x24,0x3c,0x24,0x24,0x3c,0x24,0x24,0x27,0x3c,0xe4,0x44,0x4,0x4,0x0,0x4,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x2,0xff,0x24,0x25,0x3d,0x25,0x25,0x3d,0x25,0x27,0x25,0x3f,0xe5,0x45,0x5,0x5,0x20,0x20,0x24,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfe,0x4,0x4,0x4,0x4,0x14,0x8,
-+0x2,0xff,0x24,0x24,0x3c,0x25,0x26,0x3c,0x25,0x24,0x26,0x3c,0xe4,0x44,0x4,0x4,0x20,0x20,0x50,0x50,0x88,0x46,0x24,0x20,0xfc,0x4,0x8,0x90,0x60,0x20,0x10,0x0,
-+0x2,0xff,0x24,0x25,0x3d,0x26,0x24,0x3f,0x24,0x24,0x27,0x3c,0xe4,0x44,0x4,0x4,0x40,0x20,0x20,0xfe,0x2,0x4,0x0,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,0xa0,0x40,
-+0x2,0xff,0x25,0x24,0x3c,0x27,0x24,0x3c,0x24,0x25,0x27,0x3d,0xe5,0x45,0x5,0x5,0x8,0x1c,0xe0,0x20,0x24,0xfe,0x20,0x20,0x24,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x2,0xff,0x25,0x25,0x3d,0x24,0x27,0x3c,0x25,0x25,0x27,0x3d,0xe5,0x44,0x4,0x5,0x20,0x24,0xfe,0x24,0xfc,0x20,0xfe,0x0,0xfc,0x4,0x24,0x24,0x24,0x50,0x8c,0x4,
-+0x8,0x7f,0x8,0x7f,0x8,0xff,0x10,0x2e,0x42,0xbf,0xc,0xb,0x8,0xff,0x0,0x0,0x40,0x44,0x7e,0x44,0xa8,0x10,0x28,0x46,0x84,0xf8,0x20,0xa0,0x64,0xfe,0x20,0x20,
-+0xff,0x4,0x3f,0x24,0x3f,0x0,0x1f,0x10,0x1f,0x10,0x1f,0x1,0xff,0x1,0x1,0x1,0xfe,0x40,0xf8,0x48,0xf8,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x0,0x0,0x0,
-+0x0,0xb,0x7c,0x10,0x11,0x11,0x15,0xff,0x11,0x11,0x11,0x11,0x11,0x10,0x10,0x13,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x58,0x86,0x2,
-+0x4,0xf,0x70,0x40,0x41,0x41,0x7f,0x49,0x49,0x49,0x49,0x49,0x49,0x88,0x8,0x3,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x58,0x86,0x2,
-+0x20,0x13,0x10,0xfe,0x1,0x9,0x7d,0x49,0x49,0x49,0x49,0x49,0x4d,0x48,0x80,0x3,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x44,0x58,0x86,0x2,
-+0x10,0x13,0x10,0xfe,0x11,0x11,0x7d,0x1,0x7d,0x45,0x45,0x45,0x44,0x7c,0x40,0x3,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x50,0x48,0x86,0x2,
-+0x10,0x13,0x10,0x28,0x45,0x81,0x7d,0x1,0x7d,0x45,0x45,0x45,0x44,0x7c,0x40,0x3,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x50,0x48,0x86,0x2,
-+0x40,0x45,0x48,0x70,0x45,0x7d,0x1,0x13,0xf5,0x39,0x39,0x55,0x54,0x90,0x30,0x3,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x50,0x48,0x86,0x2,
-+0x20,0x13,0x10,0xfe,0x11,0x11,0x25,0x7d,0x9,0x11,0x25,0xc9,0x18,0x24,0xc2,0x3,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x50,0x48,0x86,0x2,
-+0x10,0x13,0x28,0x26,0x53,0x81,0x7d,0x5,0x9,0x7d,0x45,0x45,0x44,0x7c,0x44,0x3,0x4,0xfe,0x20,0x44,0xfe,0x4,0x24,0x24,0x24,0x24,0x24,0x24,0x50,0x48,0x86,0x2,
-+0x1,0x77,0x55,0x55,0x77,0x0,0x3e,0x0,0xff,0x20,0x3e,0x2,0x2,0x2,0x14,0x9,0x4,0xfe,0x10,0x24,0x7e,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x64,0x28,0x46,0x82,
-+0x8,0x49,0x49,0x49,0x7f,0x0,0xff,0x8,0x7f,0x55,0x55,0x55,0x55,0x55,0x43,0x0,0x4,0xfe,0x10,0x24,0x7e,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x64,0x28,0x46,0x82,
-+0x2,0xff,0x22,0x3e,0x22,0x3e,0x22,0xff,0x2,0x77,0x11,0x55,0x22,0x22,0x55,0x88,0x4,0xfe,0x10,0x24,0x7e,0x44,0x54,0xd4,0x54,0x54,0x54,0x54,0x64,0x28,0x46,0x82,
-+0x24,0x24,0xff,0x24,0x2,0xff,0x24,0x24,0xff,0xa5,0xa5,0xdb,0x81,0x85,0x82,0x0,0x4,0xfe,0x10,0x24,0x7e,0x44,0x54,0x54,0x54,0x54,0x54,0x54,0x20,0x28,0x46,0x82,
-+0x0,0x3e,0x14,0x8,0x14,0x77,0x55,0x22,0x55,0x8,0xff,0x18,0x2c,0x4b,0x89,0x8,0x4,0xfe,0x10,0x24,0x7e,0x44,0x54,0x54,0x54,0x54,0xd4,0x54,0x20,0x28,0x46,0x82,
-+0x2,0x3f,0x22,0x3e,0x22,0x3e,0x8,0xff,0x0,0x3e,0x22,0x3e,0x8,0x2a,0x49,0x18,0x4,0xfe,0x10,0x24,0x7e,0x44,0x54,0xd4,0x54,0x54,0x54,0x54,0x20,0x28,0x46,0x82,
-+0x2,0x7f,0x8,0xff,0x88,0x6b,0x8,0x6b,0x8,0xff,0x10,0x7f,0x55,0x55,0x55,0x43,0x4,0xfe,0x10,0xa4,0xfe,0x44,0x54,0x54,0x54,0xd4,0x54,0x54,0x20,0x28,0x46,0x82,
-+0x9,0x2e,0x28,0xff,0x4a,0xc,0x32,0xdf,0x11,0x1f,0x12,0x1f,0x5,0xff,0x1,0x1,0xfe,0x20,0xfc,0x94,0x94,0x28,0xc4,0xf0,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x0,0x0,
-+0x1,0x1,0x1,0x1,0x3f,0x20,0x22,0x22,0x22,0x22,0x23,0x26,0x5a,0x42,0x81,0x0,0x0,0x10,0xf8,0x0,0xfc,0x4,0x8,0x20,0x60,0x80,0x0,0x0,0x4,0x4,0xfc,0x0,
-+0x1,0x1,0x1,0x3f,0x22,0x3f,0x22,0x23,0x21,0x20,0x2f,0x22,0x41,0x40,0x83,0x1c,0x10,0xf8,0x0,0xfc,0x4,0xc8,0x10,0xf0,0x0,0x88,0xfc,0x20,0x40,0x80,0x60,0x1c,
-+0x8,0x8,0x8,0x9,0x7f,0x49,0x49,0x49,0x49,0x7f,0x48,0x9,0xf,0xf1,0x40,0x0,0x40,0x40,0x40,0x40,0xc0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x10,0x10,0x10,0x14,0x7e,0x54,0x54,0x54,0x54,0x7c,0x50,0x14,0x1d,0xe5,0x42,0x4,0x0,0x10,0xf8,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x12,0x12,0xe,0x0,
-+0x0,0xff,0x4,0x4,0x7,0x8,0x31,0xc1,0x3f,0x21,0x21,0x3f,0x1,0x1,0x7f,0x0,0x4,0xfe,0x0,0x10,0xf8,0x10,0x50,0x28,0xfc,0x8,0x8,0xf8,0x0,0x8,0xfc,0x4,
-+0x0,0x2,0xff,0x24,0x25,0x25,0x25,0x25,0x25,0x24,0x24,0x24,0x25,0x44,0x43,0x80,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0xfc,0x20,0x24,0x3c,0xc6,0x2,0xfe,0x0,
-+0x10,0x10,0x10,0x15,0x7e,0x54,0x55,0x54,0x54,0x7c,0x50,0x14,0x1d,0xe5,0x40,0x0,0x80,0x80,0x88,0xfc,0x0,0x0,0xf8,0x8,0x10,0x20,0x40,0x80,0x2,0x2,0xfe,0x0,
-+0x10,0x10,0x10,0x14,0x7f,0x55,0x55,0x55,0x55,0x7d,0x51,0x15,0x1d,0xe5,0x40,0x0,0x40,0x20,0x20,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x8,0xfc,0x0,
-+0x10,0x10,0x10,0x14,0x7d,0x54,0x54,0x54,0x57,0x7c,0x50,0x14,0x1c,0xe4,0x41,0x6,0x20,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x50,0x50,0x88,0x88,0x6,0x4,
-+0x10,0x11,0x11,0x15,0x7f,0x55,0x55,0x55,0x55,0x7d,0x51,0x15,0x1d,0xe5,0x41,0x0,0x20,0x20,0x20,0x20,0x24,0xec,0x30,0x20,0x20,0x20,0x20,0x20,0x62,0xa2,0x1e,0x0,
-+0x10,0x10,0x10,0x14,0x7f,0x55,0x55,0x55,0x55,0x7d,0x51,0x15,0x1d,0xe5,0x41,0x1,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x54,0x4c,0x8c,0x4,0x4,0x14,0x8,
-+0x10,0x11,0x11,0x15,0x7f,0x55,0x55,0x55,0x55,0x7d,0x51,0x14,0x1c,0xe5,0x42,0xc,0x8,0xfc,0x8,0x28,0x28,0x28,0x28,0x48,0x48,0x48,0xa8,0xa0,0xa0,0x22,0x22,0x1e,
-+0x10,0x10,0x13,0x14,0x7e,0x54,0x57,0x54,0x54,0x7c,0x53,0x14,0x1c,0xe4,0x40,0x0,0x8,0x1c,0xe0,0x40,0x48,0x7c,0xc0,0x40,0x44,0x7e,0xc0,0x40,0x40,0x42,0x42,0x3e,
-+0x10,0x10,0x10,0x14,0x7e,0x55,0x56,0x54,0x54,0x7c,0x50,0x14,0x1c,0xe4,0x41,0x2,0x20,0x20,0x50,0x50,0x88,0xe,0x4,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x8,0x8,
-+0x10,0x10,0x10,0x14,0x7e,0x54,0x54,0x55,0x56,0x7c,0x50,0x14,0x1c,0xe5,0x41,0x0,0x0,0x10,0x58,0x50,0x50,0x88,0x88,0x26,0x24,0x20,0x40,0x40,0x90,0x8,0xfc,0x4,
-+0x10,0x10,0x11,0x14,0x7e,0x54,0x55,0x54,0x54,0x7c,0x53,0x14,0x1c,0xe4,0x40,0x0,0x10,0x10,0x10,0xd0,0x50,0x10,0x10,0x90,0x94,0x1e,0xf0,0x10,0x10,0x10,0x10,0x10,
-+0x10,0x13,0x10,0x14,0x7f,0x55,0x55,0x55,0x55,0x7c,0x50,0x14,0x1c,0xe4,0x1,0x0,0x24,0xf4,0x24,0x24,0xe4,0x4,0x4,0x24,0xf4,0x24,0x24,0x24,0x24,0x24,0x44,0x84,
-+0x1,0x21,0x21,0x3f,0x1,0xff,0x1,0x1,0x1f,0x11,0x11,0x1f,0x1,0x1,0x7f,0x0,0x0,0x8,0x8,0xf8,0x4,0xfe,0x0,0x10,0xf8,0x10,0x10,0xf0,0x0,0x8,0xfc,0x4,
-+0x10,0x10,0x10,0x14,0x7f,0x54,0x54,0x54,0x54,0x7c,0x50,0x14,0x1c,0xe4,0x40,0x0,0x88,0x88,0x88,0x88,0xfe,0x88,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x88,0xf8,0x88,
-+0x10,0x10,0x10,0x14,0x7f,0x54,0x54,0x54,0x54,0x7d,0x51,0x15,0x1d,0xe5,0x41,0x1,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x24,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x17,0x14,0x7e,0x55,0x55,0x55,0x55,0x7d,0x51,0x15,0x1c,0xe4,0x40,0x0,0x0,0x4,0xfe,0x8,0x8,0xe8,0x28,0x28,0x28,0x28,0xe8,0x28,0x8,0x8,0x28,0x10,
-+0x10,0x11,0x11,0x15,0x7f,0x55,0x55,0x55,0x55,0x7d,0x51,0x15,0x1d,0xe6,0x44,0x9,0x4,0xfe,0x0,0x4,0xfe,0x20,0x24,0x3e,0x24,0x24,0x24,0x24,0x44,0x44,0x94,0x8,
-+0x10,0x10,0x10,0x14,0x7f,0x55,0x55,0x55,0x55,0x7d,0x51,0x15,0x1d,0xe5,0x41,0x1,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0x24,0xfc,0x4,
-+0x10,0x10,0x10,0x15,0x7f,0x55,0x55,0x55,0x55,0x7d,0x51,0x17,0x1d,0xe5,0x41,0x1,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0xfe,0x4,0x4,0x14,0x8,
-+0x10,0x10,0x10,0x14,0x7f,0x55,0x56,0x54,0x54,0x7c,0x50,0x14,0x1c,0xe4,0x40,0x0,0x80,0xc0,0x84,0xfe,0x40,0x40,0x48,0x7c,0x40,0x40,0x44,0x7e,0x40,0x40,0x40,0x40,
-+0x10,0x10,0x10,0x14,0x7e,0x54,0x54,0x54,0x54,0x7c,0x50,0x14,0x1c,0xe4,0x47,0x0,0x8,0x1c,0xe0,0x80,0x80,0x80,0x88,0xfc,0x90,0x90,0x90,0x90,0x90,0x94,0xfe,0x0,
-+0x10,0x10,0x10,0x14,0x7e,0x55,0x56,0x54,0x54,0x7d,0x50,0x14,0x1c,0xe4,0x40,0x0,0x20,0x20,0x50,0x50,0x88,0x46,0x24,0x20,0x0,0xfc,0x8,0x10,0xa0,0x40,0x20,0x20,
-+0x10,0x11,0x11,0x14,0x7e,0x54,0x54,0x54,0x57,0x7c,0x51,0x14,0x1c,0xe4,0x43,0x0,0x0,0xfc,0x4,0x88,0x50,0x20,0x50,0x8e,0x24,0x20,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x10,0x10,0x14,0x7e,0x55,0x55,0x57,0x54,0x7c,0x51,0x17,0x1c,0xe4,0x40,0x1,0x10,0x90,0x90,0x94,0xbe,0x14,0x54,0xd4,0x94,0x94,0x54,0xf4,0x24,0x44,0x94,0x8,
-+0x4,0x7e,0x8,0x8,0x8,0xe,0xf1,0x1,0x1f,0x11,0x11,0x1f,0x11,0x1,0x7f,0x0,0x8,0xfc,0x88,0xc8,0xaa,0x8a,0x6,0x10,0xf8,0x10,0x10,0xf0,0x0,0x8,0xfc,0x4,
-+0x10,0x10,0x10,0x15,0x7e,0x55,0x54,0x54,0x54,0x7f,0x50,0x14,0x1c,0xe4,0x41,0x2,0x20,0x20,0x28,0xfc,0x20,0x24,0xac,0xb0,0x24,0xfe,0x50,0x50,0x90,0x88,0x6,0x4,
-+0x10,0x10,0x10,0x15,0x7e,0x54,0x54,0x57,0x54,0x7d,0x50,0x14,0x1c,0xe4,0x41,0x2,0x80,0x80,0x5c,0xe0,0x50,0x22,0xd2,0xe,0x0,0xfc,0x90,0x90,0x92,0x92,0xe,0x0,
-+0x10,0x10,0x11,0x14,0x7e,0x54,0x54,0x55,0x54,0x7c,0x51,0x14,0x1c,0xe4,0x43,0x0,0x0,0x8,0xfc,0x20,0x20,0x48,0x84,0xfe,0x22,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x20,0x20,0x22,0x2a,0xfe,0xaa,0xaa,0xaa,0xaa,0xfa,0xa2,0x2a,0x38,0xc9,0x1,0x2,0x80,0x84,0xbe,0x88,0x88,0xbe,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xae,0x8,0x8,0x8,
-+0x10,0x10,0x10,0x14,0x7f,0x55,0x55,0x55,0x55,0x7d,0x51,0x15,0x1d,0xe5,0x41,0x1,0x50,0x50,0x50,0x54,0xfe,0x54,0x54,0x54,0x54,0xfc,0x54,0x54,0x54,0x54,0xfc,0x4,
-+0x20,0x20,0x27,0x29,0xfd,0xaa,0xaa,0xaf,0xa9,0xf9,0xa5,0x2b,0x39,0xca,0x4,0x8,0x0,0xc,0x70,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x7c,0x0,0x86,0x7c,0x0,
-+0x10,0x10,0x11,0x14,0x7e,0x54,0x57,0x54,0x54,0x7d,0x51,0x15,0x1d,0xe5,0x41,0x1,0x8,0x1c,0xe0,0x20,0x20,0x24,0xfe,0x20,0x24,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x10,0x10,0x10,0x15,0x7e,0x54,0x54,0x54,0x57,0x7c,0x50,0x14,0x1c,0xe4,0x41,0x2,0x40,0x20,0x24,0xfe,0x88,0x50,0x20,0xd8,0x6,0x88,0x88,0x88,0x88,0x88,0x8,0x8,
-+0x10,0x10,0x10,0x15,0x7e,0x54,0x55,0x56,0x54,0x7c,0x50,0x14,0x1c,0xe4,0x1,0x6,0x40,0x20,0x4,0xfe,0x88,0x88,0x4,0x8a,0x88,0x50,0x50,0x20,0x50,0x88,0x6,0x4,
-+0x11,0x10,0x10,0x10,0x7d,0x54,0x54,0x55,0x54,0x7c,0x53,0x14,0x1c,0xe4,0x40,0x0,0x4,0x8c,0x50,0x4,0xfe,0x20,0x20,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x10,0x10,0x10,0x14,0x7f,0x54,0x54,0x54,0x55,0x7c,0x53,0x14,0x1c,0xe4,0x40,0x0,0x20,0x20,0x40,0x88,0xfc,0x20,0xa8,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x3f,0x20,0x2f,0x20,0x3f,0x24,0x24,0x26,0x24,0x2f,0x28,0x28,0x4f,0x40,0xbf,0x0,0xfc,0x0,0xf8,0x0,0xfe,0x88,0x50,0xb0,0x8e,0xf8,0x88,0x88,0xf8,0x84,0xfc,0x2,
-+0x8,0x8,0xfe,0x8,0xe,0xf8,0x9,0x2a,0x11,0x3f,0x21,0x21,0x3f,0x1,0x7f,0x0,0x4,0xf8,0x80,0x84,0xfe,0x90,0x10,0x10,0x10,0xf8,0x8,0x8,0xf8,0x4,0xfc,0x2,
-+0x10,0x11,0x10,0x14,0x7e,0x55,0x55,0x55,0x55,0x7d,0x51,0x15,0x1d,0xe5,0x41,0x1,0x20,0x24,0xa8,0xb0,0x24,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x4,0x14,0x8,
-+0x10,0x11,0x11,0x15,0x7f,0x55,0x54,0x57,0x54,0x7c,0x53,0x14,0x1c,0xe5,0x42,0x4,0x8,0xfc,0x8,0x8,0x8,0xf8,0x0,0xfc,0x40,0x44,0xfe,0xa0,0xa0,0x10,0xe,0x4,
-+0x10,0x10,0x13,0x10,0x7c,0x57,0x54,0x55,0x55,0x7e,0x52,0x14,0x1c,0xe4,0x40,0x0,0x44,0xe4,0x84,0x84,0x94,0xf4,0x94,0x94,0xd4,0xb4,0x94,0x94,0x84,0x84,0x94,0x88,
-+0x10,0x10,0x10,0x14,0x7e,0x55,0x56,0x54,0x54,0x7d,0x50,0x14,0x1d,0xe6,0x40,0x0,0x20,0x20,0x50,0x88,0x88,0x6,0xf8,0x20,0x28,0xfc,0x20,0xa8,0x26,0x22,0xa0,0x40,
-+0x10,0x10,0x13,0x11,0x7c,0x54,0x55,0x54,0x54,0x7c,0x53,0x14,0x1c,0xe4,0x40,0x0,0x8,0x1c,0xe0,0x24,0xa4,0xa8,0xfc,0x8,0x30,0x24,0xfe,0x20,0x20,0x20,0xa0,0x40,
-+0x11,0x10,0x13,0x14,0x7e,0x55,0x54,0x54,0x57,0x7c,0x50,0x14,0x1c,0xe4,0x41,0x6,0x4,0x88,0xfe,0x20,0x28,0xfc,0x20,0x24,0xfe,0x50,0x50,0x50,0x92,0x92,0xe,0x0,
-+0x10,0x10,0x13,0x10,0x7d,0x54,0x57,0x54,0x55,0x7d,0x51,0x15,0x1d,0xe5,0x41,0x1,0x20,0x24,0xfe,0x20,0xfc,0x20,0xfe,0x4,0xfe,0x4,0xfc,0x4,0xfc,0x4,0x14,0x8,
-+0x10,0x10,0x13,0x14,0x7e,0x54,0x54,0x54,0x54,0x7c,0x50,0x17,0x1c,0xe4,0x41,0x2,0x88,0x88,0xfe,0x88,0x88,0xf8,0x88,0x88,0xf8,0x88,0x88,0xfe,0x0,0x88,0x6,0x2,
-+0x10,0x10,0x10,0x14,0x7f,0x54,0x55,0x55,0x55,0x7e,0x52,0x14,0x1c,0xe4,0x40,0x0,0x80,0x86,0x98,0x90,0xf0,0x90,0x9e,0xd4,0xb4,0x94,0x94,0x94,0xa4,0xa4,0xc4,0x84,
-+0x20,0x20,0x20,0x27,0xf8,0xa8,0xab,0xaa,0xaa,0xfa,0xa3,0x28,0x39,0xce,0x4,0x0,0x20,0x28,0x24,0xfe,0x20,0x20,0xa4,0xa4,0xa4,0xa8,0xa8,0x10,0xb2,0x52,0x8a,0x4,
-+0x2,0x2,0x7e,0x2,0x3e,0x2,0x7e,0x2,0x1,0x3f,0x21,0x21,0x3f,0x1,0xff,0x0,0x80,0x88,0xfc,0x80,0xf8,0x80,0xfe,0x80,0x8,0xfc,0x8,0x8,0xf8,0x4,0xfc,0x2,
-+0x10,0x11,0x11,0x15,0x7f,0x55,0x55,0x55,0x54,0x7f,0x50,0x14,0x1c,0xe5,0x42,0x0,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0xfe,0x20,0x70,0xa8,0x2e,0x24,0x20,
-+0x10,0x11,0x11,0x15,0x7f,0x55,0x55,0x55,0x55,0x7d,0x51,0x15,0x1d,0xe5,0x41,0x1,0x4,0xfe,0x4,0x14,0xfc,0x24,0x24,0xfc,0x24,0x34,0x2c,0xfc,0x4,0x4,0xfc,0x4,
-+0x10,0x11,0x11,0x15,0x7f,0x55,0x55,0x54,0x54,0x7d,0x52,0x14,0x1d,0xe6,0x40,0x1,0x8,0xfc,0x8,0xf8,0x8,0x8,0xf8,0x84,0xfe,0x54,0x94,0xa4,0x24,0x44,0xa8,0x10,
-+0x10,0x10,0x11,0x15,0x7f,0x55,0x55,0x55,0x55,0x7c,0x50,0x17,0x1c,0xe4,0x40,0x0,0x20,0x44,0xfe,0x24,0x24,0xfc,0x24,0x44,0xfc,0x50,0x94,0xfe,0x10,0x10,0x10,0x10,
-+0x10,0x11,0x11,0x15,0x7f,0x55,0x55,0x55,0x55,0x7d,0x51,0x15,0x1d,0xe5,0x42,0x4,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x4,0x74,0x54,0x54,0x74,0x4,0x14,0x8,
-+0x10,0x11,0x10,0x10,0x7d,0x54,0x57,0x54,0x54,0x7d,0x52,0x14,0x1c,0xe4,0x40,0x0,0x20,0x24,0xa8,0x20,0xfc,0x20,0xfe,0x50,0x88,0xfe,0x88,0x88,0xa8,0x92,0x82,0x7e,
-+0x10,0x12,0x13,0x12,0x7d,0x55,0x55,0x55,0x56,0x7d,0x50,0x14,0x1c,0xe5,0x42,0x4,0x40,0x20,0xfe,0x2,0x4,0x0,0xdc,0x54,0x54,0x54,0xdc,0x90,0x92,0x12,0xe,0x0,
-+0x21,0x20,0x20,0x2b,0xfe,0xaa,0xab,0xaa,0xaa,0xfb,0xa2,0x2a,0x3a,0xcb,0x2,0x0,0x0,0x80,0x9e,0xd2,0x54,0x54,0xd8,0x54,0x54,0xd2,0x12,0x9a,0xd4,0x50,0x10,0x10,
-+0x10,0x11,0x10,0x14,0x7e,0x55,0x54,0x54,0x54,0x7d,0x51,0x15,0x1d,0xe5,0x43,0x0,0x0,0xfc,0x8,0x30,0x24,0xfe,0x20,0xa0,0x44,0xfe,0x54,0x54,0x54,0x54,0xfe,0x0,
-+0x20,0x20,0x27,0x20,0xfb,0xa8,0xaf,0xa9,0xab,0xfe,0xaa,0x23,0x3a,0xca,0x3,0x2,0x40,0x48,0xfc,0x40,0xf8,0x80,0xfe,0x10,0xf8,0xc,0xa,0xf8,0x8,0x8,0xf8,0x8,
-+0x10,0x10,0x13,0x10,0x7c,0x57,0x56,0x54,0x55,0x7c,0x50,0x14,0x1c,0xe5,0x42,0x0,0x88,0x88,0xfe,0x88,0x88,0xfe,0x2,0x24,0xfc,0x20,0x70,0x68,0xa8,0x26,0x24,0x20,
-+0x10,0x10,0x10,0x13,0x7c,0x54,0x55,0x55,0x55,0x7d,0x51,0x15,0x1d,0xe5,0x41,0x1,0x20,0x20,0x24,0xfe,0x20,0x24,0xfe,0x4,0x54,0xfc,0x24,0xfc,0x24,0x24,0x24,0xc,
-+0x10,0x13,0x10,0x14,0x7e,0x54,0x54,0x54,0x55,0x7d,0x51,0x15,0x1d,0xe5,0x41,0x1,0x4,0xfe,0x8,0xfc,0x88,0x88,0xf8,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x4,
-+0x10,0x10,0x10,0x13,0x7c,0x54,0x55,0x56,0x54,0x7d,0x50,0x14,0x1c,0xe4,0x43,0x0,0x20,0x20,0x24,0xfe,0x50,0x88,0x26,0xf8,0x20,0xfc,0x20,0xf8,0x20,0x24,0xfe,0x0,
-+0x10,0x10,0x13,0x10,0x7c,0x57,0x54,0x55,0x55,0x7e,0x52,0x14,0x1c,0xe4,0x40,0x0,0x4,0x64,0x84,0xa4,0x94,0xc4,0xa4,0x94,0xc4,0xbe,0x84,0x84,0x84,0x84,0x84,0x84,
-+0x10,0x10,0x10,0x15,0x7e,0x54,0x54,0x54,0x54,0x7c,0x50,0x14,0x1d,0xe6,0x40,0x3,0x80,0x84,0xfe,0x0,0xfc,0x84,0xfc,0x84,0xfc,0x80,0xfc,0x84,0x58,0x20,0xd8,0x6,
-+0x10,0x10,0x11,0x15,0x7f,0x55,0x55,0x55,0x54,0x7d,0x50,0x14,0x1c,0xe4,0x40,0x3,0x20,0xac,0x24,0x24,0xac,0x24,0x24,0xfc,0x20,0xfc,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x20,0x20,0x20,0x28,0xfd,0xaa,0xac,0xab,0xaa,0xfb,0xa2,0x2b,0x3a,0xca,0x2,0x2,0x20,0x20,0x50,0x90,0x8,0xf4,0x2,0xc4,0x54,0xd4,0x54,0xd4,0x54,0x54,0x44,0xcc,
-+0x22,0x21,0x21,0x27,0xfa,0xaa,0xab,0xaa,0xfa,0xa2,0x22,0x2a,0x3a,0xcc,0x5,0x8,0x20,0x20,0x24,0xbe,0x40,0x0,0xbc,0x88,0x90,0xfe,0x90,0x90,0x90,0x90,0xd0,0x20,
-+0x20,0x22,0x21,0x28,0xff,0xa8,0xa9,0xaa,0xa8,0xff,0xa1,0x2a,0x39,0xe8,0x1,0x6,0x40,0x48,0x50,0x40,0xfc,0xe0,0x58,0x48,0x80,0xfe,0x10,0x10,0xa0,0x40,0xb0,0x8,
-+0x10,0x10,0x10,0x13,0x7c,0x54,0x55,0x55,0x55,0x7d,0x51,0x15,0x1d,0xe5,0x41,0x1,0x0,0x88,0x50,0xfe,0x50,0x54,0xfe,0x54,0x54,0x54,0x9c,0x4,0x74,0x4,0xfc,0x4,
-+0x10,0x10,0x11,0x15,0x7f,0x55,0x55,0x55,0x55,0x7d,0x53,0x15,0x1d,0xe5,0x41,0x1,0x40,0x24,0xfe,0x4,0x4,0xfc,0x4,0x0,0xfe,0x4a,0x4a,0xfe,0x4a,0x4a,0x4a,0x6,
-+0x0,0x7e,0x14,0x8,0xff,0x1a,0x28,0x49,0x19,0x3f,0x21,0x21,0x3f,0x1,0xff,0x0,0x40,0x44,0x7e,0xc8,0x28,0x10,0x28,0x46,0x8,0xfc,0x8,0x8,0xf8,0x4,0xfc,0x2,
-+0x20,0x20,0x27,0x28,0xff,0xa8,0xaf,0xa8,0xa9,0xfb,0xa4,0x2b,0x38,0xc9,0x2,0x0,0x40,0x48,0xfc,0x40,0xf8,0x40,0xfe,0xa0,0x10,0xe8,0x46,0xf8,0x40,0x50,0x48,0x40,
-+0x8,0x7f,0x8,0x3e,0x8,0xff,0x10,0x1c,0x25,0x4d,0x3f,0x21,0x21,0x3f,0x1,0xff,0x20,0x20,0x24,0x7e,0xc8,0x28,0x10,0x28,0x46,0x8,0xfc,0x8,0x8,0xf8,0x4,0xfe,
-+0x20,0x20,0x27,0x28,0xfc,0xab,0xa8,0xaa,0xab,0xfa,0xa2,0x2b,0x3a,0xca,0x2,0x2,0x90,0x94,0xfe,0x90,0x90,0xfc,0x90,0x94,0xfe,0x94,0x94,0x6c,0x44,0x4,0x14,0x8,
-+0x21,0x21,0x27,0x21,0xf8,0xaf,0xa8,0xa9,0xaa,0xfd,0xa1,0x2f,0x39,0xc9,0x2,0x4,0x10,0x14,0xfe,0x18,0x44,0xfe,0xa0,0x10,0xe,0x14,0x10,0xfe,0x10,0x10,0x10,0x10,
-+0x10,0x10,0x13,0x14,0x7e,0x55,0x55,0x55,0x55,0x7d,0x50,0x17,0x1c,0xe4,0x40,0x3,0x88,0x88,0xfe,0x88,0x4,0xfe,0x4,0xfc,0x4,0xfc,0x20,0xfe,0x20,0x50,0x8e,0x4,
-+0x10,0x11,0x11,0x15,0x7f,0x55,0x55,0x55,0x55,0x7d,0x51,0x15,0x1d,0xe6,0x42,0x4,0x4,0xfe,0x10,0x24,0x7e,0x44,0x44,0x7c,0x44,0x44,0x7c,0x10,0x58,0x56,0x92,0x30,
-+0x10,0x10,0x11,0x15,0x7f,0x55,0x55,0x55,0x55,0x7d,0x51,0x14,0x1c,0xe6,0x42,0x4,0x40,0x88,0xfc,0x8,0xf8,0x8,0xf8,0x8,0x8,0xf8,0x48,0x20,0xa4,0x82,0x8a,0x78,
-+0x10,0x10,0x13,0x10,0x7d,0x55,0x55,0x55,0x54,0x7d,0x51,0x15,0x1d,0xe5,0x41,0x1,0x40,0x24,0xfe,0x0,0x54,0x24,0x54,0xfc,0x24,0xfe,0x24,0x54,0x74,0x4,0x14,0x8,
-+0x10,0x10,0x11,0x15,0x7f,0x55,0x55,0x55,0x55,0x7d,0x51,0x15,0x1d,0xe6,0x42,0x4,0x20,0x14,0xfe,0x10,0x7c,0x14,0xfe,0x14,0x7c,0x10,0x7c,0x44,0x44,0x44,0x7c,0x44,
-+0x10,0x10,0x13,0x10,0x7c,0x57,0x56,0x54,0x57,0x7c,0x50,0x14,0x1c,0xe5,0x42,0x4,0x40,0x20,0xfe,0x88,0x50,0xfe,0x42,0x20,0xfe,0x80,0xf8,0x88,0x88,0x8,0x28,0x10,
-+0x8,0x7f,0x8,0xff,0x14,0x56,0x55,0x94,0x25,0x3f,0x21,0x21,0x3f,0x1,0xff,0x0,0x40,0x40,0x44,0x7e,0xc8,0x28,0x10,0x28,0x46,0xf8,0x8,0x8,0xf8,0x4,0xfc,0x2,
-+0x10,0x10,0x13,0x10,0x7c,0x57,0x54,0x55,0x55,0x7d,0x51,0x15,0x1c,0xe4,0x41,0x2,0x88,0x88,0xfe,0x88,0x88,0xfe,0x20,0xfc,0x24,0xfc,0x24,0xfc,0x0,0x88,0x6,0x2,
-+0x20,0x20,0x27,0x20,0xfb,0xaa,0xab,0xaa,0xab,0xf8,0xa1,0x29,0x39,0xc9,0x1,0x1,0x90,0x94,0xfe,0x90,0xfc,0x94,0xfc,0x94,0xfc,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x8,
-+0x10,0x13,0x10,0x10,0x7d,0x55,0x55,0x55,0x54,0x7c,0x50,0x17,0x1c,0xe5,0x42,0x0,0x4,0xfe,0x50,0x54,0xfe,0x54,0x54,0xfc,0x0,0xf8,0x0,0xfe,0xa8,0x26,0x22,0x60,
-+0x10,0x11,0x10,0x10,0x7d,0x55,0x56,0x54,0x54,0x7c,0x50,0x15,0x1c,0xe4,0x43,0x0,0x20,0x24,0xa8,0x20,0xfe,0x2,0xf8,0x88,0x88,0xf8,0x20,0xfc,0x20,0x24,0xfe,0x0,
-+0x10,0x11,0x10,0x11,0x7c,0x57,0x54,0x54,0x55,0x7e,0x50,0x14,0x1d,0xe2,0x44,0x0,0xc,0xf0,0x24,0x24,0xa8,0xfe,0x68,0xa8,0x26,0x24,0x0,0xa0,0xa4,0x8a,0x8a,0x78,
-+0x10,0x10,0x11,0x13,0x7d,0x55,0x55,0x54,0x54,0x7d,0x52,0x14,0x1f,0xe4,0x43,0x0,0x80,0xf8,0x10,0xfc,0x24,0x24,0xfc,0x40,0xc4,0x28,0x70,0xb0,0x68,0xae,0x24,0x60,
-+0x8,0xf,0x18,0x26,0x1,0xe,0xf2,0x1,0xa,0x9,0x3e,0x2a,0x3e,0x9,0x7f,0x1,0x0,0xf0,0x20,0xc0,0x0,0xe0,0x1e,0x0,0x20,0x20,0xf8,0xa8,0xf8,0x24,0xfc,0x4,
-+0x10,0x11,0x10,0x14,0x7f,0x54,0x55,0x55,0x55,0x7d,0x51,0x14,0x1f,0xe4,0x40,0x0,0x20,0xfc,0x88,0x50,0xfe,0x4,0xfe,0x4,0xfc,0x4,0xfc,0x20,0xfe,0x20,0x20,0x20,
-+0x10,0x10,0x13,0x10,0x7c,0x56,0x55,0x56,0x54,0x7c,0x53,0x14,0x1c,0xe4,0x40,0x0,0x40,0x24,0xfe,0x20,0x48,0xf2,0x24,0x52,0xf8,0x20,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x0,0x1f,0x2,0x1,0x7f,0x2,0xc,0x30,0xca,0x9,0x3e,0x2a,0x3e,0x9,0x7f,0x1,0x0,0xf0,0x20,0x40,0xfe,0x82,0x84,0x80,0xa0,0x28,0xfc,0xa8,0xf8,0x24,0xfc,0x4,
-+0x20,0x20,0x27,0x20,0xfb,0xa8,0xab,0xaa,0xaa,0xfb,0xa0,0x2a,0x39,0xcf,0x0,0x0,0x82,0xa2,0xf4,0x84,0xe8,0x12,0xe2,0x24,0x28,0xf0,0x2,0x22,0x44,0xe8,0x10,0x60,
-+0x10,0x10,0x13,0x10,0x7d,0x55,0x55,0x55,0x55,0x7c,0x53,0x14,0x1c,0xe6,0x42,0x0,0x20,0x24,0xfe,0x24,0xfe,0x24,0xfc,0x24,0xfc,0x22,0xfe,0x42,0xa0,0xa4,0x8a,0x78,
-+0x10,0x11,0x10,0x11,0x7c,0x57,0x54,0x54,0x55,0x7f,0x51,0x15,0x1d,0xe5,0x41,0x1,0xc,0xf0,0x20,0x24,0xa8,0xfe,0x70,0xa8,0x26,0xfc,0x24,0x24,0xfc,0x24,0x24,0xfc,
-+0x10,0x10,0x13,0x10,0x7d,0x54,0x57,0x55,0x54,0x7f,0x50,0x15,0x1d,0xe5,0x41,0x1,0x88,0x50,0xfe,0x20,0xfc,0x20,0xfe,0x24,0xa8,0xfe,0x4,0xfe,0x4,0x4,0xfc,0x4,
-+0x10,0x13,0x10,0x10,0x7d,0x55,0x55,0x55,0x55,0x7d,0x51,0x15,0x1c,0xe4,0x41,0x6,0x88,0xfe,0x88,0xa0,0xfc,0x20,0xfc,0x20,0x3c,0x0,0xfc,0x8,0x90,0x60,0x98,0x6,
-+0x20,0x20,0x27,0x20,0xfb,0xaa,0xad,0xa8,0xaf,0xf8,0xa3,0x28,0x3b,0xe8,0x43,0x0,0x90,0x94,0xfe,0x90,0xfe,0x2,0xf4,0x0,0xfe,0x40,0xa4,0x78,0xb0,0x68,0xa6,0x60,
-+0x10,0x10,0x11,0x13,0x7d,0x55,0x55,0x55,0x55,0x7d,0x51,0x15,0x1d,0xe6,0x42,0x4,0x80,0xf8,0x10,0xfe,0x44,0x92,0xfe,0x0,0x7c,0x0,0x7c,0x0,0x7c,0x44,0x7c,0x44,
-+0x20,0x23,0x22,0x2a,0xff,0xaa,0xaa,0xaa,0xab,0xfa,0xa2,0x2a,0x3a,0xcd,0x6,0x8,0x20,0xfe,0x88,0x50,0xfe,0x50,0xfc,0x54,0xfe,0x54,0xfc,0x50,0xd8,0x54,0x52,0x50,
-+0x10,0x10,0x13,0x10,0x7d,0x55,0x55,0x55,0x54,0x7d,0x51,0x15,0x1d,0xe5,0x42,0x4,0x88,0x88,0xfe,0x88,0xfc,0x54,0x54,0xfc,0x28,0xfe,0x20,0x24,0x98,0x52,0x2a,0x46,
-+0xf,0x8,0x1f,0x0,0xff,0xc,0x73,0xd,0x72,0x1c,0x6b,0x3e,0x2a,0x3e,0x9,0x7f,0xe0,0x20,0xe0,0x44,0xfe,0x10,0x20,0xc0,0xa0,0x9e,0x24,0xf8,0xa8,0xf8,0x24,0xfc,
-+0x1,0x7f,0x9,0x7f,0x40,0x9f,0x4,0xf,0x38,0xcf,0x8,0x3e,0x2a,0x3e,0x8,0x7f,0x0,0xfc,0x20,0xfe,0x2,0xf4,0x0,0xf0,0x10,0xf0,0x20,0xf8,0xa8,0xf8,0x24,0xfc,
-+0x27,0x26,0x25,0x27,0xf9,0xab,0xae,0xab,0xaa,0xfa,0xa0,0x2b,0x39,0xc8,0x1,0x6,0xbc,0xb4,0xac,0xbc,0x40,0xfc,0x40,0xf8,0x40,0x7c,0x0,0xf8,0x10,0xe0,0x10,0xe,
-+0x8,0x8,0x8,0x1f,0x21,0x41,0x1,0x1,0xff,0x1,0x21,0x21,0x21,0x21,0x3f,0x0,0x0,0x0,0x10,0xf8,0x0,0x0,0x0,0x4,0xfe,0x0,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x3e,0x22,0x2a,0x2a,0x2a,0x14,0x22,0x8,0xf,0x11,0x1,0xff,0x1,0x11,0x11,0x1f,0xf8,0x88,0xa8,0xa8,0xa8,0x50,0x88,0x20,0xf0,0x0,0x4,0xfe,0x0,0x10,0x10,0xf0,
-+0x8,0x7f,0x8,0x3e,0x0,0x7f,0x49,0x7f,0x44,0x4f,0x91,0x1,0xff,0x1,0x11,0x1f,0x78,0x48,0x4e,0x80,0x78,0x48,0x30,0x48,0x86,0xf0,0x0,0x4,0xfe,0x0,0x10,0xf0,
-+0x20,0x24,0x3e,0x51,0x91,0x15,0xff,0x11,0x11,0x55,0x55,0x55,0x55,0x7d,0x2,0x4,0x20,0x3c,0x20,0xfe,0x24,0xf8,0x24,0x38,0x0,0xfe,0x54,0x54,0xfe,0x10,0x10,0x30,
-+0x0,0x6,0x79,0x11,0x15,0xff,0x11,0x11,0x15,0x7f,0x45,0x45,0x45,0x7d,0x45,0x1,0x8,0x1c,0xe0,0x20,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x10,0x10,0x4a,0x8a,0x4,
-+0x10,0x12,0x1f,0x20,0x28,0x45,0x80,0x0,0x3f,0x0,0x0,0x0,0x0,0xff,0x0,0x0,0x40,0x44,0x7e,0x80,0x90,0x8,0x0,0x10,0xf8,0x0,0x0,0x0,0x4,0xfe,0x0,0x0,
-+0x10,0x12,0x1f,0x28,0x45,0x80,0x3f,0x1,0x1,0xff,0x1,0x1,0x1,0x1,0x5,0x2,0x40,0x44,0x7e,0xa0,0x10,0x0,0xf8,0x0,0x4,0xfe,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x12,0x1f,0x28,0xc5,0x0,0x3f,0x8,0x8,0x9,0x14,0x12,0x11,0x21,0x46,0x98,0x40,0x44,0x7e,0xa0,0x10,0x20,0xf0,0x40,0x90,0xf8,0x20,0x40,0x80,0x60,0x1e,0x4,
-+0x10,0x12,0x1f,0x28,0x45,0x0,0x3f,0x8,0x8,0x8,0xf,0x0,0x7f,0x0,0x0,0x0,0x40,0x44,0x7e,0xa0,0x10,0x20,0xf0,0x20,0x20,0x24,0xfe,0x4,0xf4,0x4,0x14,0x8,
-+0x10,0x12,0x1f,0x28,0x45,0x0,0x3f,0x4,0x4,0xff,0x4,0x4,0x8,0x8,0x10,0x20,0x40,0x44,0x7e,0xa0,0x10,0x0,0xf8,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x10,0x12,0x1f,0x28,0xc5,0x0,0x1f,0x10,0x11,0x11,0x11,0x12,0x12,0x4,0x18,0xe0,0x40,0x44,0x7e,0xa0,0x10,0x10,0xf8,0x10,0x10,0x10,0x90,0x90,0x90,0x82,0x82,0x7e,
-+0x10,0x12,0x1f,0x28,0x45,0x0,0x1f,0x11,0x11,0x11,0x11,0x11,0x11,0x21,0x41,0x1,0x40,0x44,0x7e,0xa0,0x10,0x38,0xe0,0x20,0x20,0x20,0x10,0x10,0x8,0xe,0x4,0x0,
-+0x10,0x12,0x1f,0x28,0xc5,0x1,0x3f,0x21,0x21,0x3f,0x3,0x5,0x9,0x31,0xc1,0x1,0x40,0x44,0x7e,0xa0,0x10,0x8,0xf0,0x0,0x4,0xfe,0x4,0x4,0x44,0x28,0x10,0x0,
-+0x10,0x12,0x1f,0x28,0x45,0x8,0xf,0x12,0x12,0x22,0x44,0x4,0x8,0x11,0x22,0x0,0x40,0x44,0x7e,0xa0,0x10,0x8,0xfc,0x48,0x48,0x48,0x48,0x88,0x88,0x8,0x50,0x20,
-+0x10,0x12,0x1f,0x28,0x45,0x0,0x7e,0x8,0x8,0x8,0x8,0xe,0x78,0x20,0x0,0x0,0x40,0x44,0x7e,0xa0,0x10,0x0,0xfc,0x88,0x90,0x90,0x88,0xc4,0xa4,0x98,0x80,0x80,
-+0x10,0x12,0x1f,0x28,0xc5,0x3f,0x20,0x20,0x27,0x24,0x24,0x27,0x24,0x20,0x3f,0x0,0x40,0x44,0x7e,0xa0,0x10,0xfc,0x0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x4,0xfe,0x0,
-+0x10,0x12,0x1f,0x28,0xc5,0x1f,0x10,0x10,0x1f,0x10,0x10,0x1f,0x10,0x0,0xff,0x0,0x40,0x44,0x7e,0xa0,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,0x4,0xfe,0x0,
-+0x10,0x12,0x1f,0x28,0x45,0x11,0x11,0x1f,0x21,0x41,0x1f,0x1,0x1,0x1,0xff,0x0,0x40,0x44,0x7e,0xa0,0x10,0x0,0x10,0xf8,0x0,0x20,0xf0,0x0,0x0,0x4,0xfe,0x0,
-+0x10,0x12,0x1f,0x28,0xc5,0x4,0xf,0xa,0x12,0x23,0x42,0x2,0x3,0x2,0x2,0x2,0x40,0x44,0x7e,0xa0,0x10,0x8,0xfc,0x0,0x10,0xf8,0x0,0x8,0xfc,0x0,0x0,0x0,
-+0x10,0x12,0x1f,0x28,0xc5,0x8,0xf,0x10,0x10,0x2f,0x48,0x8,0xf,0x8,0x0,0x0,0x40,0x44,0x7e,0xa0,0x10,0x8,0xfc,0x8,0x48,0xe8,0x48,0x48,0xc8,0x8,0x28,0x10,
-+0x10,0x12,0x1f,0x28,0xc5,0x2,0x1,0x7f,0x0,0x8,0x4,0x4,0x2,0x2,0x7f,0x0,0x40,0x44,0x7e,0xa0,0x10,0x0,0x8,0xfc,0x0,0x20,0x20,0x40,0x40,0x84,0xfe,0x0,
-+0x10,0x12,0x1f,0x28,0xc5,0x3f,0x0,0x7f,0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x0,0x40,0x44,0x7e,0xa0,0x14,0xfe,0x4,0xe4,0x4,0x84,0x84,0x84,0x84,0x84,0x94,0x8,
-+0x10,0x12,0x1f,0x28,0xc5,0x3f,0x2,0x2,0x4,0x8,0x3f,0xd0,0x10,0x10,0x1f,0x10,0x40,0x44,0x7e,0xa0,0x10,0xf8,0x8,0x10,0x50,0x20,0xf0,0x10,0x10,0x10,0xf0,0x10,
-+0x10,0x12,0x1f,0x28,0xc5,0x8,0x8,0x7f,0x9,0x9,0x9,0x9,0x11,0x11,0x25,0xc2,0x40,0x44,0x7e,0xa0,0x10,0x0,0x4,0x7e,0x44,0x44,0x44,0x44,0x44,0x7c,0x44,0x0,
-+0x10,0x12,0x1f,0x28,0xc5,0x20,0x10,0x7,0x70,0x10,0x11,0x11,0x12,0x2c,0x44,0x3,0x40,0x44,0x7e,0xa0,0x10,0x80,0x88,0xfc,0x88,0x88,0x8,0x8,0x28,0x10,0x6,0xfc,
-+0x10,0x12,0x1f,0x28,0x45,0x84,0x8,0x10,0x3f,0x0,0x1f,0x10,0x10,0x10,0x1f,0x10,0x40,0x44,0x7e,0xa0,0x10,0x0,0x20,0x10,0xf8,0x8,0xf0,0x10,0x10,0x10,0xf0,0x10,
-+0x10,0x12,0x1f,0x28,0xc5,0x8,0x8,0xfe,0x8,0x8,0xe,0x78,0x8,0x8,0x28,0x10,0x40,0x44,0x7e,0xa0,0x10,0x0,0x4,0xfe,0x84,0x84,0x84,0x84,0x84,0xfc,0x84,0x0,
-+0x10,0x12,0x1f,0x28,0xc5,0x10,0x1e,0x10,0x10,0x1e,0x1,0xff,0x1,0x1,0x1,0x1,0x40,0x44,0x7e,0xa0,0x10,0x80,0x98,0xe0,0x84,0xfc,0x0,0xfe,0x0,0x0,0x0,0x0,
-+0x10,0x12,0x1f,0x28,0xc5,0x11,0x1f,0x21,0x1,0xff,0x4,0x4,0x4,0x8,0x10,0x60,0x40,0x44,0x7e,0xa0,0x10,0x0,0xf8,0x0,0x4,0xfe,0x80,0x80,0x80,0x84,0x84,0x7c,
-+0x10,0x12,0x1f,0x28,0xc5,0x0,0x7d,0x10,0x21,0x7d,0x5,0x49,0x29,0x10,0x28,0xc7,0x40,0x44,0x7e,0xa0,0x10,0xc,0xf0,0x20,0x28,0x3c,0x20,0x28,0xfc,0x0,0x6,0xfc,
-+0x10,0x12,0x1f,0x28,0xc5,0x2,0x4,0x8,0x3f,0xc1,0x1,0x1f,0x1,0x1,0x7f,0x0,0x40,0x44,0x7e,0xa0,0x10,0x80,0x40,0x20,0xfe,0x4,0x20,0xf0,0x0,0x8,0xfc,0x0,
-+0x10,0x12,0x1f,0x28,0xc5,0x7,0x8,0x3f,0x1,0xff,0x1,0x3f,0x1,0x1,0x5,0x2,0x40,0x44,0x7e,0xa0,0x10,0xe0,0x48,0xfc,0x8,0xfe,0x8,0xf8,0x8,0x0,0x0,0x0,
-+0x10,0x12,0x1f,0x28,0xc5,0x10,0x10,0x7c,0x11,0x12,0x10,0x1c,0xe1,0x40,0x0,0x0,0x40,0x44,0x7e,0xa0,0x10,0x84,0xfe,0x84,0x44,0x24,0x4,0x34,0xc4,0x84,0x14,0x8,
-+0x10,0x12,0x1f,0x28,0xc5,0x0,0x7f,0x1,0x11,0x11,0x11,0x29,0x45,0x1,0xff,0x0,0x40,0x44,0x7e,0xa0,0x10,0x0,0xfc,0x0,0x10,0x10,0x10,0x28,0x44,0x0,0xfe,0x0,
-+0x10,0x1f,0x28,0x45,0xff,0x1,0x3f,0x21,0x3f,0x21,0x3f,0x29,0x5,0x3,0xc,0x70,0x40,0x7e,0xa0,0x14,0xfe,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x8,0x0,0x0,0xe0,0x1e,
-+0x10,0x12,0x1f,0x28,0x45,0x8,0x9,0x7f,0x9,0xd,0x19,0x69,0x9,0x9,0x29,0x10,0x40,0x44,0x7e,0xa0,0x10,0x4,0xfe,0x24,0x24,0x24,0xfc,0x4,0x0,0x2,0x2,0xfe,
-+0x10,0x12,0x1f,0x28,0xc5,0x9,0x5,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x10,0x10,0x10,0x40,0x44,0x7e,0xa0,0x10,0x20,0x50,0xf8,0x10,0xf0,0x10,0xf0,0x10,0x10,0x50,0x20,
-+0x10,0x12,0x1f,0x28,0xc5,0x8,0x8,0x14,0x35,0x56,0x94,0x14,0x14,0x14,0x11,0x12,0x40,0x44,0x7e,0xa0,0x10,0x84,0xfe,0x88,0x88,0x90,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x10,0x12,0x1f,0x68,0x85,0x7f,0x1,0x3f,0x1,0xff,0x10,0x1f,0x10,0x1f,0x10,0x10,0x40,0x44,0x7e,0xa0,0x10,0xfc,0x0,0xf8,0x0,0xfe,0x10,0xf0,0x10,0xf0,0x10,0x30,
-+0x12,0x1f,0x28,0x45,0x7f,0x1,0x1f,0x1,0xff,0x0,0x1f,0x10,0x11,0x12,0x4,0x38,0x48,0x7c,0xa0,0x10,0xfc,0x0,0xf8,0x0,0xfe,0x10,0xf8,0x10,0x10,0xd0,0x30,0x8,
-+0x12,0x1f,0x28,0xc5,0x3f,0x20,0x20,0x2f,0x24,0x22,0x3f,0x21,0x22,0x24,0x3f,0x0,0x44,0x7e,0xa0,0x10,0xfc,0x80,0x90,0xf8,0x90,0xa0,0xfc,0x40,0x30,0x14,0xfe,0x0,
-+0x10,0x12,0x1f,0x28,0xc2,0x3f,0x2,0x2,0xff,0x4,0xf,0x18,0x6f,0x8,0xf,0x8,0x40,0x44,0x7e,0xa0,0x10,0xe0,0x40,0x84,0xfe,0x0,0xf0,0x10,0xf0,0x10,0xf0,0x10,
-+0x12,0x1f,0x28,0xc5,0x8,0x7f,0xa,0x2,0xff,0x4,0xf,0x38,0xc8,0x8,0xf,0x8,0x48,0x7c,0xa0,0x10,0x20,0xfc,0x20,0x4,0xfe,0x10,0xf8,0x10,0x10,0x10,0xf0,0x10,
-+0x10,0x12,0x1f,0x28,0x45,0x8,0x8,0xff,0x8,0x8,0xe,0xf8,0x48,0x8,0x28,0x10,0x40,0x48,0x7c,0xa0,0x10,0x88,0x88,0xfe,0x88,0x88,0xf8,0x88,0x88,0x88,0xf8,0x88,
-+0x10,0x12,0x1f,0x28,0x45,0x13,0x11,0xfc,0x11,0x12,0x1d,0xf0,0x13,0x10,0x50,0x20,0x40,0x44,0x7e,0xa0,0x10,0xf8,0x10,0xe0,0x10,0x4e,0xf4,0x40,0xf8,0x40,0x40,0x40,
-+0x10,0x12,0x1f,0x28,0x45,0x1f,0x11,0x1f,0x11,0x1f,0x0,0xff,0x8,0x8,0x10,0x20,0x40,0x44,0x7e,0xa0,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x20,0x20,0x20,0x20,
-+0x12,0x1f,0x28,0x45,0x8,0x4,0x1f,0x11,0x1f,0x11,0x1f,0x1,0xff,0x1,0x1,0x1,0x48,0x7c,0x90,0x8,0x20,0x40,0xf0,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x0,0x0,0x0,
-+0x12,0x1f,0x28,0x45,0x1,0x7f,0x40,0x88,0x10,0x20,0x1f,0x1,0x1,0x1,0xff,0x0,0x48,0x7c,0xa0,0x10,0x0,0xfe,0x2,0x24,0x18,0x8,0xf0,0x0,0x0,0x4,0xfe,0x0,
-+0x12,0x1f,0x28,0x45,0x1,0x7f,0x48,0x8e,0x12,0x12,0x32,0x4c,0x8,0x10,0x20,0x40,0x48,0x7c,0xa0,0x10,0x0,0xfe,0x2,0xf4,0x90,0x90,0x90,0xd0,0xa0,0x82,0x82,0x7e,
-+0x12,0x1f,0x28,0x45,0x3f,0x1,0xff,0x1,0x3f,0x1,0x25,0x25,0x29,0x29,0x31,0x41,0x48,0x7c,0xa0,0x10,0xf8,0x8,0xfe,0x8,0xf8,0x0,0x48,0x28,0x28,0x18,0x18,0x8,
-+0x12,0x1f,0x28,0x45,0x0,0x3f,0x20,0x3f,0x20,0x2f,0x29,0x29,0x4f,0x49,0x80,0x0,0x48,0x7c,0xa0,0x10,0x50,0xfc,0x40,0xc0,0x28,0x28,0x28,0x30,0x20,0x52,0x8a,0x4,
-+0x12,0x1f,0x28,0x41,0x3f,0x21,0x3f,0x1,0xff,0x0,0x1f,0x10,0x11,0x11,0x6,0x38,0x48,0x7c,0xa0,0x8,0xfc,0x8,0xf8,0x0,0xfe,0x10,0xf8,0x10,0x10,0x10,0x60,0x18,
-+0x12,0x1f,0x28,0x41,0x1f,0x10,0x1f,0x10,0x1f,0x0,0x7f,0x1,0x3f,0x1,0xff,0x0,0x48,0x7c,0xa0,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x0,0xfc,0x0,0xf8,0x0,0xfe,0x0,
-+0x12,0x1f,0x28,0x45,0x5,0x8,0x17,0x31,0x51,0x96,0x10,0x17,0x10,0x10,0x11,0x16,0x48,0x7c,0xa0,0x0,0xf0,0x10,0xfc,0x0,0xfc,0x40,0x44,0xfe,0x40,0xa0,0x18,0x6,
-+0x12,0x1f,0x28,0x41,0x7f,0x4,0x3f,0x4,0xff,0x11,0x1f,0x11,0xff,0x10,0x10,0x10,0x48,0x7c,0xa0,0x50,0xfc,0x40,0xf8,0x40,0xfe,0x10,0xf0,0x14,0xfe,0x10,0x10,0x30,
-+0x10,0x1f,0x28,0x45,0x3f,0x22,0x22,0x3e,0x22,0x3e,0x22,0x3e,0x22,0x22,0x3f,0x0,0x40,0x7c,0xa0,0x10,0xfc,0x40,0x50,0x78,0x40,0x78,0x40,0x78,0x40,0x48,0xfc,0x0,
-+0x10,0x1f,0x28,0x45,0x7f,0x4,0x3f,0x24,0x24,0x3f,0x1,0xff,0x3,0xd,0x71,0x1,0x40,0x7c,0xa0,0x10,0xfc,0x40,0xf8,0x48,0x48,0xf8,0x0,0xfe,0x80,0x60,0x1c,0x0,
-+0x10,0x1f,0x28,0x45,0x1,0x3f,0x24,0x23,0x24,0x3f,0x20,0x3c,0x20,0x22,0x2c,0x30,0x40,0x7c,0xa0,0x10,0x8,0xfc,0x48,0x88,0x48,0xf8,0x80,0x8c,0xb0,0xc2,0x82,0x7e,
-+0x10,0x1f,0x28,0x45,0x1e,0x10,0x10,0x17,0x14,0x15,0x24,0x24,0x29,0x49,0x91,0x26,0x44,0x7e,0xa0,0xfc,0x80,0xf0,0x80,0xfe,0x44,0xf0,0x48,0x38,0xe0,0x22,0x22,0x1e,
-+0x10,0x1f,0x28,0x45,0x8,0xff,0x8,0x7f,0x49,0x7f,0x49,0x1c,0x2a,0x4a,0x88,0x9,0x40,0x7c,0xa0,0x50,0x40,0x7e,0x82,0x24,0x20,0x20,0x20,0x50,0x50,0x88,0x8e,0x4,
-+0x10,0x1f,0x28,0x45,0x3f,0x24,0x24,0x3f,0x1,0x3f,0x21,0x28,0x24,0x40,0x43,0x8c,0x40,0x7c,0xa0,0x10,0xf8,0x48,0x48,0xf8,0x40,0xfc,0x10,0xa0,0x40,0xa2,0x1a,0x6,
-+0x10,0x1f,0x28,0x45,0xa,0x37,0x24,0x27,0x24,0x2f,0x30,0x4,0x4,0x4,0x8,0x70,0x40,0x7c,0xa0,0x10,0x8,0xfc,0x48,0xc8,0x48,0xc8,0x38,0x40,0x40,0x42,0x42,0x3e,
-+0x10,0x1f,0x28,0x45,0x1,0x3f,0x22,0x3f,0x22,0x22,0x3f,0x28,0x2f,0x48,0x49,0x8e,0x40,0x7c,0xa0,0x10,0x0,0xfc,0x40,0xf8,0x48,0x48,0xf8,0x44,0x48,0x72,0x42,0x3e,
-+0x10,0x1f,0x28,0x45,0x8,0x6a,0x5c,0x48,0x7e,0x48,0x58,0x6a,0x48,0x7e,0x1,0x0,0x40,0x7c,0xa0,0x10,0xc,0xf0,0x80,0x84,0xfe,0x90,0x90,0x90,0x90,0x90,0x10,0x10,
-+0x10,0x1f,0x28,0x5f,0x10,0x1f,0x10,0x1f,0x11,0x14,0x18,0x3f,0x24,0x24,0xff,0x0,0x40,0x7c,0xa0,0xf0,0x10,0xf0,0x10,0xf8,0x10,0xe0,0x1c,0xf8,0x48,0x48,0xfe,0x0,
-+0x10,0x1f,0x28,0x7f,0x4,0x3f,0x24,0x3f,0x10,0x1f,0x10,0x1f,0x1,0xff,0x1,0x1,0x40,0x7c,0xa0,0xfc,0x40,0xf8,0x48,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x0,0x0,
-+0x10,0x1f,0x28,0x41,0x3e,0x28,0x7f,0x18,0x28,0xcd,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x40,0x7c,0xa0,0x10,0xf8,0xa0,0xfc,0x62,0xa2,0x1e,0xf0,0x10,0xf0,0x10,0xf0,0x10,
-+0x10,0x1f,0x28,0x45,0x3e,0x2,0x14,0xf,0x10,0x2f,0xc8,0xf,0x4,0x2,0x7f,0x0,0x40,0x7c,0xa0,0x10,0xa0,0xc8,0x50,0xe0,0x10,0xee,0x24,0xe0,0x40,0x88,0xfc,0x0,
-+0x10,0x1f,0x28,0x45,0x24,0x7e,0x24,0x3c,0x24,0x3c,0x24,0xfe,0x0,0x29,0x46,0x80,0x40,0x7c,0xa0,0x10,0x10,0xfe,0x92,0x90,0xfc,0xa4,0xa4,0xa8,0x90,0x28,0x46,0x84,
-+0x10,0x1f,0x28,0x45,0x8,0x7f,0x8,0x3f,0x2a,0x2a,0x3e,0x18,0x2c,0x4a,0x88,0x8,0x40,0x7c,0xa0,0x50,0x40,0x78,0x90,0xfc,0x84,0x94,0x94,0xa4,0xb4,0x48,0x46,0x82,
-+0x10,0x1f,0x28,0x45,0x10,0x17,0xfc,0x15,0x1e,0x34,0xd3,0x12,0x13,0x12,0x53,0x22,0x40,0x7c,0xa0,0x10,0x84,0x7e,0x24,0x24,0xd4,0x8,0xf8,0x8,0xf8,0x8,0xf8,0x8,
-+0x1,0x5,0x39,0x21,0x21,0x3d,0x21,0x21,0x21,0x3f,0x21,0x2,0x2,0x4,0x18,0xe0,0x0,0x8,0x7c,0x8,0x8,0x78,0x8,0x8,0x8,0xf8,0x8,0x80,0x80,0x40,0x30,0xe,
-+0x6,0x38,0x20,0x20,0x3e,0x20,0x20,0x3f,0x24,0x4,0xff,0x4,0x4,0x8,0x10,0x20,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x48,0x40,0xfe,0x40,0x40,0x40,0x40,0x40,
-+0x1,0x7f,0x1,0x3f,0x2,0xff,0x4,0x8,0x16,0x38,0xd0,0x1e,0x10,0x10,0x1f,0x10,0x8,0xfc,0x0,0xf8,0x0,0xfe,0x40,0x20,0x10,0xfe,0x14,0xf0,0x10,0x10,0xf0,0x10,
-+0x6,0x38,0x20,0x20,0x3e,0x20,0x20,0x3f,0x8,0x1f,0x20,0xe9,0x24,0x24,0x40,0x0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x4,0xfe,0x4,0x24,0x94,0x84,0x14,0x8,
-+0x2,0x4,0x1f,0x10,0x1f,0x10,0x1f,0x10,0x1f,0x1,0xff,0x3,0x5,0x19,0x61,0x1,0x0,0x10,0xf8,0x10,0xf0,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x80,0x60,0x1c,0x8,0x0,
-+0x8,0x8,0x10,0x7f,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x5f,0xf0,0x1,0x0,0x0,0x4,0xfe,0x24,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0x24,0xa4,0x24,0xfe,0x0,
-+0x10,0x20,0x7d,0x44,0x64,0x54,0x44,0xfc,0x44,0x64,0x54,0x54,0x44,0x44,0x57,0x88,0x0,0x8,0xfc,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x10,0x24,0x7e,0x44,0x65,0x55,0x45,0xfd,0x45,0x65,0x55,0x55,0x45,0x45,0x55,0x88,0x20,0x20,0x20,0x20,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0xfc,0x4,
-+0x10,0x24,0x7e,0x45,0x65,0x54,0x44,0xfc,0x44,0x64,0x54,0x54,0x44,0x45,0x56,0x88,0x0,0x44,0x24,0x24,0x28,0x88,0x88,0x90,0x50,0x20,0x50,0x50,0x88,0xe,0x4,0x0,
-+0x10,0x25,0x7f,0x45,0x65,0x55,0x45,0xfd,0x45,0x65,0x55,0x55,0x45,0x45,0x55,0x88,0x20,0x20,0x20,0x20,0x20,0x24,0xec,0x30,0x20,0x20,0x20,0x20,0x62,0xa2,0x1e,0x0,
-+0x10,0x24,0x7e,0x45,0x65,0x55,0x45,0xfd,0x45,0x65,0x55,0x55,0x44,0x44,0x54,0x88,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0x24,0xfc,0x24,0x20,0x20,0x20,0x20,
-+0x10,0x24,0x7f,0x45,0x65,0x55,0x45,0xfd,0x45,0x65,0x55,0x55,0x45,0x46,0x54,0x89,0x8,0x1c,0xe0,0x0,0x0,0xfc,0x44,0x44,0x44,0x28,0x28,0x10,0x28,0x48,0x84,0x2,
-+0x10,0x24,0x7e,0x45,0x64,0x54,0x44,0xfc,0x44,0x64,0x54,0x54,0x44,0x45,0x55,0x8a,0x40,0x20,0x24,0xfe,0x40,0x40,0x44,0x7e,0x44,0x44,0x84,0x84,0x84,0x4,0x28,0x10,
-+0x10,0x24,0x7f,0x44,0x64,0x55,0x45,0xfd,0x45,0x65,0x55,0x55,0x44,0x44,0x54,0x88,0x0,0x4,0xfe,0x8,0x8,0xe8,0x28,0x28,0x28,0x28,0xe8,0x28,0x8,0x8,0x28,0x10,
-+0x10,0x24,0x7e,0x44,0x64,0x55,0x45,0xfd,0x45,0x65,0x55,0x55,0x45,0x45,0x55,0x8a,0x20,0x24,0x3e,0x20,0x24,0xfe,0x4,0x4,0x4,0xfc,0x0,0x0,0x0,0x0,0x0,0x0,
-+0x10,0x24,0x7e,0x44,0x65,0x55,0x45,0xfd,0x45,0x65,0x55,0x55,0x45,0x45,0x55,0x89,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xfc,0x24,0x24,0x24,0x24,0xfc,0x4,
-+0x10,0x24,0x7e,0x44,0x65,0x55,0x46,0xfc,0x44,0x64,0x54,0x54,0x44,0x44,0x54,0x88,0x80,0x80,0x84,0xfe,0x40,0x40,0x50,0x78,0x40,0x40,0x48,0x7c,0x40,0x40,0x40,0x40,
-+0x10,0x21,0x7c,0x44,0x64,0x55,0x45,0xfd,0x45,0x65,0x55,0x55,0x45,0x45,0x55,0x89,0x4,0xfe,0x50,0x50,0x54,0xfe,0x54,0x54,0x54,0x54,0x5c,0x84,0x4,0x4,0xfc,0x4,
-+0x10,0x25,0x7e,0x44,0x64,0x55,0x45,0xfd,0x45,0x65,0x55,0x55,0x45,0x45,0x55,0x89,0x20,0x24,0xa8,0xb0,0x24,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,0x4,0x14,0x8,
-+0x10,0x25,0x7f,0x45,0x65,0x55,0x45,0xfd,0x45,0x65,0x55,0x55,0x45,0x45,0x56,0x88,0x4,0xfe,0x4,0x4,0xfc,0x0,0xfc,0x20,0xfc,0x20,0xfe,0x20,0x20,0x22,0x22,0x1e,
-+0x10,0x24,0x7e,0x44,0x64,0x57,0x44,0xfc,0x44,0x65,0x55,0x55,0x45,0x45,0x57,0x88,0x8,0xfc,0x10,0x20,0x24,0xfe,0x20,0xa0,0x44,0xfe,0x54,0x54,0x54,0x54,0xfe,0x0,
-+0x11,0x20,0x7c,0x47,0x64,0x54,0x45,0xfd,0x45,0x65,0x55,0x55,0x45,0x45,0x55,0x89,0x4,0x88,0x50,0xfe,0x20,0x44,0xfe,0x4,0x4,0xfc,0x4,0xfc,0x4,0x4,0xfc,0x4,
-+0x10,0x24,0x7f,0x44,0x65,0x55,0x45,0xfd,0x45,0x64,0x55,0x55,0x45,0x45,0x55,0x89,0x50,0x54,0xfe,0x50,0xfc,0x54,0xfc,0x54,0xfc,0x0,0xfc,0x4,0xfc,0x4,0xfc,0x4,
-+0x10,0x25,0x7e,0x44,0x67,0x54,0x45,0xfd,0x45,0x65,0x55,0x54,0x45,0x44,0x57,0x88,0x20,0xfc,0x88,0x50,0xfe,0x0,0xfc,0x24,0xfc,0x24,0xfc,0x20,0xfc,0x20,0xfe,0x0,
-+0x10,0x24,0x7f,0x44,0x65,0x55,0x46,0xfc,0x47,0x64,0x57,0x54,0x47,0x44,0x57,0x88,0x50,0x54,0xfe,0x50,0xfe,0x2,0xf4,0x0,0xfe,0x84,0x48,0xb0,0x70,0xae,0x24,0x60,
-+0x1,0x2,0x6,0x9,0x37,0xc0,0x2,0x1,0xff,0x5,0xd,0x14,0x24,0xc5,0x6,0x4,0x0,0x80,0x40,0x30,0xee,0x24,0x40,0x4,0xfe,0x0,0x10,0xa0,0x40,0x30,0xe,0x4,
-+0x4,0x1f,0x10,0x14,0x12,0x10,0x1f,0x2,0x1,0xff,0x5,0xc,0x14,0x65,0x6,0x4,0x20,0xf0,0x20,0x20,0xa0,0x44,0xfe,0x4,0x24,0xf4,0x14,0xa8,0x40,0x3c,0x8,0x0,
-+0x10,0x10,0x7e,0x12,0x12,0x22,0x2a,0x45,0x1,0xff,0x5,0xc,0x34,0xc5,0x6,0x4,0x0,0x8,0xfc,0x88,0x88,0x88,0xf8,0x0,0x4,0xfe,0x10,0xa0,0x40,0x30,0xe,0x4,
-+0x1,0x1,0x7f,0x11,0xd,0x5,0x9,0x33,0xff,0x5,0xd,0x14,0x24,0xc5,0x6,0x4,0x40,0x28,0xfc,0x10,0x60,0x80,0x60,0x14,0xfe,0x8,0x10,0xa0,0x40,0x30,0xe,0x4,
-+0x10,0x8,0x41,0x25,0xa,0x10,0x21,0x2e,0x1,0xff,0x5,0xc,0x34,0xc5,0x6,0x4,0x40,0x50,0x4c,0x44,0x50,0x60,0x80,0x0,0x4,0xfe,0x10,0xa0,0x40,0x30,0xe,0x4,
-+0x2,0x3f,0x22,0x3e,0x21,0x7e,0xa2,0x22,0x3f,0x1,0xff,0x4,0xc,0x15,0x66,0x4,0x20,0xfc,0x88,0x50,0xfe,0x20,0xf8,0x20,0x20,0x24,0xfe,0x90,0x60,0x1e,0x4,0x0,
-+0x44,0x24,0x29,0xff,0x11,0x11,0x7d,0x11,0x11,0xff,0x11,0x11,0x21,0x21,0x41,0x81,0x8,0x1c,0xe0,0x20,0x20,0x20,0x24,0xfe,0x20,0x10,0x10,0x10,0x2a,0x4a,0xa6,0x12,
-+0x44,0x25,0x28,0xfe,0x10,0x10,0x7c,0x11,0x12,0xfe,0x10,0x10,0x20,0x20,0x43,0x80,0x8,0xfc,0x8,0x10,0x20,0x50,0x88,0x6,0x0,0xf8,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x44,0x24,0x28,0xfe,0x11,0x10,0x7d,0x12,0x10,0xfe,0x10,0x11,0x22,0x20,0x40,0x83,0x20,0x20,0x50,0x88,0xfc,0x88,0x6,0x82,0xf8,0x88,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x44,0x25,0x29,0xfd,0x11,0x11,0x7c,0x10,0x11,0xfe,0x15,0x11,0x21,0x21,0x40,0x80,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x84,0xfe,0x4,0x24,0x24,0x54,0x4,0xe4,0x14,0x8,
-+0x44,0x25,0x29,0xfd,0x11,0x10,0x7c,0x13,0x10,0xfe,0x11,0x11,0x22,0x22,0x44,0x88,0x20,0x24,0x24,0x24,0xfc,0x80,0x84,0xfe,0x90,0x90,0x54,0x58,0xa8,0x28,0x44,0x82,
-+0x4,0x7f,0x1,0x3f,0x1,0xff,0x0,0x3e,0x8,0xff,0x2a,0x3d,0x51,0x9e,0x2,0xc,0x40,0xfc,0x0,0xf8,0x0,0xfe,0x80,0xa0,0x94,0xfe,0x80,0x48,0x50,0x22,0x52,0x8e,
-+0x10,0x10,0x94,0x54,0x59,0x11,0xff,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x10,0x10,0x20,0x20,0x20,0x20,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0xfc,0x4,0x0,
-+0x10,0x10,0x94,0x54,0x58,0x11,0xfe,0x30,0x38,0x54,0x54,0x90,0x10,0x10,0x11,0x12,0x40,0x40,0x40,0x44,0xfe,0x8,0x88,0x88,0x88,0x90,0x50,0x20,0x50,0x8e,0x4,0x0,
-+0x10,0x10,0x95,0x55,0x59,0x11,0xff,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x10,0x10,0x0,0x4,0xfe,0x24,0x24,0x24,0x24,0x24,0xfc,0x4,0x0,0x0,0x2,0x2,0xfe,0x0,
-+0x10,0x10,0x95,0x55,0x59,0x11,0xff,0x31,0x39,0x55,0x55,0x91,0x12,0x12,0x14,0x11,0x0,0x4,0xfe,0x0,0x4,0xfe,0x40,0x44,0x7e,0x44,0x44,0x44,0x44,0x44,0x94,0x8,
-+0x1,0x11,0x11,0x1f,0x21,0x21,0x3f,0x11,0x9,0x5,0xff,0x3,0x5,0x19,0x61,0x1,0x0,0x10,0x10,0xf0,0x8,0x8,0xf8,0x10,0x30,0x44,0xfe,0x80,0x60,0x1c,0x8,0x0,
-+0x10,0x10,0x97,0x54,0x58,0x10,0xff,0x32,0x3a,0x56,0x56,0x93,0x12,0x12,0x13,0x12,0x0,0x4,0xfe,0x90,0x90,0x94,0xfe,0x94,0x94,0x94,0x9c,0x4,0x4,0x4,0xfc,0x4,
-+0x1,0x41,0x31,0x12,0x4,0x11,0x26,0x50,0x9,0x5,0xff,0x3,0x5,0x19,0x61,0x1,0x0,0x0,0xfc,0x48,0xa0,0x10,0xe,0x10,0x30,0x44,0xfe,0x80,0x60,0x1c,0x8,0x0,
-+0x8,0xf,0x28,0x3f,0x21,0x52,0x8c,0x19,0x69,0x5,0xff,0x3,0x5,0x19,0x61,0x1,0x0,0x7c,0x44,0x28,0x10,0x28,0xc6,0x10,0x30,0x44,0xfe,0x80,0x60,0x1c,0x8,0x0,
-+0x8,0x49,0x2a,0xff,0x1c,0x2a,0x49,0x49,0x7f,0x95,0x55,0x37,0x21,0x41,0x81,0x1,0x0,0x12,0x12,0x92,0x24,0x24,0x24,0x48,0xa4,0x24,0x24,0x92,0x12,0x12,0x12,0x0,
-+0x10,0x10,0x95,0x55,0x59,0x12,0xfe,0x30,0x38,0x57,0x54,0x90,0x11,0x12,0x10,0x10,0x40,0x20,0x20,0xfe,0x2,0x4,0xf8,0x0,0x4,0xfe,0x20,0xa8,0x26,0x22,0xa0,0x40,
-+0x10,0x10,0x94,0x55,0x58,0x13,0xfe,0x30,0x39,0x56,0x54,0x90,0x11,0x10,0x10,0x17,0x20,0x40,0x88,0xfc,0x40,0xfe,0x50,0x98,0x24,0xca,0x10,0x64,0x88,0x30,0xc0,0x0,
-+0x10,0x10,0x94,0x55,0x59,0x13,0xfd,0x31,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11,0x80,0xf8,0x88,0x8,0xfe,0x40,0x40,0x7c,0x90,0x14,0xfe,0x10,0x10,0x28,0x24,0xc2,
-+0x11,0x11,0x95,0x55,0x5a,0x11,0xfe,0x31,0x3a,0x54,0x55,0x91,0x11,0x11,0x11,0x11,0x10,0x10,0xd0,0x58,0x54,0x50,0x90,0x56,0x3c,0x8,0xfc,0x8,0xf8,0x8,0xf8,0x8,
-+0x10,0x10,0x94,0x54,0x5b,0x10,0xfe,0x30,0x39,0x57,0x54,0x90,0x11,0x11,0x13,0x10,0x0,0x88,0x50,0x4,0xfe,0x0,0x88,0x88,0x54,0xfc,0x88,0x88,0x10,0x54,0xfe,0x22,
-+0x10,0x11,0x94,0x54,0x58,0x12,0xfd,0x32,0x39,0x55,0x55,0x91,0x11,0x11,0x11,0x11,0x0,0xfc,0x24,0xa0,0xbc,0xe0,0x3e,0x0,0xfc,0x4,0xfc,0x4,0xfc,0x4,0x14,0x8,
-+0x10,0x11,0x94,0x54,0x59,0x10,0xfe,0x31,0x3a,0x54,0x55,0x90,0x10,0x11,0x12,0x10,0x0,0xf8,0x50,0x20,0xfe,0x62,0xa4,0x20,0x60,0x24,0xfe,0x70,0xa8,0x26,0x20,0x20,
-+0x10,0x10,0x95,0x55,0x59,0x11,0xff,0x31,0x39,0x54,0x50,0x97,0x10,0x10,0x10,0x13,0x40,0x84,0xfe,0x4,0xfc,0x4,0xfc,0x4,0xfc,0x28,0x24,0xfe,0x50,0x50,0x8e,0x4,
-+0x20,0x2f,0x21,0xa9,0x71,0x27,0xfc,0x24,0x77,0x69,0xa9,0x21,0x21,0x21,0x2a,0x24,0x4,0x7e,0x44,0x44,0x7c,0x10,0x14,0x7e,0x54,0x54,0x7c,0x10,0x10,0x14,0xfe,0x2,
-+0x0,0x3f,0x20,0x20,0x3f,0x20,0x20,0x3f,0x24,0x24,0x22,0x21,0x20,0x28,0x30,0x20,0x10,0xf8,0x10,0x10,0xf0,0x10,0x10,0xf0,0x10,0x20,0x40,0x80,0x60,0x1e,0x4,0x0,
-+0x7d,0x44,0x7d,0x45,0x7c,0x48,0x5c,0x63,0x1f,0x10,0x1f,0x10,0x1f,0x0,0xff,0x0,0xf8,0x20,0x24,0xfe,0x20,0x52,0x92,0xe,0xf0,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x0,
-+0x2,0x7f,0x22,0x12,0x2,0x1a,0x63,0xa,0x4,0x8,0xff,0x8,0x8,0x8,0x10,0x20,0x8,0xfc,0x88,0x48,0x8,0x68,0x88,0x28,0x10,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x10,0x10,0x2b,0x24,0x50,0x8a,0x1,0x7c,0x4,0x8,0x49,0x32,0x10,0x8,0x9,0x0,0x0,0x44,0xfe,0x44,0x44,0x64,0x54,0xcc,0x44,0xcc,0x54,0x64,0x44,0x44,0x54,0x88,
-+0x1,0x2,0xc,0x37,0xc0,0x1f,0x10,0x1f,0x2,0x7f,0x12,0xa,0x12,0x22,0xa,0x4,0x0,0x80,0x60,0xd8,0x6,0xf0,0x10,0xf0,0x8,0xfc,0x48,0x28,0x48,0x88,0x28,0x10,
-+0x2,0x1f,0x2,0xff,0x2,0xf,0x38,0xcf,0x8,0xf,0x0,0x7e,0x22,0x1a,0x62,0x6,0x20,0xc0,0x84,0xfe,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x4,0xfe,0x44,0x34,0xc4,0xc,
-+0x2,0x2,0x7e,0x2,0x3e,0x2,0xfe,0x2,0x7f,0x22,0x12,0xa,0x12,0x63,0xa,0x4,0x80,0x88,0xfc,0x80,0xf8,0x80,0xfe,0x88,0xfc,0x8,0x48,0x28,0x48,0x88,0x28,0x10,
-+0x8,0x4,0xff,0x0,0x3e,0x22,0x3e,0x22,0x3e,0x22,0x7e,0x22,0x12,0x1a,0x62,0x6,0x20,0x44,0xfe,0x8,0x48,0x48,0x48,0x48,0x48,0x18,0xfc,0x44,0x24,0x34,0xc4,0xc,
-+0x10,0x9,0x7f,0x41,0x41,0x7f,0x40,0x40,0x7f,0x55,0x55,0x7f,0xd5,0x55,0x41,0x43,0x0,0x24,0xfe,0x24,0x24,0xb4,0x6c,0x24,0x24,0x6c,0xb4,0x24,0x24,0x24,0xb4,0x48,
-+0x2,0x7f,0x0,0x3e,0x22,0x3e,0x0,0x7f,0x41,0x55,0x55,0x7f,0x49,0x49,0x43,0x0,0x24,0xfe,0x24,0x24,0x24,0xb4,0x6c,0x24,0x24,0x6c,0xb4,0x24,0x24,0x24,0xb4,0x48,
-+0x7f,0x50,0x5e,0x68,0x7f,0x48,0x54,0x7f,0x0,0x7e,0x22,0x12,0x1a,0x62,0xa,0x4,0x7c,0x44,0x46,0x80,0x7c,0x28,0x10,0x6e,0x4,0xfe,0x44,0x24,0x34,0xc4,0x14,0x8,
-+0x1,0x3,0x4,0x8,0x10,0x3f,0x1,0x2,0x4,0x3f,0x1,0x9,0x19,0x21,0x45,0x2,0x0,0x0,0x0,0x10,0x30,0xc0,0x0,0x20,0x10,0xf8,0x0,0x20,0x18,0xc,0x4,0x0,
-+0x8,0x8,0xfe,0x8,0x3e,0xc8,0x29,0x12,0x1f,0x1,0x2,0x3f,0x9,0x11,0x21,0x3,0x40,0x48,0xfc,0x48,0xc8,0x6a,0x8a,0x26,0xc0,0x0,0x10,0xf8,0x20,0x18,0x8,0x0,
-+0x8,0x8,0x7f,0xa,0x9,0x8,0xff,0x9,0x12,0x2f,0xc1,0x2,0x3f,0x9,0x11,0x23,0x20,0x28,0xfc,0x20,0x20,0xa4,0xfe,0x20,0x30,0xee,0x4,0x10,0xf8,0x20,0x18,0x8,
-+0x10,0x8,0x3e,0x23,0x22,0x3e,0x41,0x42,0x9f,0x1,0x2,0x3f,0x9,0x11,0x21,0x3,0x40,0x48,0xfc,0x48,0x30,0x48,0x86,0x20,0xc0,0x0,0x10,0xf8,0x20,0x18,0x8,0x0,
-+0x2,0xd,0xf0,0x94,0x54,0x49,0x7e,0x90,0x10,0xfd,0x10,0x54,0x55,0x56,0x7c,0x0,0x1c,0xe0,0x20,0x40,0x84,0xf8,0x10,0x20,0x44,0xfe,0x20,0xa8,0x26,0x22,0xa0,0x40,
-+0x1,0xff,0x1,0x1f,0x12,0xff,0x10,0x1f,0x0,0x3e,0x32,0x2a,0xff,0x28,0x4a,0x18,0x4,0xfe,0x0,0xf0,0x14,0xfe,0x90,0xf0,0x1c,0xe0,0x24,0xf8,0x24,0xfe,0x54,0xb2,
-+0x10,0x14,0xfe,0x11,0x7c,0x10,0xfe,0x21,0x3c,0x44,0xa4,0x28,0x10,0x28,0x41,0x82,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x50,0x50,0x88,0x88,0x6,0x4,
-+0x10,0x14,0xfe,0x10,0x55,0xba,0x11,0x28,0x67,0xbc,0x24,0x29,0x5a,0x10,0x20,0xc0,0x80,0x80,0x84,0xfe,0x4,0x4c,0x54,0xe4,0xfc,0x44,0xe4,0x54,0x4c,0x44,0x54,0x48,
-+0x8,0xa,0x7f,0x8,0x9,0xff,0x8,0x28,0x2a,0x2f,0x28,0x28,0x58,0x48,0x87,0x0,0x8,0x8,0x48,0x48,0x48,0xc8,0x48,0x48,0x48,0x78,0x8,0x8,0x8,0x6,0xfc,0x0,
-+0x8,0x8,0x7f,0x8,0xa,0xff,0x8,0x28,0x28,0x2e,0x28,0x2b,0x58,0x48,0x87,0x0,0x8,0xfc,0x88,0x88,0xf8,0x88,0x88,0xf8,0x88,0x88,0x88,0xfe,0x0,0x6,0xfc,0x0,
-+0x10,0x17,0x7d,0x11,0x11,0xfd,0x12,0x55,0x50,0x5c,0x51,0x72,0x50,0x48,0x87,0x0,0x44,0xe4,0x4,0x14,0xd4,0x54,0x54,0x54,0xd4,0x94,0x4,0x14,0x8,0x6,0xfc,0x0,
-+0x10,0x12,0x7d,0x11,0x14,0xfe,0x10,0x50,0x51,0x5d,0x52,0x72,0x50,0x48,0x87,0x0,0x20,0x20,0x20,0x7e,0x82,0x14,0x90,0x90,0x10,0x28,0x26,0x42,0x80,0x6,0xfc,0x0,
-+0x11,0x15,0x7f,0x19,0x17,0xfb,0x15,0x59,0x57,0x5a,0x52,0x72,0x52,0x49,0x86,0x3,0x8,0x28,0xbc,0x48,0xfe,0x18,0xaa,0x4e,0xf8,0x8,0x48,0x48,0xb8,0x8,0x6,0xfc,
-+0x8,0x8,0xa,0x7f,0x8,0x8,0xff,0x14,0x54,0x56,0x55,0x94,0x14,0x14,0x24,0x4c,0x8,0xfc,0x88,0x88,0x88,0xa8,0x90,0xfc,0x84,0xc4,0xa8,0xa8,0x90,0xa8,0xc6,0x84,
-+0x8,0x8,0x8,0x7e,0x8,0x8,0xff,0x14,0x56,0x55,0x56,0x94,0x14,0x14,0x24,0x4c,0x20,0x20,0x24,0xfc,0x28,0x30,0xfe,0x40,0xfc,0x84,0x84,0xfc,0x84,0x84,0xfc,0x84,
-+0x0,0xff,0x1,0x0,0x7e,0x42,0x42,0x42,0x7e,0x0,0x44,0x24,0x28,0xe,0xf1,0x40,0x0,0x8,0xfc,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x2,0xff,0x0,0x1,0x7e,0x42,0x42,0x42,0x7e,0x0,0x44,0x24,0x28,0xe,0xf0,0x43,0x20,0x20,0x24,0xfe,0x20,0x20,0xf8,0x8,0x88,0x50,0x50,0x20,0x50,0x48,0x8e,0x4,
-+0x1,0xff,0x14,0x14,0x7f,0x55,0x55,0x55,0x57,0x61,0x41,0x7f,0x41,0x41,0x7f,0x41,0x0,0x84,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x50,0x20,
-+0x1,0xff,0x14,0x15,0x7f,0x55,0x55,0x55,0x57,0x61,0x41,0x7f,0x41,0x41,0x7f,0x41,0x0,0x88,0x7c,0x10,0x90,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x1,0xff,0x14,0x14,0x7f,0x55,0x55,0x55,0x57,0x61,0x41,0x7f,0x41,0x41,0x7f,0x41,0x8,0x88,0x8,0x8,0xfe,0x8,0x8,0x48,0x28,0x28,0x8,0x8,0x8,0x8,0x28,0x10,
-+0x4,0xfe,0x28,0x28,0xfe,0xaa,0xaa,0xab,0xae,0xc2,0x82,0xfe,0x82,0x82,0xfe,0x82,0x20,0x20,0x20,0x24,0xa6,0xbc,0xe4,0xa4,0xa4,0xb4,0xa8,0xa0,0x82,0x82,0x7e,0x0,
-+0x4,0xfe,0x28,0x28,0xff,0xaa,0xaa,0xaa,0xae,0xc2,0x82,0xfe,0x82,0x82,0xfe,0x82,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x28,0xfc,0x88,0x88,0x88,0x88,0x88,0xf8,0x88,
-+0x1,0xff,0x14,0x14,0x7f,0x55,0x55,0x55,0x57,0x61,0x41,0x7f,0x41,0x41,0x7f,0x41,0x20,0xa0,0x20,0x24,0x7e,0x60,0xa4,0x3e,0x20,0x20,0x24,0x3e,0x20,0x20,0x20,0x20,
-+0x1,0xff,0x14,0x14,0x7f,0x55,0x55,0x55,0x57,0x61,0x41,0x7f,0x41,0x41,0x7f,0x41,0x20,0x90,0x10,0x7e,0x42,0x84,0x20,0x20,0x24,0x28,0x30,0x20,0x22,0x22,0x1e,0x0,
-+0x1,0xff,0x14,0x14,0x7f,0x55,0x55,0x55,0x57,0x61,0x41,0x7f,0x41,0x41,0x7f,0x41,0x10,0x90,0x50,0x7c,0x50,0x90,0x14,0xfe,0x28,0x28,0x28,0x28,0x2a,0x4a,0x86,0x0,
-+0x1,0xff,0x14,0x14,0x7f,0x55,0x55,0x55,0x57,0x61,0x41,0x7f,0x41,0x41,0x7f,0x41,0x10,0x90,0x10,0x3e,0x44,0xa8,0x18,0x10,0x24,0x7e,0xc4,0x44,0x44,0x44,0x7c,0x44,
-+0x1,0xff,0x14,0x14,0x7f,0x55,0x55,0x55,0x57,0x61,0x41,0x7f,0x41,0x41,0x7f,0x41,0x40,0xc4,0x4c,0x50,0x62,0x42,0x7e,0x4,0x7e,0x44,0x44,0x7c,0x44,0x44,0x7c,0x44,
-+0x4,0xff,0x28,0x28,0xfe,0xaa,0xaa,0xaa,0xae,0xc2,0x82,0xfe,0x82,0x82,0xff,0x82,0x4,0xfe,0x28,0xaa,0x6c,0x28,0xfe,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x0,0x0,
-+0x4,0xff,0x28,0x28,0x7d,0x55,0x55,0x55,0x6d,0x45,0x45,0x7d,0x45,0x45,0x7d,0x45,0x4,0xfe,0x0,0x4,0xde,0x54,0x54,0x54,0x54,0xdc,0x54,0x54,0x54,0x54,0x54,0x54,
-+0x4,0xfe,0x28,0x28,0xfe,0xaa,0xaa,0xab,0xae,0xc2,0x82,0xfe,0x82,0x82,0xff,0x82,0x4,0xfe,0x84,0x84,0x84,0xfc,0x0,0xfe,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x4,0xfe,0x28,0x28,0xfe,0xab,0xaa,0xaa,0xae,0xc3,0x82,0xfe,0x82,0x83,0xfe,0x82,0x20,0x20,0x50,0x50,0x8e,0x4,0xf8,0x20,0x24,0xfe,0x20,0x70,0xac,0x24,0xa0,0x40,
-+0x4,0xfe,0x29,0x28,0xff,0xaa,0xaa,0xab,0xae,0xc2,0x82,0xfe,0x82,0x82,0xfe,0x82,0x8,0x1c,0xe0,0x4,0x24,0xa8,0x8,0xfe,0x8,0x88,0x48,0x48,0x8,0x8,0x28,0x10,
-+0x4,0xfe,0x28,0x28,0xfe,0xaa,0xaa,0xaa,0xae,0xc2,0x82,0xfe,0x82,0x82,0xfe,0x82,0x4,0xfe,0x84,0x84,0xfc,0x84,0x84,0xfc,0x10,0x90,0x92,0xf4,0x98,0xb2,0xd2,0x8e,
-+0x4,0xfe,0x28,0x29,0xfe,0xaa,0xaa,0xab,0xae,0xc2,0x82,0xfe,0x82,0x82,0xfe,0x82,0x20,0x10,0x14,0xfe,0x0,0x84,0x48,0xfe,0x0,0x4,0xfe,0x84,0x84,0x84,0xfc,0x84,
-+0x4,0xfe,0x28,0x28,0x7f,0x54,0x54,0x55,0x6d,0x45,0x45,0x7d,0x45,0x45,0x7c,0x44,0x84,0x9e,0x94,0x94,0xf4,0x9c,0x94,0xd4,0x54,0x5c,0x54,0x54,0xd4,0x24,0x24,0x4c,
-+0x4,0xfe,0x28,0x28,0x7c,0x54,0x54,0x57,0x6c,0x44,0x44,0x7c,0x44,0x44,0x7d,0x46,0x8,0xfc,0x88,0xf8,0x88,0xf8,0x0,0xfe,0x20,0xa8,0xbc,0xa0,0xa0,0xe6,0x3c,0x0,
-+0x4,0xfe,0x28,0x28,0xfe,0xaa,0xaa,0xab,0xae,0xc2,0x82,0xfe,0x82,0x82,0xfe,0x82,0x0,0xfe,0x12,0x50,0x5c,0x50,0xb0,0xe,0x7c,0x44,0x7c,0x44,0x7c,0x44,0x54,0x48,
-+0x4,0xfe,0x2b,0x28,0x7c,0x55,0x56,0x54,0x6c,0x44,0x45,0x7d,0x45,0x45,0x7f,0x44,0x40,0x44,0xfe,0x40,0x88,0xfc,0x88,0x88,0xf8,0x4,0xfe,0x54,0x54,0x54,0xfe,0x0,
-+0x4,0xfe,0x29,0x29,0x7d,0x55,0x55,0x55,0x6d,0x45,0x45,0x7d,0x45,0x45,0x7e,0x44,0x20,0x14,0xfe,0x10,0x7c,0x14,0xfe,0x14,0x7c,0x10,0x7c,0x44,0x44,0x44,0x7c,0x44,
-+0x4,0xff,0x29,0x28,0x7d,0x54,0x54,0x54,0x6f,0x44,0x45,0x7c,0x45,0x44,0x7c,0x45,0x4,0xde,0x54,0xcc,0x54,0x64,0x50,0xa8,0x46,0x90,0x20,0x48,0x90,0x20,0x40,0x80,
-+0x2,0xff,0x28,0x28,0xff,0xaa,0xaa,0xaa,0xae,0xc2,0x82,0xff,0x82,0x82,0xfe,0x83,0x50,0x54,0xd8,0x50,0xfe,0x88,0x50,0xfc,0x20,0xfc,0x20,0xfe,0x20,0x50,0x8e,0x4,
-+0x4,0xfe,0x28,0x28,0xff,0xaa,0xaa,0xaa,0xae,0xc2,0x82,0xfe,0x82,0x83,0xff,0x82,0x40,0x60,0x94,0xfe,0x90,0xfc,0x90,0x90,0xfc,0x90,0x94,0xfe,0x80,0x54,0x52,0x2,
-+0x4,0xfe,0x29,0x28,0x7c,0x55,0x54,0x54,0x6d,0x46,0x45,0x7d,0x45,0x45,0x7f,0x44,0x40,0x24,0xfe,0x40,0x88,0xfc,0xa8,0xaa,0x2e,0x0,0xfc,0x54,0x54,0x54,0xfe,0x0,
-+0x4,0xfe,0x28,0x29,0x7d,0x55,0x55,0x55,0x6d,0x45,0x45,0x7d,0x45,0x45,0x7e,0x44,0x20,0x3c,0x20,0xfe,0x22,0xfc,0x20,0xfe,0x20,0x54,0xb8,0x58,0xb6,0x54,0x90,0x30,
-+0x4,0xff,0x29,0x29,0x7d,0x55,0x54,0x55,0x6c,0x45,0x45,0x7d,0x44,0x44,0x7f,0x44,0x50,0xfc,0x54,0xfc,0x54,0xfc,0x0,0xfc,0x0,0xfc,0x4,0xfc,0x88,0x50,0xfe,0x0,
-+0x4,0xff,0x28,0x2b,0x7c,0x55,0x55,0x55,0x6d,0x44,0x45,0x7c,0x47,0x45,0x7d,0x46,0x1c,0xe0,0x24,0xfe,0x20,0xfc,0xac,0x74,0xfc,0x20,0xfc,0x20,0xfe,0x54,0x52,0x2,
-+0x0,0xff,0x2,0x6,0x9,0x11,0x62,0x4,0x8,0x31,0x2,0x4,0x18,0x60,0x2,0x1,0x4,0xfe,0x0,0x8,0x18,0xa0,0xc0,0xc0,0xa0,0xa0,0x90,0x8e,0x84,0x80,0x80,0x0,
-+0x11,0x10,0x1f,0x10,0x7d,0x44,0x47,0x6c,0x54,0x54,0x55,0x6d,0x46,0x44,0x7f,0x44,0x8,0x90,0xfe,0x40,0xfc,0x40,0xfe,0x80,0x88,0xfc,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x0,0xff,0x4,0x7,0x4,0x8,0x30,0xdf,0x10,0x10,0x1f,0x9,0x9,0x19,0x27,0xc0,0x4,0xfe,0x0,0xf0,0x10,0x90,0x60,0xf0,0x10,0x10,0xf0,0x0,0xf8,0x0,0x6,0xfc,
-+0x0,0x7e,0x8,0x8,0xe,0x71,0x2,0x1f,0x10,0x10,0x1f,0x9,0x9,0xd,0x33,0xc0,0x8,0xfc,0x88,0xc8,0xaa,0x6,0x10,0xf8,0x10,0x10,0xf0,0x0,0xf8,0x0,0x6,0xfc,
-+0x8,0x8,0xfe,0x8,0x1e,0xe8,0x9,0x1f,0x10,0x10,0x1f,0x9,0x9,0xd,0x33,0xc0,0xc,0xf0,0x84,0xfe,0x90,0x90,0x10,0xf0,0x10,0x10,0xf0,0x0,0xf8,0x0,0x6,0xfc,
-+0x0,0x3f,0x24,0x27,0x24,0x3f,0x55,0x64,0x9f,0x10,0x1f,0x9,0x9,0xd,0x33,0xc0,0x48,0xfe,0x40,0x48,0x50,0xa0,0x52,0x8a,0xf6,0x10,0xf0,0x0,0xf8,0x0,0x6,0xfc,
-+0x49,0x2a,0x7f,0x49,0x5d,0x6b,0x49,0x1f,0x10,0x10,0x1f,0x9,0x9,0xd,0x33,0xc0,0x20,0x24,0x3e,0x44,0xa8,0x10,0x6e,0xf0,0x10,0x10,0xf0,0x0,0xf8,0x0,0x6,0xfc,
-+0x4,0x7e,0x44,0x44,0x45,0x7d,0x56,0x10,0x50,0x5c,0x50,0x50,0x5c,0xf0,0x40,0x0,0x80,0x80,0x84,0xfe,0x4,0x4,0x4,0x84,0x44,0x44,0x4,0x4,0x4,0x44,0x28,0x10,
-+0x4,0x7f,0x44,0x44,0x44,0x7c,0x54,0x10,0x50,0x5c,0x51,0x51,0x5d,0xf2,0x44,0x9,0x0,0xfc,0x84,0x88,0x88,0x90,0xbc,0x84,0xc4,0xa8,0x28,0x10,0x28,0x28,0x46,0x84,
-+0x4,0x7f,0x44,0x44,0x44,0x7c,0x10,0x13,0x50,0x5c,0x50,0x51,0x5d,0xf1,0x42,0x4,0x4,0xfe,0x88,0x88,0x88,0x88,0x88,0xfe,0x88,0x88,0x88,0x8,0x8,0x8,0x8,0x8,
-+0x4,0x7e,0x44,0x45,0x44,0x7c,0x54,0x13,0x50,0x5c,0x50,0x50,0x5c,0xf1,0x42,0x4,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x50,0x50,0x90,0x88,0x8,0x6,0x4,
-+0x4,0x7e,0x44,0x44,0x44,0x7d,0x56,0x11,0x51,0x5d,0x51,0x51,0x5d,0xf1,0x41,0x0,0x40,0x40,0xa0,0xa0,0x90,0x8,0x16,0xf8,0x10,0x10,0x10,0x50,0x20,0x4,0x4,0xfc,
-+0x4,0x7f,0x44,0x44,0x44,0x7c,0x54,0x10,0x51,0x5e,0x50,0x50,0x5c,0xf0,0x40,0x0,0x4,0xfe,0x40,0x40,0x40,0x80,0x84,0xfe,0x84,0x84,0x84,0x84,0x84,0x84,0xfc,0x84,
-+0x4,0x7e,0x44,0x45,0x45,0x7f,0x55,0x11,0x51,0x5d,0x51,0x51,0x5d,0xf1,0x41,0x1,0x88,0x88,0x88,0x8,0x8,0xfe,0x8,0x8,0x48,0x28,0x28,0x8,0x8,0x8,0x28,0x10,
-+0x0,0x7d,0x45,0x45,0x45,0x7d,0x55,0x13,0x51,0x5d,0x51,0x51,0x5d,0xf2,0x42,0x4,0x4,0xde,0x54,0x54,0x54,0x54,0x54,0xfe,0x54,0x54,0x54,0x54,0x54,0x54,0xe4,0xc,
-+0x4,0x7f,0x45,0x45,0x45,0x7d,0x55,0x11,0x50,0x5c,0x50,0x51,0x5e,0xf0,0x40,0x0,0x1c,0xe0,0x0,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0xa8,0x26,0x22,0x20,0xa0,0x40,
-+0x4,0x7e,0x44,0x45,0x45,0x7e,0x54,0x10,0x50,0x5c,0x50,0x52,0x5c,0xf0,0x40,0x0,0x40,0x20,0x20,0xfe,0x2,0x4,0x80,0x88,0x98,0xa0,0xc0,0x80,0x82,0x82,0x7e,0x0,
-+0x9,0x7d,0x49,0x49,0x4f,0x79,0x51,0x11,0x51,0x5d,0x51,0x51,0x5e,0xf2,0x45,0x8,0x0,0x0,0x0,0x4,0xde,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x5c,0x54,0x80,
-+0x4,0x7e,0x44,0x45,0x45,0x7d,0x55,0x11,0x51,0x5d,0x51,0x51,0x5d,0xf2,0x42,0x5,0x20,0x20,0x20,0xfe,0x22,0x24,0x20,0xfc,0x88,0x48,0x50,0x20,0x50,0x48,0x8e,0x4,
-+0x4,0x7e,0x44,0x44,0x45,0x7f,0x54,0x10,0x51,0x5d,0x51,0x51,0x5d,0xf1,0x41,0x1,0x40,0x40,0x80,0x90,0x8,0xfc,0x2,0x8,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x4,0x7e,0x44,0x45,0x44,0x7c,0x53,0x10,0x50,0x5c,0x51,0x50,0x5c,0xf0,0x43,0x0,0x20,0x20,0x28,0xfc,0x20,0x24,0xfe,0x0,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x4,0x7e,0x44,0x47,0x44,0x7c,0x54,0x13,0x50,0x5d,0x50,0x50,0x5c,0xf1,0x42,0x4,0x40,0x48,0x7c,0xc0,0x50,0x22,0xd2,0xe,0x8,0xfc,0xa0,0xa0,0xa0,0x22,0x22,0x1e,
-+0x0,0x7d,0x45,0x45,0x45,0x7d,0x55,0x11,0x50,0x5c,0x53,0x50,0x5c,0xf0,0x40,0x0,0x10,0x10,0x12,0xd4,0x18,0x12,0x52,0x8e,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,
-+0x4,0x7e,0x45,0x45,0x45,0x7e,0x54,0x13,0x50,0x5c,0x50,0x50,0x5c,0xf1,0x42,0x4,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x90,0x90,0x90,0x90,0x92,0x12,0xe,0x0,
-+0x4,0x7e,0x45,0x45,0x44,0x7c,0x57,0x11,0x51,0x5d,0x51,0x51,0x5d,0xf2,0x44,0x0,0x0,0xc,0x70,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x86,0x7c,0x0,
-+0x0,0x7c,0x47,0x44,0x44,0x7c,0x54,0x10,0x53,0x5c,0x50,0x50,0x5c,0xf0,0x41,0x2,0x40,0x24,0xfe,0x88,0x50,0x20,0x50,0x8e,0x4,0x88,0x88,0x88,0x88,0x88,0x8,0x8,
-+0x4,0x7e,0x44,0x47,0x44,0x7c,0x55,0x12,0x50,0x5c,0x50,0x50,0x5c,0xf0,0x41,0x2,0x40,0x20,0x4,0xfe,0x0,0x88,0x6,0x8a,0x88,0x50,0x50,0x20,0x50,0x88,0xe,0x4,
-+0x4,0x7e,0x45,0x45,0x45,0x7d,0x55,0x11,0x51,0x5d,0x51,0x51,0x5d,0xf1,0x41,0x1,0x40,0x28,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x40,0x24,0x28,0x10,0x4e,0x84,0x0,
-+0x0,0x7d,0x44,0x44,0x45,0x7d,0x55,0x11,0x50,0x5c,0x50,0x52,0x5e,0xf4,0x40,0x0,0x8,0xfc,0x8,0x8,0xf8,0x0,0x4,0x4,0xfc,0x0,0x40,0xa4,0xa2,0x8a,0x78,0x0,
-+0x4,0x7e,0x44,0x44,0x45,0x7d,0x55,0x11,0x51,0x5c,0x50,0x53,0x5c,0xf0,0x40,0x0,0x24,0x3e,0x20,0x20,0xfc,0x4,0xfc,0x4,0xfc,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x0,0x7d,0x45,0x45,0x45,0x7d,0x55,0x11,0x5c,0x53,0x50,0x50,0x5d,0xf2,0x40,0x0,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0xfe,0x70,0xa8,0x26,0x24,0x20,0x20,
-+0x9,0x7d,0x49,0x49,0x4a,0x7c,0x50,0x17,0x50,0x5c,0x50,0x51,0x5d,0xf2,0x44,0x0,0x0,0x0,0x0,0xfe,0x92,0x92,0x92,0xf2,0x92,0x92,0x92,0x52,0x32,0x1e,0x12,0x0,
-+0x4,0x7f,0x45,0x45,0x45,0x7d,0x55,0x11,0x51,0x5d,0x51,0x51,0x5e,0xf2,0x44,0x0,0xc,0xf0,0x10,0x14,0xfe,0x10,0x7c,0x44,0x54,0x54,0x54,0x54,0x20,0x28,0x46,0x82,
-+0x4,0x7e,0x45,0x45,0x45,0x7d,0x55,0x11,0x51,0x5d,0x52,0x52,0x5c,0xf4,0x48,0x0,0x20,0x10,0xfe,0x20,0x24,0x3e,0x20,0x20,0x24,0xfe,0x84,0x84,0x84,0x84,0xfc,0x84,
-+0x4,0x7e,0x45,0x44,0x44,0x7c,0x54,0x13,0x50,0x5d,0x51,0x51,0x5d,0xf1,0x41,0x1,0x40,0x28,0xfc,0x0,0x88,0x50,0x4,0xfe,0x0,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x4,0x7a,0x4a,0x48,0x4f,0x79,0x51,0x11,0x5f,0x59,0x51,0x51,0x5a,0xf2,0x44,0x0,0x40,0x5e,0x92,0x14,0xd4,0x18,0x14,0x54,0xf2,0x12,0x1a,0x14,0x90,0x50,0x50,0x10,
-+0x0,0x78,0x4f,0x49,0x49,0x7a,0x57,0x11,0x51,0x5d,0x55,0x53,0x5d,0xf2,0x44,0x8,0x10,0x10,0x7c,0x14,0xfe,0x14,0x7c,0x10,0x7c,0x10,0xfe,0x10,0x10,0x96,0x7c,0x0,
-+0x0,0x7d,0x47,0x45,0x45,0x7d,0x55,0x11,0x50,0x5c,0x53,0x50,0x5c,0xf1,0x42,0x0,0x48,0x48,0xfe,0x48,0x48,0x78,0x0,0xfc,0x20,0x24,0xfe,0x70,0xa8,0x26,0x24,0x20,
-+0x8,0x7c,0x4a,0x4a,0x4b,0x78,0x57,0x10,0x58,0x57,0x54,0x54,0x5c,0xf4,0x44,0x4,0x40,0x40,0x48,0x48,0xf8,0x0,0xfe,0x40,0x84,0xfe,0xa4,0xa4,0xa4,0xa4,0xa4,0xc,
-+0x0,0x7d,0x44,0x44,0x47,0x7c,0x55,0x11,0x51,0x5d,0x51,0x50,0x5d,0xf0,0x43,0x0,0xc,0xf0,0x20,0x24,0xfe,0x20,0xfc,0x24,0xfc,0x24,0xfc,0x20,0xfc,0x20,0xfe,0x0,
-+0x0,0x7d,0x44,0x45,0x45,0x7d,0x55,0x11,0x50,0x5f,0x52,0x52,0x5e,0xf2,0x42,0x2,0xc,0xf0,0x24,0xfe,0x24,0x24,0xfc,0x24,0x20,0xfe,0x22,0x2a,0xfa,0x2,0xa,0x4,
-+0x4,0x7e,0x45,0x45,0x45,0x7d,0x55,0x11,0x51,0x5d,0x51,0x51,0x5e,0xf2,0x44,0xb,0x20,0x14,0xfe,0x48,0x48,0xfe,0x48,0x78,0x0,0xfc,0x4,0x48,0x30,0x28,0xc6,0x4,
-+0x1,0x7c,0x47,0x44,0x45,0x7c,0x57,0x10,0x50,0x5c,0x51,0x51,0x5e,0xf0,0x43,0x0,0x8,0x90,0xfe,0x40,0xfc,0x40,0xfe,0x80,0x88,0xfc,0x20,0x20,0x20,0x24,0xfe,0x0,
-+0x4,0x7e,0x45,0x45,0x45,0x7d,0x55,0x11,0x51,0x5d,0x52,0x52,0x5c,0xf4,0x48,0x0,0x40,0x24,0xfe,0x4,0x4,0xfc,0x4,0x0,0xfe,0xaa,0xaa,0xfe,0xaa,0xaa,0xaa,0x84,
-+0x4,0x7e,0x44,0x44,0x45,0x7c,0x54,0x11,0x50,0x5c,0x53,0x50,0x5c,0xf1,0x42,0x0,0x0,0xfc,0x48,0x30,0xfe,0x32,0x54,0x90,0x30,0x24,0xfe,0x70,0xa8,0x26,0x24,0x20,
-+0x8,0x7f,0x49,0x49,0x49,0x79,0x51,0x17,0x50,0x5f,0x54,0x52,0x59,0xf2,0x44,0x8,0x4,0xfe,0x8,0xf8,0x8,0xf8,0x8,0xfe,0x8,0xbe,0xa2,0x94,0x8,0x94,0x24,0x42,
-+0x8,0x7c,0x4b,0x48,0x48,0x7f,0x50,0x13,0x52,0x5e,0x52,0x53,0x5f,0xf2,0x42,0x2,0x90,0x90,0xfc,0x90,0x94,0xfe,0x90,0xfc,0x94,0x94,0x94,0x6c,0x2c,0x44,0x14,0x8,
-+0x4,0x7f,0x45,0x44,0x44,0x7c,0x55,0x10,0x50,0x5d,0x50,0x53,0x5c,0xf0,0x40,0x3,0x1c,0xe0,0x24,0xa8,0x40,0x88,0xf0,0x20,0x44,0xfc,0x20,0xfe,0x20,0x50,0x8e,0x4,
-+0x8,0x7f,0x4a,0x4b,0x4a,0x7a,0x52,0x12,0x52,0x5a,0x52,0x52,0x5c,0xf5,0x48,0x0,0x4,0xfe,0x0,0xf4,0x4,0xe4,0xbe,0xa4,0xb4,0xec,0xc,0xa4,0xa4,0xf4,0x14,0x8,
-+0x10,0xff,0x94,0x96,0x95,0xf7,0xa4,0x26,0xa6,0xb7,0xa4,0xa4,0xa9,0xe9,0x92,0x24,0x4,0xfe,0x0,0x28,0x48,0xee,0x92,0xa4,0xa8,0xe8,0xa8,0x88,0x14,0x14,0x24,0x42,
-+0x0,0x7d,0x44,0x44,0x47,0x7c,0x50,0x11,0x50,0x5d,0x50,0x53,0x5c,0xf0,0x41,0x6,0x50,0x54,0xd8,0x50,0xfe,0x88,0x50,0xfc,0x20,0xfc,0x20,0xfe,0x20,0x50,0x8e,0x4,
-+0x4,0x7f,0x45,0x44,0x47,0x7c,0x54,0x13,0x51,0x5d,0x51,0x51,0x5d,0xf1,0x41,0x1,0x1c,0xe0,0x24,0xa8,0xfe,0x70,0xae,0x24,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x4,
-+0x14,0xfa,0x90,0x9f,0x90,0xff,0xa8,0x28,0xaf,0xb2,0xa7,0xaa,0xb2,0xe2,0x86,0x1,0x20,0x28,0x24,0xa0,0x7e,0xa8,0xa8,0xa8,0xa8,0x28,0x28,0xa8,0x4a,0x4a,0x86,0x0,
-+0x4,0x7f,0x45,0x45,0x45,0x7c,0x55,0x12,0x55,0x5d,0x51,0x50,0x5c,0xf3,0x40,0x0,0x4,0xfe,0x54,0x54,0xfc,0x84,0xfe,0x44,0xf4,0x54,0xf4,0x44,0x54,0xfc,0x14,0x8,
-+0x11,0xff,0x91,0x94,0x92,0xf5,0xa5,0x25,0xa5,0xbd,0xa5,0xa5,0xbd,0xe5,0x84,0x4,0x10,0xfe,0x10,0x4,0xfe,0x44,0xf4,0x44,0xf4,0x44,0xf4,0x44,0xfc,0x4,0x14,0x8,
-+0x10,0xff,0x94,0x95,0x95,0xf5,0xa5,0x25,0xa4,0xbd,0xa4,0xa7,0xbd,0xea,0x90,0x3,0x40,0xfe,0x0,0xfc,0x24,0xfc,0x24,0xfc,0x20,0xfc,0x20,0xfe,0x24,0xfa,0x20,0xfe,
-+0x9,0x7d,0x4a,0x49,0x4b,0x7a,0x52,0x12,0x53,0x5e,0x53,0x52,0x5f,0xf2,0x43,0x2,0x24,0x24,0x48,0x24,0xfe,0x94,0x64,0x94,0xfc,0x48,0x68,0x48,0x68,0x4a,0x6a,0x46,
-+0x1,0xf5,0x97,0x99,0x97,0xf3,0xa5,0x29,0xa3,0xba,0xa2,0xa2,0xba,0xe0,0x81,0x6,0x8,0x28,0xbc,0x48,0xbe,0x18,0xaa,0x4e,0xf8,0xc,0x48,0x48,0x48,0xb0,0xc,0x4,
-+0x10,0xff,0x90,0x95,0x94,0xf7,0xac,0x25,0xab,0xb1,0xa0,0xa3,0xb9,0xe0,0x83,0xc,0x40,0xfe,0x0,0xf4,0x4,0xf6,0xc,0xf4,0x1a,0xf2,0x0,0xf8,0x10,0xe0,0x10,0xe,
-+0x0,0x3f,0x2,0x11,0x8,0x7,0x78,0x0,0x1,0x6,0x38,0x1,0x6,0x38,0x1,0x0,0xe0,0x8,0xc,0x30,0xc0,0x0,0x80,0xc0,0x20,0x50,0x90,0x10,0x10,0x10,0x20,0xc0,
-+0x8,0x10,0x35,0xcc,0x28,0x10,0x30,0xc8,0x15,0x26,0xcc,0x14,0x24,0xc4,0x14,0x8,0x0,0x4,0xfe,0x44,0x44,0x44,0x94,0x88,0x4,0xfe,0x84,0x84,0x84,0x84,0xfc,0x84,
-+0x8,0x13,0x34,0xcc,0x28,0x11,0x31,0xc9,0x15,0x25,0xcd,0x15,0x25,0xc5,0x15,0x9,0x4,0xfe,0x40,0x40,0x84,0xfe,0x4,0x4,0x4,0xfc,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x8,0x10,0x34,0xcc,0x29,0x11,0x33,0xcd,0x15,0x25,0xcd,0x15,0x25,0xc5,0x15,0x9,0x10,0x90,0x90,0x90,0x14,0xfe,0x10,0x38,0x34,0x54,0x54,0x92,0x10,0x10,0x10,0x10,
-+0x8,0x10,0x37,0xcc,0x29,0x11,0x31,0xc9,0x15,0x24,0xcf,0x14,0x24,0xc4,0x15,0xa,0x88,0x88,0xfe,0x88,0xfc,0x4,0xfc,0x4,0xfc,0x20,0xfe,0x20,0x50,0x88,0x6,0x4,
-+0x8,0x10,0x35,0xcd,0x29,0x11,0x31,0xc9,0x15,0x24,0xcd,0x15,0x25,0xc5,0x15,0x9,0x20,0x44,0xfe,0x4,0x54,0x24,0x54,0x4,0xfc,0x10,0x12,0xd4,0x18,0x12,0xd2,0xe,
-+0x10,0x10,0x1e,0x24,0x28,0x7e,0xaa,0x2a,0x3e,0x2b,0x2a,0x3e,0x2a,0x4a,0x42,0x86,0x10,0x90,0x50,0x50,0x10,0x90,0x50,0x54,0x1e,0xf0,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x10,0x10,0x1e,0x24,0x28,0x7e,0xaa,0x2a,0x3e,0x2b,0x2a,0x3e,0x2a,0x4a,0x42,0x87,0x20,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0xfe,0x20,0x20,0x50,0x48,0x86,0x4,
-+0x10,0x10,0x1e,0x25,0x28,0x7e,0xaa,0x2a,0x3e,0x2a,0x2a,0x3e,0x2a,0x4b,0x42,0x86,0x80,0x84,0xfe,0x0,0xf8,0x20,0x44,0xfe,0x54,0x54,0x54,0x94,0xa4,0x24,0x54,0x8,
-+0x10,0x10,0x1f,0x24,0x28,0x7e,0xaa,0x2a,0x3e,0x2a,0x2a,0x3e,0x2a,0x4a,0x43,0x86,0x4,0xe,0xf0,0x88,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa4,0xac,0x7a,0x8,
-+0x8,0x8,0x2e,0x28,0x2e,0xf4,0x44,0xf,0x10,0x3f,0x51,0x1f,0x11,0x1f,0x21,0x41,0x80,0x84,0x98,0xe2,0x82,0x7e,0x0,0xe0,0x40,0xf0,0x10,0xf0,0x10,0xf0,0x10,0x30,
-+0x10,0x10,0x1d,0x24,0x28,0x7e,0xaa,0x2b,0x3e,0x2a,0x2a,0x3e,0x2a,0x4a,0x42,0x87,0x20,0x20,0x24,0xac,0xb0,0x20,0x24,0xfe,0x50,0x50,0x50,0x50,0x52,0x92,0x8e,0x0,
-+0x20,0x20,0x3d,0x48,0x50,0xfd,0x55,0x55,0x7d,0x55,0x54,0x7c,0x55,0x56,0x44,0x8c,0x20,0x24,0xfe,0x20,0x24,0xfe,0x24,0x24,0xfc,0x24,0x70,0xa8,0x26,0x24,0x20,0x20,
-+0x21,0x20,0x3c,0x49,0x51,0xfd,0x55,0x55,0x7d,0x55,0x54,0x7f,0x54,0x54,0x44,0x8c,0x4,0x88,0x50,0xfc,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0xfe,0x20,0x20,0x20,0x20,
-+0x8,0x2f,0x28,0x2f,0x7a,0x1,0xff,0x0,0x1f,0x0,0x1f,0x0,0x1f,0x10,0x1f,0x10,0x40,0x58,0x60,0x44,0x7c,0x0,0xfe,0x0,0xf0,0x0,0xf0,0x0,0xf0,0x10,0xf0,0x10,
-+0x8,0xff,0x8,0x3e,0x2b,0x3e,0x22,0x41,0xff,0x0,0x1e,0x0,0x0,0x1f,0x10,0x1f,0x78,0x48,0x48,0x86,0x78,0x48,0x30,0x4c,0xfe,0x0,0x0,0xf0,0x0,0xf0,0x10,0xf0,
-+0x10,0x14,0xfe,0x10,0x7c,0x10,0xfe,0x0,0x7c,0x44,0x7c,0x44,0x7c,0x44,0x55,0x4a,0x0,0x8,0xfc,0x88,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0x50,0x52,0x92,0xe,0x0,
-+0x1f,0x1,0x7f,0x51,0x8d,0x11,0x1,0x3f,0x0,0xff,0x8,0xf,0x0,0x0,0x0,0x0,0xf0,0x0,0xfe,0x12,0x64,0x10,0x0,0xf8,0x0,0xfe,0x0,0xf0,0x10,0x10,0xa0,0x40,
-+0x1f,0x1,0x7f,0x51,0x8d,0x11,0x3f,0x21,0x21,0x2f,0x21,0x21,0x21,0x42,0x4c,0x90,0xf0,0x0,0xfe,0x12,0x64,0x10,0xfc,0x0,0x8,0xfc,0x8,0x8,0x8,0x8,0x50,0x20,
-+0x1f,0x1,0x7f,0x51,0x8d,0x11,0x2,0x1,0xff,0x8,0x4,0x2,0x1,0x6,0x18,0x60,0xf0,0x0,0xfe,0x12,0x64,0x10,0x0,0x4,0xfe,0x20,0x40,0x80,0x0,0xc0,0x3c,0x8,
-+0x1f,0x1,0x7f,0x51,0x8d,0x11,0x78,0xb,0x10,0x78,0xf,0x28,0x10,0x2b,0x44,0x83,0xf0,0x0,0xfe,0x12,0x64,0x10,0x38,0xc0,0x40,0x48,0xfc,0x40,0x50,0xf8,0x46,0xfc,
-+0x1f,0x1,0x7f,0x51,0x8d,0x12,0x1,0x7f,0x8,0x4,0x3,0x1c,0xe8,0x8,0x10,0x20,0xf0,0x0,0xfe,0x12,0x64,0x10,0x0,0xfc,0x20,0x40,0x80,0x70,0x2e,0x20,0x20,0x20,
-+0x1f,0x1,0x7f,0x51,0x8d,0x11,0x41,0x20,0x8f,0x60,0x2b,0x12,0x62,0x22,0x22,0x20,0xf0,0x0,0xfe,0x12,0x64,0x10,0x40,0x44,0xfe,0x40,0xf8,0x48,0x48,0x48,0x58,0x40,
-+0x1f,0x1,0x7f,0x51,0x8d,0x11,0x2,0x7e,0x2,0x2,0x3e,0x2,0x2,0x7e,0x2,0x2,0xf0,0x0,0xfe,0x12,0x64,0x10,0x88,0xfc,0x80,0x90,0xf8,0x80,0x88,0xfc,0x80,0x80,
-+0x1f,0x1,0x7f,0x51,0x8d,0x12,0x1,0x1f,0x4,0xff,0x1,0x7f,0x4,0xc,0x3,0x1c,0xf0,0x0,0xfe,0x12,0x64,0x10,0x0,0xf0,0x44,0xfe,0x0,0xfc,0x40,0x40,0x80,0x70,
-+0x1f,0x1,0x7f,0x51,0x8d,0x11,0x20,0x17,0x42,0x21,0xb,0x10,0x6f,0x20,0x20,0x27,0xf0,0x0,0xfe,0x12,0x64,0x10,0x38,0xc0,0x48,0x50,0xf8,0x40,0xfe,0x40,0x48,0xfc,
-+0x1f,0x1,0x7f,0x51,0x8d,0x11,0x23,0x12,0x2,0xf3,0x11,0x13,0x1c,0x12,0x1b,0x10,0xf0,0x0,0xfe,0x12,0x64,0x10,0xf8,0x88,0x48,0xf8,0x0,0xfc,0x44,0xa4,0xf4,0x8,
-+0x1f,0x1,0x7f,0x51,0x8d,0x12,0x3f,0x12,0xff,0x21,0x3f,0x21,0x3f,0x21,0x25,0x22,0xf0,0x0,0xfe,0x12,0x64,0x10,0x20,0x24,0xfe,0x4,0x44,0x28,0x10,0x28,0x46,0x84,
-+0x1f,0x1,0x7f,0x51,0x8d,0x10,0x2b,0xe5,0x19,0x69,0x95,0x64,0x5,0x64,0x17,0x8,0xf0,0x0,0xfe,0x12,0x64,0x10,0xfc,0x24,0xfc,0x24,0xfc,0x20,0xfc,0x20,0xfe,0x0,
-+0x8,0x8,0x2a,0x2f,0x28,0x29,0xff,0x0,0x49,0x49,0x49,0x55,0x63,0x41,0x7f,0x1,0x40,0x40,0x40,0x40,0x40,0x44,0xcc,0x50,0x60,0x40,0x40,0x40,0x42,0x42,0x3e,0x0,
-+0x8,0x8,0x2a,0x2f,0x28,0x29,0xff,0x0,0x49,0x49,0x49,0x55,0x63,0x41,0x7f,0x1,0x0,0x4,0x7e,0x44,0x44,0x44,0xfc,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0xfe,0x0,
-+0x10,0x10,0x50,0x5d,0x52,0x50,0xff,0x1,0x55,0x55,0x55,0x6d,0x45,0x45,0x7c,0x4,0x80,0x80,0x84,0xfe,0x4,0x24,0xf4,0x24,0x24,0xe4,0x14,0x8,0x2,0x2,0xfe,0x0,
-+0x10,0x11,0x50,0x5c,0x50,0x54,0xfe,0x1,0x54,0x54,0x54,0x6c,0x44,0x44,0x7c,0x4,0x4,0xfe,0x44,0x44,0x44,0x44,0x94,0x8,0x0,0xfc,0x84,0x84,0x84,0x84,0xfc,0x84,
-+0x10,0x10,0x50,0x5d,0x51,0x55,0xff,0x1,0x55,0x55,0x55,0x6d,0x45,0x45,0x7f,0x4,0x50,0x50,0x50,0x50,0x52,0x74,0x58,0x50,0x50,0x50,0x50,0x50,0x50,0x72,0x92,0xe,
-+0x10,0x11,0x51,0x5d,0x51,0x55,0xff,0x1,0x55,0x55,0x55,0x6d,0x45,0x45,0x7d,0x5,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x44,0x48,0x30,0x20,0x10,0x4e,0x84,0x0,
-+0x10,0x11,0x50,0x5c,0x51,0x54,0xfe,0x0,0x57,0x54,0x54,0x6c,0x44,0x44,0x7c,0x4,0x8,0xfc,0x20,0x28,0xfc,0x48,0x48,0x48,0xfe,0x4,0xfe,0x84,0x84,0x84,0xfc,0x84,
-+0x10,0x10,0x50,0x5c,0x50,0x54,0xfe,0x0,0x54,0x54,0x54,0x6c,0x44,0x45,0x7e,0x4,0x8,0xfc,0x88,0x88,0x88,0x88,0xf8,0xa0,0x28,0xbc,0xa0,0xa0,0xa0,0x66,0x3c,0x0,
-+0x10,0x11,0x51,0x5d,0x51,0x55,0xff,0x1,0x55,0x55,0x55,0x6d,0x45,0x45,0x7e,0x4,0x4,0xfe,0x4,0x4,0xfc,0x0,0xfe,0x20,0x48,0xfc,0x10,0x7c,0x10,0x14,0xfe,0x0,
-+0x0,0x1f,0x10,0x1f,0x1,0x3f,0x21,0x21,0x3f,0x21,0x21,0x3f,0x21,0x1,0x1,0x0,0x10,0xf8,0x10,0xf0,0x8,0xfc,0x8,0x8,0xf8,0x8,0x8,0xf8,0x8,0x2,0x2,0xfe,
-+0x1f,0x0,0xff,0x4,0x78,0x1f,0x10,0x1f,0x1,0x3f,0x21,0x3f,0x21,0x3f,0x1,0x0,0xf0,0x4,0xfe,0x40,0x3c,0xf0,0x10,0xf0,0x8,0xfc,0x8,0xf8,0x8,0xfa,0x2,0xfe,
-+0x3e,0x22,0x3e,0x1f,0x11,0x1f,0x11,0xff,0x1,0x1f,0x11,0x1f,0x11,0x1f,0x1,0x0,0xf8,0x88,0xf8,0xf0,0x10,0xf0,0x14,0xfe,0x0,0xf0,0x10,0xf0,0x10,0xf4,0x4,0xfc,
-+0x9,0x8,0x8,0x1f,0x10,0x30,0x3f,0x50,0x90,0x1f,0x10,0x10,0x10,0x1f,0x10,0x10,0x0,0x80,0x88,0xfc,0x80,0x90,0xf8,0x80,0x90,0xf8,0x80,0x80,0x84,0xfe,0x0,0x0,
-+0x9,0x8,0xf,0x10,0x3f,0x50,0x1f,0x10,0x1f,0x10,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x88,0xfc,0x80,0xf8,0x80,0xf8,0x80,0xfc,0x80,0x84,0xfe,0x80,0x80,0x80,0x80,
-+0x9,0x8,0x1f,0x10,0x3f,0x50,0x9f,0x10,0x1f,0x10,0x7f,0x4,0x4,0x8,0x10,0x60,0x0,0x88,0xfc,0x80,0xf8,0x80,0xf8,0x80,0xfc,0x0,0xe0,0x28,0x7c,0x8,0x28,0x10,
-+0x0,0x8,0x7d,0x49,0x4b,0x7d,0x49,0x49,0x79,0x49,0x49,0x4d,0xf1,0x41,0x1,0x1,0xc0,0xa0,0x24,0xfe,0x20,0x28,0xfc,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,0x0,
-+0x10,0x10,0x1e,0x22,0x65,0x99,0xa,0x14,0x22,0x7f,0xa2,0x22,0x22,0x3e,0x22,0x0,0x60,0x50,0x84,0xfe,0x90,0x90,0xfc,0x90,0x90,0xfc,0x90,0x90,0x94,0xfe,0x80,0x80,
-+0x3e,0x22,0x2a,0x2a,0x22,0x3e,0x9,0x10,0x3f,0x50,0x9f,0x10,0x1f,0x10,0x1f,0x10,0xf8,0x88,0xa8,0xa8,0x88,0xf8,0x0,0x88,0xfc,0x80,0xf8,0x80,0xf8,0x80,0xfc,0x0,
-+0x20,0x32,0x21,0x3d,0x50,0xd7,0x79,0x51,0x51,0x7d,0x51,0x51,0x51,0x7d,0x40,0x40,0x10,0x18,0x10,0x3e,0x68,0x28,0x3e,0x28,0x28,0x3e,0x28,0x68,0xa8,0x3e,0x20,0x20,
-+0x4,0x7e,0x10,0x10,0x1e,0x71,0x2,0xc,0x37,0xc1,0x1f,0x1,0x9,0x5,0x7f,0x0,0x8,0xfc,0x88,0xc8,0xaa,0xe,0x80,0x60,0xde,0x4,0xf0,0x0,0x20,0x48,0xfc,0x0,
-+0x2,0x1,0x7f,0x4,0x14,0x25,0x42,0xc,0x37,0xc1,0x1f,0x1,0x9,0x5,0x7f,0x0,0x0,0x8,0xfc,0x40,0x50,0x4c,0x84,0x30,0xee,0x4,0xf0,0x0,0x20,0x48,0xfc,0x0,
-+0x20,0x13,0x40,0x27,0x8,0x73,0x22,0x2c,0x37,0xc1,0x1f,0x1,0x9,0x5,0x7f,0x0,0x38,0xc0,0x48,0xfc,0xa0,0x18,0x88,0x60,0xde,0x4,0xf0,0x0,0x20,0x48,0xfc,0x0,
-+0x8,0x7e,0x10,0x28,0x7e,0x8,0x7d,0xa,0xc,0x37,0xc1,0x1f,0x9,0x5,0x7f,0x0,0xc,0xf0,0x80,0x88,0xfc,0x90,0x10,0x90,0x60,0xde,0x4,0xf0,0x20,0x48,0xfc,0x0,
-+0x0,0x7e,0x14,0x8,0xfe,0x1a,0x29,0x4a,0xc,0x37,0xc1,0x1f,0x9,0x5,0x7f,0x0,0x40,0x44,0x7e,0xc8,0x48,0x30,0x48,0x86,0x60,0xde,0x4,0xf0,0x20,0x48,0xfc,0x0,
-+0x8,0x7f,0x8,0x3e,0x9,0xfe,0x11,0x1e,0x24,0xdf,0x31,0xdf,0x9,0x5,0x7f,0x0,0x40,0x44,0x7e,0xc8,0x48,0x30,0x48,0x86,0x40,0xf0,0xe,0xf4,0x20,0x48,0xfc,0x0,
-+0x20,0x17,0x40,0x23,0x9,0x71,0x23,0x22,0xc,0x37,0xc1,0x1f,0x9,0x5,0x7f,0x0,0x40,0xfe,0x90,0xf8,0x50,0x50,0x52,0x8e,0x60,0xde,0x4,0xf0,0x20,0x48,0xfc,0x0,
-+0x3f,0x21,0x3f,0x20,0x3f,0x51,0x9f,0x2,0xc,0x37,0xc1,0x1f,0x9,0x5,0x7f,0x0,0x10,0x7c,0x28,0xfe,0x10,0x7c,0x10,0x90,0x60,0xde,0x4,0xf0,0x20,0x48,0xfc,0x0,
-+0x1,0x6,0x18,0xef,0x1,0x1f,0x5,0x3f,0x10,0x28,0x7c,0x93,0x7c,0x10,0x54,0xfe,0x0,0xc0,0x30,0xee,0x0,0xf0,0x40,0xf8,0x10,0x28,0x7c,0x92,0x7c,0x10,0x54,0xfe,
-+0x20,0x20,0x3c,0x48,0x90,0x7f,0x54,0x54,0x7c,0x54,0x54,0x7c,0x0,0x1d,0xe2,0x44,0x40,0x60,0x50,0x50,0x44,0xfe,0x40,0x50,0x50,0x50,0x50,0x90,0x90,0x12,0x12,0xe,
-+0x20,0x20,0x3c,0x48,0x93,0x7c,0x54,0x54,0x7c,0x54,0x54,0x7c,0x0,0x1d,0xe1,0x42,0x40,0x20,0x20,0x4,0xfe,0x80,0x88,0xfc,0x88,0x88,0x88,0x88,0x88,0x8,0x28,0x10,
-+0x20,0x20,0x3c,0x48,0x93,0x7c,0x54,0x54,0x7c,0x54,0x55,0x7d,0x1,0x1e,0xe2,0x45,0x40,0x60,0x50,0x44,0xfe,0x80,0x80,0xfc,0x84,0xc4,0x48,0x28,0x10,0x28,0x46,0x84,
-+0x20,0x20,0x3d,0x48,0x91,0x7c,0x54,0x54,0x7c,0x57,0x54,0x7c,0x0,0x1c,0xe0,0x40,0x0,0x8,0xfc,0x20,0x24,0xa8,0xa8,0x20,0x24,0xfe,0x20,0x20,0x20,0x20,0x20,0x20,
-+0x20,0x20,0x3c,0x48,0x90,0x7c,0x54,0x54,0x7d,0x55,0x55,0x7d,0x1,0x1d,0xe1,0x41,0x40,0x40,0x48,0x7c,0x40,0x40,0x40,0x48,0xfc,0x8,0x8,0x8,0x8,0x8,0xf8,0x8,
-+0x20,0x20,0x3c,0x48,0x90,0x7d,0x55,0x55,0x7d,0x55,0x55,0x7d,0x1,0x1d,0xe2,0x44,0x40,0x44,0x7e,0x40,0x44,0xfe,0x4,0x4,0x4,0xfc,0x4,0x0,0x0,0x0,0x0,0x0,
-+0x20,0x20,0x3d,0x48,0x90,0x7c,0x57,0x54,0x7c,0x54,0x54,0x7d,0x2,0x1c,0xe0,0x40,0x8,0x1c,0xe0,0x20,0x20,0x24,0xfe,0x20,0x70,0x68,0xa8,0x26,0x24,0x20,0x20,0x20,
-+0x20,0x20,0x3c,0x48,0x90,0x7d,0x56,0x54,0x7c,0x54,0x54,0x7c,0x0,0x1c,0xe0,0x40,0x48,0x48,0x48,0x88,0x88,0xfe,0x88,0x88,0xc8,0xa8,0xa8,0x88,0x88,0x88,0xa8,0x90,
-+0x11,0x9,0x49,0x7f,0x44,0x84,0xf,0x10,0x3f,0x51,0x1f,0x11,0x1f,0x0,0xff,0x0,0x10,0x20,0x40,0xfe,0x2,0x4,0xc0,0x90,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,0x0,
-+0x20,0x20,0x3c,0x48,0x91,0x7f,0x54,0x54,0x7d,0x55,0x55,0x7d,0x1,0x1d,0xe1,0x41,0x20,0x20,0x40,0x88,0x4,0xfe,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x20,0x20,0x3d,0x48,0x90,0x7c,0x57,0x54,0x7c,0x54,0x55,0x7c,0x0,0x1c,0xe3,0x40,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x20,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x20,0x20,0x3c,0x4b,0x90,0x7c,0x55,0x54,0x7c,0x55,0x55,0x7d,0x1,0x1d,0xe1,0x41,0x20,0x20,0x24,0xfe,0x20,0x28,0xfc,0x0,0x4,0xfe,0x4,0x4,0x4,0x4,0xfc,0x4,
-+0x20,0x20,0x3c,0x4b,0x90,0x7c,0x55,0x56,0x7c,0x54,0x54,0x7c,0x0,0x1c,0xe0,0x40,0x40,0x40,0x44,0xfe,0x80,0x88,0xfc,0x88,0x88,0xf8,0x88,0x88,0xf8,0x88,0xa8,0x90,
-+0x20,0x23,0x3c,0x48,0x90,0x7d,0x55,0x55,0x7d,0x55,0x55,0x7d,0x1,0x1d,0xe1,0x40,0x4,0xfe,0x20,0x20,0x44,0xfe,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x4,0x14,0x8,
-+0x20,0x20,0x3c,0x4b,0x90,0x7c,0x54,0x54,0x7c,0x57,0x54,0x7c,0x0,0x1c,0xe1,0x42,0x40,0x20,0x4,0xfe,0x88,0x50,0x20,0x50,0x8e,0x4,0x88,0x88,0x88,0x88,0x8,0x8,
-+0x20,0x20,0x3c,0x4b,0x90,0x7c,0x55,0x56,0x7c,0x54,0x54,0x7c,0x0,0x1c,0xe1,0x46,0x40,0x20,0x4,0xfe,0x0,0x88,0x6,0x8a,0x88,0x50,0x50,0x20,0x50,0x88,0x6,0x4,
-+0x9,0x5,0x3f,0x2,0xff,0x4,0xa,0x37,0xc8,0x1f,0x31,0x1f,0x11,0x1f,0x0,0x7f,0x20,0x40,0xf8,0x0,0xfe,0x40,0x30,0xce,0x84,0xf0,0x10,0xf0,0x10,0xf0,0x0,0xfc,
-+0x20,0x21,0x3c,0x48,0x91,0x7c,0x54,0x55,0x7c,0x54,0x57,0x7c,0x0,0x1c,0xe0,0x40,0x4,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x8,0x8,0xfe,0x88,0x48,0x8,0x28,0x10,
-+0x20,0x23,0x3c,0x48,0x91,0x7d,0x55,0x55,0x7d,0x55,0x55,0x7c,0x0,0x1c,0xe0,0x43,0x4,0xfe,0x20,0x24,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0xa0,0xa0,0x40,0xb0,0xe,
-+0x20,0x23,0x3c,0x48,0x91,0x7d,0x55,0x55,0x7d,0x55,0x55,0x7d,0x1,0x1d,0xe1,0x41,0x4,0xfe,0x0,0x4,0xde,0x54,0x54,0x54,0x54,0xdc,0x54,0x54,0x54,0x54,0x54,0x54,
-+0x20,0x20,0x3c,0x4a,0x91,0x7d,0x54,0x57,0x7d,0x55,0x55,0x7d,0x1,0x1d,0xe2,0x44,0x20,0x20,0x24,0xfe,0x20,0x20,0x50,0x50,0xfc,0x10,0x14,0xfe,0x10,0x10,0x96,0x7c,
-+0x20,0x20,0x3d,0x49,0x91,0x7d,0x55,0x55,0x7c,0x54,0x55,0x7c,0x0,0x1c,0xe3,0x40,0x40,0x40,0x7e,0x62,0x54,0x48,0x54,0x62,0x20,0x28,0xfc,0x20,0x20,0x24,0xfe,0x0,
-+0x20,0x20,0x3d,0x49,0x91,0x7d,0x55,0x55,0x7d,0x55,0x55,0x7d,0x1,0x1d,0xe0,0x40,0x4,0x44,0xe4,0x44,0x44,0x7e,0x44,0xc4,0x64,0x54,0x54,0x44,0xc4,0x44,0x14,0x8,
-+0x20,0x20,0x3c,0x48,0x91,0x7c,0x54,0x54,0x7f,0x54,0x55,0x7c,0x0,0x1d,0xe2,0x40,0x40,0x40,0x7c,0x88,0x50,0x20,0x50,0x8e,0x24,0x20,0xfc,0x20,0xa8,0x26,0xa2,0x40,
-+0x20,0x21,0x3c,0x48,0x90,0x7d,0x54,0x54,0x7c,0x55,0x54,0x7c,0x1,0x1e,0xe0,0x40,0x1c,0xe0,0x40,0x40,0x88,0xf0,0x20,0x40,0x88,0xfc,0x20,0xa8,0x26,0x22,0xa0,0x40,
-+0x20,0x10,0x40,0x25,0x8,0x77,0x22,0x27,0x8,0x1f,0x31,0x5f,0x11,0x1f,0x0,0xff,0x20,0xa8,0xa6,0x3a,0x60,0x80,0x0,0xc0,0x90,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfe,
-+0x20,0x20,0x3c,0x4b,0x92,0x7c,0x54,0x54,0x7c,0x57,0x54,0x7c,0x0,0x1c,0xe1,0x46,0x40,0x20,0x20,0xfe,0x2,0x14,0xf8,0x0,0x4,0xfe,0x90,0x90,0x90,0x92,0x12,0xe,
-+0x20,0x20,0x3d,0x49,0x91,0x7d,0x55,0x55,0x7d,0x55,0x55,0x7d,0x1,0x1d,0xe0,0x40,0x0,0x4,0xde,0x54,0x54,0xd4,0x54,0x54,0xd4,0x14,0x94,0x54,0x5c,0x90,0x10,0x10,
-+0x20,0x20,0x3d,0x48,0x90,0x7c,0x57,0x54,0x7d,0x55,0x55,0x7d,0x1,0x1d,0xe1,0x41,0x20,0x28,0xfc,0x20,0xf8,0x20,0xfe,0x0,0xfc,0x4,0xfc,0x4,0xfc,0x4,0x14,0x8,
-+0x20,0x20,0x3d,0x48,0x90,0x7f,0x54,0x55,0x7e,0x54,0x55,0x7e,0x0,0x1c,0xe0,0x43,0x20,0x28,0xfc,0x20,0x24,0xfe,0x88,0x46,0x7a,0x88,0x48,0x50,0x20,0x50,0x8e,0x4,
-+0x20,0x23,0x3d,0x49,0x91,0x7d,0x55,0x55,0x7d,0x55,0x55,0x7d,0x1,0x1f,0xe0,0x40,0x20,0xf0,0x44,0x7e,0x44,0xd4,0x54,0x54,0x54,0xd4,0x54,0x68,0xc8,0x54,0x52,0x60,
-+0x20,0x20,0x3c,0x4b,0x90,0x7c,0x54,0x55,0x7c,0x54,0x54,0x7f,0x0,0x1c,0xe0,0x40,0x50,0x50,0x54,0xde,0x50,0x50,0x50,0xdc,0x50,0x50,0x54,0xde,0x50,0x50,0x50,0x50,
-+0x20,0x21,0x3d,0x49,0x91,0x7d,0x55,0x55,0x7c,0x55,0x55,0x7d,0x1,0x1d,0xe1,0x41,0x4,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x10,0x12,0xd6,0x18,0x10,0x52,0x92,0xe,
-+0x20,0x20,0x3c,0x48,0x90,0x7c,0x54,0x54,0x7d,0x55,0x55,0x7d,0x1,0x1d,0xe1,0x41,0x8,0xfc,0x88,0xf8,0x88,0x88,0xf8,0x4,0xfe,0x4,0x4,0xfc,0x4,0x4,0xfc,0x4,
-+0x20,0x21,0x3d,0x49,0x91,0x7d,0x55,0x55,0x7d,0x55,0x55,0x7d,0x1,0x1d,0xe1,0x41,0x4,0xfe,0x4,0x24,0x24,0xfc,0x24,0x24,0x74,0x54,0x54,0x74,0x4,0x4,0xfc,0x4,
-+0x20,0x20,0x3d,0x49,0x91,0x7d,0x55,0x55,0x7d,0x55,0x54,0x7c,0x0,0x1c,0xe1,0x46,0x0,0x44,0x8e,0x4,0x4,0xdc,0x4,0x4,0xfc,0x54,0x50,0x50,0x90,0x92,0x12,0xe,
-+0x20,0x20,0x3c,0x48,0x91,0x7e,0x54,0x55,0x7c,0x54,0x54,0x7c,0x1,0x1e,0xe2,0x40,0x20,0x20,0x50,0x88,0x46,0x24,0x20,0xf8,0x8,0x10,0x40,0xa0,0xa4,0x8a,0x8a,0x78,
-+0x20,0x21,0x3d,0x49,0x91,0x7d,0x55,0x55,0x7d,0x55,0x55,0x7d,0x1,0x1d,0xe2,0x44,0x4,0xfe,0x24,0x24,0x74,0x24,0x24,0xfc,0x4,0x74,0x54,0x54,0x74,0x4,0x14,0x8,
-+0x20,0x23,0x3c,0x48,0x91,0x7c,0x55,0x55,0x7d,0x55,0x55,0x7c,0x0,0x1c,0xe1,0x40,0x4,0xfe,0x4,0x74,0xc4,0x44,0xf4,0x54,0x54,0x54,0xf4,0x44,0x54,0x76,0xca,0x0,
-+0x20,0x20,0x3c,0x49,0x92,0x7d,0x54,0x54,0x7d,0x55,0x55,0x7d,0x1,0x1d,0xe1,0x41,0x0,0x92,0x92,0x24,0x48,0x24,0x92,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x4,
-+0x20,0x21,0x3c,0x48,0x93,0x7c,0x54,0x55,0x7d,0x55,0x55,0x7d,0x1,0x1c,0xe0,0x43,0x20,0xfc,0x20,0x88,0xfe,0x88,0x4,0xfe,0x4,0x24,0x24,0x24,0x24,0x58,0x86,0x2,
-+0x20,0x21,0x3d,0x4b,0x91,0x7d,0x55,0x55,0x7d,0x54,0x57,0x7c,0x0,0x1d,0xe2,0x40,0x48,0x48,0x48,0xfe,0x48,0x48,0x78,0x0,0xfc,0x20,0xfe,0x70,0xa8,0x26,0x24,0x20,
-+0x20,0x21,0x3d,0x49,0x91,0x7d,0x54,0x55,0x7c,0x57,0x54,0x7c,0x0,0x1c,0xe0,0x40,0x4,0xde,0x54,0x54,0x54,0xdc,0x0,0xfc,0x0,0xfe,0x80,0xfc,0x4,0x4,0x28,0x10,
-+0x20,0x20,0x3b,0x48,0x90,0x7f,0x54,0x55,0x7d,0x55,0x56,0x7c,0x0,0x1c,0xe0,0x40,0x8,0x68,0x88,0x88,0x8a,0xea,0x9c,0x88,0xc8,0xa8,0x88,0x88,0x94,0x94,0xa2,0xc0,
-+0x20,0x20,0x3c,0x49,0x93,0x7d,0x55,0x55,0x7d,0x54,0x54,0x7d,0x2,0x1c,0xe0,0x43,0x80,0x84,0xfe,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x80,0xf8,0x88,0x50,0x20,0xd0,0xe,
-+0x20,0x20,0x3d,0x49,0x91,0x7d,0x55,0x54,0x7d,0x54,0x54,0x7d,0x0,0x1c,0xe3,0x40,0x20,0x44,0xfe,0x4,0xfc,0x4,0xfc,0x0,0xfc,0x20,0x28,0xfc,0x20,0x24,0xfe,0x0,
-+0x20,0x20,0x3d,0x49,0x91,0x7d,0x55,0x55,0x7d,0x55,0x57,0x7d,0x1,0x1d,0xe1,0x41,0x40,0x24,0xfe,0x4,0x4,0xfc,0x0,0x4,0xfe,0x54,0x54,0xfc,0x54,0x54,0x54,0xc,
-+0x20,0x21,0x3d,0x48,0x90,0x7c,0x55,0x56,0x7d,0x55,0x55,0x7d,0x0,0x1c,0xe3,0x40,0x0,0xfc,0x24,0x88,0x70,0x88,0x26,0x24,0xfe,0x24,0x24,0xfc,0x20,0x24,0xfc,0x2,
-+0x8,0x7f,0x8,0xfe,0x11,0x1e,0x22,0x4f,0x88,0x1f,0x31,0x5f,0x11,0x1f,0x0,0xff,0x40,0x44,0x7e,0xc8,0x48,0x30,0x48,0xc6,0x90,0xf8,0x10,0xf0,0x10,0xf0,0x4,0xfc,
-+0x20,0x20,0x3d,0x48,0x93,0x7c,0x54,0x55,0x7e,0x54,0x55,0x7d,0x1,0x1d,0xe1,0x41,0x40,0x48,0xf8,0x50,0xfe,0x40,0xf0,0x84,0xfc,0x0,0xf8,0x8,0xf8,0x8,0xf8,0x8,
-+0x20,0x21,0x3d,0x49,0x91,0x7d,0x54,0x57,0x7c,0x56,0x55,0x7d,0x2,0x1c,0xe1,0x40,0x4,0xfe,0x4,0xfc,0x4,0xfc,0x0,0xde,0x42,0x52,0xce,0x4a,0x52,0x42,0x4a,0x84,
-+0x20,0x21,0x3d,0x49,0x91,0x7d,0x54,0x54,0x7c,0x55,0x54,0x7c,0x0,0x1d,0xe2,0x40,0x4,0xfe,0x54,0x54,0x54,0xfc,0x20,0xa8,0xa8,0x24,0x20,0xa8,0xa4,0x22,0x22,0x20,
-+0x20,0x20,0x3d,0x48,0x91,0x7c,0x54,0x54,0x7d,0x54,0x57,0x7c,0x1,0x1d,0xe1,0x41,0x8,0x1c,0xe0,0x4,0x24,0xa8,0x80,0xfc,0x20,0x24,0xfe,0x20,0x24,0x24,0xfc,0x4,
-+0x21,0x21,0x7f,0x91,0x21,0xf8,0xab,0xaa,0xfa,0xaa,0xab,0xf8,0x7,0x18,0xe0,0x40,0x48,0x48,0xf8,0x48,0xc8,0x9e,0xea,0xaa,0xaa,0xaa,0xea,0x8a,0xea,0x8a,0x92,0xa6,
-+0x20,0x23,0x3c,0x48,0x91,0x7d,0x55,0x55,0x7c,0x55,0x54,0x7f,0x0,0x1d,0xe2,0x40,0x4,0xfe,0x50,0x54,0xfe,0x54,0x54,0xfc,0x0,0xfc,0x0,0xfe,0xa8,0x26,0x22,0x60,
-+0x20,0x21,0x3c,0x4b,0x92,0x7d,0x54,0x55,0x7c,0x54,0x55,0x7c,0x0,0x1c,0xe1,0x40,0x8,0xfc,0x20,0xfe,0x22,0xac,0x20,0xac,0x20,0x4,0xfe,0x4,0xfc,0x4,0xfc,0x4,
-+0x20,0x20,0x3c,0x48,0x90,0x7c,0x55,0x55,0x7d,0x55,0x54,0x7c,0x0,0x1c,0xe0,0x43,0xfc,0x84,0xfc,0x84,0xfc,0x0,0xfe,0x4a,0x4a,0xfe,0x0,0xfc,0x48,0x30,0xc8,0x6,
-+0x20,0x3f,0x40,0xbf,0x29,0xff,0x25,0x3f,0x8,0x1f,0x31,0x5f,0x11,0x1f,0x0,0xff,0x40,0x44,0xfe,0x4,0x44,0xa8,0x10,0xe8,0x86,0xf0,0x10,0xf0,0x10,0xf0,0x4,0xfe,
-+0x20,0x23,0x7a,0x93,0x22,0xfb,0xaa,0xab,0xfa,0xab,0xab,0xfb,0x5,0x1d,0xe5,0x49,0x20,0xfe,0x20,0xfc,0x24,0xfe,0x24,0xfc,0x20,0xfc,0x24,0xfc,0x24,0xfc,0x24,0x2c,
-+0x20,0x23,0x7a,0x92,0x22,0xfa,0xab,0xaa,0xfb,0xab,0xab,0xfb,0x2,0x1c,0xe4,0x49,0x4,0xfe,0x8,0xa8,0xae,0x12,0xf4,0x44,0x54,0x54,0x54,0xf4,0x54,0x4a,0x8a,0x10,
-+0x21,0x20,0x3f,0x48,0x91,0x7c,0x57,0x55,0x7c,0x57,0x54,0x7d,0x1,0x1d,0xe1,0x41,0x4,0x88,0xfe,0x20,0xfc,0x20,0xfe,0x24,0xa8,0xfe,0x4,0xfe,0x4,0x4,0xfc,0x4,
-+0x21,0x20,0x3f,0x48,0x91,0x7d,0x55,0x55,0x7d,0x55,0x55,0x7c,0x3,0x1c,0xe0,0x40,0x4,0x88,0xfe,0x50,0xfc,0x54,0x54,0x8c,0x74,0x4,0xfc,0x8,0xfe,0x88,0x48,0x18,
-+0x20,0x21,0x3d,0x49,0x91,0x7d,0x54,0x57,0x7c,0x55,0x55,0x7d,0x0,0x1c,0xe3,0x40,0x50,0xfc,0x54,0xfc,0x54,0xfc,0x0,0xfe,0x0,0xfc,0x4,0xfc,0x88,0x50,0xfe,0x0,
-+0x28,0x28,0xfc,0x28,0x38,0x10,0x7c,0x54,0x54,0x7c,0x10,0xfe,0x10,0x10,0x13,0x10,0x4,0xfe,0x84,0x84,0x84,0x84,0xfc,0x84,0x84,0x84,0x84,0xfc,0x0,0x4,0xfe,0x0,
-+0x28,0x28,0xfe,0x29,0x39,0x11,0x7d,0x55,0x55,0x7f,0x10,0xfe,0x10,0x10,0x11,0x12,0x20,0x20,0x24,0xfe,0x24,0x24,0x24,0x24,0x24,0xfe,0x20,0x50,0x50,0x88,0x6,0x4,
-+0x28,0x28,0xfe,0x29,0x39,0x10,0x7f,0x55,0x55,0x7d,0x11,0xfd,0x11,0x12,0x14,0x10,0x10,0x10,0x10,0x10,0x7c,0x10,0x10,0x10,0x28,0x28,0x24,0x44,0x0,0x86,0x7c,0x0,
-+0x28,0x29,0xfe,0x28,0x3b,0x10,0x7c,0x55,0x56,0x7c,0x10,0xfe,0x10,0x10,0x11,0x12,0x1c,0xe0,0x20,0x24,0xfe,0x50,0x88,0x6,0x88,0x88,0x88,0x88,0x88,0x88,0x8,0x8,
-+0x28,0x28,0xfe,0x28,0x39,0x13,0x7d,0x55,0x55,0x7d,0x10,0xfe,0x10,0x10,0x11,0x12,0x40,0x40,0x78,0x90,0x24,0xfe,0x24,0x24,0x24,0xfc,0x50,0x50,0x90,0x92,0x12,0xe,
-+0x28,0x28,0xff,0x28,0x38,0x13,0x7c,0x54,0x55,0x7f,0x11,0xff,0x11,0x11,0x11,0x11,0x90,0x90,0xfc,0x90,0x44,0xfe,0x80,0xfc,0x8,0x10,0xfe,0x10,0x10,0x10,0x50,0x20,
-+0x28,0x28,0xfe,0x29,0x3a,0x13,0x7c,0x55,0x54,0x7d,0x10,0xff,0x11,0x11,0x11,0x10,0x80,0x84,0xfe,0x4,0x44,0xfc,0x4,0xf4,0x4,0xf4,0x4,0xf4,0x14,0x14,0xf4,0x8,
-+0x28,0x29,0xfe,0x28,0x3b,0x10,0x7c,0x55,0x56,0x7c,0x13,0xfc,0x10,0x11,0x12,0x10,0x0,0xfc,0x48,0x20,0xfe,0xa2,0xa4,0x20,0x60,0x24,0xfe,0x70,0xa8,0x26,0x24,0x20,
-+0x28,0x28,0xff,0x28,0x39,0x10,0x7f,0x54,0x55,0x7d,0x11,0xfd,0x13,0x11,0x11,0x11,0x88,0x88,0xfe,0x88,0xfc,0x88,0xfe,0x20,0xfc,0x24,0xfc,0x24,0xfe,0x4,0x14,0x8,
-+0x28,0x28,0xfd,0x28,0x3b,0x10,0x7d,0x57,0x55,0x7d,0x11,0xff,0x11,0x11,0x11,0x11,0x88,0x88,0xfc,0x88,0xfe,0x88,0x4,0xfe,0x24,0xfc,0x24,0xfc,0x24,0x24,0x34,0x28,
-+0x2,0x3f,0x22,0x3a,0x2a,0x7f,0x41,0xbe,0x22,0x3e,0x22,0x3e,0x22,0x22,0x2a,0x25,0x20,0x20,0x50,0x50,0x88,0x6,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x88,0x8,
-+0x2,0x3f,0x22,0x3a,0x2a,0x7f,0x41,0xbe,0x22,0x3e,0x22,0x3e,0x22,0x22,0x2a,0x25,0x8,0x7c,0x48,0x48,0x48,0x86,0x0,0xfc,0x44,0x48,0x28,0x10,0x30,0x48,0x8e,0x4,
-+0x2,0x3f,0x22,0x3a,0x2a,0x7f,0x41,0xbe,0x22,0x3e,0x22,0x3e,0x22,0x22,0x2a,0x24,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x24,0xfe,0x84,0x84,0x84,0x84,0x84,0xfc,0x84,
-+0x4,0x7e,0x44,0x74,0x54,0xfe,0x82,0x7c,0x44,0x7c,0x44,0x7c,0x45,0x44,0x54,0x48,0x20,0x48,0xfc,0x88,0xa8,0x88,0xa8,0x90,0x84,0xfe,0x4,0x24,0xf4,0x4,0x28,0x10,
-+0x4,0x7e,0x45,0x75,0x55,0xff,0x83,0x7d,0x45,0x7d,0x45,0x7d,0x45,0x45,0x55,0x49,0x8,0x1c,0xe0,0x20,0x20,0x20,0x24,0xfe,0x20,0x20,0x10,0x10,0x28,0x4a,0xa6,0x12,
-+0x4,0x7e,0x45,0x75,0x55,0xff,0x83,0x7d,0x45,0x7d,0x45,0x7d,0x45,0x45,0x56,0x48,0x8,0x1c,0xe0,0x0,0x4,0xfe,0x0,0x4,0x7e,0x44,0x44,0x44,0x44,0x44,0x7c,0x44,
-+0x4,0x7e,0x44,0x74,0x54,0xff,0x82,0x7c,0x44,0x7f,0x44,0x7c,0x44,0x44,0x54,0x48,0x40,0x40,0x7c,0x84,0x88,0x50,0x20,0x50,0x8e,0x4,0xf8,0x88,0x88,0x88,0xf8,0x88,
-+0x0,0x7d,0x45,0x75,0x55,0xff,0x83,0x7d,0x44,0x7f,0x44,0x7c,0x44,0x45,0x56,0x48,0x4,0xfe,0x24,0x24,0xfc,0x24,0x24,0xfc,0x20,0xfe,0x60,0x70,0xa8,0x26,0x24,0x20,
-+0x0,0x7c,0x45,0x75,0x55,0xff,0x83,0x7d,0x45,0x7c,0x45,0x7f,0x44,0x44,0x54,0x48,0x40,0x84,0xfe,0x24,0x24,0xfc,0x24,0x44,0xfc,0xa0,0x24,0xfe,0x20,0x20,0x20,0x20,
-+0x0,0x7d,0x44,0x74,0x55,0xfe,0x82,0x7d,0x44,0x7f,0x44,0x7c,0x44,0x44,0x54,0x49,0x20,0x24,0xa8,0x20,0xfe,0x20,0xa8,0x24,0x40,0xfe,0x48,0x88,0x70,0x50,0x8c,0x4,
-+0x4,0x7e,0x45,0x75,0x54,0xfe,0x83,0x7c,0x44,0x7d,0x44,0x7c,0x44,0x44,0x54,0x48,0x40,0x20,0xfe,0x42,0x7c,0x88,0x50,0x20,0x50,0x8e,0xf8,0x88,0x88,0x88,0xf8,0x88,
-+0x4,0x7e,0x45,0x75,0x54,0xff,0x82,0x7c,0x44,0x7c,0x44,0x7c,0x44,0x44,0x54,0x49,0x20,0x10,0xfe,0x2,0x48,0xfe,0x48,0xfc,0x94,0x94,0xa4,0xa4,0x50,0x52,0x92,0xe,
-+0x4,0x7e,0x45,0x75,0x54,0xfe,0x82,0x7c,0x44,0x7c,0x44,0x7f,0x44,0x44,0x55,0x4a,0x40,0x20,0xfe,0x2,0x1c,0xe0,0x84,0xfe,0x88,0x88,0x88,0xfe,0x0,0x88,0x6,0x2,
-+0x0,0x7d,0x45,0x75,0x55,0xfe,0x82,0x7d,0x47,0x7d,0x45,0x7d,0x44,0x47,0x54,0x48,0x4,0xfe,0x54,0x54,0xfc,0x84,0xfe,0x44,0xf4,0x54,0x54,0xf4,0x4c,0xfc,0x14,0x8,
-+0x10,0x24,0x7e,0x55,0x54,0x7c,0x55,0x54,0x7c,0x10,0x19,0x28,0x2a,0x48,0x87,0x0,0x20,0x20,0x28,0xfc,0x20,0x24,0xfe,0x20,0x70,0xac,0x24,0x20,0x22,0x2,0xfe,0x0,
-+0x10,0x24,0x7e,0x55,0x54,0x7c,0x54,0x54,0x7d,0x12,0x18,0x28,0x2a,0x48,0x87,0x0,0x50,0x48,0x40,0xfe,0x40,0x40,0xfc,0x84,0x28,0x10,0x2c,0xc4,0x2,0x2,0xfe,0x0,
-+0x3f,0x20,0x20,0x3f,0x21,0x26,0x39,0x27,0x24,0x27,0x24,0x27,0x41,0x42,0x84,0x18,0xfc,0xa0,0x94,0xfe,0x40,0x30,0xe,0xf8,0x88,0xf8,0x88,0xf8,0x40,0x52,0x42,0x3e,
-+0x10,0x25,0x7e,0x54,0x55,0x7d,0x55,0x55,0x7d,0x11,0x19,0x2d,0x29,0x48,0x87,0x0,0x8,0xfc,0x50,0x54,0xfe,0x54,0x54,0x54,0x54,0xac,0x4,0x4,0xc,0x2,0xfe,0x0,
-+0x10,0x25,0x7e,0x54,0x54,0x7c,0x54,0x54,0x7c,0x10,0x18,0x2a,0x28,0x48,0x87,0x0,0x20,0x24,0xa8,0x20,0xf8,0x88,0xf8,0x88,0xf8,0x88,0x88,0xa8,0x92,0x2,0xfe,0x0,
-+0x10,0x25,0x7f,0x55,0x55,0x7d,0x55,0x55,0x7d,0x11,0x19,0x2d,0x29,0x48,0x87,0x0,0x4,0xfe,0x4,0x54,0xfc,0x24,0xfc,0x44,0x44,0x74,0x4,0x14,0xa,0x2,0xfe,0x0,
-+0x10,0x24,0x7f,0x54,0x55,0x7d,0x55,0x54,0x7d,0x11,0x19,0x2d,0x29,0x48,0x87,0x0,0x40,0x24,0xfe,0x50,0x24,0x54,0xfc,0x20,0xfc,0x44,0x54,0x74,0xc,0x2,0xfe,0x0,
-+0x20,0x20,0x20,0x48,0x49,0xf2,0x27,0x4a,0xfb,0xa,0x13,0x12,0x22,0x42,0x83,0x2,0x40,0x40,0xa0,0xa0,0x90,0x48,0xff,0x8,0xf8,0x8,0xf8,0x88,0x50,0x20,0x1e,0x4,
-+0x3f,0x20,0x3f,0x21,0x26,0x38,0x21,0x26,0x2f,0x34,0x27,0x24,0x47,0x44,0x85,0x6,0xfc,0x90,0xfc,0x40,0x30,0x8e,0x44,0xb0,0xf8,0x16,0xf0,0x10,0xf4,0x48,0x30,0xc,
-+0x7f,0x10,0x1e,0x23,0x54,0x9,0x32,0x4,0x1f,0x28,0xcf,0x8,0xf,0x8,0xa,0xc,0x20,0x50,0x98,0x26,0x48,0x10,0xa4,0x48,0xf0,0x2e,0xe4,0x20,0xf0,0xa0,0x60,0x18,
-+0x7c,0x44,0x7d,0x1,0xff,0x21,0x7d,0x5,0x1a,0x5,0xf,0x39,0xcf,0xa,0x9,0xc,0x38,0x20,0xfc,0x24,0xf8,0x24,0x7c,0x50,0x9c,0x40,0xf0,0x2e,0xe4,0x20,0xc0,0x30,
-+0x1,0x7f,0x8,0x12,0x7d,0xa,0x7c,0x9,0x32,0x45,0xf,0x39,0xcf,0xa,0x9,0xc,0x4,0xfe,0x90,0xfc,0x90,0xfc,0x90,0x9e,0x80,0x40,0xf0,0x2e,0xe4,0x20,0xc0,0x30,
-+0x2,0x3f,0x20,0x24,0x3e,0x20,0x24,0x3e,0x20,0x22,0xff,0x10,0x10,0x20,0x7f,0x1,0x4,0x4,0x8,0x8,0x10,0x24,0x44,0x88,0x10,0x22,0x42,0x4,0x8,0x10,0x20,0x40,
-+0x1,0x3f,0x20,0x3f,0x20,0x3f,0x20,0xff,0x12,0x3f,0x0,0xff,0x4,0x4,0x18,0x60,0x4,0x88,0x10,0x24,0x48,0x10,0x24,0x88,0x10,0x60,0x4,0xfe,0x40,0x42,0x42,0x3e,
-+0x12,0x14,0x18,0x12,0xff,0x10,0x22,0x7f,0x0,0x1f,0x1,0xf,0x1,0x7f,0x1,0x0,0x8,0x10,0x64,0x8,0x72,0x4,0x18,0x60,0x18,0xe0,0x0,0xf0,0x0,0xfa,0x2,0xfe,
-+0x12,0x14,0x18,0x12,0xff,0x10,0x22,0x7f,0x1,0x1f,0x11,0x1f,0x11,0xff,0x10,0x10,0x8,0x10,0x64,0x8,0x72,0x4,0x18,0x60,0x10,0xf8,0x10,0xf0,0x14,0xfe,0x10,0x30,
-+0x12,0x14,0x18,0xfe,0x24,0x7e,0x0,0x3f,0x4,0x18,0x60,0x1f,0x10,0x10,0x1f,0x10,0x18,0xe0,0x18,0xe4,0x8,0xf0,0x0,0xf8,0x8,0x48,0x30,0xf0,0x10,0x10,0xf0,0x10,
-+0x12,0x14,0x18,0xfe,0x24,0x7e,0x1,0xff,0x1,0x1,0x3f,0x0,0x1f,0x10,0x10,0x1f,0x18,0xe0,0x18,0xe4,0x8,0xf0,0x4,0xfe,0x0,0x10,0xf8,0x0,0xf0,0x10,0x10,0xf0,
-+0x12,0x14,0x18,0x12,0xff,0x10,0x22,0x7f,0x4,0x24,0x27,0x24,0x24,0x2f,0xf0,0x40,0x8,0x10,0x64,0x8,0x72,0x4,0x18,0x60,0x40,0x44,0x48,0x70,0x40,0x42,0x3e,0x0,
-+0x12,0x14,0x18,0x12,0xff,0x10,0x22,0x7f,0x4,0x8,0x17,0x30,0xd1,0x12,0x14,0x10,0x8,0x10,0x64,0x8,0x72,0x4,0x18,0x60,0x40,0x44,0xfe,0xe0,0x50,0x4e,0x44,0x40,
-+0x12,0x14,0x18,0xfe,0x24,0x7e,0x11,0x9,0x3f,0x2,0x7f,0x8,0x3f,0xc8,0x8,0x7,0x8,0xf0,0x8,0xf0,0x4,0xf8,0x10,0x20,0xf8,0x0,0xfc,0x20,0xd8,0x46,0xd0,0xf0,
-+0x12,0x14,0x18,0xfe,0x24,0x7e,0x0,0x6,0x78,0x8,0xff,0x18,0x2c,0xca,0x8,0x9,0x18,0xe0,0x18,0xe4,0x8,0xf0,0x20,0x24,0xac,0xb0,0x20,0x50,0x50,0x88,0x86,0x4,
-+0x12,0x14,0x18,0xfe,0x24,0x7e,0x1,0x7f,0x40,0x8f,0x8,0xf,0x8,0xff,0x8,0x30,0x18,0xe0,0x18,0xe4,0x8,0xf0,0x0,0xfe,0x62,0x84,0x20,0xf0,0x44,0xfe,0x20,0x18,
-+0x12,0x14,0x18,0xfe,0x24,0x7e,0x0,0x1f,0x12,0xff,0x8,0xf,0x5,0x18,0x6c,0x8,0x18,0xe0,0x18,0xe4,0x8,0xf0,0x0,0xf0,0x94,0xfe,0x20,0xf0,0x20,0xc0,0x3c,0x8,
-+0x12,0x14,0x18,0xfe,0x24,0x7e,0x9,0x1f,0x14,0x13,0x14,0x1f,0x22,0x3b,0x22,0x3b,0x18,0xe0,0x18,0xe4,0x8,0xf0,0x20,0xf0,0x50,0x90,0x50,0xf0,0x20,0xa2,0x22,0x9e,
-+0x1,0x0,0x3f,0x22,0x3f,0x22,0x27,0x2a,0x32,0x21,0x22,0x24,0x49,0x42,0x87,0x0,0x0,0x84,0xfe,0x10,0xfc,0x10,0x38,0xd6,0x10,0x0,0x40,0x80,0x10,0x8,0xfc,0x4,
-+0x1,0x0,0x3f,0x22,0x3f,0x26,0x2b,0x32,0x3f,0x20,0x2f,0x20,0x5f,0x40,0x80,0x0,0x0,0x84,0xfe,0x10,0xfc,0x38,0x56,0x90,0xf0,0x80,0xf8,0x80,0xf8,0x82,0x82,0xfe,
-+0x1,0x0,0x3f,0x22,0x3f,0x22,0x27,0x2a,0x32,0x27,0x21,0x22,0x4f,0x42,0x84,0x9,0x0,0x84,0xfe,0x10,0xfc,0x10,0x38,0x56,0x90,0x20,0xc0,0x10,0xf8,0xa0,0x98,0x88,
-+0x1,0x3f,0x24,0x3f,0x24,0x3f,0x28,0x2f,0x28,0x2f,0x20,0x27,0x44,0x44,0x84,0x18,0x0,0xfc,0x40,0xf8,0x48,0xf8,0x40,0x78,0x44,0x3c,0x20,0xf8,0x20,0x22,0x22,0x1e,
-+0x1,0x3f,0x24,0x3f,0x24,0x3f,0x2a,0x2c,0x2f,0x20,0x27,0x20,0x5f,0x42,0x9c,0x0,0x0,0xfe,0x40,0xf8,0x48,0xf8,0x50,0x64,0x7c,0x30,0xc0,0x88,0xfc,0xa0,0x9c,0x80,
-+0x1,0x3f,0x24,0x3f,0x24,0x3f,0x28,0x2f,0x28,0x2f,0x20,0x3f,0x40,0x4f,0x80,0x3f,0x0,0xfc,0x40,0xf8,0x48,0xf8,0x40,0x78,0x44,0x3c,0x88,0xfc,0x80,0xf8,0x80,0xfe,
-+0x1,0x3f,0x24,0x3f,0x24,0x3f,0x28,0x2f,0x28,0x2f,0x24,0x22,0x5f,0x42,0x9c,0x0,0x0,0xfc,0x40,0xf8,0x48,0xf8,0x40,0x78,0x44,0x3c,0x90,0xa0,0xfc,0xa0,0x9c,0x80,
-+0x10,0xa,0x7f,0x54,0x54,0x7f,0x55,0x55,0x7f,0x44,0x55,0x5e,0x54,0x5f,0x94,0x1,0x48,0x48,0xfc,0x48,0x48,0x78,0x48,0x48,0x78,0x48,0x48,0xfe,0x0,0x48,0x86,0x2,
-+0x1,0x3f,0x24,0x3f,0x24,0x3f,0x2a,0x2c,0x2e,0x21,0x27,0x38,0x4f,0x44,0x82,0x1f,0x0,0xfc,0x40,0xf8,0x48,0xf8,0x50,0x64,0xbc,0x40,0xf0,0x8e,0xf8,0x90,0xa0,0xfc,
-+0x1,0x3f,0x24,0x3f,0x24,0x3f,0x2a,0x2c,0x2f,0x24,0x2f,0x3c,0x4a,0x4f,0x84,0x39,0x0,0xfc,0x40,0xf8,0x48,0xf8,0x50,0x64,0x3c,0x8,0x88,0xfe,0x88,0xa8,0x88,0x98,
-+0x10,0xa,0x7f,0x54,0x54,0x7f,0x55,0x55,0x7f,0x44,0x55,0x5e,0x54,0x5f,0x94,0x1,0x10,0x54,0x10,0xfe,0x10,0x54,0x10,0x48,0x48,0xfe,0x28,0xa8,0x5e,0x48,0x88,0x8,
-+0x8,0x10,0x30,0x5f,0x90,0x10,0x1f,0x19,0x15,0x1f,0x1,0x3f,0x1,0xff,0x24,0x42,0xa0,0x90,0xfc,0x40,0x32,0xe,0xf0,0x30,0x50,0xf0,0x0,0xf8,0x0,0xfe,0x88,0x44,
-+0x4,0x7e,0x55,0x55,0x7d,0x55,0x55,0x7c,0x10,0x7d,0x11,0xff,0x1,0xab,0xab,0x0,0x20,0x20,0x24,0x24,0x24,0x24,0xfc,0x20,0x20,0x24,0x24,0x24,0x24,0x24,0xfc,0x4,
-+0x4,0x7e,0x54,0x54,0x7d,0x55,0x57,0x7c,0x10,0x7c,0x11,0xff,0x1,0xaa,0xaa,0x0,0x10,0x90,0x90,0x94,0x3e,0x54,0xd4,0x94,0x94,0x94,0x14,0x54,0xd4,0x24,0x24,0x4c,
-+0x4,0x7e,0x54,0x57,0x7c,0x54,0x55,0x7c,0x10,0x7c,0x10,0xfe,0x0,0xaa,0xaa,0x0,0x20,0x20,0x24,0xfe,0x20,0x28,0xfc,0x0,0x8,0xfc,0x88,0x88,0x88,0x88,0xf8,0x88,
-+0x4,0x7e,0x54,0x54,0x7d,0x54,0x54,0x7d,0x10,0x7c,0x10,0xff,0x0,0xaa,0xaa,0x1,0x20,0x20,0x7c,0x84,0x48,0x30,0x60,0x90,0x3e,0x42,0xc4,0x28,0x10,0x20,0x40,0x80,
-+0x4,0x7e,0x54,0x54,0x7d,0x54,0x55,0x7e,0x10,0x7c,0x11,0xfe,0x0,0xaa,0xaa,0x1,0x20,0x20,0x40,0x88,0xfc,0x88,0x6,0x82,0xf8,0x88,0x88,0x50,0x20,0x50,0x8e,0x4,
-+0x4,0x7e,0x55,0x54,0x7c,0x57,0x54,0x7c,0x11,0x7c,0x13,0xfc,0x0,0xaa,0xaa,0x1,0x20,0x28,0xfc,0x20,0x20,0xfe,0x92,0x54,0x10,0x94,0xfe,0x20,0x20,0x58,0x86,0x2,
-+0x3e,0x8,0xfe,0x1c,0x2a,0x48,0x1f,0x19,0x15,0x1f,0x1,0x3f,0x1,0xff,0x24,0x44,0x44,0x7e,0xa4,0x24,0x54,0x88,0xf0,0x30,0x50,0xf0,0x0,0xf8,0x0,0xfe,0x48,0x44,
-+0x4,0x7e,0x54,0x57,0x7c,0x54,0x54,0x7c,0x10,0x7c,0x10,0xfe,0x1,0xaa,0xaa,0x0,0x40,0x20,0x4,0xfe,0x0,0xf8,0x88,0x88,0x88,0xf8,0x20,0xa8,0x26,0x22,0xa0,0x40,
-+0x4,0x7e,0x54,0x55,0x7c,0x54,0x57,0x7c,0x10,0x7d,0x10,0xfe,0x0,0xaa,0xaa,0x1,0x20,0x40,0x88,0xfc,0x20,0x24,0xfe,0x50,0x98,0x26,0xc8,0x30,0xc4,0x18,0x60,0x80,
-+0x4,0x7e,0x55,0x54,0x7c,0x54,0x57,0x7c,0x10,0x7c,0x10,0xfe,0x0,0xaa,0xaa,0x0,0x40,0x28,0xfc,0x0,0x88,0x50,0xfe,0x8,0xfc,0x88,0x88,0xf8,0x88,0x88,0xf8,0x88,
-+0x12,0x6f,0x42,0x6e,0x42,0x7e,0x1,0x54,0x7c,0x54,0x7c,0x54,0x54,0x7d,0x52,0x1,0x10,0x50,0x50,0x50,0x88,0x88,0x6,0xf8,0x48,0x48,0x48,0x48,0x48,0x88,0xa8,0x10,
-+0x12,0x6f,0x42,0x6e,0x42,0x7e,0x0,0x54,0x7c,0x54,0x7c,0x54,0x54,0x7d,0x52,0x0,0x10,0x10,0x10,0x10,0xfe,0x92,0x92,0x92,0x92,0xfe,0x92,0x92,0x92,0x92,0xfe,0x82,
-+0x12,0x6f,0x42,0x6e,0x42,0x7e,0x0,0x55,0x7c,0x54,0x7c,0x54,0x54,0x7d,0x52,0x0,0x8,0xfc,0x40,0x48,0xfc,0x48,0x48,0xfe,0x0,0xfc,0x84,0x84,0x84,0x84,0xfc,0x84,
-+0x12,0x6f,0x42,0x6e,0x42,0x7e,0x0,0x55,0x7d,0x56,0x7f,0x54,0x54,0x7e,0x52,0x1,0x4,0xfe,0x84,0xfc,0x84,0xfc,0x20,0xfe,0x22,0x24,0xfe,0x48,0x88,0x70,0x58,0x84,
-+0x12,0x6f,0x42,0x6e,0x42,0x7e,0x1,0x54,0x7c,0x55,0x7c,0x57,0x54,0x7d,0x52,0x1,0x1c,0xe0,0xa4,0xa8,0x50,0x84,0xf8,0x20,0x48,0xfc,0x20,0xfe,0x20,0x50,0x4e,0x84,
-+0x10,0x3e,0x32,0x2a,0x3e,0x0,0x7f,0x49,0x7f,0x49,0x7f,0x0,0xff,0x22,0x22,0x43,0x40,0x40,0x40,0x48,0xfc,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x4a,0x8a,0x86,0x0,
-+0x10,0x3e,0x32,0x2a,0x3e,0x0,0x7f,0x49,0x7f,0x49,0x7f,0x0,0xff,0x22,0x22,0x42,0x0,0x8,0xfc,0x10,0x10,0x10,0x14,0xfe,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
-+0x10,0x3e,0x32,0x2a,0x3e,0x0,0x7f,0x49,0x7f,0x49,0x7f,0x0,0xff,0x22,0x22,0x42,0x10,0x14,0xfe,0x10,0x38,0x56,0x90,0x7c,0x44,0x7c,0x44,0x7c,0x44,0x0,0xfe,0x0};
-diff -Nur linux_c860_org/drivers/video/font_jis16.h linux/drivers/video/font_jis16.h
---- linux_c860_org/drivers/video/font_jis16.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/video/font_jis16.h 2004-06-10 21:09:11.000000000 +0900
-@@ -0,0 +1,30231 @@
-+#define max_jis16 241824
-+unsigned char font_jis16[max_jis16] = {
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x40, 0x30, 0x18, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x30, 0x48, 0x48, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x60, 0x60, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x07,
-+ 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00,
-+ 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00,
-+ 0x03, 0x03, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x04, 0x08, 0x0c, 0x0c, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x80, 0xc0, 0x60, 0x60, 0x60, 0xc0, 0x80,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
-+ 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01,
-+ 0x01, 0x01, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00,
-+ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
-+ 0x10, 0x48, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x30, 0x48, 0x48, 0x30, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x02, 0x04, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x20, 0x90, 0x40, 0x00, 0x80, 0x40,
-+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00,
-+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00,
-+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x20, 0x90, 0x40, 0x00, 0x80, 0xc0,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x08,
-+ 0x08, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x80,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x04, 0x08, 0x10, 0x60, 0x0f,
-+ 0x01, 0x01, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x0c, 0xe0,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x03, 0x04,
-+ 0x04, 0x08, 0x12, 0x01, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x20,
-+ 0x20, 0x40, 0x80, 0x80, 0x40, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x09,
-+ 0x12, 0x14, 0x18, 0x10, 0x20, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x10, 0x20, 0x40, 0x80, 0x00,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x07, 0x18, 0x20, 0x20, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x20, 0x20, 0x18, 0x07, 0x00, 0x00,
-+ 0x00, 0xc0, 0x30, 0x08, 0x08, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x08, 0x08, 0x30, 0xc0, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x3f,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
-+ 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00,
-+ 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x22, 0x41,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10,
-+ 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x33,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x18, 0x20, 0x30, 0x38, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x20, 0x70, 0x30, 0x10, 0x60, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x02, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x98, 0x20, 0x30, 0xb8, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x22, 0x77, 0x33, 0x11, 0x66, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x10, 0x20, 0x60, 0x40, 0xc0, 0xc0, 0xc0,
-+ 0xc0, 0x40, 0x60, 0x20, 0x10, 0x08, 0x00, 0x00,
-+ 0x40, 0x20, 0x10, 0x18, 0x08, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x08, 0x18, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x10, 0x20, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00,
-+ 0x40, 0x20, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0xf8, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
-+ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0x00, 0x00,
-+ 0x7c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x7c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x18, 0x20, 0x60, 0x60, 0x60, 0x40, 0x80, 0x40,
-+ 0x60, 0x60, 0x60, 0x60, 0x20, 0x18, 0x00, 0x00,
-+ 0x60, 0x10, 0x18, 0x18, 0x18, 0x08, 0x06, 0x08,
-+ 0x18, 0x18, 0x18, 0x18, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02,
-+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00,
-+ 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01,
-+ 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02,
-+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x48, 0x48, 0x90, 0x90, 0x20, 0x20, 0x40, 0x40,
-+ 0x20, 0x20, 0x90, 0x90, 0x48, 0x48, 0x00, 0x00,
-+ 0x48, 0x48, 0x24, 0x24, 0x12, 0x12, 0x09, 0x09,
-+ 0x12, 0x12, 0x24, 0x24, 0x48, 0x48, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x7e, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x00,
-+ 0xf8, 0x08, 0xf8, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x07, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
-+ 0x05, 0x05, 0x05, 0x7d, 0x41, 0x7f, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0xf8, 0xf0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0,
-+ 0xc0, 0xc0, 0xe0, 0xe0, 0xf0, 0xf8, 0x00, 0x00,
-+ 0x7c, 0x3c, 0x1c, 0x1c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x1c, 0x1c, 0x3c, 0x7c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x3f, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x01, 0x01, 0x01, 0x3f, 0x01, 0x01,
-+ 0x01, 0x01, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x02,
-+ 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x80,
-+ 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x3f, 0x00,
-+ 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xf8, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
-+ 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0x01, 0x01, 0x01,
-+ 0x3f, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x80, 0x80, 0xf8, 0x00, 0x00, 0x00,
-+ 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x03, 0x04, 0x18, 0x20, 0x18,
-+ 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x60, 0x10, 0x00, 0x00, 0x00,
-+ 0x20, 0x18, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x04, 0x18, 0x20, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x10, 0x60,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x03, 0x0c, 0x30, 0x0c, 0x03, 0x00,
-+ 0x00, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
-+ 0x30, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x30, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x03, 0x0c,
-+ 0x30, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xc0, 0x30, 0xc0, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1c, 0x36, 0x23, 0x23,
-+ 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x88, 0x88,
-+ 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x22,
-+ 0x41, 0x41, 0x41, 0x22, 0x1c, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x18, 0x28, 0x48, 0x88, 0x08, 0x08,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x04, 0x08, 0x08, 0x08, 0x04, 0x03,
-+ 0x01, 0x01, 0x1f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0x20, 0x20, 0x20, 0x40, 0x80,
-+ 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x18, 0x18, 0x30, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1b, 0x1b, 0x36, 0x24, 0x48, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x30, 0x48, 0x49, 0x33, 0x06, 0x06, 0x06,
-+ 0x06, 0x06, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xe8, 0x18, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x08, 0x10, 0xe0, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x30, 0x18, 0x0c, 0x3f, 0x06, 0x03,
-+ 0x3f, 0x03, 0x03, 0x03, 0x0f, 0x00, 0x00, 0x00,
-+ 0x00, 0x38, 0x10, 0x20, 0x40, 0xf0, 0x80, 0x00,
-+ 0xf0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x07, 0x09, 0x11, 0x19, 0x0f, 0x03,
-+ 0x01, 0x19, 0x19, 0x09, 0x07, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xc0, 0x20, 0x30, 0x30, 0x00, 0xc0,
-+ 0x60, 0x30, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x03, 0x05, 0x09, 0x19, 0x19,
-+ 0x1a, 0x0a, 0x06, 0x07, 0x04, 0x04, 0x00, 0x00,
-+ 0x00, 0x80, 0x80, 0x80, 0x40, 0x60, 0x60, 0x00,
-+ 0x00, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x01, 0x02, 0x02, 0x06, 0x06, 0x3f,
-+ 0x06, 0x36, 0x4c, 0x4f, 0x39, 0x00, 0x00, 0x00,
-+ 0x00, 0xc0, 0x20, 0x30, 0x20, 0x00, 0x00, 0xe0,
-+ 0x00, 0x00, 0x08, 0xf0, 0xe0, 0x00, 0x00, 0x00,
-+ 0x00, 0x18, 0x24, 0x66, 0x66, 0x24, 0x19, 0x02,
-+ 0x04, 0x09, 0x11, 0x20, 0x40, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x60,
-+ 0x90, 0x98, 0x98, 0x90, 0x60, 0x00, 0x00, 0x00,
-+ 0x00, 0x02, 0x02, 0x02, 0x1f, 0x04, 0x04, 0x04,
-+ 0x04, 0x3f, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x20, 0x20, 0x20, 0xf8, 0x40, 0x40, 0x40,
-+ 0x40, 0xf0, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x07, 0x08, 0x18, 0x19, 0x0e, 0x0c, 0x16,
-+ 0x33, 0x31, 0x30, 0x19, 0x0e, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x78, 0x30,
-+ 0x20, 0xc0, 0xc0, 0x60, 0x18, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x01, 0x03, 0x19, 0x1d, 0x03, 0x03,
-+ 0x1d, 0x19, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x30, 0x70, 0x80, 0x80,
-+ 0x70, 0x30, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x0c, 0x10, 0x23, 0x24, 0x44, 0x48,
-+ 0x49, 0x27, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x10, 0xc8, 0xc8, 0xc8, 0x88,
-+ 0x90, 0x60, 0x08, 0x30, 0xc0, 0x00, 0x00, 0x00,
-+ 0x03, 0x04, 0x04, 0x06, 0x03, 0x03, 0x04, 0x06,
-+ 0x03, 0x01, 0x00, 0x04, 0x04, 0x03, 0x00, 0x00,
-+ 0x80, 0x40, 0x40, 0x00, 0x00, 0x80, 0xc0, 0x40,
-+ 0x80, 0x80, 0xc0, 0x40, 0x40, 0x80, 0x00, 0x00,
-+ 0x00, 0x01, 0x01, 0x02, 0x02, 0x7c, 0x30, 0x0c,
-+ 0x04, 0x09, 0x0a, 0x1c, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x80, 0x7c, 0x18, 0x60,
-+ 0x40, 0x20, 0xa0, 0x70, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x01, 0x03, 0x03, 0x7f, 0x3f, 0x0f,
-+ 0x07, 0x0f, 0x0e, 0x1c, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x80, 0xfc, 0xf8, 0xe0,
-+ 0xc0, 0xe0, 0xe0, 0x70, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x03, 0x0c, 0x10, 0x10, 0x20, 0x20,
-+ 0x20, 0x10, 0x10, 0x0c, 0x03, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x60, 0x10, 0x10, 0x08, 0x08,
-+ 0x08, 0x10, 0x10, 0x60, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x03, 0x0f, 0x1f, 0x1f, 0x3f, 0x3f,
-+ 0x3f, 0x1f, 0x1f, 0x0f, 0x03, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0xe0, 0xf0, 0xf0, 0xf8, 0xf8,
-+ 0xf8, 0xf0, 0xf0, 0xe0, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x03, 0x0c, 0x13, 0x14, 0x28, 0x28,
-+ 0x28, 0x14, 0x13, 0x0c, 0x03, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x60, 0x90, 0x50, 0x28, 0x28,
-+ 0x28, 0x50, 0x90, 0x60, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
-+ 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04,
-+ 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f,
-+ 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc,
-+ 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
-+ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8,
-+ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08,
-+ 0x08, 0x10, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x20,
-+ 0x20, 0x10, 0x10, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x01, 0x03, 0x03, 0x07, 0x07, 0x0f,
-+ 0x0f, 0x1f, 0x1f, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xe0,
-+ 0xe0, 0xf0, 0xf0, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04,
-+ 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40,
-+ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x1f, 0x1f, 0x0f, 0x0f, 0x07, 0x07,
-+ 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0xf0, 0xf0, 0xe0, 0xe0, 0xc0, 0xc0,
-+ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x21, 0x13, 0x09, 0x04, 0x12, 0x39,
-+ 0x12, 0x04, 0x09, 0x13, 0x21, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x08, 0x90, 0x20, 0x40, 0x90, 0x38,
-+ 0x90, 0x40, 0x20, 0x90, 0x08, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x3f, 0x00, 0x00, 0x7f, 0x7f, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0xf0, 0x00, 0x00, 0xf8, 0xf8, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x7f, 0x00,
-+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0xf8, 0x60,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x02, 0x04, 0x18, 0x7f, 0x18,
-+ 0x04, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x01, 0x03, 0x03, 0x05, 0x09, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x20, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x09,
-+ 0x05, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
-+ 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x00, 0x00,
-+ 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0x00, 0x00,
-+ 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x03, 0x0c, 0x10, 0x20, 0x3f, 0x20,
-+ 0x10, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xf0, 0x00,
-+ 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x00,
-+ 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xc0, 0x20, 0x10, 0xf0, 0x10,
-+ 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x10, 0x20, 0x20, 0x20, 0x10,
-+ 0x0f, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0xf0, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x3f, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xc0, 0x20, 0x10, 0x10, 0x10, 0x20,
-+ 0xc0, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x03, 0x0c, 0x10, 0x20, 0x20, 0x20,
-+ 0x20, 0x10, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xc0, 0x20, 0x10, 0x10, 0x10,
-+ 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x10, 0x10, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x20, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x07, 0x08, 0x10, 0x10, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x40, 0x20, 0x20, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04,
-+ 0x08, 0x08, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40,
-+ 0x20, 0x20, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04,
-+ 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40,
-+ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x7f,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x40, 0x20, 0xf0, 0x08, 0xf0,
-+ 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x08, 0x10, 0x3f, 0x40, 0x3f,
-+ 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x40, 0x20, 0xf0, 0x08, 0xf0,
-+ 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x20, 0x20, 0x10, 0x1f, 0x08, 0x08, 0x04,
-+ 0x04, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x08, 0x10, 0xf0, 0x20, 0x20, 0x40,
-+ 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00,
-+ 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0x20, 0x20, 0xe0, 0x20,
-+ 0x20, 0x20, 0x20, 0xe0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
-+ 0x04, 0x08, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x30, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x18, 0x04, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x02, 0x00, 0x00, 0x03, 0x06, 0x04,
-+ 0x0c, 0x0c, 0x0c, 0x05, 0x03, 0x00, 0x00, 0x00,
-+ 0x00, 0xc0, 0x60, 0x20, 0x20, 0xa0, 0x60, 0x60,
-+ 0x60, 0x40, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x3f, 0x1f, 0x18, 0x08, 0x0c, 0x04,
-+ 0x06, 0x02, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0xf0, 0x10, 0x20, 0x20, 0x40,
-+ 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x3f, 0x00,
-+ 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xf0, 0x00,
-+ 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x08, 0x1c, 0x08, 0x3f, 0x00, 0x00,
-+ 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00,
-+ 0xf0, 0x40, 0xe0, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x02, 0x04, 0x08, 0x11, 0x22, 0x11,
-+ 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x80, 0x40, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x22, 0x11, 0x08, 0x04, 0x02, 0x01, 0x02,
-+ 0x04, 0x08, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x20,
-+ 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
-+ 0x22, 0x74, 0x1c, 0x0c, 0x04, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x0c, 0x10, 0x21, 0x21,
-+ 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x60, 0x90, 0x08, 0x08,
-+ 0x10, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x10, 0x10,
-+ 0x09, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x30, 0x40, 0x80, 0x80,
-+ 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x38, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x38, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x01, 0x01,
-+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00,
-+ 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
-+ 0xc0, 0xc0, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x06, 0x0e, 0x11, 0x11, 0x19, 0x19, 0x0c, 0x0c,
-+ 0x06, 0x06, 0x02, 0x02, 0x1d, 0x19, 0x00, 0x00,
-+ 0x60, 0xe0, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0,
-+ 0x60, 0x60, 0x20, 0x20, 0xc0, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x03, 0x04, 0x04, 0x03, 0x01, 0x03, 0x03, 0x04,
-+ 0x04, 0x08, 0x0f, 0x10, 0x38, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x80, 0x00, 0x00, 0x80, 0x80, 0xc0,
-+ 0xc0, 0x60, 0xe0, 0x30, 0x78, 0x00, 0x00, 0x00,
-+ 0x00, 0x18, 0x24, 0x66, 0x66, 0x25, 0x1a, 0x03,
-+ 0x06, 0x0e, 0x16, 0x12, 0x21, 0x00, 0x00, 0x00,
-+ 0x00, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, 0x10,
-+ 0xa8, 0xec, 0xec, 0xa8, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x04, 0x04, 0x07, 0x1f, 0x1c, 0x04, 0x04,
-+ 0x07, 0x1f, 0x1c, 0x04, 0x04, 0x00, 0x00, 0x00,
-+ 0x80, 0x80, 0xe0, 0xe0, 0x80, 0x80, 0x80, 0xe0,
-+ 0xe0, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x06,
-+ 0x04, 0x04, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x60,
-+ 0x60, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x07, 0x0f, 0x0f, 0x06, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0xc0, 0x60, 0x20, 0x30, 0x10, 0x10,
-+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x03, 0x01, 0x09, 0x1f, 0x09, 0x03, 0x03,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x80, 0x00, 0x20, 0xf0, 0x20, 0x80, 0x80,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x03, 0x09, 0x1f, 0x09, 0x03, 0x01, 0x01,
-+ 0x03, 0x09, 0x1f, 0x09, 0x03, 0x01, 0x00, 0x00,
-+ 0x00, 0x80, 0x20, 0xf0, 0x20, 0x80, 0x00, 0x00,
-+ 0x80, 0x20, 0xf0, 0x20, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x07, 0x07, 0x07, 0x03, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0xc0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x07, 0x18, 0x20, 0x20, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x20, 0x20, 0x18, 0x07, 0x00, 0x00,
-+ 0x00, 0xc0, 0x30, 0x08, 0x08, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x08, 0x08, 0x30, 0xc0, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x30, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x03, 0x0f, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x07, 0x08, 0x18, 0x1c, 0x08, 0x00, 0x01,
-+ 0x02, 0x04, 0x0f, 0x1f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0xc0, 0x60, 0x60, 0xc0, 0x80, 0x00,
-+ 0x00, 0x20, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x07, 0x08, 0x18, 0x18, 0x00, 0x03, 0x00,
-+ 0x18, 0x18, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0xc0, 0x60, 0x60, 0xc0, 0x80, 0x40,
-+ 0x60, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x01, 0x02, 0x02, 0x04, 0x08, 0x18,
-+ 0x1f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
-+ 0xf0, 0xc0, 0xc0, 0xe0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x0f, 0x08, 0x08, 0x0f, 0x00, 0x00,
-+ 0x00, 0x18, 0x18, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0xc0, 0x00, 0x00, 0x80, 0xc0, 0x60,
-+ 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x04, 0x0c, 0x08, 0x1b, 0x1c, 0x18,
-+ 0x18, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xc0, 0x60, 0x60, 0x00, 0xc0, 0x60, 0x30,
-+ 0x30, 0x30, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x0f, 0x10, 0x00, 0x00, 0x01, 0x01,
-+ 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0xe0, 0x40, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x07, 0x08, 0x18, 0x1c, 0x0e, 0x07, 0x0d,
-+ 0x18, 0x18, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0x60, 0x60, 0xc0, 0x80, 0xc0,
-+ 0xe0, 0x60, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x0c, 0x18, 0x18, 0x18, 0x0c, 0x07,
-+ 0x00, 0x18, 0x18, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xc0, 0x60, 0x60, 0x60, 0xe0, 0x60,
-+ 0x60, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x01, 0x03, 0x03, 0x04, 0x04, 0x08,
-+ 0x0f, 0x10, 0x10, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0x60,
-+ 0xe0, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x30, 0x30, 0x60, 0xc0, 0x30,
-+ 0x18, 0x18, 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xd0, 0x30, 0x10, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x30, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x30, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x10, 0x00, 0x40, 0xc0, 0x40,
-+ 0x00, 0x08, 0x10, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x10, 0x00, 0x40, 0xc0, 0x40,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xd0, 0x30, 0x10, 0x00, 0x00, 0xf8, 0x30,
-+ 0x30, 0x30, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18,
-+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0xf0, 0x30,
-+ 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-+ 0x38, 0x30, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
-+ 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x18, 0x18, 0x18, 0x19, 0x1a, 0x1c,
-+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x20, 0x40, 0x80, 0x80, 0xc0, 0xc0,
-+ 0x60, 0x60, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x10, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x38, 0x18, 0x1c, 0x1c, 0x16, 0x16, 0x17,
-+ 0x13, 0x12, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x38, 0x30, 0x70, 0x70, 0xb0, 0xb0, 0x30,
-+ 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x38, 0x18, 0x1c, 0x16, 0x16, 0x13, 0x11,
-+ 0x11, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x70, 0x20, 0x20, 0x20, 0x20, 0x20, 0xa0,
-+ 0xa0, 0xe0, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x30, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x30, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x30, 0x30, 0x60, 0x80, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
-+ 0x33, 0x1c, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x30, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0xb0, 0x60, 0xe0, 0x18, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x3e, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x30, 0x30, 0x60, 0x80, 0xc0,
-+ 0x60, 0x60, 0x30, 0x38, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x07, 0x08, 0x18, 0x1c, 0x0f, 0x03, 0x00,
-+ 0x10, 0x18, 0x1c, 0x13, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xa0, 0x60, 0x20, 0x00, 0x00, 0xc0, 0xe0,
-+ 0x30, 0x30, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x23, 0x43, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06,
-+ 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x38, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40,
-+ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3b, 0x19, 0x19, 0x19, 0x0d, 0x0e, 0x0e,
-+ 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xb8, 0x90, 0x90, 0x90, 0xd0, 0xe0, 0xe0,
-+ 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x18, 0x0c, 0x06, 0x03, 0x03, 0x03,
-+ 0x04, 0x08, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x20, 0x40, 0x80, 0x00, 0x00, 0x80,
-+ 0xc0, 0x60, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x18, 0x0c, 0x06, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x20, 0x01, 0x01, 0x03, 0x06,
-+ 0x06, 0x0c, 0x18, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x60, 0xc0, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x08, 0x10, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x0c, 0x0c, 0x03,
-+ 0x0c, 0x18, 0x18, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x60, 0xe0,
-+ 0x60, 0x60, 0xe0, 0x30, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1c, 0x0c, 0x0c, 0x0d, 0x0e, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0e, 0x1d, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x30, 0x30,
-+ 0x30, 0x30, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x18, 0x18,
-+ 0x18, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x20, 0x00,
-+ 0x00, 0x20, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x18, 0x18,
-+ 0x18, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x60, 0x60, 0x60, 0xe0, 0x60, 0x60,
-+ 0x60, 0x60, 0xe0, 0x70, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x18, 0x1f,
-+ 0x18, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x30, 0xf0,
-+ 0x00, 0x10, 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x02, 0x06, 0x06, 0x1f, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x1f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xc0, 0x60, 0x60, 0x00, 0xe0, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x0c, 0x08, 0x08,
-+ 0x07, 0x0c, 0x0f, 0x18, 0x08, 0x07, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0xc0, 0xc0, 0x80,
-+ 0x00, 0x00, 0xc0, 0xe0, 0x20, 0xc0, 0x00, 0x00,
-+ 0x00, 0x1c, 0x0c, 0x0c, 0x0d, 0x0e, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x03, 0x01, 0x00, 0x0f, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x03, 0x01, 0x00, 0x0f, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x19, 0x19, 0x0e, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0e,
-+ 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x70, 0x40, 0x80, 0xc0, 0xc0,
-+ 0x60, 0x60, 0x30, 0x38, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x76, 0x3b, 0x33, 0x33,
-+ 0x33, 0x33, 0x33, 0x7b, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0xb8, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1d, 0x0e, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x18, 0x18,
-+ 0x18, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x30, 0x30,
-+ 0x30, 0x30, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1d, 0x0e, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0e, 0x0d, 0x0c, 0x1e, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x30, 0x30,
-+ 0x30, 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x0c, 0x18, 0x18,
-+ 0x18, 0x18, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x70, 0xe0, 0x60, 0x60,
-+ 0x60, 0x60, 0xe0, 0x60, 0x60, 0xf0, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1d, 0x0e, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x60, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x0f, 0x18, 0x1c, 0x0f,
-+ 0x03, 0x10, 0x18, 0x17, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x00, 0x00,
-+ 0xc0, 0xe0, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x02, 0x06, 0x06, 0x1f, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
-+ 0x00, 0x00, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x70, 0x98, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x3e, 0x18, 0x0c, 0x0c,
-+ 0x06, 0x06, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x70, 0x20, 0x40, 0x40,
-+ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x3d, 0x19, 0x19, 0x0e,
-+ 0x0e, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xb8, 0x90, 0x90, 0xd0,
-+ 0xe0, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 0x06, 0x03,
-+ 0x03, 0x04, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x70, 0x20, 0x40, 0x80,
-+ 0x80, 0xc0, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x0c, 0x06, 0x06,
-+ 0x03, 0x03, 0x01, 0x19, 0x19, 0x0e, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x70, 0x20, 0x20, 0x40,
-+ 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x10, 0x01, 0x03,
-+ 0x06, 0x0c, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0xc0, 0x80, 0x00,
-+ 0x00, 0x00, 0x20, 0xe0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x04, 0x02, 0x13, 0x0e, 0x04,
-+ 0x07, 0x0d, 0x16, 0x26, 0x2a, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80,
-+ 0xe0, 0x10, 0x10, 0x10, 0x20, 0xc0, 0x00, 0x00,
-+ 0x04, 0x02, 0x02, 0x1f, 0x04, 0x04, 0x07, 0x0d,
-+ 0x15, 0x22, 0x26, 0x2a, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xc0, 0x00, 0x80, 0x80, 0xe0, 0x10,
-+ 0x08, 0x08, 0x08, 0x10, 0x60, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,
-+ 0x10, 0x10, 0x0a, 0x0c, 0x04, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20,
-+ 0x10, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x40, 0x20, 0x20, 0x20, 0x22,
-+ 0x24, 0x14, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x08, 0x08,
-+ 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x13,
-+ 0x0c, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80,
-+ 0x40, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x02, 0x01, 0x00, 0x00, 0x03, 0x1c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
-+ 0x00, 0xc0, 0x00, 0x00, 0xc0, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x01,
-+ 0x0e, 0x01, 0x02, 0x07, 0x09, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0xc0,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00,
-+ 0x04, 0x03, 0x00, 0x00, 0x11, 0x0e, 0x01, 0x02,
-+ 0x04, 0x0e, 0x11, 0x21, 0x20, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x00, 0x00, 0xc0, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x0c, 0x38,
-+ 0x0b, 0x0c, 0x18, 0x28, 0x18, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x30, 0x20, 0x00,
-+ 0xc0, 0x20, 0x20, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x04, 0x05, 0x06, 0x1c, 0x04, 0x05,
-+ 0x06, 0x0c, 0x34, 0x0c, 0x04, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x30, 0x08, 0x0c, 0x00, 0x60, 0x90,
-+ 0x08, 0x08, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x04, 0x04, 0x47, 0x3c, 0x08, 0x08,
-+ 0x08, 0x10, 0x11, 0x25, 0x22, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x60, 0x10, 0x88, 0x98, 0x80,
-+ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x04, 0x04, 0x47, 0x3c, 0x08, 0x08,
-+ 0x08, 0x10, 0x11, 0x25, 0x22, 0x00, 0x00, 0x00,
-+ 0x08, 0x24, 0x10, 0x40, 0x20, 0x90, 0x88, 0x98,
-+ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x02, 0x01, 0x01, 0x0f, 0x00, 0x00, 0x1f, 0x00,
-+ 0x00, 0x07, 0x08, 0x08, 0x06, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x60, 0x80, 0x80, 0xf0, 0x40, 0x20,
-+ 0x20, 0xf0, 0x10, 0x00, 0x00, 0xc0, 0x00, 0x00,
-+ 0x04, 0x02, 0x02, 0x1f, 0x01, 0x01, 0x3e, 0x00,
-+ 0x00, 0x0f, 0x10, 0x10, 0x0c, 0x03, 0x00, 0x00,
-+ 0x08, 0x24, 0xd0, 0x00, 0x00, 0xe0, 0x80, 0x40,
-+ 0x40, 0xe0, 0x20, 0x00, 0x00, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x08, 0x08,
-+ 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x80, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x08, 0x08,
-+ 0x04, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x80, 0x40, 0x40, 0x88, 0x24, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x20, 0x10, 0x10, 0x10, 0x23, 0x20, 0x20,
-+ 0x20, 0x20, 0x18, 0x10, 0x10, 0x00, 0x00, 0x00,
-+ 0x80, 0x40, 0x20, 0x20, 0x3c, 0xe0, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x40, 0x40, 0x80, 0x00, 0x00,
-+ 0x01, 0x40, 0x20, 0x20, 0x20, 0x47, 0x40, 0x40,
-+ 0x40, 0x40, 0x30, 0x20, 0x20, 0x01, 0x00, 0x00,
-+ 0x08, 0xa4, 0x50, 0x40, 0x78, 0xc0, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0x20, 0x20, 0x10, 0x0f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x10, 0xe0, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x07, 0x00, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0x20, 0x20, 0x10, 0x0f, 0x00, 0x00, 0x00,
-+ 0x08, 0x04, 0xf0, 0x88, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x10, 0xe0, 0x00, 0x00, 0x00,
-+ 0x04, 0x02, 0x01, 0x21, 0x1e, 0x00, 0x00, 0x07,
-+ 0x08, 0x10, 0x10, 0x0c, 0x03, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x30, 0xc0, 0x80, 0x40, 0x40, 0xe0,
-+ 0x20, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
-+ 0x04, 0x02, 0x01, 0x21, 0x1e, 0x00, 0x00, 0x07,
-+ 0x08, 0x10, 0x10, 0x0c, 0x03, 0x00, 0x00, 0x00,
-+ 0x08, 0x04, 0x30, 0xc8, 0x80, 0x40, 0x40, 0xe0,
-+ 0x20, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x04, 0x03, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x10, 0x60, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x04, 0x03, 0x00, 0x00, 0x00,
-+ 0x00, 0x20, 0x90, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x10, 0x60, 0x80, 0x00, 0x00, 0x00,
-+ 0x01, 0x00, 0x40, 0x3f, 0x00, 0x03, 0x04, 0x04,
-+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
-+ 0x00, 0x80, 0xf8, 0x80, 0x80, 0x80, 0xc0, 0x40,
-+ 0xc0, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x00, 0x40, 0x3f, 0x00, 0x03, 0x04, 0x04,
-+ 0x03, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
-+ 0x28, 0x94, 0xf8, 0x80, 0x80, 0x80, 0xc0, 0x40,
-+ 0xc0, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x08, 0x08, 0x4b, 0x3c, 0x08,
-+ 0x08, 0x08, 0x08, 0x04, 0x03, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0x40, 0x78, 0xc0, 0x40, 0x40,
-+ 0x40, 0xc0, 0x40, 0x00, 0xe0, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x08, 0x08, 0x4b, 0x3c, 0x08,
-+ 0x08, 0x08, 0x08, 0x04, 0x03, 0x00, 0x00, 0x00,
-+ 0x08, 0x84, 0x50, 0x48, 0x78, 0xc0, 0x40, 0x40,
-+ 0x40, 0xc0, 0x40, 0x00, 0xe0, 0x00, 0x00, 0x00,
-+ 0x00, 0x09, 0x06, 0x00, 0x01, 0x02, 0x07, 0x38,
-+ 0x01, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0xc0, 0x40, 0x80, 0x00, 0x38, 0xc0, 0x80,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
-+ 0x00, 0x09, 0x06, 0x00, 0x01, 0x02, 0x07, 0x38,
-+ 0x01, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0xc8, 0x64, 0x90, 0x00, 0x38, 0xc0, 0x80,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
-+ 0x00, 0x08, 0x04, 0x07, 0x3c, 0x08, 0x08, 0x08,
-+ 0x10, 0x10, 0x11, 0x21, 0x20, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0xf0, 0x18, 0x20,
-+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x04, 0x07, 0x3c, 0x08, 0x08, 0x08,
-+ 0x10, 0x10, 0x11, 0x21, 0x20, 0x00, 0x00, 0x00,
-+ 0x08, 0x24, 0x90, 0x00, 0x00, 0xf0, 0x18, 0x20,
-+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x08, 0x04, 0x04, 0x47, 0x3c, 0x08, 0x08, 0x0b,
-+ 0x1c, 0x10, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
-+ 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x20,
-+ 0x10, 0x10, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x08, 0x04, 0x04, 0x47, 0x3c, 0x08, 0x08, 0x0b,
-+ 0x1c, 0x10, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
-+ 0x00, 0x08, 0xc4, 0x10, 0x08, 0x00, 0xc0, 0x20,
-+ 0x10, 0x10, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06,
-+ 0x38, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20,
-+ 0x10, 0x10, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x03, 0x4c, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xe0, 0x10, 0x08, 0x08, 0x08,
-+ 0x08, 0x10, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x03, 0x4c, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x24, 0x10, 0xe0, 0x10, 0x08, 0x08, 0x08,
-+ 0x08, 0x10, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x43, 0x3c, 0x01, 0x01, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x38, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x43, 0x3c, 0x01, 0x01, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x38, 0xc0, 0x88, 0x24, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
-+ 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x03, 0x06,
-+ 0x08, 0x10, 0x10, 0x08, 0x07, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x80, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
-+ 0x00, 0x04, 0x02, 0x02, 0x02, 0x02, 0x03, 0x06,
-+ 0x08, 0x10, 0x10, 0x08, 0x07, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x24, 0x10, 0x00, 0x70, 0x80, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
-+ 0x04, 0x02, 0x02, 0x3f, 0x04, 0x08, 0x08, 0x10,
-+ 0x10, 0x20, 0x03, 0x04, 0x04, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x70, 0x18, 0x20, 0x40,
-+ 0x40, 0x40, 0xc0, 0x60, 0x50, 0x80, 0x00, 0x00,
-+ 0x00, 0x20, 0x10, 0x10, 0x13, 0x20, 0x20, 0x20,
-+ 0x20, 0x22, 0x2a, 0x11, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x18, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x00, 0x00, 0x13, 0x15, 0x19, 0x12,
-+ 0x2a, 0x4c, 0x4c, 0x54, 0x20, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x80, 0xe0, 0x10, 0x08, 0x08,
-+ 0x08, 0x08, 0x68, 0x90, 0x68, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x08, 0x4c, 0x3f, 0x0c, 0x08,
-+ 0x18, 0x18, 0x28, 0x59, 0x08, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0xf0, 0x18, 0xe0, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x03, 0x0d, 0x11, 0x11, 0x22, 0x22,
-+ 0x24, 0x24, 0x28, 0x10, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xc0, 0x20, 0x10, 0x08, 0x08, 0x08,
-+ 0x08, 0x10, 0x10, 0x60, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x20, 0x10, 0x14, 0x13, 0x20, 0x20, 0x20,
-+ 0x20, 0x29, 0x12, 0x12, 0x11, 0x00, 0x00, 0x00,
-+ 0x40, 0x20, 0x20, 0x38, 0xe0, 0x20, 0x20, 0x20,
-+ 0x20, 0xe0, 0x30, 0x28, 0xc0, 0x00, 0x00, 0x00,
-+ 0x00, 0x40, 0x20, 0x28, 0x27, 0x40, 0x40, 0x40,
-+ 0x40, 0x53, 0x24, 0x24, 0x23, 0x00, 0x00, 0x00,
-+ 0x88, 0x44, 0x50, 0x78, 0xc0, 0x40, 0x40, 0x40,
-+ 0x40, 0xc0, 0x60, 0x50, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x40, 0x20, 0x28, 0x27, 0x40, 0x40, 0x40,
-+ 0x40, 0x53, 0x24, 0x24, 0x23, 0x00, 0x00, 0x00,
-+ 0x98, 0x64, 0x64, 0x78, 0xc0, 0x40, 0x40, 0x40,
-+ 0x40, 0xc0, 0x60, 0x50, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x04, 0x3c, 0x08, 0x08, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x08, 0x07, 0x00, 0x00, 0x00,
-+ 0x00, 0x40, 0x40, 0x20, 0x20, 0x30, 0x28, 0x20,
-+ 0x20, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x04, 0x3c, 0x08, 0x08, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x08, 0x07, 0x00, 0x00, 0x00,
-+ 0x08, 0x44, 0x50, 0x28, 0x20, 0x30, 0x28, 0x20,
-+ 0x20, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x04, 0x3c, 0x08, 0x08, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x08, 0x07, 0x00, 0x00, 0x00,
-+ 0x30, 0x48, 0x48, 0x30, 0x20, 0x30, 0x28, 0x20,
-+ 0x20, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x04, 0x03, 0x00, 0x01, 0x02, 0x02, 0x01,
-+ 0x02, 0x4c, 0x38, 0x24, 0x03, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0xb0, 0x88, 0x9c, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x04, 0x03, 0x00, 0x01, 0x02, 0x02, 0x01,
-+ 0x02, 0x4c, 0x38, 0x24, 0x03, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x88, 0xa4, 0x10, 0x00, 0x00, 0x00,
-+ 0xb0, 0x88, 0x9c, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x04, 0x03, 0x00, 0x01, 0x02, 0x02, 0x01,
-+ 0x02, 0x4c, 0x38, 0x24, 0x03, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x98, 0xa4, 0x24, 0x18, 0x00, 0x00,
-+ 0xb0, 0x88, 0x9c, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x50, 0x20,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-+ 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x50, 0x20,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x48, 0x20, 0x00, 0x80, 0x40,
-+ 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x50, 0x20,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x30, 0x48, 0x48, 0x30, 0x00, 0x80, 0x40,
-+ 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x22, 0x11, 0x10, 0x10, 0x23, 0x20, 0x20,
-+ 0x20, 0x29, 0x12, 0x12, 0x11, 0x00, 0x00, 0x00,
-+ 0x00, 0x30, 0xc0, 0x40, 0x38, 0xe0, 0x20, 0x20,
-+ 0x20, 0xe0, 0x30, 0x28, 0xc0, 0x00, 0x00, 0x00,
-+ 0x00, 0x44, 0x23, 0x20, 0x20, 0x47, 0x40, 0x40,
-+ 0x40, 0x53, 0x24, 0x24, 0x23, 0x00, 0x00, 0x00,
-+ 0x00, 0x68, 0x84, 0x90, 0x78, 0xc0, 0x40, 0x40,
-+ 0x40, 0xc0, 0x60, 0x50, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x44, 0x23, 0x20, 0x20, 0x47, 0x40, 0x40,
-+ 0x40, 0x53, 0x24, 0x24, 0x23, 0x00, 0x00, 0x00,
-+ 0x18, 0x64, 0xa4, 0x98, 0x70, 0xc0, 0x40, 0x40,
-+ 0x40, 0xc0, 0x60, 0x50, 0x80, 0x00, 0x00, 0x00,
-+ 0x01, 0x00, 0x10, 0x0f, 0x00, 0x10, 0x0f, 0x00,
-+ 0x00, 0x0f, 0x10, 0x10, 0x0f, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0xf0, 0x80, 0x80, 0xe0, 0x80, 0x80,
-+ 0x80, 0x80, 0xe0, 0x90, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x07, 0x01, 0x01, 0x02, 0x02, 0x0f,
-+ 0x34, 0x44, 0x48, 0x30, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x80, 0x00, 0x00, 0x20, 0x10, 0xf0,
-+ 0x18, 0x24, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x08, 0x04, 0x27, 0x1c, 0x04, 0x1c, 0x24, 0x24,
-+ 0x2c, 0x18, 0x08, 0x08, 0x07, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x30, 0x08, 0x0c, 0x00, 0x00,
-+ 0x20, 0x10, 0x10, 0x10, 0xe0, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x00, 0x10, 0x13, 0x1c, 0x11, 0x29,
-+ 0x2a, 0x46, 0x44, 0x4a, 0x30, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x80, 0xc0, 0xa0, 0x10, 0x08,
-+ 0x08, 0x08, 0x08, 0x10, 0x60, 0x00, 0x00, 0x00,
-+ 0x02, 0x01, 0x11, 0x0e, 0x03, 0x12, 0x24, 0x1c,
-+ 0x07, 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x20, 0x20,
-+ 0x10, 0x10, 0x10, 0x10, 0x20, 0xc0, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x09, 0x0e,
-+ 0x3c, 0x04, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0x10,
-+ 0x10, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x00, 0x01, 0x18, 0x10, 0x0b, 0x4c, 0x34,
-+ 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0xc0, 0x00, 0xf0, 0x08, 0x08, 0x08,
-+ 0x70, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x21, 0x27,
-+ 0x29, 0x31, 0x23, 0x21, 0x01, 0x02, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x10,
-+ 0x10, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x40, 0x21, 0x22, 0x24, 0x28, 0x30,
-+ 0x34, 0x22, 0x21, 0x00, 0x01, 0x02, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0xe0, 0x90, 0x88, 0x88, 0x88,
-+ 0x88, 0x90, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x0f, 0x11, 0x11, 0x0e, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xc0, 0x00,
-+ 0x00, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x00, 0x00,
-+ 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x1f, 0x21, 0x21, 0x1e, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x30, 0xc0, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x02, 0x01, 0x01, 0x06, 0x08, 0x08, 0x08, 0x09,
-+ 0x0e, 0x08, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xe0,
-+ 0x10, 0x10, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x10, 0x09, 0x0a, 0x0c, 0x0c, 0x08, 0x08, 0x08,
-+ 0x08, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x07, 0x00, 0x01, 0x02, 0x07, 0x0c,
-+ 0x10, 0x20, 0x03, 0x04, 0x04, 0x03, 0x00, 0x00,
-+ 0x00, 0xc0, 0x40, 0x80, 0x00, 0x00, 0xc0, 0x20,
-+ 0x10, 0x10, 0x90, 0x60, 0x40, 0x80, 0x00, 0x00,
-+ 0x00, 0x10, 0x08, 0x09, 0x0a, 0x1c, 0x6c, 0x08,
-+ 0x18, 0x18, 0x28, 0x48, 0x18, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xc0, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x24, 0x18, 0x00, 0x00, 0x00,
-+ 0x00, 0x11, 0x0e, 0x01, 0x02, 0x04, 0x0f, 0x08,
-+ 0x10, 0x20, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00,
-+ 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x20,
-+ 0x10, 0x10, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0x06,
-+ 0x1d, 0x06, 0x0c, 0x0c, 0x14, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
-+ 0x10, 0x10, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x08, 0x4c, 0x3f, 0x0c, 0x08,
-+ 0x18, 0x18, 0x28, 0x48, 0x18, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0x08, 0x08,
-+ 0x08, 0x08, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x00, 0x09, 0x06, 0x01, 0x01, 0x03, 0x0e, 0x12,
-+ 0x24, 0x24, 0x28, 0x19, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x80, 0x00, 0x00, 0xe0, 0x10, 0x08,
-+ 0x08, 0x08, 0xc8, 0x30, 0xe0, 0x00, 0x00, 0x00,
-+ 0x00, 0x09, 0x07, 0x02, 0x07, 0x08, 0x10, 0x06,
-+ 0x09, 0x07, 0x08, 0x1c, 0x23, 0x40, 0x00, 0x00,
-+ 0x00, 0x80, 0x00, 0x00, 0xc0, 0x20, 0x20, 0x20,
-+ 0xc0, 0x00, 0x00, 0xe0, 0x10, 0x38, 0x00, 0x00,
-+ 0x04, 0x02, 0x12, 0x0f, 0x04, 0x04, 0x0f, 0x18,
-+ 0x21, 0x02, 0x04, 0x08, 0x08, 0x07, 0x00, 0x00,
-+ 0x00, 0x00, 0xc0, 0x00, 0x00, 0x20, 0x38, 0xc0,
-+ 0x80, 0x80, 0x80, 0x00, 0x00, 0xe0, 0x00, 0x00,
-+ 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x0f,
-+ 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x80, 0x80, 0x88, 0x90, 0x60, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x1e,
-+ 0x02, 0x01, 0x01, 0x01, 0x02, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x20,
-+ 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x21, 0x1e, 0x00, 0x02, 0x01, 0x01,
-+ 0x01, 0x01, 0x02, 0x02, 0x04, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x10, 0x20, 0x40, 0x80, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
-+ 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0d, 0x30,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x20, 0x20, 0x40, 0x80, 0x00, 0x00, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x01, 0x1e,
-+ 0x08, 0x08, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x20,
-+ 0x20, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x02, 0x01, 0x01, 0x01, 0x3e, 0x10, 0x10,
-+ 0x08, 0x08, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x10, 0x10, 0x20,
-+ 0x20, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f,
-+ 0x01, 0x01, 0x01, 0x01, 0x1e, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00,
-+ 0x00, 0x00, 0x00, 0xe0, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x02, 0x01, 0x01,
-+ 0x01, 0x01, 0x03, 0x3c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x70, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x0f,
-+ 0x01, 0x02, 0x04, 0x08, 0x11, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x1f, 0x00, 0x01,
-+ 0x02, 0x04, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0x40, 0x78, 0xc0, 0xc0, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xc0, 0x40, 0x00, 0x00,
-+ 0x00, 0x02, 0x01, 0x01, 0x21, 0x1f, 0x02, 0x02,
-+ 0x04, 0x04, 0x08, 0x11, 0x20, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10,
-+ 0x20, 0x20, 0x20, 0x40, 0xc0, 0x80, 0x00, 0x00,
-+ 0x00, 0x02, 0x01, 0x01, 0x21, 0x1f, 0x02, 0x02,
-+ 0x04, 0x04, 0x08, 0x11, 0x20, 0x00, 0x00, 0x00,
-+ 0x08, 0x24, 0x14, 0x10, 0xf0, 0x10, 0x10, 0x10,
-+ 0x20, 0x20, 0x20, 0x40, 0xc0, 0x80, 0x00, 0x00,
-+ 0x00, 0x04, 0x02, 0x02, 0x03, 0x1d, 0x01, 0x01,
-+ 0x03, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x70, 0x80, 0x00, 0x00, 0x78,
-+ 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x04, 0x02, 0x02, 0x03, 0x1d, 0x01, 0x01,
-+ 0x03, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x24, 0x14, 0x70, 0x80, 0x00, 0x00, 0x78,
-+ 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x04, 0x02, 0x03, 0x02, 0x04, 0x04, 0x08,
-+ 0x10, 0x00, 0x01, 0x02, 0x04, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x70, 0x90, 0x20, 0x20, 0x40, 0x40,
-+ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x04, 0x07, 0x04, 0x08, 0x08, 0x10,
-+ 0x21, 0x01, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00,
-+ 0x08, 0x24, 0xd4, 0x50, 0x40, 0x40, 0x80, 0x80,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x04, 0x04, 0x04, 0x0f, 0x09, 0x10,
-+ 0x20, 0x00, 0x01, 0x01, 0x02, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x38, 0xc0, 0x00, 0x80,
-+ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x04, 0x04, 0x04, 0x0f, 0x09, 0x10,
-+ 0x20, 0x00, 0x01, 0x01, 0x02, 0x04, 0x00, 0x00,
-+ 0x08, 0x24, 0x14, 0x10, 0x38, 0xc0, 0x00, 0x80,
-+ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x21, 0x1e, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x03, 0x1c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10, 0x10,
-+ 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x43, 0x3c, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x07, 0x38, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x24, 0x14, 0xd0, 0x40, 0x40, 0x40, 0x40,
-+ 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x08, 0x04, 0x04, 0x24, 0x1f, 0x04,
-+ 0x04, 0x04, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40,
-+ 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x08, 0x04, 0x04, 0x24, 0x1f, 0x04,
-+ 0x04, 0x04, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
-+ 0x08, 0xa4, 0x54, 0x50, 0x40, 0xf8, 0x40, 0x40,
-+ 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x0c, 0x02, 0x00, 0x18, 0x04, 0x00,
-+ 0x00, 0x00, 0x00, 0x13, 0x0c, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10,
-+ 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x0c, 0x02, 0x00, 0x18, 0x04, 0x00,
-+ 0x00, 0x00, 0x00, 0x13, 0x0c, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x24, 0x14, 0x10, 0x00, 0x08, 0x10,
-+ 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x02, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xe0, 0x20, 0x40, 0x40, 0x80, 0x80,
-+ 0x40, 0x20, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x21, 0x1e, 0x00, 0x00, 0x01, 0x01,
-+ 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x24, 0xd4, 0x50, 0x80, 0x80, 0x00, 0x00,
-+ 0x80, 0x40, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x04, 0x04, 0x04, 0x05, 0x26, 0x1c,
-+ 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x78, 0x88, 0x10, 0x20,
-+ 0x40, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x04, 0x04, 0x04, 0x05, 0x26, 0x1c,
-+ 0x04, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00,
-+ 0x08, 0x24, 0x14, 0x10, 0x78, 0x88, 0x10, 0x20,
-+ 0x40, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x08, 0x04, 0x04, 0x04, 0x00,
-+ 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00,
-+ 0x00, 0x20, 0x10, 0x10, 0x10, 0x20, 0x20, 0x40,
-+ 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x20, 0x10, 0x08, 0x08, 0x08, 0x00,
-+ 0x00, 0x01, 0x01, 0x02, 0x04, 0x08, 0x00, 0x00,
-+ 0x08, 0xa4, 0x54, 0x50, 0x40, 0x40, 0x40, 0x80,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x02, 0x01, 0x01, 0x02, 0x02, 0x05, 0x08,
-+ 0x10, 0x00, 0x01, 0x02, 0x0c, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x10, 0x20, 0x20, 0xc0,
-+ 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x04, 0x02, 0x03, 0x04, 0x04, 0x0a, 0x11,
-+ 0x20, 0x01, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x08, 0x24, 0x14, 0xf0, 0x20, 0x20, 0x40, 0x40,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x01, 0x1e, 0x01, 0x00, 0x23, 0x1c,
-+ 0x00, 0x00, 0x01, 0x01, 0x02, 0x04, 0x00, 0x00,
-+ 0x00, 0x40, 0x80, 0x00, 0x00, 0xf8, 0x80, 0x80,
-+ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x01, 0x1e, 0x01, 0x00, 0x23, 0x1c,
-+ 0x00, 0x00, 0x01, 0x01, 0x02, 0x04, 0x00, 0x00,
-+ 0x08, 0x64, 0x94, 0x10, 0x00, 0xf8, 0x80, 0x80,
-+ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x12,
-+ 0x0a, 0x08, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20,
-+ 0x20, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x04, 0x22, 0x11, 0x09, 0x08, 0x00,
-+ 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x08, 0x08, 0x10, 0x10, 0x20,
-+ 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x08, 0x44, 0x24, 0x10, 0x10,
-+ 0x00, 0x01, 0x02, 0x04, 0x08, 0x00, 0x00, 0x00,
-+ 0x08, 0x24, 0x94, 0x50, 0x40, 0x40, 0x40, 0x80,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x11, 0x0e, 0x00, 0x00, 0x23, 0x1c,
-+ 0x00, 0x01, 0x01, 0x02, 0x04, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xe0, 0x00, 0x00, 0x78, 0x80, 0x80,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x11, 0x0e, 0x00, 0x20, 0x1f, 0x00,
-+ 0x00, 0x01, 0x01, 0x02, 0x04, 0x08, 0x00, 0x00,
-+ 0x08, 0x24, 0xd4, 0x10, 0x00, 0xf0, 0x00, 0x80,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x04, 0x04, 0x04, 0x04, 0x07, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
-+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x0e, 0x09,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x90, 0x50, 0x40, 0x00, 0x00, 0x00, 0x80,
-+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x00, 0x00, 0x20, 0x1f, 0x00, 0x00,
-+ 0x00, 0x01, 0x01, 0x02, 0x04, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x80, 0xf8, 0x80, 0x80, 0x80,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x0f, 0x00, 0x00, 0x0e, 0x01,
-+ 0x00, 0x01, 0x02, 0x0c, 0x30, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x10, 0x20, 0x20, 0x40, 0xc0,
-+ 0xc0, 0x20, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x02, 0x01, 0x01, 0x1e, 0x00, 0x00, 0x01,
-+ 0x03, 0x0d, 0x31, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xe0, 0x20, 0x40, 0x80, 0x00,
-+ 0x40, 0x30, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00,
-+ 0x00, 0x40, 0x20, 0x20, 0x20, 0x40, 0x40, 0x80,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0x08,
-+ 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x10,
-+ 0x10, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0x08,
-+ 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x24, 0x14, 0x90, 0x40, 0x20, 0x10,
-+ 0x10, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0x08,
-+ 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x18, 0x24, 0x24, 0x18, 0x80, 0x40, 0x20, 0x10,
-+ 0x10, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x08, 0x08, 0x08, 0x0f, 0x08,
-+ 0x08, 0x08, 0x08, 0x04, 0x03, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x0f,
-+ 0x08, 0x08, 0x08, 0x04, 0x03, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x48, 0x28, 0x20, 0x00, 0xe0, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x0f,
-+ 0x08, 0x08, 0x08, 0x04, 0x03, 0x00, 0x00, 0x00,
-+ 0x00, 0x30, 0x48, 0x48, 0x30, 0x00, 0xe0, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x10, 0x10, 0x20, 0x20, 0x40,
-+ 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x23, 0x1c, 0x00, 0x00, 0x00, 0x01,
-+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00, 0x00,
-+ 0x08, 0x24, 0xd4, 0x50, 0x40, 0x80, 0x80, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x23, 0x1c, 0x00, 0x00, 0x00, 0x01,
-+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00, 0x00,
-+ 0x18, 0x24, 0xe4, 0x58, 0x40, 0x80, 0x80, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x48, 0x30,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
-+ 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x48, 0x30,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x20, 0x90, 0x50, 0x40, 0x00, 0x80, 0x40,
-+ 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x05, 0x48, 0x30,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x60, 0x90, 0x90, 0x60, 0x00, 0x80, 0x40,
-+ 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x02, 0x01, 0x01, 0x21, 0x1f, 0x01, 0x01,
-+ 0x09, 0x09, 0x11, 0x21, 0x03, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x40,
-+ 0x20, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x02, 0x01, 0x01, 0x21, 0x1f, 0x01, 0x01,
-+ 0x09, 0x09, 0x11, 0x21, 0x03, 0x01, 0x00, 0x00,
-+ 0x08, 0x24, 0x14, 0x10, 0xf0, 0x00, 0x00, 0x40,
-+ 0x20, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x02, 0x01, 0x01, 0x21, 0x1f, 0x01, 0x01,
-+ 0x09, 0x09, 0x11, 0x21, 0x03, 0x01, 0x00, 0x00,
-+ 0x18, 0x24, 0x24, 0x18, 0xf0, 0x00, 0x00, 0x40,
-+ 0x20, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x20, 0x1f, 0x00, 0x00, 0x00,
-+ 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x08, 0x10, 0x20, 0x40,
-+ 0x80, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x04, 0x03, 0x00, 0x00, 0x08, 0x06, 0x01,
-+ 0x00, 0x10, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x00, 0x80,
-+ 0x40, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x00,
-+ 0x00, 0x02, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
-+ 0x04, 0x04, 0x29, 0x1e, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
-+ 0x20, 0x30, 0xc8, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0x00,
-+ 0x00, 0x00, 0x01, 0x02, 0x0c, 0x30, 0x00, 0x00,
-+ 0x00, 0x40, 0x20, 0x20, 0x20, 0x20, 0xc0, 0x40,
-+ 0xa0, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x0f, 0x02, 0x02, 0x23, 0x1e,
-+ 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xf8, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x03,
-+ 0x1e, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x90,
-+ 0x20, 0x40, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x08, 0x04, 0x04, 0x03, 0x26, 0x1a, 0x01,
-+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x78, 0x88, 0x10, 0x20, 0x40,
-+ 0x00, 0x00, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e,
-+ 0x00, 0x00, 0x01, 0x1e, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40,
-+ 0x40, 0x80, 0xe0, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x11, 0x0e, 0x00, 0x00,
-+ 0x00, 0x01, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x40, 0x80,
-+ 0x80, 0xf0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00,
-+ 0x01, 0x0e, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x20, 0x20,
-+ 0xe0, 0x40, 0x40, 0xc0, 0x20, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x01, 0x1e, 0x00, 0x00, 0x01, 0x0e,
-+ 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10, 0xe0, 0x20,
-+ 0x20, 0x20, 0x20, 0xe0, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x11, 0x0e, 0x00, 0x23, 0x1c, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0xc0, 0x00, 0x70, 0x90, 0x10, 0x10,
-+ 0x20, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00,
-+ 0x00, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x01, 0x08, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x88, 0x88,
-+ 0x90, 0x90, 0xa0, 0xc0, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x0b, 0x0c, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-+ 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x21, 0x1e, 0x10, 0x10, 0x08,
-+ 0x08, 0x09, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10, 0x20,
-+ 0x20, 0xe0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0f,
-+ 0x08, 0x04, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x10,
-+ 0x20, 0x20, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x21, 0x1e, 0x10, 0x08, 0x08, 0x08,
-+ 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10, 0x20, 0x20,
-+ 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x00, 0x00, 0x01, 0x1e, 0x08, 0x04,
-+ 0x05, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x80, 0xf0, 0x80, 0x80, 0x80,
-+ 0xf0, 0x88, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x01, 0x1e, 0x02, 0x01, 0x01,
-+ 0x01, 0x01, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xe0, 0x20, 0x40, 0x80, 0x00,
-+ 0x00, 0xf0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x01, 0x1e, 0x00, 0x00, 0x01, 0x0e,
-+ 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x10, 0x10, 0x20, 0xe0, 0x20,
-+ 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x18, 0x04, 0x02, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x13, 0x0c, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x10,
-+ 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x04, 0x02, 0x02, 0x43, 0x3c, 0x20, 0x10,
-+ 0x10, 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, 0x00,
-+ 0x08, 0x24, 0x14, 0x10, 0xe0, 0x20, 0x20, 0x40,
-+ 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x11,
-+ 0x0e, 0x02, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
-+ 0x20, 0x20, 0x20, 0x20, 0xc0, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04,
-+ 0x07, 0x08, 0x10, 0x01, 0x02, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
-+ 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x01, 0x03, 0x03, 0x04, 0x04, 0x08,
-+ 0x0f, 0x10, 0x10, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0x60,
-+ 0xe0, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x30, 0x30, 0x60, 0xc0, 0x30,
-+ 0x18, 0x18, 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x01, 0x03, 0x03, 0x04, 0x04, 0x08,
-+ 0x08, 0x10, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0x60,
-+ 0x60, 0x30, 0x30, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x10, 0x00, 0x40, 0xc0, 0x40,
-+ 0x00, 0x08, 0x10, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x20, 0x01, 0x01, 0x03, 0x06,
-+ 0x06, 0x0c, 0x18, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x60, 0xc0, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x08, 0x10, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18,
-+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0xf0, 0x30,
-+ 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x0c, 0x18, 0x30, 0x34, 0x37, 0x34,
-+ 0x30, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x30, 0x18, 0x58, 0xd8, 0x58,
-+ 0x18, 0x30, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x18, 0x18, 0x18, 0x19, 0x1a, 0x1c,
-+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x20, 0x40, 0x80, 0x80, 0xc0, 0xc0,
-+ 0x60, 0x60, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x01, 0x03, 0x03, 0x04, 0x04, 0x08,
-+ 0x08, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0x60,
-+ 0x60, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x38, 0x18, 0x1c, 0x1c, 0x16, 0x16, 0x17,
-+ 0x13, 0x12, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x38, 0x30, 0x70, 0x70, 0xb0, 0xb0, 0x30,
-+ 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x38, 0x18, 0x1c, 0x16, 0x16, 0x13, 0x11,
-+ 0x11, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x70, 0x20, 0x20, 0x20, 0x20, 0x20, 0xa0,
-+ 0xa0, 0xe0, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1f, 0x20, 0x00, 0x10, 0x1f, 0x1f,
-+ 0x10, 0x00, 0x10, 0x1f, 0x3f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0xe0, 0x20, 0x00, 0x20, 0xe0, 0xe0,
-+ 0x20, 0x00, 0x10, 0xe0, 0xe0, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x30, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x30, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x30, 0x30, 0x60, 0x80, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x18, 0x0c, 0x06, 0x03, 0x01, 0x01,
-+ 0x02, 0x04, 0x08, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x10, 0x00, 0x00, 0x80, 0x00,
-+ 0x00, 0x10, 0x20, 0xe0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x23, 0x43, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x0c, 0x17, 0x23, 0x23, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xc0, 0xa0, 0x10, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x03, 0x07, 0x1b, 0x33, 0x33, 0x33,
-+ 0x1b, 0x07, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xc0, 0x00, 0x80, 0x60, 0x30, 0x30, 0x30,
-+ 0x60, 0x80, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x18, 0x0c, 0x06, 0x03, 0x03, 0x03,
-+ 0x04, 0x08, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x20, 0x40, 0x80, 0x00, 0x00, 0x80,
-+ 0xc0, 0x60, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x03, 0x63, 0x33, 0x33, 0x33, 0x13,
-+ 0x0f, 0x03, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xc0, 0x00, 0x18, 0x30, 0x30, 0x30, 0x20,
-+ 0xc0, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x18,
-+ 0x08, 0x04, 0x22, 0x3e, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x30, 0x18, 0x18, 0x18, 0x30,
-+ 0x20, 0x40, 0x88, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x0c, 0x18, 0x10,
-+ 0x10, 0x10, 0x19, 0x0e, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x20, 0x20, 0xa0, 0x60, 0x60,
-+ 0x40, 0xc0, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x01, 0x02, 0x02, 0x04, 0x05, 0x04,
-+ 0x0c, 0x08, 0x0c, 0x1b, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xe0, 0x10, 0x10, 0x10, 0x20, 0xc0, 0x20,
-+ 0x20, 0x20, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x01, 0x01,
-+ 0x01, 0x03, 0x03, 0x03, 0x02, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x30, 0x40, 0x80, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x04, 0x04, 0x02, 0x03, 0x04, 0x0c,
-+ 0x08, 0x08, 0x09, 0x07, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0xe0, 0x10, 0x00, 0x80, 0xc0, 0x40,
-+ 0x40, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x04, 0x03,
-+ 0x06, 0x0c, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x80,
-+ 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x04, 0x0c, 0x07, 0x02, 0x04, 0x04, 0x08,
-+ 0x08, 0x0e, 0x07, 0x00, 0x06, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0xc0, 0x40, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x0c, 0x17, 0x02, 0x04,
-+ 0x04, 0x0c, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x20, 0x20,
-+ 0x20, 0x40, 0x40, 0xc0, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x01, 0x02, 0x06, 0x04, 0x0f, 0x0c,
-+ 0x08, 0x08, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x10, 0x10, 0x10, 0x30, 0xf0, 0x20,
-+ 0x60, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x02, 0x06,
-+ 0x04, 0x04, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x0d, 0x0e,
-+ 0x09, 0x19, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x70, 0xc0, 0x00, 0x00,
-+ 0x00, 0x00, 0xa0, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02,
-+ 0x06, 0x04, 0x0c, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0xc0, 0x40, 0xc0, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x0c,
-+ 0x08, 0x08, 0x0c, 0x1b, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x60, 0x40,
-+ 0x40, 0x40, 0xe8, 0x30, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x0c, 0x04, 0x04,
-+ 0x04, 0x07, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x40, 0x40,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x03, 0x04, 0x03, 0x02, 0x04, 0x04, 0x03, 0x04,
-+ 0x08, 0x08, 0x0e, 0x07, 0x00, 0x07, 0x00, 0x00,
-+ 0x00, 0x60, 0xe0, 0x00, 0x00, 0x00, 0xc0, 0xc0,
-+ 0x00, 0x00, 0x00, 0x80, 0xc0, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x0c,
-+ 0x0c, 0x08, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x10, 0x30,
-+ 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x0c, 0x1f, 0x22, 0x04, 0x04,
-+ 0x08, 0x08, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x08, 0xf0, 0x40, 0x40, 0x80,
-+ 0x80, 0x80, 0xc0, 0x60, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0x04,
-+ 0x0c, 0x0c, 0x0c, 0x1b, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0x10, 0x10,
-+ 0x30, 0x20, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0c, 0x18,
-+ 0x10, 0x10, 0x11, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x80, 0x40, 0x40,
-+ 0x40, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x0f, 0x11, 0x03,
-+ 0x02, 0x04, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x30, 0xe0, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x0c, 0x0c,
-+ 0x08, 0x08, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, 0x20, 0x20,
-+ 0x60, 0x40, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x0d, 0x19, 0x31,
-+ 0x32, 0x12, 0x0e, 0x07, 0x04, 0x04, 0x00, 0x00,
-+ 0x00, 0x80, 0x80, 0x80, 0x80, 0xc0, 0x20, 0x30,
-+ 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x06, 0x0b, 0x01, 0x01, 0x01, 0x01, 0x03,
-+ 0x07, 0x05, 0x09, 0x19, 0x31, 0x20, 0x00, 0x00,
-+ 0x00, 0x10, 0x30, 0x60, 0x40, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc0, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x31, 0x59, 0x09, 0x09,
-+ 0x12, 0x12, 0x12, 0x0f, 0x04, 0x04, 0x00, 0x00,
-+ 0x00, 0x80, 0x80, 0x80, 0xa0, 0x30, 0x10, 0x10,
-+ 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x31, 0x23,
-+ 0x22, 0x22, 0x36, 0x19, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x10, 0x10,
-+ 0x30, 0x20, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x01, 0x03, 0x03, 0x04, 0x04, 0x08,
-+ 0x0f, 0x10, 0x10, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0x60,
-+ 0xe0, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x10, 0x00, 0x00, 0x80, 0x60,
-+ 0x30, 0x30, 0x30, 0x60, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x30, 0x30, 0x60, 0xc0, 0x30,
-+ 0x18, 0x18, 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x08, 0x08, 0x1f, 0x30, 0x20, 0x00, 0x00,
-+ 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
-+ 0x60, 0x60, 0x60, 0xf8, 0x18, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x10, 0x00, 0x40, 0xc0, 0x40,
-+ 0x00, 0x08, 0x10, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x0c, 0x0c, 0x3f, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0xc0, 0xc0, 0xe0, 0x10, 0x00, 0x40, 0xc0, 0x40,
-+ 0x00, 0x08, 0x10, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x67, 0x73, 0x13, 0x13, 0x13, 0x0f, 0x0b,
-+ 0x13, 0x33, 0x23, 0x77, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x98, 0x38, 0x20, 0x20, 0x20, 0xc0, 0x40,
-+ 0x20, 0x30, 0x10, 0xb8, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x07, 0x1c, 0x10, 0x00, 0x00, 0x03, 0x00,
-+ 0x00, 0x10, 0x1c, 0x07, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x30, 0x30, 0x60, 0xc0, 0x60,
-+ 0x30, 0x30, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x19, 0x1a,
-+ 0x1c, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x30, 0x30, 0x70, 0xb0, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x06, 0x03, 0x3c, 0x18, 0x18, 0x18, 0x19, 0x1a,
-+ 0x1c, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-+ 0xc0, 0x80, 0x78, 0x30, 0x70, 0xb0, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x18, 0x18, 0x18, 0x19, 0x1f, 0x19,
-+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x38, 0x58, 0x80, 0x80, 0x00, 0x00, 0x80,
-+ 0xc0, 0x60, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x07, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
-+ 0x02, 0x34, 0x34, 0x18, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x38, 0x18, 0x18, 0x1c, 0x1c, 0x17, 0x26,
-+ 0x22, 0x22, 0x20, 0x70, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x70, 0x60, 0x60, 0xe0, 0xe0, 0x60, 0x30,
-+ 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18,
-+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0xf0, 0x30,
-+ 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x30, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x30, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x30, 0x30, 0x60, 0x80, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xd0, 0x30, 0x10, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x23, 0x43, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06,
-+ 0x03, 0x03, 0x01, 0x19, 0x1a, 0x0c, 0x00, 0x00,
-+ 0x00, 0x78, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40,
-+ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x03, 0x07, 0x1b, 0x33, 0x33, 0x33,
-+ 0x1b, 0x07, 0x03, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xc0, 0x00, 0x80, 0x60, 0x30, 0x30, 0x30,
-+ 0x60, 0x80, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x18, 0x0c, 0x06, 0x03, 0x03, 0x03,
-+ 0x04, 0x08, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x20, 0x40, 0x80, 0x00, 0x00, 0x80,
-+ 0xc0, 0x60, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x18, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0xf8, 0x18, 0x08, 0x00, 0x00,
-+ 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0f,
-+ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0xe0,
-+ 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x77, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-+ 0x33, 0x33, 0x33, 0x7f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xb8, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x77, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
-+ 0x33, 0x33, 0x33, 0x7f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xb8, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0xf8, 0x18, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x26, 0x46, 0x06, 0x07, 0x06, 0x06,
-+ 0x06, 0x06, 0x06, 0x1f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x30, 0x18,
-+ 0x18, 0x18, 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x18, 0x18, 0x18, 0x1e, 0x19, 0x18,
-+ 0x18, 0x18, 0x19, 0x3e, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, 0xb0, 0xf0,
-+ 0xf0, 0xf0, 0xb0, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0c, 0x0c, 0x0c, 0x0f, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x30,
-+ 0x30, 0x30, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x07, 0x1c, 0x10, 0x00, 0x06, 0x0b, 0x00,
-+ 0x00, 0x10, 0x1c, 0x07, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x30, 0x10, 0x18, 0xb8, 0xd8,
-+ 0x10, 0x30, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x33, 0x32, 0x36, 0x36, 0x3e, 0x36,
-+ 0x36, 0x32, 0x33, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xc0, 0x30, 0x10, 0x18, 0x18, 0x18, 0x18,
-+ 0x18, 0x10, 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x0c, 0x18, 0x18, 0x18, 0x0c, 0x07,
-+ 0x03, 0x06, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0,
-+ 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x0c, 0x0c, 0x03,
-+ 0x0c, 0x18, 0x18, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x60, 0xe0,
-+ 0x60, 0x60, 0xe0, 0x30, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x03, 0x04, 0x05, 0x0e, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0xe0, 0xc0, 0x00, 0x80, 0x60, 0x30, 0x30,
-+ 0x30, 0x30, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x0c, 0x0c, 0x0f,
-+ 0x0c, 0x0c, 0x0c, 0x1f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x60, 0xc0,
-+ 0x20, 0x30, 0x30, 0xe0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x0c, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0c, 0x1f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x20, 0x10, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x0f, 0x04, 0x04, 0x04,
-+ 0x04, 0x04, 0x08, 0x3f, 0x20, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60,
-+ 0x60, 0x60, 0x60, 0xe0, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x18, 0x1f,
-+ 0x18, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x30, 0xf0,
-+ 0x00, 0x10, 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x06, 0x06, 0x00, 0x07, 0x08, 0x18, 0x1f,
-+ 0x18, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x60, 0x60, 0x00, 0xc0, 0x20, 0x30, 0xf0,
-+ 0x00, 0x10, 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x67, 0x73, 0x0b, 0x0f,
-+ 0x0b, 0x13, 0x33, 0x67, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x98, 0x38, 0x40, 0xc0,
-+ 0x40, 0x20, 0x30, 0x98, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x10, 0x03,
-+ 0x00, 0x10, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x60, 0xc0,
-+ 0x60, 0x60, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x19,
-+ 0x1a, 0x1c, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0xe0, 0x60,
-+ 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x06, 0x03, 0x00, 0x3c, 0x18, 0x18, 0x19,
-+ 0x1a, 0x1c, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xc0, 0x80, 0x00, 0xf0, 0x60, 0xe0, 0x60,
-+ 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x19, 0x1f,
-+ 0x19, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xe0, 0x00, 0x00,
-+ 0x80, 0xc0, 0x60, 0x70, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x02, 0x02, 0x02,
-+ 0x02, 0x34, 0x34, 0x18, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60,
-+ 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x38, 0x1c, 0x1c, 0x16,
-+ 0x16, 0x13, 0x13, 0x38, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x38, 0x70, 0x70, 0xb0,
-+ 0xb0, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x1f,
-+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0xe0,
-+ 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x18, 0x18,
-+ 0x18, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x30, 0x30,
-+ 0x30, 0x30, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60,
-+ 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1d, 0x0e, 0x0c, 0x0c,
-+ 0x0c, 0x0c, 0x0e, 0x0d, 0x0c, 0x1e, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x30, 0x30,
-+ 0x30, 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x18, 0x18,
-+ 0x18, 0x18, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x20, 0x00,
-+ 0x00, 0x20, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x13, 0x23, 0x03,
-+ 0x03, 0x03, 0x03, 0x07, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x20, 0x10, 0x00,
-+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x0c, 0x06, 0x06,
-+ 0x03, 0x03, 0x01, 0x19, 0x19, 0x0e, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x70, 0x20, 0x20, 0x40,
-+ 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x03, 0x03, 0x1b, 0x37, 0x63, 0x63,
-+ 0x63, 0x63, 0x37, 0x1b, 0x03, 0x07, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x60, 0xb0, 0x18, 0x18,
-+ 0x18, 0x18, 0xb0, 0x60, 0x00, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 0x06, 0x03,
-+ 0x03, 0x04, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x70, 0x20, 0x40, 0x80,
-+ 0x80, 0xc0, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18,
-+ 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60,
-+ 0x60, 0x60, 0x60, 0xf0, 0x30, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18,
-+ 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60,
-+ 0xe0, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x77, 0x33, 0x33, 0x33,
-+ 0x33, 0x33, 0x33, 0x7f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x78, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x77, 0x33, 0x33, 0x33,
-+ 0x33, 0x33, 0x33, 0x7f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x78, 0x30, 0x30, 0x30,
-+ 0x30, 0x30, 0x30, 0xf8, 0x18, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x3f, 0x26, 0x46, 0x07,
-+ 0x06, 0x06, 0x06, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
-+ 0x30, 0x30, 0x30, 0xe0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x1f,
-+ 0x19, 0x19, 0x19, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x78, 0x30, 0x30, 0x30,
-+ 0xb0, 0xb0, 0xb0, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0f,
-+ 0x0c, 0x0c, 0x0c, 0x1f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
-+ 0x30, 0x30, 0x30, 0xe0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x10, 0x03,
-+ 0x05, 0x10, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x60, 0x30, 0x70,
-+ 0xb0, 0x30, 0x60, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0x19, 0x1b, 0x1f,
-+ 0x1b, 0x1b, 0x19, 0x3c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0x18, 0x18,
-+ 0x18, 0x18, 0x10, 0xe0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x18, 0x18,
-+ 0x0f, 0x06, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60,
-+ 0xe0, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xff, 0xff,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xff, 0xff,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xff, 0xff,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xff, 0xff,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xff,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xff,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xff,
-+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x04, 0x04, 0x3f, 0x24, 0x24, 0x24,
-+ 0x3f, 0x24, 0x04, 0x04, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x80, 0x80, 0xf0, 0x90, 0x90, 0x90,
-+ 0xf0, 0x90, 0x80, 0x80, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x48, 0x4b, 0x4a, 0x4a, 0x4a,
-+ 0x4b, 0x7a, 0x48, 0x40, 0x0f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xa0, 0xf8, 0xa8, 0xa8, 0xa8,
-+ 0xf8, 0xa8, 0xa0, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7e, 0x12, 0x13, 0x12,
-+ 0x3c, 0x24, 0x06, 0x0a, 0x11, 0x20, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x28, 0x31, 0x29, 0x25, 0x25,
-+ 0x25, 0x25, 0x38, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0x08, 0xe8, 0x28, 0x28, 0x28,
-+ 0xe8, 0x28, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x00, 0x0f, 0x08, 0x08, 0x0f,
-+ 0x03, 0x0c, 0x74, 0x04, 0x07, 0x38, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xe0, 0x20, 0x20, 0xe8,
-+ 0x08, 0x90, 0xa0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x12, 0x09, 0x3f, 0x25, 0x54, 0x13,
-+ 0x22, 0x07, 0x3a, 0x01, 0x06, 0x78, 0x00, 0x00,
-+ 0x30, 0xd0, 0x10, 0x20, 0xfc, 0x88, 0x50, 0xc8,
-+ 0x08, 0xe0, 0x40, 0x80, 0xe0, 0x1c, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x79, 0x17, 0x11, 0x11, 0x1a,
-+ 0x74, 0x17, 0x10, 0x10, 0x13, 0x3c, 0x00, 0x00,
-+ 0x80, 0xa0, 0x90, 0x38, 0xc8, 0x00, 0xf8, 0x40,
-+ 0x40, 0xfc, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7e, 0x12, 0x13, 0x12,
-+ 0x32, 0x2c, 0x04, 0x0a, 0x10, 0x60, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x50, 0x50, 0x88, 0xfc, 0x00,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x21, 0x16, 0x10, 0x01, 0x0e, 0x73, 0x10,
-+ 0x13, 0x10, 0x17, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x80, 0xf8, 0x90, 0x60, 0xf0, 0x4c, 0xf8, 0x40,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0xfc, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x07, 0x11, 0x0a, 0x04, 0x1f,
-+ 0x61, 0x1f, 0x01, 0x02, 0x0c, 0x30, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x20, 0x28, 0xc8, 0x50, 0xf0,
-+ 0x0c, 0xf0, 0x00, 0x80, 0x60, 0x18, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x7f, 0x04, 0x3f, 0x24,
-+ 0x24, 0x28, 0x30, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xfc, 0x80, 0xf8, 0x88,
-+ 0x98, 0x78, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x19, 0x76, 0x11, 0x11, 0x7d, 0x11, 0x1b,
-+ 0x36, 0x37, 0x52, 0x13, 0x12, 0x10, 0x00, 0x00,
-+ 0x40, 0xf0, 0x20, 0xf0, 0x50, 0xf0, 0xf0, 0xf8,
-+ 0x48, 0xf8, 0x48, 0xfc, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x02, 0x1f, 0x12, 0x1f, 0x02, 0x7f,
-+ 0x01, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xf8, 0x80, 0xf0, 0x90, 0xf0, 0x80, 0xfc,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x13, 0x12, 0x1a,
-+ 0x73, 0x14, 0x17, 0x18, 0x17, 0x30, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x00, 0xf8, 0x60, 0x90,
-+ 0xe8, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x43, 0x22, 0x23, 0x02, 0x02,
-+ 0x13, 0x12, 0x25, 0x24, 0x4f, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x00, 0xfc, 0x50, 0x98,
-+ 0xe4, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7e, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x12, 0x12, 0x22, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88,
-+ 0x88, 0xf8, 0x88, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x0f, 0x02, 0x7f, 0x0f, 0x08,
-+ 0x0f, 0x0f, 0x08, 0x7f, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xe0, 0x20, 0xfc, 0xe0, 0x20,
-+ 0xe0, 0xf0, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x3f, 0x00, 0x1f, 0x10,
-+ 0x10, 0x1f, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x00, 0xf0, 0x10,
-+ 0x10, 0xf0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x25, 0x7e, 0x2b, 0x3e, 0x2a,
-+ 0x3f, 0x04, 0x3a, 0x2e, 0x28, 0x41, 0x00, 0x00,
-+ 0x20, 0x30, 0x48, 0xf4, 0x20, 0xfc, 0x50, 0x98,
-+ 0x64, 0x10, 0x64, 0x08, 0x30, 0xc0, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7e, 0x08, 0x1c, 0x1b, 0x1a,
-+ 0x28, 0x29, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x48, 0x50, 0xfc, 0x20,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x17, 0x10,
-+ 0x10, 0x10, 0x20, 0x20, 0x4f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0x80, 0x80, 0xf8, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3f, 0x22, 0x3e, 0x22,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x88, 0x54, 0x30, 0x90, 0x50,
-+ 0x50, 0x1c, 0xf0, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x13, 0x11, 0x7d, 0x11, 0x11, 0x11, 0x1d,
-+ 0x72, 0x12, 0x12, 0x14, 0x15, 0x3e, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x20, 0x20, 0xf8, 0x88, 0x88,
-+ 0x50, 0x50, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x28, 0x48, 0x0e, 0x12, 0x12,
-+ 0x2a, 0x44, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x00, 0xf8, 0x88, 0x88,
-+ 0x88, 0xb0, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7e, 0x12, 0x12, 0x12,
-+ 0x3c, 0x24, 0x06, 0x08, 0x13, 0x60, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88,
-+ 0xf8, 0x88, 0x88, 0x88, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2b, 0x2a, 0x2a, 0x3e,
-+ 0x28, 0x0c, 0x0a, 0x0f, 0x71, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x78, 0x00, 0x00,
-+ 0x08, 0x0c, 0x12, 0x2a, 0x48, 0x3e, 0x23, 0x3e,
-+ 0x22, 0x3e, 0x24, 0x26, 0x3a, 0x60, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x50, 0x48, 0x9c, 0xe4, 0x00,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x11, 0x11, 0x15, 0x65, 0x1a, 0x13, 0x29, 0x7d,
-+ 0x15, 0x19, 0x35, 0x34, 0x50, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0xe8, 0x28, 0xe8,
-+ 0x28, 0xe8, 0x28, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x64, 0x1f, 0x10, 0x29, 0x7e,
-+ 0x14, 0x39, 0x36, 0x34, 0x51, 0x16, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xfc, 0xa0, 0x24, 0x9c,
-+ 0xf0, 0x90, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x20, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x7f, 0x00, 0x1e, 0x12, 0x12,
-+ 0x1e, 0x10, 0x03, 0x0c, 0x71, 0x06, 0x00, 0x00,
-+ 0x90, 0x88, 0x88, 0xfc, 0x80, 0x88, 0x88, 0x48,
-+ 0x50, 0x30, 0x24, 0x54, 0x8c, 0x04, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x1f, 0x12, 0x12, 0x1f, 0x09,
-+ 0x05, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0xf0, 0x90, 0x90, 0xf0, 0x20,
-+ 0x40, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x09, 0x0b, 0x12, 0x3c,
-+ 0x55, 0x13, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xf8, 0x04, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x22, 0x42, 0x02, 0x7f, 0x04,
-+ 0x04, 0x0f, 0x08, 0x01, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x00, 0x00, 0xfc, 0x40,
-+ 0x40, 0x40, 0xc0, 0x20, 0x10, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x11, 0x1f, 0x12, 0x14, 0x1f,
-+ 0x14, 0x17, 0x24, 0x27, 0x44, 0x00, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xfc, 0xa0, 0x90, 0xfc,
-+ 0x90, 0xf0, 0x90, 0xf0, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x14, 0x10, 0x17, 0x18,
-+ 0x70, 0x11, 0x11, 0x10, 0x10, 0x37, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0x40, 0x40, 0xfc, 0x90,
-+ 0x90, 0x90, 0x60, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x49, 0x48, 0x4f, 0x78, 0x49,
-+ 0x49, 0x49, 0x79, 0x49, 0x41, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x10, 0xa0, 0xfc, 0x00, 0xf0,
-+ 0x10, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x22, 0x7f, 0x04, 0x0f, 0x03,
-+ 0x1d, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0xf8, 0x40, 0x80, 0x60,
-+ 0x10, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x3e, 0x21, 0x2f, 0x22,
-+ 0x3f, 0x27, 0x24, 0x27, 0x27, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0xf8, 0x08, 0xe8, 0x88,
-+ 0xf8, 0xc8, 0x48, 0xc8, 0xc8, 0x58, 0x00, 0x00,
-+ 0x14, 0x14, 0x7f, 0x14, 0x1d, 0x08, 0x3f, 0x2a,
-+ 0x3e, 0x08, 0x7e, 0x08, 0x08, 0x09, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x20, 0x20, 0xfc, 0x48,
-+ 0x48, 0xf0, 0x90, 0x28, 0x44, 0x84, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01,
-+ 0x1f, 0x10, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0x12, 0x11, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x16, 0x18, 0x61, 0x06, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0x90, 0x90, 0x10, 0x10,
-+ 0x10, 0x30, 0x28, 0x48, 0x84, 0x04, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x10, 0x17, 0x30, 0x50, 0x13,
-+ 0x10, 0x10, 0x10, 0x10, 0x11, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xfc, 0x48, 0x48, 0xf8,
-+ 0x48, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x10, 0x1f, 0x30, 0x52, 0x11,
-+ 0x11, 0x11, 0x11, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0x80, 0xfc, 0x10, 0x10, 0x10,
-+ 0x10, 0x20, 0x20, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x17, 0x10, 0x30, 0x51, 0x13,
-+ 0x15, 0x11, 0x11, 0x11, 0x11, 0x16, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x80, 0xc8, 0x48, 0x50,
-+ 0x20, 0x20, 0x10, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x17, 0x10, 0x33, 0x52, 0x13,
-+ 0x10, 0x13, 0x12, 0x1f, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0xf0, 0x90, 0xfc, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x20, 0xf8, 0x20, 0xfc, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x22, 0x22, 0x2f, 0x22, 0x22,
-+ 0x3f, 0x22, 0x24, 0x28, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x48, 0x48, 0xe8, 0x48, 0x48,
-+ 0xf8, 0x48, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x3f, 0x01, 0x3f, 0x21,
-+ 0x3f, 0x23, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x00,
-+ 0xfc, 0x04, 0x84, 0x58, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x7f, 0x03, 0x0d, 0x71, 0x02,
-+ 0x7f, 0x04, 0x0f, 0x10, 0x03, 0x3c, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00,
-+ 0xfc, 0x40, 0x40, 0xc0, 0x30, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x1f, 0x12, 0x1f, 0x14,
-+ 0x14, 0x1f, 0x11, 0x22, 0x2c, 0x40, 0x00, 0x00,
-+ 0x50, 0x48, 0xfc, 0x40, 0xc8, 0x48, 0xc8, 0xd0,
-+ 0xb0, 0x30, 0x24, 0xd4, 0x8c, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x3f, 0x20, 0x3e, 0x20, 0x3f,
-+ 0x24, 0x2e, 0x2d, 0x35, 0x44, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0xfc, 0x08, 0x48, 0x28,
-+ 0x28, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x19, 0x37, 0x35, 0x31, 0x51,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x90, 0x90, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x3f, 0x04, 0x7f, 0x00, 0x0f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x25, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xfc, 0x00, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x08, 0x84, 0x24, 0xe0, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x3f, 0x2e, 0x20, 0x3f, 0x56,
-+ 0x25, 0x4d, 0x04, 0x24, 0x24, 0x43, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0xfc, 0x90, 0x50, 0x50, 0x10,
-+ 0x10, 0x30, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x02, 0x07,
-+ 0x19, 0x62, 0x0c, 0x31, 0x06, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x00, 0xf8,
-+ 0x28, 0x48, 0x88, 0x08, 0x10, 0xe0, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7e, 0x08, 0x1c, 0x1b, 0x1a,
-+ 0x29, 0x29, 0x49, 0x09, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x60, 0x50, 0x88, 0xfc, 0x08,
-+ 0xe8, 0x28, 0xe8, 0x28, 0x08, 0x18, 0x00, 0x00,
-+ 0x11, 0x09, 0x09, 0x3f, 0x02, 0x02, 0x07, 0x04,
-+ 0x0f, 0x08, 0x15, 0x32, 0x4a, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xe0, 0x20, 0x40, 0xf0, 0x10,
-+ 0xfc, 0x04, 0x44, 0xa4, 0xa4, 0x18, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x00, 0x7f,
-+ 0x09, 0x08, 0x08, 0x0b, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x10, 0x90, 0xa0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x04, 0x3f,
-+ 0x04, 0x04, 0x7f, 0x02, 0x0c, 0x30, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x40, 0xf8,
-+ 0x40, 0x40, 0xfc, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x02, 0x0c, 0x38, 0x09, 0x08, 0x7e, 0x09, 0x1c,
-+ 0x1a, 0x2a, 0x49, 0x08, 0x08, 0x0b, 0x00, 0x00,
-+ 0x40, 0x78, 0x88, 0x50, 0x20, 0x40, 0xa0, 0x3c,
-+ 0x44, 0xa8, 0x18, 0x10, 0x60, 0x80, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x15, 0x08, 0x14, 0x7e,
-+ 0x0a, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x48, 0x48, 0x90, 0xfc, 0x90, 0x90, 0xf8, 0x90,
-+ 0x90, 0xf8, 0x90, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x08, 0x09, 0x0a, 0x73, 0x14, 0x0c, 0x12, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2b, 0x48, 0x08, 0x00, 0x00,
-+ 0x20, 0xf8, 0x48, 0xfc, 0x00, 0xf8, 0x88, 0xf8,
-+ 0x10, 0xf8, 0x90, 0xfc, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x3f, 0x21, 0x3f, 0x00, 0x1f,
-+ 0x10, 0x1f, 0x10, 0x1f, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x00, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x1f, 0x01, 0x7f, 0x05, 0x19,
-+ 0x62, 0x3f, 0x04, 0x0f, 0x03, 0x3c, 0x00, 0x00,
-+ 0x40, 0xfc, 0x60, 0xc0, 0x00, 0xfc, 0x40, 0x30,
-+ 0x0c, 0xf8, 0x40, 0x80, 0x60, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x7f, 0x01, 0x03, 0x04, 0x1c,
-+ 0x64, 0x04, 0x04, 0x05, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x08, 0x88, 0x90,
-+ 0x60, 0x40, 0x20, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x3d, 0x01, 0x7f, 0x01, 0x3d, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x00, 0xfc, 0x24, 0xfc, 0x24, 0xfc, 0x00, 0xf8,
-+ 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x98, 0x00, 0x00,
-+ 0x00, 0x23, 0x10, 0x17, 0x01, 0x01, 0x71, 0x10,
-+ 0x11, 0x11, 0x17, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0xf0, 0x90, 0xfc, 0xf0, 0x10, 0xf0, 0x20,
-+ 0xf8, 0x20, 0xfc, 0x20, 0x20, 0xfc, 0x00, 0x00,
-+ 0x00, 0x21, 0x11, 0x11, 0x07, 0x01, 0x71, 0x11,
-+ 0x11, 0x11, 0x11, 0x1b, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0xf0, 0x50, 0xf0, 0xfc, 0xf0, 0x10, 0xf0,
-+ 0xf0, 0x10, 0xf0, 0x10, 0x08, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x22, 0x27, 0x24, 0x28, 0x3f,
-+ 0x21, 0x21, 0x22, 0x2c, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0xf0, 0x80, 0x80, 0xf8,
-+ 0x40, 0x20, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x04, 0x3f, 0x04, 0x04, 0x04,
-+ 0x7f, 0x04, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0x40,
-+ 0xfc, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x02, 0x1a, 0x04, 0x03,
-+ 0x02, 0x0c, 0x11, 0x06, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0x40, 0x40, 0x90, 0x20,
-+ 0x40, 0xc0, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x17, 0x10, 0x7f, 0x12, 0x12,
-+ 0x13, 0x16, 0x18, 0x63, 0x0c, 0x00, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0xfc, 0x40, 0xc8, 0xc8, 0xa8,
-+ 0xa8, 0x30, 0x94, 0x34, 0x4c, 0x84, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x02, 0x04, 0x3f, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x20, 0x70, 0x88, 0xe0, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x08, 0x08, 0x1f, 0x11, 0x3f,
-+ 0x51, 0x1f, 0x11, 0x11, 0x11, 0x13, 0x00, 0x00,
-+ 0x00, 0x78, 0xc8, 0x50, 0x50, 0x60, 0x50, 0x48,
-+ 0x44, 0x44, 0x64, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x7d, 0x12, 0x16, 0x11, 0x3a, 0x2f, 0x68,
-+ 0x2b, 0x2b, 0x3a, 0x2a, 0x04, 0x08, 0x00, 0x00,
-+ 0x50, 0x50, 0x68, 0xd8, 0x50, 0xe8, 0xfc, 0x50,
-+ 0xfc, 0x28, 0xa8, 0x94, 0x2c, 0xc4, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x1f, 0x00, 0x3f, 0x24,
-+ 0x44, 0x07, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x00, 0xfc, 0x08,
-+ 0x60, 0x80, 0x00, 0x08, 0x08, 0xf8, 0x00, 0x00,
-+ 0x24, 0x12, 0x12, 0x4f, 0x22, 0x22, 0x04, 0x1f,
-+ 0x15, 0x15, 0x25, 0x25, 0x5f, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xfc, 0x20, 0x20, 0x10, 0xf8,
-+ 0x54, 0x50, 0x50, 0x50, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x20, 0x11, 0x12, 0x07, 0x02, 0x72, 0x13,
-+ 0x12, 0x10, 0x11, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x80, 0xf0, 0x20, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0xc8, 0xc0, 0x44, 0x3c, 0x00, 0xfc, 0x00, 0x00,
-+ 0x02, 0x0f, 0x3a, 0x09, 0x09, 0x7e, 0x19, 0x1d,
-+ 0x2b, 0x2b, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x18, 0xe4, 0x44, 0x28, 0x30, 0x00, 0x78, 0x48,
-+ 0x48, 0x78, 0x48, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x05, 0x21, 0x11, 0x11,
-+ 0x02, 0x04, 0x18, 0x61, 0x06, 0x18, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x00, 0xfc, 0x48,
-+ 0x50, 0x40, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x00, 0x1f, 0x01, 0x01,
-+ 0x7f, 0x01, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf0, 0x00, 0x00,
-+ 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x1e, 0x24, 0x7f, 0x2b, 0x3f, 0x2a,
-+ 0x3f, 0x04, 0x3a, 0x2f, 0x28, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x20, 0xf8, 0x48,
-+ 0x68, 0xd8, 0xd8, 0x68, 0x48, 0xb0, 0x00, 0x00,
-+ 0x02, 0x02, 0x04, 0x08, 0x7f, 0x04, 0x04, 0x04,
-+ 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0x40, 0x30, 0x68, 0x84, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x01, 0x06, 0x38, 0x20, 0x20, 0x3e, 0x20, 0x20,
-+ 0x20, 0x3e, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0xf0, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4a, 0x4a, 0x4b, 0x4a, 0x4a,
-+ 0x4a, 0x7a, 0x4b, 0x42, 0x03, 0x02, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0xf8, 0x48, 0x48,
-+ 0xa8, 0x98, 0x18, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0f, 0x00, 0x1f, 0x10, 0x1f,
-+ 0x10, 0x1f, 0x10, 0x1f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x60, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x21, 0x21, 0x3f, 0x21, 0x23,
-+ 0x22, 0x24, 0x28, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x08,
-+ 0x88, 0x48, 0x28, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x11, 0x7d, 0x25, 0x25, 0x25,
-+ 0x79, 0x49, 0x0d, 0x15, 0x21, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0xf8, 0x48, 0x48,
-+ 0x68, 0x98, 0x98, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x01, 0x3f, 0x21, 0x20, 0x3f,
-+ 0x21, 0x01, 0x01, 0x01, 0x02, 0x1c, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x1a, 0x29, 0x7e, 0x23, 0x3e,
-+ 0x22, 0x3e, 0x28, 0x24, 0x3b, 0x62, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa8, 0x30, 0x20,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x44, 0x22, 0x22, 0x03, 0x10,
-+ 0x10, 0x13, 0x20, 0x20, 0x4f, 0x40, 0x00, 0x00,
-+ 0x0c, 0x74, 0x84, 0x88, 0x50, 0x38, 0xc0, 0x40,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x11, 0x1e, 0x12, 0x11, 0x1f, 0x10, 0x17,
-+ 0x14, 0x17, 0x14, 0x27, 0x24, 0x44, 0x00, 0x00,
-+ 0x10, 0x50, 0x50, 0x90, 0x50, 0xf0, 0x30, 0xd0,
-+ 0x50, 0xd0, 0x50, 0xd4, 0x54, 0xcc, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3c, 0x27, 0x2c, 0x31, 0x28,
-+ 0x25, 0x24, 0x27, 0x38, 0x21, 0x23, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xa0, 0xf0, 0x0c, 0xf0, 0x20,
-+ 0xf8, 0x00, 0xfc, 0xa0, 0x30, 0xc8, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x2a, 0x30, 0x2b, 0x24, 0x27,
-+ 0x24, 0x24, 0x39, 0x21, 0x22, 0x24, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0x00, 0xf8, 0x00, 0xfc,
-+ 0xa0, 0xa0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x29, 0x32, 0x28, 0x25, 0x24,
-+ 0x25, 0x24, 0x3f, 0x20, 0x21, 0x27, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xe8, 0x04, 0xf0, 0x20,
-+ 0xf0, 0x00, 0xfc, 0xa0, 0x30, 0xc8, 0x00, 0x00,
-+ 0x00, 0x3f, 0x26, 0x29, 0x31, 0x28, 0x25, 0x24,
-+ 0x25, 0x24, 0x3a, 0x22, 0x24, 0x20, 0x00, 0x00,
-+ 0x18, 0xe4, 0x44, 0x28, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x40, 0xa8, 0xa4, 0x94, 0x70, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x22, 0x14, 0x7f, 0x00, 0x3c,
-+ 0x24, 0x3c, 0x24, 0x24, 0x3c, 0x27, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x00, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x88, 0xf8, 0xc8, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x48, 0x4f, 0x48, 0x49, 0x48,
-+ 0x48, 0x78, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0xfc, 0x10, 0x10, 0x90,
-+ 0x90, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x7f, 0x04, 0x04, 0x08, 0x0f,
-+ 0x18, 0x18, 0x28, 0x48, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xf0,
-+ 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x40, 0x1f, 0x01, 0x01,
-+ 0x7f, 0x01, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x00, 0xf0, 0x00, 0x00,
-+ 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x02, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x29, 0x24, 0x24, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x00, 0xfc,
-+ 0x00, 0xf8, 0x48, 0xa8, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x02, 0x22, 0x12, 0x12, 0x02,
-+ 0x06, 0x1a, 0x63, 0x02, 0x02, 0x06, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x88, 0x48, 0x48, 0x08,
-+ 0x18, 0x68, 0x88, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x23, 0x10, 0x10, 0x00, 0x07, 0x70, 0x10,
-+ 0x10, 0x10, 0x10, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0xc0, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x01, 0x3f, 0x29, 0x25, 0x25,
-+ 0x21, 0x29, 0x25, 0x25, 0x21, 0x21, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x48, 0x28, 0x28,
-+ 0x08, 0x48, 0x28, 0x28, 0x08, 0x18, 0x00, 0x00,
-+ 0x02, 0x0c, 0x30, 0x22, 0x22, 0x22, 0x22, 0x22,
-+ 0x22, 0x3e, 0x64, 0x04, 0x08, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0xf0, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x24, 0x14, 0x18, 0x7e, 0x0a, 0x3e, 0x28, 0x3e,
-+ 0x3a, 0x1a, 0x2e, 0x49, 0x09, 0x0a, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x01, 0x3f, 0x24, 0x48, 0x19, 0x09, 0x3f, 0x09,
-+ 0x7f, 0x09, 0x15, 0x14, 0x21, 0x46, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0x78, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x02, 0x02, 0x02, 0x02, 0x3f, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7e, 0x10, 0x11, 0x11, 0x3f, 0x25, 0x65,
-+ 0x25, 0x25, 0x3d, 0x25, 0x21, 0x01, 0x00, 0x00,
-+ 0x90, 0x90, 0xa0, 0xfc, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x06, 0x38, 0x20, 0x20, 0x20, 0x20, 0x3e,
-+ 0x20, 0x20, 0x20, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x22, 0x22, 0x07, 0x14,
-+ 0x15, 0x15, 0x25, 0x25, 0x44, 0x44, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x90, 0x90, 0xf8, 0x08,
-+ 0xe8, 0x28, 0xe8, 0x28, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x70, 0x57, 0x54, 0x57, 0x54, 0x54,
-+ 0x56, 0x75, 0x49, 0x08, 0x17, 0x00, 0x00, 0x00,
-+ 0x80, 0xf8, 0x80, 0xfc, 0xf8, 0x88, 0x78, 0xa0,
-+ 0xa8, 0xa8, 0xb0, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x3d, 0x25, 0x25, 0x25, 0x25, 0x25,
-+ 0x25, 0x3d, 0x25, 0x20, 0x03, 0x0c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x08, 0xf8,
-+ 0x08, 0x08, 0xf8, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x12, 0x7d, 0x3a, 0x55, 0x1f, 0x12, 0x1f, 0x3e,
-+ 0x23, 0x3e, 0x3e, 0x24, 0x3e, 0x60, 0x00, 0x00,
-+ 0x90, 0xfc, 0xb8, 0xd4, 0xf0, 0x90, 0xf0, 0x10,
-+ 0xfc, 0x90, 0x50, 0x50, 0x10, 0x30, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3f, 0x21, 0x3f, 0x20, 0x2e,
-+ 0x20, 0x3f, 0x2e, 0x2d, 0x55, 0x0c, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x08, 0x08, 0xfc, 0x08, 0x48,
-+ 0x28, 0x28, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2a, 0x3f, 0x2b,
-+ 0x3f, 0x04, 0x3a, 0x2e, 0x28, 0x43, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc, 0x54,
-+ 0xfc, 0xf8, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x10, 0x7c, 0x27, 0x24, 0x24,
-+ 0x78, 0x49, 0x0e, 0x14, 0x20, 0x40, 0x00, 0x00,
-+ 0x40, 0x48, 0xf8, 0x50, 0x50, 0xfc, 0x20, 0xc0,
-+ 0x98, 0xe0, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x2f, 0x29, 0x2f, 0x29, 0x2f,
-+ 0x28, 0x2a, 0x29, 0x2b, 0x4c, 0x31, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x78, 0x50, 0x50, 0x50, 0xfc,
-+ 0x30, 0x30, 0x50, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x40, 0x23, 0x22, 0x02, 0x0b,
-+ 0x0a, 0x0a, 0x13, 0x12, 0x22, 0x22, 0x00, 0x00,
-+ 0x50, 0x48, 0xfc, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x11, 0x11, 0x2e, 0x40, 0x00, 0x00,
-+ 0x10, 0xe0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x10, 0x90, 0x50, 0xe8, 0x28, 0x04, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x20, 0x2f,
-+ 0x21, 0x27, 0x21, 0x2f, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0xe8,
-+ 0x08, 0xc8, 0x08, 0xe8, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x00, 0x7f, 0x48, 0x4b, 0x4a, 0x4b, 0x4b,
-+ 0x4b, 0x78, 0x4f, 0x41, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0xa0, 0xfc, 0xa0, 0xf8, 0xa8, 0x38, 0xf8,
-+ 0xf8, 0x10, 0xfc, 0x10, 0x90, 0x30, 0x00, 0x00,
-+ 0x00, 0x1f, 0x00, 0x00, 0x00, 0x7f, 0x01, 0x01,
-+ 0x01, 0x02, 0x02, 0x04, 0x3f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x40, 0x20, 0x10, 0x70, 0x88, 0x08, 0x00, 0x00,
-+ 0x00, 0x27, 0x14, 0x1f, 0x00, 0x03, 0x72, 0x13,
-+ 0x12, 0x13, 0x10, 0x17, 0x2c, 0x43, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xfc, 0x40, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xf8, 0x40, 0xfc, 0x40, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x21, 0x3d, 0x4f, 0x00,
-+ 0x1f, 0x00, 0x7f, 0x02, 0x04, 0x3f, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x04, 0x78, 0x38, 0x00,
-+ 0xf0, 0x00, 0xfc, 0x20, 0xf0, 0x08, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x0b, 0x10, 0x10,
-+ 0x37, 0x50, 0x10, 0x10, 0x13, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x18, 0xe0, 0x40, 0x40,
-+ 0xfc, 0x40, 0x40, 0x40, 0xf8, 0x00, 0x00, 0x00,
-+ 0x08, 0x0d, 0x12, 0x2a, 0x48, 0x3e, 0x22, 0x3e,
-+ 0x22, 0x3e, 0x24, 0x27, 0x3a, 0x60, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0x48, 0x78, 0x48, 0x48, 0x78,
-+ 0x48, 0x4c, 0x78, 0x88, 0x08, 0x08, 0x00, 0x00,
-+ 0x0e, 0x08, 0x7f, 0x5d, 0x5a, 0x2d, 0x52, 0x1f,
-+ 0x32, 0x5e, 0x12, 0x1e, 0x12, 0x1f, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x48, 0x48, 0x50, 0x50, 0x30,
-+ 0x20, 0x30, 0x50, 0x48, 0x88, 0x04, 0x00, 0x00,
-+ 0x12, 0x09, 0x3f, 0x20, 0x4f, 0x08, 0x08, 0x0f,
-+ 0x02, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x10, 0x20, 0xfc, 0x08, 0xe0, 0x20, 0x20, 0xe0,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x22, 0x3e,
-+ 0x15, 0x7f, 0x04, 0x0f, 0x01, 0x3e, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0xf8,
-+ 0x50, 0xfc, 0x20, 0x40, 0xe0, 0x18, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x04, 0x7f,
-+ 0x1f, 0x11, 0x1f, 0x15, 0x64, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0x20, 0x48, 0x08, 0x10, 0x90,
-+ 0x24, 0x04, 0x08, 0x08, 0x90, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x4b, 0x4a, 0x4a, 0x7a, 0x4f,
-+ 0x48, 0x48, 0x78, 0x49, 0x02, 0x0c, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0xfc,
-+ 0x40, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x01, 0x1f, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x1f,
-+ 0x11, 0x00, 0x00, 0x03, 0x3c, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x10, 0xf8,
-+ 0x10, 0xa0, 0xc0, 0x44, 0x34, 0x0c, 0x00, 0x00,
-+ 0x12, 0x09, 0x09, 0x3f, 0x20, 0x41, 0x01, 0x7f,
-+ 0x03, 0x05, 0x19, 0x61, 0x01, 0x01, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xfc, 0x08, 0x00, 0x00, 0xfc,
-+ 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00,
-+ 0x03, 0x00, 0x00, 0x0f, 0x01, 0x01, 0x7f, 0x05,
-+ 0x05, 0x09, 0x11, 0x61, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0x80, 0x00, 0x00, 0x08, 0x88, 0x90, 0x60,
-+ 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x43, 0x20, 0x20, 0x07, 0x10,
-+ 0x11, 0x11, 0x22, 0x24, 0x40, 0x40, 0x00, 0x00,
-+ 0xc0, 0x20, 0x00, 0xc0, 0x48, 0x48, 0xf0, 0xe0,
-+ 0x50, 0x50, 0x48, 0x44, 0x40, 0xc0, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x22, 0x23, 0x02, 0x0b,
-+ 0x0a, 0x08, 0x10, 0x10, 0x27, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x48, 0x30, 0x20, 0xd4, 0x0c, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x11, 0x10, 0x13, 0x7e, 0x12,
-+ 0x17, 0x10, 0x1c, 0x60, 0x03, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0x40, 0xf8, 0x48, 0x48,
-+ 0xfc, 0x40, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x04, 0x04, 0x0f, 0x0c, 0x13, 0x22,
-+ 0x4c, 0x1f, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xc0, 0x40, 0x40, 0xf8, 0x88, 0x08, 0x88,
-+ 0x70, 0xf0, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x20, 0x25, 0x38, 0x22, 0x1c, 0x02, 0x3c, 0x08,
-+ 0x7e, 0x18, 0x1c, 0x2a, 0x48, 0x0b, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x20, 0x25, 0x38, 0x22, 0x1e, 0x00, 0x3e, 0x00,
-+ 0x7f, 0x0c, 0x2a, 0x2a, 0x48, 0x1b, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x01, 0x1f, 0x11, 0x11,
-+ 0x11, 0x7f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf0, 0x10, 0x10,
-+ 0x10, 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x11, 0x17, 0x22, 0x4f, 0x08, 0x17, 0x14, 0x37,
-+ 0x51, 0x17, 0x15, 0x1f, 0x11, 0x11, 0x00, 0x00,
-+ 0x00, 0xb8, 0x80, 0xc0, 0x7c, 0x90, 0x90, 0x90,
-+ 0x10, 0x90, 0x10, 0xd0, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x00, 0x3c, 0x01, 0x3c,
-+ 0x00, 0x3c, 0x25, 0x26, 0x3c, 0x20, 0x00, 0x00,
-+ 0x40, 0x20, 0x20, 0xe0, 0x28, 0x28, 0xf0, 0x70,
-+ 0xb0, 0xa8, 0x28, 0x24, 0x20, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x72, 0x00, 0x00,
-+ 0x88, 0x48, 0x50, 0xf8, 0x88, 0x88, 0x88, 0xf8,
-+ 0x50, 0x50, 0x90, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x41, 0x21, 0x22, 0x02, 0x16,
-+ 0x1b, 0x12, 0x22, 0x22, 0x42, 0x43, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x78, 0x48, 0xa8, 0x98,
-+ 0x50, 0x50, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x29, 0x29, 0x09, 0x1a,
-+ 0x2f, 0x49, 0x10, 0x10, 0x21, 0x4e, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xe0, 0x24, 0x24, 0x1c,
-+ 0xf0, 0x10, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x08, 0x04, 0x04, 0x7f, 0x08, 0x08, 0x10, 0x1f,
-+ 0x2a, 0x4a, 0x0a, 0x0a, 0x7f, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0xfc, 0x20, 0x20, 0x10, 0xf0,
-+ 0xa8, 0xa4, 0xa0, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3e, 0x28, 0x3e,
-+ 0x0a, 0x3e, 0x3a, 0x33, 0x45, 0x1a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0xa8, 0xa0,
-+ 0xa0, 0x90, 0x90, 0x08, 0x08, 0x04, 0x00, 0x00,
-+ 0x11, 0x10, 0x10, 0x1b, 0x36, 0x36, 0x33, 0x52,
-+ 0x10, 0x11, 0x11, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xf8, 0x08, 0x08, 0xf8, 0xa8,
-+ 0xa0, 0x20, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3d, 0x01, 0x7f, 0x01, 0x3d, 0x00, 0x3d,
-+ 0x03, 0x3d, 0x25, 0x24, 0x3c, 0x20, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x80, 0xf8,
-+ 0x28, 0xc8, 0x28, 0xe8, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x3e, 0x09, 0x09, 0x7f, 0x09, 0x29,
-+ 0x2f, 0x29, 0x3b, 0x28, 0x46, 0x41, 0x00, 0x00,
-+ 0x20, 0x28, 0x24, 0xfc, 0x20, 0x28, 0x28, 0x30,
-+ 0x50, 0x94, 0x2c, 0x44, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x24, 0x22,
-+ 0x27, 0x24, 0x27, 0x22, 0x24, 0x28, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x48, 0x88,
-+ 0xc8, 0x48, 0xc8, 0x88, 0xa8, 0x78, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x7f, 0x09, 0x1d, 0x1b, 0x1b,
-+ 0x29, 0x28, 0x4b, 0x08, 0x09, 0x0e, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf8, 0x08, 0xf8, 0xf8, 0x08,
-+ 0xf8, 0xf8, 0x90, 0x60, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x2f, 0x29, 0x2f, 0x2f, 0x20,
-+ 0x2f, 0x29, 0x2f, 0x2f, 0x29, 0x4b, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x28, 0x24, 0x20, 0xfc, 0x20,
-+ 0x20, 0x20, 0x70, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x21, 0x21, 0x21, 0x21, 0x3f,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x2f, 0x21, 0x3f, 0x27, 0x24,
-+ 0x27, 0x23, 0x2d, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xe8, 0x08, 0xf8, 0xc8, 0x48,
-+ 0xe8, 0xa8, 0x48, 0x28, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x13, 0x12, 0x12, 0x7e, 0x12, 0x12, 0x12,
-+ 0x16, 0x1b, 0x62, 0x02, 0x02, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8,
-+ 0x20, 0xfc, 0xd0, 0x30, 0xc8, 0xfc, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x02, 0x0d, 0x71, 0x1f, 0x11,
-+ 0x1f, 0x11, 0x1f, 0x11, 0x11, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x80, 0x60, 0x1c, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x14, 0x04, 0xfc, 0x00, 0x00,
-+ 0x01, 0x3f, 0x20, 0x4f, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x01, 0x7f, 0x04, 0x0e, 0x03, 0x3c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xe0, 0x20, 0xe0, 0x20, 0xe0,
-+ 0x00, 0xfc, 0x40, 0x80, 0xc0, 0x30, 0x00, 0x00,
-+ 0x00, 0x78, 0x0b, 0x10, 0x10, 0x3d, 0x05, 0x25,
-+ 0x25, 0x15, 0x1b, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0x1c, 0xe0, 0x20, 0x20, 0x20, 0x38, 0x20,
-+ 0x20, 0x20, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x11, 0x2a, 0x46, 0x04, 0x18,
-+ 0x61, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x88, 0x88, 0xb0, 0x84, 0x7c,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x11, 0x12, 0x1f, 0x12,
-+ 0x33, 0x52, 0x13, 0x12, 0x10, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x50, 0x48, 0xfc, 0x48,
-+ 0xf8, 0x48, 0xf8, 0x48, 0x44, 0x3c, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x11, 0x13, 0x10, 0x1f,
-+ 0x71, 0x11, 0x12, 0x14, 0x18, 0x33, 0x00, 0x00,
-+ 0x08, 0x30, 0xc8, 0x48, 0x10, 0xf8, 0x80, 0xfc,
-+ 0x00, 0xf8, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x10, 0x08, 0x09, 0x41, 0x21, 0x22, 0x02, 0x17,
-+ 0x12, 0x12, 0x22, 0x22, 0x43, 0x42, 0x00, 0x00,
-+ 0xe0, 0x20, 0x20, 0x20, 0x10, 0x10, 0x08, 0xf4,
-+ 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x44, 0x2f, 0x20, 0x03, 0x12,
-+ 0x13, 0x12, 0x23, 0x20, 0x43, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0xfc, 0x40, 0xf8, 0x48,
-+ 0xf8, 0x48, 0xf8, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x01, 0x09, 0x09, 0x13, 0x02, 0x0c, 0x31, 0x01,
-+ 0x11, 0x13, 0x22, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0x00, 0xc0, 0x30, 0x08, 0x10,
-+ 0x10, 0x20, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x0a, 0x2b, 0x2c, 0x29, 0x49,
-+ 0x09, 0x0d, 0x13, 0x13, 0x21, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0x10, 0x20, 0x78, 0x48,
-+ 0x48, 0x78, 0x48, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x17, 0x36, 0x3a, 0x33, 0x52,
-+ 0x18, 0x17, 0x24, 0x20, 0x47, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xf8, 0xa8, 0xa8, 0xf8, 0x48,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x0f, 0x78, 0x0b, 0x1a,
-+ 0x6a, 0x0b, 0x14, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xe4, 0x28, 0xb0, 0xa0,
-+ 0xa4, 0x9c, 0x90, 0x48, 0x44, 0x04, 0x00, 0x00,
-+ 0x08, 0x4b, 0x30, 0x17, 0x30, 0x49, 0x09, 0x19,
-+ 0x28, 0x4f, 0x09, 0x09, 0x31, 0x16, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xfc, 0x00, 0xf0, 0x10, 0xf0,
-+ 0xc8, 0x48, 0x30, 0x10, 0xc8, 0x04, 0x00, 0x00,
-+ 0x10, 0x11, 0x14, 0x65, 0x18, 0x1b, 0x24, 0x7c,
-+ 0x13, 0x38, 0x37, 0x34, 0x53, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xfc, 0x40, 0xe4,
-+ 0x68, 0xb0, 0x70, 0xa8, 0x24, 0xc0, 0x00, 0x00,
-+ 0x14, 0x7f, 0x55, 0x7f, 0x55, 0x7f, 0x00, 0x7f,
-+ 0x3e, 0x22, 0x3e, 0x24, 0x1e, 0x60, 0x00, 0x00,
-+ 0x20, 0x20, 0x78, 0x90, 0x20, 0xf8, 0xa8, 0xa8,
-+ 0xf8, 0x88, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x08, 0x1e, 0x12,
-+ 0x22, 0x54, 0x0c, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x88, 0x88,
-+ 0x88, 0xb0, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3f, 0x21, 0x27, 0x3f, 0x24,
-+ 0x27, 0x23, 0x2e, 0x22, 0x3f, 0x20, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x08, 0xc8, 0xf8, 0x48,
-+ 0xe8, 0xa8, 0x48, 0x28, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x23, 0x10, 0x17, 0x00, 0x03, 0x72, 0x13,
-+ 0x10, 0x11, 0x1e, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xfc, 0x00, 0xf8, 0x08, 0xf8,
-+ 0x88, 0xd0, 0xb0, 0x88, 0x80, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5d, 0x09, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x70, 0x10, 0x90, 0x90, 0x88, 0x08, 0x04, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x1f, 0x72, 0x0c, 0x1a, 0x6f, 0x0b, 0x0f,
-+ 0x0f, 0x08, 0x0f, 0x15, 0x25, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xb0, 0x84, 0xfc, 0xc0, 0xc0,
-+ 0xf8, 0x00, 0xf8, 0x48, 0x28, 0x30, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x12, 0x7f, 0x15, 0x11, 0x10,
-+ 0x17, 0x1a, 0x62, 0x02, 0x0f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x00,
-+ 0xf8, 0xa8, 0xa8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x0f, 0x0a,
-+ 0x0a, 0x12, 0x12, 0x22, 0x42, 0x0c, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x50, 0x50, 0x88, 0x44, 0x20,
-+ 0x20, 0x00, 0x40, 0x20, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x0b, 0x08, 0x40, 0x27, 0x20, 0x00, 0x09,
-+ 0x09, 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x40, 0xfc, 0x80, 0x80, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x70, 0x00, 0x00,
-+ 0x08, 0x2b, 0x2a, 0x3e, 0x2b, 0x4a, 0x0a, 0x3f,
-+ 0x08, 0x0b, 0x0c, 0x18, 0x61, 0x06, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x40, 0xf8, 0x48, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x24, 0x24, 0x24, 0x24, 0x27,
-+ 0x24, 0x20, 0x20, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0x48, 0x48, 0x48, 0xc8,
-+ 0x48, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x1f, 0x11, 0x11, 0x11, 0x11,
-+ 0x7f, 0x03, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10, 0x10,
-+ 0xfc, 0x00, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x01, 0x02, 0x1f, 0x19, 0x15, 0x15, 0x1f, 0x13,
-+ 0x15, 0x19, 0x7f, 0x02, 0x0c, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x50, 0x50, 0x90, 0xf0, 0x90,
-+ 0x50, 0x30, 0xfc, 0x80, 0x60, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x10, 0x27, 0x44, 0x08, 0x08, 0x1b,
-+ 0x28, 0x48, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x80, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0xf8,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x10, 0x11, 0x11, 0x15,
-+ 0x15, 0x15, 0x29, 0x29, 0x41, 0x00, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x80, 0x40, 0x20, 0x20, 0x08,
-+ 0x04, 0x04, 0x04, 0x10, 0x10, 0xf0, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x13, 0x12, 0x12, 0x1f,
-+ 0x72, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x7f, 0x44, 0x44, 0x44, 0x7c, 0x47, 0x44,
-+ 0x44, 0x7c, 0x44, 0x40, 0x07, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x40, 0x40, 0xf8, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x17, 0x10, 0x3b, 0x36,
-+ 0x37, 0x52, 0x53, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xf8, 0xa0, 0xfc, 0x40, 0xf8, 0x48,
-+ 0xf8, 0x48, 0xf8, 0xa0, 0x10, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x22, 0x32, 0x2b, 0x24, 0x26,
-+ 0x2a, 0x29, 0x31, 0x20, 0x3f, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0xa4, 0x28, 0x30, 0x20,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x22, 0x32, 0x2a, 0x25, 0x24,
-+ 0x2a, 0x2a, 0x30, 0x20, 0x3e, 0x23, 0x00, 0x00,
-+ 0x00, 0x70, 0x50, 0x50, 0x54, 0x94, 0x0c, 0xf8,
-+ 0x48, 0x50, 0x30, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x01, 0x01, 0x01, 0x1f, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x05, 0x04, 0x19, 0x61, 0x02, 0x3f, 0x00, 0x7f,
-+ 0x22, 0x12, 0x06, 0x1a, 0x63, 0x06, 0x00, 0x00,
-+ 0xe0, 0x20, 0x10, 0xcc, 0x60, 0x90, 0x00, 0xf8,
-+ 0x88, 0x48, 0x18, 0x68, 0x88, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7f, 0x0a, 0x0b, 0x16, 0x1b,
-+ 0x36, 0x57, 0x10, 0x10, 0x13, 0x1c, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x58, 0xe8, 0xf8, 0xe8, 0x58,
-+ 0x48, 0xfc, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x12, 0x09, 0x3f, 0x22, 0x4f, 0x08, 0x0f, 0x0f,
-+ 0x0f, 0x08, 0x0f, 0x29, 0x24, 0x40, 0x00, 0x00,
-+ 0x10, 0x20, 0xfc, 0x08, 0xe0, 0x20, 0xe0, 0xe0,
-+ 0xfc, 0x00, 0xf8, 0x48, 0xa8, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x22, 0x22, 0x32, 0x2c, 0x24,
-+ 0x26, 0x2a, 0x30, 0x21, 0x3f, 0x22, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x04, 0x04, 0x3f, 0x04, 0x7f, 0x01, 0x1f, 0x11,
-+ 0x1f, 0x11, 0x1f, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x24, 0x24, 0x3f, 0x21, 0x29,
-+ 0x29, 0x29, 0x2f, 0x28, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x88, 0xf8, 0x08, 0x28,
-+ 0x28, 0x28, 0xe8, 0x28, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x43, 0x22, 0x22, 0x02, 0x0a,
-+ 0x0b, 0x0a, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0x48,
-+ 0xf8, 0x48, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x04, 0x34, 0x08, 0x18,
-+ 0x65, 0x0d, 0x14, 0x64, 0x05, 0x1a, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x20, 0x28, 0xa8, 0xb0,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x17, 0x10, 0x31, 0x51, 0x11,
-+ 0x11, 0x11, 0x15, 0x15, 0x19, 0x10, 0x00, 0x00,
-+ 0x40, 0xf8, 0xa0, 0xfc, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x48, 0x24, 0x14, 0xf0, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x11, 0x12,
-+ 0x1f, 0x10, 0x27, 0x20, 0x5f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x00, 0xf8, 0x40, 0x30,
-+ 0xc8, 0x80, 0xf0, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x11, 0x17, 0x38, 0x35, 0x35, 0x51,
-+ 0x11, 0x11, 0x15, 0x15, 0x19, 0x10, 0x00, 0x00,
-+ 0x40, 0xf8, 0x10, 0xfc, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x48, 0x24, 0x14, 0xf0, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x27, 0x3c, 0x25, 0x25, 0x3d,
-+ 0x25, 0x25, 0x24, 0x25, 0x26, 0x4c, 0x00, 0x00,
-+ 0x20, 0xfc, 0x90, 0xfc, 0x00, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0xa8, 0xa4, 0x94, 0x70, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x13, 0x12, 0x3a, 0x37,
-+ 0x36, 0x52, 0x53, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x90, 0x60, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x08, 0x08, 0x28, 0x28, 0x3e, 0x29, 0x28, 0x48,
-+ 0x0e, 0x78, 0x08, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x00, 0x01, 0x02, 0x04, 0x08,
-+ 0x10, 0x20, 0x20, 0x20, 0x1f, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x08, 0x08, 0xf8, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x11, 0x12, 0x34, 0x5f, 0x14,
-+ 0x17, 0x14, 0x17, 0x14, 0x10, 0x10, 0x00, 0x00,
-+ 0x80, 0x80, 0xf8, 0x40, 0xa0, 0x98, 0xf4, 0x90,
-+ 0xf0, 0x90, 0xf0, 0x94, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x24, 0x44, 0x7f, 0x04, 0x27,
-+ 0x24, 0x24, 0x27, 0x3c, 0x60, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0x48, 0xc8, 0x48, 0x48,
-+ 0x48, 0x48, 0x70, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x11, 0x12, 0x1c, 0x1f,
-+ 0x01, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xd0, 0x30, 0xf0,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x43, 0x22, 0x23, 0x02, 0x10,
-+ 0x17, 0x15, 0x25, 0x25, 0x4f, 0x40, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00,
-+ 0xf8, 0x28, 0x28, 0x28, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x1b, 0x72, 0x11, 0x11, 0x7c, 0x11, 0x18,
-+ 0x35, 0x34, 0x52, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x18, 0xe8, 0x48, 0x10, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x40, 0xa8, 0x84, 0x94, 0x70, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x08, 0x04, 0x7f, 0x00, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x20, 0x40, 0xfc, 0x00, 0xe0,
-+ 0x20, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0x80, 0x40, 0x20, 0x10,
-+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x08, 0x08, 0x18, 0x28, 0x48,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x80, 0x80, 0x88, 0x88, 0x90, 0xa0, 0xc0, 0x80,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x12, 0x13, 0x32, 0x52, 0x12,
-+ 0x12, 0x12, 0x14, 0x14, 0x19, 0x16, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x88, 0x88, 0x50,
-+ 0x50, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x10, 0x13, 0x32, 0x52, 0x12,
-+ 0x13, 0x12, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0x08, 0xc8, 0x48, 0x48, 0x48,
-+ 0xc8, 0x48, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x0a, 0x0a, 0x0a, 0x1f, 0x12, 0x32, 0x52, 0x12,
-+ 0x12, 0x12, 0x14, 0x14, 0x19, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x38, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xb8, 0xa8, 0x00, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x10, 0x10, 0x33, 0x52, 0x12,
-+ 0x12, 0x12, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xa0, 0xa0, 0xf8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x13, 0x10, 0x30, 0x57, 0x10,
-+ 0x10, 0x13, 0x10, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x40,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7f, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x11, 0x11, 0x21, 0x46, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x7c, 0x44, 0x44, 0x44, 0x44,
-+ 0x44, 0x44, 0x44, 0x7c, 0x44, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x00, 0x00, 0x1f, 0x11, 0x11, 0x11,
-+ 0x1f, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x01, 0x3f, 0x01, 0x1f, 0x00, 0x0f, 0x08, 0x0f,
-+ 0x04, 0x7f, 0x04, 0x3f, 0x09, 0x33, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xe0, 0x20, 0xe0,
-+ 0x40, 0xfc, 0x00, 0x78, 0x48, 0x78, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x0f, 0x08, 0x0f, 0x0f, 0x08,
-+ 0x0f, 0x07, 0x3c, 0x03, 0x06, 0x78, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xe0, 0x20, 0xe0, 0xe0, 0x20,
-+ 0xe0, 0xe0, 0x40, 0x80, 0xe0, 0x1c, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x12, 0x7f, 0x24, 0x24, 0x27,
-+ 0x78, 0x4b, 0x0c, 0x17, 0x20, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0xfc, 0x40, 0xe4, 0x68,
-+ 0xb0, 0x70, 0xa8, 0x24, 0x20, 0xc0, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x7f, 0x02, 0x0d, 0x33,
-+ 0x0d, 0x32, 0x04, 0x18, 0x60, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0xf8, 0x00, 0x48, 0xc8,
-+ 0xb0, 0xa0, 0x90, 0x88, 0x84, 0x00, 0x00, 0x00,
-+ 0x01, 0x3f, 0x2f, 0x42, 0x0f, 0x08, 0x0f, 0x0f,
-+ 0x0f, 0x7f, 0x0f, 0x72, 0x04, 0x19, 0x00, 0x00,
-+ 0x00, 0xfc, 0xe8, 0x00, 0xe0, 0x20, 0xe0, 0xe0,
-+ 0xe0, 0xfc, 0xe0, 0x5c, 0x40, 0x80, 0x00, 0x00,
-+ 0x02, 0x0c, 0x38, 0x08, 0x09, 0x7e, 0x08, 0x1c,
-+ 0x1a, 0x2b, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x90, 0x50, 0x50, 0x10, 0x90, 0x90, 0x1c,
-+ 0x70, 0x90, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x07, 0x74, 0x54, 0x57, 0x54, 0x74, 0x57,
-+ 0x54, 0x54, 0x77, 0x54, 0x44, 0x04, 0x00, 0x00,
-+ 0x00, 0xb8, 0x88, 0x88, 0xb8, 0x88, 0x00, 0x78,
-+ 0x48, 0x28, 0x30, 0x10, 0x28, 0xc4, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x11, 0x1f, 0x11, 0x1f, 0x01,
-+ 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0xf0, 0x00,
-+ 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x7e, 0x12, 0x12, 0x22, 0x4d, 0x01,
-+ 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00,
-+ 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x3a, 0x2a, 0x3a, 0x03, 0x7f,
-+ 0x02, 0x3a, 0x2a, 0x3a, 0x2b, 0x06, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa8, 0x30, 0x20,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x40, 0x23, 0x22, 0x02, 0x02,
-+ 0x0b, 0x0a, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0x08, 0xc8, 0x48, 0x48, 0x48,
-+ 0xc8, 0x48, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x11, 0x11, 0x11, 0x21, 0x22,
-+ 0x02, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x08, 0x08, 0x10, 0x20, 0x80, 0x80,
-+ 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x03, 0x7c, 0x10, 0x11, 0x11, 0x7d, 0x11,
-+ 0x11, 0x11, 0x1c, 0x60, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0x08, 0xe8, 0x28, 0x28, 0x28,
-+ 0xe8, 0x28, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x09, 0x09, 0x13, 0x1a,
-+ 0x36, 0x56, 0x12, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x70, 0x50, 0x50, 0xf8, 0x08,
-+ 0xe8, 0xa8, 0xe8, 0xa8, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x01, 0x1f, 0x01, 0x01, 0x7f, 0x01, 0x03,
-+ 0x05, 0x19, 0x61, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x80,
-+ 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x18, 0x73, 0x12, 0x17, 0x7c, 0x10, 0x3b,
-+ 0x34, 0x57, 0x50, 0x13, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0xf8, 0x40, 0xe4, 0x68,
-+ 0xb0, 0x70, 0xa8, 0x24, 0x20, 0xc0, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x3f, 0x21, 0x2f, 0x21,
-+ 0x27, 0x24, 0x27, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x40, 0xfc, 0xa0, 0x10, 0xf8, 0x08, 0xe8, 0x08,
-+ 0xc8, 0x48, 0xc8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x04, 0x04, 0x08, 0x08,
-+ 0x18, 0x28, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x80, 0x88, 0x90,
-+ 0xe0, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x00, 0x7f, 0x00, 0x1f,
-+ 0x11, 0x11, 0x1f, 0x11, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xfc, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x14, 0x10, 0x7e, 0x12,
-+ 0x12, 0x12, 0x12, 0x22, 0x22, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x00, 0xf8, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x0b, 0x10, 0x13,
-+ 0x32, 0x52, 0x13, 0x12, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xfc, 0x10, 0xd0,
-+ 0x50, 0x50, 0xd0, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x1f, 0x09, 0x7f, 0x09,
-+ 0x1f, 0x01, 0x7f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf0, 0x20, 0xfc, 0x20,
-+ 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x1f, 0x11, 0x1f, 0x11, 0x1f,
-+ 0x01, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x55, 0x55, 0x55, 0x7d,
-+ 0x51, 0x19, 0x15, 0x1d, 0x65, 0x01, 0x00, 0x00,
-+ 0x00, 0xd8, 0x48, 0x48, 0xd8, 0x08, 0x00, 0xf8,
-+ 0x28, 0x28, 0xd0, 0x10, 0x28, 0x44, 0x00, 0x00,
-+ 0x00, 0x3d, 0x01, 0x7f, 0x01, 0x3d, 0x01, 0x3c,
-+ 0x03, 0x3c, 0x25, 0x26, 0x3c, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0xf8, 0x40,
-+ 0xfc, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x49, 0x4b, 0x49, 0x4f, 0x49,
-+ 0x4b, 0x78, 0x4f, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0xf8, 0x50, 0xfc, 0x50,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x04, 0x04, 0x18, 0x68, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x80, 0x8c, 0xf0, 0x84, 0x7c, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x02, 0x22, 0x12, 0x1f, 0x02, 0x02, 0x72, 0x12,
-+ 0x14, 0x14, 0x18, 0x1b, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0x00, 0x38, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xb8, 0x28, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x23, 0x12, 0x12, 0x02, 0x07, 0x74, 0x15,
-+ 0x15, 0x15, 0x15, 0x1c, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x90, 0xf8, 0x08, 0xe8,
-+ 0x28, 0xe8, 0x28, 0x18, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x5d, 0x01, 0x3e,
-+ 0x22, 0x3e, 0x3d, 0x20, 0x3c, 0x21, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x78, 0x70, 0x00, 0xf8,
-+ 0x08, 0xf8, 0xf8, 0x50, 0x70, 0x8c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3f, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x70, 0x01, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x88, 0x88, 0x88, 0x50,
-+ 0x50, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x0f, 0x11, 0x11, 0x3f, 0x51, 0x11,
-+ 0x11, 0x13, 0x1d, 0x11, 0x13, 0x11, 0x00, 0x00,
-+ 0x60, 0xa8, 0x24, 0x24, 0x20, 0xfc, 0x20, 0xa8,
-+ 0x28, 0x10, 0x10, 0x34, 0x4c, 0x04, 0x00, 0x00,
-+ 0x00, 0x10, 0x13, 0x10, 0x54, 0x57, 0x54, 0x54,
-+ 0x54, 0x55, 0x7e, 0x44, 0x40, 0x01, 0x00, 0x00,
-+ 0x60, 0xa8, 0xa4, 0xa4, 0xa0, 0xfc, 0xa4, 0xa8,
-+ 0xd8, 0x90, 0xb0, 0xcc, 0x8c, 0x84, 0x00, 0x00,
-+ 0x02, 0x04, 0x38, 0x08, 0x08, 0x7f, 0x08, 0x08,
-+ 0x0e, 0x78, 0x08, 0x08, 0x0b, 0x18, 0x00, 0x00,
-+ 0x80, 0x90, 0x88, 0x88, 0x80, 0xfc, 0x88, 0x88,
-+ 0x50, 0x50, 0x24, 0xd4, 0x0c, 0x04, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x7f, 0x00,
-+ 0x01, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x40, 0x40, 0x40, 0x40, 0xfc, 0xc0,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x01, 0x2f, 0x29, 0x29, 0x2f,
-+ 0x29, 0x29, 0x2f, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xe8, 0x28, 0x28, 0xe8,
-+ 0x28, 0x28, 0xe8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x3f, 0x21, 0x21, 0x21,
-+ 0x3f, 0x24, 0x24, 0x3f, 0x21, 0x02, 0x00, 0x00,
-+ 0x20, 0xa0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60,
-+ 0x50, 0x50, 0x90, 0x88, 0x08, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x1f, 0x08, 0x08, 0x7f,
-+ 0x00, 0x01, 0x06, 0x18, 0x60, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf0, 0x40, 0x40, 0xfc,
-+ 0xc0, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x54, 0x57, 0x54, 0x7c,
-+ 0x50, 0x1b, 0x14, 0x1e, 0x60, 0x01, 0x00, 0x00,
-+ 0x60, 0xb0, 0xa8, 0xa8, 0xa0, 0xfc, 0xa0, 0xa8,
-+ 0xe8, 0xb0, 0x90, 0xb4, 0xcc, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x7e, 0x12, 0x16, 0x2f, 0x48, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x24, 0x24, 0x25, 0x7e, 0x0c, 0x0c,
-+ 0x14, 0x14, 0x24, 0x44, 0x04, 0x0c, 0x00, 0x00,
-+ 0x48, 0x48, 0x90, 0xfc, 0x90, 0x90, 0xfc, 0x90,
-+ 0x90, 0xfc, 0x90, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x08, 0x08, 0x17, 0x1a, 0x28, 0x7f, 0x24, 0x3c,
-+ 0x24, 0x3f, 0x28, 0x24, 0x3e, 0x61, 0x00, 0x00,
-+ 0x20, 0x68, 0xa4, 0xa4, 0xa0, 0xfc, 0xa0, 0xa8,
-+ 0xe8, 0x90, 0x94, 0xac, 0xcc, 0x84, 0x00, 0x00,
-+ 0x08, 0x7e, 0x12, 0x12, 0x26, 0x5f, 0x11, 0x1f,
-+ 0x1f, 0x11, 0x1f, 0x2a, 0x25, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf0, 0x00, 0xe0,
-+ 0xe0, 0x00, 0xf8, 0x48, 0x28, 0x30, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x04, 0x18, 0x64, 0x04, 0x04,
-+ 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x40, 0x30, 0x4c, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x04, 0x18, 0x67, 0x00, 0x00,
-+ 0x3f, 0x02, 0x02, 0x04, 0x3f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x40, 0x30, 0xcc, 0x00, 0x00,
-+ 0xf8, 0x40, 0x20, 0xf0, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x48, 0x3f, 0x2a, 0x2a, 0x3f,
-+ 0x2a, 0x3f, 0x22, 0x22, 0x22, 0x46, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x88, 0x30, 0xa0, 0xf8, 0x20,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x20, 0x27, 0x24, 0x24, 0x24,
-+ 0x24, 0x27, 0x20, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xc8, 0x48, 0x48, 0x48,
-+ 0x48, 0xc8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x10, 0x13, 0x12, 0x7f, 0x12, 0x13, 0x12,
-+ 0x10, 0x1d, 0x61, 0x02, 0x04, 0x08, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0xc8,
-+ 0xd0, 0x50, 0x68, 0x7c, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x17, 0x10, 0x13, 0x7e, 0x12, 0x13, 0x10,
-+ 0x17, 0x18, 0x63, 0x0d, 0x01, 0x06, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0xa8, 0xa8, 0xf8, 0x40,
-+ 0xfc, 0xc8, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x0a, 0x12, 0x12, 0x3a, 0x0a,
-+ 0x4a, 0x2a, 0x13, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xe8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xe8, 0x08, 0xf8, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x13, 0x38, 0x34, 0x34, 0x53,
-+ 0x10, 0x10, 0x10, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0xfc,
-+ 0x60, 0xa0, 0x90, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x17, 0x11, 0x10, 0x38, 0x37, 0x34, 0x50,
-+ 0x13, 0x10, 0x10, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x10, 0xa0, 0xc0, 0x30, 0x4c, 0x40,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x1a, 0x35, 0x35, 0x31, 0x57,
-+ 0x12, 0x12, 0x17, 0x14, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x50, 0x50, 0xfc,
-+ 0x50, 0x50, 0xfc, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x12, 0x3a, 0x36, 0x36, 0x52,
-+ 0x13, 0x12, 0x12, 0x14, 0x1b, 0x1c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x20, 0x28, 0xa8, 0xb0, 0xa0,
-+ 0x20, 0x20, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x1b, 0x36, 0x36, 0x33, 0x50,
-+ 0x17, 0x10, 0x13, 0x1d, 0x11, 0x16, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0xa8, 0xa8, 0xf8, 0x40,
-+ 0xfc, 0xc8, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x7f, 0x00, 0x12, 0x12, 0x12,
-+ 0x7f, 0x12, 0x12, 0x22, 0x22, 0x41, 0x00, 0x00,
-+ 0x90, 0x88, 0x88, 0xfc, 0x80, 0x88, 0x88, 0x50,
-+ 0xd0, 0x20, 0x24, 0x54, 0x8c, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x13, 0x12, 0x10, 0x1f,
-+ 0x70, 0x10, 0x10, 0x11, 0x12, 0x34, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0xf8,
-+ 0x88, 0x88, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x7c, 0x04, 0x04, 0x05, 0x7d, 0x46, 0x40,
-+ 0x40, 0x44, 0x44, 0x3c, 0x03, 0x0c, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x10, 0x90, 0x90, 0x50,
-+ 0x60, 0x20, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x10, 0x3e, 0x2b, 0x3e, 0x2a, 0x3e, 0x2d,
-+ 0x0d, 0x0d, 0x16, 0x17, 0x24, 0x43, 0x00, 0x00,
-+ 0x90, 0x50, 0x50, 0x10, 0x90, 0x90, 0x1c, 0xf0,
-+ 0x10, 0x10, 0x90, 0xd4, 0x04, 0xfc, 0x00, 0x00,
-+ 0x01, 0x01, 0x79, 0x4a, 0x4d, 0x49, 0x79, 0x4f,
-+ 0x4a, 0x4a, 0x7b, 0x4a, 0x40, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x50, 0x50, 0xfc,
-+ 0x50, 0x50, 0xfc, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x10, 0x12, 0x3a, 0x36,
-+ 0x37, 0x52, 0x52, 0x14, 0x18, 0x10, 0x00, 0x00,
-+ 0x20, 0x28, 0x24, 0xfc, 0x20, 0xa8, 0xa8, 0xa8,
-+ 0xf0, 0x90, 0x94, 0xac, 0x4c, 0x84, 0x00, 0x00,
-+ 0x11, 0x09, 0x0b, 0x42, 0x25, 0x21, 0x01, 0x1f,
-+ 0x12, 0x12, 0x27, 0x24, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x50, 0x50, 0xfc,
-+ 0x50, 0x50, 0xfc, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x10, 0x12, 0x12, 0x14,
-+ 0x10, 0x11, 0x21, 0x22, 0x4c, 0x30, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x80, 0x88, 0x88, 0x90, 0xa0,
-+ 0x80, 0x40, 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x11, 0x02,
-+ 0x0c, 0x74, 0x04, 0x04, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x80,
-+ 0x60, 0x5c, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x10, 0x10, 0x1d, 0x62, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x80, 0x98, 0xe0, 0x84, 0x84, 0x7c, 0x00, 0xe0,
-+ 0x20, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0d, 0x12, 0x7e,
-+ 0x09, 0x2c, 0x2a, 0x2a, 0x49, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x74, 0x00, 0x00,
-+ 0xfc, 0x40, 0x50, 0x98, 0xe4, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x05, 0x02, 0x04, 0x1c,
-+ 0x64, 0x04, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x80, 0x40, 0x70,
-+ 0x4c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x1d, 0x28, 0x7e, 0x2b, 0x3e, 0x2b, 0x3f,
-+ 0x23, 0x5f, 0x11, 0x1f, 0x01, 0x3f, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x98, 0xa0, 0xf8, 0x20, 0xfc,
-+ 0x20, 0xf0, 0x10, 0xf0, 0xf0, 0x08, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x20, 0x2f,
-+ 0x22, 0x3f, 0x22, 0x24, 0x28, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0xe8,
-+ 0x88, 0xf8, 0x88, 0x88, 0x88, 0x18, 0x00, 0x00,
-+ 0x01, 0x3d, 0x25, 0x29, 0x31, 0x29, 0x26, 0x25,
-+ 0x25, 0x25, 0x39, 0x21, 0x21, 0x21, 0x00, 0x00,
-+ 0x20, 0x24, 0xf8, 0x20, 0x24, 0xbc, 0x40, 0xf8,
-+ 0x08, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x10, 0x1f,
-+ 0x10, 0x10, 0x1f, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x10, 0x10, 0xf0, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x08, 0x2a, 0x2a, 0x3e, 0x00, 0x7e, 0x00, 0x3e,
-+ 0x22, 0x3e, 0x24, 0x14, 0x1f, 0x62, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x10, 0x15, 0x64, 0x18, 0x0a,
-+ 0x12, 0x24, 0x0c, 0x12, 0x21, 0x42, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x0f, 0x09, 0x11, 0x19, 0x26,
-+ 0x42, 0x04, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xc0, 0x40, 0x60, 0x58,
-+ 0x44, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x7f, 0x48, 0x4a, 0x49, 0x48, 0x48,
-+ 0x48, 0x7b, 0x48, 0x40, 0x03, 0x0c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x48, 0x90, 0xa0, 0x48,
-+ 0x90, 0x20, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x01, 0x3f, 0x21, 0x5f, 0x01, 0x1f, 0x01, 0x7f,
-+ 0x00, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf0, 0x00, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x01, 0x11, 0x1f, 0x00, 0x1f, 0x10, 0x17, 0x10,
-+ 0x1f, 0x10, 0x27, 0x20, 0x5f, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0xf0, 0x00, 0xfc, 0x80, 0xf0, 0x80,
-+ 0xf8, 0x80, 0xf0, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x17, 0x15, 0x15, 0x3f, 0x3d, 0x35, 0x57,
-+ 0x15, 0x14, 0x15, 0x16, 0x1c, 0x11, 0x00, 0x00,
-+ 0x00, 0xf8, 0x50, 0x50, 0x50, 0x50, 0xfc, 0x10,
-+ 0x30, 0xb0, 0xd0, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x10, 0x17, 0x15, 0x7d, 0x17, 0x15, 0x3d, 0x37,
-+ 0x36, 0x55, 0x55, 0x16, 0x1c, 0x11, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0x50, 0x50, 0x50, 0xfc, 0x30,
-+ 0x30, 0x30, 0xd0, 0xd4, 0x94, 0x0c, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x22, 0x22, 0x03, 0x02,
-+ 0x12, 0x12, 0x24, 0x24, 0x4b, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0xf8, 0x20, 0xfc, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7d, 0x11, 0x11, 0x11, 0x3d, 0x24, 0x65,
-+ 0x24, 0x27, 0x3d, 0x20, 0x20, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x00, 0xf8,
-+ 0x10, 0xfc, 0x10, 0x90, 0x90, 0x30, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x1f, 0x01, 0x7f, 0x02, 0x3f,
-+ 0x00, 0x1f, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x00, 0xfc, 0x40, 0xf0,
-+ 0x08, 0xf0, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x11, 0x27, 0x49, 0x09, 0x17, 0x11, 0x31,
-+ 0x57, 0x11, 0x11, 0x11, 0x16, 0x10, 0x00, 0x00,
-+ 0x00, 0x3c, 0xc0, 0x00, 0x00, 0xfc, 0x08, 0x08,
-+ 0xc8, 0x08, 0x08, 0xc8, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3c, 0x03, 0x7c, 0x00, 0x3d, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x25, 0x24, 0x3d, 0x26, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x50, 0x90, 0xa0, 0x68,
-+ 0x48, 0x90, 0x30, 0x48, 0x84, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5d, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x70, 0x00, 0x00,
-+ 0x20, 0xa8, 0xa8, 0xf8, 0x00, 0xfc, 0x00, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x50, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x23, 0x2e, 0x2a, 0x7f, 0x42, 0x7e,
-+ 0x22, 0x3e, 0x22, 0x3e, 0x22, 0x27, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x40, 0x50, 0x90, 0xa0, 0x68,
-+ 0x48, 0x90, 0x30, 0x48, 0x84, 0x04, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x23, 0x22, 0x02, 0x0b,
-+ 0x08, 0x0b, 0x10, 0x10, 0x27, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x7f, 0x3e, 0x3e, 0x2a, 0x3e, 0x27, 0x41,
-+ 0x7f, 0x05, 0x1f, 0x67, 0x04, 0x07, 0x00, 0x00,
-+ 0x70, 0x54, 0x9c, 0xf0, 0x50, 0x70, 0xcc, 0x00,
-+ 0xfc, 0x40, 0xf0, 0xcc, 0x40, 0xc0, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2a, 0x2b, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0e, 0x73, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x17, 0x10, 0x11, 0x7d, 0x11, 0x11, 0x11,
-+ 0x15, 0x19, 0x61, 0x00, 0x0f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10,
-+ 0x10, 0xf0, 0x10, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x18, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x09, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0xfc, 0x24,
-+ 0x24, 0x24, 0x24, 0x2c, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0b, 0x0f, 0x72, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xfc, 0xa0, 0xa0, 0xbc,
-+ 0xa4, 0xa4, 0x44, 0x44, 0x84, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x23, 0x5e, 0x08, 0x7e,
-+ 0x08, 0x2b, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf8, 0x08, 0x48, 0x48, 0xc8,
-+ 0xa8, 0xd8, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x3f, 0x09, 0x7f, 0x09, 0x3f, 0x3f, 0x7f,
-+ 0x3f, 0x29, 0x3f, 0x3f, 0x07, 0x78, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0xc8, 0x48, 0x48, 0x48, 0xc8,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x02, 0x02, 0x7f, 0x52, 0x52, 0x5f, 0x55, 0x55,
-+ 0x5d, 0x7d, 0x55, 0x49, 0x09, 0x13, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0x10, 0xfc, 0x28, 0x68,
-+ 0xec, 0xac, 0x6c, 0x48, 0x48, 0x98, 0x00, 0x00,
-+ 0x02, 0x02, 0x07, 0x0c, 0x12, 0x21, 0x03, 0x0c,
-+ 0x7f, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x20, 0x40, 0x80, 0x40, 0x30,
-+ 0xec, 0x20, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x10, 0x17, 0x14, 0x17,
-+ 0x10, 0x17, 0x21, 0x2f, 0x41, 0x03, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0xfc, 0x24, 0xa8, 0xb0, 0xa8,
-+ 0x24, 0xa4, 0xa4, 0x38, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x11, 0x11, 0x11, 0x1d,
-+ 0x71, 0x11, 0x12, 0x12, 0x17, 0x38, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x00, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x50, 0x48, 0x7c, 0x84, 0x04, 0x00, 0x00,
-+ 0x12, 0x11, 0x13, 0x7e, 0x15, 0x11, 0x11, 0x1d,
-+ 0x71, 0x11, 0x11, 0x10, 0x11, 0x36, 0x00, 0x00,
-+ 0x88, 0x50, 0xfc, 0x08, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7e, 0x09, 0x18, 0x1c, 0x1a,
-+ 0x2b, 0x28, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0x50, 0x20, 0x50, 0x88,
-+ 0xfc, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7e, 0x09, 0x1c, 0x1a, 0x1a,
-+ 0x28, 0x29, 0x48, 0x08, 0x09, 0x0e, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0x48, 0x88, 0x50, 0x20,
-+ 0x48, 0x90, 0x30, 0x48, 0x84, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x00, 0x3f, 0x22,
-+ 0x5c, 0x14, 0x14, 0x16, 0x24, 0x43, 0x00, 0x00,
-+ 0x00, 0x70, 0x50, 0x54, 0x54, 0x8c, 0x00, 0xf8,
-+ 0x88, 0x50, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x09, 0x4f, 0x31, 0x11, 0x33, 0x4d, 0x09, 0x19,
-+ 0x29, 0x4b, 0x08, 0x08, 0x30, 0x17, 0x00, 0x00,
-+ 0x10, 0xfc, 0x30, 0xfc, 0x20, 0xf8, 0xf8, 0x20,
-+ 0xfc, 0xf8, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7e, 0x11, 0x11, 0x12, 0x3c, 0x25, 0x67,
-+ 0x25, 0x25, 0x3d, 0x25, 0x21, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x48, 0x90, 0xa0, 0xfc, 0x20,
-+ 0xf8, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x0b, 0x70, 0x11, 0x13, 0x7d, 0x11, 0x19,
-+ 0x35, 0x37, 0x50, 0x10, 0x10, 0x17, 0x00, 0x00,
-+ 0x90, 0xfc, 0xb0, 0xfc, 0x20, 0xf8, 0xf8, 0x20,
-+ 0xfc, 0xf8, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x12, 0x09, 0x3f, 0x20, 0x4f, 0x08, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x10, 0x20, 0xfc, 0x08, 0xe0, 0x20, 0xe0, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x02, 0x07, 0x18, 0x61, 0x1f, 0x11, 0x1f, 0x11,
-+ 0x11, 0x1f, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xe0, 0x80, 0x00, 0xf0, 0x10, 0xf0, 0x10,
-+ 0x10, 0xf0, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x3e, 0x08, 0x08, 0x7f, 0x14, 0x36,
-+ 0x35, 0x55, 0x16, 0x24, 0x24, 0x4d, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x50, 0xd0,
-+ 0xd8, 0x54, 0x54, 0x90, 0x90, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x09, 0x3e, 0x2a, 0x3f, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x09, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x50, 0x88, 0x94, 0x90,
-+ 0x50, 0x60, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x04, 0x7f, 0x00, 0x1f, 0x11, 0x1f, 0x00, 0x3f,
-+ 0x02, 0x07, 0x7c, 0x04, 0x04, 0x0c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x50, 0x50, 0x60, 0x50, 0x48,
-+ 0x44, 0x44, 0x64, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x23, 0x2e,
-+ 0x21, 0x22, 0x3f, 0x24, 0x27, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xc8, 0x48,
-+ 0x88, 0xc8, 0xf8, 0x48, 0xc8, 0x58, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x29, 0x29, 0x31, 0x28, 0x27,
-+ 0x26, 0x27, 0x3a, 0x22, 0x22, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0xa8, 0x38, 0xf8, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x07, 0x01, 0x1f, 0x11,
-+ 0x1f, 0x01, 0x7f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xc0, 0x00, 0xf0, 0x10,
-+ 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x12, 0x09, 0x09, 0x3f, 0x20, 0x4f, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xfc, 0x08, 0xe0, 0x40, 0x80,
-+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x08, 0x7f,
-+ 0x01, 0x11, 0x11, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x20, 0xc0, 0x00, 0x00, 0xf8, 0x40, 0x40, 0xfc,
-+ 0x00, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x22, 0x17, 0x14, 0x07, 0x1c, 0x67, 0x01,
-+ 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0x08, 0xc8, 0x50, 0xe0, 0x58, 0xc4, 0x00,
-+ 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x3f, 0x29, 0x4e, 0x12, 0x34, 0x0c,
-+ 0x12, 0x3f, 0x52, 0x12, 0x1e, 0x13, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x77, 0x55, 0x55, 0x77, 0x00, 0x3e, 0x00,
-+ 0x7f, 0x10, 0x1e, 0x22, 0x02, 0x0f, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x79, 0x11, 0x17, 0x19, 0x11,
-+ 0x37, 0x51, 0x11, 0x11, 0x1e, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0xd0, 0x10, 0x10, 0xf8, 0x14, 0x14,
-+ 0xf0, 0x10, 0x10, 0xd0, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x18, 0x25, 0x45, 0x01, 0x3f,
-+ 0x00, 0x08, 0x04, 0x04, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0x10, 0x00, 0xf8,
-+ 0x20, 0x20, 0x40, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x13, 0x3a, 0x37,
-+ 0x34, 0x53, 0x50, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xe8, 0x50, 0xd0, 0xa8, 0xc4,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x17, 0x11, 0x7d, 0x11, 0x19, 0x35, 0x37,
-+ 0x31, 0x51, 0x51, 0x11, 0x11, 0x17, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf0, 0x50, 0xf0, 0x50, 0xf0, 0xf8,
-+ 0xf0, 0x50, 0xf0, 0x50, 0xf0, 0xfc, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x7f, 0x09, 0x19, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x0a, 0x0a, 0x0c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf0, 0x40, 0xf8,
-+ 0x40, 0xfc, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x09, 0x1e, 0x24, 0x7e, 0x2b, 0x3e, 0x2a,
-+ 0x3f, 0x05, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x30, 0xd0, 0x90, 0x94, 0xb4, 0xf4, 0xb8, 0xd0,
-+ 0xf0, 0xa8, 0xa8, 0xc8, 0xc4, 0x84, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x43, 0x22, 0x23, 0x01, 0x13,
-+ 0x16, 0x2a, 0x25, 0x45, 0x48, 0x40, 0x00, 0x00,
-+ 0x80, 0x38, 0x08, 0xb8, 0x08, 0xf8, 0x00, 0xfc,
-+ 0x24, 0x94, 0x54, 0x44, 0x04, 0x18, 0x00, 0x00,
-+ 0x08, 0x7f, 0x49, 0x7f, 0x08, 0x3e, 0x08, 0x7f,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4b, 0x4a, 0x4b, 0x48, 0x49,
-+ 0x4e, 0x7b, 0x4a, 0x42, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x80, 0xf8,
-+ 0x68, 0x88, 0x08, 0x28, 0xe8, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x18, 0x35, 0x37, 0x34, 0x50,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xf8, 0x04, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x10, 0x17, 0x10, 0x1c,
-+ 0x73, 0x12, 0x12, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x40, 0x20, 0x27, 0x00, 0x10,
-+ 0x13, 0x12, 0x22, 0x22, 0x43, 0x42, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x43, 0x22, 0x23, 0x01, 0x13,
-+ 0x16, 0x1b, 0x22, 0x22, 0x41, 0x40, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x48, 0x88, 0x08, 0x28, 0xe8, 0x30, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x22, 0x27, 0x04, 0x17,
-+ 0x1a, 0x13, 0x22, 0x23, 0x42, 0x42, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x90, 0xfc, 0x04, 0xf8,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0f, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x07, 0x18, 0x6f, 0x08, 0x07, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xe0, 0x20, 0xe0, 0x20, 0xe0,
-+ 0xf8, 0xc8, 0x08, 0x48, 0xc8, 0x70, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x09, 0x0b, 0x14, 0x19,
-+ 0x37, 0x55, 0x11, 0x11, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x80, 0xf8,
-+ 0x28, 0xc8, 0x08, 0x28, 0xe8, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x09, 0x3f, 0x2a, 0x3e, 0x2a,
-+ 0x3f, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x24, 0xf8, 0x20, 0xf8, 0x20,
-+ 0xfc, 0x00, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08,
-+ 0x0f, 0x08, 0x08, 0x08, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0x20, 0xe0, 0x20, 0x20,
-+ 0xe0, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x1f, 0x25, 0x7f, 0x2b, 0x3f, 0x2b,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x29, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x44, 0xf4, 0x28, 0xe8, 0x54, 0xe4,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x48, 0x48, 0x4f, 0x48, 0x48,
-+ 0x48, 0x78, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x7e, 0x08, 0x1c, 0x1a, 0x1b,
-+ 0x29, 0x2a, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x90, 0x40, 0x64, 0xa4, 0xa8,
-+ 0xb0, 0xa0, 0xa0, 0xa4, 0xa4, 0x9c, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x7d, 0x13, 0x19, 0x37, 0x35,
-+ 0x33, 0x50, 0x57, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0xf8, 0x50, 0xfc, 0x50,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x14, 0x14, 0x7f, 0x14, 0x1d, 0x08, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x88, 0xe8, 0x28, 0x28, 0xe8,
-+ 0xb0, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x09, 0x1a, 0x1f, 0x1a,
-+ 0x2a, 0x28, 0x49, 0x0a, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xf8, 0x20, 0x20, 0xfc, 0x60,
-+ 0x70, 0xb0, 0x28, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x09, 0x37, 0x24, 0x27, 0x24, 0x37, 0x20,
-+ 0x04, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x80, 0x00, 0xf8, 0x48, 0xc8, 0x48, 0xd8, 0x08,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x01, 0x3f, 0x2d, 0x77, 0x3f, 0x0f, 0x0f, 0x09,
-+ 0x0f, 0x1f, 0x1f, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xf8, 0xf8, 0xe0, 0xe0, 0x20,
-+ 0xe0, 0xf0, 0xf0, 0x14, 0xf4, 0xfc, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x10, 0x0f, 0x48, 0x23,
-+ 0x2a, 0x0b, 0x12, 0x13, 0x22, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x50, 0x48, 0xfc, 0x40, 0xf8,
-+ 0x48, 0xf8, 0x48, 0xf8, 0x48, 0x58, 0x00, 0x00,
-+ 0x02, 0x0c, 0x32, 0x01, 0x02, 0x0c, 0x7f, 0x01,
-+ 0x1f, 0x09, 0x05, 0x05, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x30, 0x48, 0x80, 0xc0, 0x30, 0xec, 0x00,
-+ 0xf0, 0x20, 0x20, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x10, 0x1b, 0x24, 0x27, 0x78, 0x13, 0x7c,
-+ 0x13, 0x54, 0x39, 0x32, 0x1c, 0x60, 0x00, 0x00,
-+ 0x10, 0xa0, 0xfc, 0xa0, 0xf8, 0xa8, 0xfc, 0xa8,
-+ 0xf8, 0xa8, 0xb0, 0xa8, 0xa4, 0xa0, 0x00, 0x00,
-+ 0x00, 0x01, 0x79, 0x49, 0x4f, 0x4b, 0x4a, 0x4a,
-+ 0x4b, 0x7a, 0x4b, 0x42, 0x03, 0x02, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x40, 0xfc, 0x58, 0xd8, 0xe8,
-+ 0xf8, 0xe8, 0x58, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x7c, 0x55, 0x55, 0x7d, 0x55, 0x55, 0x7d,
-+ 0x55, 0x11, 0x11, 0x12, 0x12, 0x14, 0x00, 0x00,
-+ 0x20, 0x40, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xfc,
-+ 0x00, 0xfc, 0x54, 0xac, 0x84, 0x18, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x7e, 0x09, 0x19, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x08, 0x08, 0x08,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x1f, 0x04, 0x03, 0x7f,
-+ 0x01, 0x03, 0x05, 0x19, 0x61, 0x03, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf0, 0xc0, 0x00, 0xfc,
-+ 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x3f, 0x20, 0x7f, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x00, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xfc, 0x08, 0xf8, 0xe0, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x71, 0x19, 0x15, 0x75, 0x41, 0x4f, 0x71,
-+ 0x53, 0x13, 0x15, 0x19, 0x11, 0x61, 0x00, 0x00,
-+ 0x00, 0x38, 0x48, 0x48, 0xb8, 0x20, 0xe0, 0x38,
-+ 0xa8, 0x48, 0x48, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x22, 0x12, 0x0c, 0x04, 0x06,
-+ 0x0a, 0x09, 0x11, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x04, 0x02, 0x22, 0x12,
-+ 0x0c, 0x04, 0x0c, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x08, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x48, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x7f, 0x04, 0x04, 0x07, 0x04, 0x04, 0x06,
-+ 0x09, 0x09, 0x08, 0x09, 0x0e, 0x70, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xc0, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0xc4, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3f, 0x22, 0x3e, 0x22,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x80, 0x00, 0xf8, 0x10, 0x20,
-+ 0x40, 0x40, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x12, 0x12, 0x33, 0x50, 0x12,
-+ 0x12, 0x12, 0x12, 0x14, 0x14, 0x18, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x00, 0x90,
-+ 0x90, 0x90, 0x90, 0x94, 0x94, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x7e, 0x00, 0x01, 0x7f, 0x14,
-+ 0x14, 0x14, 0x14, 0x24, 0x24, 0x43, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0x10, 0x10, 0xfc, 0x10, 0x90,
-+ 0x90, 0x10, 0x10, 0x34, 0x04, 0xfc, 0x00, 0x00,
-+ 0x01, 0x3f, 0x24, 0x7f, 0x04, 0x1f, 0x04, 0x7f,
-+ 0x04, 0x1b, 0x60, 0x06, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xf8, 0x40, 0xf0, 0x40, 0xfc,
-+ 0x40, 0x30, 0x8c, 0x00, 0x80, 0x40, 0x00, 0x00,
-+ 0x00, 0x7f, 0x08, 0x08, 0x08, 0x08, 0x7f, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x12, 0x12, 0x7f, 0x12, 0x1e, 0x12, 0x1e, 0x12,
-+ 0x7f, 0x2c, 0x2d, 0x33, 0x3f, 0x21, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0x48,
-+ 0xc8, 0x48, 0x48, 0x88, 0x88, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x3f, 0x28, 0x5f, 0x14, 0x3f, 0x64,
-+ 0x3f, 0x24, 0x3f, 0x24, 0x3f, 0x21, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x88, 0x88, 0x30, 0x00, 0x00,
-+ 0x11, 0x09, 0x09, 0x3f, 0x02, 0x7f, 0x04, 0x1f,
-+ 0x60, 0x0f, 0x08, 0x08, 0x08, 0x07, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xf8, 0x80, 0xfc, 0x40, 0xf0,
-+ 0x4c, 0xc0, 0x40, 0x08, 0x08, 0xf8, 0x00, 0x00,
-+ 0x00, 0x00, 0x79, 0x4a, 0x4f, 0x4a, 0x4a, 0x4a,
-+ 0x4b, 0x7a, 0x4f, 0x40, 0x03, 0x0c, 0x00, 0x00,
-+ 0x80, 0xf0, 0x20, 0x40, 0xf8, 0xa8, 0xa8, 0xb8,
-+ 0x28, 0x48, 0xfc, 0xa0, 0x18, 0x04, 0x00, 0x00,
-+ 0x01, 0x17, 0x11, 0x11, 0x7d, 0x11, 0x11, 0x17,
-+ 0x12, 0x1a, 0x63, 0x02, 0x03, 0x02, 0x00, 0x00,
-+ 0x10, 0xfc, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0xfc,
-+ 0xa0, 0xa8, 0x18, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x04, 0x0e, 0x03, 0x1c, 0x08,
-+ 0x7f, 0x12, 0x34, 0x0c, 0x1a, 0x61, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x40, 0x80, 0xc0, 0x30, 0x20,
-+ 0xfc, 0x48, 0xd0, 0x30, 0x68, 0x84, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x4f, 0x00, 0x00, 0x7f,
-+ 0x04, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0xe0, 0x00, 0x00, 0xfc,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x4f, 0x08, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0xe0, 0x20, 0x20, 0xe0,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x3f, 0x24, 0x7f, 0x04, 0x0f, 0x08, 0x0f,
-+ 0x0f, 0x08, 0x0f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xf8, 0x40, 0xe0, 0x20, 0xe0,
-+ 0xe0, 0x20, 0xe0, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3f, 0x22, 0x3e, 0x22,
-+ 0x3f, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x88, 0x04, 0xf8, 0x20, 0x20,
-+ 0xfc, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x01, 0x0f, 0x09, 0x0f, 0x01, 0x1f, 0x11, 0x1f,
-+ 0x01, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x2f, 0x29,
-+ 0x4f, 0x01, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x90, 0x88, 0xfc, 0x88, 0x48, 0x50, 0x20, 0x54,
-+ 0x8c, 0x04, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x17, 0x3a, 0x37, 0x37, 0x52,
-+ 0x13, 0x13, 0x12, 0x13, 0x11, 0x16, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xfc, 0x50, 0xf0, 0xf8, 0x08,
-+ 0xf8, 0xf8, 0x08, 0xf8, 0x98, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x1b, 0x36, 0x37, 0x33, 0x55,
-+ 0x18, 0x11, 0x15, 0x15, 0x19, 0x10, 0x00, 0x00,
-+ 0x28, 0xfc, 0x20, 0xe8, 0x28, 0xd0, 0x54, 0xec,
-+ 0x84, 0x50, 0x48, 0x14, 0x14, 0xf0, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7f, 0x12, 0x12, 0x13, 0x1a,
-+ 0x70, 0x17, 0x10, 0x10, 0x11, 0x36, 0x00, 0x00,
-+ 0x80, 0xf0, 0x20, 0xf8, 0xa8, 0xa8, 0x38, 0x58,
-+ 0x40, 0xfc, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x04, 0x04, 0x7f, 0x12, 0x1f, 0x12,
-+ 0x1e, 0x13, 0x1e, 0x62, 0x02, 0x03, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x88, 0x88, 0x50,
-+ 0x50, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x18, 0x1c, 0x1a,
-+ 0x2a, 0x28, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x88, 0x88, 0x88, 0xfc, 0x88, 0x88, 0x88, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x7e, 0x08, 0x18, 0x1c, 0x1a,
-+ 0x2a, 0x28, 0x48, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88,
-+ 0x88, 0xf8, 0x88, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x7e, 0x09, 0x19, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x00, 0x3f, 0x00,
-+ 0x7f, 0x0c, 0x2a, 0x2a, 0x49, 0x1a, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa8, 0x30, 0x20,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x7f, 0x14, 0x1f, 0x34,
-+ 0x5f, 0x14, 0x1f, 0x14, 0x1f, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa8, 0x30, 0x20,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x0b, 0x08, 0x40, 0x20, 0x20, 0x07, 0x08,
-+ 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x11, 0x09, 0x0f, 0x41, 0x23, 0x22, 0x03, 0x10,
-+ 0x13, 0x10, 0x27, 0x20, 0x41, 0x46, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0x48, 0xf8, 0x40,
-+ 0xf8, 0x40, 0xfc, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x20, 0x1f, 0x19, 0x4f, 0x29, 0x2f, 0x08, 0x0b,
-+ 0x1a, 0x1b, 0x2a, 0x2b, 0x4a, 0x48, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x78, 0x48, 0x78, 0x08, 0xe8,
-+ 0x28, 0xe8, 0x28, 0xe8, 0x28, 0x18, 0x00, 0x00,
-+ 0x11, 0x09, 0x0b, 0x42, 0x27, 0x29, 0x03, 0x12,
-+ 0x17, 0x2a, 0x23, 0x42, 0x43, 0x42, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x80, 0xfc, 0x20, 0xfc, 0x20,
-+ 0xf8, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x7e, 0x13, 0x10, 0x17, 0x7d, 0x11,
-+ 0x11, 0x14, 0x19, 0x66, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xf8, 0x00, 0xfc, 0xf0, 0x10,
-+ 0xf8, 0xc8, 0xb0, 0x90, 0x8c, 0x80, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x08,
-+ 0x0f, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0x20,
-+ 0xe0, 0x20, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3e, 0x22, 0x3f, 0x24, 0x3f,
-+ 0x20, 0x1f, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x80, 0x00, 0x78, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x02, 0x3f, 0x02, 0x7f, 0x04, 0x07,
-+ 0x0c, 0x0f, 0x14, 0x27, 0x44, 0x07, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0xf8, 0x00, 0xfc, 0x00, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x25, 0x42, 0x3f, 0x01,
-+ 0x01, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0x10, 0xf8, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x29, 0x45, 0x3f, 0x20, 0x4f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0xfc, 0xa0, 0x10, 0xfc, 0x08, 0xe0, 0x20,
-+ 0xe0, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x3e, 0x22, 0x3e, 0x22,
-+ 0x3f, 0x24, 0x27, 0x24, 0x27, 0x24, 0x00, 0x00,
-+ 0x40, 0xfc, 0xa0, 0x10, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x48, 0xc8, 0x48, 0xc8, 0x18, 0x00, 0x00,
-+ 0x08, 0x09, 0x0a, 0x72, 0x17, 0x0c, 0x13, 0x7e,
-+ 0x0c, 0x2a, 0x2a, 0x29, 0x4a, 0x0b, 0x00, 0x00,
-+ 0x1c, 0xe4, 0xa8, 0x50, 0xfc, 0x40, 0xfc, 0x40,
-+ 0x78, 0xc8, 0xb0, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x1f, 0x11, 0x21, 0x7f, 0x01,
-+ 0x11, 0x11, 0x11, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3f, 0x23, 0x3e, 0x23,
-+ 0x3e, 0x08, 0x7f, 0x09, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x90, 0x08, 0xfc, 0x48, 0x68,
-+ 0xd8, 0xd8, 0x68, 0x68, 0x48, 0xd8, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x24, 0x3c, 0x27, 0x24,
-+ 0x3c, 0x24, 0x24, 0x24, 0x24, 0x4c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x11, 0x3d, 0x25, 0x35, 0x2d, 0x2d, 0x7f,
-+ 0x24, 0x2d, 0x2d, 0x2d, 0x25, 0x4f, 0x00, 0x00,
-+ 0x10, 0xf0, 0x50, 0xfc, 0x30, 0xe0, 0x5c, 0xe0,
-+ 0x00, 0xf8, 0x68, 0x68, 0x68, 0xfc, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x01, 0x3f, 0x20, 0x4f,
-+ 0x00, 0x3f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xfc, 0x08, 0xe0,
-+ 0x00, 0xfc, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x10, 0x3e, 0x48, 0x7f, 0x14, 0x3f, 0x68,
-+ 0x3e, 0x28, 0x3e, 0x28, 0x3f, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x50, 0x50, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x03, 0x7c, 0x01, 0x3d, 0x01, 0x3d,
-+ 0x01, 0x3c, 0x25, 0x26, 0x3c, 0x24, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x00, 0x0f, 0x09, 0x7f, 0x12, 0x1f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xfc, 0x40, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x00, 0x27, 0x15, 0x17, 0x00, 0x0f, 0x73, 0x12,
-+ 0x13, 0x10, 0x17, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0xf8, 0x00, 0xfc, 0xf0, 0x10,
-+ 0xf8, 0xc8, 0xb0, 0x88, 0x80, 0xfc, 0x00, 0x00,
-+ 0x10, 0x13, 0x1a, 0x27, 0x26, 0x7b, 0x12, 0x7f,
-+ 0x12, 0x55, 0x39, 0x31, 0x1f, 0x60, 0x00, 0x00,
-+ 0x10, 0xd0, 0x90, 0xdc, 0x60, 0xc0, 0x9c, 0xc0,
-+ 0x00, 0xf8, 0x68, 0x68, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x20, 0x27,
-+ 0x24, 0x27, 0x24, 0x27, 0x24, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0xc8,
-+ 0x48, 0xc8, 0x48, 0xc8, 0x48, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x21, 0x21,
-+ 0x2f, 0x23, 0x25, 0x29, 0x21, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0x08,
-+ 0xe8, 0x88, 0x48, 0x28, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x24, 0x22,
-+ 0x27, 0x21, 0x2f, 0x22, 0x24, 0x28, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x48, 0x88,
-+ 0xc8, 0x08, 0xe8, 0x88, 0x48, 0x18, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x28, 0x31, 0x2a, 0x25, 0x25,
-+ 0x25, 0x25, 0x39, 0x21, 0x21, 0x21, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x90, 0x10, 0x20, 0x78, 0x48,
-+ 0x48, 0x78, 0x48, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x08, 0x08, 0x7e, 0x09, 0x3e, 0x22, 0x3e, 0x22,
-+ 0x3e, 0x08, 0x7e, 0x09, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0xf8, 0x28, 0xfc, 0x00, 0xf8, 0x88, 0xf8,
-+ 0x10, 0xf8, 0x90, 0xfc, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x1b, 0x28, 0x7e, 0x22, 0x3e,
-+ 0x22, 0x3e, 0x24, 0x26, 0x39, 0x60, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0xf0, 0x90, 0x90, 0xf0,
-+ 0x80, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x13, 0x22, 0x7e, 0x08, 0x7e,
-+ 0x08, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0xf0, 0x90, 0x90, 0xf0,
-+ 0x80, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x02, 0x7f, 0x02, 0x02, 0x1a,
-+ 0x06, 0x05, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0xc4, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x04, 0x1f, 0x60, 0x1f, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x40, 0xf0, 0x0c, 0xe0, 0x40,
-+ 0x80, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x1f, 0x00, 0x1f, 0x10, 0x17,
-+ 0x10, 0x10, 0x2f, 0x20, 0x40, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0xf0,
-+ 0x80, 0x80, 0xf8, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x01, 0x11, 0x1f, 0x09, 0x3f, 0x2f, 0x22, 0x3f,
-+ 0x29, 0x2f, 0x2f, 0x2f, 0x39, 0x41, 0x00, 0x00,
-+ 0x00, 0x08, 0xf8, 0x10, 0xfc, 0x20, 0x20, 0xbc,
-+ 0x48, 0xa8, 0x10, 0xb0, 0x48, 0x84, 0x00, 0x00,
-+ 0x00, 0x01, 0x7c, 0x10, 0x10, 0x13, 0x7c, 0x10,
-+ 0x10, 0x11, 0x1d, 0x62, 0x04, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfc, 0xa0, 0xa0,
-+ 0xa0, 0x20, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x49, 0x29, 0x29, 0x0f, 0x1c,
-+ 0x2f, 0x4c, 0x12, 0x12, 0x23, 0x42, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0xbc, 0xa4,
-+ 0xbc, 0x44, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x79, 0x49, 0x49, 0x79, 0x49, 0x49, 0x79,
-+ 0x49, 0x49, 0x79, 0x49, 0x41, 0x06, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x10, 0xf8,
-+ 0x48, 0x50, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x1f, 0x00, 0x7f, 0x04, 0x04,
-+ 0x0f, 0x0c, 0x14, 0x24, 0x47, 0x04, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x7f, 0x4c, 0x2a, 0x1b, 0x6c, 0x19, 0x08,
-+ 0x3f, 0x21, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0xf8, 0x80, 0x80, 0x80, 0xfc, 0xb0, 0x30,
-+ 0x30, 0x30, 0x50, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x14, 0x1d, 0x16, 0x14, 0x13,
-+ 0x13, 0x13, 0x22, 0x23, 0x43, 0x1c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x90, 0xfc, 0xf8, 0xf8, 0xfc, 0xf0,
-+ 0xf0, 0xf0, 0x10, 0xf0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x12, 0x14, 0x14, 0x1d, 0x16,
-+ 0x14, 0x14, 0x24, 0x24, 0x44, 0x04, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0x50, 0xfc, 0x90, 0x90, 0xf8,
-+ 0x90, 0xf8, 0x90, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x00, 0x01, 0x3e, 0x00, 0x00, 0x7f, 0x14, 0x14,
-+ 0x14, 0x15, 0x23, 0x20, 0x41, 0x06, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x7f, 0x22, 0x14, 0x3f, 0x24, 0x28,
-+ 0x32, 0x24, 0x39, 0x22, 0x4c, 0x33, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x24, 0x2f, 0x29, 0x2f, 0x29,
-+ 0x2f, 0x26, 0x2d, 0x35, 0x44, 0x0d, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0x20, 0x78, 0x48, 0x78, 0x48,
-+ 0x78, 0x48, 0x78, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x04, 0x19, 0x61, 0x01, 0x09,
-+ 0x09, 0x09, 0x09, 0x09, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0xf0, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x17, 0x10, 0x30, 0x53, 0x11,
-+ 0x11, 0x10, 0x10, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x08,
-+ 0x10, 0x90, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x02, 0x07, 0x18, 0x61, 0x1f, 0x10, 0x13, 0x12,
-+ 0x12, 0x12, 0x12, 0x22, 0x22, 0x41, 0x00, 0x00,
-+ 0x00, 0xe0, 0xc0, 0x00, 0xfc, 0x00, 0xf0, 0x10,
-+ 0x10, 0x10, 0x60, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x1f, 0x00, 0x0f, 0x08, 0x0f,
-+ 0x04, 0x7f, 0x00, 0x1f, 0x10, 0x1f, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x00, 0xe0, 0x20, 0xe0,
-+ 0x40, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x00, 0x00,
-+ 0x00, 0x1e, 0x12, 0x12, 0x1e, 0x01, 0x7f, 0x04,
-+ 0x18, 0x7e, 0x12, 0x12, 0x1e, 0x12, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0xf0, 0x00, 0xfc, 0x40,
-+ 0x30, 0xfc, 0x90, 0x90, 0xf0, 0x90, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x07, 0x04, 0x07, 0x04, 0x7f,
-+ 0x09, 0x1f, 0x61, 0x01, 0x3f, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xc0, 0x40, 0xc0, 0x40, 0xfc,
-+ 0x20, 0xf0, 0x0c, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x02, 0x04, 0x18, 0x7f, 0x00,
-+ 0x1f, 0x11, 0x11, 0x1f, 0x11, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x80, 0x40, 0x20, 0xfc, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x13, 0x7d, 0x25, 0x25, 0x24,
-+ 0x7b, 0x48, 0x0d, 0x15, 0x21, 0x41, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0xf8, 0x08, 0xf8, 0x90,
-+ 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x21, 0x5f, 0x02, 0x0c, 0x7f,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x11, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0xf8, 0x40, 0x20, 0xfc,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x17, 0x54, 0x54, 0x57, 0x55,
-+ 0x54, 0x7c, 0x44, 0x40, 0x01, 0x06, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x08,
-+ 0x90, 0x90, 0x60, 0x60, 0x90, 0x0c, 0x00, 0x00,
-+ 0x06, 0x01, 0x07, 0x39, 0x02, 0x7f, 0x04, 0x0f,
-+ 0x18, 0x28, 0x48, 0x08, 0x08, 0x00, 0x00, 0x00,
-+ 0x20, 0xc0, 0x60, 0x10, 0x00, 0xfc, 0x80, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xb0, 0x80, 0x00, 0x00,
-+ 0x11, 0x15, 0x65, 0x19, 0x0d, 0x13, 0x7f, 0x01,
-+ 0x3f, 0x08, 0x0c, 0x12, 0x21, 0x46, 0x00, 0x00,
-+ 0x20, 0x28, 0xc8, 0x30, 0x30, 0x48, 0xfc, 0x10,
-+ 0xfc, 0x90, 0xa0, 0x44, 0xb4, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x00, 0x00, 0x1f, 0x10, 0x10, 0x0f,
-+ 0x01, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x08, 0xf8,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x10, 0x13, 0x12, 0x1f,
-+ 0x72, 0x13, 0x10, 0x17, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xf8, 0x40, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x1c, 0x1a, 0x1a,
-+ 0x28, 0x28, 0x49, 0x09, 0x0a, 0x0c, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x10, 0x14, 0x14, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7e, 0x13, 0x10, 0x1c, 0x14,
-+ 0x14, 0x14, 0x27, 0x24, 0x44, 0x1b, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x90, 0xfc, 0x90, 0xf0, 0x90,
-+ 0xf0, 0x90, 0xfc, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x23, 0x3e,
-+ 0x28, 0x24, 0x26, 0x3a, 0x61, 0x02, 0x00, 0x00,
-+ 0x00, 0xfc, 0x50, 0x50, 0x50, 0x50, 0xfc, 0x30,
-+ 0x30, 0x50, 0x50, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x12, 0x12, 0x12, 0x7f, 0x12, 0x1e, 0x12, 0x1e,
-+ 0x12, 0x7f, 0x14, 0x12, 0x22, 0x41, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0xc8, 0x78, 0x48, 0x48, 0x78,
-+ 0x48, 0xc8, 0x48, 0x88, 0x88, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x1c, 0x1a, 0x1a,
-+ 0x28, 0x2b, 0x48, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x90, 0x90, 0x90, 0xfc, 0x90, 0xf0, 0x90, 0xf0,
-+ 0x90, 0xfc, 0x90, 0x88, 0x04, 0x04, 0x00, 0x00,
-+ 0x01, 0x7f, 0x02, 0x1f, 0x09, 0x7f, 0x09, 0x0f,
-+ 0x01, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xe0, 0x30, 0xfc, 0x20, 0xe0,
-+ 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x11, 0x11, 0x16, 0x7e, 0x11, 0x1a, 0x37, 0x34,
-+ 0x33, 0x52, 0x53, 0x14, 0x14, 0x18, 0x00, 0x00,
-+ 0x48, 0x48, 0xf4, 0xd4, 0x48, 0xd4, 0xfc, 0x50,
-+ 0xfc, 0x28, 0x28, 0x90, 0x3c, 0xc4, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x09, 0x28, 0x2b, 0x28, 0x4f,
-+ 0x0c, 0x0b, 0x0a, 0x12, 0x12, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x00, 0xfc,
-+ 0x44, 0xf8, 0x48, 0x48, 0x58, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x3f, 0x12, 0x0c, 0x7f, 0x19, 0x6d,
-+ 0x16, 0x6d, 0x15, 0x64, 0x04, 0x1b, 0x00, 0x00,
-+ 0x00, 0x70, 0x50, 0x50, 0x54, 0x94, 0x0c, 0xf8,
-+ 0x48, 0x50, 0x30, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x10, 0x2f, 0x40, 0x3f, 0x01,
-+ 0x01, 0x1a, 0x06, 0x05, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xe0, 0x00, 0xe0, 0x20,
-+ 0x20, 0x20, 0x14, 0x14, 0x0c, 0x04, 0x00, 0x00,
-+ 0x11, 0x09, 0x0b, 0x42, 0x25, 0x20, 0x07, 0x00,
-+ 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xf0, 0x10,
-+ 0x10, 0x10, 0x14, 0x0c, 0x0c, 0x04, 0x00, 0x00,
-+ 0x11, 0x15, 0x65, 0x19, 0x15, 0x7f, 0x02, 0x7f,
-+ 0x3e, 0x2a, 0x3e, 0x2a, 0x3e, 0x21, 0x00, 0x00,
-+ 0x20, 0x28, 0xc8, 0x30, 0x28, 0xfc, 0xa4, 0xfc,
-+ 0x88, 0x48, 0x50, 0x20, 0x54, 0x8c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7e, 0x04, 0x08, 0x0c, 0x1a,
-+ 0x2a, 0x48, 0x09, 0x09, 0x0a, 0x0c, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x80, 0x80, 0xfc, 0x90, 0x90,
-+ 0x90, 0x90, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x7f, 0x03, 0x05, 0x19, 0x6f,
-+ 0x00, 0x01, 0x7f, 0x01, 0x01, 0x07, 0x00, 0x00,
-+ 0x60, 0x80, 0x00, 0xfc, 0x80, 0x40, 0x30, 0xec,
-+ 0x40, 0x80, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x02, 0x0c, 0x38, 0x09, 0x08, 0x7f, 0x08, 0x1c,
-+ 0x1b, 0x2a, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0xd0, 0x30, 0xc8, 0x40, 0xfc, 0xa0, 0xf8,
-+ 0xa8, 0xa8, 0xa8, 0xb8, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0c, 0x12, 0x7d,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x88, 0x80,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x12, 0x1a, 0x2a, 0x4f, 0x14, 0x15, 0x3d, 0x62,
-+ 0x25, 0x3f, 0x2a, 0x2b, 0x32, 0x22, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xa0, 0x7c, 0x48, 0xc8, 0x28,
-+ 0x28, 0xb0, 0x90, 0x30, 0xc8, 0x84, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x3f, 0x09, 0x09, 0x7f, 0x09,
-+ 0x09, 0x08, 0x15, 0x15, 0x22, 0x44, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0xf8,
-+ 0xa8, 0xa0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3e, 0x00, 0x7f, 0x00, 0x3e, 0x00, 0x3e,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x88, 0x80,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x01, 0x0f, 0x09, 0x0f, 0x7f, 0x0f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0xfc, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x3e, 0x08, 0x08, 0x7f, 0x08, 0x28,
-+ 0x2f, 0x28, 0x38, 0x28, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x88, 0x80,
-+ 0x80, 0x84, 0x84, 0x7c, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3f, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x70, 0xd0, 0x50, 0x50, 0x50,
-+ 0x50, 0x50, 0x90, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x08, 0x09, 0x4b, 0x2b, 0x2c, 0x08, 0x7f, 0x14,
-+ 0x14, 0x15, 0x16, 0x25, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x28, 0xfc, 0x20, 0xf8, 0xa8, 0xf8,
-+ 0xa8, 0xf8, 0x20, 0xfc, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x1a, 0x28, 0x7e, 0x22, 0x3e,
-+ 0x22, 0x3e, 0x28, 0x25, 0x3b, 0x62, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x14, 0x14, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x29, 0x3e, 0x28, 0x3e, 0x29, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x42, 0x0c, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0x50, 0x88, 0xfc, 0x08,
-+ 0xe8, 0xa8, 0xe8, 0xa8, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x02, 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x15,
-+ 0x05, 0x05, 0x09, 0x09, 0x11, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10,
-+ 0x20, 0x20, 0x50, 0xfc, 0x04, 0xfc, 0x00, 0x00,
-+ 0x02, 0x03, 0x0c, 0x7f, 0x09, 0x0f, 0x0f, 0x1f,
-+ 0x11, 0x1f, 0x11, 0x1f, 0x11, 0x00, 0x00, 0x00,
-+ 0x00, 0xc0, 0x80, 0xe0, 0x20, 0xe0, 0xe0, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf4, 0x04, 0xfc, 0x00, 0x00,
-+ 0x0a, 0x09, 0x09, 0x17, 0x10, 0x30, 0x51, 0x11,
-+ 0x13, 0x15, 0x1c, 0x12, 0x12, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf0, 0x90, 0x90, 0xf8, 0x08,
-+ 0xfc, 0x54, 0xac, 0x84, 0x04, 0x18, 0x00, 0x00,
-+ 0x09, 0x08, 0x0f, 0x10, 0x13, 0x30, 0x57, 0x13,
-+ 0x11, 0x1f, 0x11, 0x17, 0x11, 0x13, 0x00, 0x00,
-+ 0x10, 0xa0, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0xa8,
-+ 0x24, 0xfc, 0xa8, 0x10, 0x6c, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x08, 0x7e, 0x13, 0x12, 0x12,
-+ 0x3c, 0x24, 0x06, 0x0a, 0x11, 0x22, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0x88, 0x88,
-+ 0x50, 0x50, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x4f, 0x08, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x08, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0xc0, 0x40, 0x40, 0xc0,
-+ 0x40, 0xc0, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x07, 0x04, 0x3f, 0x27, 0x3d, 0x23, 0x2a,
-+ 0x2a, 0x3b, 0x3a, 0x2b, 0x4c, 0x30, 0x00, 0x00,
-+ 0x30, 0x28, 0x28, 0xa0, 0x3c, 0xe0, 0x28, 0x28,
-+ 0xb0, 0x10, 0x34, 0x4c, 0x8c, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x10, 0x10, 0x13, 0x1d,
-+ 0x70, 0x10, 0x10, 0x10, 0x11, 0x36, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x08,
-+ 0x90, 0x90, 0x60, 0x60, 0x90, 0x0c, 0x00, 0x00,
-+ 0x14, 0x15, 0x16, 0x7c, 0x13, 0x12, 0x13, 0x1d,
-+ 0x77, 0x11, 0x13, 0x12, 0x14, 0x39, 0x00, 0x00,
-+ 0x00, 0xfc, 0x28, 0x90, 0x90, 0x7c, 0x98, 0x50,
-+ 0xdc, 0x50, 0x50, 0xf0, 0x90, 0x0c, 0x00, 0x00,
-+ 0x12, 0x12, 0x12, 0x7f, 0x12, 0x1e, 0x13, 0x1e,
-+ 0x12, 0x7f, 0x12, 0x11, 0x21, 0x42, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x7c, 0xa8, 0x30, 0x20,
-+ 0x20, 0x20, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x09, 0x08, 0x2b, 0x28, 0x3d, 0x28, 0x4b, 0x0d,
-+ 0x18, 0x6f, 0x08, 0x0b, 0x08, 0x09, 0x00, 0x00,
-+ 0x10, 0xa0, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0xe8,
-+ 0xa4, 0xfc, 0xe8, 0x94, 0xac, 0xc4, 0x00, 0x00,
-+ 0x20, 0x27, 0x38, 0x22, 0x1e, 0x11, 0x1e, 0x28,
-+ 0x7e, 0x08, 0x14, 0x13, 0x22, 0x44, 0x00, 0x00,
-+ 0x00, 0xf8, 0x90, 0x60, 0x20, 0xfc, 0x28, 0xb0,
-+ 0xa0, 0xb8, 0xa0, 0x60, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x05, 0x09, 0x09, 0x19,
-+ 0x35, 0x55, 0x11, 0x11, 0x16, 0x10, 0x00, 0x00,
-+ 0x08, 0x30, 0xe0, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x10, 0x14, 0x14, 0xcc, 0x0c, 0x04, 0x00, 0x00,
-+ 0x04, 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x06, 0x38,
-+ 0x7f, 0x08, 0x0e, 0x78, 0x08, 0x1b, 0x00, 0x00,
-+ 0x40, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x90, 0x88,
-+ 0xfc, 0x48, 0x50, 0x24, 0xd4, 0x0c, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7d, 0x54, 0x57, 0x54, 0x7f,
-+ 0x53, 0x18, 0x14, 0x1f, 0x60, 0x01, 0x00, 0x00,
-+ 0x90, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0xa8, 0xa4,
-+ 0xfc, 0xa8, 0xd8, 0x94, 0xec, 0x84, 0x00, 0x00,
-+ 0x00, 0x3c, 0x03, 0x7e, 0x03, 0x3d, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x25, 0x25, 0x3f, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x38, 0x07, 0x78, 0x03, 0x38, 0x07, 0x3b,
-+ 0x01, 0x3f, 0x29, 0x2f, 0x39, 0x2b, 0x00, 0x00,
-+ 0x10, 0xa0, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0xa8,
-+ 0x24, 0xfc, 0xa8, 0x14, 0x6c, 0x04, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7f, 0x12, 0x14, 0x12, 0x1a,
-+ 0x77, 0x11, 0x11, 0x12, 0x14, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x88, 0xa8, 0xa8, 0xc8,
-+ 0xf8, 0xc8, 0xa8, 0x98, 0x88, 0xb0, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x0c, 0x08, 0x1f, 0x12, 0x2a,
-+ 0x4a, 0x3f, 0x07, 0x0a, 0x32, 0x02, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x48, 0x48,
-+ 0x88, 0xe8, 0x08, 0xc8, 0x28, 0x30, 0x00, 0x00,
-+ 0x14, 0x14, 0x7f, 0x14, 0x1d, 0x0b, 0x3e, 0x2b,
-+ 0x3e, 0x08, 0x7f, 0x0a, 0x08, 0x08, 0x00, 0x00,
-+ 0x80, 0x80, 0xf8, 0xc8, 0x58, 0x58, 0xe8, 0xf8,
-+ 0xe8, 0xd8, 0x58, 0x48, 0x48, 0x30, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x7f, 0x01, 0x01, 0x3f, 0x00,
-+ 0x1f, 0x10, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x79, 0x4a, 0x4a, 0x4d, 0x48,
-+ 0x48, 0x78, 0x49, 0x42, 0x02, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf0, 0x20,
-+ 0x40, 0x80, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x02, 0x02, 0x7f, 0x52, 0x5f, 0x52, 0x53, 0x5e,
-+ 0x50, 0x7f, 0x50, 0x41, 0x06, 0x18, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0x28, 0xa8, 0x28, 0xc8, 0x58,
-+ 0x80, 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x1c, 0x1b, 0x1a,
-+ 0x29, 0x29, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7f, 0x10, 0x1b, 0x34, 0x37,
-+ 0x32, 0x53, 0x52, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xf0, 0xa0, 0xfc, 0xc8, 0x50, 0xc0, 0xf8,
-+ 0xa8, 0x38, 0xe8, 0xa8, 0xe8, 0x18, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7f, 0x00, 0x3c, 0x01, 0x3c,
-+ 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x25, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x08, 0x08, 0x08, 0x10, 0x1e, 0x32,
-+ 0x52, 0x12, 0x12, 0x1e, 0x10, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x20, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x09, 0x1a, 0x1c, 0x1b,
-+ 0x2a, 0x28, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x20, 0x20, 0x20, 0xfc,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x7f, 0x03, 0x0d, 0x71, 0x03,
-+ 0x0d, 0x79, 0x07, 0x0d, 0x31, 0x03, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x80,
-+ 0x60, 0x3c, 0xc0, 0x60, 0x18, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3f, 0x08, 0x08, 0x7f, 0x08,
-+ 0x0c, 0x12, 0x13, 0x7d, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0x48, 0x48, 0xc8, 0x48,
-+ 0x48, 0x48, 0x70, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x22, 0x47, 0x0c, 0x32, 0x03,
-+ 0x0c, 0x7f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0xe0, 0x40, 0x80, 0x80,
-+ 0x70, 0xec, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x01, 0x39, 0x29, 0x2f, 0x39, 0x29, 0x2f, 0x39,
-+ 0x29, 0x2a, 0x2a, 0x2f, 0x28, 0x58, 0x00, 0x00,
-+ 0x00, 0x38, 0x28, 0xe8, 0x28, 0x28, 0xe8, 0x28,
-+ 0x28, 0xa8, 0xf8, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x1f, 0x12, 0x1f, 0x11, 0x10,
-+ 0x17, 0x14, 0x27, 0x24, 0x47, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0xe8, 0x10, 0xf0, 0x00,
-+ 0xf8, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x02, 0x21, 0x11, 0x17, 0x00, 0x02, 0x02, 0x72,
-+ 0x13, 0x12, 0x10, 0x18, 0x27, 0x41, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xfc, 0x40, 0x48, 0x48, 0x48,
-+ 0xf8, 0x48, 0x40, 0x80, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x7f, 0x00, 0x00, 0x00,
-+ 0x20, 0xc0, 0x00, 0x00, 0x00, 0xf8, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x03, 0x04, 0x04, 0x08, 0x10,
-+ 0x20, 0x01, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xe0, 0x20, 0x20, 0x40, 0x40,
-+ 0xc0, 0x20, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x09, 0x09, 0x09, 0x11, 0x11, 0x3f, 0x51, 0x11,
-+ 0x11, 0x11, 0x12, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xe0, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x24, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x10, 0x17, 0x30, 0x50, 0x10,
-+ 0x11, 0x11, 0x12, 0x14, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40, 0xe0, 0xe0,
-+ 0x50, 0x50, 0x48, 0x44, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x3f, 0x04, 0x04, 0x04, 0x06, 0x0a, 0x09,
-+ 0x09, 0x08, 0x10, 0x10, 0x23, 0x4c, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x40, 0x40, 0xf0, 0x10, 0x10,
-+ 0x20, 0xa0, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x07, 0x79, 0x49, 0x49, 0x49, 0x49, 0x49,
-+ 0x7a, 0x4a, 0x42, 0x04, 0x09, 0x16, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x20, 0x20, 0xf8, 0x88, 0x88,
-+ 0x50, 0x50, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x4f, 0x08, 0x08, 0x0f,
-+ 0x01, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0xe0, 0x20, 0x20, 0xe0,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x1f, 0x00, 0x00, 0x1f, 0x10, 0x10, 0x1f,
-+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0x10, 0xe0, 0x00, 0x00,
-+ 0x02, 0x07, 0x08, 0x3f, 0x00, 0x0f, 0x00, 0x1f,
-+ 0x01, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xc0, 0x80, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x08, 0x0a, 0x09, 0x7f, 0x08, 0x4a, 0x2b, 0x2c,
-+ 0x1c, 0x1a, 0x2a, 0x48, 0x08, 0x1b, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0x88, 0x88, 0x50, 0x50,
-+ 0x30, 0x20, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x7f, 0x08, 0x1c, 0x1a, 0x1a,
-+ 0x29, 0x28, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x40, 0xf8, 0x88, 0x88,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x7f, 0x01, 0x01, 0x31, 0x09,
-+ 0x03, 0x05, 0x19, 0x61, 0x01, 0x03, 0x00, 0x00,
-+ 0x20, 0x10, 0x10, 0xfc, 0x00, 0x88, 0x88, 0x50,
-+ 0x60, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00,
-+ 0x20, 0x17, 0x12, 0x42, 0x22, 0x23, 0x03, 0x12,
-+ 0x12, 0x12, 0x24, 0x24, 0x48, 0x53, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x20, 0x20, 0x78, 0x08, 0x90,
-+ 0x90, 0x60, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x47, 0x20, 0x22, 0x01, 0x09,
-+ 0x08, 0x10, 0x10, 0x20, 0x27, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x10, 0x10, 0x10, 0x10,
-+ 0x90, 0xa0, 0xa0, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x03, 0x0c, 0x31, 0x02, 0x0d, 0x71, 0x01,
-+ 0x11, 0x12, 0x22, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xc0, 0x80, 0x80, 0x40, 0x30, 0x0c, 0x10,
-+ 0x10, 0xa0, 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x13, 0x10, 0x12, 0x7d, 0x11,
-+ 0x10, 0x14, 0x19, 0x66, 0x00, 0x00, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0xfc, 0x40, 0x48, 0x68, 0x70,
-+ 0x50, 0xd0, 0x48, 0x44, 0x40, 0xc0, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x24, 0x44, 0x04, 0x09, 0x11,
-+ 0x3f, 0x02, 0x02, 0x04, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x88, 0x80, 0x88, 0x78, 0x00,
-+ 0xc0, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x01, 0x3f, 0x24, 0x48, 0x14, 0x1e, 0x12, 0x1e,
-+ 0x1e, 0x12, 0x7e, 0x06, 0x1a, 0x66, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0x90, 0x70, 0xf0, 0x10, 0xf0,
-+ 0x80, 0xf8, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x14, 0x23, 0x5f, 0x04, 0x04,
-+ 0x06, 0x0a, 0x09, 0x10, 0x23, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0xe0, 0x20, 0x40,
-+ 0xf0, 0x10, 0x20, 0xc0, 0x60, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0c, 0x12, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2b, 0x49, 0x0a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x90, 0x90, 0xb8, 0xc8, 0xc8,
-+ 0xa8, 0xb0, 0x90, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0c, 0x12, 0x7d,
-+ 0x08, 0x2c, 0x2b, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x10, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x9c, 0xf0, 0x90, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0d, 0x12, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0xfc, 0x00, 0x00,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x20, 0x27, 0x24, 0x24, 0x24, 0x24, 0x27, 0x24,
-+ 0x24, 0x24, 0x24, 0x27, 0x24, 0x20, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10,
-+ 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00, 0x00,
-+ 0x01, 0x09, 0x09, 0x09, 0x1f, 0x11, 0x21, 0x01,
-+ 0x7f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00,
-+ 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x1f, 0x01, 0x01, 0x01, 0x7f,
-+ 0x02, 0x02, 0x04, 0x08, 0x3f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xfc,
-+ 0x00, 0x40, 0x20, 0xf0, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x10, 0x1f, 0x10,
-+ 0x10, 0x17, 0x24, 0x24, 0x47, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x88, 0x80, 0xfc, 0x80,
-+ 0x80, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x20, 0x3f, 0x20, 0x20, 0x20,
-+ 0x3f, 0x20, 0x20, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0xe0, 0x20, 0x20, 0x20,
-+ 0xe0, 0x20, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x7f, 0x09, 0x09, 0x09, 0x0f,
-+ 0x79, 0x09, 0x09, 0x09, 0x09, 0x19, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08,
-+ 0xf8, 0x08, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x12, 0x12, 0x7a, 0x17, 0x15, 0x15, 0x1b,
-+ 0x72, 0x12, 0x15, 0x19, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x70, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,
-+ 0x90, 0x94, 0x14, 0x0c, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x12, 0x09, 0x09, 0x7f, 0x04, 0x08, 0x1f, 0x61,
-+ 0x1f, 0x01, 0x3f, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xfc, 0x40, 0x60, 0x98, 0x04,
-+ 0xf0, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x0b, 0x4a, 0x23, 0x22, 0x0b, 0x0a, 0x13,
-+ 0x21, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x1f, 0x11, 0x1f, 0x11, 0x11,
-+ 0x19, 0x15, 0x25, 0x21, 0x5f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0xe8, 0x08, 0xf8, 0x40,
-+ 0x48, 0x48, 0x50, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7f, 0x01, 0x3e, 0x00, 0x3f,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf8, 0x40, 0x40, 0x40, 0xfc,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x08, 0x28, 0x2e,
-+ 0x28, 0x28, 0x28, 0x2e, 0x38, 0x60, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xf8, 0x88, 0x88, 0x88,
-+ 0xf8, 0x88, 0x80, 0x80, 0xfc, 0x80, 0x00, 0x00,
-+ 0x08, 0x09, 0x15, 0x13, 0x23, 0x5d, 0x09, 0x7f,
-+ 0x09, 0x2b, 0x1d, 0x19, 0x0e, 0x70, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x20, 0xfc, 0x20,
-+ 0x20, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x10, 0x08, 0x09, 0x41, 0x22, 0x27, 0x02, 0x13,
-+ 0x12, 0x13, 0x20, 0x25, 0x44, 0x48, 0x00, 0x00,
-+ 0x80, 0x80, 0xf0, 0x20, 0x40, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xf8, 0x00, 0x48, 0xa4, 0xa4, 0x00, 0x00,
-+ 0x12, 0x13, 0x2d, 0x4f, 0x11, 0x35, 0x55, 0x15,
-+ 0x1e, 0x1f, 0x00, 0x7f, 0x19, 0x63, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0xe8, 0x28, 0xe8, 0x28, 0xf8,
-+ 0x20, 0xf0, 0x00, 0xfc, 0x30, 0x0c, 0x00, 0x00,
-+ 0x04, 0x07, 0x08, 0x11, 0x3f, 0x51, 0x1f, 0x11,
-+ 0x11, 0x1f, 0x00, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x00, 0xc0, 0x80, 0x00, 0xf0, 0x10, 0xf0, 0x10,
-+ 0x10, 0xf0, 0x00, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x01, 0x7f, 0x00, 0x0f, 0x08, 0x0f, 0x00, 0x1f,
-+ 0x00, 0x01, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xe0, 0x20, 0xe0, 0x00, 0xe0,
-+ 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x7f, 0x00, 0x0f, 0x08, 0x0f, 0x00, 0x1f,
-+ 0x00, 0x01, 0x7f, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xe0, 0x20, 0xe0, 0x00, 0xe0,
-+ 0x40, 0x80, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x00, 0x0f, 0x08, 0x08, 0x0f,
-+ 0x01, 0x09, 0x09, 0x11, 0x21, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xe0, 0x20, 0x20, 0xe0,
-+ 0x00, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x09, 0x09, 0x09, 0x11, 0x17, 0x31, 0x51, 0x11,
-+ 0x1f, 0x10, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xf8, 0x20, 0x20, 0x20,
-+ 0xfc, 0x00, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x17, 0x12, 0x31, 0x51, 0x1f,
-+ 0x10, 0x10, 0x10, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x48, 0x48, 0x50, 0xfc,
-+ 0x40, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x1f, 0x11, 0x33, 0x55, 0x19,
-+ 0x17, 0x14, 0x15, 0x15, 0x15, 0x14, 0x00, 0x00,
-+ 0x30, 0xc0, 0x80, 0xfc, 0x20, 0xf0, 0x28, 0xe4,
-+ 0xf8, 0x08, 0xe8, 0x28, 0xe8, 0x18, 0x00, 0x00,
-+ 0x00, 0x20, 0x2d, 0x23, 0x22, 0x24, 0x28, 0x3f,
-+ 0x24, 0x04, 0x08, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x80, 0x90, 0x10, 0x10, 0x90, 0x90, 0x10, 0xf0,
-+ 0x90, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x08, 0x3f, 0x14, 0x14, 0x7f, 0x00, 0x3e,
-+ 0x22, 0x3e, 0x14, 0x15, 0x26, 0x45, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x50, 0x50, 0xfc, 0x00, 0xf8,
-+ 0x88, 0xf8, 0x50, 0x50, 0x94, 0x0c, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x04, 0x3f, 0x04, 0x04, 0x04,
-+ 0x7f, 0x00, 0x04, 0x04, 0x08, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0x40,
-+ 0xfc, 0x00, 0x40, 0x20, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x40, 0x58, 0x46, 0x41, 0x41, 0x42,
-+ 0x44, 0x48, 0x50, 0x7f, 0x40, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0x48, 0x88, 0x88, 0x08, 0x88, 0x48,
-+ 0x28, 0x28, 0x08, 0xf8, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x10, 0x7c, 0x11, 0x12, 0x12,
-+ 0x1f, 0x12, 0x12, 0x14, 0x14, 0x19, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x48, 0x88, 0x08, 0x30, 0x10,
-+ 0xfc, 0x94, 0x94, 0xa4, 0xa4, 0xcc, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x2f, 0x20, 0x20, 0x27, 0x20,
-+ 0x20, 0x20, 0x2f, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x80, 0x80, 0xf0, 0x80,
-+ 0x80, 0x80, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x33, 0x22, 0x2a, 0x2b, 0x2a, 0x2a, 0x2b,
-+ 0x2a, 0x3b, 0x6a, 0x13, 0x16, 0x20, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0x28, 0x28, 0xa8, 0xf0, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x79, 0x49, 0x49, 0x49, 0x49, 0x49,
-+ 0x49, 0x79, 0x4f, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x1c, 0xf0, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x0f, 0x01, 0x7f, 0x04, 0x1f, 0x64, 0x07,
-+ 0x3f, 0x20, 0x27, 0x24, 0x27, 0x20, 0x00, 0x00,
-+ 0x60, 0x80, 0x00, 0xfc, 0x40, 0xf0, 0x4c, 0xc0,
-+ 0xf8, 0x08, 0xc8, 0x48, 0xc8, 0x18, 0x00, 0x00,
-+ 0x00, 0x13, 0x11, 0x10, 0x7f, 0x10, 0x11, 0x11,
-+ 0x15, 0x19, 0x61, 0x00, 0x03, 0x0c, 0x00, 0x00,
-+ 0x40, 0xf8, 0x20, 0xa0, 0xfc, 0x00, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0xa0, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x10, 0x13, 0x10, 0x56, 0x55, 0x55, 0x57,
-+ 0x54, 0x7c, 0x44, 0x41, 0x02, 0x0c, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x48, 0x48, 0x50, 0xfc,
-+ 0x40, 0xa0, 0x90, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x78, 0x08, 0x0f, 0x78, 0x4b, 0x42, 0x7a,
-+ 0x4b, 0x4a, 0x08, 0x08, 0x17, 0x60, 0x00, 0x00,
-+ 0x40, 0x50, 0x88, 0xfc, 0x44, 0xf8, 0x48, 0x48,
-+ 0xf8, 0x50, 0x48, 0x7c, 0xc4, 0x04, 0x00, 0x00,
-+ 0x00, 0x7b, 0x09, 0x09, 0x79, 0x49, 0x43, 0x79,
-+ 0x49, 0x49, 0x09, 0x09, 0x17, 0x60, 0x00, 0x00,
-+ 0x00, 0xf8, 0x50, 0xf0, 0x50, 0xf0, 0xf8, 0xf0,
-+ 0x50, 0xf0, 0x50, 0xf0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x13, 0x38, 0x34, 0x34, 0x57,
-+ 0x10, 0x10, 0x10, 0x11, 0x17, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0x40, 0xfc,
-+ 0x40, 0x90, 0x88, 0x38, 0xc4, 0x04, 0x00, 0x00,
-+ 0x00, 0x7f, 0x09, 0x09, 0x09, 0x0f, 0x72, 0x04,
-+ 0x01, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x90, 0x54, 0x54, 0x0c,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x04, 0x04, 0x3f, 0x04, 0x04, 0x7f, 0x04, 0x0a,
-+ 0x12, 0x62, 0x12, 0x12, 0x22, 0x06, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x40, 0x20,
-+ 0x10, 0x0c, 0x90, 0x48, 0x48, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x78, 0x12, 0x11, 0x11, 0x1f,
-+ 0x70, 0x10, 0x10, 0x11, 0x12, 0x34, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x48, 0x48, 0x50, 0xfc,
-+ 0x40, 0xa0, 0x90, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x3f, 0x0a, 0x0a, 0x7f, 0x09, 0x1f,
-+ 0x22, 0x47, 0x3c, 0x04, 0x05, 0x0e, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x88, 0x88, 0x48,
-+ 0x50, 0x30, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7f, 0x10, 0x19, 0x36, 0x34,
-+ 0x33, 0x52, 0x52, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x18, 0xe0, 0x40, 0xfc, 0xa0, 0xf0, 0xa8, 0xe4,
-+ 0xf8, 0x08, 0xe8, 0xa8, 0xe8, 0x18, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x22, 0x23, 0x02, 0x10,
-+ 0x10, 0x11, 0x21, 0x22, 0x44, 0x48, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0xf8, 0xa8, 0xa0,
-+ 0xa0, 0x20, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x4f, 0x30, 0x10, 0x30, 0x48, 0x0b, 0x18,
-+ 0x28, 0x48, 0x08, 0x08, 0x3f, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x40, 0x40, 0xf8, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x44, 0x28, 0x17, 0x32, 0x49, 0x09, 0x1f,
-+ 0x28, 0x48, 0x08, 0x09, 0x32, 0x14, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x48, 0x48, 0x50, 0xfc,
-+ 0x40, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x3f, 0x28, 0x49, 0x0a, 0x7e,
-+ 0x0b, 0x0e, 0x16, 0x12, 0x22, 0x42, 0x00, 0x00,
-+ 0x18, 0xe0, 0x40, 0xfc, 0xa0, 0xf0, 0xa8, 0xe4,
-+ 0xf8, 0x08, 0xe8, 0xa8, 0xe8, 0x18, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x25, 0x25, 0x3e, 0x25, 0x25,
-+ 0x3d, 0x25, 0x25, 0x25, 0x24, 0x4c, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x24, 0x24, 0xd4, 0x74,
-+ 0xb4, 0x14, 0xf4, 0x14, 0x04, 0x18, 0x00, 0x00,
-+ 0x02, 0x0f, 0x02, 0x0c, 0x7f, 0x12, 0x26, 0x4f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xc0, 0x40, 0xc0, 0xf8, 0x48, 0x98, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x60, 0x00, 0x00,
-+ 0x08, 0x37, 0x24, 0x27, 0x3c, 0x27, 0x3e, 0x27,
-+ 0x24, 0x7f, 0x00, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xc8, 0x78, 0xc8, 0xf8, 0xc8,
-+ 0x48, 0xfc, 0x00, 0x60, 0x10, 0x08, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x1f, 0x01, 0x3f, 0x07, 0x1c,
-+ 0x67, 0x1f, 0x17, 0x14, 0x17, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0x60, 0xc0, 0x00, 0xf8, 0xc0, 0x70,
-+ 0xcc, 0xf0, 0xd0, 0x50, 0xd0, 0x30, 0x00, 0x00,
-+ 0x10, 0x13, 0x16, 0x66, 0x2b, 0x1a, 0x12, 0x1b,
-+ 0x2b, 0x7a, 0x12, 0x13, 0x2c, 0x40, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xa8, 0xb0, 0xb0, 0xa8, 0xa8,
-+ 0x24, 0xa4, 0xe4, 0x78, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x13, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x73, 0x00, 0x00,
-+ 0x20, 0xf8, 0x90, 0xfc, 0x00, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x50, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x13, 0x6a, 0x2b, 0x1f, 0x6a, 0x13, 0x3f, 0x04,
-+ 0x7f, 0x0f, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0xb8, 0xa8, 0xb8, 0xa4, 0xf8, 0x60, 0xf8, 0x40,
-+ 0xfc, 0xe0, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x11, 0x5b, 0x2b, 0x16, 0x7f, 0x0b, 0x33, 0x07,
-+ 0x1f, 0x67, 0x07, 0x04, 0x07, 0x38, 0x00, 0x00,
-+ 0x38, 0xa8, 0xb0, 0xa8, 0xe4, 0xf8, 0xa0, 0xc0,
-+ 0xf0, 0xcc, 0xc0, 0xb0, 0x60, 0x18, 0x00, 0x00,
-+ 0x14, 0x7f, 0x14, 0x3f, 0x7a, 0x2a, 0x3f, 0x08,
-+ 0x0f, 0x0f, 0x0f, 0x2a, 0x25, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x48, 0x30, 0xcc, 0xf0, 0x80,
-+ 0xe0, 0xe0, 0xf8, 0x48, 0x28, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x12, 0x12, 0x32, 0x52, 0x12,
-+ 0x12, 0x13, 0x1e, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x80, 0x78, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0xc8, 0x70, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x09, 0x4e, 0x28, 0x27, 0x04, 0x17, 0x1a,
-+ 0x22, 0x3f, 0x46, 0x45, 0x48, 0x11, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xb0, 0x90, 0x7c, 0x98, 0x50,
-+ 0x5c, 0xd0, 0x50, 0x70, 0x90, 0x0c, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x01, 0x09, 0x7f, 0x08, 0x08,
-+ 0x7f, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0x20, 0xfc, 0x20, 0x20,
-+ 0xfc, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x48, 0x49, 0x4f, 0x79, 0x49,
-+ 0x4f, 0x48, 0x78, 0x49, 0x42, 0x0c, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x50, 0xfc, 0x10, 0x10,
-+ 0xfc, 0xa0, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x02, 0x12, 0x0a, 0x7f, 0x04, 0x3f, 0x01, 0x1f,
-+ 0x01, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x80, 0x90, 0xa0, 0xfc, 0x40, 0xf8, 0x00, 0xf0,
-+ 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x1f, 0x10,
-+ 0x13, 0x12, 0x12, 0x23, 0x22, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x00, 0xfc, 0x04,
-+ 0xe4, 0x24, 0x24, 0xe4, 0x24, 0x18, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x3f, 0x24, 0x24, 0x24, 0x3f,
-+ 0x24, 0x24, 0x24, 0x3f, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0x48, 0xf8, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7c, 0x11, 0x11, 0x3b, 0x36,
-+ 0x36, 0x53, 0x52, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xdc, 0x24, 0xb4, 0xa8,
-+ 0xa8, 0xb4, 0x24, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x01, 0x01, 0x01, 0x1f, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00,
-+ 0x20, 0x10, 0x10, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x13, 0x12, 0x3a, 0x36,
-+ 0x36, 0x52, 0x52, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0xe8, 0xa8,
-+ 0xa8, 0xe8, 0xa8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2a, 0x2c, 0x08, 0x7e, 0x09, 0x1c,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x09, 0x09, 0x0f, 0x11, 0x13, 0x32, 0x53, 0x10,
-+ 0x13, 0x10, 0x13, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0xf8, 0x48, 0xf8, 0x40,
-+ 0xf8, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x14, 0x7f, 0x14, 0x3e, 0x2b, 0x2a, 0x3e, 0x08,
-+ 0x3e, 0x08, 0x3e, 0x08, 0x0e, 0x79, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x88, 0x88, 0x30, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x11, 0x7e, 0x13, 0x14, 0x10,
-+ 0x10, 0x14, 0x1b, 0x60, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x88, 0x88,
-+ 0x28, 0xc8, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x3f, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x30, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x09, 0x2b, 0x1d, 0x19, 0x0f, 0x70, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x20,
-+ 0xfc, 0x24, 0x24, 0x24, 0x38, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x08,
-+ 0x08, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00,
-+ 0x10, 0x60, 0x80, 0x00, 0x00, 0xfc, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x02, 0x1c, 0x10, 0x10, 0x1f, 0x15, 0x14,
-+ 0x14, 0x14, 0x24, 0x24, 0x45, 0x06, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa8, 0x30, 0x20,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x09, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x72, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa8, 0x30, 0x20,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x3e, 0x08, 0x3e, 0x08, 0x0f, 0x72, 0x04,
-+ 0x1f, 0x60, 0x0f, 0x00, 0x00, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0xf8, 0x20, 0xfc, 0x80, 0x40,
-+ 0xf0, 0x0c, 0xe0, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x1c, 0x1a, 0x2a, 0x49, 0x0f,
-+ 0x00, 0x7f, 0x09, 0x11, 0x61, 0x03, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x60, 0x70, 0xa8, 0x24, 0xe0,
-+ 0x00, 0xfc, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00,
-+ 0x01, 0x02, 0x05, 0x1f, 0x6a, 0x09, 0x0e, 0x0f,
-+ 0x01, 0x1f, 0x12, 0x1f, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0xf0, 0xac, 0xa0, 0x60, 0xe0,
-+ 0x00, 0xf0, 0x90, 0xd0, 0x50, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x14, 0x23, 0x40, 0x1e, 0x13,
-+ 0x1e, 0x12, 0x1e, 0x22, 0x22, 0x47, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0x40, 0x40, 0xf8,
-+ 0x48, 0x48, 0x48, 0x88, 0x88, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3e, 0x22, 0x3e, 0x3f, 0x21,
-+ 0x0e, 0x01, 0x7f, 0x0d, 0x31, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x50, 0x20, 0xd0, 0x0c, 0x20,
-+ 0x60, 0x98, 0xe4, 0x30, 0x08, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x04, 0x0f, 0x08, 0x0f,
-+ 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x70, 0xc0, 0x00, 0xfc,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3f, 0x20, 0x2f, 0x21, 0x3f,
-+ 0x23, 0x25, 0x39, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x68, 0x88, 0x08, 0xf8,
-+ 0x88, 0x48, 0x28, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x08, 0x0b, 0x12, 0x3c,
-+ 0x55, 0x12, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x60, 0xa0, 0x90, 0xf8, 0x04, 0x00,
-+ 0xf8, 0x10, 0x10, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x09, 0x0a, 0x14, 0x19,
-+ 0x34, 0x57, 0x11, 0x11, 0x12, 0x10, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0xd0, 0xb8, 0xd4, 0x90, 0xf8,
-+ 0x00, 0xfc, 0x28, 0x24, 0x24, 0x60, 0x00, 0x00,
-+ 0x00, 0x3c, 0x03, 0x7c, 0x03, 0x3e, 0x03, 0x3c,
-+ 0x03, 0x3c, 0x27, 0x24, 0x3f, 0x20, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x90, 0xf8, 0x48, 0xf8, 0x40,
-+ 0xf8, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x20, 0x13, 0x12, 0x02, 0x03, 0x02, 0x72,
-+ 0x12, 0x14, 0x14, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x10, 0x60, 0x80, 0x00, 0x00, 0xfc, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x00, 0xfc, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x04, 0x18, 0x67, 0x01, 0x3f,
-+ 0x01, 0x09, 0x05, 0x05, 0x3f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x40, 0x30, 0xcc, 0x00, 0xf8,
-+ 0x00, 0x20, 0x20, 0x40, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x48, 0x49, 0x4b, 0x4c, 0x48,
-+ 0x4b, 0x78, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xf8, 0x04, 0x00,
-+ 0xf8, 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x73, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x88, 0xf8,
-+ 0xa4, 0xa8, 0x90, 0xb0, 0xc8, 0x04, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x02, 0x7f, 0x02, 0x02, 0x02,
-+ 0x04, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x44, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x12, 0x13, 0x32, 0x53, 0x12,
-+ 0x13, 0x10, 0x1f, 0x11, 0x12, 0x1c, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x00, 0xfc, 0x20, 0x10, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x1f, 0x10, 0x2f, 0x48, 0x08,
-+ 0x08, 0x0f, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x20, 0x20, 0x2c, 0x23, 0x20,
-+ 0x21, 0x22, 0x24, 0x28, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80,
-+ 0x40, 0x20, 0x20, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x48, 0x30, 0x11, 0x31, 0x4a, 0x0d, 0x19,
-+ 0x29, 0x49, 0x09, 0x08, 0x30, 0x10, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf8, 0x08, 0x08, 0xe8, 0x28,
-+ 0x28, 0xe8, 0x28, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x10, 0x11, 0x11, 0x7e, 0x10,
-+ 0x10, 0x14, 0x18, 0x61, 0x02, 0x0c, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf0, 0x10, 0x10, 0x20, 0x20,
-+ 0x60, 0x60, 0x90, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x3f, 0x28, 0x48, 0x08, 0x7f,
-+ 0x08, 0x0c, 0x14, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xf8, 0x88, 0x88, 0x88,
-+ 0xf8, 0x88, 0x80, 0x80, 0xfc, 0x80, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x05, 0x01, 0x7f, 0x01,
-+ 0x01, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x00, 0xfc, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x08, 0x10, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x23,
-+ 0x3e, 0x66, 0x0a, 0x12, 0x62, 0x06, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x88, 0x88, 0xc8, 0xb0, 0x90,
-+ 0x90, 0xa8, 0xc8, 0x80, 0xfc, 0x80, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3e, 0x28, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x42, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0x88, 0xc8, 0xb0, 0x90, 0x90,
-+ 0xa8, 0xa8, 0xc0, 0x80, 0xfc, 0x80, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3e, 0x28, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x43, 0x0c, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0x80, 0x80, 0xfc, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3f, 0x28, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x42, 0x0c, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x88, 0xe8, 0xa8, 0xa8,
-+ 0xe8, 0xa8, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x0f, 0x08,
-+ 0x0f, 0x00, 0x7f, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0xe0, 0x20,
-+ 0xe0, 0x00, 0xfc, 0x60, 0x10, 0x08, 0x00, 0x00,
-+ 0x00, 0x0f, 0x09, 0x0f, 0x09, 0x0f, 0x3f, 0x21,
-+ 0x2f, 0x21, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0xf8, 0x48,
-+ 0xe8, 0x38, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x11, 0x1f, 0x10, 0x15, 0x15,
-+ 0x15, 0x17, 0x20, 0x3f, 0x46, 0x18, 0x00, 0x00,
-+ 0x00, 0xf0, 0xfc, 0xe8, 0x08, 0xf8, 0xf0, 0x10,
-+ 0xf0, 0xe0, 0x20, 0xfc, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x49, 0x4e, 0x49, 0x49, 0x49,
-+ 0x49, 0x79, 0x49, 0x41, 0x01, 0x0f, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xf0, 0x0c, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf8, 0x48, 0x30, 0xd8, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x24, 0x44, 0x08, 0x10, 0x00,
-+ 0x1f, 0x01, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x88, 0x80, 0x88, 0x78, 0x00,
-+ 0xf0, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x13, 0x12, 0x33, 0x50, 0x17,
-+ 0x14, 0x14, 0x17, 0x14, 0x14, 0x14, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0xf0, 0x90, 0xf0, 0x80, 0xf8,
-+ 0xa8, 0xf8, 0x18, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x3f, 0x20, 0x4f, 0x09, 0x0f, 0x09, 0x0f,
-+ 0x01, 0x3f, 0x21, 0x2f, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xe0, 0x20, 0xe0, 0x20, 0xe0,
-+ 0x00, 0xf8, 0x48, 0xe8, 0x28, 0x18, 0x00, 0x00,
-+ 0x00, 0x23, 0x12, 0x13, 0x02, 0x03, 0x70, 0x17,
-+ 0x14, 0x14, 0x17, 0x1c, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0xf0, 0x90, 0xf0, 0x80, 0xf8,
-+ 0xa8, 0xf8, 0x08, 0x18, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x29, 0x31, 0x29, 0x25, 0x24,
-+ 0x27, 0x26, 0x3a, 0x23, 0x22, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0xf8, 0x40,
-+ 0xfc, 0x54, 0x7c, 0x8c, 0x04, 0x0c, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x11, 0x11, 0x1f, 0x01, 0x3f,
-+ 0x21, 0x21, 0x3f, 0x21, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x12, 0x13, 0x13, 0x7c, 0x10, 0x1b, 0x36, 0x37,
-+ 0x32, 0x53, 0x53, 0x12, 0x13, 0x1c, 0x00, 0x00,
-+ 0x20, 0xfc, 0x30, 0xc8, 0x00, 0xb8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0x28, 0xb0, 0xe0, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1d, 0x19, 0x0e, 0x74, 0x00, 0x00,
-+ 0x08, 0x88, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0x28, 0x28, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x14, 0x12, 0x17, 0x14,
-+ 0x17, 0x14, 0x27, 0x24, 0x44, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x90, 0xa0, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x14, 0x14, 0x17,
-+ 0x14, 0x18, 0x28, 0x28, 0x4f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x88, 0x90, 0x90, 0xf0,
-+ 0x90, 0x88, 0x88, 0x88, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x12, 0x12, 0x1e,
-+ 0x72, 0x13, 0x15, 0x15, 0x19, 0x31, 0x00, 0x00,
-+ 0x00, 0xfc, 0x04, 0xfc, 0x24, 0xa8, 0xa8, 0xf8,
-+ 0xa8, 0x24, 0x24, 0x24, 0xfc, 0x04, 0x00, 0x00,
-+ 0x01, 0x3f, 0x26, 0x58, 0x1f, 0x10, 0x1f, 0x14,
-+ 0x14, 0x17, 0x28, 0x28, 0x4f, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0x78, 0xf8, 0x08, 0xf8, 0x90,
-+ 0x90, 0xf0, 0x88, 0x88, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x05, 0x09, 0x11, 0x63, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x08, 0x90, 0x60, 0x20, 0x10, 0x0c, 0xe0,
-+ 0x20, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x14, 0x14, 0x7f, 0x14, 0x1c, 0x09, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x60, 0x60, 0x60, 0xa4, 0xa4, 0xa8, 0xb0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa4, 0xa4, 0x9c, 0x00, 0x00,
-+ 0x21, 0x2f, 0x4f, 0x35, 0x2f, 0x7d, 0x37, 0x5f,
-+ 0x11, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x10, 0xd4, 0xe4, 0x58, 0xd4, 0x7c, 0xd8, 0xf4,
-+ 0x10, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x01, 0x3f, 0x24, 0x44, 0x08, 0x10, 0x0b, 0x48,
-+ 0x27, 0x20, 0x0b, 0x08, 0x17, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0x88, 0x78, 0x40, 0xf8, 0x40,
-+ 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x12, 0x7f, 0x01, 0x3e, 0x22, 0x3e, 0x22,
-+ 0x3e, 0x22, 0x26, 0x14, 0x22, 0x42, 0x00, 0x00,
-+ 0x40, 0x48, 0x70, 0x44, 0x3c, 0x40, 0x4c, 0x70,
-+ 0x40, 0x44, 0x3c, 0x90, 0x48, 0x44, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x29, 0x31, 0x29, 0x24, 0x27,
-+ 0x25, 0x25, 0x39, 0x21, 0x21, 0x26, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x00, 0xfc,
-+ 0x48, 0x30, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x01, 0x07, 0x18, 0x01, 0x07, 0x79, 0x09, 0x05,
-+ 0x3f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0xe0, 0x40, 0xc0, 0x30, 0x2c, 0x20, 0x40,
-+ 0xf8, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x1f, 0x12, 0x12, 0x1f, 0x01,
-+ 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0xf0, 0x90, 0x90, 0xf0, 0x00,
-+ 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0d, 0x13, 0x7f,
-+ 0x08, 0x2d, 0x2a, 0x2a, 0x49, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x00, 0xdc, 0x54, 0xdc,
-+ 0x20, 0xfc, 0x70, 0xa8, 0x24, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x04, 0x03, 0x3e, 0x12, 0x0d, 0x1b,
-+ 0x61, 0x3f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x00, 0xe0, 0x40, 0x80, 0xf8, 0x48, 0x30, 0xc8,
-+ 0x04, 0xf8, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x1b, 0x24, 0x24, 0x7b, 0x10, 0x7d,
-+ 0x11, 0x55, 0x3a, 0x30, 0x1c, 0x60, 0x00, 0x00,
-+ 0x50, 0x90, 0x90, 0x94, 0xb4, 0xf4, 0xb8, 0xd0,
-+ 0xb0, 0x98, 0xa8, 0xa8, 0xc4, 0x84, 0x00, 0x00,
-+ 0x02, 0x3c, 0x7f, 0x3f, 0x2a, 0x3e, 0x2a, 0x3e,
-+ 0x3e, 0x0f, 0x79, 0x00, 0x24, 0x42, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0x48,
-+ 0x88, 0x88, 0x30, 0x00, 0x88, 0x44, 0x00, 0x00,
-+ 0x00, 0x1f, 0x02, 0x02, 0x7f, 0x02, 0x02, 0x1f,
-+ 0x04, 0x0f, 0x14, 0x24, 0x47, 0x04, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0xfc, 0x20, 0x20, 0xe0,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0f, 0x7f, 0x0f, 0x09, 0x0f,
-+ 0x09, 0x0f, 0x1f, 0x7f, 0x12, 0x61, 0x00, 0x00,
-+ 0x40, 0xfc, 0x60, 0xc0, 0xfc, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0xf0, 0xfc, 0x48, 0x24, 0x00, 0x00,
-+ 0x00, 0x3e, 0x00, 0x7f, 0x00, 0x3e, 0x00, 0x3e,
-+ 0x00, 0x3e, 0x22, 0x23, 0x3f, 0x22, 0x00, 0x00,
-+ 0x08, 0x88, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x3e, 0x12, 0x13, 0x7f, 0x12, 0x3e, 0x10,
-+ 0x1e, 0x33, 0x32, 0x52, 0x1e, 0x10, 0x00, 0x00,
-+ 0x88, 0x48, 0x50, 0xfc, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x7f, 0x01, 0x1f, 0x11, 0x1f,
-+ 0x11, 0x1f, 0x01, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf8, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x09, 0x09, 0x7f, 0x09, 0x3f, 0x08,
-+ 0x0f, 0x19, 0x19, 0x29, 0x4f, 0x09, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x50, 0xd0, 0x60, 0x50, 0x48,
-+ 0x44, 0x44, 0x64, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x3f, 0x04, 0x04, 0x7f, 0x04,
-+ 0x04, 0x3f, 0x04, 0x04, 0x07, 0x7c, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xa0, 0x20, 0x30, 0xe8, 0x24,
-+ 0x24, 0xa0, 0x20, 0x20, 0xa0, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x7e, 0x12, 0x12, 0x22, 0x4d, 0x01,
-+ 0x7f, 0x03, 0x0c, 0x74, 0x07, 0x38, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00,
-+ 0xfc, 0x10, 0xa0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7e, 0x02, 0x04, 0x08, 0x1c,
-+ 0x2a, 0x4a, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x90, 0x90, 0xa0, 0x90, 0x88,
-+ 0x84, 0x84, 0xc4, 0xb8, 0x80, 0x80, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x10, 0x13, 0x30, 0x50, 0x11,
-+ 0x17, 0x10, 0x12, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x18, 0xe0, 0x90, 0x90, 0x20, 0xd0, 0x98, 0xe4,
-+ 0x40, 0x50, 0x48, 0x44, 0x44, 0x40, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x14, 0x15, 0x35, 0x56, 0x14,
-+ 0x14, 0x15, 0x15, 0x13, 0x10, 0x11, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0x20, 0x78, 0x48, 0x78, 0x48,
-+ 0x78, 0x48, 0x78, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x00, 0x3f, 0x12, 0x12, 0x12, 0x12, 0x7f, 0x12,
-+ 0x12, 0x12, 0x12, 0x22, 0x22, 0x42, 0x00, 0x00,
-+ 0x08, 0xc8, 0x48, 0x48, 0x48, 0x48, 0xc8, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x10, 0x1f, 0x15, 0x05,
-+ 0x05, 0x09, 0x09, 0x11, 0x21, 0x40, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0x20, 0xe0, 0x20, 0x00,
-+ 0x00, 0x00, 0x08, 0x08, 0x08, 0xf8, 0x00, 0x00,
-+ 0x00, 0x7f, 0x00, 0x3f, 0x22, 0x22, 0x3e, 0x23,
-+ 0x20, 0x4f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x90, 0x90, 0x60, 0x60, 0x90,
-+ 0x0c, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x01, 0x01, 0x7f, 0x01, 0x01,
-+ 0x3f, 0x01, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0xf8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x7f, 0x10, 0x10, 0x17, 0x7c, 0x10,
-+ 0x13, 0x14, 0x18, 0x60, 0x0f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x12, 0x12, 0x7f, 0x12, 0x12, 0x22,
-+ 0x41, 0x1f, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x08, 0xc8, 0x48, 0x48, 0xc8, 0x48, 0x48, 0x18,
-+ 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x7f, 0x08, 0x3e, 0x08, 0x0f, 0x71,
-+ 0x01, 0x7f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x88, 0x08, 0x30,
-+ 0x00, 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x12, 0x12, 0x12, 0x12, 0x7f, 0x12,
-+ 0x12, 0x12, 0x12, 0x22, 0x22, 0x42, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0x20, 0x48, 0x08, 0x90, 0x10,
-+ 0x24, 0x04, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x08, 0x0b, 0x11, 0x24, 0x04, 0x09, 0x1e, 0x28,
-+ 0x4b, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x10, 0xa0, 0x40, 0xf0, 0x4c, 0x40,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x1f, 0x11, 0x1f, 0x11, 0x1f,
-+ 0x01, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x1f, 0x12, 0x1f, 0x1f, 0x15,
-+ 0x19, 0x13, 0x2d, 0x20, 0x43, 0x1c, 0x00, 0x00,
-+ 0x80, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0xfc, 0x58,
-+ 0xe4, 0xf4, 0x20, 0xc0, 0x60, 0x1c, 0x00, 0x00,
-+ 0x08, 0x7f, 0x08, 0x3e, 0x0f, 0x78, 0x0f, 0x07,
-+ 0x00, 0x0f, 0x25, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0xfc, 0x20, 0xe0, 0xe0,
-+ 0x20, 0xe0, 0x08, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x02, 0x3c, 0x08, 0x7f, 0x08, 0x3e, 0x22, 0x3e,
-+ 0x20, 0x05, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x20, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0xf8,
-+ 0x88, 0x00, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x11, 0x11, 0x10, 0x1d,
-+ 0x73, 0x15, 0x11, 0x11, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x80, 0xfc,
-+ 0x34, 0xc4, 0x04, 0x14, 0xf4, 0x18, 0x00, 0x00,
-+ 0x11, 0x11, 0x13, 0x7f, 0x15, 0x11, 0x11, 0x15,
-+ 0x1f, 0x71, 0x11, 0x11, 0x12, 0x34, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0x20, 0xf8, 0x20, 0xfc,
-+ 0xe0, 0x20, 0x3c, 0x04, 0x04, 0x18, 0x00, 0x00,
-+ 0x14, 0x14, 0x7f, 0x14, 0x10, 0x1e, 0x23, 0x7a,
-+ 0x2a, 0x2a, 0x3a, 0x22, 0x02, 0x0d, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0x88, 0x88, 0x48, 0x50,
-+ 0x30, 0x20, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x01, 0x7f,
-+ 0x0f, 0x08, 0x0f, 0x05, 0x09, 0x33, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x00, 0xfc,
-+ 0xe0, 0x20, 0xe0, 0x60, 0x10, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7e, 0x08, 0x1b, 0x1c, 0x1a,
-+ 0x2b, 0x28, 0x48, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x21, 0x21, 0x00, 0x13,
-+ 0x10, 0x17, 0x20, 0x20, 0x41, 0x46, 0x00, 0x00,
-+ 0x08, 0x70, 0x88, 0x48, 0x50, 0x20, 0x40, 0xf8,
-+ 0x40, 0xfc, 0xc0, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x7f, 0x54, 0x54, 0x57, 0x7c, 0x54,
-+ 0x57, 0x54, 0x7c, 0x44, 0x07, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x02, 0x0d, 0x78, 0x08, 0x09, 0x7e, 0x08, 0x1c,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x28, 0xfc, 0x60, 0xa4, 0x9c, 0xf0, 0x84, 0x7c,
-+ 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3f, 0x02, 0x02, 0x1c, 0x03, 0x01, 0x7f,
-+ 0x01, 0x09, 0x09, 0x11, 0x21, 0x01, 0x00, 0x00,
-+ 0x38, 0xc0, 0x20, 0x20, 0x40, 0x90, 0x08, 0xfc,
-+ 0x04, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x0a, 0x72, 0x14, 0x0c, 0x13, 0x7f,
-+ 0x0c, 0x2a, 0x2a, 0x28, 0x4b, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x50, 0x20, 0x70, 0xac, 0x20,
-+ 0xf8, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x0b, 0x73, 0x15, 0x0d, 0x13, 0x7f,
-+ 0x09, 0x2d, 0x2b, 0x2b, 0x49, 0x09, 0x00, 0x00,
-+ 0x20, 0x20, 0xa8, 0x68, 0x70, 0x20, 0xfc, 0x20,
-+ 0x70, 0xa8, 0x28, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x7f, 0x3e, 0x2a, 0x3f, 0x2a, 0x3e, 0x7f,
-+ 0x0a, 0x0e, 0x01, 0x7f, 0x0d, 0x31, 0x00, 0x00,
-+ 0x00, 0x70, 0x54, 0x8c, 0xf8, 0x90, 0x60, 0xb0,
-+ 0x4c, 0xc0, 0x70, 0x88, 0x30, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x04, 0x3f, 0x04, 0x7f,
-+ 0x04, 0x3f, 0x04, 0x07, 0x78, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x20, 0x20, 0x30, 0xa8,
-+ 0x24, 0x24, 0x20, 0xa0, 0x20, 0x20, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x1f, 0x04, 0x03, 0x0d,
-+ 0x71, 0x0f, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf0, 0x60, 0x80, 0x60,
-+ 0x1c, 0xe0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x00, 0x3f, 0x12, 0x12,
-+ 0x7f, 0x12, 0x12, 0x12, 0x22, 0x42, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0x48, 0x48, 0x48,
-+ 0xc8, 0x48, 0x48, 0x48, 0x08, 0x18, 0x00, 0x00,
-+ 0x12, 0x09, 0x09, 0x3f, 0x21, 0x41, 0x0f, 0x09,
-+ 0x09, 0x0f, 0x09, 0x01, 0x01, 0x3e, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xfc, 0x08, 0x00, 0xe0, 0x20,
-+ 0x20, 0xe0, 0x20, 0x10, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x01, 0x3c, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x00, 0x3c, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x80, 0x98, 0xe0, 0x80, 0x84, 0x7c, 0x00, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x12, 0x7f, 0x1f, 0x3d, 0x55, 0x1e, 0x07, 0x7f,
-+ 0x07, 0x07, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0xfc, 0xc8, 0x50, 0x30, 0xcc, 0xc0, 0xfc,
-+ 0xc0, 0xc0, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x08, 0x09, 0x7e, 0x08, 0x3e, 0x2a, 0x3f, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x09, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x50, 0x20, 0xf0, 0x2c, 0x20,
-+ 0xf8, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x34, 0x0c, 0x1a, 0x29, 0x48,
-+ 0x3e, 0x08, 0x08, 0x0e, 0x70, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x02, 0x0c, 0x72, 0x4a, 0x2c, 0x08, 0x3e, 0x08,
-+ 0x7e, 0x08, 0x14, 0x13, 0x21, 0x42, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x38, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x04, 0x1f, 0x00, 0x00,
-+ 0x7f, 0x02, 0x02, 0x04, 0x3f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf0, 0x00, 0x00,
-+ 0xfc, 0x40, 0x20, 0xf0, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x20, 0x13, 0x12, 0x02, 0x02, 0x72, 0x12,
-+ 0x13, 0x1e, 0x10, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x80, 0x78, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0xc8, 0x70, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x29, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x00, 0xf8, 0x88, 0x88, 0xf8,
-+ 0x20, 0xb0, 0xa8, 0xa4, 0x24, 0x60, 0x00, 0x00,
-+ 0x04, 0x07, 0x3f, 0x26, 0x3b, 0x3f, 0x26, 0x3c,
-+ 0x27, 0x3b, 0x26, 0x3a, 0x42, 0x0c, 0x00, 0x00,
-+ 0x08, 0xa8, 0xe8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0x28, 0x28, 0xa8, 0x88, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3f, 0x22, 0x3e, 0x22,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x09, 0x08, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x5c, 0xe0, 0x48, 0x48, 0x50,
-+ 0x30, 0x20, 0x60, 0x94, 0x0c, 0x04, 0x00, 0x00,
-+ 0x08, 0x7f, 0x3e, 0x2a, 0x3f, 0x3e, 0x7f, 0x08,
-+ 0x0f, 0x1f, 0x01, 0x7f, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0x70, 0x54, 0x8c, 0xf8, 0x50, 0x30, 0xcc,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x21, 0x12, 0x17, 0x44, 0x27, 0x24, 0x07, 0x12,
-+ 0x1f, 0x13, 0x24, 0x24, 0x4b, 0x50, 0x00, 0x00,
-+ 0x20, 0x20, 0xa0, 0xa0, 0xfc, 0xc8, 0xa8, 0x28,
-+ 0xe8, 0x90, 0x90, 0xa8, 0x48, 0x84, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x2a, 0x31, 0x29, 0x25, 0x25,
-+ 0x25, 0x25, 0x39, 0x22, 0x24, 0x20, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x48, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x50, 0x48, 0x44, 0x44, 0xc0, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7e, 0x08, 0x1c, 0x1b, 0x1b,
-+ 0x29, 0x29, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x80, 0xf8, 0x00, 0x00, 0x80, 0xfc, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x09, 0x09, 0x0b, 0x12, 0x15, 0x31, 0x52, 0x14,
-+ 0x1f, 0x10, 0x11, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0xfc, 0xa8, 0xa8, 0x7c, 0x48, 0x48,
-+ 0xfc, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x1f, 0x11, 0x21, 0x41,
-+ 0x01, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x08, 0x10, 0x20,
-+ 0x80, 0x80, 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x47, 0x20, 0x20, 0x00, 0x1f,
-+ 0x10, 0x11, 0x21, 0x22, 0x44, 0x48, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf0, 0x90, 0x90, 0x90, 0xfc,
-+ 0xc0, 0x20, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x22, 0x1f, 0x12, 0x4f, 0x22, 0x23, 0x0c, 0x11,
-+ 0x17, 0x10, 0x2f, 0x22, 0x4c, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0xa8, 0x28, 0xd8, 0xa0, 0x20,
-+ 0x50, 0xb8, 0xc8, 0xb0, 0x88, 0x80, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x40, 0x01, 0x04, 0x04,
-+ 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x00, 0xc0, 0x40, 0x40,
-+ 0x40, 0x20, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x73, 0x14, 0x0c, 0x12, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0x00,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x02, 0x1f, 0x12, 0x12, 0x12,
-+ 0x12, 0x12, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7f, 0x00, 0x3c, 0x00, 0x3f,
-+ 0x00, 0x3c, 0x24, 0x25, 0x3e, 0x24, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0xfc,
-+ 0x40, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08,
-+ 0x0f, 0x08, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x13, 0x12, 0x34, 0x50, 0x17,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0x40, 0xfc,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x12, 0x17, 0x38, 0x57, 0x14,
-+ 0x17, 0x14, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x80, 0x80, 0x40, 0x20, 0xf0, 0x88, 0xf0, 0x90,
-+ 0xf0, 0x90, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00,
-+ 0x08, 0x0a, 0x09, 0x13, 0x10, 0x37, 0x50, 0x11,
-+ 0x12, 0x15, 0x11, 0x11, 0x11, 0x10, 0x00, 0x00,
-+ 0x40, 0x48, 0x50, 0xf8, 0x40, 0xfc, 0xa0, 0xf0,
-+ 0x28, 0xe4, 0x20, 0x08, 0x08, 0xf8, 0x00, 0x00,
-+ 0x08, 0x08, 0x0e, 0x13, 0x12, 0x34, 0x5f, 0x11,
-+ 0x15, 0x15, 0x12, 0x13, 0x14, 0x18, 0x00, 0x00,
-+ 0x20, 0xf8, 0x28, 0xfc, 0x28, 0xf8, 0x20, 0xf8,
-+ 0x20, 0xfc, 0x20, 0x20, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x08, 0x04, 0x7f, 0x04, 0x3f, 0x04, 0x7f, 0x04,
-+ 0x3f, 0x04, 0x1c, 0x64, 0x04, 0x04, 0x00, 0x00,
-+ 0x20, 0x40, 0xfc, 0x80, 0xf0, 0x90, 0xfc, 0x90,
-+ 0xf0, 0xc0, 0xb0, 0x8c, 0x80, 0x80, 0x00, 0x00,
-+ 0x01, 0x11, 0x09, 0x3f, 0x02, 0x7f, 0x04, 0x18,
-+ 0x6f, 0x02, 0x02, 0x04, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x10, 0x20, 0xf8, 0x80, 0xfc, 0x40, 0x30,
-+ 0xec, 0x20, 0x20, 0x20, 0x20, 0xc0, 0x00, 0x00,
-+ 0x04, 0x04, 0x0a, 0x11, 0x7f, 0x04, 0x3f, 0x25,
-+ 0x3f, 0x24, 0x0a, 0x09, 0x11, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x48, 0x48, 0xc8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x4a, 0x4b, 0x48, 0x49, 0x49,
-+ 0x49, 0x79, 0x49, 0x40, 0x0f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x08, 0xf8, 0x00, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x25, 0x2f, 0x22, 0x3f, 0x24, 0x2f,
-+ 0x30, 0x27, 0x24, 0x23, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xe8, 0x88, 0xf8, 0x48, 0xe8,
-+ 0x58, 0xc8, 0x28, 0xe8, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3e, 0x22, 0x3e, 0x24, 0x3f,
-+ 0x21, 0x1f, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x50, 0x50, 0x20, 0xd0, 0x0c,
-+ 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x10, 0x13, 0x10, 0x7d, 0x24, 0x27, 0x24,
-+ 0x79, 0x48, 0x0d, 0x16, 0x24, 0x40, 0x00, 0x00,
-+ 0x08, 0x90, 0xfc, 0xa0, 0xf8, 0xa8, 0xfc, 0xa8,
-+ 0xf8, 0xa0, 0xb0, 0xa8, 0xa4, 0xa0, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x08, 0x17, 0x10, 0x3b, 0x08,
-+ 0x4b, 0x28, 0x17, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8, 0x40,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0xfc, 0x00, 0x00,
-+ 0x01, 0x3f, 0x21, 0x7f, 0x1f, 0x01, 0x7f, 0x1f,
-+ 0x12, 0x1f, 0x25, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf8, 0xf0, 0x00, 0xfc, 0xf0,
-+ 0x90, 0xf0, 0x08, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x1e, 0x52, 0x5e, 0x5e, 0x52, 0x5f, 0x7e, 0x2a,
-+ 0x29, 0x49, 0x04, 0x24, 0x24, 0x43, 0x00, 0x00,
-+ 0x18, 0xe0, 0x28, 0xd0, 0x28, 0xfc, 0x64, 0xa8,
-+ 0x24, 0x20, 0x80, 0x88, 0x24, 0xe4, 0x00, 0x00,
-+ 0x09, 0x11, 0x1f, 0x02, 0x7f, 0x08, 0x1f, 0x61,
-+ 0x1f, 0x01, 0x3f, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x20, 0x10, 0xf0, 0x80, 0xfc, 0x20, 0xd8, 0x04,
-+ 0xf0, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x12, 0x11, 0x7f, 0x10, 0x17, 0x11, 0x13,
-+ 0x1c, 0x71, 0x11, 0x11, 0x11, 0x30, 0x00, 0x00,
-+ 0x40, 0x48, 0x50, 0xf8, 0xa0, 0xfc, 0x10, 0xe8,
-+ 0x24, 0xe0, 0x20, 0x08, 0x08, 0xf8, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x0b, 0x18, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x48, 0x08, 0x0b, 0x0c, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xf8, 0x44, 0xf8, 0x48,
-+ 0x48, 0xf8, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7e, 0x13, 0x30, 0x39, 0x37,
-+ 0x55, 0x51, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x80, 0x80, 0xf8, 0x40, 0xfc, 0x90, 0xfc, 0x20,
-+ 0xf8, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x06, 0x03, 0x7f, 0x44, 0x5f,
-+ 0x09, 0x0f, 0x11, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0xc0, 0x00, 0xfc, 0x48, 0xe0,
-+ 0x10, 0xe0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x7f, 0x01, 0x03, 0x02,
-+ 0x02, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x20, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x80,
-+ 0x80, 0x40, 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x3f, 0x33, 0x2d, 0x3f,
-+ 0x25, 0x3f, 0x25, 0x25, 0x25, 0x23, 0x00, 0x00,
-+ 0x20, 0x28, 0xa4, 0x24, 0xfc, 0x20, 0x20, 0x30,
-+ 0x50, 0x50, 0x48, 0x88, 0x84, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x08, 0x08, 0x08, 0x10, 0x1f, 0x32,
-+ 0x52, 0x12, 0x12, 0x1f, 0x11, 0x02, 0x00, 0x00,
-+ 0x00, 0xf8, 0x90, 0x90, 0x90, 0x90, 0xfc, 0x90,
-+ 0x90, 0x90, 0x90, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x7f, 0x11, 0x11, 0x11, 0x11, 0x3d, 0x25,
-+ 0x65, 0x24, 0x24, 0x3d, 0x22, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0xa0, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0c, 0x12, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x00, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x00, 0x07, 0x24, 0x27, 0x24, 0x27, 0x24, 0x27,
-+ 0x20, 0x3f, 0x25, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x00, 0xfc, 0x60, 0x18, 0x04, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x14, 0x17, 0x24, 0x47, 0x04, 0x04, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x0f, 0x08,
-+ 0x0f, 0x0a, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0xe0, 0x20,
-+ 0xe0, 0xa0, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x01, 0x38, 0x03, 0x7c, 0x03, 0x38, 0x07, 0x38,
-+ 0x03, 0x38, 0x29, 0x2a, 0x3c, 0x20, 0x00, 0x00,
-+ 0x10, 0xa0, 0xfc, 0xa0, 0xf8, 0xa8, 0xfc, 0xa8,
-+ 0xf8, 0xa0, 0xb0, 0xa8, 0xa4, 0xa0, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3e, 0x3e, 0x3f, 0x2f, 0x08,
-+ 0x0f, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x50, 0x70, 0x8c, 0xe0, 0x20,
-+ 0xe0, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x2a, 0x3f, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x23, 0x12, 0x13, 0x00, 0x0f, 0x71, 0x11,
-+ 0x11, 0x11, 0x11, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0xf8, 0x48, 0xf8, 0x40, 0xfc, 0xf0, 0x10,
-+ 0xf0, 0xf8, 0x08, 0xf8, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x10, 0x1b, 0x24, 0x25, 0x79, 0x13, 0x7c,
-+ 0x12, 0x56, 0x39, 0x31, 0x1a, 0x64, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0xa8, 0xfc, 0x28, 0xf8, 0xa0,
-+ 0xf8, 0xa0, 0xfc, 0x20, 0xa0, 0x7c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x29, 0x2b, 0x30, 0x2b, 0x26,
-+ 0x26, 0x27, 0x38, 0x20, 0x21, 0x26, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xf8, 0x44, 0xf8, 0x48,
-+ 0x48, 0xf8, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x3e, 0x22, 0x3e, 0x14, 0x15,
-+ 0x55, 0x36, 0x34, 0x16, 0x18, 0x63, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x29, 0x3e, 0x28, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x42, 0x0d, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x88, 0xfc, 0x20, 0xf8, 0xa8,
-+ 0xa8, 0xf8, 0x60, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x1e, 0x10, 0x7f, 0x52, 0x4e, 0x76,
-+ 0x6e, 0x5a, 0x76, 0x4a, 0x7e, 0x43, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x88, 0xfc, 0x20, 0xf8, 0xa8,
-+ 0xa8, 0xf8, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x00, 0x00, 0x00, 0x7f, 0x04, 0x04,
-+ 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0x00, 0x00, 0xfc, 0x80, 0x80,
-+ 0x80, 0x80, 0x84, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x13, 0x12, 0x13, 0x12, 0x13,
-+ 0x10, 0x12, 0x22, 0x24, 0x48, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x80, 0xa0, 0x90, 0x88, 0x88, 0x80, 0x00, 0x00,
-+ 0x09, 0x04, 0x1f, 0x10, 0x1f, 0x12, 0x1f, 0x15,
-+ 0x17, 0x17, 0x25, 0x3f, 0x41, 0x01, 0x00, 0x00,
-+ 0x08, 0x90, 0xfc, 0x20, 0xa0, 0x20, 0xbc, 0x48,
-+ 0xa8, 0x30, 0x10, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x0a, 0x72, 0x12, 0x0c, 0x04,
-+ 0x0c, 0x0a, 0x12, 0x7d, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x7c, 0x07, 0x04, 0x3c, 0x27, 0x20, 0x3c,
-+ 0x24, 0x24, 0x04, 0x04, 0x0b, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x48, 0x88, 0x90, 0x50,
-+ 0x20, 0x20, 0x50, 0x88, 0xf4, 0x04, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x47, 0x24, 0x27, 0x04, 0x17,
-+ 0x16, 0x16, 0x27, 0x2a, 0x48, 0x51, 0x00, 0x00,
-+ 0x20, 0x28, 0x24, 0xfc, 0x20, 0xe8, 0x28, 0xa8,
-+ 0xb0, 0x90, 0xb4, 0x4c, 0x8c, 0x04, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x22, 0x22, 0x02, 0x12,
-+ 0x12, 0x12, 0x24, 0x24, 0x49, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x20, 0xa8, 0xa4, 0x24, 0x60, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x01, 0x02, 0x1a, 0x06,
-+ 0x01, 0x00, 0x01, 0x02, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0x20, 0x20, 0x40, 0x40,
-+ 0x80, 0xa0, 0x10, 0x78, 0x84, 0x04, 0x00, 0x00,
-+ 0x00, 0x01, 0x7d, 0x11, 0x11, 0x11, 0x7d, 0x11,
-+ 0x11, 0x10, 0x1c, 0x61, 0x06, 0x18, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0xa0, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x73, 0x14, 0x0d, 0x12, 0x7e,
-+ 0x0c, 0x2a, 0x2a, 0x28, 0x4b, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x28, 0xc8, 0x50,
-+ 0x30, 0x20, 0x30, 0x48, 0xfc, 0x04, 0x00, 0x00,
-+ 0x04, 0x08, 0x1e, 0x13, 0x1a, 0x16, 0x17, 0x7f,
-+ 0x12, 0x1a, 0x1a, 0x2a, 0x23, 0x46, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x28, 0xc8, 0x50,
-+ 0x30, 0x10, 0x28, 0x48, 0xf4, 0x04, 0x00, 0x00,
-+ 0x00, 0x0f, 0x00, 0x7f, 0x00, 0x0f, 0x00, 0x0f,
-+ 0x00, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xe0, 0x00, 0xfc, 0x00, 0xe0, 0x00, 0xe0,
-+ 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x3c, 0x03, 0x7c, 0x00, 0x3d, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x25, 0x26, 0x3e, 0x25, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x50, 0xfc, 0x10, 0x20,
-+ 0xc8, 0x10, 0x64, 0x08, 0x30, 0xc0, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x29, 0x31, 0x29, 0x25, 0x25,
-+ 0x25, 0x25, 0x39, 0x21, 0x21, 0x26, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0xf0, 0x48,
-+ 0x48, 0x30, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x11, 0x09, 0x09, 0x01, 0x7f,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x30, 0xc0, 0x10, 0x10, 0x20, 0x40, 0x00, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x0f, 0x0c, 0x14, 0x17, 0x34, 0x55, 0x15,
-+ 0x15, 0x15, 0x15, 0x14, 0x17, 0x14, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0xe8, 0x28,
-+ 0x28, 0xe8, 0x28, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x7f, 0x01, 0x01, 0x01, 0x1f,
-+ 0x10, 0x10, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xf0,
-+ 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x03, 0x78, 0x4a, 0x49, 0x49, 0x48, 0x4f,
-+ 0x48, 0x78, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x18, 0xe0, 0x48, 0x48, 0x50, 0x60, 0x40, 0xfc,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x21, 0x3f, 0x21, 0x27, 0x24,
-+ 0x24, 0x27, 0x24, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0xc8, 0x48,
-+ 0x48, 0xc8, 0x48, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x09, 0x7e, 0x12, 0x12, 0x12,
-+ 0x3c, 0x24, 0x06, 0x0a, 0x10, 0x20, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0x20, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3e, 0x03, 0x05, 0x05, 0x09, 0x0d, 0x19,
-+ 0x69, 0x09, 0x0a, 0x0a, 0x0f, 0x18, 0x00, 0x00,
-+ 0x08, 0x30, 0xd0, 0x50, 0x50, 0x50, 0x50, 0x50,
-+ 0x50, 0x68, 0x58, 0x78, 0x94, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x00, 0x00, 0x3f, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x1f, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00,
-+ 0x00, 0x00, 0x08, 0x08, 0x08, 0xf8, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x17, 0x14, 0x17,
-+ 0x14, 0x17, 0x20, 0x3f, 0x40, 0x00, 0x00, 0x00,
-+ 0x80, 0xfc, 0x80, 0xf8, 0x80, 0xf0, 0x90, 0xf0,
-+ 0x90, 0xf0, 0x80, 0xfc, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x7c, 0x05, 0x05, 0x3d, 0x25, 0x21, 0x3d,
-+ 0x25, 0x25, 0x05, 0x06, 0x0b, 0x34, 0x00, 0x00,
-+ 0x08, 0x30, 0xd0, 0x50, 0x50, 0x50, 0x50, 0x50,
-+ 0x50, 0x68, 0x58, 0x7c, 0x94, 0x14, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x1f, 0x10, 0x10, 0x10, 0x1f,
-+ 0x10, 0x10, 0x10, 0x20, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0x08, 0x08, 0xf8,
-+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x09, 0x0a, 0x3e,
-+ 0x22, 0x22, 0x22, 0x3e, 0x23, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x90, 0x90, 0x90, 0x50,
-+ 0x60, 0x20, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x1c, 0x1a, 0x1b,
-+ 0x29, 0x29, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x20, 0x12, 0x12, 0x42, 0x2f, 0x22, 0x02, 0x0f,
-+ 0x19, 0x19, 0x2f, 0x29, 0x40, 0x41, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0xc8, 0x78, 0x48, 0x48,
-+ 0x48, 0x78, 0x48, 0x88, 0x88, 0x18, 0x00, 0x00,
-+ 0x04, 0x44, 0x29, 0x11, 0x31, 0x49, 0x09, 0x19,
-+ 0x29, 0x49, 0x09, 0x0a, 0x33, 0x14, 0x00, 0x00,
-+ 0x08, 0x30, 0xd0, 0x50, 0x50, 0x50, 0x50, 0x50,
-+ 0x50, 0x68, 0x58, 0x78, 0x94, 0x04, 0x00, 0x00,
-+ 0x10, 0x55, 0x35, 0x39, 0x17, 0x7d, 0x11, 0x1b,
-+ 0x36, 0x36, 0x53, 0x12, 0x10, 0x11, 0x00, 0x00,
-+ 0x00, 0x38, 0x28, 0x28, 0xe8, 0x38, 0x28, 0xa8,
-+ 0xb8, 0xa8, 0xc8, 0x48, 0x88, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7c, 0x08, 0x0b, 0x12, 0x3d,
-+ 0x54, 0x12, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x50, 0x88, 0xfc, 0x00, 0xfc,
-+ 0x40, 0x78, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x25, 0x26, 0x3d,
-+ 0x24, 0x24, 0x24, 0x24, 0x25, 0x4e, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0x94, 0x14, 0x0c, 0xf8,
-+ 0x88, 0x90, 0x60, 0x60, 0x90, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x3e,
-+ 0x22, 0x22, 0x22, 0x3f, 0x23, 0x02, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x88, 0xf8,
-+ 0x88, 0x88, 0x88, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x00, 0x3f, 0x05, 0x09,
-+ 0x0d, 0x19, 0x69, 0x0a, 0x0b, 0x1c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x18, 0xf0, 0x50, 0x50,
-+ 0x50, 0x50, 0x68, 0x58, 0xf4, 0x14, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x1f, 0x11, 0x11, 0x1f, 0x10,
-+ 0x12, 0x12, 0x22, 0x24, 0x48, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0x08, 0xf0, 0x08, 0xf8,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x03, 0x7c, 0x01, 0x3e, 0x00, 0x3d,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0xf8, 0x04, 0xf8,
-+ 0x40, 0x78, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3e, 0x23, 0x22, 0x3e, 0x09, 0x28, 0x2f,
-+ 0x28, 0x28, 0x28, 0x2e, 0x38, 0x60, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x50, 0x88, 0x74, 0x00, 0xfc,
-+ 0x40, 0x78, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x23, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x1f, 0x10, 0x1f, 0x12, 0x17,
-+ 0x1c, 0x17, 0x27, 0x24, 0x47, 0x04, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0x20, 0xfc,
-+ 0x40, 0xf0, 0xf0, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x00, 0x3f, 0x21, 0x3f, 0x2a, 0x2f,
-+ 0x3a, 0x2f, 0x2f, 0x4a, 0x4f, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0x20, 0x78, 0x48, 0x78, 0xc8,
-+ 0x78, 0x48, 0x78, 0x30, 0xc8, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x01, 0x3e, 0x22,
-+ 0x3e, 0x22, 0x14, 0x16, 0x18, 0x63, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0x88, 0x88,
-+ 0x50, 0x70, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x02, 0x02, 0x02, 0x02, 0x3f, 0x04,
-+ 0x04, 0x04, 0x08, 0x08, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x02, 0x02, 0x07, 0x04, 0x04, 0x04,
-+ 0x0f, 0x08, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0xe0, 0x20, 0x20, 0x20,
-+ 0xe0, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x10, 0x10, 0x30, 0x57, 0x11,
-+ 0x11, 0x11, 0x11, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x80, 0x80, 0x80, 0x80, 0xf0, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x11, 0x11, 0x21, 0x01, 0x7f,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x12, 0x12, 0x13, 0x10, 0x1f, 0x10,
-+ 0x00, 0x7f, 0x00, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x00, 0xf0, 0x10,
-+ 0x10, 0xfc, 0x00, 0x60, 0x10, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x02, 0x02, 0x1f, 0x04, 0x04, 0x7f,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0xe0, 0x20, 0x20, 0xfc,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x11, 0x7d, 0x25, 0x25, 0x25,
-+ 0x79, 0x48, 0x0f, 0x14, 0x21, 0x46, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0x48, 0x78, 0x48, 0x00,
-+ 0xf0, 0x10, 0xfc, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x23, 0x48, 0x08, 0x10, 0x17, 0x30,
-+ 0x51, 0x17, 0x10, 0x10, 0x11, 0x1e, 0x00, 0x00,
-+ 0x40, 0x50, 0x90, 0xa0, 0x50, 0x88, 0xf4, 0x84,
-+ 0xf8, 0x10, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x12, 0x12, 0x23, 0x4d, 0x09, 0x17, 0x11, 0x35,
-+ 0x55, 0x15, 0x15, 0x15, 0x1e, 0x10, 0x00, 0x00,
-+ 0x00, 0x38, 0xe8, 0x28, 0x28, 0xe8, 0x28, 0x28,
-+ 0xe8, 0x28, 0x78, 0xa0, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x18, 0x35, 0x34, 0x30, 0x57,
-+ 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0xf0, 0x90, 0x90, 0xfc,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x7e, 0x09, 0x1c, 0x1a, 0x1b,
-+ 0x28, 0x29, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0xf0, 0x90, 0x90, 0xfc,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x11, 0x12, 0x7f, 0x12, 0x1a, 0x37, 0x37,
-+ 0x30, 0x57, 0x55, 0x17, 0x14, 0x14, 0x00, 0x00,
-+ 0x80, 0x40, 0xb0, 0xfc, 0xb0, 0x50, 0xb0, 0xf0,
-+ 0x80, 0xf8, 0x28, 0xd8, 0x08, 0x18, 0x00, 0x00,
-+ 0x02, 0x02, 0x7a, 0x17, 0x12, 0x12, 0x7f, 0x15,
-+ 0x15, 0x15, 0x1f, 0x64, 0x01, 0x02, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0xc8, 0x48, 0x78, 0x48, 0x48,
-+ 0x78, 0x48, 0x88, 0x88, 0x08, 0x18, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x07, 0x07, 0x04, 0x7f, 0x08,
-+ 0x1f, 0x62, 0x0f, 0x34, 0x07, 0x04, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xc0, 0xc0, 0x40, 0xfc, 0x20,
-+ 0xf0, 0x0c, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x3d, 0x00, 0x7e, 0x01, 0x3c, 0x00, 0x3f,
-+ 0x00, 0x3d, 0x25, 0x25, 0x3d, 0x25, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x40, 0xf0, 0x90, 0x90, 0xfc,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7f, 0x01, 0x3d, 0x01, 0x3d,
-+ 0x00, 0x3f, 0x24, 0x24, 0x3c, 0x25, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0x78, 0x00, 0xf8, 0x08,
-+ 0x08, 0xfc, 0x50, 0x48, 0x84, 0x04, 0x00, 0x00,
-+ 0x00, 0x3b, 0x00, 0x7d, 0x03, 0x3d, 0x01, 0x3d,
-+ 0x01, 0x3f, 0x24, 0x24, 0x3c, 0x27, 0x00, 0x00,
-+ 0x90, 0xfc, 0xb0, 0xfc, 0x20, 0xf8, 0xf8, 0x20,
-+ 0xfc, 0xf8, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2e, 0x2e, 0x3f,
-+ 0x37, 0x27, 0x3f, 0x23, 0x3e, 0x22, 0x00, 0x00,
-+ 0x80, 0xb8, 0xa8, 0xa8, 0xe8, 0xb8, 0xa8, 0xe8,
-+ 0x78, 0x68, 0xe8, 0x48, 0x48, 0x98, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x1f, 0x10, 0x20, 0x4f, 0x01,
-+ 0x02, 0x04, 0x08, 0x10, 0x10, 0x0f, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xc0, 0x00,
-+ 0x00, 0x00, 0x00, 0x08, 0x08, 0xf8, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x29, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xf8, 0xa8, 0xa8, 0xf8,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x04, 0x04, 0x08, 0x14, 0x22,
-+ 0x02, 0x01, 0x01, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x40, 0x20, 0x50, 0x48, 0x48,
-+ 0x80, 0x80, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x11, 0x11, 0x32, 0x55, 0x11,
-+ 0x10, 0x10, 0x10, 0x11, 0x16, 0x18, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x20, 0x10, 0x28, 0x28, 0x20,
-+ 0xc0, 0xc0, 0xc0, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x09, 0x08, 0x08, 0x17, 0x11, 0x31, 0x51, 0x12,
-+ 0x14, 0x17, 0x10, 0x10, 0x13, 0x1c, 0x00, 0x00,
-+ 0xf0, 0x10, 0x10, 0xfc, 0x00, 0x00, 0xf8, 0x40,
-+ 0x40, 0xfc, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x09, 0x08, 0x0c, 0x17, 0x34, 0x54, 0x15, 0x16,
-+ 0x17, 0x14, 0x14, 0x14, 0x11, 0x16, 0x00, 0x00,
-+ 0xf0, 0x10, 0x10, 0xfc, 0x80, 0xf8, 0x20, 0x20,
-+ 0xfc, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x10, 0x10, 0x37, 0x51, 0x11,
-+ 0x17, 0x10, 0x10, 0x13, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x10, 0x20,
-+ 0xfc, 0x40, 0x40, 0xf8, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x11, 0x09, 0x09, 0x01, 0x7f, 0x04,
-+ 0x04, 0x04, 0x08, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x10, 0x20, 0x00, 0xfc, 0x80,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x01, 0x04, 0x04, 0x08, 0x08, 0x11, 0x21, 0x41,
-+ 0x02, 0x02, 0x02, 0x04, 0x3f, 0x00, 0x00, 0x00,
-+ 0xc0, 0x40, 0x20, 0x20, 0x10, 0x08, 0x04, 0x00,
-+ 0x40, 0x20, 0x10, 0x70, 0x88, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x7c, 0x13, 0x10, 0x10, 0x10,
-+ 0x10, 0x15, 0x19, 0x61, 0x02, 0x04, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0x80, 0xf8, 0x88, 0x88, 0x88,
-+ 0x88, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x14, 0x12, 0x23, 0x52,
-+ 0x0c, 0x04, 0x0a, 0x12, 0x21, 0x42, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x1f, 0x12, 0x22, 0x42, 0x03,
-+ 0x04, 0x05, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08,
-+ 0x88, 0xc8, 0x48, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x1f, 0x13, 0x12, 0x13, 0x12, 0x13, 0x10,
-+ 0x13, 0x10, 0x2f, 0x20, 0x40, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00,
-+ 0xf0, 0x20, 0xfc, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x1f, 0x10, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0xf0, 0x10, 0x10, 0x00, 0x00, 0x00,
-+ 0x02, 0x02, 0x04, 0x3f, 0x20, 0x20, 0x27, 0x24,
-+ 0x24, 0x24, 0x27, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0xc8, 0x48,
-+ 0x48, 0x48, 0xc8, 0x48, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x10, 0x13,
-+ 0x12, 0x12, 0x22, 0x22, 0x43, 0x02, 0x00, 0x00,
-+ 0x38, 0xc0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf0,
-+ 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x79, 0x4b, 0x4a, 0x4e, 0x4a, 0x4a,
-+ 0x4b, 0x7b, 0x4a, 0x42, 0x02, 0x03, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xfc, 0x40, 0x40, 0xfc, 0xa0,
-+ 0x20, 0xfc, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x10, 0x17, 0x10, 0x7c, 0x11, 0x11, 0x11,
-+ 0x11, 0x1d, 0x62, 0x02, 0x04, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x00, 0x00, 0xe0, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x13, 0x12, 0x12, 0x7f, 0x12, 0x12, 0x12,
-+ 0x12, 0x1e, 0x64, 0x04, 0x08, 0x00, 0x00, 0x00,
-+ 0x18, 0xe0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x08, 0x7e, 0x12, 0x12, 0x13,
-+ 0x3c, 0x24, 0x06, 0x0a, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x10, 0x10, 0x20, 0x20, 0xfc,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x3e, 0x02, 0x04, 0x04, 0x08, 0x08, 0x0e,
-+ 0x78, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x01, 0x01, 0x7f, 0x01, 0x07,
-+ 0x18, 0x60, 0x1f, 0x00, 0x00, 0x01, 0x00, 0x00,
-+ 0x00, 0x10, 0xf0, 0x20, 0x40, 0xfc, 0x00, 0xe0,
-+ 0x40, 0x80, 0xf8, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x22, 0x42, 0x7f, 0x02, 0x04,
-+ 0x04, 0x08, 0x11, 0x21, 0x4f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x00, 0xfc, 0x00, 0x80,
-+ 0x80, 0x80, 0x20, 0x30, 0xc8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x3f, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x07, 0x00, 0x7c, 0x10, 0x10, 0x11, 0x11,
-+ 0x10, 0x1c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0x80, 0xf8, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x70, 0x00, 0x00,
-+ 0x04, 0x04, 0x3f, 0x04, 0x04, 0x7f, 0x04, 0x0f,
-+ 0x10, 0x6f, 0x08, 0x08, 0x08, 0x07, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x40, 0xe0,
-+ 0x50, 0xcc, 0x40, 0x10, 0x10, 0xf0, 0x00, 0x00,
-+ 0x01, 0x1f, 0x01, 0x01, 0x7f, 0x08, 0x04, 0x7f,
-+ 0x01, 0x01, 0x3f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x20, 0x40, 0xfc,
-+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x11, 0x11, 0x22, 0x2f, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x20, 0x10, 0x38, 0xc4, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x17, 0x10, 0x1f, 0x10,
-+ 0x17, 0x10, 0x11, 0x21, 0x22, 0x4c, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x80, 0xf0, 0x90, 0xfc, 0x90,
-+ 0xf0, 0x90, 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x17, 0x10, 0x1f, 0x10,
-+ 0x17, 0x1c, 0x23, 0x26, 0x58, 0x01, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x80, 0xf0, 0x90, 0xfc, 0x90,
-+ 0xf0, 0xc8, 0xb0, 0x90, 0x8c, 0x80, 0x00, 0x00,
-+ 0x00, 0x7e, 0x02, 0x02, 0x3e, 0x22, 0x20, 0x3e,
-+ 0x22, 0x02, 0x02, 0x04, 0x07, 0x38, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x40, 0x40,
-+ 0x40, 0x50, 0x88, 0x98, 0xe4, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x11, 0x39, 0x35, 0x35, 0x51,
-+ 0x11, 0x11, 0x11, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10,
-+ 0x10, 0xf0, 0x10, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x18, 0x37, 0x35, 0x31, 0x50,
-+ 0x11, 0x11, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x90, 0xfc, 0x90, 0x40, 0xfc, 0x00, 0x00, 0xf8,
-+ 0x50, 0x50, 0x50, 0x54, 0x54, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x10, 0x11, 0x11, 0x15,
-+ 0x19, 0x71, 0x11, 0x12, 0x12, 0x34, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x00, 0x00, 0xe0, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7f, 0x12, 0x14, 0x13, 0x12,
-+ 0x1a, 0x73, 0x12, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0xc8, 0x48,
-+ 0x48, 0xc8, 0x48, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x14, 0x10, 0x11, 0x16,
-+ 0x1b, 0x70, 0x10, 0x10, 0x17, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa8, 0xa0, 0xa4, 0x1c, 0x00,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x7e, 0x11, 0x11, 0x12, 0x10,
-+ 0x14, 0x18, 0x60, 0x00, 0x03, 0x0c, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x10, 0x90, 0x90, 0x50,
-+ 0x60, 0x20, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x06, 0x38,
-+ 0x20, 0x20, 0x26, 0x38, 0x20, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x88, 0x88, 0x88, 0xf0, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x11, 0x09,
-+ 0x09, 0x7f, 0x02, 0x04, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x10, 0x10,
-+ 0x20, 0xfc, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x1f, 0x11, 0x1f, 0x11, 0x1f,
-+ 0x19, 0x05, 0x03, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x10, 0x00, 0x00, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x1c, 0x1a, 0x1a,
-+ 0x28, 0x28, 0x48, 0x09, 0x09, 0x0a, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x00, 0xf0, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x14, 0x14, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x18, 0x1d, 0x1a,
-+ 0x2a, 0x28, 0x48, 0x08, 0x09, 0x0e, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x90, 0x88, 0x94, 0x94,
-+ 0x50, 0x60, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7f, 0x12, 0x13, 0x3a, 0x37,
-+ 0x36, 0x51, 0x50, 0x10, 0x13, 0x1c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x48, 0x40, 0x80, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x7f, 0x08, 0x1b, 0x1c, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x0b, 0x09, 0x09, 0x00, 0x00,
-+ 0xa0, 0xfc, 0xa0, 0xf8, 0xa0, 0xfc, 0x40, 0xf8,
-+ 0x48, 0xf8, 0x48, 0xfc, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x0b, 0x08, 0x40, 0x20, 0x20, 0x00, 0x08,
-+ 0x08, 0x08, 0x10, 0x10, 0x27, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x09, 0x09, 0x41, 0x27, 0x21, 0x01, 0x01,
-+ 0x1f, 0x11, 0x21, 0x22, 0x44, 0x48, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xf8, 0x20, 0x20, 0x20,
-+ 0xfc, 0x00, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x09, 0x09, 0x43, 0x22, 0x24, 0x0f, 0x00,
-+ 0x13, 0x12, 0x22, 0x22, 0x43, 0x42, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x11, 0x09, 0x0f, 0x41, 0x2f, 0x21, 0x02, 0x17,
-+ 0x18, 0x13, 0x22, 0x22, 0x42, 0x41, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x20, 0xfc, 0x20, 0x10, 0xec,
-+ 0x20, 0xe0, 0x20, 0x08, 0x08, 0xf8, 0x00, 0x00,
-+ 0x11, 0x0f, 0x09, 0x47, 0x21, 0x2f, 0x00, 0x13,
-+ 0x12, 0x13, 0x22, 0x2f, 0x42, 0x42, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0x80, 0xf0,
-+ 0x90, 0xf0, 0x90, 0xfc, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x21, 0x3f, 0x21, 0x21, 0x3f,
-+ 0x21, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x08, 0xf8,
-+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x02, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x00,
-+ 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00,
-+ 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x10, 0x13, 0x12, 0x23, 0x3e, 0x67,
-+ 0x26, 0x25, 0x3c, 0x20, 0x23, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x48, 0x40, 0x80, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x04, 0x1b, 0x70, 0x11, 0x11, 0x7d, 0x10, 0x1b,
-+ 0x36, 0x36, 0x52, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x40, 0xf8, 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x08, 0xe8, 0xa8, 0xe8, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x57, 0x36, 0x3a, 0x12, 0x7f, 0x12, 0x1a,
-+ 0x37, 0x36, 0x52, 0x14, 0x17, 0x18, 0x00, 0x00,
-+ 0x40, 0xfc, 0x20, 0xf8, 0x28, 0xfc, 0x28, 0xf8,
-+ 0x24, 0xa8, 0x70, 0xa8, 0x24, 0x60, 0x00, 0x00,
-+ 0x08, 0x09, 0x0a, 0x72, 0x14, 0x0c, 0x12, 0x7d,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x4b, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x73, 0x14, 0x0c, 0x12, 0x7e,
-+ 0x0c, 0x2a, 0x2b, 0x29, 0x4b, 0x0c, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x50, 0x90,
-+ 0x90, 0xa0, 0x30, 0x48, 0xf4, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x72, 0x14, 0x0d, 0x12, 0x7e,
-+ 0x0c, 0x2a, 0x2a, 0x28, 0x49, 0x0a, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x90, 0x88, 0x94, 0x94, 0x50,
-+ 0x60, 0x20, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x17, 0x66, 0x1a, 0x1b, 0x26, 0x7f,
-+ 0x13, 0x3b, 0x37, 0x37, 0x52, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0xa8, 0xc8, 0xf8, 0x48, 0x58,
-+ 0x58, 0x58, 0xf8, 0x18, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x08, 0x7f, 0x08,
-+ 0x1d, 0x1a, 0x2a, 0x48, 0x09, 0x0a, 0x00, 0x00,
-+ 0x48, 0x48, 0x48, 0xfc, 0x48, 0x48, 0x48, 0x48,
-+ 0xfc, 0x48, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x03, 0x0f,
-+ 0x72, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0xf0, 0x20, 0xfc, 0x80, 0x00, 0xf8,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xe0, 0x00, 0x00,
-+ 0x01, 0x09, 0x09, 0x09, 0x7f, 0x00, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0xe0, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x27, 0x24, 0x3c, 0x24, 0x24,
-+ 0x3c, 0x25, 0x25, 0x26, 0x25, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0xa0, 0xa0,
-+ 0xa0, 0x30, 0x48, 0x58, 0xe4, 0x04, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x26, 0x24, 0x3c, 0x25, 0x26,
-+ 0x3f, 0x24, 0x24, 0x24, 0x27, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa8, 0xa0, 0xa8, 0x18, 0x00,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x7f, 0x07, 0x04, 0x07, 0x3f, 0x27, 0x47,
-+ 0x0f, 0x08, 0x0f, 0x0f, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0xc0, 0x40, 0xc0, 0xfc, 0xc8, 0xc0,
-+ 0xe0, 0x20, 0xe0, 0xe0, 0x20, 0x60, 0x00, 0x00,
-+ 0x04, 0x08, 0x1e, 0x13, 0x1a, 0x16, 0x16, 0x7f,
-+ 0x12, 0x1a, 0x1a, 0x2a, 0x23, 0x46, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x00, 0x70, 0x50, 0x50,
-+ 0x50, 0x50, 0x90, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x01, 0x7f, 0x08, 0x08,
-+ 0x07, 0x09, 0x09, 0x09, 0x11, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xfc, 0x00, 0x00,
-+ 0xf0, 0x20, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x09, 0x10, 0x24, 0x04, 0x0b, 0x08, 0x18,
-+ 0x28, 0x48, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfc, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x12, 0x13, 0x24, 0x49, 0x0f, 0x15, 0x37, 0x55,
-+ 0x17, 0x11, 0x1f, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x00, 0xbc, 0x80, 0x00, 0xfc, 0x48, 0xc8, 0x48,
-+ 0xc8, 0x08, 0xe8, 0x88, 0x48, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x7f, 0x00, 0x3f, 0x00, 0x3d,
-+ 0x01, 0x3d, 0x25, 0x27, 0x3d, 0x25, 0x00, 0x00,
-+ 0xa0, 0xf8, 0xa0, 0xf8, 0xa0, 0xfc, 0x40, 0xf8,
-+ 0x48, 0xf8, 0x48, 0xfc, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x7f, 0x00, 0x0f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x00, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x27, 0x3c, 0x27, 0x3c, 0x25,
-+ 0x25, 0x3d, 0x19, 0x17, 0x25, 0x41, 0x00, 0x00,
-+ 0xa0, 0xfc, 0xa0, 0xf8, 0xa0, 0xfc, 0x40, 0xf8,
-+ 0x48, 0xf8, 0x48, 0xfc, 0x08, 0x18, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x7f, 0x12, 0x11, 0x22, 0x52,
-+ 0x0c, 0x04, 0x0a, 0x12, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0xd0, 0x50, 0x60, 0xd0, 0xc8,
-+ 0x44, 0x44, 0x64, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x20, 0x24, 0xfc, 0x28, 0x28, 0xfc, 0x20, 0xf8,
-+ 0x88, 0x10, 0xfc, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1d, 0x19, 0x0f, 0x72, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x80, 0xa0, 0xa0, 0xa0,
-+ 0xa0, 0xb0, 0x48, 0x58, 0xe4, 0x04, 0x00, 0x00,
-+ 0x00, 0x7e, 0x10, 0x11, 0x11, 0x3d, 0x25, 0x65,
-+ 0x25, 0x25, 0x3d, 0x26, 0x23, 0x04, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x00, 0x20, 0x20, 0x20,
-+ 0x20, 0x30, 0x48, 0x48, 0xf4, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x1b, 0x26, 0x26, 0x7b, 0x12, 0x7f,
-+ 0x13, 0x57, 0x3b, 0x33, 0x1e, 0x62, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0xa8, 0xc8, 0xf8, 0x48, 0x58,
-+ 0x58, 0x58, 0xf8, 0x18, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x21, 0x22,
-+ 0x2f, 0x30, 0x27, 0x24, 0x27, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0x88,
-+ 0xe8, 0x18, 0xc8, 0x48, 0xc8, 0x58, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x29, 0x32, 0x28, 0x27, 0x24,
-+ 0x24, 0x24, 0x3b, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0x78, 0x88, 0x50, 0x30, 0xdc, 0x10, 0xf8,
-+ 0x90, 0x90, 0xfc, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x07, 0x00, 0x7c, 0x11, 0x11, 0x11, 0x11,
-+ 0x15, 0x19, 0x61, 0x00, 0x03, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x80, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x08, 0xf8, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x7f, 0x03, 0x05, 0x19, 0x6f,
-+ 0x08, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0xfc, 0x80, 0x40, 0x30, 0xec,
-+ 0x20, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x00, 0x0f, 0x08, 0x0f, 0x00,
-+ 0x3f, 0x20, 0x27, 0x24, 0x27, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xe0, 0x20, 0xe0, 0x00,
-+ 0xf8, 0x08, 0xc8, 0x48, 0xc8, 0x18, 0x00, 0x00,
-+ 0x20, 0x10, 0x11, 0x0f, 0x45, 0x25, 0x25, 0x05,
-+ 0x15, 0x17, 0x39, 0x22, 0x42, 0x44, 0x00, 0x00,
-+ 0x40, 0x80, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xfc,
-+ 0x00, 0xfc, 0x54, 0xac, 0x84, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x32, 0x2a, 0x2c, 0x3f, 0x24, 0x35,
-+ 0x35, 0x35, 0x3f, 0x31, 0x20, 0x21, 0x00, 0x00,
-+ 0x08, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x09, 0x08, 0x7f, 0x08,
-+ 0x0c, 0x12, 0x16, 0x79, 0x01, 0x02, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x08, 0x0f, 0x00, 0x7f, 0x04,
-+ 0x07, 0x08, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x00, 0xfc, 0x00,
-+ 0xe0, 0x20, 0x20, 0x20, 0x40, 0x80, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x04, 0x18, 0x6f, 0x00, 0x00,
-+ 0x0f, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x40, 0x30, 0xec, 0x00, 0x00,
-+ 0xe0, 0x20, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x17, 0x11, 0x11, 0x7d, 0x17, 0x14, 0x17,
-+ 0x14, 0x1f, 0x63, 0x00, 0x07, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0xf0, 0x10, 0xf0, 0xfc, 0x08, 0xf8,
-+ 0xc8, 0x70, 0xb0, 0xe8, 0x24, 0xc0, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x10, 0x17, 0x10, 0x1c,
-+ 0x71, 0x12, 0x14, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x48, 0x50, 0xfc, 0x40, 0xf8,
-+ 0x80, 0xf8, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x0f, 0x09, 0x41, 0x21, 0x27, 0x04, 0x0f,
-+ 0x10, 0x17, 0x23, 0x21, 0x46, 0x40, 0x00, 0x00,
-+ 0x40, 0xfc, 0xf0, 0x10, 0xf0, 0xfc, 0x08, 0xf8,
-+ 0xc8, 0x70, 0xf0, 0xa8, 0x24, 0xc0, 0x00, 0x00,
-+ 0x01, 0x7f, 0x0f, 0x08, 0x0f, 0x3f, 0x20, 0x7f,
-+ 0x07, 0x3a, 0x1d, 0x06, 0x38, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0xe0, 0x20, 0xe0, 0xfc, 0x08, 0xf8,
-+ 0x88, 0xd0, 0xe0, 0xb0, 0x8c, 0x00, 0x00, 0x00,
-+ 0x01, 0x1f, 0x07, 0x07, 0x07, 0x3f, 0x09, 0x7f,
-+ 0x3e, 0x3e, 0x2a, 0x3e, 0x7f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf0, 0xc0, 0xc0, 0xc0, 0xf8, 0x20, 0xfc,
-+ 0xf8, 0xf8, 0xa8, 0xf8, 0xfc, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3f, 0x08, 0x7f, 0x08,
-+ 0x1e, 0x12, 0x2d, 0x44, 0x1b, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa4, 0x2c, 0xb4, 0x64, 0xfc,
-+ 0x74, 0xac, 0x2c, 0x38, 0x00, 0xfc, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x1f, 0x10, 0x10, 0x1f,
-+ 0x12, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x90, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x08, 0x0a, 0x32, 0x0c, 0x05,
-+ 0x09, 0x12, 0x26, 0x09, 0x11, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0xc8, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x09, 0x09, 0x1f, 0x11, 0x21, 0x7f, 0x00,
-+ 0x0f, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x00,
-+ 0xe0, 0x20, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x2f, 0x21, 0x21, 0x2f, 0x21,
-+ 0x21, 0x21, 0x2f, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xe8, 0x08, 0x08, 0xe8, 0x08,
-+ 0x48, 0x28, 0xe8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x7f, 0x08, 0x3e, 0x00, 0x3f, 0x26, 0x79,
-+ 0x08, 0x7f, 0x1c, 0x2a, 0x48, 0x0b, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x94, 0x94, 0x0c, 0x00, 0xf8,
-+ 0x88, 0x50, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x10, 0xd0, 0x50, 0x7c, 0x90, 0x10, 0xfc, 0x00,
-+ 0x78, 0x48, 0x48, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x08, 0x28, 0x28, 0x3e, 0x28, 0x48, 0x7f, 0x00,
-+ 0x3e, 0x22, 0x22, 0x3f, 0x21, 0x02, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x01, 0x3f,
-+ 0x01, 0x7f, 0x00, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x00, 0xfc, 0x00, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x08, 0x4b, 0x30, 0x1f, 0x30, 0x4b, 0x08, 0x1b,
-+ 0x28, 0x4b, 0x0a, 0x0b, 0x32, 0x10, 0x00, 0x00,
-+ 0x10, 0x98, 0x14, 0xd4, 0x10, 0xfc, 0x10, 0x90,
-+ 0x10, 0xa8, 0xa8, 0xa8, 0x44, 0x84, 0x00, 0x00,
-+ 0x20, 0x10, 0x17, 0x44, 0x27, 0x24, 0x04, 0x17,
-+ 0x15, 0x15, 0x25, 0x29, 0x49, 0x56, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0xf8, 0xa8, 0xa8, 0xf8,
-+ 0x20, 0xe8, 0x30, 0x64, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x2b, 0x2a, 0x3a, 0x2b, 0x28,
-+ 0x3f, 0x28, 0x29, 0x28, 0x28, 0x5b, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xf8, 0xa8, 0xa8, 0xf8, 0x40,
-+ 0xfc, 0x90, 0xd0, 0x20, 0xd0, 0x08, 0x00, 0x00,
-+ 0x22, 0x14, 0x7f, 0x49, 0x7f, 0x49, 0x7f, 0x00,
-+ 0x3e, 0x22, 0x3e, 0x22, 0x3f, 0x22, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x78, 0x48, 0x68, 0x58,
-+ 0x58, 0x88, 0x88, 0xec, 0x8c, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x12, 0x22, 0x44, 0x08, 0x01,
-+ 0x01, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x48, 0x48, 0x88, 0x88, 0x30,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x1a, 0x34, 0x35, 0x32, 0x50,
-+ 0x10, 0x11, 0x15, 0x15, 0x19, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0xa8, 0xa8, 0x28, 0x48, 0xb0,
-+ 0x80, 0x50, 0x48, 0x14, 0x14, 0xf0, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x09, 0x09, 0x3f, 0x20, 0x4f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xfc, 0x08, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x60, 0x00, 0x00,
-+ 0x04, 0x44, 0x28, 0x11, 0x31, 0x49, 0x09, 0x19,
-+ 0x29, 0x49, 0x09, 0x09, 0x31, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0x80, 0xf8, 0x08, 0x08, 0x08, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x21, 0x10, 0x10, 0x00, 0x00, 0x70, 0x11,
-+ 0x11, 0x12, 0x14, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xc0, 0x40, 0x40, 0x40, 0xc0, 0xa0, 0x20,
-+ 0x10, 0x10, 0x08, 0x04, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x04, 0x24, 0x27, 0x24, 0x24,
-+ 0x24, 0x24, 0x25, 0x26, 0x38, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x48, 0x48, 0xd0, 0x60, 0x40,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x27, 0x20, 0x20, 0x27, 0x39, 0x21, 0x21,
-+ 0x25, 0x25, 0x1d, 0x00, 0x03, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x80, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x08, 0xf8, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x04, 0x18, 0x67, 0x00, 0x00,
-+ 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x40, 0x30, 0xcc, 0x00, 0x00,
-+ 0xe0, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x21, 0x3f, 0x23, 0x23, 0x25,
-+ 0x25, 0x29, 0x31, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x88, 0x88, 0x48,
-+ 0x48, 0x28, 0x18, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x13, 0x7e, 0x12, 0x13, 0x12,
-+ 0x16, 0x1b, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0xf8, 0x48,
-+ 0x48, 0xf8, 0x48, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x0c, 0x79, 0x26, 0x18, 0x6c, 0x36, 0x1a, 0x62,
-+ 0x0d, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0xf8, 0xc8, 0xb0, 0xd8,
-+ 0x84, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x11, 0x7d, 0x25, 0x25, 0x27,
-+ 0x79, 0x49, 0x0d, 0x15, 0x21, 0x41, 0x00, 0x00,
-+ 0x18, 0xe0, 0x20, 0xfc, 0x20, 0x10, 0xd4, 0x0c,
-+ 0xfc, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x19, 0x35, 0x35, 0x31, 0x51,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x16, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x10, 0xf4,
-+ 0x44, 0x28, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x0c, 0x78, 0x26, 0x18, 0x78, 0x1c, 0x6c, 0x14,
-+ 0x65, 0x19, 0x04, 0x24, 0x24, 0x43, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xa4, 0xb8,
-+ 0xc8, 0x04, 0x90, 0x88, 0x24, 0xe4, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x70, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x70, 0x80, 0x80, 0xfc, 0x40, 0x24, 0x1c, 0xf4,
-+ 0x10, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x1f, 0x10,
-+ 0x10, 0x1f, 0x10, 0x10, 0x1e, 0x60, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0xf0, 0x80,
-+ 0x98, 0xe0, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x09, 0x7f, 0x19, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x09, 0x09, 0x0e, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x10, 0xf4,
-+ 0x44, 0x28, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x12, 0x13, 0x3a, 0x36,
-+ 0x36, 0x53, 0x52, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0xf8, 0x48, 0xe8,
-+ 0xd8, 0x58, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x23, 0x22, 0x03, 0x12,
-+ 0x12, 0x13, 0x22, 0x22, 0x43, 0x4c, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0xf0, 0x40,
-+ 0x48, 0xf0, 0x40, 0x44, 0xc4, 0x3c, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x2b, 0x2a, 0x0b, 0x1a,
-+ 0x2b, 0x4a, 0x12, 0x12, 0x23, 0x4c, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf8, 0x48, 0x50, 0x20, 0x90, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x17, 0x0c, 0x12, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x88, 0x88, 0x88, 0x88, 0xfc, 0x88, 0x88, 0x88,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x10, 0x1f,
-+ 0x11, 0x11, 0x10, 0x13, 0x1c, 0x70, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x20, 0xe8,
-+ 0x08, 0x10, 0xa0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x3f, 0x02, 0x03, 0x7e, 0x13, 0x1a,
-+ 0x14, 0x27, 0x7b, 0x02, 0x0c, 0x30, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0xc8,
-+ 0xd0, 0x50, 0x68, 0x7c, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x08, 0x28, 0x2f, 0x28, 0x28, 0x2e, 0x70,
-+ 0x00, 0x1f, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,
-+ 0x80, 0x80, 0x98, 0xe0, 0x80, 0x84, 0x84, 0x7c,
-+ 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x17, 0x10, 0x30, 0x50, 0x11,
-+ 0x11, 0x12, 0x14, 0x18, 0x13, 0x10, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x80, 0x80, 0x80, 0xf8,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x02, 0x09, 0x09, 0x04, 0x04, 0x02,
-+ 0x01, 0x01, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40,
-+ 0x80, 0x00, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x79, 0x4f, 0x49, 0x49, 0x4a, 0x4c,
-+ 0x49, 0x7b, 0x4c, 0x40, 0x01, 0x0e, 0x00, 0x00,
-+ 0x80, 0x90, 0x18, 0xe4, 0x20, 0x24, 0x9c, 0xf0,
-+ 0x10, 0x20, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x01, 0x10, 0x13, 0x10, 0x55, 0x54, 0x57, 0x54,
-+ 0x55, 0x7d, 0x46, 0x44, 0x0b, 0x00, 0x00, 0x00,
-+ 0x08, 0x90, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0x80,
-+ 0xf8, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x7f, 0x02, 0x02, 0x04, 0x07,
-+ 0x08, 0x08, 0x10, 0x20, 0x5f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xf0,
-+ 0x80, 0x80, 0x80, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x04, 0x04, 0x3f, 0x01, 0x1f, 0x01, 0x7f,
-+ 0x08, 0x0f, 0x10, 0x20, 0x5f, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0xf8, 0x00, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xf8, 0x80, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x03, 0x05, 0x19, 0x6f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x80, 0x40, 0x30, 0xec, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x42, 0x22, 0x22, 0x04, 0x14,
-+ 0x18, 0x10, 0x20, 0x20, 0x41, 0x4e, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x50, 0x48, 0x48, 0x4c, 0x54,
-+ 0xd0, 0x60, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x01, 0x00, 0x7c, 0x13, 0x10, 0x11, 0x7c, 0x17,
-+ 0x11, 0x13, 0x1a, 0x64, 0x0b, 0x00, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xf8, 0x40, 0xf0, 0x40, 0xfc,
-+ 0x00, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x08, 0x08, 0x08, 0x10, 0x1f, 0x33,
-+ 0x52, 0x12, 0x12, 0x1e, 0x10, 0x03, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xb0, 0xa8, 0xa8, 0x24, 0x2c,
-+ 0x68, 0x10, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x01, 0x3d, 0x02, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x40, 0x40, 0x7c, 0x40,
-+ 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x73, 0x00, 0x00,
-+ 0x20, 0x24, 0xa4, 0xa8, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x09, 0x49, 0x22, 0x2c, 0x08, 0x17, 0x21,
-+ 0x7f, 0x02, 0x0c, 0x74, 0x07, 0x38, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x4c, 0xd4, 0x60, 0x80, 0x00,
-+ 0xfc, 0x90, 0x90, 0x60, 0x30, 0x0c, 0x00, 0x00,
-+ 0x01, 0x09, 0x09, 0x09, 0x19, 0x15, 0x23, 0x41,
-+ 0x3f, 0x01, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x20, 0x20, 0x20, 0x60, 0x50, 0x88, 0x04,
-+ 0xf8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x14, 0x14, 0x16, 0x19,
-+ 0x10, 0x17, 0x20, 0x20, 0x5f, 0x00, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x90, 0x90, 0x98, 0xa4,
-+ 0xc4, 0xf0, 0x80, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x11, 0x11, 0x12, 0x1c,
-+ 0x70, 0x13, 0x10, 0x10, 0x17, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0x50, 0x50, 0x50, 0x58, 0xe4, 0x44,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x13, 0x10, 0x3f, 0x53, 0x12,
-+ 0x13, 0x13, 0x12, 0x13, 0x13, 0x1c, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xf8, 0x40, 0xfc, 0xf0, 0x10,
-+ 0xf0, 0xf0, 0x10, 0xf0, 0x10, 0x08, 0x00, 0x00,
-+ 0x08, 0x0a, 0x0a, 0x13, 0x12, 0x31, 0x53, 0x16,
-+ 0x1b, 0x12, 0x13, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0xf8, 0x98, 0x20, 0xfc, 0x20,
-+ 0xf8, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x1f, 0x11, 0x11, 0x1f, 0x11,
-+ 0x11, 0x7f, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10,
-+ 0x10, 0xfc, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x7f, 0x12,
-+ 0x1e, 0x1e, 0x12, 0x1e, 0x73, 0x02, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0xfc, 0x00,
-+ 0xf8, 0x48, 0x30, 0x70, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x3f, 0x08, 0x08, 0x7f, 0x00, 0x3e,
-+ 0x22, 0x22, 0x22, 0x3e, 0x22, 0x20, 0x00, 0x00,
-+ 0x80, 0x90, 0x88, 0x88, 0x80, 0xfc, 0x48, 0x48,
-+ 0x50, 0x30, 0x20, 0x54, 0x8c, 0x04, 0x00, 0x00,
-+ 0x01, 0x3f, 0x24, 0x7f, 0x04, 0x1f, 0x04, 0x7f,
-+ 0x05, 0x19, 0x6f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xf8, 0x40, 0xf0, 0x40, 0xfc,
-+ 0x40, 0x30, 0xec, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x1f, 0x01, 0x7f, 0x01, 0x1f,
-+ 0x02, 0x7f, 0x04, 0x0f, 0x01, 0x3e, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xfc, 0x10, 0xf0,
-+ 0x00, 0xfc, 0x20, 0x40, 0xe0, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x21, 0x7f, 0x08, 0x04, 0x7f,
-+ 0x01, 0x01, 0x3f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0xf8, 0x20, 0x40, 0xfc,
-+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x06, 0x79, 0x49, 0x2a, 0x24, 0x08, 0x08, 0x7f,
-+ 0x1c, 0x1a, 0x29, 0x48, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0x28, 0x48, 0x90, 0x10, 0x24,
-+ 0x44, 0x08, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x01,
-+ 0x02, 0x0c, 0x30, 0x00, 0x00, 0x01, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0xa0, 0xc0, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7d, 0x11, 0x10, 0x10, 0x1f,
-+ 0x70, 0x10, 0x11, 0x12, 0x14, 0x30, 0x00, 0x00,
-+ 0x18, 0xe8, 0x48, 0x50, 0x20, 0x40, 0x40, 0xfc,
-+ 0xe0, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x3f, 0x08, 0x08, 0x7f, 0x08, 0x7f,
-+ 0x1c, 0x1a, 0x29, 0x48, 0x08, 0x09, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x48, 0x40, 0xfc, 0x48, 0x48,
-+ 0x50, 0x30, 0x24, 0x54, 0x8c, 0x04, 0x00, 0x00,
-+ 0x01, 0x09, 0x09, 0x3f, 0x00, 0x1f, 0x10, 0x1f,
-+ 0x12, 0x17, 0x16, 0x2a, 0x32, 0x46, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x50, 0xfc, 0x40, 0xc8,
-+ 0x28, 0x30, 0x90, 0xb4, 0x4c, 0x84, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x41, 0x20, 0x20, 0x07, 0x09,
-+ 0x09, 0x09, 0x11, 0x12, 0x22, 0x24, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0xa0, 0xe0, 0x1c, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x11, 0x22, 0x11, 0x08, 0x01, 0x01,
-+ 0x11, 0x12, 0x22, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x88, 0x88, 0x10, 0x20, 0x10, 0x88, 0x00, 0x08,
-+ 0x08, 0x90, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x3f, 0x11, 0x08, 0x08, 0x01, 0x7f,
-+ 0x03, 0x05, 0x19, 0x61, 0x01, 0x01, 0x00, 0x00,
-+ 0x18, 0xe8, 0x08, 0x10, 0xa0, 0x40, 0x00, 0xfc,
-+ 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x16, 0x10, 0x16,
-+ 0x12, 0x17, 0x28, 0x2f, 0x40, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x88, 0xb0, 0x80, 0xb0,
-+ 0x80, 0xf0, 0x80, 0xf8, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x3f, 0x09, 0x08, 0x08, 0x10, 0x1f, 0x32,
-+ 0x52, 0x13, 0x12, 0x1e, 0x10, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xf0, 0x50, 0x94, 0x94, 0x0c, 0x20,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x2f, 0x28, 0x28, 0x2e, 0x70, 0x3f,
-+ 0x02, 0x07, 0x1c, 0x64, 0x07, 0x04, 0x00, 0x00,
-+ 0x80, 0x88, 0x90, 0xe4, 0x84, 0x7c, 0x00, 0xf8,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x0f, 0x11, 0x2a, 0x64, 0x18, 0x1f, 0x60,
-+ 0x1f, 0x09, 0x09, 0x11, 0x21, 0x03, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x50, 0x20, 0x10, 0xec, 0x00,
-+ 0xf8, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x04, 0x03, 0x06, 0x78, 0x17,
-+ 0x10, 0x1f, 0x15, 0x15, 0x29, 0x43, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x40, 0x80, 0xc0, 0x3c, 0xd0,
-+ 0x10, 0xf0, 0x90, 0x50, 0x50, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0c, 0x12, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xa8, 0xa8, 0xf8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xf8, 0x88, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3f, 0x12, 0x09, 0x08, 0x01,
-+ 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x40, 0xfc, 0x70, 0x90, 0x10, 0x20, 0x40, 0x00,
-+ 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x3f, 0x08, 0x7f, 0x08, 0x7f, 0x08,
-+ 0x19, 0x36, 0x52, 0x15, 0x19, 0x60, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x48, 0xfc, 0x40, 0x48, 0x48,
-+ 0x50, 0x30, 0x24, 0x54, 0x8c, 0x04, 0x00, 0x00,
-+ 0x04, 0x1f, 0x04, 0x7f, 0x04, 0x7f, 0x1f, 0x15,
-+ 0x1f, 0x15, 0x1f, 0x7f, 0x04, 0x04, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0xfc, 0x40, 0xc8, 0x48, 0x48,
-+ 0x50, 0x30, 0x24, 0xd4, 0x8c, 0x04, 0x00, 0x00,
-+ 0x01, 0x3d, 0x25, 0x2a, 0x32, 0x2d, 0x25, 0x26,
-+ 0x27, 0x24, 0x39, 0x21, 0x22, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xe8, 0xb0, 0x90, 0xf8, 0x04,
-+ 0xf8, 0x40, 0x50, 0x48, 0x48, 0xc0, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x11, 0x0e, 0x1b, 0x71, 0x1f,
-+ 0x11, 0x1f, 0x11, 0x11, 0x21, 0x41, 0x00, 0x00,
-+ 0x08, 0x48, 0xc8, 0x48, 0x48, 0xc8, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x7f, 0x04, 0x0c, 0x08, 0x0b,
-+ 0x18, 0x28, 0x48, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x40, 0x40, 0x40, 0xf8,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x1c, 0x1a, 0x1a,
-+ 0x28, 0x28, 0x49, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0xfc, 0x10, 0x30, 0x30, 0x50,
-+ 0x50, 0x90, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x3f, 0x02, 0x3e, 0x02,
-+ 0x3e, 0x02, 0x1c, 0x64, 0x08, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x40, 0x78, 0x40,
-+ 0x78, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3f, 0x22, 0x3e, 0x22,
-+ 0x22, 0x3e, 0x15, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0xfc, 0x30, 0x30, 0x50,
-+ 0x50, 0x90, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x03, 0x21, 0x11, 0x11, 0x01, 0x0f, 0x10,
-+ 0x10, 0x20, 0x20, 0x43, 0x4c, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x10, 0x10, 0x10, 0x10, 0xfc, 0x30,
-+ 0x30, 0x50, 0x90, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x11, 0x7d, 0x11, 0x11, 0x11,
-+ 0x11, 0x1e, 0x62, 0x04, 0x0b, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x88, 0x88, 0x50,
-+ 0x50, 0x20, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x29, 0x29, 0x31, 0x29, 0x25,
-+ 0x25, 0x25, 0x3a, 0x22, 0x25, 0x2e, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x88, 0x88, 0x50,
-+ 0x50, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x13, 0x12, 0x13, 0x7e, 0x13, 0x12, 0x10,
-+ 0x1d, 0x73, 0x0d, 0x01, 0x02, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x48, 0xa0,
-+ 0x30, 0x28, 0x24, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7f, 0x10, 0x18, 0x35, 0x35,
-+ 0x33, 0x55, 0x59, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0xfc, 0xd4, 0xd4, 0x7c, 0x54,
-+ 0xd4, 0xfc, 0x54, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x02, 0x01, 0x1f, 0x01, 0x7f, 0x02, 0x07, 0x0c,
-+ 0x17, 0x64, 0x07, 0x04, 0x04, 0x04, 0x00, 0x00,
-+ 0x20, 0xc0, 0x60, 0x10, 0xfc, 0x00, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x02, 0x01, 0x79, 0x4b, 0x48, 0x48, 0x48, 0x4f,
-+ 0x48, 0x78, 0x48, 0x41, 0x06, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xf8, 0x40, 0x40, 0x40, 0xfc,
-+ 0x40, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x2a, 0x2a, 0x2a, 0x2b, 0x2a,
-+ 0x2a, 0x2a, 0x3e, 0x22, 0x20, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0x50, 0x88, 0xfc, 0x08,
-+ 0xe8, 0xa8, 0xe8, 0xa8, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x10, 0x13, 0x10, 0x7c, 0x13, 0x17, 0x10,
-+ 0x17, 0x1a, 0x62, 0x03, 0x02, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x60, 0x90, 0x08, 0xfc, 0x08,
-+ 0xc8, 0x48, 0x48, 0xc8, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x7c, 0x13, 0x10, 0x10, 0x3d, 0x27, 0x64,
-+ 0x25, 0x25, 0x3d, 0x21, 0x21, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x60, 0x90, 0x10, 0xfc, 0x08,
-+ 0xe8, 0x28, 0x28, 0xe8, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x23, 0x3e, 0x2f, 0x3e, 0x6f, 0x08,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x2a, 0x45, 0x00, 0x00,
-+ 0x40, 0x78, 0x90, 0x70, 0xfc, 0x70, 0xe0, 0x20,
-+ 0xe0, 0xe0, 0xfc, 0xf8, 0x88, 0x70, 0x00, 0x00,
-+ 0x09, 0x09, 0x09, 0x13, 0x12, 0x34, 0x58, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x80, 0x80, 0xf8, 0x80,
-+ 0x80, 0xf8, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x08, 0x49, 0x29, 0x2a, 0x08, 0x3e, 0x22, 0x3e,
-+ 0x22, 0x3e, 0x22, 0x22, 0x22, 0x26, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x79, 0x4b, 0x4a, 0x4c, 0x48, 0x48,
-+ 0x48, 0x78, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x80, 0x80, 0xf8, 0x80,
-+ 0x80, 0xf8, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x14, 0x11, 0x13, 0x19,
-+ 0x72, 0x14, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa8, 0xa8, 0x18, 0x00, 0xfc,
-+ 0x40, 0x78, 0x40, 0x78, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x79, 0x49, 0x4a, 0x4a, 0x7c, 0x48,
-+ 0x48, 0x48, 0x78, 0x48, 0x40, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x40, 0x40, 0x7c, 0x40,
-+ 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x22, 0x12, 0x14, 0x7f, 0x08, 0x2a, 0x2a, 0x2a,
-+ 0x3e, 0x2a, 0x28, 0x08, 0x11, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88,
-+ 0xf8, 0x88, 0x88, 0x88, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x12, 0x1a, 0x17, 0x36,
-+ 0x32, 0x52, 0x12, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xa8, 0xa8, 0xfc, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x24, 0x44, 0x0a, 0x12, 0x07,
-+ 0x19, 0x61, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x88, 0x88, 0x78, 0x00, 0xfc,
-+ 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x7f, 0x01, 0x1f,
-+ 0x11, 0x13, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0xfc, 0x00, 0xf0,
-+ 0x10, 0xe0, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x3f, 0x22, 0x4c, 0x03,
-+ 0x02, 0x7f, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x48, 0x80, 0x40,
-+ 0x30, 0xc8, 0x40, 0x30, 0x08, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x13, 0x22, 0x5c, 0x09, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x50, 0x50, 0x50, 0xfc, 0x50, 0x50, 0xfc, 0x00,
-+ 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x0a, 0x09, 0x7f, 0x08, 0x1c, 0x1b, 0x1a,
-+ 0x28, 0x29, 0x49, 0x08, 0x08, 0x0b, 0x00, 0x00,
-+ 0x88, 0x48, 0x48, 0x10, 0x60, 0x40, 0xfc, 0x90,
-+ 0x90, 0xd0, 0x20, 0x30, 0xc8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2b, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x29, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0xf8, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x14, 0x23, 0x49, 0x09, 0x7f,
-+ 0x09, 0x09, 0x09, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0x20, 0x20, 0xfc,
-+ 0x20, 0x20, 0xe0, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x00, 0x7f,
-+ 0x04, 0x17, 0x14, 0x1c, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x48, 0x48, 0x50, 0x60, 0xc0,
-+ 0x40, 0x44, 0x44, 0x3c, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x12, 0x12, 0x12, 0x12, 0x7f,
-+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0x90, 0x90, 0x90, 0xfc,
-+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x21, 0x3f, 0x24, 0x24, 0x3f,
-+ 0x35, 0x55, 0x55, 0x17, 0x14, 0x04, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x3f, 0x28, 0x4f, 0x19, 0x66, 0x14, 0x1f,
-+ 0x60, 0x3f, 0x05, 0x19, 0x61, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf8, 0x90, 0x60, 0x30, 0xec,
-+ 0x00, 0xf8, 0x40, 0x30, 0x08, 0x00, 0x00, 0x00,
-+ 0x11, 0x11, 0x12, 0x7c, 0x12, 0x11, 0x10, 0x14,
-+ 0x18, 0x71, 0x12, 0x10, 0x10, 0x33, 0x00, 0x00,
-+ 0x24, 0x24, 0x48, 0x90, 0x48, 0xa4, 0x40, 0x78,
-+ 0x88, 0x90, 0x50, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x11, 0x11, 0x1f, 0x1c,
-+ 0x77, 0x17, 0x14, 0x17, 0x1c, 0x30, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xfc, 0x80,
-+ 0xf8, 0xc8, 0xa8, 0x90, 0xe8, 0x84, 0x00, 0x00,
-+ 0x10, 0x13, 0x13, 0x7d, 0x13, 0x16, 0x11, 0x1b,
-+ 0x74, 0x13, 0x11, 0x12, 0x14, 0x30, 0x00, 0x00,
-+ 0x40, 0xfc, 0x08, 0xf8, 0x68, 0xf0, 0x90, 0xf8,
-+ 0x04, 0xf8, 0x50, 0x48, 0x48, 0xc0, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x18, 0x1c, 0x1a,
-+ 0x29, 0x29, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x02, 0x02, 0x34, 0x0c, 0x1a, 0x69, 0x0a, 0x7f,
-+ 0x1c, 0x1a, 0x2a, 0x48, 0x08, 0x0b, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x94, 0x94, 0x0c, 0x00, 0xf8,
-+ 0x88, 0x50, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3f, 0x24, 0x28, 0x31, 0x29,
-+ 0x25, 0x25, 0x25, 0x3a, 0x25, 0x20, 0x00, 0x00,
-+ 0x40, 0xfc, 0x60, 0xfc, 0x88, 0x50, 0xfc, 0x60,
-+ 0xf8, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7c, 0x14, 0x15, 0x23, 0x48, 0x08,
-+ 0x7f, 0x1c, 0x1a, 0x29, 0x48, 0x08, 0x00, 0x00,
-+ 0x48, 0x48, 0x90, 0xfc, 0x90, 0x90, 0xf8, 0x90,
-+ 0x90, 0xf8, 0x90, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x02, 0x04, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x1d,
-+ 0x01, 0x1d, 0x01, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x70,
-+ 0x00, 0x70, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x1e, 0x24, 0x7e, 0x2b, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0xf8,
-+ 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x98, 0x00, 0x00,
-+ 0x10, 0x17, 0x14, 0x7c, 0x14, 0x17, 0x12, 0x1a,
-+ 0x73, 0x12, 0x14, 0x14, 0x18, 0x33, 0x00, 0x00,
-+ 0x08, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0x28, 0x28,
-+ 0xa8, 0xa8, 0xa8, 0x88, 0x88, 0x18, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x22, 0x5d, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0xf8,
-+ 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x98, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x25, 0x7e, 0x2a, 0x3e, 0x2b,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x43, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x50, 0x48, 0x94, 0x54,
-+ 0x50, 0x20, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x12, 0x12, 0x12, 0x12, 0x12,
-+ 0x12, 0x12, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x48, 0x4b, 0x4a, 0x7a, 0x4a,
-+ 0x4a, 0x4b, 0x7a, 0x4a, 0x43, 0x02, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xa0, 0xf8, 0xa8, 0xa8, 0xa8,
-+ 0xb8, 0x38, 0x18, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x02, 0x05, 0x19, 0x69, 0x09, 0x15, 0x2b,
-+ 0x09, 0x15, 0x23, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0x30, 0x2c, 0x20, 0x50, 0xa8,
-+ 0x20, 0x50, 0x88, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x02, 0x02, 0x04, 0x3f, 0x02, 0x7f, 0x04, 0x09,
-+ 0x16, 0x61, 0x0e, 0x00, 0x01, 0x1e, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0x90, 0x00, 0xfc, 0xc0, 0x20,
-+ 0x50, 0x8c, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x3f, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0xf8, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x1b, 0x34, 0x37, 0x30, 0x51,
-+ 0x16, 0x11, 0x10, 0x11, 0x10, 0x13, 0x00, 0x00,
-+ 0x40, 0x60, 0x90, 0xe8, 0x40, 0xfc, 0xa0, 0x10,
-+ 0x4c, 0xa0, 0x48, 0x90, 0x60, 0x80, 0x00, 0x00,
-+ 0x12, 0x12, 0x17, 0x7a, 0x12, 0x1f, 0x10, 0x1f,
-+ 0x74, 0x17, 0x14, 0x17, 0x14, 0x35, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xe0, 0xbc, 0xa8, 0xc8, 0x28, 0xa8,
-+ 0xb0, 0x90, 0x90, 0xa8, 0xc8, 0x84, 0x00, 0x00,
-+ 0x14, 0x14, 0x3f, 0x14, 0x14, 0x7f, 0x01, 0x3e,
-+ 0x22, 0x3e, 0x22, 0x3e, 0x22, 0x27, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0x88, 0x88, 0x48, 0x50,
-+ 0x30, 0x20, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x19, 0x1c, 0x1b,
-+ 0x2a, 0x28, 0x48, 0x08, 0x08, 0x0b, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0xfc, 0x40, 0xf8, 0x40, 0xfc,
-+ 0x28, 0x28, 0x10, 0x34, 0xcc, 0x04, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x17, 0x36, 0x3d, 0x51, 0x16,
-+ 0x11, 0x17, 0x18, 0x29, 0x26, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0xe8, 0x90, 0xa8, 0x44, 0x48,
-+ 0x50, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x00, 0x03, 0x7e, 0x12, 0x12, 0x12, 0x7f, 0x12,
-+ 0x12, 0x12, 0x1e, 0x62, 0x02, 0x02, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xa8, 0xa8, 0xfc, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x01, 0x3f, 0x04, 0x02, 0x1f, 0x12, 0x12, 0x17,
-+ 0x18, 0x17, 0x20, 0x20, 0x5f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xfc, 0x80, 0x80, 0xf8,
-+ 0x80, 0xf0, 0x80, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x4f, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x04, 0x7f, 0x04, 0x18, 0x00, 0x00,
-+ 0x40, 0xfc, 0x90, 0xe0, 0x20, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x4f, 0x08, 0x0f, 0x0f, 0x0f,
-+ 0x7f, 0x16, 0x63, 0x3f, 0x0d, 0x31, 0x00, 0x00,
-+ 0x40, 0xfc, 0x90, 0xe0, 0x20, 0xe0, 0xe0, 0xe0,
-+ 0xfc, 0x90, 0x6c, 0xf0, 0x60, 0x18, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x1f, 0x02, 0x05, 0x19, 0x6f,
-+ 0x09, 0x09, 0x0f, 0x09, 0x01, 0x3e, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x80, 0x40, 0x30, 0xec,
-+ 0x20, 0x20, 0xe0, 0x20, 0xf0, 0x08, 0x00, 0x00,
-+ 0x01, 0x3b, 0x01, 0x7f, 0x02, 0x3f, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x26, 0x00, 0x00,
-+ 0x10, 0xf8, 0x10, 0xfc, 0xa8, 0xf4, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x90, 0x0c, 0x00, 0x00,
-+ 0x04, 0x3f, 0x04, 0x7f, 0x0a, 0x1f, 0x68, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x20, 0xf8, 0x20, 0xfc, 0x50, 0xe8, 0x24, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x20, 0xb0, 0x28, 0xfc, 0x50, 0x54, 0xac, 0x38,
-+ 0x48, 0x50, 0xb0, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x08, 0x0f, 0x1f, 0x72, 0x0d, 0x33, 0x0d, 0x77,
-+ 0x04, 0x07, 0x07, 0x04, 0x07, 0x38, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x30, 0x48, 0x84, 0x60, 0xdc,
-+ 0x40, 0xc0, 0xd0, 0xa0, 0x60, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x09, 0x0a, 0x08, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0x80, 0x80, 0xfc, 0x90, 0x90,
-+ 0x90, 0x90, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x7f, 0x3e, 0x2a, 0x3e, 0x3e, 0x7f, 0x09,
-+ 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x18, 0xe0, 0x80, 0xfc, 0x90, 0x90, 0x90, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x7e, 0x10, 0x13, 0x1c, 0x27, 0x24, 0x57,
-+ 0x18, 0x08, 0x10, 0x10, 0x20, 0x43, 0x00, 0x00,
-+ 0x50, 0x48, 0x40, 0xf8, 0x40, 0xf8, 0x40, 0xfc,
-+ 0x28, 0x28, 0x10, 0x34, 0xcc, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x10, 0x10, 0x37, 0x50, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x13, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x00, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x10, 0x10, 0x30, 0x50, 0x17,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x10, 0x20, 0x40, 0x40, 0x40, 0xfc,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x17, 0x10, 0x33, 0x52, 0x12,
-+ 0x12, 0x13, 0x12, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xe8, 0x08, 0xc8, 0x48, 0x48,
-+ 0x48, 0xc8, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x10, 0x13, 0x32, 0x52, 0x13,
-+ 0x12, 0x11, 0x10, 0x10, 0x13, 0x1c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x40, 0x80, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x3f, 0x25, 0x25, 0x27,
-+ 0x0c, 0x0e, 0x15, 0x25, 0x44, 0x04, 0x00, 0x00,
-+ 0x08, 0x48, 0xc8, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x7f, 0x00, 0x3f, 0x00, 0x1f, 0x10, 0x10,
-+ 0x10, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xc8, 0x08, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x1f, 0x11, 0x11, 0x11, 0x1f,
-+ 0x11, 0x0a, 0x06, 0x07, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0,
-+ 0x10, 0x00, 0x00, 0x00, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x00, 0x7f, 0x55,
-+ 0x55, 0x7f, 0x55, 0x55, 0x55, 0x43, 0x00, 0x00,
-+ 0x00, 0xfc, 0x04, 0x74, 0x04, 0x74, 0x54, 0x54,
-+ 0x54, 0x74, 0x54, 0x04, 0x04, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x44, 0x44, 0x44, 0x44, 0x48, 0x48,
-+ 0x50, 0x60, 0x40, 0x7f, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x98, 0x98,
-+ 0x78, 0x08, 0x08, 0xf8, 0x08, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x3f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0x7c, 0x24, 0x27, 0x24,
-+ 0x75, 0x49, 0x0d, 0x15, 0x21, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x50, 0x88, 0x9c, 0xe4, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x08, 0x7e, 0x12, 0x12, 0x12,
-+ 0x3c, 0x24, 0x06, 0x0a, 0x10, 0x20, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xb0, 0x20, 0x20, 0x00, 0x00,
-+ 0x01, 0x31, 0x0b, 0x02, 0x0c, 0x11, 0x66, 0x01,
-+ 0x7f, 0x02, 0x07, 0x08, 0x03, 0x3c, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x48, 0xc0, 0x30, 0x0c, 0x00,
-+ 0xfc, 0x20, 0x40, 0xc0, 0x30, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x00, 0x00, 0x01, 0x01, 0x7f,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xf0, 0x20, 0x40, 0x80, 0x00, 0x00, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x12, 0x13,
-+ 0x14, 0x1d, 0x23, 0x22, 0x4c, 0x30, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x00, 0xfc, 0x40, 0xc8,
-+ 0xf0, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x01, 0x1f, 0x11, 0x11,
-+ 0x11, 0x11, 0x11, 0x11, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf0, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x60, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x20,
-+ 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0xf8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xb0, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x7f, 0x01, 0x01, 0x1f, 0x01,
-+ 0x04, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf0, 0x00,
-+ 0x90, 0x88, 0x04, 0x24, 0x20, 0xe0, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x1f,
-+ 0x01, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7d, 0x11, 0x10, 0x10, 0x1d,
-+ 0x71, 0x11, 0x11, 0x11, 0x11, 0x31, 0x00, 0x00,
-+ 0x00, 0x18, 0xe0, 0x00, 0x04, 0xfc, 0x00, 0xf8,
-+ 0x08, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x7f, 0x01, 0x01, 0x1f, 0x04,
-+ 0x04, 0x02, 0x01, 0x03, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xe0, 0x20,
-+ 0x40, 0x40, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7e, 0x02, 0x04, 0x09, 0x09, 0x0e, 0x78,
-+ 0x08, 0x08, 0x08, 0x08, 0x0b, 0x1c, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x10, 0x90, 0x90, 0x50,
-+ 0x60, 0x20, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x12, 0x12, 0x12, 0x7f, 0x12, 0x1e, 0x12, 0x1e,
-+ 0x12, 0x7f, 0x14, 0x12, 0x23, 0x40, 0x00, 0x00,
-+ 0x08, 0x10, 0x60, 0xc0, 0x40, 0x7c, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x11, 0x12, 0x1c, 0x17,
-+ 0x14, 0x14, 0x24, 0x24, 0x44, 0x18, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x20, 0xa0, 0xb8, 0xe8, 0xa8,
-+ 0xa8, 0xa8, 0xb8, 0xa0, 0x84, 0x7c, 0x00, 0x00,
-+ 0x20, 0x20, 0x3f, 0x20, 0x20, 0x1f, 0x00, 0x1f,
-+ 0x10, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x70, 0x80, 0x08, 0x08, 0xf8, 0x00, 0xe0,
-+ 0x20, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x1c, 0x1b, 0x1b,
-+ 0x28, 0x28, 0x48, 0x08, 0x09, 0x0e, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x08,
-+ 0x90, 0x90, 0x60, 0x60, 0x90, 0x0c, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x11, 0x11, 0x11, 0x11, 0x11,
-+ 0x11, 0x11, 0x11, 0x11, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x08, 0x08, 0x0e, 0x12, 0x12, 0x2a,
-+ 0x44, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0x88, 0x88, 0x90, 0xa0,
-+ 0xc0, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x01, 0x1f, 0x11, 0x11, 0x11, 0x1f, 0x10,
-+ 0x10, 0x10, 0x10, 0x13, 0x1c, 0x60, 0x00, 0x00,
-+ 0x60, 0x80, 0x00, 0x00, 0x00, 0x78, 0x80, 0x80,
-+ 0x40, 0x40, 0x24, 0x14, 0x0c, 0x04, 0x00, 0x00,
-+ 0x12, 0x52, 0x34, 0x27, 0x35, 0x55, 0x17, 0x34,
-+ 0x37, 0x55, 0x15, 0x17, 0x14, 0x30, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0x10, 0x7c, 0x54, 0x54, 0x54,
-+ 0x54, 0x54, 0x5c, 0x50, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7e, 0x04, 0x08, 0x0c, 0x1a,
-+ 0x2a, 0x48, 0x08, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xa0, 0xbc, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x06, 0x3c, 0x04, 0x04, 0x7f, 0x0c, 0x0e,
-+ 0x15, 0x15, 0x24, 0x44, 0x07, 0x04, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x40, 0x40,
-+ 0x60, 0x50, 0x88, 0x98, 0xe4, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x1c, 0x03, 0x01, 0x02, 0x7f,
-+ 0x01, 0x09, 0x09, 0x11, 0x21, 0x01, 0x00, 0x00,
-+ 0x00, 0x20, 0x20, 0x40, 0x80, 0x20, 0x18, 0xe4,
-+ 0x00, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0c, 0x12, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x0b, 0x00, 0x00,
-+ 0x08, 0x30, 0xe0, 0xa0, 0xa0, 0xfc, 0xa0, 0xa0,
-+ 0x90, 0x90, 0x94, 0xac, 0xcc, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x2f, 0x28, 0x28, 0x2f, 0x72, 0x0c,
-+ 0x03, 0x7f, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x80, 0x98, 0xe0, 0x80, 0x84, 0x7c, 0x40, 0xc0,
-+ 0x30, 0xc8, 0x40, 0x30, 0x08, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x27, 0x3c, 0x24, 0x27, 0x3d,
-+ 0x24, 0x24, 0x24, 0x24, 0x25, 0x4e, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x08,
-+ 0x90, 0x90, 0x60, 0x60, 0x90, 0x0c, 0x00, 0x00,
-+ 0x01, 0x3d, 0x25, 0x25, 0x25, 0x3c, 0x24, 0x24,
-+ 0x3c, 0x24, 0x24, 0x24, 0x24, 0x4c, 0x00, 0x00,
-+ 0x00, 0x18, 0xe0, 0x04, 0x04, 0xfc, 0x00, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x02, 0x04, 0x3f, 0x01, 0x01,
-+ 0x1f, 0x01, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x40, 0x30, 0xc8, 0x00, 0x00,
-+ 0xf0, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x09, 0x09, 0x11, 0x19,
-+ 0x35, 0x54, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0xf8,
-+ 0xa8, 0xa0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3d, 0x00, 0x7e, 0x01, 0x3c, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x25, 0x24, 0x3c, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0xe8, 0x28,
-+ 0x28, 0xe8, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7e, 0x00, 0x3f, 0x00, 0x3c,
-+ 0x03, 0x3d, 0x24, 0x24, 0x3c, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x10, 0x10,
-+ 0xfc, 0x10, 0x90, 0x90, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7f, 0x00, 0x3c, 0x03, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x27, 0x3c, 0x20, 0x00, 0x00,
-+ 0x30, 0x28, 0x28, 0xfc, 0x20, 0x20, 0xe0, 0xa0,
-+ 0x90, 0xb0, 0xd4, 0x0c, 0x0c, 0x04, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7f, 0x00, 0x3c, 0x03, 0x3c,
-+ 0x00, 0x3d, 0x25, 0x26, 0x3c, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x40,
-+ 0xb0, 0xa8, 0x84, 0x94, 0x90, 0x70, 0x00, 0x00,
-+ 0x00, 0x3e, 0x01, 0x7d, 0x00, 0x3c, 0x03, 0x3c,
-+ 0x00, 0x3d, 0x25, 0x25, 0x3d, 0x21, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa4, 0x28, 0xb0, 0x50, 0x48,
-+ 0x84, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x11, 0x09, 0x0a, 0x04, 0x19, 0x6f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xf8, 0x50, 0xe0, 0x30, 0xec, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x3d, 0x25, 0x3c, 0x27,
-+ 0x25, 0x3d, 0x1a, 0x14, 0x25, 0x42, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0x48, 0xb0, 0x00, 0x00,
-+ 0x0a, 0x0a, 0x0a, 0x0a, 0x2a, 0x2f, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2f, 0x3b, 0x61, 0x00, 0x00, 0x00,
-+ 0x48, 0x48, 0x50, 0xfc, 0x90, 0x90, 0xf8, 0x90,
-+ 0x90, 0xf8, 0x90, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x1a, 0x2a, 0x7e, 0x22, 0x3e,
-+ 0x22, 0x3e, 0x24, 0x26, 0x3a, 0x60, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xe8, 0xa8, 0xa8,
-+ 0xa8, 0xe8, 0xa8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x09, 0x09, 0x09, 0x7f, 0x29, 0x25, 0x3f,
-+ 0x23, 0x25, 0x29, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xfc, 0x28, 0x48, 0xf8,
-+ 0x88, 0x48, 0x28, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x0f, 0x09, 0x0f, 0x01, 0x1f,
-+ 0x01, 0x7f, 0x01, 0x1f, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xe0, 0x20, 0xe0, 0x00, 0xf0,
-+ 0x10, 0xfc, 0x10, 0xf0, 0x10, 0x00, 0x00, 0x00,
-+ 0x08, 0x0a, 0x0b, 0x12, 0x12, 0x32, 0x52, 0x12,
-+ 0x12, 0x12, 0x12, 0x13, 0x1c, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x90, 0x50, 0x50, 0x10, 0x10,
-+ 0x10, 0x10, 0xb0, 0x28, 0x44, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x10, 0x10, 0x37, 0x50, 0x10,
-+ 0x17, 0x12, 0x11, 0x11, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x10, 0x10,
-+ 0xfc, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x13, 0x12, 0x12, 0x13, 0x12, 0x12, 0x13,
-+ 0x12, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x90, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x4f, 0x00, 0x01, 0x01,
-+ 0x7f, 0x01, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0xe0, 0x40, 0x80, 0x00,
-+ 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x01, 0x01, 0x7f, 0x00, 0x00,
-+ 0x7f, 0x08, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x40, 0x40,
-+ 0xfc, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x08, 0x04, 0x7f, 0x08, 0x32, 0x0c, 0x12, 0x7f,
-+ 0x01, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x20, 0x40, 0xfc, 0x20, 0xc8, 0x30, 0x48, 0xfc,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x10, 0x17, 0x10, 0x10,
-+ 0x1f, 0x71, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x10, 0x10,
-+ 0xfc, 0x10, 0x90, 0x90, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x48, 0x48, 0x4f, 0x78, 0x48,
-+ 0x4f, 0x49, 0x78, 0x48, 0x40, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x10, 0x10,
-+ 0xfc, 0x10, 0x90, 0x90, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x21, 0x11, 0x11, 0x02, 0x02, 0x14,
-+ 0x10, 0x20, 0x20, 0x41, 0x46, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x48, 0x50, 0x40,
-+ 0x40, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x11, 0x08, 0x08, 0x47, 0x21, 0x21, 0x01, 0x06,
-+ 0x12, 0x11, 0x21, 0x22, 0x4f, 0x40, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xfc, 0x10, 0x10, 0x54, 0x64,
-+ 0xa8, 0x98, 0x10, 0xa8, 0xfc, 0x44, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x40, 0x21, 0x21, 0x0f, 0x00,
-+ 0x13, 0x12, 0x22, 0x22, 0x43, 0x42, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xa0, 0x10, 0x38, 0xc4, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x7f, 0x11, 0x61, 0x3f, 0x23, 0x2d, 0x2b,
-+ 0x33, 0x2d, 0x25, 0x2b, 0x31, 0x21, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0x0c, 0xf8, 0x18, 0x68, 0x58,
-+ 0x98, 0x68, 0x28, 0x58, 0x88, 0x18, 0x00, 0x00,
-+ 0x00, 0x7f, 0x11, 0x3f, 0x5b, 0x15, 0x1b, 0x15,
-+ 0x1b, 0x3f, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0xf8, 0xb4, 0x70, 0xb0, 0x50,
-+ 0xb0, 0xf8, 0xf0, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x28, 0x2b, 0x08, 0x1f,
-+ 0x28, 0x4f, 0x12, 0x11, 0x21, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x40, 0x40, 0xf8, 0x40, 0xfc,
-+ 0x10, 0xfc, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x01, 0x7c, 0x10, 0x17, 0x11, 0x21, 0x39, 0x6e,
-+ 0x29, 0x28, 0x39, 0x2a, 0x27, 0x00, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xfc, 0x10, 0x10, 0x54, 0x64,
-+ 0x98, 0x88, 0x10, 0xa8, 0xfc, 0x44, 0x00, 0x00,
-+ 0x00, 0x1f, 0x00, 0x00, 0x00, 0x7f, 0x01, 0x09,
-+ 0x09, 0x11, 0x11, 0x21, 0x41, 0x03, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x20,
-+ 0x10, 0x08, 0x08, 0x04, 0x04, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x02, 0x3f, 0x24, 0x24, 0x24,
-+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0xf0, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x30, 0x00, 0x00,
-+ 0x00, 0x7f, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x0f,
-+ 0x08, 0x08, 0x0f, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0xe0, 0x20, 0x20, 0xe0,
-+ 0x20, 0x38, 0xe0, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x1f, 0x10, 0x10, 0x1f, 0x10,
-+ 0x10, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10,
-+ 0x10, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x00, 0x3d, 0x24, 0x27,
-+ 0x3c, 0x27, 0x25, 0x3c, 0x20, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x40, 0xfc,
-+ 0x10, 0xfc, 0x10, 0x90, 0x90, 0x30, 0x00, 0x00,
-+ 0x02, 0x04, 0x39, 0x08, 0x08, 0x7e, 0x09, 0x08,
-+ 0x3e, 0x23, 0x22, 0x22, 0x3e, 0x22, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x48, 0x50, 0xfc, 0x20,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x40, 0x21, 0x21, 0x02, 0x0c,
-+ 0x08, 0x08, 0x10, 0x10, 0x23, 0x2c, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf8, 0x08, 0x08, 0x90, 0x50,
-+ 0x20, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x12, 0x1f, 0x12, 0x12, 0x1f,
-+ 0x14, 0x17, 0x24, 0x24, 0x47, 0x18, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x40, 0xc8, 0x70, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x3f, 0x04,
-+ 0x04, 0x04, 0x04, 0x07, 0x78, 0x00, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0xfc, 0x40, 0x40, 0xc0, 0x20,
-+ 0x20, 0x20, 0x14, 0x94, 0x0c, 0x04, 0x00, 0x00,
-+ 0x01, 0x39, 0x07, 0x7a, 0x02, 0x3f, 0x00, 0x3b,
-+ 0x02, 0x3b, 0x2a, 0x2b, 0x3a, 0x20, 0x00, 0x00,
-+ 0x20, 0x30, 0xe8, 0xa8, 0xa0, 0xfc, 0x28, 0xa8,
-+ 0xb0, 0x90, 0xb4, 0xac, 0x4c, 0x84, 0x00, 0x00,
-+ 0x00, 0x00, 0x7d, 0x55, 0x55, 0x55, 0x7d, 0x55,
-+ 0x55, 0x55, 0x7d, 0x42, 0x02, 0x04, 0x00, 0x00,
-+ 0x40, 0x80, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xfc,
-+ 0x00, 0xfc, 0x54, 0xac, 0x84, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x1f, 0x28, 0x24, 0x45, 0x00,
-+ 0x1f, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0xa0, 0x90, 0x10, 0x00,
-+ 0xf0, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xf8, 0xa8, 0xa8, 0xa8,
-+ 0xf8, 0xa8, 0xa8, 0xa8, 0xf8, 0x88, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x41, 0x01, 0x01, 0x7f,
-+ 0x00, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x00, 0x00, 0x00, 0xfc,
-+ 0x00, 0x40, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x3f, 0x21, 0x5d, 0x1d, 0x00,
-+ 0x7f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0x08, 0x70, 0x70, 0x00,
-+ 0xfc, 0x80, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x07, 0x7c, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x3c, 0xc0, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x08, 0x08, 0xf8, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x44, 0x44, 0x44, 0x44, 0x44,
-+ 0x47, 0x7c, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0x88, 0x88, 0x90, 0xa0, 0xc0,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x08, 0x3e, 0x09, 0x7f, 0x22, 0x12, 0x14,
-+ 0x7f, 0x08, 0x3e, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf0, 0x50, 0x50, 0xd0, 0x50,
-+ 0x70, 0xb0, 0x90, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x01, 0x09, 0x09, 0x09, 0x1f, 0x11, 0x21, 0x7f,
-+ 0x01, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xfc,
-+ 0x00, 0x80, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x15, 0x7b, 0x2b, 0x29, 0x29,
-+ 0x7b, 0x55, 0x1a, 0x12, 0x24, 0x49, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x40, 0x40, 0x78, 0xa0, 0x20,
-+ 0xfc, 0x20, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x7f, 0x02, 0x04, 0x3f,
-+ 0x01, 0x1f, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0xf8, 0x80, 0x60, 0x90,
-+ 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x09, 0x7f, 0x03, 0x0d, 0x71,
-+ 0x01, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x30, 0xd0, 0x10, 0x20, 0xfc, 0x80, 0x60, 0x1c,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x43, 0x22, 0x23, 0x02, 0x10,
-+ 0x14, 0x12, 0x22, 0x20, 0x4f, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0xa8, 0xa0,
-+ 0xa8, 0xa8, 0xb0, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x40, 0x21, 0x26, 0x00, 0x13,
-+ 0x1e, 0x11, 0x20, 0x21, 0x46, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0xa0, 0x58,
-+ 0x4c, 0x50, 0xe0, 0x50, 0x4c, 0xc0, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x49, 0x29, 0x2b, 0x0a, 0x1c,
-+ 0x2f, 0x48, 0x10, 0x11, 0x22, 0x4c, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x00, 0xf8, 0x40, 0x40,
-+ 0xfc, 0xc0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x06, 0x38, 0x3f, 0x24, 0x25, 0x4f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x30, 0xc0, 0xfc, 0x90, 0x10, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x21, 0x41, 0x1f, 0x01, 0x0f,
-+ 0x01, 0x7f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x00, 0xf0, 0x00, 0xe0,
-+ 0x00, 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x08, 0x08, 0x7f, 0x22, 0x14,
-+ 0x7f, 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x00, 0x78, 0x48, 0x50, 0x50,
-+ 0x48, 0x44, 0x44, 0x44, 0x58, 0x40, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x08, 0x0c, 0x17, 0x14,
-+ 0x37, 0x55, 0x14, 0x15, 0x16, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0xa0, 0x10, 0x40, 0xf8, 0x90, 0xe0,
-+ 0x5c, 0xf8, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x12, 0x13, 0x32, 0x52, 0x13,
-+ 0x10, 0x11, 0x15, 0x15, 0x19, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x40, 0x20, 0x28, 0x04, 0x14, 0xf0, 0x00, 0x00,
-+ 0x08, 0x08, 0x2f, 0x28, 0x28, 0x2e, 0x71, 0x01,
-+ 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x80, 0x98, 0xe0, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x05, 0x01, 0x3f, 0x00,
-+ 0x00, 0x00, 0x13, 0x1c, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x00, 0xf8, 0x10,
-+ 0x20, 0xc0, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x14, 0x12, 0x1f, 0x13,
-+ 0x1c, 0x1f, 0x11, 0x23, 0x20, 0x4f, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x90, 0xa0, 0xfc, 0xe0,
-+ 0x98, 0xfc, 0x20, 0xa0, 0xe0, 0x18, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x01, 0x14, 0x14, 0x24, 0x03,
-+ 0x08, 0x36, 0x35, 0x51, 0x55, 0x0c, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x00, 0x90, 0x88, 0x28, 0xe0,
-+ 0x20, 0xd8, 0xd4, 0x44, 0x50, 0x30, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x72, 0x14, 0x0c, 0x12, 0x7f,
-+ 0x09, 0x2d, 0x2b, 0x2b, 0x49, 0x09, 0x00, 0x00,
-+ 0x40, 0xfc, 0x00, 0xf0, 0x90, 0xf0, 0x00, 0xf8,
-+ 0x08, 0xe8, 0xa8, 0xe8, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x02, 0x04, 0x19, 0x61, 0x0f, 0x01, 0x3f,
-+ 0x00, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0x30, 0x0c, 0xe0, 0x00, 0xf8,
-+ 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x44, 0x07, 0x04, 0x07, 0x04,
-+ 0x00, 0x7f, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0x00, 0xf0, 0x00, 0xc0, 0x40,
-+ 0x40, 0xfc, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x04, 0x08, 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x11,
-+ 0x1f, 0x73, 0x05, 0x19, 0x61, 0x03, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0xfc, 0x08, 0x48, 0xa8,
-+ 0x28, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x16, 0x11, 0x10, 0x1f,
-+ 0x70, 0x11, 0x11, 0x11, 0x11, 0x31, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x50, 0x4c, 0xf0, 0x40, 0xfc,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x3e, 0x08, 0x08, 0x7f, 0x14, 0x36,
-+ 0x35, 0x55, 0x14, 0x24, 0x24, 0x4d, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0x88, 0x48, 0x48, 0x50,
-+ 0x30, 0x20, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x23, 0x7e, 0x08, 0x7e,
-+ 0x08, 0x2d, 0x2a, 0x2a, 0x48, 0x18, 0x00, 0x00,
-+ 0x10, 0x90, 0x50, 0x50, 0x10, 0x90, 0x90, 0x1c,
-+ 0x70, 0x90, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x01, 0x1f, 0x01, 0x7f, 0x01, 0x07, 0x1c, 0x67,
-+ 0x04, 0x07, 0x04, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x10, 0xf0, 0x20, 0xfc, 0x00, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x20, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7e, 0x04, 0x09, 0x0c, 0x1a,
-+ 0x2a, 0x48, 0x08, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0c, 0x12, 0x7f,
-+ 0x09, 0x2c, 0x2a, 0x2a, 0x48, 0x0b, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xb0, 0xa8, 0xa8, 0xa4, 0x24,
-+ 0x28, 0x78, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x01, 0x01, 0x7f, 0x01, 0x07,
-+ 0x1c, 0x67, 0x04, 0x04, 0x07, 0x04, 0x00, 0x00,
-+ 0x00, 0x10, 0xf0, 0x20, 0x40, 0xfc, 0x00, 0xf0,
-+ 0x10, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x39, 0x03, 0x7e, 0x03, 0x3a, 0x03, 0x3a,
-+ 0x07, 0x38, 0x29, 0x2e, 0x38, 0x20, 0x00, 0x00,
-+ 0x88, 0x08, 0xc8, 0x48, 0xfc, 0x48, 0xe8, 0x78,
-+ 0xd8, 0xc8, 0x48, 0x48, 0x48, 0xd8, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x01, 0x1f, 0x11, 0x1f, 0x11,
-+ 0x1f, 0x01, 0x7f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x20, 0x13, 0x12, 0x03, 0x02, 0x72, 0x12,
-+ 0x14, 0x15, 0x19, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x90, 0xfc, 0x90, 0xf0, 0x90,
-+ 0x00, 0xa8, 0x54, 0x54, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2b, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x71, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x88, 0x40, 0x48, 0x48,
-+ 0x50, 0x60, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x12, 0x12, 0x7f, 0x06, 0x06,
-+ 0x0a, 0x0a, 0x12, 0x22, 0x42, 0x06, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x50, 0x50, 0x60, 0x50, 0x48,
-+ 0x44, 0x44, 0x64, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x09, 0x09, 0x09, 0x17, 0x11, 0x31, 0x5f, 0x10,
-+ 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x0f, 0x10, 0x10, 0x24, 0x42,
-+ 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x08, 0x08, 0x0f, 0x09, 0x09,
-+ 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00,
-+ 0x80, 0x80, 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x09, 0x1a, 0x1c, 0x1a,
-+ 0x2a, 0x28, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf8, 0x08, 0x08, 0x88, 0x48,
-+ 0x48, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x0a, 0x2a, 0x2d, 0x29, 0x4a,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf8, 0x88, 0x08, 0x88, 0x48,
-+ 0x48, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x12, 0x3f, 0x24, 0x3f, 0x1e, 0x13,
-+ 0x1e, 0x12, 0x1e, 0x14, 0x1e, 0x61, 0x00, 0x00,
-+ 0x78, 0x90, 0x20, 0xf8, 0x48, 0xf8, 0x10, 0xfc,
-+ 0x90, 0x50, 0x50, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x40, 0xc0, 0x40, 0x78, 0x88, 0x88, 0x48, 0x28,
-+ 0x28, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x03, 0x0c, 0x79, 0x49, 0x2a, 0x2c, 0x7f, 0x08,
-+ 0x1c, 0x1a, 0x2a, 0x49, 0x09, 0x0a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0xa8, 0xa0,
-+ 0xa0, 0xa0, 0x90, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x15, 0x13, 0x23, 0x5d, 0x08, 0x7e,
-+ 0x09, 0x2a, 0x1c, 0x19, 0x0e, 0x70, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x80, 0xfc,
-+ 0x54, 0x54, 0x94, 0x24, 0x44, 0x18, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x01, 0x01, 0x7f, 0x02,
-+ 0x07, 0x1c, 0x64, 0x04, 0x07, 0x04, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0x00, 0xfc, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x28, 0x48, 0x0e, 0x08, 0x7f,
-+ 0x08, 0x2a, 0x29, 0x49, 0x08, 0x19, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x00, 0xf8, 0x88, 0x48,
-+ 0x50, 0x30, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x7e, 0x02, 0x02, 0x3e, 0x20, 0x3e, 0x22,
-+ 0x12, 0x0e, 0x1a, 0x62, 0x02, 0x0c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x80, 0xf8, 0x88,
-+ 0x48, 0x38, 0x68, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x7f, 0x04, 0x1f, 0x64,
-+ 0x07, 0x01, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xfc, 0x00, 0xf0, 0x10,
-+ 0xf0, 0x00, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x02, 0x01, 0x01, 0x3f, 0x01, 0x01, 0x01, 0x1f,
-+ 0x01, 0x01, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xf0,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x13, 0x12, 0x1e, 0x12, 0x12, 0x1e,
-+ 0x12, 0x12, 0x1e, 0x62, 0x03, 0x02, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x88, 0x88, 0x88, 0x48, 0x50,
-+ 0x50, 0x20, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x40, 0x00, 0x7f, 0x00,
-+ 0x08, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x40, 0x40, 0xfc, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x01, 0x01, 0x3f, 0x01, 0x01,
-+ 0x7f, 0x01, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x20, 0xc0, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00,
-+ 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x09, 0x09, 0x0f, 0x11, 0x21, 0x7f, 0x03,
-+ 0x05, 0x19, 0x61, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x80,
-+ 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x11, 0x11, 0x1e, 0x24, 0x27, 0x54,
-+ 0x08, 0x09, 0x0a, 0x14, 0x20, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0xe0,
-+ 0xe0, 0x50, 0x48, 0x44, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x48, 0x33, 0x12, 0x34, 0x48, 0x0f, 0x18,
-+ 0x29, 0x48, 0x08, 0x08, 0x30, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0x10, 0x10, 0xfc, 0x10,
-+ 0x10, 0x90, 0x90, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x01, 0x7d, 0x11, 0x12, 0x14, 0x7f, 0x10,
-+ 0x10, 0x11, 0x1e, 0x64, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0xe0,
-+ 0xe0, 0x50, 0x48, 0x44, 0x40, 0x40, 0x00, 0x00,
-+ 0x04, 0x19, 0x70, 0x17, 0x10, 0x7f, 0x12, 0x1b,
-+ 0x36, 0x37, 0x50, 0x13, 0x10, 0x17, 0x00, 0x00,
-+ 0x08, 0xf0, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xf8, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3b, 0x28, 0x2f, 0x38, 0x2b, 0x2a, 0x3b,
-+ 0x2a, 0x2b, 0x28, 0x2b, 0x28, 0x4f, 0x00, 0x00,
-+ 0x08, 0xf0, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xf8, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00,
-+ 0x08, 0x0b, 0x3d, 0x09, 0x09, 0x7f, 0x09, 0x29,
-+ 0x2f, 0x29, 0x3b, 0x28, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x78, 0xc8, 0x68, 0x58, 0xd0,
-+ 0x58, 0x68, 0xe4, 0x44, 0x40, 0xfc, 0x00, 0x00,
-+ 0x10, 0x0f, 0x09, 0x41, 0x27, 0x25, 0x05, 0x15,
-+ 0x16, 0x14, 0x27, 0x24, 0x47, 0x44, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x58,
-+ 0x38, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x04, 0x7f, 0x01, 0x02, 0x1f, 0x10, 0x1f,
-+ 0x10, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x20, 0x40, 0xfc, 0x00, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x17, 0x17, 0x3b, 0x50, 0x17,
-+ 0x10, 0x13, 0x12, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xfc, 0x58, 0x58, 0x00, 0xfc,
-+ 0x40, 0xf8, 0xa8, 0xa8, 0xa8, 0xb8, 0x00, 0x00,
-+ 0x00, 0x01, 0x3e, 0x12, 0x09, 0x3f, 0x20, 0x5f,
-+ 0x04, 0x02, 0x01, 0x01, 0x06, 0x38, 0x00, 0x00,
-+ 0x30, 0xd0, 0x10, 0x20, 0x40, 0xfc, 0x08, 0xe0,
-+ 0x20, 0x40, 0x80, 0x80, 0x60, 0x18, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4a, 0x4a, 0x4b, 0x4a, 0x48,
-+ 0x48, 0x79, 0x49, 0x42, 0x04, 0x18, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0xf8, 0xa8, 0xa0,
-+ 0xa0, 0x20, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x01, 0x1f, 0x02, 0x7f, 0x04,
-+ 0x7f, 0x08, 0x14, 0x22, 0x42, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x20,
-+ 0xfc, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7d, 0x11, 0x13, 0x12, 0x15,
-+ 0x1c, 0x70, 0x10, 0x10, 0x11, 0x36, 0x00, 0x00,
-+ 0x18, 0xe8, 0x48, 0x50, 0x20, 0xfc, 0x08, 0xf0,
-+ 0x90, 0xa0, 0x60, 0x60, 0x90, 0x0c, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x79, 0x17, 0x10, 0x3b, 0x36,
-+ 0x37, 0x54, 0x52, 0x13, 0x1e, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0xc8, 0x3c, 0xc8, 0x28, 0xd8, 0x58,
-+ 0xc8, 0x48, 0x88, 0xc8, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x09, 0x0b, 0x72, 0x14, 0x0d, 0x13, 0x7f,
-+ 0x0c, 0x2a, 0x2a, 0x28, 0x49, 0x0e, 0x00, 0x00,
-+ 0x08, 0xf4, 0x44, 0xa8, 0x90, 0xfc, 0x08, 0xf0,
-+ 0x90, 0x90, 0x60, 0x60, 0x90, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x3f, 0x21, 0x5d, 0x1d, 0x7f,
-+ 0x02, 0x3f, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0x08, 0x70, 0x70, 0xfc,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22,
-+ 0x22, 0x24, 0x28, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x88,
-+ 0x88, 0x48, 0x28, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x05, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
-+ 0x26, 0x3c, 0x64, 0x04, 0x07, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x50, 0x50,
-+ 0x60, 0x20, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x11, 0x17, 0x11, 0x1f, 0x10,
-+ 0x17, 0x14, 0x14, 0x27, 0x24, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xc8, 0x08, 0xe8, 0x08,
-+ 0xc8, 0x48, 0x48, 0xc8, 0x48, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x4f, 0x00, 0x00, 0x7f,
-+ 0x01, 0x09, 0x09, 0x11, 0x21, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0xe0, 0x00, 0x00, 0xfc,
-+ 0x00, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x00, 0x3f, 0x22, 0x22, 0x3e,
-+ 0x08, 0x2c, 0x2a, 0x2b, 0x4a, 0x18, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x48, 0xfc, 0x40, 0x60, 0x60,
-+ 0x60, 0xa0, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x2c, 0x2a, 0x2a, 0x48,
-+ 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x08, 0x88, 0x88, 0x88, 0xc8, 0xa8, 0xa8, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x0c, 0x15, 0x16, 0x34, 0x57, 0x14,
-+ 0x15, 0x14, 0x15, 0x14, 0x10, 0x13, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x10, 0xa0, 0xe0, 0x3c, 0x40,
-+ 0x90, 0x60, 0x88, 0x10, 0x60, 0x80, 0x00, 0x00,
-+ 0x02, 0x3c, 0x08, 0x7e, 0x1d, 0x2a, 0x4a, 0x09,
-+ 0x01, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x20, 0x24, 0xa4, 0xa8, 0x50, 0x50, 0x88, 0x04,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x11, 0x13, 0x14, 0x1c,
-+ 0x71, 0x11, 0x11, 0x11, 0x11, 0x31, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xf8, 0x04, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x12, 0x0a, 0x0a, 0x42, 0x27, 0x26, 0x0a, 0x02,
-+ 0x12, 0x12, 0x24, 0x24, 0x48, 0x50, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x68, 0xd8, 0xd8, 0x48,
-+ 0x48, 0x48, 0x48, 0x48, 0x48, 0x08, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x7f, 0x03, 0x05, 0x19, 0x6f,
-+ 0x02, 0x02, 0x04, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0xfc, 0x80, 0x40, 0x30, 0xcc,
-+ 0x40, 0x78, 0x48, 0x08, 0x08, 0x70, 0x00, 0x00,
-+ 0x02, 0x0c, 0x38, 0x08, 0x08, 0x7e, 0x08, 0x1d,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x24, 0xa4, 0xa8, 0xb0, 0x20,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x15, 0x0c, 0x12, 0x7f,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0xc8, 0x30, 0x20, 0xd0, 0x08,
-+ 0x64, 0x10, 0x00, 0xc0, 0x30, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x14, 0x67, 0x28, 0x1b, 0x26, 0x7f,
-+ 0x12, 0x3b, 0x36, 0x37, 0x52, 0x14, 0x00, 0x00,
-+ 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8, 0x48, 0x58,
-+ 0xe8, 0xf8, 0xe8, 0x58, 0x58, 0x48, 0x00, 0x00,
-+ 0x00, 0x7f, 0x22, 0x16, 0x1a, 0x63, 0x06, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x58, 0x68, 0x88, 0x18, 0xe0,
-+ 0x20, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x01, 0x02, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08,
-+ 0x0f, 0x01, 0x7f, 0x02, 0x0c, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20,
-+ 0xe0, 0x00, 0xfc, 0x80, 0x60, 0x18, 0x00, 0x00,
-+ 0x01, 0x02, 0x0f, 0x0a, 0x09, 0x09, 0x08, 0x7f,
-+ 0x09, 0x09, 0x11, 0x11, 0x21, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0xe0, 0x20, 0x20, 0x20, 0x20, 0xfc,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x02, 0x1f, 0x11, 0x1f, 0x11,
-+ 0x1f, 0x05, 0x05, 0x09, 0x11, 0x60, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x00, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x20, 0x50, 0xfc, 0x04, 0xfc, 0x00, 0x00,
-+ 0x01, 0x02, 0x1f, 0x12, 0x12, 0x7f, 0x00, 0x09,
-+ 0x17, 0x61, 0x09, 0x11, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x90, 0x90, 0xfc, 0x40, 0x88,
-+ 0x90, 0x60, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x04, 0x3f, 0x12, 0x7f, 0x1e, 0x1e, 0x1e, 0x12,
-+ 0x17, 0x7f, 0x06, 0x7c, 0x07, 0x38, 0x00, 0x00,
-+ 0x40, 0x7c, 0x78, 0x88, 0x78, 0x70, 0x70, 0x74,
-+ 0x3c, 0xfc, 0x90, 0x60, 0x30, 0x0c, 0x00, 0x00,
-+ 0x12, 0x1f, 0x34, 0x5f, 0x1e, 0x1f, 0x07, 0x7f,
-+ 0x07, 0x07, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x48, 0x7c, 0xd0, 0x78, 0x78, 0xfc, 0xc0, 0xfc,
-+ 0xc0, 0xc0, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x01, 0x3d, 0x27, 0x24, 0x3f, 0x0a, 0x2a, 0x2f,
-+ 0x29, 0x2b, 0x2b, 0x3d, 0x61, 0x03, 0x00, 0x00,
-+ 0x10, 0x18, 0xd4, 0x14, 0x90, 0xfc, 0x90, 0x90,
-+ 0x30, 0xb0, 0x70, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x2b, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x00, 0xfc, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x8c, 0xf8, 0x88, 0x08, 0x00, 0x00,
-+ 0x00, 0x23, 0x12, 0x13, 0x02, 0x03, 0x72, 0x13,
-+ 0x15, 0x15, 0x19, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0xe8,
-+ 0x28, 0xe8, 0x28, 0x18, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x04, 0x04, 0x7f, 0x02, 0x1f, 0x12, 0x14,
-+ 0x18, 0x10, 0x1f, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0xfc, 0x80, 0xf0, 0x90, 0xb0,
-+ 0x70, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x7e, 0x18, 0x18, 0x7e, 0x5b, 0x5b, 0x5e,
-+ 0x6e, 0x46, 0x7e, 0x43, 0x7f, 0x42, 0x00, 0x00,
-+ 0x08, 0x88, 0xa8, 0xa8, 0xa8, 0xf8, 0xf8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0x28, 0x28, 0x08, 0x00, 0x00,
-+ 0x08, 0x0f, 0x18, 0x1f, 0x28, 0x4f, 0x08, 0x0f,
-+ 0x01, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x80, 0xf8, 0x80, 0xf0, 0x80, 0xf0, 0x80, 0xf8,
-+ 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0x60,
-+ 0x68, 0x68, 0xb4, 0xbc, 0x24, 0x1c, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x08, 0x08, 0x1f, 0x28, 0x48,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x17, 0x10, 0x30, 0x50, 0x13,
-+ 0x10, 0x10, 0x10, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x80, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0xf8,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x02, 0x02, 0x04, 0x3f, 0x02,
-+ 0x02, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x40, 0x20, 0x70, 0x88, 0x40,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x12, 0x11, 0x21, 0x4f, 0x08, 0x10, 0x12, 0x32,
-+ 0x52, 0x12, 0x13, 0x14, 0x14, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xfc, 0x40, 0x40, 0x40, 0x78,
-+ 0x40, 0x40, 0x40, 0xc0, 0x60, 0x1c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x7f, 0x00, 0x08, 0x08, 0x0b,
-+ 0x7c, 0x08, 0x08, 0x10, 0x11, 0x20, 0x00, 0x00,
-+ 0x90, 0x88, 0x88, 0xfc, 0x80, 0x88, 0x88, 0x50,
-+ 0x50, 0x20, 0x60, 0x94, 0x0c, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x04, 0x03, 0x7f, 0x03, 0x0d, 0x33,
-+ 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0xc0, 0x80, 0x00, 0xf8, 0x30, 0x40, 0x00,
-+ 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x40, 0x20, 0x27, 0x00, 0x08,
-+ 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x08, 0x0a, 0x42, 0x22, 0x22, 0x0f, 0x10,
-+ 0x16, 0x11, 0x20, 0x20, 0x43, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0xfc, 0x00,
-+ 0x08, 0x30, 0x00, 0xa0, 0x18, 0x04, 0x00, 0x00,
-+ 0x11, 0x49, 0x22, 0x3e, 0x2a, 0x3f, 0x2a, 0x3e,
-+ 0x7f, 0x00, 0x3e, 0x22, 0x3f, 0x22, 0x00, 0x00,
-+ 0x20, 0x28, 0x24, 0x24, 0x20, 0xfc, 0x20, 0x20,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x15, 0x65, 0x2a, 0x18, 0x24, 0x7d,
-+ 0x13, 0x39, 0x35, 0x35, 0x51, 0x11, 0x00, 0x00,
-+ 0x88, 0xc8, 0x28, 0x30, 0xfc, 0x90, 0x90, 0x50,
-+ 0x5c, 0x50, 0x50, 0xb0, 0x90, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x7f, 0x01, 0x1f, 0x11, 0x1f,
-+ 0x11, 0x1f, 0x01, 0x3f, 0x01, 0x7f, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x00, 0xf8, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x12, 0x22, 0x5c, 0x09, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x72, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x50, 0x48, 0x9c, 0xf4, 0x50,
-+ 0x50, 0x50, 0x90, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x0f, 0x08, 0x08, 0x7f, 0x08,
-+ 0x0a, 0x29, 0x29, 0x28, 0x49, 0x1a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x50, 0x50, 0x50,
-+ 0x20, 0x20, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x11, 0x11, 0x12, 0x12,
-+ 0x15, 0x18, 0x10, 0x21, 0x22, 0x44, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xd0, 0x50, 0x50,
-+ 0x50, 0x90, 0x94, 0x0c, 0x0c, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x48, 0x0f, 0x10, 0x13,
-+ 0x32, 0x53, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x00, 0xf8, 0x80, 0xf0,
-+ 0x10, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x12, 0x0a, 0x0b, 0x42, 0x22, 0x2f, 0x02, 0x13,
-+ 0x16, 0x16, 0x2a, 0x2a, 0x42, 0x47, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x48, 0x48, 0xc8, 0x28, 0x30,
-+ 0xb0, 0x90, 0x30, 0x48, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x09, 0x09, 0x11, 0x18,
-+ 0x34, 0x54, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0xf8, 0xa8, 0xa0,
-+ 0xa0, 0xa0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x10, 0x10, 0x15, 0x65, 0x2a, 0x18, 0x24, 0x7d,
-+ 0x13, 0x39, 0x35, 0x35, 0x51, 0x11, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0x80, 0xf8, 0xa0, 0x78,
-+ 0x48, 0x78, 0x48, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x01, 0x1f, 0x01, 0x7f, 0x01, 0x1f, 0x29, 0x25,
-+ 0x3f, 0x23, 0x25, 0x39, 0x21, 0x41, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xfc, 0x10, 0xf0, 0x28, 0x48,
-+ 0xf8, 0x88, 0x48, 0x38, 0x08, 0x08, 0x00, 0x00,
-+ 0x04, 0x7f, 0x1f, 0x12, 0x1f, 0x3e, 0x0c, 0x74,
-+ 0x0d, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xf0, 0x50, 0xd0, 0x70, 0x54, 0x8c,
-+ 0x04, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x01, 0x1e, 0x12, 0x1f, 0x3e, 0x06,
-+ 0x7c, 0x05, 0x0e, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x40, 0x40, 0xf0, 0x50, 0x50, 0xd0, 0x50, 0x74,
-+ 0x8c, 0x0c, 0x04, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x11, 0x11, 0x1f, 0x11, 0x21,
-+ 0x21, 0x21, 0x21, 0x3f, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x08,
-+ 0x08, 0x08, 0x08, 0xf8, 0x08, 0x08, 0x00, 0x00,
-+ 0x11, 0x11, 0x21, 0x49, 0x0f, 0x11, 0x11, 0x35,
-+ 0x55, 0x15, 0x15, 0x19, 0x11, 0x11, 0x00, 0x00,
-+ 0x00, 0xbc, 0x40, 0x40, 0xc0, 0x3c, 0x88, 0x88,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x20, 0x10, 0x1f, 0x00, 0x02, 0x72, 0x12,
-+ 0x14, 0x14, 0x18, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x80, 0x90, 0x88, 0xfc, 0x80, 0xa0, 0x90, 0x90,
-+ 0x88, 0x88, 0x88, 0x80, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x17, 0x11, 0x31, 0x52, 0x14,
-+ 0x11, 0x13, 0x14, 0x10, 0x13, 0x1c, 0x00, 0x00,
-+ 0x80, 0x90, 0x18, 0xe4, 0x20, 0x24, 0x9c, 0xf0,
-+ 0x10, 0x20, 0xc0, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x57, 0x54, 0x54, 0x55, 0x56,
-+ 0x54, 0x7d, 0x46, 0x40, 0x03, 0x0c, 0x00, 0x00,
-+ 0x40, 0x50, 0x98, 0xe4, 0xa0, 0xa4, 0x9c, 0xf0,
-+ 0x90, 0xa0, 0x40, 0xa0, 0x18, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x01, 0x1f, 0x02, 0x7f, 0x04,
-+ 0x1f, 0x68, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xf0, 0x80, 0xfc, 0x40,
-+ 0xf0, 0x2c, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x7b, 0x4a, 0x49, 0x79, 0x4f, 0x4d, 0x79,
-+ 0x4a, 0x4e, 0x79, 0x49, 0x42, 0x04, 0x00, 0x00,
-+ 0x18, 0xe8, 0x48, 0x50, 0x20, 0xfc, 0x18, 0xf8,
-+ 0xd0, 0xd0, 0xfc, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x13, 0x7e, 0x04, 0x45, 0x26,
-+ 0x28, 0x29, 0x0e, 0x70, 0x01, 0x06, 0x00, 0x00,
-+ 0x40, 0x50, 0x88, 0xfc, 0xa4, 0xa4, 0x9c, 0xf0,
-+ 0x90, 0x90, 0x60, 0x60, 0x90, 0x0c, 0x00, 0x00,
-+ 0x00, 0x01, 0x3e, 0x11, 0x09, 0x3f, 0x28, 0x4e,
-+ 0x12, 0x32, 0x0d, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x30, 0xd0, 0x10, 0x20, 0x40, 0xfc, 0x18, 0xf8,
-+ 0x90, 0x90, 0xfc, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3f, 0x28, 0x3e, 0x28, 0x3f,
-+ 0x0a, 0x3e, 0x3f, 0x32, 0x44, 0x1b, 0x00, 0x00,
-+ 0x20, 0x30, 0x48, 0xf4, 0x50, 0x54, 0xcc, 0x78,
-+ 0x48, 0xd0, 0x30, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x22, 0x13, 0x16, 0x06, 0x0b, 0x12,
-+ 0x12, 0x23, 0x22, 0x42, 0x43, 0x02, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x23, 0x4a, 0x0b, 0x12, 0x12, 0x32,
-+ 0x52, 0x12, 0x12, 0x14, 0x14, 0x18, 0x00, 0x00,
-+ 0x08, 0x30, 0xe0, 0x20, 0xfc, 0x20, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x10, 0x1f, 0x28, 0x48, 0x0f,
-+ 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x08, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x13, 0x1a, 0x36, 0x36,
-+ 0x32, 0x52, 0x54, 0x14, 0x18, 0x10, 0x00, 0x00,
-+ 0x08, 0x30, 0xe0, 0x20, 0xfc, 0x20, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x7e, 0x10, 0x11, 0x1f, 0x25, 0x25, 0x55,
-+ 0x09, 0x09, 0x09, 0x11, 0x20, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xf8, 0x08, 0xe8, 0x28, 0x28, 0xe8,
-+ 0x28, 0x28, 0xe8, 0x28, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x41, 0x21, 0x21, 0x00, 0x13,
-+ 0x10, 0x10, 0x27, 0x20, 0x40, 0x40, 0x00, 0x00,
-+ 0x40, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x10, 0x60, 0xfc, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x11, 0x09, 0x4b, 0x22, 0x27, 0x0a, 0x0b, 0x12,
-+ 0x23, 0x01, 0x7f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x10, 0x20, 0xf8, 0x40, 0xf0, 0x40, 0xf0, 0x40,
-+ 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x20, 0x1f, 0x19, 0x4f, 0x29, 0x2f, 0x08, 0x0b,
-+ 0x18, 0x1b, 0x28, 0x2b, 0x48, 0x48, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x78, 0x48, 0x78, 0x08, 0xe8,
-+ 0x88, 0xe8, 0x88, 0xe8, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x17, 0x14,
-+ 0x17, 0x14, 0x27, 0x24, 0x47, 0x04, 0x00, 0x00,
-+ 0x18, 0xe0, 0x80, 0x80, 0xfc, 0x80, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x73, 0x14, 0x0d, 0x13, 0x7f,
-+ 0x09, 0x2d, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x40, 0x4c, 0x70, 0xc0, 0x48, 0x48, 0x48, 0x48,
-+ 0xf8, 0x48, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x02, 0x42, 0x22, 0x24, 0x04, 0x09, 0x04, 0x74,
-+ 0x12, 0x12, 0x12, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x48, 0x48, 0x48, 0x90, 0x90, 0x20, 0x90, 0x90,
-+ 0x48, 0x48, 0x48, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x01, 0x20, 0x17, 0x10, 0x03, 0x02, 0x73, 0x13,
-+ 0x13, 0x10, 0x1f, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x10, 0xa0, 0xfc, 0xc0, 0xf8, 0xd8, 0x38, 0xf8,
-+ 0xf8, 0x10, 0xfc, 0x90, 0x30, 0xfc, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x20, 0xfc, 0x00, 0x78, 0x48, 0x78, 0x00, 0x78,
-+ 0x08, 0x10, 0xfc, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x23, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x22, 0x22, 0x43, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x0e, 0x12, 0x12, 0x32, 0x4a,
-+ 0x0c, 0x04, 0x0d, 0x12, 0x21, 0x40, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x90, 0x94, 0x14, 0x0c, 0x80, 0x7c, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x7e, 0x04, 0x05, 0x09, 0x1e,
-+ 0x2a, 0x49, 0x08, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x1e, 0x12, 0x12, 0x12, 0x1e,
-+ 0x12, 0x10, 0x11, 0x11, 0x22, 0x40, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0x80, 0x80, 0xfc, 0x90, 0x90,
-+ 0x90, 0x90, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x1f, 0x01, 0x1f, 0x01,
-+ 0x7f, 0x07, 0x1f, 0x64, 0x07, 0x04, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0xf0, 0x10, 0xe0, 0x40,
-+ 0xfc, 0xe0, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4b, 0x48, 0x4b, 0x78, 0x4f,
-+ 0x48, 0x4b, 0x7c, 0x48, 0x40, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xf8, 0x44, 0xf8, 0x50, 0xfc,
-+ 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x40, 0x20, 0x27, 0x00, 0x10,
-+ 0x13, 0x1d, 0x21, 0x21, 0x41, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x48, 0x50, 0xfc, 0x40, 0x80,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x11, 0x11, 0x1f, 0x11, 0x11,
-+ 0x11, 0x11, 0x20, 0x2a, 0x49, 0x11, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0xe0, 0x20, 0x00, 0x48, 0x24, 0x24, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x72, 0x0c, 0x0f, 0x12, 0x7e,
-+ 0x09, 0x2e, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x40, 0x48, 0xf8, 0x50, 0x50, 0xfc, 0x40, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x01, 0x1f, 0x01, 0x7f,
-+ 0x07, 0x1c, 0x67, 0x04, 0x07, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x10, 0xe0, 0x40, 0xfc,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x01, 0x1f, 0x01, 0x7f, 0x1f, 0x01, 0x1f, 0x01,
-+ 0x7f, 0x0f, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xfc, 0xf0, 0x00, 0xf0, 0x00,
-+ 0xfc, 0xe0, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x04, 0x7f, 0x1f, 0x12, 0x1f, 0x0f, 0x01, 0x7f,
-+ 0x07, 0x1c, 0x67, 0x04, 0x07, 0x04, 0x00, 0x00,
-+ 0x40, 0xfc, 0xf0, 0x90, 0xf0, 0xf0, 0x40, 0xfc,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3c, 0x01, 0x7e, 0x03, 0x3c,
-+ 0x3c, 0x01, 0x3e, 0x24, 0x3c, 0x20, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x48, 0xf8, 0x50, 0xfc, 0x40,
-+ 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7c, 0x00, 0x3f, 0x00, 0x3c,
-+ 0x01, 0x3e, 0x24, 0x24, 0x3c, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x48, 0x50, 0xfc, 0x40, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x27, 0x3c, 0x24, 0x24, 0x3c,
-+ 0x24, 0x24, 0x26, 0x38, 0x61, 0x02, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x22, 0x7e, 0x08, 0x7f,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x49, 0x1a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x50, 0x50, 0x50,
-+ 0x20, 0x20, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x02, 0x7f, 0x04, 0x04, 0x04,
-+ 0x0f, 0x08, 0x01, 0x02, 0x0c, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x40, 0x40, 0x40,
-+ 0x80, 0x80, 0x40, 0x20, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x17, 0x11, 0x10, 0x1f,
-+ 0x10, 0x10, 0x20, 0x20, 0x40, 0x01, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xf0, 0x20, 0xc0, 0xfc,
-+ 0x88, 0x90, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0x49, 0x0a, 0x15, 0x10, 0x37,
-+ 0x50, 0x11, 0x11, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0x08, 0xf4, 0x40, 0xfc,
-+ 0x40, 0x50, 0x48, 0x44, 0x44, 0xc0, 0x00, 0x00,
-+ 0x08, 0x08, 0x7e, 0x12, 0x12, 0x3c, 0x06, 0x18,
-+ 0x61, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x13, 0x1a, 0x26, 0x27, 0x7a, 0x12, 0x7f,
-+ 0x12, 0x56, 0x3b, 0x36, 0x1c, 0x61, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xf8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xe8, 0xc8, 0x48, 0x88, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x28, 0x31, 0x2b, 0x24, 0x27,
-+ 0x24, 0x25, 0x39, 0x22, 0x24, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x90, 0x08, 0xf4, 0x40, 0xfc,
-+ 0x40, 0x50, 0x48, 0x44, 0x44, 0xc0, 0x00, 0x00,
-+ 0x09, 0x09, 0x0b, 0x15, 0x19, 0x31, 0x51, 0x1f,
-+ 0x12, 0x13, 0x14, 0x19, 0x12, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xfc,
-+ 0x00, 0xf8, 0xa8, 0x28, 0x48, 0xb0, 0x00, 0x00,
-+ 0x0a, 0x09, 0x0f, 0x15, 0x19, 0x31, 0x53, 0x12,
-+ 0x13, 0x13, 0x12, 0x13, 0x13, 0x1c, 0x00, 0x00,
-+ 0x88, 0x50, 0xfc, 0xe8, 0x20, 0xe0, 0xf0, 0x10,
-+ 0xf0, 0xf0, 0x10, 0xf0, 0x10, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x25, 0x27, 0x24, 0x3f, 0x24, 0x25,
-+ 0x3e, 0x27, 0x24, 0x24, 0x25, 0x4e, 0x00, 0x00,
-+ 0x40, 0x48, 0x50, 0xf8, 0x40, 0xfc, 0xa0, 0x50,
-+ 0x48, 0xf4, 0x90, 0x90, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x20, 0x27, 0x24, 0x27, 0x24,
-+ 0x24, 0x28, 0x28, 0x30, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0xc0, 0x00, 0x00, 0xf8, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x06, 0x3c, 0x04, 0x04, 0x04, 0x7f, 0x04,
-+ 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00,
-+ 0x1f, 0x10, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x70, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x01, 0x79, 0x4a, 0x4c, 0x4b, 0x4a, 0x4b,
-+ 0x4a, 0x7b, 0x4a, 0x42, 0x02, 0x02, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x44, 0x44, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x08, 0x04, 0x3f, 0x24, 0x24,
-+ 0x2f, 0x34, 0x24, 0x27, 0x24, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0x98,
-+ 0xf8, 0x48, 0x48, 0xc8, 0x48, 0x18, 0x00, 0x00,
-+ 0x00, 0x01, 0x79, 0x49, 0x49, 0x49, 0x49, 0x48,
-+ 0x7b, 0x4a, 0x43, 0x02, 0x03, 0x02, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x12, 0x09, 0x3f, 0x27, 0x44, 0x17, 0x1f, 0x10,
-+ 0x0f, 0x0f, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x10, 0x20, 0xfc, 0xc8, 0x40, 0xf0, 0xc0, 0x08,
-+ 0xf8, 0xe0, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x08, 0x4b, 0x2a, 0x29, 0x08, 0x1f, 0x69, 0x08,
-+ 0x09, 0x7f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x1c, 0xe4, 0x48, 0x30, 0x10, 0xfc, 0x10, 0x90,
-+ 0x30, 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x08, 0x04, 0x7f, 0x01, 0x02,
-+ 0x7f, 0x04, 0x0f, 0x10, 0x03, 0x3c, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x20, 0x40, 0xfc, 0x00, 0x00,
-+ 0xfc, 0x40, 0x40, 0xc0, 0x30, 0x08, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x11, 0x7d, 0x25, 0x25, 0x24,
-+ 0x7b, 0x4a, 0x0f, 0x16, 0x23, 0x42, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x29, 0x45, 0x05, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x28, 0x20, 0x40, 0xe0, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x4a, 0x29, 0x29, 0x08, 0x0f,
-+ 0x19, 0x68, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x18, 0x60, 0x88, 0x48, 0x50, 0x20, 0x10, 0xfc,
-+ 0x10, 0x90, 0x90, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x09, 0x09, 0x11, 0x11,
-+ 0x21, 0x41, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x08,
-+ 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x09, 0x09, 0x11, 0x11, 0x21, 0x41,
-+ 0x03, 0x00, 0x00, 0x01, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0x00, 0x20, 0x10, 0x08, 0x14, 0x14, 0x20,
-+ 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x11, 0x09, 0x09, 0x3f, 0x20, 0x27, 0x24,
-+ 0x24, 0x27, 0x24, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x20, 0xf8, 0x08, 0xc8, 0x48,
-+ 0x48, 0xc8, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x1f,
-+ 0x10, 0x10, 0x10, 0x20, 0x3f, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x80, 0x80, 0x80, 0xf8,
-+ 0x80, 0x80, 0x80, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x10, 0x10, 0x1f, 0x11,
-+ 0x11, 0x12, 0x12, 0x24, 0x28, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x80, 0x80, 0xfc, 0xc0,
-+ 0xa0, 0xa0, 0x90, 0x88, 0x84, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x12, 0x1a, 0x17, 0x1f, 0x18,
-+ 0x1f, 0x1d, 0x2f, 0x2c, 0x48, 0x09, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x20, 0xa0, 0x20, 0xbc, 0xc8,
-+ 0xa8, 0xb0, 0x90, 0xb0, 0xc8, 0x84, 0x00, 0x00,
-+ 0x04, 0x3f, 0x0a, 0x7f, 0x00, 0x1f, 0x11, 0x1f,
-+ 0x11, 0x1f, 0x04, 0x7f, 0x04, 0x04, 0x00, 0x00,
-+ 0x10, 0x90, 0x20, 0xa8, 0x48, 0x10, 0x10, 0x24,
-+ 0x44, 0x08, 0x08, 0x90, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0x0f, 0x00, 0x00, 0x79, 0x0f, 0x09, 0x0f,
-+ 0x11, 0x1f, 0x21, 0x41, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xe0, 0x40, 0x84, 0x24, 0xe8, 0x30, 0xe0,
-+ 0x10, 0xf0, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x11, 0x12, 0x12, 0x1c,
-+ 0x70, 0x10, 0x10, 0x10, 0x13, 0x3c, 0x00, 0x00,
-+ 0x40, 0x40, 0x60, 0x50, 0x48, 0x48, 0x54, 0x54,
-+ 0xe0, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x10, 0x11, 0x11, 0x16,
-+ 0x19, 0x71, 0x11, 0x11, 0x11, 0x31, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x08, 0x30, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x12, 0x09, 0x3f, 0x20, 0x4f, 0x08, 0x0f, 0x1f,
-+ 0x01, 0x1f, 0x01, 0x7f, 0x01, 0x03, 0x00, 0x00,
-+ 0x10, 0x20, 0xfc, 0x08, 0xe0, 0x20, 0xf0, 0xc0,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7f, 0x10, 0x17, 0x10, 0x1b,
-+ 0x70, 0x11, 0x11, 0x13, 0x14, 0x38, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8,
-+ 0x40, 0x78, 0x40, 0x40, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x03, 0x3c,
-+ 0x04, 0x7f, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x40, 0x40,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00,
-+ 0x3f, 0x20, 0x3f, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x03, 0x78, 0x48, 0x48, 0x49, 0x79, 0x4a,
-+ 0x49, 0x49, 0x79, 0x49, 0x41, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x08, 0x30, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x10, 0x00,
-+ 0x7c, 0x44, 0x7c, 0x44, 0x7c, 0x44, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00,
-+ 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7e, 0x08, 0x1d, 0x1b, 0x1a,
-+ 0x28, 0x28, 0x48, 0x09, 0x0f, 0x08, 0x00, 0x00,
-+ 0x70, 0x10, 0x90, 0x90, 0x90, 0x08, 0x48, 0x44,
-+ 0x40, 0xa0, 0x90, 0x18, 0xe4, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x7e, 0x08, 0x18, 0x1c, 0x1a,
-+ 0x2a, 0x28, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x24, 0xa4, 0xa8, 0x20, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x7f, 0x08, 0x1c, 0x1a, 0x1a,
-+ 0x28, 0x28, 0x48, 0x0b, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0xfc, 0x50, 0xfc, 0x00, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x20, 0xfc, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7f, 0x13, 0x15, 0x39, 0x35,
-+ 0x35, 0x51, 0x50, 0x12, 0x12, 0x14, 0x00, 0x00,
-+ 0x90, 0x90, 0x20, 0xfc, 0x20, 0xf8, 0x20, 0xf8,
-+ 0x20, 0xfc, 0x00, 0xa8, 0x54, 0x54, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x40, 0x21, 0x21, 0x02, 0x04,
-+ 0x13, 0x12, 0x22, 0x22, 0x43, 0x42, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x08, 0x08, 0x30, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x0c, 0x0a, 0x41, 0x21, 0x23, 0x02, 0x13,
-+ 0x12, 0x13, 0x22, 0x22, 0x42, 0x42, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0x50, 0x60, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x08, 0x0a, 0x42, 0x22, 0x2f, 0x00, 0x12,
-+ 0x12, 0x14, 0x28, 0x20, 0x41, 0x4e, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x40, 0x40, 0xfc, 0x50, 0x48,
-+ 0x54, 0xd4, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x22, 0x12, 0x12, 0x4f, 0x22, 0x22, 0x07, 0x16,
-+ 0x16, 0x1a, 0x2a, 0x22, 0x42, 0x42, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0xc8, 0x48, 0x78, 0x48, 0xc8,
-+ 0xf8, 0x48, 0x48, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x0a, 0x2c, 0x2b, 0x28, 0x48,
-+ 0x0f, 0x08, 0x14, 0x13, 0x22, 0x44, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xd0, 0xf8, 0x90, 0x90,
-+ 0xfc, 0xa0, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x04, 0x04, 0x08, 0x0f, 0x18, 0x2f, 0x48, 0x0f,
-+ 0x08, 0x0f, 0x00, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x40, 0x40, 0x80, 0xf8, 0x80, 0xf0, 0x80, 0xf0,
-+ 0x80, 0xfc, 0x00, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x25, 0x3f, 0x25, 0x25,
-+ 0x3d, 0x25, 0x00, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x30, 0xf8, 0x08, 0x08,
-+ 0xf8, 0x08, 0x00, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x28, 0x2f, 0x08, 0x18,
-+ 0x2a, 0x4a, 0x12, 0x12, 0x2f, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x00, 0xf8, 0x40, 0x40,
-+ 0x78, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x09, 0x11, 0x63, 0x00, 0x07, 0x7f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x20, 0x18, 0x24, 0xc0, 0x00, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x7e, 0x11, 0x11, 0x10, 0x11, 0x3d, 0x25,
-+ 0x65, 0x25, 0x25, 0x3d, 0x25, 0x01, 0x00, 0x00,
-+ 0x40, 0x44, 0x44, 0x48, 0x50, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x7e, 0x10, 0x11, 0x11, 0x3f, 0x25, 0x65,
-+ 0x25, 0x25, 0x3c, 0x22, 0x22, 0x04, 0x00, 0x00,
-+ 0x90, 0x90, 0xa0, 0xfc, 0x20, 0xf8, 0x20, 0xf8,
-+ 0x20, 0xfc, 0x00, 0xa8, 0x54, 0x04, 0x00, 0x00,
-+ 0x11, 0x10, 0x10, 0x7f, 0x08, 0x08, 0x13, 0x18,
-+ 0x34, 0x57, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xfc, 0x40, 0x40, 0xf8, 0x40,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x02, 0x0c, 0x38, 0x09, 0x09, 0x7e, 0x08, 0x1c,
-+ 0x1a, 0x2b, 0x49, 0x0a, 0x08, 0x08, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x20, 0x20, 0xb0, 0xa8,
-+ 0xa8, 0x24, 0x24, 0x24, 0x20, 0x60, 0x00, 0x00,
-+ 0x01, 0x1f, 0x04, 0x7f, 0x00, 0x0f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x01, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x40, 0xfc, 0x00, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x25, 0x42, 0x01, 0x1f,
-+ 0x01, 0x7f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0x10, 0xe0, 0x00,
-+ 0x00, 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2b, 0x2d, 0x09, 0x7f, 0x09, 0x1d,
-+ 0x1b, 0x2b, 0x49, 0x0a, 0x0b, 0x0c, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x00, 0x20, 0x20, 0x20, 0xf8,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x72, 0x14, 0x0c, 0x12, 0x7f,
-+ 0x09, 0x2d, 0x2b, 0x2b, 0x49, 0x09, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x88, 0xb0, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x21, 0x11, 0x11, 0x01, 0x1f, 0x10, 0x1f,
-+ 0x10, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x08, 0x08, 0x10, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0f, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x3f, 0x20, 0x3f, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xe0, 0x20, 0xe0, 0x20, 0xe0,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x08, 0x0f, 0x4a, 0x29, 0x28,
-+ 0x0b, 0x19, 0x68, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x3c, 0xc8, 0x48, 0x30, 0x10,
-+ 0xfc, 0x10, 0x90, 0x90, 0x10, 0x30, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x08, 0x0f, 0x18, 0x1f, 0x28,
-+ 0x4f, 0x08, 0x0f, 0x14, 0x22, 0x42, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x80, 0xf8, 0x80, 0xf0, 0x80,
-+ 0xf0, 0x80, 0xf8, 0x90, 0x48, 0x44, 0x00, 0x00,
-+ 0x10, 0x17, 0x21, 0x4f, 0x0f, 0x15, 0x17, 0x35,
-+ 0x57, 0x11, 0x17, 0x11, 0x1e, 0x10, 0x00, 0x00,
-+ 0xc0, 0x3c, 0x00, 0xc0, 0xfc, 0x48, 0xc8, 0x48,
-+ 0xc8, 0x08, 0xc8, 0x88, 0x08, 0x18, 0x00, 0x00,
-+ 0x11, 0x09, 0x3f, 0x20, 0x4f, 0x08, 0x0f, 0x01,
-+ 0x7f, 0x02, 0x0c, 0x74, 0x07, 0x18, 0x00, 0x00,
-+ 0x10, 0x20, 0xfc, 0x08, 0xe0, 0x20, 0xe0, 0x00,
-+ 0xfc, 0x90, 0xa0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x00, 0x3d, 0x01, 0x3e,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3f, 0x20, 0x00, 0x00,
-+ 0x60, 0x20, 0xa0, 0x90, 0x90, 0x48, 0x48, 0x44,
-+ 0x40, 0x60, 0x90, 0x90, 0xe8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3d, 0x00, 0x7e, 0x00, 0x3c, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0xa0, 0xa0, 0xb8, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3d, 0x00, 0x7e, 0x00, 0x3c, 0x01, 0x3e,
-+ 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x21, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x88, 0x88, 0x30, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x3c, 0x00, 0x7f, 0x00, 0x3c, 0x03, 0x3c,
-+ 0x00, 0x3f, 0x24, 0x24, 0x3c, 0x20, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xfc, 0x40, 0x40, 0xf8, 0x40,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x02, 0x07, 0x18, 0x7f, 0x11, 0x1f, 0x13, 0x0d,
-+ 0x72, 0x0d, 0x32, 0x0c, 0x30, 0x03, 0x00, 0x00,
-+ 0x00, 0xe0, 0xc0, 0xf0, 0x10, 0xf0, 0x18, 0x90,
-+ 0xa0, 0xc0, 0xa0, 0x98, 0x84, 0x00, 0x00, 0x00,
-+ 0x11, 0x09, 0x3f, 0x27, 0x44, 0x07, 0x0f, 0x08,
-+ 0x0f, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x10, 0x20, 0xfc, 0xc8, 0x40, 0xc0, 0xe0, 0x20,
-+ 0xe0, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x08, 0x4f, 0x29, 0x1f, 0x69, 0x08, 0x7f, 0x02,
-+ 0x1f, 0x14, 0x18, 0x1f, 0x1f, 0x10, 0x00, 0x00,
-+ 0x3c, 0xc8, 0x50, 0xfc, 0x10, 0xb0, 0xfc, 0x80,
-+ 0xf0, 0xb0, 0xf0, 0xf0, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x70, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0xa0, 0xa0, 0xb8, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x70, 0x00, 0x00,
-+ 0x18, 0xe0, 0xfc, 0x20, 0xf8, 0xa8, 0xf8, 0xa8,
-+ 0xf8, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x13, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1d, 0x18, 0x0f, 0x70, 0x00, 0x00,
-+ 0x20, 0xf8, 0x90, 0xfc, 0xf8, 0xa8, 0xf8, 0xa8,
-+ 0xf8, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x2b, 0x28, 0x31, 0x29, 0x25,
-+ 0x25, 0x25, 0x38, 0x27, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0xf8, 0x90, 0xfc, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x14, 0x15, 0x7f, 0x14, 0x1c, 0x08, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x24, 0xa4, 0xa8, 0x20, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x7f, 0x01, 0x01, 0x11, 0x09,
-+ 0x05, 0x03, 0x03, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x0f, 0x00, 0x00, 0x3d, 0x05, 0x09, 0x09,
-+ 0x11, 0x21, 0x43, 0x00, 0x3f, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x40, 0x88, 0x48, 0x50, 0x20, 0x20,
-+ 0x10, 0x08, 0x04, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x09, 0x7f, 0x09, 0x3f,
-+ 0x03, 0x05, 0x19, 0x61, 0x01, 0x01, 0x00, 0x00,
-+ 0x60, 0x80, 0x00, 0xf8, 0x20, 0xfc, 0x20, 0xf8,
-+ 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x40, 0x07, 0x04, 0x04, 0x04,
-+ 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x10, 0x00, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x88, 0x88, 0x78, 0x00, 0x00,
-+ 0x01, 0x1e, 0x04, 0x3f, 0x15, 0x7f, 0x15, 0x15,
-+ 0x3f, 0x0e, 0x15, 0x25, 0x44, 0x04, 0x00, 0x00,
-+ 0x08, 0x28, 0x28, 0xa8, 0x28, 0xe8, 0x28, 0x28,
-+ 0xa8, 0x28, 0x28, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x13, 0x7e, 0x12, 0x13, 0x12,
-+ 0x16, 0x1a, 0x64, 0x06, 0x09, 0x10, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0xfc, 0x40, 0x48, 0xa8, 0xa8,
-+ 0xb0, 0x90, 0x90, 0xb4, 0xcc, 0x04, 0x00, 0x00,
-+ 0x00, 0x11, 0x11, 0x11, 0x7d, 0x11, 0x10, 0x17,
-+ 0x15, 0x1b, 0x64, 0x01, 0x02, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xf8, 0xa8, 0x28, 0x48, 0xb0, 0x00, 0x00,
-+ 0x00, 0x17, 0x11, 0x12, 0x7f, 0x10, 0x13, 0x10,
-+ 0x17, 0x18, 0x63, 0x0d, 0x01, 0x06, 0x00, 0x00,
-+ 0x40, 0xfc, 0x10, 0xa8, 0xfc, 0xa0, 0xf8, 0xa0,
-+ 0xfc, 0xc8, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x11, 0x12, 0x7f, 0x24, 0x25, 0x24,
-+ 0x7b, 0x48, 0x0f, 0x14, 0x20, 0x43, 0x00, 0x00,
-+ 0x40, 0xfc, 0xa8, 0xa4, 0xfc, 0xa0, 0xf8, 0xa0,
-+ 0xfc, 0xc8, 0xb0, 0x90, 0xc8, 0x04, 0x00, 0x00,
-+ 0x11, 0x09, 0x3f, 0x20, 0x4f, 0x08, 0x0f, 0x01,
-+ 0x1f, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x00,
-+ 0x10, 0x20, 0xfc, 0x08, 0xe0, 0x20, 0xe0, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x19, 0x34, 0x37, 0x30, 0x51,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0x00, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7d, 0x11, 0x11, 0x17, 0x1e,
-+ 0x72, 0x14, 0x11, 0x16, 0x10, 0x37, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf0, 0xf0, 0xf0, 0xfc, 0xd4,
-+ 0xf8, 0xf4, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x02, 0x02, 0x07, 0x0c, 0x32, 0x03, 0x0d, 0x71,
-+ 0x1f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xe0, 0x40, 0x80, 0x80, 0x60, 0x1c,
-+ 0xf0, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x1d, 0x1b, 0x1a,
-+ 0x28, 0x28, 0x48, 0x08, 0x09, 0x0e, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0x20, 0xa0,
-+ 0xa0, 0x60, 0x60, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x08, 0x09, 0x42, 0x24, 0x23, 0x00, 0x0f,
-+ 0x10, 0x13, 0x20, 0x20, 0x40, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xf0, 0x20, 0x40, 0xf8, 0x48, 0xfc,
-+ 0x48, 0xf8, 0x48, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x48, 0x2f, 0x28, 0x08, 0x08,
-+ 0x18, 0x28, 0x49, 0x0a, 0x0c, 0x08, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x48, 0xfc, 0x40, 0x40, 0x40,
-+ 0xa0, 0xa0, 0x10, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x0f, 0x09, 0x0f, 0x09, 0x0f, 0x3f, 0x2f,
-+ 0x48, 0x0f, 0x0f, 0x08, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0xfc, 0xe8,
-+ 0x20, 0xe0, 0xe0, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x1b, 0x71, 0x12, 0x17, 0x7c, 0x13, 0x18,
-+ 0x37, 0x34, 0x57, 0x10, 0x10, 0x13, 0x00, 0x00,
-+ 0x40, 0xfc, 0x10, 0xa8, 0xfc, 0xa0, 0xf8, 0xa0,
-+ 0xfc, 0xe8, 0x90, 0xb0, 0xc8, 0x04, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x1f, 0x00, 0x3d, 0x05, 0x19,
-+ 0x63, 0x0f, 0x00, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xe0, 0x48, 0x88, 0x50, 0x30,
-+ 0x0c, 0xe0, 0x00, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x7e, 0x03, 0x3c, 0x01, 0x3c,
-+ 0x03, 0x3c, 0x27, 0x24, 0x3c, 0x27, 0x00, 0x00,
-+ 0x40, 0xfc, 0x10, 0xa8, 0xfc, 0xa0, 0xf8, 0xa0,
-+ 0xfc, 0xe8, 0x90, 0xb0, 0xc8, 0x04, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0d, 0x3f, 0x2e, 0x2e, 0x36,
-+ 0x37, 0x22, 0x3f, 0x22, 0x3e, 0x23, 0x00, 0x00,
-+ 0x20, 0xfc, 0x88, 0x54, 0xfc, 0x50, 0xf8, 0x50,
-+ 0xfc, 0x68, 0xd0, 0x50, 0x68, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x13, 0x22, 0x5d, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x19, 0x0f, 0x72, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0x00, 0xfc, 0x20, 0xa0,
-+ 0xb8, 0xa0, 0xa0, 0x60, 0x20, 0x1c, 0x00, 0x00,
-+ 0x00, 0x07, 0x74, 0x57, 0x54, 0x57, 0x55, 0x55,
-+ 0x55, 0x77, 0x4a, 0x4b, 0x12, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x38, 0xc0, 0xf0, 0x50,
-+ 0xf0, 0xf8, 0xa8, 0xf8, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x10, 0x13, 0x10, 0x7e, 0x12, 0x12, 0x12,
-+ 0x16, 0x1a, 0x62, 0x02, 0x02, 0x01, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x88, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x29, 0x7e, 0x22, 0x3e,
-+ 0x22, 0x3e, 0x24, 0x26, 0x3a, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x20, 0x20, 0xf8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xb8, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x10, 0x10, 0x17, 0x11,
-+ 0x19, 0x71, 0x11, 0x11, 0x1e, 0x30, 0x00, 0x00,
-+ 0x20, 0x28, 0x24, 0xfc, 0x20, 0x20, 0xe0, 0x20,
-+ 0x20, 0x10, 0x50, 0x94, 0x0c, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7e, 0x09, 0x19, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0x78, 0x48, 0x78, 0x48,
-+ 0x78, 0x48, 0x78, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7e, 0x11, 0x10, 0x1d, 0x25, 0x25, 0x55,
-+ 0x19, 0x09, 0x11, 0x11, 0x21, 0x41, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0x78, 0x48, 0x78, 0x48,
-+ 0x78, 0x48, 0x78, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x12, 0x17, 0x35, 0x39, 0x52,
-+ 0x17, 0x1a, 0x17, 0x24, 0x20, 0x47, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xf8, 0x00, 0xf8, 0x88,
-+ 0xe8, 0xa8, 0xe8, 0xa8, 0xf8, 0x30, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x66, 0x2a, 0x1b, 0x24, 0x7f,
-+ 0x12, 0x3b, 0x36, 0x37, 0x52, 0x10, 0x00, 0x00,
-+ 0x20, 0x30, 0xe8, 0xa8, 0xa0, 0xfc, 0x20, 0xa8,
-+ 0xa8, 0x90, 0x90, 0xb4, 0x4c, 0x84, 0x00, 0x00,
-+ 0x01, 0x7d, 0x2f, 0x2a, 0x3a, 0x2f, 0x28, 0x3b,
-+ 0x2a, 0x2f, 0x3a, 0x6b, 0x0a, 0x08, 0x00, 0x00,
-+ 0x20, 0x30, 0xe8, 0xa8, 0xa0, 0xfc, 0x20, 0xa8,
-+ 0xa8, 0xb0, 0x90, 0xb4, 0x4c, 0x84, 0x00, 0x00,
-+ 0x04, 0x07, 0x08, 0x10, 0x7f, 0x11, 0x11, 0x11,
-+ 0x1f, 0x10, 0x10, 0x10, 0x10, 0x0f, 0x00, 0x00,
-+ 0x00, 0xe0, 0x40, 0x80, 0xf0, 0x10, 0x10, 0x10,
-+ 0xf0, 0x10, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x1e, 0x24, 0x48, 0x3e, 0x2a, 0x3e, 0x2a,
-+ 0x2a, 0x3e, 0x22, 0x22, 0x22, 0x47, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xf8, 0xa8, 0xa8, 0xa8, 0xf8,
-+ 0xa8, 0x20, 0x30, 0x28, 0x3c, 0xc4, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x04, 0x19, 0x6f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x09, 0x08, 0x0e, 0x70, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x40, 0x30, 0xec, 0x20, 0xe0,
-+ 0x20, 0xf0, 0x10, 0xa0, 0x60, 0x1c, 0x00, 0x00,
-+ 0x08, 0x0c, 0x12, 0x2a, 0x48, 0x3e, 0x22, 0x3e,
-+ 0x22, 0x3e, 0x24, 0x26, 0x3a, 0x61, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xf8, 0xa8, 0xa8, 0xa8, 0xf8,
-+ 0xa8, 0x20, 0x30, 0x28, 0x3c, 0xc4, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x17, 0x10, 0x1f, 0x12, 0x23,
-+ 0x5c, 0x00, 0x7f, 0x04, 0x02, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x00, 0xfc, 0x48, 0xb0,
-+ 0x2c, 0x20, 0xfc, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x11, 0x11, 0x1f,
-+ 0x11, 0x11, 0x12, 0x22, 0x24, 0x48, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0xe0,
-+ 0x20, 0x20, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x12, 0x12, 0x33, 0x52, 0x12,
-+ 0x13, 0x12, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48,
-+ 0xf8, 0x48, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x17, 0x10, 0x33, 0x50, 0x13,
-+ 0x10, 0x13, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x00, 0xf8, 0x00, 0xf8,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x13, 0x10, 0x33, 0x50, 0x17,
-+ 0x14, 0x1b, 0x11, 0x10, 0x13, 0x1c, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x08, 0xf0, 0x20, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x17, 0x10, 0x1f, 0x14, 0x27,
-+ 0x58, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x90, 0x60,
-+ 0x1c, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x11, 0x7d, 0x25, 0x25, 0x25,
-+ 0x79, 0x4d, 0x0a, 0x12, 0x24, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x00, 0xfc, 0x68,
-+ 0x68, 0x70, 0x50, 0x50, 0x68, 0x84, 0x00, 0x00,
-+ 0x01, 0x3f, 0x20, 0x49, 0x08, 0x49, 0x29, 0x2b,
-+ 0x0a, 0x1f, 0x68, 0x08, 0x08, 0x0b, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf0, 0x10, 0xf0, 0xf0, 0xfc,
-+ 0x08, 0xf8, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x01, 0x3f, 0x20, 0x5f, 0x05, 0x7f, 0x05, 0x19,
-+ 0x6f, 0x09, 0x0f, 0x09, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x68, 0xa0, 0x40, 0xfc, 0x40, 0x30,
-+ 0xec, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x01, 0x00, 0x00, 0x02, 0x02, 0x02, 0x12, 0x12,
-+ 0x12, 0x22, 0x42, 0x02, 0x02, 0x01, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0x40, 0x00, 0x00, 0x10, 0x08,
-+ 0x04, 0x04, 0x00, 0x10, 0x10, 0xf0, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x19, 0x35, 0x35, 0x31, 0x51,
-+ 0x11, 0x11, 0x17, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0xfc, 0xa0, 0x10, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x12, 0x12, 0x13, 0x1e,
-+ 0x72, 0x12, 0x14, 0x14, 0x18, 0x33, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x00, 0xfc, 0xc8,
-+ 0xc8, 0xb0, 0xa0, 0x90, 0xc8, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x22, 0x12, 0x14, 0x7f, 0x08,
-+ 0x7e, 0x1c, 0x1b, 0x29, 0x4a, 0x08, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0x80, 0x80, 0xfc, 0x90, 0x90,
-+ 0x90, 0x90, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x14, 0x14, 0x7f, 0x00, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x50, 0xfc, 0x00, 0xe0,
-+ 0x20, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x03, 0x0d, 0x31, 0x09, 0x08,
-+ 0x7f, 0x18, 0x1c, 0x2a, 0x49, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x80, 0x60, 0x18, 0x20, 0x20,
-+ 0xfc, 0x60, 0x70, 0xa8, 0x24, 0x20, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7f, 0x10, 0x17, 0x39, 0x36,
-+ 0x34, 0x53, 0x50, 0x11, 0x16, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0xa0, 0xfc, 0x10, 0xe8,
-+ 0x44, 0xf8, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x10, 0x0b, 0x08, 0x43, 0x20, 0x23, 0x00, 0x17,
-+ 0x14, 0x1b, 0x21, 0x20, 0x41, 0x4e, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x08, 0xf0, 0x20, 0xc0, 0xe0, 0x1c, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x44, 0x20, 0x21, 0x02, 0x10,
-+ 0x17, 0x10, 0x21, 0x22, 0x44, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa8, 0xa0, 0xa4, 0x1c, 0x40, 0x40,
-+ 0xfc, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x21, 0x21, 0x3f, 0x21, 0x21,
-+ 0x3f, 0x21, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x08,
-+ 0xf8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x29, 0x2a, 0x0c, 0x19,
-+ 0x28, 0x48, 0x13, 0x10, 0x20, 0x47, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x80, 0x40, 0x30, 0x4c, 0x80,
-+ 0x20, 0xc8, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x0f, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x7f, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0xfc, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x0a, 0x0a, 0x13, 0x1a,
-+ 0x36, 0x57, 0x12, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0xf8, 0x48,
-+ 0x48, 0xf8, 0x48, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x3f, 0x01, 0x1f, 0x02, 0x7f, 0x04, 0x0f,
-+ 0x11, 0x6f, 0x03, 0x0d, 0x31, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x80, 0xfc, 0x40, 0xa0,
-+ 0x10, 0xec, 0x80, 0x60, 0x18, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x14, 0x67, 0x1a, 0x1a, 0x27, 0x7e,
-+ 0x12, 0x1b, 0x36, 0x34, 0x50, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0xf8, 0x48,
-+ 0x48, 0xf8, 0x48, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x21, 0x3f, 0x20, 0x20, 0x20,
-+ 0x3f, 0x21, 0x21, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10,
-+ 0xf0, 0x10, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x04, 0x00, 0x01, 0x04,
-+ 0x14, 0x14, 0x24, 0x44, 0x04, 0x03, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00, 0x90,
-+ 0x48, 0x44, 0x04, 0x20, 0x20, 0xe0, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x08, 0x3f, 0x12, 0x14, 0x7f,
-+ 0x08, 0x7f, 0x1c, 0x2a, 0x4a, 0x09, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x0c, 0x70, 0x40, 0x40, 0x7c,
-+ 0x48, 0x48, 0x48, 0x88, 0x88, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x22, 0x14, 0x7f, 0x08, 0x7f,
-+ 0x1c, 0x1a, 0x2a, 0x48, 0x09, 0x0a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x68, 0x60, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x00, 0x3d, 0x02, 0x3d,
-+ 0x00, 0x3c, 0x25, 0x24, 0x3c, 0x23, 0x00, 0x00,
-+ 0x40, 0x40, 0x60, 0xa0, 0x90, 0x28, 0x44, 0x90,
-+ 0x20, 0x44, 0x88, 0x10, 0x60, 0x80, 0x00, 0x00,
-+ 0x01, 0x02, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08,
-+ 0x0f, 0x78, 0x01, 0x06, 0x38, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xe0, 0x20, 0xe0, 0x24, 0xe8, 0x30,
-+ 0xe0, 0x60, 0xa0, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x08, 0x04, 0x04, 0x7f, 0x01,
-+ 0x01, 0x3f, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x20, 0x20, 0x40, 0xfc, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x21, 0x12, 0x13, 0x06, 0x0a, 0x73, 0x12,
-+ 0x13, 0x12, 0x13, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0x20,
-+ 0xf8, 0x20, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5d, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x3f, 0x21, 0x5d, 0x1d, 0x00,
-+ 0x1f, 0x13, 0x1f, 0x14, 0x27, 0x58, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0x08, 0x70, 0x70, 0x00,
-+ 0xf8, 0xe0, 0xfc, 0x90, 0x60, 0x1c, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
-+ 0x04, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
-+ 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x10, 0x10, 0x30, 0x50, 0x10,
-+ 0x10, 0x10, 0x10, 0x17, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x02, 0x02, 0x02, 0x1e, 0x07,
-+ 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x88, 0x48, 0x08, 0x08, 0x08, 0x70, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x1f, 0x12, 0x1f, 0x17, 0x14,
-+ 0x27, 0x58, 0x0f, 0x00, 0x3f, 0x00, 0x00, 0x00,
-+ 0x80, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0xcc, 0x70,
-+ 0x44, 0xbc, 0xf0, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x3d, 0x01, 0x01, 0x01, 0x7f, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x3f, 0x00, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x3e, 0x08,
-+ 0x0e, 0x30, 0x7f, 0x04, 0x02, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0xf8, 0x88,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x04, 0x3f, 0x04, 0x07, 0x04, 0x07, 0x04, 0x7f,
-+ 0x12, 0x12, 0x14, 0x18, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xc0, 0x40, 0xc0, 0x40, 0xfc,
-+ 0x80, 0x88, 0x78, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x08, 0x0f, 0x09, 0x10, 0x10,
-+ 0x23, 0x40, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x80, 0x40,
-+ 0x30, 0x8c, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3e, 0x22, 0x3f, 0x3f, 0x2f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x50, 0x60, 0x90, 0x0c, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x3d, 0x00, 0x7e, 0x00, 0x3c, 0x00, 0x3c,
-+ 0x01, 0x3c, 0x24, 0x25, 0x3d, 0x22, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0x90, 0x90, 0xb0, 0xd0,
-+ 0x90, 0x90, 0x94, 0x0c, 0x0c, 0x04, 0x00, 0x00,
-+ 0x00, 0x27, 0x11, 0x11, 0x01, 0x01, 0x0f, 0x71,
-+ 0x11, 0x11, 0x11, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0x20, 0x20, 0xe0, 0x20,
-+ 0x10, 0x14, 0x0c, 0x04, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x28, 0x2b, 0x32, 0x2b, 0x26,
-+ 0x27, 0x24, 0x27, 0x38, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x14, 0x15, 0x7f, 0x14, 0x1c, 0x08, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0xc8, 0x68, 0x58,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x00, 0x7f, 0x00, 0x3f,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x00, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0x00, 0xf8, 0x08, 0xe8,
-+ 0x08, 0x88, 0x88, 0x88, 0x88, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x02, 0x7a, 0x03, 0x3a, 0x02, 0x3b,
-+ 0x02, 0x3a, 0x2b, 0x2e, 0x38, 0x20, 0x00, 0x00,
-+ 0x00, 0xc0, 0xf8, 0xa8, 0xa8, 0xa8, 0xa8, 0x98,
-+ 0x90, 0xd0, 0xb0, 0xa8, 0xc8, 0x84, 0x00, 0x00,
-+ 0x10, 0x17, 0x20, 0x48, 0x09, 0x11, 0x25, 0x45,
-+ 0x09, 0x09, 0x11, 0x20, 0x43, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x80, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x08, 0xf8, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x40, 0xc0, 0x40, 0x7c, 0xa0, 0xa0, 0x3c, 0x20,
-+ 0x20, 0x3c, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x22, 0x29, 0x25, 0x24, 0x20,
-+ 0x27, 0x20, 0x23, 0x2c, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x28, 0x28, 0x28, 0x48, 0x48,
-+ 0x88, 0xc8, 0x28, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x17, 0x14, 0x14,
-+ 0x17, 0x14, 0x12, 0x23, 0x23, 0x4c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xc8, 0x08, 0x88, 0xfc, 0xc8,
-+ 0xa8, 0xa8, 0x88, 0x08, 0x88, 0x18, 0x00, 0x00,
-+ 0x00, 0x27, 0x10, 0x13, 0x02, 0x02, 0x73, 0x12,
-+ 0x11, 0x11, 0x17, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x10,
-+ 0x10, 0x20, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x01, 0x01, 0x79, 0x49, 0x49, 0x4a, 0x4a, 0x4c,
-+ 0x48, 0x78, 0x48, 0x41, 0x06, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x48, 0x50, 0x40,
-+ 0x40, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x09, 0x09, 0x7f, 0x09,
-+ 0x09, 0x3f, 0x01, 0x01, 0x3f, 0x00, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0xf8, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0xf8, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x3c, 0x25, 0x25, 0x3d, 0x25, 0x21,
-+ 0x3d, 0x25, 0x25, 0x3c, 0x24, 0x20, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x24, 0x24, 0x24, 0x24,
-+ 0x24, 0x24, 0x38, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x13, 0x15, 0x11, 0x15,
-+ 0x19, 0x71, 0x11, 0x11, 0x11, 0x31, 0x00, 0x00,
-+ 0x90, 0x90, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x7f, 0x05, 0x05, 0x09,
-+ 0x09, 0x11, 0x21, 0x41, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x08, 0x88, 0x90, 0x60, 0x40, 0x20,
-+ 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x0a, 0x2a, 0x2c, 0x29, 0x4a,
-+ 0x08, 0x0c, 0x12, 0x12, 0x21, 0x42, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa8, 0x30, 0x20,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x7b, 0x48, 0x4b, 0x79, 0x49, 0x4f, 0x79,
-+ 0x49, 0x4b, 0x78, 0x48, 0x07, 0x00, 0x00, 0x00,
-+ 0x18, 0xe0, 0x40, 0xf8, 0x50, 0x50, 0xfc, 0x50,
-+ 0x50, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2b, 0x2c, 0x08, 0x7e, 0x09, 0x1c,
-+ 0x1a, 0x2b, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xf0, 0x50, 0x54, 0x94, 0x2c, 0x20,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3e, 0x12, 0x0e, 0x32, 0x07, 0x01, 0x3f,
-+ 0x04, 0x0b, 0x11, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x38, 0xc8, 0x18, 0x00, 0xf8,
-+ 0x20, 0x50, 0x88, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x7f, 0x00, 0x0f, 0x08, 0x7f, 0x08, 0x0f,
-+ 0x03, 0x0d, 0x74, 0x04, 0x07, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xe0, 0x20, 0xfc, 0x20, 0xe0,
-+ 0x10, 0x10, 0xa0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x02, 0x21, 0x17, 0x10, 0x01, 0x0e, 0x71, 0x16,
-+ 0x11, 0x16, 0x10, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0x10, 0x20, 0xfc, 0x80, 0x88, 0xc8, 0x70, 0xe0,
-+ 0x50, 0x48, 0x44, 0x80, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x40, 0x40, 0xf0, 0x50, 0x50, 0x54, 0x94, 0x2c,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x23, 0x5e, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x48, 0x48, 0x90, 0xfc, 0x90, 0x90, 0xf8, 0x90,
-+ 0x90, 0xf8, 0x90, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x13, 0x22, 0x5c, 0x09, 0x7e,
-+ 0x08, 0x2b, 0x1c, 0x18, 0x0f, 0x70, 0x00, 0x00,
-+ 0x18, 0xe0, 0x20, 0xfc, 0xa8, 0xa8, 0xfc, 0xa8,
-+ 0xa8, 0xfc, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x25, 0x29, 0x30, 0x28, 0x27, 0x25,
-+ 0x25, 0x25, 0x39, 0x21, 0x22, 0x24, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x40, 0x78, 0xc8, 0x78, 0x48,
-+ 0x78, 0x48, 0x48, 0x58, 0x80, 0x7c, 0x00, 0x00,
-+ 0x00, 0x02, 0x7e, 0x13, 0x10, 0x17, 0x7c, 0x13,
-+ 0x12, 0x16, 0x1a, 0x62, 0x02, 0x02, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0xf8, 0x00, 0xfc, 0x40, 0xf8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x25, 0x2d, 0x2c, 0x7e, 0x43, 0x7d,
-+ 0x25, 0x3d, 0x25, 0x3d, 0x26, 0x2c, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0x78, 0x48, 0xf8, 0x48,
-+ 0x78, 0x48, 0x48, 0x58, 0x80, 0x7c, 0x00, 0x00,
-+ 0x11, 0x11, 0x1f, 0x01, 0x3f, 0x20, 0x4f, 0x00,
-+ 0x7f, 0x09, 0x09, 0x11, 0x21, 0x03, 0x00, 0x00,
-+ 0x10, 0x10, 0xf0, 0x00, 0xfc, 0x08, 0xe0, 0x00,
-+ 0xfc, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00,
-+ 0x01, 0x11, 0x1f, 0x01, 0x7f, 0x0f, 0x08, 0x0f,
-+ 0x3f, 0x20, 0x27, 0x24, 0x27, 0x20, 0x00, 0x00,
-+ 0x00, 0x10, 0xf0, 0x00, 0xfc, 0xe0, 0x20, 0xe0,
-+ 0xf8, 0x08, 0xc8, 0x48, 0xc8, 0x18, 0x00, 0x00,
-+ 0x49, 0x29, 0x2a, 0x7f, 0x1c, 0x1a, 0x2b, 0x48,
-+ 0x7f, 0x12, 0x3a, 0x04, 0x1a, 0x61, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0x88, 0x88, 0x48, 0x50,
-+ 0x30, 0x20, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x7f, 0x09, 0x19, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x08, 0x08, 0x48, 0x30, 0x10,
-+ 0x30, 0x48, 0x88, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x3f, 0x09, 0x09, 0x7e, 0x09, 0x28,
-+ 0x2f, 0x29, 0x39, 0x28, 0x27, 0x41, 0x00, 0x00,
-+ 0x80, 0xf8, 0x48, 0x58, 0xf8, 0x88, 0xb0, 0xf8,
-+ 0x48, 0x58, 0xf8, 0x88, 0x30, 0xfc, 0x00, 0x00,
-+ 0x10, 0x10, 0x3e, 0x52, 0x57, 0x7f, 0x52, 0x2c,
-+ 0x3e, 0x52, 0x56, 0x7e, 0x52, 0x2c, 0x00, 0x00,
-+ 0x48, 0x48, 0x90, 0xfc, 0x90, 0x90, 0xf8, 0x90,
-+ 0x90, 0xf8, 0x90, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x12, 0x13, 0x1e,
-+ 0x72, 0x15, 0x15, 0x19, 0x11, 0x31, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x48, 0x40, 0xfc, 0x40,
-+ 0x40, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x1c, 0x1a, 0x1a,
-+ 0x28, 0x28, 0x48, 0x08, 0x08, 0x09, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0x40, 0x88, 0x08, 0x10, 0x20,
-+ 0xc4, 0x04, 0x08, 0x10, 0x60, 0x80, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7f, 0x11, 0x19, 0x35, 0x34,
-+ 0x33, 0x52, 0x53, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x3f, 0x20, 0x4f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xfc, 0x08, 0xe0, 0x20,
-+ 0xe0, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x09, 0x3f, 0x2a, 0x2c, 0x28, 0x3e, 0x22,
-+ 0x32, 0x2c, 0x24, 0x2a, 0x32, 0x43, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x01, 0x05, 0x19, 0x63, 0x00, 0x03, 0x0f, 0x78,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x60, 0x18, 0x24, 0xc0, 0x40, 0xf8, 0x80,
-+ 0xf0, 0x80, 0xf0, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x09, 0x0b, 0x13, 0x1d,
-+ 0x35, 0x53, 0x12, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x23, 0x10, 0x15, 0x43, 0x23, 0x24, 0x0b, 0x12,
-+ 0x13, 0x12, 0x21, 0x21, 0x4f, 0x40, 0x00, 0x00,
-+ 0x90, 0x90, 0x64, 0x28, 0xf0, 0x08, 0xf4, 0x10,
-+ 0xf0, 0x20, 0x20, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x17, 0x14, 0x7e, 0x13, 0x14, 0x11, 0x1c,
-+ 0x73, 0x12, 0x13, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x00, 0xf8, 0xc8, 0xa8, 0xb8, 0xc8, 0x98, 0x80,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x08, 0x04,
-+ 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x12, 0x12, 0x12, 0x12, 0x7f, 0x12, 0x12, 0x12,
-+ 0x13, 0x12, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0x20,
-+ 0xe0, 0x20, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x22, 0x12, 0x1f, 0x42, 0x2f, 0x2a, 0x0a, 0x0f,
-+ 0x12, 0x17, 0x26, 0x2a, 0x52, 0x42, 0x00, 0x00,
-+ 0x00, 0x7c, 0x90, 0x78, 0xc8, 0xf8, 0xc8, 0xf8,
-+ 0x48, 0x78, 0xb0, 0xa8, 0x44, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x00, 0x3e, 0x2b, 0x2a,
-+ 0x3e, 0x2a, 0x2a, 0x3e, 0x23, 0x02, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x78, 0x88, 0x88, 0x10, 0x10,
-+ 0x30, 0x30, 0x48, 0x88, 0x04, 0x04, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x00, 0x7f,
-+ 0x09, 0x09, 0x09, 0x15, 0x23, 0x40, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x00, 0xfc,
-+ 0x00, 0xf0, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x0f, 0x40, 0x23, 0x20, 0x0f, 0x00, 0x13,
-+ 0x10, 0x2f, 0x21, 0x43, 0x40, 0x0f, 0x00, 0x00,
-+ 0x80, 0xfc, 0x80, 0xf0, 0x90, 0xfc, 0x90, 0xf0,
-+ 0x80, 0xfc, 0x20, 0xe0, 0xd0, 0x08, 0x00, 0x00,
-+ 0x14, 0x14, 0x1f, 0x24, 0x44, 0x7f, 0x04, 0x3f,
-+ 0x25, 0x25, 0x25, 0x26, 0x24, 0x04, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0xc8, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x48, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x3e, 0x09, 0x7f, 0x15, 0x2b, 0x7e, 0x08,
-+ 0x7f, 0x01, 0x3f, 0x02, 0x0c, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xf0, 0x50, 0xd0, 0x50, 0x70, 0x94,
-+ 0x0c, 0x00, 0xf0, 0x10, 0x10, 0xe0, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x11, 0x7d, 0x26, 0x26, 0x24,
-+ 0x79, 0x48, 0x0c, 0x14, 0x23, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0x20,
-+ 0xf8, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x0b, 0x10, 0x24, 0x45, 0x09, 0x09, 0x19,
-+ 0x29, 0x49, 0x09, 0x09, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x78, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x13, 0x3a, 0x34, 0x34, 0x53,
-+ 0x10, 0x10, 0x10, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0x40, 0xf8,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x1f, 0x10, 0x10, 0x1e, 0x12,
-+ 0x12, 0x12, 0x12, 0x2c, 0x21, 0x40, 0x00, 0x00,
-+ 0x90, 0x88, 0x88, 0xfc, 0x80, 0x90, 0x90, 0x50,
-+ 0x60, 0x20, 0x64, 0x94, 0x0c, 0x04, 0x00, 0x00,
-+ 0x00, 0x7f, 0x08, 0x08, 0x29, 0x2f, 0x2a, 0x28,
-+ 0x28, 0x28, 0x2e, 0x38, 0x63, 0x0c, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x10, 0x90, 0x90, 0x50,
-+ 0x60, 0x20, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x7f, 0x3e, 0x2a, 0x3f, 0x1c, 0x2a, 0x49,
-+ 0x3f, 0x01, 0x09, 0x09, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xc8, 0x28, 0x30, 0xc8, 0x04,
-+ 0xf8, 0x00, 0xe0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x09, 0x09,
-+ 0x1f, 0x21, 0x0f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0x00,
-+ 0xf8, 0x00, 0xe0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x78, 0x49, 0x48, 0x4f, 0x78, 0x49,
-+ 0x49, 0x49, 0x79, 0x49, 0x41, 0x01, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0x00, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7d, 0x10, 0x1b, 0x34, 0x35,
-+ 0x30, 0x57, 0x50, 0x11, 0x10, 0x13, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8,
-+ 0x40, 0xfc, 0x90, 0xd0, 0x70, 0x88, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7c, 0x10, 0x13, 0x3a, 0x36,
-+ 0x36, 0x53, 0x53, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xa0, 0xa0, 0xf8, 0xa8, 0xa8,
-+ 0xb8, 0x38, 0x18, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x01, 0x01, 0x11, 0x11, 0x11,
-+ 0x11, 0x11, 0x11, 0x11, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x47, 0x20, 0x2f, 0x00, 0x03,
-+ 0x12, 0x13, 0x22, 0x23, 0x42, 0x42, 0x00, 0x00,
-+ 0x80, 0xf8, 0x80, 0xf0, 0x80, 0xfc, 0x00, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x28, 0x28, 0x3f, 0x29, 0x2a, 0x48,
-+ 0x0d, 0x78, 0x08, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xa0, 0xfc, 0x20, 0x20, 0x20,
-+ 0xf8, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x09, 0x09, 0x09, 0x1f, 0x11, 0x21, 0x41,
-+ 0x1f, 0x01, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0xf0, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x1e, 0x12, 0x22, 0x4c,
-+ 0x1f, 0x12, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x90, 0x88, 0xfc, 0x90, 0x90, 0x60, 0x64, 0x9c,
-+ 0xf4, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x4b, 0x2a, 0x2c, 0x08, 0x7f, 0x08, 0x1c,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0xf8,
-+ 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x98, 0x00, 0x00,
-+ 0x00, 0x7f, 0x12, 0x1e, 0x1e, 0x13, 0x7e, 0x02,
-+ 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x78, 0x48, 0x48, 0x78, 0x48, 0x00,
-+ 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x3f, 0x00, 0x1f, 0x11,
-+ 0x11, 0x1f, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf8, 0x00, 0xf0, 0x10,
-+ 0x10, 0xf0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x14, 0x1f, 0x24, 0x7f, 0x3f, 0x24, 0x27, 0x01,
-+ 0x7f, 0x03, 0x0c, 0x74, 0x07, 0x38, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0xc8, 0xc8, 0xc8, 0x18, 0x00,
-+ 0xfc, 0x10, 0xa0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x04, 0x04, 0x04, 0x3f, 0x24, 0x24,
-+ 0x28, 0x28, 0x30, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0x80, 0xf8, 0x88, 0x88,
-+ 0x98, 0x98, 0x78, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7f, 0x01, 0x3d, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x25, 0x26, 0x3e, 0x24, 0x00, 0x00,
-+ 0x20, 0x28, 0x24, 0xfc, 0x20, 0x28, 0xe8, 0x68,
-+ 0x50, 0x50, 0x54, 0xec, 0x4c, 0x84, 0x00, 0x00,
-+ 0x08, 0x7e, 0x08, 0x0e, 0x78, 0x19, 0x07, 0x7f,
-+ 0x07, 0x07, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x18, 0xe0, 0x80, 0xfc, 0x90, 0x10, 0xc0, 0xfc,
-+ 0xc0, 0xc0, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x3d, 0x00, 0x7e, 0x00, 0x3f, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0xf8,
-+ 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x98, 0x00, 0x00,
-+ 0x02, 0x22, 0x12, 0x1f, 0x02, 0x02, 0x03, 0x7e,
-+ 0x12, 0x12, 0x17, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x08, 0x10, 0x60, 0xc0, 0x7c, 0x50, 0xd0, 0x50,
-+ 0x90, 0x90, 0x10, 0x10, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x78, 0x48, 0x78, 0x50, 0x7c,
-+ 0x90, 0x78, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x60, 0x00, 0x00,
-+ 0x08, 0x7f, 0x08, 0x3e, 0x09, 0x7f, 0x00, 0x3f,
-+ 0x22, 0x3e, 0x22, 0x3e, 0x22, 0x26, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x90, 0x20, 0xf8, 0x28, 0xfc,
-+ 0x28, 0xf8, 0x28, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x04, 0x02, 0x03, 0x0c, 0x78,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x40, 0x80, 0x80, 0x60, 0x3c,
-+ 0xe0, 0x20, 0xe0, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x03, 0x04, 0x38, 0x09, 0x09, 0x7f, 0x09, 0x1d,
-+ 0x1a, 0x2a, 0x48, 0x09, 0x0a, 0x0c, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xf8, 0x08, 0x08, 0xf8, 0x68,
-+ 0x60, 0xa0, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x25, 0x27, 0x3d, 0x25, 0x25,
-+ 0x3d, 0x25, 0x25, 0x25, 0x26, 0x4c, 0x00, 0x00,
-+ 0x40, 0x78, 0x90, 0x20, 0xfc, 0x00, 0x78, 0x48,
-+ 0x48, 0x70, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x0f, 0x18, 0x1f, 0x28, 0x4f, 0x08, 0x0f,
-+ 0x08, 0x3f, 0x02, 0x01, 0x07, 0x38, 0x00, 0x00,
-+ 0x40, 0xf8, 0x80, 0xf0, 0x80, 0xf0, 0x80, 0xfc,
-+ 0x00, 0xf0, 0x60, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x12, 0x1f, 0x12, 0x13, 0x10,
-+ 0x17, 0x14, 0x24, 0x24, 0x44, 0x00, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x20, 0xfc, 0x20, 0xe0, 0x80,
-+ 0xf8, 0x88, 0x88, 0x88, 0xb0, 0x80, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x1b, 0x34, 0x34, 0x37, 0x50,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x90, 0x90, 0x90, 0xfc, 0x90, 0x90, 0xfc, 0x00,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x12, 0x13, 0x12, 0x1f, 0x12,
-+ 0x17, 0x16, 0x2a, 0x32, 0x42, 0x06, 0x00, 0x00,
-+ 0x50, 0x48, 0xfc, 0x40, 0xc8, 0x48, 0xc8, 0x28,
-+ 0x30, 0xb0, 0xb4, 0x4c, 0x8c, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x08,
-+ 0x09, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00,
-+ 0x10, 0x60, 0x80, 0x00, 0x00, 0xfc, 0x40, 0x40,
-+ 0xc0, 0x70, 0x48, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x04, 0x04, 0x3f, 0x04, 0x04, 0x7f, 0x00, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0xe0,
-+ 0x20, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7e, 0x08, 0x18, 0x1c, 0x1a,
-+ 0x2a, 0x28, 0x49, 0x09, 0x0a, 0x0c, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x80, 0x80, 0xfc, 0x90, 0x90,
-+ 0x90, 0x90, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x02, 0x02, 0x02, 0x04, 0x07, 0x0c,
-+ 0x0c, 0x14, 0x24, 0x44, 0x07, 0x04, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x1b, 0x70, 0x13, 0x10, 0x7f, 0x11, 0x19,
-+ 0x35, 0x35, 0x51, 0x11, 0x11, 0x16, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0xf8, 0x08,
-+ 0xf8, 0xf8, 0x08, 0xf8, 0x98, 0x04, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x08, 0x7f, 0x08, 0x3f,
-+ 0x08, 0x7f, 0x1c, 0x2a, 0x49, 0x08, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x50, 0x50, 0xfc, 0x50, 0xfc,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x00, 0x00,
-+ 0x08, 0x09, 0x0a, 0x72, 0x14, 0x0f, 0x12, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x0b, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0xf8, 0x88,
-+ 0xf8, 0xf8, 0x88, 0xf8, 0xc8, 0x04, 0x00, 0x00,
-+ 0x01, 0x39, 0x01, 0x3a, 0x02, 0x04, 0x1f, 0x68,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x38, 0x00, 0xb8, 0x40, 0x20, 0xf0, 0x2c,
-+ 0xe0, 0x20, 0xe0, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x01, 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x0f, 0x08,
-+ 0x0f, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0xe0, 0x20,
-+ 0xe0, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x01, 0x01, 0x7f, 0x02, 0x12,
-+ 0x12, 0x22, 0x44, 0x04, 0x08, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x40, 0x50,
-+ 0x48, 0x44, 0x44, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x23, 0x3e, 0x08, 0x28, 0x2e,
-+ 0x29, 0x2a, 0x2e, 0x38, 0x61, 0x02, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x50, 0x50, 0xd8, 0xd8,
-+ 0x54, 0x54, 0x90, 0x90, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3d, 0x24, 0x24, 0x3c, 0x2b, 0x08, 0x2e,
-+ 0x28, 0x28, 0x28, 0x2e, 0x38, 0x63, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0xf8, 0x88,
-+ 0xf8, 0xf8, 0x88, 0xf8, 0xc8, 0x04, 0x00, 0x00,
-+ 0x00, 0x7f, 0x10, 0x10, 0x11, 0x3d, 0x25, 0x65,
-+ 0x25, 0x25, 0x3d, 0x20, 0x23, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x80, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x08, 0xf8, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x11, 0x10, 0x13, 0x1c, 0x70, 0x10, 0x10,
-+ 0x12, 0x12, 0x0e, 0x01, 0x06, 0x18, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x88, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x12, 0x7e, 0x12, 0x13, 0x12, 0x10,
-+ 0x1a, 0x72, 0x12, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x40, 0x40, 0x48, 0x48, 0x48, 0xf8, 0x48, 0x40,
-+ 0x48, 0x48, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7d, 0x10, 0x17, 0x10, 0x17,
-+ 0x18, 0x70, 0x11, 0x10, 0x10, 0x37, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x10, 0xa0, 0xfc, 0x40, 0xfc,
-+ 0x90, 0x90, 0xe0, 0x30, 0xc8, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x1f,
-+ 0x71, 0x10, 0x10, 0x10, 0x13, 0x3c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x90, 0xf0, 0x90, 0xf0, 0x9c, 0xf0,
-+ 0x18, 0xb0, 0x00, 0xa0, 0x18, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x11, 0x11, 0x11, 0x1d,
-+ 0x71, 0x12, 0x12, 0x14, 0x18, 0x30, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x00, 0x00, 0xfc, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x00, 0x3d, 0x02, 0x3d,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x23, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x94, 0x94, 0x0c, 0x00, 0xf8,
-+ 0x88, 0x90, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x24, 0x44, 0x08, 0x10, 0x13,
-+ 0x1c, 0x70, 0x10, 0x12, 0x0f, 0x02, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x88, 0x88, 0x78, 0x00, 0xf8,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x1e, 0x12, 0x1e,
-+ 0x12, 0x1e, 0x14, 0x12, 0x1d, 0x70, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0x78, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x70, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x3c, 0x00, 0x7f, 0x01, 0x3d, 0x01, 0x3d,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3d, 0x26, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xf8, 0x08, 0x08, 0xf8, 0x68,
-+ 0x60, 0x60, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x3f, 0x21, 0x5d, 0x1d, 0x01,
-+ 0x1f, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0x08, 0x70, 0x70, 0x00,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x15, 0x0c, 0x12, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x90, 0x20, 0xf8, 0xa8, 0xa8,
-+ 0xf8, 0x88, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x01, 0x01, 0x7f, 0x01, 0x01,
-+ 0x0f, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0xe0, 0x20, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x28, 0x0c, 0x0b, 0x0e, 0x70, 0x00, 0x00, 0x00,
-+ 0x44, 0x24, 0xa8, 0x90, 0xf8, 0xa8, 0xf8, 0xa8,
-+ 0xf8, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x12, 0x12, 0x32, 0x52, 0x12,
-+ 0x12, 0x12, 0x12, 0x13, 0x12, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0xf8, 0x08, 0x08, 0x00, 0x00,
-+ 0x01, 0x09, 0x09, 0x0f, 0x11, 0x21, 0x7f, 0x02,
-+ 0x02, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x80,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x01, 0x01, 0x01, 0x7f, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, 0x02, 0x3f,
-+ 0x20, 0x20, 0x20, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xf0,
-+ 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x5f, 0x00, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x00, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0xf0, 0x00, 0xe0, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x1f, 0x11, 0x1f, 0x11, 0x1f,
-+ 0x00, 0x7f, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x01, 0x01, 0x09, 0x09, 0x11, 0x21, 0x03, 0x01,
-+ 0x7f, 0x01, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00,
-+ 0xfc, 0x00, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x08, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x11, 0x49, 0x2a, 0x24, 0x3e, 0x2b, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0x40, 0x7c, 0xc0, 0x48, 0x48,
-+ 0x50, 0x30, 0x24, 0xd4, 0x0c, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f,
-+ 0x19, 0x15, 0x27, 0x39, 0x41, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0x00, 0xf8,
-+ 0x48, 0x28, 0x38, 0xc8, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7f, 0x14, 0x14, 0x13, 0x19,
-+ 0x77, 0x11, 0x1f, 0x11, 0x16, 0x38, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x40, 0xc8, 0xb8, 0x20,
-+ 0xf8, 0x20, 0xfc, 0x10, 0x08, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7e, 0x09, 0x1e, 0x1b, 0x1a,
-+ 0x28, 0x2b, 0x48, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0x08, 0xfc, 0x40,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x0a, 0x1c, 0x1a, 0x1a,
-+ 0x28, 0x2b, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x00, 0xf8, 0xa8, 0xa8,
-+ 0xa8, 0xfc, 0x88, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x01, 0x02, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x01,
-+ 0x3f, 0x03, 0x05, 0x19, 0x61, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x08,
-+ 0x90, 0xe0, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x47, 0x20, 0x23, 0x00, 0x17,
-+ 0x10, 0x10, 0x20, 0x21, 0x46, 0x40, 0x00, 0x00,
-+ 0x90, 0x88, 0xf8, 0x80, 0xf0, 0x80, 0xf8, 0x90,
-+ 0x50, 0x60, 0x64, 0x94, 0x0c, 0x04, 0x00, 0x00,
-+ 0x10, 0x09, 0x09, 0x41, 0x22, 0x24, 0x07, 0x10,
-+ 0x10, 0x11, 0x21, 0x22, 0x44, 0x48, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0xa0,
-+ 0xa0, 0x20, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x10, 0x48, 0x2b, 0x20, 0x08, 0x11, 0x22, 0x41,
-+ 0x3f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x80, 0x80, 0xe0, 0xa0, 0xa4, 0x24, 0x1c, 0x00,
-+ 0xf8, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x11, 0x09, 0x0f, 0x41, 0x2f, 0x23, 0x02, 0x14,
-+ 0x1b, 0x12, 0x23, 0x22, 0x43, 0x42, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x20, 0xfc, 0x30, 0xd0, 0x88,
-+ 0xf4, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x04, 0x7f, 0x00, 0x3e, 0x22, 0x3e, 0x3e,
-+ 0x22, 0x26, 0x00, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x20, 0x40, 0xfc, 0x00, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x18, 0x00, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x13, 0x16, 0x37, 0x3a, 0x53,
-+ 0x12, 0x1b, 0x16, 0x23, 0x24, 0x48, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0x00, 0xf8,
-+ 0x48, 0x68, 0xd8, 0x68, 0x48, 0xd8, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x11, 0x11, 0x1e, 0x14,
-+ 0x14, 0x14, 0x24, 0x24, 0x45, 0x1a, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x00, 0xfc, 0x28, 0xb0,
-+ 0xa0, 0xbc, 0xa0, 0xa0, 0x60, 0x1c, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x24, 0x48, 0x10, 0x0f, 0x08,
-+ 0x08, 0x7f, 0x03, 0x0c, 0x70, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x88, 0x88, 0x78, 0xf0, 0x40,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x4d, 0x04, 0x7f, 0x00, 0x3e,
-+ 0x22, 0x3e, 0x22, 0x3e, 0x22, 0x26, 0x00, 0x00,
-+ 0x40, 0xfc, 0xa0, 0x30, 0x40, 0xfc, 0x00, 0x48,
-+ 0x48, 0x48, 0x48, 0x48, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0c, 0x12, 0x7f,
-+ 0x0d, 0x2a, 0x2a, 0x29, 0x4a, 0x08, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x20,
-+ 0xe4, 0x78, 0xb0, 0x28, 0x24, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x64, 0x18, 0x1b, 0x25, 0x7d,
-+ 0x13, 0x3b, 0x35, 0x31, 0x56, 0x10, 0x00, 0x00,
-+ 0x90, 0x98, 0xf4, 0x94, 0x90, 0xfc, 0x50, 0x74,
-+ 0x74, 0x58, 0x78, 0x94, 0x2c, 0x44, 0x00, 0x00,
-+ 0x04, 0x3f, 0x01, 0x0f, 0x01, 0x7f, 0x10, 0x08,
-+ 0x41, 0x22, 0x0c, 0x10, 0x21, 0x26, 0x00, 0x00,
-+ 0x40, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x80, 0x80,
-+ 0xfc, 0x48, 0x50, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x25, 0x25, 0x3d, 0x25, 0x24,
-+ 0x3d, 0x24, 0x24, 0x25, 0x26, 0x4c, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x20,
-+ 0xe4, 0x78, 0xb0, 0x28, 0x24, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x0e, 0x12, 0x12, 0x32, 0x4a,
-+ 0x05, 0x04, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0xfc, 0x90, 0x90, 0x90, 0x90,
-+ 0xfc, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x04, 0x08, 0x1e, 0x12, 0x1a, 0x16, 0x17, 0x1e,
-+ 0x72, 0x1a, 0x1a, 0x2a, 0x22, 0x46, 0x00, 0x00,
-+ 0x70, 0x10, 0x50, 0x50, 0x88, 0x88, 0x04, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x1f, 0x12, 0x1f, 0x12, 0x1f,
-+ 0x13, 0x12, 0x23, 0x2a, 0x49, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8,
-+ 0xfc, 0x00, 0xfc, 0xa4, 0x54, 0x18, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x01, 0x3e, 0x03, 0x3c,
-+ 0x00, 0x3d, 0x24, 0x24, 0x3f, 0x24, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0x08, 0xfc, 0x40,
-+ 0x40, 0xf0, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x27, 0x3c, 0x27, 0x3c, 0x27,
-+ 0x24, 0x3c, 0x18, 0x14, 0x27, 0x40, 0x00, 0x00,
-+ 0x50, 0x48, 0x7c, 0xc0, 0x78, 0xc0, 0x7c, 0xc8,
-+ 0x48, 0x30, 0x24, 0xd4, 0x0c, 0x04, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x23, 0x3e, 0x09, 0x28, 0x2f,
-+ 0x28, 0x28, 0x2e, 0x38, 0x61, 0x06, 0x00, 0x00,
-+ 0x50, 0x48, 0x78, 0xc0, 0x78, 0xc0, 0x7c, 0xc8,
-+ 0x48, 0x30, 0x24, 0x54, 0x8c, 0x04, 0x00, 0x00,
-+ 0x00, 0x27, 0x10, 0x17, 0x04, 0x03, 0x71, 0x17,
-+ 0x11, 0x1f, 0x10, 0x1b, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x44, 0xfc, 0x20, 0xf8,
-+ 0x20, 0xfc, 0xa0, 0x18, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x27, 0x10, 0x13, 0x02, 0x03, 0x70, 0x1f,
-+ 0x13, 0x1c, 0x11, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xf8, 0xa8, 0xf8, 0x80, 0xfc,
-+ 0xf0, 0x28, 0xe4, 0x10, 0xf0, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x13, 0x22, 0x5d, 0x08, 0x7f,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x73, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0xfc, 0x40, 0xf8, 0x40, 0xfc,
-+ 0x48, 0x28, 0x30, 0x34, 0xcc, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x09, 0x7f,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x72, 0x00, 0x00,
-+ 0x20, 0x20, 0xa0, 0xa0, 0xf8, 0xa0, 0x20, 0xfc,
-+ 0x50, 0x50, 0x90, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x21, 0x21,
-+ 0x22, 0x22, 0x24, 0x28, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0x08,
-+ 0x88, 0x88, 0x48, 0x28, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x25, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x05, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x88, 0x48, 0x50, 0xfc, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x04, 0x04, 0x7f, 0x00, 0x3e, 0x22, 0x22,
-+ 0x3e, 0x22, 0x3e, 0x22, 0x22, 0x26, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0xfc, 0x00, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x48, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x04, 0x3f, 0x01, 0x1f, 0x01, 0x3f, 0x09,
-+ 0x7f, 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x00, 0xf0, 0x00, 0xf8, 0x20,
-+ 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x22, 0x12, 0x1f, 0x42, 0x2f, 0x2a, 0x0f, 0x0a,
-+ 0x1f, 0x12, 0x3f, 0x22, 0x42, 0x42, 0x00, 0x00,
-+ 0x08, 0x08, 0xd0, 0x20, 0xa0, 0xbc, 0xa8, 0xa8,
-+ 0xa8, 0x28, 0xe8, 0x48, 0x48, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x19, 0x15, 0x32, 0x4a, 0x0c,
-+ 0x19, 0x60, 0x14, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x20, 0x28, 0x24, 0xfc, 0x20, 0x60, 0x50, 0x90,
-+ 0x08, 0x04, 0x90, 0x48, 0x44, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x04, 0x18, 0x60, 0x1f, 0x01,
-+ 0x01, 0x0f, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x40, 0x30, 0x0c, 0xf0, 0x00,
-+ 0x00, 0xe0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x12, 0x11, 0x7d, 0x0b, 0x0a, 0x13, 0x1a,
-+ 0x37, 0x54, 0x17, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x88, 0x48, 0x50, 0x20, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x09, 0x0a, 0x72, 0x14, 0x0f, 0x12, 0x7e,
-+ 0x09, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x88, 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0xa8, 0x70,
-+ 0xfc, 0x00, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x01, 0x3c, 0x27, 0x24, 0x25, 0x3c, 0x27, 0x25,
-+ 0x3f, 0x24, 0x25, 0x25, 0x25, 0x4d, 0x00, 0x00,
-+ 0x10, 0xa0, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0x50,
-+ 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x57, 0x36, 0x3a, 0x12, 0x7e, 0x12, 0x1a,
-+ 0x36, 0x36, 0x52, 0x14, 0x17, 0x18, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x00, 0x7b, 0x4a, 0x4b, 0x4a, 0x4b, 0x48,
-+ 0x49, 0x79, 0x49, 0x41, 0x01, 0x01, 0x00, 0x00,
-+ 0x10, 0xa0, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x00,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x22, 0x14, 0x7f, 0x2a, 0x2a, 0x3e, 0x2a, 0x09,
-+ 0x11, 0x2f, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x08,
-+ 0x18, 0xe0, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x11, 0x11, 0x55, 0x55, 0x55, 0x55, 0x55,
-+ 0x55, 0x7d, 0x45, 0x41, 0x0f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x10, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x7d, 0x11, 0x17, 0x10, 0x1f,
-+ 0x72, 0x13, 0x12, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0xf0,
-+ 0x10, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x04, 0x18, 0x7f, 0x15, 0x13, 0x1f, 0x10,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0xc0, 0x20, 0x10, 0xfc, 0x50, 0x90, 0xf0, 0x10,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x08, 0x04, 0x3f, 0x21, 0x3f, 0x21, 0x3f, 0x20,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x0e, 0x15, 0x65, 0x04, 0x7f,
-+ 0x01, 0x11, 0x11, 0x19, 0x27, 0x41, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x60, 0xb0, 0x2c, 0x20, 0xf8,
-+ 0x10, 0x20, 0xf0, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x04, 0x45, 0x29, 0x11, 0x31, 0x49, 0x09, 0x19,
-+ 0x19, 0x29, 0x49, 0x09, 0x0f, 0x30, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x10, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7e, 0x03, 0x0c, 0x08, 0x2b, 0x28, 0x2d,
-+ 0x29, 0x29, 0x29, 0x2f, 0x3a, 0x64, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x50, 0x98, 0xe4, 0x10, 0x50,
-+ 0x50, 0x50, 0x50, 0x54, 0x54, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7e, 0x07, 0x08, 0x0b, 0x2a, 0x2e, 0x2b,
-+ 0x28, 0x28, 0x29, 0x2e, 0x38, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0xe0, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x01, 0x7d, 0x17, 0x11, 0x13, 0x3b, 0x2d, 0x6b,
-+ 0x28, 0x2a, 0x3a, 0x23, 0x24, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0xb8, 0x54, 0x10, 0xfc,
-+ 0x48, 0x40, 0x78, 0x40, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x09, 0x09, 0x11, 0x19,
-+ 0x35, 0x57, 0x11, 0x11, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x10, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x02, 0x0c, 0x38, 0x08, 0x08, 0x7f, 0x08, 0x1c,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88,
-+ 0xf8, 0x88, 0x88, 0x88, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2a, 0x2c, 0x08, 0x7e, 0x08, 0x1c,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88,
-+ 0xf8, 0x88, 0x88, 0x88, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x02, 0x0c,
-+ 0x03, 0x7f, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x40, 0xc0,
-+ 0x30, 0xc8, 0x40, 0x30, 0x08, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0c, 0x12, 0x7f,
-+ 0x0c, 0x2a, 0x2a, 0x28, 0x4b, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88,
-+ 0xf8, 0x88, 0x88, 0x88, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x10, 0x1e, 0x24, 0x7e, 0x2b,
-+ 0x3e, 0x2a, 0x3e, 0x3b, 0x2d, 0x40, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x18, 0xe0, 0x20, 0x20, 0xfc,
-+ 0x70, 0x70, 0xa8, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x00, 0x3c, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x25, 0x25, 0x3e, 0x24, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x80, 0x80, 0xfc, 0x90, 0x90,
-+ 0xb0, 0x98, 0x14, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x29, 0x29, 0x31, 0x29, 0x25,
-+ 0x25, 0x25, 0x39, 0x21, 0x2f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x10, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x22, 0x13, 0x1f, 0x01, 0x05, 0x05, 0x77,
-+ 0x15, 0x11, 0x12, 0x1c, 0x26, 0x41, 0x00, 0x00,
-+ 0x80, 0xb8, 0x28, 0xe8, 0x38, 0x68, 0x68, 0xf8,
-+ 0x28, 0x48, 0x48, 0x98, 0x00, 0xfc, 0x00, 0x00,
-+ 0x03, 0x1c, 0x10, 0x1e, 0x10, 0x1f, 0x00, 0x15,
-+ 0x13, 0x19, 0x15, 0x15, 0x19, 0x66, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0x50,
-+ 0x30, 0x90, 0x54, 0x4c, 0x8c, 0x04, 0x00, 0x00,
-+ 0x09, 0x08, 0x0b, 0x12, 0x13, 0x32, 0x53, 0x10,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x10, 0xa0, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x00,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x04, 0x06, 0x09, 0x14, 0x3f, 0x51, 0x1f, 0x11,
-+ 0x1f, 0x10, 0x3f, 0x31, 0x5f, 0x11, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0xc8, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x02, 0x22, 0x12, 0x0c, 0x04,
-+ 0x04, 0x0a, 0x0a, 0x10, 0x21, 0x42, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x50, 0x50,
-+ 0x60, 0x20, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x12, 0x0a, 0x7f, 0x04, 0x3f, 0x1f, 0x01, 0x7f,
-+ 0x12, 0x1f, 0x1e, 0x12, 0x7e, 0x03, 0x00, 0x00,
-+ 0x90, 0xa0, 0xfc, 0x40, 0xf8, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xf8, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x01, 0x02, 0x04, 0x1f, 0x60, 0x0f, 0x08, 0x0f,
-+ 0x0f, 0x08, 0x1f, 0x18, 0x2f, 0x08, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0xf0, 0x0c, 0xe0, 0x20, 0xe0,
-+ 0xe0, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x3d, 0x25, 0x3d, 0x25, 0x01,
-+ 0x7f, 0x08, 0x08, 0x08, 0x0e, 0x70, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x78, 0x48, 0x78, 0x48, 0x00,
-+ 0xfc, 0x90, 0xa0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x48, 0x28, 0x2f, 0x08, 0x08,
-+ 0x18, 0x18, 0x28, 0x48, 0x0b, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x01, 0x1f, 0x02, 0x7f, 0x04,
-+ 0x1f, 0x61, 0x1f, 0x02, 0x0c, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xf0, 0x80, 0xfc, 0xc0,
-+ 0x30, 0x0c, 0xf0, 0x80, 0x60, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x05, 0x35, 0x09, 0x1d, 0x65,
-+ 0x19, 0x15, 0x66, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x68, 0x10, 0x68, 0xc8,
-+ 0x30, 0xa8, 0xc8, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x41, 0x01, 0x7f, 0x03,
-+ 0x05, 0x19, 0x61, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x00, 0x00, 0xfc, 0x80,
-+ 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x12, 0x17, 0x17, 0x14,
-+ 0x17, 0x13, 0x23, 0x22, 0x43, 0x02, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x20, 0xf8, 0xf8, 0x88,
-+ 0xf8, 0xf0, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x20, 0x27, 0x24, 0x24, 0x24,
-+ 0x24, 0x24, 0x24, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xf0, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0xe0, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x09, 0x29, 0x3f, 0x2a, 0x4c, 0x19, 0x6a, 0x08,
-+ 0x01, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0xa8, 0xa8, 0x28, 0x48, 0xb0,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x08, 0x08, 0x7e, 0x08, 0x1c, 0x1a, 0x2a, 0x48,
-+ 0x09, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0xf8,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x13, 0x12, 0x13, 0x10,
-+ 0x1f, 0x71, 0x10, 0x10, 0x11, 0x36, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x40,
-+ 0xf8, 0x10, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x10, 0x11, 0x10, 0x7d, 0x10, 0x11, 0x10, 0x1f,
-+ 0x74, 0x13, 0x12, 0x12, 0x12, 0x30, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x48, 0xf8, 0x48, 0x48, 0x70, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x17, 0x10, 0x13, 0x1e,
-+ 0x73, 0x12, 0x13, 0x12, 0x10, 0x30, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x40, 0xfc, 0x40, 0xf8, 0x48,
-+ 0xf8, 0x48, 0xf8, 0x48, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x10, 0x17, 0x10, 0x1f,
-+ 0x72, 0x13, 0x12, 0x10, 0x10, 0x37, 0x00, 0x00,
-+ 0x00, 0xf8, 0x90, 0x60, 0xf0, 0x4c, 0x40, 0xf8,
-+ 0x48, 0xf8, 0x48, 0x50, 0x78, 0x84, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x10, 0x17, 0x14, 0x1f,
-+ 0x70, 0x17, 0x10, 0x11, 0x16, 0x30, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xbc, 0xa4, 0xbc,
-+ 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x1f, 0x11,
-+ 0x01, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0xf0, 0x10,
-+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3f, 0x24, 0x3f, 0x24, 0x3f,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x12, 0x09, 0x09, 0x1f, 0x11, 0x1f, 0x11, 0x1f,
-+ 0x01, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x12, 0x15, 0x39, 0x35,
-+ 0x35, 0x51, 0x53, 0x15, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xf0, 0x08, 0xf4, 0x10, 0xf0,
-+ 0xf0, 0x00, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7f, 0x12, 0x13, 0x3a, 0x37,
-+ 0x35, 0x51, 0x51, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0xa0, 0xfc, 0xa0, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x43, 0x22, 0x23, 0x02, 0x0b,
-+ 0x09, 0x09, 0x11, 0x11, 0x21, 0x21, 0x00, 0x00,
-+ 0xa0, 0xfc, 0xa0, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x15, 0x34, 0x3b, 0x32, 0x53,
-+ 0x10, 0x17, 0x18, 0x25, 0x26, 0x40, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xb8, 0xa8, 0xb8,
-+ 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x01, 0x03, 0x0c, 0x30, 0x1f, 0x01, 0x7f, 0x01,
-+ 0x01, 0x1f, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xe0, 0x40, 0x80, 0xf0, 0x10, 0xfc, 0x10,
-+ 0x10, 0xf0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x4b, 0x2a, 0x2b, 0x0a, 0x1b,
-+ 0x28, 0x4b, 0x10, 0x10, 0x21, 0x4e, 0x00, 0x00,
-+ 0x80, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x40, 0xf8, 0x90, 0x60, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x7f, 0x09, 0x19, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x08,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x24, 0x45, 0x09, 0x12, 0x0f,
-+ 0x01, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x48, 0x38, 0x40, 0x30, 0xc8,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x57, 0x34, 0x3b, 0x12, 0x7f, 0x12, 0x3b,
-+ 0x35, 0x55, 0x51, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0xa0, 0xfc, 0xa0, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x15, 0x0c, 0x12, 0x7e,
-+ 0x0c, 0x2a, 0x2a, 0x29, 0x4a, 0x08, 0x00, 0x00,
-+ 0x30, 0x90, 0x90, 0xa8, 0x24, 0x50, 0xf8, 0x48,
-+ 0x20, 0xe8, 0xc4, 0x54, 0x50, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x15, 0x0c, 0x12, 0x7f,
-+ 0x0c, 0x2a, 0x2a, 0x29, 0x48, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x00, 0xf8, 0x00, 0xfc,
-+ 0x20, 0xa8, 0xa4, 0x24, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x7e, 0x24, 0x25, 0x3e, 0x24, 0x25, 0x3c,
-+ 0x24, 0x25, 0x3d, 0x66, 0x04, 0x04, 0x00, 0x00,
-+ 0x70, 0x90, 0x90, 0x48, 0x64, 0x90, 0xf8, 0x48,
-+ 0xa0, 0xa8, 0x84, 0x94, 0x90, 0x70, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x1f, 0x10, 0x1f, 0x10,
-+ 0x1f, 0x01, 0x7f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x48, 0x28, 0x2f,
-+ 0x08, 0x18, 0x28, 0x48, 0x0b, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0xfc,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x7f, 0x08, 0x1f, 0x72, 0x0c,
-+ 0x74, 0x04, 0x7f, 0x04, 0x08, 0x30, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xfc, 0x80, 0x98, 0xe0, 0x84,
-+ 0x7c, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x7f, 0x09, 0x02, 0x0f, 0x7f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x17, 0x14, 0x27, 0x44, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0x80, 0xe0, 0xfc, 0x20, 0xe0,
-+ 0x20, 0xe0, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x11, 0x09, 0x49, 0x23, 0x22,
-+ 0x0b, 0x08, 0x17, 0x11, 0x26, 0x20, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x10, 0xf0, 0xb8, 0xa8,
-+ 0xf8, 0x40, 0xfc, 0xf0, 0x4c, 0x40, 0x00, 0x00,
-+ 0x04, 0x24, 0x17, 0x04, 0x1c, 0x65, 0x05, 0x01,
-+ 0x7f, 0x04, 0x1c, 0x64, 0x07, 0x18, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x00, 0x00,
-+ 0xfc, 0x90, 0x90, 0x60, 0x30, 0x0c, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x01, 0x01, 0x7f, 0x01, 0x09,
-+ 0x09, 0x09, 0x09, 0x15, 0x23, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0xf8, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x02, 0x21, 0x11, 0x17, 0x00, 0x00, 0x7f, 0x10,
-+ 0x11, 0x11, 0x12, 0x1c, 0x26, 0x41, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xf8, 0x80, 0x80, 0xfc, 0xc0,
-+ 0x20, 0x10, 0x08, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x27, 0x13, 0x12, 0x03, 0x02, 0x73, 0x11,
-+ 0x11, 0x11, 0x11, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0xa0, 0xfc, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x23, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1d, 0x19, 0x0e, 0x70, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0xf8, 0x04, 0xf8, 0x88, 0xf8,
-+ 0xf8, 0x80, 0xfc, 0x84, 0xfc, 0x84, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x3f, 0x3d, 0x5d, 0x00, 0x08,
-+ 0x7f, 0x1c, 0x1a, 0x29, 0x48, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0x78, 0x70, 0x00, 0xf8,
-+ 0x88, 0xf8, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3f, 0x28, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x42, 0x0d, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x50, 0x70, 0xac, 0x20, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0x28, 0x3c, 0xc4, 0x00, 0x00,
-+ 0x08, 0x09, 0x0e, 0x13, 0x12, 0x33, 0x50, 0x11,
-+ 0x16, 0x11, 0x16, 0x11, 0x16, 0x10, 0x00, 0x00,
-+ 0x80, 0xf0, 0x20, 0xf8, 0x48, 0xf8, 0x40, 0x88,
-+ 0xd0, 0x60, 0xb0, 0x28, 0x24, 0xc0, 0x00, 0x00,
-+ 0x01, 0x10, 0x13, 0x12, 0x7f, 0x12, 0x13, 0x10,
-+ 0x15, 0x19, 0x61, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x10, 0xa0, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x00,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x11, 0x10, 0x13, 0x1a, 0x37, 0x36, 0x33, 0x50,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x10, 0xa0, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x00,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x3f, 0x29, 0x28, 0x3b, 0x2a, 0x2b, 0x3b,
-+ 0x2b, 0x2b, 0x2b, 0x2b, 0x2d, 0x58, 0x00, 0x00,
-+ 0x20, 0xfc, 0x28, 0x24, 0xfc, 0x20, 0xe8, 0xa8,
-+ 0xe8, 0x50, 0xd4, 0x9c, 0xec, 0x44, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x00, 0x1f, 0x10, 0x1f, 0x19,
-+ 0x1f, 0x18, 0x1f, 0x29, 0x2f, 0x48, 0x00, 0x00,
-+ 0x40, 0xfc, 0x50, 0x48, 0xfc, 0x40, 0xc8, 0x28,
-+ 0xa8, 0xb0, 0x90, 0x34, 0xcc, 0x84, 0x00, 0x00,
-+ 0x01, 0x3c, 0x25, 0x25, 0x3d, 0x25, 0x3d, 0x24,
-+ 0x25, 0x3d, 0x19, 0x15, 0x25, 0x41, 0x00, 0x00,
-+ 0x10, 0xa0, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x00,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x22, 0x12, 0x13, 0x04, 0x0f, 0x70, 0x13,
-+ 0x12, 0x12, 0x13, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0xf0,
-+ 0x10, 0x10, 0xf0, 0x10, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x12, 0x13, 0x32, 0x50, 0x12,
-+ 0x12, 0x12, 0x12, 0x13, 0x14, 0x18, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x48, 0x40, 0x40,
-+ 0x78, 0x40, 0x40, 0x40, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x08, 0x0f, 0x0c, 0x14, 0x17, 0x34, 0x54, 0x17,
-+ 0x14, 0x14, 0x17, 0x13, 0x14, 0x18, 0x00, 0x00,
-+ 0x08, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0x08, 0x88, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x3e, 0x22,
-+ 0x22, 0x3e, 0x14, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x22, 0x3e,
-+ 0x28, 0x24, 0x26, 0x3a, 0x62, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0xf0, 0x80, 0x80, 0x00, 0x00,
-+ 0x01, 0x02, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08,
-+ 0x0f, 0x01, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20,
-+ 0xe0, 0x00, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x12, 0x13, 0x10, 0x16,
-+ 0x1a, 0x72, 0x12, 0x13, 0x14, 0x38, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x40, 0x40,
-+ 0x78, 0x40, 0x40, 0x40, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x1f, 0x11, 0x11, 0x1f,
-+ 0x13, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x90, 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00, 0x00,
-+ 0x20, 0x17, 0x14, 0x44, 0x27, 0x24, 0x07, 0x14,
-+ 0x14, 0x17, 0x23, 0x22, 0x44, 0x48, 0x00, 0x00,
-+ 0x08, 0x88, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0x08, 0x88, 0x88, 0x18, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x11, 0x01, 0x11,
-+ 0x11, 0x11, 0x19, 0x15, 0x23, 0x40, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0xf0, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x20, 0x17, 0x10, 0x03, 0x02, 0x72, 0x13,
-+ 0x10, 0x11, 0x16, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0xe0, 0x50, 0x4c, 0x40, 0x00, 0xfc, 0x00, 0x00,
-+ 0x09, 0x09, 0x0a, 0x14, 0x10, 0x31, 0x51, 0x12,
-+ 0x17, 0x1a, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x20, 0x10, 0x08, 0x88, 0x80, 0x40, 0x20, 0x10,
-+ 0xf8, 0x14, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x17, 0x14,
-+ 0x17, 0x1f, 0x18, 0x2f, 0x28, 0x48, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x78, 0x80, 0xf0, 0x90,
-+ 0xf0, 0xf8, 0xa8, 0xf8, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x27, 0x3c, 0x24, 0x3c, 0x27,
-+ 0x24, 0x3c, 0x18, 0x14, 0x24, 0x40, 0x00, 0x00,
-+ 0x20, 0x28, 0x24, 0xfc, 0x20, 0xa8, 0xa8, 0xe8,
-+ 0x90, 0x90, 0xb4, 0xac, 0xcc, 0x84, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x12, 0x10, 0x1d, 0x16,
-+ 0x17, 0x14, 0x24, 0x24, 0x45, 0x1a, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x80, 0xf8, 0x20, 0x20,
-+ 0xfc, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x72, 0x14, 0x0c, 0x13, 0x7f,
-+ 0x09, 0x2c, 0x2a, 0x2a, 0x48, 0x09, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0x00, 0xfc, 0x08,
-+ 0x50, 0x50, 0x50, 0x94, 0x94, 0x0c, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x08, 0x08, 0x0c, 0x12, 0x23,
-+ 0x01, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x40, 0x40, 0x60, 0x90, 0x10,
-+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x09, 0x0b, 0x13, 0x3d,
-+ 0x55, 0x13, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0xf8, 0x48, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x04, 0x3f, 0x04, 0x07, 0x04, 0x07, 0x04,
-+ 0x04, 0x7f, 0x00, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xc0, 0x40, 0xc0, 0x40,
-+ 0x40, 0xfc, 0x00, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x12, 0x11, 0x11, 0x7f, 0x10, 0x17, 0x14, 0x17,
-+ 0x1c, 0x77, 0x14, 0x14, 0x14, 0x35, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xfc, 0x00, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x7f, 0x04, 0x05, 0x08, 0x18,
-+ 0x28, 0x4f, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0xf8, 0x10, 0x20,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x7c, 0x07, 0x08, 0x0b, 0x10, 0x10, 0x1b,
-+ 0x70, 0x11, 0x11, 0x12, 0x14, 0x30, 0x00, 0x00,
-+ 0x08, 0x30, 0xe0, 0x50, 0x90, 0xa0, 0x48, 0xf4,
-+ 0x44, 0x50, 0x48, 0x44, 0x44, 0x40, 0x00, 0x00,
-+ 0x08, 0x04, 0x7f, 0x02, 0x1f, 0x12, 0x14, 0x1f,
-+ 0x1f, 0x00, 0x7f, 0x08, 0x04, 0x00, 0x00, 0x00,
-+ 0x20, 0x40, 0xfc, 0x80, 0xf0, 0xd0, 0x50, 0xf0,
-+ 0xf0, 0x40, 0xfc, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x10, 0x13, 0x12, 0x1f,
-+ 0x72, 0x13, 0x12, 0x13, 0x11, 0x36, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0xf8, 0x98, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x18, 0x1c, 0x1a,
-+ 0x2a, 0x28, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0xfc, 0x10, 0x10, 0x90, 0x50,
-+ 0x50, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x2f, 0x11, 0x12, 0x02, 0x03, 0x0e, 0x72,
-+ 0x12, 0x12, 0x13, 0x1e, 0x26, 0x41, 0x00, 0x00,
-+ 0x0c, 0xf0, 0x28, 0x48, 0xd0, 0x30, 0x48, 0xfc,
-+ 0xa8, 0xa4, 0x24, 0x20, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x12, 0x12, 0x33, 0x5e, 0x12,
-+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x48, 0x78, 0xc8, 0x48, 0x48,
-+ 0x48, 0x58, 0x40, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x02, 0x03, 0x04, 0x0a, 0x31, 0x01, 0x06, 0x38,
-+ 0x03, 0x0c, 0x00, 0x00, 0x07, 0x38, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x40, 0x80, 0x40, 0x7c, 0x84,
-+ 0x88, 0x50, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x7f, 0x01, 0x02, 0x02,
-+ 0x04, 0x04, 0x0a, 0x11, 0x21, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x80, 0x80,
-+ 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x40, 0x27, 0x20, 0x00, 0x10,
-+ 0x10, 0x11, 0x21, 0x22, 0x44, 0x48, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0xc0,
-+ 0xa0, 0x20, 0x90, 0x50, 0x48, 0x04, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7f, 0x01, 0x3e, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x20, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x08, 0x80, 0x80, 0x98,
-+ 0xe0, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x03, 0x78, 0x4b, 0x49, 0x49, 0x4f, 0x49,
-+ 0x49, 0x7b, 0x48, 0x40, 0x0f, 0x00, 0x00, 0x00,
-+ 0x18, 0xe0, 0x40, 0xf8, 0x50, 0x50, 0xfc, 0x50,
-+ 0x50, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x48, 0x71, 0x53, 0x4d, 0x49, 0x71,
-+ 0x41, 0x41, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x80, 0xfc, 0x80, 0xf8, 0x08, 0xf8, 0x08, 0xf8,
-+ 0x08, 0x18, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x3f, 0x12, 0x09, 0x08, 0x01, 0x7f,
-+ 0x02, 0x04, 0x07, 0x08, 0x03, 0x3c, 0x00, 0x00,
-+ 0x18, 0xe8, 0x08, 0x10, 0x20, 0x40, 0x00, 0xfc,
-+ 0x20, 0x20, 0x40, 0xc0, 0x30, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x19, 0x36, 0x37, 0x30, 0x51,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0xfc, 0x80, 0xf8, 0x20, 0xfc, 0x00, 0xf8,
-+ 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x7e, 0x08, 0x08, 0x08, 0x0e,
-+ 0x78, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7f, 0x0a, 0x18, 0x18, 0x1c,
-+ 0x2a, 0x2a, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0x80, 0x80, 0x88, 0x90,
-+ 0xe0, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x04, 0x08, 0x1e, 0x12, 0x1b, 0x16, 0x16, 0x7f,
-+ 0x12, 0x1a, 0x1a, 0x2a, 0x22, 0x46, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x40, 0x40, 0x48, 0x50,
-+ 0x60, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x7f, 0x09, 0x1b, 0x1c, 0x1b,
-+ 0x2b, 0x2b, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x40, 0xfc, 0x80, 0xf8, 0x20, 0xfc, 0x00, 0xf8,
-+ 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x29, 0x29, 0x32, 0x28, 0x24,
-+ 0x24, 0x24, 0x24, 0x38, 0x20, 0x20, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x08, 0x80, 0x80, 0x98,
-+ 0xe0, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x29, 0x3e, 0x28, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x45, 0x1a, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0x70,
-+ 0x50, 0x50, 0xc8, 0xa8, 0x24, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3e, 0x28, 0x3e,
-+ 0x0a, 0x3e, 0x3f, 0x32, 0x42, 0x0c, 0x00, 0x00,
-+ 0x44, 0x24, 0xa8, 0x90, 0xf8, 0xa8, 0xf8, 0xa8,
-+ 0xf8, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x10, 0x17, 0x30, 0x50, 0x11,
-+ 0x11, 0x12, 0x15, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xe0, 0xe0, 0x50,
-+ 0x50, 0x48, 0xf4, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x13, 0x7f, 0x15, 0x11, 0x11,
-+ 0x15, 0x19, 0x61, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x04, 0x04, 0x24, 0x14,
-+ 0x0c, 0x0c, 0x0a, 0x12, 0x20, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0xfc, 0x10, 0x10, 0x90, 0x50,
-+ 0x50, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x7f, 0x08, 0x10, 0x7f, 0x55, 0x55, 0x55,
-+ 0x55, 0x55, 0x55, 0x55, 0x55, 0x43, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0xfc, 0x08, 0x48, 0x28,
-+ 0x28, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x10, 0x17, 0x30, 0x50, 0x10, 0x11,
-+ 0x01, 0x11, 0x11, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x90, 0x88, 0xfc, 0xc0, 0x40, 0x24, 0x14, 0x0c,
-+ 0x00, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x09, 0x09, 0x7f, 0x09, 0x0f, 0x00, 0x3f, 0x21,
-+ 0x5f, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xe0, 0x00, 0xfc, 0x08,
-+ 0xf0, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x13, 0x24, 0x04, 0x0f, 0x18, 0x28,
-+ 0x4f, 0x09, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x10, 0x10,
-+ 0xfc, 0x10, 0x90, 0x90, 0x10, 0x30, 0x00, 0x00,
-+ 0x02, 0x02, 0x04, 0x7f, 0x00, 0x0f, 0x08, 0x08,
-+ 0x0f, 0x01, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x40, 0x30, 0xe8, 0x04, 0xe0, 0x20, 0x20,
-+ 0xe0, 0x00, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x08, 0x12, 0x7f, 0x3e, 0x22, 0x3e, 0x3e, 0x22,
-+ 0x26, 0x01, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x40, 0x48, 0x70, 0x44, 0x3c, 0x48, 0x70, 0x44,
-+ 0x3c, 0x10, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x04, 0x1f, 0x04, 0x7f, 0x1f, 0x15, 0x1f, 0x15,
-+ 0x1f, 0x3f, 0x0a, 0x7f, 0x19, 0x60, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0xfc, 0x40, 0x48, 0x48, 0x28,
-+ 0x28, 0xb0, 0x14, 0xac, 0x4c, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x3e, 0x08, 0x7f, 0x14, 0x12, 0x22,
-+ 0x4f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x20, 0xfc, 0x30, 0x50, 0x88,
-+ 0xe4, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x01, 0x0f, 0x02, 0x7f, 0x05,
-+ 0x19, 0x6d, 0x03, 0x0d, 0x31, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xe0, 0x80, 0xfc, 0x40,
-+ 0x30, 0x6c, 0x80, 0x60, 0x18, 0x00, 0x00, 0x00,
-+ 0x11, 0x09, 0x0f, 0x41, 0x21, 0x20, 0x07, 0x04,
-+ 0x1b, 0x12, 0x22, 0x22, 0x42, 0x40, 0x00, 0x00,
-+ 0x50, 0x50, 0xfc, 0x50, 0xf0, 0x00, 0xfc, 0x48,
-+ 0xf8, 0x48, 0x48, 0x48, 0x70, 0x40, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x27, 0x3c,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x4d, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x50, 0x88, 0x9c, 0xe4, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3e, 0x25, 0x25, 0x24, 0x3c, 0x24, 0x27,
-+ 0x3d, 0x25, 0x25, 0x25, 0x26, 0x4c, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0x78, 0x48, 0x78, 0x64,
-+ 0x58, 0x50, 0x68, 0x84, 0x80, 0x7c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x01, 0x02, 0x04, 0x7f,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0x40, 0x30, 0xc8,
-+ 0x04, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x02, 0x04, 0x18, 0x6f, 0x08, 0x09, 0x09, 0x7f,
-+ 0x03, 0x0c, 0x74, 0x04, 0x07, 0x38, 0x00, 0x00,
-+ 0x90, 0x88, 0x7c, 0xc0, 0x20, 0x14, 0x0c, 0xfc,
-+ 0x10, 0x90, 0xa0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x02, 0x04, 0x1b, 0x68, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x90, 0x88, 0xfc, 0x40, 0x34, 0xec, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x00, 0x23, 0x12, 0x13, 0x02, 0x03, 0x72, 0x12,
-+ 0x12, 0x12, 0x1f, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x88, 0x48,
-+ 0x30, 0xd0, 0x08, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x23, 0x10, 0x17, 0x00, 0x03, 0x74, 0x12,
-+ 0x12, 0x11, 0x16, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8, 0x48, 0x50,
-+ 0xe0, 0x50, 0x48, 0xc8, 0x00, 0xfc, 0x00, 0x00,
-+ 0x01, 0x3c, 0x24, 0x2b, 0x28, 0x30, 0x2b, 0x24,
-+ 0x27, 0x24, 0x38, 0x23, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xfc, 0x40, 0xe8, 0x68, 0xb0,
-+ 0x30, 0x70, 0xa8, 0x24, 0x20, 0xc0, 0x00, 0x00,
-+ 0x02, 0x04, 0x1f, 0x68, 0x08, 0x1f, 0x11, 0x1f,
-+ 0x1f, 0x3f, 0x01, 0x7f, 0x24, 0x42, 0x00, 0x00,
-+ 0x90, 0xbc, 0xc0, 0x24, 0x1c, 0xf4, 0x10, 0xf0,
-+ 0xf0, 0xf8, 0x00, 0xfc, 0x88, 0x44, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2f, 0x29, 0x42, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xf8, 0xa8, 0xf8, 0x88,
-+ 0xf8, 0xd8, 0xf8, 0x58, 0x08, 0x18, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x08, 0x08, 0x1f, 0x28, 0x48,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x90, 0x88, 0x88, 0x80, 0xfc, 0x40, 0x40, 0x40,
-+ 0x20, 0x20, 0x14, 0x14, 0x0c, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x04, 0x08, 0x7f, 0x00, 0x00,
-+ 0x1f, 0x10, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x40, 0x30, 0xc8, 0x04, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x01, 0x02,
-+ 0x02, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x80,
-+ 0x80, 0x40, 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x29, 0x46, 0x3f, 0x01, 0x3f,
-+ 0x21, 0x3f, 0x23, 0x05, 0x19, 0x61, 0x00, 0x00,
-+ 0x80, 0x80, 0xf8, 0x20, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x00, 0xf8, 0x08, 0x08, 0x30, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x2f,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x78, 0x48, 0x78, 0x00, 0xfc,
-+ 0x10, 0x50, 0x5c, 0x50, 0xb0, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x3e, 0x22, 0x3e, 0x00, 0x7f,
-+ 0x08, 0x2e, 0x28, 0x38, 0x2d, 0x43, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xf8, 0x88, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x50, 0x88, 0x08, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x15, 0x1f, 0x15, 0x15, 0x13,
-+ 0x13, 0x13, 0x23, 0x23, 0x4d, 0x12, 0x00, 0x00,
-+ 0x80, 0xfc, 0xa0, 0xfc, 0xf0, 0xf0, 0xfc, 0xe0,
-+ 0xe0, 0xe0, 0xf8, 0xf8, 0x48, 0xb0, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x42, 0x21, 0x2f, 0x00, 0x17,
-+ 0x14, 0x17, 0x24, 0x27, 0x44, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xf8, 0x20, 0x40, 0xfc, 0x00, 0xf0,
-+ 0x90, 0xf0, 0x90, 0xf4, 0x84, 0x7c, 0x00, 0x00,
-+ 0x22, 0x12, 0x1f, 0x45, 0x25, 0x3f, 0x00, 0x0f,
-+ 0x19, 0x1f, 0x29, 0x2f, 0x49, 0x4b, 0x00, 0x00,
-+ 0x40, 0x78, 0xc0, 0x78, 0x08, 0xf8, 0x40, 0x78,
-+ 0x40, 0x78, 0x40, 0x78, 0x44, 0x3c, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x1f, 0x10, 0x1f, 0x10,
-+ 0x1f, 0x01, 0x7f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x48, 0x49, 0x4e, 0x48, 0x49,
-+ 0x7e, 0x48, 0x43, 0x0c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x88, 0xc8, 0x50, 0xe0, 0x20,
-+ 0x70, 0xa8, 0x24, 0x20, 0x20, 0xc0, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x40, 0x01, 0x1e, 0x02,
-+ 0x03, 0x7e, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x60, 0x80, 0x00, 0x00,
-+ 0xfc, 0x00, 0x00, 0x08, 0x08, 0xf8, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7e, 0x08, 0x08, 0x08, 0x0f,
-+ 0x18, 0x68, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x40, 0x40, 0x40, 0x7c, 0xc0,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x11, 0x11, 0x11, 0x1d,
-+ 0x71, 0x11, 0x12, 0x12, 0x14, 0x38, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x48, 0x40,
-+ 0x20, 0x20, 0x10, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x10, 0x10, 0x11, 0x13,
-+ 0x1d, 0x79, 0x11, 0x11, 0x11, 0x31, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x80, 0x80, 0xf8, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x22, 0x23, 0x02, 0x12,
-+ 0x12, 0x12, 0x24, 0x24, 0x48, 0x50, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x48, 0x40,
-+ 0x40, 0x20, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x20, 0x17, 0x10, 0x47, 0x20, 0x27, 0x02, 0x13,
-+ 0x16, 0x1b, 0x23, 0x22, 0x43, 0x42, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x20, 0xf8,
-+ 0x40, 0xf0, 0xf0, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x7c, 0x10, 0x11, 0x16, 0x7c, 0x11,
-+ 0x16, 0x10, 0x1b, 0x6c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x80, 0xc8, 0x48, 0xf0, 0x20,
-+ 0x70, 0xa8, 0x24, 0x20, 0x20, 0xc0, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7e, 0x00, 0x3c, 0x00, 0x3d,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x20, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x40, 0x40, 0x40, 0x7c, 0xc0,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x09, 0x15, 0x13, 0x22, 0x5c, 0x08, 0x7f,
-+ 0x08, 0x2b, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x00, 0xfc, 0x54, 0xfc, 0x20, 0xf8, 0x20, 0xfc,
-+ 0x50, 0xfc, 0x20, 0xf8, 0x20, 0x20, 0x00, 0x00,
-+ 0x20, 0x17, 0x15, 0x47, 0x22, 0x23, 0x05, 0x1f,
-+ 0x15, 0x17, 0x25, 0x21, 0x4e, 0x40, 0x00, 0x00,
-+ 0x00, 0xf0, 0x50, 0xf0, 0x00, 0xf8, 0x08, 0xc8,
-+ 0x48, 0xc8, 0x48, 0xe8, 0x28, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7e, 0x00, 0x3f, 0x00, 0x3c,
-+ 0x00, 0x3d, 0x26, 0x24, 0x3c, 0x20, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0xd0, 0x40, 0xfc, 0x40, 0x80,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x7f, 0x08, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x78, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xfc, 0x20, 0xe0, 0x20,
-+ 0xe0, 0x38, 0xe0, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x11, 0x17, 0x15, 0x15, 0x15,
-+ 0x15, 0x15, 0x15, 0x21, 0x21, 0x41, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xd0, 0x50, 0x50, 0x50,
-+ 0x50, 0x50, 0xd4, 0x0c, 0x0c, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x28, 0x0c, 0x0a, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x20, 0x24, 0xa4, 0xa8, 0x20, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x1f,
-+ 0x10, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0x10, 0x10, 0xf0,
-+ 0x10, 0x40, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x44, 0x44, 0x44, 0x44, 0x44,
-+ 0x7c, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0xf0, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x12, 0x12, 0x33, 0x52, 0x12,
-+ 0x12, 0x13, 0x12, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0x10, 0xf0, 0x10, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x23, 0x10, 0x17, 0x01, 0x00, 0x77, 0x10,
-+ 0x13, 0x10, 0x17, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xfc, 0x10, 0xa0, 0xfc, 0x40,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x17, 0x10, 0x10, 0x1f, 0x12,
-+ 0x12, 0x12, 0x22, 0x22, 0x43, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x88,
-+ 0x48, 0x50, 0x20, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x02, 0x7f, 0x06, 0x1a, 0x67, 0x0c, 0x17, 0x07,
-+ 0x04, 0x07, 0x7f, 0x04, 0x02, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xb0, 0xfc, 0x80, 0xe0, 0xe0,
-+ 0x80, 0xf0, 0xfc, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x01, 0x3c, 0x24, 0x25, 0x25, 0x3d, 0x25, 0x25,
-+ 0x3c, 0x24, 0x24, 0x24, 0x25, 0x4e, 0x00, 0x00,
-+ 0x08, 0x88, 0x90, 0xf8, 0x08, 0x08, 0xf8, 0x68,
-+ 0x60, 0x60, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3e, 0x02, 0x3e, 0x20, 0x22, 0x1e, 0x04,
-+ 0x3f, 0x04, 0x7f, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x80, 0x88, 0x78, 0x40,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3e, 0x22, 0x3e, 0x24, 0x3f,
-+ 0x01, 0x3f, 0x08, 0x04, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x30, 0x30, 0xc8, 0x04,
-+ 0x00, 0xf8, 0x20, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x20, 0x12, 0x12, 0x02, 0x02, 0x72, 0x12,
-+ 0x12, 0x13, 0x12, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0xf8, 0x08, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x12, 0x13, 0x3a, 0x36,
-+ 0x37, 0x52, 0x52, 0x14, 0x14, 0x19, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xa8, 0xa8, 0xb8, 0xa8, 0xa8,
-+ 0xb8, 0xa8, 0xa8, 0xc8, 0xc8, 0x98, 0x00, 0x00,
-+ 0x04, 0x04, 0x08, 0x11, 0x01, 0x02, 0x04, 0x18,
-+ 0x6f, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0x20, 0x10, 0x10, 0x00, 0x80, 0x40, 0x30,
-+ 0xec, 0x20, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x08, 0x4b, 0x32, 0x12, 0x33, 0x4a, 0x0a, 0x1b,
-+ 0x28, 0x4b, 0x08, 0x08, 0x3f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x25, 0x7f, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3b, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0xfc, 0x24, 0xf8, 0xf8, 0x20,
-+ 0xf8, 0x08, 0xfc, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x11, 0x10, 0x17, 0x78, 0x13, 0x1a, 0x37, 0x37,
-+ 0x33, 0x50, 0x57, 0x11, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0xa0, 0xfc, 0xa0, 0xf8, 0xb8, 0x18, 0xf8,
-+ 0xf8, 0x10, 0xfc, 0x10, 0x90, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7f, 0x01, 0x3f, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x21, 0x00, 0x00,
-+ 0x90, 0x90, 0xa0, 0xfc, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0a, 0x09, 0x09, 0x08, 0x7f,
-+ 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0x20, 0x20, 0x20, 0xfc,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x12, 0x09, 0x09, 0x1f, 0x11, 0x1f, 0x11, 0x11,
-+ 0x1f, 0x01, 0x7f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xf0, 0x10, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x49, 0x4b, 0x4a, 0x4b, 0x48,
-+ 0x4b, 0x78, 0x4f, 0x40, 0x03, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0xf8, 0x48, 0xf8, 0x40,
-+ 0xf8, 0x40, 0xfc, 0xa0, 0x18, 0x04, 0x00, 0x00,
-+ 0x00, 0x11, 0x11, 0x11, 0x7d, 0x11, 0x11, 0x11,
-+ 0x15, 0x19, 0x61, 0x00, 0x0f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0x10, 0xf0, 0x10, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x11, 0x11, 0x11, 0x15,
-+ 0x19, 0x71, 0x11, 0x10, 0x17, 0x30, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0x10, 0xf0, 0x10, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7c, 0x11, 0x12, 0x10, 0x1f,
-+ 0x70, 0x11, 0x12, 0x14, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa8, 0xa0, 0x24, 0x5c, 0x40, 0xfc,
-+ 0xe0, 0x50, 0x48, 0x44, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08,
-+ 0x08, 0x0f, 0x08, 0x00, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0x20, 0xe0, 0x20, 0x20,
-+ 0x20, 0xe0, 0x20, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x14, 0x14, 0x7f, 0x14, 0x3e, 0x2b, 0x3e, 0x08,
-+ 0x3e, 0x08, 0x7f, 0x14, 0x23, 0x42, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0xa4, 0x28, 0x30, 0x20,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x08, 0x0a, 0x42, 0x24, 0x21, 0x06, 0x10,
-+ 0x12, 0x12, 0x24, 0x21, 0x42, 0x4c, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0xd0, 0xa0, 0x18, 0x44, 0x48,
-+ 0x48, 0xd0, 0xa0, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x11, 0x0f, 0x09, 0x41, 0x21, 0x21, 0x01, 0x1f,
-+ 0x14, 0x14, 0x25, 0x26, 0x47, 0x44, 0x00, 0x00,
-+ 0x10, 0xfc, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0xfc,
-+ 0xa0, 0xa4, 0x1c, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x1f, 0x00, 0x1f, 0x10, 0x10,
-+ 0x14, 0x15, 0x29, 0x22, 0x44, 0x18, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0xf0, 0x00, 0xfc, 0x80, 0x88,
-+ 0x88, 0x50, 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x3f, 0x29, 0x49, 0x09, 0x7f,
-+ 0x09, 0x08, 0x14, 0x12, 0x23, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08,
-+ 0x08, 0x90, 0x90, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x12, 0x12, 0x13, 0x7c, 0x0b, 0x48, 0x2b,
-+ 0x2a, 0x32, 0x1e, 0x72, 0x02, 0x02, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0xf8, 0x00, 0xfc, 0x40, 0xf8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x12, 0x09, 0x1f, 0x11,
-+ 0x1f, 0x11, 0x1f, 0x01, 0x7f, 0x01, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0x10, 0x20, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x15, 0x0d, 0x12, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2b, 0x49, 0x0a, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x00, 0xfc, 0x20, 0xa0,
-+ 0xb8, 0xa0, 0xa0, 0x60, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7e, 0x24, 0x25, 0x3d, 0x26, 0x24, 0x3c,
-+ 0x24, 0x26, 0x3c, 0x64, 0x05, 0x06, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x48, 0x40, 0x40, 0x60,
-+ 0x60, 0x60, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x3d, 0x25, 0x25, 0x3d,
-+ 0x25, 0x25, 0x25, 0x24, 0x27, 0x4c, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0x10, 0xf0, 0x10, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x09, 0x09, 0x1d, 0x23, 0x41, 0x0f,
-+ 0x09, 0x09, 0x0f, 0x09, 0x01, 0x3e, 0x00, 0x00,
-+ 0x00, 0xf8, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0xe0,
-+ 0x20, 0x20, 0xe0, 0x20, 0xf0, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x7d, 0x02, 0x3a, 0x07, 0x39,
-+ 0x05, 0x3b, 0x2a, 0x2b, 0x3c, 0x28, 0x00, 0x00,
-+ 0x00, 0x0c, 0xf0, 0x10, 0x50, 0x50, 0x5c, 0x50,
-+ 0x50, 0x50, 0xfc, 0x00, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x13, 0x23, 0x5d, 0x09, 0x7f,
-+ 0x09, 0x2b, 0x1d, 0x1b, 0x0d, 0x71, 0x00, 0x00,
-+ 0x40, 0xb8, 0x28, 0x28, 0xe8, 0x4c, 0x04, 0xf8,
-+ 0x48, 0x28, 0xf0, 0x10, 0x28, 0xc4, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x20, 0x3f, 0x20, 0x24, 0x22,
-+ 0x22, 0x20, 0x20, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x17, 0x13, 0x12, 0x7e, 0x12, 0x13, 0x11,
-+ 0x15, 0x19, 0x61, 0x01, 0x00, 0x0f, 0x00, 0x00,
-+ 0x40, 0xfc, 0xf8, 0xe8, 0xa8, 0xe8, 0xf8, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x7a, 0x09, 0x0b, 0x7a, 0x4b, 0x42, 0x7b,
-+ 0x48, 0x4f, 0x08, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x88, 0x48, 0x10, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x04, 0x04, 0x65, 0x55, 0x56, 0x44, 0x7f, 0x4c,
-+ 0x4e, 0x55, 0x65, 0x44, 0x7f, 0x40, 0x00, 0x00,
-+ 0x08, 0x10, 0x60, 0x40, 0x40, 0x7c, 0xc8, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x07, 0x7a, 0x49, 0x4b, 0x48, 0x7f, 0x48,
-+ 0x49, 0x49, 0x7a, 0x4c, 0x09, 0x16, 0x00, 0x00,
-+ 0x1c, 0xe4, 0x48, 0x30, 0xf8, 0x80, 0xfc, 0x80,
-+ 0xf0, 0x10, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x10, 0x17, 0x13, 0x7e, 0x12, 0x12, 0x3b, 0x35,
-+ 0x35, 0x51, 0x51, 0x11, 0x10, 0x17, 0x00, 0x00,
-+ 0x40, 0xfc, 0xf8, 0xe8, 0xa8, 0xe8, 0xf8, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0x00,
-+ 0x06, 0x38, 0x20, 0x20, 0x3c, 0x21, 0x22, 0x3d,
-+ 0x20, 0x20, 0x3c, 0x60, 0x20, 0x23, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0x94, 0x14, 0x0c, 0xf8,
-+ 0x88, 0x90, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x1f,
-+ 0x01, 0x7f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x70, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x01, 0x3c, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x25, 0x24, 0x3c, 0x27, 0x00, 0x00,
-+ 0x20, 0x28, 0xa8, 0xb0, 0x20, 0x50, 0x88, 0x24,
-+ 0xa4, 0xa8, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x10, 0x15, 0x35, 0x55, 0x15,
-+ 0x15, 0x15, 0x15, 0x14, 0x17, 0x14, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x3f, 0x28, 0x48, 0x08, 0x7f,
-+ 0x08, 0x0c, 0x14, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00, 0x00,
-+ 0x00, 0x12, 0x12, 0x12, 0x7e, 0x13, 0x16, 0x12,
-+ 0x12, 0x16, 0x1a, 0x62, 0x02, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x48, 0x78, 0xc8, 0x48, 0x48,
-+ 0x48, 0x70, 0x40, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x7c, 0x04, 0x04, 0x3c, 0x24, 0x23, 0x3c,
-+ 0x24, 0x24, 0x04, 0x04, 0x08, 0x30, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xa8, 0xb8, 0xe8, 0xa8, 0xa8,
-+ 0xa8, 0xb8, 0xa0, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x7e, 0x24, 0x24, 0x3c, 0x24, 0x25, 0x3d,
-+ 0x25, 0x26, 0x3e, 0x64, 0x04, 0x04, 0x00, 0x00,
-+ 0x20, 0x10, 0x10, 0x40, 0x40, 0x40, 0x48, 0x44,
-+ 0x44, 0x44, 0x40, 0x48, 0x48, 0x38, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x24, 0x7f, 0x0c, 0x0a, 0x12,
-+ 0x2f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x10, 0x0a, 0x0a, 0x42, 0x22, 0x23, 0x0e, 0x02,
-+ 0x0a, 0x0a, 0x12, 0x12, 0x22, 0x21, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x48, 0x78, 0xc8, 0x48, 0x48,
-+ 0x48, 0x70, 0x40, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x4a, 0x2a, 0x2b, 0x0d, 0x19,
-+ 0x2f, 0x49, 0x11, 0x12, 0x24, 0x48, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x00, 0xf8, 0x28, 0x28,
-+ 0xe8, 0x28, 0x28, 0xb8, 0xa8, 0x00, 0x00, 0x00,
-+ 0x02, 0x0c, 0x38, 0x09, 0x0b, 0x7f, 0x09, 0x1d,
-+ 0x1b, 0x2b, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x90, 0x90, 0xa0, 0xfc, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x00, 0x7f, 0x07, 0x24,
-+ 0x27, 0x27, 0x24, 0x27, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x80, 0xfc, 0xe0, 0x20,
-+ 0xe0, 0xe0, 0x20, 0xe0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x10, 0x14, 0x23, 0x7f, 0x0a, 0x08,
-+ 0x3e, 0x08, 0x08, 0x0e, 0x71, 0x06, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x10, 0x90, 0x90, 0x50,
-+ 0x60, 0x20, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7d, 0x56, 0x56, 0x54, 0x7f,
-+ 0x50, 0x18, 0x15, 0x1f, 0x62, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x38, 0xe8, 0xa8, 0xa8, 0xa8, 0xe8,
-+ 0xa8, 0xa8, 0x68, 0x78, 0x28, 0x00, 0x00, 0x00,
-+ 0x00, 0x27, 0x14, 0x17, 0x05, 0x04, 0x77, 0x14,
-+ 0x15, 0x14, 0x1b, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x10, 0xa0, 0xf8, 0x40,
-+ 0xf0, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3f, 0x28, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x42, 0x0c, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa8, 0xb8, 0xe8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xb8, 0xa0, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x7e, 0x08, 0x0e, 0x71,
-+ 0x01, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x40, 0xfc, 0xa0, 0x10, 0xf0, 0x90, 0xd4, 0x2c,
-+ 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x02, 0x1c, 0x05, 0x03, 0x7e,
-+ 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x40, 0xc0, 0x20, 0xf0, 0x08,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x1f, 0x14, 0x25, 0x44,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x90, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x14, 0x23, 0x42, 0x7f, 0x11,
-+ 0x11, 0x11, 0x1e, 0x72, 0x04, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0x10, 0xf0, 0x10,
-+ 0x90, 0x50, 0x50, 0x14, 0x14, 0x0c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x7f, 0x02, 0x0c, 0x03, 0x7f,
-+ 0x0f, 0x09, 0x0f, 0x09, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x40, 0xc0, 0x30, 0xc8,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x27, 0x10, 0x11, 0x0e, 0x01, 0x76, 0x10,
-+ 0x13, 0x1c, 0x10, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x88, 0xc8, 0x50, 0x60, 0xd0,
-+ 0x48, 0x44, 0x44, 0x80, 0x00, 0xfc, 0x00, 0x00,
-+ 0x02, 0x04, 0x38, 0x08, 0x08, 0x7e, 0x09, 0x1d,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x20, 0x20, 0xa0, 0xa0, 0xf8, 0xa0, 0x20, 0xfc,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x01, 0x3f, 0x24, 0x44, 0x08, 0x3f, 0x02, 0x04,
-+ 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0x90, 0x70, 0xf8, 0x40, 0x70,
-+ 0x88, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x02, 0x04, 0x19, 0x61,
-+ 0x1f, 0x01, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x80, 0x40, 0x30, 0x0c,
-+ 0xf0, 0x00, 0x40, 0x30, 0x08, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x11, 0x78, 0x2b, 0x2a, 0x2b,
-+ 0x2a, 0x7a, 0x5a, 0x16, 0x22, 0x42, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0xa0, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xe8, 0xa8, 0xe8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x04, 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x0f, 0x0c,
-+ 0x17, 0x14, 0x27, 0x44, 0x07, 0x04, 0x00, 0x00,
-+ 0x40, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x3f, 0x21, 0x21, 0x21, 0x21,
-+ 0x3f, 0x21, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08,
-+ 0xf8, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x17, 0x14, 0x34, 0x54, 0x14,
-+ 0x17, 0x14, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x44, 0x44, 0x44, 0x44,
-+ 0xfc, 0x44, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x41, 0x01, 0x1f, 0x11,
-+ 0x11, 0x1f, 0x11, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x00, 0x00, 0xf0, 0x10,
-+ 0x10, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x11, 0x11, 0x11, 0x1f, 0x11,
-+ 0x01, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x13, 0x12, 0x12, 0x1e,
-+ 0x73, 0x12, 0x12, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0xf8, 0x48, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x08, 0x17, 0x14,
-+ 0x27, 0x44, 0x07, 0x00, 0x3f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x90, 0x40, 0xe0, 0x50,
-+ 0xc8, 0x44, 0xc0, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x18, 0x1c, 0x1b,
-+ 0x2a, 0x28, 0x48, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x80, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0xf8,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x47, 0x20, 0x20, 0x00, 0x13,
-+ 0x10, 0x10, 0x20, 0x20, 0x4f, 0x40, 0x00, 0x00,
-+ 0x80, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0xf8,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x1f, 0x11, 0x11, 0x11, 0x1f,
-+ 0x11, 0x01, 0x01, 0x01, 0x7e, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0,
-+ 0x10, 0x20, 0x10, 0xf8, 0x04, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x1f, 0x11, 0x1f, 0x11,
-+ 0x03, 0x0c, 0x74, 0x04, 0x07, 0x38, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x10,
-+ 0x08, 0xb0, 0xc0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7f, 0x00, 0x3c, 0x00, 0x3f,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3f, 0x20, 0x00, 0x00,
-+ 0x80, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0xf8,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x08, 0x88, 0x08, 0x08, 0xfc, 0x08, 0x48, 0x28,
-+ 0x28, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x12, 0x22, 0x5c, 0x09, 0x7e,
-+ 0x09, 0x2a, 0x1c, 0x19, 0x0e, 0x70, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x48,
-+ 0xfc, 0x48, 0xa8, 0x28, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3f, 0x28, 0x3e, 0x28, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x43, 0x0c, 0x00, 0x00,
-+ 0x40, 0x20, 0x20, 0xfc, 0x20, 0x20, 0x20, 0xf8,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7f, 0x17, 0x13, 0x39, 0x34,
-+ 0x37, 0x50, 0x50, 0x11, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xfc, 0x58, 0x58, 0xf0, 0x00,
-+ 0xfc, 0x80, 0xf0, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x20, 0x1f, 0x12, 0x42, 0x26, 0x2a, 0x03, 0x17,
-+ 0x1b, 0x22, 0x26, 0x5a, 0x42, 0x4c, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x28, 0xb0, 0xfc, 0x20, 0x78,
-+ 0xc8, 0xf8, 0xc8, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x04, 0x44, 0x2b, 0x10, 0x30, 0x4f, 0x08, 0x19,
-+ 0x2b, 0x4d, 0x09, 0x09, 0x31, 0x11, 0x00, 0x00,
-+ 0x80, 0x88, 0xf8, 0x90, 0xa0, 0xfc, 0x80, 0xf8,
-+ 0x08, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x01, 0x3f, 0x20, 0x40,
-+ 0x7f, 0x01, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xfc, 0x08, 0x00,
-+ 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x7f, 0x09, 0x01, 0x1f, 0x01, 0x7f, 0x01,
-+ 0x07, 0x1c, 0x67, 0x04, 0x07, 0x04, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0x08, 0xf0, 0x20, 0xfc, 0x00,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x25, 0x3e, 0x24, 0x3d, 0x24,
-+ 0x24, 0x3c, 0x18, 0x14, 0x24, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0x00, 0x00, 0xfc, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x24, 0x14, 0x14, 0x04, 0x06,
-+ 0x0c, 0x78, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0x90, 0x90, 0xa0, 0xc0, 0x80, 0xa0,
-+ 0x90, 0x90, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x07, 0x44, 0x24, 0x27, 0x04, 0x17, 0x14,
-+ 0x25, 0x25, 0x45, 0x49, 0x08, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xe8, 0x88, 0xf8, 0x08,
-+ 0xe8, 0x28, 0xe8, 0x28, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x49, 0x49, 0x49, 0x49, 0x48,
-+ 0x4f, 0x78, 0x49, 0x46, 0x18, 0x00, 0x00, 0x00,
-+ 0x50, 0x50, 0xfc, 0x50, 0x70, 0x00, 0xf8, 0x40,
-+ 0xfc, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x01, 0x3f, 0x28, 0x7f, 0x14, 0x7f, 0x00, 0x3e,
-+ 0x22, 0x3e, 0x22, 0x3e, 0x22, 0x26, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0x78, 0x40, 0x78, 0x08, 0x78,
-+ 0x40, 0x78, 0x78, 0x7c, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x54, 0x54, 0x54, 0x55,
-+ 0x55, 0x5d, 0x51, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x55, 0x55, 0x55, 0x57,
-+ 0x55, 0x5d, 0x51, 0x11, 0x11, 0x16, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xfc,
-+ 0x48, 0x50, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x20, 0x20, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x00, 0xfc, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x3f, 0x02, 0x02, 0x3f, 0x22, 0x22, 0x3f,
-+ 0x22, 0x22, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0xf8,
-+ 0x08, 0x08, 0x08, 0x30, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x79, 0x09, 0x09, 0x79, 0x49, 0x41, 0x7f,
-+ 0x49, 0x49, 0x09, 0x09, 0x11, 0x66, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xfc,
-+ 0x48, 0x50, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x2e, 0x24, 0x3f, 0x20,
-+ 0x2e, 0x2a, 0x2a, 0x2e, 0x2a, 0x41, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xa0, 0xc8, 0x88, 0x90, 0x90,
-+ 0xa4, 0x84, 0x88, 0x88, 0x90, 0xa0, 0x00, 0x00,
-+ 0x12, 0x1a, 0x2a, 0x4a, 0x1f, 0x10, 0x2f, 0x62,
-+ 0x22, 0x2f, 0x22, 0x23, 0x2c, 0x20, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xa0, 0xfc, 0x48, 0xc8, 0x28,
-+ 0x28, 0xb0, 0x10, 0xb0, 0x48, 0x84, 0x00, 0x00,
-+ 0x22, 0x2a, 0x4f, 0x10, 0x3f, 0x52, 0x17, 0x13,
-+ 0x1c, 0x01, 0x14, 0x14, 0x24, 0x43, 0x00, 0x00,
-+ 0x20, 0xa0, 0xbc, 0x48, 0xa8, 0x28, 0x90, 0xb0,
-+ 0x48, 0x04, 0x90, 0x88, 0x24, 0xe4, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7e, 0x11, 0x11, 0x10, 0x1d,
-+ 0x72, 0x14, 0x11, 0x11, 0x12, 0x34, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xa8, 0xa8, 0xb0, 0xa0, 0xb0, 0xa8,
-+ 0xa4, 0xa4, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x55, 0x7d, 0x54, 0x7f,
-+ 0x55, 0x53, 0x14, 0x11, 0x12, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xf8, 0xa8, 0x28, 0x48, 0xb0, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x22, 0x3e, 0x22,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88,
-+ 0xf8, 0x88, 0x88, 0x88, 0x08, 0x18, 0x00, 0x00,
-+ 0x22, 0x12, 0x1f, 0x42, 0x2f, 0x29, 0x0f, 0x19,
-+ 0x1f, 0x22, 0x3f, 0x42, 0x42, 0x43, 0x00, 0x00,
-+ 0x00, 0x78, 0xc8, 0x48, 0x48, 0x78, 0x48, 0x48,
-+ 0x78, 0x48, 0xc8, 0x48, 0x88, 0x18, 0x00, 0x00,
-+ 0x29, 0x29, 0x2b, 0x29, 0x3d, 0x21, 0x21, 0x39,
-+ 0x28, 0x2f, 0x28, 0x29, 0x2e, 0x48, 0x00, 0x00,
-+ 0x50, 0x50, 0xfc, 0x50, 0x50, 0x70, 0x00, 0xf8,
-+ 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x24, 0x3f, 0x24, 0x24,
-+ 0x24, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0xfc, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x4a, 0x79, 0x49, 0x48, 0x79,
-+ 0x4e, 0x48, 0x79, 0x49, 0x42, 0x04, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xa8, 0xa8, 0xb0, 0xa0, 0xb0, 0xa8,
-+ 0xa4, 0xa4, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x7c, 0x2b, 0x28, 0x3b, 0x2a, 0x2a, 0x3b,
-+ 0x2a, 0x2c, 0x3a, 0x6a, 0x0c, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0xa8, 0xa8, 0xf8,
-+ 0x48, 0xa0, 0xa8, 0x84, 0x94, 0x70, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x24, 0x3f,
-+ 0x24, 0x24, 0x24, 0x24, 0x24, 0x4f, 0x00, 0x00,
-+ 0x00, 0xf8, 0x80, 0xf0, 0x80, 0xf0, 0x80, 0xfc,
-+ 0xc8, 0xa8, 0x90, 0xb0, 0xc8, 0x04, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x25, 0x3d, 0x24, 0x27,
-+ 0x3d, 0x25, 0x26, 0x25, 0x26, 0x4c, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xf8, 0xa8, 0x28, 0x48, 0xb0, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x28, 0x0d, 0x0a, 0x0e, 0x73, 0x00, 0x00, 0x00,
-+ 0xa8, 0xa8, 0xfc, 0xa8, 0xa8, 0xb8, 0x80, 0xfc,
-+ 0x20, 0xfc, 0x70, 0xa8, 0x24, 0x20, 0x00, 0x00,
-+ 0x00, 0x3d, 0x01, 0x7f, 0x01, 0x3d, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x25, 0x26, 0x3e, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0xf8, 0x08,
-+ 0xe8, 0xa8, 0xa8, 0xe8, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x3d, 0x03, 0x7d, 0x01, 0x3d, 0x01, 0x3d,
-+ 0x00, 0x3f, 0x24, 0x25, 0x3e, 0x24, 0x00, 0x00,
-+ 0x50, 0x50, 0xfc, 0x50, 0x50, 0x70, 0x00, 0xf8,
-+ 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x08, 0x09, 0x3e, 0x08, 0x08, 0x7e, 0x09, 0x28,
-+ 0x2e, 0x28, 0x38, 0x28, 0x46, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x88, 0xb0, 0x00, 0xf8,
-+ 0x88, 0x88, 0xf8, 0x88, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x26, 0x3d, 0x09, 0x28, 0x2d,
-+ 0x2a, 0x28, 0x2d, 0x39, 0x62, 0x04, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xa8, 0xa8, 0xb0, 0xa0, 0xb0, 0xa8,
-+ 0xa4, 0xa4, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x13, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x09, 0x2a, 0x1c, 0x18, 0x0f, 0x72, 0x00, 0x00,
-+ 0x50, 0x50, 0x50, 0x54, 0xd4, 0xd8, 0x50, 0xd8,
-+ 0x54, 0x54, 0x90, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x7f,
-+ 0x09, 0x08, 0x08, 0x08, 0x0f, 0x70, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xfc,
-+ 0x10, 0x90, 0xa0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
-+ 0x11, 0x11, 0x11, 0x10, 0x33, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x80, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x08, 0xf8, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x01, 0x02, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x0f,
-+ 0x08, 0x0f, 0x29, 0x24, 0x24, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0xfc,
-+ 0x00, 0xfc, 0x24, 0x94, 0x04, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3f, 0x2a, 0x2a, 0x3e,
-+ 0x1c, 0x1a, 0x2a, 0x48, 0x09, 0x0a, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x11, 0x17, 0x11, 0x1d,
-+ 0x72, 0x14, 0x10, 0x10, 0x11, 0x3e, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x40, 0x40, 0xfc, 0x50, 0x48,
-+ 0x54, 0xd4, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x7f, 0x00, 0x27, 0x24, 0x27, 0x24,
-+ 0x27, 0x24, 0x27, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x80, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x02, 0x3d, 0x24, 0x24, 0x3f, 0x24, 0x24, 0x3f,
-+ 0x24, 0x24, 0x24, 0x25, 0x26, 0x4c, 0x00, 0x00,
-+ 0x08, 0x08, 0x90, 0xa0, 0xf8, 0x40, 0x40, 0xfc,
-+ 0x40, 0xa0, 0x90, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x40, 0x23, 0x22, 0x04, 0x10,
-+ 0x10, 0x20, 0x20, 0x41, 0x42, 0x44, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x48, 0x40, 0x60,
-+ 0x60, 0xa0, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x10, 0x11, 0x12, 0x7c, 0x13,
-+ 0x10, 0x11, 0x1c, 0x60, 0x00, 0x07, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0x48, 0x84, 0x20,
-+ 0x40, 0x88, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x04, 0x19, 0x77, 0x10, 0x13, 0x1f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x30, 0xc0, 0xfc, 0x40, 0xf8, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1d, 0x18, 0x0e, 0x71, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0x88, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0xfc, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x28, 0x2b, 0x32, 0x2b, 0x26,
-+ 0x27, 0x24, 0x39, 0x22, 0x24, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x40, 0x27, 0x20, 0x03, 0x10,
-+ 0x13, 0x10, 0x27, 0x20, 0x40, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8, 0x40,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x3c, 0x2b, 0x30, 0x2f, 0x24, 0x27, 0x38,
-+ 0x23, 0x21, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x10, 0xa0, 0xfc, 0xc8, 0x68, 0xb0, 0x70, 0xa8,
-+ 0x24, 0xc0, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x09, 0x1b, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x90, 0x90, 0xa0, 0xfc, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x12, 0x11, 0x7d, 0x10, 0x10, 0x3b, 0x35,
-+ 0x35, 0x51, 0x51, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x10, 0x20, 0x78, 0x48, 0x48, 0x78, 0x40, 0x78,
-+ 0x48, 0x48, 0x78, 0x48, 0x80, 0x7c, 0x00, 0x00,
-+ 0x00, 0x20, 0x13, 0x12, 0x02, 0x03, 0x72, 0x13,
-+ 0x12, 0x12, 0x13, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x80, 0xf0, 0x10, 0x10, 0xf0, 0x00, 0xf0,
-+ 0x10, 0x10, 0xf0, 0x10, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x12, 0x19, 0x25, 0x24, 0x78, 0x13, 0x7d,
-+ 0x11, 0x55, 0x39, 0x31, 0x1e, 0x64, 0x00, 0x00,
-+ 0x10, 0x20, 0x78, 0x48, 0x48, 0x78, 0x40, 0x78,
-+ 0x48, 0x48, 0x78, 0x48, 0x80, 0x7c, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x2b, 0x29, 0x08, 0x1b,
-+ 0x2a, 0x4b, 0x12, 0x13, 0x22, 0x42, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xf0, 0x20, 0xc0, 0xf8,
-+ 0x48, 0xf8, 0x48, 0xf8, 0x48, 0x58, 0x00, 0x00,
-+ 0x00, 0x27, 0x11, 0x10, 0x03, 0x02, 0x73, 0x12,
-+ 0x13, 0x12, 0x12, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0xc0, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0x48, 0x48, 0x58, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x13, 0x12, 0x17, 0x7c, 0x11, 0x16, 0x10,
-+ 0x13, 0x1c, 0x61, 0x06, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf8, 0x40, 0xc8, 0x68, 0xb0,
-+ 0x30, 0x68, 0xa4, 0x20, 0x20, 0xc0, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7e, 0x08, 0x1c, 0x1b, 0x1b,
-+ 0x29, 0x29, 0x49, 0x0b, 0x0a, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xc8, 0xa8, 0x88, 0xfc, 0x08,
-+ 0x48, 0x28, 0x08, 0xfc, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x12, 0x13, 0x1e,
-+ 0x72, 0x12, 0x13, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x48, 0x48, 0xf8, 0x48,
-+ 0x68, 0x58, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x12, 0x12, 0x12, 0x7f, 0x12, 0x1a, 0x37, 0x36,
-+ 0x32, 0x53, 0x52, 0x14, 0x14, 0x19, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0xc8, 0x78, 0x48, 0xf8, 0x48,
-+ 0x48, 0x78, 0xb0, 0xb4, 0x54, 0x8c, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x12, 0x12, 0x32, 0x53, 0x12,
-+ 0x12, 0x12, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x48, 0xf8, 0x48,
-+ 0x48, 0x48, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x0b, 0x08, 0x41, 0x20, 0x27, 0x01, 0x11,
-+ 0x11, 0x11, 0x21, 0x21, 0x41, 0x46, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0xf0, 0x10,
-+ 0xf0, 0xf0, 0x10, 0xf0, 0x90, 0x08, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x7e, 0x08, 0x18, 0x1c, 0x1a,
-+ 0x2b, 0x29, 0x4a, 0x0c, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x40, 0x80, 0xf8, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x20, 0x10, 0x10, 0x00, 0x07, 0x70, 0x10,
-+ 0x10, 0x10, 0x10, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x00, 0xfc, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x0f, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x0f, 0x08, 0x0f, 0x29, 0x24, 0x40, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xe0, 0x20, 0xe0, 0x20, 0xe0,
-+ 0xfc, 0x00, 0xfc, 0x24, 0x94, 0x18, 0x00, 0x00,
-+ 0x10, 0x13, 0x16, 0x65, 0x18, 0x11, 0x2a, 0x7f,
-+ 0x1a, 0x35, 0x34, 0x31, 0x52, 0x14, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xb0, 0x90, 0x68, 0x48, 0xf8,
-+ 0x48, 0x68, 0xb0, 0x90, 0x28, 0x44, 0x00, 0x00,
-+ 0x08, 0x09, 0x15, 0x13, 0x22, 0x5c, 0x08, 0x7f,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x00, 0xdc, 0x54, 0xdc, 0x00, 0xf8, 0x00, 0xfc,
-+ 0x40, 0x78, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x11, 0x18, 0x37, 0x35,
-+ 0x33, 0x55, 0x51, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xf0, 0xa0, 0xfc, 0x10,
-+ 0xf8, 0x14, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x43, 0x20, 0x2f, 0x03, 0x12,
-+ 0x13, 0x13, 0x22, 0x23, 0x43, 0x4c, 0x00, 0x00,
-+ 0x80, 0xf0, 0x90, 0xf0, 0x80, 0xfc, 0xf0, 0x10,
-+ 0xf0, 0xf0, 0x10, 0xf0, 0x10, 0x08, 0x00, 0x00,
-+ 0x00, 0x17, 0x10, 0x12, 0x7d, 0x11, 0x10, 0x17,
-+ 0x10, 0x1c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x48, 0x48, 0x50, 0x40, 0xfc,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x1f, 0x00, 0x3f, 0x22, 0x5f,
-+ 0x12, 0x1f, 0x12, 0x02, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x00, 0xfc, 0x88, 0xf0,
-+ 0x90, 0xf0, 0x90, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x13, 0x7f, 0x2b, 0x28, 0x2f,
-+ 0x28, 0x73, 0x5a, 0x16, 0x22, 0x42, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xfc, 0x58, 0x58, 0x40, 0xfc,
-+ 0x40, 0xf8, 0xa8, 0xa8, 0xa8, 0xb8, 0x00, 0x00,
-+ 0x10, 0x10, 0x14, 0x64, 0x1b, 0x1a, 0x26, 0x7e,
-+ 0x13, 0x1a, 0x36, 0x36, 0x53, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0xf8, 0x48, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x09, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x11, 0x11, 0x21, 0x41, 0x00, 0x00,
-+ 0x10, 0xe0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x11, 0x01, 0x3f,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x09, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x78, 0x88, 0x88, 0x48, 0x28,
-+ 0x28, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x7f, 0x52, 0x14, 0x28, 0x3e, 0x68,
-+ 0x3e, 0x28, 0x3e, 0x29, 0x3f, 0x22, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x01, 0x7f, 0x00, 0x0f, 0x08, 0x0f, 0x00, 0x3f,
-+ 0x20, 0x5f, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xe0, 0x20, 0xe0, 0x00, 0xfc,
-+ 0x08, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x12, 0x12, 0x33, 0x52, 0x12,
-+ 0x12, 0x13, 0x1c, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x18, 0xe0, 0x40, 0x40, 0x40, 0xfc, 0x20, 0x20,
-+ 0x20, 0x90, 0x14, 0x0c, 0xfc, 0x04, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x11, 0x11, 0x31, 0x50, 0x17,
-+ 0x14, 0x1b, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x08, 0xf8, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x10, 0x13, 0x32, 0x53, 0x12,
-+ 0x13, 0x12, 0x13, 0x11, 0x16, 0x18, 0x00, 0x00,
-+ 0x80, 0x80, 0xf8, 0x80, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x20, 0x10, 0x08, 0x00, 0x00,
-+ 0x22, 0x12, 0x14, 0x7f, 0x09, 0x7f, 0x48, 0x7f,
-+ 0x59, 0x19, 0x2e, 0x48, 0x08, 0x08, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x1f, 0x10, 0x1f, 0x10,
-+ 0x1f, 0x10, 0x1f, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x08, 0x0f, 0x00, 0x3f, 0x01,
-+ 0x01, 0x1f, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x00, 0xf8, 0x00,
-+ 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x11, 0x11, 0x11, 0x7d, 0x11, 0x10, 0x17,
-+ 0x10, 0x1e, 0x62, 0x03, 0x04, 0x08, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x40, 0x78, 0x40, 0x40, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x40, 0x3f, 0x01, 0x09,
-+ 0x09, 0x09, 0x09, 0x15, 0x23, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x00, 0xf8, 0x00, 0x00,
-+ 0xf0, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x08, 0x04, 0x3f, 0x21, 0x5f,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x20, 0x40, 0xfc, 0x08, 0xf0,
-+ 0x10, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x13, 0x12, 0x12, 0x13,
-+ 0x12, 0x12, 0x13, 0x1c, 0x27, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x30, 0xc0, 0x40, 0x40, 0xfc,
-+ 0x20, 0x20, 0x90, 0x14, 0xec, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x1e, 0x12, 0x14, 0x1f,
-+ 0x12, 0x1a, 0x14, 0x26, 0x29, 0x50, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x18, 0xe0, 0x20, 0x20, 0xfc,
-+ 0x20, 0x20, 0xf8, 0x00, 0x80, 0x7c, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x08, 0x10, 0x10, 0x3f, 0x08,
-+ 0x48, 0x28, 0x13, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x40, 0x40, 0x40, 0xfc, 0x40,
-+ 0x40, 0x40, 0xf8, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x04, 0x04, 0x3f, 0x01, 0x3f, 0x21, 0x3f,
-+ 0x23, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0x80, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x08, 0x08, 0x08, 0x70, 0x00, 0x00, 0x00, 0x00,
-+ 0x11, 0x10, 0x10, 0x1b, 0x34, 0x37, 0x32, 0x53,
-+ 0x12, 0x10, 0x11, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xf8, 0x48, 0xf8, 0x40, 0xfc,
-+ 0xc4, 0xc4, 0x44, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x11, 0x11, 0x11, 0x1d,
-+ 0x71, 0x11, 0x16, 0x10, 0x17, 0x30, 0x00, 0x00,
-+ 0x18, 0xe0, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0x20, 0xd0, 0x14, 0x0c, 0xfc, 0x04, 0x00, 0x00,
-+ 0x10, 0x17, 0x11, 0x7a, 0x12, 0x17, 0x11, 0x1d,
-+ 0x75, 0x12, 0x12, 0x15, 0x18, 0x30, 0x00, 0x00,
-+ 0x00, 0x18, 0xe0, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x20, 0xf8, 0x00, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x11, 0x11, 0x10, 0x1f,
-+ 0x70, 0x12, 0x12, 0x13, 0x14, 0x38, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x40, 0x78, 0x40, 0x40, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x09, 0x08, 0x08, 0x7f, 0x08, 0x1b, 0x1e, 0x1b,
-+ 0x2a, 0x28, 0x49, 0x0a, 0x0c, 0x08, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xf8, 0x48, 0xf8, 0x40, 0xfc,
-+ 0xc4, 0xc4, 0x44, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x0b, 0x08, 0x40, 0x20, 0x20, 0x00, 0x08,
-+ 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x7e, 0x11, 0x11, 0x12, 0x3f, 0x24, 0x64,
-+ 0x24, 0x24, 0x3c, 0x25, 0x22, 0x04, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0x00, 0xfc, 0x20, 0xa0,
-+ 0xb8, 0xa0, 0xa0, 0xa0, 0x60, 0x1c, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x09, 0x09, 0x11, 0x19,
-+ 0x35, 0x55, 0x11, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0x40, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x08, 0xf8, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x02, 0x0d, 0x39, 0x09, 0x09, 0x7e, 0x09, 0x1c,
-+ 0x1a, 0x2b, 0x48, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x00, 0xf8, 0x40,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x65, 0x28, 0x1b, 0x22, 0x7c,
-+ 0x13, 0x3a, 0x36, 0x36, 0x52, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0xa0, 0xfc, 0x48, 0x40,
-+ 0xf8, 0x48, 0x48, 0x48, 0x58, 0x40, 0x00, 0x00,
-+ 0x08, 0x13, 0x3c, 0x25, 0x35, 0x2f, 0x2c, 0x7e,
-+ 0x26, 0x2d, 0x2d, 0x2e, 0x24, 0x4c, 0x00, 0x00,
-+ 0x00, 0x8c, 0xf0, 0x10, 0x10, 0x90, 0xfc, 0x90,
-+ 0x90, 0x10, 0x7c, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7e, 0x00, 0x3c, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7e, 0x00, 0x3d, 0x01, 0x3e,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x50, 0xfc, 0x24, 0xf8,
-+ 0xa8, 0xa8, 0xa8, 0xb8, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3e, 0x23, 0x22, 0x3e, 0x29, 0x09, 0x2f,
-+ 0x28, 0x28, 0x28, 0x2e, 0x38, 0x60, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x50, 0xfc, 0x28, 0xf8,
-+ 0xa8, 0xa8, 0xa8, 0xb8, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x27, 0x14, 0x17, 0x04, 0x07, 0x04, 0x77,
-+ 0x1a, 0x1a, 0x12, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x18, 0xe0, 0x40, 0xfc, 0x40, 0xfc, 0x40, 0xf8,
-+ 0x48, 0x48, 0x70, 0x40, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x03, 0x3c, 0x24, 0x24, 0x24, 0x3f, 0x24, 0x24,
-+ 0x22, 0x3a, 0x61, 0x00, 0x7e, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x50, 0x50, 0xe0, 0x50, 0x48,
-+ 0x44, 0xc4, 0xe4, 0xd8, 0x40, 0x40, 0x00, 0x00,
-+ 0x11, 0x0a, 0x7f, 0x0c, 0x3f, 0x2f, 0x33, 0x3f,
-+ 0x3f, 0x04, 0x7f, 0x0a, 0x11, 0x20, 0x00, 0x00,
-+ 0x00, 0x78, 0xc8, 0x50, 0x50, 0x60, 0x50, 0x48,
-+ 0x44, 0x44, 0xe4, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x07, 0x24, 0x27, 0x27, 0x24, 0x27, 0x3e,
-+ 0x02, 0x7e, 0x12, 0x12, 0x22, 0x42, 0x00, 0x00,
-+ 0x00, 0xc0, 0x48, 0xc8, 0xc8, 0x48, 0xc8, 0xf8,
-+ 0x80, 0xfc, 0x90, 0x90, 0x90, 0x90, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x23, 0x22, 0x02, 0x02,
-+ 0x12, 0x12, 0x24, 0x24, 0x48, 0x50, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x88, 0x80, 0x98,
-+ 0xe0, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x7d, 0x10, 0x13, 0x12, 0x1f,
-+ 0x72, 0x12, 0x12, 0x12, 0x12, 0x32, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0xa0, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xe8, 0xa8, 0xe8, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7f, 0x10, 0x17, 0x11, 0x1f,
-+ 0x76, 0x13, 0x13, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x20, 0xf8,
-+ 0x40, 0xf0, 0xf0, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x22, 0x14, 0x7f, 0x49, 0x7f,
-+ 0x49, 0x5d, 0x55, 0x5d, 0x41, 0x43, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x7c, 0x90, 0x90, 0x50,
-+ 0x50, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x42, 0x21, 0x27, 0x04, 0x17,
-+ 0x14, 0x15, 0x25, 0x25, 0x45, 0x44, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0x20, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xe8, 0x28, 0xe8, 0x28, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0x7c, 0x45, 0x45, 0x46, 0x7c,
-+ 0x44, 0x44, 0x44, 0x7c, 0x40, 0x00, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf8, 0x08, 0x08, 0x88, 0x48,
-+ 0x48, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x14, 0x23, 0x41, 0x1f, 0x11,
-+ 0x11, 0x1f, 0x11, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0x00, 0xf0, 0x10,
-+ 0x10, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x20, 0x17, 0x10, 0x03, 0x02, 0x73, 0x12,
-+ 0x12, 0x12, 0x12, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xe8, 0xa8, 0xe8, 0x18, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x10, 0x1b, 0x25, 0x24, 0x7b, 0x12, 0x7f,
-+ 0x12, 0x56, 0x3a, 0x32, 0x1e, 0x62, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0xa0, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xe8, 0xa8, 0xe8, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x40, 0x27, 0x24, 0x07, 0x10,
-+ 0x14, 0x13, 0x22, 0x24, 0x40, 0x43, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x40, 0xf8, 0x88,
-+ 0xc8, 0xb8, 0xa8, 0xc8, 0x88, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x0e, 0x78, 0x09, 0x1a,
-+ 0x00, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x18, 0xe0, 0x80, 0xfc, 0x90, 0x90, 0x10, 0x10,
-+ 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x11, 0x11, 0x2f, 0x4b, 0x0a, 0x1f, 0x10, 0x37,
-+ 0x54, 0x17, 0x14, 0x17, 0x14, 0x15, 0x00, 0x00,
-+ 0x20, 0x20, 0xe0, 0x20, 0xfc, 0xc8, 0x48, 0xa8,
-+ 0xa8, 0xb0, 0x90, 0xb0, 0xc8, 0x84, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x7b, 0x12, 0x1f, 0x10, 0x1f,
-+ 0x74, 0x17, 0x14, 0x17, 0x14, 0x35, 0x00, 0x00,
-+ 0x20, 0x20, 0xe0, 0x20, 0xfc, 0xc8, 0x48, 0xa8,
-+ 0xa8, 0xb0, 0x90, 0xb0, 0xc8, 0x84, 0x00, 0x00,
-+ 0x11, 0x11, 0x7f, 0x11, 0x7e, 0x57, 0x7c, 0x57,
-+ 0x7e, 0x13, 0x7e, 0x13, 0x12, 0x12, 0x00, 0x00,
-+ 0x20, 0x20, 0xe0, 0x20, 0xbc, 0xc8, 0x68, 0xa8,
-+ 0xa8, 0x90, 0x90, 0xb0, 0xc8, 0x84, 0x00, 0x00,
-+ 0x00, 0x22, 0x12, 0x13, 0x04, 0x08, 0x7f, 0x10,
-+ 0x10, 0x11, 0x12, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0xc0,
-+ 0xa0, 0x10, 0x08, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x09, 0x7f,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x72, 0x00, 0x00,
-+ 0x20, 0x20, 0xa0, 0xa0, 0xf8, 0xa0, 0x20, 0xfc,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x1f, 0x12, 0x12, 0x1f, 0x12,
-+ 0x12, 0x7f, 0x00, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf0, 0x90, 0x90, 0xf0, 0x90,
-+ 0x90, 0xfc, 0x00, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x00, 0x10, 0x17, 0x10, 0x7d, 0x11, 0x11, 0x11,
-+ 0x11, 0x1d, 0x61, 0x07, 0x01, 0x06, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0xfc, 0x90, 0x08, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x01, 0x01, 0x3f, 0x01, 0x03,
-+ 0x02, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x80,
-+ 0x80, 0x40, 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x12, 0x12, 0x1f, 0x12,
-+ 0x1f, 0x12, 0x12, 0x22, 0x23, 0x5c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x48, 0x40, 0xf8, 0x40,
-+ 0xfc, 0x48, 0x50, 0x20, 0x90, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x17, 0x14, 0x24, 0x24, 0x47, 0x04, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x80, 0x80, 0xfc, 0x80, 0x80,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x0b, 0x08, 0x47, 0x20, 0x21, 0x02, 0x14,
-+ 0x12, 0x12, 0x24, 0x28, 0x40, 0x41, 0x00, 0x00,
-+ 0x38, 0xc0, 0x40, 0xfc, 0xa0, 0x10, 0x88, 0x84,
-+ 0xd0, 0xa8, 0xa4, 0xa4, 0x80, 0x80, 0x00, 0x00,
-+ 0x10, 0x13, 0x16, 0x66, 0x2a, 0x1a, 0x26, 0x7e,
-+ 0x13, 0x3a, 0x37, 0x36, 0x52, 0x15, 0x00, 0x00,
-+ 0x20, 0xfc, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0xf8,
-+ 0xfc, 0xb4, 0x2c, 0xf8, 0x20, 0xfc, 0x00, 0x00,
-+ 0x06, 0x38, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x08,
-+ 0x3e, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x00, 0x00,
-+ 0x88, 0x88, 0x88, 0x88, 0xfc, 0x88, 0x88, 0x88,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x3e, 0x22,
-+ 0x22, 0x3e, 0x14, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x20, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x2b, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x09, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfc, 0x20, 0x20,
-+ 0x20, 0x50, 0x48, 0x78, 0xc4, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x7f, 0x08, 0x3e, 0x22, 0x3e, 0x3e,
-+ 0x22, 0x3e, 0x7f, 0x0c, 0x12, 0x63, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x0f, 0x08, 0x08, 0x08,
-+ 0x0f, 0x08, 0x00, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xe0, 0x20, 0x20, 0x20,
-+ 0xe0, 0x20, 0x00, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x10, 0x10, 0x37, 0x50, 0x10,
-+ 0x10, 0x11, 0x11, 0x12, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfc, 0x80, 0x80,
-+ 0xa0, 0x10, 0x08, 0x38, 0xc4, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x21, 0x3f, 0x2a, 0x2a, 0x3f,
-+ 0x2a, 0x3f, 0x2c, 0x4a, 0x52, 0x23, 0x00, 0x00,
-+ 0x00, 0x70, 0x50, 0x50, 0x54, 0x94, 0x8c, 0xf8,
-+ 0x48, 0x50, 0x30, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x20, 0x1f, 0x18, 0x08, 0x4f, 0x2a, 0x2a, 0x0f,
-+ 0x1a, 0x1a, 0x2f, 0x2b, 0x54, 0x48, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xa8, 0xa8, 0xac, 0xc4, 0xfc,
-+ 0xa8, 0xa8, 0xd0, 0x30, 0xc8, 0x84, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x21, 0x21, 0x21, 0x3f, 0x21,
-+ 0x21, 0x21, 0x21, 0x3f, 0x20, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08,
-+ 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x3f, 0x21, 0x5d, 0x1d, 0x1f,
-+ 0x11, 0x1f, 0x11, 0x1f, 0x11, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0x08, 0x70, 0x70, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf4, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x00, 0x3f, 0x01, 0x1f, 0x11, 0x11, 0x1f,
-+ 0x13, 0x03, 0x05, 0x09, 0x11, 0x60, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0x00, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x10, 0x40, 0x20, 0x24, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x48, 0x4b, 0x48, 0x48, 0x48,
-+ 0x48, 0x78, 0x48, 0x40, 0x0f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x13, 0x10, 0x7c, 0x17, 0x10, 0x11,
-+ 0x17, 0x1d, 0x61, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x48, 0xf8, 0x50, 0x60, 0xfc, 0x40, 0xf8,
-+ 0x08, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x30, 0x08, 0x61, 0x17, 0x00, 0x0f, 0x11, 0x26,
-+ 0x21, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0xa0, 0x10, 0xfc, 0x40, 0xfc, 0x50, 0x48,
-+ 0xc0, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x08, 0x7e, 0x12, 0x12, 0x12,
-+ 0x3c, 0x25, 0x06, 0x0a, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x20, 0x40, 0x40, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x17, 0x10, 0x1f,
-+ 0x11, 0x17, 0x19, 0x11, 0x21, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x88, 0xf0, 0xa0, 0xfc,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0x23, 0x48, 0x08, 0x17, 0x10, 0x32,
-+ 0x52, 0x12, 0x12, 0x15, 0x18, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0x78, 0x40, 0x40, 0x40, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x00, 0x0c, 0x02, 0x00, 0x18, 0x04, 0x00, 0x00,
-+ 0x07, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7c,
-+ 0xc0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x19, 0x1c, 0x1a,
-+ 0x2a, 0x28, 0x48, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x44, 0x27, 0x24, 0x04, 0x14,
-+ 0x17, 0x15, 0x24, 0x28, 0x49, 0x56, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x90, 0xfc, 0x90, 0xf0, 0x00,
-+ 0xf8, 0x10, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x0e, 0x02, 0x24, 0x14, 0x08, 0x1f, 0x20, 0x4f,
-+ 0x08, 0x0f, 0x04, 0x04, 0x3f, 0x00, 0x00, 0x00,
-+ 0x90, 0x90, 0x64, 0x44, 0x28, 0xf0, 0x08, 0xe4,
-+ 0x20, 0xe0, 0x40, 0x80, 0xf8, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x07, 0x18, 0x7f, 0x11,
-+ 0x11, 0x1f, 0x13, 0x05, 0x19, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xe0, 0x80, 0xf0, 0x10,
-+ 0x10, 0xf0, 0x10, 0x44, 0x24, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x24, 0x3c, 0x27, 0x3c, 0x24,
-+ 0x25, 0x3e, 0x18, 0x14, 0x24, 0x40, 0x00, 0x00,
-+ 0x40, 0x48, 0xf8, 0x50, 0x50, 0xfc, 0x40, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x20, 0x11, 0x11, 0x02, 0x0f, 0x70, 0x1f,
-+ 0x12, 0x12, 0x14, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0x80, 0x80, 0x40, 0x20, 0x10, 0xf8, 0x84, 0xf8,
-+ 0xa0, 0x90, 0x88, 0x88, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x3f, 0x09, 0x0a, 0x7f, 0x08, 0x1f,
-+ 0x31, 0x5f, 0x11, 0x11, 0x1f, 0x11, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x50, 0x50, 0xe0, 0x50, 0x48,
-+ 0x44, 0x44, 0x64, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x13, 0x23, 0x7d, 0x09, 0x7f,
-+ 0x09, 0x2b, 0x1d, 0x1a, 0x0e, 0x75, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x50, 0xfc, 0x50, 0x70, 0x00,
-+ 0xf8, 0x48, 0x50, 0x20, 0x50, 0x8c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x11, 0x11, 0x11, 0x21, 0x3d, 0x65,
-+ 0x25, 0x25, 0x27, 0x3c, 0x25, 0x00, 0x00, 0x00,
-+ 0x18, 0xe0, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0x10, 0xd0, 0x14, 0x0c, 0xfc, 0x04, 0x00, 0x00,
-+ 0x00, 0x7f, 0x11, 0x11, 0x11, 0x3d, 0x25, 0x65,
-+ 0x25, 0x25, 0x3e, 0x22, 0x24, 0x09, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xfc, 0x20, 0x20, 0x38,
-+ 0x28, 0x28, 0x48, 0x48, 0x88, 0x30, 0x00, 0x00,
-+ 0x08, 0x09, 0x7e, 0x12, 0x12, 0x3c, 0x06, 0x19,
-+ 0x61, 0x3f, 0x01, 0x02, 0x0c, 0x30, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x48, 0x50, 0x20, 0xd0, 0x0c,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xe0, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x12, 0x1f, 0x12, 0x13, 0x10,
-+ 0x17, 0x12, 0x11, 0x20, 0x23, 0x5c, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x20, 0xfc, 0x20, 0xe0, 0x00,
-+ 0xf0, 0x20, 0x40, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x3f, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x08, 0x7e, 0x12, 0x12, 0x12,
-+ 0x3c, 0x24, 0x06, 0x0a, 0x11, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x48, 0x50, 0x50,
-+ 0x20, 0x20, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x12, 0x12, 0x3c, 0x04, 0x1b,
-+ 0x61, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x88, 0x50, 0x20, 0xd0, 0x0c,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x08, 0x0f, 0x09, 0x11, 0x12, 0x3f, 0x51, 0x11,
-+ 0x17, 0x11, 0x11, 0x11, 0x1e, 0x10, 0x00, 0x00,
-+ 0x08, 0xe8, 0x28, 0xa8, 0x68, 0xe8, 0x28, 0x28,
-+ 0xe8, 0x28, 0x28, 0xc8, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x11, 0x09, 0x3f, 0x20, 0x4f, 0x08, 0x08,
-+ 0x0f, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x10, 0x20, 0xfc, 0x08, 0xe0, 0x20, 0x20,
-+ 0xe0, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x01, 0x01, 0x03, 0x0c, 0x32, 0x01, 0x03, 0x0c,
-+ 0x73, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x20, 0x40, 0x80, 0x40, 0x30,
-+ 0x0c, 0x80, 0x00, 0x00, 0xc0, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x27, 0x10, 0x13, 0x02, 0x0b, 0x0a,
-+ 0x13, 0x10, 0x21, 0x22, 0x2c, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
-+ 0x02, 0x04, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x17, 0x10, 0x1f, 0x10, 0x17,
-+ 0x10, 0x17, 0x24, 0x24, 0x47, 0x04, 0x00, 0x00,
-+ 0x80, 0xfc, 0x80, 0xf0, 0x90, 0xfc, 0x90, 0xf0,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x11, 0x17, 0x11, 0x7d, 0x10, 0x11, 0x17,
-+ 0x14, 0x1b, 0x62, 0x02, 0x03, 0x02, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0x50, 0xa0, 0x10, 0xfc,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x13, 0x12, 0x13, 0x7e, 0x13, 0x12, 0x13,
-+ 0x12, 0x1f, 0x65, 0x05, 0x09, 0x11, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x04, 0x1f, 0x64, 0x07, 0x04,
-+ 0x07, 0x04, 0x7f, 0x02, 0x04, 0x3f, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x40, 0xf0, 0x0c, 0xc0, 0x00,
-+ 0xc0, 0x00, 0xfc, 0x80, 0x60, 0x90, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x40, 0x7f, 0x04, 0x04,
-+ 0x0f, 0x0c, 0x14, 0x24, 0x47, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x22, 0x22, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x00, 0xfc,
-+ 0x00, 0xfc, 0x24, 0x24, 0xe4, 0x38, 0x00, 0x00,
-+ 0x00, 0x11, 0x11, 0x55, 0x55, 0x55, 0x55, 0x55,
-+ 0x55, 0x7d, 0x47, 0x42, 0x04, 0x08, 0x00, 0x00,
-+ 0x40, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xfc, 0x54, 0xac, 0x84, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x18, 0x37, 0x36, 0x33, 0x52,
-+ 0x13, 0x10, 0x1f, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x80, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x11, 0x12, 0x14, 0x1f,
-+ 0x71, 0x11, 0x10, 0x10, 0x13, 0x3c, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0xf0,
-+ 0x10, 0x20, 0xc0, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x7d, 0x11, 0x10, 0x1b, 0x15,
-+ 0x30, 0x53, 0x12, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0x50, 0xa0, 0x18, 0xf4,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x1f, 0x11, 0x1f, 0x11,
-+ 0x1f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7e, 0x11, 0x39, 0x34, 0x35,
-+ 0x56, 0x50, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xa8, 0xa8, 0xb0, 0xa0, 0xb0, 0xa8,
-+ 0xa4, 0xa4, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x11, 0x10, 0x3f, 0x34,
-+ 0x37, 0x51, 0x52, 0x14, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0x90,
-+ 0xfc, 0x10, 0x90, 0x90, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x13, 0x12, 0x3b, 0x36,
-+ 0x37, 0x50, 0x51, 0x16, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x01, 0x21, 0x11, 0x02, 0x0a, 0x14, 0x21, 0x22,
-+ 0x1f, 0x12, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x48, 0x50, 0xa0, 0x10, 0x0c,
-+ 0xf0, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x09, 0x09, 0x43, 0x23, 0x25, 0x0a, 0x17,
-+ 0x10, 0x12, 0x22, 0x23, 0x42, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0xe8, 0x88, 0xf8,
-+ 0x88, 0xa8, 0xa8, 0xe8, 0x28, 0x30, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x43, 0x22, 0x23, 0x00, 0x1f,
-+ 0x12, 0x23, 0x24, 0x49, 0x42, 0x40, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xf8, 0xa8, 0x28, 0x48, 0xb0, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x40, 0x23, 0x20, 0x07, 0x08,
-+ 0x0f, 0x11, 0x12, 0x24, 0x28, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0x90,
-+ 0xfc, 0x10, 0x90, 0x90, 0x10, 0x30, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x0a, 0x2a, 0x2c, 0x28, 0x48,
-+ 0x08, 0x0c, 0x12, 0x12, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x11, 0x10, 0x16, 0x15, 0x39, 0x32, 0x35, 0x51,
-+ 0x11, 0x19, 0x14, 0x24, 0x27, 0x40, 0x00, 0x00,
-+ 0xc8, 0x48, 0xb0, 0xa4, 0xf8, 0x08, 0xf4, 0x10,
-+ 0xf0, 0x10, 0x90, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x11, 0x09, 0x09, 0x01, 0x3f, 0x00,
-+ 0x00, 0x1f, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x10, 0x20, 0x00, 0xf0, 0x10,
-+ 0x10, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x2f, 0x28, 0x0b, 0x1a,
-+ 0x2a, 0x4b, 0x12, 0x11, 0x21, 0x4f, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xf8, 0x00, 0xf0, 0x10,
-+ 0x10, 0xf0, 0x20, 0x20, 0x40, 0xfc, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x05, 0x08, 0x0b, 0x14,
-+ 0x37, 0x51, 0x12, 0x14, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0x90,
-+ 0xfc, 0x90, 0x50, 0x50, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x1f, 0x01, 0x3f,
-+ 0x00, 0x7f, 0x08, 0x04, 0x04, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x14, 0x23, 0x42, 0x04, 0x1f,
-+ 0x60, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x90, 0x80, 0x40, 0xf0,
-+ 0x0c, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x14, 0x23, 0x5f, 0x10, 0x17,
-+ 0x10, 0x13, 0x12, 0x12, 0x13, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0xf8, 0x08, 0xe8,
-+ 0x08, 0xc8, 0x48, 0x48, 0xc8, 0x18, 0x00, 0x00,
-+ 0x10, 0x57, 0x36, 0x3b, 0x12, 0x7f, 0x12, 0x1b,
-+ 0x36, 0x37, 0x53, 0x15, 0x15, 0x19, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x72, 0x14, 0x0c, 0x13, 0x7e,
-+ 0x0c, 0x2a, 0x2a, 0x28, 0x49, 0x0a, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x40, 0x50, 0x98, 0xe4, 0x50,
-+ 0x50, 0x50, 0x90, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x08, 0x0c, 0x12, 0x7d, 0x09, 0x08,
-+ 0x7f, 0x08, 0x08, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x08, 0xc8, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0f, 0x7f, 0x0f, 0x09, 0x0f,
-+ 0x09, 0x0f, 0x3f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x80, 0xfc, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x11, 0x09, 0x49, 0x21, 0x21,
-+ 0x0f, 0x09, 0x13, 0x1c, 0x23, 0x20, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0xfc, 0x00, 0xf8, 0xa8, 0x48, 0xb0, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x39, 0x28, 0x2b, 0x38, 0x2f,
-+ 0x29, 0x3b, 0x2c, 0x2b, 0x28, 0x58, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x50, 0xe0, 0xf8, 0xa0, 0xfc,
-+ 0x50, 0x58, 0xe4, 0x50, 0x48, 0xc0, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x01, 0x3c, 0x01, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0xfc, 0x10, 0x10, 0x90,
-+ 0x90, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x02, 0x3d, 0x27, 0x24, 0x3f, 0x25, 0x26, 0x27,
-+ 0x3c, 0x24, 0x25, 0x25, 0x25, 0x4d, 0x00, 0x00,
-+ 0x48, 0x50, 0xf8, 0xa0, 0xfc, 0x10, 0xf8, 0xfc,
-+ 0xf0, 0xf0, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x7f, 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x10,
-+ 0x08, 0x04, 0x04, 0x00, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10,
-+ 0x20, 0x20, 0x40, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x23, 0x22, 0x3e, 0x29, 0x08, 0x2e,
-+ 0x28, 0x28, 0x28, 0x2e, 0x38, 0x60, 0x00, 0x00,
-+ 0x20, 0x24, 0xf8, 0x70, 0xa8, 0x24, 0x60, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x20, 0x14, 0x12, 0x02, 0x00, 0x71, 0x12,
-+ 0x1d, 0x11, 0x12, 0x1c, 0x26, 0x41, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xa8, 0xa8, 0xb0, 0xa0, 0xb0, 0xa8,
-+ 0x28, 0x24, 0x24, 0x1c, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x23, 0x10, 0x17, 0x00, 0x01, 0x77, 0x10,
-+ 0x10, 0x11, 0x12, 0x1c, 0x26, 0x41, 0x00, 0x00,
-+ 0x10, 0xe0, 0x40, 0xfc, 0xe0, 0x50, 0xec, 0xa0,
-+ 0xb8, 0x28, 0x08, 0x30, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x12, 0x22, 0x5d, 0x09, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x70, 0x00, 0x00,
-+ 0xe8, 0x68, 0x74, 0x94, 0xf8, 0x08, 0xfc, 0x88,
-+ 0xf8, 0x90, 0x50, 0x60, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x79, 0x49, 0x53, 0x65, 0x59, 0x4a, 0x4f,
-+ 0x48, 0x4a, 0x72, 0x43, 0x42, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0xe8, 0x88, 0xf8,
-+ 0x88, 0xa8, 0xa8, 0xe8, 0x28, 0x30, 0x00, 0x00,
-+ 0x00, 0x7f, 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x22,
-+ 0x12, 0x14, 0x08, 0x0e, 0x71, 0x06, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x02, 0x39, 0x2b, 0x28, 0x2f, 0x39, 0x2b, 0x2d,
-+ 0x39, 0x29, 0x29, 0x2b, 0x2a, 0x5c, 0x00, 0x00,
-+ 0x48, 0x50, 0xf8, 0xa0, 0xfc, 0xf0, 0x48, 0xf4,
-+ 0xf0, 0x40, 0xfc, 0x54, 0xac, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x20, 0x3f,
-+ 0x2f, 0x2a, 0x2e, 0x2a, 0x27, 0x38, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x28, 0x28,
-+ 0xf8, 0xa8, 0xa8, 0x28, 0x28, 0x78, 0x00, 0x00,
-+ 0x11, 0x1e, 0x12, 0x3f, 0x2f, 0x6a, 0x2f, 0x2a,
-+ 0x2f, 0x22, 0x2f, 0x22, 0x23, 0x2c, 0x00, 0x00,
-+ 0xa0, 0x20, 0x20, 0xf8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0x28, 0xa8, 0x28, 0xc8, 0x98, 0x00, 0x00,
-+ 0x06, 0x38, 0x08, 0x7f, 0x3e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x3e, 0x08, 0x0f, 0x72, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x7f, 0x40, 0x40, 0x5f, 0x40, 0x4f, 0x48,
-+ 0x48, 0x48, 0x4f, 0x48, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xe8, 0x08, 0xc8, 0x48,
-+ 0x48, 0x48, 0xc8, 0x48, 0x08, 0x18, 0x00, 0x00,
-+ 0x11, 0x09, 0x3f, 0x20, 0x4f, 0x08, 0x08, 0x0f,
-+ 0x01, 0x1f, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x10, 0x20, 0xfc, 0x08, 0xe0, 0x20, 0x20, 0xe0,
-+ 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x21, 0x1f, 0x10, 0x03, 0x72, 0x13, 0x13, 0x1a,
-+ 0x67, 0x03, 0x7f, 0x04, 0x02, 0x00, 0x00, 0x00,
-+ 0x20, 0xfc, 0x80, 0xf0, 0x10, 0xf0, 0xf0, 0x10,
-+ 0xf0, 0xf8, 0xfc, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x10, 0x13, 0x11, 0x17, 0x3b, 0x36, 0x37, 0x52,
-+ 0x13, 0x10, 0x13, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x40, 0xf8, 0x10, 0xfc, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x11, 0x7f, 0x13, 0x12, 0x13, 0x16,
-+ 0x1b, 0x70, 0x13, 0x10, 0x17, 0x30, 0x00, 0x00,
-+ 0x40, 0xf8, 0x10, 0xfc, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x0f, 0x0c, 0x44, 0x27, 0x24, 0x05, 0x15,
-+ 0x15, 0x15, 0x25, 0x24, 0x44, 0x44, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0xe8, 0x28,
-+ 0x28, 0xe8, 0x28, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x7b, 0x49, 0x4f, 0x7b, 0x4a, 0x4b, 0x7a,
-+ 0x4b, 0x48, 0x7b, 0x40, 0x0f, 0x00, 0x00, 0x00,
-+ 0x40, 0xf8, 0x10, 0xfc, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x1f, 0x04, 0x7f, 0x0f, 0x09, 0x0f, 0x09,
-+ 0x0f, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x40, 0xfc, 0xe0, 0x20, 0xe0, 0x20,
-+ 0xe0, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x3d, 0x25, 0x25, 0x3d,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x4d, 0x00, 0x00,
-+ 0x00, 0xfc, 0x04, 0x04, 0xfc, 0x04, 0x74, 0x54,
-+ 0x54, 0x54, 0x74, 0x44, 0x04, 0x0c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x0c, 0x08, 0x1f, 0x24, 0x4f,
-+ 0x12, 0x3f, 0x12, 0x12, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x08, 0xc8,
-+ 0x08, 0xe8, 0x48, 0x48, 0xc8, 0x30, 0x00, 0x00,
-+ 0x02, 0x21, 0x1f, 0x10, 0x03, 0x02, 0x73, 0x12,
-+ 0x13, 0x12, 0x13, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x10, 0x20, 0xfc, 0x80, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x09, 0x15, 0x13, 0x23, 0x5d, 0x09, 0x7f,
-+ 0x09, 0x2b, 0x1d, 0x19, 0x0f, 0x71, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0xe8, 0xa8,
-+ 0xa8, 0xa8, 0xe8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x10, 0x54, 0x57, 0x54, 0x57,
-+ 0x54, 0x54, 0x7c, 0x44, 0x40, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x40, 0x40, 0xfc, 0x00, 0xfc,
-+ 0x60, 0x50, 0x48, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x20, 0x26, 0x39, 0x21, 0x23, 0x1f, 0x11, 0x11,
-+ 0x7f, 0x11, 0x11, 0x12, 0x12, 0x14, 0x00, 0x00,
-+ 0x40, 0x80, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xfc,
-+ 0x00, 0xfc, 0x54, 0xac, 0x84, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x2f, 0x22, 0x21, 0x3f, 0x22,
-+ 0x27, 0x2a, 0x33, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xf0, 0x40, 0x00, 0xf8, 0x00,
-+ 0xf0, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x21, 0x49, 0x09, 0x11, 0x10, 0x37,
-+ 0x50, 0x17, 0x11, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x10, 0xfc, 0x10, 0x90, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x27, 0x48, 0x0b, 0x12, 0x12, 0x33,
-+ 0x53, 0x10, 0x15, 0x15, 0x19, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0xa8, 0xa8, 0xf8,
-+ 0x08, 0xd0, 0x28, 0x04, 0x14, 0xf0, 0x00, 0x00,
-+ 0x20, 0x10, 0x17, 0x40, 0x23, 0x20, 0x03, 0x12,
-+ 0x14, 0x10, 0x20, 0x21, 0x42, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x00, 0xfc, 0x08,
-+ 0xa0, 0xa0, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x2b, 0x28, 0x3c, 0x2b, 0x28, 0x48,
-+ 0x0f, 0x79, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x10, 0x10,
-+ 0xfc, 0x10, 0x90, 0x90, 0x10, 0x30, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x7f, 0x2a, 0x29, 0x5f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x50, 0x20, 0xd0, 0xec, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x7f, 0x03, 0x05, 0x19, 0x61,
-+ 0x04, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0xfc, 0x80, 0x40, 0x30, 0x0c,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x0f, 0x08, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x29, 0x24, 0x40, 0x00, 0x00,
-+ 0x40, 0xfc, 0xa0, 0x10, 0xf8, 0x80, 0xf0, 0x80,
-+ 0xf0, 0x80, 0xfc, 0x24, 0x94, 0x18, 0x00, 0x00,
-+ 0x01, 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x0f,
-+ 0x09, 0x7f, 0x09, 0x1f, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0xe0,
-+ 0x20, 0xfc, 0x20, 0xf8, 0x20, 0xc0, 0x00, 0x00,
-+ 0x04, 0x44, 0x28, 0x13, 0x32, 0x4a, 0x0a, 0x1b,
-+ 0x2a, 0x48, 0x08, 0x08, 0x37, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0xf8,
-+ 0x48, 0x50, 0x48, 0x78, 0x84, 0x04, 0x00, 0x00,
-+ 0x00, 0x3c, 0x03, 0x7c, 0x01, 0x3c, 0x01, 0x3d,
-+ 0x02, 0x3c, 0x24, 0x24, 0x3d, 0x26, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x00, 0xfc, 0x08,
-+ 0xa0, 0xa0, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x7f, 0x09, 0x1d, 0x1b, 0x1b,
-+ 0x29, 0x2a, 0x4a, 0x0c, 0x09, 0x0a, 0x00, 0x00,
-+ 0x18, 0xe0, 0x00, 0x00, 0xfc, 0x40, 0x40, 0x78,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x11, 0x16, 0x7f, 0x12, 0x13, 0x38, 0x35,
-+ 0x36, 0x51, 0x56, 0x11, 0x16, 0x10, 0x00, 0x00,
-+ 0x80, 0xf0, 0x40, 0xf8, 0x48, 0xf8, 0x80, 0xe8,
-+ 0x68, 0xb0, 0x68, 0xa4, 0x20, 0xc0, 0x00, 0x00,
-+ 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x3c, 0x24,
-+ 0x20, 0x20, 0x20, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xc0, 0x40, 0x40, 0x40, 0x40, 0x78, 0x48,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x24, 0x44, 0x08, 0x11, 0x01,
-+ 0x7f, 0x01, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x88, 0x80, 0x88, 0x78, 0x00,
-+ 0xfc, 0x00, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x13, 0x12, 0x3a, 0x37,
-+ 0x36, 0x52, 0x53, 0x16, 0x12, 0x12, 0x00, 0x00,
-+ 0x40, 0xb8, 0x28, 0x28, 0xac, 0x4c, 0x04, 0xf8,
-+ 0x28, 0xa8, 0x10, 0x30, 0x48, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x1f, 0x18,
-+ 0x18, 0x1f, 0x28, 0x28, 0x4f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x80, 0xf8, 0x88,
-+ 0x88, 0xf8, 0x88, 0x88, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x7f, 0x02, 0x04, 0x1f, 0x1f, 0x10, 0x1f,
-+ 0x1f, 0x10, 0x1f, 0x15, 0x25, 0x40, 0x00, 0x00,
-+ 0x10, 0xfc, 0x80, 0x40, 0xe4, 0xdc, 0x44, 0xc0,
-+ 0xf0, 0x00, 0xf8, 0x48, 0x28, 0x30, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x05, 0x01, 0x01, 0x01,
-+ 0x01, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x00, 0xf8, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x5f, 0x01, 0x1f, 0x11,
-+ 0x1f, 0x11, 0x1f, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0xf0, 0x00, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x00, 0x7f, 0x04, 0x04, 0x3f, 0x24, 0x24, 0x24,
-+ 0x28, 0x30, 0x3f, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xf8, 0x88, 0x98, 0x98,
-+ 0x78, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x24, 0x1f, 0x14, 0x4f, 0x24, 0x3f, 0x00, 0x1f,
-+ 0x19, 0x2f, 0x29, 0x4f, 0x49, 0x4b, 0x00, 0x00,
-+ 0x20, 0x20, 0x78, 0x90, 0x20, 0xf8, 0x28, 0xfc,
-+ 0x28, 0xf8, 0x28, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x02, 0x02, 0x73, 0x5e, 0x52, 0x5a, 0x5a, 0x5a,
-+ 0x7f, 0x5a, 0x4a, 0x02, 0x02, 0x01, 0x00, 0x00,
-+ 0x00, 0x7c, 0x90, 0x20, 0xf8, 0xc8, 0xf8, 0xc8,
-+ 0xf8, 0xc8, 0x78, 0xb0, 0xa8, 0xc4, 0x00, 0x00,
-+ 0x02, 0x02, 0x03, 0x7e, 0x22, 0x22, 0x22, 0x22,
-+ 0x3f, 0x22, 0x22, 0x02, 0x02, 0x01, 0x00, 0x00,
-+ 0x00, 0x30, 0xc0, 0x00, 0x20, 0x20, 0x20, 0x20,
-+ 0xe0, 0x20, 0x20, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x19, 0x35, 0x35, 0x30, 0x53,
-+ 0x10, 0x10, 0x17, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xf0,
-+ 0x20, 0x40, 0xfc, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x00, 0x3e, 0x22, 0x3f, 0x00,
-+ 0x3e, 0x04, 0x0e, 0x78, 0x09, 0x1e, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x90, 0x90, 0x50,
-+ 0x50, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x47, 0x20, 0x22, 0x02, 0x0a,
-+ 0x0b, 0x0a, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xc0, 0x48, 0x48, 0x48, 0x48,
-+ 0xf8, 0x48, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x27, 0x3c, 0x24, 0x27,
-+ 0x3c, 0x24, 0x27, 0x24, 0x24, 0x4c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x88, 0x48, 0x70, 0xa0, 0x30,
-+ 0x70, 0xa8, 0x24, 0x20, 0x20, 0xc0, 0x00, 0x00,
-+ 0x00, 0x23, 0x12, 0x13, 0x02, 0x02, 0x72, 0x12,
-+ 0x12, 0x14, 0x14, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x18, 0xe0, 0x20, 0xfc, 0x20, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x88, 0xf8, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x09, 0x0f, 0x78, 0x08, 0x2a, 0x2a, 0x2a,
-+ 0x2a, 0x3e, 0x28, 0x0a, 0x0a, 0x07, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x01, 0x7f, 0x02, 0x04, 0x18,
-+ 0x6f, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0x00, 0xfc, 0x80, 0x40, 0x30,
-+ 0xec, 0x20, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x0f, 0x08, 0x0f, 0x0f, 0x3f, 0x01, 0x3f, 0x2d,
-+ 0x4d, 0x1f, 0x00, 0x7f, 0x04, 0x3f, 0x00, 0x00,
-+ 0xe0, 0x20, 0xe0, 0xe0, 0xf8, 0x00, 0xfc, 0x68,
-+ 0x60, 0xf0, 0x00, 0xfc, 0x60, 0x90, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x13, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x20, 0x20, 0x3c, 0xe0, 0x28, 0xa8, 0xa8, 0xa8,
-+ 0xf8, 0xa8, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x02, 0x04, 0x18, 0x67, 0x00,
-+ 0x3f, 0x01, 0x05, 0x19, 0x61, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x80, 0x40, 0x30, 0xcc, 0x00,
-+ 0xf8, 0x00, 0x40, 0x30, 0x08, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x09, 0x09, 0x3f, 0x09, 0x09, 0x3f,
-+ 0x09, 0x09, 0x11, 0x11, 0x21, 0x46, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x50, 0x50, 0x60, 0x50, 0x48,
-+ 0x44, 0x44, 0x64, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x3f, 0x21, 0x21, 0x22, 0x22,
-+ 0x24, 0x28, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x88, 0x48,
-+ 0x28, 0x28, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x0f, 0x09, 0x11, 0x21, 0x41,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x11, 0x11, 0x15, 0x15, 0x15,
-+ 0x15, 0x15, 0x15, 0x3f, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0x10, 0xd0, 0x10,
-+ 0x10, 0x10, 0x14, 0xec, 0x0c, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x14, 0x10, 0x3e, 0x28, 0x49,
-+ 0x7e, 0x08, 0x14, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x48, 0x90, 0xfc, 0x90,
-+ 0xf8, 0x90, 0xf8, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x00, 0x3a, 0x01, 0x7d, 0x00, 0x38, 0x07, 0x39,
-+ 0x01, 0x39, 0x29, 0x2b, 0x3c, 0x28, 0x00, 0x00,
-+ 0x20, 0x28, 0xa8, 0x70, 0x20, 0xfc, 0x70, 0x70,
-+ 0xa8, 0xa4, 0x20, 0x20, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x25, 0x15, 0x1f, 0x45, 0x2f, 0x2a, 0x0f, 0x12,
-+ 0x1f, 0x22, 0x2f, 0x43, 0x44, 0x58, 0x00, 0x00,
-+ 0x28, 0x28, 0xb0, 0x7c, 0xd0, 0xd0, 0xfc, 0x50,
-+ 0xd0, 0x7c, 0xd0, 0x50, 0xfc, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x10, 0x11, 0x13, 0x1c,
-+ 0x77, 0x11, 0x11, 0x12, 0x14, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xa0, 0x10, 0xf8, 0x04,
-+ 0xf8, 0x40, 0x50, 0x48, 0x48, 0xc0, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x09, 0x7f,
-+ 0x09, 0x2b, 0x1d, 0x19, 0x0f, 0x71, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xb8, 0xa8, 0xa8, 0xfc, 0x04,
-+ 0x74, 0x54, 0x54, 0x74, 0x04, 0x0c, 0x00, 0x00,
-+ 0x11, 0x10, 0x10, 0x7f, 0x14, 0x13, 0x3a, 0x36,
-+ 0x36, 0x53, 0x53, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xfc, 0xa0, 0xf8, 0xa8, 0xa8,
-+ 0xb8, 0x18, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3e, 0x28, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x45, 0x1a, 0x00, 0x00,
-+ 0x08, 0x88, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x16, 0x67, 0x2a, 0x1b, 0x24, 0x7f,
-+ 0x12, 0x3b, 0x36, 0x37, 0x52, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x40, 0xf8,
-+ 0x48, 0xf8, 0x48, 0xfc, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x03, 0x7c, 0x56, 0x55, 0x55, 0x7e, 0x57,
-+ 0x54, 0x56, 0x7d, 0x45, 0x42, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0xc8, 0xa8, 0x10, 0xb0, 0x48, 0xf8,
-+ 0xa8, 0xa8, 0x10, 0x90, 0x68, 0x44, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x01, 0x3f, 0x24, 0x22,
-+ 0x2f, 0x21, 0x2f, 0x21, 0x21, 0x21, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x48, 0x88,
-+ 0xe8, 0x08, 0xe8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x13, 0x13, 0x3a, 0x37,
-+ 0x36, 0x53, 0x52, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x28, 0xc8, 0xf8,
-+ 0x48, 0xf8, 0x48, 0x48, 0x48, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x2a, 0x3f, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa8, 0x30, 0x20,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x14, 0x14, 0x7f, 0x14, 0x3e, 0x2b, 0x3e, 0x08,
-+ 0x3e, 0x08, 0x7f, 0x14, 0x22, 0x40, 0x00, 0x00,
-+ 0x48, 0x48, 0x50, 0xfc, 0x90, 0x90, 0xf8, 0x90,
-+ 0x90, 0xf8, 0x90, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x40, 0x27, 0x21, 0x01, 0x09,
-+ 0x0b, 0x0a, 0x10, 0x10, 0x21, 0x26, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0x80, 0xfc, 0x10, 0x10, 0x10,
-+ 0x90, 0x60, 0x20, 0x50, 0x88, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x12, 0x12, 0x12,
-+ 0x13, 0x12, 0x12, 0x22, 0x22, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x38,
-+ 0xc0, 0x00, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x1f,
-+ 0x00, 0x00, 0x01, 0x0e, 0x70, 0x00, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0x40, 0xfc, 0x40, 0x40, 0x20,
-+ 0x20, 0x20, 0x90, 0x14, 0x0c, 0x04, 0x00, 0x00,
-+ 0x01, 0x21, 0x11, 0x13, 0x02, 0x04, 0x79, 0x11,
-+ 0x12, 0x14, 0x10, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x40, 0x40, 0x50, 0x48,
-+ 0x44, 0x44, 0x40, 0xc0, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x1f, 0x10, 0x28, 0x49, 0x0e,
-+ 0x08, 0x08, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x88, 0x08,
-+ 0x08, 0x48, 0x48, 0xc8, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x3d, 0x25, 0x3d, 0x25,
-+ 0x25, 0x3d, 0x19, 0x15, 0x22, 0x45, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0x78, 0x00, 0xfc, 0x60,
-+ 0x64, 0x58, 0x50, 0x50, 0x68, 0x84, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x21, 0x21, 0x22, 0x25, 0x29,
-+ 0x21, 0x22, 0x24, 0x28, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x08, 0x88, 0x48, 0x28, 0x28,
-+ 0x88, 0x48, 0x28, 0x28, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x3e, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x3e, 0x2c, 0x0a, 0x0f, 0x19, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x1f, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x03, 0x7c, 0x11, 0x49, 0x2a, 0x24, 0x3f, 0x02,
-+ 0x04, 0x07, 0x7c, 0x04, 0x04, 0x0c, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x0f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x02,
-+ 0x04, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
-+ 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7e, 0x12, 0x12, 0x12,
-+ 0x3c, 0x24, 0x06, 0x0a, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x10, 0x1f,
-+ 0x11, 0x12, 0x24, 0x38, 0x40, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x80, 0x88, 0xc8,
-+ 0xb0, 0xa0, 0x90, 0x88, 0x84, 0x80, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x00, 0x04, 0x3c, 0x04,
-+ 0x3c, 0x04, 0x3c, 0x04, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0x40, 0x78, 0x40,
-+ 0x78, 0x40, 0x78, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x10, 0x10, 0x30, 0x57, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x13, 0x10, 0x00, 0x00,
-+ 0x18, 0xe0, 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x08, 0x7e, 0x12, 0x12, 0x13,
-+ 0x3c, 0x24, 0x06, 0x0a, 0x11, 0x20, 0x00, 0x00,
-+ 0x00, 0x1c, 0xe0, 0x20, 0x20, 0x20, 0x20, 0xfc,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x0d, 0x03, 0x02, 0x0c, 0x30,
-+ 0x01, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0x90, 0x10, 0x60,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x00, 0x3d, 0x00, 0x7f, 0x00, 0x3c, 0x01, 0x3c,
-+ 0x00, 0x3d, 0x25, 0x26, 0x3c, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xc8, 0x68, 0x88, 0x30, 0x40,
-+ 0xa0, 0xa8, 0x84, 0x94, 0x90, 0x70, 0x00, 0x00,
-+ 0x10, 0x0b, 0x08, 0x47, 0x27, 0x23, 0x00, 0x0f,
-+ 0x08, 0x13, 0x12, 0x22, 0x22, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xfc, 0x58, 0x58, 0x40, 0xfc,
-+ 0x80, 0xf8, 0xa8, 0xa8, 0xa8, 0xb8, 0x00, 0x00,
-+ 0x10, 0x13, 0x11, 0x7e, 0x07, 0x0a, 0x0b, 0x1a,
-+ 0x37, 0x56, 0x13, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xfc, 0x50, 0x4c, 0xf8, 0xd8, 0xf8, 0xd8,
-+ 0x68, 0xd8, 0xf8, 0xd8, 0x68, 0x58, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x09, 0x0a, 0x10, 0x18,
-+ 0x34, 0x55, 0x11, 0x12, 0x10, 0x10, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x20, 0x20, 0xb0, 0xa8,
-+ 0xa8, 0x24, 0x24, 0x24, 0x20, 0x60, 0x00, 0x00,
-+ 0x01, 0x3f, 0x23, 0x54, 0x14, 0x23, 0x1f, 0x12,
-+ 0x1f, 0x00, 0x7f, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xa0, 0x50, 0xc8, 0xf0, 0x90,
-+ 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x0c, 0x0f, 0x12, 0x2f, 0x44, 0x09,
-+ 0x13, 0x00, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xc8, 0xe8, 0x08,
-+ 0x30, 0x80, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x09, 0x49, 0x37, 0x11, 0x31, 0x48, 0x0b, 0x1a,
-+ 0x2a, 0x4b, 0x0a, 0x0a, 0x33, 0x12, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0x10, 0x00, 0xf8, 0x48,
-+ 0x48, 0xf8, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x3f, 0x08, 0x7f, 0x15, 0x2b, 0x7e,
-+ 0x08, 0x0f, 0x70, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x40, 0x40, 0xf0, 0x50, 0x50, 0xd0, 0x50, 0x74,
-+ 0x94, 0x0c, 0x00, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x10, 0x20, 0x4f, 0x08, 0x08,
-+ 0x08, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x80, 0x80, 0xf0, 0x80, 0x80,
-+ 0x80, 0xfc, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x04, 0x1f, 0x60, 0x0f, 0x00,
-+ 0x01, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x40, 0xf0, 0x0c, 0xe0, 0x40,
-+ 0x80, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x13, 0x14, 0x13, 0x1c,
-+ 0x70, 0x11, 0x15, 0x15, 0x19, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xf8, 0x10,
-+ 0xa0, 0x50, 0x48, 0x14, 0x14, 0xf0, 0x00, 0x00,
-+ 0x12, 0x12, 0x13, 0x7a, 0x16, 0x15, 0x1d, 0x13,
-+ 0x1a, 0x74, 0x18, 0x15, 0x14, 0x38, 0x00, 0x00,
-+ 0x30, 0x28, 0xa8, 0xa0, 0xfc, 0xa0, 0x30, 0x50,
-+ 0x48, 0x84, 0x00, 0x48, 0xa4, 0xa4, 0x00, 0x00,
-+ 0x11, 0x11, 0x15, 0x15, 0x3b, 0x32, 0x36, 0x59,
-+ 0x12, 0x14, 0x18, 0x25, 0x24, 0x48, 0x00, 0x00,
-+ 0x20, 0x28, 0xe4, 0x64, 0x7c, 0xa0, 0xa0, 0x50,
-+ 0x50, 0x88, 0x04, 0x48, 0xa4, 0xa4, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2a, 0x2c, 0x08, 0x7e, 0x08, 0x1d,
-+ 0x1b, 0x2b, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xc0, 0x40, 0x40, 0x40, 0x40, 0x78, 0x48,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x70, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x08, 0x13, 0x12, 0x3a, 0x0a,
-+ 0x4b, 0x2a, 0x13, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xa0, 0xf8, 0xa8, 0xa8, 0xb8,
-+ 0x38, 0x08, 0xf8, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x3f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x11, 0x1a, 0x14, 0x23, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x10, 0x20, 0x20, 0x40,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x1c, 0x1a, 0x2a, 0x49, 0x09,
-+ 0x01, 0x1f, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x70, 0x70, 0xa8, 0x24, 0x20,
-+ 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x7f, 0x0f, 0x09, 0x0f, 0x3f, 0x2a, 0x7f,
-+ 0x0f, 0x7f, 0x06, 0x7c, 0x07, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0xe0, 0x20, 0xe0, 0xfc, 0xa8, 0xf8,
-+ 0xe0, 0xfc, 0x90, 0x60, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x12, 0x11, 0x19, 0x34, 0x34, 0x33, 0x52,
-+ 0x12, 0x12, 0x12, 0x13, 0x13, 0x12, 0x00, 0x00,
-+ 0x88, 0x48, 0x50, 0x20, 0x40, 0x20, 0x28, 0xa8,
-+ 0x48, 0x48, 0xa8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x43, 0x22, 0x23, 0x07, 0x05,
-+ 0x14, 0x17, 0x25, 0x25, 0x49, 0x56, 0x00, 0x00,
-+ 0xa0, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0xfc, 0xf0,
-+ 0x00, 0xfc, 0x48, 0x30, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x14, 0x67, 0x1a, 0x1a, 0x26, 0x7e,
-+ 0x12, 0x1b, 0x36, 0x36, 0x52, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0xa8,
-+ 0x98, 0x18, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x0c, 0x12, 0x7d, 0x01, 0x3e, 0x22,
-+ 0x3e, 0x22, 0x3e, 0x22, 0x22, 0x26, 0x00, 0x00,
-+ 0x40, 0x40, 0x4c, 0x70, 0x44, 0x44, 0x3c, 0x40,
-+ 0x4c, 0x70, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x3e, 0x25, 0x25, 0x3c, 0x25, 0x25, 0x3d,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x4d, 0x00, 0x00,
-+ 0x88, 0x48, 0x48, 0x10, 0x20, 0x18, 0x98, 0x68,
-+ 0x28, 0x58, 0x98, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3b, 0x2a, 0x2b, 0x3a, 0x2b, 0x2b, 0x3a,
-+ 0x2a, 0x2b, 0x2a, 0x2a, 0x2c, 0x5b, 0x00, 0x00,
-+ 0xa0, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0xfc, 0xf8,
-+ 0x00, 0xfc, 0xc8, 0xb0, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x02, 0x1f, 0x12, 0x1f, 0x12, 0x1f, 0x1f, 0x17,
-+ 0x10, 0x1f, 0x12, 0x12, 0x23, 0x5c, 0x00, 0x00,
-+ 0x80, 0xf0, 0x90, 0xf0, 0x90, 0xf0, 0xf8, 0xf0,
-+ 0x00, 0xfc, 0x90, 0x60, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7e, 0x02, 0x7e, 0x02, 0x3a, 0x2a, 0x2a,
-+ 0x2a, 0x3a, 0x2a, 0x02, 0x02, 0x0d, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x50, 0x50, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x04, 0x12, 0x09, 0x07, 0x19, 0x6f,
-+ 0x09, 0x09, 0x0f, 0x01, 0x01, 0x7e, 0x00, 0x00,
-+ 0x00, 0xf8, 0x90, 0x60, 0x80, 0xc0, 0x30, 0xec,
-+ 0x20, 0x20, 0xe0, 0x10, 0xf8, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x21, 0x21, 0x21, 0x3f, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x1f, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08,
-+ 0x00, 0x00, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x12, 0x12, 0x13, 0x1e,
-+ 0x72, 0x12, 0x12, 0x12, 0x12, 0x31, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x48, 0xf8, 0x08,
-+ 0x00, 0x00, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7d, 0x17, 0x10, 0x11, 0x1a,
-+ 0x77, 0x12, 0x13, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x10, 0xe8, 0x48, 0x50, 0xfc, 0xe0, 0x50, 0x48,
-+ 0xfc, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x7f, 0x1f, 0x12, 0x1f, 0x14, 0x7f, 0x1c,
-+ 0x3e, 0x2a, 0x3e, 0x7f, 0x09, 0x0a, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf0, 0x90, 0xf0, 0x00, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x88, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x7f, 0x09, 0x19, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x09, 0x09, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x48, 0xf8, 0x08,
-+ 0x00, 0x00, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x22, 0x22, 0x03, 0x13,
-+ 0x12, 0x12, 0x24, 0x24, 0x49, 0x56, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x48, 0x50, 0x40, 0xf8, 0x08,
-+ 0x90, 0x90, 0x60, 0x60, 0x90, 0x0c, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x22, 0x22, 0x02, 0x12,
-+ 0x12, 0x12, 0x24, 0x24, 0x48, 0x50, 0x00, 0x00,
-+ 0x20, 0xc0, 0x08, 0x30, 0xc0, 0xc8, 0xc8, 0xb0,
-+ 0xa0, 0x90, 0x90, 0x88, 0x84, 0x80, 0x00, 0x00,
-+ 0x00, 0x3e, 0x08, 0x3e, 0x08, 0x0e, 0x70, 0x1f,
-+ 0x11, 0x1f, 0x10, 0x10, 0x10, 0x0f, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0xf0,
-+ 0x10, 0xf0, 0x10, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x7e, 0x11, 0x11, 0x11, 0x21, 0x3d, 0x65,
-+ 0x25, 0x25, 0x26, 0x3e, 0x25, 0x0e, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x28, 0x30, 0x20, 0xf8, 0x88,
-+ 0x50, 0x50, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x30, 0x0b, 0x62, 0x0b, 0x12, 0x24, 0x27, 0x09,
-+ 0x7f, 0x02, 0x07, 0x08, 0x03, 0x3c, 0x00, 0x00,
-+ 0x40, 0xfc, 0x48, 0xf8, 0x90, 0x60, 0x9c, 0x00,
-+ 0xfc, 0x20, 0x40, 0xe0, 0x10, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x0f, 0x08, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x29, 0x24, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0xf8, 0x80, 0xf0, 0x80,
-+ 0xf0, 0x80, 0xfc, 0x24, 0x94, 0x38, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x04, 0x1f, 0x11, 0x11,
-+ 0x1f, 0x10, 0x10, 0x10, 0x10, 0x0f, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x10, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x11, 0x1f,
-+ 0x00, 0x09, 0x24, 0x24, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xfc,
-+ 0x04, 0x24, 0x94, 0x04, 0x04, 0x38, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x17, 0x10, 0x30, 0x57, 0x10,
-+ 0x10, 0x17, 0x10, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xa0, 0xbc, 0xa0, 0xa0, 0xbc, 0xa0,
-+ 0xa0, 0xbc, 0xa0, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x13, 0x18, 0x15, 0x12, 0x1f,
-+ 0x11, 0x1f, 0x21, 0x22, 0x44, 0x18, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0x90, 0xd4, 0x24, 0x18, 0xf8,
-+ 0x44, 0xf8, 0x40, 0x40, 0x44, 0x3c, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x13, 0x10, 0x10, 0x13,
-+ 0x18, 0x70, 0x17, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x40, 0xf8, 0x40, 0x40, 0xf8,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x10, 0x10, 0x17, 0x18,
-+ 0x70, 0x17, 0x10, 0x11, 0x12, 0x34, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xa0, 0xbc, 0xa0, 0xa0, 0xbc, 0xa0,
-+ 0xa0, 0xbc, 0xa0, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x3f, 0x22,
-+ 0x22, 0x3e, 0x14, 0x12, 0x22, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x90, 0x90, 0x50,
-+ 0x50, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x7e, 0x08, 0x1c, 0x1a, 0x1a,
-+ 0x28, 0x29, 0x4a, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x20, 0x70, 0x68, 0xa8,
-+ 0xa4, 0x24, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x7f, 0x00, 0x03, 0x0d, 0x71, 0x01, 0x1f,
-+ 0x12, 0x12, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0xc0, 0x30, 0x08, 0x04, 0xf0,
-+ 0x90, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x28, 0x28, 0x2b, 0x2a, 0x3f, 0x22, 0x23, 0x3a,
-+ 0x28, 0x29, 0x2f, 0x28, 0x28, 0x48, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0xa8,
-+ 0xa0, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x04, 0x04, 0x7c, 0x04, 0x1c, 0x64, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x80, 0x88, 0xf0, 0x80, 0x84, 0x7c, 0xe0, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x27, 0x3c, 0x24, 0x25, 0x3d,
-+ 0x25, 0x25, 0x25, 0x25, 0x24, 0x4c, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0xfc, 0x24,
-+ 0x24, 0x24, 0x24, 0x2c, 0x20, 0x20, 0x00, 0x00,
-+ 0x02, 0x7e, 0x02, 0x3e, 0x7f, 0x05, 0x7f, 0x0f,
-+ 0x09, 0x0f, 0x09, 0x0f, 0x7f, 0x01, 0x00, 0x00,
-+ 0x40, 0x7c, 0x40, 0x78, 0x7c, 0x40, 0xfc, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x78, 0x48, 0x40,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x12, 0x11, 0x31, 0x5f, 0x10,
-+ 0x13, 0x12, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0x10, 0x20, 0xfc, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x10, 0x13, 0x11, 0x7c, 0x10, 0x17, 0x10,
-+ 0x11, 0x1d, 0x61, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0x90, 0xa0, 0xfc, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x10, 0x7c, 0x24, 0x24, 0x24,
-+ 0x7f, 0x48, 0x0d, 0x16, 0x24, 0x40, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x90, 0xf0, 0x90, 0xf0, 0x40,
-+ 0xfc, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x0a, 0x18, 0x1c, 0x1b,
-+ 0x2a, 0x28, 0x49, 0x09, 0x08, 0x08, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xf8, 0xa8, 0xa8, 0xfc,
-+ 0xa8, 0xa8, 0xfc, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x7e, 0x08, 0x18, 0x1c, 0x1a,
-+ 0x2b, 0x28, 0x49, 0x0e, 0x08, 0x08, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x90, 0xf0, 0x90, 0xf0, 0x40,
-+ 0xfc, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x0a, 0x2c, 0x28, 0x28, 0x48,
-+ 0x0b, 0x08, 0x14, 0x13, 0x26, 0x40, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x90, 0xf0, 0x90, 0xf0, 0x40,
-+ 0xfc, 0xe0, 0xd0, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x04, 0x45, 0x29, 0x11, 0x31, 0x49, 0x09, 0x19,
-+ 0x19, 0x29, 0x48, 0x08, 0x09, 0x32, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0xf8, 0x08,
-+ 0x08, 0xf8, 0x90, 0x88, 0x04, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x00, 0x0f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x00, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x1f, 0x00, 0x3f, 0x20,
-+ 0x44, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x00, 0xfc, 0x08,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x3e, 0x23, 0x22, 0x3e, 0x22, 0x3f, 0x22,
-+ 0x22, 0x3e, 0x14, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x48, 0x50, 0xfc, 0x00,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x29, 0x28, 0x30, 0x2b, 0x24,
-+ 0x25, 0x25, 0x39, 0x21, 0x21, 0x21, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0x90, 0xa0, 0xfc, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x21, 0x10, 0x17, 0x00, 0x01, 0x70, 0x11,
-+ 0x10, 0x11, 0x11, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x00, 0xf0, 0x00, 0xf0,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x28, 0x0c, 0x0a, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0x20, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0xf8, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x02, 0x0d, 0x38, 0x09, 0x08, 0x7e, 0x08, 0x1d,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x28, 0xa8, 0xb0, 0x20, 0xfc,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x11, 0x10, 0x3e, 0x29, 0x49, 0x09, 0x7f,
-+ 0x09, 0x0c, 0x12, 0x12, 0x20, 0x41, 0x00, 0x00,
-+ 0x08, 0xc8, 0x48, 0x48, 0xc8, 0x08, 0x08, 0xc8,
-+ 0x48, 0x48, 0x48, 0x48, 0x48, 0x88, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x06, 0x38, 0x08, 0x7e,
-+ 0x1c, 0x1b, 0x2a, 0x48, 0x08, 0x09, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x20, 0x24, 0xa4, 0xa8,
-+ 0xb0, 0x20, 0x50, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x10, 0x13, 0x32, 0x52, 0x12,
-+ 0x13, 0x12, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x80, 0xf8, 0x08, 0x08, 0x08,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3e, 0x02, 0x3e, 0x02, 0x7f, 0x04, 0x25,
-+ 0x15, 0x16, 0x1d, 0x64, 0x04, 0x0c, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0xc8, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x88, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x13, 0x7e, 0x13, 0x12, 0x13,
-+ 0x10, 0x17, 0x11, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x48, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x10, 0xfc, 0x10, 0x90, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x11, 0x11, 0x11, 0x1d,
-+ 0x71, 0x11, 0x11, 0x11, 0x11, 0x31, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0x80, 0xf8, 0x08, 0x08, 0x08,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x09, 0x19, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0xf8, 0x08, 0x08, 0x08, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x43, 0x22, 0x22, 0x02, 0x13,
-+ 0x12, 0x12, 0x22, 0x22, 0x43, 0x42, 0x00, 0x00,
-+ 0x40, 0x40, 0x80, 0xf8, 0x08, 0x08, 0x08, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x1f, 0x10, 0x10, 0x10, 0x1f,
-+ 0x10, 0x10, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0,
-+ 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x24, 0x43, 0x10, 0x09, 0x41,
-+ 0x29, 0x09, 0x11, 0x11, 0x21, 0x21, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x30, 0x40, 0xf8, 0x08,
-+ 0x08, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2a, 0x2c, 0x08, 0x7e, 0x08, 0x1c,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0xf8, 0x88, 0x88, 0x88, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x04, 0x08, 0x1e, 0x12, 0x1a, 0x16, 0x16, 0x7f,
-+ 0x12, 0x1a, 0x1a, 0x2a, 0x22, 0x46, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0xf8, 0x88, 0x88, 0x88, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x10, 0x0f, 0x4b, 0x22, 0x23,
-+ 0x12, 0x13, 0x2f, 0x21, 0x40, 0x40, 0x00, 0x00,
-+ 0x40, 0xfc, 0x50, 0x48, 0xfc, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xf8, 0xfc, 0x10, 0x90, 0x30, 0x00, 0x00,
-+ 0x00, 0x20, 0x11, 0x13, 0x02, 0x02, 0x73, 0x12,
-+ 0x12, 0x12, 0x13, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x80, 0x80, 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10,
-+ 0x10, 0x10, 0xf0, 0x10, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x79, 0x49, 0x49, 0x49, 0x78, 0x4b, 0x48,
-+ 0x4f, 0x49, 0x7b, 0x4c, 0x43, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0xf0, 0xa0, 0xf8, 0xa0,
-+ 0xfc, 0x50, 0x58, 0xe4, 0x58, 0xc0, 0x00, 0x00,
-+ 0x11, 0x09, 0x0f, 0x41, 0x23, 0x22, 0x03, 0x12,
-+ 0x13, 0x10, 0x2f, 0x20, 0x43, 0x4c, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x80, 0xfc, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x15, 0x35, 0x38, 0x33, 0x50,
-+ 0x17, 0x19, 0x17, 0x24, 0x23, 0x40, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0xf0, 0xa0, 0xf8, 0xa0,
-+ 0xfc, 0x50, 0x58, 0xe4, 0x58, 0xc0, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x64, 0x2b, 0x1a, 0x27, 0x7e,
-+ 0x13, 0x38, 0x37, 0x35, 0x50, 0x10, 0x00, 0x00,
-+ 0x50, 0x48, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0x10, 0xfc, 0x10, 0x90, 0x30, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x1f, 0x10, 0x1f, 0x10,
-+ 0x1f, 0x01, 0x7f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3e, 0x28, 0x3f,
-+ 0x0a, 0x3e, 0x3a, 0x32, 0x42, 0x0d, 0x00, 0x00,
-+ 0x08, 0x08, 0xd0, 0x30, 0x28, 0x44, 0x88, 0x48,
-+ 0x50, 0x30, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x01,
-+ 0x03, 0x0e, 0x31, 0x01, 0x06, 0x78, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x00,
-+ 0xf0, 0x20, 0x40, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x02, 0x42, 0x47, 0x51, 0x49, 0x4b,
-+ 0x45, 0x59, 0x43, 0x40, 0x7f, 0x40, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0x08, 0x28, 0x28, 0xc8, 0x48,
-+ 0x28, 0x28, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x28, 0x45, 0x08, 0x08, 0x7f,
-+ 0x08, 0x1c, 0x1a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0x00, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x7e, 0x11, 0x12, 0x10, 0x3c, 0x24, 0x65,
-+ 0x27, 0x25, 0x3d, 0x21, 0x21, 0x01, 0x00, 0x00,
-+ 0xa0, 0x90, 0x08, 0x48, 0x40, 0xa0, 0xa0, 0x10,
-+ 0xf8, 0x14, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x1f, 0x01, 0x7f, 0x03,
-+ 0x0f, 0x74, 0x07, 0x04, 0x07, 0x04, 0x00, 0x00,
-+ 0x40, 0xfc, 0xa0, 0x10, 0xf8, 0x20, 0xfc, 0x00,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x7f, 0x3e, 0x23, 0x3e, 0x21, 0x4f, 0x7f,
-+ 0x01, 0x0f, 0x3f, 0x01, 0x7f, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x48, 0x30, 0xcc, 0xe0, 0xfc,
-+ 0x20, 0xe0, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x14, 0x23, 0x5f, 0x01, 0x7f,
-+ 0x01, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x18, 0xe0, 0x00, 0xfc,
-+ 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x1a, 0x36, 0x36,
-+ 0x32, 0x54, 0x55, 0x19, 0x11, 0x17, 0x00, 0x00,
-+ 0x70, 0xfc, 0x58, 0xe8, 0xf8, 0xa8, 0xf8, 0xa8,
-+ 0xf8, 0x00, 0xf8, 0x68, 0x68, 0xfc, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7d, 0x57, 0x54, 0x55, 0x57,
-+ 0x55, 0x5d, 0x51, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x18, 0xe8, 0x48, 0x50, 0xfc, 0xe0, 0x50, 0xf8,
-+ 0x54, 0xf0, 0x50, 0x50, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x24, 0x3c,
-+ 0x24, 0x24, 0x24, 0x25, 0x25, 0x4e, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0x90, 0x90, 0x94, 0x14, 0x14, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x0a, 0x2a, 0x2c, 0x28, 0x48,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xa8, 0xa8, 0xf8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xf8, 0x88, 0x00, 0x00, 0x00,
-+ 0x01, 0x02, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x00,
-+ 0x3f, 0x21, 0x3f, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x07, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x08,
-+ 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0xc0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x20,
-+ 0x20, 0x20, 0x10, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x23, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2b, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x70, 0x70, 0xa8,
-+ 0xa8, 0x24, 0xf8, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x23, 0x10, 0x15, 0x43, 0x22, 0x27, 0x09, 0x01,
-+ 0x1f, 0x11, 0x21, 0x22, 0x44, 0x58, 0x00, 0x00,
-+ 0x90, 0x90, 0x64, 0x28, 0x10, 0xf8, 0x24, 0x20,
-+ 0xfc, 0x20, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x1e, 0x02, 0x24, 0x14, 0x08, 0x1f, 0x22, 0x42,
-+ 0x3f, 0x02, 0x04, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x90, 0x90, 0x64, 0x44, 0x28, 0xf0, 0x48, 0x44,
-+ 0xf8, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x21, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x68, 0x28, 0xd4, 0x54, 0x88, 0xfc, 0x50, 0x50,
-+ 0xfc, 0x50, 0x50, 0x94, 0x94, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x12, 0x3f, 0x01,
-+ 0x7f, 0x02, 0x07, 0x1a, 0x61, 0x1e, 0x00, 0x00,
-+ 0x10, 0x60, 0x88, 0x30, 0xc4, 0x18, 0xe0, 0x00,
-+ 0xfc, 0x00, 0xf0, 0x20, 0xc0, 0x7c, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x08, 0x08, 0x1f, 0x28, 0x48,
-+ 0x08, 0x08, 0x08, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0x40, 0x7c, 0xc8, 0x48, 0x50,
-+ 0x30, 0x20, 0x64, 0x94, 0x0c, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x00, 0x1e, 0x7f, 0x00,
-+ 0x1e, 0x1e, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x00, 0x48, 0xc8, 0x48,
-+ 0x48, 0x48, 0x48, 0x48, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x10, 0x10, 0x10, 0x1c,
-+ 0x70, 0x11, 0x11, 0x12, 0x14, 0x3b, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x80, 0x80, 0xf8, 0x88,
-+ 0xc8, 0x50, 0x30, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x14, 0x23, 0x44, 0x04, 0x0b,
-+ 0x18, 0x28, 0x48, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0x50, 0x48, 0xfc,
-+ 0x48, 0x30, 0x20, 0xd4, 0x0c, 0x04, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x25, 0x25,
-+ 0x29, 0x3f, 0x28, 0x2b, 0x28, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x48, 0x28,
-+ 0xe8, 0x48, 0xa8, 0x68, 0x28, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x15, 0x15, 0x15, 0x17,
-+ 0x17, 0x13, 0x21, 0x22, 0x42, 0x04, 0x00, 0x00,
-+ 0x40, 0x80, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xfc,
-+ 0x00, 0xfc, 0x54, 0xac, 0x84, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x54, 0x52, 0x53, 0x5f, 0x52,
-+ 0x5f, 0x77, 0x56, 0x4a, 0x12, 0x02, 0x00, 0x00,
-+ 0x04, 0x08, 0xf0, 0xa0, 0xa0, 0x3c, 0xe8, 0x28,
-+ 0xe8, 0x28, 0xa8, 0xc8, 0x48, 0x88, 0x00, 0x00,
-+ 0x00, 0x10, 0x17, 0x10, 0x7d, 0x11, 0x11, 0x10,
-+ 0x17, 0x1c, 0x65, 0x05, 0x05, 0x04, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x00,
-+ 0xf8, 0x08, 0xe8, 0x28, 0xe8, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2b, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0xfc, 0x00, 0x00,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x18, 0x2f, 0x48, 0x0f, 0x08,
-+ 0x0f, 0x01, 0x7f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x80, 0xf0, 0x80, 0xf0, 0x80,
-+ 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x0a, 0x09, 0x11, 0x10, 0x33, 0x50, 0x10,
-+ 0x17, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0x50, 0x40, 0xf8, 0x40, 0x40,
-+ 0xfc, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x49, 0x29, 0x2a, 0x08, 0x7f, 0x08, 0x08,
-+ 0x7f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x11, 0x09, 0x09, 0x3f, 0x01, 0x01,
-+ 0x7f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x10, 0x10, 0x20, 0xf8, 0x00, 0x00,
-+ 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x12, 0x12, 0x12,
-+ 0x11, 0x11, 0x10, 0x21, 0x26, 0x58, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0xf0, 0x10, 0x10, 0x20,
-+ 0x20, 0x40, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x08, 0x0a, 0x4a, 0x2c, 0x28, 0x7e, 0x08, 0x08,
-+ 0x0f, 0x79, 0x11, 0x12, 0x22, 0x44, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xf8, 0x88, 0x88, 0xc8,
-+ 0x50, 0x30, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x55, 0x55, 0x55, 0x55,
-+ 0x55, 0x5d, 0x51, 0x12, 0x12, 0x14, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0x90, 0x50, 0x50,
-+ 0x50, 0x10, 0x10, 0x14, 0x14, 0x0c, 0x00, 0x00,
-+ 0x12, 0x12, 0x17, 0x7c, 0x16, 0x15, 0x15, 0x1f,
-+ 0x74, 0x16, 0x16, 0x1a, 0x18, 0x31, 0x00, 0x00,
-+ 0x00, 0x38, 0xa8, 0xa8, 0xac, 0xac, 0xc4, 0xf8,
-+ 0xa8, 0xa8, 0x90, 0xb0, 0xc8, 0x84, 0x00, 0x00,
-+ 0x01, 0x7d, 0x11, 0x17, 0x10, 0x14, 0x7a, 0x13,
-+ 0x11, 0x11, 0x1e, 0x62, 0x04, 0x08, 0x00, 0x00,
-+ 0x00, 0x7c, 0x10, 0xd0, 0x90, 0x90, 0xfc, 0x10,
-+ 0x10, 0x10, 0x90, 0x90, 0x7c, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x7f, 0x09, 0x19, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x0a, 0x0a, 0x0d, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x88, 0x88, 0x50,
-+ 0x50, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x09, 0x09, 0x41, 0x21, 0x21, 0x01, 0x09,
-+ 0x09, 0x09, 0x11, 0x11, 0x21, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x30,
-+ 0x00, 0x00, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x09, 0x09, 0x41, 0x21, 0x21, 0x01, 0x09,
-+ 0x09, 0x09, 0x11, 0x12, 0x22, 0x24, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0x90, 0x50, 0x50,
-+ 0x10, 0x10, 0x10, 0x14, 0x14, 0x0c, 0x00, 0x00,
-+ 0x28, 0x29, 0x29, 0x29, 0x3f, 0x21, 0x21, 0x3d,
-+ 0x25, 0x25, 0x26, 0x26, 0x45, 0x46, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x88, 0x88, 0x50,
-+ 0x50, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x04, 0x45, 0x29, 0x11, 0x31, 0x49, 0x09, 0x19,
-+ 0x29, 0x49, 0x09, 0x09, 0x09, 0x30, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x30,
-+ 0x00, 0x00, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x7c, 0x12, 0x12, 0x12, 0x12, 0x7e, 0x12,
-+ 0x12, 0x10, 0x1d, 0x61, 0x02, 0x04, 0x00, 0x00,
-+ 0x80, 0xfc, 0x90, 0x90, 0x90, 0x90, 0xfc, 0x90,
-+ 0x90, 0x90, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x02, 0x7d, 0x55, 0x54, 0x57, 0x7c, 0x54,
-+ 0x57, 0x54, 0x7c, 0x44, 0x40, 0x00, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0x50, 0x40, 0xf8, 0x40, 0x40,
-+ 0xfc, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x3f, 0x5f, 0x15, 0x7f, 0x15, 0x3f, 0x23,
-+ 0x0c, 0x03, 0x3f, 0x0d, 0x31, 0x01, 0x00, 0x00,
-+ 0x40, 0xc0, 0x7c, 0xc8, 0x48, 0x30, 0xd8, 0x44,
-+ 0xc0, 0x30, 0xc8, 0x60, 0x18, 0x00, 0x00, 0x00,
-+ 0x04, 0x08, 0x1e, 0x12, 0x1a, 0x16, 0x17, 0x7f,
-+ 0x12, 0x1a, 0x1a, 0x2a, 0x22, 0x47, 0x00, 0x00,
-+ 0x00, 0x70, 0x50, 0x50, 0x54, 0x94, 0x0c, 0xf8,
-+ 0x88, 0x50, 0x50, 0x20, 0x50, 0x8c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x10, 0x0b, 0x49, 0x27, 0x20,
-+ 0x0b, 0x0d, 0x11, 0x11, 0x21, 0x21, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x38, 0xc8, 0x50, 0xfc, 0xe0,
-+ 0xf8, 0x54, 0xf0, 0x50, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x3e, 0x22,
-+ 0x22, 0x3e, 0x19, 0x15, 0x22, 0x47, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xf8, 0xc8, 0xc8, 0xc8,
-+ 0xa8, 0xb0, 0x10, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x4d, 0x7f, 0x08, 0x3e, 0x2a,
-+ 0x3e, 0x2a, 0x3e, 0x08, 0x7f, 0x08, 0x00, 0x00,
-+ 0x40, 0xfc, 0xa0, 0x10, 0xf8, 0x88, 0x88, 0x88,
-+ 0x88, 0xb0, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x01, 0x3f, 0x11, 0x09, 0x09, 0x7f, 0x01,
-+ 0x03, 0x05, 0x19, 0x61, 0x01, 0x01, 0x00, 0x00,
-+ 0x30, 0xc0, 0x10, 0x10, 0x20, 0x40, 0xfc, 0x00,
-+ 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x0a, 0x2b, 0x2d, 0x29, 0x49,
-+ 0x09, 0x0d, 0x13, 0x12, 0x21, 0x46, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x08, 0xf8, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x1c, 0x05, 0x14, 0x14, 0x12, 0x22, 0x3f, 0x52,
-+ 0x12, 0x12, 0x12, 0x22, 0x2d, 0x42, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x0c, 0x12, 0x2a, 0x48, 0x3e, 0x22, 0x3e,
-+ 0x22, 0x3e, 0x24, 0x27, 0x39, 0x63, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xf8, 0xc8, 0xc8, 0xc8,
-+ 0xa8, 0xb0, 0x90, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7e, 0x17, 0x12, 0x12, 0x1f,
-+ 0x72, 0x10, 0x10, 0x11, 0x12, 0x34, 0x00, 0x00,
-+ 0x80, 0xf0, 0x20, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x68, 0xa0, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x00, 0x79, 0x4a, 0x4f, 0x4a, 0x7a, 0x4b,
-+ 0x4a, 0x48, 0x79, 0x49, 0x42, 0x04, 0x00, 0x00,
-+ 0x80, 0xf0, 0x20, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0xa8, 0xa0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x11, 0x09, 0x7f, 0x03, 0x05, 0x19,
-+ 0x7f, 0x11, 0x1f, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x30, 0xd0, 0x10, 0x20, 0xfc, 0x80, 0x40, 0x30,
-+ 0xfc, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x3e, 0x32, 0x2a, 0x7f, 0x2a, 0x2a, 0x47,
-+ 0x1f, 0x12, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x70, 0x54, 0x8c, 0xf8, 0x50, 0x70, 0x8c,
-+ 0xf0, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x3e, 0x32, 0x2a, 0x7f, 0x2a, 0x2a, 0x47,
-+ 0x3f, 0x02, 0x0f, 0x74, 0x07, 0x04, 0x00, 0x00,
-+ 0x00, 0x70, 0x54, 0x8c, 0xf8, 0x50, 0x30, 0xcc,
-+ 0xf8, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x1f, 0x09, 0x7f, 0x05, 0x19,
-+ 0x6f, 0x09, 0x0f, 0x09, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0xfc, 0x60, 0xd0, 0x20, 0xfc, 0x40, 0x30,
-+ 0xec, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x12, 0x12, 0x24, 0x49, 0x0f,
-+ 0x09, 0x09, 0x0f, 0x09, 0x01, 0x3e, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x50, 0x48, 0x44, 0xc4, 0xe0,
-+ 0x20, 0x20, 0xe0, 0x20, 0xf0, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x21, 0x2f, 0x21, 0x2f, 0x21,
-+ 0x2f, 0x22, 0x22, 0x24, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x78, 0x40, 0x78, 0x40,
-+ 0x78, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x02, 0x04, 0x1f, 0x11, 0x11, 0x1f, 0x11, 0x1f,
-+ 0x04, 0x08, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x03, 0x05, 0x19, 0x61, 0x01,
-+ 0x1f, 0x10, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xc0, 0x30, 0x08, 0x04, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7e, 0x12, 0x12, 0x12,
-+ 0x3c, 0x24, 0x06, 0x0a, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x88, 0x80,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x14, 0x14, 0x14, 0x17,
-+ 0x14, 0x14, 0x14, 0x25, 0x26, 0x58, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x40, 0x40, 0x44, 0xc8,
-+ 0x70, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x10, 0x10, 0x23, 0x4a, 0x0a, 0x12, 0x13, 0x32,
-+ 0x52, 0x12, 0x12, 0x14, 0x15, 0x1e, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x48, 0x50, 0x40, 0xf8, 0x88,
-+ 0x90, 0x50, 0x60, 0x60, 0x90, 0x0c, 0x00, 0x00,
-+ 0x02, 0x02, 0x3e, 0x02, 0x3e, 0x02, 0x7e, 0x04,
-+ 0x01, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x80, 0x80, 0xf8, 0x80, 0xf8, 0x80, 0xfc, 0x80,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x1f, 0x10, 0x1f, 0x11, 0x1f,
-+ 0x11, 0x1f, 0x21, 0x3e, 0x42, 0x04, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0x40, 0x78,
-+ 0x40, 0x78, 0x40, 0x7c, 0x40, 0x40, 0x00, 0x00,
-+ 0x12, 0x12, 0x12, 0x7e, 0x12, 0x13, 0x12, 0x1e,
-+ 0x72, 0x12, 0x12, 0x12, 0x13, 0x3c, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x24, 0x24, 0xe8, 0x30, 0x20,
-+ 0x20, 0x20, 0x20, 0xe4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x12, 0x12, 0x13, 0x1e,
-+ 0x72, 0x12, 0x12, 0x14, 0x15, 0x3e, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x48, 0x50, 0x40, 0xf8, 0x88,
-+ 0x90, 0x50, 0x60, 0x60, 0x90, 0x0c, 0x00, 0x00,
-+ 0x02, 0x3e, 0x02, 0x3e, 0x02, 0x7c, 0x05, 0x09,
-+ 0x7f, 0x04, 0x02, 0x03, 0x0c, 0x70, 0x00, 0x00,
-+ 0x40, 0x7c, 0x40, 0x7c, 0x40, 0x7c, 0x40, 0x00,
-+ 0xfc, 0x40, 0x80, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x1f, 0x10, 0x10,
-+ 0x10, 0x10, 0x11, 0x16, 0x18, 0x60, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0x88, 0x88, 0x90, 0xa0, 0xc0,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x40, 0x20, 0x22, 0x02, 0x12,
-+ 0x14, 0x14, 0x28, 0x21, 0x42, 0x44, 0x00, 0x00,
-+ 0x40, 0x28, 0x28, 0x88, 0x90, 0x90, 0xb0, 0xa8,
-+ 0xc4, 0xc4, 0x80, 0x88, 0x88, 0x78, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x2b, 0x2a, 0x0a, 0x1b,
-+ 0x2b, 0x4a, 0x12, 0x14, 0x25, 0x4e, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x40, 0xfc, 0x48, 0x50, 0xf0,
-+ 0x10, 0xa0, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x10, 0x10, 0x1f, 0x12,
-+ 0x11, 0x11, 0x10, 0x20, 0x23, 0x4c, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x88, 0x90, 0x80, 0xf0, 0x10,
-+ 0x20, 0x20, 0xc0, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7c, 0x10, 0x13, 0x12, 0x13, 0x3e, 0x27,
-+ 0x64, 0x25, 0x27, 0x3c, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x80, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0xa0, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x04, 0x18, 0x70, 0x10, 0x10, 0x7e, 0x12, 0x1a,
-+ 0x36, 0x34, 0x50, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x40, 0x20, 0x28, 0x88, 0x88, 0x90, 0x90, 0xb0,
-+ 0xa8, 0xc4, 0x84, 0x88, 0x88, 0x78, 0x00, 0x00,
-+ 0x10, 0x10, 0x14, 0x67, 0x18, 0x10, 0x2b, 0x7c,
-+ 0x18, 0x37, 0x35, 0x31, 0x52, 0x14, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xa0, 0xbc, 0xa0, 0xa0, 0xbc, 0xa0,
-+ 0xa0, 0xbc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x08, 0x12, 0x7f, 0x3e,
-+ 0x22, 0x3e, 0x22, 0x3e, 0x22, 0x26, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x40, 0x58, 0x60, 0x44,
-+ 0x3c, 0x40, 0x58, 0x60, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x25, 0x3d, 0x25, 0x25,
-+ 0x3d, 0x25, 0x25, 0x25, 0x25, 0x4c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x48, 0xf8, 0x08,
-+ 0x00, 0x00, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x09, 0x0b, 0x13, 0x3d,
-+ 0x55, 0x13, 0x12, 0x12, 0x15, 0x1e, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x28, 0x30, 0xf8, 0x88,
-+ 0x50, 0x50, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7f, 0x00, 0x3c, 0x03, 0x3c,
-+ 0x00, 0x3c, 0x27, 0x24, 0x3d, 0x26, 0x00, 0x00,
-+ 0x50, 0x50, 0x50, 0xdc, 0x50, 0x50, 0xdc, 0x50,
-+ 0x50, 0xdc, 0x90, 0x90, 0x10, 0x10, 0x00, 0x00,
-+ 0x02, 0x3f, 0x02, 0x3f, 0x3f, 0x44, 0x1f, 0x68,
-+ 0x0f, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x80, 0xf8, 0x88, 0xf8, 0xfc, 0x84, 0xf8, 0x20,
-+ 0xe0, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x00, 0x27, 0x14, 0x14, 0x07, 0x04, 0x77, 0x1c,
-+ 0x14, 0x14, 0x17, 0x1c, 0x26, 0x41, 0x00, 0x00,
-+ 0x10, 0x90, 0xfc, 0xc8, 0xa8, 0x30, 0xfc, 0x90,
-+ 0x90, 0xfc, 0x90, 0x10, 0x10, 0xfc, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x3e, 0x02, 0x02, 0x3e, 0x02,
-+ 0x02, 0x7e, 0x04, 0x04, 0x08, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x7c, 0x40,
-+ 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x1f, 0x02, 0x0e, 0x32, 0x12, 0x12, 0x7f,
-+ 0x12, 0x12, 0x22, 0x22, 0x42, 0x02, 0x00, 0x00,
-+ 0x00, 0xc8, 0x70, 0x50, 0x48, 0x28, 0x18, 0xc8,
-+ 0x50, 0x70, 0x28, 0x24, 0x14, 0x0c, 0x00, 0x00,
-+ 0x10, 0x15, 0x12, 0x7e, 0x10, 0x10, 0x3e, 0x36,
-+ 0x36, 0x52, 0x52, 0x12, 0x15, 0x18, 0x00, 0x00,
-+ 0x00, 0xf8, 0x50, 0x20, 0xf8, 0xa8, 0xf8, 0xa8,
-+ 0xf8, 0xa8, 0xa8, 0x98, 0x80, 0x7c, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x12, 0x7f, 0x12, 0x1e,
-+ 0x12, 0x1e, 0x12, 0x7f, 0x15, 0x63, 0x00, 0x00,
-+ 0x40, 0xfc, 0xa0, 0x10, 0x20, 0xfc, 0xa8, 0xb0,
-+ 0xf8, 0xc8, 0xa8, 0x90, 0x68, 0x84, 0x00, 0x00,
-+ 0x09, 0x09, 0x0f, 0x11, 0x17, 0x34, 0x57, 0x16,
-+ 0x17, 0x16, 0x17, 0x1a, 0x12, 0x12, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0xf8, 0x48,
-+ 0xf8, 0x48, 0xf8, 0x48, 0x48, 0x18, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x17, 0x10,
-+ 0x17, 0x10, 0x1f, 0x20, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x68, 0x80, 0xf0,
-+ 0x80, 0xfc, 0x80, 0x80, 0x84, 0x7c, 0x00, 0x00,
-+ 0x12, 0x1a, 0x2a, 0x4a, 0x1f, 0x18, 0x20, 0x7f,
-+ 0x26, 0x26, 0x2a, 0x2b, 0x32, 0x20, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xa0, 0xfc, 0x48, 0xc8, 0xe8,
-+ 0x28, 0x30, 0x90, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x09, 0x09, 0x09, 0x7f, 0x09, 0x19, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x09, 0x09, 0x0e, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x24, 0x24, 0xe8, 0x30, 0x20,
-+ 0x20, 0x20, 0x20, 0x64, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x11, 0x1f, 0x11, 0x1f, 0x10,
-+ 0x10, 0x1f, 0x10, 0x10, 0x1e, 0x70, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0xf0, 0x80,
-+ 0x98, 0xe0, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x7e, 0x08, 0x3e, 0x08, 0x0e, 0x70, 0x10,
-+ 0x10, 0x1f, 0x10, 0x10, 0x1e, 0x70, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x80, 0x80,
-+ 0x98, 0xe0, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x11, 0x1f, 0x10, 0x17, 0x14,
-+ 0x17, 0x14, 0x27, 0x24, 0x47, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x04, 0x04, 0x3f, 0x01, 0x1f, 0x01, 0x7f,
-+ 0x01, 0x7f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0xf8, 0x00, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x0f, 0x08, 0x0f, 0x0f, 0x0f, 0x1f, 0x11,
-+ 0x1f, 0x1f, 0x04, 0x7f, 0x04, 0x18, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0xe0, 0xe0, 0xf0, 0x10,
-+ 0xf0, 0xf0, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7e, 0x08, 0x1d, 0x1a, 0x1a,
-+ 0x28, 0x29, 0x48, 0x09, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0x90, 0x50, 0x20, 0x50,
-+ 0xc8, 0x24, 0x00, 0xc0, 0x30, 0x08, 0x00, 0x00,
-+ 0x04, 0x18, 0x73, 0x12, 0x13, 0x7e, 0x13, 0x18,
-+ 0x35, 0x37, 0x50, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0xa8,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x22, 0x22, 0x22, 0x22, 0x24,
-+ 0x24, 0x28, 0x30, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x40, 0x40, 0x40, 0x40, 0x48,
-+ 0x48, 0x38, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x01, 0x09, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x15, 0x13, 0x21, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0x10, 0x20, 0x00, 0x00, 0xf0,
-+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x7c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x12, 0x3f, 0x04,
-+ 0x14, 0x17, 0x14, 0x14, 0x17, 0x78, 0x00, 0x00,
-+ 0x10, 0x60, 0x88, 0x30, 0xc4, 0x18, 0xe0, 0x80,
-+ 0x98, 0xe0, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x04, 0x02, 0x1f, 0x10, 0x10,
-+ 0x17, 0x10, 0x13, 0x20, 0x20, 0x47, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x20, 0x40, 0xfc, 0x20, 0xc0,
-+ 0x10, 0x60, 0x84, 0x18, 0x60, 0x80, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x24, 0x3d, 0x26, 0x24, 0x3f,
-+ 0x26, 0x25, 0x24, 0x27, 0x24, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0xa0, 0x58,
-+ 0x4c, 0x50, 0xe0, 0x58, 0x44, 0xc0, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x3f, 0x01, 0x7f, 0x04, 0x1a,
-+ 0x63, 0x06, 0x19, 0x03, 0x0c, 0x70, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x00, 0xfc, 0x88, 0x78,
-+ 0xe0, 0x40, 0x80, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x24, 0x27, 0x3c, 0x25, 0x24,
-+ 0x3c, 0x24, 0x24, 0x24, 0x24, 0x4c, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0xfc, 0x10, 0x10, 0x90,
-+ 0x90, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x78, 0x0f, 0x09, 0x39, 0x23, 0x22, 0x3a,
-+ 0x2b, 0x0a, 0x0a, 0x0b, 0x0a, 0x30, 0x00, 0x00,
-+ 0x00, 0x78, 0xc8, 0x08, 0x38, 0xa0, 0xa0, 0xb8,
-+ 0xa8, 0x88, 0x88, 0x88, 0x88, 0x30, 0x00, 0x00,
-+ 0x02, 0x01, 0x00, 0x04, 0x04, 0x04, 0x24, 0x24,
-+ 0x24, 0x45, 0x46, 0x04, 0x1c, 0x63, 0x00, 0x00,
-+ 0x00, 0x10, 0x90, 0x90, 0x20, 0x20, 0x50, 0x48,
-+ 0x84, 0x04, 0x00, 0x10, 0x10, 0xf0, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x09, 0x7f,
-+ 0x09, 0x1f, 0x01, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x20, 0xfc,
-+ 0x20, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x25, 0x5f, 0x01, 0x7f, 0x01, 0x1f,
-+ 0x01, 0x1f, 0x01, 0x3f, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0xfc, 0x20, 0xf0, 0x10, 0xfc, 0x10, 0xf0,
-+ 0x00, 0xf0, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x27, 0x10, 0x11, 0x01, 0x01, 0x70, 0x13,
-+ 0x12, 0x13, 0x12, 0x13, 0x2c, 0x43, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x48, 0xf8, 0x48, 0xf8, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x11, 0x1b, 0x34, 0x34,
-+ 0x37, 0x50, 0x50, 0x11, 0x17, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xf8, 0x04, 0x00,
-+ 0xfc, 0xa0, 0x90, 0x38, 0xc4, 0x04, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x11, 0x7d, 0x25, 0x25, 0x25,
-+ 0x79, 0x49, 0x0d, 0x15, 0x21, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x20, 0xf8, 0x08, 0x08,
-+ 0xf8, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x11, 0x7f, 0x24, 0x27, 0x24,
-+ 0x74, 0x48, 0x09, 0x16, 0x24, 0x43, 0x00, 0x00,
-+ 0x1c, 0xe4, 0x48, 0x30, 0xfc, 0x40, 0xfc, 0x40,
-+ 0xf8, 0xc8, 0x30, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x0a, 0x72, 0x14, 0x0c, 0x13, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x49, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x48, 0xfc, 0x48,
-+ 0x48, 0x48, 0x48, 0x48, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x02, 0x1f, 0x10, 0x10, 0x10,
-+ 0x1f, 0x10, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x04, 0x7b, 0x02, 0x3c, 0x01, 0x38,
-+ 0x03, 0x3d, 0x28, 0x29, 0x38, 0x2b, 0x00, 0x00,
-+ 0x00, 0xf8, 0xc8, 0xb8, 0xa8, 0xc8, 0x98, 0xc0,
-+ 0x30, 0xcc, 0x20, 0xc8, 0x30, 0xc0, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x10, 0x13, 0x30, 0x57, 0x10,
-+ 0x11, 0x13, 0x15, 0x11, 0x11, 0x16, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0xc0,
-+ 0x48, 0x30, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x04, 0x07, 0x04, 0x3f, 0x29, 0x2e, 0x38, 0x27,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x32, 0x41, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xa8, 0x48, 0x10, 0x94, 0x24,
-+ 0x08, 0x08, 0x10, 0x20, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7f, 0x12, 0x1b, 0x34, 0x35,
-+ 0x30, 0x57, 0x51, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xf8, 0xa8, 0xf8, 0x00, 0xf0,
-+ 0x00, 0xfc, 0x50, 0x48, 0x48, 0xc0, 0x00, 0x00,
-+ 0x01, 0x11, 0x09, 0x09, 0x01, 0x7d, 0x05, 0x09,
-+ 0x09, 0x11, 0x21, 0x41, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x08, 0x88, 0x90, 0x60, 0x40, 0x20,
-+ 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x43, 0x22, 0x23, 0x00, 0x13,
-+ 0x10, 0x17, 0x21, 0x22, 0x44, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xf8, 0xa8, 0xf8, 0x00, 0xf8,
-+ 0x00, 0xfc, 0x50, 0x48, 0x48, 0xc0, 0x00, 0x00,
-+ 0x00, 0x7f, 0x19, 0x7f, 0x5b, 0x7f, 0x01, 0x3d,
-+ 0x01, 0x7f, 0x19, 0x36, 0x53, 0x34, 0x00, 0x00,
-+ 0x08, 0x30, 0xd0, 0x50, 0x50, 0x50, 0x50, 0x50,
-+ 0x50, 0x70, 0x50, 0x78, 0xd8, 0x04, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x1f, 0x12, 0x1f, 0x00, 0x1f,
-+ 0x00, 0x7f, 0x05, 0x19, 0x61, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0xf0, 0x90, 0xf0, 0x00, 0xf0,
-+ 0x00, 0xfc, 0x40, 0x30, 0x08, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x03,
-+ 0x04, 0x1c, 0x64, 0x04, 0x07, 0x38, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x10,
-+ 0x90, 0xa0, 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3d, 0x00, 0x7f, 0x00, 0x3c, 0x00, 0x3f,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x28, 0xa8, 0xb0, 0x20, 0xfc,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x04, 0x18, 0x66, 0x14, 0x19, 0x6a, 0x0c, 0x14,
-+ 0x64, 0x0c, 0x14, 0x64, 0x04, 0x18, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf8, 0x08, 0x08, 0x88, 0x48,
-+ 0x48, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x24, 0x2f, 0x29, 0x2f,
-+ 0x29, 0x2f, 0x24, 0x3f, 0x44, 0x45, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0xf8, 0x48, 0x48, 0x78, 0x48,
-+ 0x48, 0x78, 0x48, 0xc8, 0x88, 0x18, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x7d, 0x11, 0x10, 0x1b, 0x12,
-+ 0x32, 0x53, 0x12, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0x10, 0x00, 0xf8, 0x48,
-+ 0x48, 0xf8, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x2b, 0x28, 0x0b, 0x1a,
-+ 0x6a, 0x0a, 0x13, 0x12, 0x22, 0x42, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xf8, 0x40, 0xf8, 0x48,
-+ 0x68, 0x98, 0x18, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x02, 0x0c, 0x38, 0x08, 0x08, 0x7e, 0x08, 0x1d,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x0b, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xb0, 0xa8, 0xa4, 0xa4, 0x28,
-+ 0x68, 0x30, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x04, 0x1f, 0x11, 0x11,
-+ 0x1f, 0x11, 0x11, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x12, 0x22, 0x7c, 0x09, 0x7f,
-+ 0x09, 0x2b, 0x1d, 0x19, 0x0f, 0x71, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x90, 0x90, 0x00, 0xf8, 0x48,
-+ 0x48, 0xf8, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x09, 0x2a, 0x1c, 0x18, 0x0e, 0x71, 0x00, 0x00,
-+ 0x08, 0xf0, 0x80, 0x80, 0xfc, 0x90, 0x90, 0x90,
-+ 0xfc, 0x00, 0x50, 0x48, 0x84, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x3e, 0x00, 0x7f, 0x08,
-+ 0x2c, 0x2a, 0x2a, 0x49, 0x08, 0x18, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x00, 0xfc, 0x20,
-+ 0xb0, 0xa8, 0xa4, 0x24, 0x20, 0x60, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x3e, 0x2a, 0x2b, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0e, 0x73, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x50, 0x88, 0xfc, 0x24, 0x20,
-+ 0xf8, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x25, 0x7e, 0x2a, 0x3e, 0x2b,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x20, 0xf8, 0x28, 0xfc, 0x68, 0x70, 0xc4, 0x3c,
-+ 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x00,
-+ 0x7c, 0x44, 0x44, 0x44, 0x7c, 0x44, 0x00, 0x00,
-+ 0x00, 0xc0, 0x40, 0x40, 0x40, 0xc0, 0x40, 0x00,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7f, 0x11, 0x19, 0x37, 0x37,
-+ 0x33, 0x55, 0x55, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xe0, 0x08, 0x08, 0x90, 0x50,
-+ 0x64, 0x04, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7f, 0x08, 0x08, 0x4a, 0x2a,
-+ 0x12, 0x12, 0x1a, 0x2a, 0x27, 0x40, 0x00, 0x00,
-+ 0x20, 0xe8, 0x24, 0xfc, 0xa0, 0xa0, 0xa0, 0xe0,
-+ 0x90, 0x90, 0xb4, 0xcc, 0x0c, 0x04, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x23, 0x22, 0x02, 0x12,
-+ 0x1f, 0x20, 0x22, 0x42, 0x44, 0x48, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0x00, 0xf8, 0x20, 0x20, 0x20,
-+ 0xfc, 0x00, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00,
-+ 0x22, 0x12, 0x1a, 0x4b, 0x2a, 0x3f, 0x03, 0x16,
-+ 0x16, 0x2f, 0x29, 0x42, 0x44, 0x49, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0xa0, 0x78, 0xc8, 0x78, 0xc8,
-+ 0xf8, 0x48, 0x78, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x01, 0x04, 0x1f, 0x62, 0x0c, 0x3f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x80, 0x40, 0xf0, 0x4c, 0xc0, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x01, 0x3f, 0x20, 0x5f, 0x09, 0x33, 0x7f, 0x08,
-+ 0x0f, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf0, 0x30, 0xc8, 0xe0, 0x20,
-+ 0xe0, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x08, 0x09, 0x2e, 0x28, 0x28, 0x7f, 0x0c, 0x2a,
-+ 0x29, 0x49, 0x1a, 0x04, 0x18, 0x63, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x3f, 0x40, 0x3e, 0x2a, 0x2b,
-+ 0x7f, 0x2a, 0x2a, 0x7f, 0x43, 0x06, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x7c, 0x88, 0x88, 0x48,
-+ 0x50, 0x30, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x22, 0x13, 0x14, 0x7f, 0x14, 0x14, 0x14, 0x7f,
-+ 0x14, 0x14, 0x14, 0x24, 0x27, 0x44, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xf0, 0x90, 0xd0, 0xb0,
-+ 0xb0, 0x90, 0x94, 0xec, 0x0c, 0x04, 0x00, 0x00,
-+ 0x00, 0x7f, 0x00, 0x00, 0x01, 0x03, 0x05, 0x19,
-+ 0x61, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0x00, 0x80, 0x60, 0x10,
-+ 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x08, 0x0b, 0x18, 0x29, 0x48,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0xfc, 0x10, 0x10, 0x90,
-+ 0x90, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x10, 0x13, 0x12, 0x7f, 0x12, 0x13, 0x12,
-+ 0x13, 0x1c, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x80, 0xf0, 0x10, 0xf0, 0x00, 0xf8, 0x08,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x3f, 0x01, 0x01, 0x01, 0x7f,
-+ 0x01, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfc,
-+ 0x80, 0x80, 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x10, 0x11, 0x10, 0x11, 0x7c, 0x25, 0x24, 0x27,
-+ 0x7a, 0x4b, 0x0e, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x44, 0xf8, 0x48, 0x48, 0x70, 0x40, 0x00, 0x00,
-+ 0x01, 0x3f, 0x20, 0x5f, 0x07, 0x04, 0x07, 0x00,
-+ 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf0, 0xc0, 0x40, 0xc0, 0x00,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x5f, 0x0f, 0x08, 0x0f, 0x00,
-+ 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf0, 0xe0, 0x20, 0xe0, 0x00,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x7f, 0x04, 0x04, 0x0f, 0x08,
-+ 0x18, 0x28, 0x48, 0x08, 0x08, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x80, 0x80, 0xf8, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0xb0, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x11, 0x11, 0x12, 0x13, 0x16,
-+ 0x1a, 0x12, 0x12, 0x22, 0x22, 0x42, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x10, 0x10, 0x10, 0xfc, 0x10,
-+ 0x90, 0x50, 0x50, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x17, 0x38, 0x35, 0x35, 0x53,
-+ 0x15, 0x19, 0x11, 0x11, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0xa0, 0x20, 0xfc, 0x24,
-+ 0x24, 0x24, 0x24, 0x38, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x10, 0x10, 0x10, 0x1f,
-+ 0x70, 0x10, 0x10, 0x11, 0x16, 0x38, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0x40, 0xfc,
-+ 0x40, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x0a, 0x7f, 0x08, 0x3e, 0x2a, 0x3e, 0x2b, 0x3e,
-+ 0x08, 0x7f, 0x1e, 0x12, 0x23, 0x4e, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x90, 0x90, 0x50,
-+ 0x50, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x04, 0x0c, 0x32, 0x03, 0x0c, 0x70, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x60, 0x30, 0x48, 0x80, 0x60, 0xdc, 0x00, 0x00,
-+ 0xf8, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x08, 0x04, 0x3f, 0x22, 0x12, 0x12, 0x7f, 0x00,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x90, 0x90, 0xa0, 0xfc, 0x00,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x44, 0x22, 0x22, 0x03, 0x10,
-+ 0x10, 0x17, 0x20, 0x20, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x70, 0x88, 0x48, 0x50, 0x00, 0xf8, 0x30,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x04, 0x04, 0x08, 0x10, 0x24, 0x04, 0x04, 0x02,
-+ 0x02, 0x01, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0x20, 0x10, 0x08, 0x48, 0x40, 0x40, 0x80,
-+ 0x80, 0x00, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x08, 0x08, 0x17,
-+ 0x11, 0x30, 0x50, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0x10, 0x10, 0xfc,
-+ 0x10, 0x90, 0x90, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x13, 0x16, 0x1a, 0x12, 0x12,
-+ 0x2f, 0x29, 0x4a, 0x09, 0x0a, 0x08, 0x00, 0x00,
-+ 0x80, 0xfc, 0x10, 0xfc, 0x90, 0x50, 0x50, 0xb0,
-+ 0xf8, 0xc8, 0xa8, 0x48, 0x28, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x17, 0x11, 0x17, 0x17, 0x14,
-+ 0x17, 0x13, 0x22, 0x23, 0x43, 0x02, 0x00, 0x00,
-+ 0x00, 0xf0, 0xfc, 0x28, 0xe0, 0xf8, 0xf8, 0x88,
-+ 0xf8, 0xf0, 0x10, 0xf0, 0xf0, 0x30, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x05, 0x01, 0x1f, 0x01,
-+ 0x7f, 0x01, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x00, 0xf0, 0x00,
-+ 0xfc, 0x00, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x01, 0x3c, 0x03, 0x7e, 0x01, 0x3d, 0x03, 0x3c,
-+ 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x21, 0x00, 0x00,
-+ 0x08, 0x90, 0xfc, 0xa8, 0xa8, 0xb0, 0xfc, 0x00,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x02, 0x07, 0x18, 0x61, 0x1f, 0x10, 0x1f, 0x10,
-+ 0x1f, 0x10, 0x1f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0xe0, 0xc0, 0x00, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x00, 0x3d, 0x24, 0x24, 0x3f, 0x24, 0x3d, 0x25,
-+ 0x25, 0x3d, 0x19, 0x15, 0x27, 0x40, 0x00, 0x00,
-+ 0x10, 0xf8, 0x14, 0x14, 0xfc, 0x50, 0x50, 0x70,
-+ 0x50, 0x50, 0x74, 0xcc, 0x0c, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x3f, 0x04, 0x04, 0x7f, 0x04, 0x14,
-+ 0x17, 0x14, 0x14, 0x2c, 0x26, 0x41, 0x00, 0x00,
-+ 0x20, 0x20, 0xa0, 0x20, 0x20, 0xf0, 0x28, 0x24,
-+ 0xa4, 0x20, 0x20, 0x20, 0x00, 0xfc, 0x00, 0x00,
-+ 0x01, 0x02, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08,
-+ 0x0f, 0x01, 0x7f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xe0, 0x20, 0xe0, 0x00, 0xf0, 0x10,
-+ 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x29, 0x29, 0x33, 0x2b, 0x25,
-+ 0x25, 0x25, 0x25, 0x39, 0x21, 0x21, 0x00, 0x00,
-+ 0x88, 0x88, 0x88, 0x08, 0xfc, 0x08, 0x48, 0x28,
-+ 0x28, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x09, 0x09, 0x09, 0x12, 0x13, 0x35, 0x51, 0x1f,
-+ 0x12, 0x12, 0x17, 0x14, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x50, 0x50, 0xfc,
-+ 0x50, 0x50, 0xfc, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7f, 0x16, 0x12, 0x17, 0x1a,
-+ 0x72, 0x17, 0x10, 0x15, 0x14, 0x38, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0xa8, 0xa8, 0xfc, 0xa8,
-+ 0xa8, 0xfc, 0x00, 0x48, 0xa4, 0xa4, 0x00, 0x00,
-+ 0x00, 0x1f, 0x00, 0x00, 0x7f, 0x04, 0x04, 0x17,
-+ 0x14, 0x14, 0x14, 0x17, 0x78, 0x00, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0x40, 0xfc, 0x40, 0x40, 0xc0,
-+ 0x40, 0x20, 0x24, 0x94, 0x0c, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x2a, 0x7f, 0x0a, 0x3f, 0x08,
-+ 0x0f, 0x12, 0x6a, 0x0d, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0xa0, 0xfc, 0xa0, 0xf8, 0x20,
-+ 0xf8, 0xa0, 0xa0, 0xfc, 0x20, 0x20, 0x00, 0x00,
-+ 0x04, 0x7f, 0x14, 0x1f, 0x12, 0x3f, 0x22, 0x5f,
-+ 0x12, 0x1f, 0x12, 0x1f, 0x12, 0x12, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xe8, 0x28, 0xc8,
-+ 0x48, 0xc8, 0x48, 0xc8, 0x48, 0xf0, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x10, 0x1f, 0x2a, 0x4a, 0x7f,
-+ 0x0a, 0x0a, 0x7f, 0x14, 0x22, 0x42, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x00, 0xf8, 0xa0, 0xa0, 0xfc,
-+ 0xa0, 0xa0, 0xfc, 0x90, 0x48, 0x44, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x22, 0x12, 0x14, 0x7f, 0x00,
-+ 0x3e, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x50, 0x50, 0x60, 0x50, 0x48,
-+ 0x44, 0x44, 0x64, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x3e, 0x09, 0x08, 0x7f, 0x08, 0x08,
-+ 0x3e, 0x08, 0x08, 0x0e, 0x70, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0xfc, 0x10, 0x10, 0x90, 0x50,
-+ 0x50, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x1b, 0x37, 0x37,
-+ 0x33, 0x53, 0x52, 0x14, 0x17, 0x18, 0x00, 0x00,
-+ 0x00, 0xf8, 0x38, 0xc8, 0x48, 0xf8, 0x58, 0x58,
-+ 0xf8, 0x6c, 0x5c, 0x7c, 0x84, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x11, 0x17, 0x15, 0x15,
-+ 0x17, 0x15, 0x11, 0x21, 0x2e, 0x40, 0x00, 0x00,
-+ 0x00, 0xf0, 0xd0, 0x10, 0x10, 0xd0, 0x50, 0x50,
-+ 0xd0, 0x10, 0x54, 0xec, 0x2c, 0x04, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0f, 0x08, 0x0f, 0x7f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xe0, 0x20, 0xe0, 0xfc, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x3c, 0xe0, 0x20, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x3e, 0x22, 0x23, 0x3e,
-+ 0x08, 0x2f, 0x28, 0x2e, 0x38, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x78, 0xc8, 0x50, 0x30,
-+ 0xc8, 0xfc, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x10, 0x10, 0x37, 0x50, 0x10,
-+ 0x10, 0x10, 0x10, 0x11, 0x16, 0x18, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x48, 0x40, 0xfc, 0x40, 0x40,
-+ 0x40, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x7f, 0x00, 0x3e, 0x22, 0x3e, 0x00, 0x7f,
-+ 0x49, 0x7f, 0x49, 0x49, 0x7f, 0x41, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x11, 0x11, 0x21, 0x4b, 0x0d, 0x11, 0x11, 0x31,
-+ 0x50, 0x11, 0x16, 0x10, 0x11, 0x1e, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x80, 0xf0, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7d, 0x55, 0x55, 0x54, 0x57,
-+ 0x56, 0x5f, 0x52, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x48, 0xf8, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x25, 0x3d, 0x25, 0x25,
-+ 0x3d, 0x25, 0x25, 0x25, 0x25, 0x4d, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x30, 0x00, 0xf8, 0x88,
-+ 0x50, 0x50, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7d, 0x09, 0x09, 0x10, 0x1b,
-+ 0x36, 0x57, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x48, 0xf8, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x25, 0x3e, 0x24, 0x24, 0x3c,
-+ 0x24, 0x24, 0x27, 0x24, 0x24, 0x4f, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0xf8, 0x88, 0xf8, 0x88, 0xf8,
-+ 0x40, 0xf8, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x11, 0x11, 0x13, 0x7d, 0x09, 0x0b, 0x13, 0x1d,
-+ 0x34, 0x51, 0x16, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x80, 0xf0, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x1f, 0x12, 0x1f, 0x11, 0x29, 0x4b,
-+ 0x15, 0x31, 0x50, 0x13, 0x10, 0x17, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf0, 0x90, 0xf0, 0x00, 0xfc, 0xf0,
-+ 0xf0, 0xf0, 0xf0, 0xa0, 0xe0, 0x1c, 0x00, 0x00,
-+ 0x12, 0x0a, 0x0a, 0x42, 0x23, 0x22, 0x03, 0x12,
-+ 0x13, 0x12, 0x22, 0x24, 0x44, 0x48, 0x00, 0x00,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xb8, 0x08, 0xf8, 0x08,
-+ 0xb8, 0xa8, 0xa8, 0xa8, 0xa8, 0x08, 0x00, 0x00,
-+ 0x04, 0x04, 0x3f, 0x04, 0x04, 0x3f, 0x24, 0x24,
-+ 0x3f, 0x24, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x80, 0x80, 0xf0, 0x90, 0x90, 0xf0, 0x90, 0x80,
-+ 0xf8, 0x88, 0x88, 0x88, 0xb0, 0x80, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7e, 0x08, 0x08, 0x08, 0x0c,
-+ 0x78, 0x08, 0x09, 0x09, 0x0f, 0x18, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x80,
-+ 0xa0, 0x90, 0x08, 0x38, 0xc4, 0x04, 0x00, 0x00,
-+ 0x11, 0x09, 0x0f, 0x41, 0x21, 0x27, 0x05, 0x15,
-+ 0x17, 0x15, 0x21, 0x22, 0x42, 0x44, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x28, 0x28, 0xf8, 0x28, 0x20,
-+ 0xfc, 0x24, 0x24, 0x38, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x30, 0x51,
-+ 0x11, 0x11, 0x12, 0x12, 0x1f, 0x10, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00,
-+ 0x20, 0x10, 0x08, 0x78, 0x84, 0x04, 0x00, 0x00,
-+ 0x09, 0x29, 0x29, 0x29, 0x3e, 0x2a, 0x4c, 0x09,
-+ 0x0d, 0x7a, 0x08, 0x08, 0x09, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0xa8, 0xa8, 0xa8, 0x28,
-+ 0x28, 0x48, 0x48, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2b, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x48, 0x48, 0x48, 0x88, 0xfc, 0x88, 0xc8, 0xa8,
-+ 0xa8, 0x88, 0x88, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x07, 0x00, 0x08, 0x08, 0x10, 0x10, 0x3f, 0x42,
-+ 0x02, 0x02, 0x04, 0x04, 0x08, 0x10, 0x00, 0x00,
-+ 0xc0, 0x40, 0x40, 0x20, 0x20, 0x10, 0xe8, 0x24,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0xc0, 0x00, 0x00,
-+ 0x01, 0x01, 0x79, 0x4b, 0x4a, 0x4a, 0x4c, 0x49,
-+ 0x49, 0x7a, 0x4c, 0x40, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0xa8, 0xa8, 0xa8, 0x28,
-+ 0x48, 0x48, 0x48, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x03, 0x79, 0x4f, 0x49, 0x4b, 0x4a, 0x4b,
-+ 0x4a, 0x7b, 0x4a, 0x43, 0x01, 0x0e, 0x00, 0x00,
-+ 0x40, 0xf8, 0x50, 0xfc, 0x10, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0xf8, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x13, 0x11, 0x17, 0x7d, 0x13, 0x12, 0x13,
-+ 0x16, 0x1b, 0x62, 0x03, 0x03, 0x1c, 0x00, 0x00,
-+ 0x40, 0xf8, 0x50, 0xfc, 0x10, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0xf8, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x13, 0x11, 0x1f, 0x35, 0x37, 0x32, 0x53,
-+ 0x12, 0x13, 0x12, 0x13, 0x11, 0x16, 0x00, 0x00,
-+ 0x40, 0xf8, 0x50, 0xfc, 0x10, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0xf8, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x11, 0x12, 0x13, 0x1c,
-+ 0x70, 0x10, 0x11, 0x11, 0x12, 0x34, 0x00, 0x00,
-+ 0xe0, 0x20, 0x20, 0x20, 0x10, 0x10, 0xf8, 0x94,
-+ 0x90, 0x90, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x1c, 0x1a, 0x29, 0x48, 0x01,
-+ 0x09, 0x09, 0x12, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x60, 0xb0, 0x28, 0x24, 0x10,
-+ 0x10, 0xa0, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x01, 0x7f, 0x06, 0x1c, 0x6f, 0x1f, 0x2f, 0x08,
-+ 0x0f, 0x1f, 0x11, 0x1f, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x60, 0x90, 0xfc, 0xe0, 0xe0, 0x80,
-+ 0xf8, 0xf0, 0x10, 0xf0, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2a, 0x2c, 0x08, 0x7f, 0x09, 0x1e,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0xe0, 0x20, 0xa0, 0xa0, 0x90, 0x10, 0xf8, 0x54,
-+ 0x50, 0x50, 0x90, 0x90, 0x10, 0x60, 0x00, 0x00,
-+ 0x09, 0x3f, 0x07, 0x19, 0x6f, 0x09, 0x0f, 0x09,
-+ 0x0f, 0x3f, 0x04, 0x7f, 0x0c, 0x30, 0x00, 0x00,
-+ 0x20, 0xf8, 0xc0, 0x30, 0xfc, 0x20, 0xe0, 0x20,
-+ 0xe0, 0xf8, 0x40, 0xfc, 0x60, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0d, 0x13, 0x7e,
-+ 0x0c, 0x2a, 0x2a, 0x28, 0x49, 0x0a, 0x00, 0x00,
-+ 0xe0, 0x20, 0xa0, 0xa0, 0x90, 0x10, 0xf8, 0x54,
-+ 0x50, 0x50, 0x90, 0x90, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x3f, 0x21, 0x5d, 0x1d, 0x07,
-+ 0x04, 0x18, 0x6f, 0x02, 0x04, 0x18, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0x08, 0x70, 0x70, 0xc0,
-+ 0x40, 0x30, 0xec, 0x20, 0x20, 0xc0, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x7f, 0x08, 0x08, 0x04, 0x04,
-+ 0x02, 0x01, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x20, 0x20, 0x40, 0x40,
-+ 0x80, 0x00, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x2f, 0x24,
-+ 0x27, 0x24, 0x27, 0x24, 0x2f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xe8, 0x48,
-+ 0xc8, 0x48, 0xc8, 0x48, 0xc8, 0x58, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x01, 0x3f, 0x21, 0x21, 0x22,
-+ 0x22, 0x24, 0x28, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x88,
-+ 0x48, 0x28, 0x28, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x0a, 0x09, 0x09, 0x17, 0x11, 0x31, 0x51, 0x1f,
-+ 0x11, 0x11, 0x12, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xf8, 0x20, 0x20, 0x20, 0xfc,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08,
-+ 0x08, 0x7f, 0x00, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0xe0, 0x00, 0x00, 0x00, 0xf8, 0x40, 0x40, 0x40,
-+ 0x40, 0xfc, 0x00, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x00, 0x13, 0x12, 0x13, 0x7e, 0x12, 0x13, 0x12,
-+ 0x16, 0x1b, 0x64, 0x04, 0x09, 0x12, 0x00, 0x00,
-+ 0x00, 0xfc, 0x04, 0xfc, 0x8c, 0x50, 0xfc, 0x50,
-+ 0x50, 0xfc, 0x90, 0x90, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x49, 0x2a, 0x7f, 0x5d, 0x5b, 0x6b, 0x41,
-+ 0x1f, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xc8, 0x30, 0x30, 0xc8, 0x04,
-+ 0xf0, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x11, 0x09, 0x09, 0x01, 0x7f,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x10, 0x10, 0x20, 0x00, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x2a, 0x1c, 0x7f, 0x5d, 0x5b, 0x69, 0x4b,
-+ 0x04, 0x7f, 0x04, 0x04, 0x08, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xc8, 0x28, 0x30, 0xc8, 0x44,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x7e, 0x09, 0x19, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x68,
-+ 0x98, 0x98, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x04, 0x04, 0x7f, 0x04, 0x04, 0x24, 0x14,
-+ 0x14, 0x14, 0x04, 0x04, 0x7f, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0xfc, 0x40, 0x40, 0x48, 0x48,
-+ 0x50, 0x60, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x4d, 0x29, 0x2a, 0x7f,
-+ 0x49, 0x5d, 0x5b, 0x6b, 0x49, 0x4b, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x7c, 0xc8, 0x48,
-+ 0x28, 0x30, 0x10, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x20, 0x20,
-+ 0x2f, 0x21, 0x22, 0x24, 0x28, 0x21, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x88,
-+ 0xe8, 0x88, 0x88, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x01, 0x3d, 0x25, 0x29, 0x29, 0x31, 0x29, 0x27,
-+ 0x24, 0x27, 0x38, 0x20, 0x27, 0x20, 0x00, 0x00,
-+ 0x20, 0x24, 0x28, 0xf0, 0x20, 0x24, 0xe4, 0x5c,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x11, 0x09, 0x09, 0x01, 0x7f, 0x03, 0x03,
-+ 0x05, 0x19, 0x61, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x20, 0x00, 0xfc, 0x80, 0x80,
-+ 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x02, 0x0f, 0x08, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xe0, 0x20, 0xe0, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x12, 0x12, 0x33, 0x52, 0x12,
-+ 0x17, 0x16, 0x1a, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x10, 0x90, 0xfc, 0xa8, 0xa8, 0xa8, 0x7c, 0x10,
-+ 0x90, 0xfc, 0x90, 0x90, 0x90, 0x10, 0x00, 0x00,
-+ 0x00, 0x1e, 0x13, 0x1e, 0x10, 0x3f, 0x32, 0x5f,
-+ 0x12, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x50, 0xfc, 0x20, 0xfc,
-+ 0x20, 0x20, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x2b, 0x2a, 0x0a, 0x1b,
-+ 0x2a, 0x4b, 0x16, 0x16, 0x2b, 0x42, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x10, 0x90, 0xfc, 0xa8, 0xb0,
-+ 0x7c, 0x90, 0xfc, 0x90, 0x90, 0x10, 0x00, 0x00,
-+ 0x00, 0x7f, 0x08, 0x3e, 0x08, 0x0f, 0x70, 0x00,
-+ 0x7f, 0x02, 0x07, 0x1c, 0x67, 0x04, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x00,
-+ 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x21, 0x21, 0x3f, 0x29, 0x08,
-+ 0x0f, 0x09, 0x11, 0x11, 0x21, 0x46, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x49, 0x2a, 0x7f, 0x49, 0x5d, 0x6b, 0x4f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x7c, 0xc8, 0x30, 0xd0, 0xec, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x1f, 0x12, 0x1f, 0x00, 0x1f,
-+ 0x10, 0x14, 0x12, 0x22, 0x20, 0x43, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x90, 0xfc,
-+ 0x48, 0x48, 0x30, 0x34, 0xcc, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x24, 0x5f, 0x11, 0x12, 0x14,
-+ 0x10, 0x1f, 0x10, 0x13, 0x1c, 0x70, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x90, 0xf0, 0x10, 0x90, 0x50,
-+ 0x88, 0x90, 0xe0, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x13, 0x12, 0x33, 0x52, 0x13,
-+ 0x16, 0x16, 0x1b, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0xa8, 0xa8, 0xf8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x02, 0x12, 0x12, 0x24, 0x4a,
-+ 0x03, 0x04, 0x1a, 0x01, 0x06, 0x78, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x40, 0x50, 0x48, 0xc4, 0x04,
-+ 0xe0, 0x40, 0x80, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x0f,
-+ 0x08, 0x08, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0xe0,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x7f, 0x00, 0x1f, 0x10, 0x1f,
-+ 0x10, 0x1f, 0x29, 0x2f, 0x49, 0x09, 0x00, 0x00,
-+ 0x40, 0xfc, 0x90, 0xfc, 0x00, 0xf8, 0x08, 0xf8,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x48, 0x58, 0x00, 0x00,
-+ 0x10, 0x13, 0x14, 0x65, 0x19, 0x19, 0x25, 0x7f,
-+ 0x11, 0x3b, 0x37, 0x35, 0x51, 0x11, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0x00, 0xfc,
-+ 0x54, 0xfc, 0x54, 0x54, 0x54, 0x0c, 0x00, 0x00,
-+ 0x00, 0x20, 0x17, 0x10, 0x00, 0x00, 0x70, 0x11,
-+ 0x11, 0x12, 0x14, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x08,
-+ 0x08, 0x08, 0x30, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x23, 0x12, 0x12, 0x03, 0x03, 0x72, 0x12,
-+ 0x12, 0x14, 0x17, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf0, 0x10, 0x90, 0x60,
-+ 0x20, 0xd0, 0x08, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x27, 0x10, 0x13, 0x02, 0x03, 0x72, 0x13,
-+ 0x16, 0x17, 0x1a, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0x00, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0xa8, 0x18, 0xfc, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x13, 0x12, 0x33, 0x52, 0x13,
-+ 0x12, 0x11, 0x10, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x48, 0x40, 0x80, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7f, 0x2a, 0x2a, 0x3e,
-+ 0x2c, 0x0c, 0x15, 0x16, 0x24, 0x43, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x88, 0x88, 0x08, 0x34, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x13, 0x7d, 0x25, 0x25, 0x25,
-+ 0x79, 0x48, 0x0c, 0x14, 0x21, 0x46, 0x00, 0x00,
-+ 0x40, 0x78, 0x90, 0x20, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x68, 0x60, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x04, 0x3f, 0x04, 0x04, 0x04,
-+ 0x7f, 0x04, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x40, 0x30, 0xc8, 0x40, 0x40, 0x40,
-+ 0xfc, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x28, 0x28, 0x7c, 0x29, 0x39, 0x13, 0x7d, 0x55,
-+ 0x55, 0x7d, 0x11, 0x7d, 0x11, 0x11, 0x00, 0x00,
-+ 0x80, 0xfc, 0x90, 0x7c, 0x54, 0x7c, 0x54, 0x7c,
-+ 0x54, 0x50, 0x20, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x12, 0x13, 0x32, 0x50, 0x17,
-+ 0x10, 0x11, 0x12, 0x14, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x48, 0x40, 0xfc,
-+ 0xe0, 0x50, 0x48, 0x44, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x17, 0x1a, 0x29, 0x7f, 0x09, 0x7f,
-+ 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x25, 0x00, 0x00,
-+ 0x50, 0x48, 0xfc, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x28, 0x24, 0xfc, 0x20, 0xf8, 0xa8, 0xa8, 0xf8,
-+ 0xa8, 0xa8, 0xf8, 0xa8, 0xa8, 0x98, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x3f, 0x21, 0x2f, 0x29, 0x2f,
-+ 0x29, 0x2f, 0x29, 0x29, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0xf8, 0x08, 0xe8, 0x28, 0xe8,
-+ 0x28, 0xe8, 0x28, 0x68, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x7c, 0x13, 0x12, 0x12, 0x1f,
-+ 0x72, 0x12, 0x13, 0x12, 0x12, 0x32, 0x00, 0x00,
-+ 0x50, 0x48, 0xfc, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x01, 0x09, 0x09, 0x09, 0x09, 0x7f, 0x01, 0x09,
-+ 0x09, 0x11, 0x23, 0x01, 0x06, 0x78, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x00, 0x20,
-+ 0x10, 0x28, 0x48, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x1f, 0x11, 0x11, 0x1f,
-+ 0x11, 0x11, 0x1f, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x20, 0x10, 0xfc, 0x00, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x10, 0x10, 0xf0, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x0b, 0x0a, 0x16, 0x3b,
-+ 0x56, 0x16, 0x13, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x50, 0x48, 0xfc, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x28, 0x24, 0xfc, 0x20, 0xf8, 0xa8, 0xa8, 0xf8,
-+ 0xa8, 0xa8, 0xf8, 0xa8, 0xa8, 0xb8, 0x00, 0x00,
-+ 0x04, 0x18, 0x77, 0x10, 0x13, 0x7e, 0x13, 0x1a,
-+ 0x37, 0x34, 0x52, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0x40, 0xa8, 0x84, 0x94, 0x70, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0f, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x7f, 0x05, 0x1f, 0x61, 0x06, 0x18, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xe0, 0x20, 0xe0, 0x20, 0xe0,
-+ 0xfc, 0x40, 0xf0, 0x2c, 0x20, 0xc0, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0f, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x7f, 0x19, 0x6f, 0x01, 0x3f, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xe0, 0x20, 0xe0, 0x20, 0xe0,
-+ 0xfc, 0x30, 0xec, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0f, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x7f, 0x0a, 0x1b, 0x6a, 0x12, 0x06, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xe0, 0x20, 0xe0, 0x20, 0xe0,
-+ 0xfc, 0x20, 0x50, 0xac, 0xa0, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x1f, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x21, 0x26, 0x40, 0x00, 0x00,
-+ 0x80, 0x90, 0x88, 0xfc, 0x80, 0x88, 0x88, 0x50,
-+ 0x50, 0x20, 0x64, 0x94, 0x0c, 0x04, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0f, 0x08, 0x0f, 0x0f, 0x7f,
-+ 0x07, 0x1c, 0x67, 0x04, 0x07, 0x04, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xe0, 0x20, 0xe0, 0xe0, 0xfc,
-+ 0xc0, 0x70, 0xcc, 0x40, 0xc0, 0x40, 0x00, 0x00,
-+ 0x00, 0x0f, 0x09, 0x08, 0x08, 0x7f, 0x12, 0x11,
-+ 0x11, 0x10, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x90, 0x90, 0xfc, 0x10, 0x10,
-+ 0x10, 0x10, 0xfc, 0x20, 0x20, 0xc0, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x17, 0x09, 0x49, 0x21,
-+ 0x29, 0x09, 0x17, 0x11, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0x58, 0xfc, 0xf0, 0x50, 0xf0,
-+ 0x50, 0xf0, 0xfc, 0x10, 0x90, 0x30, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x01, 0x3f, 0x08, 0x04, 0x7f,
-+ 0x00, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x20, 0x40, 0xfc,
-+ 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x0a, 0x0a, 0x0a, 0x1f, 0x12, 0x32, 0x53, 0x12,
-+ 0x12, 0x12, 0x14, 0x14, 0x18, 0x13, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xa0, 0x7c, 0x48, 0xc8, 0xa8,
-+ 0xa8, 0xb0, 0x90, 0xb0, 0xc8, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x10, 0x13, 0x30, 0x57, 0x11,
-+ 0x13, 0x14, 0x13, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xf8, 0xa0, 0xfc, 0x50,
-+ 0xf8, 0x44, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x1f, 0x10, 0x3f, 0x40, 0x00,
-+ 0x1f, 0x10, 0x10, 0x10, 0x10, 0x0f, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0x88, 0x88, 0x88,
-+ 0x88, 0xb0, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x11, 0x01, 0x7f,
-+ 0x03, 0x05, 0x19, 0x61, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0xfc,
-+ 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x3e, 0x08, 0x7f, 0x22, 0x12, 0x14,
-+ 0x7f, 0x08, 0x3e, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xb0, 0x80, 0xf8, 0xc8,
-+ 0xa8, 0xb0, 0x90, 0xb0, 0xc8, 0x84, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x01, 0x1f, 0x02, 0x7f, 0x09,
-+ 0x17, 0x61, 0x1f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xf0, 0x80, 0xfc, 0x20,
-+ 0xd0, 0x0c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x40, 0x1f, 0x01, 0x01,
-+ 0x1f, 0x01, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x00, 0xf0, 0x00, 0x00,
-+ 0xf0, 0x00, 0x20, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x13, 0x10, 0x54, 0x57, 0x57, 0x54,
-+ 0x55, 0x7c, 0x47, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0xf8, 0x90, 0x60, 0xb0, 0x4c, 0xf8, 0x40,
-+ 0xf0, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x11, 0x1f, 0x02, 0x07, 0x3c, 0x03, 0x0d, 0x77,
-+ 0x01, 0x0f, 0x01, 0x3f, 0x01, 0x01, 0x00, 0x00,
-+ 0x10, 0xf0, 0x00, 0xe0, 0x40, 0x80, 0x60, 0xdc,
-+ 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x1f, 0x00, 0x1e, 0x12, 0x1e,
-+ 0x12, 0x1e, 0x12, 0x22, 0x22, 0x47, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0xf0, 0x00, 0x78, 0x48, 0x78,
-+ 0x48, 0x78, 0x48, 0x88, 0x88, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x11, 0x11, 0x12, 0x17, 0x18,
-+ 0x13, 0x12, 0x12, 0x22, 0x22, 0x41, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xf8, 0x08, 0xc8, 0x48,
-+ 0xc8, 0x70, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7e, 0x13, 0x14, 0x10, 0x1f,
-+ 0x72, 0x12, 0x12, 0x12, 0x12, 0x31, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x08, 0xc8, 0x48, 0x48, 0xc8,
-+ 0x48, 0x30, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x11, 0x10, 0x1f, 0x11,
-+ 0x33, 0x54, 0x13, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xf0, 0xa0, 0xfc, 0x50,
-+ 0xf8, 0x44, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x08, 0x0f, 0x0a,
-+ 0x0a, 0x12, 0x12, 0x22, 0x43, 0x0e, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x88, 0x88, 0x48,
-+ 0x50, 0x30, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x7f, 0x02, 0x02, 0x03, 0x02,
-+ 0x02, 0x04, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf0, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0xe0, 0x00, 0x00,
-+ 0x00, 0x1e, 0x12, 0x12, 0x12, 0x1e, 0x12, 0x12,
-+ 0x1e, 0x12, 0x12, 0x22, 0x23, 0x46, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0x48, 0x78, 0x48, 0x48,
-+ 0x78, 0x48, 0x88, 0x88, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x43, 0x20, 0x20, 0x07, 0x00,
-+ 0x08, 0x08, 0x10, 0x11, 0x27, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x40,
-+ 0x40, 0x90, 0x88, 0x38, 0xc4, 0x04, 0x00, 0x00,
-+ 0x11, 0x09, 0x09, 0x43, 0x22, 0x27, 0x08, 0x03,
-+ 0x0a, 0x0a, 0x12, 0x12, 0x22, 0x21, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0xc8, 0x48, 0xc8,
-+ 0x70, 0x00, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x01, 0x7f, 0x00, 0x0f, 0x08, 0x0f, 0x3f, 0x00,
-+ 0x01, 0x01, 0x03, 0x14, 0x22, 0x42, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xe0, 0x20, 0xe0, 0xf8, 0x60,
-+ 0x80, 0x00, 0x00, 0x90, 0x48, 0x44, 0x00, 0x00,
-+ 0x00, 0x7e, 0x10, 0x11, 0x13, 0x20, 0x3c, 0x65,
-+ 0x25, 0x25, 0x25, 0x3d, 0x25, 0x20, 0x00, 0x00,
-+ 0x80, 0x80, 0xf8, 0x08, 0xe8, 0x28, 0x28, 0xe8,
-+ 0x30, 0x00, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x12, 0x15, 0x65, 0x28, 0x18, 0x27, 0x7d,
-+ 0x19, 0x35, 0x35, 0x31, 0x52, 0x14, 0x00, 0x00,
-+ 0x20, 0x38, 0xc8, 0x30, 0xe8, 0x24, 0xf8, 0x20,
-+ 0xf8, 0x20, 0xfc, 0x20, 0xe0, 0x3c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x25, 0x3d, 0x26, 0x24, 0x3d,
-+ 0x25, 0x25, 0x25, 0x25, 0x25, 0x4c, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x04, 0xe4, 0x24, 0x24, 0xe4,
-+ 0x38, 0x00, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x05, 0x01, 0x7f, 0x01,
-+ 0x01, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x00, 0xfc, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x7c, 0x44, 0x44, 0x7c,
-+ 0x44, 0x44, 0x7c, 0x44, 0x41, 0x02, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x88, 0x88, 0xf8,
-+ 0x88, 0x88, 0xf8, 0x88, 0x08, 0x18, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x21, 0x1f, 0x10, 0x03, 0x7f,
-+ 0x10, 0x13, 0x10, 0x17, 0x2c, 0x43, 0x00, 0x00,
-+ 0x40, 0xfc, 0xc0, 0xf0, 0x20, 0xe0, 0x5c, 0xf8,
-+ 0x40, 0xf8, 0x40, 0xfc, 0x40, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3f, 0x2a, 0x2b, 0x2a, 0x3e,
-+ 0x28, 0x0c, 0x0b, 0x0e, 0x70, 0x00, 0x00, 0x00,
-+ 0x40, 0x78, 0xd0, 0x20, 0x70, 0xac, 0xf8, 0x20,
-+ 0xf8, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x01, 0x7f, 0x09, 0x09, 0x11, 0x77, 0x11, 0x16,
-+ 0x11, 0x03, 0x0c, 0x74, 0x07, 0x18, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf0, 0x10, 0xf0, 0xfc, 0x50, 0x4c,
-+ 0x40, 0x10, 0xa0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7f, 0x00, 0x3c, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x25, 0x3e, 0x24, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x78, 0x48,
-+ 0x48, 0x88, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x02, 0x1f, 0x12, 0x1f, 0x12, 0x1f, 0x00, 0x7f,
-+ 0x0f, 0x08, 0x0f, 0x04, 0x7f, 0x00, 0x00, 0x00,
-+ 0x80, 0xf0, 0x90, 0xf0, 0x90, 0xf0, 0x00, 0xfc,
-+ 0xe0, 0x20, 0xe0, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x3f, 0x04, 0x04, 0x3f, 0x04, 0x04,
-+ 0x7f, 0x04, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0x78, 0xc8, 0x50, 0x50, 0xe0, 0x50, 0x48,
-+ 0xc4, 0x44, 0x64, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x13, 0x22, 0x5d, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1d, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x40, 0x78, 0xd0, 0x20, 0x70, 0xac, 0xf8, 0x20,
-+ 0xf8, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x0c, 0x12, 0x2a, 0x49, 0x3e, 0x22, 0x3e,
-+ 0x22, 0x3e, 0x24, 0x26, 0x3a, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0xe8, 0x28, 0x28, 0xe8,
-+ 0xb0, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x12, 0x17, 0x14, 0x17,
-+ 0x17, 0x17, 0x14, 0x27, 0x2d, 0x52, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xd0, 0x50, 0xd0,
-+ 0xd0, 0xf4, 0x0c, 0xfc, 0x54, 0xe4, 0x00, 0x00,
-+ 0x00, 0x3f, 0x2d, 0x2d, 0x2d, 0x3f, 0x2d, 0x2d,
-+ 0x2d, 0x3f, 0x2d, 0x2d, 0x2d, 0x5b, 0x00, 0x00,
-+ 0x10, 0x20, 0x78, 0x48, 0x78, 0x48, 0x78, 0x7c,
-+ 0x40, 0x7c, 0x34, 0xf4, 0xc4, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x3f, 0x01, 0x01, 0x1f, 0x00, 0x00,
-+ 0x00, 0x09, 0x0e, 0x14, 0x23, 0x40, 0x00, 0x00,
-+ 0x18, 0xe0, 0x00, 0x00, 0x00, 0xf0, 0x10, 0x20,
-+ 0x40, 0x80, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x7f, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x0f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x11, 0x10, 0x37, 0x54, 0x1f,
-+ 0x10, 0x10, 0x10, 0x11, 0x16, 0x18, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0xa0, 0xfc, 0x44, 0xfc,
-+ 0x40, 0xf8, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x04, 0x04, 0x3f, 0x11, 0x09, 0x0a, 0x7f, 0x00,
-+ 0x1f, 0x11, 0x11, 0x11, 0x1f, 0x11, 0x00, 0x00,
-+ 0x08, 0x48, 0xc8, 0x48, 0x48, 0x48, 0xc8, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x17, 0x7c, 0x10, 0x10, 0x10,
-+ 0x10, 0x1c, 0x61, 0x02, 0x04, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x78,
-+ 0x88, 0x88, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x09, 0x7e, 0x12, 0x12, 0x12,
-+ 0x3c, 0x24, 0x06, 0x0a, 0x11, 0x22, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x40, 0x40, 0x78, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x56, 0x57, 0x55, 0x55,
-+ 0x55, 0x55, 0x59, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x08, 0x08, 0x08, 0x07, 0x01,
-+ 0x04, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xf0, 0x00,
-+ 0x80, 0x90, 0x08, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x17, 0x39, 0x35, 0x35, 0x51,
-+ 0x11, 0x11, 0x11, 0x11, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f,
-+ 0x10, 0x10, 0x11, 0x22, 0x2c, 0x70, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x10, 0xf0, 0x80, 0xfc,
-+ 0x80, 0xf0, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x3f, 0x04,
-+ 0x7f, 0x09, 0x15, 0x67, 0x19, 0x03, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0xf8, 0x40,
-+ 0xfc, 0x20, 0x50, 0xcc, 0x30, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x20, 0x20, 0x20, 0x1f, 0x02,
-+ 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0x30,
-+ 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x0f, 0x08, 0x0f, 0x01,
-+ 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xe0, 0x20, 0xe0, 0x00,
-+ 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x7e, 0x09, 0x1c, 0x1b, 0x1b,
-+ 0x2b, 0x2c, 0x4b, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0xa0, 0xfc, 0x50,
-+ 0xf8, 0x44, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x3f, 0x20, 0x3f, 0x2f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0xe8, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x73, 0x14, 0x0c, 0x12, 0x7d,
-+ 0x0c, 0x2a, 0x2a, 0x28, 0x49, 0x0a, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x40, 0x40, 0x78, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x27, 0x3c, 0x24, 0x24, 0x3c,
-+ 0x24, 0x24, 0x24, 0x25, 0x26, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x78, 0x48,
-+ 0x48, 0x88, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x01, 0x39, 0x2f, 0x29, 0x2f, 0x38, 0x2b, 0x2a,
-+ 0x3b, 0x2a, 0x29, 0x29, 0x2e, 0x58, 0x00, 0x00,
-+ 0x08, 0x08, 0xd0, 0x10, 0xe0, 0x08, 0xc8, 0x50,
-+ 0xe4, 0x44, 0x88, 0xc8, 0x10, 0x20, 0x00, 0x00,
-+ 0x01, 0x39, 0x03, 0x7d, 0x01, 0x3d, 0x01, 0x3c,
-+ 0x03, 0x3c, 0x25, 0x26, 0x3c, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0xf0, 0x10, 0xf0, 0x40,
-+ 0xfc, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x04, 0x18, 0x6a, 0x25, 0x19, 0x69, 0x0d, 0x15,
-+ 0x65, 0x0c, 0x14, 0x64, 0x05, 0x1a, 0x00, 0x00,
-+ 0x40, 0x40, 0x80, 0xf8, 0x08, 0xf8, 0x08, 0xf8,
-+ 0x68, 0x60, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x06, 0x38, 0x24, 0x26, 0x3a, 0x6f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x88, 0xf8, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x23, 0x5c, 0x08, 0x7f,
-+ 0x09, 0x2a, 0x1d, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x40, 0x40, 0x50, 0x88, 0xf4, 0xa0, 0xa0, 0xf8,
-+ 0x20, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x2b, 0x28, 0x30, 0x28, 0x24,
-+ 0x24, 0x24, 0x24, 0x39, 0x22, 0x24, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x78, 0x48,
-+ 0x48, 0x88, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x48, 0x48, 0x4f, 0x48, 0x48,
-+ 0x48, 0x78, 0x48, 0x41, 0x06, 0x18, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x48, 0x40, 0xfc, 0x40, 0x40,
-+ 0x60, 0xa0, 0x90, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x7f, 0x0a, 0x4a, 0x2c, 0x28,
-+ 0x7f, 0x0c, 0x12, 0x12, 0x20, 0x43, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x04, 0x7c, 0x04, 0x04, 0x04,
-+ 0x04, 0x1c, 0x64, 0x04, 0x04, 0x04, 0x00, 0x00,
-+ 0x80, 0x80, 0x88, 0x88, 0x90, 0xa0, 0xc0, 0x80,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x0a, 0x09, 0x17, 0x11, 0x30, 0x57, 0x10,
-+ 0x13, 0x10, 0x17, 0x10, 0x13, 0x1c, 0x00, 0x00,
-+ 0xa0, 0xa8, 0xb0, 0xfc, 0x10, 0xa0, 0xfc, 0x40,
-+ 0xf8, 0x40, 0xfc, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02, 0x02,
-+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20,
-+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x09, 0x0f, 0x09, 0x0f, 0x1f, 0x01,
-+ 0x7f, 0x15, 0x2f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0xf0, 0x00,
-+ 0xfc, 0x50, 0xe8, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x12, 0x11, 0x7f, 0x11, 0x10, 0x13, 0x1c,
-+ 0x71, 0x10, 0x17, 0x10, 0x13, 0x3c, 0x00, 0x00,
-+ 0xa0, 0xa8, 0xb0, 0xfc, 0x10, 0xa0, 0xf8, 0x40,
-+ 0xf0, 0x40, 0xfc, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x18, 0x1c, 0x1a,
-+ 0x2a, 0x28, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x60, 0x50, 0x48, 0x44,
-+ 0x44, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x28, 0x28, 0x3e, 0x29, 0x29, 0x4a,
-+ 0x0e, 0x78, 0x08, 0x08, 0x09, 0x0e, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0x80, 0xfc, 0x10, 0x90, 0x90,
-+ 0x50, 0x60, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x78, 0x4b, 0x48, 0x7f, 0x49, 0x49, 0x7a,
-+ 0x4c, 0x4b, 0x78, 0x40, 0x0f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xfc, 0x20, 0x24, 0x5c,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x19, 0x71, 0x11, 0x11, 0x7d, 0x10, 0x19,
-+ 0x36, 0x35, 0x50, 0x11, 0x10, 0x13, 0x00, 0x00,
-+ 0x40, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x40, 0x58,
-+ 0x64, 0x90, 0x60, 0x88, 0x30, 0xc0, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x3f, 0x08, 0x3f, 0x22, 0x7e, 0x04,
-+ 0x08, 0x0e, 0x78, 0x08, 0x09, 0x1a, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x09, 0x09, 0x41, 0x21, 0x22, 0x04, 0x0b,
-+ 0x09, 0x10, 0x10, 0x20, 0x21, 0x2e, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0xf0,
-+ 0x10, 0x90, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x08, 0x08, 0x0e, 0x12, 0x13, 0x2a,
-+ 0x45, 0x05, 0x09, 0x11, 0x21, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x50, 0x88, 0x8c, 0xf4, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x13, 0x12, 0x13, 0x7e, 0x12, 0x12, 0x12,
-+ 0x16, 0x1b, 0x65, 0x05, 0x09, 0x11, 0x00, 0x00,
-+ 0x00, 0xfc, 0x04, 0xfc, 0x20, 0xa8, 0xa8, 0xa8,
-+ 0xf8, 0x24, 0x24, 0x24, 0xfc, 0x04, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x55, 0x55, 0x56, 0x55,
-+ 0x57, 0x54, 0x58, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x48, 0x50,
-+ 0xfc, 0xa0, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x04, 0x09, 0x1f, 0x61, 0x05,
-+ 0x04, 0x7f, 0x04, 0x04, 0x08, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x40, 0x20, 0xf0, 0x0c, 0x40,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x7f, 0x03, 0x05, 0x05,
-+ 0x09, 0x11, 0x2f, 0x41, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x80, 0x40, 0x40,
-+ 0x20, 0x10, 0xe8, 0x04, 0x00, 0x00, 0x00, 0x00,
-+ 0x06, 0x7b, 0x2a, 0x1c, 0x7f, 0x1c, 0x1a, 0x2a,
-+ 0x7e, 0x2b, 0x3e, 0x2a, 0x3e, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x68, 0xd8, 0xd8, 0x48,
-+ 0xd8, 0x68, 0x48, 0x48, 0x48, 0xd8, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x08, 0x08, 0x0a, 0x09, 0x09,
-+ 0x09, 0x08, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xc0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x03, 0x08, 0x08, 0x1f, 0x21, 0x42, 0x0c, 0x30,
-+ 0x1f, 0x12, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0xc0, 0x40, 0x20, 0xf0, 0x28, 0x24, 0x20, 0xc0,
-+ 0xf0, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x1f, 0x17, 0x1a, 0x12, 0x17,
-+ 0x10, 0x17, 0x20, 0x3f, 0x40, 0x01, 0x00, 0x00,
-+ 0x80, 0xfc, 0x10, 0xfc, 0x38, 0xd4, 0x30, 0xc0,
-+ 0x80, 0xf8, 0x80, 0xfc, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x12, 0x1f, 0x17, 0x1a, 0x12,
-+ 0x17, 0x10, 0x23, 0x2e, 0x43, 0x02, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x10, 0xfc, 0x38, 0xd4, 0x90,
-+ 0xfc, 0x80, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x1f, 0x12, 0x1f, 0x17, 0x1a, 0x17, 0x14,
-+ 0x17, 0x17, 0x25, 0x22, 0x4c, 0x30, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xfc, 0x70, 0xa8, 0xf4, 0x90,
-+ 0xf0, 0xf0, 0xa8, 0xfc, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x12, 0x12, 0x1f, 0x12, 0x17,
-+ 0x16, 0x1a, 0x13, 0x22, 0x42, 0x02, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x20, 0x20, 0xfc, 0x20, 0x70,
-+ 0xf0, 0xa8, 0x24, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x12, 0x7f, 0x12, 0x12, 0x13,
-+ 0x10, 0x1f, 0x60, 0x00, 0x0f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x09, 0x7e, 0x12, 0x13, 0x12,
-+ 0x3c, 0x24, 0x07, 0x0a, 0x12, 0x20, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0x70,
-+ 0x70, 0xa8, 0x24, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x4b, 0x48, 0x48, 0x7f, 0x48,
-+ 0x48, 0x49, 0x7a, 0x4c, 0x48, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0xe0,
-+ 0xe0, 0x50, 0x48, 0x44, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x09, 0x1a, 0x1c, 0x1a,
-+ 0x2a, 0x28, 0x48, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x10, 0x90, 0x90, 0x50,
-+ 0x60, 0x20, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x10, 0x2f, 0x49, 0x09, 0x7f,
-+ 0x09, 0x09, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xe0, 0x20, 0x20, 0xfc,
-+ 0x20, 0x20, 0xf8, 0x20, 0x20, 0xc0, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4a, 0x4b, 0x4a, 0x4a, 0x4b,
-+ 0x48, 0x7b, 0x48, 0x40, 0x0f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x7e, 0x09, 0x19, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x0f, 0x09, 0x0e, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0xfc, 0x90, 0x08, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0f, 0x0f, 0x08, 0x0f, 0x7f,
-+ 0x05, 0x1f, 0x69, 0x09, 0x09, 0x01, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xe0, 0xe0, 0x20, 0xe0, 0xfc,
-+ 0x40, 0xf0, 0x2c, 0x20, 0x60, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x24, 0x25, 0x3d, 0x25, 0x25,
-+ 0x3d, 0x24, 0x27, 0x24, 0x25, 0x4e, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x90, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x40, 0xfc, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x09, 0x1a, 0x1c, 0x1a,
-+ 0x2a, 0x28, 0x48, 0x09, 0x0a, 0x0c, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x48, 0x40, 0x60, 0x60,
-+ 0x60, 0xa0, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x25, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3f, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x40, 0x78, 0xc8, 0xf8,
-+ 0x48, 0x78, 0x48, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x7e, 0x08, 0x19, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x09, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3b, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x88, 0x50, 0xfc, 0x30, 0xf8, 0xb8, 0xd8, 0xf8,
-+ 0xf8, 0x10, 0xfc, 0x90, 0x50, 0x30, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7d, 0x12, 0x12, 0x3e, 0x35,
-+ 0x34, 0x51, 0x51, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0xfc, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xfc, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x7f, 0x02, 0x02, 0x12, 0x12,
-+ 0x22, 0x42, 0x04, 0x04, 0x08, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x40, 0x40, 0x50, 0x48,
-+ 0x44, 0x44, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x12, 0x13, 0x30, 0x53, 0x10,
-+ 0x10, 0x17, 0x10, 0x10, 0x13, 0x1c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x00, 0xf8, 0x40,
-+ 0x40, 0xfc, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02,
-+ 0x02, 0x01, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40,
-+ 0x80, 0x00, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x10, 0x10, 0x13, 0x1c,
-+ 0x70, 0x11, 0x12, 0x14, 0x10, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0xe0,
-+ 0xe0, 0x50, 0x48, 0x44, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x7f, 0x01, 0x01, 0x1f, 0x01,
-+ 0x03, 0x05, 0x19, 0x61, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf0, 0x00,
-+ 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x47, 0x20, 0x20, 0x03, 0x08,
-+ 0x08, 0x09, 0x11, 0x12, 0x24, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0xe0,
-+ 0xe0, 0x50, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x01, 0x21, 0x11, 0x12, 0x07, 0x00, 0x70, 0x11,
-+ 0x12, 0x12, 0x11, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x40, 0x80, 0x00,
-+ 0x04, 0x04, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x12, 0x13, 0x32, 0x52, 0x12,
-+ 0x14, 0x14, 0x18, 0x11, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x28, 0x20, 0x90,
-+ 0x50, 0x48, 0x04, 0x80, 0x60, 0x10, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3f, 0x29, 0x2b, 0x3b, 0x25,
-+ 0x2b, 0x3f, 0x25, 0x2f, 0x35, 0x25, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0xd8, 0xd8,
-+ 0xf8, 0x68, 0x58, 0xf8, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x1f, 0x13, 0x16, 0x1b, 0x12,
-+ 0x13, 0x10, 0x27, 0x24, 0x47, 0x04, 0x00, 0x00,
-+ 0x80, 0xfc, 0x10, 0xfc, 0x30, 0xd8, 0xf4, 0x10,
-+ 0xf0, 0x80, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x02, 0x02, 0x03, 0x02, 0x02,
-+ 0x04, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0xf0, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x19, 0x35, 0x35, 0x33, 0x52,
-+ 0x13, 0x17, 0x10, 0x10, 0x11, 0x1e, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xf8, 0xa8,
-+ 0xf8, 0xf8, 0x90, 0x60, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x21, 0x11, 0x1f, 0x41, 0x2f, 0x20, 0x0f, 0x18,
-+ 0x1a, 0x2a, 0x2b, 0x4a, 0x48, 0x48, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x20, 0xfc, 0x80, 0xf8, 0x88,
-+ 0xa8, 0xa8, 0xe8, 0x28, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x43, 0x22, 0x23, 0x07, 0x15,
-+ 0x17, 0x23, 0x21, 0x40, 0x41, 0x4e, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xf8, 0x28,
-+ 0xf8, 0xf0, 0x20, 0xc0, 0xe0, 0x1c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x0f, 0x08, 0x0f, 0x0f, 0x1f, 0x12,
-+ 0x1f, 0x3f, 0x04, 0x02, 0x07, 0x78, 0x00, 0x00,
-+ 0x40, 0xfc, 0xe0, 0x20, 0xe0, 0xe0, 0xf0, 0x90,
-+ 0xf0, 0xe0, 0x40, 0x80, 0x80, 0x78, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x48, 0x48, 0x4f, 0x48, 0x48,
-+ 0x49, 0x7a, 0x4c, 0x48, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0xe0, 0xe0,
-+ 0x50, 0x48, 0x44, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x01, 0x01, 0x7f, 0x01, 0x03,
-+ 0x05, 0x19, 0x61, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x00, 0x80,
-+ 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x10, 0x3e, 0x2a, 0x3e, 0x2b, 0x3e, 0x2c,
-+ 0x0d, 0x0d, 0x16, 0x17, 0x24, 0x43, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x70, 0x70,
-+ 0xa8, 0x24, 0xa0, 0xa0, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x20, 0x20, 0x20, 0x3f, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x1f, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10,
-+ 0x00, 0x00, 0x00, 0x08, 0x08, 0xf8, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x4d, 0x3f, 0x08, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x7f, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0xfc, 0xa0, 0x30, 0xf8, 0x20, 0xe0, 0x20,
-+ 0xe0, 0x20, 0xfc, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x00, 0x11, 0x11, 0x11, 0x55, 0x55, 0x55, 0x55,
-+ 0x55, 0x7c, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x24, 0x24, 0xfc, 0x24, 0x24, 0xfc,
-+ 0x24, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x22, 0x45, 0x15, 0x14, 0x25,
-+ 0x07, 0x19, 0x11, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x50, 0x48, 0x84, 0x24,
-+ 0xe0, 0x00, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x23, 0x54, 0x15, 0x27, 0x19,
-+ 0x0f, 0x09, 0x0f, 0x01, 0x01, 0x3e, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x48, 0x90, 0x28, 0xe4, 0x00,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xf0, 0x08, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x40, 0x23, 0x20, 0x07, 0x11,
-+ 0x13, 0x14, 0x23, 0x20, 0x41, 0x46, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0xa0, 0xfc, 0x10,
-+ 0xe8, 0x44, 0xf8, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x01, 0x7f, 0x0f, 0x08, 0x7f,
-+ 0x08, 0x0f, 0x0c, 0x74, 0x07, 0x38, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x00, 0xfc, 0xe0, 0x20, 0xfc,
-+ 0x20, 0xe0, 0x88, 0x50, 0x30, 0x0c, 0x00, 0x00,
-+ 0x04, 0x18, 0x70, 0x11, 0x12, 0x7c, 0x13, 0x18,
-+ 0x34, 0x34, 0x52, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xe8, 0x04, 0xf8, 0x10,
-+ 0x60, 0x28, 0xa4, 0x84, 0x90, 0x70, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x3d, 0x25, 0x25, 0x3d,
-+ 0x25, 0x25, 0x25, 0x26, 0x26, 0x4c, 0x00, 0x00,
-+ 0x18, 0xe0, 0x00, 0x0c, 0x70, 0x64, 0x64, 0x68,
-+ 0x50, 0x50, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7e, 0x12, 0x12, 0x13,
-+ 0x3d, 0x24, 0x06, 0x0a, 0x10, 0x23, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xb0, 0xa8, 0xa8, 0xa4, 0x2c,
-+ 0x28, 0x70, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2b, 0x2c, 0x08, 0x7f, 0x08, 0x1c,
-+ 0x1b, 0x2a, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x40, 0x40, 0xf8, 0x40, 0x40,
-+ 0xfc, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x10, 0x1f,
-+ 0x10, 0x10, 0x10, 0x16, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x88, 0x80, 0xfc,
-+ 0x40, 0x40, 0x24, 0x14, 0x0c, 0x04, 0x00, 0x00,
-+ 0x00, 0x79, 0x49, 0x49, 0x79, 0x49, 0x49, 0x79,
-+ 0x49, 0x49, 0x79, 0x49, 0x41, 0x06, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x20, 0x20, 0xfc,
-+ 0x20, 0x20, 0x10, 0x54, 0x8c, 0x04, 0x00, 0x00,
-+ 0x00, 0x3e, 0x04, 0x19, 0x0a, 0x7e, 0x0a, 0x1b,
-+ 0x1c, 0x2b, 0x48, 0x08, 0x09, 0x1a, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x90, 0x50, 0x20, 0xd0, 0x4c,
-+ 0x40, 0xf8, 0x48, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x1f, 0x12, 0x1f, 0x00, 0x3f,
-+ 0x21, 0x43, 0x1e, 0x01, 0x03, 0x3c, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x90, 0xf0, 0x00, 0xfc,
-+ 0x08, 0xe0, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x1a, 0x2a, 0x7f, 0x0a, 0x0a,
-+ 0x0a, 0x7f, 0x00, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0xa0, 0xa0, 0xf8, 0xa0, 0xa0,
-+ 0xa0, 0xfc, 0x00, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x04, 0x3f, 0x09, 0x0f, 0x11,
-+ 0x21, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x40, 0x20, 0xf0, 0x08, 0x00, 0xf0, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x02, 0x01, 0x00, 0x7f, 0x00, 0x01,
-+ 0x02, 0x04, 0x18, 0x60, 0x00, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x20, 0x40, 0x80, 0xfc, 0x88, 0x90,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x5d, 0x01, 0x3e,
-+ 0x14, 0x7f, 0x1b, 0x2c, 0x48, 0x19, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x78, 0x70, 0x40, 0x7c,
-+ 0xd0, 0x70, 0xac, 0xf8, 0x48, 0x98, 0x00, 0x00,
-+ 0x04, 0x3e, 0x05, 0x04, 0x7f, 0x14, 0x14, 0x3c,
-+ 0x34, 0x34, 0x36, 0x3f, 0x63, 0x02, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7e, 0x08, 0x18, 0x1c, 0x1a,
-+ 0x2a, 0x28, 0x48, 0x09, 0x0a, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x00, 0xf8, 0x88, 0x88, 0xf8,
-+ 0x20, 0xb0, 0xa8, 0x24, 0x24, 0x60, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x11, 0x7d, 0x25, 0x26, 0x25,
-+ 0x75, 0x49, 0x0d, 0x15, 0x21, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0x50, 0x78, 0xc0, 0x3c, 0xf8,
-+ 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7e, 0x12, 0x12, 0x12,
-+ 0x3a, 0x24, 0x06, 0x0a, 0x10, 0x23, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0xf8,
-+ 0xa4, 0xa8, 0x90, 0xb0, 0xc8, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x4f, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x01, 0x7f, 0x00, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xe0, 0x20, 0xe0, 0x20, 0xe0,
-+ 0x00, 0xfc, 0x00, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x02, 0x02, 0x07, 0x04, 0x0c, 0x12, 0x21, 0x02,
-+ 0x07, 0x1c, 0x64, 0x04, 0x07, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0xe0, 0x20, 0x40, 0x80, 0x00, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x02, 0x04, 0x18, 0x6f, 0x00, 0x3c, 0x24,
-+ 0x24, 0x24, 0x3c, 0x24, 0x20, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0x30, 0xec, 0x00, 0xf8, 0x88,
-+ 0x88, 0x88, 0x88, 0xf0, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x7c, 0x44, 0x44, 0x44, 0x7c, 0x44, 0x44,
-+ 0x44, 0x7c, 0x45, 0x41, 0x02, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88,
-+ 0x88, 0xf8, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x21, 0x02,
-+ 0x1f, 0x12, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0x18,
-+ 0xf0, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x24, 0x12, 0x12, 0x00, 0x0f, 0x71, 0x11,
-+ 0x12, 0x14, 0x10, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x80, 0x90, 0x90, 0xa0, 0x80, 0xf8, 0xc0, 0xa0,
-+ 0x90, 0x88, 0x80, 0x80, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5d, 0x08, 0x7e,
-+ 0x08, 0x2b, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0x90, 0x50, 0x20, 0x40,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x4a, 0x4b, 0x4a, 0x4b, 0x4b,
-+ 0x4a, 0x7b, 0x4a, 0x45, 0x05, 0x08, 0x00, 0x00,
-+ 0x40, 0x80, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xfc,
-+ 0x00, 0xfc, 0xa4, 0x54, 0x04, 0x18, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x10, 0x7d, 0x27, 0x24, 0x24,
-+ 0x77, 0x48, 0x0c, 0x14, 0x27, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0xa0, 0x10, 0xf8, 0x48, 0x40,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x28, 0x28, 0x28, 0x3e, 0x28, 0x48, 0x08,
-+ 0x0e, 0x78, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0x88, 0x88, 0x90, 0xa0, 0xc0,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x47, 0x24, 0x27, 0x05, 0x17,
-+ 0x17, 0x15, 0x25, 0x2a, 0x4c, 0x50, 0x00, 0x00,
-+ 0x20, 0x28, 0x24, 0xfc, 0x20, 0xe8, 0x28, 0x68,
-+ 0xb0, 0x10, 0xb0, 0x54, 0x8c, 0x04, 0x00, 0x00,
-+ 0x04, 0x07, 0x08, 0x11, 0x7f, 0x11, 0x11, 0x1f,
-+ 0x12, 0x02, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0xc0, 0x80, 0x00, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x90, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7e, 0x08, 0x1c, 0x1a, 0x1a,
-+ 0x29, 0x29, 0x49, 0x09, 0x09, 0x08, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x20,
-+ 0xfc, 0x24, 0x24, 0x24, 0x38, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x15, 0x65, 0x19, 0x19, 0x25, 0x7c,
-+ 0x13, 0x3a, 0x36, 0x32, 0x52, 0x10, 0x00, 0x00,
-+ 0x40, 0x80, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x40,
-+ 0xf8, 0x48, 0x48, 0x48, 0x70, 0x40, 0x00, 0x00,
-+ 0x10, 0x17, 0x14, 0x64, 0x1b, 0x1a, 0x26, 0x7e,
-+ 0x12, 0x3a, 0x36, 0x36, 0x53, 0x12, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x80, 0xf8, 0xa8, 0xa8, 0xe8,
-+ 0xa8, 0xe8, 0xa8, 0xa8, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x02, 0x3f, 0x24, 0x24, 0x27,
-+ 0x24, 0x27, 0x24, 0x24, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x48, 0x48, 0xc8,
-+ 0x48, 0xc8, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x09, 0x7e, 0x08, 0x3f, 0x09, 0x7f, 0x11,
-+ 0x1d, 0x25, 0x55, 0x09, 0x16, 0x61, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x80, 0xfc, 0x54, 0x74, 0x54,
-+ 0x74, 0x54, 0xfc, 0x04, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x7c, 0x11, 0x11, 0x19, 0x11,
-+ 0x31, 0x50, 0x17, 0x10, 0x11, 0x36, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xfc, 0xa0, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x40, 0xfc, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x7e, 0x09, 0x1d, 0x1b, 0x1b,
-+ 0x29, 0x28, 0x4f, 0x08, 0x09, 0x0e, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x90, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x40, 0xfc, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x01, 0x01, 0x1f, 0x11,
-+ 0x10, 0x10, 0x10, 0x10, 0x21, 0x46, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x10, 0x08, 0xfc, 0x00,
-+ 0x90, 0x90, 0x60, 0x64, 0x9c, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x08, 0x08, 0x07, 0x01, 0x02,
-+ 0x7f, 0x04, 0x0f, 0x10, 0x03, 0x3c, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x00, 0x00,
-+ 0xfc, 0x20, 0x40, 0xc0, 0x30, 0x08, 0x00, 0x00,
-+ 0x1f, 0x00, 0x01, 0x01, 0x7f, 0x01, 0x03, 0x1f,
-+ 0x12, 0x12, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0xf0, 0x60, 0x80, 0x00, 0xfc, 0x00, 0x00, 0xf0,
-+ 0x90, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x1e, 0x02, 0x02, 0x3f, 0x02, 0x02,
-+ 0x7f, 0x02, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00,
-+ 0xfc, 0x00, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x08, 0x4b, 0x30, 0x10, 0x37, 0x48, 0x08, 0x1b,
-+ 0x2a, 0x4a, 0x0a, 0x0a, 0x0f, 0x30, 0x00, 0x00,
-+ 0x00, 0xf8, 0x10, 0x60, 0xfc, 0x40, 0xc0, 0xf8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x08, 0x07, 0x00, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x00, 0xe0, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x10, 0x13, 0x17, 0x66, 0x1a, 0x1b, 0x26, 0x7f,
-+ 0x12, 0x3a, 0x36, 0x36, 0x52, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0xa8, 0xc8, 0xf8, 0x48, 0xf8,
-+ 0x88, 0x88, 0x88, 0x78, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x7e, 0x09, 0x7e, 0x08,
-+ 0x1d, 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x40, 0x58, 0xe0, 0x40, 0x5c,
-+ 0xe0, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3f, 0x2f, 0x40, 0x7f, 0x03,
-+ 0x3d, 0x06, 0x39, 0x06, 0x78, 0x03, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xfc, 0xe8, 0x00, 0xfc, 0x48,
-+ 0xd0, 0xa0, 0x90, 0x88, 0x84, 0x00, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x1f, 0x10, 0x37, 0x50, 0x17,
-+ 0x10, 0x17, 0x15, 0x15, 0x17, 0x15, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x28, 0x30, 0xfc, 0x20, 0x78,
-+ 0xc8, 0x78, 0x48, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x7f, 0x03, 0x03, 0x05,
-+ 0x09, 0x11, 0x21, 0x41, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x80, 0x80, 0x40,
-+ 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x25, 0x3f, 0x25, 0x3f, 0x04, 0x3f,
-+ 0x06, 0x78, 0x14, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x30, 0x28, 0x28, 0xfc, 0x20, 0x20, 0x50, 0x50,
-+ 0x88, 0x04, 0x90, 0x48, 0x44, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x10, 0x1f, 0x10, 0x10,
-+ 0x1f, 0x10, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01,
-+ 0x1f, 0x01, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00,
-+ 0xf0, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x0f, 0x12, 0x12, 0x22, 0x44,
-+ 0x04, 0x08, 0x10, 0x01, 0x02, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x88, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x09, 0x0c, 0x12, 0x2b, 0x48, 0x3c, 0x24, 0x3f,
-+ 0x24, 0x3c, 0x28, 0x25, 0x3b, 0x62, 0x00, 0x00,
-+ 0x08, 0x88, 0x90, 0xfc, 0x90, 0x90, 0x90, 0xfc,
-+ 0x90, 0x90, 0x90, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x7f, 0x03, 0x03, 0x03,
-+ 0x05, 0x05, 0x09, 0x11, 0x21, 0x40, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x10,
-+ 0x1f, 0x10, 0x21, 0x22, 0x4c, 0x30, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0x88, 0x80,
-+ 0xfc, 0x80, 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x08, 0x09, 0x4a, 0x2a, 0x2c, 0x09, 0x7e, 0x0c,
-+ 0x1a, 0x1a, 0x28, 0x48, 0x09, 0x0a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x48, 0xc8, 0x68,
-+ 0x58, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x09, 0x7f, 0x09, 0x09, 0x0f, 0x0f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xe0, 0xf8, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x20, 0x27,
-+ 0x24, 0x24, 0x27, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0xc8,
-+ 0x48, 0x48, 0xc8, 0x48, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x21, 0x20,
-+ 0x22, 0x2a, 0x2a, 0x32, 0x21, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0x88,
-+ 0x88, 0x28, 0x58, 0x58, 0xc8, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x73, 0x14, 0x0c, 0x12, 0x7e,
-+ 0x0c, 0x2a, 0x2a, 0x28, 0x49, 0x0e, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x88, 0x88, 0x88, 0x50,
-+ 0x50, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x0f, 0x09, 0x15, 0x13, 0x21,
-+ 0x42, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10, 0x10,
-+ 0xd0, 0x30, 0x1c, 0x10, 0x20, 0xc0, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x11, 0x11, 0x17, 0x19, 0x71,
-+ 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x30, 0xd0, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x60, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x00, 0x20, 0x10, 0x11, 0x01, 0x07, 0x10,
-+ 0x13, 0x22, 0x22, 0x42, 0x43, 0x02, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xa0, 0x10, 0x38, 0xc4, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x08, 0x08, 0x10, 0x11, 0x31,
-+ 0x53, 0x14, 0x10, 0x10, 0x13, 0x1c, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x80, 0x80, 0xf0, 0x90, 0x50,
-+ 0x20, 0xa0, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x02, 0x0c, 0x32, 0x01, 0x06, 0x78, 0x3f, 0x12,
-+ 0x1e, 0x12, 0x1e, 0x13, 0x7e, 0x02, 0x00, 0x00,
-+ 0xc0, 0x30, 0x48, 0x80, 0x60, 0x1c, 0xf8, 0x50,
-+ 0x70, 0x48, 0x44, 0x44, 0x78, 0x40, 0x00, 0x00,
-+ 0x00, 0x7f, 0x12, 0x12, 0x1e, 0x12, 0x12, 0x1e,
-+ 0x12, 0x13, 0x1e, 0x62, 0x02, 0x02, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x50, 0x50, 0x60, 0x50, 0x48,
-+ 0x44, 0x44, 0x64, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x3f, 0x2a, 0x2a, 0x3e, 0x2b, 0x2a, 0x3e,
-+ 0x08, 0x3e, 0x08, 0x0e, 0x70, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x90, 0x60, 0x20, 0xfc, 0x28, 0x30,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x7c, 0x04, 0x05, 0x3d, 0x26, 0x20, 0x3c,
-+ 0x24, 0x25, 0x05, 0x06, 0x08, 0x30, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x20, 0x20, 0xb0, 0xa8,
-+ 0xa8, 0x24, 0x24, 0x24, 0x20, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x1f, 0x11, 0x21, 0x01, 0x7f,
-+ 0x01, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0xfc,
-+ 0x00, 0x80, 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x13, 0x12, 0x12, 0x12,
-+ 0x12, 0x12, 0x12, 0x22, 0x22, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10,
-+ 0x10, 0x60, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x11, 0x21, 0x49, 0x09, 0x12, 0x14, 0x37,
-+ 0x51, 0x11, 0x10, 0x10, 0x13, 0x1c, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0xf0,
-+ 0x10, 0x20, 0xc0, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0d, 0x12, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x88, 0x08, 0x88, 0x48,
-+ 0x48, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x27, 0x14, 0x0f, 0x14, 0x67,
-+ 0x01, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xc8, 0x50, 0xe0, 0x58, 0xc4,
-+ 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x00, 0x3c, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x25, 0x25, 0x3e, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0xa8, 0xa0,
-+ 0xa0, 0xa0, 0x10, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x27, 0x3c, 0x2b, 0x08, 0x2d,
-+ 0x2b, 0x29, 0x29, 0x2f, 0x39, 0x61, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x90, 0xfc,
-+ 0x20, 0xf8, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00,
-+ 0x00, 0x09, 0x08, 0x08, 0x7e, 0x05, 0x24, 0x14,
-+ 0x14, 0x08, 0x0e, 0x70, 0x00, 0x00, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0xf8,
-+ 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x98, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x12, 0x1a, 0x36, 0x36,
-+ 0x32, 0x53, 0x14, 0x11, 0x11, 0x12, 0x00, 0x00,
-+ 0x40, 0x80, 0x38, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xb8, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x04, 0x7f, 0x0c, 0x2a, 0x1c, 0x7f, 0x1c, 0x2a,
-+ 0x7f, 0x12, 0x3c, 0x04, 0x1a, 0x63, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x7c, 0x90, 0x90,
-+ 0x50, 0x60, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x12, 0x19, 0x25, 0x24, 0x79, 0x10, 0x7f,
-+ 0x11, 0x55, 0x39, 0x31, 0x1e, 0x64, 0x00, 0x00,
-+ 0x20, 0xf8, 0xa8, 0xf8, 0x20, 0xfc, 0x70, 0x50,
-+ 0x70, 0x78, 0x48, 0x78, 0xc0, 0x7c, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x19, 0x37, 0x34, 0x37, 0x54,
-+ 0x17, 0x14, 0x17, 0x14, 0x14, 0x15, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0x88, 0x98, 0x00, 0x00,
-+ 0x01, 0x02, 0x04, 0x1f, 0x7e, 0x12, 0x1e, 0x1e,
-+ 0x12, 0x17, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0xf0, 0x9c, 0x90, 0x90, 0x90,
-+ 0x10, 0x30, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x40, 0x23, 0x22, 0x02, 0x0a,
-+ 0x0b, 0x0a, 0x12, 0x12, 0x23, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0xf8, 0x48, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x4f, 0x29, 0x2b, 0x0a, 0x1b,
-+ 0x2b, 0x4a, 0x10, 0x15, 0x25, 0x48, 0x00, 0x00,
-+ 0x80, 0xfc, 0xc0, 0x30, 0xfc, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0x98, 0xc0, 0x28, 0x14, 0xf4, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x38, 0x00, 0x7d, 0x03, 0x3c, 0x03, 0x3a,
-+ 0x03, 0x3a, 0x2b, 0x2a, 0x3a, 0x2a, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0x88, 0x98, 0x00, 0x00,
-+ 0x10, 0x10, 0x7e, 0x10, 0x7d, 0x57, 0x7c, 0x57,
-+ 0x7e, 0x13, 0x7e, 0x13, 0x12, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xf8, 0x04, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0x88, 0x98, 0x00, 0x00,
-+ 0x00, 0x00, 0x79, 0x49, 0x4b, 0x4b, 0x4d, 0x49,
-+ 0x49, 0x79, 0x49, 0x41, 0x01, 0x01, 0x00, 0x00,
-+ 0x90, 0x90, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x17, 0x11, 0x31, 0x52, 0x13,
-+ 0x15, 0x19, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x00, 0x00, 0x00, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x11, 0x11, 0x31, 0x57, 0x17,
-+ 0x1a, 0x14, 0x11, 0x16, 0x11, 0x1e, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf0, 0xf0, 0xf0, 0xfc, 0x58,
-+ 0xe8, 0xf4, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x04, 0x03, 0x1f, 0x11, 0x1f, 0x11,
-+ 0x1f, 0x01, 0x7f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0xe0, 0xc0, 0x00, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x00, 0xf8, 0x08, 0x08, 0x70, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x7f, 0x02, 0x02, 0x07, 0x06,
-+ 0x05, 0x09, 0x08, 0x11, 0x26, 0x58, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf0, 0x10,
-+ 0x20, 0x40, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x02, 0x02, 0x3f, 0x22, 0x7f, 0x04, 0x07, 0x0c,
-+ 0x0f, 0x14, 0x27, 0x44, 0x04, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0xfc, 0x00, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x01, 0x05, 0x25, 0x39, 0x2b, 0x2b, 0x25, 0x27,
-+ 0x2b, 0x3f, 0x21, 0x3f, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x20, 0x28, 0xc8, 0x58, 0x58, 0x28, 0x38,
-+ 0x58, 0xf8, 0x08, 0xf8, 0x08, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x15, 0x36, 0x54, 0x15, 0x16,
-+ 0x11, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x10, 0xa0, 0x40, 0xb0, 0x0c,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x0f, 0x0f, 0x0f, 0x3f, 0x25,
-+ 0x57, 0x23, 0x0e, 0x31, 0x07, 0x78, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xe0, 0xe0, 0xe0, 0xfc, 0x38,
-+ 0xe8, 0xe4, 0x40, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x10, 0x17, 0x11, 0x1d,
-+ 0x71, 0x11, 0x11, 0x11, 0x17, 0x30, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xfc, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x1c, 0xf0, 0x10, 0x10, 0x00, 0x00,
-+ 0x02, 0x02, 0x7f, 0x04, 0x04, 0x0f, 0x0c, 0x17,
-+ 0x24, 0x47, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x13, 0x12, 0x3a, 0x36,
-+ 0x37, 0x52, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0xf8, 0x48, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x40, 0x23, 0x22, 0x03, 0x12,
-+ 0x13, 0x20, 0x2f, 0x40, 0x43, 0x4c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x90, 0x60, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0x40, 0xfc, 0x84, 0x04, 0x18, 0x00, 0x00,
-+ 0x10, 0x0b, 0x08, 0x40, 0x23, 0x22, 0x02, 0x0b,
-+ 0x0a, 0x0a, 0x13, 0x12, 0x22, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0xb0, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x09, 0x48, 0x30, 0x17, 0x30, 0x4b, 0x0a, 0x1a,
-+ 0x2b, 0x4a, 0x0b, 0x0a, 0x33, 0x12, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xfc, 0xa0, 0xf8, 0xa8, 0xa8,
-+ 0x38, 0x18, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x21, 0x11, 0x12, 0x7f, 0x0c, 0x3f, 0x2d, 0x2d,
-+ 0x37, 0x33, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x20, 0x28, 0x24, 0xa4, 0x20, 0xfc, 0x20, 0x20,
-+ 0x30, 0x50, 0x50, 0x88, 0x88, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x3f, 0x21, 0x21, 0x21,
-+ 0x3f, 0x21, 0x21, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x08, 0x08, 0x18, 0x14,
-+ 0x35, 0x51, 0x12, 0x14, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x80, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7e, 0x08, 0x0a, 0x14, 0x19,
-+ 0x37, 0x55, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0xa0, 0x90, 0x08, 0x48, 0x40, 0xa0, 0xa0, 0x10,
-+ 0xf8, 0x14, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x3d, 0x00, 0x7f, 0x00, 0x3d, 0x02, 0x3d,
-+ 0x00, 0x3c, 0x24, 0x25, 0x3d, 0x22, 0x00, 0x00,
-+ 0x18, 0xe0, 0x40, 0xfc, 0xe0, 0x50, 0x48, 0xe4,
-+ 0xa0, 0xb8, 0xa8, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x02, 0x22, 0x12, 0x1f, 0x02, 0x02, 0x73, 0x12,
-+ 0x12, 0x14, 0x14, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x40, 0x7c, 0x88, 0x90,
-+ 0xfc, 0x90, 0x90, 0xb0, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x08, 0x0f, 0x00, 0x3f, 0x21,
-+ 0x21, 0x3f, 0x20, 0x20, 0x20, 0x1f, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x00, 0xf8, 0x08,
-+ 0x08, 0xf8, 0x08, 0x00, 0x04, 0xfc, 0x00, 0x00,
-+ 0x01, 0x3e, 0x04, 0x3f, 0x15, 0x15, 0x7f, 0x15,
-+ 0x15, 0x3f, 0x04, 0x04, 0x07, 0x38, 0x00, 0x00,
-+ 0x80, 0x78, 0x48, 0xd0, 0x50, 0x60, 0xd0, 0x48,
-+ 0x44, 0xc4, 0x64, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x09, 0x0a, 0x0c, 0x0c,
-+ 0x14, 0x16, 0x29, 0x4f, 0x38, 0x00, 0x00, 0x00,
-+ 0x48, 0x48, 0x90, 0xfc, 0x90, 0x90, 0xf8, 0x90,
-+ 0x90, 0xf8, 0x90, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x00, 0x7f, 0x00, 0x3e, 0x22, 0x3e, 0x00, 0x7f,
-+ 0x55, 0x67, 0x5f, 0x49, 0x49, 0x4b, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xf8, 0xa8, 0xa8, 0xa8, 0xf8,
-+ 0xa8, 0x30, 0x28, 0x38, 0xe4, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x02, 0x02, 0x05, 0x08, 0x10,
-+ 0x00, 0x00, 0x00, 0x01, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x08, 0x08, 0x10, 0x90, 0x60,
-+ 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x02, 0x01, 0x01, 0x7f, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xf0, 0x20, 0x40, 0x80, 0xfc, 0x08, 0x10,
-+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x04, 0x18, 0x6f, 0x01, 0x01,
-+ 0x3f, 0x09, 0x09, 0x11, 0x21, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x40, 0x30, 0xec, 0x00, 0x00,
-+ 0xf8, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x07, 0x04, 0x04, 0x07, 0x04, 0x00,
-+ 0x7f, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x00, 0x00, 0xc0, 0x40, 0x40,
-+ 0xfc, 0x40, 0x40, 0x40, 0x40, 0x80, 0x00, 0x00,
-+ 0x12, 0x09, 0x7f, 0x10, 0x17, 0x3f, 0x40, 0x07,
-+ 0x07, 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x10, 0x20, 0xfc, 0x20, 0xd0, 0xf8, 0x04, 0xc0,
-+ 0xc0, 0x00, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x09, 0x31, 0x2f, 0x27, 0x35, 0x27, 0x25, 0x37,
-+ 0x2f, 0x21, 0x7f, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x38, 0xe8, 0xc8, 0x58, 0xc8, 0x48, 0xd8,
-+ 0xe8, 0x08, 0xfc, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x12, 0x0c, 0x08, 0x7f, 0x09, 0x0a,
-+ 0x0c, 0x08, 0x08, 0x08, 0x08, 0x1b, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x17, 0x14, 0x27, 0x24, 0x67, 0x27, 0x24,
-+ 0x27, 0x26, 0x2b, 0x2b, 0x32, 0x22, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xfc, 0xf8, 0x40,
-+ 0xf8, 0x48, 0xf8, 0xf8, 0x48, 0x58, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x12, 0x53, 0x24, 0x14, 0x08,
-+ 0x0c, 0x12, 0x16, 0x3a, 0x61, 0x02, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x08, 0x7e, 0x12, 0x13, 0x12,
-+ 0x3c, 0x24, 0x06, 0x0a, 0x11, 0x22, 0x00, 0x00,
-+ 0x08, 0x30, 0xe0, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x24, 0x44, 0x09, 0x12, 0x04,
-+ 0x18, 0x6f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x48, 0x20, 0x10, 0x90, 0x40,
-+ 0x30, 0xec, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x17, 0x10, 0x1f, 0x17, 0x10,
-+ 0x17, 0x14, 0x27, 0x27, 0x44, 0x04, 0x00, 0x00,
-+ 0x80, 0xfc, 0x80, 0xf0, 0x90, 0xfc, 0xf0, 0x80,
-+ 0xf0, 0x90, 0xf0, 0xf0, 0x90, 0xb0, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x11, 0x11, 0x10, 0x1f,
-+ 0x71, 0x13, 0x14, 0x11, 0x12, 0x30, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xf8, 0xa8, 0x28, 0x48, 0xb0, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7d, 0x11, 0x10, 0x13, 0x18,
-+ 0x77, 0x10, 0x12, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x38, 0xc8, 0x48, 0x50, 0x20, 0x40, 0xf8, 0x40,
-+ 0xfc, 0x40, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x79, 0x11, 0x16, 0x12, 0x19,
-+ 0x72, 0x17, 0x11, 0x11, 0x12, 0x34, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x28, 0x28, 0xfc, 0xd0, 0x7c,
-+ 0xd0, 0xfc, 0x50, 0x50, 0x7c, 0x40, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x4b, 0x48, 0x4f, 0x79, 0x4b,
-+ 0x4e, 0x4b, 0x7a, 0x4b, 0x42, 0x03, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xb8, 0x88, 0xf8, 0x20, 0xf8,
-+ 0x40, 0xf0, 0x40, 0xf0, 0x40, 0xf8, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x11, 0x19, 0x34, 0x37,
-+ 0x31, 0x53, 0x54, 0x11, 0x12, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xf8, 0xa8, 0x28, 0x48, 0xb0, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7e, 0x08, 0x18, 0x1d, 0x1b,
-+ 0x2a, 0x28, 0x48, 0x0b, 0x08, 0x08, 0x00, 0x00,
-+ 0x88, 0x50, 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x24,
-+ 0xb8, 0x70, 0xa8, 0x24, 0x20, 0x60, 0x00, 0x00,
-+ 0x11, 0x08, 0x08, 0x47, 0x20, 0x20, 0x03, 0x08,
-+ 0x08, 0x0f, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xfc, 0x40, 0x40, 0xf8, 0x40,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x25, 0x21, 0x02, 0x10,
-+ 0x11, 0x23, 0x25, 0x41, 0x41, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0x10, 0x48, 0x48, 0xa0,
-+ 0x10, 0xf8, 0x14, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x16, 0x35, 0x35, 0x3a, 0x50,
-+ 0x11, 0x1f, 0x15, 0x25, 0x21, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0x10, 0x48, 0x48, 0xa0,
-+ 0x10, 0xfc, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x11, 0x11, 0x1f, 0x11, 0x11,
-+ 0x1f, 0x11, 0x11, 0x11, 0x21, 0x40, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x01, 0x3f, 0x24, 0x4c, 0x12, 0x3f, 0x01, 0x0f,
-+ 0x01, 0x3f, 0x00, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0x48, 0xb8, 0xf0, 0x00, 0xe0,
-+ 0x00, 0xf8, 0x00, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x08, 0x04, 0x04, 0x3f, 0x01, 0x01, 0x1f, 0x01,
-+ 0x01, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0xf8, 0x00, 0x00, 0xf0, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x4a, 0x2b, 0x2c, 0x09, 0x7e, 0x19,
-+ 0x1b, 0x19, 0x1b, 0x2d, 0x29, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x90, 0xfc,
-+ 0x20, 0xf8, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x09, 0x7f, 0x09, 0x09, 0x0f,
-+ 0x01, 0x3f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x20, 0xfc, 0x20, 0xe0, 0xf0,
-+ 0x00, 0xf8, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x01, 0x3f, 0x24, 0x49, 0x12,
-+ 0x04, 0x1f, 0x68, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x00, 0xfc, 0x48, 0x20, 0x90,
-+ 0x40, 0xf0, 0x2c, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x1f, 0x12, 0x12, 0x1f, 0x02,
-+ 0x7f, 0x04, 0x0f, 0x08, 0x03, 0x3c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0xf0, 0x90, 0x90, 0xf0, 0x00,
-+ 0xfc, 0x40, 0x40, 0xc0, 0x30, 0x08, 0x00, 0x00,
-+ 0x00, 0x3c, 0x03, 0x7e, 0x01, 0x3d, 0x03, 0x3c,
-+ 0x03, 0x38, 0x2a, 0x2a, 0x3b, 0x22, 0x00, 0x00,
-+ 0x08, 0x30, 0xc8, 0x48, 0x50, 0x20, 0xf8, 0x40,
-+ 0xfc, 0x40, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x3d, 0x29, 0x09, 0x2f,
-+ 0x29, 0x29, 0x29, 0x2f, 0x39, 0x61, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa0, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x00, 0x27, 0x12, 0x11, 0x01, 0x03, 0x70, 0x17,
-+ 0x12, 0x12, 0x13, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x3c, 0xc8, 0x48, 0x50, 0x20, 0xf8, 0x40, 0xfc,
-+ 0x48, 0x48, 0xf8, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x29, 0x29, 0x31, 0x28, 0x27,
-+ 0x25, 0x25, 0x3a, 0x24, 0x21, 0x22, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0x48, 0xb0, 0x00, 0x00,
-+ 0x04, 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x05, 0x1f,
-+ 0x67, 0x04, 0x07, 0x05, 0x06, 0x38, 0x00, 0x00,
-+ 0x40, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x40, 0xf0,
-+ 0xcc, 0x40, 0xe0, 0x20, 0xc0, 0x38, 0x00, 0x00,
-+ 0x14, 0x12, 0x2a, 0x0c, 0x13, 0x3e, 0x52, 0x1f,
-+ 0x01, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa8, 0x30, 0x20, 0x50, 0x88,
-+ 0x04, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x12, 0x12, 0x12, 0x1e,
-+ 0x72, 0x13, 0x1e, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x80, 0x80, 0x78, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0xc8, 0x70, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x14, 0x12, 0x22, 0x48, 0x08, 0x14, 0x13, 0x22,
-+ 0x7e, 0x22, 0x22, 0x3e, 0x23, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa8, 0x30, 0x20,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x40, 0x20, 0x20, 0x07, 0x10,
-+ 0x10, 0x20, 0x20, 0x41, 0x42, 0x4c, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x40, 0x40, 0x40, 0xfc, 0x40,
-+ 0x40, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x11, 0x09, 0x0a, 0x42, 0x24, 0x20, 0x01, 0x12,
-+ 0x17, 0x1a, 0x22, 0x22, 0x43, 0x42, 0x00, 0x00,
-+ 0x20, 0x10, 0x08, 0x48, 0x40, 0xa0, 0x20, 0x10,
-+ 0xf8, 0x14, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x12, 0x0a, 0x0e, 0x32, 0x07, 0x01,
-+ 0x3f, 0x04, 0x02, 0x02, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x28, 0x38, 0xc8, 0x18, 0x00,
-+ 0xf8, 0x40, 0x40, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x12, 0x1a, 0x6f, 0x09, 0x0f, 0x09,
-+ 0x0f, 0x1f, 0x04, 0x7f, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0xf8, 0x98, 0x68, 0xf8, 0x20, 0xe0, 0x20,
-+ 0xe0, 0xf0, 0x40, 0xfc, 0x60, 0x18, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x24, 0x27, 0x00, 0x12,
-+ 0x12, 0x22, 0x22, 0x43, 0x44, 0x48, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0x00, 0xfc, 0x40, 0x40,
-+ 0x78, 0x40, 0x40, 0x40, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x10, 0x14, 0x64, 0x19,
-+ 0x16, 0x7e, 0x2c, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x88, 0x90, 0xfc, 0x90,
-+ 0xf8, 0x90, 0xf8, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x28, 0x0d, 0x0a, 0x0e, 0x71, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0x48, 0xd0,
-+ 0x28, 0xfc, 0xa4, 0xa8, 0x24, 0x20, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x0b, 0x0a, 0x17, 0x18,
-+ 0x37, 0x54, 0x11, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0xf8, 0x40,
-+ 0xfc, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x09, 0x05, 0x05, 0x7f, 0x01,
-+ 0x03, 0x05, 0x19, 0x61, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x20, 0x20, 0x40, 0xfc, 0x00,
-+ 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x01, 0x3f, 0x09, 0x05,
-+ 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x20, 0x40,
-+ 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x7f, 0x08, 0x3e, 0x2a, 0x2a, 0x3e,
-+ 0x1c, 0x1a, 0x2a, 0x48, 0x08, 0x0b, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x3f, 0x21, 0x5d, 0x1d, 0x00,
-+ 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0x08, 0x70, 0x70, 0x00,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x41, 0x23, 0x24, 0x00, 0x13,
-+ 0x1f, 0x22, 0x22, 0x42, 0x43, 0x42, 0x00, 0x00,
-+ 0x80, 0x80, 0xf0, 0x10, 0x20, 0xc0, 0xc0, 0x30,
-+ 0xfc, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0d, 0x12, 0x7e,
-+ 0x09, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0xd0, 0x20, 0x50, 0x88,
-+ 0xfc, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x10, 0x09, 0x4a, 0x20,
-+ 0x25, 0x0f, 0x11, 0x11, 0x21, 0x21, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xc0, 0xf0, 0x90, 0x60, 0x60,
-+ 0x90, 0xfc, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x20, 0xa0, 0x38, 0x48, 0xd0, 0x30, 0x30, 0x48,
-+ 0xfc, 0x48, 0x48, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x02, 0x0c, 0x38, 0x08, 0x08, 0x7f, 0x08, 0x08,
-+ 0x3e, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x02, 0x0c, 0x32, 0x22, 0x32, 0x2a, 0x2a, 0x22,
-+ 0x22, 0x2e, 0x74, 0x04, 0x08, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x88, 0xc8, 0xa8, 0xa8, 0x88,
-+ 0x88, 0x88, 0xf0, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x11, 0x11, 0x1f, 0x00, 0x1f, 0x10, 0x1f, 0x17,
-+ 0x15, 0x17, 0x15, 0x21, 0x2e, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0xf0, 0x00, 0xf0, 0xd0, 0x10, 0xd0,
-+ 0x50, 0xd0, 0x54, 0xec, 0x2c, 0x04, 0x00, 0x00,
-+ 0x10, 0x17, 0x14, 0x7f, 0x17, 0x34, 0x3f, 0x3d,
-+ 0x55, 0x55, 0x15, 0x14, 0x17, 0x14, 0x00, 0x00,
-+ 0x00, 0xbc, 0xa4, 0xbc, 0xbc, 0x44, 0xfc, 0xf4,
-+ 0xf4, 0x54, 0xf4, 0xe4, 0x5c, 0x4c, 0x00, 0x00,
-+ 0x20, 0x17, 0x15, 0x47, 0x24, 0x27, 0x05, 0x17,
-+ 0x10, 0x17, 0x25, 0x25, 0x5f, 0x40, 0x00, 0x00,
-+ 0x20, 0xe0, 0x20, 0xbc, 0xc0, 0x80, 0x38, 0xc0,
-+ 0x00, 0xf8, 0x28, 0x28, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3f, 0x24, 0x3e, 0x3f, 0x24,
-+ 0x3f, 0x1f, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x40, 0x7c, 0x80, 0x00, 0x78,
-+ 0x00, 0xf0, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x3e, 0x22, 0x3e, 0x3e, 0x21, 0x2f,
-+ 0x27, 0x27, 0x27, 0x23, 0x2d, 0x21, 0x00, 0x00,
-+ 0x40, 0xfc, 0xf8, 0x88, 0xf8, 0xf8, 0x08, 0xe8,
-+ 0xc8, 0xc8, 0xc8, 0x88, 0x68, 0x18, 0x00, 0x00,
-+ 0x00, 0x7e, 0x48, 0x7d, 0x7c, 0x7e, 0x4f, 0x08,
-+ 0x0f, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x00, 0x78, 0x00, 0xe0, 0x20,
-+ 0xe0, 0xe0, 0x20, 0xe0, 0x84, 0x7c, 0x00, 0x00,
-+ 0x01, 0x06, 0x3c, 0x04, 0x04, 0x7f, 0x0c, 0x0e,
-+ 0x15, 0x15, 0x24, 0x44, 0x04, 0x04, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x1f, 0x11, 0x11, 0x1f,
-+ 0x19, 0x05, 0x02, 0x05, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x10, 0x00, 0x00, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x12, 0x14, 0x1b, 0x12,
-+ 0x14, 0x1c, 0x14, 0x27, 0x24, 0x47, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x80, 0xfc, 0xf0, 0xf0,
-+ 0x90, 0xf0, 0xf8, 0x90, 0x60, 0x9c, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x03, 0x05, 0x19, 0x61, 0x0f,
-+ 0x00, 0x01, 0x7f, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x80, 0x40, 0x30, 0x0c, 0xe0,
-+ 0xc0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x3e, 0x04, 0x7f, 0x0e, 0x15, 0x64, 0x05,
-+ 0x3f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0xc8, 0x48, 0x48, 0x98, 0x00,
-+ 0xf8, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x7e, 0x12, 0x13, 0x12, 0x7e, 0x13,
-+ 0x10, 0x13, 0x18, 0x60, 0x07, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x07, 0x7e, 0x12, 0x12, 0x12, 0x7f, 0x10,
-+ 0x17, 0x14, 0x1c, 0x67, 0x04, 0x04, 0x00, 0x00,
-+ 0x40, 0xfc, 0x28, 0xa8, 0x68, 0x98, 0xf8, 0x40,
-+ 0xfc, 0x64, 0x94, 0xf4, 0x14, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x29, 0x2f, 0x09, 0x1f,
-+ 0x29, 0x4b, 0x13, 0x15, 0x29, 0x41, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x48, 0xa8, 0x28, 0x28, 0xe8,
-+ 0x28, 0xa8, 0x68, 0x48, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x7f, 0x0f, 0x09, 0x0f, 0x09, 0x0f, 0x3f,
-+ 0x01, 0x7f, 0x0c, 0x74, 0x07, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0xf8,
-+ 0x00, 0xfc, 0x90, 0x60, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x0b, 0x0a, 0x16, 0x1b,
-+ 0x34, 0x57, 0x10, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x1f,
-+ 0x01, 0x3f, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x26, 0x3a, 0x37, 0x3e, 0x08,
-+ 0x7f, 0x4d, 0x53, 0x7f, 0x41, 0x43, 0x00, 0x00,
-+ 0x48, 0x48, 0x50, 0xfc, 0xd0, 0x50, 0x78, 0x50,
-+ 0x50, 0x78, 0x50, 0x50, 0x7c, 0x40, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x28, 0x2b, 0x30, 0x29, 0x26,
-+ 0x24, 0x27, 0x38, 0x20, 0x27, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xfc, 0xa0, 0x24, 0x5c,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x23, 0x48, 0x0f, 0x10, 0x13, 0x30,
-+ 0x53, 0x10, 0x17, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8, 0x40,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x21, 0x16, 0x02, 0x19, 0x62,
-+ 0x0f, 0x01, 0x7f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x50, 0x80, 0xb0, 0x4c,
-+ 0xa0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x3f, 0x00, 0x08, 0x04, 0x04,
-+ 0x02, 0x02, 0x02, 0x00, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x40, 0x40, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x13, 0x10, 0x2f, 0x48, 0x13,
-+ 0x30, 0x57, 0x10, 0x1f, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0xc0, 0xf0, 0x90, 0xfc, 0x90, 0xf0,
-+ 0x80, 0xf8, 0x80, 0xfc, 0x80, 0x80, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x7c, 0x13, 0x12, 0x12, 0x1f,
-+ 0x70, 0x11, 0x11, 0x12, 0x14, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x00, 0xf8, 0x08, 0x08, 0xf8,
-+ 0x40, 0x50, 0x48, 0x44, 0x44, 0xc0, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x54, 0x55, 0x56, 0x7c, 0x55,
-+ 0x56, 0x54, 0x7c, 0x44, 0x40, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0x50, 0x20, 0x50, 0x88,
-+ 0xfc, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x37, 0x32, 0x2a, 0x3c, 0x65, 0x0a, 0x1f,
-+ 0x64, 0x3f, 0x15, 0x0e, 0x07, 0x78, 0x00, 0x00,
-+ 0x04, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0x24, 0x24,
-+ 0xa4, 0xa4, 0x24, 0x04, 0x84, 0x0c, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x40, 0x21, 0x27, 0x00, 0x12,
-+ 0x12, 0x22, 0x22, 0x42, 0x44, 0x48, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0xe8, 0x08, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa4, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x21, 0x16, 0x14, 0x45, 0x24, 0x25, 0x0e, 0x10,
-+ 0x17, 0x24, 0x27, 0x44, 0x47, 0x44, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0x28, 0xa8, 0xc8, 0x58, 0x80,
-+ 0xf0, 0x90, 0xf0, 0x90, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x7f, 0x10, 0x10, 0x13, 0x7c, 0x11,
-+ 0x11, 0x11, 0x1e, 0x62, 0x04, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x60, 0x90, 0xf8, 0x08, 0x50,
-+ 0x50, 0x50, 0x50, 0x54, 0x54, 0x0c, 0x00, 0x00,
-+ 0x06, 0x39, 0x20, 0x24, 0x26, 0x39, 0x62, 0x1f,
-+ 0x11, 0x1f, 0x11, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x88, 0x08, 0x30, 0xf0,
-+ 0x10, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x7c, 0x13, 0x10, 0x10, 0x3f, 0x24, 0x65,
-+ 0x25, 0x25, 0x3d, 0x25, 0x22, 0x04, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x60, 0x90, 0xe8, 0x08, 0x50,
-+ 0x50, 0x50, 0x50, 0x54, 0x54, 0x0c, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2a, 0x2c, 0x09, 0x7e, 0x08, 0x1c,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x08, 0x88, 0x48,
-+ 0x48, 0x50, 0x50, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x29, 0x2a, 0x30, 0x2b, 0x25,
-+ 0x25, 0x26, 0x39, 0x20, 0x27, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x90, 0x60, 0xf0, 0x4c, 0x40,
-+ 0xf8, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x04, 0x7f, 0x00, 0x1f, 0x11,
-+ 0x1f, 0x11, 0x1f, 0x11, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x40, 0xfc, 0x00, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x14, 0x04, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x22, 0x14, 0x7f, 0x00, 0x3e,
-+ 0x22, 0x3e, 0x22, 0x3e, 0x22, 0x26, 0x00, 0x00,
-+ 0x80, 0xf8, 0x80, 0xf8, 0x08, 0xf8, 0x80, 0xf8,
-+ 0x80, 0xf8, 0x80, 0xf8, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x12, 0x12, 0x33, 0x50, 0x11,
-+ 0x17, 0x14, 0x14, 0x14, 0x17, 0x14, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x80, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x11, 0x1f, 0x10, 0x17, 0x14,
-+ 0x17, 0x14, 0x27, 0x2a, 0x4a, 0x11, 0x00, 0x00,
-+ 0x00, 0xf0, 0xfc, 0xe8, 0x10, 0xf0, 0xf0, 0x90,
-+ 0xf0, 0x90, 0xf8, 0x44, 0x34, 0xf0, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x09, 0x0e, 0x0a,
-+ 0x0a, 0x13, 0x12, 0x22, 0x42, 0x0c, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0xa0, 0x28, 0x48, 0x70,
-+ 0xe0, 0x50, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x17, 0x11, 0x17, 0x14, 0x17,
-+ 0x14, 0x17, 0x2f, 0x20, 0x43, 0x0c, 0x00, 0x00,
-+ 0x00, 0xf0, 0xfc, 0x28, 0xe0, 0xf0, 0x90, 0xf0,
-+ 0x90, 0xf0, 0xf8, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xf0, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x7f, 0x00, 0x0f, 0x08, 0x0f, 0x00, 0x3f,
-+ 0x20, 0x44, 0x04, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xe0, 0x20, 0xe0, 0x00, 0xfc,
-+ 0x08, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x14, 0x13, 0x33, 0x55, 0x11,
-+ 0x11, 0x11, 0x12, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa4, 0x18, 0xf8, 0x14, 0xf0,
-+ 0x10, 0xf0, 0x48, 0x44, 0x44, 0xc0, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x01, 0x3f, 0x21, 0x29, 0x29,
-+ 0x29, 0x29, 0x2f, 0x28, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x08, 0x28, 0x28,
-+ 0x28, 0x28, 0xe8, 0x28, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x23, 0x10, 0x17, 0x00, 0x11, 0x16,
-+ 0x20, 0x21, 0x46, 0x40, 0x01, 0x0e, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xfc, 0xa0, 0x24, 0x9c,
-+ 0xf0, 0x10, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x01, 0x3f, 0x21, 0x7f, 0x24, 0x1f, 0x68, 0x0f,
-+ 0x08, 0x0f, 0x05, 0x09, 0x31, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xfc, 0x48, 0xf0, 0x2c, 0xe0,
-+ 0x20, 0xe0, 0x60, 0x10, 0x08, 0x00, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2a, 0x2c, 0x09, 0x7e, 0x08, 0x1c,
-+ 0x1a, 0x2b, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x90, 0x50, 0x50, 0x10, 0x90, 0x90, 0x1c,
-+ 0x70, 0x90, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x0b, 0x40, 0x22, 0x0a, 0x0d, 0x12, 0x21,
-+ 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0x98, 0x14, 0x64, 0x00,
-+ 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x40, 0x23, 0x22, 0x02, 0x13,
-+ 0x10, 0x12, 0x22, 0x24, 0x48, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x00, 0xf8, 0x08, 0x08, 0xf8,
-+ 0x40, 0x50, 0x48, 0x44, 0x44, 0xc0, 0x00, 0x00,
-+ 0x0c, 0x4a, 0x32, 0x11, 0x31, 0x49, 0x09, 0x19,
-+ 0x29, 0x49, 0x0a, 0x0a, 0x0c, 0x38, 0x00, 0x00,
-+ 0x88, 0x48, 0x50, 0xf0, 0x50, 0x50, 0xf0, 0x50,
-+ 0x50, 0xf0, 0x54, 0x4c, 0x4c, 0x44, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x4f, 0x2a, 0x29, 0x0b, 0x1d,
-+ 0x29, 0x49, 0x11, 0x12, 0x24, 0x40, 0x00, 0x00,
-+ 0x80, 0xfc, 0x40, 0xfc, 0xa8, 0x10, 0xf8, 0x14,
-+ 0xf0, 0x10, 0xf0, 0x48, 0x44, 0xc0, 0x00, 0x00,
-+ 0x00, 0x78, 0x4f, 0x4a, 0x79, 0x4b, 0x4d, 0x79,
-+ 0x49, 0x49, 0x7a, 0x4a, 0x44, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa8, 0x10, 0xf8, 0x14, 0xf0,
-+ 0x10, 0xf0, 0x48, 0x44, 0x44, 0xc0, 0x00, 0x00,
-+ 0x04, 0x18, 0x73, 0x10, 0x17, 0x7c, 0x11, 0x1a,
-+ 0x34, 0x35, 0x52, 0x10, 0x11, 0x1e, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xfc, 0xa0, 0x24, 0x9c,
-+ 0xf0, 0x90, 0x60, 0x60, 0x90, 0x0c, 0x00, 0x00,
-+ 0x10, 0x55, 0x35, 0x39, 0x11, 0x7f, 0x11, 0x19,
-+ 0x35, 0x35, 0x53, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0xf0, 0x10, 0xf0, 0xfc, 0xf0, 0x50,
-+ 0xf0, 0xf0, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x0a, 0x09, 0x08, 0x08, 0x0e, 0x70, 0x00, 0x00,
-+ 0x00, 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0xf0,
-+ 0x10, 0x20, 0xc0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7e, 0x00, 0x3c, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x25, 0x3e, 0x20, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x00, 0xf8, 0x88, 0x88, 0xf8,
-+ 0x20, 0xb0, 0xa8, 0x24, 0x24, 0x60, 0x00, 0x00,
-+ 0x00, 0x20, 0x17, 0x12, 0x01, 0x03, 0x75, 0x11,
-+ 0x11, 0x11, 0x12, 0x14, 0x2c, 0x43, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa8, 0x10, 0xf8, 0x14, 0xf0,
-+ 0x10, 0xf0, 0x48, 0x44, 0xc0, 0xfc, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0f, 0x0f, 0x7f, 0x0f, 0x09,
-+ 0x0f, 0x0f, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0xe0, 0xfc, 0xe0, 0x20,
-+ 0xe0, 0xe0, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x28, 0x33, 0x28, 0x25, 0x26,
-+ 0x24, 0x25, 0x3a, 0x20, 0x21, 0x2e, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xfc, 0xa0, 0x24, 0x9c,
-+ 0xf0, 0x10, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x22, 0x5c, 0x00, 0x7e,
-+ 0x12, 0x12, 0x12, 0x1c, 0x10, 0x13, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x02, 0x7f, 0x02, 0x02, 0x02,
-+ 0x04, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x11, 0x14, 0x65, 0x18, 0x1b, 0x26, 0x7d,
-+ 0x19, 0x34, 0x35, 0x36, 0x50, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xfc, 0x40, 0x64,
-+ 0x68, 0xd0, 0x50, 0x48, 0x44, 0xc0, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x11, 0x13, 0x34, 0x5b, 0x12,
-+ 0x12, 0x13, 0x12, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xf8, 0xa8,
-+ 0xa8, 0xf8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x17, 0x14, 0x17, 0x14, 0x17,
-+ 0x10, 0x17, 0x10, 0x20, 0x3f, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x90, 0xf0, 0x90, 0xf0,
-+ 0x80, 0xf0, 0x80, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x0c, 0x1a, 0x1a,
-+ 0x29, 0x4a, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x60, 0xe0, 0xd0,
-+ 0x50, 0x48, 0x44, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x22, 0x12, 0x12, 0x4f, 0x22, 0x23, 0x06, 0x16,
-+ 0x1a, 0x1b, 0x22, 0x22, 0x42, 0x42, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x30, 0xf0, 0xe8,
-+ 0xa8, 0x24, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x12, 0x11, 0x17, 0x34, 0x39, 0x56, 0x11,
-+ 0x11, 0x1a, 0x16, 0x21, 0x22, 0x44, 0x00, 0x00,
-+ 0x40, 0x48, 0x50, 0xfc, 0xe0, 0x50, 0x4c, 0x48,
-+ 0xfc, 0xa8, 0xa8, 0x7c, 0x08, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x7d, 0x17, 0x11, 0x11, 0x7f, 0x13,
-+ 0x13, 0x15, 0x1d, 0x61, 0x01, 0x01, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0xfc, 0x10, 0x90, 0x78, 0x78,
-+ 0x54, 0x94, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x01, 0x7d, 0x51, 0x52, 0x7b, 0x4d, 0x49, 0x49,
-+ 0x78, 0x53, 0x52, 0x7e, 0x43, 0x02, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x00, 0xb8, 0xa8, 0xa8, 0xb8, 0xa8, 0x00, 0x00,
-+ 0x10, 0x10, 0x7e, 0x10, 0x7d, 0x57, 0x7c, 0x57,
-+ 0x7e, 0x12, 0x7f, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xf8, 0x04, 0xf8,
-+ 0xa8, 0xa8, 0xf8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x25, 0x2b, 0x30, 0x29, 0x26, 0x25,
-+ 0x25, 0x26, 0x3b, 0x24, 0x21, 0x26, 0x00, 0x00,
-+ 0x40, 0x48, 0x50, 0xfc, 0xe0, 0x50, 0x4c, 0x48,
-+ 0xfc, 0x68, 0xa8, 0xfc, 0x08, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x25, 0x7e, 0x2a, 0x3f, 0x2a,
-+ 0x3e, 0x05, 0x3b, 0x2e, 0x28, 0x41, 0x00, 0x00,
-+ 0x20, 0xa8, 0x70, 0xfc, 0x70, 0xa8, 0x24, 0xa8,
-+ 0xfc, 0x68, 0xe8, 0x7c, 0x88, 0x08, 0x00, 0x00,
-+ 0x04, 0x04, 0x3f, 0x2a, 0x3f, 0x2b, 0x2b, 0x3f,
-+ 0x2a, 0x2f, 0x2a, 0x2a, 0x2f, 0x59, 0x00, 0x00,
-+ 0x20, 0xa8, 0x70, 0xfc, 0x70, 0xa8, 0x64, 0x48,
-+ 0xfc, 0xa8, 0xa8, 0x7c, 0x88, 0x08, 0x00, 0x00,
-+ 0x00, 0x03, 0x7e, 0x12, 0x12, 0x13, 0x7c, 0x13,
-+ 0x12, 0x13, 0x1e, 0x62, 0x03, 0x02, 0x00, 0x00,
-+ 0x80, 0x7c, 0x14, 0x94, 0xd4, 0x24, 0x4c, 0xf8,
-+ 0x48, 0xf8, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x30, 0x09,
-+ 0x0d, 0x71, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x08, 0x30,
-+ 0x60, 0x18, 0xf4, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x43, 0x22, 0x23, 0x02, 0x12,
-+ 0x13, 0x24, 0x24, 0x48, 0x53, 0x4c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0x48, 0x40,
-+ 0xfc, 0x40, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x02, 0x1c,
-+ 0x03, 0x7f, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x40, 0xc0,
-+ 0x30, 0xc8, 0x40, 0x30, 0x08, 0x00, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2a, 0x2c, 0x7f, 0x1c, 0x1a, 0x2a,
-+ 0x48, 0x7f, 0x08, 0x14, 0x22, 0x43, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x04, 0x18, 0x6f, 0x00, 0x1f,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x40, 0x30, 0xec, 0x00, 0xf0,
-+ 0x10, 0x10, 0x10, 0xe0, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x08, 0x09, 0x1b, 0x2c, 0x4b,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xf8, 0x04, 0xf8,
-+ 0x48, 0x48, 0x48, 0x70, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x0f, 0x0a, 0x12, 0x13, 0x34, 0x54, 0x1a,
-+ 0x11, 0x11, 0x11, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x08, 0xe8, 0x28, 0x28, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0x28, 0x28, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x21, 0x11, 0x12, 0x05, 0x08, 0x17,
-+ 0x10, 0x20, 0x20, 0x40, 0x40, 0x00, 0x00, 0x00,
-+ 0x80, 0x80, 0x40, 0x20, 0x10, 0xe8, 0x04, 0xf8,
-+ 0x88, 0x88, 0x88, 0xf0, 0x80, 0x80, 0x00, 0x00,
-+ 0x01, 0x1e, 0x10, 0x10, 0x1f, 0x14, 0x14, 0x17,
-+ 0x15, 0x15, 0x15, 0x29, 0x29, 0x57, 0x00, 0x00,
-+ 0xa0, 0x20, 0x20, 0x20, 0xfc, 0x24, 0x24, 0x24,
-+ 0x24, 0x24, 0x44, 0x44, 0x84, 0x18, 0x00, 0x00,
-+ 0x11, 0x11, 0x1f, 0x18, 0x0d, 0x12, 0x1e, 0x20,
-+ 0x7e, 0x0a, 0x0a, 0x0c, 0x08, 0x0b, 0x00, 0x00,
-+ 0x10, 0x10, 0xf0, 0x10, 0xfc, 0x20, 0xf8, 0x88,
-+ 0xf8, 0xf8, 0x88, 0xf8, 0xc8, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x18, 0x35, 0x37, 0x34, 0x53,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xf8, 0x04, 0xf8,
-+ 0x48, 0x48, 0x48, 0x70, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x10, 0x11, 0x12, 0x7c, 0x13,
-+ 0x10, 0x14, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xe8, 0x04, 0xf8,
-+ 0x48, 0x48, 0x48, 0x70, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7e, 0x04, 0x08, 0x08, 0x1c,
-+ 0x2a, 0x4a, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x02, 0x04, 0x1f, 0x60,
-+ 0x1f, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x80, 0x40, 0xf0, 0x0c,
-+ 0xf0, 0x10, 0x10, 0x60, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x23, 0x5d, 0x08, 0x7f,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xe8, 0x04, 0xf8,
-+ 0x48, 0x48, 0x48, 0x70, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x7e, 0x08, 0x3f, 0x00, 0x3e, 0x01,
-+ 0x7e, 0x08, 0x2c, 0x2b, 0x4a, 0x18, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x28, 0xfc, 0x28, 0xf8, 0x20,
-+ 0xa4, 0xb8, 0x70, 0xa8, 0x24, 0x60, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x3f, 0x21, 0x5d, 0x1d, 0x02,
-+ 0x0f, 0x70, 0x1f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0x08, 0x70, 0x70, 0x80,
-+ 0xe0, 0x1c, 0xf0, 0x10, 0x60, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x3f, 0x21, 0x5d, 0x1d, 0x0f,
-+ 0x00, 0x3f, 0x12, 0x0a, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0x08, 0x70, 0x70, 0xe0,
-+ 0x00, 0xf8, 0x90, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x3e, 0x22, 0x2b, 0x1f, 0x12, 0x1f,
-+ 0x12, 0x1f, 0x17, 0x24, 0x47, 0x18, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf8, 0x88, 0xa8, 0xfc, 0x40, 0xf8,
-+ 0x48, 0xf8, 0x58, 0x60, 0x44, 0x3c, 0x00, 0x00,
-+ 0x04, 0x14, 0x17, 0x14, 0x7f, 0x24, 0x35, 0x2e,
-+ 0x3f, 0x2e, 0x35, 0x24, 0x3f, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0xa8, 0x28, 0xc4, 0xfc, 0x80, 0xfc,
-+ 0x94, 0x94, 0x98, 0x90, 0x90, 0x90, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x3f, 0x27, 0x2a, 0x32, 0x22,
-+ 0x27, 0x24, 0x27, 0x44, 0x47, 0x04, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xfc, 0x30, 0xe8, 0xa4, 0x20,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x22, 0x3f, 0x27, 0x2a, 0x32,
-+ 0x20, 0x24, 0x24, 0x44, 0x5f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0xfc, 0x70, 0xa8, 0xa4,
-+ 0x80, 0xf0, 0x80, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x08, 0x08, 0x0e, 0x12, 0x12, 0x2a,
-+ 0x46, 0x04, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x09, 0x09, 0x11, 0x23, 0x01, 0x06, 0x78,
-+ 0x0f, 0x01, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x20, 0x10, 0x28, 0x44, 0x84, 0x80, 0x80,
-+ 0xf8, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x7f, 0x08, 0x0f, 0x11, 0x29, 0x06, 0x04,
-+ 0x18, 0x60, 0x14, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x08, 0x88, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x08, 0x18, 0x90, 0x48, 0x44, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x08, 0x0f, 0x19, 0x26, 0x0d, 0x31,
-+ 0x7f, 0x03, 0x0c, 0x74, 0x07, 0x38, 0x00, 0x00,
-+ 0x08, 0xc8, 0x48, 0x48, 0x48, 0x48, 0x48, 0x18,
-+ 0xfc, 0x10, 0xa0, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x1f, 0x11, 0x17, 0x11, 0x1f,
-+ 0x11, 0x17, 0x23, 0x2d, 0x71, 0x01, 0x00, 0x00,
-+ 0x80, 0xfc, 0x20, 0xfc, 0x40, 0xf0, 0x50, 0xfc,
-+ 0x50, 0xf0, 0x60, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x02, 0x12, 0x12, 0x22, 0x44,
-+ 0x01, 0x14, 0x14, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x40, 0x50, 0x48, 0x44, 0xc4,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x12, 0x11, 0x1b, 0x34, 0x35, 0x36, 0x52,
-+ 0x13, 0x12, 0x15, 0x11, 0x12, 0x1c, 0x00, 0x00,
-+ 0x40, 0x48, 0x50, 0xfc, 0xe0, 0x50, 0x4c, 0x48,
-+ 0xfc, 0xa8, 0xa8, 0x7c, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x15, 0x12, 0x42, 0x20, 0x20, 0x0e, 0x12,
-+ 0x12, 0x23, 0x22, 0x42, 0x45, 0x48, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8,
-+ 0x20, 0xfc, 0x20, 0x20, 0xa0, 0x7c, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x10, 0x17, 0x36, 0x3b, 0x52,
-+ 0x13, 0x10, 0x19, 0x26, 0x24, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x5f, 0x12, 0x1f, 0x17, 0x11,
-+ 0x1f, 0x11, 0x2f, 0x27, 0x59, 0x01, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0xfc, 0x20, 0xfc, 0xf0, 0x50,
-+ 0xfc, 0x50, 0xf0, 0x70, 0x4c, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x64, 0x1b, 0x1a, 0x27, 0x7e,
-+ 0x1b, 0x34, 0x35, 0x32, 0x54, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x01, 0x7d, 0x2e, 0x2a, 0x39, 0x2a, 0x2f, 0x38,
-+ 0x2a, 0x2e, 0x3b, 0x6a, 0x09, 0x0a, 0x00, 0x00,
-+ 0x10, 0x10, 0xe8, 0xa8, 0x10, 0xa8, 0xfc, 0xa4,
-+ 0xa8, 0xa8, 0xb8, 0xa8, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x20, 0x17, 0x13, 0x02, 0x73,
-+ 0x12, 0x13, 0x17, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x40, 0xfc, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xf8, 0xfc, 0x40, 0x40, 0xfc, 0x00, 0x00,
-+ 0x00, 0x20, 0x17, 0x10, 0x03, 0x02, 0x73, 0x12,
-+ 0x13, 0x10, 0x17, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x19, 0x0e, 0x70, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0xa8, 0xf8, 0xa8,
-+ 0xf8, 0x70, 0xa8, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x08, 0x08, 0x0f, 0x09, 0x02,
-+ 0x1f, 0x10, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0x20, 0xe0, 0x20, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x02, 0x07, 0x19, 0x7f, 0x11, 0x1f, 0x11, 0x1f,
-+ 0x12, 0x6f, 0x08, 0x0f, 0x08, 0x0f, 0x00, 0x00,
-+ 0x00, 0xc0, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x48, 0xe4, 0x20, 0xe0, 0x20, 0xe0, 0x00, 0x00,
-+ 0x10, 0x11, 0x16, 0x7f, 0x12, 0x1b, 0x36, 0x37,
-+ 0x32, 0x53, 0x55, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x80, 0xf0, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0xa8, 0xf4, 0x14, 0xf0, 0x10, 0xf0, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x0a, 0x2a, 0x2c, 0x28, 0x48,
-+ 0x08, 0x08, 0x15, 0x13, 0x22, 0x44, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8,
-+ 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x23, 0x3e, 0x22,
-+ 0x23, 0x3e, 0x14, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0xd0, 0x50, 0x20, 0x50,
-+ 0xfc, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x09, 0x08, 0x2e,
-+ 0x29, 0x28, 0x28, 0x2e, 0x38, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0xd0, 0x20, 0x50, 0x88,
-+ 0xfc, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x3f, 0x3d, 0x5d, 0x01, 0x3e,
-+ 0x23, 0x3e, 0x0f, 0x28, 0x2e, 0x70, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0x78, 0x70, 0x00, 0x78,
-+ 0xd0, 0x70, 0xfc, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x12, 0x09, 0x09, 0x3f, 0x20, 0x41, 0x01, 0x3f,
-+ 0x01, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xfc, 0x08, 0x00, 0x00, 0xf0,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x01, 0x0f, 0x09, 0x7f, 0x09, 0x0f, 0x0f, 0x09,
-+ 0x0f, 0x7f, 0x04, 0x0f, 0x01, 0x3e, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xfc, 0x20, 0xe0, 0xe0, 0x20,
-+ 0xe0, 0xfc, 0x40, 0x40, 0xc0, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x12, 0x12, 0x17, 0x14, 0x17,
-+ 0x14, 0x17, 0x25, 0x25, 0x46, 0x18, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x38, 0xa8, 0xa8, 0xb0,
-+ 0xa8, 0xa4, 0x24, 0xb8, 0xa0, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x0f, 0x01, 0x01, 0x3f, 0x04,
-+ 0x04, 0x7f, 0x04, 0x04, 0x08, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xe0, 0x00, 0x00, 0xf8, 0x40,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x3e,
-+ 0x28, 0x24, 0x27, 0x39, 0x62, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88,
-+ 0xf8, 0x88, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x0a, 0x09, 0x7f, 0x08, 0x0d, 0x1a, 0x1a,
-+ 0x2b, 0x48, 0x09, 0x08, 0x08, 0x0f, 0x00, 0x00,
-+ 0x40, 0x48, 0x50, 0xfc, 0xe0, 0x50, 0x48, 0x40,
-+ 0xfc, 0x90, 0xd0, 0x20, 0xd0, 0x08, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x7c, 0x14, 0x17, 0x3c, 0x3f,
-+ 0x36, 0x55, 0x54, 0x15, 0x16, 0x18, 0x00, 0x00,
-+ 0x00, 0x3c, 0xa4, 0xa8, 0xa8, 0xb0, 0xa8, 0xa4,
-+ 0x24, 0x24, 0xa4, 0x78, 0x60, 0x20, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x22, 0x23, 0x02, 0x13,
-+ 0x12, 0x22, 0x22, 0x42, 0x43, 0x4c, 0x00, 0x00,
-+ 0x80, 0x80, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x88, 0x48, 0x50, 0x20, 0x90, 0x0c, 0x00, 0x00,
-+ 0x20, 0x17, 0x14, 0x47, 0x24, 0x27, 0x04, 0x17,
-+ 0x17, 0x16, 0x2a, 0x2b, 0x52, 0x42, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x00, 0xfc, 0x40, 0xf8,
-+ 0x68, 0xd8, 0x48, 0x68, 0xd8, 0x58, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x49, 0x09, 0x0f, 0x11,
-+ 0x21, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x00, 0x00, 0xf0, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x44, 0x29, 0x11, 0x31, 0x49, 0x09, 0x19,
-+ 0x29, 0x49, 0x09, 0x09, 0x09, 0x36, 0x00, 0x00,
-+ 0x40, 0x40, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x48, 0x28, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x1f, 0x29, 0x45, 0x3f, 0x04, 0x7f, 0x1f,
-+ 0x11, 0x1f, 0x11, 0x1f, 0x11, 0x00, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0xf8, 0x40, 0xfc, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf4, 0x04, 0xfc, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x01, 0x01, 0x7f, 0x03, 0x02,
-+ 0x06, 0x1b, 0x62, 0x02, 0x02, 0x01, 0x00, 0x00,
-+ 0x00, 0x10, 0xf0, 0x20, 0x40, 0xfc, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0x08, 0x08, 0xf8, 0x00, 0x00,
-+ 0x04, 0x3f, 0x0a, 0x7f, 0x1e, 0x12, 0x1e, 0x1e,
-+ 0x16, 0x7f, 0x07, 0x07, 0x7f, 0x00, 0x00, 0x00,
-+ 0x80, 0xf8, 0xf0, 0x10, 0xf0, 0xf0, 0xf0, 0xf4,
-+ 0x7c, 0xfc, 0xc0, 0xf8, 0xc0, 0x40, 0x00, 0x00,
-+ 0x10, 0x12, 0x11, 0x7d, 0x55, 0x55, 0x55, 0x7d,
-+ 0x51, 0x19, 0x15, 0x1d, 0x62, 0x04, 0x00, 0x00,
-+ 0x88, 0x48, 0x50, 0xf0, 0x50, 0x50, 0xf0, 0x50,
-+ 0x50, 0xf0, 0x54, 0x4c, 0x4c, 0x44, 0x00, 0x00,
-+ 0x08, 0x08, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x3e,
-+ 0x24, 0x22, 0x27, 0x39, 0x60, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x50, 0x50, 0x60, 0x50, 0x48,
-+ 0x44, 0x44, 0x64, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x04, 0x04,
-+ 0x08, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x40, 0x20,
-+ 0x10, 0x10, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x0e, 0x15, 0x25, 0x5f, 0x12, 0x1f,
-+ 0x12, 0x1f, 0x17, 0x24, 0x47, 0x18, 0x00, 0x00,
-+ 0x20, 0xfc, 0x70, 0xa8, 0x24, 0xfc, 0x40, 0xf8,
-+ 0x48, 0xf8, 0x58, 0x60, 0x44, 0x3c, 0x00, 0x00,
-+ 0x10, 0x11, 0x10, 0x7d, 0x08, 0x0b, 0x18, 0x16,
-+ 0x35, 0x50, 0x11, 0x16, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xfc, 0x40, 0x64,
-+ 0x68, 0xd0, 0x50, 0x48, 0x44, 0xc0, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x24, 0x27, 0x3c, 0x24, 0x24,
-+ 0x3c, 0x24, 0x24, 0x24, 0x25, 0x4e, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5d, 0x08, 0x7f,
-+ 0x08, 0x2a, 0x1c, 0x19, 0x0e, 0x70, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xfc, 0x20, 0x24,
-+ 0xb8, 0x70, 0x68, 0xa4, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x38, 0x00, 0x7c, 0x01, 0x3b, 0x04, 0x3b,
-+ 0x02, 0x3a, 0x2b, 0x2a, 0x3a, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xf8, 0x04, 0xf8,
-+ 0xa8, 0xa8, 0xf8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x17, 0x10, 0x31, 0x52, 0x10,
-+ 0x17, 0x10, 0x11, 0x10, 0x10, 0x17, 0x00, 0x00,
-+ 0x18, 0xe0, 0x40, 0xfc, 0xe0, 0x50, 0x48, 0x40,
-+ 0xfc, 0x90, 0xd0, 0x20, 0xd0, 0x08, 0x00, 0x00,
-+ 0x02, 0x04, 0x38, 0x08, 0x08, 0x7f, 0x08, 0x1c,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7e, 0x00, 0x3f, 0x00, 0x3c,
-+ 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x25, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x03, 0x0d, 0x71, 0x01, 0x3f,
-+ 0x01, 0x09, 0x09, 0x09, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xc0, 0x30, 0x08, 0x00, 0xf8,
-+ 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x24, 0x3c, 0x24, 0x3c, 0x25,
-+ 0x26, 0x3c, 0x18, 0x14, 0x24, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x24, 0x3c, 0x24, 0x25, 0x3d,
-+ 0x27, 0x25, 0x25, 0x25, 0x26, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x48, 0x48, 0x88, 0x30, 0x10,
-+ 0xfc, 0x54, 0x54, 0x54, 0x64, 0xcc, 0x00, 0x00,
-+ 0x00, 0x00, 0x7f, 0x00, 0x1e, 0x12, 0x1e, 0x07,
-+ 0x79, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x90, 0x88, 0xfc, 0x90, 0x90, 0x60, 0x64, 0x9c,
-+ 0x04, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7e, 0x08, 0x0c, 0x1b, 0x1a,
-+ 0x28, 0x4b, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xf0, 0x50, 0x50, 0x94, 0x54, 0x4c,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x7f, 0x3f, 0x22, 0x3e, 0x2b, 0x5f, 0x08,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x29, 0x44, 0x00, 0x00,
-+ 0x30, 0x28, 0xfc, 0x60, 0xa4, 0x1c, 0xe0, 0x20,
-+ 0xe0, 0xe0, 0xfc, 0xfc, 0x24, 0x98, 0x00, 0x00,
-+ 0x00, 0x3f, 0x02, 0x02, 0x07, 0x05, 0x04, 0x04,
-+ 0x0a, 0x09, 0x09, 0x00, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0xe0, 0x20, 0xa0, 0xa0,
-+ 0x20, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x00, 0x0f, 0x08, 0x08, 0x0f,
-+ 0x08, 0x08, 0x0f, 0x08, 0x00, 0x7f, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0xe0, 0x20, 0x20, 0xe0,
-+ 0x20, 0x20, 0xe0, 0x20, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x09, 0x1f, 0x25, 0x7e, 0x2a, 0x3e, 0x2b,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x00, 0xdc, 0x54, 0xdc, 0x00, 0xf8, 0x00, 0xfc,
-+ 0x40, 0x78, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7f, 0x02, 0x3d, 0x00, 0x3c,
-+ 0x03, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0x18, 0xe0, 0x40, 0x7c,
-+ 0xc0, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x7f, 0x07, 0x07, 0x3f, 0x27,
-+ 0x24, 0x27, 0x7f, 0x05, 0x19, 0x61, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xfc, 0xc0, 0xc0, 0xf8, 0xc8,
-+ 0x48, 0xd8, 0xfc, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x1f, 0x14, 0x13, 0x1f, 0x1a,
-+ 0x1a, 0x1f, 0x1a, 0x12, 0x24, 0x48, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xfc, 0xa0, 0x20, 0xfc, 0xb4,
-+ 0xd8, 0x90, 0xb0, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x15, 0x19, 0x35, 0x37,
-+ 0x32, 0x54, 0x50, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0x00, 0xf8, 0x68, 0x68,
-+ 0xe8, 0xb8, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x42, 0x24, 0x29, 0x03, 0x10,
-+ 0x13, 0x12, 0x27, 0x24, 0x40, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa8, 0xa4, 0x64, 0xf0, 0x10,
-+ 0xf0, 0x00, 0xf8, 0x08, 0x08, 0x70, 0x00, 0x00,
-+ 0x00, 0x7c, 0x13, 0x12, 0x11, 0x21, 0x3d, 0x65,
-+ 0x26, 0x26, 0x3c, 0x25, 0x22, 0x04, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0x00, 0xf8, 0x68, 0x68,
-+ 0xe8, 0xb8, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x26, 0x25, 0x3d, 0x25, 0x27,
-+ 0x3e, 0x24, 0x24, 0x25, 0x26, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0x00, 0xf8, 0x68, 0x68,
-+ 0xe8, 0xb8, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0x40, 0xfc, 0x40, 0x40, 0x20,
-+ 0x20, 0xa0, 0x10, 0x14, 0x0c, 0x04, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x01, 0x21, 0x21, 0x21, 0x3f,
-+ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x00, 0x00, 0xf8,
-+ 0x08, 0x08, 0x08, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x01, 0x03, 0x05, 0x09, 0x31,
-+ 0x41, 0x01, 0x01, 0x00, 0x3f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x80, 0x00, 0x80, 0x60, 0x10, 0x08,
-+ 0x04, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x02, 0x04, 0x08, 0x11, 0x21,
-+ 0x41, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x80, 0x40, 0x20, 0x10, 0x08,
-+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
-+ 0x7c, 0x44, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x80, 0x80, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0xf8, 0x88, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x3f, 0x04, 0x05, 0x04, 0x04,
-+ 0x7f, 0x04, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0xa0, 0xa0,
-+ 0xfc, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x01, 0x06, 0x18, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x08, 0x08, 0x08, 0x04, 0x04,
-+ 0x02, 0x01, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x40, 0x40, 0x40, 0x80,
-+ 0x80, 0x00, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x01, 0x7f, 0x01, 0x09, 0x79,
-+ 0x09, 0x09, 0x19, 0x69, 0x01, 0x01, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0x00, 0xfc, 0x00, 0x20, 0x2c,
-+ 0x30, 0x20, 0x24, 0x1c, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x7f, 0x05, 0x3d, 0x05, 0x1d,
-+ 0x65, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x60, 0x80, 0x00, 0xfc, 0x48, 0x70, 0x40, 0x48,
-+ 0x38, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x07, 0x7a, 0x29, 0x3f, 0x56, 0x08, 0x7f, 0x55,
-+ 0x7d, 0x5d, 0x55, 0x49, 0x55, 0x63, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x7e, 0x24, 0x19, 0x08, 0x7e, 0x12, 0x14,
-+ 0x1b, 0x10, 0x13, 0x10, 0x13, 0x30, 0x00, 0x00,
-+ 0x40, 0x78, 0x90, 0xf8, 0xa8, 0xa8, 0xfc, 0x64,
-+ 0xf8, 0xb0, 0x70, 0xa8, 0x24, 0xc0, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x11, 0x09, 0x09, 0x1f, 0x01,
-+ 0x7f, 0x01, 0x1f, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x10, 0x10, 0x20, 0xf0, 0x10,
-+ 0xfc, 0x10, 0xf0, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x22, 0x7f, 0x08, 0x7e,
-+ 0x08, 0x3e, 0x22, 0x22, 0x3e, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x90, 0x60, 0x20, 0xfc, 0x24, 0x28,
-+ 0x30, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x3f,
-+ 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0xfc, 0x40, 0x40, 0x40, 0x20,
-+ 0x20, 0x20, 0x10, 0x94, 0x0c, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x06, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x04, 0x04, 0x04, 0x3c, 0x20, 0x20,
-+ 0x3c, 0x24, 0x04, 0x04, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x40, 0x78, 0x08, 0x08,
-+ 0x78, 0x48, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x02, 0x07, 0x3c, 0x24, 0x24,
-+ 0x24, 0x3c, 0x20, 0x03, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0xc8, 0xa8, 0xb0,
-+ 0x90, 0xa8, 0xc4, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x7f,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x00, 0x00, 0x07, 0x04, 0x04,
-+ 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0x00, 0xc0, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x00, 0x1f, 0x10, 0x1f, 0x10,
-+ 0x1f, 0x09, 0x09, 0x11, 0x21, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00, 0x00,
-+ 0x01, 0x7f, 0x00, 0x0f, 0x08, 0x0f, 0x00, 0x3f,
-+ 0x20, 0x4f, 0x01, 0x3f, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xe0, 0x20, 0xe0, 0x00, 0xfc,
-+ 0xc8, 0x00, 0xf8, 0x00, 0x04, 0xfc, 0x00, 0x00,
-+ 0x01, 0x7f, 0x1f, 0x17, 0x14, 0x17, 0x1f, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf0, 0xd0, 0x50, 0xd0, 0xf0, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x0c, 0x12, 0x12, 0x11, 0x21, 0x42, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x60,
-+ 0x50, 0x50, 0x90, 0x88, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x0f, 0x09, 0x11, 0x11, 0x31, 0x51, 0x11,
-+ 0x11, 0x11, 0x12, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0x20, 0x20, 0x38, 0x28,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11,
-+ 0x11, 0x12, 0x22, 0x24, 0x48, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40,
-+ 0x40, 0x20, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x08, 0x08, 0x18, 0x28, 0x48,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x60, 0x50, 0x48, 0x44,
-+ 0x44, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x10, 0x1f, 0x30, 0x50, 0x10,
-+ 0x10, 0x11, 0x11, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0x80, 0xf8, 0x88, 0x88, 0x88,
-+ 0x88, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x17, 0x10, 0x32, 0x52, 0x11,
-+ 0x11, 0x10, 0x10, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40,
-+ 0xc0, 0x80, 0xc0, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x10, 0x10, 0x30, 0x52, 0x12,
-+ 0x14, 0x10, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x10, 0x10, 0x34, 0x52, 0x11,
-+ 0x10, 0x11, 0x11, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x68, 0x1c, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x10, 0x10, 0x30, 0x5f, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x40, 0x40, 0x40, 0xfc, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x11, 0x11, 0x32, 0x55, 0x19,
-+ 0x11, 0x11, 0x12, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x80, 0x80, 0xc0, 0x40, 0x20, 0x10, 0x28, 0x24,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x10, 0x10, 0x31, 0x51, 0x11,
-+ 0x11, 0x11, 0x12, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x00, 0x00, 0xe0, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x0a, 0x0a, 0x12, 0x13, 0x34, 0x58, 0x1f,
-+ 0x10, 0x10, 0x11, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc,
-+ 0xc0, 0xa0, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x17, 0x10, 0x30, 0x50, 0x13,
-+ 0x12, 0x12, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x10, 0x10, 0x37, 0x54, 0x14,
-+ 0x17, 0x14, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xf8, 0xa8, 0xa8, 0xf8, 0xa0, 0xa0,
-+ 0xfc, 0xa4, 0x24, 0x24, 0x38, 0x20, 0x00, 0x00,
-+ 0x09, 0x09, 0x09, 0x13, 0x12, 0x34, 0x53, 0x12,
-+ 0x12, 0x12, 0x13, 0x12, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0xc8, 0x48,
-+ 0x48, 0x48, 0xc8, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x12, 0x12, 0x34, 0x50, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x04, 0x88, 0x80, 0x88, 0x90,
-+ 0xe0, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x12, 0x12, 0x34, 0x57, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x04, 0x08, 0x00, 0xfc, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x1f, 0x10, 0x30, 0x53, 0x10,
-+ 0x13, 0x12, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x12, 0x14, 0x30, 0x51, 0x16,
-+ 0x10, 0x13, 0x10, 0x10, 0x10, 0x17, 0x00, 0x00,
-+ 0x80, 0xf8, 0x08, 0x90, 0x60, 0x40, 0xa0, 0x7c,
-+ 0x84, 0x48, 0x30, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x13, 0x12, 0x34, 0x5f, 0x10,
-+ 0x10, 0x11, 0x11, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0xe0,
-+ 0xe0, 0x50, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x12, 0x12, 0x34, 0x53, 0x10,
-+ 0x10, 0x17, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x04, 0x18, 0x60, 0xc0, 0x40,
-+ 0x7c, 0xc0, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x14, 0x12, 0x32, 0x50, 0x11,
-+ 0x12, 0x1c, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xa8, 0xa8, 0xb0, 0xa0, 0xb0, 0xa8,
-+ 0xa4, 0xa4, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x0f, 0x0c, 0x14, 0x17, 0x34, 0x57, 0x16,
-+ 0x16, 0x16, 0x16, 0x1a, 0x18, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x90, 0xf0, 0xb0,
-+ 0xb0, 0xb0, 0xf4, 0x8c, 0x8c, 0x84, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x10, 0x13, 0x32, 0x52, 0x12,
-+ 0x13, 0x12, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x80, 0xf8, 0x08, 0x08, 0x08,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x10, 0x11, 0x31, 0x53, 0x15,
-+ 0x19, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x80, 0x00, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x0a, 0x09, 0x09, 0x17, 0x10, 0x30, 0x53, 0x10,
-+ 0x10, 0x17, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xfc, 0x40, 0x40, 0xf8, 0x40,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x09, 0x09, 0x0d, 0x13, 0x23,
-+ 0x03, 0x05, 0x19, 0x61, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x20, 0x20, 0x30, 0x48, 0x88,
-+ 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x04, 0x1f, 0x60, 0x1f, 0x12,
-+ 0x12, 0x1f, 0x12, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0x00, 0x80, 0x40, 0xf0, 0x0c, 0xf0, 0x90,
-+ 0x90, 0xf0, 0x90, 0x90, 0x90, 0xb0, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x2f, 0x27, 0x60, 0x3f, 0x2a,
-+ 0x31, 0x27, 0x25, 0x25, 0x3f, 0x20, 0x00, 0x00,
-+ 0x80, 0xf0, 0x90, 0xfc, 0xf0, 0x80, 0xfc, 0x48,
-+ 0x24, 0xf0, 0x50, 0x50, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x13, 0x12, 0x33, 0x52, 0x13,
-+ 0x12, 0x10, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0xf8,
-+ 0xa8, 0xa0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x11, 0x17, 0x31, 0x51, 0x12,
-+ 0x14, 0x1f, 0x10, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0x80, 0xa0, 0x90, 0x38, 0xc8, 0x00, 0xf8, 0x40,
-+ 0x40, 0xfc, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x19, 0x25, 0x25, 0x51, 0x11,
-+ 0x19, 0x15, 0x25, 0x21, 0x4f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x10, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x12, 0x12, 0x34, 0x53, 0x10,
-+ 0x10, 0x17, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x30, 0xd0, 0x48, 0x44, 0x04, 0xf8, 0x30,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x12, 0x17, 0x32, 0x52, 0x13,
-+ 0x12, 0x10, 0x10, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x80, 0xf0, 0x20, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x68, 0xa0, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x10, 0x13, 0x32, 0x52, 0x13,
-+ 0x12, 0x12, 0x13, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x90, 0x60, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x12, 0x13, 0x32, 0x52, 0x13,
-+ 0x10, 0x13, 0x10, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x0f, 0x11, 0x11, 0x3f, 0x51, 0x13,
-+ 0x13, 0x15, 0x15, 0x19, 0x11, 0x11, 0x00, 0x00,
-+ 0x48, 0xa8, 0x28, 0x28, 0x28, 0xe8, 0x28, 0x28,
-+ 0xa8, 0x68, 0x68, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x09, 0x08, 0x08, 0x13, 0x10, 0x33, 0x52, 0x13,
-+ 0x12, 0x10, 0x11, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xf8, 0x48, 0xf8, 0x40, 0xfc,
-+ 0xc4, 0xc4, 0x44, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x10, 0x13, 0x32, 0x53, 0x12,
-+ 0x13, 0x10, 0x17, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x10, 0x11, 0x32, 0x5f, 0x10,
-+ 0x13, 0x12, 0x12, 0x13, 0x12, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0x10, 0xfc, 0x08,
-+ 0xc8, 0x48, 0x48, 0xc8, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x12, 0x13, 0x32, 0x52, 0x13,
-+ 0x12, 0x15, 0x15, 0x19, 0x11, 0x11, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x48, 0x40, 0xfc,
-+ 0x40, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x13, 0x12, 0x32, 0x52, 0x12,
-+ 0x12, 0x13, 0x15, 0x15, 0x19, 0x11, 0x00, 0x00,
-+ 0x00, 0xfc, 0x04, 0xfc, 0x20, 0xa8, 0xa8, 0xa8,
-+ 0xf8, 0x24, 0x24, 0x24, 0xfc, 0x04, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x12, 0x13, 0x32, 0x52, 0x13,
-+ 0x12, 0x10, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x80, 0x38, 0x08, 0x08, 0xb8, 0x08, 0x08, 0xf8,
-+ 0xa8, 0xa0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x12, 0x12, 0x34, 0x51, 0x12,
-+ 0x13, 0x10, 0x10, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa4, 0xa8, 0xa4, 0x1c, 0x00,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x11, 0x11, 0x31, 0x52, 0x14,
-+ 0x10, 0x17, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0x10, 0x30, 0xc8, 0x48,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x10, 0x11, 0x31, 0x52, 0x14,
-+ 0x10, 0x17, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x80, 0x80, 0xe0, 0xa0, 0x24, 0x24, 0x1c, 0x40,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x0a, 0x0a, 0x0a, 0x13, 0x12, 0x32, 0x5f, 0x12,
-+ 0x13, 0x16, 0x16, 0x1a, 0x12, 0x16, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x88, 0x48, 0x48, 0xc8, 0x28,
-+ 0x30, 0x90, 0xb0, 0x28, 0x48, 0x84, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x13, 0x12, 0x33, 0x52, 0x10,
-+ 0x17, 0x14, 0x17, 0x14, 0x17, 0x14, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x13, 0x10, 0x37, 0x50, 0x13,
-+ 0x12, 0x12, 0x13, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x10, 0x13, 0x32, 0x53, 0x12,
-+ 0x13, 0x10, 0x17, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0x40, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x12, 0x13, 0x32, 0x53, 0x10,
-+ 0x10, 0x11, 0x17, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x40,
-+ 0xa0, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x14, 0x14, 0x34, 0x55, 0x15,
-+ 0x17, 0x15, 0x15, 0x19, 0x19, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x88, 0x88, 0x88, 0xfc, 0x48,
-+ 0x28, 0x28, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x0f, 0x0c, 0x17, 0x14, 0x37, 0x54, 0x14,
-+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x00,
-+ 0x00, 0xbc, 0xa4, 0xbc, 0xa4, 0xbc, 0x04, 0x04,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x0c, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x10, 0x17, 0x34, 0x57, 0x15,
-+ 0x15, 0x16, 0x14, 0x14, 0x14, 0x14, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0xfc, 0x44, 0x74, 0x54,
-+ 0x54, 0xec, 0xcc, 0x44, 0x44, 0x4c, 0x00, 0x00,
-+ 0x08, 0x0f, 0x0d, 0x15, 0x15, 0x35, 0x55, 0x14,
-+ 0x17, 0x15, 0x14, 0x15, 0x17, 0x14, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x40,
-+ 0xfc, 0x90, 0x60, 0xd8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x0f, 0x0c, 0x14, 0x17, 0x34, 0x54, 0x17,
-+ 0x14, 0x14, 0x17, 0x14, 0x14, 0x14, 0x00, 0x00,
-+ 0x00, 0xb8, 0x88, 0x88, 0xb8, 0x88, 0x00, 0x78,
-+ 0x48, 0x28, 0x30, 0x10, 0x28, 0xc4, 0x00, 0x00,
-+ 0x01, 0x02, 0x04, 0x1f, 0x60, 0x1f, 0x19, 0x15,
-+ 0x1f, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0xf0, 0x0c, 0xf0, 0x30, 0x50,
-+ 0xf0, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x00, 0x00,
-+ 0x0a, 0x0a, 0x0b, 0x12, 0x12, 0x33, 0x5e, 0x10,
-+ 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x20, 0x24, 0xe8, 0x30, 0x20, 0xa4, 0x5c, 0x80,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x10, 0x11, 0x33, 0x52, 0x12,
-+ 0x13, 0x12, 0x12, 0x14, 0x14, 0x19, 0x00, 0x00,
-+ 0x40, 0xfc, 0x90, 0x60, 0x90, 0xfc, 0x10, 0x60,
-+ 0x88, 0x30, 0xc4, 0x08, 0x30, 0xc0, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x13, 0x12, 0x33, 0x52, 0x13,
-+ 0x14, 0x1c, 0x15, 0x16, 0x17, 0x14, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x88, 0xc8, 0x28, 0x08, 0xe8, 0x30, 0x00, 0x00,
-+ 0x08, 0x0a, 0x0a, 0x12, 0x1f, 0x32, 0x52, 0x17,
-+ 0x14, 0x14, 0x14, 0x17, 0x14, 0x10, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x48, 0xc8, 0xa8,
-+ 0xb0, 0x90, 0xb0, 0xa8, 0x48, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x10, 0x10, 0x37, 0x50, 0x10,
-+ 0x13, 0x1d, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x48, 0x50, 0xfc, 0x60, 0x90,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x09, 0x09, 0x0b, 0x12, 0x15, 0x39, 0x52, 0x14,
-+ 0x10, 0x11, 0x15, 0x15, 0x19, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0xa8, 0xa8, 0x68, 0x68, 0xb0,
-+ 0x80, 0x50, 0x48, 0x04, 0x14, 0xf0, 0x00, 0x00,
-+ 0x09, 0x08, 0x08, 0x11, 0x17, 0x38, 0x57, 0x14,
-+ 0x16, 0x15, 0x16, 0x15, 0x14, 0x15, 0x00, 0x00,
-+ 0xc0, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xa8, 0xa8,
-+ 0xa8, 0xd0, 0xd0, 0xa8, 0xa8, 0xa8, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x12, 0x13, 0x32, 0x53, 0x12,
-+ 0x10, 0x10, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0xc8,
-+ 0xd0, 0xd0, 0x68, 0x7c, 0x44, 0x3c, 0x00, 0x00,
-+ 0x09, 0x09, 0x09, 0x1f, 0x15, 0x34, 0x54, 0x1b,
-+ 0x11, 0x11, 0x12, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x48, 0xc8, 0xa8, 0x28,
-+ 0x30, 0x10, 0x90, 0xa8, 0x48, 0x84, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x13, 0x12, 0x33, 0x52, 0x13,
-+ 0x12, 0x10, 0x1f, 0x11, 0x10, 0x10, 0x00, 0x00,
-+ 0x50, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x58, 0x10, 0xfc, 0x10, 0x90, 0x30, 0x00, 0x00,
-+ 0x08, 0x0f, 0x0c, 0x14, 0x14, 0x34, 0x54, 0x15,
-+ 0x15, 0x15, 0x15, 0x14, 0x17, 0x14, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x90, 0xf0, 0x00, 0xf8,
-+ 0x68, 0x68, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x0a, 0x0a, 0x0f, 0x12, 0x1f, 0x32, 0x52, 0x1f,
-+ 0x12, 0x13, 0x12, 0x14, 0x14, 0x19, 0x00, 0x00,
-+ 0x20, 0x20, 0xa0, 0x7c, 0xc8, 0x48, 0xa8, 0xa8,
-+ 0x30, 0x90, 0x90, 0xa8, 0xc8, 0x84, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x02, 0x04, 0x1f, 0x60, 0x1e, 0x12, 0x12,
-+ 0x1e, 0x08, 0x0c, 0x12, 0x22, 0x41, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0xf0, 0x0c, 0xf0, 0x90, 0x90,
-+ 0xf0, 0x20, 0x20, 0x50, 0x88, 0x08, 0x00, 0x00,
-+ 0x08, 0x0f, 0x09, 0x17, 0x15, 0x37, 0x50, 0x1f,
-+ 0x11, 0x17, 0x1a, 0x13, 0x12, 0x11, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xf8, 0x28, 0xf8, 0x80, 0xfc,
-+ 0x20, 0xf8, 0x24, 0xe0, 0x08, 0xf8, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x13, 0x12, 0x33, 0x53, 0x10,
-+ 0x17, 0x10, 0x1f, 0x12, 0x11, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0xf8, 0x48,
-+ 0xfc, 0x10, 0xfc, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x17, 0x12, 0x33, 0x53, 0x12,
-+ 0x13, 0x10, 0x1f, 0x11, 0x10, 0x17, 0x00, 0x00,
-+ 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8, 0xf8, 0x48,
-+ 0xf8, 0x80, 0xfc, 0x90, 0x70, 0x88, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x13, 0x10, 0x33, 0x52, 0x13,
-+ 0x11, 0x1f, 0x10, 0x13, 0x12, 0x13, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x00, 0xf8, 0x08, 0xf8,
-+ 0x10, 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0x00, 0x00,
-+ 0x08, 0x0f, 0x0a, 0x14, 0x13, 0x32, 0x53, 0x12,
-+ 0x13, 0x12, 0x15, 0x14, 0x1a, 0x12, 0x00, 0x00,
-+ 0x18, 0xf0, 0x48, 0x44, 0xf0, 0x10, 0xf8, 0x08,
-+ 0xfc, 0x54, 0x2c, 0xac, 0x84, 0x18, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x17, 0x11, 0x37, 0x51, 0x11,
-+ 0x16, 0x17, 0x10, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xfc, 0x10, 0xbc, 0x10, 0xbc,
-+ 0x00, 0xfc, 0xa0, 0xa0, 0x24, 0x1c, 0x00, 0x00,
-+ 0x09, 0x0f, 0x0d, 0x15, 0x17, 0x33, 0x55, 0x19,
-+ 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x10, 0xfc, 0x50, 0x50, 0xfc, 0x30, 0xb4, 0x4c,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x09, 0x09, 0x0f, 0x11, 0x1f, 0x33, 0x52, 0x14,
-+ 0x1b, 0x12, 0x13, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x20, 0xfc, 0x30, 0xb0, 0xc8,
-+ 0xf4, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x0f, 0x09, 0x1f, 0x10, 0x33, 0x52, 0x13,
-+ 0x12, 0x13, 0x10, 0x13, 0x10, 0x17, 0x00, 0x00,
-+ 0x40, 0xf8, 0x20, 0xfc, 0x00, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xf8, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00,
-+ 0x08, 0x0f, 0x09, 0x17, 0x15, 0x37, 0x53, 0x12,
-+ 0x13, 0x13, 0x12, 0x13, 0x11, 0x16, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xf8, 0x28, 0xf8, 0xf0, 0x10,
-+ 0xf0, 0xf0, 0x10, 0xf0, 0x30, 0x08, 0x00, 0x00,
-+ 0x08, 0x0f, 0x0b, 0x12, 0x13, 0x32, 0x53, 0x17,
-+ 0x13, 0x12, 0x13, 0x12, 0x13, 0x17, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0xfc,
-+ 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x11, 0x17, 0x30, 0x53, 0x12,
-+ 0x12, 0x13, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xfc, 0x00, 0xb8, 0xa8,
-+ 0xa8, 0xb8, 0x10, 0x98, 0x64, 0x44, 0x00, 0x00,
-+ 0x09, 0x09, 0x0b, 0x12, 0x17, 0x3a, 0x53, 0x12,
-+ 0x13, 0x10, 0x17, 0x14, 0x14, 0x14, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x40, 0xf8, 0x40, 0xf8, 0x40,
-+ 0xfc, 0x00, 0xbc, 0xa4, 0xe4, 0x0c, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x13, 0x12, 0x33, 0x50, 0x17,
-+ 0x14, 0x17, 0x15, 0x19, 0x19, 0x17, 0x00, 0x00,
-+ 0xa0, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0x00, 0xf8,
-+ 0xe0, 0xfc, 0x48, 0x30, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x08, 0x0f, 0x0d, 0x17, 0x14, 0x37, 0x55, 0x17,
-+ 0x10, 0x13, 0x12, 0x12, 0x1f, 0x10, 0x00, 0x00,
-+ 0x20, 0xe0, 0x20, 0xbc, 0xc0, 0x80, 0x38, 0xc0,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x11, 0x3e, 0x2a, 0x6a, 0x2e, 0x32,
-+ 0x23, 0x22, 0x23, 0x22, 0x24, 0x28, 0x00, 0x00,
-+ 0x80, 0xfc, 0x48, 0xb8, 0xa8, 0xb8, 0xe8, 0x14,
-+ 0xf0, 0x10, 0xf0, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x0f, 0x08, 0x13, 0x1f, 0x33, 0x50, 0x13,
-+ 0x1f, 0x10, 0x17, 0x15, 0x17, 0x14, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0xfc, 0xe8, 0x40, 0xf8,
-+ 0xfc, 0x08, 0xfc, 0x48, 0x28, 0x18, 0x00, 0x00,
-+ 0x09, 0x0f, 0x09, 0x13, 0x12, 0x33, 0x50, 0x17,
-+ 0x14, 0x18, 0x13, 0x10, 0x10, 0x17, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0xa8, 0xf8, 0x00, 0xfc,
-+ 0x44, 0xf8, 0x90, 0x60, 0xc0, 0x00, 0x00, 0x00,
-+ 0x08, 0x0b, 0x0a, 0x13, 0x12, 0x33, 0x52, 0x10,
-+ 0x17, 0x15, 0x17, 0x15, 0x17, 0x14, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00,
-+ 0xfc, 0x54, 0xfc, 0x54, 0xfc, 0x44, 0x00, 0x00,
-+ 0x15, 0x1f, 0x15, 0x17, 0x22, 0x2f, 0x6a, 0x2f,
-+ 0x22, 0x2f, 0x22, 0x2f, 0x25, 0x28, 0x00, 0x00,
-+ 0x28, 0xa8, 0x28, 0x7c, 0x50, 0xd0, 0xfc, 0xd0,
-+ 0x50, 0xfc, 0x50, 0xd0, 0x7c, 0xc0, 0x00, 0x00,
-+ 0x0f, 0x08, 0x0f, 0x15, 0x10, 0x37, 0x54, 0x17,
-+ 0x14, 0x17, 0x15, 0x19, 0x19, 0x17, 0x00, 0x00,
-+ 0xbc, 0x00, 0xbc, 0xb4, 0x40, 0xfc, 0xa0, 0xf8,
-+ 0xa8, 0xf8, 0xe4, 0x38, 0xe4, 0x1c, 0x00, 0x00,
-+ 0x13, 0x12, 0x13, 0x20, 0x2f, 0x6b, 0x29, 0x2f,
-+ 0x2a, 0x2b, 0x2b, 0x32, 0x37, 0x20, 0x00, 0x00,
-+ 0xb8, 0xa8, 0xb8, 0x00, 0xfc, 0xa0, 0x20, 0xfc,
-+ 0xe8, 0xa8, 0x90, 0xd0, 0xa8, 0xc4, 0x00, 0x00,
-+ 0x09, 0x0f, 0x0d, 0x11, 0x13, 0x33, 0x52, 0x13,
-+ 0x10, 0x13, 0x10, 0x17, 0x12, 0x14, 0x00, 0x00,
-+ 0x50, 0xfc, 0x18, 0xf0, 0xf8, 0x58, 0xe8, 0xf8,
-+ 0x40, 0xf8, 0x40, 0xfc, 0xa8, 0xa4, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x02, 0x3c, 0x20, 0x20, 0x3e, 0x20, 0x20, 0x3f,
-+ 0x24, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x08, 0xf8,
-+ 0x88, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x01, 0x04, 0x08, 0x10, 0x6f, 0x08, 0x08, 0x08,
-+ 0x0f, 0x02, 0x02, 0x04, 0x08, 0x30, 0x00, 0x00,
-+ 0xc0, 0x40, 0x20, 0x10, 0xec, 0x20, 0x20, 0x20,
-+ 0xe0, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x02, 0x03, 0x04, 0x18, 0x7f, 0x11, 0x11, 0x1f,
-+ 0x13, 0x03, 0x05, 0x09, 0x11, 0x60, 0x00, 0x00,
-+ 0x00, 0xe0, 0x40, 0x80, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x10, 0x40, 0x20, 0x24, 0x04, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x22, 0x22, 0x3e,
-+ 0x14, 0x14, 0x15, 0x26, 0x2c, 0x41, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0x88, 0x88, 0xf8,
-+ 0x50, 0x50, 0x50, 0x94, 0x94, 0x0c, 0x00, 0x00,
-+ 0x08, 0x3e, 0x14, 0x7f, 0x00, 0x3e, 0x22, 0x3e,
-+ 0x22, 0x3e, 0x14, 0x15, 0x26, 0x4d, 0x00, 0x00,
-+ 0x20, 0xf8, 0x50, 0xfc, 0x00, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x50, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x01, 0x3f, 0x21, 0x2d, 0x25,
-+ 0x25, 0x2b, 0x33, 0x21, 0x21, 0x21, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x08, 0x68, 0x28,
-+ 0x28, 0x58, 0x98, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x07, 0x02, 0x04, 0x18, 0x6f, 0x00, 0x3e, 0x22,
-+ 0x3a, 0x27, 0x3a, 0x26, 0x22, 0x26, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0x30, 0xec, 0x00, 0x48, 0x48,
-+ 0x90, 0x20, 0x90, 0x90, 0x48, 0x48, 0x00, 0x00,
-+ 0x01, 0x04, 0x08, 0x10, 0x6f, 0x04, 0x04, 0x07,
-+ 0x08, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
-+ 0xc0, 0x40, 0x20, 0x10, 0xec, 0x00, 0x00, 0xe0,
-+ 0x20, 0x20, 0x20, 0x40, 0x40, 0x80, 0x00, 0x00,
-+ 0x04, 0x3c, 0x04, 0x1f, 0x69, 0x0f, 0x09, 0x0f,
-+ 0x04, 0x3f, 0x04, 0x7f, 0x08, 0x30, 0x00, 0x00,
-+ 0x48, 0x70, 0x44, 0xfc, 0x20, 0xe0, 0x20, 0xe0,
-+ 0x40, 0xf8, 0x40, 0xfc, 0x20, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x20, 0x27, 0x24, 0x24, 0x27,
-+ 0x24, 0x24, 0x24, 0x23, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xc8, 0x48, 0x48, 0xc8,
-+ 0x08, 0x28, 0x28, 0xe8, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x1e, 0x12, 0x12, 0x12, 0x12, 0x7f, 0x12,
-+ 0x12, 0x12, 0x12, 0x22, 0x22, 0x47, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0x48, 0x48, 0xfc, 0x48,
-+ 0x48, 0x48, 0x48, 0x88, 0x88, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x1f, 0x11, 0x11, 0x1f, 0x11,
-+ 0x11, 0x7f, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10,
-+ 0x10, 0xfc, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x28, 0x28, 0x30, 0x27,
-+ 0x24, 0x24, 0x24, 0x27, 0x24, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x98, 0x78, 0x08, 0xc8,
-+ 0x48, 0x48, 0x48, 0xc8, 0x48, 0x18, 0x00, 0x00,
-+ 0x01, 0x3f, 0x21, 0x3f, 0x21, 0x3f, 0x00, 0x1f,
-+ 0x10, 0x17, 0x10, 0x17, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x00, 0xf0,
-+ 0x10, 0xd0, 0x10, 0xd0, 0x10, 0x30, 0x00, 0x00,
-+ 0x04, 0x3f, 0x04, 0x1f, 0x04, 0x7f, 0x01, 0x1f,
-+ 0x11, 0x1f, 0x11, 0x7f, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0x00, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xfc, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x07, 0x18,
-+ 0x7f, 0x11, 0x1f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xc0, 0x80,
-+ 0xf0, 0x10, 0xf0, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x1f, 0x10, 0x20, 0x40,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x04, 0x08, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x47, 0x18, 0x7f, 0x11, 0x11,
-+ 0x1f, 0x13, 0x03, 0x05, 0x19, 0x60, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xc0, 0x80, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x10, 0x40, 0x24, 0x24, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x5e, 0x00, 0x00, 0x7f, 0x14,
-+ 0x14, 0x14, 0x14, 0x25, 0x24, 0x43, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0x40, 0x7c, 0x40, 0xf8, 0x88,
-+ 0x50, 0x30, 0x68, 0x8c, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x5f, 0x02, 0x06, 0x19, 0x6b,
-+ 0x0c, 0x35, 0x06, 0x0c, 0x30, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf8, 0x00, 0x48, 0x48, 0x50,
-+ 0xa0, 0xa0, 0x90, 0x88, 0x84, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x5c, 0x10, 0x1e, 0x10, 0x1f,
-+ 0x04, 0x1f, 0x6a, 0x25, 0x25, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x00, 0xf8, 0x48, 0x28, 0x28, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x7f, 0x0f, 0x08, 0x0f, 0x08,
-+ 0x0f, 0x7f, 0x09, 0x1f, 0x69, 0x09, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xf8, 0xe0, 0x20, 0xe0, 0x20,
-+ 0xe0, 0xfc, 0x20, 0xf0, 0x2c, 0x60, 0x00, 0x00,
-+ 0x00, 0x04, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x02, 0x02, 0x04, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x20, 0x17, 0x10, 0x00, 0x00, 0x1f,
-+ 0x10, 0x21, 0x21, 0x42, 0x44, 0x08, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf0, 0x90, 0x90, 0x90, 0xfc,
-+ 0xc0, 0x20, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x0f, 0x22, 0x12, 0x13, 0x02, 0x02, 0x12,
-+ 0x13, 0x22, 0x20, 0x40, 0x5f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10,
-+ 0xf0, 0x10, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x20, 0x13, 0x12, 0x02, 0x02, 0x12,
-+ 0x13, 0x22, 0x20, 0x40, 0x40, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0x48,
-+ 0xf8, 0x48, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x20, 0x10, 0x17, 0x00, 0x00, 0x11,
-+ 0x11, 0x22, 0x24, 0x48, 0x40, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x44, 0xe4, 0xe8, 0xf0, 0x60,
-+ 0x50, 0x50, 0x48, 0x44, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x03, 0x22, 0x12, 0x12, 0x03, 0x02, 0x10,
-+ 0x10, 0x21, 0x21, 0x42, 0x44, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0xf8, 0xa8, 0xa0,
-+ 0xa0, 0x20, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x0f, 0x22, 0x12, 0x13, 0x04, 0x04, 0x1a,
-+ 0x13, 0x21, 0x22, 0x42, 0x44, 0x08, 0x00, 0x00,
-+ 0x08, 0xc8, 0x28, 0x28, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0x28, 0x28, 0x28, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x07, 0x24, 0x14, 0x17, 0x04, 0x04, 0x15,
-+ 0x15, 0x25, 0x25, 0x44, 0x47, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x88, 0xe8,
-+ 0x28, 0x28, 0xe8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x27, 0x10, 0x13, 0x02, 0x02, 0x13,
-+ 0x10, 0x22, 0x22, 0x44, 0x48, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x00, 0xf8, 0x08, 0x08, 0xf8,
-+ 0x40, 0x50, 0x48, 0x44, 0x44, 0xc0, 0x00, 0x00,
-+ 0x00, 0x07, 0x20, 0x13, 0x12, 0x02, 0x02, 0x13,
-+ 0x11, 0x20, 0x27, 0x41, 0x42, 0x04, 0x00, 0x00,
-+ 0x40, 0xfc, 0x00, 0xf8, 0xe8, 0xa8, 0xe8, 0xf8,
-+ 0xf0, 0x00, 0xfc, 0x50, 0x48, 0x48, 0x00, 0x00,
-+ 0x00, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
-+ 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xc0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x1f, 0x12, 0x1f, 0x11, 0x14,
-+ 0x17, 0x15, 0x1d, 0x22, 0x25, 0x58, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0xe8, 0x10, 0xf0, 0x00,
-+ 0x70, 0x54, 0x54, 0xcc, 0x80, 0x7c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x11, 0x11, 0x1f, 0x11, 0x13,
-+ 0x13, 0x15, 0x15, 0x29, 0x31, 0x41, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x90,
-+ 0x50, 0x50, 0x34, 0x2c, 0x0c, 0x04, 0x00, 0x00,
-+ 0x08, 0x0b, 0x10, 0x17, 0x30, 0x50, 0x13, 0x10,
-+ 0x07, 0x04, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x18, 0xe0, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x00,
-+ 0xc0, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x17, 0x14, 0x17, 0x14, 0x17,
-+ 0x10, 0x1f, 0x11, 0x27, 0x21, 0x4f, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xd0, 0x50, 0xd0, 0x50, 0xd0,
-+ 0x10, 0xf0, 0x14, 0xcc, 0x0c, 0xe4, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x0f, 0x00, 0x40, 0x41, 0x5d, 0x55, 0x55, 0x55,
-+ 0x5d, 0x55, 0x41, 0x46, 0x7f, 0x40, 0x00, 0x00,
-+ 0xe0, 0x40, 0x88, 0x08, 0xf8, 0x98, 0x68, 0x28,
-+ 0x58, 0x98, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x02, 0x22, 0x12, 0x0a, 0x06,
-+ 0x05, 0x04, 0x08, 0x10, 0x20, 0x41, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x90, 0x70, 0x1c, 0x10, 0x20, 0xc0, 0x00, 0x00,
-+ 0x01, 0x06, 0x3c, 0x04, 0x04, 0x04, 0x7f, 0x04,
-+ 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0xc8, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3f, 0x09, 0x09, 0x09, 0x7f,
-+ 0x08, 0x0c, 0x12, 0x11, 0x21, 0x40, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0xc8,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x1f, 0x2a, 0x2a, 0x4a, 0x12,
-+ 0x14, 0x24, 0x08, 0x11, 0x01, 0x06, 0x00, 0x00,
-+ 0x08, 0x28, 0x28, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x3f, 0x04, 0x04, 0x7f, 0x08,
-+ 0x0a, 0x09, 0x11, 0x1f, 0x70, 0x00, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0xc8, 0x48,
-+ 0x48, 0x48, 0x48, 0x88, 0x88, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x2a, 0x2a, 0x2a, 0x2a, 0x7f, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x21, 0x00, 0x00,
-+ 0x08, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xe8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x01, 0x06, 0x3c, 0x04, 0x04, 0x7f, 0x04, 0x04,
-+ 0x3f, 0x21, 0x21, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0xc8, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x14, 0x22, 0x5d, 0x00, 0x7f,
-+ 0x10, 0x1e, 0x22, 0x02, 0x02, 0x0c, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x02, 0x02, 0x3c, 0x06, 0x19, 0x64, 0x04, 0x7f,
-+ 0x0c, 0x0e, 0x15, 0x25, 0x44, 0x04, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x22, 0x12, 0x15, 0x7e, 0x14, 0x15, 0x14, 0x7f,
-+ 0x14, 0x14, 0x14, 0x24, 0x25, 0x46, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x48, 0x48, 0x48, 0xc8, 0x48,
-+ 0x68, 0x58, 0x8c, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x7f, 0x2a, 0x2a, 0x54, 0x54, 0x2a, 0x2a,
-+ 0x00, 0x7f, 0x08, 0x08, 0x0f, 0x78, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x22, 0x22,
-+ 0x3e, 0x14, 0x14, 0x14, 0x24, 0x43, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x08, 0x1c, 0x04, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x7f, 0x49, 0x49, 0x7f,
-+ 0x4c, 0x1a, 0x19, 0x29, 0x48, 0x08, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x0c, 0x12, 0x22, 0x7f, 0x01,
-+ 0x3d, 0x25, 0x25, 0x3d, 0x21, 0x03, 0x00, 0x00,
-+ 0x08, 0x48, 0xc8, 0x48, 0x48, 0x48, 0xc8, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x3f, 0x21, 0x3f, 0x10, 0x1f,
-+ 0x2b, 0x4b, 0x15, 0x25, 0x09, 0x16, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x04, 0x7f, 0x3e, 0x2a, 0x36, 0x2a, 0x2a,
-+ 0x26, 0x00, 0x7f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x20, 0x40, 0xfc, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x18, 0x00, 0xf8, 0x08, 0x08, 0x70, 0x00, 0x00,
-+ 0x08, 0x2a, 0x2a, 0x3e, 0x00, 0x7f, 0x00, 0x3e,
-+ 0x22, 0x3e, 0x22, 0x14, 0x1e, 0x70, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x04, 0x7f, 0x15, 0x75, 0x15, 0x35,
-+ 0x5c, 0x0e, 0x15, 0x24, 0x44, 0x04, 0x00, 0x00,
-+ 0x88, 0x28, 0x28, 0xe8, 0x28, 0xe8, 0x28, 0x68,
-+ 0xe8, 0x28, 0x28, 0x88, 0x88, 0x18, 0x00, 0x00,
-+ 0x12, 0x12, 0x7f, 0x12, 0x14, 0x0a, 0x11, 0x1f,
-+ 0x20, 0x5f, 0x11, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x08, 0x48, 0xc8, 0x48, 0x48, 0x48, 0x48, 0xc8,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x24, 0x49, 0x24, 0x3f, 0x24, 0x3f, 0x24, 0x3f,
-+ 0x04, 0x7f, 0x0e, 0x15, 0x64, 0x04, 0x00, 0x00,
-+ 0x88, 0x28, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0x28, 0xe8, 0x28, 0x08, 0x88, 0x18, 0x00, 0x00,
-+ 0x00, 0x7f, 0x14, 0x7f, 0x55, 0x7f, 0x00, 0x3e,
-+ 0x00, 0x7f, 0x2a, 0x29, 0x49, 0x18, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x04, 0x04, 0x0a, 0x11, 0x3f, 0x40, 0x3f, 0x2d,
-+ 0x3f, 0x12, 0x1a, 0x15, 0x24, 0x48, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x08, 0x88, 0x98, 0x00, 0x00,
-+ 0x04, 0x04, 0x0a, 0x11, 0x3f, 0x40, 0x3f, 0x2d,
-+ 0x3f, 0x12, 0x12, 0x2d, 0x25, 0x49, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0xa8, 0xa8, 0x68, 0x68, 0x28,
-+ 0x38, 0x28, 0x4c, 0x48, 0x88, 0x30, 0x00, 0x00,
-+ 0x04, 0x04, 0x0a, 0x11, 0x3f, 0x40, 0x3f, 0x2d,
-+ 0x3f, 0x12, 0x12, 0x2d, 0x25, 0x49, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0x28, 0x68, 0x68, 0xa8, 0xa8,
-+ 0x28, 0x28, 0x48, 0x48, 0x88, 0x30, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x3e, 0x49, 0x3e, 0x2a,
-+ 0x2a, 0x3e, 0x14, 0x12, 0x23, 0x42, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x48, 0xc8, 0x48,
-+ 0x68, 0x58, 0x8c, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x21, 0x3e, 0x32, 0x5e,
-+ 0x10, 0x3f, 0x01, 0x02, 0x0c, 0x30, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x50, 0xfc, 0x20, 0xf8, 0x20,
-+ 0x20, 0xf8, 0x08, 0x08, 0x08, 0x70, 0x00, 0x00,
-+ 0x04, 0x7f, 0x0a, 0x7f, 0x2e, 0x2e, 0x3f, 0x51,
-+ 0x1f, 0x11, 0x1f, 0x11, 0x21, 0x41, 0x00, 0x00,
-+ 0x08, 0xe8, 0xa8, 0x28, 0xa8, 0xe8, 0x68, 0x28,
-+ 0x28, 0x28, 0x28, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x7c, 0x28, 0x2a, 0x2a, 0x7e, 0x12,
-+ 0x1e, 0x70, 0x10, 0x11, 0x21, 0x42, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0xa8, 0xa8, 0xa8, 0xfc, 0x90,
-+ 0x90, 0xfc, 0x90, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x7f, 0x2a, 0x2a, 0x2a, 0x7e, 0x12,
-+ 0x1e, 0x72, 0x12, 0x14, 0x24, 0x49, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0xa8, 0xa8, 0xa8, 0xfc, 0x90,
-+ 0x90, 0xfc, 0x90, 0x90, 0x90, 0x90, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x1e, 0x23, 0x22, 0x7a, 0x2a,
-+ 0x2a, 0x2a, 0x3a, 0x22, 0x03, 0x0e, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x7e, 0x12, 0x12, 0x13, 0x22, 0x4c, 0x00,
-+ 0x3e, 0x22, 0x22, 0x22, 0x3f, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x09, 0x08, 0x3e, 0x00,
-+ 0x3e, 0x22, 0x22, 0x22, 0x3f, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x01, 0x09, 0x09, 0x1f, 0x21, 0x02, 0x7f, 0x06,
-+ 0x0a, 0x1f, 0x62, 0x04, 0x08, 0x10, 0x00, 0x00,
-+ 0x00, 0x20, 0x10, 0xf8, 0x08, 0x80, 0xfc, 0x40,
-+ 0x20, 0xf0, 0x2c, 0x20, 0x20, 0xc0, 0x00, 0x00,
-+ 0x00, 0x7f, 0x2a, 0x2a, 0x55, 0x54, 0x2a, 0x2a,
-+ 0x00, 0x7f, 0x08, 0x08, 0x0e, 0x79, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x88, 0x88, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x00, 0x3f, 0x22, 0x22, 0x3e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x49, 0x1a, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x3e, 0x22,
-+ 0x3f, 0x22, 0x3e, 0x22, 0x3f, 0x61, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x40, 0x40,
-+ 0xf8, 0x48, 0x48, 0x88, 0x88, 0x30, 0x00, 0x00,
-+ 0x08, 0x0c, 0x2a, 0x2a, 0x59, 0x14, 0x22, 0x3f,
-+ 0x22, 0x5f, 0x02, 0x04, 0x08, 0x30, 0x00, 0x00,
-+ 0x20, 0x30, 0xa8, 0xa8, 0x60, 0x50, 0x88, 0xfc,
-+ 0x08, 0xf0, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x08, 0x7f, 0x08, 0x3e, 0x08, 0x7f, 0x3e, 0x22,
-+ 0x3e, 0x3e, 0x22, 0x3e, 0x12, 0x61, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x88, 0x88, 0x30, 0x00, 0x00,
-+ 0x2a, 0x54, 0x2a, 0x3e, 0x2b, 0x3e, 0x2a, 0x3e,
-+ 0x08, 0x7e, 0x1c, 0x2a, 0x49, 0x0a, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x1e, 0x23, 0x7e, 0x23, 0x3e,
-+ 0x22, 0x3e, 0x3e, 0x20, 0x3e, 0x21, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x40, 0x40, 0xf8, 0x48,
-+ 0x48, 0x48, 0x48, 0x88, 0x88, 0x30, 0x00, 0x00,
-+ 0x00, 0x7f, 0x2b, 0x5d, 0x2b, 0x4d, 0x1a, 0x61,
-+ 0x09, 0x34, 0x0a, 0x34, 0x09, 0x32, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x06, 0x38, 0x7f, 0x08, 0x7f, 0x6b, 0x5d, 0x7f,
-+ 0x08, 0x7f, 0x08, 0x7e, 0x3a, 0x55, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x88, 0x88, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x25, 0x3f, 0x25, 0x2f, 0x2a, 0x2f,
-+ 0x2a, 0x2f, 0x3f, 0x33, 0x3f, 0x50, 0x00, 0x00,
-+ 0x20, 0xa0, 0x20, 0xa0, 0x78, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xe8, 0x68, 0xc8, 0xd8, 0x00, 0x00,
-+ 0x14, 0x7f, 0x14, 0x77, 0x55, 0x77, 0x24, 0x3f,
-+ 0x24, 0x7e, 0x24, 0x3e, 0x24, 0x3f, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x88, 0x88, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x0f, 0x10, 0x10, 0x20, 0x40,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x0f, 0x12, 0x12, 0x2e, 0x45,
-+ 0x04, 0x08, 0x10, 0x01, 0x02, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x48, 0x48, 0x48, 0xc8,
-+ 0x48, 0xa8, 0x88, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x0f, 0x10, 0x11, 0x39, 0x57,
-+ 0x13, 0x14, 0x18, 0x1f, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x48, 0x48,
-+ 0x48, 0xc8, 0x48, 0xc8, 0x48, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x10, 0x10, 0x3f, 0x52, 0x12,
-+ 0x1f, 0x12, 0x12, 0x1f, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x08, 0x08, 0xc8, 0x48, 0x48,
-+ 0xc8, 0x48, 0x48, 0xc8, 0x48, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x12, 0x3f, 0x42, 0x1f, 0x12,
-+ 0x1f, 0x12, 0x1f, 0x12, 0x12, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x48, 0xe8, 0x08, 0xc8, 0x48,
-+ 0xc8, 0x48, 0xc8, 0x48, 0xc8, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x10, 0x3f, 0x4f, 0x08, 0x0f,
-+ 0x1f, 0x12, 0x1f, 0x12, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x08, 0xc8, 0x88, 0x88, 0x88,
-+ 0xc8, 0x48, 0xc8, 0x48, 0xc8, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x14, 0x12, 0x3f, 0x40, 0x7e,
-+ 0x10, 0x1e, 0x22, 0x02, 0x02, 0x0c, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x88, 0xe8, 0xa8, 0xa8,
-+ 0xe8, 0xb0, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x13, 0x1c,
-+ 0x70, 0x10, 0x10, 0x10, 0x08, 0x07, 0x00, 0x00,
-+ 0x00, 0x00, 0x08, 0x10, 0x20, 0xc0, 0x00, 0x00,
-+ 0x00, 0x00, 0x04, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x27, 0x24, 0x27, 0x24, 0x27,
-+ 0x24, 0x20, 0x20, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x90, 0xf0, 0x90, 0xf0,
-+ 0x90, 0x80, 0x80, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x24, 0x35, 0x2b, 0x29, 0x21,
-+ 0x25, 0x25, 0x29, 0x29, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x90, 0xa0, 0xf8, 0x20, 0xf8, 0x20,
-+ 0xf8, 0x20, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x27, 0x24, 0x3f, 0x27, 0x24,
-+ 0x27, 0x27, 0x27, 0x2c, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0xf0, 0x90, 0xfc, 0xf0, 0x10,
-+ 0xf0, 0xf0, 0xf0, 0x18, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x21, 0x27, 0x38, 0x27, 0x25,
-+ 0x27, 0x22, 0x25, 0x29, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x80, 0x40, 0xf0, 0x08, 0x70, 0x50,
-+ 0x70, 0x20, 0x50, 0x88, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x08, 0x07, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x20, 0x23, 0x22, 0x23, 0x20, 0x2f,
-+ 0x29, 0x2f, 0x29, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xe0, 0x20, 0xe0, 0x00, 0x78,
-+ 0x48, 0x78, 0x48, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x02, 0x02, 0x3f, 0x04, 0x04, 0x08, 0x11, 0x21,
-+ 0x01, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xc0, 0x40, 0x44, 0x44, 0x3c, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x7f, 0x11,
-+ 0x11, 0x11, 0x11, 0x21, 0x21, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0xfc, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x7f, 0x11, 0x11,
-+ 0x11, 0x11, 0x11, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0xfc, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x3f, 0x01, 0x09, 0x09, 0x08,
-+ 0x7f, 0x08, 0x08, 0x10, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x00, 0x20, 0x20, 0x20,
-+ 0xfc, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x01, 0x01, 0x01, 0x3f, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x01, 0x21, 0x13, 0x12, 0x07, 0x1a, 0x13, 0x22,
-+ 0x23, 0x01, 0x7f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x10, 0x20, 0xf8, 0x40, 0xf0, 0x40, 0xf0, 0x40,
-+ 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x01,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0x00, 0x80, 0x40, 0x20,
-+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x09, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x13, 0x12,
-+ 0x12, 0x12, 0x12, 0x22, 0x22, 0x41, 0x00, 0x00,
-+ 0x18, 0xe0, 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x10,
-+ 0x10, 0x10, 0x60, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x10, 0x1e, 0x12, 0x12, 0x32, 0x2a, 0x4c,
-+ 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0xb0, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x08, 0x0c, 0x12, 0x21, 0x49, 0x0c, 0x12, 0x11,
-+ 0x3f, 0x52, 0x12, 0x12, 0x1e, 0x10, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x70, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x09, 0x09, 0x1f, 0x02, 0x7f, 0x04, 0x08,
-+ 0x17, 0x64, 0x04, 0x05, 0x04, 0x03, 0x00, 0x00,
-+ 0x00, 0x20, 0x10, 0xf0, 0x80, 0xfc, 0x40, 0x20,
-+ 0xd0, 0x4c, 0x40, 0x80, 0x10, 0xf0, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x20, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x13, 0x12, 0x12, 0x12, 0x1f, 0x12,
-+ 0x13, 0x13, 0x25, 0x25, 0x49, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0x90, 0xa8, 0x28, 0xd0, 0x14,
-+ 0x24, 0x08, 0x10, 0x24, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x17, 0x14, 0x17, 0x14, 0x17,
-+ 0x14, 0x14, 0x17, 0x23, 0x24, 0x48, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x88, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0x28, 0x88, 0x98, 0x00, 0x00,
-+ 0x00, 0x1f, 0x17, 0x10, 0x13, 0x12, 0x13, 0x13,
-+ 0x12, 0x13, 0x11, 0x27, 0x20, 0x4f, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf8, 0x80, 0xf0, 0x10, 0xf0, 0xf0,
-+ 0x10, 0xf0, 0xf0, 0x20, 0xe0, 0x38, 0x00, 0x00,
-+ 0x00, 0x1f, 0x18, 0x14, 0x15, 0x1f, 0x12, 0x1a,
-+ 0x1a, 0x1f, 0x1a, 0x22, 0x24, 0x48, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xa0, 0x20, 0xfc, 0x54, 0x98,
-+ 0x90, 0x90, 0xb0, 0x28, 0x48, 0x84, 0x00, 0x00,
-+ 0x00, 0x1f, 0x15, 0x15, 0x1f, 0x15, 0x17, 0x15,
-+ 0x17, 0x15, 0x1f, 0x25, 0x24, 0x48, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0x10, 0xe0, 0x40, 0x7c, 0x50,
-+ 0x50, 0x50, 0xd0, 0x50, 0x90, 0x90, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x17, 0x16, 0x1a, 0x1f, 0x18,
-+ 0x1f, 0x1d, 0x1d, 0x2f, 0x28, 0x49, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0xa0, 0xfc, 0xc8, 0xa8,
-+ 0xa8, 0x90, 0x90, 0xa8, 0xc8, 0x84, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02,
-+ 0x04, 0x04, 0x08, 0x10, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x20, 0x10, 0x08, 0xf8, 0x04, 0x04, 0x00, 0x00,
-+ 0x01, 0x02, 0x1f, 0x08, 0x15, 0x7e, 0x04, 0x18,
-+ 0x63, 0x0c, 0x01, 0x0e, 0x00, 0x1f, 0x00, 0x00,
-+ 0x00, 0x40, 0xf0, 0x10, 0x28, 0xfc, 0x40, 0xb0,
-+ 0x0c, 0x40, 0x90, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x5f, 0x10, 0x1f, 0x17, 0x1f,
-+ 0x02, 0x7f, 0x1a, 0x64, 0x19, 0x07, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0xf0, 0x10, 0xd0, 0xf0, 0xf0,
-+ 0x00, 0xfc, 0xb0, 0xcc, 0x20, 0xd0, 0x00, 0x00,
-+ 0x12, 0x1f, 0x24, 0x7f, 0x24, 0x3e, 0x24, 0x3f,
-+ 0x20, 0x1f, 0x02, 0x01, 0x06, 0x38, 0x00, 0x00,
-+ 0x48, 0xfc, 0x90, 0xf8, 0x90, 0xf8, 0x90, 0xfc,
-+ 0x80, 0xf0, 0x60, 0x80, 0xe0, 0x1c, 0x00, 0x00,
-+ 0x05, 0x39, 0x21, 0x3d, 0x21, 0x21, 0x3f, 0x01,
-+ 0x3f, 0x04, 0x02, 0x01, 0x06, 0x78, 0x00, 0x00,
-+ 0x00, 0x78, 0x08, 0x78, 0x08, 0x08, 0xf8, 0x00,
-+ 0xf0, 0x20, 0x40, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x3f, 0x24,
-+ 0x3f, 0x0f, 0x02, 0x01, 0x03, 0x3c, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0xf8, 0x48,
-+ 0xf8, 0xe0, 0x40, 0x80, 0xc0, 0x38, 0x00, 0x00,
-+ 0x13, 0x17, 0x54, 0x5b, 0x33, 0x1b, 0x2a, 0x23,
-+ 0x40, 0x1f, 0x04, 0x03, 0x06, 0x38, 0x00, 0x00,
-+ 0x90, 0xd4, 0x34, 0xb8, 0xd0, 0x98, 0xa4, 0xc4,
-+ 0x00, 0xe0, 0x40, 0x80, 0xc0, 0x38, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x78, 0x48, 0x40, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x79, 0x49, 0x42, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x01, 0x00, 0x78, 0x48, 0x49, 0x49, 0x49, 0x49,
-+ 0x49, 0x79, 0x4a, 0x42, 0x04, 0x08, 0x00, 0x00,
-+ 0xe0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x00, 0x00,
-+ 0x01, 0x00, 0x78, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x79, 0x49, 0x42, 0x04, 0x08, 0x00, 0x00,
-+ 0xc0, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0xa0,
-+ 0xa0, 0x20, 0x10, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x03, 0x78, 0x48, 0x48, 0x48, 0x4f, 0x48,
-+ 0x48, 0x48, 0x78, 0x48, 0x40, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x01, 0x79, 0x49, 0x49, 0x4a, 0x4a, 0x4c,
-+ 0x4f, 0x48, 0x78, 0x48, 0x40, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0x40,
-+ 0xfc, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x03, 0x78, 0x4a, 0x4a, 0x4a, 0x4b, 0x48,
-+ 0x48, 0x48, 0x79, 0x4a, 0x44, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0x20, 0x20, 0x20, 0xfc, 0x60,
-+ 0xa0, 0xa0, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x79, 0x49, 0x49, 0x49, 0x49, 0x49,
-+ 0x49, 0x49, 0x7a, 0x42, 0x44, 0x00, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x00, 0x00, 0xfc, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x4f, 0x48, 0x49, 0x49, 0x49,
-+ 0x49, 0x79, 0x49, 0x42, 0x02, 0x04, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x00, 0xe0, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x48, 0x48, 0x49, 0x49, 0x49,
-+ 0x4f, 0x79, 0x49, 0x41, 0x01, 0x03, 0x00, 0x00,
-+ 0x20, 0xe0, 0x60, 0xa0, 0xa0, 0x20, 0x60, 0xa0,
-+ 0x20, 0x20, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x48, 0x49, 0x4f, 0x48, 0x48,
-+ 0x48, 0x48, 0x79, 0x49, 0x42, 0x04, 0x00, 0x00,
-+ 0x40, 0x40, 0x90, 0x88, 0x3c, 0xe4, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x01, 0x00, 0x78, 0x4b, 0x4a, 0x4a, 0x4a, 0x4a,
-+ 0x4a, 0x4b, 0x7a, 0x4a, 0x42, 0x02, 0x00, 0x00,
-+ 0xc0, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0xa8,
-+ 0x98, 0x18, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x01, 0x79, 0x49, 0x4a, 0x4a, 0x4f, 0x48,
-+ 0x48, 0x48, 0x79, 0x49, 0x42, 0x04, 0x00, 0x00,
-+ 0x60, 0x20, 0x20, 0x20, 0x10, 0x10, 0xf8, 0x94,
-+ 0x90, 0x90, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x04, 0x02, 0x01, 0x06, 0x78,
-+ 0x0f, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x20, 0x40, 0x80, 0x60, 0x1c,
-+ 0xe0, 0x20, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x01, 0x79, 0x49, 0x49, 0x49, 0x49, 0x49,
-+ 0x79, 0x4a, 0x42, 0x04, 0x08, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x88,
-+ 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x49, 0x48, 0x48, 0x4f, 0x48,
-+ 0x48, 0x49, 0x79, 0x42, 0x44, 0x00, 0x00, 0x00,
-+ 0x40, 0x20, 0x20, 0xc0, 0x44, 0x64, 0xe8, 0xf0,
-+ 0xe0, 0x50, 0x50, 0x48, 0x44, 0xc0, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x48, 0x4b, 0x4a, 0x4a, 0x4a,
-+ 0x4a, 0x4b, 0x7a, 0x48, 0x40, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0x08, 0xc8, 0x48, 0x48, 0x48,
-+ 0x48, 0xc8, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x12, 0x34, 0x4c, 0x0d, 0x13,
-+ 0x60, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x60, 0x50, 0x88, 0x08, 0xfc,
-+ 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x4f, 0x48, 0x48, 0x4a, 0x49,
-+ 0x48, 0x48, 0x78, 0x48, 0x41, 0x07, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x50, 0x90, 0x90,
-+ 0xa0, 0x60, 0x50, 0x88, 0x3c, 0xc4, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a,
-+ 0x4a, 0x4a, 0x7a, 0x4c, 0x47, 0x08, 0x00, 0x00,
-+ 0x08, 0x30, 0xe0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
-+ 0xa0, 0x90, 0xd0, 0xa8, 0xf8, 0x14, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4a, 0x4a, 0x4b, 0x4a, 0x4a,
-+ 0x4a, 0x7b, 0x4a, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0xf8, 0x48, 0x48,
-+ 0x48, 0xf8, 0x48, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x28, 0x2f, 0x28, 0x28, 0x2e, 0x38,
-+ 0x60, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x80, 0x88, 0x90, 0xe0, 0x80, 0x84, 0x84, 0x7c,
-+ 0x00, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x00, 0x07,
-+ 0x04, 0x04, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0xc0,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x4a, 0x4a, 0x4b, 0x4a, 0x4a,
-+ 0x4b, 0x7a, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48,
-+ 0xf8, 0x48, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x01, 0x79, 0x49, 0x49, 0x49, 0x49, 0x49,
-+ 0x49, 0x49, 0x79, 0x49, 0x47, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x10, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x02, 0x02, 0x72, 0x52, 0x5f, 0x55, 0x55, 0x55,
-+ 0x5d, 0x53, 0x72, 0x52, 0x44, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x48, 0xc8, 0x48, 0x48, 0x30,
-+ 0x30, 0x10, 0xb0, 0xa8, 0x48, 0x84, 0x00, 0x00,
-+ 0x00, 0x02, 0x7a, 0x4a, 0x4a, 0x4b, 0x4a, 0x48,
-+ 0x4a, 0x4a, 0x7a, 0x4a, 0x43, 0x02, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0x48, 0x48, 0xf8, 0x48, 0x40,
-+ 0x48, 0x48, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x49, 0x49, 0x4b, 0x4d, 0x49,
-+ 0x49, 0x49, 0x79, 0x49, 0x41, 0x01, 0x00, 0x00,
-+ 0x88, 0x88, 0x88, 0x08, 0xfc, 0x08, 0x48, 0x28,
-+ 0x28, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x79, 0x4a, 0x4a, 0x4d, 0x49, 0x49,
-+ 0x49, 0x79, 0x49, 0x41, 0x01, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x08, 0x08, 0xe8, 0x28, 0x28,
-+ 0xe8, 0x30, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x48, 0x48, 0x4f, 0x48, 0x48,
-+ 0x4b, 0x78, 0x48, 0x40, 0x0f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x00, 0x1f, 0x00, 0x7f,
-+ 0x04, 0x07, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x00, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xe0, 0x20, 0x20, 0x40, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x1f, 0x10, 0x17, 0x10, 0x17,
-+ 0x14, 0x14, 0x14, 0x27, 0x24, 0x40, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0xfc, 0x40, 0xc8, 0x28, 0xa8,
-+ 0xb0, 0x90, 0xb4, 0xac, 0x4c, 0x84, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x48, 0x49, 0x4f, 0x48, 0x48,
-+ 0x4b, 0x78, 0x48, 0x40, 0x0f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x90, 0x88, 0x3c, 0xc4, 0x40, 0x40,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x7f, 0x49, 0x49, 0x4b, 0x4c, 0x48,
-+ 0x48, 0x78, 0x48, 0x40, 0x03, 0x0c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0x08, 0x14, 0x94, 0x90,
-+ 0x60, 0x60, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x79, 0x49, 0x4f, 0x49, 0x49, 0x49,
-+ 0x49, 0x7f, 0x49, 0x41, 0x02, 0x04, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xf8, 0x20, 0x20, 0x20,
-+ 0x20, 0xfc, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x48, 0x49, 0x4b, 0x4c, 0x48,
-+ 0x49, 0x79, 0x49, 0x41, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xf8, 0x04, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x79, 0x02, 0x04, 0x00, 0x19, 0x62,
-+ 0x0f, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x44, 0x48, 0xb0, 0x10, 0x08,
-+ 0xe4, 0x20, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1e, 0x12, 0x12, 0x12, 0x12, 0x1e, 0x1a,
-+ 0x18, 0x14, 0x15, 0x22, 0x21, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0xf8, 0x60,
-+ 0x50, 0x88, 0x08, 0x00, 0x80, 0x7c, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x48, 0x4b, 0x4a, 0x4a, 0x4a,
-+ 0x4b, 0x7b, 0x4a, 0x42, 0x03, 0x02, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xa0, 0xf8, 0xa8, 0xa8, 0xa8,
-+ 0x38, 0x38, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x4a, 0x4c, 0x4b, 0x48, 0x48,
-+ 0x4f, 0x48, 0x78, 0x48, 0x40, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0x30, 0xc0, 0x40, 0x7c,
-+ 0xc0, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x48, 0x48, 0x4f, 0x48, 0x48,
-+ 0x49, 0x4e, 0x78, 0x48, 0x40, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x48, 0x50, 0xfc, 0x40, 0x88,
-+ 0x90, 0xe0, 0x80, 0x88, 0x88, 0x78, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x09, 0x09, 0x09, 0x3f, 0x20,
-+ 0x27, 0x24, 0x24, 0x27, 0x24, 0x20, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0x20, 0xf8, 0x08,
-+ 0xc8, 0x48, 0x48, 0xc8, 0x48, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x7a, 0x4c, 0x48, 0x48, 0x49, 0x4b,
-+ 0x4d, 0x79, 0x49, 0x41, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x78, 0x00, 0x00, 0x80, 0xfc, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x1f, 0x11, 0x1f, 0x00, 0x7f,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x11, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0x20, 0x20, 0x20, 0x20, 0xfc,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x01, 0x7f, 0x49, 0x49, 0x4f, 0x49, 0x49,
-+ 0x49, 0x7f, 0x49, 0x41, 0x01, 0x03, 0x00, 0x00,
-+ 0xa0, 0x28, 0x24, 0x24, 0x20, 0xfc, 0x28, 0x28,
-+ 0x90, 0x10, 0x34, 0x4c, 0x8c, 0x04, 0x00, 0x00,
-+ 0x00, 0x01, 0x78, 0x4b, 0x48, 0x4f, 0x49, 0x4a,
-+ 0x4b, 0x7e, 0x4a, 0x42, 0x02, 0x00, 0x00, 0x00,
-+ 0x10, 0xa0, 0xe0, 0x90, 0x80, 0xfc, 0x40, 0x40,
-+ 0xf8, 0x48, 0x48, 0x48, 0x58, 0x40, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x48, 0x4b, 0x49, 0x49, 0x4f,
-+ 0x48, 0x7b, 0x4a, 0x42, 0x03, 0x02, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xf0, 0x10, 0x10, 0xfc,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x4b, 0x4a, 0x4b, 0x4a, 0x4b,
-+ 0x4a, 0x79, 0x48, 0x41, 0x02, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x40, 0x80, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x48, 0x48, 0x4f, 0x48, 0x49,
-+ 0x4b, 0x7c, 0x4f, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x80, 0x88, 0xe8, 0x90, 0x90, 0xfc, 0x40, 0xf8,
-+ 0x30, 0x40, 0xfc, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x01, 0x01,
-+ 0x7f, 0x01, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x20, 0x10,
-+ 0xfc, 0x00, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x7f, 0x48, 0x4b, 0x4a, 0x4a, 0x4b,
-+ 0x4a, 0x7a, 0x4b, 0x42, 0x02, 0x02, 0x00, 0x00,
-+ 0x50, 0x48, 0xfc, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x00, 0x03, 0x78, 0x49, 0x48, 0x48, 0x4f, 0x49,
-+ 0x49, 0x7f, 0x49, 0x41, 0x02, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xf0, 0x40, 0x40, 0xfc, 0x10,
-+ 0x10, 0xfc, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x79, 0x4f, 0x4a, 0x4a, 0x4a, 0x4b,
-+ 0x4a, 0x7a, 0x4c, 0x44, 0x08, 0x13, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0xe8, 0x28, 0x44, 0xa4, 0x90,
-+ 0x90, 0x80, 0xa0, 0x90, 0x88, 0x08, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4a, 0x4a, 0x4a, 0x4b, 0x4a,
-+ 0x4a, 0x7a, 0x4c, 0x44, 0x0b, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x02, 0x02, 0x72, 0x57, 0x55, 0x59, 0x5f, 0x51,
-+ 0x55, 0x75, 0x55, 0x45, 0x07, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x38, 0xe8, 0x28, 0x28, 0xe8, 0x28,
-+ 0xe8, 0x28, 0x28, 0xf0, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x4a, 0x4c, 0x49, 0x4a, 0x48,
-+ 0x4b, 0x78, 0x48, 0x40, 0x0f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa8, 0xa0, 0x24, 0x1c, 0x00,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x0f, 0x18, 0x1f, 0x28, 0x4f, 0x08, 0x0f,
-+ 0x00, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x20, 0xfc, 0x40, 0xf8, 0x40, 0xf8, 0x40, 0xfc,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x07, 0x7c, 0x4a, 0x49, 0x4a, 0x4c, 0x4f,
-+ 0x4c, 0x7a, 0x49, 0x41, 0x02, 0x0c, 0x00, 0x00,
-+ 0x00, 0xf8, 0xc8, 0xa8, 0x10, 0xa8, 0xc8, 0xf8,
-+ 0xc8, 0xa8, 0x30, 0x90, 0xa8, 0x44, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x48, 0x4b, 0x4a, 0x4b, 0x4a,
-+ 0x4b, 0x78, 0x4f, 0x40, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0x40, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x7a, 0x4a, 0x4c, 0x49, 0x4a, 0x48,
-+ 0x4a, 0x7a, 0x4c, 0x41, 0x02, 0x0c, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0xd0, 0xa0, 0x10, 0x50, 0x40,
-+ 0x48, 0xc8, 0xb0, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x49, 0x4a, 0x4c, 0x4b, 0x4a,
-+ 0x4a, 0x7b, 0x4a, 0x42, 0x03, 0x02, 0x00, 0x00,
-+ 0x80, 0x80, 0xf8, 0x08, 0x10, 0xe0, 0x38, 0x08,
-+ 0x08, 0xb8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x49, 0x4e, 0x48, 0x4b, 0x48,
-+ 0x48, 0x78, 0x4d, 0x45, 0x09, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xec, 0x00, 0xf8, 0x10,
-+ 0xa0, 0x50, 0x48, 0x04, 0x14, 0xf0, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x4b, 0x4a, 0x4a, 0x4b, 0x4a,
-+ 0x4a, 0x7b, 0x4c, 0x44, 0x09, 0x06, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x50,
-+ 0x48, 0xfc, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x01, 0x7f, 0x49, 0x49, 0x4f, 0x49, 0x4b,
-+ 0x4b, 0x7d, 0x45, 0x09, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x80, 0x38, 0x28, 0x28, 0xe8, 0x28, 0xa8,
-+ 0xa8, 0x78, 0x40, 0x20, 0x10, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x79, 0x4b, 0x48, 0x4f, 0x48, 0x49,
-+ 0x4e, 0x79, 0x4e, 0x41, 0x06, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xe0, 0x20, 0xfc, 0x88, 0xc8,
-+ 0xf0, 0x60, 0xd0, 0x48, 0x44, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x4a, 0x4c, 0x48, 0x49, 0x4a,
-+ 0x48, 0x7b, 0x4d, 0x41, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x88, 0xf0, 0x90, 0xa0, 0x60,
-+ 0x90, 0xfc, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x79, 0x49, 0x4b, 0x4c, 0x48, 0x49,
-+ 0x4f, 0x79, 0x49, 0x41, 0x01, 0x01, 0x00, 0x00,
-+ 0x80, 0x80, 0xf0, 0x10, 0x20, 0xa0, 0x60, 0x98,
-+ 0xf4, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x70, 0x57, 0x54, 0x57, 0x54, 0x57,
-+ 0x56, 0x76, 0x57, 0x4a, 0x08, 0x10, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0xfc, 0x40, 0xc8, 0x28, 0xa8,
-+ 0xb0, 0x90, 0xb4, 0x4c, 0x8c, 0x04, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4b, 0x4a, 0x4b, 0x48, 0x49,
-+ 0x49, 0x79, 0x49, 0x41, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x00, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x01, 0x3f, 0x04, 0x02, 0x3f, 0x21, 0x5f, 0x11,
-+ 0x11, 0x01, 0x1f, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x80, 0xfc, 0x08, 0xf0, 0x10,
-+ 0x30, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x01, 0x7f, 0x49, 0x49, 0x4f, 0x49, 0x49,
-+ 0x4b, 0x7b, 0x4d, 0x49, 0x01, 0x01, 0x00, 0x00,
-+ 0x50, 0x90, 0x10, 0x14, 0x34, 0xf8, 0x50, 0x90,
-+ 0x50, 0x70, 0x28, 0x28, 0x44, 0x84, 0x00, 0x00,
-+ 0x00, 0x02, 0x7a, 0x4b, 0x48, 0x4f, 0x48, 0x4b,
-+ 0x4a, 0x7a, 0x4a, 0x42, 0x02, 0x02, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0xf8, 0x00, 0xfc, 0x40, 0xf8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x02, 0x02, 0x77, 0x54, 0x57, 0x54, 0x57, 0x54,
-+ 0x54, 0x77, 0x54, 0x47, 0x04, 0x04, 0x00, 0x00,
-+ 0x00, 0x38, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0x28, 0xa8, 0x30, 0xa0, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x00, 0x1f, 0x11, 0x1f,
-+ 0x11, 0x1f, 0x01, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x49, 0x48, 0x4b, 0x4a, 0x4c,
-+ 0x4b, 0x7a, 0x4a, 0x42, 0x02, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x10, 0xa0, 0xfc, 0x48, 0x40,
-+ 0xf8, 0x48, 0x48, 0x48, 0x58, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x7f, 0x48, 0x4b, 0x4b, 0x4a, 0x4b,
-+ 0x4a, 0x7b, 0x4a, 0x42, 0x02, 0x02, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x28, 0xa8, 0xf8,
-+ 0x48, 0xf8, 0x48, 0x48, 0x48, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x71, 0x52, 0x57, 0x58, 0x57, 0x54,
-+ 0x56, 0x75, 0x56, 0x45, 0x04, 0x05, 0x00, 0x00,
-+ 0x80, 0x80, 0x40, 0x20, 0xf0, 0x08, 0xac, 0xa8,
-+ 0xa8, 0xd0, 0xd0, 0xa8, 0xa8, 0xa8, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x51, 0x57, 0x55, 0x55, 0x57,
-+ 0x51, 0x73, 0x53, 0x45, 0x09, 0x01, 0x00, 0x00,
-+ 0x08, 0x08, 0xe8, 0x28, 0xe8, 0x68, 0x68, 0xe8,
-+ 0x28, 0xa8, 0x48, 0x48, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x49, 0x49, 0x49, 0x48, 0x4b,
-+ 0x4a, 0x7c, 0x48, 0x40, 0x01, 0x06, 0x00, 0x00,
-+ 0x40, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x08, 0xa0, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x4a, 0x4a, 0x4b, 0x4a, 0x4b,
-+ 0x4a, 0x7b, 0x4a, 0x45, 0x05, 0x08, 0x00, 0x00,
-+ 0x40, 0x80, 0xf0, 0x10, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x00, 0xfc, 0xa4, 0x54, 0x54, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x4a, 0x4b, 0x4a, 0x4b, 0x4a,
-+ 0x4b, 0x78, 0x4f, 0x40, 0x03, 0x0c, 0x00, 0x00,
-+ 0x40, 0x80, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x88, 0xfc, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x01, 0x00, 0x7b, 0x48, 0x49, 0x48, 0x4f, 0x49,
-+ 0x49, 0x7a, 0x4a, 0x44, 0x0b, 0x00, 0x00, 0x00,
-+ 0x10, 0xa0, 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0x00,
-+ 0xf8, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x4b, 0x4a, 0x4b, 0x4b, 0x4a,
-+ 0x4b, 0x79, 0x4b, 0x44, 0x01, 0x0e, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf0, 0x10, 0xf0, 0xf0, 0x10,
-+ 0xf0, 0xf0, 0x20, 0xc0, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x03, 0x78, 0x4f, 0x48, 0x49, 0x4e, 0x48,
-+ 0x4b, 0x7a, 0x4b, 0x42, 0x03, 0x02, 0x00, 0x00,
-+ 0x80, 0xf8, 0x90, 0xfc, 0xd8, 0xe0, 0x88, 0xf8,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x02, 0x7a, 0x4b, 0x48, 0x4f, 0x48, 0x4b,
-+ 0x4a, 0x7b, 0x4a, 0x40, 0x00, 0x0f, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0xf8, 0x80, 0xfc, 0x40, 0xf8,
-+ 0x48, 0xf8, 0x50, 0x48, 0x7c, 0x84, 0x00, 0x00,
-+ 0x01, 0x01, 0x79, 0x48, 0x4a, 0x4a, 0x4a, 0x4a,
-+ 0x4a, 0x7a, 0x4a, 0x43, 0x01, 0x0e, 0x00, 0x00,
-+ 0x18, 0xe0, 0x04, 0xfc, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0xfc, 0x98, 0x04, 0x00, 0x00,
-+ 0x00, 0x07, 0x74, 0x54, 0x54, 0x54, 0x54, 0x55,
-+ 0x55, 0x75, 0x55, 0x44, 0x07, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x90, 0xf0, 0x00, 0xf8,
-+ 0x68, 0xf8, 0x68, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x02, 0x02, 0x7f, 0x52, 0x52, 0x5f, 0x52, 0x5f,
-+ 0x52, 0x73, 0x54, 0x44, 0x08, 0x13, 0x00, 0x00,
-+ 0x20, 0x20, 0xa0, 0x20, 0x7c, 0xc8, 0x48, 0xa8,
-+ 0x28, 0x90, 0x90, 0xa8, 0xc8, 0x04, 0x00, 0x00,
-+ 0x00, 0x03, 0x78, 0x49, 0x48, 0x4f, 0x49, 0x49,
-+ 0x49, 0x79, 0x49, 0x41, 0x01, 0x06, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0xf0, 0x10,
-+ 0xf0, 0xf0, 0x10, 0xf0, 0x90, 0x08, 0x00, 0x00,
-+ 0x02, 0x02, 0x7a, 0x4f, 0x4a, 0x4a, 0x4b, 0x4a,
-+ 0x4a, 0x7a, 0x4c, 0x44, 0x08, 0x13, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xbc, 0x40, 0x60, 0xbc, 0xd0,
-+ 0x90, 0xfc, 0xb0, 0xa8, 0xc8, 0x04, 0x00, 0x00,
-+ 0x02, 0x02, 0x7f, 0x52, 0x5f, 0x5a, 0x5a, 0x5a,
-+ 0x7f, 0x57, 0x46, 0x0a, 0x12, 0x02, 0x00, 0x00,
-+ 0x20, 0x20, 0xe0, 0x20, 0xfc, 0xd4, 0x98, 0x90,
-+ 0x90, 0x30, 0xa8, 0xa8, 0x44, 0x84, 0x00, 0x00,
-+ 0x00, 0x00, 0x77, 0x54, 0x54, 0x57, 0x54, 0x55,
-+ 0x55, 0x75, 0x55, 0x4a, 0x08, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x90, 0x90, 0xfc, 0x90, 0xd8,
-+ 0xf8, 0xf8, 0xfc, 0xbc, 0xd4, 0x90, 0x00, 0x00,
-+ 0x00, 0x04, 0x73, 0x52, 0x58, 0x54, 0x54, 0x50,
-+ 0x5e, 0x72, 0x53, 0x42, 0x05, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0xa8, 0xf8, 0xa8,
-+ 0xf8, 0x20, 0xfc, 0x20, 0x20, 0xfc, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x49, 0x4b, 0x4a, 0x4f, 0x49,
-+ 0x49, 0x79, 0x49, 0x40, 0x0f, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0xfc, 0x08, 0xfc, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x1e, 0x12, 0x12, 0x1e, 0x00, 0x3f, 0x01,
-+ 0x7f, 0x00, 0x1e, 0x12, 0x1e, 0x12, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0xf0, 0x00, 0xf8, 0x00,
-+ 0xfc, 0x00, 0xf0, 0x90, 0xf0, 0x90, 0x00, 0x00,
-+ 0x05, 0x16, 0x2c, 0x12, 0x3f, 0x20, 0x4f, 0x08,
-+ 0x0f, 0x02, 0x1f, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x28, 0x70, 0xb0, 0x48, 0xfc, 0x08, 0xe0, 0x20,
-+ 0xe0, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x05, 0x75, 0x55, 0x57, 0x5c, 0x51, 0x5f,
-+ 0x52, 0x73, 0x52, 0x43, 0x04, 0x08, 0x00, 0x00,
-+ 0x20, 0x24, 0xf8, 0x20, 0xa4, 0xfc, 0x20, 0xf8,
-+ 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x18, 0x00, 0x00,
-+ 0x05, 0x05, 0x75, 0x5f, 0x55, 0x57, 0x55, 0x57,
-+ 0x55, 0x7f, 0x55, 0x45, 0x08, 0x11, 0x00, 0x00,
-+ 0x08, 0x10, 0x60, 0xc0, 0x40, 0x7c, 0x50, 0x50,
-+ 0x50, 0xd0, 0x50, 0x90, 0x90, 0x10, 0x00, 0x00,
-+ 0x02, 0x02, 0x7f, 0x52, 0x57, 0x54, 0x57, 0x54,
-+ 0x57, 0x72, 0x5f, 0x42, 0x02, 0x03, 0x00, 0x00,
-+ 0x00, 0x38, 0xe8, 0x28, 0xa8, 0xb8, 0xa8, 0xa8,
-+ 0xb8, 0x28, 0xc8, 0x48, 0x88, 0x18, 0x00, 0x00,
-+ 0x02, 0x02, 0x73, 0x56, 0x5a, 0x5f, 0x52, 0x52,
-+ 0x52, 0x77, 0x50, 0x45, 0x04, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0xa8, 0xa8, 0xfc, 0xa8, 0xa8,
-+ 0xa8, 0xfc, 0x00, 0x48, 0xa4, 0xa4, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x49, 0x4f, 0x49, 0x49, 0x49,
-+ 0x49, 0x79, 0x48, 0x45, 0x05, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x20, 0xfc, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0xc0, 0x28, 0x14, 0xf4, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x4b, 0x4b, 0x4d, 0x49, 0x4b,
-+ 0x48, 0x7f, 0x4a, 0x42, 0x04, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0xb0, 0x78, 0x54, 0x10, 0xf8,
-+ 0x00, 0xfc, 0x50, 0x48, 0x48, 0xc0, 0x00, 0x00,
-+ 0x00, 0x07, 0x70, 0x5f, 0x50, 0x57, 0x55, 0x57,
-+ 0x54, 0x77, 0x54, 0x47, 0x05, 0x09, 0x00, 0x00,
-+ 0x80, 0xf8, 0x88, 0xfc, 0x88, 0xf8, 0xa8, 0xb8,
-+ 0x88, 0xf8, 0x88, 0xb8, 0xa8, 0xa8, 0x00, 0x00,
-+ 0x02, 0x02, 0x7b, 0x4d, 0x48, 0x48, 0x4f, 0x49,
-+ 0x49, 0x79, 0x4a, 0x44, 0x1f, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x50, 0x88, 0x00, 0xfc, 0x50,
-+ 0x50, 0x58, 0xe4, 0x44, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x79, 0x49, 0x48, 0x4b, 0x4a, 0x4b,
-+ 0x48, 0x7f, 0x48, 0x41, 0x06, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xb8, 0xa8, 0xb8,
-+ 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x01, 0x07, 0x79, 0x48, 0x4f, 0x49, 0x49, 0x49,
-+ 0x4b, 0x7a, 0x4a, 0x42, 0x02, 0x02, 0x00, 0x00,
-+ 0x10, 0xfc, 0x50, 0x40, 0xfc, 0xf0, 0x10, 0xf0,
-+ 0xf8, 0x08, 0xe8, 0xa8, 0xe8, 0x18, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4c, 0x4a, 0x4a, 0x4c, 0x4b,
-+ 0x4a, 0x7f, 0x48, 0x47, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x48, 0xa8, 0xa4, 0x94, 0x70, 0xf8,
-+ 0xa8, 0xfc, 0x00, 0xfc, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x01, 0x79, 0x49, 0x49, 0x49, 0x49, 0x4b,
-+ 0x4b, 0x7a, 0x4b, 0x47, 0x01, 0x06, 0x00, 0x00,
-+ 0x40, 0xf0, 0x10, 0xf0, 0xf0, 0x10, 0xf0, 0xf8,
-+ 0xf8, 0x48, 0xf8, 0xfc, 0x10, 0x10, 0x00, 0x00,
-+ 0x01, 0x06, 0x76, 0x55, 0x5f, 0x51, 0x52, 0x57,
-+ 0x59, 0x77, 0x55, 0x43, 0x03, 0x0c, 0x00, 0x00,
-+ 0x04, 0xf4, 0xb4, 0xb4, 0x74, 0x94, 0x94, 0xf4,
-+ 0x34, 0xd4, 0x54, 0x84, 0xc4, 0x0c, 0x00, 0x00,
-+ 0x00, 0x03, 0x78, 0x4b, 0x4b, 0x4d, 0x49, 0x49,
-+ 0x49, 0x78, 0x4b, 0x42, 0x05, 0x08, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xfc, 0xf8, 0x50, 0xf0, 0x50,
-+ 0xf0, 0xa0, 0xf0, 0x78, 0xc0, 0x7c, 0x00, 0x00,
-+ 0x00, 0x03, 0x78, 0x4b, 0x4b, 0x4d, 0x49, 0x49,
-+ 0x49, 0x7f, 0x4a, 0x42, 0x05, 0x08, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xfc, 0xf8, 0x50, 0xf0, 0x50,
-+ 0xf0, 0xfc, 0x48, 0x78, 0xc0, 0x7c, 0x00, 0x00,
-+ 0x01, 0x0f, 0x71, 0x55, 0x54, 0x5d, 0x55, 0x55,
-+ 0x5d, 0x75, 0x50, 0x45, 0x04, 0x08, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xd0, 0x14, 0xd8, 0x50, 0x54,
-+ 0xd4, 0x4c, 0x00, 0x48, 0xa4, 0xa4, 0x00, 0x00,
-+ 0x17, 0x13, 0x6a, 0x2b, 0x13, 0x2a, 0x7b, 0x13,
-+ 0x21, 0x3f, 0x27, 0x24, 0x27, 0x20, 0x00, 0x00,
-+ 0xf8, 0xa8, 0xb0, 0xb0, 0xa8, 0x28, 0xb8, 0xa0,
-+ 0x00, 0xf8, 0xc8, 0x48, 0xc8, 0x18, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4b, 0x4a, 0x4b, 0x4a, 0x4b,
-+ 0x4a, 0x7c, 0x4f, 0x43, 0x00, 0x07, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0xa8, 0xb8, 0xa8, 0xb8,
-+ 0xa8, 0xc4, 0xfc, 0x20, 0xe0, 0x18, 0x00, 0x00,
-+ 0x1e, 0x12, 0x1e, 0x3f, 0x20, 0x2f, 0x22, 0x3f,
-+ 0x29, 0x2f, 0x2f, 0x29, 0x3f, 0x41, 0x00, 0x00,
-+ 0x78, 0x48, 0x78, 0xfc, 0x20, 0xa0, 0x20, 0xfc,
-+ 0x48, 0xa8, 0x30, 0xb0, 0x48, 0x84, 0x00, 0x00,
-+ 0x1e, 0x12, 0x1e, 0x7f, 0x02, 0x1f, 0x1f, 0x13,
-+ 0x1f, 0x0c, 0x7e, 0x12, 0x1e, 0x12, 0x00, 0x00,
-+ 0xf0, 0x90, 0xf0, 0xfc, 0x00, 0xf0, 0x90, 0xf0,
-+ 0xf0, 0x60, 0xfc, 0x90, 0xf0, 0x90, 0x00, 0x00,
-+ 0x00, 0x07, 0x74, 0x5f, 0x55, 0x57, 0x57, 0x54,
-+ 0x57, 0x77, 0x54, 0x47, 0x07, 0x04, 0x00, 0x00,
-+ 0x18, 0xf0, 0x88, 0xfc, 0x28, 0xf8, 0x88, 0x88,
-+ 0xfc, 0xc8, 0x28, 0xa8, 0x88, 0x18, 0x00, 0x00,
-+ 0x00, 0x03, 0x79, 0x49, 0x49, 0x4b, 0x48, 0x4f,
-+ 0x4a, 0x7b, 0x4b, 0x42, 0x0f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x10, 0xf0, 0xf0, 0xf8, 0x10, 0xfc,
-+ 0xa8, 0xb8, 0xb8, 0xac, 0xf8, 0x88, 0x00, 0x00,
-+ 0x02, 0x02, 0x7f, 0x55, 0x55, 0x57, 0x5a, 0x52,
-+ 0x5f, 0x77, 0x56, 0x4a, 0x12, 0x02, 0x00, 0x00,
-+ 0x28, 0x28, 0xa8, 0x7c, 0x68, 0xa8, 0xbc, 0x28,
-+ 0xa8, 0x3c, 0xa8, 0xa8, 0x3c, 0x20, 0x00, 0x00,
-+ 0x02, 0x02, 0x7f, 0x52, 0x5f, 0x5a, 0x5f, 0x5a,
-+ 0x5f, 0x72, 0x5f, 0x42, 0x02, 0x02, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x7c, 0xd4, 0xfc, 0xd4, 0xfc,
-+ 0xa8, 0x7c, 0x88, 0x7c, 0x28, 0x18, 0x00, 0x00,
-+ 0x01, 0x0f, 0x73, 0x57, 0x52, 0x5f, 0x57, 0x5f,
-+ 0x53, 0x7e, 0x53, 0x4f, 0x01, 0x07, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xa0, 0xf8, 0xa8, 0xe8, 0xbc,
-+ 0xac, 0x44, 0xf0, 0xfc, 0x10, 0xf8, 0x00, 0x00,
-+ 0x00, 0x07, 0x75, 0x55, 0x57, 0x55, 0x55, 0x57,
-+ 0x55, 0x75, 0x57, 0x46, 0x05, 0x09, 0x00, 0x00,
-+ 0x30, 0x50, 0x48, 0xfc, 0xac, 0xf4, 0xfc, 0x00,
-+ 0x78, 0x48, 0x78, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x0f, 0x08, 0x7f, 0x5b, 0x5b, 0x5f, 0x5d, 0x5f,
-+ 0x5b, 0x7b, 0x4e, 0x0b, 0x10, 0x27, 0x00, 0x00,
-+ 0xf8, 0x08, 0xf8, 0x58, 0x58, 0xf8, 0x28, 0xf8,
-+ 0xf8, 0xe8, 0xa8, 0xe8, 0xa8, 0xf0, 0x00, 0x00,
-+ 0x03, 0x0e, 0x73, 0x5e, 0x53, 0x5c, 0x52, 0x5f,
-+ 0x55, 0x76, 0x57, 0x45, 0x06, 0x07, 0x00, 0x00,
-+ 0x80, 0x78, 0xa8, 0x28, 0xc8, 0x98, 0xf0, 0xfc,
-+ 0x28, 0xd8, 0xf8, 0x28, 0xd8, 0xf8, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x22, 0x22, 0x24, 0x2c, 0x34,
-+ 0x24, 0x24, 0x24, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x88, 0x98, 0xa8, 0xc8, 0x88,
-+ 0x98, 0x98, 0x78, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x22, 0x2c, 0x37, 0x20, 0x2f,
-+ 0x21, 0x21, 0x21, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x88, 0x68, 0xd8, 0x08, 0xe8,
-+ 0x28, 0x28, 0xc8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x29, 0x21, 0x2f, 0x21,
-+ 0x21, 0x22, 0x24, 0x28, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x98, 0x78, 0x08, 0xe8, 0x08,
-+ 0xe8, 0x28, 0x28, 0xc8, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x3f, 0x22, 0x27, 0x26, 0x2b,
-+ 0x32, 0x23, 0x22, 0x22, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xe8, 0x28, 0xe8,
-+ 0x28, 0xe8, 0x28, 0x68, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x2f, 0x21, 0x2f, 0x22, 0x3f,
-+ 0x27, 0x24, 0x27, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xe8, 0x08, 0xc8, 0x48, 0xf8,
-+ 0xc8, 0x48, 0xc8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x27, 0x21, 0x2f, 0x24, 0x22,
-+ 0x2f, 0x21, 0x27, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xc8, 0x08, 0xe8, 0x48, 0x88,
-+ 0xe8, 0x08, 0xc8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x29, 0x37, 0x22, 0x3f, 0x24, 0x2f,
-+ 0x34, 0x25, 0x24, 0x23, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0xd8, 0x88, 0xf8, 0x48, 0xe8,
-+ 0x58, 0x88, 0x28, 0xe8, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x20, 0x3f, 0x20, 0x2e, 0x2a,
-+ 0x2e, 0x23, 0x3c, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0xc8, 0xa8, 0xf8, 0x88, 0xa8, 0xa8,
-+ 0x58, 0x78, 0xb8, 0x18, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x27, 0x22, 0x2f, 0x27, 0x27,
-+ 0x27, 0x24, 0x2f, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xc8, 0x48, 0xe8, 0xc8, 0xc8,
-+ 0xe8, 0x48, 0xe8, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x27, 0x24, 0x2f, 0x28, 0x2f, 0x2f,
-+ 0x28, 0x2f, 0x26, 0x38, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0xc8, 0x48, 0xe8, 0x28, 0xe8, 0xe8,
-+ 0x28, 0xe8, 0x68, 0x18, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x2f, 0x27, 0x25, 0x27, 0x25,
-+ 0x27, 0x2f, 0x20, 0x2f, 0x22, 0x3f, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xe8, 0xc8, 0x48, 0xc8, 0x48,
-+ 0xe8, 0xe8, 0x48, 0xe8, 0x48, 0xf8, 0x00, 0x00,
-+ 0x00, 0x3f, 0x27, 0x24, 0x27, 0x21, 0x3f, 0x2f,
-+ 0x2b, 0x2a, 0x2b, 0x2f, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0xc8, 0x48, 0xc8, 0x08, 0xf8, 0xe8,
-+ 0xa8, 0xa8, 0xa8, 0xe8, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x09, 0x15, 0x25, 0x7f, 0x00,
-+ 0x1f, 0x17, 0x14, 0x17, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x20, 0x50, 0x90, 0xfc, 0x00,
-+ 0xf0, 0xd0, 0x50, 0xd0, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x2f, 0x2a, 0x2f, 0x3f, 0x27, 0x24,
-+ 0x27, 0x3e, 0x27, 0x2c, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0xe8, 0xa8, 0xe8, 0xf8, 0xc8, 0x48,
-+ 0xd8, 0xa8, 0x48, 0x38, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10,
-+ 0x14, 0x19, 0x61, 0x02, 0x04, 0x08, 0x00, 0x00,
-+ 0xc0, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0xa0,
-+ 0xa0, 0x20, 0x10, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x13, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10,
-+ 0x14, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x40, 0x60, 0x50, 0x48,
-+ 0x48, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x12, 0x7e, 0x12, 0x12, 0x12,
-+ 0x16, 0x1a, 0x62, 0x03, 0x02, 0x02, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0xf8, 0x08, 0x08, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x11, 0x7e, 0x12, 0x14, 0x10,
-+ 0x14, 0x18, 0x61, 0x01, 0x02, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x44, 0x48, 0x50, 0xc0,
-+ 0xa0, 0xa0, 0x10, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x10, 0x11, 0x11, 0x7d, 0x11, 0x11, 0x11,
-+ 0x15, 0x1a, 0x62, 0x04, 0x08, 0x00, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x00, 0x00, 0xfc, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x12, 0x7e, 0x12, 0x12, 0x12,
-+ 0x16, 0x1a, 0x62, 0x02, 0x0f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x13, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x11,
-+ 0x16, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x40, 0x60, 0xd0, 0x48,
-+ 0x44, 0x44, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x17, 0x7d, 0x11, 0x11, 0x11,
-+ 0x15, 0x19, 0x61, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0xfc, 0x10, 0x10, 0x10, 0xf0,
-+ 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x7f, 0x05, 0x3d, 0x05, 0x0d,
-+ 0x35, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0xfc, 0x48, 0x50, 0x60, 0x48,
-+ 0x38, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x08, 0x0b, 0x18, 0x28, 0x49, 0x09,
-+ 0x01, 0x1f, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x50, 0x48, 0x5c, 0xe0, 0x20, 0x10, 0x14, 0x0c,
-+ 0x04, 0xf0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x13, 0x12, 0x7e, 0x12, 0x13, 0x13,
-+ 0x16, 0x1a, 0x64, 0x04, 0x09, 0x16, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x48, 0x50, 0x40, 0xf8, 0x08,
-+ 0x90, 0x90, 0x60, 0x60, 0x90, 0x0c, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x11, 0x7d, 0x13, 0x15, 0x11,
-+ 0x15, 0x19, 0x61, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x90, 0x90, 0x90, 0x10, 0xfc, 0x10, 0x90, 0x50,
-+ 0x50, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x13, 0x7e, 0x17, 0x12, 0x12,
-+ 0x17, 0x1a, 0x62, 0x02, 0x02, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0xc8, 0x48, 0x48,
-+ 0xc8, 0x70, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x10, 0x13, 0x10, 0x7c, 0x11, 0x10, 0x10,
-+ 0x14, 0x18, 0x61, 0x00, 0x01, 0x06, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x50, 0x90, 0xa0, 0x68,
-+ 0x48, 0x90, 0x30, 0x48, 0x84, 0x04, 0x00, 0x00,
-+ 0x00, 0x13, 0x12, 0x12, 0x7f, 0x12, 0x12, 0x13,
-+ 0x16, 0x1a, 0x62, 0x02, 0x03, 0x0c, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x10, 0xf4,
-+ 0x44, 0x48, 0x30, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x10, 0x11, 0x12, 0x7c, 0x10, 0x11, 0x13,
-+ 0x15, 0x19, 0x61, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x80, 0xf8, 0x00, 0x00, 0x80, 0xfc, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x13, 0x10, 0x10, 0x7c, 0x13, 0x10, 0x10,
-+ 0x17, 0x18, 0x60, 0x00, 0x07, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x50, 0x88, 0xfc, 0x44, 0x40,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x10, 0x10, 0x13, 0x7c, 0x10, 0x10, 0x10,
-+ 0x17, 0x18, 0x61, 0x01, 0x02, 0x04, 0x00, 0x00,
-+ 0x08, 0x88, 0x90, 0xfc, 0x90, 0x90, 0x90, 0x90,
-+ 0xfc, 0x90, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x10, 0x7c, 0x13, 0x10, 0x13,
-+ 0x14, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x40, 0x40, 0xfc, 0x00, 0xfc,
-+ 0x40, 0x70, 0x48, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x13, 0x7c, 0x10, 0x11, 0x12,
-+ 0x10, 0x1f, 0x60, 0x00, 0x03, 0x0c, 0x00, 0x00,
-+ 0x40, 0x50, 0x88, 0xfc, 0x84, 0x80, 0xf8, 0x40,
-+ 0x40, 0xfc, 0xc0, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x10, 0x11, 0x16, 0x7f, 0x12, 0x12, 0x13,
-+ 0x16, 0x1a, 0x63, 0x02, 0x04, 0x08, 0x00, 0x00,
-+ 0x80, 0xf0, 0x20, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x10, 0x17, 0x10, 0x7f, 0x12, 0x12, 0x13,
-+ 0x16, 0x1a, 0x63, 0x02, 0x02, 0x02, 0x00, 0x00,
-+ 0x50, 0x48, 0xfc, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x00, 0x10, 0x13, 0x11, 0x7d, 0x12, 0x10, 0x10,
-+ 0x17, 0x19, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x30, 0xd0, 0x48, 0x44, 0x44, 0x10, 0x10,
-+ 0xfc, 0x10, 0x90, 0x90, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x10, 0x13, 0x11, 0x7c, 0x10, 0x13, 0x10,
-+ 0x17, 0x19, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x20, 0x44, 0xa4, 0x18, 0x90, 0xe0, 0x90, 0x10,
-+ 0xfc, 0x10, 0x90, 0x90, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x1e, 0x10, 0x1e, 0x12, 0x02,
-+ 0x7f, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0xf0, 0x10, 0xf0, 0x90, 0x80,
-+ 0xfc, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x11, 0x17, 0x11, 0x7c, 0x10, 0x10, 0x11,
-+ 0x15, 0x1b, 0x65, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0xa0, 0xa0, 0xa4, 0x28,
-+ 0x30, 0x20, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x10, 0x17, 0x11, 0x7d, 0x11, 0x12, 0x14,
-+ 0x10, 0x1f, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0x10, 0x98, 0x64, 0x44,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x13, 0x12, 0x12, 0x7e, 0x13, 0x12, 0x12,
-+ 0x13, 0x1e, 0x64, 0x04, 0x08, 0x11, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xa8, 0xa8, 0xb8, 0xa8, 0xa8,
-+ 0xb8, 0xa8, 0xa8, 0xc8, 0xc8, 0x98, 0x00, 0x00,
-+ 0x00, 0x17, 0x10, 0x13, 0x7e, 0x12, 0x13, 0x12,
-+ 0x14, 0x1b, 0x60, 0x00, 0x0f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xf8, 0xa8, 0xa8, 0xf8, 0x48,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x11, 0x11, 0x11, 0x7d, 0x11, 0x13, 0x12,
-+ 0x16, 0x1a, 0x62, 0x02, 0x02, 0x02, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x70, 0x50, 0x50, 0xf8, 0x08,
-+ 0xe8, 0xa8, 0xa8, 0xe8, 0x88, 0x18, 0x00, 0x00,
-+ 0x01, 0x11, 0x13, 0x15, 0x7d, 0x11, 0x11, 0x11,
-+ 0x17, 0x1a, 0x63, 0x05, 0x09, 0x02, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0xfc, 0x00, 0xf8, 0x48, 0x48, 0xb0, 0x00, 0x00,
-+ 0x08, 0x09, 0x11, 0x11, 0x30, 0x57, 0x10, 0x13,
-+ 0x14, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x40, 0xfc, 0xe0, 0x58,
-+ 0x44, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x13, 0x12, 0x7e, 0x13, 0x12, 0x13,
-+ 0x16, 0x1b, 0x62, 0x05, 0x05, 0x08, 0x00, 0x00,
-+ 0x40, 0x80, 0xf0, 0x10, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x00, 0xfc, 0xa4, 0x54, 0x54, 0x18, 0x00, 0x00,
-+ 0x08, 0x0c, 0x2a, 0x2a, 0x59, 0x14, 0x22, 0x3f,
-+ 0x21, 0x5f, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x20, 0x30, 0xa8, 0xa8, 0x60, 0x50, 0x88, 0xfc,
-+ 0x08, 0xf0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x09, 0x4a, 0x25, 0x21, 0x0f, 0x12, 0x23,
-+ 0x21, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x68, 0xfc, 0x68, 0xfc,
-+ 0x30, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x36, 0x22, 0x36, 0x22, 0x23, 0x3e, 0x2b,
-+ 0x08, 0x3e, 0x08, 0x08, 0x0e, 0x73, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0x94, 0x14, 0x0c, 0xf8,
-+ 0x88, 0x90, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x10, 0x17, 0x15, 0x7d, 0x15, 0x17, 0x15,
-+ 0x15, 0x1d, 0x67, 0x04, 0x00, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x10, 0x10,
-+ 0xfc, 0x90, 0x50, 0x50, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x13, 0x12, 0x12, 0x7f, 0x10, 0x17, 0x10,
-+ 0x14, 0x1c, 0x64, 0x04, 0x07, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xf8, 0x00, 0xfc, 0x40,
-+ 0x40, 0x78, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x7f, 0x3e, 0x2a, 0x3e, 0x2a, 0x3e, 0x7f,
-+ 0x0a, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x18, 0xe0, 0x80, 0xfc, 0x90, 0x90, 0x90, 0x10,
-+ 0x10, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x2a, 0x3e, 0x2b, 0x3e, 0x08, 0x3e,
-+ 0x0c, 0x71, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x50, 0x20, 0xfc, 0x28, 0x30, 0x20,
-+ 0x60, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x2f, 0x29, 0x2f, 0x79, 0x2f, 0x28, 0x2b,
-+ 0x2a, 0x3b, 0x6a, 0x0b, 0x0a, 0x08, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x78, 0x48, 0x78, 0x08, 0xe8,
-+ 0x28, 0xe8, 0x28, 0xe8, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0x17, 0x7c, 0x14, 0x17, 0x14,
-+ 0x16, 0x1e, 0x6b, 0x08, 0x1f, 0x00, 0x00, 0x00,
-+ 0x80, 0xf8, 0x80, 0xfc, 0xb8, 0xc8, 0x78, 0xa0,
-+ 0xa8, 0xa8, 0xb8, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x11, 0x17, 0x10, 0x7f, 0x12, 0x13, 0x13,
-+ 0x16, 0x1b, 0x60, 0x0f, 0x01, 0x00, 0x00, 0x00,
-+ 0x60, 0x10, 0xfc, 0xa0, 0xf8, 0xb8, 0x38, 0xf8,
-+ 0x08, 0xf8, 0x10, 0xfc, 0x10, 0xb0, 0x00, 0x00,
-+ 0x00, 0x10, 0x13, 0x12, 0x7f, 0x12, 0x13, 0x12,
-+ 0x17, 0x18, 0x6f, 0x00, 0x03, 0x0c, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0xe8, 0x58, 0xe8, 0xf8, 0xe8,
-+ 0x58, 0x40, 0xfc, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x17, 0x10, 0x13, 0x7e, 0x13, 0x10, 0x13,
-+ 0x17, 0x18, 0x63, 0x0d, 0x01, 0x06, 0x00, 0x00,
-+ 0x40, 0xfc, 0x00, 0xf8, 0xa8, 0xf8, 0x40, 0x58,
-+ 0x58, 0xc8, 0x28, 0x30, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x10, 0x17, 0x11, 0x7d, 0x12, 0x17, 0x10,
-+ 0x17, 0x1a, 0x62, 0x02, 0x03, 0x02, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x50, 0xd8, 0x64, 0xfc, 0x00,
-+ 0xf8, 0xe8, 0xa8, 0xe8, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x17, 0x11, 0x10, 0x7d, 0x10, 0x17, 0x10,
-+ 0x15, 0x1f, 0x61, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x10, 0xfc, 0x50, 0x48, 0xf8, 0x50, 0xfc, 0x50,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x29, 0x3a, 0x25, 0x25, 0x39,
-+ 0x21, 0x21, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x80, 0xfc, 0xf8, 0x20, 0xf8, 0xf8, 0x08, 0xf8,
-+ 0xf8, 0x18, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x7f, 0x10, 0x14, 0x65, 0x1a, 0x14, 0x7c,
-+ 0x09, 0x11, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x90, 0xfc, 0x90, 0xf8, 0xf8, 0x90,
-+ 0xfc, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x2f, 0x2e, 0x2f, 0x2f, 0x28, 0x2f,
-+ 0x2f, 0x49, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x98, 0x94, 0xfc, 0x90, 0xb0, 0xa8,
-+ 0xc8, 0x84, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x0e, 0x3f, 0x2d, 0x52, 0x2c, 0x1e, 0x73,
-+ 0x1e, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x50, 0x50, 0x20, 0x50, 0x88,
-+ 0x04, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x13, 0x10, 0x17, 0x7c, 0x13, 0x10, 0x17,
-+ 0x16, 0x1a, 0x67, 0x02, 0x0f, 0x00, 0x00, 0x00,
-+ 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8, 0x40, 0xfc,
-+ 0xa8, 0x94, 0xf8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x13, 0x12, 0x13, 0x7e, 0x12, 0x13, 0x12,
-+ 0x16, 0x1a, 0x62, 0x04, 0x04, 0x0b, 0x00, 0x00,
-+ 0x40, 0xfc, 0x90, 0xfc, 0x90, 0xf0, 0xfc, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0xf8, 0xc8, 0x04, 0x00, 0x00,
-+ 0x00, 0x0f, 0x09, 0x0f, 0x09, 0x0f, 0x3e, 0x2a,
-+ 0x3e, 0x2b, 0x3f, 0x1f, 0x01, 0x7f, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0xf8, 0xa8,
-+ 0xf8, 0xa8, 0xf8, 0xf0, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x13, 0x12, 0x12, 0x7e, 0x12, 0x12, 0x12,
-+ 0x17, 0x1a, 0x65, 0x05, 0x08, 0x13, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf8, 0xa8, 0xf8, 0xf8, 0x20, 0xf8,
-+ 0xfc, 0xe8, 0x74, 0xf8, 0x20, 0xfc, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x11, 0x7f, 0x10, 0x17, 0x14,
-+ 0x17, 0x1b, 0x61, 0x07, 0x00, 0x03, 0x00, 0x00,
-+ 0xf0, 0x10, 0xf0, 0xf0, 0xf8, 0x40, 0xfc, 0x48,
-+ 0x58, 0x58, 0xf0, 0xfc, 0x90, 0xf8, 0x00, 0x00,
-+ 0x00, 0x17, 0x13, 0x12, 0x7f, 0x10, 0x17, 0x13,
-+ 0x10, 0x1f, 0x61, 0x0f, 0x01, 0x06, 0x00, 0x00,
-+ 0x40, 0xfc, 0xb8, 0xa8, 0xb8, 0xa0, 0xfc, 0xf8,
-+ 0xa0, 0xfc, 0x48, 0x30, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x08, 0x3e, 0x14, 0x7f, 0x3e, 0x22, 0x3e, 0x3e,
-+ 0x26, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x80, 0xf8, 0xf8, 0x08, 0xf8, 0xf0, 0xb8, 0x9c,
-+ 0x7c, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x24, 0x24, 0x24, 0x3c, 0x27, 0x04, 0x04,
-+ 0x7c, 0x24, 0x24, 0x24, 0x47, 0x04, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x00, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x1f, 0x00, 0x3f, 0x22, 0x5e,
-+ 0x10, 0x1e, 0x12, 0x02, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x00, 0xfc, 0x88, 0xf0,
-+ 0x10, 0xf0, 0x90, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x3f, 0x01, 0x1f, 0x00, 0x3f, 0x20, 0x5f,
-+ 0x0f, 0x08, 0x0f, 0x04, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x08, 0xf0,
-+ 0xe0, 0x20, 0xe0, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x17, 0x10, 0x11, 0x7d, 0x12, 0x14, 0x13,
-+ 0x16, 0x1b, 0x62, 0x03, 0x02, 0x02, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0x50, 0x70, 0xc0, 0x3c, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x01, 0x3f, 0x01, 0x1f, 0x3f, 0x20, 0x5f, 0x02,
-+ 0x1e, 0x10, 0x1e, 0x02, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0xfc, 0x08, 0xf0, 0x80,
-+ 0xf0, 0x10, 0xf0, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x3f, 0x01, 0x1f, 0x00, 0x7f, 0x0f, 0x01,
-+ 0x0f, 0x7f, 0x1e, 0x13, 0x1e, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0xe8, 0x00,
-+ 0xe0, 0xfc, 0x10, 0xfc, 0x90, 0x30, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x07, 0x04, 0x0c, 0x14, 0x22,
-+ 0x02, 0x01, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xe0, 0x20, 0x20, 0x40, 0x40,
-+ 0x80, 0x00, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x02, 0x22, 0x22, 0x17, 0x14, 0x08, 0x18, 0x24,
-+ 0x02, 0x01, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xe0, 0x20, 0x20, 0x40, 0x40,
-+ 0x80, 0x00, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x03, 0x0c, 0x7f, 0x12, 0x14, 0x0f, 0x08, 0x0f,
-+ 0x0f, 0x08, 0x0f, 0x3c, 0x03, 0x7c, 0x00, 0x00,
-+ 0xc0, 0x80, 0xf0, 0x90, 0x50, 0xe0, 0x20, 0xe0,
-+ 0xe0, 0x20, 0xe0, 0x40, 0x80, 0x78, 0x00, 0x00,
-+ 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x7f, 0x01, 0x03,
-+ 0x0c, 0x32, 0x01, 0x01, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xfc, 0x00, 0xf0,
-+ 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x1c, 0x1a, 0x2a, 0x49, 0x01,
-+ 0x06, 0x1a, 0x01, 0x01, 0x06, 0x38, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x70, 0x70, 0xa8, 0x24, 0xf0,
-+ 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x2a, 0x3e, 0x2b, 0x3e, 0x08, 0x7e,
-+ 0x1c, 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0x50, 0x20, 0x50, 0x9c,
-+ 0x24, 0x68, 0x98, 0x10, 0x20, 0xc0, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x1f, 0x01, 0x01, 0x01, 0x7f,
-+ 0x01, 0x03, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf0, 0x10, 0x10, 0x10, 0xfc,
-+ 0x00, 0x00, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x01, 0x1f, 0x01, 0x01, 0x01, 0x7f, 0x03,
-+ 0x02, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00,
-+ 0x80, 0x80, 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x7f, 0x02, 0x04, 0x19, 0x61,
-+ 0x01, 0x1f, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x80, 0x40, 0x30, 0x0c,
-+ 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x02, 0x04, 0x1f, 0x60, 0x1f,
-+ 0x02, 0x03, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x80, 0x40, 0xf0, 0x0c, 0xf0,
-+ 0x00, 0xe0, 0x20, 0x40, 0x40, 0x80, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x09, 0x09, 0x09, 0x15, 0x15,
-+ 0x23, 0x02, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x20, 0x20, 0x20, 0x50, 0x48,
-+ 0x88, 0x80, 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x08, 0x04, 0x04, 0x7f, 0x00,
-+ 0x1f, 0x11, 0x11, 0x1f, 0x11, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x20, 0x20, 0x40, 0xfc, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x02, 0x12, 0x12, 0x24, 0x09,
-+ 0x01, 0x7f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x40, 0x50, 0x48, 0x48, 0xc0,
-+ 0x00, 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x01, 0x03, 0x0c, 0x70, 0x1f, 0x12, 0x12, 0x14,
-+ 0x11, 0x01, 0x7f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0xe0, 0x40, 0x80, 0xf0, 0x90, 0xb0, 0x70,
-+ 0x10, 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x02, 0x05, 0x19, 0x6f, 0x01,
-+ 0x1f, 0x01, 0x0f, 0x01, 0x3f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x80, 0x40, 0x30, 0xec, 0x00,
-+ 0xf0, 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x11, 0x22, 0x0e, 0x01, 0x03,
-+ 0x1f, 0x01, 0x7f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x30, 0xe0, 0x10, 0x08, 0x48, 0x40, 0xa0, 0x10,
-+ 0xf0, 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x24, 0x24, 0x3c, 0x05, 0x7c, 0x24, 0x24, 0x45,
-+ 0x01, 0x7f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0x00,
-+ 0x00, 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x02, 0x02, 0x7f, 0x09, 0x1f, 0x61, 0x1f, 0x02,
-+ 0x0f, 0x74, 0x07, 0x04, 0x07, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x20, 0xf0, 0x4c, 0xf8, 0x40,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x07, 0x10, 0x2f, 0x42, 0x1f, 0x12, 0x14, 0x1f,
-+ 0x10, 0x1f, 0x01, 0x7f, 0x0c, 0x70, 0x00, 0x00,
-+ 0xe0, 0x20, 0xf0, 0x8c, 0xf0, 0xb0, 0x70, 0xf0,
-+ 0x10, 0xf0, 0x00, 0xfc, 0x60, 0x1c, 0x00, 0x00,
-+ 0x02, 0x04, 0x1f, 0x13, 0x15, 0x13, 0x1f, 0x13,
-+ 0x15, 0x01, 0x7f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x90, 0x50, 0x90, 0xf0, 0x90,
-+ 0x50, 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x24, 0x24, 0x3f, 0x25, 0x04, 0x7f, 0x25, 0x24,
-+ 0x44, 0x01, 0x7f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x40, 0xf8, 0x50, 0x20, 0xd0, 0xfc, 0x10, 0x90,
-+ 0x30, 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x02, 0x0c, 0x7f, 0x13, 0x12,
-+ 0x13, 0x17, 0x15, 0x17, 0x10, 0x0f, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x40, 0x30, 0xfc, 0xe0, 0x20,
-+ 0xe0, 0x70, 0x50, 0x70, 0x00, 0xf8, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7e, 0x12, 0x13, 0x12,
-+ 0x3e, 0x24, 0x06, 0x0a, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7e, 0x13, 0x12, 0x12,
-+ 0x3c, 0x24, 0x06, 0x0a, 0x10, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x88, 0x08, 0x88, 0x48,
-+ 0x48, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x04, 0x24, 0x24, 0x24, 0x3f, 0x24, 0x04, 0x7c,
-+ 0x15, 0x15, 0x14, 0x24, 0x25, 0x46, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x90, 0x90, 0x90,
-+ 0x10, 0xa0, 0x60, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x10, 0x17, 0x30, 0x50, 0x17,
-+ 0x11, 0x11, 0x13, 0x10, 0x10, 0x17, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x80, 0x80, 0xfc,
-+ 0x10, 0x10, 0xe0, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x12, 0x12, 0x31, 0x50, 0x17,
-+ 0x11, 0x11, 0x13, 0x10, 0x10, 0x17, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x00, 0x00, 0xf8, 0x80, 0xfc,
-+ 0x10, 0x10, 0xe0, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x11, 0x7d, 0x25, 0x25, 0x25,
-+ 0x79, 0x49, 0x0d, 0x15, 0x21, 0x46, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x24, 0x24, 0xe8, 0x30, 0x20,
-+ 0x20, 0x20, 0x20, 0x64, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7e, 0x12, 0x12, 0x12,
-+ 0x3c, 0x24, 0x06, 0x0a, 0x13, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88,
-+ 0x88, 0xf8, 0x88, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7e, 0x12, 0x13, 0x12,
-+ 0x3e, 0x24, 0x06, 0x0b, 0x11, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xc8, 0xa8, 0xa8, 0xfc, 0x88,
-+ 0xc8, 0xa8, 0xa8, 0xfc, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x08, 0x7e, 0x12, 0x12, 0x12,
-+ 0x3d, 0x24, 0x06, 0x08, 0x11, 0x26, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0x28, 0xf8, 0xa0,
-+ 0xfc, 0x24, 0x78, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x04, 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x02,
-+ 0x7f, 0x04, 0x0f, 0x11, 0x06, 0x38, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x00,
-+ 0xfc, 0x40, 0x40, 0xc0, 0x20, 0x10, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x08, 0x7e, 0x12, 0x13, 0x12,
-+ 0x3c, 0x24, 0x06, 0x0b, 0x11, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x90, 0x90, 0x90, 0x90, 0xfc, 0x90,
-+ 0x90, 0x90, 0x90, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x11, 0x7d, 0x27, 0x25, 0x25,
-+ 0x79, 0x49, 0x0d, 0x15, 0x21, 0x41, 0x00, 0x00,
-+ 0x80, 0x8c, 0xf0, 0x10, 0x10, 0x10, 0x10, 0xfc,
-+ 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x12, 0x11, 0x7d, 0x24, 0x24, 0x25,
-+ 0x7a, 0x48, 0x0d, 0x15, 0x22, 0x44, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xa8, 0xa8, 0xb0, 0xa0, 0xb0, 0xa8,
-+ 0xa8, 0xa0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x10, 0x7c, 0x27, 0x24, 0x24,
-+ 0x78, 0x4b, 0x0c, 0x14, 0x20, 0x41, 0x00, 0x00,
-+ 0x60, 0xa8, 0xa4, 0xa4, 0xa0, 0xfc, 0xa8, 0xa8,
-+ 0xd8, 0x90, 0x94, 0xac, 0xcc, 0x84, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x11, 0x7d, 0x24, 0x25, 0x25,
-+ 0x75, 0x49, 0x0d, 0x15, 0x25, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x00, 0xf8, 0x08,
-+ 0xf8, 0x08, 0xf8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x49, 0x29, 0x22, 0x0c, 0x10, 0x20, 0x27,
-+ 0x02, 0x7f, 0x04, 0x0f, 0x03, 0x3c, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x54, 0xd4, 0x60, 0xc0, 0x00,
-+ 0x00, 0xfc, 0x40, 0x80, 0x60, 0x10, 0x00, 0x00,
-+ 0x10, 0x17, 0x12, 0x12, 0x7f, 0x2a, 0x2a, 0x2f,
-+ 0x2a, 0x72, 0x12, 0x1c, 0x27, 0x48, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xa8, 0xb0, 0xb0, 0xa8, 0xa8,
-+ 0xa4, 0xa4, 0xa4, 0xb8, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7e, 0x12, 0x12, 0x13,
-+ 0x3c, 0x04, 0x06, 0x0a, 0x10, 0x20, 0x00, 0x00,
-+ 0x20, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0x00, 0xfc,
-+ 0x40, 0x78, 0x88, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7e, 0x12, 0x12, 0x12,
-+ 0x3c, 0x05, 0x06, 0x0a, 0x10, 0x23, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xf8, 0xa8, 0xa8, 0xf8,
-+ 0x20, 0xfc, 0x24, 0x44, 0x84, 0x18, 0x00, 0x00,
-+ 0x10, 0x17, 0x15, 0x15, 0x7e, 0x2e, 0x2d, 0x2d,
-+ 0x75, 0x55, 0x1f, 0x2c, 0x24, 0x44, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0x08, 0xe8, 0xa8, 0xa8, 0xa8,
-+ 0xe8, 0xa8, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x11, 0x7e, 0x24, 0x25, 0x24,
-+ 0x78, 0x08, 0x0c, 0x10, 0x27, 0x40, 0x00, 0x00,
-+ 0x08, 0x30, 0xc8, 0x24, 0x24, 0x18, 0xe0, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x11, 0x7e, 0x24, 0x24, 0x25,
-+ 0x6b, 0x18, 0x0c, 0x14, 0x21, 0x42, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x04, 0x88, 0xb8, 0xe8, 0x68,
-+ 0x68, 0xf0, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x10, 0x17, 0x12, 0x12, 0x7b, 0x2a, 0x2a, 0x2b,
-+ 0x6a, 0x12, 0x13, 0x1c, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xf8, 0xc8, 0xc8, 0xa8,
-+ 0xb0, 0x90, 0xb0, 0xa8, 0xc8, 0x84, 0x00, 0x00,
-+ 0x00, 0x7f, 0x12, 0x1e, 0x12, 0x1e, 0x12, 0x7f,
-+ 0x02, 0x7f, 0x04, 0x0f, 0x03, 0x3c, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x88, 0x50, 0x20, 0xd0, 0x0c,
-+ 0x00, 0xfc, 0x40, 0x80, 0x60, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x7e, 0x12, 0x12, 0x12,
-+ 0x3a, 0x24, 0x07, 0x0a, 0x10, 0x20, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0xa8, 0xf8, 0xa8, 0xa8, 0xf8,
-+ 0x50, 0x90, 0xfc, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x1c, 0x1a, 0x2a, 0x49, 0x08,
-+ 0x02, 0x7f, 0x04, 0x0f, 0x03, 0x3c, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x70, 0x70, 0xa8, 0x24, 0x20,
-+ 0x00, 0xfc, 0x40, 0x80, 0x60, 0x10, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x12, 0x7f, 0x2a, 0x2a, 0x2a,
-+ 0x6a, 0x12, 0x1a, 0x14, 0x24, 0x48, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x00, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x11, 0x7d, 0x25, 0x25, 0x24,
-+ 0x6b, 0x1a, 0x0e, 0x12, 0x2f, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x68, 0x98, 0x08, 0xf8, 0x00,
-+ 0xf8, 0xa8, 0xa8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x08, 0x7e, 0x13, 0x12, 0x12,
-+ 0x3c, 0x24, 0x06, 0x0b, 0x10, 0x20, 0x00, 0x00,
-+ 0x50, 0xfc, 0x50, 0xf8, 0x50, 0xfc, 0x20, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0xfc, 0x88, 0x98, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x10, 0x7f, 0x2a, 0x2a, 0x2b,
-+ 0x29, 0x72, 0x11, 0x1a, 0x20, 0x43, 0x00, 0x00,
-+ 0x00, 0xb8, 0x88, 0x88, 0xb8, 0x20, 0x20, 0xb8,
-+ 0x98, 0xa8, 0x98, 0xa8, 0x88, 0x30, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x12, 0x7b, 0x2a, 0x2a, 0x2b,
-+ 0x28, 0x73, 0x11, 0x18, 0x20, 0x47, 0x00, 0x00,
-+ 0xc0, 0x58, 0x48, 0x48, 0x58, 0x48, 0x48, 0xf8,
-+ 0x40, 0xf8, 0x10, 0xa0, 0xe0, 0x1c, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x11, 0x7d, 0x25, 0x25, 0x25,
-+ 0x75, 0x08, 0x0d, 0x16, 0x22, 0x44, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0xf8, 0x20, 0xf8, 0x20,
-+ 0xfc, 0x54, 0x2c, 0xac, 0x84, 0x18, 0x00, 0x00,
-+ 0x10, 0x11, 0x10, 0x10, 0x7c, 0x27, 0x24, 0x24,
-+ 0x78, 0x08, 0x0d, 0x16, 0x22, 0x44, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xb8, 0xa0, 0xfc, 0x80, 0xf8,
-+ 0x80, 0xfc, 0x54, 0xac, 0xac, 0x18, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x12, 0x7a, 0x2a, 0x2a, 0x2b,
-+ 0x2b, 0x73, 0x13, 0x1a, 0x23, 0x42, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x90, 0xf0, 0x00, 0xf8,
-+ 0x68, 0x68, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x12, 0x11, 0x13, 0x7a, 0x2d, 0x29, 0x29,
-+ 0x28, 0x73, 0x1a, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x40, 0x48, 0x50, 0xfc, 0x08, 0xf0, 0x10, 0xf0,
-+ 0x40, 0xf8, 0x48, 0x48, 0x70, 0x40, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x17, 0x79, 0x2f, 0x2d, 0x2d,
-+ 0x2f, 0x73, 0x13, 0x1d, 0x29, 0x41, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0xd0, 0x3c, 0xe8, 0x68, 0x68,
-+ 0xd8, 0x98, 0x50, 0x58, 0x28, 0x44, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x13, 0x7a, 0x2a, 0x2b, 0x28,
-+ 0x29, 0x70, 0x17, 0x19, 0x22, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xf8, 0xa8, 0xa8, 0xf8, 0x00,
-+ 0xf0, 0x00, 0xfc, 0x50, 0x48, 0xc0, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x13, 0x7a, 0x2b, 0x2a, 0x2a,
-+ 0x2a, 0x72, 0x12, 0x1a, 0x22, 0x43, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0xa8, 0xb8, 0x08, 0xe8,
-+ 0xa8, 0xe8, 0xa8, 0xe8, 0xa8, 0x78, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x13, 0x7a, 0x2b, 0x2a, 0x2a,
-+ 0x2b, 0x72, 0x12, 0x1b, 0x22, 0x42, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0xa8, 0xb8, 0x48, 0x48,
-+ 0xf8, 0xe8, 0xd8, 0x58, 0x48, 0x58, 0x00, 0x00,
-+ 0x10, 0x11, 0x10, 0x13, 0x7c, 0x25, 0x26, 0x24,
-+ 0x7b, 0x0a, 0x0e, 0x12, 0x22, 0x42, 0x00, 0x00,
-+ 0x18, 0xe0, 0x40, 0xf8, 0xa0, 0xf0, 0xa8, 0xe4,
-+ 0xf8, 0x08, 0xe8, 0xa8, 0xe8, 0x98, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x13, 0x7c, 0x2b, 0x2a, 0x2b,
-+ 0x2a, 0x73, 0x18, 0x17, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0x00, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x21, 0x3e, 0x32, 0x5e,
-+ 0x02, 0x7f, 0x04, 0x0f, 0x03, 0x3c, 0x00, 0x00,
-+ 0x20, 0xf8, 0x50, 0x50, 0xfc, 0x20, 0xf8, 0x20,
-+ 0x20, 0xfc, 0x40, 0x80, 0x60, 0x10, 0x00, 0x00,
-+ 0x01, 0x7d, 0x55, 0x55, 0x7f, 0x56, 0x7e, 0x12,
-+ 0x7f, 0x15, 0x15, 0x26, 0x26, 0x4c, 0x00, 0x00,
-+ 0x00, 0x7c, 0x54, 0x54, 0xfc, 0xd4, 0xfc, 0x90,
-+ 0xfc, 0x14, 0x94, 0xa4, 0x24, 0x4c, 0x00, 0x00,
-+ 0x10, 0x17, 0x15, 0x15, 0x7f, 0x2d, 0x2f, 0x29,
-+ 0x2f, 0x71, 0x12, 0x1a, 0x24, 0x48, 0x00, 0x00,
-+ 0x08, 0xc8, 0x48, 0x48, 0xfc, 0x54, 0xd4, 0x14,
-+ 0xd4, 0x78, 0x48, 0x48, 0x54, 0xe4, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x13, 0x7d, 0x26, 0x24, 0x27,
-+ 0x24, 0x78, 0x08, 0x14, 0x20, 0x43, 0x00, 0x00,
-+ 0x40, 0xfc, 0x08, 0xf8, 0x50, 0x60, 0xf8, 0x88,
-+ 0xf8, 0xf8, 0x88, 0xf8, 0xc8, 0x04, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x11, 0x7d, 0x25, 0x25, 0x27,
-+ 0x7a, 0x0b, 0x0f, 0x17, 0x21, 0x46, 0x00, 0x00,
-+ 0x40, 0xf0, 0x10, 0xf0, 0xf0, 0x10, 0xf0, 0xf8,
-+ 0x48, 0xf8, 0xf8, 0xfc, 0x10, 0x10, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x11, 0x7f, 0x2d, 0x2d, 0x2f,
-+ 0x2b, 0x73, 0x15, 0x19, 0x29, 0x41, 0x00, 0x00,
-+ 0x00, 0x3c, 0xd4, 0x14, 0xec, 0x7c, 0x64, 0xfc,
-+ 0x24, 0xbc, 0x64, 0x3c, 0x18, 0x64, 0x00, 0x00,
-+ 0x10, 0x17, 0x13, 0x12, 0x7b, 0x28, 0x2b, 0x29,
-+ 0x28, 0x77, 0x11, 0x1f, 0x29, 0x43, 0x00, 0x00,
-+ 0x40, 0xfc, 0xb8, 0xa8, 0xb8, 0xa0, 0xf8, 0xf0,
-+ 0xa0, 0xfc, 0xc8, 0x30, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x12, 0x12, 0x13, 0x15, 0x78, 0x2f, 0x2a, 0x2e,
-+ 0x2a, 0x76, 0x12, 0x1e, 0x23, 0x4e, 0x00, 0x00,
-+ 0xa0, 0xb0, 0xe8, 0x68, 0x20, 0xfc, 0xa0, 0xe8,
-+ 0xa8, 0xd0, 0xd4, 0xac, 0xcc, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x13, 0x7b, 0x2d, 0x29, 0x29,
-+ 0x2f, 0x73, 0x13, 0x1d, 0x29, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xfc, 0x58, 0x50, 0x78, 0x48,
-+ 0xf8, 0x48, 0xf8, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x00, 0x1f, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
-+ 0x0f, 0x71, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xf0, 0x20, 0x40, 0x80, 0x00, 0x30, 0xc0,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x04, 0x04, 0x08, 0x08, 0x1f, 0x20,
-+ 0x40, 0x01, 0x7f, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xc0, 0x40, 0x78, 0x08, 0x08, 0xe8, 0x70,
-+ 0x80, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x1e, 0x11, 0x11, 0x2f, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x30, 0xe0, 0x10, 0x08, 0x08, 0xe0, 0x40, 0x80,
-+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x3f, 0x20, 0x4f, 0x00,
-+ 0x00, 0x7f, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x08, 0xe0, 0x40,
-+ 0x80, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x7f, 0x12, 0x12, 0x3c, 0x06, 0x19, 0x6f,
-+ 0x00, 0x01, 0x7f, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x50, 0x20, 0xd0, 0x0c, 0xe0,
-+ 0xc0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x7c, 0x07, 0x08, 0x0a, 0x11, 0x10, 0x14,
-+ 0x18, 0x70, 0x11, 0x10, 0x11, 0x36, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x50, 0x90, 0xa0, 0x68,
-+ 0x48, 0x90, 0x30, 0x48, 0x84, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x00, 0x3f, 0x22, 0x3f, 0x00,
-+ 0x3e, 0x04, 0x0e, 0x78, 0x09, 0x1a, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf0, 0x50, 0x50, 0xd0,
-+ 0x50, 0x70, 0xb4, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x08, 0x04, 0x7f, 0x0a, 0x34, 0x0a, 0x3f, 0x01,
-+ 0x1f, 0x00, 0x01, 0x7f, 0x01, 0x03, 0x00, 0x00,
-+ 0x20, 0x40, 0xfc, 0x28, 0xd0, 0x28, 0xfc, 0x04,
-+ 0xf0, 0xc0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x37, 0x2d, 0x2d, 0x3f, 0x3f, 0x2d,
-+ 0x2d, 0x2d, 0x7d, 0x16, 0x14, 0x24, 0x00, 0x00,
-+ 0x04, 0x78, 0x58, 0x54, 0x94, 0x00, 0x7c, 0x08,
-+ 0x10, 0xfc, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x04, 0x1a, 0x11, 0x1e, 0x12, 0x1d, 0x12, 0x3f,
-+ 0x20, 0x4f, 0x00, 0x3f, 0x01, 0x03, 0x00, 0x00,
-+ 0x80, 0xf0, 0x10, 0xf0, 0x90, 0x70, 0x90, 0xfc,
-+ 0x08, 0xe0, 0xc0, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x04, 0x02, 0x03, 0x0c, 0x77,
-+ 0x00, 0x01, 0x7f, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x40, 0x80, 0x80, 0x60, 0xdc,
-+ 0x80, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3d, 0x04, 0x0b, 0x0b, 0x15, 0x10, 0x1f,
-+ 0x70, 0x13, 0x12, 0x12, 0x12, 0x32, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xfc, 0x58, 0x50, 0x40, 0xfc,
-+ 0x80, 0xf8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x01, 0x01, 0x3f, 0x20, 0x20,
-+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x04, 0x08,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x22, 0x42, 0x02, 0x02,
-+ 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x04, 0x08, 0x00, 0x10, 0x60,
-+ 0x80, 0x00, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x3f, 0x51, 0x1f, 0x10,
-+ 0x10, 0x1f, 0x11, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x04, 0xf8, 0x00, 0xf0, 0x10,
-+ 0x10, 0xf0, 0x10, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x3f, 0x20, 0x5f, 0x10, 0x17, 0x10, 0x1f,
-+ 0x12, 0x12, 0x12, 0x22, 0x23, 0x4c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf8, 0x00, 0xf0, 0x00, 0xfc,
-+ 0x80, 0x48, 0x50, 0x20, 0x90, 0x0c, 0x00, 0x00,
-+ 0x01, 0x3f, 0x22, 0x47, 0x18, 0x7f, 0x11, 0x11,
-+ 0x1f, 0x12, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xc0, 0x80, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x90, 0xa0, 0x94, 0x84, 0x7c, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x20, 0x3e, 0x40, 0x7f, 0x14,
-+ 0x14, 0x14, 0x14, 0x25, 0x24, 0x43, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x44, 0x78, 0x40, 0xf8, 0x88,
-+ 0x50, 0x30, 0x70, 0x88, 0x04, 0xfc, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x24, 0x44, 0x08, 0x0f, 0x18,
-+ 0x2f, 0x48, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0x40, 0x80, 0xf8, 0x80,
-+ 0xf0, 0x80, 0xf0, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x3f, 0x20, 0x4f, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x00, 0x7f, 0x11, 0x19, 0x27, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xe0, 0x20, 0xe0, 0x20, 0xe0,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x24, 0x64, 0x25, 0x3c, 0x27,
-+ 0x04, 0x7c, 0x15, 0x16, 0x24, 0x44, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x48, 0x40, 0xf8, 0x40, 0xfc,
-+ 0xe0, 0xd0, 0x50, 0x48, 0x44, 0xc0, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x24, 0x65, 0x24, 0x3d, 0x24,
-+ 0x07, 0x7c, 0x15, 0x15, 0x25, 0x45, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x08, 0xf8, 0x40, 0xf0, 0x90,
-+ 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x3f, 0x27, 0x45, 0x7f, 0x09, 0x0f, 0x0f,
-+ 0x08, 0x0f, 0x0f, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0xe8, 0x20, 0xfc, 0x40, 0xc0, 0xe0,
-+ 0x20, 0xe0, 0xe0, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x01, 0x3f, 0x25, 0x64, 0x27, 0x3c, 0x25, 0x07,
-+ 0x7e, 0x15, 0x14, 0x14, 0x24, 0x47, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf8, 0x10, 0xfc, 0x10, 0xf0, 0xfc,
-+ 0x08, 0xf0, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x01, 0x3f, 0x24, 0x5f, 0x04, 0x0f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x01, 0x7f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xf0, 0x40, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x00, 0xfc, 0xc0, 0x38, 0x00, 0x00,
-+ 0x01, 0x3f, 0x20, 0x5e, 0x0a, 0x16, 0x0b, 0x12,
-+ 0x0c, 0x77, 0x01, 0x06, 0x01, 0x0e, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf0, 0x50, 0xb0, 0x50, 0x80,
-+ 0xe0, 0x5c, 0xa0, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x01, 0x3f, 0x22, 0x5c, 0x10, 0x1e, 0x10, 0x1f,
-+ 0x08, 0x1f, 0x65, 0x12, 0x12, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x00, 0xf8, 0x48, 0xa8, 0xa8, 0x30, 0x00, 0x00,
-+ 0x01, 0x3f, 0x20, 0x5f, 0x12, 0x1f, 0x7f, 0x0f,
-+ 0x08, 0x0f, 0x0c, 0x74, 0x07, 0x18, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf0, 0x90, 0xf0, 0xfc, 0xe0,
-+ 0x20, 0xe0, 0x88, 0x50, 0x30, 0x0c, 0x00, 0x00,
-+ 0x01, 0x3f, 0x3e, 0x49, 0x3f, 0x0e, 0x38, 0x0f,
-+ 0x08, 0x0f, 0x0f, 0x08, 0x0f, 0x3c, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf8, 0x20, 0xfc, 0xa8, 0xf8, 0xe0,
-+ 0x20, 0xe0, 0xe0, 0x20, 0xe0, 0x38, 0x00, 0x00,
-+ 0x01, 0x3f, 0x3e, 0x48, 0x3f, 0x0e, 0x39, 0x0f,
-+ 0x08, 0x0f, 0x0f, 0x08, 0x0f, 0x3c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0xf8, 0xb0, 0xa8, 0x68, 0xe0,
-+ 0x20, 0xe0, 0xe0, 0x20, 0xe0, 0x38, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3f, 0x22, 0x22, 0x3e,
-+ 0x14, 0x14, 0x14, 0x24, 0x24, 0x43, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0xfc, 0x10, 0x90, 0x50,
-+ 0x50, 0x10, 0x10, 0x34, 0x04, 0xfc, 0x00, 0x00,
-+ 0x04, 0x24, 0x24, 0x24, 0x3d, 0x26, 0x04, 0x7c,
-+ 0x17, 0x15, 0x14, 0x24, 0x44, 0x04, 0x00, 0x00,
-+ 0x40, 0x78, 0x88, 0xd0, 0x30, 0xa0, 0xd0, 0x90,
-+ 0xfc, 0x10, 0x90, 0x90, 0x10, 0x30, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x1f, 0x11, 0x1f, 0x11, 0x1f,
-+ 0x01, 0x3f, 0x00, 0x7f, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf8, 0x48, 0xfc, 0x40, 0xc0, 0x00, 0x00,
-+ 0x0a, 0x4a, 0x2a, 0x2b, 0x7f, 0x11, 0x0a, 0x3f,
-+ 0x04, 0x3f, 0x04, 0x04, 0x07, 0x78, 0x00, 0x00,
-+ 0x08, 0x88, 0x88, 0x08, 0xfc, 0x08, 0x48, 0x28,
-+ 0x28, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x1f, 0x11, 0x21, 0x49, 0x09,
-+ 0x11, 0x11, 0x21, 0x41, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x20, 0x10,
-+ 0x10, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x12, 0x12, 0x3f, 0x12, 0x1e, 0x12, 0x1e, 0x13,
-+ 0x7f, 0x2c, 0x2d, 0x33, 0x20, 0x1f, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xb0, 0xa8, 0xa8, 0xa4, 0x2c,
-+ 0x68, 0x30, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x7f, 0x01, 0x02, 0x02,
-+ 0x02, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x14, 0x12, 0x12, 0x7e, 0x15, 0x14, 0x14,
-+ 0x14, 0x14, 0x14, 0x24, 0x24, 0x43, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0x50, 0x90, 0x20, 0x28, 0x48,
-+ 0x90, 0x10, 0x20, 0x44, 0x84, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x20, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x01, 0x7f, 0x01, 0x01, 0x1f,
-+ 0x01, 0x01, 0x02, 0x02, 0x04, 0x08, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xfc, 0x10, 0x10, 0xf0,
-+ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x14, 0x14, 0x14,
-+ 0x17, 0x14, 0x14, 0x24, 0x27, 0x5c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x48, 0x40, 0x44,
-+ 0xc8, 0x70, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x10, 0x14, 0x17,
-+ 0x14, 0x14, 0x15, 0x24, 0x27, 0x44, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x88, 0x80, 0x88, 0xf8,
-+ 0x88, 0x88, 0xe8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x14, 0x12, 0x12,
-+ 0x1f, 0x11, 0x12, 0x24, 0x28, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x88, 0x90, 0x90, 0xa0,
-+ 0xfc, 0xc0, 0xa0, 0x90, 0x8c, 0x80, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x17, 0x14, 0x17,
-+ 0x14, 0x17, 0x14, 0x27, 0x23, 0x4c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x30, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x12, 0x12, 0x15, 0x1a,
-+ 0x13, 0x14, 0x1c, 0x24, 0x24, 0x47, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x20, 0x20, 0xfc, 0x20,
-+ 0xf8, 0x88, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x12, 0x11, 0x17, 0x11,
-+ 0x11, 0x1f, 0x11, 0x22, 0x24, 0x48, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x10, 0x20, 0xf8, 0x20,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x13, 0x10, 0x1f, 0x10,
-+ 0x17, 0x11, 0x13, 0x3e, 0x22, 0x46, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0xe0, 0x40, 0xf8, 0x80,
-+ 0xfc, 0x08, 0x10, 0xfc, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x16, 0x16, 0x17, 0x15,
-+ 0x17, 0x17, 0x1d, 0x27, 0x21, 0x4f, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0xb0, 0xb0, 0xf0, 0x50,
-+ 0xf0, 0xf8, 0x48, 0xc8, 0x68, 0xf0, 0x00, 0x00,
-+ 0x01, 0x01, 0x21, 0x21, 0x21, 0x21, 0x21, 0x3f,
-+ 0x21, 0x22, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf8,
-+ 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x54, 0x54, 0x54, 0x54, 0x54,
-+ 0x54, 0x54, 0x7c, 0x44, 0x40, 0x00, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x84, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x01, 0x21, 0x21, 0x21, 0x3f, 0x20, 0x00, 0x7f,
-+ 0x02, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x70, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x55, 0x55, 0x56, 0x55, 0x54,
-+ 0x54, 0x54, 0x7c, 0x45, 0x41, 0x00, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x00, 0x00, 0xf0, 0x20,
-+ 0x40, 0x80, 0x80, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x01, 0x21, 0x3f, 0x00, 0x3f, 0x04, 0x04, 0x07,
-+ 0x04, 0x0a, 0x09, 0x10, 0x23, 0x4c, 0x00, 0x00,
-+ 0x00, 0x08, 0xf8, 0x00, 0xc0, 0x40, 0x40, 0xf0,
-+ 0x10, 0x20, 0x40, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x01, 0x21, 0x21, 0x3f, 0x21, 0x02, 0x04, 0x18,
-+ 0x67, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x08, 0xf8, 0x08, 0x80, 0x40, 0x30,
-+ 0xcc, 0x00, 0xc0, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x07, 0x04, 0x18, 0x6f, 0x02, 0x02, 0x0c, 0x30,
-+ 0x01, 0x21, 0x21, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0xc0, 0x40, 0x30, 0xec, 0x20, 0x20, 0x20, 0xc0,
-+ 0x00, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x1f, 0x00, 0x7f, 0x02, 0x3f,
-+ 0x04, 0x04, 0x0f, 0x08, 0x03, 0x3c, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0xf8,
-+ 0x40, 0x40, 0x80, 0xe0, 0x10, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x54, 0x55, 0x55, 0x55, 0x55,
-+ 0x55, 0x55, 0x7d, 0x45, 0x41, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0xf8, 0x48, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x55, 0x55, 0x55, 0x55, 0x55,
-+ 0x55, 0x55, 0x7d, 0x46, 0x43, 0x00, 0x00, 0x00,
-+ 0x18, 0xe0, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0x10, 0x50, 0x94, 0x0c, 0xec, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x55, 0x55, 0x55, 0x55, 0x55,
-+ 0x55, 0x55, 0x7d, 0x45, 0x41, 0x01, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0xf8, 0x08, 0x08, 0x08, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x55, 0x55, 0x56, 0x54, 0x57,
-+ 0x54, 0x54, 0x7c, 0x44, 0x40, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x50, 0x48, 0x48, 0x40, 0xfc,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x55, 0x55, 0x55, 0x55, 0x55,
-+ 0x55, 0x55, 0x7d, 0x45, 0x41, 0x06, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x28, 0x20, 0xfc,
-+ 0x20, 0x20, 0x10, 0x54, 0x8c, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x54, 0x57, 0x54, 0x54, 0x54,
-+ 0x57, 0x7c, 0x45, 0x41, 0x02, 0x04, 0x00, 0x00,
-+ 0x40, 0x40, 0x90, 0x98, 0xe4, 0x90, 0x90, 0x90,
-+ 0xfc, 0x90, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x54, 0x54, 0x54, 0x54, 0x55,
-+ 0x55, 0x55, 0x7d, 0x45, 0x41, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x21, 0x21, 0x3f, 0x21, 0x02, 0x04, 0x1f,
-+ 0x60, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x08, 0x08, 0xf8, 0x08, 0x80, 0x40, 0xf0,
-+ 0x0c, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x54, 0x54, 0x57, 0x54, 0x54,
-+ 0x57, 0x55, 0x7c, 0x44, 0x40, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x10, 0x10,
-+ 0xfc, 0x10, 0x90, 0x90, 0x10, 0x30, 0x00, 0x00,
-+ 0x01, 0x21, 0x3f, 0x20, 0x06, 0x38, 0x08, 0x7f,
-+ 0x08, 0x0e, 0x78, 0x08, 0x09, 0x18, 0x00, 0x00,
-+ 0x00, 0x08, 0xf8, 0x08, 0x50, 0x48, 0x40, 0xfc,
-+ 0x48, 0x48, 0x30, 0x74, 0x8c, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x55, 0x55, 0x55, 0x56, 0x56,
-+ 0x54, 0x54, 0x7c, 0x45, 0x42, 0x04, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x50, 0x50, 0x50, 0xe8, 0x44,
-+ 0x44, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x55, 0x55, 0x55, 0x55, 0x55,
-+ 0x57, 0x55, 0x7c, 0x44, 0x43, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x48, 0x40, 0x80, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x56, 0x54, 0x55, 0x55, 0x55,
-+ 0x55, 0x7d, 0x45, 0x41, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x44, 0x44, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x21, 0x3f, 0x01, 0x0f, 0x08, 0x0f, 0x0f,
-+ 0x08, 0x0f, 0x0f, 0x2a, 0x25, 0x40, 0x00, 0x00,
-+ 0x00, 0x08, 0xf8, 0x00, 0xe0, 0x20, 0xe0, 0xe0,
-+ 0x00, 0xfc, 0xf8, 0x88, 0x48, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x56, 0x54, 0x54, 0x54, 0x55,
-+ 0x57, 0x55, 0x7d, 0x45, 0x41, 0x01, 0x00, 0x00,
-+ 0xa0, 0x90, 0x08, 0x48, 0x40, 0xa0, 0xa0, 0x10,
-+ 0xf8, 0x14, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x21, 0x3f, 0x00, 0x3f, 0x09, 0x7f, 0x09,
-+ 0x09, 0x3f, 0x01, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x08, 0xf8, 0x00, 0xf8, 0x20, 0xfc, 0x20,
-+ 0x20, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x55, 0x55, 0x55, 0x55, 0x55,
-+ 0x55, 0x55, 0x7d, 0x46, 0x43, 0x04, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x21, 0x3f, 0x00, 0x3f, 0x24, 0x22, 0x3f,
-+ 0x21, 0x29, 0x29, 0x2f, 0x28, 0x20, 0x00, 0x00,
-+ 0x00, 0x08, 0xf8, 0x00, 0xf8, 0x48, 0x88, 0xf8,
-+ 0x08, 0x28, 0x28, 0xe8, 0x28, 0x18, 0x00, 0x00,
-+ 0x01, 0x21, 0x3f, 0x01, 0x3f, 0x08, 0x04, 0x7f,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x11, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0xf8, 0x00, 0xf8, 0x20, 0x40, 0xfc,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x01, 0x21, 0x21, 0x3f, 0x22, 0x04, 0x1f, 0x61,
-+ 0x1f, 0x09, 0x05, 0x05, 0x3f, 0x00, 0x00, 0x00,
-+ 0x00, 0x08, 0x08, 0xf8, 0x88, 0x40, 0xf0, 0x0c,
-+ 0xf0, 0x20, 0x20, 0x40, 0xf8, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x55, 0x55, 0x55, 0x55, 0x55,
-+ 0x55, 0x7e, 0x47, 0x45, 0x09, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x04, 0x04, 0xfc, 0x20, 0xa8, 0xa8,
-+ 0xf8, 0x20, 0x24, 0x24, 0xfc, 0x04, 0x00, 0x00,
-+ 0x01, 0x21, 0x3f, 0x20, 0x1f, 0x10, 0x1f, 0x10,
-+ 0x1f, 0x10, 0x1e, 0x10, 0x1c, 0x70, 0x00, 0x00,
-+ 0x00, 0x08, 0xf8, 0x08, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x98, 0xe0, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x01, 0x21, 0x21, 0x3f, 0x24, 0x04, 0x0f, 0x08,
-+ 0x1f, 0x28, 0x4f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x08, 0x08, 0xf8, 0x48, 0x80, 0xf8, 0x80,
-+ 0xf0, 0x80, 0xf0, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x55, 0x56, 0x55, 0x54, 0x57,
-+ 0x54, 0x55, 0x7c, 0x44, 0x40, 0x00, 0x00, 0x00,
-+ 0x18, 0xf0, 0x48, 0x24, 0x04, 0xf8, 0x48, 0xfc,
-+ 0x48, 0xf8, 0x48, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x10, 0x11, 0x10, 0x57, 0x54, 0x54, 0x55, 0x56,
-+ 0x54, 0x55, 0x7e, 0x44, 0x41, 0x0e, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xfc, 0xa0, 0xa4, 0x5c, 0x40,
-+ 0xf0, 0x10, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x01, 0x21, 0x21, 0x3f, 0x22, 0x04, 0x1f, 0x60,
-+ 0x1f, 0x12, 0x1f, 0x12, 0x12, 0x10, 0x00, 0x00,
-+ 0x00, 0x08, 0x08, 0xf8, 0x88, 0x40, 0xf0, 0x0c,
-+ 0xf0, 0x90, 0xf0, 0x90, 0x90, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x55, 0x57, 0x54, 0x57, 0x56,
-+ 0x56, 0x57, 0x7e, 0x46, 0x42, 0x02, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xf8, 0xa8,
-+ 0xa8, 0xf8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x01, 0x21, 0x21, 0x3f, 0x24, 0x24, 0x7f, 0x24,
-+ 0x25, 0x3c, 0x24, 0x24, 0x3d, 0x26, 0x00, 0x00,
-+ 0x00, 0x08, 0x08, 0xf8, 0x48, 0x40, 0x7c, 0xa8,
-+ 0x30, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0f, 0x00, 0x3e, 0x22, 0x3e,
-+ 0x22, 0x01, 0x21, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x00, 0xf8, 0x88, 0xf8,
-+ 0x88, 0x00, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x55, 0x55, 0x55, 0x55, 0x54,
-+ 0x57, 0x56, 0x7e, 0x47, 0x42, 0x02, 0x00, 0x00,
-+ 0x00, 0xf0, 0x50, 0xf0, 0x50, 0x50, 0xf0, 0x40,
-+ 0xf8, 0x68, 0x58, 0xf8, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x55, 0x55, 0x55, 0x55, 0x55,
-+ 0x55, 0x55, 0x7d, 0x46, 0x42, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0x28, 0xf8, 0x00, 0x78, 0x48,
-+ 0x78, 0x48, 0x78, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x01, 0x21, 0x3f, 0x02, 0x1f, 0x11, 0x1f, 0x11,
-+ 0x1f, 0x12, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x08, 0xf8, 0x00, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0xb0, 0xa8, 0xfc, 0x84, 0x7c, 0x00, 0x00,
-+ 0x01, 0x21, 0x3f, 0x04, 0x7f, 0x01, 0x1f, 0x01,
-+ 0x7f, 0x08, 0x0f, 0x11, 0x3f, 0x40, 0x00, 0x00,
-+ 0x00, 0x08, 0xf8, 0x40, 0xfc, 0x00, 0xf0, 0x00,
-+ 0xfc, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x54, 0x57, 0x56, 0x56, 0x57,
-+ 0x55, 0x56, 0x7d, 0x46, 0x40, 0x03, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x40, 0x40, 0xf8,
-+ 0x98, 0xe8, 0x98, 0xe8, 0x88, 0x30, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x56, 0x56, 0x56, 0x56, 0x57,
-+ 0x57, 0x57, 0x7f, 0x46, 0x43, 0x02, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x90, 0xf0, 0x00, 0xf8,
-+ 0x68, 0x68, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x21, 0x3f, 0x08, 0x7f, 0x08, 0x3e, 0x2a,
-+ 0x3e, 0x2a, 0x3e, 0x09, 0x7f, 0x0a, 0x00, 0x00,
-+ 0x00, 0x08, 0xf8, 0x08, 0x30, 0xc0, 0x80, 0xfc,
-+ 0x90, 0x90, 0x90, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x13, 0x11, 0x57, 0x54, 0x55, 0x55, 0x55,
-+ 0x55, 0x55, 0x7c, 0x47, 0x40, 0x00, 0x00, 0x00,
-+ 0x40, 0xf8, 0x20, 0xfc, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x57, 0x55, 0x57, 0x55, 0x55,
-+ 0x56, 0x7f, 0x44, 0x40, 0x01, 0x06, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xfc, 0x10, 0xb8, 0x10, 0xfc,
-+ 0x00, 0xfc, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x54, 0x55, 0x56, 0x55, 0x55,
-+ 0x55, 0x7d, 0x45, 0x40, 0x03, 0x00, 0x00, 0x00,
-+ 0xe0, 0x68, 0x50, 0x94, 0xf8, 0x08, 0xf4, 0x10,
-+ 0x10, 0xf0, 0x10, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x10, 0x13, 0x54, 0x55, 0x54, 0x57, 0x54,
-+ 0x57, 0x57, 0x7d, 0x47, 0x41, 0x03, 0x00, 0x00,
-+ 0x08, 0x90, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0xa8,
-+ 0x24, 0xfc, 0xa8, 0x14, 0x2c, 0xc4, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x54, 0x55, 0x57, 0x54, 0x57,
-+ 0x56, 0x7f, 0x45, 0x41, 0x02, 0x04, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xf8, 0x04, 0xb8,
-+ 0xa8, 0xb8, 0x10, 0x90, 0xa8, 0x44, 0x00, 0x00,
-+ 0x01, 0x21, 0x3f, 0x08, 0x2b, 0x17, 0x18, 0x2b,
-+ 0x4b, 0x18, 0x2b, 0x4a, 0x0b, 0x32, 0x00, 0x00,
-+ 0x00, 0x08, 0xf8, 0x18, 0x94, 0xd4, 0x7c, 0x90,
-+ 0x90, 0x10, 0xb0, 0xa8, 0xc8, 0x84, 0x00, 0x00,
-+ 0x01, 0x21, 0x3f, 0x00, 0x3c, 0x27, 0x28, 0x33,
-+ 0x29, 0x25, 0x25, 0x3b, 0x20, 0x27, 0x00, 0x00,
-+ 0x00, 0x08, 0xf8, 0x40, 0xf8, 0x90, 0x60, 0x9c,
-+ 0xf0, 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0x00, 0x00,
-+ 0x01, 0x21, 0x3f, 0x24, 0x38, 0x22, 0x1e, 0x21,
-+ 0x3e, 0x48, 0x7e, 0x08, 0x15, 0x62, 0x00, 0x00,
-+ 0x00, 0x08, 0xf8, 0x00, 0xf8, 0x50, 0x20, 0xfc,
-+ 0x28, 0xa0, 0xb8, 0xa0, 0x60, 0x3c, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x55, 0x55, 0x55, 0x55, 0x55,
-+ 0x55, 0x55, 0x7f, 0x44, 0x41, 0x02, 0x00, 0x00,
-+ 0x40, 0xd8, 0x68, 0x48, 0xf8, 0x28, 0x68, 0xf8,
-+ 0x68, 0x68, 0xfc, 0x90, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x54, 0x55, 0x55, 0x55, 0x57,
-+ 0x54, 0x57, 0x7d, 0x45, 0x40, 0x03, 0x00, 0x00,
-+ 0x70, 0xa0, 0xf8, 0x88, 0xf8, 0xb0, 0xe4, 0x5c,
-+ 0xe0, 0xf0, 0x50, 0xf4, 0xac, 0x1c, 0x00, 0x00,
-+ 0x01, 0x21, 0x3f, 0x0c, 0x39, 0x7f, 0x1d, 0x2b,
-+ 0x49, 0x7e, 0x14, 0x3c, 0x0d, 0x32, 0x00, 0x00,
-+ 0x00, 0x08, 0xf8, 0x40, 0xf0, 0x50, 0xf0, 0x50,
-+ 0xf0, 0xd0, 0xe8, 0xfc, 0x44, 0x3c, 0x00, 0x00,
-+ 0x21, 0x3f, 0x24, 0x3b, 0x1e, 0x5e, 0x52, 0x5e,
-+ 0x5e, 0x52, 0x5e, 0x3e, 0x14, 0x63, 0x00, 0x00,
-+ 0x08, 0xf8, 0x00, 0xfc, 0x20, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x88, 0xf8, 0x48, 0x84, 0x00, 0x00,
-+ 0x13, 0x1f, 0x68, 0x13, 0x2b, 0x7c, 0x3b, 0x56,
-+ 0x13, 0x01, 0x21, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0x90, 0xd8, 0x68, 0x90, 0xa8, 0x7c, 0xb8, 0xd4,
-+ 0x90, 0x00, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x21, 0x3f, 0x1e, 0x12, 0x1e, 0x3f, 0x2f, 0x24,
-+ 0x3f, 0x29, 0x2f, 0x2f, 0x3f, 0x41, 0x00, 0x00,
-+ 0x08, 0xf8, 0xf0, 0x90, 0xf0, 0xfc, 0x20, 0x20,
-+ 0xfc, 0x48, 0xb0, 0x90, 0x68, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x11, 0x11, 0x22, 0x44,
-+ 0x22, 0x11, 0x11, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x88, 0x88, 0x88, 0x88, 0x10, 0x10, 0x20, 0x40,
-+ 0x20, 0x10, 0x10, 0x88, 0x88, 0x88, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x09, 0x09, 0x09, 0x09, 0x0d,
-+ 0x13, 0x13, 0x21, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x20, 0x20, 0x20, 0x20, 0x60,
-+ 0x50, 0x88, 0x08, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x00, 0x20, 0x20, 0x3f, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x1f, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10,
-+ 0x00, 0x00, 0x04, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x17, 0x14, 0x14,
-+ 0x17, 0x14, 0x14, 0x24, 0x24, 0x43, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0xfc, 0x00, 0xf0, 0x90, 0x90,
-+ 0xf0, 0x10, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x10, 0x1e, 0x71, 0x01,
-+ 0x1f, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0xfc, 0x80, 0x64, 0x1c, 0x04,
-+ 0xf0, 0x10, 0x10, 0x10, 0xe0, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x00, 0x7f, 0x00, 0x0f, 0x00, 0x3f,
-+ 0x21, 0x5f, 0x11, 0x11, 0x11, 0x01, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xfc, 0x20, 0xe0, 0x00, 0xfc,
-+ 0x08, 0xf0, 0x10, 0x10, 0x60, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x55, 0x56, 0x54, 0x57,
-+ 0x54, 0x58, 0x50, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0x40, 0xfc,
-+ 0x40, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x12, 0x12, 0x3c, 0x06, 0x19,
-+ 0x7f, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x88, 0x50, 0x20, 0xd0, 0x0c,
-+ 0xf0, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00, 0x00,
-+ 0x01, 0x02, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x01,
-+ 0x3f, 0x21, 0x21, 0x21, 0x21, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00, 0x00,
-+ 0x0a, 0x0a, 0x7f, 0x0a, 0x0b, 0x10, 0x3f, 0x21,
-+ 0x5f, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xfc, 0xa0, 0xa8, 0x18, 0xfc, 0x08,
-+ 0xf0, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x55, 0x57, 0x55, 0x55,
-+ 0x55, 0x55, 0x59, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x90, 0x90, 0xa0, 0xfc, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x55, 0x55, 0x55, 0x55,
-+ 0x55, 0x55, 0x59, 0x12, 0x13, 0x14, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x00, 0xfc, 0x50, 0x58,
-+ 0xe8, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7f, 0x54, 0x55, 0x55, 0x55,
-+ 0x54, 0x55, 0x59, 0x17, 0x10, 0x10, 0x00, 0x00,
-+ 0x80, 0xf0, 0x90, 0xfc, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x20, 0xf8, 0x20, 0xfc, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x55, 0x55, 0x55, 0x55,
-+ 0x55, 0x55, 0x59, 0x10, 0x10, 0x13, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0x40, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x08, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7d, 0x55, 0x55, 0x55, 0x55,
-+ 0x54, 0x57, 0x58, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x40, 0xfc, 0x00, 0x90, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x57, 0x56, 0x57, 0x57,
-+ 0x57, 0x56, 0x5b, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x68, 0x58, 0xf8, 0x48, 0xd8, 0x58,
-+ 0xe8, 0x78, 0xb8, 0x58, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x55, 0x55, 0x57, 0x56,
-+ 0x57, 0x55, 0x58, 0x10, 0x10, 0x17, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xf8, 0xa8,
-+ 0xf8, 0xf0, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x7d, 0x55, 0x57, 0x54, 0x57,
-+ 0x56, 0x57, 0x5a, 0x13, 0x12, 0x10, 0x00, 0x00,
-+ 0xa0, 0xb0, 0xe8, 0x68, 0xa0, 0xfc, 0x20, 0xe8,
-+ 0x68, 0xd8, 0x50, 0xd4, 0x2c, 0x44, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7f, 0x55, 0x55, 0x55, 0x55,
-+ 0x55, 0x54, 0x5b, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x40, 0xf8, 0xa0, 0xfc, 0xf0, 0x50, 0xf0, 0x50,
-+ 0xf0, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x2a, 0x49, 0x7f, 0x5d, 0x55, 0x5d, 0x41,
-+ 0x3f, 0x21, 0x21, 0x21, 0x21, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0x88, 0x50, 0x30, 0xcc, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00, 0x00,
-+ 0x08, 0x3e, 0x09, 0x7e, 0x08, 0x3e, 0x0f, 0x71,
-+ 0x1f, 0x11, 0x11, 0x11, 0x11, 0x01, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x90, 0x50, 0x10, 0x30, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x7f, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x04, 0x04, 0x3f, 0x04, 0x04, 0x04, 0x7f,
-+ 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0xf8, 0x40, 0x40, 0x40, 0xfc,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x01, 0x01, 0x1a, 0x06, 0x01, 0x00,
-+ 0x00, 0x01, 0x02, 0x04, 0x3f, 0x00, 0x00, 0x00,
-+ 0x80, 0x80, 0x00, 0x10, 0x10, 0x20, 0x20, 0xc0,
-+ 0x80, 0x20, 0x10, 0x78, 0x84, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x1f, 0x16, 0x16, 0x1a, 0x12,
-+ 0x11, 0x17, 0x10, 0x21, 0x2f, 0x40, 0x00, 0x00,
-+ 0x80, 0xfc, 0x20, 0xfc, 0x68, 0xec, 0xec, 0xa0,
-+ 0x10, 0x20, 0xd0, 0x08, 0xfc, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x20, 0x20, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x12, 0x11, 0x1f, 0x10, 0x17,
-+ 0x10, 0x10, 0x1f, 0x20, 0x20, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x20, 0x40, 0xf8, 0x80, 0xf0,
-+ 0x80, 0x80, 0xfc, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x17, 0x14, 0x17, 0x14, 0x17,
-+ 0x14, 0x17, 0x13, 0x22, 0x24, 0x48, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0x88, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0x28, 0x88, 0x88, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x12, 0x12, 0x1f, 0x12, 0x13,
-+ 0x16, 0x16, 0x1a, 0x32, 0x22, 0x42, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x78, 0xc8, 0x48, 0x78,
-+ 0xc8, 0xf8, 0x48, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x13, 0x13, 0x13,
-+ 0x12, 0x13, 0x11, 0x27, 0x20, 0x4f, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0xfc, 0x80, 0xf0, 0xf0, 0xf0,
-+ 0x10, 0xf0, 0xf0, 0x20, 0xe0, 0x1c, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x12, 0x17, 0x15, 0x17, 0x15,
-+ 0x17, 0x14, 0x15, 0x26, 0x24, 0x43, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x78, 0x50, 0x50, 0x7c,
-+ 0x50, 0x10, 0x30, 0x34, 0xd4, 0x8c, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x12, 0x17, 0x15, 0x17, 0x15,
-+ 0x17, 0x14, 0x15, 0x26, 0x24, 0x43, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x70, 0x50, 0x54, 0x8c,
-+ 0xf8, 0x48, 0x50, 0x20, 0xd0, 0x8c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x17, 0x11, 0x16, 0x11, 0x16,
-+ 0x13, 0x1c, 0x13, 0x21, 0x20, 0x47, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0xf8, 0x98, 0xe8, 0x98, 0xe8,
-+ 0x70, 0xdc, 0x60, 0x90, 0x60, 0x80, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x1f, 0x13, 0x1f, 0x10, 0x17,
-+ 0x14, 0x17, 0x24, 0x27, 0x43, 0x0c, 0x00, 0x00,
-+ 0x80, 0xfc, 0x20, 0xf8, 0xe0, 0xfc, 0x80, 0xf0,
-+ 0x90, 0xf0, 0x90, 0xf0, 0x30, 0x08, 0x00, 0x00,
-+ 0x00, 0x1f, 0x15, 0x15, 0x1f, 0x15, 0x17, 0x15,
-+ 0x17, 0x15, 0x3f, 0x25, 0x44, 0x08, 0x00, 0x00,
-+ 0x80, 0xfc, 0x08, 0x70, 0xc0, 0x40, 0x7c, 0x50,
-+ 0x50, 0x50, 0xd0, 0x50, 0x90, 0x90, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x11, 0x17, 0x10, 0x17,
-+ 0x14, 0x17, 0x14, 0x23, 0x23, 0x4c, 0x00, 0x00,
-+ 0x80, 0xfc, 0x08, 0xc8, 0x08, 0xfc, 0x08, 0xc8,
-+ 0xa8, 0xa8, 0x88, 0x08, 0x88, 0x18, 0x00, 0x00,
-+ 0x00, 0x1f, 0x17, 0x14, 0x17, 0x14, 0x17, 0x17,
-+ 0x1f, 0x12, 0x14, 0x3b, 0x20, 0x5f, 0x00, 0x00,
-+ 0x80, 0xfc, 0xf0, 0x90, 0xf0, 0x90, 0xf0, 0xf0,
-+ 0xfc, 0x28, 0xb8, 0xe0, 0x80, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x17, 0x19, 0x16, 0x17, 0x19,
-+ 0x17, 0x14, 0x1f, 0x21, 0x21, 0x46, 0x00, 0x00,
-+ 0x80, 0xfc, 0x10, 0xd4, 0x24, 0x18, 0x7c, 0x50,
-+ 0x54, 0x8c, 0xf8, 0x50, 0x30, 0xcc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x12, 0x13, 0x16, 0x1a, 0x1f,
-+ 0x12, 0x12, 0x17, 0x25, 0x24, 0x48, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0x00, 0xfc, 0xa8, 0xa8, 0xfc,
-+ 0xa8, 0xa8, 0xfc, 0x48, 0xa4, 0xa4, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x27, 0x29, 0x32, 0x2f, 0x2a,
-+ 0x2f, 0x2a, 0x2f, 0x28, 0x28, 0x51, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0x78, 0x28, 0x28, 0xd8, 0xb0,
-+ 0xb0, 0xfc, 0xd0, 0xfc, 0x90, 0x90, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x17, 0x15, 0x15, 0x15,
-+ 0x17, 0x10, 0x13, 0x3f, 0x26, 0x58, 0x00, 0x00,
-+ 0x80, 0xfc, 0x80, 0xf8, 0xf0, 0xd0, 0x50, 0xd0,
-+ 0xf0, 0xe0, 0x80, 0xfc, 0xb0, 0x8c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x17, 0x14, 0x17, 0x15, 0x15,
-+ 0x15, 0x15, 0x25, 0x2b, 0x4a, 0x17, 0x00, 0x00,
-+ 0x80, 0xfc, 0xf0, 0xfc, 0xe8, 0x78, 0xf0, 0x50,
-+ 0xf0, 0x50, 0xf0, 0xf8, 0xa8, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3f, 0x2a, 0x35, 0x2a, 0x2f, 0x29, 0x2f,
-+ 0x20, 0x2f, 0x2a, 0x2f, 0x28, 0x47, 0x00, 0x00,
-+ 0x80, 0xfc, 0xa8, 0x28, 0xbc, 0x68, 0x68, 0xbc,
-+ 0x28, 0xbc, 0xa8, 0xa8, 0x7c, 0xe0, 0x00, 0x00,
-+ 0x00, 0x3f, 0x3f, 0x29, 0x2f, 0x29, 0x2f, 0x29,
-+ 0x3f, 0x3f, 0x25, 0x2f, 0x25, 0x4f, 0x00, 0x00,
-+ 0x80, 0xfc, 0x20, 0xfc, 0x20, 0xfc, 0xb4, 0xfc,
-+ 0x00, 0xfc, 0x28, 0xd4, 0xcc, 0x38, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x3f, 0x2a, 0x2b, 0x2f, 0x2b,
-+ 0x2e, 0x2a, 0x2f, 0x3a, 0x23, 0x42, 0x00, 0x00,
-+ 0x80, 0xfc, 0x20, 0xfc, 0x20, 0xfc, 0x54, 0xfc,
-+ 0x20, 0x58, 0xd4, 0xc4, 0x48, 0x38, 0x00, 0x00,
-+ 0x00, 0x3c, 0x04, 0x08, 0x08, 0x10, 0x3c, 0x04,
-+ 0x24, 0x28, 0x18, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x78, 0x08, 0x10, 0x13, 0x22, 0x7a, 0x0b,
-+ 0x4a, 0x32, 0x13, 0x2a, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x04, 0x04, 0x7f, 0x04, 0x04,
-+ 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x02, 0x02, 0x04, 0x3f, 0x04,
-+ 0x04, 0x7f, 0x04, 0x08, 0x08, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0x20, 0x10, 0xf8, 0x48,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x24, 0x24, 0x3c, 0x07, 0x7c, 0x24, 0x25, 0x44,
-+ 0x04, 0x7f, 0x04, 0x04, 0x08, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x00,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x03, 0x07, 0x7f, 0x2a, 0x1c, 0x7e, 0x1d,
-+ 0x2a, 0x49, 0x04, 0x7f, 0x04, 0x18, 0x00, 0x00,
-+ 0x00, 0xe0, 0xc0, 0xfc, 0x28, 0xd0, 0x28, 0xfc,
-+ 0xa8, 0x24, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x03, 0x07, 0x7f, 0x2a, 0x1c, 0x7f, 0x1c,
-+ 0x2a, 0x48, 0x04, 0x7f, 0x04, 0x18, 0x00, 0x00,
-+ 0x00, 0xe0, 0xc0, 0xfc, 0x50, 0x88, 0xfc, 0x48,
-+ 0x48, 0x98, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x00, 0x07, 0x78, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x20, 0x10, 0x10, 0x0c, 0xf0, 0x80, 0x80, 0x40,
-+ 0x40, 0x20, 0x24, 0x14, 0x0c, 0x04, 0x00, 0x00,
-+ 0x02, 0x02, 0x34, 0x0d, 0x1a, 0x6a, 0x09, 0x7e,
-+ 0x18, 0x1c, 0x2a, 0x2a, 0x49, 0x08, 0x00, 0x00,
-+ 0x18, 0x14, 0x14, 0xfc, 0x10, 0x10, 0xf0, 0x50,
-+ 0x50, 0x54, 0x4c, 0x6c, 0x84, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x00, 0x00, 0x1f, 0x10, 0x10, 0x1f,
-+ 0x10, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0xf8,
-+ 0x08, 0x08, 0x10, 0xe0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x12, 0x3a, 0x06, 0x19, 0x6f,
-+ 0x00, 0x0f, 0x08, 0x1f, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x50, 0x20, 0xd0, 0x0c, 0xe0,
-+ 0x20, 0xe0, 0x00, 0xf0, 0x10, 0xe0, 0x00, 0x00,
-+ 0x00, 0x7f, 0x09, 0x09, 0x79, 0x49, 0x41, 0x41,
-+ 0x79, 0x49, 0x09, 0x0f, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0x10, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x10, 0x10, 0xf0, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x7b, 0x0a, 0x0a, 0x7a, 0x4b, 0x42, 0x7a,
-+ 0x4a, 0x0b, 0x0a, 0x0c, 0x14, 0x69, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xa8, 0xa8, 0xb8, 0xa8, 0xa8,
-+ 0xa8, 0xb8, 0xa8, 0xc8, 0xc8, 0x98, 0x00, 0x00,
-+ 0x00, 0x7f, 0x08, 0x0b, 0x7a, 0x4b, 0x40, 0x7f,
-+ 0x48, 0x0b, 0x0a, 0x0b, 0x0a, 0x30, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xc8, 0x48, 0xc8, 0x18, 0xfc,
-+ 0x08, 0xc8, 0x48, 0xc8, 0x48, 0x18, 0x00, 0x00,
-+ 0x00, 0x7b, 0x0a, 0x0b, 0x78, 0x4b, 0x42, 0x7b,
-+ 0x4a, 0x0b, 0x08, 0x0f, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0x00, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x7f, 0x09, 0x0e, 0x7b, 0x4a, 0x43, 0x7a,
-+ 0x4b, 0x0a, 0x0b, 0x0a, 0x0b, 0x32, 0x00, 0x00,
-+ 0x00, 0xfc, 0x58, 0x44, 0xf8, 0xd8, 0xf8, 0xd8,
-+ 0x68, 0xd8, 0xf8, 0xd8, 0x68, 0x58, 0x00, 0x00,
-+ 0x13, 0x6f, 0x2b, 0x17, 0x7f, 0x3a, 0x57, 0x1f,
-+ 0x00, 0x0f, 0x08, 0x1f, 0x10, 0x00, 0x00, 0x00,
-+ 0x90, 0xe8, 0xa8, 0x94, 0xfc, 0xb8, 0xd4, 0xe0,
-+ 0x20, 0xe0, 0x00, 0xf0, 0x10, 0xe0, 0x00, 0x00,
-+ 0x01, 0x7f, 0x02, 0x12, 0x12, 0x24, 0x4f, 0x00,
-+ 0x0f, 0x08, 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x50, 0x48, 0xc4, 0xe4, 0x20,
-+ 0xe0, 0x00, 0xf0, 0x10, 0x10, 0xe0, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x07, 0x04, 0x04, 0x04, 0x04,
-+ 0x0f, 0x08, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xe0, 0x20, 0x20, 0x20, 0x20,
-+ 0xe0, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x02, 0x03, 0x04, 0x0f, 0x00, 0x7f, 0x01, 0x07,
-+ 0x79, 0x06, 0x39, 0x06, 0x38, 0x03, 0x00, 0x00,
-+ 0x00, 0xe0, 0x40, 0x80, 0x80, 0xfc, 0x00, 0x48,
-+ 0xd0, 0xe0, 0xa0, 0x90, 0x8c, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7e, 0x08, 0x3e, 0x08, 0x0e, 0x78,
-+ 0x1f, 0x00, 0x7f, 0x00, 0x1f, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x20,
-+ 0xf0, 0x10, 0xfc, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x02, 0x07, 0x0f, 0x7f, 0x00, 0x3f, 0x2f, 0x49,
-+ 0x0f, 0x09, 0x0f, 0x7f, 0x0d, 0x31, 0x00, 0x00,
-+ 0x00, 0xe0, 0xc0, 0xfc, 0x00, 0xfc, 0xe8, 0x20,
-+ 0xe0, 0x20, 0xe0, 0xfc, 0x60, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x02, 0x04, 0x08, 0x10, 0x01,
-+ 0x02, 0x04, 0x00, 0x00, 0x03, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x40, 0x40, 0x80, 0x90, 0x10,
-+ 0x20, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x00, 0x3e, 0x22,
-+ 0x3e, 0x22, 0x12, 0x14, 0x1e, 0x70, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0x28, 0x48, 0x90, 0x14, 0x24,
-+ 0x48, 0x08, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x02, 0x04, 0x08, 0x00, 0x01,
-+ 0x03, 0x05, 0x09, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x40, 0x40, 0x80, 0x80, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x10, 0x17, 0x24, 0x08, 0x08, 0x18,
-+ 0x28, 0x48, 0x08, 0x09, 0x0a, 0x0c, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x78, 0x48,
-+ 0x48, 0x88, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x12, 0x22, 0x2a, 0x4b, 0x14, 0x14, 0x38,
-+ 0x53, 0x10, 0x10, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x11, 0x15, 0x25, 0x49, 0x09, 0x19,
-+ 0x29, 0x49, 0x09, 0x09, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x10, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x13, 0x14, 0x24, 0x4b, 0x0a, 0x1a,
-+ 0x2b, 0x4a, 0x08, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xf8, 0xa8, 0xa8, 0xf8, 0xa8, 0xa0,
-+ 0xfc, 0xa4, 0xa4, 0xb8, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x13, 0x22, 0x4a, 0x0a, 0x12, 0x12, 0x32,
-+ 0x52, 0x12, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xe8, 0xa8, 0xa8, 0xa8,
-+ 0xe8, 0xa8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x09, 0x11, 0x15, 0x25, 0x49, 0x09, 0x19,
-+ 0x29, 0x49, 0x09, 0x09, 0x09, 0x0e, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x10, 0xf4,
-+ 0x44, 0x48, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x17, 0x22, 0x4a, 0x0c, 0x12, 0x12, 0x30,
-+ 0x53, 0x10, 0x10, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0x48, 0x90, 0x48, 0x48, 0x00,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x09, 0x09, 0x11, 0x15, 0x26, 0x4b, 0x0d, 0x19,
-+ 0x29, 0x49, 0x09, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0xe8, 0x28, 0xe8,
-+ 0x28, 0xe8, 0x28, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x11, 0x11, 0x21, 0x4a, 0x0a, 0x14, 0x10, 0x32,
-+ 0x52, 0x12, 0x12, 0x15, 0x14, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0xa8, 0xa4, 0x44, 0x40, 0x40,
-+ 0x40, 0x78, 0x40, 0x40, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x10, 0x10, 0x22, 0x4a, 0x0a, 0x12, 0x17, 0x30,
-+ 0x52, 0x12, 0x12, 0x13, 0x14, 0x18, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0xfc, 0x40,
-+ 0x40, 0x78, 0x40, 0x40, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0x4f, 0x08, 0x10, 0x17, 0x30,
-+ 0x50, 0x1f, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xa0, 0xbc, 0xa0, 0xa0, 0xb8, 0xa0,
-+ 0xa0, 0xbc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x27, 0x49, 0x09, 0x13, 0x12, 0x34,
-+ 0x50, 0x10, 0x11, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x50, 0x50, 0x58, 0xe4, 0x44,
-+ 0xe0, 0xd0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x11, 0x15, 0x25, 0x49, 0x09, 0x18,
-+ 0x2f, 0x48, 0x0b, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x00,
-+ 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x21, 0x4e, 0x09, 0x11, 0x17, 0x31,
-+ 0x52, 0x17, 0x10, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x80, 0xf0, 0x90, 0x60, 0x40, 0x80, 0xf8, 0x40,
-+ 0x40, 0xfc, 0x40, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x11, 0x12, 0x27, 0x4c, 0x0f, 0x14, 0x17, 0x32,
-+ 0x5f, 0x12, 0x13, 0x12, 0x14, 0x19, 0x00, 0x00,
-+ 0x20, 0x20, 0xa0, 0xa0, 0xfc, 0xc8, 0xa8, 0x28,
-+ 0xb0, 0x10, 0x90, 0xa8, 0xc8, 0x84, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x18, 0x37, 0x34, 0x31, 0x50,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0xfc, 0x10, 0x10, 0x90,
-+ 0x90, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x19, 0x35, 0x35, 0x31, 0x51,
-+ 0x11, 0x11, 0x12, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x00, 0x00, 0xfc, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x19, 0x36, 0x34, 0x30, 0x57,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x40, 0x40, 0x40, 0xfc,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x13, 0x11, 0x19, 0x35, 0x35, 0x37, 0x51,
-+ 0x11, 0x11, 0x11, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0x10, 0xfc, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x13, 0x3a, 0x36, 0x34, 0x50,
-+ 0x10, 0x10, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x44, 0x48, 0x60, 0x60,
-+ 0xa0, 0xa0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x01, 0x1f, 0x01, 0x7f, 0x02, 0x04, 0x1a,
-+ 0x62, 0x0b, 0x0a, 0x12, 0x22, 0x06, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0x00, 0xfc, 0x80, 0x40, 0x30,
-+ 0x0c, 0x20, 0x90, 0x48, 0x48, 0x00, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x27, 0x24, 0x27, 0x27, 0x24,
-+ 0x27, 0x3f, 0x01, 0x24, 0x24, 0x43, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0xf0, 0x10,
-+ 0xf0, 0xfc, 0x00, 0x88, 0x24, 0xe4, 0x00, 0x00,
-+ 0x01, 0x04, 0x08, 0x10, 0x6f, 0x02, 0x04, 0x18,
-+ 0x01, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0xc0, 0x40, 0x20, 0x10, 0xec, 0x20, 0x20, 0xc0,
-+ 0x00, 0x90, 0x88, 0x04, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x10, 0x18, 0x34, 0x34, 0x31, 0x57, 0x10,
-+ 0x13, 0x12, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x90, 0x88, 0x1c, 0xe4, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x1b, 0x35, 0x35, 0x32, 0x56,
-+ 0x1a, 0x12, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x00, 0x20, 0x20, 0x20,
-+ 0xf8, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x3b, 0x34, 0x34, 0x50, 0x13,
-+ 0x12, 0x12, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x3b, 0x36, 0x34, 0x53, 0x12,
-+ 0x12, 0x12, 0x13, 0x12, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0xc8, 0x48,
-+ 0x48, 0x48, 0xc8, 0x48, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x13, 0x1a, 0x36, 0x37, 0x32, 0x52, 0x12,
-+ 0x12, 0x12, 0x14, 0x14, 0x18, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x80, 0x88,
-+ 0x90, 0xe0, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x11, 0x11, 0x21, 0x41, 0x01,
-+ 0x01, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x00, 0xf0, 0x00,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x12, 0x2e, 0x45, 0x08, 0x01,
-+ 0x01, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x48, 0x48, 0x88, 0xc8, 0x30,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x19, 0x35, 0x35, 0x31, 0x51,
-+ 0x11, 0x11, 0x11, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0x10, 0xf0, 0x10, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x19, 0x35, 0x35, 0x31, 0x51,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0x80, 0xf8, 0x08, 0x08, 0x08, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x18, 0x34, 0x37, 0x32, 0x52,
-+ 0x13, 0x12, 0x10, 0x10, 0x11, 0x12, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xf8, 0xa8, 0xa8, 0xf8, 0xa0, 0xa0,
-+ 0xfc, 0xa4, 0xa4, 0xb8, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x19, 0x35, 0x36, 0x30, 0x57,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x50, 0x48, 0x48, 0x40, 0xfc,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x1b, 0x36, 0x36, 0x32, 0x57,
-+ 0x10, 0x10, 0x10, 0x11, 0x12, 0x1c, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0xfc,
-+ 0x40, 0xc0, 0xa0, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x19, 0x34, 0x34, 0x33, 0x50,
-+ 0x11, 0x11, 0x12, 0x14, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x20, 0x20, 0xc0, 0x48, 0x68, 0xf0, 0xe0,
-+ 0x50, 0x50, 0x48, 0x44, 0x40, 0xc0, 0x00, 0x00,
-+ 0x01, 0x1f, 0x01, 0x7f, 0x01, 0x1f, 0x01, 0x7f,
-+ 0x01, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x00, 0xf0, 0x00, 0xfc,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x08, 0x0b, 0x10, 0x10, 0x37, 0x50, 0x10, 0x13,
-+ 0x11, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x18, 0xe0, 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x19, 0x35, 0x36, 0x30, 0x50,
-+ 0x11, 0x17, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x80, 0x80, 0xf0, 0x10, 0xa0, 0x60, 0x60, 0x90,
-+ 0xf8, 0x14, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x17, 0x10, 0x30, 0x51, 0x12, 0x14,
-+ 0x11, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xe0, 0xe0, 0x50, 0x48, 0x44,
-+ 0x40, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x12, 0x12, 0x12, 0x1b, 0x34, 0x36, 0x39, 0x54,
-+ 0x15, 0x16, 0x17, 0x14, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x48, 0x48, 0xa8, 0xa8,
-+ 0x68, 0x28, 0xe8, 0x28, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x18, 0x34, 0x35, 0x32, 0x52,
-+ 0x1f, 0x12, 0x12, 0x14, 0x14, 0x19, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x88, 0x88, 0x08, 0x30, 0x10,
-+ 0xfc, 0x94, 0x94, 0xa4, 0xa4, 0xcc, 0x00, 0x00,
-+ 0x10, 0x17, 0x11, 0x19, 0x35, 0x35, 0x31, 0x51,
-+ 0x13, 0x12, 0x12, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf0, 0x90, 0x50, 0x50,
-+ 0x10, 0xa0, 0xa0, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x12, 0x19, 0x35, 0x34, 0x37, 0x50,
-+ 0x10, 0x10, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x40, 0x40, 0x48, 0x48, 0x50, 0x40, 0xfc, 0xa0,
-+ 0xa0, 0xa0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x01, 0x01, 0x79, 0x02, 0x04, 0x18, 0x61, 0x06,
-+ 0x01, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x48, 0x50, 0xa0, 0x10, 0x0c,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x18, 0x34, 0x37, 0x30, 0x50,
-+ 0x17, 0x11, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x10, 0x10,
-+ 0xfc, 0x10, 0x90, 0x90, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x18, 0x37, 0x36, 0x32, 0x52,
-+ 0x12, 0x12, 0x12, 0x12, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x80, 0xf8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x19, 0x36, 0x37, 0x32, 0x53,
-+ 0x12, 0x13, 0x12, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0xc8, 0x48, 0xc8,
-+ 0x48, 0xc8, 0x48, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x18, 0x34, 0x37, 0x30, 0x50,
-+ 0x13, 0x12, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x1a, 0x37, 0x36, 0x32, 0x52,
-+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0xe8, 0xa8,
-+ 0xa8, 0xe8, 0xa8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x04, 0x3f, 0x01, 0x1f, 0x01, 0x01, 0x7f,
-+ 0x01, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x00, 0xf0, 0x00, 0x00, 0xfc,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x1a, 0x37, 0x34, 0x33, 0x52,
-+ 0x13, 0x12, 0x13, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x00, 0xf8, 0x08,
-+ 0xf8, 0x08, 0xf8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x1b, 0x36, 0x37, 0x30, 0x53,
-+ 0x10, 0x10, 0x17, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x00, 0xf8,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x19, 0x35, 0x35, 0x31, 0x51,
-+ 0x11, 0x17, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xfc, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x1a, 0x36, 0x37, 0x32, 0x52,
-+ 0x12, 0x13, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0xf8, 0x48, 0xe8,
-+ 0xd8, 0x58, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x10, 0x3b, 0x36, 0x36, 0x53,
-+ 0x12, 0x10, 0x11, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0xc8, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x1a, 0x34, 0x37, 0x32, 0x53,
-+ 0x12, 0x13, 0x12, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x44, 0x44, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x1b, 0x34, 0x34, 0x31, 0x52,
-+ 0x10, 0x11, 0x12, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0x40, 0x50, 0x88, 0xfc, 0xa4, 0xa0, 0x24, 0x9c,
-+ 0xf0, 0x10, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x1b, 0x14, 0x37, 0x32, 0x35, 0x50,
-+ 0x10, 0x17, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xfc, 0x08, 0xf0, 0x20,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x1a, 0x37, 0x36, 0x32, 0x53,
-+ 0x12, 0x10, 0x10, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x80, 0xf0, 0x20, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0xe0, 0xd0, 0x54, 0x44, 0x3c, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x19, 0x34, 0x37, 0x32, 0x52,
-+ 0x13, 0x12, 0x12, 0x12, 0x12, 0x11, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xf8, 0x48, 0x48,
-+ 0xf8, 0x08, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x19, 0x35, 0x37, 0x31, 0x53,
-+ 0x13, 0x15, 0x19, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x48, 0xa8, 0x28, 0x28, 0x28, 0xe8, 0x28, 0xa8,
-+ 0x68, 0x68, 0x28, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x19, 0x34, 0x34, 0x31, 0x56,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0xa0, 0x40, 0xb0, 0x0c,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x1e, 0x10, 0x1e, 0x02, 0x7f,
-+ 0x01, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0xf0, 0x10, 0xf0, 0x80, 0xfc,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x13, 0x18, 0x17, 0x34, 0x31, 0x36, 0x51,
-+ 0x10, 0x10, 0x17, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x18, 0xe0, 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0xf0,
-+ 0x20, 0x40, 0xfc, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x1f, 0x11, 0x1f, 0x11, 0x1f,
-+ 0x01, 0x3f, 0x01, 0x24, 0x24, 0x43, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf8, 0x00, 0x88, 0x24, 0xe4, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x1b, 0x34, 0x37, 0x31, 0x53,
-+ 0x15, 0x11, 0x11, 0x11, 0x11, 0x10, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0xf8, 0xa0, 0xfc, 0x10, 0xf8,
-+ 0x14, 0x10, 0x60, 0x08, 0x08, 0xf8, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x19, 0x35, 0x35, 0x32, 0x54,
-+ 0x10, 0x17, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0x10, 0x98, 0x64, 0x44,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x18, 0x34, 0x35, 0x31, 0x52,
-+ 0x10, 0x17, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x80, 0x80, 0xe0, 0xa0, 0xa4, 0x24, 0x1c, 0x40,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x1b, 0x34, 0x37, 0x30, 0x53,
-+ 0x10, 0x17, 0x11, 0x13, 0x10, 0x17, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8,
-+ 0x80, 0xfc, 0x10, 0xe0, 0xd0, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x1a, 0x36, 0x36, 0x32, 0x52,
-+ 0x12, 0x12, 0x12, 0x14, 0x14, 0x18, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xe8, 0x48, 0xe8, 0x48,
-+ 0xe8, 0xa8, 0xa8, 0xe8, 0x88, 0x18, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x19, 0x35, 0x35, 0x31, 0x57,
-+ 0x11, 0x11, 0x11, 0x11, 0x11, 0x16, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xfc,
-+ 0x48, 0x28, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x13, 0x1a, 0x36, 0x37, 0x32, 0x53,
-+ 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0xa8, 0xc8, 0xf8, 0x48, 0xf8,
-+ 0x88, 0x88, 0xe8, 0x88, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x19, 0x35, 0x35, 0x31, 0x50,
-+ 0x13, 0x12, 0x12, 0x12, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x50, 0x50, 0xb0, 0x10, 0xf0, 0x00,
-+ 0xf8, 0xa8, 0xa8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x1b, 0x34, 0x35, 0x30, 0x57,
-+ 0x10, 0x10, 0x11, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0x00, 0xf0, 0x00, 0xfc,
-+ 0x80, 0xf0, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x12, 0x11, 0x24, 0x4a, 0x08, 0x11, 0x32, 0x52,
-+ 0x10, 0x01, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0x78, 0x00, 0x00, 0xfc, 0x10, 0x10, 0x10,
-+ 0x30, 0x00, 0x88, 0x84, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x19, 0x35, 0x35, 0x31, 0x50,
-+ 0x13, 0x10, 0x11, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x40, 0x80, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00,
-+ 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x1f, 0x0f, 0x02, 0x7f, 0x0f, 0x14, 0x67,
-+ 0x04, 0x07, 0x21, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xf0, 0xe0, 0x80, 0xfc, 0xe0, 0x50, 0xcc,
-+ 0x40, 0xc0, 0x08, 0x84, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x19, 0x35, 0x37, 0x31, 0x51,
-+ 0x13, 0x13, 0x15, 0x19, 0x11, 0x11, 0x00, 0x00,
-+ 0x50, 0x90, 0x10, 0x14, 0x34, 0xf8, 0x50, 0x90,
-+ 0x50, 0x50, 0x28, 0x28, 0x44, 0x84, 0x00, 0x00,
-+ 0x10, 0x12, 0x12, 0x12, 0x3b, 0x34, 0x37, 0x50,
-+ 0x13, 0x12, 0x12, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0x48, 0xf8, 0x00, 0xfc, 0x80,
-+ 0xf8, 0xa8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x1b, 0x36, 0x37, 0x31, 0x51,
-+ 0x13, 0x14, 0x13, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x40, 0x40,
-+ 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x1a, 0x37, 0x34, 0x31, 0x51,
-+ 0x11, 0x11, 0x11, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0xf8, 0x00, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x1a, 0x35, 0x35, 0x32, 0x50,
-+ 0x10, 0x11, 0x15, 0x15, 0x19, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0xa8, 0xa8, 0x68, 0x58, 0xb0,
-+ 0x80, 0x50, 0x48, 0x14, 0x14, 0xf0, 0x00, 0x00,
-+ 0x10, 0x17, 0x14, 0x1c, 0x3f, 0x3c, 0x37, 0x54,
-+ 0x14, 0x17, 0x13, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x08, 0x88, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0x28, 0x88, 0x88, 0x18, 0x00, 0x00,
-+ 0x11, 0x11, 0x12, 0x1a, 0x35, 0x35, 0x30, 0x53,
-+ 0x12, 0x12, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x28, 0x28, 0x50, 0x50, 0x28, 0x68, 0x80, 0xf8,
-+ 0x28, 0xc8, 0x68, 0x98, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x29, 0x3f, 0x24, 0x3b,
-+ 0x61, 0x01, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xc8, 0x48, 0x30, 0x30, 0xc8,
-+ 0x04, 0x10, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x11, 0x11, 0x12, 0x1d, 0x35, 0x35, 0x31, 0x51,
-+ 0x10, 0x11, 0x16, 0x10, 0x10, 0x17, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x80, 0xf8, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x06, 0x38, 0x3e, 0x22, 0x3f, 0x3e, 0x3e, 0x23,
-+ 0x4c, 0x01, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x94, 0xfc, 0x90, 0x60, 0xb0,
-+ 0x0c, 0x00, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x1a, 0x35, 0x34, 0x37, 0x54,
-+ 0x12, 0x12, 0x17, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x00, 0xf0, 0xb0,
-+ 0xb0, 0xd0, 0xf4, 0xcc, 0xac, 0x84, 0x00, 0x00,
-+ 0x08, 0x7f, 0x08, 0x3e, 0x00, 0x3f, 0x22, 0x5e,
-+ 0x00, 0x01, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x70, 0x50, 0x54, 0x8c, 0xf8, 0x48, 0x30, 0xd8,
-+ 0x04, 0x10, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x1a, 0x37, 0x36, 0x33, 0x52,
-+ 0x10, 0x11, 0x11, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0xc8,
-+ 0xd0, 0x50, 0x68, 0x7c, 0x44, 0x3c, 0x00, 0x00,
-+ 0x10, 0x11, 0x10, 0x1f, 0x34, 0x37, 0x30, 0x57,
-+ 0x10, 0x13, 0x11, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x48, 0xb0, 0xa0, 0xfc, 0xa0, 0xf8, 0xa8, 0xfc,
-+ 0xa8, 0xf8, 0xb0, 0xa8, 0xa4, 0xa0, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x17, 0x17, 0x14, 0x27, 0x24,
-+ 0x59, 0x01, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0xf0, 0xf0, 0x10, 0xf0, 0xb0,
-+ 0x8c, 0x00, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x18, 0x34, 0x36, 0x32, 0x52,
-+ 0x12, 0x12, 0x12, 0x13, 0x11, 0x16, 0x00, 0x00,
-+ 0x10, 0x64, 0x84, 0xf8, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0xfc, 0x98, 0x04, 0x00, 0x00,
-+ 0x22, 0x14, 0x7f, 0x08, 0x2a, 0x2a, 0x3e, 0x09,
-+ 0x13, 0x20, 0x04, 0x24, 0x24, 0x43, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x08,
-+ 0x18, 0x80, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x19, 0x36, 0x35, 0x31, 0x51,
-+ 0x11, 0x11, 0x12, 0x13, 0x15, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xf0, 0x08, 0xf4, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x00, 0xf8, 0x08, 0xf8, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x1b, 0x36, 0x37, 0x32, 0x53,
-+ 0x12, 0x10, 0x17, 0x11, 0x10, 0x10, 0x00, 0x00,
-+ 0x48, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x48, 0x10, 0xfc, 0x10, 0x90, 0x30, 0x00, 0x00,
-+ 0x13, 0x08, 0x4b, 0x22, 0x23, 0x0a, 0x13, 0x22,
-+ 0x22, 0x01, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0xf0, 0xa0, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x48,
-+ 0x58, 0x00, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x1b, 0x36, 0x36, 0x33, 0x50,
-+ 0x17, 0x10, 0x11, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xf8, 0xa8, 0xa8, 0xf8, 0x40,
-+ 0xfc, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x10, 0x17, 0x15, 0x1f, 0x34, 0x37, 0x35, 0x57,
-+ 0x14, 0x13, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x24, 0xa8, 0x98, 0x90, 0x68, 0x84,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x1b, 0x36, 0x37, 0x32, 0x53,
-+ 0x12, 0x13, 0x14, 0x17, 0x18, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8,
-+ 0x48, 0x68, 0xd0, 0x50, 0x4c, 0xc0, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x19, 0x35, 0x36, 0x37, 0x50,
-+ 0x11, 0x17, 0x10, 0x11, 0x10, 0x13, 0x00, 0x00,
-+ 0x40, 0x90, 0xf8, 0x10, 0x18, 0xa4, 0xfc, 0xa0,
-+ 0x50, 0xac, 0x48, 0x90, 0x60, 0x80, 0x00, 0x00,
-+ 0x08, 0x7f, 0x3e, 0x2a, 0x3e, 0x2a, 0x3e, 0x7f,
-+ 0x08, 0x01, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x08, 0xf0, 0x80, 0xfc, 0x90, 0x90, 0x90, 0x10,
-+ 0x10, 0x00, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x11, 0x3f, 0x3d, 0x37, 0x55,
-+ 0x17, 0x11, 0x17, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x04, 0x38, 0xe0, 0x20, 0xe0, 0x7c, 0xe8, 0x68,
-+ 0xe8, 0x28, 0xe8, 0x48, 0x48, 0x88, 0x00, 0x00,
-+ 0x11, 0x11, 0x22, 0x4c, 0x0a, 0x12, 0x33, 0x54,
-+ 0x18, 0x01, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x10, 0x10, 0xa8, 0x44, 0x40, 0x78, 0x40, 0xc0,
-+ 0x3c, 0x00, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x17, 0x11, 0x1a, 0x35, 0x36, 0x34, 0x51,
-+ 0x13, 0x12, 0x13, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x98, 0xa8, 0xd8, 0xa8, 0xc8, 0x00,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x11, 0x11, 0x13, 0x15, 0x39, 0x35, 0x35, 0x51,
-+ 0x17, 0x11, 0x13, 0x14, 0x11, 0x12, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0xfc, 0x00, 0xf8, 0xa8, 0x48, 0xb0, 0x00, 0x00,
-+ 0x10, 0x12, 0x11, 0x19, 0x34, 0x37, 0x33, 0x50,
-+ 0x16, 0x12, 0x12, 0x12, 0x15, 0x18, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xf8, 0xa0, 0x20, 0xfc, 0x20,
-+ 0xf8, 0x88, 0x88, 0xf8, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x1b, 0x36, 0x37, 0x32, 0x53,
-+ 0x10, 0x17, 0x10, 0x17, 0x11, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xfc, 0x10, 0xfc, 0x10, 0xb0, 0x00, 0x00,
-+ 0x10, 0x17, 0x11, 0x17, 0x39, 0x3f, 0x35, 0x57,
-+ 0x15, 0x17, 0x11, 0x17, 0x11, 0x17, 0x00, 0x00,
-+ 0x50, 0x90, 0x10, 0xd0, 0x3c, 0xd4, 0x54, 0xd4,
-+ 0x54, 0xd4, 0x14, 0xe4, 0xe4, 0x4c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x25, 0x3f, 0x27, 0x3a,
-+ 0x23, 0x3f, 0x01, 0x24, 0x24, 0x43, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xf0, 0x40, 0xf8, 0xe0, 0x20,
-+ 0xe0, 0xf8, 0x00, 0xa8, 0x24, 0xe4, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x1b, 0x36, 0x37, 0x30, 0x53,
-+ 0x10, 0x17, 0x11, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xf8, 0xa8, 0xf8, 0x00, 0xf8,
-+ 0x00, 0xfc, 0x50, 0x48, 0x48, 0xc0, 0x00, 0x00,
-+ 0x10, 0x17, 0x14, 0x1d, 0x3c, 0x3f, 0x34, 0x55,
-+ 0x17, 0x16, 0x17, 0x1a, 0x1b, 0x12, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8,
-+ 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x58, 0x00, 0x00,
-+ 0x01, 0x7f, 0x1f, 0x0f, 0x08, 0x0f, 0x04, 0x7f,
-+ 0x0f, 0x08, 0x0f, 0x25, 0x24, 0x43, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf0, 0xe0, 0x20, 0xe0, 0x40, 0xfc,
-+ 0xe0, 0x20, 0xe0, 0x08, 0xa4, 0xe4, 0x00, 0x00,
-+ 0x08, 0x7f, 0x2a, 0x2a, 0x5d, 0x1c, 0x2a, 0x4b,
-+ 0x01, 0x04, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x30, 0x28, 0x28, 0xfc, 0x20, 0x30, 0x48, 0x84,
-+ 0x00, 0x90, 0x88, 0x24, 0x24, 0xe0, 0x00, 0x00,
-+ 0x02, 0x3c, 0x09, 0x7e, 0x08, 0x3e, 0x22, 0x3e,
-+ 0x20, 0x01, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x88, 0x88, 0xfc, 0x88, 0xf8, 0x88, 0x88, 0xf8,
-+ 0x88, 0x00, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x19, 0x35, 0x35, 0x30, 0x57,
-+ 0x11, 0x11, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x40, 0xfc,
-+ 0xf0, 0x10, 0xf0, 0x50, 0x48, 0xc8, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x1b, 0x37, 0x35, 0x31, 0x51,
-+ 0x11, 0x11, 0x10, 0x12, 0x12, 0x14, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xfc, 0x20, 0xf8, 0x20, 0xf8,
-+ 0x20, 0xfc, 0x00, 0xa8, 0x54, 0x54, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x1b, 0x34, 0x37, 0x32, 0x53,
-+ 0x12, 0x13, 0x10, 0x17, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0x00, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x0b, 0x10, 0x17, 0x31, 0x53, 0x1d, 0x11,
-+ 0x11, 0x11, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0xa0, 0xf8, 0xa0, 0xfc, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0x58, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x00, 0x23, 0x12, 0x13, 0x03, 0x0a, 0x13, 0x25,
-+ 0x24, 0x09, 0x04, 0x24, 0x24, 0x43, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xf0, 0xf0, 0x40, 0xfc, 0x54,
-+ 0xac, 0x18, 0x80, 0x88, 0x24, 0xe4, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x1b, 0x36, 0x37, 0x32, 0x53,
-+ 0x12, 0x12, 0x12, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0xa8, 0xb8, 0x48, 0xf8,
-+ 0xa8, 0x48, 0x68, 0xa8, 0x08, 0x18, 0x00, 0x00,
-+ 0x12, 0x12, 0x13, 0x1e, 0x36, 0x37, 0x32, 0x52,
-+ 0x12, 0x17, 0x10, 0x15, 0x14, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0xa8, 0xa8, 0xfc, 0xa8, 0xa8,
-+ 0xa8, 0xfc, 0x00, 0x48, 0xa4, 0xa4, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x1b, 0x34, 0x37, 0x30, 0x57,
-+ 0x11, 0x17, 0x10, 0x13, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xf8, 0x40, 0xf8, 0x40, 0xfc,
-+ 0x10, 0xfc, 0x40, 0xf8, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x1a, 0x37, 0x36, 0x33, 0x52,
-+ 0x13, 0x10, 0x17, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0xe8, 0x58, 0xe8, 0xf8, 0xe8,
-+ 0x58, 0x40, 0xfc, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x12, 0x15, 0x1e, 0x14, 0x14,
-+ 0x14, 0x14, 0x20, 0x2a, 0x4a, 0x11, 0x00, 0x00,
-+ 0x80, 0xfc, 0x90, 0xfc, 0x90, 0xf8, 0x90, 0xf8,
-+ 0x90, 0xfc, 0x80, 0x48, 0x14, 0xf4, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x1b, 0x36, 0x37, 0x30, 0x57,
-+ 0x17, 0x11, 0x1f, 0x11, 0x11, 0x16, 0x00, 0x00,
-+ 0x40, 0xfc, 0x00, 0xf8, 0xa8, 0xf8, 0x40, 0x5c,
-+ 0x5c, 0xc8, 0x28, 0x30, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x12, 0x13, 0x14, 0x19, 0x37, 0x3d, 0x3d, 0x57,
-+ 0x15, 0x15, 0x17, 0x14, 0x18, 0x10, 0x00, 0x00,
-+ 0x00, 0xbc, 0x94, 0x14, 0xe4, 0x4c, 0x68, 0xe8,
-+ 0x7c, 0x48, 0xfc, 0x48, 0x48, 0xc8, 0x00, 0x00,
-+ 0x14, 0x7f, 0x1c, 0x3f, 0x2a, 0x3e, 0x7f, 0x3e,
-+ 0x0f, 0x71, 0x04, 0x24, 0x24, 0x43, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x88, 0x88,
-+ 0x30, 0x00, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x19, 0x34, 0x37, 0x32, 0x53,
-+ 0x10, 0x17, 0x10, 0x11, 0x16, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xb8, 0xa8, 0xb8,
-+ 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x1b, 0x36, 0x36, 0x33, 0x53,
-+ 0x12, 0x12, 0x14, 0x14, 0x18, 0x10, 0x00, 0x00,
-+ 0x40, 0xf0, 0x20, 0xfc, 0xa8, 0x98, 0x70, 0xfc,
-+ 0x70, 0x70, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x10, 0x17, 0x7a, 0x11, 0x3f, 0x3b, 0x35, 0x59,
-+ 0x13, 0x01, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x10, 0xd0, 0xbc, 0x10, 0xf8, 0xb8, 0x34, 0x54,
-+ 0x10, 0x00, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x11, 0x11, 0x1b, 0x36,
-+ 0x37, 0x52, 0x13, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x10, 0x20, 0xf8, 0x40,
-+ 0xf0, 0x40, 0xf0, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x1b, 0x36, 0x36, 0x32, 0x53,
-+ 0x13, 0x10, 0x17, 0x11, 0x16, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0x00, 0xf8, 0xe8, 0xa8, 0xe8, 0xf8,
-+ 0xf0, 0x40, 0xfc, 0xf0, 0x4c, 0x40, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x1b, 0x36, 0x37, 0x33, 0x50,
-+ 0x17, 0x10, 0x13, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xfc, 0x48, 0x58, 0x58, 0x40,
-+ 0xfc, 0x80, 0xf8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x11, 0x0f, 0x49, 0x21, 0x27, 0x0f, 0x15, 0x15,
-+ 0x26, 0x24, 0x01, 0x24, 0x24, 0x43, 0x00, 0x00,
-+ 0x10, 0xfc, 0x10, 0xf0, 0xfc, 0x74, 0x54, 0x54,
-+ 0xec, 0x44, 0x00, 0x88, 0x24, 0xe4, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x11, 0x3f, 0x3d, 0x35, 0x57,
-+ 0x13, 0x13, 0x15, 0x19, 0x11, 0x11, 0x00, 0x00,
-+ 0x00, 0x3c, 0xd4, 0x14, 0xec, 0x7c, 0x64, 0xfc,
-+ 0x24, 0xbc, 0x64, 0x7c, 0x28, 0x44, 0x00, 0x00,
-+ 0x12, 0x12, 0x13, 0x1d, 0x38, 0x3f, 0x32, 0x56,
-+ 0x12, 0x16, 0x12, 0x16, 0x13, 0x1e, 0x00, 0x00,
-+ 0xa0, 0xb0, 0xe8, 0x68, 0x20, 0xfc, 0xa0, 0xe8,
-+ 0xa8, 0xd0, 0xd4, 0xac, 0xcc, 0x04, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x19, 0x3f, 0x32, 0x36, 0x52,
-+ 0x16, 0x12, 0x16, 0x12, 0x13, 0x1e, 0x00, 0x00,
-+ 0x20, 0x30, 0xe8, 0x28, 0xfc, 0xa0, 0xe8, 0xa8,
-+ 0xd8, 0x90, 0xd4, 0xac, 0xcc, 0x04, 0x00, 0x00,
-+ 0x10, 0x7c, 0x13, 0x38, 0x7c, 0x45, 0x7e, 0x00,
-+ 0x3c, 0x24, 0x3d, 0x25, 0x1e, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa8, 0x30, 0x30, 0x48, 0xc4,
-+ 0x20, 0x20, 0x48, 0x44, 0x54, 0x30, 0x00, 0x00,
-+ 0x11, 0x17, 0x11, 0x1b, 0x36, 0x37, 0x31, 0x51,
-+ 0x13, 0x15, 0x19, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x10, 0xfc, 0x10, 0xb8, 0xa8, 0xb8, 0x20, 0xfc,
-+ 0x20, 0xf8, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x1b, 0x37, 0x36, 0x33, 0x51,
-+ 0x11, 0x13, 0x15, 0x19, 0x11, 0x11, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0xb8, 0xa8, 0xb8, 0x20,
-+ 0xfc, 0x20, 0xf8, 0xf8, 0x20, 0xfc, 0x00, 0x00,
-+ 0x10, 0x13, 0x11, 0x19, 0x35, 0x37, 0x30, 0x57,
-+ 0x12, 0x13, 0x13, 0x12, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x10, 0xf0, 0xf0, 0xf8, 0x10, 0xfc,
-+ 0xa8, 0xb8, 0xb8, 0xac, 0xf8, 0x88, 0x00, 0x00,
-+ 0x13, 0x1f, 0x68, 0x13, 0x2b, 0x7c, 0x3b, 0x56,
-+ 0x13, 0x01, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x90, 0xd8, 0x68, 0x90, 0xa8, 0x7c, 0xb8, 0xd4,
-+ 0x90, 0x00, 0x88, 0xa4, 0x24, 0xe0, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x03, 0x1c, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x08, 0x08, 0xfc, 0x80, 0x88, 0x88,
-+ 0x50, 0x60, 0xe4, 0x14, 0x0c, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x1f, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x12, 0x14, 0x18, 0x61, 0x06, 0x00, 0x00,
-+ 0x90, 0x88, 0x88, 0xfc, 0x80, 0x88, 0x88, 0x48,
-+ 0x50, 0x30, 0x24, 0x54, 0x8c, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x1f, 0x10, 0x10, 0x18, 0x14,
-+ 0x12, 0x12, 0x10, 0x20, 0x21, 0x46, 0x00, 0x00,
-+ 0x90, 0x88, 0x88, 0xfc, 0x80, 0x88, 0x88, 0x48,
-+ 0x50, 0x30, 0x24, 0x54, 0x8c, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x1f, 0x10, 0x10, 0x10, 0x10,
-+ 0x1f, 0x10, 0x10, 0x20, 0x21, 0x46, 0x00, 0x00,
-+ 0x90, 0x88, 0x88, 0xfc, 0x80, 0x88, 0x88, 0x48,
-+ 0x50, 0x30, 0x24, 0x54, 0x8c, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x00, 0x00, 0x01, 0x1e, 0x01,
-+ 0x7f, 0x00, 0x00, 0x00, 0x07, 0x38, 0x00, 0x00,
-+ 0x20, 0x10, 0xfc, 0x90, 0x64, 0xb4, 0x2c, 0x10,
-+ 0xfc, 0x90, 0x60, 0xe4, 0x1c, 0x04, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x1f, 0x10, 0x1f, 0x1f, 0x10,
-+ 0x1f, 0x01, 0x7f, 0x00, 0x03, 0x3c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0xf0, 0x10,
-+ 0xf0, 0x08, 0xfc, 0xb0, 0xe4, 0x1c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x0f, 0x08, 0x0f, 0x0f, 0x08,
-+ 0x3f, 0x21, 0x5f, 0x00, 0x03, 0x3c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xe0, 0x20, 0xe0, 0xe0, 0x20,
-+ 0xfc, 0x28, 0xf8, 0xa0, 0xe4, 0x1c, 0x00, 0x00,
-+ 0x12, 0x12, 0x7f, 0x12, 0x1e, 0x12, 0x1e, 0x12,
-+ 0x7f, 0x2a, 0x2b, 0x31, 0x20, 0x1f, 0x00, 0x00,
-+ 0x28, 0x24, 0xa4, 0x3c, 0xe0, 0x28, 0x28, 0x28,
-+ 0xb0, 0x10, 0x34, 0x4c, 0x8c, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x3f, 0x04, 0x7f, 0x12, 0x1f, 0x32,
-+ 0x3f, 0x52, 0x1f, 0x12, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x48, 0xfc, 0x40, 0xa8, 0x28,
-+ 0xb8, 0x10, 0x94, 0x2c, 0xcc, 0x04, 0x00, 0x00,
-+ 0x00, 0x7f, 0x19, 0x2a, 0x5d, 0x2a, 0x4c, 0x16,
-+ 0x69, 0x34, 0x09, 0x32, 0x0c, 0x70, 0x00, 0x00,
-+ 0x30, 0xa8, 0xa8, 0xa0, 0xbc, 0xe0, 0xa8, 0x28,
-+ 0x10, 0x10, 0x34, 0x4c, 0x8c, 0x04, 0x00, 0x00,
-+ 0x00, 0x77, 0x55, 0x77, 0x00, 0x3e, 0x2a, 0x3e,
-+ 0x2a, 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x00, 0x00,
-+ 0x30, 0x28, 0x28, 0x20, 0x3c, 0xe0, 0x28, 0x28,
-+ 0x18, 0x10, 0x34, 0x4c, 0x8c, 0x04, 0x00, 0x00,
-+ 0x04, 0x07, 0x3f, 0x2b, 0x3d, 0x27, 0x3f, 0x20,
-+ 0x2f, 0x29, 0x2f, 0x2a, 0x27, 0x5c, 0x00, 0x00,
-+ 0x30, 0x28, 0xa8, 0x20, 0x3c, 0xe0, 0x28, 0x28,
-+ 0x18, 0x10, 0x34, 0x4c, 0x8c, 0x04, 0x00, 0x00,
-+ 0x00, 0x7f, 0x19, 0x2a, 0x5d, 0x2a, 0x5a, 0x1f,
-+ 0x24, 0x7f, 0x24, 0x3f, 0x24, 0x3f, 0x00, 0x00,
-+ 0x30, 0xa8, 0xa8, 0xa0, 0xbc, 0xe0, 0xa8, 0xa8,
-+ 0x18, 0x10, 0x14, 0x2c, 0x4c, 0x84, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f,
-+ 0x19, 0x19, 0x2f, 0x29, 0x49, 0x09, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0x00, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x14,
-+ 0x18, 0x70, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-+ 0x80, 0x80, 0x84, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x11, 0x10, 0x7c, 0x10, 0x10, 0x13, 0x14,
-+ 0x18, 0x70, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x11, 0x11, 0x11, 0x15,
-+ 0x19, 0x71, 0x11, 0x11, 0x11, 0x31, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0xf8, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x14,
-+ 0x18, 0x70, 0x10, 0x10, 0x1f, 0x30, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x11, 0x11, 0x10, 0x14,
-+ 0x18, 0x70, 0x10, 0x11, 0x12, 0x34, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x48, 0x28, 0x30, 0x90, 0xa0,
-+ 0x60, 0x40, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x10, 0x12, 0x11, 0x14,
-+ 0x18, 0x70, 0x11, 0x11, 0x12, 0x34, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
-+ 0xd0, 0xb0, 0x1c, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x12, 0x12, 0x12, 0x16,
-+ 0x1a, 0x72, 0x12, 0x14, 0x14, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x88, 0x88, 0x88,
-+ 0x88, 0xb0, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7c, 0x10, 0x10, 0x13, 0x14,
-+ 0x18, 0x70, 0x10, 0x10, 0x17, 0x30, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x40, 0x40, 0xf8, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x10, 0x10, 0x10, 0x17,
-+ 0x18, 0x70, 0x11, 0x12, 0x14, 0x38, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf0, 0x90, 0x90, 0x90, 0xfc,
-+ 0x80, 0xc0, 0x40, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x10, 0x13, 0x10, 0x14,
-+ 0x18, 0x70, 0x10, 0x10, 0x13, 0x30, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0x40, 0x7c, 0xc8, 0x48, 0x50,
-+ 0x30, 0x20, 0x54, 0x94, 0x0c, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x10, 0x17, 0x10, 0x14,
-+ 0x18, 0x70, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0xf8, 0x90, 0x60, 0x40, 0xfc, 0x48, 0x50,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x11, 0x11, 0x11, 0x15,
-+ 0x19, 0x71, 0x12, 0x12, 0x14, 0x38, 0x00, 0x00,
-+ 0x08, 0x30, 0xd0, 0x50, 0x50, 0x50, 0x50, 0x50,
-+ 0x50, 0x50, 0x50, 0x48, 0x48, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x10, 0x11, 0x10, 0x14,
-+ 0x18, 0x70, 0x13, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x90, 0x50, 0x50, 0x10, 0x10, 0x90, 0x90,
-+ 0x1c, 0x70, 0x90, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x10, 0x10, 0x10, 0x15,
-+ 0x19, 0x71, 0x12, 0x12, 0x14, 0x39, 0x00, 0x00,
-+ 0x90, 0x88, 0x88, 0xfc, 0x80, 0x90, 0x90, 0xd0,
-+ 0x50, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x10, 0x10, 0x10, 0x14,
-+ 0x18, 0x70, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x60, 0x50,
-+ 0x48, 0x48, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x15,
-+ 0x1a, 0x70, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x60, 0x60, 0xd0, 0x48,
-+ 0x44, 0x44, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x16, 0x12, 0x12, 0x15,
-+ 0x19, 0x72, 0x12, 0x1f, 0x10, 0x30, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x78, 0xa8, 0xa8, 0x28,
-+ 0x28, 0xa8, 0xa8, 0xc8, 0x48, 0x98, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7f, 0x11, 0x11, 0x11, 0x15,
-+ 0x19, 0x71, 0x11, 0x11, 0x11, 0x31, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0xfc, 0x10, 0x10, 0x10, 0xf0,
-+ 0x10, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x12, 0x12, 0x13, 0x16,
-+ 0x1a, 0x73, 0x12, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0xf8, 0x48,
-+ 0x48, 0xf8, 0x48, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x7f, 0x12, 0x12, 0x3c, 0x06, 0x19, 0x60,
-+ 0x0f, 0x1f, 0x01, 0x3f, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x50, 0x20, 0xd0, 0x0c, 0xe0,
-+ 0x00, 0xf0, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x02, 0x0f, 0x70, 0x0f, 0x08, 0x0f, 0x01,
-+ 0x0f, 0x1f, 0x01, 0x7f, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0x80, 0xe0, 0x1c, 0xe0, 0x20, 0xe0, 0xc0,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x12, 0x13, 0x12, 0x16,
-+ 0x1a, 0x72, 0x12, 0x14, 0x14, 0x38, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x00, 0x00, 0xfc, 0x20, 0xa0,
-+ 0x60, 0x30, 0x28, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7f, 0x12, 0x12, 0x13, 0x16,
-+ 0x1a, 0x72, 0x12, 0x14, 0x14, 0x38, 0x00, 0x00,
-+ 0x40, 0xf0, 0x20, 0xfc, 0xa4, 0x9c, 0x70, 0xf8,
-+ 0x70, 0x70, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x14,
-+ 0x1b, 0x72, 0x12, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x02, 0x05, 0x38, 0x08, 0x08, 0x3e, 0x08, 0x08,
-+ 0x0e, 0x79, 0x08, 0x10, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xf8, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x12, 0x11, 0x10, 0x14,
-+ 0x1b, 0x70, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0x50, 0x48, 0x48, 0xf0, 0x40, 0x40,
-+ 0xfc, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7d, 0x13, 0x12, 0x16, 0x16,
-+ 0x1a, 0x72, 0x12, 0x12, 0x12, 0x32, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0xfc, 0x10, 0x90, 0x50,
-+ 0x50, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x10, 0x13, 0x12, 0x16,
-+ 0x1b, 0x70, 0x10, 0x10, 0x11, 0x32, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xf8, 0xa8, 0xa8, 0xf8, 0xa0, 0xa0,
-+ 0xfc, 0xa4, 0xa4, 0xb8, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x11, 0x11, 0x17, 0x16,
-+ 0x1a, 0x72, 0x12, 0x13, 0x12, 0x30, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x48, 0x28, 0x28, 0xfc, 0x08,
-+ 0x88, 0x48, 0x48, 0xfc, 0x08, 0x30, 0x00, 0x00,
-+ 0x12, 0x12, 0x12, 0x7e, 0x17, 0x12, 0x12, 0x16,
-+ 0x1a, 0x72, 0x12, 0x14, 0x14, 0x38, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x78, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xc8, 0x98, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x10, 0x12, 0x11, 0x15,
-+ 0x18, 0x70, 0x10, 0x10, 0x17, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x10, 0x10, 0x10, 0x10,
-+ 0xa0, 0xa0, 0xa0, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x13, 0x14, 0x10, 0x14,
-+ 0x19, 0x77, 0x11, 0x11, 0x11, 0x31, 0x00, 0x00,
-+ 0x80, 0x80, 0xf0, 0x10, 0x20, 0xa0, 0x40, 0xa0,
-+ 0xf8, 0x14, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x10, 0x10, 0x11, 0x14,
-+ 0x19, 0x71, 0x11, 0x11, 0x11, 0x31, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7d, 0x17, 0x11, 0x11, 0x15,
-+ 0x19, 0x77, 0x11, 0x11, 0x12, 0x34, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xf8, 0x20, 0x20, 0x20,
-+ 0x20, 0xfc, 0x20, 0x10, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7d, 0x11, 0x12, 0x14, 0x15,
-+ 0x19, 0x72, 0x14, 0x10, 0x10, 0x31, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x98, 0x98, 0xa8, 0xc8, 0x98,
-+ 0x98, 0xa8, 0xc8, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x10, 0x17, 0x10, 0x14,
-+ 0x1b, 0x70, 0x10, 0x10, 0x17, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x0a, 0x0d, 0x3a, 0x0c, 0x3a, 0x0c, 0x39, 0x00,
-+ 0x0f, 0x1f, 0x01, 0x7f, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x88, 0x30, 0xe0,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x10, 0x7c, 0x13, 0x10, 0x10, 0x15,
-+ 0x19, 0x72, 0x14, 0x10, 0x17, 0x30, 0x00, 0x00,
-+ 0x00, 0xf0, 0x20, 0x40, 0xc8, 0xe8, 0xf0, 0x50,
-+ 0x50, 0x48, 0x44, 0xc0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x11, 0x11, 0x12, 0x16,
-+ 0x1a, 0x73, 0x12, 0x12, 0x12, 0x32, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x00, 0xf8, 0x08, 0x10,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x13, 0x10, 0x13, 0x16,
-+ 0x1b, 0x72, 0x13, 0x12, 0x12, 0x32, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x00, 0xf8, 0x08,
-+ 0xf8, 0x08, 0xf8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x11, 0x11, 0x11, 0x16,
-+ 0x1a, 0x70, 0x10, 0x10, 0x11, 0x36, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x50, 0x50, 0x58, 0xe4,
-+ 0x44, 0x60, 0xa0, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x13, 0x10, 0x17,
-+ 0x18, 0x70, 0x17, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x00, 0xf8,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x11, 0x12, 0x12, 0x7f, 0x12, 0x12, 0x13, 0x10,
-+ 0x1f, 0x71, 0x10, 0x10, 0x11, 0x36, 0x00, 0x00,
-+ 0x40, 0x58, 0x48, 0x58, 0x48, 0x48, 0xf8, 0x40,
-+ 0xf8, 0x10, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x13, 0x12, 0x10,
-+ 0x18, 0x73, 0x10, 0x10, 0x17, 0x30, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x40,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7d, 0x11, 0x11, 0x12, 0x16,
-+ 0x1a, 0x72, 0x12, 0x12, 0x12, 0x33, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x20, 0x20, 0x38, 0x48, 0x68,
-+ 0x98, 0x50, 0x30, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x10, 0x11, 0x13, 0x14,
-+ 0x19, 0x71, 0x11, 0x11, 0x11, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x90, 0x10, 0xfc, 0x08,
-+ 0xe8, 0x28, 0x28, 0xe8, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x11, 0x16, 0x7c, 0x14, 0x17, 0x15, 0x15,
-+ 0x1d, 0x75, 0x15, 0x19, 0x19, 0x31, 0x00, 0x00,
-+ 0xc0, 0x40, 0x40, 0x40, 0x7c, 0xa4, 0xa8, 0x20,
-+ 0x20, 0x30, 0x50, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x17, 0x12, 0x7e, 0x13, 0x12, 0x12, 0x17,
-+ 0x1a, 0x72, 0x13, 0x16, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xf8, 0xc8, 0xc8, 0xa8,
-+ 0xb0, 0x90, 0xb0, 0xc8, 0x88, 0x84, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7f, 0x11, 0x11, 0x17, 0x11,
-+ 0x19, 0x73, 0x10, 0x10, 0x17, 0x30, 0x00, 0x00,
-+ 0x18, 0xe0, 0x40, 0xf8, 0x50, 0x50, 0xfc, 0x50,
-+ 0x50, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x28, 0x3e, 0x48, 0x7f, 0x08, 0x3e, 0x2a, 0x2e,
-+ 0x07, 0x1f, 0x01, 0x7f, 0x01, 0x03, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x08, 0xd8,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7e, 0x15, 0x11, 0x12, 0x17,
-+ 0x18, 0x72, 0x12, 0x13, 0x12, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x08, 0x08, 0xe8, 0x88, 0xe8,
-+ 0x88, 0xa8, 0xa8, 0xe8, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x13, 0x12, 0x13, 0x16,
-+ 0x1b, 0x70, 0x17, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0x40, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x14, 0x17, 0x10, 0x16,
-+ 0x1a, 0x72, 0x12, 0x13, 0x14, 0x38, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0x00, 0xfc, 0x40, 0x40,
-+ 0x78, 0x40, 0x40, 0x40, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x13, 0x14, 0x13, 0x16,
-+ 0x1a, 0x72, 0x13, 0x12, 0x10, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xb8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0x30, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x13, 0x12, 0x16,
-+ 0x1a, 0x72, 0x12, 0x12, 0x12, 0x32, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0xa8, 0xb8, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7f, 0x12, 0x13, 0x12, 0x1e,
-+ 0x73, 0x12, 0x14, 0x14, 0x1b, 0x3c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0x48, 0x40,
-+ 0xfc, 0x40, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x10, 0x17, 0x10, 0x14,
-+ 0x1b, 0x70, 0x13, 0x10, 0x13, 0x30, 0x00, 0x00,
-+ 0x80, 0xf0, 0x90, 0xe0, 0x20, 0xfc, 0x40, 0xe8,
-+ 0x68, 0xb0, 0x70, 0xa8, 0x24, 0xc0, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7d, 0x11, 0x11, 0x16, 0x10,
-+ 0x19, 0x71, 0x11, 0x11, 0x11, 0x31, 0x00, 0x00,
-+ 0x20, 0x24, 0xf8, 0x20, 0x20, 0xe4, 0x5c, 0x80,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x7c, 0x13, 0x13, 0x12, 0x16,
-+ 0x1b, 0x70, 0x11, 0x12, 0x14, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x58, 0xd8, 0xe8,
-+ 0xf8, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x11, 0x10, 0x12, 0x7d, 0x11, 0x12, 0x11, 0x14,
-+ 0x18, 0x73, 0x10, 0x10, 0x11, 0x36, 0x00, 0x00,
-+ 0xd0, 0x54, 0xa4, 0xa8, 0x10, 0x08, 0xf4, 0x40,
-+ 0x40, 0xf8, 0xa0, 0x90, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x12, 0x12, 0x7e, 0x13, 0x10, 0x17, 0x10,
-+ 0x1b, 0x72, 0x12, 0x12, 0x12, 0x32, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0x48, 0xf8, 0x00, 0xfc, 0x40,
-+ 0xf8, 0xa8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x17, 0x10, 0x13, 0x14,
-+ 0x18, 0x77, 0x10, 0x11, 0x16, 0x30, 0x00, 0x00,
-+ 0x00, 0xf0, 0xa0, 0x40, 0xfc, 0xc8, 0x50, 0xc0,
-+ 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x10, 0x17, 0x11, 0x12,
-+ 0x1a, 0x73, 0x12, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x40, 0x40, 0xfc, 0x40, 0x58,
-+ 0x48, 0x58, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x17, 0x12, 0x7e, 0x13, 0x12, 0x12, 0x17,
-+ 0x1a, 0x72, 0x13, 0x16, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xb0, 0xb0, 0xa8, 0xa8,
-+ 0xa4, 0xa4, 0xa4, 0xb8, 0xa0, 0xa0, 0x00, 0x00,
-+ 0x11, 0x10, 0x10, 0x7d, 0x13, 0x14, 0x17, 0x14,
-+ 0x1e, 0x75, 0x16, 0x15, 0x14, 0x35, 0x00, 0x00,
-+ 0xc0, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xa8, 0xa8,
-+ 0xa8, 0xd0, 0xd0, 0xa8, 0xa8, 0xa8, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7e, 0x11, 0x11, 0x17, 0x12,
-+ 0x1f, 0x30, 0x52, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x80, 0xf0, 0x90, 0x60, 0x40, 0x80, 0xf8, 0x40,
-+ 0xfc, 0x40, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x3f, 0x22, 0x5f, 0x0f, 0x02, 0x3f, 0x08,
-+ 0x17, 0x6f, 0x01, 0x3f, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0xf0, 0xe0, 0x80, 0xf8, 0xe0,
-+ 0x10, 0xec, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7f, 0x10, 0x17, 0x10, 0x17,
-+ 0x1a, 0x77, 0x12, 0x17, 0x12, 0x32, 0x00, 0x00,
-+ 0xa0, 0xfc, 0xa0, 0xf8, 0xa0, 0xfc, 0x40, 0xf8,
-+ 0x48, 0xfc, 0x48, 0xfc, 0x08, 0x18, 0x00, 0x00,
-+ 0x11, 0x10, 0x13, 0x7c, 0x11, 0x10, 0x17, 0x11,
-+ 0x19, 0x72, 0x14, 0x18, 0x17, 0x30, 0x00, 0x00,
-+ 0x10, 0xa0, 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0x00,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x13, 0x12, 0x12, 0x17,
-+ 0x19, 0x72, 0x15, 0x12, 0x14, 0x33, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xb8, 0x20, 0x20, 0xb8,
-+ 0x98, 0xa8, 0xd8, 0xa8, 0xc8, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x12, 0x15, 0x11, 0x15,
-+ 0x19, 0x71, 0x11, 0x13, 0x15, 0x31, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xf0, 0x08, 0xf4, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x00, 0xf8, 0x08, 0xf8, 0x00, 0x00,
-+ 0x10, 0x17, 0x11, 0x7d, 0x11, 0x17, 0x10, 0x17,
-+ 0x1a, 0x73, 0x13, 0x12, 0x17, 0x30, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0xf0, 0xf0, 0xfc, 0x10, 0xfc,
-+ 0xa8, 0xb8, 0xb8, 0xac, 0xf8, 0x88, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x11, 0x11, 0x11, 0x15,
-+ 0x19, 0x71, 0x11, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x00,
-+ 0xfc, 0x00, 0xfc, 0xa4, 0xe4, 0x18, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x13, 0x10, 0x17,
-+ 0x19, 0x72, 0x15, 0x12, 0x14, 0x31, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x98, 0xa8, 0xd8, 0xa8, 0xc8, 0x98, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7f, 0x12, 0x13, 0x12, 0x17,
-+ 0x1a, 0x70, 0x17, 0x11, 0x10, 0x30, 0x00, 0x00,
-+ 0x50, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x48, 0x10, 0xfc, 0x10, 0x90, 0x30, 0x00, 0x00,
-+ 0x10, 0x12, 0x12, 0x7f, 0x12, 0x10, 0x11, 0x15,
-+ 0x1b, 0x75, 0x11, 0x11, 0x11, 0x31, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0xf8, 0x98, 0xa0, 0xfc, 0x20,
-+ 0xf8, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x3e, 0x08, 0x7f, 0x14, 0x7f, 0x3f, 0x08,
-+ 0x07, 0x1f, 0x01, 0x7f, 0x01, 0x03, 0x00, 0x00,
-+ 0x40, 0x40, 0xf0, 0x50, 0xd4, 0xb4, 0x0c, 0x60,
-+ 0x80, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7f, 0x12, 0x13, 0x12, 0x17,
-+ 0x18, 0x73, 0x10, 0x17, 0x11, 0x30, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x50, 0xf8, 0x10, 0xfc, 0x10, 0xb0, 0x00, 0x00,
-+ 0x10, 0x17, 0x11, 0x7a, 0x15, 0x12, 0x14, 0x11,
-+ 0x1e, 0x71, 0x10, 0x11, 0x10, 0x33, 0x00, 0x00,
-+ 0x00, 0xf8, 0x98, 0xa8, 0xd8, 0xa8, 0xc8, 0x20,
-+ 0x50, 0xac, 0x48, 0x90, 0x60, 0x80, 0x00, 0x00,
-+ 0x11, 0x12, 0x13, 0x7f, 0x12, 0x17, 0x15, 0x1d,
-+ 0x71, 0x11, 0x11, 0x11, 0x11, 0x36, 0x00, 0x00,
-+ 0xb8, 0x68, 0xb8, 0x78, 0xa8, 0xfc, 0xf8, 0x10,
-+ 0xf0, 0xf0, 0x10, 0xf0, 0xa4, 0x3c, 0x00, 0x00,
-+ 0x12, 0x12, 0x12, 0x7f, 0x12, 0x13, 0x12, 0x17,
-+ 0x1a, 0x77, 0x13, 0x12, 0x14, 0x38, 0x00, 0x00,
-+ 0x84, 0x88, 0xb0, 0xe0, 0xa0, 0xbc, 0xa8, 0xa8,
-+ 0xa8, 0xe8, 0x28, 0xc8, 0x48, 0x88, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7f, 0x11, 0x17, 0x11, 0x11,
-+ 0x1e, 0x73, 0x10, 0x10, 0x11, 0x36, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xfc, 0x10, 0xfc, 0x10, 0xfc,
-+ 0x00, 0xf8, 0xa0, 0xa0, 0x24, 0x1c, 0x00, 0x00,
-+ 0x11, 0x12, 0x11, 0x7d, 0x12, 0x17, 0x11, 0x17,
-+ 0x1c, 0x77, 0x15, 0x11, 0x11, 0x36, 0x00, 0x00,
-+ 0xd0, 0x54, 0xa4, 0x18, 0x08, 0x74, 0x50, 0x54,
-+ 0x8c, 0xf8, 0x48, 0x30, 0x28, 0xc4, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x13, 0x17, 0x11, 0x15,
-+ 0x19, 0x71, 0x11, 0x12, 0x14, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa4, 0x18, 0xf8, 0x14, 0xf0,
-+ 0x10, 0xf0, 0x50, 0x48, 0x48, 0xc0, 0x00, 0x00,
-+ 0x11, 0x15, 0x13, 0x79, 0x12, 0x14, 0x13, 0x12,
-+ 0x1c, 0x73, 0x10, 0x10, 0x11, 0x32, 0x00, 0x00,
-+ 0x10, 0x54, 0xb4, 0x18, 0xa8, 0x44, 0xfc, 0x48,
-+ 0x40, 0xf8, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x13, 0x12, 0x13, 0x17,
-+ 0x1b, 0x74, 0x12, 0x12, 0x14, 0x30, 0x00, 0x00,
-+ 0x28, 0x24, 0xfc, 0x20, 0xe8, 0x28, 0xd0, 0x54,
-+ 0xec, 0x44, 0xa8, 0xa4, 0x94, 0x70, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x13, 0x12, 0x13, 0x16,
-+ 0x1b, 0x72, 0x13, 0x14, 0x15, 0x38, 0x00, 0x00,
-+ 0x40, 0x78, 0xfc, 0x78, 0xc8, 0x38, 0xfc, 0x68,
-+ 0xb8, 0x70, 0xb8, 0x58, 0x94, 0x60, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7f, 0x12, 0x12, 0x13, 0x17,
-+ 0x18, 0x77, 0x14, 0x15, 0x14, 0x34, 0x00, 0x00,
-+ 0x40, 0xa0, 0x58, 0xfc, 0xa8, 0x68, 0x98, 0xf8,
-+ 0x40, 0xfc, 0xa4, 0xf4, 0x14, 0x0c, 0x00, 0x00,
-+ 0x10, 0x17, 0x13, 0x7e, 0x12, 0x12, 0x13, 0x15,
-+ 0x19, 0x71, 0x11, 0x11, 0x17, 0x30, 0x00, 0x00,
-+ 0x40, 0xfc, 0xf8, 0xe8, 0xa8, 0xe8, 0xf8, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x10, 0x13, 0x10, 0x17,
-+ 0x19, 0x77, 0x10, 0x13, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xf8, 0x40, 0xf8, 0x40, 0xfc,
-+ 0x10, 0xfc, 0x40, 0xf8, 0x40, 0x40, 0x00, 0x00,
-+ 0x14, 0x12, 0x12, 0x79, 0x14, 0x12, 0x13, 0x10,
-+ 0x1e, 0x72, 0x13, 0x12, 0x15, 0x38, 0x00, 0x00,
-+ 0x20, 0xf8, 0x20, 0xfc, 0x88, 0x50, 0xfc, 0x20,
-+ 0xf8, 0x20, 0xfc, 0x20, 0x20, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3f, 0x20, 0x3e, 0x52, 0x1e,
-+ 0x07, 0x1f, 0x01, 0x7f, 0x01, 0x03, 0x00, 0x00,
-+ 0x20, 0xf8, 0x50, 0xfc, 0x20, 0xf8, 0x20, 0xe0,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7f, 0x12, 0x17, 0x13, 0x10,
-+ 0x1b, 0x72, 0x13, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xfc, 0x48, 0x58, 0x58, 0x40,
-+ 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x13, 0x12, 0x16,
-+ 0x1b, 0x72, 0x13, 0x12, 0x12, 0x32, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0xa8, 0xb8, 0x88, 0xe8,
-+ 0xa8, 0x48, 0xf8, 0xa8, 0xe8, 0x18, 0x00, 0x00,
-+ 0x0a, 0x13, 0x1a, 0x13, 0x18, 0x12, 0x7f, 0x08,
-+ 0x17, 0x6f, 0x01, 0x3f, 0x01, 0x03, 0x00, 0x00,
-+ 0x30, 0x90, 0x30, 0x90, 0xb0, 0x90, 0xfc, 0xe0,
-+ 0x10, 0xec, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x06, 0x1b, 0x12, 0x1b, 0x12, 0x1a, 0x12, 0x7f,
-+ 0x09, 0x17, 0x61, 0x1f, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xb0, 0x10, 0xb0, 0x90, 0xb0, 0x90, 0xfc,
-+ 0x20, 0xd0, 0x0c, 0xf0, 0x00, 0x00, 0x00, 0x00,
-+ 0x20, 0x2f, 0x21, 0x7e, 0x2a, 0x2a, 0x36, 0x22,
-+ 0x33, 0x62, 0x23, 0x22, 0x24, 0x68, 0x00, 0x00,
-+ 0x80, 0xfc, 0x48, 0xb8, 0xa8, 0xa8, 0xb4, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7f, 0x11, 0x11, 0x11, 0x17,
-+ 0x1d, 0x70, 0x11, 0x10, 0x11, 0x37, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0xf0, 0x10, 0xf0, 0xfc,
-+ 0xf8, 0x90, 0xf8, 0x40, 0xf0, 0xfc, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x10, 0x11, 0x17, 0x14,
-+ 0x19, 0x71, 0x11, 0x11, 0x11, 0x31, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x90, 0x88, 0x1c, 0xe4, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7d, 0x10, 0x17, 0x11, 0x14,
-+ 0x19, 0x77, 0x13, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x00, 0xfc, 0xe8, 0x40,
-+ 0xf0, 0xfc, 0x88, 0xfc, 0xa8, 0x18, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x14, 0x11, 0x17,
-+ 0x19, 0x71, 0x11, 0x11, 0x11, 0x36, 0x00, 0x00,
-+ 0x40, 0xfc, 0x08, 0xf8, 0x58, 0xe4, 0xf4, 0x10,
-+ 0xf0, 0xf0, 0x10, 0xf0, 0x90, 0x08, 0x00, 0x00,
-+ 0x20, 0x2f, 0x2a, 0x7f, 0x2f, 0x2a, 0x2f, 0x2b,
-+ 0x32, 0x63, 0x23, 0x23, 0x21, 0x6e, 0x00, 0x00,
-+ 0x40, 0xfc, 0x80, 0x78, 0xfc, 0xb4, 0xfc, 0xf0,
-+ 0x10, 0xf0, 0xf0, 0xf4, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x14, 0x17, 0x15, 0x79, 0x10, 0x17, 0x10, 0x17,
-+ 0x1c, 0x77, 0x14, 0x17, 0x14, 0x35, 0x00, 0x00,
-+ 0x20, 0xfc, 0x50, 0x18, 0xa0, 0xfc, 0x00, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0x88, 0x98, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x13, 0x12, 0x16,
-+ 0x1a, 0x72, 0x12, 0x14, 0x14, 0x3b, 0x00, 0x00,
-+ 0x40, 0xfc, 0x90, 0xfc, 0xf0, 0xfc, 0x20, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0xf8, 0xc8, 0x04, 0x00, 0x00,
-+ 0x24, 0x27, 0x2b, 0x7f, 0x2b, 0x2d, 0x2f, 0x28,
-+ 0x3f, 0x62, 0x2f, 0x23, 0x24, 0x68, 0x00, 0x00,
-+ 0x80, 0xf8, 0x68, 0xe8, 0x70, 0xf0, 0xe8, 0x68,
-+ 0xe4, 0x24, 0xe4, 0x38, 0xa0, 0x20, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x14, 0x1f, 0x10,
-+ 0x1f, 0x74, 0x17, 0x17, 0x14, 0x35, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xf8, 0x20, 0xa8, 0xf0, 0x64,
-+ 0x9c, 0xa0, 0xa8, 0xb0, 0xa4, 0x9c, 0x00, 0x00,
-+ 0x10, 0x13, 0x7d, 0x1a, 0x36, 0x51, 0x13, 0x7f,
-+ 0x05, 0x1f, 0x6f, 0x3f, 0x01, 0x03, 0x00, 0x00,
-+ 0x90, 0x90, 0x7c, 0xb0, 0xd8, 0x94, 0x50, 0xfc,
-+ 0xc0, 0x30, 0xec, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x12, 0x12, 0x15, 0x7d, 0x12, 0x13, 0x15, 0x17,
-+ 0x18, 0x77, 0x10, 0x11, 0x16, 0x30, 0x00, 0x00,
-+ 0x48, 0x48, 0xf4, 0xb4, 0xe8, 0xac, 0xb4, 0xfc,
-+ 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x10, 0x17, 0x13, 0x7a, 0x13, 0x10, 0x13, 0x11,
-+ 0x18, 0x77, 0x10, 0x17, 0x11, 0x33, 0x00, 0x00,
-+ 0x40, 0xfc, 0xb8, 0xa8, 0xb8, 0xa0, 0xf8, 0xf0,
-+ 0xa0, 0xfc, 0xc8, 0x30, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x12, 0x13, 0x11, 0x7f, 0x12, 0x17, 0x13, 0x12,
-+ 0x1b, 0x77, 0x15, 0x17, 0x15, 0x35, 0x00, 0x00,
-+ 0x48, 0xf8, 0x20, 0xf8, 0x40, 0xf0, 0xf0, 0x40,
-+ 0xf8, 0xf8, 0x58, 0xf8, 0x48, 0xd8, 0x00, 0x00,
-+ 0x11, 0x17, 0x11, 0x7f, 0x11, 0x12, 0x15, 0x1d,
-+ 0x71, 0x11, 0x11, 0x11, 0x11, 0x36, 0x00, 0x00,
-+ 0x20, 0xf8, 0x20, 0xfc, 0xb0, 0x48, 0xf4, 0x10,
-+ 0xf0, 0xf0, 0x10, 0xf0, 0x90, 0x08, 0x00, 0x00,
-+ 0x25, 0x2f, 0x25, 0x7f, 0x2f, 0x2a, 0x2f, 0x22,
-+ 0x3f, 0x62, 0x2f, 0x23, 0x24, 0x68, 0x00, 0x00,
-+ 0x28, 0xa8, 0x28, 0x7c, 0xd0, 0xd0, 0xfc, 0x50,
-+ 0xd0, 0x7c, 0xd0, 0x50, 0xfc, 0x40, 0x00, 0x00,
-+ 0x13, 0x6f, 0x2b, 0x17, 0x7c, 0x3b, 0x56, 0x13,
-+ 0x0f, 0x1f, 0x01, 0x7f, 0x01, 0x03, 0x00, 0x00,
-+ 0x90, 0xe8, 0xa8, 0x94, 0x7c, 0xb8, 0xd4, 0xe0,
-+ 0x80, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x13, 0x12, 0x13, 0x7f, 0x13, 0x11, 0x13, 0x16,
-+ 0x1a, 0x73, 0x13, 0x10, 0x10, 0x37, 0x00, 0x00,
-+ 0xb8, 0xa8, 0xb8, 0xb8, 0xb8, 0x20, 0xfc, 0xf0,
-+ 0xf0, 0xfc, 0xf0, 0xa0, 0xe0, 0x1c, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x3f, 0x04, 0x02,
-+ 0x02, 0x01, 0x00, 0x03, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf0, 0x10, 0x20,
-+ 0x20, 0x40, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x04, 0x0f, 0x0c, 0x14, 0x22,
-+ 0x02, 0x01, 0x01, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x20, 0x20, 0x40,
-+ 0x40, 0x80, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7e, 0x10, 0x10, 0x11, 0x1d, 0x26, 0x24,
-+ 0x04, 0x04, 0x04, 0x08, 0x08, 0x33, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x10, 0x90, 0x90, 0x50,
-+ 0x60, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x24, 0x25, 0x25, 0x26, 0x24, 0x24,
-+ 0x26, 0x3c, 0x64, 0x04, 0x05, 0x06, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x10, 0x90, 0x90, 0x50,
-+ 0x60, 0x20, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x0c, 0x14, 0x15, 0x35, 0x56, 0x14,
-+ 0x14, 0x14, 0x14, 0x14, 0x10, 0x13, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x10, 0x90, 0x90, 0x50,
-+ 0x60, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x54, 0x55, 0x55, 0x7e, 0x54,
-+ 0x54, 0x54, 0x7c, 0x44, 0x01, 0x06, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x10, 0x90, 0x90, 0x50,
-+ 0x60, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x14, 0x12, 0x26, 0x65, 0x14,
-+ 0x0c, 0x0c, 0x0a, 0x12, 0x20, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0x90, 0x90, 0x90, 0x50,
-+ 0x60, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x3e, 0x08, 0x7f, 0x08, 0x09, 0x7f,
-+ 0x08, 0x0e, 0x12, 0x12, 0x22, 0x4d, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x90, 0x90, 0x50, 0x50,
-+ 0x60, 0x20, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x2b, 0x2a, 0x3e,
-+ 0x1c, 0x1a, 0x2a, 0x48, 0x08, 0x0b, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x90, 0x90, 0x90, 0x50,
-+ 0x60, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x3e, 0x49, 0x08, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x1b, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0x40, 0x40, 0xf8, 0x88, 0x88,
-+ 0x50, 0x50, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x3e, 0x49, 0x0a, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x1b, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x90, 0x90, 0x90, 0x50,
-+ 0x60, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x2a, 0x29, 0x49, 0x08, 0x7f, 0x41, 0x5d,
-+ 0x55, 0x55, 0x5d, 0x55, 0x41, 0x43, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0xc8, 0xc8, 0x48, 0x48,
-+ 0x30, 0x30, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x2a, 0x29, 0x49, 0x08, 0x7f, 0x49, 0x6b,
-+ 0x6b, 0x6b, 0x6b, 0x49, 0x49, 0x43, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0xc8, 0xc8, 0x48, 0x48,
-+ 0x30, 0x30, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x00, 0x3e, 0x22, 0x3e, 0x00,
-+ 0x7f, 0x41, 0x5d, 0x55, 0x5d, 0x43, 0x00, 0x00,
-+ 0x20, 0x20, 0x3c, 0x20, 0x20, 0xf8, 0x48, 0x48,
-+ 0x28, 0x30, 0x10, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x04, 0x3f, 0x25, 0x7f, 0x25, 0x3f, 0x3f, 0x25,
-+ 0x3f, 0x08, 0x7f, 0x12, 0x1e, 0x71, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x48, 0xc8, 0x48, 0x50,
-+ 0x30, 0x20, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x3f, 0x40, 0x77, 0x55,
-+ 0x77, 0x12, 0x12, 0x2d, 0x25, 0x49, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0xc8, 0xc8, 0x28, 0x28,
-+ 0x30, 0x10, 0x30, 0x48, 0x88, 0x04, 0x00, 0x00,
-+ 0x49, 0x2a, 0x7f, 0x49, 0x5d, 0x6b, 0x4b, 0x00,
-+ 0x7f, 0x08, 0x1e, 0x72, 0x0c, 0x70, 0x00, 0x00,
-+ 0x20, 0x20, 0x7c, 0xc8, 0x30, 0x30, 0xcc, 0x00,
-+ 0xfc, 0x88, 0xb0, 0xc4, 0x84, 0x7c, 0x00, 0x00,
-+ 0x13, 0x1f, 0x68, 0x13, 0x2b, 0x7f, 0x3a, 0x57,
-+ 0x12, 0x07, 0x3c, 0x03, 0x0e, 0x70, 0x00, 0x00,
-+ 0x90, 0xd8, 0x68, 0x90, 0xa8, 0xfc, 0xb8, 0xd4,
-+ 0x10, 0xf8, 0x40, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x10, 0x1e, 0x24, 0x7e, 0x2a, 0x2a, 0x3e, 0x2a,
-+ 0x2a, 0x3e, 0x23, 0x22, 0x22, 0x46, 0x00, 0x00,
-+ 0x10, 0x90, 0x50, 0x50, 0x10, 0x90, 0x50, 0x50,
-+ 0x1c, 0x70, 0x90, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x12, 0x12, 0x7f, 0x12, 0x1e, 0x12, 0x1e, 0x12,
-+ 0x7f, 0x2a, 0x2b, 0x33, 0x20, 0x1f, 0x00, 0x00,
-+ 0x10, 0x90, 0x50, 0x50, 0x10, 0x90, 0x50, 0x50,
-+ 0x1c, 0x70, 0x90, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x7f, 0x08, 0x08, 0x08, 0x10, 0x1e, 0x32,
-+ 0x32, 0x52, 0x13, 0x1f, 0x12, 0x10, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x80, 0x80, 0xfc, 0x90, 0x90,
-+ 0x90, 0x90, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x12, 0x5b, 0x6d, 0x52, 0x6d, 0x7f, 0x7f, 0x5b,
-+ 0x6d, 0x52, 0x6d, 0x7f, 0x7f, 0x40, 0x00, 0x00,
-+ 0x08, 0x70, 0x40, 0x40, 0x40, 0x7c, 0x50, 0x50,
-+ 0x50, 0x50, 0x90, 0x90, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x11, 0x12, 0x1c, 0x14,
-+ 0x14, 0x15, 0x24, 0x24, 0x44, 0x18, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x00, 0xf8, 0xa8, 0xa8,
-+ 0xa8, 0xfc, 0x88, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x12, 0x13, 0x1c, 0x14,
-+ 0x14, 0x14, 0x24, 0x24, 0x44, 0x18, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x20, 0x20, 0xfc, 0x20, 0xf8,
-+ 0xa8, 0xa8, 0xa8, 0xb8, 0x20, 0x20, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x04, 0x02, 0x3f, 0x21, 0x41,
-+ 0x3f, 0x01, 0x01, 0x02, 0x0c, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x40, 0x80, 0xfc, 0x08, 0x00,
-+ 0xf8, 0x00, 0xf0, 0x10, 0x10, 0xe0, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x13, 0x10, 0x1c, 0x15,
-+ 0x14, 0x14, 0x27, 0x24, 0x44, 0x18, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x10, 0xe0, 0x40, 0x78, 0xc0,
-+ 0x40, 0x7c, 0xc0, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x11, 0x12, 0x1c, 0x14,
-+ 0x15, 0x14, 0x24, 0x24, 0x45, 0x18, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xa0, 0xa0, 0xf8, 0xa0,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7e, 0x13, 0x10, 0x1c, 0x17,
-+ 0x14, 0x15, 0x25, 0x25, 0x45, 0x1a, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x20, 0xfc, 0x50, 0x98, 0xe8,
-+ 0x10, 0x50, 0x50, 0x54, 0x54, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7e, 0x10, 0x11, 0x1c, 0x14,
-+ 0x17, 0x14, 0x24, 0x24, 0x44, 0x18, 0x00, 0x00,
-+ 0x80, 0xfc, 0x18, 0xe8, 0xb0, 0xfc, 0x70, 0xa8,
-+ 0xfc, 0xa8, 0xf8, 0xa8, 0xf8, 0x88, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7c, 0x13, 0x10, 0x1c, 0x17,
-+ 0x14, 0x14, 0x24, 0x24, 0x44, 0x18, 0x00, 0x00,
-+ 0x18, 0xe8, 0x28, 0xb0, 0xfc, 0x70, 0xa8, 0x24,
-+ 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x01,
-+ 0x01, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x80,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x21, 0x21, 0x21, 0x3f, 0x21,
-+ 0x01, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x80,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x00, 0x3f,
-+ 0x01, 0x01, 0x7f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x10, 0x01,
-+ 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00,
-+ 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x00, 0x7f,
-+ 0x01, 0x3f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xf8, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x00, 0x1f,
-+ 0x10, 0x10, 0x11, 0x21, 0x26, 0x58, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x80, 0x80, 0xc0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x01, 0x7f,
-+ 0x04, 0x04, 0x02, 0x03, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x40, 0x40, 0x80, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x03, 0x05, 0x19, 0x61, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x80, 0x40, 0x30, 0x0c, 0xe0,
-+ 0x20, 0xe0, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4a, 0x4b, 0x4a, 0x7a, 0x4a,
-+ 0x4a, 0x4a, 0x7a, 0x4c, 0x44, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x80, 0x88,
-+ 0x90, 0xe0, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x7e, 0x00, 0x3c, 0x05, 0x05, 0x7e, 0x0e,
-+ 0x0d, 0x15, 0x14, 0x24, 0x44, 0x0c, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0x78, 0x48, 0x48, 0x48,
-+ 0x78, 0x48, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x02, 0x3c,
-+ 0x22, 0x22, 0x2e, 0x72, 0x04, 0x08, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x88, 0x88, 0x88, 0xf0, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x00, 0x7f,
-+ 0x08, 0x0f, 0x12, 0x22, 0x04, 0x09, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x00, 0xfc,
-+ 0x00, 0xf8, 0x48, 0x48, 0x88, 0x30, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x01, 0x3f,
-+ 0x22, 0x7f, 0x04, 0x0f, 0x03, 0x3c, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x08, 0xf8, 0x40, 0x80, 0x60, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x7a, 0x49, 0x49, 0x48, 0x7f, 0x48,
-+ 0x48, 0x48, 0x79, 0x49, 0x02, 0x04, 0x00, 0x00,
-+ 0x40, 0x40, 0x48, 0x48, 0x50, 0x40, 0xfc, 0xa0,
-+ 0xa0, 0xa0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x08, 0x14, 0x3e, 0x02, 0x7f, 0x00,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0x50, 0xf8, 0x08, 0xfc, 0x00,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x02, 0x12,
-+ 0x0a, 0x0a, 0x1c, 0x64, 0x08, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x90, 0x90,
-+ 0xe0, 0xa0, 0x90, 0x94, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x01, 0x78, 0x4b, 0x48, 0x4f, 0x79, 0x4b,
-+ 0x4e, 0x4a, 0x7a, 0x4a, 0x02, 0x00, 0x00, 0x00,
-+ 0x08, 0xd0, 0x70, 0x88, 0x80, 0xfc, 0x40, 0xf8,
-+ 0x48, 0x48, 0x48, 0x48, 0x70, 0x40, 0x00, 0x00,
-+ 0x01, 0x1f, 0x01, 0x7f, 0x1f, 0x0f, 0x01, 0x3f,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x7f, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xfc, 0xf0, 0xe0, 0x00, 0xf8,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0xfc, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x48, 0x4b, 0x48, 0x78, 0x4f,
-+ 0x48, 0x49, 0x79, 0x49, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0xf0, 0x90, 0x90, 0xfc,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x01, 0x79, 0x49, 0x4a, 0x4c, 0x7f, 0x48,
-+ 0x4b, 0x4a, 0x7a, 0x4a, 0x03, 0x02, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x40,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x3f, 0x20,
-+ 0x2f, 0x20, 0x3f, 0x24, 0x26, 0x5c, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xf8, 0x00,
-+ 0xf0, 0x00, 0xfc, 0x90, 0x60, 0x1c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x00, 0x3f,
-+ 0x20, 0x3e, 0x24, 0x24, 0x38, 0x43, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x88, 0xfc,
-+ 0x80, 0x48, 0x50, 0x24, 0xd4, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x0e, 0x78, 0x09, 0x1a,
-+ 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x18, 0xe0, 0x80, 0xfc, 0x90, 0x90, 0x10, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x79, 0x4f, 0x49, 0x49, 0x7b, 0x4b,
-+ 0x4b, 0x4d, 0x7d, 0x49, 0x01, 0x01, 0x00, 0x00,
-+ 0x04, 0x08, 0x30, 0xe0, 0x20, 0xbc, 0x68, 0x68,
-+ 0x28, 0x28, 0x48, 0x48, 0x88, 0x08, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x02, 0x7e,
-+ 0x02, 0x3e, 0x02, 0x0e, 0x74, 0x08, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x80, 0xfc,
-+ 0x80, 0xf8, 0x80, 0xfc, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0f, 0x0f, 0x3f, 0x21, 0x7f,
-+ 0x0f, 0x0f, 0x09, 0x0f, 0x7f, 0x01, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0xe0, 0xfc, 0x08, 0xf8,
-+ 0xe0, 0xe0, 0x20, 0xe0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x49, 0x48, 0x4b, 0x7a, 0x4a,
-+ 0x4a, 0x4f, 0x78, 0x48, 0x03, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x50, 0x40, 0xf8, 0x48, 0x48,
-+ 0x48, 0xfc, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4f, 0x48, 0x4b, 0x7a, 0x4b,
-+ 0x4a, 0x4b, 0x78, 0x4f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xf8, 0x40, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x4a, 0x4f, 0x48, 0x79, 0x49,
-+ 0x49, 0x49, 0x79, 0x48, 0x07, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0xf8, 0x00, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x79, 0x49, 0x49, 0x49, 0x78, 0x4f,
-+ 0x49, 0x4b, 0x7c, 0x49, 0x02, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xf8, 0xa8, 0x28, 0x48, 0xb0, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4d, 0x49, 0x49, 0x79, 0x49,
-+ 0x48, 0x4f, 0x78, 0x48, 0x01, 0x06, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x40, 0xfc, 0x00, 0x90, 0x08, 0x08, 0x00, 0x00,
-+ 0x08, 0x3e, 0x22, 0x3f, 0x3e, 0x26, 0x39, 0x1f,
-+ 0x04, 0x07, 0x04, 0x07, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x90, 0xfc, 0x30, 0xd4, 0x0c, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x23, 0x13, 0x11, 0x01, 0x73,
-+ 0x15, 0x11, 0x11, 0x19, 0x27, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0xf8, 0x10, 0xfc, 0x20,
-+ 0xf8, 0xf8, 0x20, 0xfc, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x03, 0x78, 0x4f, 0x49, 0x4f, 0x79, 0x49,
-+ 0x4e, 0x4b, 0x78, 0x40, 0x01, 0x06, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xfc, 0x10, 0xbc, 0x10, 0xbc,
-+ 0x00, 0xf8, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x48, 0x4b, 0x4a, 0x7b, 0x48,
-+ 0x4f, 0x48, 0x79, 0x4f, 0x01, 0x03, 0x00, 0x00,
-+ 0x20, 0x20, 0xe0, 0x3c, 0xc8, 0xe8, 0xa8, 0x28,
-+ 0xf0, 0x90, 0x98, 0x28, 0x44, 0x84, 0x00, 0x00,
-+ 0x08, 0x2a, 0x49, 0x7f, 0x49, 0x5d, 0x6b, 0x49,
-+ 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xc8, 0x48, 0x30, 0x30, 0xc8,
-+ 0xf4, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x07, 0x79, 0x4b, 0x49, 0x49, 0x7f, 0x49,
-+ 0x49, 0x4b, 0x78, 0x4f, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0xfc, 0x10, 0xf8, 0x50, 0x50, 0xfc, 0x50,
-+ 0x50, 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x07, 0x7a, 0x49, 0x4b, 0x4d, 0x79, 0x49,
-+ 0x49, 0x49, 0x79, 0x42, 0x04, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x48, 0xb0, 0x18, 0xf4, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x50, 0x48, 0x48, 0xc0, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x49, 0x4b, 0x4a, 0x7d, 0x49,
-+ 0x4a, 0x48, 0x7b, 0x48, 0x00, 0x07, 0x00, 0x00,
-+ 0x18, 0xe8, 0x48, 0x10, 0xfc, 0x68, 0x98, 0xf4,
-+ 0x40, 0xf8, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x01, 0x07, 0x79, 0x4b, 0x4a, 0x4c, 0x7f, 0x48,
-+ 0x4f, 0x48, 0x7b, 0x48, 0x07, 0x00, 0x00, 0x00,
-+ 0x10, 0xfc, 0x10, 0xfc, 0xe8, 0x00, 0xfc, 0xc8,
-+ 0x68, 0xb0, 0x70, 0xa8, 0x24, 0xc0, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4b, 0x4a, 0x4b, 0x7a, 0x4a,
-+ 0x4a, 0x4a, 0x7c, 0x44, 0x08, 0x03, 0x00, 0x00,
-+ 0x40, 0xfc, 0x90, 0xfc, 0xf0, 0xfc, 0x20, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0xf8, 0xc8, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x4b, 0x4a, 0x4a, 0x7a, 0x4a,
-+ 0x4a, 0x4a, 0x7a, 0x44, 0x07, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x00, 0x20, 0x20, 0x20,
-+ 0x40, 0x50, 0x88, 0x98, 0xe4, 0x04, 0x00, 0x00,
-+ 0x00, 0x03, 0x78, 0x49, 0x4f, 0x4b, 0x79, 0x4f,
-+ 0x4b, 0x4d, 0x7f, 0x47, 0x04, 0x01, 0x00, 0x00,
-+ 0x90, 0xf8, 0x40, 0xf0, 0xfc, 0xa8, 0x24, 0xfc,
-+ 0xa8, 0x28, 0xd0, 0xb4, 0xcc, 0x84, 0x00, 0x00,
-+ 0x1f, 0x17, 0x1f, 0x01, 0x7f, 0x1e, 0x12, 0x1e,
-+ 0x3f, 0x0f, 0x7f, 0x0c, 0x77, 0x1c, 0x00, 0x00,
-+ 0xf0, 0xd0, 0xf0, 0x00, 0xfc, 0xf0, 0x90, 0xf0,
-+ 0xf8, 0xe0, 0xfc, 0x90, 0x60, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x20, 0x20, 0x20, 0x3f, 0x20,
-+ 0x20, 0x20, 0x20, 0x3f, 0x20, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0x10, 0x90, 0x10,
-+ 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x11, 0x1f, 0x11, 0x11, 0x1f,
-+ 0x11, 0x00, 0x00, 0x03, 0x3c, 0x00, 0x00, 0x00,
-+ 0x20, 0x10, 0xf0, 0x10, 0xd0, 0x10, 0x10, 0xf8,
-+ 0x10, 0xa0, 0xc0, 0x44, 0x34, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x12, 0x07,
-+ 0x19, 0x71, 0x12, 0x14, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x08, 0x88, 0x48, 0x08, 0xe8, 0x30, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x25, 0x3d, 0x25, 0x24,
-+ 0x3d, 0x25, 0x25, 0x25, 0x25, 0x4d, 0x00, 0x00,
-+ 0x20, 0x24, 0x24, 0x24, 0x24, 0xfc, 0x24, 0x20,
-+ 0x24, 0x24, 0x24, 0x24, 0xfc, 0x04, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x25, 0x25, 0x3d, 0x25, 0x25,
-+ 0x3d, 0x25, 0x25, 0x25, 0x25, 0x4f, 0x00, 0x00,
-+ 0x40, 0x40, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x48, 0x28, 0x30, 0x10, 0xc8, 0x04, 0x00, 0x00,
-+ 0x04, 0x3f, 0x04, 0x07, 0x07, 0x04, 0x7f, 0x08,
-+ 0x17, 0x64, 0x07, 0x07, 0x08, 0x10, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xc0, 0xc0, 0x40, 0xfc, 0x20,
-+ 0xd0, 0x48, 0xc4, 0xc0, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x25, 0x25, 0x3e, 0x27, 0x24,
-+ 0x3f, 0x24, 0x27, 0x24, 0x27, 0x4c, 0x00, 0x00,
-+ 0x90, 0xfc, 0x90, 0xfc, 0x08, 0xf0, 0xfc, 0xc8,
-+ 0x68, 0xb0, 0x70, 0xa8, 0x24, 0xc0, 0x00, 0x00,
-+ 0x01, 0x39, 0x2f, 0x2a, 0x2a, 0x3f, 0x28, 0x2b,
-+ 0x3a, 0x2b, 0x2a, 0x2b, 0x2a, 0x5a, 0x00, 0x00,
-+ 0x20, 0x3c, 0xe0, 0xb8, 0x88, 0xf8, 0x20, 0xb8,
-+ 0xa0, 0xb8, 0xa0, 0xbc, 0xa4, 0x9c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x4f, 0x15, 0x7f,
-+ 0x14, 0x3e, 0x2a, 0x3e, 0x7f, 0x09, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0xe8, 0x70, 0x00, 0xf8,
-+ 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x18, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x7f, 0x01, 0x09, 0x09, 0x09,
-+ 0x09, 0x09, 0x11, 0x11, 0x21, 0x01, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0xfc, 0x00, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x1f, 0x11, 0x11, 0x11,
-+ 0x11, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x10, 0x10, 0x10,
-+ 0x60, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x04, 0x04, 0x08, 0x10, 0x21, 0x01,
-+ 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0xc0, 0x40, 0x78, 0x08, 0x08, 0x70, 0x00,
-+ 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x09, 0x08, 0x08, 0x7e, 0x08, 0x0c, 0x1a, 0x1a,
-+ 0x18, 0x28, 0x29, 0x49, 0x0a, 0x0c, 0x00, 0x00,
-+ 0xc0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xe0,
-+ 0xa0, 0xa0, 0x10, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x1c, 0x1a, 0x1a,
-+ 0x28, 0x28, 0x48, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x7e, 0x08, 0x1c, 0x1a, 0x1a,
-+ 0x28, 0x28, 0x49, 0x09, 0x0a, 0x0c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
-+ 0x88, 0x88, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x7e, 0x08, 0x1c, 0x1b, 0x1a,
-+ 0x28, 0x28, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x7e, 0x08, 0x1c, 0x1b, 0x1b,
-+ 0x29, 0x29, 0x49, 0x09, 0x09, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08,
-+ 0x00, 0x00, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x7e, 0x08, 0x1c, 0x1a, 0x1a,
-+ 0x28, 0x28, 0x48, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7e, 0x08, 0x1d, 0x1a, 0x1a,
-+ 0x28, 0x28, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0x40, 0x7c, 0xc0, 0x40, 0x20,
-+ 0x20, 0x20, 0x14, 0x14, 0x0c, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7e, 0x12, 0x1a, 0x36, 0x36,
-+ 0x32, 0x52, 0x52, 0x13, 0x12, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0xf8, 0x08, 0x08, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x7e, 0x08, 0x1c, 0x1a, 0x1a,
-+ 0x28, 0x28, 0x49, 0x09, 0x0a, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x40, 0x78, 0x48, 0x48,
-+ 0x88, 0x88, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x7e, 0x08, 0x1c, 0x1b, 0x1a,
-+ 0x28, 0x28, 0x48, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x7f, 0x03, 0x05, 0x09, 0x11,
-+ 0x61, 0x01, 0x00, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x80, 0x40, 0x20, 0x10,
-+ 0x0c, 0x00, 0x00, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x03, 0x05, 0x19, 0x61, 0x04,
-+ 0x08, 0x11, 0x61, 0x02, 0x04, 0x1f, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x40,
-+ 0x30, 0x08, 0x04, 0x20, 0x70, 0x88, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x7e, 0x08, 0x1f, 0x1a, 0x1a,
-+ 0x28, 0x28, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x10, 0x60, 0x20, 0xfc, 0x24, 0x28,
-+ 0x30, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7e, 0x08, 0x1c, 0x1b, 0x1a,
-+ 0x28, 0x28, 0x48, 0x08, 0x09, 0x0e, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xb0, 0xa8, 0xa4, 0x2c, 0x28,
-+ 0x70, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x11, 0x10, 0x10, 0x7d, 0x11, 0x1a, 0x37, 0x34,
-+ 0x30, 0x50, 0x51, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0xe0, 0xa0, 0xa0, 0x10, 0x10, 0x08, 0xf4, 0x90,
-+ 0x90, 0x90, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x1c, 0x1a, 0x1a,
-+ 0x28, 0x28, 0x48, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x78, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x7f, 0x09, 0x1d, 0x1b, 0x1b,
-+ 0x29, 0x29, 0x49, 0x0a, 0x0a, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0x08, 0x08, 0xf8,
-+ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x10, 0x18, 0x37, 0x34,
-+ 0x30, 0x50, 0x51, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x50, 0x90, 0x90, 0x90, 0x90, 0x90, 0xfc, 0x90,
-+ 0x90, 0x90, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x7e, 0x08, 0x1c, 0x1b, 0x1a,
-+ 0x28, 0x28, 0x49, 0x09, 0x0a, 0x0c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x90, 0x90, 0x90, 0x90, 0xfc, 0x90,
-+ 0x90, 0x90, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x12, 0x12, 0x12, 0x7f, 0x12, 0x1a, 0x36, 0x36,
-+ 0x32, 0x52, 0x52, 0x14, 0x14, 0x19, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xb8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xb8, 0xa8, 0x80, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x7e, 0x09, 0x1d, 0x1b, 0x1b,
-+ 0x29, 0x29, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0x08, 0xe8, 0x28, 0x28, 0x28,
-+ 0xe8, 0x28, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x7f, 0x09, 0x1d, 0x1a, 0x1b,
-+ 0x2a, 0x28, 0x48, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0xf8,
-+ 0x48, 0x48, 0x48, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x01, 0x1f, 0x19, 0x15, 0x15,
-+ 0x1f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x00, 0xf0, 0x50, 0x50, 0x90,
-+ 0xf0, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x7f, 0x09, 0x1d, 0x1b, 0x1b,
-+ 0x29, 0x28, 0x48, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf8,
-+ 0x08, 0x00, 0x90, 0x88, 0x04, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x12, 0x1a, 0x37, 0x36,
-+ 0x32, 0x52, 0x53, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x70, 0x90, 0x20, 0x20,
-+ 0x50, 0x88, 0x04, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x11, 0x3a, 0x35, 0x35,
-+ 0x51, 0x51, 0x11, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf8, 0x08, 0x08, 0xe8, 0x28,
-+ 0x28, 0xe8, 0x28, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x7f, 0x09, 0x1d, 0x1b, 0x1b,
-+ 0x29, 0x29, 0x49, 0x09, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x10, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x09, 0x1e, 0x1a, 0x1a,
-+ 0x28, 0x28, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x40, 0x40, 0x78, 0x40,
-+ 0x40, 0x78, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7f, 0x09, 0x1d, 0x1b, 0x1b,
-+ 0x29, 0x29, 0x4a, 0x0a, 0x0c, 0x08, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x00, 0x00, 0xfc, 0x20, 0x60,
-+ 0x30, 0x28, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7f, 0x09, 0x1d, 0x1b, 0x1b,
-+ 0x29, 0x29, 0x49, 0x0f, 0x09, 0x08, 0x00, 0x00,
-+ 0x08, 0x30, 0xe0, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0x10, 0x10, 0xd4, 0x0c, 0xec, 0x04, 0x00, 0x00,
-+ 0x10, 0x12, 0x12, 0x7e, 0x12, 0x1b, 0x36, 0x34,
-+ 0x32, 0x52, 0x52, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0x48, 0x48, 0xf8, 0x48, 0x40,
-+ 0x48, 0x48, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7d, 0x12, 0x1b, 0x35, 0x35,
-+ 0x31, 0x51, 0x51, 0x11, 0x11, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0xe8, 0x28, 0x28,
-+ 0xe8, 0x30, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x11, 0x19, 0x37, 0x35,
-+ 0x31, 0x51, 0x51, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x88, 0x88, 0x88, 0x88, 0xfc, 0x08, 0x48, 0x28,
-+ 0x28, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x10, 0x12, 0x39, 0x35,
-+ 0x34, 0x50, 0x50, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x10, 0x10, 0x10, 0x10,
-+ 0x90, 0xa0, 0xa0, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7f, 0x09, 0x1d, 0x1b, 0x1b,
-+ 0x29, 0x29, 0x49, 0x0a, 0x0b, 0x0c, 0x00, 0x00,
-+ 0x08, 0x30, 0xd0, 0x50, 0x50, 0x50, 0x50, 0x50,
-+ 0x50, 0x50, 0x70, 0x58, 0xf8, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7e, 0x13, 0x13, 0x3a, 0x37,
-+ 0x35, 0x51, 0x51, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0xa0, 0x10, 0xe8, 0xfc, 0x58, 0xe8, 0xf8,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x3e, 0x08, 0x08, 0x7f, 0x08, 0x09, 0x01,
-+ 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0x20, 0xfc, 0x20, 0x20, 0x00,
-+ 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x12, 0x1a, 0x36, 0x36,
-+ 0x32, 0x52, 0x52, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0x20, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7d, 0x11, 0x1a, 0x34, 0x35,
-+ 0x31, 0x52, 0x54, 0x10, 0x10, 0x11, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x98, 0x98, 0xa8, 0xc8, 0x98,
-+ 0x98, 0xa8, 0xc8, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x22, 0x54, 0x0f, 0x18, 0x61,
-+ 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x90, 0x90, 0xfc, 0x10, 0x10,
-+ 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x10, 0x19, 0x36, 0x37,
-+ 0x30, 0x50, 0x51, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x90, 0xf8, 0x04, 0xf8,
-+ 0x80, 0xf0, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7e, 0x08, 0x1f, 0x1a, 0x1a,
-+ 0x29, 0x2a, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x48, 0xf8, 0x50, 0x50, 0xfc, 0x40, 0xfc,
-+ 0x80, 0xf8, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x10, 0x1f, 0x34, 0x34,
-+ 0x33, 0x50, 0x50, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x50, 0x88, 0xfc, 0x44, 0x40,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x7c, 0x11, 0x1f, 0x34, 0x35,
-+ 0x31, 0x51, 0x51, 0x12, 0x12, 0x14, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x90, 0x18, 0xe4, 0x00, 0x50,
-+ 0x50, 0x50, 0x50, 0x54, 0x54, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x10, 0x18, 0x35, 0x35,
-+ 0x33, 0x55, 0x51, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x80, 0xf8, 0x08, 0x10,
-+ 0x10, 0xfc, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x1c, 0x1a, 0x1b,
-+ 0x2a, 0x2b, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x50, 0x88, 0xfc, 0xa4, 0xa0, 0xf8, 0x20,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x12, 0x7d, 0x11, 0x18, 0x37, 0x34,
-+ 0x30, 0x53, 0x50, 0x10, 0x13, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x48, 0x48, 0x50, 0x40, 0xf8, 0x08,
-+ 0x08, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7e, 0x13, 0x1a, 0x36, 0x37,
-+ 0x32, 0x52, 0x53, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x80, 0xf0, 0x20, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x1b, 0x34, 0x37,
-+ 0x30, 0x50, 0x57, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x00, 0xf8,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x0f, 0x0f, 0x08, 0x0f, 0x0f, 0x08, 0x0f,
-+ 0x09, 0x01, 0x7f, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x00, 0xe0, 0xe0, 0x20, 0xe0, 0xf8, 0x00, 0xf0,
-+ 0x10, 0x60, 0xfc, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x12, 0x1c, 0x37, 0x34,
-+ 0x31, 0x51, 0x51, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x40,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x1c, 0x1b, 0x1a,
-+ 0x28, 0x29, 0x4a, 0x08, 0x09, 0x0e, 0x00, 0x00,
-+ 0x40, 0x50, 0x98, 0xe4, 0xa0, 0xa4, 0x5c, 0x40,
-+ 0xf0, 0x10, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x1a, 0x36, 0x36,
-+ 0x32, 0x52, 0x54, 0x14, 0x18, 0x10, 0x00, 0x00,
-+ 0x18, 0xe0, 0x00, 0xfc, 0x00, 0xf8, 0xa8, 0xa8,
-+ 0xf8, 0x88, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x0d, 0x16, 0x14, 0x37, 0x54,
-+ 0x17, 0x14, 0x15, 0x16, 0x14, 0x10, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x10, 0xa0, 0x60, 0xdc, 0x40,
-+ 0xfc, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x10, 0x17, 0x12, 0x7a, 0x17, 0x1a, 0x3a, 0x37,
-+ 0x32, 0x52, 0x54, 0x14, 0x18, 0x13, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xa8, 0xb0, 0xb0, 0xa8, 0xa8,
-+ 0xa4, 0xa4, 0xa4, 0xb8, 0xa0, 0x20, 0x00, 0x00,
-+ 0x10, 0x17, 0x11, 0x7d, 0x12, 0x1a, 0x37, 0x31,
-+ 0x35, 0x55, 0x52, 0x12, 0x15, 0x18, 0x00, 0x00,
-+ 0x18, 0xe0, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0x20, 0x20, 0xf8, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7d, 0x17, 0x11, 0x38, 0x35,
-+ 0x37, 0x50, 0x53, 0x12, 0x13, 0x10, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xf0, 0xfc, 0xe8, 0x40, 0xf0,
-+ 0xfc, 0x08, 0xfc, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x11, 0x19, 0x35, 0x35,
-+ 0x31, 0x57, 0x51, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x00, 0xfc, 0x10, 0x10, 0x10,
-+ 0x10, 0xfc, 0x10, 0x08, 0x04, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7d, 0x11, 0x1a, 0x35, 0x34,
-+ 0x30, 0x53, 0x50, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x30, 0xc8, 0x24, 0x24, 0x00, 0xf8, 0x10,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x1c, 0x1a, 0x2a, 0x49, 0x07,
-+ 0x04, 0x06, 0x05, 0x09, 0x10, 0x20, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x70, 0x70, 0xa8, 0x24, 0xc0,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x11, 0x19, 0x34, 0x34,
-+ 0x33, 0x52, 0x52, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x40, 0x80,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x1c, 0x2a, 0x4b, 0x08, 0x7f,
-+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x70, 0xa8, 0x24, 0x20, 0xfc,
-+ 0x00, 0xc0, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x10, 0x1b, 0x36, 0x36,
-+ 0x33, 0x52, 0x50, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa0, 0xa0, 0xa0, 0xb8, 0x08, 0x08,
-+ 0xb8, 0xa8, 0xa0, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x11, 0x19, 0x35, 0x34,
-+ 0x30, 0x50, 0x53, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x80,
-+ 0x9c, 0xe0, 0x80, 0x88, 0x88, 0x78, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x17, 0x10, 0x38, 0x37,
-+ 0x35, 0x51, 0x53, 0x15, 0x11, 0x11, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0xfc, 0x90, 0x90, 0xf0,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7d, 0x11, 0x19, 0x34, 0x37,
-+ 0x30, 0x50, 0x57, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x10, 0x60, 0xfc, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x04, 0x3f, 0x04, 0x07, 0x04, 0x07, 0x04, 0x7f,
-+ 0x09, 0x1f, 0x63, 0x0d, 0x31, 0x01, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xc0, 0x40, 0xc0, 0x40, 0xfc,
-+ 0x20, 0xf0, 0x8c, 0x60, 0x18, 0x00, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7e, 0x14, 0x12, 0x39, 0x37,
-+ 0x35, 0x51, 0x52, 0x14, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x88, 0xa8, 0xa8, 0xc8, 0xf8,
-+ 0xc8, 0xa8, 0xa8, 0x88, 0x88, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x2a, 0x2a, 0x2a,
-+ 0x2e, 0x0c, 0x1c, 0x2a, 0x49, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0xa8, 0xa8, 0xa8,
-+ 0xb8, 0x30, 0x70, 0xa8, 0x24, 0x20, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x1a, 0x37, 0x36,
-+ 0x32, 0x52, 0x53, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x48, 0x48, 0xf8, 0x48,
-+ 0x68, 0x58, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7f, 0x10, 0x1b, 0x34, 0x35,
-+ 0x36, 0x53, 0x50, 0x10, 0x11, 0x12, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0xf8, 0x40, 0xfc, 0xa0, 0x50,
-+ 0x4c, 0xf8, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x17, 0x15, 0x7c, 0x14, 0x1f, 0x3c, 0x35,
-+ 0x35, 0x55, 0x55, 0x15, 0x14, 0x14, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0xa8, 0xc8, 0xf8, 0x48, 0x58,
-+ 0x58, 0x58, 0xf8, 0x18, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x14, 0x18, 0x35, 0x36,
-+ 0x33, 0x50, 0x50, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa8, 0xa0, 0xa4, 0x1c, 0x00,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x7f, 0x09, 0x1d, 0x1b, 0x1b,
-+ 0x29, 0x29, 0x49, 0x09, 0x09, 0x0f, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0xf8, 0x20,
-+ 0x24, 0xf8, 0x20, 0x24, 0xe4, 0x1c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x7f, 0x09, 0x1d, 0x1b, 0x1b,
-+ 0x29, 0x29, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x18, 0xe0, 0x20, 0xfc, 0x20, 0x10, 0xd4, 0x0c,
-+ 0xfc, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x08, 0x1c, 0x1b, 0x1a,
-+ 0x28, 0x2b, 0x48, 0x08, 0x08, 0x09, 0x00, 0x00,
-+ 0x50, 0x48, 0x7c, 0xc8, 0x30, 0x34, 0xcc, 0x54,
-+ 0x7c, 0xc8, 0x30, 0x14, 0x6c, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7f, 0x0a, 0x1c, 0x1a, 0x1b,
-+ 0x28, 0x28, 0x48, 0x09, 0x0a, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0x00, 0xf8, 0x00, 0xfc,
-+ 0x20, 0xb0, 0xa8, 0x24, 0x24, 0x60, 0x00, 0x00,
-+ 0x10, 0x12, 0x13, 0x7e, 0x12, 0x1b, 0x34, 0x35,
-+ 0x32, 0x50, 0x51, 0x16, 0x10, 0x17, 0x00, 0x00,
-+ 0x20, 0x28, 0xc8, 0x68, 0x98, 0xf8, 0xa0, 0x24,
-+ 0x9c, 0xf0, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7d, 0x11, 0x17, 0x39, 0x35,
-+ 0x37, 0x53, 0x55, 0x19, 0x11, 0x13, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x24, 0x24, 0xe8, 0x28, 0x18,
-+ 0x90, 0x50, 0x68, 0x28, 0x44, 0x84, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7d, 0x10, 0x1f, 0x34, 0x37,
-+ 0x30, 0x50, 0x51, 0x10, 0x10, 0x17, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x10, 0xa0, 0xfc, 0x40, 0xfc,
-+ 0x90, 0x90, 0xe0, 0x30, 0xc8, 0x08, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x1f, 0x13, 0x1d, 0x31, 0x7f,
-+ 0x01, 0x1f, 0x13, 0x1d, 0x71, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x90, 0x60, 0x10, 0xfc,
-+ 0x00, 0xf0, 0x90, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x13, 0x18, 0x37, 0x36,
-+ 0x31, 0x51, 0x50, 0x11, 0x16, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8, 0x48,
-+ 0x68, 0x70, 0xd0, 0x48, 0x44, 0xc0, 0x00, 0x00,
-+ 0x12, 0x12, 0x12, 0x7f, 0x15, 0x19, 0x3f, 0x35,
-+ 0x35, 0x51, 0x52, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x38, 0xe8, 0x28, 0x28, 0xe8, 0x28,
-+ 0x28, 0xa8, 0x68, 0x78, 0x28, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x13, 0x1a, 0x37, 0x36,
-+ 0x33, 0x50, 0x57, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0x40, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x11, 0x09, 0x3f, 0x20, 0x4f, 0x08, 0x0f, 0x01,
-+ 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x10, 0x20, 0xfc, 0x08, 0xe0, 0x20, 0xe0, 0x00,
-+ 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x13, 0x14, 0x39, 0x34,
-+ 0x34, 0x50, 0x52, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xf0, 0x20,
-+ 0x40, 0xa0, 0xa8, 0x84, 0x94, 0x70, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x12, 0x1a, 0x36, 0x36,
-+ 0x33, 0x52, 0x54, 0x14, 0x18, 0x10, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x48, 0x48, 0x48, 0xfc, 0xc8,
-+ 0xa8, 0xa8, 0x88, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x11, 0x10, 0x10, 0x7f, 0x10, 0x1a, 0x36, 0x35,
-+ 0x31, 0x51, 0x51, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xfc, 0xa0, 0xa8, 0xa8, 0xa8,
-+ 0xb0, 0xb0, 0xa0, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x1b, 0x36, 0x36,
-+ 0x32, 0x52, 0x52, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0xa8, 0xb8, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x12, 0x1a, 0x37, 0x36,
-+ 0x32, 0x57, 0x50, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xa0, 0xf8, 0xa8, 0xa8, 0xf8, 0xa8,
-+ 0xa8, 0xfc, 0xa0, 0x90, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x17, 0x11, 0x7d, 0x12, 0x17, 0x39, 0x35,
-+ 0x37, 0x51, 0x51, 0x11, 0x17, 0x10, 0x00, 0x00,
-+ 0x08, 0xc8, 0x28, 0xa8, 0xa8, 0xe8, 0x68, 0x28,
-+ 0xe8, 0x28, 0x28, 0xc8, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x13, 0x14, 0x3b, 0x36,
-+ 0x36, 0x53, 0x52, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xf8, 0xa8,
-+ 0xa8, 0xf8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x11, 0x19, 0x36, 0x36,
-+ 0x33, 0x52, 0x52, 0x12, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x9c, 0xf4, 0x54, 0x64, 0x98,
-+ 0xf8, 0xa8, 0xa8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x09, 0x09, 0x09, 0x7f, 0x09, 0x19, 0x1f, 0x1a,
-+ 0x2b, 0x29, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x20, 0x24, 0xe8, 0x30, 0x20, 0xe4, 0x3c, 0x40,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7f, 0x11, 0x19, 0x37, 0x36,
-+ 0x32, 0x52, 0x53, 0x12, 0x10, 0x11, 0x00, 0x00,
-+ 0x00, 0x38, 0x28, 0xe8, 0x28, 0x38, 0xa8, 0xa8,
-+ 0xb8, 0xa8, 0xc8, 0x48, 0x88, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x7d, 0x11, 0x17, 0x39, 0x35,
-+ 0x37, 0x53, 0x55, 0x19, 0x11, 0x11, 0x00, 0x00,
-+ 0x50, 0x90, 0x10, 0x14, 0x34, 0xf8, 0x58, 0x90,
-+ 0x50, 0x50, 0x28, 0x28, 0x44, 0x84, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x10, 0x1f, 0x35, 0x35,
-+ 0x31, 0x51, 0x51, 0x11, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xfc, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x1c, 0xf0, 0x10, 0x10, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x79, 0x17, 0x11, 0x39, 0x37,
-+ 0x35, 0x57, 0x50, 0x10, 0x13, 0x1c, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x24, 0xe4, 0x24, 0xc4, 0x18,
-+ 0x40, 0xfc, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x13, 0x1a, 0x37, 0x34,
-+ 0x37, 0x50, 0x51, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x48,
-+ 0xe8, 0xf0, 0x50, 0x48, 0x44, 0xc0, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x10, 0x1f, 0x34, 0x34,
-+ 0x31, 0x57, 0x51, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x48, 0x50, 0xfc, 0x60, 0x90,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x7d, 0x11, 0x19, 0x35, 0x35,
-+ 0x37, 0x52, 0x52, 0x13, 0x13, 0x12, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xfc, 0xa0, 0xa8, 0x18, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7d, 0x10, 0x1b, 0x36, 0x34,
-+ 0x33, 0x52, 0x52, 0x12, 0x12, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x10, 0xa0, 0xfc, 0x48, 0x40,
-+ 0xf8, 0x48, 0x48, 0x48, 0x70, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x10, 0x1f, 0x34, 0x37,
-+ 0x30, 0x53, 0x50, 0x17, 0x10, 0x10, 0x00, 0x00,
-+ 0x80, 0xf8, 0x10, 0xf0, 0x20, 0xfc, 0xc8, 0x68,
-+ 0xb0, 0x70, 0xa8, 0x24, 0x20, 0xc0, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7f, 0x11, 0x17, 0x39, 0x35,
-+ 0x37, 0x53, 0x55, 0x19, 0x11, 0x13, 0x00, 0x00,
-+ 0x10, 0xd0, 0x90, 0x7c, 0x10, 0xd0, 0x78, 0xb8,
-+ 0x38, 0x54, 0x54, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x17, 0x12, 0x7e, 0x13, 0x1a, 0x36, 0x37,
-+ 0x32, 0x52, 0x53, 0x16, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xb0, 0xb0, 0xa8, 0xa8,
-+ 0xa4, 0xe4, 0xa4, 0xb8, 0xa0, 0xa0, 0x00, 0x00,
-+ 0x11, 0x10, 0x10, 0x7d, 0x13, 0x14, 0x3f, 0x3c,
-+ 0x36, 0x55, 0x56, 0x15, 0x14, 0x15, 0x00, 0x00,
-+ 0xc0, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xa8, 0xa8,
-+ 0xa8, 0xd0, 0xd0, 0xa8, 0xa8, 0xa8, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x13, 0x12, 0x38, 0x37,
-+ 0x34, 0x50, 0x50, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xf8, 0x48, 0x40, 0xfc,
-+ 0x40, 0x78, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x7c, 0x13, 0x1b, 0x36, 0x36,
-+ 0x33, 0x50, 0x51, 0x16, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x58, 0xd8, 0xe8,
-+ 0xf8, 0xe0, 0x50, 0x4c, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x17, 0x18, 0x35, 0x37,
-+ 0x30, 0x53, 0x50, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0xfc, 0xa0, 0x10, 0xe8,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x7d, 0x11, 0x19, 0x35, 0x34,
-+ 0x37, 0x50, 0x51, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x50, 0x50, 0xfc, 0x50, 0x70, 0x00, 0xf8, 0x40,
-+ 0xfc, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x12, 0x1b, 0x37, 0x34,
-+ 0x33, 0x52, 0x52, 0x12, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x68, 0x98, 0x08, 0xf8, 0x00,
-+ 0xf8, 0xa8, 0xa8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x2a, 0x2c, 0x49, 0x14, 0x22, 0x3f, 0x21,
-+ 0x5f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x20, 0xa4, 0xa8, 0x30, 0x48, 0x88, 0xfc, 0x08,
-+ 0xf0, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x12, 0x1b, 0x36, 0x37,
-+ 0x31, 0x51, 0x51, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x50, 0x50, 0x68, 0x7c, 0x44, 0x3c, 0x00, 0x00,
-+ 0x10, 0x12, 0x12, 0x7f, 0x10, 0x1f, 0x34, 0x35,
-+ 0x31, 0x51, 0x51, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0xf8, 0x00, 0xfc, 0x00, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x7c, 0x11, 0x19, 0x35, 0x34,
-+ 0x33, 0x52, 0x52, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x00,
-+ 0xf8, 0x08, 0xe8, 0xa8, 0xe8, 0x18, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x7f, 0x08, 0x19, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x09, 0x09, 0x0e, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xfc, 0x00, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0xf8, 0x98, 0x04, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x11, 0x1b, 0x36, 0x35,
-+ 0x31, 0x51, 0x51, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x78, 0x48, 0xfc, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x18, 0x00, 0x00,
-+ 0x11, 0x10, 0x17, 0x7c, 0x13, 0x18, 0x37, 0x35,
-+ 0x31, 0x52, 0x54, 0x18, 0x17, 0x10, 0x00, 0x00,
-+ 0x10, 0xa0, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0x00,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x3f, 0x24, 0x7f, 0x04, 0x1f, 0x04, 0x7f,
-+ 0x09, 0x1f, 0x63, 0x0d, 0x31, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xf8, 0x40, 0xf0, 0x40, 0xfc,
-+ 0x20, 0xf0, 0x8c, 0x60, 0x18, 0x00, 0x00, 0x00,
-+ 0x22, 0x14, 0x7f, 0x08, 0x2a, 0x2a, 0x3e, 0x09,
-+ 0x11, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x18,
-+ 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x1b, 0x36, 0x37,
-+ 0x32, 0x53, 0x54, 0x14, 0x17, 0x14, 0x00, 0x00,
-+ 0x80, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xfc, 0x94, 0x94, 0xf4, 0x18, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x1b, 0x34, 0x37,
-+ 0x31, 0x56, 0x51, 0x16, 0x10, 0x11, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x98, 0xe8, 0x98, 0xe8, 0x88, 0x98, 0x00, 0x00,
-+ 0x08, 0x3e, 0x32, 0x2b, 0x2f, 0x7a, 0x2a, 0x47,
-+ 0x01, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0xf0, 0x90, 0x94, 0x0c, 0xf8, 0x90, 0x60, 0x9c,
-+ 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x13, 0x1a, 0x37, 0x36,
-+ 0x33, 0x52, 0x52, 0x13, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xfc, 0x50, 0x50, 0xdc, 0x50, 0xdc, 0x70,
-+ 0xdc, 0x50, 0x90, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7f, 0x12, 0x1a, 0x37, 0x34,
-+ 0x32, 0x52, 0x54, 0x10, 0x13, 0x1c, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xf8, 0xa8, 0xa8, 0xf8, 0x40,
-+ 0x48, 0x48, 0xd0, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7f, 0x12, 0x1b, 0x36, 0x37,
-+ 0x32, 0x50, 0x57, 0x11, 0x10, 0x10, 0x00, 0x00,
-+ 0x48, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x48, 0x10, 0xfc, 0x10, 0x90, 0x30, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7d, 0x11, 0x19, 0x35, 0x35,
-+ 0x30, 0x57, 0x50, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x40, 0xfc, 0x00, 0x90, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7d, 0x10, 0x1b, 0x36, 0x37,
-+ 0x30, 0x50, 0x50, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x10, 0xa0, 0xfc, 0x48, 0xf8,
-+ 0x40, 0x78, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x15, 0x19, 0x36, 0x34,
-+ 0x31, 0x53, 0x55, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0x10, 0x48, 0x48, 0xa0,
-+ 0x10, 0xf8, 0x14, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x12, 0x1a, 0x37, 0x34,
-+ 0x33, 0x52, 0x53, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x40, 0xbc, 0x14, 0x94, 0x54, 0xe4, 0x2c, 0x40,
-+ 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7d, 0x10, 0x1f, 0x34, 0x37,
-+ 0x32, 0x53, 0x52, 0x13, 0x12, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x10, 0xa0, 0xfc, 0x00, 0xf8,
-+ 0x48, 0xf8, 0x48, 0xfc, 0x44, 0x3c, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x7c, 0x13, 0x12, 0x3b, 0x34,
-+ 0x37, 0x50, 0x51, 0x17, 0x11, 0x13, 0x00, 0x00,
-+ 0x00, 0x38, 0xe8, 0x28, 0xb0, 0xb0, 0xa8, 0x28,
-+ 0xa4, 0xa4, 0xa4, 0x38, 0x20, 0x20, 0x00, 0x00,
-+ 0x11, 0x11, 0x6b, 0x2a, 0x13, 0x1a, 0x2e, 0x77,
-+ 0x01, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x10, 0x10, 0xe8, 0xa8, 0x90, 0x98, 0xac, 0xf4,
-+ 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7d, 0x12, 0x19, 0x36, 0x35,
-+ 0x36, 0x51, 0x50, 0x11, 0x10, 0x13, 0x00, 0x00,
-+ 0x00, 0xfc, 0xcc, 0x54, 0xec, 0x54, 0x64, 0xb0,
-+ 0x4c, 0xa0, 0x48, 0x90, 0x60, 0x80, 0x00, 0x00,
-+ 0x11, 0x17, 0x11, 0x7d, 0x13, 0x1a, 0x37, 0x34,
-+ 0x33, 0x50, 0x53, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xe0, 0xf8, 0x48, 0xf8, 0x40,
-+ 0xf8, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x17, 0x11, 0x7f, 0x12, 0x1b, 0x35, 0x35,
-+ 0x33, 0x53, 0x55, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x10, 0xfc, 0x10, 0xb8, 0xa8, 0xb8, 0xfc, 0x20,
-+ 0xf8, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x13, 0x1a, 0x37, 0x34,
-+ 0x33, 0x50, 0x53, 0x17, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x40,
-+ 0x58, 0x40, 0x58, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x12, 0x13, 0x14, 0x7d, 0x17, 0x15, 0x3d, 0x3f,
-+ 0x35, 0x55, 0x57, 0x14, 0x14, 0x18, 0x00, 0x00,
-+ 0x08, 0xe8, 0x98, 0x18, 0xc8, 0x68, 0x58, 0xd8,
-+ 0x4c, 0x78, 0xc8, 0x48, 0x48, 0xc8, 0x00, 0x00,
-+ 0x08, 0x7f, 0x3e, 0x2a, 0x3e, 0x2a, 0x3e, 0x7f,
-+ 0x09, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x18, 0xe0, 0x80, 0xfc, 0x90, 0x90, 0x90, 0x10,
-+ 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x11, 0x11, 0x12, 0x7c, 0x11, 0x19, 0x36, 0x36,
-+ 0x36, 0x52, 0x52, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x48, 0x48, 0x48, 0x48, 0xb4, 0xa4, 0x00, 0x20,
-+ 0xa0, 0xb8, 0xa0, 0xa0, 0x60, 0x1c, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7d, 0x11, 0x17, 0x39, 0x35,
-+ 0x34, 0x51, 0x57, 0x11, 0x11, 0x13, 0x00, 0x00,
-+ 0x40, 0xfc, 0x00, 0xf0, 0x10, 0xfc, 0x10, 0xf0,
-+ 0xc8, 0x48, 0x30, 0x10, 0xc8, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x12, 0x1a, 0x36, 0x37,
-+ 0x33, 0x53, 0x53, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x90, 0xf0, 0x00, 0xf8,
-+ 0x68, 0x68, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x12, 0x1a, 0x36, 0x36,
-+ 0x33, 0x52, 0x55, 0x15, 0x1a, 0x11, 0x00, 0x00,
-+ 0x20, 0x28, 0x24, 0xfc, 0x20, 0xa8, 0xe8, 0xa8,
-+ 0xe8, 0x90, 0xd0, 0xb4, 0xac, 0xc4, 0x00, 0x00,
-+ 0x12, 0x14, 0x12, 0x7f, 0x12, 0x1b, 0x36, 0x37,
-+ 0x30, 0x57, 0x50, 0x11, 0x16, 0x10, 0x00, 0x00,
-+ 0x48, 0x90, 0x48, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x10, 0x17, 0x13, 0x7e, 0x13, 0x1a, 0x37, 0x34,
-+ 0x37, 0x50, 0x57, 0x11, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x50,
-+ 0xf8, 0x10, 0xfc, 0x10, 0x90, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x7f, 0x11, 0x3a, 0x34, 0x57, 0x51,
-+ 0x13, 0x7f, 0x01, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x90, 0x90, 0x7c, 0x90, 0xb8, 0xb8, 0x54, 0x94,
-+ 0x10, 0xfc, 0x00, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7e, 0x14, 0x12, 0x3a, 0x34,
-+ 0x35, 0x56, 0x52, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x98, 0x50, 0xa8, 0xa4, 0xd4,
-+ 0xf0, 0x40, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7c, 0x12, 0x1a, 0x34, 0x35,
-+ 0x36, 0x53, 0x52, 0x13, 0x10, 0x17, 0x00, 0x00,
-+ 0x40, 0xfc, 0x98, 0x50, 0xa8, 0xa4, 0xd4, 0xf0,
-+ 0x40, 0xf8, 0x48, 0xf8, 0x58, 0xe4, 0x00, 0x00,
-+ 0x11, 0x10, 0x13, 0x7c, 0x11, 0x18, 0x37, 0x34,
-+ 0x31, 0x50, 0x57, 0x11, 0x16, 0x10, 0x00, 0x00,
-+ 0x10, 0xa0, 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0xc0,
-+ 0xc8, 0x68, 0xf0, 0x50, 0x4c, 0xc0, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x1b, 0x37, 0x36,
-+ 0x33, 0x50, 0x57, 0x11, 0x10, 0x17, 0x00, 0x00,
-+ 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8, 0xf8, 0x48,
-+ 0xf8, 0x80, 0xfc, 0x90, 0x70, 0x88, 0x00, 0x00,
-+ 0x10, 0x13, 0x11, 0x7f, 0x12, 0x1a, 0x37, 0x36,
-+ 0x33, 0x52, 0x53, 0x16, 0x10, 0x10, 0x00, 0x00,
-+ 0x20, 0xe0, 0x20, 0xe0, 0xbc, 0xe8, 0xe8, 0xa8,
-+ 0xb0, 0x90, 0xb0, 0xa8, 0xc8, 0x84, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7f, 0x12, 0x1b, 0x35, 0x35,
-+ 0x31, 0x51, 0x51, 0x11, 0x11, 0x16, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xfc, 0x50, 0xf0, 0xf8, 0x08,
-+ 0xf8, 0xf8, 0x08, 0xf8, 0x98, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7d, 0x10, 0x19, 0x35, 0x35,
-+ 0x30, 0x57, 0x51, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xf0, 0x00, 0xf0, 0x10, 0xf0,
-+ 0xa0, 0xfc, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x11, 0x19, 0x37, 0x36,
-+ 0x33, 0x52, 0x53, 0x12, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xfc, 0x80,
-+ 0xf8, 0xa8, 0xa8, 0x90, 0xe8, 0x84, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x11, 0x19, 0x35, 0x34,
-+ 0x33, 0x52, 0x53, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00,
-+ 0xb8, 0xa8, 0xb8, 0xa8, 0xb8, 0xa8, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7f, 0x10, 0x1b, 0x34, 0x35,
-+ 0x36, 0x53, 0x56, 0x13, 0x16, 0x11, 0x00, 0x00,
-+ 0x30, 0xc0, 0xf0, 0x80, 0xf8, 0x88, 0x78, 0x98,
-+ 0x60, 0xb8, 0x60, 0xbc, 0x64, 0xdc, 0x00, 0x00,
-+ 0x10, 0x17, 0x15, 0x7d, 0x16, 0x17, 0x3d, 0x3d,
-+ 0x35, 0x55, 0x56, 0x14, 0x14, 0x14, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0x78, 0x90, 0xfc, 0x00, 0x78,
-+ 0x48, 0x78, 0x48, 0x78, 0x48, 0x58, 0x00, 0x00,
-+ 0x11, 0x10, 0x12, 0x7d, 0x11, 0x1b, 0x34, 0x35,
-+ 0x31, 0x51, 0x51, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0xd0, 0x50, 0xa8, 0xa8, 0x10, 0xf8, 0x04, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x11, 0x7f, 0x13, 0x1a, 0x37, 0x36,
-+ 0x33, 0x50, 0x53, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x40, 0xf8, 0x10, 0xfc, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7f, 0x11, 0x1b, 0x35, 0x35,
-+ 0x36, 0x57, 0x50, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xfc, 0x10, 0xb8, 0x10, 0xfc,
-+ 0x00, 0xfc, 0xa0, 0xa0, 0x24, 0x1c, 0x00, 0x00,
-+ 0x10, 0x12, 0x11, 0x7f, 0x11, 0x18, 0x37, 0x34,
-+ 0x31, 0x50, 0x57, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0xa0, 0xa8, 0xb0, 0xfc, 0x10, 0xa0, 0xf8, 0x40,
-+ 0xf0, 0x40, 0xfc, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x1b, 0x36, 0x37,
-+ 0x32, 0x53, 0x52, 0x15, 0x15, 0x18, 0x00, 0x00,
-+ 0x80, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x00, 0xfc, 0xa4, 0x54, 0x04, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7f, 0x12, 0x1b, 0x36, 0x37,
-+ 0x32, 0x52, 0x55, 0x15, 0x19, 0x11, 0x00, 0x00,
-+ 0x40, 0xf0, 0x20, 0xfc, 0xa8, 0x58, 0x40, 0xfc,
-+ 0xf0, 0xf0, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x11, 0x7f, 0x10, 0x19, 0x35, 0x35,
-+ 0x31, 0x51, 0x50, 0x12, 0x12, 0x14, 0x00, 0x00,
-+ 0x40, 0xf8, 0x10, 0xfc, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x48, 0xa4, 0x94, 0x70, 0x00, 0x00,
-+ 0x14, 0x7f, 0x14, 0x1e, 0x23, 0x7a, 0x2a, 0x3b,
-+ 0x0d, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0x90, 0x50, 0x20, 0x50, 0x8c,
-+ 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x11, 0x13, 0x12, 0x7f, 0x12, 0x1b, 0x35, 0x37,
-+ 0x31, 0x51, 0x52, 0x12, 0x14, 0x11, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xbc, 0xe8, 0xe8, 0x28, 0xe8,
-+ 0x10, 0x90, 0x90, 0xa8, 0xc8, 0x84, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x13, 0x14, 0x3b, 0x36,
-+ 0x37, 0x51, 0x51, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xb8, 0xa8,
-+ 0xb8, 0x10, 0x10, 0xa8, 0x64, 0x44, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x7d, 0x11, 0x1a, 0x37, 0x34,
-+ 0x33, 0x52, 0x52, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x50, 0x50, 0xe8, 0xfc, 0x00,
-+ 0xf8, 0xe8, 0xa8, 0xe8, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3f, 0x20, 0x3f, 0x52, 0x1f,
-+ 0x01, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x20, 0xf8, 0x50, 0xfc, 0x20, 0xfc, 0x20, 0x20,
-+ 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3e, 0x22, 0x3f, 0x3e, 0x32,
-+ 0x5f, 0x01, 0x7f, 0x07, 0x79, 0x01, 0x00, 0x00,
-+ 0x40, 0xfc, 0x60, 0xf8, 0x50, 0xfc, 0x20, 0xf8,
-+ 0x20, 0x00, 0xfc, 0xc0, 0x3c, 0x00, 0x00, 0x00,
-+ 0x10, 0x17, 0x15, 0x7f, 0x14, 0x17, 0x3d, 0x3f,
-+ 0x34, 0x53, 0x52, 0x12, 0x17, 0x10, 0x00, 0x00,
-+ 0x20, 0xe0, 0x20, 0xbc, 0xc0, 0x80, 0x38, 0xc0,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x12, 0x1b, 0x36, 0x36,
-+ 0x32, 0x52, 0x52, 0x13, 0x13, 0x12, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xf8, 0xa8, 0xfc, 0xf8, 0xe8,
-+ 0xb8, 0xf8, 0x50, 0x88, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7f, 0x10, 0x1b, 0x34, 0x35,
-+ 0x33, 0x55, 0x51, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x00, 0xfc, 0xcc, 0x74, 0xcc, 0x74, 0x90, 0xfc,
-+ 0x20, 0xf8, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7d, 0x11, 0x12, 0x3b, 0x36,
-+ 0x37, 0x50, 0x57, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0x48, 0xa8, 0x94, 0x70, 0xf8, 0xa8,
-+ 0xfc, 0x00, 0xfc, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7d, 0x11, 0x12, 0x39, 0x37,
-+ 0x35, 0x51, 0x51, 0x11, 0x11, 0x16, 0x00, 0x00,
-+ 0x40, 0xfc, 0x08, 0xf8, 0x50, 0x60, 0xf8, 0x08,
-+ 0xf8, 0xf8, 0x08, 0xf8, 0x88, 0x04, 0x00, 0x00,
-+ 0x11, 0x17, 0x11, 0x7f, 0x12, 0x15, 0x3f, 0x34,
-+ 0x37, 0x50, 0x53, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x10, 0xfc, 0x10, 0xfc, 0x08, 0xf0, 0xfc, 0xc8,
-+ 0x68, 0xb0, 0x70, 0xa8, 0x24, 0xc0, 0x00, 0x00,
-+ 0x11, 0x11, 0x16, 0x7e, 0x11, 0x19, 0x36, 0x37,
-+ 0x31, 0x55, 0x55, 0x15, 0x19, 0x11, 0x00, 0x00,
-+ 0x10, 0x3c, 0xa8, 0xf8, 0x08, 0xfc, 0xa0, 0xf4,
-+ 0x34, 0xd8, 0xb8, 0xd4, 0x10, 0x60, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x1b, 0x36, 0x34,
-+ 0x37, 0x55, 0x57, 0x15, 0x17, 0x14, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00,
-+ 0xfc, 0x54, 0xfc, 0x54, 0xfc, 0x44, 0x00, 0x00,
-+ 0x12, 0x12, 0x15, 0x7f, 0x12, 0x15, 0x3f, 0x34,
-+ 0x37, 0x50, 0x51, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x48, 0x48, 0xf4, 0xac, 0xe8, 0xb4, 0xfc, 0x40,
-+ 0xfc, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x10, 0x14, 0x13, 0x7d, 0x13, 0x13, 0x3d, 0x34,
-+ 0x37, 0x50, 0x51, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x40, 0x84, 0xf4, 0x18, 0xf8, 0x14, 0xf4, 0x40,
-+ 0xfc, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x12, 0x1b, 0x36, 0x36,
-+ 0x32, 0x52, 0x52, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0xa8, 0xb8, 0xe8, 0xa8,
-+ 0xe8, 0x48, 0xe8, 0xa8, 0xe8, 0x18, 0x00, 0x00,
-+ 0x10, 0x17, 0x15, 0x7c, 0x17, 0x15, 0x3e, 0x3c,
-+ 0x34, 0x55, 0x55, 0x19, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf8, 0x90, 0xfc, 0xf0, 0xd8, 0x94,
-+ 0x40, 0x78, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x13, 0x12, 0x3b, 0x36,
-+ 0x34, 0x57, 0x50, 0x11, 0x10, 0x13, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0xb8, 0xa8, 0xb8, 0xa8,
-+ 0x44, 0xfc, 0x90, 0xe0, 0x70, 0x88, 0x00, 0x00,
-+ 0x11, 0x12, 0x13, 0x7e, 0x13, 0x1a, 0x37, 0x31,
-+ 0x33, 0x55, 0x50, 0x13, 0x10, 0x10, 0x00, 0x00,
-+ 0x98, 0xe8, 0x98, 0xe8, 0xb8, 0xa8, 0xfc, 0x70,
-+ 0xc8, 0xf4, 0x40, 0xf8, 0x40, 0xc0, 0x00, 0x00,
-+ 0x04, 0x7f, 0x14, 0x3e, 0x22, 0x3f, 0x3e, 0x22,
-+ 0x3f, 0x01, 0x7f, 0x07, 0x79, 0x01, 0x00, 0x00,
-+ 0x40, 0xfc, 0x60, 0xf8, 0x50, 0xfc, 0x20, 0xf8,
-+ 0x20, 0x00, 0xfc, 0xc0, 0x3c, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7f, 0x12, 0x17, 0x3b, 0x34,
-+ 0x37, 0x55, 0x55, 0x15, 0x17, 0x15, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xfc, 0x48, 0x58, 0x58, 0x40,
-+ 0xfc, 0xb4, 0xb4, 0xb4, 0xfc, 0xb4, 0x00, 0x00,
-+ 0x13, 0x1f, 0x68, 0x13, 0x2b, 0x7f, 0x3a, 0x57,
-+ 0x11, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x90, 0xd8, 0x68, 0x90, 0xa8, 0xfc, 0xb8, 0xd4,
-+ 0x10, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x10, 0x17, 0x15, 0x7f, 0x17, 0x15, 0x3f, 0x37,
-+ 0x36, 0x53, 0x53, 0x13, 0x11, 0x1e, 0x00, 0x00,
-+ 0x20, 0xfc, 0x40, 0xb8, 0xfc, 0x74, 0xfc, 0xf0,
-+ 0x10, 0xf0, 0xf0, 0xf4, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x12, 0x7f, 0x17, 0x3d, 0x57, 0x3f, 0x2a, 0x7b,
-+ 0x36, 0x2b, 0x3f, 0x26, 0x38, 0x1f, 0x00, 0x00,
-+ 0x10, 0xfc, 0xd0, 0x78, 0xd4, 0xfc, 0x88, 0x90,
-+ 0xe8, 0x90, 0xe4, 0x08, 0xb0, 0xc0, 0x00, 0x00,
-+ 0x14, 0x1f, 0x14, 0x7f, 0x1b, 0x1f, 0x35, 0x3f,
-+ 0x3d, 0x57, 0x57, 0x15, 0x17, 0x14, 0x00, 0x00,
-+ 0x80, 0xf8, 0xa8, 0xe8, 0x78, 0xe8, 0x38, 0xe8,
-+ 0x28, 0xb8, 0xb0, 0x54, 0xd4, 0x8c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0c, 0x12, 0x7d, 0x20, 0x3f, 0x28,
-+ 0x48, 0x7f, 0x08, 0x14, 0x23, 0x42, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa4, 0x28, 0x30,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x02, 0x34, 0x1c, 0x6a, 0x08, 0x7f, 0x11, 0x28,
-+ 0x7e, 0x2a, 0x2a, 0x2e, 0x29, 0x0a, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa4, 0x28, 0x30,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x11, 0x09, 0x41, 0x21, 0x0a, 0x14, 0x20, 0x21,
-+ 0x1f, 0x12, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x48, 0x50, 0x60, 0x90, 0x0c,
-+ 0xf0, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x0c, 0x12, 0x22, 0x7f, 0x02,
-+ 0x3a, 0x2a, 0x2a, 0x3a, 0x02, 0x07, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa4, 0x28, 0x30,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x0c, 0x12, 0x1e, 0x20, 0x7e, 0x23, 0x3e,
-+ 0x22, 0x3e, 0x3e, 0x20, 0x3e, 0x21, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa4, 0x28, 0x30,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x11, 0x1f,
-+ 0x29, 0x6d, 0x2b, 0x33, 0x3d, 0x27, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa4, 0x28, 0x30,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x03, 0x3c, 0x08, 0x7f, 0x08, 0x18, 0x6b, 0x49,
-+ 0x49, 0x6b, 0x49, 0x49, 0x7f, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa4, 0x28, 0x30,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x12, 0x34, 0x7f, 0x14, 0x3f, 0x15, 0x7f, 0x15,
-+ 0x3f, 0x16, 0x35, 0x35, 0x54, 0x15, 0x00, 0x00,
-+ 0x40, 0x40, 0xc0, 0x40, 0x7c, 0xa4, 0xa8, 0x30,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x7f, 0x40, 0x5e, 0x52, 0x5e, 0x40, 0x7f,
-+ 0x6d, 0x6d, 0x7f, 0x40, 0x7f, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x7c, 0xa4, 0xa8, 0x30,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x0c, 0x12, 0x3f, 0x5e, 0x12, 0x1f, 0x7f,
-+ 0x1b, 0x2d, 0x5b, 0x2d, 0x49, 0x1b, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa4, 0x28, 0x30,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x04, 0x07, 0x04, 0x3f, 0x2b, 0x3d, 0x27, 0x2a,
-+ 0x3b, 0x3b, 0x3b, 0x2a, 0x4f, 0x39, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xc0, 0x7c, 0xa4, 0xa8, 0x30,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x0a, 0x11, 0x3f, 0x40, 0x3f, 0x2d,
-+ 0x3f, 0x12, 0x1a, 0x17, 0x24, 0x49, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa4, 0x28, 0x30,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x18, 0x29, 0x2e, 0x28, 0x3f, 0x22, 0x2a, 0x3b,
-+ 0x2a, 0x2a, 0x7f, 0x0a, 0x11, 0x61, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xa0, 0xfc, 0xe4, 0xa8, 0xb0,
-+ 0xa0, 0xa0, 0xd0, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x14, 0x7f, 0x14, 0x77, 0x55, 0x77, 0x3f, 0x24,
-+ 0x7f, 0x24, 0x3f, 0x24, 0x3f, 0x21, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0xa4, 0x28, 0x30,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x3e, 0x22, 0x3f, 0x20, 0x3e, 0x22, 0x3f,
-+ 0x09, 0x2e, 0x28, 0x28, 0x2e, 0x70, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xfc, 0x08, 0xf8, 0x00, 0xfc,
-+ 0x28, 0xf8, 0xa8, 0xa8, 0xb8, 0x20, 0x00, 0x00,
-+ 0x00, 0x7f, 0x02, 0x02, 0x03, 0x04, 0x04, 0x0a,
-+ 0x11, 0x21, 0x00, 0x01, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf0, 0x10, 0x10, 0x20,
-+ 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x7e, 0x10, 0x10, 0x1e, 0x13, 0x32, 0x2b,
-+ 0x4c, 0x04, 0x08, 0x10, 0x20, 0x47, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0x88, 0x08, 0x30, 0xf8,
-+ 0x88, 0x90, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7e, 0x11, 0x10, 0x1e, 0x22, 0x33, 0x4a,
-+ 0x0c, 0x04, 0x08, 0x11, 0x22, 0x44, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x40, 0x40, 0x40, 0xfc, 0x40,
-+ 0x40, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x7f, 0x10, 0x10, 0x1f, 0x22, 0x32, 0x4b,
-+ 0x0c, 0x04, 0x09, 0x10, 0x20, 0x43, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0x28, 0x44, 0x80,
-+ 0x10, 0x60, 0x88, 0x10, 0x60, 0x80, 0x00, 0x00,
-+ 0x00, 0x7e, 0x10, 0x11, 0x1d, 0x25, 0x25, 0x57,
-+ 0x18, 0x08, 0x10, 0x11, 0x22, 0x44, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0xfc,
-+ 0x40, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x7e, 0x13, 0x11, 0x1d, 0x26, 0x27, 0x54,
-+ 0x18, 0x0f, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x08, 0x30, 0xd0, 0x48, 0x24, 0x04, 0xf8, 0x10,
-+ 0x60, 0xfc, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x7e, 0x10, 0x13, 0x1c, 0x24, 0x25, 0x54,
-+ 0x08, 0x0b, 0x10, 0x10, 0x20, 0x43, 0x00, 0x00,
-+ 0x50, 0x48, 0x7c, 0xc8, 0x30, 0x74, 0x8c, 0x54,
-+ 0x7c, 0xc8, 0x50, 0x34, 0xdc, 0x04, 0x00, 0x00,
-+ 0x00, 0x7e, 0x13, 0x11, 0x1c, 0x24, 0x27, 0x54,
-+ 0x19, 0x09, 0x11, 0x11, 0x21, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x10, 0x90, 0xa0, 0xfc, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x7d, 0x11, 0x11, 0x1c, 0x25, 0x25, 0x55,
-+ 0x19, 0x09, 0x11, 0x11, 0x21, 0x46, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x00, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0xf8, 0x98, 0x04, 0x00, 0x00,
-+ 0x01, 0x7f, 0x11, 0x13, 0x1d, 0x25, 0x25, 0x57,
-+ 0x19, 0x09, 0x12, 0x14, 0x21, 0x42, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xfc,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0x48, 0xb0, 0x00, 0x00,
-+ 0x00, 0x7f, 0x10, 0x11, 0x1c, 0x27, 0x26, 0x57,
-+ 0x19, 0x09, 0x11, 0x10, 0x27, 0x40, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xf0, 0x00, 0xfc, 0x08, 0xf8,
-+ 0xf0, 0x10, 0xf0, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x12, 0x13, 0x1c, 0x27, 0x26, 0x57,
-+ 0x1a, 0x0b, 0x10, 0x17, 0x20, 0x40, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0x00, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x7f, 0x12, 0x15, 0x1d, 0x26, 0x25, 0x57,
-+ 0x19, 0x09, 0x11, 0x11, 0x21, 0x46, 0x00, 0x00,
-+ 0x40, 0xfc, 0x08, 0xf8, 0x50, 0x60, 0xf8, 0x08,
-+ 0xf8, 0xf8, 0x08, 0xf8, 0x98, 0x04, 0x00, 0x00,
-+ 0x02, 0x7e, 0x13, 0x15, 0x38, 0x2f, 0x2a, 0x6e,
-+ 0x5a, 0x1e, 0x12, 0x16, 0x23, 0x4e, 0x00, 0x00,
-+ 0xa0, 0xb0, 0xe8, 0x68, 0x20, 0xfc, 0xa0, 0xe8,
-+ 0xa8, 0xd0, 0xd4, 0x9c, 0xec, 0x44, 0x00, 0x00,
-+ 0x01, 0x7d, 0x17, 0x11, 0x3f, 0x2a, 0x2e, 0x6a,
-+ 0x5e, 0x1a, 0x16, 0x13, 0x2e, 0x40, 0x00, 0x00,
-+ 0x20, 0x30, 0xe8, 0x28, 0xfc, 0xa0, 0xe8, 0xa8,
-+ 0xe8, 0xd0, 0x94, 0xec, 0x4c, 0x84, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x08, 0x08, 0x10, 0x60, 0x3f,
-+ 0x08, 0x04, 0x02, 0x03, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0xc0, 0x40, 0x44, 0x44, 0x3c, 0x00, 0xe0,
-+ 0x20, 0x40, 0x80, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x06, 0x38, 0x20, 0x3e, 0x22, 0x3e, 0x23, 0x3f,
-+ 0x20, 0x3e, 0x22, 0x22, 0x22, 0x4f, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x94, 0x94, 0x8c, 0x00, 0xf8,
-+ 0x88, 0x50, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x08, 0x7f, 0x08, 0x3e, 0x00, 0x3f, 0x22, 0x5d,
-+ 0x00, 0x1c, 0x14, 0x16, 0x24, 0x4b, 0x00, 0x00,
-+ 0x00, 0x70, 0x50, 0x50, 0x54, 0x54, 0x8c, 0xf8,
-+ 0x88, 0x50, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x40, 0x5e, 0x52, 0x5e, 0x41, 0x7f,
-+ 0x6d, 0x6d, 0x7f, 0x40, 0x7f, 0x41, 0x00, 0x00,
-+ 0x00, 0x70, 0x50, 0x50, 0x54, 0x94, 0x0c, 0xf8,
-+ 0x48, 0x50, 0x30, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x11, 0x11, 0x11, 0x7f, 0x11,
-+ 0x11, 0x11, 0x11, 0x3f, 0x20, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0x10, 0xfc, 0x10,
-+ 0x10, 0x10, 0x10, 0xfc, 0x20, 0xc0, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x20, 0x7e, 0x33, 0x2a, 0x7f,
-+ 0x32, 0x2a, 0x3f, 0x22, 0x05, 0x0e, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x30, 0x48, 0xfc, 0x04, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xac, 0x2c, 0x04, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x23, 0x41, 0x0e, 0x70, 0x1f,
-+ 0x03, 0x3e, 0x03, 0x7e, 0x02, 0x01, 0x00, 0x00,
-+ 0x00, 0x10, 0x18, 0x64, 0x84, 0x00, 0xe0, 0x00,
-+ 0xf0, 0x00, 0xfc, 0x00, 0x04, 0xfc, 0x00, 0x00,
-+ 0x04, 0x08, 0x73, 0x10, 0x1e, 0x71, 0x11, 0x1c,
-+ 0x71, 0x16, 0x10, 0x10, 0x10, 0x0f, 0x00, 0x00,
-+ 0x50, 0x48, 0xf8, 0x40, 0x48, 0x68, 0x70, 0xd0,
-+ 0x48, 0x44, 0x40, 0xc4, 0x04, 0xfc, 0x00, 0x00,
-+ 0x01, 0x7f, 0x00, 0x0f, 0x08, 0x0f, 0x3f, 0x20,
-+ 0x4f, 0x03, 0x1e, 0x03, 0x3e, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xe0, 0x20, 0xe0, 0xfc, 0xc8,
-+ 0x00, 0xf0, 0x00, 0xf8, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x0f, 0x03, 0x1e, 0x03, 0x3e, 0x01, 0x06,
-+ 0x38, 0x0e, 0x38, 0x0f, 0x79, 0x0f, 0x00, 0x00,
-+ 0xc0, 0x00, 0xe0, 0x00, 0xf0, 0x08, 0xf8, 0x18,
-+ 0xe0, 0x38, 0xe0, 0x3c, 0xe4, 0x3c, 0x00, 0x00,
-+ 0x04, 0x09, 0x71, 0x12, 0x1c, 0x71, 0x12, 0x1d,
-+ 0x71, 0x12, 0x10, 0x11, 0x12, 0x0f, 0x00, 0x00,
-+ 0x48, 0x48, 0x50, 0x60, 0x90, 0x50, 0x48, 0x48,
-+ 0x50, 0x60, 0x90, 0x14, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x26, 0x36, 0x37, 0x24,
-+ 0x27, 0x21, 0x2f, 0x21, 0x3f, 0x40, 0x00, 0x00,
-+ 0x80, 0xfc, 0x20, 0xfc, 0xb0, 0xb4, 0x2c, 0x60,
-+ 0x80, 0xf0, 0x00, 0xfc, 0x04, 0xfc, 0x00, 0x00,
-+ 0x04, 0x7f, 0x3f, 0x2e, 0x2a, 0x2e, 0x3f, 0x1f,
-+ 0x11, 0x1f, 0x1f, 0x11, 0x1f, 0x70, 0x00, 0x00,
-+ 0x08, 0xd0, 0xe0, 0xa0, 0xb8, 0xe0, 0xa0, 0x20,
-+ 0x3c, 0xe0, 0x20, 0x24, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x12, 0x7f, 0x42, 0x42, 0x43,
-+ 0x42, 0x46, 0x3e, 0x02, 0x03, 0x0c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x48, 0x40, 0xfc,
-+ 0x40, 0x20, 0x24, 0x94, 0x0c, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x10, 0x3f, 0x40, 0x3f, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xe0, 0x00, 0xf0, 0x10,
-+ 0x10, 0x10, 0x14, 0x0c, 0x0c, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x10, 0x3f, 0x40, 0x3f, 0x0f,
-+ 0x10, 0x7f, 0x04, 0x08, 0x10, 0x63, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xf0, 0x10,
-+ 0x90, 0xf0, 0x94, 0x8c, 0x8c, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x10, 0x3f, 0x40, 0x3f, 0x1f,
-+ 0x12, 0x1f, 0x15, 0x18, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xe0, 0x00, 0xf0, 0xd0,
-+ 0x50, 0xd0, 0x54, 0xcc, 0xcc, 0x44, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x10, 0x3f, 0x40, 0x3f, 0x12,
-+ 0x0a, 0x3f, 0x07, 0x0a, 0x32, 0x02, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x00, 0xe0, 0x00, 0xf0, 0x50,
-+ 0x90, 0xd0, 0x14, 0x8c, 0x4c, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x01, 0x7f, 0x01, 0x01, 0x7d,
-+ 0x05, 0x09, 0x09, 0x11, 0x61, 0x03, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0xfc, 0x00, 0x88, 0x88,
-+ 0x50, 0x60, 0x20, 0x10, 0x0c, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x42, 0x22, 0x22, 0x02, 0x0a,
-+ 0x0a, 0x12, 0x12, 0x23, 0x22, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0xf8, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x40, 0x20, 0x23, 0x00, 0x08,
-+ 0x08, 0x10, 0x10, 0x20, 0x27, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x40, 0x20, 0x20, 0x03, 0x08,
-+ 0x08, 0x10, 0x10, 0x20, 0x27, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x40, 0x40, 0xf8, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x22, 0x23, 0x02, 0x0a,
-+ 0x0a, 0x12, 0x12, 0x24, 0x24, 0x28, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x00, 0x00, 0xfc, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x40, 0x21, 0x21, 0x01, 0x09,
-+ 0x0b, 0x12, 0x10, 0x20, 0x2f, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xf0, 0x10, 0x10, 0x10,
-+ 0xf0, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x42, 0x22, 0x22, 0x02, 0x0a,
-+ 0x0a, 0x12, 0x12, 0x22, 0x2f, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x40, 0x20, 0x20, 0x02, 0x0a,
-+ 0x0a, 0x14, 0x14, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0x20, 0x20, 0x80, 0x80, 0x80, 0x88, 0x84,
-+ 0x84, 0x80, 0x80, 0x88, 0x88, 0x78, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x47, 0x20, 0x20, 0x03, 0x0a,
-+ 0x0a, 0x12, 0x12, 0x22, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x48,
-+ 0x48, 0x48, 0x48, 0x70, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x08, 0x09, 0x41, 0x22, 0x22, 0x07, 0x08,
-+ 0x08, 0x10, 0x11, 0x21, 0x22, 0x24, 0x00, 0x00,
-+ 0xe0, 0x20, 0x20, 0x10, 0x10, 0x08, 0xf4, 0x90,
-+ 0x90, 0x90, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x22, 0x22, 0x03, 0x0a,
-+ 0x0a, 0x12, 0x12, 0x22, 0x23, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x23, 0x22, 0x02, 0x0a,
-+ 0x0a, 0x12, 0x12, 0x24, 0x27, 0x2c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x88, 0x88, 0x50,
-+ 0x50, 0x20, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x11, 0x09, 0x09, 0x41, 0x22, 0x24, 0x00, 0x0b,
-+ 0x09, 0x10, 0x10, 0x20, 0x21, 0x2e, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x70, 0x00, 0xf8,
-+ 0x08, 0x90, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x40, 0x27, 0x20, 0x00, 0x08,
-+ 0x09, 0x11, 0x12, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40, 0xe0, 0xe0,
-+ 0x50, 0x50, 0x48, 0x44, 0x40, 0x40, 0x00, 0x00,
-+ 0x12, 0x0a, 0x0a, 0x42, 0x27, 0x22, 0x02, 0x0a,
-+ 0x0a, 0x12, 0x12, 0x22, 0x23, 0x22, 0x00, 0x00,
-+ 0x50, 0x50, 0x50, 0x50, 0xfc, 0x50, 0x50, 0x50,
-+ 0x50, 0x70, 0x50, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x43, 0x22, 0x22, 0x02, 0x0a,
-+ 0x0f, 0x10, 0x10, 0x20, 0x23, 0x2c, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0x48,
-+ 0xfc, 0x40, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x10, 0x0f, 0x09, 0x41, 0x27, 0x24, 0x04, 0x0f,
-+ 0x0d, 0x11, 0x11, 0x21, 0x21, 0x26, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x30, 0x48, 0x48, 0x5c, 0xe4, 0x04, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x47, 0x20, 0x20, 0x00, 0x0b,
-+ 0x0a, 0x12, 0x12, 0x22, 0x23, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x0f, 0x0d, 0x45, 0x25, 0x25, 0x05, 0x0d,
-+ 0x0e, 0x16, 0x14, 0x24, 0x27, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x48, 0x48, 0x58,
-+ 0x58, 0x38, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x0f, 0x0c, 0x44, 0x24, 0x24, 0x04, 0x0c,
-+ 0x0d, 0x15, 0x16, 0x24, 0x27, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x88, 0x88, 0x88, 0x88, 0xc8,
-+ 0x48, 0x28, 0x18, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x22, 0x23, 0x02, 0x0a,
-+ 0x0a, 0x12, 0x12, 0x24, 0x24, 0x28, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x00, 0x00, 0xfc, 0x20, 0xe0,
-+ 0x30, 0x28, 0x24, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x09, 0x09, 0x41, 0x21, 0x21, 0x01, 0x09,
-+ 0x09, 0x11, 0x11, 0x21, 0x2f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x10, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x25, 0x21, 0x01, 0x09,
-+ 0x09, 0x11, 0x11, 0x21, 0x21, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0x00, 0x00, 0x08, 0x30,
-+ 0xc0, 0x00, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x40, 0x20, 0x20, 0x00, 0x0b,
-+ 0x0a, 0x12, 0x12, 0x22, 0x23, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x22, 0x22, 0x03, 0x0a,
-+ 0x0a, 0x12, 0x12, 0x22, 0x23, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x48, 0xf8, 0x48,
-+ 0x48, 0x48, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x40, 0x20, 0x27, 0x00, 0x08,
-+ 0x08, 0x10, 0x12, 0x23, 0x24, 0x28, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x40, 0x40, 0xf8, 0x08, 0x10,
-+ 0x10, 0x20, 0x40, 0x80, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x23, 0x22, 0x02, 0x0b,
-+ 0x0a, 0x12, 0x12, 0x22, 0x23, 0x2e, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x48, 0x40, 0xfc,
-+ 0x20, 0x20, 0x10, 0x14, 0xcc, 0x04, 0x00, 0x00,
-+ 0x10, 0x0b, 0x08, 0x41, 0x21, 0x22, 0x00, 0x0f,
-+ 0x08, 0x10, 0x10, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x50, 0x48, 0x48, 0x40, 0xfc,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x22, 0x23, 0x02, 0x0a,
-+ 0x0b, 0x12, 0x12, 0x22, 0x23, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x08,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x40, 0x23, 0x20, 0x03, 0x0a,
-+ 0x0b, 0x12, 0x10, 0x20, 0x21, 0x26, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x40,
-+ 0xfc, 0x44, 0x58, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x12, 0x11, 0x21, 0x48, 0x0c, 0x12, 0x12, 0x30,
-+ 0x51, 0x11, 0x12, 0x12, 0x14, 0x14, 0x00, 0x00,
-+ 0x00, 0x78, 0x00, 0x00, 0x00, 0xfc, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x11, 0x09, 0x09, 0x43, 0x22, 0x24, 0x0e, 0x15,
-+ 0x14, 0x25, 0x26, 0x47, 0x44, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0x48, 0x68, 0xa8,
-+ 0xa8, 0x68, 0x28, 0xe8, 0x28, 0x30, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x43, 0x22, 0x22, 0x02, 0x0a,
-+ 0x0a, 0x12, 0x12, 0x22, 0x27, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x80, 0xf8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x40, 0x21, 0x23, 0x04, 0x08,
-+ 0x0b, 0x12, 0x12, 0x22, 0x23, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xf8, 0x04, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x08, 0x0a, 0x41, 0x21, 0x20, 0x07, 0x08,
-+ 0x08, 0x10, 0x11, 0x21, 0x22, 0x24, 0x00, 0x00,
-+ 0x40, 0x40, 0x48, 0x48, 0x50, 0x40, 0xfc, 0xa0,
-+ 0xa0, 0xa0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x10, 0x09, 0x09, 0x41, 0x22, 0x24, 0x07, 0x08,
-+ 0x08, 0x11, 0x11, 0x22, 0x24, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0xe0,
-+ 0xe0, 0x50, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x11, 0x09, 0x09, 0x41, 0x22, 0x23, 0x06, 0x0b,
-+ 0x0a, 0x13, 0x12, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xf8, 0x08, 0xc8, 0x48, 0xc8,
-+ 0x48, 0xc8, 0x48, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x11, 0x09, 0x09, 0x41, 0x2f, 0x22, 0x02, 0x0a,
-+ 0x0a, 0x17, 0x11, 0x21, 0x22, 0x24, 0x00, 0x00,
-+ 0x00, 0x00, 0x38, 0x28, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0x78, 0x28, 0x00, 0x00, 0x00,
-+ 0x10, 0x0f, 0x09, 0x41, 0x27, 0x25, 0x05, 0x0d,
-+ 0x0d, 0x16, 0x16, 0x24, 0x27, 0x24, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x58,
-+ 0x58, 0x38, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x0f, 0x0a, 0x42, 0x23, 0x24, 0x04, 0x0e,
-+ 0x09, 0x11, 0x11, 0x22, 0x24, 0x28, 0x00, 0x00,
-+ 0x08, 0xc8, 0x28, 0x28, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0x28, 0x28, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x27, 0x20, 0x00, 0x0f,
-+ 0x08, 0x10, 0x11, 0x21, 0x22, 0x24, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0xf8, 0x00, 0x00, 0xfc,
-+ 0xa0, 0xa0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x23, 0x20, 0x03, 0x0a,
-+ 0x0b, 0x12, 0x13, 0x22, 0x22, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x00, 0xf8, 0x08,
-+ 0xf8, 0x08, 0xf8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x24, 0x20, 0x07, 0x08,
-+ 0x09, 0x11, 0x12, 0x24, 0x28, 0x23, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0x80, 0x80, 0xfc, 0x80,
-+ 0x20, 0x20, 0x50, 0x48, 0xfc, 0x84, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x47, 0x21, 0x21, 0x02, 0x0c,
-+ 0x09, 0x13, 0x14, 0x20, 0x21, 0x2e, 0x00, 0x00,
-+ 0x40, 0x50, 0x98, 0xe4, 0x20, 0x24, 0x9c, 0xf0,
-+ 0x10, 0x20, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x47, 0x21, 0x21, 0x01, 0x0a,
-+ 0x0c, 0x10, 0x10, 0x21, 0x22, 0x24, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x50, 0x50, 0x58, 0xe4,
-+ 0x44, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x12, 0x0a, 0x0a, 0x4f, 0x22, 0x22, 0x02, 0x0a,
-+ 0x0b, 0x1e, 0x12, 0x22, 0x22, 0x27, 0x00, 0x00,
-+ 0x08, 0x10, 0x60, 0xc0, 0x40, 0x7c, 0x50, 0xd0,
-+ 0x50, 0x50, 0x50, 0x90, 0x90, 0x10, 0x00, 0x00,
-+ 0x10, 0x0f, 0x09, 0x41, 0x22, 0x22, 0x07, 0x09,
-+ 0x0d, 0x15, 0x12, 0x23, 0x24, 0x28, 0x00, 0x00,
-+ 0x04, 0x08, 0x70, 0x10, 0x10, 0x50, 0x5c, 0x50,
-+ 0x50, 0x50, 0x50, 0x3c, 0x80, 0x7c, 0x00, 0x00,
-+ 0x12, 0x09, 0x09, 0x47, 0x20, 0x23, 0x02, 0x0b,
-+ 0x0a, 0x10, 0x11, 0x22, 0x2c, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xf8, 0x48, 0xf8, 0x40, 0xfc,
-+ 0xc4, 0xc4, 0x44, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x20, 0x17, 0x10, 0x43, 0x2f, 0x23, 0x00, 0x13,
-+ 0x1f, 0x20, 0x27, 0x45, 0x47, 0x40, 0x00, 0x00,
-+ 0x80, 0xf8, 0x80, 0xf0, 0xfc, 0xe8, 0x80, 0xf0,
-+ 0xfc, 0x10, 0xfc, 0x50, 0x30, 0x30, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x43, 0x22, 0x23, 0x02, 0x08,
-+ 0x0b, 0x10, 0x10, 0x20, 0x27, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x48, 0x40,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x41, 0x21, 0x22, 0x07, 0x0a,
-+ 0x0b, 0x12, 0x13, 0x22, 0x20, 0x20, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x10, 0x50, 0x48, 0xfc, 0x48,
-+ 0xf8, 0x48, 0xf8, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x10, 0x0c, 0x0a, 0x43, 0x27, 0x21, 0x01, 0x0f,
-+ 0x09, 0x11, 0x12, 0x24, 0x28, 0x20, 0x00, 0x00,
-+ 0x08, 0x88, 0xa8, 0x28, 0xe8, 0x28, 0x28, 0xe8,
-+ 0x28, 0xa8, 0x68, 0x48, 0x08, 0x18, 0x00, 0x00,
-+ 0x12, 0x0a, 0x0b, 0x42, 0x22, 0x22, 0x03, 0x0a,
-+ 0x0a, 0x12, 0x13, 0x26, 0x24, 0x28, 0x00, 0x00,
-+ 0x08, 0x48, 0x58, 0xd8, 0xe8, 0x48, 0xf8, 0x48,
-+ 0xe8, 0xd8, 0x58, 0x48, 0x48, 0x08, 0x00, 0x00,
-+ 0x20, 0x1f, 0x11, 0x41, 0x29, 0x2e, 0x0a, 0x1a,
-+ 0x19, 0x2e, 0x28, 0x49, 0x4f, 0x48, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xa8, 0xa8, 0xc8, 0xc8,
-+ 0xa8, 0xa8, 0x98, 0x88, 0xf8, 0x08, 0x00, 0x00,
-+ 0x11, 0x09, 0x09, 0x47, 0x21, 0x21, 0x01, 0x09,
-+ 0x09, 0x17, 0x10, 0x20, 0x21, 0x26, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0xfc, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xfc, 0x00, 0x90, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x41, 0x23, 0x24, 0x00, 0x0b,
-+ 0x08, 0x12, 0x11, 0x21, 0x27, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xf8, 0x44, 0x40, 0xf8,
-+ 0x40, 0x48, 0x48, 0x50, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x23, 0x22, 0x02, 0x0a,
-+ 0x0a, 0x12, 0x12, 0x22, 0x23, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48, 0xe8,
-+ 0xa8, 0xa8, 0xe8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x09, 0x08, 0x43, 0x27, 0x20, 0x01, 0x09,
-+ 0x0b, 0x15, 0x19, 0x21, 0x21, 0x21, 0x00, 0x00,
-+ 0x10, 0xe0, 0xd0, 0x48, 0xfc, 0x80, 0xf8, 0x08,
-+ 0xf8, 0x08, 0xf8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x41, 0x21, 0x21, 0x02, 0x0c,
-+ 0x08, 0x17, 0x10, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0x10, 0x18, 0xa4, 0x44,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x22, 0x12, 0x12, 0x4f, 0x22, 0x23, 0x06, 0x16,
-+ 0x16, 0x2a, 0x2a, 0x42, 0x43, 0x42, 0x00, 0x00,
-+ 0x70, 0x10, 0x50, 0xd0, 0x48, 0x48, 0xa4, 0xa0,
-+ 0x20, 0x30, 0x48, 0x58, 0xe4, 0x04, 0x00, 0x00,
-+ 0x10, 0x09, 0x09, 0x42, 0x24, 0x23, 0x02, 0x0a,
-+ 0x0a, 0x12, 0x12, 0x22, 0x22, 0x22, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x44, 0x44, 0xf8, 0x08, 0xe8,
-+ 0xa8, 0xa8, 0xa8, 0xe8, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x24, 0x23, 0x00, 0x0f,
-+ 0x08, 0x13, 0x10, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x18, 0xf0, 0x48, 0x44, 0x04, 0xf8, 0x48, 0xfc,
-+ 0x48, 0xf8, 0x48, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x43, 0x20, 0x27, 0x00, 0x0b,
-+ 0x08, 0x17, 0x10, 0x21, 0x20, 0x27, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8,
-+ 0x40, 0xfc, 0x90, 0xe0, 0x70, 0x88, 0x00, 0x00,
-+ 0x22, 0x12, 0x12, 0x4f, 0x22, 0x23, 0x06, 0x16,
-+ 0x16, 0x2a, 0x2a, 0x52, 0x43, 0x42, 0x00, 0x00,
-+ 0x08, 0x10, 0x60, 0xc0, 0x40, 0x7c, 0xd0, 0xd0,
-+ 0x50, 0x50, 0x90, 0x90, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x47, 0x20, 0x20, 0x03, 0x08,
-+ 0x08, 0x17, 0x10, 0x20, 0x20, 0x27, 0x00, 0x00,
-+ 0x90, 0x88, 0xfc, 0x90, 0x50, 0x64, 0x9c, 0xa4,
-+ 0xfc, 0x90, 0x50, 0x24, 0xdc, 0x04, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x25, 0x20, 0x00, 0x0f,
-+ 0x08, 0x11, 0x11, 0x22, 0x24, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0xf0, 0x00, 0x00, 0xfc,
-+ 0x40, 0x50, 0x48, 0x44, 0x44, 0xc0, 0x00, 0x00,
-+ 0x12, 0x0a, 0x0a, 0x42, 0x2f, 0x22, 0x02, 0x0b,
-+ 0x0a, 0x12, 0x14, 0x24, 0x28, 0x33, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x50, 0xd0, 0x88, 0x24, 0x90,
-+ 0x90, 0xc0, 0xa0, 0x90, 0x88, 0x08, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x40, 0x27, 0x21, 0x01, 0x0a,
-+ 0x0c, 0x13, 0x10, 0x20, 0x27, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xfc, 0x20, 0x24, 0x5c,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x41, 0x23, 0x24, 0x03, 0x0a,
-+ 0x0a, 0x13, 0x12, 0x22, 0x22, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xf8, 0xa8,
-+ 0xa8, 0xf8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x11, 0x09, 0x09, 0x43, 0x22, 0x22, 0x07, 0x0a,
-+ 0x0a, 0x13, 0x12, 0x22, 0x23, 0x22, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x0f, 0x0c, 0x47, 0x24, 0x27, 0x04, 0x0b,
-+ 0x0a, 0x13, 0x12, 0x23, 0x22, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x0f, 0x09, 0x47, 0x25, 0x25, 0x06, 0x0f,
-+ 0x08, 0x17, 0x10, 0x20, 0x2f, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf8, 0x48, 0x58, 0x38, 0xf8,
-+ 0x80, 0xf8, 0x80, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x09, 0x0f, 0x41, 0x21, 0x27, 0x00, 0x0b,
-+ 0x0a, 0x12, 0x13, 0x22, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0x10, 0xfc, 0x08, 0xc8,
-+ 0x48, 0x48, 0xc8, 0x48, 0x08, 0x18, 0x00, 0x00,
-+ 0x20, 0x11, 0x12, 0x4f, 0x25, 0x25, 0x05, 0x16,
-+ 0x14, 0x2f, 0x20, 0x41, 0x46, 0x58, 0x00, 0x00,
-+ 0x80, 0xf0, 0x20, 0xf8, 0x48, 0x58, 0x58, 0x38,
-+ 0x88, 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x25, 0x20, 0x07, 0x08,
-+ 0x09, 0x11, 0x12, 0x24, 0x28, 0x23, 0x00, 0x00,
-+ 0x18, 0xf0, 0x48, 0x44, 0xf4, 0x80, 0xfc, 0x80,
-+ 0xf8, 0x48, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x23, 0x22, 0x03, 0x08,
-+ 0x0f, 0x10, 0x13, 0x20, 0x27, 0x20, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x00,
-+ 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x47, 0x20, 0x23, 0x02, 0x0b,
-+ 0x0a, 0x13, 0x10, 0x27, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xfc, 0x40, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x40, 0x21, 0x26, 0x01, 0x09,
-+ 0x09, 0x11, 0x11, 0x20, 0x27, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x20, 0x11, 0x1e, 0x42, 0x22, 0x2f, 0x02, 0x17,
-+ 0x16, 0x2a, 0x2a, 0x52, 0x42, 0x43, 0x00, 0x00,
-+ 0xa0, 0x20, 0x20, 0x24, 0x64, 0xe8, 0x70, 0xa0,
-+ 0xb0, 0xb0, 0x50, 0x48, 0x88, 0x04, 0x00, 0x00,
-+ 0x11, 0x09, 0x0f, 0x41, 0x21, 0x21, 0x01, 0x08,
-+ 0x0f, 0x10, 0x11, 0x22, 0x24, 0x20, 0x00, 0x00,
-+ 0x50, 0x50, 0xfc, 0x50, 0x70, 0x00, 0xf8, 0x40,
-+ 0xfc, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x23, 0x22, 0x03, 0x08,
-+ 0x0f, 0x10, 0x11, 0x22, 0x2c, 0x20, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x44,
-+ 0xe4, 0xe8, 0x50, 0x48, 0x44, 0xc0, 0x00, 0x00,
-+ 0x10, 0x0a, 0x0a, 0x42, 0x23, 0x20, 0x07, 0x08,
-+ 0x0b, 0x12, 0x12, 0x22, 0x22, 0x22, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0x48, 0xf8, 0x00, 0xfc, 0x80,
-+ 0xf8, 0xa8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x41, 0x21, 0x21, 0x00, 0x0b,
-+ 0x0a, 0x17, 0x10, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x08, 0xf8, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x10, 0x09, 0x0f, 0x41, 0x21, 0x27, 0x01, 0x09,
-+ 0x09, 0x17, 0x11, 0x22, 0x22, 0x24, 0x00, 0x00,
-+ 0x40, 0xfc, 0x10, 0x10, 0x7c, 0x90, 0x10, 0x7c,
-+ 0x90, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x20, 0x1f, 0x19, 0x49, 0x2f, 0x29, 0x09, 0x1f,
-+ 0x19, 0x29, 0x2f, 0x49, 0x40, 0x43, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x70, 0x68, 0x68, 0xa4, 0x2c,
-+ 0x28, 0x70, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x41, 0x27, 0x25, 0x05, 0x0d,
-+ 0x0d, 0x15, 0x15, 0x25, 0x27, 0x24, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x00, 0xf8, 0x28, 0x28, 0xe8,
-+ 0x28, 0xe8, 0x28, 0x28, 0xf8, 0x08, 0x00, 0x00,
-+ 0x22, 0x12, 0x1f, 0x42, 0x2f, 0x28, 0x17, 0x11,
-+ 0x12, 0x23, 0x2e, 0x42, 0x42, 0x47, 0x00, 0x00,
-+ 0x20, 0x20, 0xe0, 0x20, 0xf8, 0xa8, 0x28, 0x28,
-+ 0x28, 0xa8, 0x48, 0x48, 0x88, 0x30, 0x00, 0x00,
-+ 0x22, 0x1f, 0x12, 0x43, 0x20, 0x2f, 0x08, 0x1e,
-+ 0x1a, 0x2a, 0x2d, 0x48, 0x48, 0x48, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xe0, 0x80, 0xf8, 0x88, 0xe8,
-+ 0xa8, 0xa8, 0xd8, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x11, 0x08, 0x08, 0x41, 0x23, 0x2c, 0x07, 0x0c,
-+ 0x0e, 0x15, 0x16, 0x25, 0x24, 0x25, 0x00, 0x00,
-+ 0xc0, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xa8, 0xa8,
-+ 0xa8, 0xd0, 0xd0, 0xa8, 0xa8, 0xa8, 0x00, 0x00,
-+ 0x12, 0x0a, 0x0a, 0x42, 0x2f, 0x22, 0x02, 0x0b,
-+ 0x0a, 0x12, 0x12, 0x24, 0x24, 0x2b, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x3c, 0xc0, 0xf8, 0x08, 0x90,
-+ 0x90, 0xfc, 0x90, 0x90, 0x90, 0x30, 0x00, 0x00,
-+ 0x22, 0x12, 0x1f, 0x42, 0x2f, 0x2a, 0x0a, 0x1f,
-+ 0x12, 0x27, 0x26, 0x4a, 0x52, 0x42, 0x00, 0x00,
-+ 0x08, 0x28, 0xe8, 0x28, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0x28, 0x28, 0xa8, 0x88, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x24, 0x21, 0x00, 0x08,
-+ 0x0b, 0x10, 0x17, 0x20, 0x21, 0x26, 0x00, 0x00,
-+ 0x18, 0xf0, 0x88, 0x44, 0x54, 0x90, 0xa0, 0x50,
-+ 0xf8, 0x48, 0xfc, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x40, 0x27, 0x20, 0x01, 0x0f,
-+ 0x08, 0x13, 0x12, 0x22, 0x27, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xfc, 0xa0, 0x10, 0xf8,
-+ 0x08, 0xf8, 0xa8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x43, 0x22, 0x23, 0x02, 0x09,
-+ 0x09, 0x17, 0x10, 0x20, 0x21, 0x26, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x48, 0x48,
-+ 0x50, 0xfc, 0xa0, 0xa0, 0x24, 0x1c, 0x00, 0x00,
-+ 0x10, 0x0f, 0x0c, 0x47, 0x24, 0x25, 0x06, 0x0d,
-+ 0x0e, 0x15, 0x16, 0x25, 0x27, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x88, 0xd8, 0xd8, 0x68,
-+ 0xe8, 0x58, 0x58, 0x88, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x24, 0x23, 0x01, 0x08,
-+ 0x0f, 0x10, 0x13, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0x40, 0xf8, 0x10, 0xa0,
-+ 0xfc, 0x40, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x43, 0x22, 0x27, 0x05, 0x09,
-+ 0x0f, 0x10, 0x17, 0x21, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x00, 0xfc, 0x28, 0xd0,
-+ 0x1c, 0x10, 0xfc, 0x10, 0x90, 0x30, 0x00, 0x00,
-+ 0x28, 0x14, 0x15, 0x4f, 0x22, 0x2a, 0x0a, 0x1a,
-+ 0x1f, 0x2a, 0x22, 0x42, 0x44, 0x49, 0x00, 0x00,
-+ 0x80, 0xb8, 0x28, 0xe8, 0x28, 0xb8, 0xa8, 0xa8,
-+ 0xb8, 0xa8, 0x48, 0x48, 0x88, 0x18, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x41, 0x22, 0x25, 0x01, 0x09,
-+ 0x09, 0x12, 0x13, 0x25, 0x29, 0x21, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xf0, 0x08, 0xf4, 0x10, 0xf0,
-+ 0xf0, 0x00, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x11, 0x0a, 0x0a, 0x43, 0x22, 0x23, 0x02, 0x08,
-+ 0x0b, 0x11, 0x10, 0x20, 0x21, 0x2e, 0x00, 0x00,
-+ 0x40, 0x58, 0x48, 0x58, 0x48, 0x58, 0x48, 0x40,
-+ 0xf8, 0x10, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x42, 0x24, 0x20, 0x03, 0x0a,
-+ 0x0a, 0x13, 0x12, 0x22, 0x23, 0x22, 0x00, 0x00,
-+ 0x18, 0xf0, 0x48, 0x24, 0x24, 0x80, 0x38, 0x08,
-+ 0x08, 0xb8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x27, 0x24, 0x3f, 0x25, 0x26,
-+ 0x3d, 0x24, 0x24, 0x27, 0x24, 0x4c, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0xf8, 0xa0, 0xfc, 0x50, 0x48,
-+ 0x54, 0xd0, 0xe0, 0x50, 0x48, 0xc0, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x44, 0x25, 0x24, 0x07, 0x14,
-+ 0x15, 0x24, 0x25, 0x49, 0x49, 0x51, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xfc, 0x48,
-+ 0xf8, 0x40, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x43, 0x22, 0x23, 0x02, 0x0b,
-+ 0x0a, 0x10, 0x17, 0x21, 0x20, 0x20, 0x00, 0x00,
-+ 0x50, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x48, 0x10, 0xfc, 0x10, 0x90, 0x30, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x41, 0x20, 0x27, 0x04, 0x08,
-+ 0x0f, 0x10, 0x10, 0x20, 0x21, 0x26, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x10, 0xa0, 0xfc, 0x48, 0x40,
-+ 0xfc, 0x40, 0x78, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x45, 0x21, 0x21, 0x01, 0x09,
-+ 0x08, 0x17, 0x10, 0x20, 0x21, 0x26, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x40, 0xfc, 0x00, 0x90, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x23, 0x3c, 0x20, 0x22, 0x1e, 0x08, 0x0a,
-+ 0x7a, 0x1c, 0x2c, 0x2a, 0x49, 0x1b, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x22, 0x12, 0x1f, 0x49, 0x29, 0x2f, 0x09, 0x1f,
-+ 0x18, 0x2f, 0x28, 0x4f, 0x48, 0x49, 0x00, 0x00,
-+ 0x00, 0xf8, 0x10, 0x50, 0x50, 0x50, 0xfc, 0x20,
-+ 0x30, 0x30, 0x50, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x43, 0x22, 0x23, 0x01, 0x13,
-+ 0x16, 0x1b, 0x23, 0x22, 0x43, 0x42, 0x00, 0x00,
-+ 0xa0, 0xfc, 0xa0, 0xb8, 0xa8, 0xb8, 0x20, 0xfc,
-+ 0x40, 0xf8, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x20, 0x1f, 0x10, 0x47, 0x24, 0x27, 0x05, 0x15,
-+ 0x15, 0x27, 0x26, 0x4b, 0x4a, 0x51, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0xf0, 0x10,
-+ 0xf0, 0xf8, 0x48, 0xf8, 0x04, 0xfc, 0x00, 0x00,
-+ 0x20, 0x17, 0x10, 0x4f, 0x20, 0x27, 0x00, 0x17,
-+ 0x10, 0x27, 0x25, 0x45, 0x47, 0x45, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x50, 0x90, 0x10, 0x10,
-+ 0xfc, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x0f, 0x09, 0x42, 0x2f, 0x22, 0x02, 0x0b,
-+ 0x08, 0x11, 0x1f, 0x21, 0x21, 0x26, 0x00, 0x00,
-+ 0x40, 0xfc, 0x10, 0x08, 0xf4, 0x10, 0x10, 0xf0,
-+ 0xc8, 0x28, 0x30, 0x10, 0xc8, 0x04, 0x00, 0x00,
-+ 0x24, 0x24, 0x3f, 0x04, 0x7f, 0x15, 0x24, 0x45,
-+ 0x01, 0x7f, 0x05, 0x19, 0x61, 0x03, 0x00, 0x00,
-+ 0x40, 0xf8, 0x50, 0xf0, 0x90, 0xfc, 0x90, 0x30,
-+ 0x08, 0x90, 0x60, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x41, 0x21, 0x22, 0x07, 0x08,
-+ 0x0b, 0x1d, 0x10, 0x21, 0x20, 0x23, 0x00, 0x00,
-+ 0x40, 0x90, 0xf8, 0x10, 0x98, 0x64, 0xfc, 0xa0,
-+ 0x50, 0xac, 0x48, 0x90, 0x60, 0x80, 0x00, 0x00,
-+ 0x22, 0x12, 0x1f, 0x42, 0x2f, 0x2a, 0x0a, 0x1f,
-+ 0x13, 0x26, 0x26, 0x4a, 0x52, 0x43, 0x00, 0x00,
-+ 0x20, 0x20, 0xa0, 0x20, 0xfc, 0xe4, 0xa8, 0xb0,
-+ 0x20, 0xa0, 0xd0, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x25, 0x15, 0x1f, 0x45, 0x25, 0x28, 0x0f, 0x18,
-+ 0x17, 0x24, 0x24, 0x44, 0x44, 0x40, 0x00, 0x00,
-+ 0x50, 0x50, 0xfc, 0x50, 0xd4, 0x0c, 0xfc, 0x88,
-+ 0xf0, 0x90, 0x90, 0x90, 0xe0, 0x80, 0x00, 0x00,
-+ 0x20, 0x1e, 0x12, 0x42, 0x2e, 0x28, 0x08, 0x1f,
-+ 0x1a, 0x22, 0x22, 0x42, 0x42, 0x4d, 0x00, 0x00,
-+ 0x00, 0xf8, 0x80, 0xf0, 0x80, 0xf0, 0x80, 0xfc,
-+ 0xa8, 0xa8, 0x90, 0xb0, 0xc8, 0x84, 0x00, 0x00,
-+ 0x22, 0x12, 0x12, 0x45, 0x25, 0x2d, 0x15, 0x15,
-+ 0x15, 0x25, 0x25, 0x45, 0x45, 0x44, 0x00, 0x00,
-+ 0x20, 0x20, 0x7c, 0x48, 0xb0, 0x30, 0xec, 0x20,
-+ 0xfc, 0x70, 0x70, 0xa8, 0x24, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x11, 0x0f, 0x08, 0x43, 0x20, 0x27, 0x03, 0x09,
-+ 0x08, 0x17, 0x10, 0x21, 0x26, 0x20, 0x00, 0x00,
-+ 0x10, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0xf0, 0xc0,
-+ 0x68, 0xe8, 0xd0, 0x48, 0x44, 0xc0, 0x00, 0x00,
-+ 0x20, 0x1f, 0x14, 0x47, 0x24, 0x25, 0x07, 0x10,
-+ 0x1f, 0x28, 0x29, 0x4f, 0x48, 0x48, 0x00, 0x00,
-+ 0x80, 0xfc, 0x50, 0x50, 0xd0, 0x30, 0xf0, 0x80,
-+ 0xf8, 0xc8, 0x28, 0xd8, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x40, 0x27, 0x24, 0x06, 0x0d,
-+ 0x0e, 0x15, 0x15, 0x26, 0x27, 0x24, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x80, 0xf8, 0xa8, 0x68, 0x68,
-+ 0xd8, 0xc8, 0xa8, 0x58, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x0b, 0x08, 0x47, 0x21, 0x27, 0x01, 0x09,
-+ 0x0e, 0x17, 0x10, 0x20, 0x21, 0x26, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xfc, 0x10, 0xbc, 0x10, 0xbc,
-+ 0x00, 0xfc, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x20, 0x17, 0x14, 0x47, 0x25, 0x24, 0x07, 0x14,
-+ 0x17, 0x24, 0x29, 0x4f, 0x51, 0x43, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0xf0, 0x60, 0xfc, 0x40,
-+ 0xf8, 0x88, 0x90, 0x7c, 0x10, 0x30, 0x00, 0x00,
-+ 0x22, 0x12, 0x1f, 0x42, 0x2a, 0x2a, 0x0a, 0x13,
-+ 0x12, 0x23, 0x22, 0x43, 0x44, 0x48, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0xd8, 0xdc, 0x94, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x20, 0x12, 0x12, 0x42, 0x22, 0x2f, 0x02, 0x1a,
-+ 0x1b, 0x2a, 0x2a, 0x4b, 0x4e, 0x58, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x40, 0x40, 0xfc, 0x10, 0x50,
-+ 0xdc, 0x50, 0x50, 0x50, 0xfc, 0x00, 0x00, 0x00,
-+ 0x20, 0x1f, 0x12, 0x4a, 0x26, 0x24, 0x0b, 0x12,
-+ 0x1b, 0x2a, 0x2a, 0x4b, 0x4e, 0x58, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xe8, 0xa8, 0xc8, 0xb0, 0x10,
-+ 0xdc, 0x50, 0x50, 0x50, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x0b, 0x08, 0x47, 0x20, 0x23, 0x07, 0x09,
-+ 0x09, 0x16, 0x17, 0x21, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xfc, 0x10, 0xf0, 0xb8, 0x28,
-+ 0xb8, 0x10, 0xfc, 0x10, 0x90, 0x30, 0x00, 0x00,
-+ 0x22, 0x1f, 0x1a, 0x4a, 0x2f, 0x26, 0x07, 0x1a,
-+ 0x13, 0x22, 0x23, 0x42, 0x43, 0x42, 0x00, 0x00,
-+ 0x10, 0xfc, 0x50, 0x50, 0xfc, 0xb0, 0x34, 0x4c,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x26, 0x16, 0x1f, 0x4a, 0x3f, 0x25, 0x05, 0x15,
-+ 0x1b, 0x22, 0x23, 0x42, 0x43, 0x42, 0x00, 0x00,
-+ 0x30, 0x30, 0xfc, 0x50, 0xfc, 0x30, 0xb4, 0x4c,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x43, 0x22, 0x23, 0x01, 0x09,
-+ 0x09, 0x11, 0x11, 0x27, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xf8, 0xa8, 0xf8, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x22, 0x1a, 0x1a, 0x4a, 0x2f, 0x20, 0x0f, 0x10,
-+ 0x1f, 0x22, 0x2f, 0x42, 0x43, 0x5c, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xa0, 0xbc, 0x48, 0xe8, 0xa8,
-+ 0xb0, 0x10, 0x90, 0x28, 0xc8, 0x84, 0x00, 0x00,
-+ 0x10, 0x0b, 0x09, 0x47, 0x23, 0x22, 0x03, 0x0a,
-+ 0x0b, 0x10, 0x13, 0x20, 0x27, 0x20, 0x00, 0x00,
-+ 0x40, 0xf8, 0x10, 0xfc, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x41, 0x2f, 0x20, 0x01, 0x0e,
-+ 0x0b, 0x12, 0x13, 0x22, 0x23, 0x22, 0x00, 0x00,
-+ 0x18, 0xe8, 0x48, 0x50, 0xfc, 0xe0, 0x50, 0x4c,
-+ 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x11, 0x09, 0x0f, 0x41, 0x27, 0x20, 0x07, 0x0c,
-+ 0x0f, 0x14, 0x12, 0x22, 0x23, 0x2c, 0x00, 0x00,
-+ 0x10, 0x10, 0xe0, 0x28, 0xc8, 0x10, 0xd0, 0x64,
-+ 0xc4, 0x88, 0x88, 0xd0, 0x20, 0x40, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x43, 0x22, 0x22, 0x03, 0x08,
-+ 0x0b, 0x12, 0x13, 0x22, 0x23, 0x22, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xb8, 0xa8, 0xa8, 0xb8, 0xa0,
-+ 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x20, 0x17, 0x14, 0x47, 0x24, 0x27, 0x04, 0x17,
-+ 0x14, 0x27, 0x25, 0x4a, 0x4c, 0x50, 0x00, 0x00,
-+ 0x40, 0xfc, 0xd8, 0xfc, 0xa0, 0xf8, 0xa8, 0xfc,
-+ 0xa8, 0xf8, 0xb0, 0xa8, 0xa4, 0xa0, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x44, 0x23, 0x23, 0x0d, 0x09,
-+ 0x09, 0x11, 0x12, 0x22, 0x24, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa8, 0x10, 0xf8, 0x14, 0xf0,
-+ 0x10, 0xf0, 0x50, 0x48, 0x48, 0xc0, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x23, 0x22, 0x03, 0x0a,
-+ 0x0b, 0x10, 0x17, 0x20, 0x21, 0x26, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0xe8, 0x58, 0xe8, 0xf8, 0xe8,
-+ 0x58, 0x40, 0xfc, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x22, 0x12, 0x1f, 0x42, 0x2f, 0x29, 0x0f, 0x19,
-+ 0x1f, 0x22, 0x3f, 0x42, 0x42, 0x42, 0x00, 0x00,
-+ 0x20, 0x20, 0xb0, 0x50, 0x48, 0xfc, 0x20, 0x20,
-+ 0xfc, 0x20, 0xa0, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x09, 0x09, 0x41, 0x20, 0x27, 0x04, 0x0f,
-+ 0x08, 0x17, 0x10, 0x21, 0x26, 0x20, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xbc, 0xa4, 0xbc,
-+ 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x43, 0x20, 0x23, 0x00, 0x0f,
-+ 0x09, 0x17, 0x10, 0x23, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xf8, 0x40, 0xf8, 0x40, 0xfc,
-+ 0x10, 0xfc, 0x40, 0xf8, 0x40, 0x40, 0x00, 0x00,
-+ 0x20, 0x13, 0x1c, 0x47, 0x24, 0x27, 0x04, 0x17,
-+ 0x14, 0x24, 0x25, 0x49, 0x49, 0x51, 0x00, 0x00,
-+ 0x80, 0xf0, 0x40, 0xfc, 0xa4, 0x1c, 0xf0, 0xfc,
-+ 0xf0, 0xf0, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x0b, 0x09, 0x07, 0x41, 0x23, 0x22, 0x0b,
-+ 0x0a, 0x13, 0x12, 0x23, 0x21, 0x2e, 0x00, 0x00,
-+ 0x40, 0xf8, 0x50, 0xfc, 0x10, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0xf8, 0x98, 0x04, 0x00, 0x00,
-+ 0x10, 0x0b, 0x08, 0x43, 0x22, 0x27, 0x03, 0x08,
-+ 0x0b, 0x1c, 0x13, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xfc, 0x48, 0x58, 0x58, 0xa0,
-+ 0xf8, 0x04, 0xf8, 0x48, 0x70, 0x40, 0x00, 0x00,
-+ 0x20, 0x1f, 0x11, 0x4f, 0x25, 0x25, 0x07, 0x1a,
-+ 0x13, 0x22, 0x23, 0x42, 0x44, 0x48, 0x00, 0x00,
-+ 0x80, 0xfc, 0x48, 0xb0, 0xa8, 0xa8, 0xb8, 0x14,
-+ 0xf0, 0x10, 0xf0, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x43, 0x22, 0x23, 0x01, 0x0e,
-+ 0x0b, 0x12, 0x17, 0x23, 0x24, 0x28, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x10, 0xe8,
-+ 0x30, 0xa8, 0xfc, 0x48, 0xa4, 0xa4, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x42, 0x25, 0x21, 0x02, 0x09,
-+ 0x0f, 0x11, 0x11, 0x21, 0x21, 0x21, 0x00, 0x00,
-+ 0x40, 0x78, 0xfc, 0xe8, 0x10, 0x48, 0xa8, 0xf0,
-+ 0x1c, 0xf0, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x20, 0x1f, 0x12, 0x4c, 0x2f, 0x29, 0x0e, 0x1b,
-+ 0x1c, 0x29, 0x2e, 0x4b, 0x4c, 0x48, 0x00, 0x00,
-+ 0x00, 0xfc, 0xb0, 0x88, 0xf8, 0x98, 0xe8, 0xa8,
-+ 0xd8, 0x98, 0xe8, 0xa8, 0xd8, 0x98, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x45, 0x22, 0x24, 0x03, 0x0a,
-+ 0x0f, 0x10, 0x13, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0xfc, 0x48, 0xa8, 0x94, 0x74, 0xf8, 0xa8,
-+ 0xfc, 0x00, 0xf8, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x45, 0x22, 0x24, 0x01, 0x0f,
-+ 0x09, 0x11, 0x11, 0x21, 0x21, 0x26, 0x00, 0x00,
-+ 0x40, 0xfc, 0x08, 0xf0, 0x58, 0xe4, 0xf8, 0x08,
-+ 0xf8, 0xf8, 0x08, 0xf8, 0x98, 0x04, 0x00, 0x00,
-+ 0x22, 0x13, 0x12, 0x47, 0x24, 0x2c, 0x05, 0x14,
-+ 0x14, 0x24, 0x25, 0x44, 0x44, 0x45, 0x00, 0x00,
-+ 0x50, 0x54, 0xd8, 0xfc, 0x88, 0x50, 0xfc, 0x20,
-+ 0xf8, 0x20, 0xfc, 0x20, 0x50, 0x8c, 0x00, 0x00,
-+ 0x11, 0x0f, 0x09, 0x43, 0x22, 0x24, 0x07, 0x08,
-+ 0x0f, 0x10, 0x13, 0x20, 0x23, 0x20, 0x00, 0x00,
-+ 0x10, 0xfc, 0x10, 0xfc, 0xe8, 0x00, 0xfc, 0xc8,
-+ 0x68, 0xf0, 0x70, 0xa8, 0x24, 0xc0, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x47, 0x22, 0x23, 0x02, 0x0b,
-+ 0x08, 0x13, 0x1e, 0x29, 0x25, 0x24, 0x00, 0x00,
-+ 0x40, 0xfc, 0x88, 0x38, 0x08, 0xb8, 0x08, 0xf8,
-+ 0x80, 0xfc, 0xa4, 0x54, 0x04, 0x18, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x47, 0x21, 0x27, 0x00, 0x0b,
-+ 0x0f, 0x12, 0x13, 0x22, 0x23, 0x22, 0x00, 0x00,
-+ 0x40, 0xfc, 0x28, 0xc8, 0x50, 0xfc, 0xe0, 0x58,
-+ 0xfc, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x20, 0x1f, 0x19, 0x49, 0x2f, 0x29, 0x09, 0x1f,
-+ 0x19, 0x29, 0x2f, 0x46, 0x49, 0x51, 0x00, 0x00,
-+ 0x50, 0x48, 0x5c, 0xe8, 0x28, 0x34, 0xcc, 0x54,
-+ 0x5c, 0xe8, 0x28, 0x14, 0x6c, 0x84, 0x00, 0x00,
-+ 0x20, 0x17, 0x14, 0x47, 0x24, 0x27, 0x0f, 0x12,
-+ 0x1f, 0x26, 0x39, 0x42, 0x4c, 0x41, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xf8, 0x20,
-+ 0xfc, 0xb0, 0xcc, 0xb0, 0x88, 0x80, 0x00, 0x00,
-+ 0x11, 0x0f, 0x08, 0x41, 0x27, 0x21, 0x02, 0x0d,
-+ 0x09, 0x11, 0x11, 0x21, 0x21, 0x26, 0x00, 0x00,
-+ 0x10, 0xfc, 0x40, 0xf0, 0xfc, 0x10, 0xe8, 0xf4,
-+ 0x10, 0xf0, 0xf8, 0x50, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x22, 0x1f, 0x1d, 0x4b, 0x3e, 0x22, 0x05, 0x1f,
-+ 0x12, 0x2f, 0x2a, 0x47, 0x43, 0x4e, 0x00, 0x00,
-+ 0x08, 0xc8, 0x68, 0x68, 0xe8, 0x28, 0x28, 0xe8,
-+ 0x28, 0xe8, 0xa8, 0x08, 0x88, 0x18, 0x00, 0x00,
-+ 0x20, 0x10, 0x17, 0x44, 0x27, 0x24, 0x05, 0x15,
-+ 0x15, 0x25, 0x25, 0x4a, 0x4a, 0x54, 0x00, 0x00,
-+ 0x40, 0x78, 0xfc, 0xe8, 0x88, 0x78, 0xf0, 0x50,
-+ 0xf0, 0x50, 0xf8, 0xa4, 0x94, 0x70, 0x00, 0x00,
-+ 0x20, 0x1f, 0x12, 0x41, 0x27, 0x24, 0x07, 0x1e,
-+ 0x1b, 0x2f, 0x2b, 0x4e, 0x4a, 0x57, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0xf8, 0xf0, 0x10, 0xf0, 0xb8,
-+ 0xe8, 0x68, 0x78, 0xbc, 0xec, 0x44, 0x00, 0x00,
-+ 0x24, 0x14, 0x1f, 0x44, 0x2e, 0x2b, 0x0f, 0x1a,
-+ 0x1e, 0x25, 0x3e, 0x45, 0x44, 0x44, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x04, 0xf8, 0x48,
-+ 0xd8, 0x68, 0xd8, 0x68, 0x48, 0xd8, 0x00, 0x00,
-+ 0x22, 0x12, 0x1b, 0x44, 0x24, 0x2b, 0x02, 0x16,
-+ 0x17, 0x2a, 0x2a, 0x42, 0x42, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x48, 0x50, 0xfc, 0x50, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x20, 0x17, 0x15, 0x44, 0x27, 0x25, 0x06, 0x14,
-+ 0x15, 0x25, 0x25, 0x49, 0x4f, 0x50, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf8, 0x90, 0xfc, 0xf8, 0xd4, 0x40,
-+ 0x40, 0x78, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x20, 0x10, 0x17, 0x44, 0x27, 0x25, 0x05, 0x15,
-+ 0x15, 0x25, 0x27, 0x4a, 0x57, 0x40, 0x00, 0x00,
-+ 0x40, 0x78, 0xfc, 0xc8, 0x78, 0xf0, 0x50, 0xf0,
-+ 0x50, 0xf0, 0xf8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x22, 0x1f, 0x12, 0x47, 0x20, 0x3f, 0x07, 0x1a,
-+ 0x1e, 0x2f, 0x28, 0x4e, 0x4a, 0x52, 0x00, 0x00,
-+ 0x20, 0xfc, 0xa0, 0xf0, 0x90, 0xfc, 0xf0, 0xa8,
-+ 0xb8, 0xf8, 0x88, 0xb8, 0xa8, 0xa8, 0x00, 0x00,
-+ 0x20, 0x1f, 0x12, 0x43, 0x2f, 0x29, 0x09, 0x1f,
-+ 0x1b, 0x23, 0x23, 0x43, 0x43, 0x4d, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa8, 0x24, 0xfc, 0x6c, 0xfc, 0x6c,
-+ 0xb4, 0x6c, 0xfc, 0x6c, 0xb4, 0x2c, 0x00, 0x00,
-+ 0x20, 0x1f, 0x19, 0x4f, 0x29, 0x2f, 0x0f, 0x1b,
-+ 0x1b, 0x2a, 0x2b, 0x49, 0x4e, 0x48, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x78, 0x48, 0xf8, 0xf8, 0xe8,
-+ 0xe8, 0xa8, 0xe8, 0xc8, 0xb8, 0x98, 0x00, 0x00,
-+ 0x22, 0x12, 0x13, 0x44, 0x27, 0x28, 0x0f, 0x1b,
-+ 0x1b, 0x2f, 0x24, 0x44, 0x4b, 0x52, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xa0, 0xfc, 0x48, 0xe8, 0x68,
-+ 0x68, 0xd0, 0x90, 0xa8, 0x68, 0x44, 0x00, 0x00,
-+ 0x20, 0x1f, 0x10, 0x4f, 0x2d, 0x2f, 0x09, 0x1f,
-+ 0x19, 0x2f, 0x2b, 0x4a, 0x53, 0x6c, 0x00, 0x00,
-+ 0x00, 0x7c, 0x00, 0x78, 0xe8, 0xfc, 0x40, 0xf8,
-+ 0x48, 0xf8, 0xc8, 0x70, 0xc4, 0x3c, 0x00, 0x00,
-+ 0x24, 0x17, 0x1a, 0x44, 0x2e, 0x25, 0x0f, 0x1d,
-+ 0x17, 0x20, 0x27, 0x47, 0x48, 0x40, 0x00, 0x00,
-+ 0xc8, 0xec, 0x14, 0xc8, 0xdc, 0xe8, 0x3c, 0xec,
-+ 0xf0, 0x10, 0xf0, 0xf8, 0x08, 0xf0, 0x00, 0x00,
-+ 0x01, 0x03, 0x0d, 0x34, 0x02, 0x07, 0x79, 0x09,
-+ 0x09, 0x11, 0x22, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xf8, 0x10, 0xa0, 0xc0, 0x00, 0x08, 0x08,
-+ 0x10, 0x20, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x0a, 0x2a, 0x2c, 0x28, 0x49,
-+ 0x08, 0x0c, 0x12, 0x12, 0x21, 0x46, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xb0, 0xa8, 0xa8, 0xa4, 0x2c,
-+ 0x68, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x16, 0x36, 0x3a, 0x32, 0x52,
-+ 0x12, 0x1a, 0x16, 0x26, 0x22, 0x42, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xe8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xe8, 0xa8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x16, 0x36, 0x3b, 0x32, 0x52,
-+ 0x12, 0x1a, 0x16, 0x26, 0x22, 0x42, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xb8, 0x38, 0x18, 0xe8,
-+ 0xa8, 0xa8, 0xe8, 0xa8, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x0b, 0x2b, 0x2d, 0x29, 0x49,
-+ 0x09, 0x0d, 0x13, 0x13, 0x21, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08,
-+ 0xf8, 0x08, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x0a, 0x2d, 0x29, 0x2a, 0x48,
-+ 0x08, 0x0c, 0x12, 0x12, 0x20, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x40, 0x40, 0x78, 0x40,
-+ 0x40, 0x78, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x0a, 0x2b, 0x2d, 0x29, 0x49,
-+ 0x09, 0x0d, 0x13, 0x13, 0x21, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x68,
-+ 0x98, 0x98, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x0a, 0x2d, 0x29, 0x2b, 0x49,
-+ 0x09, 0x0d, 0x13, 0x13, 0x21, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf8, 0x08, 0xe8, 0x28, 0x28,
-+ 0xe8, 0x30, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x0b, 0x2b, 0x2d, 0x29, 0x49,
-+ 0x09, 0x0d, 0x13, 0x13, 0x21, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0xf8, 0x48, 0x48,
-+ 0x68, 0x98, 0x98, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x10, 0x17, 0x30, 0x50, 0x11, 0x12,
-+ 0x14, 0x10, 0x00, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0xe0, 0xe0, 0x50, 0x48,
-+ 0x44, 0x40, 0x00, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x00, 0x0f, 0x00, 0x01, 0x3f, 0x05, 0x09, 0x11,
-+ 0x63, 0x1f, 0x00, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x00, 0xe0, 0x40, 0x88, 0x48, 0x50, 0x20, 0x10,
-+ 0x0c, 0xf0, 0x00, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x0a, 0x2a, 0x2d, 0x28, 0x48,
-+ 0x0b, 0x0c, 0x12, 0x12, 0x20, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0xd0, 0x50, 0x20, 0xd8,
-+ 0xfc, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x09, 0x09, 0x7f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x1a, 0x15, 0x24, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0xf0,
-+ 0x00, 0xf8, 0x48, 0x28, 0x08, 0x70, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x0b, 0x2e, 0x28, 0x2f, 0x4b,
-+ 0x08, 0x0d, 0x12, 0x13, 0x20, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x90, 0x60, 0xf0, 0x4c, 0xf8,
-+ 0x40, 0xf0, 0x40, 0xf8, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x0b, 0x2b, 0x2d, 0x29, 0x49,
-+ 0x09, 0x0d, 0x13, 0x13, 0x21, 0x47, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0xf8, 0x20,
-+ 0x24, 0xf8, 0x20, 0x24, 0xe4, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x0b, 0x2a, 0x2c, 0x2b, 0x48,
-+ 0x09, 0x0d, 0x13, 0x13, 0x21, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x10, 0x90, 0xa0, 0xfc, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x16, 0x37, 0x3a, 0x32, 0x53,
-+ 0x12, 0x1f, 0x14, 0x24, 0x21, 0x46, 0x00, 0x00,
-+ 0x80, 0xf0, 0x20, 0x40, 0xf8, 0xa8, 0xb8, 0x18,
-+ 0x48, 0xfc, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x2b, 0x29, 0x29, 0x2b, 0x22,
-+ 0x3f, 0x20, 0x00, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0x78, 0x48, 0x40, 0x44,
-+ 0x44, 0x3c, 0x00, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x00, 0x2f, 0x2a, 0x2f, 0x29, 0x29, 0x2f, 0x2a,
-+ 0x2f, 0x48, 0x00, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x78, 0x48, 0x40, 0x44,
-+ 0xc4, 0x3c, 0x00, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x25, 0x27, 0x3d, 0x25, 0x25,
-+ 0x3d, 0x24, 0x00, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x80, 0x80, 0xf8, 0x08, 0xe8, 0x28, 0x28, 0xe8,
-+ 0x28, 0x08, 0x30, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x08, 0x2a, 0x2c, 0x55, 0x22, 0x3f, 0x20, 0x5f,
-+ 0x02, 0x02, 0x1f, 0x02, 0x02, 0x02, 0x00, 0x00,
-+ 0x20, 0xa8, 0xb0, 0x50, 0x88, 0xfc, 0x08, 0xf0,
-+ 0x10, 0x10, 0xd4, 0x0c, 0x0c, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x0b, 0x2b, 0x2d, 0x29, 0x48,
-+ 0x0b, 0x08, 0x15, 0x14, 0x23, 0x40, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x00,
-+ 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x0b, 0x2a, 0x2d, 0x28, 0x4b,
-+ 0x08, 0x0c, 0x12, 0x11, 0x22, 0x45, 0x00, 0x00,
-+ 0x18, 0xf0, 0x48, 0x24, 0x04, 0xf8, 0x40, 0xfc,
-+ 0x40, 0xf8, 0xc8, 0x30, 0x70, 0x8c, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x0b, 0x2b, 0x2d, 0x28, 0x4b,
-+ 0x09, 0x0d, 0x16, 0x14, 0x21, 0x42, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x00, 0xfc,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0x48, 0xb0, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x7f, 0x1f, 0x15, 0x13, 0x1f,
-+ 0x01, 0x3f, 0x01, 0x7f, 0x24, 0x42, 0x00, 0x00,
-+ 0x30, 0xc0, 0x00, 0xfc, 0xf0, 0x50, 0x90, 0xf0,
-+ 0x00, 0xf8, 0x00, 0xfc, 0x88, 0x44, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x17, 0x37, 0x3b, 0x32, 0x53,
-+ 0x10, 0x1b, 0x14, 0x27, 0x22, 0x44, 0x00, 0x00,
-+ 0x18, 0xe0, 0x40, 0xfc, 0xf8, 0x58, 0xe8, 0xf8,
-+ 0x40, 0xf8, 0x40, 0xfc, 0xa8, 0x54, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x0b, 0x2b, 0x2d, 0x29, 0x49,
-+ 0x09, 0x0c, 0x12, 0x12, 0x24, 0x40, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x40, 0xa8, 0x84, 0x94, 0x70, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x0b, 0x2a, 0x2d, 0x29, 0x49,
-+ 0x09, 0x0d, 0x13, 0x13, 0x21, 0x46, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xfc, 0x00, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0xf8, 0x98, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x3f, 0x2e, 0x3f, 0x36, 0x55,
-+ 0x2d, 0x09, 0x09, 0x12, 0x0c, 0x70, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0xfc, 0x48, 0xa8, 0x28, 0x08,
-+ 0x18, 0x10, 0x10, 0xa0, 0x60, 0x1c, 0x00, 0x00,
-+ 0x08, 0x3e, 0x08, 0x7f, 0x08, 0x7f, 0x08, 0x0e,
-+ 0x12, 0x23, 0x4c, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x90, 0x50, 0x50, 0x20,
-+ 0x50, 0x88, 0x04, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x17, 0x36, 0x3b, 0x32, 0x52,
-+ 0x12, 0x1a, 0x16, 0x26, 0x23, 0x42, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0xa8, 0xb8, 0xe8, 0xa8,
-+ 0xe8, 0xa8, 0xe8, 0xa8, 0x68, 0x18, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x1f, 0x0f, 0x08, 0x0f, 0x04,
-+ 0x7f, 0x0f, 0x08, 0x0f, 0x24, 0x42, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0xe0, 0x20, 0xe0, 0x40,
-+ 0xfc, 0xe0, 0x20, 0xe0, 0x88, 0x44, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x14, 0x36, 0x3f, 0x30, 0x53,
-+ 0x12, 0x1b, 0x16, 0x27, 0x22, 0x40, 0x00, 0x00,
-+ 0x20, 0x30, 0xe8, 0xa8, 0xa0, 0xfc, 0x20, 0xe8,
-+ 0x58, 0xd0, 0x54, 0xec, 0x4c, 0x84, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x17, 0x35, 0x3b, 0x31, 0x51,
-+ 0x16, 0x1b, 0x14, 0x24, 0x21, 0x46, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xfc, 0x10, 0xb8, 0x10, 0xfc,
-+ 0x00, 0xfc, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x14, 0x37, 0x3a, 0x33, 0x50,
-+ 0x13, 0x18, 0x15, 0x27, 0x21, 0x43, 0x00, 0x00,
-+ 0x20, 0x20, 0xe0, 0x20, 0xfc, 0xc8, 0xa8, 0x28,
-+ 0xb0, 0x90, 0xd0, 0x28, 0x48, 0x84, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x15, 0x37, 0x38, 0x31, 0x52,
-+ 0x17, 0x1a, 0x17, 0x26, 0x23, 0x42, 0x00, 0x00,
-+ 0x18, 0xe8, 0x48, 0x50, 0xfc, 0xe0, 0x50, 0x48,
-+ 0xfc, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x16, 0x35, 0x3b, 0x35, 0x51,
-+ 0x11, 0x19, 0x15, 0x25, 0x22, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa8, 0x10, 0xf8, 0x14, 0xf0,
-+ 0x10, 0xf0, 0x50, 0x48, 0x48, 0xc0, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x16, 0x37, 0x3a, 0x33, 0x52,
-+ 0x12, 0x1b, 0x17, 0x24, 0x21, 0x46, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0xe8, 0x58, 0xe8, 0xf8, 0xe8,
-+ 0xd8, 0x48, 0xfc, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x11, 0x16, 0x15, 0x14, 0x3f, 0x3c, 0x34, 0x57,
-+ 0x11, 0x1b, 0x15, 0x25, 0x21, 0x46, 0x00, 0x00,
-+ 0x00, 0x38, 0xa8, 0xa8, 0xac, 0xac, 0xc4, 0xf8,
-+ 0x28, 0xa8, 0x10, 0x10, 0xa8, 0x44, 0x00, 0x00,
-+ 0x12, 0x11, 0x11, 0x14, 0x36, 0x39, 0x31, 0x57,
-+ 0x11, 0x19, 0x15, 0x25, 0x22, 0x44, 0x00, 0x00,
-+ 0x30, 0x50, 0x48, 0x84, 0xfc, 0x24, 0xf4, 0x38,
-+ 0xd8, 0x34, 0xd4, 0x10, 0xe0, 0x7c, 0x00, 0x00,
-+ 0x12, 0x11, 0x11, 0x15, 0x36, 0x39, 0x31, 0x57,
-+ 0x11, 0x19, 0x15, 0x25, 0x22, 0x44, 0x00, 0x00,
-+ 0x20, 0xf8, 0x20, 0xfc, 0x48, 0x50, 0xfc, 0x20,
-+ 0xf8, 0x20, 0xfc, 0x20, 0xa0, 0x7c, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x17, 0x34, 0x3b, 0x30, 0x57,
-+ 0x12, 0x1c, 0x17, 0x22, 0x22, 0x47, 0x00, 0x00,
-+ 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8, 0x40, 0xfc,
-+ 0xa8, 0x54, 0xf8, 0xa8, 0xa8, 0xfc, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x7e, 0x10, 0x7a, 0x1e, 0x6c, 0x1a, 0x6a,
-+ 0x31, 0x09, 0x09, 0x12, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xf4, 0x34, 0xd8, 0x34, 0xd4,
-+ 0x60, 0x10, 0x10, 0xa0, 0x60, 0x1c, 0x00, 0x00,
-+ 0x10, 0x17, 0x12, 0x15, 0x36, 0x34, 0x3a, 0x53,
-+ 0x16, 0x1f, 0x17, 0x26, 0x23, 0x42, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xd8, 0xa8, 0xc8, 0x20, 0xf8,
-+ 0x40, 0xf0, 0xf0, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x12, 0x12, 0x15, 0x17, 0x36, 0x3d, 0x37, 0x50,
-+ 0x17, 0x10, 0x19, 0x26, 0x24, 0x40, 0x00, 0x00,
-+ 0x48, 0x48, 0xf4, 0xac, 0xe8, 0xb4, 0xfc, 0x40,
-+ 0xfc, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x14, 0x3f, 0x3d, 0x35, 0x55,
-+ 0x15, 0x15, 0x1f, 0x26, 0x2a, 0x57, 0x00, 0x00,
-+ 0x80, 0xf8, 0xfc, 0xc8, 0x78, 0xf0, 0x50, 0xf0,
-+ 0x50, 0xf0, 0xf8, 0xa8, 0xa8, 0xfc, 0x00, 0x00,
-+ 0x10, 0x17, 0x14, 0x1f, 0x3c, 0x37, 0x37, 0x55,
-+ 0x15, 0x15, 0x1d, 0x2c, 0x27, 0x44, 0x00, 0x00,
-+ 0x00, 0xbc, 0xa4, 0xbc, 0xa4, 0xfc, 0xfc, 0xf4,
-+ 0x54, 0xf4, 0xf4, 0xe4, 0x54, 0x4c, 0x00, 0x00,
-+ 0x0f, 0x15, 0x1f, 0x1e, 0x17, 0x3f, 0x24, 0x7f,
-+ 0x0e, 0x35, 0x7f, 0x15, 0x6a, 0x1c, 0x00, 0x00,
-+ 0xf0, 0xd0, 0xf0, 0xf0, 0xd0, 0xfc, 0x28, 0xfc,
-+ 0x70, 0xac, 0xfc, 0x30, 0xcc, 0x70, 0x00, 0x00,
-+ 0x00, 0x3f, 0x12, 0x11, 0x21, 0x5f, 0x01, 0x7f,
-+ 0x01, 0x01, 0x1f, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x30, 0xe0, 0x10, 0x08, 0x08, 0xf0, 0x10, 0xfc,
-+ 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x06, 0x3a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x2a, 0x29, 0x29, 0x28, 0x28, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xa8, 0xf8, 0x88, 0x80,
-+ 0x84, 0x84, 0x7c, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x10, 0x2f, 0x42, 0x7f, 0x04,
-+ 0x07, 0x0a, 0x09, 0x10, 0x23, 0x5c, 0x00, 0x00,
-+ 0x30, 0xe0, 0x10, 0x88, 0xf8, 0x00, 0xfc, 0x00,
-+ 0xf0, 0x20, 0x40, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x11, 0x2f, 0x48, 0x0f, 0x08,
-+ 0x08, 0x0f, 0x15, 0x1a, 0x2a, 0x50, 0x00, 0x00,
-+ 0x30, 0xe0, 0x10, 0x08, 0xe8, 0x20, 0xf0, 0x10,
-+ 0x10, 0xfc, 0x24, 0x94, 0x04, 0x38, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x01, 0x06, 0x38, 0x04, 0x04,
-+ 0x02, 0x02, 0x01, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x20, 0x40, 0x80, 0x60, 0x10, 0x40, 0x40, 0x40,
-+ 0x80, 0x80, 0x00, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x04, 0x05, 0x65, 0x19, 0x09, 0x15, 0x21, 0x45,
-+ 0x25, 0x19, 0x09, 0x15, 0x27, 0x40, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x10, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x04, 0x07, 0x04, 0x00, 0x3f,
-+ 0x02, 0x02, 0x02, 0x04, 0x08, 0x30, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xe0, 0x20, 0x20, 0xe0,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x04, 0x24, 0x24, 0x24, 0x3f, 0x24, 0x04, 0x7c,
-+ 0x15, 0x15, 0x16, 0x24, 0x24, 0x44, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x40, 0xe0, 0xe0,
-+ 0x50, 0x50, 0x48, 0x44, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x28, 0x2f, 0x29, 0x3b, 0x2c, 0x0f, 0x78,
-+ 0x2b, 0x2a, 0x2a, 0x2a, 0x2b, 0x4a, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x50, 0x58, 0xe4, 0xfc, 0x00,
-+ 0xf8, 0xe8, 0xa8, 0xe8, 0xf8, 0x08, 0x00, 0x00,
-+ 0x24, 0x24, 0x24, 0x25, 0x3e, 0x20, 0x21, 0x3c,
-+ 0x24, 0x27, 0x24, 0x24, 0x25, 0x44, 0x00, 0x00,
-+ 0x50, 0x48, 0x7c, 0xc8, 0x30, 0x74, 0x8c, 0x54,
-+ 0x7c, 0xc8, 0x30, 0x74, 0x8c, 0x04, 0x00, 0x00,
-+ 0x28, 0x2f, 0x29, 0x2b, 0x3e, 0x23, 0x23, 0x39,
-+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x4e, 0x00, 0x00,
-+ 0x40, 0xfc, 0xf0, 0xf8, 0xa8, 0x38, 0xf8, 0xf0,
-+ 0x10, 0xf0, 0xf0, 0xf0, 0x90, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x29, 0x29, 0x3f, 0x29, 0x29, 0x49,
-+ 0x0f, 0x79, 0x0b, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x08, 0x30, 0xe0, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0x20, 0xd0, 0x14, 0x0c, 0xfc, 0x04, 0x00, 0x00,
-+ 0x08, 0x0b, 0x28, 0x28, 0x3f, 0x28, 0x28, 0x4b,
-+ 0x0c, 0x79, 0x09, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0xf0, 0x90, 0x90, 0xfc,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x06, 0x38, 0x08, 0x7f, 0x1d, 0x1a, 0x2a, 0x49,
-+ 0x11, 0x1f, 0x21, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x80, 0x80, 0xf8, 0xa8, 0x28, 0x48, 0x88, 0x30,
-+ 0x00, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x02, 0x3c, 0x08, 0x7f, 0x1c, 0x1a, 0x2a, 0x49,
-+ 0x11, 0x1f, 0x21, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x08, 0x48, 0x48, 0x48, 0x48, 0x48, 0x08, 0x18,
-+ 0x00, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x09, 0x0f, 0x11, 0x3f, 0x01, 0x09, 0x28,
-+ 0x3e, 0x28, 0x4f, 0x79, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x00, 0xf8, 0x00, 0x20, 0xa0,
-+ 0xf8, 0xa0, 0x20, 0xfc, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x2b, 0x28, 0x3d, 0x29, 0x29, 0x48,
-+ 0x0f, 0x7a, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x00,
-+ 0xf8, 0x08, 0xe8, 0xa8, 0xe8, 0x18, 0x00, 0x00,
-+ 0x08, 0x2a, 0x2c, 0x49, 0x14, 0x22, 0x3f, 0x29,
-+ 0x4f, 0x11, 0x7f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x20, 0xa8, 0xb0, 0x20, 0x50, 0x88, 0xfc, 0x08,
-+ 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x0b, 0x29, 0x2b, 0x3e, 0x2b, 0x2b, 0x49,
-+ 0x0d, 0x79, 0x09, 0x09, 0x09, 0x0e, 0x00, 0x00,
-+ 0x40, 0xfc, 0xf0, 0xf8, 0xb8, 0x18, 0xf8, 0xf0,
-+ 0x10, 0xf0, 0xf0, 0xf0, 0x90, 0x08, 0x00, 0x00,
-+ 0x08, 0x0b, 0x28, 0x29, 0x3f, 0x29, 0x28, 0x4b,
-+ 0x0d, 0x7a, 0x0b, 0x09, 0x0a, 0x08, 0x00, 0x00,
-+ 0x90, 0xfc, 0x40, 0xf8, 0xfc, 0xe8, 0xa4, 0xfc,
-+ 0xe8, 0xa8, 0xd8, 0xd4, 0x6c, 0xc4, 0x00, 0x00,
-+ 0x04, 0x44, 0x28, 0x10, 0x37, 0x48, 0x08, 0x18,
-+ 0x28, 0x49, 0x09, 0x0a, 0x34, 0x18, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0x40, 0xfc, 0xc0, 0xc0, 0xc0,
-+ 0xc0, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x04, 0x44, 0x28, 0x10, 0x37, 0x48, 0x08, 0x18,
-+ 0x28, 0x49, 0x0a, 0x0c, 0x30, 0x10, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x60, 0x60, 0xa0,
-+ 0xa0, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x04, 0x47, 0x28, 0x10, 0x30, 0x48, 0x0b, 0x18,
-+ 0x28, 0x48, 0x08, 0x08, 0x3f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0x90, 0x90, 0xfc, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x48, 0x30, 0x13, 0x32, 0x4a, 0x0a, 0x1b,
-+ 0x2a, 0x48, 0x08, 0x08, 0x30, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0xf8,
-+ 0x48, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x48, 0x30, 0x11, 0x31, 0x49, 0x0a, 0x1a,
-+ 0x28, 0x48, 0x08, 0x09, 0x32, 0x14, 0x00, 0x00,
-+ 0x40, 0x40, 0x48, 0x48, 0x50, 0x60, 0x40, 0x60,
-+ 0x60, 0xa0, 0x90, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x4b, 0x32, 0x12, 0x33, 0x4a, 0x0a, 0x1b,
-+ 0x2a, 0x48, 0x08, 0x08, 0x30, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x04, 0x44, 0x2b, 0x10, 0x30, 0x4b, 0x0a, 0x1a,
-+ 0x2b, 0x4a, 0x08, 0x09, 0x32, 0x14, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xf8, 0xa8, 0xa8, 0xf8, 0xa8, 0xa0,
-+ 0xfc, 0xa4, 0xa4, 0x38, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x48, 0x31, 0x11, 0x33, 0x4c, 0x08, 0x19,
-+ 0x2f, 0x4a, 0x0a, 0x0a, 0x33, 0x12, 0x00, 0x00,
-+ 0x80, 0x80, 0xf0, 0x10, 0x20, 0xc0, 0xc0, 0x30,
-+ 0xfc, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x04, 0x45, 0x29, 0x11, 0x31, 0x49, 0x09, 0x19,
-+ 0x29, 0x49, 0x09, 0x09, 0x31, 0x17, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x10, 0xf4,
-+ 0x44, 0x28, 0x30, 0x10, 0xc8, 0x04, 0x00, 0x00,
-+ 0x08, 0x48, 0x37, 0x11, 0x31, 0x4b, 0x0d, 0x18,
-+ 0x28, 0x48, 0x08, 0x09, 0x32, 0x1c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0x08, 0x14, 0x14, 0xa0,
-+ 0xa0, 0x40, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x48, 0x30, 0x17, 0x31, 0x49, 0x09, 0x1a,
-+ 0x2c, 0x48, 0x08, 0x09, 0x32, 0x14, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x50, 0x50, 0x50, 0xe8,
-+ 0x44, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x4b, 0x32, 0x12, 0x33, 0x48, 0x0b, 0x1a,
-+ 0x2b, 0x4a, 0x0b, 0x0a, 0x32, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x00, 0xf8, 0x08,
-+ 0xf8, 0x08, 0xf8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x15, 0x16, 0x34, 0x57, 0x14,
-+ 0x14, 0x17, 0x14, 0x14, 0x11, 0x16, 0x00, 0x00,
-+ 0x80, 0x80, 0xf8, 0x90, 0x60, 0xe0, 0x1c, 0x50,
-+ 0x48, 0xfc, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x04, 0x44, 0x2b, 0x10, 0x30, 0x49, 0x0f, 0x18,
-+ 0x29, 0x49, 0x09, 0x09, 0x30, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xa0, 0x10, 0xfc, 0x08,
-+ 0xe8, 0x28, 0xe8, 0x28, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x4b, 0x32, 0x12, 0x33, 0x4a, 0x0a, 0x1b,
-+ 0x28, 0x48, 0x08, 0x09, 0x32, 0x14, 0x00, 0x00,
-+ 0x80, 0x38, 0x08, 0x08, 0xb8, 0x08, 0x08, 0xf8,
-+ 0xa0, 0xa0, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x4f, 0x30, 0x13, 0x30, 0x4f, 0x08, 0x1b,
-+ 0x2a, 0x4a, 0x0b, 0x0a, 0x32, 0x12, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x49, 0x31, 0x11, 0x31, 0x49, 0x09, 0x18,
-+ 0x2b, 0x4a, 0x0b, 0x0a, 0x33, 0x12, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x48, 0x37, 0x11, 0x31, 0x4a, 0x0c, 0x18,
-+ 0x2f, 0x48, 0x08, 0x08, 0x30, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0x10, 0xa8, 0x44, 0x40,
-+ 0xfc, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x09, 0x49, 0x31, 0x12, 0x33, 0x4e, 0x0a, 0x1a,
-+ 0x2b, 0x4b, 0x0a, 0x0a, 0x32, 0x13, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xfc, 0x80, 0xf8, 0xa0,
-+ 0x20, 0xfc, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x4a, 0x32, 0x13, 0x30, 0x4f, 0x08, 0x1b,
-+ 0x2a, 0x4a, 0x0a, 0x0a, 0x32, 0x12, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0xf8, 0x00, 0xfc, 0x40, 0xf8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x08, 0x4b, 0x32, 0x13, 0x32, 0x4b, 0x09, 0x19,
-+ 0x2a, 0x4d, 0x08, 0x08, 0x3f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x40, 0xf8,
-+ 0x40, 0xf0, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x4b, 0x32, 0x13, 0x32, 0x4b, 0x08, 0x1f,
-+ 0x29, 0x49, 0x09, 0x09, 0x31, 0x16, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x00, 0xfc,
-+ 0x48, 0x28, 0x30, 0x10, 0xc8, 0x04, 0x00, 0x00,
-+ 0x08, 0x4b, 0x32, 0x12, 0x32, 0x4f, 0x0c, 0x1b,
-+ 0x2a, 0x4b, 0x0a, 0x0b, 0x32, 0x12, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x90, 0xfc, 0x08, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x24, 0x24, 0x3f, 0x25, 0x04, 0x7f, 0x25, 0x24,
-+ 0x45, 0x01, 0x7f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x40, 0xf8, 0x50, 0x20, 0xd0, 0xfc, 0x10, 0xb0,
-+ 0x20, 0x10, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x09, 0x4f, 0x31, 0x13, 0x32, 0x4b, 0x0a, 0x1b,
-+ 0x28, 0x4f, 0x08, 0x08, 0x31, 0x16, 0x00, 0x00,
-+ 0x10, 0xfc, 0x10, 0xf8, 0x08, 0xf8, 0x08, 0xf8,
-+ 0x40, 0xfc, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x35, 0x2e, 0x2c, 0x3f, 0x04, 0x3f,
-+ 0x04, 0x07, 0x78, 0x15, 0x2a, 0x40, 0x00, 0x00,
-+ 0x10, 0x98, 0x94, 0x94, 0x90, 0xfc, 0x10, 0x90,
-+ 0x10, 0x90, 0x28, 0x28, 0xc4, 0x84, 0x00, 0x00,
-+ 0x10, 0x57, 0x36, 0x25, 0x35, 0x57, 0x15, 0x17,
-+ 0x37, 0x37, 0x57, 0x19, 0x1a, 0x34, 0x00, 0x00,
-+ 0x00, 0xfc, 0x50, 0x50, 0x90, 0xfc, 0x34, 0x58,
-+ 0x58, 0xd0, 0x30, 0x28, 0x48, 0x84, 0x00, 0x00,
-+ 0x08, 0x48, 0x31, 0x16, 0x33, 0x4b, 0x0a, 0x1b,
-+ 0x29, 0x49, 0x09, 0x09, 0x31, 0x11, 0x00, 0x00,
-+ 0x40, 0xa0, 0xf0, 0x0c, 0xf8, 0x58, 0xe8, 0xf8,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x4b, 0x32, 0x13, 0x31, 0x49, 0x0a, 0x1f,
-+ 0x2a, 0x4b, 0x08, 0x08, 0x37, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xf8, 0x00, 0xf8, 0x88, 0xe8,
-+ 0xa8, 0xe8, 0xa8, 0xf8, 0x18, 0x30, 0x00, 0x00,
-+ 0x08, 0x4b, 0x32, 0x16, 0x32, 0x4c, 0x0b, 0x1a,
-+ 0x2b, 0x48, 0x0f, 0x08, 0x30, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0x48, 0xa8, 0x94, 0x70, 0xf8, 0xa8,
-+ 0xf8, 0x00, 0xfc, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x77, 0x55, 0x77, 0x3f, 0x25, 0x3f, 0x25, 0x3f,
-+ 0x7f, 0x00, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x20, 0x28, 0x24, 0x24, 0x20, 0xfc, 0x20, 0x20,
-+ 0xa0, 0x30, 0x50, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x0a, 0x4c, 0x32, 0x13, 0x32, 0x4b, 0x0b, 0x1b,
-+ 0x2a, 0x4b, 0x0a, 0x0a, 0x33, 0x16, 0x00, 0x00,
-+ 0x48, 0x90, 0x48, 0xf8, 0xe8, 0xa8, 0xf8, 0x68,
-+ 0xd8, 0x68, 0xd8, 0x4c, 0x6c, 0x44, 0x00, 0x00,
-+ 0x04, 0x07, 0x3f, 0x2d, 0x37, 0x3f, 0x2f, 0x29,
-+ 0x2f, 0x3f, 0x36, 0x3f, 0x32, 0x52, 0x00, 0x00,
-+ 0x20, 0xa8, 0xa4, 0x24, 0x20, 0xfc, 0x20, 0x20,
-+ 0x30, 0xb0, 0xd0, 0xc8, 0x88, 0x84, 0x00, 0x00,
-+ 0x12, 0x52, 0x2f, 0x22, 0x3f, 0x5a, 0x1a, 0x3f,
-+ 0x32, 0x57, 0x16, 0x1a, 0x12, 0x62, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0x48, 0xf8, 0xc8, 0xf8, 0xc8,
-+ 0x78, 0x48, 0xf8, 0x30, 0x48, 0x88, 0x00, 0x00,
-+ 0x02, 0x02, 0x7a, 0x12, 0x1f, 0x12, 0x7a, 0x12,
-+ 0x12, 0x12, 0x1c, 0x64, 0x08, 0x13, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x38, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xb8, 0xa8, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x7d, 0x12, 0x12, 0x17, 0x7a, 0x12,
-+ 0x12, 0x12, 0x1a, 0x62, 0x02, 0x02, 0x00, 0x00,
-+ 0x20, 0x28, 0x24, 0x24, 0x3c, 0xe0, 0x20, 0x20,
-+ 0x20, 0x10, 0x14, 0x0c, 0x0c, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x7d, 0x11, 0x12, 0x14, 0x7c, 0x11,
-+ 0x11, 0x11, 0x1a, 0x64, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0xfc, 0x48, 0x50, 0x40, 0x60,
-+ 0x50, 0x48, 0x44, 0x44, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x00, 0x7f, 0x12, 0x12, 0x12, 0x7f, 0x12,
-+ 0x12, 0x12, 0x1a, 0x64, 0x05, 0x0e, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x48, 0x50, 0x40, 0xf8, 0x88,
-+ 0x50, 0x50, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x11, 0x11, 0x11, 0x7d, 0x11,
-+ 0x11, 0x11, 0x1d, 0x61, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0x80, 0xf8, 0x08, 0x08, 0x08, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x07, 0x7d, 0x11, 0x11, 0x11, 0x7d, 0x11,
-+ 0x11, 0x11, 0x19, 0x67, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0x10, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x10, 0x10, 0xf0, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x07, 0x7c, 0x17, 0x14, 0x14, 0x7f, 0x16,
-+ 0x16, 0x16, 0x1e, 0x66, 0x08, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x90, 0x90, 0xf0, 0xb0,
-+ 0xb0, 0xb0, 0xb4, 0xec, 0x8c, 0x84, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x11, 0x13, 0x14, 0x7c, 0x11,
-+ 0x17, 0x12, 0x1a, 0x62, 0x03, 0x02, 0x00, 0x00,
-+ 0x80, 0x80, 0xf0, 0x10, 0x20, 0xc0, 0xc0, 0x30,
-+ 0xfc, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x07, 0x7c, 0x13, 0x12, 0x12, 0x7f, 0x10,
-+ 0x13, 0x12, 0x1f, 0x62, 0x03, 0x02, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xb8, 0xa8, 0xa8, 0xb8, 0xa0,
-+ 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x7d, 0x11, 0x11, 0x11, 0x7d, 0x11,
-+ 0x11, 0x11, 0x1d, 0x61, 0x01, 0x06, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x08, 0xf8, 0x08, 0x08, 0xf8,
-+ 0x24, 0x24, 0x18, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x14, 0x17, 0x14, 0x7c, 0x17,
-+ 0x14, 0x15, 0x1c, 0x65, 0x06, 0x18, 0x00, 0x00,
-+ 0x00, 0x38, 0xa8, 0xa8, 0xb0, 0xb0, 0xa8, 0xe8,
-+ 0x64, 0xa4, 0xa4, 0x78, 0x60, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x13, 0x12, 0x12, 0x7f, 0x12,
-+ 0x12, 0x12, 0x1c, 0x64, 0x09, 0x12, 0x00, 0x00,
-+ 0x40, 0x78, 0x40, 0xfc, 0x48, 0x78, 0xc8, 0x38,
-+ 0xa0, 0xa0, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x03, 0x7c, 0x10, 0x11, 0x10, 0x7c, 0x17,
-+ 0x10, 0x11, 0x1d, 0x61, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x40, 0xf0, 0x90, 0x90, 0xfc,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x17, 0x10, 0x10, 0x7f, 0x10,
-+ 0x10, 0x11, 0x1f, 0x61, 0x02, 0x04, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xa0, 0xbc, 0xa0, 0xa0, 0xbc, 0xa0,
-+ 0xa0, 0xbc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x02, 0x01, 0x7d, 0x14, 0x12, 0x12, 0x7d, 0x11,
-+ 0x11, 0x12, 0x1e, 0x64, 0x05, 0x04, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x30, 0x48, 0x78, 0xc4, 0x04, 0x00, 0x00,
-+ 0x00, 0x07, 0x7c, 0x14, 0x17, 0x14, 0x7c, 0x17,
-+ 0x14, 0x14, 0x1f, 0x64, 0x04, 0x04, 0x00, 0x00,
-+ 0x00, 0xb8, 0x88, 0x88, 0xb8, 0x88, 0x00, 0xf8,
-+ 0x48, 0x28, 0xb0, 0x10, 0x28, 0xc4, 0x00, 0x00,
-+ 0x00, 0x03, 0x7e, 0x17, 0x10, 0x13, 0x7e, 0x13,
-+ 0x12, 0x13, 0x18, 0x67, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xfc, 0x40, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x7e, 0x08, 0x3e, 0x08, 0x7e, 0x02, 0x01,
-+ 0x05, 0x14, 0x14, 0x25, 0x46, 0x1b, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x20, 0x20,
-+ 0x50, 0x48, 0x84, 0x14, 0x10, 0xf0, 0x00, 0x00,
-+ 0x02, 0x02, 0x7c, 0x12, 0x12, 0x10, 0x7f, 0x12,
-+ 0x13, 0x12, 0x1a, 0x63, 0x03, 0x02, 0x00, 0x00,
-+ 0x48, 0x48, 0x90, 0x48, 0x48, 0x80, 0xf8, 0x28,
-+ 0xa8, 0x48, 0xa8, 0x18, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x03, 0x7e, 0x12, 0x12, 0x12, 0x7d, 0x11,
-+ 0x11, 0x11, 0x1d, 0x61, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xe8, 0x08, 0xe8, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x00, 0x7c, 0x11, 0x13, 0x14, 0x7f, 0x14,
-+ 0x16, 0x15, 0x1e, 0x65, 0x04, 0x05, 0x00, 0x00,
-+ 0xc0, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xa8, 0xa8,
-+ 0xa8, 0xd0, 0xd0, 0xa8, 0xa8, 0xa8, 0x00, 0x00,
-+ 0x08, 0x0a, 0x2a, 0x2c, 0x55, 0x22, 0x3f, 0x20,
-+ 0x7f, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x20, 0x28, 0xa8, 0xb0, 0x50, 0x88, 0xfc, 0x08,
-+ 0xf8, 0x00, 0xf0, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x7f, 0x12, 0x13, 0x12, 0x7e, 0x13,
-+ 0x10, 0x10, 0x1d, 0x61, 0x02, 0x0c, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x48, 0xf8, 0x48, 0x48, 0xf8,
-+ 0xd0, 0xd0, 0x68, 0x7c, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x01, 0x7d, 0x12, 0x17, 0x12, 0x7f, 0x12,
-+ 0x13, 0x12, 0x1b, 0x60, 0x03, 0x0c, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x44, 0xfc, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x08, 0xf8, 0xb0, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x03, 0x7e, 0x13, 0x12, 0x13, 0x7e, 0x13,
-+ 0x12, 0x10, 0x1e, 0x65, 0x09, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf8, 0x40, 0xf8, 0x40, 0xfc,
-+ 0x24, 0x94, 0x54, 0x44, 0x04, 0x18, 0x00, 0x00,
-+ 0x00, 0x03, 0x7e, 0x11, 0x11, 0x10, 0x7f, 0x10,
-+ 0x17, 0x12, 0x1e, 0x62, 0x03, 0x02, 0x00, 0x00,
-+ 0x38, 0xc8, 0x48, 0x50, 0x20, 0x40, 0xf8, 0x40,
-+ 0xfc, 0x48, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x07, 0x7d, 0x11, 0x13, 0x12, 0x7f, 0x10,
-+ 0x13, 0x10, 0x1d, 0x60, 0x07, 0x00, 0x00, 0x00,
-+ 0x10, 0xfc, 0x10, 0xf0, 0xf8, 0x48, 0xf8, 0x40,
-+ 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x7d, 0x10, 0x17, 0x11, 0x7d, 0x11,
-+ 0x11, 0x15, 0x18, 0x67, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0xf8, 0x10, 0xa0, 0xfc, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x02, 0x7d, 0x17, 0x11, 0x10, 0x7f, 0x10,
-+ 0x11, 0x10, 0x1f, 0x60, 0x01, 0x06, 0x00, 0x00,
-+ 0xa0, 0xa8, 0xb0, 0xfc, 0x10, 0xa0, 0xf8, 0x40,
-+ 0xf0, 0x40, 0xfc, 0x60, 0x90, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x3e, 0x21, 0x3e, 0x53, 0x1e,
-+ 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x20, 0xfc, 0x88, 0x50, 0xfc, 0x20, 0xfc, 0x20,
-+ 0xf8, 0x00, 0xf0, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x7e, 0x13, 0x12, 0x13, 0x7d, 0x11,
-+ 0x11, 0x15, 0x19, 0x67, 0x00, 0x07, 0x00, 0x00,
-+ 0x80, 0xf0, 0x20, 0xf8, 0xa8, 0xf8, 0x10, 0xf0,
-+ 0xf0, 0x10, 0xf8, 0x10, 0xe0, 0x1c, 0x00, 0x00,
-+ 0x01, 0x07, 0x7a, 0x12, 0x17, 0x10, 0x7f, 0x14,
-+ 0x17, 0x14, 0x1f, 0x64, 0x04, 0x05, 0x00, 0x00,
-+ 0x20, 0xfc, 0xa0, 0xb8, 0xc8, 0x38, 0xa0, 0xb8,
-+ 0xa0, 0xb8, 0xa0, 0xb8, 0xa4, 0x9c, 0x00, 0x00,
-+ 0x00, 0x07, 0x7c, 0x17, 0x17, 0x14, 0x7f, 0x13,
-+ 0x14, 0x17, 0x18, 0x61, 0x00, 0x07, 0x00, 0x00,
-+ 0x00, 0xbc, 0xa4, 0xbc, 0xbc, 0xa4, 0xbc, 0x28,
-+ 0xc4, 0xfc, 0x90, 0xd0, 0x78, 0x84, 0x00, 0x00,
-+ 0x00, 0x04, 0x7a, 0x12, 0x10, 0x10, 0x7f, 0x11,
-+ 0x11, 0x13, 0x1c, 0x60, 0x01, 0x0e, 0x00, 0x00,
-+ 0x84, 0x44, 0x48, 0x10, 0x80, 0x80, 0xfc, 0x10,
-+ 0x10, 0xa0, 0x60, 0x50, 0x88, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x19, 0x25, 0x5f, 0x01, 0x7f,
-+ 0x11, 0x1d, 0x25, 0x06, 0x06, 0x1d, 0x00, 0x00,
-+ 0x08, 0x30, 0xd0, 0x50, 0x50, 0x50, 0x50, 0x50,
-+ 0x50, 0x50, 0x70, 0x58, 0x78, 0xc4, 0x00, 0x00,
-+ 0x10, 0x10, 0x7f, 0x2b, 0x2b, 0x2b, 0x7f, 0x13,
-+ 0x1f, 0x73, 0x15, 0x15, 0x2f, 0x48, 0x00, 0x00,
-+ 0x50, 0x90, 0xfc, 0xa8, 0xa8, 0xa8, 0xfc, 0x90,
-+ 0x90, 0x7c, 0xd0, 0xd0, 0x30, 0x10, 0x00, 0x00,
-+ 0x00, 0x7f, 0x10, 0x10, 0x1e, 0x13, 0x12, 0x1a,
-+ 0x16, 0x16, 0x12, 0x16, 0x1a, 0x61, 0x00, 0x00,
-+ 0x20, 0xa0, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x24, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x7f, 0x10, 0x10, 0x1e, 0x12, 0x1b, 0x16,
-+ 0x16, 0x12, 0x12, 0x16, 0x1a, 0x61, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x20, 0x20, 0x24, 0x04, 0xfc, 0x00, 0x00,
-+ 0x07, 0x04, 0x19, 0x61, 0x02, 0x1f, 0x00, 0x7f,
-+ 0x04, 0x07, 0x05, 0x08, 0x0f, 0x70, 0x00, 0x00,
-+ 0xc0, 0x40, 0x30, 0x8c, 0x60, 0x90, 0x00, 0xfc,
-+ 0x00, 0xe0, 0x20, 0xa4, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x11, 0x10, 0x1e, 0x12, 0x1a, 0x16,
-+ 0x16, 0x12, 0x12, 0x16, 0x1a, 0x61, 0x00, 0x00,
-+ 0x20, 0x2c, 0xf0, 0x20, 0xa8, 0xa8, 0xa8, 0xf8,
-+ 0xa8, 0x20, 0x28, 0x1c, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x7f, 0x10, 0x10, 0x1e, 0x13, 0x1a, 0x16,
-+ 0x16, 0x12, 0x13, 0x16, 0x1a, 0x61, 0x00, 0x00,
-+ 0x70, 0x10, 0x50, 0x48, 0x88, 0xfc, 0x48, 0x48,
-+ 0x48, 0x88, 0x30, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x7f, 0x11, 0x10, 0x1e, 0x13, 0x1a, 0x16,
-+ 0x17, 0x12, 0x12, 0x16, 0x1a, 0x61, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x40, 0x78, 0xc0, 0x40, 0x7c,
-+ 0xc0, 0x40, 0x44, 0x3c, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x7f, 0x10, 0x10, 0x1e, 0x12, 0x1a, 0x16,
-+ 0x16, 0x12, 0x12, 0x16, 0x1a, 0x61, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0x88, 0xf8, 0x88, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x01, 0x01, 0x79, 0x02, 0x1c, 0x61, 0x06, 0x7f,
-+ 0x08, 0x0f, 0x0a, 0x11, 0x1f, 0x70, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x48, 0xd0, 0x20, 0x18, 0xfc,
-+ 0x00, 0xe0, 0x20, 0x24, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x14, 0x7f, 0x55, 0x55, 0x7f, 0x49,
-+ 0x08, 0x7f, 0x08, 0x08, 0x0e, 0x71, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x78, 0x48, 0x68, 0x58,
-+ 0x58, 0x48, 0x48, 0x5c, 0x6c, 0x84, 0x00, 0x00,
-+ 0x02, 0x3c, 0x08, 0x7e, 0x1d, 0x2a, 0x48, 0x7f,
-+ 0x04, 0x07, 0x05, 0x08, 0x0f, 0x70, 0x00, 0x00,
-+ 0x20, 0x24, 0xa4, 0xa8, 0x50, 0x48, 0x84, 0xfc,
-+ 0x00, 0xe0, 0x20, 0xa4, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x21, 0x21, 0x3d, 0x25, 0x35, 0x2d,
-+ 0x2d, 0x26, 0x26, 0x2d, 0x34, 0x63, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8,
-+ 0x20, 0xf8, 0x20, 0xfc, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x7f, 0x40, 0x5e, 0x52, 0x5e, 0x40, 0x7f,
-+ 0x6d, 0x6d, 0x7f, 0x40, 0x7f, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x78, 0x48, 0x68, 0x58,
-+ 0x58, 0x48, 0x4c, 0x5c, 0x64, 0x84, 0x00, 0x00,
-+ 0x08, 0x7f, 0x3e, 0x2a, 0x3e, 0x2a, 0x3e, 0x0a,
-+ 0x7f, 0x04, 0x7f, 0x24, 0x14, 0x0d, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x78, 0x48, 0x68, 0x58,
-+ 0x58, 0x48, 0x4c, 0x5c, 0x64, 0x84, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x1f, 0x12, 0x1f, 0x3f, 0x20,
-+ 0x5f, 0x04, 0x3f, 0x09, 0x0f, 0x70, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x90, 0xf0, 0xfc, 0x08,
-+ 0xf0, 0x00, 0xe0, 0x24, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x01, 0x7f, 0x08, 0x32, 0x0d, 0x0a, 0x7e, 0x04,
-+ 0x08, 0x3f, 0x04, 0x3f, 0x09, 0x7e, 0x00, 0x00,
-+ 0x00, 0xfc, 0x90, 0xfc, 0x90, 0xf8, 0xf8, 0x90,
-+ 0xfc, 0xf8, 0x00, 0xe4, 0x24, 0x9c, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3f, 0x20, 0x3e, 0x52, 0x1e,
-+ 0x7f, 0x04, 0x07, 0x09, 0x0f, 0x78, 0x00, 0x00,
-+ 0x20, 0xf8, 0x50, 0xfc, 0x20, 0xf8, 0x20, 0x20,
-+ 0xfc, 0x00, 0xe0, 0x24, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x11, 0x09, 0x3f, 0x20, 0x4f, 0x08, 0x0f, 0x08,
-+ 0x7f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x10, 0x20, 0xfc, 0x08, 0xe0, 0x20, 0xe0, 0x20,
-+ 0xfc, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x7f, 0x08, 0x3e, 0x2a, 0x3f, 0x2b, 0x3e,
-+ 0x6a, 0x28, 0x11, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xa0, 0xfc, 0x20, 0x20, 0xf8,
-+ 0x20, 0x20, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3f, 0x04, 0x03, 0x01, 0x3f, 0x21, 0x3f,
-+ 0x21, 0x21, 0x3f, 0x21, 0x21, 0x21, 0x00, 0x00,
-+ 0x00, 0xf8, 0x60, 0x80, 0x00, 0xf8, 0x08, 0xf8,
-+ 0x08, 0x08, 0xf8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x11, 0x11, 0x1f, 0x00,
-+ 0x7f, 0x01, 0x01, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0x10, 0xf0, 0x00,
-+ 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x02, 0x21, 0x11, 0x10, 0x00, 0x3f, 0x21, 0x21,
-+ 0x3f, 0x21, 0x21, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x10, 0x20, 0x40, 0xf8, 0x08, 0x08,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x54, 0x54, 0x55, 0x7e, 0x54,
-+ 0x54, 0x54, 0x7d, 0x45, 0x02, 0x04, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xa8, 0xa4,
-+ 0xa0, 0xa0, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x57, 0x54, 0x54, 0x7c, 0x54,
-+ 0x57, 0x54, 0x7d, 0x45, 0x02, 0x04, 0x00, 0x00,
-+ 0x90, 0x90, 0x90, 0xfc, 0x90, 0x90, 0x90, 0x90,
-+ 0xfc, 0x90, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x57, 0x54, 0x54, 0x7c, 0x57,
-+ 0x54, 0x54, 0x7c, 0x45, 0x02, 0x04, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0x40, 0xfc,
-+ 0x40, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x54, 0x55, 0x56, 0x7c, 0x57,
-+ 0x54, 0x54, 0x7f, 0x44, 0x00, 0x07, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0x28, 0xc4, 0x10,
-+ 0x20, 0xc8, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x00, 0x3e, 0x2a, 0x2a,
-+ 0x3e, 0x2a, 0x2a, 0x2a, 0x3f, 0x22, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x30, 0x48, 0x48, 0x7c, 0x84, 0x04, 0x00, 0x00,
-+ 0x02, 0x02, 0x04, 0x3f, 0x01, 0x7f, 0x04, 0x18,
-+ 0x7f, 0x11, 0x1f, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xc0, 0x70, 0x88, 0x00, 0xfc, 0x40, 0x30,
-+ 0xfc, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x57, 0x54, 0x54, 0x7d, 0x55,
-+ 0x57, 0x55, 0x7d, 0x45, 0x01, 0x06, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0xc0, 0xc8, 0x48, 0x50,
-+ 0x20, 0x20, 0x10, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x7f, 0x54, 0x54, 0x57, 0x7c, 0x54,
-+ 0x57, 0x55, 0x7c, 0x44, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x10, 0x10,
-+ 0xfc, 0x10, 0x90, 0x90, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x02, 0x07,
-+ 0x3c, 0x03, 0x7f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xf0,
-+ 0x40, 0x80, 0xfc, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x01, 0x1f, 0x7f, 0x01, 0x1f, 0x0f, 0x7f, 0x1f,
-+ 0x11, 0x1f, 0x11, 0x1f, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0xfc, 0x10, 0xf0, 0xe0, 0xfc, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x55, 0x57, 0x54, 0x7c, 0x57,
-+ 0x54, 0x55, 0x7d, 0x46, 0x04, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xf8, 0x44, 0x40, 0xfc,
-+ 0x40, 0x50, 0x48, 0x44, 0x44, 0xc0, 0x00, 0x00,
-+ 0x00, 0x00, 0x7f, 0x54, 0x54, 0x55, 0x7f, 0x54,
-+ 0x55, 0x55, 0x7d, 0x45, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xa0, 0x10, 0xfc, 0x08,
-+ 0xe8, 0x28, 0xe8, 0x28, 0x08, 0x18, 0x00, 0x00,
-+ 0x11, 0x09, 0x3f, 0x20, 0x4f, 0x08, 0x0f, 0x00,
-+ 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x10, 0x20, 0xfc, 0x08, 0xe0, 0x20, 0xe0, 0x00,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x7f, 0x05, 0x05, 0x3d, 0x21, 0x3d, 0x27,
-+ 0x15, 0x3d, 0x15, 0x1d, 0x65, 0x1b, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0xfc,
-+ 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0xfc, 0x00, 0x00,
-+ 0x00, 0x03, 0x7c, 0x55, 0x57, 0x55, 0x7c, 0x55,
-+ 0x57, 0x54, 0x7f, 0x46, 0x03, 0x02, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xf0, 0xfc, 0xe8, 0x40, 0xf0,
-+ 0xfc, 0x08, 0xfc, 0xa8, 0x98, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x7f, 0x54, 0x55, 0x54, 0x7f, 0x54,
-+ 0x57, 0x55, 0x7d, 0x46, 0x04, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0x90,
-+ 0xfc, 0x90, 0x50, 0x50, 0x10, 0x30, 0x00, 0x00,
-+ 0x0f, 0x09, 0x0f, 0x0f, 0x3e, 0x2a, 0x3e, 0x3e,
-+ 0x3f, 0x3f, 0x4f, 0x0f, 0x08, 0x7f, 0x00, 0x00,
-+ 0xe0, 0x20, 0xe0, 0xe0, 0xf8, 0xa8, 0xf8, 0xf8,
-+ 0xfc, 0xe8, 0xe0, 0xe0, 0x20, 0xfc, 0x00, 0x00,
-+ 0x0f, 0x09, 0x0f, 0x0f, 0x3e, 0x2a, 0x3e, 0x3f,
-+ 0x3f, 0x22, 0x47, 0x06, 0x09, 0x7f, 0x00, 0x00,
-+ 0xe0, 0x20, 0xe0, 0xe0, 0xf8, 0xa8, 0xf8, 0xf8,
-+ 0xfc, 0x08, 0xe0, 0x40, 0x40, 0xfc, 0x00, 0x00,
-+ 0x0f, 0x09, 0x0f, 0x0f, 0x38, 0x0e, 0x30, 0x3f,
-+ 0x2f, 0x4f, 0x0f, 0x08, 0x7f, 0x00, 0x00, 0x00,
-+ 0xe0, 0x20, 0xe0, 0xe0, 0x38, 0xe0, 0x18, 0xfc,
-+ 0xe8, 0xe0, 0xe0, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x28, 0x2f, 0x08, 0x18,
-+ 0x28, 0x48, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x00, 0x00, 0xfc, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x28, 0x29, 0x09, 0x1a,
-+ 0x2c, 0x48, 0x10, 0x11, 0x26, 0x58, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x80, 0x80, 0xf0, 0x10, 0x20,
-+ 0x20, 0x40, 0xc0, 0x20, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x28, 0x2a, 0x0a, 0x1a,
-+ 0x2a, 0x4a, 0x12, 0x12, 0x23, 0x42, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x40, 0x40, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x28, 0x28, 0x09, 0x1b,
-+ 0x2d, 0x49, 0x11, 0x11, 0x22, 0x44, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x40, 0x40, 0xa0, 0x10, 0x28,
-+ 0x24, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x28, 0x2f, 0x08, 0x18,
-+ 0x28, 0x49, 0x11, 0x12, 0x24, 0x58, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x90, 0x88, 0xfc, 0x80, 0xc0,
-+ 0xc0, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x4a, 0x2a, 0x2f, 0x0a, 0x1a,
-+ 0x2a, 0x4a, 0x12, 0x12, 0x24, 0x49, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x00, 0xb8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xb8, 0xa8, 0x80, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x49, 0x29, 0x2f, 0x09, 0x19,
-+ 0x29, 0x49, 0x11, 0x11, 0x21, 0x41, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x10, 0x10, 0xfc, 0x10, 0x10,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x28, 0x2f, 0x08, 0x18,
-+ 0x2b, 0x48, 0x10, 0x10, 0x2f, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x40, 0x40, 0xfc, 0x40, 0x90,
-+ 0x90, 0x60, 0x50, 0x98, 0xe4, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x51, 0x31, 0x35, 0x15, 0x15,
-+ 0x35, 0x55, 0x15, 0x25, 0x27, 0x5c, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x20, 0x20, 0x20, 0x24, 0xe8,
-+ 0x30, 0x20, 0x20, 0xe4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x2b, 0x2a, 0x0a, 0x1b,
-+ 0x2a, 0x4b, 0x12, 0x12, 0x2f, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x10, 0x10, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x2b, 0x2a, 0x0a, 0x1b,
-+ 0x2a, 0x4a, 0x13, 0x10, 0x2f, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x10, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x28, 0x29, 0x0e, 0x18,
-+ 0x2b, 0x4c, 0x10, 0x13, 0x20, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x80, 0xf0, 0x10, 0xa0, 0xc0,
-+ 0x30, 0xcc, 0x20, 0x80, 0x60, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x49, 0x29, 0x2b, 0x0c, 0x1b,
-+ 0x2a, 0x4b, 0x12, 0x12, 0x22, 0x41, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0x00, 0xf8, 0x08, 0xc8,
-+ 0x48, 0xc8, 0x70, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x0f, 0x48, 0x2f, 0x28, 0x0b, 0x18, 0x2b,
-+ 0x4a, 0x0f, 0x14, 0x10, 0x23, 0x4c, 0x00, 0x00,
-+ 0x80, 0xfc, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8,
-+ 0x40, 0xfc, 0x44, 0xb8, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x49, 0x28, 0x29, 0x0f, 0x18,
-+ 0x28, 0x4b, 0x10, 0x10, 0x2f, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0xc0, 0xa0, 0x10, 0xfc, 0x40,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x49, 0x28, 0x2f, 0x08, 0x1b,
-+ 0x28, 0x48, 0x1f, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0xa0, 0xfc, 0x40, 0xf8,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x2f, 0x2a, 0x0a, 0x1c,
-+ 0x2a, 0x4b, 0x10, 0x10, 0x2f, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xfc, 0x48, 0x48, 0x90,
-+ 0x48, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x28, 0x2f, 0x08, 0x1b,
-+ 0x28, 0x49, 0x15, 0x15, 0x29, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x40, 0x40, 0xfc, 0x40, 0xf8,
-+ 0x40, 0x20, 0x28, 0x04, 0x14, 0xf0, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x2f, 0x28, 0x09, 0x1e,
-+ 0x28, 0x4b, 0x12, 0x12, 0x23, 0x42, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xfc, 0x60, 0xd8, 0x44,
-+ 0x40, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x50, 0x37, 0x35, 0x16, 0x16,
-+ 0x35, 0x55, 0x15, 0x26, 0x24, 0x44, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xfc, 0x08, 0xe8, 0xa8,
-+ 0xa8, 0xe8, 0xa8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x4b, 0x28, 0x2f, 0x09, 0x1e,
-+ 0x28, 0x4f, 0x11, 0x13, 0x20, 0x47, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0xf0, 0x40, 0xfc, 0xf0, 0x4c,
-+ 0xc0, 0xfc, 0x20, 0xe0, 0xd0, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x1f, 0x50, 0x37, 0x34, 0x17, 0x14,
-+ 0x35, 0x55, 0x15, 0x24, 0x27, 0x44, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xe8, 0x28, 0xe8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x2f, 0x29, 0x09, 0x1b,
-+ 0x2c, 0x48, 0x1f, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x40, 0xfc, 0x10, 0x10, 0x28,
-+ 0xc4, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x2a, 0x2a, 0x0c, 0x19,
-+ 0x2e, 0x4a, 0x12, 0x14, 0x23, 0x4c, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x48, 0x48, 0x50, 0xb0, 0x4c,
-+ 0x48, 0x48, 0x50, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x48, 0x2b, 0x2a, 0x0b, 0x1a,
-+ 0x2b, 0x48, 0x11, 0x17, 0x20, 0x40, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x80, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0xa0, 0x20, 0xfc, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x49, 0x29, 0x2f, 0x09, 0x1b,
-+ 0x2b, 0x4b, 0x13, 0x15, 0x29, 0x41, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x10, 0x10, 0xfc, 0x10, 0xb8,
-+ 0xb8, 0xb8, 0xdc, 0x5c, 0x90, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x49, 0x29, 0x2f, 0x09, 0x1b,
-+ 0x2b, 0x4b, 0x15, 0x15, 0x29, 0x41, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x10, 0x10, 0xfc, 0x10, 0xb8,
-+ 0xb8, 0x78, 0x54, 0x94, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x1f, 0x50, 0x37, 0x34, 0x17, 0x17, 0x36,
-+ 0x56, 0x17, 0x14, 0x28, 0x2f, 0x50, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0xf0, 0x70, 0x90, 0xf0, 0xb0,
-+ 0xb0, 0xf0, 0xac, 0xfc, 0x14, 0x04, 0x00, 0x00,
-+ 0x00, 0x0f, 0x4b, 0x2a, 0x2b, 0x0a, 0x1b, 0x2f,
-+ 0x4a, 0x0b, 0x15, 0x19, 0x22, 0x45, 0x00, 0x00,
-+ 0x80, 0xfc, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xfc,
-+ 0x00, 0xf8, 0x48, 0x48, 0x88, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x4b, 0x29, 0x2b, 0x0c, 0x1f,
-+ 0x2e, 0x4d, 0x16, 0x15, 0x24, 0x45, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0xc0, 0x20, 0xf0, 0x0c, 0xa8,
-+ 0xa8, 0xd0, 0xd0, 0xa8, 0xa8, 0xa8, 0x00, 0x00,
-+ 0x00, 0x0f, 0x48, 0x2b, 0x2a, 0x0a, 0x1b, 0x2b,
-+ 0x48, 0x0b, 0x12, 0x12, 0x3f, 0x40, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0xf0, 0x90, 0xd0, 0x30, 0xf0,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x48, 0x28, 0x2b, 0x0a, 0x1b, 0x2a,
-+ 0x4a, 0x0a, 0x17, 0x14, 0x28, 0x50, 0x00, 0x00,
-+ 0x80, 0xfc, 0x40, 0x78, 0xfc, 0x78, 0xc8, 0x38,
-+ 0xf8, 0x80, 0xfc, 0x80, 0xf8, 0x80, 0x00, 0x00,
-+ 0x00, 0x0f, 0x48, 0x2f, 0x28, 0x0f, 0x19, 0x2f,
-+ 0x49, 0x09, 0x11, 0x11, 0x21, 0x41, 0x00, 0x00,
-+ 0x80, 0xfc, 0x40, 0x5c, 0x40, 0xbc, 0x10, 0xfc,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x0f, 0x48, 0x28, 0x29, 0x0f, 0x19, 0x29,
-+ 0x49, 0x09, 0x13, 0x13, 0x25, 0x49, 0x00, 0x00,
-+ 0x80, 0xfc, 0x40, 0xa0, 0xf0, 0xfc, 0x10, 0xf0,
-+ 0xf0, 0x00, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x1f, 0x51, 0x32, 0x37, 0x14, 0x16, 0x35,
-+ 0x5f, 0x16, 0x16, 0x26, 0x2a, 0x51, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0x38, 0xa8, 0xa8, 0xac, 0xc4,
-+ 0xf8, 0xa8, 0xa8, 0x90, 0xa8, 0xc4, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x4b, 0x2b, 0x2a, 0x0f, 0x18,
-+ 0x2b, 0x4a, 0x13, 0x12, 0x23, 0x42, 0x00, 0x00,
-+ 0x80, 0xfc, 0x80, 0x78, 0x28, 0xa8, 0xd8, 0x80,
-+ 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x0f, 0x48, 0x2b, 0x28, 0x0f, 0x19, 0x29,
-+ 0x49, 0x09, 0x11, 0x17, 0x20, 0x40, 0x00, 0x00,
-+ 0x80, 0xfc, 0x40, 0xf8, 0xa0, 0xfc, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x0f, 0x4b, 0x2a, 0x2b, 0x0a, 0x1b, 0x28,
-+ 0x4b, 0x08, 0x1f, 0x11, 0x26, 0x40, 0x00, 0x00,
-+ 0x80, 0xfc, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x90,
-+ 0x30, 0xc8, 0xfc, 0x58, 0x44, 0x40, 0x00, 0x00,
-+ 0x00, 0x0f, 0x48, 0x2b, 0x2f, 0x0b, 0x18, 0x2b,
-+ 0x4b, 0x08, 0x17, 0x11, 0x20, 0x47, 0x00, 0x00,
-+ 0x80, 0xfc, 0x40, 0xf8, 0xfc, 0xf8, 0x40, 0xf8,
-+ 0xf8, 0x40, 0xfc, 0x90, 0x70, 0x88, 0x00, 0x00,
-+ 0x00, 0x1f, 0x50, 0x37, 0x34, 0x17, 0x14, 0x37,
-+ 0x55, 0x15, 0x15, 0x25, 0x25, 0x45, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0xf8, 0xc8, 0xf8, 0xc8, 0xf8,
-+ 0xe8, 0x28, 0xe8, 0x28, 0xe8, 0x38, 0x00, 0x00,
-+ 0x00, 0x0f, 0x49, 0x2c, 0x2b, 0x0e, 0x1f, 0x29,
-+ 0x4f, 0x0c, 0x17, 0x11, 0x21, 0x46, 0x00, 0x00,
-+ 0x80, 0xfc, 0xd0, 0xd4, 0x24, 0x18, 0x74, 0x54,
-+ 0x9c, 0xf8, 0x48, 0x30, 0x30, 0xcc, 0x00, 0x00,
-+ 0x00, 0x0f, 0x49, 0x2d, 0x2d, 0x0a, 0x1c, 0x2f,
-+ 0x4c, 0x0f, 0x10, 0x11, 0x22, 0x4c, 0x00, 0x00,
-+ 0x80, 0xfc, 0x54, 0xb4, 0x58, 0xa8, 0xc4, 0xfc,
-+ 0x88, 0xf8, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x1f, 0x50, 0x37, 0x34, 0x17, 0x16, 0x37,
-+ 0x56, 0x16, 0x1f, 0x2a, 0x32, 0x44, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0xf8, 0x68, 0xec, 0xac, 0xc4,
-+ 0xb8, 0xa8, 0xf0, 0x90, 0x68, 0x44, 0x00, 0x00,
-+ 0x00, 0x0f, 0x49, 0x2f, 0x2b, 0x0a, 0x1b, 0x2a,
-+ 0x4b, 0x0f, 0x14, 0x14, 0x27, 0x44, 0x00, 0x00,
-+ 0x80, 0xfc, 0x10, 0xfc, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0xfc, 0x54, 0x7c, 0x8c, 0x0c, 0x00, 0x00,
-+ 0x00, 0x0f, 0x4a, 0x2a, 0x2b, 0x0a, 0x19, 0x2a,
-+ 0x4b, 0x0d, 0x1f, 0x13, 0x24, 0x48, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0xfc, 0x28, 0x90, 0xfc, 0x14,
-+ 0xd8, 0x5c, 0xd0, 0x70, 0xd0, 0x8c, 0x00, 0x00,
-+ 0x00, 0x0f, 0x49, 0x2f, 0x28, 0x0b, 0x1f, 0x29,
-+ 0x4b, 0x0d, 0x11, 0x11, 0x21, 0x47, 0x00, 0x00,
-+ 0x80, 0xfc, 0x10, 0xfc, 0x40, 0xf8, 0xfc, 0x50,
-+ 0xf8, 0x14, 0xf0, 0xf8, 0x70, 0x88, 0x00, 0x00,
-+ 0x00, 0x0f, 0x4b, 0x28, 0x2f, 0x0f, 0x1b, 0x2b,
-+ 0x4e, 0x0b, 0x13, 0x12, 0x23, 0x42, 0x00, 0x00,
-+ 0x80, 0xfc, 0xf8, 0x40, 0xfc, 0x58, 0x58, 0xf8,
-+ 0x20, 0xf8, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x52, 0x3f, 0x32, 0x1f, 0x1a, 0x3a,
-+ 0x5f, 0x17, 0x16, 0x2a, 0x32, 0x42, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0xf8, 0x28, 0xd8, 0xf8, 0xc8,
-+ 0xf8, 0x78, 0xc8, 0xf8, 0x28, 0xc4, 0x00, 0x00,
-+ 0x00, 0x1f, 0x51, 0x3e, 0x32, 0x12, 0x1f, 0x32,
-+ 0x57, 0x16, 0x1a, 0x32, 0x22, 0x42, 0x00, 0x00,
-+ 0x80, 0xfc, 0x20, 0xf8, 0x70, 0xfc, 0xf8, 0x48,
-+ 0x78, 0xf8, 0xc8, 0x78, 0x28, 0xc4, 0x00, 0x00,
-+ 0x00, 0x1f, 0x50, 0x37, 0x37, 0x15, 0x17, 0x35,
-+ 0x57, 0x14, 0x15, 0x29, 0x2f, 0x50, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0xfc, 0xb8, 0x10, 0xfc, 0x98,
-+ 0x74, 0x40, 0x78, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x52, 0x37, 0x39, 0x1f, 0x1a, 0x3f,
-+ 0x5a, 0x1f, 0x15, 0x2a, 0x2a, 0x50, 0x00, 0x00,
-+ 0x80, 0xfc, 0x48, 0xa8, 0x30, 0xfc, 0x90, 0xb8,
-+ 0x90, 0xfc, 0x90, 0xd0, 0xd0, 0x10, 0x00, 0x00,
-+ 0x00, 0x1f, 0x55, 0x3a, 0x35, 0x17, 0x14, 0x37,
-+ 0x5f, 0x1a, 0x1f, 0x28, 0x28, 0x47, 0x00, 0x00,
-+ 0x80, 0xfc, 0x68, 0xa8, 0x7c, 0xa8, 0xe8, 0xbc,
-+ 0xa8, 0xbc, 0xa8, 0x28, 0xbc, 0xa0, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x54, 0x37, 0x34, 0x13, 0x1b, 0x3b,
-+ 0x5b, 0x1a, 0x1b, 0x2f, 0x22, 0x4c, 0x00, 0x00,
-+ 0x80, 0xfc, 0x80, 0x7c, 0x90, 0xb8, 0xa8, 0xb8,
-+ 0xa8, 0xb8, 0xa8, 0xf8, 0x98, 0x64, 0x00, 0x00,
-+ 0x00, 0x00, 0x0f, 0x01, 0x22, 0x12, 0x0c, 0x08,
-+ 0x10, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x20, 0x20, 0xc8, 0x88, 0x50, 0x20,
-+ 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x1e, 0x02, 0x24, 0x14, 0x08, 0x1f, 0x21, 0x41,
-+ 0x3f, 0x01, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x90, 0x90, 0x64, 0x44, 0x28, 0xf0, 0x08, 0x04,
-+ 0xf8, 0x00, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x1e, 0x02, 0x24, 0x18, 0x1c, 0x64, 0x04, 0x3d,
-+ 0x23, 0x3c, 0x24, 0x04, 0x08, 0x33, 0x00, 0x00,
-+ 0x90, 0x94, 0x64, 0x28, 0xf8, 0xa4, 0xa8, 0x18,
-+ 0xf0, 0x90, 0xa0, 0x40, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x01, 0x02, 0x3f, 0x20, 0x3f, 0x20, 0x3f, 0x20,
-+ 0x10, 0x11, 0x1e, 0x10, 0x10, 0x0f, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08,
-+ 0x30, 0xc0, 0x00, 0x08, 0x08, 0xf8, 0x00, 0x00,
-+ 0x01, 0x02, 0x3f, 0x20, 0x3f, 0x20, 0x3f, 0x24,
-+ 0x04, 0x04, 0x08, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x88,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x11, 0x21, 0x79, 0x49, 0x49, 0x79, 0x49,
-+ 0x49, 0x4a, 0x7a, 0x44, 0x09, 0x16, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x88, 0x88, 0x50,
-+ 0x50, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x01, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x01, 0x7f,
-+ 0x02, 0x05, 0x19, 0x6f, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xfc,
-+ 0x80, 0x40, 0x30, 0xec, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x27, 0x79, 0x49, 0x4a, 0x7d, 0x49,
-+ 0x48, 0x48, 0x78, 0x48, 0x03, 0x0c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0x08, 0x14, 0x14, 0x10,
-+ 0xa0, 0xa0, 0x40, 0xa0, 0x18, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x23, 0x7a, 0x4d, 0x48, 0x78, 0x4f,
-+ 0x48, 0x78, 0x48, 0x01, 0x06, 0x18, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0xf0, 0x00, 0x00, 0xfc,
-+ 0xa0, 0xa0, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x10, 0x11, 0x21, 0x79, 0x4a, 0x4c, 0x7f, 0x48,
-+ 0x49, 0x49, 0x79, 0x49, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x7e, 0x1c, 0x1a, 0x28, 0x4a, 0x0d,
-+ 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x18, 0xe0, 0x80, 0xfc, 0x90, 0x90, 0x90, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x12, 0x22, 0x7b, 0x48, 0x4f, 0x78, 0x4b,
-+ 0x4a, 0x4b, 0x79, 0x48, 0x07, 0x00, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0xf8, 0x00, 0xfc, 0x00, 0xf8,
-+ 0x08, 0xf8, 0x10, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x3f, 0x2a, 0x2c, 0x29, 0x3e, 0x32,
-+ 0x2a, 0x24, 0x24, 0x2a, 0x32, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x84, 0xf4, 0x94, 0x94,
-+ 0xf4, 0x98, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x0c, 0x12, 0x7d, 0x14, 0x15, 0x2b, 0x48,
-+ 0x1e, 0x32, 0x4c, 0x0d, 0x13, 0x62, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0xa8, 0xb0, 0xa0, 0xf8, 0xc8,
-+ 0xa8, 0xb0, 0x90, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x00, 0x3f, 0x2a, 0x7f, 0x08, 0x3e, 0x2a, 0x3e,
-+ 0x2a, 0x3e, 0x08, 0x7f, 0x09, 0x0a, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0xa8, 0xb0, 0xa0, 0xf8, 0xc8,
-+ 0xa8, 0xb0, 0x90, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x3f, 0x2b, 0x2c, 0x28, 0x3e, 0x32,
-+ 0x2a, 0x24, 0x24, 0x2b, 0x32, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa8, 0xfc, 0x20, 0xf8, 0xa8, 0xf8,
-+ 0xa8, 0xf8, 0x20, 0xfc, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x1e, 0x2a, 0x6e, 0x3e, 0x2a, 0x14, 0x1e,
-+ 0x2a, 0x6e, 0x3e, 0x2a, 0x12, 0x25, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0xa8, 0xb0, 0xa0, 0xf8, 0xc8,
-+ 0xa8, 0xb0, 0x90, 0xb0, 0xc8, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x01, 0x7f, 0x01, 0x01, 0x03,
-+ 0x1f, 0x12, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0xf0, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x1f, 0x01, 0x7f, 0x02, 0x04, 0x3f, 0x00,
-+ 0x1f, 0x12, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x40, 0x70, 0x88, 0x00,
-+ 0xf0, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x04, 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x00,
-+ 0x1f, 0x12, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x00,
-+ 0xf0, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x02, 0x04, 0x1f, 0x60, 0x0f, 0x08, 0x0f,
-+ 0x00, 0x1f, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0xf0, 0x0c, 0xe0, 0x20, 0xe0,
-+ 0x00, 0xf0, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x02, 0x7f, 0x01, 0x01, 0x1e, 0x02, 0x7f, 0x01,
-+ 0x1e, 0x1f, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x20, 0xfc, 0x60, 0xc4, 0xb4, 0xec, 0x20, 0xc4,
-+ 0x34, 0xfc, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x1f, 0x01, 0x7f, 0x1f, 0x01, 0x7f, 0x14,
-+ 0x22, 0x5f, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xfc, 0xf0, 0x00, 0xfc, 0x90,
-+ 0x48, 0xf4, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x09, 0x31, 0x27, 0x3b, 0x23, 0x3d, 0x29, 0x23,
-+ 0x1f, 0x12, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0xb8, 0x88, 0x78, 0x28, 0x08,
-+ 0xf0, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x11, 0x1f, 0x10, 0x17, 0x14,
-+ 0x17, 0x14, 0x17, 0x2f, 0x29, 0x5f, 0x00, 0x00,
-+ 0x00, 0xf0, 0xfc, 0xe8, 0x10, 0xf0, 0xf0, 0x90,
-+ 0xf0, 0x90, 0xf0, 0xf8, 0x48, 0xfc, 0x00, 0x00,
-+ 0x11, 0x09, 0x41, 0x21, 0x0f, 0x11, 0x13, 0x24,
-+ 0x21, 0x1f, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0xf0, 0x10, 0xf0, 0xf0, 0xfc, 0x00, 0xfc, 0xa4,
-+ 0x58, 0xf0, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x23, 0x13, 0x43, 0x2f, 0x13,
-+ 0x2d, 0x42, 0x1f, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0xd0, 0xf0, 0xfc, 0xf8,
-+ 0x48, 0xb0, 0xf0, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x01, 0x79, 0x4a, 0x4c, 0x7b, 0x48, 0x48,
-+ 0x79, 0x49, 0x48, 0x78, 0x48, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0x10, 0x08, 0xf4, 0x80, 0xf0,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x4b, 0x4a, 0x7a, 0x48, 0x48,
-+ 0x78, 0x48, 0x49, 0x7a, 0x4c, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x48, 0x40, 0x60, 0x60,
-+ 0xa0, 0xa0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x49, 0x49, 0x79, 0x4a, 0x4a,
-+ 0x7c, 0x48, 0x48, 0x78, 0x49, 0x0e, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x50, 0x48, 0x44, 0x4c, 0x48,
-+ 0x50, 0xd0, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x4a, 0x4a, 0x7a, 0x4a, 0x4a,
-+ 0x7b, 0x4a, 0x4a, 0x78, 0x48, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x78, 0x48, 0x48, 0x48,
-+ 0xf8, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x4f, 0x48, 0x7a, 0x49, 0x48,
-+ 0x78, 0x48, 0x48, 0x79, 0x4f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x50, 0x90, 0xa0,
-+ 0x60, 0x60, 0x90, 0x38, 0xc4, 0x04, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4a, 0x4b, 0x7a, 0x4a, 0x4a,
-+ 0x7a, 0x4a, 0x4a, 0x7c, 0x4c, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x88, 0x80, 0x88,
-+ 0xb0, 0xc0, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x11, 0x1e, 0x0f, 0x27, 0x24, 0x27, 0x24,
-+ 0x27, 0x24, 0x27, 0x3f, 0x0c, 0x70, 0x00, 0x00,
-+ 0x30, 0xc0, 0x08, 0xf8, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0xfc, 0x30, 0x0c, 0x00, 0x00,
-+ 0x04, 0x14, 0x17, 0x14, 0x17, 0x78, 0x1f, 0x10,
-+ 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0x48, 0x70, 0x44, 0x44, 0x3c, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x4a, 0x4a, 0x7a, 0x4a, 0x4a,
-+ 0x7a, 0x4a, 0x4a, 0x7a, 0x4b, 0x0c, 0x00, 0x00,
-+ 0x90, 0x90, 0x90, 0x90, 0x94, 0xf8, 0x90, 0x90,
-+ 0x90, 0x90, 0xb0, 0xd4, 0x14, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x4b, 0x48, 0x78, 0x4f, 0x48,
-+ 0x78, 0x49, 0x4a, 0x7c, 0x48, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0xe0,
-+ 0xe0, 0x50, 0x48, 0x44, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x09, 0x0f, 0x12, 0x7f, 0x08, 0x1f, 0x68,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x20, 0xf0, 0x90, 0xfc, 0x20, 0xf0, 0x2c,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x4f, 0x49, 0x79, 0x4b, 0x4c,
-+ 0x78, 0x4f, 0x48, 0x78, 0x48, 0x00, 0x00, 0x00,
-+ 0x40, 0x60, 0x90, 0xe8, 0x48, 0x40, 0xf8, 0x40,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x00, 0x78, 0x4b, 0x48, 0x7b, 0x4a, 0x4b,
-+ 0x7a, 0x48, 0x49, 0x7a, 0x4c, 0x00, 0x00, 0x00,
-+ 0x10, 0x90, 0xa0, 0xf8, 0x48, 0xf8, 0x40, 0xfc,
-+ 0xc4, 0xc4, 0x44, 0x58, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4a, 0x4a, 0x7a, 0x4b, 0x4a,
-+ 0x7a, 0x4a, 0x4a, 0x7c, 0x4f, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4b, 0x4a, 0x7a, 0x4b, 0x4a,
-+ 0x78, 0x48, 0x49, 0x79, 0x4a, 0x0c, 0x00, 0x00,
-+ 0x80, 0x38, 0x08, 0xb8, 0x08, 0x08, 0xf8, 0xa8,
-+ 0xa0, 0xa0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x07, 0x78, 0x4b, 0x48, 0x7f, 0x48, 0x4b,
-+ 0x78, 0x4a, 0x4a, 0x7b, 0x4c, 0x08, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8,
-+ 0x48, 0x40, 0x7c, 0x40, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x00, 0x7b, 0x48, 0x49, 0x78, 0x4f, 0x48, 0x7b,
-+ 0x4a, 0x4a, 0x7b, 0x4a, 0x02, 0x02, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0x00, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x4a, 0x4b, 0x7a, 0x4b, 0x4a,
-+ 0x78, 0x49, 0x4f, 0x78, 0x48, 0x00, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x88,
-+ 0xa0, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x2f, 0x49, 0x12, 0x04, 0x1f,
-+ 0x68, 0x0f, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf0, 0xfc, 0xe8, 0x20, 0x90, 0x40, 0xf0,
-+ 0x2c, 0xe0, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x01, 0x3f, 0x24, 0x3f, 0x01, 0x1f, 0x01, 0x7f,
-+ 0x04, 0x3f, 0x01, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x00, 0xf0, 0x00, 0xfc,
-+ 0x40, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x7b, 0x48, 0x48, 0x7f, 0x48, 0x48,
-+ 0x79, 0x4f, 0x49, 0x79, 0x49, 0x01, 0x00, 0x00,
-+ 0x80, 0x88, 0xf8, 0x90, 0xa0, 0xfc, 0x50, 0x88,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4d, 0x48, 0x7b, 0x48, 0x4f,
-+ 0x78, 0x4b, 0x4a, 0x7a, 0x4b, 0x02, 0x00, 0x00,
-+ 0x40, 0xfc, 0x58, 0xe0, 0x40, 0xf8, 0x40, 0xfc,
-+ 0x40, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x79, 0x49, 0x4a, 0x7a, 0x4a, 0x4a, 0x7a,
-+ 0x4a, 0x4a, 0x7a, 0x4b, 0x01, 0x06, 0x00, 0x00,
-+ 0x08, 0x34, 0xc4, 0xfc, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0xfc, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4d, 0x49, 0x79, 0x49, 0x49,
-+ 0x78, 0x4f, 0x48, 0x78, 0x49, 0x06, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x40, 0xfc, 0x00, 0x90, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x7a, 0x49, 0x4b, 0x7a, 0x4d, 0x49, 0x79,
-+ 0x49, 0x48, 0x7b, 0x48, 0x0f, 0x00, 0x00, 0x00,
-+ 0x40, 0x48, 0x50, 0xfc, 0x08, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x77, 0x51, 0x51, 0x70, 0x57, 0x54,
-+ 0x77, 0x55, 0x55, 0x76, 0x54, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0xf0, 0x40, 0xfc, 0x44,
-+ 0x74, 0x54, 0x54, 0xec, 0x44, 0x4c, 0x00, 0x00,
-+ 0x00, 0x07, 0x72, 0x5f, 0x54, 0x74, 0x57, 0x54,
-+ 0x77, 0x54, 0x57, 0x7c, 0x50, 0x00, 0x00, 0x00,
-+ 0x20, 0xa0, 0x20, 0xe0, 0xbc, 0xe8, 0xa8, 0xa8,
-+ 0xa8, 0x90, 0x90, 0xa8, 0xc8, 0x84, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x4b, 0x4f, 0x7b, 0x4a, 0x4b,
-+ 0x7a, 0x4b, 0x4a, 0x7b, 0x49, 0x06, 0x00, 0x00,
-+ 0x40, 0xf8, 0x48, 0xf8, 0xfc, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0xf8, 0x98, 0x04, 0x00, 0x00,
-+ 0x00, 0x03, 0x7a, 0x49, 0x4b, 0x7a, 0x4d, 0x4a,
-+ 0x78, 0x49, 0x4e, 0x78, 0x49, 0x0e, 0x00, 0x00,
-+ 0x18, 0xe4, 0x48, 0x30, 0xfc, 0x48, 0xa8, 0x94,
-+ 0xf0, 0xf8, 0x90, 0x60, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x3e, 0x22, 0x3e, 0x3e, 0x22, 0x3e, 0x08, 0x0f,
-+ 0x18, 0x2f, 0x4f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0xf8, 0x88, 0xf8, 0xf8, 0x88, 0xf8, 0x40, 0xf8,
-+ 0x80, 0xf0, 0xf0, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x49, 0x4b, 0x7c, 0x4b, 0x4a,
-+ 0x7a, 0x4b, 0x49, 0x79, 0x4a, 0x04, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xb8, 0xa8,
-+ 0xa8, 0xb8, 0x10, 0x98, 0x64, 0x44, 0x00, 0x00,
-+ 0x08, 0x7f, 0x3e, 0x3e, 0x22, 0x3e, 0x17, 0x7f,
-+ 0x10, 0x1f, 0x1f, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0x48, 0x30, 0xd8, 0xf4,
-+ 0x10, 0xf0, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x7f, 0x4b, 0x4a, 0x7a, 0x4b, 0x4b,
-+ 0x7a, 0x4a, 0x4a, 0x7c, 0x4c, 0x08, 0x00, 0x00,
-+ 0x40, 0xf0, 0x20, 0xfc, 0xa8, 0x98, 0x70, 0xfc,
-+ 0x70, 0x70, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x01, 0x07, 0x79, 0x4b, 0x4a, 0x7c, 0x4f, 0x48,
-+ 0x7f, 0x49, 0x4e, 0x79, 0x4e, 0x00, 0x00, 0x00,
-+ 0x10, 0xfc, 0x10, 0xfc, 0xe8, 0x00, 0xfc, 0xc8,
-+ 0x68, 0xf0, 0x70, 0xa8, 0x24, 0xc0, 0x00, 0x00,
-+ 0x3e, 0x22, 0x3e, 0x3e, 0x22, 0x3e, 0x0f, 0x1b,
-+ 0x6b, 0x0f, 0x3f, 0x04, 0x03, 0x7c, 0x00, 0x00,
-+ 0xf8, 0x88, 0xf8, 0xf8, 0x88, 0xf8, 0xf8, 0xe0,
-+ 0xe0, 0xf8, 0xe0, 0x40, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x01, 0x3f, 0x07, 0x17, 0x17, 0x17, 0x1f, 0x7f,
-+ 0x1c, 0x5d, 0x5d, 0x5d, 0x7f, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0xc0, 0xc0, 0xc0, 0xc0, 0xf8, 0xfc,
-+ 0x70, 0x70, 0x70, 0x70, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x07, 0x74, 0x57, 0x57, 0x77, 0x57, 0x56,
-+ 0x77, 0x55, 0x57, 0x79, 0x48, 0x17, 0x00, 0x00,
-+ 0x00, 0xfc, 0x04, 0xfc, 0x58, 0x58, 0xf8, 0xa8,
-+ 0xf8, 0xfc, 0xf4, 0xf4, 0x7c, 0x98, 0x00, 0x00,
-+ 0x00, 0x3f, 0x12, 0x0c, 0x04, 0x7f, 0x0d, 0x0e,
-+ 0x14, 0x14, 0x24, 0x44, 0x04, 0x0c, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0xf4, 0x00, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x02, 0x04, 0x3f, 0x08, 0x0f, 0x11,
-+ 0x21, 0x7f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x40, 0x30, 0xc8, 0x00, 0xf8, 0x00,
-+ 0x00, 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x11, 0x10, 0x1f, 0x28, 0x28, 0x49, 0x7e,
-+ 0x09, 0x0c, 0x12, 0x12, 0x20, 0x43, 0x00, 0x00,
-+ 0x18, 0xe0, 0x20, 0xfc, 0x70, 0xa8, 0x24, 0x20,
-+ 0xfc, 0x48, 0xc8, 0x30, 0x68, 0x84, 0x00, 0x00,
-+ 0x00, 0x3f, 0x08, 0x08, 0x08, 0x10, 0x1e, 0x32,
-+ 0x52, 0x12, 0x12, 0x1e, 0x13, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x02, 0x7e, 0x12, 0x12, 0x13, 0x3e, 0x2a, 0x6a,
-+ 0x2a, 0x2a, 0x39, 0x28, 0x20, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0xa8, 0x28, 0x28, 0x28, 0x28,
-+ 0xa8, 0xa8, 0xc8, 0x48, 0x88, 0x18, 0x00, 0x00,
-+ 0x01, 0x7f, 0x11, 0x11, 0x11, 0x3d, 0x25, 0x65,
-+ 0x25, 0x25, 0x3d, 0x25, 0x21, 0x06, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x24, 0xe8, 0x30, 0x20,
-+ 0x20, 0x20, 0x20, 0x64, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x12, 0x13, 0x12, 0x3a, 0x2b, 0x6a,
-+ 0x2a, 0x2a, 0x3a, 0x2c, 0x24, 0x0b, 0x00, 0x00,
-+ 0x20, 0xfc, 0x50, 0xfc, 0x50, 0x70, 0xfc, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0xf8, 0xc8, 0x04, 0x00, 0x00,
-+ 0x00, 0x7e, 0x10, 0x10, 0x10, 0x3c, 0x24, 0x64,
-+ 0x24, 0x24, 0x3c, 0x24, 0x23, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88,
-+ 0xf8, 0x88, 0x88, 0x88, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x12, 0x13, 0x12, 0x3a, 0x2a, 0x6a,
-+ 0x2a, 0x2b, 0x3d, 0x25, 0x29, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x50, 0xfc, 0xf8, 0xa8, 0xf8, 0xa8,
-+ 0xf8, 0xfc, 0x34, 0xfc, 0x04, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7e, 0x13, 0x10, 0x10, 0x3f, 0x24, 0x64,
-+ 0x27, 0x24, 0x3c, 0x24, 0x27, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7e, 0x13, 0x10, 0x10, 0x3c, 0x25, 0x66,
-+ 0x24, 0x27, 0x3c, 0x24, 0x20, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x90, 0x90, 0x98, 0x64, 0x64,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x7c, 0x13, 0x10, 0x10, 0x3c, 0x24, 0x65,
-+ 0x27, 0x25, 0x3d, 0x25, 0x21, 0x01, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x90, 0x90, 0xa0, 0xa4, 0x28,
-+ 0x30, 0x20, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x10, 0x0b, 0x42, 0x23, 0x0a, 0x12, 0x24, 0x2b,
-+ 0x7f, 0x04, 0x1f, 0x68, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0xfc, 0x48, 0xf8, 0x90, 0x60, 0xf0, 0x0c,
-+ 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x7f, 0x12, 0x12, 0x12, 0x3b, 0x2a, 0x6a,
-+ 0x2b, 0x2a, 0x3a, 0x2c, 0x24, 0x09, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xa8, 0xa8, 0xb8, 0xa8, 0xa8,
-+ 0xb8, 0xa8, 0xa8, 0xc8, 0xc8, 0x98, 0x00, 0x00,
-+ 0x00, 0x7e, 0x13, 0x11, 0x10, 0x3c, 0x27, 0x64,
-+ 0x25, 0x25, 0x3d, 0x25, 0x21, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x10, 0x90, 0xa0, 0xfc, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x7e, 0x11, 0x11, 0x10, 0x3f, 0x26, 0x65,
-+ 0x25, 0x24, 0x3d, 0x26, 0x20, 0x00, 0x00, 0x00,
-+ 0x80, 0xf0, 0x10, 0xe0, 0x20, 0xfc, 0x68, 0x68,
-+ 0x50, 0xd0, 0x48, 0x44, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x7f, 0x11, 0x11, 0x11, 0x3d, 0x24, 0x64,
-+ 0x25, 0x27, 0x3d, 0x25, 0x21, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x80, 0xf8,
-+ 0x48, 0x68, 0x98, 0xe8, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x7e, 0x10, 0x10, 0x11, 0x3d, 0x25, 0x65,
-+ 0x25, 0x25, 0x3d, 0x24, 0x21, 0x06, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0x40, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x08, 0xf8, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x7c, 0x13, 0x10, 0x10, 0x3c, 0x24, 0x64,
-+ 0x27, 0x25, 0x3d, 0x25, 0x21, 0x01, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x90, 0xf0, 0x90, 0xf0, 0x90,
-+ 0xfc, 0x50, 0x54, 0x8c, 0xfc, 0x00, 0x00, 0x00,
-+ 0x02, 0x7a, 0x14, 0x12, 0x12, 0x38, 0x2b, 0x6a,
-+ 0x2b, 0x2a, 0x3a, 0x2b, 0x23, 0x02, 0x00, 0x00,
-+ 0x48, 0x48, 0x90, 0x48, 0x48, 0x80, 0xf8, 0x28,
-+ 0xa8, 0x48, 0xa8, 0x18, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x7e, 0x13, 0x10, 0x17, 0x3c, 0x25, 0x65,
-+ 0x25, 0x25, 0x3d, 0x24, 0x27, 0x00, 0x00, 0x00,
-+ 0x40, 0x48, 0xf8, 0x00, 0xfc, 0x00, 0xf0, 0x10,
-+ 0x10, 0xf0, 0x10, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x11, 0x11, 0x11, 0x3f, 0x26, 0x65,
-+ 0x25, 0x25, 0x3d, 0x25, 0x21, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x70, 0x50, 0xfc, 0x08, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x01, 0x7c, 0x13, 0x10, 0x11, 0x3c, 0x27, 0x64,
-+ 0x24, 0x25, 0x3d, 0x26, 0x27, 0x00, 0x00, 0x00,
-+ 0x10, 0xa0, 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0x80,
-+ 0xf8, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x7d, 0x11, 0x12, 0x16, 0x39, 0x29, 0x6a,
-+ 0x2f, 0x28, 0x39, 0x2a, 0x24, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0xbc, 0xa8, 0xa8, 0xfc, 0x48, 0x48,
-+ 0xfc, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x00, 0x7d, 0x11, 0x11, 0x11, 0x3d, 0x25, 0x65,
-+ 0x25, 0x25, 0x3e, 0x22, 0x04, 0x09, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x50, 0x50, 0xf8, 0x50,
-+ 0x50, 0xfc, 0xa8, 0x90, 0xe8, 0x84, 0x00, 0x00,
-+ 0x00, 0x7f, 0x11, 0x11, 0x11, 0x3d, 0x25, 0x65,
-+ 0x25, 0x24, 0x3f, 0x22, 0x22, 0x04, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xf8, 0x20, 0xf8, 0x20, 0x20,
-+ 0xfc, 0x54, 0x2c, 0xac, 0x84, 0x18, 0x00, 0x00,
-+ 0x00, 0x7e, 0x13, 0x11, 0x10, 0x3f, 0x26, 0x64,
-+ 0x27, 0x24, 0x3c, 0x24, 0x21, 0x06, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x10, 0xa0, 0xfc, 0x48, 0x40,
-+ 0xfc, 0x40, 0x78, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x02, 0x07, 0x1c, 0x67, 0x04, 0x7e,
-+ 0x10, 0x1e, 0x32, 0x53, 0x1e, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xfc,
-+ 0x40, 0x78, 0xc8, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x08, 0x7f, 0x08, 0x3e, 0x3f, 0x2a, 0x3e, 0x21,
-+ 0x7f, 0x04, 0x1f, 0x68, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x70, 0x54, 0x8c, 0xf8, 0x50, 0x70, 0x8c,
-+ 0xf8, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x10, 0x11, 0x10, 0x3f, 0x25, 0x65,
-+ 0x25, 0x25, 0x3d, 0x25, 0x21, 0x06, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0xf0, 0x10,
-+ 0xf0, 0xf0, 0x10, 0xf0, 0x90, 0x08, 0x00, 0x00,
-+ 0x00, 0x7f, 0x10, 0x11, 0x11, 0x3d, 0x25, 0x65,
-+ 0x24, 0x27, 0x3c, 0x27, 0x20, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xfc, 0x10, 0xfc, 0x90, 0x70, 0x00, 0x00,
-+ 0x00, 0x7f, 0x10, 0x17, 0x11, 0x3f, 0x29, 0x69,
-+ 0x2e, 0x2f, 0x38, 0x28, 0x21, 0x06, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xfc, 0x10, 0xbc, 0x10, 0xbc,
-+ 0x00, 0xfc, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x01, 0x7e, 0x12, 0x11, 0x11, 0x3f, 0x24, 0x65,
-+ 0x25, 0x25, 0x3c, 0x24, 0x27, 0x00, 0x00, 0x00,
-+ 0xd0, 0x54, 0xa4, 0xa8, 0x10, 0xf8, 0x04, 0xf8,
-+ 0x08, 0xf8, 0x90, 0x60, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x12, 0x13, 0x12, 0x3b, 0x2a, 0x6b,
-+ 0x2a, 0x28, 0x3f, 0x28, 0x21, 0x06, 0x00, 0x00,
-+ 0x40, 0xf8, 0xe8, 0x58, 0xe8, 0xf8, 0xe8, 0x58,
-+ 0x48, 0x40, 0xfc, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x01, 0x7f, 0x10, 0x13, 0x10, 0x3f, 0x28, 0x6f,
-+ 0x2f, 0x29, 0x39, 0x2f, 0x21, 0x03, 0x00, 0x00,
-+ 0x10, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0xa8, 0x24,
-+ 0xfc, 0x28, 0x98, 0x34, 0xcc, 0x04, 0x00, 0x00,
-+ 0x02, 0x7d, 0x13, 0x12, 0x15, 0x39, 0x29, 0x68,
-+ 0x2b, 0x2a, 0x3b, 0x2a, 0x23, 0x02, 0x00, 0x00,
-+ 0x48, 0x50, 0xfc, 0x08, 0xf0, 0x10, 0xf0, 0x00,
-+ 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x7c, 0x17, 0x14, 0x13, 0x3a, 0x2b, 0x6d,
-+ 0x29, 0x2f, 0x3b, 0x2a, 0x24, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x28, 0x90, 0x90, 0x7c, 0x94, 0x58,
-+ 0x50, 0xdc, 0x50, 0xf0, 0x50, 0x8c, 0x00, 0x00,
-+ 0x10, 0x12, 0x7d, 0x1a, 0x36, 0x51, 0x12, 0x7f,
-+ 0x04, 0x1f, 0x62, 0x0f, 0x34, 0x07, 0x00, 0x00,
-+ 0x90, 0x90, 0x7c, 0x90, 0xb8, 0x54, 0x90, 0xfc,
-+ 0x20, 0xf0, 0x0c, 0xf0, 0x10, 0xf0, 0x00, 0x00,
-+ 0x02, 0x7e, 0x13, 0x15, 0x12, 0x3a, 0x2d, 0x6f,
-+ 0x28, 0x2f, 0x38, 0x29, 0x26, 0x00, 0x00, 0x00,
-+ 0x48, 0x48, 0xec, 0xb4, 0xe8, 0xa8, 0xf4, 0x5c,
-+ 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x00, 0x3e, 0x00, 0x00, 0x7f, 0x08, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x3d, 0x00, 0x01, 0x7e, 0x08, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xe8, 0xa8, 0xa8,
-+ 0xa8, 0xe8, 0xa8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x00, 0x00, 0x7f, 0x08, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2b, 0x49, 0x08, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0xa0, 0xa0, 0xfc, 0xa0, 0x90,
-+ 0x90, 0xb4, 0xcc, 0x0c, 0xf4, 0x04, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x1f, 0x21, 0x3f, 0x20, 0x0f,
-+ 0x00, 0x7f, 0x05, 0x19, 0x61, 0x03, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0xf0, 0x08, 0xf8, 0x08, 0xe0,
-+ 0x00, 0xfc, 0x40, 0x30, 0x08, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x00, 0x00, 0x7f, 0x08, 0x2b, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0xa0, 0xa0, 0x3c, 0x20,
-+ 0x20, 0x3c, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3e, 0x00, 0x00, 0x7f, 0x08, 0x2a, 0x2a,
-+ 0x2b, 0x2b, 0x2a, 0x28, 0x48, 0x09, 0x00, 0x00,
-+ 0x20, 0x10, 0x50, 0x48, 0x48, 0xc8, 0xd8, 0xd4,
-+ 0x54, 0x64, 0x60, 0x48, 0xc8, 0x38, 0x00, 0x00,
-+ 0x00, 0x3e, 0x00, 0x00, 0x7f, 0x08, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x29, 0x4a, 0x0c, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0x40, 0xfc, 0x40, 0x48, 0x68,
-+ 0x68, 0xb0, 0x90, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x03, 0x7e, 0x08, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2b, 0x28, 0x49, 0x0a, 0x00, 0x00,
-+ 0x90, 0x90, 0x90, 0xfc, 0x90, 0xf0, 0x90, 0xf0,
-+ 0x90, 0x90, 0xfc, 0x90, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x3e, 0x00, 0x00, 0x7e, 0x09, 0x2b, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2b, 0x48, 0x08, 0x00, 0x00,
-+ 0x40, 0x78, 0x88, 0xf0, 0x10, 0xfc, 0x20, 0xb4,
-+ 0xb8, 0x70, 0xa8, 0x24, 0x20, 0x60, 0x00, 0x00,
-+ 0x01, 0x3d, 0x03, 0x01, 0x7f, 0x11, 0x37, 0x35,
-+ 0x34, 0x37, 0x34, 0x34, 0x51, 0x16, 0x00, 0x00,
-+ 0x00, 0x78, 0xa8, 0x28, 0xa8, 0xa8, 0x48, 0x98,
-+ 0x40, 0xfc, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3e, 0x00, 0x00, 0x7f, 0x08, 0x2a, 0x2a,
-+ 0x2b, 0x2a, 0x2a, 0x2b, 0x48, 0x09, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0x50, 0x94,
-+ 0x4c, 0x70, 0xd0, 0x20, 0x50, 0x8c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x00, 0x7e, 0x08, 0x2a, 0x2a,
-+ 0x2a, 0x2b, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0x00, 0xf8, 0x88, 0xf8,
-+ 0x50, 0xfc, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x01, 0x7f, 0x02, 0x7d, 0x15, 0x15, 0x2d, 0x50,
-+ 0x1f, 0x10, 0x1f, 0x15, 0x25, 0x49, 0x00, 0x00,
-+ 0x00, 0xfc, 0x98, 0x70, 0x50, 0x50, 0xe8, 0x14,
-+ 0xf0, 0x10, 0xf0, 0x50, 0x30, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x01, 0x7e, 0x08, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x2b, 0x48, 0x08, 0x00, 0x00,
-+ 0x00, 0xdc, 0x54, 0xdc, 0x00, 0xf8, 0xa8, 0xf8,
-+ 0xa8, 0xf8, 0x20, 0xfc, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x02, 0x03, 0x7e, 0x13, 0x34, 0x37,
-+ 0x35, 0x35, 0x35, 0x30, 0x57, 0x10, 0x00, 0x00,
-+ 0xa0, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0x00, 0xfc,
-+ 0xf0, 0x10, 0xf0, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x03, 0x02, 0x7f, 0x10, 0x37, 0x35,
-+ 0x34, 0x37, 0x34, 0x37, 0x51, 0x13, 0x00, 0x00,
-+ 0x40, 0xfc, 0xb8, 0xa8, 0xb8, 0xa0, 0xf8, 0xf0,
-+ 0xa0, 0xfc, 0xc8, 0x30, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x1f, 0x11, 0x11, 0x1f, 0x01,
-+ 0x3f, 0x21, 0x21, 0x3f, 0x20, 0x20, 0x00, 0x00,
-+ 0x38, 0xc0, 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x00,
-+ 0xf8, 0x48, 0x68, 0x98, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x11, 0x1f, 0x11, 0x1f, 0x01,
-+ 0x3f, 0x21, 0x21, 0x3f, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0xf0, 0x00,
-+ 0xf8, 0x48, 0x68, 0x98, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x1f, 0x7f, 0x01, 0x1f, 0x01, 0x7f, 0x01,
-+ 0x1f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x70, 0x80, 0xfc, 0x00, 0xf0, 0x10, 0xfc, 0x10,
-+ 0xf0, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x03, 0x05, 0x39, 0x09, 0x09, 0x7f, 0x09, 0x1d,
-+ 0x1b, 0x2b, 0x49, 0x09, 0x09, 0x0b, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x24, 0xe8, 0x30, 0x20,
-+ 0x20, 0x20, 0x20, 0x64, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x02, 0x04, 0x38, 0x08, 0x08, 0x7e, 0x08, 0x1d,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xf8, 0xa8, 0xa8, 0xa8, 0xfc,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x02, 0x04, 0x38, 0x08, 0x08, 0x7f, 0x08, 0x1c,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xf8, 0x88, 0x88, 0x88,
-+ 0xf8, 0x88, 0x80, 0x80, 0xfc, 0x80, 0x00, 0x00,
-+ 0x02, 0x04, 0x38, 0x08, 0x09, 0x7e, 0x08, 0x1c,
-+ 0x1a, 0x2a, 0x48, 0x09, 0x0a, 0x0c, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x48, 0xfc, 0x40, 0x48, 0x68,
-+ 0x68, 0xb0, 0x90, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x02, 0x04, 0x38, 0x09, 0x08, 0x7e, 0x08, 0x1c,
-+ 0x1a, 0x2a, 0x48, 0x09, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0x20,
-+ 0x70, 0x70, 0xa8, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x02, 0x04, 0x38, 0x08, 0x08, 0x7e, 0x08, 0x1c,
-+ 0x1a, 0x2a, 0x49, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x00, 0xf8,
-+ 0x20, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x02, 0x04, 0x38, 0x09, 0x08, 0x7e, 0x08, 0x1c,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0xb0, 0xa8, 0x24, 0x20, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x02, 0x04, 0x38, 0x0b, 0x08, 0x7e, 0x0c, 0x1a,
-+ 0x1a, 0x28, 0x4b, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x90, 0x90, 0x90, 0xfc, 0x90, 0xf0, 0x90, 0xf0,
-+ 0x90, 0x90, 0xfc, 0x90, 0x08, 0x08, 0x00, 0x00,
-+ 0x02, 0x04, 0x39, 0x08, 0x09, 0x7f, 0x09, 0x1d,
-+ 0x1b, 0x2b, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0x78, 0x48, 0x78, 0x48,
-+ 0x78, 0x48, 0x78, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x02, 0x05, 0x39, 0x09, 0x09, 0x7f, 0x09, 0x1d,
-+ 0x1b, 0x2b, 0x49, 0x0a, 0x0a, 0x0c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0xf8, 0x08,
-+ 0xe8, 0xa8, 0xa8, 0xe8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x01, 0x7f, 0x1f, 0x17, 0x14, 0x17, 0x1f, 0x00,
-+ 0x1f, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf0, 0xd0, 0x50, 0xd0, 0xf0, 0x60,
-+ 0x80, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x01, 0x7f, 0x1f, 0x17, 0x14, 0x17, 0x1f, 0x00,
-+ 0x1f, 0x00, 0x7f, 0x0d, 0x31, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf0, 0xd0, 0x50, 0xd0, 0xf0, 0x00,
-+ 0xf0, 0x00, 0xfc, 0x60, 0x18, 0x00, 0x00, 0x00,
-+ 0x02, 0x04, 0x38, 0x08, 0x09, 0x7e, 0x0c, 0x1a,
-+ 0x1a, 0x28, 0x49, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x18, 0xf0, 0xa8, 0xa4, 0x04, 0x20, 0xf8, 0xa8,
-+ 0xf8, 0xa8, 0xfc, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x02, 0x04, 0x39, 0x09, 0x0a, 0x7e, 0x09, 0x1d,
-+ 0x1b, 0x2b, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x08, 0x30, 0xc8, 0x24, 0x24, 0x40, 0xb8, 0x08,
-+ 0x08, 0xb8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x7f, 0x0f, 0x08, 0x0f, 0x3f, 0x27, 0x24,
-+ 0x27, 0x1f, 0x7f, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0xe0, 0x20, 0xe0, 0xf8, 0xc8, 0x48,
-+ 0xf8, 0xc0, 0xfc, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x02, 0x05, 0x39, 0x09, 0x09, 0x7f, 0x08, 0x1d,
-+ 0x1a, 0x2a, 0x4b, 0x08, 0x08, 0x0b, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0xa0, 0x24,
-+ 0x5c, 0xf0, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x02, 0x04, 0x39, 0x09, 0x0a, 0x7e, 0x09, 0x1c,
-+ 0x1a, 0x2b, 0x4a, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0x90, 0xa8, 0x24, 0x50,
-+ 0x88, 0xfc, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x02, 0x05, 0x38, 0x08, 0x08, 0x7e, 0x08, 0x1c,
-+ 0x1b, 0x2a, 0x48, 0x09, 0x0a, 0x08, 0x00, 0x00,
-+ 0x20, 0xfc, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0x28,
-+ 0xf4, 0x40, 0xa8, 0xa4, 0x94, 0x70, 0x00, 0x00,
-+ 0x02, 0x05, 0x39, 0x09, 0x09, 0x7f, 0x09, 0x1d,
-+ 0x1b, 0x2b, 0x49, 0x0b, 0x0a, 0x0c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x20, 0xac, 0xac, 0x20,
-+ 0x60, 0x78, 0xa0, 0xfc, 0x20, 0x20, 0x00, 0x00,
-+ 0x04, 0x08, 0x77, 0x11, 0x11, 0x7e, 0x17, 0x38,
-+ 0x37, 0x56, 0x52, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x50, 0x50, 0xe8, 0xfc, 0x00,
-+ 0xf8, 0xe8, 0xa8, 0xe8, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x09, 0x71, 0x11, 0x17, 0x7c, 0x13, 0x3a,
-+ 0x37, 0x56, 0x53, 0x16, 0x14, 0x1b, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x40, 0xfc, 0x28, 0xfc, 0x20,
-+ 0xe8, 0xd8, 0xb4, 0xdc, 0xac, 0x44, 0x00, 0x00,
-+ 0x04, 0x09, 0x71, 0x13, 0x10, 0x7d, 0x11, 0x3b,
-+ 0x34, 0x55, 0x50, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x08, 0xf0, 0x48, 0xf4, 0x40, 0xf0, 0xf8, 0xfc,
-+ 0x08, 0xf8, 0x40, 0xa8, 0x94, 0x70, 0x00, 0x00,
-+ 0x04, 0x09, 0x76, 0x13, 0x12, 0x7f, 0x13, 0x3f,
-+ 0x37, 0x54, 0x53, 0x17, 0x13, 0x10, 0x00, 0x00,
-+ 0x40, 0xf0, 0x20, 0xf8, 0xa8, 0xb8, 0xa0, 0xbc,
-+ 0xbc, 0xac, 0xb4, 0xbc, 0x84, 0x7c, 0x00, 0x00,
-+ 0x04, 0x0f, 0x73, 0x12, 0x13, 0x7c, 0x13, 0x39,
-+ 0x34, 0x57, 0x50, 0x17, 0x11, 0x13, 0x00, 0x00,
-+ 0x40, 0xfc, 0xb8, 0xa8, 0xb8, 0xa0, 0xf8, 0xf0,
-+ 0xa0, 0xfc, 0xc8, 0x30, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x22, 0x4c, 0x30, 0x1f, 0x00,
-+ 0x1f, 0x10, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x88, 0x88, 0x78, 0xf0, 0x10,
-+ 0xf0, 0x00, 0xf8, 0x08, 0x08, 0xf0, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x22, 0x4c, 0x34, 0x04, 0x3f,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x88, 0x88, 0x78, 0x40, 0xf8,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x22, 0x4c, 0x30, 0x08, 0x0a,
-+ 0x73, 0x14, 0x0c, 0x0a, 0x1f, 0x62, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x88, 0x88, 0x78, 0x40, 0x40,
-+ 0xf8, 0x48, 0x48, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x24, 0x49, 0x32, 0x1f, 0x11,
-+ 0x17, 0x1e, 0x11, 0x16, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x48, 0x48, 0x38, 0xf0, 0x10,
-+ 0xd0, 0x50, 0x90, 0x50, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x24, 0x48, 0x32, 0x02, 0x32,
-+ 0x0a, 0x0e, 0x74, 0x04, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x88, 0x88, 0xf8, 0x88, 0xb0,
-+ 0xc0, 0xb0, 0x88, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x01, 0x3f, 0x22, 0x4c, 0x30, 0x1f, 0x02, 0x7f,
-+ 0x02, 0x1f, 0x07, 0x1c, 0x67, 0x04, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0x88, 0x78, 0xf0, 0x10, 0xfc,
-+ 0x10, 0xf0, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x22, 0x4c, 0x35, 0x05, 0x0f,
-+ 0x11, 0x7f, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x88, 0x88, 0x78, 0x00, 0xf0,
-+ 0x00, 0xfc, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x22, 0x4c, 0x30, 0x0f, 0x09,
-+ 0x09, 0x3f, 0x27, 0x24, 0x27, 0x24, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x88, 0x88, 0x78, 0xe0, 0xe0,
-+ 0x20, 0xf8, 0xc8, 0x48, 0xc8, 0x58, 0x00, 0x00,
-+ 0x01, 0x3f, 0x29, 0x77, 0x3f, 0x1f, 0x12, 0x1e,
-+ 0x3e, 0x22, 0x3e, 0x3e, 0x22, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x28, 0xd8, 0xf8, 0xf0, 0x90, 0xf0,
-+ 0xf8, 0x88, 0xf8, 0xf8, 0x84, 0xfc, 0x00, 0x00,
-+ 0x01, 0x3f, 0x22, 0x4c, 0x32, 0x07, 0x3a, 0x0b,
-+ 0x7f, 0x09, 0x7f, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0x88, 0x78, 0xf0, 0x60, 0x80,
-+ 0xf0, 0x00, 0xfc, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x3f, 0x25, 0x7f, 0x09, 0x7f, 0x0f, 0x0f,
-+ 0x09, 0x0f, 0x7f, 0x06, 0x01, 0x3e, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xf8, 0x20, 0xfc, 0xe0, 0xe0,
-+ 0x20, 0xe0, 0xfc, 0x40, 0xe0, 0x10, 0x00, 0x00,
-+ 0x01, 0x3f, 0x22, 0x4c, 0x38, 0x3e, 0x22, 0x3e,
-+ 0x3f, 0x08, 0x7f, 0x0e, 0x12, 0x67, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0x88, 0x78, 0x40, 0x7c, 0x88,
-+ 0x48, 0x50, 0x30, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x01, 0x3f, 0x24, 0x59, 0x1e, 0x10, 0x1e, 0x1f,
-+ 0x11, 0x1d, 0x1d, 0x11, 0x1d, 0x73, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0x78, 0xf0, 0x10, 0xf0, 0xf0,
-+ 0x10, 0xd0, 0xd4, 0x0c, 0xcc, 0x04, 0x00, 0x00,
-+ 0x01, 0x3f, 0x22, 0x4c, 0x30, 0x3c, 0x27, 0x38,
-+ 0x2b, 0x25, 0x26, 0x39, 0x20, 0x27, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0x78, 0x40, 0xf8, 0x90, 0xe0,
-+ 0x5c, 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0x00, 0x00,
-+ 0x20, 0x17, 0x14, 0x4b, 0x20, 0x27, 0x00, 0x77,
-+ 0x10, 0x13, 0x10, 0x13, 0x2c, 0x43, 0x00, 0x00,
-+ 0x40, 0xfc, 0xac, 0x3c, 0xa0, 0xfc, 0xc8, 0xe8,
-+ 0xf0, 0x70, 0xa8, 0x28, 0xc0, 0xfc, 0x00, 0x00,
-+ 0x01, 0x3f, 0x26, 0x59, 0x7f, 0x0f, 0x3f, 0x2c,
-+ 0x3f, 0x1f, 0x1f, 0x17, 0x1f, 0x78, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0x78, 0xfc, 0xe0, 0xf8, 0xe8,
-+ 0xf8, 0xf0, 0xd0, 0xf0, 0xf0, 0x1c, 0x00, 0x00,
-+ 0x01, 0x3f, 0x26, 0x58, 0x06, 0x7a, 0x2a, 0x1c,
-+ 0x7e, 0x19, 0x1d, 0x2b, 0x49, 0x09, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0x78, 0x20, 0x3c, 0xf8, 0xa8,
-+ 0xd8, 0xfc, 0x54, 0xfc, 0x04, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x02, 0x22, 0x13, 0x12,
-+ 0x14, 0x14, 0x06, 0x18, 0x60, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x02, 0x22, 0x13, 0x12,
-+ 0x14, 0x14, 0x06, 0x18, 0x60, 0x00, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7e, 0x04, 0x24, 0x15, 0x16,
-+ 0x14, 0x18, 0x0e, 0x18, 0x61, 0x02, 0x00, 0x00,
-+ 0x70, 0x10, 0x50, 0x50, 0x88, 0x88, 0xfc, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7e, 0x04, 0x24, 0x15, 0x14,
-+ 0x14, 0x19, 0x0e, 0x18, 0x60, 0x00, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0x40, 0x40, 0x78, 0xc0, 0x40,
-+ 0x7c, 0xc0, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x04, 0x24, 0x14, 0x15,
-+ 0x15, 0x09, 0x0f, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7f, 0x06, 0x24, 0x15, 0x14,
-+ 0x14, 0x18, 0x0e, 0x18, 0x60, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0x00, 0x00, 0xfc, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x02, 0x22, 0x12, 0x12,
-+ 0x14, 0x14, 0x06, 0x18, 0x63, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x08, 0x88, 0x48, 0x48,
-+ 0x50, 0x50, 0x10, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x0b, 0x08, 0x7e, 0x05, 0x25, 0x15, 0x15,
-+ 0x15, 0x09, 0x0f, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x08, 0x08, 0x08,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x05, 0x24, 0x14, 0x14,
-+ 0x15, 0x09, 0x0e, 0x18, 0x60, 0x03, 0x00, 0x00,
-+ 0x20, 0x20, 0x30, 0x48, 0xf4, 0x84, 0xf8, 0xa0,
-+ 0x20, 0xfc, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x7e, 0x04, 0x24, 0x14, 0x14,
-+ 0x14, 0x08, 0x0e, 0x19, 0x62, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0xa8, 0xa8, 0xf8,
-+ 0x70, 0x70, 0xa8, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x7f, 0x05, 0x25, 0x14, 0x14,
-+ 0x15, 0x0b, 0x0f, 0x19, 0x61, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x80, 0xf8,
-+ 0x48, 0x68, 0x98, 0xf8, 0x08, 0x30, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x0a, 0x4a, 0x2a, 0x2a,
-+ 0x2a, 0x32, 0x16, 0x1c, 0x67, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x1e, 0x29, 0x45, 0x01, 0x3f, 0x01,
-+ 0x0d, 0x03, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x20, 0x10, 0x00, 0xe0, 0x20,
-+ 0x20, 0x20, 0xa0, 0x64, 0x24, 0x1c, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x08, 0x0f, 0x12,
-+ 0x22, 0x44, 0x08, 0x11, 0x02, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x00, 0xf8, 0x48,
-+ 0x48, 0x88, 0x88, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x00, 0x0f, 0x09,
-+ 0x09, 0x09, 0x11, 0x11, 0x21, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x18, 0xe0, 0x20,
-+ 0x20, 0x20, 0x10, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x00, 0x1f, 0x11,
-+ 0x11, 0x1f, 0x10, 0x10, 0x10, 0x0f, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x00, 0xf0, 0x10,
-+ 0x10, 0xf0, 0x10, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x08, 0x08, 0x7e,
-+ 0x0a, 0x0a, 0x12, 0x12, 0x22, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x00, 0xf8, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x01, 0x01, 0x01,
-+ 0x01, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x00, 0xfc, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x09, 0x09, 0x1f,
-+ 0x11, 0x2f, 0x41, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x00, 0x00, 0xf8,
-+ 0x00, 0xe0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x02, 0x02, 0x04,
-+ 0x7f, 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x00, 0x60, 0x38,
-+ 0xc4, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x10, 0x09, 0x49,
-+ 0x21, 0x25, 0x09, 0x11, 0x21, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x00, 0xf8, 0x08,
-+ 0x08, 0x08, 0x30, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x01, 0x01, 0x7f,
-+ 0x03, 0x05, 0x19, 0x67, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x00, 0x00, 0xfc,
-+ 0x80, 0x40, 0x30, 0xcc, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x08, 0x0f, 0x11,
-+ 0x21, 0x7f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x00, 0xf8, 0x00,
-+ 0x00, 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x3f, 0x20, 0x2f, 0x20,
-+ 0x27, 0x20, 0x2f, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0xfc, 0x00, 0xf8, 0x80,
-+ 0xf0, 0x80, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x3f, 0x20, 0x2f, 0x20,
-+ 0x27, 0x20, 0x2f, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0xfc, 0x00, 0xf8, 0x80,
-+ 0xf0, 0x90, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x00, 0x3f, 0x04,
-+ 0x04, 0x7f, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x00, 0xf8, 0x40,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x04, 0x0f, 0x10,
-+ 0x6f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x00, 0xf8, 0x08,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0xb0, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x1f, 0x01, 0x7f,
-+ 0x01, 0x1f, 0x01, 0x02, 0x0c, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0xf0, 0x10, 0xfc,
-+ 0x10, 0xf0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x02, 0x04, 0x18,
-+ 0x6f, 0x01, 0x0f, 0x01, 0x3f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x80, 0x40, 0x30,
-+ 0xec, 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x09, 0x0f, 0x11,
-+ 0x7f, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x00, 0xf0, 0x00,
-+ 0xfc, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x7b, 0x08, 0x11,
-+ 0x3d, 0x49, 0x29, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x1c, 0xf0, 0x20, 0x3c,
-+ 0x20, 0x20, 0x20, 0xfc, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x1f, 0x10, 0x10, 0x1f,
-+ 0x02, 0x3f, 0x20, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x01, 0x7f, 0x09,
-+ 0x09, 0x16, 0x22, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x00, 0xfc, 0x20,
-+ 0x30, 0xc8, 0x88, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x29, 0x4f, 0x08, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x20, 0xe0, 0x20, 0xe0, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x09, 0x09, 0x12,
-+ 0x34, 0x50, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x00, 0xfc, 0x40,
-+ 0x7c, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x08, 0x08, 0x14,
-+ 0x35, 0x56, 0x14, 0x14, 0x14, 0x13, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x80, 0x80, 0xfc,
-+ 0x90, 0x90, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x00, 0x1f, 0x10,
-+ 0x1e, 0x12, 0x12, 0x12, 0x2c, 0x43, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x90, 0xfc, 0x88,
-+ 0x48, 0x50, 0x34, 0x34, 0xcc, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x3f, 0x09, 0x09,
-+ 0x0d, 0x13, 0x23, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0xf8, 0x20, 0x20,
-+ 0x30, 0x48, 0x88, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x09, 0x09, 0x7f,
-+ 0x09, 0x0d, 0x19, 0x69, 0x09, 0x19, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x10, 0x10, 0xfc,
-+ 0x10, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x3f, 0x20, 0x2f, 0x21,
-+ 0x3f, 0x27, 0x39, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0xf8, 0x28, 0xc8, 0x08,
-+ 0xf8, 0xc8, 0x38, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x1f, 0x10, 0x1f, 0x10,
-+ 0x1f, 0x10, 0x1f, 0x10, 0x1e, 0x60, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x88, 0x90, 0xe4, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x10, 0x13, 0x7e, 0x12,
-+ 0x12, 0x1a, 0x72, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0x00, 0xfc, 0x20, 0xf8,
-+ 0xa8, 0xa8, 0xb8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x01, 0x3f, 0x22, 0x4c,
-+ 0x30, 0x0f, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0x00, 0xfc, 0x88, 0x88,
-+ 0x78, 0xe0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x04, 0x06, 0x09,
-+ 0x1f, 0x60, 0x1f, 0x11, 0x1f, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x08, 0x48, 0x48,
-+ 0xc8, 0x48, 0x48, 0x48, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x3f, 0x01, 0x00, 0x1f,
-+ 0x02, 0x7f, 0x01, 0x00, 0x03, 0x3c, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x18, 0xfc, 0x10, 0xe0, 0xb4,
-+ 0x4c, 0xf8, 0x20, 0xc4, 0xb4, 0x0c, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x5f, 0x00, 0x7f, 0x1f, 0x3f,
-+ 0x21, 0x5f, 0x11, 0x11, 0x11, 0x01, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0xf0, 0x10, 0xfc, 0xf0, 0xfc,
-+ 0x08, 0xf0, 0x10, 0x10, 0x60, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x3f, 0x11, 0x3f, 0x41,
-+ 0x7f, 0x01, 0x1f, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x18, 0xf0, 0x08, 0xf4, 0x10,
-+ 0xfc, 0x10, 0xf0, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x03, 0x0c, 0x3f, 0x01,
-+ 0x7f, 0x01, 0x1f, 0x01, 0x01, 0x03, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0xe0, 0x80, 0xf0, 0x10,
-+ 0xfc, 0x10, 0xf0, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x3d, 0x25, 0x25, 0x3d,
-+ 0x25, 0x3d, 0x25, 0x25, 0x25, 0x4d, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0xf8, 0x08, 0x30, 0xf8,
-+ 0x48, 0x48, 0x30, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x3f, 0x20, 0x2f, 0x24,
-+ 0x26, 0x29, 0x22, 0x2c, 0x3f, 0x20, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0xfc, 0x80, 0xf8, 0x90,
-+ 0xb0, 0x48, 0x20, 0x18, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x29, 0x47, 0x0f, 0x08, 0x0f, 0x0f,
-+ 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0xe0, 0x20, 0xe0, 0xe0,
-+ 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x09, 0x08, 0x17, 0x11,
-+ 0x31, 0x52, 0x17, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0xf0, 0x10, 0xfc, 0x00,
-+ 0xf8, 0x40, 0xfc, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x12, 0x12, 0x7f,
-+ 0x12, 0x1f, 0x12, 0x12, 0x1e, 0x13, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0x40, 0x40, 0xfc,
-+ 0xa4, 0x28, 0x70, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x00, 0x1f, 0x10, 0x1f,
-+ 0x10, 0x17, 0x14, 0x17, 0x24, 0x41, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0x50, 0xfc, 0x48, 0xc8,
-+ 0x48, 0xb0, 0xb4, 0xb4, 0x4c, 0x84, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x47, 0x04, 0x0f, 0x7f, 0x03,
-+ 0x7d, 0x07, 0x39, 0x06, 0x38, 0x03, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0xe0, 0x40, 0xc0, 0xfc, 0x88,
-+ 0xd0, 0xe0, 0xa0, 0x90, 0x8c, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x3f, 0x1f, 0x04, 0x7f,
-+ 0x0f, 0x0f, 0x09, 0x7f, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0x48, 0xf8, 0xf0, 0x40, 0xfc,
-+ 0xe0, 0xe0, 0x20, 0xfc, 0x20, 0x60, 0x00, 0x00,
-+ 0x10, 0x10, 0x1f, 0x28, 0x45, 0x09, 0x3e, 0x22,
-+ 0x3e, 0x20, 0x3e, 0x22, 0x3e, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xa0, 0x10, 0xfc, 0x20, 0xf8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xb8, 0x20, 0x00, 0x00,
-+ 0x10, 0x1f, 0x29, 0x45, 0x7f, 0x0f, 0x08, 0x7f,
-+ 0x08, 0x0f, 0x06, 0x7c, 0x07, 0x38, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0xfc, 0xe0, 0x20, 0xfc,
-+ 0x20, 0xe8, 0x90, 0x60, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x1f, 0x29, 0x45, 0x7f, 0x3f, 0x08, 0x7f,
-+ 0x08, 0x3f, 0x06, 0x7c, 0x07, 0x38, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0xfc, 0xf8, 0x20, 0xfc,
-+ 0x20, 0xf8, 0x90, 0x60, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x1f, 0x29, 0x47, 0x3f, 0x26, 0x21, 0x2e,
-+ 0x3f, 0x10, 0x1f, 0x10, 0x1e, 0x70, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0xf8, 0x48, 0xc8, 0x28,
-+ 0xf8, 0x88, 0x90, 0xe4, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x7f, 0x04, 0x3f, 0x24,
-+ 0x3f, 0x01, 0x7f, 0x07, 0x79, 0x01, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0xfc, 0x40, 0xf8, 0x48,
-+ 0xf8, 0x00, 0xfc, 0xc0, 0x3c, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x49, 0x7e, 0x14, 0x7f, 0x3e,
-+ 0x22, 0x3e, 0x22, 0x3e, 0x22, 0x26, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0x40, 0x7c, 0x78, 0x08, 0x78,
-+ 0x40, 0x78, 0x78, 0x78, 0x44, 0x3c, 0x00, 0x00,
-+ 0x10, 0x1f, 0x29, 0x45, 0x3f, 0x1f, 0x7f, 0x0f,
-+ 0x08, 0x0f, 0x0f, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0xf8, 0xf0, 0xfc, 0xe0,
-+ 0x20, 0xe0, 0xe0, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x08, 0x08, 0x7f, 0x08,
-+ 0x0f, 0x13, 0x12, 0x22, 0x44, 0x1f, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0x80, 0xfc, 0x80, 0xf8,
-+ 0x20, 0xfc, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x3f, 0x24, 0x3f, 0x24,
-+ 0x3f, 0x24, 0x2e, 0x2a, 0x2e, 0x41, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0x90, 0x90, 0xa8, 0xc8,
-+ 0x90, 0xa4, 0x84, 0x88, 0x90, 0xa0, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x5f, 0x11, 0x1f, 0x11, 0x1f,
-+ 0x7f, 0x09, 0x3f, 0x01, 0x3f, 0x01, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0xfc, 0x20, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x10, 0x0b, 0x40, 0x27,
-+ 0x03, 0x71, 0x13, 0x10, 0x2c, 0x43, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x90, 0xf0, 0xa0, 0xe0, 0x5c,
-+ 0xf8, 0xf0, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x13, 0x48, 0x22, 0x15,
-+ 0x23, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0xf0, 0x98, 0x94, 0x14,
-+ 0x60, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x25, 0x4f, 0x09, 0x7f, 0x0f, 0x0f,
-+ 0x09, 0x0f, 0x7f, 0x0e, 0x01, 0x3e, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0xe0, 0x20, 0xfc, 0xe0, 0xe0,
-+ 0x20, 0xe0, 0xfc, 0x40, 0xe0, 0x10, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x7f, 0x01, 0x09, 0x09, 0x7f,
-+ 0x07, 0x04, 0x0f, 0x2a, 0x25, 0x40, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0xf8, 0x00, 0xf0, 0x00, 0xfc,
-+ 0xf0, 0x00, 0xf8, 0x48, 0x28, 0x30, 0x00, 0x00,
-+ 0x10, 0x1f, 0x29, 0x4f, 0x09, 0x0f, 0x7f, 0x08,
-+ 0x0f, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0xe0, 0x20, 0xe0, 0xfc, 0x20,
-+ 0xe0, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x7f, 0x04, 0x07, 0x7f, 0x1f,
-+ 0x11, 0x1f, 0x11, 0x1f, 0x06, 0x38, 0x00, 0x00,
-+ 0x40, 0x7c, 0xd0, 0xf8, 0x40, 0xc0, 0xfc, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x60, 0x18, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x7e, 0x14, 0x7f, 0x0e, 0x14,
-+ 0x7f, 0x10, 0x1f, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0xf8, 0x50, 0xfc, 0x30, 0xd4,
-+ 0xfc, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x7f, 0x1f, 0x12, 0x1f, 0x0f,
-+ 0x08, 0x0f, 0x0f, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0xfc, 0xf0, 0x90, 0xf0, 0xe0,
-+ 0x20, 0xe0, 0xe0, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x25, 0x43, 0x0c, 0x7f, 0x12, 0x1d,
-+ 0x17, 0x11, 0x11, 0x13, 0x22, 0x43, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0xe0, 0x80, 0xfc, 0x24, 0xfc,
-+ 0xf8, 0xe0, 0xe0, 0xf0, 0x10, 0xf0, 0x00, 0x00,
-+ 0x10, 0x1f, 0x25, 0x5f, 0x01, 0x7f, 0x1f, 0x15,
-+ 0x1d, 0x11, 0x1f, 0x1d, 0x25, 0x45, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0xf0, 0x10, 0xfc, 0xf0, 0x50,
-+ 0x70, 0x10, 0xf0, 0x70, 0x50, 0x50, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x02, 0x0c, 0x77, 0x00,
-+ 0x1e, 0x12, 0x1e, 0x0c, 0x12, 0x61, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x10, 0x80, 0x60, 0xdc, 0x00,
-+ 0xf0, 0x90, 0xf0, 0x60, 0x90, 0x08, 0x00, 0x00,
-+ 0x10, 0x1f, 0x25, 0x7f, 0x1f, 0x7f, 0x1f, 0x01,
-+ 0x1f, 0x7f, 0x1e, 0x13, 0x1e, 0x10, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0xfc, 0xf0, 0xfc, 0xe8, 0x00,
-+ 0xe0, 0xfc, 0x10, 0xfc, 0x90, 0x30, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x7f, 0x24, 0x3e, 0x3f, 0x24,
-+ 0x3f, 0x1f, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0x40, 0x7c, 0x80, 0x00, 0x78,
-+ 0x00, 0xf0, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x5f, 0x15, 0x7f, 0x1f, 0x1f,
-+ 0x15, 0x1f, 0x7f, 0x1a, 0x06, 0x39, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0x20, 0x20, 0xfc, 0x48, 0xc8,
-+ 0x28, 0x30, 0x90, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x4d, 0x09, 0x7e, 0x13, 0x1c,
-+ 0x14, 0x14, 0x14, 0x27, 0x24, 0x5b, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x90, 0xfc, 0x90, 0xfc, 0x90,
-+ 0xf0, 0xf0, 0x90, 0xfc, 0x90, 0x08, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x51, 0x13, 0x7e, 0x12, 0x17,
-+ 0x13, 0x1e, 0x73, 0x12, 0x13, 0x32, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0x40, 0xbc, 0x94, 0xe4, 0x58,
-+ 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x1f, 0x28, 0x45, 0x3e, 0x27, 0x24, 0x3f,
-+ 0x25, 0x3f, 0x24, 0x27, 0x24, 0x4c, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0x50, 0x48, 0xfc, 0xa0, 0xfc,
-+ 0x50, 0x58, 0xe4, 0x50, 0x4c, 0xc0, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x41, 0x3f, 0x24, 0x27, 0x3d,
-+ 0x27, 0x3c, 0x27, 0x25, 0x25, 0x4e, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0x50, 0xf8, 0xa4, 0xfc, 0x50,
-+ 0xac, 0xd0, 0xf8, 0x54, 0x48, 0x48, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x49, 0x7f, 0x08, 0x3e, 0x2a,
-+ 0x2a, 0x3e, 0x1c, 0x2a, 0x48, 0x09, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0xf8, 0x48, 0x98, 0xf8, 0x88,
-+ 0xf8, 0xf8, 0x88, 0xf8, 0x48, 0x84, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x52, 0x12, 0x2d, 0x7f, 0x0a,
-+ 0x3b, 0x3b, 0x0a, 0x3b, 0x0f, 0x78, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0x40, 0x50, 0x48, 0xfc, 0x28,
-+ 0xa8, 0xb0, 0x10, 0xb4, 0xcc, 0x84, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x44, 0x3f, 0x04, 0x7f, 0x0a,
-+ 0x3b, 0x3b, 0x0a, 0x3b, 0x0f, 0x70, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0x40, 0xd0, 0x48, 0xfc, 0x28,
-+ 0xa8, 0xb0, 0x14, 0xb4, 0xcc, 0x84, 0x00, 0x00,
-+ 0x10, 0x1f, 0x29, 0x46, 0x0c, 0x77, 0x3b, 0x2a,
-+ 0x3b, 0x3f, 0x24, 0x3f, 0x24, 0x24, 0x00, 0x00,
-+ 0x40, 0x7c, 0xa0, 0x90, 0x60, 0xdc, 0xb8, 0xa8,
-+ 0xb8, 0xf8, 0x48, 0xf8, 0x48, 0x58, 0x00, 0x00,
-+ 0x10, 0x1f, 0x24, 0x49, 0x7f, 0x26, 0x3a, 0x37,
-+ 0x3e, 0x7f, 0x4d, 0x7f, 0x41, 0x43, 0x00, 0x00,
-+ 0x40, 0x7c, 0x90, 0x48, 0x50, 0x7c, 0xd0, 0x78,
-+ 0x50, 0x78, 0x50, 0x50, 0x7c, 0x40, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2a, 0x2c, 0x08, 0x7f, 0x08, 0x1c,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x11, 0x55, 0x35, 0x39, 0x11, 0x7d, 0x11, 0x39,
-+ 0x35, 0x55, 0x51, 0x11, 0x11, 0x16, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x24, 0xe8, 0x30, 0x20,
-+ 0x20, 0x20, 0x20, 0x64, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x08, 0x4b, 0x2a, 0x2c, 0x08, 0x7e, 0x08, 0x1c,
-+ 0x1a, 0x2a, 0x49, 0x09, 0x0a, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8,
-+ 0x88, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x02, 0x1f, 0x15, 0x13, 0x1f, 0x13, 0x1d, 0x1f,
-+ 0x00, 0x7f, 0x08, 0x0f, 0x10, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x50, 0x90, 0xf0, 0x90, 0x50, 0xf0,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xe0, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2a, 0x2c, 0x09, 0x7f, 0x08, 0x1c,
-+ 0x1b, 0x2b, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xf8, 0x04, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x7c, 0x01, 0x02, 0x0c, 0x71, 0x13, 0x09,
-+ 0x09, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x48, 0xc0, 0x30, 0x2c, 0x20,
-+ 0x40, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x10, 0x57, 0x34, 0x38, 0x10, 0x7f, 0x12, 0x3a,
-+ 0x36, 0x56, 0x52, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x80, 0xf8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x10, 0x57, 0x36, 0x3a, 0x13, 0x7e, 0x12, 0x3a,
-+ 0x36, 0x56, 0x52, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0xe8, 0xa8,
-+ 0xa8, 0xe8, 0xa8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x4b, 0x2a, 0x2c, 0x08, 0x7f, 0x08, 0x1c,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x40, 0xf8, 0x88, 0x88,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x4b, 0x2a, 0x2d, 0x09, 0x7f, 0x09, 0x1d,
-+ 0x1b, 0x2b, 0x48, 0x09, 0x0a, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x48, 0x80, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x08, 0x0e, 0x08, 0x1f, 0x72, 0x0c, 0x73, 0x11,
-+ 0x09, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x50, 0x20, 0xd0, 0x0c, 0x10,
-+ 0x20, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x10, 0x0b, 0x40, 0x2a, 0x12, 0x25, 0x22, 0x11,
-+ 0x09, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x98, 0x94, 0x14, 0x60, 0x10,
-+ 0x20, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2a, 0x2c, 0x08, 0x7f, 0x08, 0x1c,
-+ 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x0b, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0xf8,
-+ 0xa4, 0xa8, 0x90, 0x90, 0xe8, 0x04, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2b, 0x2c, 0x08, 0x7e, 0x09, 0x1e,
-+ 0x1a, 0x2b, 0x48, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x90, 0x90, 0xd8, 0x24, 0x24,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2a, 0x2c, 0x09, 0x7e, 0x08, 0x1d,
-+ 0x1a, 0x2a, 0x48, 0x09, 0x0a, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0xf8, 0x00, 0x00, 0xfc,
-+ 0x20, 0xb0, 0xa8, 0x24, 0x24, 0x60, 0x00, 0x00,
-+ 0x10, 0x54, 0x37, 0x38, 0x10, 0x7c, 0x11, 0x39,
-+ 0x37, 0x55, 0x51, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x90, 0xa0, 0xa0, 0x24, 0x28,
-+ 0x30, 0x60, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x10, 0x55, 0x34, 0x38, 0x13, 0x7c, 0x13, 0x38,
-+ 0x34, 0x57, 0x50, 0x11, 0x16, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x50, 0x20, 0xfc, 0xe8, 0x30, 0x60,
-+ 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2b, 0x2c, 0x08, 0x7e, 0x08, 0x1c,
-+ 0x1b, 0x2b, 0x49, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x90, 0xf0, 0x90, 0xf0, 0x90,
-+ 0xfc, 0x50, 0x54, 0x8c, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x4a, 0x2b, 0x2d, 0x0b, 0x7e, 0x09, 0x1c,
-+ 0x1b, 0x2a, 0x48, 0x0b, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0xfc, 0x40, 0xe4, 0x68,
-+ 0xb0, 0x70, 0xa8, 0x24, 0x20, 0xc0, 0x00, 0x00,
-+ 0x10, 0x57, 0x34, 0x38, 0x13, 0x7e, 0x12, 0x3a,
-+ 0x36, 0x56, 0x52, 0x14, 0x14, 0x18, 0x00, 0x00,
-+ 0x90, 0xfc, 0x90, 0x00, 0xfc, 0x00, 0xf8, 0xa8,
-+ 0xf8, 0xa8, 0xf8, 0xa8, 0xa8, 0x98, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x1f, 0x16, 0x16, 0x1a, 0x14,
-+ 0x12, 0x1f, 0x11, 0x26, 0x38, 0x40, 0x00, 0x00,
-+ 0x80, 0xfc, 0x10, 0xfc, 0xb8, 0xbc, 0x54, 0x90,
-+ 0xa0, 0xfc, 0xc0, 0xb0, 0x8c, 0x80, 0x00, 0x00,
-+ 0x10, 0x54, 0x37, 0x38, 0x11, 0x7f, 0x11, 0x39,
-+ 0x35, 0x54, 0x53, 0x10, 0x11, 0x16, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x90, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x40, 0xfc, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x3d, 0x0b, 0x3f, 0x3b, 0x0d, 0x31, 0x7f, 0x0f,
-+ 0x08, 0x0f, 0x3f, 0x24, 0x3f, 0x21, 0x00, 0x00,
-+ 0x78, 0x48, 0xf8, 0xb8, 0x48, 0x30, 0xfc, 0xe0,
-+ 0x20, 0xe0, 0xf8, 0x58, 0xf8, 0x18, 0x00, 0x00,
-+ 0x10, 0x57, 0x34, 0x3b, 0x13, 0x7d, 0x10, 0x3b,
-+ 0x34, 0x57, 0x52, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xfc, 0x58, 0xf8, 0x40, 0xfc,
-+ 0x80, 0xf8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x10, 0x57, 0x36, 0x3b, 0x12, 0x7e, 0x12, 0x3a,
-+ 0x36, 0x57, 0x53, 0x15, 0x15, 0x19, 0x00, 0x00,
-+ 0x00, 0xfc, 0x50, 0xfc, 0xf8, 0xa8, 0xf8, 0xa8,
-+ 0xf8, 0xfc, 0x34, 0xfc, 0x04, 0x0c, 0x00, 0x00,
-+ 0x00, 0x39, 0x08, 0x09, 0x14, 0x23, 0x48, 0x2a,
-+ 0x1d, 0x7e, 0x1c, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0xd8, 0x68, 0xd8, 0x68, 0x50, 0xfc,
-+ 0x90, 0xf8, 0xf8, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x08, 0x2b, 0x2a, 0x3f, 0x4a, 0x7f, 0x4a, 0x2a,
-+ 0x1d, 0x7e, 0x1c, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0xd8, 0x68, 0xd8, 0x68, 0x50, 0xfc,
-+ 0x90, 0xf8, 0xf8, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0c, 0x12, 0x7d,
-+ 0x08, 0x2a, 0x29, 0x29, 0x48, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0c, 0x13, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x15, 0x0c, 0x12, 0x7d,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0xfc, 0x10, 0x90, 0x50,
-+ 0x50, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0d, 0x12, 0x7d,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x4b, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfc, 0x20, 0x20,
-+ 0x20, 0x50, 0x48, 0x98, 0xe4, 0x04, 0x00, 0x00,
-+ 0x11, 0x11, 0x15, 0x65, 0x19, 0x19, 0x25, 0x7d,
-+ 0x11, 0x39, 0x35, 0x35, 0x51, 0x16, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x24, 0xe8, 0x30, 0x20,
-+ 0x20, 0x20, 0x20, 0x64, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x04, 0x03, 0x0d, 0x71, 0x02,
-+ 0x1e, 0x03, 0x7f, 0x05, 0x09, 0x31, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x40, 0x80, 0x60, 0x1c, 0x40,
-+ 0xa0, 0x18, 0xe4, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x16, 0x66, 0x1a, 0x1a, 0x26, 0x7e,
-+ 0x12, 0x1a, 0x36, 0x36, 0x52, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xe8, 0xa8, 0xa8, 0xa8,
-+ 0xe8, 0xa8, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x73, 0x15, 0x0d, 0x13, 0x7f,
-+ 0x0d, 0x2b, 0x2b, 0x29, 0x4b, 0x0c, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x00, 0x20, 0x20, 0x20,
-+ 0x20, 0x30, 0x48, 0x58, 0xe4, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x1c, 0x1a, 0x29, 0x49, 0x02,
-+ 0x1e, 0x03, 0x7f, 0x05, 0x09, 0x31, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x40,
-+ 0xa0, 0x18, 0xe4, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x15, 0x0c, 0x12, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xfc, 0xa8, 0xa8, 0xa8,
-+ 0xb8, 0xa8, 0x80, 0x80, 0xfc, 0x80, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0c, 0x13, 0x7e,
-+ 0x09, 0x2d, 0x2b, 0x2b, 0x49, 0x09, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x90, 0x88, 0xf4, 0x04,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x0d, 0x0c, 0x13, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x00, 0x00, 0xfc, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x15, 0x0c, 0x12, 0x7e,
-+ 0x09, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xa8, 0xa4, 0x24, 0xf8, 0x20, 0x20,
-+ 0xfc, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x0d, 0x0c, 0x12, 0x7f,
-+ 0x08, 0x2c, 0x2a, 0x2b, 0x48, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0x50, 0x30, 0xdc, 0x10,
-+ 0xf8, 0x90, 0x90, 0xfc, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x72, 0x14, 0x0c, 0x13, 0x7e,
-+ 0x0c, 0x2a, 0x2a, 0x28, 0x49, 0x0a, 0x00, 0x00,
-+ 0x20, 0x20, 0x24, 0xa4, 0xa8, 0x20, 0xfc, 0x50,
-+ 0x50, 0x50, 0x90, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x15, 0x65, 0x1a, 0x18, 0x24, 0x7d,
-+ 0x13, 0x19, 0x35, 0x35, 0x51, 0x11, 0x00, 0x00,
-+ 0x80, 0xf8, 0x00, 0x00, 0x80, 0xfc, 0x90, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x73, 0x14, 0x0c, 0x12, 0x7f,
-+ 0x09, 0x2c, 0x2a, 0x2a, 0x49, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x28, 0xc8, 0x50, 0x30, 0x48, 0xfc,
-+ 0x24, 0xb0, 0xa8, 0xa4, 0x24, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x14, 0x64, 0x1b, 0x18, 0x24, 0x7c,
-+ 0x13, 0x38, 0x35, 0x35, 0x52, 0x10, 0x00, 0x00,
-+ 0x20, 0x28, 0x24, 0x24, 0xfc, 0xa0, 0xa8, 0xe8,
-+ 0xa8, 0x90, 0x14, 0x2c, 0x4c, 0x84, 0x00, 0x00,
-+ 0x08, 0x7e, 0x12, 0x12, 0x3c, 0x04, 0x1b, 0x62,
-+ 0x1c, 0x03, 0x7f, 0x05, 0x09, 0x31, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x40,
-+ 0xa0, 0x18, 0xe4, 0x40, 0x30, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x73, 0x15, 0x0d, 0x13, 0x7f,
-+ 0x0c, 0x2a, 0x2a, 0x28, 0x4b, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x48,
-+ 0x48, 0x30, 0x24, 0xd4, 0x0c, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x73, 0x14, 0x0c, 0x12, 0x7f,
-+ 0x0c, 0x2a, 0x2a, 0x28, 0x49, 0x0a, 0x00, 0x00,
-+ 0x88, 0x48, 0x50, 0xfc, 0x50, 0x50, 0x50, 0xfc,
-+ 0x50, 0x50, 0x90, 0x90, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x09, 0x0a, 0x72, 0x15, 0x0c, 0x12, 0x7e,
-+ 0x0d, 0x2a, 0x2a, 0x28, 0x4b, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa8, 0xa8, 0x50, 0xa8, 0xa8, 0x00,
-+ 0xf8, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x73, 0x14, 0x0c, 0x13, 0x7e,
-+ 0x0c, 0x2a, 0x2a, 0x28, 0x49, 0x0a, 0x00, 0x00,
-+ 0x08, 0xf0, 0x20, 0xfc, 0x70, 0xa8, 0x24, 0xf0,
-+ 0x50, 0x50, 0x9c, 0x84, 0x04, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x16, 0x14, 0x37, 0x54, 0x15,
-+ 0x14, 0x17, 0x15, 0x15, 0x12, 0x10, 0x00, 0x00,
-+ 0x80, 0xfc, 0x90, 0x60, 0xf0, 0x4c, 0x50, 0xb0,
-+ 0x48, 0xfc, 0x50, 0x48, 0x48, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x72, 0x14, 0x0d, 0x12, 0x7f,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x09, 0x00, 0x00,
-+ 0x08, 0x10, 0xe8, 0xa4, 0x94, 0x20, 0x20, 0xfc,
-+ 0x48, 0x48, 0xf0, 0x10, 0x68, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0c, 0x12, 0x7e,
-+ 0x09, 0x2d, 0x2b, 0x2b, 0x49, 0x09, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x20, 0x40,
-+ 0xfc, 0x04, 0x04, 0x04, 0xfc, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x14, 0x64, 0x29, 0x18, 0x25, 0x7e,
-+ 0x18, 0x35, 0x35, 0x32, 0x54, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xc8, 0xa8, 0x30, 0x40,
-+ 0xa0, 0xa8, 0x84, 0x84, 0x90, 0x70, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x72, 0x14, 0x0c, 0x13, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x60, 0x50, 0x88, 0xfc, 0x08,
-+ 0xe8, 0xa8, 0xe8, 0xa8, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x7e, 0x00, 0x3f, 0x22, 0x3e, 0x23, 0x22,
-+ 0x4e, 0x01, 0x7f, 0x0d, 0x31, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x90, 0x50, 0x60, 0x90, 0x4c,
-+ 0xc0, 0x30, 0xc8, 0x60, 0x18, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x73, 0x14, 0x0d, 0x12, 0x7e,
-+ 0x09, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x20, 0xa8, 0xa4, 0xfc, 0x20, 0xfc, 0x50, 0x88,
-+ 0xf4, 0x90, 0x90, 0xb4, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x0c, 0x0d, 0x12, 0x7e,
-+ 0x09, 0x2c, 0x2a, 0x2a, 0x49, 0x08, 0x00, 0x00,
-+ 0x08, 0x10, 0xe8, 0xa4, 0x94, 0x10, 0x20, 0x20,
-+ 0xfc, 0x70, 0x70, 0xa8, 0x24, 0x20, 0x00, 0x00,
-+ 0x12, 0x12, 0x14, 0x66, 0x1a, 0x18, 0x27, 0x7e,
-+ 0x12, 0x3b, 0x36, 0x36, 0x53, 0x12, 0x00, 0x00,
-+ 0x48, 0x48, 0x90, 0x48, 0x48, 0x00, 0xf8, 0x48,
-+ 0x48, 0xf8, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0c, 0x12, 0x7e,
-+ 0x08, 0x2c, 0x2b, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x3c, 0x20, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x73, 0x14, 0x0c, 0x12, 0x7e,
-+ 0x08, 0x2d, 0x2a, 0x2a, 0x48, 0x09, 0x00, 0x00,
-+ 0x50, 0x48, 0x7c, 0xe8, 0x28, 0x34, 0xcc, 0x50,
-+ 0x5c, 0xe8, 0x28, 0x14, 0x6c, 0x84, 0x00, 0x00,
-+ 0x10, 0x13, 0x16, 0x66, 0x2b, 0x1a, 0x26, 0x7f,
-+ 0x18, 0x34, 0x36, 0x32, 0x54, 0x10, 0x00, 0x00,
-+ 0x80, 0xf8, 0x48, 0xf8, 0xa8, 0x68, 0x98, 0xf8,
-+ 0x40, 0xa8, 0xa4, 0x84, 0x90, 0x70, 0x00, 0x00,
-+ 0x10, 0x13, 0x16, 0x66, 0x1b, 0x1a, 0x27, 0x7e,
-+ 0x1a, 0x36, 0x36, 0x32, 0x54, 0x18, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xe8, 0xa8, 0xe8, 0xa8, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x14, 0x65, 0x1b, 0x19, 0x26, 0x7f,
-+ 0x10, 0x3a, 0x36, 0x37, 0x52, 0x10, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf8, 0x08, 0xe8, 0x88, 0xf8,
-+ 0x88, 0xa8, 0xa8, 0xe8, 0x28, 0x30, 0x00, 0x00,
-+ 0x08, 0x11, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x09,
-+ 0x7e, 0x4a, 0x4a, 0x4a, 0x4f, 0x08, 0x00, 0x00,
-+ 0x0c, 0xf0, 0x20, 0xc8, 0x50, 0x30, 0x48, 0xfc,
-+ 0x24, 0xb0, 0xa8, 0xa4, 0x24, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x14, 0x64, 0x19, 0x1b, 0x24, 0x7f,
-+ 0x12, 0x3b, 0x36, 0x36, 0x52, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xf8, 0x04, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x10, 0x13, 0x14, 0x65, 0x19, 0x19, 0x25, 0x7d,
-+ 0x19, 0x35, 0x35, 0x32, 0x53, 0x16, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0x20, 0x20,
-+ 0xfc, 0x20, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x73, 0x16, 0x0c, 0x12, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0xf0, 0x90, 0x90, 0xf0,
-+ 0x80, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x10, 0x10, 0x14, 0x67, 0x2a, 0x1b, 0x26, 0x7f,
-+ 0x13, 0x3b, 0x37, 0x33, 0x54, 0x18, 0x00, 0x00,
-+ 0x20, 0x28, 0x24, 0xfc, 0x20, 0xe8, 0x28, 0xe8,
-+ 0x50, 0x54, 0xdc, 0x6c, 0x44, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0f, 0x12, 0x7e,
-+ 0x0c, 0x2a, 0x2a, 0x28, 0x4b, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x00, 0xfc, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x72, 0x14, 0x0c, 0x12, 0x7e,
-+ 0x09, 0x2c, 0x2a, 0x2a, 0x49, 0x08, 0x00, 0x00,
-+ 0xa8, 0xa8, 0xfc, 0xa8, 0xb8, 0x80, 0xfc, 0x20,
-+ 0xfc, 0x70, 0x70, 0xa8, 0x24, 0x20, 0x00, 0x00,
-+ 0x10, 0x13, 0x16, 0x66, 0x2b, 0x1a, 0x26, 0x7f,
-+ 0x12, 0x3a, 0x37, 0x36, 0x52, 0x12, 0x00, 0x00,
-+ 0x80, 0x70, 0x50, 0x54, 0xd4, 0x4c, 0x80, 0xf8,
-+ 0x48, 0x28, 0xb0, 0x10, 0x28, 0xc4, 0x00, 0x00,
-+ 0x10, 0x17, 0x11, 0x69, 0x2a, 0x1a, 0x27, 0x7d,
-+ 0x17, 0x39, 0x35, 0x31, 0x56, 0x10, 0x00, 0x00,
-+ 0x20, 0xe0, 0x20, 0x20, 0xbc, 0xc8, 0x68, 0x28,
-+ 0xe8, 0x10, 0x50, 0xa8, 0x48, 0x84, 0x00, 0x00,
-+ 0x10, 0x13, 0x16, 0x66, 0x2b, 0x1a, 0x26, 0x7f,
-+ 0x12, 0x3a, 0x37, 0x36, 0x50, 0x10, 0x00, 0x00,
-+ 0x10, 0x90, 0x90, 0xb8, 0xb8, 0xb4, 0xd4, 0xd4,
-+ 0xb8, 0x88, 0x90, 0xa0, 0x40, 0x80, 0x00, 0x00,
-+ 0x10, 0x11, 0x15, 0x65, 0x29, 0x19, 0x25, 0x7d,
-+ 0x13, 0x39, 0x35, 0x35, 0x51, 0x11, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x20, 0xfc, 0x10, 0xcc,
-+ 0xfc, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x14, 0x67, 0x2a, 0x1b, 0x26, 0x7f,
-+ 0x13, 0x3b, 0x37, 0x34, 0x55, 0x1a, 0x00, 0x00,
-+ 0x20, 0x28, 0x24, 0xfc, 0x20, 0xe8, 0xa8, 0xe8,
-+ 0x58, 0x50, 0x94, 0xec, 0x2c, 0x44, 0x00, 0x00,
-+ 0x10, 0x10, 0x14, 0x65, 0x2a, 0x18, 0x24, 0x7d,
-+ 0x13, 0x39, 0x35, 0x35, 0x53, 0x10, 0x00, 0x00,
-+ 0xf0, 0x10, 0x90, 0xf8, 0x04, 0xb0, 0x90, 0x08,
-+ 0xfc, 0x68, 0x68, 0x68, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x1e, 0x52, 0x5e, 0x52, 0x5e, 0x52, 0x5f,
-+ 0x40, 0x7e, 0x2c, 0x2a, 0x4b, 0x08, 0x00, 0x00,
-+ 0x04, 0xf8, 0x20, 0xc8, 0x50, 0x30, 0x48, 0xfc,
-+ 0x24, 0xb0, 0xa8, 0xa4, 0x24, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x66, 0x2c, 0x1b, 0x25, 0x7c,
-+ 0x13, 0x38, 0x37, 0x34, 0x50, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x48, 0x40, 0xf8, 0x10, 0xa0,
-+ 0xfc, 0x40, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x73, 0x14, 0x0c, 0x12, 0x7f,
-+ 0x0c, 0x2a, 0x2b, 0x2a, 0x4f, 0x08, 0x00, 0x00,
-+ 0x88, 0x48, 0x50, 0xfc, 0x20, 0xf8, 0x20, 0xfc,
-+ 0x80, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x11, 0x12, 0x6a, 0x2d, 0x19, 0x25, 0x7e,
-+ 0x16, 0x3a, 0x36, 0x36, 0x53, 0x12, 0x00, 0x00,
-+ 0x50, 0x50, 0x50, 0x50, 0xb8, 0xa4, 0x24, 0xa0,
-+ 0xa0, 0xb8, 0xa0, 0xe0, 0x20, 0x1c, 0x00, 0x00,
-+ 0x10, 0x13, 0x16, 0x67, 0x2a, 0x1b, 0x26, 0x7e,
-+ 0x13, 0x3a, 0x37, 0x34, 0x58, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x00, 0xfc, 0xa8, 0xf0,
-+ 0x9c, 0x10, 0xfc, 0x90, 0x50, 0x30, 0x00, 0x00,
-+ 0x10, 0x13, 0x14, 0x64, 0x29, 0x1b, 0x24, 0x7f,
-+ 0x11, 0x39, 0x35, 0x35, 0x51, 0x11, 0x00, 0x00,
-+ 0x00, 0xfc, 0x90, 0x90, 0x68, 0xfc, 0x00, 0xfc,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x12, 0x11, 0x15, 0x64, 0x2a, 0x19, 0x25, 0x7c,
-+ 0x13, 0x39, 0x35, 0x35, 0x52, 0x14, 0x00, 0x00,
-+ 0x10, 0x20, 0x78, 0x48, 0x48, 0x78, 0x40, 0x78,
-+ 0x48, 0x48, 0x78, 0x48, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x00, 0x39, 0x29, 0x2a, 0x2f, 0x39, 0x2a, 0x2d,
-+ 0x38, 0x2f, 0x29, 0x29, 0x2a, 0x58, 0x00, 0x00,
-+ 0x40, 0x50, 0xf8, 0xa4, 0xfc, 0x50, 0x58, 0xb4,
-+ 0x48, 0xfc, 0x50, 0x48, 0x48, 0x40, 0x00, 0x00,
-+ 0x10, 0x13, 0x14, 0x67, 0x28, 0x1b, 0x24, 0x7c,
-+ 0x13, 0x39, 0x34, 0x35, 0x50, 0x13, 0x00, 0x00,
-+ 0x00, 0xfc, 0xcc, 0x74, 0xcc, 0x74, 0x44, 0xa0,
-+ 0x70, 0x9c, 0x68, 0x90, 0x60, 0x80, 0x00, 0x00,
-+ 0x10, 0x17, 0x11, 0x69, 0x2f, 0x14, 0x2c, 0x7f,
-+ 0x15, 0x39, 0x35, 0x35, 0x51, 0x16, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0x78, 0x20, 0xf8, 0xa8,
-+ 0xa8, 0xf8, 0x30, 0x28, 0xfc, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x1f, 0x16, 0x16, 0x1a, 0x11,
-+ 0x17, 0x10, 0x1f, 0x22, 0x2c, 0x40, 0x00, 0x00,
-+ 0x80, 0xfc, 0x10, 0xfc, 0xb8, 0xbc, 0xd4, 0x20,
-+ 0x60, 0x98, 0xe4, 0xb0, 0x88, 0x80, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x72, 0x14, 0x0c, 0x13, 0x7f,
-+ 0x09, 0x2d, 0x2a, 0x2a, 0x48, 0x0b, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc, 0x54,
-+ 0xfc, 0xf8, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x6b, 0x2a, 0x1b, 0x24, 0x7d,
-+ 0x10, 0x3b, 0x35, 0x35, 0x52, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xf8, 0xa8, 0xf8, 0x00, 0xf0,
-+ 0x00, 0xfc, 0x50, 0x48, 0x48, 0xc0, 0x00, 0x00,
-+ 0x10, 0x12, 0x16, 0x67, 0x28, 0x1b, 0x26, 0x7e,
-+ 0x13, 0x3a, 0x37, 0x34, 0x54, 0x19, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0xf8, 0x00, 0xb8, 0xa8, 0xa8,
-+ 0xb8, 0xa8, 0xb8, 0xa8, 0xc8, 0x98, 0x00, 0x00,
-+ 0x08, 0x08, 0x0a, 0x73, 0x14, 0x0c, 0x12, 0x7e,
-+ 0x08, 0x2d, 0x2a, 0x2a, 0x48, 0x09, 0x00, 0x00,
-+ 0x20, 0xf8, 0xa8, 0xfc, 0xa8, 0xf8, 0xf8, 0xa8,
-+ 0xf8, 0xfc, 0x48, 0xf0, 0x28, 0xc4, 0x00, 0x00,
-+ 0x10, 0x13, 0x16, 0x67, 0x2a, 0x1b, 0x24, 0x7d,
-+ 0x10, 0x3b, 0x35, 0x35, 0x52, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x90, 0xb0,
-+ 0x48, 0xf4, 0x50, 0x48, 0x48, 0x40, 0x00, 0x00,
-+ 0x12, 0x11, 0x15, 0x64, 0x2a, 0x19, 0x25, 0x7c,
-+ 0x13, 0x39, 0x35, 0x35, 0x52, 0x14, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0xa8, 0xf8, 0xa8,
-+ 0xf8, 0x20, 0xfc, 0x20, 0xe0, 0x3c, 0x00, 0x00,
-+ 0x10, 0x13, 0x14, 0x67, 0x2b, 0x1b, 0x24, 0x7d,
-+ 0x10, 0x3b, 0x34, 0x34, 0x53, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xfc, 0x58, 0xf8, 0x40, 0xf8,
-+ 0x00, 0xfc, 0x50, 0x88, 0xf4, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x16, 0x67, 0x2a, 0x1b, 0x26, 0x7e,
-+ 0x12, 0x3a, 0x36, 0x36, 0x53, 0x12, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0xa8, 0xb8, 0xe8, 0xa8,
-+ 0xe8, 0xa8, 0xe8, 0xa8, 0x68, 0x08, 0x00, 0x00,
-+ 0x12, 0x12, 0x17, 0x6a, 0x2f, 0x18, 0x2b, 0x7e,
-+ 0x13, 0x3a, 0x37, 0x36, 0x52, 0x12, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xe0, 0xa0, 0xfc, 0x48, 0xa8, 0xa8,
-+ 0xa8, 0x90, 0x90, 0xa8, 0xc8, 0x84, 0x00, 0x00,
-+ 0x10, 0x11, 0x14, 0x67, 0x29, 0x1b, 0x25, 0x7d,
-+ 0x13, 0x3b, 0x34, 0x34, 0x51, 0x12, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xfc, 0x10, 0xb8, 0x10, 0xfc,
-+ 0x00, 0xfc, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x09, 0x0a, 0x72, 0x17, 0x0c, 0x12, 0x7f,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x18, 0xe8, 0xa8, 0x70, 0xfc, 0x70, 0xa8, 0x24,
-+ 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x73, 0x14, 0x0d, 0x12, 0x7e,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x49, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x54, 0x88, 0xfc, 0x88, 0xf8,
-+ 0x88, 0xf8, 0xa8, 0xa4, 0x24, 0x60, 0x00, 0x00,
-+ 0x10, 0x13, 0x16, 0x67, 0x28, 0x1b, 0x24, 0x7f,
-+ 0x11, 0x3f, 0x34, 0x37, 0x50, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xf8, 0x40, 0xf8, 0x40, 0xfc,
-+ 0x10, 0xfc, 0x40, 0xf8, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x14, 0x65, 0x2a, 0x1b, 0x27, 0x7e,
-+ 0x13, 0x39, 0x35, 0x35, 0x51, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xf0, 0x08, 0xfc, 0x58, 0xe8,
-+ 0xf8, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0x00,
-+ 0x10, 0x13, 0x16, 0x67, 0x29, 0x1a, 0x26, 0x7f,
-+ 0x12, 0x3a, 0x37, 0x36, 0x50, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xb8, 0xa0, 0xb8, 0xa8, 0xb8,
-+ 0xa8, 0xa8, 0xb8, 0xa4, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x12, 0x17, 0x66, 0x2a, 0x1b, 0x27, 0x7e,
-+ 0x13, 0x3a, 0x37, 0x37, 0x53, 0x12, 0x00, 0x00,
-+ 0x90, 0xd8, 0x68, 0xd0, 0xa8, 0xf8, 0xfc, 0xd8,
-+ 0x68, 0x90, 0x68, 0xf8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x14, 0x67, 0x2b, 0x1f, 0x24, 0x7f,
-+ 0x10, 0x3b, 0x36, 0x36, 0x52, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xfc, 0x58, 0x58, 0x40, 0xfc,
-+ 0x40, 0xf8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x17, 0x68, 0x2f, 0x12, 0x2a, 0x7d,
-+ 0x11, 0x39, 0x35, 0x35, 0x52, 0x14, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa4, 0xf8, 0xe8, 0xf8, 0xe4,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x0b, 0x72, 0x14, 0x0c, 0x13, 0x7e,
-+ 0x0c, 0x2a, 0x2a, 0x28, 0x49, 0x0a, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x50, 0x70, 0x8c, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x88, 0x08, 0x08, 0x00, 0x00,
-+ 0x08, 0x09, 0x0b, 0x73, 0x14, 0x0d, 0x12, 0x7f,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x0b, 0x00, 0x00,
-+ 0x20, 0xfc, 0x08, 0xfc, 0xa8, 0x70, 0x78, 0x88,
-+ 0xf8, 0xf8, 0x88, 0xf8, 0x88, 0x04, 0x00, 0x00,
-+ 0x11, 0x11, 0x7d, 0x2e, 0x2a, 0x29, 0x7e, 0x13,
-+ 0x1d, 0x75, 0x15, 0x25, 0x29, 0x41, 0x00, 0x00,
-+ 0x10, 0x10, 0x7c, 0xa8, 0xa8, 0x28, 0xfc, 0xd0,
-+ 0x10, 0xfc, 0x50, 0x50, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x13, 0x16, 0x67, 0x2a, 0x1b, 0x26, 0x7f,
-+ 0x18, 0x37, 0x36, 0x32, 0x57, 0x10, 0x00, 0x00,
-+ 0x10, 0xd0, 0x90, 0xdc, 0x60, 0xc0, 0xb8, 0xc0,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x11, 0x15, 0x67, 0x29, 0x19, 0x27, 0x7c,
-+ 0x13, 0x3a, 0x36, 0x37, 0x52, 0x10, 0x00, 0x00,
-+ 0x00, 0x7c, 0x10, 0xd0, 0x38, 0x28, 0xb8, 0x28,
-+ 0xb8, 0xa8, 0xb8, 0xa8, 0xa4, 0x44, 0x00, 0x00,
-+ 0x11, 0x13, 0x15, 0x67, 0x29, 0x1a, 0x25, 0x7d,
-+ 0x11, 0x39, 0x35, 0x35, 0x50, 0x13, 0x00, 0x00,
-+ 0x10, 0xb8, 0x10, 0xfc, 0x10, 0xa8, 0xf4, 0x10,
-+ 0xf0, 0xf0, 0x10, 0xf0, 0x90, 0x08, 0x00, 0x00,
-+ 0x10, 0x17, 0x11, 0x67, 0x2a, 0x1b, 0x27, 0x7f,
-+ 0x11, 0x39, 0x35, 0x35, 0x51, 0x16, 0x00, 0x00,
-+ 0x40, 0xfc, 0xf0, 0xf8, 0xb8, 0x38, 0xf8, 0xf0,
-+ 0xf0, 0xf0, 0x10, 0xf0, 0x90, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x16, 0x66, 0x2a, 0x1a, 0x26, 0x7e,
-+ 0x13, 0x3a, 0x37, 0x34, 0x54, 0x1b, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0xf8,
-+ 0xfc, 0xa8, 0x74, 0xf8, 0x20, 0xfc, 0x00, 0x00,
-+ 0x11, 0x11, 0x15, 0x67, 0x2a, 0x1a, 0x24, 0x7e,
-+ 0x19, 0x35, 0x35, 0x32, 0x54, 0x10, 0x00, 0x00,
-+ 0x00, 0x7c, 0x10, 0xd0, 0xb8, 0x68, 0xf8, 0xa8,
-+ 0xb8, 0xa8, 0x78, 0x68, 0x24, 0x44, 0x00, 0x00,
-+ 0x10, 0x13, 0x16, 0x67, 0x2b, 0x1a, 0x27, 0x7d,
-+ 0x12, 0x3b, 0x34, 0x35, 0x50, 0x13, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0xb8, 0xa8, 0xb8, 0xa8,
-+ 0x44, 0xfc, 0x90, 0xe0, 0x70, 0x88, 0x00, 0x00,
-+ 0x10, 0x11, 0x17, 0x65, 0x29, 0x19, 0x25, 0x7f,
-+ 0x10, 0x3b, 0x35, 0x35, 0x50, 0x17, 0x00, 0x00,
-+ 0xf0, 0x20, 0xf8, 0xf8, 0xe4, 0x38, 0xe4, 0x5c,
-+ 0xf0, 0xf0, 0x50, 0xf8, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x12, 0x12, 0x13, 0x6d, 0x2f, 0x1a, 0x2e, 0x7a,
-+ 0x16, 0x3a, 0x3e, 0x33, 0x56, 0x10, 0x00, 0x00,
-+ 0xa0, 0xb0, 0xa8, 0x68, 0xfc, 0xa0, 0xe8, 0xa8,
-+ 0xe8, 0xd0, 0x90, 0xf4, 0x4c, 0x84, 0x00, 0x00,
-+ 0x11, 0x11, 0x17, 0x69, 0x2f, 0x1a, 0x2e, 0x7a,
-+ 0x16, 0x3a, 0x3e, 0x33, 0x56, 0x10, 0x00, 0x00,
-+ 0x20, 0x30, 0xe8, 0x28, 0xfc, 0xa0, 0xe8, 0xa8,
-+ 0xe8, 0xd0, 0x90, 0xf4, 0x4c, 0x84, 0x00, 0x00,
-+ 0x01, 0x3f, 0x0f, 0x7f, 0x0f, 0x7f, 0x1f, 0x2e,
-+ 0x2f, 0x2e, 0x2e, 0x3f, 0x2a, 0x49, 0x00, 0x00,
-+ 0x00, 0xf8, 0xe0, 0xfc, 0xe0, 0xfc, 0xe0, 0xdc,
-+ 0xf8, 0xd0, 0x28, 0xfc, 0x58, 0x94, 0x00, 0x00,
-+ 0x10, 0x17, 0x15, 0x6f, 0x2f, 0x15, 0x2f, 0x7d,
-+ 0x19, 0x35, 0x35, 0x31, 0x50, 0x17, 0x00, 0x00,
-+ 0x20, 0xbc, 0x40, 0xf8, 0xfc, 0x74, 0xfc, 0xf0,
-+ 0xf0, 0xf0, 0x10, 0xf4, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x10, 0x11, 0x1e, 0x28, 0x48, 0x7f, 0x08, 0x2a,
-+ 0x2a, 0x2a, 0x2a, 0x3e, 0x23, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x1e, 0x28, 0x48, 0x7f, 0x08, 0x2b,
-+ 0x2a, 0x2a, 0x2a, 0x3e, 0x23, 0x22, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xf8, 0x28, 0x28, 0x28, 0xfc,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x3f, 0x29, 0x49, 0x7f, 0x09,
-+ 0x2d, 0x2d, 0x2d, 0x3e, 0x26, 0x24, 0x00, 0x00,
-+ 0x40, 0x78, 0xfc, 0x58, 0xe8, 0x38, 0x18, 0xe8,
-+ 0xa8, 0x70, 0xfc, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x3e, 0x3e, 0x14, 0x66,
-+ 0x0f, 0x11, 0x7f, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0xf8, 0xf8, 0x50, 0x8c,
-+ 0xf0, 0x00, 0xfc, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x0f, 0x09, 0x0f, 0x0f, 0x3e, 0x3e, 0x2a,
-+ 0x3e, 0x0f, 0x7f, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0xe0, 0xf8, 0xf8, 0xa8,
-+ 0xf8, 0xe0, 0xfc, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x3f, 0x2b, 0x48, 0x7f, 0x0b,
-+ 0x2d, 0x2c, 0x2f, 0x3c, 0x24, 0x23, 0x00, 0x00,
-+ 0xf0, 0x10, 0xf0, 0xf0, 0xf8, 0x40, 0xfc, 0x78,
-+ 0xd8, 0xf0, 0xfc, 0x90, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x3f, 0x29, 0x49, 0x7e, 0x09,
-+ 0x2f, 0x2d, 0x2d, 0x3d, 0x25, 0x21, 0x00, 0x00,
-+ 0x90, 0xfc, 0x90, 0xf8, 0x68, 0xf8, 0x90, 0xfc,
-+ 0x20, 0xf8, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x44, 0x44, 0x44, 0x66, 0x55, 0x48,
-+ 0x4c, 0x4c, 0x53, 0x51, 0x62, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x48, 0x48, 0x88,
-+ 0xc8, 0xc8, 0x28, 0x28, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x44, 0x08, 0x10, 0x1f, 0x01,
-+ 0x01, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0x88, 0x78, 0x00, 0xf0, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x22, 0x22, 0x3f, 0x21, 0x27,
-+ 0x24, 0x24, 0x24, 0x23, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x88, 0xf8, 0x08, 0xe8,
-+ 0x08, 0x08, 0x08, 0xc8, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x3f, 0x00, 0x7f, 0x00,
-+ 0x01, 0x07, 0x19, 0x61, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x00, 0xfc, 0x80,
-+ 0x80, 0x60, 0x18, 0x04, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x3f, 0x21, 0x01, 0x7f,
-+ 0x01, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x08, 0x00, 0xfc,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x00, 0x1f, 0x10, 0x1f,
-+ 0x11, 0x1f, 0x10, 0x10, 0x1f, 0x70, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x00, 0xf8, 0x80, 0x44, 0x34, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x02, 0x7f, 0x09, 0x1f,
-+ 0x69, 0x0f, 0x09, 0x0f, 0x09, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x00, 0xfc, 0x20, 0xf0,
-+ 0x2c, 0xe0, 0x20, 0xe8, 0x08, 0xf8, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x01, 0x01, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x00, 0xf8, 0xe0, 0x20,
-+ 0xe0, 0x20, 0xe0, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x3f, 0x08, 0x08, 0x7f,
-+ 0x1c, 0x1a, 0x2a, 0x49, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x20, 0x20, 0xfc,
-+ 0x70, 0x70, 0xa8, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x00, 0x1c, 0x7f, 0x00,
-+ 0x1c, 0x1c, 0x3e, 0x22, 0x3e, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x10, 0x10, 0xfc, 0x10,
-+ 0x90, 0x50, 0x50, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x10, 0x14, 0x64, 0x19,
-+ 0x15, 0x7f, 0x2d, 0x2b, 0x49, 0x09, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0xf0, 0x90, 0xf0, 0xf8,
-+ 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x14, 0x7e, 0x3e, 0x22,
-+ 0x3e, 0x3e, 0x22, 0x26, 0x24, 0x42, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x90, 0xe0, 0x88, 0x78,
-+ 0x90, 0xe0, 0x88, 0x78, 0x88, 0x44, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x7f, 0x0f, 0x08, 0x0f,
-+ 0x0f, 0x7f, 0x1f, 0x69, 0x09, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0xfc, 0xe0, 0x20, 0xe0,
-+ 0xe0, 0xfc, 0xf0, 0x2c, 0x60, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x14, 0x7f, 0x14, 0x1c,
-+ 0x3e, 0x2a, 0x3e, 0x7f, 0x09, 0x0a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0xfc, 0xa0, 0xf8, 0xa0,
-+ 0xf8, 0xa0, 0xfc, 0xd4, 0x6c, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x14, 0x7f, 0x14, 0x1c,
-+ 0x3f, 0x2a, 0x3e, 0x7f, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x20, 0xf8, 0x60, 0x90,
-+ 0xfc, 0xe8, 0xa8, 0xe8, 0x88, 0x18, 0x00, 0x00,
-+ 0x08, 0x04, 0x04, 0x3f, 0x01, 0x1f, 0x01, 0x7f,
-+ 0x04, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0xf8, 0x00, 0xf0, 0x00, 0xfc,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x04, 0x04, 0x3f, 0x01, 0x01, 0x1f, 0x01,
-+ 0x01, 0x7f, 0x00, 0x24, 0x22, 0x42, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0xf8, 0x00, 0x00, 0xf0, 0x00,
-+ 0x00, 0xfc, 0x00, 0x88, 0x44, 0x44, 0x00, 0x00,
-+ 0x08, 0x04, 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x08,
-+ 0x0f, 0x11, 0x2f, 0x42, 0x3f, 0x00, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x00,
-+ 0xe0, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x22, 0x12, 0x14, 0x7f, 0x08, 0x08, 0x3e, 0x08,
-+ 0x0e, 0x78, 0x10, 0x11, 0x27, 0x40, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0xa0, 0xa0, 0xa0, 0xfc, 0x90,
-+ 0x90, 0x94, 0xcc, 0x8c, 0xf4, 0x04, 0x00, 0x00,
-+ 0x22, 0x12, 0x14, 0x7f, 0x08, 0x09, 0x3e, 0x09,
-+ 0x0e, 0x78, 0x10, 0x10, 0x20, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0xfc, 0x00, 0xf8,
-+ 0x48, 0x48, 0x48, 0x70, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x7f, 0x1f, 0x07, 0x1c, 0x67,
-+ 0x04, 0x3f, 0x1f, 0x01, 0x7f, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xfc, 0xf0, 0xf8, 0x08, 0xf8,
-+ 0x40, 0xf8, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x22, 0x12, 0x14, 0x7f, 0x08, 0x08, 0x3e, 0x08,
-+ 0x0f, 0x79, 0x11, 0x11, 0x21, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x40, 0xfc,
-+ 0x24, 0x64, 0x94, 0xf4, 0x04, 0x18, 0x00, 0x00,
-+ 0x04, 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x06, 0x38,
-+ 0x7f, 0x1a, 0x7f, 0x1e, 0x02, 0x0d, 0x00, 0x00,
-+ 0x40, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x50, 0x48,
-+ 0xfc, 0x28, 0x28, 0x14, 0x6c, 0x84, 0x00, 0x00,
-+ 0x04, 0x3f, 0x01, 0x1f, 0x7f, 0x24, 0x4a, 0x3f,
-+ 0x0f, 0x7f, 0x01, 0x7f, 0x0c, 0x70, 0x00, 0x00,
-+ 0x40, 0xf8, 0x00, 0xf0, 0xfc, 0x88, 0x64, 0xf8,
-+ 0xe0, 0xfc, 0x00, 0xfc, 0x60, 0x1c, 0x00, 0x00,
-+ 0x04, 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x24, 0x42,
-+ 0x3f, 0x0f, 0x01, 0x7f, 0x0c, 0x70, 0x00, 0x00,
-+ 0x40, 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x88, 0x44,
-+ 0xf8, 0xe0, 0x00, 0xfc, 0x60, 0x1c, 0x00, 0x00,
-+ 0x44, 0x2b, 0x7f, 0x12, 0x12, 0x3a, 0x13, 0x1d,
-+ 0x71, 0x11, 0x21, 0x21, 0x47, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0xf8, 0xe8, 0xa8, 0xe8, 0xf8, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x3f, 0x20, 0x1f, 0x1f, 0x10, 0x1f, 0x3a,
-+ 0x2f, 0x3b, 0x29, 0x3f, 0x29, 0x59, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0xf0, 0x10, 0xf0, 0xb8,
-+ 0xe8, 0xa8, 0x38, 0xec, 0x2c, 0x44, 0x00, 0x00,
-+ 0x08, 0x3f, 0x01, 0x1f, 0x7f, 0x01, 0x19, 0x7f,
-+ 0x19, 0x19, 0x3d, 0x25, 0x3d, 0x25, 0x00, 0x00,
-+ 0x20, 0xf8, 0x00, 0xf0, 0xfc, 0x00, 0x30, 0xfc,
-+ 0x30, 0x30, 0x78, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x11, 0x12, 0x7c, 0x24,
-+ 0x15, 0x1a, 0x08, 0x14, 0x23, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0xd8, 0xd8, 0x68, 0x48, 0xd8, 0xd8,
-+ 0x68, 0x48, 0x48, 0xd8, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3e, 0x0a, 0x36, 0x0a, 0x32, 0x02, 0x3f,
-+ 0x04, 0x09, 0x31, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0xd8, 0x28, 0xc8, 0x00, 0xc0,
-+ 0x44, 0x3c, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7d, 0x09, 0x4a, 0x2c, 0x28,
-+ 0x29, 0x11, 0x1a, 0x64, 0x00, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x98, 0x98, 0xa8, 0xc8, 0x98,
-+ 0x98, 0xa8, 0xc8, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x01, 0x02, 0x0f, 0x70, 0x0f, 0x08, 0x0f, 0x00,
-+ 0x7f, 0x0a, 0x36, 0x0a, 0x32, 0x06, 0x00, 0x00,
-+ 0x00, 0x80, 0xe0, 0x1c, 0xe0, 0x20, 0xe0, 0x00,
-+ 0xf8, 0x28, 0xd8, 0x28, 0xc8, 0x18, 0x00, 0x00,
-+ 0x44, 0x27, 0x28, 0x7c, 0x12, 0x11, 0x3d, 0x10,
-+ 0x19, 0x72, 0x14, 0x10, 0x20, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xc8, 0xa8, 0xa8, 0x88,
-+ 0x98, 0xa8, 0xc8, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x04, 0x7c, 0x04, 0x3c, 0x04, 0x7c, 0x08, 0x7f,
-+ 0x06, 0x1a, 0x67, 0x1a, 0x63, 0x06, 0x00, 0x00,
-+ 0x80, 0xfc, 0x80, 0xf8, 0x80, 0xfc, 0x80, 0xf8,
-+ 0x18, 0x68, 0x98, 0x68, 0x88, 0x18, 0x00, 0x00,
-+ 0x04, 0x7f, 0x3e, 0x3a, 0x26, 0x3a, 0x26, 0x26,
-+ 0x7f, 0x0a, 0x36, 0x0a, 0x32, 0x06, 0x00, 0x00,
-+ 0x40, 0xfc, 0x08, 0x48, 0x48, 0x48, 0x48, 0x18,
-+ 0xf8, 0x28, 0xd8, 0x28, 0xc8, 0x18, 0x00, 0x00,
-+ 0x00, 0x7f, 0x00, 0x3e, 0x22, 0x3f, 0x20, 0x3e,
-+ 0x2e, 0x7f, 0x6e, 0x2e, 0x2e, 0x26, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xd8, 0xd8, 0x68, 0x48, 0xd8,
-+ 0xd8, 0x68, 0x48, 0x48, 0x48, 0xd8, 0x00, 0x00,
-+ 0x00, 0x3f, 0x2e, 0x34, 0x3f, 0x2c, 0x32, 0x3f,
-+ 0x3e, 0x0a, 0x36, 0x0a, 0x32, 0x06, 0x00, 0x00,
-+ 0x00, 0x70, 0x54, 0x8c, 0xf8, 0x50, 0x30, 0xcc,
-+ 0xf8, 0x28, 0xd8, 0x28, 0xc8, 0x18, 0x00, 0x00,
-+ 0x08, 0x3d, 0x08, 0x7e, 0x25, 0x7e, 0x24, 0x3e,
-+ 0x41, 0x7e, 0x14, 0x14, 0x24, 0x43, 0x00, 0x00,
-+ 0x00, 0xf8, 0xd8, 0xd8, 0x68, 0x48, 0xd8, 0xd8,
-+ 0x68, 0x48, 0x48, 0xdc, 0x04, 0xfc, 0x00, 0x00,
-+ 0x06, 0x7b, 0x2a, 0x1c, 0x7f, 0x1c, 0x1a, 0x29,
-+ 0x7e, 0x2a, 0x3e, 0x2a, 0x3f, 0x22, 0x00, 0x00,
-+ 0x00, 0xf4, 0x78, 0xb8, 0xb4, 0xac, 0xa4, 0xf4,
-+ 0xb8, 0xb8, 0xb4, 0xac, 0x2c, 0x24, 0x00, 0x00,
-+ 0x02, 0x1f, 0x02, 0x7f, 0x03, 0x0f, 0x72, 0x01,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x10, 0xe0, 0x40, 0xfc, 0x30, 0xc8, 0x08, 0xf8,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x02, 0x1f, 0x02, 0x7f, 0x03, 0x0f, 0x72, 0x01,
-+ 0x1f, 0x03, 0x3e, 0x03, 0x7e, 0x01, 0x00, 0x00,
-+ 0x10, 0xe0, 0x40, 0xfc, 0x30, 0xc8, 0x08, 0xf8,
-+ 0x80, 0xf0, 0x00, 0xfc, 0x04, 0xfc, 0x00, 0x00,
-+ 0x02, 0x1f, 0x02, 0x7f, 0x03, 0x0f, 0x71, 0x3f,
-+ 0x02, 0x3f, 0x0f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x10, 0xe0, 0x40, 0xfc, 0x30, 0xc4, 0xfc, 0xf8,
-+ 0x20, 0xf8, 0xe0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x01, 0x1f, 0x01, 0x01, 0x7f,
-+ 0x03, 0x05, 0x19, 0x61, 0x01, 0x01, 0x00, 0x00,
-+ 0x18, 0xe0, 0x00, 0x00, 0xf0, 0x00, 0x00, 0xfc,
-+ 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x0e, 0x78, 0x08, 0x3e, 0x09, 0x7e, 0x08,
-+ 0x1c, 0x1a, 0x2a, 0x48, 0x09, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfc, 0x20, 0x20,
-+ 0x20, 0x30, 0x48, 0x58, 0xe4, 0x04, 0x00, 0x00,
-+ 0x08, 0x0e, 0x78, 0x08, 0x3e, 0x08, 0x7f, 0x08,
-+ 0x1c, 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xa8, 0xa8, 0xf8, 0x88,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x0e, 0x78, 0x08, 0x3e, 0x08, 0x7e, 0x08,
-+ 0x1c, 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0x90, 0xf0, 0x90, 0x80,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x10, 0x1f, 0x72, 0x12, 0x3b, 0x12, 0x7e, 0x1b,
-+ 0x36, 0x36, 0x53, 0x16, 0x10, 0x11, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xa0, 0xf8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xe8, 0xc8, 0x48, 0x88, 0x30, 0x00, 0x00,
-+ 0x08, 0x0f, 0x79, 0x09, 0x3f, 0x09, 0x7f, 0x0d,
-+ 0x1b, 0x1b, 0x29, 0x4a, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x00, 0xfc, 0x54, 0x78,
-+ 0xcc, 0xfc, 0x48, 0x28, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x7f, 0x12, 0x12, 0x1e, 0x12, 0x12, 0x1f,
-+ 0x12, 0x12, 0x1e, 0x72, 0x03, 0x02, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x24, 0xa4, 0xa8, 0xb0, 0x20,
-+ 0x30, 0x50, 0x50, 0x88, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x7e, 0x24, 0x24, 0x3c, 0x24, 0x24, 0x3c,
-+ 0x24, 0x24, 0x3c, 0x64, 0x07, 0x04, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xa0, 0xb8, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x2a, 0x2a, 0x3a, 0x2a, 0x2a, 0x3a,
-+ 0x2a, 0x2b, 0x3e, 0x68, 0x09, 0x0a, 0x00, 0x00,
-+ 0x80, 0x38, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xb8, 0xa0, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x7e, 0x24, 0x24, 0x3d, 0x27, 0x24, 0x3f,
-+ 0x24, 0x24, 0x3c, 0x64, 0x04, 0x04, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xa0, 0x10, 0xf8, 0x04, 0xf8,
-+ 0x48, 0x48, 0x48, 0x70, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x7e, 0x24, 0x24, 0x3c, 0x25, 0x24, 0x3c,
-+ 0x24, 0x24, 0x3c, 0x64, 0x04, 0x04, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x7f, 0x25, 0x25, 0x3d, 0x25, 0x24, 0x3f,
-+ 0x24, 0x24, 0x3c, 0x64, 0x04, 0x04, 0x00, 0x00,
-+ 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x00, 0xfc,
-+ 0x40, 0x78, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x7f, 0x12, 0x1e, 0x1e, 0x12, 0x1f, 0x72,
-+ 0x03, 0x09, 0x35, 0x09, 0x31, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x48, 0x30, 0x70, 0x88, 0x44,
-+ 0x90, 0x90, 0x60, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x10, 0x1e, 0x28, 0x7f, 0x0c, 0x12, 0x20, 0x7f,
-+ 0x08, 0x0f, 0x0f, 0x08, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0xfc,
-+ 0x20, 0xe0, 0xe0, 0x3c, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x7e, 0x25, 0x25, 0x3e, 0x25, 0x24, 0x3c,
-+ 0x24, 0x24, 0x3c, 0x64, 0x05, 0x06, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0x00, 0xfc, 0x20, 0xa0,
-+ 0xb8, 0xa0, 0xa0, 0xe0, 0x20, 0x1c, 0x00, 0x00,
-+ 0x01, 0x7d, 0x2e, 0x2a, 0x39, 0x2a, 0x2f, 0x38,
-+ 0x28, 0x2f, 0x38, 0x68, 0x09, 0x0a, 0x00, 0x00,
-+ 0x10, 0x10, 0xe8, 0xa8, 0x10, 0xa8, 0xfc, 0x44,
-+ 0x90, 0xfc, 0x90, 0x90, 0x10, 0x10, 0x00, 0x00,
-+ 0x09, 0x31, 0x0a, 0x15, 0x71, 0x12, 0x14, 0x7f,
-+ 0x08, 0x0f, 0x0f, 0x08, 0x7f, 0x00, 0x00, 0x00,
-+ 0x10, 0x90, 0x68, 0x44, 0x78, 0xc0, 0x7c, 0xfc,
-+ 0x20, 0xe0, 0xe0, 0x3c, 0xe0, 0x20, 0x00, 0x00,
-+ 0x08, 0x7f, 0x08, 0x3e, 0x3e, 0x2a, 0x3e, 0x21,
-+ 0x5f, 0x0f, 0x0f, 0x08, 0x7f, 0x00, 0x00, 0x00,
-+ 0x70, 0x50, 0x54, 0x8c, 0xf8, 0x50, 0x30, 0xcc,
-+ 0xf8, 0xe0, 0xe0, 0x38, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x7f, 0x25, 0x25, 0x3d, 0x25, 0x25, 0x3d,
-+ 0x24, 0x25, 0x3d, 0x66, 0x04, 0x04, 0x00, 0x00,
-+ 0x40, 0xf8, 0x48, 0x78, 0xa8, 0x68, 0x98, 0xf8,
-+ 0x40, 0xa8, 0xa4, 0x84, 0x90, 0x70, 0x00, 0x00,
-+ 0x00, 0x3f, 0x04, 0x07, 0x07, 0x3f, 0x00, 0x7f,
-+ 0x12, 0x1e, 0x1e, 0x12, 0x7f, 0x02, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xc0, 0xc0, 0xc0, 0x40, 0xfc,
-+ 0x90, 0xf0, 0xf0, 0x90, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x7f, 0x2a, 0x2d, 0x3a, 0x2c, 0x2b, 0x3a,
-+ 0x2f, 0x28, 0x3f, 0x68, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0xfc, 0x48, 0xa8, 0x94, 0x70, 0xf8, 0xa8,
-+ 0xfc, 0x00, 0xfc, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x7c, 0x2f, 0x38, 0x3b, 0x2a, 0x3b, 0x68,
-+ 0x7f, 0x28, 0x7a, 0x3a, 0x6c, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0xa8, 0xf8, 0x00,
-+ 0xfc, 0x40, 0xa8, 0xa4, 0x94, 0x70, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x01, 0x7f, 0x01, 0x1f, 0x01,
-+ 0x1f, 0x01, 0x7f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x10, 0xfc, 0x10, 0xf0, 0x00,
-+ 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x20, 0x26, 0x38, 0x22, 0x1f, 0x10, 0x1e, 0x28,
-+ 0x7e, 0x08, 0x15, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x28, 0xfc, 0x28, 0xf8, 0x20,
-+ 0xf8, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3e, 0x20, 0x3c, 0x21, 0x3c, 0x20, 0x7e,
-+ 0x10, 0x18, 0x25, 0x2a, 0x72, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x28, 0xfc, 0x28, 0xf8, 0x20,
-+ 0xf8, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x01, 0x1f, 0x01, 0x7f, 0x01, 0x1f, 0x15, 0x1d,
-+ 0x11, 0x1f, 0x11, 0x1d, 0x25, 0x45, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xfc, 0x10, 0xf0, 0x50, 0x70,
-+ 0x10, 0xf0, 0x10, 0x70, 0x50, 0x50, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x24, 0x3c, 0x24, 0x24,
-+ 0x3c, 0x24, 0x24, 0x24, 0x27, 0x4c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x3f, 0x20, 0x20, 0x1f, 0x00, 0x1f, 0x10,
-+ 0x1f, 0x10, 0x1f, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0xf8, 0x00, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x24, 0x24, 0x3f, 0x24, 0x24,
-+ 0x3c, 0x24, 0x24, 0x24, 0x27, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0xf8, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x3c, 0x24, 0x25, 0x25, 0x3d, 0x25, 0x25,
-+ 0x3d, 0x25, 0x25, 0x25, 0x25, 0x4d, 0x00, 0x00,
-+ 0xc0, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0x68,
-+ 0x98, 0x18, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x20, 0x3f, 0x20, 0x3f, 0x20, 0x1f,
-+ 0x10, 0x1f, 0x10, 0x1f, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xe8, 0x08, 0xe8, 0x08, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x27, 0x24, 0x3c, 0x24, 0x24,
-+ 0x3c, 0x24, 0x24, 0x25, 0x26, 0x4c, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0xfc, 0x40, 0x40, 0x60, 0x60,
-+ 0x60, 0xa0, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x25, 0x3d, 0x25, 0x25,
-+ 0x3d, 0x24, 0x24, 0x24, 0x24, 0x4c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x7f, 0x09, 0x09, 0x17, 0x61, 0x00, 0x1f,
-+ 0x10, 0x1f, 0x10, 0x1f, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x10, 0xf8, 0x00, 0xfc, 0x00, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x24, 0x25, 0x3e, 0x24, 0x24,
-+ 0x3c, 0x24, 0x24, 0x24, 0x24, 0x4c, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x40, 0x40, 0x7c, 0x40,
-+ 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x25, 0x25, 0x3d, 0x25, 0x25,
-+ 0x3d, 0x25, 0x27, 0x24, 0x27, 0x4c, 0x00, 0x00,
-+ 0x08, 0x30, 0xe0, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0x20, 0xd4, 0x14, 0x0c, 0xfc, 0x04, 0x00, 0x00,
-+ 0x01, 0x3f, 0x21, 0x3f, 0x21, 0x3f, 0x00, 0x1f,
-+ 0x10, 0x1f, 0x10, 0x1f, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x00, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x24, 0x3c, 0x24, 0x25,
-+ 0x3e, 0x24, 0x24, 0x24, 0x27, 0x4c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x40, 0x60, 0xd0, 0x48,
-+ 0x44, 0x44, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x25, 0x26, 0x3f, 0x24, 0x24,
-+ 0x3f, 0x24, 0x24, 0x24, 0x24, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0x50, 0x48, 0x44, 0xf8, 0x40, 0x40,
-+ 0xfc, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x25, 0x24, 0x3f, 0x24, 0x24,
-+ 0x3d, 0x25, 0x26, 0x24, 0x24, 0x4c, 0x00, 0x00,
-+ 0x40, 0x20, 0x20, 0xc0, 0x48, 0xe8, 0xf0, 0xe0,
-+ 0x50, 0x50, 0x48, 0x44, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x24, 0x25, 0x3e, 0x24, 0x27,
-+ 0x3c, 0x24, 0x24, 0x24, 0x24, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0x10, 0xe8, 0x04, 0xf8,
-+ 0x40, 0x78, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x26, 0x25, 0x25, 0x3c, 0x27, 0x24,
-+ 0x3c, 0x24, 0x25, 0x25, 0x26, 0x4c, 0x00, 0x00,
-+ 0x40, 0x48, 0x48, 0x50, 0x60, 0x40, 0xfc, 0xa0,
-+ 0xa0, 0xa0, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x25, 0x3d, 0x24, 0x24,
-+ 0x3d, 0x24, 0x24, 0x24, 0x27, 0x4c, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa8, 0xa8, 0x50, 0x50, 0xa8, 0x00,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x15, 0x16, 0x34, 0x57, 0x14,
-+ 0x14, 0x14, 0x14, 0x14, 0x14, 0x10, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x90, 0x60, 0xf0, 0x0c, 0xf8,
-+ 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x98, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1f, 0x10, 0x1f, 0x14, 0x37, 0x2c,
-+ 0x5f, 0x10, 0x1f, 0x1f, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf0, 0x00, 0xfc, 0x90, 0x60, 0x1c,
-+ 0xf0, 0x10, 0xf0, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x24, 0x25, 0x3d, 0x25, 0x25,
-+ 0x3d, 0x25, 0x25, 0x25, 0x25, 0x4d, 0x00, 0x00,
-+ 0x50, 0x48, 0xfc, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x24, 0x24, 0x3d, 0x25, 0x27,
-+ 0x3d, 0x25, 0x25, 0x25, 0x25, 0x4d, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0xa0, 0x38, 0x48, 0x68,
-+ 0xd0, 0x50, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x28, 0x29, 0x32, 0x28, 0x25,
-+ 0x25, 0x25, 0x39, 0x21, 0x21, 0x21, 0x00, 0x00,
-+ 0x80, 0xfc, 0x80, 0xf8, 0x20, 0xfc, 0x00, 0xf8,
-+ 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x38, 0x28, 0x2b, 0x2a, 0x3a, 0x2b, 0x2a,
-+ 0x3a, 0x2f, 0x28, 0x28, 0x29, 0x5a, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xa0, 0xf8, 0xa8, 0xa8, 0xf8, 0xa8,
-+ 0xa8, 0xfc, 0xa0, 0x90, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x25, 0x25, 0x3d, 0x25, 0x25,
-+ 0x3c, 0x24, 0x27, 0x24, 0x24, 0x4c, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x48, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x50, 0x90, 0xfc, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x27, 0x24, 0x3c, 0x27, 0x24,
-+ 0x3c, 0x27, 0x24, 0x25, 0x25, 0x4e, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xa0, 0xbc, 0xa0, 0xa0, 0xbc, 0xa0,
-+ 0xe0, 0xbc, 0xa0, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x38, 0x2b, 0x2a, 0x2a, 0x3a, 0x2a, 0x2b,
-+ 0x3a, 0x2a, 0x2a, 0x2c, 0x2c, 0x58, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x48, 0x48, 0x88, 0xfc, 0xc8,
-+ 0xa8, 0xa8, 0x88, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x01, 0x3c, 0x24, 0x27, 0x24, 0x3c, 0x24, 0x27,
-+ 0x3c, 0x24, 0x24, 0x25, 0x25, 0x4e, 0x00, 0x00,
-+ 0x08, 0x88, 0x90, 0xfc, 0x90, 0x90, 0x90, 0xfc,
-+ 0x90, 0x90, 0x90, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x38, 0x2f, 0x29, 0x2a, 0x3a, 0x2f, 0x29,
-+ 0x3d, 0x2d, 0x2b, 0x2b, 0x2c, 0x58, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x28, 0xfc, 0x28, 0xf8, 0x20,
-+ 0xf8, 0x20, 0xfc, 0x20, 0xe0, 0x3c, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x25, 0x3d, 0x25, 0x25,
-+ 0x3c, 0x25, 0x25, 0x26, 0x24, 0x4c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x40, 0xa8, 0xa4, 0x84, 0x90, 0x70, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x25, 0x3d, 0x24, 0x24,
-+ 0x3d, 0x26, 0x25, 0x24, 0x27, 0x4c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0xa0, 0xa0,
-+ 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x25, 0x24, 0x3c, 0x25, 0x25,
-+ 0x3d, 0x25, 0x25, 0x25, 0x25, 0x4d, 0x00, 0x00,
-+ 0xa8, 0xa8, 0x50, 0x50, 0xa8, 0x40, 0xf8, 0x28,
-+ 0xe8, 0x28, 0x58, 0x88, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3d, 0x26, 0x26, 0x27, 0x3e, 0x26, 0x27,
-+ 0x3e, 0x24, 0x24, 0x24, 0x25, 0x4e, 0x00, 0x00,
-+ 0x40, 0x58, 0x48, 0x48, 0x58, 0x48, 0x48, 0x58,
-+ 0x48, 0x60, 0xa0, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x25, 0x3d, 0x25, 0x24,
-+ 0x3d, 0x25, 0x25, 0x25, 0x27, 0x4c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0x28, 0x58, 0x88, 0xf8, 0x00,
-+ 0xf8, 0x68, 0x68, 0x68, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3b, 0x28, 0x29, 0x29, 0x39, 0x28, 0x2b,
-+ 0x3a, 0x2b, 0x2a, 0x2a, 0x2a, 0x5a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0xa8, 0x38, 0xe8, 0x48, 0x48, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x25, 0x25, 0x25, 0x3d, 0x25, 0x25,
-+ 0x3d, 0x24, 0x27, 0x25, 0x24, 0x4c, 0x00, 0x00,
-+ 0x50, 0xfc, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x48,
-+ 0x58, 0x10, 0xfc, 0x10, 0x90, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x25, 0x24, 0x3f, 0x26, 0x27,
-+ 0x3c, 0x24, 0x24, 0x24, 0x25, 0x4e, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0xa0, 0xfc, 0x48, 0xfc,
-+ 0x40, 0x78, 0x48, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x7e, 0x11, 0x1e, 0x14, 0x24, 0x39, 0x4f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x08, 0x08, 0x00, 0x00,
-+ 0x80, 0xfc, 0x20, 0xe8, 0x90, 0xe8, 0x84, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x3f, 0x25, 0x26, 0x25, 0x3e, 0x24, 0x25,
-+ 0x3e, 0x25, 0x24, 0x25, 0x24, 0x4f, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xd8, 0xa8, 0xc8, 0x40, 0xb0,
-+ 0x4c, 0xa0, 0x48, 0x90, 0x60, 0x80, 0x00, 0x00,
-+ 0x00, 0x3b, 0x2a, 0x2a, 0x2b, 0x3a, 0x2b, 0x2b,
-+ 0x3b, 0x2a, 0x2b, 0x2a, 0x2b, 0x5a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x38, 0x28, 0xf8, 0x28, 0xe8, 0x78,
-+ 0xf8, 0x68, 0xb8, 0x58, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x27, 0x26, 0x3f, 0x27, 0x24,
-+ 0x3d, 0x24, 0x27, 0x24, 0x25, 0x4c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xfc, 0x48, 0x58, 0x58, 0x00,
-+ 0xf8, 0x08, 0xfc, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x26, 0x24, 0x3d, 0x27, 0x24,
-+ 0x3d, 0x24, 0x25, 0x24, 0x27, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa8, 0xa4, 0x1c, 0xf8, 0x90,
-+ 0xf8, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x26, 0x27, 0x3c, 0x24, 0x27,
-+ 0x3c, 0x25, 0x24, 0x24, 0x27, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x08, 0xfc, 0x50, 0x88, 0xf4,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x27, 0x25, 0x3d, 0x25, 0x25,
-+ 0x3f, 0x25, 0x25, 0x26, 0x25, 0x4c, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0xfc, 0x00, 0xf8, 0xa8, 0x48, 0xb0, 0x00, 0x00,
-+ 0x00, 0x38, 0x2f, 0x2b, 0x28, 0x3f, 0x2b, 0x2a,
-+ 0x3b, 0x2b, 0x2a, 0x2b, 0x29, 0x5a, 0x00, 0x00,
-+ 0x28, 0x24, 0xfc, 0xe0, 0x20, 0xe0, 0xe0, 0x50,
-+ 0xd0, 0xd4, 0x4c, 0xcc, 0x84, 0x44, 0x00, 0x00,
-+ 0x00, 0x3f, 0x25, 0x24, 0x27, 0x3c, 0x25, 0x26,
-+ 0x3d, 0x25, 0x25, 0x25, 0x25, 0x4d, 0x00, 0x00,
-+ 0x18, 0xe8, 0x48, 0xd0, 0xfc, 0xe0, 0x50, 0x4c,
-+ 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x24, 0x24, 0x3f, 0x25, 0x25,
-+ 0x3e, 0x24, 0x27, 0x24, 0x24, 0x4c, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0xd0, 0x40, 0xfc, 0x50, 0x50,
-+ 0xe8, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x26, 0x27, 0x3f, 0x26, 0x27,
-+ 0x3d, 0x25, 0x25, 0x25, 0x25, 0x4d, 0x00, 0x00,
-+ 0x40, 0xa0, 0xf0, 0x08, 0xfc, 0x58, 0xe8, 0xf8,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x02, 0x3d, 0x25, 0x24, 0x26, 0x3d, 0x25, 0x24,
-+ 0x3f, 0x25, 0x25, 0x25, 0x26, 0x4c, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x78, 0x90, 0xfc, 0x78, 0x48,
-+ 0x78, 0x48, 0x78, 0x48, 0xd8, 0x7c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x27, 0x25, 0x3d, 0x25, 0x25,
-+ 0x3d, 0x25, 0x25, 0x26, 0x26, 0x4c, 0x00, 0x00,
-+ 0x40, 0xf0, 0x20, 0xfc, 0x54, 0x8c, 0x70, 0xfc,
-+ 0x70, 0x70, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x3f, 0x3f, 0x2a, 0x3f, 0x52,
-+ 0x3f, 0x10, 0x1f, 0x1f, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x70, 0x54, 0x9c, 0xf8, 0x50, 0x30, 0xcc,
-+ 0xf0, 0x10, 0xf0, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3f, 0x3e, 0x32, 0x5e, 0x1f,
-+ 0x10, 0x1f, 0x10, 0x1f, 0x10, 0x10, 0x00, 0x00,
-+ 0x20, 0xf8, 0x50, 0xfc, 0x20, 0xf8, 0x20, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x12, 0x15, 0x1e, 0x14, 0x14,
-+ 0x13, 0x12, 0x13, 0x23, 0x22, 0x42, 0x00, 0x00,
-+ 0x80, 0xfc, 0x90, 0xfc, 0xf8, 0xf8, 0x90, 0xfc,
-+ 0xf0, 0x10, 0xf0, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x25, 0x27, 0x3c, 0x27, 0x26,
-+ 0x3e, 0x27, 0x25, 0x25, 0x26, 0x4c, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xb8, 0xa8,
-+ 0xa8, 0xb8, 0x10, 0x98, 0x64, 0x44, 0x00, 0x00,
-+ 0x00, 0x38, 0x2f, 0x28, 0x2f, 0x3a, 0x2b, 0x2c,
-+ 0x39, 0x29, 0x29, 0x29, 0x2a, 0x5c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa4, 0xf8, 0xe8, 0xf8, 0x44,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x3b, 0x28, 0x2b, 0x2a, 0x3f, 0x2b, 0x28,
-+ 0x3b, 0x28, 0x2b, 0x2a, 0x2a, 0x5a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xfc, 0x48, 0x58, 0x58, 0x40,
-+ 0xf8, 0x80, 0xf8, 0xa8, 0xa8, 0xb8, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x28, 0x29, 0x3f, 0x29, 0x29,
-+ 0x3b, 0x2d, 0x28, 0x2a, 0x2a, 0x5c, 0x00, 0x00,
-+ 0xa0, 0xfc, 0xa0, 0xe0, 0x10, 0xf4, 0xb8, 0xb0,
-+ 0xf4, 0xac, 0x00, 0xa8, 0x54, 0x54, 0x00, 0x00,
-+ 0x02, 0x3a, 0x2c, 0x2a, 0x2b, 0x3a, 0x2a, 0x2b,
-+ 0x3b, 0x2a, 0x2b, 0x2a, 0x2b, 0x5e, 0x00, 0x00,
-+ 0x48, 0x48, 0x90, 0x48, 0xf8, 0x68, 0xe8, 0xf8,
-+ 0x68, 0xd8, 0x68, 0xd8, 0x6c, 0xc4, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x25, 0x25, 0x3d, 0x25, 0x25,
-+ 0x3c, 0x27, 0x25, 0x25, 0x25, 0x4d, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xfc, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0xf8, 0x48, 0x68, 0x98, 0xf8, 0x30, 0x00, 0x00,
-+ 0x00, 0x38, 0x2b, 0x2a, 0x2b, 0x3a, 0x2a, 0x2a,
-+ 0x3a, 0x2a, 0x2b, 0x2b, 0x2d, 0x5b, 0x00, 0x00,
-+ 0x40, 0x78, 0xfc, 0x68, 0xb8, 0xf8, 0xa8, 0xf8,
-+ 0xa8, 0xf8, 0xf8, 0x68, 0x68, 0xfc, 0x00, 0x00,
-+ 0x01, 0x3f, 0x29, 0x28, 0x2d, 0x3d, 0x2f, 0x29,
-+ 0x3f, 0x2b, 0x2b, 0x2d, 0x2a, 0x5c, 0x00, 0x00,
-+ 0x10, 0xfc, 0x18, 0x14, 0xfc, 0x10, 0xf4, 0xd4,
-+ 0xf8, 0xb8, 0xf4, 0xdc, 0xec, 0x44, 0x00, 0x00,
-+ 0x13, 0x6f, 0x13, 0x2b, 0x7f, 0x3a, 0x57, 0x01,
-+ 0x3f, 0x22, 0x2d, 0x22, 0x2c, 0x20, 0x00, 0x00,
-+ 0x90, 0xe8, 0x90, 0xa8, 0xfc, 0xb8, 0xd4, 0x00,
-+ 0xf8, 0xc8, 0x28, 0xc8, 0x28, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x2f, 0x28, 0x2f, 0x3d, 0x2f, 0x0c,
-+ 0x7c, 0x2f, 0x2d, 0x57, 0x14, 0x20, 0x00, 0x00,
-+ 0x50, 0x48, 0xfc, 0x40, 0xc8, 0x48, 0xc8, 0xa8,
-+ 0xb0, 0xb0, 0x14, 0xf4, 0x4c, 0x84, 0x00, 0x00,
-+ 0x01, 0x1f, 0x0f, 0x0f, 0x08, 0x0f, 0x3f, 0x2f,
-+ 0x42, 0x1f, 0x0f, 0x01, 0x3f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0xe0, 0xe0, 0x20, 0xe0, 0xfc, 0xe8,
-+ 0x40, 0xf0, 0xe0, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x7c, 0x13, 0x18, 0x25, 0x7c, 0x13, 0x11,
-+ 0x7e, 0x13, 0x10, 0x1d, 0x62, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0xa0, 0xfc, 0x30,
-+ 0xc8, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x01, 0x05, 0x39, 0x21, 0x21, 0x3d, 0x21, 0x21,
-+ 0x3d, 0x21, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x00, 0x78, 0x08, 0x08, 0x78, 0x08, 0x08,
-+ 0x78, 0x88, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x02, 0x1c, 0x10, 0x1e, 0x10, 0x10, 0x1f, 0x12,
-+ 0x02, 0x7f, 0x02, 0x04, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0x10, 0xf0, 0x50,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x3f, 0x01, 0x1f, 0x02, 0x7f, 0x04, 0x1a,
-+ 0x6c, 0x08, 0x0e, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x80, 0xfc, 0x40, 0x30,
-+ 0xec, 0x20, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x02, 0x3c, 0x3e, 0x20, 0x3f, 0x1f, 0x11, 0x1f,
-+ 0x11, 0x1f, 0x7f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0xf8, 0xf8, 0x08, 0xf8, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0xf8, 0x08, 0x08, 0x70, 0x00, 0x00,
-+ 0x0a, 0x32, 0x23, 0x22, 0x3b, 0x20, 0x3a, 0x22,
-+ 0x22, 0x7f, 0x00, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0x38, 0x88, 0x08, 0xb8, 0x88, 0xb8, 0x88,
-+ 0x88, 0xfc, 0x00, 0x60, 0x18, 0x04, 0x00, 0x00,
-+ 0x04, 0x7f, 0x0c, 0x1f, 0x71, 0x1f, 0x1f, 0x1f,
-+ 0x02, 0x1c, 0x1e, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0xc0, 0xf8, 0x00, 0xe0, 0xe0, 0xf8,
-+ 0x00, 0xf0, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x02, 0x04, 0x18, 0x6f, 0x01, 0x01, 0x3f,
-+ 0x01, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0x30, 0xec, 0x00, 0x00, 0xf8,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x02, 0x04, 0x38, 0x08, 0x08, 0x7f, 0x08, 0x08,
-+ 0x3e, 0x22, 0x22, 0x22, 0x3e, 0x23, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0xa0, 0xa0, 0xa0, 0xfc, 0xa0,
-+ 0xa0, 0x90, 0x94, 0xac, 0xcc, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x12, 0x3f, 0x49, 0x09, 0x7f,
-+ 0x09, 0x3d, 0x25, 0x25, 0x3d, 0x25, 0x00, 0x00,
-+ 0x50, 0x48, 0xfc, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x04, 0x08, 0x1e, 0x12, 0x1a, 0x16, 0x17, 0x1f,
-+ 0x72, 0x1a, 0x1a, 0x2a, 0x23, 0x46, 0x00, 0x00,
-+ 0x70, 0x10, 0x50, 0x50, 0x88, 0x88, 0x24, 0x20,
-+ 0x20, 0x50, 0x48, 0x98, 0xe4, 0x04, 0x00, 0x00,
-+ 0x04, 0x08, 0x1e, 0x13, 0x1a, 0x16, 0x16, 0x1f,
-+ 0x72, 0x1a, 0x1a, 0x2a, 0x23, 0x46, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x40, 0x40, 0x78, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x04, 0x09, 0x1e, 0x12, 0x1a, 0x16, 0x16, 0x1f,
-+ 0x72, 0x1a, 0x1a, 0x2a, 0x22, 0x46, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0x08, 0xe8, 0xa8, 0xa8, 0xa8,
-+ 0xe8, 0xa8, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x04, 0x08, 0x1e, 0x12, 0x1a, 0x16, 0x16, 0x1f,
-+ 0x72, 0x1a, 0x1a, 0x2a, 0x22, 0x46, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xf8, 0xa8, 0xa8, 0xa8,
-+ 0xf8, 0xa8, 0xa8, 0xa8, 0xf8, 0x88, 0x00, 0x00,
-+ 0x04, 0x09, 0x1e, 0x12, 0x1b, 0x16, 0x17, 0x1e,
-+ 0x72, 0x1b, 0x1a, 0x2a, 0x22, 0x46, 0x00, 0x00,
-+ 0x0c, 0xf0, 0xa8, 0xa4, 0x24, 0x10, 0xf8, 0x10,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x04, 0x08, 0x1e, 0x12, 0x1b, 0x16, 0x16, 0x1e,
-+ 0x72, 0x1a, 0x1b, 0x2b, 0x22, 0x46, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0xf8, 0x04, 0xf8, 0xf8, 0x88,
-+ 0xf8, 0x80, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x10, 0x3d, 0x25, 0x35, 0x2d, 0x2d, 0x3f,
-+ 0x64, 0x37, 0x34, 0x34, 0x25, 0x4e, 0x00, 0x00,
-+ 0x40, 0xc0, 0x58, 0x48, 0xd8, 0x48, 0xd8, 0x48,
-+ 0x40, 0xf8, 0x90, 0x60, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x08, 0x11, 0x3c, 0x27, 0x36, 0x2d, 0x2d, 0x3e,
-+ 0x65, 0x34, 0x37, 0x34, 0x25, 0x4c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xfc, 0x48, 0xd8, 0xd8, 0x40,
-+ 0xf8, 0x08, 0xfc, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x13, 0x3c, 0x27, 0x36, 0x2f, 0x2e, 0x3f,
-+ 0x65, 0x35, 0x35, 0x35, 0x25, 0x4d, 0x00, 0x00,
-+ 0xa0, 0xfc, 0xa0, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x04, 0x08, 0x1e, 0x13, 0x1a, 0x16, 0x16, 0x1e,
-+ 0x72, 0x1a, 0x1a, 0x2a, 0x23, 0x46, 0x00, 0x00,
-+ 0x20, 0xf8, 0x50, 0xfc, 0xf8, 0xa8, 0xf8, 0xa8,
-+ 0xf8, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x09, 0x10, 0x3f, 0x24, 0x35, 0x2c, 0x2f, 0x3c,
-+ 0x65, 0x37, 0x34, 0x37, 0x24, 0x4d, 0x00, 0x00,
-+ 0x10, 0xa0, 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0x68,
-+ 0xa4, 0xfc, 0xe8, 0x94, 0xec, 0x84, 0x00, 0x00,
-+ 0x08, 0x10, 0x3f, 0x25, 0x35, 0x2e, 0x2f, 0x3c,
-+ 0x67, 0x36, 0x36, 0x36, 0x27, 0x4e, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x50, 0x50, 0xe8, 0xfc, 0x00,
-+ 0xf8, 0xe8, 0xa8, 0xe8, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x13, 0x3c, 0x27, 0x36, 0x2c, 0x2f, 0x3c,
-+ 0x67, 0x34, 0x37, 0x34, 0x27, 0x4c, 0x00, 0x00,
-+ 0x90, 0xfc, 0x90, 0xfc, 0xe8, 0x00, 0xfc, 0x48,
-+ 0xe8, 0xb0, 0x70, 0xa8, 0x24, 0xc0, 0x00, 0x00,
-+ 0x08, 0x10, 0x3f, 0x25, 0x35, 0x2d, 0x2d, 0x3d,
-+ 0x66, 0x35, 0x35, 0x35, 0x25, 0x4d, 0x00, 0x00,
-+ 0x40, 0xf0, 0x20, 0xf8, 0x48, 0xf8, 0xf8, 0xa8,
-+ 0x54, 0xf8, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x10, 0x3d, 0x25, 0x35, 0x2d, 0x2d, 0x3d,
-+ 0x65, 0x35, 0x35, 0x36, 0x26, 0x4d, 0x00, 0x00,
-+ 0x40, 0x78, 0xfc, 0x68, 0xb8, 0xf8, 0xa8, 0xf8,
-+ 0xa8, 0xf8, 0xf8, 0xe8, 0xe8, 0xfc, 0x00, 0x00,
-+ 0x04, 0x09, 0x1e, 0x12, 0x1a, 0x16, 0x16, 0x1f,
-+ 0x72, 0x1a, 0x1a, 0x2a, 0x23, 0x47, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8,
-+ 0x88, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
-+ 0x14, 0x7f, 0x14, 0x1c, 0x3e, 0x2a, 0x3e, 0x08,
-+ 0x3e, 0x08, 0x7e, 0x14, 0x22, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0xf8, 0xa4,
-+ 0xa4, 0xa8, 0x90, 0x90, 0xe8, 0x84, 0x00, 0x00,
-+ 0x5b, 0x7f, 0x5b, 0x7f, 0x7f, 0x5b, 0x7f, 0x00,
-+ 0x7f, 0x3e, 0x22, 0x3e, 0x16, 0x78, 0x00, 0x00,
-+ 0x40, 0x78, 0x90, 0x20, 0xf8, 0xa8, 0xa8, 0xa8,
-+ 0xf8, 0x88, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x3e, 0x2a, 0x08, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xf8, 0xa8, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x00, 0x08, 0x08, 0x04,
-+ 0x04, 0x02, 0x01, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x20, 0x20, 0x20, 0x40,
-+ 0x40, 0x80, 0x00, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x08, 0x1f, 0x10,
-+ 0x22, 0x41, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0x00, 0xf8, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x05, 0x01, 0x7f, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x0f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x00, 0xfc, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x00, 0x1f, 0x00, 0x7f,
-+ 0x04, 0x04, 0x04, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf0, 0x00, 0xfc,
-+ 0x80, 0x80, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x07, 0x04, 0x04, 0x08,
-+ 0x3f, 0x04, 0x02, 0x03, 0x0c, 0x70, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xc0, 0x48, 0x48, 0x38,
-+ 0xe0, 0x40, 0x80, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x08, 0x0f, 0x12, 0x72, 0x1f, 0x12, 0x0c, 0x38,
-+ 0x0f, 0x12, 0x72, 0x1f, 0x04, 0x38, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xc8, 0x48, 0x30, 0x00,
-+ 0xf8, 0x48, 0x48, 0xc8, 0x48, 0x30, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x07, 0x04, 0x08, 0x10,
-+ 0x7f, 0x02, 0x02, 0x04, 0x08, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xc0, 0x40, 0x20, 0x10,
-+ 0xec, 0x20, 0x20, 0x20, 0x20, 0xc0, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x04, 0x10, 0x12, 0x11,
-+ 0x11, 0x10, 0x10, 0x16, 0x18, 0x63, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x30, 0x28, 0xc4, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x1f, 0x10, 0x1f, 0x10,
-+ 0x10, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x00, 0xf0, 0x10,
-+ 0x10, 0xf0, 0x10, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x0f, 0x10, 0x2f,
-+ 0x48, 0x08, 0x0f, 0x08, 0x00, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x08, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x01, 0x1f, 0x11, 0x1f,
-+ 0x11, 0x11, 0x7f, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x10, 0x10, 0xfc, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x0f, 0x08, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x08, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xe0, 0x20, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x06, 0x03, 0x0c, 0x32, 0x03,
-+ 0x0e, 0x71, 0x01, 0x00, 0x01, 0x06, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xe0, 0x40, 0x80, 0x80,
-+ 0x60, 0x1c, 0x00, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x0f, 0x0a, 0x09, 0x7f,
-+ 0x12, 0x11, 0x11, 0x3f, 0x20, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xe0, 0x20, 0x20, 0xfc,
-+ 0x20, 0x20, 0x20, 0xf8, 0x40, 0x80, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x10, 0x1f, 0x20, 0x4f, 0x09,
-+ 0x08, 0x7f, 0x12, 0x11, 0x3f, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x00, 0xfc, 0x00, 0xe0, 0x20,
-+ 0xa0, 0xfc, 0x20, 0x20, 0xf8, 0xc0, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x10, 0x09, 0x49, 0x21,
-+ 0x21, 0x09, 0x11, 0x11, 0x21, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x08, 0x08,
-+ 0x08, 0x30, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x08, 0x17, 0x10,
-+ 0x31, 0x50, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x10, 0x10, 0xfc, 0x10,
-+ 0x10, 0x90, 0x90, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x3f, 0x09, 0x09, 0x11,
-+ 0x21, 0x7f, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x20, 0x10, 0x08,
-+ 0x08, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x0f, 0x10, 0x2f,
-+ 0x48, 0x0f, 0x08, 0x08, 0x08, 0x07, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x08, 0x88,
-+ 0x88, 0x88, 0xb0, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x06, 0x38, 0x24, 0x24,
-+ 0x24, 0x24, 0x3c, 0x64, 0x08, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0xf0, 0x80, 0x80, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x1f, 0x10, 0x10, 0x1f,
-+ 0x10, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x05, 0x01, 0x7f, 0x01,
-+ 0x3f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x00, 0xfc, 0x00,
-+ 0xf8, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x05, 0x01, 0x3f, 0x00,
-+ 0x08, 0x04, 0x04, 0x04, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x00, 0xf8, 0x20,
-+ 0x20, 0x40, 0x40, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x00, 0x3f, 0x21, 0x2f,
-+ 0x21, 0x22, 0x24, 0x28, 0x3f, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x08, 0xe8,
-+ 0x08, 0x88, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x00, 0x3f, 0x20, 0x27,
-+ 0x24, 0x24, 0x27, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x08, 0xc8,
-+ 0x48, 0x48, 0xc8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x01, 0x03, 0x3c, 0x03,
-+ 0x06, 0x7f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xe0, 0x40, 0x80,
-+ 0x60, 0xfc, 0x20, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x08, 0x32, 0x12,
-+ 0x0c, 0x04, 0x0c, 0x12, 0x7f, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x20, 0x20, 0xc8, 0x48,
-+ 0x30, 0x10, 0x30, 0x48, 0xf4, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x09, 0x09, 0x1f, 0x21,
-+ 0x7f, 0x03, 0x05, 0x19, 0x61, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0x00, 0xf0, 0x00,
-+ 0xfc, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x0f, 0x10, 0x2f,
-+ 0x48, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x08, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0x88, 0x30, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x08, 0x7e, 0x12,
-+ 0x12, 0x3a, 0x24, 0x06, 0x1a, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x88, 0x88,
-+ 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x01, 0x7f, 0x02, 0x0f,
-+ 0x08, 0x18, 0x6f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xfc, 0x00, 0xf0,
-+ 0x20, 0x40, 0xfc, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x02, 0x04, 0x18, 0x6f,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x80, 0x40, 0x30, 0xec,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x08, 0x10, 0x17,
-+ 0x30, 0x50, 0x10, 0x10, 0x13, 0x1c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x50, 0x48, 0x40, 0xfc,
-+ 0x40, 0x60, 0xa0, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x10, 0x08, 0x4b, 0x22,
-+ 0x22, 0x0a, 0x12, 0x12, 0x21, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0xfc, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x01, 0x03, 0x0e, 0x31,
-+ 0x01, 0x0f, 0x74, 0x04, 0x07, 0x04, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf0, 0x20, 0x40,
-+ 0x80, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x1f, 0x01, 0x06, 0x18,
-+ 0x00, 0x7f, 0x12, 0x12, 0x22, 0x4d, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf0, 0x10, 0x10, 0x60,
-+ 0x00, 0xf8, 0x48, 0x48, 0x88, 0x30, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x08, 0x17, 0x10,
-+ 0x32, 0x51, 0x11, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x80, 0x80, 0xf8, 0x10,
-+ 0x10, 0x20, 0x20, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x78, 0x0b, 0x10, 0x3a,
-+ 0x0a, 0x4a, 0x32, 0x11, 0x2c, 0x43, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x18, 0xe0, 0x40, 0x40,
-+ 0x78, 0x40, 0x40, 0xf8, 0x00, 0xfc, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x06, 0x38, 0x08, 0x7f,
-+ 0x08, 0x0e, 0x78, 0x08, 0x0b, 0x18, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x50, 0x48, 0x40, 0xfc,
-+ 0x48, 0x30, 0x20, 0xd4, 0x0c, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x02, 0x04, 0x1f, 0x60,
-+ 0x1f, 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x80, 0x40, 0xf0, 0x0c,
-+ 0xe0, 0x40, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x01, 0x7f, 0x09, 0x09,
-+ 0x15, 0x23, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xfc, 0x20, 0x30,
-+ 0x48, 0x88, 0x80, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x7f, 0x08, 0x11, 0x33,
-+ 0x08, 0x3f, 0x01, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xfc, 0x88, 0x10, 0x30,
-+ 0x88, 0xf8, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x13, 0x12, 0x13, 0x10,
-+ 0x1f, 0x01, 0x7f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf0, 0x10, 0xf0, 0x00,
-+ 0xf0, 0x10, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x10, 0x09, 0x49, 0x22,
-+ 0x22, 0x0c, 0x10, 0x10, 0x21, 0x26, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x50, 0x48, 0x44,
-+ 0x4c, 0xd0, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x3c, 0x24, 0x25, 0x3c,
-+ 0x24, 0x3c, 0x24, 0x26, 0x39, 0x62, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0xf8, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x24, 0x24, 0x3c, 0x27,
-+ 0x04, 0x7c, 0x14, 0x14, 0x27, 0x44, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0xfc,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x02, 0x04, 0x1f, 0x61,
-+ 0x1f, 0x01, 0x05, 0x19, 0x61, 0x03, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x80, 0x40, 0xf0, 0x0c,
-+ 0xf0, 0x00, 0x40, 0x30, 0x08, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x02, 0x1f, 0x11, 0x11,
-+ 0x1f, 0x11, 0x03, 0x05, 0x19, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf0, 0x10, 0x10,
-+ 0xf0, 0x10, 0x40, 0x24, 0x24, 0xfc, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x3f, 0x00, 0x0f, 0x08,
-+ 0x08, 0x0f, 0x04, 0x02, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x00, 0xe0, 0x20,
-+ 0x20, 0xe0, 0x40, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x3f, 0x02, 0x0e, 0x05,
-+ 0x18, 0x61, 0x24, 0x24, 0x44, 0x03, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf0, 0x10, 0x10, 0x90,
-+ 0x60, 0x00, 0x88, 0x84, 0x24, 0xe0, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x1f, 0x01, 0x7f, 0x05,
-+ 0x19, 0x6f, 0x02, 0x02, 0x0c, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x70, 0xc0, 0x00, 0xfc, 0x40,
-+ 0x30, 0xcc, 0x40, 0x70, 0x10, 0xe0, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x06, 0x38, 0x08, 0x7f,
-+ 0x1c, 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x08, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0x48, 0x08, 0x18, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x01, 0x1f, 0x10, 0x1f,
-+ 0x10, 0x1f, 0x11, 0x10, 0x1e, 0x70, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf8, 0x10, 0xa0, 0x60, 0x1c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x01, 0x7f, 0x05, 0x1f,
-+ 0x69, 0x0f, 0x09, 0x0f, 0x09, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xfc, 0x40, 0xf0,
-+ 0x2c, 0xe0, 0x20, 0xe8, 0x08, 0xf8, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x3f, 0x20, 0x4f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xfc, 0x08, 0xe0, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x7f, 0x1f, 0x11, 0x1f, 0x01,
-+ 0x3f, 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xfc, 0xf0, 0x10, 0xf0, 0x00,
-+ 0xf8, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x1f, 0x10, 0x1f, 0x10,
-+ 0x1f, 0x10, 0x1e, 0x10, 0x1e, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x98, 0xe0, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x0e, 0x08, 0x7f,
-+ 0x08, 0x2c, 0x2a, 0x2a, 0x48, 0x19, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x48, 0x48,
-+ 0x50, 0x30, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x01, 0x3f, 0x04, 0x0a,
-+ 0x31, 0x01, 0x7f, 0x01, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x20, 0x50,
-+ 0x88, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x08, 0x7e, 0x08,
-+ 0x1d, 0x1a, 0x2a, 0x48, 0x0b, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x70, 0x10, 0x90, 0x88,
-+ 0x44, 0x40, 0x50, 0x88, 0xfc, 0x04, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x3f, 0x1f, 0x01, 0x7f, 0x01,
-+ 0x1f, 0x7f, 0x04, 0x0f, 0x03, 0x3c, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0xe0, 0x20, 0xfc, 0x20,
-+ 0xe0, 0xfc, 0x40, 0xc0, 0x60, 0x10, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x3f, 0x01, 0x1f, 0x01, 0x7f,
-+ 0x1f, 0x11, 0x1f, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x00, 0xf0, 0x00, 0xfc,
-+ 0xf0, 0x10, 0xf0, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0f, 0x00, 0x7f, 0x00, 0x0f,
-+ 0x3f, 0x21, 0x5f, 0x11, 0x11, 0x01, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xe0, 0x20, 0xfc, 0x20, 0xe0,
-+ 0xfc, 0x08, 0xf0, 0x10, 0x30, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0f, 0x08, 0x0f, 0x08, 0x0f,
-+ 0x08, 0x7f, 0x09, 0x08, 0x0e, 0x30, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x00, 0xe0, 0x00, 0xe0,
-+ 0x00, 0xfc, 0x10, 0xa0, 0x60, 0x1c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x10, 0x0b, 0x4a, 0x22,
-+ 0x23, 0x0a, 0x12, 0x12, 0x24, 0x2b, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0xfc, 0x48, 0x50,
-+ 0xf8, 0x88, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x02, 0x02, 0x3e, 0x02,
-+ 0x3e, 0x03, 0x7e, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x80, 0x80, 0xf8, 0x80,
-+ 0xf8, 0x80, 0xfc, 0x80, 0x80, 0x80, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x13, 0x09, 0x49, 0x22,
-+ 0x20, 0x0f, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x50, 0x48, 0x48,
-+ 0x40, 0xfc, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x11, 0x09, 0x4a, 0x27,
-+ 0x20, 0x0b, 0x12, 0x12, 0x22, 0x21, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x08, 0xc8,
-+ 0x48, 0xc8, 0x70, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x1e, 0x12, 0x1a, 0x16,
-+ 0x12, 0x1a, 0x16, 0x12, 0x22, 0x47, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x78, 0x48, 0x68, 0x58,
-+ 0x48, 0x68, 0x58, 0x48, 0x88, 0x18, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x01, 0x7f, 0x02, 0x04,
-+ 0x1c, 0x64, 0x3f, 0x04, 0x08, 0x30, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xfc, 0x80, 0x40,
-+ 0x70, 0x4c, 0xf8, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x05, 0x19, 0x11, 0x1d,
-+ 0x11, 0x1d, 0x12, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0x70, 0x10, 0x70,
-+ 0x10, 0x70, 0x90, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x10, 0x0b, 0x48, 0x27, 0x21,
-+ 0x16, 0x11, 0x23, 0x24, 0x41, 0x4e, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x40, 0xfc, 0x24,
-+ 0x9c, 0xf0, 0x20, 0xc0, 0xb0, 0x0c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x08, 0x7f, 0x08,
-+ 0x1c, 0x1a, 0x2a, 0x49, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x20, 0x20, 0xfc, 0x20,
-+ 0x70, 0x70, 0xa8, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x3e, 0x22, 0x3e, 0x20,
-+ 0x3e, 0x20, 0x3e, 0x20, 0x20, 0x23, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x08, 0xf8, 0x00,
-+ 0xf8, 0x88, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x06, 0x38, 0x08, 0x7e,
-+ 0x1c, 0x1a, 0x2a, 0x48, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x48, 0x28, 0x28, 0x88,
-+ 0x48, 0x4c, 0x38, 0xc8, 0x08, 0x08, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x1e, 0x12, 0x1e, 0x00, 0x1f,
-+ 0x00, 0x7f, 0x04, 0x07, 0x08, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x90, 0xf0, 0x00, 0xf0,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xe0, 0x00, 0x00,
-+ 0x04, 0x7f, 0x0f, 0x08, 0x0f, 0x3e, 0x22, 0x3e,
-+ 0x0f, 0x7f, 0x08, 0x0f, 0x10, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0xe0, 0x20, 0xe0, 0xf8, 0x88, 0xf8,
-+ 0xe0, 0xfc, 0x00, 0xf0, 0x10, 0xe0, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x3f, 0x20, 0x5e, 0x01,
-+ 0x7e, 0x14, 0x14, 0x14, 0x24, 0x43, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xfc, 0x18, 0x10, 0xfc,
-+ 0x90, 0x50, 0x50, 0x14, 0x34, 0xfc, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3f, 0x21, 0x7f, 0x0f, 0x09,
-+ 0x0f, 0x09, 0x0f, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xfc, 0x08, 0xf8, 0xe0, 0x20,
-+ 0xe0, 0x20, 0xe0, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x08, 0x7f, 0x08,
-+ 0x08, 0x3e, 0x22, 0x22, 0x3e, 0x23, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0x78, 0x48, 0x48,
-+ 0x78, 0x48, 0x78, 0x88, 0x88, 0x18, 0x00, 0x00,
-+ 0x04, 0x7f, 0x06, 0x1f, 0x72, 0x1f, 0x0c, 0x34,
-+ 0x0f, 0x12, 0x72, 0x1f, 0x0c, 0x70, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xc8, 0x48, 0x30,
-+ 0xf8, 0x48, 0x48, 0xc8, 0x48, 0x38, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x06, 0x1c, 0x10, 0x1e, 0x11,
-+ 0x1f, 0x10, 0x1e, 0x70, 0x10, 0x13, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf0, 0x94, 0x94, 0x0c,
-+ 0xf8, 0x88, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x01, 0x3f, 0x04, 0x3f,
-+ 0x21, 0x4f, 0x09, 0x09, 0x09, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x40, 0xfc,
-+ 0x08, 0xe0, 0x20, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x11, 0x3d, 0x25,
-+ 0x25, 0x3d, 0x25, 0x25, 0x3d, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x48, 0x48,
-+ 0xf8, 0x08, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x09, 0x09, 0x11, 0x10,
-+ 0x37, 0x50, 0x11, 0x16, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf0, 0x10, 0xf0, 0x40,
-+ 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x40, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0f, 0x09, 0x0f, 0x09, 0x0f,
-+ 0x01, 0x3f, 0x21, 0x21, 0x2e, 0x20, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xe0, 0x20, 0xe0, 0x20, 0xe0,
-+ 0x00, 0xf8, 0x48, 0xe8, 0x28, 0x18, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x10, 0x14, 0x64, 0x19,
-+ 0x16, 0x7e, 0x2c, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x80, 0x80, 0xf8, 0x08,
-+ 0x88, 0x48, 0x48, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x08, 0x7f, 0x08,
-+ 0x0e, 0x13, 0x12, 0x22, 0x42, 0x0c, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x80, 0xfc, 0x20, 0xb8,
-+ 0xe8, 0xa8, 0xb8, 0xa4, 0x84, 0x7c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0f, 0x08, 0x09, 0x09, 0x3f,
-+ 0x20, 0x27, 0x24, 0x27, 0x24, 0x20, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xe0, 0x20, 0xe0, 0x20, 0xf8,
-+ 0x08, 0xc8, 0x48, 0xc8, 0x48, 0x18, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x05, 0x19, 0x62, 0x1f, 0x00,
-+ 0x3e, 0x0a, 0x36, 0x0a, 0x32, 0x06, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xc0, 0x30, 0x4c, 0xe0, 0x00,
-+ 0xf8, 0x28, 0xd8, 0x28, 0xc8, 0x18, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x01, 0x3f, 0x04, 0x19,
-+ 0x60, 0x1f, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x40, 0x30,
-+ 0x8c, 0xf0, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x06, 0x0c, 0x7f, 0x1f, 0x02, 0x7f,
-+ 0x02, 0x1f, 0x06, 0x1a, 0x62, 0x02, 0x00, 0x00,
-+ 0x40, 0xfc, 0x60, 0xc0, 0xfc, 0xf0, 0x90, 0xfc,
-+ 0x90, 0xf0, 0xc0, 0xb0, 0x8c, 0x80, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x01, 0x7f, 0x0f, 0x08, 0x0f,
-+ 0x3f, 0x20, 0x27, 0x24, 0x27, 0x20, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x00, 0xfc, 0xe0, 0x20, 0xe0,
-+ 0xf8, 0x08, 0xc8, 0x48, 0xc8, 0x18, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x08, 0x7f, 0x06,
-+ 0x24, 0x14, 0x18, 0x1e, 0x70, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xc0, 0x80, 0xf8, 0x08, 0xe8,
-+ 0xa8, 0xa8, 0xe8, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x05, 0x01, 0x3f, 0x25, 0x25,
-+ 0x2b, 0x31, 0x2f, 0x21, 0x5f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x20, 0x20,
-+ 0x50, 0x88, 0xf0, 0x00, 0xf8, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x1f, 0x01, 0x7f, 0x07, 0x1e,
-+ 0x63, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x00, 0x00,
-+ 0x40, 0xfc, 0x50, 0xe0, 0x40, 0xfc, 0xe0, 0x08,
-+ 0xf8, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x3e, 0x02, 0x3e, 0x20,
-+ 0x3e, 0x0a, 0x36, 0x0a, 0x32, 0x06, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x08, 0xf8, 0x80,
-+ 0xf8, 0x28, 0xd8, 0x28, 0xc8, 0x18, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0c, 0x08, 0x15, 0x16, 0x34,
-+ 0x57, 0x14, 0x14, 0x14, 0x14, 0x11, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xc0, 0xfc, 0x90, 0x60, 0xd0,
-+ 0x2c, 0xc0, 0x30, 0xc8, 0x30, 0xc0, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x1f, 0x17, 0x10, 0x1f, 0x12,
-+ 0x13, 0x1e, 0x3f, 0x22, 0x41, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xfc, 0xf0, 0x00, 0xfc, 0x48,
-+ 0xb0, 0x2c, 0xfc, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x3f, 0x01, 0x1f, 0x7f, 0x04,
-+ 0x1f, 0x6f, 0x03, 0x0d, 0x31, 0x01, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x00, 0xf0, 0xfc, 0xc0,
-+ 0x30, 0xec, 0xc0, 0x30, 0x08, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3f, 0x22, 0x3f, 0x22, 0x23,
-+ 0x20, 0x2f, 0x28, 0x28, 0x48, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0xc0, 0xfc, 0x20, 0xfc, 0x20, 0xe0,
-+ 0x80, 0xf8, 0x88, 0x88, 0xb0, 0x80, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x01, 0x1f, 0x12, 0x11, 0x16,
-+ 0x1f, 0x10, 0x1e, 0x10, 0x1e, 0x70, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x00, 0xf0, 0x50, 0x90, 0x50,
-+ 0xf0, 0x98, 0xe0, 0x80, 0x84, 0x7c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x01, 0x3f, 0x04, 0x3f, 0x21,
-+ 0x7f, 0x01, 0x01, 0x02, 0x0c, 0x30, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x40, 0xfc, 0x08,
-+ 0xf8, 0x00, 0xf0, 0x10, 0x10, 0x60, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0f, 0x19, 0x66, 0x14, 0x1f,
-+ 0x60, 0x1f, 0x01, 0x09, 0x31, 0x03, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x78, 0x90, 0x60, 0x30, 0xcc,
-+ 0x00, 0xf0, 0x00, 0x30, 0x08, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x01, 0x3f, 0x28, 0x4f, 0x10,
-+ 0x13, 0x32, 0x53, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x00, 0xfc, 0x08, 0xf8, 0x80,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x7f, 0x1f, 0x11, 0x1f, 0x1f,
-+ 0x01, 0x3f, 0x00, 0x7f, 0x04, 0x02, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xfc, 0xf0, 0x10, 0xf0, 0xf0,
-+ 0x10, 0xf8, 0x20, 0xfc, 0x20, 0x60, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x01, 0x1f, 0x12, 0x12, 0x1f,
-+ 0x12, 0x12, 0x1f, 0x20, 0x2a, 0x51, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x00, 0xf8, 0x40, 0x40, 0xf0,
-+ 0x40, 0x40, 0xf8, 0x00, 0x48, 0x24, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x02, 0x17, 0x29, 0x7e, 0x04,
-+ 0x19, 0x6e, 0x01, 0x0e, 0x01, 0x1e, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x80, 0xd0, 0x28, 0xfc, 0x40,
-+ 0xb0, 0x4c, 0x90, 0x60, 0x80, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x00, 0x7f, 0x0a, 0x0c, 0x29,
-+ 0x2e, 0x29, 0x29, 0x2d, 0x3a, 0x64, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x20, 0xfc, 0x20, 0x48, 0xfc,
-+ 0x00, 0x50, 0x50, 0x54, 0x54, 0x0c, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x08, 0x09, 0x7e, 0x08,
-+ 0x0f, 0x13, 0x12, 0x22, 0x42, 0x0d, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xc0, 0x80, 0xfc, 0x80, 0xf8,
-+ 0x20, 0xfc, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0a, 0x7f, 0x0a, 0x33, 0x3f,
-+ 0x21, 0x5f, 0x11, 0x11, 0x11, 0x01, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xa0, 0xfc, 0xa4, 0x9c, 0xfc,
-+ 0x08, 0xf0, 0x10, 0x10, 0x60, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x14, 0x1f, 0x10, 0x3f, 0x4f, 0x08,
-+ 0x0f, 0x1f, 0x1f, 0x12, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x08, 0xe8, 0x88, 0x88,
-+ 0x88, 0xc8, 0xc8, 0x48, 0xc8, 0x30, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3e, 0x0a, 0x36, 0x0b, 0x32,
-+ 0x0d, 0x76, 0x01, 0x0e, 0x01, 0x1e, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x28, 0xd8, 0x28, 0xc8,
-+ 0x60, 0x5c, 0xa0, 0x40, 0x80, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x08, 0x7f, 0x08, 0x3e, 0x2a,
-+ 0x2a, 0x2e, 0x1c, 0x2a, 0x49, 0x08, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x20, 0xfc, 0x20, 0xf8, 0xa8,
-+ 0xa8, 0xb8, 0x70, 0xa8, 0x24, 0x20, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3f, 0x12, 0x09, 0x3f, 0x28,
-+ 0x4e, 0x12, 0x2a, 0x05, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0xfc, 0x70, 0x90, 0x20, 0x40, 0xfc, 0x28,
-+ 0xf8, 0xa0, 0xa0, 0xfc, 0x20, 0x20, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x1f, 0x01, 0x7f, 0x08, 0x3e,
-+ 0x0e, 0x71, 0x3f, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x00, 0xfc, 0x20, 0xf8,
-+ 0x20, 0xfc, 0xf8, 0x80, 0x84, 0x7c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x7f, 0x1f, 0x12, 0x1f, 0x0f,
-+ 0x0f, 0x08, 0x0f, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xfc, 0xf0, 0x90, 0xf0, 0xe0,
-+ 0xe0, 0x20, 0xe0, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x1f, 0x00, 0x7f, 0x1f, 0x3e,
-+ 0x08, 0x3e, 0x7f, 0x08, 0x04, 0x00, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x10, 0xfc, 0xf0, 0xf8,
-+ 0x88, 0xf8, 0xfc, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x14, 0x14, 0x23, 0x1a, 0x35,
-+ 0x55, 0x0d, 0x7f, 0x05, 0x19, 0x61, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xb0, 0x48, 0xc0, 0x68, 0xd4,
-+ 0x54, 0x30, 0xfc, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x09, 0x09, 0x09, 0x3f, 0x08,
-+ 0x08, 0x2e, 0x28, 0x2e, 0x39, 0x60, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x00, 0xf0, 0x00, 0xf8, 0x20,
-+ 0xa0, 0xb8, 0xa0, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x08, 0x69, 0x13, 0x14, 0x2b,
-+ 0x4a, 0x1b, 0x2b, 0x4a, 0x0b, 0x32, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x10, 0xf8, 0xa4, 0xf8,
-+ 0xa8, 0x38, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x13, 0x0a, 0x4a, 0x23, 0x23,
-+ 0x10, 0x17, 0x25, 0x25, 0x4f, 0x40, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x90, 0xd0, 0x30, 0xf0,
-+ 0x00, 0xf8, 0x28, 0x28, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x7e, 0x10, 0x1f, 0x14,
-+ 0x27, 0x58, 0x0b, 0x10, 0x27, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xa0, 0xa0, 0xb8, 0xa0,
-+ 0xb8, 0xa0, 0xb8, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x7f, 0x09, 0x06, 0x1f, 0x7f, 0x19, 0x15,
-+ 0x1f, 0x0f, 0x08, 0x0f, 0x08, 0x0f, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xc0, 0xf0, 0xfc, 0x30, 0x50,
-+ 0xf0, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x7f, 0x1f, 0x1f, 0x11, 0x1f,
-+ 0x7f, 0x1f, 0x1f, 0x11, 0x1f, 0x7f, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xfc, 0xf0, 0xf0, 0x10, 0xf0,
-+ 0xfc, 0xf0, 0xf0, 0x10, 0xf0, 0xfc, 0x00, 0x00,
-+ 0x04, 0x7f, 0x0c, 0x0f, 0x12, 0x3f, 0x55, 0x1f,
-+ 0x15, 0x1f, 0x15, 0x2a, 0x2a, 0x40, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x08, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x48, 0xc8, 0x88, 0x18, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x1f, 0x12, 0x1f, 0x3f, 0x20,
-+ 0x7f, 0x1e, 0x72, 0x0c, 0x18, 0x60, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x90, 0xf0, 0xfc, 0x08,
-+ 0xf8, 0x98, 0xe0, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x1f, 0x01, 0x7f, 0x1f, 0x15,
-+ 0x1d, 0x1f, 0x11, 0x1d, 0x25, 0x45, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x10, 0xfc, 0xf0, 0x50,
-+ 0x70, 0xf0, 0x10, 0x70, 0x50, 0x50, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x3f, 0x09, 0x0d, 0x13, 0x7f,
-+ 0x1f, 0x17, 0x14, 0x17, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x20, 0x30, 0x48, 0xfc,
-+ 0xf0, 0xd0, 0x50, 0xd0, 0xf0, 0x10, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x0c, 0x10, 0x3d, 0x24, 0x3c,
-+ 0x21, 0x3c, 0x25, 0x24, 0x3c, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x60, 0x20, 0xfc, 0x88, 0x50,
-+ 0xfc, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x1f, 0x15, 0x7f, 0x1f, 0x1f,
-+ 0x15, 0x1f, 0x7f, 0x1a, 0x06, 0x39, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x20, 0x20, 0xfc, 0x48, 0xc8,
-+ 0x28, 0x30, 0x90, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x22, 0x2a, 0x4a, 0x1f, 0x10,
-+ 0x2f, 0x60, 0x27, 0x25, 0x29, 0x30, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x20, 0xa0, 0xa0, 0xfc, 0x48,
-+ 0xa8, 0x30, 0x10, 0xb0, 0x48, 0x84, 0x00, 0x00,
-+ 0x04, 0x04, 0x7f, 0x04, 0x3c, 0x25, 0x24, 0x3c,
-+ 0x21, 0x3c, 0x65, 0x24, 0x3c, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x60, 0x20, 0xfc, 0x88, 0x50,
-+ 0xfc, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3f, 0x14, 0x08, 0x7f, 0x0a,
-+ 0x0c, 0x08, 0x08, 0x08, 0x08, 0x19, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xfc, 0x20, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x88, 0xf8, 0x58, 0x84, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3f, 0x01, 0x3f, 0x2d, 0x4d,
-+ 0x1f, 0x11, 0x1f, 0x11, 0x1f, 0x10, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x00, 0xfc, 0x68, 0x60,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x06, 0x39, 0x08, 0x7f, 0x08,
-+ 0x1d, 0x1a, 0x29, 0x48, 0x08, 0x0b, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x40, 0xfc, 0xa4,
-+ 0x5c, 0x70, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x0c, 0x0e, 0x78, 0x08, 0x3f, 0x08,
-+ 0x7e, 0x1c, 0x1a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x40, 0xfc, 0x50, 0x50, 0xf8, 0x50, 0xfc, 0x00,
-+ 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x7f, 0x02, 0x7d, 0x15, 0x2d,
-+ 0x49, 0x0f, 0x08, 0x0f, 0x10, 0x20, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xfc, 0x88, 0x70, 0x50, 0xf8,
-+ 0x24, 0xe0, 0x20, 0xe0, 0x20, 0x20, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x00, 0x2f, 0x28, 0x3f, 0x0d,
-+ 0x7f, 0x2c, 0x2f, 0x55, 0x17, 0x24, 0x00, 0x00,
-+ 0x40, 0xfc, 0x50, 0x48, 0xfc, 0x40, 0xc8, 0x48,
-+ 0xa8, 0xb0, 0x90, 0x34, 0xcc, 0x84, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x3f, 0x1f, 0x08, 0x0f, 0x3f,
-+ 0x2f, 0x42, 0x0f, 0x1f, 0x01, 0x3f, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0xf0, 0x20, 0xe0, 0xfc,
-+ 0xe8, 0x40, 0xf0, 0xf0, 0x00, 0xf8, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x0e, 0x73, 0x55, 0x29, 0x19,
-+ 0x6d, 0x14, 0x6c, 0x14, 0x65, 0x1a, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x80, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0xa0, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x0c, 0x0b, 0x7c, 0x08, 0x3e, 0x08,
-+ 0x7e, 0x1d, 0x1b, 0x2b, 0x49, 0x09, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8,
-+ 0x20, 0xfc, 0x34, 0xfc, 0x04, 0x0c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x0c, 0x3e, 0x7f, 0x2d, 0x5f, 0x0e,
-+ 0x39, 0x1f, 0x7f, 0x02, 0x07, 0x38, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0x50, 0xd0, 0x74, 0x94,
-+ 0x0c, 0xf0, 0xfc, 0x20, 0xf0, 0x08, 0x00, 0x00,
-+ 0x04, 0x7f, 0x15, 0x6b, 0x2a, 0x13, 0x2a, 0x7f,
-+ 0x01, 0x7f, 0x03, 0x0d, 0x71, 0x01, 0x00, 0x00,
-+ 0x40, 0xfc, 0x50, 0xe8, 0xa8, 0x90, 0xa8, 0xfc,
-+ 0x00, 0xfc, 0x80, 0x60, 0x1c, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x06, 0x38, 0x09, 0x7e, 0x1d, 0x6a,
-+ 0x0e, 0x19, 0x65, 0x07, 0x39, 0x03, 0x00, 0x00,
-+ 0x40, 0xfc, 0xc0, 0xf8, 0x28, 0x48, 0x88, 0xb0,
-+ 0x40, 0x30, 0x4c, 0xc0, 0x38, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3c, 0x00, 0x7e, 0x00, 0x3c,
-+ 0x3c, 0x01, 0x3f, 0x25, 0x3d, 0x21, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8,
-+ 0xfc, 0x44, 0x64, 0x94, 0xf4, 0x18, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x11, 0x15, 0x65, 0x19, 0x15,
-+ 0x7e, 0x09, 0x2d, 0x2b, 0x4b, 0x08, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0x68, 0x98, 0xf8,
-+ 0x00, 0xf8, 0x68, 0x68, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x06, 0x38, 0x09, 0x7e, 0x08,
-+ 0x1c, 0x1a, 0x2a, 0x49, 0x09, 0x0a, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0x70, 0xa0, 0xf8, 0xa8, 0xf8,
-+ 0xa8, 0xf8, 0x00, 0xa8, 0x54, 0x54, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x09, 0x28, 0x2e, 0x28, 0x7f,
-+ 0x28, 0x2a, 0x5a, 0x04, 0x18, 0x63, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xfc, 0x20, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x04, 0x00, 0x00,
-+ 0x04, 0x7f, 0x0c, 0x09, 0x7e, 0x08, 0x3f, 0x2a,
-+ 0x3e, 0x1c, 0x1a, 0x2a, 0x48, 0x09, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0x98, 0xf8, 0x88,
-+ 0xf8, 0xf8, 0x88, 0xf8, 0x58, 0x84, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3e, 0x22, 0x3e, 0x3e, 0x24,
-+ 0x27, 0x2f, 0x37, 0x24, 0x27, 0x24, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x88, 0xf8, 0xf8, 0x88,
-+ 0xe8, 0xc8, 0xc8, 0x88, 0xe8, 0x18, 0x00, 0x00,
-+ 0x04, 0x7f, 0x05, 0x01, 0x1f, 0x11, 0x1e, 0x17,
-+ 0x14, 0x17, 0x17, 0x2f, 0x29, 0x5f, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0xfc, 0xc8, 0xf8, 0xf0,
-+ 0x90, 0xf0, 0xf0, 0xf8, 0x48, 0xfc, 0x00, 0x00,
-+ 0x04, 0x7f, 0x0c, 0x3e, 0x14, 0x7e, 0x00, 0x3c,
-+ 0x24, 0x3c, 0x24, 0x3c, 0x24, 0x2c, 0x00, 0x00,
-+ 0x40, 0xfc, 0xc0, 0xfc, 0xf8, 0x08, 0xf8, 0x80,
-+ 0xf8, 0xf8, 0x80, 0xfc, 0x84, 0x7c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x0c, 0x0f, 0x12, 0x3f, 0x55, 0x1f,
-+ 0x15, 0x1f, 0x16, 0x2b, 0x2b, 0x40, 0x00, 0x00,
-+ 0x40, 0xfc, 0xc8, 0x48, 0x50, 0xfc, 0x20, 0xf8,
-+ 0x20, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x04, 0x7f, 0x0c, 0x0a, 0x72, 0x14, 0x0d, 0x13,
-+ 0x7f, 0x0d, 0x2a, 0x2a, 0x48, 0x0b, 0x00, 0x00,
-+ 0x40, 0xfc, 0xf8, 0x88, 0xf8, 0xf8, 0xfc, 0x54,
-+ 0xfc, 0xf8, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x04, 0x7f, 0x04, 0x3f, 0x24, 0x3f, 0x14, 0x74,
-+ 0x1b, 0x7e, 0x2c, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x90, 0xfc,
-+ 0x90, 0xf8, 0xf8, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x1f, 0x11, 0x11, 0x11, 0x11,
-+ 0x1f, 0x11, 0x11, 0x21, 0x21, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0x08, 0x10, 0x1c, 0xe0,
-+ 0x00, 0x00, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x1f, 0x10, 0x17,
-+ 0x14, 0x14, 0x24, 0x24, 0x40, 0x00, 0x00, 0x00,
-+ 0x78, 0x80, 0x80, 0xfc, 0x80, 0xfc, 0x80, 0xf8,
-+ 0x88, 0x88, 0x88, 0xb0, 0x80, 0x80, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x1f, 0x11, 0x1f, 0x10, 0x10,
-+ 0x1f, 0x12, 0x11, 0x20, 0x23, 0x5c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0xe8, 0x08, 0xf8, 0x80,
-+ 0xfc, 0x20, 0x40, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x25, 0x3d, 0x01, 0x7f, 0x11,
-+ 0x1d, 0x25, 0x05, 0x0a, 0x0a, 0x35, 0x00, 0x00,
-+ 0x40, 0x78, 0x40, 0xfc, 0x48, 0x70, 0xc4, 0x3c,
-+ 0x50, 0x50, 0x50, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x08, 0x0f, 0x3f, 0x2f, 0x39, 0x27, 0x2a, 0x2f,
-+ 0x3a, 0x2f, 0x2f, 0x2a, 0x4f, 0x08, 0x00, 0x00,
-+ 0x00, 0x78, 0xa0, 0x20, 0x20, 0xfc, 0x40, 0xc0,
-+ 0x78, 0x48, 0x08, 0x08, 0x88, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x03, 0x3c, 0x04, 0x3f, 0x24,
-+ 0x24, 0x3f, 0x25, 0x04, 0x07, 0x78, 0x00, 0x00,
-+ 0x00, 0xe0, 0xa0, 0x20, 0x20, 0x20, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0x14, 0x94, 0x4c, 0x44, 0x00, 0x00,
-+ 0x10, 0x11, 0x10, 0x7c, 0x55, 0x55, 0x55, 0x7d,
-+ 0x55, 0x18, 0x14, 0x1e, 0x62, 0x01, 0x00, 0x00,
-+ 0x08, 0xe8, 0x28, 0x28, 0xe8, 0x08, 0x08, 0xe8,
-+ 0x28, 0x28, 0x28, 0x28, 0x28, 0xc8, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2a, 0x2b, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x71, 0x00, 0x00, 0x00,
-+ 0x70, 0x10, 0x50, 0x50, 0x88, 0x88, 0x24, 0x20,
-+ 0x20, 0x30, 0x48, 0x58, 0xe4, 0x04, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x1f, 0x02, 0x7f, 0x01, 0x1f,
-+ 0x11, 0x11, 0x1f, 0x11, 0x01, 0x7e, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0xf0,
-+ 0x10, 0x10, 0xf0, 0x10, 0xf8, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x71, 0x00, 0x00, 0x00,
-+ 0x08, 0x48, 0x28, 0x28, 0x88, 0x48, 0x48, 0x0c,
-+ 0x38, 0xc8, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x60, 0x20, 0x20, 0xf8, 0xa8, 0xa8, 0xa8, 0xd8,
-+ 0xd8, 0x88, 0x88, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3f, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x2a, 0x0d, 0x0a, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3f, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x88, 0x88, 0x88, 0xfc, 0x88, 0x88, 0x88, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0e, 0x71, 0x00, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0x80, 0x80, 0xfc, 0x90, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3f, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0x20, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x71, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88,
-+ 0xf8, 0x88, 0x88, 0x88, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xf8, 0xa8, 0xa8, 0xa8, 0xf8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2b, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x74, 0x00, 0xfc,
-+ 0x24, 0x24, 0x24, 0x38, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x3f, 0x2b, 0x2b, 0x2b, 0x3f,
-+ 0x29, 0x0d, 0x0b, 0x0f, 0x73, 0x05, 0x00, 0x00,
-+ 0x00, 0xfc, 0x50, 0xfc, 0xf8, 0xa8, 0xf8, 0xa8,
-+ 0xf8, 0xfc, 0x34, 0xfc, 0x04, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2b, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0e, 0x70, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x88, 0xe8, 0xa8, 0xa8,
-+ 0xe8, 0xb0, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x3f, 0x2b, 0x2b, 0x2b, 0x3f,
-+ 0x29, 0x0d, 0x0b, 0x0f, 0x71, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xe8, 0xa8, 0xa8, 0xa8,
-+ 0xe8, 0xa8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2b, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x7d, 0x11, 0x11, 0x11, 0x1e, 0x64, 0x01,
-+ 0x1f, 0x11, 0x1f, 0x11, 0x01, 0x7e, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x90, 0x54, 0x54, 0x0c, 0x00,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf8, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x3f, 0x04, 0x7f, 0x05, 0x19, 0x6f,
-+ 0x09, 0x09, 0x0f, 0x09, 0x01, 0x3e, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xfc, 0x40, 0x30, 0xec,
-+ 0x20, 0x20, 0xe0, 0x20, 0xf0, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x3e, 0x2a, 0x2a, 0x2b, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x70, 0x03, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x50, 0x48, 0x94, 0x54, 0x50,
-+ 0x60, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2b, 0x2b, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x72, 0x00, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xf8, 0xa0, 0x20, 0xfc, 0x70,
-+ 0x70, 0xa8, 0xa8, 0x24, 0x20, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2b, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0b, 0x0e, 0x70, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x24, 0x28, 0xfc, 0x10, 0x60,
-+ 0x4c, 0xf0, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7c, 0x55, 0x55, 0x57, 0x7c,
-+ 0x52, 0x1a, 0x15, 0x1d, 0x62, 0x04, 0x00, 0x00,
-+ 0x04, 0x88, 0xf0, 0x90, 0x10, 0x5c, 0xd0, 0xd0,
-+ 0xd0, 0xd0, 0x3c, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0e, 0x71, 0x02, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0xe8, 0x60, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0b, 0x0e, 0x70, 0x03, 0x00, 0x00,
-+ 0x00, 0x38, 0xa8, 0xa8, 0xa8, 0xb8, 0x80, 0xf8,
-+ 0xa8, 0x28, 0xfc, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x08, 0x0f, 0x12, 0x3f,
-+ 0x52, 0x1f, 0x12, 0x03, 0x7c, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x00, 0xf8, 0x08, 0xc8,
-+ 0x48, 0xc8, 0x48, 0xe8, 0x28, 0x70, 0x00, 0x00,
-+ 0x00, 0x1f, 0x17, 0x10, 0x1f, 0x14, 0x27, 0x79,
-+ 0x0f, 0x09, 0x0f, 0x09, 0x01, 0x3e, 0x00, 0x00,
-+ 0x00, 0xf8, 0xf0, 0x00, 0xfc, 0x90, 0x60, 0x1c,
-+ 0xe0, 0x20, 0xe0, 0x20, 0xf0, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2b, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0e, 0x71, 0x02, 0x00, 0x00,
-+ 0x70, 0x10, 0x50, 0x48, 0x88, 0xfc, 0x88, 0x88,
-+ 0xf8, 0x50, 0x50, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7d, 0x08, 0x3d, 0x15, 0x08, 0x1e, 0x61,
-+ 0x1f, 0x11, 0x1f, 0x11, 0x01, 0x7e, 0x00, 0x00,
-+ 0x0c, 0xf0, 0x20, 0x3c, 0x20, 0xfc, 0x00, 0xfc,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf8, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x3e, 0x2a, 0x2b, 0x2a, 0x3e,
-+ 0x28, 0x0d, 0x0a, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x08, 0x30, 0xd0, 0xa8, 0xa4, 0x04, 0xf8, 0x10,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2b, 0x2a, 0x3f,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x72, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0xfc, 0x20, 0xfc,
-+ 0x20, 0xb0, 0xa8, 0x24, 0x24, 0x60, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x50, 0x20, 0xf8, 0xa8, 0xa8, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0xa8, 0xa8, 0x98, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x54, 0x57, 0x54, 0x7d,
-+ 0x51, 0x1a, 0x14, 0x1c, 0x60, 0x00, 0x00, 0x00,
-+ 0x48, 0x88, 0xa8, 0xa8, 0xa8, 0xe8, 0xa8, 0xa8,
-+ 0xe8, 0xe8, 0xa8, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x29, 0x0e, 0x0a, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x40, 0xfc,
-+ 0x54, 0x54, 0x94, 0x24, 0x44, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x56, 0x54, 0x54, 0x7d,
-+ 0x57, 0x18, 0x14, 0x1e, 0x61, 0x02, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x80, 0xf8, 0xe8, 0x68,
-+ 0x68, 0xf8, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3f, 0x2a, 0x2a, 0x2b, 0x3e,
-+ 0x29, 0x0e, 0x0a, 0x0e, 0x70, 0x00, 0x00, 0x00,
-+ 0x20, 0xa8, 0xa4, 0x24, 0xf8, 0x50, 0xfc, 0x88,
-+ 0xf4, 0x90, 0x90, 0xb4, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x3e, 0x2a, 0x2b, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0xf8,
-+ 0xa8, 0xa8, 0xf8, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7f, 0x54, 0x55, 0x55, 0x7d,
-+ 0x52, 0x1a, 0x14, 0x1c, 0x64, 0x00, 0x00, 0x00,
-+ 0x84, 0x88, 0xb0, 0xe0, 0xa0, 0xbc, 0xe8, 0xe8,
-+ 0xa8, 0xa8, 0xc8, 0xc8, 0x88, 0x88, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x55, 0x55, 0x55, 0x7d,
-+ 0x55, 0x19, 0x15, 0x1e, 0x62, 0x04, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xe8, 0xa8, 0xe8, 0xa8, 0x08, 0x18, 0x00, 0x00,
-+ 0x02, 0x3e, 0x02, 0x1e, 0x03, 0x7e, 0x04, 0x09,
-+ 0x1f, 0x11, 0x1f, 0x11, 0x01, 0x7e, 0x00, 0x00,
-+ 0x40, 0x7c, 0x40, 0x78, 0x40, 0x7c, 0x40, 0x40,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf8, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3f,
-+ 0x29, 0x0d, 0x0b, 0x0f, 0x71, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x90, 0xf0, 0x00, 0xf8,
-+ 0x48, 0xf8, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x3f, 0x2b, 0x2b, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0a, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x24, 0xfc, 0x24, 0xfc, 0x00, 0xf8,
-+ 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x98, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2a, 0x2b, 0x3f,
-+ 0x29, 0x0d, 0x0b, 0x0f, 0x71, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0xf0, 0xd0, 0xd0, 0xf8, 0x08,
-+ 0xe8, 0xa8, 0xa8, 0xe8, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x54, 0x57, 0x54, 0x7d,
-+ 0x51, 0x1a, 0x16, 0x1c, 0x60, 0x00, 0x00, 0x00,
-+ 0x48, 0xa8, 0x98, 0x98, 0x88, 0xe8, 0x98, 0x98,
-+ 0xcc, 0xb8, 0xa8, 0x88, 0x88, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x29, 0x0c, 0x0a, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x40, 0xfc,
-+ 0xa4, 0xb4, 0xcc, 0xfc, 0x84, 0x18, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7d, 0x57, 0x55, 0x55, 0x7f,
-+ 0x52, 0x1a, 0x17, 0x1e, 0x60, 0x01, 0x00, 0x00,
-+ 0x00, 0x38, 0x28, 0x28, 0xe8, 0x38, 0x28, 0xa8,
-+ 0xb8, 0xa8, 0xc8, 0x48, 0x88, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x29, 0x0c, 0x0a, 0x0e, 0x73, 0x00, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x00,
-+ 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x02, 0x3f, 0x02, 0x04, 0x08, 0x3e,
-+ 0x2a, 0x2a, 0x3e, 0x2a, 0x0f, 0x71, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe4, 0x14, 0x0c, 0x24, 0xf8,
-+ 0xa8, 0xa8, 0xf8, 0xa8, 0x3c, 0xc4, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3f, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x2a, 0x0c, 0x0b, 0x0e, 0x70, 0x07, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0xf8, 0x88, 0xf8, 0x88, 0xf8,
-+ 0x40, 0xf8, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7d, 0x55, 0x55, 0x55, 0x7d,
-+ 0x51, 0x19, 0x17, 0x1f, 0x65, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0x00, 0xf8,
-+ 0x68, 0x68, 0xf8, 0x68, 0x68, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x55, 0x56, 0x57, 0x7e,
-+ 0x53, 0x1a, 0x17, 0x1e, 0x62, 0x02, 0x00, 0x00,
-+ 0xe0, 0x20, 0x50, 0x90, 0xf8, 0x04, 0xa8, 0xa8,
-+ 0xa8, 0xd0, 0xd0, 0xa8, 0xa8, 0xa8, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7d, 0x57, 0x55, 0x55, 0x7d,
-+ 0x51, 0x19, 0x15, 0x1e, 0x62, 0x05, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x3c, 0xc0, 0x7c, 0x08, 0xd0,
-+ 0x50, 0x7c, 0x50, 0x50, 0x50, 0xb0, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3e, 0x2a, 0x2a, 0x2a, 0x3f,
-+ 0x28, 0x0d, 0x0a, 0x0e, 0x71, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x00, 0xfc,
-+ 0x80, 0xfc, 0x54, 0x94, 0x24, 0x58, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x54, 0x55, 0x56, 0x7f,
-+ 0x52, 0x1b, 0x16, 0x1c, 0x60, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xb8, 0xa0, 0xb8, 0xa8, 0xb8,
-+ 0xa8, 0xb8, 0xa8, 0xa0, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x2a, 0x2c, 0x49, 0x14, 0x22, 0x3f, 0x21,
-+ 0x5f, 0x11, 0x1f, 0x11, 0x01, 0x7e, 0x00, 0x00,
-+ 0x20, 0xa8, 0xb0, 0x30, 0x48, 0x88, 0xfc, 0x08,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf8, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x09, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x28, 0x0d, 0x0a, 0x0f, 0x70, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xf8, 0x88, 0xf8, 0x88, 0xf8,
-+ 0x20, 0xfc, 0x00, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x11, 0x11, 0x13, 0x7e, 0x56, 0x57, 0x56, 0x7f,
-+ 0x52, 0x1b, 0x16, 0x1e, 0x63, 0x0c, 0x00, 0x00,
-+ 0x00, 0x38, 0xa8, 0xa8, 0xb0, 0xb0, 0xa8, 0xa8,
-+ 0x64, 0xa4, 0xb8, 0xe0, 0x60, 0x20, 0x00, 0x00,
-+ 0x08, 0x3e, 0x7f, 0x08, 0x7f, 0x0e, 0x12, 0x67,
-+ 0x1f, 0x11, 0x1f, 0x11, 0x01, 0x7e, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0x90, 0x50, 0x20, 0x50, 0x8c,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf8, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x3e, 0x2b, 0x2a, 0x2a, 0x3f,
-+ 0x28, 0x0c, 0x0a, 0x0e, 0x71, 0x00, 0x00, 0x00,
-+ 0x18, 0xe8, 0xa8, 0x70, 0xfc, 0x70, 0xa8, 0x24,
-+ 0x40, 0x28, 0xc4, 0xd4, 0x50, 0x30, 0x00, 0x00,
-+ 0x01, 0x03, 0x1e, 0x01, 0x07, 0x78, 0x03, 0x08,
-+ 0x3e, 0x2a, 0x3e, 0x2a, 0x0f, 0x71, 0x00, 0x00,
-+ 0x00, 0xe0, 0x40, 0x80, 0x60, 0x9c, 0x80, 0x60,
-+ 0xf8, 0xa8, 0xf8, 0xa8, 0x3c, 0xc4, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x3e, 0x2a, 0x2b, 0x2a, 0x3e,
-+ 0x2b, 0x0c, 0x0b, 0x0e, 0x70, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xa8, 0x54, 0x20, 0xd8,
-+ 0x74, 0x20, 0xfc, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x09, 0x08, 0x09, 0x3f, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x29, 0x0d, 0x0b, 0x0f, 0x71, 0x00, 0x00, 0x00,
-+ 0x24, 0xa8, 0xfc, 0x08, 0xf8, 0x88, 0xf8, 0x20,
-+ 0xfc, 0x24, 0x24, 0x24, 0x38, 0x20, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x08, 0x3f, 0x2a, 0x2a,
-+ 0x3e, 0x28, 0x0a, 0x0f, 0x71, 0x00, 0x00, 0x00,
-+ 0x48, 0x48, 0x50, 0xfc, 0x90, 0x90, 0xf8, 0x90,
-+ 0x90, 0xf8, 0x90, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x04, 0x3f, 0x04, 0x7f, 0x2b, 0x2a, 0x56, 0x21,
-+ 0x1f, 0x11, 0x1f, 0x11, 0x01, 0x7e, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xc8, 0x28, 0x90, 0x68, 0x84,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf8, 0x04, 0x00, 0x00,
-+ 0x08, 0x3e, 0x09, 0x7f, 0x14, 0x7f, 0x3e, 0x09,
-+ 0x1f, 0x11, 0x1f, 0x11, 0x01, 0x3e, 0x00, 0x00,
-+ 0x40, 0x40, 0xf0, 0x50, 0xd0, 0x74, 0x94, 0x0c,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x3f, 0x2b, 0x2a, 0x2a, 0x3e,
-+ 0x28, 0x0c, 0x0a, 0x0e, 0x73, 0x00, 0x00, 0x00,
-+ 0x20, 0x24, 0xa8, 0xfc, 0x08, 0xf8, 0x88, 0xf8,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x7f, 0x0f, 0x08, 0x0f, 0x0f, 0x02, 0x7f,
-+ 0x09, 0x1f, 0x69, 0x0f, 0x01, 0x3e, 0x00, 0x00,
-+ 0x40, 0xfc, 0xe0, 0x20, 0xe0, 0xe0, 0x00, 0xfc,
-+ 0x20, 0xf0, 0x2c, 0xe0, 0xf0, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x3e, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x28, 0x0c, 0x0b, 0x0e, 0x70, 0x03, 0x00, 0x00,
-+ 0x50, 0x50, 0xfc, 0x50, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x20, 0xfc, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3f, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x28, 0x0d, 0x0a, 0x0e, 0x70, 0x03, 0x00, 0x00,
-+ 0x20, 0xf8, 0xa8, 0xfc, 0xa8, 0xf8, 0xf8, 0xa8,
-+ 0xf8, 0xfc, 0x50, 0xf0, 0x78, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x3f, 0x2a, 0x2b, 0x2a, 0x3e,
-+ 0x29, 0x0d, 0x0a, 0x0e, 0x70, 0x03, 0x00, 0x00,
-+ 0x20, 0xf8, 0x20, 0xfc, 0x88, 0xdc, 0x88, 0xfc,
-+ 0x00, 0xfc, 0x50, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x01, 0x1f, 0x11, 0x1f, 0x11, 0x01, 0x3e, 0x08,
-+ 0x3e, 0x2a, 0x3e, 0x2a, 0x0f, 0x71, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf8, 0x08, 0x20,
-+ 0xf8, 0xa8, 0xf8, 0xa8, 0x3c, 0xc4, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x3e, 0x2b, 0x2a, 0x2a, 0x3f,
-+ 0x28, 0x0c, 0x0a, 0x0f, 0x70, 0x00, 0x00, 0x00,
-+ 0x18, 0xe8, 0xa8, 0x70, 0xfc, 0x70, 0xa8, 0x24,
-+ 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0x88, 0x00, 0x00,
-+ 0x11, 0x11, 0x12, 0x7c, 0x57, 0x56, 0x56, 0x7f,
-+ 0x52, 0x1a, 0x17, 0x1c, 0x64, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x54, 0x94, 0xec, 0xc8, 0xd8, 0xdc,
-+ 0xe8, 0xc8, 0xfc, 0x48, 0x48, 0xc8, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x56, 0x57, 0x55, 0x7f,
-+ 0x53, 0x1f, 0x16, 0x1f, 0x62, 0x00, 0x00, 0x00,
-+ 0x10, 0xd0, 0x50, 0xd0, 0x7c, 0xf4, 0x18, 0xd0,
-+ 0x50, 0x50, 0xe8, 0xe8, 0x44, 0xc4, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7f, 0x55, 0x55, 0x55, 0x7d,
-+ 0x51, 0x19, 0x16, 0x1e, 0x64, 0x00, 0x00, 0x00,
-+ 0x40, 0xf0, 0x20, 0xfc, 0x54, 0x9c, 0x78, 0xfc,
-+ 0x70, 0x70, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x10, 0x13, 0x11, 0x7d, 0x55, 0x55, 0x57, 0x7c,
-+ 0x51, 0x18, 0x14, 0x1c, 0x63, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x5c, 0xd4, 0xd4, 0x54, 0xdc, 0x58,
-+ 0xe0, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x09, 0x08, 0x09, 0x3f, 0x2a, 0x2a, 0x2a, 0x3e,
-+ 0x29, 0x0d, 0x0b, 0x0f, 0x71, 0x01, 0x00, 0x00,
-+ 0x24, 0xa8, 0xfc, 0x08, 0xf0, 0x90, 0xf0, 0x00,
-+ 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x3e, 0x2b, 0x2a, 0x2a, 0x3f,
-+ 0x28, 0x0c, 0x0b, 0x0e, 0x71, 0x02, 0x00, 0x00,
-+ 0x50, 0xfc, 0x50, 0x20, 0xfc, 0x50, 0xa8, 0xfc,
-+ 0x20, 0xa8, 0xfc, 0x88, 0x08, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x3e, 0x2a, 0x2b, 0x2a, 0x3e,
-+ 0x29, 0x0c, 0x0b, 0x0e, 0x70, 0x01, 0x00, 0x00,
-+ 0x50, 0x50, 0xfc, 0x50, 0x20, 0xfc, 0x50, 0x88,
-+ 0x54, 0x50, 0xfc, 0x50, 0x90, 0x10, 0x00, 0x00,
-+ 0x10, 0x11, 0x12, 0x7c, 0x55, 0x56, 0x55, 0x7d,
-+ 0x52, 0x1b, 0x14, 0x1c, 0x63, 0x00, 0x00, 0x00,
-+ 0x90, 0xf4, 0xf8, 0x90, 0x68, 0x44, 0xfc, 0x28,
-+ 0x20, 0xfc, 0x70, 0xa8, 0x24, 0x20, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x3e, 0x2b, 0x2a, 0x2a, 0x3e,
-+ 0x28, 0x0d, 0x0a, 0x0e, 0x70, 0x03, 0x00, 0x00,
-+ 0x50, 0xfc, 0x50, 0xfc, 0xa0, 0xf8, 0xf8, 0xa0,
-+ 0xfc, 0xf8, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x3f, 0x2b, 0x2b, 0x2b, 0x3f,
-+ 0x28, 0x0d, 0x0b, 0x0f, 0x71, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xfc, 0x28, 0xac, 0xac, 0xfc,
-+ 0x20, 0xfc, 0x54, 0x54, 0x54, 0x0c, 0x00, 0x00,
-+ 0x01, 0x3f, 0x0f, 0x7f, 0x07, 0x1c, 0x67, 0x07,
-+ 0x08, 0x3e, 0x2a, 0x3e, 0x0e, 0x71, 0x00, 0x00,
-+ 0x00, 0xf8, 0xe0, 0xfc, 0xc0, 0x70, 0xcc, 0xc0,
-+ 0x20, 0xf8, 0xa8, 0xf8, 0x38, 0xc4, 0x00, 0x00,
-+ 0x04, 0x07, 0x0f, 0x7f, 0x07, 0x3b, 0x1d, 0x3e,
-+ 0x0b, 0x3e, 0x2a, 0x3e, 0x0e, 0x71, 0x00, 0x00,
-+ 0x00, 0xe0, 0xc0, 0xfc, 0x90, 0xe0, 0xb0, 0x8c,
-+ 0x20, 0xf8, 0xa8, 0xf8, 0x38, 0xc4, 0x00, 0x00,
-+ 0x01, 0x0f, 0x09, 0x0f, 0x3f, 0x08, 0x3e, 0x3e,
-+ 0x0e, 0x71, 0x1f, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xf0, 0xf8, 0x20, 0xf8, 0xf8,
-+ 0x38, 0xc4, 0xf0, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x14, 0x7f, 0x1e, 0x6f, 0x0f, 0x08,
-+ 0x0f, 0x3e, 0x2a, 0x3e, 0x0e, 0x71, 0x00, 0x00,
-+ 0x00, 0xf8, 0x50, 0xfc, 0x74, 0xec, 0xe0, 0x20,
-+ 0xe0, 0xf8, 0xa8, 0xf8, 0x38, 0xc4, 0x00, 0x00,
-+ 0x01, 0x7f, 0x0f, 0x0f, 0x3f, 0x2f, 0x47, 0x3a,
-+ 0x0b, 0x3e, 0x2a, 0x3e, 0x0e, 0x71, 0x00, 0x00,
-+ 0x00, 0xfc, 0xe0, 0xe0, 0xfc, 0xf8, 0xe0, 0x20,
-+ 0xe0, 0xf8, 0xa8, 0xf8, 0x38, 0xc4, 0x00, 0x00,
-+ 0x01, 0x7f, 0x0f, 0x3f, 0x2f, 0x47, 0x1c, 0x67,
-+ 0x08, 0x3e, 0x2a, 0x3e, 0x0e, 0x71, 0x00, 0x00,
-+ 0x00, 0xfc, 0xe0, 0xfc, 0xf8, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xf8, 0xa8, 0xf8, 0x38, 0xc4, 0x00, 0x00,
-+ 0x13, 0x17, 0x6b, 0x17, 0x7c, 0x3b, 0x36, 0x53,
-+ 0x1f, 0x11, 0x1f, 0x11, 0x01, 0x3e, 0x00, 0x00,
-+ 0x90, 0xd4, 0xa8, 0x98, 0x7c, 0xb8, 0xd4, 0x94,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x10, 0x3f, 0x2d, 0x2d, 0x2d, 0x2d,
-+ 0x2d, 0x2d, 0x2f, 0x3c, 0x61, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x48, 0xfc, 0x48,
-+ 0x48, 0x48, 0xc8, 0x48, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x10, 0x3f, 0x2d, 0x2d, 0x2d, 0x2d,
-+ 0x2d, 0x2d, 0x2f, 0x3c, 0x61, 0x02, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0xc8, 0x48, 0x68,
-+ 0x58, 0x4c, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x12, 0x12, 0x22, 0x4f, 0x0a, 0x12, 0x1c, 0x35,
-+ 0x53, 0x13, 0x14, 0x1f, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x38, 0x00, 0xc0, 0x00, 0xfc, 0x90, 0x10,
-+ 0x10, 0x10, 0x90, 0x50, 0x50, 0x30, 0x00, 0x00,
-+ 0x10, 0x1f, 0x22, 0x4f, 0x0a, 0x12, 0x1f, 0x30,
-+ 0x57, 0x14, 0x14, 0x17, 0x14, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x80, 0x80, 0xbc, 0xd0, 0x10,
-+ 0x90, 0x90, 0x90, 0x90, 0x90, 0x30, 0x00, 0x00,
-+ 0x11, 0x17, 0x22, 0x4f, 0x0f, 0x14, 0x17, 0x3f,
-+ 0x51, 0x17, 0x15, 0x15, 0x15, 0x11, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xe0, 0xc0, 0x7c, 0xc8, 0xe8,
-+ 0x08, 0xc8, 0x48, 0x48, 0xc8, 0x18, 0x00, 0x00,
-+ 0x10, 0x1e, 0x2a, 0x4e, 0x1e, 0x1a, 0x2e, 0x27,
-+ 0x6c, 0x37, 0x27, 0x24, 0x27, 0x24, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xe0, 0xe0, 0xbc, 0xe8, 0xe8,
-+ 0x88, 0xc8, 0xc8, 0x88, 0xe8, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7e, 0x04, 0x05, 0x09, 0x1e,
-+ 0x2a, 0x49, 0x08, 0x08, 0x08, 0x09, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0x28, 0x48, 0x90, 0x10, 0x24,
-+ 0x44, 0x88, 0x08, 0x10, 0x60, 0x80, 0x00, 0x00,
-+ 0x01, 0x1f, 0x01, 0x7f, 0x00, 0x0f, 0x08, 0x0f,
-+ 0x02, 0x0c, 0x74, 0x04, 0x07, 0x38, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x00, 0xe0, 0x20, 0xe0,
-+ 0x88, 0x88, 0x50, 0x60, 0x30, 0x0c, 0x00, 0x00,
-+ 0x01, 0x02, 0x0c, 0x77, 0x00, 0x1f, 0x00, 0x01,
-+ 0x7f, 0x03, 0x0c, 0x74, 0x07, 0x38, 0x00, 0x00,
-+ 0x00, 0x80, 0x60, 0xdc, 0x00, 0xf0, 0x20, 0x40,
-+ 0xfc, 0x10, 0xa0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x04, 0x18, 0x6f, 0x08, 0x08,
-+ 0x0f, 0x06, 0x7c, 0x04, 0x07, 0x38, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x60, 0x18, 0xe4, 0x20, 0x20,
-+ 0xe0, 0x88, 0x50, 0x60, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x09, 0x0b, 0x13, 0x3d,
-+ 0x55, 0x13, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7c, 0x08, 0x0a, 0x13, 0x3c,
-+ 0x54, 0x12, 0x10, 0x10, 0x11, 0x10, 0x00, 0x00,
-+ 0x08, 0x30, 0xe0, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x09, 0x0b, 0x13, 0x3d,
-+ 0x55, 0x13, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x80, 0x8c, 0xf0, 0x10, 0x10, 0x10, 0x10, 0xfc,
-+ 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x09, 0x0b, 0x13, 0x3d,
-+ 0x55, 0x13, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0xc0, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0xa8,
-+ 0xa8, 0x18, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x08, 0x0a, 0x12, 0x3d,
-+ 0x54, 0x12, 0x10, 0x10, 0x11, 0x12, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0xfc,
-+ 0x40, 0x60, 0xa0, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x08, 0x0b, 0x12, 0x3d,
-+ 0x54, 0x12, 0x11, 0x10, 0x10, 0x13, 0x00, 0x00,
-+ 0x40, 0x40, 0x60, 0xa0, 0x90, 0x28, 0x44, 0x90,
-+ 0x20, 0x48, 0x90, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x09, 0x0b, 0x13, 0x3d,
-+ 0x55, 0x13, 0x11, 0x10, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0x10, 0xf0, 0x10, 0x10,
-+ 0x10, 0xf0, 0x10, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x08, 0x0b, 0x12, 0x3c,
-+ 0x54, 0x12, 0x11, 0x12, 0x10, 0x10, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0x80, 0xfc, 0x20, 0x20, 0xb0,
-+ 0xa8, 0xa8, 0x24, 0x24, 0x20, 0x60, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x09, 0x0b, 0x13, 0x3d,
-+ 0x55, 0x13, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x40, 0x40, 0x80, 0xf8, 0x08, 0x08, 0x08, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x08, 0x0a, 0x12, 0x3d,
-+ 0x54, 0x12, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x20, 0xa8, 0xa4, 0x24, 0xf8, 0x20, 0x20, 0xfc,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x09, 0x0b, 0x13, 0x3d,
-+ 0x55, 0x13, 0x11, 0x11, 0x11, 0x10, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf8, 0x08, 0xe8, 0x28, 0x28,
-+ 0xe8, 0x30, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x01, 0x7f, 0x0f, 0x02, 0x7f, 0x03, 0x0d, 0x73,
-+ 0x01, 0x7f, 0x03, 0x7c, 0x07, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0xe0, 0x80, 0xfc, 0x30, 0x00, 0x00,
-+ 0x00, 0xfc, 0x90, 0x60, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x07, 0x04, 0x7f, 0x09, 0x08, 0x1f, 0x01,
-+ 0x01, 0x7f, 0x03, 0x7c, 0x07, 0x38, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0xfc, 0x10, 0x90, 0xfc, 0x60,
-+ 0x00, 0xfc, 0x88, 0x50, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7c, 0x08, 0x0b, 0x12, 0x3c,
-+ 0x55, 0x12, 0x10, 0x10, 0x13, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x40, 0x40,
-+ 0xf8, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x09, 0x0b, 0x15, 0x39,
-+ 0x55, 0x15, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0xa0, 0xa8, 0xa4, 0x24, 0x20, 0xfc, 0x20, 0x20,
-+ 0x20, 0x50, 0x50, 0x88, 0x88, 0x04, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7c, 0x08, 0x0b, 0x12, 0x3d,
-+ 0x54, 0x12, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x40, 0x40, 0xfc, 0x00, 0xfc,
-+ 0x40, 0x70, 0x48, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7e, 0x08, 0x08, 0x15, 0x39,
-+ 0x57, 0x15, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x80, 0xb8, 0x00, 0x00, 0x80, 0xfc, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x01, 0x7f, 0x02, 0x0c, 0x74, 0x07, 0x38, 0x3f,
-+ 0x24, 0x28, 0x37, 0x24, 0x27, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0x50, 0x60, 0x30, 0x0c, 0xf8,
-+ 0x98, 0x78, 0xc8, 0x48, 0xc8, 0x18, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x39, 0x07, 0x19, 0x63, 0x01,
-+ 0x7f, 0x03, 0x0c, 0x74, 0x07, 0x38, 0x00, 0x00,
-+ 0x10, 0xfc, 0x08, 0xb0, 0x60, 0x18, 0x04, 0x00,
-+ 0xfc, 0x10, 0xa0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x11, 0x10, 0x7c, 0x0b, 0x08, 0x13, 0x3c,
-+ 0x54, 0x13, 0x12, 0x14, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xfc, 0x48, 0xf8, 0x80,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x24, 0x24, 0x3f, 0x04, 0x7c, 0x25, 0x45, 0x01,
-+ 0x7f, 0x03, 0x0c, 0x74, 0x07, 0x38, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x00, 0x00,
-+ 0xfc, 0x10, 0xa0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x01, 0x7f, 0x0f, 0x09, 0x0f, 0x09, 0x0f, 0x7f,
-+ 0x11, 0x63, 0x0c, 0x74, 0x07, 0x18, 0x00, 0x00,
-+ 0x00, 0xfc, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0xfc,
-+ 0x30, 0x28, 0xc4, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x13, 0x7c, 0x08, 0x0b, 0x14, 0x18,
-+ 0x37, 0x54, 0x10, 0x10, 0x13, 0x10, 0x00, 0x00,
-+ 0x90, 0x90, 0xf0, 0x90, 0x90, 0xf8, 0x94, 0x94,
-+ 0xf0, 0x90, 0x90, 0xf0, 0x90, 0x10, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x09, 0x0b, 0x12, 0x3c,
-+ 0x55, 0x12, 0x14, 0x11, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x80, 0xfc,
-+ 0x54, 0x54, 0x94, 0x24, 0x44, 0x18, 0x00, 0x00,
-+ 0x02, 0x7e, 0x02, 0x3e, 0x03, 0x7e, 0x04, 0x09,
-+ 0x7f, 0x03, 0x0c, 0x74, 0x07, 0x38, 0x00, 0x00,
-+ 0x40, 0x7c, 0x40, 0x78, 0x40, 0x7c, 0x40, 0x40,
-+ 0xfc, 0x10, 0xa0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7d, 0x09, 0x0b, 0x13, 0x1d,
-+ 0x34, 0x52, 0x13, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x50, 0x90, 0xfc, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7f, 0x0a, 0x0b, 0x16, 0x3a,
-+ 0x56, 0x17, 0x12, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0xd8, 0xd8,
-+ 0xd8, 0x68, 0x48, 0x48, 0x48, 0x18, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7d, 0x08, 0x0b, 0x14, 0x19,
-+ 0x34, 0x57, 0x10, 0x11, 0x10, 0x13, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8,
-+ 0x40, 0xfc, 0x90, 0xe0, 0x70, 0x88, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x08, 0x0b, 0x15, 0x19,
-+ 0x35, 0x55, 0x10, 0x13, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xfc, 0x40, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x0a, 0x0b, 0x16, 0x1b,
-+ 0x36, 0x56, 0x17, 0x1a, 0x12, 0x12, 0x00, 0x00,
-+ 0x18, 0xe0, 0x00, 0xf8, 0x08, 0xf8, 0x00, 0xf8,
-+ 0xa8, 0xa8, 0xf8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x7d, 0x09, 0x0b, 0x15, 0x39,
-+ 0x55, 0x15, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x80, 0xf8, 0xc8, 0x48, 0x48, 0x78, 0x20, 0xfc,
-+ 0x70, 0x70, 0xa8, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x01, 0x7f, 0x04, 0x38, 0x20, 0x3d, 0x20, 0x3d,
-+ 0x21, 0x03, 0x0c, 0x74, 0x07, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf8, 0x88, 0xf8, 0xfc, 0x70, 0xac,
-+ 0x20, 0x10, 0xa0, 0x40, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7d, 0x09, 0x0b, 0x15, 0x38,
-+ 0x57, 0x12, 0x12, 0x12, 0x17, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x50, 0x50, 0xb0, 0x10, 0xf0, 0x00,
-+ 0xf8, 0xa8, 0xa8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x0b, 0x0a, 0x16, 0x3b,
-+ 0x56, 0x17, 0x12, 0x14, 0x18, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf8, 0x00, 0xfc, 0xa8, 0xf0, 0x8c,
-+ 0x10, 0xfc, 0x90, 0x50, 0x10, 0x30, 0x00, 0x00,
-+ 0x12, 0x11, 0x11, 0x7c, 0x0a, 0x09, 0x15, 0x38,
-+ 0x57, 0x15, 0x11, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0x78, 0x48, 0x7c, 0x44,
-+ 0x58, 0x48, 0x74, 0xc4, 0xc0, 0x3c, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7e, 0x0a, 0x0a, 0x16, 0x1a,
-+ 0x36, 0x52, 0x15, 0x15, 0x1a, 0x11, 0x00, 0x00,
-+ 0x18, 0xe0, 0x38, 0x20, 0xfc, 0xb8, 0xe4, 0x9c,
-+ 0xf0, 0xd0, 0x50, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x20, 0x27, 0x21, 0x79, 0x17, 0x14, 0x2c, 0x37,
-+ 0x6d, 0x29, 0x21, 0x21, 0x21, 0x26, 0x00, 0x00,
-+ 0x20, 0x30, 0x48, 0xfc, 0x24, 0xf8, 0xa8, 0xa8,
-+ 0xf8, 0xa8, 0x30, 0x28, 0xf4, 0x04, 0x00, 0x00,
-+ 0x01, 0x7f, 0x1e, 0x12, 0x1e, 0x04, 0x3f, 0x1f,
-+ 0x04, 0x7f, 0x06, 0x7c, 0x07, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf0, 0x90, 0xf0, 0x40, 0xf8, 0xf0,
-+ 0x40, 0xfc, 0x90, 0x60, 0x30, 0x0c, 0x00, 0x00,
-+ 0x01, 0x7f, 0x08, 0x3e, 0x7f, 0x2d, 0x4b, 0x3e,
-+ 0x0e, 0x31, 0x06, 0x7c, 0x07, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf0, 0x50, 0xd0, 0x70, 0x54,
-+ 0x94, 0x8c, 0x90, 0x60, 0x30, 0x0c, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7d, 0x0a, 0x09, 0x16, 0x18,
-+ 0x35, 0x55, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00,
-+ 0x00, 0xfc, 0xcc, 0x54, 0xec, 0x54, 0x64, 0x80,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x7f, 0x09, 0x09, 0x15, 0x39,
-+ 0x55, 0x17, 0x10, 0x11, 0x10, 0x13, 0x00, 0x00,
-+ 0x40, 0xf8, 0x48, 0xfc, 0x48, 0xf8, 0xf8, 0x48,
-+ 0xf8, 0xfc, 0x90, 0xe0, 0x70, 0x88, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x08, 0x0b, 0x15, 0x19,
-+ 0x35, 0x55, 0x10, 0x17, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0x00, 0xf0, 0x50, 0xf0,
-+ 0x50, 0xf0, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x12, 0x11, 0x7d, 0x09, 0x0b, 0x15, 0x19,
-+ 0x35, 0x54, 0x17, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x88, 0x48, 0x50, 0x20, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x12, 0x11, 0x13, 0x7e, 0x09, 0x0b, 0x15, 0x18,
-+ 0x37, 0x56, 0x13, 0x12, 0x13, 0x12, 0x00, 0x00,
-+ 0x48, 0x50, 0xfc, 0x08, 0xf0, 0x10, 0xf0, 0x00,
-+ 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x3e, 0x21, 0x3e, 0x53, 0x1e,
-+ 0x11, 0x7f, 0x06, 0x7c, 0x07, 0x38, 0x00, 0x00,
-+ 0x20, 0xfc, 0x88, 0x50, 0xfc, 0x20, 0xfc, 0x20,
-+ 0x20, 0xfc, 0x90, 0x60, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7f, 0x0a, 0x0b, 0x17, 0x1b,
-+ 0x34, 0x57, 0x12, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xfc, 0x48, 0x58, 0x58, 0xf8,
-+ 0x80, 0xf8, 0xa8, 0xa8, 0xa8, 0xb8, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x7f, 0x0a, 0x0b, 0x16, 0x3b,
-+ 0x54, 0x17, 0x12, 0x12, 0x17, 0x10, 0x00, 0x00,
-+ 0x10, 0xd0, 0x90, 0xdc, 0x60, 0xc0, 0xb8, 0xc0,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x11, 0x11, 0x11, 0x7f, 0x09, 0x09, 0x17, 0x18,
-+ 0x37, 0x56, 0x12, 0x13, 0x12, 0x10, 0x00, 0x00,
-+ 0x00, 0x7c, 0x10, 0xe0, 0x38, 0x28, 0xf8, 0x28,
-+ 0xb8, 0xa8, 0xb8, 0x98, 0xa4, 0x44, 0x00, 0x00,
-+ 0x10, 0x17, 0x10, 0x7f, 0x0a, 0x0b, 0x14, 0x1b,
-+ 0x36, 0x57, 0x12, 0x12, 0x14, 0x18, 0x00, 0x00,
-+ 0xa0, 0xfc, 0xa0, 0xf8, 0xa8, 0xf8, 0x28, 0xfc,
-+ 0x28, 0xa8, 0x10, 0x34, 0xcc, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x10, 0x7f, 0x0a, 0x0e, 0x17, 0x19,
-+ 0x37, 0x57, 0x13, 0x15, 0x11, 0x11, 0x00, 0x00,
-+ 0x00, 0xb8, 0x28, 0xe8, 0xb8, 0xa8, 0xf8, 0x28,
-+ 0xf8, 0xb0, 0x70, 0x34, 0x54, 0x8c, 0x00, 0x00,
-+ 0x20, 0x27, 0x24, 0x7f, 0x14, 0x17, 0x2c, 0x37,
-+ 0x6d, 0x2d, 0x25, 0x24, 0x27, 0x24, 0x00, 0x00,
-+ 0x00, 0xbc, 0xa4, 0xbc, 0xa4, 0xbc, 0x44, 0xfc,
-+ 0xf4, 0xf4, 0xf4, 0xe4, 0x5c, 0x4c, 0x00, 0x00,
-+ 0x10, 0x11, 0x12, 0x7f, 0x0b, 0x0a, 0x17, 0x19,
-+ 0x36, 0x55, 0x10, 0x13, 0x10, 0x10, 0x00, 0x00,
-+ 0x80, 0xf8, 0xe8, 0x38, 0xb8, 0xa8, 0xfc, 0x30,
-+ 0xc8, 0xf4, 0x40, 0xf8, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x7f, 0x04, 0x04, 0x3f, 0x24, 0x24, 0x24,
-+ 0x27, 0x24, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0xc8, 0x48, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x7f, 0x04, 0x3f, 0x24, 0x27, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x7f, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf8, 0x48, 0xc8, 0xe0, 0x20,
-+ 0xe0, 0x20, 0xe0, 0xfc, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x04, 0x3f, 0x27, 0x08, 0x3e, 0x22,
-+ 0x3e, 0x3f, 0x7f, 0x1e, 0x22, 0x4d, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf8, 0xc8, 0x40, 0x40, 0xfc,
-+ 0x90, 0x90, 0x60, 0x20, 0x50, 0x8c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x04, 0x3f, 0x27, 0x14, 0x7f, 0x1c,
-+ 0x3e, 0x2a, 0x3e, 0x7f, 0x09, 0x0a, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf8, 0xc8, 0xfc, 0xa0, 0xf8,
-+ 0xf8, 0xa0, 0xfc, 0xd4, 0x6c, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x11, 0x21, 0x4f, 0x08, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x38, 0xd0, 0x08, 0x04, 0xe4, 0x20, 0xe0, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x10, 0x11, 0x11, 0x1f, 0x11, 0x11, 0x7d, 0x45,
-+ 0x45, 0x44, 0x7c, 0x45, 0x02, 0x0c, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0xf0, 0x10,
-+ 0xf0, 0xa0, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x00, 0x7f, 0x08, 0x2a, 0x2a, 0x2a, 0x2a,
-+ 0x3f, 0x5d, 0x48, 0x0e, 0x71, 0x06, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x50, 0x50, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x08, 0x09, 0x3f, 0x0a, 0x0a, 0x7f, 0x0c, 0x12,
-+ 0x3e, 0x52, 0x1e, 0x12, 0x1f, 0x12, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x50, 0x50, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x0e, 0x06, 0x09, 0x10, 0x3f, 0x40, 0x3a, 0x2a,
-+ 0x3a, 0x2d, 0x3d, 0x2a, 0x2a, 0x2a, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0xc8, 0xf8, 0x48, 0xf8, 0xc8,
-+ 0xf8, 0x30, 0x30, 0xb4, 0xd4, 0x8c, 0x00, 0x00,
-+ 0x08, 0x2a, 0x2a, 0x3e, 0x00, 0x7f, 0x00, 0x3e,
-+ 0x22, 0x3e, 0x22, 0x14, 0x1e, 0x61, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x50, 0x50, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x14, 0x7f, 0x14, 0x3e, 0x14, 0x7f, 0x08, 0x3e,
-+ 0x2a, 0x3e, 0x2a, 0x7f, 0x22, 0x27, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x50, 0x50, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x14, 0x7f, 0x14, 0x1c, 0x08, 0x3e, 0x2a, 0x3e,
-+ 0x08, 0x3e, 0x08, 0x3e, 0x0c, 0x71, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x50, 0x50, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x04, 0x1b, 0x12, 0x1a, 0x19, 0x12, 0x3f, 0x2f,
-+ 0x48, 0x0f, 0x0f, 0x0f, 0x06, 0x78, 0x00, 0x00,
-+ 0x80, 0x70, 0x90, 0xb0, 0x30, 0x90, 0xfc, 0xe8,
-+ 0x20, 0xe0, 0xe0, 0xe4, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x7e, 0x49, 0x7e, 0x7d, 0x49, 0x7f, 0x4f,
-+ 0x08, 0x0f, 0x0f, 0x0f, 0x06, 0x78, 0x00, 0x00,
-+ 0x80, 0xfc, 0x00, 0xf8, 0xfc, 0x54, 0xfc, 0xe0,
-+ 0x20, 0xe0, 0xe0, 0xe4, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x7f, 0x3e, 0x7f, 0x57, 0x7f, 0x3e, 0x22,
-+ 0x3e, 0x3e, 0x22, 0x3e, 0x14, 0x63, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0x78, 0x48, 0x78, 0x48,
-+ 0x78, 0x30, 0x30, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x14, 0x7f, 0x14, 0x77, 0x55, 0x77, 0x14, 0x3f,
-+ 0x64, 0x3f, 0x3f, 0x24, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0x78, 0x48, 0x78, 0x48,
-+ 0x78, 0x30, 0x30, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x10, 0x1e, 0x25, 0x49, 0x3f, 0x2b, 0x2b, 0x3f,
-+ 0x2b, 0x3f, 0x23, 0x23, 0x23, 0x46, 0x00, 0x00,
-+ 0x08, 0x30, 0xd0, 0x50, 0x50, 0x50, 0x50, 0x50,
-+ 0x50, 0x70, 0x58, 0x78, 0x94, 0x04, 0x00, 0x00,
-+ 0x08, 0x2f, 0x28, 0x2f, 0x72, 0x07, 0x18, 0x6f,
-+ 0x09, 0x0f, 0x09, 0x0f, 0x10, 0x20, 0x00, 0x00,
-+ 0x80, 0x98, 0xe4, 0x84, 0x7c, 0xc0, 0x80, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x30, 0x00, 0x00,
-+ 0x10, 0x1e, 0x24, 0x48, 0x3e, 0x2a, 0x2a, 0x3e,
-+ 0x2a, 0x3e, 0x23, 0x22, 0x23, 0x46, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0xa0, 0xa0, 0xfc, 0xa0, 0xa0,
-+ 0x90, 0xf4, 0x8c, 0x0c, 0xf4, 0x04, 0x00, 0x00,
-+ 0x10, 0x1e, 0x24, 0x49, 0x3e, 0x2a, 0x2a, 0x3e,
-+ 0x2a, 0x3f, 0x22, 0x22, 0x22, 0x46, 0x00, 0x00,
-+ 0x88, 0x48, 0x50, 0xfc, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x1e, 0x24, 0x49, 0x3e, 0x2a, 0x2a, 0x3e,
-+ 0x2b, 0x3e, 0x23, 0x22, 0x23, 0x46, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xf0, 0x90, 0xf0, 0x90, 0xf0,
-+ 0xfc, 0xf8, 0x68, 0xa8, 0x48, 0x30, 0x00, 0x00,
-+ 0x10, 0x1f, 0x25, 0x49, 0x3e, 0x2a, 0x2b, 0x3f,
-+ 0x2b, 0x3f, 0x22, 0x22, 0x23, 0x46, 0x00, 0x00,
-+ 0x00, 0xf8, 0x68, 0xf8, 0x80, 0xf8, 0x48, 0xf8,
-+ 0x58, 0xf8, 0x68, 0x78, 0x88, 0x30, 0x00, 0x00,
-+ 0x00, 0x3e, 0x00, 0x7f, 0x00, 0x3e, 0x00, 0x3e,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x28, 0x24,
-+ 0x24, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x01, 0x3f, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x25, 0x25, 0x3d, 0x24, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xfc, 0x00, 0xf8, 0x10, 0x20,
-+ 0x40, 0x80, 0x00, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x00, 0x3c, 0x01, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3d, 0x00, 0x7e, 0x00, 0x3c, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3f, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x01, 0x3d, 0x03, 0x3d,
-+ 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x25, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xa0, 0xa4, 0x24, 0x28, 0x28, 0x30,
-+ 0x60, 0x20, 0x24, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3d, 0x00, 0x7e, 0x00, 0x3c, 0x03, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x25, 0x3e, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x10, 0x90, 0x90, 0x90, 0xfc, 0x30,
-+ 0x30, 0x50, 0x90, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7f, 0x01, 0x3d, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x25, 0x00, 0x00,
-+ 0xc0, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0x68,
-+ 0xa8, 0x98, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3d, 0x00, 0x7e, 0x01, 0x3d, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0x08, 0xe8, 0x28, 0x28, 0x28,
-+ 0xe8, 0x28, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7f, 0x00, 0x3c, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0x20, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x00, 0x3c, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3f, 0x24, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0x90, 0xf0, 0x90, 0x90,
-+ 0xf0, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x00, 0x3c, 0x03, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x50, 0x48, 0x88, 0xf4, 0x04,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7f, 0x01, 0x3d, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x27, 0x24, 0x3f, 0x24, 0x00, 0x00,
-+ 0x08, 0x30, 0xe0, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0x10, 0xd0, 0x14, 0x0c, 0xec, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3f, 0x0f, 0x00, 0x7f, 0x0f,
-+ 0x0f, 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0xe0, 0x00, 0xfc, 0xe0,
-+ 0xe0, 0x00, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7e, 0x00, 0x3c, 0x01, 0x3e,
-+ 0x00, 0x3d, 0x24, 0x24, 0x3c, 0x25, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xa0, 0xa4, 0x24, 0xa8,
-+ 0xb0, 0x20, 0x50, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7f, 0x01, 0x3d, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x25, 0x26, 0x3e, 0x24, 0x00, 0x00,
-+ 0x40, 0x78, 0x90, 0x20, 0xfc, 0x00, 0x78, 0x48,
-+ 0x48, 0x70, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x3d, 0x01, 0x7f, 0x01, 0x3d, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x26, 0x26, 0x3c, 0x24, 0x00, 0x00,
-+ 0x18, 0xe0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x01, 0x3f, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x25, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf8, 0x08, 0xe8, 0x28, 0xe8,
-+ 0x28, 0xe8, 0x28, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x01, 0x3e, 0x03, 0x3c,
-+ 0x00, 0x3c, 0x25, 0x26, 0x3c, 0x24, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xf8, 0x20, 0x20, 0xfc, 0x70,
-+ 0x70, 0xa8, 0x28, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x38, 0x00, 0x7e, 0x01, 0x39, 0x00, 0x39,
-+ 0x06, 0x38, 0x29, 0x29, 0x3a, 0x2c, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xa0, 0xa8, 0xa8, 0xb0, 0xb0, 0xa8,
-+ 0xa4, 0xa4, 0x20, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x03, 0x7c, 0x01, 0x3c, 0x03, 0x3c,
-+ 0x00, 0x3d, 0x26, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x40, 0x58, 0xe0, 0x40, 0xf8, 0x40, 0xfc, 0xe0,
-+ 0xe0, 0x50, 0x48, 0x44, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7f, 0x02, 0x3c, 0x00, 0x3f,
-+ 0x01, 0x3d, 0x25, 0x27, 0x3c, 0x24, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xf8, 0xc8, 0xa8, 0xfc,
-+ 0x48, 0x28, 0x28, 0xfc, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x38, 0x00, 0x7f, 0x00, 0x3a, 0x02, 0x3f,
-+ 0x02, 0x3a, 0x2a, 0x2a, 0x3c, 0x28, 0x00, 0x00,
-+ 0x28, 0x24, 0x24, 0xfc, 0x20, 0xa8, 0xa8, 0xe8,
-+ 0xb8, 0x90, 0x94, 0xac, 0x4c, 0x84, 0x00, 0x00,
-+ 0x00, 0x38, 0x02, 0x7d, 0x01, 0x3f, 0x00, 0x39,
-+ 0x01, 0x3a, 0x2c, 0x28, 0x38, 0x2b, 0x00, 0x00,
-+ 0x80, 0xfc, 0x90, 0x10, 0x10, 0x10, 0xfc, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x01, 0x3e, 0x03, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xfc, 0x20, 0x20, 0xfc, 0x20,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3d, 0x00, 0x7e, 0x01, 0x3d, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x25, 0x00, 0x00,
-+ 0x00, 0xf8, 0x50, 0x20, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7f, 0x02, 0x3d, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x25, 0x00, 0x00,
-+ 0x20, 0xb0, 0xa8, 0x24, 0x24, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3b, 0x00, 0x7d, 0x01, 0x39, 0x01, 0x39,
-+ 0x02, 0x3a, 0x2c, 0x28, 0x3f, 0x28, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x50, 0x50, 0x50, 0x50, 0x50,
-+ 0xe8, 0xe4, 0x44, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7e, 0x00, 0x3c, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x25, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x00, 0xf8, 0x88, 0xf8, 0x00,
-+ 0xf8, 0x10, 0xfc, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x3d, 0x01, 0x7f, 0x02, 0x3d, 0x00, 0x3f,
-+ 0x00, 0x3d, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x18, 0xf0, 0x48, 0x24, 0x04, 0xf8, 0x48, 0xfc,
-+ 0x48, 0xf8, 0x48, 0x40, 0x40, 0xc0, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x00, 0x3d, 0x00, 0x3d,
-+ 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x25, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0x88, 0x30, 0x40, 0xb8,
-+ 0x08, 0xb8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7f, 0x02, 0x3d, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3d, 0x26, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0x00, 0xfc, 0x20, 0xa0,
-+ 0xb8, 0xa0, 0xa0, 0xe0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x03, 0x7c, 0x03, 0x3f, 0x02, 0x3e,
-+ 0x03, 0x3c, 0x25, 0x26, 0x3c, 0x24, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x58, 0xd8, 0xe8,
-+ 0xf8, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7e, 0x00, 0x3c, 0x01, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x48, 0x50, 0xfc, 0x00,
-+ 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x01, 0x3d, 0x01, 0x7f, 0x01, 0x3d, 0x03, 0x3c,
-+ 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x25, 0x00, 0x00,
-+ 0x20, 0x24, 0xf8, 0x20, 0x24, 0xe4, 0x3c, 0x40,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3d, 0x01, 0x7f, 0x00, 0x3c, 0x00, 0x3d,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x00, 0xdc, 0x54, 0xdc, 0x00, 0xf8, 0x00, 0xfc,
-+ 0x40, 0x78, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3d, 0x00, 0x7f, 0x00, 0x3c, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x27, 0x3c, 0x24, 0x00, 0x00,
-+ 0x40, 0xf8, 0x48, 0xfc, 0x00, 0xf8, 0x88, 0xf8,
-+ 0x10, 0xf8, 0x90, 0xfc, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7f, 0x01, 0x3d, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x25, 0x26, 0x3e, 0x24, 0x00, 0x00,
-+ 0x20, 0x3c, 0x20, 0xfc, 0x38, 0xe4, 0x1c, 0x00,
-+ 0x7c, 0x40, 0xfc, 0x40, 0x7c, 0x40, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7f, 0x03, 0x3c, 0x00, 0x3c,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3f, 0x24, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0xfc, 0x00, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3d, 0x01, 0x7f, 0x00, 0x3d, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x24, 0x27, 0x3c, 0x24, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xfc, 0x40, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x3b, 0x02, 0x7f, 0x02, 0x3b, 0x03, 0x3b,
-+ 0x03, 0x3a, 0x2a, 0x2c, 0x3f, 0x28, 0x00, 0x00,
-+ 0x00, 0xf0, 0x30, 0xd0, 0x90, 0xf0, 0xb0, 0xb0,
-+ 0xf0, 0x90, 0xb4, 0xfc, 0x1c, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x7f, 0x02, 0x3b, 0x02, 0x3b,
-+ 0x02, 0x3f, 0x2a, 0x2a, 0x3a, 0x2a, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0x00, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x00, 0x3b, 0x02, 0x7e, 0x03, 0x3a, 0x02, 0x3b,
-+ 0x02, 0x38, 0x28, 0x29, 0x3a, 0x2c, 0x00, 0x00,
-+ 0xc0, 0x58, 0x48, 0x48, 0x58, 0x48, 0x48, 0xf8,
-+ 0x48, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x3d, 0x00, 0x7e, 0x00, 0x3c, 0x00, 0x3d,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x24, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0xe8, 0xa8, 0xe8, 0x18, 0xfc,
-+ 0x08, 0xe8, 0xa8, 0xe8, 0x08, 0x18, 0x00, 0x00,
-+ 0x01, 0x3f, 0x22, 0x5f, 0x0f, 0x7f, 0x04, 0x1f,
-+ 0x6f, 0x07, 0x07, 0x0f, 0x08, 0x0f, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0xf8, 0xe0, 0xfc, 0x40, 0xf0,
-+ 0xec, 0xc0, 0xc0, 0xe0, 0x20, 0xe0, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7f, 0x00, 0x3c, 0x00, 0x3d,
-+ 0x03, 0x3d, 0x25, 0x25, 0x3f, 0x24, 0x00, 0x00,
-+ 0xf0, 0x90, 0x08, 0xf4, 0x00, 0xf0, 0x90, 0x08,
-+ 0xfc, 0x68, 0x68, 0x68, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7d, 0x02, 0x3c, 0x00, 0x3c,
-+ 0x01, 0x3d, 0x25, 0x25, 0x3f, 0x24, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0xf8, 0x44, 0xf0, 0x10, 0x60,
-+ 0xf8, 0x68, 0x68, 0x68, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3d, 0x01, 0x7f, 0x01, 0x3d, 0x00, 0x3d,
-+ 0x02, 0x3c, 0x27, 0x24, 0x3c, 0x27, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0xa4, 0x5c,
-+ 0x40, 0xf8, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x38, 0x00, 0x7e, 0x02, 0x3a, 0x04, 0x38,
-+ 0x03, 0x3a, 0x2a, 0x2a, 0x3f, 0x28, 0x00, 0x00,
-+ 0x40, 0x28, 0xa8, 0x90, 0x98, 0xa4, 0xd4, 0xf0,
-+ 0xf8, 0xa8, 0xa8, 0xa8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x01, 0x7e, 0x00, 0x3d, 0x01, 0x3e,
-+ 0x01, 0x3c, 0x24, 0x24, 0x3c, 0x25, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x50, 0xfc, 0x28, 0x20,
-+ 0xfc, 0x20, 0x38, 0x48, 0x88, 0x30, 0x00, 0x00,
-+ 0x00, 0x3c, 0x03, 0x7e, 0x00, 0x3f, 0x00, 0x3d,
-+ 0x03, 0x3c, 0x25, 0x25, 0x3d, 0x25, 0x00, 0x00,
-+ 0x40, 0xf8, 0x48, 0xb0, 0xe0, 0x80, 0xf8, 0x20,
-+ 0xfc, 0x20, 0x28, 0x28, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3b, 0x02, 0x7e, 0x02, 0x3a, 0x02, 0x3b,
-+ 0x03, 0x3b, 0x2b, 0x2a, 0x3b, 0x2a, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x90, 0xf0, 0x00, 0xf8,
-+ 0x68, 0x68, 0xf8, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x14, 0x7f, 0x14, 0x1d, 0x0b, 0x3f, 0x2a, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x80, 0x80, 0xf8, 0x08, 0xe8, 0xf8, 0x08, 0xe8,
-+ 0xe8, 0x08, 0xe8, 0xa8, 0xe8, 0x30, 0x00, 0x00,
-+ 0x08, 0x7f, 0x3e, 0x3f, 0x2a, 0x3e, 0x23, 0x47,
-+ 0x3f, 0x07, 0x07, 0x0f, 0x08, 0x0f, 0x00, 0x00,
-+ 0x70, 0x50, 0x94, 0xfc, 0x90, 0x60, 0x9c, 0xc0,
-+ 0xf8, 0xc0, 0xc0, 0xe0, 0x20, 0xe0, 0x00, 0x00,
-+ 0x00, 0x38, 0x07, 0x7d, 0x00, 0x3b, 0x02, 0x3b,
-+ 0x02, 0x3a, 0x2a, 0x2a, 0x3a, 0x2a, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x10, 0xa0, 0xf8, 0x48, 0xf8,
-+ 0x48, 0xe8, 0xa8, 0xe8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x00, 0x3c, 0x00, 0x7e, 0x00, 0x3c, 0x01, 0x3d,
-+ 0x01, 0x3d, 0x24, 0x24, 0x3c, 0x27, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc, 0x54,
-+ 0xfc, 0xf8, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x03, 0x7e, 0x01, 0x3d, 0x01, 0x3d,
-+ 0x01, 0x3c, 0x27, 0x24, 0x3d, 0x26, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x90, 0xf8, 0x08, 0xf8, 0x08,
-+ 0xf8, 0x40, 0xfc, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x38, 0x07, 0x7c, 0x03, 0x39, 0x07, 0x39,
-+ 0x03, 0x38, 0x2f, 0x28, 0x38, 0x28, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xfc, 0xa0, 0xf8, 0x50, 0xfc, 0x50,
-+ 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x3b, 0x01, 0x7d, 0x03, 0x39, 0x01, 0x39,
-+ 0x01, 0x3a, 0x2a, 0x2d, 0x39, 0x2a, 0x00, 0x00,
-+ 0x18, 0xf0, 0x48, 0x24, 0xe4, 0x20, 0xf0, 0x10,
-+ 0xfc, 0x04, 0xd4, 0x6c, 0x44, 0x18, 0x00, 0x00,
-+ 0x01, 0x39, 0x06, 0x7e, 0x01, 0x3a, 0x07, 0x38,
-+ 0x03, 0x39, 0x29, 0x2a, 0x3a, 0x2c, 0x00, 0x00,
-+ 0x48, 0x48, 0xf4, 0xd4, 0x48, 0xd4, 0xfc, 0x50,
-+ 0xfc, 0x28, 0xa8, 0x94, 0x2c, 0xc4, 0x00, 0x00,
-+ 0x00, 0x3b, 0x00, 0x7c, 0x07, 0x38, 0x03, 0x38,
-+ 0x03, 0x3a, 0x2b, 0x2a, 0x3a, 0x2a, 0x00, 0x00,
-+ 0x00, 0xf0, 0xa0, 0x40, 0xfc, 0xc8, 0x50, 0xc0,
-+ 0xf8, 0xb8, 0xf8, 0xa8, 0xe8, 0x18, 0x00, 0x00,
-+ 0x01, 0x38, 0x02, 0x7d, 0x01, 0x3a, 0x05, 0x39,
-+ 0x01, 0x39, 0x29, 0x28, 0x3f, 0x28, 0x00, 0x00,
-+ 0xc8, 0x68, 0xb4, 0x94, 0xf8, 0x08, 0xf4, 0x10,
-+ 0x10, 0xf0, 0x10, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3b, 0x02, 0x7e, 0x03, 0x39, 0x01, 0x3a,
-+ 0x05, 0x39, 0x29, 0x29, 0x39, 0x29, 0x00, 0x00,
-+ 0x88, 0xfc, 0xa8, 0xa8, 0xfc, 0xd8, 0xac, 0x4c,
-+ 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x01, 0x39, 0x07, 0x79, 0x07, 0x39, 0x02, 0x3c,
-+ 0x01, 0x39, 0x29, 0x29, 0x39, 0x29, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x10, 0xfc, 0x10, 0xa8, 0x44,
-+ 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x7f, 0x02, 0x3b, 0x01, 0x39,
-+ 0x01, 0x39, 0x29, 0x2f, 0x38, 0x28, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xf8, 0xa8, 0xf8, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x38, 0x03, 0x7f, 0x02, 0x3b, 0x02, 0x3b,
-+ 0x02, 0x3a, 0x2a, 0x2a, 0x3c, 0x28, 0x00, 0x00,
-+ 0x40, 0xf8, 0x20, 0xfc, 0x54, 0x8c, 0x70, 0xfc,
-+ 0x70, 0x70, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x39, 0x01, 0x7d, 0x00, 0x3b, 0x02, 0x3b,
-+ 0x00, 0x3f, 0x28, 0x29, 0x3e, 0x28, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xb8, 0xa8, 0xb8,
-+ 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3f, 0x3e, 0x33, 0x5e, 0x0f,
-+ 0x7f, 0x07, 0x07, 0x0f, 0x08, 0x0f, 0x00, 0x00,
-+ 0x20, 0xf8, 0x50, 0xfc, 0x20, 0xfc, 0x20, 0xe0,
-+ 0xfc, 0xc0, 0xc0, 0xe0, 0x20, 0xe0, 0x00, 0x00,
-+ 0x00, 0x3b, 0x02, 0x7f, 0x00, 0x3b, 0x00, 0x3f,
-+ 0x01, 0x3f, 0x28, 0x2b, 0x38, 0x28, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xf8, 0x40, 0xf8, 0x40, 0xfc,
-+ 0x10, 0xfc, 0x40, 0xf8, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x3a, 0x01, 0x79, 0x04, 0x3b, 0x02, 0x38,
-+ 0x06, 0x3a, 0x2a, 0x2a, 0x3d, 0x28, 0x00, 0x00,
-+ 0x20, 0xf8, 0xa8, 0xf8, 0x20, 0xfc, 0xf0, 0x90,
-+ 0xf0, 0xf8, 0x88, 0xf8, 0x80, 0xfc, 0x00, 0x00,
-+ 0x06, 0x1b, 0x13, 0x1c, 0x1e, 0x12, 0x7f, 0x17,
-+ 0x3f, 0x47, 0x07, 0x0f, 0x08, 0x0f, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0xf0, 0xf0, 0x90, 0xfc, 0xd0,
-+ 0xf8, 0xc4, 0xc0, 0xe0, 0x20, 0xe0, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x7f, 0x02, 0x3b, 0x03, 0x39,
-+ 0x01, 0x39, 0x29, 0x29, 0x39, 0x2e, 0x00, 0x00,
-+ 0x40, 0xfc, 0xf0, 0xf8, 0xa8, 0x38, 0xf8, 0xf0,
-+ 0x10, 0xf0, 0xf0, 0xf0, 0x90, 0x08, 0x00, 0x00,
-+ 0x00, 0x38, 0x07, 0x7c, 0x01, 0x3f, 0x01, 0x3b,
-+ 0x05, 0x39, 0x28, 0x2a, 0x3a, 0x2c, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xfc, 0xa0, 0xf0, 0x14, 0xf8, 0xb0,
-+ 0xf4, 0xac, 0x00, 0xa8, 0x54, 0x54, 0x00, 0x00,
-+ 0x14, 0x17, 0x28, 0x3f, 0x68, 0x2b, 0x3c, 0x2b,
-+ 0x28, 0x3f, 0x2a, 0x2b, 0x3e, 0x20, 0x00, 0x00,
-+ 0x14, 0x94, 0x28, 0xfc, 0x68, 0xa8, 0x3c, 0xa8,
-+ 0x28, 0xbc, 0xa8, 0xa8, 0xbc, 0x20, 0x00, 0x00,
-+ 0x00, 0x38, 0x07, 0x7d, 0x01, 0x39, 0x01, 0x3b,
-+ 0x00, 0x3b, 0x29, 0x29, 0x38, 0x2f, 0x00, 0x00,
-+ 0x40, 0xf8, 0xf0, 0x10, 0xf4, 0xb8, 0xe4, 0x7c,
-+ 0xa0, 0xf0, 0x50, 0xf4, 0xac, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x03, 0x7e, 0x03, 0x38, 0x07, 0x3b,
-+ 0x00, 0x3f, 0x29, 0x2f, 0x39, 0x2e, 0x00, 0x00,
-+ 0x40, 0xfc, 0xb8, 0xa8, 0xb8, 0xa0, 0xfc, 0xf8,
-+ 0xa0, 0xfc, 0xa8, 0x30, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x02, 0x3a, 0x02, 0x7d, 0x07, 0x3a, 0x06, 0x3a,
-+ 0x06, 0x3a, 0x2e, 0x2b, 0x3e, 0x28, 0x00, 0x00,
-+ 0xa0, 0xb0, 0xa8, 0x68, 0xfc, 0xa0, 0xe8, 0xa8,
-+ 0xe8, 0xd0, 0x94, 0xfc, 0x4c, 0x84, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x7f, 0x02, 0x3b, 0x00, 0x39,
-+ 0x03, 0x3d, 0x29, 0x29, 0x39, 0x29, 0x00, 0x00,
-+ 0xa0, 0xfc, 0xa0, 0xb8, 0xa8, 0xb8, 0x90, 0xfc,
-+ 0x20, 0xf8, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x03, 0x3b, 0x05, 0x7f, 0x03, 0x3b, 0x05, 0x39,
-+ 0x01, 0x39, 0x29, 0x29, 0x39, 0x2e, 0x00, 0x00,
-+ 0x30, 0xb8, 0x50, 0xfc, 0x30, 0xb4, 0x4c, 0xf0,
-+ 0x10, 0xf0, 0xf0, 0xf0, 0x90, 0x08, 0x00, 0x00,
-+ 0x14, 0x12, 0x22, 0x48, 0x08, 0x14, 0x13, 0x22,
-+ 0x7e, 0x22, 0x22, 0x3f, 0x22, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x90, 0x90, 0x90, 0x90, 0xfc, 0x30,
-+ 0x30, 0x50, 0x90, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x08, 0x3f, 0x2a, 0x7e, 0x09, 0x3e, 0x08, 0x7f,
-+ 0x08, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x00, 0x00,
-+ 0x50, 0x48, 0x88, 0xa0, 0x20, 0x50, 0x50, 0x88,
-+ 0xfc, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x02, 0x3e, 0x29, 0x49, 0x0a, 0x32, 0x0c, 0x0a,
-+ 0x3f, 0x08, 0x7f, 0x0c, 0x12, 0x60, 0x00, 0x00,
-+ 0x50, 0x48, 0x88, 0x20, 0x20, 0x50, 0x50, 0x88,
-+ 0xfc, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x01, 0x11, 0x11, 0x1f, 0x00, 0x7f, 0x00, 0x0f,
-+ 0x08, 0x0f, 0x04, 0x02, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0x10, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0xe0,
-+ 0x20, 0xe0, 0x40, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7e, 0x01, 0x3d, 0x26, 0x24, 0x24, 0x3d,
-+ 0x27, 0x14, 0x18, 0x1c, 0x61, 0x02, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0x80, 0xb8, 0xe8, 0x68,
-+ 0x68, 0xf8, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3e, 0x3e, 0x24, 0x3f, 0x3f,
-+ 0x0f, 0x08, 0x0f, 0x04, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x50, 0x20, 0xd0, 0x0c, 0xf8,
-+ 0xe0, 0x20, 0xe0, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x25, 0x2f, 0x25, 0x2f, 0x2f, 0x25, 0x3f, 0x7f,
-+ 0x0f, 0x08, 0x0f, 0x04, 0x7f, 0x00, 0x00, 0x00,
-+ 0x48, 0xe8, 0x48, 0xe8, 0xe8, 0x48, 0xf8, 0xfc,
-+ 0xe0, 0x20, 0xe0, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x02, 0x0e, 0x73, 0x05, 0x19,
-+ 0x62, 0x04, 0x18, 0x60, 0x01, 0x06, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0x48, 0x48, 0x50, 0xa0,
-+ 0xa0, 0x90, 0x88, 0x84, 0x00, 0x00, 0x00, 0x00,
-+ 0x09, 0x09, 0x1f, 0x02, 0x7f, 0x04, 0x1f, 0x63,
-+ 0x3d, 0x06, 0x39, 0x06, 0x38, 0x03, 0x00, 0x00,
-+ 0x20, 0x10, 0xf8, 0x80, 0xfc, 0x40, 0xf0, 0x1c,
-+ 0x90, 0xa0, 0xe0, 0x98, 0x84, 0x00, 0x00, 0x00,
-+ 0x00, 0x7e, 0x11, 0x10, 0x32, 0x4b, 0x1c, 0x2c,
-+ 0x4a, 0x1b, 0x2a, 0x48, 0x08, 0x30, 0x00, 0x00,
-+ 0x40, 0x48, 0xf8, 0x50, 0x50, 0xfc, 0x30, 0x48,
-+ 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x00, 0x03, 0x3c, 0x02, 0x03, 0x7c, 0x01,
-+ 0x06, 0x38, 0x01, 0x06, 0x38, 0x01, 0x00, 0x00,
-+ 0x40, 0x80, 0x88, 0x50, 0x60, 0x80, 0x80, 0x40,
-+ 0x60, 0xa0, 0x20, 0x20, 0x40, 0x80, 0x00, 0x00,
-+ 0x04, 0x18, 0x6a, 0x24, 0x1b, 0x70, 0x08, 0x1c,
-+ 0x64, 0x0c, 0x15, 0x66, 0x04, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x10, 0xfc, 0x30, 0x30, 0x50,
-+ 0x50, 0x90, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x04, 0x19, 0x6a, 0x24, 0x18, 0x68, 0x0d, 0x14,
-+ 0x65, 0x0d, 0x15, 0x65, 0x05, 0x19, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x88, 0x30, 0x00,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x18, 0x6a, 0x24, 0x19, 0x6a, 0x0c, 0x15,
-+ 0x66, 0x0d, 0x15, 0x65, 0x05, 0x19, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x88, 0x90, 0x60, 0x60, 0x90,
-+ 0x0c, 0xf8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x09, 0x11, 0x6d, 0x29, 0x13, 0x72, 0x1e, 0x2a,
-+ 0x4a, 0x1a, 0x2b, 0x4a, 0x0a, 0x32, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x70, 0x70,
-+ 0xa8, 0xa8, 0x24, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x04, 0x19, 0x6a, 0x24, 0x18, 0x68, 0x0c, 0x14,
-+ 0x64, 0x0c, 0x14, 0x64, 0x04, 0x18, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x40, 0xf8, 0x88, 0x88,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x04, 0x19, 0x6b, 0x25, 0x19, 0x69, 0x0d, 0x15,
-+ 0x64, 0x0d, 0x14, 0x64, 0x07, 0x18, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x19, 0x6b, 0x25, 0x19, 0x69, 0x0d, 0x15,
-+ 0x64, 0x0c, 0x14, 0x64, 0x05, 0x1a, 0x00, 0x00,
-+ 0x40, 0xb8, 0x08, 0x08, 0xb8, 0x08, 0x08, 0xf8,
-+ 0xa0, 0xa0, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x04, 0x18, 0x6b, 0x25, 0x19, 0x69, 0x0d, 0x15,
-+ 0x65, 0x0d, 0x15, 0x65, 0x05, 0x1e, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x28, 0xe8, 0x58, 0x88, 0xf8,
-+ 0x24, 0xf8, 0x20, 0x24, 0xe4, 0x1c, 0x00, 0x00,
-+ 0x05, 0x19, 0x6b, 0x25, 0x19, 0x69, 0x0d, 0x15,
-+ 0x65, 0x0d, 0x15, 0x65, 0x05, 0x1e, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x24, 0xe8, 0x30, 0x20,
-+ 0x20, 0x20, 0x24, 0x64, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x04, 0x1b, 0x68, 0x25, 0x19, 0x69, 0x0d, 0x15,
-+ 0x64, 0x0f, 0x14, 0x64, 0x05, 0x1e, 0x00, 0x00,
-+ 0x90, 0xfc, 0x90, 0xf8, 0x08, 0xf8, 0x08, 0xf8,
-+ 0x40, 0xfc, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x23, 0x3e, 0x22,
-+ 0x22, 0x3e, 0x14, 0x12, 0x23, 0x42, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0x40, 0x7c, 0xc8, 0x48, 0x50,
-+ 0x30, 0x20, 0x54, 0x94, 0x0c, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x1f, 0x10, 0x17, 0x14, 0x17,
-+ 0x14, 0x17, 0x24, 0x27, 0x43, 0x1c, 0x00, 0x00,
-+ 0x18, 0xe0, 0x80, 0xfc, 0x80, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x10, 0xf0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x01, 0x02, 0x0f, 0x70, 0x0f, 0x00, 0x0f, 0x08,
-+ 0x0f, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0x80, 0xe0, 0x1c, 0xe0, 0x40, 0xe0, 0x20,
-+ 0xe0, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x3f, 0x22,
-+ 0x22, 0x3e, 0x14, 0x12, 0x22, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x50, 0x48, 0x88, 0xf4, 0x04,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x2f, 0x28, 0x2e, 0x78, 0x0f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x80, 0x98, 0xe0, 0x84, 0x7c, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x7f, 0x1f, 0x00, 0x7f, 0x1f, 0x11,
-+ 0x1f, 0x1f, 0x11, 0x1f, 0x19, 0x60, 0x00, 0x00,
-+ 0x50, 0x48, 0xfc, 0x40, 0x40, 0xc0, 0x40, 0x40,
-+ 0x20, 0x20, 0x14, 0x14, 0x0c, 0x84, 0x00, 0x00,
-+ 0x00, 0x1f, 0x00, 0x7f, 0x00, 0x1f, 0x11, 0x1f,
-+ 0x11, 0x1f, 0x11, 0x1f, 0x19, 0x60, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0xfc, 0x40, 0x40, 0x40, 0x40,
-+ 0x20, 0x20, 0x14, 0x14, 0x0c, 0x84, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x24, 0x3c, 0x27, 0x3c, 0x24,
-+ 0x24, 0x3c, 0x19, 0x15, 0x22, 0x44, 0x00, 0x00,
-+ 0x08, 0x30, 0xc0, 0x40, 0x40, 0xf8, 0x08, 0x10,
-+ 0x10, 0x20, 0x40, 0x80, 0x40, 0x3c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x04, 0x3f, 0x24, 0x3f, 0x0f, 0x08,
-+ 0x0f, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0xe0, 0x20,
-+ 0xe0, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x01, 0x1f, 0x05, 0x7f, 0x04, 0x0f, 0x08, 0x0f,
-+ 0x08, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xf0, 0x40, 0xfc, 0x40, 0xe0, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x27, 0x3c, 0x24, 0x3d, 0x24,
-+ 0x24, 0x3f, 0x18, 0x14, 0x24, 0x43, 0x00, 0x00,
-+ 0x50, 0x48, 0x7c, 0xc8, 0x30, 0x74, 0x8c, 0x54,
-+ 0x7c, 0xc8, 0x30, 0x34, 0xcc, 0x04, 0x00, 0x00,
-+ 0x01, 0x7f, 0x1f, 0x3f, 0x24, 0x3f, 0x0f, 0x08,
-+ 0x0f, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf0, 0xf8, 0x48, 0xf8, 0xe0, 0x20,
-+ 0xe0, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x01, 0x7f, 0x09, 0x17, 0x25, 0x19, 0x6f, 0x08,
-+ 0x0f, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0xa8, 0x48, 0x30, 0xec, 0x20,
-+ 0xe0, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x01, 0x3f, 0x24, 0x7f, 0x1f, 0x04, 0x7f, 0x0f,
-+ 0x18, 0x6f, 0x0f, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xfc, 0xf0, 0x40, 0xfc, 0xe0,
-+ 0x30, 0xec, 0xe0, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x00, 0x3d, 0x27, 0x24, 0x3f, 0x24, 0x3f, 0x24,
-+ 0x27, 0x3d, 0x19, 0x16, 0x24, 0x40, 0x00, 0x00,
-+ 0x48, 0xb0, 0xfc, 0xa0, 0xf8, 0xa8, 0xfc, 0xa8,
-+ 0xf8, 0xb0, 0xb0, 0xa8, 0xa4, 0xa0, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x25, 0x3d, 0x25, 0x3d, 0x25,
-+ 0x25, 0x3c, 0x1b, 0x15, 0x24, 0x40, 0x00, 0x00,
-+ 0x50, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48, 0xf8,
-+ 0x48, 0x10, 0xfc, 0x10, 0x90, 0x30, 0x00, 0x00,
-+ 0x08, 0x3e, 0x7f, 0x14, 0x7f, 0x3e, 0x09, 0x0f,
-+ 0x08, 0x0f, 0x0f, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x40, 0x40, 0xf0, 0x50, 0xd4, 0xb4, 0x0c, 0xe0,
-+ 0x20, 0xe0, 0xe0, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x08, 0x3e, 0x7e, 0x09, 0x7f, 0x1e, 0x27, 0x4f,
-+ 0x08, 0x0f, 0x0f, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x90, 0x50, 0x70, 0x8c, 0xe0,
-+ 0x20, 0xe0, 0xe0, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x14, 0x1f, 0x25, 0x7f, 0x16, 0x25, 0x4f, 0x08,
-+ 0x0f, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0xa0, 0xf8, 0x20, 0xfc, 0x50, 0x94, 0xec, 0x20,
-+ 0xe0, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x08, 0x7f, 0x12, 0x0d, 0x1d, 0x63, 0x0f, 0x08,
-+ 0x0f, 0x0f, 0x08, 0x0f, 0x06, 0x38, 0x00, 0x00,
-+ 0xd4, 0xfc, 0x70, 0x50, 0x74, 0x8c, 0xe4, 0x20,
-+ 0xe0, 0xe0, 0x20, 0xe0, 0x60, 0x18, 0x00, 0x00,
-+ 0x01, 0x7f, 0x08, 0x07, 0x1f, 0x10, 0x1f, 0x3b,
-+ 0x2a, 0x3b, 0x2b, 0x3b, 0x2b, 0x5c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0xf0, 0x10, 0xf0, 0xb8,
-+ 0xa8, 0xb8, 0xb8, 0xac, 0x4c, 0x84, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x25, 0x3d, 0x25, 0x3d, 0x25,
-+ 0x25, 0x3d, 0x1a, 0x16, 0x24, 0x40, 0x00, 0x00,
-+ 0x40, 0xf0, 0x20, 0xfc, 0x54, 0x8c, 0x70, 0xfc,
-+ 0x70, 0x70, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3d, 0x24, 0x27, 0x3d, 0x24, 0x3f, 0x25,
-+ 0x26, 0x3d, 0x19, 0x15, 0x27, 0x40, 0x00, 0x00,
-+ 0x40, 0xf8, 0x48, 0xfc, 0xf8, 0x40, 0xfc, 0xa8,
-+ 0x54, 0xf8, 0x68, 0x68, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x7f, 0x3e, 0x15, 0x1d, 0x3f, 0x5f, 0x17,
-+ 0x14, 0x17, 0x17, 0x17, 0x22, 0x4c, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf8, 0x50, 0x78, 0xf4, 0xf0, 0xd0,
-+ 0x50, 0xd0, 0xd0, 0xd0, 0x90, 0x50, 0x00, 0x00,
-+ 0x00, 0x38, 0x2d, 0x2d, 0x3d, 0x2f, 0x39, 0x2f,
-+ 0x2d, 0x3d, 0x15, 0x1a, 0x2a, 0x44, 0x00, 0x00,
-+ 0x18, 0x14, 0xfc, 0x10, 0xf4, 0xd4, 0xf4, 0xb8,
-+ 0xf8, 0xdc, 0xfc, 0x9c, 0x24, 0x44, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x25, 0x3d, 0x25, 0x3d, 0x25,
-+ 0x25, 0x3d, 0x1a, 0x16, 0x27, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0x20, 0x20, 0xf8, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x0f, 0x08, 0x0f, 0x0f, 0x0f, 0x18, 0x3e,
-+ 0x22, 0x3e, 0x3e, 0x3e, 0x14, 0x63, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0xe0, 0xe0, 0x30, 0xf8,
-+ 0x88, 0xf8, 0xf8, 0xf8, 0x48, 0x84, 0x00, 0x00,
-+ 0x00, 0x3d, 0x24, 0x25, 0x3d, 0x25, 0x3d, 0x24,
-+ 0x24, 0x3c, 0x18, 0x14, 0x24, 0x43, 0x00, 0x00,
-+ 0x20, 0xfc, 0xf8, 0xfc, 0x54, 0x9c, 0xfc, 0xf8,
-+ 0x88, 0xf8, 0xf8, 0xf8, 0xc8, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x3e, 0x08, 0x08, 0x7f, 0x14, 0x36,
-+ 0x36, 0x35, 0x55, 0x14, 0x24, 0x4c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x80, 0xf8, 0xc8,
-+ 0xa8, 0xb0, 0x90, 0xb0, 0xc8, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x3f, 0x08, 0x08, 0x7f, 0x14, 0x36,
-+ 0x37, 0x35, 0x55, 0x14, 0x24, 0x4c, 0x00, 0x00,
-+ 0x40, 0x48, 0xf8, 0x50, 0x50, 0xfc, 0x50, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x01, 0x01, 0x7f, 0x08, 0x04,
-+ 0x04, 0x10, 0x1b, 0x14, 0x23, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x00, 0x00, 0xfc, 0x20, 0x20,
-+ 0x40, 0x80, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x3e, 0x08, 0x08, 0x7f, 0x08, 0x28,
-+ 0x2e, 0x29, 0x38, 0x28, 0x46, 0x41, 0x00, 0x00,
-+ 0x10, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x9c,
-+ 0xf0, 0x90, 0x10, 0x10, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x3e, 0x08, 0x08, 0x7f, 0x08, 0x28,
-+ 0x2e, 0x28, 0x38, 0x28, 0x47, 0x41, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x24, 0x40, 0x90,
-+ 0x24, 0xc8, 0x10, 0x60, 0x80, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x3e, 0x09, 0x08, 0x7f, 0x08, 0x28,
-+ 0x2e, 0x28, 0x38, 0x28, 0x46, 0x41, 0x00, 0x00,
-+ 0x20, 0xa8, 0xa4, 0x24, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0x88, 0x98, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x23, 0x3e, 0x08, 0x29, 0x2e,
-+ 0x28, 0x28, 0x2e, 0x38, 0x61, 0x06, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0x88,
-+ 0x50, 0x50, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x08, 0x28, 0x2e,
-+ 0x28, 0x28, 0x2e, 0x38, 0x63, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xa0, 0xbc, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0xa0, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x08, 0x29, 0x2e,
-+ 0x28, 0x28, 0x2e, 0x38, 0x61, 0x06, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x01, 0x3d, 0x25, 0x27, 0x3d, 0x09, 0x29, 0x2d,
-+ 0x29, 0x29, 0x2e, 0x3a, 0x64, 0x09, 0x00, 0x00,
-+ 0x00, 0x00, 0x1c, 0xd4, 0x54, 0x54, 0x54, 0x54,
-+ 0x54, 0x54, 0x54, 0x5c, 0x54, 0x80, 0x00, 0x00,
-+ 0x00, 0x7b, 0x4a, 0x4a, 0x7a, 0x12, 0x57, 0x5e,
-+ 0x52, 0x52, 0x5e, 0x72, 0x42, 0x02, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xa8, 0xa8, 0xfc, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x22, 0x3e, 0x08, 0x28, 0x2f,
-+ 0x29, 0x2a, 0x28, 0x2e, 0x38, 0x60, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x40, 0x80, 0xf8, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x09, 0x2b, 0x2e,
-+ 0x28, 0x28, 0x2e, 0x38, 0x61, 0x06, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xf8, 0xa0, 0x20, 0xfc, 0x20,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x25, 0x3d, 0x09, 0x29, 0x2f,
-+ 0x29, 0x29, 0x2e, 0x3a, 0x65, 0x0e, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x28, 0x20, 0x20, 0xf8, 0x88,
-+ 0x50, 0x50, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x23, 0x3e, 0x08, 0x28, 0x2e,
-+ 0x28, 0x28, 0x2f, 0x3a, 0x64, 0x0b, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0xfc, 0x40, 0x48, 0x48, 0xc8,
-+ 0xb0, 0xb0, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x27, 0x3d, 0x09, 0x29, 0x2f,
-+ 0x29, 0x29, 0x2e, 0x3a, 0x64, 0x08, 0x00, 0x00,
-+ 0x40, 0x78, 0x90, 0x20, 0xfc, 0x00, 0x78, 0x48,
-+ 0x48, 0x70, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x09, 0x09, 0x0f, 0x71, 0x02, 0x1f,
-+ 0x10, 0x1f, 0x09, 0x09, 0x15, 0x63, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x90, 0x54, 0x54, 0x0c, 0xf0,
-+ 0x10, 0xf0, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x08, 0x28, 0x2e,
-+ 0x28, 0x28, 0x28, 0x2e, 0x38, 0x63, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0xf8, 0xa4,
-+ 0xa4, 0xa8, 0x90, 0xb0, 0xc8, 0x04, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x09, 0x29, 0x2e,
-+ 0x28, 0x28, 0x2e, 0x38, 0x61, 0x02, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xf8, 0xa0, 0x20, 0xfc, 0x50,
-+ 0x50, 0x50, 0x90, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x3d, 0x09, 0x29, 0x2f,
-+ 0x29, 0x29, 0x2e, 0x3a, 0x64, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x00, 0xfc, 0x04,
-+ 0xf4, 0x94, 0xf4, 0x94, 0x04, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x23, 0x22, 0x3e, 0x08, 0x28, 0x2e,
-+ 0x28, 0x28, 0x2e, 0x39, 0x62, 0x00, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0xa8, 0xa8, 0xf8,
-+ 0x70, 0x70, 0xa8, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x28, 0x08, 0x2e,
-+ 0x28, 0x28, 0x28, 0x2e, 0x38, 0x63, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0xf8,
-+ 0xa4, 0xa8, 0x90, 0xb0, 0xc8, 0x04, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x09, 0x28, 0x2e,
-+ 0x28, 0x28, 0x2f, 0x39, 0x62, 0x04, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x20, 0xa0,
-+ 0xb8, 0xa0, 0xa0, 0x60, 0x30, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x08, 0x28, 0x2e,
-+ 0x29, 0x28, 0x2e, 0x39, 0x62, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xf8, 0xa8, 0xf8, 0x20,
-+ 0xfc, 0x70, 0xa8, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x3d, 0x09, 0x29, 0x2f,
-+ 0x29, 0x29, 0x2e, 0x3a, 0x64, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x28, 0x20, 0xfc,
-+ 0x20, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x23, 0x3e, 0x08, 0x29, 0x2e,
-+ 0x28, 0x29, 0x2e, 0x38, 0x60, 0x03, 0x00, 0x00,
-+ 0x50, 0x48, 0x7c, 0xc8, 0x30, 0x74, 0x8c, 0x54,
-+ 0x7c, 0xc8, 0x30, 0x24, 0xdc, 0x04, 0x00, 0x00,
-+ 0x01, 0x3d, 0x25, 0x25, 0x3d, 0x0a, 0x28, 0x2f,
-+ 0x28, 0x28, 0x2f, 0x39, 0x62, 0x04, 0x00, 0x00,
-+ 0x00, 0x00, 0x38, 0xe8, 0xa8, 0xa8, 0xa8, 0xe8,
-+ 0xa8, 0xa8, 0x68, 0x78, 0x28, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3f, 0x28, 0x09, 0x2e,
-+ 0x28, 0x29, 0x28, 0x2e, 0x39, 0x60, 0x00, 0x00,
-+ 0x00, 0xf8, 0x50, 0x20, 0xfc, 0x68, 0xa0, 0x60,
-+ 0x20, 0xfc, 0x70, 0xa8, 0x24, 0x20, 0x00, 0x00,
-+ 0x00, 0x3e, 0x23, 0x22, 0x3e, 0x08, 0x28, 0x2e,
-+ 0x28, 0x28, 0x2e, 0x38, 0x63, 0x00, 0x00, 0x00,
-+ 0x18, 0xe0, 0xfc, 0x20, 0xf8, 0xa8, 0xf8, 0xa8,
-+ 0xf8, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x25, 0x3e, 0x28, 0x0b, 0x2e,
-+ 0x2b, 0x2a, 0x2b, 0x2e, 0x3a, 0x62, 0x00, 0x00,
-+ 0xe0, 0x60, 0x90, 0x08, 0xf4, 0x00, 0xa8, 0xa8,
-+ 0xa8, 0xd0, 0xd0, 0xa8, 0xa8, 0xa8, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x22, 0x3e, 0x28, 0x08, 0x2e,
-+ 0x28, 0x28, 0x2b, 0x2c, 0x38, 0x63, 0x00, 0x00,
-+ 0x00, 0xf8, 0x50, 0x20, 0xf8, 0xa8, 0xf8, 0xa8,
-+ 0xf8, 0x20, 0xfc, 0x44, 0x84, 0x18, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x3e, 0x09, 0x28, 0x2e,
-+ 0x29, 0x28, 0x2f, 0x38, 0x61, 0x06, 0x00, 0x00,
-+ 0x18, 0xf0, 0x48, 0x24, 0x54, 0x90, 0x60, 0x50,
-+ 0xf8, 0x40, 0xfc, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x3f, 0x24, 0x7f, 0x1f, 0x04, 0x7f, 0x0f,
-+ 0x14, 0x67, 0x09, 0x09, 0x17, 0x61, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xf8, 0xf0, 0x40, 0xfc, 0xe0,
-+ 0x50, 0xcc, 0x00, 0xe0, 0x00, 0xfc, 0x00, 0x00,
-+ 0x01, 0x3c, 0x27, 0x24, 0x3d, 0x08, 0x2b, 0x2c,
-+ 0x28, 0x28, 0x2f, 0x3a, 0x67, 0x00, 0x00, 0x00,
-+ 0x10, 0xa0, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0x80,
-+ 0xf8, 0xa0, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x25, 0x3e, 0x09, 0x29, 0x2f,
-+ 0x29, 0x29, 0x2f, 0x3b, 0x65, 0x01, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0xf0, 0x08, 0xf4, 0x10, 0xf0,
-+ 0xf0, 0x00, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x27, 0x3c, 0x29, 0x0b, 0x2f,
-+ 0x29, 0x29, 0x29, 0x2f, 0x39, 0x61, 0x00, 0x00,
-+ 0x40, 0x58, 0x40, 0x58, 0xa0, 0x10, 0xf8, 0x14,
-+ 0xf0, 0x10, 0xf0, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x3e, 0x28, 0x09, 0x2f,
-+ 0x29, 0x29, 0x29, 0x2f, 0x39, 0x61, 0x00, 0x00,
-+ 0x18, 0xf0, 0x48, 0x24, 0x24, 0x40, 0xb8, 0x08,
-+ 0x08, 0xb8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x13, 0x1f, 0x17, 0x1a, 0x22,
-+ 0x4f, 0x08, 0x0f, 0x09, 0x17, 0x21, 0x00, 0x00,
-+ 0x50, 0xfc, 0x48, 0xa8, 0xf0, 0x30, 0xd4, 0x0c,
-+ 0xe4, 0x20, 0xe0, 0xf0, 0x00, 0xf8, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x26, 0x3c, 0x08, 0x29, 0x2f,
-+ 0x2b, 0x29, 0x29, 0x2f, 0x39, 0x61, 0x00, 0x00,
-+ 0xa8, 0xa8, 0x28, 0x54, 0xd4, 0x90, 0x10, 0x50,
-+ 0x5c, 0x50, 0x50, 0xb0, 0x90, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x25, 0x3d, 0x09, 0x29, 0x2d,
-+ 0x29, 0x29, 0x2e, 0x3b, 0x65, 0x0a, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x50, 0x50, 0xfc, 0x50, 0x50,
-+ 0x70, 0x50, 0x00, 0xa8, 0x54, 0x54, 0x00, 0x00,
-+ 0x00, 0x3e, 0x23, 0x23, 0x3e, 0x28, 0x08, 0x2f,
-+ 0x28, 0x28, 0x28, 0x2d, 0x3a, 0x60, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0x00, 0xf8, 0x00, 0xfc,
-+ 0x20, 0xb0, 0xa8, 0x24, 0x24, 0x60, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x24, 0x3c, 0x28, 0x0b, 0x2e,
-+ 0x2b, 0x2a, 0x2a, 0x2f, 0x3a, 0x62, 0x00, 0x00,
-+ 0xa0, 0xa0, 0xfc, 0xa0, 0xe0, 0x40, 0xf8, 0x48,
-+ 0xf8, 0xd8, 0xd8, 0x68, 0x48, 0x58, 0x00, 0x00,
-+ 0x00, 0x3f, 0x26, 0x27, 0x3e, 0x2b, 0x09, 0x2f,
-+ 0x29, 0x2b, 0x28, 0x2f, 0x38, 0x60, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x50, 0xfc,
-+ 0x50, 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x3f, 0x27, 0x26, 0x3e, 0x0b, 0x2a, 0x2f,
-+ 0x2b, 0x2b, 0x2f, 0x3c, 0x65, 0x0a, 0x00, 0x00,
-+ 0x00, 0xfc, 0x30, 0xb0, 0xd0, 0xfc, 0xb4, 0xf8,
-+ 0xd0, 0xd0, 0x98, 0xa8, 0x24, 0x44, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x26, 0x3d, 0x29, 0x09, 0x2f,
-+ 0x29, 0x28, 0x2b, 0x2c, 0x38, 0x60, 0x00, 0x00,
-+ 0xf0, 0x90, 0xf8, 0x64, 0xf8, 0x78, 0x98, 0xf8,
-+ 0xf8, 0x10, 0xfc, 0x90, 0x50, 0x30, 0x00, 0x00,
-+ 0x00, 0x3e, 0x25, 0x27, 0x3d, 0x08, 0x2b, 0x2c,
-+ 0x29, 0x28, 0x2f, 0x38, 0x61, 0x06, 0x00, 0x00,
-+ 0xa0, 0xa8, 0xb0, 0xfc, 0x10, 0xa0, 0xf8, 0x40,
-+ 0xf0, 0x40, 0xfc, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x09, 0x29, 0x2f,
-+ 0x28, 0x29, 0x2e, 0x38, 0x63, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x00, 0xdc, 0x54, 0xdc,
-+ 0x20, 0xfc, 0x70, 0xa8, 0x24, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x3d, 0x28, 0x0b, 0x2e,
-+ 0x28, 0x2b, 0x28, 0x2e, 0x38, 0x60, 0x00, 0x00,
-+ 0x90, 0xfc, 0x90, 0x48, 0xf8, 0x50, 0xfc, 0x50,
-+ 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x3c, 0x09, 0x29, 0x2f,
-+ 0x29, 0x29, 0x2e, 0x38, 0x63, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x68, 0xf8, 0x80, 0xfc, 0x44, 0xf4,
-+ 0x54, 0xf4, 0x54, 0x7c, 0x8c, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3f, 0x3e, 0x32, 0x5e, 0x1f,
-+ 0x08, 0x0f, 0x09, 0x09, 0x17, 0x21, 0x00, 0x00,
-+ 0x20, 0xf8, 0x50, 0xfc, 0x20, 0xf8, 0x20, 0xe0,
-+ 0x20, 0xe0, 0x00, 0xf0, 0x00, 0xf8, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x27, 0x3e, 0x0b, 0x2c, 0x2f,
-+ 0x29, 0x29, 0x2f, 0x39, 0x62, 0x04, 0x00, 0x00,
-+ 0x40, 0xfc, 0xa8, 0xf0, 0xe8, 0xf8, 0x64, 0x10,
-+ 0xf0, 0x10, 0xf0, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x25, 0x3f, 0x29, 0x08, 0x2f,
-+ 0x2b, 0x28, 0x2b, 0x2e, 0x3b, 0x62, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0xfc, 0xe8, 0x40, 0xf0,
-+ 0xfc, 0x08, 0xfc, 0xc8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x25, 0x3d, 0x2a, 0x09, 0x2f,
-+ 0x29, 0x29, 0x2f, 0x39, 0x61, 0x06, 0x00, 0x00,
-+ 0x48, 0xb0, 0x20, 0xfc, 0x68, 0x48, 0xf0, 0x10,
-+ 0xf0, 0xf0, 0x10, 0xf0, 0x90, 0x08, 0x00, 0x00,
-+ 0x02, 0x7a, 0x4f, 0x49, 0x7f, 0x15, 0x56, 0x5f,
-+ 0x57, 0x51, 0x5f, 0x72, 0x44, 0x08, 0x00, 0x00,
-+ 0x80, 0x78, 0xe8, 0xa8, 0xf0, 0xf0, 0xe8, 0xe8,
-+ 0xe4, 0x24, 0xe4, 0xb8, 0x60, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x26, 0x26, 0x3e, 0x0a, 0x2a, 0x2e,
-+ 0x2b, 0x2a, 0x2f, 0x3c, 0x6b, 0x00, 0x00, 0x00,
-+ 0x20, 0xfc, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0xf8,
-+ 0xfc, 0xac, 0xfc, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x26, 0x27, 0x3e, 0x2b, 0x0a, 0x2e,
-+ 0x2b, 0x2a, 0x2a, 0x2e, 0x3a, 0x62, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0xa8, 0xb8, 0x68, 0xf8,
-+ 0xa8, 0xf8, 0xf8, 0xa8, 0xf8, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x27, 0x3e, 0x2b, 0x0b, 0x2e,
-+ 0x2a, 0x2b, 0x2a, 0x2e, 0x3a, 0x62, 0x00, 0x00,
-+ 0xa0, 0xfc, 0xa0, 0xb8, 0xa8, 0xb8, 0xb8, 0x68,
-+ 0xf8, 0xf8, 0xf8, 0xa8, 0xf8, 0x18, 0x00, 0x00,
-+ 0x00, 0x3d, 0x24, 0x24, 0x3c, 0x09, 0x28, 0x2f,
-+ 0x2a, 0x2b, 0x2f, 0x3b, 0x66, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x90, 0xf0, 0xf0, 0xf0, 0x10, 0xfc,
-+ 0xa8, 0xb8, 0xb8, 0xb8, 0xe8, 0x88, 0x00, 0x00,
-+ 0x08, 0x11, 0x3c, 0x24, 0x3d, 0x25, 0x3d, 0x27,
-+ 0x7d, 0x0d, 0x14, 0x64, 0x04, 0x0c, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x10, 0x00, 0xf8,
-+ 0x08, 0x08, 0x08, 0x08, 0x10, 0x60, 0x00, 0x00,
-+ 0x08, 0x10, 0x3c, 0x27, 0x3c, 0x24, 0x3d, 0x27,
-+ 0x7e, 0x0d, 0x14, 0x64, 0x04, 0x0c, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0xe0, 0xe0, 0x50, 0x50,
-+ 0x48, 0xf4, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x13, 0x3e, 0x27, 0x3e, 0x27, 0x3c, 0x27,
-+ 0x7d, 0x0d, 0x15, 0x64, 0x07, 0x0c, 0x00, 0x00,
-+ 0xa0, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0x00, 0xfc,
-+ 0xf0, 0x10, 0xf0, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x11, 0x3c, 0x24, 0x3c, 0x25, 0x3e, 0x26,
-+ 0x7f, 0x0c, 0x15, 0x66, 0x04, 0x0c, 0x00, 0x00,
-+ 0x00, 0xe0, 0xa0, 0xb8, 0xa8, 0x08, 0x70, 0x40,
-+ 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x40, 0x00, 0x00,
-+ 0x09, 0x10, 0x3f, 0x24, 0x3d, 0x24, 0x3f, 0x26,
-+ 0x7c, 0x0f, 0x14, 0x64, 0x05, 0x0e, 0x00, 0x00,
-+ 0x10, 0xa0, 0xf8, 0x40, 0xf0, 0x40, 0xfc, 0x40,
-+ 0x40, 0xfc, 0x40, 0xa0, 0x10, 0x0c, 0x00, 0x00,
-+ 0x08, 0x13, 0x3a, 0x2a, 0x3a, 0x2b, 0x3b, 0x2f,
-+ 0x7b, 0x1b, 0x2d, 0x4d, 0x09, 0x19, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa8, 0xa8, 0xb0, 0x7c, 0xd0, 0x78,
-+ 0x50, 0x78, 0x50, 0x50, 0x7c, 0x40, 0x00, 0x00,
-+ 0x08, 0x13, 0x3a, 0x2a, 0x3b, 0x2b, 0x3b, 0x2f,
-+ 0x7b, 0x1a, 0x2d, 0x4d, 0x0a, 0x18, 0x00, 0x00,
-+ 0x40, 0xfc, 0xa8, 0xfc, 0xd0, 0x78, 0x78, 0x50,
-+ 0x7c, 0x40, 0xa8, 0xa4, 0x94, 0x70, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x09, 0x0a, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xf8, 0xc8, 0xc8, 0xc8,
-+ 0xd8, 0xc0, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x01, 0x3f, 0x0f, 0x09, 0x0f, 0x09, 0x0f, 0x7f,
-+ 0x01, 0x31, 0x0c, 0x06, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xf8, 0xe0, 0x20, 0xe0, 0x20, 0xe0, 0xfc,
-+ 0x00, 0x18, 0x60, 0xc0, 0x30, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x2a, 0x3f, 0x2b,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xa0, 0xf8, 0xa0, 0x20, 0xfc,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x7f, 0x08, 0x3e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x08, 0x08, 0xe8, 0xa8, 0xa8, 0xa8,
-+ 0xe8, 0xa8, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x2b, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7e, 0x08, 0x08, 0x09, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x24, 0xc0, 0x10,
-+ 0x20, 0xc4, 0x08, 0x10, 0x60, 0x80, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x09, 0x3e, 0x2a, 0x3f, 0x2a,
-+ 0x3e, 0x08, 0x7e, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x28, 0x24, 0x24, 0xfc, 0x20, 0x20, 0xe0, 0xa0,
-+ 0x90, 0x90, 0xb4, 0xcc, 0x0c, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x7f, 0x08, 0x3e, 0x2b, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x09, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x30, 0x48, 0xf4, 0x24, 0x20,
-+ 0xf8, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x2b, 0x3e, 0x2a,
-+ 0x3f, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0xd0, 0x20, 0x50, 0x88,
-+ 0xfc, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x09, 0x7f, 0x08, 0x3f, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x09, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa8, 0xa8, 0x50, 0xa8, 0xa8, 0x00,
-+ 0xf8, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x0b, 0x7f, 0x09, 0x3d, 0x2d, 0x3d, 0x2d,
-+ 0x3d, 0x09, 0x7f, 0x0b, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x50, 0x50, 0xd0, 0x50, 0x50, 0xd0,
-+ 0x50, 0x50, 0xd4, 0x54, 0x54, 0x4c, 0x00, 0x00,
-+ 0x08, 0x0b, 0x7f, 0x09, 0x3f, 0x2b, 0x3f, 0x2b,
-+ 0x3f, 0x09, 0x7f, 0x0b, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0xf8, 0x68, 0x68, 0xe8,
-+ 0x50, 0x50, 0xd8, 0x68, 0x44, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x09, 0x3e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x40, 0x78, 0x90, 0x20, 0xf8, 0xa8, 0xa8, 0xa8,
-+ 0xf8, 0x50, 0x50, 0x94, 0x14, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x09, 0x3e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0xa8, 0xa8, 0x50, 0x50, 0xa8, 0xa8, 0x00, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0xa8, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x09, 0x7e, 0x09, 0x3e, 0x2a, 0x3f, 0x2b,
-+ 0x3e, 0x09, 0x7f, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x68, 0x90, 0xd8, 0x24, 0xf8,
-+ 0x68, 0x68, 0x90, 0x90, 0x68, 0x44, 0x00, 0x00,
-+ 0x10, 0x13, 0x7c, 0x10, 0x7f, 0x56, 0x7f, 0x56,
-+ 0x7e, 0x13, 0x7e, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0xf8, 0x48, 0xf8, 0xd8,
-+ 0xd8, 0x68, 0x48, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x10, 0x13, 0x7c, 0x10, 0x7f, 0x56, 0x7f, 0x57,
-+ 0x7f, 0x13, 0x7f, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0xf8, 0x48, 0x58, 0x58,
-+ 0x58, 0xf8, 0x18, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x3e, 0x08, 0x7f, 0x14, 0x23, 0x5f, 0x0f,
-+ 0x09, 0x0f, 0x09, 0x0f, 0x7f, 0x01, 0x00, 0x00,
-+ 0x20, 0xf8, 0x20, 0xfc, 0x50, 0x88, 0xf4, 0xe0,
-+ 0x20, 0xe0, 0x20, 0xe0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x2a, 0x3f, 0x2a,
-+ 0x3e, 0x09, 0x7e, 0x08, 0x08, 0x09, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x50,
-+ 0xf8, 0x24, 0xf8, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x08, 0x09, 0x7e, 0x08, 0x3e, 0x2a, 0x3e, 0x2a,
-+ 0x3f, 0x09, 0x7f, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xf0, 0x90, 0x90, 0xf0, 0x00,
-+ 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x09, 0x3e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x0b, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0xf0, 0x90, 0xf0, 0x90, 0xf0,
-+ 0x40, 0xf8, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x7e, 0x09, 0x3e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x09, 0x00, 0x00,
-+ 0x20, 0xf8, 0x20, 0xfc, 0x00, 0xf8, 0x88, 0xf8,
-+ 0x24, 0x64, 0xd8, 0x50, 0x68, 0x84, 0x00, 0x00,
-+ 0x08, 0x7f, 0x08, 0x3e, 0x3f, 0x5e, 0x7f, 0x3e,
-+ 0x2a, 0x3e, 0x2a, 0x3e, 0x7f, 0x09, 0x00, 0x00,
-+ 0x00, 0x70, 0x50, 0x50, 0x54, 0x94, 0x0c, 0xf8,
-+ 0x48, 0x50, 0x30, 0x20, 0x50, 0x8c, 0x00, 0x00,
-+ 0x08, 0x09, 0x7f, 0x09, 0x3f, 0x2b, 0x3f, 0x2b,
-+ 0x3f, 0x09, 0x7f, 0x0a, 0x0c, 0x09, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xf8, 0x50, 0xf8, 0x50,
-+ 0x50, 0xfc, 0xa8, 0x90, 0xe8, 0x84, 0x00, 0x00,
-+ 0x08, 0x09, 0x7e, 0x09, 0x3f, 0x2b, 0x3f, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xfc, 0x28, 0xac, 0xac, 0x00,
-+ 0xf8, 0x08, 0xfc, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x09, 0x7e, 0x08, 0x3e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x09, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x28, 0xfc, 0x20, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8,
-+ 0x38, 0xe8, 0xfc, 0x90, 0x50, 0x30, 0x00, 0x00,
-+ 0x10, 0x10, 0x7f, 0x12, 0x7f, 0x56, 0x7e, 0x57,
-+ 0x7f, 0x13, 0x7f, 0x15, 0x15, 0x1a, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xa0, 0xf8, 0xa8, 0xa8, 0xf8,
-+ 0x24, 0xe8, 0x30, 0x64, 0xa4, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x7e, 0x09, 0x3e, 0x2a, 0x3f, 0x2a,
-+ 0x3f, 0x09, 0x7f, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x18, 0xe0, 0x20, 0xfc, 0x50, 0xf8, 0x54, 0x70,
-+ 0xfc, 0x04, 0x74, 0x54, 0x74, 0x0c, 0x00, 0x00,
-+ 0x10, 0x10, 0x7f, 0x12, 0x7f, 0x56, 0x7f, 0x57,
-+ 0x7d, 0x10, 0x7e, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x28, 0x24, 0xfc, 0x28, 0xe8, 0x10, 0xd4, 0x6c,
-+ 0xc4, 0x40, 0xa8, 0x84, 0x94, 0x70, 0x00, 0x00,
-+ 0x10, 0x13, 0x7c, 0x13, 0x7e, 0x57, 0x7f, 0x57,
-+ 0x7c, 0x13, 0x7e, 0x12, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xfc, 0x48, 0x58, 0x58, 0xfc,
-+ 0x80, 0xf8, 0xa8, 0xa8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x12, 0x12, 0x7d, 0x15, 0x7a, 0x5a, 0x7d, 0x5f,
-+ 0x78, 0x17, 0x78, 0x11, 0x16, 0x10, 0x00, 0x00,
-+ 0x48, 0x48, 0xf4, 0xb4, 0xe8, 0xa8, 0xf4, 0x5c,
-+ 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x10, 0x13, 0x7e, 0x13, 0x7f, 0x56, 0x7f, 0x56,
-+ 0x7e, 0x12, 0x7e, 0x14, 0x17, 0x18, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0xb0, 0xfc, 0xd0, 0xb8, 0x94,
-+ 0x20, 0xb8, 0xa0, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x7f, 0x12, 0x7f, 0x57, 0x7f, 0x57,
-+ 0x7f, 0x13, 0x7f, 0x15, 0x15, 0x1b, 0x00, 0x00,
-+ 0x40, 0x78, 0xfc, 0x68, 0xb8, 0xf0, 0x50, 0xf0,
-+ 0x50, 0xf0, 0xf8, 0x68, 0x68, 0xfc, 0x00, 0x00,
-+ 0x01, 0x7f, 0x01, 0x1f, 0x10, 0x1f, 0x01, 0x3f,
-+ 0x08, 0x7f, 0x01, 0x3f, 0x01, 0x01, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x20, 0xfc, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1e, 0x13, 0x12, 0x12, 0x1e, 0x13, 0x10,
-+ 0x3e, 0x33, 0x52, 0x1e, 0x12, 0x10, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x48, 0x50, 0xfc, 0x20,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x24, 0x15, 0x19, 0x7f, 0x09,
-+ 0x0e, 0x78, 0x09, 0x12, 0x10, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0xe0, 0xe0, 0x50, 0x48, 0x44, 0x40, 0x00, 0x00,
-+ 0x03, 0x3e, 0x29, 0x3f, 0x4a, 0x04, 0x3f, 0x2b,
-+ 0x3f, 0x3f, 0x2b, 0x25, 0x3b, 0x23, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x48, 0x28, 0x30, 0xfc, 0x10,
-+ 0x10, 0xfc, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x10, 0x13, 0x7c, 0x2f, 0x28, 0x2b, 0x7c, 0x13,
-+ 0x1c, 0x73, 0x12, 0x23, 0x22, 0x40, 0x00, 0x00,
-+ 0x10, 0x90, 0x7c, 0xe8, 0x28, 0xa8, 0x7c, 0x90,
-+ 0x10, 0xfc, 0x90, 0x90, 0x90, 0x10, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x20, 0x10, 0x17, 0x00, 0x70,
-+ 0x10, 0x10, 0x10, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x23, 0x12, 0x12, 0x02, 0x73,
-+ 0x12, 0x10, 0x10, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48, 0xf8,
-+ 0x48, 0x40, 0x40, 0x40, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x22, 0x12, 0x12, 0x02, 0x72,
-+ 0x12, 0x12, 0x12, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0x08, 0xe8, 0xa8, 0xa8, 0xe8,
-+ 0xa8, 0x08, 0x08, 0x18, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x0b, 0x08, 0x20, 0x10, 0x11, 0x02, 0x71,
-+ 0x11, 0x11, 0x11, 0x11, 0x2c, 0x43, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x30, 0x00, 0xf8,
-+ 0x08, 0x08, 0xf8, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x20, 0x10, 0x13, 0x02, 0x02, 0x73, 0x12,
-+ 0x12, 0x13, 0x12, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0xf8, 0x48,
-+ 0x48, 0xf8, 0x08, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x22, 0x12, 0x12, 0x43, 0x24, 0x24, 0x0a, 0x71,
-+ 0x11, 0x12, 0x14, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xa0, 0xb0, 0xa8, 0xa4, 0x24,
-+ 0x20, 0x20, 0x20, 0x20, 0x00, 0xfc, 0x00, 0x00,
-+ 0x20, 0x17, 0x11, 0x42, 0x27, 0x22, 0x03, 0x73,
-+ 0x12, 0x13, 0x13, 0x12, 0x2a, 0x47, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0x44, 0xfc, 0xd8, 0x68, 0xf8,
-+ 0xd8, 0x68, 0xf8, 0x48, 0x58, 0xfc, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x22, 0x12, 0x12, 0x02, 0x72,
-+ 0x12, 0x12, 0x13, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xe8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xe8, 0x08, 0xf8, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x22, 0x13, 0x12, 0x02, 0x73,
-+ 0x15, 0x15, 0x19, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0x18, 0xe0, 0x00, 0x00, 0xfc, 0x00, 0x00, 0xf8,
-+ 0x08, 0x08, 0xf8, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x27, 0x10, 0x12, 0x02, 0x74,
-+ 0x18, 0x11, 0x11, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0xa0, 0xb0, 0xa8, 0xa4,
-+ 0xa4, 0x20, 0x20, 0x60, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x20, 0x13, 0x12, 0x02, 0x72,
-+ 0x13, 0x12, 0x13, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xa0, 0xf8, 0xa8, 0xb8, 0xb8,
-+ 0x18, 0x08, 0xf8, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x27, 0x10, 0x12, 0x01, 0x71,
-+ 0x11, 0x16, 0x10, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x50, 0x48, 0x48, 0xfc, 0x40, 0x48, 0x48, 0x70,
-+ 0xd0, 0x48, 0x48, 0xc0, 0x00, 0xfc, 0x00, 0x00,
-+ 0x20, 0x17, 0x12, 0x42, 0x24, 0x22, 0x00, 0x73,
-+ 0x10, 0x10, 0x17, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0x48, 0x48, 0x90, 0x48, 0x00, 0xf8,
-+ 0x40, 0x40, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x08, 0x09, 0x27, 0x11, 0x11, 0x02, 0x74,
-+ 0x11, 0x12, 0x10, 0x1b, 0x26, 0x41, 0x00, 0x00,
-+ 0x80, 0xa0, 0x18, 0xe4, 0x20, 0x24, 0x9c, 0xf0,
-+ 0x90, 0x60, 0xd0, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x09, 0x09, 0x22, 0x15, 0x11, 0x01, 0x71,
-+ 0x11, 0x11, 0x11, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0x44, 0xf4, 0x10, 0xf0, 0x10,
-+ 0xf0, 0x10, 0x10, 0x30, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x09, 0x09, 0x21, 0x11, 0x10, 0x03, 0x70,
-+ 0x11, 0x10, 0x17, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0x10, 0xf0, 0x00, 0xf8, 0x40,
-+ 0xf0, 0x40, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x21, 0x11, 0x16, 0x42, 0x26, 0x2b, 0x03, 0x75,
-+ 0x19, 0x11, 0x11, 0x1e, 0x26, 0x41, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x28, 0x68, 0x70, 0xa0, 0x20,
-+ 0x50, 0x50, 0x88, 0x04, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x20, 0x13, 0x12, 0x03, 0x72,
-+ 0x13, 0x12, 0x12, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x50, 0x48, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xf8, 0x48, 0x48, 0x58, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x08, 0x09, 0x22, 0x10, 0x10, 0x01, 0x73,
-+ 0x15, 0x11, 0x11, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0xa0, 0x90, 0x08, 0x48, 0x40, 0xa0, 0x10, 0xf8,
-+ 0x14, 0x10, 0xf0, 0x10, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x0b, 0x08, 0x27, 0x10, 0x11, 0x02, 0x77,
-+ 0x10, 0x11, 0x10, 0x1b, 0x26, 0x41, 0x00, 0x00,
-+ 0x18, 0xe0, 0x40, 0xfc, 0xe0, 0x50, 0x48, 0xfc,
-+ 0x90, 0xd0, 0x70, 0x88, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x0b, 0x08, 0x27, 0x11, 0x11, 0x02, 0x74,
-+ 0x11, 0x10, 0x17, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xfc, 0x20, 0x24, 0x5c, 0x40,
-+ 0xf0, 0x40, 0xfc, 0x00, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x08, 0x0b, 0x20, 0x17, 0x11, 0x00, 0x77,
-+ 0x10, 0x13, 0x10, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x40, 0xfc, 0x10, 0xa0, 0xfc,
-+ 0x40, 0xf8, 0x40, 0x40, 0x00, 0xfc, 0x00, 0x00,
-+ 0x22, 0x11, 0x11, 0x47, 0x21, 0x21, 0x0f, 0x71,
-+ 0x11, 0x12, 0x14, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x23, 0x12, 0x13, 0x01, 0x73,
-+ 0x16, 0x12, 0x13, 0x1b, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x48, 0xa8, 0x28, 0xf8, 0x10, 0xfc, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x22, 0x13, 0x12, 0x03, 0x72,
-+ 0x12, 0x13, 0x12, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xb8, 0x88, 0x88, 0xb8, 0x00, 0xf8, 0x28,
-+ 0x10, 0x90, 0x28, 0x48, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x09, 0x09, 0x21, 0x11, 0x11, 0x00, 0x73,
-+ 0x10, 0x11, 0x10, 0x1f, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0x00, 0xf8,
-+ 0x40, 0xf0, 0x40, 0xfc, 0x00, 0xfc, 0x00, 0x00,
-+ 0x11, 0x09, 0x0a, 0x27, 0x10, 0x13, 0x02, 0x73,
-+ 0x12, 0x12, 0x13, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0xf0, 0x10, 0x08, 0xfc, 0xa0, 0xf8, 0xa8, 0x38,
-+ 0xe8, 0x08, 0xf8, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x23, 0x12, 0x12, 0x02, 0x73,
-+ 0x12, 0x12, 0x13, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xf8, 0xa8, 0xa8, 0xb8, 0x18,
-+ 0xe8, 0x08, 0xf8, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x08, 0x08, 0x23, 0x12, 0x13, 0x02, 0x73,
-+ 0x12, 0x13, 0x13, 0x1c, 0x26, 0x41, 0x00, 0x00,
-+ 0x80, 0xf8, 0x80, 0xf0, 0x10, 0xf0, 0x10, 0xf0,
-+ 0x10, 0xf0, 0x30, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x11, 0x08, 0x09, 0x23, 0x14, 0x13, 0x02, 0x73,
-+ 0x12, 0x13, 0x12, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0xc0, 0xa0, 0x10, 0xf8, 0x04, 0xa8, 0xa8, 0xd0,
-+ 0xd0, 0xa8, 0xa8, 0xa8, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x08, 0x0f, 0x20, 0x13, 0x13, 0x02, 0x73,
-+ 0x12, 0x13, 0x12, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x18, 0xa8, 0xf8,
-+ 0x48, 0xf8, 0x48, 0x58, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x23, 0x10, 0x17, 0x01, 0x71,
-+ 0x11, 0x11, 0x17, 0x19, 0x27, 0x41, 0x00, 0x00,
-+ 0xa0, 0xfc, 0xa0, 0xf8, 0xa0, 0xfc, 0xf0, 0x50,
-+ 0xf0, 0x50, 0xfc, 0x10, 0x30, 0xfc, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x22, 0x12, 0x12, 0x02, 0x72,
-+ 0x15, 0x15, 0x1a, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x18, 0xe0, 0x38, 0xfc, 0xa8, 0xb8, 0xe4, 0x9c,
-+ 0x50, 0x54, 0x54, 0x8c, 0x00, 0xfc, 0x00, 0x00,
-+ 0x11, 0x0b, 0x09, 0x27, 0x11, 0x17, 0x01, 0x71,
-+ 0x12, 0x12, 0x14, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0x20, 0xa0, 0x20, 0xfc, 0x48, 0xe8, 0x18, 0x90,
-+ 0x98, 0xa8, 0xc4, 0x84, 0x00, 0xfc, 0x00, 0x00,
-+ 0x20, 0x17, 0x15, 0x45, 0x27, 0x25, 0x05, 0x77,
-+ 0x15, 0x15, 0x19, 0x1b, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x64, 0xb4, 0x38, 0xd8, 0x38,
-+ 0xd4, 0x14, 0x10, 0x60, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x09, 0x08, 0x27, 0x11, 0x17, 0x01, 0x76,
-+ 0x13, 0x10, 0x11, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0xf0, 0x40, 0xfc, 0x10, 0xb8, 0x90, 0x3c,
-+ 0xf8, 0xa0, 0x24, 0x1c, 0x00, 0xfc, 0x00, 0x00,
-+ 0x02, 0x39, 0x29, 0x2c, 0x32, 0x33, 0x28, 0x2f,
-+ 0x25, 0x25, 0x25, 0x39, 0x22, 0x24, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x78, 0x90, 0xfc, 0x78, 0x48,
-+ 0x78, 0x78, 0x48, 0x58, 0x80, 0x7c, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x23, 0x12, 0x13, 0x03, 0x72,
-+ 0x12, 0x15, 0x17, 0x18, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x20, 0xac, 0xac, 0xa0,
-+ 0xf8, 0x20, 0xfc, 0x20, 0x20, 0xfc, 0x00, 0x00,
-+ 0x22, 0x13, 0x14, 0x49, 0x27, 0x25, 0x07, 0x75,
-+ 0x17, 0x14, 0x14, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0x28, 0xd8, 0xb0, 0xb8, 0xd0,
-+ 0xfc, 0x90, 0x90, 0x90, 0x00, 0xfc, 0x00, 0x00,
-+ 0x20, 0x10, 0x17, 0x44, 0x27, 0x24, 0x07, 0x74,
-+ 0x17, 0x14, 0x1b, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0x80, 0xf0, 0xfc, 0xe8, 0x90, 0x70, 0xf8, 0xc8,
-+ 0x68, 0xb0, 0x68, 0xa4, 0xc0, 0xfc, 0x00, 0x00,
-+ 0x10, 0x0f, 0x08, 0x21, 0x11, 0x11, 0x01, 0x71,
-+ 0x13, 0x12, 0x13, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0xa0, 0xfc, 0xa0, 0xf0, 0x50, 0xf0, 0x50, 0xf0,
-+ 0xf8, 0x68, 0xf8, 0x08, 0x18, 0xfc, 0x00, 0x00,
-+ 0x11, 0x0f, 0x0c, 0x27, 0x14, 0x17, 0x02, 0x7f,
-+ 0x13, 0x12, 0x14, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xbc, 0xc8, 0xc8, 0x28, 0xd0,
-+ 0x98, 0xa8, 0xc4, 0x84, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x09, 0x09, 0x21, 0x11, 0x11, 0x03, 0x72,
-+ 0x15, 0x17, 0x10, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0xf0, 0x10, 0xf0, 0xf0, 0xf0, 0xfc, 0xa8,
-+ 0x78, 0xfc, 0xf0, 0x10, 0x60, 0xfc, 0x00, 0x00,
-+ 0x10, 0x09, 0x09, 0x21, 0x11, 0x11, 0x03, 0x72,
-+ 0x15, 0x17, 0x11, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0xf0, 0x10, 0xd0, 0xd0, 0xf0, 0xfc, 0xe8,
-+ 0x10, 0xfc, 0x10, 0xf0, 0x00, 0xfc, 0x00, 0x00,
-+ 0x10, 0x0b, 0x0a, 0x23, 0x12, 0x1d, 0x03, 0x72,
-+ 0x17, 0x13, 0x15, 0x19, 0x26, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xf8, 0x28, 0x7c, 0x50, 0xfc,
-+ 0xd0, 0x7c, 0xd0, 0x7c, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x0f, 0x78, 0x0a, 0x2a, 0x2a, 0x2a,
-+ 0x3e, 0x2a, 0x08, 0x0a, 0x0c, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x90, 0x90, 0xa0, 0x90, 0x88,
-+ 0x88, 0x88, 0x88, 0xf0, 0x80, 0x80, 0x00, 0x00,
-+ 0x12, 0x12, 0x12, 0x12, 0x7f, 0x12, 0x12, 0x12,
-+ 0x1e, 0x12, 0x12, 0x12, 0x1e, 0x12, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x50, 0xd0, 0x60, 0x50, 0x50,
-+ 0x48, 0x48, 0x48, 0x70, 0x40, 0x40, 0x00, 0x00,
-+ 0x01, 0x06, 0x38, 0x20, 0x20, 0x3f, 0x24, 0x24,
-+ 0x24, 0x24, 0x27, 0x38, 0x60, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x90, 0x90, 0xa0, 0x90, 0x88,
-+ 0x88, 0x88, 0x88, 0xf0, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x7e, 0x12, 0x12, 0x12, 0x22, 0x4c, 0x00,
-+ 0x3e, 0x22, 0x22, 0x22, 0x3e, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x90, 0x90, 0xa0, 0x90, 0x88,
-+ 0x88, 0x88, 0x88, 0xf0, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x00, 0x7e, 0x08,
-+ 0x08, 0x3e, 0x08, 0x08, 0x0e, 0x70, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x90, 0x90, 0xa0, 0x90, 0x88,
-+ 0x88, 0x88, 0xc8, 0xb0, 0x80, 0x80, 0x00, 0x00,
-+ 0x14, 0x12, 0x22, 0x48, 0x08, 0x14, 0x12, 0x22,
-+ 0x7e, 0x22, 0x22, 0x3e, 0x22, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x90, 0x90, 0xa0, 0x90, 0x88,
-+ 0x88, 0x88, 0xc8, 0xb0, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x3f, 0x00, 0x1f, 0x10, 0x1f, 0x13, 0x12,
-+ 0x13, 0x17, 0x14, 0x27, 0x24, 0x43, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x08, 0xf8, 0xe0, 0x20,
-+ 0xe0, 0xf0, 0x90, 0xf4, 0x04, 0xfc, 0x00, 0x00,
-+ 0x03, 0x3c, 0x32, 0x29, 0x29, 0x40, 0x3e, 0x04,
-+ 0x08, 0x0e, 0x78, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x90, 0x90, 0xa0, 0x90, 0x88,
-+ 0x88, 0x88, 0xc8, 0xb0, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x77, 0x55, 0x55, 0x77, 0x00, 0x3e, 0x00,
-+ 0x7f, 0x10, 0x1e, 0x22, 0x02, 0x0c, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x50, 0x50, 0x60, 0x50, 0x48,
-+ 0x48, 0x48, 0x48, 0x70, 0x40, 0x40, 0x00, 0x00,
-+ 0x10, 0x1f, 0x29, 0x6b, 0x3f, 0x29, 0x0e, 0x10,
-+ 0x1f, 0x29, 0x6b, 0x3f, 0x29, 0x16, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x50, 0x50, 0x60, 0x50, 0x48,
-+ 0x48, 0x48, 0x48, 0x70, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x3f, 0x7f, 0x08, 0x3f, 0x21,
-+ 0x2f, 0x2b, 0x2f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x50, 0xd0, 0x60, 0x50, 0x48,
-+ 0x48, 0x48, 0x48, 0x70, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x77, 0x55, 0x77, 0x00, 0x3e, 0x2a, 0x3e,
-+ 0x2a, 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x50, 0x50, 0x60, 0x50, 0x48,
-+ 0x48, 0x48, 0x48, 0x70, 0x40, 0x40, 0x00, 0x00,
-+ 0x04, 0x25, 0x16, 0x7f, 0x0e, 0x15, 0x75, 0x1f,
-+ 0x2d, 0x6d, 0x1f, 0x11, 0x21, 0x41, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0xd0, 0x50, 0x60, 0xd0, 0xc8,
-+ 0x48, 0x48, 0xc8, 0x70, 0x40, 0x40, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0x80, 0xfc, 0x10, 0x10, 0x10, 0x10, 0x10,
-+ 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x2f,
-+ 0x33, 0x31, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x20, 0xa0, 0x20, 0x20, 0xfc, 0xa8, 0x20, 0x20,
-+ 0x30, 0x30, 0x50, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0xf0, 0x50, 0x50, 0x54, 0x94, 0x0c, 0xf8,
-+ 0x48, 0x50, 0x30, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x48, 0xc8, 0x48, 0x48, 0xfc, 0x48, 0x48, 0x48,
-+ 0x78, 0x48, 0x48, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x08, 0xb0, 0xe0, 0x20, 0x20, 0xfc, 0x70, 0x70,
-+ 0x70, 0xa8, 0xa8, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x20, 0xa0, 0x38, 0x48, 0xd0, 0x30, 0x20, 0x40,
-+ 0xf8, 0x48, 0x48, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x20, 0x28, 0xc8, 0x30, 0x28, 0xfc, 0x04, 0x78,
-+ 0x48, 0x78, 0x48, 0x78, 0x48, 0x58, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x2f,
-+ 0x37, 0x33, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x78, 0x08, 0xf0,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x37, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x50, 0xd0, 0x50, 0xf8, 0x50, 0x50, 0xfc, 0x00,
-+ 0x78, 0x48, 0x78, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2d, 0x2d, 0x37,
-+ 0x33, 0x23, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x48, 0x48, 0x68, 0xb4, 0x24,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3f, 0x2e, 0x2e, 0x37,
-+ 0x37, 0x22, 0x3e, 0x22, 0x3e, 0x22, 0x00, 0x00,
-+ 0x90, 0x90, 0x90, 0x90, 0xfc, 0x90, 0xd8, 0xf8,
-+ 0xb8, 0xd4, 0xd4, 0x90, 0x90, 0x90, 0x00, 0x00,
-+ 0x00, 0x7e, 0x18, 0x19, 0x7e, 0x5a, 0x5a, 0x7e,
-+ 0x67, 0x47, 0x7f, 0x43, 0x7f, 0x42, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xf0, 0x90, 0xf0, 0x00,
-+ 0xf8, 0x68, 0x68, 0x68, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x2e, 0x35, 0x3f, 0x2a, 0x3f, 0x7f,
-+ 0x02, 0x1f, 0x14, 0x1f, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0x70, 0x54, 0x9c, 0xf8, 0x70, 0xd8, 0xfc,
-+ 0x80, 0xf0, 0xd0, 0xf0, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0d, 0x3e, 0x2e, 0x2e, 0x36,
-+ 0x37, 0x22, 0x3e, 0x22, 0x3f, 0x22, 0x00, 0x00,
-+ 0x20, 0xfc, 0x50, 0xf8, 0x00, 0xa8, 0xa8, 0xac,
-+ 0x04, 0xf8, 0xe8, 0xe8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0d, 0x3e, 0x2f, 0x2e, 0x36,
-+ 0x37, 0x22, 0x3e, 0x22, 0x3e, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0xd8, 0x68, 0xd8, 0x68, 0x20, 0xd0,
-+ 0x2c, 0xd0, 0x20, 0xc8, 0x30, 0xc0, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0c, 0x0c, 0x3e, 0x2e, 0x2e, 0x36,
-+ 0x36, 0x22, 0x3e, 0x23, 0x3f, 0x22, 0x00, 0x00,
-+ 0x20, 0x38, 0xfc, 0xb8, 0xe8, 0x98, 0xfc, 0xa0,
-+ 0xf4, 0xb8, 0xd8, 0x34, 0x54, 0x30, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0d, 0x0d, 0x3f, 0x2f, 0x2e, 0x37,
-+ 0x36, 0x22, 0x3e, 0x22, 0x3f, 0x22, 0x00, 0x00,
-+ 0x60, 0xf8, 0x68, 0xf8, 0x68, 0xf8, 0x00, 0xfc,
-+ 0xf8, 0x88, 0xf8, 0x50, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0d, 0x0c, 0x3e, 0x2e, 0x2e, 0x36,
-+ 0x36, 0x22, 0x3f, 0x22, 0x3e, 0x23, 0x00, 0x00,
-+ 0x18, 0xe0, 0xfc, 0x20, 0xf8, 0xb8, 0xe8, 0xf8,
-+ 0x20, 0xf8, 0xfc, 0x00, 0xe8, 0x54, 0x00, 0x00,
-+ 0x00, 0x7f, 0x0d, 0x0d, 0x3f, 0x2e, 0x2f, 0x36,
-+ 0x36, 0x23, 0x3e, 0x23, 0x3e, 0x23, 0x00, 0x00,
-+ 0x20, 0xfc, 0xdc, 0x54, 0xdc, 0x50, 0xfc, 0xf8,
-+ 0x50, 0xfc, 0x68, 0xd0, 0x68, 0x84, 0x00, 0x00,
-+ 0x1b, 0x12, 0x1b, 0x1b, 0x3f, 0x2f, 0x5f, 0x14,
-+ 0x1f, 0x1f, 0x07, 0x0f, 0x72, 0x0c, 0x00, 0x00,
-+ 0xb0, 0x90, 0xb0, 0xb0, 0xfc, 0xe8, 0xf0, 0xd0,
-+ 0xf0, 0xf0, 0xc0, 0xf0, 0x4c, 0xc0, 0x00, 0x00,
-+ 0x03, 0x7d, 0x49, 0x2a, 0x2c, 0x7f, 0x18, 0x1c,
-+ 0x1a, 0x29, 0x29, 0x48, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0xf8, 0xa8, 0xa8, 0xa8,
-+ 0xf8, 0xa8, 0xa8, 0xa8, 0xf8, 0x88, 0x00, 0x00,
-+ 0x02, 0x7d, 0x4b, 0x2b, 0x2c, 0x7f, 0x18, 0x1d,
-+ 0x1a, 0x2b, 0x28, 0x49, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x68, 0xf8, 0x40, 0xf8, 0x40, 0xfc,
-+ 0x90, 0xfc, 0x40, 0xf8, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x3e, 0x7f, 0x1c, 0x2a, 0x5f, 0x17, 0x14,
-+ 0x17, 0x17, 0x1f, 0x20, 0x5f, 0x00, 0x00, 0x00,
-+ 0x40, 0x7c, 0xd0, 0x30, 0xcc, 0xf8, 0xf0, 0x90,
-+ 0xf0, 0xf0, 0xf8, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x72, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x19, 0x0f, 0x72, 0x00, 0x00,
-+ 0x00, 0x70, 0x10, 0x10, 0x50, 0x50, 0x50, 0x50,
-+ 0x90, 0x88, 0x88, 0x08, 0x04, 0x04, 0x00, 0x00,
-+ 0x04, 0x04, 0x09, 0x11, 0x02, 0x04, 0x1f, 0x61,
-+ 0x1f, 0x09, 0x05, 0x05, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x20, 0x10, 0x10, 0x80, 0x40, 0xf0, 0x0c,
-+ 0xf0, 0x20, 0x20, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x23, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x72, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x23, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x72, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0xc8, 0x48, 0x68,
-+ 0x58, 0x4c, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x72, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xc8, 0xa8, 0x90, 0x50, 0x50,
-+ 0x60, 0x20, 0x60, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x09, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xa8, 0xb8, 0xe8, 0xa8, 0xa8,
-+ 0xa8, 0xb8, 0xa0, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5d, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x88, 0x08, 0xe8, 0x08,
-+ 0x28, 0xc8, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1d, 0x19, 0x0e, 0x70, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0x80, 0x80, 0xfc, 0x90, 0x90,
-+ 0x90, 0x90, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x09, 0x7f,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x73, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xb0, 0xa8, 0xa8, 0x24, 0x2c,
-+ 0x68, 0x10, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x19, 0x0f, 0x72, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0xa8, 0xa0,
-+ 0xa0, 0xa0, 0x90, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x22, 0x5c, 0x09, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x70, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x90, 0x90, 0x90, 0xfc, 0x90,
-+ 0x90, 0x90, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x19, 0x0f, 0x72, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xf8, 0xc8, 0xc8, 0xa8,
-+ 0xb0, 0x90, 0xb0, 0x28, 0x48, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x72, 0x00, 0x00,
-+ 0x20, 0x28, 0x24, 0xfc, 0xa0, 0xa8, 0xa8, 0xa8,
-+ 0x98, 0x90, 0x94, 0xec, 0xac, 0x44, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x23, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x90, 0x90, 0x90, 0x90, 0xfc, 0x90, 0x90, 0x90,
-+ 0xf0, 0x90, 0x90, 0x90, 0xf0, 0x90, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x70, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xf8, 0x88, 0x88, 0x88,
-+ 0xf8, 0x88, 0x80, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x13, 0x22, 0x5d, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x70, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x28, 0xc8, 0x50,
-+ 0x30, 0x20, 0x30, 0x48, 0xf4, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5d, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x88, 0xe8, 0xa8, 0xa8,
-+ 0xe8, 0xa8, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5d, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x88, 0x40, 0x40, 0x48,
-+ 0x70, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x12, 0x23, 0x5c, 0x09, 0x7f,
-+ 0x09, 0x2b, 0x1c, 0x18, 0x0e, 0x71, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0x28, 0xf8, 0x20,
-+ 0xfc, 0x24, 0x58, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xa8, 0xa8, 0xf8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0xf8, 0x88, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5d, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xf8, 0x88, 0xe8, 0xa8, 0xa8,
-+ 0xe8, 0xb0, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7f,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x40, 0x80, 0xf8, 0x88,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x11, 0x11, 0x22, 0x4a, 0x0f, 0x11, 0x17, 0x31,
-+ 0x55, 0x13, 0x13, 0x11, 0x16, 0x10, 0x00, 0x00,
-+ 0x00, 0x3c, 0x80, 0x40, 0xfc, 0x08, 0xc8, 0x08,
-+ 0x48, 0x88, 0x08, 0xc8, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5d, 0x09, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x19, 0x0e, 0x70, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xf8, 0xa0, 0x20, 0xfc, 0x70,
-+ 0x70, 0xa8, 0xa8, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5d, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x70, 0x00, 0x00,
-+ 0xe0, 0x20, 0x50, 0x50, 0x88, 0xfc, 0x20, 0x20,
-+ 0xf8, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5d, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x10, 0x10, 0x1b, 0x2a, 0x26, 0x7a, 0x12, 0x7e,
-+ 0x12, 0x57, 0x38, 0x31, 0x1d, 0x62, 0x00, 0x00,
-+ 0x40, 0x80, 0x38, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xa8, 0xb8, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x12, 0x22, 0x5c, 0x08, 0x7f,
-+ 0x09, 0x2a, 0x1c, 0x18, 0x0f, 0x72, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xa8, 0xa8, 0xa8, 0x74,
-+ 0x24, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x13, 0x22, 0x5c, 0x09, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x72, 0x00, 0x00,
-+ 0x18, 0xe0, 0x20, 0xfc, 0x70, 0xa8, 0x24, 0xf0,
-+ 0x50, 0x5c, 0x94, 0x84, 0x04, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x23, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x20, 0x20, 0xa8, 0xa4, 0x24, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x12, 0x22, 0x5c, 0x09, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x90, 0x20, 0x20, 0xfc, 0x80,
-+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x78, 0x00, 0x00,
-+ 0x10, 0x13, 0x18, 0x24, 0x27, 0x7e, 0x12, 0x7f,
-+ 0x12, 0x54, 0x38, 0x30, 0x1f, 0x60, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xa0, 0xb8, 0x08, 0x08, 0xb8,
-+ 0xa8, 0xa0, 0xa0, 0xa0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x19, 0x25, 0x27, 0x7d, 0x11, 0x7d,
-+ 0x12, 0x54, 0x38, 0x31, 0x1e, 0x64, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0x00, 0xf8, 0x68, 0x68,
-+ 0xe8, 0xb8, 0xa0, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x19, 0x0e, 0x70, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x00, 0xf8, 0x88, 0x88, 0xf8,
-+ 0x20, 0xb0, 0xa8, 0x24, 0x24, 0x60, 0x00, 0x00,
-+ 0x08, 0x09, 0x15, 0x13, 0x23, 0x5d, 0x09, 0x7f,
-+ 0x09, 0x2b, 0x1d, 0x19, 0x0f, 0x71, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0x48, 0xe8,
-+ 0xa8, 0xa8, 0xe8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x13, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0xa8, 0xa8, 0x50, 0x50, 0xa8, 0xa8, 0x00, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0xa8, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x13, 0x22, 0x5c, 0x09, 0x7e,
-+ 0x08, 0x2b, 0x1c, 0x18, 0x0f, 0x70, 0x00, 0x00,
-+ 0x50, 0x48, 0x7c, 0xc8, 0x30, 0x74, 0x8c, 0x50,
-+ 0x7c, 0xc8, 0x30, 0x64, 0x9c, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x23, 0x5c, 0x08, 0x7f,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x0c, 0xf0, 0xa8, 0xa4, 0x04, 0xf8, 0x28, 0xfc,
-+ 0x28, 0xf8, 0x28, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x13, 0x22, 0x5c, 0x09, 0x7f,
-+ 0x08, 0x2b, 0x1c, 0x18, 0x0f, 0x72, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x68, 0x90, 0xd0, 0x28, 0xf8,
-+ 0x48, 0x68, 0x90, 0x90, 0x68, 0x44, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x12, 0x22, 0x5c, 0x09, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x71, 0x00, 0x00,
-+ 0x50, 0x50, 0xfc, 0x50, 0x20, 0x20, 0xfc, 0x20,
-+ 0x38, 0x28, 0x48, 0x48, 0x88, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x09, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x50, 0x50, 0xfc, 0x50, 0x60, 0x60, 0xa4, 0xa8,
-+ 0xb0, 0xa0, 0xa0, 0xa4, 0xa4, 0x9c, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x23, 0x5c, 0x09, 0x7f,
-+ 0x09, 0x2b, 0x1d, 0x19, 0x0f, 0x70, 0x00, 0x00,
-+ 0x10, 0xf8, 0x14, 0x14, 0xfc, 0x50, 0x50, 0x70,
-+ 0x50, 0x50, 0x74, 0xcc, 0x0c, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x15, 0x13, 0x23, 0x5d, 0x09, 0x7f,
-+ 0x09, 0x2b, 0x1d, 0x19, 0x0f, 0x71, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xd8, 0x48, 0x00, 0xf8,
-+ 0x28, 0x28, 0xd0, 0x10, 0x28, 0x44, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x09, 0x2a, 0x1c, 0x18, 0x0f, 0x70, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x00,
-+ 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x18, 0x14, 0x27, 0x22, 0x7b, 0x12, 0x7f,
-+ 0x13, 0x57, 0x3b, 0x32, 0x1c, 0x64, 0x00, 0x00,
-+ 0x28, 0x24, 0x24, 0xfc, 0x20, 0xe8, 0x28, 0xe8,
-+ 0x50, 0x50, 0xf4, 0x2c, 0x4c, 0x84, 0x00, 0x00,
-+ 0x10, 0x10, 0x18, 0x25, 0x27, 0x78, 0x13, 0x7e,
-+ 0x13, 0x56, 0x3b, 0x32, 0x1e, 0x62, 0x00, 0x00,
-+ 0xc0, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xa8, 0xa8,
-+ 0xa8, 0xd0, 0xd0, 0xa8, 0xa8, 0xa8, 0x00, 0x00,
-+ 0x10, 0x10, 0x1b, 0x24, 0x24, 0x78, 0x10, 0x7c,
-+ 0x13, 0x55, 0x39, 0x31, 0x1d, 0x61, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x90, 0xf0, 0x90, 0xf0, 0x90,
-+ 0xfc, 0x50, 0x54, 0x8c, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x13, 0x22, 0x7c, 0x08, 0x7f,
-+ 0x09, 0x2b, 0x1d, 0x19, 0x0f, 0x70, 0x00, 0x00,
-+ 0xf0, 0x90, 0x08, 0xfc, 0x00, 0xf0, 0x90, 0x08,
-+ 0xfc, 0x68, 0x68, 0x68, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x09, 0x2b, 0x1d, 0x19, 0x0f, 0x71, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x00, 0xf8, 0x88, 0xf8, 0x00,
-+ 0xfc, 0x04, 0x74, 0x54, 0x74, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x23, 0x5d, 0x09, 0x7f,
-+ 0x09, 0x2b, 0x1d, 0x19, 0x0e, 0x73, 0x00, 0x00,
-+ 0x98, 0xe0, 0x84, 0x7c, 0x78, 0x48, 0x78, 0x48,
-+ 0x78, 0x48, 0x78, 0xfc, 0xc8, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x13, 0x22, 0x5c, 0x09, 0x7c,
-+ 0x08, 0x2b, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x58, 0x48, 0xa8, 0x20, 0x50,
-+ 0x88, 0xfc, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x12, 0x11, 0x19, 0x26, 0x25, 0x7d, 0x10, 0x7c,
-+ 0x13, 0x55, 0x39, 0x31, 0x1e, 0x64, 0x00, 0x00,
-+ 0x70, 0x10, 0x50, 0x48, 0x84, 0x78, 0x20, 0xfc,
-+ 0x20, 0x30, 0x48, 0x88, 0x80, 0x7c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1f, 0x12, 0x1f, 0x17, 0x27, 0x59,
-+ 0x0e, 0x77, 0x1f, 0x09, 0x3f, 0x00, 0x00, 0x00,
-+ 0x80, 0xfc, 0xf8, 0x48, 0xf8, 0x58, 0xe4, 0x3c,
-+ 0xe0, 0xdc, 0xf0, 0x20, 0xf8, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x1a, 0x27, 0x26, 0x7b, 0x12, 0x7f,
-+ 0x12, 0x55, 0x38, 0x30, 0x1f, 0x60, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xe8, 0x50, 0xd0, 0xa8, 0xc4,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x7f, 0x3e, 0x3e, 0x2a, 0x3e, 0x7f, 0x09,
-+ 0x06, 0x7b, 0x1f, 0x09, 0x3f, 0x00, 0x00, 0x00,
-+ 0x18, 0xe0, 0x80, 0xfc, 0x90, 0x90, 0x10, 0x10,
-+ 0xc0, 0xbc, 0xf0, 0x20, 0xf8, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x13, 0x22, 0x5c, 0x09, 0x7f,
-+ 0x0b, 0x2b, 0x1d, 0x19, 0x0f, 0x71, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x08, 0x80, 0xfc, 0x20, 0x78,
-+ 0x48, 0x78, 0x48, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x10, 0x12, 0x1a, 0x26, 0x27, 0x7a, 0x10, 0x7c,
-+ 0x13, 0x56, 0x3a, 0x32, 0x1c, 0x60, 0x00, 0x00,
-+ 0xa0, 0xb8, 0xa8, 0xe8, 0xd0, 0xb0, 0xa8, 0xc8,
-+ 0xfc, 0xc8, 0xa8, 0xa8, 0x88, 0x98, 0x00, 0x00,
-+ 0x11, 0x11, 0x19, 0x25, 0x27, 0x79, 0x11, 0x7d,
-+ 0x11, 0x55, 0x3a, 0x32, 0x1c, 0x61, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x7c, 0xe0, 0x20, 0xbc, 0xd0,
-+ 0xfc, 0x90, 0xa8, 0xa8, 0xc4, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x5c, 0x09, 0x7f,
-+ 0x09, 0x2b, 0x1c, 0x18, 0x0e, 0x73, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc, 0x54,
-+ 0xfc, 0xf8, 0x88, 0x50, 0x70, 0x8c, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x13, 0x22, 0x5d, 0x08, 0x7e,
-+ 0x09, 0x2a, 0x1c, 0x18, 0x0e, 0x71, 0x00, 0x00,
-+ 0x00, 0xf8, 0xd8, 0x68, 0xd8, 0x68, 0x40, 0xa0,
-+ 0x30, 0xcc, 0x20, 0xc8, 0x30, 0xc0, 0x00, 0x00,
-+ 0x12, 0x11, 0x19, 0x24, 0x26, 0x79, 0x11, 0x7c,
-+ 0x13, 0x55, 0x39, 0x31, 0x1e, 0x64, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0xa8, 0xf8, 0xa8,
-+ 0xf8, 0x20, 0xfc, 0x20, 0xa0, 0x7c, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x13, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2b, 0x1c, 0x18, 0x0e, 0x71, 0x00, 0x00,
-+ 0x20, 0xf8, 0xa8, 0xfc, 0xa8, 0xf8, 0xf8, 0xa8,
-+ 0xf8, 0xfc, 0x50, 0xd0, 0x30, 0xc8, 0x00, 0x00,
-+ 0x10, 0x13, 0x18, 0x27, 0x26, 0x7f, 0x12, 0x7c,
-+ 0x13, 0x54, 0x3a, 0x32, 0x1c, 0x60, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xb8, 0x08, 0xb8, 0xa8, 0xa0,
-+ 0xfc, 0x40, 0xa8, 0xa4, 0x94, 0x70, 0x00, 0x00,
-+ 0x10, 0x17, 0x18, 0x27, 0x26, 0x7b, 0x11, 0x7d,
-+ 0x11, 0x55, 0x39, 0x33, 0x1c, 0x60, 0x00, 0x00,
-+ 0x00, 0xfc, 0xa0, 0xf8, 0xa8, 0xf8, 0xf0, 0x10,
-+ 0xf0, 0x10, 0xf0, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x11, 0x11, 0x1f, 0x27, 0x26, 0x7a, 0x13, 0x7f,
-+ 0x10, 0x55, 0x3b, 0x31, 0x1d, 0x63, 0x00, 0x00,
-+ 0x20, 0x20, 0xe0, 0xa0, 0xbc, 0xe8, 0xe8, 0xa8,
-+ 0x90, 0xd0, 0x30, 0x28, 0x48, 0x84, 0x00, 0x00,
-+ 0x10, 0x11, 0x18, 0x27, 0x25, 0x7b, 0x11, 0x7d,
-+ 0x13, 0x57, 0x38, 0x30, 0x1d, 0x62, 0x00, 0x00,
-+ 0x40, 0xf8, 0x40, 0xfc, 0x10, 0xb8, 0x10, 0xbc,
-+ 0x00, 0xfc, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x23, 0x5c, 0x08, 0x7f,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x70, 0x00, 0x00,
-+ 0x18, 0xe8, 0xa8, 0x70, 0xfc, 0x70, 0xa8, 0x24,
-+ 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x13, 0x22, 0x5d, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0f, 0x70, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x54, 0x88, 0xfc, 0x88, 0xf8,
-+ 0x88, 0xf8, 0xa8, 0xa4, 0x24, 0x60, 0x00, 0x00,
-+ 0x08, 0x09, 0x15, 0x13, 0x22, 0x5d, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x19, 0x0e, 0x71, 0x00, 0x00,
-+ 0x00, 0xfc, 0x54, 0xfc, 0x00, 0xfc, 0x00, 0xf8,
-+ 0x88, 0xf8, 0x64, 0xd8, 0x68, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x13, 0x23, 0x5d, 0x09, 0x7f,
-+ 0x08, 0x2b, 0x1d, 0x19, 0x0f, 0x71, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x20, 0xf8, 0xf8, 0x20, 0xfc,
-+ 0x00, 0xdc, 0x54, 0x74, 0x04, 0x0c, 0x00, 0x00,
-+ 0x11, 0x13, 0x19, 0x27, 0x24, 0x7b, 0x12, 0x7f,
-+ 0x13, 0x55, 0x3b, 0x31, 0x1f, 0x60, 0x00, 0x00,
-+ 0x30, 0xe8, 0x28, 0xfc, 0x20, 0xa8, 0xa8, 0xa8,
-+ 0xd8, 0x10, 0x94, 0xec, 0x4c, 0x84, 0x00, 0x00,
-+ 0x10, 0x10, 0x1b, 0x24, 0x27, 0x78, 0x13, 0x7e,
-+ 0x13, 0x56, 0x39, 0x31, 0x1e, 0x60, 0x00, 0x00,
-+ 0xa0, 0xb0, 0xe8, 0xa8, 0xfc, 0x20, 0xe8, 0x68,
-+ 0xd8, 0x50, 0x94, 0xec, 0x2c, 0x44, 0x00, 0x00,
-+ 0x09, 0x08, 0x15, 0x13, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x09, 0x2b, 0x1d, 0x19, 0x0f, 0x71, 0x00, 0x00,
-+ 0x24, 0xa8, 0xfc, 0x08, 0xf8, 0x88, 0xf8, 0x00,
-+ 0xfc, 0x24, 0xfc, 0x24, 0xfc, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x15, 0x13, 0x23, 0x5d, 0x09, 0x7e,
-+ 0x09, 0x2a, 0x1c, 0x19, 0x0c, 0x71, 0x00, 0x00,
-+ 0x50, 0x3c, 0xd4, 0xb4, 0x6c, 0x94, 0xfc, 0x54,
-+ 0xcc, 0x70, 0xd0, 0x20, 0x50, 0x8c, 0x00, 0x00,
-+ 0x00, 0x3e, 0x29, 0x3e, 0x25, 0x3d, 0x29, 0x3f,
-+ 0x06, 0x7b, 0x1f, 0x09, 0x3f, 0x00, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0x00, 0xf8, 0x68, 0xf8, 0x00,
-+ 0xc0, 0xbc, 0xf0, 0x20, 0xf8, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x18, 0x25, 0x27, 0x79, 0x10, 0x7d,
-+ 0x13, 0x54, 0x3b, 0x32, 0x1f, 0x60, 0x00, 0x00,
-+ 0x40, 0xfc, 0x40, 0xf0, 0xfc, 0xe8, 0x40, 0xf0,
-+ 0xfc, 0x08, 0xfc, 0xc8, 0xa8, 0x18, 0x00, 0x00,
-+ 0x10, 0x13, 0x1a, 0x27, 0x26, 0x7a, 0x13, 0x7e,
-+ 0x12, 0x56, 0x3a, 0x32, 0x1c, 0x67, 0x00, 0x00,
-+ 0x20, 0xfc, 0x50, 0xfc, 0x50, 0x70, 0xfc, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0xf8, 0xc8, 0x04, 0x00, 0x00,
-+ 0x12, 0x12, 0x15, 0x2d, 0x26, 0x7a, 0x15, 0x7f,
-+ 0x10, 0x57, 0x38, 0x31, 0x1e, 0x60, 0x00, 0x00,
-+ 0x48, 0x88, 0xf4, 0xb4, 0xe8, 0xa8, 0xf4, 0x5c,
-+ 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0x1b, 0x26, 0x27, 0x7a, 0x12, 0x7e,
-+ 0x12, 0x56, 0x3a, 0x32, 0x1c, 0x65, 0x00, 0x00,
-+ 0x40, 0x78, 0xfc, 0x68, 0xb8, 0xf8, 0xa8, 0xf8,
-+ 0xa8, 0xf8, 0x28, 0xd4, 0xcc, 0x38, 0x00, 0x00,
-+ 0x11, 0x11, 0x1a, 0x25, 0x27, 0x7a, 0x13, 0x7f,
-+ 0x13, 0x56, 0x3b, 0x32, 0x1f, 0x64, 0x00, 0x00,
-+ 0x50, 0x50, 0xa0, 0x50, 0xf8, 0xe8, 0x98, 0xf8,
-+ 0x68, 0xd8, 0x68, 0xdc, 0x64, 0x84, 0x00, 0x00,
-+ 0x10, 0x10, 0x1b, 0x26, 0x27, 0x7a, 0x12, 0x7e,
-+ 0x12, 0x56, 0x3b, 0x35, 0x1d, 0x67, 0x00, 0x00,
-+ 0x40, 0x78, 0xfc, 0x68, 0xb8, 0xf8, 0xa8, 0xf8,
-+ 0xa8, 0xf8, 0xf8, 0x68, 0x68, 0xfc, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x22, 0x5c, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x19, 0x0f, 0x72, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8,
-+ 0x88, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x19, 0x27, 0x24, 0x7f, 0x15, 0x7f,
-+ 0x13, 0x56, 0x3b, 0x32, 0x1e, 0x62, 0x00, 0x00,
-+ 0x40, 0xa0, 0x10, 0xfc, 0x00, 0xfc, 0xb4, 0xfc,
-+ 0xf8, 0xa8, 0xf8, 0xa8, 0xa8, 0xb8, 0x00, 0x00,
-+ 0x10, 0x17, 0x18, 0x27, 0x26, 0x7b, 0x10, 0x7d,
-+ 0x13, 0x55, 0x39, 0x31, 0x1d, 0x61, 0x00, 0x00,
-+ 0xa0, 0xfc, 0xa0, 0xb8, 0xa8, 0xb8, 0x90, 0xfc,
-+ 0x20, 0xf8, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x13, 0x18, 0x24, 0x24, 0x7b, 0x10, 0x7f,
-+ 0x12, 0x57, 0x3b, 0x32, 0x1f, 0x60, 0x00, 0x00,
-+ 0x00, 0xfc, 0x90, 0xf0, 0xf0, 0xf0, 0x10, 0xfc,
-+ 0xa8, 0xb8, 0xb8, 0xa8, 0xf8, 0x88, 0x00, 0x00,
-+ 0x11, 0x11, 0x1a, 0x27, 0x25, 0x7a, 0x11, 0x7d,
-+ 0x11, 0x55, 0x39, 0x31, 0x1d, 0x66, 0x00, 0x00,
-+ 0x98, 0xfc, 0xa8, 0xfc, 0xd8, 0xac, 0xfc, 0x08,
-+ 0xf8, 0xf8, 0x08, 0xf8, 0x98, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x13, 0x22, 0x5d, 0x08, 0x7e,
-+ 0x08, 0x2a, 0x1c, 0x18, 0x0e, 0x73, 0x00, 0x00,
-+ 0x90, 0xf8, 0x90, 0xfc, 0xd0, 0x28, 0xfc, 0x88,
-+ 0xf8, 0xf8, 0x88, 0xf8, 0xc8, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x1a, 0x27, 0x25, 0x79, 0x16, 0x7d,
-+ 0x12, 0x57, 0x39, 0x33, 0x1d, 0x61, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xf8, 0x28, 0x50, 0xfc, 0x50,
-+ 0xf8, 0xd0, 0x78, 0xd0, 0x7c, 0x40, 0x00, 0x00,
-+ 0x13, 0x17, 0x6b, 0x17, 0x7f, 0x3a, 0x57, 0x11,
-+ 0x06, 0x7b, 0x1f, 0x09, 0x3f, 0x00, 0x00, 0x00,
-+ 0x90, 0xd4, 0xe8, 0x98, 0xfc, 0xb8, 0xd4, 0x10,
-+ 0xc0, 0xbc, 0xf0, 0x20, 0xf8, 0x00, 0x00, 0x00,
-+ 0x13, 0x12, 0x1b, 0x27, 0x27, 0x79, 0x13, 0x7d,
-+ 0x11, 0x55, 0x3b, 0x30, 0x1c, 0x63, 0x00, 0x00,
-+ 0xb8, 0xa8, 0xb8, 0xb8, 0xb8, 0xfc, 0xf8, 0xf8,
-+ 0x20, 0xfc, 0xf8, 0x90, 0x60, 0x9c, 0x00, 0x00,
-+ 0x2d, 0x7f, 0x12, 0x3f, 0x7f, 0x2b, 0x3b, 0x3f,
-+ 0x06, 0x7b, 0x1f, 0x09, 0x3f, 0x00, 0x00, 0x00,
-+ 0x70, 0xd0, 0x54, 0x8c, 0xf8, 0x50, 0xf0, 0x0c,
-+ 0xc0, 0xbc, 0xf0, 0x20, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x20, 0x20,
-+ 0x2f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0x08,
-+ 0xe8, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x20, 0x2f,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0xe8,
-+ 0x08, 0x88, 0x48, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x21, 0x29,
-+ 0x29, 0x29, 0x29, 0x2f, 0x28, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0x28,
-+ 0x28, 0x28, 0x28, 0xe8, 0x28, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x21, 0x21,
-+ 0x2f, 0x22, 0x21, 0x22, 0x2c, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0x08,
-+ 0xe8, 0x88, 0x08, 0x88, 0x68, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x21, 0x21,
-+ 0x2f, 0x23, 0x25, 0x29, 0x23, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0x28,
-+ 0xc8, 0x88, 0x48, 0x28, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x20, 0x27,
-+ 0x25, 0x27, 0x25, 0x27, 0x21, 0x21, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0xc8,
-+ 0x48, 0xc8, 0x48, 0xc8, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x21, 0x3f,
-+ 0x21, 0x2f, 0x29, 0x29, 0x29, 0x21, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xe8, 0x28, 0x28, 0xc8, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x20, 0x2f,
-+ 0x21, 0x27, 0x21, 0x21, 0x2f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0xe8,
-+ 0x08, 0xc8, 0x88, 0x48, 0xe8, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x21, 0x27,
-+ 0x21, 0x2f, 0x27, 0x21, 0x2f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0xc8,
-+ 0x08, 0xe8, 0xc8, 0x08, 0xe8, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x20, 0x22,
-+ 0x2f, 0x22, 0x2f, 0x22, 0x2c, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0x88,
-+ 0xe8, 0x88, 0xe8, 0x88, 0x48, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x27, 0x24,
-+ 0x27, 0x22, 0x27, 0x24, 0x27, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xc8, 0x48,
-+ 0xc8, 0x08, 0xc8, 0x48, 0xc8, 0x58, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x24, 0x3f,
-+ 0x24, 0x27, 0x25, 0x29, 0x36, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x48, 0x48,
-+ 0xa8, 0xd8, 0x28, 0xc8, 0x28, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x23, 0x24,
-+ 0x29, 0x26, 0x26, 0x24, 0x27, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xc8, 0x48,
-+ 0x88, 0xc8, 0xc8, 0x48, 0xc8, 0x58, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x21, 0x3f,
-+ 0x27, 0x2d, 0x37, 0x27, 0x25, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x08, 0xf8,
-+ 0xc8, 0x68, 0xd8, 0xc8, 0x28, 0xf8, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x20, 0x3f,
-+ 0x2e, 0x2a, 0x2e, 0x26, 0x39, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xa8, 0xf8,
-+ 0xa8, 0xc8, 0x68, 0xe8, 0x28, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x28, 0x25,
-+ 0x33, 0x28, 0x25, 0x25, 0x29, 0x29, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x68, 0x88,
-+ 0xf8, 0x88, 0xe8, 0x28, 0xe8, 0x38, 0x00, 0x00,
-+ 0x20, 0x1f, 0x19, 0x4f, 0x29, 0x2f, 0x08, 0x1b,
-+ 0x1f, 0x28, 0x2b, 0x4a, 0x4b, 0x4a, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x78, 0x48, 0x78, 0x68, 0x88,
-+ 0xf8, 0x88, 0xe8, 0x28, 0xe8, 0x38, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x3e, 0x27, 0x24, 0x27,
-+ 0x27, 0x27, 0x21, 0x2f, 0x22, 0x2c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0xf8, 0xc8, 0x48, 0xc8,
-+ 0xc8, 0xc8, 0x48, 0xe8, 0x88, 0x78, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x3e, 0x21, 0x27, 0x2f,
-+ 0x21, 0x27, 0x3b, 0x22, 0x23, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0xf8, 0x28, 0xc8, 0xe8,
-+ 0x48, 0xe8, 0xc8, 0x48, 0xc8, 0x58, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x3e, 0x21, 0x2f, 0x27,
-+ 0x25, 0x27, 0x27, 0x23, 0x2d, 0x21, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0xf8, 0x08, 0xe8, 0xc8,
-+ 0x48, 0xc8, 0xc8, 0x88, 0x68, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x29, 0x26,
-+ 0x3f, 0x25, 0x2d, 0x2f, 0x24, 0x29, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x88,
-+ 0xf8, 0x68, 0x48, 0x48, 0xa8, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x3e, 0x21, 0x27, 0x2f,
-+ 0x22, 0x2f, 0x27, 0x27, 0x2f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0xf8, 0x08, 0xc8, 0xe8,
-+ 0x48, 0xe8, 0xc8, 0x48, 0xe8, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x3e, 0x27, 0x25, 0x27,
-+ 0x27, 0x25, 0x27, 0x2e, 0x2d, 0x30, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0xf8, 0xe8, 0x08, 0xc8,
-+ 0xc8, 0x08, 0xe8, 0xa8, 0x68, 0xd8, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x24, 0x3b,
-+ 0x26, 0x3f, 0x2a, 0x2e, 0x24, 0x28, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x48, 0xa8,
-+ 0x68, 0xf8, 0xa8, 0xe8, 0x88, 0x98, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x3e, 0x2e, 0x2a, 0x2e,
-+ 0x27, 0x25, 0x27, 0x27, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0xf8, 0xe8, 0xa8, 0xe8,
-+ 0xc8, 0x48, 0xc8, 0xc8, 0xf8, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x3e, 0x28, 0x25, 0x2b,
-+ 0x25, 0x23, 0x2d, 0x27, 0x24, 0x2b, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0xf8, 0x88, 0xc8, 0xe8,
-+ 0x48, 0xe8, 0xc8, 0xe8, 0x88, 0xf8, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x2e, 0x2b,
-+ 0x2e, 0x29, 0x2e, 0x3b, 0x2e, 0x28, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x48, 0xf8,
-+ 0xa8, 0xf8, 0x48, 0xf8, 0x48, 0x58, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x28, 0x30, 0x28, 0x27, 0x24,
-+ 0x24, 0x24, 0x38, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x30, 0xe0, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x29, 0x31, 0x29, 0x25, 0x25,
-+ 0x25, 0x25, 0x3a, 0x22, 0x24, 0x28, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x00, 0x78, 0x48, 0x48, 0x48,
-+ 0x48, 0x70, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x3d, 0x24, 0x28, 0x30, 0x2b, 0x24, 0x24,
-+ 0x24, 0x24, 0x39, 0x21, 0x22, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0x00, 0x00, 0xfc, 0xa0, 0xa0,
-+ 0xa0, 0xa0, 0x24, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x29, 0x31, 0x29, 0x25, 0x25,
-+ 0x25, 0x25, 0x39, 0x21, 0x27, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40,
-+ 0x40, 0x40, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x29, 0x31, 0x29, 0x25, 0x25,
-+ 0x25, 0x25, 0x3a, 0x22, 0x24, 0x2b, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x28, 0x20, 0xf8, 0x88,
-+ 0x50, 0x50, 0x20, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x28, 0x30, 0x29, 0x25, 0x25,
-+ 0x25, 0x25, 0x39, 0x21, 0x21, 0x21, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0x80, 0xf8, 0x08, 0x08,
-+ 0xf8, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x2b, 0x30, 0x28, 0x25, 0x26,
-+ 0x24, 0x24, 0x38, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x80, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x00, 0x39, 0x28, 0x2a, 0x32, 0x32, 0x2a, 0x2a,
-+ 0x2a, 0x2a, 0x3a, 0x22, 0x23, 0x22, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xf8, 0xa8, 0xa8, 0xa8, 0xd8,
-+ 0x98, 0x88, 0x98, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x29, 0x31, 0x2a, 0x24, 0x25,
-+ 0x25, 0x25, 0x39, 0x21, 0x21, 0x21, 0x00, 0x00,
-+ 0x80, 0xf8, 0x88, 0x08, 0x08, 0x30, 0x40, 0xb8,
-+ 0x08, 0xb8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x2b, 0x31, 0x29, 0x25, 0x26,
-+ 0x24, 0x24, 0x38, 0x21, 0x22, 0x24, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x50, 0x50, 0x50, 0xe8,
-+ 0x48, 0xa0, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x3d, 0x24, 0x28, 0x33, 0x28, 0x25, 0x26,
-+ 0x24, 0x27, 0x38, 0x20, 0x27, 0x20, 0x00, 0x00,
-+ 0x30, 0xd0, 0x90, 0x90, 0xfc, 0x90, 0x10, 0x50,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x2b, 0x30, 0x2b, 0x25, 0x25,
-+ 0x26, 0x24, 0x38, 0x21, 0x22, 0x24, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0xfc, 0x40, 0x58, 0x48, 0x48,
-+ 0xd4, 0xa4, 0xa0, 0x10, 0x08, 0x04, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x28, 0x30, 0x2b, 0x24, 0x24,
-+ 0x24, 0x25, 0x3a, 0x20, 0x20, 0x23, 0x00, 0x00,
-+ 0x20, 0x20, 0xb8, 0xa0, 0xa0, 0xfc, 0x20, 0xa4,
-+ 0xa4, 0x28, 0x70, 0x20, 0xc0, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x27, 0x28, 0x31, 0x28, 0x27, 0x24,
-+ 0x27, 0x39, 0x22, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0x90,
-+ 0xfc, 0x90, 0x50, 0x50, 0x10, 0x30, 0x00, 0x00,
-+ 0x00, 0x3d, 0x24, 0x2b, 0x31, 0x29, 0x27, 0x25,
-+ 0x25, 0x27, 0x38, 0x20, 0x27, 0x20, 0x00, 0x00,
-+ 0x18, 0xe0, 0x40, 0xf8, 0x50, 0x50, 0xfc, 0x50,
-+ 0x50, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x2a, 0x2a, 0x33, 0x32, 0x2a, 0x2b,
-+ 0x2a, 0x2a, 0x3b, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0x80, 0xf8, 0xa8, 0xa8, 0xa8,
-+ 0xb0, 0x90, 0xb0, 0xa8, 0xc8, 0x84, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x29, 0x31, 0x29, 0x25, 0x24,
-+ 0x27, 0x24, 0x39, 0x20, 0x27, 0x20, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x00,
-+ 0xfc, 0x40, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x2a, 0x30, 0x28, 0x24, 0x25,
-+ 0x27, 0x25, 0x39, 0x21, 0x23, 0x20, 0x00, 0x00,
-+ 0xf0, 0x90, 0x08, 0xf4, 0x00, 0xf0, 0x90, 0x08,
-+ 0xfc, 0x68, 0x68, 0x68, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x29, 0x30, 0x29, 0x25, 0x25,
-+ 0x25, 0x25, 0x39, 0x21, 0x21, 0x26, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x00, 0xf8, 0x08, 0xf8,
-+ 0x08, 0xf8, 0x08, 0xf8, 0x98, 0x04, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x29, 0x31, 0x29, 0x25, 0x25,
-+ 0x24, 0x24, 0x38, 0x21, 0x22, 0x24, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x48, 0x48, 0xf8, 0x48, 0xf8,
-+ 0xd0, 0xd0, 0xe8, 0x7c, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x38, 0x28, 0x29, 0x33, 0x34, 0x2b, 0x2a,
-+ 0x2a, 0x2b, 0x39, 0x21, 0x22, 0x24, 0x00, 0x00,
-+ 0x40, 0x40, 0xa0, 0x10, 0xf8, 0x04, 0xb8, 0xa8,
-+ 0xa8, 0xb8, 0x10, 0x98, 0x64, 0x44, 0x00, 0x00,
-+ 0x04, 0x3a, 0x2a, 0x29, 0x34, 0x32, 0x2b, 0x28,
-+ 0x2f, 0x2a, 0x3b, 0x22, 0x25, 0x28, 0x00, 0x00,
-+ 0x70, 0x50, 0x88, 0xfc, 0x20, 0x64, 0xb4, 0x58,
-+ 0xb8, 0x54, 0x94, 0x10, 0x60, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x2b, 0x30, 0x29, 0x25, 0x24,
-+ 0x27, 0x25, 0x38, 0x22, 0x22, 0x24, 0x00, 0x00,
-+ 0x18, 0xe8, 0x24, 0xf4, 0x40, 0xf0, 0xf8, 0x08,
-+ 0xfc, 0xf8, 0x48, 0xa4, 0x94, 0x70, 0x00, 0x00,
-+ 0x00, 0x3c, 0x25, 0x2a, 0x31, 0x29, 0x25, 0x25,
-+ 0x25, 0x25, 0x39, 0x23, 0x22, 0x24, 0x00, 0x00,
-+ 0x20, 0xa8, 0x6c, 0x34, 0xc0, 0xfc, 0x20, 0xf8,
-+ 0xf8, 0x20, 0xfc, 0x54, 0xac, 0x18, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x29, 0x31, 0x29, 0x24, 0x27,
-+ 0x24, 0x25, 0x3b, 0x20, 0x22, 0x24, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xf8, 0x08, 0xf8, 0x88, 0x74,
-+ 0x88, 0x54, 0xfc, 0x00, 0xa8, 0x54, 0x00, 0x00,
-+ 0x01, 0x39, 0x2f, 0x2a, 0x37, 0x30, 0x2b, 0x2a,
-+ 0x2b, 0x3a, 0x23, 0x22, 0x22, 0x22, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0xa0, 0xf8, 0x08, 0xb8, 0xa0,
-+ 0xb8, 0xb8, 0xa0, 0xb8, 0xa4, 0x9c, 0x00, 0x00,
-+ 0x01, 0x01, 0x1f, 0x01, 0x7f, 0x01, 0x1f, 0x11,
-+ 0x09, 0x0b, 0x0d, 0x71, 0x01, 0x03, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x10, 0xfc, 0x10, 0xf0, 0x10,
-+ 0x90, 0xa0, 0x40, 0x30, 0x0c, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7e, 0x1c, 0x1b, 0x2a, 0x48, 0x3e,
-+ 0x00, 0x7e, 0x2c, 0x2b, 0x4a, 0x18, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x28, 0xfc, 0x28, 0xf8, 0x28,
-+ 0xa4, 0x78, 0x70, 0xa8, 0x24, 0x60, 0x00, 0x00,
-+ 0x04, 0x04, 0x04, 0x0f, 0x08, 0x18, 0x2f, 0x48,
-+ 0x08, 0x0f, 0x08, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0xfc, 0x40, 0x40, 0xf8, 0x40,
-+ 0x40, 0xf8, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3c, 0x24, 0x24, 0x3c, 0x25, 0x26, 0x3c,
-+ 0x24, 0x24, 0x26, 0x38, 0x60, 0x00, 0x00, 0x00,
-+ 0x48, 0x48, 0x50, 0xfc, 0x90, 0x90, 0xf8, 0x90,
-+ 0x90, 0xf8, 0x90, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x04, 0x04, 0x0f, 0x08, 0x1f, 0x28, 0x4f, 0x08,
-+ 0x0f, 0x1e, 0x12, 0x13, 0x12, 0x10, 0x00, 0x00,
-+ 0x20, 0x40, 0xfc, 0x40, 0xf0, 0x40, 0xf0, 0x40,
-+ 0xfc, 0x78, 0x48, 0xc8, 0x48, 0x18, 0x00, 0x00,
-+ 0x10, 0x10, 0x10, 0x1e, 0x28, 0x49, 0x7f, 0x08,
-+ 0x08, 0x14, 0x12, 0x22, 0x40, 0x00, 0x00, 0x00,
-+ 0x48, 0x48, 0x50, 0xfc, 0x90, 0x90, 0xf8, 0x90,
-+ 0x90, 0xf8, 0x90, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x10, 0x14, 0x65, 0x29, 0x1b,
-+ 0x15, 0x1d, 0x65, 0x09, 0x11, 0x21, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x90, 0x90, 0xfc, 0x20, 0xf8,
-+ 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x10, 0x10, 0x11, 0x7f, 0x09, 0x0b, 0x15, 0x39,
-+ 0x54, 0x17, 0x10, 0x11, 0x16, 0x10, 0x00, 0x00,
-+ 0x90, 0xa0, 0xfc, 0x20, 0xf8, 0xf8, 0x20, 0xfc,
-+ 0x40, 0xfc, 0xe0, 0x50, 0x4c, 0x40, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x12, 0x12, 0x2d, 0x49, 0x08,
-+ 0x7f, 0x1c, 0x1a, 0x2a, 0x48, 0x08, 0x00, 0x00,
-+ 0x48, 0x48, 0x50, 0xfc, 0x90, 0x90, 0xf8, 0x90,
-+ 0x90, 0xf8, 0x90, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x00, 0x3f, 0x01, 0x3f, 0x3d, 0x5d, 0x05, 0x0f,
-+ 0x18, 0x6f, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x00, 0xfc, 0x78, 0x70, 0x40, 0xf8,
-+ 0x80, 0xf0, 0xf0, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3f, 0x25, 0x25, 0x3f, 0x25, 0x3f, 0x25,
-+ 0x2f, 0x2b, 0x2f, 0x2b, 0x21, 0x43, 0x00, 0x00,
-+ 0x48, 0x48, 0x50, 0x7c, 0xd0, 0xd0, 0x78, 0x50,
-+ 0x50, 0x78, 0x50, 0x50, 0x7c, 0x40, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x5d, 0x02, 0x07,
-+ 0x18, 0x6f, 0x08, 0x0f, 0x08, 0x07, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x78, 0x70, 0x00, 0xf0,
-+ 0x10, 0x90, 0x90, 0xe4, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x5d, 0x05, 0x19,
-+ 0x6f, 0x08, 0x0f, 0x0f, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x78, 0x70, 0x60, 0x18,
-+ 0xe4, 0x20, 0xe0, 0xe0, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x5d, 0x00, 0x3d,
-+ 0x08, 0x3f, 0x12, 0x0c, 0x1e, 0x61, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x78, 0x70, 0x18, 0xe0,
-+ 0x20, 0xfc, 0x20, 0xf8, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x21, 0x5d, 0x1d, 0x10,
-+ 0x4f, 0x20, 0x0b, 0x12, 0x22, 0x20, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x08, 0x70, 0x70, 0x40,
-+ 0xfc, 0x40, 0xf8, 0x48, 0x70, 0x40, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x5d, 0x03, 0x1c,
-+ 0x1e, 0x10, 0x1f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x78, 0x70, 0x00, 0xf0,
-+ 0xf0, 0x10, 0xf0, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x5d, 0x01, 0x3f,
-+ 0x04, 0x7f, 0x3f, 0x0e, 0x03, 0x3c, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x78, 0x70, 0x00, 0xf8,
-+ 0x40, 0xfc, 0xf8, 0x40, 0xc0, 0x30, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x21, 0x5d, 0x1d, 0x10,
-+ 0x48, 0x20, 0x0b, 0x12, 0x23, 0x22, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x08, 0x70, 0x70, 0x40,
-+ 0x7c, 0x40, 0xf8, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x21, 0x5d, 0x1d, 0x02,
-+ 0x3e, 0x02, 0x3e, 0x02, 0x7c, 0x08, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x08, 0x70, 0x70, 0x80,
-+ 0xf8, 0x80, 0xf8, 0x80, 0xfc, 0x80, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x21, 0x5d, 0x1d, 0x08,
-+ 0x7f, 0x1c, 0x1a, 0x2a, 0x49, 0x08, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x08, 0x70, 0x70, 0x20,
-+ 0xfc, 0x70, 0x70, 0xa8, 0x24, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x5d, 0x04, 0x7f,
-+ 0x05, 0x0f, 0x09, 0x7f, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x78, 0x70, 0x40, 0xfc,
-+ 0x40, 0xe0, 0x20, 0xfc, 0xc0, 0x38, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x5d, 0x1e, 0x12,
-+ 0x3d, 0x0f, 0x0f, 0x09, 0x0f, 0x08, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x78, 0x70, 0xf8, 0x48,
-+ 0x98, 0xe0, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x5d, 0x10, 0x0b,
-+ 0x46, 0x21, 0x0f, 0x10, 0x23, 0x20, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x78, 0x70, 0x18, 0xf0,
-+ 0x4c, 0xf0, 0xfc, 0x40, 0xf8, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x5d, 0x3f, 0x14,
-+ 0x7f, 0x1f, 0x1e, 0x1e, 0x12, 0x17, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x78, 0x70, 0x40, 0x7c,
-+ 0x90, 0x50, 0x20, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x5d, 0x1e, 0x12,
-+ 0x1e, 0x11, 0x3e, 0x53, 0x1e, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x78, 0x70, 0x20, 0xf8,
-+ 0x50, 0xfc, 0x20, 0xfc, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x5d, 0x01, 0x7f,
-+ 0x3e, 0x15, 0x6d, 0x07, 0x0f, 0x30, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x78, 0x70, 0x00, 0xfc,
-+ 0xf8, 0x50, 0x7c, 0xe0, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x5d, 0x0d, 0x79,
-+ 0x2f, 0x79, 0x35, 0x1c, 0x67, 0x18, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x78, 0x70, 0xf0, 0x50,
-+ 0xf0, 0xf0, 0xf8, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x5d, 0x1c, 0x7f,
-+ 0x1c, 0x1c, 0x3e, 0x23, 0x3e, 0x22, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x78, 0x70, 0xf8, 0x88,
-+ 0xf8, 0xf8, 0x7c, 0xd4, 0xfc, 0x98, 0x00, 0x00,
-+ 0x00, 0x3f, 0x08, 0x3e, 0x2a, 0x7f, 0x3e, 0x08,
-+ 0x3c, 0x01, 0x7e, 0x14, 0x3e, 0x43, 0x00, 0x00,
-+ 0x10, 0x10, 0xf8, 0x98, 0x7c, 0x18, 0xf8, 0xd4,
-+ 0x38, 0xb8, 0xd4, 0x94, 0xf0, 0x3c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x5d, 0x3b, 0x2a,
-+ 0x3b, 0x3f, 0x09, 0x35, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x78, 0x70, 0xb8, 0xa8,
-+ 0xb8, 0xf8, 0x30, 0x48, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x01, 0x3f, 0x3d, 0x5d, 0x3f, 0x2e,
-+ 0x3f, 0x2e, 0x35, 0x24, 0x24, 0x5f, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x78, 0x70, 0xfc, 0x70,
-+ 0xfc, 0x70, 0xa8, 0xf0, 0x80, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3e, 0x08, 0x3e, 0x2b, 0x7f, 0x3e, 0x08,
-+ 0x3d, 0x00, 0x7e, 0x15, 0x1e, 0x63, 0x00, 0x00,
-+ 0x0c, 0xf4, 0xa8, 0x50, 0xfc, 0x28, 0xd8, 0xf4,
-+ 0x44, 0x78, 0xc8, 0x30, 0x70, 0x8c, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3f, 0x08, 0x7f, 0x3f,
-+ 0x2a, 0x2a, 0x3e, 0x22, 0x22, 0x26, 0x00, 0x00,
-+ 0x18, 0xf0, 0xa8, 0xa4, 0x04, 0xf8, 0x28, 0xfc,
-+ 0x28, 0xf8, 0x28, 0x20, 0x20, 0x60, 0x00, 0x00,
-+ 0x09, 0x0f, 0x11, 0x7f, 0x0f, 0x08, 0x0f, 0x7e,
-+ 0x02, 0x3e, 0x03, 0x7c, 0x0c, 0x30, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xfc, 0xe0, 0x20, 0xe0, 0xfc,
-+ 0x80, 0xf8, 0x80, 0xfc, 0x80, 0x80, 0x00, 0x00,
-+ 0x00, 0x7f, 0x08, 0x10, 0x3f, 0x2b, 0x2b, 0x2f,
-+ 0x2b, 0x2f, 0x2b, 0x2b, 0x3f, 0x21, 0x00, 0x00,
-+ 0x40, 0xc0, 0x40, 0x78, 0x88, 0xf8, 0x58, 0x58,
-+ 0x78, 0x50, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x08, 0x08, 0x3f, 0x2a, 0x2a, 0x2e,
-+ 0x2a, 0x2e, 0x2a, 0x2a, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xf8, 0xc8, 0xf8, 0xc8,
-+ 0xf8, 0xb0, 0xb0, 0xd4, 0xd4, 0x8c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x17, 0x17, 0x1f, 0x2f, 0x4f, 0x09,
-+ 0x7f, 0x1f, 0x13, 0x13, 0x1f, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x18, 0x14, 0xfc, 0x90, 0xa8, 0xc4,
-+ 0xfc, 0xf0, 0x90, 0x90, 0xf0, 0x10, 0x00, 0x00,
-+ 0x14, 0x14, 0x7f, 0x14, 0x1d, 0x08, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x48,
-+ 0x48, 0x48, 0x88, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x14, 0x15, 0x7e, 0x14, 0x1c, 0x08, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x00, 0xf8, 0xc8, 0xa8, 0xa8, 0x48, 0x50, 0x50,
-+ 0x20, 0x20, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x14, 0x15, 0x7e, 0x14, 0x1d, 0x08, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0xc8, 0x48, 0x68,
-+ 0x58, 0x4c, 0xc8, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x14, 0x14, 0x7f, 0x15, 0x1d, 0x09, 0x3f, 0x2b,
-+ 0x3f, 0x09, 0x7f, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0xc0, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x68, 0x98,
-+ 0x98, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x14, 0x14, 0x7f, 0x14, 0x1c, 0x08, 0x3e, 0x2b,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x09, 0x0a, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xf8, 0xa8, 0xa8, 0xa8, 0xfc,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x14, 0x14, 0x7f, 0x14, 0x1c, 0x08, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x0b, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x88,
-+ 0x88, 0xf8, 0x88, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x14, 0x14, 0x7f, 0x14, 0x1c, 0x08, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x09, 0x0a, 0x09, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0xa8, 0xb0, 0xa0, 0xf8, 0xc8,
-+ 0xc8, 0xb0, 0x30, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x14, 0x14, 0x7f, 0x15, 0x1c, 0x08, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0x70,
-+ 0x70, 0xa8, 0x24, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x14, 0x15, 0x7e, 0x14, 0x1d, 0x09, 0x3f, 0x2b,
-+ 0x3f, 0x09, 0x7f, 0x09, 0x09, 0x09, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0x40, 0xf8, 0x48, 0x48, 0x68,
-+ 0x98, 0x98, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x14, 0x14, 0x7f, 0x14, 0x1c, 0x09, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x09, 0x08, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0xf8, 0x20, 0x20, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x7f, 0x09, 0x09, 0x0f, 0x72, 0x04, 0x7f,
-+ 0x07, 0x0f, 0x09, 0x0f, 0x7f, 0x01, 0x00, 0x00,
-+ 0x00, 0xf0, 0x90, 0x54, 0x54, 0x0c, 0x40, 0xfc,
-+ 0xc0, 0xe0, 0x20, 0xe0, 0xfc, 0x00, 0x00, 0x00,
-+ 0x14, 0x14, 0x7f, 0x14, 0x1c, 0x09, 0x3e, 0x2b,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x40, 0x40, 0xfc, 0x00, 0xfc,
-+ 0x60, 0x50, 0x50, 0x40, 0x40, 0x40, 0x00, 0x00,
-+ 0x14, 0x14, 0x7f, 0x14, 0x1c, 0x09, 0x3e, 0x2a,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x20, 0x24, 0xf8, 0x70, 0xa8, 0x24, 0x60, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x14, 0x14, 0x7e, 0x14, 0x1c, 0x08, 0x3e, 0x2a,
-+ 0x3f, 0x08, 0x7e, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x40, 0xfc,
-+ 0xa4, 0xb4, 0xcc, 0xfc, 0x84, 0x18, 0x00, 0x00,
-+ 0x28, 0x28, 0x7f, 0x28, 0x38, 0x13, 0x7c, 0x55,
-+ 0x7d, 0x12, 0x7e, 0x14, 0x10, 0x10, 0x00, 0x00,
-+ 0x50, 0x90, 0x90, 0x94, 0xb4, 0xf4, 0xb8, 0xd0,
-+ 0xd0, 0xe8, 0xa8, 0xa8, 0xc4, 0x84, 0x00, 0x00,
-+ 0x14, 0x15, 0x7e, 0x14, 0x1d, 0x08, 0x3e, 0x2b,
-+ 0x3e, 0x09, 0x7f, 0x08, 0x09, 0x08, 0x00, 0x00,
-+ 0x00, 0xf8, 0x50, 0x20, 0xfc, 0x68, 0xb0, 0x60,
-+ 0x20, 0xfc, 0x70, 0xa8, 0x24, 0x20, 0x00, 0x00,
-+ 0x14, 0x14, 0x7f, 0x14, 0x1c, 0x08, 0x3e, 0x2b,
-+ 0x3e, 0x08, 0x7f, 0x08, 0x08, 0x08, 0x00, 0x00,
-+ 0x50, 0x50, 0xfc, 0x50, 0x20, 0x50, 0x88, 0xfc,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x28, 0x28, 0x7f, 0x28, 0x39, 0x11, 0x7d, 0x55,
-+ 0x7d, 0x11, 0x7e, 0x12, 0x14, 0x10, 0x00, 0x00,
-+ 0x90, 0x90, 0xfc, 0x90, 0xfc, 0x00, 0xf8, 0xa8,
-+ 0xf8, 0xa8, 0xf8, 0xa8, 0xa8, 0x98, 0x00, 0x00,
-+ 0x2a, 0x29, 0x7d, 0x28, 0x3a, 0x11, 0x7d, 0x54,
-+ 0x7f, 0x11, 0x7d, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x20, 0xfc, 0x50, 0xfc, 0x20,
-+ 0xf8, 0x20, 0xfc, 0x20, 0xa0, 0x7c, 0x00, 0x00,
-+ 0x2a, 0x29, 0x7d, 0x28, 0x3a, 0x11, 0x7d, 0x54,
-+ 0x7f, 0x11, 0x7d, 0x11, 0x12, 0x14, 0x00, 0x00,
-+ 0x00, 0xfc, 0x30, 0xfc, 0xb4, 0xfc, 0x20, 0xfc,
-+ 0x78, 0xd4, 0x70, 0x48, 0xb8, 0x7c, 0x00, 0x00,
-+ 0x28, 0x2f, 0x7c, 0x2b, 0x3a, 0x13, 0x7c, 0x57,
-+ 0x7e, 0x13, 0x7e, 0x12, 0x14, 0x14, 0x00, 0x00,
-+ 0xa0, 0xfc, 0xa0, 0xf8, 0xa8, 0xf8, 0x48, 0xfc,
-+ 0x48, 0x28, 0xb0, 0x94, 0x2c, 0x44, 0x00, 0x00,
-+ 0x01, 0x1f, 0x02, 0x7f, 0x00, 0x0f, 0x08, 0x0f,
-+ 0x00, 0x0f, 0x08, 0x7f, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xfc, 0x00, 0xe0, 0x20, 0xe0,
-+ 0x40, 0xf8, 0x40, 0xfc, 0x40, 0x40, 0x00, 0x00,
-+ 0x08, 0x3e, 0x12, 0x7f, 0x01, 0x3e, 0x22, 0x3e,
-+ 0x04, 0x3e, 0x24, 0x7f, 0x04, 0x04, 0x00, 0x00,
-+ 0x18, 0xf0, 0xa8, 0xa4, 0x04, 0x20, 0xd8, 0x88,
-+ 0x88, 0xd8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x02, 0x02, 0x02, 0x3e, 0x02, 0x02, 0x3e, 0x02,
-+ 0x02, 0x3e, 0x02, 0x02, 0x7f, 0x00, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x78, 0x40,
-+ 0x40, 0x78, 0x40, 0x40, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x7f, 0x3e, 0x15, 0x2d, 0x51, 0x1f, 0x1f,
-+ 0x12, 0x16, 0x16, 0x16, 0x2f, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf8, 0x50, 0x68, 0x14, 0xf0, 0xf0,
-+ 0x90, 0xd0, 0xd0, 0xd0, 0xf0, 0x10, 0x00, 0x00,
-+ 0x01, 0x7f, 0x02, 0x3d, 0x15, 0x2d, 0x42, 0x3e,
-+ 0x02, 0x1e, 0x1e, 0x02, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0x70, 0x50, 0xe8, 0x84, 0xf8,
-+ 0x80, 0xf0, 0xf0, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x01, 0x3f, 0x04, 0x7f, 0x00, 0x0f, 0x08,
-+ 0x0f, 0x08, 0x0f, 0x02, 0x0c, 0x70, 0x00, 0x00,
-+ 0x00, 0x00, 0xf8, 0x40, 0xfc, 0x00, 0xe0, 0x20,
-+ 0xe0, 0x20, 0xe0, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x09, 0x7e, 0x24, 0x14, 0x18, 0x7f, 0x00,
-+ 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0x48, 0x88, 0x30, 0x00,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x7e, 0x24, 0x15, 0x19, 0x7e, 0x00,
-+ 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x22, 0x00, 0x00,
-+ 0x80, 0x80, 0x80, 0xf8, 0x08, 0x08, 0xe8, 0x08,
-+ 0x28, 0xc8, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x7f, 0x00, 0x1c, 0x14, 0x14,
-+ 0x14, 0x15, 0x15, 0x23, 0x20, 0x43, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x1d, 0x04, 0x14, 0x12, 0x22, 0x49, 0x08,
-+ 0x08, 0x14, 0x16, 0x7a, 0x00, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x7f, 0x2a, 0x2a, 0x54, 0x2a, 0x2a, 0x00,
-+ 0x7e, 0x08, 0x08, 0x0e, 0x70, 0x03, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x24, 0x2e, 0x2a, 0x2a, 0x2a,
-+ 0x2e, 0x24, 0x24, 0x24, 0x3e, 0x23, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x08, 0x7f, 0x08, 0x08, 0x3e, 0x00,
-+ 0x3e, 0x22, 0x22, 0x22, 0x3e, 0x23, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x12, 0x3e, 0x40, 0x3e, 0x04,
-+ 0x08, 0x3e, 0x22, 0x22, 0x3e, 0x23, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x02, 0x3d, 0x08, 0x7f, 0x1c, 0x2a, 0x4a, 0x1c,
-+ 0x14, 0x14, 0x15, 0x16, 0x24, 0x43, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x2a, 0x3e, 0x2a, 0x3e, 0x08, 0x7f,
-+ 0x1c, 0x1a, 0x2a, 0x48, 0x08, 0x0b, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x09, 0x7f, 0x14, 0x0c, 0x12, 0x3f, 0x24,
-+ 0x3a, 0x24, 0x39, 0x22, 0x4c, 0x33, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x2a, 0x2a, 0x3e, 0x2a, 0x3e, 0x08,
-+ 0x06, 0x35, 0x31, 0x54, 0x54, 0x0f, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x04, 0x7f, 0x3f, 0x2f, 0x2b, 0x2f, 0x3f, 0x1e,
-+ 0x12, 0x1e, 0x12, 0x1e, 0x0e, 0x71, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0x20, 0x78, 0x48, 0x78, 0x48,
-+ 0x78, 0x48, 0x78, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x00, 0x3f, 0x21, 0x3f, 0x21, 0x3f, 0x12, 0x6d,
-+ 0x2d, 0x1b, 0x7f, 0x35, 0x2a, 0x4a, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0x20, 0x78, 0x48, 0x78, 0x48,
-+ 0x78, 0x48, 0xf8, 0x30, 0xc8, 0x84, 0x00, 0x00,
-+ 0x08, 0x2f, 0x28, 0x7f, 0x2a, 0x5c, 0x1a, 0x6f,
-+ 0x09, 0x0f, 0x0f, 0x04, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0xf8, 0x88, 0xf8, 0xf8, 0xf8, 0xec,
-+ 0x20, 0xe0, 0xe0, 0x40, 0xfc, 0x40, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x04, 0x07, 0x3f, 0x2d, 0x37, 0x3f, 0x35, 0x3f,
-+ 0x3f, 0x20, 0x3f, 0x57, 0x17, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0x90, 0x20, 0x78, 0x48, 0x78, 0x48,
-+ 0x78, 0x48, 0x78, 0x30, 0xc8, 0x84, 0x00, 0x00,
-+ 0x14, 0x7f, 0x14, 0x77, 0x55, 0x77, 0x14, 0x3f,
-+ 0x64, 0x3e, 0x3e, 0x24, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0x20, 0x78, 0x48, 0x78, 0x48,
-+ 0x78, 0x48, 0x78, 0x30, 0x48, 0x84, 0x00, 0x00,
-+ 0x00, 0x3f, 0x09, 0x0f, 0x0f, 0x3f, 0x01, 0x7f,
-+ 0x2a, 0x3b, 0x3b, 0x2a, 0x7f, 0x08, 0x00, 0x00,
-+ 0x00, 0xfc, 0x10, 0x20, 0x78, 0x48, 0x78, 0xc8,
-+ 0xf8, 0xc8, 0xf8, 0xb0, 0xa8, 0xc4, 0x00, 0x00,
-+ 0x00, 0x7f, 0x01, 0x01, 0x01, 0x1f, 0x10, 0x1f,
-+ 0x17, 0x15, 0x17, 0x11, 0x2f, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0xc0, 0x20, 0x00, 0xf0, 0xd0, 0x10,
-+ 0xd0, 0x50, 0xd4, 0x6c, 0x9c, 0x04, 0x00, 0x00,
-+ 0x10, 0x13, 0x12, 0x13, 0x7e, 0x0b, 0x4b, 0x2b,
-+ 0x2b, 0x32, 0x1c, 0x64, 0x0b, 0x10, 0x00, 0x00,
-+ 0x00, 0xf0, 0x30, 0xd0, 0x90, 0xf0, 0xb0, 0xb0,
-+ 0xf0, 0xd0, 0xb4, 0xec, 0x1c, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x11, 0x1e, 0x14, 0x1f, 0x1d, 0x1d,
-+ 0x1f, 0x16, 0x15, 0x27, 0x38, 0x40, 0x00, 0x00,
-+ 0x20, 0xa0, 0xb0, 0xa8, 0xcc, 0xf4, 0x80, 0xf8,
-+ 0xc8, 0xc8, 0x78, 0xc4, 0xb4, 0x0c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x13, 0x1c, 0x14, 0x1f, 0x1d, 0x1d,
-+ 0x1f, 0x16, 0x15, 0x27, 0x38, 0x40, 0x00, 0x00,
-+ 0x00, 0xb8, 0xa8, 0xb8, 0xa8, 0xb8, 0xa8, 0xb8,
-+ 0xfc, 0x98, 0x64, 0xc4, 0xb4, 0x0c, 0x00, 0x00,
-+ 0x00, 0x7f, 0x19, 0x7f, 0x5b, 0x7f, 0x01, 0x3d,
-+ 0x01, 0x7f, 0x2d, 0x2a, 0x4b, 0x1c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x18, 0xe8, 0x48, 0xf8, 0xd8, 0xd8,
-+ 0xf8, 0x6c, 0x5c, 0x74, 0x94, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x23, 0x3d, 0x29, 0x3f, 0x3b, 0x3b,
-+ 0x3f, 0x2d, 0x2a, 0x2f, 0x31, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x30, 0xfc, 0xb4, 0xfc, 0x78, 0x00,
-+ 0xfc, 0x58, 0x94, 0xb4, 0x64, 0x1c, 0x00, 0x00,
-+ 0x0c, 0x0b, 0x3f, 0x09, 0x15, 0x13, 0x35, 0x2f,
-+ 0x7f, 0x25, 0x37, 0x2a, 0x4b, 0x54, 0x00, 0x00,
-+ 0x00, 0xf8, 0x18, 0xe8, 0x48, 0xf8, 0xd8, 0xd8,
-+ 0xf8, 0x6c, 0x5c, 0x74, 0x94, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x1f, 0x22, 0x7c, 0x24, 0x3c,
-+ 0x24, 0x3c, 0x3c, 0x20, 0x3e, 0x20, 0x00, 0x00,
-+ 0x20, 0x20, 0x3c, 0xe0, 0x20, 0xa8, 0xa8, 0xa8,
-+ 0xa8, 0xf8, 0xa8, 0x24, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x1e, 0x22, 0x7c, 0x25, 0x3c,
-+ 0x24, 0x3c, 0x3e, 0x20, 0x3f, 0x22, 0x00, 0x00,
-+ 0x08, 0x10, 0xe0, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x60, 0x50, 0x90, 0x08, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x1e, 0x22, 0x7c, 0x25, 0x3c,
-+ 0x24, 0x3c, 0x3e, 0x20, 0x3e, 0x23, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x50, 0x48, 0x94, 0x54, 0x50,
-+ 0x60, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x1f, 0x21, 0x7d, 0x25, 0x3d,
-+ 0x25, 0x3d, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x20, 0x20, 0x40, 0xf8, 0x08, 0xe8, 0xa8, 0xa8,
-+ 0xa8, 0xe8, 0xa8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x1e, 0x23, 0x7e, 0x22, 0x3f,
-+ 0x22, 0x3e, 0x3e, 0x20, 0x3e, 0x23, 0x00, 0x00,
-+ 0x18, 0xf0, 0xa8, 0xa4, 0x04, 0x20, 0x20, 0xfc,
-+ 0x48, 0x48, 0xf0, 0x10, 0x68, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x17, 0x1e, 0x23, 0x7d, 0x25, 0x3d,
-+ 0x25, 0x3d, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x50, 0x48, 0xfc, 0x40, 0xf8, 0x48, 0x48, 0xf8,
-+ 0x48, 0x48, 0xf8, 0x48, 0x48, 0x58, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x1e, 0x22, 0x7d, 0x24, 0x3d,
-+ 0x24, 0x3c, 0x3e, 0x21, 0x3e, 0x20, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0xfc, 0x20, 0xfc,
-+ 0x20, 0xb0, 0xa8, 0x24, 0x24, 0x60, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x1e, 0x23, 0x7e, 0x24, 0x3d,
-+ 0x25, 0x3d, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x80, 0xf8, 0x88, 0x88, 0x08, 0x30, 0x40, 0x98,
-+ 0x08, 0xd8, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x1e, 0x22, 0x7c, 0x25, 0x3c,
-+ 0x24, 0x3c, 0x3e, 0x20, 0x3f, 0x22, 0x00, 0x00,
-+ 0x50, 0x50, 0xfc, 0x50, 0x20, 0x20, 0xfc, 0x20,
-+ 0x38, 0x48, 0x48, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x1f, 0x22, 0x7c, 0x25, 0x3c,
-+ 0x24, 0x3d, 0x3e, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x50, 0x48, 0x7c, 0xc8, 0x30, 0x74, 0x8c, 0x54,
-+ 0x7c, 0xc8, 0x30, 0x74, 0x8c, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x1e, 0x23, 0x7c, 0x24, 0x3d,
-+ 0x24, 0x3c, 0x3f, 0x20, 0x3e, 0x21, 0x00, 0x00,
-+ 0x20, 0x24, 0xa4, 0xa8, 0x70, 0x50, 0x88, 0x24,
-+ 0xa4, 0xa8, 0x70, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x1f, 0x22, 0x7c, 0x24, 0x3c,
-+ 0x27, 0x3c, 0x3e, 0x21, 0x3f, 0x22, 0x00, 0x00,
-+ 0x90, 0x90, 0x20, 0xfc, 0x90, 0x90, 0x90, 0xd0,
-+ 0xbc, 0x90, 0x90, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x11, 0x11, 0x19, 0x27, 0x3d, 0x79, 0x2b, 0x3a,
-+ 0x2a, 0x3a, 0x3f, 0x22, 0x3c, 0x21, 0x00, 0x00,
-+ 0x00, 0x38, 0x28, 0xe8, 0x28, 0x38, 0xa8, 0xa8,
-+ 0xb8, 0xa8, 0xc8, 0x48, 0x88, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x09, 0x1e, 0x74, 0x19, 0x62, 0x0f,
-+ 0x77, 0x04, 0x07, 0x07, 0x07, 0x3c, 0x00, 0x00,
-+ 0x20, 0x50, 0xac, 0xd0, 0x68, 0x70, 0x80, 0xe0,
-+ 0xfc, 0x40, 0xc0, 0xd0, 0xe0, 0x38, 0x00, 0x00,
-+ 0x08, 0x08, 0x15, 0x1f, 0x23, 0x7d, 0x25, 0x3d,
-+ 0x24, 0x3c, 0x3f, 0x21, 0x3e, 0x24, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0xc8,
-+ 0xd0, 0xd0, 0x68, 0x7c, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x09, 0x15, 0x1f, 0x23, 0x7d, 0x27, 0x3c,
-+ 0x25, 0x3d, 0x3f, 0x21, 0x3f, 0x21, 0x00, 0x00,
-+ 0x40, 0xbc, 0x14, 0x94, 0x54, 0xd4, 0x2c, 0x40,
-+ 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x08, 0x00, 0x00,
-+ 0x08, 0x09, 0x15, 0x1f, 0x23, 0x7d, 0x25, 0x3c,
-+ 0x25, 0x3d, 0x3f, 0x21, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x68, 0x98, 0x18, 0xf8, 0x00,
-+ 0xf8, 0x68, 0x68, 0x68, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x1e, 0x22, 0x7c, 0x24, 0x3c,
-+ 0x25, 0x3c, 0x3e, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x50, 0xfc, 0x50, 0x70, 0xf8, 0xa8, 0xf8, 0x20,
-+ 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x1e, 0x22, 0x7c, 0x25, 0x3d,
-+ 0x25, 0x3c, 0x3e, 0x20, 0x3e, 0x23, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc, 0x54,
-+ 0xfc, 0xf8, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x08, 0x09, 0x14, 0x1e, 0x23, 0x7d, 0x27, 0x3c,
-+ 0x24, 0x3c, 0x3e, 0x20, 0x3f, 0x20, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0xfc, 0x08, 0xfc, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x50, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x1e, 0x23, 0x7c, 0x24, 0x3c,
-+ 0x24, 0x3c, 0x3e, 0x20, 0x3e, 0x23, 0x00, 0x00,
-+ 0x20, 0xf8, 0xa8, 0xf8, 0xfc, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x88, 0xf8, 0xc8, 0x04, 0x00, 0x00,
-+ 0x11, 0x11, 0x1a, 0x25, 0x3d, 0x7a, 0x2b, 0x38,
-+ 0x2b, 0x3b, 0x3e, 0x22, 0x3e, 0x24, 0x00, 0x00,
-+ 0x48, 0x48, 0xf4, 0xd4, 0x48, 0xd4, 0xfc, 0x48,
-+ 0xfc, 0x48, 0xa8, 0x34, 0xcc, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x1e, 0x23, 0x7c, 0x27, 0x3c,
-+ 0x24, 0x3f, 0x3f, 0x20, 0x3c, 0x23, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x20, 0xfc, 0x90, 0xfc, 0x90,
-+ 0xfc, 0x00, 0xfc, 0x50, 0x94, 0x0c, 0x00, 0x00,
-+ 0x08, 0x09, 0x15, 0x1f, 0x23, 0x7d, 0x24, 0x3c,
-+ 0x25, 0x3c, 0x3f, 0x20, 0x3e, 0x21, 0x00, 0x00,
-+ 0x00, 0xf8, 0x68, 0xf8, 0x20, 0x64, 0xdc, 0x50,
-+ 0xf8, 0x50, 0xfc, 0x50, 0x88, 0x08, 0x00, 0x00,
-+ 0x1e, 0x12, 0x1e, 0x7f, 0x1e, 0x23, 0x0e, 0x0f,
-+ 0x77, 0x04, 0x07, 0x07, 0x06, 0x38, 0x00, 0x00,
-+ 0x38, 0xfc, 0xa8, 0xd8, 0xb0, 0x34, 0xcc, 0xe0,
-+ 0xdc, 0x40, 0xc0, 0xd0, 0xe0, 0x38, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x08, 0x7e, 0x0a, 0x0a, 0x0a,
-+ 0x0a, 0x0a, 0x12, 0x12, 0x22, 0x41, 0x00, 0x00,
-+ 0x88, 0x50, 0xfc, 0x40, 0xf8, 0x88, 0xf8, 0x88,
-+ 0xf8, 0x88, 0xf8, 0x8c, 0x04, 0xfc, 0x00, 0x00,
-+ 0x24, 0x14, 0x18, 0x7f, 0x08, 0x11, 0x3d, 0x25,
-+ 0x3d, 0x25, 0x3c, 0x27, 0x3c, 0x24, 0x00, 0x00,
-+ 0x30, 0x28, 0x28, 0xfc, 0x20, 0xe8, 0x68, 0x68,
-+ 0xd0, 0x10, 0x74, 0xac, 0x4c, 0x84, 0x00, 0x00,
-+ 0x06, 0x38, 0x08, 0x7f, 0x1c, 0x1a, 0x2a, 0x48,
-+ 0x3e, 0x22, 0x3f, 0x22, 0x3e, 0x23, 0x00, 0x00,
-+ 0x80, 0x80, 0xfc, 0xf8, 0x88, 0xf8, 0x88, 0xf8,
-+ 0x40, 0xf8, 0x90, 0x60, 0xf0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x24, 0x3e, 0x24, 0x3e, 0x24, 0x3f,
-+ 0x05, 0x3b, 0x2f, 0x2d, 0x42, 0x0d, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0x88, 0x50, 0x50, 0x70,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x03, 0x22, 0x13, 0x12, 0x03, 0x0a, 0x0b,
-+ 0x10, 0x16, 0x25, 0x25, 0x28, 0x00, 0x00, 0x00,
-+ 0x00, 0xf8, 0x40, 0xf0, 0x40, 0xf0, 0x40, 0xfc,
-+ 0x24, 0x94, 0x54, 0x44, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3f, 0x28, 0x3e, 0x28, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x42, 0x0d, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x88, 0x88, 0x88, 0x50,
-+ 0x50, 0x30, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x29, 0x3d, 0x29, 0x3d, 0x29, 0x3f,
-+ 0x0b, 0x3f, 0x3f, 0x33, 0x45, 0x19, 0x00, 0x00,
-+ 0x00, 0xf8, 0x68, 0x68, 0x68, 0x68, 0x68, 0x78,
-+ 0xb8, 0x98, 0x08, 0x08, 0xf8, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3e, 0x28, 0x3e,
-+ 0x0b, 0x3e, 0x3e, 0x32, 0x42, 0x0d, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xf8, 0xa8, 0xa8, 0xa8, 0xf8,
-+ 0xa8, 0xa0, 0x40, 0x60, 0x98, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3f, 0x28, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x42, 0x0c, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x88, 0x40, 0x40, 0x4c,
-+ 0x70, 0x40, 0x40, 0x40, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3e, 0x29, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x42, 0x0c, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x50, 0x48, 0xf4, 0x04,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x7e, 0x12, 0x3a, 0x0c, 0x77, 0x04, 0x07,
-+ 0x07, 0x04, 0x07, 0x15, 0x12, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x30, 0xc8, 0xf4, 0x80, 0xe0,
-+ 0xe0, 0x80, 0xf8, 0x48, 0xa8, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x29, 0x3e, 0x28, 0x3f, 0x28, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x44, 0x1b, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x40, 0x50, 0x90, 0x60, 0x28,
-+ 0x48, 0x90, 0x10, 0x28, 0xc4, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x29, 0x3e, 0x28, 0x3e, 0x29, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x42, 0x0d, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x50, 0x48, 0x94, 0x54, 0x50,
-+ 0x60, 0x20, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3f, 0x28, 0x3e,
-+ 0x0b, 0x3e, 0x3e, 0x32, 0x42, 0x0c, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0xd0, 0x20, 0x50, 0x88,
-+ 0xfc, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3e, 0x28, 0x3c, 0x28, 0x3c, 0x29, 0x3f,
-+ 0x0a, 0x3e, 0x3e, 0x33, 0x45, 0x1a, 0x00, 0x00,
-+ 0x08, 0x88, 0xa8, 0xa8, 0xa8, 0xf8, 0xf8, 0xa8,
-+ 0xa8, 0xa8, 0xa8, 0x28, 0x28, 0x08, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3e, 0x28, 0x3e,
-+ 0x0a, 0x3f, 0x3e, 0x32, 0x42, 0x0c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x00, 0xf8,
-+ 0x20, 0xfc, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3e, 0x28, 0x3f, 0x28, 0x3e, 0x28, 0x3f,
-+ 0x0b, 0x3e, 0x3e, 0x32, 0x44, 0x1b, 0x00, 0x00,
-+ 0x00, 0xf8, 0x08, 0xfc, 0x08, 0xf8, 0x00, 0xfc,
-+ 0x08, 0xf8, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3e, 0x28, 0x3f,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x42, 0x0c, 0x00, 0x00,
-+ 0x20, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0x00, 0xfc,
-+ 0x40, 0x78, 0x88, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3e, 0x28, 0x3e,
-+ 0x0a, 0x3f, 0x3e, 0x32, 0x42, 0x0d, 0x00, 0x00,
-+ 0x48, 0x48, 0x48, 0xfc, 0x48, 0x78, 0x48, 0x78,
-+ 0x48, 0xfc, 0x50, 0x48, 0x84, 0x04, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3f, 0x28, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x42, 0x0c, 0x00, 0x00,
-+ 0x48, 0x48, 0x50, 0xfc, 0x90, 0x90, 0xf8, 0x90,
-+ 0x90, 0xf8, 0x90, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3f, 0x28, 0x3e, 0x28, 0x3f,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x45, 0x1a, 0x00, 0x00,
-+ 0x88, 0x48, 0x50, 0xfc, 0x50, 0x50, 0x50, 0xfc,
-+ 0x50, 0x50, 0x90, 0x90, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3e, 0x28, 0x3e,
-+ 0x0a, 0x3f, 0x3f, 0x32, 0x42, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x88, 0xf8, 0x80, 0xfc,
-+ 0xb4, 0xfc, 0xb4, 0xb4, 0xb4, 0x8c, 0x00, 0x00,
-+ 0x01, 0x3f, 0x22, 0x7f, 0x1f, 0x02, 0x7f, 0x0f,
-+ 0x17, 0x67, 0x05, 0x07, 0x1a, 0x25, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0xf8, 0xe0, 0x80, 0xfc, 0xf0,
-+ 0xd0, 0xcc, 0x00, 0xf0, 0x90, 0x60, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3f, 0x28, 0x3e, 0x2b, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x32, 0x42, 0x0d, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0x50, 0xa0, 0x70, 0xac, 0xf8,
-+ 0xa8, 0xf8, 0xb0, 0x28, 0x3c, 0xc4, 0x00, 0x00,
-+ 0x00, 0x3f, 0x29, 0x3d, 0x29, 0x3d, 0x29, 0x3f,
-+ 0x0b, 0x3f, 0x3f, 0x33, 0x45, 0x19, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0x78, 0x48, 0x78, 0x00, 0xfc,
-+ 0xb4, 0xb4, 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x3e, 0x29, 0x3c, 0x29, 0x3f, 0x28, 0x3e,
-+ 0x0b, 0x3e, 0x3e, 0x32, 0x42, 0x0d, 0x00, 0x00,
-+ 0x40, 0x90, 0xf8, 0x90, 0x68, 0xfc, 0x60, 0x90,
-+ 0x2c, 0xc0, 0x20, 0xc8, 0x30, 0xc0, 0x00, 0x00,
-+ 0x04, 0x7f, 0x0f, 0x08, 0x0f, 0x0f, 0x7f, 0x07,
-+ 0x1d, 0x67, 0x07, 0x07, 0x1a, 0x25, 0x00, 0x00,
-+ 0x40, 0xfc, 0xe0, 0x20, 0xe0, 0xe0, 0xfc, 0xc0,
-+ 0x30, 0xcc, 0xc0, 0xf8, 0x88, 0x70, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3f, 0x29, 0x3f, 0x28, 0x3e,
-+ 0x0a, 0x3f, 0x3e, 0x32, 0x43, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x50, 0xfc, 0x54, 0xfc, 0x00, 0xf8,
-+ 0x00, 0xfc, 0xa8, 0xa4, 0x24, 0x60, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3e, 0x28, 0x3e,
-+ 0x0a, 0x3f, 0x3e, 0x32, 0x43, 0x0c, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0x50, 0xd0,
-+ 0x28, 0xfc, 0xa8, 0xa4, 0x24, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3f, 0x28, 0x3e, 0x29, 0x3e,
-+ 0x0b, 0x3f, 0x3f, 0x33, 0x45, 0x19, 0x00, 0x00,
-+ 0x18, 0xe0, 0x20, 0xfc, 0x50, 0xf8, 0x54, 0x70,
-+ 0xfc, 0x74, 0x54, 0x74, 0x04, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3f, 0x28, 0x3f, 0x28, 0x3e,
-+ 0x0b, 0x3f, 0x3e, 0x32, 0x42, 0x0d, 0x00, 0x00,
-+ 0x20, 0xf8, 0x20, 0xfc, 0x88, 0xdc, 0x88, 0xdc,
-+ 0x00, 0xfc, 0x50, 0x50, 0x94, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x29, 0x3f, 0x28, 0x3e, 0x28, 0x3f,
-+ 0x0a, 0x3f, 0x3e, 0x32, 0x42, 0x0c, 0x00, 0x00,
-+ 0x00, 0xfc, 0x54, 0xfc, 0x20, 0xf8, 0x20, 0xfc,
-+ 0x50, 0xfc, 0x20, 0xf8, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x28, 0x3f, 0x28, 0x3f,
-+ 0x0b, 0x3f, 0x3e, 0x32, 0x45, 0x1a, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0xfc, 0x00, 0xf8,
-+ 0x68, 0xf8, 0x90, 0xd8, 0x24, 0x44, 0x00, 0x00,
-+ 0x00, 0x3f, 0x29, 0x3d, 0x29, 0x3d, 0x2b, 0x3e,
-+ 0x0a, 0x3f, 0x3e, 0x32, 0x43, 0x0c, 0x00, 0x00,
-+ 0x00, 0xe0, 0x7c, 0xd4, 0xc8, 0x54, 0xe4, 0x50,
-+ 0x64, 0xb8, 0x70, 0xa8, 0x24, 0x20, 0x00, 0x00,
-+ 0x00, 0x3e, 0x29, 0x3f, 0x29, 0x3f, 0x29, 0x3f,
-+ 0x0b, 0x3f, 0x3f, 0x33, 0x46, 0x19, 0x00, 0x00,
-+ 0x20, 0x38, 0xfc, 0x28, 0xd8, 0xf8, 0xa8, 0xf8,
-+ 0xa8, 0xf8, 0xf8, 0xe8, 0xe8, 0xfc, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3e, 0x29, 0x3e, 0x28, 0x3e,
-+ 0x0a, 0x3e, 0x3e, 0x33, 0x42, 0x0d, 0x00, 0x00,
-+ 0x50, 0xd4, 0x58, 0xd4, 0x4c, 0xf8, 0xa8, 0xf8,
-+ 0xf8, 0x50, 0xf8, 0xfc, 0x48, 0x84, 0x00, 0x00,
-+ 0x00, 0x3f, 0x29, 0x3f, 0x29, 0x3e, 0x29, 0x3e,
-+ 0x0a, 0x3f, 0x3e, 0x33, 0x44, 0x19, 0x00, 0x00,
-+ 0x20, 0xfc, 0xdc, 0x54, 0xdc, 0x50, 0xfc, 0xf8,
-+ 0x50, 0xfc, 0x68, 0x90, 0xe8, 0x84, 0x00, 0x00,
-+ 0x00, 0x3f, 0x28, 0x3d, 0x29, 0x3d, 0x28, 0x3e,
-+ 0x0b, 0x3e, 0x3e, 0x32, 0x42, 0x0c, 0x00, 0x00,
-+ 0x50, 0xfc, 0x50, 0xdc, 0x54, 0xdc, 0x50, 0xfc,
-+ 0x90, 0xf8, 0xf8, 0x90, 0xfc, 0x80, 0x00, 0x00,
-+ 0x00, 0x07, 0x07, 0x07, 0x07, 0x0e, 0x15, 0x3f,
-+ 0x28, 0x3e, 0x3e, 0x3f, 0x3d, 0x57, 0x00, 0x00,
-+ 0x00, 0xe0, 0xc0, 0xc0, 0xf0, 0x90, 0x60, 0xfc,
-+ 0xa0, 0xf8, 0xf8, 0xfc, 0xf4, 0x58, 0x00, 0x00,
-+ 0x00, 0x3f, 0x29, 0x3f, 0x29, 0x3e, 0x29, 0x3f,
-+ 0x0b, 0x3f, 0x3f, 0x33, 0x46, 0x19, 0x00, 0x00,
-+ 0x00, 0xdc, 0xdc, 0xdc, 0x54, 0x20, 0xfc, 0x50,
-+ 0xf8, 0x58, 0xfc, 0xd8, 0xf4, 0x8c, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x2e, 0x2a, 0x7f, 0x42, 0x3e,
-+ 0x22, 0x3e, 0x22, 0x3e, 0x22, 0x26, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x2e, 0x2a, 0x7e, 0x43, 0x3f,
-+ 0x22, 0x3e, 0x22, 0x3e, 0x22, 0x27, 0x00, 0x00,
-+ 0x00, 0x70, 0x50, 0x54, 0x54, 0x8c, 0x00, 0xf8,
-+ 0x48, 0x50, 0x30, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x2e, 0x2a, 0x7f, 0x42, 0x3e,
-+ 0x23, 0x3e, 0x22, 0x3e, 0x22, 0x26, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0xd0, 0x20, 0x50, 0x88,
-+ 0xfc, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x2e, 0x2a, 0x7f, 0x42, 0x3e,
-+ 0x22, 0x3f, 0x22, 0x3e, 0x22, 0x26, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0x50,
-+ 0x90, 0xfc, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x2f, 0x2a, 0x7f, 0x42, 0x3e,
-+ 0x22, 0x3f, 0x22, 0x3e, 0x22, 0x27, 0x00, 0x00,
-+ 0x20, 0xf8, 0xa8, 0xfc, 0xa8, 0xf8, 0xf8, 0xa8,
-+ 0xf8, 0xfc, 0x50, 0xd0, 0x30, 0xc8, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x3d, 0x34, 0x7e, 0x45, 0x3f,
-+ 0x25, 0x3d, 0x25, 0x3c, 0x27, 0x2c, 0x00, 0x00,
-+ 0x00, 0xf8, 0x68, 0xf8, 0x80, 0xf8, 0x48, 0xf8,
-+ 0x58, 0xf8, 0x68, 0x78, 0x88, 0x30, 0x00, 0x00,
-+ 0x02, 0x3d, 0x25, 0x3c, 0x36, 0x7f, 0x45, 0x3c,
-+ 0x27, 0x3d, 0x25, 0x3d, 0x26, 0x2c, 0x00, 0x00,
-+ 0x20, 0xfc, 0x40, 0x78, 0x90, 0xfc, 0x78, 0x48,
-+ 0x78, 0x48, 0x78, 0x48, 0xd8, 0x7c, 0x00, 0x00,
-+ 0x00, 0x3d, 0x25, 0x3d, 0x35, 0x7f, 0x42, 0x3f,
-+ 0x25, 0x3d, 0x25, 0x3c, 0x27, 0x2c, 0x00, 0x00,
-+ 0x60, 0xf8, 0x68, 0xf8, 0x68, 0xf8, 0x00, 0xfc,
-+ 0xf8, 0x08, 0xf8, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7e, 0x3c, 0x24, 0x3d, 0x01, 0x7f,
-+ 0x42, 0x5f, 0x56, 0x5e, 0x43, 0x46, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x00, 0xdc, 0x54, 0xdc,
-+ 0x20, 0xfc, 0x70, 0xa8, 0x24, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x10, 0x1e, 0x10, 0x1e, 0x10,
-+ 0x7f, 0x14, 0x12, 0x27, 0x79, 0x01, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0x28, 0x48, 0x90, 0x10, 0x24,
-+ 0x44, 0x08, 0x08, 0x10, 0x60, 0x80, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x12, 0x3f, 0x09,
-+ 0x09, 0x0f, 0x79, 0x09, 0x08, 0x07, 0x00, 0x00,
-+ 0x10, 0x60, 0x88, 0x30, 0xc4, 0x18, 0xe0, 0x00,
-+ 0xf0, 0x10, 0x10, 0x64, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x12, 0x3f, 0x01,
-+ 0x7f, 0x01, 0x01, 0x02, 0x0c, 0x30, 0x00, 0x00,
-+ 0x10, 0x60, 0x88, 0x30, 0xc4, 0x18, 0xe0, 0x00,
-+ 0xfc, 0x00, 0xf0, 0x10, 0x10, 0xe0, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x12, 0x3f, 0x00,
-+ 0x0f, 0x1f, 0x02, 0x7f, 0x02, 0x01, 0x00, 0x00,
-+ 0x10, 0x60, 0x88, 0x30, 0xc4, 0x18, 0xe0, 0xc0,
-+ 0x00, 0xf0, 0x00, 0xfc, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x12, 0x3f, 0x01,
-+ 0x0f, 0x0f, 0x09, 0x7f, 0x08, 0x08, 0x00, 0x00,
-+ 0x10, 0x60, 0x88, 0x30, 0xc4, 0x18, 0xe0, 0x00,
-+ 0xe0, 0xe0, 0x20, 0xfc, 0x20, 0x60, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x12, 0x3d, 0x1f,
-+ 0x03, 0x0c, 0x7f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x10, 0x60, 0x88, 0x30, 0xc4, 0x18, 0xe0, 0xf0,
-+ 0x10, 0x60, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x12, 0x3f, 0x01,
-+ 0x7f, 0x02, 0x05, 0x19, 0x66, 0x18, 0x00, 0x00,
-+ 0x10, 0x60, 0x88, 0x30, 0xc4, 0x18, 0xf0, 0x08,
-+ 0xfc, 0x20, 0x40, 0x80, 0x60, 0x1c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x12, 0x3f, 0x1f,
-+ 0x04, 0x3f, 0x3f, 0x24, 0x18, 0x60, 0x00, 0x00,
-+ 0x10, 0x60, 0x88, 0x30, 0xc4, 0x18, 0xe0, 0xf0,
-+ 0x90, 0xf0, 0xfc, 0x84, 0x98, 0x80, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x12, 0x3f, 0x02,
-+ 0x0f, 0x7f, 0x08, 0x0f, 0x08, 0x07, 0x00, 0x00,
-+ 0x10, 0x60, 0x88, 0x30, 0xc4, 0x18, 0xe0, 0x00,
-+ 0xf0, 0x90, 0x90, 0xe4, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x12, 0x3f, 0x02,
-+ 0x1f, 0x12, 0x1f, 0x12, 0x1f, 0x10, 0x00, 0x00,
-+ 0x10, 0x60, 0x88, 0x30, 0xc4, 0x18, 0xe0, 0x80,
-+ 0xf0, 0x90, 0xf0, 0x90, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x12, 0x3f, 0x01,
-+ 0x7f, 0x1f, 0x0f, 0x08, 0x0f, 0x08, 0x00, 0x00,
-+ 0x10, 0x60, 0x88, 0x30, 0xc4, 0x18, 0xe0, 0x00,
-+ 0xfc, 0xf0, 0xe0, 0x20, 0xe0, 0x20, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x12, 0x3f, 0x08,
-+ 0x7e, 0x18, 0x1d, 0x2a, 0x49, 0x08, 0x00, 0x00,
-+ 0x10, 0x60, 0x88, 0x30, 0xc4, 0x18, 0xe0, 0x78,
-+ 0x88, 0xa4, 0x30, 0x48, 0xf4, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x16, 0x3f, 0x07,
-+ 0x07, 0x1f, 0x1f, 0x0f, 0x03, 0x3c, 0x00, 0x00,
-+ 0x10, 0x60, 0x90, 0x64, 0x98, 0x60, 0xc0, 0xc0,
-+ 0xc0, 0xf0, 0xf0, 0xe0, 0x80, 0x78, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x12, 0x3f, 0x0f,
-+ 0x71, 0x09, 0x31, 0x05, 0x19, 0x67, 0x00, 0x00,
-+ 0x10, 0x60, 0x88, 0x30, 0xc4, 0x18, 0xe0, 0xfc,
-+ 0xf0, 0x10, 0xf0, 0xf0, 0xf0, 0x1c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x16, 0x3f, 0x0f,
-+ 0x7f, 0x07, 0x07, 0x7c, 0x07, 0x18, 0x00, 0x00,
-+ 0x10, 0x60, 0x90, 0x64, 0x98, 0xe0, 0xe0, 0xe0,
-+ 0xfc, 0xc0, 0xd8, 0xe0, 0x60, 0x1c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x16, 0x3f, 0x2f,
-+ 0x4b, 0x37, 0x3f, 0x07, 0x07, 0x3c, 0x00, 0x00,
-+ 0x10, 0x60, 0x90, 0x64, 0x18, 0xe0, 0xfc, 0xe8,
-+ 0x40, 0xe0, 0xe0, 0xe0, 0xe0, 0x38, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1e, 0x1e, 0x7f, 0x16, 0x39, 0x04,
-+ 0x1f, 0x13, 0x1f, 0x1d, 0x1d, 0x73, 0x00, 0x00,
-+ 0x10, 0x60, 0x90, 0x64, 0x18, 0xe8, 0x30, 0x88,
-+ 0xf0, 0x90, 0xf0, 0xd4, 0xcc, 0x04, 0x00, 0x00,
-+ 0x00, 0x2e, 0x24, 0x2e, 0x24, 0x2e, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x00, 0xe8, 0x48, 0xe8, 0x48, 0xe8, 0x08, 0x08,
-+ 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x00, 0x2e, 0x24, 0x2e, 0x24, 0x2e, 0x21, 0x3f,
-+ 0x21, 0x2f, 0x29, 0x29, 0x29, 0x21, 0x00, 0x00,
-+ 0x00, 0xe8, 0x48, 0xe8, 0x48, 0xe8, 0x08, 0xf8,
-+ 0x08, 0xe8, 0x28, 0x28, 0xc8, 0x18, 0x00, 0x00,
-+ 0x00, 0x2e, 0x24, 0x2e, 0x24, 0x2e, 0x20, 0x22,
-+ 0x2f, 0x22, 0x3f, 0x22, 0x24, 0x28, 0x00, 0x00,
-+ 0x00, 0xe8, 0x48, 0xe8, 0x48, 0xe8, 0x08, 0x88,
-+ 0xe8, 0x88, 0xf8, 0x88, 0x48, 0x58, 0x00, 0x00,
-+ 0x00, 0x2e, 0x24, 0x2e, 0x24, 0x2e, 0x22, 0x24,
-+ 0x26, 0x24, 0x27, 0x22, 0x24, 0x28, 0x00, 0x00,
-+ 0x00, 0xe8, 0x48, 0xe8, 0x48, 0xe8, 0x08, 0xc8,
-+ 0xc8, 0x48, 0xc8, 0x88, 0xa8, 0x78, 0x00, 0x00,
-+ 0x00, 0x2e, 0x24, 0x2e, 0x24, 0x2e, 0x20, 0x3f,
-+ 0x2f, 0x29, 0x2f, 0x2a, 0x27, 0x38, 0x00, 0x00,
-+ 0x00, 0xe8, 0x48, 0xe8, 0x48, 0xe8, 0x28, 0x28,
-+ 0xf8, 0xa8, 0x68, 0x28, 0x28, 0x78, 0x00, 0x00,
-+ 0x00, 0x2e, 0x24, 0x2e, 0x2e, 0x23, 0x3f, 0x2e,
-+ 0x3a, 0x3e, 0x3a, 0x3a, 0x3e, 0x39, 0x00, 0x00,
-+ 0x00, 0xe8, 0x48, 0xe8, 0xe8, 0x88, 0xe8, 0xe8,
-+ 0xf8, 0xb8, 0xf8, 0xf8, 0x98, 0xf8, 0x00, 0x00,
-+ 0x02, 0x21, 0x2c, 0x33, 0x29, 0x23, 0x2c, 0x3f,
-+ 0x28, 0x08, 0x0f, 0x08, 0x08, 0x07, 0x00, 0x00,
-+ 0x40, 0x48, 0xa8, 0x98, 0x48, 0x28, 0x88, 0xf8,
-+ 0x08, 0x70, 0x80, 0x04, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x7f, 0x00, 0x0f, 0x08, 0x0f, 0x00, 0x3f,
-+ 0x22, 0x2c, 0x37, 0x21, 0x21, 0x21, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xe0, 0x20, 0xe0, 0x00, 0xf8,
-+ 0x88, 0x98, 0xf8, 0x08, 0x08, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x11, 0x3d, 0x25, 0x25, 0x3d, 0x25,
-+ 0x24, 0x24, 0x3d, 0x25, 0x06, 0x18, 0x00, 0x00,
-+ 0x40, 0x80, 0xf8, 0x48, 0xf8, 0x48, 0xf8, 0x48,
-+ 0xd0, 0xd0, 0x68, 0x78, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x10, 0x3e, 0x2b, 0x3e, 0x2a, 0x3e, 0x18,
-+ 0x1a, 0x1a, 0x1d, 0x2f, 0x29, 0x47, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0xfc, 0x40, 0x50, 0x50, 0x50,
-+ 0xa0, 0xa0, 0x50, 0x88, 0x04, 0xfc, 0x00, 0x00,
-+ 0x06, 0x38, 0x08, 0x7f, 0x1c, 0x1a, 0x2a, 0x48,
-+ 0x7e, 0x12, 0x3a, 0x04, 0x1b, 0x62, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0xa0,
-+ 0x68, 0x68, 0xb4, 0xbc, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x10, 0x3e, 0x2a, 0x3e, 0x2a, 0x3e, 0x18,
-+ 0x1a, 0x1a, 0x1d, 0x2f, 0x28, 0x47, 0x00, 0x00,
-+ 0x00, 0xf8, 0xd8, 0xb8, 0xa8, 0xf8, 0xa8, 0xf8,
-+ 0xc8, 0xb8, 0x88, 0x9c, 0x04, 0xfc, 0x00, 0x00,
-+ 0x08, 0x11, 0x3e, 0x2b, 0x3f, 0x2b, 0x3f, 0x19,
-+ 0x1b, 0x1b, 0x1d, 0x2f, 0x28, 0x47, 0x00, 0x00,
-+ 0x00, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0xd8, 0xd8,
-+ 0xe8, 0x48, 0x48, 0x1c, 0x04, 0xfc, 0x00, 0x00,
-+ 0x08, 0x11, 0x3e, 0x2a, 0x3e, 0x2a, 0x3e, 0x19,
-+ 0x1d, 0x1d, 0x1b, 0x2f, 0x28, 0x47, 0x00, 0x00,
-+ 0x20, 0xfc, 0x98, 0xe8, 0xd8, 0xf8, 0x20, 0xfc,
-+ 0x54, 0xfc, 0x04, 0x0c, 0x04, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x17, 0x17, 0x1f, 0x1f, 0x1f, 0x19,
-+ 0x17, 0x17, 0x27, 0x21, 0x46, 0x38, 0x00, 0x00,
-+ 0x00, 0xfc, 0x18, 0x14, 0xfc, 0x90, 0xa8, 0xc4,
-+ 0xf0, 0xf0, 0xf0, 0xa8, 0xfc, 0x7c, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x29, 0x42, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0x38, 0x28,
-+ 0x28, 0x48, 0x48, 0x88, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2a, 0x3f, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x7c, 0xa0, 0xa0, 0x3c, 0x20,
-+ 0x20, 0x3c, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x09, 0x1e, 0x24, 0x7e, 0x2b, 0x3e, 0x2b,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xa8, 0xa4, 0x24, 0x20, 0xfc,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2b, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x78, 0x88, 0xe8, 0xa8, 0xa8,
-+ 0xe8, 0xb0, 0x80, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x08, 0x09, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3f, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0x20, 0x40, 0x40, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7f, 0x2a, 0x3e, 0x2a,
-+ 0x3f, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0x50, 0x20, 0x50, 0xc8,
-+ 0x24, 0x20, 0x00, 0xc0, 0x30, 0x08, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7f, 0x2a, 0x3f, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x43, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x88, 0x20, 0x20, 0xfc, 0x48,
-+ 0x48, 0xf0, 0x90, 0x38, 0xc4, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7f, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2f, 0x29, 0x42, 0x00, 0x00,
-+ 0x20, 0x20, 0x78, 0x90, 0xfc, 0x80, 0xf8, 0xc8,
-+ 0xc8, 0xc8, 0xd8, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x80, 0x98, 0xe0, 0x80, 0x84, 0x7c, 0x00, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2b, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x50, 0x50, 0x50, 0x90, 0xfc, 0x90, 0xb8, 0xb8,
-+ 0xb8, 0xd4, 0xd4, 0x90, 0x90, 0x90, 0x00, 0x00,
-+ 0x08, 0x09, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3f, 0x04, 0x3a, 0x2e, 0x29, 0x40, 0x00, 0x00,
-+ 0x0c, 0xf0, 0x20, 0x28, 0xc8, 0x30, 0x30, 0x48,
-+ 0xf4, 0x20, 0xa8, 0xa4, 0x24, 0x20, 0x00, 0x00,
-+ 0x10, 0x49, 0x21, 0x0a, 0x14, 0x23, 0x27, 0x08,
-+ 0x3f, 0x09, 0x0f, 0x0f, 0x14, 0x22, 0x00, 0x00,
-+ 0x40, 0x50, 0x48, 0xd4, 0x64, 0x80, 0xc0, 0x80,
-+ 0xe0, 0x20, 0xe0, 0xe0, 0x90, 0x48, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7f, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0xa8, 0xa4, 0x24, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x88, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x28, 0x24, 0xfc, 0x20, 0xf8, 0xa8, 0xa8, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0xa8, 0xa8, 0x98, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x24, 0x7e, 0x2b, 0x3e, 0x2a,
-+ 0x3f, 0x05, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x48, 0x88, 0xa8, 0xa8, 0xa8, 0xe8, 0xa8, 0xe8,
-+ 0xe8, 0xa8, 0xa8, 0x88, 0x88, 0x98, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x25, 0x7e, 0x2b, 0x3e, 0x2a,
-+ 0x3f, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x08, 0xd0, 0x70, 0xa8, 0x20, 0xfc, 0x60, 0xa0,
-+ 0xf8, 0xa8, 0xa8, 0xa8, 0xb8, 0x20, 0x00, 0x00,
-+ 0x08, 0x09, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x50, 0x20, 0xf8, 0xa8, 0xa8, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0xa8, 0xa8, 0xb8, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3f, 0x04, 0x3a, 0x2f, 0x28, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x40, 0xfc,
-+ 0x54, 0x54, 0x94, 0x24, 0x44, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x29, 0x42, 0x00, 0x00,
-+ 0x20, 0x40, 0x98, 0x88, 0xd8, 0x88, 0x88, 0xf8,
-+ 0x68, 0x60, 0xa0, 0xa4, 0x24, 0x1c, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x43, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0xf8, 0x90,
-+ 0x94, 0xf8, 0x90, 0x94, 0xd4, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x25, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0xa8, 0xa8, 0x50, 0x50, 0xa8, 0xa8, 0x00, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0xa8, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x25, 0x7e, 0x2a, 0x3f, 0x2a,
-+ 0x3e, 0x05, 0x3a, 0x2e, 0x29, 0x42, 0x00, 0x00,
-+ 0x50, 0x50, 0x50, 0xdc, 0x50, 0x50, 0xdc, 0x50,
-+ 0x70, 0xdc, 0x90, 0x90, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7f, 0x2b, 0x3e, 0x2b,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x41, 0x00, 0x00,
-+ 0x20, 0x50, 0xf8, 0x90, 0x68, 0xfc, 0x60, 0xb0,
-+ 0xcc, 0x20, 0xc8, 0x10, 0x60, 0x80, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7f, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3b, 0x2f, 0x2a, 0x41, 0x00, 0x00,
-+ 0x90, 0x90, 0x90, 0xa8, 0xe8, 0x84, 0x94, 0xc8,
-+ 0xc8, 0xc0, 0x50, 0x48, 0x44, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3b, 0x2f, 0x2a, 0x41, 0x00, 0x00,
-+ 0x20, 0x38, 0x20, 0xfc, 0xa8, 0xf8, 0xa4, 0x9c,
-+ 0xf0, 0xd0, 0x50, 0x54, 0x94, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7f, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x29, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x88, 0x74, 0x00, 0xf8, 0x10,
-+ 0x20, 0x58, 0xd4, 0xc4, 0x50, 0x30, 0x00, 0x00,
-+ 0x08, 0x09, 0x1f, 0x25, 0x7f, 0x2b, 0x3f, 0x2b,
-+ 0x3f, 0x05, 0x3b, 0x2f, 0x29, 0x41, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x48, 0xd8, 0x48, 0x00, 0xf8,
-+ 0x28, 0x28, 0xd0, 0x10, 0x28, 0x44, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x25, 0x7f, 0x2b, 0x3f, 0x2b,
-+ 0x3f, 0x05, 0x3b, 0x2f, 0x2a, 0x42, 0x00, 0x00,
-+ 0x28, 0x24, 0x24, 0xfc, 0x20, 0xe8, 0x28, 0xe8,
-+ 0xb0, 0xf0, 0x94, 0x2c, 0x4c, 0x84, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3f, 0x04, 0x3a, 0x2e, 0x29, 0x40, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0x00,
-+ 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2f, 0x29, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xf8, 0xa8, 0xf8, 0x20,
-+ 0x50, 0xd8, 0xc4, 0x54, 0x50, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7f, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x70, 0x50, 0x50, 0x88, 0xfc, 0x30, 0xf8, 0xb8,
-+ 0xd8, 0x88, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x24, 0x7e, 0x2a, 0x3f, 0x2a,
-+ 0x3e, 0x05, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0x20, 0xfc, 0x50,
-+ 0xf8, 0x8c, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3f, 0x04, 0x3a, 0x2e, 0x29, 0x40, 0x00, 0x00,
-+ 0xa8, 0xa8, 0xfc, 0xa8, 0xb8, 0x80, 0xfc, 0x20,
-+ 0xfc, 0x70, 0x70, 0xa8, 0x24, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x25, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3b, 0x2e, 0x28, 0x43, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0xf8, 0x88, 0xf8, 0x88, 0xf8,
-+ 0x40, 0xf8, 0x50, 0x20, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2f, 0x28, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x20, 0xf8, 0xb8, 0xe8, 0xf8,
-+ 0x70, 0x70, 0xa8, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x10, 0x10, 0x1c, 0x2b, 0x7e, 0x2f, 0x3e, 0x2f,
-+ 0x3f, 0x0b, 0x3e, 0x3e, 0x35, 0x48, 0x00, 0x00,
-+ 0x30, 0x28, 0x28, 0xfc, 0x20, 0xe8, 0xa8, 0xe8,
-+ 0x78, 0x50, 0x94, 0xdc, 0x2c, 0x44, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x29, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0xa8, 0xa8, 0xd8, 0x88, 0xf8, 0x00,
-+ 0xf8, 0xe8, 0xe8, 0xe8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x29, 0x40, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0x88, 0xf8, 0x88, 0xf8, 0x00,
-+ 0xf8, 0xe8, 0xe8, 0xe8, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x09, 0x1f, 0x25, 0x7f, 0x2a, 0x3e, 0x2a,
-+ 0x3f, 0x04, 0x3a, 0x2f, 0x28, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x54, 0x54, 0xfc, 0x20, 0xa8, 0xa8,
-+ 0x24, 0x70, 0xa8, 0x24, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x25, 0x7f, 0x2b, 0x3f, 0x2b,
-+ 0x3f, 0x05, 0x3b, 0x2f, 0x29, 0x40, 0x00, 0x00,
-+ 0x80, 0xfc, 0x10, 0xd0, 0x7c, 0x74, 0xf4, 0x34,
-+ 0xf4, 0x74, 0x7c, 0xd0, 0x10, 0x10, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x25, 0x7f, 0x2b, 0x3f, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x94, 0x54, 0xf4, 0x2c, 0x40,
-+ 0xf8, 0xa8, 0xf8, 0xa8, 0xf8, 0x88, 0x00, 0x00,
-+ 0x10, 0x11, 0x1c, 0x28, 0x7f, 0x2a, 0x3f, 0x2b,
-+ 0x3f, 0x05, 0x3f, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x10, 0xd0, 0x10, 0x3c, 0xf4, 0xb4, 0xfc, 0xf4,
-+ 0xf4, 0xfc, 0xb4, 0x90, 0x90, 0x90, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2f, 0x29, 0x42, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0xa0, 0xf8, 0xa8, 0xfc, 0xa8,
-+ 0xf8, 0xa8, 0xf0, 0x68, 0xa4, 0x60, 0x00, 0x00,
-+ 0x08, 0x3e, 0x7f, 0x08, 0x7f, 0x1e, 0x26, 0x47,
-+ 0x3f, 0x09, 0x0f, 0x0f, 0x14, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0x7c, 0xc8, 0x28, 0x30, 0xc8, 0x84,
-+ 0xe0, 0x20, 0xe0, 0xe0, 0x90, 0x48, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7f, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x04, 0x3a, 0x2f, 0x28, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0xf8, 0x50, 0xfc, 0xf8, 0x88, 0xf8,
-+ 0x88, 0xf8, 0x20, 0xfc, 0x20, 0x20, 0x00, 0x00,
-+ 0x08, 0x09, 0x1e, 0x25, 0x7f, 0x2b, 0x3e, 0x2a,
-+ 0x3e, 0x05, 0x3a, 0x2e, 0x29, 0x40, 0x00, 0x00,
-+ 0x00, 0xfc, 0x50, 0xfc, 0x54, 0xfc, 0x00, 0xf8,
-+ 0x00, 0xfc, 0xa8, 0xa4, 0x24, 0x60, 0x00, 0x00,
-+ 0x08, 0x09, 0x1e, 0x24, 0x7e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x05, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0x00, 0xf8, 0x88, 0xf8,
-+ 0x50, 0xfc, 0xf8, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x25, 0x7f, 0x2b, 0x3f, 0x2b,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x40, 0x00, 0x00,
-+ 0x40, 0x60, 0x90, 0xf8, 0xfc, 0xd8, 0x68, 0xf8,
-+ 0xf0, 0x90, 0xf0, 0x90, 0xf0, 0x90, 0x00, 0x00,
-+ 0x08, 0x09, 0x1f, 0x25, 0x7f, 0x2b, 0x3e, 0x2b,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x29, 0x40, 0x00, 0x00,
-+ 0x60, 0xf8, 0x68, 0xf8, 0x68, 0xf8, 0x00, 0xfc,
-+ 0xf8, 0x88, 0xf8, 0x50, 0xfc, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x24, 0x7e, 0x2b, 0x3e, 0x2b,
-+ 0x3e, 0x04, 0x3a, 0x2e, 0x28, 0x43, 0x00, 0x00,
-+ 0x88, 0x50, 0xfc, 0x20, 0xf8, 0xfc, 0xd0, 0xf8,
-+ 0x94, 0xf0, 0xf0, 0xa8, 0xd0, 0x0c, 0x00, 0x00,
-+ 0x08, 0x08, 0x1f, 0x25, 0x7f, 0x2b, 0x3f, 0x2b,
-+ 0x3f, 0x05, 0x3b, 0x2f, 0x2a, 0x41, 0x00, 0x00,
-+ 0x20, 0x38, 0xfc, 0x68, 0xd8, 0xf8, 0xa8, 0xf8,
-+ 0xa8, 0xf8, 0xf8, 0xe8, 0xe8, 0xfc, 0x00, 0x00,
-+ 0x01, 0x0f, 0x08, 0x0f, 0x0f, 0x0f, 0x0f, 0x15,
-+ 0x12, 0x20, 0x07, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0xe0, 0xfc, 0xf8, 0x48,
-+ 0xa8, 0x30, 0xc0, 0x40, 0x44, 0x3c, 0x00, 0x00,
-+ 0x02, 0x1f, 0x10, 0x1f, 0x1f, 0x1f, 0x10, 0x1f,
-+ 0x10, 0x07, 0x04, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xe0, 0xe0, 0xfc, 0x00, 0xf8,
-+ 0x08, 0x88, 0xf0, 0x84, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x00, 0x39, 0x09, 0x09, 0x09, 0x19, 0x15,
-+ 0x15, 0x23, 0x20, 0x43, 0x02, 0x04, 0x00, 0x00,
-+ 0x40, 0x80, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xfc,
-+ 0x00, 0xfc, 0xa4, 0x54, 0x84, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x24, 0x24, 0x24, 0x7e, 0x0c, 0x0c,
-+ 0x14, 0x14, 0x24, 0x45, 0x05, 0x0e, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x12, 0x12, 0x14, 0x14, 0x1c,
-+ 0x14, 0x14, 0x24, 0x25, 0x45, 0x06, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xf8, 0x88, 0xf8, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x00, 0x1f, 0x10, 0x13, 0x12, 0x13, 0x13, 0x13,
-+ 0x12, 0x13, 0x26, 0x25, 0x49, 0x10, 0x00, 0x00,
-+ 0x00, 0xfc, 0x80, 0xf0, 0x10, 0xf0, 0xf0, 0xfc,
-+ 0x00, 0xfc, 0xa4, 0x54, 0x04, 0x18, 0x00, 0x00,
-+ 0x08, 0x10, 0x3e, 0x22, 0x3e, 0x22, 0x3e, 0x3f,
-+ 0x20, 0x3f, 0x0d, 0x3d, 0x32, 0x4d, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xf8, 0x28, 0x28, 0x28, 0xfc,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x08, 0x3f, 0x2a, 0x48, 0x0c,
-+ 0x0c, 0x15, 0x16, 0x25, 0x41, 0x02, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x3f, 0x22, 0x40, 0x1c, 0x04, 0x14,
-+ 0x14, 0x14, 0x22, 0x23, 0x41, 0x02, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x01, 0x0f, 0x0a, 0x7f, 0x05, 0x1f, 0x64, 0x07,
-+ 0x07, 0x07, 0x07, 0x15, 0x12, 0x20, 0x00, 0x00,
-+ 0x00, 0xe0, 0x20, 0xfc, 0x40, 0xf0, 0x4c, 0xc0,
-+ 0xc0, 0xfc, 0xf8, 0x48, 0xa8, 0x30, 0x00, 0x00,
-+ 0x15, 0x0e, 0x19, 0x3f, 0x21, 0x4f, 0x08, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x2a, 0x25, 0x40, 0x00, 0x00,
-+ 0xa8, 0x70, 0xc8, 0xfc, 0x08, 0xe0, 0x20, 0xe0,
-+ 0xe0, 0xfc, 0xf8, 0x48, 0x28, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x09, 0x09, 0x7f, 0x09, 0x09, 0x3d,
-+ 0x25, 0x25, 0x25, 0x3e, 0x22, 0x04, 0x00, 0x00,
-+ 0x40, 0x80, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xfc,
-+ 0x00, 0xfc, 0x54, 0xac, 0x84, 0x18, 0x00, 0x00,
-+ 0x00, 0x06, 0x38, 0x28, 0x28, 0x3f, 0x28, 0x2a,
-+ 0x26, 0x26, 0x3a, 0x63, 0x3d, 0x02, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x00, 0x7e, 0x11, 0x19, 0x25, 0x7b, 0x09, 0x09,
-+ 0x3f, 0x09, 0x09, 0x0e, 0x72, 0x04, 0x00, 0x00,
-+ 0x40, 0x80, 0xf0, 0x10, 0xf0, 0x10, 0xf0, 0xfc,
-+ 0x00, 0xfc, 0x54, 0xac, 0x84, 0x18, 0x00, 0x00,
-+ 0x08, 0x10, 0x3e, 0x22, 0x3e, 0x23, 0x3e, 0x3f,
-+ 0x20, 0x3f, 0x0d, 0x3d, 0x31, 0x46, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x88, 0x40, 0x40, 0x4c,
-+ 0x70, 0x40, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x7c, 0x00, 0x7e,
-+ 0x12, 0x12, 0x12, 0x1d, 0x11, 0x12, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x14, 0x12, 0x22, 0x54,
-+ 0x0c, 0x08, 0x0c, 0x15, 0x21, 0x42, 0x00, 0x00,
-+ 0x20, 0x40, 0xf0, 0x90, 0xf0, 0x90, 0xf0, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xbc, 0x44, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x14, 0x12, 0x22, 0x7e, 0x00, 0x3e,
-+ 0x22, 0x22, 0x3e, 0x23, 0x21, 0x02, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x08, 0x0c, 0x12, 0x7d, 0x08, 0x28, 0x3e, 0x28,
-+ 0x48, 0x7f, 0x08, 0x09, 0x09, 0x0a, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x11, 0x12, 0x27, 0x4c, 0x0f, 0x14, 0x17, 0x37,
-+ 0x54, 0x17, 0x13, 0x1f, 0x1c, 0x11, 0x00, 0x00,
-+ 0x00, 0x3c, 0x80, 0x80, 0x80, 0xbc, 0x88, 0xe8,
-+ 0x08, 0xc8, 0x48, 0x48, 0x48, 0x98, 0x00, 0x00,
-+ 0x00, 0x7e, 0x24, 0x24, 0x3c, 0x24, 0x24, 0x3c,
-+ 0x24, 0x24, 0x3c, 0x65, 0x05, 0x06, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x0c, 0x16, 0x75, 0x15, 0x14, 0x7f, 0x15, 0x15,
-+ 0x1e, 0x72, 0x17, 0x1b, 0x11, 0x31, 0x00, 0x00,
-+ 0x10, 0x20, 0x78, 0x48, 0x78, 0x48, 0x78, 0x7c,
-+ 0x40, 0x7c, 0x34, 0xf4, 0xc4, 0x18, 0x00, 0x00,
-+ 0x06, 0x38, 0x7f, 0x0c, 0x79, 0x1f, 0x04, 0x07,
-+ 0x07, 0x07, 0x07, 0x15, 0x12, 0x20, 0x00, 0x00,
-+ 0x50, 0x48, 0xfc, 0x70, 0xb4, 0xec, 0x20, 0xe0,
-+ 0xe0, 0xfc, 0xf8, 0x48, 0xa8, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x1e, 0x24, 0x7e, 0x2a, 0x2a, 0x3e,
-+ 0x2a, 0x3e, 0x22, 0x23, 0x23, 0x46, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x3e, 0x00, 0x3e, 0x22, 0x3e,
-+ 0x22, 0x3e, 0x22, 0x23, 0x23, 0x26, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x00, 0x7f, 0x08, 0x2a, 0x2a, 0x2a, 0x2a, 0x3d,
-+ 0x4d, 0x48, 0x08, 0x0f, 0x71, 0x02, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x22, 0x3e, 0x22, 0x3e, 0x22,
-+ 0x22, 0x3e, 0x18, 0x15, 0x25, 0x42, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x14, 0x14, 0x14, 0x7f, 0x14, 0x14, 0x7f, 0x00,
-+ 0x3e, 0x22, 0x3e, 0x23, 0x3f, 0x22, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x08, 0x7f, 0x00, 0x3c, 0x24, 0x3c, 0x00, 0x3e,
-+ 0x04, 0x0e, 0x78, 0x09, 0x09, 0x1a, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x2a, 0x3e, 0x2a,
-+ 0x3e, 0x1c, 0x1a, 0x29, 0x49, 0x0a, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x7f, 0x6b, 0x5d, 0x7f,
-+ 0x18, 0x1c, 0x2a, 0x49, 0x09, 0x0a, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x08, 0x10, 0x3e, 0x2a, 0x2a, 0x3e, 0x2a, 0x3e,
-+ 0x14, 0x24, 0x7e, 0x05, 0x05, 0x06, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x14, 0x17, 0x29, 0x2e,
-+ 0x72, 0x2c, 0x26, 0x2b, 0x31, 0x22, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x00, 0x77, 0x55, 0x77, 0x00, 0x3c, 0x00, 0x7e,
-+ 0x10, 0x1c, 0x24, 0x05, 0x05, 0x1a, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x2a, 0x7f, 0x08, 0x3e, 0x2a, 0x3e,
-+ 0x2a, 0x3e, 0x08, 0x7f, 0x09, 0x0a, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x14, 0x7f, 0x1a, 0x29, 0x5f, 0x04,
-+ 0x07, 0x07, 0x07, 0x07, 0x15, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0xfc, 0x90, 0x60, 0x9c, 0xe0, 0x20,
-+ 0xe0, 0xe0, 0xfc, 0xf8, 0x48, 0xb0, 0x00, 0x00,
-+ 0x0c, 0x24, 0x2a, 0x49, 0x14, 0x3e, 0x00, 0x7e,
-+ 0x36, 0x5a, 0x36, 0x5b, 0x13, 0x36, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x06, 0x3c, 0x2a, 0x49, 0x14, 0x3c, 0x08, 0x14,
-+ 0x3e, 0x08, 0x7e, 0x0d, 0x13, 0x62, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x1c, 0x14, 0x22, 0x3d, 0x40, 0x1c, 0x14, 0x22,
-+ 0x7f, 0x2e, 0x2e, 0x2f, 0x71, 0x02, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x00, 0x3e, 0x22, 0x2e, 0x2a, 0x7f, 0x41, 0x3e,
-+ 0x22, 0x3e, 0x22, 0x3f, 0x23, 0x26, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x00, 0x7e, 0x12, 0x12, 0x7e, 0x48, 0x7e, 0x5a,
-+ 0x36, 0x5a, 0x36, 0x5b, 0x13, 0x6e, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x08, 0x6b, 0x08, 0x6f, 0x14, 0x12, 0x3f, 0x52,
-+ 0x1e, 0x12, 0x1e, 0x13, 0x13, 0x16, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x13, 0x1c, 0x11, 0x0f, 0x2e, 0x2a, 0x2e, 0x2e,
-+ 0x2a, 0x2e, 0x3f, 0x2d, 0x13, 0x62, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x08, 0x7f, 0x08, 0x3e, 0x22, 0x3e, 0x3e, 0x22,
-+ 0x3e, 0x00, 0x7f, 0x0d, 0x13, 0x62, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x10, 0x1e, 0x1a, 0x24, 0x54, 0x18, 0x7e, 0x28,
-+ 0x7f, 0x2a, 0x2a, 0x3f, 0x21, 0x22, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x08, 0x3e, 0x7f, 0x14, 0x7f, 0x3e, 0x09, 0x0f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x15, 0x22, 0x00, 0x00,
-+ 0x40, 0x40, 0xf0, 0x50, 0xd4, 0xb4, 0x0c, 0xe0,
-+ 0xe0, 0xe0, 0xfc, 0xf8, 0x48, 0xb0, 0x00, 0x00,
-+ 0x04, 0x04, 0x3f, 0x2a, 0x2a, 0x3f, 0x2a, 0x2e,
-+ 0x2a, 0x20, 0x3e, 0x57, 0x57, 0x21, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xec, 0xc4, 0x18, 0x00, 0x00,
-+ 0x00, 0x3f, 0x0a, 0x04, 0x7f, 0x1d, 0x64, 0x3f,
-+ 0x2d, 0x37, 0x2f, 0x2b, 0x2f, 0x23, 0x00, 0x00,
-+ 0x10, 0x20, 0x78, 0x48, 0xf8, 0x48, 0x78, 0x7c,
-+ 0x40, 0x7c, 0x34, 0xf4, 0xc4, 0x18, 0x00, 0x00,
-+ 0x12, 0x14, 0x3f, 0x68, 0x3e, 0x28, 0x3e, 0x28,
-+ 0x3f, 0x04, 0x3e, 0x2f, 0x29, 0x42, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x06, 0x3a, 0x2a, 0x1c, 0x7f, 0x1c, 0x2a, 0x7e,
-+ 0x2a, 0x3e, 0x2a, 0x3f, 0x21, 0x22, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x55, 0x32, 0x3f, 0x62, 0x3e,
-+ 0x22, 0x3e, 0x2a, 0x29, 0x49, 0x1a, 0x00, 0x00,
-+ 0x20, 0x40, 0xf8, 0x88, 0xf8, 0x88, 0xf8, 0xfc,
-+ 0x80, 0xfc, 0x54, 0xac, 0x44, 0x18, 0x00, 0x00,
-+ 0x0a, 0x11, 0x1a, 0x19, 0x3f, 0x21, 0x4f, 0x0f,
-+ 0x08, 0x0f, 0x0f, 0x0f, 0x15, 0x22, 0x00, 0x00,
-+ 0xb0, 0x90, 0xb0, 0xb0, 0xfc, 0x08, 0xe0, 0xe0,
-+ 0x20, 0xe0, 0xfc, 0xf8, 0x48, 0xb0, 0x00, 0x00,
-+ 0x00, 0x3b, 0x2a, 0x3b, 0x3b, 0x2a, 0x3b, 0x1b,
-+ 0x24, 0x7f, 0x0a, 0x1e, 0x0d, 0x31, 0x00, 0x00,
-+ 0x10, 0xa0, 0xb8, 0xa8, 0xb8, 0xa8, 0xb8, 0x3c,
-+ 0xa0, 0xbc, 0x34, 0xf4, 0xc4, 0x18, 0x00, 0x00,
-+ 0x14, 0x7f, 0x14, 0x77, 0x55, 0x77, 0x14, 0x3f,
-+ 0x68, 0x3e, 0x3e, 0x28, 0x3f, 0x21, 0x00, 0x00,
-+ 0x10, 0x20, 0x78, 0x48, 0x78, 0x48, 0x78, 0x7c,
-+ 0x40, 0x7c, 0x34, 0xfc, 0xc4, 0x18, 0x00, 0x00,
-+ 0x13, 0x17, 0x6b, 0x1b, 0x7f, 0x3a, 0x57, 0x1f,
-+ 0x0f, 0x0f, 0x0f, 0x0f, 0x15, 0x22, 0x00, 0x00,
-+ 0x90, 0xd4, 0xe8, 0x98, 0xfc, 0xb8, 0xd4, 0xf0,
-+ 0xe0, 0xe0, 0xfc, 0xf8, 0x48, 0xb0, 0x00, 0x00,
-+ 0x01, 0x01, 0x01, 0x3f, 0x22, 0x21, 0x2c, 0x23,
-+ 0x38, 0x25, 0x23, 0x24, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x00, 0xf8, 0x48, 0x48, 0x68, 0x98,
-+ 0x98, 0x48, 0x28, 0x88, 0xf8, 0x08, 0x00, 0x00,
-+ 0x10, 0x10, 0x1e, 0x11, 0x7f, 0x57, 0x4f, 0x7b,
-+ 0x6f, 0x57, 0x73, 0x4b, 0x7e, 0x42, 0x00, 0x00,
-+ 0x30, 0x28, 0x28, 0xfc, 0x20, 0xe8, 0x28, 0xe8,
-+ 0xb0, 0xf0, 0xb4, 0x2c, 0x4c, 0x04, 0x00, 0x00,
-+ 0x01, 0x3d, 0x2a, 0x3f, 0x26, 0x3f, 0x2b, 0x3f,
-+ 0x22, 0x1f, 0x12, 0x12, 0x7f, 0x00, 0x00, 0x00,
-+ 0x00, 0xfc, 0x7c, 0xf8, 0xd8, 0x78, 0xa8, 0xf8,
-+ 0x08, 0xf0, 0x90, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x01, 0x03, 0x0c, 0x71, 0x1f, 0x12, 0x1f, 0x12,
-+ 0x1f, 0x14, 0x17, 0x24, 0x27, 0x58, 0x00, 0x00,
-+ 0x00, 0xe0, 0x40, 0x80, 0xfc, 0x40, 0xf8, 0x48,
-+ 0xf8, 0x4c, 0xf0, 0x40, 0x44, 0x3c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x1f, 0x12, 0x1f, 0x17, 0x17,
-+ 0x1c, 0x2f, 0x27, 0x40, 0x1f, 0x00, 0x00, 0x00,
-+ 0x80, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x70, 0x44,
-+ 0xbc, 0xf8, 0xf0, 0x80, 0xfc, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x1f, 0x12, 0x1f, 0x27, 0x47,
-+ 0x19, 0x09, 0x7f, 0x07, 0x79, 0x01, 0x00, 0x00,
-+ 0x80, 0xfc, 0x40, 0xf8, 0x48, 0xf8, 0x70, 0x44,
-+ 0x3c, 0x20, 0xfc, 0xc0, 0x3c, 0x00, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1f, 0x12, 0x1f, 0x27, 0x5e, 0x07,
-+ 0x14, 0x17, 0x1f, 0x7f, 0x06, 0x78, 0x00, 0x00,
-+ 0x80, 0xfc, 0xf8, 0x48, 0xf8, 0x74, 0x3c, 0xe0,
-+ 0x20, 0xe0, 0xf0, 0xfc, 0x60, 0x1c, 0x00, 0x00,
-+ 0x04, 0x04, 0x3f, 0x2a, 0x3f, 0x2b, 0x2b, 0x3f,
-+ 0x34, 0x3d, 0x36, 0x54, 0x5d, 0x33, 0x00, 0x00,
-+ 0x48, 0x48, 0x48, 0xfc, 0x48, 0x78, 0x48, 0x78,
-+ 0x48, 0xfc, 0x50, 0x48, 0x84, 0x04, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1f, 0x12, 0x1f, 0x23, 0x4e, 0x1f,
-+ 0x17, 0x1f, 0x13, 0x1d, 0x1f, 0x10, 0x00, 0x00,
-+ 0x80, 0xfc, 0xf8, 0x48, 0xf8, 0xe4, 0x3c, 0xf0,
-+ 0xd0, 0xf0, 0x90, 0x50, 0xf0, 0x10, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1f, 0x12, 0x1f, 0x2f, 0x4e, 0x32,
-+ 0x1c, 0x1e, 0x10, 0x1f, 0x0c, 0x70, 0x00, 0x00,
-+ 0x80, 0xfc, 0xf8, 0x48, 0xf8, 0x70, 0x44, 0x3c,
-+ 0xf0, 0xf0, 0x10, 0xf0, 0x84, 0x7c, 0x00, 0x00,
-+ 0x00, 0x1f, 0x1f, 0x12, 0x1f, 0x27, 0x4e, 0x1e,
-+ 0x13, 0x1e, 0x1e, 0x7e, 0x1a, 0x66, 0x00, 0x00,
-+ 0x80, 0xfc, 0xf8, 0x48, 0xf8, 0x74, 0x3c, 0x10,
-+ 0xfc, 0x90, 0x50, 0x50, 0x10, 0x30, 0x00, 0x00,
-+ 0x01, 0x01, 0x7f, 0x09, 0x19, 0x27, 0x05, 0x19,
-+ 0x63, 0x0e, 0x31, 0x01, 0x06, 0x38, 0x00, 0x00,
-+ 0x00, 0x00, 0xfc, 0x20, 0x30, 0xc8, 0x40, 0x30,
-+ 0xec, 0x20, 0x40, 0xc0, 0x20, 0x00, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x2a, 0x2a, 0x5d, 0x1a, 0x29,
-+ 0x4e, 0x12, 0x2c, 0x45, 0x1b, 0x60, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x20,
-+ 0x50, 0x50, 0x88, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x08, 0x7f, 0x10,
-+ 0x1e, 0x32, 0x4c, 0x05, 0x1b, 0x60, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xf8, 0x20, 0x20, 0xfc, 0x20,
-+ 0x50, 0x50, 0x88, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x08, 0x09, 0x7f, 0x2a, 0x2a, 0x5d, 0x1c, 0x2a,
-+ 0x4e, 0x12, 0x2c, 0x44, 0x1a, 0x60, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0xa0, 0xb8, 0xa8, 0xa8, 0xa8,
-+ 0xf8, 0x88, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x2a, 0x2a, 0x5d, 0x1c, 0x2a,
-+ 0x4e, 0x12, 0x2c, 0x44, 0x1b, 0x60, 0x00, 0x00,
-+ 0x40, 0x40, 0x78, 0x88, 0xe8, 0xa8, 0xa8, 0xe8,
-+ 0xb0, 0x80, 0x84, 0x7c, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x1f, 0x12, 0x1f, 0x17, 0x17, 0x1a, 0x11,
-+ 0x1f, 0x1f, 0x21, 0x3f, 0x42, 0x0c, 0x00, 0x00,
-+ 0x80, 0xfc, 0x10, 0xfc, 0x38, 0xbc, 0xd4, 0x40,
-+ 0x7c, 0x78, 0xc0, 0x7c, 0x40, 0x40, 0x00, 0x00,
-+ 0x0a, 0x11, 0x1a, 0x19, 0x3f, 0x24, 0x5f, 0x07,
-+ 0x7f, 0x0f, 0x0f, 0x09, 0x0f, 0x38, 0x00, 0x00,
-+ 0xb0, 0x90, 0xb0, 0xb0, 0xfc, 0x48, 0xf0, 0xc0,
-+ 0xfc, 0xe0, 0xe0, 0x20, 0xe0, 0x38, 0x00, 0x00,
-+ 0x06, 0x38, 0x08, 0x7f, 0x1c, 0x2a, 0x49, 0x0a,
-+ 0x0d, 0x79, 0x05, 0x07, 0x39, 0x03, 0x00, 0x00,
-+ 0x40, 0x40, 0xf8, 0x28, 0x48, 0x88, 0x30, 0x80,
-+ 0x60, 0x3c, 0xc0, 0x60, 0x18, 0x00, 0x00, 0x00,
-+ 0x06, 0x38, 0x08, 0x7f, 0x1c, 0x2a, 0x4d, 0x1c,
-+ 0x6b, 0x2e, 0x1c, 0x6b, 0x08, 0x18, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x20, 0x3c, 0x20, 0x20, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x06, 0x38, 0x09, 0x7f, 0x1c, 0x2a, 0x49, 0x1c,
-+ 0x2a, 0x6d, 0x1d, 0x6b, 0x09, 0x19, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x98, 0xe8, 0xb8, 0xc8, 0xf8,
-+ 0x20, 0xfc, 0x54, 0xec, 0x04, 0x0c, 0x00, 0x00,
-+ 0x00, 0x3f, 0x35, 0x2f, 0x2d, 0x3f, 0x04, 0x3f,
-+ 0x06, 0x78, 0x1a, 0x2d, 0x2d, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x50, 0x50, 0x88, 0x74, 0x00,
-+ 0xf0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00,
-+ 0x00, 0x3f, 0x35, 0x2f, 0x2d, 0x3f, 0x04, 0x3f,
-+ 0x06, 0x78, 0x1a, 0x2d, 0x2d, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0xa8, 0xa8, 0xa8, 0xf8, 0xa8, 0x20,
-+ 0xa8, 0xa8, 0xa8, 0xa8, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3f, 0x35, 0x2f, 0x2d, 0x3f, 0x04, 0x3f,
-+ 0x06, 0x78, 0x1a, 0x2d, 0x2d, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0x3c, 0x20, 0x20, 0x20, 0xf8,
-+ 0x88, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3e, 0x2a, 0x2e, 0x3b, 0x3f, 0x08, 0x3e,
-+ 0x0c, 0x71, 0x1f, 0x2e, 0x2e, 0x40, 0x00, 0x00,
-+ 0x90, 0x90, 0x90, 0x90, 0x50, 0x7c, 0xd4, 0x94,
-+ 0xd4, 0x54, 0xe4, 0x24, 0x44, 0x98, 0x00, 0x00,
-+ 0x00, 0x3f, 0x35, 0x2f, 0x2d, 0x3f, 0x04, 0x3f,
-+ 0x06, 0x78, 0x1a, 0x2d, 0x2d, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0x20, 0x20, 0xf8, 0x00,
-+ 0xf8, 0x88, 0x88, 0x88, 0xf8, 0x88, 0x00, 0x00,
-+ 0x00, 0x3f, 0x35, 0x2f, 0x2d, 0x3f, 0x04, 0x3f,
-+ 0x06, 0x78, 0x1a, 0x2d, 0x2d, 0x40, 0x00, 0x00,
-+ 0x10, 0x10, 0xfc, 0x00, 0x78, 0x48, 0x48, 0x78,
-+ 0x10, 0x58, 0x54, 0x94, 0x10, 0x30, 0x00, 0x00,
-+ 0x09, 0x05, 0x3f, 0x27, 0x47, 0x1f, 0x19, 0x15,
-+ 0x1f, 0x3f, 0x01, 0x7f, 0x24, 0x42, 0x00, 0x00,
-+ 0x20, 0x40, 0xfc, 0xc8, 0xc0, 0xf0, 0x30, 0x50,
-+ 0xf0, 0xf8, 0x00, 0xfc, 0x88, 0x44, 0x00, 0x00,
-+ 0x00, 0x3f, 0x35, 0x2f, 0x2d, 0x3f, 0x04, 0x3f,
-+ 0x06, 0x78, 0x1a, 0x2d, 0x2d, 0x40, 0x00, 0x00,
-+ 0x20, 0x20, 0xfc, 0x48, 0x30, 0xfc, 0x00, 0x78,
-+ 0x48, 0x78, 0x48, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x12, 0x1a, 0x2f, 0x5f, 0x1f, 0x1b, 0x2e, 0x6f,
-+ 0x2f, 0x22, 0x3f, 0x2f, 0x2b, 0x30, 0x00, 0x00,
-+ 0x20, 0xa0, 0xa0, 0xe0, 0xbc, 0xe8, 0xe8, 0xa8,
-+ 0x98, 0x10, 0xd8, 0xa8, 0xc4, 0x84, 0x00, 0x00,
-+ 0x00, 0x1f, 0x17, 0x17, 0x1f, 0x2f, 0x4f, 0x0f,
-+ 0x0d, 0x0f, 0x1f, 0x7f, 0x24, 0x42, 0x00, 0x00,
-+ 0x00, 0xfc, 0x14, 0x7c, 0x90, 0xb0, 0xc8, 0xe4,
-+ 0x60, 0xe0, 0xf0, 0xfc, 0x88, 0x44, 0x00, 0x00,
-+ 0x00, 0x3f, 0x2a, 0x2e, 0x3b, 0x3f, 0x09, 0x3e,
-+ 0x0c, 0x70, 0x1e, 0x2e, 0x28, 0x43, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0xfc, 0x5c, 0xfc, 0xf8,
-+ 0x88, 0xf8, 0xf8, 0xf8, 0xc8, 0x04, 0x00, 0x00,
-+ 0x02, 0x12, 0x0a, 0x7f, 0x11, 0x11, 0x3f, 0x51,
-+ 0x15, 0x15, 0x15, 0x19, 0x11, 0x11, 0x00, 0x00,
-+ 0x80, 0x90, 0xa0, 0xfc, 0x10, 0x08, 0xf4, 0x14,
-+ 0x50, 0x50, 0x50, 0x50, 0x10, 0x30, 0x00, 0x00,
-+ 0x14, 0x55, 0x36, 0x7f, 0x0a, 0x29, 0x7f, 0x2a,
-+ 0x3e, 0x3e, 0x3e, 0x2b, 0x2a, 0x27, 0x00, 0x00,
-+ 0x30, 0x28, 0x28, 0x20, 0xfc, 0x20, 0x28, 0x28,
-+ 0x68, 0x70, 0x90, 0x30, 0xc8, 0x04, 0x00, 0x00,
-+ 0x14, 0x55, 0x36, 0x7f, 0x0a, 0x29, 0x7f, 0x2a,
-+ 0x3e, 0x3e, 0x3e, 0x2a, 0x2a, 0x26, 0x00, 0x00,
-+ 0x28, 0x24, 0xfc, 0x20, 0xf8, 0xa8, 0xa8, 0xf8,
-+ 0xa8, 0xf8, 0xa8, 0xa8, 0xa8, 0x98, 0x00, 0x00,
-+ 0x00, 0x3f, 0x22, 0x3e, 0x02, 0x3e, 0x22, 0x3e,
-+ 0x22, 0x22, 0x3e, 0x22, 0x02, 0x01, 0x00, 0x00,
-+ 0x00, 0xf8, 0x88, 0xf8, 0x80, 0xf8, 0x88, 0xf8,
-+ 0x88, 0x88, 0xf8, 0x88, 0x04, 0xfc, 0x00, 0x00,
-+ 0x08, 0x3e, 0x7f, 0x08, 0x7f, 0x1e, 0x26, 0x5f,
-+ 0x1e, 0x3e, 0x3e, 0x22, 0x3e, 0x21, 0x00, 0x00,
-+ 0x20, 0x20, 0x7c, 0xc8, 0x30, 0x30, 0xcc, 0xf0,
-+ 0xf0, 0xf8, 0xf8, 0x88, 0xfc, 0xfc, 0x00, 0x00,
-+ 0x2a, 0x49, 0x7f, 0x5d, 0x6b, 0x49, 0x1f, 0x1e,
-+ 0x32, 0x22, 0x3a, 0x3a, 0x22, 0x01, 0x00, 0x00,
-+ 0x40, 0x7c, 0xc8, 0x28, 0x30, 0xcc, 0xf0, 0xf0,
-+ 0xf8, 0x88, 0xf8, 0xf8, 0x84, 0xfc, 0x00, 0x00,
-+ 0x08, 0x08, 0x7f, 0x08, 0x3e, 0x00, 0x3e, 0x22,
-+ 0x3e, 0x24, 0x15, 0x1f, 0x1a, 0x65, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xfc, 0xa8, 0xa0, 0xf8, 0xc8,
-+ 0xd0, 0xb0, 0x20, 0x50, 0x88, 0x04, 0x00, 0x00,
-+ 0x08, 0x7f, 0x3e, 0x1e, 0x12, 0x1e, 0x0f, 0x73,
-+ 0x06, 0x19, 0x07, 0x79, 0x00, 0x07, 0x00, 0x00,
-+ 0x20, 0xfc, 0x20, 0xf8, 0x50, 0x70, 0x8c, 0xe0,
-+ 0x40, 0x80, 0xe0, 0x9c, 0xc0, 0x00, 0x00, 0x00,
-+ 0x02, 0x11, 0x09, 0x08, 0x1f, 0x11, 0x11, 0x1f,
-+ 0x11, 0x11, 0x1f, 0x21, 0x21, 0x41, 0x00, 0x00,
-+ 0x10, 0x10, 0x20, 0x40, 0xf0, 0x10, 0x10, 0xf0,
-+ 0x10, 0x10, 0xf4, 0x0c, 0x0c, 0x04, 0x00, 0x00,
-+ 0x08, 0x36, 0x22, 0x36, 0x22, 0x3e, 0x2a, 0x2a,
-+ 0x3e, 0x2a, 0x3d, 0x29, 0x3e, 0x48, 0x00, 0x00,
-+ 0x20, 0x20, 0x20, 0xf8, 0xa8, 0xa8, 0xf8, 0xa8,
-+ 0xa8, 0xf8, 0x88, 0x04, 0xc4, 0x3c, 0x00, 0x00,
-+ 0x08, 0x1e, 0x12, 0x1e, 0x1e, 0x1e, 0x3f, 0x3f,
-+ 0x25, 0x3f, 0x7f, 0x12, 0x12, 0x22, 0x00, 0x00,
-+ 0x00, 0xf8, 0x20, 0x20, 0x20, 0x20, 0xfc, 0x20,
-+ 0x20, 0x20, 0xa0, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x01, 0x7f, 0x02, 0x7d, 0x15, 0x15, 0x2d, 0x48,
-+ 0x0f, 0x08, 0x0f, 0x08, 0x10, 0x20, 0x00, 0x00,
-+ 0x00, 0xfc, 0x88, 0x70, 0x50, 0x50, 0xe8, 0x24,
-+ 0xe0, 0x20, 0xe0, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x01, 0x09, 0x09, 0x09, 0x7f, 0x24, 0x2a, 0x33,
-+ 0x3f, 0x24, 0x2a, 0x33, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0x00, 0xf0, 0x00, 0xfc, 0x48, 0xa8, 0x28,
-+ 0xf8, 0x48, 0xa8, 0x28, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x14, 0x17, 0x14, 0x7f, 0x2a, 0x2a, 0x35,
-+ 0x3f, 0x2a, 0x2a, 0x35, 0x3f, 0x20, 0x00, 0x00,
-+ 0x20, 0x20, 0xa0, 0x20, 0xe4, 0xa4, 0xa8, 0xb0,
-+ 0xa0, 0xa0, 0xa0, 0xa4, 0xa4, 0x9c, 0x00, 0x00,
-+ 0x04, 0x14, 0x17, 0x14, 0x7f, 0x2b, 0x2b, 0x35,
-+ 0x3f, 0x2b, 0x2b, 0x35, 0x3f, 0x21, 0x00, 0x00,
-+ 0x40, 0x40, 0x40, 0x78, 0x88, 0xe8, 0xa8, 0xa8,
-+ 0xe8, 0xa8, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x04, 0x14, 0x17, 0x14, 0x7f, 0x2b, 0x2b, 0x35,
-+ 0x3f, 0x2b, 0x2b, 0x35, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0xc8, 0x78, 0x48, 0x48,
-+ 0x78, 0x48, 0x48, 0x48, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x14, 0x17, 0x14, 0x7f, 0x2b, 0x2b, 0x35,
-+ 0x3f, 0x2b, 0x2b, 0x35, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0xf8, 0x28, 0x28, 0xa8, 0x48, 0xb0, 0x00,
-+ 0x78, 0x48, 0x48, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x04, 0x14, 0x17, 0x14, 0x7f, 0x2b, 0x2b, 0x35,
-+ 0x3f, 0x2b, 0x2b, 0x35, 0x3f, 0x21, 0x00, 0x00,
-+ 0x20, 0x20, 0x50, 0x50, 0x88, 0x74, 0x00, 0xf8,
-+ 0x28, 0x28, 0x30, 0x20, 0x20, 0x20, 0x00, 0x00,
-+ 0x04, 0x14, 0x17, 0x14, 0x7f, 0x2b, 0x2b, 0x35,
-+ 0x3f, 0x2b, 0x2b, 0x35, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0xf8, 0x48, 0x48, 0x78,
-+ 0x64, 0x68, 0x50, 0x50, 0x68, 0x84, 0x00, 0x00,
-+ 0x08, 0x7f, 0x3e, 0x0e, 0x79, 0x09, 0x7f, 0x26,
-+ 0x29, 0x3f, 0x26, 0x29, 0x3f, 0x20, 0x00, 0x00,
-+ 0x00, 0xf8, 0x48, 0x88, 0x30, 0xf0, 0xfc, 0x48,
-+ 0xa8, 0xf8, 0x48, 0xa8, 0xf8, 0x08, 0x00, 0x00,
-+ 0x04, 0x14, 0x17, 0x14, 0x7f, 0x2b, 0x2b, 0x35,
-+ 0x3f, 0x2b, 0x2b, 0x35, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0xfc, 0x20, 0x20, 0xf8, 0x48, 0x48, 0xfc,
-+ 0x00, 0x78, 0x48, 0x48, 0x78, 0x48, 0x00, 0x00,
-+ 0x04, 0x14, 0x17, 0x14, 0x7f, 0x2b, 0x2b, 0x35,
-+ 0x3f, 0x2b, 0x2b, 0x35, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x48, 0xc8, 0x78, 0x10, 0x50,
-+ 0x5c, 0x50, 0x50, 0x70, 0x90, 0x0c, 0x00, 0x00,
-+ 0x04, 0x14, 0x17, 0x14, 0x7f, 0x2b, 0x2b, 0x35,
-+ 0x3f, 0x2b, 0x2b, 0x35, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0x78, 0x48, 0x78, 0xc0, 0x7c, 0x58, 0x54,
-+ 0x7c, 0x50, 0x7c, 0x90, 0xfc, 0x00, 0x00, 0x00,
-+ 0x04, 0x14, 0x17, 0x14, 0x7f, 0x2b, 0x2b, 0x35,
-+ 0x3f, 0x2b, 0x2b, 0x35, 0x3f, 0x21, 0x00, 0x00,
-+ 0x18, 0xe0, 0x20, 0xf8, 0xa8, 0xa8, 0xf8, 0x20,
-+ 0xfc, 0xd4, 0xfc, 0x84, 0x84, 0x8c, 0x00, 0x00,
-+ 0x04, 0x14, 0x17, 0x14, 0x7f, 0x2b, 0x2b, 0x35,
-+ 0x3f, 0x2b, 0x2b, 0x35, 0x3f, 0x21, 0x00, 0x00,
-+ 0x00, 0xfc, 0xb4, 0xfc, 0x00, 0x78, 0x00, 0xfc,
-+ 0x20, 0x38, 0x48, 0x08, 0x08, 0x30, 0x00, 0x00,
-+ 0x01, 0x02, 0x0f, 0x7f, 0x08, 0x0f, 0x3f, 0x12,
-+ 0x7f, 0x1e, 0x1e, 0x1e, 0x12, 0x16, 0x00, 0x00,
-+ 0x00, 0x80, 0xe0, 0xfc, 0x20, 0xe0, 0xf8, 0xf0,
-+ 0x10, 0xf0, 0xf0, 0xf0, 0xf4, 0x7c, 0x00, 0x00,
-+ 0x02, 0x07, 0x19, 0x7f, 0x12, 0x1e, 0x3a, 0x7e,
-+ 0x3a, 0x3a, 0x7e, 0x0a, 0x3a, 0x01, 0x00, 0x00,
-+ 0x00, 0xc0, 0x00, 0xf0, 0x90, 0xf0, 0x80, 0xf8,
-+ 0xd8, 0xa8, 0xd8, 0xfc, 0x84, 0xfc, 0x00, 0x00,
-+ 0x01, 0x02, 0x04, 0x1f, 0x60, 0x3b, 0x2a, 0x3b,
-+ 0x00, 0x1f, 0x12, 0x1f, 0x12, 0x12, 0x00, 0x00,
-+ 0x00, 0x80, 0x40, 0xf0, 0x0c, 0xb8, 0xa8, 0xb8,
-+ 0x00, 0xf0, 0x90, 0xf0, 0x90, 0xb0, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x01, 0x1f, 0x01, 0x3f, 0x08, 0x3e, 0x08, 0x0f,
-+ 0x70, 0x3f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00,
-+ 0x00, 0xf0, 0x00, 0xf8, 0x20, 0xf8, 0x20, 0xfc,
-+ 0x00, 0xf8, 0x40, 0x44, 0x44, 0x3c, 0x00, 0x00,
-+ 0x08, 0x08, 0x08, 0x7f, 0x09, 0x19, 0x1d, 0x1b,
-+ 0x2b, 0x29, 0x49, 0x09, 0x08, 0x0b, 0x00, 0x00,
-+ 0x98, 0xe0, 0x84, 0x7c, 0x78, 0x48, 0x78, 0x48,
-+ 0x78, 0x48, 0x78, 0xfc, 0xd8, 0x04, 0x00, 0x00,
-+ 0x20, 0x10, 0x11, 0x46, 0x21, 0x2f, 0x02, 0x77,
-+ 0x12, 0x12, 0x13, 0x1a, 0x26, 0x41, 0x00, 0x00,
-+ 0x40, 0xf8, 0x90, 0x60, 0x80, 0xf8, 0x40, 0xfc,
-+ 0x48, 0x48, 0xf8, 0x08, 0x00, 0xfc, 0x00, 0x00,
-+ 0x00, 0x00, 0x7c, 0x11, 0x16, 0x10, 0x7f, 0x11,
-+ 0x12, 0x17, 0x1e, 0x62, 0x03, 0x02, 0x00, 0x00,
-+ 0x40, 0x78, 0xc8, 0x30, 0xa0, 0xc0, 0x00, 0xf8,
-+ 0x40, 0xfc, 0x48, 0x48, 0xf8, 0x08, 0x00, 0x00
-+};
-diff -Nur linux_c860_org/drivers/video/shepherdLogoMsg.c linux/drivers/video/shepherdLogoMsg.c
---- linux_c860_org/drivers/video/shepherdLogoMsg.c 2003-07-12 18:18:36.000000000 +0900
-+++ linux/drivers/video/shepherdLogoMsg.c 2004-06-10 21:09:11.000000000 +0900
-@@ -2,147 +2,257 @@
- #ifndef __initdata
- #define __initdata
- #endif
--static const int logo_msg_width __initdata = 20;
--static const int logo_msg_height __initdata = 140;
--static const unsigned short logo_msg_data[20*140] __initdata ={
-- 0xffff,0x3186,0x0000,0x0841,0x0841,0x0841,0x0841,0x0841,0x0841,0x0841,0x0861,0x0861,0x0841,0x0841,0x0841,0x0841,0x0841,0x0841,0x0841,0x18e3,
-- 0xffff,0x39e7,0x10a2,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x2104,0x18c3,0x0000,0x0000,0x18c3,0x2104,0x18e3,0x18e3,0x2104,0x18c3,0x0000,0x0861,
-- 0xad37,0x83f3,0x83f3,0x8bf3,0x8bf3,0x8bf3,0x8bf3,0x8bf3,0x8c33,0x7b91,0x0862,0x0862,0x7b90,0x8c33,0x8bf3,0x8bf3,0x8c33,0x7b91,0x1062,0x0841,
-- 0xb558,0xa4b6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4f7,0xa4d6,0x83f3,0x1082,0x1082,0x9454,0xa4d6,0xa4d6,0xa4f7,0xa4d6,0x83f3,0x1082,0x0841,
-- 0xf79e,0xf77e,0xf79e,0xf79e,0xf79e,0xf79e,0xf79e,0xf79e,0xe73d,0x8c33,0x1082,0x18c3,0xd6ba,0xf79e,0xf79e,0xf79e,0xe73d,0x8c33,0x1082,0x0841,
-- 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x8c33,0x1082,0x18c3,0xdefb,0xffff,0xffff,0xffff,0xf79e,0x8c34,0x1082,0x0841,
-- 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x8c33,0x1082,0x18c3,0xdefb,0xffff,0xffff,0xffff,0xf79e,0x8c33,0x1082,0x0841,
-- 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x8c33,0x1082,0x18c3,0xdefb,0xffff,0xffff,0xffff,0xf79e,0x8c33,0x1082,0x0841,
-- 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x8c33,0x1082,0x18c3,0xe71c,0xffff,0xffff,0xffff,0xf79e,0x9454,0x1082,0x0841,
-- 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x8c33,0x1082,0x10a2,0xce59,0xffff,0xffff,0xffff,0xf79e,0x83d2,0x0862,0x0841,
-- 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x9454,0x20e4,0x0000,0x3186,0xd69a,0xef7d,0xef7d,0xc639,0x18e4,0x0000,0x2104,
-- 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf77e,0xa4d6,0x7bb1,0x3166,0x18c3,0x2124,0x2124,0x2124,0x2104,0x1062,0x20e4,0xbdf7,
-- 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xad37,0x9475,0x9cb5,0xb5b7,0x2965,0x10a2,0x1082,0x20e4,0x7370,0x9475,0xffff,
-- 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73d,0xad37,0xa4d6,0xa4f7,0x9474,0x9454,0x9454,0x8c34,0xad17,0xe71d,0xffff,
-- 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7bf,0xef3d,0xad17,0xa4b6,0xa4b6,0xad17,0xef3d,0xf7bf,0xffff,0xffff,
-- 0xffff,0xe71c,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xd69a,0xd69a,0xd69a,0xd69a,0xdefb,0xdefb,0xdefb,0xdefb,
-- 0xffff,0x39e7,0x1082,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x10a2,0x2124,
-- 0xf79e,0x39c7,0x1082,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x10a2,0x2124,
-- 0xb558,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c13,0x9454,0xdefb,
-- 0xb558,0x9cb6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4b6,0xa4f7,0xffff,
-- 0xf79e,0xf77e,0xf79e,0xf79e,0xef7e,0xd6ba,0xce7a,0xd69a,0xd69a,0xce7a,0xd6ba,0xef7e,0xf79e,0xf79e,0xf79e,0xf79e,0xf79e,0xf77e,0xf79e,0xffff,
-- 0xffff,0xffff,0xffff,0xf79e,0xce79,0x3186,0x10a2,0x2104,0x2104,0x10a2,0x3186,0xce79,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xce79,0x39e7,0x18e3,0x20e4,0x18c3,0x0000,0x0000,0x18c3,0x2104,0x18e3,0x39e7,0xce79,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xe73c,0x31a6,0x0000,0x18e4,0x83f2,0x83f2,0x1062,0x0862,0x8c12,0xc618,0x2965,0x0000,0x39c7,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xb5b7,0x0841,0x18c3,0x83f2,0xa4d6,0x83f3,0x1082,0x1082,0x9454,0xa4d7,0x8c53,0x2124,0x1082,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xf7be,0x2945,0x0841,0x83d1,0xef5e,0xef5d,0x8c33,0x1082,0x18c3,0xce7a,0xad17,0x9c75,0x83f2,0x1082,0x31a6,0xe73c,0xffff,0xffff,0xffff,0xffff,
-- 0xe73d,0x1082,0x1082,0xce7a,0xffff,0xf79e,0x8c33,0x1082,0x18c3,0xdefb,0xef5d,0xad17,0x8c34,0x18e3,0x10a2,0xdedb,0xffff,0xffff,0xffff,0xffff,
-- 0xb558,0x1082,0x18c3,0xe71c,0xffff,0xf79e,0x8c33,0x1082,0x18c3,0xdefb,0xffff,0xe73d,0x7bb1,0x0861,0x3186,0xe73c,0xffff,0xffff,0xffff,0xffff,
-- 0xa4f7,0x2105,0x1082,0xc638,0xffff,0xf79e,0x8c33,0x1082,0x18c3,0xe71c,0xffff,0xc639,0x18c3,0x0841,0xbdb7,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xa4f7,0x7bb1,0x1082,0x2965,0xce79,0xf79e,0x8c33,0x1082,0x10a2,0xce59,0xd69a,0x2945,0x0000,0x2125,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xad38,0x9454,0x31a6,0x0000,0x3186,0xdefc,0x9454,0x1082,0x0000,0x18c3,0x18e3,0x0862,0x2104,0xbdb7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xe73d,0x9cb6,0x8412,0x2945,0x3186,0xdedb,0x9474,0x2105,0x18c3,0x1082,0x20e4,0x7370,0x9cd5,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xf7be,0xad38,0x9475,0x9cb5,0xdefb,0xf79e,0xa4d6,0x83f3,0x8c33,0x8c33,0x8c33,0xad37,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xef5d,0xad17,0x9cb5,0xdedb,0xd69a,0x9cb5,0xa4d6,0xa4b6,0xad17,0xef3d,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xc638,0x3186,0x10a2,0x10a2,0x3186,0xc618,0xf77e,0xf79e,0xffdf,0xdefb,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xd69a,0x3186,0x0000,0x10a2,0x10a2,0x0000,0x31a6,0xd69a,0xffff,0xe71c,0x31a6,0x2965,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0x39c7,0x0000,0x20e4,0x83f2,0x8c33,0x2966,0x0000,0x39c7,0xef5d,0xdedb,0x31a6,0x0861,0x3186,0xce79,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xef5e,0x18a3,0x0841,0x7bb1,0xa4b6,0x9c75,0x8412,0x1082,0x18e3,0xd6ba,0xad37,0x9c95,0xb576,0x1082,0x3186,0xe73c,0xffff,0xffff,0xffff,0xffff,
-- 0xb558,0x1082,0x10a2,0xd69a,0xef5e,0xad37,0x8c13,0x18e4,0x10a2,0xc618,0xad38,0x9cb6,0x9494,0x18e3,0x18c3,0xdefb,0xffff,0xffff,0xffff,0xffff,
-- 0xa4f7,0x2104,0x0861,0xc638,0xffff,0xef3d,0x9cb6,0x7b91,0x10a2,0x39c7,0xdefb,0xe71d,0x8c33,0x1082,0x18c3,0xdefb,0xffff,0xffff,0xffff,0xffff,
-- 0xa4f7,0x83f2,0x3186,0x2965,0xce79,0xf7be,0xad17,0x8c34,0x18e3,0x18c3,0xdefb,0xf79e,0x83d2,0x0861,0x18c3,0xdefb,0xffff,0xffff,0xffff,0xffff,
-- 0xad38,0x9cb6,0xad76,0x0861,0x2965,0xce59,0xd69b,0x7bb1,0x1082,0x10a2,0xce59,0xce59,0x20e4,0x0000,0x31a6,0xe73c,0xffff,0xffff,0xffff,0xffff,
-- 0xef5d,0x8c33,0x2125,0x0000,0x0000,0x18c3,0x2104,0x1082,0x0000,0x0000,0x18e3,0x18c3,0x0000,0x18e4,0xc618,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0x3186,0x0000,0x0862,0x18c3,0x10a2,0x1082,0x0861,0x1082,0x18c3,0x1082,0x0841,0x18c3,0x8c33,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xef5e,0x2125,0x18c3,0x7370,0x8c33,0x8c13,0x8c13,0x83d2,0x83d2,0x8c13,0x8c13,0x7bb2,0x9454,0xef3d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xad58,0x83f3,0x9454,0xa4d6,0xa4b6,0xa4b6,0xa4b6,0xa4d6,0xa4d6,0xa4b6,0x9cb6,0xad17,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xad37,0xad17,0xd67a,0xd67a,0xd69a,0xef5d,0xef7e,0xef7e,0xef5e,0xd69a,0xce7a,0xd67a,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xf79e,0xdedb,0x4208,0x1082,0x39c7,0xe71c,0xffff,0xffff,0xce79,0x39c7,0x18c3,0x18c3,0x39c7,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xbdf7,0x10a2,0x0841,0x39c7,0xe71c,0xffff,0xe71c,0x31a6,0x0000,0x18c3,0x18c3,0x0000,0x3186,0xce79,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xf7be,0x2925,0x0861,0x83f2,0xdefc,0xffdf,0xffff,0xce5a,0x1082,0x0862,0x83d2,0x9453,0x2966,0x0000,0x39c7,0xe73c,0xffff,0xffff,0xffff,0xffff,
-- 0xe73d,0x1082,0x1082,0x9c95,0xf79e,0xffff,0xf79e,0x8c33,0x0862,0x1082,0x8c33,0x9c75,0x8412,0x1082,0x18c3,0xdefb,0xffff,0xffff,0xffff,0xffff,
-- 0xad38,0x10a3,0x18c3,0xd6bb,0xffff,0xffff,0xdedb,0x2925,0x0000,0x31a6,0xd69a,0xad37,0x83f3,0x1082,0x18c3,0xdefb,0xffff,0xffff,0xffff,0xffff,
-- 0xa4f7,0x10a3,0x18c3,0xe71c,0xffff,0xffff,0xce5a,0x1082,0x0861,0xbdf7,0xffff,0xef3d,0x8c33,0x1082,0x18c3,0xdefb,0xffff,0xffff,0xffff,0xffff,
-- 0xa4f7,0x10a3,0x1082,0xce59,0xffff,0xf7be,0x8c33,0x0861,0x1082,0xd69a,0xffff,0xf79e,0x7bd1,0x0861,0x3166,0xe73c,0xffff,0xffff,0xffff,0xffff,
-- 0xa4f7,0x2925,0x0000,0x3186,0xd69a,0xc639,0x20e4,0x0000,0x3186,0xe73c,0xffff,0xc618,0x18c3,0x0841,0xbdb7,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xa4f7,0x83d2,0x2945,0x0000,0x18c3,0x18c3,0x0000,0x18e4,0xc618,0xffff,0xe73c,0x2966,0x0000,0x2125,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xb558,0x9c75,0x8c33,0x3186,0x1082,0x0862,0x18e4,0x8c33,0xf79e,0xffff,0xce7a,0x18e4,0x18c3,0xbdb7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xef5d,0xad17,0x9475,0x8c54,0x8c33,0x83f3,0x9cb5,0xef5d,0xffff,0xf79e,0xad17,0x83f3,0x9c95,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xef5d,0xad37,0xa4b6,0xa4b6,0x9cb5,0xce7a,0xdefb,0xdefb,0xd69a,0x9c95,0xad17,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xf77e,0xdedb,0xbdf7,0x2965,0x10a2,0x2104,0x2104,0x10a2,0x2965,0xbdd7,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xce59,0x31a6,0x10a2,0x18e3,0x18c3,0x0000,0x0000,0x18c3,0x2104,0x10a2,0x31a6,0xce59,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xe73c,0x39a7,0x0000,0x18e4,0x83f2,0x83f2,0x1062,0x0862,0x8c12,0xbdf8,0x2965,0x0000,0x39c7,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xb596,0x0841,0x18c3,0x83f2,0xa4d6,0x83f3,0x1082,0x1082,0x9454,0xa4d6,0x8c33,0x2125,0x1082,0xc618,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xf7be,0x2125,0x0841,0x83f2,0xef5e,0xef5d,0x8c33,0x1082,0x18c3,0xce7a,0xad17,0x9c75,0x8c12,0x1082,0x3186,0xe73c,0xffff,0xffff,0xffff,0xffff,
-- 0xe73d,0x1082,0x1082,0xce7a,0xffff,0xf79e,0x8c33,0x1082,0x18c3,0xdefb,0xef5d,0xad17,0x8c34,0x18e3,0x10a2,0xdedb,0xffff,0xffff,0xffff,0xffff,
-- 0xad38,0x1082,0x18c3,0xe71c,0xffff,0xf79e,0x8c33,0x1082,0x18c3,0xdefb,0xffff,0xef3d,0x7bb1,0x0861,0x3186,0xe73c,0xffff,0xffff,0xffff,0xffff,
-- 0xa4f7,0x2105,0x1082,0xc638,0xffff,0xf79e,0x8c33,0x1082,0x18c3,0xe71c,0xffff,0xc639,0x18c3,0x0841,0xbdb7,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xa4f7,0x7bb1,0x1082,0x2965,0xce79,0xf79e,0x8c33,0x1082,0x10a2,0xce59,0xd69a,0x2945,0x0000,0x2125,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xad38,0x9454,0x31a6,0x0000,0x3186,0xdefc,0x9454,0x1082,0x0000,0x18c3,0x18e3,0x0862,0x2104,0xbdb7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xe73d,0x9cb6,0x8412,0x2945,0x3186,0xdedb,0x9474,0x2105,0x18c3,0x1082,0x20e4,0x7370,0x9cd5,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xf7be,0xad38,0x9475,0x9494,0xd6bb,0xf77e,0xa4d6,0x83f3,0x8c33,0x8c33,0x8c33,0xad37,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xef5d,0xad17,0xad17,0xf7be,0xf7bf,0xb558,0xa4d6,0xa4b6,0xad17,0xef3d,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xf79e,0xf79e,0xffff,0xffff,0xf79e,0xf77e,0xf77e,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0xdefb,0xffdf,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0xef5d,0xce79,0x2945,0x2965,0xe71c,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0xe71c,0xce59,0x39c7,0x18e3,0x2124,0x10a2,0x39c7,0xe71c,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xffff,0xffff,0xe71c,0xe71c,0xce59,0x3186,0x10a2,0x18e3,0x18e3,0x1082,0x18e4,0x83f2,0xdefb,0xffdf,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xe71c,0xe73c,0xce59,0x31a6,0x10a2,0x18e3,0x18e3,0x1082,0x20e4,0x83d2,0x9474,0x8c34,0xad37,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0x4208,0x18e3,0x2104,0x0020,0x10a2,0x2125,0x83d2,0x9454,0x8c33,0x9cb6,0xad17,0xef3d,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xf79e,0x39e7,0x0861,0x0000,0x0862,0x734f,0x8c33,0x8c33,0x9cb5,0xef3d,0xf79e,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xb558,0x9474,0x83d2,0x20e4,0x1082,0x2125,0x2945,0x10a2,0x2965,0xbdf7,0xe71c,0xdefb,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xb558,0x9cb6,0x9475,0x8c34,0xc619,0xb596,0x2945,0x10a2,0x2104,0x2965,0x2124,0x18c3,0x31a6,0xc638,0xe73c,0xffdf,0xffff,0xffff,0xffff,0xffff,
-- 0xf7bf,0xef3d,0xad37,0xa4f7,0xad37,0xad17,0x9454,0x9494,0xd69b,0xb5b7,0x18c3,0x0000,0x0000,0x1082,0x39c7,0xe71c,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xf79e,0xf79e,0xe71d,0xad17,0x9454,0x9454,0x9cb5,0x7bb1,0x1082,0x0000,0x0000,0x1082,0x39c7,0xe71c,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xffff,0xe73c,0xef5d,0xbdf7,0x2965,0x10a2,0x18e3,0x18a3,0x1082,0x0841,0x18e4,0x8412,0xdedb,0xffdf,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xef5d,0xce59,0x39e7,0x2945,0x39e7,0x2945,0x10a2,0x2945,0x7370,0x83d2,0x7bb2,0x8c13,0xad37,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0x4208,0x0861,0x0000,0x10a2,0x7390,0x8c13,0x8c34,0x9c95,0xa4d6,0xa4b6,0xad17,0xef3d,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xf7bf,0x31a7,0x0861,0x1082,0x0020,0x1082,0x2925,0x8c33,0xce7a,0xd6bb,0xef5d,0xf77e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xb558,0x8413,0x83d2,0x7bb1,0x2945,0x1082,0x18c3,0x2104,0x18e3,0x31a6,0xce79,0xe73c,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xb558,0xa4b6,0xa4d6,0x9c95,0x9454,0x9cb5,0xbdb7,0x2965,0x10a2,0x18e3,0x18e3,0x10a2,0x3186,0xc638,0xe73c,0xffdf,0xffff,0xffff,0xffff,0xffff,
-- 0xf77e,0xf77e,0xe73d,0xad37,0x9cb6,0xa4d6,0xa4f7,0x9454,0x9c95,0xbdb7,0x2965,0x10a2,0x18e3,0x10a2,0x39c7,0xe71c,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xffff,0xf79e,0xf79e,0xef3d,0xad17,0xa4b6,0xa4d7,0xa4d6,0x8c33,0x9c95,0xb5b7,0x2104,0x2945,0xe71c,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xffff,0xe71c,0xdefb,0xdedb,0xd6bb,0xf79e,0xef3d,0xad17,0xa4b6,0xa4d7,0xa4b6,0x9474,0xce59,0xffdf,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xce79,0x31a6,0x10a2,0x10a2,0x31a6,0xce79,0xffff,0xf79e,0xef7e,0xce39,0x9454,0xa4f7,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xce79,0x2965,0x0000,0x10a3,0x18c3,0x0000,0x3186,0xce79,0xffff,0xe71c,0x3186,0x2124,0xc5f8,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0x39e7,0x0000,0x18e4,0x83d2,0x8c33,0x2945,0x0000,0x39e7,0xef5d,0xdedb,0x3186,0x0841,0x31a6,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xef5e,0x10a3,0x0841,0x7bd1,0xa4d6,0x9c75,0x83f2,0x1082,0x18e3,0xd6bb,0xad17,0x9495,0xad76,0x1082,0x3186,0xe73c,0xffff,0xffff,0xffff,0xffff,
-- 0xb558,0x1082,0x10a2,0xd67a,0xef5d,0xad17,0x8c13,0x2105,0x10a2,0xbdf7,0xad37,0x9c96,0x9c95,0x18e3,0x18c3,0xdefb,0xffff,0xffff,0xffff,0xffff,
-- 0xa4f7,0x20e4,0x0862,0xce79,0xffff,0xef3d,0x9cb6,0x7bd1,0x10a2,0x3186,0xdedb,0xe71d,0x8c33,0x1082,0x18c3,0xdefb,0xffff,0xffff,0xffff,0xffff,
-- 0xa4f7,0x83d2,0x3186,0x31a6,0xce79,0xf7be,0xad37,0x8c34,0x18e3,0x18c3,0xdefb,0xf79e,0x83d2,0x0861,0x18c3,0xdefb,0xffff,0xffff,0xffff,0xffff,
-- 0xad37,0x9cb6,0xb576,0x0861,0x2965,0xce59,0xd6bb,0x7bb1,0x1082,0x10a2,0xce59,0xce59,0x20e4,0x0000,0x31a6,0xe73c,0xffff,0xffff,0xffff,0xffff,
-- 0xef3d,0x8c33,0x2925,0x0000,0x0000,0x18c3,0x2104,0x1062,0x0000,0x0000,0x18e3,0x18c3,0x0000,0x18e4,0xc618,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0x3186,0x0000,0x1082,0x2104,0x18c3,0x18c3,0x1082,0x10a3,0x18e3,0x18c3,0x0862,0x18e4,0x8c33,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xef5e,0x2125,0x18c3,0x7b91,0x9454,0x9454,0x8c33,0x83f2,0x83f2,0x8c33,0x8c33,0x83d2,0x9494,0xef3d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xad58,0x83f3,0x8c54,0xa4f7,0xa4d6,0xa4d6,0xa4d6,0xa4f7,0xa4f7,0xa4d6,0xa4b6,0xad37,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xad37,0xad17,0xef3d,0xf79e,0xf79e,0xf79e,0xf79e,0xf79e,0xf79e,0xf79e,0xf77e,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xf79e,0xd6bb,0xdedb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xe71c,0xffff,0xffff,0xe71c,0xdedb,0xdefb,
-- 0xffff,0x39e7,0x1082,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x10a2,0x31a6,0xe73c,0xe73c,0x31a6,0x0861,0x2124,
-- 0xf79e,0x39c7,0x1082,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x1082,0x31a6,0xe73c,0xdedb,0x31a6,0x0861,0x2124,
-- 0xb558,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x9474,0xd6bb,0xf79e,0xad37,0x8c13,0x8c53,0xdefb,
-- 0xb558,0x9cb6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4b6,0xad37,0xf7be,0xf7be,0xad37,0x9cb6,0xa4f7,0xffff,
-- 0xf79e,0xf77e,0xf79e,0xf79e,0xf79e,0xf79e,0xf79e,0xf79e,0xf79e,0xf79e,0xf79e,0xf79e,0xef7e,0xd69a,0xdefb,0xffdf,0xf79e,0xf77e,0xf79e,0xffff,
-- 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0x31a6,0x31a6,0xe73c,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xffff,0xe71c,0xdedb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xe73c,0xbdd7,0x10a2,0x10a2,0xc618,0xe73c,0xdedb,0xe71c,0xffdf,
-- 0xffff,0xce79,0x31a6,0x10a2,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x18e3,0x1082,0x0000,0x0020,0x18c3,0x18e3,0x10a2,0x31a6,0xe71c,
-- 0xffff,0x39c7,0x0000,0x18c3,0x18e3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x18c3,0x1082,0x0000,0x0020,0x18c3,0x18e3,0x1082,0x31a6,0xe71c,
-- 0xef5d,0x10a3,0x0861,0x7bb1,0x9454,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x8c33,0x9454,0x7370,0x0861,0x0861,0x7bb1,0x9454,0x9474,0xd6bb,0xffdf,
-- 0xb558,0x2105,0x20e4,0x9454,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0xa4d6,0x8c13,0x20e4,0x20e4,0x9454,0xa4b6,0xad37,0xf79e,0xffff,
-- 0xa4f7,0x8c33,0xce39,0xf77e,0xf79e,0xf79e,0xf79e,0xf79e,0xf79e,0xf79e,0xf79e,0xe73d,0x9cb6,0x8c13,0xce39,0xf77e,0xf77e,0xf79e,0xffff,0xffff,
-- 0xb558,0xad37,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xad37,0xad37,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xf79e,0xd6ba,0xdedb,0xe71c,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0x39e7,0x0841,0x31a6,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xf79e,0x39c7,0x0841,0x31a6,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xb558,0x8c13,0x9474,0xd6bb,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xb558,0x9c96,0xad37,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xf79e,0xef7e,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xe71c,0xdedb,0xe71c,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0x39e7,0x0841,0x31a6,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xf79e,0x39c7,0x0841,0x31a6,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xb558,0x8c13,0x9474,0xd6bb,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xb558,0x9c96,0xad37,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xf79e,0xef7e,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0xe71c,0xdedb,0xe71c,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xffff,0x39e7,0x0841,0x31a6,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xf79e,0x41e8,0x1082,0x39e7,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xb558,0x9c96,0xad37,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- 0xb578,0xa4b6,0xb558,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-- };
-+
-+static int logo_msg_width __initdata = 30;
-+static int logo_msg_height __initdata = 250;
-+static unsigned short logo_msg_data[] __initdata ={
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0xad55,0x7bef,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedb,0xc638,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x738e,0x0020,0x0000,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0x0020,0x528a,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x18c3,0x738e,0x9cf3,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x52aa,0x2104,0x0000,0x2104,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffbf,0x1082,0x18e3,0xef3d,0xffff,0xffff,0xffff,0xffff,0xe73c,0xbdf7,0xdebb,0xffdf,0xffff,0xffff,0xffdf,0x6b6d,0x0000,0x9cf3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xdebd,0xad17,0x0000,0x5a8c,0xef3e,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x7bb1,0xc5da,0xd67c,0xffbf,0xffff,0xef7d,0x0000,0x632c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xb558,0x0000,0x6b4e,0xf7bf,0xffff,0xffff,0xffff,0xffff,0x9492,0x0000,0x62ec,0xce1b,0xc5ba,0xce1b,0xffff,0xf7be,0x0000,0x630c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xc5fb,0xce1b,0xffff,0x18e3,0x2124,0xf79e,0xffff,0xffdf,0xf77e,0xef7d,0x2945,0x0000,0x10a2,0xe71c,0xdebd,0xc5ba,0xef1e,0x94b2,0x0000,0x9cd3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffbf,0xc5ba,0xdebd,0xffff,0x8c71,0x0000,0x2945,0x8430,0x9493,0x6b0e,0x2125,0x0000,0x94b2,0x0020,0x0841,0x526a,0x4209,0x3166,0x0000,0x2104,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffbf,0xc5ba,0xdedd,0xffff,0xffff,0x8430,0x0020,0x0000,0x0000,0x0000,0x0000,0x8410,0xffff,0xb596,0x18e3,0x0000,0x0000,0x0000,0x3186,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xcdfb,0xce1b,0xffff,0xffff,0xffff,0xe71c,0x9cd3,0x630d,0x6b4f,0xa4f6,0xffbf,0xffff,0xffff,0xffff,0xbdd8,0x9474,0xc5f9,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe6fd,0xc5ba,0xce1b,0xe6fd,0xef3e,0xe6fd,0xce1b,0xc5ba,0xe71d,0xc5da,0xc5db,0xd67c,0xde9c,0xd63c,0xc5ba,0xce1b,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe6fd,0xc5da,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xe6dd,0xffff,0xef5e,0xcdfb,0xc5ba,0xc5ba,0xc5ba,0xce3b,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffbf,0xef1e,0xe6dd,0xe71d,0xf79f,0xffff,0xffff,0xffff,0xffff,0xf79f,0xf77e,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x2124,0x2104,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c71,0x0000,0x4a69,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedb,0x6b6d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xf79f,0xffff,0xffff,0x4a69,0x0000,0x738e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x52aa,0x0000,0x9cd3,0xffff,0xffff,0xffff,0xffff,0xce1b,0xce1b,0xffff,0x4208,0x632c,0x2945,0x0000,0x630c,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0x1082,0x0841,0xc618,0xffff,0xffff,0xffff,0xe6fd,0xc5ba,0xd67c,0x2104,0x5aeb,0xe73c,0x2965,0x0000,0x39c7,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xf7bf,0xdebd,0xffff,0xffff,0xc618,0x0861,0x0861,0x94b2,0xffdf,0xffff,0xffff,0xd67c,0xc5ba,0x18e3,0x5aeb,0xffff,0xf79e,0x5aeb,0x0000,0x0861,0x8c71,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xd67c,0xc5ba,0xe71d,0xffff,0xffff,0xc638,0x18e3,0x0000,0x18c3,0x6b6d,0x9494,0xc5fa,0xce1b,0x18c3,0x526a,0xffff,0xffff,0xffff,0xad55,0x10a2,0x0000,0x2124,0xef7d,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffbf,0xc5fb,0xc5db,0xf77e,0xffff,0xffff,0xf79e,0x8410,0x18e3,0x0000,0x0000,0x0000,0x0861,0x0000,0x4209,0xd63c,0xffbf,0xffff,0xffff,0xef7d,0x738e,0x39c7,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf77e,0xc5db,0xc5db,0xe71d,0xffff,0xffff,0xffff,0xffff,0xc618,0x6b0e,0x4209,0x2945,0x0000,0x4a6a,0xc5ba,0xc5db,0xe6fd,0xffff,0xffff,0xffff,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf77e,0x9cb5,0x8c13,0xcdfb,0xdebd,0xef5e,0xffdf,0xffff,0xce1b,0xde9c,0xffff,0x2104,0x5aeb,0xef3e,0xc5fb,0xc5ba,0xce1b,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x528a,0xcdfb,0xc5ba,0xc5ba,0xc5ba,0xc5db,0xc5da,0xde9c,0xffff,0x2104,0x5aeb,0xffff,0xffdf,0xdebd,0xd65c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x5aeb,0xffff,0xf77e,0xe6fd,0xd67c,0xce1b,0xc5ba,0xde9c,0xffff,0x2104,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xf7be,0x9492,0x630c,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xf79e,0xef5e,0xffff,0x2104,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xce1b,0xde9c,0xffff,0x2104,0x5aeb,0xffff,0xffff,0xffff,0xbdf7,0x2124,0x0000,0x0841,0xef7d,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xde9c,0xffff,0x2104,0x528a,0xdefb,0xdefb,0xdefb,0xffdf,0xffff,0xce1b,0xde9c,0xffff,0x2104,0x5aeb,0xffff,0xffff,0x8410,0x0020,0x0020,0x6b4d,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xde9c,0xffff,0x4a49,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x5aeb,0xffdf,0x5acb,0x0000,0x18e3,0xce59,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xde9c,0xffff,0xdefb,0x5aeb,0x4228,0x4228,0x4228,0x4228,0x4228,0x31a7,0x20e4,0x2104,0x2104,0x73ae,0x4a6a,0x0000,0x2946,0xbd79,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xd67c,0xf7bf,0xf7bf,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xce1b,0xde9c,0xffff,0xffff,0x6b4e,0x0000,0x3187,0xd65b,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xd65c,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xde9c,0xffff,0x9473,0x0000,0x2105,0xe73d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xf7bf,0xde9c,0xd65c,0xd65c,0xd65c,0xd65c,0xd65c,0xd65c,0xce1b,0xce1b,0xce1b,0xdebd,0xd67c,0x3166,0x0861,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xce1a,0xbdd7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0xd69a,0xffff,0xffff,0xffff,0xef5e,0xc5ba,0xce3b,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9492,0x0000,0x4228,0xad55,0xffdf,0xd65c,0xc5fb,0xffbf,0xffff,0xffff,0x2104,0x5aeb,0xffff,0xffff,0xce59,0x2945,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedb,0x6b6d,0x2104,0x0000,0x10a2,0x630c,0xad55,0xf79e,0xffff,0xffff,0x2104,0x5aeb,0xffff,0xffff,0xce79,0x0000,0xb5b6,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xdebb,0xdefb,0xdefb,0xdefb,0xdefb,0xb5b6,0x6b6d,0x31a6,0x0000,0x0841,0x39c7,0x6b6d,0x1082,0x528a,0xdefb,0xdefb,0xce59,0x0000,0x9cd3,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe71d,0x18c3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x6b6d,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf7bf,0x9493,0x83d1,0x7bb1,0x7bb1,0x8c32,0x94b3,0xa514,0x8430,0x2945,0x0000,0x18e3,0x9492,0x10a2,0x39c7,0x7bb1,0x94b3,0xa514,0x2945,0x4208,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffbf,0xf7bf,0xf7bf,0xf7bf,0xf7bf,0xef5e,0xdebd,0xbdb9,0x7b90,0x3187,0x0000,0x10a2,0x734f,0xce3b,0xf7bf,0x2104,0x5acb,0xc5ba,0xe71d,0xffff,0x7bcf,0x0841,0xf79e,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0x62ee,0x0000,0x0000,0x20e4,0x7370,0xbd9a,0xc5ba,0xc5ba,0xc5ba,0x18c3,0x4209,0xc5ba,0xdebd,0xffff,0xbdd7,0x3186,0xe73c,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xef5e,0xef3e,0xef3e,0x8411,0x18e4,0xef3e,0xb577,0x526a,0x9c94,0xc5ba,0xce1b,0xe71d,0x8c33,0x9494,0xef3e,0xce3a,0xb5b7,0xb558,0xb578,0xdefb,0xdedb,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0xef1e,0xd65c,0xc5ba,0x0000,0x738e,0xffff,0xffff,0x31a7,0x39c7,0xffff,0xdefb,0x0000,0x0000,0x0000,0x0000,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x736e,0x0000,0xc5ba,0xce1b,0xe71d,0x0000,0x7bef,0xffff,0xffff,0x31a7,0x39c7,0xffff,0xdefb,0x0000,0x62ec,0x83f1,0x9cf3,0x39c7,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe71d,0xce1b,0xffff,0x7baf,0x0000,0xf77e,0xffff,0xffff,0x0000,0x73af,0xef5e,0xffff,0x4208,0x4208,0xf7bf,0xd6bb,0x0000,0x9cd3,0xf7bf,0xffff,0x5aeb,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0x7bef,0x0000,0xc5ba,0xe6dd,0xffff,0x0000,0x6b2e,0xd65c,0xffff,0x4208,0x3187,0xc5ba,0xacf7,0x0000,0x7bb1,0xce1b,0xffff,0x5aeb,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0x7bef,0x0000,0x62cd,0x736e,0x7bef,0x0000,0x3187,0x6b2e,0x7bef,0x2104,0x3187,0xdebc,0xce3a,0x0000,0x83f1,0xce1b,0xffff,0x5aeb,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0x7bef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3187,0xef3e,0xdefb,0x0000,0x8c32,0xce1b,0xffff,0x5aeb,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0x7bef,0x0000,0xc5ba,0xe6dd,0xffff,0x0000,0x6b2e,0xd65c,0xffff,0x4208,0x3187,0xef3e,0xdefb,0x0000,0x8c32,0xce1b,0xffff,0x5aeb,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xe6dd,0x736e,0x0000,0xc5ba,0xd65c,0xe6dd,0x0000,0x630d,0xd65c,0xffff,0x4208,0x3187,0xef3e,0xdefb,0x0000,0x8c32,0xce1b,0xffff,0x5aeb,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xc5ba,0x62cd,0x0000,0xc5ba,0xc5ba,0xc5ba,0x0000,0x62cd,0xd65c,0xffff,0x4208,0x3187,0xef3e,0xdefb,0x0000,0x738f,0xb537,0xdefb,0x528a,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0x7bef,0x0000,0xc5ba,0xe6dd,0xffff,0x0000,0x6b2e,0xd65c,0xffff,0x4208,0x3187,0xef3e,0xdefb,0x0000,0x0000,0x0000,0x0000,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0x7bef,0x0000,0xc5ba,0xe6dd,0xffff,0xc638,0xbd98,0xd65c,0xffff,0x736e,0x5a8c,0xef3e,0xf79e,0xa514,0x8c32,0x83d1,0xa514,0xa514,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0xe71c,0xc638,0xc5ba,0xe6dd,0xffff,0xffff,0xd65c,0xd65c,0xffff,0xf7bf,0xc5ba,0xe6fd,0xf7bf,0xf7bf,0xd67c,0xce1b,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0xffff,0xffff,0xc5ba,0xe6dd,0xffff,0xffff,0xd65c,0xd65c,0xffff,0xf7bf,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xce1b,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0xffff,0xdefb,0xdedb,0xf77e,0xffbf,0xffff,0xffff,0xdebd,0xdebd,0xffff,0xffff,0xef3e,0xef3e,0xef3e,0xef3e,0xef3e,0xef5e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffbf,0xf77e,0xffff,0x5aeb,0x0000,0x39e7,0x8c71,0xbdf7,0xdefb,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9cd3,0x2965,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xf7bf,0xf7bf,0xffff,0xffff,0xffff,0xe73c,0xb5b6,0x9492,0x7bef,0x630c,0x5aeb,0x5aeb,0x5aeb,0x5aeb,0x5aeb,0x5aeb,0x5aeb,0x5aeb,0x528a,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xd65c,0xbdd8,0x9493,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc638,0xad75,0xffff,0xdefb,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe71d,0xce3b,0xc5ba,0x2945,0x1082,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0x4209,0x18c3,0xef3e,0xdefb,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x736e,0x0000,0xb577,0xde9c,0xde9c,0xd67c,0x9473,0x18e3,0xbdd9,0xde9c,0xde9c,0xde9c,0x4a4a,0x18c3,0xef3e,0xdefb,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xf79f,0xef1e,0xffff,0xc618,0x0000,0x8430,0xffff,0xf7be,0x2965,0x528a,0x0000,0xdefb,0xa514,0x73af,0x7bef,0x2965,0x0861,0x738f,0xad75,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xd63c,0xcdfb,0xffff,0xffff,0x18e3,0x39e7,0xffff,0x7bcf,0x0000,0x5aeb,0x0000,0xdefb,0x4a6a,0x0000,0x0000,0x0000,0x0000,0x0000,0x8410,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xdedd,0xc5ba,0xf79e,0xffff,0x73ae,0x0000,0xbdb7,0x0020,0x4a69,0xa514,0x0000,0xdefb,0x4a6a,0x10a3,0xdefb,0x4a69,0x10a3,0xce3a,0xd69a,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xf77e,0xc5ba,0xe6fd,0xffff,0xdefb,0x0000,0x10a2,0x0000,0xce59,0x9493,0x0000,0xc5f9,0x4a2a,0x18c3,0xe6dd,0x52ab,0x18c3,0xef3e,0xdefb,0x0000,0x39c7,0x5aeb,0xdedb,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xcdfb,0xd65c,0xffff,0xe6dd,0x39c8,0x0000,0x3187,0xf7bf,0x8c32,0x0000,0xacf7,0x4209,0x18c3,0xc5ba,0x528a,0x18c3,0xef3e,0xdefb,0x0000,0x0000,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdedd,0xc5ba,0xf79e,0xc5db,0x630d,0x0000,0x62ed,0xf7bf,0x8c32,0x0000,0xd6bb,0x4a4a,0x18c3,0xf7bf,0x5acb,0x18c3,0xef3e,0xdefb,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf7bf,0xc5ba,0xcdfb,0xbd9a,0x1082,0x0000,0x1082,0xef7e,0x8c32,0x0000,0xdefb,0x4a6a,0x18c3,0xffff,0x5acb,0x18c3,0xd65c,0xbdb8,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xd67c,0xc5ba,0x8411,0x0000,0x6b4d,0x0000,0x8410,0x8c32,0x0000,0xdefb,0x4a6a,0x18c3,0xffff,0x5acb,0x18c3,0xc5ba,0xacf7,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe6dd,0xc5ba,0x39a7,0x1082,0xe6fd,0x4a2a,0x0861,0x736e,0x0000,0xdefb,0x4a6a,0x0020,0x4228,0x18c3,0x0020,0x39e8,0x94b2,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xc5fb,0xb558,0x0000,0x5acb,0xef3e,0xb559,0x2104,0x0020,0x0000,0xdefb,0x62ed,0x18c3,0x2104,0x0861,0x0000,0x18e4,0x8c71,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xef3e,0xc5ba,0x9452,0x0000,0x9493,0xef3e,0xc5ba,0xce59,0x0841,0x0000,0xdefb,0xde9c,0xce1b,0xffff,0x5acb,0x18c3,0xef3e,0xdefb,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xd65c,0xc5fb,0x5aeb,0x0000,0xb558,0xe6fd,0xc5ba,0xf7bf,0xa515,0x62ed,0xc5fa,0xcdfb,0xc5db,0xd65c,0x528a,0x18c3,0xef3e,0xdefb,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffdf,0xc5da,0xde9c,0x5aeb,0x2124,0xce1b,0xc5db,0xc5ba,0xf7bf,0xdebd,0xce1b,0xce1b,0xc5db,0xc5da,0xce1b,0x7bcf,0x4209,0xef3e,0xdefb,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xef3e,0xc5ba,0xef3e,0xffff,0xef7d,0xf79f,0xc5db,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xde9c,0xce1b,0xffff,0xf7bf,0xc5ba,0xef3e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xffdf,0xffff,0xffff,0xffff,0xf77e,0xe6dd,0xffdf,0xffff,0xffff,0xffff,0xde9c,0xce1b,0xffff,0xf7bf,0xc5ba,0xef3e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xde9c,0xce1b,0xffff,0xffff,0xffff,0xffff,0xef5d,0x9cd3,0x7bef,0xa534,0xef7d,0xffff,0xe6fd,0xde9c,0xffff,0xf7bf,0xc5ba,0xef3e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffdf,0xffff,0xffff,0xffff,0xad55,0x0861,0x0000,0x0000,0x0000,0x1082,0x9cf3,0xffff,0xffff,0xffff,0xffff,0xffff,0x9492,0x2104,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0x0841,0x1082,0xa534,0xdefb,0xad75,0x2965,0x0000,0x94b2,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x6b4e,0x0000,0xa535,0xffdf,0xffff,0xffff,0xf79e,0x2965,0x0841,0xdefb,0xffff,0xffff,0xffff,0x7bef,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xef3e,0xc5db,0x4209,0x0000,0xbd9a,0xc5fb,0xef1e,0xffff,0xffff,0xd69a,0x0000,0x630c,0xe71d,0xce1b,0xffbf,0x7bef,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf7bf,0xc5db,0xc5fb,0x83f0,0x0000,0x4a6a,0x8c32,0x9474,0xb576,0xc638,0xc638,0x3186,0x0861,0xad56,0x9474,0xbdf8,0x630c,0x0000,0xad55,0xc638,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdedd,0xc5ba,0xef5e,0xf79e,0x4a49,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xffff,0xffff,0xffff,0xd6ba,0xad75,0x9cd3,0x7bb1,0x8c32,0xa514,0x8430,0x0000,0x528a,0x7bb1,0x9cf3,0x528a,0x0000,0x8c71,0xa514,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe6fd,0xc5ba,0xd67c,0xef5e,0xef3d,0xf77e,0xf77e,0xf77e,0xce3b,0xc5db,0xf77e,0xef5e,0x0000,0x5aac,0xc5ba,0xef3e,0x7baf,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xd65c,0xc5ba,0x4a2a,0x20e4,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0x18c3,0x3187,0xc5ba,0xc5ba,0x62cd,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7bf,0x41e8,0x0841,0xef3e,0xef3e,0xef3e,0xe6fd,0xc5ba,0xde9c,0xef3e,0x18e4,0x39a7,0xc5ba,0xe6fd,0x738f,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5acb,0x0000,0xef5d,0xffff,0xffff,0xffff,0xc5ba,0xdebc,0xffff,0x1082,0x4229,0xc5ba,0xf7bf,0x7bef,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xde9c,0xce1b,0xffff,0x8c71,0x0000,0xb596,0xffff,0xffff,0xffff,0xce1b,0xd65c,0xdefb,0x0000,0x630d,0xc5ba,0xf7bf,0xe71c,0xc638,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xd65c,0xc5db,0xffff,0xd69a,0x0000,0x5acb,0xffff,0xffff,0xffff,0xce1b,0xd65c,0x8410,0x0000,0xa515,0xc5ba,0xf7bf,0xffff,0x94b2,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xffdf,0xffff,0x2965,0x0020,0xc618,0xffff,0xffff,0xc5fb,0xad57,0x0861,0x2124,0xdebc,0xc5ba,0xf7bf,0x8c71,0x0000,0x39e7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe6fd,0xc5ba,0xef5e,0xffff,0xce59,0x0020,0x0861,0x73ae,0x9cf3,0x526b,0x0020,0x0861,0xc638,0xffbf,0xf77e,0x7bef,0x0000,0x2124,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf79f,0xc5ba,0xde9c,0xffff,0xffff,0xb5b6,0x2104,0x0000,0x0000,0x0000,0x3186,0xd69a,0xffff,0xffff,0xce5a,0x18a3,0x39e7,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xce3b,0xc5da,0xf77e,0xffff,0xffff,0xffff,0xce39,0x9474,0xb578,0xffff,0xffff,0xffff,0xe6fd,0xc5ba,0xbd98,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xc5da,0xc5db,0xdedd,0xef3e,0xdebc,0xc5db,0xc5db,0xf77e,0xffff,0xffff,0xe6dd,0xc5ba,0xce1b,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5e,0xce1b,0xc5ba,0xc5ba,0xc5ba,0xd63b,0xf79f,0xd6ba,0xffff,0xffdf,0xcdfb,0xd65c,0xffdf,0xef5d,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79f,0xf77e,0xffbf,0xffff,0x9cd3,0x0020,0xad55,0xffff,0xffbf,0xffff,0xffdf,0x39e7,0x4a69,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc618,0x18c3,0x0000,0x8430,0xffff,0xffff,0xffdf,0x52aa,0x0000,0x3186,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x73ae,0x5aeb,0x5aeb,0x5aeb,0x5acb,0x5aeb,0x5aeb,0x4228,0x0000,0x0000,0x4228,0xe71c,0xffff,0xffdf,0x7bef,0x0000,0x1082,0x9cd3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0020,0x7bef,0xef7d,0xffff,0xbdf7,0x2104,0x0000,0x2965,0xd69a,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf77e,0xcdfb,0xc5ba,0xe6fd,0xffff,0xffff,0xffff,0xad57,0x2925,0x0000,0x1082,0xd69a,0xffff,0xf7be,0x8410,0x0841,0xdedb,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xdebd,0xde9c,0xde9c,0xde9c,0xde9c,0xde9c,0xde9c,0xd65c,0xc5ba,0xc5ba,0xd65c,0xffbf,0xffff,0xffff,0xe6dd,0x83d1,0x39a7,0xe6fd,0xffff,0xffff,0xffff,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0x3187,0x7bb1,0xe6dd,0xffdf,0x5aeb,0x2104,0xce1b,0xc5ba,0xa516,0x7bcf,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x0000,0x6b0d,0xc5ba,0xc5fb,0x5acb,0x2104,0xffff,0xe6dd,0x7bb1,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa534,0x4228,0xffdf,0x0000,0x7bef,0xef3e,0xd65c,0x5aeb,0x2104,0xffff,0xffff,0x9cf4,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0x5aeb,0x0000,0x10a3,0xd6ba,0x0000,0x6b4e,0xce1b,0xffff,0x5aeb,0x2104,0xe6dd,0xffdf,0xa514,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4208,0x0000,0x39a8,0xc61a,0xffff,0x0000,0x6b4e,0xce1b,0xffff,0x5aeb,0x18e4,0xc5ba,0xf7bf,0xa514,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef3e,0xb577,0xa514,0xc5ba,0xe6dd,0xffff,0x0000,0x6b4e,0xce1b,0xffff,0x5aeb,0x10a3,0x9474,0xbdf8,0x7bef,0x0000,0xad55,0xc638,0xef7d,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xd67c,0xacf7,0xcdfb,0xf79f,0xc5ba,0xe6dd,0xffff,0x0000,0x6b4e,0xce1b,0xffff,0x5aeb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xd65c,0x20e4,0x4a4a,0xffbf,0xffff,0xc5ba,0xe6dd,0xffff,0x0000,0x6b4e,0xce1b,0xffff,0x5aeb,0x1082,0x7bb1,0x9cf3,0x632c,0x0000,0x8c71,0xa514,0xe73c,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf7bf,0x18e4,0x5aeb,0xffff,0xffff,0xc5ba,0xe6dd,0xffff,0x0000,0x6b4e,0xcdfb,0xf77e,0x5aab,0x18e3,0xc5ba,0xef3e,0x9cb3,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf7bf,0xffff,0x2104,0x4228,0xc638,0xc638,0x9474,0xad56,0xc638,0x0000,0x528b,0x9474,0x9474,0x31a7,0x18c3,0xc5ba,0xc5ba,0x7bb1,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xde9c,0xffff,0x4a69,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x18e3,0xc5ba,0xe6fd,0x9493,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xde9c,0xffff,0xf79e,0xa534,0xa514,0xa514,0x7bb1,0x8c52,0xa514,0x0000,0x4209,0x83d1,0xa514,0x39c7,0x18e4,0xc5ba,0xf7bf,0xa514,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xce1b,0xd65c,0xf77e,0xf77e,0xf77e,0xf77e,0xf77e,0xc5ba,0xde9c,0xf77e,0x0000,0x6b2e,0xce1b,0xffff,0x5aeb,0x18e4,0xc5ba,0xf7bf,0xb5b6,0x4228,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xd67c,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xce1b,0xffff,0xdedb,0xb5b7,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xef3e,0xef3e,0xef3e,0xef3e,0xef3e,0xef3e,0xc5ba,0xd67c,0xef3e,0xef3e,0xd65c,0xce1b,0xffff,0xffff,0xef3e,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc5ba,0xe6dd,0xffff,0xffff,0xde9c,0xce1b,0xffff,0xffff,0xef5e,0xa4d5,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc638,0xad75,0xef5d,0xf79e,0xffff,0xffff,0xffff,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x632c,0x0000,0x0841,0x4a69,0x9cf3,0xe73c,0xffff,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x632c,0x0000,0x18c3,0x1082,0x0000,0x0000,0x3186,0x5aeb,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xbdf7,0x7bef,0xd6bb,0xef5e,0xffff,0xf79e,0x3186,0x0020,0xce79,0xa4f4,0x41e9,0x0841,0x0000,0x0000,0x0861,0x528a,0x9492,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x6b6d,0x0000,0xbdb8,0xc5ba,0xc5db,0xd67c,0xce5a,0x0861,0x4208,0xf77e,0xc5ba,0xe6fd,0x94b2,0x0000,0x18e3,0x0000,0x0000,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4a49,0x0861,0xdebc,0xc5ba,0xcdfb,0xc5fb,0xc5ba,0x62ed,0x0000,0xa4f5,0xc5ba,0xef3e,0xc638,0x0000,0xa514,0xef5d,0xa534,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf77e,0xe6dd,0xffbf,0x2965,0x31a6,0xffff,0xce3b,0xc5da,0xf79e,0xef3e,0xce1a,0x0020,0x4209,0xc5ba,0xc5db,0xa4f5,0x0000,0x9cf4,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdebd,0xc5ba,0xf7bf,0x2104,0x4228,0xffff,0xffbf,0xc5db,0xd65c,0xffff,0xffff,0x4229,0x10a2,0xc5ba,0xcdfb,0x9474,0x0000,0x9cf3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xd65c,0xc5db,0xffff,0x2104,0x4228,0xffff,0xffff,0xe6dd,0xc5ba,0xf77e,0xffff,0x738e,0x0000,0xb558,0xef3e,0xc5f8,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce3b,0xce3b,0xffff,0x4208,0x18e3,0xffff,0xffff,0xffdf,0xc5db,0xde9c,0xffff,0x7bef,0x0000,0xacf7,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xd65c,0xffff,0x632c,0x0000,0xef5d,0xffff,0xffff,0xd65c,0xcdfb,0xffff,0x6b4d,0x0000,0xb559,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xd65c,0xffff,0xad55,0x0000,0x9cd3,0xffff,0xffff,0xdebd,0xc5ba,0xffdf,0x2124,0x2104,0xc5ba,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xd65c,0xcdfb,0xffff,0xf7be,0x10a2,0x2104,0xf79e,0xffff,0xe6dd,0xc5ba,0xa4f4,0x0000,0x6b4d,0xc5ba,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdebc,0xc5ba,0xffdf,0xffff,0x9492,0x0000,0x4228,0xdedb,0xde9c,0x83d1,0x0861,0x10a2,0xdedc,0xc5ba,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xef3e,0xc5ba,0xe71d,0xffff,0xffff,0x5aeb,0x0000,0x0000,0x0000,0x0000,0x1082,0xc618,0xf77e,0xc5ba,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xc5fb,0xce1b,0xffff,0xffff,0xffff,0xbdd7,0x630d,0x4209,0x7bd0,0xef5d,0xffff,0xf77e,0xc5ba,0xef3e,0xe71c,0x7bef,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5ba,0xd65c,0xf7bf,0xffff,0xef3e,0xc5db,0xc5fb,0xffdf,0xffff,0xffff,0xf77e,0xc5ba,0xef3e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5fb,0xf77e,0xffff,0xe71c,0x8430,0xbdd8,0xc5ba,0xef3e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef7e,0xdebd,0xde9c,0xe71d,0xffdf,0xffff,0xe73c,0x18c3,0x0000,0x0020,0xb557,0xf79f,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x6b4d,0x0000,0x73ae,0x0020,0x3186,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffbf,0xc619,0x0020,0x528a,0xffff,0x7bcf,0x0000,0x94b2,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xcdfb,0x41e9,0x0000,0xc639,0xffff,0xf7be,0x2104,0x1082,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdebc,0x9474,0x0000,0x39c8,0xce3b,0xffff,0xffff,0xb596,0x0000,0x52aa,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7bf,0xc5ba,0x2104,0x0020,0xc5f9,0xc5ba,0xe71d,0xffff,0xffff,0x52aa,0x0000,0xad55,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd67c,0x62cd,0x0000,0x6b6d,0xffff,0xce1b,0xc5fb,0xffbf,0xffff,0xe71c,0x1082,0x10a2,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf77e,0x9cb5,0x0000,0x18c3,0xef7d,0xffff,0xef5e,0xc5ba,0xd67c,0xffff,0xffff,0x94b2,0x0000,0x52aa,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc5fa,0x2105,0x0000,0xad55,0xffff,0xffff,0xffff,0xd67c,0xc5ba,0xef3e,0xffff,0xffff,0x39c7,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe6dd,0x524b,0x0000,0x52aa,0xffff,0xffff,0xffff,0xffff,0xffbf,0xc5fb,0xc5fb,0xffdf,0xffff,0xdedb,0x0841,0x0861,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79f,0x7bb1,0x0000,0x18c3,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5ba,0xd67c,0xffff,0xffff,0x9492,0x0000,0x4208,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xce3b,0x5acd,0x0020,0xbdd7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd65c,0xc5ba,0xef3e,0xffff,0xffff,0x5aeb,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xdebc,0xc5ba,0xd67c,0xc618,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7bf,0xc5db,0xc5db,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xef3e,0xc5ba,0xcdfb,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5ba,0xd65c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe6dd,0xc5da,0xef7e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xde9c,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf77e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xce79,0x528a,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x73ae,0x0000,0x0000,0x39e7,0xa534,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xce59,0x5aeb,0x0861,0x0000,0x0861,0x52aa,0xa514,0xe73c,0xffff,0xffff,0xffff,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf79e,0xd67c,0xf79f,0xffff,0xffff,0xffff,0xf79e,0xa534,0x52aa,0x0861,0x0000,0x0000,0x2104,0x39c8,0x7bd0,0x8410,0x0000,0x8c71,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdebd,0xc5ba,0xc5ba,0xd65c,0xef3e,0xffff,0xffff,0xffff,0xffff,0xf7be,0xbdd7,0x7bcf,0x39c7,0x0841,0x0000,0x0000,0x0000,0x0000,0x0000,0x18e3,0xb596,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xde9c,0xc5db,0xc5ba,0xc5db,0xd67c,0xef3e,0xffdf,0xffff,0xffff,0xffff,0xf77e,0xc5ba,0xbdf8,0x8c51,0x0000,0x4208,0x4a69,0x2945,0xb596,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9cd4,0x1082,0x0841,0x528c,0xbd79,0xce1b,0xd67c,0xe6fd,0xe6dd,0xc5ba,0xe6fd,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0x0841,0x0020,0x10a2,0x1082,0xd65b,0xd65c,0xc5db,0x9474,0x62cd,0xb559,0xc5ba,0x9474,0x0000,0x94b3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9492,0x0000,0x9cf3,0xffdf,0xbdf7,0xffff,0xffff,0xffff,0x7bf0,0x0000,0x9454,0xd65c,0xa4f5,0x0000,0x94b3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xef3e,0xc5fb,0x4a29,0x0000,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xad75,0x0000,0x7bb1,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffbf,0xc5db,0xc5da,0x3187,0x10a3,0xffdf,0xffff,0xffff,0xf77e,0xe6dd,0xffdf,0xce79,0x0000,0x62ed,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5ba,0xef1e,0x4228,0x2104,0xffff,0xffff,0xffff,0xe6fd,0xc5ba,0xf77e,0xdefb,0x0000,0x62cd,0xef3e,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xffff,0x4228,0x18e3,0xffff,0xffff,0xffff,0xef5e,0xc5ba,0xef3e,0xdefb,0x0000,0x62cd,0xef3e,0xe71c,0x7bef,0xd69a,0xf7be,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xd65c,0xcdfb,0xffff,0x5acb,0x0000,0xffdf,0xffff,0xffff,0xf79e,0xc5ba,0xe6fd,0xc638,0x0000,0x7370,0xef3e,0xffff,0xe71c,0x630c,0x10a2,0x4a69,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xd65c,0xce1b,0xffff,0x738e,0x0000,0xd69a,0xffff,0xffff,0xf7bf,0xc5ba,0xe6dd,0xad55,0x0000,0x8c12,0xef3e,0xffff,0xf79e,0x1082,0x528a,0xb5b6,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xd65c,0xcdfb,0xffff,0xa534,0x0000,0x94b2,0xffff,0xffff,0xf7bf,0xc5ba,0xe6dd,0x9cf3,0x2104,0xbdd9,0xf79f,0xffff,0xffdf,0xf7be,0xffff,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xffff,0xdedb,0x5aeb,0xbdf7,0xffff,0xffff,0xf77e,0xc5ba,0xe71d,0xffff,0xffff,0xffbf,0xde9c,0xc5fb,0xd67c,0xbdf7,0x4a69,0x0020,0xbdf7,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdebd,0xc5ba,0xf79f,0xffff,0xffff,0xffff,0xffff,0xffff,0xef3e,0xc5ba,0xef5e,0xffff,0xffff,0xffff,0xc5fb,0xd67c,0xef5e,0xa534,0x18e3,0x73ae,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xef3e,0xc5ba,0xe71d,0xffff,0xffff,0xffff,0xffff,0xffff,0xef1e,0xce1b,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffbf,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf7bf,0xde9c,0xf77e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf77e,0xd67c,0xc5da,0xf77e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xa534,0x528a,0x4228,0x738e,0xe71c,0xffff,0xffff,0xffff,0xef3e,0xcdfb,0x0000,0x5acb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x52aa,0x0000,0x0861,0x18c3,0x0000,0x18c3,0xdedb,0xffff,0xffff,0xffff,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9492,0x0000,0x632c,0xf7be,0xffff,0xb5b6,0x0841,0x3186,0xffff,0xffff,0xffff,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71d,0x10a2,0x20e4,0xdebc,0xffbf,0xffff,0xffff,0x73ae,0x0000,0xbdd7,0xc5ba,0xde9c,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd67c,0x9474,0x0000,0x7370,0xc5ba,0xcdfb,0xf7bf,0xffff,0xd6ba,0x0000,0x6b6d,0xc5ba,0xde9c,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5ba,0x7bd0,0x0000,0xd69a,0xef5e,0xc5db,0xce3b,0xffff,0xffff,0x1082,0x4a49,0xc5ba,0xde9c,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xcdfb,0xce1b,0x6b6d,0x0000,0xf79e,0xffff,0xdedd,0xc5ba,0xef7e,0xffff,0x2104,0x4228,0xc5ba,0xde9c,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf77e,0xc5ba,0xe71d,0x5aeb,0x0000,0xffff,0xffff,0xf7bf,0xc5ba,0xdebd,0xffff,0x10a2,0x4a69,0xc5ba,0xde9c,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5ba,0xf79f,0x5aeb,0x0000,0xffff,0xffff,0xffff,0xc5fb,0xd65c,0xe71c,0x0000,0x6b6d,0xc5ba,0xde9c,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdebd,0xc5ba,0xffff,0x6b6d,0x0000,0xe73c,0xffff,0xffff,0xce1b,0xd65c,0x9cd3,0x0000,0xb596,0xc5ba,0xde9c,0xffff,0x0000,0x5aeb,0xdedb,0x9cd3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xffff,0x9492,0x0000,0xbdf7,0xffff,0xffff,0xc5fb,0xd67c,0x2965,0x1082,0xf7be,0xc5ba,0xde9c,0xd69a,0x0000,0x0841,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xde9c,0xc5ba,0xffff,0xbdf7,0x0000,0x8430,0xffff,0xffbf,0xc5ba,0x8c52,0x0000,0x8410,0xf7be,0x7370,0x2945,0x0000,0x0000,0x18c3,0x6b6d,0xb596,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdebd,0xc5ba,0xffdf,0xf7be,0x4228,0x6b4d,0xffff,0xe71d,0xbd79,0x18c3,0x1082,0x6b6d,0x10a2,0x0000,0x0861,0x632d,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5ba,0xf77e,0xffff,0xffff,0xffff,0xffff,0xce3b,0x5aac,0x0000,0x0000,0x0000,0x2124,0x7370,0xbd9a,0xc5ba,0x0000,0x5acb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf77e,0xc5ba,0xe6fd,0xffff,0xffff,0xffff,0xef3e,0xc5ba,0x9cb4,0x0000,0x2945,0x8c33,0xc5ba,0xc5ba,0xcdfb,0xdebd,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xd65c,0xdebc,0xffff,0xffff,0xffff,0xcdfb,0xc5fb,0xdebd,0x9474,0xc5ba,0xc5fb,0xdebc,0xc5ba,0xde9c,0xffff,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedd,0xc5ba,0xc5ba,0xc5ba,0xce1b,0xe71d,0xffff,0xffff,0xc5ba,0xde9c,0xffff,0x7bef,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5e,0xc5ba,0xce3b,0xef5e,0xffff,0xffff,0xffff,0xffff,0xc5ba,0xde9c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf77e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc5ba,0xde9c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedb,0xb596,0x9cf3,0x7bef,0x7bef,0x736e,0x73af,0xa514,0xad55,0xc638,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0x632c,0x18c3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x31a6,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9cd3,0x0020,0x0000,0x18e3,0x632c,0xa514,0xc638,0xdefb,0xdefb,0xdefb,0xd69a,0xc638,0x9cf3,0x738e,0x8c51,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0x0020,0x18c3,0x9cd4,0xe6fd,0xe6dd,0xe6dd,0xe6dd,0xe6dd,0xef3e,0xef3e,0xf77e,0xffbf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7bf,0x8c32,0x0000,0x4a2a,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xce3b,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5da,0xa4d6,0x0000,0x0000,0x4a49,0xb576,0xef7e,0xf7bf,0xf7bf,0xf79f,0xf77e,0xef1e,0xdebd,0xe6fd,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf7bf,0xc5da,0xcdfb,0xef3e,0x94b2,0x1082,0x0000,0x0000,0x2104,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xef3e,0xc5ba,0xde9c,0xffff,0xffff,0xef7d,0x94b2,0x4208,0x7bcf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf79f,0xc5ba,0xc5ba,0xd67c,0xef7e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe71d,0xc5fb,0xc5ba,0xc5ba,0xce1b,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xe71d,0xd65c,0xe6dd,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0x8410,0x18e3,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xad55,0x52aa,0x0841,0x0000,0x0841,0xc618,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0xd69a,0xbdd7,0x94b2,0x6b4d,0x39c7,0x0020,0x0000,0x0000,0x2104,0x8c51,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4208,0x0000,0x0000,0x0000,0x0000,0x0000,0x2945,0x630d,0x9c94,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8410,0x4228,0x630c,0x8430,0xad35,0xc5fa,0xc5db,0xc5ba,0xc5db,0xf77e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffbf,0xf79f,0xef7e,0xe71d,0xdebc,0xd63c,0xc5da,0xc5ba,0xc5ba,0xce1b,0xe6fd,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd65c,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xc5ba,0xce1b,0xdebd,0xf77e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe6dd,0xd65c,0xde9c,0xe6fd,0xef5e,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0x8c51,0x7bef,0x7bef,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe71d,0xe6dd,0xe6dd,0x8c71,0x7bef,0x7bef,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe71d,0xe6dd,0xe6dd,0x2104,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce1b,0xc5ba,0xc5ba,0xf7bf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff};
-diff -Nur linux_c860_org/drivers/video/shepherdLogoMsgJ.c linux/drivers/video/shepherdLogoMsgJ.c
---- linux_c860_org/drivers/video/shepherdLogoMsgJ.c 2003-06-18 17:49:13.000000000 +0900
-+++ linux/drivers/video/shepherdLogoMsgJ.c 2004-06-10 21:09:11.000000000 +0900
-@@ -3,6 +3,7 @@
- * ChangeLog:
- * 16-04-2003 SHARP
- */
-+/* Logo Screen 16bits RGB(565) data*/
- #ifndef __initdata
- #define __initdata
- #endif
-diff -Nur linux_c860_org/drivers/video/tc6393fb.c linux/drivers/video/tc6393fb.c
---- linux_c860_org/drivers/video/tc6393fb.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/video/tc6393fb.c 2004-06-10 21:10:10.000000000 +0900
-@@ -0,0 +1,1255 @@
-+/*
-+ * linux/drivers/video/tc6393fb.c
-+ *
-+ * Frame Buffer Device for TOSHIBA tc6393
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * Based on:
-+ * linux/drivers/video/w100fb.c
-+ *
-+ * Frame Buffer Device for ATI w100 (Wallaby)
-+ *
-+ * Copyright (C) 2002, ATI Corp.
-+ *
-+ * 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.
-+ *
-+ * Based on:
-+ * drivers/video/skeletonfb.c
-+ *
-+ * ChangeLog:
-+ * 28-02-2003 SHARP supported VRAM image cache for ver.1.3
-+ * 19-03-2003 SHARP disabled VRAM image cache for ver.1.3
-+ */
-+
-+// define this here because unistd.h needs it
-+extern int errno;
-+
-+#include <asm/io.h>
-+#include <asm/hardware.h>
-+#include <asm/ucb1200.h>
-+#include <asm/uaccess.h>
-+// unistd.h is included for the configuration ioctl stuff
-+#define __KERNEL_SYSCALLS__ 1
-+#include <asm/unistd.h>
-+#undef __KERNEL_SYSCALLS__
-+#include <linux/ioport.h>
-+#include <linux/delay.h>
-+#include <linux/errno.h>
-+#include <linux/fb.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/slab.h>
-+#include <linux/mm.h>
-+#include <linux/module.h>
-+#include <linux/sched.h>
-+#include <linux/string.h>
-+#include <linux/tty.h>
-+#include <linux/fs.h>
-+#include <linux/file.h>
-+#include <video/fbcon-cfb8.h>
-+#include <video/fbcon-cfb16.h>
-+#include <video/fbcon-mfb.h>
-+#include <video/fbcon.h>
-+
-+#include "tc6393fb.h"
-+#include <linux/pm.h>
-+#include <asm/arch/i2sc.h>
-+#include <asm/arch/tosa.h>
-+
-+#include <video/tosa_backlight.h>
-+
-+#ifdef CONFIG_PM
-+#include <asm/arch/sharpsl_param.h>
-+static struct pm_dev *tc6393_pm_dev;
-+static int tc6393_pm_callback(struct pm_dev* pm_dev,pm_request_t req, void* data);
-+#endif //CONFIG_PM
-+
-+static void tc6393_pm_suspend(int suspend_mode);
-+static void tc6393_pm_resume(void);
-+static void tc6393_clear_screen(u32 mode);
-+
-+// Some hardware related constants
-+// The name the kernel will know us by
-+#define TC6393_NAME "TC6393FB"
-+
-+
-+#define KH_CMDREG_NUM 6
-+
-+#define PIXEL_PER_LINE_QVGA 240
-+#define HORIZONTAL_LINE_QVGA 320
-+#define PIXEL_PER_LINE_VGA 480
-+#define HORIZONTAL_LINE_VGA 640
-+
-+typedef struct FrameBuffer_QVGA {
-+ unsigned short pixel[HORIZONTAL_LINE_QVGA][PIXEL_PER_LINE_QVGA];
-+} FrameBuffer_QVGA;
-+
-+typedef struct FrameBuffer_VGA {
-+ unsigned short pixel[HORIZONTAL_LINE_VGA][PIXEL_PER_LINE_VGA];
-+} FrameBuffer_VGA;
-+
-+static TC6393_REGS kh_cmd[] =
-+{
-+ { KH_BASEADDR_H, 0x0000}, // base address high
-+ { KH_BASEADDR_L, TC6393_GC_INTERNAL_REG_BASE}, // base address low
-+ { KH_COMMAND_REG, 0x0002}, // base address enable
-+ { KH_VRAMTC, 0x40a8}, // VRAMRC, VRAMTC
-+ { KH_VRAMAC, 0x0018}, // VRAMSTS, VRAMAC
-+ { KH_VRAMBC, 0x0002},
-+};
-+
-+#define TC6393_lcdinner (TC6393_SYS_BASE+TC6393_GC_INTERNAL_REG_BASE)
-+
-+#define FB_OFFSET 0x00100000
-+#define TC6393_LCD_INNER_ADDRESS TC6393_lcdinner
-+#define TC6393_FB_BASE TC6393_RAM1_BASE
-+#define REMAPPED_FB_LEN 0x100000
-+
-+#define REMAPPED_LCD_BASE_LEN 0x200
-+#define REMAPPED_CFG_LEN 0x100
-+#define REMAPPED_MMR_LEN 0x200
-+#define TC6393_PHYS_ADR_LEN 0x2000000
-+#define MAX_XRES_QVGA 240
-+#define MAX_YRES_QVGA 320
-+#define MAX_XRES_VGA 480
-+#define MAX_YRES_VGA 640
-+#define BITS_PER_PIXEL 16
-+
-+#define TC6393_SMEM_START (TOSA_LCDC_PHYS+FB_OFFSET)
-+#define TC6393_MMIO_START (TOSA_LCDC_PHYS+0x500)
-+
-+#define COMADJ_DEFAULT 97
-+
-+// Pseudo palette size
-+#define MAX_PALETTES 16
-+
-+#define USE_ACCELERATOR
-+#ifdef USE_ACCELERATOR
-+// for Accelerator
-+#define FIFO_ADDR (((int)remapped_fbuf)+(1024*1024)-(4*512))
-+static void tc6393_acc_init(void);
-+static void tc6393_acc_write( u32* cmd, int cmdnum );
-+static void tc6393_acc_sync(void);
-+#endif
-+
-+// ioctls
-+#define TC6393FB_POWERDOWN 0x54433601 /* TC6\01 */
-+#ifdef USE_ACCELERATOR
-+#define TC6393FB_ACC_CMD_WRITE 0x54433602 /* TC6\02 */
-+#define TC6393FB_ACC_SYNC 0x54433603 /* TC6\03 */
-+#define TC6393FB_ACC_CMD_MAX_LEN 10
-+#endif
-+
-+// General frame buffer data structures
-+struct tc6393fb_info {
-+ struct fb_info_gen gen;
-+ union {
-+#ifdef FBCON_HAS_CFB16
-+ u16 cfb16[ MAX_PALETTES];
-+#endif
-+#ifdef FBCON_HAS_CFB24
-+ u32 cfb24[ MAX_PALETTES];
-+#endif
-+#ifdef FBCON_HAS_CFB32
-+ u32 cfb32[ MAX_PALETTES];
-+#endif
-+ } fbcon_cmap;
-+};
-+
-+struct tc6393fb_par {
-+ u32 xres;
-+ u32 yres;
-+ u32 xres_virtual;
-+ u32 yres_virtual;
-+ u32 bits_per_pixel;
-+ u32 visual;
-+ u32 palette_size;
-+};
-+
-+static struct tc6393fb_info fb_info;
-+static struct tc6393fb_par current_par;
-+static int current_par_valid = 0;
-+static struct display disp;
-+
-+static void *remapped_lcdbase;
-+static void *remapped_regs;
-+static void *remapped_inner;
-+static void *remapped_fbuf;
-+
-+static FrameBuffer_QVGA *fb_QVGA;
-+static FrameBuffer_VGA *fb_VGA;
-+
-+static void *remapped_scoop2_1;
-+static void *remapped_scoop2_2;
-+
-+#define LCD_MODE_QVGA 0
-+#define LCD_MODE_VGA 1
-+
-+// referenced by tosa_fb
-+int tc6393fb_lcdMode = LCD_MODE_VGA;
-+int tc6393fb_isblank = 0;
-+
-+static int tg_ssp_reg0;
-+
-+#if defined(CONFIG_ARCH_SHARP_SL)
-+// checking in mm/omm_kill.c
-+int disable_signal_to_mm = 0;
-+#endif
-+
-+int tc6393fb_init(void);
-+static void tc6393fb_setlcdmode(int);
-+static void tc6393fb_initssp(void);
-+static void tc6393fb_lcdhwsetup(int);
-+static void tc6393_soft_reset(void);
-+
-+static int tc6393_encode_var(struct fb_var_screeninfo *var,
-+ const void *raw_par,
-+ struct fb_info_gen *info);
-+static int tc6393fb_ioctl(struct inode *inode,
-+ struct file *file,
-+ u_int cmd,
-+ u_long arg,
-+ int con,
-+ struct fb_info *info);
-+
-+void pxa_nssp_init(void);
-+
-+int isspace(int x);
-+int config_open(const char *config_filename);
-+int config_close(int config_fd);
-+int config_get_dword(int config_fd,
-+ const char *section,
-+ const char *id,
-+ u32 *val,
-+ u32 defval);
-+long my_strtol(const char *string, char **endPtr, int base);
-+
-+extern void pxa_nssp_output(unsigned char, unsigned char);
-+
-+#define LINE_WAIT 20
-+#define PLCLN_MASK 0x03FF
-+static int wait_vsync(void)
-+{
-+ int ct=0;
-+ volatile u16 val1,val2;
-+
-+ u16 line = (tc6393fb_lcdMode==LCD_MODE_VGA)?HORIZONTAL_LINE_VGA:HORIZONTAL_LINE_QVGA;
-+ do {
-+ val1 = readw(remapped_inner + PLCLN)&PLCLN_MASK;
-+ while(val1!=(val2=(readw(remapped_inner + PLCLN)&PLCLN_MASK))) {
-+ val1 = val2;
-+ }
-+ if (val1==line) break;
-+ if (++ct>1000*1000/LINE_WAIT) break;
-+ udelay(LINE_WAIT);
-+ } while(1);
-+ if (val1!=line) {
-+ printk("unable to wait vsync\n");
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+// save & restore image
-+//#define STATIC_IMAGE_BUF
-+#ifdef STATIC_IMAGE_BUF
-+static u32 ImageBuf[MAX_XRES_VGA*MAX_YRES_VGA/2];
-+static void save_image(void)
-+{
-+ int i,size = current_par.xres*current_par.yres/2;
-+ u32 *src = (u32*)remapped_fbuf;
-+ u32 *dst = ImageBuf;
-+
-+ for (i=0; i<size; i++) {
-+ *dst++ = *src++;
-+ }
-+}
-+static void load_image(void)
-+{
-+ int i,size = current_par.xres*current_par.yres/2;
-+ u32 *src = ImageBuf;
-+ u32 *dst = (u32*)remapped_fbuf;
-+
-+ for (i=0; i<size; i++) {
-+ *dst++ = *src++;
-+ }
-+}
-+#else
-+#define SAVE_LINES 20
-+static u16 *gSaveImagePtr[HORIZONTAL_LINE_VGA/SAVE_LINES] = {NULL};
-+void clear_imagebuf()
-+{
-+ if(gSaveImagePtr[0] != NULL){
-+ int i;
-+ for (i = 0; i < HORIZONTAL_LINE_VGA/SAVE_LINES; i++) {
-+ if (gSaveImagePtr[i] != NULL) {
-+ kfree(gSaveImagePtr[i]);
-+ gSaveImagePtr[i]=NULL;
-+ }
-+ }
-+ }
-+}
-+#endif
-+
-+
-+
-+/* ------------------- chipset specific functions -------------------------- */
-+//
-+// static void tc6393_hw_init(void)
-+//
-+static void tc6393_hw_init(void)
-+{
-+ remapped_regs = (void *)TC6393_SYS_BASE;
-+ remapped_lcdbase = (void *)TC6393_GC_BASE;
-+ remapped_inner = (void *)TC6393_LCD_INNER_ADDRESS;
-+ remapped_scoop2_1 = (void *)CF_BUF_CTRL_BASE;
-+ remapped_scoop2_2 = (void *)CF2_BUF_CTRL_BASE;
-+ remapped_fbuf = (void *)TC6393_FB_BASE;
-+ tc6393_soft_reset();
-+#ifdef USE_ACCELERATOR
-+ tc6393_acc_init();
-+#endif
-+
-+}
-+
-+
-+//
-+// Fill the fix structure based on values in the par
-+//
-+static int tc6393_encode_fix(struct fb_fix_screeninfo *fix,
-+ const void *raw_par,
-+ struct fb_info_gen *info)
-+{
-+ const struct tc6393fb_par *par = raw_par;
-+
-+ if (!par)
-+ BUG();
-+
-+ memset(fix, 0, sizeof *fix);
-+
-+ strcpy(fix->id, TC6393_NAME);
-+
-+ fix->type= FB_TYPE_PACKED_PIXELS;
-+ fix->type_aux = 0;
-+
-+ if (par->bits_per_pixel == 1)
-+ {
-+ fix->visual = FB_VISUAL_MONO10;
-+ }
-+ else if (par->bits_per_pixel <= 8)
-+ {
-+ fix->visual = FB_VISUAL_PSEUDOCOLOR;
-+ }
-+ else
-+ {
-+ fix->visual = FB_VISUAL_TRUECOLOR;
-+ }
-+
-+#if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+ fix->ypanstep = fix->xpanstep = fix->xwrapstep = 0;
-+#else
-+ fix->xpanstep = fix->ypanstep = fix->ywrapstep = 0;
-+#endif
-+ fix->smem_start = TC6393_SMEM_START;
-+
-+ if(tc6393fb_lcdMode == LCD_MODE_VGA ){
-+ fix->line_length = (480 * BITS_PER_PIXEL) / 8;
-+ fix->smem_len = (480 * 640 * BITS_PER_PIXEL) / 8;
-+ } else { // QVGA
-+ fix->line_length = (240 * BITS_PER_PIXEL) / 8;
-+ fix->smem_len = (240 * 320 * BITS_PER_PIXEL) / 8;
-+ }
-+ fix->mmio_start = TC6393_MMIO_START;
-+ fix->mmio_len = REMAPPED_CFG_LEN + REMAPPED_MMR_LEN; // LCD-COMMON+LCD-MMR
-+
-+ fix->accel = FB_ACCEL_NONE;
-+
-+ return 0;
-+}
-+
-+//
-+// Get video parameters out of the par
-+//
-+static int tc6393_decode_var(const struct fb_var_screeninfo *var,
-+ void *raw_par,
-+ struct fb_info_gen *info)
-+{
-+ struct tc6393fb_par *par = raw_par;
-+
-+ *par = current_par;
-+
-+ if (!par)
-+ BUG();
-+
-+ if((par->xres == 480 && par->yres == 640)||
-+ (par->xres == 240 && par->yres == 320)){
-+ par->xres = var->xres;
-+ par->yres = var->yres;
-+ }else{
-+
-+ if(tc6393fb_lcdMode == LCD_MODE_VGA ){
-+ par->xres = MAX_XRES_VGA;
-+ par->yres = MAX_YRES_VGA;
-+ }else{ // QVGA
-+ par->xres = MAX_XRES_QVGA;
-+ par->yres = MAX_YRES_QVGA;
-+ }
-+ }
-+
-+ par->xres_virtual =
-+ var->xres_virtual < par->xres ? par->xres : var->xres_virtual;
-+ par->yres_virtual =
-+ var->yres_virtual < par->yres ? par->yres : var->yres_virtual;
-+
-+ par->bits_per_pixel = var->bits_per_pixel;
-+
-+ par->visual = FB_VISUAL_TRUECOLOR;
-+ par->palette_size = 0;
-+
-+ return 0;
-+}
-+
-+//
-+// Fill the var structure with values in the par
-+//
-+static int tc6393_encode_var(struct fb_var_screeninfo *var,
-+ const void *raw_par,
-+ struct fb_info_gen *info)
-+{
-+ struct tc6393fb_par *par = (struct tc6393fb_par *)raw_par;
-+
-+ // set up var for 565
-+ var->bits_per_pixel = BITS_PER_PIXEL;
-+ var->red.offset = 11;
-+ var->red.length = 5;
-+ var->green.offset = 5;
-+ var->green.length = 6;
-+ var->blue.offset = 0;
-+ var->blue.length = 5;
-+ var->transp.offset = 0;
-+ var->transp.length = 0;
-+
-+ var->red.msb_right = 0;
-+ var->green.msb_right = 0;
-+ var->blue.msb_right = 0;
-+ var->transp.msb_right = 0;
-+
-+ var->nonstd = 0;
-+
-+ var->grayscale = 0;
-+
-+ // set up screen coordinates
-+ if((par->xres == 480 && par->yres == 640)||
-+ (par->xres == 240 && par->yres == 320)){
-+ var->xres = par->xres;
-+ var->yres = par->yres;
-+ }else{
-+ if(tc6393fb_lcdMode == LCD_MODE_VGA ){
-+ var->xres = MAX_XRES_VGA;
-+ var->yres = MAX_YRES_VGA;
-+ }else{ // QVGA
-+ var->xres = MAX_XRES_QVGA;
-+ var->yres = MAX_YRES_QVGA;
-+ }
-+ }
-+
-+ var->xres_virtual = var->xres;
-+ var->yres_virtual = var->yres;
-+ var->xoffset = var->yoffset = 0;
-+
-+ var->activate = FB_ACTIVATE_NOW;
-+
-+ var->height = -1;
-+ var->width = -1;
-+ var->vmode = FB_VMODE_NONINTERLACED;
-+
-+ var->sync = 0;
-+ var->pixclock = 0x04;
-+
-+ return 0;
-+}
-+
-+//
-+// Fill the par structure with relevant hardware values
-+//
-+static void tc6393_get_par(void *raw_par, struct fb_info_gen *info)
-+{
-+ struct tc6393fb_par *par = raw_par;
-+
-+ if (current_par_valid)
-+ *par = current_par;
-+}
-+
-+//
-+// Set the hardware according to the values in the par
-+//
-+static void tc6393_set_par(const void *raw_par, struct fb_info_gen *info)
-+{
-+ const struct tc6393fb_par *par = raw_par;
-+
-+ current_par = *par;
-+ current_par_valid = 1;
-+}
-+
-+//
-+// Split a color register into RGBT components. N/A on TC6393
-+//
-+static int tc6393_getcolreg(unsigned regno, unsigned *red, unsigned *green,
-+ unsigned *blue, unsigned *transp,
-+ struct fb_info *info)
-+{
-+ struct tc6393fb_info *linfo = (struct tc6393fb_info *)info;
-+
-+ if (regno >= 16) return 1;
-+
-+ *transp = 0;
-+ *red = ((linfo->fbcon_cmap.cfb16[regno] >> 11) & 31) << 11;
-+ *green = ((linfo->fbcon_cmap.cfb16[regno] >> 5 ) & 63) << 10;
-+ *blue = ((linfo->fbcon_cmap.cfb16[regno]) & 31) << 11;
-+
-+ return 0;
-+}
-+
-+//
-+// Set a single color register. N/A on TC6393
-+//
-+static int tc6393_setcolreg(unsigned regno, unsigned red, unsigned green,
-+ unsigned blue, unsigned transp,
-+ struct fb_info *info)
-+{
-+ struct tc6393fb_info *linfo = (struct tc6393fb_info *)info;
-+
-+ if (regno < MAX_PALETTES)
-+ {
-+ linfo->fbcon_cmap.cfb16[regno] =
-+ (red & 0xf800) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11);
-+ }
-+
-+ return 0;
-+}
-+
-+//
-+// Pan the display based on var->xoffset & var->yoffset values
-+//
-+static int tc6393_pan_display(const struct fb_var_screeninfo *var,
-+ struct fb_info_gen *info)
-+{
-+
-+ return 0;
-+}
-+
-+//
-+// Blank the display based on value in blank_mode
-+//
-+static int tc6393_blank(int blank_mode, struct fb_info_gen *info)
-+{
-+ if(!in_interrupt()){
-+ if (blank_mode && !tc6393fb_isblank) {
-+ tc6393_pm_suspend(1);
-+ }else if(!blank_mode && tc6393fb_isblank){
-+ tc6393_pm_resume();
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+#ifdef CONFIG_SHARP_LOGO_SCREEN
-+#include "vgaLogoScreen.c"
-+#define SHOW_WAIT_MSG
-+#ifdef SHOW_WAIT_MSG
-+#include "tosaLogoMsgJ.c"
-+#include "tosaLogoMsg.c"
-+#if 0
-+static int logo_lang = 0;
-+#else
-+extern int logo_lang; // Battery Driver refers.
-+#endif
-+static int logo_msg_width __initdata = 0;
-+static int logo_msg_height __initdata = 0;
-+static unsigned short *logo_msg_data __initdata = NULL;
-+#ifndef MODULE
-+static int __init logolang_setup(char *str)
-+{
-+ logo_lang = simple_strtoul(str,NULL,0);
-+ return 0;
-+}
-+__setup("LOGOLANG=", logolang_setup);
-+#endif // MODULE
-+#if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+static int logo_msg_yoff __initdata = 100;
-+#else
-+static int logo_msg_yoff __initdata = 500;
-+#endif
-+#endif // end SHOW_WAIT_MSG
-+
-+//
-+// static void __init draw_img()
-+//
-+static void __init draw_img( int sx, int sy, int w, int h, unsigned short* data )
-+{
-+ int x, y,ppl;
-+ unsigned short *p;
-+ // LCD_MODE_VGA
-+ if (tc6393fb_lcdMode == LCD_MODE_VGA ){
-+ ppl = PIXEL_PER_LINE_VGA;
-+ p = &fb_VGA->pixel[sy][sx];
-+ }else{ // QVGA
-+ ppl = PIXEL_PER_LINE_QVGA;
-+ p = &fb_QVGA->pixel[sy][sx];
-+ }
-+
-+ for (y=0; y<h; y++) {
-+ for (x=0; x<w; x++) {
-+ unsigned short col = data[(h-1-y)+x*h];
-+#if 0 //
-+ if (col==0x7bef) col=0xFFFF;
-+#endif
-+ *p++ = col;
-+ }
-+ p += ppl - w;
-+ }
-+}
-+
-+static void __init draw_logo_screen(void)
-+{
-+ switch(logo_lang) {
-+ case 1: // JP
-+ logo_msg_width = logo_msg_width_jp;
-+ logo_msg_height = logo_msg_height_jp;
-+ logo_msg_data = logo_msg_data_jp;
-+ break;
-+ default: // EN
-+ logo_msg_width = logo_msg_width_en;
-+ logo_msg_height = logo_msg_height_en;
-+ logo_msg_data = logo_msg_data_en;
-+ break;
-+ }
-+
-+ if (tc6393fb_lcdMode == LCD_MODE_VGA){
-+ memset(remapped_fbuf,0xff,(HORIZONTAL_LINE_VGA-16)*(PIXEL_PER_LINE_VGA*2));
-+ }else{ // QVGA
-+ memset(remapped_fbuf,0xff,(HORIZONTAL_LINE_QVGA-16)*(PIXEL_PER_LINE_QVGA*2));
-+ }
-+
-+ draw_img((current_par.xres - logo_screen_height) / 2,
-+ (current_par.yres - logo_screen_width) / 2,
-+ logo_screen_height, logo_screen_width, logo_screen_data);
-+
-+
-+#ifdef SHOW_WAIT_MSG
-+ draw_img((current_par.xres - logo_msg_height) / 2,logo_msg_yoff,
-+ logo_msg_height,logo_msg_width,logo_msg_data);
-+#endif
-+
-+}
-+#endif //CONFIG_SHARP_LOGO_SCREEN
-+
-+
-+//
-+// Set up the display for the fb subsystem
-+//
-+static void tc6393_set_disp(const void *unused, struct display *disp,
-+ struct fb_info_gen *info)
-+{
-+ struct tc6393fb_info *linfo = (struct tc6393fb_info *)info;
-+ int newLcdMode = -1;
-+
-+ if (current_par.xres == PIXEL_PER_LINE_QVGA && current_par.yres == HORIZONTAL_LINE_QVGA){
-+ newLcdMode = LCD_MODE_QVGA;
-+ } else if (current_par.xres == PIXEL_PER_LINE_VGA && current_par.yres == HORIZONTAL_LINE_VGA){
-+ newLcdMode = LCD_MODE_VGA;
-+ } else { // unknown
-+ return;
-+ }
-+
-+ if (newLcdMode!=tc6393fb_lcdMode) {
-+#if 0
-+ printk("change resolution from %s to %s\n", tc6393fb_lcdMode?"VGA":"QVGA", newLcdMode?"VGA":"QVGA");
-+#endif
-+ if (tc6393fb_isblank) {
-+ printk("force resume from blank!!!\n");
-+ clear_imagebuf();
-+ tc6393_pm_resume();
-+ }
-+
-+ wait_vsync();
-+ tc6393_clear_screen(LCD_MODE_VGA);
-+ wait_vsync();
-+ tc6393fb_setlcdmode(newLcdMode);
-+ }
-+
-+ // Do the rest of the display initialization
-+ disp->screen_base = remapped_fbuf;
-+
-+ // Set appropriate low level text console handler
-+ switch(disp->var.bits_per_pixel)
-+ {
-+#ifdef FBCON_HAS_MFB
-+ case 1:
-+ disp->dispsw = &fbcon_mfb;
-+ break;
-+#endif
-+#ifdef FBCON_HAS_CFB8
-+ case 8:
-+ disp->dispsw = &fbcon_cfb8;
-+ break;
-+#endif
-+#ifdef FBCON_HAS_CFB16
-+ case 16:
-+ disp->dispsw = &fbcon_cfb16;
-+ disp->dispsw_data = linfo->fbcon_cmap.cfb16;
-+ break;
-+#endif
-+ default:
-+ disp->dispsw = &fbcon_dummy;
-+ break;
-+ }
-+
-+#if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
-+ disp->xpanstep = 0;
-+ disp->xwrapstep = 0;
-+ disp->scrollmode = 0; // for logoscreen scroll
-+#else
-+ disp->ypanstep = 0;
-+ disp->ywrapstep = 0;
-+#endif
-+
-+
-+}
-+
-+/* ------------ Interfaces to hardware functions ------------ */
-+
-+struct fbgen_hwswitch tc6393_switch =
-+{
-+ //X detect: tc6393_detect,
-+ encode_fix: tc6393_encode_fix,
-+ decode_var: tc6393_decode_var,
-+ encode_var: tc6393_encode_var,
-+ get_par: tc6393_get_par,
-+ set_par: tc6393_set_par,
-+ getcolreg: tc6393_getcolreg,
-+ setcolreg: tc6393_setcolreg,
-+ pan_display: tc6393_pan_display,
-+ blank: tc6393_blank,
-+ set_disp: tc6393_set_disp,
-+};
-+
-+/* ------------ Hardware Independent Functions ------------ */
-+
-+
-+static struct fb_ops tc6393fb_ops =
-+{
-+ owner: THIS_MODULE,
-+ fb_get_fix: fbgen_get_fix,
-+ fb_get_var: fbgen_get_var,
-+ fb_set_var: fbgen_set_var,
-+ fb_get_cmap: fbgen_get_cmap,
-+ fb_set_cmap: fbgen_set_cmap,
-+ fb_pan_display: fbgen_pan_display,
-+ fb_ioctl: tc6393fb_ioctl,
-+};
-+
-+//
-+int __init tc6393fb_init(void)
-+{
-+#ifndef STATIC_IMAGE_BUF
-+ memset(gSaveImagePtr,0,sizeof(gSaveImagePtr));
-+#endif
-+
-+ fb_info.gen.fbhw = &tc6393_switch; // generic frame buffer device
-+ tc6393_hw_init();
-+ tc6393_clear_screen(LCD_MODE_VGA);
-+ tc6393fb_setlcdmode(tc6393fb_lcdMode);
-+
-+ strcpy(fb_info.gen.info.modename, TC6393_NAME);
-+ fb_info.gen.info.changevar = NULL;
-+ fb_info.gen.info.node = -1;
-+ fb_info.gen.info.fbops = &tc6393fb_ops;
-+ fb_info.gen.info.disp = &disp;
-+ fb_info.gen.parsize = sizeof(struct tc6393fb_par);
-+ fb_info.gen.info.switch_con = &fbgen_switch;
-+ fb_info.gen.info.updatevar = &fbgen_update_var;
-+ fb_info.gen.info.blank = &fbgen_blank;
-+ fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;
-+ /* This should give a reasonable default video mode */
-+ fbgen_get_var(&disp.var, -1, &fb_info.gen.info);
-+ fbgen_do_set_var(&disp.var, 1, &fb_info.gen);
-+ fbgen_set_disp(-1, &fb_info.gen);
-+
-+ if (disp.var.bits_per_pixel > 1)
-+ fbgen_install_cmap(0, &fb_info.gen);
-+
-+ if (register_framebuffer(&fb_info.gen.info) < 0)
-+ return -EINVAL;
-+
-+#ifdef CONFIG_PM
-+ tc6393_pm_dev = pm_register(PM_COTULLA_DEV, 0, tc6393_pm_callback);
-+#endif //CONFIG_PM
-+
-+ printk("fb%d: %s frame buffer device\n",
-+ GET_FB_IDX(fb_info.gen.info.node),
-+ fb_info.gen.info.modename);
-+
-+
-+#if defined(CONFIG_SHARP_LOGO_SCREEN)
-+ draw_logo_screen();
-+ tosa_bl_temporary_contrast_set();
-+ tosa_bl_temporary_contrast_reset();
-+#endif
-+
-+ return 0;
-+}
-+
-+void tc6393fb_cleanup(struct fb_info *info)
-+{
-+ unregister_framebuffer(info);
-+#ifndef STATIC_IMAGE_BUF
-+ if(gSaveImagePtr[0] != NULL){
-+ int i;
-+ for (i = 0; i < HORIZONTAL_LINE_VGA/SAVE_LINES; i++) {
-+ if (gSaveImagePtr[i] != NULL) {
-+ kfree(gSaveImagePtr[i]);
-+ gSaveImagePtr[i]=NULL;
-+ }
-+ }
-+ }
-+#endif
-+}
-+
-+#ifdef MODULE
-+int __init init_module(void)
-+{
-+ return tc6393fb_init();
-+}
-+
-+void cleanup_module(void)
-+{
-+ tc6393fb_cleanup(&fb_info.gen.info);
-+}
-+#endif
-+
-+static int tc6393fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-+ u_long arg, int con, struct fb_info *info2)
-+{
-+ switch (cmd){
-+ case TC6393FB_POWERDOWN:
-+ {
-+ int blank_mode = (int)arg;
-+ tc6393_blank(blank_mode,NULL);
-+ }
-+ break;
-+#ifdef USE_ACCELERATOR
-+ case TC6393FB_ACC_CMD_WRITE:
-+ {
-+ u32 cmdbuf[TC6393FB_ACC_CMD_MAX_LEN + 1];
-+
-+ if (tc6393fb_isblank) {
-+ printk("force resume from blank!\n");
-+ clear_imagebuf();
-+ tc6393_pm_resume();
-+ }
-+ if (copy_from_user(cmdbuf, (void *)arg,
-+ (TC6393FB_ACC_CMD_MAX_LEN + 1) * sizeof(u32)))
-+ return -EFAULT;
-+
-+ if (cmdbuf[0] == 0)
-+ return 0;
-+
-+ if (cmdbuf[0] > TC6393FB_ACC_CMD_MAX_LEN)
-+ return -EFAULT;
-+
-+ tc6393_acc_write( &cmdbuf[1], cmdbuf[0] );
-+ }
-+ break;
-+ case TC6393FB_ACC_SYNC:
-+ if (tc6393fb_isblank) {
-+ printk("force resume from blank!!\n");
-+ clear_imagebuf();
-+ tc6393_pm_resume();
-+ }
-+ tc6393_acc_sync();
-+ break;
-+#endif // end USE_ACCELERATOR
-+ default:
-+ return -EINVAL;
-+ }
-+ return 0;
-+}
-+
-+//
-+// Constants
-+//
-+
-+static void tc6393fb_initssp( void)
-+{
-+ pxa_nssp_init();
-+ tg_ssp_reg0 = TG_REG0_COLOR | TG_REG0_UD | TG_REG0_LR;
-+ pxa_nssp_output(1,0x00); //delaied 0clk TCTL signal for VGA
-+ pxa_nssp_output(3,0x02); // GPOS0=powercontrol, GPOS1=GPIO, GPOS2=TCTL
-+}
-+
-+static void tc6393fb_setpnlctl(int dat)
-+{
-+ pxa_nssp_output(6,dat);
-+}
-+
-+static void tc6393fb_lcdhwsetup(int mode)
-+{
-+ int i;
-+
-+ // define the framebuffer base.
-+ fb_VGA = (FrameBuffer_VGA *) (remapped_fbuf);
-+ fb_QVGA = (FrameBuffer_QVGA *) (remapped_fbuf);
-+
-+ if ( mode == LCD_MODE_QVGA ) { // change to QVGA
-+ writew((u16)(0x0000), remapped_inner + PLGMD);
-+ writew((u16)(readw(remapped_regs + TC6393_SYS_FER) & ~FUNC_SLCDEN),
-+ remapped_regs + TC6393_SYS_FER);
-+ writew((u16)(PLCNT_DEFAULT), remapped_inner + PLCNT);
-+ writew((u16)(PLL10_QVGA), remapped_regs + TC6393_SYS_PLL1CR1);
-+ writew((u16)(PLL11_QVGA), remapped_regs + TC6393_SYS_PLL1CR2);
-+ writew((u16)(readw(remapped_regs + TC6393_SYS_FER) | FUNC_SLCDEN),
-+ remapped_regs + TC6393_SYS_FER);
-+
-+ for( i=0; i<kurohyo_LCDCREG_NUM-1; i++){
-+ writew((u16)(kurohyoLcdcQVGA[i].Value), remapped_inner + kurohyoLcdcQVGA[i].Index);
-+ }
-+ } else { // change to VGA
-+ writew((u16)(0x0000), remapped_inner + PLGMD);
-+ writew((u16)(readw(remapped_regs + TC6393_SYS_FER) & ~FUNC_SLCDEN),
-+ remapped_regs + TC6393_SYS_FER);
-+ writew((u16)(PLCNT_DEFAULT), remapped_inner + PLCNT);
-+ writew((u16)(PLL10_VGA), remapped_regs + TC6393_SYS_PLL1CR1);
-+ writew((u16)(PLL11_VGA), remapped_regs + TC6393_SYS_PLL1CR2);
-+ writew((u16)(readw(remapped_regs + TC6393_SYS_FER) | FUNC_SLCDEN),
-+ remapped_regs + TC6393_SYS_FER);
-+
-+ for( i=0; i<kurohyo_LCDCREG_NUM-1; i++){
-+ writew((u16)(kurohyoLcdcVGA[i].Value), remapped_inner + kurohyoLcdcVGA[i].Index);
-+ }
-+ }
-+
-+ writew((u16)(PLCNT_DEFAULT), remapped_inner + PLCNT);
-+ mdelay(5);
-+ writew((u16)(PLCNT_DEFAULT | PLCNT_STOP_CKP), remapped_inner+PLCNT);
-+ mdelay(5);
-+ writew((u16)(PLCNT_DEFAULT | PLCNT_STOP_CKP | PLCNT_SOFT_RESET), remapped_inner + PLCNT);
-+ writew((u16)(0xfffa), remapped_inner + PIFEN);
-+
-+ // TG LCD pannel power up
-+ tc6393fb_setpnlctl(0x4);
-+ mdelay(50);
-+
-+ // TG LCD GVSS
-+ tc6393fb_setpnlctl(0x0);
-+
-+ {
-+ int comadj;
-+ /* Set Common Voltage */
-+ comadj = -1;
-+ comadj = sharpsl_get_comadj();
-+ if ( comadj < 0 ) {
-+ comadj = COMADJ_DEFAULT;
-+ }
-+ mdelay(50);
-+ i2c_init(1);
-+ tosa_set_common_voltage( comadj );
-+ }
-+
-+}
-+
-+static void tc6393fb_setlcdmode(int mode)
-+{
-+ if( mode == LCD_MODE_VGA ){
-+ tg_ssp_reg0 |= TG_REG0_VQV;
-+ pxa_nssp_output(0, tg_ssp_reg0); // data send to TG
-+ tc6393fb_lcdhwsetup(LCD_MODE_VGA);
-+ tc6393fb_lcdMode = LCD_MODE_VGA;
-+ }else{
-+ tg_ssp_reg0 &= ~TG_REG0_VQV;
-+ pxa_nssp_output(0, tg_ssp_reg0); // data send to TG
-+ tc6393fb_lcdhwsetup(LCD_MODE_QVGA);
-+ tc6393fb_lcdMode = LCD_MODE_QVGA;
-+ }
-+}
-+
-+static void tc6393_soft_reset()
-+{
-+ int i;
-+ PSPR=0;// Clear Core Clock Change status
-+
-+ // L3V On
-+ writew((u16)(readw(remapped_scoop2_2 + SCP_GPWR) | SCOOP22_L3VON),remapped_scoop2_2 + SCP_GPWR);
-+
-+ // TG On
-+ writew((u16)(readw(remapped_regs + TC6393_SYS_GPODSR1) & ~0x0001),remapped_regs + TC6393_SYS_GPODSR1);
-+
-+ // Clock Control Register
-+ writew((u16)((readw(remapped_regs + TC6393_SYS_CCR) & CLKCTL_USB_MASK) | CLKCTL_CONFIG_DTA),
-+ remapped_regs + TC6393_SYS_CCR);
-+
-+ writew((u16)(0x0cc1), remapped_regs + TC6393_SYS_PLL2CR);
-+
-+ if ( tc6393fb_lcdMode == LCD_MODE_VGA ) { // VGA
-+ writew((u16)(PLL10_VGA), remapped_regs + TC6393_SYS_PLL1CR1);
-+ writew((u16)(PLL11_VGA), remapped_regs + TC6393_SYS_PLL1CR2);
-+ } else { // QVGA
-+ writew((u16)(PLL10_QVGA), remapped_regs + TC6393_SYS_PLL1CR1);
-+ writew((u16)(PLL11_QVGA), remapped_regs + TC6393_SYS_PLL1CR2);
-+ }
-+ writew((u16)(0x003a), remapped_lcdbase + KH_CLKEN);
-+ writew((u16)(0x003a), remapped_lcdbase + KH_GCLKEN);
-+ writew((u16)(0x3f00), remapped_lcdbase + KH_PSWCLR);
-+ writew((u16)(readw(remapped_regs + TC6393_SYS_FER) | FUNC_SLCDEN), remapped_regs + TC6393_SYS_FER);
-+ mdelay(2);
-+
-+ writew((u16)(0x0000), remapped_lcdbase + KH_PSWCLR);
-+ writew((u16)(0x3300), remapped_regs + TC6393_SYS_GPER);
-+
-+ // initialize kurohyo configration register
-+ for( i=0; i <= KH_CMDREG_NUM; i++){
-+ writew((u16)(kh_cmd[i].Value), remapped_lcdbase + kh_cmd[i].Index);
-+ }
-+ mdelay(2);
-+ writew((u16)(0x000b), remapped_lcdbase + KH_VRAMBC);
-+
-+ tc6393fb_initssp();
-+ tc6393fb_isblank = 0;
-+}
-+
-+#ifdef USE_ACCELERATOR
-+static void tc6393_acc_init()
-+{
-+ writew((u16)((FIFO_ADDR>>16)&0x001f), remapped_inner + KH_CMDADR_H);
-+ writew((u16)(FIFO_ADDR&0x0fff8), remapped_inner + KH_CMDADR_L);
-+ writew(512-1, remapped_inner + KH_CMDFIF);
-+
-+ writew(1, remapped_inner + KH_FIFOR);
-+
-+ writew(0, remapped_inner + KH_BINTMSK);
-+ writew(0, remapped_inner + KH_CMDFINT);
-+}
-+
-+static void tc6393_acc_write( u32* cmd, int cmdnum )
-+{
-+ volatile int i;
-+ int ct=0;
-+
-+ if (readw(remapped_inner + KH_FIPT)>400) {
-+ while(readw(remapped_inner + KH_FIPT)>200) {
-+ mdelay(1);
-+ if (++ct>1000) {
-+ printk(__FUNCTION__ ": timeout\n");
-+ return; // timeout
-+ }
-+ }
-+ }
-+
-+ for ( i = 0; i < cmdnum; i ++ ) {
-+ writew((u16)((cmd[i]>>16) & 0x0ffff), remapped_inner + KH_COMD_H);
-+ writew((u16)(cmd[i] & 0x0ffff), remapped_inner + KH_COMD_L);
-+ }
-+}
-+
-+static void tc6393_acc_sync()
-+{
-+ int ct=0;
-+ while(readw(remapped_inner + KH_FIPT)>0) {
-+ mdelay(1);
-+ if (++ct>1000) {
-+ printk(__FUNCTION__ ": timeout\n");
-+ return; // timeout
-+ }
-+ }
-+ ct=0;
-+ while(readw(remapped_inner + KH_DMAST)&PXAIO_DMAST_BLT) {
-+ mdelay(1);
-+ if (++ct>1000) {
-+ printk(__FUNCTION__ ": timeout\n");
-+ return; // timeout
-+ }
-+ }
-+}
-+#endif // end USE_ACCELERATOR
-+
-+static void tc6393_clear_screen(u32 mode)
-+{
-+#ifndef USE_ACCELERATOR
-+ if(mode == LCD_MODE_VGA){
-+ memset(remapped_fbuf,0xff,MAX_XRES_VGA*MAX_YRES_VGA*2);
-+ }else if(mode == LCD_MODE_QVGA){
-+ memset(remapped_fbuf,0xff,MAX_XRES_QVGA*MAX_YRES_QVGA*2);
-+ }
-+#else // Accelerator always clear VGA area
-+ static u32 cmd[6];
-+ u16 xres = (tc6393fb_lcdMode == LCD_MODE_VGA)?MAX_XRES_VGA:MAX_XRES_QVGA;
-+ u16 yres = (tc6393fb_lcdMode == LCD_MODE_VGA)?MAX_YRES_VGA:MAX_YRES_QVGA;
-+
-+ cmd[0] = PXAIO_COMDI_DSADR|PXAIO_COMDD_DSADR(((int)remapped_fbuf));
-+ cmd[1] = PXAIO_COMDI_DHPIX|PXAIO_COMDD_DHPIX(xres - 1);
-+ cmd[2] = PXAIO_COMDI_DVPIX|PXAIO_COMDD_DVPIX(yres - 1);
-+ cmd[3] = PXAIO_COMDI_FILL|PXAIO_COMDD_FILL(0xffff);
-+ cmd[4] = PXAIO_COMDI_FLGO;
-+
-+ tc6393_acc_write(cmd,5);
-+ tc6393_acc_sync();
-+
-+#endif // end USE_ACCELERATOR
-+}
-+
-+static DECLARE_WAIT_QUEUE_HEAD(blank_queue);
-+
-+static void tc6393_pm_suspend(int suspend_mode)
-+{
-+#ifndef STATIC_IMAGE_BUF
-+ int i,j;
-+ u32 *pVram = (u32*)remapped_fbuf;
-+#endif
-+
-+#ifdef USE_ACCELERATOR
-+ tc6393_acc_sync();
-+#endif
-+
-+ if (!tc6393fb_isblank) {
-+#ifdef STATIC_IMAGE_BUF
-+ save_image();
-+#else
-+ for (i = 0; i < current_par.yres/SAVE_LINES; i++) {
-+ if (gSaveImagePtr[i] != NULL){
-+ kfree(gSaveImagePtr[i]);
-+ gSaveImagePtr[i] = NULL;
-+ }
-+ gSaveImagePtr[i] = kmalloc(current_par.xres * BITS_PER_PIXEL*SAVE_LINES / 8, GFP_KERNEL);
-+ if (gSaveImagePtr[i] != NULL){
-+ memcpy(gSaveImagePtr[i],pVram,current_par.xres*SAVE_LINES*2);
-+ pVram += current_par.xres*SAVE_LINES/2;
-+ }
-+ else {
-+ printk("can't alloc pre-off image buffer %d\n", i);
-+ for (j = 0; j < i; j++) {
-+ if (gSaveImagePtr[i] != NULL) {
-+ kfree(gSaveImagePtr[i]);
-+ gSaveImagePtr[i] = NULL;
-+ }
-+ }
-+ break;
-+ }
-+ }
-+ for (; i < HORIZONTAL_LINE_VGA/SAVE_LINES; i++) {
-+ gSaveImagePtr[i] = NULL;
-+ }
-+#endif
-+
-+#ifdef CONFIG_PM
-+ tosa_bl_pm_callback(NULL, PM_SUSPEND, NULL);
-+#endif
-+
-+ tc6393fb_isblank = 1;
-+
-+ wait_vsync();
-+ tc6393_clear_screen(LCD_MODE_VGA);
-+ wait_vsync();
-+ wait_vsync();
-+
-+ // TG LCD VHSA off
-+ tc6393fb_setpnlctl(0x4);
-+ if (suspend_mode) interruptible_sleep_on_timeout((wait_queue_head_t*)&blank_queue, 50/2 );
-+ else mdelay(50);
-+
-+ // TG LCD signal off
-+ tc6393fb_setpnlctl(0x6);
-+ wait_vsync();
-+ if (suspend_mode) interruptible_sleep_on_timeout((wait_queue_head_t*)&blank_queue, 50/2 );
-+ else mdelay(50);
-+
-+ // TG Off
-+ writew((u16)(readw(remapped_regs + TC6393_SYS_GPODSR1) | 0x0001),remapped_regs + TC6393_SYS_GPODSR1);
-+ if (suspend_mode) interruptible_sleep_on_timeout((wait_queue_head_t*)&blank_queue, 120/2 );
-+ else mdelay(120);
-+
-+ // CLK: Stop
-+ writew((u16)(0x0), remapped_lcdbase + KH_CLKEN);
-+ if (suspend_mode) interruptible_sleep_on_timeout((wait_queue_head_t*)&blank_queue, 100/2 );
-+ else mdelay(100);
-+
-+ // L3V Off
-+ writew((u16)(readw(remapped_scoop2_2 + SCP_GPWR) & ~SCOOP22_L3VON),remapped_scoop2_2 + SCP_GPWR);
-+
-+//X tc6393fb_isblank = 1;
-+ }
-+}
-+
-+static void tc6393_pm_resume()
-+{
-+#ifndef STATIC_IMAGE_BUF
-+ int i;
-+ u32 *pVram = (u32*)remapped_fbuf;
-+#endif
-+
-+ tc6393_hw_init();
-+
-+#ifdef USE_ACCELERATOR
-+ // erase whole VRAM
-+ if (tc6393fb_lcdMode == LCD_MODE_QVGA) {
-+ memset(remapped_fbuf,0xff,MAX_XRES_VGA*MAX_YRES_VGA*2);
-+ }
-+#endif
-+
-+#ifdef STATIC_IMAGE_BUF
-+ load_image();
-+#else
-+ if (gSaveImagePtr[0] != NULL){
-+ for (i = 0; i < (current_par.yres)/SAVE_LINES; i++) {
-+ if (gSaveImagePtr[i] == NULL) {
-+ printk("can't find pre-off image buffer %d\n", i);
-+ continue;
-+ }
-+ memcpy(pVram,gSaveImagePtr[i],current_par.xres*SAVE_LINES*2);
-+ pVram += current_par.xres*SAVE_LINES/2;
-+ kfree(gSaveImagePtr[i]);
-+ gSaveImagePtr[i] = NULL;
-+ }
-+ }
-+#endif
-+
-+ tc6393fb_setlcdmode(tc6393fb_lcdMode);
-+
-+#ifdef CONFIG_PM
-+ tosa_bl_pm_callback(NULL, PM_RESUME, NULL);
-+#endif
-+
-+}
-+
-+#ifdef CONFIG_PM
-+static int tc6393_pm_callback(struct pm_dev* pm_dev,
-+ pm_request_t req, void* data)
-+{
-+ switch (req) {
-+ case PM_SUSPEND:
-+ tc6393_pm_suspend(0);
-+ break;
-+
-+ case PM_RESUME:
-+ tc6393_pm_resume();
-+ break;
-+ }
-+ return 0;
-+}
-+
-+void tc6393_fatal_off(void)
-+{
-+ tc6393_pm_suspend(0);
-+}
-+#endif //CONFIG_PM
-+
-+// EOF
-diff -Nur linux_c860_org/drivers/video/tc6393fb.h linux/drivers/video/tc6393fb.h
---- linux_c860_org/drivers/video/tc6393fb.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/video/tc6393fb.h 2004-06-10 21:09:11.000000000 +0900
-@@ -0,0 +1,249 @@
-+/*
-+ * linux/drivers/video/tc6393fb.h
-+ *
-+ * Frame Buffer Device for TOSHIBA tc6393
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ *
-+ */
-+
-+#if !defined (_TC6393FB)
-+#define _TC6393FB
-+
-+#define KH_COMMAND_REG 0x004
-+#define KH_BASEADDR_H 0x012
-+#define KH_BASEADDR_L 0x010
-+#define KH_CLKEN 0x040
-+#define KH_GCLKEN 0x042
-+#define KH_PSWCLR 0x050
-+#define KH_VRAMTC 0x060
-+#define KH_VRAMRC 0x061
-+#define KH_VRAMAC 0x062
-+#define KH_VRAMBC 0x064
-+#define KH_VMREQMD 0x06F
-+
-+#define KH_CMDADR_L 0x00A
-+#define KH_CMDADR_H 0x00C
-+#define KH_CMDFIF 0x00E
-+#define KH_CMDFINT 0x010
-+#define KH_BINTMSK 0x012
-+#define KH_BINTST 0x014
-+#define KH_FIPT 0x016
-+#define KH_DMAST 0x018
-+#define KH_COMD_L 0x01C
-+#define KH_COMD_H 0x01E
-+#define KH_FIFOR 0x022
-+
-+#define PXAIO_DMAST_DMA 0x0001
-+#define PXAIO_DMAST_BLT 0x0002
-+
-+#define kurohyo_LCDCREG_NUM 18
-+
-+#define PLMOD 0x164
-+#define PLCST 0x102
-+#define VHLIN 0x008
-+#define PLDSA_H 0x124
-+#define PLDSA_L 0x122
-+#define PLPIT_H 0x12c
-+#define PLPIT_L 0x12a
-+#define PLHT 0x140
-+#define PLHDS 0x142
-+#define PLHSS 0x144
-+#define PLHSE 0x146
-+#define PLHBS 0x148
-+#define PLHBE 0x14a
-+#define PLHPX 0x14c
-+#define PLVT 0x150
-+#define PLVDS 0x152
-+#define PLVSS 0x154
-+#define PLVSE 0x156
-+#define PLVBS 0x158
-+#define PLVBE 0x15a
-+#define PLGMD 0x12e
-+#define PLCST 0x102
-+#define PLMOD 0x164
-+#define MISC 0x166
-+#define PLCNT 0x100
-+#define PIFEN 0x18e
-+#define PLCLN 0x160
-+
-+
-+#define CLKCTL_USB_MASK 0x0002
-+#define CLKCTL_CONFIG_DTA 0x1310
-+
-+#define SCOOP_CF_MODE 0x0100
-+#define SCOOP21_OUT_MASK 0x0004
-+#define SCOOP22_OUT_MASK 0x036e
-+
-+#define SCOOP21_RESET_IN 0x0004
-+#define SCOOP22_SUSPEND 0x0020
-+#define SCOOP22_L3VON 0x0040
-+
-+
-+#define PLCNT_SOFT_RESET 0x0001
-+#define PLCNT_STOP_CKP 0x0004
-+#define PLCNT_DEFAULT 0x0010
-+
-+
-+
-+#define FUNC_SLCDEN 0x0004
-+#define PLL10_QVGA 0xf203
-+#define PLL11_QVGA 0x00e7
-+#define PLL10_VGA 0xdf00
-+#define PLL11_VGA 0x002c
-+
-+typedef struct
-+{
-+ unsigned short Index;
-+ unsigned short Value;
-+} TC6393_REGS;
-+
-+static TC6393_REGS kurohyoLcdcQVGA[] =
-+{
-+ { VHLIN, 0x01E0 }, // VHLIN
-+ { PLDSA_H, 0x0000 }, // PLDSA display start address high
-+ { PLDSA_L, 0x0000 }, // PLDSA display start address low
-+ { PLPIT_H, 0x0000 }, // PLPIT horizontal pixel high
-+ { PLPIT_L, 0x01E0 }, // PLPIT horizontal pixel low
-+ { PLHT, 0x0145 }, // PLHT horizontal total
-+ { PLHDS, 0x0026 }, // PLHDS horizontal display start
-+ { PLHSS, 0x0000 }, // PLHSS H-sync start
-+ { PLHSE, 0x0002 }, // PLHSE H-sync end
-+ { PLHPX, 0x00f0 }, // PLHPX Horizontal number of pixel
-+ { PLVT, 0x014F }, // PLVT Vertical total
-+ { PLVDS, 0x0002 }, // PLVDS Vertical display start
-+ { PLVSS, 0x0000 }, // PLVSS V-sync start
-+ { PLVSE, 0x0001 }, // PLVSE V-sync end
-+ { MISC, 0x0003 }, // MISC RGB565 mode
-+ { PLGMD, 0x0001 }, // PLGMD vram access enable
-+ { PLCST, 0x4007 }, // PLCST
-+ { PLMOD, 0x0003 }, // PLMOD Sync polarity
-+};
-+
-+static TC6393_REGS kurohyoLcdcVGA[] =
-+{
-+ { VHLIN, 0x03c0 }, // VHLIN
-+ { PLDSA_H, 0x0000 }, // PLDSA display start address high
-+ { PLDSA_L, 0x0000 }, // PLDSA display start address low
-+ { PLPIT_H, 0x0000 }, // PLPIT horizontal pixel high
-+ { PLPIT_L, 0x03c0 }, // PLPIT horizontal pixel low
-+ { PLHT, 0x0289 }, // PLHT horizontal total
-+ { PLHDS, 0x004e }, // PLHDS horizontal display start
-+ { PLHSS, 0x0000 }, // PLHSS H-sync start
-+ { PLHSE, 0x0002 }, // PLHSE H-sync end
-+ { PLHPX, 0x01e0 }, // PLHPX Horizontal number of pixel
-+ { PLVT, 0x028f }, // PLVT Vertical total
-+ { PLVDS, 0x0002 }, // PLVDS Vertical display start
-+ { PLVSS, 0x0000 }, // PLVSS V-sync start
-+ { PLVSE, 0x0001 }, // PLVSE V-sync end
-+ { MISC, 0x0003 }, // MISC RGB565 mode
-+ { PLGMD, 0x0001 }, // PLGMD vram access enable
-+ { PLCST, 0x4007 }, // PLCST
-+ { PLMOD, 0x0003 }, // PLMOD Sync polarity
-+};
-+
-+#define TG_REG0_VQV 0x0001
-+#define TG_REG0_COLOR 0x0002
-+#define TG_REG0_UD 0x0004
-+#define TG_REG0_LR 0x0008
-+
-+#define CK_SSP (0x1u << 3)
-+
-+/*
-+ * Accelerator COMMAND
-+ */
-+
-+// Set Command
-+#define PXAIO_COMDI_CSADR 0x00000000
-+#define PXAIO_COMDD_CSADR(x) (x&0x001ffffe)
-+#define PXAIO_COMDI_CHPIX 0x01000000
-+#define PXAIO_COMDD_CHPIX(x) (x&0x000003ff)
-+#define PXAIO_COMDI_CVPIX 0x02000000
-+#define PXAIO_COMDD_CVPIX(x) (x&0x000003ff)
-+#define PXAIO_COMDI_PSADR 0x03000000
-+#define PXAIO_COMDD_PSADR(x) (x&0x00fffffe)
-+#define PXAIO_COMDI_PHPIX 0x04000000
-+#define PXAIO_COMDD_PHPIX(x) (x&0x000003ff)
-+#define PXAIO_COMDI_PVPIX 0x05000000
-+#define PXAIO_COMDD_PVPIX(x) (x&0x000003ff)
-+#define PXAIO_COMDI_PHOFS 0x06000000
-+#define PXAIO_COMDD_PHOFS(x) (x&0x000003ff)
-+#define PXAIO_COMDI_PVOFS 0x07000000
-+#define PXAIO_COMDD_PVOFS(x) (x&0x000003ff)
-+#define PXAIO_COMDI_POADR 0x08000000
-+#define PXAIO_COMDD_POADR(x) (x&0x00fffffe)
-+#define PXAIO_COMDI_RSTR 0x09000000
-+#define PXAIO_COMDD_RSTR(x) (x&0x000000ff)
-+#define PXAIO_COMDI_TCLOR 0x0A000000
-+#define PXAIO_COMDD_TCLOR(x) (x&0x0000ffff)
-+#define PXAIO_COMDI_FILL 0x0B000000
-+#define PXAIO_COMDD_FILL(x) (x&0x0000ffff)
-+#define PXAIO_COMDI_DSADR 0x0C000000
-+#define PXAIO_COMDD_DSADR(x) (x&0x00fffffe)
-+#define PXAIO_COMDI_SSADR 0x0D000000
-+#define PXAIO_COMDD_SSADR(x) (x&0x00fffffe)
-+#define PXAIO_COMDI_DHPIX 0x0E000000
-+#define PXAIO_COMDD_DHPIX(x) (x&0x000003ff)
-+#define PXAIO_COMDI_DVPIX 0x0F000000
-+#define PXAIO_COMDD_DVPIX(x) (x&0x000003ff)
-+#define PXAIO_COMDI_SHPIX 0x10000000
-+#define PXAIO_COMDD_SHPIX(x) (x&0x000003ff)
-+#define PXAIO_COMDI_SVPIX 0x11000000
-+#define PXAIO_COMDD_SVPIX(x) (x&0x000003ff)
-+#define PXAIO_COMDI_LBINI 0x12000000
-+#define PXAIO_COMDD_LBINI(x) (x&0x0000ffff)
-+#define PXAIO_COMDI_LBK2 0x13000000
-+#define PXAIO_COMDD_LBK2(x) (x&0x0000ffff)
-+#define PXAIO_COMDI_SHBINI 0x14000000
-+#define PXAIO_COMDD_SHBINI(x) (x&0x0000ffff)
-+#define PXAIO_COMDI_SHBK2 0x15000000
-+#define PXAIO_COMDD_SHBK2(x) (x&0x0000ffff)
-+#define PXAIO_COMDI_SVBINI 0x16000000
-+#define PXAIO_COMDD_SVBINI(x) (x&0x0000ffff)
-+#define PXAIO_COMDI_SVBK2 0x17000000
-+#define PXAIO_COMDD_SVBK2(x) (x&0x0000ffff)
-+
-+// Action Command
-+#define PXAIO_COMDI_CMGO 0x20000000
-+#define PXAIO_COMDD_CMGO_CEND 0x00000001
-+#define PXAIO_COMDD_CMGO_INT 0x00000002
-+#define PXAIO_COMDD_CMGO_CMOD 0x00000010
-+#define PXAIO_COMDD_CMGO_CDVRV 0x00000020
-+#define PXAIO_COMDD_CMGO_CDHRV 0x00000040
-+#define PXAIO_COMDD_CMGO_RUND 0x00008000
-+#define PXAIO_COMDI_SCGO 0x21000000
-+#define PXAIO_COMDD_SCGO_CEND 0x00000001
-+#define PXAIO_COMDD_SCGO_INT 0x00000002
-+#define PXAIO_COMDD_SCGO_ROP3 0x00000004
-+#define PXAIO_COMDD_SCGO_TRNS 0x00000008
-+#define PXAIO_COMDD_SCGO_DVRV 0x00000010
-+#define PXAIO_COMDD_SCGO_DHRV 0x00000020
-+#define PXAIO_COMDD_SCGO_SVRV 0x00000040
-+#define PXAIO_COMDD_SCGO_SHRV 0x00000080
-+// Specifications Document Rev.18 Add
-+#define PXAIO_COMDD_SCGO_DSTXY 0x00008000
-+#define PXAIO_COMDI_SBGO 0x22000000
-+#define PXAIO_COMDD_SBGO_CEND 0x00000001
-+#define PXAIO_COMDD_SBGO_INT 0x00000002
-+#define PXAIO_COMDD_SBGO_DVRV 0x00000010
-+#define PXAIO_COMDD_SBGO_DHRV 0x00000020
-+#define PXAIO_COMDD_SBGO_SVRV 0x00000040
-+#define PXAIO_COMDD_SBGO_SHRV 0x00000080
-+#define PXAIO_COMDD_SBGO_SBMD 0x00000100
-+#define PXAIO_COMDI_FLGO 0x23000000
-+#define PXAIO_COMDD_FLGO_CEND 0x00000001
-+#define PXAIO_COMDD_FLGO_INT 0x00000002
-+#define PXAIO_COMDD_FLGO_ROP3 0x00000004
-+#define PXAIO_COMDI_LDGO 0x24000000
-+#define PXAIO_COMDD_LDGO_CEND 0x00000001
-+#define PXAIO_COMDD_LDGO_INT 0x00000002
-+#define PXAIO_COMDD_LDGO_ROP3 0x00000004
-+#define PXAIO_COMDD_LDGO_ENDPX 0x00000008
-+#define PXAIO_COMDD_LDGO_LVRV 0x00000010
-+#define PXAIO_COMDD_LDGO_LHRV 0x00000020
-+#define PXAIO_COMDD_LDGO_LDMOD 0x00000040
-+
-+#endif
-diff -Nur linux_c860_org/drivers/video/tosaLogoMsg.c linux/drivers/video/tosaLogoMsg.c
---- linux_c860_org/drivers/video/tosaLogoMsg.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/video/tosaLogoMsg.c 2004-06-10 21:09:11.000000000 +0900
-@@ -0,0 +1,488 @@
-+/* Logo Screen 16bits RGB(565) data*/
-+#ifndef __initdata
-+#define __initdata
-+#endif
-+static const int logo_msg_width_en __initdata = 32;
-+static const int logo_msg_height_en __initdata = 480;
-+static const unsigned short logo_msg_data_en[32*480] __initdata ={
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xbdf7,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd69a,0xa514,0xa514,0xa514,0xa514,0xa514,0xa514,0x528a,0x0000,0x528a,0xa514,0xa514,0xa514,0xa514,0xa514,0x632c,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x7bcf,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x4a69,0xffff,0xffff,0xffff,0xffff,0xffff,0x8430,0x0000,0x73ae,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0x0020,0x0020,0xbdd7,0xffff,0xffff,0xffff,0xdedb,0x18e3,0x0000,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x738e,0x0000,0x0000,0x39e7,0x5aeb,0x4a49,0x0841,0x0000,0x4208,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x94b2,0x18e3,0x0000,0x0000,0x0000,0x0841,0x632c,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd6ba,0xc638,0xce79,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xbdf7,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xb596,0x8c71,0x7bef,0x8430,0xad55,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7be,0x738e,0x0841,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4208,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x4228,0x0000,0x18c3,0x7bcf,0xad75,0x31a6,0x10a2,0x9492,0x4a69,0x0000,0x0861,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa534,0x0000,0x39c7,0xef7d,0xffff,0xffff,0x4228,0x2104,0xffff,0xffff,0xad55,0x0020,0x2945,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x528a,0x0000,0xd69a,0xffff,0xffff,0xffff,0x4228,0x2104,0xffff,0xffff,0xffff,0x5acb,0x0000,0xd6ba,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0xffff,0xffff,0xffff,0xffff,0x4228,0x2104,0xffff,0xffff,0xffff,0x7bef,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5acb,0x0000,0xc618,0xffff,0xffff,0xffff,0x4228,0x2104,0xffff,0xffff,0xffff,0x39e7,0x0000,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xb596,0x0000,0x2124,0xce79,0xffff,0xffff,0x4228,0x2104,0xffff,0xffdf,0x7bef,0x0000,0x52aa,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x738e,0x0000,0x0000,0x9cf3,0xffff,0x4228,0x0861,0x4a69,0x10a2,0x0000,0x2965,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x39e7,0xad75,0xffff,0x4228,0x0000,0x0000,0x31a6,0x9492,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0xdefb,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xb596,0x7bef,0x9492,0xdefb,0xffff,0xffff,0xffff,0xe71c,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x39e7,0x0000,0x0000,0x0000,0x0020,0x9cf3,0xffff,0xffff,0x4228,0x10a2,0x8c71,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c51,0x0000,0x39c7,0xb5b6,0xa514,0x10a2,0x0841,0xe71c,0xffff,0x73ae,0x1082,0x0000,0x8430,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4a49,0x0000,0xdedb,0xffff,0xffff,0x94b2,0x0000,0x94b2,0xffff,0xffff,0xe73c,0x18c3,0x1082,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4a49,0x0000,0xffff,0xffff,0xffff,0xd69a,0x0000,0x630c,0xffff,0xffff,0xffff,0x6b6d,0x0000,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c51,0x0000,0xd6ba,0xffff,0xffff,0xffdf,0x0841,0x39c7,0xffff,0xffff,0xffff,0x7bef,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x2104,0x4a69,0xffdf,0xffff,0xffff,0x4228,0x0020,0xf79e,0xffff,0xffff,0x4a49,0x0000,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xb5b6,0x0020,0x39c7,0x9cf3,0xc638,0x738e,0x0000,0x8430,0xbdf7,0x6b4d,0x0000,0x18c3,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9492,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0020,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c71,0x528a,0x738e,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0xa514,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x8410,0x2945,0xad75,0xffff,0xffff,0xef5d,0x73ae,0x4228,0x52aa,0xb596,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x2124,0x0000,0x0861,0xa534,0xffff,0xef7d,0x2104,0x0000,0x0000,0x0000,0x0000,0x94b2,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c51,0x0000,0x528a,0xef7d,0xffff,0xffff,0x8430,0x0000,0x2945,0xef5d,0xdefb,0x10a2,0x1082,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4a69,0x0000,0xe71c,0xffff,0xffff,0xffff,0x2124,0x0000,0xa534,0xffff,0xffff,0x6b6d,0x0000,0xce59,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0xffff,0xffff,0xffff,0xd69a,0x0000,0x0841,0xf79e,0xffff,0xffff,0x7bcf,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x632c,0x0000,0xbdf7,0xffff,0xffff,0x73ae,0x0000,0x528a,0xffff,0xffff,0xf79e,0x2945,0x0020,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xce79,0x0020,0x18c3,0x8c71,0x8c51,0x0861,0x0000,0xad75,0xffff,0xad75,0x18c3,0x0000,0x5acb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9cd3,0x0841,0x0000,0x0000,0x0000,0x5acb,0xffff,0xffff,0xad55,0x0861,0x632c,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0xb596,0xa514,0xd6ba,0xffff,0xffff,0xffff,0xf7be,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0x7bef,0x31a6,0x0861,0x0000,0x0020,0x2945,0x5acb,0xbdf7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xad75,0x0861,0x0000,0x0020,0x2965,0x1082,0x0020,0x1082,0x0000,0x0000,0x5aeb,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0x0861,0x0020,0x8c51,0xf79e,0xffff,0x4228,0x2104,0xffff,0xce79,0x39c7,0x0000,0x6b6d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x738e,0x0000,0x9492,0xffff,0xffff,0xffff,0x4228,0x2104,0xffff,0xffff,0xf79e,0x2124,0x0841,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0xf79e,0xffff,0xffff,0xffff,0x4228,0x2104,0xffff,0xffff,0xffff,0x73ae,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4a49,0x0000,0xef7d,0xffff,0xffff,0xffff,0x4228,0x2104,0xffff,0xffff,0xffff,0x6b4d,0x0000,0xce79,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x7bcf,0xffff,0xffff,0xffff,0x4228,0x2104,0xffff,0xffff,0xe71c,0x1082,0x18c3,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0x18c3,0x0000,0x4a69,0xd6ba,0xffff,0x4228,0x18e3,0xce79,0x9492,0x18c3,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedb,0x2124,0x0000,0x9cd3,0xffff,0x4228,0x0000,0x0000,0x0000,0x18c3,0xa534,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xbdd7,0xdefb,0xffff,0x8c51,0x5aeb,0x73ae,0xb596,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0xa514,0x5aeb,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0xa514,0x5aeb,0x2104,0x0000,0x0000,0x0000,0x10a2,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0xa514,0x5aeb,0x2104,0x0000,0x0000,0x0000,0x2965,0x632c,0xa514,0xd6ba,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c51,0x0000,0x0000,0x0861,0x4208,0x7bcf,0xb5b6,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x2124,0x528a,0x8c71,0xc618,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7be,0xc618,0x9492,0x52aa,0x2124,0x0000,0x0000,0x0020,0x31a6,0x632c,0xa514,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0xb5b6,0x7bef,0x4a69,0x1082,0x0000,0x0000,0x1082,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xce79,0x9492,0x5acb,0x31a6,0x0020,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0xb596,0x7bcf,0x4208,0x0861,0x0000,0x0000,0x1082,0x4228,0x7bef,0xb596,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c71,0x0000,0x0000,0x0000,0x31a6,0x632c,0xa514,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x18c3,0x528a,0x9492,0xd69a,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef7d,0xb596,0x6b6d,0x39c7,0x0020,0x0000,0x0000,0x0861,0x4228,0x8410,0xbdd7,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xb5b6,0x7bcf,0x39c7,0x0020,0x0000,0x0000,0x0020,0x39c7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xb5b6,0x8410,0x4208,0x0841,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xb596,0x31a6,0x0000,0x1082,0x630c,0xef7d,0xffff,0xffff,0x8430,0x9492,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc638,0x0020,0x0000,0x39c7,0x2124,0x0000,0x31a6,0xffdf,0xffff,0x31a6,0x0000,0x18e3,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0x9cd3,0xffff,0xffdf,0x52aa,0x0000,0xbdd7,0xffff,0xe73c,0x73ae,0x0000,0x39e7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0xf7be,0xffff,0xffff,0xb5b6,0x0000,0x738e,0xffff,0xffff,0xffff,0x4a49,0x0000,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0xf79e,0xffff,0xffff,0xef5d,0x0000,0x528a,0xffff,0xffff,0xffff,0x7bef,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc638,0x0000,0xa514,0xffff,0xffff,0xffff,0x2104,0x18c3,0xffff,0xffff,0xffff,0x6b6d,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0861,0xb5b6,0xffff,0xffff,0x6b6d,0x0000,0xd69a,0xffff,0xe71c,0x18c3,0x0000,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd69a,0x5aeb,0x0020,0x0000,0x18e3,0x4228,0x2965,0x0000,0x2124,0x4208,0x0841,0x0000,0x52aa,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2104,0x630c,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xce59,0xd69a,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xbdf7,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0xffff,0xffff,0xa514,0x7bef,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0x4228,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xffff,0xffff,0xd69a,0xc638,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xad75,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xd69a,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0x4a49,0x0000,0xc638,0xc638,0xc638,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc638,0x1082,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x738e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x52aa,0x0000,0x4208,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x2965,0x0000,0x7bef,0x7bef,0x7bef,0x7bef,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xad75,0xad55,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedb,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xad75,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x10a2,0x5aeb,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x18c3,0x0000,0x4228,0x4228,0x0861,0x0000,0x630c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0xffff,0xffff,0xdefb,0x0000,0x2124,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9cd3,0x5aeb,0xffff,0xffff,0xffff,0x0000,0x31a6,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xb5b6,0x9492,0x7bef,0x7bef,0xa534,0xd6ba,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd69a,0xce59,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x73ae,0x0841,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2965,0xc618,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4a69,0x0000,0x18c3,0x7bcf,0xad75,0xc638,0xbdf7,0x94b2,0x4a69,0x0000,0x0020,0xbdd7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa534,0x0000,0x39e7,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xad55,0x0020,0x2124,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x528a,0x0000,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5acb,0x0000,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bcf,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x6b4d,0x0000,0xad55,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x2965,0x0000,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd69a,0x0020,0x0861,0xad55,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0x528a,0x0000,0x5acb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x94b2,0x0020,0x0000,0x18c3,0x4a69,0x5aeb,0x5acb,0x39c7,0x0020,0x0000,0x39c7,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd69a,0x5acb,0x10a2,0x0000,0x0000,0x0000,0x0000,0x31a6,0x9492,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef7d,0xdefb,0xdefb,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x2124,0x0000,0x0000,0x2965,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x73ae,0x0000,0x5acb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x10a2,0x0000,0xce79,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef7d,0x0841,0x0000,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xbdd7,0x8c51,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xb596,0x7bef,0x9492,0xdefb,0xffff,0xffff,0xffff,0xe71c,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x39e7,0x0000,0x0000,0x0000,0x0020,0x9cf3,0xffff,0xffff,0x4228,0x10a2,0x8c71,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c51,0x0000,0x39c7,0xb5b6,0xa514,0x10a2,0x0841,0xe71c,0xffff,0x73ae,0x1082,0x0000,0x8430,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4a49,0x0000,0xdedb,0xffff,0xffff,0x94b2,0x0000,0x94b2,0xffff,0xffff,0xe73c,0x18c3,0x1082,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4a49,0x0000,0xffff,0xffff,0xffff,0xd69a,0x0000,0x630c,0xffff,0xffff,0xffff,0x6b6d,0x0000,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c51,0x0000,0xd6ba,0xffff,0xffff,0xffdf,0x0841,0x39c7,0xffff,0xffff,0xffff,0x7bef,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x2104,0x4a69,0xffdf,0xffff,0xffff,0x4228,0x0020,0xf79e,0xffff,0xffff,0x4a49,0x0000,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xb5b6,0x0020,0x39c7,0x9cf3,0xc638,0x738e,0x0000,0x8430,0xbdf7,0x6b4d,0x0000,0x18c3,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9492,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0020,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c71,0x528a,0x738e,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0xa514,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xad75,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x10a2,0x5aeb,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x18c3,0x0000,0x4228,0x4228,0x0861,0x0000,0x630c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0xffff,0xffff,0xdefb,0x0000,0x2124,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9cd3,0x5aeb,0xffff,0xffff,0xffff,0x0000,0x31a6,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xb596,0x8c71,0x7bef,0x8430,0xad55,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd69a,0xce59,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7be,0x738e,0x0841,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x4208,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x4228,0x0000,0x18c3,0x7bcf,0xad75,0x31a6,0x10a2,0x9492,0x4a69,0x0000,0x0861,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa534,0x0000,0x39c7,0xef7d,0xffff,0xffff,0x4228,0x2104,0xffff,0xffff,0xad55,0x0020,0x2945,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x528a,0x0000,0xd69a,0xffff,0xffff,0xffff,0x4228,0x2104,0xffff,0xffff,0xffff,0x5acb,0x0000,0xd6ba,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0xffff,0xffff,0xffff,0xffff,0x4228,0x2104,0xffff,0xffff,0xffff,0x7bef,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5acb,0x0000,0xc618,0xffff,0xffff,0xffff,0x4228,0x2104,0xffff,0xffff,0xffff,0x39e7,0x0000,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xb596,0x0000,0x2124,0xce79,0xffff,0xffff,0x4228,0x2104,0xffff,0xffdf,0x7bef,0x0000,0x52aa,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x738e,0x0000,0x0000,0x9cf3,0xffff,0x4228,0x0861,0x4a69,0x10a2,0x0000,0x2965,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x39e7,0xad75,0xffff,0x4228,0x0000,0x0000,0x31a6,0x9492,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0xdefb,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0xa514,0x5aeb,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0xa514,0x5aeb,0x2104,0x0000,0x0000,0x0000,0x10a2,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0xa514,0x5aeb,0x2104,0x0000,0x0000,0x0000,0x2965,0x632c,0xa514,0xd6ba,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c51,0x0000,0x0000,0x0861,0x4208,0x7bcf,0xb5b6,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x2124,0x528a,0x8c71,0xc618,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7be,0xc618,0x9492,0x52aa,0x2124,0x0000,0x0000,0x0020,0x31a6,0x632c,0xa514,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0xb5b6,0x7bef,0x4a69,0x1082,0x0000,0x0000,0x1082,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xce79,0x9492,0x5acb,0x31a6,0x0020,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0xb596,0x7bcf,0x4208,0x0861,0x0000,0x0000,0x1082,0x4228,0x7bef,0xb596,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c71,0x0000,0x0000,0x0000,0x31a6,0x632c,0xa514,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x18c3,0x528a,0x9492,0xd69a,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef7d,0xb596,0x6b6d,0x39c7,0x0020,0x0000,0x0000,0x0861,0x4228,0x8410,0xbdd7,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xb5b6,0x7bcf,0x39c7,0x0020,0x0000,0x0000,0x0020,0x39c7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xb5b6,0x8410,0x4208,0x0841,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xbdf7,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xad55,0x7bcf,0x18c3,0x3186,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0x1082,0x4228,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x52aa,0x0000,0xd6ba,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x2965,0x0000,0xce59,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xbdf7,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x738e,0x2945,0x0000,0x18e3,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x3186,0xce79,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xbdd7,0x8430,0x18e3,0x4a49,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0x1082,0x39e7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5acb,0x0000,0xd6ba,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x2945,0x0000,0xce59,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xbdf7,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x738e,0x2965,0x0000,0x18c3,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2945,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0x4228,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0xffff,0xffff,0x73ae,0x4228,0x8c51,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xbdf7,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xb596,0x7bef,0x10a2,0x31a6,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0x1082,0x4a49,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x52aa,0x0000,0xd6ba,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4208,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef7d,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xce59,0x632c,0x0000,0x0861,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0020,0x94b2,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xad75,0x5aeb,0x5aeb,0x5aeb,0x5aeb,0x5aeb,0x5aeb,0x5aeb,0x5aeb,0x632c,0x8c71,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd6ba,0x9cf3,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x5aeb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9cd3,0x0000,0x0861,0x8430,0xb5b6,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4a49,0x0000,0xa534,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4a69,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x9cf3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x630c,0x0861,0xa514,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x4228,0x0861,0x0000,0x0000,0x18e3,0x2104,0x2104,0x2104,0x2104,0x2104,0x2104,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x8430,0x528a,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x18c3,0x0000,0x4228,0x4228,0x4228,0xce79,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8410,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2104,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0xad55,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x528a,0x2945,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c51,0x4228,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0x7bef,0x31a6,0x0861,0x0000,0x0020,0x2945,0x5acb,0xbdf7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xad75,0x0861,0x0000,0x0020,0x2965,0x1082,0x0020,0x1082,0x0000,0x0000,0x5aeb,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0x0861,0x0020,0x8c51,0xf79e,0xffff,0x4228,0x2104,0xffff,0xce79,0x39c7,0x0000,0x6b6d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x738e,0x0000,0x9492,0xffff,0xffff,0xffff,0x4228,0x2104,0xffff,0xffff,0xf79e,0x2124,0x0841,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0xf79e,0xffff,0xffff,0xffff,0x4228,0x2104,0xffff,0xffff,0xffff,0x73ae,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4a49,0x0000,0xef7d,0xffff,0xffff,0xffff,0x4228,0x2104,0xffff,0xffff,0xffff,0x6b4d,0x0000,0xce79,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x7bcf,0xffff,0xffff,0xffff,0x4228,0x2104,0xffff,0xffff,0xe71c,0x1082,0x18c3,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0x18c3,0x0000,0x4a69,0xd6ba,0xffff,0x4228,0x18e3,0xce79,0x9492,0x18c3,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedb,0x2124,0x0000,0x9cd3,0xffff,0x4228,0x0000,0x0000,0x0000,0x18c3,0xa534,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xbdd7,0xdefb,0xffff,0x8c51,0x5aeb,0x73ae,0xb596,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef7d,0xad55,0xdefb,0xffff,0xffff,0xffff,0xef7d,0xc638,0xd6ba,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9cd3,0x1082,0x0000,0x9cd3,0xffff,0xffff,0x8c71,0x0841,0x0000,0x0000,0x3186,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc638,0x0000,0x0861,0x7bcf,0xdefb,0xffff,0xbdf7,0x0000,0x0020,0x6b4d,0x5aeb,0x0000,0x4208,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x630c,0x0000,0xad55,0xffff,0xffff,0xffff,0x528a,0x0000,0x6b6d,0xffff,0xffff,0x4228,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0xffdf,0xffff,0xffff,0xf79e,0x0841,0x0000,0xd69a,0xffff,0xffff,0x7bef,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4a69,0x0000,0xef5d,0xffff,0xffff,0xa534,0x0000,0x2124,0xffff,0xffff,0xffff,0x630c,0x0000,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9492,0x0000,0x6b6d,0xffdf,0xf7be,0x39c7,0x0000,0x7bef,0xffff,0xef5d,0x8c71,0x0020,0x18e3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7be,0x2945,0x0000,0x1082,0x1082,0x0000,0x0861,0xe73c,0xffff,0x94b2,0x0000,0x0841,0xb596,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x738e,0x31a6,0x2104,0x52aa,0xce79,0xffff,0xffff,0xd69a,0x8c51,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9492,0x2104,0x4208,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xbdf7,0x7bef,0x9492,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd69a,0xa514,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9492,0x2104,0x4208,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ };
-diff -Nur linux_c860_org/drivers/video/tosaLogoMsgJ.c linux/drivers/video/tosaLogoMsgJ.c
---- linux_c860_org/drivers/video/tosaLogoMsgJ.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/video/tosaLogoMsgJ.c 2004-06-10 21:09:11.000000000 +0900
-@@ -0,0 +1,488 @@
-+/* Logo Screen 16bits RGB(565) data*/
-+#ifndef __initdata
-+#define __initdata
-+#endif
-+static const int logo_msg_width_jp __initdata = 32;
-+static const int logo_msg_height_jp __initdata = 480;
-+static const unsigned short logo_msg_data_jp[32*480] __initdata ={
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xd69a,0x7bef,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x0000,0x39c7,0xd6ba,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x0000,0x0020,0x39c7,0x9492,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x0861,0x0000,0x0020,0x7bef,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x39e7,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x7bef,0x94b2,0x0861,0x0000,0x3186,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7be,0xbdd7,0x3186,0x0000,0x6b6d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x7bef,0xffff,0xdefb,0x3186,0x0000,0x0861,0xb596,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0x0861,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xf7be,0x632c,0x0000,0x0000,0x8430,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0x94b2,0x0020,0x0000,0x52aa,0xe73c,0xffff,0xffff,0xffff,0xffff,0xd69a,0x0020,0x2965,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xb5b6,0x1082,0x0000,0x0841,0x5acb,0x94b2,0xa514,0x6b4d,0x0861,0x0000,0x8c51,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0x4a49,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x5acb,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xce59,0x738e,0x4228,0x4228,0x5acb,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xdefb,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xbdd7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe71c,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8410,0x0000,0x8430,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xc618,0x18c3,0x2124,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x630c,0x0000,0x0020,0xad55,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xdedb,0x0861,0x0000,0x738e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x4a49,0x0000,0x0020,0xad55,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x94b2,0x0000,0x0000,0xb5b6,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0xc638,0xd6ba,0x39e7,0x0000,0x0020,0x9cd3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0x632c,0x0000,0x0861,0xc618,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x7bef,0xf7be,0x52aa,0x0000,0x0000,0x632c,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x52aa,0x0000,0x0861,0xbdd7,0xffff,0xffff,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0x8410,0x0020,0x0000,0x18e3,0xa534,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x5acb,0x0000,0x0000,0x6b4d,0xdefb,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xbdf7,0x2104,0x0000,0x0000,0x2965,0xd6ba,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9492,0x0861,0x0000,0x0000,0x2124,0x2965,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xf7be,0x8410,0x1082,0x2124,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0x738e,0x18c3,0x0000,0x0000,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0xce79,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd6ba,0x7bef,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xf7be,0xa534,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xdefb,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xdefb,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xb5b6,0x630c,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xdefb,0x0000,0x0000,0xbdd7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xad55,0x2945,0x0000,0x0000,0xad55,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xf7be,0x10a2,0x0000,0x0000,0x18c3,0x2104,0x4208,0x4228,0x5acb,0x5aeb,0x4a69,0x0000,0x7bef,0xffff,0xffff,0xdefb,0x39c7,0x0000,0x0000,0x2124,0x94b2,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xc638,0x3186,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7bef,0xffff,0xa514,0x0861,0x0000,0x0861,0x8c71,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0xc638,0xc638,0xa534,0xa514,0x94b2,0x7bef,0x7bef,0x630c,0xad75,0x8c71,0x0000,0x0000,0x3186,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9cd3,0x0000,0x0000,0x528a,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xce79,0x0020,0x0000,0x39e7,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x2945,0x0000,0x18e3,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc618,0x2104,0xad55,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef7d,0x630c,0x52aa,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xc638,0xce59,0xffff,0xffff,0xffff,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0020,0x0000,0x4228,0xe73c,0xffff,0xffff,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0x39e7,0x0000,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xb5b6,0x10a2,0x0000,0x10a2,0x9cf3,0xffdf,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0x4a49,0x0000,0xbdd7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0x632c,0x0020,0x0000,0x2124,0x94b2,0xe73c,0x0000,0x2104,0xffff,0xffff,0x6b6d,0x0000,0x8c71,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0x73ae,0x2104,0x2104,0x2104,0x2104,0x2104,0x2104,0x2104,0x2104,0x0861,0x0000,0x0000,0x0000,0x0000,0x0000,0x0020,0x2104,0x2104,0x1082,0x0000,0x528a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0x5aeb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x1082,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xef5d,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0xdedb,0x39c7,0x0000,0x2104,0xd6ba,0xdefb,0x0000,0x18e3,0xdefb,0xdefb,0xdefb,0x0861,0x0000,0xc618,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef7d,0x39e7,0x0000,0x0861,0xd6ba,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0xffff,0x52aa,0x0000,0x6b6d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x5aeb,0x73ae,0xffff,0xffff,0xffff,0xffff,0xd6ba,0x18e3,0x0861,0xc618,0xffff,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0xffff,0x9492,0x2965,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0xc638,0xffff,0xffff,0xffff,0xffff,0x7bef,0x9492,0xffff,0xffff,0xffff,0xe71c,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0x9cd3,0x5aeb,0xdedb,0xffff,0x7bef,0x0000,0xa514,0xef7d,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0x5aeb,0x0000,0xc638,0xffff,0x7bef,0x0000,0xa514,0xc638,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0x5aeb,0x0000,0xc638,0xffff,0x7bef,0x0000,0xa514,0xd69a,0x2945,0x0000,0x2104,0x4228,0x4228,0x31a6,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0x5aeb,0x0000,0xc638,0xffff,0x7bef,0x0000,0xa514,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xc638,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x0000,0x1082,0x7bef,0x7bef,0x2965,0x0000,0x630c,0x7bef,0x4208,0x0000,0xa514,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xc638,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xa514,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xc638,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x0000,0x1082,0x7bef,0x7bef,0x2965,0x0000,0x630c,0x7bef,0x4208,0x0000,0xa514,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xc638,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0x5aeb,0x0000,0xc638,0xffff,0x7bef,0x0000,0xa514,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xc638,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0x5aeb,0x0000,0xc638,0xffff,0x7bef,0x0000,0xa514,0xe71c,0x528a,0x0000,0x4208,0x7bef,0x7bef,0x630c,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0x5aeb,0x0000,0xc638,0xffff,0x7bef,0x0000,0xa514,0xc638,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0xc638,0xa514,0xe73c,0xffff,0x7bef,0x0000,0xa514,0xe71c,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x4228,0x5acb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef7d,0xdefb,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xe73c,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xf79e,0x3186,0x0000,0x528a,0xb5b6,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xe73c,0x52aa,0x0000,0x0000,0x0000,0x0841,0x39e7,0x5aeb,0x7bcf,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0xbdf7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xd6ba,0x6b6d,0x2104,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdefb,0xe73c,0xffff,0xffff,0xe71c,0xb5b6,0x9cd3,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x7bef,0x528a,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0x6b4d,0x0000,0xb596,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0xdefb,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0x632c,0x0000,0x8c71,0xffff,0xffff,0xffff,0xffff,0x5acb,0x73ae,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0xdefb,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0x9492,0x0000,0x5acb,0xffff,0xffff,0xffff,0xffff,0x2104,0x4228,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0xdefb,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xc638,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0x18e3,0x4228,0xf7be,0xc638,0xc638,0xc638,0x630c,0x0000,0xad55,0xc638,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffdf,0x10a2,0x0000,0xdedb,0xffff,0xf79e,0x5aeb,0x0000,0x4228,0xdefb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x632c,0x0000,0x8410,0xef7d,0x39e7,0x0000,0x0000,0x4228,0xe73c,0x2104,0x0000,0x39e7,0x2104,0x0000,0x39e7,0x31a6,0xa514,0x0000,0x2965,0x5aeb,0x73ae,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xd69a,0x0000,0x18c3,0x2124,0x0000,0x8410,0x2104,0x4228,0xffff,0x7bef,0x0000,0xdefb,0x7bef,0x0000,0xdefb,0xffff,0xa514,0x0000,0x0000,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0x4a49,0x0000,0x0000,0x738e,0xffff,0x2104,0x4228,0xffff,0x7bef,0x0000,0xdefb,0x7bef,0x0000,0xdefb,0xffff,0xa514,0x0000,0x2965,0x5aeb,0x52aa,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0x8c51,0x0000,0x0000,0xd6ba,0xffff,0x2104,0x4228,0xffff,0x7bef,0x0000,0xdefb,0x7bef,0x0000,0xdefb,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffdf,0x18e3,0x0841,0x0020,0x2945,0xf79e,0x2104,0x4228,0xffff,0x528a,0x0000,0x8c71,0x528a,0x0000,0x8c71,0xa514,0x94b2,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xad75,0x0000,0x5acb,0x7bef,0x0000,0x4a49,0x18e3,0x4228,0xffff,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x8410,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x5acb,0x0000,0xa514,0xffdf,0x52aa,0x0000,0x0000,0x4228,0xffff,0x5aeb,0x5aeb,0x5aeb,0x2965,0x0000,0x528a,0x4a69,0x8c51,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x1082,0x0000,0xdefb,0xffff,0xf79e,0x39e7,0x0000,0x31a6,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0xdefb,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xd69a,0x0000,0x10a2,0xffff,0xffff,0xffff,0xffdf,0x39e7,0xc638,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0xdefb,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0x9cf3,0x0000,0x4208,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0xdefb,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0x6b6d,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0xdefb,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xd6ba,0x9492,0xb596,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef7d,0xdefb,0xffdf,0xffff,0xf79e,0xdefb,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffdf,0x73ae,0x18e3,0x0020,0x2945,0x6b6d,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0x9492,0xbdd7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x6b6d,0x0000,0x1082,0x2104,0x0861,0x0000,0x0861,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xef5d,0x0020,0x2945,0xf79e,0xffff,0xf7be,0x94b2,0x0020,0x0020,0xbdf7,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x6b6d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xdefb,0x0000,0x5acb,0xffff,0xffff,0xffff,0xffff,0xb5b6,0x0020,0x18c3,0xef5d,0xffff,0xffff,0xffff,0xc638,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xf7be,0x1082,0x0861,0x9cd3,0xd6ba,0xdefb,0xdefb,0xdefb,0x73ae,0x0000,0x5aeb,0xdefb,0xdefb,0xdefb,0xb596,0x0000,0x4208,0xdefb,0xdefb,0xdefb,0xdefb,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x94b2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xad55,0x4228,0x2104,0x2104,0x2104,0x2104,0x2104,0x10a2,0x0000,0x1082,0x2104,0x2104,0x2104,0x0020,0x0000,0x2104,0x2104,0x2104,0x18c3,0x8430,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd69a,0x0000,0x52aa,0xffff,0xffff,0xffff,0x4228,0x0000,0xd69a,0xffff,0xffff,0xffdf,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x1082,0x18e3,0xffff,0xffff,0xffff,0x6b6d,0x0000,0x9cd3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0x73ae,0xffff,0xffff,0xffff,0xffff,0xffff,0x4208,0x0000,0xf79e,0xffff,0xffff,0xad55,0x0000,0x4228,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xc618,0x1082,0x0000,0x9cd3,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0xdefb,0xffff,0xffff,0xe73c,0x0841,0x39e7,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf7be,0x18c3,0x0000,0x528a,0xef7d,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xb596,0x0000,0x39c7,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0x4a69,0x0000,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x9cf3,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x10a2,0x18e3,0xffff,0xffff,0xffff,0xffff,0xffff,0x6b6d,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x738e,0xffff,0xffff,0xffff,0xffff,0xffff,0x9cf3,0x0000,0x630c,0xffff,0xffff,0xffff,0xffff,0x9492,0x0000,0x2945,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdedb,0x0000,0x1082,0xdedb,0xffff,0xffff,0xffff,0xad75,0x0861,0x0020,0xd6ba,0xffff,0xffff,0xffff,0xbdf7,0x0020,0x0000,0x8c71,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0x5acb,0x0000,0x1082,0x52aa,0x5aeb,0x39c7,0x0000,0x0000,0x8c51,0xffff,0xffff,0xffff,0xdedb,0x10a2,0x0000,0x4228,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x4a69,0x0000,0x0000,0x0000,0x0000,0x10a2,0x9cf3,0xffff,0xffff,0xffff,0xe71c,0x18c3,0x0000,0x2104,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedb,0xa534,0xa514,0xb5b6,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffdf,0x52aa,0x18c3,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xbdf7,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffdf,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x4a69,0x0000,0x4228,0xffdf,0xffff,0xffff,0xe73c,0x3186,0x1082,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xad55,0x0020,0x0000,0x52aa,0xffdf,0xffff,0xffff,0x4228,0x0000,0x3186,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xdedb,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0xc638,0x738e,0x0000,0x0000,0x4228,0xef5d,0xffff,0xef5d,0x2124,0x0000,0x39e7,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0x5aeb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x18c3,0xad75,0xffff,0xe73c,0x2124,0x0000,0x2104,0xce59,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0x8c51,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x4228,0x2945,0x0000,0x0000,0x4228,0xd69a,0xe73c,0x4228,0x0000,0x0020,0xb5b6,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x9492,0x1082,0x0000,0x39c7,0xffff,0xffdf,0x8c71,0x2124,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd69a,0xc638,0xf7be,0xffff,0xd69a,0x7bef,0xad55,0x4a69,0xd6ba,0xffff,0xffff,0xffff,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0xdefb,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xa514,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedb,0x94b2,0xffff,0x4228,0x0000,0xdefb,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0x2124,0x0000,0xad55,0x4228,0x0000,0xdefb,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd6ba,0x2104,0x0000,0x2124,0xf79e,0x4228,0x0000,0xdefb,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xad55,0x0020,0x18c3,0xdefb,0xffff,0x4228,0x0000,0xdefb,0xffff,0xa514,0x0000,0x6b6d,0xdefb,0xdefb,0x0000,0x18e3,0xdefb,0xdefb,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xbdd7,0xe73c,0xffff,0xffff,0x4228,0x0000,0xdefb,0xffff,0xa514,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0x7bcf,0x0861,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0xdefb,0xffff,0xa514,0x0000,0x1082,0x2104,0x2104,0x0000,0x0020,0x2104,0x2104,0x3186,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0x5aeb,0x0000,0xad55,0xdefb,0xdefb,0xdefb,0xdefb,0xdefb,0x39e7,0x0000,0xc618,0xdefb,0x8c71,0x0000,0x7bef,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0x5aeb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x7bef,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xc618,0x2965,0x2104,0x2104,0x2104,0x2104,0x2104,0x2104,0x0841,0x0000,0x18e3,0x2104,0x10a2,0x0000,0x7bef,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0xdefb,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0xdefb,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0x4228,0x5acb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0xdefb,0xffff,0xa514,0x0000,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd69a,0xc638,0xf7be,0xffff,0xad75,0x2104,0x9492,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd69a,0x39c7,0x6b6d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xce59,0x0000,0x528a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0x7bcf,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0x0000,0x4228,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0x2945,0x8430,0xce79,0xffff,0xffff,0xffff,0xef5d,0x0000,0x39e7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x0000,0x0000,0x0000,0x18c3,0x528a,0x9492,0xce79,0x0000,0x2104,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x4228,0x0000,0x1082,0x4208,0x0841,0x0000,0x0000,0x0000,0x0000,0x0841,0x630c,0x94b2,0xbdf7,0xdedb,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0xf7be,0xffff,0xffff,0xffff,0xe73c,0x10a2,0x0000,0xd6ba,0xf7be,0xc638,0x8c51,0x528a,0x0841,0x0000,0x0000,0x0000,0x0000,0x0000,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x528a,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x6b6d,0xffff,0xffff,0xffff,0xffff,0x528a,0x0000,0x8c71,0x6b6d,0x39c7,0x10a2,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffdf,0x10a2,0x18e3,0xffff,0xffff,0xffff,0xffff,0x632c,0x0000,0xc638,0xffff,0xffff,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x2104,0x0000,0xdedb,0xffff,0xffff,0xffff,0xffff,0xffff,0x52aa,0x0000,0xd6ba,0xffff,0xffff,0xffff,0x8430,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x2965,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c51,0x0000,0xad75,0xffff,0xffff,0xffff,0xa514,0x0000,0x7bcf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x4a49,0x0000,0xad55,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0xa514,0xffff,0xffff,0xffff,0xc638,0x0000,0x528a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x6b6d,0x0000,0x738e,0xffff,0xffff,0xffff,0xffff,0xffff,0x9cf3,0x0000,0xa514,0xffff,0xffff,0xffff,0xdefb,0x0000,0x2965,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xad55,0x0000,0x2945,0xffff,0xffff,0xffff,0xffff,0xffff,0x6b4d,0x0000,0xbdf7,0xffff,0xffff,0xffff,0xffff,0x9492,0xc618,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xef5d,0x0841,0x0000,0x9cf3,0xffff,0xffff,0xffff,0xdedb,0x0861,0x0841,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0x738e,0x0000,0x0020,0x5acb,0x9cd3,0x738e,0x0861,0x0000,0x738e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x4a49,0x0000,0x0000,0x0000,0x0000,0x0000,0x5acb,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xb596,0x6b4d,0x5aeb,0x6b6d,0xbdd7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedb,0x39e7,0x2124,0x9492,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedb,0x18c3,0x0000,0x0000,0x0000,0x8c51,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0x2124,0x0000,0x39e7,0x8430,0x0020,0x0000,0x8c71,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x39c7,0x0000,0x2124,0xf79e,0xffff,0xad55,0x0000,0x0000,0x8c71,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x39e7,0x0000,0x1082,0xdedb,0xffff,0xffff,0xffff,0x8c71,0x0000,0x0000,0x8c71,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x52aa,0x0000,0x0020,0xbdd7,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c71,0x0000,0x0000,0x8c71,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0x52aa,0x0000,0x0000,0x9cf3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c71,0x0000,0x0000,0x73ae,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x4a69,0x0000,0x0000,0x8c51,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c71,0x0000,0x0000,0x52aa,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xef7d,0x39e7,0x0000,0x0000,0x738e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x9cd3,0x0020,0x0000,0x2945,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x4208,0x0000,0x0000,0x738e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xb596,0x0861,0x0000,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xdedb,0x18c3,0x8430,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x8410,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0xad75,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0x9492,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xc618,0x0000,0x0020,0x528a,0xad75,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xbdd7,0x2945,0x0000,0x0000,0x0000,0x0861,0x52aa,0xa514,0xe71c,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0xc638,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xce59,0x6b6d,0x2124,0x0000,0x0000,0x0000,0x0000,0x2124,0x5acb,0x9492,0xc618,0x6b4d,0x0000,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdedb,0x9cd3,0x52aa,0x18e3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x2945,0x5acb,0x7bcf,0xa514,0xc638,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0xb596,0x7bef,0x4a69,0x18e3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb596,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xce59,0x0000,0x4a49,0xa534,0x738e,0x4208,0x0841,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0x0000,0x39e7,0xffff,0xffff,0xffff,0xdefb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf7be,0x3186,0x9492,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x10a2,0x1082,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x4a69,0xffff,0xffff,0xffff,0xffff,0xffff,0xad75,0x6b4d,0xf7be,0xffff,0xffff,0x4208,0x0000,0xd6ba,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0x4208,0x0000,0xad75,0xffff,0xffff,0xb5b6,0xb5b6,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xf79e,0x0020,0x0000,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0x94b2,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xce59,0x0000,0x18e3,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd69a,0x0000,0x2124,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xa534,0x0000,0x4228,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x0841,0x0000,0xef7d,0xffff,0xffff,0xffff,0xffff,0xb5b6,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x4228,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x31a6,0x0000,0xce59,0xffff,0xffff,0xffff,0xe71c,0x0861,0x4a49,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x4228,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x4a69,0x0000,0xad55,0xffff,0xffff,0xffff,0x4208,0x0020,0xdedb,0x9492,0xe71c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x4228,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0x9cd3,0xffff,0xffff,0x94b2,0x0000,0x8430,0xbdf7,0x0000,0x6b4d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x4228,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bcf,0x0000,0x7bef,0xffff,0xffff,0xbdd7,0x5acb,0xef7d,0x2104,0x18e3,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xad75,0x2104,0x5acb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd6ba,0xd69a,0xffdf,0xffff,0xffff,0xffff,0xffff,0x630c,0x0000,0xb596,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xce59,0x8c51,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd69a,0xbdd7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xad55,0x630c,0x5aeb,0x94b2,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xbdf7,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x4208,0x0000,0x0000,0x0000,0x0000,0x2124,0xe73c,0xffff,0xffff,0xffff,0xffff,0xc638,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0x4228,0x0000,0x2104,0x9492,0x9cf3,0x4208,0x0000,0x528a,0xffff,0xffff,0xffff,0xffff,0xc638,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xb596,0x0000,0x1082,0xe73c,0xffff,0xffff,0xf7be,0x2124,0x0000,0xdefb,0xffff,0xffff,0xffff,0xc638,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x52aa,0x0000,0x73ae,0xffff,0xffff,0xffff,0xffff,0x8c71,0x0000,0xa514,0xffff,0xffff,0xffff,0xc638,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0x18e3,0x0000,0xbdd7,0xffff,0xffff,0xffff,0xffff,0xc638,0x0000,0x7bef,0xffff,0xffff,0xffff,0xdefb,0x0000,0x52aa,0xffff,0xffff,0xffff,0xd69a,0xce59,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xf79e,0x0000,0x0000,0xdefb,0xffff,0xffff,0xffff,0xffff,0xdefb,0x0000,0x7bef,0xffff,0xffff,0xffff,0xdefb,0x0000,0x39e7,0xa534,0x52aa,0x1082,0x0000,0x5aeb,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xdefb,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0x0000,0x7bef,0xffff,0xffff,0xffff,0xdedb,0x0000,0x0000,0x0000,0x0000,0x0000,0x1082,0x630c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xdefb,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xd69a,0x0000,0x7bef,0xffff,0xef7d,0x6b4d,0x0020,0x0000,0x0000,0x39e7,0x8c51,0xd6ba,0xffff,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xdefb,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xb596,0x0000,0x8c51,0xbdd7,0x18e3,0x0000,0x0841,0x0841,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xdefb,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0x7bef,0x0000,0x39e7,0x0020,0x0000,0x4228,0xe71c,0x4208,0x0000,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xdefb,0x0000,0x0000,0xffff,0xffff,0xffff,0xffff,0xffff,0x39e7,0x0000,0x0000,0x0000,0x8410,0xffff,0xffff,0x528a,0x0000,0xce59,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffdf,0xb596,0x7bcf,0xffff,0xffff,0xffff,0xffff,0xe71c,0x0000,0x0000,0x0000,0x8c71,0xffff,0xffff,0xffff,0x632c,0x0000,0xa514,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8430,0x0000,0x0000,0x8c51,0xffff,0xffff,0xffff,0xffff,0x8430,0x0000,0x738e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xc618,0x18c3,0x5acb,0xffff,0xffff,0xffff,0xffff,0xffff,0xa534,0x18e3,0x7bef,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xe71c,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xd69a,0xb5b6,0xa514,0x9cd3,0x7bef,0x7bef,0x7bef,0x7bef,0xa514,0xa514,0xad75,0xc638,0xd69a,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x6b6d,0x0861,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xad75,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x2124,0x0000,0x0000,0x0020,0x2965,0x4a49,0x5aeb,0x5aeb,0x5aeb,0x5aeb,0x5aeb,0x52aa,0x4228,0x31a6,0x18c3,0x0000,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0x8c51,0x0000,0x0020,0x9492,0xf79e,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xb5b6,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0x5aeb,0x0000,0x39c7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0x8410,0x0000,0x0020,0xbdf7,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xf79e,0x2124,0x0000,0x0020,0x630c,0xce79,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef5d,0x4a69,0x0000,0x0000,0x0000,0xc618,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xad75,0x39c7,0x6b6d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef7d,0xef7d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xd6ba,0x2124,0x73ae,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xf7be,0x8c51,0x0841,0x0000,0x10a2,0xf7be,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef7d,0x9492,0x18e3,0x0000,0x0000,0x18c3,0xc618,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xdefb,0xa514,0x528a,0x0841,0x0000,0x0000,0x0000,0x4a69,0xe73c,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xef7d,0x10a2,0x0000,0x0000,0x0000,0x0000,0x0000,0x2124,0xa534,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x2945,0x0000,0x0000,0x0020,0x4228,0xad55,0xffdf,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0x8c51,0x6b6d,0xad55,0xef5d,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x4228,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x4228,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0xc638,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x4228,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x4228,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0xc638,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x4228,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xa514,0x0000,0x4228,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xe73c,0xc638,0xd69a,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ 0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,0xffff,
-+ };
-diff -Nur linux_c860_org/drivers/video/tosa_backlight.c linux/drivers/video/tosa_backlight.c
---- linux_c860_org/drivers/video/tosa_backlight.c 1970-01-01 09:00:00.000000000 +0900
-+++ linux/drivers/video/tosa_backlight.c 2004-06-10 21:09:11.000000000 +0900
-@@ -0,0 +1,489 @@
-+/*
-+ * drivers/video/tosa_backlight.c
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ *
-+ * Based on:
-+ *
-+ * linux/drivers/video/corgi_frontlight.c
-+ *
-+ * (C) Copyright 2002 SHARP
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ *
-+ * Based on:
-+ *
-+ * linux/drivers/video/poodle_frontlight.c
-+ *
-+ * (C) Copyright 2001 Lineo Japan, Inc.
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ *
-+ * Based on:
-+ *
-+ * linux/drivers/video/collie_frontlight.c
-+ *
-+ * (C) Copyright 2001 Lineo Japan, Inc.
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ *
-+ * Based on:
-+ * drivers/video/sa1100_frontlight.c
-+ * Initial Version by: Nicholas Mistry (nmistry@lhsl.com)
-+ *
-+ * ChangeLog:
-+ * 02-Dec-2002 SHARP for SL-C700
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/ctype.h>
-+#include <linux/mm.h>
-+#include <linux/tty.h>
-+#include <linux/slab.h>
-+#include <linux/proc_fs.h>
-+#include <linux/init.h>
-+#include <linux/fb.h>
-+#include <linux/delay.h>
-+
-+#include <linux/pm.h>
-+
-+#include <asm/system.h>
-+#include <asm/hardware.h>
-+#include <asm/io.h>
-+#include <asm/irq.h>
-+#include <asm/uaccess.h>
-+#include <asm/proc/pgtable.h>
-+
-+#include <video/tosa_backlight.h>
-+
-+#include <linux/interrupt.h>
-+
-+#include <asm/arch/i2sc.h>
-+
-+extern void pxa_nssp_output(unsigned char, unsigned char);
-+
-+#if 0
-+#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
-+#else
-+#define DPRINTK(fmt, args...)
-+#endif
-+
-+#ifdef CONFIG_PM
-+static int is_bl_pm = 0;
-+static int is_bl_blank = 0;
-+static int counter_step_save = 0;
-+#endif
-+
-+#define BL_SETTING 6
-+#define BL_DEFAULT 3
-+
-+int counter_step_contrast = BL_DEFAULT;
-+static int bl_limit = BL_SETTING - 1;
-+static spinlock_t bl_lock = SPIN_LOCK_UNLOCKED;
-+
-+typedef struct _duty_vr_t {
-+ int duty;
-+ int vr;
-+} duty_vr_t;
-+
-+static duty_vr_t bl_duty_table[BL_SETTING] = {
-+ {0, 0}, //Light Off
-+ {11, 1},
-+ {33, 1},
-+ {68, 1},
-+ {100, 1},
-+ {255, 1},
-+};
-+
-+static int tosa_bl_ioctl(struct inode* inode, struct file*, unsigned int,
-+ unsigned long);
-+static int bl_step_contrast_setting(int);
-+
-+extern unsigned short set_scoop_gpio(unsigned short);
-+extern unsigned short reset_scoop_gpio(unsigned short);
-+
-+#define SetBacklightDuty(a) set_bl_bright(a);
-+#define SetBacklightVR(a) if (a) { TC6393_SYS_REG(TC6393_SYS_GPODSR1) |= TC6393_BL_C20MA; } \
-+ else { TC6393_SYS_REG(TC6393_SYS_GPODSR1) &= ~TC6393_BL_C20MA; }
-+
-+/*
-+ * I2C functions.
-+ */
-+#define I2C_TIMEOUT 100 //wait for 5ms
-+#define I2C_ADR_DAC 0x4e //DAC Slave address
-+#define DAC_CH1 0
-+#define DAC_CH2 1
-+#define I2C_ICR_DEF_VAL (ICR_IUE | ICR_SCLE | ICR_FM)
-+#define i2c_reset() i2c_init(1)
-+#define i2c_set() i2c_init(0)
-+void i2c_init(int reset)
-+{
-+ if( reset ) {
-+ ICR = ICR_UR;
-+ CKEN &= ~CKEN14_I2C;
-+ }
-+ CKEN |= CKEN14_I2C; //Set I2C cleck
-+ ICR = I2C_ICR_DEF_VAL;
-+ ISR = 0x6f0; //Clear all status.
-+}
-+
-+static int i2c_wait_for_fifo_empty(void)
-+{
-+ int timeo = 0;
-+ while( 1 ) {
-+ if( ISR & ISR_ITE) break;
-+ if( timeo++ > I2C_TIMEOUT ) {
-+ DPRINTK("timeout: %x\n", ISR);
-+ i2c_reset();
-+ return -EBUSY;
-+ }
-+ mdelay(1);
-+ }
-+ ISR = ISR_ITE;
-+ return 0;
-+}
-+
-+static int i2c_write(unsigned char reg, unsigned char val)
-+{
-+ int ret;
-+
-+ /* Start condition */
-+ if( ISR & ISR_IBB ) {
-+ DPRINTK("bus is busy\n");
-+ i2c_reset();
-+ return -EBUSY;
-+ }
-+ /* Slave address write */
-+ IDBR = (I2C_ADR_DAC << 1);
-+ ICR = (ICR_START | ICR_TB | I2C_ICR_DEF_VAL | ICR_ACKNAK);
-+ if( (ret = i2c_wait_for_fifo_empty()) < 0 ) return ret;
-+
-+ /* DAC channel write */
-+ IDBR = reg;
-+ ICR = (ICR_TB | I2C_ICR_DEF_VAL);
-+ if( (ret = i2c_wait_for_fifo_empty()) < 0 ) return ret;
-+
-+ /* data write */
-+ IDBR = val;
-+ ICR = (ICR_STOP | ICR_TB | I2C_ICR_DEF_VAL | ICR_ACKNAK);
-+ if( (ret = i2c_wait_for_fifo_empty()) < 0 ) return ret;
-+
-+ ICR = I2C_ICR_DEF_VAL;
-+ return 0;
-+}
-+
-+/*
-+ * Backlight control functions.
-+ */
-+static void bl_enable(int sw)
-+{
-+ if( sw ) pxa_nssp_output(TG_GPODR2, 0x01); //GP04=1
-+ else pxa_nssp_output(TG_GPODR2, 0x00); //GP04=0
-+}
-+
-+static int set_bl_bright(unsigned char dat)
-+{
-+ return i2c_write(DAC_CH2, dat);
-+}
-+
-+#ifdef CONFIG_PROC_FS
-+struct proc_dir_entry *proc_bl;
-+
-+static ssize_t bl_read_params(struct file *file, char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ char obuf[15];
-+ int count = 0;
-+
-+ if( *ppos>0 ) /* Assume reading completed in previous read*/
-+ return 0;
-+ count = sprintf(obuf, "0x%02X%02X\n",
-+ bl_duty_table[counter_step_contrast].vr,
-+ bl_duty_table[counter_step_contrast].duty);
-+ *ppos += count;
-+ if( count>nbytes ) /* Assume output can be read at one time */
-+ return -EINVAL;
-+ if( copy_to_user(buf, obuf, count) )
-+ return -EFAULT;
-+ return count;
-+}
-+
-+static ssize_t bl_write_params(struct file *file, const char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ unsigned long param;
-+ char *endp;
-+
-+ param = simple_strtoul(buf,&endp,0);
-+ SetBacklightDuty(param & 0xff);
-+ SetBacklightVR((param & 0xff00) >> 8);
-+ return nbytes+endp-buf;
-+}
-+
-+static struct file_operations proc_params_operations = {
-+ read: bl_read_params,
-+ write: bl_write_params,
-+};
-+#endif /* CONFIG_PROC_FS */
-+
-+#ifdef CONFIG_PM
-+void tosa_bl_blank(int blank)
-+{
-+ if( blank ) {
-+ if( !is_bl_blank ) {
-+ is_bl_blank = 1;
-+ counter_step_save = counter_step_contrast;
-+ bl_step_contrast_setting(0);
-+ }
-+ } else {
-+ if( is_bl_blank && !is_bl_pm ) {
-+ bl_step_contrast_setting(counter_step_save);
-+ is_bl_blank = 0;
-+ }
-+ }
-+}
-+
-+void tosa_l_blank_power_button(void)
-+{
-+ if (!is_bl_blank) {
-+ is_bl_blank = 1;
-+ counter_step_save = counter_step_contrast;
-+ bl_step_contrast_setting(0);
-+ }else{
-+ counter_step_contrast = counter_step_save;
-+ bl_step_contrast_setting(counter_step_contrast);
-+ is_bl_blank = 0;
-+ }
-+}
-+
-+
-+int tosa_bl_pm_callback(struct pm_dev* pm_dev,
-+ pm_request_t req, void *data)
-+{
-+ switch (req) {
-+ case PM_SUSPEND:
-+ is_bl_pm = 1;
-+ tosa_bl_blank(1);
-+ break;
-+ case PM_RESUME:
-+ is_bl_pm = 0;
-+ tosa_bl_blank(0);
-+ break;
-+ }
-+ return 0;
-+}
-+#endif /* CONFIG_PM */
-+
-+static struct file_operations tosa_bl_fops = {
-+ ioctl: tosa_bl_ioctl,
-+};
-+
-+static int bl_major;
-+
-+#define CHECK_BATTERY_TIME 1
-+static int bl_step_contrast_setting_nocheck(int need_value)
-+{
-+ unsigned long flags;
-+
-+ /* Check value */
-+ if( need_value < 0 ) need_value = 0;
-+ if( need_value > bl_limit ) need_value = bl_limit;
-+
-+ spin_lock_irqsave(&bl_lock, flags);
-+ if(need_value > 0) bl_enable(1);
-+ else bl_enable(0);
-+ SetBacklightDuty(bl_duty_table[need_value].duty);
-+ SetBacklightVR(bl_duty_table[need_value].vr);
-+ spin_unlock_irqrestore(&bl_lock, flags);
-+ counter_step_contrast = need_value;
-+
-+ return counter_step_contrast;
-+}
-+
-+
-+static int bl_step_contrast_setting(int need_value)
-+{
-+ int ret = 0;
-+ extern void sharpsl_kick_battery_check(int,int,int);
-+ sharpsl_kick_battery_check(0,1,0); // check battery and wait 10msec
-+ ret = bl_step_contrast_setting_nocheck(need_value);
-+ sharpsl_kick_battery_check(1,0,0); // wait 10msec and check battery
-+ return ret;
-+}
-+
-+static int temporary_contrast_set_flag = 0;
-+
-+void tosa_bl_temporary_contrast_set(void)
-+{
-+ int need_value = counter_step_contrast;
-+
-+ if( temporary_contrast_set_flag ) return;
-+
-+ temporary_contrast_set_flag = 1;
-+ bl_step_contrast_setting(need_value);
-+}
-+
-+void tosa_bl_temporary_contrast_reset(void)
-+{
-+ int need_value = counter_step_contrast;
-+
-+ if( !temporary_contrast_set_flag ) return;
-+
-+ temporary_contrast_set_flag = 0;
-+ bl_step_contrast_setting(need_value);
-+}
-+
-+void tosa_bl_set_limit_contrast(int val)
-+{
-+ unsigned long flags;
-+ spin_lock_irqsave(&bl_lock, flags);
-+ if( (val > BL_SETTING - 1) || (val < 0) ) {
-+ if( bl_limit != BL_SETTING - 1 ) {
-+ printk("bl : unlimit contrast\n");
-+ }
-+ bl_limit = BL_SETTING - 1;
-+ } else {
-+ if( bl_limit != val ) {
-+ printk("bl : change limit contrast %d\n", val);
-+ }
-+ bl_limit = val;
-+ }
-+ spin_unlock_irqrestore(&bl_lock, flags);
-+ if( counter_step_contrast > bl_limit )
-+ bl_step_contrast_setting_nocheck(bl_limit);
-+}
-+
-+int tosa_set_common_voltage(unsigned char dat)
-+{
-+ return i2c_write(DAC_CH1, dat);
-+}
-+
-+static int tosa_bl_ioctl(struct inode* inode, struct file* filp,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ int ret = -EINVAL;
-+
-+ switch(cmd) {
-+ case TOSA_BL_IOCTL_ON:
-+ if (is_bl_blank) return 0;
-+ ret = bl_step_contrast_setting_nocheck(counter_step_contrast);
-+ break;
-+ case TOSA_BL_IOCTL_OFF:
-+ if (is_bl_blank) return 0;
-+ ret = bl_step_contrast_setting_nocheck(0);
-+ break;
-+ case TOSA_BL_IOCTL_STEP_CONTRAST:
-+ if (is_bl_blank) return 0;
-+ ret = bl_step_contrast_setting_nocheck(arg);
-+ break;
-+ case TOSA_BL_IOCTL_GET_STEP_CONTRAST:
-+ ret = counter_step_contrast;
-+ break;
-+ case TOSA_BL_IOCTL_GET_STEP:
-+ ret = BL_SETTING;
-+ break;
-+ default:
-+ ;
-+ }
-+
-+ return ret;
-+}
-+
-+static __init int tosa_bl_init(void)
-+{
-+ int ret;
-+
-+ bl_major = BL_MAJOR;
-+
-+ if( (ret = register_chrdev(bl_major, BL_NAME, &tosa_bl_fops)) < 0 ) {
-+ DPRINTK("%s: cant get major %d\n", BL_NAME, bl_major);
-+ return ret;
-+ }
-+
-+ if( !bl_major ) bl_major = ret;
-+
-+ bl_step_contrast_setting_nocheck(counter_step_contrast);
-+
-+#ifdef CONFIG_PROC_FS
-+ {
-+ struct proc_dir_entry *entry;
-+
-+ proc_bl = proc_mkdir("driver/fl", NULL);
-+ if (proc_bl == NULL) {
-+ bl_step_contrast_setting(0);
-+ unregister_chrdev(bl_major, BL_NAME);
-+ printk(KERN_ERR "%s: can't create /proc/driver/fl\n", BL_NAME);
-+ return -ENOMEM;
-+ }
-+ entry = create_proc_entry(BL_NAME, S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH,
-+ proc_bl);
-+ if( entry ) {
-+ entry->proc_fops = &proc_params_operations;
-+ } else {
-+ remove_proc_entry("driver/fl", &proc_root);
-+ proc_bl = 0;
-+ bl_step_contrast_setting(0);
-+ unregister_chrdev(bl_major, BL_NAME);
-+ printk(KERN_ERR "%s: can't create /proc/driver/fl/\n", BL_NAME);
-+ return -ENOMEM;
-+ }
-+ }
-+#endif /* CONFIG_PROC_FS */
-+
-+ printk(KERN_INFO "%s: Initialized.\n", BL_NAME);
-+
-+#if 0
-+ { /* IOCTL TEST */
-+ int i;
-+ printk("\n%s: ioctl test.\n", BL_NAME);
-+ printk("%s: Backlight off\n", BL_NAME);
-+ ret = tosa_bl_ioctl(0, 0, TOSA_BL_IOCTL_OFF, 0);
-+ if(ret < 0) printk("%s: error:%d\n", BL_NAME, ret);
-+ mdelay(5000);
-+ printk("%s: Backlight on\n", BL_NAME);
-+ ret = tosa_bl_ioctl(0, 0, TOSA_BL_IOCTL_ON, 0);
-+ if(ret < 0) printk("%s: error:%d\n", BL_NAME, ret);
-+ mdelay(5000);
-+ for(i = 1; i < BL_SETTING; i++) {
-+ printk("%s: Backlight step: %d\n", BL_NAME, i);
-+ ret = tosa_bl_ioctl(0, 0, TOSA_BL_IOCTL_STEP_CONTRAST, i);
-+ if(ret < 0) printk("%s: error:%d\n", BL_NAME, ret);
-+ mdelay(5000);
-+ }
-+ }
-+#endif
-+ return 0;
-+}
-+
-+#ifdef MODULE
-+void __exit tosa_bl_exit(void)
-+{
-+ bl_step_contrast_setting(0);
-+
-+ unregister_chrdev(bl_major, BL_NAME);
-+
-+#ifdef CONFIG_PROC_FS
-+ {
-+ remove_proc_entry(BL_NAME, proc_bl);
-+ remove_proc_entry("driver/fl", NULL);
-+ proc_bl = 0;
-+ }
-+#endif /* CONFIG_PROC_FS */
-+ printk(KERN_INFO "%s: Unloaded\n", BL_NAME);
-+}
-+
-+module_exit(tosa_bl_exit);
-+#endif /* MODULE */
-+
-+module_init(tosa_bl_init);
-diff -Nur linux_c860_org/drivers/video/w100fb.c linux/drivers/video/w100fb.c
---- linux_c860_org/drivers/video/w100fb.c 2003-06-18 17:43:52.000000000 +0900
-+++ linux/drivers/video/w100fb.c 2004-06-10 21:09:11.000000000 +0900
-@@ -54,6 +54,9 @@
- #include <video/fbcon-mfb.h>
- #include <video/fbcon.h>
-
-+#include <linux/proc_fs.h>
-+#include <asm/proc/pgtable.h>
-+
- #include "w100fb.h"
- #include <linux/pm.h>
-
-@@ -74,6 +77,7 @@
- static void w100_resume(void);
- static void w100_suspend(u32 mode);
- static void w100_init_qvga_rotation(u16 deg);
-+static void w100_init_vga_rotation(u16 deg);
- static void w100_soft_reset(void);
- static void w100_clear_screen(u32 mode,void *fbuf);
- static void w100_vsync(void);
-@@ -106,7 +110,7 @@
- #define REMAPPED_CFG_LEN 0x10
- #define REMAPPED_MMR_LEN 0x2000
- #define W100_PHYS_ADR_LEN 0x1000000
--#define MAX_XRES 480
-+#define MAX_XRES 640
- #define MAX_YRES 640
- #define BITS_PER_PIXEL 16
-
-@@ -177,9 +181,23 @@
- #define LCD_MODE_480 0
- #define LCD_MODE_320 1
- #define LCD_MODE_240 2
-+#define LCD_MODE_640 3
-+
- #define LCD_MODE_UNKOWN (-1)
-
- int w100fb_lcdMode = LCD_MODE_UNKOWN; //default UNKOWN
-+#if defined(CONFIG_FBCON_ROTATE_R)
-+static int w100fb_rotation_flag = 270;
-+#else
-+static int w100fb_rotation_flag = 90;
-+#endif
-+#if defined(CONFIG_SL_SYSCLK100)
-+int fastsysclk_mode=100;
-+#else
-+int fastsysclk_mode=75;
-+#endif
-+static int lcd_param=0;
-+static int proc_resume_mode=0;
-
- static u16 *gSaveImagePtr[640] = {NULL};
- #define SAVE_IMAGE_MAX_SIZE ((640 * 480 * BITS_PER_PIXEL) / 8)
-@@ -245,6 +263,171 @@
- static void w100_PwmSetup(void);
- static void w100_InitExtMem(u32 mode);
-
-+#ifdef CONFIG_PROC_FS
-+struct proc_dir_entry *proc_w100;
-+
-+
-+static ssize_t w100_read_rotation(struct file *file, char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ char outputbuf[50];
-+ int count;
-+ if (*ppos>0) /* Assume reading completed in previous read*/
-+ return 0;
-+ count = sprintf(outputbuf, "Rotation degree %d.\n",w100fb_rotation_flag);
-+ *ppos += count;
-+ if (count>nbytes) /* Assume output can be read at one time */
-+ return -EINVAL;
-+ if (copy_to_user(buf, outputbuf, count))
-+ return -EFAULT;
-+ return count;
-+}
-+
-+static ssize_t w100_write_rotation(struct file *file, const char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ int len;
-+ unsigned int degree;
-+
-+ sscanf(buf,"%d",&degree);
-+ printk("Change rotation degree %d\n",degree);
-+
-+ if ( degree == 180)
-+ w100fb_rotation_flag = 90;
-+ else
-+ w100fb_rotation_flag = 270;
-+
-+ if (w100fb_lcdMode == LCD_MODE_320)
-+ w100_init_qvga_rotation(w100fb_rotation_flag);
-+
-+ len=strlen(buf);
-+ return len;
-+}
-+
-+static ssize_t w100_read_reg(struct file *file, const char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ int len;
-+ unsigned long regs;
-+ unsigned long param;
-+
-+
-+ sscanf(buf,"%x",&regs);
-+
-+ param = readl(remapped_regs+regs);
-+
-+ printk("Read reg:: regs 0x%08X : 0x%08X\n", regs, param);
-+
-+ len=strlen(buf);
-+ return len;
-+}
-+
-+static ssize_t w100_write_reg(struct file *file, const char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ int len;
-+ unsigned long regs;
-+ unsigned long param;
-+
-+
-+ sscanf(buf,"%x %x",&regs,&param);
-+
-+ if (regs <= 0x2000){
-+ printk("Write regs 0x%08X : 0x%08X\n", regs, param);
-+ writel(param, remapped_regs+regs);
-+ }
-+
-+ len=strlen(buf);
-+ return len;
-+}
-+
-+static ssize_t lcd_read_param(struct file *file, char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ char outputbuf[50];
-+ int count;
-+ if (*ppos>0) /* Assume reading completed in previous read*/
-+ return 0;
-+ count = sprintf(outputbuf, "LCD parm %d.\n",lcd_param);
-+ *ppos += count;
-+ if (count>nbytes) /* Assume output can be read at one time */
-+ return -EINVAL;
-+ if (copy_to_user(buf, outputbuf, count))
-+ return -EFAULT;
-+ return count;
-+}
-+
-+static ssize_t lcd_write_param(struct file *file, const char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ int len;
-+ int param;
-+
-+ sscanf(buf,"%d",&param);
-+ printk("LCD param %d\n",param);
-+
-+ lcd_param=param;
-+
-+ len=strlen(buf);
-+ return len;
-+}
-+
-+static ssize_t fastsysclk_read_param(struct file *file, char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ char outputbuf[50];
-+ int count;
-+ if (*ppos>0) /* Assume reading completed in previous read*/
-+ return 0;
-+ count = sprintf(outputbuf, "Fastsysclk : %d.\n",fastsysclk_mode);
-+ *ppos += count;
-+ if (count>nbytes) /* Assume output can be read at one time */
-+ return -EINVAL;
-+ if (copy_to_user(buf, outputbuf, count))
-+ return -EFAULT;
-+ return count;
-+}
-+
-+static ssize_t fastsysclk_write_param(struct file *file, const char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ int len;
-+ int param;
-+
-+ sscanf(buf,"%d",&param);
-+ if (param == 75) {
-+ printk("Set fastsysclk %d\n",param);
-+ fastsysclk_mode=param;
-+ w100_SetFastSysClk(fastsysclk_mode);
-+ }else if (param == 100) {
-+ printk("Set fastsysclk %d\n",param);
-+ fastsysclk_mode=param;
-+ w100_SetFastSysClk(fastsysclk_mode);
-+ }
-+ len=strlen(buf);
-+ return len;
-+}
-+
-+static struct file_operations proc_read_reg = {
-+ write: w100_read_reg,
-+};
-+static struct file_operations proc_write_reg = {
-+ write: w100_write_reg,
-+};
-+static struct file_operations proc_rotation = {
-+ read: w100_read_rotation,
-+ write: w100_write_rotation,
-+};
-+static struct file_operations proc_lcd = {
-+ read: lcd_read_param,
-+ write: lcd_write_param,
-+};
-+static struct file_operations proc_fastsysclk = {
-+ read: fastsysclk_read_param,
-+ write: fastsysclk_write_param,
-+};
-+#endif
-+
- /* ------------------- chipset specific functions -------------------------- */
-
- //
-@@ -317,8 +500,12 @@
- // remap the areas we're going to use
- remapped_base = ioremap_nocache(W100_PHYS_ADDRESS, REMAPPED_CFG_LEN);
- remapped_regs = ioremap_nocache(W100_REG_BASE, REMAPPED_MMR_LEN);
-- remapped_fbuf = ioremap_nocache(W100_FB_BASE, REMAPPED_FB_LEN);
--
-+#if defined(CONFIG_CORGI_LCD_BUFF)
-+ remapped_fbuf = __ioremap(W100_FB_BASE, REMAPPED_FB_LEN, L_PTE_BUFFERABLE );
-+#else
-+ remapped_fbuf = ioremap_nocache(W100_FB_BASE, REMAPPED_FB_LEN);
-+#endif
-+
- isRemapped = 1;
- }
-
-@@ -385,7 +572,7 @@
-
- if (w100fb_lcdMode == LCD_MODE_UNKOWN){
- w100_InitExtMem(LCD_SHARP_VGA);
-- } else if(w100fb_lcdMode == LCD_MODE_480) {
-+ } else if( (w100fb_lcdMode == LCD_MODE_480) || (w100fb_lcdMode == LCD_MODE_640) ) {
- w100_InitExtMem(LCD_SHARP_VGA);
- } else {
- w100_InitExtMem(LCD_SHARP_QVGA);
-@@ -400,6 +587,76 @@
- writel((u32)(wrap_top_dir.val), remapped_regs+mmWRAP_TOP_DIR);
-
- writel((u32)0x2440, remapped_regs+mmRBBM_CNTL);
-+
-+#ifdef CONFIG_PROC_FS
-+ {
-+ struct proc_dir_entry *entry;
-+ if (proc_resume_mode == 0) {
-+
-+ proc_w100 = proc_mkdir("driver/w100", NULL);
-+ if (proc_w100 == NULL) {
-+ unregister_chrdev(228, "w100");
-+ printk(KERN_ERR "w100: can't create /proc/driver/w100\n");
-+ return -ENOMEM;
-+ }
-+
-+ entry = create_proc_entry("read_reg", S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, proc_w100);
-+ if (entry) {
-+ entry->proc_fops = &proc_read_reg;
-+ } else {
-+ remove_proc_entry("driver/w100", &proc_root);
-+ proc_w100 = 0;
-+ unregister_chrdev(228, "w100");
-+ printk(KERN_ERR "w100: can't create /proc/driver/w100/\n");
-+ return -ENOMEM;
-+ }
-+ entry = create_proc_entry("write_reg", S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, proc_w100);
-+ if (entry) {
-+ entry->proc_fops = &proc_write_reg;
-+ } else {
-+ remove_proc_entry("driver/w100", &proc_root);
-+ proc_w100 = 0;
-+ unregister_chrdev(228, "w100");
-+ printk(KERN_ERR "w100: can't create /proc/driver/w100/\n");
-+ return -ENOMEM;
-+ }
-+ entry = create_proc_entry("rotation", S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, proc_w100);
-+ if (entry) {
-+ entry->proc_fops = &proc_rotation;
-+ } else {
-+ remove_proc_entry("driver/w100", &proc_root);
-+ proc_w100 = 0;
-+ unregister_chrdev(228, "w100");
-+ printk(KERN_ERR "w100: can't create /proc/driver/w100/\n");
-+ return -ENOMEM;
-+ }
-+
-+ entry = create_proc_entry("lcd", S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, proc_w100);
-+ if (entry) {
-+ entry->proc_fops = &proc_lcd;
-+ } else {
-+ remove_proc_entry("driver/w100", &proc_root);
-+ proc_w100 = 0;
-+ unregister_chrdev(228, "w100");
-+ printk(KERN_ERR "w100: can't create /proc/driver/w100/\n");
-+ return -ENOMEM;
-+ }
-+
-+ entry = create_proc_entry("fastsysclk", S_IWUSR |S_IRUSR | S_IRGRP | S_IROTH, proc_w100);
-+ if (entry) {
-+ entry->proc_fops = &proc_fastsysclk;
-+ } else {
-+ remove_proc_entry("driver/w100", &proc_root);
-+ proc_w100 = 0;
-+ unregister_chrdev(228, "w100");
-+ printk(KERN_ERR "w100: can't create /proc/driver/w100/\n");
-+ return -ENOMEM;
-+ }
-+ }
-+ }
-+
-+#endif
-+
- }
-
- //
-@@ -453,9 +710,11 @@
- #endif
-
- fix->smem_start = W100_FB_BASE;
--
-- if(w100fb_lcdMode == LCD_MODE_UNKOWN || w100fb_lcdMode == LCD_MODE_480){
--
-+#if defined(CONFIG_FBCON_ROTATE_R)
-+ if(w100fb_lcdMode == LCD_MODE_UNKOWN || w100fb_lcdMode == LCD_MODE_480 ){
-+#else
-+ if(w100fb_lcdMode == LCD_MODE_480 ){
-+#endif
- fix->line_length = (480 * BITS_PER_PIXEL) / 8;
- fix->smem_len = 0x200000;
-
-@@ -468,6 +727,13 @@
-
- fix->line_length = (240 * BITS_PER_PIXEL) / 8;
- fix->smem_len = 0x60000;
-+#if defined(CONFIG_FBCON_ROTATE_R)
-+ } else if(w100fb_lcdMode == LCD_MODE_640){
-+#else
-+ } else if(w100fb_lcdMode == LCD_MODE_UNKOWN || w100fb_lcdMode == LCD_MODE_640){
-+#endif
-+ fix->line_length = (640 * BITS_PER_PIXEL) / 8;
-+ fix->smem_len = 0x200000;
-
- }
-
-@@ -494,13 +760,19 @@
- BUG();
-
- if((par->xres == 480 && par->yres == 640)||
-+ (par->xres == 640 && par->yres == 480)||
- (par->xres == 320 && par->yres == 240)||
- (par->xres == 240 && par->yres == 320)){
- par->xres = var->xres;
- par->yres = var->yres;
- }else{
-- par->xres = MAX_XRES;
-- par->yres = MAX_YRES;
-+#if defined(CONFIG_FBCON_ROTATE_R)
-+ par->xres = 480;
-+ par->yres = 640;
-+#else
-+ par->xres = 640;
-+ par->yres = 480;
-+#endif
- }
-
- par->xres_virtual =
-@@ -547,13 +819,19 @@
-
- // set up screen coordinates
- if((par->xres == 480 && par->yres == 640)||
-+ (par->xres == 640 && par->yres == 480)||
- (par->xres == 320 && par->yres == 240)||
- (par->xres == 240 && par->yres == 320)){
- var->xres = par->xres;
- var->yres = par->yres;
- }else{
-- var->xres = MAX_XRES;
-- var->yres = MAX_YRES;
-+#if defined(CONFIG_FBCON_ROTATE_R)
-+ var->xres = 480;
-+ var->yres = 640;
-+#else
-+ var->xres = 640;
-+ var->yres = 480;
-+#endif
- }
-
- var->xres_virtual = var->xres;
-@@ -851,7 +1129,7 @@
- w100_vsync();
- w100_suspend(W100_SUSPEND_EXTMEM);
- w100_init_sharp_lcd(LCD_SHARP_QVGA);
-- w100_init_qvga_rotation( (u16)270 );
-+ w100_init_qvga_rotation( w100fb_rotation_flag );
- w100_InitExtMem(LCD_SHARP_QVGA);
- w100_clear_screen(LCD_SHARP_QVGA,NULL);
- lcdtg_lcd_change(LCD_SHARP_QVGA);
-@@ -873,6 +1151,70 @@
-
- w100fb_lcdMode = LCD_MODE_240;
-
-+ }else if(current_par.xres == 640 && current_par.yres == 480){
-+
-+ printk("change resolution 480x640 => 640x480\n");
-+
-+ w100_PwmSetup();
-+ w100_clear_screen(LCD_SHARP_QVGA,NULL);
-+ writel(0xBFFFA000, remapped_regs+mmMC_EXT_MEM_LOCATION);
-+ w100_InitExtMem(LCD_SHARP_VGA);
-+ w100_clear_screen(LCD_SHARP_VGA,(void*)0xF1A00000);
-+ w100_vsync();
-+ w100_init_sharp_lcd(LCD_SHARP_VGA);
-+ w100_init_vga_rotation( (u16)90 );
-+ lcdtg_lcd_change(LCD_SHARP_VGA);
-+
-+ w100fb_lcdMode = LCD_MODE_640;
-+
-+ }
-+ break;
-+ case LCD_MODE_640:
-+ if(current_par.xres == 320 && current_par.yres == 240){
-+
-+ printk("change resolution 640x480 => 320x240\n");
-+
-+ w100_PwmSetup();
-+ w100_vsync();
-+ w100_suspend(W100_SUSPEND_EXTMEM);
-+ w100_init_sharp_lcd(LCD_SHARP_QVGA);
-+ w100_init_qvga_rotation( w100fb_rotation_flag );
-+ w100_InitExtMem(LCD_SHARP_QVGA);
-+ w100_clear_screen(LCD_SHARP_QVGA,NULL);
-+ lcdtg_lcd_change(LCD_SHARP_QVGA);
-+
-+ w100fb_lcdMode = LCD_MODE_320;
-+
-+ }else if(current_par.xres == 240 && current_par.yres == 320){
-+
-+ printk("change resolution 640x480 => 240x320\n");
-+
-+ w100_PwmSetup();
-+ w100_vsync();
-+ w100_suspend(W100_SUSPEND_EXTMEM);
-+ w100_init_sharp_lcd(LCD_SHARP_QVGA);
-+ w100_init_qvga_rotation( (u16)0 );
-+ w100_InitExtMem(LCD_SHARP_QVGA);
-+ w100_clear_screen(LCD_SHARP_QVGA,NULL);
-+ lcdtg_lcd_change(LCD_SHARP_QVGA);
-+
-+ w100fb_lcdMode = LCD_MODE_240;
-+
-+ }else if(current_par.xres == 480 && current_par.yres == 640){
-+
-+ printk("change resolution 640x480 => 480x640\n");
-+
-+ w100_PwmSetup();
-+ w100_clear_screen(LCD_SHARP_QVGA,NULL);
-+ writel(0xBFFFA000, remapped_regs+mmMC_EXT_MEM_LOCATION);
-+ w100_InitExtMem(LCD_SHARP_VGA);
-+ w100_clear_screen(LCD_SHARP_VGA,(void*)0xF1A00000);
-+ w100_vsync();
-+ w100_init_sharp_lcd(LCD_SHARP_VGA);
-+ lcdtg_lcd_change(LCD_SHARP_VGA);
-+
-+ w100fb_lcdMode = LCD_MODE_480;
-+
- }
- break;
- case LCD_MODE_240:
-@@ -891,12 +1233,28 @@
-
- w100fb_lcdMode = LCD_MODE_480;
-
-+ }else if(current_par.xres == 640 && current_par.yres == 480){
-+
-+ printk("change resolution 240x320 => 640x480\n");
-+
-+ w100_PwmSetup();
-+ w100_clear_screen(LCD_SHARP_QVGA,NULL);
-+ writel(0xBFFFA000, remapped_regs+mmMC_EXT_MEM_LOCATION);
-+ w100_InitExtMem(LCD_SHARP_VGA);
-+ w100_clear_screen(LCD_SHARP_VGA,(void*)0xF1A00000);
-+ w100_vsync();
-+ w100_init_sharp_lcd(LCD_SHARP_VGA);
-+ w100_init_vga_rotation( (u16)90 );
-+ lcdtg_lcd_change(LCD_SHARP_VGA);
-+
-+ w100fb_lcdMode = LCD_MODE_640;
-+
- }else if(current_par.xres == 320 && current_par.yres == 240){
-
- printk("change resolution 240x320 => 320x240\n");
-
- w100_clear_screen(LCD_SHARP_QVGA,NULL);
-- w100_init_qvga_rotation( (u16)270 );
-+ w100_init_qvga_rotation( w100fb_rotation_flag );
-
- w100fb_lcdMode = LCD_MODE_320;
- }
-@@ -917,6 +1275,22 @@
-
- w100fb_lcdMode = LCD_MODE_480;
-
-+ }else if(current_par.xres == 640 && current_par.yres == 480){
-+
-+ printk("change resolution 320x240 => 640x480\n");
-+
-+ w100_PwmSetup();
-+ w100_clear_screen(LCD_SHARP_QVGA,NULL);
-+ writel(0xBFFFA000, remapped_regs+mmMC_EXT_MEM_LOCATION);
-+ w100_InitExtMem(LCD_SHARP_VGA);
-+ w100_clear_screen(LCD_SHARP_VGA,(void*)0xF1A00000);
-+ w100_vsync();
-+ w100_init_sharp_lcd(LCD_SHARP_VGA);
-+ w100_init_vga_rotation( (u16)90 );
-+ lcdtg_lcd_change(LCD_SHARP_VGA);
-+
-+ w100fb_lcdMode = LCD_MODE_640;
-+
- }else if(current_par.xres == 240 && current_par.yres == 320){
-
- printk("change resolution 320x240 => 240x320\n");
-@@ -928,9 +1302,16 @@
- }
- break;
- case LCD_MODE_UNKOWN:
-- printk("reset resolution unkown => 480x640\n");
-- w100_init_sharp_lcd(LCD_SHARP_VGA);
-+#if defined(CONFIG_FBCON_ROTATE_R)
-+ printk("reset resolution unkown => 480x640\n");
-+ w100_init_sharp_lcd(LCD_SHARP_VGA);
- w100fb_lcdMode = LCD_MODE_480;
-+#else
-+ printk("reset resolution unkown => 640x480\n");
-+ w100_init_sharp_lcd(LCD_SHARP_VGA);
-+ w100_init_vga_rotation( (u16)90 );
-+ w100fb_lcdMode = LCD_MODE_640;
-+#endif
- isInitTG = 1;
- break;
- default:
-@@ -992,14 +1373,16 @@
- #if defined(CONFIG_FBCON_ROTATE_R) || defined(CONFIG_FBCON_ROTATE_L)
- disp->xpanstep = 0;
- disp->xwrapstep = 0;
-- disp->scrollmode = 0; // for logoscreen scroll
-+ disp->scrollmode = SCROLL_XREDRAW;
- #else
- disp->ypanstep = 0;
- disp->ywrapstep = 0;
-+ disp->scrollmode = SCROLL_YREDRAW;
- #endif
-
- switch(w100fb_lcdMode){
- case LCD_MODE_480:
-+ case LCD_MODE_640:
- if(isInitTG != 0)
- lcdtg_hw_init(LCD_SHARP_VGA);
- break;
-@@ -1267,7 +1650,149 @@
- end_skip_save_image_no = (-1);
- return 0;
- }
-+ break;
- #endif //_IMAGE_CACHE_SUPPORT
-+ case 100: //change 480x640
-+ printk("[w100fb] set 480x640 (VGA 0 degree)\n");
-+
-+ w100_PwmSetup();
-+ w100_clear_screen(LCD_SHARP_QVGA,NULL);
-+ writel(0xBFFFA000, remapped_regs+mmMC_EXT_MEM_LOCATION);
-+ w100_InitExtMem(LCD_SHARP_VGA);
-+ w100_clear_screen(LCD_SHARP_VGA,(void*)0xF1A00000);
-+ w100_vsync();
-+ w100_init_sharp_lcd(LCD_SHARP_VGA);
-+ w100_init_vga_rotation( (u16)0 );
-+ lcdtg_lcd_change(LCD_SHARP_VGA);
-+
-+ break;
-+ case 101: //change 640x480
-+ printk("[w100fb] set 640x480 (VGA 90 degree)\n");
-+
-+ w100_PwmSetup();
-+ w100_clear_screen(LCD_SHARP_QVGA,NULL);
-+ writel(0xBFFFA000, remapped_regs+mmMC_EXT_MEM_LOCATION);
-+ w100_InitExtMem(LCD_SHARP_VGA);
-+ w100_clear_screen(LCD_SHARP_VGA,(void*)0xF1A00000);
-+ w100_vsync();
-+ w100_init_sharp_lcd(LCD_SHARP_VGA);
-+ w100_init_vga_rotation( (u16)90 );
-+ lcdtg_lcd_change(LCD_SHARP_VGA);
-+
-+ break;
-+ case 102: //change 480x640
-+ printk("[w100fb] set 480x640 (VGA 180 degree)\n");
-+
-+ w100_PwmSetup();
-+ w100_clear_screen(LCD_SHARP_QVGA,NULL);
-+ writel(0xBFFFA000, remapped_regs+mmMC_EXT_MEM_LOCATION);
-+ w100_InitExtMem(LCD_SHARP_VGA);
-+ w100_clear_screen(LCD_SHARP_VGA,(void*)0xF1A00000);
-+ w100_vsync();
-+ w100_init_sharp_lcd(LCD_SHARP_VGA);
-+ w100_init_vga_rotation( (u16)180 );
-+ lcdtg_lcd_change(LCD_SHARP_VGA);
-+
-+ break;
-+ case 103: //change 640x480
-+ printk("[w100fb] set 640x480 (VGA 270 degree)\n");
-+
-+ w100_PwmSetup();
-+ w100_clear_screen(LCD_SHARP_QVGA,NULL);
-+ writel(0xBFFFA000, remapped_regs+mmMC_EXT_MEM_LOCATION);
-+ w100_InitExtMem(LCD_SHARP_VGA);
-+ w100_clear_screen(LCD_SHARP_VGA,(void*)0xF1A00000);
-+ w100_vsync();
-+ w100_init_sharp_lcd(LCD_SHARP_VGA);
-+ w100_init_vga_rotation( (u16)270 );
-+ lcdtg_lcd_change(LCD_SHARP_VGA);
-+
-+ break;
-+ case 110: //change 240x320
-+ printk("[w100fb] set 240x320 (QVGA 0 degree)\n");
-+
-+ w100_PwmSetup();
-+ w100_vsync();
-+ w100_suspend(W100_SUSPEND_EXTMEM);
-+ w100_init_sharp_lcd(LCD_SHARP_QVGA);
-+ w100_init_qvga_rotation( (u16)0 );
-+ w100_InitExtMem(LCD_SHARP_QVGA);
-+ w100_clear_screen(LCD_SHARP_QVGA,NULL);
-+ lcdtg_lcd_change(LCD_SHARP_QVGA);
-+
-+ break;
-+ case 111: //change 320x240
-+ printk("[w100fb] set 320x240 (QVGA 90 degree)\n");
-+
-+ w100fb_rotation_flag=90;
-+ w100_PwmSetup();
-+ w100_vsync();
-+ w100_suspend(W100_SUSPEND_EXTMEM);
-+ w100_init_sharp_lcd(LCD_SHARP_QVGA);
-+ w100_init_qvga_rotation(w100fb_rotation_flag);
-+ w100_InitExtMem(LCD_SHARP_QVGA);
-+ w100_clear_screen(LCD_SHARP_QVGA,NULL);
-+ lcdtg_lcd_change(LCD_SHARP_QVGA);
-+
-+ break;
-+
-+ case 112: //change 240x320
-+ printk("[w100fb] set 240x320 (QVGA 180 degree)\n");
-+
-+ w100_PwmSetup();
-+ w100_vsync();
-+ w100_suspend(W100_SUSPEND_EXTMEM);
-+ w100_init_sharp_lcd(LCD_SHARP_QVGA);
-+ w100_init_qvga_rotation( (u16)180 );
-+ w100_InitExtMem(LCD_SHARP_QVGA);
-+ w100_clear_screen(LCD_SHARP_QVGA,NULL);
-+ lcdtg_lcd_change(LCD_SHARP_QVGA);
-+
-+ break;
-+ case 113: //change 320x240
-+ printk("[w100fb] set 320x240 (QVGA 270 degree)\n");
-+
-+ w100fb_rotation_flag=270;
-+ w100_PwmSetup();
-+ w100_vsync();
-+ w100_suspend(W100_SUSPEND_EXTMEM);
-+ w100_init_sharp_lcd(LCD_SHARP_QVGA);
-+ w100_init_qvga_rotation(w100fb_rotation_flag);
-+ w100_InitExtMem(LCD_SHARP_QVGA);
-+ w100_clear_screen(LCD_SHARP_QVGA,NULL);
-+ lcdtg_lcd_change(LCD_SHARP_QVGA);
-+
-+ break;
-+ case 120: //non rotation in QVGA
-+ printk("[w100fb] set rotation 0 in QVGA\n");
-+
-+ w100fb_rotation_flag = 270;
-+ if (w100fb_lcdMode == LCD_MODE_320)
-+ w100_init_qvga_rotation(w100fb_rotation_flag);
-+
-+ break;
-+ case 121: //rotation 180 degree in QVGA
-+ printk("[w100fb] set rotation 180 in QVGA\n");
-+
-+ w100fb_rotation_flag = 90;
-+ if (w100fb_lcdMode == LCD_MODE_320)
-+ w100_init_qvga_rotation(w100fb_rotation_flag);
-+
-+ break;
-+ case 130: //Fastsysclock 75MHz
-+ printk("[w100fb] set Fastsysclk 75MHz\n");
-+
-+ fastsysclk_mode=75;
-+ w100_SetFastSysClk(fastsysclk_mode);
-+
-+ break;
-+ case 131: //Fastsysclock 100MHz
-+ printk("[w100fb] set Fastsysclk 100MHz\n");
-+
-+ fastsysclk_mode=100;
-+ w100_SetFastSysClk(fastsysclk_mode);
-+
-+ break;
- default:
- break;
- }
-@@ -2348,6 +2873,8 @@
- { 50, 0, 1, 0, 0xE0, 56}, // 50.00 MHz
- { 75, 0, 5, 0, 0xDE, 37}, // 75.00 MHz
- {100, 0, 7, 0, 0xE0, 28}, // 100.00 MHz
-+ {125, 0, 9, 0, 0xE0, 22}, // 125.00 MHz
-+ {150, 0, 11, 0, 0xE0, 17}, // 150.00 MHz
- { 0, 0, 0, 0, 0, 0} // Terminator
- };
- #else
-@@ -2779,7 +3306,8 @@
- break;
- case LCD_SHARP_VGA:
- w100_SetSlowSysClk(12); // use crystal -- 12.5MHz
-- w100_SetFastSysClk(75); // use PLL -- 75.0MHz
-+ w100_SetFastSysClk(fastsysclk_mode);
-+
- gPowerState.pclk_cntl.f.pclk_src_sel = 0x1;
- gPowerState.pclk_cntl.f.pclk_post_div = 0x2;
- writel((u32)(gPowerState.pclk_cntl.val), remapped_regs+mmPCLK_CNTL);
-@@ -2836,6 +3364,72 @@
- writel((u32)(disp_db_buf_wr_cntl.val), remapped_regs+mmDISP_DB_BUF_CNTL);
- } // w100_init_sharp_lcd
-
-+static void w100_init_vga_rotation(u16 deg)
-+{
-+ // for resolution change and rotation
-+ // GRAPHIC_CTRL
-+ // GRAPHIC_OFFSET
-+ // GRAPHIC_PITCH
-+
-+ switch(deg){
-+ case 0:
-+ gPowerState.pclk_cntl.f.pclk_src_sel = 0x1;
-+ gPowerState.pclk_cntl.f.pclk_post_div = 0x2;
-+ writel((u32)(gPowerState.pclk_cntl.val), remapped_regs+mmPCLK_CNTL);
-+
-+ writel(0x00DE1D66, remapped_regs+mmGRAPHIC_CTRL);
-+ writel(0x00800000, remapped_regs+mmGRAPHIC_OFFSET);
-+ writel(0x000003c0, remapped_regs+mmGRAPHIC_PITCH);
-+
-+ // Re-enable display updates
-+ writel(0x0000007b, remapped_regs+mmDISP_DB_BUF_CNTL);
-+
-+ break;
-+ case 90:
-+ gPowerState.pclk_cntl.f.pclk_src_sel = 0x1;
-+ gPowerState.pclk_cntl.f.pclk_post_div = 0x6;
-+ writel((u32)(gPowerState.pclk_cntl.val), remapped_regs+mmPCLK_CNTL);
-+
-+ writel(0x00DE1D0e, remapped_regs+mmGRAPHIC_CTRL);
-+ writel(0x00895b00, remapped_regs+mmGRAPHIC_OFFSET);
-+ writel(0x00000500, remapped_regs+mmGRAPHIC_PITCH);
-+
-+ // Re-enable display updates
-+ writel(0x0000007b, remapped_regs+mmDISP_DB_BUF_CNTL);
-+
-+ break;
-+ case 180:
-+ gPowerState.pclk_cntl.f.pclk_src_sel = 0x1;
-+ gPowerState.pclk_cntl.f.pclk_post_div = 0x2;
-+ writel((u32)(gPowerState.pclk_cntl.val), remapped_regs+mmPCLK_CNTL);
-+
-+ writel(0x00DE1D7e, remapped_regs+mmGRAPHIC_CTRL);
-+ writel(0x00895ffc, remapped_regs+mmGRAPHIC_OFFSET);
-+ writel(0x000003c0, remapped_regs+mmGRAPHIC_PITCH);
-+
-+ // Re-enable display updates
-+ writel(0x0000007b, remapped_regs+mmDISP_DB_BUF_CNTL);
-+
-+ break;
-+ case 270:
-+ gPowerState.pclk_cntl.f.pclk_src_sel = 0x1;
-+ gPowerState.pclk_cntl.f.pclk_post_div = 0x6;
-+ writel((u32)(gPowerState.pclk_cntl.val), remapped_regs+mmPCLK_CNTL);
-+
-+ writel(0x00DE1D16, remapped_regs+mmGRAPHIC_CTRL);
-+ writel(0x008004fc, remapped_regs+mmGRAPHIC_OFFSET);
-+ writel(0x00000500, remapped_regs+mmGRAPHIC_PITCH);
-+
-+ // Re-enable display updates
-+ writel(0x0000007b, remapped_regs+mmDISP_DB_BUF_CNTL);
-+
-+ break;
-+ default:
-+ // not-support
-+ break;
-+ }
-+}
-+
- static void w100_init_qvga_rotation(u16 deg)
- {
- // for resolution change and rotation
-@@ -2848,12 +3442,38 @@
- writel(0x00d41c06, remapped_regs+mmGRAPHIC_CTRL);
- writel(0x00800000, remapped_regs+mmGRAPHIC_OFFSET);
- writel(0x000001e0, remapped_regs+mmGRAPHIC_PITCH);
-+
-+ // Re-enable display updates
-+ writel(0x0000007b, remapped_regs+mmDISP_DB_BUF_CNTL);
-+
-+ break;
-+ case 90:
-+ writel(0x00d41c0E, remapped_regs+mmGRAPHIC_CTRL);
-+ //writel(0x0080027e, remapped_regs+mmGRAPHIC_OFFSET);
-+ writel(0x00825580, remapped_regs+mmGRAPHIC_OFFSET);
-+ writel(0x00000280, remapped_regs+mmGRAPHIC_PITCH);
-+
-+ // Re-enable display updates
-+ writel(0x0000007b, remapped_regs+mmDISP_DB_BUF_CNTL);
-+
-+ break;
-+ case 180:
-+ writel(0x00d41c1e, remapped_regs+mmGRAPHIC_CTRL);
-+ writel(0x008257fc, remapped_regs+mmGRAPHIC_OFFSET);
-+ writel(0x000001e0, remapped_regs+mmGRAPHIC_PITCH);
-+
-+ // Re-enable display updates
-+ writel(0x0000007b, remapped_regs+mmDISP_DB_BUF_CNTL);
-+
- break;
- case 270:
- writel(0x00d41c16, remapped_regs+mmGRAPHIC_CTRL);
- //writel(0x0080027e, remapped_regs+mmGRAPHIC_OFFSET);
- writel(0x0080027c, remapped_regs+mmGRAPHIC_OFFSET);
- writel(0x00000280, remapped_regs+mmGRAPHIC_PITCH);
-+
-+ // Re-enable display updates
-+ writel(0x0000007b, remapped_regs+mmDISP_DB_BUF_CNTL);
- break;
- default:
- // not-support
-@@ -2920,6 +3540,7 @@
- {
- u32 temp32;
-
-+ proc_resume_mode=1;
- w100_hw_init();
- w100_PwmSetup();
-
-@@ -2928,13 +3549,16 @@
- temp32 |= 0x00800000;
- writel(temp32, remapped_regs+mmDISP_DEBUG2);
-
-- if (w100fb_lcdMode == LCD_MODE_480) {
-+ if (w100fb_lcdMode == LCD_MODE_480 || w100fb_lcdMode == LCD_MODE_640) {
- w100_init_sharp_lcd(LCD_SHARP_VGA);
-+ if (w100fb_lcdMode == LCD_MODE_640) {
-+ w100_init_vga_rotation( (u16)90 );
-+ }
- }
- else {
- w100_init_sharp_lcd(LCD_SHARP_QVGA);
- if (w100fb_lcdMode == LCD_MODE_320) {
-- w100_init_qvga_rotation( (u16)270 );
-+ w100_init_qvga_rotation( w100fb_rotation_flag );
- }
- }
-
-@@ -3269,7 +3893,7 @@
-
- static void lcdtg_resume()
- {
-- if (w100fb_lcdMode == LCD_MODE_480) {
-+ if (w100fb_lcdMode == LCD_MODE_480 || w100fb_lcdMode == LCD_MODE_640) {
- lcdtg_hw_init(LCD_SHARP_VGA);
- }
- else {
-@@ -3379,7 +4003,7 @@
- break;
- case LCD_SHARP_VGA:
- /* Set Lcd Resolution (VGA) */
-- lcdtg_ssp_send( RESCTL_ADRS, RESCTL_VGA );
-+ lcdtg_ssp_send( RESCTL_ADRS, lcd_param );
- break;
- default:
- break;
-@@ -3393,7 +4017,7 @@
-
- if(mode == LCD_SHARP_VGA)
- /* Set Lcd Resolution (VGA) */
-- lcdtg_ssp_send( RESCTL_ADRS, RESCTL_VGA );
-+ lcdtg_ssp_send( RESCTL_ADRS, lcd_param );
- else if(mode == LCD_SHARP_QVGA)
- /* Set Lcd Resolution (QVGA) */
- lcdtg_ssp_send( RESCTL_ADRS, RESCTL_QVGA );
-@@ -3659,6 +4283,8 @@
- int i, j;
- u16 *pVram = (u16*)remapped_fbuf;
-
-+
-+
- if(suspend_mode == 1){
- // called from blank()
- isSuspended_tg_only = 1;
-diff -Nur linux_c860_org/fs/adfs/map.c linux/fs/adfs/map.c
---- linux_c860_org/fs/adfs/map.c 2002-08-26 14:43:25.000000000 +0900
-+++ linux/fs/adfs/map.c 2004-06-10 21:09:11.000000000 +0900
-@@ -12,6 +12,7 @@
- #include <linux/fs.h>
- #include <linux/adfs_fs.h>
- #include <linux/spinlock.h>
-+#include <linux/sched.h>
-
- #include <asm/unaligned.h>
-
-diff -Nur linux_c860_org/fs/buffer.c linux/fs/buffer.c
---- linux_c860_org/fs/buffer.c 2002-08-29 12:24:14.000000000 +0900
-+++ linux/fs/buffer.c 2004-06-10 21:09:11.000000000 +0900
-@@ -267,6 +267,11 @@
- }
- if (dev && bh->b_dev != dev)
- continue;
-+ if (conditional_schedule_needed()) {
-+ debug_lock_break(1);
-+ spin_unlock(&lru_list_lock);
-+ return -EAGAIN;
-+ }
-
- get_bh(bh);
- spin_unlock(&lru_list_lock);
-@@ -696,6 +701,13 @@
- /* Not hashed? */
- if (!bh->b_pprev)
- continue;
-+ if (conditional_schedule_needed()) {
-+ debug_lock_break(2); /* bkl is held too */
-+ get_bh(bh);
-+ break_spin_lock_and_resched(&lru_list_lock);
-+ put_bh(bh);
-+ slept = 1;
-+ }
- if (buffer_locked(bh)) {
- get_bh(bh);
- spin_unlock(&lru_list_lock);
-@@ -847,6 +859,8 @@
- struct buffer_head *bh;
- struct inode tmp;
- int err = 0, err2;
-+
-+ DEFINE_LOCK_COUNT();
-
- INIT_LIST_HEAD(&tmp.i_dirty_buffers);
-
-@@ -868,6 +882,12 @@
- spin_lock(&lru_list_lock);
- }
- }
-+ /* haven't hit this code path ... */
-+ debug_lock_break(551);
-+ if (TEST_LOCK_COUNT(32)) {
-+ RESET_LOCK_COUNT();
-+ break_spin_lock(&lru_list_lock);
-+ }
- }
-
- while (!list_empty(&tmp.i_dirty_buffers)) {
-@@ -897,6 +917,7 @@
- struct inode tmp;
- int err = 0, err2;
-
-+ DEFINE_LOCK_COUNT();
- INIT_LIST_HEAD(&tmp.i_dirty_data_buffers);
-
- spin_lock(&lru_list_lock);
-@@ -928,9 +949,14 @@
- if (!buffer_uptodate(bh))
- err = -EIO;
- brelse(bh);
-+ debug_lock_break(1);
-+ if (TEST_LOCK_COUNT(32)) {
-+ RESET_LOCK_COUNT();
-+ conditional_schedule();
-+ }
- spin_lock(&lru_list_lock);
- }
--
-+
- spin_unlock(&lru_list_lock);
- err2 = osync_inode_data_buffers(inode);
-
-@@ -957,6 +983,8 @@
- struct list_head *list;
- int err = 0;
-
-+ DEFINE_LOCK_COUNT();
-+
- spin_lock(&lru_list_lock);
-
- repeat:
-@@ -964,6 +992,17 @@
- for (list = inode->i_dirty_buffers.prev;
- bh = BH_ENTRY(list), list != &inode->i_dirty_buffers;
- list = bh->b_inode_buffers.prev) {
-+ /* untested code path ... */
-+ debug_lock_break(551);
-+
-+ if (TEST_LOCK_COUNT(32)) {
-+ RESET_LOCK_COUNT();
-+ if (conditional_schedule_needed()) {
-+ break_spin_lock(&lru_list_lock);
-+ goto repeat;
-+ }
-+ }
-+
- if (buffer_locked(bh)) {
- get_bh(bh);
- spin_unlock(&lru_list_lock);
-diff -Nur linux_c860_org/fs/dcache.c linux/fs/dcache.c
---- linux_c860_org/fs/dcache.c 2002-08-26 14:37:31.000000000 +0900
-+++ linux/fs/dcache.c 2004-06-10 21:09:11.000000000 +0900
-@@ -320,11 +320,24 @@
-
- void prune_dcache(int count)
- {
-+ DEFINE_LOCK_COUNT();
-+
- spin_lock(&dcache_lock);
-+
-+redo:
- for (;;) {
- struct dentry *dentry;
- struct list_head *tmp;
-
-+ if (TEST_LOCK_COUNT(100)) {
-+ RESET_LOCK_COUNT();
-+ debug_lock_break(1);
-+ if (conditional_schedule_needed()) {
-+ break_spin_lock(&dcache_lock);
-+ goto redo;
-+ }
-+ }
-+
- tmp = dentry_unused.prev;
-
- if (tmp == &dentry_unused)
-@@ -480,6 +493,8 @@
- struct list_head *next;
- int found = 0;
-
-+ DEFINE_LOCK_COUNT();
-+
- spin_lock(&dcache_lock);
- repeat:
- next = this_parent->d_subdirs.next;
-@@ -493,6 +508,12 @@
- list_add(&dentry->d_lru, dentry_unused.prev);
- found++;
- }
-+ if (TEST_LOCK_COUNT(500) && found > 10) {
-+ debug_lock_break(1);
-+ if (conditional_schedule_needed())
-+ goto out;
-+ RESET_LOCK_COUNT();
-+ }
- /*
- * Descend a level if the d_subdirs list is non-empty.
- */
-@@ -517,6 +538,7 @@
- #endif
- goto resume;
- }
-+out:
- spin_unlock(&dcache_lock);
- return found;
- }
-diff -Nur linux_c860_org/fs/exec.c linux/fs/exec.c
---- linux_c860_org/fs/exec.c 2003-06-18 16:12:27.000000000 +0900
-+++ linux/fs/exec.c 2004-06-10 21:09:11.000000000 +0900
-@@ -469,8 +469,8 @@
- active_mm = current->active_mm;
- current->mm = mm;
- current->active_mm = mm;
-- task_unlock(current);
- activate_mm(active_mm, mm);
-+ task_unlock(current);
- mm_release();
- if (old_mm) {
- if (active_mm != old_mm) BUG();
-@@ -631,8 +631,10 @@
-
- current->sas_ss_sp = current->sas_ss_size = 0;
-
-- if (current->euid == current->uid && current->egid == current->gid)
-+ if (current->euid == current->uid && current->egid == current->gid) {
- current->mm->dumpable = 1;
-+ current->task_dumpable = 1;
-+ }
- name = bprm->filename;
- for (i=0; (ch = *(name++)) != '\0';) {
- if (ch == '/')
-@@ -1024,7 +1026,7 @@
- binfmt = current->binfmt;
- if (!binfmt || !binfmt->core_dump)
- goto fail;
-- if (!current->mm->dumpable)
-+ if (!is_dumpable(current))
- goto fail;
- current->mm->dumpable = 0;
- if (current->rlim[RLIMIT_CORE].rlim_cur < binfmt->min_coredump)
-diff -Nur linux_c860_org/fs/ext3/inode.c linux/fs/ext3/inode.c
---- linux_c860_org/fs/ext3/inode.c 2002-08-26 14:37:42.000000000 +0900
-+++ linux/fs/ext3/inode.c 2004-06-10 21:09:11.000000000 +0900
-@@ -1649,6 +1649,8 @@
- }
-
- for (p = first; p < last; p++) {
-+ debug_lock_break(1); /* bkl is held */
-+ conditional_schedule();
- nr = le32_to_cpu(*p);
- if (nr) {
- /* accumulate blocks to free if they're contiguous */
-@@ -1714,6 +1716,9 @@
- /* Go read the buffer for the next level down */
- bh = sb_bread(inode->i_sb, nr);
-
-+ debug_lock_break(1);
-+ conditional_schedule();
-+
- /*
- * A read failure? Report error and clear slot
- * (should be rare).
-diff -Nur linux_c860_org/fs/ext3/namei.c linux/fs/ext3/namei.c
---- linux_c860_org/fs/ext3/namei.c 2002-08-26 14:43:28.000000000 +0900
-+++ linux/fs/ext3/namei.c 2004-06-10 21:09:11.000000000 +0900
-@@ -157,6 +157,8 @@
- if ((bh = bh_use[ra_ptr++]) == NULL)
- goto next;
- wait_on_buffer(bh);
-+ debug_lock_break(1);
-+ conditional_schedule();
- if (!buffer_uptodate(bh)) {
- /* read error, skip block & hope for the best */
- brelse(bh);
-diff -Nur linux_c860_org/fs/fat/cache.c linux/fs/fat/cache.c
---- linux_c860_org/fs/fat/cache.c 2002-08-29 12:24:17.000000000 +0900
-+++ linux/fs/fat/cache.c 2004-06-10 21:09:11.000000000 +0900
-@@ -17,6 +17,7 @@
- #include <linux/string.h>
- #include <linux/stat.h>
- #include <linux/fat_cvf.h>
-+#include <linux/sched.h>
-
- #if 0
- # define PRINTK(x) printk x
-diff -Nur linux_c860_org/fs/inode.c linux/fs/inode.c
---- linux_c860_org/fs/inode.c 2002-11-22 21:03:26.000000000 +0900
-+++ linux/fs/inode.c 2004-06-10 21:09:11.000000000 +0900
-@@ -589,6 +589,12 @@
- if (tmp == head)
- break;
- inode = list_entry(tmp, struct inode, i_list);
-+
-+ debug_lock_break(2); /* bkl is also held */
-+ atomic_inc(&inode->i_count);
-+ break_spin_lock_and_resched(&inode_lock);
-+ atomic_dec(&inode->i_count);
-+
- if (inode->i_sb != sb)
- continue;
- invalidate_inode_buffers(inode);
-@@ -699,8 +705,11 @@
- #endif
- #endif
-
-+ DEFINE_LOCK_COUNT();
-+
- spin_lock(&inode_lock);
-
-+free_unused:
- count = 0;
- entry = inode_unused.prev;
- while (entry != &inode_unused)
-@@ -736,6 +745,14 @@
- count++;
- if (!--goal)
- break;
-+ if (TEST_LOCK_COUNT(32)) {
-+ RESET_LOCK_COUNT();
-+ debug_lock_break(1);
-+ if (conditional_schedule_needed()) {
-+ break_spin_lock(&inode_lock);
-+ goto free_unused;
-+ }
-+ }
- }
- inodes_stat.nr_unused -= count;
- spin_unlock(&inode_lock);
-diff -Nur linux_c860_org/fs/jbd/commit.c linux/fs/jbd/commit.c
---- linux_c860_org/fs/jbd/commit.c 2002-08-26 14:37:42.000000000 +0900
-+++ linux/fs/jbd/commit.c 2004-06-10 21:09:11.000000000 +0900
-@@ -212,6 +212,9 @@
- __journal_remove_journal_head(bh);
- refile_buffer(bh);
- __brelse(bh);
-+ debug_lock_break(2);
-+ if (conditional_schedule_needed())
-+ break;
- }
- }
- if (bufs == ARRAY_SIZE(wbuf)) {
-@@ -235,8 +238,7 @@
- journal_brelse_array(wbuf, bufs);
- lock_journal(journal);
- spin_lock(&journal_datalist_lock);
-- if (bufs)
-- goto write_out_data_locked;
-+ goto write_out_data_locked;
- }
-
- /*
-@@ -272,6 +274,14 @@
- */
- while ((jh = commit_transaction->t_async_datalist)) {
- struct buffer_head *bh = jh2bh(jh);
-+ if (conditional_schedule_needed()) {
-+ debug_lock_break(551);
-+ spin_unlock(&journal_datalist_lock);
-+ unlock_journal(journal);
-+ lock_journal(journal);
-+ spin_lock(&journal_datalist_lock);
-+ continue;
-+ }
- if (buffer_locked(bh)) {
- spin_unlock(&journal_datalist_lock);
- unlock_journal(journal);
-diff -Nur linux_c860_org/fs/jffs2/build.c linux/fs/jffs2/build.c
---- linux_c860_org/fs/jffs2/build.c 2003-05-14 15:01:21.000000000 +0900
-+++ linux/fs/jffs2/build.c 2004-06-10 21:09:11.000000000 +0900
-@@ -13,6 +13,7 @@
- * 15-Nov-2002 Lineo Japan, Inc. add nodemerge facility
- * 20-Sep-2002 Lineo Japan, Inc. add jffs2_orphaned_inodes
- * but it is useless right now
-+ * 05-Aug-2003 SHARP for Tosa
- *
- */
-
-@@ -295,7 +296,7 @@
-
- c->free_size = c->flash_size;
- c->nr_blocks = c->flash_size / c->sector_size;
--#ifdef CONFIG_ARCH_PXA_HUSKY
-+#if defined(CONFIG_ARCH_PXA_HUSKY) || defined(CONFIG_ARCH_PXA_TOSA)
- c->blocks = consistent_alloc(GFP_KERNEL,
- sizeof(struct jffs2_eraseblock) * c->nr_blocks,
- &c->blocks_phys);
-@@ -341,7 +342,7 @@
- D1(printk(KERN_DEBUG "build_fs failed\n"));
- jffs2_free_ino_caches(c);
- jffs2_free_raw_node_refs(c);
--#ifdef CONFIG_ARCH_PXA_HUSKY
-+#if defined(CONFIG_ARCH_PXA_HUSKY) || defined(CONFIG_ARCH_PXA_TOSA)
- consistent_free( c->blocks,
- sizeof(struct jffs2_eraseblock) * c->nr_blocks,
- c->blocks_phys );
-diff -Nur linux_c860_org/fs/jffs2/fs.c linux/fs/jffs2/fs.c
---- linux_c860_org/fs/jffs2/fs.c 2003-05-14 15:01:21.000000000 +0900
-+++ linux/fs/jffs2/fs.c 2004-06-10 21:09:11.000000000 +0900
-@@ -19,6 +19,7 @@
- * 24-Nov-2002 SHARP modify storage-avail calculation, and add erasing_dirty_size
- * 09-Nov-2002 Lineo Japan, Inc. add code to do avail = 0 when cannot reserve space
- * 01-Nov-2002 Lineo Japan, Inc. involve nr_bad_blocks in USED calc.
-+ * 05-Aug-2003 SHARP for Tosa
- *
- */
-
-@@ -402,7 +403,7 @@
- out_nodes:
- jffs2_free_ino_caches(c);
- jffs2_free_raw_node_refs(c);
--#ifdef CONFIG_ARCH_PXA_HUSKY
-+#if defined(CONFIG_ARCH_PXA_HUSKY) || defined(CONFIG_ARCH_PXA_TOSA)
- consistent_free( c->blocks,
- sizeof(struct jffs2_eraseblock) * c->nr_blocks,
- c->blocks_phys );
-diff -Nur linux_c860_org/fs/jffs2/nodelist.h linux/fs/jffs2/nodelist.h
---- linux_c860_org/fs/jffs2/nodelist.h 2003-06-19 17:23:10.000000000 +0900
-+++ linux/fs/jffs2/nodelist.h 2004-06-10 21:14:59.000000000 +0900
-@@ -17,8 +17,16 @@
- * 18-Nov-2002 Lineo Japan, Inc. add dynamic construction of fragtree
- * 11-Nov-2002 Lineo Japan, Inc. add JFFS2_RESERVED_BLOCKS_ROOT
- * 29-Oct-2002 Lineo Japan, Inc. add JFFS2_RESERVED_BLOCKS_BAD and JFFS2_MAX_CONT_GC
-+ *
-+ * ChangeLog:
- * 05-Dec-2002 SHARP adjust REVERVED_BLOCKS values for storage-full
-- * 21-May-2003 SHARP modified JFFS2_RESERVED_BLOCKS_BAD
-+ * 27-Nov-2002 Lineo Japan, Inc. add effective-gc mode
-+ * 23-Nov-2002 Lineo Japan, Inc. add JFFS2_RESERVED_BLOCKS_DIRTY
-+ * add JFFS2_RESERVED_BLOCKS_CLEAN
-+ * 19-Nov-2002 Lineo Japan, Inc. add counter of fragtree elements
-+ * 18-Nov-2002 Lineo Japan, Inc. add dynamic construction of fragtree
-+ * 11-Nov-2002 Lineo Japan, Inc. add JFFS2_RESERVED_BLOCKS_ROOT
-+ * 29-Oct-2002 Lineo Japan, Inc. add JFFS2_RESERVED_BLOCKS_BAD and JFFS2_MAX_CONT_GC
- *
- */
-
-@@ -233,13 +241,7 @@
- #define JFFS2_RESERVED_BLOCKS_GCTRIGGER 39 /* ... wake up the GC thread */
- #define JFFS2_RESERVED_BLOCKS_GCBAD (JFFS2_RESERVED_BLOCKS_BASE + 1) /* ... pick a block from the bad_list to GC */
- #define JFFS2_RESERVED_BLOCKS_GCMERGE (JFFS2_RESERVED_BLOCKS_BASE) /* ... merge pages when garbage collecting */
--
--#ifdef CONFIG_ARCH_PXA_HUSKY
- #define JFFS2_RESERVED_BLOCKS_BAD 80
--#else
--#define JFFS2_RESERVED_BLOCKS_BAD 24
--#endif
--
- #define JFFS2_RESERVED_BLOCKS_ROOT 5
- #define JFFS2_RESERVED_BLOCKS_DIRTY 24
- #define JFFS2_RESERVED_BLOCKS_CLEAN 12
-diff -Nur linux_c860_org/fs/jffs2/super-v24.c linux/fs/jffs2/super-v24.c
---- linux_c860_org/fs/jffs2/super-v24.c 2003-05-14 15:01:21.000000000 +0900
-+++ linux/fs/jffs2/super-v24.c 2004-06-10 21:09:11.000000000 +0900
-@@ -11,6 +11,7 @@
- *
- * ChangeLog:
- * 08-Nov-2002 Lineo Japan, Inc. add /proc/fs/jffs2 files for JFFS2 information
-+ * 05-Aug-2003 SHARP for Tosa
- *
- */
-
-@@ -106,7 +107,7 @@
- up(&c->alloc_sem);
- jffs2_free_ino_caches(c);
- jffs2_free_raw_node_refs(c);
--#ifdef CONFIG_ARCH_PXA_HUSKY
-+#if defined(CONFIG_ARCH_PXA_HUSKY) || defined(CONFIG_ARCH_PXA_TOSA)
- consistent_free( c->blocks,
- sizeof(struct jffs2_eraseblock) * c->nr_blocks,
- c->blocks_phys );
-diff -Nur linux_c860_org/fs/jffs2/super.c linux/fs/jffs2/super.c
---- linux_c860_org/fs/jffs2/super.c 2003-05-14 15:01:21.000000000 +0900
-+++ linux/fs/jffs2/super.c 2004-06-10 21:09:11.000000000 +0900
-@@ -9,6 +9,9 @@
- *
- * $Id$
- *
-+ * ChangeLog:
-+ * 05-Aug-2003 SHARP for Tosa
-+ *
- */
-
- #include <linux/config.h>
-@@ -263,7 +266,7 @@
- up(&c->alloc_sem);
- jffs2_free_ino_caches(c);
- jffs2_free_raw_node_refs(c);
--#ifdef CONFIG_ARCH_PXA_HUSKY
-+#if defined(CONFIG_ARCH_PXA_HUSKY) || defined(CONFIG_ARCH_PXA_TOSA)
- consistent_free( c->blocks,
- sizeof(struct jffs2_eraseblock) * c->nr_blocks,
- c->blocks_phys );
-diff -Nur linux_c860_org/fs/nls/nls_base.c linux/fs/nls/nls_base.c
---- linux_c860_org/fs/nls/nls_base.c 2002-08-26 14:37:33.000000000 +0900
-+++ linux/fs/nls/nls_base.c 2004-06-10 21:09:11.000000000 +0900
-@@ -18,6 +18,7 @@
- #ifdef CONFIG_KMOD
- #include <linux/kmod.h>
- #endif
-+#include <linux/sched.h>
- #include <linux/spinlock.h>
-
- static struct nls_table *tables;
-diff -Nur linux_c860_org/fs/reiserfs/bitmap.c linux/fs/reiserfs/bitmap.c
---- linux_c860_org/fs/reiserfs/bitmap.c 2002-08-26 14:37:39.000000000 +0900
-+++ linux/fs/reiserfs/bitmap.c 2004-06-10 21:09:11.000000000 +0900
-@@ -410,19 +410,23 @@
- amount_needed++ ;
- continue ;
- }
--
-
-- reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[i], 1) ;
-+ RFALSE( is_reusable (s, search_start, 0) == 0,
-+ "vs-4140: bad block number found");
-
-- RFALSE( buffer_locked (SB_AP_BITMAP (s)[i]) ||
-- is_reusable (s, search_start, 0) == 0,
-- "vs-4140: bitmap block is locked or bad block number found");
-+ reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[i], 1) ;
-
- /* if this bit was already set, we've scheduled, and someone else
- ** has allocated it. loop around and try again
- */
- if (reiserfs_test_and_set_le_bit (j, SB_AP_BITMAP (s)[i]->b_data)) {
- reiserfs_restore_prepared_buffer(s, SB_AP_BITMAP(s)[i]) ;
-+ /* if this block has been allocated while we slept, it is
-+ ** impossible to find any more contiguous blocks for ourselves.
-+ ** If we are doing preallocation, give up now and return.
-+ */
-+ if (for_prealloc)
-+ goto free_and_return;
- amount_needed++ ;
- continue ;
- }
-diff -Nur linux_c860_org/fs/reiserfs/buffer2.c linux/fs/reiserfs/buffer2.c
---- linux_c860_org/fs/reiserfs/buffer2.c 2002-08-26 14:37:40.000000000 +0900
-+++ linux/fs/reiserfs/buffer2.c 2004-06-10 21:09:11.000000000 +0900
-@@ -55,6 +55,8 @@
- PROC_EXP( unsigned int ctx_switches = kstat.context_swtch );
-
- result = bread (super -> s_dev, n_block, n_size);
-+ debug_lock_break(1);
-+ conditional_schedule();
- PROC_INFO_INC( super, breads );
- PROC_EXP( if( kstat.context_swtch != ctx_switches )
- PROC_INFO_INC( super, bread_miss ) );
-diff -Nur linux_c860_org/fs/reiserfs/journal.c linux/fs/reiserfs/journal.c
---- linux_c860_org/fs/reiserfs/journal.c 2002-08-26 14:37:40.000000000 +0900
-+++ linux/fs/reiserfs/journal.c 2004-06-10 21:09:11.000000000 +0900
-@@ -574,6 +574,8 @@
- /* lock the current transaction */
- inline static void lock_journal(struct super_block *p_s_sb) {
- PROC_INFO_INC( p_s_sb, journal.lock_journal );
-+ debug_lock_break(1);
-+ conditional_schedule();
- while(atomic_read(&(SB_JOURNAL(p_s_sb)->j_wlock)) > 0) {
- PROC_INFO_INC( p_s_sb, journal.lock_journal_wait );
- sleep_on(&(SB_JOURNAL(p_s_sb)->j_wait)) ;
-@@ -704,6 +706,8 @@
- mark_buffer_dirty(tbh) ;
- }
- ll_rw_block(WRITE, 1, &tbh) ;
-+ debug_lock_break(1);
-+ conditional_schedule();
- count++ ;
- put_bh(tbh) ; /* once for our get_hash */
- }
-@@ -833,6 +837,8 @@
- set_bit(BH_Dirty, &(SB_JOURNAL(p_s_sb)->j_header_bh->b_state)) ;
- ll_rw_block(WRITE, 1, &(SB_JOURNAL(p_s_sb)->j_header_bh)) ;
- wait_on_buffer((SB_JOURNAL(p_s_sb)->j_header_bh)) ;
-+ debug_lock_break(1);
-+ conditional_schedule();
- if (!buffer_uptodate(SB_JOURNAL(p_s_sb)->j_header_bh)) {
- printk( "reiserfs: journal-837: IO error during journal replay\n" );
- return -EIO ;
-@@ -2089,6 +2095,8 @@
- }
-
- int journal_begin(struct reiserfs_transaction_handle *th, struct super_block * p_s_sb, unsigned long nblocks) {
-+ debug_lock_break(1);
-+ conditional_schedule();
- return do_journal_begin_r(th, p_s_sb, nblocks, 0) ;
- }
-
-@@ -2229,6 +2237,8 @@
- }
-
- int journal_end(struct reiserfs_transaction_handle *th, struct super_block *p_s_sb, unsigned long nblocks) {
-+ debug_lock_break(1);
-+ conditional_schedule();
- return do_journal_end(th, p_s_sb, nblocks, 0) ;
- }
-
-@@ -2680,6 +2690,8 @@
- RFALSE( buffer_locked(bh) && cur_tb != NULL,
- "waiting while do_balance was running\n") ;
- wait_on_buffer(bh) ;
-+ debug_lock_break(1);
-+ conditional_schedule();
- }
- PROC_INFO_INC( p_s_sb, journal.prepare_retry );
- retry_count++ ;
-@@ -2852,6 +2864,8 @@
- /* copy all the real blocks into log area. dirty log blocks */
- if (test_bit(BH_JDirty, &cn->bh->b_state)) {
- struct buffer_head *tmp_bh ;
-+ debug_lock_break(1);
-+ conditional_schedule();
- tmp_bh = sb_getblk(p_s_sb, reiserfs_get_journal_block(p_s_sb) +
- ((cur_write_start + jindex) % JOURNAL_BLOCK_COUNT)) ;
- mark_buffer_uptodate(tmp_bh, 1) ;
-diff -Nur linux_c860_org/fs/reiserfs/stree.c linux/fs/reiserfs/stree.c
---- linux_c860_org/fs/reiserfs/stree.c 2002-08-26 14:37:40.000000000 +0900
-+++ linux/fs/reiserfs/stree.c 2004-06-10 21:09:11.000000000 +0900
-@@ -648,9 +648,8 @@
- stop at leaf level - set to
- DISK_LEAF_NODE_LEVEL */
- ) {
-- int n_block_number = SB_ROOT_BLOCK (p_s_sb),
-- expected_level = SB_TREE_HEIGHT (p_s_sb),
-- n_block_size = p_s_sb->s_blocksize;
-+ int n_block_number, expected_level;
-+ int n_block_size = p_s_sb->s_blocksize;
- struct buffer_head * p_s_bh;
- struct path_element * p_s_last_element;
- int n_node_level, n_retval;
-@@ -662,7 +661,10 @@
- #endif
-
- PROC_INFO_INC( p_s_sb, search_by_key );
--
-+
-+ debug_lock_break(1);
-+ conditional_schedule();
-+
- /* As we add each node to a path we increase its count. This means that
- we must be careful to release all nodes in a path before we either
- discard the path struct or re-use the path struct, as we do here. */
-@@ -674,6 +676,8 @@
- /* With each iteration of this loop we search through the items in the
- current node, and calculate the next current node(next path element)
- for the next iteration of this loop.. */
-+ n_block_number = SB_ROOT_BLOCK (p_s_sb);
-+ expected_level = SB_TREE_HEIGHT (p_s_sb);
- while ( 1 ) {
-
- #ifdef CONFIG_REISERFS_CHECK
-@@ -1100,6 +1104,9 @@
- for (n_counter = *p_n_removed;
- n_counter < n_unfm_number; n_counter++, p_n_unfm_pointer-- ) {
-
-+ debug_lock_break(1);
-+ conditional_schedule();
-+
- if (item_moved (&s_ih, p_s_path)) {
- need_research = 1 ;
- break;
-diff -Nur linux_c860_org/include/asm-alpha/processor.h linux/include/asm-alpha/processor.h
---- linux_c860_org/include/asm-alpha/processor.h 2002-08-26 14:37:49.000000000 +0900
-+++ linux/include/asm-alpha/processor.h 2004-06-10 21:09:11.000000000 +0900
-@@ -119,7 +119,7 @@
- extern void release_thread(struct task_struct *);
-
- /* Create a kernel thread without removing it from tasklists. */
--extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-+extern long arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
- #define copy_segments(tsk, mm) do { } while (0)
- #define release_segments(mm) do { } while (0)
-diff -Nur linux_c860_org/include/asm-arm/arch-pxa/hardware.h linux/include/asm-arm/arch-pxa/hardware.h
---- linux_c860_org/include/asm-arm/arch-pxa/hardware.h 2002-12-18 19:52:24.000000000 +0900
-+++ linux/include/asm-arm/arch-pxa/hardware.h 2004-06-10 21:12:44.000000000 +0900
-@@ -11,6 +11,7 @@
- *
- * ChangLog:
- * 12-Dec-2002 Lineo Japan, Inc.
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- #ifndef __ASM_ARCH_HARDWARE_H
-@@ -160,6 +161,10 @@
-
- #ifdef CONFIG_ARCH_PXA_CORGI
- #include "corgi.h"
--#endif
-+#endif /* CONFIG_ARCH_PXA_CORGI */
-+
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+#include "tosa.h"
-+#endif /* CONFIG_ARCH_PXA_TOSA */
-
- #endif /* _ASM_ARCH_HARDWARE_H */
-diff -Nur linux_c860_org/include/asm-arm/arch-pxa/irqs.h linux/include/asm-arm/arch-pxa/irqs.h
---- linux_c860_org/include/asm-arm/arch-pxa/irqs.h 2002-12-18 19:29:34.000000000 +0900
-+++ linux/include/asm-arm/arch-pxa/irqs.h 2004-06-10 21:12:37.000000000 +0900
-@@ -11,6 +11,7 @@
- *
- * ChangLog:
- * 12-Dec-2002 Lineo Japan, Inc.
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- #define PXA_IRQ_SKIP 8 /* The first 8 IRQs are reserved */
-@@ -345,6 +346,20 @@
-
- #endif
-
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+#define TC6393_IRQ(x) (IRQ_GPIO(80) + 1 + (x))
-+#define TC6393_IRQ_NDINT TC6393_IRQ(0)
-+#define TC6393_IRQ_SDINT TC6393_IRQ(1)
-+#define TC6393_IRQ_USBINT TC6393_IRQ(2)
-+#define TC6393_IRQ_SIOINT TC6393_IRQ(3)
-+#define TC6393_IRQ_GCINT TC6393_IRQ(4)
-+#define TC6393_IRQ_GPINT TC6393_IRQ(5)
-+#define TC6393_IRQ_CLKINT TC6393_IRQ(7)
-+
-+#undef NR_IRQS
-+#define NR_IRQS (TC6393_IRQ(7) + 1)
-+#endif /* CONFIG_ARCH_PXA_TOSA */
-+
- #if defined(CONFIG_ARCH_PXA_POODLE)
- #if CONFIG_SA1111
- #error POODLE configuration error
-diff -Nur linux_c860_org/include/asm-arm/arch-pxa/keyboard.h linux/include/asm-arm/arch-pxa/keyboard.h
---- linux_c860_org/include/asm-arm/arch-pxa/keyboard.h 2002-12-18 19:29:34.000000000 +0900
-+++ linux/include/asm-arm/arch-pxa/keyboard.h 2004-06-10 21:13:12.000000000 +0900
-@@ -5,6 +5,7 @@
- *
- * ChangLog:
- * 12-Dec-2002 Lineo Japan, Inc.
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- #ifndef _PXA_KEYBOARD_H
-@@ -22,6 +23,8 @@
- #include <asm/arch/keyboard_poodle.h>
- #elif defined(CONFIG_ARCH_PXA_CORGI)
- #include <asm/arch/keyboard_corgi.h>
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+#include <asm/arch/keyboard_tosa.h>
- #else
-
- #define kbd_disable_irq() do { } while(0);
-diff -Nur linux_c860_org/include/asm-arm/arch-pxa/keyboard_tosa.h linux/include/asm-arm/arch-pxa/keyboard_tosa.h
---- linux_c860_org/include/asm-arm/arch-pxa/keyboard_tosa.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/include/asm-arm/arch-pxa/keyboard_tosa.h 2004-06-10 21:13:12.000000000 +0900
-@@ -0,0 +1,162 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/keyboard_tosa.h
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ *
-+ * Based on:
-+ *
-+ * linux/include/asm-arm/arch-pxa/keyboard_corgi.h
-+ *
-+ * (C) Copyright 2001 Lineo Japan, Inc.
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ *
-+ * Based on:
-+ * linux/include/asm-arm/arch-sa1100/keyboard_collie.h
-+ * include/asm-arm/arch-linkup/keyboard.h
-+ * Created by Xuejun Tao 2000, ISDCorp www.isdcorp.com
-+ *
-+ * Changelog:
-+ * 04-13-2001 Lineo Japan, Inc.
-+ * 04-25-2001 Lineo Japan, Inc.
-+ * 10-23-2002 Sharp Corporation
-+ */
-+#ifndef __ASM_ARCH_KEYBOARD_TOSA_H
-+#define __ASM_ARCH_KEYBOARD_TOSA_H
-+
-+#include <linux/spinlock.h>
-+#include <asm/arch/hardware.h>
-+
-+/* =========================================================
-+ * !!! CAUTION !!!
-+ * Iris board without Keyboard Enhancements makes PA5 INTR
-+ * all times. So , you should disable PA5 INTR on such boards.
-+ * Define this option to run on such board.
-+ * ========================================================= */
-+#define TOSA_WITHOUT_KEY_ENH_WORKAROUND
-+/* =========================================================
-+ * CAUTION ends.
-+ * ========================================================= */
-+
-+/*
-+ * My driver now supports both keyboard interrupt driven or timer driven
-+ * Both modes work although keyboard interrupt mode is highly recommended.
-+ */
-+#define USE_KBD_IRQ /* Use keyboard interrupt instead of timer */
-+
-+#define KB_ROWS 7
-+#define KB_COLS 11
-+
-+#define KBD_COL9_IS_USED_FOR_SIC
-+ /* KBDCOL9 Hardware is used as SIC SYS_CLK , so , it cannot be used */
-+
-+#define ALL_AUX_COLS 0x00 /* no AUX Cols */
-+
-+#define set_bits(var, mask, bits) (var) = (((var) & ~(mask)) | (bits))
-+
-+/*
-+ * Be sure to change the if you increase the
-+ * number of kbd rows...
-+ */
-+#define KEYCODE(r,c) ( ((r)<<4) + (c) + 1 )
-+#define KB_ROWMASK(r) (1 << (r))
-+
-+ /*
-+ * KB_DELAY is used to allow the matrix
-+ * to stabilize.., value is determined via
-+ * experimentation.
-+ */
-+
-+#define KB_DISCHARGE_DELAY 10
-+#define KB_ACTIVATE_DELAY 10
-+
-+typedef struct {
-+ int in; /* If the key down */
-+} kbd_keyinfo;
-+
-+#define KBUP (0x80)
-+#define KBDOWN (0)
-+
-+#define KBSCANCDE(x,y) ((x) | (y))
-+
-+#define CHARGE_VALUE 0x00FF
-+#define DISCHARGE_VALUE 0x0000
-+#define IRQ_STATE_CLEAR 0xFEFF
-+#define INIT_KCMD 0x0001
-+
-+
-+
-+/*
-+ * We have a spinlock we use to ensure that keysdown
-+ * is consisent with kbd_state[]
-+ *
-+ * This is prolly overkill since the arm doesn't support SMP.
-+ */
-+// Yes, it is - WA static spinlock_t kbd_spinlock;
-+extern spinlock_t kbd_spinlock;
-+
-+ /*
-+ * #define for functions we can't make use of
-+ */
-+
-+#define kbd_leds(x)
-+#define kbd_setleds(x)
-+#define kbd_getledstate (0)
-+extern int tosa_kbd_translate(unsigned char sc,unsigned char *keycode_p);
-+#define kbd_translate(sc,kc,rm) tosa_kbd_translate(sc,kc)
-+/*
-+ *#define kbd_sysrq_xlate() (1)
-+ */
-+#define kbd_pretranslate(x,y) (1)
-+#define kbd_unexpected_up(kc) (0x80)
-+#define kbd_setkeycode(sc,kc) (-EINVAL)
-+#define kbd_getkeycode(sc) (-EINVAL)
-+
-+extern void tosa_kbd_hw_init(void);
-+#define kbd_init_hw() tosa_kbd_hw_init()
-+
-+extern void tosa_kbd_cleartable(void);
-+
-+/*
-+ * I need to do something better for these two...
-+ * Sometime v. soon. I don't like these at all, as they
-+ *
-+ * don't look like fn calls.
-+ */
-+
-+#define kbd_disable_irq() { \
-+ int flags; \
-+ spin_lock_irqsave(&kbd_spinlock,flags);
-+
-+
-+#define kbd_enable_irq() spin_unlock_irqrestore(&kbd_spinlock,flags); \
-+ }
-+
-+
-+/* data structure for raw keyboard event */
-+
-+/*
-+ * row , col values for feature keys
-+ */
-+#define TOSA_KEYPOS_2nd_ROW 0
-+#define TOSA_KEYPOS_2nd_COL 1
-+
-+#define TOSA_KEYPOS_NUM_ROW 0
-+#define TOSA_KEYPOS_NUM_COL 8
-+
-+#define TOSA_KEYPOS_LSHIFT_ROW 1
-+#define TOSA_KEYPOS_LSHIFT_COL 0
-+
-+#define TOSA_KEYPOS_RSHIFT_ROW 1
-+#define TOSA_KEYPOS_RSHIFT_COL 8
-+
-+/*
-+ * number of modifier status keys resolved on corgikb driver
-+ */
-+#define TOSAKB_MODIFIERS 5 /* for CapsLock / NumLock / 2ND / LSHIFT / RSHIFT */
-+
-+#endif
-diff -Nur linux_c860_org/include/asm-arm/arch-pxa/pcmcia.h linux/include/asm-arm/arch-pxa/pcmcia.h
---- linux_c860_org/include/asm-arm/arch-pxa/pcmcia.h 2002-12-18 19:29:34.000000000 +0900
-+++ linux/include/asm-arm/arch-pxa/pcmcia.h 2004-06-10 21:13:56.000000000 +0900
-@@ -14,6 +14,7 @@
- *
- * ChangLog:
- * 12-Dec-2002 Lineo Japan, Inc.
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- #ifndef _ASM_ARCH_PCMCIA
-@@ -71,6 +72,10 @@
- int (*socket_state)(struct pcmcia_state_array *);
- int (*get_irq_info)(struct pcmcia_irq_info *);
- int (*configure_socket)(const struct pcmcia_configure *);
-+#ifdef CONFIG_ARCH_SHARP_SL
-+ int (*socket_init)(int sock);
-+ int (*socket_suspend)(int sock);
-+#endif
- };
-
- extern struct pcmcia_low_level *pcmcia_low_level;
-diff -Nur linux_c860_org/include/asm-arm/arch-pxa/pxa-regs.h linux/include/asm-arm/arch-pxa/pxa-regs.h
---- linux_c860_org/include/asm-arm/arch-pxa/pxa-regs.h 2002-08-29 14:59:56.000000000 +0900
-+++ linux/include/asm-arm/arch-pxa/pxa-regs.h 2004-06-10 21:09:11.000000000 +0900
-@@ -11,6 +11,7 @@
- *
- * Change Log
- * 08-19-2002 Sharp add I2S defines
-+ * 26-Feb-2004 Lineo Solutions, Inc. supply a definition for FM bit of ICR
- *
- */
- #ifndef _PXA_REGS_H_
-@@ -443,6 +444,7 @@
- #define ICR_ALDIE 0x1000 /* enable arbitration interrupt */
- #define ICR_SADIE 0x2000 /* slave address detected int enable */
- #define ICR_UR 0x4000 /* unit reset */
-+#define ICR_FM 0x8000 /* fast mode */
-
- /* ----- Status register bits ----------------------------------------- */
-
-diff -Nur linux_c860_org/include/asm-arm/arch-pxa/serial_pxa200.h linux/include/asm-arm/arch-pxa/serial_pxa200.h
---- linux_c860_org/include/asm-arm/arch-pxa/serial_pxa200.h 2003-01-15 15:51:16.000000000 +0900
-+++ linux/include/asm-arm/arch-pxa/serial_pxa200.h 2004-06-10 21:13:15.000000000 +0900
-@@ -3,6 +3,7 @@
- *
- * Change Log
- * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- #ifndef __ASM_ARCH_SERIAL_H
-@@ -30,7 +31,10 @@
- #define CONFIG_UART2_DFLT_CONSOLE
- #elif defined(CONFIG_ARCH_PXA_CORGI)
- #define CONFIG_UART2_DFLT_CONSOLE
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+#define CONFIG_UART2_DFLT_CONSOLE
- #endif
-+
- #if defined(CONFIG_UART0_DFLT_CONSOLE)
-
- #define STD_SERIAL_PORT_DEFNS \
-diff -Nur linux_c860_org/include/asm-arm/arch-pxa/sharpsl_battery.h linux/include/asm-arm/arch-pxa/sharpsl_battery.h
---- linux_c860_org/include/asm-arm/arch-pxa/sharpsl_battery.h 2002-08-26 16:00:32.000000000 +0900
-+++ linux/include/asm-arm/arch-pxa/sharpsl_battery.h 2004-06-10 21:17:53.000000000 +0900
-@@ -10,6 +10,7 @@
- *
- * ChangeLog:
- * 21-Aug-2002 Lineo Japan, Inc. for 2.4.18
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- *
- */
-
-@@ -81,6 +82,11 @@
- #define BATT_AD 4u /* channel of BATTery */
- #define BATT_THM 2u /* channel of BATTery */
- #define JK_VAD 6u /* channel of BATTery */
-+#elif defined(CONFIG_ARCH_PXA_TOSA)
-+#define BATT_VC 0x4 /* channel of BAT V CAUTION */
-+#define BATT_TH 0x5 /* channel of BAT TH */
-+#define BATT_V 0x6 /* channel of BAT V */
-+#define BU_V 0x7 /* channel of BU V */
- #endif
-
- #define Temper_V47 0x449 /* 0.670v (47"C) */
-diff -Nur linux_c860_org/include/asm-arm/arch-pxa/sharpsl_wakeup.h linux/include/asm-arm/arch-pxa/sharpsl_wakeup.h
---- linux_c860_org/include/asm-arm/arch-pxa/sharpsl_wakeup.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/include/asm-arm/arch-pxa/sharpsl_wakeup.h 2004-06-10 21:09:11.000000000 +0900
-@@ -0,0 +1,26 @@
-+/*
-+ * include/asm-arm/arch-pxa/sharpsl_wakeup.h
-+ * Copyright (C) 2003 SHARP
-+ */
-+
-+#ifndef __SHARPSL_WAKEUP_H__
-+#define __SHARPSL_WAKEUP_H__
-+
-+
-+#define IDPM_WAKEUP_AC (0x1<<1)
-+#define IDPM_WAKEUP_SYNC (0x1<<3)
-+#define IDPM_WAKEUP_REMOCON (0x1<<4)
-+#define IDPM_WAKEUP_REC (0x1<<10)
-+#define IDPM_WAKEUP_JACKET (0x1<<16)
-+#define IDPM_WAKEUP_USBD (0x1<<17)
-+#define IDPM_WAKEUP_CALENDAR (0x1<<25)
-+#define IDPM_WAKEUP_ADDRESSBOOK (0x1<<26)
-+#define IDPM_WAKEUP_MAIL (0x1<<27)
-+#define IDPM_WAKEUP_MENU (0x1<<28)
-+#define IDPM_WAKEUP_HOME (0x1<<29)
-+#define IDPM_WAKEUP_RTC (0x1<<31)
-+
-+extern unsigned long logical_wakeup_src_mask;
-+
-+
-+#endif // end __SHARPSL_WAKEUP_H__
-diff -Nur linux_c860_org/include/asm-arm/arch-pxa/system.h linux/include/asm-arm/arch-pxa/system.h
---- linux_c860_org/include/asm-arm/arch-pxa/system.h 2003-06-18 16:12:28.000000000 +0900
-+++ linux/include/asm-arm/arch-pxa/system.h 2004-06-10 21:17:56.000000000 +0900
-@@ -12,6 +12,7 @@
- * Change Log
- * 17-Sep-2002 Lineo Japan, Inc.
- * 13-Mar-2003 Sharp for Shepherd
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- #include <linux/config.h>
-@@ -32,11 +33,13 @@
- static inline void arch_reset(char mode)
- {
- #ifdef CONFIG_ARCH_SHARP_SL
--#ifdef CONFIG_ARCH_PXA_SHEPHERD
-+#ifdef CONFIG_PM
-+#if defined(CONFIG_ARCH_PXA_SHEPHERD) || defined(CONFIG_ARCH_PXA_TOSA)
- sharpsl_restart_nonstop();
- #else
- sharpsl_restart();
- #endif
-+#endif
- #else
- if (mode == 's') {
- /* Jump into ROM at address 0 */
-diff -Nur linux_c860_org/include/asm-arm/arch-pxa/time.h linux/include/asm-arm/arch-pxa/time.h
---- linux_c860_org/include/asm-arm/arch-pxa/time.h 2003-01-14 12:07:55.000000000 +0900
-+++ linux/include/asm-arm/arch-pxa/time.h 2004-06-10 21:18:00.000000000 +0900
-@@ -12,6 +12,7 @@
- * ChangLog:
- * 12-Dec-2002 Lineo Japan, Inc.
- * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- #ifdef CONFIG_SABINAL_DISCOVERY
-@@ -19,14 +20,18 @@
- //#define RTC_DEF_TRIM 0
- #define RTC_DEF_TRIM 0x11b3
- #endif
-+
- #ifdef CONFIG_ARCH_PXA_POODLE
- #define RTC_DEF_DIVIDER 32768 - 1
- #define RTC_DEF_TRIM 0
--#endif
--#ifdef CONFIG_ARCH_PXA_CORGI
-+#elif CONFIG_ARCH_PXA_CORGI
-+#define RTC_DEF_DIVIDER 32768 - 1
-+#define RTC_DEF_TRIM 0
-+#elif CONFIG_ARCH_PXA_TOSA
- #define RTC_DEF_DIVIDER 32768 - 1
- #define RTC_DEF_TRIM 0
- #endif
-+
- #ifdef CONFIG_ARCH_SHARP_SL
- #define SHARP_SL_DEF_YEAR 2003
- #endif
-diff -Nur linux_c860_org/include/asm-arm/arch-pxa/tosa.h linux/include/asm-arm/arch-pxa/tosa.h
---- linux_c860_org/include/asm-arm/arch-pxa/tosa.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/include/asm-arm/arch-pxa/tosa.h 2004-06-10 21:09:11.000000000 +0900
-@@ -0,0 +1,433 @@
-+/*
-+ * include/asm-arm/arch-pxa/tosa.h
-+ * Copyright (C) 2003 Lineo uSolutions, Inc.
-+ *
-+ * ChangeLog:
-+ * 23-Oct-2003 SHARP Corporation
-+ */
-+
-+#ifndef _ASM_ARCH_TOSA_H_
-+#define _ASM_ARCH_TOSA_H_ 1
-+
-+/* TOSA Chip selects */
-+#define TOSA_LCDC_PHYS PXA_CS4_PHYS
-+/* Internel Scoop */
-+#define TOSA_CF_PHYS (PXA_CS2_PHYS + 0x00800000)
-+/* Jacket Scoop */
-+#define TOSA_SCOOP_PHYS (PXA_CS5_PHYS + 0x00800000)
-+
-+/*
-+ * TC6393 internal I/O mappings
-+ *
-+ * We have the following mapping:
-+ * phys virt
-+ * 10000000 f1000000
-+ */
-+#define TC6393_SYS_BASE 0xf1000000
-+#define TC6393_NAND_BASE (TC6393_SYS_BASE + 0x000100)
-+#define TC6393_SD_BASE (TC6393_SYS_BASE + 0x000200)
-+#define TC6393_USB_BASE (TC6393_SYS_BASE + 0x000300)
-+#define TC6393_SERIAL_BASE (TC6393_SYS_BASE + 0x000400)
-+#define TC6393_GC_BASE (TC6393_SYS_BASE + 0x000500)
-+#define TC6393_RAM0_BASE (TC6393_SYS_BASE + 0x010000)
-+#define TC6393_RAM0_SIZE (32*1024)
-+#define TC6393_RAM1_BASE (TC6393_SYS_BASE + 0x100000)
-+#define TC6393_RAM1_SIZE (64 * 1024 * 16)
-+
-+/*
-+ * Internal Local Memory use purpose
-+ * RAM0 is used for USB
-+ * RAM1 is used for GC
-+ */
-+/* Internal register mapping */
-+#define TC6393_GC_INTERNAL_REG_BASE 0x000600 /* Length 0x200 */
-+#define TC6393_USB_OHCI_OP_REG_BASE 0x000A00 /* Length 0x100 */
-+#define TC6393_NAND_FLASH_CTL_REG_BASE 0x001000 /* Length 0x8 */
-+
-+
-+/* System Configuration register */
-+#define TC6393_SYS_REG(ofst) (*(volatile unsigned short*)(TC6393_SYS_BASE+(ofst)))
-+#define TC6393_SYS_RIDR 0x008
-+#define TC6393_SYS_ISR 0x050
-+#define TC6393_SYS_IMR 0x052
-+#define TC6393_SYS_IRR 0x054
-+#define TC6393_SYS_GPER 0x060
-+#define TC6393_SYS_GPISR1 0x064
-+#define TC6393_SYS_GPISR2 0x066
-+#define TC6393_SYS_GPIIMR1 0x068
-+#define TC6393_SYS_GPIIMR2 0x06A
-+#define TC6393_SYS_GPIEDER1 0x06C
-+#define TC6393_SYS_GPIEDER2 0x06E
-+#define TC6393_SYS_GPILIR1 0x070
-+#define TC6393_SYS_GPILIR2 0x072
-+#define TC6393_SYS_GPODSR1 0x078
-+#define TC6393_SYS_GPODSR2 0x07A
-+#define TC6393_SYS_GPOOECR1 0x07C
-+#define TC6393_SYS_GPOOECR2 0x07E
-+#define TC6393_SYS_GPIARCR1 0x080
-+#define TC6393_SYS_GPIARCR2 0x082
-+#define TC6393_SYS_GPIARLCR1 0x084
-+#define TC6393_SYS_GPIARLCR2 0x086
-+#define TC6393_SYS_GPIBCR1 0x088
-+#define TC6393_SYS_GPIBCR2 0x08A
-+#define TC6393_SYS_GPaIARCR 0x08C
-+#define TC6393_SYS_GPaIARLCR 0x090
-+#define TC6393_SYS_GPaIBCR 0x094
-+#define TC6393_SYS_CCR 0x098 /* Clock Control Register */
-+#define TC6393_SYS_PLL2CR 0x09A
-+#define TC6393_SYS_PLL1CR1 0x09C
-+#define TC6393_SYS_PLL1CR2 0x09E
-+#define TC6393_SYS_DCR 0x0A0
-+#define TC6393_SYS_FER 0x0E0 /* Function Enable Register */
-+#define TC6393_SYS_MCR 0x0E4
-+#define TC6393_SYS_ConfigCR 0x0FC
-+
-+/* NAND FLASH controller configuration register */
-+#define TC6393_NAND_REG(ofst) (*(volatile unsigned short*)(TC6393_NAND_BASE+(ofst)))
-+
-+/* SD Card Configuration register */
-+#define TC6393_SD_REG(ofst) (*(volatile unsigned short*)(TC6393_SD_BASE+(ofst)))
-+
-+/* USB HOST Configuration register */
-+#define TC6393_USB_REG(ofst) (*(volatile unsigned short*)(TC6393_USB_BASE+(ofst)))
-+#define TC6393_USB_SPRID 0x08
-+#define TC6393_USB_SPBA1 0x10
-+#define TC6393_USB_SPBA2 0x12
-+#define TC6393_USB_ILME 0x40
-+#define TC6393_USB_SVPMCS 0x4C
-+#define TC6393_USB_PM_PMES (1 << 15)
-+#define TC6393_USB_PM_PMEE (1 << 8)
-+#define TC6393_USB_PM_USPW2 (1 << 3)
-+#define TC6393_USB_PM_USPW1 (1 << 2)
-+#define TC6393_USB_PM_CKRNEN (1 << 1)
-+#define TC6393_USB_PM_GCKEN (1 << 0)
-+#define TC6393_USB_INTC 0x50
-+#define TC6393_USB_SP1INTC1 0x54
-+#define TC6393_USB_SP1INTC2 0x56
-+#define TC6393_USB_SP1MBA1 0x58
-+#define TC6393_USB_SP1MBA2 0x5A
-+#define TC6393_USB_SP2INTC1 0x5C
-+#define TC6393_USB_SP2INTC2 0x5E
-+#define TC6393_USB_SP2MBA1 0x60
-+#define TC6393_USB_SP2MBA2 0x62
-+#define TC6393_USB_SPPCNF 0xFC
-+
-+#define IS_TC6393_RAM0(p) (TC6393_RAM0_BASE <= (unsigned int)p \
-+ && (unsigned int)p <= TC6393_RAM0_BASE + TC6393_RAM0_SIZE)
-+#define TC6393_RAM0_VAR_TO_OFFSET(x) ((unsigned int)x - TC6393_RAM0_BASE)
-+#define TC6393_RAM0_OFFSET_TO_VAR(x) ((unsigned int)x + TC6393_RAM0_BASE)
-+
-+/* Serial I/O controller Configuration register */
-+#define TC6393_SERIAL_REG(ofst) (*(volatile unsigned short*)(TC6393_SERIAL_BASE+(ofst)))
-+
-+/* Graphic controller Configuration register */
-+#define TC6393_GC_REG(ofst) (*(volatile unsigned short*)(TC6393_GC_BASE+(ofst)))
-+
-+/* GPIO bit */
-+#define TC6393_GPIO19 ( 1 << 19 )
-+#define TC6393_GPIO18 ( 1 << 18 )
-+#define TC6393_GPIO17 ( 1 << 17 )
-+#define TC6393_GPIO16 ( 1 << 16 )
-+#define TC6393_GPIO15 ( 1 << 15 )
-+#define TC6393_GPIO14 ( 1 << 14 )
-+#define TC6393_GPIO13 ( 1 << 13 )
-+#define TC6393_GPIO12 ( 1 << 12 )
-+#define TC6393_GPIO11 ( 1 << 11 )
-+#define TC6393_GPIO10 ( 1 << 10 )
-+#define TC6393_GPIO9 ( 1 << 9 )
-+#define TC6393_GPIO8 ( 1 << 8 )
-+#define TC6393_GPIO7 ( 1 << 7 )
-+#define TC6393_GPIO6 ( 1 << 6 )
-+#define TC6393_GPIO5 ( 1 << 5 )
-+#define TC6393_GPIO4 ( 1 << 4 )
-+#define TC6393_GPIO3 ( 1 << 3 )
-+#define TC6393_GPIO2 ( 1 << 2 )
-+#define TC6393_GPIO1 ( 1 << 1 )
-+#define TC6393_GPIO0 ( 1 << 0 )
-+
-+/*
-+ * TC6393 GPIOs
-+ */
-+#define TC6393_TG_ON TC6393_GPIO0
-+#define TC6393_L_MUTE TC6393_GPIO1
-+#define TC6393_BL_C20MA TC6393_GPIO3
-+#define TC6393_CARD_VCC_ON TC6393_GPIO4
-+#define TC6393_CHARGE_OFF TC6393_GPIO6
-+#define TC6393_CHARGE_OFF_JC TC6393_GPIO7
-+#define TC6393_BAT0_V_ON TC6393_GPIO9
-+#define TC6393_BAT1_V_ON TC6393_GPIO10
-+#define TC6393_BU_CHRG_ON TC6393_GPIO11
-+#define TC6393_BAT_SW_ON TC6393_GPIO12
-+#define TC6393_BAT0_TH_ON TC6393_GPIO14
-+#define TC6393_BAT1_TH_ON TC6393_GPIO15
-+
-+#define TC6393_GPO_OE ( TC6393_TG_ON | TC6393_L_MUTE | TC6393_BL_C20MA | \
-+ TC6393_CARD_VCC_ON | TC6393_CHARGE_OFF | \
-+ TC6393_CHARGE_OFF_JC | TC6393_BAT0_V_ON | \
-+ TC6393_BAT1_V_ON | TC6393_BU_CHRG_ON | \
-+ TC6393_BAT_SW_ON | TC6393_BAT0_TH_ON | \
-+ TC6393_BAT1_TH_ON )
-+
-+/*
-+ * SCOOP2 internal I/O mappings
-+ *
-+ * We have the following mapping:
-+ * phys virt
-+ * 08800000 f2000000
-+ */
-+#define CF_BUF_CTRL_BASE 0xF2000000
-+#define SCP_REG(adr) (*(volatile unsigned short*)(CF_BUF_CTRL_BASE+(adr)))
-+
-+#define SCP_MCR 0x00
-+#define SCP_CDR 0x04
-+#define SCP_CSR 0x08
-+#define SCP_CPR 0x0C
-+#define SCP_CCR 0x10
-+#define SCP_IRR 0x14
-+#define SCP_IRM 0x14
-+#define SCP_IMR 0x18
-+#define SCP_ISR 0x1C
-+#define SCP_GPCR 0x20
-+#define SCP_GPWR 0x24
-+#define SCP_GPRR 0x28
-+#define SCP_REG_MCR SCP_REG(SCP_MCR)
-+#define SCP_REG_CDR SCP_REG(SCP_CDR)
-+#define SCP_REG_CSR SCP_REG(SCP_CSR)
-+#define SCP_REG_CPR SCP_REG(SCP_CPR)
-+#define SCP_REG_CCR SCP_REG(SCP_CCR)
-+#define SCP_REG_IRR SCP_REG(SCP_IRR)
-+#define SCP_REG_IRM SCP_REG(SCP_IRM)
-+#define SCP_REG_IMR SCP_REG(SCP_IMR)
-+#define SCP_REG_ISR SCP_REG(SCP_ISR)
-+#define SCP_REG_GPCR SCP_REG(SCP_GPCR)
-+#define SCP_REG_GPWR SCP_REG(SCP_GPWR)
-+#define SCP_REG_GPRR SCP_REG(SCP_GPRR)
-+
-+#define SCP_GPCR_PA22 ( 1 << 12 )
-+#define SCP_GPCR_PA21 ( 1 << 11 )
-+#define SCP_GPCR_PA20 ( 1 << 10 )
-+#define SCP_GPCR_PA19 ( 1 << 9 )
-+#define SCP_GPCR_PA18 ( 1 << 8 )
-+#define SCP_GPCR_PA17 ( 1 << 7 )
-+#define SCP_GPCR_PA16 ( 1 << 6 )
-+#define SCP_GPCR_PA15 ( 1 << 5 )
-+#define SCP_GPCR_PA14 ( 1 << 4 )
-+#define SCP_GPCR_PA13 ( 1 << 3 )
-+#define SCP_GPCR_PA12 ( 1 << 2 )
-+#define SCP_GPCR_PA11 ( 1 << 1 )
-+
-+/*
-+ * SCOOP2 internal GPIOs
-+ */
-+#define SCP_PXA_VCORE1 SCP_GPCR_PA11
-+#define SCP_TC6393_REST_IN SCP_GPCR_PA12
-+#define SCP_IR_POWERDWN SCP_GPCR_PA13
-+#define SCP_SD_WP SCP_GPCR_PA14
-+#define SCP_PWR_ON SCP_GPCR_PA15
-+#define SCP_AUD_PWR_ON SCP_GPCR_PA16
-+#define SCP_BT_RESET SCP_GPCR_PA17
-+#define SCP_BT_PWR_EN SCP_GPCR_PA18
-+#define SCP_AC_IN_OL SCP_GPCR_PA19
-+
-+/* GPIO Direction 1 : outpu mode / 0:input mode */
-+#define SCP_IO_DIR ( SCP_PXA_VCORE1 | SCP_TC6393_REST_IN | \
-+ SCP_IR_POWERDWN | SCP_PWR_ON | SCP_AUD_PWR_ON |\
-+ SCP_BT_RESET | SCP_BT_PWR_EN )
-+/* GPIO out put level when init 1: Hi */
-+#define SCP_IO_OUT ( SCP_TC6393_REST_IN )
-+//#define GPIO_CO 16
-+
-+/*
-+ * SCOOP2 for jacket I/O mappings
-+ *
-+ * We have the following mapping:
-+ * phys virt
-+ * 14800000 f2200000
-+ */
-+
-+#define CF2_BUF_CTRL_BASE 0xF2200040
-+#define SCP_JC_REG(adr) (*(volatile unsigned short*)(CF2_BUF_CTRL_BASE+(adr)))
-+
-+#define SCP_JC_REG_MCR SCP_JC_REG(SCP_MCR)
-+#define SCP_JC_REG_CDR SCP_JC_REG(SCP_CDR)
-+#define SCP_JC_REG_CSR SCP_JC_REG(SCP_CSR)
-+#define SCP_JC_REG_CPR SCP_JC_REG(SCP_CPR)
-+#define SCP_JC_REG_CCR SCP_JC_REG(SCP_CCR)
-+#define SCP_JC_REG_IRR SCP_JC_REG(SCP_IRR)
-+#define SCP_JC_REG_IRM SCP_JC_REG(SCP_IRM)
-+#define SCP_JC_REG_IMR SCP_JC_REG(SCP_IMR)
-+#define SCP_JC_REG_ISR SCP_JC_REG(SCP_ISR)
-+#define SCP_JC_REG_GPCR SCP_JC_REG(SCP_GPCR)
-+#define SCP_JC_REG_GPWR SCP_JC_REG(SCP_GPWR)
-+#define SCP_JC_REG_GPRR SCP_JC_REG(SCP_GPRR)
-+
-+/*
-+ * SCOOP2 jacket GPIOs
-+ */
-+#define SCP_JC_BT_LED SCP_GPCR_PA11
-+#define SCP_JC_NOTE_LED SCP_GPCR_PA12
-+#define SCP_JC_CHRG_ERR_LED SCP_GPCR_PA13
-+#define SCP_JC_USB_PULLUP SCP_GPCR_PA14
-+#define SCP_JC_TC6393_SUSPEND SCP_GPCR_PA15
-+#define SCP_JC_TC3693_L3V_ON SCP_GPCR_PA16
-+#define SCP_JC_WLAN_DETECT SCP_GPCR_PA17
-+#define SCP_JC_WLAN_LED SCP_GPCR_PA18
-+#define SCP_JC_CARD_LIMIT_SEL SCP_GPCR_PA19
-+
-+/* GPIO Direction 1 : outpu mode / 0:input mode */
-+#define SCP_JC_IO_DIR ( SCP_JC_BT_LED | SCP_JC_NOTE_LED | \
-+ SCP_JC_CHRG_ERR_LED | SCP_JC_USB_PULLUP | \
-+ SCP_JC_TC6393_SUSPEND | SCP_JC_TC3693_L3V_ON | \
-+ SCP_JC_WLAN_LED | SCP_JC_CARD_LIMIT_SEL )
-+/* GPIO out put level when init 1: Hi */
-+//#define SCP_JC_IO_OUT ( SCP_JC_TC6393_SUSPEND | SCP_JC_TC3693_L3V_ON )
-+#define SCP_JC_IO_OUT ( 0 )
-+
-+/*
-+ * NSSP
-+ */
-+#define NSSCR0 __REG(0x41400000)
-+#define NSSCR1 __REG(0x41400008)
-+#define NSSSR __REG(0x4140000C)
-+#define NSSITR __REG(0x41400010)
-+#define NSSDRTO __REG(0x41400028)
-+
-+/*
-+ * Timing Generator
-+ */
-+#define TG_PNLCTL 0x00
-+#define TG_TPOSCTL 0x01
-+#define TG_DUTYCTL 0x02
-+#define TG_GPOSR 0x03
-+#define TG_GPODR1 0x04
-+#define TG_GPODR2 0x05
-+#define TG_PINICTL 0x06
-+#define TG_HPOSCTL 0x07
-+
-+#if 0
-+/*
-+ * Flash Memory mappings
-+ *
-+ * We have the following mapping:
-+ * phys virt
-+ * boot ROM 00000000 ef000000
-+ * NAND Flash 0C000000 f2100000
-+ */
-+#define NAND_FLASH_REG_BASE 0xf2100000
-+#define CPLD_REG(ofst) (*(volatile unsigned char*)(NAND_FLASH_REG_BASE+(ofst)))
-+
-+/* register offset */
-+#define ECCLPLB 0x00 /* line parity 7 - 0 bit */
-+#define ECCLPUB 0x04 /* line parity 15 - 8 bit */
-+#define ECCCP 0x08 /* column parity 5 - 0 bit */
-+#define ECCCNTR 0x0C /* ECC byte counter */
-+#define ECCCLRR 0x10 /* cleare ECC */
-+#define FLASHIO 0x14 /* Flash I/O */
-+#define FLASHCTL 0x18 /* Flash Control */
-+
-+/* Flash control bit */
-+#define FLRYBY (1 << 5)
-+#define FLCE1 (1 << 4)
-+#define FLWP (1 << 3)
-+#define FLALE (1 << 2)
-+#define FLCLE (1 << 1)
-+#define FLCE0 (1 << 0)
-+#endif
-+
-+
-+/*
-+ * LED
-+ */
-+#define SCP_LED_BLUE SCP_GPCR_PA11
-+#define SCP_LED_GREEN SCP_GPCR_PA12
-+#define SCP_LED_ORANGE SCP_GPCR_PA13
-+#define SCP_LED_WLAN SCP_GPCR_PA18
-+
-+
-+/*
-+ * PXA GPIOs
-+ */
-+#define GPIO_POWERON (0)
-+#define GPIO_RESET (1)
-+#define GPIO_AC_IN (2)
-+#define GPIO_RECORD_BTN (3)
-+#define GPIO_SYNC (4) /* Cradle SYNC Button */
-+#define GPIO_USB_IN (5)
-+//#define GPIO_nSD_CLK (6)
-+#define GPIO_JACKET_DETECT (7)
-+#define GPIO_nSD_DETECT (9)
-+#define GPIO_nSD_INT (10)
-+#define GPIO_TC6393_CLK (11)
-+#define GPIO_BAT1_CRG (12)
-+#define GPIO_CF_CD (13)
-+#define GPIO_BAT0_CRG (14)
-+#define GPIO_TC6393_INT (15)
-+#define GPIO_BAT0_LOW (17)
-+#define GPIO_TC6393_RDY (18)
-+#define GPIO_ON_RESET (19)
-+#define GPIO_EAR_IN (20)
-+#define GPIO_CF_IRQ (21) /* CF slot0 Ready */
-+#define GPIO_ON_KEY (22)
-+#define GPIO_VGA_LINE (27)
-+#define GPIO_TP_INT (32) /* Touch Panel pen down interrupt */
-+#define GPIO_JC_CF_IRQ (36) /* CF slot1 Ready */
-+#define GPIO_BAT_LOCKED (38) /* Battery locked */
-+#define GPIO_TG_SPI_SCLK (81)
-+#define GPIO_TG_SPI_CS (82)
-+#define GPIO_TG_SPI_MOSI (83)
-+#define GPIO_BAT1_LOW (84)
-+
-+#define GPIO_HP_IN GPIO_EAR_IN
-+
-+#define GPIO_MAIN_BAT_LOW GPIO_BAT0_LOW
-+
-+#define KEY_STROBE_NUM (11)
-+#define KEY_SENSE_NUM (7)
-+#define GPIO_HIGH_STROBE_BIT (0xfc000000)
-+#define GPIO_LOW_STROBE_BIT (0x0000001f)
-+#define GPIO_ALL_SENSE_BIT (0x00000fe0)
-+#define GPIO_ALL_SENSE_RSHIFT (5)
-+#define GPIO_STROBE_BIT(a) GPIO_bit(58+(a))
-+#define GPIO_SENSE_BIT(a) GPIO_bit(69+(a))
-+#define GAFR_HIGH_STROBE_BIT (0xfff00000)
-+#define GAFR_LOW_STROBE_BIT (0x000003ff)
-+#define GAFR_ALL_SENSE_BIT (0x00fffc00)
-+#define GPIO_KEY_SENSE(a) (69+(a))
-+
-+
-+/*
-+ * Interrupts
-+ */
-+#define IRQ_GPIO_WAKEUP IRQ_GPIO(GPIO_WAKEUP)
-+#define IRQ_GPIO_AC_IN IRQ_GPIO(GPIO_AC_IN)
-+#define IRQ_GPIO_RECORD_BTN IRQ_GPIO(GPIO_RECORD_BTN)
-+#define IRQ_GPIO_SYNC IRQ_GPIO(GPIO_SYNC)
-+#define IRQ_GPIO_USB_IN IRQ_GPIO(GPIO_USB_IN)
-+#define IRQ_GPIO_JACKET_DETECT IRQ_GPIO(GPIO_JACKET_DETECT)
-+#define IRQ_GPIO_nSD_INT IRQ_GPIO(GPIO_nSD_INT)
-+#define IRQ_GPIO_nSD_DETECT IRQ_GPIO(GPIO_nSD_DETECT)
-+#define IRQ_GPIO_BAT1_CRG IRQ_GPIO(GPIO_BAT1_CRG)
-+#define IRQ_GPIO_CF_CD IRQ_GPIO(GPIO_CF_CD)
-+#define IRQ_GPIO_BAT0_CRG IRQ_GPIO(GPIO_BAT0_CRG)
-+#define IRQ_GPIO_TC6393_INT IRQ_GPIO(GPIO_TC6393_INT)
-+#define IRQ_GPIO_BAT0_LOW IRQ_GPIO(GPIO_BAT0_LOW)
-+#define IRQ_GPIO_EAR_IN IRQ_GPIO(GPIO_EAR_IN)
-+#define IRQ_GPIO_CF_IRQ IRQ_GPIO(GPIO_CF_IRQ)
-+#define IRQ_GPIO_ON_KEY IRQ_GPIO(GPIO_ON_KEY)
-+#define IRQ_GPIO_VGA_LINE IRQ_GPIO(GPIO_VGA_LINE)
-+#define IRQ_GPIO_TP_INT IRQ_GPIO(GPIO_TP_INT)
-+#define IRQ_GPIO_JC_CF_IRQ IRQ_GPIO(GPIO_JC_CF_IRQ)
-+#define IRQ_GPIO_BAT_LOCKED IRQ_GPIO(GPIO_BAT_LOCKED)
-+#define IRQ_GPIO_BAT1_LOW IRQ_GPIO(GPIO_BAT1_LOW)
-+#define IRQ_GPIO_KEY_SENSE(a) IRQ_GPIO(69+(a))
-+
-+#define IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO(GPIO_MAIN_BAT_LOW)
-+
-+// CS
-+#define CS_MAX1111 1
-+#define CS_ADS7846 2
-+#define CS_LZ9JG18 3
-+
-+#define LOGICAL_WAKEUP_SRC
-+
-+#endif /* _ASM_ARCH_TOSA_H_ */
-diff -Nur linux_c860_org/include/asm-arm/arch-pxa/tosa_ac97_codec.h linux/include/asm-arm/arch-pxa/tosa_ac97_codec.h
---- linux_c860_org/include/asm-arm/arch-pxa/tosa_ac97_codec.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/include/asm-arm/arch-pxa/tosa_ac97_codec.h 2004-06-10 21:09:11.000000000 +0900
-@@ -0,0 +1,32 @@
-+/*
-+ * linux/include/asm-arm/arch-pxa/tosa_ac97_codec.h
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ */
-+#ifndef _TOSA_AC97_CODEC_H_
-+#define _TOSA_AC97_CODEC_H_
-+
-+//#define USE_AC97_INTERRUPT
-+
-+extern int pxa_ac97_get(struct ac97_codec **, unsigned char *);
-+extern void pxa_ac97_put(unsigned char *);
-+extern unsigned int ac97_set_dac_rate(struct ac97_codec *, unsigned int);
-+extern unsigned int ac97_set_adc_rate(struct ac97_codec *, unsigned int);
-+
-+extern struct ac97_codec *codec;
-+#define ac97_read(r) codec->codec_read(codec, r)
-+#define ac97_write(r, v) codec->codec_write(codec, r, v);
-+#define ac97_bit_clear(r, v) codec->codec_bit_clear(codec, r, v)
-+#define ac97_bit_set(r, v) codec->codec_bit_set(codec, r, v)
-+
-+/* Function1 */
-+#define AC97_JIEN (1 << 12)
-+#define AC97_FRC (1 << 11)
-+/* Function2 */
-+#define AC97_AMUTE (1 << 15) //DAC Auto-Mute Enable(read-only)
-+#define AC97_AMEN (1 << 7) //DAC Auto-Mute Enable
-+
-+#endif /* _TOSA_AC97_CODEC_H_ */
-diff -Nur linux_c860_org/include/asm-arm/arch-pxa/tosa_wm9712.h linux/include/asm-arm/arch-pxa/tosa_wm9712.h
---- linux_c860_org/include/asm-arm/arch-pxa/tosa_wm9712.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/include/asm-arm/arch-pxa/tosa_wm9712.h 2004-06-10 21:13:20.000000000 +0900
-@@ -0,0 +1,204 @@
-+/*
-+ * linux/drivers/sound/tosa_wm9712.h
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * Sound Driver for WM9712 codec device header file
-+ *
-+ * Base on:
-+ * linux/drivers/sound/poodle_wm8731.h
-+ *
-+ * Copyright (C) 2002 SHARP
-+ *
-+ *
-+ * 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.
-+ *
-+ * Change Log
-+ *
-+ */
-+#ifndef _WM9712_H_
-+#define _WM9712_H_
-+
-+#define TRUE 1
-+#define FALSE 0
-+
-+// Line input volume ctrl registers
-+#define LINEIN_MUTE_H (1 << 15) //Headphone
-+#define LINEIN_MUTE_S (1 << 14) //Speaker
-+#define LINEIN_MUTE_P (1 << 13) //Phone
-+#define LINEIN_MUTE_ALL ( LINEIN_MUTE_H | \
-+ LINEIN_MUTE_S | \
-+ LINEIN_MUTE_P )
-+
-+// Headphone volume ctrl
-+#define HP_MUTE (1 << 15)
-+#define HP_ZC_ENABLE (1 << 7)
-+
-+// Speaker volume ctrl
-+#define SP_MUTE (1 << 15)
-+#define SP_SRC (1 << 8)
-+#define SP_ZC_ENABLE (1 << 7)
-+#define SP_INV (1 << 6)
-+
-+// Initial value
-+#define INIT_HP_VOL (0) // Initial Volume 0dB
-+#define INIT_SP_VOL (0) // Initial Volume 0dB
-+#define INIT_LINE_VOL (8) // Initial Volume 0dB
-+#define INIT_DAC_VOL (8) // Initial Volume 0dB
-+#define MAX_HP_VOL (63)
-+#define MIN_HP_VOL (0)
-+#define MAX_SP_VOL (63)
-+#define MIN_SP_VOL (0)
-+#define MAX_LINE_VOL (31)
-+#define MIN_LINE_VOL (0)
-+#define MAX_DAC_VOL (31)
-+#define MIN_DAC_VOL (0)
-+
-+//DAC Volume control
-+#define DAC_MUTE_H (1 << 15) //Headphone
-+#define DAC_MUTE_S (1 << 14) //Speaker
-+#define DAC_MUTE_P (1 << 13) //Phone
-+#define DAC_MUTE_ALL ( DAC_MUTE_H | \
-+ DAC_MUTE_S | \
-+ DAC_MUTE_P )
-+
-+// Analog Audio path ctrl register (0000100)
-+#define SIDETONE_ENABLE (1<<5)
-+#define SIDETONE_DISABLE ( 0 )
-+#define ST_ATTN_6dB ( (0) << 6 )
-+#define ST_ATTN_9dB ( (1) << 6 )
-+#define ST_ATTN_12dB ( (2) << 6 )
-+#define ST_ATTN_15dB ( (3) << 6 )
-+#define DAC_OFF ( 0 )
-+#define DAC_SELECT ( 1 << 4 )
-+#define BYPASS_ENABLE ( 1 << 3 )
-+#define BYPASS_DISABLE ( 0 )
-+#define INPUT_MIC ( 1 << 2 )
-+#define INPUT_LINE ( 0 << 2 )
-+#define MIC_MUTE ( (1 << 13) | (1 << 14) )
-+#define REC_SELECT_MASK ( (1 << 10) | (1 << 9) | (1 << 8) | \
-+ (1 << 2) | (1 << 1) | (1 << 0) )
-+#define REC_SELECT_LINEIN ( 4 )
-+#define MIC_BOOST ( 1 << 7 )
-+
-+// Digital Audio path ctrl register (0000101)
-+#define DPC_DAC_MUTE_ON ( 1U << 3 )
-+#define DPC_DAC_MUTE_OFF ( 0U )
-+#define DPC_DAC_MUTE_MASK (~ ( 1U << 3 ) )
-+#define DEEMPHASIS_MODE(x) ( (( x ) & 3U ) << 1 )
-+#define DPC_DEEMPHASIS_MASK (~ ( 3U << 1 ) )
-+#define DPC_ADC_HPF_ENABLE ( 1U )
-+#define DPC_ADC_HPF_DISABLE ( 0U )
-+#define DPC_INIT ( 0U )
-+
-+// Power Consumption
-+#define NUM_OF_WM9712_DEV ( 4 )
-+#define WM9712_DEV_TS ( 0 )
-+#define WM9712_DEV_AUDIO ( 1 )
-+#define WM9712_DEV_AUDIOIN ( 2 )
-+#define WM9712_DEV_TMP ( 3 )
-+
-+#define WM9712_PWR_OFF ( 0 )
-+#define WM9712_PWR_REC ( 1 )
-+#define WM9712_PWR_PLAY ( 2 )
-+#define WM9712_PWR_REC_HP ( 3 )
-+#define WM9712_PWR_PLAY_HP ( 4 )
-+#define WM9712_PWR_REC_MIC ( 5 )
-+#define WM9712_PWR_PLAY_MIC ( 6 )
-+#define WM9712_PWR_TP_WAIT ( 7 )
-+#define WM9712_PWR_TP_CONV ( 8 )
-+#define WM9712_PWR_ENMICBIAS ( 9 )
-+#define WM9712_PWR_FULL ( 10 )
-+
-+extern void wm9712_power_mode(int, int);
-+#define wm9712_power_mode_ts(m) wm9712_power_mode(WM9712_DEV_TS, m)
-+#define wm9712_power_mode_audio(m) wm9712_power_mode(WM9712_DEV_AUDIO, m)
-+#define wm9712_power_mode_audioin(m) wm9712_power_mode(WM9712_DEV_AUDIOIN, m)
-+#define wm9712_power_mode_tmp(m) wm9712_power_mode(WM9712_DEV_TMP, m)
-+#ifdef CONFIG_PM
-+extern void lock_FCS_AC97(int, int);
-+#define lock_FCS_AC97_ts(m) lock_FCS_AC97(WM9712_DEV_TS, m)
-+#define lock_FCS_AC97_audio(m) lock_FCS_AC97(WM9712_DEV_AUDIO, m)
-+#endif /* CONFIG_PM */
-+
-+// Digital Audio Interface Format register (0000111)
-+#define SLAVE ( 0 )
-+#define MASTER ( 1U << 6 )
-+#define I2S_MODE ( 2U )
-+#define LEFT_JUSTIFIED ( 1U )
-+#define RIGHT_JUSTIFIED ( 0U )
-+#define IWL_16BIT ( 0 )
-+#define IWL_20BIT ( 1U << 2 )
-+#define IWL_24BIT ( 2U << 2 )
-+#define IWL_32BIT ( 3U << 2 )
-+#define LRSWAP_DISABLE ( 0U )
-+#define LRSWAP_ENABLE ( 1U << 5 )
-+#define LRP_RIGHT_HIGH ( 0U )
-+#define LRP_RIGHT_LOW ( 1U )
-+
-+// Sampling ctrl register defines (0001000)
-+#define SRC_CLKOUT_DIV ( 1 << 7 )
-+#define SRC_CLKIN_DIV ( 1 << 6 )
-+#define SRC_BOTH_44KHZ ( 8 << 2 )
-+#define SRC_BOTH_48KHZ ( 0 << 2 )
-+#define SRC_BOTH_8KHZ ( 3 << 2 )
-+#define SRC_OSR_256FS ( 0 ) // 12.288MHz/48kHz,11.2896MHz/44.1kHz
-+#define SRC_OSR_384FS ( 1 << 1 ) // 18.432MHz/48kHz,16.9344MHz/44.1kHz
-+#define SRC_OSR_250FS ( 0 ) // 12MHz/48 kHz
-+#define SRC_OSR_272FS ( 1 << 1 ) // 12MHz/44.1kHz
-+#define SRC_USB_MODE ( 1 )
-+#define SRC_NORMAL_MODE ( 0 )
-+#define DIGITAL_IF_ACTIVE ( 1 ) // digital interface active
-+#define DIGITAL_IF_INACTIVE ( 0 )
-+
-+typedef struct {
-+ int left;
-+ int right;
-+} GAIN_SETTINGS;
-+
-+typedef struct {
-+ unsigned short mode;
-+ GAIN_SETTINGS output;
-+ GAIN_SETTINGS input;
-+ int frequency;
-+} SOUND_SETTINGS;
-+
-+// mode
-+#define SOUND_PLAY_MODE (0x0001)
-+#define SOUND_REC_MODE (0x0002)
-+#define SOUND_MODE_MASK (0x0003)
-+
-+// volume
-+enum {
-+ VOLUME_IGNORE = -2,
-+ VOLUME_MUTE = -1
-+};
-+#define MAX_VOLUME MAX_HP_VOL
-+#define MIN_VOLUME MIN_HP_VOL
-+#define MAX_INPUT_VOLUME MAX_LINE_VOL
-+#define MIN_INPUT_VOLUME MIN_LINE_VOL
-+
-+int wm9712_busy(void);
-+int wm9712_init(void);
-+void wm9712_exit(void);
-+int wm9712_open(SOUND_SETTINGS *);
-+int wm9712_close(void);
-+int wm9712_set_freq(SOUND_SETTINGS *);
-+int wm9712_set_output_volume(int, int);
-+int wm9712_set_input_gain(int, int);
-+int wm9712_set_agc(int);
-+void wm9712_suspend(void);
-+void wm9712_resume(void);
-+void wm9712_update_jack_state(void);
-+void wm9712_checkjack_sleep(void);
-+void wm9712_checkjack_wakeup(void);
-+
-+#endif /* _WM9712_H_ */
-diff -Nur linux_c860_org/include/asm-arm/arch-pxa/uncompress.h linux/include/asm-arm/arch-pxa/uncompress.h
---- linux_c860_org/include/asm-arm/arch-pxa/uncompress.h 2003-01-14 12:07:55.000000000 +0900
-+++ linux/include/asm-arm/arch-pxa/uncompress.h 2004-06-10 21:09:11.000000000 +0900
-@@ -11,6 +11,7 @@
- * Change Log
- * 31-Jul-2002 Lineo Japan, Inc.
- * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- #define FFUART ((volatile unsigned long *)0x40100000)
-@@ -35,7 +36,7 @@
- */
- static void puts(const char *s)
- {
--#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-+#if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI) || defined(CONFIG_ARCH_PXA_TOSA)
- return;
- #endif
-
-diff -Nur linux_c860_org/include/asm-arm/dma.h linux/include/asm-arm/dma.h
---- linux_c860_org/include/asm-arm/dma.h 2002-08-26 14:37:53.000000000 +0900
-+++ linux/include/asm-arm/dma.h 2004-06-10 21:13:07.000000000 +0900
-@@ -5,6 +5,7 @@
-
- #include <linux/config.h>
- #include <linux/spinlock.h>
-+#include <linux/sched.h>
- #include <asm/system.h>
- #include <asm/memory.h>
- #include <asm/scatterlist.h>
-diff -Nur linux_c860_org/include/asm-arm/hardirq.h linux/include/asm-arm/hardirq.h
---- linux_c860_org/include/asm-arm/hardirq.h 2002-08-26 14:37:53.000000000 +0900
-+++ linux/include/asm-arm/hardirq.h 2004-06-10 21:12:36.000000000 +0900
-@@ -34,6 +34,7 @@
- #define irq_exit(cpu,irq) (local_irq_count(cpu)--)
-
- #define synchronize_irq() do { } while (0)
-+#define release_irqlock(cpu) do { } while (0)
-
- #else
- #error SMP not supported
-diff -Nur linux_c860_org/include/asm-arm/pgalloc.h linux/include/asm-arm/pgalloc.h
---- linux_c860_org/include/asm-arm/pgalloc.h 2003-06-18 16:12:27.000000000 +0900
-+++ linux/include/asm-arm/pgalloc.h 2004-06-10 21:12:37.000000000 +0900
-@@ -60,40 +60,48 @@
- {
- unsigned long *ret;
-
-+ preempt_disable();
- if ((ret = pgd_quicklist) != NULL) {
- pgd_quicklist = (unsigned long *)__pgd_next(ret);
- ret[1] = ret[2];
- clean_dcache_entry(ret + 1);
- pgtable_cache_size--;
- }
-+ preempt_enable();
- return (pgd_t *)ret;
- }
-
- static inline void free_pgd_fast(pgd_t *pgd)
- {
-+ preempt_disable();
- __pgd_next(pgd) = (unsigned long) pgd_quicklist;
- pgd_quicklist = (unsigned long *) pgd;
- pgtable_cache_size++;
-+ preempt_enable();
- }
-
- static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
- {
- unsigned long *ret;
-
-+ preempt_disable();
- if((ret = pte_quicklist) != NULL) {
- pte_quicklist = (unsigned long *)__pte_next(ret);
- ret[0] = 0;
- clean_dcache_entry(ret);
- pgtable_cache_size--;
- }
-+ preempt_enable();
- return (pte_t *)ret;
- }
-
- static inline void free_pte_fast(pte_t *pte)
- {
-+ preempt_disable();
- __pte_next(pte) = (unsigned long) pte_quicklist;
- pte_quicklist = (unsigned long *) pte;
- pgtable_cache_size++;
-+ preempt_enable();
- }
-
- #else /* CONFIG_NO_PGT_CACHE */
-diff -Nur linux_c860_org/include/asm-arm/processor.h linux/include/asm-arm/processor.h
---- linux_c860_org/include/asm-arm/processor.h 2002-08-26 14:43:40.000000000 +0900
-+++ linux/include/asm-arm/processor.h 2004-06-10 21:12:37.000000000 +0900
-@@ -117,7 +117,7 @@
- /*
- * Create a new kernel thread
- */
--extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-+extern int arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
- #endif
-
-diff -Nur linux_c860_org/include/asm-arm/sharp_apm.h linux/include/asm-arm/sharp_apm.h
---- linux_c860_org/include/asm-arm/sharp_apm.h 2003-03-13 14:53:18.000000000 +0900
-+++ linux/include/asm-arm/sharp_apm.h 2004-06-10 21:13:10.000000000 +0900
-@@ -9,6 +9,7 @@
- * Change Log
- * 26-Jun-2002 SHARP Add `APM_IOC_GET_BACKPACK_STATE`
- * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
-+ * 26-Feb-2004 Lineo Solutions, Inc. for Tosa
- */
-
- #ifndef _SHARP_APM_H
-@@ -59,6 +60,10 @@
-
- #define APM_IOC_KICK_BATTERY_CHECK _IO(APM_IOC_MAGIC, 80)
-
-+#define APM_IOC_GET_JACKET_STATE _IO(APM_IOC_MAGIC, 90) /* for tosa */
-+#define APM_IOC_BATTERY_JACKET_CHK _IO(APM_IOC_MAGIC, 91)
-+#define APM_IOC_GET_CARDSLOT_ERROR _IO(APM_IOC_MAGIC, 92)
-+
-
- #define APM_IOCGWUPSRC _IOR (APM_IOC_MAGIC, 200, int) /* 0x800441c8 */
- #define APM_IOCSWUPSRC _IOWR(APM_IOC_MAGIC, 201, int) /* 0xc00441c9 */
-@@ -90,6 +95,11 @@
- #define LOCK_FCS_AC97 0x00000080
- #define LOCK_FCS_PCMCIA 0x00000100
- #define LOCK_FCS_SOUND 0x00000200
-+#define LOCK_FCS_KEY 0x00000400
-+#define LOCK_FCS_TOUCH 0x00000800
-+#define LOCK_FCS_BATTERY 0x00001000
-+#define LOCK_FCS_AC97_SUB 0x00002000
-+#define LOCK_FCS_PCMCIA2 0x00004000
- #define LOCK_FCS_USR0 0x01000000
- #define LOCK_FCS_USR1 0x02000000
- #define LOCK_FCS_USR2 0x04000000
-@@ -113,10 +123,17 @@
- #define POWER_MODE_SOUND 0x00000200
- #define POWER_MODE_KEY 0x00000400
- #define POWER_MODE_TOUCH 0x00000800
-+#define POWER_MODE_BATTERY 0x00001000
-+#define POWER_MODE_AC97_SUB 0x00002000
-+#define POWER_MODE_PCMCIA2 0x00004000
-
- #define POWER_MODE_CAUTION_MASK (POWER_MODE_MMC|POWER_MODE_STUART|POWER_MODE_UDC|POWER_MODE_PCMCIA)
-
-+#if defined(CONFIG_ARCH_PXA_TOSA)
-+#define LOCK_FCS_POWER_MODE_CORRESPOND_MASK (POWER_MODE_FFUART|POWER_MODE_STUART|POWER_MODE_BTUART|POWER_MODE_IRDA|POWER_MODE_SSP|POWER_MODE_UDC|POWER_MODE_AC97|POWER_MODE_PCMCIA|POWER_MODE_SOUND|POWER_MODE_KEY|POWER_MODE_TOUCH|POWER_MODE_BATTERY|POWER_MODE_AC97_SUB|POWER_MODE_PCMCIA2)
-+#else
- #define LOCK_FCS_POWER_MODE_CORRESPOND_MASK (POWER_MODE_FFUART|POWER_MODE_STUART|POWER_MODE_BTUART|POWER_MODE_IRDA|POWER_MODE_SSP|POWER_MODE_UDC|POWER_MODE_AC97|POWER_MODE_PCMCIA|POWER_MODE_SOUND)
-+#endif
-
- int change_power_mode(unsigned long, int);
- int lock_FCS(unsigned long, int);
-diff -Nur linux_c860_org/include/asm-arm/sharp_char.h linux/include/asm-arm/sharp_char.h
---- linux_c860_org/include/asm-arm/sharp_char.h 2003-01-14 12:07:55.000000000 +0900
-+++ linux/include/asm-arm/sharp_char.h 2004-06-10 21:09:11.000000000 +0900
-@@ -17,6 +17,7 @@
- *
- * Change Log
- * 12-Dec-2002 Sharp Corporation for Poodle and Corgi
-+ * 1-Nov-2003 Sharp Corporation for Tosa
- */
-
- #ifndef __ASM_SHARP_CHAR_H_INCLUDED
-@@ -65,7 +66,7 @@
- int status; /* set new led status if you call SHARP_LED_SETSTATUS */
- } sharp_led_status;
-
--#define SHARP_LED_WHICH_MAX 15 /* last number of LED */
-+#define SHARP_LED_WHICH_MAX 17 /* last number of LED */
-
- /* parameters for 'which' member */
- #define SHARP_LED_PDA 0 /* PDA status */
-@@ -84,6 +85,8 @@
- #define SHARP_LED_COLLIE_1 13 /* 1st pri. mail LED control */
- #define SHARP_LED_COMM 14 /* communication status */
- #define SHARP_LED_BROWSER 15 /* WWW browser status */
-+#define SHARP_LED_BLUETOOTH 16 /* Bluetooth */
-+#define SHARP_LED_WLAN 17 /* Wireless LAN */
-
- /* parameters for 'status' member */
- #define LED_PDA_RUNNING 0 /* for SHARP_LED_RUN */
-@@ -158,6 +161,14 @@
- #define LED_BROWSER_ONLINE 1 /* for SHARP_LED_BROWSER */
- #define LED_BROWSER_ERROR 2 /* for SHARP_LED_BROWSER */
-
-+#define LED_BLUETOOTH_OFFLINE 0 /* for SHARP_LED_BLUETOOTH */
-+#define LED_BLUETOOTH_OUTOFRANGE 1 /* for SHARP_LED_BLUETOOTH */
-+#define LED_BLUETOOTH_STANBY 2 /* for SHARP_LED_BLUETOOTH */
-+
-+#define LED_WLAN_OFFLINE 0 /* for SHARP_LED_WLAN */
-+#define LED_WLAN_OUTOFRANGE 1 /* for SHARP_LED_WLAN */
-+#define LED_WLAN_BLINK 2 /* for SHARP_LED_WLAN */
-+
-
- /* --- for SHARP_BUZZER device --- */
- #define SHARP_BUZZER_IOCTL_START (SHARP_DEV_IOCTL_COMMAND_START)
-@@ -257,6 +268,9 @@
- #define IRIS_KBDCTL_ENABLEKEYBOARD (SHARP_KBDCTL_IOCTL_START+16)
- #define IRIS_KBDCTL_DISABLEKEYBOARD (SHARP_KBDCTL_IOCTL_START+17)
- #define SHARP_KBDCTL_SENDKEY (SHARP_KBDCTL_IOCTL_START+18)
-+#define SHARP_KBDCTL_SETMODIFSTAT (SHARP_KBDCTL_IOCTL_START+20)
-+#define SHARP_KBDCTL_SETSWKEY (SHARP_KBDCTL_IOCTL_START+21)
-+#define SHARP_KBDCTL_GETSWKEY (SHARP_KBDCTL_IOCTL_START+22)
-
- typedef struct sharp_kbdctl_modifstat {
- int which;
-@@ -274,6 +288,11 @@
- int hold_slcode;
- } sharp_kbdctl_holdcustom;
-
-+typedef struct _sharp_kbdctl_swkey {
-+ int key;
-+ int mode;
-+} sharp_kbdctl_swkey;
-+
- #define SHARP_EXTMODIF_2ND 0x01
- #define SHARP_EXTMODIF_CAPS 0x02
- #define SHARP_EXTMODIF_NUMLOCK 0x03
-diff -Nur linux_c860_org/include/asm-arm/sharp_tc6393.h linux/include/asm-arm/sharp_tc6393.h
---- linux_c860_org/include/asm-arm/sharp_tc6393.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/include/asm-arm/sharp_tc6393.h 2004-06-10 21:09:11.000000000 +0900
-@@ -0,0 +1,333 @@
-+/*
-+ * linux/include/asm-arm/sharp_tc6393.h
-+ *
-+ * Copyright (C) 2003 SHARP
-+ *
-+ * 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.
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ *
-+ * ChangeLog:
-+ * 05-Aug-2003 SHARP Corporation
-+ *
-+ */
-+
-+#ifndef _TC6393XB_H_
-+#define _TC6393XB_H_
-+
-+//TC6393XB Resource Area Map (Offset)
-+// System Configration Register Area 0x00000000 - 0x000000FF (Size 0x00000100)
-+// NAND Flash Host Controller Register Area 0x00000100 - 0x000001FF (Size 0x00000100)
-+// USB Host Controller Register Area 0x00000300 - 0x000003FF (Size 0x00000100)
-+// LCD Host Controller Register Area 0x00000500 - 0x000005FF (Size 0x00000100)
-+// NAND Flash Control Register 0x00001000 - 0x00001007 (Size 0x00000008)
-+// USB Control Register 0x00003000 - 0x000031FF (Size 0x00000200)
-+// LCD Control Register 0x00005000 - 0x000051FF (Size 0x00000200)
-+// Local Memory 0 (32KB) 0x00010000 - 0x00017FFF (Size 0x00008000)
-+// Local Memory 0 (32KB) alias 0x00018000 - 0x0001FFFF (Size 0x00008000)
-+// Local Memory 1 (1MB) 0x00100000 - 0x001FFFFF (Size 0x00100000)
-+
-+
-+#define TC6393XB_BASE (0xf1000000)
-+
-+typedef struct {
-+ volatile unsigned char reserved1[8];
-+ // Revision ID
-+ volatile unsigned char warid;
-+ volatile unsigned char reserved2[71];
-+ // Interrupt Status
-+ volatile unsigned char r_itrsts;
-+ volatile unsigned char reserved3;
-+ // Interrupt Mask
-+ volatile unsigned char r_itrmsk;
-+ volatile unsigned char reserved4;
-+ // Interrupt Routing
-+ volatile unsigned char r_itrrot;
-+ volatile unsigned char reserved5[11];
-+ // GP Enable
-+ volatile unsigned char gpioen;
-+ // GP Alternative Enable
-+ volatile unsigned char gpaioen;
-+ volatile unsigned char reserved6[2];
-+ // GPI Status 0
-+ volatile unsigned char gpists0;
-+ // GPI Status 1
-+ volatile unsigned char gpists1;
-+ // GPI Status 2
-+ volatile unsigned char gpists2;
-+ volatile unsigned char reserved7;
-+ // GPI INT Mask 0
-+ volatile unsigned char gpintmsk0;
-+ // GPI INT Mask 1
-+ volatile unsigned char gpintmsk1;
-+ // GPI INT Mask 2
-+ volatile unsigned char gpintmsk2;
-+ volatile unsigned char reserved8;
-+ // GPI Edge Detect Enable 0
-+ volatile unsigned char gpedgen0;
-+ // GPI Edge Detect Enable 1
-+ volatile unsigned char gpedgen1;
-+ // GPI Edge Detect Enable 2
-+ volatile unsigned char gpedgen2;
-+ volatile unsigned char reserved9;
-+ // GPI Level Invert 0
-+ volatile unsigned char gplvinv0;
-+ // GPI Level Invert 1
-+ volatile unsigned char gplvinv1;
-+ // GPI Level Invert 2
-+ volatile unsigned char gplvinv2;
-+ volatile unsigned char reserved10[5];
-+ // GPO Data set 0
-+ volatile unsigned char gpodt0;
-+ // GPO Data set 1
-+ volatile unsigned char gpodt1;
-+ // GPO Data set 2
-+ volatile unsigned char gpodt2;
-+ volatile unsigned char reserved11;
-+ // GPO Data OE Contorol 0
-+ volatile unsigned char gpooe0;
-+ // GPO Data OE Contorol 1
-+ volatile unsigned char gpooe1;
-+ // GPO Data OE Contorol 2
-+ volatile unsigned char gpooe2;
-+ volatile unsigned char reserved12;
-+ // GP Internal Active Register Contorol 0
-+ volatile unsigned char gpapulc0;
-+ // GP Internal Active Register Contorol 1
-+ volatile unsigned char gpapulc1;
-+ // GP Internal Active Register Contorol 2
-+ volatile unsigned char gpIapulc2;
-+ volatile unsigned char reserved13;
-+ // GP Internal Active Register Level Contorol 0
-+ volatile unsigned char gparlv0;
-+ // GP Internal Active Register Level Contorol 1
-+ volatile unsigned char gparlv1;
-+ // GP Internal Active Register Level Contorol 2
-+ volatile unsigned char gparlv2;
-+ volatile unsigned char reserved14;
-+ // GPI Buffer Contorol 0
-+ volatile unsigned char gpibfc0;
-+ // GPI Buffer Contorol 1
-+ volatile unsigned char gpibfc1;
-+ // GPI Buffer Contorol 2
-+ volatile unsigned char gpibfc2;
-+ volatile unsigned char reserved15;
-+ // GPa Internal Activ Register Contorol 0
-+ volatile unsigned char gpaapulc0;
-+ // GPa Internal Activ Register Contorol 1
-+ volatile unsigned char gpaapulc1;
-+ volatile unsigned char reserved16[2];
-+ // GPa Internal Activ Register Level Contorol 0
-+ volatile unsigned char gpaarlv0;
-+ // GPa Internal Activ Register Level Contorol 1
-+ volatile unsigned char gpaarlv1;
-+ volatile unsigned char reserved17[2];
-+ // GPa Buffer Contorol 0
-+ volatile unsigned char gpaibfc0;
-+ // GPa Buffer Contorol 1
-+ volatile unsigned char gpaibfc1;
-+ volatile unsigned char reserved18[2];
-+ // Clock Control
-+ volatile unsigned short clkctl;
-+ // PLL2 Control
-+ volatile unsigned short pll2ctl;
-+ // PLL1 Control
-+ volatile unsigned short pll1ctl;
-+ // Device Internal Avtive Register Contorol
-+ volatile unsigned char diarctl;
-+ // Device Buffer Contorol
-+ volatile unsigned char dvbctl;
-+ volatile unsigned char reserved19[62];
-+ // Function Enable
-+ volatile unsigned char funcebl;
-+ volatile unsigned char reserved20[3];
-+ // Mode Contorol 0
-+ volatile unsigned char modectl0;
-+ // Mode Contorol 1
-+ volatile unsigned char modectl1;
-+ volatile unsigned char reserved21[22];
-+ // Configuraation Control
-+ volatile unsigned char cfctl;
-+ volatile unsigned char reserved22[2];
-+ // Debug
-+ volatile unsigned char debug;
-+} TC6393XB_SysConfig;
-+
-+#define TC6393XB_SYSCONFIG_BASE ((TC6393XB_SysConfig *)TC6393XB_BASE)
-+
-+typedef struct {
-+ // Vendor ID Register
-+ volatile unsigned short spvid;
-+ // Device ID Register
-+ volatile unsigned short spdid;
-+ // Command Register
-+ volatile unsigned short spcmd;
-+ // Status Register
-+ volatile unsigned short spst;
-+ // Revision ID Register / Class Code Register
-+ volatile unsigned short sprid_spcc;
-+ volatile unsigned char reserved1[4];
-+ // Header Tyep Register
-+ volatile unsigned char spht;
-+ volatile unsigned char reserved2;
-+ // SmartMedia Controller Register Base Address Register
-+ union {
-+ volatile unsigned short spba1;
-+ volatile unsigned short spba2;
-+ } spba;
-+ volatile unsigned char reserved3[22];
-+ // CIS Pointer Register
-+ volatile unsigned short scisp;
-+ // Subsystem Vender ID Register
-+ volatile unsigned short spsvid;
-+ // Subsystem Deviece ID Register
-+ volatile unsigned short spsdid;
-+ volatile unsigned char reserved4[4];
-+ // Capability Pointer Register
-+ volatile unsigned char sid;
-+ volatile unsigned char reserved5[7];
-+ // Interrupt Ling Register
-+ volatile unsigned char spitrl;
-+ // Interrupt Pin Register
-+ volatile unsigned char spitrp;
-+ volatile unsigned char reserved6[10];
-+ // INT Enable Register
-+ volatile unsigned char spintc;
-+ // PME Enable Register
-+ volatile unsigned char sppmec;
-+ // Event Control Register
-+ volatile unsigned char sevntcnt;
-+ volatile unsigned char reserved7;
-+ // CLKRUN Control Register
-+ volatile unsigned char spcrunc;
-+ volatile unsigned char reserved8[14];
-+ // Debug Register
-+ volatile unsigned char spdbg;
-+ volatile unsigned char reserved9[4];
-+ // SmartMedia Transaction Control Register
-+ volatile unsigned char smtrcnt;
-+ // SmartMedia Monitor Register
-+ volatile unsigned char smsts;
-+ // SmartMedia Power Supply Control Register
-+ volatile unsigned char ssmpwc;
-+ // SmartMedia Detect Control Register
-+ volatile unsigned char ssmdtc;
-+ volatile unsigned char reserved10[28];
-+ // Capability ID Register
-+ volatile unsigned char svcid;
-+ // Next Item Ptr Register
-+ volatile unsigned char svniptr;
-+ // Power Management Capabilities (PMC) Register
-+ volatile unsigned short svpmc;
-+ // Power Management Control/Status (PMCSR) Register
-+ volatile unsigned short svpmcs;
-+ // PMCSR PCI to PCI Bridge Support Extensions Register
-+ volatile unsigned char svppcbs;
-+ // Data Register
-+ volatile unsigned char svdata;
-+ volatile unsigned char reserved11[24];
-+ // CIS Register SCISRx
-+ volatile unsigned char scisr[80];
-+ // ROM Data Port Register
-+ volatile unsigned short srmdp;
-+ // ROM Index Port Register
-+ volatile unsigned char srmip;
-+ // ROM Control Register
-+ volatile unsigned char srmcr;
-+ volatile unsigned char reserved12[8];
-+ // Configration Control Register
-+ volatile unsigned char sppcnf;
-+ volatile unsigned char reserved13[2];
-+ // Monitor Select Register
-+ volatile unsigned char pfadb;
-+} TC6393XB_NandConfig;
-+
-+#define TC6393XB_NANDCONFIG_BASE ((TC6393XB_NandConfig *)(TC6393XB_BASE+0x100))
-+
-+
-+typedef struct {
-+ union {
-+ volatile struct {
-+ unsigned char sdata0; // Data Register0
-+ unsigned char sdata1; // Data Register1
-+ unsigned char sdata2; // Data Register2
-+ unsigned char sdata3; // Data Register3
-+ } data8;
-+ volatile struct {
-+ unsigned short sdata0_1; // Data Register0,1
-+ unsigned short sdata2_3; // Data Register2,3
-+ } data16;
-+ volatile struct {
-+ unsigned long sdata0_3; // Data Register 0,1,2,3
-+ } data32;
-+ } sdata;
-+ // Mode Register
-+ volatile unsigned char smode;
-+ // Status Register
-+ volatile unsigned char sustus;
-+ // Interrupt Status Register
-+ volatile unsigned char sintst;
-+ // Interrupt Mask Register
-+ volatile unsigned char sintmsk;
-+} TC6393XB_NandCtrl;
-+
-+#define TC6393XB_NANDCTRL_OFFSET 0x1000
-+#define TC6393XB_NANDCTRL_BASE ((TC6393XB_NandCtrl *)(TC6393XB_BASE+TC6393XB_NANDCTRL_OFFSET))
-+
-+
-+/* SMODE Register Command List */
-+#define SMODE_READ_COMMAND 0x15 // DataRead Command_Mode
-+#define SMODE_READ_ADDRESS 0x16 // DataRead Address_Mode
-+#define SMODE_READ_DATAREAD 0x14 // DataRead Data_Mode
-+#define SMODE_WRITE_COMMAND 0x95 // DataWrite Command_Mode
-+#define SMODE_WRITE_ADDRESS 0x96 // DataWrite Address_Mode
-+#define SMODE_WRITE_DATAWRITE 0x94 // DataWrite Data_Mode
-+
-+#define SMODE_POWER_ON 0x0C // Power Supply ON to SSFDC card
-+#define SMODE_POWER_OFF 0x08 // Power Supply OFF to SSFDC card
-+
-+#define SMODE_LED_OFF 0x00 // LED OFF
-+#define SMODE_LED_ON 0x04 // LED ON
-+
-+#define SMODE_EJECT_ON 0x68 // Ejection Demand from Penguin is Advanced
-+#define SMODE_EJECT_OFF 0x08 // Ejection Demand from Penguin is Not Advanced
-+
-+#define SMODE_LOCK 0x6C // Operates By Lock_Mode. Ejection Switch is Invalid
-+#define SMODE_UNLOCK 0x0C // Operates By UnLock_Mode.Ejection Switch is Effective
-+
-+#define SMODE_HWECC_READ_ECCCALC 0x34 // HW-ECC DataRead
-+#define SMODE_HWECC_READ_RESET_ECC 0x74 // HW-ECC ResetMode
-+#define SMODE_HWECC_READ_CALC_RESULT 0x54 // HW-ECC Calculation Result Read_Mode
-+
-+#define SMODE_HWECC_WRITE_ECCCALC 0xB4 // HW-ECC DataWrite
-+#define SMODE_HWECC_WRITE_RESET_ECC 0xF4 // HW-ECC ResetMode
-+#define SMODE_HWECC_WRITE_CALC_RESULT 0xD4 // HW-ECC Calculation Result Read_Mode
-+
-+#define SMODE_CONTROLLER_ID_READ 0x40 // Controller ID Read
-+#define SMODE_STANDBY 0x00 // SSFDC card Changes Standby State
-+
-+#define SMODE_WE 0x80
-+#define SMODE_ECC1 0x40
-+#define SMODE_ECC0 0x20
-+#define SMODE_CE 0x10
-+#define SMODE_PCNT1 0x08
-+#define SMODE_PCNT0 0x04
-+#define SMODE_ALE 0x02
-+#define SMODE_CLE 0x01
-+
-+#define SMODE_SELECT (SMODE_WE|SMODE_CE|SMODE_PCNT0)
-+#define SMODE_DESELECT 0x00 //Changes Standby State
-+
-+/* SUSTUS Register */
-+#define SUSTUS_BUSY 0x80
-+
-+#endif
-diff -Nur linux_c860_org/include/asm-arm/sharp_tc6393_usb.h linux/include/asm-arm/sharp_tc6393_usb.h
---- linux_c860_org/include/asm-arm/sharp_tc6393_usb.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/include/asm-arm/sharp_tc6393_usb.h 2004-06-10 21:09:11.000000000 +0900
-@@ -0,0 +1,22 @@
-+/*
-+ * linux/include/asm-arm/sharp_tc6393_usb.h
-+ *
-+ * Sharp PDA Driver Header File
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ *
-+ */
-+
-+#ifndef _SHARP_TC6393_USB_H
-+#define _SHARP_TC6393_USB_H
-+
-+#define TC6393_OHCI_IOC_MAGIC 'U'
-+
-+#define TC6393_OHCI_IOC_PDOWN _IO(TC6393_OHCI_IOC_MAGIC, 10)
-+#define TC6393_OHCI_IOC_PON _IO(TC6393_OHCI_IOC_MAGIC, 11)
-+#define TC6393_OHCI_IOC_PCHECK _IO(TC6393_OHCI_IOC_MAGIC, 12)
-+
-+#endif /* _SHARP_TC6393_USB_H */
-diff -Nur linux_c860_org/include/asm-arm/smplock.h linux/include/asm-arm/smplock.h
---- linux_c860_org/include/asm-arm/smplock.h 2002-08-26 14:37:53.000000000 +0900
-+++ linux/include/asm-arm/smplock.h 2004-06-10 21:12:37.000000000 +0900
-@@ -3,12 +3,17 @@
- *
- * Default SMP lock implementation
- */
-+#include <linux/config.h>
- #include <linux/interrupt.h>
- #include <linux/spinlock.h>
-
- extern spinlock_t kernel_flag;
-
-+#ifdef CONFIG_PREEMPT
-+#define kernel_locked() preempt_get_count()
-+#else
- #define kernel_locked() spin_is_locked(&kernel_flag)
-+#endif
-
- /*
- * Release global kernel lock and global interrupt lock
-@@ -40,8 +45,14 @@
- */
- static inline void lock_kernel(void)
- {
-+#ifdef CONFIG_PREEMPT
-+ if (current->lock_depth == -1)
-+ spin_lock(&kernel_flag);
-+ ++current->lock_depth;
-+#else
- if (!++current->lock_depth)
- spin_lock(&kernel_flag);
-+#endif
- }
-
- static inline void unlock_kernel(void)
-diff -Nur linux_c860_org/include/asm-arm/softirq.h linux/include/asm-arm/softirq.h
---- linux_c860_org/include/asm-arm/softirq.h 2002-08-26 14:37:53.000000000 +0900
-+++ linux/include/asm-arm/softirq.h 2004-06-10 21:12:37.000000000 +0900
-@@ -5,20 +5,22 @@
- #include <asm/hardirq.h>
-
- #define __cpu_bh_enable(cpu) \
-- do { barrier(); local_bh_count(cpu)--; } while (0)
-+ do { barrier(); local_bh_count(cpu)--; preempt_enable(); } while (0)
- #define cpu_bh_disable(cpu) \
-- do { local_bh_count(cpu)++; barrier(); } while (0)
-+ do { preempt_disable(); local_bh_count(cpu)++; barrier(); } while (0)
-
- #define local_bh_disable() cpu_bh_disable(smp_processor_id())
- #define __local_bh_enable() __cpu_bh_enable(smp_processor_id())
-
- #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
-
--#define local_bh_enable() \
-+#define _local_bh_enable() \
- do { \
- unsigned int *ptr = &local_bh_count(smp_processor_id()); \
- if (!--*ptr && ptr[-2]) \
- __asm__("bl%? __do_softirq": : : "lr");/* out of line */\
- } while (0)
-
-+#define local_bh_enable() do { _local_bh_enable(); preempt_enable(); } while (0)
-+
- #endif /* __ASM_SOFTIRQ_H */
-diff -Nur linux_c860_org/include/asm-cris/processor.h linux/include/asm-cris/processor.h
---- linux_c860_org/include/asm-cris/processor.h 2002-08-26 14:38:01.000000000 +0900
-+++ linux/include/asm-cris/processor.h 2004-06-10 21:09:11.000000000 +0900
-@@ -81,7 +81,7 @@
- #define INIT_THREAD { \
- 0, 0, 0x20 } /* ccr = int enable, nothing else */
-
--extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
- /* give the thread a program location
- * set user-mode (The 'U' flag (User mode flag) is CCR/DCCR bit 8)
-diff -Nur linux_c860_org/include/asm-i386/hardirq.h linux/include/asm-i386/hardirq.h
---- linux_c860_org/include/asm-i386/hardirq.h 2002-08-26 14:37:47.000000000 +0900
-+++ linux/include/asm-i386/hardirq.h 2004-06-10 21:09:11.000000000 +0900
-@@ -19,12 +19,16 @@
-
- /*
- * Are we in an interrupt context? Either doing bottom half
-- * or hardware interrupt processing?
-+ * or hardware interrupt processing? Note the preempt check,
-+ * this is both a bugfix and an optimization. If we are
-+ * preemptible, we cannot be in an interrupt.
- */
--#define in_interrupt() ({ int __cpu = smp_processor_id(); \
-- (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); })
-+#define in_interrupt() (preempt_is_disabled() && \
-+ ({unsigned long __cpu = smp_processor_id(); \
-+ (local_irq_count(__cpu) + local_bh_count(__cpu) != 0); }))
-
--#define in_irq() (local_irq_count(smp_processor_id()) != 0)
-+#define in_irq() (preempt_is_disabled() && \
-+ (local_irq_count(smp_processor_id()) != 0))
-
- #ifndef CONFIG_SMP
-
-@@ -36,6 +40,8 @@
-
- #define synchronize_irq() barrier()
-
-+#define release_irqlock(cpu) do { } while (0)
-+
- #else
-
- #include <asm/atomic.h>
-diff -Nur linux_c860_org/include/asm-i386/highmem.h linux/include/asm-i386/highmem.h
---- linux_c860_org/include/asm-i386/highmem.h 2002-08-26 14:37:48.000000000 +0900
-+++ linux/include/asm-i386/highmem.h 2004-06-10 21:09:11.000000000 +0900
-@@ -88,6 +88,7 @@
- enum fixed_addresses idx;
- unsigned long vaddr;
-
-+ preempt_disable();
- if (page < highmem_start_page)
- return page_address(page);
-
-@@ -109,8 +110,10 @@
- unsigned long vaddr = (unsigned long) kvaddr;
- enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id();
-
-- if (vaddr < FIXADDR_START) // FIXME
-+ if (vaddr < FIXADDR_START) { // FIXME
-+ preempt_enable();
- return;
-+ }
-
- if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN+idx))
- BUG();
-@@ -122,6 +125,8 @@
- pte_clear(kmap_pte-idx);
- __flush_tlb_one(vaddr);
- #endif
-+
-+ preempt_enable();
- }
-
- #endif /* __KERNEL__ */
-diff -Nur linux_c860_org/include/asm-i386/hw_irq.h linux/include/asm-i386/hw_irq.h
---- linux_c860_org/include/asm-i386/hw_irq.h 2002-08-26 14:37:48.000000000 +0900
-+++ linux/include/asm-i386/hw_irq.h 2004-06-10 21:09:11.000000000 +0900
-@@ -95,6 +95,18 @@
- #define __STR(x) #x
- #define STR(x) __STR(x)
-
-+#define GET_CURRENT \
-+ "movl %esp, %ebx\n\t" \
-+ "andl $-8192, %ebx\n\t"
-+
-+#ifdef CONFIG_PREEMPT
-+#define BUMP_LOCK_COUNT \
-+ GET_CURRENT \
-+ "incl 4(%ebx)\n\t"
-+#else
-+#define BUMP_LOCK_COUNT
-+#endif
-+
- #define SAVE_ALL \
- "cld\n\t" \
- "pushl %es\n\t" \
-@@ -108,15 +120,12 @@
- "pushl %ebx\n\t" \
- "movl $" STR(__KERNEL_DS) ",%edx\n\t" \
- "movl %edx,%ds\n\t" \
-- "movl %edx,%es\n\t"
-+ "movl %edx,%es\n\t" \
-+ BUMP_LOCK_COUNT
-
- #define IRQ_NAME2(nr) nr##_interrupt(void)
- #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
-
--#define GET_CURRENT \
-- "movl %esp, %ebx\n\t" \
-- "andl $-8192, %ebx\n\t"
--
- /*
- * SMP has a few special interrupts for IPI messages
- */
-diff -Nur linux_c860_org/include/asm-i386/i387.h linux/include/asm-i386/i387.h
---- linux_c860_org/include/asm-i386/i387.h 2002-08-26 14:37:48.000000000 +0900
-+++ linux/include/asm-i386/i387.h 2004-06-10 21:09:11.000000000 +0900
-@@ -12,6 +12,7 @@
- #define __ASM_I386_I387_H
-
- #include <linux/sched.h>
-+#include <linux/spinlock.h>
- #include <asm/processor.h>
- #include <asm/sigcontext.h>
- #include <asm/user.h>
-@@ -24,7 +25,7 @@
- extern void restore_fpu( struct task_struct *tsk );
-
- extern void kernel_fpu_begin(void);
--#define kernel_fpu_end() stts()
-+#define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
-
-
- #define unlazy_fpu( tsk ) do { \
-diff -Nur linux_c860_org/include/asm-i386/pgalloc.h linux/include/asm-i386/pgalloc.h
---- linux_c860_org/include/asm-i386/pgalloc.h 2002-08-26 14:37:48.000000000 +0900
-+++ linux/include/asm-i386/pgalloc.h 2004-06-10 21:09:11.000000000 +0900
-@@ -75,20 +75,26 @@
- {
- unsigned long *ret;
-
-+ preempt_disable();
- if ((ret = pgd_quicklist) != NULL) {
- pgd_quicklist = (unsigned long *)(*ret);
- ret[0] = 0;
- pgtable_cache_size--;
-- } else
-+ preempt_enable();
-+ } else {
-+ preempt_enable();
- ret = (unsigned long *)get_pgd_slow();
-+ }
- return (pgd_t *)ret;
- }
-
- static inline void free_pgd_fast(pgd_t *pgd)
- {
-+ preempt_disable();
- *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
- pgd_quicklist = (unsigned long *) pgd;
- pgtable_cache_size++;
-+ preempt_enable();
- }
-
- static inline void free_pgd_slow(pgd_t *pgd)
-@@ -119,19 +125,23 @@
- {
- unsigned long *ret;
-
-+ preempt_disable();
- if ((ret = (unsigned long *)pte_quicklist) != NULL) {
- pte_quicklist = (unsigned long *)(*ret);
- ret[0] = ret[1];
- pgtable_cache_size--;
- }
-+ preempt_enable();
- return (pte_t *)ret;
- }
-
- static inline void pte_free_fast(pte_t *pte)
- {
-+ preempt_disable();
- *(unsigned long *)pte = (unsigned long) pte_quicklist;
- pte_quicklist = (unsigned long *) pte;
- pgtable_cache_size++;
-+ preempt_enable();
- }
-
- static __inline__ void pte_free_slow(pte_t *pte)
-diff -Nur linux_c860_org/include/asm-i386/processor.h linux/include/asm-i386/processor.h
---- linux_c860_org/include/asm-i386/processor.h 2002-08-26 14:37:47.000000000 +0900
-+++ linux/include/asm-i386/processor.h 2004-06-10 21:09:11.000000000 +0900
-@@ -429,7 +429,7 @@
- /*
- * create a kernel thread without removing it from tasklists
- */
--extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
- /* Copy and release all segment info associated with a VM */
- extern void copy_segments(struct task_struct *p, struct mm_struct * mm);
-diff -Nur linux_c860_org/include/asm-i386/smplock.h linux/include/asm-i386/smplock.h
---- linux_c860_org/include/asm-i386/smplock.h 2002-08-26 14:37:48.000000000 +0900
-+++ linux/include/asm-i386/smplock.h 2004-06-10 21:09:11.000000000 +0900
-@@ -10,7 +10,15 @@
-
- extern spinlock_t kernel_flag;
-
-+#ifdef CONFIG_SMP
- #define kernel_locked() spin_is_locked(&kernel_flag)
-+#else
-+#ifdef CONFIG_PREEMPT
-+#define kernel_locked() preempt_get_count()
-+#else
-+#define kernel_locked() 1
-+#endif
-+#endif
-
- /*
- * Release global kernel lock and global interrupt lock
-@@ -42,6 +50,11 @@
- */
- static __inline__ void lock_kernel(void)
- {
-+#ifdef CONFIG_PREEMPT
-+ if (current->lock_depth == -1)
-+ spin_lock(&kernel_flag);
-+ ++current->lock_depth;
-+#else
- #if 1
- if (!++current->lock_depth)
- spin_lock(&kernel_flag);
-@@ -54,6 +67,7 @@
- :"=m" (__dummy_lock(&kernel_flag)),
- "=m" (current->lock_depth));
- #endif
-+#endif
- }
-
- static __inline__ void unlock_kernel(void)
-diff -Nur linux_c860_org/include/asm-i386/softirq.h linux/include/asm-i386/softirq.h
---- linux_c860_org/include/asm-i386/softirq.h 2002-08-26 14:37:47.000000000 +0900
-+++ linux/include/asm-i386/softirq.h 2004-06-10 21:09:11.000000000 +0900
-@@ -6,9 +6,9 @@
- #include <linux/stringify.h>
-
- #define __cpu_bh_enable(cpu) \
-- do { barrier(); local_bh_count(cpu)--; } while (0)
-+ do { barrier(); local_bh_count(cpu)--; preempt_enable(); } while (0)
- #define cpu_bh_disable(cpu) \
-- do { local_bh_count(cpu)++; barrier(); } while (0)
-+ do { preempt_disable(); local_bh_count(cpu)++; barrier(); } while (0)
-
- #define local_bh_disable() cpu_bh_disable(smp_processor_id())
- #define __local_bh_enable() __cpu_bh_enable(smp_processor_id())
-@@ -23,7 +23,7 @@
- * If you change the offsets in irq_stat then you have to
- * update this code as well.
- */
--#define local_bh_enable() \
-+#define _local_bh_enable() \
- do { \
- unsigned int *ptr = &local_bh_count(smp_processor_id()); \
- \
-@@ -49,4 +49,6 @@
- /* no registers clobbered */ ); \
- } while (0)
-
-+#define local_bh_enable() do { _local_bh_enable(); preempt_enable(); } while (0)
-+
- #endif /* __ASM_SOFTIRQ_H */
-diff -Nur linux_c860_org/include/asm-i386/spinlock.h linux/include/asm-i386/spinlock.h
---- linux_c860_org/include/asm-i386/spinlock.h 2002-08-26 14:37:47.000000000 +0900
-+++ linux/include/asm-i386/spinlock.h 2004-06-10 21:09:11.000000000 +0900
-@@ -81,7 +81,7 @@
- :"=m" (lock->lock) : : "memory"
-
-
--static inline void spin_unlock(spinlock_t *lock)
-+static inline void _raw_spin_unlock(spinlock_t *lock)
- {
- #if SPINLOCK_DEBUG
- if (lock->magic != SPINLOCK_MAGIC)
-@@ -101,7 +101,7 @@
- :"=q" (oldval), "=m" (lock->lock) \
- :"0" (oldval) : "memory"
-
--static inline void spin_unlock(spinlock_t *lock)
-+static inline void _raw_spin_unlock(spinlock_t *lock)
- {
- char oldval = 1;
- #if SPINLOCK_DEBUG
-@@ -117,7 +117,7 @@
-
- #endif
-
--static inline int spin_trylock(spinlock_t *lock)
-+static inline int _raw_spin_trylock(spinlock_t *lock)
- {
- char oldval;
- __asm__ __volatile__(
-@@ -127,7 +127,7 @@
- return oldval > 0;
- }
-
--static inline void spin_lock(spinlock_t *lock)
-+static inline void _raw_spin_lock(spinlock_t *lock)
- {
- #if SPINLOCK_DEBUG
- __label__ here;
-@@ -183,7 +183,7 @@
- */
- /* the spinlock helpers are in arch/i386/kernel/semaphore.c */
-
--static inline void read_lock(rwlock_t *rw)
-+static inline void _raw_read_lock(rwlock_t *rw)
- {
- #if SPINLOCK_DEBUG
- if (rw->magic != RWLOCK_MAGIC)
-@@ -192,7 +192,7 @@
- __build_read_lock(rw, "__read_lock_failed");
- }
-
--static inline void write_lock(rwlock_t *rw)
-+static inline void _raw_write_lock(rwlock_t *rw)
- {
- #if SPINLOCK_DEBUG
- if (rw->magic != RWLOCK_MAGIC)
-@@ -201,10 +201,10 @@
- __build_write_lock(rw, "__write_lock_failed");
- }
-
--#define read_unlock(rw) asm volatile("lock ; incl %0" :"=m" ((rw)->lock) : : "memory")
--#define write_unlock(rw) asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" ((rw)->lock) : : "memory")
-+#define _raw_read_unlock(rw) asm volatile("lock ; incl %0" :"=m" ((rw)->lock) : : "memory")
-+#define _raw_write_unlock(rw) asm volatile("lock ; addl $" RW_LOCK_BIAS_STR ",%0":"=m" ((rw)->lock) : : "memory")
-
--static inline int write_trylock(rwlock_t *lock)
-+static inline int _raw_write_trylock(rwlock_t *lock)
- {
- atomic_t *count = (atomic_t *)lock;
- if (atomic_sub_and_test(RW_LOCK_BIAS, count))
-diff -Nur linux_c860_org/include/asm-ia64/processor.h linux/include/asm-ia64/processor.h
---- linux_c860_org/include/asm-ia64/processor.h 2002-08-26 14:37:56.000000000 +0900
-+++ linux/include/asm-ia64/processor.h 2004-06-10 21:09:11.000000000 +0900
-@@ -463,7 +463,7 @@
- * do_basic_setup() and the timing is such that free_initmem() has
- * been called already.
- */
--extern int kernel_thread (int (*fn)(void *), void *arg, unsigned long flags);
-+extern int arch_kernel_thread (int (*fn)(void *), void *arg, unsigned long flags);
-
- /* Copy and release all segment info associated with a VM */
- #define copy_segments(tsk, mm) do { } while (0)
-diff -Nur linux_c860_org/include/asm-m68k/processor.h linux/include/asm-m68k/processor.h
---- linux_c860_org/include/asm-m68k/processor.h 2002-08-26 14:37:50.000000000 +0900
-+++ linux/include/asm-m68k/processor.h 2004-06-10 21:09:11.000000000 +0900
-@@ -105,7 +105,7 @@
- {
- }
-
--extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
- #define copy_segments(tsk, mm) do { } while (0)
- #define release_segments(mm) do { } while (0)
-diff -Nur linux_c860_org/include/asm-mips/processor.h linux/include/asm-mips/processor.h
---- linux_c860_org/include/asm-mips/processor.h 2002-08-26 14:37:48.000000000 +0900
-+++ linux/include/asm-mips/processor.h 2004-06-10 21:09:11.000000000 +0900
-@@ -208,7 +208,7 @@
- /* Free all resources held by a thread. */
- #define release_thread(thread) do { } while(0)
-
--extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
- /* Copy and release all segment info associated with a VM */
- #define copy_segments(p, mm) do { } while(0)
-diff -Nur linux_c860_org/include/asm-mips64/processor.h linux/include/asm-mips64/processor.h
---- linux_c860_org/include/asm-mips64/processor.h 2002-08-26 14:37:58.000000000 +0900
-+++ linux/include/asm-mips64/processor.h 2004-06-10 21:09:11.000000000 +0900
-@@ -231,7 +231,7 @@
- /* Free all resources held by a thread. */
- #define release_thread(thread) do { } while(0)
-
--extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
- /* Copy and release all segment info associated with a VM */
- #define copy_segments(p, mm) do { } while(0)
-diff -Nur linux_c860_org/include/asm-parisc/processor.h linux/include/asm-parisc/processor.h
---- linux_c860_org/include/asm-parisc/processor.h 2002-08-26 14:38:01.000000000 +0900
-+++ linux/include/asm-parisc/processor.h 2004-06-10 21:09:11.000000000 +0900
-@@ -305,7 +305,7 @@
-
- /* Free all resources held by a thread. */
- extern void release_thread(struct task_struct *);
--extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
- #define copy_segments(tsk, mm) do { } while (0)
- #define release_segments(mm) do { } while (0)
-diff -Nur linux_c860_org/include/asm-ppc/processor.h linux/include/asm-ppc/processor.h
---- linux_c860_org/include/asm-ppc/processor.h 2002-08-26 14:37:52.000000000 +0900
-+++ linux/include/asm-ppc/processor.h 2004-06-10 21:09:11.000000000 +0900
-@@ -571,7 +571,7 @@
- /*
- * Create a new kernel thread.
- */
--extern long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-+extern long arch_kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
- /*
- * Bus types
-diff -Nur linux_c860_org/include/asm-s390/processor.h linux/include/asm-s390/processor.h
---- linux_c860_org/include/asm-s390/processor.h 2002-08-26 14:37:59.000000000 +0900
-+++ linux/include/asm-s390/processor.h 2004-06-10 21:09:11.000000000 +0900
-@@ -116,7 +116,7 @@
-
- /* Free all resources held by a thread. */
- extern void release_thread(struct task_struct *);
--extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
- /* Copy and release all segment info associated with a VM */
- #define copy_segments(nr, mm) do { } while (0)
-diff -Nur linux_c860_org/include/asm-s390x/processor.h linux/include/asm-s390x/processor.h
---- linux_c860_org/include/asm-s390x/processor.h 2002-08-26 14:38:02.000000000 +0900
-+++ linux/include/asm-s390x/processor.h 2004-06-10 21:09:11.000000000 +0900
-@@ -127,7 +127,7 @@
-
- /* Free all resources held by a thread. */
- extern void release_thread(struct task_struct *);
--extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
- /* Copy and release all segment info associated with a VM */
- #define copy_segments(nr, mm) do { } while (0)
-diff -Nur linux_c860_org/include/asm-sh/hardirq.h linux/include/asm-sh/hardirq.h
---- linux_c860_org/include/asm-sh/hardirq.h 2002-08-26 14:37:55.000000000 +0900
-+++ linux/include/asm-sh/hardirq.h 2004-06-10 21:09:11.000000000 +0900
-@@ -34,6 +34,8 @@
-
- #define synchronize_irq() barrier()
-
-+#define release_irqlock(cpu) do { } while (0)
-+
- #else
-
- #error Super-H SMP is not available
-diff -Nur linux_c860_org/include/asm-sh/processor.h linux/include/asm-sh/processor.h
---- linux_c860_org/include/asm-sh/processor.h 2002-08-26 14:37:55.000000000 +0900
-+++ linux/include/asm-sh/processor.h 2004-06-10 21:09:11.000000000 +0900
-@@ -137,7 +137,7 @@
- /*
- * create a kernel thread without removing it from tasklists
- */
--extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-+extern int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
- /*
- * Bus types
-diff -Nur linux_c860_org/include/asm-sh/smplock.h linux/include/asm-sh/smplock.h
---- linux_c860_org/include/asm-sh/smplock.h 2002-08-26 14:37:55.000000000 +0900
-+++ linux/include/asm-sh/smplock.h 2004-06-10 21:09:11.000000000 +0900
-@@ -9,15 +9,88 @@
-
- #include <linux/config.h>
-
--#ifndef CONFIG_SMP
--
-+#if !defined(CONFIG_SMP) && !defined(CONFIG_PREEMPT)
-+/*
-+ * Should never happen, since linux/smp_lock.h catches this case;
-+ * but in case this file is included directly with neither SMP nor
-+ * PREEMPT configuration, provide same dummys as linux/smp_lock.h
-+ */
- #define lock_kernel() do { } while(0)
- #define unlock_kernel() do { } while(0)
--#define release_kernel_lock(task, cpu, depth) ((depth) = 1)
--#define reacquire_kernel_lock(task, cpu, depth) do { } while(0)
-+#define release_kernel_lock(task, cpu) do { } while(0)
-+#define reacquire_kernel_lock(task) do { } while(0)
-+#define kernel_locked() 1
-+
-+#else /* CONFIG_SMP || CONFIG_PREEMPT */
-+
-+#if CONFIG_SMP
-+#error "We do not support SMP on SH yet"
-+#endif
-+/*
-+ * Default SMP lock implementation (i.e. the i386 version)
-+ */
-+
-+#include <linux/interrupt.h>
-+#include <linux/spinlock.h>
-+
-+extern spinlock_t kernel_flag;
-+#define lock_bkl() spin_lock(&kernel_flag)
-+#define unlock_bkl() spin_unlock(&kernel_flag)
-
-+#ifdef CONFIG_SMP
-+#define kernel_locked() spin_is_locked(&kernel_flag)
-+#elif CONFIG_PREEMPT
-+#define kernel_locked() preempt_get_count()
-+#else /* neither */
-+#define kernel_locked() 1
-+#endif
-+
-+/*
-+ * Release global kernel lock and global interrupt lock
-+ */
-+#define release_kernel_lock(task, cpu) \
-+do { \
-+ if (task->lock_depth >= 0) \
-+ spin_unlock(&kernel_flag); \
-+ release_irqlock(cpu); \
-+ __sti(); \
-+} while (0)
-+
-+/*
-+ * Re-acquire the kernel lock
-+ */
-+#define reacquire_kernel_lock(task) \
-+do { \
-+ if (task->lock_depth >= 0) \
-+ spin_lock(&kernel_flag); \
-+} while (0)
-+
-+/*
-+ * Getting the big kernel lock.
-+ *
-+ * This cannot happen asynchronously,
-+ * so we only need to worry about other
-+ * CPU's.
-+ */
-+static __inline__ void lock_kernel(void)
-+{
-+#ifdef CONFIG_PREEMPT
-+ if (current->lock_depth == -1)
-+ spin_lock(&kernel_flag);
-+ ++current->lock_depth;
- #else
--#error "We do not support SMP on SH"
--#endif /* CONFIG_SMP */
-+ if (!++current->lock_depth)
-+ spin_lock(&kernel_flag);
-+#endif
-+}
-+
-+static __inline__ void unlock_kernel(void)
-+{
-+ if (current->lock_depth < 0)
-+ BUG();
-+ if (--current->lock_depth < 0)
-+ spin_unlock(&kernel_flag);
-+}
-+#endif /* CONFIG_SMP || CONFIG_PREEMPT */
-
- #endif /* __ASM_SH_SMPLOCK_H */
-diff -Nur linux_c860_org/include/asm-sh/softirq.h linux/include/asm-sh/softirq.h
---- linux_c860_org/include/asm-sh/softirq.h 2002-08-26 14:37:55.000000000 +0900
-+++ linux/include/asm-sh/softirq.h 2004-06-10 21:09:11.000000000 +0900
-@@ -6,6 +6,7 @@
-
- #define local_bh_disable() \
- do { \
-+ preempt_disable(); \
- local_bh_count(smp_processor_id())++; \
- barrier(); \
- } while (0)
-@@ -14,6 +15,7 @@
- do { \
- barrier(); \
- local_bh_count(smp_processor_id())--; \
-+ preempt_enable(); \
- } while (0)
-
- #define local_bh_enable() \
-@@ -23,6 +25,7 @@
- && softirq_pending(smp_processor_id())) { \
- do_softirq(); \
- } \
-+ preempt_enable(); \
- } while (0)
-
- #define in_softirq() (local_bh_count(smp_processor_id()) != 0)
-diff -Nur linux_c860_org/include/asm-sparc/processor.h linux/include/asm-sparc/processor.h
---- linux_c860_org/include/asm-sparc/processor.h 2002-08-26 14:37:51.000000000 +0900
-+++ linux/include/asm-sparc/processor.h 2004-06-10 21:09:11.000000000 +0900
-@@ -146,7 +146,7 @@
-
- /* Free all resources held by a thread. */
- #define release_thread(tsk) do { } while(0)
--extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-+extern pid_t arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
-
- #define copy_segments(tsk, mm) do { } while (0)
-diff -Nur linux_c860_org/include/asm-sparc64/processor.h linux/include/asm-sparc64/processor.h
---- linux_c860_org/include/asm-sparc64/processor.h 2002-08-26 14:37:53.000000000 +0900
-+++ linux/include/asm-sparc64/processor.h 2004-06-10 21:09:11.000000000 +0900
-@@ -253,7 +253,7 @@
- /* Free all resources held by a thread. */
- #define release_thread(tsk) do { } while(0)
-
--extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-+extern pid_t arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-
- #define copy_segments(tsk, mm) do { } while (0)
- #define release_segments(mm) do { } while (0)
-diff -Nur linux_c860_org/include/linux/ac97_codec.h linux/include/linux/ac97_codec.h
---- linux_c860_org/include/linux/ac97_codec.h 2002-08-26 14:37:45.000000000 +0900
-+++ linux/include/linux/ac97_codec.h 2004-06-10 21:13:20.000000000 +0900
-@@ -1,3 +1,8 @@
-+/*
-+ * ChangeLog:
-+ * 1-Nov-2003 Sharp Corporation for Tosa
-+ *
-+ */
- #ifndef _AC97_CODEC_H_
- #define _AC97_CODEC_H_
-
-@@ -5,124 +10,145 @@
- #include <linux/soundcard.h>
-
- /* AC97 1.0 */
--#define AC97_RESET 0x0000 //
--#define AC97_MASTER_VOL_STEREO 0x0002 // Line Out
--#define AC97_HEADPHONE_VOL 0x0004 //
--#define AC97_MASTER_VOL_MONO 0x0006 // TAD Output
--#define AC97_MASTER_TONE 0x0008 //
--#define AC97_PCBEEP_VOL 0x000a // none
--#define AC97_PHONE_VOL 0x000c // TAD Input (mono)
--#define AC97_MIC_VOL 0x000e // MIC Input (mono)
--#define AC97_LINEIN_VOL 0x0010 // Line Input (stereo)
--#define AC97_CD_VOL 0x0012 // CD Input (stereo)
--#define AC97_VIDEO_VOL 0x0014 // none
--#define AC97_AUX_VOL 0x0016 // Aux Input (stereo)
--#define AC97_PCMOUT_VOL 0x0018 // Wave Output (stereo)
--#define AC97_RECORD_SELECT 0x001a //
--#define AC97_RECORD_GAIN 0x001c
--#define AC97_RECORD_GAIN_MIC 0x001e
--#define AC97_GENERAL_PURPOSE 0x0020
--#define AC97_3D_CONTROL 0x0022
--#define AC97_MODEM_RATE 0x0024
--#define AC97_POWER_CONTROL 0x0026
-+#define AC97_RESET 0x0000 //
-+#define AC97_MASTER_VOL_STEREO 0x0002 // Line Out
-+#define AC97_HEADPHONE_VOL 0x0004 //
-+#define AC97_MASTER_VOL_MONO 0x0006 // TAD Output
-+#define AC97_MASTER_TONE 0x0008 //
-+#define AC97_PCBEEP_VOL 0x000a // none
-+#define AC97_PHONE_VOL 0x000c // TAD Input (mono)
-+#define AC97_MIC_VOL 0x000e // MIC Input (mono)
-+#define AC97_LINEIN_VOL 0x0010 // Line Input (stereo)
-+#define AC97_CD_VOL 0x0012 // CD Input (stereo)
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+#define AC97_SIDETONE 0x0014
-+#endif /* CONFIG_ARCH_PXA_TOSA */
-+#define AC97_VIDEO_VOL 0x0014 // none
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+#define AC97_OUT3_VOL 0x0016
-+#define AC97_DAC_VOL 0x0018
-+#endif /* CONFIG_ARCH_PXA_TOSA */
-+#define AC97_AUX_VOL 0x0016 // Aux Input (stereo)
-+#define AC97_PCMOUT_VOL 0x0018 // Wave Output (stereo)
-+#define AC97_RECORD_SELECT 0x001a //
-+#define AC97_RECORD_GAIN 0x001c
-+#define AC97_RECORD_GAIN_MIC 0x001e
-+#define AC97_GENERAL_PURPOSE 0x0020
-+#define AC97_3D_CONTROL 0x0022
-+#define AC97_MODEM_RATE 0x0024
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+#define AC97_POWERDOWN 0x0024
-+#endif /* CONFIG_ARCH_PXA_TOSA */
-+#define AC97_POWER_CONTROL 0x0026
-
- /* AC'97 2.0 */
--#define AC97_EXTENDED_ID 0x0028 /* Extended Audio ID */
--#define AC97_EXTENDED_STATUS 0x002A /* Extended Audio Status */
--#define AC97_PCM_FRONT_DAC_RATE 0x002C /* PCM Front DAC Rate */
--#define AC97_PCM_SURR_DAC_RATE 0x002E /* PCM Surround DAC Rate */
--#define AC97_PCM_LFE_DAC_RATE 0x0030 /* PCM LFE DAC Rate */
--#define AC97_PCM_LR_ADC_RATE 0x0032 /* PCM LR DAC Rate */
--#define AC97_PCM_MIC_ADC_RATE 0x0034 /* PCM MIC ADC Rate */
--#define AC97_CENTER_LFE_MASTER 0x0036 /* Center + LFE Master Volume */
--#define AC97_SURROUND_MASTER 0x0038 /* Surround (Rear) Master Volume */
--#define AC97_RESERVED_3A 0x003A /* Reserved in AC '97 < 2.2 */
-+#define AC97_EXTENDED_ID 0x0028 /* Extended Audio ID */
-+#define AC97_EXTENDED_STATUS 0x002A /* Extended Audio Status */
-+#define AC97_PCM_FRONT_DAC_RATE 0x002C /* PCM Front DAC Rate */
-+#define AC97_PCM_SURR_DAC_RATE 0x002E /* PCM Surround DAC Rate */
-+#define AC97_PCM_LFE_DAC_RATE 0x0030 /* PCM LFE DAC Rate */
-+#define AC97_PCM_LR_ADC_RATE 0x0032 /* PCM LR ADC Rate */
-+#define AC97_PCM_MIC_ADC_RATE 0x0034 /* PCM MIC ADC Rate */
-+#define AC97_CENTER_LFE_MASTER 0x0036 /* Center + LFE Master Volume */
-+#define AC97_SURROUND_MASTER 0x0038 /* Surround (Rear) Master Volume */
-+#define AC97_RESERVED_3A 0x003A /* Reserved in AC '97 < 2.2 */
-
- /* AC'97 2.2 */
--#define AC97_SPDIF_CONTROL 0x003A /* S/PDIF Control */
-+#define AC97_SPDIF_CONTROL 0x003A /* S/PDIF Control */
-
- /* range 0x3c-0x58 - MODEM */
--#define AC97_EXTENDED_MODEM_ID 0x003C
--#define AC97_EXTEND_MODEM_STAT 0x003E
--#define AC97_LINE1_RATE 0x0040
--#define AC97_LINE2_RATE 0x0042
--#define AC97_HANDSET_RATE 0x0044
--#define AC97_LINE1_LEVEL 0x0046
--#define AC97_LINE2_LEVEL 0x0048
--#define AC97_HANDSET_LEVEL 0x004A
--#define AC97_GPIO_CONFIG 0x004C
--#define AC97_GPIO_POLARITY 0x004E
--#define AC97_GPIO_STICKY 0x0050
--#define AC97_GPIO_WAKE_UP 0x0052
--#define AC97_GPIO_STATUS 0x0054
--#define AC97_MISC_MODEM_STAT 0x0056
--#define AC97_RESERVED_58 0x0058
-+#define AC97_EXTENDED_MODEM_ID 0x003C
-+#define AC97_EXTEND_MODEM_STAT 0x003E
-+#define AC97_LINE1_RATE 0x0040
-+#define AC97_LINE2_RATE 0x0042
-+#define AC97_HANDSET_RATE 0x0044
-+#define AC97_LINE1_LEVEL 0x0046
-+#define AC97_LINE2_LEVEL 0x0048
-+#define AC97_HANDSET_LEVEL 0x004A
-+#define AC97_GPIO_CONFIG 0x004C
-+#define AC97_GPIO_POLARITY 0x004E
-+#define AC97_GPIO_STICKY 0x0050
-+#define AC97_GPIO_WAKE_UP 0x0052
-+#define AC97_GPIO_STATUS 0x0054
-+#define AC97_MISC_MODEM_STAT 0x0056
-+#define AC97_RESERVED_58 0x0058
-+
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+#define AC97_GPIO_FUNC 0x0056
-+#define AC97_ADITFUNC1 0x0058
-+#define AC97_ADITFUNC2 0x005c
-+#define AC97_ALC_CTL 0x0060
-+#define AC97_NOISE_CTL 0x0062
-+#define AC97_AUXDAC_CTL 0x0064
-+#define AC97_TS_REG1 0x0076
-+#define AC97_TS_REG2 0x0078
-+#define AC97_TS_READBACK 0x007a
-+#endif /* CONFIG_ARCH_PXA_TOSA */
-
- /* registers 0x005a - 0x007a are vendor reserved */
--
--#define AC97_VENDOR_ID1 0x007c
--#define AC97_VENDOR_ID2 0x007e
-+#define AC97_VENDOR_ID1 0x007c
-+#define AC97_VENDOR_ID2 0x007e
-
- /* volume control bit defines */
--#define AC97_MUTE 0x8000
--#define AC97_MICBOOST 0x0040
--#define AC97_LEFTVOL 0x3f00
--#define AC97_RIGHTVOL 0x003f
-+#define AC97_MUTE 0x8000
-+#define AC97_MICBOOST 0x0040
-+#define AC97_LEFTVOL 0x3f00
-+#define AC97_RIGHTVOL 0x003f
-
- /* record mux defines */
--#define AC97_RECMUX_MIC 0x0000
--#define AC97_RECMUX_CD 0x0101
--#define AC97_RECMUX_VIDEO 0x0202
--#define AC97_RECMUX_AUX 0x0303
--#define AC97_RECMUX_LINE 0x0404
--#define AC97_RECMUX_STEREO_MIX 0x0505
--#define AC97_RECMUX_MONO_MIX 0x0606
--#define AC97_RECMUX_PHONE 0x0707
-+#define AC97_RECMUX_MIC 0x0000
-+#define AC97_RECMUX_CD 0x0101
-+#define AC97_RECMUX_VIDEO 0x0202
-+#define AC97_RECMUX_AUX 0x0303
-+#define AC97_RECMUX_LINE 0x0404
-+#define AC97_RECMUX_STEREO_MIX 0x0505
-+#define AC97_RECMUX_MONO_MIX 0x0606
-+#define AC97_RECMUX_PHONE 0x0707
-
- /* general purpose register bit defines */
--#define AC97_GP_LPBK 0x0080 /* Loopback mode */
--#define AC97_GP_MS 0x0100 /* Mic Select 0=Mic1, 1=Mic2 */
--#define AC97_GP_MIX 0x0200 /* Mono output select 0=Mix, 1=Mic */
--#define AC97_GP_RLBK 0x0400 /* Remote Loopback - Modem line codec */
--#define AC97_GP_LLBK 0x0800 /* Local Loopback - Modem Line codec */
--#define AC97_GP_LD 0x1000 /* Loudness 1=on */
--#define AC97_GP_3D 0x2000 /* 3D Enhancement 1=on */
--#define AC97_GP_ST 0x4000 /* Stereo Enhancement 1=on */
--#define AC97_GP_POP 0x8000 /* Pcm Out Path, 0=pre 3D, 1=post 3D */
-+#define AC97_GP_LPBK 0x0080 /* Loopback mode */
-+#define AC97_GP_MS 0x0100 /* Mic Select 0=Mic1, 1=Mic2 */
-+#define AC97_GP_MIX 0x0200 /* Mono output select 0=Mix, 1=Mic */
-+#define AC97_GP_RLBK 0x0400 /* Remote Loopback - Modem line codec */
-+#define AC97_GP_LLBK 0x0800 /* Local Loopback - Modem Line codec */
-+#define AC97_GP_LD 0x1000 /* Loudness 1=on */
-+#define AC97_GP_3D 0x2000 /* 3D Enhancement 1=on */
-+#define AC97_GP_ST 0x4000 /* Stereo Enhancement 1=on */
-+#define AC97_GP_POP 0x8000 /* Pcm Out Path, 0=pre 3D, 1=post 3D */
-
- /* extended audio status and control bit defines */
--#define AC97_EA_VRA 0x0001 /* Variable bit rate enable bit */
--#define AC97_EA_DRA 0x0002 /* Double-rate audio enable bit */
--#define AC97_EA_SPDIF 0x0004 /* S/PDIF Enable bit */
--#define AC97_EA_VRM 0x0008 /* Variable bit rate for MIC enable bit */
--#define AC97_EA_CDAC 0x0040 /* PCM Center DAC is ready (Read only) */
--#define AC97_EA_SDAC 0x0040 /* PCM Surround DACs are ready (Read only) */
--#define AC97_EA_LDAC 0x0080 /* PCM LFE DAC is ready (Read only) */
--#define AC97_EA_MDAC 0x0100 /* MIC ADC is ready (Read only) */
--#define AC97_EA_SPCV 0x0400 /* S/PDIF configuration valid (Read only) */
--#define AC97_EA_PRI 0x0800 /* Turns the PCM Center DAC off */
--#define AC97_EA_PRJ 0x1000 /* Turns the PCM Surround DACs off */
--#define AC97_EA_PRK 0x2000 /* Turns the PCM LFE DAC off */
--#define AC97_EA_PRL 0x4000 /* Turns the MIC ADC off */
--#define AC97_EA_SLOT_MASK 0xffcf /* Mask for slot assignment bits */
--#define AC97_EA_SPSA_3_4 0x0000 /* Slot assigned to 3 & 4 */
--#define AC97_EA_SPSA_7_8 0x0010 /* Slot assigned to 7 & 8 */
--#define AC97_EA_SPSA_6_9 0x0020 /* Slot assigned to 6 & 9 */
--#define AC97_EA_SPSA_10_11 0x0030 /* Slot assigned to 10 & 11 */
-+#define AC97_EA_VRA 0x0001 /* Variable bit rate enable bit */
-+#define AC97_EA_DRA 0x0002 /* Double-rate audio enable bit */
-+#define AC97_EA_SPDIF 0x0004 /* S/PDIF Enable bit */
-+#define AC97_EA_VRM 0x0008 /* Variable bit rate for MIC enable bit */
-+#define AC97_EA_CDAC 0x0040 /* PCM Center DAC is ready (Read only) */
-+#define AC97_EA_SDAC 0x0040 /* PCM Surround DACs are ready (Read only) */
-+#define AC97_EA_LDAC 0x0080 /* PCM LFE DAC is ready (Read only) */
-+#define AC97_EA_MDAC 0x0100 /* MIC ADC is ready (Read only) */
-+#define AC97_EA_SPCV 0x0400 /* S/PDIF configuration valid (Read only) */
-+#define AC97_EA_PRI 0x0800 /* Turns the PCM Center DAC off */
-+#define AC97_EA_PRJ 0x1000 /* Turns the PCM Surround DACs off */
-+#define AC97_EA_PRK 0x2000 /* Turns the PCM LFE DAC off */
-+#define AC97_EA_PRL 0x4000 /* Turns the MIC ADC off */
-+#define AC97_EA_SLOT_MASK 0xffcf /* Mask for slot assignment bits */
-+#define AC97_EA_SPSA_3_4 0x0000 /* Slot assigned to 3 & 4 */
-+#define AC97_EA_SPSA_7_8 0x0010 /* Slot assigned to 7 & 8 */
-+#define AC97_EA_SPSA_6_9 0x0020 /* Slot assigned to 6 & 9 */
-+#define AC97_EA_SPSA_10_11 0x0030 /* Slot assigned to 10 & 11 */
-
- /* S/PDIF control bit defines */
--#define AC97_SC_PRO 0x0001 /* Professional status */
--#define AC97_SC_NAUDIO 0x0002 /* Non audio stream */
--#define AC97_SC_COPY 0x0004 /* Copyright status */
--#define AC97_SC_PRE 0x0008 /* Preemphasis status */
--#define AC97_SC_CC_MASK 0x07f0 /* Category Code mask */
--#define AC97_SC_L 0x0800 /* Generation Level status */
--#define AC97_SC_SPSR_MASK 0xcfff /* S/PDIF Sample Rate bits */
--#define AC97_SC_SPSR_44K 0x0000 /* Use 44.1kHz Sample rate */
--#define AC97_SC_SPSR_48K 0x2000 /* Use 48kHz Sample rate */
--#define AC97_SC_SPSR_32K 0x3000 /* Use 32kHz Sample rate */
--#define AC97_SC_DRS 0x4000 /* Double Rate S/PDIF */
--#define AC97_SC_V 0x8000 /* Validity status */
-+#define AC97_SC_PRO 0x0001 /* Professional status */
-+#define AC97_SC_NAUDIO 0x0002 /* Non audio stream */
-+#define AC97_SC_COPY 0x0004 /* Copyright status */
-+#define AC97_SC_PRE 0x0008 /* Preemphasis status */
-+#define AC97_SC_CC_MASK 0x07f0 /* Category Code mask */
-+#define AC97_SC_L 0x0800 /* Generation Level status */
-+#define AC97_SC_SPSR_MASK 0xcfff /* S/PDIF Sample Rate bits */
-+#define AC97_SC_SPSR_44K 0x0000 /* Use 44.1kHz Sample rate */
-+#define AC97_SC_SPSR_48K 0x2000 /* Use 48kHz Sample rate */
-+#define AC97_SC_SPSR_32K 0x3000 /* Use 32kHz Sample rate */
-+#define AC97_SC_DRS 0x4000 /* Double Rate S/PDIF */
-+#define AC97_SC_V 0x8000 /* Validity status */
-
- /* powerdown control and status bit defines */
-
-@@ -143,6 +169,39 @@
- #define AC97_PWR_PR6 0x4000 /* HP amp powerdown */
- #define AC97_PWR_PR7 0x8000 /* Modem off - if supported */
-
-+/* extended audio ID register bit defines */
-+#define AC97_EXTID_VRA 0x0001
-+#define AC97_EXTID_DRA 0x0002
-+#define AC97_EXTID_SPDIF 0x0004
-+#define AC97_EXTID_VRM 0x0008
-+#define AC97_EXTID_DSA0 0x0010
-+#define AC97_EXTID_DSA1 0x0020
-+#define AC97_EXTID_CDAC 0x0040
-+#define AC97_EXTID_SDAC 0x0080
-+#define AC97_EXTID_LDAC 0x0100
-+#define AC97_EXTID_AMAP 0x0200
-+#define AC97_EXTID_REV0 0x0400
-+#define AC97_EXTID_REV1 0x0800
-+#define AC97_EXTID_ID0 0x4000
-+#define AC97_EXTID_ID1 0x8000
-+
-+/* extended status register bit defines */
-+#define AC97_EXTSTAT_VRA 0x0001
-+#define AC97_EXTSTAT_DRA 0x0002
-+#define AC97_EXTSTAT_SPDIF 0x0004
-+#define AC97_EXTSTAT_VRM 0x0008
-+#define AC97_EXTSTAT_SPSA0 0x0010
-+#define AC97_EXTSTAT_SPSA1 0x0020
-+#define AC97_EXTSTAT_CDAC 0x0040
-+#define AC97_EXTSTAT_SDAC 0x0080
-+#define AC97_EXTSTAT_LDAC 0x0100
-+#define AC97_EXTSTAT_MADC 0x0200
-+#define AC97_EXTSTAT_SPCV 0x0400
-+#define AC97_EXTSTAT_PRI 0x0800
-+#define AC97_EXTSTAT_PRJ 0x1000
-+#define AC97_EXTSTAT_PRK 0x2000
-+#define AC97_EXTSTAT_PRL 0x4000
-+
- /* useful power states */
- #define AC97_PWR_D0 0x0000 /* everything on */
- #define AC97_PWR_D1 AC97_PWR_PR0|AC97_PWR_PR1|AC97_PWR_PR4
-@@ -189,11 +248,18 @@
- int dev_mixer;
- int type;
-
-+ int modem:1;
-+
- struct ac97_ops *codec_ops;
-
- /* controller specific lower leverl ac97 accessing routines */
- u16 (*codec_read) (struct ac97_codec *codec, u8 reg);
- void (*codec_write) (struct ac97_codec *codec, u8 reg, u16 val);
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+ void (*codec_bit_clear) (struct ac97_codec *codec, u8 reg, u16 val);
-+ void (*codec_bit_set) (struct ac97_codec *codec, u8 reg, u16 val);
-+ int mixer_busy;
-+#endif /* CONFIG_ARCH_PXA_TOSA */
-
- /* Wait for codec-ready. Ok to sleep here. */
- void (*codec_wait) (struct ac97_codec *codec);
-@@ -204,6 +270,9 @@
- int stereo_mixers;
- int record_sources;
-
-+ /* Property flags */
-+ int flags;
-+
- int bit_resolution;
-
- /* OSS mixer interface */
-@@ -232,6 +301,8 @@
- int (*amplifier)(struct ac97_codec *codec, int on);
- /* Digital mode control */
- int (*digital)(struct ac97_codec *codec, int format);
-+#define AC97_DELUDED_MODEM 1 /* Audio codec reports its a modem */
-+#define AC97_NO_PCM_VOLUME 2 /* Volume control is missing */
- };
-
- extern int ac97_read_proc (char *page_out, char **start, off_t off,
-@@ -242,4 +313,8 @@
- extern int ac97_save_state(struct ac97_codec *codec);
- extern int ac97_restore_state(struct ac97_codec *codec);
-
-+#ifdef CONFIG_ARCH_PXA_TOSA
-+#include <asm/arch/tosa_ac97_codec.h>
-+#endif /* CONFIG_ARCH_PXA_TOSA */
-+
- #endif /* _AC97_CODEC_H_ */
-diff -Nur linux_c860_org/include/linux/brlock.h linux/include/linux/brlock.h
---- linux_c860_org/include/linux/brlock.h 2002-08-26 14:37:46.000000000 +0900
-+++ linux/include/linux/brlock.h 2004-06-10 21:12:50.000000000 +0900
-@@ -171,11 +171,11 @@
- }
-
- #else
--# define br_read_lock(idx) ((void)(idx))
--# define br_read_unlock(idx) ((void)(idx))
--# define br_write_lock(idx) ((void)(idx))
--# define br_write_unlock(idx) ((void)(idx))
--#endif
-+# define br_read_lock(idx) ({ (void)(idx); preempt_disable(); })
-+# define br_read_unlock(idx) ({ (void)(idx); preempt_enable(); })
-+# define br_write_lock(idx) ({ (void)(idx); preempt_disable(); })
-+# define br_write_unlock(idx) ({ (void)(idx); preempt_enable(); })
-+#endif /* CONFIG_SMP */
-
- /*
- * Now enumerate all of the possible sw/hw IRQ protected
-diff -Nur linux_c860_org/include/linux/dcache.h linux/include/linux/dcache.h
---- linux_c860_org/include/linux/dcache.h 2002-12-18 19:52:24.000000000 +0900
-+++ linux/include/linux/dcache.h 2004-06-10 21:12:37.000000000 +0900
-@@ -129,31 +129,6 @@
-
- extern spinlock_t dcache_lock;
-
--/**
-- * d_drop - drop a dentry
-- * @dentry: dentry to drop
-- *
-- * d_drop() unhashes the entry from the parent
-- * dentry hashes, so that it won't be found through
-- * a VFS lookup any more. Note that this is different
-- * from deleting the dentry - d_delete will try to
-- * mark the dentry negative if possible, giving a
-- * successful _negative_ lookup, while d_drop will
-- * just make the cache lookup fail.
-- *
-- * d_drop() is used mainly for stuff that wants
-- * to invalidate a dentry for some reason (NFS
-- * timeouts or autofs deletes).
-- */
--
--static __inline__ void d_drop(struct dentry * dentry)
--{
-- spin_lock(&dcache_lock);
-- list_del(&dentry->d_hash);
-- INIT_LIST_HEAD(&dentry->d_hash);
-- spin_unlock(&dcache_lock);
--}
--
- static __inline__ int dname_external(struct dentry *d)
- {
- return d->d_name.name != d->d_iname;
-@@ -281,3 +256,34 @@
- #endif /* __KERNEL__ */
-
- #endif /* __LINUX_DCACHE_H */
-+
-+#if !defined(__LINUX_DCACHE_H_INLINES) && defined(_TASK_STRUCT_DEFINED)
-+#define __LINUX_DCACHE_H_INLINES
-+
-+#ifdef __KERNEL__
-+/**
-+ * d_drop - drop a dentry
-+ * @dentry: dentry to drop
-+ *
-+ * d_drop() unhashes the entry from the parent
-+ * dentry hashes, so that it won't be found through
-+ * a VFS lookup any more. Note that this is different
-+ * from deleting the dentry - d_delete will try to
-+ * mark the dentry negative if possible, giving a
-+ * successful _negative_ lookup, while d_drop will
-+ * just make the cache lookup fail.
-+ *
-+ * d_drop() is used mainly for stuff that wants
-+ * to invalidate a dentry for some reason (NFS
-+ * timeouts or autofs deletes).
-+ */
-+
-+static __inline__ void d_drop(struct dentry * dentry)
-+{
-+ spin_lock(&dcache_lock);
-+ list_del(&dentry->d_hash);
-+ INIT_LIST_HEAD(&dentry->d_hash);
-+ spin_unlock(&dcache_lock);
-+}
-+#endif
-+#endif
-diff -Nur linux_c860_org/include/linux/fb_doublebyte.h linux/include/linux/fb_doublebyte.h
---- linux_c860_org/include/linux/fb_doublebyte.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/include/linux/fb_doublebyte.h 2004-06-10 21:09:11.000000000 +0900
-@@ -0,0 +1,43 @@
-+/*
-+ * linux/include/linux/fb_widechar.h
-+ *
-+ * Copyright (C) 1999 Christopher Li, Jim Chen
-+ * GNU/Linux Research Center
-+ *
-+ * This file is subject to the terms and conditions of the GNU General Public
-+ * License. See the file COPYING in the main directory of this archive
-+ * for more details.
-+ *
-+ *
-+ */
-+
-+#ifndef _LINUX_FB_DOUBLEBYTE_H
-+#define _LINUX_FB_DOUBLEbYTE_H
-+
-+#define DB_VALIDATE 0x8000
-+#define DB_RIGHT_MASK 0x4000
-+#define DB_HALF_MASK 0x2000
-+#define DB_SYMBOL 0x1000
-+#define DB_ASCII 0
-+
-+#define DB_RIGHT (DB_VALIDATE|DB_RIGHT_MASK)
-+#define DB_LEFT (DB_VALIDATE)
-+#define DB_NUM 8
-+
-+#define DB_INDEX_ERROR -512
-+struct double_byte
-+{
-+ unsigned int num;
-+ char name[16];
-+ int (*is_left)(int );
-+ int (*is_right)(int );
-+ int (*font_index)(int left,int right);
-+ unsigned int width,height; /* right now only support 16x16 */
-+ int charcount;
-+ unsigned char * font_data;
-+};
-+extern int register_doublebyte(struct double_byte *);
-+extern int unregister_doublebyte(struct double_byte *);
-+extern struct double_byte * doublebyte_encodeing[DB_NUM];
-+extern struct double_byte * doublebyte_default;
-+#endif
-diff -Nur linux_c860_org/include/linux/fs_struct.h linux/include/linux/fs_struct.h
---- linux_c860_org/include/linux/fs_struct.h 2002-08-26 14:37:46.000000000 +0900
-+++ linux/include/linux/fs_struct.h 2004-06-10 21:09:11.000000000 +0900
-@@ -20,6 +20,15 @@
- extern void exit_fs(struct task_struct *);
- extern void set_fs_altroot(void);
-
-+struct fs_struct *copy_fs_struct(struct fs_struct *old);
-+void put_fs_struct(struct fs_struct *fs);
-+
-+#endif
-+#endif
-+
-+#if !defined(_LINUX_FS_STRUCT_H_INLINES) && defined(_TASK_STRUCT_DEFINED)
-+#define _LINUX_FS_STRUCT_H_INLINES
-+#ifdef __KERNEL__
- /*
- * Replace the fs->{rootmnt,root} with {mnt,dentry}. Put the old values.
- * It can block. Requires the big lock held.
-@@ -65,9 +74,5 @@
- mntput(old_pwdmnt);
- }
- }
--
--struct fs_struct *copy_fs_struct(struct fs_struct *old);
--void put_fs_struct(struct fs_struct *fs);
--
- #endif
- #endif
-diff -Nur linux_c860_org/include/linux/jffs2_fs_sb.h linux/include/linux/jffs2_fs_sb.h
---- linux_c860_org/include/linux/jffs2_fs_sb.h 2003-05-14 15:01:52.000000000 +0900
-+++ linux/include/linux/jffs2_fs_sb.h 2004-06-10 21:12:37.000000000 +0900
-@@ -16,6 +16,7 @@
- * 15-Nov-2002 Lineo Japan, Inc. add nodemerge facility
- * 05-Nov-2002 Lineo Japan, Inc. modify nr_bad_blocks type
- * 29-Oct-2002 Lineo Japan, Inc. add member nr_bad_blocks and cont_gc_count
-+ * 05-Aug-2003 SHARP for Tosa
- *
- */
-
-@@ -81,7 +82,7 @@
- uint32_t nr_blocks;
- struct jffs2_eraseblock *blocks; /* The whole array of blocks. Used for getting blocks
- * from the offset (blocks[ofs / sector_size]) */
--#ifdef CONFIG_ARCH_PXA_HUSKY
-+#if defined(CONFIG_ARCH_PXA_HUSKY) || defined(CONFIG_ARCH_PXA_TOSA)
- dma_addr_t blocks_phys;
- #endif
- struct jffs2_eraseblock *nextblock; /* The block we're currently filling */
-diff -Nur linux_c860_org/include/linux/lock_break.h linux/include/linux/lock_break.h
---- linux_c860_org/include/linux/lock_break.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/include/linux/lock_break.h 2004-06-10 21:09:11.000000000 +0900
-@@ -0,0 +1,84 @@
-+/*
-+ * include/linux/lock_break.h - lock breaking routines
-+ *
-+ * since in-kernel preemption can not occur while a lock is
-+ * held, we can drop and reacquire long-held locks when they are
-+ * in a natural quiescent state to further lower system latency.
-+ *
-+ * (C) 2001 Robert Love
-+ *
-+ */
-+
-+#ifndef _LINUX_LOCK_BREAK_H
-+#define _LINUX_LOCK_BREAK_H
-+
-+#include <linux/compiler.h>
-+
-+/*
-+ * setting this to 1 will instruct debug_lock_break to
-+ * note when the expected lock count does not equal the
-+ * actual count. if the lock count is higher than expected,
-+ * we aren't dropping enough locks. if it is 0, we are
-+ * wasting our time since the system is already preemptible.
-+ */
-+#ifndef DEBUG_LOCK_BREAK
-+#define DEBUG_LOCK_BREAK 0
-+#endif
-+
-+#ifdef CONFIG_LOCK_BREAK
-+
-+#define conditional_schedule_needed() (unlikely(current->need_resched))
-+
-+/*
-+ * setting the task's state to TASK_RUNNING is nothing but paranoia,
-+ * in the case where a task is delinquent in properly putting itself
-+ * to sleep. we should test without it.
-+ */
-+#define unconditional_schedule() do { \
-+ __set_current_state(TASK_RUNNING); \
-+ schedule(); \
-+} while(0)
-+
-+#define conditional_schedule() do { \
-+ if (conditional_schedule_needed()) \
-+ unconditional_schedule(); \
-+} while(0)
-+
-+#define break_spin_lock(n) do { \
-+ spin_unlock(n); \
-+ spin_lock(n); \
-+} while(0)
-+
-+#define break_spin_lock_and_resched(n) do { \
-+ spin_unlock(n); \
-+ conditional_schedule(); \
-+ spin_lock(n); \
-+} while(0)
-+
-+#if DEBUG_LOCK_BREAK
-+#define debug_lock_break(n) do { \
-+ if (current->preempt_count != n) \
-+ printk(KERN_ERR "lock_break: %s:%d: count was %d not %d\n", \
-+ __FILE__, __LINE__, current->preempt_count, n); \
-+} while(0)
-+#else
-+#define debug_lock_break(n)
-+#endif
-+
-+#define DEFINE_LOCK_COUNT() int _lock_break_count = 0
-+#define TEST_LOCK_COUNT(n) (++_lock_break_count > (n))
-+#define RESET_LOCK_COUNT() _lock_break_count = 0
-+
-+#else
-+#define unconditional_schedule()
-+#define conditional_schedule()
-+#define conditional_schedule_needed() 0
-+#define break_spin_lock(n)
-+#define break_spin_lock_and_resched(n)
-+#define debug_lock_break(n)
-+#define DEFINE_LOCK_COUNT()
-+#define TEST_LOCK_COUNT(n) 0
-+#define RESET_LOCK_COUNT()
-+#endif
-+
-+#endif /* _LINUX_LOCK_BREAK_H */
-diff -Nur linux_c860_org/include/linux/mm.h linux/include/linux/mm.h
---- linux_c860_org/include/linux/mm.h 2003-01-29 14:45:03.000000000 +0900
-+++ linux/include/linux/mm.h 2004-06-10 21:12:37.000000000 +0900
-@@ -126,6 +126,9 @@
- */
- extern pgprot_t protection_map[16];
-
-+#define ZPR_MAX_BYTES 256*PAGE_SIZE
-+#define ZPR_NORMAL 0 /* perform zap_page_range request in one walk */
-+#define ZPR_PARTITION 1 /* partition into a series of smaller operations */
-
- /*
- * These are the virtual MM functions - opening of an area, closing and
-@@ -409,7 +412,7 @@
- extern void shmem_lock(struct file * file, int lock);
- extern int shmem_zero_setup(struct vm_area_struct *);
-
--extern void zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long size);
-+extern void zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long size, int actions);
- extern int copy_page_range(struct mm_struct *dst, struct mm_struct *src, struct vm_area_struct *vma);
- extern int remap_page_range(unsigned long from, unsigned long to, unsigned long size, pgprot_t prot);
- extern int zeromap_page_range(unsigned long from, unsigned long size, pgprot_t prot);
-diff -Nur linux_c860_org/include/linux/ppp-comp.h linux/include/linux/ppp-comp.h
---- linux_c860_org/include/linux/ppp-comp.h 2002-08-26 14:37:45.000000000 +0900
-+++ linux/include/linux/ppp-comp.h 2004-06-10 21:09:11.000000000 +0900
-@@ -24,11 +24,11 @@
- * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
- * OR MODIFICATIONS.
- *
-- * $Id$
-+ * $Id$
- */
-
- /*
-- * ==FILEVERSION 980319==
-+ * ==FILEVERSION 990623==
- *
- * NOTE TO MAINTAINERS:
- * If you modify this file at all, please set the above date.
-@@ -120,6 +120,7 @@
- * Don't you just lurve software patents.
- */
-
-+#define DECOMP_OK 0 /* no error occured */
- #define DECOMP_ERROR -1 /* error detected before decomp. */
- #define DECOMP_FATALERROR -2 /* error detected after decomp. */
-
-@@ -138,7 +139,7 @@
- * Max # bytes for a CCP option
- */
-
--#define CCP_MAX_OPTION_LENGTH 32
-+#define CCP_MAX_OPTION_LENGTH 64
-
- /*
- * Parts of a CCP packet.
-@@ -187,6 +188,20 @@
- #define DEFLATE_CHK_SEQUENCE 0
-
- /*
-+ * Definitions for MPPE.
-+ */
-+
-+#define CI_MPPE 18 /* config. option for MPPE */
-+#define CILEN_MPPE 6 /* length of config. option */
-+
-+/*
-+ * Definitions for Stac LZS.
-+ */
-+
-+#define CI_LZS 17 /* config option for Stac LZS */
-+#define CILEN_LZS 5 /* length of config option */
-+
-+/*
- * Definitions for other, as yet unsupported, compression methods.
- */
-
-diff -Nur linux_c860_org/include/linux/sched.h linux/include/linux/sched.h
---- linux_c860_org/include/linux/sched.h 2002-12-18 19:29:48.000000000 +0900
-+++ linux/include/linux/sched.h 2004-06-10 21:12:37.000000000 +0900
-@@ -31,6 +31,7 @@
- #include <linux/signal.h>
- #include <linux/securebits.h>
- #include <linux/fs_struct.h>
-+#include <linux/lock_break.h>
-
- struct exec_domain;
-
-@@ -93,6 +94,7 @@
- #define TASK_UNINTERRUPTIBLE 2
- #define TASK_ZOMBIE 4
- #define TASK_STOPPED 8
-+#define PREEMPT_ACTIVE 0x4000000
-
- #define __set_task_state(tsk, state_value) \
- do { (tsk)->state = (state_value); } while (0)
-@@ -159,6 +161,9 @@
- #define MAX_SCHEDULE_TIMEOUT LONG_MAX
- extern signed long FASTCALL(schedule_timeout(signed long timeout));
- asmlinkage void schedule(void);
-+#ifdef CONFIG_PREEMPT
-+asmlinkage void preempt_schedule(void);
-+#endif
-
- extern int schedule_task(struct tq_struct *task);
- extern void flush_scheduled_tasks(void);
-@@ -288,7 +293,7 @@
- * offsets of these are hardcoded elsewhere - touch with care
- */
- volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */
-- unsigned long flags; /* per process flags, defined below */
-+ int preempt_count; /* 0 => preemptable, <0 => BUG */
- int sigpending;
- mm_segment_t addr_limit; /* thread address space:
- 0-0xBFFFFFFF for user-thead
-@@ -330,6 +335,7 @@
- struct mm_struct *active_mm;
- struct list_head local_pages;
- unsigned int allocation_order, nr_local_pages;
-+ unsigned long flags;
-
- /* task state */
- struct linux_binfmt *binfmt;
-@@ -338,6 +344,7 @@
- /* ??? */
- unsigned long personality;
- int did_exec:1;
-+ unsigned task_dumpable:1;
- pid_t pid;
- pid_t pgrp;
- pid_t tty_old_pgrp;
-@@ -505,6 +512,8 @@
- #define PT_TRACESYSGOOD 0x00000008
- #define PT_PTRACE_CAP 0x00000010 /* ptracer can follow suid-exec */
-
-+#define is_dumpable(tsk) (((tsk)->task_dumpable) && (((tsk)->mm != NULL) && (tsk)->mm->dumpable))
-+
- /*
- * Limit the stack by to some sane default: root can always
- * increase this limit if needed.. 8MB seems reasonable.
-@@ -854,6 +863,8 @@
- extern int do_execve(char *, char **, char **, struct pt_regs *);
- extern int do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long);
-
-+extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-+
- extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
- extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait));
- extern void FASTCALL(remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait));
-@@ -992,6 +1003,11 @@
- return res;
- }
-
-+#define _TASK_STRUCT_DEFINED
-+#include <linux/dcache.h>
-+#include <linux/tqueue.h>
-+#include <linux/fs_struct.h>
-+
- #endif /* __KERNEL__ */
-
- #endif
-diff -Nur linux_c860_org/include/linux/smp.h linux/include/linux/smp.h
---- linux_c860_org/include/linux/smp.h 2002-08-26 14:37:45.000000000 +0900
-+++ linux/include/linux/smp.h 2004-06-10 21:12:36.000000000 +0900
-@@ -81,11 +81,17 @@
- #define smp_processor_id() 0
- #define hard_smp_processor_id() 0
- #define smp_threads_ready 1
-+#ifndef CONFIG_PREEMPT
- #define kernel_lock()
-+#endif
- #define cpu_logical_map(cpu) 0
- #define cpu_number_map(cpu) 0
- #define smp_call_function(func,info,retry,wait) ({ 0; })
- #define cpu_online_map 1
-
--#endif
--#endif
-+#endif /* !SMP */
-+
-+#define get_cpu() smp_processor_id()
-+#define put_cpu() do { } while(0)
-+
-+#endif /* __LINUX_SMP_H */
-diff -Nur linux_c860_org/include/linux/smp_lock.h linux/include/linux/smp_lock.h
---- linux_c860_org/include/linux/smp_lock.h 2002-08-26 14:37:45.000000000 +0900
-+++ linux/include/linux/smp_lock.h 2004-06-10 21:12:37.000000000 +0900
-@@ -3,7 +3,7 @@
-
- #include <linux/config.h>
-
--#ifndef CONFIG_SMP
-+#if !defined(CONFIG_SMP) && !defined(CONFIG_PREEMPT)
-
- #define lock_kernel() do { } while(0)
- #define unlock_kernel() do { } while(0)
-diff -Nur linux_c860_org/include/linux/spinlock.h linux/include/linux/spinlock.h
---- linux_c860_org/include/linux/spinlock.h 2002-08-26 14:37:46.000000000 +0900
-+++ linux/include/linux/spinlock.h 2004-06-10 21:12:37.000000000 +0900
-@@ -2,6 +2,7 @@
- #define __LINUX_SPINLOCK_H
-
- #include <linux/config.h>
-+#include <linux/compiler.h>
-
- /*
- * These are the generic versions of the spinlocks and read-write
-@@ -45,8 +46,10 @@
-
- #if (DEBUG_SPINLOCKS < 1)
-
-+#ifndef CONFIG_PREEMPT
- #define atomic_dec_and_lock(atomic,lock) atomic_dec_and_test(atomic)
- #define ATOMIC_DEC_AND_LOCK
-+#endif
-
- /*
- * Your basic spinlocks, allowing only a single CPU anywhere
-@@ -62,11 +65,11 @@
- #endif
-
- #define spin_lock_init(lock) do { } while(0)
--#define spin_lock(lock) (void)(lock) /* Not "unused variable". */
-+#define _raw_spin_lock(lock) (void)(lock) /* Not "unused variable". */
- #define spin_is_locked(lock) (0)
--#define spin_trylock(lock) ({1; })
-+#define _raw_spin_trylock(lock) ({1; })
- #define spin_unlock_wait(lock) do { } while(0)
--#define spin_unlock(lock) do { } while(0)
-+#define _raw_spin_unlock(lock) do { } while(0)
-
- #elif (DEBUG_SPINLOCKS < 2)
-
-@@ -125,13 +128,78 @@
- #endif
-
- #define rwlock_init(lock) do { } while(0)
--#define read_lock(lock) (void)(lock) /* Not "unused variable". */
--#define read_unlock(lock) do { } while(0)
--#define write_lock(lock) (void)(lock) /* Not "unused variable". */
--#define write_unlock(lock) do { } while(0)
-+#define _raw_read_lock(lock) (void)(lock) /* Not "unused variable". */
-+#define _raw_read_unlock(lock) do { } while(0)
-+#define _raw_write_lock(lock) (void)(lock) /* Not "unused variable". */
-+#define _raw_write_unlock(lock) do { } while(0)
-
- #endif /* !SMP */
-
-+#ifdef CONFIG_PREEMPT
-+
-+#define preempt_get_count() (current->preempt_count)
-+#define preempt_is_disabled() (preempt_get_count() != 0)
-+
-+#define preempt_disable() \
-+do { \
-+ ++current->preempt_count; \
-+ barrier(); \
-+} while (0)
-+
-+#define preempt_enable_no_resched() \
-+do { \
-+ --current->preempt_count; \
-+ barrier(); \
-+} while (0)
-+
-+#define preempt_enable() \
-+do { \
-+ --current->preempt_count; \
-+ barrier(); \
-+ if (unlikely(current->preempt_count < current->need_resched)) \
-+ preempt_schedule(); \
-+} while (0)
-+
-+#define spin_lock(lock) \
-+do { \
-+ preempt_disable(); \
-+ _raw_spin_lock(lock); \
-+} while(0)
-+
-+#define spin_trylock(lock) ({preempt_disable(); _raw_spin_trylock(lock) ? \
-+ 1 : ({preempt_enable(); 0;});})
-+#define spin_unlock(lock) \
-+do { \
-+ _raw_spin_unlock(lock); \
-+ preempt_enable(); \
-+} while (0)
-+
-+#define read_lock(lock) ({preempt_disable(); _raw_read_lock(lock);})
-+#define read_unlock(lock) ({_raw_read_unlock(lock); preempt_enable();})
-+#define write_lock(lock) ({preempt_disable(); _raw_write_lock(lock);})
-+#define write_unlock(lock) ({_raw_write_unlock(lock); preempt_enable();})
-+#define write_trylock(lock) ({preempt_disable();_raw_write_trylock(lock) ? \
-+ 1 : ({preempt_enable(); 0;});})
-+
-+#else
-+
-+#define preempt_get_count() (0)
-+#define preempt_is_disabled() (1)
-+#define preempt_disable() do { } while (0)
-+#define preempt_enable_no_resched() do {} while(0)
-+#define preempt_enable() do { } while (0)
-+
-+#define spin_lock(lock) _raw_spin_lock(lock)
-+#define spin_trylock(lock) _raw_spin_trylock(lock)
-+#define spin_unlock(lock) _raw_spin_unlock(lock)
-+
-+#define read_lock(lock) _raw_read_lock(lock)
-+#define read_unlock(lock) _raw_read_unlock(lock)
-+#define write_lock(lock) _raw_write_lock(lock)
-+#define write_unlock(lock) _raw_write_unlock(lock)
-+#define write_trylock(lock) _raw_write_trylock(lock)
-+#endif
-+
- /* "lock on reference count zero" */
- #ifndef ATOMIC_DEC_AND_LOCK
- #include <asm/atomic.h>
-diff -Nur linux_c860_org/include/linux/tqueue.h linux/include/linux/tqueue.h
---- linux_c860_org/include/linux/tqueue.h 2002-08-26 14:37:44.000000000 +0900
-+++ linux/include/linux/tqueue.h 2004-06-10 21:12:37.000000000 +0900
-@@ -94,6 +94,22 @@
- extern spinlock_t tqueue_lock;
-
- /*
-+ * Call all "bottom halfs" on a given list.
-+ */
-+
-+extern void __run_task_queue(task_queue *list);
-+
-+static inline void run_task_queue(task_queue *list)
-+{
-+ if (TQ_ACTIVE(*list))
-+ __run_task_queue(list);
-+}
-+
-+#endif /* _LINUX_TQUEUE_H */
-+
-+#if !defined(_LINUX_TQUEUE_H_INLINES) && defined(_TASK_STRUCT_DEFINED)
-+#define _LINUX_TQUEUE_H_INLINES
-+/*
- * Queue a task on a tq. Return non-zero if it was successfully
- * added.
- */
-@@ -109,17 +125,4 @@
- }
- return ret;
- }
--
--/*
-- * Call all "bottom halfs" on a given list.
-- */
--
--extern void __run_task_queue(task_queue *list);
--
--static inline void run_task_queue(task_queue *list)
--{
-- if (TQ_ACTIVE(*list))
-- __run_task_queue(list);
--}
--
--#endif /* _LINUX_TQUEUE_H */
-+#endif
-diff -Nur linux_c860_org/include/linux/tty_flip.h linux/include/linux/tty_flip.h
---- linux_c860_org/include/linux/tty_flip.h 2002-08-26 14:37:44.000000000 +0900
-+++ linux/include/linux/tty_flip.h 2004-06-10 21:12:59.000000000 +0900
-@@ -7,9 +7,22 @@
- #define _INLINE_ static __inline__
- #endif
-
-+#ifdef CONFIG_UNICON
-+extern int (*Unicon_fnKeyHook) (struct tty_struct *tty,
-+ unsigned char ch, char flag);
-+#endif
- _INLINE_ void tty_insert_flip_char(struct tty_struct *tty,
-- unsigned char ch, char flag)
-+ unsigned char ch, char flag)
- {
-+ #ifdef CONFIG_UNICON
-+ if (Unicon_fnKeyHook != NULL)
-+ {
-+ /* return 1 ==> processed by kernel
-+ return 0 ==> processed by app */
-+ if ((*Unicon_fnKeyHook) (tty, ch, flag) == 1)
-+ return;
-+ }
-+ #endif
- if (tty->flip.count < TTY_FLIPBUF_SIZE) {
- tty->flip.count++;
- *tty->flip.flag_buf_ptr++ = flag;
-diff -Nur linux_c860_org/include/net/irda/irlmp.h linux/include/net/irda/irlmp.h
---- linux_c860_org/include/net/irda/irlmp.h 2002-08-29 12:24:49.000000000 +0900
-+++ linux/include/net/irda/irlmp.h 2004-06-10 21:13:39.000000000 +0900
-@@ -21,6 +21,9 @@
- * Neither Dag Brattli nor University of Tromsø admit liability nor
- * provide warranty for any of this software. This material is
- * provided "AS-IS" and at no charge.
-+ *
-+ * ChangeLog:
-+ * 1-Nov-2003 Sharp Corporation for Tosa
- *
- ********************************************************************/
-
-@@ -181,6 +184,9 @@
- int running;
-
- __u16_host_order hints; /* Hint bits */
-+#if defined(CONFIG_ARCH_SHARP_SL)
-+ int discovery_retry; /* Discovery retry flag at media busy */
-+#endif
- };
-
- /* Prototype declarations */
-diff -Nur linux_c860_org/include/openssl/opensslconf.h linux/include/openssl/opensslconf.h
---- linux_c860_org/include/openssl/opensslconf.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/include/openssl/opensslconf.h 2004-06-10 21:09:11.000000000 +0900
-@@ -0,0 +1,176 @@
-+/* opensslconf.h */
-+/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
-+
-+/* OpenSSL was configured with the following options: */
-+#ifdef OPENSSL_ALGORITHM_DEFINES
-+ /* no ciphers excluded */
-+#endif
-+#ifdef OPENSSL_THREAD_DEFINES
-+# ifndef THREADS
-+# define THREADS
-+# endif
-+#endif
-+#ifdef OPENSSL_OTHER_DEFINES
-+# ifndef DSO_DLFCN
-+# define DSO_DLFCN
-+# endif
-+# ifndef HAVE_DLFCN_H
-+# define HAVE_DLFCN_H
-+# endif
-+#endif
-+
-+/* crypto/opensslconf.h.in */
-+
-+/* Generate 80386 code? */
-+#undef I386_ONLY
-+
-+#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
-+#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
-+#define OPENSSLDIR "/usr/local/ssl"
-+#endif
-+#endif
-+
-+#define OPENSSL_UNISTD <unistd.h>
-+
-+#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
-+#define IDEA_INT unsigned int
-+#endif
-+
-+#if defined(HEADER_MD2_H) && !defined(MD2_INT)
-+#define MD2_INT unsigned int
-+#endif
-+
-+#if defined(HEADER_RC2_H) && !defined(RC2_INT)
-+/* I need to put in a mod for the alpha - eay */
-+#define RC2_INT unsigned int
-+#endif
-+
-+#if defined(HEADER_RC4_H)
-+#if !defined(RC4_INT)
-+/* using int types make the structure larger but make the code faster
-+ * on most boxes I have tested - up to %20 faster. */
-+/*
-+ * I don't know what does "most" mean, but declaring "int" is a must on:
-+ * - Intel P6 because partial register stalls are very expensive;
-+ * - elder Alpha because it lacks byte load/store instructions;
-+ */
-+#define RC4_INT unsigned int
-+#endif
-+#if !defined(RC4_CHUNK)
-+/*
-+ * This enables code handling data aligned at natural CPU word
-+ * boundary. See crypto/rc4/rc4_enc.c for further details.
-+ */
-+#undef RC4_CHUNK
-+#endif
-+#endif
-+
-+#if defined(HEADER_DES_H) && !defined(DES_LONG)
-+/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
-+ * %20 speed up (longs are 8 bytes, int's are 4). */
-+#ifndef DES_LONG
-+#define DES_LONG unsigned long
-+#endif
-+#endif
-+
-+#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
-+#define CONFIG_HEADER_BN_H
-+#define BN_LLONG
-+
-+/* Should we define BN_DIV2W here? */
-+
-+/* Only one for the following should be defined */
-+/* The prime number generation stuff may not work when
-+ * EIGHT_BIT but I don't care since I've only used this mode
-+ * for debuging the bignum libraries */
-+#undef SIXTY_FOUR_BIT_LONG
-+#undef SIXTY_FOUR_BIT
-+#define THIRTY_TWO_BIT
-+#undef SIXTEEN_BIT
-+#undef EIGHT_BIT
-+#endif
-+
-+#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
-+#define CONFIG_HEADER_RC4_LOCL_H
-+/* if this is defined data[i] is used instead of *data, this is a %20
-+ * speedup on x86 */
-+#define RC4_INDEX
-+#endif
-+
-+#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
-+#define CONFIG_HEADER_BF_LOCL_H
-+#undef BF_PTR
-+#endif /* HEADER_BF_LOCL_H */
-+
-+#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
-+#define CONFIG_HEADER_DES_LOCL_H
-+#ifndef DES_DEFAULT_OPTIONS
-+/* the following is tweaked from a config script, that is why it is a
-+ * protected undef/define */
-+#ifndef DES_PTR
-+#define DES_PTR
-+#endif
-+
-+/* This helps C compiler generate the correct code for multiple functional
-+ * units. It reduces register dependancies at the expense of 2 more
-+ * registers */
-+#ifndef DES_RISC1
-+#define DES_RISC1
-+#endif
-+
-+#ifndef DES_RISC2
-+#undef DES_RISC2
-+#endif
-+
-+#if defined(DES_RISC1) && defined(DES_RISC2)
-+YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
-+#endif
-+
-+/* Unroll the inner loop, this sometimes helps, sometimes hinders.
-+ * Very mucy CPU dependant */
-+#ifndef DES_UNROLL
-+#define DES_UNROLL
-+#endif
-+
-+/* These default values were supplied by
-+ * Peter Gutman <pgut001@cs.auckland.ac.nz>
-+ * They are only used if nothing else has been defined */
-+#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
-+/* Special defines which change the way the code is built depending on the
-+ CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
-+ even newer MIPS CPU's, but at the moment one size fits all for
-+ optimization options. Older Sparc's work better with only UNROLL, but
-+ there's no way to tell at compile time what it is you're running on */
-+
-+#if defined( sun ) /* Newer Sparc's */
-+# define DES_PTR
-+# define DES_RISC1
-+# define DES_UNROLL
-+#elif defined( __ultrix ) /* Older MIPS */
-+# define DES_PTR
-+# define DES_RISC2
-+# define DES_UNROLL
-+#elif defined( __osf1__ ) /* Alpha */
-+# define DES_PTR
-+# define DES_RISC2
-+#elif defined ( _AIX ) /* RS6000 */
-+ /* Unknown */
-+#elif defined( __hpux ) /* HP-PA */
-+ /* Unknown */
-+#elif defined( __aux ) /* 68K */
-+ /* Unknown */
-+#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
-+# define DES_UNROLL
-+#elif defined( __sgi ) /* Newer MIPS */
-+# define DES_PTR
-+# define DES_RISC2
-+# define DES_UNROLL
-+#elif defined( i386 ) /* x86 boxes, should be gcc */
-+# define DES_PTR
-+# define DES_RISC1
-+# define DES_UNROLL
-+#endif /* Systems-specific speed defines */
-+#endif
-+
-+#endif /* DES_DEFAULT_OPTIONS */
-+#endif /* HEADER_DES_LOCL_H */
-diff -Nur linux_c860_org/include/openssl/opensslv.h linux/include/openssl/opensslv.h
---- linux_c860_org/include/openssl/opensslv.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/include/openssl/opensslv.h 2004-06-10 21:09:11.000000000 +0900
-@@ -0,0 +1,85 @@
-+#ifndef HEADER_OPENSSLV_H
-+#define HEADER_OPENSSLV_H
-+
-+/* Numeric release version identifier:
-+ * MMNNFFPPS: major minor fix patch status
-+ * The status nibble has one of the values 0 for development, 1 to e for betas
-+ * 1 to 14, and f for release. The patch level is exactly that.
-+ * For example:
-+ * 0.9.3-dev 0x00903000
-+ * 0.9.3-beta1 0x00903001
-+ * 0.9.3-beta2-dev 0x00903002
-+ * 0.9.3-beta2 0x00903002 (same as ...beta2-dev)
-+ * 0.9.3 0x0090300f
-+ * 0.9.3a 0x0090301f
-+ * 0.9.4 0x0090400f
-+ * 1.2.3z 0x102031af
-+ *
-+ * For continuity reasons (because 0.9.5 is already out, and is coded
-+ * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level
-+ * part is slightly different, by setting the highest bit. This means
-+ * that 0.9.5a looks like this: 0x0090581f. At 0.9.6, we can start
-+ * with 0x0090600S...
-+ *
-+ * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.)
-+ * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
-+ * major minor fix final patch/beta)
-+ */
-+#define OPENSSL_VERSION_NUMBER 0x0090601fL
-+#define OPENSSL_VERSION_TEXT "OpenSSL 0.9.6a 5 Apr 2001"
-+#define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
-+
-+
-+/* The macros below are to be used for shared library (.so, .dll, ...)
-+ * versioning. That kind of versioning works a bit differently between
-+ * operating systems. The most usual scheme is to set a major and a minor
-+ * number, and have the runtime loader check that the major number is equal
-+ * to what it was at application link time, while the minor number has to
-+ * be greater or equal to what it was at application link time. With this
-+ * scheme, the version number is usually part of the file name, like this:
-+ *
-+ * libcrypto.so.0.9
-+ *
-+ * Some unixen also make a softlink with the major verson number only:
-+ *
-+ * libcrypto.so.0
-+ *
-+ * On True64 it works a little bit differently. There, the shared library
-+ * version is stored in the file, and is actually a series of versions,
-+ * separated by colons. The rightmost version present in the library when
-+ * linking an application is stored in the application to be matched at
-+ * run time. When the application is run, a check is done to see if the
-+ * library version stored in the application matches any of the versions
-+ * in the version string of the library itself.
-+ * This version string can be constructed in any way, depending on what
-+ * kind of matching is desired. However, to implement the same scheme as
-+ * the one used in the other unixen, all compatible versions, from lowest
-+ * to highest, should be part of the string. Consecutive builds would
-+ * give the following versions strings:
-+ *
-+ * 3.0
-+ * 3.0:3.1
-+ * 3.0:3.1:3.2
-+ * 4.0
-+ * 4.0:4.1
-+ *
-+ * Notice how version 4 is completely incompatible with version, and
-+ * therefore give the breach you can see.
-+ *
-+ * There may be other schemes as well that I haven't yet discovered.
-+ *
-+ * So, here's the way it works here: first of all, the library version
-+ * number doesn't need at all to match the overall OpenSSL version.
-+ * However, it's nice and more understandable if it actually does.
-+ * The current library version is stored in the macro SHLIB_VERSION_NUMBER,
-+ * which is just a piece of text in the format "M.m.e" (Major, minor, edit).
-+ * For the sake of True64 and any other OS that behaves in similar ways,
-+ * we need to keep a history of version numbers, which is done in the
-+ * macro SHLIB_VERSION_HISTORY. The numbers are separated by colons and
-+ * should only keep the versions that are binary compatible with the current.
-+ */
-+#define SHLIB_VERSION_HISTORY ""
-+#define SHLIB_VERSION_NUMBER "0.9.6"
-+
-+
-+#endif /* HEADER_OPENSSLV_H */
-diff -Nur linux_c860_org/include/openssl/rc4.h linux/include/openssl/rc4.h
---- linux_c860_org/include/openssl/rc4.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/include/openssl/rc4.h 2004-06-10 21:09:11.000000000 +0900
-@@ -0,0 +1,88 @@
-+/* crypto/rc4/rc4.h */
-+/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+#ifndef HEADER_RC4_H
-+#define HEADER_RC4_H
-+
-+#ifdef NO_RC4
-+#error RC4 is disabled.
-+#endif
-+
-+#include <openssl/opensslconf.h> /* RC4_INT */
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+typedef struct rc4_key_st
-+ {
-+ RC4_INT x,y;
-+ RC4_INT data[256];
-+ } RC4_KEY;
-+
-+
-+const char *RC4_options(void);
-+void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);
-+void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
-+ unsigned char *outdata);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
-diff -Nur linux_c860_org/include/openssl/sha.h linux/include/openssl/sha.h
---- linux_c860_org/include/openssl/sha.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/include/openssl/sha.h 2004-06-10 21:09:11.000000000 +0900
-@@ -0,0 +1,119 @@
-+/* crypto/sha/sha.h */
-+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
-+ * All rights reserved.
-+ *
-+ * This package is an SSL implementation written
-+ * by Eric Young (eay@cryptsoft.com).
-+ * The implementation was written so as to conform with Netscapes SSL.
-+ *
-+ * This library is free for commercial and non-commercial use as long as
-+ * the following conditions are aheared to. The following conditions
-+ * apply to all code found in this distribution, be it the RC4, RSA,
-+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
-+ * included with this distribution is covered by the same copyright terms
-+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
-+ *
-+ * Copyright remains Eric Young's, and as such any Copyright notices in
-+ * the code are not to be removed.
-+ * If this package is used in a product, Eric Young should be given attribution
-+ * as the author of the parts of the library used.
-+ * This can be in the form of a textual message at program startup or
-+ * in documentation (online or textual) provided with the package.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. All advertising materials mentioning features or use of this software
-+ * must display the following acknowledgement:
-+ * "This product includes cryptographic software written by
-+ * Eric Young (eay@cryptsoft.com)"
-+ * The word 'cryptographic' can be left out if the rouines from the library
-+ * being used are not cryptographic related :-).
-+ * 4. If you include any Windows specific code (or a derivative thereof) from
-+ * the apps directory (application code) you must include an acknowledgement:
-+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ *
-+ * The licence and distribution terms for any publically available version or
-+ * derivative of this code cannot be changed. i.e. this code cannot simply be
-+ * copied and put under another distribution licence
-+ * [including the GNU Public Licence.]
-+ */
-+
-+#ifndef HEADER_SHA_H
-+#define HEADER_SHA_H
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#if defined(NO_SHA) || (defined(NO_SHA0) && defined(NO_SHA1))
-+#error SHA is disabled.
-+#endif
-+
-+/*
-+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+ * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then !
-+ * ! SHA_LONG_LOG2 has to be defined along. !
-+ * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-+ */
-+
-+#if defined(WIN16) || defined(__LP32__)
-+#define SHA_LONG unsigned long
-+#elif defined(_CRAY) || defined(__ILP64__)
-+#define SHA_LONG unsigned long
-+#define SHA_LONG_LOG2 3
-+#else
-+#define SHA_LONG unsigned int
-+#endif
-+
-+#define SHA_LBLOCK 16
-+#define SHA_CBLOCK (SHA_LBLOCK*4) /* SHA treats input data as a
-+ * contiguous array of 32 bit
-+ * wide big-endian values. */
-+#define SHA_LAST_BLOCK (SHA_CBLOCK-8)
-+#define SHA_DIGEST_LENGTH 20
-+
-+typedef struct SHAstate_st
-+ {
-+ SHA_LONG h0,h1,h2,h3,h4;
-+ SHA_LONG Nl,Nh;
-+ SHA_LONG data[SHA_LBLOCK];
-+ int num;
-+ } SHA_CTX;
-+
-+#ifndef NO_SHA0
-+void SHA_Init(SHA_CTX *c);
-+void SHA_Update(SHA_CTX *c, const void *data, unsigned long len);
-+void SHA_Final(unsigned char *md, SHA_CTX *c);
-+unsigned char *SHA(const unsigned char *d, unsigned long n,unsigned char *md);
-+void SHA_Transform(SHA_CTX *c, const unsigned char *data);
-+#endif
-+#ifndef NO_SHA1
-+void SHA1_Init(SHA_CTX *c);
-+void SHA1_Update(SHA_CTX *c, const void *data, unsigned long len);
-+void SHA1_Final(unsigned char *md, SHA_CTX *c);
-+unsigned char *SHA1(const unsigned char *d, unsigned long n,unsigned char *md);
-+void SHA1_Transform(SHA_CTX *c, const unsigned char *data);
-+#endif
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
-diff -Nur linux_c860_org/include/video/tosa_backlight.h linux/include/video/tosa_backlight.h
---- linux_c860_org/include/video/tosa_backlight.h 1970-01-01 09:00:00.000000000 +0900
-+++ linux/include/video/tosa_backlight.h 2004-06-10 21:09:11.000000000 +0900
-@@ -0,0 +1,47 @@
-+/*
-+ * linux/include/video/tosa_backlight.h
-+ *
-+ * (C) Copyright 2004 Lineo Solutions, Inc.
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ *
-+ * Based on:
-+ * linux/include/video/corgi_backlight.h
-+ *
-+ * (C) Copyright 2002 Lineo Japan, Inc.
-+ *
-+ * May be copied or modified under the terms of the GNU General Public
-+ * License. See linux/COPYING for more information.
-+ *
-+ * Based on include/video/sa1100_frontlight.h
-+ *
-+ * ChangeLog:
-+ * 06-Nov-2002 SHARP for SL-B500/5600
-+ */
-+
-+
-+#ifndef __TOSA_FRONTLIGHT_H
-+#define __TOSA_FRONTLIGHT_H
-+
-+#define TOSA_BL_IOCTL_ON 1
-+#define TOSA_BL_IOCTL_OFF 2
-+#define TOSA_BL_IOCTL_STEP_CONTRAST 100
-+#define TOSA_BL_IOCTL_GET_STEP_CONTRAST 101
-+#define TOSA_BL_IOCTL_GET_STEP 102
-+
-+#define TOSA_BL_RESET_CONTRAST (-1)
-+#define TOSA_BL_CAUTION_CONTRAST (1)
-+
-+#define BL_MAJOR 254
-+#define BL_NAME "tosa-bl"
-+
-+#ifdef CONFIG_PM
-+void tosa_bl_blank(int);
-+int tosa_bl_pm_callback(struct pm_dev*, pm_request_t, void*);
-+#endif
-+void tosa_bl_temporary_contrast_set(void);
-+void tosa_bl_temporary_contrast_reset(void);
-+void tosa_bl_set_limit_contrast(int);
-+
-+#endif /* __TOSA_FRONTLIGHT_H */
-diff -Nur linux_c860_org/kernel/exit.c linux/kernel/exit.c
---- linux_c860_org/kernel/exit.c 2002-08-26 14:43:29.000000000 +0900
-+++ linux/kernel/exit.c 2004-06-10 21:09:11.000000000 +0900
-@@ -203,6 +203,8 @@
- }
- i++;
- set >>= 1;
-+ debug_lock_break(1);
-+ conditional_schedule();
- }
- }
- }
-@@ -320,8 +322,8 @@
- /* more a memory barrier than a real lock */
- task_lock(tsk);
- tsk->mm = NULL;
-- task_unlock(tsk);
- enter_lazy_tlb(mm, current, smp_processor_id());
-+ task_unlock(tsk);
- mmput(mm);
- }
- }
-@@ -442,6 +444,11 @@
- tsk->flags |= PF_EXITING;
- del_timer_sync(&tsk->real_timer);
-
-+ if (unlikely(preempt_get_count()))
-+ printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",
-+ current->comm, current->pid,
-+ preempt_get_count());
-+
- fake_volatile:
- #ifdef CONFIG_BSD_PROCESS_ACCT
- acct_process(code);
-diff -Nur linux_c860_org/kernel/fork.c linux/kernel/fork.c
---- linux_c860_org/kernel/fork.c 2002-12-18 19:29:50.000000000 +0900
-+++ linux/kernel/fork.c 2004-06-10 21:09:11.000000000 +0900
-@@ -28,6 +28,7 @@
- #include <asm/pgalloc.h>
- #include <asm/uaccess.h>
- #include <asm/mmu_context.h>
-+#include <asm/processor.h>
-
- /* The idle threads do not count.. */
- int nr_threads;
-@@ -561,6 +562,31 @@
- p->flags = new_flags;
- }
-
-+long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-+{
-+ struct task_struct *task = current;
-+ unsigned old_task_dumpable;
-+ long ret;
-+
-+ /* lock out any potential ptracer */
-+ task_lock(task);
-+ if (task->ptrace) {
-+ task_unlock(task);
-+ return -EPERM;
-+ }
-+
-+ old_task_dumpable = task->task_dumpable;
-+ task->task_dumpable = 0;
-+ task_unlock(task);
-+
-+ ret = arch_kernel_thread(fn, arg, flags);
-+
-+ /* never reached in child process, only in parent */
-+ current->task_dumpable = old_task_dumpable;
-+
-+ return ret;
-+}
-+
- /*
- * Ok, this is the main fork-routine. It copies the system process
- * information (task[nr]) and sets up the necessary registers. It also
-@@ -622,6 +648,13 @@
- if (p->binfmt && p->binfmt->module)
- __MOD_INC_USE_COUNT(p->binfmt->module);
-
-+#ifdef CONFIG_PREEMPT
-+ /*
-+ * Continue with preemption disabled as part of the context
-+ * switch, so start with preempt_count set to 1.
-+ */
-+ p->preempt_count = 1;
-+#endif
- p->did_exec = 0;
- p->swappable = 0;
- p->state = TASK_UNINTERRUPTIBLE;
-diff -Nur linux_c860_org/kernel/ksyms.c linux/kernel/ksyms.c
---- linux_c860_org/kernel/ksyms.c 2002-08-26 14:43:29.000000000 +0900
-+++ linux/kernel/ksyms.c 2004-06-10 21:09:11.000000000 +0900
-@@ -439,6 +439,9 @@
- EXPORT_SYMBOL(interruptible_sleep_on);
- EXPORT_SYMBOL(interruptible_sleep_on_timeout);
- EXPORT_SYMBOL(schedule);
-+#ifdef CONFIG_PREEMPT
-+EXPORT_SYMBOL(preempt_schedule);
-+#endif
- EXPORT_SYMBOL(schedule_timeout);
- EXPORT_SYMBOL(jiffies);
- EXPORT_SYMBOL(xtime);
-diff -Nur linux_c860_org/kernel/ptrace.c linux/kernel/ptrace.c
---- linux_c860_org/kernel/ptrace.c 2002-08-26 14:37:42.000000000 +0900
-+++ linux/kernel/ptrace.c 2004-06-10 21:09:11.000000000 +0900
-@@ -21,6 +21,9 @@
- */
- int ptrace_check_attach(struct task_struct *child, int kill)
- {
-+ mb();
-+ if (!child->task_dumpable)
-+ return -EPERM;
- if (!(child->ptrace & PT_PTRACED))
- return -ESRCH;
-
-@@ -70,7 +73,7 @@
- (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
- goto bad;
- rmb();
-- if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
-+ if (!is_dumpable(task) && !capable(CAP_SYS_PTRACE))
- goto bad;
- /* the same process cannot be attached many times */
- if (task->ptrace & PT_PTRACED)
-@@ -136,6 +139,8 @@
- /* Worry about races with exit() */
- task_lock(tsk);
- mm = tsk->mm;
-+ if (!tsk->task_dumpable || (&init_mm == mm))
-+ mm = NULL;
- if (mm)
- atomic_inc(&mm->mm_users);
- task_unlock(tsk);
-diff -Nur linux_c860_org/kernel/sched.c linux/kernel/sched.c
---- linux_c860_org/kernel/sched.c 2002-08-26 14:37:42.000000000 +0900
-+++ linux/kernel/sched.c 2004-06-10 21:09:11.000000000 +0900
-@@ -491,7 +491,7 @@
- task_lock(prev);
- task_release_cpu(prev);
- mb();
-- if (prev->state == TASK_RUNNING)
-+ if (task_on_runqueue(prev))
- goto needs_resched;
-
- out_unlock:
-@@ -521,7 +521,7 @@
- goto out_unlock;
-
- spin_lock_irqsave(&runqueue_lock, flags);
-- if ((prev->state == TASK_RUNNING) && !task_has_cpu(prev))
-+ if (task_on_runqueue(prev) && !task_has_cpu(prev))
- reschedule_idle(prev);
- spin_unlock_irqrestore(&runqueue_lock, flags);
- goto out_unlock;
-@@ -534,6 +534,7 @@
- asmlinkage void schedule_tail(struct task_struct *prev)
- {
- __schedule_tail(prev);
-+ preempt_enable();
- }
-
- /*
-@@ -553,10 +554,12 @@
- struct list_head *tmp;
- int this_cpu, c;
-
--
- spin_lock_prefetch(&runqueue_lock);
-
-+ preempt_disable();
-+
- if (!current->active_mm) BUG();
-+
- need_resched_back:
- prev = current;
- this_cpu = prev->processor;
-@@ -583,6 +586,14 @@
- move_last_runqueue(prev);
- }
-
-+#ifdef CONFIG_PREEMPT
-+ /*
-+ * entering from preempt_schedule, off a kernel preemption,
-+ * go straight to picking the next task.
-+ */
-+ if (unlikely(preempt_get_count() & PREEMPT_ACTIVE))
-+ goto treat_like_run;
-+#endif
- switch (prev->state) {
- case TASK_INTERRUPTIBLE:
- if (signal_pending(prev)) {
-@@ -593,6 +604,9 @@
- del_from_runqueue(prev);
- case TASK_RUNNING:;
- }
-+#ifdef CONFIG_PREEMPT
-+ treat_like_run:
-+#endif
- prev->need_resched = 0;
-
- /*
-@@ -701,9 +715,25 @@
- reacquire_kernel_lock(current);
- if (current->need_resched)
- goto need_resched_back;
-+ preempt_enable_no_resched();
- return;
- }
-
-+#ifdef CONFIG_PREEMPT
-+/*
-+ * this is is the entry point to schedule() from in-kernel preemption.
-+ */
-+asmlinkage void preempt_schedule(void)
-+{
-+ do {
-+ current->preempt_count += PREEMPT_ACTIVE;
-+ schedule();
-+ current->preempt_count -= PREEMPT_ACTIVE;
-+ barrier();
-+ } while (current->need_resched);
-+}
-+#endif /* CONFIG_PREEMPT */
-+
- /*
- * The core wakeup function. Non-exclusive wakeups (nr_exclusive == 0) just wake everything
- * up. If it's an exclusive wakeup (nr_exclusive == small +ve number) then we wake all the
-@@ -1312,6 +1342,13 @@
- sched_data->curr = current;
- sched_data->last_schedule = get_cycles();
- clear_bit(current->processor, &wait_init_idle);
-+#ifdef CONFIG_PREEMPT
-+ /*
-+ * fix up the preempt_count for non-CPU0 idle threads
-+ */
-+ if (current->processor)
-+ current->preempt_count = 0;
-+#endif
- }
-
- extern void init_timervecs (void);
-diff -Nur linux_c860_org/kernel/sys.c linux/kernel/sys.c
---- linux_c860_org/kernel/sys.c 2002-08-29 12:24:32.000000000 +0900
-+++ linux/kernel/sys.c 2004-06-10 21:09:11.000000000 +0900
-@@ -1231,7 +1231,7 @@
- error = put_user(current->pdeath_signal, (int *)arg2);
- break;
- case PR_GET_DUMPABLE:
-- if (current->mm->dumpable)
-+ if (is_dumpable(current))
- error = 1;
- break;
- case PR_SET_DUMPABLE:
-@@ -1239,7 +1239,8 @@
- error = -EINVAL;
- break;
- }
-- current->mm->dumpable = arg2;
-+ if (is_dumpable(current))
-+ current->mm->dumpable = arg2;
- break;
- case PR_SET_UNALIGN:
- #ifdef SET_UNALIGN_CTL
-diff -Nur linux_c860_org/lib/dec_and_lock.c linux/lib/dec_and_lock.c
---- linux_c860_org/lib/dec_and_lock.c 2002-08-26 14:37:42.000000000 +0900
-+++ linux/lib/dec_and_lock.c 2004-06-10 21:09:11.000000000 +0900
-@@ -1,5 +1,6 @@
- #include <linux/module.h>
- #include <linux/spinlock.h>
-+#include <linux/sched.h>
- #include <asm/atomic.h>
-
- /*
-diff -Nur linux_c860_org/mm/filemap.c linux/mm/filemap.c
---- linux_c860_org/mm/filemap.c 2002-08-26 14:37:43.000000000 +0900
-+++ linux/mm/filemap.c 2004-06-10 21:09:11.000000000 +0900
-@@ -296,6 +296,7 @@
-
- page_cache_release(page);
-
-+ /* we hit this with lock depth of 1 or 2 */
- if (current->need_resched) {
- __set_current_state(TASK_RUNNING);
- schedule();
-@@ -406,6 +407,8 @@
- }
-
- page_cache_release(page);
-+
-+ debug_lock_break(551);
- if (current->need_resched) {
- __set_current_state(TASK_RUNNING);
- schedule();
-@@ -560,12 +563,16 @@
- list_del(&page->list);
- list_add(&page->list, &mapping->locked_pages);
-
-- if (!PageDirty(page))
-- continue;
--
- page_cache_get(page);
- spin_unlock(&pagecache_lock);
-
-+ /* BKL is held ... */
-+ debug_lock_break(1);
-+ conditional_schedule();
-+
-+ if (!PageDirty(page))
-+ goto clean;
-+
- lock_page(page);
-
- if (PageDirty(page)) {
-@@ -576,7 +583,7 @@
- ret = err;
- } else
- UnlockPage(page);
--
-+clean:
- page_cache_release(page);
- spin_lock(&pagecache_lock);
- }
-@@ -595,14 +602,28 @@
- {
- int ret = 0;
-
-+ DEFINE_LOCK_COUNT();
-+
- spin_lock(&pagecache_lock);
-
-+restart:
- while (!list_empty(&mapping->locked_pages)) {
- struct page *page = list_entry(mapping->locked_pages.next, struct page, list);
-
- list_del(&page->list);
- list_add(&page->list, &mapping->clean_pages);
-
-+ debug_lock_break(2);
-+ if (TEST_LOCK_COUNT(32)) {
-+ RESET_LOCK_COUNT();
-+ if (conditional_schedule_needed()) {
-+ page_cache_get(page);
-+ break_spin_lock_and_resched(&pagecache_lock);
-+ page_cache_release(page);
-+ goto restart;
-+ }
-+ }
-+
- if (!PageLocked(page))
- continue;
-
-@@ -869,6 +890,7 @@
- * the hash-list needs a held write-lock.
- */
- repeat:
-+ break_spin_lock(&pagecache_lock);
- page = __find_page_nolock(mapping, offset, hash);
- if (page) {
- page_cache_get(page);
-@@ -2031,6 +2053,8 @@
- address += PAGE_SIZE;
- pte++;
- } while (address && (address < end));
-+ debug_lock_break(1);
-+ break_spin_lock(&vma->vm_mm->page_table_lock);
- return error;
- }
-
-@@ -2061,6 +2085,9 @@
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address && (address < end));
-+
-+ debug_lock_break(1);
-+ break_spin_lock(&vma->vm_mm->page_table_lock);
- return error;
- }
-
-@@ -2438,7 +2465,7 @@
- if (vma->vm_flags & VM_LOCKED)
- return -EINVAL;
-
-- zap_page_range(vma->vm_mm, start, end - start);
-+ zap_page_range(vma->vm_mm, start, end - start, ZPR_PARTITION);
- return 0;
- }
-
-diff -Nur linux_c860_org/mm/memory.c linux/mm/memory.c
---- linux_c860_org/mm/memory.c 2003-06-18 16:12:29.000000000 +0900
-+++ linux/mm/memory.c 2004-06-10 21:09:11.000000000 +0900
-@@ -384,7 +384,8 @@
- /*
- * remove user pages in a given range.
- */
--void zap_page_range(struct mm_struct *mm, unsigned long address, unsigned long size)
-+void do_zap_page_range(struct mm_struct *mm, unsigned long address,
-+ unsigned long size)
- {
- unsigned long start = address, end = address + size;
- mmu_gather_t *tlb;
-@@ -643,6 +644,20 @@
- iobuf->locked = 0;
- }
-
-+void zap_page_range(struct mm_struct *mm, unsigned long address,
-+ unsigned long size, int actions)
-+{
-+ while (size) {
-+ unsigned long chunk = size;
-+
-+ if (actions & ZPR_PARTITION && chunk > ZPR_MAX_BYTES)
-+ chunk = ZPR_MAX_BYTES;
-+ do_zap_page_range(mm, address, chunk);
-+
-+ address += chunk;
-+ size -= chunk;
-+ }
-+}
-
- /*
- * Lock down all of the pages of a kiovec for IO.
-@@ -752,11 +767,15 @@
- return 0;
- }
-
--static inline void zeromap_pte_range(pte_t * pte, unsigned long address,
-- unsigned long size, pgprot_t prot)
-+static inline void zeromap_pte_range(struct mm_struct *mm, pte_t * pte,
-+ unsigned long address, unsigned long size,
-+ pgprot_t prot)
- {
- unsigned long end;
-
-+ debug_lock_break(1);
-+ break_spin_lock(&mm->page_table_lock);
-+
- address &= ~PMD_MASK;
- end = address + size;
- if (end > PMD_SIZE)
-@@ -784,7 +803,7 @@
- pte_t * pte = pte_alloc(mm, pmd, address);
- if (!pte)
- return -ENOMEM;
-- zeromap_pte_range(pte, address, end - address, prot);
-+ zeromap_pte_range(mm, pte, address, end - address, prot);
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address && (address < end));
-@@ -1022,7 +1041,7 @@
-
- /* mapping wholly truncated? */
- if (mpnt->vm_pgoff >= pgoff) {
-- zap_page_range(mm, start, len);
-+ zap_page_range(mm, start, len, ZPR_NORMAL);
- continue;
- }
-
-@@ -1035,7 +1054,7 @@
- /* Ok, partially affected.. */
- start += diff << PAGE_SHIFT;
- len = (len - diff) << PAGE_SHIFT;
-- zap_page_range(mm, start, len);
-+ zap_page_range(mm, start, len, ZPR_NORMAL);
- } while ((mpnt = mpnt->vm_next_share) != NULL);
- }
-
-diff -Nur linux_c860_org/mm/mmap.c linux/mm/mmap.c
---- linux_c860_org/mm/mmap.c 2003-06-18 16:12:29.000000000 +0900
-+++ linux/mm/mmap.c 2004-06-10 21:09:11.000000000 +0900
-@@ -578,7 +578,7 @@
- fput(file);
-
- /* Undo any partial mapping done by a device driver. */
-- zap_page_range(mm, vma->vm_start, vma->vm_end - vma->vm_start);
-+ zap_page_range(mm, vma->vm_start, vma->vm_end - vma->vm_start, ZPR_NORMAL);
- free_vma:
- kmem_cache_free(vm_area_cachep, vma);
- return error;
-@@ -978,7 +978,7 @@
- remove_shared_vm_struct(mpnt);
- mm->map_count--;
-
-- zap_page_range(mm, st, size);
-+ zap_page_range(mm, st, size, ZPR_PARTITION);
-
- /*
- * Fix the mapping, and free the old area if it wasn't reused.
-@@ -1025,6 +1025,9 @@
- if (!len)
- return addr;
-
-+ if ((addr + len) > TASK_SIZE || (addr + len) < addr)
-+ return -EINVAL;
-+
- /*
- * mlock MCL_FUTURE?
- */
-diff -Nur linux_c860_org/mm/mremap.c linux/mm/mremap.c
---- linux_c860_org/mm/mremap.c 2002-08-26 14:37:43.000000000 +0900
-+++ linux/mm/mremap.c 2004-06-10 21:09:11.000000000 +0900
-@@ -118,7 +118,7 @@
- flush_cache_range(mm, new_addr, new_addr + len);
- while ((offset += PAGE_SIZE) < len)
- move_one_page(mm, new_addr + offset, old_addr + offset);
-- zap_page_range(mm, new_addr, len);
-+ zap_page_range(mm, new_addr, len, ZPR_NORMAL);
- return -1;
- }
-
-@@ -236,6 +236,13 @@
-
- if (new_len > TASK_SIZE || new_addr > TASK_SIZE - new_len)
- goto out;
-+ /*
-+ * Allow new_len == 0 only if new_addr == addr
-+ * to preserve truncation in place (that was working
-+ * safe and some app may depend on it).
-+ */
-+ if (unlikely(!new_len && new_addr != addr))
-+ goto out;
-
- /* Check if the location we're moving into overlaps the
- * old location at all, and fail if it does.
-@@ -246,16 +253,20 @@
- if ((addr <= new_addr) && (addr+old_len) > new_addr)
- goto out;
-
-- do_munmap(current->mm, new_addr, new_len);
-+ ret = do_munmap(current->mm, new_addr, new_len);
-+ if (ret && new_len)
-+ goto out;
- }
-
- /*
- * Always allow a shrinking remap: that just unmaps
- * the unnecessary pages..
- */
-- ret = addr;
- if (old_len >= new_len) {
-- do_munmap(current->mm, addr+new_len, old_len - new_len);
-+ ret = do_munmap(current->mm, addr+new_len, old_len - new_len);
-+ if (ret && old_len != new_len)
-+ goto out;
-+ ret = addr;
- if (!(flags & MREMAP_FIXED) || (new_addr == addr))
- goto out;
- }
-diff -Nur linux_c860_org/mm/oom_kill.c linux/mm/oom_kill.c
---- linux_c860_org/mm/oom_kill.c 2003-06-18 16:12:29.000000000 +0900
-+++ linux/mm/oom_kill.c 2004-06-10 21:09:11.000000000 +0900
-@@ -20,6 +20,7 @@
- * 16-Jan-2003 SHARP add VM switch
- * 24-Feb-2003 SHARP modify check out of memory function
- * 18-Apr-2003 Sharp modify threshold
-+ * 05-Aug-2003 SHARP for Tosa
- */
-
- #include <linux/mm.h>
-@@ -237,7 +238,7 @@
-
- #if defined(CONFIG_ARCH_SHARP_SL)
- #define MIN_KILL_INTERVAL (60*HZ)
--#if defined(CONFIG_ARCH_PXA_SHEPHERD)
-+#if defined(CONFIG_ARCH_PXA_SHEPHERD) || defined (CONFIG_ARCH_PXA_TOSA)
- #define OOM_KILL_PG_CACHE_SIZE (1280) /* 5MB */
- #define MIN_SIGNAL_PG_CACHE_SIZE (1536) /* 6MB */
- #define LOW_SIGNAL_PG_CACHE_SIZE (2048) /* 8MB */
-diff -Nur linux_c860_org/mm/slab.c linux/mm/slab.c
---- linux_c860_org/mm/slab.c 2002-11-22 21:03:26.000000000 +0900
-+++ linux/mm/slab.c 2004-06-10 21:09:11.000000000 +0900
-@@ -49,7 +49,8 @@
- * constructors and destructors are called without any locking.
- * Several members in kmem_cache_t and slab_t never change, they
- * are accessed without any locking.
-- * The per-cpu arrays are never accessed from the wrong cpu, no locking.
-+ * The per-cpu arrays are never accessed from the wrong cpu, no locking,
-+ * and local interrupts are disabled so slab code is preempt-safe.
- * The non-constant members are protected with a per-cache irq spinlock.
- *
- * Further notes from the original documentation:
-diff -Nur linux_c860_org/mm/swapfile.c linux/mm/swapfile.c
---- linux_c860_org/mm/swapfile.c 2002-08-26 14:37:43.000000000 +0900
-+++ linux/mm/swapfile.c 2004-06-10 21:09:11.000000000 +0900
-@@ -696,6 +696,7 @@
- * interactive performance. Interruptible check on
- * signal_pending() would be nice, but changes the spec?
- */
-+ debug_lock_break(551);
- if (current->need_resched)
- schedule();
- }
-@@ -1124,6 +1125,13 @@
- if (swap_info[i].flags != SWP_USED)
- continue;
- for (j = 0; j < swap_info[i].max; ++j) {
-+ if (conditional_schedule_needed()) {
-+ debug_lock_break(551);
-+ swap_list_unlock();
-+ debug_lock_break(551);
-+ unconditional_schedule();
-+ swap_list_lock();
-+ }
- switch (swap_info[i].swap_map[j]) {
- case 0:
- case SWAP_MAP_BAD:
-diff -Nur linux_c860_org/mm/vmscan.c linux/mm/vmscan.c
---- linux_c860_org/mm/vmscan.c 2003-01-30 18:59:16.000000000 +0900
-+++ linux/mm/vmscan.c 2004-06-10 21:09:11.000000000 +0900
-@@ -170,6 +170,8 @@
- pte_t * pte;
- unsigned long pmd_end;
-
-+ DEFINE_LOCK_COUNT();
-+
- if (pmd_none(*dir))
- return count;
- if (pmd_bad(*dir)) {
-@@ -194,6 +196,14 @@
- address += PAGE_SIZE;
- break;
- }
-+ /* we reach this with a lock depth of 1 or 2 */
-+#if 0
-+ if (TEST_LOCK_COUNT(4)) {
-+ if (conditional_schedule_needed())
-+ return count;
-+ RESET_LOCK_COUNT();
-+ }
-+#endif
- }
- }
- address += PAGE_SIZE;
-@@ -227,6 +237,9 @@
- count = swap_out_pmd(mm, vma, pmd, address, end, count, classzone);
- if (!count)
- break;
-+ /* lock depth can be 1 or 2 */
-+ if (conditional_schedule_needed())
-+ return count;
- address = (address + PMD_SIZE) & PMD_MASK;
- pmd++;
- } while (address && (address < end));
-@@ -252,6 +265,9 @@
- count = swap_out_pgd(mm, vma, pgdir, address, end, count, classzone);
- if (!count)
- break;
-+ /* lock depth can be 1 or 2 */
-+ if (conditional_schedule_needed())
-+ return count;
- address = (address + PGDIR_SIZE) & PGDIR_MASK;
- pgdir++;
- } while (address && (address < end));
-@@ -274,6 +290,8 @@
- * and ptes.
- */
- spin_lock(&mm->page_table_lock);
-+
-+continue_scan:
- address = mm->swap_address;
- if (address == TASK_SIZE || swap_mm != mm) {
- /* We raced: don't count this mm but try again */
-@@ -290,6 +308,13 @@
- vma = vma->vm_next;
- if (!vma)
- break;
-+ /* we reach this with a lock depth of 1 and 2 */
-+#if 0
-+ if (conditional_schedule_needed()) {
-+ break_spin_lock(&mm->page_table_lock);
-+ goto continue_scan;
-+ }
-+#endif
- if (!count)
- goto out_unlock;
- address = vma->vm_start;
-@@ -311,6 +336,7 @@
-
- counter = mmlist_nr;
- do {
-+ /* lock depth can be 0 or 1 */
- if (unlikely(current->need_resched)) {
- __set_current_state(TASK_RUNNING);
- schedule();
-@@ -356,6 +382,7 @@
- while (--max_scan >= 0 && (entry = inactive_list.prev) != &inactive_list) {
- struct page * page;
-
-+ /* lock depth is 1 or 2 */
- if (unlikely(current->need_resched)) {
- spin_unlock(&pagemap_lru_lock);
- __set_current_state(TASK_RUNNING);
-@@ -673,8 +700,11 @@
-
- for (i = pgdat->nr_zones-1; i >= 0; i--) {
- zone = pgdat->node_zones + i;
-+ debug_lock_break(0);
-+#ifndef CONFIG_PREEMPT
- if (unlikely(current->need_resched))
- schedule();
-+#endif
- if (!zone->need_balance)
- continue;
- if (!try_to_free_pages(zone, GFP_KSWAPD, 0)) {
-diff -Nur linux_c860_org/net/core/dev.c linux/net/core/dev.c
---- linux_c860_org/net/core/dev.c 2002-08-26 14:42:28.000000000 +0900
-+++ linux/net/core/dev.c 2004-06-10 21:09:11.000000000 +0900
-@@ -1033,9 +1033,15 @@
- int cpu = smp_processor_id();
-
- if (dev->xmit_lock_owner != cpu) {
-+ /*
-+ * The spin_lock effectivly does a preempt lock, but
-+ * we are about to drop that...
-+ */
-+ preempt_disable();
- spin_unlock(&dev->queue_lock);
- spin_lock(&dev->xmit_lock);
- dev->xmit_lock_owner = cpu;
-+ preempt_enable();
-
- if (!netif_queue_stopped(dev)) {
- if (netdev_nit)
-diff -Nur linux_c860_org/net/core/skbuff.c linux/net/core/skbuff.c
---- linux_c860_org/net/core/skbuff.c 2002-08-26 14:42:28.000000000 +0900
-+++ linux/net/core/skbuff.c 2004-06-10 21:09:11.000000000 +0900
-@@ -111,33 +111,37 @@
-
- static __inline__ struct sk_buff *skb_head_from_pool(void)
- {
-- struct sk_buff_head *list = &skb_head_pool[smp_processor_id()].list;
-+ struct sk_buff_head *list;
-+ struct sk_buff *skb = NULL;
-+ unsigned long flags;
-
-- if (skb_queue_len(list)) {
-- struct sk_buff *skb;
-- unsigned long flags;
-+ local_irq_save(flags);
-
-- local_irq_save(flags);
-+ list = &skb_head_pool[smp_processor_id()].list;
-+
-+ if (skb_queue_len(list))
- skb = __skb_dequeue(list);
-- local_irq_restore(flags);
-- return skb;
-- }
-- return NULL;
-+
-+ local_irq_restore(flags);
-+ return skb;
- }
-
- static __inline__ void skb_head_to_pool(struct sk_buff *skb)
- {
-- struct sk_buff_head *list = &skb_head_pool[smp_processor_id()].list;
-+ struct sk_buff_head *list;
-+ unsigned long flags;
-
-- if (skb_queue_len(list) < sysctl_hot_list_len) {
-- unsigned long flags;
-+ local_irq_save(flags);
-+ list = &skb_head_pool[smp_processor_id()].list;
-
-- local_irq_save(flags);
-+ if (skb_queue_len(list) < sysctl_hot_list_len) {
- __skb_queue_head(list, skb);
- local_irq_restore(flags);
-
- return;
- }
-+
-+ local_irq_restore(flags);
- kmem_cache_free(skbuff_head_cache, skb);
- }
-
-diff -Nur linux_c860_org/net/irda/irlmp.c linux/net/irda/irlmp.c
---- linux_c860_org/net/irda/irlmp.c 2003-01-10 15:02:41.000000000 +0900
-+++ linux/net/irda/irlmp.c 2004-06-10 21:09:11.000000000 +0900
-@@ -24,6 +24,8 @@
- *
- * ChangeLog:
- * 11-20-2002 SHARP apply patch (fix small bugs in /proc)
-+ * 1-Nov-2003 Sharp Corporation for Tosa
-+ *
- ********************************************************************/
-
- #include <linux/config.h>
-@@ -769,6 +771,14 @@
- nslots = sysctl_discovery_slots = 8;
- }
-
-+#if defined(CONFIG_ARCH_SHARP_SL)
-+ /*
-+ * Clear the passive discovery retry flag.
-+ * modified by SHARP
-+ */
-+ irlmp->discovery_retry = FALSE;
-+#endif
-+
- /* Construct new discovery info to be used by IrLAP, */
- irlmp->discovery_cmd.hints.word = irlmp->hints.word;
-
-diff -Nur linux_c860_org/net/irda/irlmp_event.c linux/net/irda/irlmp_event.c
---- linux_c860_org/net/irda/irlmp_event.c 2002-08-29 12:25:13.000000000 +0900
-+++ linux/net/irda/irlmp_event.c 2004-06-10 21:09:11.000000000 +0900
-@@ -22,6 +22,9 @@
- * provide warranty for any of this software. This material is
- * provided "AS-IS" and at no charge.
- *
-+ * ChangeLog:
-+ * 1-Nov-2003 Sharp Corporation for Tosa
-+ *
- ********************************************************************/
-
- #include <linux/config.h>
-@@ -178,6 +181,16 @@
- /* Active discovery is conditional */
- if (sysctl_discovery)
- irlmp_do_discovery(sysctl_discovery_slots);
-+#if defined(CONFIG_ARCH_SHARP_SL)
-+ else if (( irlmp != NULL )&&( irlmp->discovery_retry )){
-+ /*
-+ * Retry discovery at passive mode, if it hasn't been done
-+ * because of the media busy.
-+ * modified by SHARP
-+ */
-+ irlmp_do_discovery(sysctl_discovery_slots);
-+ }
-+#endif
-
- /* Restart timer */
- irlmp_start_discovery_timer(irlmp, sysctl_discovery_timeout * HZ);
-diff -Nur linux_c860_org/net/irda/irlmp_frame.c linux/net/irda/irlmp_frame.c
---- linux_c860_org/net/irda/irlmp_frame.c 2002-08-29 12:25:13.000000000 +0900
-+++ linux/net/irda/irlmp_frame.c 2004-06-10 21:09:11.000000000 +0900
-@@ -22,6 +22,9 @@
- * provide warranty for any of this software. This material is
- * provided "AS-IS" and at no charge.
- *
-+ * ChangeLog:
-+ * 1-Nov-2003 Sharp Corporation for Tosa
-+ *
- ********************************************************************/
-
- #include <linux/config.h>
-@@ -397,6 +400,16 @@
- ASSERT(self->magic == LMP_LAP_MAGIC, return;);
-
- irlmp_add_discovery_log(irlmp->cachelog, log);
-+#if defined(CONFIG_ARCH_SHARP_SL)
-+ /*
-+ * Retry discovery at passive mode, if it hasn't been done
-+ * because of the media busy.
-+ * modified by SHARP
-+ */
-+ if(( log == NULL )&&( irlmp != NULL )){
-+ irlmp->discovery_retry = TRUE;
-+ }
-+#endif
-
- /* Propagate event to various LSAPs registered for it.
- * We bypass the LM_LAP state machine because
-diff -Nur linux_c860_org/net/socket.c linux/net/socket.c
---- linux_c860_org/net/socket.c 2002-08-29 12:25:05.000000000 +0900
-+++ linux/net/socket.c 2004-06-10 21:09:11.000000000 +0900
-@@ -140,7 +140,7 @@
-
- static struct net_proto_family *net_families[NPROTO];
-
--#ifdef CONFIG_SMP
-+#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
- static atomic_t net_family_lockct = ATOMIC_INIT(0);
- static spinlock_t net_family_lock = SPIN_LOCK_UNLOCKED;
-
-diff -Nur linux_c860_org/net/sunrpc/pmap_clnt.c linux/net/sunrpc/pmap_clnt.c
---- linux_c860_org/net/sunrpc/pmap_clnt.c 2002-08-26 14:38:06.000000000 +0900
-+++ linux/net/sunrpc/pmap_clnt.c 2004-06-10 21:09:11.000000000 +0900
-@@ -12,6 +12,7 @@
- #include <linux/config.h>
- #include <linux/types.h>
- #include <linux/socket.h>
-+#include <linux/sched.h>
- #include <linux/kernel.h>
- #include <linux/errno.h>
- #include <linux/uio.h>
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/sharpsl_battery.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/sharpsl_battery.patch
deleted file mode 100644
index fafdf32e55..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/sharpsl_battery.patch
+++ /dev/null
@@ -1,346 +0,0 @@
---- linux-orig/arch/arm/mach-pxa/sharpsl_battery.c 2004-02-18 23:41:57.000000000 +0300
-+++ linux/arch/arm/mach-pxa/sharpsl_battery.c 2004-02-24 06:21:56.000000000 +0300
-@@ -197,7 +197,7 @@
- #define SHARPSL_CHECK_BATTERY_WAIT_TIME_VOLT 1 // 10msec
- #define SHARPSL_CHECK_BATTERY_WAIT_TIME_JKVAD 1 // 10msec
- #define SHARPSL_CORGI_FATAL_ACIN_VOLT 182 // 3.45V
--#define SHARPSL_CORGI_FATAL_NOACIN_VOLT 179 // 3.40V
-+#define SHARPSL_CORGI_FATAL_NOACIN_VOLT 170 // 3.40V
- #define SHARPSL_CORGI_WAIT_CO_TIME 15 // 15 Sec
- //NOTICE !! you want to change this value , so you must change
- // alarm check mirgin time ( +30 ) in the sharpsl_power.c.
-@@ -245,10 +245,17 @@
- BATTERY_THRESH *GetMainLevel( int Volt );
- int sharpsl_get_main_battery(void);
- int suspend_sharpsl_read_Voltage(void);
-+int GetMainPercent(int);
- int GetMainChargePercent(int);
- int Get_DAC_Value(int);
- int sharpsl_check_battery(int mode);
-
-+// remove warnings
-+static int sharpsl_battery_thread_main(void);
-+int handle_scancode(int, int);
-+int sharpsl_ac_check(void);
-+void sharpsl_charge_err_off(void);
-+
- /*** extern ***********************************************************************/
- extern u32 apm_wakeup_src_mask;
- #if defined(CONFIG_ARCH_PXA_POODLE) || defined(CONFIG_ARCH_PXA_CORGI)
-@@ -269,7 +276,6 @@
-
- /*** variables ********************************************************************/
-
--
- #if defined(CONFIG_ARCH_PXA_POODLE)
-
- BATTERY_THRESH sharpsl_main_battery_thresh_fl[] = {
-@@ -293,20 +299,26 @@
- #elif defined(CONFIG_ARCH_PXA_CORGI)
-
- BATTERY_THRESH sharpsl_main_battery_thresh_fl[] = {
-- { 194, 100, SHARPSL_BATTERY_STATUS_HIGH},
-- { 188, 75, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 999, 100, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 210, 100, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 194, 90, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 188, 70, SHARPSL_BATTERY_STATUS_HIGH},
- { 184, 50, SHARPSL_BATTERY_STATUS_HIGH},
- { 180, 25, SHARPSL_BATTERY_STATUS_LOW},
-- { 171, 5, SHARPSL_BATTERY_STATUS_VERYLOW},
-+ { 174, 10, SHARPSL_BATTERY_STATUS_LOW},
-+ { 170, 5, SHARPSL_BATTERY_STATUS_VERYLOW},
- { 0, 0, SHARPSL_BATTERY_STATUS_CRITICAL},
- };
-
- BATTERY_THRESH sharpsl_main_battery_thresh_nofl[] = {
-- { 194, 100, SHARPSL_BATTERY_STATUS_HIGH},
-- { 188, 75, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 999, 100, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 210, 100, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 194, 90, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 188, 70, SHARPSL_BATTERY_STATUS_HIGH},
- { 184, 50, SHARPSL_BATTERY_STATUS_HIGH},
- { 180, 25, SHARPSL_BATTERY_STATUS_LOW},
-- { 171, 5, SHARPSL_BATTERY_STATUS_VERYLOW},
-+ { 174, 10, SHARPSL_BATTERY_STATUS_LOW},
-+ { 170, 5, SHARPSL_BATTERY_STATUS_VERYLOW},
- { 0, 0, SHARPSL_BATTERY_STATUS_CRITICAL},
- };
- #endif
-@@ -332,25 +344,36 @@
- #elif defined(CONFIG_ARCH_PXA_CORGI)
-
- BATTERY_THRESH sharpsl_main_battery_thresh_charge_fl[] = {
-- { 200, 100, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 999, 100, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 210, 100, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 200, 95, SHARPSL_BATTERY_STATUS_HIGH},
- { 196, 75, SHARPSL_BATTERY_STATUS_HIGH},
- { 192, 50, SHARPSL_BATTERY_STATUS_HIGH},
- { 187, 25, SHARPSL_BATTERY_STATUS_LOW},
-- { 171, 5, SHARPSL_BATTERY_STATUS_VERYLOW},
-+ { 182, 10, SHARPSL_BATTERY_STATUS_LOW},
-+ { 170, 5, SHARPSL_BATTERY_STATUS_VERYLOW},
- { 0, 0, SHARPSL_BATTERY_STATUS_CRITICAL},
- };
-
- BATTERY_THRESH sharpsl_main_battery_thresh_charge_nofl[] = {
-- { 200, 100, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 999, 100, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 210, 100, SHARPSL_BATTERY_STATUS_HIGH},
-+ { 200, 95, SHARPSL_BATTERY_STATUS_HIGH},
- { 196, 75, SHARPSL_BATTERY_STATUS_HIGH},
- { 192, 50, SHARPSL_BATTERY_STATUS_HIGH},
- { 187, 25, SHARPSL_BATTERY_STATUS_LOW},
-- { 171, 5, SHARPSL_BATTERY_STATUS_VERYLOW},
-+ { 182, 10, SHARPSL_BATTERY_STATUS_LOW},
-+ { 170, 5, SHARPSL_BATTERY_STATUS_VERYLOW},
- { 0, 0, SHARPSL_BATTERY_STATUS_CRITICAL},
- };
-
- #endif
-
-+//#if defined(CONFIG_ARCH_PXA_CORGI)
-+#define MAIN_BATTERY_THRES (sizeof(sharpsl_main_battery_thresh_charge_nofl) / sizeof(BATTERY_THRESH) - 1)
-+//#endif
-+
-+
- #if 1
- static struct file_operations sharpsl_battery_fops = {
- };
-@@ -389,6 +412,8 @@
- int sharpsl_main_battery = SHARPSL_BATTERY_STATUS_HIGH;
- int sharpsl_main_battery_percentage = 100;
- int sharpsl_main_charge_battery = 100;
-+int sharpsl_main_battery_voltage = 200;
-+
- int sharpsl_ac_status = APM_AC_OFFLINE;
-
- static int MainCntWk = SHARPSL_MAIN_GOOD_COUNT;
-@@ -498,7 +523,7 @@
- // 2 : check battery w/ refresh battery status.
- void sharpsl_kick_battery_check(int before_waitms,int after_waitms,int flag)
- {
-- int start;
-+ //int start;
-
-
- MainCntWk = MainCnt + 1;
-@@ -604,6 +629,7 @@
- }
- #endif
-
-+ return 0;
- }
-
-
-@@ -920,13 +946,17 @@
- #endif
-
- voltage = sharpsl_cnv_value(voltage);
--
-+ sharpsl_main_battery_voltage = voltage;
-+
- thresh = GetMainLevel(voltage);
-
-+ sharpsl_main_battery = thresh->status;
-+ sharpsl_main_battery_percentage = GetMainPercent(voltage);
-+ sharpsl_main_charge_battery = GetMainChargePercent(voltage);
-+
- // if battery is low , backlight driver become to save power.
- if ( ( ( thresh->status == SHARPSL_BATTERY_STATUS_VERYLOW ) ||
-- ( thresh->status == SHARPSL_BATTERY_STATUS_CRITICAL ) ||
-- ( thresh->status == SHARPSL_BATTERY_STATUS_LOW ) ) &&
-+ ( thresh->status == SHARPSL_BATTERY_STATUS_CRITICAL )) &&
- ( !sharpsl_main_bk_flag ) ) {
- SHARPSL_LIMIT_CONTRAST(SHARPSL_CAUTION_CONTRAST);
- }
-@@ -934,11 +964,7 @@
- if ( sharpsl_main_bk_flag == 0 ) {
- return sharpsl_main_battery;
- }
-- sharpsl_main_battery = thresh->status;
-- sharpsl_main_battery_percentage = thresh->percentage;
-- sharpsl_main_charge_battery = GetMainChargePercent(voltage);
--
-- //printk("bat : main battery = %d\n",sharpsl_main_battery);
-+
-
- if ( sharpsl_debug_flag != 0 ) {
- int i;
-@@ -946,7 +972,8 @@
- sharpsl_main_battery = sharpsl_debug_flag;
- for (i = 0; sharpsl_main_battery_thresh_nofl[i].voltage > 0; i++) {
- if ( sharpsl_debug_flag == sharpsl_main_battery_thresh_nofl[i].status ) {
-- sharpsl_main_battery_percentage = sharpsl_main_battery_thresh_nofl[i].percentage;
-+ //sharpsl_main_battery_percentage = sharpsl_main_battery_thresh_nofl[i].percentage;
-+ sharpsl_main_battery_percentage = GetMainPercent(voltage);
- break;
- }
- }
-@@ -965,7 +992,7 @@
- sharpsl_main_battery_percentage = sharpsl_main_percent_bk;
- }
-
-- DPRINTK2("charge percent = %d ( at %d ) \n",sharpsl_main_charge_battery,(int)jiffies);
-+ //DPRINTK2("charge percent = %d ( at %d ) \n",sharpsl_main_charge_battery,(int)jiffies);
- DPRINTK(" get Main battery status %d\n",sharpsl_main_battery);
-
- } else {
-@@ -975,40 +1002,79 @@
- return sharpsl_main_battery;
- }
-
--int GetMainChargePercent( int Volt )
-+int GetLevelIndex(BATTERY_THRESH *thresh, int Volt)
-+{
-+ int i = MAIN_BATTERY_THRES;
-+
-+ DPRINTK("volt = %d \n", Volt);
-+ while (i > 0 && (Volt > thresh[i].voltage))
-+ i--;
-+
-+ return i;
-+}
-+
-+int GetPercent(BATTERY_THRESH *thresh, int Volt)
-+{
-+ int i = GetLevelIndex(thresh, Volt);
-+
-+ /* i is now between 0 and MAIN_BATTERY_THRES. That means
-+ * we can safely access main_batt_thres[i] and
-+ * main_batt_thres[i+1] */
-+
-+ {
-+// long percentage = thresh[i].percentage;
-+
-+ long deltav = thresh[i].voltage - thresh[i + 1].voltage;
-+ long deltap = thresh[i].percentage - thresh[i + 1].percentage;
-+
-+ long percentage =
-+ thresh[i + 1].percentage +
-+ deltap * (Volt - thresh[i + 1].voltage) /
-+ deltav;
-+
-+ DPRINTK("percentage = %d \n", percentage);
-+ return percentage;
-+ }
-+
-+ return thresh[i].percentage;
-+}
-+
-+int GetMainPercent( int Volt )
- {
-- int i;
- BATTERY_THRESH *thresh;
-
-- DPRINTK(" volt = %d \n",Volt);
-+ if (counter_step_contrast)
-+ thresh = sharpsl_main_battery_thresh_fl;
-+ else
-+ thresh = sharpsl_main_battery_thresh_nofl;
-+
-+ return GetPercent(thresh, Volt);
-+}
-+
-+int GetMainChargePercent( int Volt )
-+{
-+ BATTERY_THRESH *thresh;
-
- if (counter_step_contrast)
-- thresh = sharpsl_main_battery_thresh_charge_fl;
-+ thresh = sharpsl_main_battery_thresh_charge_fl;
- else
-- thresh = sharpsl_main_battery_thresh_charge_nofl;
-- for (i = 0; thresh[i].voltage > 0; i++) {
-- if (Volt >= thresh[i].voltage)
-- return thresh[i].percentage;
-- }
-- return thresh[i].percentage;
-+ thresh = sharpsl_main_battery_thresh_charge_nofl;
-+
-+ return GetPercent(thresh, Volt);
- }
-
- BATTERY_THRESH *GetMainLevel( int Volt )
- {
-- int i;
- BATTERY_THRESH *thresh;
-
- DPRINTK(" volt = %d \n",Volt);
-
- if (counter_step_contrast)
-- thresh = sharpsl_main_battery_thresh_fl;
-+ thresh = sharpsl_main_battery_thresh_fl;
- else
-- thresh = sharpsl_main_battery_thresh_nofl;
-- for (i = 0; thresh[i].voltage > 0; i++) {
-- if (Volt >= thresh[i].voltage)
-- return &thresh[i];
-- }
-- return &thresh[i];
-+ thresh = sharpsl_main_battery_thresh_nofl;
-+
-+ return &thresh[GetLevelIndex(thresh, Volt)];
- }
-
-
-@@ -1018,7 +1084,7 @@
- int Get_DAC_Value(int channel)
- {
- unsigned long cmd;
-- unsigned int dummy;
-+ unsigned int dummy;
- int voltage;
-
- #if defined(CONFIG_ARCH_PXA_POODLE)
-@@ -1263,7 +1329,7 @@
- // 0: OK
- int sharpsl_ac_check(void)
- {
-- int temp, i, volt;
-+ int temp, i; //, volt;
- int buff[5];
-
- if ( in_interrupt() ) {
-@@ -1835,14 +1901,18 @@
- int def_value;
- char* name;
- char* description;
-+ char readonly;
- unsigned short low_ino;
- } sharpsl_battery_entry_t;
-
- static sharpsl_battery_entry_t sharpsl_battery_params[] = {
- /* { addr, def_value, name, description }*/
-- { &msglevel, 0, "msglevel", "debug message output level" },
-- { &sharpsl_debug_flag , 0 , "dflag", "debug flag" },
-- { &sharpsl_change_battery_status , 0 , "chg_status", "Change status" }
-+ { &msglevel, 0, "msglevel", "debug message output level", 0 },
-+ { &sharpsl_debug_flag , 0 , "dflag", "debug flag", 0 },
-+ { &sharpsl_change_battery_status , 0 , "chg_status", "Change status", 1 },
-+ { &sharpsl_main_battery_percentage , 0 , "charge_percentage", "Charge percentage", 1 },
-+ { &sharpsl_main_battery_voltage , 0 , "main_voltage", "Main voltage", 1 }, // alias
-+ { &sharpsl_main_battery_voltage , 0 , "charge_voltage", "Charge voltage", 1 }
- };
- #define NUM_OF_BATTERY_ENTRY (sizeof(sharpsl_battery_params)/sizeof(sharpsl_battery_entry_t))
-
-@@ -1866,7 +1936,7 @@
- if (current_param==NULL) {
- return -EINVAL;
- }
-- count = sprintf(outputbuf, "0x%08X\n",
-+ count = sprintf(outputbuf, "%04i\n",
- *((volatile Word *) current_param->addr));
- *ppos += count;
- if (count>nbytes) /* Assume output can be read at one time */
-@@ -1891,7 +1961,7 @@
- break;
- }
- }
-- if (current_param==NULL) {
-+ if (current_param==NULL || current_param->readonly) {
- return -EINVAL;
- }
-
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/smallfonts.diff b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/smallfonts.diff
deleted file mode 100644
index bcf3734f63..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/smallfonts.diff
+++ /dev/null
@@ -1,2453 +0,0 @@
-diff -Nur linux-2.4.1-pre12/drivers/video/font_4x6.c linux-2.4.1-pre12.smallfonts/drivers/video/font_4x6.c
---- linux-2.4.1-pre12/drivers/video/font_4x6.c Wed Dec 31 17:00:00 1969
-+++ linux-2.4.1-pre12.smallfonts/drivers/video/font_4x6.c Tue Jan 30 14:17:15 2001
-@@ -0,0 +1,1059 @@
-+/* Font file generated by Jay Carlson from clR4x6.bdf */
-+
-+/*
-+COMMENT Copyright 1989 Dale Schumacher, dal@syntel.mn.org
-+COMMENT 399 Beacon Ave.
-+COMMENT St. Paul, MN 55104-3527
-+COMMENT
-+COMMENT Permission to use, copy, modify, and distribute this software and
-+COMMENT its documentation for any purpose and without fee is hereby
-+COMMENT granted, provided that the above copyright notice appear in all
-+COMMENT copies and that both that copyright notice and this permission
-+COMMENT notice appear in supporting documentation, and that the name of
-+COMMENT Dale Schumacher not be used in advertising or publicity pertaining to
-+COMMENT distribution of the software without specific, written prior
-+COMMENT permission. Dale Schumacher makes no representations about the
-+COMMENT suitability of this software for any purpose. It is provided "as
-+COMMENT is" without express or implied warranty.
-+*/
-+
-+#include <video/font.h>
-+
-+#define FONTDATAMAX (6 * 256)
-+
-+static unsigned char fontdata_4x6[FONTDATAMAX] = {
-+
-+ /* 0 0x00 C000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0xf0, /* 11110000 */
-+
-+ /* 1 0x01 C001 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 2 0x02 C002 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 3 0x03 C003 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 4 0x04 C004 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 5 0x05 C005 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 6 0x06 C006 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 7 0x07 C007 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 8 0x08 C010 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 9 0x09 C011 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 10 0x0a C012 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 11 0x0b C013 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 12 0x0c C014 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 13 0x0d C015 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 14 0x0e C016 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 15 0x0f C017 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 16 0x10 C020 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 17 0x11 C021 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 18 0x12 C022 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 19 0x13 C023 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 20 0x14 C024 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 21 0x15 C025 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 22 0x16 C026 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 23 0x17 C027 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 24 0x18 C030 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 25 0x19 C031 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 26 0x1a C032 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 27 0x1b C033 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 28 0x1c C034 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 29 0x1d C035 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 30 0x1e C036 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 31 0x1f C037 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 32 0x20 C040 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 33 0x21 ! */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 34 0x22 " */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 35 0x23 # */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 36 0x24 $ */
-+ 0xe0, /* 11100000 */
-+ 0xc0, /* 11000000 */
-+ 0xe0, /* 11100000 */
-+ 0x60, /* 01100000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 37 0x25 % */
-+ 0xa0, /* 10100000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x80, /* 10000000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 38 0x26 & */
-+ 0xe0, /* 11100000 */
-+ 0x40, /* 01000000 */
-+ 0xe0, /* 11100000 */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 39 0x27 ' */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 40 0x28 ( */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 41 0x29 ) */
-+ 0x40, /* 01000000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 42 0x2a * */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0xe0, /* 11100000 */
-+ 0x40, /* 01000000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 43 0x2b + */
-+ 0x00, /* 00000000 */
-+ 0x40, /* 01000000 */
-+ 0xe0, /* 11100000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 44 0x2c , */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 45 0x2d - */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 46 0x2e . */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 47 0x2f / */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x80, /* 10000000 */
-+ 0x80, /* 10000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 48 0x30 0 */
-+ 0xe0, /* 11100000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 49 0x31 1 */
-+ 0x40, /* 01000000 */
-+ 0xc0, /* 11000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 50 0x32 2 */
-+ 0xe0, /* 11100000 */
-+ 0x20, /* 00100000 */
-+ 0xe0, /* 11100000 */
-+ 0x80, /* 10000000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 51 0x33 3 */
-+ 0xe0, /* 11100000 */
-+ 0x20, /* 00100000 */
-+ 0xe0, /* 11100000 */
-+ 0x20, /* 00100000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 52 0x34 4 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 53 0x35 5 */
-+ 0xe0, /* 11100000 */
-+ 0x80, /* 10000000 */
-+ 0xe0, /* 11100000 */
-+ 0x20, /* 00100000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 54 0x36 6 */
-+ 0xe0, /* 11100000 */
-+ 0x80, /* 10000000 */
-+ 0xe0, /* 11100000 */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 55 0x37 7 */
-+ 0xe0, /* 11100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 56 0x38 8 */
-+ 0xe0, /* 11100000 */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 57 0x39 9 */
-+ 0xe0, /* 11100000 */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0x20, /* 00100000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 58 0x3a : */
-+ 0x00, /* 00000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 59 0x3b ; */
-+ 0x00, /* 00000000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 60 0x3c < */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x80, /* 10000000 */
-+ 0x40, /* 01000000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 61 0x3d = */
-+ 0x00, /* 00000000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 62 0x3e > */
-+ 0x80, /* 10000000 */
-+ 0x40, /* 01000000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x80, /* 10000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 63 0x3f ? */
-+ 0xc0, /* 11000000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 64 0x40 @ */
-+ 0xe0, /* 11100000 */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0x80, /* 10000000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 65 0x41 A */
-+ 0x40, /* 01000000 */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 66 0x42 B */
-+ 0xc0, /* 11000000 */
-+ 0xa0, /* 10100000 */
-+ 0xc0, /* 11000000 */
-+ 0xa0, /* 10100000 */
-+ 0xc0, /* 11000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 67 0x43 C */
-+ 0x60, /* 01100000 */
-+ 0x80, /* 10000000 */
-+ 0x80, /* 10000000 */
-+ 0x80, /* 10000000 */
-+ 0x60, /* 01100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 68 0x44 D */
-+ 0xc0, /* 11000000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xc0, /* 11000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 69 0x45 E */
-+ 0xe0, /* 11100000 */
-+ 0x80, /* 10000000 */
-+ 0xc0, /* 11000000 */
-+ 0x80, /* 10000000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 70 0x46 F */
-+ 0xe0, /* 11100000 */
-+ 0x80, /* 10000000 */
-+ 0xc0, /* 11000000 */
-+ 0x80, /* 10000000 */
-+ 0x80, /* 10000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 71 0x47 G */
-+ 0x60, /* 01100000 */
-+ 0x80, /* 10000000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x60, /* 01100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 72 0x48 H */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 73 0x49 I */
-+ 0xe0, /* 11100000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 74 0x4a J */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0xa0, /* 10100000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 75 0x4b K */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xc0, /* 11000000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 76 0x4c L */
-+ 0x80, /* 10000000 */
-+ 0x80, /* 10000000 */
-+ 0x80, /* 10000000 */
-+ 0x80, /* 10000000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 77 0x4d M */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0xe0, /* 11100000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 78 0x4e N */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0xe0, /* 11100000 */
-+ 0xe0, /* 11100000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 79 0x4f O */
-+ 0x40, /* 01000000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 80 0x50 P */
-+ 0xc0, /* 11000000 */
-+ 0xa0, /* 10100000 */
-+ 0xc0, /* 11000000 */
-+ 0x80, /* 10000000 */
-+ 0x80, /* 10000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 81 0x51 Q */
-+ 0x40, /* 01000000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xc0, /* 11000000 */
-+ 0x60, /* 01100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 82 0x52 R */
-+ 0xc0, /* 11000000 */
-+ 0xa0, /* 10100000 */
-+ 0xc0, /* 11000000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 83 0x53 S */
-+ 0x60, /* 01100000 */
-+ 0x80, /* 10000000 */
-+ 0x40, /* 01000000 */
-+ 0x20, /* 00100000 */
-+ 0xc0, /* 11000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 84 0x54 T */
-+ 0xe0, /* 11100000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 85 0x55 U */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 86 0x56 V */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 87 0x57 W */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0xe0, /* 11100000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 88 0x58 X */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x40, /* 01000000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 89 0x59 Y */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 90 0x5a Z */
-+ 0xe0, /* 11100000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x80, /* 10000000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 91 0x5b [ */
-+ 0x60, /* 01100000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x60, /* 01100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 92 0x5c \ */
-+ 0x80, /* 10000000 */
-+ 0x80, /* 10000000 */
-+ 0x40, /* 01000000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 93 0x5d ] */
-+ 0x60, /* 01100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x60, /* 01100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 94 0x5e ^ */
-+ 0x40, /* 01000000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 95 0x5f _ */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 96 0x60 ` */
-+ 0x40, /* 01000000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 97 0x61 a */
-+ 0x00, /* 00000000 */
-+ 0x40, /* 01000000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x60, /* 01100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 98 0x62 b */
-+ 0x80, /* 10000000 */
-+ 0xc0, /* 11000000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xc0, /* 11000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 99 0x63 c */
-+ 0x00, /* 00000000 */
-+ 0x60, /* 01100000 */
-+ 0x80, /* 10000000 */
-+ 0x80, /* 10000000 */
-+ 0x60, /* 01100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 100 0x64 d */
-+ 0x20, /* 00100000 */
-+ 0x60, /* 01100000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x60, /* 01100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 101 0x65 e */
-+ 0x00, /* 00000000 */
-+ 0x60, /* 01100000 */
-+ 0xe0, /* 11100000 */
-+ 0x80, /* 10000000 */
-+ 0x60, /* 01100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 102 0x66 f */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0xe0, /* 11100000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 103 0x67 g */
-+ 0x00, /* 00000000 */
-+ 0x60, /* 01100000 */
-+ 0xa0, /* 10100000 */
-+ 0x60, /* 01100000 */
-+ 0x20, /* 00100000 */
-+ 0xc0, /* 11000000 */
-+
-+ /* 104 0x68 h */
-+ 0x80, /* 10000000 */
-+ 0xc0, /* 11000000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 105 0x69 i */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 106 0x6a j */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0xa0, /* 10100000 */
-+ 0x40, /* 01000000 */
-+
-+ /* 107 0x6b k */
-+ 0x80, /* 10000000 */
-+ 0xa0, /* 10100000 */
-+ 0xc0, /* 11000000 */
-+ 0xc0, /* 11000000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 108 0x6c l */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 109 0x6d m */
-+ 0x00, /* 00000000 */
-+ 0xe0, /* 11100000 */
-+ 0xe0, /* 11100000 */
-+ 0xe0, /* 11100000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 110 0x6e n */
-+ 0x00, /* 00000000 */
-+ 0xc0, /* 11000000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 111 0x6f o */
-+ 0x00, /* 00000000 */
-+ 0x40, /* 01000000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 112 0x70 p */
-+ 0x00, /* 00000000 */
-+ 0xc0, /* 11000000 */
-+ 0xa0, /* 10100000 */
-+ 0xc0, /* 11000000 */
-+ 0x80, /* 10000000 */
-+ 0x80, /* 10000000 */
-+
-+ /* 113 0x71 q */
-+ 0x00, /* 00000000 */
-+ 0x60, /* 01100000 */
-+ 0xa0, /* 10100000 */
-+ 0x60, /* 01100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+
-+ /* 114 0x72 r */
-+ 0x00, /* 00000000 */
-+ 0xc0, /* 11000000 */
-+ 0xa0, /* 10100000 */
-+ 0x80, /* 10000000 */
-+ 0x80, /* 10000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 115 0x73 s */
-+ 0x00, /* 00000000 */
-+ 0x60, /* 01100000 */
-+ 0xc0, /* 11000000 */
-+ 0x60, /* 01100000 */
-+ 0xc0, /* 11000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 116 0x74 t */
-+ 0x40, /* 01000000 */
-+ 0xe0, /* 11100000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 117 0x75 u */
-+ 0x00, /* 00000000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 118 0x76 v */
-+ 0x00, /* 00000000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 119 0x77 w */
-+ 0x00, /* 00000000 */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0xe0, /* 11100000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 120 0x78 x */
-+ 0x00, /* 00000000 */
-+ 0xa0, /* 10100000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0xa0, /* 10100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 121 0x79 y */
-+ 0x00, /* 00000000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0x60, /* 01100000 */
-+ 0x20, /* 00100000 */
-+ 0xc0, /* 11000000 */
-+
-+ /* 122 0x7a z */
-+ 0x00, /* 00000000 */
-+ 0xe0, /* 11100000 */
-+ 0x60, /* 01100000 */
-+ 0xc0, /* 11000000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 123 0x7b { */
-+ 0x60, /* 01100000 */
-+ 0x40, /* 01000000 */
-+ 0xc0, /* 11000000 */
-+ 0x40, /* 01000000 */
-+ 0x60, /* 01100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 124 0x7c | */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 125 0x7d } */
-+ 0xc0, /* 11000000 */
-+ 0x40, /* 01000000 */
-+ 0x60, /* 01100000 */
-+ 0x40, /* 01000000 */
-+ 0xc0, /* 11000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 126 0x7e ~ */
-+ 0x20, /* 00100000 */
-+ 0xe0, /* 11100000 */
-+ 0x80, /* 10000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 127 0x7f C177 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0xa0, /* 10100000 */
-+ 0xa0, /* 10100000 */
-+ 0xe0, /* 11100000 */
-+ 0x00, /* 00000000 */
-+
-+};
-+
-+struct fbcon_font_desc font_clean_4x6 = {
-+ CLEAN4x6_IDX,
-+ "Clean4x6",
-+ 4,
-+ 6,
-+ fontdata_4x6,
-+ -1000 /* Try avoiding this font if possible unless screen really small */
-+};
-diff -Nur linux-2.4.1-pre12/drivers/video/font_5x8.c linux-2.4.1-pre12.smallfonts/drivers/video/font_5x8.c
---- linux-2.4.1-pre12/drivers/video/font_5x8.c Wed Dec 31 17:00:00 1969
-+++ linux-2.4.1-pre12.smallfonts/drivers/video/font_5x8.c Tue Jan 30 14:17:16 2001
-@@ -0,0 +1,1314 @@
-+/* Font file generated by Jay Carlson from clR5x8.bdf */
-+
-+/*
-+COMMENT Copyright 1989 Dale Schumacher, dal@syntel.mn.org
-+COMMENT 399 Beacon Ave.
-+COMMENT St. Paul, MN 55104-3527
-+COMMENT
-+COMMENT Permission to use, copy, modify, and distribute this software and
-+COMMENT its documentation for any purpose and without fee is hereby
-+COMMENT granted, provided that the above copyright notice appear in all
-+COMMENT copies and that both that copyright notice and this permission
-+COMMENT notice appear in supporting documentation, and that the name of
-+COMMENT Dale Schumacher not be used in advertising or publicity pertaining to
-+COMMENT distribution of the software without specific, written prior
-+COMMENT permission. Dale Schumacher makes no representations about the
-+COMMENT suitability of this software for any purpose. It is provided "as
-+COMMENT is" without express or implied warranty.
-+*/
-+
-+#include <video/font.h>
-+
-+#define FONTDATAMAX (8 * 256)
-+
-+static unsigned char fontdata_5x8[FONTDATAMAX] = {
-+
-+ /* 0 0x00 C000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 1 0x01 C001 */
-+ 0x00, /* 00000000 */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x78, /* 01111000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 2 0x02 C002 */
-+ 0x00, /* 00000000 */
-+ 0x70, /* 01110000 */
-+ 0x48, /* 01001000 */
-+ 0x70, /* 01110000 */
-+ 0x48, /* 01001000 */
-+ 0x70, /* 01110000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 3 0x03 C003 */
-+ 0x00, /* 00000000 */
-+ 0x38, /* 00111000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x38, /* 00111000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 4 0x04 C004 */
-+ 0x00, /* 00000000 */
-+ 0x70, /* 01110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x70, /* 01110000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 5 0x05 C005 */
-+ 0x00, /* 00000000 */
-+ 0x78, /* 01111000 */
-+ 0x40, /* 01000000 */
-+ 0x70, /* 01110000 */
-+ 0x40, /* 01000000 */
-+ 0x78, /* 01111000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 6 0x06 C006 */
-+ 0x00, /* 00000000 */
-+ 0x78, /* 01111000 */
-+ 0x40, /* 01000000 */
-+ 0x70, /* 01110000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 7 0x07 C007 */
-+ 0x00, /* 00000000 */
-+ 0x38, /* 00111000 */
-+ 0x40, /* 01000000 */
-+ 0x58, /* 01011000 */
-+ 0x48, /* 01001000 */
-+ 0x38, /* 00111000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 8 0x08 C010 */
-+ 0x00, /* 00000000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x78, /* 01111000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 9 0x09 C011 */
-+ 0x00, /* 00000000 */
-+ 0x70, /* 01110000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x70, /* 01110000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 10 0x0a C012 */
-+ 0x00, /* 00000000 */
-+ 0x18, /* 00011000 */
-+ 0x08, /* 00001000 */
-+ 0x08, /* 00001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 11 0x0b C013 */
-+ 0x00, /* 00000000 */
-+ 0x48, /* 01001000 */
-+ 0x50, /* 01010000 */
-+ 0x60, /* 01100000 */
-+ 0x50, /* 01010000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 12 0x0c C014 */
-+ 0x00, /* 00000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x78, /* 01111000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 13 0x0d C015 */
-+ 0x00, /* 00000000 */
-+ 0x48, /* 01001000 */
-+ 0x78, /* 01111000 */
-+ 0x78, /* 01111000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 14 0x0e C016 */
-+ 0x00, /* 00000000 */
-+ 0x48, /* 01001000 */
-+ 0x68, /* 01101000 */
-+ 0x58, /* 01011000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 15 0x0f C017 */
-+ 0x00, /* 00000000 */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 16 0x10 C020 */
-+ 0x00, /* 00000000 */
-+ 0x70, /* 01110000 */
-+ 0x48, /* 01001000 */
-+ 0x70, /* 01110000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 17 0x11 C021 */
-+ 0x00, /* 00000000 */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x18, /* 00011000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 18 0x12 C022 */
-+ 0x00, /* 00000000 */
-+ 0x70, /* 01110000 */
-+ 0x48, /* 01001000 */
-+ 0x70, /* 01110000 */
-+ 0x50, /* 01010000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 19 0x13 C023 */
-+ 0x00, /* 00000000 */
-+ 0x38, /* 00111000 */
-+ 0x40, /* 01000000 */
-+ 0x30, /* 00110000 */
-+ 0x08, /* 00001000 */
-+ 0x70, /* 01110000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 20 0x14 C024 */
-+ 0x00, /* 00000000 */
-+ 0xf8, /* 11111000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 21 0x15 C025 */
-+ 0x00, /* 00000000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 22 0x16 C026 */
-+ 0x00, /* 00000000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 23 0x17 C027 */
-+ 0x00, /* 00000000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x78, /* 01111000 */
-+ 0x78, /* 01111000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 24 0x18 C030 */
-+ 0x00, /* 00000000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 25 0x19 C031 */
-+ 0x00, /* 00000000 */
-+ 0x88, /* 10001000 */
-+ 0x50, /* 01010000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 26 0x1a C032 */
-+ 0x00, /* 00000000 */
-+ 0x78, /* 01111000 */
-+ 0x10, /* 00010000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x78, /* 01111000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 27 0x1b C033 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 28 0x1c C034 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 29 0x1d C035 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 30 0x1e C036 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 31 0x1f C037 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 32 0x20 C040 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 33 0x21 ! */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 34 0x22 " */
-+ 0x28, /* 00101000 */
-+ 0x28, /* 00101000 */
-+ 0x28, /* 00101000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 35 0x23 # */
-+ 0x50, /* 01010000 */
-+ 0x50, /* 01010000 */
-+ 0xf8, /* 11111000 */
-+ 0x50, /* 01010000 */
-+ 0xf8, /* 11111000 */
-+ 0x50, /* 01010000 */
-+ 0x50, /* 01010000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 36 0x24 $ */
-+ 0x20, /* 00100000 */
-+ 0x78, /* 01111000 */
-+ 0xa0, /* 10100000 */
-+ 0x70, /* 01110000 */
-+ 0x28, /* 00101000 */
-+ 0xf0, /* 11110000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 37 0x25 % */
-+ 0x60, /* 01100000 */
-+ 0x68, /* 01101000 */
-+ 0x10, /* 00010000 */
-+ 0x20, /* 00100000 */
-+ 0x58, /* 01011000 */
-+ 0x18, /* 00011000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 38 0x26 & */
-+ 0x30, /* 00110000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x28, /* 00101000 */
-+ 0x50, /* 01010000 */
-+ 0x50, /* 01010000 */
-+ 0x28, /* 00101000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 39 0x27 ' */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 40 0x28 ( */
-+ 0x08, /* 00001000 */
-+ 0x10, /* 00010000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x10, /* 00010000 */
-+ 0x08, /* 00001000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 41 0x29 ) */
-+ 0x40, /* 01000000 */
-+ 0x20, /* 00100000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 42 0x2a * */
-+ 0x00, /* 00000000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x78, /* 01111000 */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 43 0x2b + */
-+ 0x00, /* 00000000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0xf8, /* 11111000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 44 0x2c , */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+
-+ /* 45 0x2d - */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0xf8, /* 11111000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 46 0x2e . */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 47 0x2f / */
-+ 0x08, /* 00001000 */
-+ 0x08, /* 00001000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+
-+ /* 48 0x30 0 */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x58, /* 01011000 */
-+ 0x68, /* 01101000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 49 0x31 1 */
-+ 0x20, /* 00100000 */
-+ 0x60, /* 01100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 50 0x32 2 */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x08, /* 00001000 */
-+ 0x10, /* 00010000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x78, /* 01111000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 51 0x33 3 */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x08, /* 00001000 */
-+ 0x30, /* 00110000 */
-+ 0x08, /* 00001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 52 0x34 4 */
-+ 0x08, /* 00001000 */
-+ 0x18, /* 00011000 */
-+ 0x18, /* 00011000 */
-+ 0x28, /* 00101000 */
-+ 0x28, /* 00101000 */
-+ 0x78, /* 01111000 */
-+ 0x08, /* 00001000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 53 0x35 5 */
-+ 0x78, /* 01111000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x70, /* 01110000 */
-+ 0x08, /* 00001000 */
-+ 0x08, /* 00001000 */
-+ 0x70, /* 01110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 54 0x36 6 */
-+ 0x30, /* 00110000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x70, /* 01110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 55 0x37 7 */
-+ 0x78, /* 01111000 */
-+ 0x08, /* 00001000 */
-+ 0x08, /* 00001000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 56 0x38 8 */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 57 0x39 9 */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x38, /* 00111000 */
-+ 0x08, /* 00001000 */
-+ 0x08, /* 00001000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 58 0x3a : */
-+ 0x00, /* 00000000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 59 0x3b ; */
-+ 0x00, /* 00000000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+
-+ /* 60 0x3c < */
-+ 0x08, /* 00001000 */
-+ 0x10, /* 00010000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x20, /* 00100000 */
-+ 0x10, /* 00010000 */
-+ 0x08, /* 00001000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 61 0x3d = */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0xf8, /* 11111000 */
-+ 0x00, /* 00000000 */
-+ 0xf8, /* 11111000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 62 0x3e > */
-+ 0x40, /* 01000000 */
-+ 0x20, /* 00100000 */
-+ 0x10, /* 00010000 */
-+ 0x08, /* 00001000 */
-+ 0x10, /* 00010000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 63 0x3f ? */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x08, /* 00001000 */
-+ 0x10, /* 00010000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 64 0x40 @ */
-+ 0x00, /* 00000000 */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x58, /* 01011000 */
-+ 0x58, /* 01011000 */
-+ 0x40, /* 01000000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 65 0x41 A */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x78, /* 01111000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 66 0x42 B */
-+ 0x70, /* 01110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x70, /* 01110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x70, /* 01110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 67 0x43 C */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 68 0x44 D */
-+ 0x70, /* 01110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x70, /* 01110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 69 0x45 E */
-+ 0x78, /* 01111000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x70, /* 01110000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x78, /* 01111000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 70 0x46 F */
-+ 0x78, /* 01111000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x70, /* 01110000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 71 0x47 G */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x40, /* 01000000 */
-+ 0x58, /* 01011000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x38, /* 00111000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 72 0x48 H */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x78, /* 01111000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 73 0x49 I */
-+ 0x70, /* 01110000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x70, /* 01110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 74 0x4a J */
-+ 0x18, /* 00011000 */
-+ 0x08, /* 00001000 */
-+ 0x08, /* 00001000 */
-+ 0x08, /* 00001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 75 0x4b K */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x50, /* 01010000 */
-+ 0x60, /* 01100000 */
-+ 0x50, /* 01010000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 76 0x4c L */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x78, /* 01111000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 77 0x4d M */
-+ 0x48, /* 01001000 */
-+ 0x78, /* 01111000 */
-+ 0x78, /* 01111000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 78 0x4e N */
-+ 0x48, /* 01001000 */
-+ 0x68, /* 01101000 */
-+ 0x68, /* 01101000 */
-+ 0x58, /* 01011000 */
-+ 0x58, /* 01011000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 79 0x4f O */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 80 0x50 P */
-+ 0x70, /* 01110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x70, /* 01110000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 81 0x51 Q */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x18, /* 00011000 */
-+
-+ /* 82 0x52 R */
-+ 0x70, /* 01110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x70, /* 01110000 */
-+ 0x50, /* 01010000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 83 0x53 S */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x40, /* 01000000 */
-+ 0x30, /* 00110000 */
-+ 0x08, /* 00001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 84 0x54 T */
-+ 0xf8, /* 11111000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 85 0x55 U */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 86 0x56 V */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x30, /* 00110000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 87 0x57 W */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x78, /* 01111000 */
-+ 0x78, /* 01111000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 88 0x58 X */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 89 0x59 Y */
-+ 0x88, /* 10001000 */
-+ 0x88, /* 10001000 */
-+ 0x50, /* 01010000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 90 0x5a Z */
-+ 0x78, /* 01111000 */
-+ 0x08, /* 00001000 */
-+ 0x10, /* 00010000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x78, /* 01111000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 91 0x5b [ */
-+ 0x38, /* 00111000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x38, /* 00111000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 92 0x5c \ */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x08, /* 00001000 */
-+ 0x08, /* 00001000 */
-+
-+ /* 93 0x5d ] */
-+ 0x70, /* 01110000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x70, /* 01110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 94 0x5e ^ */
-+ 0x20, /* 00100000 */
-+ 0x50, /* 01010000 */
-+ 0x88, /* 10001000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 95 0x5f _ */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0xf8, /* 11111000 */
-+
-+ /* 96 0x60 ` */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x10, /* 00010000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 97 0x61 a */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x38, /* 00111000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x58, /* 01011000 */
-+ 0x28, /* 00101000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 98 0x62 b */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x70, /* 01110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x70, /* 01110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 99 0x63 c */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x38, /* 00111000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x38, /* 00111000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 100 0x64 d */
-+ 0x08, /* 00001000 */
-+ 0x08, /* 00001000 */
-+ 0x38, /* 00111000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x38, /* 00111000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 101 0x65 e */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x78, /* 01111000 */
-+ 0x40, /* 01000000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 102 0x66 f */
-+ 0x18, /* 00011000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x70, /* 01110000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 103 0x67 g */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x38, /* 00111000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x38, /* 00111000 */
-+ 0x08, /* 00001000 */
-+ 0x30, /* 00110000 */
-+
-+ /* 104 0x68 h */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x70, /* 01110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 105 0x69 i */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+ 0x60, /* 01100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x70, /* 01110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 106 0x6a j */
-+ 0x10, /* 00010000 */
-+ 0x00, /* 00000000 */
-+ 0x30, /* 00110000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x60, /* 01100000 */
-+
-+ /* 107 0x6b k */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x48, /* 01001000 */
-+ 0x50, /* 01010000 */
-+ 0x60, /* 01100000 */
-+ 0x50, /* 01010000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 108 0x6c l */
-+ 0x60, /* 01100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x70, /* 01110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 109 0x6d m */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0xd0, /* 11010000 */
-+ 0xa8, /* 10101000 */
-+ 0xa8, /* 10101000 */
-+ 0xa8, /* 10101000 */
-+ 0x88, /* 10001000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 110 0x6e n */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x70, /* 01110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 111 0x6f o */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 112 0x70 p */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x70, /* 01110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x70, /* 01110000 */
-+ 0x40, /* 01000000 */
-+
-+ /* 113 0x71 q */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x38, /* 00111000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x38, /* 00111000 */
-+ 0x08, /* 00001000 */
-+
-+ /* 114 0x72 r */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x58, /* 01011000 */
-+ 0x60, /* 01100000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 115 0x73 s */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x38, /* 00111000 */
-+ 0x40, /* 01000000 */
-+ 0x30, /* 00110000 */
-+ 0x08, /* 00001000 */
-+ 0x70, /* 01110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 116 0x74 t */
-+ 0x00, /* 00000000 */
-+ 0x20, /* 00100000 */
-+ 0x78, /* 01111000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x18, /* 00011000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 117 0x75 u */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x38, /* 00111000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 118 0x76 v */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x30, /* 00110000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 119 0x77 w */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x88, /* 10001000 */
-+ 0xa8, /* 10101000 */
-+ 0xa8, /* 10101000 */
-+ 0xa8, /* 10101000 */
-+ 0x50, /* 01010000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 120 0x78 x */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x30, /* 00110000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 121 0x79 y */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x48, /* 01001000 */
-+ 0x38, /* 00111000 */
-+ 0x08, /* 00001000 */
-+ 0x30, /* 00110000 */
-+
-+ /* 122 0x7a z */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x78, /* 01111000 */
-+ 0x10, /* 00010000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x78, /* 01111000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 123 0x7b { */
-+ 0x08, /* 00001000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x20, /* 00100000 */
-+ 0x10, /* 00010000 */
-+ 0x10, /* 00010000 */
-+ 0x08, /* 00001000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 124 0x7c | */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 125 0x7d } */
-+ 0x40, /* 01000000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x10, /* 00010000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x40, /* 01000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 126 0x7e ~ */
-+ 0x28, /* 00101000 */
-+ 0x50, /* 01010000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+ 0x00, /* 00000000 */
-+
-+ /* 127 0x7f C177 */
-+ 0x00, /* 00000000 */
-+ 0x20, /* 00100000 */
-+ 0x20, /* 00100000 */
-+ 0x50, /* 01010000 */
-+ 0x50, /* 01010000 */
-+ 0x88, /* 10001000 */
-+ 0xf8, /* 11111000 */
-+ 0x00, /* 00000000 */
-+};
-+
-+struct fbcon_font_desc font_clean_5x8 = {
-+ CLEAN5x8_IDX,
-+ "Clean5x8",
-+ 5,
-+ 8,
-+ fontdata_5x8,
-+ -1000 /* Try avoiding this font if possible unless screen really small */
-+};
---- Makefile.~1~ 2002-02-26 05:38:07 +10:00
-+++ linux/drivers/video/Makefile 2004-08-31 18:04:15 +10:00
-@@ -33,6 +33,8 @@
- obj-$(CONFIG_FONT_6x11) += font_6x11.o
- obj-$(CONFIG_FONT_PEARL_8x8) += font_pearl_8x8.o
- obj-$(CONFIG_FONT_ACORN_8x8) += font_acorn_8x8.o
-+obj-$(CONFIG_FONT_5x8) += font_5x8.o
-+obj-$(CONFIG_FONT_4x6) += font_4x6.o
-
- # Add fbmon.o back into obj-$(CONFIG_FB) in 2.5.x
- obj-$(CONFIG_FB) += fbmem.o fbcmap.o modedb.o fbcon.o fonts.o
---- Config.in.~1~ 2002-02-26 05:38:07 +10:00
-+++ linux/drivers/video/Config.in 2004-08-31 18:03:46 +10:00
-@@ -424,6 +424,8 @@
- bool ' VGA 8x16 font' CONFIG_FONT_8x16
- if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then
- bool ' Mac console 6x11 font (not supported by all drivers)' CONFIG_FONT_6x11
-+ bool ' X11 Clean 5x8 font (not supported by all drivers)' CONFIG_FONT_5x8
-+ bool ' X11 Clean 4x6 font (not supported by all drivers)' CONFIG_FONT_4x6
- fi
- bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8
- bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8
-@@ -437,6 +439,8 @@
- if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then
- bool ' Sparc console 12x22 font (not supported by all drivers)' CONFIG_FONT_SUN12x22
- bool ' Mac console 6x11 font (not supported by all drivers)' CONFIG_FONT_6x11
-+ bool ' X11 Clean 5x8 font (not supported by all drivers)' CONFIG_FONT_5x8
-+ bool ' X11 Clean 4x6 font (not supported by all drivers)' CONFIG_FONT_4x6
- fi
- bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8
- bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8
---- fonts.c.~1~ 2001-03-03 12:38:39 +10:00
-+++ linux/drivers/video/fonts.c 2004-08-31 18:08:22 +10:00
-@@ -56,6 +56,16 @@
- #undef NO_FONTS
- &font_pearl_8x8,
- #endif
-+#ifdef CONFIG_FONT_5x8
-+#if defined(CONFIG_FBCON_MAC) /* XXX fixme, need better test */
-+#undef NO_FONTS
-+#endif
-+ &font_clean_5x8,
-+#endif
-+#ifdef CONFIG_FONT_4x6
-+#undef NO_FONTS
-+ &font_clean_4x6,
-+#endif
- };
-
- #define num_fonts (sizeof(fbcon_fonts)/sizeof(*fbcon_fonts))
---- font.h.~1~ 1999-01-20 04:47:48 +10:00
-+++ linux/include/video/font.h 2004-08-31 18:10:39 +10:00
-@@ -28,6 +28,8 @@
- #define SUN8x16_IDX 4
- #define SUN12x22_IDX 5
- #define ACORN8x8_IDX 6
-+#define CLEAN5x8_IDX 7
-+#define CLEAN4x6_IDX 8
-
- extern struct fbcon_font_desc font_vga_8x8,
- font_vga_8x16,
-@@ -35,7 +37,9 @@
- font_vga_6x11,
- font_sun_8x16,
- font_sun_12x22,
-- font_acorn_8x8;
-+ font_acorn_8x8,
-+ font_clean_5x8,
-+ font_clean_4x6;
-
- /* Find a font with a specific name */
-
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/swap-performance.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/swap-performance.patch
deleted file mode 100644
index 1cde717bb4..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/swap-performance.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-*** ../linux/mm/swap.c Tue Jan 14 14:54:41 2003
---- linux/mm/swap.c Sun Sep 28 21:34:25 2003
-***************
-*** 32,38 ****
- int page_cluster;
-
- pager_daemon_t pager_daemon = {
-! 512, /* base number for calculating the number of tries */
- SWAP_CLUSTER_MAX, /* minimum number of tries */
- 8, /* do swap I/O in clusters of this size */
- };
---- 32,38 ----
- int page_cluster;
-
- pager_daemon_t pager_daemon = {
-! 128, /* base number for calculating the number of tries */
- SWAP_CLUSTER_MAX, /* minimum number of tries */
- 8, /* do swap I/O in clusters of this size */
- };
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/tosa-power-key-off.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/tosa-power-key-off.patch
deleted file mode 100644
index 380e6be813..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/tosa-power-key-off.patch
+++ /dev/null
@@ -1,127 +0,0 @@
-
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- linux/drivers/char/tosa_ts.c~tosa-power-key-off
-+++ linux/drivers/char/tosa_ts.c
-@@ -205,10 +205,53 @@
- write: tosa_ts_write_params,
- };
-
-+#if defined(CONFIG_TOSA_POWER_KEY_OFF)
-+extern unsigned int power_key_off_mode;
-+
-+static ssize_t power_key_off_read_params(struct file *file, char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ char outputbuf[32];
-+ int count;
-+
-+ if (*ppos>0) /* Assume reading completed in previous read*/
-+ return 0;
-+ count = sprintf(outputbuf, "%d\n", (unsigned int)power_key_off_mode);
-+ count++;
-+ *ppos += count;
-+ if (count>nbytes) /* Assume output can be read at one time */
-+ return -EINVAL;
-+ if (copy_to_user(buf, outputbuf, count+1))
-+ return -EFAULT;
-+ return count;
-+}
-+
-+static ssize_t power_key_off_write_params(struct file *file, const char *buf,
-+ size_t nbytes, loff_t *ppos)
-+{
-+ unsigned int param=0;
-+
-+ sscanf(buf,"%d",&param);
-+ if (power_key_off_mode != param) {
-+ power_key_off_mode = param;
-+ printk("power_key_off = %d\n", power_key_off_mode);
-+ }
-+ return nbytes;
-+}
-+
-+static struct file_operations proc_power_key_off_operations = {
-+ read: power_key_off_read_params,
-+ write: power_key_off_write_params,
-+};
-+#endif
-+
- static int init_procinfo(void)
- {
- int i;
- struct proc_dir_entry *entry;
-+#if defined(CONFIG_TOSA_POWER_KEY_OFF)
-+ struct proc_dir_entry *power_key_off_proc;
-+#endif
-
- proc_ts = proc_mkdir("driver/ts", NULL);
- if (proc_ts == NULL) {
-@@ -234,6 +277,12 @@
- }
- }
-
-+#if defined(CONFIG_TOSA_POWER_KEY_OFF)
-+ power_key_off_proc = create_proc_entry("power_key_off", 0, NULL);
-+ if (power_key_off_proc)
-+ power_key_off_proc->proc_fops = &proc_power_key_off_operations;
-+#endif
-+
- return 0;
- }
-
---- linux/drivers/char/Config.in~tosa-power-key-off
-+++ linux/drivers/char/Config.in
-@@ -35,6 +35,8 @@
- if [ "$CONFIG_SERIAL_SL_SERIES" = "y" ]; then
- bool ' SL-series Bluetooth support' CONFIG_BLUETOOTH_SL
- fi
-+ dep_bool ' Tosa power key suspend (EXPERIMENTAL)' CONFIG_TOSA_POWER_KEY_OFF $CONFIG_ARCH_PXA_TOSA
-+ dep_bool ' Tosa Boot On power key suspend' CONFIG_BOOT_TOSA_POWER_KEY_OFF $CONFIG_TOSA_POWER_KEY_OFF
- fi
- bool 'Use Keyboard device file (EXPERIMENTAL)' CONFIG_KBD_DEV_FILE
- if [ "$CONFIG_SA1100_COLLIE" = "y" ]; then
---- linux/drivers/char/keyboard.c~tosa-power-key-off
-+++ linux/drivers/char/keyboard.c
-@@ -119,8 +119,8 @@
- static struct kbd_struct * kbd = kbd_table;
- static struct tty_struct * tty;
-
--#if defined(CONFIG_SL7X0_POWER_KEY_OFF)
--#if defined(CONFIG_BOOT_POWER_KEY_OFF)
-+#if defined(CONFIG_SL7X0_POWER_KEY_OFF) || defined(CONFIG_TOSA_POWER_KEY_OFF)
-+#if defined(CONFIG_BOOT_POWER_KEY_OFF) || defined(CONFIG_BOOT_TOSA_POWER_KEY_OFF)
- unsigned int power_key_off_mode = 1;
- #else
- unsigned int power_key_off_mode = 0;
-@@ -245,7 +245,7 @@
- void handle_scancode(unsigned char scancode, int down)
- {
-
--#if defined(CONFIG_SL7X0_POWER_KEY_OFF)
-+#if defined(CONFIG_SL7X0_POWER_KEY_OFF) || defined(CONFIG_TOSA_POWER_KEY_OFF)
- /* printk("scancode = %x down = %x \n",scancode,down); */
- /* SL-C700 side power 0x6d */
- if ( power_key_off_mode && ( scancode == 0x6d ) && ( down == 0x01 ) ){
-@@ -282,7 +282,7 @@
- handle_scancode_main ( scancode, down );
- } else
- #endif
--#if defined(CONFIG_SL7X0_POWER_KEY_OFF) || defined(CONFIG_SL_3BUTTON_PATCH)
-+#if defined(CONFIG_SL7X0_POWER_KEY_OFF) || defined(CONFIG_SL_3BUTTON_PATCH) || defined(CONFIG_TOSA_POWER_KEY_OFF)
- {
-
- handle_scancode_main ( scancode, down );
---- linux/arch/arm/mach-pxa/sharpsl_power.c~tosa-power-key-off
-+++ linux/arch/arm/mach-pxa/sharpsl_power.c
-@@ -1725,7 +1725,7 @@
- return 0;
- }
-
--#if defined(CONFIG_SL7X0_POWER_KEY_OFF)
-+#if defined(CONFIG_SL7X0_POWER_KEY_OFF) || defined(CONFIG_TOSA_POWER_KEY_OFF)
- static int key_suspend_thread(void* unused)
- {
- int time_cnt = 0;
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/tosa_map.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/tosa_map.patch
deleted file mode 100644
index feca970614..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/tosa_map.patch
+++ /dev/null
@@ -1,889 +0,0 @@
-
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- linux/drivers/char/tosa_keymap.c~tosa_map.patch
-+++ linux/drivers/char/tosa_keymap.c
-@@ -6,348 +6,88 @@
- #include <linux/keyboard.h>
- #include <linux/kd.h>
-
--u_short plain_map[] = {
-+u_short plain_map[NR_KEYS] = {
- 0xf200, 0xfb61, 0xfb62, 0xfb63, 0xfb64, 0xfb65, 0xfb66, 0xfb67,
- 0xfb68, 0xfb69, 0xfb6a, 0xfb6b, 0xfb6c, 0xfb6d, 0xfb6e, 0xfb6f,
- 0xfb70, 0xfb71, 0xfb72, 0xfb73, 0xfb74, 0xfb75, 0xfb76, 0xfb77,
-- 0xfb78, 0xfb79, 0xfb7a, 0xf700, 0xf201, 0xf101, 0xf703, 0xf008,
-- 0xf208, 0xf200, 0xf01b, 0xf601, 0xf603, 0xf600, 0xf602, 0xf201,
-+ 0xfb78, 0xfb79, 0xfb7a, 0xf700, 0xf201, 0xf101, 0xf200, 0xf008,
-+ 0xf07c, 0xf200, 0xf01b, 0xf601, 0xf603, 0xf600, 0xf602, 0xf201,
- 0xf200, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
-- 0xf038, 0xf039, 0xf030, 0xf02d, 0xf05e, 0xf05c, 0xf05b, 0xf040,
-- 0xf702, 0xf703, 0xf702, 0xf02b, 0xfa00, 0xf040, 0xf03f, 0xf02c,
-- 0xf02e, 0xf009, 0xf104, 0xf105, 0xf106, 0xf02f, 0xf027, 0xf301,
-- 0xf302, 0xf303, 0xf304, 0xf305, 0xf306, 0xf307, 0xf308, 0xf309,
-- 0xf300, 0xf07f, 0xf30d, 0xf30c, 0xf200, 0xf30b, 0xf30a, 0xf30e,
-- 0xf702, 0xf703, 0xf01b, 0xf020, 0xf020, 0xf310, 0xf200, 0xf03b,
-- 0xf03a, 0xf05d, 0xf02c, 0xf02e, 0xf02f, 0xf05f, 0xf200, 0xf700,
-- 0xf114, 0xf117, 0xf118, 0xf119, 0xf701, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf200, 0xf200,
-- 0xf702, 0xf703, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf038, 0xf039, 0xf030, 0xfbe4, 0xfbfc, 0xfbf6, 0xfbc4, 0xfbdc,
-+ 0xfbd6, 0xfbdf, 0xf02d, 0xf02b, 0xfa00, 0xf040, 0xf03f, 0xf02c,
-+ 0xf02e, 0xf009, 0xf104, 0xf105, 0xf106, 0xf02f, 0xf027, 0xf03b,
-+ 0xf022, 0xf03a, 0xf023, 0xf024, 0xf025, 0xf05f, 0xf026, 0xf02a,
-+ 0xf028, 0xf07f, 0xf109, 0xf03d, 0xf029, 0xf07e, 0xf03c, 0xf03e,
-+ 0xf702, 0xf703, 0xf200, 0xf020, 0xf020, 0xf200, 0xf021, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf700,
-+ 0xf702, 0xf702, 0xf703, 0xf703, 0xf701, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- };
-
--u_short shift_map[] = {
-+u_short shift_map[NR_KEYS] = {
- 0xf200, 0xfb41, 0xfb42, 0xfb43, 0xfb44, 0xfb45, 0xfb46, 0xfb47,
- 0xfb48, 0xfb49, 0xfb4a, 0xfb4b, 0xfb4c, 0xfb4d, 0xfb4e, 0xfb4f,
- 0xfb50, 0xfb51, 0xfb52, 0xfb53, 0xfb54, 0xfb55, 0xfb56, 0xfb57,
-- 0xfb58, 0xfb59, 0xfb5a, 0xf700, 0xf201, 0xf101, 0xf702, 0xf008,
-- 0xf208, 0xf200, 0xf01b, 0xf601, 0xf603, 0xf600, 0xf602, 0xf201,
-- 0xf200, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
-- 0xf028, 0xf029, 0xf07e, 0xf03d, 0xf07e, 0xf07c, 0xf07b, 0xf060,
-- 0xf702, 0xf703, 0xf702, 0xf02b, 0xfa00, 0xf040, 0xf03f, 0xf03b,
-- 0xf03a, 0xf009, 0xf104, 0xf105, 0xf106, 0xf03f, 0xf022, 0xf301,
-- 0xf302, 0xf303, 0xf304, 0xf305, 0xf306, 0xf307, 0xf308, 0xf309,
-- 0xf300, 0xf07f, 0xf30d, 0xf30c, 0xf200, 0xf30b, 0xf30a, 0xf30e,
-- 0xf702, 0xf703, 0xf01b, 0xf020, 0xf020, 0xf310, 0xf200, 0xf02b,
-- 0xf02a, 0xf07d, 0xf03c, 0xf03e, 0xf03f, 0xf05f, 0xf200, 0xf700,
-- 0xf114, 0xf117, 0xf20b, 0xf20a, 0xf701, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf200, 0xf200,
-- 0xf702, 0xf703, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xfb58, 0xfb59, 0xfb5a, 0xf700, 0xf201, 0xf101, 0xf200, 0xf008,
-+ 0xf07c, 0xf200, 0xf01b, 0xf601, 0xf603, 0xf600, 0xf602, 0xf201,
-+ 0xf200, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
-+ 0xf038, 0xf039, 0xf030, 0xfbe4, 0xfbfc, 0xfbf6, 0xfbc4, 0xfbdc,
-+ 0xfbd6, 0xfbdf, 0xf02d, 0xf02b, 0xfa00, 0xf040, 0xf03f, 0xf02c,
-+ 0xf02e, 0xf009, 0xf104, 0xf105, 0xf106, 0xf02f, 0xf027, 0xf03b,
-+ 0xf022, 0xf03a, 0xf023, 0xf024, 0xf025, 0xf05f, 0xf026, 0xf02a,
-+ 0xf028, 0xf07f, 0xf109, 0xf03d, 0xf029, 0xf07e, 0xf03c, 0xf03e,
-+ 0xf702, 0xf703, 0xf200, 0xf020, 0xf020, 0xf200, 0xf021, 0xf200,
-+ 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf700,
-+ 0xf702, 0xf702, 0xf703, 0xf703, 0xf701, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- };
-
--u_short ctrl_map[] = {
-+u_short ctrl_map[NR_KEYS] = {
- 0xf200, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007,
- 0xf008, 0xf009, 0xf00a, 0xf00b, 0xf00c, 0xf00d, 0xf00e, 0xf00f,
- 0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017,
- 0xf018, 0xf019, 0xf01a, 0xf700, 0xf201, 0xf101, 0xf200, 0xf008,
-- 0xf208, 0xf200, 0xf01b, 0xf601, 0xf603, 0xf600, 0xf602, 0xf201,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf702, 0xf703, 0xf702, 0xf02b, 0xfa00, 0xf040, 0xf03f, 0xf200,
-- 0xf200, 0xf009, 0xf104, 0xf105, 0xf106, 0xf200, 0xf200, 0xf301,
-- 0xf302, 0xf303, 0xf304, 0xf305, 0xf306, 0xf307, 0xf308, 0xf309,
-- 0xf300, 0xf07f, 0xf30d, 0xf30c, 0xf200, 0xf30b, 0xf30a, 0xf30e,
-- 0xf702, 0xf703, 0xf01b, 0xf020, 0xf000, 0xf310, 0xf200, 0xf200,
-+ 0xf07c, 0xf200, 0xf01b, 0xf601, 0xf603, 0xf600, 0xf602, 0xf201,
-+ 0xf200, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
-+ 0xf038, 0xf039, 0xf030, 0xfbe4, 0xfbfc, 0xfbf6, 0xfbc4, 0xfbdc,
-+ 0xfbd6, 0xfbdf, 0xf02d, 0xf02b, 0xfa00, 0xf040, 0xf03f, 0xf02c,
-+ 0xf02e, 0xf009, 0xf104, 0xf105, 0xf106, 0xf02f, 0xf027, 0xf03b,
-+ 0xf022, 0xf03a, 0xf023, 0xf024, 0xf025, 0xf05f, 0xf026, 0xf02a,
-+ 0xf028, 0xf07f, 0xf109, 0xf03d, 0xf029, 0xf07e, 0xf03c, 0xf03e,
-+ 0xf702, 0xf703, 0xf200, 0xf000, 0xf000, 0xf200, 0xf021, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf700,
-- 0xf114, 0xf117, 0xf118, 0xf119, 0xf701, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf200, 0xf200,
-- 0xf702, 0xf703, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf702, 0xf702, 0xf703, 0xf703, 0xf701, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- };
-
--u_short shift_ctrl_map[] = {
-+u_short shift_ctrl_map[NR_KEYS] = {
- 0xf200, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007,
- 0xf008, 0xf009, 0xf00a, 0xf00b, 0xf00c, 0xf00d, 0xf00e, 0xf00f,
- 0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017,
- 0xf018, 0xf019, 0xf01a, 0xf700, 0xf201, 0xf101, 0xf200, 0xf008,
-- 0xf208, 0xf200, 0xf01b, 0xf601, 0xf603, 0xf600, 0xf602, 0xf201,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf702, 0xf703, 0xf702, 0xf02b, 0xfa00, 0xf040, 0xf03f, 0xf200,
-- 0xf200, 0xf009, 0xf104, 0xf105, 0xf106, 0xf200, 0xf200, 0xf301,
-- 0xf302, 0xf303, 0xf304, 0xf305, 0xf306, 0xf307, 0xf308, 0xf309,
-- 0xf300, 0xf07f, 0xf30d, 0xf30c, 0xf200, 0xf30b, 0xf30a, 0xf30e,
-- 0xf702, 0xf703, 0xf01b, 0xf020, 0xf020, 0xf310, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf700,
-- 0xf114, 0xf117, 0xf118, 0xf119, 0xf701, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf200, 0xf200,
-- 0xf702, 0xf703, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
--};
--
--u_short alt_map[] = {
-- 0xf200, 0xf021, 0xf02d, 0xf863, 0xf023, 0xf033, 0xf024, 0xf025,
-- 0xf05f, 0xf038, 0xf026, 0xf02a, 0xf028, 0xf03d, 0xf02b, 0xf039,
-- 0xf030, 0xf031, 0xf034, 0xf040, 0xf035, 0xf037, 0xf876, 0xf032,
-- 0xf878, 0xf036, 0xf87a, 0xf700, 0xf201, 0xf101, 0xf200, 0xf07f,
-- 0xf208, 0xf200, 0xf01b, 0xf601, 0xf603, 0xf600, 0xf602, 0xf07d,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf702, 0xf703, 0xf702, 0xf02b, 0xfa00, 0xf040, 0xf03f, 0xf029,
-- 0xf03c, 0xf207, 0xf104, 0xf105, 0xf106, 0xf200, 0xf07e, 0xf301,
-- 0xf302, 0xf303, 0xf304, 0xf305, 0xf306, 0xf307, 0xf308, 0xf309,
-- 0xf300, 0xf07f, 0xf30d, 0xf30c, 0xf200, 0xf30b, 0xf30a, 0xf30e,
-- 0xf702, 0xf703, 0xf01b, 0xf000, 0xf020, 0xf310, 0xf200, 0xf200,
-+ 0xf07c, 0xf200, 0xf01b, 0xf601, 0xf603, 0xf600, 0xf602, 0xf201,
-+ 0xf200, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
-+ 0xf038, 0xf039, 0xf030, 0xfbe4, 0xfbfc, 0xfbf6, 0xfbc4, 0xfbdc,
-+ 0xfbd6, 0xfbdf, 0xf02d, 0xf02b, 0xfa00, 0xf040, 0xf03f, 0xf02c,
-+ 0xf02e, 0xf009, 0xf104, 0xf105, 0xf106, 0xf02f, 0xf027, 0xf03b,
-+ 0xf022, 0xf03a, 0xf023, 0xf024, 0xf025, 0xf05f, 0xf026, 0xf02a,
-+ 0xf028, 0xf07f, 0xf109, 0xf03d, 0xf029, 0xf07e, 0xf03c, 0xf03e,
-+ 0xf702, 0xf703, 0xf200, 0xf020, 0xf020, 0xf200, 0xf021, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf700,
-- 0xf114, 0xf117, 0xf118, 0xf119, 0xf701, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf702, 0xf200, 0xf200,
-- 0xf702, 0xf703, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
-+ 0xf702, 0xf702, 0xf703, 0xf703, 0xf701, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- };
-
- ushort *key_maps[MAX_NR_KEYMAPS] = {
- plain_map, shift_map, 0, 0,
-- ctrl_map, shift_ctrl_map, 0, 0,
-- alt_map, 0
-+ ctrl_map, shift_ctrl_map, 0
- };
-
--unsigned int keymap_count = 5;
-+unsigned int keymap_count = 4;
-
-
- /*
---- linux/drivers/char/tosa_keymap.map~tosa_map.patch
-+++ linux/drivers/char/tosa_keymap.map
-@@ -8,9 +8,8 @@
- # 1 for [SHIFT]
- # 4 for [CTRL] , to symbol input for debug
- # 5 for [CTRL] [SHIFT] , to symbol input for debug
--# 8 for [ALT]
- #
--keymaps 0,1,4,5,8
-+keymaps 0,1,4,5
- #
- # loadkeys --mktable iris_keymap.map
- #
-@@ -20,60 +19,38 @@
- #
- #
- keycode 1 = a
-- alt keycode 1 = exclam
- keycode 2 = b
-- alt keycode 2 = minus
- keycode 3 = c
- keycode 4 = d
-- alt keycode 4 = numbersign
- keycode 5 = e
-- alt keycode 5 = three
- keycode 6 = f
-- alt keycode 6 = dollar
- keycode 7 = g
-- alt keycode 7 = percent
- keycode 8 = h
-- alt keycode 8 = underscore
- keycode 9 = i
-- alt keycode 9 = eight
- keycode 10 = j
-- alt keycode 10 = ampersand
- keycode 11 = k
-- alt keycode 11 = asterisk
- keycode 12 = l
-- alt keycode 12 = parenleft
- keycode 13 = m
-- alt keycode 13 = equal
- keycode 14 = n
-- alt keycode 14 = plus
- keycode 15 = o
-- alt keycode 15 = nine
- keycode 16 = p
-- alt keycode 16 = zero
- keycode 17 = q
-- alt keycode 17 = one
- keycode 18 = r
-- alt keycode 18 = four
- keycode 19 = s
-- alt keycode 19 = at
- keycode 20 = t
-- alt keycode 20 = five
- keycode 21 = u
-- alt keycode 21 = seven
- keycode 22 = v
- keycode 23 = w
-- alt keycode 23 = two
- keycode 24 = x
- keycode 25 = y
-- alt keycode 25 = six
- keycode 26 = z
- keycode 27 = Shift
- keycode 28 = Return
- keycode 29 = F2
--keycode 30 = Alt Control
-+keycode 30 =
- keycode 31 = BackSpace
-- alt keycode 31 = Delete
--keycode 32 = Num_Lock
-+# for Debug , keycode 32(F3, Sym) --> Control
-+keycode 32 = bar
- keycode 33 =
- # (Cancel:34) F9 -> Escape
- keycode 34 = Escape
-@@ -83,100 +60,84 @@
- keycode 38 = Right
- # (OK:39) F4 -> Return
- keycode 39 = Return
-- alt keycode 39 = braceright
- keycode 40 =
--keycode 41 = one exclam
--keycode 42 = two quotedbl
--keycode 43 = three numbersign
--keycode 44 = four dollar
--keycode 45 = five percent
--keycode 46 = six ampersand
--keycode 47 = seven apostrophe
--keycode 48 = eight parenleft
--keycode 49 = nine parenright
--keycode 50 = zero asciitilde
--keycode 51 = minus equal
--keycode 52 = asciicircum asciitilde
--keycode 53 = backslash bar
--keycode 54 = bracketleft braceleft
--keycode 55 = at grave
--keycode 56 = Control
--keycode 57 = Alt
--keycode 58 = Control
-+keycode 41 = one
-+keycode 42 = two
-+keycode 43 = three
-+keycode 44 = four
-+keycode 45 = five
-+keycode 46 = six
-+keycode 47 = seven
-+keycode 48 = eight
-+keycode 49 = nine
-+keycode 50 = zero
-+keycode 51 = +adiaeresis
-+keycode 52 = +udiaeresis
-+keycode 53 = +odiaeresis
-+keycode 54 = +Adiaeresis
-+keycode 55 = +Udiaeresis
-+keycode 56 = +Odiaeresis
-+keycode 57 = +ssharp
-+keycode 58 = minus
- keycode 59 = plus
- keycode 60 = Shift_Lock
- keycode 61 = at
- keycode 62 = question
--keycode 63 = comma semicolon
-- alt keycode 63 = parenright
--keycode 64 = period colon
-- alt keycode 64 = less
-+keycode 63 = comma
-+keycode 64 = period
- keycode 65 = Tab
-- alt keycode 65 = Caps_Lock
- keycode 66 = F5
- keycode 67 = F6
- keycode 68 = F7
--keycode 69 = slash question
--keycode 70 = apostrophe quotedbl
-- alt keycode 70 = asciitilde
--keycode 71 = KP_1
--keycode 72 = KP_2
--keycode 73 = KP_3
--keycode 74 = KP_4
--keycode 75 = KP_5
--keycode 76 = KP_6
--keycode 77 = KP_7
--keycode 78 = KP_8
--keycode 79 = KP_9
--keycode 80 = KP_0
-+keycode 69 = slash
-+keycode 70 = apostrophe
-+keycode 71 = semicolon
-+keycode 72 = quotedbl
-+keycode 73 = colon
-+keycode 74 = numbersign
-+keycode 75 = dollar
-+keycode 76 = percent
-+# 2001/7/5 old keycode 77 = asciicircum
-+keycode 77 = underscore
-+keycode 78 = ampersand
-+keycode 79 = asterisk
-+keycode 80 = parenleft
- keycode 81 = Delete
--keycode 82 = KP_Divide
--keycode 83 = KP_Multiply
--keycode 84 =
--keycode 85 = KP_Subtract
--keycode 86 = KP_Add
--keycode 87 = KP_Enter
-+keycode 82 = F10
-+keycode 83 = equal
-+keycode 84 = parenright
-+keycode 85 = asciitilde
-+keycode 86 = less
-+keycode 87 = greater
- # (Activity:88) -> Ctrl
- keycode 88 = Control
- # (Contacts:89) -> Alt
- keycode 89 = Alt
--keycode 90 = Escape
-+keycode 90 =
- # (select:91) F11 -> space
- keycode 91 = space
-- alt keycode 91 = nul
-+ control keycode 91 = nul
- keycode 92 = space
- control keycode 92 = nul
--keycode 93 = KP_Period
--keycode 94 =
--keycode 95 = semicolon plus
--keycode 96 = colon asterisk
--keycode 97 = bracketright braceright
--keycode 98 = comma less
--keycode 99 = period greater
--keycode 100 = slash question
--keycode 101 = underscore underscore
-+keycode 93 =
-+keycode 94 = exclam
-+keycode 95 =
-+keycode 96 =
-+keycode 97 =
-+keycode 98 =
-+keycode 99 =
-+keycode 100 =
-+keycode 101 =
- keycode 102 =
- keycode 103 = Shift
--keycode 104 = Find
--keycode 105 = Select
--keycode 106 = Prior
-- shift keycode 106 = Scroll_Backward
--keycode 107 = Next
-- shift keycode 107 = Scroll_Forward
-+keycode 104 = Control
-+keycode 105 = Control
-+keycode 106 = Alt
-+keycode 107 = Alt
- keycode 108 = AltGr
- keycode 109 =
- keycode 110 =
- keycode 111 =
--keycode 112 =
--keycode 113 =
--keycode 114 =
--keycode 115 =
--keycode 116 =
--keycode 117 = Control
--keycode 118 =
--keycode 119 =
--keycode 120 = Control
--keycode 121 = Alt
-
-
- string F1 = "\033[[A"
---- linux/drivers/char/tosa_rawmap.h~tosa_map.patch
-+++ linux/drivers/char/tosa_rawmap.h
-@@ -22,28 +22,156 @@
-
-
- static unsigned char rawkeytable_table_NormalLower[(NR_KEYCODES+1)] = {
--KEY_IGN,KEY_IGN,SLKEY_W,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_K,SLKEY_BACK_SPACE,SLKEY_P,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_OFF,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Q,SLKEY_E,SLKEY_T,SLKEY_Y,KEY_IGN,SLKEY_O,SLKEY_I,SLKEY_COMMA,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_RECORDER,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_A,SLKEY_D,SLKEY_G,SLKEY_U,KEY_IGN,SLKEY_L,SLKEY_ENTER,SLKEY_PERIOD,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_SYNCSTART,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Z,SLKEY_C,SLKEY_V,SLKEY_J,SLKEY_CONTACTS,SLKEY_F9,SLKEY_F11,SLKEY_F4,SLKEY_LSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_S,SLKEY_R,SLKEY_B,SLKEY_N,SLKEY_ACTIVITY,SLKEY_HOME,SLKEY_MINUS,SLKEY_FRONTLIGHT,KEY_IGN,SLKEY_RSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_TAB,SLKEY_SLASH,SLKEY_H,SLKEY_M,SLKEY_F2,KEY_IGN,SLKEY_UP,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_2ND,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_X,SLKEY_F,SLKEY_SPACE,SLKEY_APOSTROPHE,SLKEY_MAIL,SLKEY_LEFT,SLKEY_DOWN,SLKEY_RIGHT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN};
-+KEY_IGN, KEY_IGN, SLKEY_W, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_K, SLKEY_BACK_SPACE,
-+SLKEY_P, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_OFF, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_Q, SLKEY_E, SLKEY_T, SLKEY_Y, KEY_IGN, SLKEY_O, SLKEY_I,
-+SLKEY_COMMA, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_RECORDER, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_A, SLKEY_D, SLKEY_G, SLKEY_U, KEY_IGN, SLKEY_L, SLKEY_ENTER,
-+SLKEY_PERIOD, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_SYNCSTART,KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_Z, SLKEY_C, SLKEY_V, SLKEY_J, SLKEY_CONTACTS, SLKEY_F9, SLKEY_F11,
-+SLKEY_F4, SLKEY_LSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_S, SLKEY_R, SLKEY_B, SLKEY_N, SLKEY_ACTIVITY, SLKEY_HOME,SLKEY_MINUS,
-+SLKEY_FRONTLIGHT,KEY_IGN, SLKEY_RSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_TAB, SLKEY_SLASH, SLKEY_H, SLKEY_M, SLKEY_F2, KEY_IGN, SLKEY_UP,
-+KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_2ND, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_X, SLKEY_F, SLKEY_SPACE, SLKEY_APOSTROPHE,SLKEY_MAIL, SLKEY_LEFT,SLKEY_DOWN,
-+SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN
-+};
-
- static unsigned char rawkeytable_table_NormalUpper[(NR_KEYCODES+1)] = {
--KEY_IGN,KEY_IGN,SLKEY_W,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_K,SLKEY_BACK_SPACE,SLKEY_P,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_OFF,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Q,SLKEY_E,SLKEY_T,SLKEY_Y,KEY_IGN,SLKEY_O,SLKEY_I,SLKEY_COMMA,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_RECORDER,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_A,SLKEY_D,SLKEY_G,SLKEY_U,KEY_IGN,SLKEY_L,SLKEY_ENTER,SLKEY_PERIOD,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_SYNCSTART,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Z,SLKEY_C,SLKEY_V,SLKEY_J,SLKEY_CONTACTS,SLKEY_F9,SLKEY_F11,SLKEY_F4,SLKEY_LSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_S,SLKEY_R,SLKEY_B,SLKEY_N,SLKEY_ACTIVITY,SLKEY_HOME,SLKEY_MINUS,SLKEY_FRONTLIGHT,KEY_IGN,SLKEY_RSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_TAB,SLKEY_SLASH,SLKEY_H,SLKEY_M,SLKEY_F2,KEY_IGN,SLKEY_UP,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_2ND,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_X,SLKEY_F,SLKEY_SPACE,SLKEY_APOSTROPHE,SLKEY_MAIL,SLKEY_LEFT,SLKEY_DOWN,SLKEY_RIGHT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN};
-+KEY_IGN, KEY_IGN, SLKEY_W, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_K, SLKEY_BACK_SPACE,
-+SLKEY_P, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_OFF, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_Q, SLKEY_E, SLKEY_T, SLKEY_Y, KEY_IGN, SLKEY_O, SLKEY_I,
-+SLKEY_SEMICOLON,KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_RECORDER, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_A, SLKEY_D, SLKEY_G, SLKEY_U, KEY_IGN, SLKEY_L, SLKEY_ENTER,
-+SLKEY_COLON, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_SYNCSTART,KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_Z, SLKEY_C, SLKEY_V, SLKEY_J, SLKEY_CONTACTS, SLKEY_F9, SLKEY_F11,
-+SLKEY_F4, SLKEY_LSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_S, SLKEY_R, SLKEY_B, SLKEY_N, SLKEY_ACTIVITY, SLKEY_HOME, SLKEY_MINUS,
-+SLKEY_FRONTLIGHT, KEY_IGN, SLKEY_RSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_TAB, SLKEY_QUESTION, SLKEY_H, SLKEY_M, SLKEY_F2, KEY_IGN, SLKEY_UP,
-+KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_2ND, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_X, SLKEY_F, SLKEY_SPACE, SLKEY_QUOTEDBL, SLKEY_MAIL, SLKEY_LEFT, SLKEY_DOWN,
-+SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN
-+};
-
- static unsigned char rawkeytable_table_2ndLower[(NR_KEYCODES+1)] = {
--KEY_IGN,KEY_IGN,SLKEY_W,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_K,SLKEY_BACK_SPACE,SLKEY_P,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_OFF,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Q,SLKEY_E,SLKEY_T,SLKEY_Y,KEY_IGN,SLKEY_O,SLKEY_I,SLKEY_COMMA,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_RECORDER,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_A,SLKEY_D,SLKEY_G,SLKEY_U,KEY_IGN,SLKEY_L,SLKEY_ENTER,SLKEY_PERIOD,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_SYNCSTART,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Z,SLKEY_C,SLKEY_V,SLKEY_J,SLKEY_CONTACTS,SLKEY_F9,SLKEY_F11,SLKEY_F4,SLKEY_LSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_S,SLKEY_R,SLKEY_B,SLKEY_N,SLKEY_ACTIVITY,SLKEY_HOME,SLKEY_MINUS,SLKEY_FRONTLIGHT,KEY_IGN,SLKEY_RSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_TAB,SLKEY_SLASH,SLKEY_H,SLKEY_M,SLKEY_F2,KEY_IGN,SLKEY_UP,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_2ND,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_X,SLKEY_F,SLKEY_SPACE,SLKEY_APOSTROPHE,SLKEY_MAIL,SLKEY_LEFT,SLKEY_DOWN,SLKEY_RIGHT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN};
-+KEY_IGN, KEY_IGN, SLKEY_2, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_ASTERISK, SLKEY_DELETE,
-+SLKEY_0, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_OFF, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_1, SLKEY_3, SLKEY_5, SLKEY_6, KEY_IGN, SLKEY_9, SLKEY_8,
-+SLKEY_PARENRIGHT, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_RECORDER, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_EXCLAM, SLKEY_NUMBERSIGN, SLKEY_PERCENT,SLKEY_7, KEY_IGN, SLKEY_PARENLEFT,SLKEY_GREATER,
-+SLKEY_LESS, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_SYNCSTART,KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_F10, SLKEY_F6, SLKEY_F7, SLKEY_AMPERSAND,SLKEY_CONTACTS, SLKEY_F9, SLKEY_F11,
-+SLKEY_F4, SLKEY_LSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_AT, SLKEY_4, SLKEY_MINUS, SLKEY_PLUS, SLKEY_ACTIVITY, SLKEY_HOME, SLKEY_MINUS,
-+SLKEY_FRONTLIGHT, KEY_IGN, SLKEY_RSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_CAPS_LOCK,SLKEY_NUMLOCK, SLKEY_ASCIICIRCUM, SLKEY_EQUAL, SLKEY_F2, KEY_IGN, SLKEY_UP,
-+KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_2ND, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_F5, SLKEY_DOLLAR, SLKEY_SYM, SLKEY_ASCIITILDE, SLKEY_MAIL, SLKEY_LEFT, SLKEY_DOWN,
-+SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN
-+};
-
- static unsigned char rawkeytable_table_2ndUpper[(NR_KEYCODES+1)] = {
--KEY_IGN,KEY_IGN,SLKEY_W,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_K,SLKEY_BACK_SPACE,SLKEY_P,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_OFF,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Q,SLKEY_E,SLKEY_T,SLKEY_Y,KEY_IGN,SLKEY_O,SLKEY_I,SLKEY_COMMA,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_RECORDER,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_A,SLKEY_D,SLKEY_G,SLKEY_U,KEY_IGN,SLKEY_L,SLKEY_ENTER,SLKEY_PERIOD,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_SYNCSTART,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Z,SLKEY_PRINTSCREEN,SLKEY_V,SLKEY_J,SLKEY_CONTACTS,SLKEY_F9,SLKEY_F11,SLKEY_F4,SLKEY_LSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_S,SLKEY_R,SLKEY_B,SLKEY_N,SLKEY_ACTIVITY,SLKEY_HOME,SLKEY_MINUS,SLKEY_FRONTLIGHT,KEY_IGN,SLKEY_RSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_TAB,SLKEY_SLASH,SLKEY_H,SLKEY_M,SLKEY_F2,KEY_IGN,SLKEY_UP,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_2ND,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_X,SLKEY_F,SLKEY_SPACE,SLKEY_APOSTROPHE,SLKEY_MAIL,SLKEY_LEFT,SLKEY_DOWN,SLKEY_RIGHT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN};
-+KEY_IGN, KEY_IGN, SLKEY_2, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_ASTERISK, SLKEY_DELETE,
-+SLKEY_0, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_OFF, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_1, SLKEY_3, SLKEY_5, SLKEY_6, KEY_IGN, SLKEY_9, SLKEY_8,
-+SLKEY_PARENRIGHT, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_RECORDER, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_EXCLAM, SLKEY_NUMBERSIGN, SLKEY_PERCENT,SLKEY_7, KEY_IGN, SLKEY_PARENLEFT,SLKEY_GREATER,
-+SLKEY_LESS, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_SYNCSTART,KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_F10, SLKEY_F6, SLKEY_F7, SLKEY_AMPERSAND,SLKEY_CONTACTS, SLKEY_F9, SLKEY_F11,
-+SLKEY_F4, SLKEY_LSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_AT, SLKEY_4, SLKEY_MINUS, SLKEY_PLUS, SLKEY_ACTIVITY, SLKEY_HOME, SLKEY_MINUS,
-+SLKEY_FRONTLIGHT, KEY_IGN, SLKEY_RSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_CAPS_LOCK,SLKEY_NUMLOCK, SLKEY_ASCIICIRCUM, SLKEY_EQUAL, SLKEY_F2, KEY_IGN, SLKEY_UP,
-+KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_2ND, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_F5, SLKEY_DOLLAR, SLKEY_SYM, SLKEY_ASCIITILDE, SLKEY_MAIL, SLKEY_LEFT, SLKEY_DOWN,
-+SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN
-+};
-
- static unsigned char rawkeytable_table_NumlockLower[(NR_KEYCODES+1)] = {
--KEY_IGN,KEY_IGN,SLKEY_W,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_K,SLKEY_BACK_SPACE,SLKEY_P,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_OFF,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Q,SLKEY_E,SLKEY_T,SLKEY_Y,KEY_IGN,SLKEY_O,SLKEY_I,SLKEY_COMMA,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_RECORDER,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_A,SLKEY_D,SLKEY_G,SLKEY_U,KEY_IGN,SLKEY_L,SLKEY_ENTER,SLKEY_PERIOD,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_SYNCSTART,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Z,SLKEY_C,SLKEY_V,SLKEY_J,SLKEY_CONTACTS,SLKEY_F9,SLKEY_F11,SLKEY_F4,SLKEY_LSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_S,SLKEY_R,SLKEY_B,SLKEY_N,SLKEY_ACTIVITY,SLKEY_HOME,SLKEY_MINUS,SLKEY_FRONTLIGHT,KEY_IGN,SLKEY_RSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_TAB,SLKEY_SLASH,SLKEY_H,SLKEY_M,SLKEY_F2,KEY_IGN,SLKEY_UP,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_2ND,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_X,SLKEY_F,SLKEY_SPACE,SLKEY_APOSTROPHE,SLKEY_MAIL,SLKEY_LEFT,SLKEY_DOWN,SLKEY_RIGHT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN};
-+KEY_IGN, KEY_IGN, SLKEY_2, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_ASTERISK, SLKEY_BACK_SPACE,
-+SLKEY_0, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_OFF, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_1, SLKEY_3, SLKEY_5, SLKEY_6, KEY_IGN, SLKEY_9, SLKEY_8,
-+SLKEY_PARENRIGHT, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_RECORDER, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_EXCLAM, SLKEY_NUMBERSIGN, SLKEY_PERCENT, SLKEY_7, KEY_IGN, SLKEY_PARENLEFT,SLKEY_GREATER,
-+SLKEY_LESS, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_SYNCSTART, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_F10, SLKEY_F6, SLKEY_F7, SLKEY_AMPERSAND, SLKEY_CONTACTS, SLKEY_F9, SLKEY_F11,
-+SLKEY_F4, SLKEY_LSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_AT, SLKEY_4, SLKEY_MINUS, SLKEY_PLUS, SLKEY_ACTIVITY, SLKEY_HOME, SLKEY_MINUS,
-+SLKEY_FRONTLIGHT, KEY_IGN, SLKEY_RSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_TAB, SLKEY_SLASH, SLKEY_ASCIICIRCUM, SLKEY_EQUAL, SLKEY_F2, KEY_IGN, SLKEY_UP,
-+KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_2ND, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_F5, SLKEY_DOLLAR, SLKEY_SPACE, SLKEY_ASCIITILDE, SLKEY_MAIL, SLKEY_LEFT, SLKEY_DOWN,
-+SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN
-+};
-
- static unsigned char rawkeytable_table_NumlockUpper[(NR_KEYCODES+1)] = {
--KEY_IGN,KEY_IGN,SLKEY_W,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_K,SLKEY_BACK_SPACE,SLKEY_P,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_OFF,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Q,SLKEY_E,SLKEY_T,SLKEY_Y,KEY_IGN,SLKEY_O,SLKEY_I,SLKEY_COMMA,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_RECORDER,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_A,SLKEY_D,SLKEY_G,SLKEY_U,KEY_IGN,SLKEY_L,SLKEY_ENTER,SLKEY_PERIOD,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_SYNCSTART,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Z,SLKEY_C,SLKEY_V,SLKEY_J,SLKEY_CONTACTS,SLKEY_F9,SLKEY_F11,SLKEY_F4,SLKEY_LSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_S,SLKEY_R,SLKEY_B,SLKEY_N,SLKEY_ACTIVITY,SLKEY_HOME,SLKEY_MINUS,SLKEY_FRONTLIGHT,KEY_IGN,SLKEY_RSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_TAB,SLKEY_SLASH,SLKEY_H,SLKEY_M,SLKEY_F2,KEY_IGN,SLKEY_UP,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_2ND,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_X,SLKEY_F,SLKEY_SPACE,SLKEY_APOSTROPHE,SLKEY_MAIL,SLKEY_LEFT,SLKEY_DOWN,SLKEY_RIGHT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN};
-+KEY_IGN, KEY_IGN, SLKEY_2, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_ASTERISK, SLKEY_BACK_SPACE,
-+SLKEY_0, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_OFF, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_1, SLKEY_3, SLKEY_5, SLKEY_6, KEY_IGN, SLKEY_9, SLKEY_8,
-+SLKEY_PARENRIGHT, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_RECORDER, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_EXCLAM, SLKEY_NUMBERSIGN, SLKEY_PERCENT, SLKEY_7, KEY_IGN, SLKEY_PARENLEFT,SLKEY_GREATER,
-+SLKEY_LESS, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_SYNCSTART, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_F10, SLKEY_F6, SLKEY_F7, SLKEY_AMPERSAND, SLKEY_CONTACTS, SLKEY_F9, SLKEY_F11,
-+SLKEY_F4, SLKEY_LSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_AT, SLKEY_4, SLKEY_MINUS, SLKEY_PLUS, SLKEY_ACTIVITY, SLKEY_HOME, SLKEY_MINUS,
-+SLKEY_FRONTLIGHT, KEY_IGN, SLKEY_RSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_TAB, SLKEY_QUESTION, SLKEY_ASCIICIRCUM, SLKEY_EQUAL, SLKEY_F2, KEY_IGN, SLKEY_UP,
-+KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_2ND, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_F5, SLKEY_DOLLAR, SLKEY_SPACE, SLKEY_ASCIITILDE, SLKEY_MAIL, SLKEY_LEFT, SLKEY_DOWN,
-+SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN
-+};
-
- static unsigned char rawkeytable_table_Num2ndLower[(NR_KEYCODES+1)] = {
--KEY_IGN,KEY_IGN,SLKEY_W,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_K,SLKEY_BACK_SPACE,SLKEY_P,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_OFF,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Q,SLKEY_E,SLKEY_T,SLKEY_Y,KEY_IGN,SLKEY_O,SLKEY_I,SLKEY_COMMA,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_RECORDER,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_A,SLKEY_D,SLKEY_G,SLKEY_U,KEY_IGN,SLKEY_L,SLKEY_ENTER,SLKEY_PERIOD,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_SYNCSTART,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Z,SLKEY_C,SLKEY_V,SLKEY_J,SLKEY_CONTACTS,SLKEY_F9,SLKEY_F11,SLKEY_F4,SLKEY_LSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_S,SLKEY_R,SLKEY_B,SLKEY_N,SLKEY_ACTIVITY,SLKEY_HOME,SLKEY_MINUS,SLKEY_FRONTLIGHT,KEY_IGN,SLKEY_RSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_TAB,SLKEY_SLASH,SLKEY_H,SLKEY_M,SLKEY_F2,KEY_IGN,SLKEY_UP,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_2ND,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_X,SLKEY_F,SLKEY_SPACE,SLKEY_APOSTROPHE,SLKEY_MAIL,SLKEY_LEFT,SLKEY_DOWN,SLKEY_RIGHT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN};
-+KEY_IGN, KEY_IGN, SLKEY_W, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_K, SLKEY_DELETE,
-+SLKEY_P, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_OFF, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_Q, SLKEY_E, SLKEY_T, SLKEY_Y, KEY_IGN, SLKEY_O, SLKEY_I,
-+SLKEY_COMMA, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_RECORDER, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_A, SLKEY_D, SLKEY_G, SLKEY_U, KEY_IGN, SLKEY_L, SLKEY_ENTER,
-+SLKEY_PERIOD, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_SYNCSTART,KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_Z, SLKEY_F6, SLKEY_F7, SLKEY_J, SLKEY_CONTACTS, SLKEY_F9, SLKEY_F11,
-+SLKEY_F4, SLKEY_LSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_S, SLKEY_R, SLKEY_B, SLKEY_N, SLKEY_ACTIVITY, SLKEY_HOME,SLKEY_MINUS,
-+SLKEY_FRONTLIGHT,KEY_IGN, SLKEY_RSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_CAPS_LOCK, SLKEY_NUMLOCK, SLKEY_H, SLKEY_M, SLKEY_F2, KEY_IGN, SLKEY_UP,
-+KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_2ND, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_F5, SLKEY_F, SLKEY_SYM, SLKEY_APOSTROPHE,SLKEY_MAIL, SLKEY_LEFT,SLKEY_DOWN,
-+SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN
-+};
-
- static unsigned char rawkeytable_table_Num2ndUpper[(NR_KEYCODES+1)] = {
--KEY_IGN,KEY_IGN,SLKEY_W,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_K,SLKEY_BACK_SPACE,SLKEY_P,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_OFF,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Q,SLKEY_E,SLKEY_T,SLKEY_Y,KEY_IGN,SLKEY_O,SLKEY_I,SLKEY_COMMA,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_RECORDER,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_A,SLKEY_D,SLKEY_G,SLKEY_U,KEY_IGN,SLKEY_L,SLKEY_ENTER,SLKEY_PERIOD,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_SYNCSTART,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_Z,SLKEY_PRINTSCREEN,SLKEY_V,SLKEY_J,SLKEY_CONTACTS,SLKEY_F9,SLKEY_F11,SLKEY_F4,SLKEY_LSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_S,SLKEY_R,SLKEY_B,SLKEY_N,SLKEY_ACTIVITY,SLKEY_HOME,SLKEY_MINUS,SLKEY_FRONTLIGHT,KEY_IGN,SLKEY_RSHIFT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_TAB,SLKEY_SLASH,SLKEY_H,SLKEY_M,SLKEY_F2,KEY_IGN,SLKEY_UP,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_2ND,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,SLKEY_X,SLKEY_F,SLKEY_SPACE,SLKEY_APOSTROPHE,SLKEY_MAIL,SLKEY_LEFT,SLKEY_DOWN,SLKEY_RIGHT,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN,KEY_IGN};
-+KEY_IGN, KEY_IGN, SLKEY_W, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_K, SLKEY_DELETE,
-+SLKEY_P, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_OFF, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_Q, SLKEY_E, SLKEY_T, SLKEY_Y, KEY_IGN, SLKEY_O, SLKEY_I,
-+SLKEY_SEMICOLON,KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_RECORDER, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_A, SLKEY_D, SLKEY_G, SLKEY_U, KEY_IGN, SLKEY_L, SLKEY_ENTER,
-+SLKEY_COLON, KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_SYNCSTART,KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_Z, SLKEY_F6, SLKEY_F7, SLKEY_J, SLKEY_CONTACTS, SLKEY_F9, SLKEY_F11,
-+SLKEY_F4, SLKEY_LSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_S, SLKEY_R, SLKEY_B, SLKEY_N, SLKEY_ACTIVITY, SLKEY_HOME,SLKEY_MINUS,
-+SLKEY_FRONTLIGHT,KEY_IGN, SLKEY_RSHIFT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_CAPS_LOCK, SLKEY_NUMLOCK, SLKEY_H, SLKEY_M, SLKEY_F2, KEY_IGN, SLKEY_UP,
-+KEY_IGN, KEY_IGN, KEY_IGN, SLKEY_2ND, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, SLKEY_F5, SLKEY_F, SLKEY_SYM, SLKEY_QUOTEDBL, SLKEY_MAIL, SLKEY_LEFT,SLKEY_DOWN,
-+SLKEY_RIGHT, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN,
-+KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN, KEY_IGN
-+};
-
-
-
-@@ -334,7 +462,87 @@
-
-
- static unsigned char *state_to_keymap[STATE_NUMS_TOTAL] = {
--rawkeytable_table_NormalLower,rawkeytable_table_NormalUpper,rawkeytable_table_2ndLower,rawkeytable_table_2ndUpper,rawkeytable_table_2ndLower,rawkeytable_table_2ndUpper,rawkeytable_table_2ndLower,rawkeytable_table_2ndUpper,rawkeytable_table_2ndLower,rawkeytable_table_2ndUpper,rawkeytable_table_NormalLower,rawkeytable_table_NormalUpper,rawkeytable_table_2ndLower,rawkeytable_table_2ndUpper,rawkeytable_table_2ndLower,rawkeytable_table_2ndUpper,rawkeytable_table_2ndLower,rawkeytable_table_2ndUpper,rawkeytable_table_2ndLower,rawkeytable_table_2ndUpper,rawkeytable_table_NumlockLower,rawkeytable_table_NumlockUpper,rawkeytable_table_Num2ndLower,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndLower,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndLower,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndLower,rawkeytable_table_Num2ndUpper,rawkeytable_table_NumlockLower,rawkeytable_table_NumlockUpper,rawkeytable_table_Num2ndLower,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndLower,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndLower,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndLower,rawkeytable_table_Num2ndUpper,rawkeytable_table_NormalUpper,rawkeytable_table_NormalUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_NormalUpper,rawkeytable_table_NormalUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_2ndUpper,rawkeytable_table_NumlockUpper,rawkeytable_table_NumlockUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_NumlockUpper,rawkeytable_table_NumlockUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper,rawkeytable_table_Num2ndUpper};
-+rawkeytable_table_NormalLower, /*S0*/
-+rawkeytable_table_NormalUpper, /*S1*/
-+rawkeytable_table_2ndLower, /*S2*/
-+rawkeytable_table_2ndUpper, /*S3*/
-+rawkeytable_table_2ndLower, /*S4*/
-+rawkeytable_table_2ndUpper, /*S5*/
-+rawkeytable_table_2ndLower, /*S6*/
-+rawkeytable_table_2ndUpper, /*S7*/
-+rawkeytable_table_2ndLower, /*S8*/
-+rawkeytable_table_2ndUpper, /*S9*/
-+rawkeytable_table_NormalLower, /*S10*/
-+rawkeytable_table_NormalUpper, /*S11*/
-+rawkeytable_table_2ndLower, /*S12*/
-+rawkeytable_table_2ndUpper, /*S13*/
-+rawkeytable_table_2ndLower, /*S14*/
-+rawkeytable_table_2ndUpper, /*S15*/
-+rawkeytable_table_2ndLower, /*S16*/
-+rawkeytable_table_2ndUpper, /*S17*/
-+rawkeytable_table_2ndLower, /*S18*/
-+rawkeytable_table_2ndUpper, /*S19*/
-+rawkeytable_table_NumlockLower, /*S20*/
-+rawkeytable_table_NumlockUpper, /*S21*/
-+rawkeytable_table_Num2ndLower, /*S22*/
-+rawkeytable_table_Num2ndUpper, /*S23*/
-+rawkeytable_table_Num2ndLower, /*S24*/
-+rawkeytable_table_Num2ndUpper, /*S25*/
-+rawkeytable_table_Num2ndLower, /*S26*/
-+rawkeytable_table_Num2ndUpper, /*S27*/
-+rawkeytable_table_Num2ndLower, /*S28*/
-+rawkeytable_table_Num2ndUpper, /*S29*/
-+rawkeytable_table_NumlockLower, /*S30*/
-+rawkeytable_table_NumlockUpper, /*S31*/
-+rawkeytable_table_Num2ndLower, /*S32*/
-+rawkeytable_table_Num2ndUpper, /*S33*/
-+rawkeytable_table_Num2ndLower, /*S34*/
-+rawkeytable_table_Num2ndUpper, /*S35*/
-+rawkeytable_table_Num2ndLower, /*S36*/
-+rawkeytable_table_Num2ndUpper, /*S37*/
-+rawkeytable_table_Num2ndLower, /*S38*/
-+rawkeytable_table_Num2ndUpper, /*S39*/
-+rawkeytable_table_NormalUpper, /*S40*/
-+rawkeytable_table_NormalUpper, /*S41*/
-+rawkeytable_table_2ndUpper, /*S42*/
-+rawkeytable_table_2ndUpper, /*S43*/
-+rawkeytable_table_2ndUpper, /*S44*/
-+rawkeytable_table_2ndUpper, /*S45*/
-+rawkeytable_table_2ndUpper, /*S46*/
-+rawkeytable_table_2ndUpper, /*S47*/
-+rawkeytable_table_2ndUpper, /*S48*/
-+rawkeytable_table_2ndUpper, /*S49*/
-+rawkeytable_table_NormalUpper, /*S50*/
-+rawkeytable_table_NormalUpper, /*S51*/
-+rawkeytable_table_2ndUpper, /*S52*/
-+rawkeytable_table_2ndUpper, /*S53*/
-+rawkeytable_table_2ndUpper, /*S54*/
-+rawkeytable_table_2ndUpper, /*S55*/
-+rawkeytable_table_2ndUpper, /*S56*/
-+rawkeytable_table_2ndUpper, /*S57*/
-+rawkeytable_table_2ndUpper, /*S58*/
-+rawkeytable_table_2ndUpper, /*S59*/
-+rawkeytable_table_NumlockUpper, /*S60*/
-+rawkeytable_table_NumlockUpper, /*S61*/
-+rawkeytable_table_Num2ndUpper, /*S62*/
-+rawkeytable_table_Num2ndUpper, /*S63*/
-+rawkeytable_table_Num2ndUpper, /*S64*/
-+rawkeytable_table_Num2ndUpper, /*S65*/
-+rawkeytable_table_Num2ndUpper, /*S66*/
-+rawkeytable_table_Num2ndUpper, /*S67*/
-+rawkeytable_table_Num2ndUpper, /*S68*/
-+rawkeytable_table_Num2ndUpper, /*S69*/
-+rawkeytable_table_NumlockUpper, /*S70*/
-+rawkeytable_table_NumlockUpper, /*S71*/
-+rawkeytable_table_Num2ndUpper, /*S72*/
-+rawkeytable_table_Num2ndUpper, /*S73*/
-+rawkeytable_table_Num2ndUpper, /*S74*/
-+rawkeytable_table_Num2ndUpper, /*S75*/
-+rawkeytable_table_Num2ndUpper, /*S76*/
-+rawkeytable_table_Num2ndUpper, /*S77*/
-+rawkeytable_table_Num2ndUpper, /*S78*/
-+rawkeytable_table_Num2ndUpper /*S79*/
-+};
-
-
- #endif /* ! __KEYTABLE_H_INCLUDED__ */
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/tosa_ts.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/tosa_ts.patch
deleted file mode 100644
index 678cb2e25b..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/tosa_ts.patch
+++ /dev/null
@@ -1,207 +0,0 @@
-
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- linux/drivers/char/tosa_ts.c~tosa_ts.patch
-+++ linux/drivers/char/tosa_ts.c
-@@ -102,6 +102,8 @@
- static int head = 0, tail = 0;
-
- #ifdef CONFIG_PM
-+#include <linux/pm.h>
-+static struct pm_dev* tosa_ts_pm_dev;
- static int tp_suspend = 0;
- #endif /* CONFIG_PM */
-
-@@ -495,25 +497,6 @@
- ioctl: ts_ioctl,
- };
-
--static void ts_exit(void)
--{
-- ts_timer_clear();
-- ts_clear();
-- free_irq(IRQ_GPIO_TP_INT, NULL);
-- wm9712_power_mode_ts(WM9712_PWR_OFF);
--
-- pxa_ac97_put(&ac97_on);
--}
--
--#ifdef MODULE
--static void __exit ac97_ts_cleanup(void)
--{
-- ts_exit();
-- unregister_chrdev(TS_MAJOR, "ts");
--}
--module_exit(ac97_ts_cleanup);
--#endif /* MODULE */
--
- extern int tc6393fb_lcdMode;
-
- int ac97_ad_input(int ch, unsigned short *dat)
-@@ -608,7 +591,7 @@
- #endif
- }
-
--static int ts_init(void)
-+static int tosa_ts_hardware_start(void)
- {
- pxa_ac97_get(&codec, &ac97_on);
-
-@@ -625,7 +608,6 @@
- /* GPIO3/PENDOWN wakeup */
- ac97_bit_set(AC97_GPIO_WAKE_UP, CODEC_PENDOWN);
-
-- ts_clear();
-
- /* Init queue */
- //X kernel_thread(ts_pendown, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
-@@ -639,12 +621,39 @@
- return -EBUSY;
- }
-
-- // printk(KERN_INFO "Tosa Touch Screen driver initialized\n");
--
- return 0;
- }
-
--static int __init ac97_ts_init(void)
-+static void tosa_ts_hardware_stop(void)
-+{
-+ ts_timer_clear();
-+ ts_clear();
-+ free_irq(IRQ_GPIO_TP_INT, NULL);
-+ wm9712_power_mode_ts(WM9712_PWR_OFF);
-+
-+ pxa_ac97_put(&ac97_on);
-+}
-+
-+#ifdef CONFIG_PM
-+static int tosa_ts_pm_callback(struct pm_dev *pm_dev,
-+ pm_request_t req, void *data)
-+{
-+ switch (req) {
-+ case PM_SUSPEND:
-+ tp_suspend = 1;
-+ tosa_ts_hardware_stop();
-+ break;
-+ case PM_RESUME:
-+ tp_suspend = 0;
-+ tosa_ts_hardware_start();
-+ break;
-+ }
-+ return 0;
-+}
-+#endif
-+
-+
-+static int __init tosa_ts_init(void)
- {
- ac97_on = 0;
-
-@@ -663,28 +672,37 @@
-
- if( register_chrdev(TS_MAJOR,DEV_NAME, &ts_fops) ) {
- printk("unable to get major %d for touch screen\n", TS_MAJOR);
-- ts_exit();
- }
-
- init_procinfo();
-
-+ tosa_ts_hardware_start();
-+
-+#ifdef CONFIG_PM
-+ tosa_ts_pm_dev = pm_register(PM_SYS_DEV, 0, tosa_ts_pm_callback);
-+#endif
-+
- kernel_thread(ts_pendown, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
-
- return 0;
- }
-
--module_init(ac97_ts_init);
-+static int __exit tosa_ts_cleanup()
-+{
-+ tosa_hardware_stop();
-+ pm_unregister(tosa_ts_pm_dev);
-+ unregister_chrdev(TS_MAJOR, "ts");
-+}
-+
-+module_init(tosa_ts_init);
-+module_exit(tosa_ts_cleanup);
-
- /*
- * Driver functions
- */
- static int ts_open(struct inode *inode, struct file *file)
- {
-- if( ts_init() < 0 ) {
-- ts_exit();
-- return -EINVAL;
-- }
--
-+ ts_clear();
- MOD_INC_USE_COUNT;
- return 0;
- }
-@@ -692,7 +710,6 @@
-
- static int ts_release(struct inode *inode, struct file *file)
- {
-- ts_exit();
-
- MOD_DEC_USE_COUNT;
- return 0;
-@@ -788,20 +805,3 @@
- return 0;
- }
-
--#ifdef CONFIG_PM
--void tosa_ts_suspend(void)
--{
-- DEBUG(DBG_L1, "in\n");
-- tp_suspend = 1;
-- ts_exit();
-- DEBUG(DBG_L1, "out\n");
--}
--
--void tosa_ts_resume(void)
--{
-- DEBUG(DBG_L1, "in\n");
-- tp_suspend = 0;
-- ts_init();
-- DEBUG(DBG_L1, "out\n");
--}
--#endif /* CONFIG_PM */
---- linux/drivers/sound/pxa-ac97_tosa.c~tosa_ts.patch
-+++ linux/drivers/sound/pxa-ac97_tosa.c
-@@ -90,8 +90,6 @@
- #include <linux/pm.h>
- static struct pm_dev* pxa_sound_pm_dev;
- static int tosa_pm_callback(struct pm_dev *,pm_request_t, void *);
--extern void tosa_ts_suspend(void);
--extern void tosa_ts_resume(void);
- #endif /* CONFIG_PM */
-
- /************************************************************
-@@ -2195,9 +2193,6 @@
- case PM_SUSPEND:
- DEBUG(DBG_L1, "PM_SUSPEND: start\n");
- wm9712_suspend();
--#ifdef CONFIG_TOSA_TS
-- tosa_ts_suspend();
--#endif /* CONFIG_TOSA_TS */
- if ( ac97_audio_state.rd_ref != 0 ) {
- audio_clear_buf(ac97_audio_state.input_stream);
- *ac97_audio_state.input_stream->drcmr = 0;
-@@ -2239,9 +2234,6 @@
- ac97_audio_state.input_stream->dma_ch = err;
- }
- wm9712_resume();
--#ifdef CONFIG_TOSA_TS
-- tosa_ts_resume();
--#endif /* CONFIG_TOSA_TS */
- DEBUG(DBG_L1, "PM_RESUME: done\n");
- break;
- }
diff --git a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/usb-storage.patch b/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/usb-storage.patch
deleted file mode 100644
index c9296cf224..0000000000
--- a/linux/openzaurus-pxa-2.4.18-rmk7-pxa3-embedix20031107/usb-storage.patch
+++ /dev/null
@@ -1,3433 +0,0 @@
-diff -Nur linux-2.4.18/drivers/usb/device/bi/sa1100.c linux-2.4.18-usb-storage/drivers/usb/device/bi/sa1100.c
---- linux-2.4.18/drivers/usb/device/bi/sa1100.c 2003-05-13 13:18:44.000000000 +0400
-+++ linux-2.4.18-usb-storage/drivers/usb/device/bi/sa1100.c 2004-03-01 07:20:38.000000000 +0300
-@@ -440,6 +440,7 @@
- udc_interrupts, *(UDCSR), *(UDCCS0), *(UDCAR));
-
- usbd_device_event (udc_device, DEVICE_RESET, 0);
-+ usbd_device_event (udc_device, DEVICE_ADDRESS_ASSIGNED,0);
- }
-
- if (status & UDCSR_SUSIR) {
-diff -Nur linux-2.4.18/drivers/usb/device/Config.in linux-2.4.18-usb-storage/drivers/usb/device/Config.in
---- linux-2.4.18/drivers/usb/device/Config.in 2003-05-13 13:18:45.000000000 +0400
-+++ linux-2.4.18-usb-storage/drivers/usb/device/Config.in 2003-11-07 05:35:14.000000000 +0300
-@@ -34,6 +34,7 @@
- comment 'USB Device functions'
- source drivers/usb/device/net_fd/Config.in
- source drivers/usb/device/serial_fd/Config.in
-+ source drivers/usb/device/storage_fd/Config.in
-
- comment 'USB Device bus interfaces'
- source drivers/usb/device/bi/Config.in
-diff -Nur linux-2.4.18/drivers/usb/device/Makefile linux-2.4.18-usb-storage/drivers/usb/device/Makefile
---- linux-2.4.18/drivers/usb/device/Makefile 2003-05-13 13:18:45.000000000 +0400
-+++ linux-2.4.18-usb-storage/drivers/usb/device/Makefile 2003-11-07 05:35:01.000000000 +0300
-@@ -20,6 +20,7 @@
-
- subdir-$(CONFIG_USBD_NET) += net_fd
- subdir-$(CONFIG_USBD_SERIAL) += serial_fd
-+subdir-$(CONFIG_USBD_STORAGE) += storage_fd
-
- #subdir-$(CONFIG_USBD_GENERIC_BUS) += gen_bi
- #subdir-$(CONFIG_USBD_L7205_BUS) += l7205_bi
-diff -Nur linux-2.4.18/drivers/usb/device/storage_fd/Config.help linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/Config.help
---- linux-2.4.18/drivers/usb/device/storage_fd/Config.help 1970-01-01 03:00:00.000000000 +0300
-+++ linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/Config.help 2003-11-07 05:34:43.000000000 +0300
-@@ -0,0 +1,55 @@
-+CONFIG_USBD_STORAGE
-+ Enable the generic mass storage function driver. This function is
-+ used emulating a Linux block driver.
-+
-+CONFIG_USBD_STORAGE_VENDORID
-+ Optionally specify the mass storage USB Device Vendor ID. The top
-+ level Vendor ID will be used if this is not specified.
-+
-+CONFIG_USBD_STORAGE_PRODUCTID
-+ Optionally specify the mass storage USB Device Product ID. The top
-+ level Vendor ID will be used if this is not specified.
-+
-+CONFIG_USBD_STORAGE_OUT_ENDPOINT
-+ Specify the preferred OUT (received data) endpoint number. This is a
-+ number from 0-15 and must be allowed by the bus interface device.
-+
-+ Some devices such as the SA-1110 or L7205/L7210 may override this
-+ value with a fixed value.
-+
-+CONFIG_USBD_STORAGE_IN_ENDPOINT
-+ Specify the preferred IN (transmit data) endpoint number. This is a
-+ number from 0-15 and must be allowed by the bus interface device.
-+
-+ Some devices such as the SA-1110 or L7205/L7210 may override this
-+ value with a fixed value.
-+
-+CONFIG_USBD_STORAGE_INT_ENDPOINT
-+ Specify the preferred INT (interrupt) endpoint number. This is a
-+ number from 0-15 and must be allowed by the bus interface device.
-+
-+ Some devices such as the L7205/L7210 may override this value with a
-+ fixed value. Others such as the SA-1110 do not allow an interrupt
-+ value.
-+
-+CONFIG_USBD_STORAGE_OUT_PKTSIZE
-+ Specify the maximum packet size for the OUT endpoint. This allowable
-+ values are normally 16, 32 and 64.
-+
-+ Some devices such as the Linkup L7205/L7210 may override this value
-+ with a lower maximum value (such as 32).
-+
-+CONFIG_USBD_STORAGE_IN_PKTSIZE
-+ Specify the maximum packet size for the IN endpoint. This allowable
-+ values are normally 16, 32 and 64.
-+
-+ Some devices such as the Linkup L7205/L7210 may override this value
-+ with a lower maximum value (such as 32).
-+
-+CONFIG_USBD_STORAGE_INT_PKTSIZE
-+ Specify the maximum packet size for the INT endpoint. This allowable
-+ values are normally 8 and 16. Some bus interface devices may not
-+ support all values.
-+
-+CONFIG_USBD_STORAGE_DEF_DEVICE_NAME
-+ Specify the default block device name to used on mass storage.
-diff -Nur linux-2.4.18/drivers/usb/device/storage_fd/Config.in linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/Config.in
---- linux-2.4.18/drivers/usb/device/storage_fd/Config.in 1970-01-01 03:00:00.000000000 +0300
-+++ linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/Config.in 2003-11-07 05:34:43.000000000 +0300
-@@ -0,0 +1,29 @@
-+#
-+# Generic Mass Storage Function Driver
-+#
-+# Copyright (c) 2003 Communication Technology Inc.
-+# Copyright (C) 2001 Lineo, Inc.
-+# Copyright (C) 2001 Hewlett-Packard Co.
-+mainmenu_option next_comment
-+comment "Mass Storage Function"
-+
-+dep_tristate ' Mass Storage Function Driver' CONFIG_USBD_STORAGE $CONFIG_USBD
-+if [ "$CONFIG_USBD_STORAGE" = "y" -o "$CONFIG_USBD_STORAGE" = "m" ]; then
-+ hex ' Overide VendorID (hex value)' CONFIG_USBD_STORAGE_VENDORID "0000"
-+ hex ' Overide ProductID (hex value)' CONFIG_USBD_STORAGE_PRODUCTID "0000"
-+
-+ # allow setting of endpoint configurations for some architectures
-+ int ' OUT Endpoint (0-15)' CONFIG_USBD_STORAGE_OUT_ENDPOINT "1"
-+ int ' OUT PacketSize (16, 32, 64)' CONFIG_USBD_STORAGE_OUT_PKTSIZE "64"
-+ int ' IN Endpoint (0-15)' CONFIG_USBD_STORAGE_IN_ENDPOINT "2"
-+ int ' IN PacketSize (16, 32, 64)' CONFIG_USBD_STORAGE_IN_PKTSIZE "64"
-+
-+ if [ ! "$CONFIG_ARCH_SA1100" = "y" -a ! "$CONFIG_ARCH_L7200" = "y" ]; then
-+ int ' INT Endpoint (0-15)' CONFIG_USBD_STORAGE_INT_ENDPOINT "3"
-+ int ' INT PacketSize (8, 16)' CONFIG_USBD_STORAGE_INT_PKTSIZE "16"
-+ fi
-+
-+ string ' Default Mass Storage device name' CONFIG_USBD_STORAGE_DEF_DEVICE_NAME ""
-+fi
-+
-+endmenu
-diff -Nur linux-2.4.18/drivers/usb/device/storage_fd/Makefile linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/Makefile
---- linux-2.4.18/drivers/usb/device/storage_fd/Makefile 1970-01-01 03:00:00.000000000 +0300
-+++ linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/Makefile 2003-11-07 05:34:43.000000000 +0300
-@@ -0,0 +1,58 @@
-+#
-+# SA1100 Function driver for a network USB Device
-+#
-+# Copyright (C) 2001 Lineo, Inc.
-+# Copyright (C) 2001 Hewlett-Packard Co.
-+
-+
-+O_TARGET := storage_fd_drv.o
-+list-multi := storage_fd.o
-+
-+storage_fd-objs := storage-fd.o storageproto.o schedule_task.o # netproto.o crc32.o
-+
-+# Object file lists.
-+
-+obj-y :=
-+obj-m :=
-+obj-n :=
-+obj- :=
-+
-+# Each configuration option enables a list of files.
-+
-+obj-$(CONFIG_USBD_STORAGE) += storage_fd.o
-+
-+# Extract lists of the multi-part drivers.
-+# The 'int-*' lists are the intermediate files used to build the multi's.
-+
-+multi-y := $(filter $(list-multi), $(obj-y))
-+multi-m := $(filter $(list-multi), $(obj-m))
-+int-y := $(sort $(foreach m, $(multi-y), $($(basename $(m))-objs)))
-+int-m := $(sort $(foreach m, $(multi-m), $($(basename $(m))-objs)))
-+
-+# Files that are both resident and modular: remove from modular.
-+
-+obj-m := $(filter-out $(obj-y), $(obj-m))
-+int-m := $(filter-out $(int-y), $(int-m))
-+
-+# Translate to Rules.make lists.
-+
-+O_OBJS := $(filter-out $(export-objs), $(obj-y))
-+OX_OBJS := $(filter $(export-objs), $(obj-y))
-+M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
-+MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
-+MI_OBJS := $(sort $(filter-out $(export-objs), $(int-m)))
-+MIX_OBJS := $(sort $(filter $(export-objs), $(int-m)))
-+
-+# The global Rules.make.
-+
-+include $(TOPDIR)/Rules.make
-+
-+# Link rules for multi-part drivers.
-+
-+storage_fd.o: $(storage_fd-objs)
-+ $(LD) -r -o $@ $(storage_fd-objs)
-+
-+# dependencies:
-+
-+storage-fd.o: ../usbd.h ../usbd-bus.h ../usbd-func.h
-+
-diff -Nur linux-2.4.18/drivers/usb/device/storage_fd/schedule_task.c linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/schedule_task.c
---- linux-2.4.18/drivers/usb/device/storage_fd/schedule_task.c 1970-01-01 03:00:00.000000000 +0300
-+++ linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/schedule_task.c 2003-11-07 05:34:43.000000000 +0300
-@@ -0,0 +1,230 @@
-+/*
-+ * linux/drivers/usb/device/storage_fd/schedule_task.c - schedule task library
-+ *
-+ * Copyright (c) 2003 Lineo Solutions, Inc.
-+ *
-+ * Written by Shunnosuke kabata
-+ *
-+ * 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 File
-+******************************************************************************/
-+#include <linux/config.h>
-+#include <linux/fs.h>
-+#include <linux/string.h>
-+#include <linux/mm.h>
-+#include <linux/dcache.h>
-+#include <linux/init.h>
-+#include <linux/quotaops.h>
-+#include <linux/slab.h>
-+#include <linux/cache.h>
-+#include <linux/swap.h>
-+#include <linux/swapctl.h>
-+#include <linux/prefetch.h>
-+#include <linux/locks.h>
-+#include <asm/uaccess.h>
-+
-+#include "schedule_task.h"
-+
-+/******************************************************************************
-+** Macro Define
-+******************************************************************************/
-+#define TASK_DESC_NUM (512)
-+
-+/******************************************************************************
-+** Structure Define
-+******************************************************************************/
-+
-+/**************************************
-+** TASK_DESC
-+**************************************/
-+typedef struct _TASK_DESC{
-+ struct _TASK_DESC* next;
-+ SCHEDULE_TASK_FUNC task_entry;
-+ int task_param1;
-+ int task_param2;
-+ int task_param3;
-+ int task_param4;
-+ int task_param5;
-+ char* file;
-+ int line;
-+} TASK_DESC;
-+
-+/**************************************
-+** OS_WRP_TASK_DATA
-+**************************************/
-+typedef struct{
-+ volatile TASK_DESC* read_desc;
-+ volatile TASK_DESC* write_desc;
-+ TASK_DESC desc_pool[TASK_DESC_NUM];
-+ spinlock_t spin_lock;
-+ struct tq_struct task_que;
-+ unsigned long use_num;
-+ unsigned long max_num;
-+} TASK_DATA;
-+
-+/******************************************************************************
-+** Variable Declaration
-+******************************************************************************/
-+static TASK_DATA TaskData;
-+
-+/******************************************************************************
-+** Local Function Prototype
-+******************************************************************************/
-+static void task_entry(void*);
-+
-+/******************************************************************************
-+** Global Function
-+******************************************************************************/
-+void schedule_task_init(void)
-+{
-+ int i;
-+
-+ /* 0 clear */
-+ memset(&TaskData, 0x00, sizeof(TaskData));
-+
-+ /* Read/write pointer initialize */
-+ TaskData.read_desc = TaskData.write_desc = &TaskData.desc_pool[0];
-+
-+ /* Ling buffer initialize */
-+ for(i=0; i<(TASK_DESC_NUM-1); i++){
-+ TaskData.desc_pool[i].next = &TaskData.desc_pool[i+1];
-+ }
-+ TaskData.desc_pool[i].next = &TaskData.desc_pool[0];
-+
-+ /* Spin lock initialize */
-+ spin_lock_init(&TaskData.spin_lock);
-+
-+ /* Task queue initialize */
-+ PREPARE_TQUEUE(&TaskData.task_que, task_entry, &TaskData);
-+
-+ return;
-+}
-+
-+int schedule_task_register(SCHEDULE_TASK_FUNC entry, int param1, int param2,
-+ int param3, int param4, int param5)
-+{
-+ unsigned long flags = 0;
-+
-+ spin_lock_irqsave(&TaskData.spin_lock, flags);
-+
-+ /* Free descriptor check */
-+ if(TaskData.write_desc->next == TaskData.read_desc){
-+ printk(KERN_INFO "storage_fd: schedule task no descriptor.\n");
-+ spin_unlock_irqrestore(&TaskData.spin_lock, flags);
-+ return -1;
-+ }
-+
-+ /* Descriptor set */
-+ TaskData.write_desc->task_entry = entry;
-+ TaskData.write_desc->task_param1 = param1;
-+ TaskData.write_desc->task_param2 = param2;
-+ TaskData.write_desc->task_param3 = param3;
-+ TaskData.write_desc->task_param4 = param4;
-+ TaskData.write_desc->task_param5 = param5;
-+
-+ /* Pointer update */
-+ TaskData.write_desc = TaskData.write_desc->next;
-+
-+ /* Statistics set */
-+ TaskData.use_num++;
-+ if(TaskData.use_num > TaskData.max_num){
-+ TaskData.max_num = TaskData.use_num;
-+ }
-+
-+ spin_unlock_irqrestore(&TaskData.spin_lock, flags);
-+
-+ /* Task queue register */
-+ schedule_task(&TaskData.task_que);
-+
-+ return 0;
-+}
-+
-+void schedule_task_all_unregister(void)
-+{
-+ unsigned long flags = 0;
-+
-+ spin_lock_irqsave(&TaskData.spin_lock, flags);
-+ TaskData.read_desc = TaskData.write_desc;
-+ TaskData.use_num = 0;
-+ spin_unlock_irqrestore(&TaskData.spin_lock, flags);
-+}
-+
-+ssize_t schedule_task_proc_read(struct file* file, char* buf, size_t count,
-+ loff_t* pos)
-+{
-+ char string[1024];
-+ int len = 0;
-+
-+ len += sprintf(string + len, "Schedule task max num:0x%d\n",
-+ TASK_DESC_NUM);
-+
-+ len += sprintf(string + len, "Schedule task use num:0x%ld\n",
-+ TaskData.use_num);
-+
-+ len += sprintf(string + len, "Schedule task max use num:0x%ld\n",
-+ TaskData.max_num);
-+
-+ *pos += len;
-+ if(len > count){
-+ len = -EINVAL;
-+ }
-+ else
-+ if(len > 0 && copy_to_user(buf, string, len)) {
-+ len = -EFAULT;
-+ }
-+
-+ return len;
-+}
-+
-+/******************************************************************************
-+** Local Function
-+******************************************************************************/
-+static void task_entry(void* data)
-+{
-+ int cond;
-+ unsigned long flags = 0;
-+ volatile TASK_DESC* desc;
-+
-+ for(;;){
-+
-+ spin_lock_irqsave(&TaskData.spin_lock, flags);
-+ desc = TaskData.read_desc;
-+ cond = (TaskData.read_desc == TaskData.write_desc);
-+ spin_unlock_irqrestore(&TaskData.spin_lock, flags);
-+
-+ if(cond) break;
-+
-+ /* Task call */
-+ desc->task_entry(desc->task_param1, desc->task_param2,
-+ desc->task_param3, desc->task_param4, desc->task_param5);
-+
-+ spin_lock_irqsave(&TaskData.spin_lock, flags);
-+
-+ /* Pointer update */
-+ TaskData.read_desc = TaskData.read_desc->next;
-+
-+ /* Statistics set */
-+ TaskData.use_num--;
-+
-+ spin_unlock_irqrestore(&TaskData.spin_lock, flags);
-+ }
-+
-+ return;
-+}
-+
-diff -Nur linux-2.4.18/drivers/usb/device/storage_fd/schedule_task.h linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/schedule_task.h
---- linux-2.4.18/drivers/usb/device/storage_fd/schedule_task.h 1970-01-01 03:00:00.000000000 +0300
-+++ linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/schedule_task.h 2003-11-07 05:34:43.000000000 +0300
-@@ -0,0 +1,41 @@
-+/*
-+ * linux/drivers/usb/device/storage_fd/schedule_task.h - schedule task library header
-+ *
-+ * Copyright (c) 2003 Lineo Solutions, Inc.
-+ *
-+ * Written by Shunnosuke kabata
-+ *
-+ * 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 _SCHEDULE_TASK_H_
-+#define _SCHEDULE_TASK_H_
-+
-+/******************************************************************************
-+** Macro Define
-+******************************************************************************/
-+typedef int (*SCHEDULE_TASK_FUNC)(int, int, int, int, int);
-+
-+/******************************************************************************
-+** Global Function Prototype
-+******************************************************************************/
-+void schedule_task_init(void);
-+int schedule_task_register(SCHEDULE_TASK_FUNC, int, int, int, int, int);
-+void schedule_task_all_unregister(void);
-+ssize_t schedule_task_proc_read(struct file*, char*, size_t, loff_t*);
-+
-+#endif /* _SCHEDULE_TASK_H_ */
-+
-diff -Nur linux-2.4.18/drivers/usb/device/storage_fd/storage-fd.c linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/storage-fd.c
---- linux-2.4.18/drivers/usb/device/storage_fd/storage-fd.c 1970-01-01 03:00:00.000000000 +0300
-+++ linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/storage-fd.c 2003-11-07 05:34:43.000000000 +0300
-@@ -0,0 +1,865 @@
-+/*
-+ * linux/drivers/usb/device/storage_fd/storage-fd.c - mass storage function driver
-+ *
-+ * Copyright (c) 2003 Lineo Solutions, Inc.
-+ *
-+ * Written by Shunnosuke kabata
-+ *
-+ * 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.
-+ *
-+ * Based on
-+ *
-+ * linux/drivers/usbd/net_fd/net-fd.c - network function driver
-+ *
-+ * Copyright (c) 2000, 2001, 2002 Lineo
-+ * Copyright (c) 2001 Hewlett Packard
-+ *
-+ * By:
-+ * Stuart Lynne <sl@lineo.com>,
-+ * Tom Rushworth <tbr@lineo.com>,
-+ * Bruce Balden <balden@lineo.com>
-+ *
-+ * 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 File
-+******************************************************************************/
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include "../usbd-export.h"
-+#include "../usbd-build.h"
-+#include "../usbd-module.h"
-+
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/list.h>
-+#include <linux/netdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/etherdevice.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/smp_lock.h>
-+#include <linux/ctype.h>
-+#include <linux/timer.h>
-+#include <linux/string.h>
-+#include <linux/atmdev.h>
-+#include <linux/pkt_sched.h>
-+#include <linux/delay.h>
-+#include <asm/uaccess.h>
-+#include <asm/system.h>
-+#include <net/arp.h>
-+
-+#include <linux/autoconf.h>
-+
-+#include "../usbd.h"
-+#include "../usbd-func.h"
-+#include "../usbd-bus.h"
-+#include "../usbd-inline.h"
-+#include "../usbd-arch.h"
-+#include "../hotplug.h"
-+
-+#include "schedule_task.h"
-+#include "storageproto.h"
-+
-+/******************************************************************************
-+** Macro Define
-+******************************************************************************/
-+
-+/**************************************
-+** Module Information
-+**************************************/
-+
-+MODULE_AUTHOR("Shunnosuke kabata");
-+MODULE_DESCRIPTION("USB Device Mass Storage Function");
-+USBD_MODULE_INFO("storage_fd 0.1");
-+
-+/**************************************
-+** Configration Check
-+**************************************/
-+
-+#if !defined (CONFIG_USBD_VENDORID) && !defined(CONFIG_USBD_STORAGE_VENDORID)
-+#error No Vendor ID
-+#endif
-+#if !defined (CONFIG_USBD_PRODUCTID) && !defined(CONFIG_USBD_STORAGE_PRODUCTID)
-+#error No Product ID
-+#endif
-+
-+#if defined(CONFIG_USBD_STORAGE_VENDORID) && (CONFIG_USBD_STORAGE_VENDORID > 0)
-+#undef CONFIG_USBD_VENDORID
-+#define CONFIG_USBD_VENDORID CONFIG_USBD_STORAGE_VENDORID
-+#endif
-+
-+#if defined(CONFIG_USBD_STORAGE_PRODUCTID) && (CONFIG_USBD_STORAGE_PRODUCTID > 0)
-+#undef CONFIG_USBD_PRODUCTID
-+#define CONFIG_USBD_PRODUCTID CONFIG_USBD_STORAGE_PRODUCTID
-+#endif
-+
-+#ifndef CONFIG_USBD_MAXPOWER
-+#define CONFIG_USBD_MAXPOWER 0
-+#endif
-+
-+#ifndef CONFIG_USBD_MANUFACTURER
-+#define CONFIG_USBD_MANUFACTURER "Sharp"
-+#endif
-+
-+#define MAXTRANSFER (512)
-+
-+#ifndef CONFIG_USBD_VENDORID
-+#error "CONFIG_USBD_VENDORID not defined"
-+#endif
-+
-+#ifndef CONFIG_USBD_PRODUCTID
-+#error "CONFIG_USBD_PRODUCTID not defined"
-+#endif
-+
-+#ifndef CONFIG_USBD_PRODUCT_NAME
-+#define CONFIG_USBD_PRODUCT_NAME "Linux Mass Storage Driver"
-+#endif
-+
-+#ifndef CONFIG_USBD_SERIAL_NUMBER_STR
-+#define CONFIG_USBD_SERIAL_NUMBER_STR ""
-+#endif
-+
-+/*
-+ * USB 2.0 spec does not mention it, but MaxPower is expected to be at least one
-+ * and is tested for in USB configuration tests.
-+ */
-+
-+#ifdef CONFIG_USBD_SELFPOWERED
-+#define BMATTRIBUTE BMATTRIBUTE_RESERVED | BMATTRIBUTE_SELF_POWERED
-+#define BMAXPOWER 1
-+#else
-+#define BMATTRIBUTE BMATTRIBUTE_RESERVED
-+#define BMAXPOWER CONFIG_USBD_MAXPOWER
-+#endif
-+
-+/*
-+ * setup some default values for pktsizes and endpoint addresses.
-+ */
-+
-+#ifndef CONFIG_USBD_STORAGE_OUT_PKTSIZE
-+#define CONFIG_USBD_STORAGE_OUT_PKTSIZE 64
-+#endif
-+
-+#ifndef CONFIG_USBD_STORAGE_IN_PKTSIZE
-+#define CONFIG_USBD_STORAGE_IN_PKTSIZE 64
-+#endif
-+
-+#ifndef CONFIG_USBD_STORAGE_INT_PKTSIZE
-+#define CONFIG_USBD_STORAGE_INT_PKTSIZE 16
-+#endif
-+
-+#ifndef CONFIG_USBD_STORAGE_OUT_ENDPOINT
-+#define CONFIG_USBD_STORAGE_OUT_ENDPOINT 1
-+#endif
-+
-+#ifndef CONFIG_USBD_STORAGE_IN_ENDPOINT
-+#define CONFIG_USBD_STORAGE_IN_ENDPOINT 2
-+#endif
-+
-+#ifndef CONFIG_USBD_STORAGE_INT_ENDPOINT
-+#define CONFIG_USBD_STORAGE_INT_ENDPOINT 3
-+#endif
-+
-+/*
-+ * check for architecture specific endpoint configurations
-+ */
-+
-+#if defined(ABS_OUT_ADDR)
-+ //#warning
-+ //#warning USING ABS ENDPOINT OUT ADDRESS
-+ #undef CONFIG_USBD_STORAGE_OUT_ENDPOINT
-+
-+ #if ABS_OUT_ADDR > 0
-+ #define CONFIG_USBD_STORAGE_OUT_ENDPOINT ABS_OUT_ADDR
-+ #endif
-+
-+#elif defined(MAX_OUT_ADDR) && defined(CONFIG_USBD_STORAGE_OUT_ENDPOINT) && (CONFIG_USBD_STORAGE_OUT_ENDPOINT > MAX_OUT_ADDR)
-+ //#warning
-+ //#warning USING DEFAULT ENDPOINT OUT ADDRESS
-+ #undef CONFIG_USBD_STORAGE_OUT_ENDPOINT
-+ #define CONFIG_USBD_STORAGE_OUT_ENDPOINT DFL_OUT_ADDR
-+
-+#endif /* elif */
-+
-+#if defined(ABS_IN_ADDR)
-+ //#warning
-+ //#warning USING ABS ENDPOINT IN ADDRESS
-+ #undef CONFIG_USBD_STORAGE_IN_ENDPOINT
-+
-+ #if ABS_IN_ADDR > 0
-+ #define CONFIG_USBD_STORAGE_IN_ENDPOINT ABS_IN_ADDR
-+ #endif
-+
-+#elif defined(MAX_IN_ADDR) && defined(CONFIG_USBD_STORAGE_IN_ENDPOINT) && (CONFIG_USBD_STORAGE_IN_ENDPOINT > MAX_IN_ADDR)
-+ //#warning
-+ //#warning USING DEFAULT ENDPOINT IN ADDRESS
-+ #undef CONFIG_USBD_STORAGE_IN_ENDPOINT
-+ #define CONFIG_USBD_STORAGE_IN_ENDPOINT DFL_IN_ADDR
-+
-+#endif /* elif */
-+
-+#if defined(ABS_INT_ADDR)
-+ //#warning
-+ //#warning USING ABS ENDPOINT INT ADDRESS
-+ #undef CONFIG_USBD_STORAGE_INT_ENDPOINT
-+
-+ #if ABS_INT_ADDR
-+ #define CONFIG_USBD_STORAGE_INT_ENDPOINT ABS_INT_ADDR
-+ #endif
-+
-+#elif defined(MAX_INT_ADDR) && defined(CONFIG_USBD_STORAGE_INT_ENDPOINT) && (CONFIG_USBD_STORAGE_INT_ENDPOINT > MAX_INT_ADDR)
-+ //#warning
-+ //#warning USING DEFAULT ENDPOINT INT ADDRESS
-+ #undef CONFIG_USBD_STORAGE_INT_ENDPOINT
-+ #define CONFIG_USBD_STORAGE_INT_ENDPOINT DFL_INT_ADDR
-+
-+#endif /* elif */
-+
-+#if defined(MAX_OUT_PKTSIZE) && defined(CONFIG_USBD_STORAGE_OUT_PKTSIZE) && CONFIG_USBD_STORAGE_OUT_PKTSIZE > MAX_OUT_PKTSIZE
-+ //#warning
-+ //#warning OVERIDING ENDPOINT OUT PKTSIZE
-+ #undef CONFIG_USBD_STORAGE_OUT_PKTSIZE
-+ #define CONFIG_USBD_STORAGE_OUT_PKTSIZE MAX_OUT_PKTSIZE
-+#endif
-+
-+#if defined(MAX_IN_PKTSIZE) && defined(CONFIG_USBD_STORAGE_IN_PKTSIZE) && CONFIG_USBD_STORAGE_IN_PKTSIZE > MAX_IN_PKTSIZE
-+ //#warning
-+ //#warning OVERIDING ENDPOINT IN PKTSIZE
-+ #undef CONFIG_USBD_STORAGE_IN_PKTSIZE
-+ #define CONFIG_USBD_STORAGE_IN_PKTSIZE MAX_IN_PKTSIZE
-+#endif
-+
-+#if defined(MAX_INT_PKTSIZE) && defined(CONFIG_USBD_STORAGE_INT_PKTSIZE) && CONFIG_USBD_STORAGE_INT_PKTSIZE > MAX_INT_PKTSIZE
-+ //#warning
-+ //#warning OVERIDING ENDPOINT INT PKTSIZE
-+ #undef CONFIG_USBD_STORAGE_INT_PKTSIZE
-+ #define CONFIG_USBD_STORAGE_INT_PKTSIZE MAX_INT_PKTSIZE
-+#endif
-+
-+/******************************************************************************
-+** Variable Declaration
-+******************************************************************************/
-+
-+/**************************************
-+** Module Parameters
-+**************************************/
-+
-+static u32 vendor_id;
-+static u32 product_id;
-+static int out_pkt_sz = CONFIG_USBD_STORAGE_OUT_PKTSIZE;
-+static int in_pkt_sz = CONFIG_USBD_STORAGE_IN_PKTSIZE;
-+
-+MODULE_PARM(vendor_id, "i");
-+MODULE_PARM(product_id, "i");
-+MODULE_PARM(out_pkt_sz, "i");
-+MODULE_PARM(in_pkt_sz, "i");
-+
-+MODULE_PARM_DESC(vendor_id, "vendor id");
-+MODULE_PARM_DESC(product_id, "product id");
-+
-+/**************************************
-+** Mass Storage Configuration
-+**************************************/
-+
-+/*
-+ * Data Interface Alternate 1 endpoints
-+ */
-+static __initdata struct usb_endpoint_description StorageAlt1Endpoints[] = {
-+ {
-+ bEndpointAddress:CONFIG_USBD_STORAGE_OUT_ENDPOINT,
-+ bmAttributes:BULK,
-+ wMaxPacketSize:CONFIG_USBD_STORAGE_OUT_PKTSIZE,
-+ bInterval:0,
-+ direction:OUT,
-+ transferSize:MAXTRANSFER,
-+ },
-+
-+ {
-+ bEndpointAddress:CONFIG_USBD_STORAGE_IN_ENDPOINT,
-+ bmAttributes:BULK,
-+ wMaxPacketSize:CONFIG_USBD_STORAGE_IN_PKTSIZE,
-+ bInterval:0,
-+ direction:IN,
-+ transferSize:MAXTRANSFER,
-+ },
-+
-+#if defined(CONFIG_USBD_STORAGE_INT_ENDPOINT) && (CONFIG_USBD_STORAGE_INT_ENDPOINT > 0)
-+ {
-+ bEndpointAddress:CONFIG_USBD_STORAGE_INT_ENDPOINT,
-+ bmAttributes:INTERRUPT,
-+ wMaxPacketSize:CONFIG_USBD_STORAGE_INT_PKTSIZE,
-+ bInterval:10,
-+ direction:IN,
-+ transferSize:CONFIG_USBD_STORAGE_INT_PKTSIZE,
-+ },
-+#endif
-+};
-+
-+
-+/*
-+ * Data Interface Alternate description(s)
-+ */
-+static __initdata struct usb_alternate_description StorageAlternateDescriptions[] = {
-+ {
-+ #if defined(CONFIG_USBD_STORAGE_NO_STRINGS)
-+ iInterface:"",
-+ #else
-+ iInterface:"Mass Storage Interface",
-+ #endif
-+ bAlternateSetting:0,
-+ classes:0,
-+ class_list:NULL,
-+ endpoints:sizeof (StorageAlt1Endpoints) / sizeof (struct usb_endpoint_description),
-+ endpoint_list:StorageAlt1Endpoints,
-+ },
-+};
-+
-+/*
-+ * Interface description(s)
-+ */
-+static __initdata struct usb_interface_description StorageInterfaces[] = {
-+ {
-+ #if defined(CONFIG_USBD_STORAGE_NO_STRINGS)
-+ iInterface:"",
-+ #else
-+ iInterface:"Mass Storage Interface",
-+ #endif
-+ bInterfaceClass:MASS_STORAGE_CLASS,
-+ bInterfaceSubClass:MASS_STORAGE_SUBCLASS_SCSI,
-+ bInterfaceProtocol:MASS_STORAGE_PROTO_BULK_ONLY,
-+ alternates:sizeof (StorageAlternateDescriptions) / sizeof (struct usb_alternate_description),
-+ alternate_list:StorageAlternateDescriptions,
-+ },
-+};
-+
-+/******************************************************************************
-+** USB Configuration
-+******************************************************************************/
-+
-+/*
-+ * Configuration description(s)
-+ */
-+struct __initdata usb_configuration_description StorageDescription[] = {
-+ {
-+ #if defined(CONFIG_USBD_STORAGE_NO_STRINGS)
-+ iConfiguration:"",
-+ #else
-+ iConfiguration:"Mass Storage Configuration",
-+ #endif
-+ bmAttributes:BMATTRIBUTE,
-+ bMaxPower:BMAXPOWER,
-+ interfaces:sizeof (StorageInterfaces) / sizeof (struct usb_interface_description),
-+ interface_list:StorageInterfaces,
-+ },
-+};
-+
-+/*
-+ * Device Description
-+ */
-+struct __initdata usb_device_description StorageDeviceDescription = {
-+ bDeviceClass:0,
-+ bDeviceSubClass:0, // XXX
-+ bDeviceProtocol:0, // XXX
-+ idVendor:CONFIG_USBD_VENDORID,
-+ idProduct:CONFIG_USBD_PRODUCTID,
-+ iManufacturer:CONFIG_USBD_MANUFACTURER,
-+ iProduct:CONFIG_USBD_PRODUCT_NAME,
-+ iSerialNumber:CONFIG_USBD_SERIAL_NUMBER_STR,
-+};
-+
-+/**************************************
-+** Other Variable
-+**************************************/
-+static int storage_exit_flag = 0;
-+static pid_t storage_pid = 0;
-+static struct semaphore storage_sem;
-+struct timer_list storage_usb_event_tim;
-+
-+
-+/******************************************************************************
-+** Global Function
-+******************************************************************************/
-+
-+void storage_urb_send(struct usb_device_instance* device, void* buffer,
-+ int length)
-+{
-+ int port = 0;
-+ struct urb* urb;
-+
-+ if(!(urb = usbd_alloc_urb(device,
-+ device->function_instance_array + port,
-+ CONFIG_USBD_STORAGE_IN_ENDPOINT,
-+ length + 5 + in_pkt_sz))){
-+ printk(KERN_INFO "storage_fd: usbd_alloc_urb failed. length '%d'.\n", length);
-+ return;
-+ }
-+
-+ if(buffer){
-+ memcpy(urb->buffer, buffer, length);
-+ }
-+ else{
-+ memset(urb->buffer, 0x00, length);
-+ }
-+ urb->actual_length = length;
-+
-+ if(usbd_send_urb(urb)){
-+ printk(KERN_INFO "storage_fd: usbd_send_urb failed.\n");
-+ usbd_dealloc_urb(urb);
-+ return;
-+ }
-+
-+ return;
-+}
-+
-+/******************************************************************************
-+** Local Function
-+******************************************************************************/
-+
-+/**************************************
-+** Called when a USB Device is created or destroyed
-+**************************************/
-+
-+static int storage_thread(void *_c)
-+{
-+ siginfo_t info;
-+ unsigned long signr;
-+ char buff[32];
-+
-+ /* current status set */
-+ daemonize();
-+
-+ /* PID set */
-+ storage_pid = current->pid;
-+
-+ /* thread name set */
-+ sprintf(current->comm, STORAGE_THREAD_NAME);
-+ (current)->nice = 10;
-+
-+ /* signal register */
-+ spin_lock_irq(&current->sigmask_lock);
-+ siginitsetinv(&current->blocked,
-+ sigmask(SIGUSR1) | sigmask(SIGHUP) | sigmask(SIGKILL) |
-+ sigmask(SIGSTOP) | sigmask(SIGCONT) | sigmask(SIGTERM) |
-+ sigmask(SIGALRM));
-+ recalc_sigpending(current);
-+ spin_unlock_irq(&current->sigmask_lock);
-+
-+ /* media open */
-+ schedule_task_register(
-+ (SCHEDULE_TASK_FUNC)storageproto_media_status_check, CONTEXT_STORAGE,
-+ 0, 0, 0, 0);
-+
-+ /* thread active indicate */
-+ sprintf(buff, "%d\n", storage_pid);
-+ hotplug("usbdstorage", buff, "active");
-+
-+ for(;;){
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (!signal_pending(current)) {
-+ schedule();
-+ continue;
-+ }
-+
-+ spin_lock_irq(&current->sigmask_lock);
-+ signr = dequeue_signal(&current->blocked, &info);
-+ spin_unlock_irq(&current->sigmask_lock);
-+
-+ switch(signr) {
-+ case SIGHUP:
-+ /* media signal indicate */
-+ schedule_task_register(
-+ (SCHEDULE_TASK_FUNC)storageproto_media_status_check, CONTEXT_STORAGE,
-+ 0, 0, 0, 0);
-+
-+ DBG_STORAGE_FD(KERN_INFO "storage_fd: signal receive 'SIGHUP'.\n");
-+ break;
-+
-+ default:
-+ DBG_STORAGE_FD(KERN_INFO "storage_fd: signal receive '%ld'\n", signr);
-+ break;
-+ }
-+
-+ if(storage_exit_flag) break;
-+ }
-+ /* current status set */
-+ current->state = TASK_RUNNING;
-+
-+ /* PID clear */
-+ storage_pid = 0;
-+
-+ /* thread inactive indicate */
-+ hotplug("usbdstorage", buff, "inactive");
-+
-+ up(&storage_sem);
-+
-+ return 0;
-+}
-+
-+static void storage_function_init(struct usb_bus_instance* bus,
-+ struct usb_device_instance* device,
-+ struct usb_function_driver* function_driver)
-+{
-+ /* schedule task init */
-+ schedule_task_init();
-+
-+ /* storage protocol initialize */
-+ storageproto_init();
-+
-+ /* semaphore init */
-+ sema_init(&storage_sem, 0);
-+
-+ /* timer initialize */
-+ init_timer(&storage_usb_event_tim);
-+
-+ /* thread create */
-+ storage_pid = kernel_thread(storage_thread, NULL, 0);
-+
-+ return;
-+}
-+
-+static void storage_function_exit(struct usb_device_instance* device)
-+{
-+ /* thread kill */
-+ storage_exit_flag = 1;
-+ kill_proc(storage_pid, SIGKILL, 1);
-+ down(&storage_sem);
-+
-+ /* delete timer */
-+ del_timer(&storage_usb_event_tim);
-+
-+ /* storage protocol exit */
-+ storageproto_exit();
-+
-+ /* schedule task delete */
-+ schedule_task_all_unregister();
-+
-+ return;
-+}
-+
-+
-+/**************************************
-+** Called to handle USB Events
-+**************************************/
-+
-+static void storage_usb_event_delay_timeout(unsigned long param)
-+{
-+ /* media signal indicate */
-+ schedule_task_register(
-+ (SCHEDULE_TASK_FUNC)storageproto_usb_status_check, (int)param,
-+ 0, 0, 0, 0);
-+
-+ return;
-+}
-+
-+/*
-+ * storage_event - process a device event
-+ * @device: usb device
-+ * @event: the event that happened
-+ *
-+ * Called by the usb device core layer to respond to various USB events.
-+ *
-+ * This routine IS called at interrupt time. Please use the usual precautions.
-+ *
-+ */
-+void storage_event(struct usb_device_instance* device,
-+ usb_device_event_t event, int data)
-+{
-+#if 0
-+ static struct {
-+ usb_device_event_t event;
-+ char* string;
-+ } eventAnal[] = {
-+ {DEVICE_UNKNOWN, "DEVICE_UNKNOWN"},
-+ {DEVICE_INIT, "DEVICE_INIT"},
-+ {DEVICE_CREATE, "DEVICE_CREATE"},
-+ {DEVICE_HUB_CONFIGURED, "DEVICE_HUB_CONFIGURED"},
-+ {DEVICE_RESET, "DEVICE_RESET"},
-+ {DEVICE_ADDRESS_ASSIGNED, "DEVICE_ADDRESS_ASSIGNED"},
-+ {DEVICE_CONFIGURED, "DEVICE_CONFIGURED"},
-+ {DEVICE_SET_INTERFACE, "DEVICE_SET_INTERFACE"},
-+ {DEVICE_SET_FEATURE, "DEVICE_SET_FEATURE"},
-+ {DEVICE_CLEAR_FEATURE, "DEVICE_CLEAR_FEATURE"},
-+ {DEVICE_DE_CONFIGURED, "DEVICE_DE_CONFIGURED"},
-+ {DEVICE_BUS_INACTIVE, "DEVICE_BUS_INACTIVE"},
-+ {DEVICE_BUS_ACTIVITY, "DEVICE_BUS_ACTIVITY"},
-+ {DEVICE_POWER_INTERRUPTION, "DEVICE_POWER_INTERRUPTION"},
-+ {DEVICE_HUB_RESET, "DEVICE_HUB_RESET"},
-+ {DEVICE_DESTROY, "DEVICE_DESTROY"},
-+ {DEVICE_FUNCTION_PRIVATE, "DEVICE_FUNCTION_PRIVATE"}
-+ };
-+ int i;
-+
-+ for(i=0; i<(sizeof(eventAnal)/sizeof(eventAnal[0])); i++){
-+ if(event == eventAnal[i].event){
-+ DBG_STORAGE_FD(KERN_INFO "storage_fd: event receive '%s'.\n",
-+ eventAnal[i].string);
-+ break;
-+ }
-+ }
-+ if(i == (sizeof(eventAnal)/sizeof(eventAnal[0]))){
-+ DBG_STORAGE_FD(KERN_INFO "storage_fd: unknown event receive.\n");
-+ }
-+#endif
-+
-+ switch(event){
-+ case DEVICE_ADDRESS_ASSIGNED:
-+ {
-+ static int Is1stCheck = 1;
-+ if(Is1stCheck){
-+ Is1stCheck = 0;
-+
-+ /* delay timer set */
-+ del_timer(&storage_usb_event_tim);
-+ storage_usb_event_tim.expires = jiffies + ((USB_EVENT_DELAY_TIM * HZ) / 1000);
-+ storage_usb_event_tim.data = USB_DISCONNECT;
-+ storage_usb_event_tim.function = storage_usb_event_delay_timeout;
-+ add_timer(&storage_usb_event_tim);
-+ break;
-+ }
-+ }
-+ case DEVICE_BUS_ACTIVITY:
-+ /* delay timer set */
-+ del_timer(&storage_usb_event_tim);
-+ storage_usb_event_tim.expires = jiffies + ((USB_EVENT_DELAY_TIM * HZ) / 1000);
-+ storage_usb_event_tim.data = USB_CONNECT;
-+ storage_usb_event_tim.function = storage_usb_event_delay_timeout;
-+ add_timer(&storage_usb_event_tim);
-+ break;
-+
-+ case DEVICE_BUS_INACTIVE:
-+ /* delay timer set */
-+ del_timer(&storage_usb_event_tim);
-+ storage_usb_event_tim.expires = jiffies + ((USB_EVENT_DELAY_TIM * HZ) / 1000);
-+ storage_usb_event_tim.data = USB_DISCONNECT;
-+ storage_usb_event_tim.function = storage_usb_event_delay_timeout;
-+ add_timer(&storage_usb_event_tim);
-+ break;
-+
-+ case DEVICE_RESET:
-+ schedule_task_register(
-+ (SCHEDULE_TASK_FUNC)storageproto_usb_reset_ind,
-+ 0, 0, 0, 0, 0);
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+ return;
-+}
-+
-+/*
-+ * storage_recv_setup - called with a control URB
-+ * @urb - pointer to struct urb
-+ *
-+ * Check if this is a setup packet, process the device request, put results
-+ * back into the urb and return zero or non-zero to indicate success (DATA)
-+ * or failure (STALL).
-+ *
-+ * This routine IS called at interrupt time. Please use the usual precautions.
-+ *
-+ */
-+int storage_recv_setup(struct urb* urb)
-+{
-+ return 0;
-+}
-+
-+/*
-+ * storage_recv_urb - called with a received URB
-+ * @urb - pointer to struct urb
-+ *
-+ * Return non-zero if we failed and urb is still valid (not disposed)
-+ *
-+ * This routine IS called at interrupt time. Please use the usual precautions.
-+ *
-+ */
-+int storage_recv_urb(struct urb* urb)
-+{
-+ int port = 0; // XXX compound device
-+ struct usb_device_instance* device;
-+ struct usb_function_instance* function;
-+
-+ if(!urb || !(device = urb->device) ||
-+ !(function = device->function_instance_array + port)){
-+ return -EINVAL;
-+ }
-+
-+ if(urb->status != RECV_OK){
-+ return -EINVAL;
-+ }
-+
-+ /* URB urb_analysis */
-+ schedule_task_register(
-+ (SCHEDULE_TASK_FUNC)storageproto_urb_analysis, (int)urb,
-+ 0, 0, 0, 0);
-+
-+ return 0;
-+}
-+
-+/*
-+ * storage_urb_sent - called to indicate URB transmit finished
-+ * @urb: pointer to struct urb
-+ * @rc: result
-+ *
-+ * The usb device core layer will use this to let us know when an URB has
-+ * been finished with.
-+ *
-+ * This routine IS called at interrupt time. Please use the usual precautions.
-+ *
-+ */
-+int storage_urb_sent(struct urb* urb, int rc)
-+{
-+ int port = 0; // XXX compound device
-+ struct usb_device_instance* device;
-+ struct usb_function_instance* function;
-+
-+ if(!urb || !(device = urb->device) ||
-+ !(function = device->function_instance_array + port)){
-+ return -EINVAL;
-+ }
-+
-+ usbd_dealloc_urb (urb);
-+
-+ return 0;
-+}
-+
-+/**************************************
-+** Proc file system
-+**************************************/
-+
-+static ssize_t storage_proc_read(struct file* file, char* buf, size_t count,
-+ loff_t* pos)
-+{
-+ int len = 0, ret;
-+
-+ if(*pos > 0) return 0;
-+
-+ if((ret = storageproto_proc_read(file, buf + len, count - len, pos)) < 0){
-+ return ret;
-+ }
-+ len += ret;
-+
-+ if((ret = schedule_task_proc_read(file, buf + len, count - len, pos)) < 0){
-+ return ret;
-+ }
-+ len += ret;
-+
-+ return len;
-+}
-+
-+static struct file_operations StorageProcOps = {
-+ read:storage_proc_read,
-+};
-+
-+/**************************************
-+** Module init and exit
-+**************************************/
-+
-+struct usb_function_operations StorageFunctionOps = {
-+ event:storage_event,
-+ recv_urb:storage_recv_urb,
-+ recv_setup:storage_recv_setup,
-+ urb_sent:storage_urb_sent,
-+ function_init:storage_function_init,
-+ function_exit:storage_function_exit,
-+};
-+
-+struct usb_function_driver StorageFunctionDriver = {
-+ name:"Mass Storage",
-+ ops:&StorageFunctionOps,
-+ device_description:&StorageDeviceDescription,
-+ configurations:sizeof (StorageDescription) / sizeof (struct usb_configuration_description),
-+ configuration_description:StorageDescription,
-+ this_module:THIS_MODULE,
-+};
-+
-+/*
-+ * net_modinit - module init
-+ *
-+ */
-+static int __init net_modinit(void)
-+{
-+ struct proc_dir_entry* proc_entry;
-+
-+ printk(KERN_INFO "storage_fd: %s (OUT=%d,IN=%d)\n",
-+ __usbd_module_info, out_pkt_sz, in_pkt_sz);
-+
-+ printk(KERN_INFO "storage_fd: vendorID: %x productID: %x\n",
-+ CONFIG_USBD_VENDORID, CONFIG_USBD_PRODUCTID);
-+
-+ // verify pkt sizes not too small
-+ if (out_pkt_sz < 3 || in_pkt_sz < 3){
-+ printk(KERN_INFO "storage_fd: Rx pkt size %d or Tx pkt size %d too small\n",
-+ out_pkt_sz, in_pkt_sz);
-+ return (-EINVAL);
-+ }
-+
-+ if(vendor_id){
-+ StorageDeviceDescription.idVendor = vendor_id;
-+ }
-+ if(product_id){
-+ StorageDeviceDescription.idProduct = product_id;
-+ }
-+
-+ // register us with the usb device support layer
-+ if(usbd_register_function(&StorageFunctionDriver)){
-+ printk(KERN_INFO "storage_fd: usbd_register_function failed.\n");
-+ return -EINVAL;
-+ }
-+
-+ // create proc entry
-+ if ((proc_entry = create_proc_entry("usb-storage", 0, 0)) == NULL) {
-+ usbd_deregister_function (&StorageFunctionDriver);
-+ printk(KERN_INFO "storage_fd: create_proc_entry failed.\n");
-+ return -ENOMEM;
-+ }
-+ proc_entry->proc_fops = &StorageProcOps;
-+
-+ return 0;
-+}
-+
-+/*
-+ * function_exit - module cleanup
-+ *
-+ */
-+static void __exit net_modexit (void)
-+{
-+ // de-register us with the usb device support layer
-+ usbd_deregister_function (&StorageFunctionDriver);
-+
-+ // remove proc entry
-+ remove_proc_entry("usb-storage", NULL);
-+
-+ return;
-+}
-+
-+module_init (net_modinit);
-+module_exit (net_modexit);
-diff -Nur linux-2.4.18/drivers/usb/device/storage_fd/storageproto.c linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/storageproto.c
---- linux-2.4.18/drivers/usb/device/storage_fd/storageproto.c 1970-01-01 03:00:00.000000000 +0300
-+++ linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/storageproto.c 2003-11-07 05:34:43.000000000 +0300
-@@ -0,0 +1,1505 @@
-+/*
-+ * linux/drivers/usb/device/storage_fd/storageproto.c - mass storage protocol library
-+ *
-+ * Copyright (c) 2003 Lineo Solutions, Inc.
-+ *
-+ * Written by Shunnosuke kabata
-+ *
-+ * 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 File
-+******************************************************************************/
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include "../usbd-export.h"
-+#include "../usbd-build.h"
-+#include "../usbd-module.h"
-+
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/list.h>
-+#include <linux/netdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/etherdevice.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/smp_lock.h>
-+#include <linux/ctype.h>
-+#include <linux/timer.h>
-+#include <linux/string.h>
-+#include <linux/atmdev.h>
-+#include <linux/pkt_sched.h>
-+#include <linux/delay.h>
-+#include <linux/blkdev.h>
-+#include <linux/file.h>
-+#include <asm/uaccess.h>
-+#include <asm/system.h>
-+#include <net/arp.h>
-+
-+#include <linux/autoconf.h>
-+
-+#include "../usbd.h"
-+#include "../usbd-func.h"
-+#include "../usbd-bus.h"
-+#include "../usbd-inline.h"
-+#include "../usbd-arch.h"
-+#include "../hotplug.h"
-+
-+#include "schedule_task.h"
-+#include "storageproto.h"
-+
-+/******************************************************************************
-+** macro define
-+******************************************************************************/
-+
-+#define DEVICE_BLOCK_SIZE 512
-+
-+#define BLOCK_BUFFER_SIZE (1024 * 64)
-+
-+#define DEF_NUMBER_OF_HEADS 0x10
-+#define DEF_SECTORS_PER_TRACK 0x20
-+
-+/******************************************************************************
-+** Structure Define
-+******************************************************************************/
-+
-+typedef struct{
-+ unsigned char scsi_command;
-+ unsigned char* command_name;
-+ void (*scsi_func)(struct usb_device_instance*,
-+ COMMAND_BLOCK_WRAPPER*);
-+} SCSI_ANALYSIS_TBL;
-+
-+typedef struct{
-+ unsigned char scsi_command;
-+ unsigned char* command_name;
-+ void (*bulkout_func)(struct usb_device_instance*,
-+ void*, int);
-+} SCSI_BULKOUT_ANALYSIS_TBL;
-+
-+/******************************************************************************
-+** Variable Declaration
-+******************************************************************************/
-+
-+/**************************************
-+** Module Parameters
-+**************************************/
-+
-+static char* storage_device = CONFIG_USBD_STORAGE_DEF_DEVICE_NAME;
-+MODULE_PARM(storage_device, "s");
-+
-+/**************************************
-+** Device Information
-+**************************************/
-+
-+static struct file* DeviceFile = NULL;
-+static int DeviceSize = 0;
-+static int DeviceBlockSize = DEVICE_BLOCK_SIZE;
-+static int DeviceWrProtect = WR_PROTECT_OFF;
-+
-+/**************************************
-+** Status
-+**************************************/
-+
-+static int StorageStatus = STORAGE_IDLE;
-+static int UsbStatus = USB_DISCONNECT;
-+static int MediaStatus = MEDIA_EJECT;
-+static int MediaChange = MEDIA_CHANGE_OFF;
-+
-+/**************************************
-+** Keep Information
-+**************************************/
-+
-+static SCSI_REQUEST_SENSE_DATA RequestSenseData;
-+static COMMAND_BLOCK_WRAPPER KeepCBW;
-+static unsigned long BulkOutLength = 0;
-+static unsigned char BlockBuffer[BLOCK_BUFFER_SIZE];
-+
-+/**************************************
-+** Statistics
-+**************************************/
-+static unsigned long StatMaxBulkInSize = 0;
-+static unsigned long StatMaxBulkOutSize = 0;
-+static unsigned long StatDevWriteError = 0;
-+static unsigned long StatDevReadError = 0;
-+static unsigned long StatDevFlushError = 0;
-+static unsigned long StatWriteTimout = 0;
-+static unsigned long StatMaxWriteTime = 0;
-+
-+/**************************************
-+** Timer
-+**************************************/
-+static struct timer_list BulkOutTim;
-+static struct timer_list MediaCheckTim;
-+
-+/******************************************************************************
-+** Local Function
-+******************************************************************************/
-+
-+static void storage_bulkout_timeout(unsigned long param)
-+{
-+ /* statistics update */
-+ StatWriteTimout++;
-+ printk(KERN_INFO "storage_fd: write bulk out timeout. length '%ld/%ld'.\n",
-+ BulkOutLength, KeepCBW.dCBWDataTransferLength);
-+
-+ return;
-+}
-+
-+static void media_check_timeout(unsigned long param)
-+{
-+ /* media check */
-+ schedule_task_register(
-+ (SCHEDULE_TASK_FUNC)storageproto_media_status_check, CONTEXT_TIMER,
-+ 0, 0, 0, 0);
-+
-+ return;
-+}
-+
-+static void request_sense_data_set(unsigned char sense_key, unsigned char asc,
-+ unsigned char ascq, unsigned long info)
-+{
-+ /*
-+ * set REQUEST SENSE DATA
-+ */
-+
-+ memset(&RequestSenseData, 0x00, sizeof(RequestSenseData));
-+
-+ RequestSenseData.ErrorCode = 0x70;
-+ RequestSenseData.Valid = (info) ? 1 : 0;
-+ RequestSenseData.SenseKey = sense_key;
-+ memcpy(RequestSenseData.Information, &info, sizeof(info));
-+ RequestSenseData.AdditionalSenseLength = 0x0a;
-+ RequestSenseData.AdditionalSenseCode = asc;
-+ RequestSenseData.AdditionalSenseCodeQualifier = ascq;
-+
-+ return;
-+}
-+
-+static void scsi_inquiry_analysis(struct usb_device_instance* device,
-+ COMMAND_BLOCK_WRAPPER* cbw)
-+{
-+ SCSI_INQUIRY_DATA data;
-+ COMMAND_STATUS_WRAPPER csw;
-+ unsigned long data_len;
-+
-+ /*
-+ * data transport
-+ */
-+
-+ memset(&data, 0x00, sizeof(data));
-+
-+ data.PeripheralDeviceType = 0x00;
-+ data.RMB = 1;
-+ data.ResponseDataFormat = 0x01;
-+ data.AdditionalLength = 0x1f;
-+ strncpy(data.VendorInformation, CONFIG_USBD_MANUFACTURER,
-+ sizeof(data.VendorInformation));
-+ strncpy(data.ProductIdentification, CONFIG_USBD_PRODUCT_NAME,
-+ sizeof(data.ProductIdentification));
-+ strncpy(data.ProductRevisionLevel, PRODUCT_REVISION_LEVEL,
-+ sizeof(data.ProductRevisionLevel));
-+
-+ data_len = sizeof(data);
-+ if(cbw->dCBWDataTransferLength < data_len){
-+ data_len = cbw->dCBWDataTransferLength;
-+ }
-+
-+ storage_urb_send(device, &data, data_len);
-+
-+ /*
-+ * status transport
-+ */
-+
-+ memset(&csw, 0x00, sizeof(csw));
-+
-+ csw.dCSWSignature = CSW_SIGNATURE;
-+ csw.dCSWTag = cbw->dCBWTag;
-+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength - data_len;
-+ csw.bCSWStatus = 0;
-+
-+ storage_urb_send(device, &csw, sizeof(csw));
-+
-+ return;
-+}
-+
-+static void scsi_read_format_capacity_analysis(struct usb_device_instance* device,
-+ COMMAND_BLOCK_WRAPPER* cbw)
-+{
-+ SCSI_READ_FORMAT_CAPACITY_DATA data;
-+ COMMAND_STATUS_WRAPPER csw;
-+ unsigned long block_num, data_len;
-+ unsigned short block_len;
-+
-+ /*
-+ * data transport
-+ */
-+
-+ block_num = 0xffffffff;
-+ block_len = (unsigned short)DeviceBlockSize;
-+ block_num = htonl(block_num);
-+ block_len = htons(block_len);
-+
-+ memset(&data, 0x00, sizeof(data));
-+
-+ data.CapacityListHeader.CapacityListLength =
-+ sizeof(data.CurrentMaximumCapacityDescriptor);
-+ memcpy(data.CurrentMaximumCapacityDescriptor.NumberofBlocks, &block_num,
-+ sizeof(block_num));
-+ data.CurrentMaximumCapacityDescriptor.DescriptorCode = 0x03;
-+ memcpy(data.CurrentMaximumCapacityDescriptor.BlockLength + 1, &block_len,
-+ sizeof(block_len));
-+
-+ data_len = sizeof(data);
-+ if(cbw->dCBWDataTransferLength < data_len){
-+ data_len = cbw->dCBWDataTransferLength;
-+ }
-+
-+ storage_urb_send(device, &data, data_len);
-+
-+ /*
-+ * status transport
-+ */
-+
-+ memset(&csw, 0x00, sizeof(csw));
-+
-+ csw.dCSWSignature = CSW_SIGNATURE;
-+ csw.dCSWTag = cbw->dCBWTag;
-+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength - data_len;
-+ csw.bCSWStatus = 0;
-+
-+ storage_urb_send(device, &csw, sizeof(csw));
-+
-+ return;
-+}
-+
-+static void scsi_read_capacity_analysis(struct usb_device_instance* device,
-+ COMMAND_BLOCK_WRAPPER* cbw)
-+{
-+ SCSI_READ_CAPACITY_DATA data;
-+ COMMAND_STATUS_WRAPPER csw;
-+ unsigned char data_len, status = 0;
-+
-+ if(DeviceFile == NULL){
-+ /* 0 clear */
-+ memset(&data, 0x00, sizeof(data));
-+
-+ /* data length set */
-+ data_len = cbw->dCBWDataTransferLength;
-+
-+ /* status set */
-+ status = 1;
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x02, 0x3a, 0x00, 0x00);
-+ }
-+ else
-+ if(MediaChange == MEDIA_CHANGE_ON){
-+ /* 0 clear */
-+ memset(&data, 0x00, sizeof(data));
-+
-+ /* data length set */
-+ data_len = cbw->dCBWDataTransferLength;
-+
-+ /* status set */
-+ status = 1;
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x06, 0x28, 0x00, 0x00);
-+
-+ /* media change flag off */
-+ MediaChange = MEDIA_CHANGE_OFF;
-+ }
-+ else{
-+ unsigned long last_lba, block_len;
-+
-+ /* 0 clear */
-+ memset(&data, 0x00, sizeof(data));
-+
-+ /* data set */
-+ last_lba = (DeviceSize / DeviceBlockSize) - 1;
-+ block_len = DeviceBlockSize;
-+ last_lba = htonl(last_lba);
-+ block_len = htonl(block_len);
-+
-+ memcpy(data.LastLogicalBlockAddress, &last_lba, sizeof(last_lba));
-+ memcpy(data.BlockLengthInBytes, &block_len, sizeof(block_len));
-+
-+ /* data length set */
-+ data_len = sizeof(data);
-+
-+ /* status set */
-+ status = 0;
-+ }
-+
-+ /*
-+ * data transport
-+ */
-+
-+ if(cbw->dCBWDataTransferLength < data_len){
-+ data_len = cbw->dCBWDataTransferLength;
-+ }
-+
-+ storage_urb_send(device, &data, data_len);
-+
-+ /*
-+ * status transport
-+ */
-+
-+ memset(&csw, 0x00, sizeof(csw));
-+
-+ csw.dCSWSignature = CSW_SIGNATURE;
-+ csw.dCSWTag = cbw->dCBWTag;
-+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength - data_len;
-+ csw.bCSWStatus = status;
-+
-+ storage_urb_send(device, &csw, sizeof(csw));
-+
-+ return;
-+}
-+
-+static void scsi_request_sense_analysis(struct usb_device_instance* device,
-+ COMMAND_BLOCK_WRAPPER* cbw)
-+{
-+ COMMAND_STATUS_WRAPPER csw;
-+ unsigned long data_len;
-+
-+ /*
-+ * data transport
-+ */
-+
-+ data_len = sizeof(RequestSenseData);
-+ if(cbw->dCBWDataTransferLength < data_len){
-+ data_len = cbw->dCBWDataTransferLength;
-+ }
-+
-+ storage_urb_send(device, &RequestSenseData, data_len);
-+
-+ /*
-+ * status transport
-+ */
-+
-+ memset(&csw, 0x00, sizeof(csw));
-+
-+ csw.dCSWSignature = CSW_SIGNATURE;
-+ csw.dCSWTag = cbw->dCBWTag;
-+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength - data_len;
-+ csw.bCSWStatus = 0;
-+
-+ storage_urb_send(device, &csw, sizeof(csw));
-+
-+ return;
-+}
-+
-+static void scsi_read_10_analysis(struct usb_device_instance* device,
-+ COMMAND_BLOCK_WRAPPER* cbw)
-+{
-+ SCSI_READ_10_COMMAND* command = (SCSI_READ_10_COMMAND*)cbw->CBWCB;
-+ COMMAND_STATUS_WRAPPER csw;
-+ unsigned char status = 0;
-+ unsigned short len;
-+ unsigned long lba, size, offset;
-+
-+ memcpy(&lba, command->LogicalBlockAddress, sizeof(lba));
-+ memcpy(&len, command->TransferLength, sizeof(len));
-+ lba = ntohl(lba);
-+ len = ntohs(len);
-+ offset = lba * DeviceBlockSize;
-+ size = cbw->dCBWDataTransferLength;
-+
-+ if(DeviceFile == NULL){
-+ /* command fail */
-+ status = 1;
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x02, 0x3a, 0x00, 0x00);
-+
-+ /*
-+ * data transport
-+ */
-+
-+ storage_urb_send(device, NULL, size);
-+ }
-+ else
-+ if(MediaChange == MEDIA_CHANGE_ON){
-+ /* command fail */
-+ status = 1;
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x06, 0x28, 0x00, 0x00);
-+
-+ /* media change flag off */
-+ MediaChange = MEDIA_CHANGE_OFF;
-+
-+ /*
-+ * data transport
-+ */
-+
-+ storage_urb_send(device, NULL, size);
-+ }
-+ else{
-+ unsigned long count, read_size;
-+
-+ /*
-+ * data transport
-+ */
-+
-+ /* device seek */
-+ DeviceFile->f_op->llseek(DeviceFile, offset, 0);
-+
-+ /* device read */
-+ for(count = size; count; count -= read_size){
-+ read_size = (count > sizeof(BlockBuffer)) ?
-+ sizeof(BlockBuffer) : count;
-+ if(DeviceFile &&
-+ DeviceFile->f_op->read(DeviceFile, BlockBuffer, read_size,
-+ &DeviceFile->f_pos) != read_size){
-+
-+ /* command fail */
-+ status = 1;
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x02, 0x3a, 0x00, 0x00);
-+
-+ /* statistics update */
-+ StatDevReadError++;
-+ printk(KERN_INFO "storage_fd: device read error. length '%ld'.\n", read_size);
-+ }
-+
-+ storage_urb_send(device, BlockBuffer, read_size);
-+ }
-+ }
-+
-+ /*
-+ * status transport
-+ */
-+
-+ memset(&csw, 0x00, sizeof(csw));
-+
-+ csw.dCSWSignature = CSW_SIGNATURE;
-+ csw.dCSWTag = cbw->dCBWTag;
-+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength - size;
-+ csw.bCSWStatus = status;
-+
-+ storage_urb_send(device, &csw, sizeof(csw));
-+
-+ return;
-+}
-+
-+static void scsi_mode_sense_analysis(struct usb_device_instance* device,
-+ COMMAND_BLOCK_WRAPPER* cbw)
-+{
-+ static READ_WRITE_ERROR_RECOVERY_PAGE page_01 = {
-+ PageCode:0x01,
-+ PageLength:0x0A,
-+ ReadRetryCount:0x03,
-+ WriteRetryCount:0x80,
-+ };
-+ static FLEXIBLE_DISK_PAGE page_05 = {
-+ PageCode:0x05,
-+ PageLength:0x1E,
-+ TransferRate:{0x00, 0xFA},
-+ NumberofHeads:0xA0,
-+ SectorsperTrack:0x00,
-+ DataBytesperSector:{0x02, 0x00},
-+ NumberofCylinders:{0x00, 0x00},
-+ MotorOnDelay:0x05,
-+ MotorOffDelay:0x1E,
-+ MediumRotationRate:{0x01, 0x68},
-+ };
-+ static REMOVABLE_BLOCK_ACCESS_CAPABILITIES_PAGE page_1b = {
-+ PageCode:0x1B,
-+ PageLength:0x0A,
-+ TLUN:0x01,
-+ };
-+ static TIMER_AND_PROTECT_PAGE page_1c = {
-+ PageCode:0x1c,
-+ PageLength:0x06,
-+ InactivityTimeMultiplier:0x0A,
-+ };
-+
-+
-+ SCSI_MODE_SENSE_COMMAND* command = (SCSI_MODE_SENSE_COMMAND*)cbw->CBWCB;
-+ SCSI_MODE_SENSE_DATA data;
-+ COMMAND_STATUS_WRAPPER csw;
-+ unsigned char data_len, status = 0;
-+ unsigned short cylinder, sector;
-+ unsigned long size;
-+
-+ /*
-+ * data transport
-+ */
-+
-+ memset(&data, 0x00, sizeof(data));
-+
-+ /* set write protect */
-+ data.ModeParameterHeader.WP = DeviceWrProtect;
-+
-+ /* set Flexible Disk Page */
-+ if(DeviceFile == NULL){
-+ sector = (unsigned short)DeviceBlockSize;
-+ cylinder = 0;
-+ sector = htons(sector);
-+ cylinder = htons(cylinder);
-+
-+ page_05.NumberofHeads = 0;
-+ page_05.SectorsperTrack = 0;
-+ memcpy(page_05.DataBytesperSector, &sector, sizeof(sector));
-+ memcpy(page_05.NumberofCylinders, &cylinder, sizeof(cylinder));
-+ }
-+ else{
-+ sector = (unsigned short)DeviceBlockSize;
-+ size = DEF_NUMBER_OF_HEADS * DEF_SECTORS_PER_TRACK * sector;
-+ cylinder = DeviceSize / size;
-+ sector = htons(sector);
-+ cylinder = htons(cylinder);
-+
-+ page_05.NumberofHeads = DEF_NUMBER_OF_HEADS;
-+ page_05.SectorsperTrack = DEF_SECTORS_PER_TRACK;
-+ memcpy(page_05.DataBytesperSector, &sector, sizeof(sector));
-+ memcpy(page_05.NumberofCylinders, &cylinder, sizeof(cylinder));
-+ }
-+
-+ if(command->PC == 0 && command->PageCode == 0x01){
-+ data_len = sizeof(MODE_PARAMETER_HEADER) + sizeof(page_01);
-+ data.ModeParameterHeader.ModeDataLength = data_len - 1;
-+ memcpy(&data.ModePages, &page_01, sizeof(page_01));
-+ }
-+ else
-+ if(command->PC == 0 && command->PageCode == 0x05){
-+ data_len = sizeof(MODE_PARAMETER_HEADER) + sizeof(page_05);
-+ data.ModeParameterHeader.ModeDataLength = data_len - 1;
-+ memcpy(&data.ModePages, &page_05, sizeof(page_05));
-+ }
-+ else
-+ if(command->PC == 0 && command->PageCode == 0x1b){
-+ data_len = sizeof(MODE_PARAMETER_HEADER) + sizeof(page_1b);
-+ data.ModeParameterHeader.ModeDataLength = data_len - 1;
-+ memcpy(&data.ModePages, &page_1b, sizeof(page_1b));
-+ }
-+ else
-+ if(command->PC == 0 && command->PageCode == 0x1c){
-+ data_len = sizeof(MODE_PARAMETER_HEADER) + sizeof(page_1c);
-+ data.ModeParameterHeader.ModeDataLength = data_len - 1;
-+ memcpy(&data.ModePages, &page_1c, sizeof(page_1c));
-+ }
-+ else
-+ if(command->PC == 0 && command->PageCode == 0x3f){
-+ data_len = sizeof(MODE_PARAMETER_HEADER) + sizeof(MODE_ALL_PAGES);
-+ data.ModeParameterHeader.ModeDataLength = data_len - 1;
-+ memcpy(&data.ModePages.ModeAllPages.ReadWriteErrorRecoveryPage,
-+ &page_01, sizeof(page_01));
-+ memcpy(&data.ModePages.ModeAllPages.FlexibleDiskPage,
-+ &page_05, sizeof(page_05));
-+ memcpy(&data.ModePages.ModeAllPages.RemovableBlockAccessCapabilitiesPage,
-+ &page_1b, sizeof(page_1b));
-+ memcpy(&data.ModePages.ModeAllPages.TimerAndProtectPage,
-+ &page_1c, sizeof(page_1c));
-+ }
-+ else{
-+ /* command fail */
-+ status = 1;
-+ data_len = cbw->dCBWDataTransferLength;
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x05, 0x24, 0x00, 0x00);
-+ }
-+
-+ if(cbw->dCBWDataTransferLength < data_len){
-+ data_len = cbw->dCBWDataTransferLength;
-+ }
-+
-+ storage_urb_send(device, &data, data_len);
-+
-+ /*
-+ * status transport
-+ */
-+
-+ memset(&csw, 0x00, sizeof(csw));
-+
-+ csw.dCSWSignature = CSW_SIGNATURE;
-+ csw.dCSWTag = cbw->dCBWTag;
-+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength - data_len;
-+ csw.bCSWStatus = status;
-+
-+ storage_urb_send(device, &csw, sizeof(csw));
-+
-+ return;
-+}
-+
-+static void scsi_test_unit_ready_analysis(struct usb_device_instance* device,
-+ COMMAND_BLOCK_WRAPPER* cbw)
-+{
-+ COMMAND_STATUS_WRAPPER csw;
-+ unsigned char status = 0;
-+
-+ if(DeviceFile == NULL){
-+ /* command fail */
-+ status = 1;
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x02, 0x3a, 0x00, 0x00);
-+ }
-+ else
-+ if(MediaChange == MEDIA_CHANGE_ON){
-+ /* command fail */
-+ status = 1;
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x06, 0x28, 0x00, 0x00);
-+
-+ /* media change flag off */
-+ MediaChange = MEDIA_CHANGE_OFF;
-+ }
-+
-+ /*
-+ * status transport
-+ */
-+
-+ memset(&csw, 0x00, sizeof(csw));
-+
-+ csw.dCSWSignature = CSW_SIGNATURE;
-+ csw.dCSWTag = cbw->dCBWTag;
-+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength;
-+ csw.bCSWStatus = status;
-+
-+ storage_urb_send(device, &csw, sizeof(csw));
-+
-+ return;
-+}
-+
-+static void scsi_prevent_allow_medium_removal_analysis(struct usb_device_instance* device,
-+ COMMAND_BLOCK_WRAPPER* cbw)
-+{
-+ SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL_COMMAND* command = (SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL_COMMAND*)cbw->CBWCB;
-+ COMMAND_STATUS_WRAPPER csw;
-+ unsigned char status = 0;
-+
-+ if(command->Prevent){
-+ /* command fail */
-+ status = 1;
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x05, 0x24, 0x00, 0x00);
-+ }
-+
-+ /*
-+ * status transport
-+ */
-+
-+ memset(&csw, 0x00, sizeof(csw));
-+
-+ csw.dCSWSignature = CSW_SIGNATURE;
-+ csw.dCSWTag = cbw->dCBWTag;
-+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength;
-+ csw.bCSWStatus = status;
-+
-+ storage_urb_send(device, &csw, sizeof(csw));
-+
-+ return;
-+}
-+
-+static void scsi_start_stop_analysis(struct usb_device_instance* device,
-+ COMMAND_BLOCK_WRAPPER* cbw)
-+{
-+ SCSI_START_STOP_COMMAND* command = (SCSI_START_STOP_COMMAND*)cbw->CBWCB;
-+ COMMAND_STATUS_WRAPPER csw;
-+ unsigned char status = 0;
-+
-+ if(DeviceFile == NULL){
-+ /* command fail */
-+ status = 1;
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x02, 0x3a, 0x00, 0x00);
-+ }
-+ else
-+ if(MediaChange == MEDIA_CHANGE_ON){
-+ /* command fail */
-+ status = 1;
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x06, 0x28, 0x00, 0x00);
-+
-+ /* media change flag off */
-+ MediaChange = MEDIA_CHANGE_OFF;
-+ }
-+ else
-+ if(command->Start && command->LoEj){
-+ /* command fail */
-+ status = 1;
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x05, 0x24, 0x00, 0x00);
-+ }
-+
-+ /* device buffer flush */
-+ if(DeviceFile && DeviceFile->f_op->ioctl(DeviceFile->f_dentry->d_inode,
-+ DeviceFile, BLKFLSBUF, 0) != 0){
-+ /* statistics update */
-+ StatDevFlushError++;
-+ printk(KERN_INFO "storage_fd: device flush error.\n");
-+ }
-+
-+ /*
-+ * status transport
-+ */
-+
-+ memset(&csw, 0x00, sizeof(csw));
-+
-+ csw.dCSWSignature = CSW_SIGNATURE;
-+ csw.dCSWTag = cbw->dCBWTag;
-+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength;
-+ csw.bCSWStatus = status;
-+
-+ storage_urb_send(device, &csw, sizeof(csw));
-+
-+ return;
-+}
-+
-+static void scsi_write_10_analysis(struct usb_device_instance* device,
-+ COMMAND_BLOCK_WRAPPER* cbw)
-+{
-+ /* status set */
-+ BulkOutLength = 0;
-+ StorageStatus = STORAGE_BULKOUT;
-+
-+ /* timer set */
-+ del_timer(&BulkOutTim);
-+ BulkOutTim.expires = jiffies + ((WR_BULKOUT_CHK_TIM * HZ) / 1000);
-+ BulkOutTim.data = 0;
-+ BulkOutTim.function = storage_bulkout_timeout;
-+ add_timer(&BulkOutTim);
-+
-+ return;
-+}
-+
-+static void scsi_verify_analysis(struct usb_device_instance* device,
-+ COMMAND_BLOCK_WRAPPER* cbw)
-+{
-+ COMMAND_STATUS_WRAPPER csw;
-+ unsigned char status = 0;
-+
-+ if(DeviceFile == NULL){
-+ /* command fail */
-+ status = 1;
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x02, 0x3a, 0x00, 0x00);
-+ }
-+ else
-+ if(MediaChange == MEDIA_CHANGE_ON){
-+ /* command fail */
-+ status = 1;
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x06, 0x28, 0x00, 0x00);
-+
-+ /* media change flag off */
-+ MediaChange = MEDIA_CHANGE_OFF;
-+ }
-+
-+ /*
-+ * status transport
-+ */
-+
-+ memset(&csw, 0x00, sizeof(csw));
-+
-+ csw.dCSWSignature = CSW_SIGNATURE;
-+ csw.dCSWTag = cbw->dCBWTag;
-+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength;
-+ csw.bCSWStatus = status;
-+
-+ storage_urb_send(device, &csw, sizeof(csw));
-+
-+ return;
-+}
-+
-+static void scsi_unsupport_analysis(struct usb_device_instance* device,
-+ COMMAND_BLOCK_WRAPPER* cbw)
-+{
-+ COMMAND_STATUS_WRAPPER csw;
-+ unsigned char data_len = 0;
-+
-+ if(((cbw->bmCBWFlags & 0x80) == 0x00) && (cbw->dCBWDataTransferLength)){
-+ /* BLKOUT */
-+
-+ /* status set */
-+ BulkOutLength = 0;
-+ StorageStatus = STORAGE_BULKOUT;
-+ }
-+ else{
-+ /* BLKIN */
-+
-+ if(cbw->dCBWDataTransferLength){
-+ data_len = cbw->dCBWDataTransferLength;
-+ storage_urb_send(device, NULL, data_len);
-+ }
-+
-+ /*
-+ * status transport
-+ */
-+
-+ memset(&csw, 0x00, sizeof(csw));
-+
-+ csw.dCSWSignature = CSW_SIGNATURE;
-+ csw.dCSWTag = cbw->dCBWTag;
-+ csw.dCSWDataResidue = cbw->dCBWDataTransferLength - data_len;
-+ csw.bCSWStatus = 0x01;
-+ storage_urb_send(device, &csw, sizeof(csw));
-+
-+ }
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x05, 0x20, 0x00, 0x00);
-+
-+ return;
-+}
-+
-+static void scsi_bulkout_write_10_analysis(struct usb_device_instance* device,
-+ void* buffer, int length)
-+{
-+ COMMAND_STATUS_WRAPPER csw;
-+ unsigned char status = 0;
-+ unsigned long buff_used_len, buff_offset;
-+ unsigned long s_tick, e_tick, wr_tick;
-+
-+ buff_offset = BulkOutLength % sizeof(BlockBuffer);
-+
-+ memcpy(BlockBuffer + buff_offset, buffer, length);
-+ BulkOutLength += length;
-+
-+ buff_used_len = BulkOutLength % sizeof(BlockBuffer);
-+ if(buff_used_len == 0) buff_used_len = sizeof(BlockBuffer);
-+
-+ /* delete timer */
-+ if(BulkOutLength >= KeepCBW.dCBWDataTransferLength){
-+ del_timer(&BulkOutTim);
-+ }
-+
-+ if(buff_used_len >= sizeof(BlockBuffer) ||
-+ BulkOutLength >= KeepCBW.dCBWDataTransferLength){
-+
-+ /* buffer full */
-+ SCSI_WRITE_10_COMMAND* command = (SCSI_WRITE_10_COMMAND*)&KeepCBW.CBWCB;
-+ unsigned short len;
-+ unsigned long lba, offset;
-+
-+ memcpy(&lba, command->LogicalBlockAddress, sizeof(lba));
-+ memcpy(&len, command->TransferLength, sizeof(len));
-+ lba = ntohl(lba);
-+ len = ntohs(len);
-+
-+ offset = (lba * DeviceBlockSize) +
-+ (sizeof(BlockBuffer) * ((BulkOutLength - 1) / sizeof(BlockBuffer)));
-+
-+ /* device check */
-+ if(DeviceFile &&
-+ MediaChange != MEDIA_CHANGE_ON &&
-+ DeviceWrProtect != WR_PROTECT_ON){
-+
-+ /* write before jiffies get */
-+ s_tick = jiffies;
-+
-+ /* device seek */
-+ DeviceFile->f_op->llseek(DeviceFile, offset, 0);
-+
-+ /* device write */
-+ if(DeviceFile->f_op->write(DeviceFile, BlockBuffer, buff_used_len,
-+ &DeviceFile->f_pos) != buff_used_len){
-+ /* statistics update */
-+ StatDevWriteError++;
-+ printk(KERN_INFO "storage_fd: device write error. length '%ld'.\n", buff_used_len);
-+ }
-+
-+ /* write after jiffies get */
-+ e_tick = jiffies;
-+
-+ /* statistics update */
-+ wr_tick = e_tick - s_tick;
-+ if(wr_tick > StatMaxWriteTime){
-+ StatMaxWriteTime = wr_tick;
-+ }
-+ }
-+ }
-+
-+ if(BulkOutLength >= KeepCBW.dCBWDataTransferLength){
-+ if(DeviceFile == NULL){
-+ /* command fail */
-+ status = 1;
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x02, 0x3a, 0x00, 0x00);
-+ }
-+ else
-+ if(MediaChange == MEDIA_CHANGE_ON){
-+ /* command fail */
-+ status = 1;
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x06, 0x28, 0x00, 0x00);
-+
-+ /* media change flag off */
-+ MediaChange = MEDIA_CHANGE_OFF;
-+ }
-+ else
-+ if(DeviceWrProtect == WR_PROTECT_ON){
-+ /* command fail */
-+ status = 1;
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x07, 0x27, 0x00, 0x00);
-+
-+ /* media change flag off */
-+ MediaChange = MEDIA_CHANGE_OFF;
-+ }
-+
-+ /*
-+ * status transport
-+ */
-+
-+ memset(&csw, 0x00, sizeof(csw));
-+
-+ csw.dCSWSignature = CSW_SIGNATURE;
-+ csw.dCSWTag = KeepCBW.dCBWTag;
-+ csw.dCSWDataResidue = KeepCBW.dCBWDataTransferLength - BulkOutLength;
-+ csw.bCSWStatus = status;
-+
-+ storage_urb_send(device, &csw, sizeof(csw));
-+
-+ /* status reset */
-+ BulkOutLength = 0;
-+ StorageStatus = STORAGE_IDLE;
-+
-+ /* flush before jiffies get */
-+ s_tick = jiffies;
-+
-+ /* device buffer flush */
-+ if(DeviceFile && DeviceFile->f_op->ioctl(DeviceFile->f_dentry->d_inode,
-+ DeviceFile, BLKFLSBUF, 0) != 0){
-+ /* statistics update */
-+ StatDevFlushError++;
-+ printk(KERN_INFO "storage_fd: device flush error.\n");
-+ }
-+
-+ /* flush after jiffies get */
-+ e_tick = jiffies;
-+
-+ /* statistics update */
-+ wr_tick = e_tick - s_tick;
-+ if(wr_tick > StatMaxWriteTime){
-+ StatMaxWriteTime = wr_tick;
-+ }
-+
-+ }
-+
-+ return;
-+}
-+
-+static void scsi_bulkout_unsupport_analysis(struct usb_device_instance* device,
-+ void* buffer, int length)
-+{
-+ COMMAND_STATUS_WRAPPER csw;
-+
-+ BulkOutLength += length;
-+
-+ if(BulkOutLength >= KeepCBW.dCBWDataTransferLength){
-+ /*
-+ * status transport
-+ */
-+
-+ memset(&csw, 0x00, sizeof(csw));
-+
-+ csw.dCSWSignature = CSW_SIGNATURE;
-+ csw.dCSWTag = KeepCBW.dCBWTag;
-+ csw.dCSWDataResidue = KeepCBW.dCBWDataTransferLength - BulkOutLength;
-+ csw.bCSWStatus = 1;
-+
-+ storage_urb_send(device, &csw, sizeof(csw));
-+
-+ /* error code save REQUEST SENSE */
-+ request_sense_data_set(0x05, 0x20, 0x00, 0x00);
-+
-+ /* status reset */
-+ BulkOutLength = 0;
-+ StorageStatus = STORAGE_IDLE;
-+ }
-+
-+ return;
-+}
-+
-+/******************************************************************************
-+** Global Function
-+******************************************************************************/
-+
-+static SCSI_ANALYSIS_TBL ScsiAnalysisTbl[] = {
-+ {SCSI_FORMAT_UNT, "SCSI_FORMAT_UNT", NULL},
-+ {SCSI_INQUIRY, "SCSI_INQUIRY", scsi_inquiry_analysis},
-+ {SCSI_START_STOP, "SCSI_START_STOP", scsi_start_stop_analysis},
-+ {SCSI_MODE_SELECT, "SCSI_MODE_SELECT", NULL},
-+ {SCSI_MODE_SENSE, "SCSI_MODE_SENSE", scsi_mode_sense_analysis},
-+ {SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL, "SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL", scsi_prevent_allow_medium_removal_analysis},
-+ {SCSI_READ_10, "SCSI_READ_10", scsi_read_10_analysis},
-+ {SCSI_READ_12, "SCSI_READ_12", NULL},
-+ {SCSI_READ_CAPACITY, "SCSI_READ_CAPACITY", scsi_read_capacity_analysis},
-+ {SCSI_READ_FORMAT_CAPACITY, "SCSI_READ_FORMAT_CAPACITY", scsi_read_format_capacity_analysis},
-+ {SCSI_REQUEST_SENSE, "SCSI_REQUEST_SENSE", scsi_request_sense_analysis},
-+ {SCSI_REZERO_UNIT, "SCSI_REZERO_UNIT", NULL},
-+ {SCSI_SEEK_10, "SCSI_SEEK_10", NULL},
-+ {SCSI_SEND_DIAGNOSTIC, "SCSI_SEND_DIAGNOSTIC", NULL},
-+ {SCSI_TEST_UNIT_READY, "SCSI_TEST_UNIT_READY", scsi_test_unit_ready_analysis},
-+ {SCSI_VERIFY, "SCSI_VERIFY", scsi_verify_analysis},
-+ {SCSI_WRITE_10, "SCSI_WRITE_10", scsi_write_10_analysis},
-+ {SCSI_WRITE_12, "SCSI_WRITE_12", NULL},
-+ {SCSI_WRITE_AND_VERIFY, "SCSI_WRITE_AND_VERIFY", NULL}
-+};
-+
-+static SCSI_BULKOUT_ANALYSIS_TBL ScsiBlkOutAnalysisTbl[] = {
-+ {SCSI_WRITE_10, "SCSI_WRITE_10", scsi_bulkout_write_10_analysis},
-+};
-+
-+void storageproto_urb_analysis(struct urb* urb)
-+{
-+ COMMAND_BLOCK_WRAPPER* cbw = (COMMAND_BLOCK_WRAPPER*)urb->buffer;
-+ int i;
-+
-+ /* status BLKOUT check */
-+ if(StorageStatus == STORAGE_BULKOUT){
-+ for(i = 0;
-+ i < sizeof(ScsiBlkOutAnalysisTbl) / sizeof(SCSI_ANALYSIS_TBL);
-+ i++){
-+ if(ScsiBlkOutAnalysisTbl[i].scsi_command == KeepCBW.CBWCB[0]){
-+ if(ScsiBlkOutAnalysisTbl[i].bulkout_func){
-+ ScsiBlkOutAnalysisTbl[i].bulkout_func(urb->device,
-+ urb->buffer,
-+ urb->actual_length);
-+ goto RETURN_LABEL;
-+ }
-+ break;
-+ }
-+ }
-+ scsi_bulkout_unsupport_analysis(urb->device, urb->buffer, urb->actual_length);
-+ goto RETURN_LABEL;
-+ }
-+
-+ /* signature check */
-+ if(cbw->dCBWSignature != CBW_SIGNATURE){
-+ printk(KERN_INFO "storage_fd: signature error. '0x%08lx'.\n",
-+ cbw->dCBWSignature);
-+ goto RETURN_LABEL;
-+ }
-+
-+ /* statistics set */
-+ if(cbw->dCBWDataTransferLength){
-+ if(((cbw->bmCBWFlags & 0x80) == 0x00) && (cbw->dCBWDataTransferLength)){
-+ /* BULK OUT */
-+ if(StatMaxBulkOutSize < cbw->dCBWDataTransferLength){
-+ StatMaxBulkOutSize = cbw->dCBWDataTransferLength;
-+ }
-+ }
-+ else{
-+ /* BULK IN */
-+ if(StatMaxBulkInSize < cbw->dCBWDataTransferLength){
-+ StatMaxBulkInSize = cbw->dCBWDataTransferLength;
-+ }
-+ }
-+ }
-+
-+ /* save CBW and set storage status */
-+ memcpy(&KeepCBW, cbw, sizeof(KeepCBW));
-+
-+ /* UFI command analysis */
-+ for(i = 0; i < sizeof(ScsiAnalysisTbl) / sizeof(SCSI_ANALYSIS_TBL); i++){
-+ if(ScsiAnalysisTbl[i].scsi_command == cbw->CBWCB[0]){
-+ if(ScsiAnalysisTbl[i].scsi_func){
-+ ScsiAnalysisTbl[i].scsi_func(urb->device, cbw);
-+ goto RETURN_LABEL;
-+ }
-+ break;
-+ }
-+ }
-+
-+ scsi_unsupport_analysis(urb->device, cbw);
-+ printk(KERN_INFO "storage_fd: SCSI command error. '0x%02x'.\n",
-+ cbw->CBWCB[0]);
-+ goto RETURN_LABEL;
-+
-+RETURN_LABEL:
-+
-+ /* URB free */
-+ usbd_recycle_urb(urb);
-+
-+ return;
-+}
-+
-+int storageproto_device_open_check(void)
-+{
-+ struct file* file;
-+ struct inode* inode;
-+ kdev_t dev;
-+ int read_org;
-+
-+ /* device already open check */
-+ if(DeviceFile){
-+ storageproto_device_close();
-+ }
-+
-+ /* device open */
-+ file = filp_open(storage_device, O_RDWR, 0000);
-+ if(IS_ERR(file)){
-+ file = filp_open(storage_device, O_RDONLY, 0000);
-+ if(IS_ERR(file)){
-+ storageproto_device_close();
-+ return MEDIA_EJECT;
-+ }
-+ DeviceWrProtect = WR_PROTECT_ON;
-+ }
-+
-+ file->f_op->llseek(file, 0, 0);
-+ if(file->f_op->read(file, (void*)&read_org, sizeof(read_org), &file->f_pos)
-+ != sizeof(read_org)){
-+ filp_close(file, NULL);
-+ storageproto_device_close();
-+ return MEDIA_EJECT;
-+ }
-+
-+ /* struct file pointer save */
-+ DeviceFile = file;
-+
-+ /* device information */
-+ inode = file->f_dentry->d_inode;
-+ dev = inode->i_rdev;
-+
-+ if (blk_size[MAJOR(dev)]){
-+ DeviceSize = blk_size[MAJOR(dev)][MINOR(dev)] << BLOCK_SIZE_BITS;
-+ }
-+ else{
-+ DeviceSize = INT_MAX << BLOCK_SIZE_BITS;
-+ }
-+
-+ if(blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)]){
-+ DeviceBlockSize = DEVICE_BLOCK_SIZE;
-+ }
-+ else{
-+ DeviceBlockSize = DEVICE_BLOCK_SIZE;
-+ }
-+
-+ return MEDIA_INSERT;
-+}
-+
-+void storageproto_device_close(void)
-+{
-+ if(DeviceFile){
-+ filp_close(DeviceFile, NULL);
-+ DeviceFile = NULL;
-+ DeviceSize = 0;
-+ DeviceBlockSize = DEVICE_BLOCK_SIZE;
-+ DeviceWrProtect = WR_PROTECT_OFF;
-+ }
-+
-+ return;
-+}
-+
-+void storageproto_usb_status_check(int status)
-+{
-+ static int Is1stCheck = 1;
-+
-+ /* USB status check */
-+ if(Is1stCheck){
-+ Is1stCheck = 0;
-+ }
-+ else{
-+ if(UsbStatus == status) goto RETURN_LABEL;
-+ }
-+
-+ /* set status */
-+ UsbStatus = status;
-+
-+ switch(UsbStatus){
-+ case USB_CONNECT:
-+ /* media status check */
-+ storageproto_media_status_check(CONTEXT_SCHEDULE);
-+
-+ switch(MediaStatus){
-+ case MEDIA_EJECT:
-+ break;
-+
-+ case MEDIA_INSERT:
-+ hotplug("usbdstorage", storage_device, "umount");
-+ break;
-+
-+ default:
-+ break;
-+ }
-+ hotplug("usbdstorage", storage_device, "connect");
-+ break;
-+
-+ case USB_DISCONNECT:
-+ /* device close */
-+ storageproto_device_close();
-+
-+ switch(MediaStatus){
-+ case MEDIA_EJECT:
-+ break;
-+
-+ case MEDIA_INSERT:
-+ hotplug("usbdstorage", storage_device, "mount");
-+ break;
-+
-+ default:
-+ break;
-+ }
-+ hotplug("usbdstorage", storage_device, "disconnect");
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+RETURN_LABEL:
-+ DBG_STORAGE_FD(KERN_INFO "storage_fd: USB check '%s' '%s' 'file:%p'.\n",
-+ (UsbStatus) ? "USB_CONNECT" : "USB_DISCONNECT",
-+ (MediaStatus) ? "MEDIA_INSERT" : "MEDIA_EJECT", DeviceFile);
-+
-+ return;
-+}
-+
-+void storageproto_media_status_check(int call_context)
-+{
-+ static unsigned long RetryCount = 0;
-+ int status;
-+
-+ /* media open check */
-+ status = storageproto_device_open_check();
-+
-+ /* media status check retry */
-+ if(status == MEDIA_EJECT){
-+ switch(call_context){
-+ case CONTEXT_STORAGE:
-+
-+ /* retry counter init */
-+ RetryCount = 0;
-+
-+ /* timer set */
-+ del_timer(&MediaCheckTim);
-+ MediaCheckTim.expires = jiffies + ((MEDIA_CHECK_TIM * HZ) / 1000);
-+ MediaCheckTim.data = 0;
-+ MediaCheckTim.function = media_check_timeout;
-+ add_timer(&MediaCheckTim);
-+
-+ break;
-+
-+ case CONTEXT_TIMER:
-+
-+ /* retry counter update */
-+ RetryCount++;
-+
-+ /* retry counter check */
-+ if(RetryCount >= MEDIA_CHECK_RETRY) break;
-+
-+ /* timer set */
-+ del_timer(&MediaCheckTim);
-+ MediaCheckTim.expires = jiffies + ((MEDIA_CHECK_TIM * HZ) / 1000);
-+ MediaCheckTim.data = 0;
-+ MediaCheckTim.function = media_check_timeout;
-+ add_timer(&MediaCheckTim);
-+
-+ break;
-+
-+ default:
-+ break;
-+ }
-+ }
-+ else
-+ if(status == MEDIA_INSERT){
-+ /* delete timer */
-+ del_timer(&MediaCheckTim);
-+ }
-+
-+ /* media status check */
-+ if(status == MediaStatus){
-+ if(UsbStatus == USB_DISCONNECT){
-+ storageproto_device_close();
-+ }
-+ if(MediaStatus == MEDIA_INSERT){
-+ if(call_context == CONTEXT_STORAGE || call_context == CONTEXT_TIMER){
-+ MediaChange = MEDIA_CHANGE_ON;
-+ }
-+ }
-+ goto RETURN_LABEL;
-+ }
-+
-+ /* set status */
-+ MediaStatus = status;
-+
-+ switch(MediaStatus){
-+ case MEDIA_INSERT:
-+ /* set status */
-+ MediaChange = MEDIA_CHANGE_ON;
-+
-+ switch(UsbStatus){
-+ case USB_DISCONNECT:
-+ storageproto_device_close();
-+ break;
-+
-+ case USB_CONNECT:
-+ break;
-+
-+ default:
-+ break;
-+ }
-+ hotplug("usbdstorage", storage_device, "insert");
-+ break;
-+
-+ case MEDIA_EJECT:
-+ switch(UsbStatus){
-+ case USB_DISCONNECT:
-+ storageproto_device_close();
-+ break;
-+
-+ case USB_CONNECT:
-+ break;
-+
-+ default:
-+ break;
-+ }
-+ hotplug("usbdstorage", storage_device, "eject");
-+ break;
-+
-+ default:
-+ break;
-+ }
-+
-+RETURN_LABEL:
-+ DBG_STORAGE_FD(KERN_INFO "storage_fd: media check. '%s' '%s' 'file:%p' '%s'.\n",
-+ (UsbStatus) ? "USB_CONNECT" : "USB_DISCONNECT",
-+ (MediaStatus) ? "MEDIA_INSERT" : "MEDIA_EJECT", DeviceFile,
-+ (call_context == CONTEXT_SCHEDULE) ? "CONTEXT_SCHEDULE" :
-+ (call_context == CONTEXT_STORAGE) ? "CONTEXT_STORAGE" : "CONTEXT_TIMER");
-+
-+ return;
-+}
-+
-+void storageproto_usb_reset_ind(void)
-+{
-+ /* status reset */
-+ BulkOutLength = 0;
-+ StorageStatus = STORAGE_IDLE;
-+
-+ DBG_STORAGE_FD(KERN_INFO "storage_fd: storage protocol reset.\n");
-+
-+ return;
-+}
-+
-+void storageproto_init(void)
-+{
-+ /* timer init */
-+ init_timer(&BulkOutTim);
-+
-+ /* timer init */
-+ init_timer(&MediaCheckTim);
-+
-+ return;
-+}
-+
-+void storageproto_exit(void)
-+{
-+ /* device close */
-+ storageproto_device_close();
-+
-+ /* delete timer */
-+ del_timer(&BulkOutTim);
-+
-+ /* delete timer */
-+ del_timer(&MediaCheckTim);
-+
-+ return;
-+}
-+
-+ssize_t storageproto_proc_read(struct file* file, char* buf, size_t count,
-+ loff_t* pos)
-+{
-+ char string[1024];
-+ int len = 0;
-+
-+ len += sprintf(string + len, "Protocol status:%s\n",
-+ (StorageStatus == STORAGE_IDLE) ? "STORAGE_IDLE" :
-+ (StorageStatus == STORAGE_BULKIN) ? "STORAGE_BULKIN" :
-+ "STORAGE_BULKOUT");
-+
-+ len += sprintf(string + len, "USB status:%s\n",
-+ (UsbStatus == USB_DISCONNECT) ? "USB_DISCONNECT" :
-+ "USB_CONNECT");
-+
-+ len += sprintf(string + len, "Media status:%s\n",
-+ (MediaStatus == MEDIA_EJECT) ? "MEDIA_EJECT" :
-+ "MEDIA_INSERT");
-+
-+ len += sprintf(string + len, "Media chage:%s\n",
-+ (MediaChange == MEDIA_CHANGE_OFF) ? "MEDIA_CHANGE_OFF" :
-+ "MEDIA_CHANGE_ON");
-+
-+ len += sprintf(string + len, "Device name:%s\n",
-+ storage_device);
-+
-+ len += sprintf(string + len, "Device file descriptor:0x%p\n",
-+ DeviceFile);
-+
-+ len += sprintf(string + len, "Device size:0x%d\n",
-+ DeviceSize);
-+
-+ len += sprintf(string + len, "Device block size:0x%d\n",
-+ DeviceBlockSize);
-+
-+ len += sprintf(string + len, "Device write protect:%s\n",
-+ (DeviceWrProtect == WR_PROTECT_OFF) ? "WR_PROTECT_OFF":
-+ "WR_PROTECT_ON");
-+
-+ len += sprintf(string + len, "Bulk in max size:%ld\n",
-+ StatMaxBulkInSize);
-+
-+ len += sprintf(string + len, "Bulk out max size:%ld\n",
-+ StatMaxBulkOutSize);
-+
-+ len += sprintf(string + len, "device write error:%ld\n",
-+ StatDevWriteError);
-+
-+ len += sprintf(string + len, "device read error:%ld\n",
-+ StatDevReadError);
-+
-+ len += sprintf(string + len, "device flush error:%ld\n",
-+ StatDevFlushError);
-+
-+ len += sprintf(string + len, "write data bulk out timout:%ld\n",
-+ StatWriteTimout);
-+
-+ len += sprintf(string + len, "device write max time:%ld msec\n",
-+ (StatMaxWriteTime * 1000) / HZ);
-+
-+ *pos += len;
-+ if(len > count){
-+ len = -EINVAL;
-+ }
-+ else
-+ if(len > 0 && copy_to_user(buf, string, len)) {
-+ len = -EFAULT;
-+ }
-+
-+ return len;
-+}
-+
-diff -Nur linux-2.4.18/drivers/usb/device/storage_fd/storageproto.h linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/storageproto.h
---- linux-2.4.18/drivers/usb/device/storage_fd/storageproto.h 1970-01-01 03:00:00.000000000 +0300
-+++ linux-2.4.18-usb-storage/drivers/usb/device/storage_fd/storageproto.h 2003-11-07 05:34:43.000000000 +0300
-@@ -0,0 +1,585 @@
-+/*
-+ * linux/drivers/usb/device/storage_fd/storageproto.h - mass storage protocol library header
-+ *
-+ * Copyright (c) 2003 Lineo Solutions, Inc.
-+ *
-+ * Written by Shunnosuke kabata
-+ *
-+ * 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 _STORAGEPROTO_H_
-+#define _STORAGEPROTO_H_
-+
-+/******************************************************************************
-+** Macro Define
-+******************************************************************************/
-+
-+/**************************************
-+** Class Code
-+**************************************/
-+
-+/*
-+ * Class
-+ */
-+
-+#define MASS_STORAGE_CLASS 0x08
-+
-+/*
-+ * SubClass
-+ */
-+
-+#define MASS_STORAGE_SUBCLASS_RBC 0x01
-+#define MASS_STORAGE_SUBCLASS_SFF8020I 0x02
-+#define MASS_STORAGE_SUBCLASS_QIC157 0x03
-+#define MASS_STORAGE_SUBCLASS_UFI 0x04
-+#define MASS_STORAGE_SUBCLASS_SFF8070I 0x05
-+#define MASS_STORAGE_SUBCLASS_SCSI 0x06
-+
-+/*
-+ * Protocol
-+ */
-+
-+#define MASS_STORAGE_PROTO_CBI_WITH_COMP 0x00
-+#define MASS_STORAGE_PROTO_CBI_NO_COMP 0x01
-+#define MASS_STORAGE_PROTO_BULK_ONLY 0x50
-+
-+/**************************************
-+** SCSI Command
-+**************************************/
-+
-+#define SCSI_FORMAT_UNT 0x04
-+#define SCSI_INQUIRY 0x12
-+#define SCSI_START_STOP 0x1b
-+#define SCSI_MODE_SELECT 0x55
-+#define SCSI_MODE_SENSE 0x1a
-+#define SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1e
-+#define SCSI_READ_10 0x28
-+#define SCSI_READ_12 0xa8
-+#define SCSI_READ_CAPACITY 0x25
-+#define SCSI_READ_FORMAT_CAPACITY 0x23
-+#define SCSI_REQUEST_SENSE 0x03
-+#define SCSI_REZERO_UNIT 0x01
-+#define SCSI_SEEK_10 0x2b
-+#define SCSI_SEND_DIAGNOSTIC 0x1d
-+#define SCSI_TEST_UNIT_READY 0x00
-+#define SCSI_VERIFY 0x2f
-+#define SCSI_WRITE_10 0x2a
-+#define SCSI_WRITE_12 0xaa
-+#define SCSI_WRITE_AND_VERIFY 0x2e
-+
-+/**************************************
-+** SCSI Command Parameter
-+**************************************/
-+
-+#define CBW_SIGNATURE 0x43425355 /* USBC */
-+#define CSW_SIGNATURE 0x53425355 /* USBS */
-+
-+#define PRODUCT_REVISION_LEVEL "1.00"
-+
-+/**************************************
-+** Status
-+**************************************/
-+
-+#define WR_PROTECT_OFF 0
-+#define WR_PROTECT_ON 1
-+
-+#define STORAGE_IDLE 0
-+#define STORAGE_BULKIN 1
-+#define STORAGE_BULKOUT 2
-+
-+#define USB_DISCONNECT 0
-+#define USB_CONNECT 1
-+
-+#define MEDIA_EJECT 0
-+#define MEDIA_INSERT 1
-+
-+#define MEDIA_CHANGE_OFF 0
-+#define MEDIA_CHANGE_ON 1
-+
-+/**************************************
-+** Mass Storage Thread Name
-+**************************************/
-+
-+#define STORAGE_THREAD_NAME "usbdstorage"
-+
-+/**************************************
-+** Media Signal Delay Time(ms)
-+**************************************/
-+
-+#define USB_EVENT_DELAY_TIM 1000
-+
-+/**************************************
-+** Write Bulk Out Check Time(ms)
-+**************************************/
-+
-+#define WR_BULKOUT_CHK_TIM 1000
-+
-+/**************************************
-+** Media Check Time(ms)
-+**************************************/
-+
-+#define MEDIA_CHECK_TIM 3000
-+#define MEDIA_CHECK_RETRY 3
-+
-+/**************************************
-+** Context
-+**************************************/
-+
-+#define CONTEXT_SCHEDULE 0
-+#define CONTEXT_STORAGE 1
-+#define CONTEXT_TIMER 2
-+
-+/**************************************
-+** Debug Message
-+**************************************/
-+#if 0
-+#define DBG_STORAGE_FD(fmt, args...) printk(fmt, ##args)
-+#else
-+#define DBG_STORAGE_FD(fmt, args...)
-+#endif
-+
-+/******************************************************************************
-+** Structure Define
-+******************************************************************************/
-+
-+/**************************************
-+** Command Block Wrapper / Command Status Wrapper
-+**************************************/
-+
-+/*
-+ * Command Block Wrapper
-+ */
-+typedef struct{
-+ unsigned long dCBWSignature;
-+ unsigned long dCBWTag;
-+ unsigned long dCBWDataTransferLength;
-+ unsigned char bmCBWFlags;
-+ unsigned char bCBWLUN:4,
-+ Reserved:4;
-+ unsigned char bCBWCBLength:5,
-+ Reserved2:3;
-+ unsigned char CBWCB[16];
-+} __attribute__((packed)) COMMAND_BLOCK_WRAPPER;
-+
-+/*
-+ * Command Status Wrapper
-+ */
-+typedef struct{
-+ unsigned long dCSWSignature;
-+ unsigned long dCSWTag;
-+ unsigned long dCSWDataResidue;
-+ unsigned char bCSWStatus;
-+} __attribute__((packed)) COMMAND_STATUS_WRAPPER;
-+
-+/**************************************
-+** SCSI Command
-+**************************************/
-+
-+/*
-+ * INQUIRY
-+ */
-+
-+typedef struct{
-+ unsigned char OperationCode;
-+ unsigned char EVPD:1,
-+ Reserved1:4,
-+ LogicalUnitNumber:3;
-+ unsigned char PageCode;
-+ unsigned char Reserved2;
-+ unsigned char AllocationLength;
-+ unsigned char Reserved3;
-+ unsigned char Reserved4;
-+ unsigned char Reserved5;
-+ unsigned char Reserved6;
-+ unsigned char Reserved7;
-+ unsigned char Reserved8;
-+ unsigned char Reserved9;
-+} __attribute__((packed)) SCSI_INQUIRY_COMMAND;
-+
-+typedef struct{
-+ unsigned char PeripheralDeviceType:5,
-+ Reserved1:3;
-+ unsigned char Reserved2:7,
-+ RMB:1;
-+ unsigned char ANSIVersion:3,
-+ ECMAVersion:3,
-+ ISOVersion:2;
-+ unsigned char ResponseDataFormat:4,
-+ Reserved3:4;
-+ unsigned char AdditionalLength;
-+ unsigned char Reserved4;
-+ unsigned char Reserved5;
-+ unsigned char Reserved6;
-+ unsigned char VendorInformation[8];
-+ unsigned char ProductIdentification[16];
-+ unsigned char ProductRevisionLevel[4];
-+} __attribute__((packed)) SCSI_INQUIRY_DATA;
-+
-+/*
-+ * READ FORMAT CAPACITY
-+ */
-+
-+typedef struct{
-+ unsigned char OperationCode;
-+ unsigned char Reserved1:5,
-+ LogicalUnitNumber:3;
-+ unsigned char Reserved2;
-+ unsigned char Reserved3;
-+ unsigned char Reserved4;
-+ unsigned char Reserved5;
-+ unsigned char Reserved6;
-+ unsigned char AllocationLength[2];
-+ unsigned char Reserved7;
-+ unsigned char Reserved8;
-+ unsigned char Reserved9;
-+} __attribute__((packed)) SCSI_READ_FORMAT_CAPACITY_COMMAND;
-+
-+typedef struct{
-+ struct{
-+ unsigned char Reserved1;
-+ unsigned char Reserved2;
-+ unsigned char Reserved3;
-+ unsigned char CapacityListLength;
-+ } __attribute__((packed)) CapacityListHeader;
-+ struct{
-+ unsigned char NumberofBlocks[4];
-+ unsigned char DescriptorCode:2,
-+ Reserved1:6;
-+ unsigned char BlockLength[3];
-+ } __attribute__((packed)) CurrentMaximumCapacityDescriptor;
-+} __attribute__((packed)) SCSI_READ_FORMAT_CAPACITY_DATA;
-+
-+/*
-+ * READ FORMAT CAPACITY
-+ */
-+
-+typedef struct{
-+ unsigned char OperationCode;
-+ unsigned char RelAdr:1,
-+ Reserved1:4,
-+ LogicalUnitNumber:3;
-+ unsigned char LogicalBlockAddress[4];
-+ unsigned char Reserved2;
-+ unsigned char Reserved3;
-+ unsigned char PMI:1,
-+ Reserved4:7;
-+ unsigned char Reserved5;
-+ unsigned char Reserved6;
-+ unsigned char Reserved7;
-+} __attribute__((packed)) SCSI_READ_CAPACITY_COMMAND;
-+
-+typedef struct{
-+ unsigned char LastLogicalBlockAddress[4];
-+ unsigned char BlockLengthInBytes[4];
-+} __attribute__((packed)) SCSI_READ_CAPACITY_DATA;
-+
-+/*
-+ * REQUEST SENSE
-+ */
-+
-+typedef struct{
-+ unsigned char OperationCode;
-+ unsigned char Reserved1:5,
-+ LogicalUnitNumber:3;
-+ unsigned char Reserved2;
-+ unsigned char Reserved3;
-+ unsigned char AllocationLength;
-+ unsigned char Reserved4;
-+ unsigned char Reserved5;
-+ unsigned char Reserved6;
-+ unsigned char Reserved7;
-+ unsigned char Reserved8;
-+ unsigned char Reserved9;
-+ unsigned char Reserved10;
-+} __attribute__((packed)) SCSI_REQUEST_SENSE_COMMAND;
-+
-+typedef struct{
-+ unsigned char ErrorCode:7,
-+ Valid:1;
-+ unsigned char Reserved1;
-+ unsigned char SenseKey:4,
-+ Reserved2:4;
-+ unsigned char Information[4];
-+ unsigned char AdditionalSenseLength;
-+ unsigned char Reserved3[4];
-+ unsigned char AdditionalSenseCode;
-+ unsigned char AdditionalSenseCodeQualifier;
-+ unsigned char Reserved4;
-+ unsigned char Reserved5[3];
-+} __attribute__((packed)) SCSI_REQUEST_SENSE_DATA;
-+
-+/*
-+ * READ(10)
-+ */
-+
-+typedef struct{
-+ unsigned char OperationCode;
-+ unsigned char RelAdr:1,
-+ Reserved1:2,
-+ FUA:1,
-+ DPO:1,
-+ LogicalUnitNumber:3;
-+ unsigned char LogicalBlockAddress[4];
-+ unsigned char Reserved2;
-+ unsigned char TransferLength[2];
-+ unsigned char Reserved3;
-+ unsigned char Reserved4;
-+ unsigned char Reserved5;
-+} __attribute__((packed)) SCSI_READ_10_COMMAND;
-+
-+/*
-+ * MODE SENSE
-+ */
-+
-+typedef struct{
-+ unsigned char OperationCode;
-+ unsigned char Reserved1:3,
-+ DBD:1,
-+ Reserved2:1,
-+ LogicalUnitNumber:3;
-+ unsigned char PageCode:6,
-+ PC:2;
-+ unsigned char Reserved3;
-+ unsigned char Reserved4;
-+ unsigned char Reserved5;
-+ unsigned char Reserved6;
-+ unsigned char ParameterListLength[2];
-+ unsigned char Reserved7;
-+ unsigned char Reserved8;
-+ unsigned char Reserved9;
-+} __attribute__((packed)) SCSI_MODE_SENSE_COMMAND;
-+
-+typedef struct{
-+ unsigned char ModeDataLength;
-+ unsigned char MediumTypeCode;
-+ unsigned char Reserved1:4,
-+ DPOFUA:1,
-+ Reserved2:2,
-+ WP:1;
-+ unsigned char Reserved3;
-+} __attribute__((packed)) MODE_PARAMETER_HEADER;
-+
-+typedef struct{
-+ unsigned char PageCode:6,
-+ Reserved1:1,
-+ PS:1;
-+ unsigned char PageLength;
-+ unsigned char DCR:1,
-+ Reserved2:1,
-+ PER:1,
-+ Reserved3:1,
-+ RC:1,
-+ Reserved4:1,
-+ Reserved5:1,
-+ AWRE:1;
-+ unsigned char ReadRetryCount;
-+ unsigned char Reserved6[4];
-+ unsigned char WriteRetryCount;
-+ unsigned char Reserved7[3];
-+} __attribute__((packed)) READ_WRITE_ERROR_RECOVERY_PAGE;
-+
-+typedef struct{
-+ unsigned char PageCode:6,
-+ Reserved1:1,
-+ PS:1;
-+ unsigned char PageLength;
-+ unsigned char TransferRate[2];
-+ unsigned char NumberofHeads;
-+ unsigned char SectorsperTrack;
-+ unsigned char DataBytesperSector[2];
-+ unsigned char NumberofCylinders[2];
-+ unsigned char Reserved2[9];
-+ unsigned char MotorOnDelay;
-+ unsigned char MotorOffDelay;
-+ unsigned char Reserved3[7];
-+ unsigned char MediumRotationRate[2];
-+ unsigned char Reserved4;
-+ unsigned char Reserved5;
-+} __attribute__((packed)) FLEXIBLE_DISK_PAGE;
-+
-+typedef struct{
-+ unsigned char PageCode:6,
-+ Reserved1:1,
-+ PS:1;
-+ unsigned char PageLength;
-+ unsigned char Reserved2:6,
-+ SRFP:1,
-+ SFLP:1;
-+ unsigned char TLUN:3,
-+ Reserved3:3,
-+ SML:1,
-+ NCD:1;
-+ unsigned char Reserved4[8];
-+} __attribute__((packed)) REMOVABLE_BLOCK_ACCESS_CAPABILITIES_PAGE;
-+
-+typedef struct{
-+ unsigned char PageCode:6,
-+ Reserved1:1,
-+ PS:1;
-+ unsigned char PageLength;
-+ unsigned char Reserved2;
-+ unsigned char InactivityTimeMultiplier:4,
-+ Reserved3:4;
-+ unsigned char SWPP:1,
-+ DISP:1,
-+ Reserved4:6;
-+ unsigned char Reserved5;
-+ unsigned char Reserved6;
-+ unsigned char Reserved7;
-+} __attribute__((packed)) TIMER_AND_PROTECT_PAGE;
-+
-+typedef struct{
-+ READ_WRITE_ERROR_RECOVERY_PAGE ReadWriteErrorRecoveryPage;
-+ FLEXIBLE_DISK_PAGE FlexibleDiskPage;
-+ REMOVABLE_BLOCK_ACCESS_CAPABILITIES_PAGE RemovableBlockAccessCapabilitiesPage;
-+ TIMER_AND_PROTECT_PAGE TimerAndProtectPage;
-+} __attribute__((packed)) MODE_ALL_PAGES;
-+
-+typedef struct{
-+ MODE_PARAMETER_HEADER ModeParameterHeader;
-+ union{
-+ READ_WRITE_ERROR_RECOVERY_PAGE ReadWriteErrorRecoveryPage;
-+ FLEXIBLE_DISK_PAGE FlexibleDiskPage;
-+ REMOVABLE_BLOCK_ACCESS_CAPABILITIES_PAGE RemovableBlockAccessCapabilitiesPage;
-+ TIMER_AND_PROTECT_PAGE TimerAndProtectPage;
-+ MODE_ALL_PAGES ModeAllPages;
-+ } __attribute__((packed)) ModePages;
-+} __attribute__((packed)) SCSI_MODE_SENSE_DATA;
-+
-+/*
-+ * TEST UNIT READY
-+ */
-+
-+typedef struct{
-+ unsigned char OperationCode;
-+ unsigned char Reserved1:5,
-+ LogicalUnitNumber:3;
-+ unsigned char Reserved2;
-+ unsigned char Reserved3;
-+ unsigned char Reserved4;
-+ unsigned char Reserved5;
-+ unsigned char Reserved6;
-+ unsigned char Reserved7;
-+ unsigned char Reserved8;
-+ unsigned char Reserved9;
-+ unsigned char Reserved10;
-+ unsigned char Reserved11;
-+} __attribute__((packed)) SCSI_TEST_UNIT_READY_COMMAND;
-+
-+/*
-+ * PREVENT-ALLOW MEDIUM REMOVAL
-+ */
-+
-+typedef struct{
-+ unsigned char OperationCode;
-+ unsigned char Reserved1:5,
-+ LogicalUnitNumber:3;
-+ unsigned char Reserved2;
-+ unsigned char Reserved3;
-+ unsigned char Prevent:1,
-+ Reserved4:7;
-+ unsigned char Reserved5;
-+ unsigned char Reserved6;
-+ unsigned char Reserved7;
-+ unsigned char Reserved8;
-+ unsigned char Reserved9;
-+ unsigned char Reserved10;
-+ unsigned char Reserved11;
-+} __attribute__((packed)) SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL_COMMAND;
-+
-+/*
-+ * START-STOP UNIT
-+ */
-+
-+typedef struct{
-+ unsigned char OperationCode;
-+ unsigned char IMMED:1,
-+ Reserved1:4,
-+ LogicalUnitNumber:3;
-+ unsigned char Reserved2;
-+ unsigned char Reserved3;
-+ unsigned char Start:1,
-+ LoEj:1,
-+ Reserved4:6;
-+ unsigned char Reserved5;
-+ unsigned char Reserved6;
-+ unsigned char Reserved7;
-+ unsigned char Reserved8;
-+ unsigned char Reserved9;
-+ unsigned char Reserved10;
-+ unsigned char Reserved11;
-+} __attribute__((packed)) SCSI_START_STOP_COMMAND;
-+
-+/*
-+ * WRITE(10)
-+ */
-+
-+typedef struct{
-+ unsigned char OperationCode;
-+ unsigned char RelAdr:1,
-+ Reserved1:2,
-+ FUA:1,
-+ DPO:1,
-+ LogicalUnitNumber:3;
-+ unsigned char LogicalBlockAddress[4];
-+ unsigned char Reserved2;
-+ unsigned char TransferLength[2];
-+ unsigned char Reserved3;
-+ unsigned char Reserved4;
-+ unsigned char Reserved5;
-+} __attribute__((packed)) SCSI_WRITE_10_COMMAND;
-+
-+/*
-+ * VERIFY
-+ */
-+
-+typedef struct{
-+ unsigned char OperationCode;
-+ unsigned char RelAdr:1,
-+ ByteChk:1,
-+ Reserved1:1,
-+ Reserved2:1,
-+ DPO:1,
-+ LogicalUnitNumber:3;
-+ unsigned char LogicalBlockAddress[4];
-+ unsigned char Reserved3;
-+ unsigned char VerificationLength[2];
-+ unsigned char Reserved4;
-+ unsigned char Reserved5;
-+ unsigned char Reserved6;
-+} __attribute__((packed)) SCSI_VERIFY_COMMAND;
-+
-+/******************************************************************************
-+** Global Function Prototype
-+******************************************************************************/
-+
-+/* storage-fd.c */
-+void storage_urb_send(struct usb_device_instance*, void*, int);
-+
-+/* storageproto.c */
-+void storageproto_urb_analysis(struct urb*);
-+int storageproto_device_open_check(void);
-+void storageproto_device_close(void);
-+void storageproto_usb_status_check(int);
-+void storageproto_media_status_check(int);
-+void storageproto_usb_reset_ind(void);
-+ssize_t storageproto_proc_read(struct file*, char*, size_t, loff_t* pos);
-+void storageproto_init(void);
-+void storageproto_exit(void);
-+
-+#endif /* _STORAGEPROTO_H_ */
-+
diff --git a/linux/openzaurus-pxa_2.4.18-rmk7-pxa3-embedix20031107.bb b/linux/openzaurus-pxa_2.4.18-rmk7-pxa3-embedix20031107.bb
deleted file mode 100644
index f3054b9752..0000000000
--- a/linux/openzaurus-pxa_2.4.18-rmk7-pxa3-embedix20031107.bb
+++ /dev/null
@@ -1,104 +0,0 @@
-SECTION = "kernel"
-PV = "2.4.18-rmk7-pxa3-embedix"
-LICENSE = "GPL"
-KV = "2.4.18"
-RMKV = "7"
-PXAV = "3"
-SHARPV = "20031107"
-PR = "r26"
-DESCRIPTION = "Linux kernel for OpenZaurus PXA processor based devices."
-MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>"
-FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/openzaurus-pxa-${KV}-rmk${RMKV}-pxa${PXAV}-embedix${SHARPV}"
-
-ALLOW_EMPTY_kernel = "1"
-
-SRC_URI = "ftp://ftp.kernel.org/pub/linux/kernel/v2.4/linux-${KV}.tar.bz2 \
- ftp://ftp.arm.linux.org.uk/pub/armlinux/source/kernel-patches/v2.4/patch-${KV}-rmk${RMKV}.gz;patch=1 \
- ftp://source.mvista.com/pub/xscale/pxa/diff-${KV}-rmk${RMKV}-pxa${PXAV}.gz;patch=1 \
- http://developer.ezaurus.com/sl_j/source/c860/${SHARPV}/linux-${PV}-slc860-${SHARPV}-rom1_10.bz2;patch=1 \
- file://piro.patch;patch=1 \
- file://swap-performance.patch;patch=1 \
- file://bluetooth-2.4.18-mh15.patch;patch=1 \
- file://iw_handlers.w13-5.diff;patch=1 \
- file://iw_handlers.w14-5.diff;patch=1 \
- file://iw240_we15-6.diff;patch=1 \
- file://bt950_cs.patch;patch=1 \
- file://bluecard_cs.patch;patch=1 \
- file://sharpsl_battery.patch;patch=1 \
- file://irda-qos.patch;patch=1 \
- file://buffered-fbmem.patch;patch=1 \
- file://enable-sysrq.patch;patch=1 \
- file://compile.patch;patch=1 \
- file://idecs.patch;patch=1 \
- file://logo.patch;patch=1 \
- file://initsh.patch;patch=1 \
- file://keyboard-ctrl+alt.patch;patch=1 \
- file://keymap-more-sane.patch;patch=1 \
- file://mkdep.patch;patch=1 \
- file://disable-pcmcia-probe.patch;patch=1 \
- file://deviceinfo.patch;patch=1 \
- file://linux-2.4.18-list_move.patch;patch=1 \
- file://tosa_map.patch;patch=1 \
- file://tosa_ts.patch;patch=1 \
- file://corgi-fbcon-logo.patch;patch=1 \
- http://www.openswan.org/download/openswan-2.2.0-kernel-2.4-klips.patch.gz;patch=1 \
- file://1764-1.patch;patch=1 \
- file://module_licence.patch;patch=1 \
- http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/iw249_we16-6.diff;patch=1 \
- file://defconfig-${MACHINE} \
- http://us1.samba.org/samba/ftp/cifs-cvs/cifs-1.20c-2.4.tar.gz "
-
-def get_sysreq_setting(bb, d):
- if bb.data.getVar('ENABLE_SYSREQ', d, 1) in [ 'yes' ]:
- return "file://enable-sysrq.patch;patch=1 "
- return ""
-
-SRC_URI_append_poodle += " file://smallfonts.diff;patch=1"
-# apply this when we have a kernel that builds with gcc 3.x:
-# SRC_URI_append = file://machtune-args.patch;patch=1
-SRC_URI_append_tosa = " file://tosa-power-key-off.patch;patch=1"
-
-S = "${WORKDIR}/linux"
-
-inherit kernel
-
-#
-# Create the kernel command line. CMDLINE_CONSOLE is set through kernel.oeclass.
-#
-CMDLINE_MTDPARTS_poodle = "mtdparts=sharpsl-nand:7168k@0k(smf),22528k@7168k(root),-(home)"
-CMDLINE_MTDPARTS_corgi = "mtdparts=sharpsl-nand:7168k@0k(smf),25600k@7168k(root),-(home)"
-CMDLINE_MTDPARTS_shepherd = "mtdparts=sharpsl-nand:7168k@0k(smf),25600k@7168k(root),-(home)"
-CMDLINE_MTDPARTS_husky = "mtdparts=sharpsl-nand:7168k@0k(smf),54272k@7168k(root),-(home)"
-CMDLINE_MTDPARTS_tosa = "mtdparts=sharpsl-nand:7168k@0k(smf),28672k@7168k(root),-(home) EQUIPMENT=2"
-
-CMDLINE_ROOT = "root=/dev/mtdblock2 rootfstype=jffs2 jffs2_orphaned_inodes=delete"
-CMDLINE = "${CMDLINE_MTDPARTS} ${CMDLINE_ROOT} ${CMDLINE_CONSOLE}"
-
-#
-# Compensate for sucky bootloader on all Sharp Zaurus models
-#
-FILES_kernel = ""
-
-EXTRA_OEMAKE = " EXTRAVERSION=-rmk7-pxa3-embedix-${DISTRO_VERSION}"
-KERNEL_CCSUFFIX = "-2.95"
-KERNEL_LDSUFFIX = "-2.11.2"
-COMPATIBLE_HOST = "arm.*-linux"
-
-module_conf_usbdmonitor = "alias usbd0 usbdmonitor"
-module_conf_pxa_bi = "below pxa_bi net_fd usbdcore "
-module_autoload_pxa_bi = "pxa_bi"
-
-do_configure_prepend() {
- patch -p1 < cifs_24.patch
- install -m 0644 ${WORKDIR}/defconfig-${MACHINE} ${S}/.config || die "No default configuration for ${MACHINE} available."
- echo "CONFIG_CMDLINE=\"${CMDLINE}\"" >> ${S}/.config
-}
-
-do_deploy() {
- install -d ${DEPLOY_DIR}/images
- install -m 0644 arch/${ARCH}/boot/${KERNEL_IMAGETYPE} ${DEPLOY_DIR}/images/${KERNEL_IMAGETYPE}-${MACHINE}-${DATETIME}.bin
-}
-
-do_deploy[dirs] = "${S}"
-
-addtask deploy before do_build after do_compile
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/1764-1.patch b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/1764-1.patch
deleted file mode 100644
index 0b660f3521..0000000000
--- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/1764-1.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-__arch_strncpy_from_user needs to be exported if you build the framebuffer console driver as a module.
-
-Cheers,
-
-Ian.
-
---- linux-2.6-bkpxa.orig/arch/arm/kernel/armksyms.c 2004-02-27 10:35:29.000000000 +0000
-+++ linux-2.6-bkpxa/arch/arm/kernel/armksyms.c 2004-02-27 14:55:02.000000000 +0000
-@@ -187,6 +187,7 @@
- EXPORT_SYMBOL(__arch_copy_to_user);
- EXPORT_SYMBOL(__arch_clear_user);
- EXPORT_SYMBOL(__arch_strnlen_user);
-+EXPORT_SYMBOL(__arch_strncpy_from_user);
-
- /* consistent area handling */
- EXPORT_SYMBOL(consistent_alloc);
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/battery.patch b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/battery.patch
deleted file mode 100644
index 1912b33328..0000000000
--- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/battery.patch
+++ /dev/null
@@ -1,326 +0,0 @@
-
---- linux/arch/arm/mach-sa1100/collie_battery.c Tue Jul 22 02:24:32 2003
-+++ linux/arch/arm/mach-sa1100/collie_battery.c Tue Jul 22 03:07:56 2003
-@@ -14,10 +14,11 @@
- * 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.
- *
- * ChangeLog:
-+ * Nov 2002 Dietz Proepper: improved battery status.
- * 12-Nov-2001 Lineo Japan, Inc.
- * 30-Jul-2002 Lineo Japan, Inc. for 2.4.18
- * 29-Jan-2003 Sharp Corporation modify for new QT I/F
- *
- */
-@@ -79,10 +80,11 @@ int collie_read_BackBattery(void);
- int collie_read_Temp(void);
- int collie_check_temp(void);
- int collie_check_voltage(void);
- static void collie_charge_on(void);
- static void collie_charge_off(void);
-+static void do_main_battery(void);
- int set_led_status(int which,int status);
- int GetMainLevel( int Volt );
- int GetBackLevel( int Volt );
- int collie_get_main_battery(void);
- unsigned short GetBackupBatteryAD(void);
-@@ -91,40 +93,35 @@ int suspend_collie_read_Temp(void);
- /*** extern ***********************************************************************/
- extern u32 apm_wakeup_src_mask;
- extern int counter_step_contrast;
-
-
--/*** gloabal variables ************************************************************/
--int charge_status = 0; /* charge status 1 : charge 0: not charge */
--
--typedef struct BatteryThresh {
-- int high;
-- int low;
-- int verylow;
--} BATTERY_THRESH;
-+/* defines */
-+#define COLLIE_BATTERY_STATUS_HIGH APM_BATTERY_STATUS_HIGH
-+#define COLLIE_BATTERY_STATUS_LOW APM_BATTERY_STATUS_LOW
-+#define COLLIE_BATTERY_STATUS_VERYLOW APM_BATTERY_STATUS_VERY_LOW
-+#define COLLIE_BATTERY_STATUS_CRITICAL APM_BATTERY_STATUS_CRITICAL
-
-+/*** gloabal variables ************************************************************/
-+int charge_status = 0; /* charge status 1 : charge 0: not charge */
-
--#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0) || \
-- defined(CONFIG_COLLIE_TR1) || defined(CONFIG_COLLIE_DEV)
--BATTERY_THRESH collie_main_battery_thresh_fl = {
-- 368, 358, 356
--};
--
--BATTERY_THRESH collie_main_battery_thresh_nofl = {
-- 378, 364, 362
--};
--#else
--BATTERY_THRESH collie_main_battery_thresh_fl = {
-- 368, 358, 356
--};
--
--BATTERY_THRESH collie_main_battery_thresh_nofl = {
-- 378, 365, 363
-+typedef struct {
-+ int voltage_thres[2]; /* 0: nofl 1: fl */
-+ int percent;
-+ int state;
-+} main_battery_thres;
-+
-+#define MAIN_BATTERY_THRES 4
-+
-+main_battery_thres main_batt_thres[MAIN_BATTERY_THRES+2] = {
-+ {{5000, 5000}, 100, COLLIE_BATTERY_STATUS_HIGH }, /* do not remove! */
-+ {{412,408}, 100, COLLIE_BATTERY_STATUS_HIGH},
-+ {{378,368}, 40, COLLIE_BATTERY_STATUS_HIGH},
-+ {{364,358}, 5, COLLIE_BATTERY_STATUS_LOW},
-+ {{362,356}, 1, COLLIE_BATTERY_STATUS_CRITICAL},
-+ {{0, 0}, 1, COLLIE_BATTERY_STATUS_CRITICAL } /* do not remove, too! */
- };
--#endif
--
--
-
- typedef struct ChargeThresh {
- int bar1;
- int bar2;
- int bar3;
-@@ -180,24 +177,18 @@ static struct miscdevice battery_device
- #define GetBackADCtoPower(x) (( 330 * x * 2 ) / 1024 ) // MAX 3.3V
- #define ConvRevise(x) ( ( ad_revise * x ) / 652 )
- #define MAIN_DIFF 50 // 0.5V
- #define DIFF_CNT ( 3 - 1 )
-
--#define COLLIE_BATTERY_STATUS_HIGH APM_BATTERY_STATUS_HIGH
--#define COLLIE_BATTERY_STATUS_LOW APM_BATTERY_STATUS_LOW
--#define COLLIE_BATTERY_STATUS_VERYLOW APM_BATTERY_STATUS_VERY_LOW
--#define COLLIE_BATTERY_STATUS_CRITICAL APM_BATTERY_STATUS_CRITICAL
--
- #define COLLIE_AC_LINE_STATUS (!( GPLR & GPIO_AC_IN ) ? APM_AC_OFFLINE : APM_AC_ONLINE)
-
--
- #define COLLIE_PM_TICK ( 1000 / 10 ) // 1sec
- #define COLLIE_APO_TICKTIME ( 5 * COLLIE_PM_TICK ) // 5sec
- #define COLLIE_LPO_TICKTIME COLLIE_APO_TICKTIME
- #define COLLIE_APO_DEFAULT ( ( 3 * 60 ) * COLLIE_PM_TICK ) // 3 min
- #define COLLIE_LPO_DEFAULT ( 20 * COLLIE_PM_TICK ) // 20 sec
--#define COLLIE_MAIN_GOOD_COUNT ( 10*60 / ( COLLIE_APO_TICKTIME / COLLIE_PM_TICK ) )
-+#define COLLIE_MAIN_GOOD_COUNT ( 1*60 / ( COLLIE_APO_TICKTIME / COLLIE_PM_TICK ) )
- #define COLLIE_MAIN_NOGOOD_COUNT ( 1*60 / ( COLLIE_APO_TICKTIME / COLLIE_PM_TICK ) )
-
- #define COLLIE_BACKUP_BATTERY_CK_TIME ( 10*60*1*100 ) // 10min
- #define COLLIE_BACKUP_BATTERY_LOW ( 190 )
-
-@@ -212,10 +203,11 @@ unsigned int LPOCntWk = 0;
- static DECLARE_WAIT_QUEUE_HEAD(queue);
- static int msglevel;
-
- int collie_backup_battery = COLLIE_BATTERY_STATUS_HIGH;
- int collie_main_battery = COLLIE_BATTERY_STATUS_HIGH;
-+int collie_main_battery_percent = 100;
- int collie_main_charge_battery = 100;
- int collie_ac_status = APM_AC_OFFLINE;
- int ad_revise = 0;
-
- static int MainCntWk = COLLIE_MAIN_GOOD_COUNT;
-@@ -229,10 +221,11 @@ static struct pm_dev *battery_pm_dev; /
-
- static int battery_off_flag = 0; /* charge : suspend while get adc */
- static int collie_charge_temp = 973;
- static int collie_charge_volt = 465; /* charge : check charge 3.0V */
- static int charge_off_mode = 0; /* charge : check volt or non */
-+static int collie_main_battery_voltage = 400;
-
- static DECLARE_WAIT_QUEUE_HEAD(wq_on);
- static DECLARE_WAIT_QUEUE_HEAD(wq_off);
- #if 1 // 2003.1.29
- static DECLARE_WAIT_QUEUE_HEAD(battery_waitqueue);
-@@ -276,28 +269,11 @@ int collie_apm_get_power_status(u_char *
- }
- collie_battery_status = *battery_status;
- #endif
-
- // main battery status to percentage
-- switch (*battery_status)
-- {
-- case COLLIE_BATTERY_STATUS_HIGH:
-- *battery_percentage = 100;
-- break;
-- case COLLIE_BATTERY_STATUS_LOW:
-- *battery_percentage = 40;
-- break;
-- case COLLIE_BATTERY_STATUS_VERYLOW:
-- *battery_percentage = 5;
-- break;
-- case COLLIE_BATTERY_STATUS_CRITICAL:
-- *battery_percentage = 1;
-- break;
-- default:
-- *battery_percentage = 100;
-- break;
-- }
-+ *battery_percentage = collie_main_battery_percent;
-
- if ( *ac_line_status == APM_AC_ONLINE )
- *battery_percentage = 100;
-
- // good or ac in --> GOOD_COUNT
-@@ -529,12 +505,13 @@ int collie_get_main_battery(void)
- voltage = collie_read_MainBattery();
- if ( voltage > 0 ) break;
- if ( i++ > 5 ) { voltage = 380; break; }
- }
-
-- collie_main_battery = GetMainLevel(GetMainADCtoPower(voltage));
-- collie_main_charge_battery = GetMainChargePercent(GetMainADCtoPower(voltage));
-+ collie_main_battery_voltage = GetMainADCtoPower(voltage);
-+ do_main_battery();
-+ collie_main_charge_battery = GetMainChargePercent(collie_main_battery_voltage);
-
- DPRINTK2("charge percent = %d ( at %d ) \n",collie_main_charge_battery,jiffies);
-
- DPRINTK(" get Main battery status %d\n",collie_main_battery);
-
-@@ -562,36 +539,36 @@ int GetMainChargePercent( int Volt )
- } else {
- return 5;
- }
- }
-
--int GetMainLevel( int Volt )
-+static void do_main_battery()
- {
--
-- DPRINTK(" volt = %d \n",Volt);
--
--
-- if ( counter_step_contrast ) {
-- if ( Volt > collie_main_battery_thresh_fl.high )
-- return COLLIE_BATTERY_STATUS_HIGH;
-- else if ( Volt > collie_main_battery_thresh_fl.low )
-- return COLLIE_BATTERY_STATUS_LOW;
-- else if ( Volt > collie_main_battery_thresh_fl.verylow )
-- return COLLIE_BATTERY_STATUS_VERYLOW;
-- else
-- return COLLIE_BATTERY_STATUS_CRITICAL;
-- } else {
-- if ( Volt > collie_main_battery_thresh_nofl.high )
-- return COLLIE_BATTERY_STATUS_HIGH;
-- else if ( Volt > collie_main_battery_thresh_nofl.low )
-- return COLLIE_BATTERY_STATUS_LOW;
-- else if ( Volt > collie_main_battery_thresh_nofl.verylow )
-- return COLLIE_BATTERY_STATUS_VERYLOW;
-- else
-- return COLLIE_BATTERY_STATUS_CRITICAL;
-- }
--
-+ int i = MAIN_BATTERY_THRES;
-+ int fl = (counter_step_contrast)? 1 : 0;
-+
-+ while ( i > 0 &&
-+ ( collie_main_battery_voltage > main_batt_thres[i].voltage_thres[fl] ) )
-+ i--;
-+ /* i is now between 0 and MAIN_BATTERY_THRES. That means
-+ * we can safely access main_batt_thres[i] and
-+ * main_batt_thres[i+1] */
-+
-+ collie_main_battery = main_batt_thres[i].state;
-+ { /* perhaps we should put that deltas to our table, too? */
-+ long deltav = main_batt_thres[i].voltage_thres[fl] -
-+ main_batt_thres[i+1].voltage_thres[fl];
-+ long deltap = main_batt_thres[i].percent -
-+ main_batt_thres[i+1].percent;
-+
-+ collie_main_battery_percent = /* (1) */
-+ main_batt_thres[i+1].percent +
-+ deltap * (collie_main_battery_voltage -
-+ main_batt_thres[i+1].voltage_thres[fl]) /
-+ deltav;
-+ DPRINTK("Battery stuff: v=%i i=%i , dv=%li , dp=%li , p=%i",collie_main_battery_voltage , i, deltav, deltap, collie_main_battery_percent );
-+ }
- }
-
-
- int GetBackLevel( int Volt )
- {
-@@ -834,20 +811,18 @@ unsigned short chkFatalBatt(void)
- GEDR = GPIO_CO;
- // printk("CO = %x\n",GEDR&GPIO_CO);
- }
-
-
-- if ( volt < collie_main_battery_thresh_nofl.verylow )
-+ if ( volt < main_batt_thres[MAIN_BATTERY_THRES].voltage_thres[0] )
- return 0;
- else
- return 1;
- #endif
- }
-
-
--
--
- int suspend_collie_check_temp(void)
- {
- unsigned short temp , i = 0;
-
- while(1) {
-@@ -1032,10 +1007,11 @@ struct proc_dir_entry *proc_batt;
- typedef struct collie_battery_entry {
- int* addr;
- int def_value;
- char* name;
- char* description;
-+ char readonly;
- unsigned short low_ino;
- } collie_battery_entry_t;
-
- #if 1 // 2003.1.29
- static collie_battery_entry_t collie_battery_params[] = {
-@@ -1044,11 +1020,13 @@ static collie_battery_entry_t collie_bat
- { &collie_change_battery_status , 0 , "chg_status", "Change status" }
- };
- #else
- static collie_battery_entry_t collie_battery_params[] = {
- /* { addr, def_value, name, description }*/
-- { &msglevel, 0, "msglevel", "debug message output level" }
-+/* { &msglevel, 0, "msglevel", "debug message output level" } */
-+ { &msglevel, 0, "msglevel", "debug message output level", 0 },
-+ { &collie_main_battery_voltage, -1, "main_voltage", "main battery voltage", 1 }
- };
- #endif
- #define NUM_OF_BATTERY_ENTRY (sizeof(collie_battery_params)/sizeof(collie_battery_entry_t))
-
- static ssize_t collie_battery_read_params(struct file *file, char *buf,
-@@ -1069,11 +1047,12 @@ static ssize_t collie_battery_read_param
- }
- }
- if (current_param==NULL) {
- return -EINVAL;
- }
-- count = sprintf(outputbuf, "0x%08X\n",
-+// count = sprintf(outputbuf, "0x%08X\n",
-+ count = sprintf(outputbuf, "%04i\n",
- *((volatile Word *) current_param->addr));
- *ppos += count;
- if (count>nbytes) /* Assume output can be read at one time */
- return -EINVAL;
- if (copy_to_user(buf, outputbuf, count))
-@@ -1094,11 +1073,12 @@ static ssize_t collie_battery_write_para
- if(collie_battery_params[i].low_ino==i_ino) {
- current_param = &collie_battery_params[i];
- break;
- }
- }
-- if (current_param==NULL) {
-+// if (current_param==NULL) {
-+ if (current_param==NULL || current_param->readonly) {
- return -EINVAL;
- }
-
- param = simple_strtoul(buf,&endp,0);
- if (param == -1) {
-
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/bluetooth-2.4.18-mh15.patch b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/bluetooth-2.4.18-mh15.patch
deleted file mode 100644
index 1a7fd98653..0000000000
--- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/bluetooth-2.4.18-mh15.patch
+++ /dev/null
@@ -1,32759 +0,0 @@
-diff -urN linux-2.4.18/arch/alpha/config.in linux-2.4.18-mh15/arch/alpha/config.in
---- linux-2.4.18/arch/alpha/config.in 2001-11-21 00:49:31.000000000 +0100
-+++ linux-2.4.18-mh15/arch/alpha/config.in 2004-08-01 16:26:22.000000000 +0200
-@@ -371,9 +371,7 @@
- source drivers/usb/Config.in
- source drivers/input/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Kernel hacking'
-diff -urN linux-2.4.18/arch/arm/config.in linux-2.4.18-mh15/arch/arm/config.in
---- linux-2.4.18/arch/arm/config.in 2001-11-09 22:58:02.000000000 +0100
-+++ linux-2.4.18-mh15/arch/arm/config.in 2004-08-01 16:26:22.000000000 +0200
-@@ -584,9 +584,7 @@
-
- source drivers/usb/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Kernel hacking'
-diff -urN linux-2.4.18/arch/i386/config.in linux-2.4.18-mh15/arch/i386/config.in
---- linux-2.4.18/arch/i386/config.in 2002-02-25 20:37:52.000000000 +0100
-+++ linux-2.4.18-mh15/arch/i386/config.in 2004-08-01 16:26:22.000000000 +0200
-@@ -407,9 +407,7 @@
-
- source drivers/usb/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Kernel hacking'
-diff -urN linux-2.4.18/arch/ppc/config.in linux-2.4.18-mh15/arch/ppc/config.in
---- linux-2.4.18/arch/ppc/config.in 2002-02-25 20:37:55.000000000 +0100
-+++ linux-2.4.18-mh15/arch/ppc/config.in 2004-08-01 16:26:22.000000000 +0200
-@@ -389,9 +389,7 @@
-
- source drivers/usb/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Kernel hacking'
-diff -urN linux-2.4.18/arch/sparc/config.in linux-2.4.18-mh15/arch/sparc/config.in
---- linux-2.4.18/arch/sparc/config.in 2001-06-12 04:15:27.000000000 +0200
-+++ linux-2.4.18-mh15/arch/sparc/config.in 2004-08-01 16:26:22.000000000 +0200
-@@ -251,9 +251,7 @@
-
- source fs/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Watchdog'
-diff -urN linux-2.4.18/arch/sparc64/config.in linux-2.4.18-mh15/arch/sparc64/config.in
---- linux-2.4.18/arch/sparc64/config.in 2001-12-21 18:41:53.000000000 +0100
-+++ linux-2.4.18-mh15/arch/sparc64/config.in 2004-08-01 16:26:22.000000000 +0200
-@@ -283,9 +283,7 @@
-
- source drivers/usb/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Watchdog'
-diff -urN linux-2.4.18/arch/sparc64/kernel/ioctl32.c linux-2.4.18-mh15/arch/sparc64/kernel/ioctl32.c
---- linux-2.4.18/arch/sparc64/kernel/ioctl32.c 2002-02-25 20:37:56.000000000 +0100
-+++ linux-2.4.18-mh15/arch/sparc64/kernel/ioctl32.c 2004-08-01 16:26:23.000000000 +0200
-@@ -92,6 +92,7 @@
-
- #include <net/bluetooth/bluetooth.h>
- #include <net/bluetooth/hci.h>
-+#include <net/bluetooth/rfcomm.h>
-
- #include <linux/usb.h>
- #include <linux/usbdevice_fs.h>
-@@ -3822,6 +3823,15 @@
- return err;
- }
-
-+/* Bluetooth ioctls */
-+#define HCIUARTSETPROTO _IOW('U', 200, int)
-+#define HCIUARTGETPROTO _IOR('U', 201, int)
-+
-+#define BNEPCONNADD _IOW('B', 200, int)
-+#define BNEPCONNDEL _IOW('B', 201, int)
-+#define BNEPGETCONNLIST _IOR('B', 210, int)
-+#define BNEPGETCONNINFO _IOR('B', 211, int)
-+
- struct mtd_oob_buf32 {
- u32 start;
- u32 length;
-@@ -3878,6 +3888,16 @@
- return ((0 == ret) ? 0 : -EFAULT);
- }
-
-+#define CMTPCONNADD _IOW('C', 200, int)
-+#define CMTPCONNDEL _IOW('C', 201, int)
-+#define CMTPGETCONNLIST _IOR('C', 210, int)
-+#define CMTPGETCONNINFO _IOR('C', 211, int)
-+
-+#define HIDPCONNADD _IOW('H', 200, int)
-+#define HIDPCONNDEL _IOW('H', 201, int)
-+#define HIDPGETCONNLIST _IOR('H', 210, int)
-+#define HIDPGETCONNINFO _IOR('H', 211, int)
-+
- struct ioctl_trans {
- unsigned int cmd;
- unsigned int handler;
-@@ -4540,6 +4560,25 @@
- COMPATIBLE_IOCTL(HCISETSCAN)
- COMPATIBLE_IOCTL(HCISETAUTH)
- COMPATIBLE_IOCTL(HCIINQUIRY)
-+COMPATIBLE_IOCTL(HCIUARTSETPROTO)
-+COMPATIBLE_IOCTL(HCIUARTGETPROTO)
-+COMPATIBLE_IOCTL(RFCOMMCREATEDEV)
-+COMPATIBLE_IOCTL(RFCOMMRELEASEDEV)
-+COMPATIBLE_IOCTL(RFCOMMGETDEVLIST)
-+COMPATIBLE_IOCTL(RFCOMMGETDEVINFO)
-+COMPATIBLE_IOCTL(RFCOMMSTEALDLC)
-+COMPATIBLE_IOCTL(BNEPCONNADD)
-+COMPATIBLE_IOCTL(BNEPCONNDEL)
-+COMPATIBLE_IOCTL(BNEPGETCONNLIST)
-+COMPATIBLE_IOCTL(BNEPGETCONNINFO)
-+COMPATIBLE_IOCTL(CMTPCONNADD)
-+COMPATIBLE_IOCTL(CMTPCONNDEL)
-+COMPATIBLE_IOCTL(CMTPGETCONNLIST)
-+COMPATIBLE_IOCTL(CMTPGETCONNINFO)
-+COMPATIBLE_IOCTL(HIDPCONNADD)
-+COMPATIBLE_IOCTL(HIDPCONNDEL)
-+COMPATIBLE_IOCTL(HIDPGETCONNLIST)
-+COMPATIBLE_IOCTL(HIDPGETCONNINFO)
- /* Misc. */
- COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */
- COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */
-diff -urN linux-2.4.18/CREDITS linux-2.4.18-mh15/CREDITS
---- linux-2.4.18/CREDITS 2002-02-25 20:37:50.000000000 +0100
-+++ linux-2.4.18-mh15/CREDITS 2004-08-01 16:26:23.000000000 +0200
-@@ -1317,6 +1317,16 @@
- S: Provo, Utah 84606-5607
- S: USA
-
-+N: Marcel Holtmann
-+E: marcel@holtmann.org
-+W: http://www.holtmann.org
-+D: Maintainer of the Linux Bluetooth Subsystem
-+D: Author and maintainer of the various Bluetooth HCI drivers
-+D: Author and maintainer of the CAPI message transport protocol driver
-+D: Author and maintainer of the Bluetooth HID protocol driver
-+D: Various other Bluetooth related patches, cleanups and fixes
-+S: Germany
-+
- N: Rob W. W. Hooft
- E: hooft@EMBL-Heidelberg.DE
- D: Shared libs for graphics-tools and for the f2c compiler
-@@ -2546,6 +2556,7 @@
- N: Aristeu Sergio Rozanski Filho
- E: aris@conectiva.com.br
- D: Support for EtherExpress 10 ISA (i82595) in eepro driver
-+D: User level driver support for input
- S: Conectiva S.A.
- S: R. Tocantins, 89 - Cristo Rei
- S: 80050-430 - Curitiba - Paraná
-diff -urN linux-2.4.18/Documentation/Configure.help linux-2.4.18-mh15/Documentation/Configure.help
---- linux-2.4.18/Documentation/Configure.help 2002-02-25 20:37:51.000000000 +0100
-+++ linux-2.4.18-mh15/Documentation/Configure.help 2004-08-01 16:26:23.000000000 +0200
-@@ -2824,14 +2824,6 @@
-
- If unsure, say N.
-
--HCI EMU (virtual device) driver
--CONFIG_BLUEZ_HCIEMU
-- Bluetooth Virtual HCI device driver.
-- This driver is required if you want to use HCI Emulation software.
--
-- Say Y here to compile support for Virtual HCI devices into the
-- kernel or say M to compile it as module (hci_usb.o).
--
- # Choice: alphatype
- Alpha system type
- CONFIG_ALPHA_GENERIC
-@@ -11037,6 +11029,12 @@
-
- If unsure, say N.
-
-+Hotplug firmware loading support (EXPERIMENTAL)
-+CONFIG_FW_LOADER
-+ This option is provided for the case where no in-kernel-tree modules require
-+ hotplug firmware loading support, but a module built outside the kernel tree
-+ does.
-+
- Use PCI shared memory for NIC registers
- CONFIG_TULIP_MMIO
- Use PCI shared memory for the NIC registers, rather than going through
-@@ -12896,6 +12894,15 @@
- accessible under char device 13:64+ - /dev/input/eventX in a generic
- way. This is the future ...
-
-+CONFIG_INPUT_UINPUT
-+ Say Y here if you want to support user level drivers for input
-+ subsystem accessible under char device 10:223 - /dev/input/uinput.
-+
-+ This driver is also available as a module ( = code which can be
-+ inserted in and removed from the running kernel whenever you want).
-+ The module will be called uinput.o. If you want to compile it as a
-+ module, say M here and read <file:Documentation/modules.txt>.
-+
- USB Scanner support
- CONFIG_USB_SCANNER
- Say Y here if you want to connect a USB scanner to your computer's
-@@ -19870,19 +19877,22 @@
- Bluetooth can be found at <http://www.bluetooth.com/>.
-
- Linux Bluetooth subsystem consist of several layers:
-- HCI Core (device and connection manager, scheduler)
-- HCI Device drivers (interface to the hardware)
-- L2CAP Module (L2CAP protocol)
-+ BlueZ Core (HCI device and connection manager, scheduler)
-+ HCI Device drivers (Interface to the hardware)
-+ SCO Module (SCO audio links)
-+ L2CAP Module (Logical Link Control and Adaptation Protocol)
-+ RFCOMM Module (RFCOMM Protocol)
-+ BNEP Module (Bluetooth Network Encapsulation Protocol)
-+ CMTP Module (CAPI Message Transport Protocol)
-+ HIDP Module (Human Interface Device Protocol)
-
-- Say Y here to enable Linux Bluetooth support and to build HCI Core
-- layer.
-+ Say Y here to compile Bluetooth support into the kernel or say M to
-+ compile it as module (bluez.o).
-
- To use Linux Bluetooth subsystem, you will need several user-space
- utilities like hciconfig and hcid. These utilities and updates to
- Bluetooth kernel modules are provided in the BlueZ package.
-- For more information, see <http://bluez.sourceforge.net/>.
--
-- If you want to compile HCI Core as module (hci.o) say M here.
-+ For more information, see <http://www.bluez.org/>.
-
- L2CAP protocol support
- CONFIG_BLUEZ_L2CAP
-@@ -19893,15 +19903,96 @@
- Say Y here to compile L2CAP support into the kernel or say M to
- compile it as module (l2cap.o).
-
-+SCO links support
-+CONFIG_BLUEZ_SCO
-+ SCO link provides voice transport over Bluetooth. SCO support is
-+ required for voice applications like Headset and Audio.
-+
-+ Say Y here to compile SCO support into the kernel or say M to
-+ compile it as module (sco.o).
-+
-+RFCOMM protocol support
-+CONFIG_BLUEZ_RFCOMM
-+ RFCOMM provides connection oriented stream transport. RFCOMM
-+ support is required for Dialup Networking, OBEX and other Bluetooth
-+ applications.
-+
-+ Say Y here to compile RFCOMM support into the kernel or say M to
-+ compile it as module (rfcomm.o).
-+
-+RFCOMM TTY emulation support
-+CONFIG_BLUEZ_RFCOMM_TTY
-+ This option enables TTY emulation support for RFCOMM channels.
-+
-+BNEP protocol support
-+CONFIG_BLUEZ_BNEP
-+ BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet
-+ emulation layer on top of Bluetooth. BNEP is required for
-+ Bluetooth PAN (Personal Area Network).
-+
-+ Say Y here to compile BNEP support into the kernel or say M to
-+ compile it as module (bnep.o).
-+
-+BNEP multicast filter support
-+CONFIG_BLUEZ_BNEP_MC_FILTER
-+ This option enables the multicast filter support for BNEP.
-+
-+BNEP protocol filter support
-+CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+ This option enables the protocol filter support for BNEP.
-+
-+CMTP protocol support
-+CONFIG_BLUEZ_CMTP
-+ CMTP (CAPI Message Transport Protocol) is a transport layer
-+ for CAPI messages. CMTP is required for the Bluetooth Common
-+ ISDN Access Profile.
-+
-+ Say Y here to compile CMTP support into the kernel or say M to
-+ compile it as module (cmtp.o).
-+
-+HIDP protocol support
-+CONFIG_BLUEZ_HIDP
-+ HIDP (Human Interface Device Protocol) is a transport layer
-+ for HID reports. HIDP is required for the Bluetooth Human
-+ Interface Device Profile.
-+
-+ Say Y here to compile HIDP support into the kernel or say M to
-+ compile it as module (hidp.o).
-+
- HCI UART driver
- CONFIG_BLUEZ_HCIUART
- Bluetooth HCI UART driver.
- This driver is required if you want to use Bluetooth devices with
-- serial port interface.
-+ serial port interface. You will also need this driver if you have
-+ UART based Bluetooth PCMCIA and CF devices like Xircom Credit Card
-+ adapter and BrainBoxes Bluetooth PC Card.
-
- Say Y here to compile support for Bluetooth UART devices into the
- kernel or say M to compile it as module (hci_uart.o).
-
-+HCI UART (H4) protocol support
-+CONFIG_BLUEZ_HCIUART_H4
-+ UART (H4) is serial protocol for communication between Bluetooth
-+ device and host. This protocol is required for most Bluetooth devices
-+ with UART interface, including PCMCIA and CF cards.
-+
-+ Say Y here to compile support for HCI UART (H4) protocol.
-+
-+HCI BCSP protocol support
-+CONFIG_BLUEZ_HCIUART_BCSP
-+ BCSP (BlueCore Serial Protocol) is serial protocol for communication
-+ between Bluetooth device and host. This protocol is required for non
-+ USB Bluetooth devices based on CSR BlueCore chip, including PCMCIA and
-+ CF cards.
-+
-+ Say Y here to compile support for HCI BCSP protocol.
-+
-+HCI BCSP transmit CRC with every BCSP packet
-+CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ If you say Y here, a 16-bit CRC checksum will be transmitted along with
-+ every BCSP (BlueCore Serial Protocol) packet sent to the Bluetooth chip.
-+ This increases reliability, but slightly reduces efficiency.
-+
- HCI USB driver
- CONFIG_BLUEZ_HCIUSB
- Bluetooth HCI USB driver.
-@@ -19911,7 +20002,16 @@
- Say Y here to compile support for Bluetooth USB devices into the
- kernel or say M to compile it as module (hci_usb.o).
-
--HCI VHCI virtual HCI device driver
-+HCI USB SCO (voice) support
-+CONFIG_BLUEZ_HCIUSB_SCO
-+ This option enables the SCO support in the HCI USB driver. You need this
-+ to transmit voice data with your Bluetooth USB device. And your device
-+ must also support sending SCO data over the HCI layer, because some of
-+ them sends the SCO data to an internal PCM adapter.
-+
-+ Say Y here to compile support for HCI SCO data.
-+
-+HCI VHCI Virtual HCI device driver
- CONFIG_BLUEZ_HCIVHCI
- Bluetooth Virtual HCI device driver.
- This driver is required if you want to use HCI Emulation software.
-@@ -19919,6 +20019,63 @@
- Say Y here to compile support for virtual HCI devices into the
- kernel or say M to compile it as module (hci_vhci.o).
-
-+HCI BFUSB device driver
-+CONFIG_BLUEZ_HCIBFUSB
-+ Bluetooth HCI BlueFRITZ! USB driver.
-+ This driver provides support for Bluetooth USB devices with AVM
-+ interface:
-+ AVM BlueFRITZ! USB
-+
-+ Say Y here to compile support for HCI BFUSB devices into the
-+ kernel or say M to compile it as module (bfusb.o).
-+
-+HCI DTL1 (PC Card) device driver
-+CONFIG_BLUEZ_HCIDTL1
-+ Bluetooth HCI DTL1 (PC Card) driver.
-+ This driver provides support for Bluetooth PCMCIA devices with
-+ Nokia DTL1 interface:
-+ Nokia Bluetooth Card
-+ Socket Bluetooth CF Card
-+
-+ Say Y here to compile support for HCI DTL1 devices into the
-+ kernel or say M to compile it as module (dtl1_cs.o).
-+
-+HCI BT3C (PC Card) device driver
-+CONFIG_BLUEZ_HCIBT3C
-+ Bluetooth HCI BT3C (PC Card) driver.
-+ This driver provides support for Bluetooth PCMCIA devices with
-+ 3Com BT3C interface:
-+ 3Com Bluetooth Card (3CRWB6096)
-+ HP Bluetooth Card
-+
-+ Say Y here to compile support for HCI BT3C devices into the
-+ kernel or say M to compile it as module (bt3c_cs.o).
-+
-+HCI BlueCard (PC Card) device driver
-+CONFIG_BLUEZ_HCIBLUECARD
-+ Bluetooth HCI BlueCard (PC Card) driver.
-+ This driver provides support for Bluetooth PCMCIA devices with
-+ Anycom BlueCard interface:
-+ Anycom Bluetooth PC Card
-+ Anycom Bluetooth CF Card
-+
-+ Say Y here to compile support for HCI BlueCard devices into the
-+ kernel or say M to compile it as module (bluecard_cs.o).
-+
-+HCI UART (PC Card) device driver
-+CONFIG_BLUEZ_HCIBTUART
-+ Bluetooth HCI UART (PC Card) driver.
-+ This driver provides support for Bluetooth PCMCIA devices with
-+ an UART interface:
-+ Xircom CreditCard Bluetooth Adapter
-+ Xircom RealPort2 Bluetooth Adapter
-+ Sphinx PICO Card
-+ H-Soft blue+Card
-+ Cyber-blue Compact Flash Card
-+
-+ Say Y here to compile support for HCI UART devices into the
-+ kernel or say M to compile it as module (btuart_cs.o).
-+
- # The following options are for Linux when running on the Hitachi
- # SuperH family of RISC microprocessors.
-
-diff -urN linux-2.4.18/Documentation/devices.txt linux-2.4.18-mh15/Documentation/devices.txt
---- linux-2.4.18/Documentation/devices.txt 2001-11-07 23:46:01.000000000 +0100
-+++ linux-2.4.18-mh15/Documentation/devices.txt 2004-08-01 16:26:23.000000000 +0200
-@@ -419,6 +419,7 @@
- 220 = /dev/mptctl Message passing technology (MPT) control
- 221 = /dev/mvista/hssdsi Montavista PICMG hot swap system driver
- 222 = /dev/mvista/hasi Montavista PICMG high availability
-+ 223 = /dev/input/uinput User level driver support for input
- 240-255 Reserved for local use
-
- 11 char Raw keyboard device
-diff -urN linux-2.4.18/Documentation/firmware_class/firmware_sample_driver.c linux-2.4.18-mh15/Documentation/firmware_class/firmware_sample_driver.c
---- linux-2.4.18/Documentation/firmware_class/firmware_sample_driver.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/Documentation/firmware_class/firmware_sample_driver.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,121 @@
-+/*
-+ * firmware_sample_driver.c -
-+ *
-+ * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
-+ *
-+ * Sample code on how to use request_firmware() from drivers.
-+ *
-+ * Note that register_firmware() is currently useless.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/string.h>
-+
-+#include "linux/firmware.h"
-+
-+#define WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
-+#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
-+char __init inkernel_firmware[] = "let's say that this is firmware\n";
-+#endif
-+
-+static char ghost_device[] = "ghost0";
-+
-+static void sample_firmware_load(char *firmware, int size)
-+{
-+ u8 buf[size+1];
-+ memcpy(buf, firmware, size);
-+ buf[size] = '\0';
-+ printk("firmware_sample_driver: firmware: %s\n", buf);
-+}
-+
-+static void sample_probe_default(void)
-+{
-+ /* uses the default method to get the firmware */
-+ const struct firmware *fw_entry;
-+ printk("firmware_sample_driver: a ghost device got inserted :)\n");
-+
-+ if(request_firmware(&fw_entry, "sample_driver_fw", ghost_device)!=0)
-+ {
-+ printk(KERN_ERR
-+ "firmware_sample_driver: Firmware not available\n");
-+ return;
-+ }
-+
-+ sample_firmware_load(fw_entry->data, fw_entry->size);
-+
-+ release_firmware(fw_entry);
-+
-+ /* finish setting up the device */
-+}
-+static void sample_probe_specific(void)
-+{
-+ /* Uses some specific hotplug support to get the firmware from
-+ * userspace directly into the hardware, or via some sysfs file */
-+
-+ /* NOTE: This currently doesn't work */
-+
-+ printk("firmware_sample_driver: a ghost device got inserted :)\n");
-+
-+ if(request_firmware(NULL, "sample_driver_fw", ghost_device)!=0)
-+ {
-+ printk(KERN_ERR
-+ "firmware_sample_driver: Firmware load failed\n");
-+ return;
-+ }
-+
-+ /* request_firmware blocks until userspace finished, so at
-+ * this point the firmware should be already in the device */
-+
-+ /* finish setting up the device */
-+}
-+static void sample_probe_async_cont(const struct firmware *fw, void *context)
-+{
-+ if(!fw){
-+ printk(KERN_ERR
-+ "firmware_sample_driver: firmware load failed\n");
-+ return;
-+ }
-+
-+ printk("firmware_sample_driver: device pointer \"%s\"\n",
-+ (char *)context);
-+ sample_firmware_load(fw->data, fw->size);
-+}
-+static void sample_probe_async(void)
-+{
-+ /* Let's say that I can't sleep */
-+ int error;
-+ error = request_firmware_nowait (THIS_MODULE,
-+ "sample_driver_fw", ghost_device,
-+ "my device pointer",
-+ sample_probe_async_cont);
-+ if(error){
-+ printk(KERN_ERR
-+ "firmware_sample_driver:"
-+ " request_firmware_nowait failed\n");
-+ }
-+}
-+
-+static int sample_init(void)
-+{
-+#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
-+ register_firmware("sample_driver_fw", inkernel_firmware,
-+ sizeof(inkernel_firmware));
-+#endif
-+ /* since there is no real hardware insertion I just call the
-+ * sample probe functions here */
-+ sample_probe_specific();
-+ sample_probe_default();
-+ sample_probe_async();
-+ return 0;
-+}
-+static void __exit sample_exit(void)
-+{
-+}
-+
-+module_init (sample_init);
-+module_exit (sample_exit);
-+
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/Documentation/firmware_class/hotplug-script linux-2.4.18-mh15/Documentation/firmware_class/hotplug-script
---- linux-2.4.18/Documentation/firmware_class/hotplug-script 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/Documentation/firmware_class/hotplug-script 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,16 @@
-+#!/bin/sh
-+
-+# Simple hotplug script sample:
-+#
-+# Both $DEVPATH and $FIRMWARE are already provided in the environment.
-+
-+HOTPLUG_FW_DIR=/usr/lib/hotplug/firmware/
-+
-+echo 1 > /sysfs/$DEVPATH/loading
-+cat $HOTPLUG_FW_DIR/$FIRMWARE > /sysfs/$DEVPATH/data
-+echo 0 > /sysfs/$DEVPATH/loading
-+
-+# To cancel the load in case of error:
-+#
-+# echo -1 > /sysfs/$DEVPATH/loading
-+#
-diff -urN linux-2.4.18/Documentation/firmware_class/README linux-2.4.18-mh15/Documentation/firmware_class/README
---- linux-2.4.18/Documentation/firmware_class/README 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/Documentation/firmware_class/README 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,58 @@
-+
-+ request_firmware() hotplug interface:
-+ ------------------------------------
-+ Copyright (C) 2003 Manuel Estrada Sainz <ranty@debian.org>
-+
-+ Why:
-+ ---
-+
-+ Today, the most extended way to use firmware in the Linux kernel is linking
-+ it statically in a header file. Which has political and technical issues:
-+
-+ 1) Some firmware is not legal to redistribute.
-+ 2) The firmware occupies memory permanently, even though it often is just
-+ used once.
-+ 3) Some people, like the Debian crowd, don't consider some firmware free
-+ enough and remove entire drivers (e.g.: keyspan).
-+
-+ about in-kernel persistence:
-+ ---------------------------
-+ Under some circumstances, as explained below, it would be interesting to keep
-+ firmware images in non-swappable kernel memory or even in the kernel image
-+ (probably within initramfs).
-+
-+ Note that this functionality has not been implemented.
-+
-+ - Why OPTIONAL in-kernel persistence may be a good idea sometimes:
-+
-+ - If the device that needs the firmware is needed to access the
-+ filesystem. When upon some error the device has to be reset and the
-+ firmware reloaded, it won't be possible to get it from userspace.
-+ e.g.:
-+ - A diskless client with a network card that needs firmware.
-+ - The filesystem is stored in a disk behind an scsi device
-+ that needs firmware.
-+ - Replacing buggy DSDT/SSDT ACPI tables on boot.
-+ Note: this would require the persistent objects to be included
-+ within the kernel image, probably within initramfs.
-+
-+ And the same device can be needed to access the filesystem or not depending
-+ on the setup, so I think that the choice on what firmware to make
-+ persistent should be left to userspace.
-+
-+ - Why register_firmware()+__init can be useful:
-+ - For boot devices needing firmware.
-+ - To make the transition easier:
-+ The firmware can be declared __init and register_firmware()
-+ called on module_init. Then the firmware is warranted to be
-+ there even if "firmware hotplug userspace" is not there yet or
-+ it doesn't yet provide the needed firmware.
-+ Once the firmware is widely available in userspace, it can be
-+ removed from the kernel. Or made optional (CONFIG_.*_FIRMWARE).
-+
-+ In either case, if firmware hotplug support is there, it can move the
-+ firmware out of kernel memory into the real filesystem for later
-+ usage.
-+
-+ Note: If persistence is implemented on top of initramfs,
-+ register_firmware() may not be appropriate.
-diff -urN linux-2.4.18/drivers/bluetooth/bfusb.c linux-2.4.18-mh15/drivers/bluetooth/bfusb.c
---- linux-2.4.18/drivers/bluetooth/bfusb.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/bfusb.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,782 @@
-+/*
-+ *
-+ * AVM BlueFRITZ! USB driver
-+ *
-+ * Copyright (C) 2003 Marcel Holtmann <marcel@holtmann.org>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/skbuff.h>
-+
-+#include <linux/firmware.h>
-+#include <linux/usb.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+#ifndef CONFIG_BLUEZ_HCIBFUSB_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define VERSION "1.1"
-+
-+static struct usb_device_id bfusb_table[] = {
-+ /* AVM BlueFRITZ! USB */
-+ { USB_DEVICE(0x057c, 0x2200) },
-+
-+ { } /* Terminating entry */
-+};
-+
-+MODULE_DEVICE_TABLE(usb, bfusb_table);
-+
-+
-+#define BFUSB_MAX_BLOCK_SIZE 256
-+
-+#define BFUSB_BLOCK_TIMEOUT (HZ * 3)
-+
-+#define BFUSB_TX_PROCESS 1
-+#define BFUSB_TX_WAKEUP 2
-+
-+#define BFUSB_MAX_BULK_TX 1
-+#define BFUSB_MAX_BULK_RX 1
-+
-+struct bfusb {
-+ struct hci_dev hdev;
-+
-+ unsigned long state;
-+
-+ struct usb_device *udev;
-+
-+ unsigned int bulk_in_ep;
-+ unsigned int bulk_out_ep;
-+ unsigned int bulk_pkt_size;
-+
-+ rwlock_t lock;
-+
-+ struct sk_buff_head transmit_q;
-+
-+ struct sk_buff *reassembly;
-+
-+ atomic_t pending_tx;
-+ struct sk_buff_head pending_q;
-+ struct sk_buff_head completed_q;
-+};
-+
-+struct bfusb_scb {
-+ struct urb *urb;
-+};
-+
-+static void bfusb_tx_complete(struct urb *urb);
-+static void bfusb_rx_complete(struct urb *urb);
-+
-+static struct urb *bfusb_get_completed(struct bfusb *bfusb)
-+{
-+ struct sk_buff *skb;
-+ struct urb *urb = NULL;
-+
-+ BT_DBG("bfusb %p", bfusb);
-+
-+ skb = skb_dequeue(&bfusb->completed_q);
-+ if (skb) {
-+ urb = ((struct bfusb_scb *) skb->cb)->urb;
-+ kfree_skb(skb);
-+ }
-+
-+ return urb;
-+}
-+
-+static inline void bfusb_unlink_urbs(struct bfusb *bfusb)
-+{
-+ struct sk_buff *skb;
-+ struct urb *urb;
-+
-+ BT_DBG("bfusb %p", bfusb);
-+
-+ while ((skb = skb_dequeue(&bfusb->pending_q))) {
-+ urb = ((struct bfusb_scb *) skb->cb)->urb;
-+ usb_unlink_urb(urb);
-+ skb_queue_tail(&bfusb->completed_q, skb);
-+ }
-+
-+ while ((urb = bfusb_get_completed(bfusb)))
-+ usb_free_urb(urb);
-+}
-+
-+
-+static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb)
-+{
-+ struct bfusb_scb *scb = (void *) skb->cb;
-+ struct urb *urb = bfusb_get_completed(bfusb);
-+ int err, pipe;
-+
-+ BT_DBG("bfusb %p skb %p len %d", bfusb, skb, skb->len);
-+
-+ if (!urb && !(urb = usb_alloc_urb(0)))
-+ return -ENOMEM;
-+
-+ pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
-+
-+ FILL_BULK_URB(urb, bfusb->udev, pipe, skb->data, skb->len,
-+ bfusb_tx_complete, skb);
-+
-+ urb->transfer_flags = USB_QUEUE_BULK;
-+
-+ scb->urb = urb;
-+
-+ skb_queue_tail(&bfusb->pending_q, skb);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s bulk tx submit failed urb %p err %d",
-+ bfusb->hdev.name, urb, err);
-+ skb_unlink(skb);
-+ usb_free_urb(urb);
-+ } else
-+ atomic_inc(&bfusb->pending_tx);
-+
-+ return err;
-+}
-+
-+static void bfusb_tx_wakeup(struct bfusb *bfusb)
-+{
-+ struct sk_buff *skb;
-+
-+ BT_DBG("bfusb %p", bfusb);
-+
-+ if (test_and_set_bit(BFUSB_TX_PROCESS, &bfusb->state)) {
-+ set_bit(BFUSB_TX_WAKEUP, &bfusb->state);
-+ return;
-+ }
-+
-+ do {
-+ clear_bit(BFUSB_TX_WAKEUP, &bfusb->state);
-+
-+ while ((atomic_read(&bfusb->pending_tx) < BFUSB_MAX_BULK_TX) &&
-+ (skb = skb_dequeue(&bfusb->transmit_q))) {
-+ if (bfusb_send_bulk(bfusb, skb) < 0) {
-+ skb_queue_head(&bfusb->transmit_q, skb);
-+ break;
-+ }
-+ }
-+
-+ } while (test_bit(BFUSB_TX_WAKEUP, &bfusb->state));
-+
-+ clear_bit(BFUSB_TX_PROCESS, &bfusb->state);
-+}
-+
-+static void bfusb_tx_complete(struct urb *urb)
-+{
-+ struct sk_buff *skb = (struct sk_buff *) urb->context;
-+ struct bfusb *bfusb = (struct bfusb *) skb->dev;
-+
-+ BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
-+
-+ atomic_dec(&bfusb->pending_tx);
-+
-+ if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags))
-+ return;
-+
-+ if (!urb->status)
-+ bfusb->hdev.stat.byte_tx += skb->len;
-+ else
-+ bfusb->hdev.stat.err_tx++;
-+
-+ read_lock(&bfusb->lock);
-+
-+ skb_unlink(skb);
-+ skb_queue_tail(&bfusb->completed_q, skb);
-+
-+ bfusb_tx_wakeup(bfusb);
-+
-+ read_unlock(&bfusb->lock);
-+}
-+
-+
-+static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb)
-+{
-+ struct bfusb_scb *scb;
-+ struct sk_buff *skb;
-+ int err, pipe, size = HCI_MAX_FRAME_SIZE + 32;
-+
-+ BT_DBG("bfusb %p urb %p", bfusb, urb);
-+
-+ if (!urb && !(urb = usb_alloc_urb(0)))
-+ return -ENOMEM;
-+
-+ if (!(skb = bluez_skb_alloc(size, GFP_ATOMIC))) {
-+ usb_free_urb(urb);
-+ return -ENOMEM;
-+ }
-+
-+ skb->dev = (void *) bfusb;
-+
-+ scb = (struct bfusb_scb *) skb->cb;
-+ scb->urb = urb;
-+
-+ pipe = usb_rcvbulkpipe(bfusb->udev, bfusb->bulk_in_ep);
-+
-+ FILL_BULK_URB(urb, bfusb->udev, pipe, skb->data, size,
-+ bfusb_rx_complete, skb);
-+
-+ urb->transfer_flags = USB_QUEUE_BULK;
-+
-+ skb_queue_tail(&bfusb->pending_q, skb);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s bulk rx submit failed urb %p err %d",
-+ bfusb->hdev.name, urb, err);
-+ skb_unlink(skb);
-+ kfree_skb(skb);
-+ usb_free_urb(urb);
-+ }
-+
-+ return err;
-+}
-+
-+static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *data, int len)
-+{
-+ BT_DBG("bfusb %p hdr 0x%02x data %p len %d", bfusb, hdr, data, len);
-+
-+ if (hdr & 0x10) {
-+ BT_ERR("%s error in block", bfusb->hdev.name);
-+ if (bfusb->reassembly)
-+ kfree_skb(bfusb->reassembly);
-+ bfusb->reassembly = NULL;
-+ return -EIO;
-+ }
-+
-+ if (hdr & 0x04) {
-+ struct sk_buff *skb;
-+ unsigned char pkt_type;
-+ int pkt_len = 0;
-+
-+ if (bfusb->reassembly) {
-+ BT_ERR("%s unexpected start block", bfusb->hdev.name);
-+ kfree_skb(bfusb->reassembly);
-+ bfusb->reassembly = NULL;
-+ }
-+
-+ if (len < 1) {
-+ BT_ERR("%s no packet type found", bfusb->hdev.name);
-+ return -EPROTO;
-+ }
-+
-+ pkt_type = *data++; len--;
-+
-+ switch (pkt_type) {
-+ case HCI_EVENT_PKT:
-+ if (len >= HCI_EVENT_HDR_SIZE) {
-+ hci_event_hdr *hdr = (hci_event_hdr *) data;
-+ pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;
-+ } else {
-+ BT_ERR("%s event block is too short", bfusb->hdev.name);
-+ return -EILSEQ;
-+ }
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ if (len >= HCI_ACL_HDR_SIZE) {
-+ hci_acl_hdr *hdr = (hci_acl_hdr *) data;
-+ pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen);
-+ } else {
-+ BT_ERR("%s data block is too short", bfusb->hdev.name);
-+ return -EILSEQ;
-+ }
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ if (len >= HCI_SCO_HDR_SIZE) {
-+ hci_sco_hdr *hdr = (hci_sco_hdr *) data;
-+ pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen;
-+ } else {
-+ BT_ERR("%s audio block is too short", bfusb->hdev.name);
-+ return -EILSEQ;
-+ }
-+ break;
-+ }
-+
-+ skb = bluez_skb_alloc(pkt_len, GFP_ATOMIC);
-+ if (!skb) {
-+ BT_ERR("%s no memory for the packet", bfusb->hdev.name);
-+ return -ENOMEM;
-+ }
-+
-+ skb->dev = (void *) &bfusb->hdev;
-+ skb->pkt_type = pkt_type;
-+
-+ bfusb->reassembly = skb;
-+ } else {
-+ if (!bfusb->reassembly) {
-+ BT_ERR("%s unexpected continuation block", bfusb->hdev.name);
-+ return -EIO;
-+ }
-+ }
-+
-+ if (len > 0)
-+ memcpy(skb_put(bfusb->reassembly, len), data, len);
-+
-+ if (hdr & 0x08) {
-+ hci_recv_frame(bfusb->reassembly);
-+ bfusb->reassembly = NULL;
-+ }
-+
-+ return 0;
-+}
-+
-+static void bfusb_rx_complete(struct urb *urb)
-+{
-+ struct sk_buff *skb = (struct sk_buff *) urb->context;
-+ struct bfusb *bfusb = (struct bfusb *) skb->dev;
-+ unsigned char *buf = urb->transfer_buffer;
-+ int count = urb->actual_length;
-+ int err, hdr, len;
-+
-+ BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
-+
-+ read_lock(&bfusb->lock);
-+
-+ if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags))
-+ goto unlock;
-+
-+ if (urb->status || !count)
-+ goto resubmit;
-+
-+ bfusb->hdev.stat.byte_rx += count;
-+
-+ skb_put(skb, count);
-+
-+ while (count) {
-+ hdr = buf[0] | (buf[1] << 8);
-+
-+ if (hdr & 0x4000) {
-+ len = 0;
-+ count -= 2;
-+ buf += 2;
-+ } else {
-+ len = (buf[2] == 0) ? 256 : buf[2];
-+ count -= 3;
-+ buf += 3;
-+ }
-+
-+ if (count < len) {
-+ BT_ERR("%s block extends over URB buffer ranges",
-+ bfusb->hdev.name);
-+ }
-+
-+ if ((hdr & 0xe1) == 0xc1)
-+ bfusb_recv_block(bfusb, hdr, buf, len);
-+
-+ count -= len;
-+ buf += len;
-+ }
-+
-+ skb_unlink(skb);
-+ kfree_skb(skb);
-+
-+ bfusb_rx_submit(bfusb, urb);
-+
-+ read_unlock(&bfusb->lock);
-+
-+ return;
-+
-+resubmit:
-+ urb->dev = bfusb->udev;
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s bulk resubmit failed urb %p err %d",
-+ bfusb->hdev.name, urb, err);
-+ }
-+
-+unlock:
-+ read_unlock(&bfusb->lock);
-+}
-+
-+
-+static int bfusb_open(struct hci_dev *hdev)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
-+ unsigned long flags;
-+ int i, err;
-+
-+ BT_DBG("hdev %p bfusb %p", hdev, bfusb);
-+
-+ if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ write_lock_irqsave(&bfusb->lock, flags);
-+
-+ err = bfusb_rx_submit(bfusb, NULL);
-+ if (!err) {
-+ for (i = 1; i < BFUSB_MAX_BULK_RX; i++)
-+ bfusb_rx_submit(bfusb, NULL);
-+ } else {
-+ clear_bit(HCI_RUNNING, &hdev->flags);
-+ MOD_DEC_USE_COUNT;
-+ }
-+
-+ write_unlock_irqrestore(&bfusb->lock, flags);
-+
-+ return err;
-+}
-+
-+static int bfusb_flush(struct hci_dev *hdev)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
-+
-+ BT_DBG("hdev %p bfusb %p", hdev, bfusb);
-+
-+ skb_queue_purge(&bfusb->transmit_q);
-+
-+ return 0;
-+}
-+
-+static int bfusb_close(struct hci_dev *hdev)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
-+ unsigned long flags;
-+
-+ BT_DBG("hdev %p bfusb %p", hdev, bfusb);
-+
-+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-+
-+ write_lock_irqsave(&bfusb->lock, flags);
-+
-+ bfusb_unlink_urbs(bfusb);
-+ bfusb_flush(hdev);
-+
-+ write_unlock_irqrestore(&bfusb->lock, flags);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ return 0;
-+}
-+
-+static int bfusb_send_frame(struct sk_buff *skb)
-+{
-+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-+ struct bfusb *bfusb;
-+ struct sk_buff *nskb;
-+ unsigned char buf[3];
-+ int sent = 0, size, count;
-+
-+ BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, skb->pkt_type, skb->len);
-+
-+ if (!hdev) {
-+ BT_ERR("Frame for unknown HCI device (hdev=NULL)");
-+ return -ENODEV;
-+ }
-+
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return -EBUSY;
-+
-+ bfusb = (struct bfusb *) hdev->driver_data;
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+
-+ count = skb->len;
-+
-+ /* Max HCI frame size seems to be 1511 + 1 */
-+ if (!(nskb = bluez_skb_alloc(count + 32, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for new packet");
-+ return -ENOMEM;
-+ }
-+
-+ nskb->dev = (void *) bfusb;
-+
-+ while (count) {
-+ size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE);
-+
-+ buf[0] = 0xc1 | ((sent == 0) ? 0x04 : 0) | ((count == size) ? 0x08 : 0);
-+ buf[1] = 0x00;
-+ buf[2] = (size == BFUSB_MAX_BLOCK_SIZE) ? 0 : size;
-+
-+ memcpy(skb_put(nskb, 3), buf, 3);
-+ memcpy(skb_put(nskb, size), skb->data + sent, size);
-+
-+ sent += size;
-+ count -= size;
-+ }
-+
-+ /* Don't send frame with multiple size of bulk max packet */
-+ if ((nskb->len % bfusb->bulk_pkt_size) == 0) {
-+ buf[0] = 0xdd;
-+ buf[1] = 0x00;
-+ memcpy(skb_put(nskb, 2), buf, 2);
-+ }
-+
-+ read_lock(&bfusb->lock);
-+
-+ skb_queue_tail(&bfusb->transmit_q, nskb);
-+ bfusb_tx_wakeup(bfusb);
-+
-+ read_unlock(&bfusb->lock);
-+
-+ kfree_skb(skb);
-+
-+ return 0;
-+}
-+
-+static void bfusb_destruct(struct hci_dev *hdev)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
-+
-+ BT_DBG("hdev %p bfusb %p", hdev, bfusb);
-+
-+ kfree(bfusb);
-+}
-+
-+static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int count)
-+{
-+ unsigned char *buf;
-+ int err, pipe, len, size, sent = 0;
-+
-+ BT_DBG("bfusb %p udev %p firmware %p count %d", bfusb, bfusb->udev, firmware, count);
-+
-+ BT_INFO("BlueFRITZ! USB loading firmware");
-+
-+ if (usb_set_configuration(bfusb->udev, 1) < 0) {
-+ BT_ERR("Can't change to loading configuration");
-+ return -EBUSY;
-+ }
-+
-+ buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
-+ if (!buf) {
-+ BT_ERR("Can't allocate memory chunk for firmware");
-+ return -ENOMEM;
-+ }
-+
-+ pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
-+
-+ while (count) {
-+ size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3);
-+
-+ memcpy(buf, firmware + sent, size);
-+
-+ err = usb_bulk_msg(bfusb->udev, pipe, buf, size,
-+ &len, BFUSB_BLOCK_TIMEOUT);
-+
-+ if (err || (len != size)) {
-+ BT_ERR("Error in firmware loading");
-+ goto error;
-+ }
-+
-+ sent += size;
-+ count -= size;
-+ }
-+
-+ if ((err = usb_bulk_msg(bfusb->udev, pipe, NULL, 0,
-+ &len, BFUSB_BLOCK_TIMEOUT)) < 0) {
-+ BT_ERR("Error in null packet request");
-+ goto error;
-+ }
-+
-+ if ((err = usb_set_configuration(bfusb->udev, 2)) < 0) {
-+ BT_ERR("Can't change to running configuration");
-+ goto error;
-+ }
-+
-+ BT_INFO("BlueFRITZ! USB device ready");
-+
-+ kfree(buf);
-+ return 0;
-+
-+error:
-+ kfree(buf);
-+
-+ pipe = usb_sndctrlpipe(bfusb->udev, 0);
-+
-+ usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
-+ 0, 0, 0, NULL, 0, BFUSB_BLOCK_TIMEOUT);
-+
-+ return err;
-+}
-+
-+static void *bfusb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
-+{
-+ const struct firmware *firmware;
-+ char device[16];
-+ struct usb_interface *iface;
-+ struct usb_interface_descriptor *iface_desc;
-+ struct usb_endpoint_descriptor *bulk_out_ep;
-+ struct usb_endpoint_descriptor *bulk_in_ep;
-+ struct hci_dev *hdev;
-+ struct bfusb *bfusb;
-+
-+ BT_DBG("udev %p ifnum %d id %p", udev, ifnum, id);
-+
-+ /* Check number of endpoints */
-+ iface = &udev->actconfig->interface[0];
-+ iface_desc = &iface->altsetting[0];
-+
-+ if (iface_desc->bNumEndpoints < 2)
-+ return NULL;
-+
-+ bulk_out_ep = &iface_desc->endpoint[0];
-+ bulk_in_ep = &iface_desc->endpoint[1];
-+
-+ if (!bulk_out_ep || !bulk_in_ep) {
-+ BT_ERR("Bulk endpoints not found");
-+ goto done;
-+ }
-+
-+ /* Initialize control structure and load firmware */
-+ if (!(bfusb = kmalloc(sizeof(struct bfusb), GFP_KERNEL))) {
-+ BT_ERR("Can't allocate memory for control structure");
-+ goto done;
-+ }
-+
-+ memset(bfusb, 0, sizeof(struct bfusb));
-+
-+ bfusb->udev = udev;
-+ bfusb->bulk_in_ep = bulk_in_ep->bEndpointAddress;
-+ bfusb->bulk_out_ep = bulk_out_ep->bEndpointAddress;
-+ bfusb->bulk_pkt_size = bulk_out_ep->wMaxPacketSize;
-+
-+ bfusb->lock = RW_LOCK_UNLOCKED;
-+
-+ bfusb->reassembly = NULL;
-+
-+ skb_queue_head_init(&bfusb->transmit_q);
-+ skb_queue_head_init(&bfusb->pending_q);
-+ skb_queue_head_init(&bfusb->completed_q);
-+
-+ snprintf(device, sizeof(device), "bfusb%3.3d%3.3d", udev->bus->busnum, udev->devnum);
-+
-+ if (request_firmware(&firmware, "bfubase.frm", device) < 0) {
-+ BT_ERR("Firmware request failed");
-+ goto error;
-+ }
-+
-+ if (bfusb_load_firmware(bfusb, firmware->data, firmware->size) < 0) {
-+ BT_ERR("Firmware loading failed");
-+ goto release;
-+ }
-+
-+ release_firmware(firmware);
-+
-+ /* Initialize and register HCI device */
-+ hdev = &bfusb->hdev;
-+
-+ hdev->type = HCI_USB;
-+ hdev->driver_data = bfusb;
-+
-+ hdev->open = bfusb_open;
-+ hdev->close = bfusb_close;
-+ hdev->flush = bfusb_flush;
-+ hdev->send = bfusb_send_frame;
-+ hdev->destruct = bfusb_destruct;
-+ hdev->ioctl = bfusb_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ BT_ERR("Can't register HCI device");
-+ goto error;
-+ }
-+
-+ return bfusb;
-+
-+release:
-+ release_firmware(firmware);
-+
-+error:
-+ kfree(bfusb);
-+
-+done:
-+ return NULL;
-+}
-+
-+static void bfusb_disconnect(struct usb_device *udev, void *ptr)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) ptr;
-+ struct hci_dev *hdev = &bfusb->hdev;
-+
-+ BT_DBG("udev %p ptr %p", udev, ptr);
-+
-+ if (!hdev)
-+ return;
-+
-+ bfusb_close(hdev);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ BT_ERR("Can't unregister HCI device %s", hdev->name);
-+}
-+
-+static struct usb_driver bfusb_driver = {
-+ name: "bfusb",
-+ probe: bfusb_probe,
-+ disconnect: bfusb_disconnect,
-+ id_table: bfusb_table,
-+};
-+
-+static int __init bfusb_init(void)
-+{
-+ int err;
-+
-+ BT_INFO("BlueFRITZ! USB driver ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2003 Marcel Holtmann <marcel@holtmann.org>");
-+
-+ if ((err = usb_register(&bfusb_driver)) < 0)
-+ BT_ERR("Failed to register BlueFRITZ! USB driver");
-+
-+ return err;
-+}
-+
-+static void __exit bfusb_cleanup(void)
-+{
-+ usb_deregister(&bfusb_driver);
-+}
-+
-+module_init(bfusb_init);
-+module_exit(bfusb_cleanup);
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/drivers/bluetooth/bluecard_cs.c linux-2.4.18-mh15/drivers/bluetooth/bluecard_cs.c
---- linux-2.4.18/drivers/bluetooth/bluecard_cs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/bluecard_cs.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,1116 @@
-+/*
-+ *
-+ * Bluetooth driver for the Anycom BlueCard (LSE039/LSE041)
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+#include <linux/skbuff.h>
-+#include <asm/io.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0x86bc;
-+static int irq_list[4] = { -1 };
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ driver for the Anycom BlueCard (LSE039/LSE041)");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct bluecard_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+ struct timer_list timer; /* For LED control */
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+
-+ unsigned char ctrl_reg;
-+ unsigned long hw_state; /* Status of the hardware and LED control */
-+} bluecard_info_t;
-+
-+
-+void bluecard_config(dev_link_t *link);
-+void bluecard_release(u_long arg);
-+int bluecard_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "bluecard_cs";
-+
-+dev_link_t *bluecard_attach(void);
-+void bluecard_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+
-+/* Default baud rate: 57600, 115200, 230400 or 460800 */
-+#define DEFAULT_BAUD_RATE 230400
-+
-+
-+/* Hardware states */
-+#define CARD_READY 1
-+#define CARD_HAS_PCCARD_ID 4
-+#define CARD_HAS_POWER_LED 5
-+#define CARD_HAS_ACTIVITY_LED 6
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_BUFFER_NUMBER 5 /* unset = buffer one, set = buffer two */
-+#define XMIT_BUF_ONE_READY 6
-+#define XMIT_BUF_TWO_READY 7
-+#define XMIT_SENDING_READY 8
-+
-+/* Receiver states */
-+#define RECV_WAIT_PACKET_TYPE 0
-+#define RECV_WAIT_EVENT_HEADER 1
-+#define RECV_WAIT_ACL_HEADER 2
-+#define RECV_WAIT_SCO_HEADER 3
-+#define RECV_WAIT_DATA 4
-+
-+/* Special packet types */
-+#define PKT_BAUD_RATE_57600 0x80
-+#define PKT_BAUD_RATE_115200 0x81
-+#define PKT_BAUD_RATE_230400 0x82
-+#define PKT_BAUD_RATE_460800 0x83
-+
-+
-+/* These are the register offsets */
-+#define REG_COMMAND 0x20
-+#define REG_INTERRUPT 0x21
-+#define REG_CONTROL 0x22
-+#define REG_RX_CONTROL 0x24
-+#define REG_CARD_RESET 0x30
-+#define REG_LED_CTRL 0x30
-+
-+/* REG_COMMAND */
-+#define REG_COMMAND_TX_BUF_ONE 0x01
-+#define REG_COMMAND_TX_BUF_TWO 0x02
-+#define REG_COMMAND_RX_BUF_ONE 0x04
-+#define REG_COMMAND_RX_BUF_TWO 0x08
-+#define REG_COMMAND_RX_WIN_ONE 0x00
-+#define REG_COMMAND_RX_WIN_TWO 0x10
-+
-+/* REG_CONTROL */
-+#define REG_CONTROL_BAUD_RATE_57600 0x00
-+#define REG_CONTROL_BAUD_RATE_115200 0x01
-+#define REG_CONTROL_BAUD_RATE_230400 0x02
-+#define REG_CONTROL_BAUD_RATE_460800 0x03
-+#define REG_CONTROL_RTS 0x04
-+#define REG_CONTROL_BT_ON 0x08
-+#define REG_CONTROL_BT_RESET 0x10
-+#define REG_CONTROL_BT_RES_PU 0x20
-+#define REG_CONTROL_INTERRUPT 0x40
-+#define REG_CONTROL_CARD_RESET 0x80
-+
-+/* REG_RX_CONTROL */
-+#define RTS_LEVEL_SHIFT_BITS 0x02
-+
-+
-+
-+/* ======================== LED handling routines ======================== */
-+
-+
-+void bluecard_activity_led_timeout(u_long arg)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)arg;
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) {
-+ /* Disable activity LED */
-+ outb(0x08 | 0x20, iobase + 0x30);
-+ } else {
-+ /* Disable power LED */
-+ outb(0x00, iobase + 0x30);
-+ }
-+}
-+
-+
-+static void bluecard_enable_activity_led(bluecard_info_t *info)
-+{
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) {
-+ /* Enable activity LED */
-+ outb(0x10 | 0x40, iobase + 0x30);
-+
-+ /* Stop the LED after HZ/4 */
-+ mod_timer(&(info->timer), jiffies + HZ / 4);
-+ } else {
-+ /* Enable power LED */
-+ outb(0x08 | 0x20, iobase + 0x30);
-+
-+ /* Stop the LED after HZ/2 */
-+ mod_timer(&(info->timer), jiffies + HZ / 2);
-+ }
-+}
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int bluecard_write(unsigned int iobase, unsigned int offset, __u8 *buf, int len)
-+{
-+ int i, actual;
-+
-+ actual = (len > 15) ? 15 : len;
-+
-+ outb_p(actual, iobase + offset);
-+
-+ for (i = 0; i < actual; i++)
-+ outb_p(buf[i], iobase + offset + i + 1);
-+
-+ return actual;
-+}
-+
-+
-+static void bluecard_write_wakeup(bluecard_info_t *info)
-+{
-+ if (!info) {
-+ printk(KERN_WARNING "bluecard_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (!test_bit(XMIT_SENDING_READY, &(info->tx_state)))
-+ return;
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register unsigned int offset;
-+ register unsigned char command;
-+ register unsigned long ready_bit;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ clear_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ return;
-+
-+ if (test_bit(XMIT_BUFFER_NUMBER, &(info->tx_state))) {
-+ if (!test_bit(XMIT_BUF_TWO_READY, &(info->tx_state)))
-+ break;
-+ offset = 0x10;
-+ command = REG_COMMAND_TX_BUF_TWO;
-+ ready_bit = XMIT_BUF_TWO_READY;
-+ } else {
-+ if (!test_bit(XMIT_BUF_ONE_READY, &(info->tx_state)))
-+ break;
-+ offset = 0x00;
-+ command = REG_COMMAND_TX_BUF_ONE;
-+ ready_bit = XMIT_BUF_ONE_READY;
-+ }
-+
-+ if (!(skb = skb_dequeue(&(info->txq))))
-+ break;
-+
-+ if (skb->pkt_type & 0x80) {
-+ /* Disable RTS */
-+ info->ctrl_reg |= REG_CONTROL_RTS;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+ }
-+
-+ /* Activate LED */
-+ bluecard_enable_activity_led(info);
-+
-+ /* Send frame */
-+ len = bluecard_write(iobase, offset, skb->data, skb->len);
-+
-+ /* Tell the FPGA to send the data */
-+ outb_p(command, iobase + REG_COMMAND);
-+
-+ /* Mark the buffer as dirty */
-+ clear_bit(ready_bit, &(info->tx_state));
-+
-+ if (skb->pkt_type & 0x80) {
-+
-+ wait_queue_head_t wait;
-+ unsigned char baud_reg;
-+
-+ switch (skb->pkt_type) {
-+ case PKT_BAUD_RATE_460800:
-+ baud_reg = REG_CONTROL_BAUD_RATE_460800;
-+ break;
-+ case PKT_BAUD_RATE_230400:
-+ baud_reg = REG_CONTROL_BAUD_RATE_230400;
-+ break;
-+ case PKT_BAUD_RATE_115200:
-+ baud_reg = REG_CONTROL_BAUD_RATE_115200;
-+ break;
-+ case PKT_BAUD_RATE_57600:
-+ /* Fall through... */
-+ default:
-+ baud_reg = REG_CONTROL_BAUD_RATE_57600;
-+ break;
-+ }
-+
-+ /* Wait until the command reaches the baseband */
-+ init_waitqueue_head(&wait);
-+ interruptible_sleep_on_timeout(&wait, HZ / 10);
-+
-+ /* Set baud on baseband */
-+ info->ctrl_reg &= ~0x03;
-+ info->ctrl_reg |= baud_reg;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Enable RTS */
-+ info->ctrl_reg &= ~REG_CONTROL_RTS;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Wait before the next HCI packet can be send */
-+ interruptible_sleep_on_timeout(&wait, HZ);
-+
-+ }
-+
-+ if (len == skb->len) {
-+ kfree_skb(skb);
-+ } else {
-+ skb_pull(skb, len);
-+ skb_queue_head(&(info->txq), skb);
-+ }
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ /* Change buffer */
-+ change_bit(XMIT_BUFFER_NUMBER, &(info->tx_state));
-+
-+ } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
-+
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+}
-+
-+
-+static int bluecard_read(unsigned int iobase, unsigned int offset, __u8 *buf, int size)
-+{
-+ int i, n, len;
-+
-+ outb(REG_COMMAND_RX_WIN_ONE, iobase + REG_COMMAND);
-+
-+ len = inb(iobase + offset);
-+ n = 0;
-+ i = 1;
-+
-+ while (n < len) {
-+
-+ if (i == 16) {
-+ outb(REG_COMMAND_RX_WIN_TWO, iobase + REG_COMMAND);
-+ i = 0;
-+ }
-+
-+ buf[n] = inb(iobase + offset + i);
-+
-+ n++;
-+ i++;
-+
-+ }
-+
-+ return len;
-+}
-+
-+
-+static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
-+{
-+ unsigned int iobase;
-+ unsigned char buf[31];
-+ int i, len;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bluecard_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ if (test_bit(XMIT_SENDING_READY, &(info->tx_state)))
-+ bluecard_enable_activity_led(info);
-+
-+ len = bluecard_read(iobase, offset, buf, sizeof(buf));
-+
-+ for (i = 0; i < len; i++) {
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL) {
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "bluecard_cs: Can't allocate mem for new packet.\n");
-+ return;
-+ }
-+ }
-+
-+ if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
-+
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type = buf[i];
-+
-+ switch (info->rx_skb->pkt_type) {
-+
-+ case 0x00:
-+ /* init packet */
-+ if (offset != 0x00) {
-+ set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
-+ set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
-+ set_bit(XMIT_SENDING_READY, &(info->tx_state));
-+ bluecard_write_wakeup(info);
-+ }
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ case HCI_EVENT_PKT:
-+ info->rx_state = RECV_WAIT_EVENT_HEADER;
-+ info->rx_count = HCI_EVENT_HDR_SIZE;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ info->rx_state = RECV_WAIT_ACL_HEADER;
-+ info->rx_count = HCI_ACL_HDR_SIZE;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ info->rx_state = RECV_WAIT_SCO_HEADER;
-+ info->rx_count = HCI_SCO_HDR_SIZE;
-+ break;
-+
-+ default:
-+ /* unknown packet */
-+ printk(KERN_WARNING "bluecard_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-+ info->hdev.stat.err_rx++;
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ } else {
-+
-+ *skb_put(info->rx_skb, 1) = buf[i];
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ int dlen;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+
-+ switch (info->rx_state) {
-+
-+ case RECV_WAIT_EVENT_HEADER:
-+ eh = (hci_event_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = eh->plen;
-+ break;
-+
-+ case RECV_WAIT_ACL_HEADER:
-+ ah = (hci_acl_hdr *)(info->rx_skb->data);
-+ dlen = __le16_to_cpu(ah->dlen);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = dlen;
-+ break;
-+
-+ case RECV_WAIT_SCO_HEADER:
-+ sh = (hci_sco_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = sh->dlen;
-+ break;
-+
-+ case RECV_WAIT_DATA:
-+ hci_recv_frame(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+
-+ }
-+
-+ info->hdev.stat.byte_rx += len;
-+}
-+
-+
-+void bluecard_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ bluecard_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ unsigned char reg;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bluecard_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ if (!test_bit(CARD_READY, &(info->hw_state)))
-+ return;
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ /* Disable interrupt */
-+ info->ctrl_reg &= ~REG_CONTROL_INTERRUPT;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ reg = inb(iobase + REG_INTERRUPT);
-+
-+ if ((reg != 0x00) && (reg != 0xff)) {
-+
-+ if (reg & 0x04) {
-+ bluecard_receive(info, 0x00);
-+ outb(0x04, iobase + REG_INTERRUPT);
-+ outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
-+ }
-+
-+ if (reg & 0x08) {
-+ bluecard_receive(info, 0x10);
-+ outb(0x08, iobase + REG_INTERRUPT);
-+ outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);
-+ }
-+
-+ if (reg & 0x01) {
-+ set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
-+ outb(0x01, iobase + REG_INTERRUPT);
-+ bluecard_write_wakeup(info);
-+ }
-+
-+ if (reg & 0x02) {
-+ set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
-+ outb(0x02, iobase + REG_INTERRUPT);
-+ bluecard_write_wakeup(info);
-+ }
-+
-+ }
-+
-+ /* Enable interrupt */
-+ info->ctrl_reg |= REG_CONTROL_INTERRUPT;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+
-+
-+/* ======================== Device specific HCI commands ======================== */
-+
-+
-+static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-+ struct sk_buff *skb;
-+
-+ /* Ericsson baud rate command */
-+ unsigned char cmd[] = { HCI_COMMAND_PKT, 0x09, 0xfc, 0x01, 0x03 };
-+
-+ if (!(skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "bluecard_cs: Can't allocate mem for new packet.\n");
-+ return -1;
-+ }
-+
-+ switch (baud) {
-+ case 460800:
-+ cmd[4] = 0x00;
-+ skb->pkt_type = PKT_BAUD_RATE_460800;
-+ break;
-+ case 230400:
-+ cmd[4] = 0x01;
-+ skb->pkt_type = PKT_BAUD_RATE_230400;
-+ break;
-+ case 115200:
-+ cmd[4] = 0x02;
-+ skb->pkt_type = PKT_BAUD_RATE_115200;
-+ break;
-+ case 57600:
-+ /* Fall through... */
-+ default:
-+ cmd[4] = 0x03;
-+ skb->pkt_type = PKT_BAUD_RATE_57600;
-+ break;
-+ }
-+
-+ memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
-+
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ bluecard_write_wakeup(info);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int bluecard_hci_flush(struct hci_dev *hdev)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int bluecard_hci_open(struct hci_dev *hdev)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
-+
-+ if (test_and_set_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ /* Enable LED */
-+ outb(0x08 | 0x20, iobase + 0x30);
-+
-+ return 0;
-+}
-+
-+
-+static int bluecard_hci_close(struct hci_dev *hdev)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ bluecard_hci_flush(hdev);
-+
-+ /* Disable LED */
-+ outb(0x00, iobase + 0x30);
-+
-+ return 0;
-+}
-+
-+
-+static int bluecard_hci_send_frame(struct sk_buff *skb)
-+{
-+ bluecard_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+
-+ if (!hdev) {
-+ printk(KERN_WARNING "bluecard_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (bluecard_info_t *)(hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ bluecard_write_wakeup(info);
-+
-+ return 0;
-+}
-+
-+
-+static void bluecard_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+int bluecard_open(bluecard_info_t *info)
-+{
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev;
-+ unsigned char id;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ init_timer(&(info->timer));
-+ info->timer.function = &bluecard_activity_led_timeout;
-+ info->timer.data = (u_long)info;
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ info->rx_skb = NULL;
-+
-+ id = inb(iobase + 0x30);
-+
-+ if ((id & 0x0f) == 0x02)
-+ set_bit(CARD_HAS_PCCARD_ID, &(info->hw_state));
-+
-+ if (id & 0x10)
-+ set_bit(CARD_HAS_POWER_LED, &(info->hw_state));
-+
-+ if (id & 0x20)
-+ set_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state));
-+
-+ /* Reset card */
-+ info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Turn FPGA off */
-+ outb(0x80, iobase + 0x30);
-+
-+ /* Wait some time */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ / 100);
-+
-+ /* Turn FPGA on */
-+ outb(0x00, iobase + 0x30);
-+
-+ /* Activate card */
-+ info->ctrl_reg = REG_CONTROL_BT_ON | REG_CONTROL_BT_RES_PU;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Enable interrupt */
-+ outb(0xff, iobase + REG_INTERRUPT);
-+ info->ctrl_reg |= REG_CONTROL_INTERRUPT;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Start the RX buffers */
-+ outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
-+ outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);
-+
-+ /* Signal that the hardware is ready */
-+ set_bit(CARD_READY, &(info->hw_state));
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ /* Control the point at which RTS is enabled */
-+ outb((0x0f << RTS_LEVEL_SHIFT_BITS) | 1, iobase + REG_RX_CONTROL);
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout((HZ * 5) / 4); // or set it to 3/2
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = bluecard_hci_open;
-+ hdev->close = bluecard_hci_close;
-+ hdev->flush = bluecard_hci_flush;
-+ hdev->send = bluecard_hci_send_frame;
-+ hdev->destruct = bluecard_hci_destruct;
-+ hdev->ioctl = bluecard_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_WARNING "bluecard_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int bluecard_close(bluecard_info_t *info)
-+{
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ if (info->link.state & DEV_CONFIG_PENDING)
-+ return -ENODEV;
-+
-+ bluecard_hci_close(hdev);
-+
-+ clear_bit(CARD_READY, &(info->hw_state));
-+
-+ /* Reset card */
-+ info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Turn FPGA off */
-+ outb(0x80, iobase + 0x30);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_WARNING "bluecard_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+dev_link_t *bluecard_attach(void)
-+{
-+ bluecard_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &bluecard_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = bluecard_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.Vcc = 50;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &bluecard_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ bluecard_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+void bluecard_detach(dev_link_t *link)
-+{
-+ bluecard_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+ if (link->state & DEV_CONFIG)
-+ bluecard_release((u_long)link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+void bluecard_config(dev_link_t *link)
-+{
-+ client_handle_t handle = link->handle;
-+ bluecard_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ config_info_t config;
-+ int i, n, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ link->conf.ConfigIndex = 0x20;
-+ link->io.NumPorts1 = 64;
-+ link->io.IOAddrLines = 6;
-+
-+ for (n = 0; n < 0x400; n += 0x40) {
-+ link->io.BasePort1 = n ^ 0x300;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ break;
-+ }
-+
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (bluecard_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ bluecard_release((u_long)link);
-+}
-+
-+
-+void bluecard_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *)arg;
-+ bluecard_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ bluecard_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+int bluecard_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ bluecard_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ bluecard_close(info);
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ bluecard_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG)
-+ CardServices(ReleaseConfiguration, link->handle);
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (DEV_OK(link))
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_bluecard_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "bluecard_cs: Card Services release does not match!\n");
-+ return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &bluecard_attach, &bluecard_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_bluecard_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ bluecard_detach(dev_list);
-+}
-+
-+
-+module_init(init_bluecard_cs);
-+module_exit(exit_bluecard_cs);
-+
-+EXPORT_NO_SYMBOLS;
-diff -urN linux-2.4.18/drivers/bluetooth/bt3c_cs.c linux-2.4.18-mh15/drivers/bluetooth/bt3c_cs.c
---- linux-2.4.18/drivers/bluetooth/bt3c_cs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/bt3c_cs.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,986 @@
-+/*
-+ *
-+ * Driver for the 3Com Bluetooth PCMCIA card
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ * Jose Orlando Pereira <jop@di.uminho.pt>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/kmod.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/delay.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/unistd.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+
-+#include <linux/skbuff.h>
-+#include <linux/string.h>
-+#include <linux/serial.h>
-+#include <linux/serial_reg.h>
-+#include <asm/system.h>
-+#include <asm/bitops.h>
-+#include <asm/io.h>
-+
-+#include <linux/firmware.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0xffff;
-+static int irq_list[4] = { -1 };
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>, Jose Orlando Pereira <jop@di.uminho.pt>");
-+MODULE_DESCRIPTION("BlueZ driver for the 3Com Bluetooth PCMCIA card");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct bt3c_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+} bt3c_info_t;
-+
-+
-+void bt3c_config(dev_link_t *link);
-+void bt3c_release(u_long arg);
-+int bt3c_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "bt3c_cs";
-+
-+dev_link_t *bt3c_attach(void);
-+void bt3c_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_WAITING 8
-+
-+/* Receiver states */
-+#define RECV_WAIT_PACKET_TYPE 0
-+#define RECV_WAIT_EVENT_HEADER 1
-+#define RECV_WAIT_ACL_HEADER 2
-+#define RECV_WAIT_SCO_HEADER 3
-+#define RECV_WAIT_DATA 4
-+
-+
-+
-+/* ======================== Special I/O functions ======================== */
-+
-+
-+#define DATA_L 0
-+#define DATA_H 1
-+#define ADDR_L 2
-+#define ADDR_H 3
-+#define CONTROL 4
-+
-+
-+inline void bt3c_address(unsigned int iobase, unsigned short addr)
-+{
-+ outb(addr & 0xff, iobase + ADDR_L);
-+ outb((addr >> 8) & 0xff, iobase + ADDR_H);
-+}
-+
-+
-+inline void bt3c_put(unsigned int iobase, unsigned short value)
-+{
-+ outb(value & 0xff, iobase + DATA_L);
-+ outb((value >> 8) & 0xff, iobase + DATA_H);
-+}
-+
-+
-+inline void bt3c_io_write(unsigned int iobase, unsigned short addr, unsigned short value)
-+{
-+ bt3c_address(iobase, addr);
-+ bt3c_put(iobase, value);
-+}
-+
-+
-+inline unsigned short bt3c_get(unsigned int iobase)
-+{
-+ unsigned short value = inb(iobase + DATA_L);
-+
-+ value |= inb(iobase + DATA_H) << 8;
-+
-+ return value;
-+}
-+
-+
-+inline unsigned short bt3c_read(unsigned int iobase, unsigned short addr)
-+{
-+ bt3c_address(iobase, addr);
-+
-+ return bt3c_get(iobase);
-+}
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int bt3c_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
-+{
-+ int actual = 0;
-+
-+ bt3c_address(iobase, 0x7080);
-+
-+ /* Fill FIFO with current frame */
-+ while (actual < len) {
-+ /* Transmit next byte */
-+ bt3c_put(iobase, buf[actual]);
-+ actual++;
-+ }
-+
-+ bt3c_io_write(iobase, 0x7005, actual);
-+
-+ return actual;
-+}
-+
-+
-+static void bt3c_write_wakeup(bt3c_info_t *info, int from)
-+{
-+ unsigned long flags;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bt3c_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state)))
-+ return;
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ break;
-+
-+
-+ if (!(skb = skb_dequeue(&(info->txq)))) {
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+ break;
-+ }
-+
-+ /* Send frame */
-+ len = bt3c_write(iobase, 256, skb->data, skb->len);
-+
-+ if (len != skb->len) {
-+ printk(KERN_WARNING "bt3c_cs: very strange\n");
-+ }
-+
-+ kfree_skb(skb);
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ } while (0);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+}
-+
-+
-+static void bt3c_receive(bt3c_info_t *info)
-+{
-+ unsigned int iobase;
-+ int size = 0, avail;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bt3c_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ avail = bt3c_read(iobase, 0x7006);
-+ //printk("bt3c_cs: receiving %d bytes\n", avail);
-+
-+ bt3c_address(iobase, 0x7480);
-+ while (size < avail) {
-+ size++;
-+ info->hdev.stat.byte_rx++;
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL) {
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "bt3c_cs: Can't allocate mem for new packet.\n");
-+ return;
-+ }
-+ }
-+
-+
-+ if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
-+
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type = inb(iobase + DATA_L);
-+ inb(iobase + DATA_H);
-+ //printk("bt3c: PACKET_TYPE=%02x\n", info->rx_skb->pkt_type);
-+
-+ switch (info->rx_skb->pkt_type) {
-+
-+ case HCI_EVENT_PKT:
-+ info->rx_state = RECV_WAIT_EVENT_HEADER;
-+ info->rx_count = HCI_EVENT_HDR_SIZE;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ info->rx_state = RECV_WAIT_ACL_HEADER;
-+ info->rx_count = HCI_ACL_HDR_SIZE;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ info->rx_state = RECV_WAIT_SCO_HEADER;
-+ info->rx_count = HCI_SCO_HDR_SIZE;
-+ break;
-+
-+ default:
-+ /* Unknown packet */
-+ printk(KERN_WARNING "bt3c_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-+ info->hdev.stat.err_rx++;
-+ clear_bit(HCI_RUNNING, &(info->hdev.flags));
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ } else {
-+
-+ __u8 x = inb(iobase + DATA_L);
-+
-+ *skb_put(info->rx_skb, 1) = x;
-+ inb(iobase + DATA_H);
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ int dlen;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+
-+ switch (info->rx_state) {
-+
-+ case RECV_WAIT_EVENT_HEADER:
-+ eh = (hci_event_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = eh->plen;
-+ break;
-+
-+ case RECV_WAIT_ACL_HEADER:
-+ ah = (hci_acl_hdr *)(info->rx_skb->data);
-+ dlen = __le16_to_cpu(ah->dlen);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = dlen;
-+ break;
-+
-+ case RECV_WAIT_SCO_HEADER:
-+ sh = (hci_sco_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = sh->dlen;
-+ break;
-+
-+ case RECV_WAIT_DATA:
-+ hci_recv_frame(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+ bt3c_io_write(iobase, 0x7006, 0x0000);
-+}
-+
-+
-+void bt3c_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ bt3c_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ int iir;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bt3c_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ iir = inb(iobase + CONTROL);
-+ if (iir & 0x80) {
-+ int stat = bt3c_read(iobase, 0x7001);
-+
-+ if ((stat & 0xff) == 0x7f) {
-+ printk(KERN_WARNING "bt3c_cs: STRANGE stat=%04x\n", stat);
-+ } else if ((stat & 0xff) != 0xff) {
-+ if (stat & 0x0020) {
-+ int stat = bt3c_read(iobase, 0x7002) & 0x10;
-+ printk(KERN_WARNING "bt3c_cs: antena %s\n", stat ? "OUT" : "IN");
-+ }
-+ if (stat & 0x0001)
-+ bt3c_receive(info);
-+ if (stat & 0x0002) {
-+ //printk("bt3c_cs: ACK %04x\n", stat);
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+ bt3c_write_wakeup(info, 1);
-+ }
-+
-+ bt3c_io_write(iobase, 0x7001, 0x0000);
-+
-+ outb(iir, iobase + CONTROL);
-+ }
-+ }
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int bt3c_hci_flush(struct hci_dev *hdev)
-+{
-+ bt3c_info_t *info = (bt3c_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int bt3c_hci_open(struct hci_dev *hdev)
-+{
-+ set_bit(HCI_RUNNING, &(hdev->flags));
-+
-+ return 0;
-+}
-+
-+
-+static int bt3c_hci_close(struct hci_dev *hdev)
-+{
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ bt3c_hci_flush(hdev);
-+
-+ return 0;
-+}
-+
-+
-+static int bt3c_hci_send_frame(struct sk_buff *skb)
-+{
-+ bt3c_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+
-+ if (!hdev) {
-+ printk(KERN_WARNING "bt3c_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (bt3c_info_t *) (hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ bt3c_write_wakeup(info, 0);
-+
-+ return 0;
-+}
-+
-+
-+static void bt3c_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+static int bt3c_load_firmware(bt3c_info_t *info, unsigned char *firmware, int count)
-+{
-+ char *ptr = (char *) firmware;
-+ char b[9];
-+ unsigned int iobase, size, addr, fcs, tmp;
-+ int i, err = 0;
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ /* Reset */
-+
-+ bt3c_io_write(iobase, 0x8040, 0x0404);
-+ bt3c_io_write(iobase, 0x8040, 0x0400);
-+
-+ udelay(1);
-+
-+ bt3c_io_write(iobase, 0x8040, 0x0404);
-+
-+ udelay(17);
-+
-+ /* Load */
-+
-+ while (count) {
-+ if (ptr[0] != 'S') {
-+ printk(KERN_WARNING "bt3c_cs: Bad address in firmware.\n");
-+ err = -EFAULT;
-+ goto error;
-+ }
-+
-+ memset(b, 0, sizeof(b));
-+ memcpy(b, ptr + 2, 2);
-+ size = simple_strtol(b, NULL, 16);
-+
-+ memset(b, 0, sizeof(b));
-+ memcpy(b, ptr + 4, 8);
-+ addr = simple_strtol(b, NULL, 16);
-+
-+ memset(b, 0, sizeof(b));
-+ memcpy(b, ptr + (size * 2) + 2, 2);
-+ fcs = simple_strtol(b, NULL, 16);
-+
-+ memset(b, 0, sizeof(b));
-+ for (tmp = 0, i = 0; i < size; i++) {
-+ memcpy(b, ptr + (i * 2) + 2, 2);
-+ tmp += simple_strtol(b, NULL, 16);
-+ }
-+
-+ if (((tmp + fcs) & 0xff) != 0xff) {
-+ printk(KERN_WARNING "bt3c_cs: Checksum error in firmware.\n");
-+ err = -EILSEQ;
-+ goto error;
-+ }
-+
-+ if (ptr[1] == '3') {
-+ bt3c_address(iobase, addr);
-+
-+ memset(b, 0, sizeof(b));
-+ for (i = 0; i < (size - 4) / 2; i++) {
-+ memcpy(b, ptr + (i * 4) + 12, 4);
-+ tmp = simple_strtol(b, NULL, 16);
-+ bt3c_put(iobase, tmp);
-+ }
-+ }
-+
-+ ptr += (size * 2) + 6;
-+ count -= (size * 2) + 6;
-+ }
-+
-+ udelay(17);
-+
-+ /* Boot */
-+
-+ bt3c_address(iobase, 0x3000);
-+ outb(inb(iobase + CONTROL) | 0x40, iobase + CONTROL);
-+
-+error:
-+ udelay(17);
-+
-+ /* Clear */
-+
-+ bt3c_io_write(iobase, 0x7006, 0x0000);
-+ bt3c_io_write(iobase, 0x7005, 0x0000);
-+ bt3c_io_write(iobase, 0x7001, 0x0000);
-+
-+ return err;
-+}
-+
-+
-+int bt3c_open(bt3c_info_t *info)
-+{
-+ const struct firmware *firmware;
-+ char device[16];
-+ struct hci_dev *hdev;
-+ int err;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ info->rx_skb = NULL;
-+
-+ /* Load firmware */
-+
-+ snprintf(device, sizeof(device), "bt3c%4.4x", info->link.io.BasePort1);
-+
-+ err = request_firmware(&firmware, "BT3CPCC.bin", device);
-+ if (err < 0) {
-+ printk(KERN_WARNING "bt3c_cs: Firmware request failed.\n");
-+ return err;
-+ }
-+
-+ err = bt3c_load_firmware(info, firmware->data, firmware->size);
-+
-+ release_firmware(firmware);
-+
-+ if (err < 0) {
-+ printk(KERN_WARNING "bt3c_cs: Firmware loading failed.\n");
-+ return err;
-+ }
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ);
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = bt3c_hci_open;
-+ hdev->close = bt3c_hci_close;
-+ hdev->flush = bt3c_hci_flush;
-+ hdev->send = bt3c_hci_send_frame;
-+ hdev->destruct = bt3c_hci_destruct;
-+ hdev->ioctl = bt3c_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_WARNING "bt3c_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int bt3c_close(bt3c_info_t *info)
-+{
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ if (info->link.state & DEV_CONFIG_PENDING)
-+ return -ENODEV;
-+
-+ bt3c_hci_close(hdev);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_WARNING "bt3c_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+dev_link_t *bt3c_attach(void)
-+{
-+ bt3c_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &bt3c_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = bt3c_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.Vcc = 50;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &bt3c_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ bt3c_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+void bt3c_detach(dev_link_t *link)
-+{
-+ bt3c_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+
-+ if (link->state & DEV_CONFIG)
-+ bt3c_release((u_long)link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+void bt3c_config(dev_link_t *link)
-+{
-+ static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
-+ client_handle_t handle = link->handle;
-+ bt3c_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
-+ int i, j, try, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ /* First pass: look for a config entry that looks normal. */
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-+ /* Two tries: without IO aliases, then with aliases */
-+ for (try = 0; try < 2; try++) {
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if (i != CS_SUCCESS)
-+ goto next_entry;
-+ if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
-+ link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-+ if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
-+ link->conf.ConfigIndex = cf->index;
-+ link->io.BasePort1 = cf->io.win[0].base;
-+ link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+next_entry:
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+ }
-+
-+ /* Second pass: try to find an entry that isn't picky about
-+ its base address, then try to grab any standard serial port
-+ address, and finally try to get any free port. */
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
-+ link->conf.ConfigIndex = cf->index;
-+ for (j = 0; j < 5; j++) {
-+ link->io.BasePort1 = base[j];
-+ link->io.IOAddrLines = base[j] ? 16 : 3;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+ }
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+
-+found_port:
-+ if (i != CS_SUCCESS) {
-+ printk(KERN_NOTICE "bt3c_cs: No usable port range found. Giving up.\n");
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (bt3c_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ bt3c_release((u_long)link);
-+}
-+
-+
-+void bt3c_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *)arg;
-+ bt3c_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ bt3c_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+int bt3c_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ bt3c_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ bt3c_close(info);
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ bt3c_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG)
-+ CardServices(ReleaseConfiguration, link->handle);
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (DEV_OK(link))
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_bt3c_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "bt3c_cs: Card Services release does not match!\n");
-+ return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &bt3c_attach, &bt3c_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_bt3c_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ bt3c_detach(dev_list);
-+}
-+
-+
-+module_init(init_bt3c_cs);
-+module_exit(exit_bt3c_cs);
-+
-+EXPORT_NO_SYMBOLS;
-diff -urN linux-2.4.18/drivers/bluetooth/btuart_cs.c linux-2.4.18-mh15/drivers/bluetooth/btuart_cs.c
---- linux-2.4.18/drivers/bluetooth/btuart_cs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/btuart_cs.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,909 @@
-+/*
-+ *
-+ * Driver for Bluetooth PCMCIA cards with HCI UART interface
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+
-+#include <linux/skbuff.h>
-+#include <linux/string.h>
-+#include <linux/serial.h>
-+#include <linux/serial_reg.h>
-+#include <asm/system.h>
-+#include <asm/bitops.h>
-+#include <asm/io.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0xffff;
-+static int irq_list[4] = { -1 };
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ driver for Bluetooth PCMCIA cards with HCI UART interface");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct btuart_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+} btuart_info_t;
-+
-+
-+void btuart_config(dev_link_t *link);
-+void btuart_release(u_long arg);
-+int btuart_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "btuart_cs";
-+
-+dev_link_t *btuart_attach(void);
-+void btuart_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+
-+/* Maximum baud rate */
-+#define SPEED_MAX 115200
-+
-+/* Default baud rate: 57600, 115200, 230400 or 460800 */
-+#define DEFAULT_BAUD_RATE 115200
-+
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_WAITING 8
-+
-+/* Receiver states */
-+#define RECV_WAIT_PACKET_TYPE 0
-+#define RECV_WAIT_EVENT_HEADER 1
-+#define RECV_WAIT_ACL_HEADER 2
-+#define RECV_WAIT_SCO_HEADER 3
-+#define RECV_WAIT_DATA 4
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int btuart_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
-+{
-+ int actual = 0;
-+
-+ /* Tx FIFO should be empty */
-+ if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
-+ return 0;
-+
-+ /* Fill FIFO with current frame */
-+ while ((fifo_size-- > 0) && (actual < len)) {
-+ /* Transmit next byte */
-+ outb(buf[actual], iobase + UART_TX);
-+ actual++;
-+ }
-+
-+ return actual;
-+}
-+
-+
-+static void btuart_write_wakeup(btuart_info_t *info)
-+{
-+ if (!info) {
-+ printk(KERN_WARNING "btuart_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ clear_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ return;
-+
-+ if (!(skb = skb_dequeue(&(info->txq))))
-+ break;
-+
-+ /* Send frame */
-+ len = btuart_write(iobase, 16, skb->data, skb->len);
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (len == skb->len) {
-+ kfree_skb(skb);
-+ } else {
-+ skb_pull(skb, len);
-+ skb_queue_head(&(info->txq), skb);
-+ }
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
-+
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+}
-+
-+
-+static void btuart_receive(btuart_info_t *info)
-+{
-+ unsigned int iobase;
-+ int boguscount = 0;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "btuart_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ do {
-+ info->hdev.stat.byte_rx++;
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL) {
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "btuart_cs: Can't allocate mem for new packet.\n");
-+ return;
-+ }
-+ }
-+
-+ if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
-+
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type = inb(iobase + UART_RX);
-+
-+ switch (info->rx_skb->pkt_type) {
-+
-+ case HCI_EVENT_PKT:
-+ info->rx_state = RECV_WAIT_EVENT_HEADER;
-+ info->rx_count = HCI_EVENT_HDR_SIZE;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ info->rx_state = RECV_WAIT_ACL_HEADER;
-+ info->rx_count = HCI_ACL_HDR_SIZE;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ info->rx_state = RECV_WAIT_SCO_HEADER;
-+ info->rx_count = HCI_SCO_HDR_SIZE;
-+ break;
-+
-+ default:
-+ /* Unknown packet */
-+ printk(KERN_WARNING "btuart_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-+ info->hdev.stat.err_rx++;
-+ clear_bit(HCI_RUNNING, &(info->hdev.flags));
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ } else {
-+
-+ *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ int dlen;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+
-+
-+ switch (info->rx_state) {
-+
-+ case RECV_WAIT_EVENT_HEADER:
-+ eh = (hci_event_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = eh->plen;
-+ break;
-+
-+ case RECV_WAIT_ACL_HEADER:
-+ ah = (hci_acl_hdr *)(info->rx_skb->data);
-+ dlen = __le16_to_cpu(ah->dlen);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = dlen;
-+ break;
-+
-+ case RECV_WAIT_SCO_HEADER:
-+ sh = (hci_sco_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = sh->dlen;
-+ break;
-+
-+ case RECV_WAIT_DATA:
-+ hci_recv_frame(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+ /* Make sure we don't stay here to long */
-+ if (boguscount++ > 16)
-+ break;
-+
-+ } while (inb(iobase + UART_LSR) & UART_LSR_DR);
-+}
-+
-+
-+void btuart_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ btuart_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ int boguscount = 0;
-+ int iir, lsr;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "btuart_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-+ while (iir) {
-+
-+ /* Clear interrupt */
-+ lsr = inb(iobase + UART_LSR);
-+
-+ switch (iir) {
-+ case UART_IIR_RLSI:
-+ printk(KERN_NOTICE "btuart_cs: RLSI\n");
-+ break;
-+ case UART_IIR_RDI:
-+ /* Receive interrupt */
-+ btuart_receive(info);
-+ break;
-+ case UART_IIR_THRI:
-+ if (lsr & UART_LSR_THRE) {
-+ /* Transmitter ready for data */
-+ btuart_write_wakeup(info);
-+ }
-+ break;
-+ default:
-+ printk(KERN_NOTICE "btuart_cs: Unhandled IIR=%#x\n", iir);
-+ break;
-+ }
-+
-+ /* Make sure we don't stay here to long */
-+ if (boguscount++ > 100)
-+ break;
-+
-+ iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-+
-+ }
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+
-+static void btuart_change_speed(btuart_info_t *info, unsigned int speed)
-+{
-+ unsigned long flags;
-+ unsigned int iobase;
-+ int fcr; /* FIFO control reg */
-+ int lcr; /* Line control reg */
-+ int divisor;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "btuart_cs: Call of change speed for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ divisor = SPEED_MAX / speed;
-+
-+ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT;
-+
-+ /*
-+ * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and
-+ * almost 1,7 ms at 19200 bps. At speeds above that we can just forget
-+ * about this timeout since it will always be fast enough.
-+ */
-+
-+ if (speed < 38400)
-+ fcr |= UART_FCR_TRIGGER_1;
-+ else
-+ fcr |= UART_FCR_TRIGGER_14;
-+
-+ /* Bluetooth cards use 8N1 */
-+ lcr = UART_LCR_WLEN8;
-+
-+ outb(UART_LCR_DLAB | lcr, iobase + UART_LCR); /* Set DLAB */
-+ outb(divisor & 0xff, iobase + UART_DLL); /* Set speed */
-+ outb(divisor >> 8, iobase + UART_DLM);
-+ outb(lcr, iobase + UART_LCR); /* Set 8N1 */
-+ outb(fcr, iobase + UART_FCR); /* Enable FIFO's */
-+
-+ /* Turn on interrups */
-+ outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+}
-+
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int btuart_hci_flush(struct hci_dev *hdev)
-+{
-+ btuart_info_t *info = (btuart_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int btuart_hci_open(struct hci_dev *hdev)
-+{
-+ set_bit(HCI_RUNNING, &(hdev->flags));
-+
-+ return 0;
-+}
-+
-+
-+static int btuart_hci_close(struct hci_dev *hdev)
-+{
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ btuart_hci_flush(hdev);
-+
-+ return 0;
-+}
-+
-+
-+static int btuart_hci_send_frame(struct sk_buff *skb)
-+{
-+ btuart_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+
-+ if (!hdev) {
-+ printk(KERN_WARNING "btuart_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (btuart_info_t *)(hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ btuart_write_wakeup(info);
-+
-+ return 0;
-+}
-+
-+
-+static void btuart_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+int btuart_open(btuart_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ info->rx_skb = NULL;
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Reset UART */
-+ outb(0, iobase + UART_MCR);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ /* Initialize UART */
-+ outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
-+ outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
-+
-+ /* Turn on interrupts */
-+ // outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ btuart_change_speed(info, DEFAULT_BAUD_RATE);
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ);
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = btuart_hci_open;
-+ hdev->close = btuart_hci_close;
-+ hdev->flush = btuart_hci_flush;
-+ hdev->send = btuart_hci_send_frame;
-+ hdev->destruct = btuart_hci_destruct;
-+ hdev->ioctl = btuart_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_WARNING "btuart_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int btuart_close(btuart_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ if (info->link.state & DEV_CONFIG_PENDING)
-+ return -ENODEV;
-+
-+ btuart_hci_close(hdev);
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Reset UART */
-+ outb(0, iobase + UART_MCR);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_WARNING "btuart_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+dev_link_t *btuart_attach(void)
-+{
-+ btuart_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &btuart_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = btuart_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.Vcc = 50;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &btuart_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ btuart_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+void btuart_detach(dev_link_t *link)
-+{
-+ btuart_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+ if (link->state & DEV_CONFIG)
-+ btuart_release((u_long)link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+void btuart_config(dev_link_t *link)
-+{
-+ static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
-+ client_handle_t handle = link->handle;
-+ btuart_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
-+ int i, j, try, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ /* First pass: look for a config entry that looks normal. */
-+ tuple.TupleData = (cisdata_t *) buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-+ /* Two tries: without IO aliases, then with aliases */
-+ for (try = 0; try < 2; try++) {
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if (i != CS_SUCCESS)
-+ goto next_entry;
-+ if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
-+ link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-+ if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
-+ link->conf.ConfigIndex = cf->index;
-+ link->io.BasePort1 = cf->io.win[0].base;
-+ link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+next_entry:
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+ }
-+
-+ /* Second pass: try to find an entry that isn't picky about
-+ its base address, then try to grab any standard serial port
-+ address, and finally try to get any free port. */
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if ((i == CS_SUCCESS) && (cf->io.nwin > 0)
-+ && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
-+ link->conf.ConfigIndex = cf->index;
-+ for (j = 0; j < 5; j++) {
-+ link->io.BasePort1 = base[j];
-+ link->io.IOAddrLines = base[j] ? 16 : 3;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+ }
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+
-+found_port:
-+ if (i != CS_SUCCESS) {
-+ printk(KERN_NOTICE "btuart_cs: No usable port range found. Giving up.\n");
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (btuart_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ btuart_release((u_long) link);
-+}
-+
-+
-+void btuart_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *)arg;
-+ btuart_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ btuart_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+int btuart_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ btuart_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ btuart_close(info);
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ btuart_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG)
-+ CardServices(ReleaseConfiguration, link->handle);
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (DEV_OK(link))
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_btuart_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "btuart_cs: Card Services release does not match!\n");
-+ return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &btuart_attach, &btuart_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_btuart_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ btuart_detach(dev_list);
-+}
-+
-+
-+module_init(init_btuart_cs);
-+module_exit(exit_btuart_cs);
-+
-+EXPORT_NO_SYMBOLS;
-diff -urN linux-2.4.18/drivers/bluetooth/Config.in linux-2.4.18-mh15/drivers/bluetooth/Config.in
---- linux-2.4.18/drivers/bluetooth/Config.in 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/drivers/bluetooth/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -1,8 +1,33 @@
-+#
-+# Bluetooth HCI device drivers configuration
-+#
-+
- mainmenu_option next_comment
- comment 'Bluetooth device drivers'
-
- dep_tristate 'HCI USB driver' CONFIG_BLUEZ_HCIUSB $CONFIG_BLUEZ $CONFIG_USB
-+if [ "$CONFIG_BLUEZ_HCIUSB" != "n" ]; then
-+ bool ' SCO (voice) support' CONFIG_BLUEZ_HCIUSB_SCO
-+fi
-+
- dep_tristate 'HCI UART driver' CONFIG_BLUEZ_HCIUART $CONFIG_BLUEZ
--dep_tristate 'HCI VHCI virtual HCI device driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
-+if [ "$CONFIG_BLUEZ_HCIUART" != "n" ]; then
-+ bool ' UART (H4) protocol support' CONFIG_BLUEZ_HCIUART_H4
-+ bool ' BCSP protocol support' CONFIG_BLUEZ_HCIUART_BCSP
-+ dep_bool ' Transmit CRC with every BCSP packet' CONFIG_BLUEZ_HCIUART_BCSP_TXCRC $CONFIG_BLUEZ_HCIUART_BCSP
-+fi
-+
-+dep_tristate 'HCI BlueFRITZ! USB driver' CONFIG_BLUEZ_HCIBFUSB $CONFIG_BLUEZ $CONFIG_USB
-+
-+dep_tristate 'HCI DTL1 (PC Card) driver' CONFIG_BLUEZ_HCIDTL1 $CONFIG_PCMCIA $CONFIG_BLUEZ
-+
-+dep_tristate 'HCI BT3C (PC Card) driver' CONFIG_BLUEZ_HCIBT3C $CONFIG_PCMCIA $CONFIG_BLUEZ
-+
-+dep_tristate 'HCI BlueCard (PC Card) driver' CONFIG_BLUEZ_HCIBLUECARD $CONFIG_PCMCIA $CONFIG_BLUEZ
-+
-+dep_tristate 'HCI UART (PC Card) driver' CONFIG_BLUEZ_HCIBTUART $CONFIG_PCMCIA $CONFIG_BLUEZ
-+
-+dep_tristate 'HCI VHCI (Virtual HCI device) driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
-
- endmenu
-+
-diff -urN linux-2.4.18/drivers/bluetooth/dtl1_cs.c linux-2.4.18-mh15/drivers/bluetooth/dtl1_cs.c
---- linux-2.4.18/drivers/bluetooth/dtl1_cs.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/dtl1_cs.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,861 @@
-+/*
-+ *
-+ * A driver for Nokia Connectivity Card DTL-1 devices
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+
-+#include <linux/skbuff.h>
-+#include <linux/string.h>
-+#include <linux/serial.h>
-+#include <linux/serial_reg.h>
-+#include <asm/system.h>
-+#include <asm/bitops.h>
-+#include <asm/io.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0xffff;
-+static int irq_list[4] = { -1 };
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ driver for Nokia Connectivity Card DTL-1");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct dtl1_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+
-+ unsigned long flowmask; /* HCI flow mask */
-+ int ri_latch;
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+} dtl1_info_t;
-+
-+
-+void dtl1_config(dev_link_t *link);
-+void dtl1_release(u_long arg);
-+int dtl1_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "dtl1_cs";
-+
-+dev_link_t *dtl1_attach(void);
-+void dtl1_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_WAITING 8
-+
-+/* Receiver States */
-+#define RECV_WAIT_NSH 0
-+#define RECV_WAIT_DATA 1
-+
-+
-+typedef struct {
-+ u8 type;
-+ u8 zero;
-+ u16 len;
-+} __attribute__ ((packed)) nsh_t; /* Nokia Specific Header */
-+
-+#define NSHL 4 /* Nokia Specific Header Length */
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int dtl1_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
-+{
-+ int actual = 0;
-+
-+ /* Tx FIFO should be empty */
-+ if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
-+ return 0;
-+
-+ /* Fill FIFO with current frame */
-+ while ((fifo_size-- > 0) && (actual < len)) {
-+ /* Transmit next byte */
-+ outb(buf[actual], iobase + UART_TX);
-+ actual++;
-+ }
-+
-+ return actual;
-+}
-+
-+
-+static void dtl1_write_wakeup(dtl1_info_t *info)
-+{
-+ if (!info) {
-+ printk(KERN_WARNING "dtl1_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (test_bit(XMIT_WAITING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ clear_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ return;
-+
-+ if (!(skb = skb_dequeue(&(info->txq))))
-+ break;
-+
-+ /* Send frame */
-+ len = dtl1_write(iobase, 32, skb->data, skb->len);
-+
-+ if (len == skb->len) {
-+ set_bit(XMIT_WAITING, &(info->tx_state));
-+ kfree_skb(skb);
-+ } else {
-+ skb_pull(skb, len);
-+ skb_queue_head(&(info->txq), skb);
-+ }
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
-+
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+}
-+
-+
-+static void dtl1_control(dtl1_info_t *info, struct sk_buff *skb)
-+{
-+ u8 flowmask = *(u8 *)skb->data;
-+ int i;
-+
-+ printk(KERN_INFO "dtl1_cs: Nokia control data = ");
-+ for (i = 0; i < skb->len; i++) {
-+ printk("%02x ", skb->data[i]);
-+ }
-+ printk("\n");
-+
-+ /* transition to active state */
-+ if (((info->flowmask & 0x07) == 0) && ((flowmask & 0x07) != 0)) {
-+ clear_bit(XMIT_WAITING, &(info->tx_state));
-+ dtl1_write_wakeup(info);
-+ }
-+
-+ info->flowmask = flowmask;
-+
-+ kfree_skb(skb);
-+}
-+
-+
-+static void dtl1_receive(dtl1_info_t *info)
-+{
-+ unsigned int iobase;
-+ nsh_t *nsh;
-+ int boguscount = 0;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "dtl1_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ do {
-+ info->hdev.stat.byte_rx++;
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL)
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "dtl1_cs: Can't allocate mem for new packet.\n");
-+ info->rx_state = RECV_WAIT_NSH;
-+ info->rx_count = NSHL;
-+ return;
-+ }
-+
-+ *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
-+ nsh = (nsh_t *)info->rx_skb->data;
-+
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ switch (info->rx_state) {
-+ case RECV_WAIT_NSH:
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = nsh->len + (nsh->len & 0x0001);
-+ break;
-+ case RECV_WAIT_DATA:
-+ info->rx_skb->pkt_type = nsh->type;
-+
-+ /* remove PAD byte if it exists */
-+ if (nsh->len & 0x0001) {
-+ info->rx_skb->tail--;
-+ info->rx_skb->len--;
-+ }
-+
-+ /* remove NSH */
-+ skb_pull(info->rx_skb, NSHL);
-+
-+ switch (info->rx_skb->pkt_type) {
-+ case 0x80:
-+ /* control data for the Nokia Card */
-+ dtl1_control(info, info->rx_skb);
-+ break;
-+ case 0x82:
-+ case 0x83:
-+ case 0x84:
-+ /* send frame to the HCI layer */
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type &= 0x0f;
-+ hci_recv_frame(info->rx_skb);
-+ break;
-+ default:
-+ /* unknown packet */
-+ printk(KERN_WARNING "dtl1_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-+ kfree_skb(info->rx_skb);
-+ break;
-+ }
-+
-+ info->rx_state = RECV_WAIT_NSH;
-+ info->rx_count = NSHL;
-+ info->rx_skb = NULL;
-+ break;
-+ }
-+
-+ }
-+
-+ /* Make sure we don't stay here to long */
-+ if (boguscount++ > 32)
-+ break;
-+
-+ } while (inb(iobase + UART_LSR) & UART_LSR_DR);
-+}
-+
-+
-+void dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ dtl1_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ unsigned char msr;
-+ int boguscount = 0;
-+ int iir, lsr;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "dtl1_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-+ while (iir) {
-+
-+ /* Clear interrupt */
-+ lsr = inb(iobase + UART_LSR);
-+
-+ switch (iir) {
-+ case UART_IIR_RLSI:
-+ printk(KERN_NOTICE "dtl1_cs: RLSI\n");
-+ break;
-+ case UART_IIR_RDI:
-+ /* Receive interrupt */
-+ dtl1_receive(info);
-+ break;
-+ case UART_IIR_THRI:
-+ if (lsr & UART_LSR_THRE) {
-+ /* Transmitter ready for data */
-+ dtl1_write_wakeup(info);
-+ }
-+ break;
-+ default:
-+ printk(KERN_NOTICE "dtl1_cs: Unhandled IIR=%#x\n", iir);
-+ break;
-+ }
-+
-+ /* Make sure we don't stay here to long */
-+ if (boguscount++ > 100)
-+ break;
-+
-+ iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-+
-+ }
-+
-+ msr = inb(iobase + UART_MSR);
-+
-+ if (info->ri_latch ^ (msr & UART_MSR_RI)) {
-+ info->ri_latch = msr & UART_MSR_RI;
-+ clear_bit(XMIT_WAITING, &(info->tx_state));
-+ dtl1_write_wakeup(info);
-+ }
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int dtl1_hci_open(struct hci_dev *hdev)
-+{
-+ set_bit(HCI_RUNNING, &(hdev->flags));
-+
-+ return 0;
-+}
-+
-+
-+static int dtl1_hci_flush(struct hci_dev *hdev)
-+{
-+ dtl1_info_t *info = (dtl1_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int dtl1_hci_close(struct hci_dev *hdev)
-+{
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ dtl1_hci_flush(hdev);
-+
-+ return 0;
-+}
-+
-+
-+static int dtl1_hci_send_frame(struct sk_buff *skb)
-+{
-+ dtl1_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+ struct sk_buff *s;
-+ nsh_t nsh;
-+
-+ if (!hdev) {
-+ printk(KERN_WARNING "dtl1_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (dtl1_info_t *)(hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ nsh.type = 0x81;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ nsh.type = 0x82;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ nsh.type = 0x83;
-+ break;
-+ };
-+
-+ nsh.zero = 0;
-+ nsh.len = skb->len;
-+
-+ s = bluez_skb_alloc(NSHL + skb->len + 1, GFP_ATOMIC);
-+ skb_reserve(s, NSHL);
-+ memcpy(skb_put(s, skb->len), skb->data, skb->len);
-+ if (skb->len & 0x0001)
-+ *skb_put(s, 1) = 0; /* PAD */
-+
-+ /* Prepend skb with Nokia frame header and queue */
-+ memcpy(skb_push(s, NSHL), &nsh, NSHL);
-+ skb_queue_tail(&(info->txq), s);
-+
-+ dtl1_write_wakeup(info);
-+
-+ kfree_skb(skb);
-+
-+ return 0;
-+}
-+
-+
-+static void dtl1_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+int dtl1_open(dtl1_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_NSH;
-+ info->rx_count = NSHL;
-+ info->rx_skb = NULL;
-+
-+ set_bit(XMIT_WAITING, &(info->tx_state));
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Reset UART */
-+ outb(0, iobase + UART_MCR);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ /* Initialize UART */
-+ outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
-+ outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
-+
-+ info->ri_latch = inb(info->link.io.BasePort1 + UART_MSR) & UART_MSR_RI;
-+
-+ /* Turn on interrupts */
-+ outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ * 2);
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = dtl1_hci_open;
-+ hdev->close = dtl1_hci_close;
-+ hdev->flush = dtl1_hci_flush;
-+ hdev->send = dtl1_hci_send_frame;
-+ hdev->destruct = dtl1_hci_destruct;
-+ hdev->ioctl = dtl1_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_WARNING "dtl1_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int dtl1_close(dtl1_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ if (info->link.state & DEV_CONFIG_PENDING)
-+ return -ENODEV;
-+
-+ dtl1_hci_close(hdev);
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Reset UART */
-+ outb(0, iobase + UART_MCR);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_WARNING "dtl1_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+dev_link_t *dtl1_attach(void)
-+{
-+ dtl1_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &dtl1_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = dtl1_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.Vcc = 50;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &dtl1_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ dtl1_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+void dtl1_detach(dev_link_t *link)
-+{
-+ dtl1_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+ if (link->state & DEV_CONFIG)
-+ dtl1_release((u_long)link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+void dtl1_config(dev_link_t *link)
-+{
-+ client_handle_t handle = link->handle;
-+ dtl1_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
-+ int i, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-+
-+ /* Look for a generic full-sized window */
-+ link->io.NumPorts1 = 8;
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
-+ link->conf.ConfigIndex = cf->index;
-+ link->io.BasePort1 = cf->io.win[0].base;
-+ link->io.NumPorts1 = cf->io.win[0].len; /*yo */
-+ link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ break;
-+ }
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (dtl1_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ dtl1_release((u_long)link);
-+}
-+
-+
-+void dtl1_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *)arg;
-+ dtl1_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ dtl1_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+int dtl1_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ dtl1_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ dtl1_close(info);
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ dtl1_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG)
-+ CardServices(ReleaseConfiguration, link->handle);
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (DEV_OK(link))
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_dtl1_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "dtl1_cs: Card Services release does not match!\n");
-+ return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &dtl1_attach, &dtl1_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_dtl1_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ dtl1_detach(dev_list);
-+}
-+
-+
-+module_init(init_dtl1_cs);
-+module_exit(exit_dtl1_cs);
-+
-+EXPORT_NO_SYMBOLS;
-diff -urN linux-2.4.18/drivers/bluetooth/hci_bcsp.c linux-2.4.18-mh15/drivers/bluetooth/hci_bcsp.c
---- linux-2.4.18/drivers/bluetooth/hci_bcsp.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_bcsp.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,710 @@
-+/*
-+ BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
-+ Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com>
-+
-+ Based on
-+ hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com>
-+ ABCSP by Carl Orsborn <cjo@csr.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#define VERSION "0.1"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/types.h>
-+#include <linux/fcntl.h>
-+#include <linux/interrupt.h>
-+#include <linux/ptrace.h>
-+#include <linux/poll.h>
-+
-+#include <linux/slab.h>
-+#include <linux/tty.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/signal.h>
-+#include <linux/ioctl.h>
-+#include <linux/skbuff.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include "hci_uart.h"
-+#include "hci_bcsp.h"
-+
-+#ifndef HCI_UART_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#undef BT_DMP
-+#define BT_DMP( A... )
-+#endif
-+
-+/* ---- BCSP CRC calculation ---- */
-+
-+/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
-+initial value 0xffff, bits shifted in reverse order. */
-+
-+static const u16 crc_table[] = {
-+ 0x0000, 0x1081, 0x2102, 0x3183,
-+ 0x4204, 0x5285, 0x6306, 0x7387,
-+ 0x8408, 0x9489, 0xa50a, 0xb58b,
-+ 0xc60c, 0xd68d, 0xe70e, 0xf78f
-+};
-+
-+/* Initialise the crc calculator */
-+#define BCSP_CRC_INIT(x) x = 0xffff
-+
-+/*
-+ Update crc with next data byte
-+
-+ Implementation note
-+ The data byte is treated as two nibbles. The crc is generated
-+ in reverse, i.e., bits are fed into the register from the top.
-+*/
-+static void bcsp_crc_update(u16 *crc, u8 d)
-+{
-+ u16 reg = *crc;
-+
-+ reg = (reg >> 4) ^ crc_table[(reg ^ d) & 0x000f];
-+ reg = (reg >> 4) ^ crc_table[(reg ^ (d >> 4)) & 0x000f];
-+
-+ *crc = reg;
-+}
-+
-+/*
-+ Get reverse of generated crc
-+
-+ Implementation note
-+ The crc generator (bcsp_crc_init() and bcsp_crc_update())
-+ creates a reversed crc, so it needs to be swapped back before
-+ being passed on.
-+*/
-+static u16 bcsp_crc_reverse(u16 crc)
-+{
-+ u16 b, rev;
-+
-+ for (b = 0, rev = 0; b < 16; b++) {
-+ rev = rev << 1;
-+ rev |= (crc & 1);
-+ crc = crc >> 1;
-+ }
-+ return (rev);
-+}
-+
-+/* ---- BCSP core ---- */
-+
-+static void bcsp_slip_msgdelim(struct sk_buff *skb)
-+{
-+ const char pkt_delim = 0xc0;
-+ memcpy(skb_put(skb, 1), &pkt_delim, 1);
-+}
-+
-+static void bcsp_slip_one_byte(struct sk_buff *skb, u8 c)
-+{
-+ const char esc_c0[2] = { 0xdb, 0xdc };
-+ const char esc_db[2] = { 0xdb, 0xdd };
-+
-+ switch (c) {
-+ case 0xc0:
-+ memcpy(skb_put(skb, 2), &esc_c0, 2);
-+ break;
-+ case 0xdb:
-+ memcpy(skb_put(skb, 2), &esc_db, 2);
-+ break;
-+ default:
-+ memcpy(skb_put(skb, 1), &c, 1);
-+ }
-+}
-+
-+static int bcsp_enqueue(struct hci_uart *hu, struct sk_buff *skb)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+
-+ if (skb->len > 0xFFF) {
-+ BT_ERR("Packet too long");
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+
-+ switch (skb->pkt_type) {
-+ case HCI_ACLDATA_PKT:
-+ case HCI_COMMAND_PKT:
-+ skb_queue_tail(&bcsp->rel, skb);
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ skb_queue_tail(&bcsp->unrel, skb);
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown packet type");
-+ kfree_skb(skb);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
-+ int len, int pkt_type)
-+{
-+ struct sk_buff *nskb;
-+ u8 hdr[4], chan;
-+ int rel, i;
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
-+#endif
-+
-+ switch (pkt_type) {
-+ case HCI_ACLDATA_PKT:
-+ chan = 6; /* BCSP ACL channel */
-+ rel = 1; /* reliable channel */
-+ break;
-+ case HCI_COMMAND_PKT:
-+ chan = 5; /* BCSP cmd/evt channel */
-+ rel = 1; /* reliable channel */
-+ break;
-+ case HCI_SCODATA_PKT:
-+ chan = 7; /* BCSP SCO channel */
-+ rel = 0; /* unreliable channel */
-+ break;
-+ case BCSP_LE_PKT:
-+ chan = 1; /* BCSP LE channel */
-+ rel = 0; /* unreliable channel */
-+ break;
-+ case BCSP_ACK_PKT:
-+ chan = 0; /* BCSP internal channel */
-+ rel = 0; /* unreliable channel */
-+ break;
-+ default:
-+ BT_ERR("Unknown packet type");
-+ return NULL;
-+ }
-+
-+ /* Max len of packet: (original len +4(bcsp hdr) +2(crc))*2
-+ (because bytes 0xc0 and 0xdb are escaped, worst case is
-+ when the packet is all made of 0xc0 and 0xdb :) )
-+ + 2 (0xc0 delimiters at start and end). */
-+
-+ nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC);
-+ if (!nskb)
-+ return NULL;
-+
-+ nskb->pkt_type = pkt_type;
-+
-+ bcsp_slip_msgdelim(nskb);
-+
-+ hdr[0] = bcsp->rxseq_txack << 3;
-+ bcsp->txack_req = 0;
-+ BT_DBG("We request packet no %u to card", bcsp->rxseq_txack);
-+
-+ if (rel) {
-+ hdr[0] |= 0x80 + bcsp->msgq_txseq;
-+ BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
-+ bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07;
-+ }
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ hdr[0] |= 0x40;
-+#endif
-+
-+ hdr[1] = (len << 4) & 0xFF;
-+ hdr[1] |= chan;
-+ hdr[2] = len >> 4;
-+ hdr[3] = ~(hdr[0] + hdr[1] + hdr[2]);
-+
-+ /* Put BCSP header */
-+ for (i = 0; i < 4; i++) {
-+ bcsp_slip_one_byte(nskb, hdr[i]);
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
-+#endif
-+ }
-+
-+ /* Put payload */
-+ for (i = 0; i < len; i++) {
-+ bcsp_slip_one_byte(nskb, data[i]);
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
-+#endif
-+ }
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ /* Put CRC */
-+ bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
-+ bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
-+ bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
-+#endif
-+
-+ bcsp_slip_msgdelim(nskb);
-+ return nskb;
-+}
-+
-+/* This is a rewrite of pkt_avail in ABCSP */
-+static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
-+ unsigned long flags;
-+ struct sk_buff *skb;
-+
-+ /* First of all, check for unreliable messages in the queue,
-+ since they have priority */
-+
-+ if ((skb = skb_dequeue(&bcsp->unrel)) != NULL) {
-+ struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
-+ if (nskb) {
-+ kfree_skb(skb);
-+ return nskb;
-+ } else {
-+ skb_queue_head(&bcsp->unrel, skb);
-+ BT_ERR("Could not dequeue pkt because alloc_skb failed");
-+ }
-+ }
-+
-+ /* Now, try to send a reliable pkt. We can only send a
-+ reliable packet if the number of packets sent but not yet ack'ed
-+ is < than the winsize */
-+
-+ spin_lock_irqsave(&bcsp->unack.lock, flags);
-+
-+ if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) {
-+ struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
-+ if (nskb) {
-+ __skb_queue_tail(&bcsp->unack, skb);
-+ mod_timer(&bcsp->tbcsp, jiffies + HZ / 4);
-+ spin_unlock_irqrestore(&bcsp->unack.lock, flags);
-+ return nskb;
-+ } else {
-+ skb_queue_head(&bcsp->rel, skb);
-+ BT_ERR("Could not dequeue pkt because alloc_skb failed");
-+ }
-+ }
-+
-+ spin_unlock_irqrestore(&bcsp->unack.lock, flags);
-+
-+
-+ /* We could not send a reliable packet, either because there are
-+ none or because there are too many unack'ed pkts. Did we receive
-+ any packets we have not acknowledged yet ? */
-+
-+ if (bcsp->txack_req) {
-+ /* if so, craft an empty ACK pkt and send it on BCSP unreliable
-+ channel 0 */
-+ struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, NULL, 0, BCSP_ACK_PKT);
-+ return nskb;
-+ }
-+
-+ /* We have nothing to send */
-+ return NULL;
-+}
-+
-+static int bcsp_flush(struct hci_uart *hu)
-+{
-+ BT_DBG("hu %p", hu);
-+ return 0;
-+}
-+
-+/* Remove ack'ed packets */
-+static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
-+{
-+ unsigned long flags;
-+ struct sk_buff *skb;
-+ int i, pkts_to_be_removed;
-+ u8 seqno;
-+
-+ spin_lock_irqsave(&bcsp->unack.lock, flags);
-+
-+ pkts_to_be_removed = bcsp->unack.qlen;
-+ seqno = bcsp->msgq_txseq;
-+
-+ while (pkts_to_be_removed) {
-+ if (bcsp->rxack == seqno)
-+ break;
-+ pkts_to_be_removed--;
-+ seqno = (seqno - 1) & 0x07;
-+ }
-+
-+ if (bcsp->rxack != seqno)
-+ BT_ERR("Peer acked invalid packet");
-+
-+ BT_DBG("Removing %u pkts out of %u, up to seqno %u",
-+ pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07);
-+
-+ for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed
-+ && skb != (struct sk_buff *) &bcsp->unack; i++) {
-+ struct sk_buff *nskb;
-+
-+ nskb = skb->next;
-+ __skb_unlink(skb, &bcsp->unack);
-+ kfree_skb(skb);
-+ skb = nskb;
-+ }
-+ if (bcsp->unack.qlen == 0)
-+ del_timer(&bcsp->tbcsp);
-+ spin_unlock_irqrestore(&bcsp->unack.lock, flags);
-+
-+ if (i != pkts_to_be_removed)
-+ BT_ERR("Removed only %u out of %u pkts", i, pkts_to_be_removed);
-+}
-+
-+/* Handle BCSP link-establishment packets. When we
-+ detect a "sync" packet, symptom that the BT module has reset,
-+ we do nothing :) (yet) */
-+static void bcsp_handle_le_pkt(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+ u8 conf_pkt[4] = { 0xad, 0xef, 0xac, 0xed };
-+ u8 conf_rsp_pkt[4] = { 0xde, 0xad, 0xd0, 0xd0 };
-+ u8 sync_pkt[4] = { 0xda, 0xdc, 0xed, 0xed };
-+
-+ /* spot "conf" pkts and reply with a "conf rsp" pkt */
-+ if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
-+ !memcmp(&bcsp->rx_skb->data[4], conf_pkt, 4)) {
-+ struct sk_buff *nskb = alloc_skb(4, GFP_ATOMIC);
-+
-+ BT_DBG("Found a LE conf pkt");
-+ if (!nskb)
-+ return;
-+ memcpy(skb_put(nskb, 4), conf_rsp_pkt, 4);
-+ nskb->pkt_type = BCSP_LE_PKT;
-+
-+ skb_queue_head(&bcsp->unrel, nskb);
-+ hci_uart_tx_wakeup(hu);
-+ }
-+ /* Spot "sync" pkts. If we find one...disaster! */
-+ else if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
-+ !memcmp(&bcsp->rx_skb->data[4], sync_pkt, 4)) {
-+ BT_ERR("Found a LE sync pkt, card has reset");
-+ }
-+}
-+
-+static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char byte)
-+{
-+ const u8 c0 = 0xc0, db = 0xdb;
-+
-+ switch (bcsp->rx_esc_state) {
-+ case BCSP_ESCSTATE_NOESC:
-+ switch (byte) {
-+ case 0xdb:
-+ bcsp->rx_esc_state = BCSP_ESCSTATE_ESC;
-+ break;
-+ default:
-+ memcpy(skb_put(bcsp->rx_skb, 1), &byte, 1);
-+ if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
-+ bcsp->rx_state != BCSP_W4_CRC)
-+ bcsp_crc_update(&bcsp->message_crc, byte);
-+ bcsp->rx_count--;
-+ }
-+ break;
-+
-+ case BCSP_ESCSTATE_ESC:
-+ switch (byte) {
-+ case 0xdc:
-+ memcpy(skb_put(bcsp->rx_skb, 1), &c0, 1);
-+ if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
-+ bcsp->rx_state != BCSP_W4_CRC)
-+ bcsp_crc_update(&bcsp-> message_crc, 0xc0);
-+ bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
-+ bcsp->rx_count--;
-+ break;
-+
-+ case 0xdd:
-+ memcpy(skb_put(bcsp->rx_skb, 1), &db, 1);
-+ if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
-+ bcsp->rx_state != BCSP_W4_CRC)
-+ bcsp_crc_update(&bcsp-> message_crc, 0xdb);
-+ bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
-+ bcsp->rx_count--;
-+ break;
-+
-+ default:
-+ BT_ERR ("Invalid byte %02x after esc byte", byte);
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_skb = NULL;
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ }
-+ }
-+}
-+
-+static inline void bcsp_complete_rx_pkt(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+ int pass_up;
-+
-+ if (bcsp->rx_skb->data[0] & 0x80) { /* reliable pkt */
-+ BT_DBG("Received seqno %u from card", bcsp->rxseq_txack);
-+ bcsp->rxseq_txack++;
-+ bcsp->rxseq_txack %= 0x8;
-+ bcsp->txack_req = 1;
-+
-+ /* If needed, transmit an ack pkt */
-+ hci_uart_tx_wakeup(hu);
-+ }
-+
-+ bcsp->rxack = (bcsp->rx_skb->data[0] >> 3) & 0x07;
-+ BT_DBG("Request for pkt %u from card", bcsp->rxack);
-+
-+ bcsp_pkt_cull(bcsp);
-+ if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
-+ bcsp->rx_skb->data[0] & 0x80) {
-+ bcsp->rx_skb->pkt_type = HCI_ACLDATA_PKT;
-+ pass_up = 1;
-+ } else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
-+ bcsp->rx_skb->data[0] & 0x80) {
-+ bcsp->rx_skb->pkt_type = HCI_EVENT_PKT;
-+ pass_up = 1;
-+ } else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
-+ bcsp->rx_skb->pkt_type = HCI_SCODATA_PKT;
-+ pass_up = 1;
-+ } else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 &&
-+ !(bcsp->rx_skb->data[0] & 0x80)) {
-+ bcsp_handle_le_pkt(hu);
-+ pass_up = 0;
-+ } else
-+ pass_up = 0;
-+
-+ if (!pass_up) {
-+ if ((bcsp->rx_skb->data[1] & 0x0f) != 0 &&
-+ (bcsp->rx_skb->data[1] & 0x0f) != 1) {
-+ BT_ERR ("Packet for unknown channel (%u %s)",
-+ bcsp->rx_skb->data[1] & 0x0f,
-+ bcsp->rx_skb->data[0] & 0x80 ?
-+ "reliable" : "unreliable");
-+ }
-+ kfree_skb(bcsp->rx_skb);
-+ } else {
-+ /* Pull out BCSP hdr */
-+ skb_pull(bcsp->rx_skb, 4);
-+
-+ hci_recv_frame(bcsp->rx_skb);
-+ }
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_skb = NULL;
-+}
-+
-+/* Recv data */
-+static int bcsp_recv(struct hci_uart *hu, void *data, int count)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+ register unsigned char *ptr;
-+
-+ BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
-+ hu, count, bcsp->rx_state, bcsp->rx_count);
-+
-+ ptr = data;
-+ while (count) {
-+ if (bcsp->rx_count) {
-+ if (*ptr == 0xc0) {
-+ BT_ERR("Short BCSP packet");
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_state = BCSP_W4_PKT_START;
-+ bcsp->rx_count = 0;
-+ } else
-+ bcsp_unslip_one_byte(bcsp, *ptr);
-+
-+ ptr++; count--;
-+ continue;
-+ }
-+
-+ switch (bcsp->rx_state) {
-+ case BCSP_W4_BCSP_HDR:
-+ if ((0xff & (u8) ~ (bcsp->rx_skb->data[0] + bcsp->rx_skb->data[1] +
-+ bcsp->rx_skb->data[2])) != bcsp->rx_skb->data[3]) {
-+ BT_ERR("Error in BCSP hdr checksum");
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ continue;
-+ }
-+ if (bcsp->rx_skb->data[0] & 0x80 /* reliable pkt */
-+ && (bcsp->rx_skb->data[0] & 0x07) != bcsp->rxseq_txack) {
-+ BT_ERR ("Out-of-order packet arrived, got %u expected %u",
-+ bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);
-+
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ continue;
-+ }
-+ bcsp->rx_state = BCSP_W4_DATA;
-+ bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) +
-+ (bcsp->rx_skb->data[2] << 4); /* May be 0 */
-+ continue;
-+
-+ case BCSP_W4_DATA:
-+ if (bcsp->rx_skb->data[0] & 0x40) { /* pkt with crc */
-+ bcsp->rx_state = BCSP_W4_CRC;
-+ bcsp->rx_count = 2;
-+ } else
-+ bcsp_complete_rx_pkt(hu);
-+ continue;
-+
-+ case BCSP_W4_CRC:
-+ if (bcsp_crc_reverse(bcsp->message_crc) !=
-+ (bcsp->rx_skb->data[bcsp->rx_skb->len - 2] << 8) +
-+ bcsp->rx_skb->data[bcsp->rx_skb->len - 1]) {
-+
-+ BT_ERR ("Checksum failed: computed %04x received %04x",
-+ bcsp_crc_reverse(bcsp->message_crc),
-+ (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) +
-+ bcsp->rx_skb->data[bcsp->rx_skb->len - 1]);
-+
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ continue;
-+ }
-+ skb_trim(bcsp->rx_skb, bcsp->rx_skb->len - 2);
-+ bcsp_complete_rx_pkt(hu);
-+ continue;
-+
-+ case BCSP_W4_PKT_DELIMITER:
-+ switch (*ptr) {
-+ case 0xc0:
-+ bcsp->rx_state = BCSP_W4_PKT_START;
-+ break;
-+ default:
-+ /*BT_ERR("Ignoring byte %02x", *ptr);*/
-+ break;
-+ }
-+ ptr++; count--;
-+ break;
-+
-+ case BCSP_W4_PKT_START:
-+ switch (*ptr) {
-+ case 0xc0:
-+ ptr++; count--;
-+ break;
-+
-+ default:
-+ bcsp->rx_state = BCSP_W4_BCSP_HDR;
-+ bcsp->rx_count = 4;
-+ bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
-+ BCSP_CRC_INIT(bcsp->message_crc);
-+
-+ /* Do not increment ptr or decrement count
-+ * Allocate packet. Max len of a BCSP pkt=
-+ * 0xFFF (payload) +4 (header) +2 (crc) */
-+
-+ bcsp->rx_skb = bluez_skb_alloc(0x1005, GFP_ATOMIC);
-+ if (!bcsp->rx_skb) {
-+ BT_ERR("Can't allocate mem for new packet");
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ return 0;
-+ }
-+ bcsp->rx_skb->dev = (void *) &hu->hdev;
-+ break;
-+ }
-+ break;
-+ }
-+ }
-+ return count;
-+}
-+
-+ /* Arrange to retransmit all messages in the relq. */
-+static void bcsp_timed_event(unsigned long arg)
-+{
-+ struct hci_uart *hu = (struct hci_uart *) arg;
-+ struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
-+ struct sk_buff *skb;
-+ unsigned long flags;
-+
-+ BT_DBG("hu %p retransmitting %u pkts", hu, bcsp->unack.qlen);
-+
-+ spin_lock_irqsave(&bcsp->unack.lock, flags);
-+
-+ while ((skb = __skb_dequeue_tail(&bcsp->unack)) != NULL) {
-+ bcsp->msgq_txseq = (bcsp->msgq_txseq - 1) & 0x07;
-+ skb_queue_head(&bcsp->rel, skb);
-+ }
-+
-+ spin_unlock_irqrestore(&bcsp->unack.lock, flags);
-+
-+ hci_uart_tx_wakeup(hu);
-+}
-+
-+static int bcsp_open(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp;
-+
-+ BT_DBG("hu %p", hu);
-+
-+ bcsp = kmalloc(sizeof(*bcsp), GFP_ATOMIC);
-+ if (!bcsp)
-+ return -ENOMEM;
-+ memset(bcsp, 0, sizeof(*bcsp));
-+
-+ hu->priv = bcsp;
-+ skb_queue_head_init(&bcsp->unack);
-+ skb_queue_head_init(&bcsp->rel);
-+ skb_queue_head_init(&bcsp->unrel);
-+
-+ init_timer(&bcsp->tbcsp);
-+ bcsp->tbcsp.function = bcsp_timed_event;
-+ bcsp->tbcsp.data = (u_long) hu;
-+
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+
-+ return 0;
-+}
-+
-+static int bcsp_close(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+ hu->priv = NULL;
-+
-+ BT_DBG("hu %p", hu);
-+
-+ skb_queue_purge(&bcsp->unack);
-+ skb_queue_purge(&bcsp->rel);
-+ skb_queue_purge(&bcsp->unrel);
-+ del_timer(&bcsp->tbcsp);
-+
-+ kfree(bcsp);
-+ return 0;
-+}
-+
-+static struct hci_uart_proto bcsp = {
-+ id: HCI_UART_BCSP,
-+ open: bcsp_open,
-+ close: bcsp_close,
-+ enqueue: bcsp_enqueue,
-+ dequeue: bcsp_dequeue,
-+ recv: bcsp_recv,
-+ flush: bcsp_flush
-+};
-+
-+int bcsp_init(void)
-+{
-+ return hci_uart_register_proto(&bcsp);
-+}
-+
-+int bcsp_deinit(void)
-+{
-+ return hci_uart_unregister_proto(&bcsp);
-+}
-diff -urN linux-2.4.18/drivers/bluetooth/hci_bcsp.h linux-2.4.18-mh15/drivers/bluetooth/hci_bcsp.h
---- linux-2.4.18/drivers/bluetooth/hci_bcsp.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_bcsp.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,70 @@
-+/*
-+ BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
-+ Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com>
-+
-+ Based on
-+ hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com>
-+ ABCSP by Carl Orsborn <cjo@csr.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef __HCI_BCSP_H__
-+#define __HCI_BCSP_H__
-+
-+#define BCSP_TXWINSIZE 4
-+
-+#define BCSP_ACK_PKT 0x05
-+#define BCSP_LE_PKT 0x06
-+
-+struct bcsp_struct {
-+ struct sk_buff_head unack; /* Unack'ed packets queue */
-+ struct sk_buff_head rel; /* Reliable packets queue */
-+ struct sk_buff_head unrel; /* Unreliable packets queue */
-+
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+ u8 rxseq_txack; /* rxseq == txack. */
-+ u8 rxack; /* Last packet sent by us that the peer ack'ed */
-+ struct timer_list tbcsp;
-+
-+ enum {
-+ BCSP_W4_PKT_DELIMITER,
-+ BCSP_W4_PKT_START,
-+ BCSP_W4_BCSP_HDR,
-+ BCSP_W4_DATA,
-+ BCSP_W4_CRC
-+ } rx_state;
-+
-+ enum {
-+ BCSP_ESCSTATE_NOESC,
-+ BCSP_ESCSTATE_ESC
-+ } rx_esc_state;
-+
-+ u16 message_crc;
-+ u8 txack_req; /* Do we need to send ack's to the peer? */
-+
-+ /* Reliable packet sequence number - used to assign seq to each rel pkt. */
-+ u8 msgq_txseq;
-+};
-+
-+#endif /* __HCI_BCSP_H__ */
-diff -urN linux-2.4.18/drivers/bluetooth/hci_h4.c linux-2.4.18-mh15/drivers/bluetooth/hci_h4.c
---- linux-2.4.18/drivers/bluetooth/hci_h4.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_h4.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,277 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * BlueZ HCI UART(H4) protocol.
-+ *
-+ * $Id$
-+ */
-+#define VERSION "1.2"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/types.h>
-+#include <linux/fcntl.h>
-+#include <linux/interrupt.h>
-+#include <linux/ptrace.h>
-+#include <linux/poll.h>
-+
-+#include <linux/slab.h>
-+#include <linux/tty.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/signal.h>
-+#include <linux/ioctl.h>
-+#include <linux/skbuff.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include "hci_uart.h"
-+#include "hci_h4.h"
-+
-+#ifndef HCI_UART_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#undef BT_DMP
-+#define BT_DMP( A... )
-+#endif
-+
-+/* Initialize protocol */
-+static int h4_open(struct hci_uart *hu)
-+{
-+ struct h4_struct *h4;
-+
-+ BT_DBG("hu %p", hu);
-+
-+ h4 = kmalloc(sizeof(*h4), GFP_ATOMIC);
-+ if (!h4)
-+ return -ENOMEM;
-+ memset(h4, 0, sizeof(*h4));
-+
-+ skb_queue_head_init(&h4->txq);
-+
-+ hu->priv = h4;
-+ return 0;
-+}
-+
-+/* Flush protocol data */
-+static int h4_flush(struct hci_uart *hu)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+
-+ BT_DBG("hu %p", hu);
-+ skb_queue_purge(&h4->txq);
-+ return 0;
-+}
-+
-+/* Close protocol */
-+static int h4_close(struct hci_uart *hu)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+ hu->priv = NULL;
-+
-+ BT_DBG("hu %p", hu);
-+
-+ skb_queue_purge(&h4->txq);
-+ if (h4->rx_skb)
-+ kfree_skb(h4->rx_skb);
-+
-+ hu->priv = NULL;
-+ kfree(h4);
-+ return 0;
-+}
-+
-+/* Enqueue frame for transmittion (padding, crc, etc) */
-+static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+
-+ BT_DBG("hu %p skb %p", hu, skb);
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
-+ skb_queue_tail(&h4->txq, skb);
-+ return 0;
-+}
-+
-+static inline int h4_check_data_len(struct h4_struct *h4, int len)
-+{
-+ register int room = skb_tailroom(h4->rx_skb);
-+
-+ BT_DBG("len %d room %d", len, room);
-+ if (!len) {
-+ BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
-+ hci_recv_frame(h4->rx_skb);
-+ } else if (len > room) {
-+ BT_ERR("Data length is too large");
-+ kfree_skb(h4->rx_skb);
-+ } else {
-+ h4->rx_state = H4_W4_DATA;
-+ h4->rx_count = len;
-+ return len;
-+ }
-+
-+ h4->rx_state = H4_W4_PACKET_TYPE;
-+ h4->rx_skb = NULL;
-+ h4->rx_count = 0;
-+ return 0;
-+}
-+
-+/* Recv data */
-+static int h4_recv(struct hci_uart *hu, void *data, int count)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+ register char *ptr;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+ register int len, type, dlen;
-+
-+ BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
-+ hu, count, h4->rx_state, h4->rx_count);
-+
-+ ptr = data;
-+ while (count) {
-+ if (h4->rx_count) {
-+ len = MIN(h4->rx_count, count);
-+ memcpy(skb_put(h4->rx_skb, len), ptr, len);
-+ h4->rx_count -= len; count -= len; ptr += len;
-+
-+ if (h4->rx_count)
-+ continue;
-+
-+ switch (h4->rx_state) {
-+ case H4_W4_DATA:
-+ BT_DBG("Complete data");
-+
-+ BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
-+
-+ hci_recv_frame(h4->rx_skb);
-+
-+ h4->rx_state = H4_W4_PACKET_TYPE;
-+ h4->rx_skb = NULL;
-+ continue;
-+
-+ case H4_W4_EVENT_HDR:
-+ eh = (hci_event_hdr *) h4->rx_skb->data;
-+
-+ BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
-+
-+ h4_check_data_len(h4, eh->plen);
-+ continue;
-+
-+ case H4_W4_ACL_HDR:
-+ ah = (hci_acl_hdr *) h4->rx_skb->data;
-+ dlen = __le16_to_cpu(ah->dlen);
-+
-+ BT_DBG("ACL header: dlen %d", dlen);
-+
-+ h4_check_data_len(h4, dlen);
-+ continue;
-+
-+ case H4_W4_SCO_HDR:
-+ sh = (hci_sco_hdr *) h4->rx_skb->data;
-+
-+ BT_DBG("SCO header: dlen %d", sh->dlen);
-+
-+ h4_check_data_len(h4, sh->dlen);
-+ continue;
-+ }
-+ }
-+
-+ /* H4_W4_PACKET_TYPE */
-+ switch (*ptr) {
-+ case HCI_EVENT_PKT:
-+ BT_DBG("Event packet");
-+ h4->rx_state = H4_W4_EVENT_HDR;
-+ h4->rx_count = HCI_EVENT_HDR_SIZE;
-+ type = HCI_EVENT_PKT;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ BT_DBG("ACL packet");
-+ h4->rx_state = H4_W4_ACL_HDR;
-+ h4->rx_count = HCI_ACL_HDR_SIZE;
-+ type = HCI_ACLDATA_PKT;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ BT_DBG("SCO packet");
-+ h4->rx_state = H4_W4_SCO_HDR;
-+ h4->rx_count = HCI_SCO_HDR_SIZE;
-+ type = HCI_SCODATA_PKT;
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
-+ hu->hdev.stat.err_rx++;
-+ ptr++; count--;
-+ continue;
-+ };
-+ ptr++; count--;
-+
-+ /* Allocate packet */
-+ h4->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
-+ if (!h4->rx_skb) {
-+ BT_ERR("Can't allocate mem for new packet");
-+ h4->rx_state = H4_W4_PACKET_TYPE;
-+ h4->rx_count = 0;
-+ return 0;
-+ }
-+ h4->rx_skb->dev = (void *) &hu->hdev;
-+ h4->rx_skb->pkt_type = type;
-+ }
-+ return count;
-+}
-+
-+static struct sk_buff *h4_dequeue(struct hci_uart *hu)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+ return skb_dequeue(&h4->txq);
-+}
-+
-+static struct hci_uart_proto h4p = {
-+ id: HCI_UART_H4,
-+ open: h4_open,
-+ close: h4_close,
-+ recv: h4_recv,
-+ enqueue: h4_enqueue,
-+ dequeue: h4_dequeue,
-+ flush: h4_flush,
-+};
-+
-+int h4_init(void)
-+{
-+ return hci_uart_register_proto(&h4p);
-+}
-+
-+int h4_deinit(void)
-+{
-+ return hci_uart_unregister_proto(&h4p);
-+}
-diff -urN linux-2.4.18/drivers/bluetooth/hci_h4.h linux-2.4.18-mh15/drivers/bluetooth/hci_h4.h
---- linux-2.4.18/drivers/bluetooth/hci_h4.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_h4.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,44 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifdef __KERNEL__
-+struct h4_struct {
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+ struct sk_buff_head txq;
-+};
-+
-+/* H4 receiver States */
-+#define H4_W4_PACKET_TYPE 0
-+#define H4_W4_EVENT_HDR 1
-+#define H4_W4_ACL_HDR 2
-+#define H4_W4_SCO_HDR 3
-+#define H4_W4_DATA 4
-+
-+#endif /* __KERNEL__ */
-diff -urN linux-2.4.18/drivers/bluetooth/hci_ldisc.c linux-2.4.18-mh15/drivers/bluetooth/hci_ldisc.c
---- linux-2.4.18/drivers/bluetooth/hci_ldisc.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_ldisc.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,579 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * BlueZ HCI UART driver.
-+ *
-+ * $Id$
-+ */
-+#define VERSION "2.1"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/types.h>
-+#include <linux/fcntl.h>
-+#include <linux/interrupt.h>
-+#include <linux/ptrace.h>
-+#include <linux/poll.h>
-+
-+#include <linux/slab.h>
-+#include <linux/tty.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/signal.h>
-+#include <linux/ioctl.h>
-+#include <linux/skbuff.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include "hci_uart.h"
-+
-+#ifndef HCI_UART_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#undef BT_DMP
-+#define BT_DMP( A... )
-+#endif
-+
-+static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
-+
-+int hci_uart_register_proto(struct hci_uart_proto *p)
-+{
-+ if (p->id >= HCI_UART_MAX_PROTO)
-+ return -EINVAL;
-+
-+ if (hup[p->id])
-+ return -EEXIST;
-+
-+ hup[p->id] = p;
-+ return 0;
-+}
-+
-+int hci_uart_unregister_proto(struct hci_uart_proto *p)
-+{
-+ if (p->id >= HCI_UART_MAX_PROTO)
-+ return -EINVAL;
-+
-+ if (!hup[p->id])
-+ return -EINVAL;
-+
-+ hup[p->id] = NULL;
-+ return 0;
-+}
-+
-+static struct hci_uart_proto *hci_uart_get_proto(unsigned int id)
-+{
-+ if (id >= HCI_UART_MAX_PROTO)
-+ return NULL;
-+ return hup[id];
-+}
-+
-+static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type)
-+{
-+ struct hci_dev *hdev = &hu->hdev;
-+
-+ /* Update HCI stat counters */
-+ switch (pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ }
-+}
-+
-+static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu)
-+{
-+ struct sk_buff *skb = hu->tx_skb;
-+ if (!skb)
-+ skb = hu->proto->dequeue(hu);
-+ else
-+ hu->tx_skb = NULL;
-+ return skb;
-+}
-+
-+int hci_uart_tx_wakeup(struct hci_uart *hu)
-+{
-+ struct tty_struct *tty = hu->tty;
-+ struct hci_dev *hdev = &hu->hdev;
-+ struct sk_buff *skb;
-+
-+ if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
-+ set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
-+ return 0;
-+ }
-+
-+ BT_DBG("");
-+
-+restart:
-+ clear_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
-+
-+ while ((skb = hci_uart_dequeue(hu))) {
-+ int len;
-+
-+ set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-+ len = tty->driver.write(tty, 0, skb->data, skb->len);
-+ hdev->stat.byte_tx += len;
-+
-+ skb_pull(skb, len);
-+ if (skb->len) {
-+ hu->tx_skb = skb;
-+ break;
-+ }
-+
-+ hci_uart_tx_complete(hu, skb->pkt_type);
-+ kfree_skb(skb);
-+ }
-+
-+ if (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state))
-+ goto restart;
-+
-+ clear_bit(HCI_UART_SENDING, &hu->tx_state);
-+ return 0;
-+}
-+
-+/* ------- Interface to HCI layer ------ */
-+/* Initialize device */
-+static int hci_uart_open(struct hci_dev *hdev)
-+{
-+ BT_DBG("%s %p", hdev->name, hdev);
-+
-+ /* Nothing to do for UART driver */
-+
-+ set_bit(HCI_RUNNING, &hdev->flags);
-+ return 0;
-+}
-+
-+/* Reset device */
-+static int hci_uart_flush(struct hci_dev *hdev)
-+{
-+ struct hci_uart *hu = (struct hci_uart *) hdev->driver_data;
-+ struct tty_struct *tty = hu->tty;
-+
-+ BT_DBG("hdev %p tty %p", hdev, tty);
-+
-+ if (hu->tx_skb) {
-+ kfree_skb(hu->tx_skb); hu->tx_skb = NULL;
-+ }
-+
-+ /* Flush any pending characters in the driver and discipline. */
-+ if (tty->ldisc.flush_buffer)
-+ tty->ldisc.flush_buffer(tty);
-+
-+ if (tty->driver.flush_buffer)
-+ tty->driver.flush_buffer(tty);
-+
-+ if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
-+ hu->proto->flush(hu);
-+
-+ return 0;
-+}
-+
-+/* Close device */
-+static int hci_uart_close(struct hci_dev *hdev)
-+{
-+ BT_DBG("hdev %p", hdev);
-+
-+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-+
-+ hci_uart_flush(hdev);
-+ return 0;
-+}
-+
-+/* Send frames from HCI layer */
-+static int hci_uart_send_frame(struct sk_buff *skb)
-+{
-+ struct hci_dev* hdev = (struct hci_dev *) skb->dev;
-+ struct tty_struct *tty;
-+ struct hci_uart *hu;
-+
-+ if (!hdev) {
-+ BT_ERR("Frame for uknown device (hdev=NULL)");
-+ return -ENODEV;
-+ }
-+
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return -EBUSY;
-+
-+ hu = (struct hci_uart *) hdev->driver_data;
-+ tty = hu->tty;
-+
-+ BT_DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
-+
-+ hu->proto->enqueue(hu, skb);
-+
-+ hci_uart_tx_wakeup(hu);
-+ return 0;
-+}
-+
-+static void hci_uart_destruct(struct hci_dev *hdev)
-+{
-+ struct hci_uart *hu;
-+
-+ if (!hdev) return;
-+
-+ BT_DBG("%s", hdev->name);
-+
-+ hu = (struct hci_uart *) hdev->driver_data;
-+ kfree(hu);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+/* ------ LDISC part ------ */
-+/* hci_uart_tty_open
-+ *
-+ * Called when line discipline changed to HCI_UART.
-+ *
-+ * Arguments:
-+ * tty pointer to tty info structure
-+ * Return Value:
-+ * 0 if success, otherwise error code
-+ */
-+static int hci_uart_tty_open(struct tty_struct *tty)
-+{
-+ struct hci_uart *hu = (void *) tty->disc_data;
-+
-+ BT_DBG("tty %p", tty);
-+
-+ if (hu)
-+ return -EEXIST;
-+
-+ if (!(hu = kmalloc(sizeof(struct hci_uart), GFP_KERNEL))) {
-+ BT_ERR("Can't allocate controll structure");
-+ return -ENFILE;
-+ }
-+ memset(hu, 0, sizeof(struct hci_uart));
-+
-+ tty->disc_data = hu;
-+ hu->tty = tty;
-+
-+ spin_lock_init(&hu->rx_lock);
-+
-+ /* Flush any pending characters in the driver and line discipline */
-+ if (tty->ldisc.flush_buffer)
-+ tty->ldisc.flush_buffer(tty);
-+
-+ if (tty->driver.flush_buffer)
-+ tty->driver.flush_buffer(tty);
-+
-+ MOD_INC_USE_COUNT;
-+ return 0;
-+}
-+
-+/* hci_uart_tty_close()
-+ *
-+ * Called when the line discipline is changed to something
-+ * else, the tty is closed, or the tty detects a hangup.
-+ */
-+static void hci_uart_tty_close(struct tty_struct *tty)
-+{
-+ struct hci_uart *hu = (void *)tty->disc_data;
-+
-+ BT_DBG("tty %p", tty);
-+
-+ /* Detach from the tty */
-+ tty->disc_data = NULL;
-+
-+ if (hu) {
-+ struct hci_dev *hdev = &hu->hdev;
-+ hci_uart_close(hdev);
-+
-+ if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
-+ hu->proto->close(hu);
-+ hci_unregister_dev(hdev);
-+ }
-+
-+ MOD_DEC_USE_COUNT;
-+ }
-+}
-+
-+/* hci_uart_tty_wakeup()
-+ *
-+ * Callback for transmit wakeup. Called when low level
-+ * device driver can accept more send data.
-+ *
-+ * Arguments: tty pointer to associated tty instance data
-+ * Return Value: None
-+ */
-+static void hci_uart_tty_wakeup(struct tty_struct *tty)
-+{
-+ struct hci_uart *hu = (void *)tty->disc_data;
-+
-+ BT_DBG("");
-+
-+ if (!hu)
-+ return;
-+
-+ clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-+
-+ if (tty != hu->tty)
-+ return;
-+
-+ if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
-+ hci_uart_tx_wakeup(hu);
-+}
-+
-+/* hci_uart_tty_room()
-+ *
-+ * Callback function from tty driver. Return the amount of
-+ * space left in the receiver's buffer to decide if remote
-+ * transmitter is to be throttled.
-+ *
-+ * Arguments: tty pointer to associated tty instance data
-+ * Return Value: number of bytes left in receive buffer
-+ */
-+static int hci_uart_tty_room (struct tty_struct *tty)
-+{
-+ return 65536;
-+}
-+
-+/* hci_uart_tty_receive()
-+ *
-+ * Called by tty low level driver when receive data is
-+ * available.
-+ *
-+ * Arguments: tty pointer to tty isntance data
-+ * data pointer to received data
-+ * flags pointer to flags for data
-+ * count count of received data in bytes
-+ *
-+ * Return Value: None
-+ */
-+static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char *flags, int count)
-+{
-+ struct hci_uart *hu = (void *)tty->disc_data;
-+
-+ if (!hu || tty != hu->tty)
-+ return;
-+
-+ if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
-+ return;
-+
-+ spin_lock(&hu->rx_lock);
-+ hu->proto->recv(hu, (void *) data, count);
-+ hu->hdev.stat.byte_rx += count;
-+ spin_unlock(&hu->rx_lock);
-+
-+ if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver.unthrottle)
-+ tty->driver.unthrottle(tty);
-+}
-+
-+static int hci_uart_register_dev(struct hci_uart *hu)
-+{
-+ struct hci_dev *hdev;
-+
-+ BT_DBG("");
-+
-+ /* Initialize and register HCI device */
-+ hdev = &hu->hdev;
-+
-+ hdev->type = HCI_UART;
-+ hdev->driver_data = hu;
-+
-+ hdev->open = hci_uart_open;
-+ hdev->close = hci_uart_close;
-+ hdev->flush = hci_uart_flush;
-+ hdev->send = hci_uart_send_frame;
-+ hdev->destruct = hci_uart_destruct;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ BT_ERR("Can't register HCI device %s", hdev->name);
-+ return -ENODEV;
-+ }
-+ MOD_INC_USE_COUNT;
-+ return 0;
-+}
-+
-+static int hci_uart_set_proto(struct hci_uart *hu, int id)
-+{
-+ struct hci_uart_proto *p;
-+ int err;
-+
-+ p = hci_uart_get_proto(id);
-+ if (!p)
-+ return -EPROTONOSUPPORT;
-+
-+ err = p->open(hu);
-+ if (err)
-+ return err;
-+
-+ hu->proto = p;
-+
-+ err = hci_uart_register_dev(hu);
-+ if (err) {
-+ p->close(hu);
-+ return err;
-+ }
-+ return 0;
-+}
-+
-+/* hci_uart_tty_ioctl()
-+ *
-+ * Process IOCTL system call for the tty device.
-+ *
-+ * Arguments:
-+ *
-+ * tty pointer to tty instance data
-+ * file pointer to open file object for device
-+ * cmd IOCTL command code
-+ * arg argument for IOCTL call (cmd dependent)
-+ *
-+ * Return Value: Command dependent
-+ */
-+static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ struct hci_uart *hu = (void *)tty->disc_data;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ /* Verify the status of the device */
-+ if (!hu)
-+ return -EBADF;
-+
-+ switch (cmd) {
-+ case HCIUARTSETPROTO:
-+ if (!test_and_set_bit(HCI_UART_PROTO_SET, &hu->flags)) {
-+ err = hci_uart_set_proto(hu, arg);
-+ if (err) {
-+ clear_bit(HCI_UART_PROTO_SET, &hu->flags);
-+ return err;
-+ }
-+ tty->low_latency = 1;
-+ } else
-+ return -EBUSY;
-+
-+ case HCIUARTGETPROTO:
-+ if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
-+ return hu->proto->id;
-+ return -EUNATCH;
-+
-+ default:
-+ err = n_tty_ioctl(tty, file, cmd, arg);
-+ break;
-+ };
-+
-+ return err;
-+}
-+
-+/*
-+ * We don't provide read/write/poll interface for user space.
-+ */
-+static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr)
-+{
-+ return 0;
-+}
-+static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
-+{
-+ return 0;
-+}
-+static unsigned int hci_uart_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
-+{
-+ return 0;
-+}
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_H4
-+int h4_init(void);
-+int h4_deinit(void);
-+#endif
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP
-+int bcsp_init(void);
-+int bcsp_deinit(void);
-+#endif
-+
-+int __init hci_uart_init(void)
-+{
-+ static struct tty_ldisc hci_uart_ldisc;
-+ int err;
-+
-+ BT_INFO("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-+ VERSION);
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+
-+ /* Register the tty discipline */
-+
-+ memset(&hci_uart_ldisc, 0, sizeof (hci_uart_ldisc));
-+ hci_uart_ldisc.magic = TTY_LDISC_MAGIC;
-+ hci_uart_ldisc.name = "n_hci";
-+ hci_uart_ldisc.open = hci_uart_tty_open;
-+ hci_uart_ldisc.close = hci_uart_tty_close;
-+ hci_uart_ldisc.read = hci_uart_tty_read;
-+ hci_uart_ldisc.write = hci_uart_tty_write;
-+ hci_uart_ldisc.ioctl = hci_uart_tty_ioctl;
-+ hci_uart_ldisc.poll = hci_uart_tty_poll;
-+ hci_uart_ldisc.receive_room= hci_uart_tty_room;
-+ hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
-+ hci_uart_ldisc.write_wakeup= hci_uart_tty_wakeup;
-+
-+ if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) {
-+ BT_ERR("Can't register HCI line discipline (%d)", err);
-+ return err;
-+ }
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_H4
-+ h4_init();
-+#endif
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP
-+ bcsp_init();
-+#endif
-+
-+ return 0;
-+}
-+
-+void hci_uart_cleanup(void)
-+{
-+ int err;
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_H4
-+ h4_deinit();
-+#endif
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP
-+ bcsp_deinit();
-+#endif
-+
-+ /* Release tty registration of line discipline */
-+ if ((err = tty_register_ldisc(N_HCI, NULL)))
-+ BT_ERR("Can't unregister HCI line discipline (%d)", err);
-+}
-+
-+module_init(hci_uart_init);
-+module_exit(hci_uart_cleanup);
-+
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
-+MODULE_DESCRIPTION("BlueZ HCI UART driver ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/drivers/bluetooth/hci_uart.c linux-2.4.18-mh15/drivers/bluetooth/hci_uart.c
---- linux-2.4.18/drivers/bluetooth/hci_uart.c 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_uart.c 1970-01-01 01:00:00.000000000 +0100
-@@ -1,580 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * BlueZ HCI UART driver.
-- *
-- * $Id$
-- */
--#define VERSION "1.0"
--
--#include <linux/config.h>
--#include <linux/module.h>
--
--#include <linux/version.h>
--#include <linux/config.h>
--#include <linux/kernel.h>
--#include <linux/init.h>
--#include <linux/sched.h>
--#include <linux/types.h>
--#include <linux/fcntl.h>
--#include <linux/interrupt.h>
--#include <linux/ptrace.h>
--#include <linux/poll.h>
--
--#include <linux/slab.h>
--#include <linux/tty.h>
--#include <linux/errno.h>
--#include <linux/string.h>
--#include <linux/signal.h>
--#include <linux/ioctl.h>
--#include <linux/skbuff.h>
--
--#include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
--#include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/hci_uart.h>
--
--#ifndef HCI_UART_DEBUG
--#undef DBG
--#define DBG( A... )
--#undef DMP
--#define DMP( A... )
--#endif
--
--/* ------- Interface to HCI layer ------ */
--/* Initialize device */
--int n_hci_open(struct hci_dev *hdev)
--{
-- DBG("%s %p", hdev->name, hdev);
--
-- /* Nothing to do for UART driver */
--
-- hdev->flags |= HCI_RUNNING;
--
-- return 0;
--}
--
--/* Reset device */
--int n_hci_flush(struct hci_dev *hdev)
--{
-- struct n_hci *n_hci = (struct n_hci *) hdev->driver_data;
-- struct tty_struct *tty = n_hci->tty;
--
-- DBG("hdev %p tty %p", hdev, tty);
--
-- /* Drop TX queue */
-- skb_queue_purge(&n_hci->txq);
--
-- /* Flush any pending characters in the driver and discipline. */
-- if (tty->ldisc.flush_buffer)
-- tty->ldisc.flush_buffer(tty);
--
-- if (tty->driver.flush_buffer)
-- tty->driver.flush_buffer(tty);
--
-- return 0;
--}
--
--/* Close device */
--int n_hci_close(struct hci_dev *hdev)
--{
-- DBG("hdev %p", hdev);
--
-- hdev->flags &= ~HCI_RUNNING;
--
-- n_hci_flush(hdev);
--
-- return 0;
--}
--
--int n_hci_tx_wakeup(struct n_hci *n_hci)
--{
-- register struct tty_struct *tty = n_hci->tty;
--
-- if (test_and_set_bit(TRANS_SENDING, &n_hci->tx_state)) {
-- set_bit(TRANS_WAKEUP, &n_hci->tx_state);
-- return 0;
-- }
--
-- DBG("");
-- do {
-- register struct sk_buff *skb;
-- register int len;
--
-- clear_bit(TRANS_WAKEUP, &n_hci->tx_state);
--
-- if (!(skb = skb_dequeue(&n_hci->txq)))
-- break;
--
-- DMP(skb->data, skb->len);
--
-- /* Send frame to TTY driver */
-- tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
-- len = tty->driver.write(tty, 0, skb->data, skb->len);
--
-- n_hci->hdev.stat.byte_tx += len;
--
-- DBG("sent %d", len);
--
-- if (len == skb->len) {
-- /* Full frame was sent */
-- kfree_skb(skb);
-- } else {
-- /* Subtract sent part and requeue */
-- skb_pull(skb, len);
-- skb_queue_head(&n_hci->txq, skb);
-- }
-- } while (test_bit(TRANS_WAKEUP, &n_hci->tx_state));
-- clear_bit(TRANS_SENDING, &n_hci->tx_state);
--
-- return 0;
--}
--
--/* Send frames from HCI layer */
--int n_hci_send_frame(struct sk_buff *skb)
--{
-- struct hci_dev* hdev = (struct hci_dev *) skb->dev;
-- struct tty_struct *tty;
-- struct n_hci *n_hci;
--
-- if (!hdev) {
-- ERR("Frame for uknown device (hdev=NULL)");
-- return -ENODEV;
-- }
--
-- if (!(hdev->flags & HCI_RUNNING))
-- return -EBUSY;
--
-- n_hci = (struct n_hci *) hdev->driver_data;
-- tty = n_hci2tty(n_hci);
--
-- DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
--
-- switch (skb->pkt_type) {
-- case HCI_COMMAND_PKT:
-- hdev->stat.cmd_tx++;
-- break;
--
-- case HCI_ACLDATA_PKT:
-- hdev->stat.acl_tx++;
-- break;
--
-- case HCI_SCODATA_PKT:
-- hdev->stat.cmd_tx++;
-- break;
-- };
--
-- /* Prepend skb with frame type and queue */
-- memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
-- skb_queue_tail(&n_hci->txq, skb);
--
-- n_hci_tx_wakeup(n_hci);
--
-- return 0;
--}
--
--/* ------ LDISC part ------ */
--
--/* n_hci_tty_open
-- *
-- * Called when line discipline changed to N_HCI.
-- *
-- * Arguments:
-- * tty pointer to tty info structure
-- * Return Value:
-- * 0 if success, otherwise error code
-- */
--static int n_hci_tty_open(struct tty_struct *tty)
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
-- struct hci_dev *hdev;
--
-- DBG("tty %p", tty);
--
-- if (n_hci)
-- return -EEXIST;
--
-- if (!(n_hci = kmalloc(sizeof(struct n_hci), GFP_KERNEL))) {
-- ERR("Can't allocate controll structure");
-- return -ENFILE;
-- }
-- memset(n_hci, 0, sizeof(struct n_hci));
--
-- /* Initialize and register HCI device */
-- hdev = &n_hci->hdev;
--
-- hdev->type = HCI_UART;
-- hdev->driver_data = n_hci;
--
-- hdev->open = n_hci_open;
-- hdev->close = n_hci_close;
-- hdev->flush = n_hci_flush;
-- hdev->send = n_hci_send_frame;
--
-- if (hci_register_dev(hdev) < 0) {
-- ERR("Can't register HCI device %s", hdev->name);
-- kfree(n_hci);
-- return -ENODEV;
-- }
--
-- tty->disc_data = n_hci;
-- n_hci->tty = tty;
--
-- spin_lock_init(&n_hci->rx_lock);
-- n_hci->rx_state = WAIT_PACKET_TYPE;
--
-- skb_queue_head_init(&n_hci->txq);
--
-- MOD_INC_USE_COUNT;
--
-- /* Flush any pending characters in the driver and discipline. */
-- if (tty->ldisc.flush_buffer)
-- tty->ldisc.flush_buffer(tty);
--
-- if (tty->driver.flush_buffer)
-- tty->driver.flush_buffer(tty);
--
-- return 0;
--}
--
--/* n_hci_tty_close()
-- *
-- * Called when the line discipline is changed to something
-- * else, the tty is closed, or the tty detects a hangup.
-- */
--static void n_hci_tty_close(struct tty_struct *tty)
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
-- struct hci_dev *hdev = &n_hci->hdev;
--
-- DBG("tty %p hdev %p", tty, hdev);
--
-- if (n_hci != NULL) {
-- n_hci_close(hdev);
--
-- if (hci_unregister_dev(hdev) < 0) {
-- ERR("Can't unregister HCI device %s",hdev->name);
-- }
--
-- hdev->driver_data = NULL;
-- tty->disc_data = NULL;
-- kfree(n_hci);
--
-- MOD_DEC_USE_COUNT;
-- }
--}
--
--/* n_hci_tty_wakeup()
-- *
-- * Callback for transmit wakeup. Called when low level
-- * device driver can accept more send data.
-- *
-- * Arguments: tty pointer to associated tty instance data
-- * Return Value: None
-- */
--static void n_hci_tty_wakeup( struct tty_struct *tty )
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
--
-- DBG("");
--
-- if (!n_hci)
-- return;
--
-- tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
--
-- if (tty != n_hci->tty)
-- return;
--
-- n_hci_tx_wakeup(n_hci);
--}
--
--/* n_hci_tty_room()
-- *
-- * Callback function from tty driver. Return the amount of
-- * space left in the receiver's buffer to decide if remote
-- * transmitter is to be throttled.
-- *
-- * Arguments: tty pointer to associated tty instance data
-- * Return Value: number of bytes left in receive buffer
-- */
--static int n_hci_tty_room (struct tty_struct *tty)
--{
-- return 65536;
--}
--
--static inline int n_hci_check_data_len(struct n_hci *n_hci, int len)
--{
-- register int room = skb_tailroom(n_hci->rx_skb);
--
-- DBG("len %d room %d", len, room);
-- if (!len) {
-- DMP(n_hci->rx_skb->data, n_hci->rx_skb->len);
-- hci_recv_frame(n_hci->rx_skb);
-- } else if (len > room) {
-- ERR("Data length is to large");
-- kfree_skb(n_hci->rx_skb);
-- n_hci->hdev.stat.err_rx++;
-- } else {
-- n_hci->rx_state = WAIT_DATA;
-- n_hci->rx_count = len;
-- return len;
-- }
--
-- n_hci->rx_state = WAIT_PACKET_TYPE;
-- n_hci->rx_skb = NULL;
-- n_hci->rx_count = 0;
-- return 0;
--}
--
--static inline void n_hci_rx(struct n_hci *n_hci, const __u8 * data, char *flags, int count)
--{
-- register const char *ptr;
-- hci_event_hdr *eh;
-- hci_acl_hdr *ah;
-- hci_sco_hdr *sh;
-- register int len, type, dlen;
--
-- DBG("count %d state %ld rx_count %ld", count, n_hci->rx_state, n_hci->rx_count);
--
-- n_hci->hdev.stat.byte_rx += count;
--
-- ptr = data;
-- while (count) {
-- if (n_hci->rx_count) {
-- len = MIN(n_hci->rx_count, count);
-- memcpy(skb_put(n_hci->rx_skb, len), ptr, len);
-- n_hci->rx_count -= len; count -= len; ptr += len;
--
-- if (n_hci->rx_count)
-- continue;
--
-- switch (n_hci->rx_state) {
-- case WAIT_DATA:
-- DBG("Complete data");
--
-- DMP(n_hci->rx_skb->data, n_hci->rx_skb->len);
--
-- hci_recv_frame(n_hci->rx_skb);
--
-- n_hci->rx_state = WAIT_PACKET_TYPE;
-- n_hci->rx_skb = NULL;
-- continue;
--
-- case WAIT_EVENT_HDR:
-- eh = (hci_event_hdr *) n_hci->rx_skb->data;
--
-- DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
--
-- n_hci_check_data_len(n_hci, eh->plen);
-- continue;
--
-- case WAIT_ACL_HDR:
-- ah = (hci_acl_hdr *) n_hci->rx_skb->data;
-- dlen = __le16_to_cpu(ah->dlen);
--
-- DBG("ACL header: dlen %d", dlen);
--
-- n_hci_check_data_len(n_hci, dlen);
-- continue;
--
-- case WAIT_SCO_HDR:
-- sh = (hci_sco_hdr *) n_hci->rx_skb->data;
--
-- DBG("SCO header: dlen %d", sh->dlen);
--
-- n_hci_check_data_len(n_hci, sh->dlen);
-- continue;
-- };
-- }
--
-- /* WAIT_PACKET_TYPE */
-- switch (*ptr) {
-- case HCI_EVENT_PKT:
-- DBG("Event packet");
-- n_hci->rx_state = WAIT_EVENT_HDR;
-- n_hci->rx_count = HCI_EVENT_HDR_SIZE;
-- type = HCI_EVENT_PKT;
-- break;
--
-- case HCI_ACLDATA_PKT:
-- DBG("ACL packet");
-- n_hci->rx_state = WAIT_ACL_HDR;
-- n_hci->rx_count = HCI_ACL_HDR_SIZE;
-- type = HCI_ACLDATA_PKT;
-- break;
--
-- case HCI_SCODATA_PKT:
-- DBG("SCO packet");
-- n_hci->rx_state = WAIT_SCO_HDR;
-- n_hci->rx_count = HCI_SCO_HDR_SIZE;
-- type = HCI_SCODATA_PKT;
-- break;
--
-- default:
-- ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
-- n_hci->hdev.stat.err_rx++;
-- ptr++; count--;
-- continue;
-- };
-- ptr++; count--;
--
-- /* Allocate packet */
-- if (!(n_hci->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-- ERR("Can't allocate mem for new packet");
--
-- n_hci->rx_state = WAIT_PACKET_TYPE;
-- n_hci->rx_count = 0;
-- return;
-- }
-- n_hci->rx_skb->dev = (void *) &n_hci->hdev;
-- n_hci->rx_skb->pkt_type = type;
-- }
--}
--
--/* n_hci_tty_receive()
-- *
-- * Called by tty low level driver when receive data is
-- * available.
-- *
-- * Arguments: tty pointer to tty isntance data
-- * data pointer to received data
-- * flags pointer to flags for data
-- * count count of received data in bytes
-- *
-- * Return Value: None
-- */
--static void n_hci_tty_receive(struct tty_struct *tty, const __u8 * data, char *flags, int count)
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
--
-- if (!n_hci || tty != n_hci->tty)
-- return;
--
-- spin_lock(&n_hci->rx_lock);
-- n_hci_rx(n_hci, data, flags, count);
-- spin_unlock(&n_hci->rx_lock);
--
-- if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver.unthrottle)
-- tty->driver.unthrottle(tty);
--}
--
--/* n_hci_tty_ioctl()
-- *
-- * Process IOCTL system call for the tty device.
-- *
-- * Arguments:
-- *
-- * tty pointer to tty instance data
-- * file pointer to open file object for device
-- * cmd IOCTL command code
-- * arg argument for IOCTL call (cmd dependent)
-- *
-- * Return Value: Command dependent
-- */
--static int n_hci_tty_ioctl (struct tty_struct *tty, struct file * file,
-- unsigned int cmd, unsigned long arg)
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
-- int error = 0;
--
-- DBG("");
--
-- /* Verify the status of the device */
-- if (!n_hci)
-- return -EBADF;
--
-- switch (cmd) {
-- default:
-- error = n_tty_ioctl(tty, file, cmd, arg);
-- break;
-- };
--
-- return error;
--}
--
--/*
-- * We don't provide read/write/poll interface for user space.
-- */
--static ssize_t n_hci_tty_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr)
--{
-- return 0;
--}
--static ssize_t n_hci_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
--{
-- return 0;
--}
--static unsigned int n_hci_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
--{
-- return 0;
--}
--
--int __init n_hci_init(void)
--{
-- static struct tty_ldisc n_hci_ldisc;
-- int err;
--
-- INF("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
--
-- /* Register the tty discipline */
--
-- memset(&n_hci_ldisc, 0, sizeof (n_hci_ldisc));
-- n_hci_ldisc.magic = TTY_LDISC_MAGIC;
-- n_hci_ldisc.name = "n_hci";
-- n_hci_ldisc.open = n_hci_tty_open;
-- n_hci_ldisc.close = n_hci_tty_close;
-- n_hci_ldisc.read = n_hci_tty_read;
-- n_hci_ldisc.write = n_hci_tty_write;
-- n_hci_ldisc.ioctl = n_hci_tty_ioctl;
-- n_hci_ldisc.poll = n_hci_tty_poll;
-- n_hci_ldisc.receive_room= n_hci_tty_room;
-- n_hci_ldisc.receive_buf = n_hci_tty_receive;
-- n_hci_ldisc.write_wakeup= n_hci_tty_wakeup;
--
-- if ((err = tty_register_ldisc(N_HCI, &n_hci_ldisc))) {
-- ERR("Can't register HCI line discipline (%d)", err);
-- return err;
-- }
--
-- return 0;
--}
--
--void n_hci_cleanup(void)
--{
-- int err;
--
-- /* Release tty registration of line discipline */
-- if ((err = tty_register_ldisc(N_HCI, NULL)))
-- ERR("Can't unregister HCI line discipline (%d)", err);
--}
--
--module_init(n_hci_init);
--module_exit(n_hci_cleanup);
--
--MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
--MODULE_DESCRIPTION("BlueZ HCI UART driver ver " VERSION);
--MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/drivers/bluetooth/hci_uart.h linux-2.4.18-mh15/drivers/bluetooth/hci_uart.h
---- linux-2.4.18/drivers/bluetooth/hci_uart.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_uart.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,82 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef N_HCI
-+#define N_HCI 15
-+#endif
-+
-+/* Ioctls */
-+#define HCIUARTSETPROTO _IOW('U', 200, int)
-+#define HCIUARTGETPROTO _IOR('U', 201, int)
-+
-+/* UART protocols */
-+#define HCI_UART_MAX_PROTO 4
-+
-+#define HCI_UART_H4 0
-+#define HCI_UART_BCSP 1
-+#define HCI_UART_3WIRE 2
-+#define HCI_UART_H4DS 3
-+
-+#ifdef __KERNEL__
-+struct hci_uart;
-+
-+struct hci_uart_proto {
-+ unsigned int id;
-+ int (*open)(struct hci_uart *hu);
-+ int (*close)(struct hci_uart *hu);
-+ int (*flush)(struct hci_uart *hu);
-+ int (*recv)(struct hci_uart *hu, void *data, int len);
-+ int (*enqueue)(struct hci_uart *hu, struct sk_buff *skb);
-+ struct sk_buff *(*dequeue)(struct hci_uart *hu);
-+};
-+
-+struct hci_uart {
-+ struct tty_struct *tty;
-+ struct hci_dev hdev;
-+ unsigned long flags;
-+
-+ struct hci_uart_proto *proto;
-+ void *priv;
-+
-+ struct sk_buff *tx_skb;
-+ unsigned long tx_state;
-+ spinlock_t rx_lock;
-+};
-+
-+/* HCI_UART flag bits */
-+#define HCI_UART_PROTO_SET 0
-+
-+/* TX states */
-+#define HCI_UART_SENDING 1
-+#define HCI_UART_TX_WAKEUP 2
-+
-+int hci_uart_register_proto(struct hci_uart_proto *p);
-+int hci_uart_unregister_proto(struct hci_uart_proto *p);
-+int hci_uart_tx_wakeup(struct hci_uart *hu);
-+
-+#endif /* __KERNEL__ */
-diff -urN linux-2.4.18/drivers/bluetooth/hci_usb.c linux-2.4.18-mh15/drivers/bluetooth/hci_usb.c
---- linux-2.4.18/drivers/bluetooth/hci_usb.c 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_usb.c 2004-08-01 16:26:23.000000000 +0200
-@@ -1,9 +1,10 @@
- /*
-- BlueZ - Bluetooth protocol stack for Linux
-+ HCI USB driver for Linux Bluetooth protocol stack (BlueZ)
- Copyright (C) 2000-2001 Qualcomm Incorporated
--
- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-
-+ Copyright (C) 2003 Maxim Krasnyansky <maxk@qualcomm.com>
-+
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as
- published by the Free Software Foundation;
-@@ -23,598 +24,938 @@
- */
-
- /*
-- * BlueZ HCI USB driver.
- * Based on original USB Bluetooth driver for Linux kernel
- * Copyright (c) 2000 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (c) 2000 Mark Douglas Corner <mcorner@umich.edu>
- *
-- * $Id$
-+ * $Id$
- */
--#define VERSION "1.0"
-+#define VERSION "2.7"
-
- #include <linux/config.h>
- #include <linux/module.h>
-
- #include <linux/version.h>
--#include <linux/config.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/sched.h>
-+#include <linux/unistd.h>
- #include <linux/types.h>
--#include <linux/fcntl.h>
- #include <linux/interrupt.h>
--#include <linux/ptrace.h>
--#include <linux/poll.h>
-
- #include <linux/slab.h>
--#include <linux/tty.h>
- #include <linux/errno.h>
- #include <linux/string.h>
--#include <linux/signal.h>
--#include <linux/ioctl.h>
- #include <linux/skbuff.h>
-
- #include <linux/usb.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/hci_usb.h>
-+
-+#include "hci_usb.h"
-
- #ifndef HCI_USB_DEBUG
--#undef DBG
--#define DBG( A... )
--#undef DMP
--#define DMP( A... )
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#undef BT_DMP
-+#define BT_DMP( A... )
- #endif
-
--static struct usb_device_id usb_bluetooth_ids [] = {
-+#ifndef CONFIG_BLUEZ_HCIUSB_ZERO_PACKET
-+#undef USB_ZERO_PACKET
-+#define USB_ZERO_PACKET 0
-+#endif
-+
-+static struct usb_driver hci_usb_driver;
-+
-+static struct usb_device_id bluetooth_ids[] = {
-+ /* Generic Bluetooth USB device */
- { USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) },
-+
-+ /* AVM BlueFRITZ! USB v2.0 */
-+ { USB_DEVICE(0x057c, 0x3800) },
-+
-+ /* Bluetooth Ultraport Module from IBM */
-+ { USB_DEVICE(0x04bf, 0x030a) },
-+
-+ /* ALPS Modules with non-standard id */
-+ { USB_DEVICE(0x044e, 0x3001) },
-+ { USB_DEVICE(0x044e, 0x3002) },
-+
-+ /* Ericsson with non-standard id */
-+ { USB_DEVICE(0x0bdb, 0x1002) },
-+
- { } /* Terminating entry */
- };
-
--MODULE_DEVICE_TABLE (usb, usb_bluetooth_ids);
-+MODULE_DEVICE_TABLE (usb, bluetooth_ids);
-
--static int hci_usb_ctrl_msg(struct hci_usb *husb, struct sk_buff *skb);
--static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb);
-+static struct usb_device_id blacklist_ids[] = {
-+ /* Broadcom BCM2033 without firmware */
-+ { USB_DEVICE(0x0a5c, 0x2033), driver_info: HCI_IGNORE },
-
--static void hci_usb_unlink_urbs(struct hci_usb *husb)
-+ /* Broadcom BCM2035 */
-+ { USB_DEVICE(0x0a5c, 0x200a), driver_info: HCI_RESET },
-+
-+ /* ISSC Bluetooth Adapter v3.1 */
-+ { USB_DEVICE(0x1131, 0x1001), driver_info: HCI_RESET },
-+
-+ /* Digianswer device */
-+ { USB_DEVICE(0x08fd, 0x0001), driver_info: HCI_DIGIANSWER },
-+
-+ /* RTX Telecom based adapter with buggy SCO support */
-+ { USB_DEVICE(0x0400, 0x0807), driver_info: HCI_BROKEN_ISOC },
-+
-+ { } /* Terminating entry */
-+};
-+
-+struct _urb *_urb_alloc(int isoc, int gfp)
- {
-- usb_unlink_urb(husb->read_urb);
-- usb_unlink_urb(husb->intr_urb);
-- usb_unlink_urb(husb->ctrl_urb);
-- usb_unlink_urb(husb->write_urb);
-+ struct _urb *_urb = kmalloc(sizeof(struct _urb) +
-+ sizeof(iso_packet_descriptor_t) * isoc, gfp);
-+ if (_urb) {
-+ memset(_urb, 0, sizeof(*_urb));
-+ spin_lock_init(&_urb->urb.lock);
-+ }
-+ return _urb;
-+}
-+
-+struct _urb *_urb_dequeue(struct _urb_queue *q)
-+{
-+ struct _urb *_urb = NULL;
-+ unsigned long flags;
-+ spin_lock_irqsave(&q->lock, flags);
-+ {
-+ struct list_head *head = &q->head;
-+ struct list_head *next = head->next;
-+ if (next != head) {
-+ _urb = list_entry(next, struct _urb, list);
-+ list_del(next); _urb->queue = NULL;
-+ }
-+ }
-+ spin_unlock_irqrestore(&q->lock, flags);
-+ return _urb;
- }
-
--static void hci_usb_free_bufs(struct hci_usb *husb)
-+static void hci_usb_rx_complete(struct urb *urb);
-+static void hci_usb_tx_complete(struct urb *urb);
-+
-+#define __pending_tx(husb, type) (&husb->pending_tx[type-1])
-+#define __pending_q(husb, type) (&husb->pending_q[type-1])
-+#define __completed_q(husb, type) (&husb->completed_q[type-1])
-+#define __transmit_q(husb, type) (&husb->transmit_q[type-1])
-+#define __reassembly(husb, type) (husb->reassembly[type-1])
-+
-+static inline struct _urb *__get_completed(struct hci_usb *husb, int type)
- {
-- if (husb->read_urb) {
-- if (husb->read_urb->transfer_buffer)
-- kfree(husb->read_urb->transfer_buffer);
-- usb_free_urb(husb->read_urb);
-- }
-+ return _urb_dequeue(__completed_q(husb, type));
-+}
-
-- if (husb->intr_urb) {
-- if (husb->intr_urb->transfer_buffer)
-- kfree(husb->intr_urb->transfer_buffer);
-- usb_free_urb(husb->intr_urb);
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+static void __fill_isoc_desc(struct urb *urb, int len, int mtu)
-+{
-+ int offset = 0, i;
-+
-+ BT_DBG("len %d mtu %d", len, mtu);
-+
-+ for (i=0; i < HCI_MAX_ISOC_FRAMES && len >= mtu; i++, offset += mtu, len -= mtu) {
-+ urb->iso_frame_desc[i].offset = offset;
-+ urb->iso_frame_desc[i].length = mtu;
-+ BT_DBG("desc %d offset %d len %d", i, offset, mtu);
-+ }
-+ if (len && i < HCI_MAX_ISOC_FRAMES) {
-+ urb->iso_frame_desc[i].offset = offset;
-+ urb->iso_frame_desc[i].length = len;
-+ BT_DBG("desc %d offset %d len %d", i, offset, len);
-+ i++;
- }
-+ urb->number_of_packets = i;
-+}
-+#endif
-
-- if (husb->ctrl_urb)
-- usb_free_urb(husb->ctrl_urb);
-+static int hci_usb_intr_rx_submit(struct hci_usb *husb)
-+{
-+ struct _urb *_urb;
-+ struct urb *urb;
-+ int err, pipe, interval, size;
-+ void *buf;
-+
-+ BT_DBG("%s", husb->hdev.name);
-+
-+ size = husb->intr_in_ep->wMaxPacketSize;
-+
-+ buf = kmalloc(size, GFP_ATOMIC);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ _urb = _urb_alloc(0, GFP_ATOMIC);
-+ if (!_urb) {
-+ kfree(buf);
-+ return -ENOMEM;
-+ }
-+ _urb->type = HCI_EVENT_PKT;
-+ _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
-+
-+ urb = &_urb->urb;
-+ pipe = usb_rcvintpipe(husb->udev, husb->intr_in_ep->bEndpointAddress);
-+ interval = husb->intr_in_ep->bInterval;
-+ FILL_INT_URB(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb, interval);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s intr rx submit failed urb %p err %d",
-+ husb->hdev.name, urb, err);
-+ _urb_unlink(_urb);
-+ _urb_free(_urb);
-+ kfree(buf);
-+ }
-+ return err;
-+}
-
-- if (husb->write_urb)
-- usb_free_urb(husb->write_urb);
-+static int hci_usb_bulk_rx_submit(struct hci_usb *husb)
-+{
-+ struct _urb *_urb;
-+ struct urb *urb;
-+ int err, pipe, size = HCI_MAX_FRAME_SIZE;
-+ void *buf;
-+
-+ buf = kmalloc(size, GFP_ATOMIC);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ _urb = _urb_alloc(0, GFP_ATOMIC);
-+ if (!_urb) {
-+ kfree(buf);
-+ return -ENOMEM;
-+ }
-+ _urb->type = HCI_ACLDATA_PKT;
-+ _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
-+
-+ urb = &_urb->urb;
-+ pipe = usb_rcvbulkpipe(husb->udev, husb->bulk_in_ep->bEndpointAddress);
-+ FILL_BULK_URB(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb);
-+ urb->transfer_flags = USB_QUEUE_BULK;
-+
-+ BT_DBG("%s urb %p", husb->hdev.name, urb);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s bulk rx submit failed urb %p err %d",
-+ husb->hdev.name, urb, err);
-+ _urb_unlink(_urb);
-+ _urb_free(_urb);
-+ kfree(buf);
-+ }
-+ return err;
-+}
-
-- if (husb->intr_skb)
-- kfree_skb(husb->intr_skb);
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+static int hci_usb_isoc_rx_submit(struct hci_usb *husb)
-+{
-+ struct _urb *_urb;
-+ struct urb *urb;
-+ int err, mtu, size;
-+ void *buf;
-+
-+ mtu = husb->isoc_in_ep->wMaxPacketSize;
-+ size = mtu * HCI_MAX_ISOC_FRAMES;
-+
-+ buf = kmalloc(size, GFP_ATOMIC);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
-+ if (!_urb) {
-+ kfree(buf);
-+ return -ENOMEM;
-+ }
-+ _urb->type = HCI_SCODATA_PKT;
-+ _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
-+
-+ urb = &_urb->urb;
-+
-+ urb->context = husb;
-+ urb->dev = husb->udev;
-+ urb->pipe = usb_rcvisocpipe(husb->udev, husb->isoc_in_ep->bEndpointAddress);
-+ urb->complete = hci_usb_rx_complete;
-+
-+ urb->transfer_buffer_length = size;
-+ urb->transfer_buffer = buf;
-+ urb->transfer_flags = USB_ISO_ASAP;
-+
-+ __fill_isoc_desc(urb, size, mtu);
-+
-+ BT_DBG("%s urb %p", husb->hdev.name, urb);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s isoc rx submit failed urb %p err %d",
-+ husb->hdev.name, urb, err);
-+ _urb_unlink(_urb);
-+ _urb_free(_urb);
-+ kfree(buf);
-+ }
-+ return err;
- }
-+#endif
-
--/* ------- Interface to HCI layer ------ */
- /* Initialize device */
--int hci_usb_open(struct hci_dev *hdev)
-+static int hci_usb_open(struct hci_dev *hdev)
- {
- struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-- int status;
-+ int i, err;
-+ unsigned long flags;
-+
-+ BT_DBG("%s", hdev->name);
-
-- DBG("%s", hdev->name);
-+ if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-
-- husb->read_urb->dev = husb->udev;
-- if ((status = usb_submit_urb(husb->read_urb)))
-- DBG("read submit failed. %d", status);
-+ MOD_INC_USE_COUNT;
-
-- husb->intr_urb->dev = husb->udev;
-- if ((status = usb_submit_urb(husb->intr_urb)))
-- DBG("interrupt submit failed. %d", status);
-+ write_lock_irqsave(&husb->completion_lock, flags);
-
-- hdev->flags |= HCI_RUNNING;
-+ err = hci_usb_intr_rx_submit(husb);
-+ if (!err) {
-+ for (i = 0; i < HCI_MAX_BULK_RX; i++)
-+ hci_usb_bulk_rx_submit(husb);
-+
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ if (husb->isoc_iface)
-+ for (i = 0; i < HCI_MAX_ISOC_RX; i++)
-+ hci_usb_isoc_rx_submit(husb);
-+#endif
-+ } else {
-+ clear_bit(HCI_RUNNING, &hdev->flags);
-+ MOD_DEC_USE_COUNT;
-+ }
-
-- return 0;
-+ write_unlock_irqrestore(&husb->completion_lock, flags);
-+ return err;
- }
-
- /* Reset device */
--int hci_usb_flush(struct hci_dev *hdev)
-+static int hci_usb_flush(struct hci_dev *hdev)
- {
- struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-+ int i;
-
-- DBG("%s", hdev->name);
--
-- /* Drop TX queues */
-- skb_queue_purge(&husb->tx_ctrl_q);
-- skb_queue_purge(&husb->tx_write_q);
-+ BT_DBG("%s", hdev->name);
-
-+ for (i=0; i < 4; i++)
-+ skb_queue_purge(&husb->transmit_q[i]);
- return 0;
- }
-
--/* Close device */
--int hci_usb_close(struct hci_dev *hdev)
-+static void hci_usb_unlink_urbs(struct hci_usb *husb)
- {
-- struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-+ int i;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s", husb->hdev.name);
-
-- hdev->flags &= ~HCI_RUNNING;
-- hci_usb_unlink_urbs(husb);
-+ for (i=0; i < 4; i++) {
-+ struct _urb *_urb;
-+ struct urb *urb;
-+
-+ /* Kill pending requests */
-+ while ((_urb = _urb_dequeue(&husb->pending_q[i]))) {
-+ urb = &_urb->urb;
-+ BT_DBG("%s unlinking _urb %p type %d urb %p",
-+ husb->hdev.name, _urb, _urb->type, urb);
-+ usb_unlink_urb(urb);
-+ _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
-+ }
-
-- hci_usb_flush(hdev);
-+ /* Release completed requests */
-+ while ((_urb = _urb_dequeue(&husb->completed_q[i]))) {
-+ urb = &_urb->urb;
-+ BT_DBG("%s freeing _urb %p type %d urb %p",
-+ husb->hdev.name, _urb, _urb->type, urb);
-+ if (urb->setup_packet)
-+ kfree(urb->setup_packet);
-+ if (urb->transfer_buffer)
-+ kfree(urb->transfer_buffer);
-+ _urb_free(_urb);
-+ }
-
-- return 0;
-+ /* Release reassembly buffers */
-+ if (husb->reassembly[i]) {
-+ kfree_skb(husb->reassembly[i]);
-+ husb->reassembly[i] = NULL;
-+ }
-+ }
- }
-
--void hci_usb_ctrl_wakeup(struct hci_usb *husb)
-+/* Close device */
-+static int hci_usb_close(struct hci_dev *hdev)
- {
-- struct sk_buff *skb;
-+ struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-+ unsigned long flags;
-+
-+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-
-- if (test_and_set_bit(HCI_TX_CTRL, &husb->tx_state))
-- return;
-+ BT_DBG("%s", hdev->name);
-
-- DBG("%s", husb->hdev.name);
-+ write_lock_irqsave(&husb->completion_lock, flags);
-+
-+ hci_usb_unlink_urbs(husb);
-+ hci_usb_flush(hdev);
-
-- if (!(skb = skb_dequeue(&husb->tx_ctrl_q)))
-- goto done;
-+ write_unlock_irqrestore(&husb->completion_lock, flags);
-
-- if (hci_usb_ctrl_msg(husb, skb)){
-- kfree_skb(skb);
-- goto done;
-- }
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-
-- DMP(skb->data, skb->len);
-+static int __tx_submit(struct hci_usb *husb, struct _urb *_urb)
-+{
-+ struct urb *urb = &_urb->urb;
-+ int err;
-
-- husb->hdev.stat.byte_tx += skb->len;
-- return;
-+ BT_DBG("%s urb %p type %d", husb->hdev.name, urb, _urb->type);
-+
-+ _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s tx submit failed urb %p type %d err %d",
-+ husb->hdev.name, urb, _urb->type, err);
-+ _urb_unlink(_urb);
-+ _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
-+ } else
-+ atomic_inc(__pending_tx(husb, _urb->type));
-
--done:
-- clear_bit(HCI_TX_CTRL, &husb->tx_state);
-- return;
-+ return err;
- }
-
--void hci_usb_write_wakeup(struct hci_usb *husb)
-+static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
- {
-- struct sk_buff *skb;
-+ struct _urb *_urb = __get_completed(husb, skb->pkt_type);
-+ devrequest *dr;
-+ struct urb *urb;
-+
-+ if (!_urb) {
-+ _urb = _urb_alloc(0, GFP_ATOMIC);
-+ if (!_urb)
-+ return -ENOMEM;
-+ _urb->type = skb->pkt_type;
-+
-+ dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
-+ if (!dr) {
-+ _urb_free(_urb);
-+ return -ENOMEM;
-+ }
-+ } else
-+ dr = (void *) _urb->urb.setup_packet;
-
-- if (test_and_set_bit(HCI_TX_WRITE, &husb->tx_state))
-- return;
-+ dr->requesttype = husb->ctrl_req;
-+ dr->request = 0;
-+ dr->index = 0;
-+ dr->value = 0;
-+ dr->length = __cpu_to_le16(skb->len);
-
-- DBG("%s", husb->hdev.name);
-+ urb = &_urb->urb;
-+ FILL_CONTROL_URB(urb, husb->udev, usb_sndctrlpipe(husb->udev, 0),
-+ (void *) dr, skb->data, skb->len, hci_usb_tx_complete, husb);
-
-- if (!(skb = skb_dequeue(&husb->tx_write_q)))
-- goto done;
-+ BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
-+
-+ _urb->priv = skb;
-+ return __tx_submit(husb, _urb);
-+}
-
-- if (hci_usb_write_msg(husb, skb)) {
-- skb_queue_head(&husb->tx_write_q, skb);
-- goto done;
-+static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
-+{
-+ struct _urb *_urb = __get_completed(husb, skb->pkt_type);
-+ struct urb *urb;
-+ int pipe;
-+
-+ if (!_urb) {
-+ _urb = _urb_alloc(0, GFP_ATOMIC);
-+ if (!_urb)
-+ return -ENOMEM;
-+ _urb->type = skb->pkt_type;
- }
-
-- DMP(skb->data, skb->len);
-+ urb = &_urb->urb;
-+ pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep->bEndpointAddress);
-+ FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,
-+ hci_usb_tx_complete, husb);
-+ urb->transfer_flags = USB_QUEUE_BULK | USB_ZERO_PACKET;
-
-- husb->hdev.stat.byte_tx += skb->len;
-- return;
-+ BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
-
--done:
-- clear_bit(HCI_TX_WRITE, &husb->tx_state);
-- return;
-+ _urb->priv = skb;
-+ return __tx_submit(husb, _urb);
- }
-
--/* Send frames from HCI layer */
--int hci_usb_send_frame(struct sk_buff *skb)
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb)
- {
-- struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-- struct hci_usb *husb;
--
-- if (!hdev) {
-- ERR("frame for uknown device (hdev=NULL)");
-- return -ENODEV;
-+ struct _urb *_urb = __get_completed(husb, skb->pkt_type);
-+ struct urb *urb;
-+
-+ if (!_urb) {
-+ _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
-+ if (!_urb)
-+ return -ENOMEM;
-+ _urb->type = skb->pkt_type;
- }
-
-- if (!(hdev->flags & HCI_RUNNING))
-- return 0;
-+ BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
-
-- husb = (struct hci_usb *) hdev->driver_data;
-+ urb = &_urb->urb;
-+
-+ urb->context = husb;
-+ urb->dev = husb->udev;
-+ urb->pipe = usb_sndisocpipe(husb->udev, husb->isoc_out_ep->bEndpointAddress);
-+ urb->complete = hci_usb_tx_complete;
-+ urb->transfer_flags = USB_ISO_ASAP;
-
-- DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-+ urb->transfer_buffer = skb->data;
-+ urb->transfer_buffer_length = skb->len;
-+
-+ __fill_isoc_desc(urb, skb->len, husb->isoc_out_ep->wMaxPacketSize);
-
-- switch (skb->pkt_type) {
-- case HCI_COMMAND_PKT:
-- skb_queue_tail(&husb->tx_ctrl_q, skb);
-- hci_usb_ctrl_wakeup(husb);
-- hdev->stat.cmd_tx++;
-- return 0;
--
-- case HCI_ACLDATA_PKT:
-- skb_queue_tail(&husb->tx_write_q, skb);
-- hci_usb_write_wakeup(husb);
-- hdev->stat.acl_tx++;
-- return 0;
--
-- case HCI_SCODATA_PKT:
-- return -EOPNOTSUPP;
-- };
--
-- return 0;
-+ _urb->priv = skb;
-+ return __tx_submit(husb, _urb);
- }
-+#endif
-
--/* ---------- USB ------------- */
--
--static void hci_usb_ctrl(struct urb *urb)
-+static void hci_usb_tx_process(struct hci_usb *husb)
- {
-- struct sk_buff *skb = (struct sk_buff *) urb->context;
-- struct hci_dev *hdev;
-- struct hci_usb *husb;
-+ struct sk_buff_head *q;
-+ struct sk_buff *skb;
-
-- if (!skb)
-- return;
-- hdev = (struct hci_dev *) skb->dev;
-- husb = (struct hci_usb *) hdev->driver_data;
-+ BT_DBG("%s", husb->hdev.name);
-
-- DBG("%s", hdev->name);
-+ do {
-+ clear_bit(HCI_USB_TX_WAKEUP, &husb->state);
-
-- if (urb->status)
-- DBG("%s ctrl status: %d", hdev->name, urb->status);
-+ /* Process command queue */
-+ q = __transmit_q(husb, HCI_COMMAND_PKT);
-+ if (!atomic_read(__pending_tx(husb, HCI_COMMAND_PKT)) &&
-+ (skb = skb_dequeue(q))) {
-+ if (hci_usb_send_ctrl(husb, skb) < 0)
-+ skb_queue_head(q, skb);
-+ }
-
-- clear_bit(HCI_TX_CTRL, &husb->tx_state);
-- kfree_skb(skb);
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ /* Process SCO queue */
-+ q = __transmit_q(husb, HCI_SCODATA_PKT);
-+ if (atomic_read(__pending_tx(husb, HCI_SCODATA_PKT)) < HCI_MAX_ISOC_TX &&
-+ (skb = skb_dequeue(q))) {
-+ if (hci_usb_send_isoc(husb, skb) < 0)
-+ skb_queue_head(q, skb);
-+ }
-+#endif
-+
-+ /* Process ACL queue */
-+ q = __transmit_q(husb, HCI_ACLDATA_PKT);
-+ while (atomic_read(__pending_tx(husb, HCI_ACLDATA_PKT)) < HCI_MAX_BULK_TX &&
-+ (skb = skb_dequeue(q))) {
-+ if (hci_usb_send_bulk(husb, skb) < 0) {
-+ skb_queue_head(q, skb);
-+ break;
-+ }
-+ }
-+ } while(test_bit(HCI_USB_TX_WAKEUP, &husb->state));
-+}
-
-- /* Wake up device */
-- hci_usb_ctrl_wakeup(husb);
-+static inline void hci_usb_tx_wakeup(struct hci_usb *husb)
-+{
-+ /* Serialize TX queue processing to avoid data reordering */
-+ if (!test_and_set_bit(HCI_USB_TX_PROCESS, &husb->state)) {
-+ hci_usb_tx_process(husb);
-+ clear_bit(HCI_USB_TX_PROCESS, &husb->state);
-+ } else
-+ set_bit(HCI_USB_TX_WAKEUP, &husb->state);
- }
-
--static void hci_usb_bulk_write(struct urb *urb)
-+/* Send frames from HCI layer */
-+static int hci_usb_send_frame(struct sk_buff *skb)
- {
-- struct sk_buff *skb = (struct sk_buff *) urb->context;
-- struct hci_dev *hdev;
-+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
- struct hci_usb *husb;
-
-- if (!skb)
-- return;
-- hdev = (struct hci_dev *) skb->dev;
-- husb = (struct hci_usb *) hdev->driver_data;
-+ if (!hdev) {
-+ BT_ERR("frame for uknown device (hdev=NULL)");
-+ return -ENODEV;
-+ }
-
-- DBG("%s", hdev->name);
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return -EBUSY;
-
-- if (urb->status)
-- DBG("%s bulk write status: %d", hdev->name, urb->status);
-+ BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-
-- clear_bit(HCI_TX_WRITE, &husb->tx_state);
-- kfree_skb(skb);
-+ husb = (struct hci_usb *) hdev->driver_data;
-
-- /* Wake up device */
-- hci_usb_write_wakeup(husb);
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+#endif
-
-- return;
--}
-+ default:
-+ kfree_skb(skb);
-+ return 0;
-+ }
-
--static void hci_usb_intr(struct urb *urb)
--{
-- struct hci_usb *husb = (struct hci_usb *) urb->context;
-- unsigned char *data = urb->transfer_buffer;
-- register int count = urb->actual_length;
-- register struct sk_buff *skb = husb->intr_skb;
-- hci_event_hdr *eh;
-- register int len;
-+ read_lock(&husb->completion_lock);
-
-- if (!husb)
-- return;
-+ skb_queue_tail(__transmit_q(husb, skb->pkt_type), skb);
-+ hci_usb_tx_wakeup(husb);
-
-- DBG("%s count %d", husb->hdev.name, count);
-+ read_unlock(&husb->completion_lock);
-+ return 0;
-+}
-
-- if (urb->status || !count) {
-- DBG("%s intr status %d, count %d", husb->hdev.name, urb->status, count);
-- return;
-- }
-+static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int count)
-+{
-+ BT_DBG("%s type %d data %p count %d", husb->hdev.name, type, data, count);
-
-- /* Do we really have to handle continuations here ? */
-- if (!skb) {
-- /* New frame */
-- if (count < HCI_EVENT_HDR_SIZE) {
-- DBG("%s bad frame len %d", husb->hdev.name, count);
-- return;
-- }
-+ husb->hdev.stat.byte_rx += count;
-
-- eh = (hci_event_hdr *) data;
-- len = eh->plen + HCI_EVENT_HDR_SIZE;
-+ while (count) {
-+ struct sk_buff *skb = __reassembly(husb, type);
-+ struct { int expect; } *scb;
-+ int len = 0;
-+
-+ if (!skb) {
-+ /* Start of the frame */
-+
-+ switch (type) {
-+ case HCI_EVENT_PKT:
-+ if (count >= HCI_EVENT_HDR_SIZE) {
-+ hci_event_hdr *h = data;
-+ len = HCI_EVENT_HDR_SIZE + h->plen;
-+ } else
-+ return -EILSEQ;
-+ break;
-
-- if (count > len) {
-- DBG("%s corrupted frame, len %d", husb->hdev.name, count);
-- return;
-- }
-+ case HCI_ACLDATA_PKT:
-+ if (count >= HCI_ACL_HDR_SIZE) {
-+ hci_acl_hdr *h = data;
-+ len = HCI_ACL_HDR_SIZE + __le16_to_cpu(h->dlen);
-+ } else
-+ return -EILSEQ;
-+ break;
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ case HCI_SCODATA_PKT:
-+ if (count >= HCI_SCO_HDR_SIZE) {
-+ hci_sco_hdr *h = data;
-+ len = HCI_SCO_HDR_SIZE + h->dlen;
-+ } else
-+ return -EILSEQ;
-+ break;
-+#endif
-+ }
-+ BT_DBG("new packet len %d", len);
-
-- /* Allocate skb */
-- if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {
-- ERR("Can't allocate mem for new packet");
-- return;
-+ skb = bluez_skb_alloc(len, GFP_ATOMIC);
-+ if (!skb) {
-+ BT_ERR("%s no memory for the packet", husb->hdev.name);
-+ return -ENOMEM;
-+ }
-+ skb->dev = (void *) &husb->hdev;
-+ skb->pkt_type = type;
-+
-+ __reassembly(husb, type) = skb;
-+
-+ scb = (void *) skb->cb;
-+ scb->expect = len;
-+ } else {
-+ /* Continuation */
-+ scb = (void *) skb->cb;
-+ len = scb->expect;
- }
-- skb->dev = (void *) &husb->hdev;
-- skb->pkt_type = HCI_EVENT_PKT;
--
-- husb->intr_skb = skb;
-- husb->intr_count = len;
-- } else {
-- /* Continuation */
-- if (count > husb->intr_count) {
-- ERR("%s bad frame len %d (expected %d)", husb->hdev.name, count, husb->intr_count);
-
-- kfree_skb(skb);
-- husb->intr_skb = NULL;
-- husb->intr_count = 0;
-- return;
-+ len = min(len, count);
-+
-+ memcpy(skb_put(skb, len), data, len);
-+
-+ scb->expect -= len;
-+ if (!scb->expect) {
-+ /* Complete frame */
-+ __reassembly(husb, type) = NULL;
-+ hci_recv_frame(skb);
- }
-- }
--
-- memcpy(skb_put(skb, count), data, count);
-- husb->intr_count -= count;
--
-- DMP(data, count);
--
-- if (!husb->intr_count) {
-- /* Got complete frame */
-
-- husb->hdev.stat.byte_rx += skb->len;
-- hci_recv_frame(skb);
--
-- husb->intr_skb = NULL;
-+ count -= len; data += len;
- }
-+ return 0;
- }
-
--static void hci_usb_bulk_read(struct urb *urb)
-+static void hci_usb_rx_complete(struct urb *urb)
- {
-- struct hci_usb *husb = (struct hci_usb *) urb->context;
-- unsigned char *data = urb->transfer_buffer;
-- int count = urb->actual_length, status;
-- struct sk_buff *skb;
-- hci_acl_hdr *ah;
-- register __u16 dlen;
--
-- if (!husb)
-- return;
-+ struct _urb *_urb = container_of(urb, struct _urb, urb);
-+ struct hci_usb *husb = (void *) urb->context;
-+ struct hci_dev *hdev = &husb->hdev;
-+ int err, count = urb->actual_length;
-
-- DBG("%s status %d, count %d, flags %x", husb->hdev.name, urb->status, count, urb->transfer_flags);
-+ BT_DBG("%s urb %p type %d status %d count %d flags %x", hdev->name, urb,
-+ _urb->type, urb->status, count, urb->transfer_flags);
-
-- if (urb->status) {
-- /* Do not re-submit URB on critical errors */
-- switch (urb->status) {
-- case -ENOENT:
-- return;
-- default:
-- goto resubmit;
-- };
-- }
-- if (!count)
-- goto resubmit;
--
-- DMP(data, count);
-+ read_lock(&husb->completion_lock);
-
-- ah = (hci_acl_hdr *) data;
-- dlen = le16_to_cpu(ah->dlen);
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ goto unlock;
-
-- /* Verify frame len and completeness */
-- if ((count - HCI_ACL_HDR_SIZE) != dlen) {
-- ERR("%s corrupted ACL packet: count %d, plen %d", husb->hdev.name, count, dlen);
-+ if (urb->status || !count)
- goto resubmit;
-- }
-
-- /* Allocate packet */
-- if (!(skb = bluez_skb_alloc(count, GFP_ATOMIC))) {
-- ERR("Can't allocate mem for new packet");
-- goto resubmit;
-+ if (_urb->type == HCI_SCODATA_PKT) {
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ int i;
-+ for (i=0; i < urb->number_of_packets; i++) {
-+ BT_DBG("desc %d status %d offset %d len %d", i,
-+ urb->iso_frame_desc[i].status,
-+ urb->iso_frame_desc[i].offset,
-+ urb->iso_frame_desc[i].actual_length);
-+
-+ if (!urb->iso_frame_desc[i].status)
-+ __recv_frame(husb, _urb->type,
-+ urb->transfer_buffer + urb->iso_frame_desc[i].offset,
-+ urb->iso_frame_desc[i].actual_length);
-+ }
-+#else
-+ ;
-+#endif
-+ } else {
-+ err = __recv_frame(husb, _urb->type, urb->transfer_buffer, count);
-+ if (err < 0) {
-+ BT_ERR("%s corrupted packet: type %d count %d",
-+ husb->hdev.name, _urb->type, count);
-+ hdev->stat.err_rx++;
-+ }
- }
-
-- memcpy(skb_put(skb, count), data, count);
-- skb->dev = (void *) &husb->hdev;
-- skb->pkt_type = HCI_ACLDATA_PKT;
--
-- husb->hdev.stat.byte_rx += skb->len;
--
-- hci_recv_frame(skb);
--
- resubmit:
-- husb->read_urb->dev = husb->udev;
-- if ((status = usb_submit_urb(husb->read_urb)))
-- DBG("%s read URB submit failed %d", husb->hdev.name, status);
-+ if (_urb->type != HCI_EVENT_PKT) {
-+ urb->dev = husb->udev;
-+ err = usb_submit_urb(urb);
-+ BT_DBG("%s urb %p type %d resubmit status %d", hdev->name, urb,
-+ _urb->type, err);
-+ }
-
-- DBG("%s read URB re-submited", husb->hdev.name);
-+unlock:
-+ read_unlock(&husb->completion_lock);
- }
-
--static int hci_usb_ctrl_msg(struct hci_usb *husb, struct sk_buff *skb)
-+static void hci_usb_tx_complete(struct urb *urb)
- {
-- struct urb *urb = husb->ctrl_urb;
-- devrequest *dr = &husb->dev_req;
-- int pipe, status;
-+ struct _urb *_urb = container_of(urb, struct _urb, urb);
-+ struct hci_usb *husb = (void *) urb->context;
-+ struct hci_dev *hdev = &husb->hdev;
-
-- DBG("%s len %d", husb->hdev.name, skb->len);
-+ BT_DBG("%s urb %p status %d flags %x", hdev->name, urb,
-+ urb->status, urb->transfer_flags);
-
-- pipe = usb_sndctrlpipe(husb->udev, 0);
-+ atomic_dec(__pending_tx(husb, _urb->type));
-
-- dr->requesttype = HCI_CTRL_REQ;
-- dr->request = 0;
-- dr->index = 0;
-- dr->value = 0;
-- dr->length = cpu_to_le16(skb->len);
--
-- FILL_CONTROL_URB(urb, husb->udev, pipe, (void*)dr, skb->data, skb->len,
-- hci_usb_ctrl, skb);
-+ urb->transfer_buffer = NULL;
-+ kfree_skb((struct sk_buff *) _urb->priv);
-
-- if ((status = usb_submit_urb(urb))) {
-- DBG("%s control URB submit failed %d", husb->hdev.name, status);
-- return status;
-- }
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return;
-
-- return 0;
--}
-+ if (!urb->status)
-+ hdev->stat.byte_tx += urb->transfer_buffer_length;
-+ else
-+ hdev->stat.err_tx++;
-
--static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb)
--{
-- struct urb *urb = husb->write_urb;
-- int pipe, status;
-+ read_lock(&husb->completion_lock);
-
-- DBG("%s len %d", husb->hdev.name, skb->len);
-+ _urb_unlink(_urb);
-+ _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
-
-- pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep_addr);
-+ hci_usb_tx_wakeup(husb);
-+
-+ read_unlock(&husb->completion_lock);
-+}
-
-- FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,
-- hci_usb_bulk_write, skb);
-- urb->transfer_flags |= USB_QUEUE_BULK;
-+static void hci_usb_destruct(struct hci_dev *hdev)
-+{
-+ struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-
-- if ((status = usb_submit_urb(urb))) {
-- DBG("%s write URB submit failed %d", husb->hdev.name, status);
-- return status;
-- }
-+ BT_DBG("%s", hdev->name);
-
-- return 0;
-+ kfree(husb);
- }
-
--static void * hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
-+static void *hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
- {
-- struct usb_endpoint_descriptor *bulk_out_ep, *intr_in_ep, *bulk_in_ep;
-+ struct usb_endpoint_descriptor *bulk_out_ep[HCI_MAX_IFACE_NUM];
-+ struct usb_endpoint_descriptor *isoc_out_ep[HCI_MAX_IFACE_NUM];
-+ struct usb_endpoint_descriptor *bulk_in_ep[HCI_MAX_IFACE_NUM];
-+ struct usb_endpoint_descriptor *isoc_in_ep[HCI_MAX_IFACE_NUM];
-+ struct usb_endpoint_descriptor *intr_in_ep[HCI_MAX_IFACE_NUM];
- struct usb_interface_descriptor *uif;
- struct usb_endpoint_descriptor *ep;
-+ struct usb_interface *iface, *isoc_iface;
- struct hci_usb *husb;
- struct hci_dev *hdev;
-- int i, size, pipe;
-- __u8 * buf;
-+ int i, a, e, size, ifn, isoc_ifnum, isoc_alts;
-
-- DBG("udev %p ifnum %d", udev, ifnum);
-+ BT_DBG("udev %p ifnum %d", udev, ifnum);
-
-- /* Check device signature */
-- if ((udev->descriptor.bDeviceClass != HCI_DEV_CLASS) ||
-- (udev->descriptor.bDeviceSubClass != HCI_DEV_SUBCLASS)||
-- (udev->descriptor.bDeviceProtocol != HCI_DEV_PROTOCOL) )
-- return NULL;
-+ iface = &udev->actconfig->interface[0];
-
-- MOD_INC_USE_COUNT;
--
-- uif = &udev->actconfig->interface[ifnum].altsetting[0];
-+ if (!id->driver_info) {
-+ const struct usb_device_id *match;
-+ match = usb_match_id(udev, iface, blacklist_ids);
-+ if (match)
-+ id = match;
-+ }
-
-- if (uif->bNumEndpoints != 3) {
-- DBG("Wrong number of endpoints %d", uif->bNumEndpoints);
-- MOD_DEC_USE_COUNT;
-+ if (id->driver_info & HCI_IGNORE)
- return NULL;
-- }
-
-- bulk_out_ep = intr_in_ep = bulk_in_ep = NULL;
-+ /* Check number of endpoints */
-+ if (udev->actconfig->interface[ifnum].altsetting[0].bNumEndpoints < 3)
-+ return NULL;
-
-+ memset(bulk_out_ep, 0, sizeof(bulk_out_ep));
-+ memset(isoc_out_ep, 0, sizeof(isoc_out_ep));
-+ memset(bulk_in_ep, 0, sizeof(bulk_in_ep));
-+ memset(isoc_in_ep, 0, sizeof(isoc_in_ep));
-+ memset(intr_in_ep, 0, sizeof(intr_in_ep));
-+
-+ size = 0;
-+ isoc_iface = NULL;
-+ isoc_alts = isoc_ifnum = 0;
-+
- /* Find endpoints that we need */
-- for ( i = 0; i < uif->bNumEndpoints; ++i) {
-- ep = &uif->endpoint[i];
-
-- switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
-- case USB_ENDPOINT_XFER_BULK:
-- if (ep->bEndpointAddress & USB_DIR_IN)
-- bulk_in_ep = ep;
-- else
-- bulk_out_ep = ep;
-- break;
-+ ifn = MIN(udev->actconfig->bNumInterfaces, HCI_MAX_IFACE_NUM);
-+ for (i = 0; i < ifn; i++) {
-+ iface = &udev->actconfig->interface[i];
-+ for (a = 0; a < iface->num_altsetting; a++) {
-+ uif = &iface->altsetting[a];
-+ for (e = 0; e < uif->bNumEndpoints; e++) {
-+ ep = &uif->endpoint[e];
-+
-+ switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
-+ case USB_ENDPOINT_XFER_INT:
-+ if (ep->bEndpointAddress & USB_DIR_IN)
-+ intr_in_ep[i] = ep;
-+ break;
-+
-+ case USB_ENDPOINT_XFER_BULK:
-+ if (ep->bEndpointAddress & USB_DIR_IN)
-+ bulk_in_ep[i] = ep;
-+ else
-+ bulk_out_ep[i] = ep;
-+ break;
-+
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ case USB_ENDPOINT_XFER_ISOC:
-+ if (ep->wMaxPacketSize < size || a > 2)
-+ break;
-+ size = ep->wMaxPacketSize;
-+
-+ isoc_iface = iface;
-+ isoc_alts = a;
-+ isoc_ifnum = i;
-+
-+ if (ep->bEndpointAddress & USB_DIR_IN)
-+ isoc_in_ep[i] = ep;
-+ else
-+ isoc_out_ep[i] = ep;
-+ break;
-+#endif
-+ }
-+ }
-+ }
-+ }
-
-- case USB_ENDPOINT_XFER_INT:
-- intr_in_ep = ep;
-- break;
-- };
-+ if (!bulk_in_ep[0] || !bulk_out_ep[0] || !intr_in_ep[0]) {
-+ BT_DBG("Bulk endpoints not found");
-+ goto done;
- }
-
-- if (!bulk_in_ep || !bulk_out_ep || !intr_in_ep) {
-- DBG("Endpoints not found: %p %p %p", bulk_in_ep, bulk_out_ep, intr_in_ep);
-- MOD_DEC_USE_COUNT;
-- return NULL;
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ if (id->driver_info & HCI_BROKEN_ISOC || !isoc_in_ep[1] || !isoc_out_ep[1]) {
-+ BT_DBG("Isoc endpoints not found");
-+ isoc_iface = NULL;
- }
-+#endif
-
- if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
-- ERR("Can't allocate: control structure");
-- MOD_DEC_USE_COUNT;
-- return NULL;
-+ BT_ERR("Can't allocate: control structure");
-+ goto done;
- }
-
- memset(husb, 0, sizeof(struct hci_usb));
-
- husb->udev = udev;
-- husb->bulk_out_ep_addr = bulk_out_ep->bEndpointAddress;
--
-- if (!(husb->ctrl_urb = usb_alloc_urb(0))) {
-- ERR("Can't allocate: control URB");
-- goto probe_error;
-- }
--
-- if (!(husb->write_urb = usb_alloc_urb(0))) {
-- ERR("Can't allocate: write URB");
-- goto probe_error;
-- }
--
-- if (!(husb->read_urb = usb_alloc_urb(0))) {
-- ERR("Can't allocate: read URB");
-- goto probe_error;
-- }
--
-- ep = bulk_in_ep;
-- pipe = usb_rcvbulkpipe(udev, ep->bEndpointAddress);
-- size = HCI_MAX_FRAME_SIZE;
--
-- if (!(buf = kmalloc(size, GFP_KERNEL))) {
-- ERR("Can't allocate: read buffer");
-- goto probe_error;
-- }
--
-- FILL_BULK_URB(husb->read_urb, udev, pipe, buf, size, hci_usb_bulk_read, husb);
-- husb->read_urb->transfer_flags |= USB_QUEUE_BULK;
--
-- ep = intr_in_ep;
-- pipe = usb_rcvintpipe(udev, ep->bEndpointAddress);
-- size = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
--
-- if (!(husb->intr_urb = usb_alloc_urb(0))) {
-- ERR("Can't allocate: interrupt URB");
-- goto probe_error;
-+ husb->bulk_out_ep = bulk_out_ep[0];
-+ husb->bulk_in_ep = bulk_in_ep[0];
-+ husb->intr_in_ep = intr_in_ep[0];
-+
-+ if (id->driver_info & HCI_DIGIANSWER)
-+ husb->ctrl_req = HCI_DIGI_REQ;
-+ else
-+ husb->ctrl_req = HCI_CTRL_REQ;
-+
-+#ifdef CONFIG_BLUEZ_HCIUSB_SCO
-+ if (isoc_iface) {
-+ BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, isoc_alts);
-+ if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) {
-+ BT_ERR("Can't set isoc interface settings");
-+ isoc_iface = NULL;
-+ }
-+ usb_driver_claim_interface(&hci_usb_driver, isoc_iface, husb);
-+ husb->isoc_iface = isoc_iface;
-+ husb->isoc_in_ep = isoc_in_ep[isoc_ifnum];
-+ husb->isoc_out_ep = isoc_out_ep[isoc_ifnum];
- }
-+#endif
-+
-+ husb->completion_lock = RW_LOCK_UNLOCKED;
-
-- if (!(buf = kmalloc(size, GFP_KERNEL))) {
-- ERR("Can't allocate: interrupt buffer");
-- goto probe_error;
-+ for (i = 0; i < 4; i++) {
-+ skb_queue_head_init(&husb->transmit_q[i]);
-+ _urb_queue_init(&husb->pending_q[i]);
-+ _urb_queue_init(&husb->completed_q[i]);
- }
-
-- FILL_INT_URB(husb->intr_urb, udev, pipe, buf, size, hci_usb_intr, husb, ep->bInterval);
--
-- skb_queue_head_init(&husb->tx_ctrl_q);
-- skb_queue_head_init(&husb->tx_write_q);
--
- /* Initialize and register HCI device */
- hdev = &husb->hdev;
-
-- hdev->type = HCI_USB;
-+ hdev->type = HCI_USB;
- hdev->driver_data = husb;
-
- hdev->open = hci_usb_open;
- hdev->close = hci_usb_close;
- hdev->flush = hci_usb_flush;
-- hdev->send = hci_usb_send_frame;
-+ hdev->send = hci_usb_send_frame;
-+ hdev->destruct = hci_usb_destruct;
-+
-+ if (id->driver_info & HCI_RESET)
-+ set_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks);
-
- if (hci_register_dev(hdev) < 0) {
-- ERR("Can't register HCI device %s", hdev->name);
-+ BT_ERR("Can't register HCI device");
- goto probe_error;
- }
-
- return husb;
-
- probe_error:
-- hci_usb_free_bufs(husb);
- kfree(husb);
-- MOD_DEC_USE_COUNT;
-+
-+done:
- return NULL;
- }
-
-@@ -626,38 +967,34 @@
- if (!husb)
- return;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s", hdev->name);
-
- hci_usb_close(hdev);
-
-- if (hci_unregister_dev(hdev) < 0) {
-- ERR("Can't unregister HCI device %s", hdev->name);
-- }
-+ if (husb->isoc_iface)
-+ usb_driver_release_interface(&hci_usb_driver, husb->isoc_iface);
-
-- hci_usb_free_bufs(husb);
-- kfree(husb);
--
-- MOD_DEC_USE_COUNT;
-+ if (hci_unregister_dev(hdev) < 0)
-+ BT_ERR("Can't unregister HCI device %s", hdev->name);
- }
-
--static struct usb_driver hci_usb_driver =
--{
-+static struct usb_driver hci_usb_driver = {
- name: "hci_usb",
- probe: hci_usb_probe,
- disconnect: hci_usb_disconnect,
-- id_table: usb_bluetooth_ids,
-+ id_table: bluetooth_ids,
- };
-
- int hci_usb_init(void)
- {
- int err;
-
-- INF("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-+ BT_INFO("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-
- if ((err = usb_register(&hci_usb_driver)) < 0)
-- ERR("Failed to register HCI USB driver");
-+ BT_ERR("Failed to register HCI USB driver");
-
- return err;
- }
-@@ -670,6 +1007,6 @@
- module_init(hci_usb_init);
- module_exit(hci_usb_cleanup);
-
--MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
- MODULE_DESCRIPTION("BlueZ HCI USB driver ver " VERSION);
- MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/drivers/bluetooth/hci_usb.h linux-2.4.18-mh15/drivers/bluetooth/hci_usb.h
---- linux-2.4.18/drivers/bluetooth/hci_usb.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_usb.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,147 @@
-+/*
-+ HCI USB driver for Linux Bluetooth protocol stack (BlueZ)
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ Copyright (C) 2003 Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifdef __KERNEL__
-+
-+/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
-+#define HCI_DEV_CLASS 0xe0 /* Wireless class */
-+#define HCI_DEV_SUBCLASS 0x01 /* RF subclass */
-+#define HCI_DEV_PROTOCOL 0x01 /* Bluetooth programming protocol */
-+
-+#define HCI_CTRL_REQ 0x20
-+#define HCI_DIGI_REQ 0x40
-+
-+#define HCI_IGNORE 0x01
-+#define HCI_RESET 0x02
-+#define HCI_DIGIANSWER 0x04
-+#define HCI_BROKEN_ISOC 0x08
-+
-+#define HCI_MAX_IFACE_NUM 3
-+
-+#define HCI_MAX_BULK_TX 4
-+#define HCI_MAX_BULK_RX 1
-+
-+#define HCI_MAX_ISOC_RX 2
-+#define HCI_MAX_ISOC_TX 2
-+
-+#define HCI_MAX_ISOC_FRAMES 10
-+
-+struct _urb_queue {
-+ struct list_head head;
-+ spinlock_t lock;
-+};
-+
-+struct _urb {
-+ struct list_head list;
-+ struct _urb_queue *queue;
-+ int type;
-+ void *priv;
-+ struct urb urb;
-+};
-+
-+struct _urb *_urb_alloc(int isoc, int gfp);
-+
-+static inline void _urb_free(struct _urb *_urb)
-+{
-+ kfree(_urb);
-+}
-+
-+static inline void _urb_queue_init(struct _urb_queue *q)
-+{
-+ INIT_LIST_HEAD(&q->head);
-+ spin_lock_init(&q->lock);
-+}
-+
-+static inline void _urb_queue_head(struct _urb_queue *q, struct _urb *_urb)
-+{
-+ unsigned long flags;
-+ spin_lock_irqsave(&q->lock, flags);
-+ list_add(&_urb->list, &q->head); _urb->queue = q;
-+ spin_unlock_irqrestore(&q->lock, flags);
-+}
-+
-+static inline void _urb_queue_tail(struct _urb_queue *q, struct _urb *_urb)
-+{
-+ unsigned long flags;
-+ spin_lock_irqsave(&q->lock, flags);
-+ list_add_tail(&_urb->list, &q->head); _urb->queue = q;
-+ spin_unlock_irqrestore(&q->lock, flags);
-+}
-+
-+static inline void _urb_unlink(struct _urb *_urb)
-+{
-+ struct _urb_queue *q = _urb->queue;
-+ unsigned long flags;
-+ if (q) {
-+ spin_lock_irqsave(&q->lock, flags);
-+ list_del(&_urb->list); _urb->queue = NULL;
-+ spin_unlock_irqrestore(&q->lock, flags);
-+ }
-+}
-+
-+struct _urb *_urb_dequeue(struct _urb_queue *q);
-+
-+#ifndef container_of
-+#define container_of(ptr, type, member) ({ \
-+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
-+ (type *)( (char *)__mptr - offsetof(type,member) );})
-+#endif
-+
-+struct hci_usb {
-+ struct hci_dev hdev;
-+
-+ unsigned long state;
-+
-+ struct usb_device *udev;
-+
-+ struct usb_endpoint_descriptor *bulk_in_ep;
-+ struct usb_endpoint_descriptor *bulk_out_ep;
-+ struct usb_endpoint_descriptor *intr_in_ep;
-+
-+ struct usb_interface *isoc_iface;
-+ struct usb_endpoint_descriptor *isoc_out_ep;
-+ struct usb_endpoint_descriptor *isoc_in_ep;
-+
-+ __u8 ctrl_req;
-+
-+ struct sk_buff_head transmit_q[4];
-+ struct sk_buff *reassembly[4]; // Reassembly buffers
-+
-+ rwlock_t completion_lock;
-+
-+ atomic_t pending_tx[4]; // Number of pending requests
-+ struct _urb_queue pending_q[4]; // Pending requests
-+ struct _urb_queue completed_q[4]; // Completed requests
-+};
-+
-+/* States */
-+#define HCI_USB_TX_PROCESS 1
-+#define HCI_USB_TX_WAKEUP 2
-+
-+#endif /* __KERNEL__ */
-diff -urN linux-2.4.18/drivers/bluetooth/hci_vhci.c linux-2.4.18-mh15/drivers/bluetooth/hci_vhci.c
---- linux-2.4.18/drivers/bluetooth/hci_vhci.c 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_vhci.c 2004-08-01 16:26:23.000000000 +0200
-@@ -25,9 +25,9 @@
- /*
- * BlueZ HCI virtual device driver.
- *
-- * $Id$
-+ * $Id$
- */
--#define VERSION "1.0"
-+#define VERSION "1.1"
-
- #include <linux/config.h>
- #include <linux/module.h>
-@@ -49,43 +49,56 @@
- #include <asm/uaccess.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/hci_vhci.h>
-+#include "hci_vhci.h"
-
- /* HCI device part */
-
--int hci_vhci_open(struct hci_dev *hdev)
-+static int hci_vhci_open(struct hci_dev *hdev)
- {
-- hdev->flags |= HCI_RUNNING;
-+ set_bit(HCI_RUNNING, &hdev->flags);
- return 0;
- }
-
--int hci_vhci_flush(struct hci_dev *hdev)
-+static int hci_vhci_flush(struct hci_dev *hdev)
- {
- struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
- skb_queue_purge(&hci_vhci->readq);
- return 0;
- }
-
--int hci_vhci_close(struct hci_dev *hdev)
-+static int hci_vhci_close(struct hci_dev *hdev)
- {
-- hdev->flags &= ~HCI_RUNNING;
-+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-+
- hci_vhci_flush(hdev);
- return 0;
- }
-
--int hci_vhci_send_frame(struct sk_buff *skb)
-+static void hci_vhci_destruct(struct hci_dev *hdev)
-+{
-+ struct hci_vhci_struct *vhci;
-+
-+ if (!hdev) return;
-+
-+ vhci = (struct hci_vhci_struct *) hdev->driver_data;
-+ kfree(vhci);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static int hci_vhci_send_frame(struct sk_buff *skb)
- {
- struct hci_dev* hdev = (struct hci_dev *) skb->dev;
- struct hci_vhci_struct *hci_vhci;
-
- if (!hdev) {
-- ERR("Frame for uknown device (hdev=NULL)");
-+ BT_ERR("Frame for uknown device (hdev=NULL)");
- return -ENODEV;
- }
-
-- if (!(hdev->flags & HCI_RUNNING))
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
- return -EBUSY;
-
- hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
-@@ -188,7 +201,7 @@
-
- add_wait_queue(&hci_vhci->read_wait, &wait);
- while (count) {
-- current->state = TASK_INTERRUPTIBLE;
-+ set_current_state(TASK_INTERRUPTIBLE);
-
- /* Read frames from device queue */
- if (!(skb = skb_dequeue(&hci_vhci->readq))) {
-@@ -214,8 +227,7 @@
- kfree_skb(skb);
- break;
- }
--
-- current->state = TASK_RUNNING;
-+ set_current_state(TASK_RUNNING);
- remove_wait_queue(&hci_vhci->read_wait, &wait);
-
- return ret;
-@@ -270,11 +282,13 @@
- hdev->close = hci_vhci_close;
- hdev->flush = hci_vhci_flush;
- hdev->send = hci_vhci_send_frame;
-+ hdev->destruct = hci_vhci_destruct;
-
- if (hci_register_dev(hdev) < 0) {
- kfree(hci_vhci);
- return -EBUSY;
- }
-+ MOD_INC_USE_COUNT;
-
- file->private_data = hci_vhci;
- return 0;
-@@ -285,12 +299,10 @@
- struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
-
- if (hci_unregister_dev(&hci_vhci->hdev) < 0) {
-- ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
-+ BT_ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
- }
-
-- kfree(hci_vhci);
- file->private_data = NULL;
--
- return 0;
- }
-
-@@ -315,12 +327,12 @@
-
- int __init hci_vhci_init(void)
- {
-- INF("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-+ BT_INFO("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-
- if (misc_register(&hci_vhci_miscdev)) {
-- ERR("Can't register misc device %d\n", VHCI_MINOR);
-+ BT_ERR("Can't register misc device %d\n", VHCI_MINOR);
- return -EIO;
- }
-
-@@ -337,4 +349,4 @@
-
- MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
- MODULE_DESCRIPTION("BlueZ VHCI driver ver " VERSION);
--MODULE_LICENSE("GPL");
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/drivers/bluetooth/hci_vhci.h linux-2.4.18-mh15/drivers/bluetooth/hci_vhci.h
---- linux-2.4.18/drivers/bluetooth/hci_vhci.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/hci_vhci.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,50 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef __HCI_VHCI_H
-+#define __HCI_VHCI_H
-+
-+#ifdef __KERNEL__
-+
-+struct hci_vhci_struct {
-+ struct hci_dev hdev;
-+ __u32 flags;
-+ wait_queue_head_t read_wait;
-+ struct sk_buff_head readq;
-+ struct fasync_struct *fasync;
-+};
-+
-+/* VHCI device flags */
-+#define VHCI_FASYNC 0x0010
-+
-+#endif /* __KERNEL__ */
-+
-+#define VHCI_DEV "/dev/vhci"
-+#define VHCI_MINOR 250
-+
-+#endif /* __HCI_VHCI_H */
-diff -urN linux-2.4.18/drivers/bluetooth/Makefile linux-2.4.18-mh15/drivers/bluetooth/Makefile
---- linux-2.4.18/drivers/bluetooth/Makefile 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/drivers/bluetooth/Makefile 2004-08-01 16:26:23.000000000 +0200
-@@ -1,11 +1,27 @@
- #
--# Makefile for Bluetooth HCI device drivers.
-+# Makefile for the Linux Bluetooth HCI device drivers
- #
-
- O_TARGET := bluetooth.o
-
-+list-multi := hci_uart.o
-+
- obj-$(CONFIG_BLUEZ_HCIUSB) += hci_usb.o
--obj-$(CONFIG_BLUEZ_HCIUART) += hci_uart.o
- obj-$(CONFIG_BLUEZ_HCIVHCI) += hci_vhci.o
-
-+obj-$(CONFIG_BLUEZ_HCIUART) += hci_uart.o
-+uart-y := hci_ldisc.o
-+uart-$(CONFIG_BLUEZ_HCIUART_H4) += hci_h4.o
-+uart-$(CONFIG_BLUEZ_HCIUART_BCSP) += hci_bcsp.o
-+
-+obj-$(CONFIG_BLUEZ_HCIBFUSB) += bfusb.o
-+
-+obj-$(CONFIG_BLUEZ_HCIDTL1) += dtl1_cs.o
-+obj-$(CONFIG_BLUEZ_HCIBT3C) += bt3c_cs.o
-+obj-$(CONFIG_BLUEZ_HCIBLUECARD) += bluecard_cs.o
-+obj-$(CONFIG_BLUEZ_HCIBTUART) += btuart_cs.o
-+
- include $(TOPDIR)/Rules.make
-+
-+hci_uart.o: $(uart-y)
-+ $(LD) -r -o $@ $(uart-y)
-diff -urN linux-2.4.18/drivers/bluetooth/Makefile.lib linux-2.4.18-mh15/drivers/bluetooth/Makefile.lib
---- linux-2.4.18/drivers/bluetooth/Makefile.lib 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/bluetooth/Makefile.lib 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,2 @@
-+obj-$(CONFIG_BLUEZ_HCIBFUSB) += firmware_class.o
-+obj-$(CONFIG_BLUEZ_HCIBT3C) += firmware_class.o
-diff -urN linux-2.4.18/drivers/char/pcmcia/serial_cs.c linux-2.4.18-mh15/drivers/char/pcmcia/serial_cs.c
---- linux-2.4.18/drivers/char/pcmcia/serial_cs.c 2001-12-21 18:41:54.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/char/pcmcia/serial_cs.c 2004-08-01 16:26:23.000000000 +0200
-@@ -2,7 +2,7 @@
-
- A driver for PCMCIA serial devices
-
-- serial_cs.c 1.128 2001/10/18 12:18:35
-+ serial_cs.c 1.138 2002/10/25 06:24:52
-
- The contents of this file are subject to the Mozilla Public
- License Version 1.1 (the "License"); you may not use this file
-@@ -69,14 +69,14 @@
- static int irq_list[4] = { -1 };
- MODULE_PARM(irq_list, "1-4i");
-
--/* Enable the speaker? */
--INT_MODULE_PARM(do_sound, 1);
-+INT_MODULE_PARM(do_sound, 1); /* Enable the speaker? */
-+INT_MODULE_PARM(buggy_uart, 0); /* Skip strict UART tests? */
-
- #ifdef PCMCIA_DEBUG
- INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
- #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
- static char *version =
--"serial_cs.c 1.128 2001/10/18 12:18:35 (David Hinds)";
-+"serial_cs.c 1.138 2002/10/25 06:24:52 (David Hinds)";
- #else
- #define DEBUG(n, args...)
- #endif
-@@ -95,6 +95,7 @@
- { MANFID_OMEGA, PRODID_OMEGA_QSP_100, 4 },
- { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232, 2 },
- { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 },
-+ { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D2, 2 },
- { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS232, 4 },
- { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS422, 2 },
- { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS422, 4 },
-@@ -148,7 +149,7 @@
- client_reg_t client_reg;
- dev_link_t *link;
- int i, ret;
--
-+
- DEBUG(0, "serial_attach()\n");
-
- /* Create new serial device */
-@@ -160,7 +161,7 @@
- link->release.function = &serial_release;
- link->release.data = (u_long)link;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-- link->io.NumPorts1 = 8;
-+ link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
- link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
- if (irq_list[0] == -1)
-@@ -169,13 +170,12 @@
- for (i = 0; i < 4; i++)
- link->irq.IRQInfo2 |= 1 << irq_list[i];
- link->conf.Attributes = CONF_ENABLE_IRQ;
-- link->conf.Vcc = 50;
- if (do_sound) {
- link->conf.Attributes |= CONF_ENABLE_SPKR;
- link->conf.Status = CCSR_AUDIO_ENA;
- }
- link->conf.IntType = INT_MEMORY_AND_IO;
--
-+
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
-@@ -194,7 +194,7 @@
- serial_detach(link);
- return NULL;
- }
--
-+
- return link;
- } /* serial_attach */
-
-@@ -214,7 +214,7 @@
- int ret;
-
- DEBUG(0, "serial_detach(0x%p)\n", link);
--
-+
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
-@@ -224,17 +224,17 @@
- del_timer(&link->release);
- if (link->state & DEV_CONFIG)
- serial_release((u_long)link);
--
-+
- if (link->handle) {
- ret = CardServices(DeregisterClient, link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
- }
--
-+
- /* Unlink device structure, free bits */
- *linkp = link->next;
- kfree(info);
--
-+
- } /* serial_detach */
-
- /*====================================================================*/
-@@ -243,18 +243,20 @@
- {
- struct serial_struct serial;
- int line;
--
-+
- memset(&serial, 0, sizeof(serial));
- serial.port = port;
- serial.irq = irq;
- serial.flags = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ;
-+ if (buggy_uart)
-+ serial.flags |= ASYNC_BUGGY_UART;
- line = register_serial(&serial);
- if (line < 0) {
- printk(KERN_NOTICE "serial_cs: register_serial() at 0x%04lx,"
- " irq %d failed\n", (u_long)serial.port, serial.irq);
- return -1;
- }
--
-+
- info->line[info->ndev] = line;
- sprintf(info->node[info->ndev].dev_name, "ttyS%d", line);
- info->node[info->ndev].major = TTY_MAJOR;
-@@ -262,7 +264,7 @@
- if (info->ndev > 0)
- info->node[info->ndev-1].next = &info->node[info->ndev];
- info->ndev++;
--
-+
- return 0;
- }
-
-@@ -313,7 +315,10 @@
- return setup_serial(info, port, config.AssignedIRQ);
- }
- link->conf.Vcc = config.Vcc;
--
-+
-+ link->io.NumPorts1 = 8;
-+ link->io.NumPorts2 = 0;
-+
- /* First pass: look for a config entry that looks normal. */
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
-@@ -340,7 +345,7 @@
- i = next_tuple(handle, &tuple, &parse);
- }
- }
--
-+
- /* Second pass: try to find an entry that isn't picky about
- its base address, then try to grab any standard serial port
- address, and finally try to get any free port. */
-@@ -352,8 +357,7 @@
- for (j = 0; j < 5; j++) {
- link->io.BasePort1 = base[j];
- link->io.IOAddrLines = base[j] ? 16 : 3;
-- i = CardServices(RequestIO, link->handle,
-- &link->io);
-+ i = CardServices(RequestIO, link->handle, &link->io);
- if (i == CS_SUCCESS) goto found_port;
- }
- }
-@@ -365,7 +369,7 @@
- cs_error(link->handle, RequestIO, i);
- return -1;
- }
--
-+
- i = CardServices(RequestIRQ, link->handle, &link->irq);
- if (i != CS_SUCCESS) {
- cs_error(link->handle, RequestIRQ, i);
-@@ -390,8 +394,12 @@
- u_char buf[256];
- cisparse_t parse;
- cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
- int i, base2 = 0;
-
-+ CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
-@@ -433,12 +441,12 @@
- i = next_tuple(handle, &tuple, &parse);
- }
- }
--
-+
- if (i != CS_SUCCESS) {
-- cs_error(link->handle, RequestIO, i);
-- return -1;
-+ /* At worst, try to configure as a single port */
-+ return simple_config(link);
- }
--
-+
- i = CardServices(RequestIRQ, link->handle, &link->irq);
- if (i != CS_SUCCESS) {
- cs_error(link->handle, RequestIRQ, i);
-@@ -454,14 +462,27 @@
- cs_error(link->handle, RequestConfiguration, i);
- return -1;
- }
--
-+
-+ /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
-+ 8 registers are for the UART, the others are extra registers */
-+ if (info->manfid == MANFID_OXSEMI) {
-+ if (cf->index == 1 || cf->index == 3) {
-+ setup_serial(info, base2, link->irq.AssignedIRQ);
-+ outb(12,link->io.BasePort1+1);
-+ } else {
-+ setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
-+ outb(12,base2+1);
-+ }
-+ return 0;
-+ }
-+
- setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
- /* The Nokia cards are not really multiport cards */
- if (info->manfid == MANFID_NOKIA)
- return 0;
- for (i = 0; i < info->multi-1; i++)
- setup_serial(info, base2+(8*i), link->irq.AssignedIRQ);
--
-+
- return 0;
- }
-
-@@ -500,7 +521,7 @@
- }
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
--
-+
- /* Configure card */
- link->state |= DEV_CONFIG;
-
-@@ -508,8 +529,8 @@
- tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
- tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
- info->multi = (first_tuple(handle, &tuple, &parse) == CS_SUCCESS);
--
-- /* Is this a multiport card? */
-+
-+ /* Scan list of known multiport card ID's */
- tuple.DesiredTuple = CISTPL_MANFID;
- if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
- info->manfid = le16_to_cpu(buf[0]);
-@@ -537,15 +558,15 @@
- info->multi = 2;
- }
- }
--
-+
- if (info->multi > 1)
- multi_config(link);
- else
- simple_config(link);
--
-+
- if (info->ndev == 0)
- goto failed;
--
-+
- if (info->manfid == MANFID_IBM) {
- conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
- CS_CHECK(AccessConfigurationRegister, link->handle, &reg);
-@@ -562,6 +583,7 @@
- cs_error(link->handle, last_fn, last_ret);
- failed:
- serial_release((u_long)link);
-+ link->state &= ~DEV_CONFIG_PENDING;
-
- } /* serial_config */
-
-@@ -569,7 +591,7 @@
-
- After a card is removed, serial_release() will unregister the net
- device, and release the PCMCIA configuration.
--
-+
- ======================================================================*/
-
- void serial_release(u_long arg)
-@@ -577,7 +599,7 @@
- dev_link_t *link = (dev_link_t *)arg;
- serial_info_t *info = link->priv;
- int i;
--
-+
- DEBUG(0, "serial_release(0x%p)\n", link);
-
- for (i = 0; i < info->ndev; i++) {
-@@ -590,7 +612,7 @@
- CardServices(ReleaseIO, link->handle, &link->io);
- CardServices(ReleaseIRQ, link->handle, &link->irq);
- }
--
-+
- link->state &= ~DEV_CONFIG;
-
- } /* serial_release */
-@@ -601,7 +623,7 @@
- stuff to run after an event is received. A CARD_REMOVAL event
- also sets some flags to discourage the serial drivers from
- talking to the ports.
--
-+
- ======================================================================*/
-
- static int serial_event(event_t event, int priority,
-@@ -609,9 +631,9 @@
- {
- dev_link_t *link = args->client_data;
- serial_info_t *info = link->priv;
--
-+
- DEBUG(1, "serial_event(0x%06x)\n", event);
--
-+
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
-@@ -650,7 +672,7 @@
- if (serv.Revision != CS_RELEASE_CODE) {
- printk(KERN_NOTICE "serial_cs: Card Services release "
- "does not match!\n");
-- return -1;
-+ return -EINVAL;
- }
- register_pccard_driver(&dev_info, &serial_attach, &serial_detach);
- return 0;
-diff -urN linux-2.4.18/drivers/input/Config.in linux-2.4.18-mh15/drivers/input/Config.in
---- linux-2.4.18/drivers/input/Config.in 2001-09-13 00:34:06.000000000 +0200
-+++ linux-2.4.18-mh15/drivers/input/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -14,5 +14,6 @@
- fi
- dep_tristate ' Joystick support' CONFIG_INPUT_JOYDEV $CONFIG_INPUT
- dep_tristate ' Event interface support' CONFIG_INPUT_EVDEV $CONFIG_INPUT
-+dep_tristate ' User level driver support' CONFIG_INPUT_UINPUT $CONFIG_INPUT
-
- endmenu
-diff -urN linux-2.4.18/drivers/input/keybdev.c linux-2.4.18-mh15/drivers/input/keybdev.c
---- linux-2.4.18/drivers/input/keybdev.c 2001-10-11 18:14:32.000000000 +0200
-+++ linux-2.4.18-mh15/drivers/input/keybdev.c 2004-08-01 16:26:23.000000000 +0200
-@@ -154,16 +154,18 @@
-
- static struct input_handler keybdev_handler;
-
-+static unsigned int ledstate = 0xff;
-+
- void keybdev_ledfunc(unsigned int led)
- {
- struct input_handle *handle;
-
-- for (handle = keybdev_handler.handle; handle; handle = handle->hnext) {
-+ ledstate = led;
-
-+ for (handle = keybdev_handler.handle; handle; handle = handle->hnext) {
- input_event(handle->dev, EV_LED, LED_SCROLLL, !!(led & 0x01));
- input_event(handle->dev, EV_LED, LED_NUML, !!(led & 0x02));
- input_event(handle->dev, EV_LED, LED_CAPSL, !!(led & 0x04));
--
- }
- }
-
-@@ -202,6 +204,12 @@
-
- // printk(KERN_INFO "keybdev.c: Adding keyboard: input%d\n", dev->number);
-
-+ if (ledstate != 0xff) {
-+ input_event(dev, EV_LED, LED_SCROLLL, !!(ledstate & 0x01));
-+ input_event(dev, EV_LED, LED_NUML, !!(ledstate & 0x02));
-+ input_event(dev, EV_LED, LED_CAPSL, !!(ledstate & 0x04));
-+ }
-+
- return handle;
- }
-
-diff -urN linux-2.4.18/drivers/input/Makefile linux-2.4.18-mh15/drivers/input/Makefile
---- linux-2.4.18/drivers/input/Makefile 2000-12-29 23:07:22.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/input/Makefile 2004-08-01 16:26:23.000000000 +0200
-@@ -24,6 +24,7 @@
- obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
- obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
- obj-$(CONFIG_INPUT_EVDEV) += evdev.o
-+obj-$(CONFIG_INPUT_UINPUT) += uinput.o
-
- # The global Rules.make.
-
-diff -urN linux-2.4.18/drivers/input/uinput.c linux-2.4.18-mh15/drivers/input/uinput.c
---- linux-2.4.18/drivers/input/uinput.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/input/uinput.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,428 @@
-+/*
-+ * User level driver support for input subsystem
-+ *
-+ * Heavily based on evdev.c by Vojtech Pavlik
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
-+ *
-+ * Changes/Revisions:
-+ * 0.1 20/06/2002
-+ * - first public version
-+ */
-+
-+#include <linux/poll.h>
-+#include <linux/slab.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/input.h>
-+#include <linux/smp_lock.h>
-+#include <linux/fs.h>
-+#include <linux/miscdevice.h>
-+#include <linux/uinput.h>
-+
-+static int uinput_dev_open(struct input_dev *dev)
-+{
-+ return 0;
-+}
-+
-+static void uinput_dev_close(struct input_dev *dev)
-+{
-+}
-+
-+static int uinput_dev_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
-+{
-+ struct uinput_device *udev;
-+
-+ udev = (struct uinput_device *)dev->private;
-+
-+ udev->buff[udev->head].type = type;
-+ udev->buff[udev->head].code = code;
-+ udev->buff[udev->head].value = value;
-+ do_gettimeofday(&udev->buff[udev->head].time);
-+ udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE;
-+
-+ wake_up_interruptible(&udev->waitq);
-+
-+ return 0;
-+}
-+
-+static int uinput_dev_upload_effect(struct input_dev *dev, struct ff_effect *effect)
-+{
-+ return 0;
-+}
-+
-+static int uinput_dev_erase_effect(struct input_dev *dev, int effect_id)
-+{
-+ return 0;
-+}
-+
-+static int uinput_create_device(struct uinput_device *udev)
-+{
-+ if (!udev->dev->name) {
-+ printk(KERN_DEBUG "%s: write device info first\n", UINPUT_NAME);
-+ return -EINVAL;
-+ }
-+
-+ udev->dev->open = uinput_dev_open;
-+ udev->dev->close = uinput_dev_close;
-+ udev->dev->event = uinput_dev_event;
-+ udev->dev->upload_effect = uinput_dev_upload_effect;
-+ udev->dev->erase_effect = uinput_dev_erase_effect;
-+ udev->dev->private = udev;
-+
-+ init_waitqueue_head(&(udev->waitq));
-+
-+ input_register_device(udev->dev);
-+
-+ set_bit(UIST_CREATED, &(udev->state));
-+
-+ return 0;
-+}
-+
-+static int uinput_destroy_device(struct uinput_device *udev)
-+{
-+ if (!test_bit(UIST_CREATED, &(udev->state))) {
-+ printk(KERN_WARNING "%s: create the device first\n", UINPUT_NAME);
-+ return -EINVAL;
-+ }
-+
-+ input_unregister_device(udev->dev);
-+
-+ clear_bit(UIST_CREATED, &(udev->state));
-+
-+ return 0;
-+}
-+
-+static int uinput_open(struct inode *inode, struct file *file)
-+{
-+ struct uinput_device *newdev;
-+ struct input_dev *newinput;
-+
-+ newdev = kmalloc(sizeof(struct uinput_device), GFP_KERNEL);
-+ if (!newdev)
-+ goto error;
-+ memset(newdev, 0, sizeof(struct uinput_device));
-+
-+ newinput = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
-+ if (!newinput)
-+ goto cleanup;
-+ memset(newinput, 0, sizeof(struct input_dev));
-+
-+ newdev->dev = newinput;
-+
-+ file->private_data = newdev;
-+
-+ return 0;
-+cleanup:
-+ kfree(newdev);
-+error:
-+ return -ENOMEM;
-+}
-+
-+static int uinput_validate_absbits(struct input_dev *dev)
-+{
-+ unsigned int cnt;
-+ int retval = 0;
-+
-+ for (cnt = 0; cnt < ABS_MAX; cnt++) {
-+ if (!test_bit(cnt, dev->absbit))
-+ continue;
-+
-+ if (/*!dev->absmin[cnt] || !dev->absmax[cnt] || */
-+ (dev->absmax[cnt] <= dev->absmin[cnt])) {
-+ printk(KERN_DEBUG
-+ "%s: invalid abs[%02x] min:%d max:%d\n",
-+ UINPUT_NAME, cnt,
-+ dev->absmin[cnt], dev->absmax[cnt]);
-+ retval = -EINVAL;
-+ break;
-+ }
-+
-+ if ((dev->absflat[cnt] < dev->absmin[cnt]) ||
-+ (dev->absflat[cnt] > dev->absmax[cnt])) {
-+ printk(KERN_DEBUG
-+ "%s: absflat[%02x] out of range: %d "
-+ "(min:%d/max:%d)\n",
-+ UINPUT_NAME, cnt, dev->absflat[cnt],
-+ dev->absmin[cnt], dev->absmax[cnt]);
-+ retval = -EINVAL;
-+ break;
-+ }
-+ }
-+ return retval;
-+}
-+
-+static int uinput_alloc_device(struct file *file, const char *buffer, size_t count)
-+{
-+ struct uinput_user_dev *user_dev;
-+ struct input_dev *dev;
-+ struct uinput_device *udev;
-+ int size,
-+ retval;
-+
-+ retval = count;
-+
-+ udev = (struct uinput_device *)file->private_data;
-+ dev = udev->dev;
-+
-+ user_dev = kmalloc(sizeof(*user_dev), GFP_KERNEL);
-+ if (!user_dev) {
-+ retval = -ENOMEM;
-+ goto exit;
-+ }
-+
-+ if (copy_from_user(user_dev, buffer, sizeof(struct uinput_user_dev))) {
-+ retval = -EFAULT;
-+ goto exit;
-+ }
-+
-+ if (NULL != dev->name)
-+ kfree(dev->name);
-+
-+ size = strnlen(user_dev->name, UINPUT_MAX_NAME_SIZE) + 1;
-+ dev->name = kmalloc(size, GFP_KERNEL);
-+ if (!dev->name) {
-+ retval = -ENOMEM;
-+ goto exit;
-+ }
-+
-+ strncpy(dev->name, user_dev->name, size);
-+ dev->idbus = user_dev->idbus;
-+ dev->idvendor = user_dev->idvendor;
-+ dev->idproduct = user_dev->idproduct;
-+ dev->idversion = user_dev->idversion;
-+ dev->ff_effects_max = user_dev->ff_effects_max;
-+
-+ size = sizeof(int) * (ABS_MAX + 1);
-+ memcpy(dev->absmax, user_dev->absmax, size);
-+ memcpy(dev->absmin, user_dev->absmin, size);
-+ memcpy(dev->absfuzz, user_dev->absfuzz, size);
-+ memcpy(dev->absflat, user_dev->absflat, size);
-+
-+ /* check if absmin/absmax/absfuzz/absflat are filled as
-+ * told in Documentation/input/input-programming.txt */
-+ if (test_bit(EV_ABS, dev->evbit)) {
-+ retval = uinput_validate_absbits(dev);
-+ if (retval < 0)
-+ kfree(dev->name);
-+ }
-+
-+exit:
-+ kfree(user_dev);
-+ return retval;
-+}
-+
-+static ssize_t uinput_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
-+{
-+ struct uinput_device *udev = file->private_data;
-+
-+ if (test_bit(UIST_CREATED, &(udev->state))) {
-+ struct input_event ev;
-+
-+ if (copy_from_user(&ev, buffer, sizeof(struct input_event)))
-+ return -EFAULT;
-+ input_event(udev->dev, ev.type, ev.code, ev.value);
-+ }
-+ else
-+ count = uinput_alloc_device(file, buffer, count);
-+
-+ return count;
-+}
-+
-+static ssize_t uinput_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
-+{
-+ struct uinput_device *udev = file->private_data;
-+ int retval = 0;
-+
-+ if (!test_bit(UIST_CREATED, &(udev->state)))
-+ return -ENODEV;
-+
-+ if ((udev->head == udev->tail) && (file->f_flags & O_NONBLOCK))
-+ return -EAGAIN;
-+
-+ retval = wait_event_interruptible(udev->waitq,
-+ (udev->head != udev->tail) ||
-+ !test_bit(UIST_CREATED, &(udev->state)));
-+
-+ if (retval)
-+ return retval;
-+
-+ if (!test_bit(UIST_CREATED, &(udev->state)))
-+ return -ENODEV;
-+
-+ while ((udev->head != udev->tail) &&
-+ (retval + sizeof(struct input_event) <= count)) {
-+ if (copy_to_user(buffer + retval, &(udev->buff[udev->tail]),
-+ sizeof(struct input_event))) return -EFAULT;
-+ udev->tail = (udev->tail + 1) % UINPUT_BUFFER_SIZE;
-+ retval += sizeof(struct input_event);
-+ }
-+
-+ return retval;
-+}
-+
-+static unsigned int uinput_poll(struct file *file, poll_table *wait)
-+{
-+ struct uinput_device *udev = file->private_data;
-+
-+ poll_wait(file, &udev->waitq, wait);
-+
-+ if (udev->head != udev->tail)
-+ return POLLIN | POLLRDNORM;
-+
-+ return 0;
-+}
-+
-+static int uinput_burn_device(struct uinput_device *udev)
-+{
-+ if (test_bit(UIST_CREATED, &(udev->state)))
-+ uinput_destroy_device(udev);
-+
-+ kfree(udev->dev);
-+ kfree(udev);
-+
-+ return 0;
-+}
-+
-+static int uinput_close(struct inode *inode, struct file *file)
-+{
-+ return uinput_burn_device((struct uinput_device *)file->private_data);
-+}
-+
-+static int uinput_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
-+{
-+ int retval = 0;
-+ struct uinput_device *udev;
-+
-+ udev = (struct uinput_device *)file->private_data;
-+
-+ /* device attributes can not be changed after the device is created */
-+ if (cmd >= UI_SET_EVBIT && test_bit(UIST_CREATED, &(udev->state)))
-+ return -EINVAL;
-+
-+ switch (cmd) {
-+ case UI_DEV_CREATE:
-+ retval = uinput_create_device(udev);
-+ break;
-+
-+ case UI_DEV_DESTROY:
-+ retval = uinput_destroy_device(udev);
-+ break;
-+
-+ case UI_SET_EVBIT:
-+ if (arg > EV_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->evbit);
-+ break;
-+
-+ case UI_SET_KEYBIT:
-+ if (arg > KEY_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->keybit);
-+ break;
-+
-+ case UI_SET_RELBIT:
-+ if (arg > REL_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->relbit);
-+ break;
-+
-+ case UI_SET_ABSBIT:
-+ if (arg > ABS_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->absbit);
-+ break;
-+
-+ case UI_SET_MSCBIT:
-+ if (arg > MSC_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->mscbit);
-+ break;
-+
-+ case UI_SET_LEDBIT:
-+ if (arg > LED_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->ledbit);
-+ break;
-+
-+ case UI_SET_SNDBIT:
-+ if (arg > SND_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->sndbit);
-+ break;
-+
-+ case UI_SET_FFBIT:
-+ if (arg > FF_MAX) {
-+ retval = -EINVAL;
-+ break;
-+ }
-+ set_bit(arg, udev->dev->ffbit);
-+ break;
-+
-+ default:
-+ retval = -EFAULT;
-+ }
-+ return retval;
-+}
-+
-+struct file_operations uinput_fops = {
-+ owner: THIS_MODULE,
-+ open: uinput_open,
-+ release: uinput_close,
-+ read: uinput_read,
-+ write: uinput_write,
-+ poll: uinput_poll,
-+ ioctl: uinput_ioctl,
-+};
-+
-+static struct miscdevice uinput_misc = {
-+ fops: &uinput_fops,
-+ minor: UINPUT_MINOR,
-+ name: UINPUT_NAME,
-+};
-+
-+static int __init uinput_init(void)
-+{
-+ return misc_register(&uinput_misc);
-+}
-+
-+static void __exit uinput_exit(void)
-+{
-+ misc_deregister(&uinput_misc);
-+}
-+
-+MODULE_AUTHOR("Aristeu Sergio Rozanski Filho");
-+MODULE_DESCRIPTION("User level driver support for input subsystem");
-+MODULE_LICENSE("GPL");
-+
-+module_init(uinput_init);
-+module_exit(uinput_exit);
-+
-diff -urN linux-2.4.18/drivers/isdn/avmb1/capidrv.c linux-2.4.18-mh15/drivers/isdn/avmb1/capidrv.c
---- linux-2.4.18/drivers/isdn/avmb1/capidrv.c 2001-12-21 18:41:54.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/isdn/avmb1/capidrv.c 2004-08-01 16:26:23.000000000 +0200
-@@ -514,13 +514,25 @@
-
- static void send_message(capidrv_contr * card, _cmsg * cmsg)
- {
-- struct sk_buff *skb;
-- size_t len;
-+ struct sk_buff *skb;
-+ size_t len;
-+ u16 err;
-+
- capi_cmsg2message(cmsg, cmsg->buf);
- len = CAPIMSG_LEN(cmsg->buf);
- skb = alloc_skb(len, GFP_ATOMIC);
-+ if(!skb) {
-+ printk(KERN_ERR "no skb len(%d) memory\n", len);
-+ return;
-+ }
- memcpy(skb_put(skb, len), cmsg->buf, len);
-- (*capifuncs->capi_put_message) (global.appid, skb);
-+ err = (*capifuncs->capi_put_message) (global.appid, skb);
-+ if (err) {
-+ printk(KERN_WARNING "%s: capi_put_message error: %04x\n",
-+ __FUNCTION__, err);
-+ kfree_skb(skb);
-+ return;
-+ }
- global.nsentctlpkt++;
- }
-
-@@ -2179,10 +2191,10 @@
- free_ncci(card, card->bchans[card->nbchan-1].nccip);
- if (card->bchans[card->nbchan-1].plcip)
- free_plci(card, card->bchans[card->nbchan-1].plcip);
-- if (card->plci_list)
-- printk(KERN_ERR "capidrv: bug in free_plci()\n");
- card->nbchan--;
- }
-+ if (card->plci_list)
-+ printk(KERN_ERR "capidrv: bug in free_plci()\n");
- kfree(card->bchans);
- card->bchans = 0;
-
-diff -urN linux-2.4.18/drivers/isdn/avmb1/kcapi.c linux-2.4.18-mh15/drivers/isdn/avmb1/kcapi.c
---- linux-2.4.18/drivers/isdn/avmb1/kcapi.c 2001-12-21 18:41:54.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/isdn/avmb1/kcapi.c 2004-08-01 16:26:23.000000000 +0200
-@@ -545,7 +545,13 @@
- static void notify_up(__u32 contr)
- {
- struct capi_interface_user *p;
-+ __u16 appl;
-
-+ for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
-+ if (!VALID_APPLID(appl)) continue;
-+ if (APPL(appl)->releasing) continue;
-+ CARD(contr)->driver->register_appl(CARD(contr), appl, &APPL(appl)->rparam);
-+ }
- printk(KERN_NOTICE "kcapi: notify up contr %d\n", contr);
- spin_lock(&capi_users_lock);
- for (p = capi_users; p; p = p->next) {
-@@ -705,12 +711,16 @@
- nextpp = &(*pp)->next;
- }
- }
-- APPL(appl)->releasing--;
-- if (APPL(appl)->releasing <= 0) {
-- APPL(appl)->signal = 0;
-- APPL_MARK_FREE(appl);
-- printk(KERN_INFO "kcapi: appl %d down\n", appl);
-- }
-+ if (APPL(appl)->releasing) { /* only release if the application was marked for release */
-+ printk(KERN_DEBUG "kcapi: appl %d releasing(%d)\n", appl, APPL(appl)->releasing);
-+ APPL(appl)->releasing--;
-+ if (APPL(appl)->releasing <= 0) {
-+ APPL(appl)->signal = 0;
-+ APPL_MARK_FREE(appl);
-+ printk(KERN_INFO "kcapi: appl %d down\n", appl);
-+ }
-+ } else
-+ printk(KERN_WARNING "kcapi: appl %d card%d released without request\n", appl, card->cnr);
- }
- /*
- * ncci management
-@@ -863,16 +873,7 @@
-
- static void controllercb_ready(struct capi_ctr * card)
- {
-- __u16 appl;
--
- card->cardstate = CARD_RUNNING;
--
-- for (appl = 1; appl <= CAPI_MAXAPPL; appl++) {
-- if (!VALID_APPLID(appl)) continue;
-- if (APPL(appl)->releasing) continue;
-- card->driver->register_appl(card, appl, &APPL(appl)->rparam);
-- }
--
- printk(KERN_NOTICE "kcapi: card %d \"%s\" ready.\n",
- CARDNR(card), card->name);
-
-diff -urN linux-2.4.18/drivers/usb/Config.in linux-2.4.18-mh15/drivers/usb/Config.in
---- linux-2.4.18/drivers/usb/Config.in 2002-02-25 20:38:07.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/usb/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -31,7 +31,13 @@
-
- comment 'USB Device Class drivers'
- dep_tristate ' USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND
--dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB $CONFIG_EXPERIMENTAL
-+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-+ if [ "$CONFIG_BLUEZ" = "n" ]; then
-+ dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB
-+ else
-+ comment ' USB Bluetooth can only be used with disabled Bluetooth subsystem'
-+ fi
-+fi
- if [ "$CONFIG_SCSI" = "n" ]; then
- comment ' SCSI support is needed for USB Storage'
- fi
-diff -urN linux-2.4.18/drivers/usb/hid-core.c linux-2.4.18-mh15/drivers/usb/hid-core.c
---- linux-2.4.18/drivers/usb/hid-core.c 2001-12-21 18:41:55.000000000 +0100
-+++ linux-2.4.18-mh15/drivers/usb/hid-core.c 2004-08-01 16:26:23.000000000 +0200
-@@ -217,6 +217,8 @@
-
- offset = report->size;
- report->size += parser->global.report_size * parser->global.report_count;
-+ if (usages < parser->global.report_count)
-+ usages = parser->global.report_count;
-
- if (usages == 0)
- return 0; /* ignore padding fields */
-diff -urN linux-2.4.18/include/linux/firmware.h linux-2.4.18-mh15/include/linux/firmware.h
---- linux-2.4.18/include/linux/firmware.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/include/linux/firmware.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,20 @@
-+#ifndef _LINUX_FIRMWARE_H
-+#define _LINUX_FIRMWARE_H
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#define FIRMWARE_NAME_MAX 30
-+struct firmware {
-+ size_t size;
-+ u8 *data;
-+};
-+int request_firmware (const struct firmware **fw, const char *name,
-+ const char *device);
-+int request_firmware_nowait (
-+ struct module *module,
-+ const char *name, const char *device, void *context,
-+ void (*cont)(const struct firmware *fw, void *context));
-+/* On 2.5 'device' is 'struct device *' */
-+
-+void release_firmware (const struct firmware *fw);
-+void register_firmware (const char *name, const u8 *data, size_t size);
-+#endif
-diff -urN linux-2.4.18/include/linux/input.h linux-2.4.18-mh15/include/linux/input.h
---- linux-2.4.18/include/linux/input.h 2001-09-13 00:34:06.000000000 +0200
-+++ linux-2.4.18-mh15/include/linux/input.h 2004-08-01 16:26:23.000000000 +0200
-@@ -468,6 +468,8 @@
- #define BUS_PCI 0x01
- #define BUS_ISAPNP 0x02
- #define BUS_USB 0x03
-+#define BUS_HIL 0x04
-+#define BUS_BLUETOOTH 0x05
-
- #define BUS_ISA 0x10
- #define BUS_I8042 0x11
-diff -urN linux-2.4.18/include/linux/kernel.h linux-2.4.18-mh15/include/linux/kernel.h
---- linux-2.4.18/include/linux/kernel.h 2002-02-25 20:38:13.000000000 +0100
-+++ linux-2.4.18-mh15/include/linux/kernel.h 2004-08-01 16:26:23.000000000 +0200
-@@ -11,6 +11,7 @@
- #include <linux/linkage.h>
- #include <linux/stddef.h>
- #include <linux/types.h>
-+#include <linux/compiler.h>
-
- /* Optimization barrier */
- /* The "volatile" is due to gcc bugs */
-@@ -181,4 +182,6 @@
- char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
- };
-
--#endif
-+#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
-+
-+#endif /* _LINUX_KERNEL_H */
-diff -urN linux-2.4.18/include/linux/net.h linux-2.4.18-mh15/include/linux/net.h
---- linux-2.4.18/include/linux/net.h 2001-11-22 20:46:19.000000000 +0100
-+++ linux-2.4.18-mh15/include/linux/net.h 2004-08-01 16:26:23.000000000 +0200
-@@ -139,6 +139,7 @@
- extern int sock_recvmsg(struct socket *, struct msghdr *m, int len, int flags);
- extern int sock_readv_writev(int type, struct inode * inode, struct file * file,
- const struct iovec * iov, long count, long size);
-+extern struct socket *sockfd_lookup(int fd, int *err);
-
- extern int net_ratelimit(void);
- extern unsigned long net_random(void);
-diff -urN linux-2.4.18/include/linux/uinput.h linux-2.4.18-mh15/include/linux/uinput.h
---- linux-2.4.18/include/linux/uinput.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/include/linux/uinput.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,79 @@
-+/*
-+ * User level driver support for input subsystem
-+ *
-+ * Heavily based on evdev.c by Vojtech Pavlik
-+ *
-+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org>
-+ *
-+ * Changes/Revisions:
-+ * 0.1 20/06/2002
-+ * - first public version
-+ */
-+
-+#ifndef __UINPUT_H_
-+#define __UINPUT_H_
-+
-+#ifdef __KERNEL__
-+#define UINPUT_MINOR 223
-+#define UINPUT_NAME "uinput"
-+#define UINPUT_BUFFER_SIZE 16
-+
-+/* state flags => bit index for {set|clear|test}_bit ops */
-+#define UIST_CREATED 0
-+
-+struct uinput_device {
-+ struct input_dev *dev;
-+ unsigned long state;
-+ wait_queue_head_t waitq;
-+ unsigned char ready,
-+ head,
-+ tail;
-+ struct input_event buff[UINPUT_BUFFER_SIZE];
-+};
-+#endif /* __KERNEL__ */
-+
-+/* ioctl */
-+#define UINPUT_IOCTL_BASE 'U'
-+#define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1)
-+#define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2)
-+#define UI_SET_EVBIT _IOW(UINPUT_IOCTL_BASE, 100, int)
-+#define UI_SET_KEYBIT _IOW(UINPUT_IOCTL_BASE, 101, int)
-+#define UI_SET_RELBIT _IOW(UINPUT_IOCTL_BASE, 102, int)
-+#define UI_SET_ABSBIT _IOW(UINPUT_IOCTL_BASE, 103, int)
-+#define UI_SET_MSCBIT _IOW(UINPUT_IOCTL_BASE, 104, int)
-+#define UI_SET_LEDBIT _IOW(UINPUT_IOCTL_BASE, 105, int)
-+#define UI_SET_SNDBIT _IOW(UINPUT_IOCTL_BASE, 106, int)
-+#define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int)
-+
-+#ifndef NBITS
-+#define NBITS(x) ((((x)-1)/(sizeof(long)*8))+1)
-+#endif /* NBITS */
-+
-+#define UINPUT_MAX_NAME_SIZE 80
-+struct uinput_user_dev {
-+ char name[UINPUT_MAX_NAME_SIZE];
-+ unsigned short idbus;
-+ unsigned short idvendor;
-+ unsigned short idproduct;
-+ unsigned short idversion;
-+ int ff_effects_max;
-+ int absmax[ABS_MAX + 1];
-+ int absmin[ABS_MAX + 1];
-+ int absfuzz[ABS_MAX + 1];
-+ int absflat[ABS_MAX + 1];
-+};
-+#endif /* __UINPUT_H_ */
-diff -urN linux-2.4.18/include/net/bluetooth/bluetooth.h linux-2.4.18-mh15/include/net/bluetooth/bluetooth.h
---- linux-2.4.18/include/net/bluetooth/bluetooth.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/bluetooth.h 2004-08-01 16:26:23.000000000 +0200
-@@ -23,7 +23,7 @@
- */
-
- /*
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __BLUETOOTH_H
-@@ -31,17 +31,64 @@
-
- #include <asm/types.h>
- #include <asm/byteorder.h>
-+#include <linux/poll.h>
-+#include <net/sock.h>
-
- #ifndef AF_BLUETOOTH
- #define AF_BLUETOOTH 31
- #define PF_BLUETOOTH AF_BLUETOOTH
- #endif
-
-+/* Reserv for core and drivers use */
-+#define BLUEZ_SKB_RESERVE 8
-+
-+#ifndef MIN
-+#define MIN(a,b) ((a) < (b) ? (a) : (b))
-+#endif
-+
- #define BTPROTO_L2CAP 0
- #define BTPROTO_HCI 1
-+#define BTPROTO_SCO 2
-+#define BTPROTO_RFCOMM 3
-+#define BTPROTO_BNEP 4
-+#define BTPROTO_CMTP 5
-+#define BTPROTO_HIDP 6
-
- #define SOL_HCI 0
- #define SOL_L2CAP 6
-+#define SOL_SCO 17
-+#define SOL_RFCOMM 18
-+
-+/* Debugging */
-+#ifdef CONFIG_BLUEZ_DEBUG
-+
-+#define HCI_CORE_DEBUG 1
-+#define HCI_SOCK_DEBUG 1
-+#define HCI_UART_DEBUG 1
-+#define HCI_USB_DEBUG 1
-+//#define HCI_DATA_DUMP 1
-+
-+#define L2CAP_DEBUG 1
-+#define SCO_DEBUG 1
-+#define AF_BLUETOOTH_DEBUG 1
-+
-+#endif /* CONFIG_BLUEZ_DEBUG */
-+
-+extern void bluez_dump(char *pref, __u8 *buf, int count);
-+
-+#if __GNUC__ <= 2 && __GNUC_MINOR__ < 95
-+#define __func__ __FUNCTION__
-+#endif
-+
-+#define BT_INFO(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
-+#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __func__ , ## arg)
-+#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
-+
-+#ifdef HCI_DATA_DUMP
-+#define BT_DMP(buf, len) bluez_dump(__func__, buf, len)
-+#else
-+#define BT_DMP(D...)
-+#endif
-
- /* Connection and socket states */
- enum {
-@@ -50,6 +97,7 @@
- BT_BOUND,
- BT_LISTEN,
- BT_CONNECT,
-+ BT_CONNECT2,
- BT_CONFIG,
- BT_DISCONN,
- BT_CLOSED
-@@ -66,7 +114,8 @@
- __u8 b[6];
- } __attribute__((packed)) bdaddr_t;
-
--#define BDADDR_ANY ((bdaddr_t *)"\000\000\000\000\000")
-+#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
-+#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
-
- /* Copy, swap, convert BD Address */
- static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2)
-@@ -82,6 +131,91 @@
- char *batostr(bdaddr_t *ba);
- bdaddr_t *strtoba(char *str);
-
-+/* Common socket structures and functions */
-+
-+#define bluez_pi(sk) ((struct bluez_pinfo *) &sk->protinfo)
-+#define bluez_sk(pi) ((struct sock *) \
-+ ((void *)pi - (unsigned long)(&((struct sock *)0)->protinfo)))
-+
-+struct bluez_pinfo {
-+ bdaddr_t src;
-+ bdaddr_t dst;
-+
-+ struct list_head accept_q;
-+ struct sock *parent;
-+};
-+
-+struct bluez_sock_list {
-+ struct sock *head;
-+ rwlock_t lock;
-+};
-+
-+int bluez_sock_register(int proto, struct net_proto_family *ops);
-+int bluez_sock_unregister(int proto);
-+void bluez_sock_init(struct socket *sock, struct sock *sk);
-+void bluez_sock_link(struct bluez_sock_list *l, struct sock *s);
-+void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *s);
-+int bluez_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm);
-+uint bluez_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
-+int bluez_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
-+
-+void bluez_accept_enqueue(struct sock *parent, struct sock *sk);
-+struct sock * bluez_accept_dequeue(struct sock *parent, struct socket *newsock);
-+
-+/* Skb helpers */
-+struct bluez_skb_cb {
-+ int incomming;
-+};
-+#define bluez_cb(skb) ((struct bluez_skb_cb *)(skb->cb))
-+
-+static inline struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
-+{
-+ struct sk_buff *skb;
-+
-+ if ((skb = alloc_skb(len + BLUEZ_SKB_RESERVE, how))) {
-+ skb_reserve(skb, BLUEZ_SKB_RESERVE);
-+ bluez_cb(skb)->incomming = 0;
-+ }
-+ return skb;
-+}
-+
-+static inline struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len,
-+ int nb, int *err)
-+{
-+ struct sk_buff *skb;
-+
-+ if ((skb = sock_alloc_send_skb(sk, len + BLUEZ_SKB_RESERVE, nb, err))) {
-+ skb_reserve(skb, BLUEZ_SKB_RESERVE);
-+ bluez_cb(skb)->incomming = 0;
-+ }
-+
-+ return skb;
-+}
-+
-+static inline int skb_frags_no(struct sk_buff *skb)
-+{
-+ register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
-+ register int n = 1;
-+
-+ for (; frag; frag=frag->next, n++);
-+ return n;
-+}
-+
-+int hci_core_init(void);
-+int hci_core_cleanup(void);
-+int hci_sock_init(void);
-+int hci_sock_cleanup(void);
-+
- int bterr(__u16 code);
-
-+#ifndef MODULE_LICENSE
-+#define MODULE_LICENSE(x)
-+#endif
-+
-+#ifndef list_for_each_safe
-+#define list_for_each_safe(pos, n, head) \
-+ for (pos = (head)->next, n = pos->next; pos != (head); \
-+ pos = n, n = pos->next)
-+#endif
-+
- #endif /* __BLUETOOTH_H */
-diff -urN linux-2.4.18/include/net/bluetooth/bluez.h linux-2.4.18-mh15/include/net/bluetooth/bluez.h
---- linux-2.4.18/include/net/bluetooth/bluez.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/bluez.h 1970-01-01 01:00:00.000000000 +0100
-@@ -1,124 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifndef __IF_BLUEZ_H
--#define __IF_BLUEZ_H
--
--#include <net/sock.h>
--
--#define BLUEZ_MAX_PROTO 2
--
--/* Reserv for core and drivers use */
--#define BLUEZ_SKB_RESERVE 8
--
--#ifndef MIN
--#define MIN(a,b) ((a) < (b) ? (a) : (b))
--#endif
--
--/* Debugging */
--#ifdef BLUEZ_DEBUG
--
--#define HCI_CORE_DEBUG 1
--#define HCI_SOCK_DEBUG 1
--#define HCI_UART_DEBUG 1
--#define HCI_USB_DEBUG 1
--//#define HCI_DATA_DUMP 1
--
--#define L2CAP_DEBUG 1
--
--#endif /* BLUEZ_DEBUG */
--
--extern void bluez_dump(char *pref, __u8 *buf, int count);
--
--#define INF(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
--#define DBG(fmt, arg...) printk(KERN_INFO __FUNCTION__ ": " fmt "\n" , ## arg)
--#define ERR(fmt, arg...) printk(KERN_ERR __FUNCTION__ ": " fmt "\n" , ## arg)
--
--#ifdef HCI_DATA_DUMP
--#define DMP(buf, len) bluez_dump(__FUNCTION__, buf, len)
--#else
--#define DMP(D...)
--#endif
--
--/* ----- Sockets ------ */
--struct bluez_sock_list {
-- struct sock *head;
-- rwlock_t lock;
--};
--
--extern int bluez_sock_register(int proto, struct net_proto_family *ops);
--extern int bluez_sock_unregister(int proto);
--
--extern void bluez_sock_link(struct bluez_sock_list *l, struct sock *s);
--extern void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *s);
--
--/* ----- SKB helpers ----- */
--struct bluez_skb_cb {
-- int incomming;
--};
--#define bluez_cb(skb) ((struct bluez_skb_cb *)(skb->cb))
--
--static inline struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
--{
-- struct sk_buff *skb;
--
-- if ((skb = alloc_skb(len + BLUEZ_SKB_RESERVE, how))) {
-- skb_reserve(skb, BLUEZ_SKB_RESERVE);
-- bluez_cb(skb)->incomming = 0;
-- }
-- return skb;
--}
--
--static inline struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len,
-- int nb, int *err)
--{
-- struct sk_buff *skb;
--
-- if ((skb = sock_alloc_send_skb(sk, len + BLUEZ_SKB_RESERVE, nb, err))) {
-- skb_reserve(skb, BLUEZ_SKB_RESERVE);
-- bluez_cb(skb)->incomming = 0;
-- }
--
-- return skb;
--}
--
--static inline int skb_frags_no(struct sk_buff *skb)
--{
-- register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
-- register int n = 1;
--
-- for (; frag; frag=frag->next, n++);
-- return n;
--}
--
--extern int hci_core_init(void);
--extern int hci_core_cleanup(void);
--extern int hci_sock_init(void);
--extern int hci_sock_cleanup(void);
--
--#endif /* __IF_BLUEZ_H */
-diff -urN linux-2.4.18/include/net/bluetooth/hci_core.h linux-2.4.18-mh15/include/net/bluetooth/hci_core.h
---- linux-2.4.18/include/net/bluetooth/hci_core.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/hci_core.h 2004-08-01 16:26:23.000000000 +0200
-@@ -23,7 +23,7 @@
- */
-
- /*
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __HCI_CORE_H
-@@ -32,14 +32,12 @@
- #include <net/bluetooth/hci.h>
-
- /* HCI upper protocols */
--#define HCI_MAX_PROTO 1
- #define HCI_PROTO_L2CAP 0
-+#define HCI_PROTO_SCO 1
-
- #define HCI_INIT_TIMEOUT (HZ * 10)
-
--/* ----- Inquiry cache ----- */
--#define INQUIRY_CACHE_AGE_MAX (HZ*5) // 5 seconds
--#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds
-+/* HCI Core structures */
-
- struct inquiry_entry {
- struct inquiry_entry *next;
-@@ -53,111 +51,188 @@
- struct inquiry_entry *list;
- };
-
--static inline void inquiry_cache_init(struct inquiry_cache *cache)
--{
-- spin_lock_init(&cache->lock);
-- cache->list = NULL;
--}
-+struct conn_hash {
-+ struct list_head list;
-+ spinlock_t lock;
-+ unsigned int num;
-+};
-
--static inline void inquiry_cache_lock(struct inquiry_cache *cache)
--{
-- spin_lock(&cache->lock);
--}
-+struct hci_dev {
-+ struct list_head list;
-+ spinlock_t lock;
-+ atomic_t refcnt;
-
--static inline void inquiry_cache_unlock(struct inquiry_cache *cache)
--{
-- spin_unlock(&cache->lock);
--}
-+ char name[8];
-+ unsigned long flags;
-+ __u16 id;
-+ __u8 type;
-+ bdaddr_t bdaddr;
-+ __u8 features[8];
-
--static inline void inquiry_cache_lock_bh(struct inquiry_cache *cache)
--{
-- spin_lock_bh(&cache->lock);
--}
-+ __u16 pkt_type;
-+ __u16 link_policy;
-+ __u16 link_mode;
-
--static inline void inquiry_cache_unlock_bh(struct inquiry_cache *cache)
--{
-- spin_unlock_bh(&cache->lock);
--}
-+ unsigned long quirks;
-
--static inline long inquiry_cache_age(struct inquiry_cache *cache)
--{
-- return jiffies - cache->timestamp;
--}
-+ atomic_t cmd_cnt;
-+ unsigned int acl_cnt;
-+ unsigned int sco_cnt;
-
--static inline long inquiry_entry_age(struct inquiry_entry *e)
--{
-- return jiffies - e->timestamp;
--}
--extern void inquiry_cache_flush(struct inquiry_cache *cache);
-+ unsigned int acl_mtu;
-+ unsigned int sco_mtu;
-+ unsigned int acl_pkts;
-+ unsigned int sco_pkts;
-
--struct hci_dev;
-+ unsigned long cmd_last_tx;
-+ unsigned long acl_last_tx;
-+ unsigned long sco_last_tx;
-+
-+ struct tasklet_struct cmd_task;
-+ struct tasklet_struct rx_task;
-+ struct tasklet_struct tx_task;
-+
-+ struct sk_buff_head rx_q;
-+ struct sk_buff_head raw_q;
-+ struct sk_buff_head cmd_q;
-+
-+ struct sk_buff *sent_cmd;
-+
-+ struct semaphore req_lock;
-+ wait_queue_head_t req_wait_q;
-+ __u32 req_status;
-+ __u32 req_result;
-+
-+ struct inquiry_cache inq_cache;
-+ struct conn_hash conn_hash;
-+
-+ struct hci_dev_stats stat;
-+
-+ void *driver_data;
-+ void *core_data;
-+
-+ atomic_t promisc;
-+
-+ int (*open)(struct hci_dev *hdev);
-+ int (*close)(struct hci_dev *hdev);
-+ int (*flush)(struct hci_dev *hdev);
-+ int (*send)(struct sk_buff *skb);
-+ void (*destruct)(struct hci_dev *hdev);
-+ int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
-+};
-
--/* ----- HCI Connections ----- */
- struct hci_conn {
- struct list_head list;
-+
-+ atomic_t refcnt;
-+ spinlock_t lock;
-+
- bdaddr_t dst;
- __u16 handle;
-+ __u16 state;
- __u8 type;
-- unsigned int sent;
-+ __u8 out;
-+ __u32 link_mode;
-+ unsigned long pend;
-+
-+ unsigned int sent;
-+
-+ struct sk_buff_head data_q;
-
-+ struct timer_list timer;
-+
- struct hci_dev *hdev;
- void *l2cap_data;
-+ void *sco_data;
- void *priv;
-
-- struct sk_buff_head data_q;
-+ struct hci_conn *link;
- };
-
--struct conn_hash {
-- struct list_head list;
-- spinlock_t lock;
-- unsigned int num;
--};
-+extern struct hci_proto *hci_proto[];
-+extern struct list_head hdev_list;
-+extern rwlock_t hdev_list_lock;
-+
-+/* ----- Inquiry cache ----- */
-+#define INQUIRY_CACHE_AGE_MAX (HZ*30) // 30 seconds
-+#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds
-+
-+#define inquiry_cache_lock(c) spin_lock(&c->lock)
-+#define inquiry_cache_unlock(c) spin_unlock(&c->lock)
-+#define inquiry_cache_lock_bh(c) spin_lock_bh(&c->lock)
-+#define inquiry_cache_unlock_bh(c) spin_unlock_bh(&c->lock)
-
--static inline void conn_hash_init(struct conn_hash *h)
-+static inline void inquiry_cache_init(struct hci_dev *hdev)
- {
-- INIT_LIST_HEAD(&h->list);
-- spin_lock_init(&h->lock);
-- h->num = 0;
-+ struct inquiry_cache *c = &hdev->inq_cache;
-+ spin_lock_init(&c->lock);
-+ c->list = NULL;
- }
-
--static inline void conn_hash_lock(struct conn_hash *h)
-+static inline int inquiry_cache_empty(struct hci_dev *hdev)
- {
-- spin_lock(&h->lock);
-+ struct inquiry_cache *c = &hdev->inq_cache;
-+ return (c->list == NULL);
- }
-
--static inline void conn_hash_unlock(struct conn_hash *h)
-+static inline long inquiry_cache_age(struct hci_dev *hdev)
- {
-- spin_unlock(&h->lock);
-+ struct inquiry_cache *c = &hdev->inq_cache;
-+ return jiffies - c->timestamp;
- }
-
--static inline void __conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
-+static inline long inquiry_entry_age(struct inquiry_entry *e)
- {
-- list_add(&c->list, &h->list);
-- h->num++;
-+ return jiffies - e->timestamp;
- }
-
--static inline void conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
-+struct inquiry_entry *inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
-+void inquiry_cache_update(struct hci_dev *hdev, inquiry_info *info);
-+void inquiry_cache_flush(struct hci_dev *hdev);
-+int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf);
-+
-+/* ----- HCI Connections ----- */
-+enum {
-+ HCI_CONN_AUTH_PEND,
-+ HCI_CONN_ENCRYPT_PEND
-+};
-+
-+#define hci_conn_lock(c) spin_lock(&c->lock)
-+#define hci_conn_unlock(c) spin_unlock(&c->lock)
-+#define hci_conn_lock_bh(c) spin_lock_bh(&c->lock)
-+#define hci_conn_unlock_bh(c) spin_unlock_bh(&c->lock)
-+
-+#define conn_hash_lock(d) spin_lock(&d->conn_hash->lock)
-+#define conn_hash_unlock(d) spin_unlock(&d->conn_hash->lock)
-+#define conn_hash_lock_bh(d) spin_lock_bh(&d->conn_hash->lock)
-+#define conn_hash_unlock_bh(d) spin_unlock_bh(&d->conn_hash->lock)
-+
-+static inline void conn_hash_init(struct hci_dev *hdev)
- {
-- conn_hash_lock(h);
-- __conn_hash_add(h, handle, c);
-- conn_hash_unlock(h);
-+ struct conn_hash *h = &hdev->conn_hash;
-+ INIT_LIST_HEAD(&h->list);
-+ spin_lock_init(&h->lock);
-+ h->num = 0;
- }
-
--static inline void __conn_hash_del(struct conn_hash *h, struct hci_conn *c)
-+static inline void conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
- {
-- list_del(&c->list);
-- h->num--;
-+ struct conn_hash *h = &hdev->conn_hash;
-+ list_add(&c->list, &h->list);
-+ h->num++;
- }
-
--static inline void conn_hash_del(struct conn_hash *h, struct hci_conn *c)
-+static inline void conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
- {
-- conn_hash_lock(h);
-- __conn_hash_del(h, c);
-- conn_hash_unlock(h);
-+ struct conn_hash *h = &hdev->conn_hash;
-+ list_del(&c->list);
-+ h->num--;
- }
-
--static inline struct hci_conn *__conn_hash_lookup(struct conn_hash *h, __u16 handle)
-+static inline struct hci_conn *conn_hash_lookup_handle(struct hci_dev *hdev,
-+ __u16 handle)
- {
-+ register struct conn_hash *h = &hdev->conn_hash;
- register struct list_head *p;
- register struct hci_conn *c;
-
-@@ -169,101 +244,97 @@
- return NULL;
- }
-
--static inline struct hci_conn *conn_hash_lookup(struct conn_hash *h, __u16 handle)
-+static inline struct hci_conn *conn_hash_lookup_ba(struct hci_dev *hdev,
-+ __u8 type, bdaddr_t *ba)
- {
-- struct hci_conn *conn;
-+ register struct conn_hash *h = &hdev->conn_hash;
-+ register struct list_head *p;
-+ register struct hci_conn *c;
-
-- conn_hash_lock(h);
-- conn = __conn_hash_lookup(h, handle);
-- conn_hash_unlock(h);
-- return conn;
-+ list_for_each(p, &h->list) {
-+ c = list_entry(p, struct hci_conn, list);
-+ if (c->type == type && !bacmp(&c->dst, ba))
-+ return c;
-+ }
-+ return NULL;
- }
-
--/* ----- HCI Devices ----- */
--struct hci_dev {
-- atomic_t refcnt;
--
-- char name[8];
-- __u32 flags;
-- __u16 id;
-- __u8 type;
-- bdaddr_t bdaddr;
-- __u8 features[8];
--
-- __u16 pkt_type;
--
-- atomic_t cmd_cnt;
-- unsigned int acl_cnt;
-- unsigned int sco_cnt;
--
-- unsigned int acl_mtu;
-- unsigned int sco_mtu;
-- unsigned int acl_max;
-- unsigned int sco_max;
--
-- void *driver_data;
-- void *l2cap_data;
-- void *priv;
--
-- struct tasklet_struct cmd_task;
-- struct tasklet_struct rx_task;
-- struct tasklet_struct tx_task;
--
-- struct sk_buff_head rx_q;
-- struct sk_buff_head raw_q;
-- struct sk_buff_head cmd_q;
--
-- struct sk_buff *sent_cmd;
-+void hci_acl_connect(struct hci_conn *conn);
-+void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
-+void hci_add_sco(struct hci_conn *conn, __u16 handle);
-
-- struct semaphore req_lock;
-- wait_queue_head_t req_wait_q;
-- __u32 req_status;
-- __u32 req_result;
-+struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
-+int hci_conn_del(struct hci_conn *conn);
-+void hci_conn_hash_flush(struct hci_dev *hdev);
-
-- struct inquiry_cache inq_cache;
-+struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src);
-+int hci_conn_auth(struct hci_conn *conn);
-+int hci_conn_encrypt(struct hci_conn *conn);
-
-- struct conn_hash conn_hash;
--
-- struct hci_dev_stats stat;
--
-- int (*open)(struct hci_dev *hdev);
-- int (*close)(struct hci_dev *hdev);
-- int (*flush)(struct hci_dev *hdev);
-- int (*send)(struct sk_buff *skb);
--};
-+static inline void hci_conn_set_timer(struct hci_conn *conn, long timeout)
-+{
-+ mod_timer(&conn->timer, jiffies + timeout);
-+}
-
--static inline void hci_dev_hold(struct hci_dev *hdev)
-+static inline void hci_conn_del_timer(struct hci_conn *conn)
- {
-- atomic_inc(&hdev->refcnt);
-+ del_timer(&conn->timer);
- }
-
--static inline void hci_dev_put(struct hci_dev *hdev)
-+static inline void hci_conn_hold(struct hci_conn *conn)
- {
-- atomic_dec(&hdev->refcnt);
-+ atomic_inc(&conn->refcnt);
-+ hci_conn_del_timer(conn);
- }
-
--extern struct hci_dev *hci_dev_get(int index);
--extern int hci_register_dev(struct hci_dev *hdev);
--extern int hci_unregister_dev(struct hci_dev *hdev);
--extern int hci_dev_open(__u16 dev);
--extern int hci_dev_close(__u16 dev);
--extern int hci_dev_reset(__u16 dev);
--extern int hci_dev_reset_stat(__u16 dev);
--extern int hci_dev_info(unsigned long arg);
--extern int hci_dev_list(unsigned long arg);
--extern int hci_dev_setscan(unsigned long arg);
--extern int hci_dev_setauth(unsigned long arg);
--extern int hci_dev_setptype(unsigned long arg);
--extern int hci_conn_list(unsigned long arg);
--extern int hci_inquiry(unsigned long arg);
-+static inline void hci_conn_put(struct hci_conn *conn)
-+{
-+ if (atomic_dec_and_test(&conn->refcnt)) {
-+ if (conn->type == ACL_LINK) {
-+ unsigned long timeo = (conn->out) ?
-+ HCI_DISCONN_TIMEOUT : HCI_DISCONN_TIMEOUT * 2;
-+ hci_conn_set_timer(conn, timeo);
-+ } else
-+ hci_conn_set_timer(conn, HZ / 100);
-+ }
-+}
-
--extern __u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode);
--extern __u32 hci_dev_getmode(struct hci_dev *hdev);
-+/* ----- HCI Devices ----- */
-+static inline void hci_dev_put(struct hci_dev *d)
-+{
-+ if (atomic_dec_and_test(&d->refcnt))
-+ d->destruct(d);
-+}
-+#define hci_dev_hold(d) atomic_inc(&d->refcnt)
-+
-+#define hci_dev_lock(d) spin_lock(&d->lock)
-+#define hci_dev_unlock(d) spin_unlock(&d->lock)
-+#define hci_dev_lock_bh(d) spin_lock_bh(&d->lock)
-+#define hci_dev_unlock_bh(d) spin_unlock_bh(&d->lock)
-+
-+struct hci_dev *hci_dev_get(int index);
-+struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst);
-+int hci_register_dev(struct hci_dev *hdev);
-+int hci_unregister_dev(struct hci_dev *hdev);
-+int hci_suspend_dev(struct hci_dev *hdev);
-+int hci_resume_dev(struct hci_dev *hdev);
-+int hci_dev_open(__u16 dev);
-+int hci_dev_close(__u16 dev);
-+int hci_dev_reset(__u16 dev);
-+int hci_dev_reset_stat(__u16 dev);
-+int hci_dev_cmd(unsigned int cmd, unsigned long arg);
-+int hci_get_dev_list(unsigned long arg);
-+int hci_get_dev_info(unsigned long arg);
-+int hci_get_conn_list(unsigned long arg);
-+int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg);
-+int hci_inquiry(unsigned long arg);
-
--extern int hci_recv_frame(struct sk_buff *skb);
-+int hci_recv_frame(struct sk_buff *skb);
-+void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
-
- /* ----- LMP capabilities ----- */
- #define lmp_rswitch_capable(dev) (dev->features[0] & LMP_RSWITCH)
-+#define lmp_encrypt_capable(dev) (dev->features[0] & LMP_ENCRYPT)
-
- /* ----- HCI tasks ----- */
- static inline void hci_sched_cmd(struct hci_dev *hdev)
-@@ -284,43 +355,130 @@
- /* ----- HCI protocols ----- */
- struct hci_proto {
- char *name;
-- __u32 id;
-- __u32 flags;
-+ unsigned int id;
-+ unsigned long flags;
-
- void *priv;
-
-- int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr);
-- int (*connect_cfm) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 status, struct hci_conn *conn);
-+ int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type);
-+ int (*connect_cfm) (struct hci_conn *conn, __u8 status);
- int (*disconn_ind) (struct hci_conn *conn, __u8 reason);
-- int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb , __u16 flags);
-+ int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
- int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb);
-+ int (*auth_cfm) (struct hci_conn *conn, __u8 status);
-+ int (*encrypt_cfm) (struct hci_conn *conn, __u8 status);
- };
-
--extern int hci_register_proto(struct hci_proto *hproto);
--extern int hci_unregister_proto(struct hci_proto *hproto);
--extern int hci_register_notifier(struct notifier_block *nb);
--extern int hci_unregister_notifier(struct notifier_block *nb);
--extern int hci_connect(struct hci_dev * hdev, bdaddr_t * bdaddr);
--extern int hci_disconnect(struct hci_conn *conn, __u8 reason);
--extern int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void * param);
--extern int hci_send_raw(struct sk_buff *skb);
--extern int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
--extern int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
-+static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
-+{
-+ register struct hci_proto *hp;
-+ int mask = 0;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->connect_ind)
-+ mask |= hp->connect_ind(hdev, bdaddr, type);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->connect_ind)
-+ mask |= hp->connect_ind(hdev, bdaddr, type);
-+
-+ return mask;
-+}
-+
-+static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
-+{
-+ register struct hci_proto *hp;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->connect_cfm)
-+ hp->connect_cfm(conn, status);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->connect_cfm)
-+ hp->connect_cfm(conn, status);
-+}
-+
-+static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason)
-+{
-+ register struct hci_proto *hp;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->disconn_ind)
-+ hp->disconn_ind(conn, reason);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->disconn_ind)
-+ hp->disconn_ind(conn, reason);
-+}
-+
-+static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
-+{
-+ register struct hci_proto *hp;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->auth_cfm)
-+ hp->auth_cfm(conn, status);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->auth_cfm)
-+ hp->auth_cfm(conn, status);
-+}
-+
-+static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status)
-+{
-+ register struct hci_proto *hp;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->encrypt_cfm)
-+ hp->encrypt_cfm(conn, status);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->encrypt_cfm)
-+ hp->encrypt_cfm(conn, status);
-+}
-+
-+int hci_register_proto(struct hci_proto *hproto);
-+int hci_unregister_proto(struct hci_proto *hproto);
-+int hci_register_notifier(struct notifier_block *nb);
-+int hci_unregister_notifier(struct notifier_block *nb);
-+
-+int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param);
-+int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
-+int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
-+
-+void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf);
-+
-+void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
-
- /* ----- HCI Sockets ----- */
--extern void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
-+void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
-
- /* HCI info for socket */
--#define hci_pi(sk) ((struct hci_pinfo *) &sk->protinfo)
-+#define hci_pi(sk) ((struct hci_pinfo *) &sk->tp_pinfo)
- struct hci_pinfo {
- struct hci_dev *hdev;
- struct hci_filter filter;
- __u32 cmsg_mask;
- };
-
-+/* HCI security filter */
-+#define HCI_SFLT_MAX_OGF 5
-+
-+struct hci_sec_filter {
-+ __u32 type_mask;
-+ __u32 event_mask[2];
-+ __u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4];
-+};
-+
- /* ----- HCI requests ----- */
- #define HCI_REQ_DONE 0
- #define HCI_REQ_PEND 1
- #define HCI_REQ_CANCELED 2
-
-+#define hci_req_lock(d) down(&d->req_lock)
-+#define hci_req_unlock(d) up(&d->req_lock)
-+
-+void hci_req_complete(struct hci_dev *hdev, int result);
-+void hci_req_cancel(struct hci_dev *hdev, int err);
-+
- #endif /* __HCI_CORE_H */
-diff -urN linux-2.4.18/include/net/bluetooth/hci.h linux-2.4.18-mh15/include/net/bluetooth/hci.h
---- linux-2.4.18/include/net/bluetooth/hci.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/hci.h 2004-08-01 16:26:23.000000000 +0200
-@@ -23,59 +23,80 @@
- */
-
- /*
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __HCI_H
- #define __HCI_H
-
--#include <asm/byteorder.h>
--
--#define HCI_MAX_DEV 8
--#define HCI_MAX_FRAME_SIZE 2048
-+#define HCI_MAX_ACL_SIZE 1024
-+#define HCI_MAX_SCO_SIZE 255
-+#define HCI_MAX_EVENT_SIZE 260
-+#define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4)
-
- /* HCI dev events */
- #define HCI_DEV_REG 1
- #define HCI_DEV_UNREG 2
- #define HCI_DEV_UP 3
- #define HCI_DEV_DOWN 4
-+#define HCI_DEV_SUSPEND 5
-+#define HCI_DEV_RESUME 6
-
- /* HCI device types */
--#define HCI_UART 0
-+#define HCI_VHCI 0
- #define HCI_USB 1
--#define HCI_VHCI 2
--
--/* HCI device modes */
--#define HCI_NORMAL 0x0001
--#define HCI_RAW 0x0002
--#define HCI_MODE_MASK (HCI_NORMAL | HCI_RAW)
--#define HCI_SOCK 0x1000
--
--/* HCI device states */
--#define HCI_INIT 0x0010
--#define HCI_UP 0x0020
--#define HCI_RUNNING 0x0040
-+#define HCI_PCCARD 2
-+#define HCI_UART 3
-+#define HCI_RS232 4
-+#define HCI_PCI 5
-+
-+/* HCI device quirks */
-+enum {
-+ HCI_QUIRK_RESET_ON_INIT
-+};
-
- /* HCI device flags */
--#define HCI_PSCAN 0x0100
--#define HCI_ISCAN 0x0200
--#define HCI_AUTH 0x0400
-+enum {
-+ HCI_UP,
-+ HCI_INIT,
-+ HCI_RUNNING,
-+
-+ HCI_PSCAN,
-+ HCI_ISCAN,
-+ HCI_AUTH,
-+ HCI_ENCRYPT,
-+ HCI_INQUIRY,
-+
-+ HCI_RAW
-+};
-
--/* HCI Ioctl defines */
-+/* HCI ioctl defines */
- #define HCIDEVUP _IOW('H', 201, int)
- #define HCIDEVDOWN _IOW('H', 202, int)
- #define HCIDEVRESET _IOW('H', 203, int)
--#define HCIRESETSTAT _IOW('H', 204, int)
--#define HCIGETINFO _IOR('H', 205, int)
--#define HCIGETDEVLIST _IOR('H', 206, int)
--#define HCISETRAW _IOW('H', 207, int)
--#define HCISETSCAN _IOW('H', 208, int)
--#define HCISETAUTH _IOW('H', 209, int)
--#define HCIINQUIRY _IOR('H', 210, int)
--#define HCISETPTYPE _IOW('H', 211, int)
-+#define HCIDEVRESTAT _IOW('H', 204, int)
-+
-+#define HCIGETDEVLIST _IOR('H', 210, int)
-+#define HCIGETDEVINFO _IOR('H', 211, int)
- #define HCIGETCONNLIST _IOR('H', 212, int)
-+#define HCIGETCONNINFO _IOR('H', 213, int)
-
--#ifndef __NO_HCI_DEFS
-+#define HCISETRAW _IOW('H', 220, int)
-+#define HCISETSCAN _IOW('H', 221, int)
-+#define HCISETAUTH _IOW('H', 222, int)
-+#define HCISETENCRYPT _IOW('H', 223, int)
-+#define HCISETPTYPE _IOW('H', 224, int)
-+#define HCISETLINKPOL _IOW('H', 225, int)
-+#define HCISETLINKMODE _IOW('H', 226, int)
-+#define HCISETACLMTU _IOW('H', 227, int)
-+#define HCISETSCOMTU _IOW('H', 228, int)
-+
-+#define HCIINQUIRY _IOR('H', 240, int)
-+
-+/* HCI timeouts */
-+#define HCI_CONN_TIMEOUT (HZ * 40)
-+#define HCI_DISCONN_TIMEOUT (HZ * 2)
-+#define HCI_CONN_IDLE_TIMEOUT (HZ * 60)
-
- /* HCI Packet types */
- #define HCI_COMMAND_PKT 0x01
-@@ -92,11 +113,18 @@
- #define HCI_DH3 0x0800
- #define HCI_DH5 0x8000
-
-+#define HCI_HV1 0x0020
-+#define HCI_HV2 0x0040
-+#define HCI_HV3 0x0080
-+
-+#define SCO_PTYPE_MASK (HCI_HV1 | HCI_HV2 | HCI_HV3)
-+#define ACL_PTYPE_MASK (~SCO_PTYPE_MASK)
-+
- /* ACL flags */
--#define ACL_CONT 0x0001
--#define ACL_START 0x0002
--#define ACL_ACTIVE_BCAST 0x0010
--#define ACL_PICO_BCAST 0x0020
-+#define ACL_CONT 0x01
-+#define ACL_START 0x02
-+#define ACL_ACTIVE_BCAST 0x04
-+#define ACL_PICO_BCAST 0x08
-
- /* Baseband links */
- #define SCO_LINK 0x00
-@@ -125,6 +153,20 @@
- #define LMP_PSCHEME 0x02
- #define LMP_PCONTROL 0x04
-
-+/* Link policies */
-+#define HCI_LP_RSWITCH 0x0001
-+#define HCI_LP_HOLD 0x0002
-+#define HCI_LP_SNIFF 0x0004
-+#define HCI_LP_PARK 0x0008
-+
-+/* Link mode */
-+#define HCI_LM_ACCEPT 0x8000
-+#define HCI_LM_MASTER 0x0001
-+#define HCI_LM_AUTH 0x0002
-+#define HCI_LM_ENCRYPT 0x0004
-+#define HCI_LM_TRUSTED 0x0008
-+#define HCI_LM_RELIABLE 0x0010
-+
- /* ----- HCI Commands ----- */
- /* OGF & OCF values */
-
-@@ -137,9 +179,10 @@
- __u8 hci_ver;
- __u16 hci_rev;
- __u8 lmp_ver;
-- __u16 man_name;
-- __u16 lmp_sub;
-+ __u16 manufacturer;
-+ __u16 lmp_subver;
- } __attribute__ ((packed)) read_local_version_rp;
-+#define READ_LOCAL_VERSION_RP_SIZE 9
-
- #define OCF_READ_LOCAL_FEATURES 0x0003
- typedef struct {
-@@ -165,18 +208,24 @@
- /* Host Controller and Baseband */
- #define OGF_HOST_CTL 0x03
- #define OCF_RESET 0x0003
-+#define OCF_READ_AUTH_ENABLE 0x001F
- #define OCF_WRITE_AUTH_ENABLE 0x0020
-- #define AUTH_DISABLED 0x00
-- #define AUTH_ENABLED 0x01
-+ #define AUTH_DISABLED 0x00
-+ #define AUTH_ENABLED 0x01
-+
-+#define OCF_READ_ENCRYPT_MODE 0x0021
-+#define OCF_WRITE_ENCRYPT_MODE 0x0022
-+ #define ENCRYPT_DISABLED 0x00
-+ #define ENCRYPT_P2P 0x01
-+ #define ENCRYPT_BOTH 0x02
-
- #define OCF_WRITE_CA_TIMEOUT 0x0016
- #define OCF_WRITE_PG_TIMEOUT 0x0018
-
- #define OCF_WRITE_SCAN_ENABLE 0x001A
-- #define SCANS_DISABLED 0x00
-- #define IS_ENA_PS_DIS 0x01
-- #define IS_DIS_PS_ENA 0x02
-- #define IS_ENA_PS_ENA 0x03
-+ #define SCAN_DISABLED 0x00
-+ #define SCAN_INQUIRY 0x01
-+ #define SCAN_PAGE 0x02
-
- #define OCF_SET_EVENT_FLT 0x0005
- typedef struct {
-@@ -226,9 +275,18 @@
- } __attribute__ ((packed)) write_class_of_dev_cp;
- #define WRITE_CLASS_OF_DEV_CP_SIZE 3
-
-+#define OCF_HOST_BUFFER_SIZE 0x0033
-+typedef struct {
-+ __u16 acl_mtu;
-+ __u8 sco_mtu;
-+ __u16 acl_max_pkt;
-+ __u16 sco_max_pkt;
-+} __attribute__ ((packed)) host_buffer_size_cp;
-+#define HOST_BUFFER_SIZE_CP_SIZE 7
-+
- /* Link Control */
- #define OGF_LINK_CTL 0x01
--#define OCF_CREATE_CONN 0x0005
-+#define OCF_CREATE_CONN 0x0005
- typedef struct {
- bdaddr_t bdaddr;
- __u16 pkt_type;
-@@ -246,6 +304,13 @@
- } __attribute__ ((packed)) accept_conn_req_cp;
- #define ACCEPT_CONN_REQ_CP_SIZE 7
-
-+#define OCF_REJECT_CONN_REQ 0x000a
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 reason;
-+} __attribute__ ((packed)) reject_conn_req_cp;
-+#define REJECT_CONN_REQ_CP_SIZE 7
-+
- #define OCF_DISCONNECT 0x0006
- typedef struct {
- __u16 handle;
-@@ -253,17 +318,142 @@
- } __attribute__ ((packed)) disconnect_cp;
- #define DISCONNECT_CP_SIZE 3
-
-+#define OCF_ADD_SCO 0x0007
-+typedef struct {
-+ __u16 handle;
-+ __u16 pkt_type;
-+} __attribute__ ((packed)) add_sco_cp;
-+#define ADD_SCO_CP_SIZE 4
-+
- #define OCF_INQUIRY 0x0001
- typedef struct {
- __u8 lap[3];
-- __u8 lenght;
-+ __u8 length;
- __u8 num_rsp;
- } __attribute__ ((packed)) inquiry_cp;
- #define INQUIRY_CP_SIZE 5
-
--#define OGF_LINK_POLICY 0x02 /* Link Policy */
-+typedef struct {
-+ __u8 status;
-+ bdaddr_t bdaddr;
-+} __attribute__ ((packed)) status_bdaddr_rp;
-+#define STATUS_BDADDR_RP_SIZE 7
-+
-+#define OCF_INQUIRY_CANCEL 0x0002
-+
-+#define OCF_LINK_KEY_REPLY 0x000B
-+#define OCF_LINK_KEY_NEG_REPLY 0x000C
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 link_key[16];
-+} __attribute__ ((packed)) link_key_reply_cp;
-+#define LINK_KEY_REPLY_CP_SIZE 22
-+
-+#define OCF_PIN_CODE_REPLY 0x000D
-+#define OCF_PIN_CODE_NEG_REPLY 0x000E
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 pin_len;
-+ __u8 pin_code[16];
-+} __attribute__ ((packed)) pin_code_reply_cp;
-+#define PIN_CODE_REPLY_CP_SIZE 23
-+
-+#define OCF_CHANGE_CONN_PTYPE 0x000F
-+typedef struct {
-+ __u16 handle;
-+ __u16 pkt_type;
-+} __attribute__ ((packed)) change_conn_ptype_cp;
-+#define CHANGE_CONN_PTYPE_CP_SIZE 4
-+
-+#define OCF_AUTH_REQUESTED 0x0011
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) auth_requested_cp;
-+#define AUTH_REQUESTED_CP_SIZE 2
-+
-+#define OCF_SET_CONN_ENCRYPT 0x0013
-+typedef struct {
-+ __u16 handle;
-+ __u8 encrypt;
-+} __attribute__ ((packed)) set_conn_encrypt_cp;
-+#define SET_CONN_ENCRYPT_CP_SIZE 3
-+
-+#define OCF_REMOTE_NAME_REQ 0x0019
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 pscan_rep_mode;
-+ __u8 pscan_mode;
-+ __u16 clock_offset;
-+} __attribute__ ((packed)) remote_name_req_cp;
-+#define REMOTE_NAME_REQ_CP_SIZE 10
-+
-+#define OCF_READ_REMOTE_FEATURES 0x001B
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) read_remote_features_cp;
-+#define READ_REMOTE_FEATURES_CP_SIZE 2
-+
-+#define OCF_READ_REMOTE_VERSION 0x001D
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) read_remote_version_cp;
-+#define READ_REMOTE_VERSION_CP_SIZE 2
-+
-+/* Link Policy */
-+#define OGF_LINK_POLICY 0x02
-+#define OCF_ROLE_DISCOVERY 0x0009
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) role_discovery_cp;
-+#define ROLE_DISCOVERY_CP_SIZE 2
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u8 role;
-+} __attribute__ ((packed)) role_discovery_rp;
-+#define ROLE_DISCOVERY_RP_SIZE 4
-+
-+#define OCF_READ_LINK_POLICY 0x000C
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) read_link_policy_cp;
-+#define READ_LINK_POLICY_CP_SIZE 2
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u16 policy;
-+} __attribute__ ((packed)) read_link_policy_rp;
-+#define READ_LINK_POLICY_RP_SIZE 5
-
--/* --------- HCI Events --------- */
-+#define OCF_SWITCH_ROLE 0x000B
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 role;
-+} __attribute__ ((packed)) switch_role_cp;
-+#define SWITCH_ROLE_CP_SIZE 7
-+
-+#define OCF_WRITE_LINK_POLICY 0x000D
-+typedef struct {
-+ __u16 handle;
-+ __u16 policy;
-+} __attribute__ ((packed)) write_link_policy_cp;
-+#define WRITE_LINK_POLICY_CP_SIZE 4
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+} __attribute__ ((packed)) write_link_policy_rp;
-+#define WRITE_LINK_POLICY_RP_SIZE 3
-+
-+/* Status params */
-+#define OGF_STATUS_PARAM 0x05
-+
-+/* Testing commands */
-+#define OGF_TESTING_CMD 0x3e
-+
-+/* Vendor specific commands */
-+#define OGF_VENDOR_CMD 0x3f
-+
-+/* ---- HCI Events ---- */
- #define EVT_INQUIRY_COMPLETE 0x01
-
- #define EVT_INQUIRY_RESULT 0x02
-@@ -272,11 +462,22 @@
- __u8 pscan_rep_mode;
- __u8 pscan_period_mode;
- __u8 pscan_mode;
-- __u8 class[3];
-+ __u8 dev_class[3];
- __u16 clock_offset;
- } __attribute__ ((packed)) inquiry_info;
- #define INQUIRY_INFO_SIZE 14
-
-+#define EVT_INQUIRY_RESULT_WITH_RSSI 0x22
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 pscan_rep_mode;
-+ __u8 pscan_period_mode;
-+ __u8 dev_class[3];
-+ __u16 clock_offset;
-+ __s8 rssi;
-+} __attribute__ ((packed)) inquiry_info_with_rssi;
-+#define INQUIRY_INFO_WITH_RSSI_SIZE 14
-+
- #define EVT_CONN_COMPLETE 0x03
- typedef struct {
- __u8 status;
-@@ -303,6 +504,44 @@
- } __attribute__ ((packed)) evt_disconn_complete;
- #define EVT_DISCONN_COMPLETE_SIZE 4
-
-+#define EVT_AUTH_COMPLETE 0x06
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+} __attribute__ ((packed)) evt_auth_complete;
-+#define EVT_AUTH_COMPLETE_SIZE 3
-+
-+#define EVT_REMOTE_NAME_REQ_COMPLETE 0x07
-+typedef struct {
-+ __u8 status;
-+ bdaddr_t bdaddr;
-+ __u8 name[248];
-+} __attribute__ ((packed)) evt_remote_name_req_complete;
-+#define EVT_REMOTE_NAME_REQ_COMPLETE_SIZE 255
-+
-+#define EVT_ENCRYPT_CHANGE 0x08
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u8 encrypt;
-+} __attribute__ ((packed)) evt_encrypt_change;
-+#define EVT_ENCRYPT_CHANGE_SIZE 5
-+
-+#define EVT_QOS_SETUP_COMPLETE 0x0D
-+typedef struct {
-+ __u8 service_type;
-+ __u32 token_rate;
-+ __u32 peak_bandwidth;
-+ __u32 latency;
-+ __u32 delay_variation;
-+} __attribute__ ((packed)) hci_qos;
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ hci_qos qos;
-+} __attribute__ ((packed)) evt_qos_setup_complete;
-+#define EVT_QOS_SETUP_COMPLETE_SIZE 20
-+
- #define EVT_CMD_COMPLETE 0x0e
- typedef struct {
- __u8 ncmd;
-@@ -321,16 +560,78 @@
- #define EVT_NUM_COMP_PKTS 0x13
- typedef struct {
- __u8 num_hndl;
-- /* variable lenght part */
-+ /* variable length part */
- } __attribute__ ((packed)) evt_num_comp_pkts;
- #define EVT_NUM_COMP_PKTS_SIZE 1
-
--#define EVT_HCI_DEV_EVENT 0xfd
-+#define EVT_ROLE_CHANGE 0x12
-+typedef struct {
-+ __u8 status;
-+ bdaddr_t bdaddr;
-+ __u8 role;
-+} __attribute__ ((packed)) evt_role_change;
-+#define EVT_ROLE_CHANGE_SIZE 8
-+
-+#define EVT_PIN_CODE_REQ 0x16
-+typedef struct {
-+ bdaddr_t bdaddr;
-+} __attribute__ ((packed)) evt_pin_code_req;
-+#define EVT_PIN_CODE_REQ_SIZE 6
-+
-+#define EVT_LINK_KEY_REQ 0x17
-+typedef struct {
-+ bdaddr_t bdaddr;
-+} __attribute__ ((packed)) evt_link_key_req;
-+#define EVT_LINK_KEY_REQ_SIZE 6
-+
-+#define EVT_LINK_KEY_NOTIFY 0x18
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 link_key[16];
-+ __u8 key_type;
-+} __attribute__ ((packed)) evt_link_key_notify;
-+#define EVT_LINK_KEY_NOTIFY_SIZE 23
-+
-+#define EVT_READ_REMOTE_FEATURES_COMPLETE 0x0B
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u8 features[8];
-+} __attribute__ ((packed)) evt_read_remote_features_complete;
-+#define EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE 11
-+
-+#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u8 lmp_ver;
-+ __u16 manufacturer;
-+ __u16 lmp_subver;
-+} __attribute__ ((packed)) evt_read_remote_version_complete;
-+#define EVT_READ_REMOTE_VERSION_COMPLETE_SIZE 8
-+
-+/* Internal events generated by BlueZ stack */
-+#define EVT_STACK_INTERNAL 0xfd
-+typedef struct {
-+ __u16 type;
-+ __u8 data[0];
-+} __attribute__ ((packed)) evt_stack_internal;
-+#define EVT_STACK_INTERNAL_SIZE 2
-+
-+#define EVT_SI_DEVICE 0x01
-+typedef struct {
-+ __u16 event;
-+ __u16 dev_id;
-+} __attribute__ ((packed)) evt_si_device;
-+#define EVT_SI_DEVICE_SIZE 4
-+
-+#define EVT_SI_SECURITY 0x02
- typedef struct {
- __u16 event;
-- __u16 param;
--} __attribute__ ((packed)) evt_hci_dev_event;
--#define EVT_HCI_DEV_EVENT_SIZE 4
-+ __u16 proto;
-+ __u16 subproto;
-+ __u8 incomming;
-+} __attribute__ ((packed)) evt_si_security;
-
- /* -------- HCI Packet structures -------- */
- #define HCI_TYPE_LEN 1
-@@ -369,14 +670,14 @@
- #define acl_handle(h) (h & 0x0fff)
- #define acl_flags(h) (h >> 12)
-
--#endif /* _NO_HCI_DEFS */
--
- /* HCI Socket options */
--#define HCI_DATA_DIR 0x0001
--#define HCI_FILTER 0x0002
-+#define HCI_DATA_DIR 1
-+#define HCI_FILTER 2
-+#define HCI_TIME_STAMP 3
-
- /* HCI CMSG flags */
- #define HCI_CMSG_DIR 0x0001
-+#define HCI_CMSG_TSTAMP 0x0002
-
- struct sockaddr_hci {
- sa_family_t hci_family;
-@@ -387,27 +688,29 @@
- struct hci_filter {
- __u32 type_mask;
- __u32 event_mask[2];
-+ __u16 opcode;
- };
-
--struct hci_dev_req {
-- __u16 dev_id;
-- __u32 dev_opt;
--};
--
--struct hci_dev_list_req {
-- __u16 dev_num;
-- struct hci_dev_req dev_req[0]; /* hci_dev_req structures */
--};
--
--struct hci_inquiry_req {
-- __u16 dev_id;
-- __u16 flags;
-- __u8 lap[3];
-- __u8 length;
-- __u8 num_rsp;
--};
--#define IREQ_CACHE_FLUSH 0x0001
-+#define HCI_FLT_TYPE_BITS 31
-+#define HCI_FLT_EVENT_BITS 63
-+#define HCI_FLT_OGF_BITS 63
-+#define HCI_FLT_OCF_BITS 127
-+
-+#if BITS_PER_LONG == 64
-+static inline void hci_set_bit(int nr, void *addr)
-+{
-+ *((__u32 *) addr + (nr >> 5)) |= ((__u32) 1 << (nr & 31));
-+}
-+static inline int hci_test_bit(int nr, void *addr)
-+{
-+ return *((__u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
-+}
-+#else
-+#define hci_set_bit set_bit
-+#define hci_test_bit test_bit
-+#endif
-
-+/* Ioctl requests structures */
- struct hci_dev_stats {
- __u32 err_rx;
- __u32 err_tx;
-@@ -433,11 +736,13 @@
- __u8 features[8];
-
- __u32 pkt_type;
-+ __u32 link_policy;
-+ __u32 link_mode;
-
- __u16 acl_mtu;
-- __u16 acl_max;
-+ __u16 acl_pkts;
- __u16 sco_mtu;
-- __u16 sco_max;
-+ __u16 sco_pkts;
-
- struct hci_dev_stats stat;
- };
-@@ -445,6 +750,20 @@
- struct hci_conn_info {
- __u16 handle;
- bdaddr_t bdaddr;
-+ __u8 type;
-+ __u8 out;
-+ __u16 state;
-+ __u32 link_mode;
-+};
-+
-+struct hci_dev_req {
-+ __u16 dev_id;
-+ __u32 dev_opt;
-+};
-+
-+struct hci_dev_list_req {
-+ __u16 dev_num;
-+ struct hci_dev_req dev_req[0]; /* hci_dev_req structures */
- };
-
- struct hci_conn_list_req {
-@@ -453,4 +772,26 @@
- struct hci_conn_info conn_info[0];
- };
-
-+struct hci_conn_info_req {
-+ bdaddr_t bdaddr;
-+ __u8 type;
-+ struct hci_conn_info conn_info[0];
-+};
-+
-+struct hci_inquiry_req {
-+ __u16 dev_id;
-+ __u16 flags;
-+ __u8 lap[3];
-+ __u8 length;
-+ __u8 num_rsp;
-+};
-+#define IREQ_CACHE_FLUSH 0x0001
-+
-+struct hci_remotename_req {
-+ __u16 dev_id;
-+ __u16 flags;
-+ bdaddr_t bdaddr;
-+ __u8 name[248];
-+};
-+
- #endif /* __HCI_H */
-diff -urN linux-2.4.18/include/net/bluetooth/hci_uart.h linux-2.4.18-mh15/include/net/bluetooth/hci_uart.h
---- linux-2.4.18/include/net/bluetooth/hci_uart.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/hci_uart.h 1970-01-01 01:00:00.000000000 +0100
-@@ -1,62 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifndef N_HCI
--#define N_HCI 15
--#endif
--
--#ifdef __KERNEL__
--
--#define tty2n_hci(tty) ((struct n_hci *)((tty)->disc_data))
--#define n_hci2tty(n_hci) ((n_hci)->tty)
--
--struct n_hci {
-- struct tty_struct *tty;
-- struct hci_dev hdev;
--
-- struct sk_buff_head txq;
-- unsigned long tx_state;
--
-- spinlock_t rx_lock;
-- unsigned long rx_state;
-- unsigned long rx_count;
-- struct sk_buff *rx_skb;
--};
--
--/* Transmit states */
--#define TRANS_SENDING 1
--#define TRANS_WAKEUP 2
--
--/* Receiver States */
--#define WAIT_PACKET_TYPE 0
--#define WAIT_EVENT_HDR 1
--#define WAIT_ACL_HDR 2
--#define WAIT_SCO_HDR 3
--#define WAIT_DATA 4
--
--#endif /* __KERNEL__ */
-diff -urN linux-2.4.18/include/net/bluetooth/hci_usb.h linux-2.4.18-mh15/include/net/bluetooth/hci_usb.h
---- linux-2.4.18/include/net/bluetooth/hci_usb.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/hci_usb.h 1970-01-01 01:00:00.000000000 +0100
-@@ -1,68 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifdef __KERNEL__
--
--/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
--#define HCI_DEV_CLASS 0xe0 /* Wireless class */
--#define HCI_DEV_SUBCLASS 0x01 /* RF subclass */
--#define HCI_DEV_PROTOCOL 0x01 /* Bluetooth programming protocol */
--
--#define HCI_CTRL_REQ 0x20
--
--struct hci_usb {
-- struct usb_device *udev;
--
-- devrequest dev_req;
-- struct urb *ctrl_urb;
-- struct urb *intr_urb;
-- struct urb *read_urb;
-- struct urb *write_urb;
--
-- __u8 *read_buf;
-- __u8 *intr_buf;
-- struct sk_buff *intr_skb;
-- int intr_count;
--
-- __u8 bulk_out_ep_addr;
-- __u8 bulk_in_ep_addr;
-- __u8 intr_in_ep_addr;
-- __u8 intr_in_interval;
--
-- struct hci_dev hdev;
--
-- unsigned long tx_state;
-- struct sk_buff_head tx_ctrl_q;
-- struct sk_buff_head tx_write_q;
--};
--
--/* Transmit states */
--#define HCI_TX_CTRL 1
--#define HCI_TX_WRITE 2
--
--#endif /* __KERNEL__ */
-diff -urN linux-2.4.18/include/net/bluetooth/hci_vhci.h linux-2.4.18-mh15/include/net/bluetooth/hci_vhci.h
---- linux-2.4.18/include/net/bluetooth/hci_vhci.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/hci_vhci.h 1970-01-01 01:00:00.000000000 +0100
-@@ -1,50 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifndef __HCI_VHCI_H
--#define __HCI_VHCI_H
--
--#ifdef __KERNEL__
--
--struct hci_vhci_struct {
-- struct hci_dev hdev;
-- __u32 flags;
-- wait_queue_head_t read_wait;
-- struct sk_buff_head readq;
-- struct fasync_struct *fasync;
--};
--
--/* VHCI device flags */
--#define VHCI_FASYNC 0x0010
--
--#endif /* __KERNEL__ */
--
--#define VHCI_DEV "/dev/vhci"
--#define VHCI_MINOR 250
--
--#endif /* __HCI_VHCI_H */
-diff -urN linux-2.4.18/include/net/bluetooth/l2cap_core.h linux-2.4.18-mh15/include/net/bluetooth/l2cap_core.h
---- linux-2.4.18/include/net/bluetooth/l2cap_core.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/l2cap_core.h 1970-01-01 01:00:00.000000000 +0100
-@@ -1,144 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifndef __L2CAP_CORE_H
--#define __L2CAP_CORE_H
--
--#ifdef __KERNEL__
--
--/* ----- L2CAP interface ----- */
--struct l2cap_iff {
-- struct list_head list;
-- struct hci_dev *hdev;
-- bdaddr_t *bdaddr;
-- __u16 mtu;
-- spinlock_t lock;
-- struct list_head conn_list;
--};
--
--static inline void l2cap_iff_lock(struct l2cap_iff *iff)
--{
-- spin_lock(&iff->lock);
--}
--
--static inline void l2cap_iff_unlock(struct l2cap_iff *iff)
--{
-- spin_unlock(&iff->lock);
--}
--
--/* ----- L2CAP connections ----- */
--struct l2cap_chan_list {
-- struct sock *head;
-- rwlock_t lock;
-- long num;
--};
--
--struct l2cap_conn {
-- struct l2cap_iff *iff;
-- struct list_head list;
--
-- struct hci_conn *hconn;
--
-- __u16 state;
-- __u8 out;
-- bdaddr_t src;
-- bdaddr_t dst;
--
-- spinlock_t lock;
-- atomic_t refcnt;
--
-- struct sk_buff *rx_skb;
-- __u32 rx_len;
-- __u8 rx_ident;
-- __u8 tx_ident;
--
-- struct l2cap_chan_list chan_list;
--
-- struct timer_list timer;
--};
--
--static inline void __l2cap_conn_link(struct l2cap_iff *iff, struct l2cap_conn *c)
--{
-- list_add(&c->list, &iff->conn_list);
--}
--
--static inline void __l2cap_conn_unlink(struct l2cap_iff *iff, struct l2cap_conn *c)
--{
-- list_del(&c->list);
--}
--
--/* ----- L2CAP channel and socket info ----- */
--#define l2cap_pi(sk) ((struct l2cap_pinfo *) &sk->protinfo)
--
--struct l2cap_accept_q {
-- struct sock *head;
-- struct sock *tail;
--};
--
--struct l2cap_pinfo {
-- bdaddr_t src;
-- bdaddr_t dst;
-- __u16 psm;
-- __u16 dcid;
-- __u16 scid;
-- __u32 flags;
--
-- __u16 imtu;
-- __u16 omtu;
-- __u16 flush_to;
--
-- __u8 conf_state;
-- __u16 conf_mtu;
--
-- __u8 ident;
--
-- struct l2cap_conn *conn;
-- struct sock *next_c;
-- struct sock *prev_c;
--
-- struct sock *parent;
-- struct sock *next_q;
-- struct sock *prev_q;
--
-- struct l2cap_accept_q accept_q;
--};
--
--#define CONF_REQ_SENT 0x01
--#define CONF_INPUT_DONE 0x02
--#define CONF_OUTPUT_DONE 0x04
--
--extern struct bluez_sock_list l2cap_sk_list;
--extern struct list_head l2cap_iff_list;
--extern rwlock_t l2cap_rt_lock;
--
--extern void l2cap_register_proc(void);
--extern void l2cap_unregister_proc(void);
--
--#endif /* __KERNEL__ */
--
--#endif /* __L2CAP_CORE_H */
-diff -urN linux-2.4.18/include/net/bluetooth/l2cap.h linux-2.4.18-mh15/include/net/bluetooth/l2cap.h
---- linux-2.4.18/include/net/bluetooth/l2cap.h 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/include/net/bluetooth/l2cap.h 2004-08-01 16:26:23.000000000 +0200
-@@ -23,22 +23,17 @@
- */
-
- /*
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __L2CAP_H
- #define __L2CAP_H
-
--#include <asm/types.h>
--#include <asm/byteorder.h>
--
- /* L2CAP defaults */
- #define L2CAP_DEFAULT_MTU 672
- #define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
-
- #define L2CAP_CONN_TIMEOUT (HZ * 40)
--#define L2CAP_DISCONN_TIMEOUT (HZ * 2)
--#define L2CAP_CONN_IDLE_TIMEOUT (HZ * 60)
-
- /* L2CAP socket address */
- struct sockaddr_l2 {
-@@ -47,17 +42,12 @@
- bdaddr_t l2_bdaddr;
- };
-
--/* set/get sockopt defines */
--#define L2CAP_OPTIONS 0x01
-+/* Socket options */
-+#define L2CAP_OPTIONS 0x01
- struct l2cap_options {
- __u16 omtu;
- __u16 imtu;
- __u16 flush_to;
-- __u32 token_rate;
-- __u32 bucket_size;
-- __u32 pick_band;
-- __u32 latency;
-- __u32 delay_var;
- };
-
- #define L2CAP_CONNINFO 0x02
-@@ -65,6 +55,27 @@
- __u16 hci_handle;
- };
-
-+#define L2CAP_LM 0x03
-+#define L2CAP_LM_MASTER 0x0001
-+#define L2CAP_LM_AUTH 0x0002
-+#define L2CAP_LM_ENCRYPT 0x0004
-+#define L2CAP_LM_TRUSTED 0x0008
-+#define L2CAP_LM_RELIABLE 0x0010
-+
-+#define L2CAP_QOS 0x04
-+struct l2cap_qos {
-+ __u16 service_type;
-+ __u32 token_rate;
-+ __u32 token_bucket_size;
-+ __u32 peak_bandwidth;
-+ __u32 latency;
-+ __u32 delay_variation;
-+};
-+
-+#define L2CAP_SERV_NO_TRAFFIC 0x00
-+#define L2CAP_SERV_BEST_EFFORT 0x01
-+#define L2CAP_SERV_GUARANTEED 0x02
-+
- /* L2CAP command codes */
- #define L2CAP_COMMAND_REJ 0x01
- #define L2CAP_CONN_REQ 0x02
-@@ -79,7 +90,6 @@
- #define L2CAP_INFO_RSP 0x0b
-
- /* L2CAP structures */
--
- typedef struct {
- __u16 len;
- __u16 cid;
-@@ -112,11 +122,17 @@
- } __attribute__ ((packed)) l2cap_conn_rsp;
- #define L2CAP_CONN_RSP_SIZE 8
-
--#define L2CAP_CONN_SUCCESS 0x0000
--#define L2CAP_CONN_PEND 0x0001
--#define L2CAP_CONN_BAD_PSM 0x0002
--#define L2CAP_CONN_SEC_BLOCK 0x0003
--#define L2CAP_CONN_NO_MEM 0x0004
-+/* connect result */
-+#define L2CAP_CR_SUCCESS 0x0000
-+#define L2CAP_CR_PEND 0x0001
-+#define L2CAP_CR_BAD_PSM 0x0002
-+#define L2CAP_CR_SEC_BLOCK 0x0003
-+#define L2CAP_CR_NO_MEM 0x0004
-+
-+/* connect status */
-+#define L2CAP_CS_NO_INFO 0x0000
-+#define L2CAP_CS_AUTHEN_PEND 0x0001
-+#define L2CAP_CS_AUTHOR_PEND 0x0002
-
- typedef struct {
- __u16 dcid;
-@@ -147,6 +163,8 @@
- #define L2CAP_CONF_FLUSH_TO 0x02
- #define L2CAP_CONF_QOS 0x03
-
-+#define L2CAP_CONF_MAX_SIZE 22
-+
- typedef struct {
- __u16 dcid;
- __u16 scid;
-@@ -159,4 +177,82 @@
- } __attribute__ ((packed)) l2cap_disconn_rsp;
- #define L2CAP_DISCONN_RSP_SIZE 4
-
-+typedef struct {
-+ __u16 type;
-+ __u8 data[0];
-+} __attribute__ ((packed)) l2cap_info_req;
-+#define L2CAP_INFO_REQ_SIZE 2
-+
-+typedef struct {
-+ __u16 type;
-+ __u16 result;
-+ __u8 data[0];
-+} __attribute__ ((packed)) l2cap_info_rsp;
-+#define L2CAP_INFO_RSP_SIZE 4
-+
-+/* info type */
-+#define L2CAP_IT_CL_MTU 0x0001
-+#define L2CAP_IT_FEAT_MASK 0x0002
-+
-+/* info result */
-+#define L2CAP_IR_SUCCESS 0x0000
-+#define L2CAP_IR_NOTSUPP 0x0001
-+
-+/* ----- L2CAP connections ----- */
-+struct l2cap_chan_list {
-+ struct sock *head;
-+ rwlock_t lock;
-+ long num;
-+};
-+
-+struct l2cap_conn {
-+ struct hci_conn *hcon;
-+
-+ bdaddr_t *dst;
-+ bdaddr_t *src;
-+
-+ unsigned int mtu;
-+
-+ spinlock_t lock;
-+
-+ struct sk_buff *rx_skb;
-+ __u32 rx_len;
-+ __u8 rx_ident;
-+ __u8 tx_ident;
-+
-+ struct l2cap_chan_list chan_list;
-+};
-+
-+/* ----- L2CAP channel and socket info ----- */
-+#define l2cap_pi(sk) ((struct l2cap_pinfo *) &sk->tp_pinfo)
-+
-+struct l2cap_pinfo {
-+ __u16 psm;
-+ __u16 dcid;
-+ __u16 scid;
-+
-+ __u16 imtu;
-+ __u16 omtu;
-+ __u16 flush_to;
-+
-+ __u32 link_mode;
-+
-+ __u8 conf_state;
-+ __u8 conf_retry;
-+ __u16 conf_mtu;
-+
-+ __u8 ident;
-+
-+ struct l2cap_conn *conn;
-+ struct sock *next_c;
-+ struct sock *prev_c;
-+};
-+
-+#define L2CAP_CONF_REQ_SENT 0x01
-+#define L2CAP_CONF_INPUT_DONE 0x02
-+#define L2CAP_CONF_OUTPUT_DONE 0x04
-+#define L2CAP_CONF_MAX_RETRIES 2
-+
-+void l2cap_load(void);
-+
- #endif /* __L2CAP_H */
-diff -urN linux-2.4.18/include/net/bluetooth/rfcomm.h linux-2.4.18-mh15/include/net/bluetooth/rfcomm.h
---- linux-2.4.18/include/net/bluetooth/rfcomm.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/include/net/bluetooth/rfcomm.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,361 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ RPN support - Dirk Husemann <hud@zurich.ibm.com>
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef __RFCOMM_H
-+#define __RFCOMM_H
-+
-+#define RFCOMM_PSM 3
-+
-+#define RFCOMM_CONN_TIMEOUT (HZ * 30)
-+#define RFCOMM_DISC_TIMEOUT (HZ * 20)
-+
-+#define RFCOMM_DEFAULT_MTU 127
-+#define RFCOMM_DEFAULT_CREDITS 7
-+
-+#define RFCOMM_MAX_L2CAP_MTU 1024
-+#define RFCOMM_MAX_CREDITS 40
-+
-+#define RFCOMM_SKB_HEAD_RESERVE 8
-+#define RFCOMM_SKB_TAIL_RESERVE 2
-+#define RFCOMM_SKB_RESERVE (RFCOMM_SKB_HEAD_RESERVE + RFCOMM_SKB_TAIL_RESERVE)
-+
-+#define RFCOMM_SABM 0x2f
-+#define RFCOMM_DISC 0x43
-+#define RFCOMM_UA 0x63
-+#define RFCOMM_DM 0x0f
-+#define RFCOMM_UIH 0xef
-+
-+#define RFCOMM_TEST 0x08
-+#define RFCOMM_FCON 0x28
-+#define RFCOMM_FCOFF 0x18
-+#define RFCOMM_MSC 0x38
-+#define RFCOMM_RPN 0x24
-+#define RFCOMM_RLS 0x14
-+#define RFCOMM_PN 0x20
-+#define RFCOMM_NSC 0x04
-+
-+#define RFCOMM_V24_FC 0x02
-+#define RFCOMM_V24_RTC 0x04
-+#define RFCOMM_V24_RTR 0x08
-+#define RFCOMM_V24_IC 0x40
-+#define RFCOMM_V24_DV 0x80
-+
-+#define RFCOMM_RPN_BR_2400 0x0
-+#define RFCOMM_RPN_BR_4800 0x1
-+#define RFCOMM_RPN_BR_7200 0x2
-+#define RFCOMM_RPN_BR_9600 0x3
-+#define RFCOMM_RPN_BR_19200 0x4
-+#define RFCOMM_RPN_BR_38400 0x5
-+#define RFCOMM_RPN_BR_57600 0x6
-+#define RFCOMM_RPN_BR_115200 0x7
-+#define RFCOMM_RPN_BR_230400 0x8
-+
-+#define RFCOMM_RPN_DATA_5 0x0
-+#define RFCOMM_RPN_DATA_6 0x1
-+#define RFCOMM_RPN_DATA_7 0x2
-+#define RFCOMM_RPN_DATA_8 0x3
-+
-+#define RFCOMM_RPN_STOP_1 0
-+#define RFCOMM_RPN_STOP_15 1
-+
-+#define RFCOMM_RPN_PARITY_NONE 0x0
-+#define RFCOMM_RPN_PARITY_ODD 0x4
-+#define RFCOMM_RPN_PARITY_EVEN 0x5
-+#define RFCOMM_RPN_PARITY_MARK 0x6
-+#define RFCOMM_RPN_PARITY_SPACE 0x7
-+
-+#define RFCOMM_RPN_FLOW_NONE 0x00
-+
-+#define RFCOMM_RPN_XON_CHAR 0x11
-+#define RFCOMM_RPN_XOFF_CHAR 0x13
-+
-+#define RFCOMM_RPN_PM_BITRATE 0x0001
-+#define RFCOMM_RPN_PM_DATA 0x0002
-+#define RFCOMM_RPN_PM_STOP 0x0004
-+#define RFCOMM_RPN_PM_PARITY 0x0008
-+#define RFCOMM_RPN_PM_PARITY_TYPE 0x0010
-+#define RFCOMM_RPN_PM_XON 0x0020
-+#define RFCOMM_RPN_PM_XOFF 0x0040
-+#define RFCOMM_RPN_PM_FLOW 0x3F00
-+
-+#define RFCOMM_RPN_PM_ALL 0x3F7F
-+
-+struct rfcomm_hdr {
-+ u8 addr;
-+ u8 ctrl;
-+ u8 len; // Actual size can be 2 bytes
-+} __attribute__ ((packed));
-+
-+struct rfcomm_cmd {
-+ u8 addr;
-+ u8 ctrl;
-+ u8 len;
-+ u8 fcs;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_mcc {
-+ u8 type;
-+ u8 len;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_pn {
-+ u8 dlci;
-+ u8 flow_ctrl;
-+ u8 priority;
-+ u8 ack_timer;
-+ u16 mtu;
-+ u8 max_retrans;
-+ u8 credits;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_rpn {
-+ u8 dlci;
-+ u8 bit_rate;
-+ u8 line_settings;
-+ u8 flow_ctrl;
-+ u8 xon_char;
-+ u8 xoff_char;
-+ u16 param_mask;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_rls {
-+ u8 dlci;
-+ u8 status;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_msc {
-+ u8 dlci;
-+ u8 v24_sig;
-+} __attribute__ ((packed));
-+
-+/* ---- Core structures, flags etc ---- */
-+
-+struct rfcomm_session {
-+ struct list_head list;
-+ struct socket *sock;
-+ unsigned long state;
-+ unsigned long flags;
-+ atomic_t refcnt;
-+ int initiator;
-+
-+ /* Default DLC parameters */
-+ int cfc;
-+ uint mtu;
-+
-+ struct list_head dlcs;
-+};
-+
-+struct rfcomm_dlc {
-+ struct list_head list;
-+ struct rfcomm_session *session;
-+ struct sk_buff_head tx_queue;
-+ struct timer_list timer;
-+
-+ spinlock_t lock;
-+ unsigned long state;
-+ unsigned long flags;
-+ atomic_t refcnt;
-+ u8 dlci;
-+ u8 addr;
-+ u8 priority;
-+ u8 v24_sig;
-+ u8 mscex;
-+
-+ uint mtu;
-+ uint cfc;
-+ uint rx_credits;
-+ uint tx_credits;
-+
-+ void *owner;
-+
-+ void (*data_ready)(struct rfcomm_dlc *d, struct sk_buff *skb);
-+ void (*state_change)(struct rfcomm_dlc *d, int err);
-+ void (*modem_status)(struct rfcomm_dlc *d, u8 v24_sig);
-+};
-+
-+/* DLC and session flags */
-+#define RFCOMM_RX_THROTTLED 0
-+#define RFCOMM_TX_THROTTLED 1
-+#define RFCOMM_MSC_PENDING 2
-+#define RFCOMM_TIMED_OUT 3
-+
-+/* Scheduling flags and events */
-+#define RFCOMM_SCHED_STATE 0
-+#define RFCOMM_SCHED_RX 1
-+#define RFCOMM_SCHED_TX 2
-+#define RFCOMM_SCHED_TIMEO 3
-+#define RFCOMM_SCHED_WAKEUP 31
-+
-+/* MSC exchange flags */
-+#define RFCOMM_MSCEX_TX 1
-+#define RFCOMM_MSCEX_RX 2
-+#define RFCOMM_MSCEX_OK (RFCOMM_MSCEX_TX + RFCOMM_MSCEX_RX)
-+
-+/* CFC states */
-+#define RFCOMM_CFC_UNKNOWN -1
-+#define RFCOMM_CFC_DISABLED 0
-+#define RFCOMM_CFC_ENABLED RFCOMM_MAX_CREDITS
-+
-+extern struct task_struct *rfcomm_thread;
-+extern unsigned long rfcomm_event;
-+
-+static inline void rfcomm_schedule(uint event)
-+{
-+ if (!rfcomm_thread)
-+ return;
-+ set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
-+ wake_up_process(rfcomm_thread);
-+}
-+
-+extern struct semaphore rfcomm_sem;
-+#define rfcomm_lock() down(&rfcomm_sem);
-+#define rfcomm_unlock() up(&rfcomm_sem);
-+
-+/* ---- RFCOMM DLCs (channels) ---- */
-+struct rfcomm_dlc *rfcomm_dlc_alloc(int prio);
-+void rfcomm_dlc_free(struct rfcomm_dlc *d);
-+int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel);
-+int rfcomm_dlc_close(struct rfcomm_dlc *d, int reason);
-+int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb);
-+int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig);
-+int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig);
-+
-+#define rfcomm_dlc_lock(d) spin_lock(&d->lock)
-+#define rfcomm_dlc_unlock(d) spin_unlock(&d->lock)
-+
-+static inline void rfcomm_dlc_hold(struct rfcomm_dlc *d)
-+{
-+ atomic_inc(&d->refcnt);
-+}
-+
-+static inline void rfcomm_dlc_put(struct rfcomm_dlc *d)
-+{
-+ if (atomic_dec_and_test(&d->refcnt))
-+ rfcomm_dlc_free(d);
-+}
-+
-+extern void FASTCALL(__rfcomm_dlc_throttle(struct rfcomm_dlc *d));
-+extern void FASTCALL(__rfcomm_dlc_unthrottle(struct rfcomm_dlc *d));
-+
-+static inline void rfcomm_dlc_throttle(struct rfcomm_dlc *d)
-+{
-+ if (!test_and_set_bit(RFCOMM_RX_THROTTLED, &d->flags))
-+ __rfcomm_dlc_throttle(d);
-+}
-+
-+static inline void rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
-+{
-+ if (test_and_clear_bit(RFCOMM_RX_THROTTLED, &d->flags))
-+ __rfcomm_dlc_unthrottle(d);
-+}
-+
-+/* ---- RFCOMM sessions ---- */
-+struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state);
-+struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
-+struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err);
-+void rfcomm_session_del(struct rfcomm_session *s);
-+void rfcomm_session_close(struct rfcomm_session *s, int err);
-+void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst);
-+
-+static inline void rfcomm_session_hold(struct rfcomm_session *s)
-+{
-+ atomic_inc(&s->refcnt);
-+}
-+
-+static inline void rfcomm_session_put(struct rfcomm_session *s)
-+{
-+ if (atomic_dec_and_test(&s->refcnt))
-+ rfcomm_session_del(s);
-+}
-+
-+/* ---- RFCOMM chechsum ---- */
-+extern u8 rfcomm_crc_table[];
-+
-+/* ---- RFCOMM sockets ---- */
-+struct sockaddr_rc {
-+ sa_family_t rc_family;
-+ bdaddr_t rc_bdaddr;
-+ u8 rc_channel;
-+};
-+
-+#define rfcomm_pi(sk) ((struct rfcomm_pinfo *) &sk->tp_pinfo)
-+
-+struct rfcomm_pinfo {
-+ struct rfcomm_dlc *dlc;
-+ u8 channel;
-+};
-+
-+int rfcomm_init_sockets(void);
-+void rfcomm_cleanup_sockets(void);
-+
-+int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d);
-+
-+/* ---- RFCOMM TTY ---- */
-+#define RFCOMM_MAX_DEV 256
-+
-+#define RFCOMMCREATEDEV _IOW('R', 200, int)
-+#define RFCOMMRELEASEDEV _IOW('R', 201, int)
-+#define RFCOMMGETDEVLIST _IOR('R', 210, int)
-+#define RFCOMMGETDEVINFO _IOR('R', 211, int)
-+#define RFCOMMSTEALDLC _IOW('R', 220, int)
-+
-+#define RFCOMM_REUSE_DLC 0
-+#define RFCOMM_RELEASE_ONHUP 1
-+#define RFCOMM_HANGUP_NOW 2
-+#define RFCOMM_TTY_ATTACHED 3
-+
-+struct rfcomm_dev_req {
-+ s16 dev_id;
-+ u32 flags;
-+ bdaddr_t src;
-+ bdaddr_t dst;
-+ u8 channel;
-+};
-+
-+struct rfcomm_dev_info {
-+ s16 id;
-+ u32 flags;
-+ u16 state;
-+ bdaddr_t src;
-+ bdaddr_t dst;
-+ u8 channel;
-+};
-+
-+struct rfcomm_dev_list_req {
-+ u16 dev_num;
-+ struct rfcomm_dev_info dev_info[0];
-+};
-+
-+int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg);
-+int rfcomm_init_ttys(void);
-+void rfcomm_cleanup_ttys(void);
-+
-+#endif /* __RFCOMM_H */
-diff -urN linux-2.4.18/include/net/bluetooth/sco.h linux-2.4.18-mh15/include/net/bluetooth/sco.h
---- linux-2.4.18/include/net/bluetooth/sco.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/include/net/bluetooth/sco.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,81 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef __SCO_H
-+#define __SCO_H
-+
-+/* SCO defaults */
-+#define SCO_DEFAULT_MTU 500
-+#define SCO_DEFAULT_FLUSH_TO 0xFFFF
-+
-+#define SCO_CONN_TIMEOUT (HZ * 40)
-+#define SCO_DISCONN_TIMEOUT (HZ * 2)
-+#define SCO_CONN_IDLE_TIMEOUT (HZ * 60)
-+
-+/* SCO socket address */
-+struct sockaddr_sco {
-+ sa_family_t sco_family;
-+ bdaddr_t sco_bdaddr;
-+};
-+
-+/* set/get sockopt defines */
-+#define SCO_OPTIONS 0x01
-+struct sco_options {
-+ __u16 mtu;
-+};
-+
-+#define SCO_CONNINFO 0x02
-+struct sco_conninfo {
-+ __u16 hci_handle;
-+};
-+
-+/* ---- SCO connections ---- */
-+struct sco_conn {
-+ struct hci_conn *hcon;
-+
-+ bdaddr_t *dst;
-+ bdaddr_t *src;
-+
-+ spinlock_t lock;
-+ struct sock *sk;
-+
-+ unsigned int mtu;
-+};
-+
-+#define sco_conn_lock(c) spin_lock(&c->lock);
-+#define sco_conn_unlock(c) spin_unlock(&c->lock);
-+
-+/* ----- SCO socket info ----- */
-+#define sco_pi(sk) ((struct sco_pinfo *) &sk->tp_pinfo)
-+
-+struct sco_pinfo {
-+ __u32 flags;
-+ struct sco_conn *conn;
-+};
-+
-+#endif /* __SCO_H */
-diff -urN linux-2.4.18/include/pcmcia/ciscode.h linux-2.4.18-mh15/include/pcmcia/ciscode.h
---- linux-2.4.18/include/pcmcia/ciscode.h 2001-12-21 18:42:04.000000000 +0100
-+++ linux-2.4.18-mh15/include/pcmcia/ciscode.h 2004-08-01 16:26:23.000000000 +0200
-@@ -1,5 +1,5 @@
- /*
-- * ciscode.h 1.48 2001/08/24 12:16:12
-+ * ciscode.h 1.57 2002/11/03 20:38:14
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
-@@ -60,6 +60,10 @@
- #define PRODID_INTEL_DUAL_RS232 0x0301
- #define PRODID_INTEL_2PLUS 0x8422
-
-+#define MANFID_KME 0x0032
-+#define PRODID_KME_KXLC005_A 0x0704
-+#define PRODID_KME_KXLC005_B 0x2904
-+
- #define MANFID_LINKSYS 0x0143
- #define PRODID_LINKSYS_PCMLM28 0xc0ab
- #define PRODID_LINKSYS_3400 0x3341
-@@ -94,6 +98,8 @@
- #define PRODID_OSITECH_JACK_336 0x0007
- #define PRODID_OSITECH_SEVEN 0x0008
-
-+#define MANFID_OXSEMI 0x0279
-+
- #define MANFID_PIONEER 0x000b
-
- #define MANFID_PSION 0x016c
-@@ -103,6 +109,7 @@
- #define PRODID_QUATECH_SPP100 0x0003
- #define PRODID_QUATECH_DUAL_RS232 0x0012
- #define PRODID_QUATECH_DUAL_RS232_D1 0x0007
-+#define PRODID_QUATECH_DUAL_RS232_D2 0x0052
- #define PRODID_QUATECH_QUAD_RS232 0x001b
- #define PRODID_QUATECH_DUAL_RS422 0x000e
- #define PRODID_QUATECH_QUAD_RS422 0x0045
-@@ -120,9 +127,12 @@
-
- #define MANFID_TDK 0x0105
- #define PRODID_TDK_CF010 0x0900
-+#define PRODID_TDK_GN3410 0x4815
-
- #define MANFID_TOSHIBA 0x0098
-
-+#define MANFID_UNGERMANN 0x02c0
-+
- #define MANFID_XIRCOM 0x0105
-
- #endif /* _LINUX_CISCODE_H */
-diff -urN linux-2.4.18/kernel/ksyms.c linux-2.4.18-mh15/kernel/ksyms.c
---- linux-2.4.18/kernel/ksyms.c 2002-02-25 20:38:13.000000000 +0100
-+++ linux-2.4.18-mh15/kernel/ksyms.c 2004-08-01 16:26:23.000000000 +0200
-@@ -47,6 +47,7 @@
- #include <linux/in6.h>
- #include <linux/completion.h>
- #include <linux/seq_file.h>
-+#include <linux/firmware.h>
- #include <asm/checksum.h>
-
- #if defined(CONFIG_PROC_FS)
-@@ -538,6 +539,13 @@
- EXPORT_SYMBOL(strspn);
- EXPORT_SYMBOL(strsep);
-
-+#ifdef CONFIG_FW_LOADER
-+EXPORT_SYMBOL(release_firmware);
-+EXPORT_SYMBOL(request_firmware);
-+EXPORT_SYMBOL(request_firmware_nowait);
-+EXPORT_SYMBOL(register_firmware);
-+#endif
-+
- /* software interrupts */
- EXPORT_SYMBOL(tasklet_hi_vec);
- EXPORT_SYMBOL(tasklet_vec);
-diff -urN linux-2.4.18/lib/Config.in linux-2.4.18-mh15/lib/Config.in
---- linux-2.4.18/lib/Config.in 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/lib/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,12 @@
-+#
-+# Library configuration
-+#
-+mainmenu_option next_comment
-+comment 'Library routines'
-+
-+if [ "$CONFIG_EXPERIMENTAL" = "y" -a \
-+ "$CONFIG_HOTPLUG" = "y" ]; then
-+ tristate 'Hotplug firmware loading support (EXPERIMENTAL)' CONFIG_FW_LOADER
-+fi
-+
-+endmenu
-diff -urN linux-2.4.18/lib/firmware_class.c linux-2.4.18-mh15/lib/firmware_class.c
---- linux-2.4.18/lib/firmware_class.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/lib/firmware_class.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,573 @@
-+/*
-+ * firmware_class.c - Multi purpose firmware loading support
-+ *
-+ * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
-+ *
-+ * Please see Documentation/firmware_class/ for more information.
-+ *
-+ */
-+/*
-+ * Based on kernel/kmod.c and drivers/usb/usb.c
-+ */
-+/*
-+ kernel/kmod.c
-+ Kirk Petersen
-+
-+ Reorganized not to be a daemon by Adam Richter, with guidance
-+ from Greg Zornetzer.
-+
-+ Modified to avoid chroot and file sharing problems.
-+ Mikael Pettersson
-+
-+ Limit the concurrent number of kmod modprobes to catch loops from
-+ "modprobe needs a service that is in a module".
-+ Keith Owens <kaos@ocs.com.au> December 1999
-+
-+ Unblock all signals when we exec a usermode process.
-+ Shuu Yamaguchi <shuu@wondernetworkresources.com> December 2000
-+*/
-+/*
-+ * drivers/usb/usb.c
-+ *
-+ * (C) Copyright Linus Torvalds 1999
-+ * (C) Copyright Johannes Erdfelt 1999-2001
-+ * (C) Copyright Andreas Gal 1999
-+ * (C) Copyright Gregory P. Smith 1999
-+ * (C) Copyright Deti Fliegl 1999 (new USB architecture)
-+ * (C) Copyright Randy Dunlap 2000
-+ * (C) Copyright David Brownell 2000 (kernel hotplug, usb_device_id)
-+ * (C) Copyright Yggdrasil Computing, Inc. 2000
-+ * (usb_device_id matching changes by Adam J. Richter)
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/types.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/kmod.h>
-+#include <linux/proc_fs.h>
-+#include <linux/vmalloc.h>
-+#include <asm/hardirq.h>
-+
-+#include "linux/firmware.h"
-+
-+MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>");
-+MODULE_DESCRIPTION("Multi purpose firmware loading support");
-+MODULE_LICENSE("GPL");
-+
-+#define err(format, arg...) \
-+ printk(KERN_ERR "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
-+#define warn(format, arg...) \
-+ printk(KERN_WARNING "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
-+#define dbg(format, arg...) \
-+ printk(KERN_DEBUG "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
-+
-+static int loading_timeout = 10; /* In seconds */
-+static struct proc_dir_entry *proc_dir_timeout;
-+static struct proc_dir_entry *proc_dir;
-+
-+#ifdef CONFIG_HOTPLUG
-+
-+static int
-+call_helper(char *verb, const char *name, const char *device)
-+{
-+ char *argv[3], **envp, *buf, *scratch;
-+ int i = 0;
-+
-+ int retval = 0;
-+
-+ if (!hotplug_path[0])
-+ return -ENOENT;
-+ if (in_interrupt()) {
-+ err("in_interrupt");
-+ return -EFAULT;
-+ }
-+ if (!current->fs->root) {
-+ warn("call_policy %s -- no FS yet", verb);
-+ return -EPERM;
-+ }
-+
-+ if (!(envp = (char **) kmalloc(20 * sizeof (char *), GFP_KERNEL))) {
-+ err("unable to allocate envp");
-+ return -ENOMEM;
-+ }
-+ if (!(buf = kmalloc(256, GFP_KERNEL))) {
-+ kfree(envp);
-+ err("unable to allocate buf");
-+ return -ENOMEM;
-+ }
-+
-+ /* only one standardized param to hotplug command: type */
-+ argv[0] = hotplug_path;
-+ argv[1] = "firmware";
-+ argv[2] = 0;
-+
-+ /* minimal command environment */
-+ envp[i++] = "HOME=/";
-+ envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-+
-+#ifdef DEBUG
-+ /* hint that policy agent should enter no-stdout debug mode */
-+ envp[i++] = "DEBUG=kernel";
-+#endif
-+ scratch = buf;
-+
-+ if (device) {
-+ envp[i++] = scratch;
-+ scratch += snprintf(scratch, FIRMWARE_NAME_MAX+25,
-+ "DEVPATH=/driver/firmware/%s", device) + 1;
-+ }
-+
-+ envp[i++] = scratch;
-+ scratch += sprintf(scratch, "ACTION=%s", verb) + 1;
-+
-+ envp[i++] = scratch;
-+ scratch += snprintf(scratch, FIRMWARE_NAME_MAX,
-+ "FIRMWARE=%s", name) + 1;
-+
-+ envp[i++] = 0;
-+
-+#ifdef DEBUG
-+ dbg("firmware: %s %s %s", argv[0], argv[1], verb);
-+#endif
-+
-+ retval = call_usermodehelper(argv[0], argv, envp);
-+ if (retval) {
-+ printk("call_usermodehelper return %d\n", retval);
-+ }
-+
-+ kfree(buf);
-+ kfree(envp);
-+ return retval;
-+}
-+#else
-+
-+static inline int
-+call_helper(char *verb, const char *name, const char *device)
-+{
-+ return -ENOENT;
-+}
-+
-+#endif /* CONFIG_HOTPLUG */
-+
-+struct firmware_priv {
-+ struct completion completion;
-+ struct proc_dir_entry *proc_dir;
-+ struct proc_dir_entry *attr_data;
-+ struct proc_dir_entry *attr_loading;
-+ struct firmware *fw;
-+ int loading;
-+ int abort;
-+ int alloc_size;
-+ struct timer_list timeout;
-+};
-+
-+static int
-+firmware_timeout_show(char *buf, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ return sprintf(buf, "%d\n", loading_timeout);
-+}
-+
-+/**
-+ * firmware_timeout_store:
-+ * Description:
-+ * Sets the number of seconds to wait for the firmware. Once
-+ * this expires an error will be return to the driver and no
-+ * firmware will be provided.
-+ *
-+ * Note: zero means 'wait for ever'
-+ *
-+ **/
-+static int
-+firmware_timeout_store(struct file *file, const char *buf,
-+ unsigned long count, void *data)
-+{
-+ loading_timeout = simple_strtol(buf, NULL, 10);
-+ return count;
-+}
-+
-+static int
-+firmware_loading_show(char *buf, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ struct firmware_priv *fw_priv = data;
-+ return sprintf(buf, "%d\n", fw_priv->loading);
-+}
-+
-+/**
-+ * firmware_loading_store: - loading control file
-+ * Description:
-+ * The relevant values are:
-+ *
-+ * 1: Start a load, discarding any previous partial load.
-+ * 0: Conclude the load and handle the data to the driver code.
-+ * -1: Conclude the load with an error and discard any written data.
-+ **/
-+static int
-+firmware_loading_store(struct file *file, const char *buf,
-+ unsigned long count, void *data)
-+{
-+ struct firmware_priv *fw_priv = data;
-+ int prev_loading = fw_priv->loading;
-+
-+ fw_priv->loading = simple_strtol(buf, NULL, 10);
-+
-+ switch (fw_priv->loading) {
-+ case -1:
-+ fw_priv->abort = 1;
-+ wmb();
-+ complete(&fw_priv->completion);
-+ break;
-+ case 1:
-+ kfree(fw_priv->fw->data);
-+ fw_priv->fw->data = NULL;
-+ fw_priv->fw->size = 0;
-+ fw_priv->alloc_size = 0;
-+ break;
-+ case 0:
-+ if (prev_loading == 1)
-+ complete(&fw_priv->completion);
-+ break;
-+ }
-+
-+ return count;
-+}
-+
-+static int
-+firmware_data_read(char *buffer, char **start, off_t offset,
-+ int count, int *eof, void *data)
-+{
-+ struct firmware_priv *fw_priv = data;
-+ struct firmware *fw = fw_priv->fw;
-+
-+ if (offset > fw->size)
-+ return 0;
-+ if (offset + count > fw->size)
-+ count = fw->size - offset;
-+
-+ memcpy(buffer, fw->data + offset, count);
-+ *start = (void *) ((long) count);
-+ return count;
-+}
-+static int
-+fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
-+{
-+ u8 *new_data;
-+ int new_size;
-+
-+ if (min_size <= fw_priv->alloc_size)
-+ return 0;
-+ if((min_size % PAGE_SIZE) == 0)
-+ new_size = min_size;
-+ else
-+ new_size = (min_size + PAGE_SIZE) & PAGE_MASK;
-+ new_data = vmalloc(new_size);
-+ if (!new_data) {
-+ printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__);
-+ /* Make sure that we don't keep incomplete data */
-+ fw_priv->abort = 1;
-+ return -ENOMEM;
-+ }
-+ fw_priv->alloc_size = new_size;
-+ if (fw_priv->fw->data) {
-+ memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size);
-+ vfree(fw_priv->fw->data);
-+ }
-+ fw_priv->fw->data = new_data;
-+ BUG_ON(min_size > fw_priv->alloc_size);
-+ return 0;
-+}
-+
-+/**
-+ * firmware_data_write:
-+ *
-+ * Description:
-+ *
-+ * Data written to the 'data' attribute will be later handled to
-+ * the driver as a firmware image.
-+ **/
-+static int
-+firmware_data_write(struct file *file, const char *buffer,
-+ unsigned long count, void *data)
-+{
-+ struct firmware_priv *fw_priv = data;
-+ struct firmware *fw = fw_priv->fw;
-+ int offset = file->f_pos;
-+ int retval;
-+
-+ retval = fw_realloc_buffer(fw_priv, offset + count);
-+ if (retval) {
-+ printk("%s: retval:%d\n", __FUNCTION__, retval);
-+ return retval;
-+ }
-+
-+ memcpy(fw->data + offset, buffer, count);
-+
-+ fw->size = max_t(size_t, offset + count, fw->size);
-+ file->f_pos += count;
-+ return count;
-+}
-+
-+static void
-+firmware_class_timeout(u_long data)
-+{
-+ struct firmware_priv *fw_priv = (struct firmware_priv *) data;
-+ fw_priv->abort = 1;
-+ wmb();
-+ complete(&fw_priv->completion);
-+}
-+static int
-+fw_setup_class_device(struct firmware_priv **fw_priv_p,
-+ const char *fw_name, const char *device)
-+{
-+ int retval;
-+ struct firmware_priv *fw_priv = kmalloc(sizeof (struct firmware_priv),
-+ GFP_KERNEL);
-+ *fw_priv_p = fw_priv;
-+ if (!fw_priv) {
-+ retval = -ENOMEM;
-+ goto out;
-+ }
-+ memset(fw_priv, 0, sizeof (*fw_priv));
-+
-+ init_completion(&fw_priv->completion);
-+
-+ fw_priv->timeout.function = firmware_class_timeout;
-+ fw_priv->timeout.data = (u_long) fw_priv;
-+ init_timer(&fw_priv->timeout);
-+
-+ retval = -EAGAIN;
-+ fw_priv->proc_dir = create_proc_entry(device, 0644 | S_IFDIR, proc_dir);
-+ if (!fw_priv->proc_dir)
-+ goto err_free_fw_priv;
-+
-+ fw_priv->attr_data = create_proc_entry("data", 0644 | S_IFREG,
-+ fw_priv->proc_dir);
-+ if (!fw_priv->attr_data)
-+ goto err_remove_dir;
-+
-+ fw_priv->attr_data->read_proc = firmware_data_read;
-+ fw_priv->attr_data->write_proc = firmware_data_write;
-+ fw_priv->attr_data->data = fw_priv;
-+
-+ fw_priv->attr_loading = create_proc_entry("loading", 0644 | S_IFREG,
-+ fw_priv->proc_dir);
-+ if (!fw_priv->attr_loading)
-+ goto err_remove_data;
-+
-+ fw_priv->attr_loading->read_proc = firmware_loading_show;
-+ fw_priv->attr_loading->write_proc = firmware_loading_store;
-+ fw_priv->attr_loading->data = fw_priv;
-+
-+ retval = 0;
-+ fw_priv->fw = kmalloc(sizeof (struct firmware), GFP_KERNEL);
-+ if (!fw_priv->fw) {
-+ printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n",
-+ __FUNCTION__);
-+ retval = -ENOMEM;
-+ goto err_remove_loading;
-+ }
-+ memset(fw_priv->fw, 0, sizeof (*fw_priv->fw));
-+
-+ goto out;
-+
-+err_remove_loading:
-+ remove_proc_entry("loading", fw_priv->proc_dir);
-+err_remove_data:
-+ remove_proc_entry("data", fw_priv->proc_dir);
-+err_remove_dir:
-+ remove_proc_entry(device, proc_dir);
-+err_free_fw_priv:
-+ kfree(fw_priv);
-+out:
-+ return retval;
-+}
-+static void
-+fw_remove_class_device(struct firmware_priv *fw_priv)
-+{
-+ remove_proc_entry("loading", fw_priv->proc_dir);
-+ remove_proc_entry("data", fw_priv->proc_dir);
-+ remove_proc_entry(fw_priv->proc_dir->name, proc_dir);
-+}
-+
-+/**
-+ * request_firmware: - request firmware to hotplug and wait for it
-+ * Description:
-+ * @firmware will be used to return a firmware image by the name
-+ * of @name for device @device.
-+ *
-+ * Should be called from user context where sleeping is allowed.
-+ *
-+ * @name will be use as $FIRMWARE in the hotplug environment and
-+ * should be distinctive enough not to be confused with any other
-+ * firmware image for this or any other device.
-+ **/
-+int
-+request_firmware(const struct firmware **firmware, const char *name,
-+ const char *device)
-+{
-+ struct firmware_priv *fw_priv;
-+ int retval;
-+
-+ if (!firmware) {
-+ retval = -EINVAL;
-+ goto out;
-+ }
-+ *firmware = NULL;
-+
-+ retval = fw_setup_class_device(&fw_priv, name, device);
-+ if (retval)
-+ goto out;
-+
-+ retval = call_helper("add", name, device);
-+ if (retval)
-+ goto out;
-+ if (loading_timeout) {
-+ fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
-+ add_timer(&fw_priv->timeout);
-+ }
-+
-+ wait_for_completion(&fw_priv->completion);
-+
-+ del_timer(&fw_priv->timeout);
-+ fw_remove_class_device(fw_priv);
-+
-+ if (fw_priv->fw->size && !fw_priv->abort) {
-+ *firmware = fw_priv->fw;
-+ } else {
-+ retval = -ENOENT;
-+ vfree(fw_priv->fw->data);
-+ kfree(fw_priv->fw);
-+ }
-+out:
-+ kfree(fw_priv);
-+ return retval;
-+}
-+
-+void
-+release_firmware(const struct firmware *fw)
-+{
-+ if (fw) {
-+ vfree(fw->data);
-+ kfree(fw);
-+ }
-+}
-+
-+/**
-+ * register_firmware: - provide a firmware image for later usage
-+ *
-+ * Description:
-+ * Make sure that @data will be available by requesting firmware @name.
-+ *
-+ * Note: This will not be possible until some kind of persistence
-+ * is available.
-+ **/
-+void
-+register_firmware(const char *name, const u8 *data, size_t size)
-+{
-+ /* This is meaningless without firmware caching, so until we
-+ * decide if firmware caching is reasonable just leave it as a
-+ * noop */
-+}
-+
-+/* Async support */
-+struct firmware_work {
-+ struct tq_struct work;
-+ struct module *module;
-+ const char *name;
-+ const char *device;
-+ void *context;
-+ void (*cont)(const struct firmware *fw, void *context);
-+};
-+
-+static void
-+request_firmware_work_func(void *arg)
-+{
-+ struct firmware_work *fw_work = arg;
-+ const struct firmware *fw;
-+ if (!arg)
-+ return;
-+ request_firmware(&fw, fw_work->name, fw_work->device);
-+ fw_work->cont(fw, fw_work->context);
-+ release_firmware(fw);
-+ __MOD_DEC_USE_COUNT(fw_work->module);
-+ kfree(fw_work);
-+}
-+
-+/**
-+ * request_firmware_nowait:
-+ *
-+ * Description:
-+ * Asynchronous variant of request_firmware() for contexts where
-+ * it is not possible to sleep.
-+ *
-+ * @cont will be called asynchronously when the firmware request is over.
-+ *
-+ * @context will be passed over to @cont.
-+ *
-+ * @fw may be %NULL if firmware request fails.
-+ *
-+ **/
-+int
-+request_firmware_nowait(
-+ struct module *module,
-+ const char *name, const char *device, void *context,
-+ void (*cont)(const struct firmware *fw, void *context))
-+{
-+ struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
-+ GFP_ATOMIC);
-+ if (!fw_work)
-+ return -ENOMEM;
-+ if (!try_inc_mod_count(module)) {
-+ kfree(fw_work);
-+ return -EFAULT;
-+ }
-+
-+ *fw_work = (struct firmware_work) {
-+ .module = module,
-+ .name = name,
-+ .device = device,
-+ .context = context,
-+ .cont = cont,
-+ };
-+ INIT_TQUEUE(&fw_work->work, request_firmware_work_func, fw_work);
-+
-+ schedule_task(&fw_work->work);
-+ return 0;
-+}
-+
-+static int __init
-+firmware_class_init(void)
-+{
-+ proc_dir = create_proc_entry("driver/firmware", 0755 | S_IFDIR, NULL);
-+ if (!proc_dir)
-+ return -EAGAIN;
-+ proc_dir_timeout = create_proc_entry("timeout",
-+ 0644 | S_IFREG, proc_dir);
-+ if (!proc_dir_timeout) {
-+ remove_proc_entry("driver/firmware", NULL);
-+ return -EAGAIN;
-+ }
-+ proc_dir_timeout->read_proc = firmware_timeout_show;
-+ proc_dir_timeout->write_proc = firmware_timeout_store;
-+ return 0;
-+}
-+static void __exit
-+firmware_class_exit(void)
-+{
-+ remove_proc_entry("timeout", proc_dir);
-+ remove_proc_entry("driver/firmware", NULL);
-+}
-+
-+module_init(firmware_class_init);
-+module_exit(firmware_class_exit);
-+
-+#ifndef CONFIG_FW_LOADER
-+EXPORT_SYMBOL(release_firmware);
-+EXPORT_SYMBOL(request_firmware);
-+EXPORT_SYMBOL(request_firmware_nowait);
-+EXPORT_SYMBOL(register_firmware);
-+#endif
-diff -urN linux-2.4.18/lib/Makefile linux-2.4.18-mh15/lib/Makefile
---- linux-2.4.18/lib/Makefile 2001-09-18 00:31:15.000000000 +0200
-+++ linux-2.4.18-mh15/lib/Makefile 2004-08-01 16:26:23.000000000 +0200
-@@ -8,13 +8,17 @@
-
- L_TARGET := lib.a
-
--export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o
-+export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o \
-+ firmware_class.o
-
- obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o bust_spinlocks.o rbtree.o
-
-+obj-$(CONFIG_FW_LOADER) += firmware_class.o
- obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
- obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
-
-+include $(TOPDIR)/drivers/bluetooth/Makefile.lib
-+
- ifneq ($(CONFIG_HAVE_DEC_LOCK),y)
- obj-y += dec_and_lock.o
- endif
-diff -urN linux-2.4.18/MAINTAINERS linux-2.4.18-mh15/MAINTAINERS
---- linux-2.4.18/MAINTAINERS 2002-02-25 20:37:52.000000000 +0100
-+++ linux-2.4.18-mh15/MAINTAINERS 2004-08-01 16:26:23.000000000 +0200
-@@ -252,10 +252,88 @@
- L: linux-kernel@vger.kernel.org
- S: Maintained
-
--BLUETOOTH SUBSYSTEM (BlueZ)
-+BLUETOOTH SUBSYSTEM
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
- P: Maxim Krasnyansky
- M: maxk@qualcomm.com
-+L: bluez-devel@lists.sf.net
- W: http://bluez.sf.net
-+W: http://www.bluez.org
-+W: http://www.holtmann.org/linux/bluetooth/
-+S: Maintained
-+
-+BLUETOOTH RFCOMM LAYER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+S: Maintained
-+
-+BLUETOOTH BNEP LAYER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+S: Maintained
-+
-+BLUETOOTH CMTP LAYER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+S: Maintained
-+
-+BLUETOOTH HIDP LAYER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+S: Maintained
-+
-+BLUETOOTH HCI UART DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+S: Maintained
-+
-+BLUETOOTH HCI USB DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+S: Maintained
-+
-+BLUETOOTH HCI BCM203X DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+S: Maintained
-+
-+BLUETOOTH HCI BFUSB DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+S: Maintained
-+
-+BLUETOOTH HCI DTL1 DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+S: Maintained
-+
-+BLUETOOTH HCI BLUECARD DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+S: Maintained
-+
-+BLUETOOTH HCI BT3C DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+S: Maintained
-+
-+BLUETOOTH HCI BTUART DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+S: Maintained
-+
-+BLUETOOTH HCI VHCI DRIVER
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
- S: Maintained
-
- BTTV VIDEO4LINUX DRIVER
-diff -urN linux-2.4.18/net/bluetooth/af_bluetooth.c linux-2.4.18-mh15/net/bluetooth/af_bluetooth.c
---- linux-2.4.18/net/bluetooth/af_bluetooth.c 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/net/bluetooth/af_bluetooth.c 2004-08-01 16:26:23.000000000 +0200
-@@ -25,14 +25,15 @@
- /*
- * BlueZ Bluetooth address family and sockets.
- *
-- * $Id$
-+ * $Id$
- */
--#define VERSION "1.1"
-+#define VERSION "2.4"
-
- #include <linux/config.h>
- #include <linux/module.h>
-
- #include <linux/types.h>
-+#include <linux/list.h>
- #include <linux/errno.h>
- #include <linux/kernel.h>
- #include <linux/major.h>
-@@ -40,6 +41,7 @@
- #include <linux/slab.h>
- #include <linux/skbuff.h>
- #include <linux/init.h>
-+#include <linux/poll.h>
- #include <linux/proc_fs.h>
- #include <net/sock.h>
-
-@@ -48,70 +50,79 @@
- #endif
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
-+
-+#ifndef AF_BLUETOOTH_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-
- /* Bluetooth sockets */
--static struct net_proto_family *bluez_sock[BLUEZ_MAX_PROTO];
-+#define BLUEZ_MAX_PROTO 7
-+static struct net_proto_family *bluez_proto[BLUEZ_MAX_PROTO];
-
- int bluez_sock_register(int proto, struct net_proto_family *ops)
- {
-- if (proto > BLUEZ_MAX_PROTO)
-+ if (proto >= BLUEZ_MAX_PROTO)
- return -EINVAL;
-
-- if (bluez_sock[proto])
-+ if (bluez_proto[proto])
- return -EEXIST;
-
-- bluez_sock[proto] = ops;
-+ bluez_proto[proto] = ops;
- return 0;
- }
-
- int bluez_sock_unregister(int proto)
- {
-- if (proto > BLUEZ_MAX_PROTO)
-+ if (proto >= BLUEZ_MAX_PROTO)
- return -EINVAL;
-
-- if (!bluez_sock[proto])
-+ if (!bluez_proto[proto])
- return -ENOENT;
-
-- bluez_sock[proto] = NULL;
-+ bluez_proto[proto] = NULL;
- return 0;
- }
-
- static int bluez_sock_create(struct socket *sock, int proto)
- {
-- if (proto > BLUEZ_MAX_PROTO)
-+ if (proto >= BLUEZ_MAX_PROTO)
- return -EINVAL;
-
- #if defined(CONFIG_KMOD)
-- if (!bluez_sock[proto]) {
-+ if (!bluez_proto[proto]) {
- char module_name[30];
- sprintf(module_name, "bt-proto-%d", proto);
- request_module(module_name);
- }
- #endif
-
-- if (!bluez_sock[proto])
-+ if (!bluez_proto[proto])
- return -ENOENT;
-
-- return bluez_sock[proto]->create(sock, proto);
-+ return bluez_proto[proto]->create(sock, proto);
-+}
-+
-+void bluez_sock_init(struct socket *sock, struct sock *sk)
-+{
-+ sock_init_data(sock, sk);
-+ INIT_LIST_HEAD(&bluez_pi(sk)->accept_q);
- }
-
- void bluez_sock_link(struct bluez_sock_list *l, struct sock *sk)
- {
-- write_lock(&l->lock);
--
-+ write_lock_bh(&l->lock);
- sk->next = l->head;
- l->head = sk;
- sock_hold(sk);
--
-- write_unlock(&l->lock);
-+ write_unlock_bh(&l->lock);
- }
-
- void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *sk)
- {
- struct sock **skp;
-
-- write_lock(&l->lock);
-+ write_lock_bh(&l->lock);
- for (skp = &l->head; *skp; skp = &((*skp)->next)) {
- if (*skp == sk) {
- *skp = sk->next;
-@@ -119,7 +130,163 @@
- break;
- }
- }
-- write_unlock(&l->lock);
-+ write_unlock_bh(&l->lock);
-+}
-+
-+void bluez_accept_enqueue(struct sock *parent, struct sock *sk)
-+{
-+ BT_DBG("parent %p, sk %p", parent, sk);
-+
-+ sock_hold(sk);
-+ list_add_tail(&bluez_pi(sk)->accept_q, &bluez_pi(parent)->accept_q);
-+ bluez_pi(sk)->parent = parent;
-+ parent->ack_backlog++;
-+}
-+
-+static void bluez_accept_unlink(struct sock *sk)
-+{
-+ BT_DBG("sk %p state %d", sk, sk->state);
-+
-+ list_del_init(&bluez_pi(sk)->accept_q);
-+ bluez_pi(sk)->parent->ack_backlog--;
-+ bluez_pi(sk)->parent = NULL;
-+ sock_put(sk);
-+}
-+
-+struct sock *bluez_accept_dequeue(struct sock *parent, struct socket *newsock)
-+{
-+ struct list_head *p, *n;
-+ struct bluez_pinfo *pi;
-+ struct sock *sk;
-+
-+ BT_DBG("parent %p", parent);
-+
-+ list_for_each_safe(p, n, &bluez_pi(parent)->accept_q) {
-+ pi = list_entry(p, struct bluez_pinfo, accept_q);
-+ sk = bluez_sk(pi);
-+
-+ lock_sock(sk);
-+ if (sk->state == BT_CLOSED) {
-+ release_sock(sk);
-+ bluez_accept_unlink(sk);
-+ continue;
-+ }
-+
-+ if (sk->state == BT_CONNECTED || !newsock) {
-+ bluez_accept_unlink(sk);
-+ if (newsock)
-+ sock_graft(sk, newsock);
-+ release_sock(sk);
-+ return sk;
-+ }
-+ release_sock(sk);
-+ }
-+ return NULL;
-+}
-+
-+int bluez_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
-+{
-+ int noblock = flags & MSG_DONTWAIT;
-+ struct sock *sk = sock->sk;
-+ struct sk_buff *skb;
-+ int copied, err;
-+
-+ BT_DBG("sock %p sk %p len %d", sock, sk, len);
-+
-+ if (flags & (MSG_OOB))
-+ return -EOPNOTSUPP;
-+
-+ if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) {
-+ if (sk->shutdown & RCV_SHUTDOWN)
-+ return 0;
-+ return err;
-+ }
-+
-+ msg->msg_namelen = 0;
-+
-+ copied = skb->len;
-+ if (len < copied) {
-+ msg->msg_flags |= MSG_TRUNC;
-+ copied = len;
-+ }
-+
-+ skb->h.raw = skb->data;
-+ err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
-+
-+ skb_free_datagram(sk, skb);
-+
-+ return err ? : copied;
-+}
-+
-+unsigned int bluez_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
-+{
-+ struct sock *sk = sock->sk;
-+ unsigned int mask = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ poll_wait(file, sk->sleep, wait);
-+
-+ if (sk->err || !skb_queue_empty(&sk->error_queue))
-+ mask |= POLLERR;
-+
-+ if (sk->shutdown == SHUTDOWN_MASK)
-+ mask |= POLLHUP;
-+
-+ if (!skb_queue_empty(&sk->receive_queue) ||
-+ !list_empty(&bluez_pi(sk)->accept_q) ||
-+ (sk->shutdown & RCV_SHUTDOWN))
-+ mask |= POLLIN | POLLRDNORM;
-+
-+ if (sk->state == BT_CLOSED)
-+ mask |= POLLHUP;
-+
-+ if (sk->state == BT_CONNECT ||
-+ sk->state == BT_CONNECT2 ||
-+ sk->state == BT_CONFIG)
-+ return mask;
-+
-+ if (sock_writeable(sk))
-+ mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
-+ else
-+ set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
-+
-+ return mask;
-+}
-+
-+int bluez_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ int err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ add_wait_queue(sk->sleep, &wait);
-+ while (sk->state != state) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+
-+ if (sk->err) {
-+ err = sock_error(sk);
-+ break;
-+ }
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+ return err;
- }
-
- struct net_proto_family bluez_sock_family_ops =
-@@ -129,9 +296,9 @@
-
- int bluez_init(void)
- {
-- INF("BlueZ HCI Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-+ BT_INFO("BlueZ Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-
- proc_mkdir("bluetooth", NULL);
-
-@@ -164,5 +331,6 @@
- module_exit(bluez_cleanup);
-
- MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
--MODULE_DESCRIPTION("BlueZ HCI Core ver " VERSION);
-+MODULE_DESCRIPTION("BlueZ Core ver " VERSION);
-+MODULE_LICENSE("GPL");
- #endif
-diff -urN linux-2.4.18/net/bluetooth/bnep/bnep.h linux-2.4.18-mh15/net/bluetooth/bnep/bnep.h
---- linux-2.4.18/net/bluetooth/bnep/bnep.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/bnep/bnep.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,185 @@
-+/*
-+ BNEP protocol definition for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License, version 2, as
-+ published by the Free Software Foundation.
-+
-+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef _BNEP_H
-+#define _BNEP_H
-+
-+#include <linux/types.h>
-+#include <net/bluetooth/bluetooth.h>
-+
-+#include "crc32.h"
-+
-+// Limits
-+#define BNEP_MAX_PROTO_FILTERS 5
-+#define BNEP_MAX_MULTICAST_FILTERS 20
-+
-+// UUIDs
-+#define BNEP_BASE_UUID 0x0000000000001000800000805F9B34FB
-+#define BNEP_UUID16 0x02
-+#define BNEP_UUID32 0x04
-+#define BNEP_UUID128 0x16
-+
-+#define BNEP_SVC_PANU 0x1115
-+#define BNEP_SVC_NAP 0x1116
-+#define BNEP_SVC_GN 0x1117
-+
-+// Packet types
-+#define BNEP_GENERAL 0x00
-+#define BNEP_CONTROL 0x01
-+#define BNEP_COMPRESSED 0x02
-+#define BNEP_COMPRESSED_SRC_ONLY 0x03
-+#define BNEP_COMPRESSED_DST_ONLY 0x04
-+
-+// Control types
-+#define BNEP_CMD_NOT_UNDERSTOOD 0x00
-+#define BNEP_SETUP_CONN_REQ 0x01
-+#define BNEP_SETUP_CONN_RSP 0x02
-+#define BNEP_FILTER_NET_TYPE_SET 0x03
-+#define BNEP_FILTER_NET_TYPE_RSP 0x04
-+#define BNEP_FILTER_MULTI_ADDR_SET 0x05
-+#define BNEP_FILTER_MULTI_ADDR_RSP 0x06
-+
-+// Extension types
-+#define BNEP_EXT_CONTROL 0x00
-+
-+// Response messages
-+#define BNEP_SUCCESS 0x00
-+
-+#define BNEP_CONN_INVALID_DST 0x01
-+#define BNEP_CONN_INVALID_SRC 0x02
-+#define BNEP_CONN_INVALID_SVC 0x03
-+#define BNEP_CONN_NOT_ALLOWED 0x04
-+
-+#define BNEP_FILTER_UNSUPPORTED_REQ 0x01
-+#define BNEP_FILTER_INVALID_RANGE 0x02
-+#define BNEP_FILTER_INVALID_MCADDR 0x02
-+#define BNEP_FILTER_LIMIT_REACHED 0x03
-+#define BNEP_FILTER_DENIED_SECURITY 0x04
-+
-+// L2CAP settings
-+#define BNEP_MTU 1691
-+#define BNEP_PSM 0x0f
-+#define BNEP_FLUSH_TO 0xffff
-+#define BNEP_CONNECT_TO 15
-+#define BNEP_FILTER_TO 15
-+
-+// Headers
-+#define BNEP_TYPE_MASK 0x7f
-+#define BNEP_EXT_HEADER 0x80
-+
-+struct bnep_setup_conn_req {
-+ __u8 type;
-+ __u8 ctrl;
-+ __u8 uuid_size;
-+ __u8 service[0];
-+} __attribute__((packed));
-+
-+struct bnep_set_filter_req {
-+ __u8 type;
-+ __u8 ctrl;
-+ __u16 len;
-+ __u8 list[0];
-+} __attribute__((packed));
-+
-+struct bnep_control_rsp {
-+ __u8 type;
-+ __u8 ctrl;
-+ __u16 resp;
-+} __attribute__((packed));
-+
-+struct bnep_ext_hdr {
-+ __u8 type;
-+ __u8 len;
-+ __u8 data[0];
-+} __attribute__((packed));
-+
-+/* BNEP ioctl defines */
-+#define BNEPCONNADD _IOW('B', 200, int)
-+#define BNEPCONNDEL _IOW('B', 201, int)
-+#define BNEPGETCONNLIST _IOR('B', 210, int)
-+#define BNEPGETCONNINFO _IOR('B', 211, int)
-+
-+struct bnep_connadd_req {
-+ int sock; // Connected socket
-+ __u32 flags;
-+ __u16 role;
-+ char device[16]; // Name of the Ethernet device
-+};
-+
-+struct bnep_conndel_req {
-+ __u32 flags;
-+ __u8 dst[ETH_ALEN];
-+};
-+
-+struct bnep_conninfo {
-+ __u32 flags;
-+ __u16 role;
-+ __u16 state;
-+ __u8 dst[ETH_ALEN];
-+ char device[16];
-+};
-+
-+struct bnep_connlist_req {
-+ __u32 cnum;
-+ struct bnep_conninfo *ci;
-+};
-+
-+struct bnep_proto_filter {
-+ __u16 start;
-+ __u16 end;
-+};
-+
-+int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock);
-+int bnep_del_connection(struct bnep_conndel_req *req);
-+int bnep_get_connlist(struct bnep_connlist_req *req);
-+int bnep_get_conninfo(struct bnep_conninfo *ci);
-+
-+// BNEP sessions
-+struct bnep_session {
-+ struct list_head list;
-+
-+ unsigned int role;
-+ unsigned long state;
-+ unsigned long flags;
-+ atomic_t killed;
-+
-+ struct ethhdr eh;
-+ struct msghdr msg;
-+
-+ struct bnep_proto_filter proto_filter[BNEP_MAX_PROTO_FILTERS];
-+ u64 mc_filter;
-+
-+ struct socket *sock;
-+ struct net_device dev;
-+ struct net_device_stats stats;
-+};
-+
-+int bnep_net_init(struct net_device *dev);
-+int bnep_sock_init(void);
-+int bnep_sock_cleanup(void);
-+
-+static inline int bnep_mc_hash(__u8 *addr)
-+{
-+ return (bnep_crc32(~0, addr, ETH_ALEN) >> 26);
-+}
-+
-+#endif
-diff -urN linux-2.4.18/net/bluetooth/bnep/Config.in linux-2.4.18-mh15/net/bluetooth/bnep/Config.in
---- linux-2.4.18/net/bluetooth/bnep/Config.in 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/bnep/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,11 @@
-+#
-+# Bluetooth BNEP layer configuration
-+#
-+
-+dep_tristate 'BNEP protocol support' CONFIG_BLUEZ_BNEP $CONFIG_BLUEZ_L2CAP
-+
-+if [ "$CONFIG_BLUEZ_BNEP" != "n" ]; then
-+ bool ' Multicast filter support' CONFIG_BLUEZ_BNEP_MC_FILTER
-+ bool ' Protocol filter support' CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+fi
-+
-diff -urN linux-2.4.18/net/bluetooth/bnep/core.c linux-2.4.18-mh15/net/bluetooth/bnep/core.c
---- linux-2.4.18/net/bluetooth/bnep/core.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/bnep/core.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,718 @@
-+/*
-+ BNEP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2001-2002 Inventel Systemes
-+ Written 2001-2002 by
-+ Clément Moreau <clement.moreau@inventel.fr>
-+ David Libault <david.libault@inventel.fr>
-+
-+ Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#define __KERNEL_SYSCALLS__
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/signal.h>
-+#include <linux/init.h>
-+#include <linux/wait.h>
-+#include <linux/errno.h>
-+#include <linux/smp_lock.h>
-+#include <linux/net.h>
-+#include <net/sock.h>
-+
-+#include <linux/socket.h>
-+#include <linux/file.h>
-+
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#include "bnep.h"
-+
-+#ifndef CONFIG_BLUEZ_BNEP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define VERSION "1.2"
-+
-+static LIST_HEAD(bnep_session_list);
-+static DECLARE_RWSEM(bnep_session_sem);
-+
-+static struct bnep_session *__bnep_get_session(u8 *dst)
-+{
-+ struct bnep_session *s;
-+ struct list_head *p;
-+
-+ BT_DBG("");
-+
-+ list_for_each(p, &bnep_session_list) {
-+ s = list_entry(p, struct bnep_session, list);
-+ if (!memcmp(dst, s->eh.h_source, ETH_ALEN))
-+ return s;
-+ }
-+ return NULL;
-+}
-+
-+static void __bnep_link_session(struct bnep_session *s)
-+{
-+ MOD_INC_USE_COUNT;
-+ list_add(&s->list, &bnep_session_list);
-+}
-+
-+static void __bnep_unlink_session(struct bnep_session *s)
-+{
-+ list_del(&s->list);
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static int bnep_send(struct bnep_session *s, void *data, size_t len)
-+{
-+ struct socket *sock = s->sock;
-+ struct iovec iv = { data, len };
-+ s->msg.msg_iov = &iv;
-+ s->msg.msg_iovlen = 1;
-+ return sock->ops->sendmsg(sock, &s->msg, len, NULL);
-+}
-+
-+static int bnep_send_rsp(struct bnep_session *s, u8 ctrl, u16 resp)
-+{
-+ struct bnep_control_rsp rsp;
-+ rsp.type = BNEP_CONTROL;
-+ rsp.ctrl = ctrl;
-+ rsp.resp = htons(resp);
-+ return bnep_send(s, &rsp, sizeof(rsp));
-+}
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+static inline void bnep_set_default_proto_filter(struct bnep_session *s)
-+{
-+ /* (IPv4, ARP) */
-+ s->proto_filter[0].start = htons(0x0800);
-+ s->proto_filter[0].end = htons(0x0806);
-+ /* (RARP, AppleTalk) */
-+ s->proto_filter[1].start = htons(0x8035);
-+ s->proto_filter[1].end = htons(0x80F3);
-+ /* (IPX, IPv6) */
-+ s->proto_filter[2].start = htons(0x8137);
-+ s->proto_filter[2].end = htons(0x86DD);
-+}
-+#endif
-+
-+static int bnep_ctrl_set_netfilter(struct bnep_session *s, u16 *data, int len)
-+{
-+ int n;
-+
-+ if (len < 2)
-+ return -EILSEQ;
-+
-+ n = ntohs(get_unaligned(data));
-+ data++; len -= 2;
-+
-+ if (len < n)
-+ return -EILSEQ;
-+
-+ BT_DBG("filter len %d", n);
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+ n /= 4;
-+ if (n <= BNEP_MAX_PROTO_FILTERS) {
-+ struct bnep_proto_filter *f = s->proto_filter;
-+ int i;
-+
-+ for (i = 0; i < n; i++) {
-+ f[i].start = get_unaligned(data++);
-+ f[i].end = get_unaligned(data++);
-+
-+ BT_DBG("proto filter start %d end %d",
-+ f[i].start, f[i].end);
-+ }
-+
-+ if (i < BNEP_MAX_PROTO_FILTERS)
-+ memset(f + i, 0, sizeof(*f));
-+
-+ if (n == 0)
-+ bnep_set_default_proto_filter(s);
-+
-+ bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_SUCCESS);
-+ } else {
-+ bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_LIMIT_REACHED);
-+ }
-+#else
-+ bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
-+#endif
-+ return 0;
-+}
-+
-+static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
-+{
-+ int n;
-+
-+ if (len < 2)
-+ return -EILSEQ;
-+
-+ n = ntohs(get_unaligned((u16 *) data));
-+ data += 2; len -= 2;
-+
-+ if (len < n)
-+ return -EILSEQ;
-+
-+ BT_DBG("filter len %d", n);
-+
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+ n /= (ETH_ALEN * 2);
-+
-+ if (n > 0) {
-+ s->mc_filter = 0;
-+
-+ /* Always send broadcast */
-+ set_bit(bnep_mc_hash(s->dev.broadcast), &s->mc_filter);
-+
-+ /* Add address ranges to the multicast hash */
-+ for (; n > 0; n--) {
-+ u8 a1[6], *a2;
-+
-+ memcpy(a1, data, ETH_ALEN); data += ETH_ALEN;
-+ a2 = data; data += ETH_ALEN;
-+
-+ BT_DBG("mc filter %s -> %s",
-+ batostr((void *) a1), batostr((void *) a2));
-+
-+ #define INCA(a) { int i = 5; while (i >=0 && ++a[i--] == 0); }
-+
-+ /* Iterate from a1 to a2 */
-+ set_bit(bnep_mc_hash(a1), &s->mc_filter);
-+ while (memcmp(a1, a2, 6) < 0 && s->mc_filter != ~0LL) {
-+ INCA(a1);
-+ set_bit(bnep_mc_hash(a1), &s->mc_filter);
-+ }
-+ }
-+ }
-+
-+ BT_DBG("mc filter hash 0x%llx", s->mc_filter);
-+
-+ bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_SUCCESS);
-+#else
-+ bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
-+#endif
-+ return 0;
-+}
-+
-+static int bnep_rx_control(struct bnep_session *s, void *data, int len)
-+{
-+ u8 cmd = *(u8 *)data;
-+ int err = 0;
-+
-+ data++; len--;
-+
-+ switch (cmd) {
-+ case BNEP_CMD_NOT_UNDERSTOOD:
-+ case BNEP_SETUP_CONN_REQ:
-+ case BNEP_SETUP_CONN_RSP:
-+ case BNEP_FILTER_NET_TYPE_RSP:
-+ case BNEP_FILTER_MULTI_ADDR_RSP:
-+ /* Ignore these for now */
-+ break;
-+
-+ case BNEP_FILTER_NET_TYPE_SET:
-+ err = bnep_ctrl_set_netfilter(s, data, len);
-+ break;
-+
-+ case BNEP_FILTER_MULTI_ADDR_SET:
-+ err = bnep_ctrl_set_mcfilter(s, data, len);
-+ break;
-+
-+ default: {
-+ u8 pkt[3];
-+ pkt[0] = BNEP_CONTROL;
-+ pkt[1] = BNEP_CMD_NOT_UNDERSTOOD;
-+ pkt[2] = cmd;
-+ bnep_send(s, pkt, sizeof(pkt));
-+ }
-+ break;
-+ }
-+
-+ return err;
-+}
-+
-+static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb)
-+{
-+ struct bnep_ext_hdr *h;
-+ int err = 0;
-+
-+ do {
-+ h = (void *) skb->data;
-+ if (!skb_pull(skb, sizeof(*h))) {
-+ err = -EILSEQ;
-+ break;
-+ }
-+
-+ BT_DBG("type 0x%x len %d", h->type, h->len);
-+
-+ switch (h->type & BNEP_TYPE_MASK) {
-+ case BNEP_EXT_CONTROL:
-+ bnep_rx_control(s, skb->data, skb->len);
-+ break;
-+
-+ default:
-+ /* Unknown extension, skip it. */
-+ break;
-+ }
-+
-+ if (!skb_pull(skb, h->len)) {
-+ err = -EILSEQ;
-+ break;
-+ }
-+ } while (!err && (h->type & BNEP_EXT_HEADER));
-+
-+ return err;
-+}
-+
-+static u8 __bnep_rx_hlen[] = {
-+ ETH_HLEN, /* BNEP_GENERAL */
-+ 0, /* BNEP_CONTROL */
-+ 2, /* BNEP_COMPRESSED */
-+ ETH_ALEN + 2, /* BNEP_COMPRESSED_SRC_ONLY */
-+ ETH_ALEN + 2 /* BNEP_COMPRESSED_DST_ONLY */
-+};
-+#define BNEP_RX_TYPES (sizeof(__bnep_rx_hlen) - 1)
-+
-+static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
-+{
-+ struct net_device *dev = &s->dev;
-+ struct sk_buff *nskb;
-+ u8 type;
-+
-+ dev->last_rx = jiffies;
-+ s->stats.rx_bytes += skb->len;
-+
-+ type = *(u8 *) skb->data; skb_pull(skb, 1);
-+
-+ if ((type & BNEP_TYPE_MASK) > BNEP_RX_TYPES)
-+ goto badframe;
-+
-+ if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) {
-+ bnep_rx_control(s, skb->data, skb->len);
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+
-+ skb->mac.raw = skb->data;
-+
-+ /* Verify and pull out header */
-+ if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK]))
-+ goto badframe;
-+
-+ s->eh.h_proto = get_unaligned((u16 *) (skb->data - 2));
-+
-+ if (type & BNEP_EXT_HEADER) {
-+ if (bnep_rx_extension(s, skb) < 0)
-+ goto badframe;
-+ }
-+
-+ /* Strip 802.1p header */
-+ if (ntohs(s->eh.h_proto) == 0x8100) {
-+ if (!skb_pull(skb, 4))
-+ goto badframe;
-+ s->eh.h_proto = get_unaligned((u16 *) (skb->data - 2));
-+ }
-+
-+ /* We have to alloc new skb and copy data here :(. Because original skb
-+ * may not be modified and because of the alignment requirements. */
-+ nskb = alloc_skb(2 + ETH_HLEN + skb->len, GFP_KERNEL);
-+ if (!nskb) {
-+ s->stats.rx_dropped++;
-+ kfree_skb(skb);
-+ return -ENOMEM;
-+ }
-+ skb_reserve(nskb, 2);
-+
-+ /* Decompress header and construct ether frame */
-+ switch (type & BNEP_TYPE_MASK) {
-+ case BNEP_COMPRESSED:
-+ memcpy(__skb_put(nskb, ETH_HLEN), &s->eh, ETH_HLEN);
-+ break;
-+
-+ case BNEP_COMPRESSED_SRC_ONLY:
-+ memcpy(__skb_put(nskb, ETH_ALEN), s->eh.h_dest, ETH_ALEN);
-+ memcpy(__skb_put(nskb, ETH_ALEN), skb->mac.raw, ETH_ALEN);
-+ put_unaligned(s->eh.h_proto, (u16 *) __skb_put(nskb, 2));
-+ break;
-+
-+ case BNEP_COMPRESSED_DST_ONLY:
-+ memcpy(__skb_put(nskb, ETH_ALEN), skb->mac.raw, ETH_ALEN);
-+ memcpy(__skb_put(nskb, ETH_ALEN + 2), s->eh.h_source, ETH_ALEN + 2);
-+ break;
-+
-+ case BNEP_GENERAL:
-+ memcpy(__skb_put(nskb, ETH_ALEN * 2), skb->mac.raw, ETH_ALEN * 2);
-+ put_unaligned(s->eh.h_proto, (u16 *) __skb_put(nskb, 2));
-+ break;
-+ }
-+
-+ memcpy(__skb_put(nskb, skb->len), skb->data, skb->len);
-+ kfree_skb(skb);
-+
-+ s->stats.rx_packets++;
-+ nskb->dev = dev;
-+ nskb->ip_summed = CHECKSUM_UNNECESSARY;
-+ nskb->protocol = eth_type_trans(nskb, dev);
-+ netif_rx_ni(nskb);
-+ return 0;
-+
-+badframe:
-+ s->stats.rx_errors++;
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+static u8 __bnep_tx_types[] = {
-+ BNEP_GENERAL,
-+ BNEP_COMPRESSED_SRC_ONLY,
-+ BNEP_COMPRESSED_DST_ONLY,
-+ BNEP_COMPRESSED
-+};
-+
-+static inline int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb)
-+{
-+ struct ethhdr *eh = (void *) skb->data;
-+ struct socket *sock = s->sock;
-+ struct iovec iv[3];
-+ int len = 0, il = 0;
-+ u8 type = 0;
-+
-+ BT_DBG("skb %p dev %p type %d", skb, skb->dev, skb->pkt_type);
-+
-+ if (!skb->dev) {
-+ /* Control frame sent by us */
-+ goto send;
-+ }
-+
-+ iv[il++] = (struct iovec) { &type, 1 };
-+ len++;
-+
-+ if (!memcmp(eh->h_dest, s->eh.h_source, ETH_ALEN))
-+ type |= 0x01;
-+
-+ if (!memcmp(eh->h_source, s->eh.h_dest, ETH_ALEN))
-+ type |= 0x02;
-+
-+ if (type)
-+ skb_pull(skb, ETH_ALEN * 2);
-+
-+ type = __bnep_tx_types[type];
-+ switch (type) {
-+ case BNEP_COMPRESSED_SRC_ONLY:
-+ iv[il++] = (struct iovec) { eh->h_source, ETH_ALEN };
-+ len += ETH_ALEN;
-+ break;
-+
-+ case BNEP_COMPRESSED_DST_ONLY:
-+ iv[il++] = (struct iovec) { eh->h_dest, ETH_ALEN };
-+ len += ETH_ALEN;
-+ break;
-+ }
-+
-+send:
-+ iv[il++] = (struct iovec) { skb->data, skb->len };
-+ len += skb->len;
-+
-+ /* FIXME: linearize skb */
-+
-+ s->msg.msg_iov = iv;
-+ s->msg.msg_iovlen = il;
-+ len = sock->ops->sendmsg(sock, &s->msg, len, NULL);
-+ kfree_skb(skb);
-+
-+ if (len > 0) {
-+ s->stats.tx_bytes += len;
-+ s->stats.tx_packets++;
-+ return 0;
-+ }
-+
-+ return len;
-+}
-+
-+static int bnep_session(void *arg)
-+{
-+ struct bnep_session *s = arg;
-+ struct net_device *dev = &s->dev;
-+ struct sock *sk = s->sock->sk;
-+ struct sk_buff *skb;
-+ wait_queue_t wait;
-+
-+ BT_DBG("");
-+
-+ daemonize(); reparent_to_init();
-+
-+ sprintf(current->comm, "kbnepd %s", dev->name);
-+
-+ sigfillset(&current->blocked);
-+ flush_signals(current);
-+
-+ current->nice = -15;
-+
-+ set_fs(KERNEL_DS);
-+
-+ init_waitqueue_entry(&wait, current);
-+ add_wait_queue(sk->sleep, &wait);
-+ while (!atomic_read(&s->killed)) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ // RX
-+ while ((skb = skb_dequeue(&sk->receive_queue))) {
-+ skb_orphan(skb);
-+ bnep_rx_frame(s, skb);
-+ }
-+
-+ if (sk->state != BT_CONNECTED)
-+ break;
-+
-+ // TX
-+ while ((skb = skb_dequeue(&sk->write_queue)))
-+ if (bnep_tx_frame(s, skb))
-+ break;
-+ netif_wake_queue(dev);
-+
-+ schedule();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ /* Cleanup session */
-+ down_write(&bnep_session_sem);
-+
-+ /* Delete network device */
-+ unregister_netdev(dev);
-+
-+ /* Release the socket */
-+ fput(s->sock->file);
-+
-+ __bnep_unlink_session(s);
-+
-+ up_write(&bnep_session_sem);
-+ kfree(s);
-+ return 0;
-+}
-+
-+int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
-+{
-+ struct net_device *dev;
-+ struct bnep_session *s, *ss;
-+ u8 dst[ETH_ALEN], src[ETH_ALEN];
-+ int err;
-+
-+ BT_DBG("");
-+
-+ baswap((void *) dst, &bluez_pi(sock->sk)->dst);
-+ baswap((void *) src, &bluez_pi(sock->sk)->src);
-+
-+ s = kmalloc(sizeof(struct bnep_session), GFP_KERNEL);
-+ if (!s)
-+ return -ENOMEM;
-+ memset(s, 0, sizeof(struct bnep_session));
-+
-+ down_write(&bnep_session_sem);
-+
-+ ss = __bnep_get_session(dst);
-+ if (ss && ss->state == BT_CONNECTED) {
-+ err = -EEXIST;
-+ goto failed;
-+ }
-+
-+ dev = &s->dev;
-+
-+ if (*req->device)
-+ strcpy(dev->name, req->device);
-+ else
-+ strcpy(dev->name, "bnep%d");
-+
-+ memset(dev->broadcast, 0xff, ETH_ALEN);
-+
-+ /* This is rx header therefor addresses are swaped.
-+ * ie eh.h_dest is our local address. */
-+ memcpy(s->eh.h_dest, &src, ETH_ALEN);
-+ memcpy(s->eh.h_source, &dst, ETH_ALEN);
-+
-+ s->sock = sock;
-+ s->role = req->role;
-+ s->state = BT_CONNECTED;
-+
-+ s->msg.msg_flags = MSG_NOSIGNAL;
-+
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+ /* Set default mc filter */
-+ set_bit(bnep_mc_hash(dev->broadcast), &s->mc_filter);
-+#endif
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+ /* Set default protocol filter */
-+ bnep_set_default_proto_filter(s);
-+#endif
-+
-+ dev->init = bnep_net_init;
-+ dev->priv = s;
-+ err = register_netdev(dev);
-+ if (err) {
-+ goto failed;
-+ }
-+
-+ __bnep_link_session(s);
-+
-+ err = kernel_thread(bnep_session, s, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-+ if (err < 0) {
-+ /* Session thread start failed, gotta cleanup. */
-+ unregister_netdev(dev);
-+ __bnep_unlink_session(s);
-+ goto failed;
-+ }
-+
-+ up_write(&bnep_session_sem);
-+ strcpy(req->device, dev->name);
-+ return 0;
-+
-+failed:
-+ up_write(&bnep_session_sem);
-+ kfree(s);
-+ return err;
-+}
-+
-+int bnep_del_connection(struct bnep_conndel_req *req)
-+{
-+ struct bnep_session *s;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ down_read(&bnep_session_sem);
-+
-+ s = __bnep_get_session(req->dst);
-+ if (s) {
-+ /* Wakeup user-space which is polling for socket errors.
-+ * This is temporary hack untill we have shutdown in L2CAP */
-+ s->sock->sk->err = EUNATCH;
-+
-+ /* Kill session thread */
-+ atomic_inc(&s->killed);
-+ wake_up_interruptible(s->sock->sk->sleep);
-+ } else
-+ err = -ENOENT;
-+
-+ up_read(&bnep_session_sem);
-+ return err;
-+}
-+
-+static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s)
-+{
-+ memcpy(ci->dst, s->eh.h_source, ETH_ALEN);
-+ strcpy(ci->device, s->dev.name);
-+ ci->flags = s->flags;
-+ ci->state = s->state;
-+ ci->role = s->role;
-+}
-+
-+int bnep_get_connlist(struct bnep_connlist_req *req)
-+{
-+ struct list_head *p;
-+ int err = 0, n = 0;
-+
-+ down_read(&bnep_session_sem);
-+
-+ list_for_each(p, &bnep_session_list) {
-+ struct bnep_session *s;
-+ struct bnep_conninfo ci;
-+
-+ s = list_entry(p, struct bnep_session, list);
-+
-+ __bnep_copy_ci(&ci, s);
-+
-+ if (copy_to_user(req->ci, &ci, sizeof(ci))) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ if (++n >= req->cnum)
-+ break;
-+
-+ req->ci++;
-+ }
-+ req->cnum = n;
-+
-+ up_read(&bnep_session_sem);
-+ return err;
-+}
-+
-+int bnep_get_conninfo(struct bnep_conninfo *ci)
-+{
-+ struct bnep_session *s;
-+ int err = 0;
-+
-+ down_read(&bnep_session_sem);
-+
-+ s = __bnep_get_session(ci->dst);
-+ if (s)
-+ __bnep_copy_ci(ci, s);
-+ else
-+ err = -ENOENT;
-+
-+ up_read(&bnep_session_sem);
-+ return err;
-+}
-+
-+static int __init bnep_init_module(void)
-+{
-+ l2cap_load();
-+
-+ bnep_crc32_init();
-+ bnep_sock_init();
-+
-+ BT_INFO("BlueZ BNEP ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2001,2002 Inventel Systemes");
-+ BT_INFO("Written 2001,2002 by Clement Moreau <clement.moreau@inventel.fr>");
-+ BT_INFO("Written 2001,2002 by David Libault <david.libault@inventel.fr>");
-+ BT_INFO("Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>");
-+
-+ return 0;
-+}
-+
-+static void __exit bnep_cleanup_module(void)
-+{
-+ bnep_sock_cleanup();
-+ bnep_crc32_cleanup();
-+}
-+
-+module_init(bnep_init_module);
-+module_exit(bnep_cleanup_module);
-+
-+MODULE_DESCRIPTION("BlueZ BNEP ver " VERSION);
-+MODULE_AUTHOR("David Libault <david.libault@inventel.fr>, Maxim Krasnyanskiy <maxk@qualcomm.com>");
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/bnep/crc32.c linux-2.4.18-mh15/net/bluetooth/bnep/crc32.c
---- linux-2.4.18/net/bluetooth/bnep/crc32.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/bnep/crc32.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,59 @@
-+/*
-+ * Based on linux-2.5/lib/crc32 by Matt Domsch <Matt_Domsch@dell.com>
-+ *
-+ * FIXME: Remove in 2.5
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <asm/atomic.h>
-+
-+#include "crc32.h"
-+
-+#define CRCPOLY_BE 0x04c11db7
-+#define CRC_BE_BITS 8
-+
-+static u32 *bnep_crc32_table;
-+
-+/*
-+ * This code is in the public domain; copyright abandoned.
-+ * Liability for non-performance of this code is limited to the amount
-+ * you paid for it. Since it is distributed for free, your refund will
-+ * be very very small. If it breaks, you get to keep both pieces.
-+ */
-+u32 bnep_crc32(u32 crc, unsigned char const *p, size_t len)
-+{
-+ while (len--)
-+ crc = (crc << 8) ^ bnep_crc32_table[(crc >> 24) ^ *p++];
-+
-+ return crc;
-+}
-+
-+int __init bnep_crc32_init(void)
-+{
-+ unsigned i, j;
-+ u32 crc = 0x80000000;
-+
-+ bnep_crc32_table = kmalloc((1 << CRC_BE_BITS) * sizeof(u32), GFP_KERNEL);
-+ if (!bnep_crc32_table)
-+ return -ENOMEM;
-+
-+ bnep_crc32_table[0] = 0;
-+
-+ for (i = 1; i < 1 << CRC_BE_BITS; i <<= 1) {
-+ crc = (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE : 0);
-+ for (j = 0; j < i; j++)
-+ bnep_crc32_table[i + j] = crc ^ bnep_crc32_table[j];
-+ }
-+ return 0;
-+}
-+
-+void __exit bnep_crc32_cleanup(void)
-+{
-+ if (bnep_crc32_table)
-+ kfree(bnep_crc32_table);
-+ bnep_crc32_table = NULL;
-+}
-diff -urN linux-2.4.18/net/bluetooth/bnep/crc32.h linux-2.4.18-mh15/net/bluetooth/bnep/crc32.h
---- linux-2.4.18/net/bluetooth/bnep/crc32.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/bnep/crc32.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,10 @@
-+/*
-+ * crc32.h
-+ * See crc32.c for license and changes
-+ *
-+ * FIXME: Remove in 2.5
-+ */
-+
-+int bnep_crc32_init(void);
-+void bnep_crc32_cleanup(void);
-+u32 bnep_crc32(u32 crc, unsigned char const *p, size_t len);
-diff -urN linux-2.4.18/net/bluetooth/bnep/Makefile linux-2.4.18-mh15/net/bluetooth/bnep/Makefile
---- linux-2.4.18/net/bluetooth/bnep/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/bnep/Makefile 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the Linux Bluetooth BNEP layer
-+#
-+
-+O_TARGET := bnep.o
-+
-+obj-y := core.o sock.o netdev.o crc32.o
-+obj-m += $(O_TARGET)
-+
-+include $(TOPDIR)/Rules.make
-diff -urN linux-2.4.18/net/bluetooth/bnep/netdev.c linux-2.4.18-mh15/net/bluetooth/bnep/netdev.c
---- linux-2.4.18/net/bluetooth/bnep/netdev.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/bnep/netdev.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,254 @@
-+/*
-+ BNEP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2001-2002 Inventel Systemes
-+ Written 2001-2002 by
-+ Clément Moreau <clement.moreau@inventel.fr>
-+ David Libault <david.libault@inventel.fr>
-+
-+ Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/socket.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/wait.h>
-+
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#include "bnep.h"
-+
-+#ifndef CONFIG_BLUEZ_BNEP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+#define BNEP_TX_QUEUE_LEN 20
-+
-+static int bnep_net_open(struct net_device *dev)
-+{
-+ netif_start_queue(dev);
-+ return 0;
-+}
-+
-+static int bnep_net_close(struct net_device *dev)
-+{
-+ netif_stop_queue(dev);
-+ return 0;
-+}
-+
-+static struct net_device_stats *bnep_net_get_stats(struct net_device *dev)
-+{
-+ struct bnep_session *s = dev->priv;
-+ return &s->stats;
-+}
-+
-+static void bnep_net_set_mc_list(struct net_device *dev)
-+{
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+ struct bnep_session *s = dev->priv;
-+ struct sock *sk = s->sock->sk;
-+ struct bnep_set_filter_req *r;
-+ struct sk_buff *skb;
-+ int size;
-+
-+ BT_DBG("%s mc_count %d", dev->name, dev->mc_count);
-+
-+ size = sizeof(*r) + (BNEP_MAX_MULTICAST_FILTERS + 1) * ETH_ALEN * 2;
-+ skb = alloc_skb(size, GFP_ATOMIC);
-+ if (!skb) {
-+ BT_ERR("%s Multicast list allocation failed", dev->name);
-+ return;
-+ }
-+
-+ r = (void *) skb->data;
-+ __skb_put(skb, sizeof(*r));
-+
-+ r->type = BNEP_CONTROL;
-+ r->ctrl = BNEP_FILTER_MULTI_ADDR_SET;
-+
-+ if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
-+ u8 start[ETH_ALEN] = { 0x01 };
-+
-+ /* Request all addresses */
-+ memcpy(__skb_put(skb, ETH_ALEN), start, ETH_ALEN);
-+ memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
-+ r->len = htons(ETH_ALEN * 2);
-+ } else {
-+ struct dev_mc_list *dmi = dev->mc_list;
-+ int i, len = skb->len;
-+
-+ if (dev->flags & IFF_BROADCAST) {
-+ memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
-+ memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
-+ }
-+
-+ /* FIXME: We should group addresses here. */
-+
-+ for (i = 0; i < dev->mc_count && i < BNEP_MAX_MULTICAST_FILTERS; i++) {
-+ memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN);
-+ memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN);
-+ dmi = dmi->next;
-+ }
-+ r->len = htons(skb->len - len);
-+ }
-+
-+ skb_queue_tail(&sk->write_queue, skb);
-+ wake_up_interruptible(sk->sleep);
-+#endif
-+}
-+
-+static int bnep_net_set_mac_addr(struct net_device *dev, void *arg)
-+{
-+ BT_DBG("%s", dev->name);
-+ return 0;
-+}
-+
-+static void bnep_net_timeout(struct net_device *dev)
-+{
-+ BT_DBG("net_timeout");
-+ netif_wake_queue(dev);
-+}
-+
-+static int bnep_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-+{
-+ return -EINVAL;
-+}
-+
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+static inline int bnep_net_mc_filter(struct sk_buff *skb, struct bnep_session *s)
-+{
-+ struct ethhdr *eh = (void *) skb->data;
-+
-+ if ((eh->h_dest[0] & 1) && !test_bit(bnep_mc_hash(eh->h_dest), &s->mc_filter)) {
-+ BT_DBG("BNEP: filtered skb %p, dst %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", skb,
-+ eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
-+ eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]);
-+ return 1;
-+ }
-+ return 0;
-+}
-+#endif
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+/* Determine ether protocol. Based on eth_type_trans. */
-+static inline u16 bnep_net_eth_proto(struct sk_buff *skb)
-+{
-+ struct ethhdr *eh = (void *) skb->data;
-+
-+ if (ntohs(eh->h_proto) >= 1536)
-+ return eh->h_proto;
-+
-+ if (get_unaligned((u16 *) skb->data) == 0xFFFF)
-+ return htons(ETH_P_802_3);
-+
-+ return htons(ETH_P_802_2);
-+}
-+
-+static inline int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session *s)
-+{
-+ u16 proto = bnep_net_eth_proto(skb);
-+ struct bnep_proto_filter *f = s->proto_filter;
-+ int i;
-+
-+ for (i = 0; i < BNEP_MAX_PROTO_FILTERS && f[i].end; i++) {
-+ if (proto >= f[i].start && proto <= f[i].end)
-+ return 0;
-+ }
-+
-+ BT_DBG("BNEP: filtered skb %p, proto 0x%.4x", skb, proto);
-+ return 1;
-+}
-+#endif
-+
-+static int bnep_net_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+ struct bnep_session *s = dev->priv;
-+ struct sock *sk = s->sock->sk;
-+
-+ BT_DBG("skb %p, dev %p", skb, dev);
-+
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+ if (bnep_net_mc_filter(skb, s)) {
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+#endif
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+ if (bnep_net_proto_filter(skb, s)) {
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+#endif
-+
-+ /*
-+ * We cannot send L2CAP packets from here as we are potentially in a bh.
-+ * So we have to queue them and wake up session thread which is sleeping
-+ * on the sk->sleep.
-+ */
-+ dev->trans_start = jiffies;
-+ skb_queue_tail(&sk->write_queue, skb);
-+ wake_up_interruptible(sk->sleep);
-+
-+ if (skb_queue_len(&sk->write_queue) >= BNEP_TX_QUEUE_LEN) {
-+ BT_DBG("tx queue is full");
-+
-+ /* Stop queuing.
-+ * Session thread will do netif_wake_queue() */
-+ netif_stop_queue(dev);
-+ }
-+
-+ return 0;
-+}
-+
-+int bnep_net_init(struct net_device *dev)
-+{
-+ struct bnep_session *s = dev->priv;
-+
-+ memcpy(dev->dev_addr, s->eh.h_dest, ETH_ALEN);
-+ dev->addr_len = ETH_ALEN;
-+
-+ ether_setup(dev);
-+
-+ dev->open = bnep_net_open;
-+ dev->stop = bnep_net_close;
-+ dev->hard_start_xmit = bnep_net_xmit;
-+ dev->get_stats = bnep_net_get_stats;
-+ dev->do_ioctl = bnep_net_ioctl;
-+ dev->set_mac_address = bnep_net_set_mac_addr;
-+ dev->set_multicast_list = bnep_net_set_mc_list;
-+
-+ dev->watchdog_timeo = HZ * 2;
-+ dev->tx_timeout = bnep_net_timeout;
-+
-+ return 0;
-+}
-diff -urN linux-2.4.18/net/bluetooth/bnep/sock.c linux-2.4.18-mh15/net/bluetooth/bnep/sock.c
---- linux-2.4.18/net/bluetooth/bnep/sock.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/bnep/sock.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,210 @@
-+/*
-+ BNEP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2001-2002 Inventel Systemes
-+ Written 2001-2002 by
-+ David Libault <david.libault@inventel.fr>
-+
-+ Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include "bnep.h"
-+
-+#ifndef CONFIG_BLUEZ_BNEP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+static int bnep_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ sock_orphan(sk);
-+ sock_put(sk);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct bnep_connlist_req cl;
-+ struct bnep_connadd_req ca;
-+ struct bnep_conndel_req cd;
-+ struct bnep_conninfo ci;
-+ struct socket *nsock;
-+ int err;
-+
-+ BT_DBG("cmd %x arg %lx", cmd, arg);
-+
-+ switch (cmd) {
-+ case BNEPCONNADD:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
-+ return -EFAULT;
-+
-+ nsock = sockfd_lookup(ca.sock, &err);
-+ if (!nsock)
-+ return err;
-+
-+ if (nsock->sk->state != BT_CONNECTED) {
-+ fput(nsock->file);
-+ return -EBADFD;
-+ }
-+
-+ err = bnep_add_connection(&ca, nsock);
-+ if (!err) {
-+ if (copy_to_user((void *) arg, &ca, sizeof(ca)))
-+ err = -EFAULT;
-+ } else
-+ fput(nsock->file);
-+
-+ return err;
-+
-+ case BNEPCONNDEL:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
-+ return -EFAULT;
-+
-+ return bnep_del_connection(&cd);
-+
-+ case BNEPGETCONNLIST:
-+ if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
-+ return -EFAULT;
-+
-+ if (cl.cnum <= 0)
-+ return -EINVAL;
-+
-+ err = bnep_get_connlist(&cl);
-+ if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
-+ return -EFAULT;
-+
-+ return err;
-+
-+ case BNEPGETCONNINFO:
-+ if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
-+ return -EFAULT;
-+
-+ err = bnep_get_conninfo(&ci);
-+ if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
-+ return -EFAULT;
-+
-+ return err;
-+
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static struct proto_ops bnep_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: bnep_sock_release,
-+ ioctl: bnep_sock_ioctl,
-+ bind: sock_no_bind,
-+ getname: sock_no_getname,
-+ sendmsg: sock_no_sendmsg,
-+ recvmsg: sock_no_recvmsg,
-+ poll: sock_no_poll,
-+ listen: sock_no_listen,
-+ shutdown: sock_no_shutdown,
-+ setsockopt: sock_no_setsockopt,
-+ getsockopt: sock_no_getsockopt,
-+ connect: sock_no_connect,
-+ socketpair: sock_no_socketpair,
-+ accept: sock_no_accept,
-+ mmap: sock_no_mmap
-+};
-+
-+static int bnep_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ if (sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &bnep_sock_ops;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, 1)))
-+ return -ENOMEM;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ sock->state = SS_UNCONNECTED;
-+ sock_init_data(sock, sk);
-+
-+ sk->destruct = NULL;
-+ sk->protocol = protocol;
-+
-+ return 0;
-+}
-+
-+static struct net_proto_family bnep_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: bnep_sock_create
-+};
-+
-+int bnep_sock_init(void)
-+{
-+ bluez_sock_register(BTPROTO_BNEP, &bnep_sock_family_ops);
-+ return 0;
-+}
-+
-+int bnep_sock_cleanup(void)
-+{
-+ if (bluez_sock_unregister(BTPROTO_BNEP))
-+ BT_ERR("Can't unregister BNEP socket");
-+ return 0;
-+}
-diff -urN linux-2.4.18/net/bluetooth/cmtp/capi.c linux-2.4.18-mh15/net/bluetooth/cmtp/capi.c
---- linux-2.4.18/net/bluetooth/cmtp/capi.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/cmtp/capi.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,707 @@
-+/*
-+ CMTP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <net/sock.h>
-+
-+#include <linux/capi.h>
-+
-+#include "../drivers/isdn/avmb1/capilli.h"
-+#include "../drivers/isdn/avmb1/capicmd.h"
-+#include "../drivers/isdn/avmb1/capiutil.h"
-+
-+#include "cmtp.h"
-+
-+#ifndef CONFIG_BLUEZ_CMTP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define REVISION "1.0"
-+
-+#define CAPI_INTEROPERABILITY 0x20
-+
-+#define CAPI_INTEROPERABILITY_REQ CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
-+#define CAPI_INTEROPERABILITY_CONF CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
-+#define CAPI_INTEROPERABILITY_IND CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
-+#define CAPI_INTEROPERABILITY_RESP CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
-+
-+#define CAPI_INTEROPERABILITY_REQ_LEN (CAPI_MSG_BASELEN + 2)
-+#define CAPI_INTEROPERABILITY_CONF_LEN (CAPI_MSG_BASELEN + 4)
-+#define CAPI_INTEROPERABILITY_IND_LEN (CAPI_MSG_BASELEN + 2)
-+#define CAPI_INTEROPERABILITY_RESP_LEN (CAPI_MSG_BASELEN + 2)
-+
-+#define CAPI_FUNCTION_REGISTER 0
-+#define CAPI_FUNCTION_RELEASE 1
-+#define CAPI_FUNCTION_GET_PROFILE 2
-+#define CAPI_FUNCTION_GET_MANUFACTURER 3
-+#define CAPI_FUNCTION_GET_VERSION 4
-+#define CAPI_FUNCTION_GET_SERIAL_NUMBER 5
-+#define CAPI_FUNCTION_MANUFACTURER 6
-+#define CAPI_FUNCTION_LOOPBACK 7
-+
-+static struct capi_driver_interface *di;
-+
-+
-+#define CMTP_MSGNUM 1
-+#define CMTP_APPLID 2
-+#define CMTP_MAPPING 3
-+
-+static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
-+{
-+ struct cmtp_application *app = kmalloc(sizeof(*app), GFP_KERNEL);
-+
-+ BT_DBG("session %p application %p appl %d", session, app, appl);
-+
-+ if (!app)
-+ return NULL;
-+
-+ memset(app, 0, sizeof(*app));
-+
-+ app->state = BT_OPEN;
-+ app->appl = appl;
-+
-+ list_add_tail(&app->list, &session->applications);
-+
-+ return app;
-+}
-+
-+static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
-+{
-+ BT_DBG("session %p application %p", session, app);
-+
-+ if (app) {
-+ list_del(&app->list);
-+ kfree(app);
-+ }
-+}
-+
-+static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
-+{
-+ struct cmtp_application *app;
-+ struct list_head *p, *n;
-+
-+ list_for_each_safe(p, n, &session->applications) {
-+ app = list_entry(p, struct cmtp_application, list);
-+ switch (pattern) {
-+ case CMTP_MSGNUM:
-+ if (app->msgnum == value)
-+ return app;
-+ break;
-+ case CMTP_APPLID:
-+ if (app->appl == value)
-+ return app;
-+ break;
-+ case CMTP_MAPPING:
-+ if (app->mapping == value)
-+ return app;
-+ break;
-+ }
-+ }
-+
-+ return NULL;
-+}
-+
-+static int cmtp_msgnum_get(struct cmtp_session *session)
-+{
-+ session->msgnum++;
-+
-+ if ((session->msgnum & 0xff) > 200)
-+ session->msgnum = CMTP_INITIAL_MSGNUM + 1;
-+
-+ return session->msgnum;
-+}
-+
-+
-+static void cmtp_send_interopmsg(struct cmtp_session *session,
-+ __u8 subcmd, __u16 appl, __u16 msgnum,
-+ __u16 function, unsigned char *buf, int len)
-+{
-+ struct sk_buff *skb;
-+ unsigned char *s;
-+
-+ BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum);
-+
-+ if (!(skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for interoperability packet");
-+ return;
-+ }
-+
-+ s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
-+
-+ capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
-+ capimsg_setu16(s, 2, appl);
-+ capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
-+ capimsg_setu8 (s, 5, subcmd);
-+ capimsg_setu16(s, 6, msgnum);
-+
-+ /* Interoperability selector (Bluetooth Device Management) */
-+ capimsg_setu16(s, 8, 0x0001);
-+
-+ capimsg_setu8 (s, 10, 3 + len);
-+ capimsg_setu16(s, 11, function);
-+ capimsg_setu8 (s, 13, len);
-+
-+ if (len > 0)
-+ memcpy(s + 14, buf, len);
-+
-+ cmtp_send_capimsg(session, skb);
-+}
-+
-+static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
-+{
-+ struct capi_ctr *ctrl = session->ctrl;
-+ struct cmtp_application *application;
-+ __u16 appl, msgnum, func, info;
-+ __u32 controller;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ switch (CAPIMSG_SUBCOMMAND(skb->data)) {
-+ case CAPI_CONF:
-+ func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
-+ info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
-+
-+ switch (func) {
-+ case CAPI_FUNCTION_REGISTER:
-+ msgnum = CAPIMSG_MSGID(skb->data);
-+
-+ application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
-+ if (application) {
-+ application->state = BT_CONNECTED;
-+ application->msgnum = 0;
-+ application->mapping = CAPIMSG_APPID(skb->data);
-+ wake_up_interruptible(&session->wait);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_RELEASE:
-+ appl = CAPIMSG_APPID(skb->data);
-+
-+ application = cmtp_application_get(session, CMTP_MAPPING, appl);
-+ if (application) {
-+ application->state = BT_CLOSED;
-+ application->msgnum = 0;
-+ wake_up_interruptible(&session->wait);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_GET_PROFILE:
-+ controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
-+ msgnum = CAPIMSG_MSGID(skb->data);
-+
-+ if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
-+ session->ncontroller = controller;
-+ wake_up_interruptible(&session->wait);
-+ break;
-+ }
-+
-+ if (!info && ctrl) {
-+ memcpy(&ctrl->profile,
-+ skb->data + CAPI_MSG_BASELEN + 11,
-+ sizeof(capi_profile));
-+ session->state = BT_CONNECTED;
-+ ctrl->ready(ctrl);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_GET_MANUFACTURER:
-+ controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);
-+
-+ if (!info && ctrl) {
-+ strncpy(ctrl->manu,
-+ skb->data + CAPI_MSG_BASELEN + 15,
-+ skb->data[CAPI_MSG_BASELEN + 14]);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_GET_VERSION:
-+ controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
-+
-+ if (!info && ctrl) {
-+ ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
-+ ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
-+ ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
-+ ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_GET_SERIAL_NUMBER:
-+ controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
-+
-+ if (!info && ctrl) {
-+ memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
-+ strncpy(ctrl->serial,
-+ skb->data + CAPI_MSG_BASELEN + 17,
-+ skb->data[CAPI_MSG_BASELEN + 16]);
-+ }
-+
-+ break;
-+ }
-+
-+ break;
-+
-+ case CAPI_IND:
-+ func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
-+
-+ if (func == CAPI_FUNCTION_LOOPBACK) {
-+ appl = CAPIMSG_APPID(skb->data);
-+ msgnum = CAPIMSG_MSGID(skb->data);
-+ cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
-+ skb->data + CAPI_MSG_BASELEN + 6,
-+ skb->data[CAPI_MSG_BASELEN + 5]);
-+ }
-+
-+ break;
-+ }
-+
-+ kfree_skb(skb);
-+}
-+
-+void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
-+{
-+ struct capi_ctr *ctrl = session->ctrl;
-+ struct cmtp_application *application;
-+ __u16 cmd, appl, info;
-+ __u32 ncci, contr;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
-+ cmtp_recv_interopmsg(session, skb);
-+ return;
-+ }
-+
-+ if (session->flags & (1 << CMTP_LOOPBACK)) {
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data));
-+ appl = CAPIMSG_APPID(skb->data);
-+ contr = CAPIMSG_CONTROL(skb->data);
-+
-+ application = cmtp_application_get(session, CMTP_MAPPING, appl);
-+ if (application) {
-+ appl = application->appl;
-+ CAPIMSG_SETAPPID(skb->data, appl);
-+ } else {
-+ BT_ERR("Can't find application with id %d", appl);
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ if ((contr & 0x7f) == 0x01) {
-+ contr = (contr & 0xffffff80) | session->num;
-+ CAPIMSG_SETCONTROL(skb->data, contr);
-+ }
-+
-+ if (!ctrl) {
-+ BT_ERR("Can't find controller %d for message", session->num);
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ switch (cmd) {
-+ case CAPI_CONNECT_B3_CONF:
-+ ncci = CAPIMSG_NCCI(skb->data);
-+ info = CAPIMSG_U16(skb->data, 12);
-+
-+ BT_DBG("CONNECT_B3_CONF ncci 0x%02x info 0x%02x", ncci, info);
-+
-+ if (info == 0)
-+ ctrl->new_ncci(ctrl, appl, ncci, 8);
-+
-+ ctrl->handle_capimsg(ctrl, appl, skb);
-+ break;
-+
-+ case CAPI_CONNECT_B3_IND:
-+ ncci = CAPIMSG_NCCI(skb->data);
-+
-+ BT_DBG("CONNECT_B3_IND ncci 0x%02x", ncci);
-+
-+ ctrl->new_ncci(ctrl, appl, ncci, 8);
-+ ctrl->handle_capimsg(ctrl, appl, skb);
-+ break;
-+
-+ case CAPI_DISCONNECT_B3_IND:
-+ ncci = CAPIMSG_NCCI(skb->data);
-+
-+ BT_DBG("DISCONNECT_B3_IND ncci 0x%02x", ncci);
-+
-+ if (ncci == 0xffffffff)
-+ BT_ERR("DISCONNECT_B3_IND with ncci 0xffffffff");
-+
-+ ctrl->handle_capimsg(ctrl, appl, skb);
-+ ctrl->free_ncci(ctrl, appl, ncci);
-+ break;
-+
-+ default:
-+ ctrl->handle_capimsg(ctrl, appl, skb);
-+ break;
-+ }
-+}
-+
-+void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
-+{
-+ struct cmtp_scb *scb = (void *) skb->cb;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ scb->id = -1;
-+ scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
-+
-+ skb_queue_tail(&session->transmit, skb);
-+
-+ cmtp_schedule(session);
-+}
-+
-+
-+static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
-+{
-+ BT_DBG("ctrl %p data %p", ctrl, data);
-+
-+ return -EIO;
-+}
-+
-+static void cmtp_reset_ctr(struct capi_ctr *ctrl)
-+{
-+ BT_DBG("ctrl %p", ctrl);
-+
-+ ctrl->reseted(ctrl);
-+}
-+
-+static void cmtp_remove_ctr(struct capi_ctr *ctrl)
-+{
-+ struct cmtp_session *session = ctrl->driverdata;
-+
-+ BT_DBG("ctrl %p", ctrl);
-+
-+ ctrl->suspend_output(ctrl);
-+
-+ atomic_inc(&session->terminate);
-+ cmtp_schedule(session);
-+}
-+
-+static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct cmtp_session *session = ctrl->driverdata;
-+ struct cmtp_application *application;
-+ unsigned long timeo = CMTP_INTEROP_TIMEOUT;
-+ unsigned char buf[8];
-+ int err = 0, nconn, want = rp->level3cnt;
-+
-+ BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
-+ ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
-+
-+ application = cmtp_application_add(session, appl);
-+ if (!application) {
-+ BT_ERR("Can't allocate memory for new application");
-+ ctrl->appl_released(ctrl, appl);
-+ return;
-+ }
-+
-+ if (want < 0)
-+ nconn = ctrl->profile.nbchannel * -want;
-+ else
-+ nconn = want;
-+
-+ if (nconn == 0)
-+ nconn = ctrl->profile.nbchannel;
-+
-+ capimsg_setu16(buf, 0, nconn);
-+ capimsg_setu16(buf, 2, rp->datablkcnt);
-+ capimsg_setu16(buf, 4, rp->datablklen);
-+
-+ application->state = BT_CONFIG;
-+ application->msgnum = cmtp_msgnum_get(session);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
-+ CAPI_FUNCTION_REGISTER, buf, 6);
-+
-+ add_wait_queue(&session->wait, &wait);
-+ while (1) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ if (application->state == BT_CLOSED) {
-+ err = -application->err;
-+ break;
-+ }
-+
-+ if (application->state == BT_CONNECTED)
-+ break;
-+
-+ if (signal_pending(current)) {
-+ err = -EINTR;
-+ break;
-+ }
-+
-+ timeo = schedule_timeout(timeo);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&session->wait, &wait);
-+
-+ if (err) {
-+ ctrl->appl_released(ctrl, appl);
-+ cmtp_application_del(session, application);
-+ return;
-+ }
-+
-+ ctrl->appl_registered(ctrl, appl);
-+}
-+
-+static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct cmtp_session *session = ctrl->driverdata;
-+ struct cmtp_application *application;
-+ unsigned long timeo = CMTP_INTEROP_TIMEOUT;
-+
-+ BT_DBG("ctrl %p appl %d", ctrl, appl);
-+
-+ application = cmtp_application_get(session, CMTP_APPLID, appl);
-+ if (!application) {
-+ BT_ERR("Can't find application");
-+ return;
-+ }
-+
-+ application->msgnum = cmtp_msgnum_get(session);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
-+ CAPI_FUNCTION_RELEASE, NULL, 0);
-+
-+ add_wait_queue(&session->wait, &wait);
-+ while (timeo) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (application->state == BT_CLOSED)
-+ break;
-+
-+ if (signal_pending(current))
-+ break;
-+
-+ timeo = schedule_timeout(timeo);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&session->wait, &wait);
-+
-+ cmtp_application_del(session, application);
-+ ctrl->appl_released(ctrl, appl);
-+}
-+
-+static void cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
-+{
-+ struct cmtp_session *session = ctrl->driverdata;
-+ struct cmtp_application *application;
-+ __u16 appl;
-+ __u32 contr;
-+
-+ BT_DBG("ctrl %p skb %p", ctrl, skb);
-+
-+ appl = CAPIMSG_APPID(skb->data);
-+ contr = CAPIMSG_CONTROL(skb->data);
-+
-+ application = cmtp_application_get(session, CMTP_APPLID, appl);
-+ if ((!application) || (application->state != BT_CONNECTED)) {
-+ BT_ERR("Can't find application with id %d", appl);
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ CAPIMSG_SETAPPID(skb->data, application->mapping);
-+
-+ if ((contr & 0x7f) == session->num) {
-+ contr = (contr & 0xffffff80) | 0x01;
-+ CAPIMSG_SETCONTROL(skb->data, contr);
-+ }
-+
-+ cmtp_send_capimsg(session, skb);
-+}
-+
-+static char *cmtp_procinfo(struct capi_ctr *ctrl)
-+{
-+ return "CAPI Message Transport Protocol";
-+}
-+
-+static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl)
-+{
-+ struct cmtp_session *session = ctrl->driverdata;
-+ struct cmtp_application *app;
-+ struct list_head *p, *n;
-+ int len = 0;
-+
-+ len += sprintf(page + len, "%s (Revision %s)\n\n", cmtp_procinfo(ctrl), REVISION);
-+ len += sprintf(page + len, "addr %s\n", session->name);
-+ len += sprintf(page + len, "ctrl %d\n", session->num);
-+
-+ list_for_each_safe(p, n, &session->applications) {
-+ app = list_entry(p, struct cmtp_application, list);
-+ len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping);
-+ }
-+
-+ if (off + count >= len)
-+ *eof = 1;
-+
-+ if (len < off)
-+ return 0;
-+
-+ *start = page + off;
-+
-+ return ((count < len - off) ? count : len - off);
-+}
-+
-+static struct capi_driver cmtp_driver = {
-+ name: "cmtp",
-+ revision: REVISION,
-+ load_firmware: cmtp_load_firmware,
-+ reset_ctr: cmtp_reset_ctr,
-+ remove_ctr: cmtp_remove_ctr,
-+ register_appl: cmtp_register_appl,
-+ release_appl: cmtp_release_appl,
-+ send_message: cmtp_send_message,
-+ procinfo: cmtp_procinfo,
-+ ctr_read_proc: cmtp_ctr_read_proc,
-+
-+ driver_read_proc: 0,
-+ add_card: 0,
-+};
-+
-+
-+int cmtp_attach_device(struct cmtp_session *session)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ unsigned long timeo = CMTP_INTEROP_TIMEOUT;
-+ unsigned char buf[4];
-+
-+ BT_DBG("session %p", session);
-+
-+ capimsg_setu32(buf, 0, 0);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
-+ CAPI_FUNCTION_GET_PROFILE, buf, 4);
-+
-+ add_wait_queue(&session->wait, &wait);
-+ while (timeo) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (session->ncontroller)
-+ break;
-+
-+ if (signal_pending(current))
-+ break;
-+
-+ timeo = schedule_timeout(timeo);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&session->wait, &wait);
-+
-+ BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
-+
-+ if (!timeo)
-+ return -ETIMEDOUT;
-+
-+ if (!session->ncontroller)
-+ return -ENODEV;
-+
-+
-+ if (session->ncontroller > 1)
-+ BT_INFO("Setting up only CAPI controller 1");
-+
-+ if (!(session->ctrl = di->attach_ctr(&cmtp_driver, session->name, session))) {
-+ BT_ERR("Can't attach new controller");
-+ return -EBUSY;
-+ }
-+
-+ session->num = session->ctrl->cnr;
-+
-+ BT_DBG("session %p ctrl %p num %d", session, session->ctrl, session->num);
-+
-+ capimsg_setu32(buf, 0, 1);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-+ CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-+ CAPI_FUNCTION_GET_VERSION, buf, 4);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-+ CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-+ CAPI_FUNCTION_GET_PROFILE, buf, 4);
-+
-+ return 0;
-+}
-+
-+void cmtp_detach_device(struct cmtp_session *session)
-+{
-+ struct capi_ctr *ctrl = session->ctrl;
-+
-+ BT_DBG("session %p ctrl %p", session, ctrl);
-+
-+ if (!ctrl)
-+ return;
-+
-+ ctrl->reseted(ctrl);
-+
-+ di->detach_ctr(ctrl);
-+}
-+
-+int cmtp_init_capi(void)
-+{
-+ if (!(di = attach_capi_driver(&cmtp_driver))) {
-+ BT_ERR("Can't attach CAPI driver");
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+void cmtp_cleanup_capi(void)
-+{
-+ detach_capi_driver(&cmtp_driver);
-+}
-diff -urN linux-2.4.18/net/bluetooth/cmtp/cmtp.h linux-2.4.18-mh15/net/bluetooth/cmtp/cmtp.h
---- linux-2.4.18/net/bluetooth/cmtp/cmtp.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/cmtp/cmtp.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,138 @@
-+/*
-+ CMTP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#ifndef __CMTP_H
-+#define __CMTP_H
-+
-+#include <linux/types.h>
-+#include <net/bluetooth/bluetooth.h>
-+
-+#define BTNAMSIZ 18
-+
-+/* CMTP ioctl defines */
-+#define CMTPCONNADD _IOW('C', 200, int)
-+#define CMTPCONNDEL _IOW('C', 201, int)
-+#define CMTPGETCONNLIST _IOR('C', 210, int)
-+#define CMTPGETCONNINFO _IOR('C', 211, int)
-+
-+#define CMTP_LOOPBACK 0
-+
-+struct cmtp_connadd_req {
-+ int sock; // Connected socket
-+ __u32 flags;
-+};
-+
-+struct cmtp_conndel_req {
-+ bdaddr_t bdaddr;
-+ __u32 flags;
-+};
-+
-+struct cmtp_conninfo {
-+ bdaddr_t bdaddr;
-+ __u32 flags;
-+ __u16 state;
-+ int num;
-+};
-+
-+struct cmtp_connlist_req {
-+ __u32 cnum;
-+ struct cmtp_conninfo *ci;
-+};
-+
-+int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock);
-+int cmtp_del_connection(struct cmtp_conndel_req *req);
-+int cmtp_get_connlist(struct cmtp_connlist_req *req);
-+int cmtp_get_conninfo(struct cmtp_conninfo *ci);
-+
-+/* CMTP session defines */
-+#define CMTP_INTEROP_TIMEOUT (HZ * 5)
-+#define CMTP_INITIAL_MSGNUM 0xff00
-+
-+struct cmtp_session {
-+ struct list_head list;
-+
-+ struct socket *sock;
-+
-+ bdaddr_t bdaddr;
-+
-+ unsigned long state;
-+ unsigned long flags;
-+
-+ uint mtu;
-+
-+ char name[BTNAMSIZ];
-+
-+ atomic_t terminate;
-+
-+ wait_queue_head_t wait;
-+
-+ int ncontroller;
-+ int num;
-+ struct capi_ctr *ctrl;
-+
-+ struct list_head applications;
-+
-+ unsigned long blockids;
-+ int msgnum;
-+
-+ struct sk_buff_head transmit;
-+
-+ struct sk_buff *reassembly[16];
-+};
-+
-+struct cmtp_application {
-+ struct list_head list;
-+
-+ unsigned long state;
-+ int err;
-+
-+ __u16 appl;
-+ __u16 mapping;
-+
-+ __u16 msgnum;
-+};
-+
-+struct cmtp_scb {
-+ int id;
-+ int data;
-+};
-+
-+int cmtp_attach_device(struct cmtp_session *session);
-+void cmtp_detach_device(struct cmtp_session *session);
-+
-+void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb);
-+void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb);
-+
-+static inline void cmtp_schedule(struct cmtp_session *session)
-+{
-+ struct sock *sk = session->sock->sk;
-+
-+ wake_up_interruptible(sk->sleep);
-+}
-+
-+/* CMTP init defines */
-+int cmtp_init_capi(void);
-+int cmtp_init_sockets(void);
-+void cmtp_cleanup_capi(void);
-+void cmtp_cleanup_sockets(void);
-+
-+#endif /* __CMTP_H */
-diff -urN linux-2.4.18/net/bluetooth/cmtp/Config.in linux-2.4.18-mh15/net/bluetooth/cmtp/Config.in
---- linux-2.4.18/net/bluetooth/cmtp/Config.in 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/cmtp/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,7 @@
-+#
-+# Bluetooth CMTP layer configuration
-+#
-+
-+if [ "$CONFIG_ISDN" = "y" -o "$CONFIG_ISDN" = "m" ]; then
-+ dep_tristate 'CMTP protocol support' CONFIG_BLUEZ_CMTP $CONFIG_ISDN_CAPI $CONFIG_BLUEZ_L2CAP
-+fi
-diff -urN linux-2.4.18/net/bluetooth/cmtp/core.c linux-2.4.18-mh15/net/bluetooth/cmtp/core.c
---- linux-2.4.18/net/bluetooth/cmtp/core.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/cmtp/core.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,515 @@
-+/*
-+ CMTP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <linux/init.h>
-+#include <net/sock.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#include "cmtp.h"
-+
-+#ifndef CONFIG_BLUEZ_CMTP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define VERSION "1.0"
-+
-+static DECLARE_RWSEM(cmtp_session_sem);
-+static LIST_HEAD(cmtp_session_list);
-+
-+static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr)
-+{
-+ struct cmtp_session *session;
-+ struct list_head *p;
-+
-+ BT_DBG("");
-+
-+ list_for_each(p, &cmtp_session_list) {
-+ session = list_entry(p, struct cmtp_session, list);
-+ if (!bacmp(bdaddr, &session->bdaddr))
-+ return session;
-+ }
-+ return NULL;
-+}
-+
-+static void __cmtp_link_session(struct cmtp_session *session)
-+{
-+ MOD_INC_USE_COUNT;
-+ list_add(&session->list, &cmtp_session_list);
-+}
-+
-+static void __cmtp_unlink_session(struct cmtp_session *session)
-+{
-+ list_del(&session->list);
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci)
-+{
-+ bacpy(&ci->bdaddr, &session->bdaddr);
-+
-+ ci->flags = session->flags;
-+ ci->state = session->state;
-+
-+ ci->num = session->num;
-+}
-+
-+
-+static inline int cmtp_alloc_block_id(struct cmtp_session *session)
-+{
-+ int i, id = -1;
-+
-+ for (i = 0; i < 16; i++)
-+ if (!test_and_set_bit(i, &session->blockids)) {
-+ id = i;
-+ break;
-+ }
-+
-+ return id;
-+}
-+
-+static inline void cmtp_free_block_id(struct cmtp_session *session, int id)
-+{
-+ clear_bit(id, &session->blockids);
-+}
-+
-+static inline void cmtp_add_msgpart(struct cmtp_session *session, int id, const unsigned char *buf, int count)
-+{
-+ struct sk_buff *skb = session->reassembly[id], *nskb;
-+ int size;
-+
-+ BT_DBG("session %p buf %p count %d", session, buf, count);
-+
-+ size = (skb) ? skb->len + count : count;
-+
-+ if (!(nskb = alloc_skb(size, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for CAPI message");
-+ return;
-+ }
-+
-+ if (skb && (skb->len > 0))
-+ memcpy(skb_put(nskb, skb->len), skb->data, skb->len);
-+
-+ memcpy(skb_put(nskb, count), buf, count);
-+
-+ session->reassembly[id] = nskb;
-+
-+ if (skb)
-+ kfree_skb(skb);
-+}
-+
-+static inline int cmtp_recv_frame(struct cmtp_session *session, struct sk_buff *skb)
-+{
-+ __u8 hdr, hdrlen, id;
-+ __u16 len;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ while (skb->len > 0) {
-+ hdr = skb->data[0];
-+
-+ switch (hdr & 0xc0) {
-+ case 0x40:
-+ hdrlen = 2;
-+ len = skb->data[1];
-+ break;
-+ case 0x80:
-+ hdrlen = 3;
-+ len = skb->data[1] | (skb->data[2] << 8);
-+ break;
-+ default:
-+ hdrlen = 1;
-+ len = 0;
-+ break;
-+ }
-+
-+ id = (hdr & 0x3c) >> 2;
-+
-+ BT_DBG("hdr 0x%02x hdrlen %d len %d id %d", hdr, hdrlen, len, id);
-+
-+ if (hdrlen + len > skb->len) {
-+ BT_ERR("Wrong size or header information in CMTP frame");
-+ break;
-+ }
-+
-+ if (len == 0) {
-+ skb_pull(skb, hdrlen);
-+ continue;
-+ }
-+
-+ switch (hdr & 0x03) {
-+ case 0x00:
-+ cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
-+ cmtp_recv_capimsg(session, session->reassembly[id]);
-+ session->reassembly[id] = NULL;
-+ break;
-+ case 0x01:
-+ cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
-+ break;
-+ default:
-+ if (session->reassembly[id] != NULL)
-+ kfree_skb(session->reassembly[id]);
-+ session->reassembly[id] = NULL;
-+ break;
-+ }
-+
-+ skb_pull(skb, hdrlen + len);
-+ }
-+
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+static int cmtp_send_frame(struct cmtp_session *session, unsigned char *data, int len)
-+{
-+ struct socket *sock = session->sock;
-+ struct iovec iv = { data, len };
-+ struct msghdr msg;
-+ int err;
-+
-+ BT_DBG("session %p data %p len %d", session, data, len);
-+
-+ if (!len)
-+ return 0;
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_iovlen = 1;
-+ msg.msg_iov = &iv;
-+
-+ err = sock->ops->sendmsg(sock, &msg, len, 0);
-+ return err;
-+}
-+
-+static int cmtp_process_transmit(struct cmtp_session *session)
-+{
-+ struct sk_buff *skb, *nskb;
-+ unsigned char *hdr;
-+ unsigned int size, tail;
-+
-+ BT_DBG("session %p", session);
-+
-+ if (!(nskb = alloc_skb(session->mtu, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for new frame");
-+ return -ENOMEM;
-+ }
-+
-+ while ((skb = skb_dequeue(&session->transmit))) {
-+ struct cmtp_scb *scb = (void *) skb->cb;
-+
-+ if ((tail = (session->mtu - nskb->len)) < 5) {
-+ cmtp_send_frame(session, nskb->data, nskb->len);
-+ skb_trim(nskb, 0);
-+ tail = session->mtu;
-+ }
-+
-+ size = min_t(uint, ((tail < 258) ? (tail - 2) : (tail - 3)), skb->len);
-+
-+ if ((scb->id < 0) && ((scb->id = cmtp_alloc_block_id(session)) < 0)) {
-+ skb_queue_head(&session->transmit, skb);
-+ break;
-+ }
-+
-+ if (size < 256) {
-+ hdr = skb_put(nskb, 2);
-+ hdr[0] = 0x40
-+ | ((scb->id << 2) & 0x3c)
-+ | ((skb->len == size) ? 0x00 : 0x01);
-+ hdr[1] = size;
-+ } else {
-+ hdr = skb_put(nskb, 3);
-+ hdr[0] = 0x80
-+ | ((scb->id << 2) & 0x3c)
-+ | ((skb->len == size) ? 0x00 : 0x01);
-+ hdr[1] = size & 0xff;
-+ hdr[2] = size >> 8;
-+ }
-+
-+ memcpy(skb_put(nskb, size), skb->data, size);
-+ skb_pull(skb, size);
-+
-+ if (skb->len > 0) {
-+ skb_queue_head(&session->transmit, skb);
-+ } else {
-+ cmtp_free_block_id(session, scb->id);
-+ if (scb->data) {
-+ cmtp_send_frame(session, nskb->data, nskb->len);
-+ skb_trim(nskb, 0);
-+ }
-+ kfree_skb(skb);
-+ }
-+ }
-+
-+ cmtp_send_frame(session, nskb->data, nskb->len);
-+
-+ kfree_skb(nskb);
-+
-+ return skb_queue_len(&session->transmit);
-+}
-+
-+static int cmtp_session(void *arg)
-+{
-+ struct cmtp_session *session = arg;
-+ struct sock *sk = session->sock->sk;
-+ struct sk_buff *skb;
-+ wait_queue_t wait;
-+
-+ BT_DBG("session %p", session);
-+
-+ daemonize(); reparent_to_init();
-+
-+ sprintf(current->comm, "kcmtpd_ctr_%d", session->num);
-+
-+ sigfillset(&current->blocked);
-+ flush_signals(current);
-+
-+ current->nice = -15;
-+
-+ set_fs(KERNEL_DS);
-+
-+ init_waitqueue_entry(&wait, current);
-+ add_wait_queue(sk->sleep, &wait);
-+ while (!atomic_read(&session->terminate)) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (sk->state != BT_CONNECTED)
-+ break;
-+
-+ while ((skb = skb_dequeue(&sk->receive_queue))) {
-+ skb_orphan(skb);
-+ cmtp_recv_frame(session, skb);
-+ }
-+
-+ cmtp_process_transmit(session);
-+
-+ schedule();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ down_write(&cmtp_session_sem);
-+
-+ if (!(session->flags & (1 << CMTP_LOOPBACK)))
-+ cmtp_detach_device(session);
-+
-+ fput(session->sock->file);
-+
-+ __cmtp_unlink_session(session);
-+
-+ up_write(&cmtp_session_sem);
-+
-+ kfree(session);
-+ return 0;
-+}
-+
-+int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
-+{
-+ struct cmtp_session *session, *s;
-+ bdaddr_t src, dst;
-+ int i, err;
-+
-+ BT_DBG("");
-+
-+ baswap(&src, &bluez_pi(sock->sk)->src);
-+ baswap(&dst, &bluez_pi(sock->sk)->dst);
-+
-+ session = kmalloc(sizeof(struct cmtp_session), GFP_KERNEL);
-+ if (!session)
-+ return -ENOMEM;
-+ memset(session, 0, sizeof(struct cmtp_session));
-+
-+ down_write(&cmtp_session_sem);
-+
-+ s = __cmtp_get_session(&bluez_pi(sock->sk)->dst);
-+ if (s && s->state == BT_CONNECTED) {
-+ err = -EEXIST;
-+ goto failed;
-+ }
-+
-+ bacpy(&session->bdaddr, &bluez_pi(sock->sk)->dst);
-+
-+ session->mtu = min_t(uint, l2cap_pi(sock->sk)->omtu, l2cap_pi(sock->sk)->imtu);
-+
-+ BT_DBG("mtu %d", session->mtu);
-+
-+ sprintf(session->name, "%s", batostr(&dst));
-+
-+ session->sock = sock;
-+ session->state = BT_CONFIG;
-+
-+ init_waitqueue_head(&session->wait);
-+
-+ session->ctrl = NULL;
-+ session->msgnum = CMTP_INITIAL_MSGNUM;
-+
-+ INIT_LIST_HEAD(&session->applications);
-+
-+ skb_queue_head_init(&session->transmit);
-+
-+ for (i = 0; i < 16; i++)
-+ session->reassembly[i] = NULL;
-+
-+ session->flags = req->flags;
-+
-+ __cmtp_link_session(session);
-+
-+ err = kernel_thread(cmtp_session, session, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-+ if (err < 0)
-+ goto unlink;
-+
-+ if (!(session->flags & (1 << CMTP_LOOPBACK))) {
-+ err = cmtp_attach_device(session);
-+ if (err < 0)
-+ goto detach;
-+ }
-+
-+ up_write(&cmtp_session_sem);
-+ return 0;
-+
-+detach:
-+ cmtp_detach_device(session);
-+
-+unlink:
-+ __cmtp_unlink_session(session);
-+
-+failed:
-+ up_write(&cmtp_session_sem);
-+ kfree(session);
-+ return err;
-+}
-+
-+int cmtp_del_connection(struct cmtp_conndel_req *req)
-+{
-+ struct cmtp_session *session;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ down_read(&cmtp_session_sem);
-+
-+ session = __cmtp_get_session(&req->bdaddr);
-+ if (session) {
-+ /* Flush the transmit queue */
-+ skb_queue_purge(&session->transmit);
-+
-+ /* Kill session thread */
-+ atomic_inc(&session->terminate);
-+ cmtp_schedule(session);
-+ } else
-+ err = -ENOENT;
-+
-+ up_read(&cmtp_session_sem);
-+ return err;
-+}
-+
-+int cmtp_get_connlist(struct cmtp_connlist_req *req)
-+{
-+ struct list_head *p;
-+ int err = 0, n = 0;
-+
-+ BT_DBG("");
-+
-+ down_read(&cmtp_session_sem);
-+
-+ list_for_each(p, &cmtp_session_list) {
-+ struct cmtp_session *session;
-+ struct cmtp_conninfo ci;
-+
-+ session = list_entry(p, struct cmtp_session, list);
-+
-+ __cmtp_copy_session(session, &ci);
-+
-+ if (copy_to_user(req->ci, &ci, sizeof(ci))) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ if (++n >= req->cnum)
-+ break;
-+
-+ req->ci++;
-+ }
-+ req->cnum = n;
-+
-+ up_read(&cmtp_session_sem);
-+ return err;
-+}
-+
-+int cmtp_get_conninfo(struct cmtp_conninfo *ci)
-+{
-+ struct cmtp_session *session;
-+ int err = 0;
-+
-+ down_read(&cmtp_session_sem);
-+
-+ session = __cmtp_get_session(&ci->bdaddr);
-+ if (session)
-+ __cmtp_copy_session(session, ci);
-+ else
-+ err = -ENOENT;
-+
-+ up_read(&cmtp_session_sem);
-+ return err;
-+}
-+
-+
-+int __init init_cmtp(void)
-+{
-+ l2cap_load();
-+
-+ cmtp_init_capi();
-+ cmtp_init_sockets();
-+
-+ BT_INFO("BlueZ CMTP ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>");
-+
-+ return 0;
-+}
-+
-+void __exit exit_cmtp(void)
-+{
-+ cmtp_cleanup_sockets();
-+ cmtp_cleanup_capi();
-+}
-+
-+module_init(init_cmtp);
-+module_exit(exit_cmtp);
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ CMTP ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/cmtp/Makefile linux-2.4.18-mh15/net/bluetooth/cmtp/Makefile
---- linux-2.4.18/net/bluetooth/cmtp/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/cmtp/Makefile 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the Linux Bluetooth CMTP layer
-+#
-+
-+O_TARGET := cmtp.o
-+
-+obj-y := core.o sock.o capi.o
-+obj-m += $(O_TARGET)
-+
-+include $(TOPDIR)/Rules.make
-diff -urN linux-2.4.18/net/bluetooth/cmtp/sock.c linux-2.4.18-mh15/net/bluetooth/cmtp/sock.c
---- linux-2.4.18/net/bluetooth/cmtp/sock.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/cmtp/sock.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,208 @@
-+/*
-+ CMTP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include "cmtp.h"
-+
-+#ifndef CONFIG_BLUEZ_CMTP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+static int cmtp_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ sock_orphan(sk);
-+ sock_put(sk);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct cmtp_connadd_req ca;
-+ struct cmtp_conndel_req cd;
-+ struct cmtp_connlist_req cl;
-+ struct cmtp_conninfo ci;
-+ struct socket *nsock;
-+ int err;
-+
-+ BT_DBG("cmd %x arg %lx", cmd, arg);
-+
-+ switch (cmd) {
-+ case CMTPCONNADD:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
-+ return -EFAULT;
-+
-+ nsock = sockfd_lookup(ca.sock, &err);
-+ if (!nsock)
-+ return err;
-+
-+ if (nsock->sk->state != BT_CONNECTED) {
-+ fput(nsock->file);
-+ return -EBADFD;
-+ }
-+
-+ err = cmtp_add_connection(&ca, nsock);
-+ if (!err) {
-+ if (copy_to_user((void *) arg, &ca, sizeof(ca)))
-+ err = -EFAULT;
-+ } else
-+ fput(nsock->file);
-+
-+ return err;
-+
-+ case CMTPCONNDEL:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
-+ return -EFAULT;
-+
-+ return cmtp_del_connection(&cd);
-+
-+ case CMTPGETCONNLIST:
-+ if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
-+ return -EFAULT;
-+
-+ if (cl.cnum <= 0)
-+ return -EINVAL;
-+
-+ err = cmtp_get_connlist(&cl);
-+ if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
-+ return -EFAULT;
-+
-+ return err;
-+
-+ case CMTPGETCONNINFO:
-+ if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
-+ return -EFAULT;
-+
-+ err = cmtp_get_conninfo(&ci);
-+ if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
-+ return -EFAULT;
-+
-+ return err;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static struct proto_ops cmtp_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: cmtp_sock_release,
-+ ioctl: cmtp_sock_ioctl,
-+ bind: sock_no_bind,
-+ getname: sock_no_getname,
-+ sendmsg: sock_no_sendmsg,
-+ recvmsg: sock_no_recvmsg,
-+ poll: sock_no_poll,
-+ listen: sock_no_listen,
-+ shutdown: sock_no_shutdown,
-+ setsockopt: sock_no_setsockopt,
-+ getsockopt: sock_no_getsockopt,
-+ connect: sock_no_connect,
-+ socketpair: sock_no_socketpair,
-+ accept: sock_no_accept,
-+ mmap: sock_no_mmap
-+};
-+
-+static int cmtp_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ if (sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &cmtp_sock_ops;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, 1)))
-+ return -ENOMEM;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ sock->state = SS_UNCONNECTED;
-+ sock_init_data(sock, sk);
-+
-+ sk->destruct = NULL;
-+ sk->protocol = protocol;
-+
-+ return 0;
-+}
-+
-+static struct net_proto_family cmtp_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: cmtp_sock_create
-+};
-+
-+int cmtp_init_sockets(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_CMTP, &cmtp_sock_family_ops))) {
-+ BT_ERR("Can't register CMTP socket layer (%d)", err);
-+ return err;
-+ }
-+
-+ return 0;
-+}
-+
-+void cmtp_cleanup_sockets(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_unregister(BTPROTO_CMTP)))
-+ BT_ERR("Can't unregister CMTP socket layer (%d)", err);
-+
-+ return;
-+}
-diff -urN linux-2.4.18/net/bluetooth/Config.in linux-2.4.18-mh15/net/bluetooth/Config.in
---- linux-2.4.18/net/bluetooth/Config.in 2001-06-12 04:15:27.000000000 +0200
-+++ linux-2.4.18-mh15/net/bluetooth/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -1,16 +1,23 @@
- #
--# Bluetooth configuration
-+# Bluetooth subsystem configuration
- #
-
- if [ "$CONFIG_NET" != "n" ]; then
-+
- mainmenu_option next_comment
- comment 'Bluetooth support'
- dep_tristate 'Bluetooth subsystem support' CONFIG_BLUEZ $CONFIG_NET
-
- if [ "$CONFIG_BLUEZ" != "n" ]; then
- dep_tristate 'L2CAP protocol support' CONFIG_BLUEZ_L2CAP $CONFIG_BLUEZ
-+ dep_tristate 'SCO links support' CONFIG_BLUEZ_SCO $CONFIG_BLUEZ
-+ source net/bluetooth/rfcomm/Config.in
-+ source net/bluetooth/bnep/Config.in
-+ source net/bluetooth/cmtp/Config.in
-+ source net/bluetooth/hidp/Config.in
- source drivers/bluetooth/Config.in
- fi
-+
- endmenu
- fi
-
-diff -urN linux-2.4.18/net/bluetooth/hci_conn.c linux-2.4.18-mh15/net/bluetooth/hci_conn.c
---- linux-2.4.18/net/bluetooth/hci_conn.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/hci_conn.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,435 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * HCI Connection handling.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/notifier.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+#ifndef HCI_CORE_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+void hci_acl_connect(struct hci_conn *conn)
-+{
-+ struct hci_dev *hdev = conn->hdev;
-+ struct inquiry_entry *ie;
-+ create_conn_cp cp;
-+
-+ BT_DBG("%p", conn);
-+
-+ conn->state = BT_CONNECT;
-+ conn->out = 1;
-+ conn->link_mode = HCI_LM_MASTER;
-+
-+ memset(&cp, 0, sizeof(cp));
-+ bacpy(&cp.bdaddr, &conn->dst);
-+ cp.pscan_rep_mode = 0x02;
-+
-+ if ((ie = inquiry_cache_lookup(hdev, &conn->dst)) &&
-+ inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
-+ cp.pscan_rep_mode = ie->info.pscan_rep_mode;
-+ cp.pscan_mode = ie->info.pscan_mode;
-+ cp.clock_offset = ie->info.clock_offset | __cpu_to_le16(0x8000);
-+ }
-+
-+ cp.pkt_type = __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK);
-+ if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
-+ cp.role_switch = 0x01;
-+ else
-+ cp.role_switch = 0x00;
-+
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN,
-+ CREATE_CONN_CP_SIZE, &cp);
-+}
-+
-+void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
-+{
-+ disconnect_cp cp;
-+
-+ BT_DBG("%p", conn);
-+
-+ conn->state = BT_DISCONN;
-+
-+ cp.handle = __cpu_to_le16(conn->handle);
-+ cp.reason = reason;
-+ hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT,
-+ DISCONNECT_CP_SIZE, &cp);
-+}
-+
-+void hci_add_sco(struct hci_conn *conn, __u16 handle)
-+{
-+ struct hci_dev *hdev = conn->hdev;
-+ add_sco_cp cp;
-+
-+ BT_DBG("%p", conn);
-+
-+ conn->state = BT_CONNECT;
-+ conn->out = 1;
-+
-+ cp.pkt_type = __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
-+ cp.handle = __cpu_to_le16(handle);
-+
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, ADD_SCO_CP_SIZE, &cp);
-+}
-+
-+static void hci_conn_timeout(unsigned long arg)
-+{
-+ struct hci_conn *conn = (void *)arg;
-+ struct hci_dev *hdev = conn->hdev;
-+
-+ BT_DBG("conn %p state %d", conn, conn->state);
-+
-+ if (atomic_read(&conn->refcnt))
-+ return;
-+
-+ hci_dev_lock(hdev);
-+ if (conn->state == BT_CONNECTED)
-+ hci_acl_disconn(conn, 0x13);
-+ else
-+ conn->state = BT_CLOSED;
-+ hci_dev_unlock(hdev);
-+ return;
-+}
-+
-+static void hci_conn_init_timer(struct hci_conn *conn)
-+{
-+ init_timer(&conn->timer);
-+ conn->timer.function = hci_conn_timeout;
-+ conn->timer.data = (unsigned long)conn;
-+}
-+
-+struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
-+{
-+ struct hci_conn *conn;
-+
-+ BT_DBG("%s dst %s", hdev->name, batostr(dst));
-+
-+ if (!(conn = kmalloc(sizeof(struct hci_conn), GFP_ATOMIC)))
-+ return NULL;
-+ memset(conn, 0, sizeof(struct hci_conn));
-+
-+ bacpy(&conn->dst, dst);
-+ conn->type = type;
-+ conn->hdev = hdev;
-+ conn->state = BT_OPEN;
-+
-+ skb_queue_head_init(&conn->data_q);
-+ hci_conn_init_timer(conn);
-+
-+ atomic_set(&conn->refcnt, 0);
-+
-+ hci_dev_hold(hdev);
-+
-+ tasklet_disable(&hdev->tx_task);
-+ conn_hash_add(hdev, conn);
-+ tasklet_enable(&hdev->tx_task);
-+
-+ return conn;
-+}
-+
-+int hci_conn_del(struct hci_conn *conn)
-+{
-+ struct hci_dev *hdev = conn->hdev;
-+
-+ BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
-+
-+ hci_conn_del_timer(conn);
-+
-+ if (conn->type == SCO_LINK) {
-+ struct hci_conn *acl = conn->link;
-+ if (acl) {
-+ acl->link = NULL;
-+ hci_conn_put(acl);
-+ }
-+ } else {
-+ struct hci_conn *sco = conn->link;
-+ if (sco)
-+ sco->link = NULL;
-+
-+ /* Unacked frames */
-+ hdev->acl_cnt += conn->sent;
-+ }
-+
-+ tasklet_disable(&hdev->tx_task);
-+ conn_hash_del(hdev, conn);
-+ tasklet_enable(&hdev->tx_task);
-+
-+ skb_queue_purge(&conn->data_q);
-+
-+ hci_dev_put(hdev);
-+
-+ kfree(conn);
-+ return 0;
-+}
-+
-+struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
-+{
-+ int use_src = bacmp(src, BDADDR_ANY);
-+ struct hci_dev *hdev = NULL;
-+ struct list_head *p;
-+
-+ BT_DBG("%s -> %s", batostr(src), batostr(dst));
-+
-+ read_lock_bh(&hdev_list_lock);
-+
-+ list_for_each(p, &hdev_list) {
-+ struct hci_dev *d;
-+ d = list_entry(p, struct hci_dev, list);
-+
-+ if (!test_bit(HCI_UP, &d->flags))
-+ continue;
-+
-+ /* Simple routing:
-+ * No source address - find interface with bdaddr != dst
-+ * Source address - find interface with bdaddr == src
-+ */
-+
-+ if (use_src) {
-+ if (!bacmp(&d->bdaddr, src)) {
-+ hdev = d; break;
-+ }
-+ } else {
-+ if (bacmp(&d->bdaddr, dst)) {
-+ hdev = d; break;
-+ }
-+ }
-+ }
-+
-+ if (hdev)
-+ hci_dev_hold(hdev);
-+
-+ read_unlock_bh(&hdev_list_lock);
-+ return hdev;
-+}
-+
-+/* Create SCO or ACL connection.
-+ * Device _must_ be locked */
-+struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
-+{
-+ struct hci_conn *acl;
-+
-+ BT_DBG("%s dst %s", hdev->name, batostr(dst));
-+
-+ if (!(acl = conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
-+ if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
-+ return NULL;
-+ }
-+
-+ hci_conn_hold(acl);
-+
-+ if (acl->state == BT_OPEN || acl->state == BT_CLOSED)
-+ hci_acl_connect(acl);
-+
-+ if (type == SCO_LINK) {
-+ struct hci_conn *sco;
-+
-+ if (!(sco = conn_hash_lookup_ba(hdev, SCO_LINK, dst))) {
-+ if (!(sco = hci_conn_add(hdev, SCO_LINK, dst))) {
-+ hci_conn_put(acl);
-+ return NULL;
-+ }
-+ }
-+ acl->link = sco;
-+ sco->link = acl;
-+
-+ hci_conn_hold(sco);
-+
-+ if (acl->state == BT_CONNECTED &&
-+ (sco->state == BT_OPEN || sco->state == BT_CLOSED))
-+ hci_add_sco(sco, acl->handle);
-+
-+ return sco;
-+ } else {
-+ return acl;
-+ }
-+}
-+
-+/* Authenticate remote device */
-+int hci_conn_auth(struct hci_conn *conn)
-+{
-+ BT_DBG("conn %p", conn);
-+
-+ if (conn->link_mode & HCI_LM_AUTH)
-+ return 1;
-+
-+ if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
-+ auth_requested_cp ar;
-+ ar.handle = __cpu_to_le16(conn->handle);
-+ hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_AUTH_REQUESTED,
-+ AUTH_REQUESTED_CP_SIZE, &ar);
-+ }
-+ return 0;
-+}
-+
-+/* Enable encryption */
-+int hci_conn_encrypt(struct hci_conn *conn)
-+{
-+ BT_DBG("conn %p", conn);
-+
-+ if (conn->link_mode & HCI_LM_ENCRYPT)
-+ return 1;
-+
-+ if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
-+ return 0;
-+
-+ if (hci_conn_auth(conn)) {
-+ set_conn_encrypt_cp ce;
-+ ce.handle = __cpu_to_le16(conn->handle);
-+ ce.encrypt = 1;
-+ hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT,
-+ SET_CONN_ENCRYPT_CP_SIZE, &ce);
-+ }
-+ return 0;
-+}
-+
-+/* Drop all connection on the device */
-+void hci_conn_hash_flush(struct hci_dev *hdev)
-+{
-+ struct conn_hash *h = &hdev->conn_hash;
-+ struct list_head *p;
-+
-+ BT_DBG("hdev %s", hdev->name);
-+
-+ p = h->list.next;
-+ while (p != &h->list) {
-+ struct hci_conn *c;
-+
-+ c = list_entry(p, struct hci_conn, list);
-+ p = p->next;
-+
-+ c->state = BT_CLOSED;
-+
-+ hci_proto_disconn_ind(c, 0x16);
-+ hci_conn_del(c);
-+ }
-+}
-+
-+int hci_get_conn_list(unsigned long arg)
-+{
-+ struct hci_conn_list_req req, *cl;
-+ struct hci_conn_info *ci;
-+ struct hci_dev *hdev;
-+ struct list_head *p;
-+ int n = 0, size, err;
-+
-+ if (copy_from_user(&req, (void *) arg, sizeof(req)))
-+ return -EFAULT;
-+
-+ if (!req.conn_num || req.conn_num > (PAGE_SIZE * 2) / sizeof(*ci))
-+ return -EINVAL;
-+
-+ size = sizeof(req) + req.conn_num * sizeof(*ci);
-+
-+ if (!(cl = (void *) kmalloc(size, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ if (!(hdev = hci_dev_get(req.dev_id))) {
-+ kfree(cl);
-+ return -ENODEV;
-+ }
-+
-+ ci = cl->conn_info;
-+
-+ hci_dev_lock_bh(hdev);
-+ list_for_each(p, &hdev->conn_hash.list) {
-+ register struct hci_conn *c;
-+ c = list_entry(p, struct hci_conn, list);
-+
-+ bacpy(&(ci + n)->bdaddr, &c->dst);
-+ (ci + n)->handle = c->handle;
-+ (ci + n)->type = c->type;
-+ (ci + n)->out = c->out;
-+ (ci + n)->state = c->state;
-+ (ci + n)->link_mode = c->link_mode;
-+ if (++n >= req.conn_num)
-+ break;
-+ }
-+ hci_dev_unlock_bh(hdev);
-+
-+ cl->dev_id = hdev->id;
-+ cl->conn_num = n;
-+ size = sizeof(req) + n * sizeof(*ci);
-+
-+ hci_dev_put(hdev);
-+
-+ err = copy_to_user((void *) arg, cl, size);
-+ kfree(cl);
-+
-+ return err ? -EFAULT : 0;
-+}
-+
-+int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg)
-+{
-+ struct hci_conn_info_req req;
-+ struct hci_conn_info ci;
-+ struct hci_conn *conn;
-+ char *ptr = (void *) arg + sizeof(req);
-+
-+ if (copy_from_user(&req, (void *) arg, sizeof(req)))
-+ return -EFAULT;
-+
-+ hci_dev_lock_bh(hdev);
-+ conn = conn_hash_lookup_ba(hdev, req.type, &req.bdaddr);
-+ if (conn) {
-+ bacpy(&ci.bdaddr, &conn->dst);
-+ ci.handle = conn->handle;
-+ ci.type = conn->type;
-+ ci.out = conn->out;
-+ ci.state = conn->state;
-+ ci.link_mode = conn->link_mode;
-+ }
-+ hci_dev_unlock_bh(hdev);
-+
-+ if (!conn)
-+ return -ENOENT;
-+
-+ return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0;
-+}
-diff -urN linux-2.4.18/net/bluetooth/hci_core.c linux-2.4.18-mh15/net/bluetooth/hci_core.c
---- linux-2.4.18/net/bluetooth/hci_core.c 2001-11-09 23:21:21.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/hci_core.c 2004-08-01 16:26:23.000000000 +0200
-@@ -25,11 +25,12 @@
- /*
- * BlueZ HCI Core.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
- #include <linux/module.h>
-+#include <linux/kmod.h>
-
- #include <linux/types.h>
- #include <linux/errno.h>
-@@ -50,12 +51,11 @@
- #include <asm/unaligned.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
-
- #ifndef HCI_CORE_DEBUG
--#undef DBG
--#define DBG( A... )
-+#undef BT_DBG
-+#define BT_DBG( A... )
- #endif
-
- static void hci_cmd_task(unsigned long arg);
-@@ -63,279 +63,69 @@
- static void hci_tx_task(unsigned long arg);
- static void hci_notify(struct hci_dev *hdev, int event);
-
--static rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
-+rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
-
- /* HCI device list */
--struct hci_dev *hdev_list[HCI_MAX_DEV];
--spinlock_t hdev_list_lock;
--#define GET_HDEV(a) (hdev_list[a])
--
--/* HCI protocol list */
--struct hci_proto *hproto_list[HCI_MAX_PROTO];
--#define GET_HPROTO(a) (hproto_list[a])
-+LIST_HEAD(hdev_list);
-+rwlock_t hdev_list_lock = RW_LOCK_UNLOCKED;
-
--/* HCI notifiers list */
--struct notifier_block *hci_dev_notifier;
--
--/* HCI device notifications */
--int hci_register_notifier(struct notifier_block *nb)
--{
-- int err, i;
-- struct hci_dev *hdev;
--
-- if ((err = notifier_chain_register(&hci_dev_notifier, nb)))
-- return err;
--
-- /* Notify about already registered devices */
-- spin_lock(&hdev_list_lock);
-- for (i = 0; i < HCI_MAX_DEV; i++) {
-- if (!(hdev = GET_HDEV(i)))
-- continue;
-- if (hdev->flags & HCI_UP)
-- (*nb->notifier_call)(nb, HCI_DEV_UP, hdev);
-- }
-- spin_unlock(&hdev_list_lock);
--
-- return 0;
--}
--
--int hci_unregister_notifier(struct notifier_block *nb)
--{
-- return notifier_chain_unregister(&hci_dev_notifier, nb);
--}
--
--static inline void hci_notify(struct hci_dev *hdev, int event)
--{
-- notifier_call_chain(&hci_dev_notifier, event, hdev);
--}
--
--/* Get HCI device by index (device is locked on return)*/
--struct hci_dev *hci_dev_get(int index)
--{
-- struct hci_dev *hdev;
-- DBG("%d", index);
--
-- if (index < 0 || index >= HCI_MAX_DEV)
-- return NULL;
--
-- spin_lock(&hdev_list_lock);
-- if ((hdev = GET_HDEV(index)))
-- hci_dev_hold(hdev);
-- spin_unlock(&hdev_list_lock);
--
-- return hdev;
--}
--
--/* Flush inquiry cache */
--void inquiry_cache_flush(struct inquiry_cache *cache)
--{
-- struct inquiry_entry *next = cache->list, *e;
--
-- DBG("cache %p", cache);
--
-- cache->list = NULL;
-- while ((e = next)) {
-- next = e->next;
-- kfree(e);
-- }
--}
--
--/* Lookup by bdaddr.
-- * Cache must be locked. */
--static struct inquiry_entry * __inquiry_cache_lookup(struct inquiry_cache *cache, bdaddr_t *bdaddr)
--{
-- struct inquiry_entry *e;
--
-- DBG("cache %p, %s", cache, batostr(bdaddr));
--
-- for (e = cache->list; e; e = e->next)
-- if (!bacmp(&e->info.bdaddr, bdaddr))
-- break;
--
-- return e;
--}
--
--static void inquiry_cache_update(struct inquiry_cache *cache, inquiry_info *info)
--{
-- struct inquiry_entry *e;
--
-- DBG("cache %p, %s", cache, batostr(&info->bdaddr));
--
-- inquiry_cache_lock(cache);
--
-- if (!(e = __inquiry_cache_lookup(cache, &info->bdaddr))) {
-- /* Entry not in the cache. Add new one. */
-- if (!(e = kmalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
-- goto unlock;
-- memset(e, 0, sizeof(struct inquiry_entry));
-- e->next = cache->list;
-- cache->list = e;
-- }
--
-- memcpy(&e->info, info, sizeof(inquiry_info));
-- e->timestamp = jiffies;
-- cache->timestamp = jiffies;
--unlock:
-- inquiry_cache_unlock(cache);
--}
--
--static int inquiry_cache_dump(struct inquiry_cache *cache, int num, __u8 *buf)
--{
-- inquiry_info *info = (inquiry_info *) buf;
-- struct inquiry_entry *e;
-- int copied = 0;
-+/* HCI protocols */
-+#define HCI_MAX_PROTO 2
-+struct hci_proto *hci_proto[HCI_MAX_PROTO];
-
-- inquiry_cache_lock(cache);
--
-- for (e = cache->list; e && copied < num; e = e->next, copied++)
-- memcpy(info++, &e->info, sizeof(inquiry_info));
-+/* HCI notifiers list */
-+static struct notifier_block *hci_notifier;
-
-- inquiry_cache_unlock(cache);
-
-- DBG("cache %p, copied %d", cache, copied);
-- return copied;
--}
-+/* ---- HCI notifications ---- */
-
--/* --------- BaseBand connections --------- */
--static struct hci_conn *hci_conn_add(struct hci_dev *hdev, __u16 handle, __u8 type, bdaddr_t *dst)
-+int hci_register_notifier(struct notifier_block *nb)
- {
-- struct hci_conn *conn;
--
-- DBG("%s handle %d dst %s", hdev->name, handle, batostr(dst));
--
-- if ( conn_hash_lookup(&hdev->conn_hash, handle)) {
-- ERR("%s handle 0x%x already exists", hdev->name, handle);
-- return NULL;
-- }
--
-- if (!(conn = kmalloc(sizeof(struct hci_conn), GFP_ATOMIC)))
-- return NULL;
-- memset(conn, 0, sizeof(struct hci_conn));
--
-- bacpy(&conn->dst, dst);
-- conn->handle = handle;
-- conn->type = type;
-- conn->hdev = hdev;
--
-- skb_queue_head_init(&conn->data_q);
--
-- hci_dev_hold(hdev);
-- conn_hash_add(&hdev->conn_hash, handle, conn);
--
-- return conn;
-+ return notifier_chain_register(&hci_notifier, nb);
- }
-
--static int hci_conn_del(struct hci_dev *hdev, struct hci_conn *conn)
-+int hci_unregister_notifier(struct notifier_block *nb)
- {
-- DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
--
-- conn_hash_del(&hdev->conn_hash, conn);
-- hci_dev_put(hdev);
--
-- /* Unacked frames */
-- hdev->acl_cnt += conn->sent;
--
-- skb_queue_purge(&conn->data_q);
--
-- kfree(conn);
-- return 0;
-+ return notifier_chain_unregister(&hci_notifier, nb);
- }
-
--/* Drop all connection on the device */
--static void hci_conn_hash_flush(struct hci_dev *hdev)
-+void hci_notify(struct hci_dev *hdev, int event)
- {
-- struct conn_hash *h = &hdev->conn_hash;
-- struct hci_proto *hp;
-- struct list_head *p;
--
-- DBG("hdev %s", hdev->name);
--
-- p = h->list.next;
-- while (p != &h->list) {
-- struct hci_conn *c;
--
-- c = list_entry(p, struct hci_conn, list);
-- p = p->next;
--
-- if (c->type == ACL_LINK) {
-- /* ACL link notify L2CAP layer */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
-- hp->disconn_ind(c, 0x16);
-- } else {
-- /* SCO link (no notification) */
-- }
--
-- hci_conn_del(hdev, c);
-- }
-+ notifier_call_chain(&hci_notifier, event, hdev);
- }
-
--int hci_connect(struct hci_dev *hdev, bdaddr_t *bdaddr)
--{
-- struct inquiry_cache *cache = &hdev->inq_cache;
-- struct inquiry_entry *e;
-- create_conn_cp cc;
-- __u16 clock_offset;
--
-- DBG("%s bdaddr %s", hdev->name, batostr(bdaddr));
--
-- if (!(hdev->flags & HCI_UP))
-- return -ENODEV;
--
-- inquiry_cache_lock_bh(cache);
--
-- if (!(e = __inquiry_cache_lookup(cache, bdaddr)) || inquiry_entry_age(e) > INQUIRY_ENTRY_AGE_MAX) {
-- cc.pscan_rep_mode = 0;
-- cc.pscan_mode = 0;
-- clock_offset = 0;
-- } else {
-- cc.pscan_rep_mode = e->info.pscan_rep_mode;
-- cc.pscan_mode = e->info.pscan_mode;
-- clock_offset = __le16_to_cpu(e->info.clock_offset) & 0x8000;
-- }
--
-- inquiry_cache_unlock_bh(cache);
--
-- bacpy(&cc.bdaddr, bdaddr);
-- cc.pkt_type = __cpu_to_le16(hdev->pkt_type);
-- cc.clock_offset = __cpu_to_le16(clock_offset);
--
-- if (lmp_rswitch_capable(hdev))
-- cc.role_switch = 0x01;
-- else
-- cc.role_switch = 0x00;
--
-- hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, CREATE_CONN_CP_SIZE, &cc);
-+/* ---- HCI hotplug support ---- */
-
-- return 0;
--}
-+#ifdef CONFIG_HOTPLUG
-
--int hci_disconnect(struct hci_conn *conn, __u8 reason)
-+static int hci_run_hotplug(char *dev, char *action)
- {
-- disconnect_cp dc;
--
-- DBG("conn %p handle %d", conn, conn->handle);
-+ char *argv[3], *envp[5], dstr[20], astr[32];
-
-- dc.handle = __cpu_to_le16(conn->handle);
-- dc.reason = reason;
-- hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT, DISCONNECT_CP_SIZE, &dc);
-+ sprintf(dstr, "DEVICE=%s", dev);
-+ sprintf(astr, "ACTION=%s", action);
-
-- return 0;
--}
-+ argv[0] = hotplug_path;
-+ argv[1] = "bluetooth";
-+ argv[2] = NULL;
-
--/* --------- HCI request handling ------------ */
--static inline void hci_req_lock(struct hci_dev *hdev)
--{
-- down(&hdev->req_lock);
-+ envp[0] = "HOME=/";
-+ envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-+ envp[2] = dstr;
-+ envp[3] = astr;
-+ envp[4] = NULL;
-+
-+ return call_usermodehelper(argv[0], argv, envp);
- }
-+#else
-+#define hci_run_hotplug(A...)
-+#endif
-
--static inline void hci_req_unlock(struct hci_dev *hdev)
--{
-- up(&hdev->req_lock);
--}
-+/* ---- HCI requests ---- */
-
--static inline void hci_req_complete(struct hci_dev *hdev, int result)
-+void hci_req_complete(struct hci_dev *hdev, int result)
- {
-- DBG("%s result 0x%2.2x", hdev->name, result);
-+ BT_DBG("%s result 0x%2.2x", hdev->name, result);
-
- if (hdev->req_status == HCI_REQ_PEND) {
- hdev->req_result = result;
-@@ -344,9 +134,9 @@
- }
- }
-
--static inline void hci_req_cancel(struct hci_dev *hdev, int err)
-+void hci_req_cancel(struct hci_dev *hdev, int err)
- {
-- DBG("%s err 0x%2.2x", hdev->name, err);
-+ BT_DBG("%s err 0x%2.2x", hdev->name, err);
-
- if (hdev->req_status == HCI_REQ_PEND) {
- hdev->req_result = err;
-@@ -356,23 +146,22 @@
- }
-
- /* Execute request and wait for completion. */
--static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
-- unsigned long opt, __u32 timeout)
-+static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), unsigned long opt, __u32 timeout)
- {
- DECLARE_WAITQUEUE(wait, current);
- int err = 0;
-
-- DBG("%s start", hdev->name);
-+ BT_DBG("%s start", hdev->name);
-
- hdev->req_status = HCI_REQ_PEND;
-
- add_wait_queue(&hdev->req_wait_q, &wait);
-- current->state = TASK_INTERRUPTIBLE;
-+ set_current_state(TASK_INTERRUPTIBLE);
-
- req(hdev, opt);
- schedule_timeout(timeout);
-
-- current->state = TASK_RUNNING;
-+ set_current_state(TASK_RUNNING);
- remove_wait_queue(&hdev->req_wait_q, &wait);
-
- if (signal_pending(current))
-@@ -394,7 +183,7 @@
-
- hdev->req_status = hdev->req_result = 0;
-
-- DBG("%s end: err %d", hdev->name, err);
-+ BT_DBG("%s end: err %d", hdev->name, err);
-
- return err;
- }
-@@ -412,10 +201,9 @@
- return ret;
- }
-
--/* --------- HCI requests ---------- */
- static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
- {
-- DBG("%s %ld", hdev->name, opt);
-+ BT_DBG("%s %ld", hdev->name, opt);
-
- /* Reset device */
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
-@@ -423,27 +211,44 @@
-
- static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
- {
-- set_event_flt_cp ec;
-+ set_event_flt_cp ef;
- __u16 param;
-
-- DBG("%s %ld", hdev->name, opt);
-+ BT_DBG("%s %ld", hdev->name, opt);
-
- /* Mandatory initialization */
-
-+ /* Reset */
-+ if (test_bit(HCI_QUIRK_RESET_ON_INIT, &hdev->quirks))
-+ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
-+
- /* Read Local Supported Features */
- hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES, 0, NULL);
-
- /* Read Buffer Size (ACL mtu, max pkt, etc.) */
- hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
-
-+#if 0
-+ /* Host buffer size */
-+ {
-+ host_buffer_size_cp bs;
-+ bs.acl_mtu = __cpu_to_le16(HCI_MAX_ACL_SIZE);
-+ bs.sco_mtu = HCI_MAX_SCO_SIZE;
-+ bs.acl_max_pkt = __cpu_to_le16(0xffff);
-+ bs.sco_max_pkt = __cpu_to_le16(0xffff);
-+ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_HOST_BUFFER_SIZE,
-+ HOST_BUFFER_SIZE_CP_SIZE, &bs);
-+ }
-+#endif
-+
- /* Read BD Address */
- hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, NULL);
-
- /* Optional initialization */
-
- /* Clear Event Filters */
-- ec.flt_type = FLT_CLEAR_ALL;
-- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &ec);
-+ ef.flt_type = FLT_CLEAR_ALL;
-+ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &ef);
-
- /* Page timeout ~20 secs */
- param = __cpu_to_le16(0x8000);
-@@ -458,7 +263,7 @@
- {
- __u8 scan = opt;
-
-- DBG("%s %x", hdev->name, scan);
-+ BT_DBG("%s %x", hdev->name, scan);
-
- /* Inquiry and Page scans */
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, &scan);
-@@ -468,116 +273,273 @@
- {
- __u8 auth = opt;
-
-- DBG("%s %x", hdev->name, auth);
-+ BT_DBG("%s %x", hdev->name, auth);
-
- /* Authentication */
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE, 1, &auth);
- }
-
--static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
-+static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
- {
-- struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
-- inquiry_cp ic;
-+ __u8 encrypt = opt;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s %x", hdev->name, encrypt);
-
-- /* Start Inquiry */
-- memcpy(&ic.lap, &ir->lap, 3);
-- ic.lenght = ir->length;
-- ic.num_rsp = ir->num_rsp;
-- hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, &ic);
-+ /* Authentication */
-+ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE, 1, &encrypt);
- }
-
--/* HCI ioctl helpers */
--int hci_dev_open(__u16 dev)
-+/* Get HCI device by index.
-+ * Device is locked on return. */
-+struct hci_dev *hci_dev_get(int index)
- {
- struct hci_dev *hdev;
-- int ret = 0;
--
-- if (!(hdev = hci_dev_get(dev)))
-- return -ENODEV;
-+ struct list_head *p;
-
-- DBG("%s %p", hdev->name, hdev);
-+ BT_DBG("%d", index);
-
-- hci_req_lock(hdev);
-+ if (index < 0)
-+ return NULL;
-
-- if (hdev->flags & HCI_UP) {
-- ret = -EALREADY;
-- goto done;
-+ read_lock(&hdev_list_lock);
-+ list_for_each(p, &hdev_list) {
-+ hdev = list_entry(p, struct hci_dev, list);
-+ if (hdev->id == index) {
-+ hci_dev_hold(hdev);
-+ goto done;
-+ }
- }
-+ hdev = NULL;
-+done:
-+ read_unlock(&hdev_list_lock);
-+ return hdev;
-+}
-
-- if (hdev->open(hdev)) {
-- ret = -EIO;
-- goto done;
-- }
-+/* ---- Inquiry support ---- */
-+void inquiry_cache_flush(struct hci_dev *hdev)
-+{
-+ struct inquiry_cache *cache = &hdev->inq_cache;
-+ struct inquiry_entry *next = cache->list, *e;
-
-- if (hdev->flags & HCI_NORMAL) {
-- atomic_set(&hdev->cmd_cnt, 1);
-- hdev->flags |= HCI_INIT;
-+ BT_DBG("cache %p", cache);
-
-- //__hci_request(hdev, hci_reset_req, 0, HZ);
-- ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
--
-- hdev->flags &= ~HCI_INIT;
-+ cache->list = NULL;
-+ while ((e = next)) {
-+ next = e->next;
-+ kfree(e);
- }
-+}
-
-- if (!ret) {
-- hdev->flags |= HCI_UP;
-- hci_notify(hdev, HCI_DEV_UP);
-- } else {
-- /* Init failed, cleanup */
-- tasklet_kill(&hdev->rx_task);
-- tasklet_kill(&hdev->tx_task);
-- tasklet_kill(&hdev->cmd_task);
-+struct inquiry_entry *inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
-+{
-+ struct inquiry_cache *cache = &hdev->inq_cache;
-+ struct inquiry_entry *e;
-
-- skb_queue_purge(&hdev->cmd_q);
-- skb_queue_purge(&hdev->rx_q);
-+ BT_DBG("cache %p, %s", cache, batostr(bdaddr));
-
-- if (hdev->flush)
-- hdev->flush(hdev);
-+ for (e = cache->list; e; e = e->next)
-+ if (!bacmp(&e->info.bdaddr, bdaddr))
-+ break;
-+ return e;
-+}
-
-- if (hdev->sent_cmd) {
-- kfree_skb(hdev->sent_cmd);
-- hdev->sent_cmd = NULL;
-- }
-+void inquiry_cache_update(struct hci_dev *hdev, inquiry_info *info)
-+{
-+ struct inquiry_cache *cache = &hdev->inq_cache;
-+ struct inquiry_entry *e;
-
-- hdev->close(hdev);
-- }
-+ BT_DBG("cache %p, %s", cache, batostr(&info->bdaddr));
-
--done:
-- hci_req_unlock(hdev);
-- hci_dev_put(hdev);
-+ if (!(e = inquiry_cache_lookup(hdev, &info->bdaddr))) {
-+ /* Entry not in the cache. Add new one. */
-+ if (!(e = kmalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
-+ return;
-+ memset(e, 0, sizeof(struct inquiry_entry));
-+ e->next = cache->list;
-+ cache->list = e;
-+ }
-
-- return ret;
-+ memcpy(&e->info, info, sizeof(inquiry_info));
-+ e->timestamp = jiffies;
-+ cache->timestamp = jiffies;
- }
-
--int hci_dev_close(__u16 dev)
-+int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
- {
-- struct hci_dev *hdev;
--
-- if (!(hdev = hci_dev_get(dev)))
-- return -ENODEV;
-+ struct inquiry_cache *cache = &hdev->inq_cache;
-+ inquiry_info *info = (inquiry_info *) buf;
-+ struct inquiry_entry *e;
-+ int copied = 0;
-
-- DBG("%s %p", hdev->name, hdev);
-+ for (e = cache->list; e && copied < num; e = e->next, copied++)
-+ memcpy(info++, &e->info, sizeof(inquiry_info));
-
-- hci_req_cancel(hdev, ENODEV);
-- hci_req_lock(hdev);
-+ BT_DBG("cache %p, copied %d", cache, copied);
-+ return copied;
-+}
-
-- if (!(hdev->flags & HCI_UP))
-- goto done;
-+static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
-+{
-+ struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
-+ inquiry_cp ic;
-
-- /* Kill RX and TX tasks */
-- tasklet_kill(&hdev->rx_task);
-- tasklet_kill(&hdev->tx_task);
-+ BT_DBG("%s", hdev->name);
-
-- inquiry_cache_flush(&hdev->inq_cache);
-+ if (test_bit(HCI_INQUIRY, &hdev->flags))
-+ return;
-
-- hci_conn_hash_flush(hdev);
-+ /* Start Inquiry */
-+ memcpy(&ic.lap, &ir->lap, 3);
-+ ic.length = ir->length;
-+ ic.num_rsp = ir->num_rsp;
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, &ic);
-+}
-
-- /* Clear flags */
-- hdev->flags &= HCI_SOCK;
-- hdev->flags |= HCI_NORMAL;
-+int hci_inquiry(unsigned long arg)
-+{
-+ struct hci_inquiry_req ir;
-+ struct hci_dev *hdev;
-+ int err = 0, do_inquiry = 0, max_rsp;
-+ long timeo;
-+ __u8 *buf, *ptr;
-
-+ ptr = (void *) arg;
-+ if (copy_from_user(&ir, ptr, sizeof(ir)))
-+ return -EFAULT;
-+
-+ if (!(hdev = hci_dev_get(ir.dev_id)))
-+ return -ENODEV;
-+
-+ hci_dev_lock_bh(hdev);
-+ if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
-+ inquiry_cache_empty(hdev) ||
-+ ir.flags & IREQ_CACHE_FLUSH) {
-+ inquiry_cache_flush(hdev);
-+ do_inquiry = 1;
-+ }
-+ hci_dev_unlock_bh(hdev);
-+
-+ timeo = ir.length * 2 * HZ;
-+ if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
-+ goto done;
-+
-+ /* for unlimited number of responses we will use buffer with 255 entries */
-+ max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
-+
-+ /* cache_dump can't sleep. Therefore we allocate temp buffer and then
-+ * copy it to the user space.
-+ */
-+ if (!(buf = kmalloc(sizeof(inquiry_info) * max_rsp, GFP_KERNEL))) {
-+ err = -ENOMEM;
-+ goto done;
-+ }
-+
-+ hci_dev_lock_bh(hdev);
-+ ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
-+ hci_dev_unlock_bh(hdev);
-+
-+ BT_DBG("num_rsp %d", ir.num_rsp);
-+
-+ if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) +
-+ (sizeof(inquiry_info) * ir.num_rsp))) {
-+ copy_to_user(ptr, &ir, sizeof(ir));
-+ ptr += sizeof(ir);
-+ copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
-+ } else
-+ err = -EFAULT;
-+
-+ kfree(buf);
-+
-+done:
-+ hci_dev_put(hdev);
-+ return err;
-+}
-+
-+/* ---- HCI ioctl helpers ---- */
-+
-+int hci_dev_open(__u16 dev)
-+{
-+ struct hci_dev *hdev;
-+ int ret = 0;
-+
-+ if (!(hdev = hci_dev_get(dev)))
-+ return -ENODEV;
-+
-+ BT_DBG("%s %p", hdev->name, hdev);
-+
-+ hci_req_lock(hdev);
-+
-+ if (test_bit(HCI_UP, &hdev->flags)) {
-+ ret = -EALREADY;
-+ goto done;
-+ }
-+
-+ if (hdev->open(hdev)) {
-+ ret = -EIO;
-+ goto done;
-+ }
-+
-+ if (!test_bit(HCI_RAW, &hdev->flags)) {
-+ atomic_set(&hdev->cmd_cnt, 1);
-+ set_bit(HCI_INIT, &hdev->flags);
-+
-+ //__hci_request(hdev, hci_reset_req, 0, HZ);
-+ ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
-+
-+ clear_bit(HCI_INIT, &hdev->flags);
-+ }
-+
-+ if (!ret) {
-+ set_bit(HCI_UP, &hdev->flags);
-+ hci_notify(hdev, HCI_DEV_UP);
-+ } else {
-+ /* Init failed, cleanup */
-+ tasklet_kill(&hdev->rx_task);
-+ tasklet_kill(&hdev->tx_task);
-+ tasklet_kill(&hdev->cmd_task);
-+
-+ skb_queue_purge(&hdev->cmd_q);
-+ skb_queue_purge(&hdev->rx_q);
-+
-+ if (hdev->flush)
-+ hdev->flush(hdev);
-+
-+ if (hdev->sent_cmd) {
-+ kfree_skb(hdev->sent_cmd);
-+ hdev->sent_cmd = NULL;
-+ }
-+
-+ hdev->close(hdev);
-+ hdev->flags = 0;
-+ }
-+
-+done:
-+ hci_req_unlock(hdev);
-+ hci_dev_put(hdev);
-+ return ret;
-+}
-+
-+static int hci_dev_do_close(struct hci_dev *hdev)
-+{
-+ BT_DBG("%s %p", hdev->name, hdev);
-+
-+ hci_req_cancel(hdev, ENODEV);
-+ hci_req_lock(hdev);
-+
-+ if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
-+ hci_req_unlock(hdev);
-+ return 0;
-+ }
-+
-+ /* Kill RX and TX tasks */
-+ tasklet_kill(&hdev->rx_task);
-+ tasklet_kill(&hdev->tx_task);
-+
-+ hci_dev_lock_bh(hdev);
-+ inquiry_cache_flush(hdev);
-+ hci_conn_hash_flush(hdev);
-+ hci_dev_unlock_bh(hdev);
-+
- hci_notify(hdev, HCI_DEV_DOWN);
-
- if (hdev->flush)
-@@ -586,9 +548,9 @@
- /* Reset device */
- skb_queue_purge(&hdev->cmd_q);
- atomic_set(&hdev->cmd_cnt, 1);
-- hdev->flags |= HCI_INIT;
-- __hci_request(hdev, hci_reset_req, 0, HZ);
-- hdev->flags &= ~HCI_INIT;
-+ set_bit(HCI_INIT, &hdev->flags);
-+ __hci_request(hdev, hci_reset_req, 0, HZ/4);
-+ clear_bit(HCI_INIT, &hdev->flags);
-
- /* Kill cmd task */
- tasklet_kill(&hdev->cmd_task);
-@@ -605,17 +567,28 @@
- }
-
- /* After this point our queues are empty
-- * and no tasks are scheduled.
-- */
-+ * and no tasks are scheduled. */
- hdev->close(hdev);
-
--done:
-- hci_req_unlock(hdev);
-- hci_dev_put(hdev);
-+ /* Clear flags */
-+ hdev->flags = 0;
-
-+ hci_req_unlock(hdev);
- return 0;
- }
-
-+int hci_dev_close(__u16 dev)
-+{
-+ struct hci_dev *hdev;
-+ int err;
-+
-+ if (!(hdev = hci_dev_get(dev)))
-+ return -ENODEV;
-+ err = hci_dev_do_close(hdev);
-+ hci_dev_put(hdev);
-+ return err;
-+}
-+
- int hci_dev_reset(__u16 dev)
- {
- struct hci_dev *hdev;
-@@ -627,16 +600,17 @@
- hci_req_lock(hdev);
- tasklet_disable(&hdev->tx_task);
-
-- if (!(hdev->flags & HCI_UP))
-+ if (!test_bit(HCI_UP, &hdev->flags))
- goto done;
-
- /* Drop queues */
- skb_queue_purge(&hdev->rx_q);
- skb_queue_purge(&hdev->cmd_q);
-
-- inquiry_cache_flush(&hdev->inq_cache);
--
-+ hci_dev_lock_bh(hdev);
-+ inquiry_cache_flush(hdev);
- hci_conn_hash_flush(hdev);
-+ hci_dev_unlock_bh(hdev);
-
- if (hdev->flush)
- hdev->flush(hdev);
-@@ -650,7 +624,6 @@
- tasklet_enable(&hdev->tx_task);
- hci_req_unlock(hdev);
- hci_dev_put(hdev);
--
- return ret;
- }
-
-@@ -669,30 +642,11 @@
- return ret;
- }
-
--int hci_dev_setauth(unsigned long arg)
--{
-- struct hci_dev *hdev;
-- struct hci_dev_req dr;
-- int ret = 0;
--
-- if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
-- return -EFAULT;
--
-- if (!(hdev = hci_dev_get(dr.dev_id)))
-- return -ENODEV;
--
-- ret = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
--
-- hci_dev_put(hdev);
--
-- return ret;
--}
--
--int hci_dev_setscan(unsigned long arg)
-+int hci_dev_cmd(unsigned int cmd, unsigned long arg)
- {
- struct hci_dev *hdev;
- struct hci_dev_req dr;
-- int ret = 0;
-+ int err = 0;
-
- if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
- return -EFAULT;
-@@ -700,75 +654,105 @@
- if (!(hdev = hci_dev_get(dr.dev_id)))
- return -ENODEV;
-
-- ret = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
--
-- hci_dev_put(hdev);
-+ switch (cmd) {
-+ case HCISETAUTH:
-+ err = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
-+ break;
-
-- return ret;
--}
-+ case HCISETENCRYPT:
-+ if (!lmp_encrypt_capable(hdev)) {
-+ err = -EOPNOTSUPP;
-+ break;
-+ }
-
--int hci_dev_setptype(unsigned long arg)
--{
-- struct hci_dev *hdev;
-- struct hci_dev_req dr;
-- int ret = 0;
-+ if (!test_bit(HCI_AUTH, &hdev->flags)) {
-+ /* Auth must be enabled first */
-+ err = hci_request(hdev, hci_auth_req,
-+ dr.dev_opt, HCI_INIT_TIMEOUT);
-+ if (err)
-+ break;
-+ }
-+
-+ err = hci_request(hdev, hci_encrypt_req,
-+ dr.dev_opt, HCI_INIT_TIMEOUT);
-+ break;
-+
-+ case HCISETSCAN:
-+ err = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
-+ break;
-+
-+ case HCISETPTYPE:
-+ hdev->pkt_type = (__u16) dr.dev_opt;
-+ break;
-+
-+ case HCISETLINKPOL:
-+ hdev->link_policy = (__u16) dr.dev_opt;
-+ break;
-
-- if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
-- return -EFAULT;
-+ case HCISETLINKMODE:
-+ hdev->link_mode = ((__u16) dr.dev_opt) & (HCI_LM_MASTER | HCI_LM_ACCEPT);
-+ break;
-
-- if (!(hdev = hci_dev_get(dr.dev_id)))
-- return -ENODEV;
-+ case HCISETACLMTU:
-+ hdev->acl_mtu = *((__u16 *)&dr.dev_opt + 1);
-+ hdev->acl_pkts = *((__u16 *)&dr.dev_opt + 0);
-+ break;
-
-- hdev->pkt_type = (__u16) dr.dev_opt;
-+ case HCISETSCOMTU:
-+ hdev->sco_mtu = *((__u16 *)&dr.dev_opt + 1);
-+ hdev->sco_pkts = *((__u16 *)&dr.dev_opt + 0);
-+ break;
-
-+ default:
-+ err = -EINVAL;
-+ break;
-+ }
- hci_dev_put(hdev);
--
-- return ret;
-+ return err;
- }
-
--int hci_dev_list(unsigned long arg)
-+int hci_get_dev_list(unsigned long arg)
- {
- struct hci_dev_list_req *dl;
- struct hci_dev_req *dr;
-- struct hci_dev *hdev;
-- int i, n, size;
-+ struct list_head *p;
-+ int n = 0, size, err;
- __u16 dev_num;
-
- if (get_user(dev_num, (__u16 *) arg))
- return -EFAULT;
-
-- /* Avoid long loop, overflow */
-- if (dev_num > 2048)
-+ if (!dev_num || dev_num > (PAGE_SIZE * 2) / sizeof(*dr))
- return -EINVAL;
--
-- size = dev_num * sizeof(struct hci_dev_req) + sizeof(__u16);
-
-- if (verify_area(VERIFY_WRITE, (void *) arg, size))
-- return -EFAULT;
-+ size = sizeof(*dl) + dev_num * sizeof(*dr);
-
- if (!(dl = kmalloc(size, GFP_KERNEL)))
- return -ENOMEM;
-+
- dr = dl->dev_req;
-
-- spin_lock_bh(&hdev_list_lock);
-- for (i = 0, n = 0; i < HCI_MAX_DEV && n < dev_num; i++) {
-- if ((hdev = hdev_list[i])) {
-- (dr + n)->dev_id = hdev->id;
-- (dr + n)->dev_opt = hdev->flags;
-- n++;
-- }
-+ read_lock_bh(&hdev_list_lock);
-+ list_for_each(p, &hdev_list) {
-+ struct hci_dev *hdev;
-+ hdev = list_entry(p, struct hci_dev, list);
-+ (dr + n)->dev_id = hdev->id;
-+ (dr + n)->dev_opt = hdev->flags;
-+ if (++n >= dev_num)
-+ break;
- }
-- spin_unlock_bh(&hdev_list_lock);
-+ read_unlock_bh(&hdev_list_lock);
-
- dl->dev_num = n;
-- size = n * sizeof(struct hci_dev_req) + sizeof(__u16);
-+ size = sizeof(*dl) + n * sizeof(*dr);
-
-- copy_to_user((void *) arg, dl, size);
-+ err = copy_to_user((void *) arg, dl, size);
-+ kfree(dl);
-
-- return 0;
-+ return err ? -EFAULT : 0;
- }
-
--int hci_dev_info(unsigned long arg)
-+int hci_get_dev_info(unsigned long arg)
- {
- struct hci_dev *hdev;
- struct hci_dev_info di;
-@@ -786,9 +770,11 @@
- di.flags = hdev->flags;
- di.pkt_type = hdev->pkt_type;
- di.acl_mtu = hdev->acl_mtu;
-- di.acl_max = hdev->acl_max;
-+ di.acl_pkts = hdev->acl_pkts;
- di.sco_mtu = hdev->sco_mtu;
-- di.sco_max = hdev->sco_max;
-+ di.sco_pkts = hdev->sco_pkts;
-+ di.link_policy = hdev->link_policy;
-+ di.link_mode = hdev->link_mode;
-
- memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
- memcpy(&di.features, &hdev->features, sizeof(di.features));
-@@ -801,258 +787,168 @@
- return err;
- }
-
--__u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode)
--{
-- __u32 omode = hdev->flags & HCI_MODE_MASK;
--
-- hdev->flags &= ~HCI_MODE_MASK;
-- hdev->flags |= (mode & HCI_MODE_MASK);
-
-- return omode;
--}
-+/* ---- Interface to HCI drivers ---- */
-
--__u32 hci_dev_getmode(struct hci_dev *hdev)
-+/* Register HCI device */
-+int hci_register_dev(struct hci_dev *hdev)
- {
-- return hdev->flags & HCI_MODE_MASK;
--}
-+ struct list_head *head = &hdev_list, *p;
-+ int id = 0;
-
--int hci_conn_list(unsigned long arg)
--{
-- struct hci_conn_list_req req, *cl;
-- struct hci_conn_info *ci;
-- struct hci_dev *hdev;
-- struct list_head *p;
-- int n = 0, size;
-+ BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
-
-- if (copy_from_user(&req, (void *) arg, sizeof(req)))
-- return -EFAULT;
-+ if (!hdev->open || !hdev->close || !hdev->destruct)
-+ return -EINVAL;
-
-- if (!(hdev = hci_dev_get(req.dev_id)))
-- return -ENODEV;
-+ write_lock_bh(&hdev_list_lock);
-
-- /* Set a limit to avoid overlong loops, and also numeric overflow - AC */
-- if(req.conn_num < 2048)
-- return -EINVAL;
-+ /* Find first available device id */
-+ list_for_each(p, &hdev_list) {
-+ if (list_entry(p, struct hci_dev, list)->id != id)
-+ break;
-+ head = p; id++;
-+ }
-
-- size = req.conn_num * sizeof(struct hci_conn_info) + sizeof(req);
-+ sprintf(hdev->name, "hci%d", id);
-+ hdev->id = id;
-+ list_add(&hdev->list, head);
-
-- if (!(cl = kmalloc(size, GFP_KERNEL)))
-- return -ENOMEM;
-- ci = cl->conn_info;
--
-- local_bh_disable();
-- conn_hash_lock(&hdev->conn_hash);
-- list_for_each(p, &hdev->conn_hash.list) {
-- register struct hci_conn *c;
-- c = list_entry(p, struct hci_conn, list);
-+ atomic_set(&hdev->refcnt, 1);
-+ spin_lock_init(&hdev->lock);
-+
-+ hdev->flags = 0;
-+ hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1);
-+ hdev->link_mode = (HCI_LM_ACCEPT);
-
-- (ci + n)->handle = c->handle;
-- bacpy(&(ci + n)->bdaddr, &c->dst);
-- n++;
-- }
-- conn_hash_unlock(&hdev->conn_hash);
-- local_bh_enable();
--
-- cl->dev_id = hdev->id;
-- cl->conn_num = n;
-- size = n * sizeof(struct hci_conn_info) + sizeof(req);
-+ tasklet_init(&hdev->cmd_task, hci_cmd_task,(unsigned long) hdev);
-+ tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
-+ tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
-
-- hci_dev_put(hdev);
-+ skb_queue_head_init(&hdev->rx_q);
-+ skb_queue_head_init(&hdev->cmd_q);
-+ skb_queue_head_init(&hdev->raw_q);
-
-- if(copy_to_user((void *) arg, cl, size))
-- return -EFAULT;
-- return 0;
--}
-+ init_waitqueue_head(&hdev->req_wait_q);
-+ init_MUTEX(&hdev->req_lock);
-
--int hci_inquiry(unsigned long arg)
--{
-- struct inquiry_cache *cache;
-- struct hci_inquiry_req ir;
-- struct hci_dev *hdev;
-- int err = 0, do_inquiry = 0;
-- long timeo;
-- __u8 *buf, *ptr;
-+ inquiry_cache_init(hdev);
-
-- ptr = (void *) arg;
-- if (copy_from_user(&ir, ptr, sizeof(ir)))
-- return -EFAULT;
-+ conn_hash_init(hdev);
-
-- if (!(hdev = hci_dev_get(ir.dev_id)))
-- return -ENODEV;
-+ memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
-
-- cache = &hdev->inq_cache;
-+ atomic_set(&hdev->promisc, 0);
-
-- inquiry_cache_lock(cache);
-- if (inquiry_cache_age(cache) > INQUIRY_CACHE_AGE_MAX || ir.flags & IREQ_CACHE_FLUSH) {
-- inquiry_cache_flush(cache);
-- do_inquiry = 1;
-- }
-- inquiry_cache_unlock(cache);
-+ MOD_INC_USE_COUNT;
-
-- /* Limit inquiry time, also avoid overflows */
-+ write_unlock_bh(&hdev_list_lock);
-
-- if(ir.length > 2048 || ir.num_rsp > 2048)
-- {
-- err = -EINVAL;
-- goto done;
-- }
-+ hci_notify(hdev, HCI_DEV_REG);
-+ hci_run_hotplug(hdev->name, "register");
-
-- timeo = ir.length * 2 * HZ;
-- if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
-- goto done;
-+ return id;
-+}
-
-- /* cache_dump can't sleep. Therefore we allocate temp buffer and then
-- * copy it to the user space.
-- */
-- if (!(buf = kmalloc(sizeof(inquiry_info) * ir.num_rsp, GFP_KERNEL))) {
-- err = -ENOMEM;
-- goto done;
-- }
-- ir.num_rsp = inquiry_cache_dump(cache, ir.num_rsp, buf);
-+/* Unregister HCI device */
-+int hci_unregister_dev(struct hci_dev *hdev)
-+{
-+ BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
-
-- DBG("num_rsp %d", ir.num_rsp);
-+ write_lock_bh(&hdev_list_lock);
-+ list_del(&hdev->list);
-+ write_unlock_bh(&hdev_list_lock);
-
-- if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) + (sizeof(inquiry_info) * ir.num_rsp))) {
-- copy_to_user(ptr, &ir, sizeof(ir));
-- ptr += sizeof(ir);
-- copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
-- } else
-- err = -EFAULT;
-+ hci_dev_do_close(hdev);
-
-- kfree(buf);
-+ hci_notify(hdev, HCI_DEV_UNREG);
-+ hci_run_hotplug(hdev->name, "unregister");
-
--done:
- hci_dev_put(hdev);
-
-- return err;
-+ MOD_DEC_USE_COUNT;
-+ return 0;
- }
-
--/* Interface to HCI drivers */
--
--/* Register HCI device */
--int hci_register_dev(struct hci_dev *hdev)
-+/* Suspend HCI device */
-+int hci_suspend_dev(struct hci_dev *hdev)
- {
-- int i;
-+ hci_notify(hdev, HCI_DEV_SUSPEND);
-+ hci_run_hotplug(hdev->name, "suspend");
-+ return 0;
-+}
-
-- DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
-+/* Resume HCI device */
-+int hci_resume_dev(struct hci_dev *hdev)
-+{
-+ hci_notify(hdev, HCI_DEV_RESUME);
-+ hci_run_hotplug(hdev->name, "resume");
-+ return 0;
-+}
-
-- /* Find free slot */
-- spin_lock_bh(&hdev_list_lock);
-- for (i = 0; i < HCI_MAX_DEV; i++) {
-- if (!hdev_list[i]) {
-- hdev_list[i] = hdev;
--
-- sprintf(hdev->name, "hci%d", i);
-- atomic_set(&hdev->refcnt, 0);
-- hdev->id = i;
-- hdev->flags = HCI_NORMAL;
--
-- hdev->pkt_type = (HCI_DM1 | HCI_DH1);
--
-- tasklet_init(&hdev->cmd_task, hci_cmd_task, (unsigned long) hdev);
-- tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
-- tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
--
-- skb_queue_head_init(&hdev->rx_q);
-- skb_queue_head_init(&hdev->cmd_q);
-- skb_queue_head_init(&hdev->raw_q);
--
-- init_waitqueue_head(&hdev->req_wait_q);
-- init_MUTEX(&hdev->req_lock);
--
-- inquiry_cache_init(&hdev->inq_cache);
--
-- conn_hash_init(&hdev->conn_hash);
--
-- memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
--
-- hci_notify(hdev, HCI_DEV_REG);
--
-- MOD_INC_USE_COUNT;
-- break;
-- }
-- }
-- spin_unlock_bh(&hdev_list_lock);
--
-- return (i == HCI_MAX_DEV) ? -1 : i;
--}
--
--/* Unregister HCI device */
--int hci_unregister_dev(struct hci_dev *hdev)
-+/* Receive frame from HCI drivers */
-+int hci_recv_frame(struct sk_buff *skb)
- {
-- int i;
--
-- DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
--
-- if (hdev->flags & HCI_UP)
-- hci_dev_close(hdev->id);
-+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-
-- /* Find device slot */
-- spin_lock(&hdev_list_lock);
-- for (i = 0; i < HCI_MAX_DEV; i++) {
-- if (hdev_list[i] == hdev) {
-- hdev_list[i] = NULL;
-- MOD_DEC_USE_COUNT;
-- break;
-- }
-+ if (!hdev || (!test_bit(HCI_UP, &hdev->flags) &&
-+ !test_bit(HCI_INIT, &hdev->flags)) ) {
-+ kfree_skb(skb);
-+ return -1;
- }
-- spin_unlock(&hdev_list_lock);
-
-- hci_notify(hdev, HCI_DEV_UNREG);
--
-- /* Sleep while device is in use */
-- while (atomic_read(&hdev->refcnt)) {
-- int sleep_cnt = 100;
-+ BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-
-- DBG("%s sleeping on lock %d", hdev->name, atomic_read(&hdev->refcnt));
-+ /* Incomming skb */
-+ bluez_cb(skb)->incomming = 1;
-
-- sleep_on_timeout(&hdev->req_wait_q, HZ*10);
-- if (!(--sleep_cnt))
-- break;
-- }
-+ /* Time stamp */
-+ do_gettimeofday(&skb->stamp);
-
-+ /* Queue frame for rx task */
-+ skb_queue_tail(&hdev->rx_q, skb);
-+ hci_sched_rx(hdev);
- return 0;
- }
-
--/* Interface to upper protocols */
-+/* ---- Interface to upper protocols ---- */
-
- /* Register/Unregister protocols.
-- * hci_task_lock is used to ensure that no tasks are running.
-- */
--int hci_register_proto(struct hci_proto *hproto)
-+ * hci_task_lock is used to ensure that no tasks are running. */
-+int hci_register_proto(struct hci_proto *hp)
- {
- int err = 0;
-
-- DBG("%p name %s", hproto, hproto->name);
-+ BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
-
-- if (hproto->id >= HCI_MAX_PROTO)
-+ if (hp->id >= HCI_MAX_PROTO)
- return -EINVAL;
-
- write_lock_bh(&hci_task_lock);
-
-- if (!hproto_list[hproto->id])
-- hproto_list[hproto->id] = hproto;
-+ if (!hci_proto[hp->id])
-+ hci_proto[hp->id] = hp;
- else
-- err = -1;
-+ err = -EEXIST;
-
- write_unlock_bh(&hci_task_lock);
-
- return err;
- }
-
--int hci_unregister_proto(struct hci_proto *hproto)
-+int hci_unregister_proto(struct hci_proto *hp)
- {
- int err = 0;
-
-- DBG("%p name %s", hproto, hproto->name);
-+ BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
-
-- if (hproto->id > HCI_MAX_PROTO)
-+ if (hp->id >= HCI_MAX_PROTO)
- return -EINVAL;
-
- write_lock_bh(&hci_task_lock);
-
-- if (hproto_list[hproto->id])
-- hproto_list[hproto->id] = NULL;
-+ if (hci_proto[hp->id])
-+ hci_proto[hp->id] = NULL;
- else
- err = -ENOENT;
-
-@@ -1070,10 +966,14 @@
- return -ENODEV;
- }
-
-- DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-+ BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-+
-+ if (atomic_read(&hdev->promisc)) {
-+ /* Time stamp */
-+ do_gettimeofday(&skb->stamp);
-
-- if (hdev->flags & HCI_SOCK)
- hci_send_to_sock(hdev, skb);
-+ }
-
- /* Get rid of skb owner, prior to sending to the driver. */
- skb_orphan(skb);
-@@ -1081,128 +981,6 @@
- return hdev->send(skb);
- }
-
--/* Connection scheduler */
--static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
--{
-- struct conn_hash *h = &hdev->conn_hash;
-- struct hci_conn *conn = NULL;
-- int num = 0, min = 0xffff;
-- struct list_head *p;
--
-- conn_hash_lock(h);
-- list_for_each(p, &h->list) {
-- register struct hci_conn *c;
--
-- c = list_entry(p, struct hci_conn, list);
--
-- if (c->type != type || skb_queue_empty(&c->data_q))
-- continue;
-- num++;
--
-- if (c->sent < min) {
-- min = c->sent;
-- conn = c;
-- }
-- }
-- conn_hash_unlock(h);
--
-- if (conn) {
-- int q = hdev->acl_cnt / num;
-- *quote = q ? q : 1;
-- } else
-- *quote = 0;
--
-- DBG("conn %p quote %d", conn, *quote);
--
-- return conn;
--}
--
--static inline void hci_sched_acl(struct hci_dev *hdev)
--{
-- struct hci_conn *conn;
-- struct sk_buff *skb;
-- int quote;
--
-- DBG("%s", hdev->name);
--
-- while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, &quote))) {
-- while (quote && (skb = skb_dequeue(&conn->data_q))) {
-- DBG("skb %p len %d", skb, skb->len);
--
-- hci_send_frame(skb);
--
-- conn->sent++;
-- hdev->acl_cnt--;
-- quote--;
-- }
-- }
--}
--
--/* Schedule SCO */
--static inline void hci_sched_sco(struct hci_dev *hdev)
--{
-- /* FIXME: For now we queue SCO packets to the raw queue
--
-- while (hdev->sco_cnt && (skb = skb_dequeue(&conn->data_q))) {
-- hci_send_frame(skb);
-- conn->sco_sent++;
-- hdev->sco_cnt--;
-- }
-- */
--}
--
--/* Get data from the previously sent command */
--static void * hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
--{
-- hci_command_hdr *hc;
--
-- if (!hdev->sent_cmd)
-- return NULL;
--
-- hc = (void *) hdev->sent_cmd->data;
--
-- if (hc->opcode != __cpu_to_le16(cmd_opcode_pack(ogf, ocf)))
-- return NULL;
--
-- DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
--
-- return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
--}
--
--/* Send raw HCI frame */
--int hci_send_raw(struct sk_buff *skb)
--{
-- struct hci_dev *hdev = (struct hci_dev *) skb->dev;
--
-- if (!hdev) {
-- kfree_skb(skb);
-- return -ENODEV;
-- }
--
-- DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
--
-- if (hdev->flags & HCI_NORMAL) {
-- /* Queue frame according it's type */
-- switch (skb->pkt_type) {
-- case HCI_COMMAND_PKT:
-- skb_queue_tail(&hdev->cmd_q, skb);
-- hci_sched_cmd(hdev);
-- return 0;
--
-- case HCI_ACLDATA_PKT:
-- case HCI_SCODATA_PKT:
-- /* FIXME:
-- * Check header here and queue to apropriate connection.
-- */
-- break;
-- }
-- }
--
-- skb_queue_tail(&hdev->raw_q, skb);
-- hci_sched_tx(hdev);
-- return 0;
--}
--
- /* Send HCI command */
- int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param)
- {
-@@ -1210,10 +988,10 @@
- hci_command_hdr *hc;
- struct sk_buff *skb;
-
-- DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
-+ BT_DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
-
- if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {
-- ERR("%s Can't allocate memory for HCI command", hdev->name);
-+ BT_ERR("%s Can't allocate memory for HCI command", hdev->name);
- return -ENOMEM;
- }
-
-@@ -1224,7 +1002,7 @@
- if (plen)
- memcpy(skb_put(skb, plen), param, plen);
-
-- DBG("skb len %d", skb->len);
-+ BT_DBG("skb len %d", skb->len);
-
- skb->pkt_type = HCI_COMMAND_PKT;
- skb->dev = (void *) hdev;
-@@ -1234,10 +1012,28 @@
- return 0;
- }
-
-+/* Get data from the previously sent command */
-+void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
-+{
-+ hci_command_hdr *hc;
-+
-+ if (!hdev->sent_cmd)
-+ return NULL;
-+
-+ hc = (void *) hdev->sent_cmd->data;
-+
-+ if (hc->opcode != __cpu_to_le16(cmd_opcode_pack(ogf, ocf)))
-+ return NULL;
-+
-+ BT_DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
-+
-+ return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
-+}
-+
- /* Send ACL data */
- static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
- {
-- int len = skb->len;
-+ int len = skb->len;
- hci_acl_hdr *ah;
-
- ah = (hci_acl_hdr *) skb_push(skb, HCI_ACL_HDR_SIZE);
-@@ -1252,7 +1048,7 @@
- struct hci_dev *hdev = conn->hdev;
- struct sk_buff *list;
-
-- DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
-+ BT_DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
-
- skb->dev = (void *) hdev;
- skb->pkt_type = HCI_ACLDATA_PKT;
-@@ -1260,12 +1056,12 @@
-
- if (!(list = skb_shinfo(skb)->frag_list)) {
- /* Non fragmented */
-- DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
-+ BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
-
- skb_queue_tail(&conn->data_q, skb);
- } else {
- /* Fragmented */
-- DBG("%s frag %p len %d", hdev->name, skb, skb->len);
-+ BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
-
- skb_shinfo(skb)->frag_list = NULL;
-
-@@ -1280,7 +1076,7 @@
- skb->pkt_type = HCI_ACLDATA_PKT;
- hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT);
-
-- DBG("%s frag %p len %d", hdev->name, skb, skb->len);
-+ BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
-
- __skb_queue_tail(&conn->data_q, skb);
- } while (list);
-@@ -1298,7 +1094,7 @@
- struct hci_dev *hdev = conn->hdev;
- hci_sco_hdr hs;
-
-- DBG("%s len %d", hdev->name, skb->len);
-+ BT_DBG("%s len %d", hdev->name, skb->len);
-
- if (skb->len > hdev->sco_mtu) {
- kfree_skb(skb);
-@@ -1315,544 +1111,136 @@
- skb->pkt_type = HCI_SCODATA_PKT;
- skb_queue_tail(&conn->data_q, skb);
- hci_sched_tx(hdev);
--
- return 0;
- }
-
--/* Handle HCI Event packets */
--
--/* Command Complete OGF LINK_CTL */
--static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
--{
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Complete OGF LINK_POLICY */
--static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
--{
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s: Command complete: ogf LINK_POLICY ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Complete OGF HOST_CTL */
--static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
--{
-- __u8 status, param;
-- void *sent;
--
--
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- case OCF_RESET:
-- status = *((__u8 *) skb->data);
--
-- hci_req_complete(hdev, status);
-- break;
--
-- case OCF_SET_EVENT_FLT:
-- status = *((__u8 *) skb->data);
--
-- if (status) {
-- DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
-- } else {
-- DBG("%s SET_EVENT_FLT succeseful", hdev->name);
-- }
-- break;
--
-- case OCF_WRITE_AUTH_ENABLE:
-- if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE)))
-- break;
--
-- status = *((__u8 *) skb->data);
-- param = *((__u8 *) sent);
--
-- if (!status) {
-- if (param == AUTH_ENABLED)
-- hdev->flags |= HCI_AUTH;
-- else
-- hdev->flags &= ~HCI_AUTH;
-- }
-- hci_req_complete(hdev, status);
-- break;
--
-- case OCF_WRITE_CA_TIMEOUT:
-- status = *((__u8 *) skb->data);
--
-- if (status) {
-- DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
-- } else {
-- DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
-- }
-- break;
--
-- case OCF_WRITE_PG_TIMEOUT:
-- status = *((__u8 *) skb->data);
--
-- if (status) {
-- DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
-- } else {
-- DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
-- }
-- break;
--
-- case OCF_WRITE_SCAN_ENABLE:
-- if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE)))
-- break;
-- status = *((__u8 *) skb->data);
-- param = *((__u8 *) sent);
--
-- DBG("param 0x%x", param);
--
-- if (!status) {
-- switch (param) {
-- case IS_ENA_PS_ENA:
-- hdev->flags |= HCI_PSCAN | HCI_ISCAN;
-- break;
--
-- case IS_ENA_PS_DIS:
-- hdev->flags &= ~HCI_PSCAN;
-- hdev->flags |= HCI_ISCAN;
-- break;
-+/* ---- HCI TX task (outgoing data) ---- */
-
-- case IS_DIS_PS_ENA:
-- hdev->flags &= ~HCI_ISCAN;
-- hdev->flags |= HCI_PSCAN;
-- break;
--
-- default:
-- hdev->flags &= ~(HCI_ISCAN | HCI_PSCAN);
-- break;
-- };
-- }
-- hci_req_complete(hdev, status);
-- break;
--
-- default:
-- DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Complete OGF INFO_PARAM */
--static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+/* HCI Connection scheduler */
-+static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
- {
-- read_local_features_rp *lf;
-- read_buffer_size_rp *bs;
-- read_bd_addr_rp *ba;
--
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- case OCF_READ_LOCAL_FEATURES:
-- lf = (read_local_features_rp *) skb->data;
--
-- if (lf->status) {
-- DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
-- break;
-- }
--
-- memcpy(hdev->features, lf->features, sizeof(hdev->features));
--
-- /* Adjust default settings according to features
-- * supported by device. */
-- if (hdev->features[0] & LMP_3SLOT)
-- hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
--
-- if (hdev->features[0] & LMP_5SLOT)
-- hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
--
-- DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
--
-- break;
--
-- case OCF_READ_BUFFER_SIZE:
-- bs = (read_buffer_size_rp *) skb->data;
--
-- if (bs->status) {
-- DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
-- break;
-- }
--
-- hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
-- hdev->sco_mtu = bs->sco_mtu;
-- hdev->acl_max = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
-- hdev->sco_max = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
--
-- DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
-- hdev->acl_mtu, hdev->sco_mtu, hdev->acl_max, hdev->sco_max);
-+ struct conn_hash *h = &hdev->conn_hash;
-+ struct hci_conn *conn = NULL;
-+ int num = 0, min = ~0;
-+ struct list_head *p;
-
-- break;
-+ /* We don't have to lock device here. Connections are always
-+ * added and removed with TX task disabled. */
-+ list_for_each(p, &h->list) {
-+ struct hci_conn *c;
-+ c = list_entry(p, struct hci_conn, list);
-
-- case OCF_READ_BD_ADDR:
-- ba = (read_bd_addr_rp *) skb->data;
-+ if (c->type != type || c->state != BT_CONNECTED
-+ || skb_queue_empty(&c->data_q))
-+ continue;
-+ num++;
-
-- if (!ba->status) {
-- bacpy(&hdev->bdaddr, &ba->bdaddr);
-- } else {
-- DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
-+ if (c->sent < min) {
-+ min = c->sent;
-+ conn = c;
- }
-+ }
-
-- hci_req_complete(hdev, ba->status);
-- break;
-+ if (conn) {
-+ int cnt = (type == ACL_LINK ? hdev->acl_cnt : hdev->sco_cnt);
-+ int q = cnt / num;
-+ *quote = q ? q : 1;
-+ } else
-+ *quote = 0;
-
-- default:
-- DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-- break;
-- };
-+ BT_DBG("conn %p quote %d", conn, *quote);
-+ return conn;
- }
-
--/* Command Status OGF LINK_CTL */
--static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+static inline void hci_acl_tx_to(struct hci_dev *hdev)
- {
-- struct hci_proto * hp;
--
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- case OCF_CREATE_CONN:
-- if (status) {
-- create_conn_cp *cc = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
--
-- if (!cc)
-- break;
--
-- DBG("%s Create connection error: status 0x%x %s", hdev->name,
-- status, batostr(&cc->bdaddr));
-+ struct conn_hash *h = &hdev->conn_hash;
-+ struct list_head *p;
-+ struct hci_conn *c;
-
-- /* Notify upper protocols */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm) {
-- tasklet_disable(&hdev->tx_task);
-- hp->connect_cfm(hdev, &cc->bdaddr, status, NULL);
-- tasklet_enable(&hdev->tx_task);
-- }
-- }
-- break;
-+ BT_ERR("%s ACL tx timeout", hdev->name);
-
-- case OCF_INQUIRY:
-- if (status) {
-- DBG("%s Inquiry error: status 0x%x", hdev->name, status);
-- hci_req_complete(hdev, status);
-+ /* Kill stalled connections */
-+ list_for_each(p, &h->list) {
-+ c = list_entry(p, struct hci_conn, list);
-+ if (c->type == ACL_LINK && c->sent) {
-+ BT_ERR("%s killing stalled ACL connection %s",
-+ hdev->name, batostr(&c->dst));
-+ hci_acl_disconn(c, 0x13);
- }
-- break;
--
-- default:
-- DBG("%s Command status: ogf LINK_CTL ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Status OGF LINK_POLICY */
--static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
--{
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Status OGF HOST_CTL */
--static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
--{
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Status OGF INFO_PARAM */
--static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
--{
-- DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Inquiry Complete */
--static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
--{
-- __u8 status = *((__u8 *) skb->data);
--
-- DBG("%s status %d", hdev->name, status);
--
-- hci_req_complete(hdev, status);
-+ }
- }
-
--/* Inquiry Result */
--static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+static inline void hci_sched_acl(struct hci_dev *hdev)
- {
-- inquiry_info *info = (inquiry_info *) (skb->data + 1);
-- int num_rsp = *((__u8 *) skb->data);
--
-- DBG("%s num_rsp %d", hdev->name, num_rsp);
-+ struct hci_conn *conn;
-+ struct sk_buff *skb;
-+ int quote;
-
-- for (; num_rsp; num_rsp--)
-- inquiry_cache_update(&hdev->inq_cache, info++);
--}
-+ BT_DBG("%s", hdev->name);
-
--/* Connect Request */
--static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
--{
-- evt_conn_request *cr = (evt_conn_request *) skb->data;
-- struct hci_proto *hp;
-- accept_conn_req_cp ac;
-- int accept = 0;
-+ /* ACL tx timeout must be longer than maximum
-+ * link supervision timeout (40.9 seconds) */
-+ if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45))
-+ hci_acl_tx_to(hdev);
-
-- DBG("%s Connection request: %s type 0x%x", hdev->name, batostr(&cr->bdaddr), cr->link_type);
-+ while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, &quote))) {
-+ while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
-+ BT_DBG("skb %p len %d", skb, skb->len);
-+ hci_send_frame(skb);
-+ hdev->acl_last_tx = jiffies;
-
-- /* Notify upper protocols */
-- if (cr->link_type == ACL_LINK) {
-- /* ACL link notify L2CAP */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_ind) {
-- tasklet_disable(&hdev->tx_task);
-- accept = hp->connect_ind(hdev, &cr->bdaddr);
-- tasklet_enable(&hdev->tx_task);
-+ hdev->acl_cnt--;
-+ conn->sent++;
- }
-- } else {
-- /* SCO link (no notification) */
-- /* FIXME: Should be accept it here or let the requester (app) accept it ? */
-- accept = 1;
-- }
--
-- if (accept) {
-- /* Connection accepted by upper layer */
-- bacpy(&ac.bdaddr, &cr->bdaddr);
-- ac.role = 0x01; /* Remain slave */
-- hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, ACCEPT_CONN_REQ_CP_SIZE, &ac);
-- } else {
-- /* Connection rejected by upper layer */
-- /* FIXME:
-- * Should we use HCI reject here ?
-- */
-- return;
- }
- }
-
--/* Connect Complete */
--static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+/* Schedule SCO */
-+static inline void hci_sched_sco(struct hci_dev *hdev)
- {
-- evt_conn_complete *cc = (evt_conn_complete *) skb->data;
-- struct hci_conn *conn = NULL;
-- struct hci_proto *hp;
--
-- DBG("%s", hdev->name);
--
-- tasklet_disable(&hdev->tx_task);
--
-- if (!cc->status)
-- conn = hci_conn_add(hdev, __le16_to_cpu(cc->handle), cc->link_type, &cc->bdaddr);
-+ struct hci_conn *conn;
-+ struct sk_buff *skb;
-+ int quote;
-
-- /* Notify upper protocols */
-- if (cc->link_type == ACL_LINK) {
-- /* ACL link notify L2CAP layer */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm)
-- hp->connect_cfm(hdev, &cc->bdaddr, cc->status, conn);
-- } else {
-- /* SCO link (no notification) */
-- }
-+ BT_DBG("%s", hdev->name);
-
-- tasklet_enable(&hdev->tx_task);
--}
-+ while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
-+ while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
-+ BT_DBG("skb %p len %d", skb, skb->len);
-+ hci_send_frame(skb);
-
--/* Disconnect Complete */
--static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
--{
-- evt_disconn_complete *dc = (evt_disconn_complete *) skb->data;
-- struct hci_conn *conn = NULL;
-- struct hci_proto *hp;
-- __u16 handle = __le16_to_cpu(dc->handle);
--
-- DBG("%s", hdev->name);
--
-- if (!dc->status && (conn = conn_hash_lookup(&hdev->conn_hash, handle))) {
-- tasklet_disable(&hdev->tx_task);
--
-- /* Notify upper protocols */
-- if (conn->type == ACL_LINK) {
-- /* ACL link notify L2CAP layer */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
-- hp->disconn_ind(conn, dc->reason);
-- } else {
-- /* SCO link (no notification) */
-+ conn->sent++;
-+ if (conn->sent == ~0)
-+ conn->sent = 0;
- }
--
-- hci_conn_del(hdev, conn);
--
-- tasklet_enable(&hdev->tx_task);
- }
- }
-
--/* Number of completed packets */
--static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+static void hci_tx_task(unsigned long arg)
- {
-- evt_num_comp_pkts *nc = (evt_num_comp_pkts *) skb->data;
-- __u16 *ptr;
-- int i;
--
-- skb_pull(skb, EVT_NUM_COMP_PKTS_SIZE);
--
-- DBG("%s num_hndl %d", hdev->name, nc->num_hndl);
-+ struct hci_dev *hdev = (struct hci_dev *) arg;
-+ struct sk_buff *skb;
-
-- if (skb->len < nc->num_hndl * 4) {
-- DBG("%s bad parameters", hdev->name);
-- return;
-- }
-+ read_lock(&hci_task_lock);
-
-- tasklet_disable(&hdev->tx_task);
-+ BT_DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
-
-- for (i = 0, ptr = (__u16 *) skb->data; i < nc->num_hndl; i++) {
-- struct hci_conn *conn;
-- __u16 handle, count;
-+ /* Schedule queues and send stuff to HCI driver */
-
-- handle = __le16_to_cpu(get_unaligned(ptr++));
-- count = __le16_to_cpu(get_unaligned(ptr++));
-+ hci_sched_acl(hdev);
-
-- hdev->acl_cnt += count;
-+ hci_sched_sco(hdev);
-
-- if ((conn = conn_hash_lookup(&hdev->conn_hash, handle)))
-- conn->sent -= count;
-- }
-+ /* Send next queued raw (unknown type) packet */
-+ while ((skb = skb_dequeue(&hdev->raw_q)))
-+ hci_send_frame(skb);
-
-- tasklet_enable(&hdev->tx_task);
--
-- hci_sched_tx(hdev);
-+ read_unlock(&hci_task_lock);
- }
-
--static inline void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
--{
-- hci_event_hdr *he = (hci_event_hdr *) skb->data;
-- evt_cmd_status *cs;
-- evt_cmd_complete *ec;
-- __u16 opcode, ocf, ogf;
--
-- skb_pull(skb, HCI_EVENT_HDR_SIZE);
--
-- DBG("%s evt 0x%x", hdev->name, he->evt);
--
-- switch (he->evt) {
-- case EVT_NUM_COMP_PKTS:
-- hci_num_comp_pkts_evt(hdev, skb);
-- break;
--
-- case EVT_INQUIRY_COMPLETE:
-- hci_inquiry_complete_evt(hdev, skb);
-- break;
-
-- case EVT_INQUIRY_RESULT:
-- hci_inquiry_result_evt(hdev, skb);
-- break;
--
-- case EVT_CONN_REQUEST:
-- hci_conn_request_evt(hdev, skb);
-- break;
--
-- case EVT_CONN_COMPLETE:
-- hci_conn_complete_evt(hdev, skb);
-- break;
--
-- case EVT_DISCONN_COMPLETE:
-- hci_disconn_complete_evt(hdev, skb);
-- break;
--
-- case EVT_CMD_STATUS:
-- cs = (evt_cmd_status *) skb->data;
-- skb_pull(skb, EVT_CMD_STATUS_SIZE);
--
-- opcode = __le16_to_cpu(cs->opcode);
-- ogf = cmd_opcode_ogf(opcode);
-- ocf = cmd_opcode_ocf(opcode);
--
-- switch (ogf) {
-- case OGF_INFO_PARAM:
-- hci_cs_info_param(hdev, ocf, cs->status);
-- break;
--
-- case OGF_HOST_CTL:
-- hci_cs_host_ctl(hdev, ocf, cs->status);
-- break;
--
-- case OGF_LINK_CTL:
-- hci_cs_link_ctl(hdev, ocf, cs->status);
-- break;
--
-- case OGF_LINK_POLICY:
-- hci_cs_link_policy(hdev, ocf, cs->status);
-- break;
--
-- default:
-- DBG("%s Command Status OGF %x", hdev->name, ogf);
-- break;
-- };
--
-- if (cs->ncmd) {
-- atomic_set(&hdev->cmd_cnt, 1);
-- if (!skb_queue_empty(&hdev->cmd_q))
-- hci_sched_cmd(hdev);
-- }
-- break;
--
-- case EVT_CMD_COMPLETE:
-- ec = (evt_cmd_complete *) skb->data;
-- skb_pull(skb, EVT_CMD_COMPLETE_SIZE);
--
-- opcode = __le16_to_cpu(ec->opcode);
-- ogf = cmd_opcode_ogf(opcode);
-- ocf = cmd_opcode_ocf(opcode);
--
-- switch (ogf) {
-- case OGF_INFO_PARAM:
-- hci_cc_info_param(hdev, ocf, skb);
-- break;
--
-- case OGF_HOST_CTL:
-- hci_cc_host_ctl(hdev, ocf, skb);
-- break;
--
-- case OGF_LINK_CTL:
-- hci_cc_link_ctl(hdev, ocf, skb);
-- break;
--
-- case OGF_LINK_POLICY:
-- hci_cc_link_policy(hdev, ocf, skb);
-- break;
--
-- default:
-- DBG("%s Command Completed OGF %x", hdev->name, ogf);
-- break;
-- };
--
-- if (ec->ncmd) {
-- atomic_set(&hdev->cmd_cnt, 1);
-- if (!skb_queue_empty(&hdev->cmd_q))
-- hci_sched_cmd(hdev);
-- }
-- break;
-- };
--
-- kfree_skb(skb);
-- hdev->stat.evt_rx++;
--}
-+/* ----- HCI RX task (incomming data proccessing) ----- */
-
- /* ACL data packet */
- static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
-@@ -1867,51 +1255,86 @@
- flags = acl_flags(handle);
- handle = acl_handle(handle);
-
-- DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
-+ BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
-+
-+ hdev->stat.acl_rx++;
-
-- if ((conn = conn_hash_lookup(&hdev->conn_hash, handle))) {
-+ hci_dev_lock(hdev);
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ hci_dev_unlock(hdev);
-+
-+ if (conn) {
- register struct hci_proto *hp;
-
- /* Send to upper protocol */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->recv_acldata) {
-+ if ((hp = hci_proto[HCI_PROTO_L2CAP]) && hp->recv_acldata) {
- hp->recv_acldata(conn, skb, flags);
-- goto sent;
-+ return;
- }
- } else {
-- ERR("%s ACL packet for unknown connection handle %d", hdev->name, handle);
-+ BT_ERR("%s ACL packet for unknown connection handle %d",
-+ hdev->name, handle);
- }
-
- kfree_skb(skb);
--sent:
-- hdev->stat.acl_rx++;
- }
-
- /* SCO data packet */
- static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
- {
-- DBG("%s len %d", hdev->name, skb->len);
-+ hci_sco_hdr *sh = (void *) skb->data;
-+ struct hci_conn *conn;
-+ __u16 handle;
-+
-+ skb_pull(skb, HCI_SCO_HDR_SIZE);
-+
-+ handle = __le16_to_cpu(sh->handle);
-+
-+ BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
-
-- kfree_skb(skb);
- hdev->stat.sco_rx++;
-+
-+ hci_dev_lock(hdev);
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ hci_dev_unlock(hdev);
-+
-+ if (conn) {
-+ register struct hci_proto *hp;
-+
-+ /* Send to upper protocol */
-+ if ((hp = hci_proto[HCI_PROTO_SCO]) && hp->recv_scodata) {
-+ hp->recv_scodata(conn, skb);
-+ return;
-+ }
-+ } else {
-+ BT_ERR("%s SCO packet for unknown connection handle %d",
-+ hdev->name, handle);
-+ }
-+
-+ kfree_skb(skb);
- }
-
--/* ----- HCI tasks ----- */
- void hci_rx_task(unsigned long arg)
- {
- struct hci_dev *hdev = (struct hci_dev *) arg;
- struct sk_buff *skb;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s", hdev->name);
-
- read_lock(&hci_task_lock);
-
- while ((skb = skb_dequeue(&hdev->rx_q))) {
-- if (hdev->flags & HCI_SOCK) {
-+ if (atomic_read(&hdev->promisc)) {
- /* Send copy to the sockets */
- hci_send_to_sock(hdev, skb);
- }
-
-- if (hdev->flags & HCI_INIT) {
-+ if (test_bit(HCI_RAW, &hdev->flags)) {
-+ kfree_skb(skb);
-+ continue;
-+ }
-+
-+ if (test_bit(HCI_INIT, &hdev->flags)) {
- /* Don't process data packets in this states. */
- switch (skb->pkt_type) {
- case HCI_ACLDATA_PKT:
-@@ -1921,64 +1344,43 @@
- };
- }
-
-- if (hdev->flags & HCI_NORMAL) {
-- /* Process frame */
-- switch (skb->pkt_type) {
-- case HCI_EVENT_PKT:
-- hci_event_packet(hdev, skb);
-- break;
-+ /* Process frame */
-+ switch (skb->pkt_type) {
-+ case HCI_EVENT_PKT:
-+ hci_event_packet(hdev, skb);
-+ break;
-
-- case HCI_ACLDATA_PKT:
-- DBG("%s ACL data packet", hdev->name);
-- hci_acldata_packet(hdev, skb);
-- break;
-+ case HCI_ACLDATA_PKT:
-+ BT_DBG("%s ACL data packet", hdev->name);
-+ hci_acldata_packet(hdev, skb);
-+ break;
-
-- case HCI_SCODATA_PKT:
-- DBG("%s SCO data packet", hdev->name);
-- hci_scodata_packet(hdev, skb);
-- break;
-+ case HCI_SCODATA_PKT:
-+ BT_DBG("%s SCO data packet", hdev->name);
-+ hci_scodata_packet(hdev, skb);
-+ break;
-
-- default:
-- kfree_skb(skb);
-- break;
-- };
-- } else {
-+ default:
- kfree_skb(skb);
-+ break;
- }
- }
-
- read_unlock(&hci_task_lock);
- }
-
--static void hci_tx_task(unsigned long arg)
--{
-- struct hci_dev *hdev = (struct hci_dev *) arg;
-- struct sk_buff *skb;
--
-- read_lock(&hci_task_lock);
--
-- DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
--
-- /* Schedule queues and send stuff to HCI driver */
--
-- hci_sched_acl(hdev);
--
-- hci_sched_sco(hdev);
--
-- /* Send next queued raw (unknown type) packet */
-- while ((skb = skb_dequeue(&hdev->raw_q)))
-- hci_send_frame(skb);
--
-- read_unlock(&hci_task_lock);
--}
--
- static void hci_cmd_task(unsigned long arg)
- {
- struct hci_dev *hdev = (struct hci_dev *) arg;
- struct sk_buff *skb;
-
-- DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
-+ BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
-
-+ if (!atomic_read(&hdev->cmd_cnt) && (jiffies - hdev->cmd_last_tx) > HZ) {
-+ BT_ERR("%s command tx timeout", hdev->name);
-+ atomic_set(&hdev->cmd_cnt, 1);
-+ }
-+
- /* Send queued commands */
- if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) {
- if (hdev->sent_cmd)
-@@ -1987,6 +1389,7 @@
- if ((hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC))) {
- atomic_dec(&hdev->cmd_cnt);
- hci_send_frame(skb);
-+ hdev->cmd_last_tx = jiffies;
- } else {
- skb_queue_head(&hdev->cmd_q, skb);
- hci_sched_cmd(hdev);
-@@ -1994,33 +1397,10 @@
- }
- }
-
--/* Receive frame from HCI drivers */
--int hci_recv_frame(struct sk_buff *skb)
--{
-- struct hci_dev *hdev = (struct hci_dev *) skb->dev;
--
-- if (!hdev || !(hdev->flags & (HCI_UP | HCI_INIT))) {
-- kfree_skb(skb);
-- return -1;
-- }
--
-- DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
--
-- /* Incomming skb */
-- bluez_cb(skb)->incomming = 1;
--
-- /* Queue frame for rx task */
-- skb_queue_tail(&hdev->rx_q, skb);
-- hci_sched_rx(hdev);
--
-- return 0;
--}
-+/* ---- Initialization ---- */
-
- int hci_core_init(void)
- {
-- /* Init locks */
-- spin_lock_init(&hdev_list_lock);
--
- return 0;
- }
-
-@@ -2028,5 +1408,3 @@
- {
- return 0;
- }
--
--MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/hci_event.c linux-2.4.18-mh15/net/bluetooth/hci_event.c
---- linux-2.4.18/net/bluetooth/hci_event.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/hci_event.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,910 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * HCI Events.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/notifier.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+#ifndef HCI_CORE_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+/* Handle HCI Event packets */
-+
-+/* Command Complete OGF LINK_CTL */
-+static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+{
-+ __u8 status;
-+
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_INQUIRY_CANCEL:
-+ status = *((__u8 *) skb->data);
-+
-+ if (status) {
-+ BT_DBG("%s Inquiry cancel error: status 0x%x", hdev->name, status);
-+ } else {
-+ clear_bit(HCI_INQUIRY, &hdev->flags);
-+ hci_req_complete(hdev, status);
-+ }
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Complete OGF LINK_POLICY */
-+static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+{
-+ struct hci_conn *conn;
-+ role_discovery_rp *rd;
-+
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_ROLE_DISCOVERY:
-+ rd = (void *) skb->data;
-+
-+ if (rd->status)
-+ break;
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_handle(hdev, __le16_to_cpu(rd->handle));
-+ if (conn) {
-+ if (rd->role)
-+ conn->link_mode &= ~HCI_LM_MASTER;
-+ else
-+ conn->link_mode |= HCI_LM_MASTER;
-+ }
-+
-+ hci_dev_unlock(hdev);
-+ break;
-+
-+ default:
-+ BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x",
-+ hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Complete OGF HOST_CTL */
-+static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+{
-+ __u8 status, param;
-+ void *sent;
-+
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_RESET:
-+ status = *((__u8 *) skb->data);
-+ hci_req_complete(hdev, status);
-+ break;
-+
-+ case OCF_SET_EVENT_FLT:
-+ status = *((__u8 *) skb->data);
-+ if (status) {
-+ BT_DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
-+ } else {
-+ BT_DBG("%s SET_EVENT_FLT succeseful", hdev->name);
-+ }
-+ break;
-+
-+ case OCF_WRITE_AUTH_ENABLE:
-+ sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE);
-+ if (!sent)
-+ break;
-+
-+ status = *((__u8 *) skb->data);
-+ param = *((__u8 *) sent);
-+
-+ if (!status) {
-+ if (param == AUTH_ENABLED)
-+ set_bit(HCI_AUTH, &hdev->flags);
-+ else
-+ clear_bit(HCI_AUTH, &hdev->flags);
-+ }
-+ hci_req_complete(hdev, status);
-+ break;
-+
-+ case OCF_WRITE_ENCRYPT_MODE:
-+ sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE);
-+ if (!sent)
-+ break;
-+
-+ status = *((__u8 *) skb->data);
-+ param = *((__u8 *) sent);
-+
-+ if (!status) {
-+ if (param)
-+ set_bit(HCI_ENCRYPT, &hdev->flags);
-+ else
-+ clear_bit(HCI_ENCRYPT, &hdev->flags);
-+ }
-+ hci_req_complete(hdev, status);
-+ break;
-+
-+ case OCF_WRITE_CA_TIMEOUT:
-+ status = *((__u8 *) skb->data);
-+ if (status) {
-+ BT_DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
-+ } else {
-+ BT_DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
-+ }
-+ break;
-+
-+ case OCF_WRITE_PG_TIMEOUT:
-+ status = *((__u8 *) skb->data);
-+ if (status) {
-+ BT_DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
-+ } else {
-+ BT_DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
-+ }
-+ break;
-+
-+ case OCF_WRITE_SCAN_ENABLE:
-+ sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE);
-+ if (!sent)
-+ break;
-+ status = *((__u8 *) skb->data);
-+ param = *((__u8 *) sent);
-+
-+ BT_DBG("param 0x%x", param);
-+
-+ if (!status) {
-+ clear_bit(HCI_PSCAN, &hdev->flags);
-+ clear_bit(HCI_ISCAN, &hdev->flags);
-+ if (param & SCAN_INQUIRY)
-+ set_bit(HCI_ISCAN, &hdev->flags);
-+
-+ if (param & SCAN_PAGE)
-+ set_bit(HCI_PSCAN, &hdev->flags);
-+ }
-+ hci_req_complete(hdev, status);
-+ break;
-+
-+ case OCF_HOST_BUFFER_SIZE:
-+ status = *((__u8 *) skb->data);
-+ if (status) {
-+ BT_DBG("%s OCF_BUFFER_SIZE failed %d", hdev->name, status);
-+ hci_req_complete(hdev, status);
-+ }
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Complete OGF INFO_PARAM */
-+static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+{
-+ read_local_features_rp *lf;
-+ read_buffer_size_rp *bs;
-+ read_bd_addr_rp *ba;
-+
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_READ_LOCAL_FEATURES:
-+ lf = (read_local_features_rp *) skb->data;
-+
-+ if (lf->status) {
-+ BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
-+ break;
-+ }
-+
-+ memcpy(hdev->features, lf->features, sizeof(hdev->features));
-+
-+ /* Adjust default settings according to features
-+ * supported by device. */
-+ if (hdev->features[0] & LMP_3SLOT)
-+ hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
-+
-+ if (hdev->features[0] & LMP_5SLOT)
-+ hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
-+
-+ if (hdev->features[1] & LMP_HV2)
-+ hdev->pkt_type |= (HCI_HV2);
-+
-+ if (hdev->features[1] & LMP_HV3)
-+ hdev->pkt_type |= (HCI_HV3);
-+
-+ BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
-+
-+ break;
-+
-+ case OCF_READ_BUFFER_SIZE:
-+ bs = (read_buffer_size_rp *) skb->data;
-+
-+ if (bs->status) {
-+ BT_DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
-+ hci_req_complete(hdev, bs->status);
-+ break;
-+ }
-+
-+ hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
-+ hdev->sco_mtu = bs->sco_mtu ? bs->sco_mtu : 64;
-+ hdev->acl_pkts = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
-+ hdev->sco_pkts = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
-+
-+ BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
-+ hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
-+ break;
-+
-+ case OCF_READ_BD_ADDR:
-+ ba = (read_bd_addr_rp *) skb->data;
-+
-+ if (!ba->status) {
-+ bacpy(&hdev->bdaddr, &ba->bdaddr);
-+ } else {
-+ BT_DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
-+ }
-+
-+ hci_req_complete(hdev, ba->status);
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Status OGF LINK_CTL */
-+static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
-+{
-+ struct hci_conn *conn;
-+ create_conn_cp *cc = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
-+
-+ if (!cc)
-+ return;
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_ba(hdev, ACL_LINK, &cc->bdaddr);
-+
-+ BT_DBG("%s status 0x%x bdaddr %s conn %p", hdev->name,
-+ status, batostr(&cc->bdaddr), conn);
-+
-+ if (status) {
-+ if (conn && conn->state == BT_CONNECT) {
-+ conn->state = BT_CLOSED;
-+ hci_proto_connect_cfm(conn, status);
-+ hci_conn_del(conn);
-+ }
-+ } else {
-+ if (!conn) {
-+ conn = hci_conn_add(hdev, ACL_LINK, &cc->bdaddr);
-+ if (conn) {
-+ conn->out = 1;
-+ conn->link_mode |= HCI_LM_MASTER;
-+ } else
-+ BT_ERR("No memmory for new connection");
-+ }
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+{
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_CREATE_CONN:
-+ hci_cs_create_conn(hdev, status);
-+ break;
-+
-+ case OCF_ADD_SCO:
-+ if (status) {
-+ struct hci_conn *acl, *sco;
-+ add_sco_cp *cp = hci_sent_cmd_data(hdev,
-+ OGF_LINK_CTL, OCF_ADD_SCO);
-+ __u16 handle;
-+
-+ if (!cp)
-+ break;
-+
-+ handle = __le16_to_cpu(cp->handle);
-+
-+ BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
-+
-+ hci_dev_lock(hdev);
-+
-+ acl = conn_hash_lookup_handle(hdev, handle);
-+ if (acl && (sco = acl->link)) {
-+ sco->state = BT_CLOSED;
-+ hci_proto_connect_cfm(sco, status);
-+ hci_conn_del(sco);
-+ }
-+
-+ hci_dev_unlock(hdev);
-+ }
-+ break;
-+
-+ case OCF_INQUIRY:
-+ if (status) {
-+ BT_DBG("%s Inquiry error: status 0x%x", hdev->name, status);
-+ hci_req_complete(hdev, status);
-+ } else {
-+ set_bit(HCI_INQUIRY, &hdev->flags);
-+ }
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command status: ogf LINK_CTL ocf %x status %d",
-+ hdev->name, ocf, status);
-+ break;
-+ };
-+}
-+
-+/* Command Status OGF LINK_POLICY */
-+static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+{
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ default:
-+ BT_DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Status OGF HOST_CTL */
-+static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+{
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ default:
-+ BT_DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Status OGF INFO_PARAM */
-+static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+{
-+ BT_DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ default:
-+ BT_DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Inquiry Complete */
-+static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ __u8 status = *((__u8 *) skb->data);
-+
-+ BT_DBG("%s status %d", hdev->name, status);
-+
-+ clear_bit(HCI_INQUIRY, &hdev->flags);
-+ hci_req_complete(hdev, status);
-+}
-+
-+/* Inquiry Result */
-+static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ inquiry_info *info = (inquiry_info *) (skb->data + 1);
-+ int num_rsp = *((__u8 *) skb->data);
-+
-+ BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
-+
-+ hci_dev_lock(hdev);
-+ for (; num_rsp; num_rsp--)
-+ inquiry_cache_update(hdev, info++);
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Inquiry Result With RSSI */
-+static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ inquiry_info_with_rssi *info = (inquiry_info_with_rssi *) (skb->data + 1);
-+ int num_rsp = *((__u8 *) skb->data);
-+
-+ BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
-+
-+ hci_dev_lock(hdev);
-+ for (; num_rsp; num_rsp--) {
-+ inquiry_info tmp;
-+ bacpy(&tmp.bdaddr, &info->bdaddr);
-+ tmp.pscan_rep_mode = info->pscan_rep_mode;
-+ tmp.pscan_period_mode = info->pscan_period_mode;
-+ tmp.pscan_mode = 0x00;
-+ memcpy(tmp.dev_class, &info->dev_class, 3);
-+ tmp.clock_offset = info->clock_offset;
-+ info++;
-+ inquiry_cache_update(hdev, &tmp);
-+ }
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Connect Request */
-+static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_conn_request *cr = (evt_conn_request *) skb->data;
-+ int mask = hdev->link_mode;
-+
-+ BT_DBG("%s Connection request: %s type 0x%x", hdev->name,
-+ batostr(&cr->bdaddr), cr->link_type);
-+
-+ mask |= hci_proto_connect_ind(hdev, &cr->bdaddr, cr->link_type);
-+
-+ if (mask & HCI_LM_ACCEPT) {
-+ /* Connection accepted */
-+ struct hci_conn *conn;
-+ accept_conn_req_cp ac;
-+
-+ hci_dev_lock(hdev);
-+ conn = conn_hash_lookup_ba(hdev, cr->link_type, &cr->bdaddr);
-+ if (!conn) {
-+ if (!(conn = hci_conn_add(hdev, cr->link_type, &cr->bdaddr))) {
-+ BT_ERR("No memmory for new connection");
-+ hci_dev_unlock(hdev);
-+ return;
-+ }
-+ }
-+ conn->state = BT_CONNECT;
-+ hci_dev_unlock(hdev);
-+
-+ bacpy(&ac.bdaddr, &cr->bdaddr);
-+
-+ if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
-+ ac.role = 0x00; /* Become master */
-+ else
-+ ac.role = 0x01; /* Remain slave */
-+
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ,
-+ ACCEPT_CONN_REQ_CP_SIZE, &ac);
-+ } else {
-+ /* Connection rejected */
-+ reject_conn_req_cp rc;
-+
-+ bacpy(&rc.bdaddr, &cr->bdaddr);
-+ rc.reason = 0x0f;
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_REJECT_CONN_REQ,
-+ REJECT_CONN_REQ_CP_SIZE, &rc);
-+ }
-+}
-+
-+/* Connect Complete */
-+static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_conn_complete *cc = (evt_conn_complete *) skb->data;
-+ struct hci_conn *conn = NULL;
-+
-+ BT_DBG("%s", hdev->name);
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_ba(hdev, cc->link_type, &cc->bdaddr);
-+ if (!conn) {
-+ hci_dev_unlock(hdev);
-+ return;
-+ }
-+
-+ if (!cc->status) {
-+ conn->handle = __le16_to_cpu(cc->handle);
-+ conn->state = BT_CONNECTED;
-+
-+ if (test_bit(HCI_AUTH, &hdev->flags))
-+ conn->link_mode |= HCI_LM_AUTH;
-+
-+ if (test_bit(HCI_ENCRYPT, &hdev->flags))
-+ conn->link_mode |= HCI_LM_ENCRYPT;
-+
-+
-+ /* Set link policy */
-+ if (conn->type == ACL_LINK && hdev->link_policy) {
-+ write_link_policy_cp lp;
-+ lp.handle = cc->handle;
-+ lp.policy = __cpu_to_le16(hdev->link_policy);
-+ hci_send_cmd(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY,
-+ WRITE_LINK_POLICY_CP_SIZE, &lp);
-+ }
-+
-+ /* Set packet type for incomming connection */
-+ if (!conn->out) {
-+ change_conn_ptype_cp cp;
-+ cp.handle = cc->handle;
-+ cp.pkt_type = (conn->type == ACL_LINK) ?
-+ __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK):
-+ __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
-+
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CHANGE_CONN_PTYPE,
-+ CHANGE_CONN_PTYPE_CP_SIZE, &cp);
-+ }
-+ } else
-+ conn->state = BT_CLOSED;
-+
-+ if (conn->type == ACL_LINK) {
-+ struct hci_conn *sco = conn->link;
-+ if (sco) {
-+ if (!cc->status)
-+ hci_add_sco(sco, conn->handle);
-+ else {
-+ hci_proto_connect_cfm(sco, cc->status);
-+ hci_conn_del(sco);
-+ }
-+ }
-+ }
-+
-+ hci_proto_connect_cfm(conn, cc->status);
-+ if (cc->status)
-+ hci_conn_del(conn);
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Disconnect Complete */
-+static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_disconn_complete *dc = (evt_disconn_complete *) skb->data;
-+ struct hci_conn *conn = NULL;
-+ __u16 handle = __le16_to_cpu(dc->handle);
-+
-+ BT_DBG("%s status %d", hdev->name, dc->status);
-+
-+ if (dc->status)
-+ return;
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ if (conn) {
-+ conn->state = BT_CLOSED;
-+ hci_proto_disconn_ind(conn, dc->reason);
-+ hci_conn_del(conn);
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Number of completed packets */
-+static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_num_comp_pkts *nc = (evt_num_comp_pkts *) skb->data;
-+ __u16 *ptr;
-+ int i;
-+
-+ skb_pull(skb, EVT_NUM_COMP_PKTS_SIZE);
-+
-+ BT_DBG("%s num_hndl %d", hdev->name, nc->num_hndl);
-+
-+ if (skb->len < nc->num_hndl * 4) {
-+ BT_DBG("%s bad parameters", hdev->name);
-+ return;
-+ }
-+
-+ tasklet_disable(&hdev->tx_task);
-+
-+ for (i = 0, ptr = (__u16 *) skb->data; i < nc->num_hndl; i++) {
-+ struct hci_conn *conn;
-+ __u16 handle, count;
-+
-+ handle = __le16_to_cpu(get_unaligned(ptr++));
-+ count = __le16_to_cpu(get_unaligned(ptr++));
-+
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ if (conn) {
-+ conn->sent -= count;
-+
-+ if (conn->type == SCO_LINK) {
-+ if ((hdev->sco_cnt += count) > hdev->sco_pkts)
-+ hdev->sco_cnt = hdev->sco_pkts;
-+ } else {
-+ if ((hdev->acl_cnt += count) > hdev->acl_pkts)
-+ hdev->acl_cnt = hdev->acl_pkts;
-+ }
-+ }
-+ }
-+ hci_sched_tx(hdev);
-+
-+ tasklet_enable(&hdev->tx_task);
-+}
-+
-+/* Role Change */
-+static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_role_change *rc = (evt_role_change *) skb->data;
-+ struct hci_conn *conn = NULL;
-+
-+ BT_DBG("%s status %d", hdev->name, rc->status);
-+
-+ if (rc->status)
-+ return;
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_ba(hdev, ACL_LINK, &rc->bdaddr);
-+ if (conn) {
-+ if (rc->role)
-+ conn->link_mode &= ~HCI_LM_MASTER;
-+ else
-+ conn->link_mode |= HCI_LM_MASTER;
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Authentication Complete */
-+static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_auth_complete *ac = (evt_auth_complete *) skb->data;
-+ struct hci_conn *conn = NULL;
-+ __u16 handle = __le16_to_cpu(ac->handle);
-+
-+ BT_DBG("%s status %d", hdev->name, ac->status);
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ if (conn) {
-+ if (!ac->status)
-+ conn->link_mode |= HCI_LM_AUTH;
-+ clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
-+
-+ hci_proto_auth_cfm(conn, ac->status);
-+
-+ if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
-+ if (!ac->status) {
-+ set_conn_encrypt_cp ce;
-+ ce.handle = __cpu_to_le16(conn->handle);
-+ ce.encrypt = 1;
-+ hci_send_cmd(conn->hdev, OGF_LINK_CTL,
-+ OCF_SET_CONN_ENCRYPT,
-+ SET_CONN_ENCRYPT_CP_SIZE, &ce);
-+ } else {
-+ clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
-+ hci_proto_encrypt_cfm(conn, ac->status);
-+ }
-+ }
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Encryption Change */
-+static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_encrypt_change *ec = (evt_encrypt_change *) skb->data;
-+ struct hci_conn *conn = NULL;
-+ __u16 handle = __le16_to_cpu(ec->handle);
-+
-+ BT_DBG("%s status %d", hdev->name, ec->status);
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ if (conn) {
-+ if (!ec->status) {
-+ if (ec->encrypt)
-+ conn->link_mode |= HCI_LM_ENCRYPT;
-+ else
-+ conn->link_mode &= ~HCI_LM_ENCRYPT;
-+ }
-+ clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
-+
-+ hci_proto_encrypt_cfm(conn, ec->status);
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ hci_event_hdr *he = (hci_event_hdr *) skb->data;
-+ evt_cmd_status *cs;
-+ evt_cmd_complete *ec;
-+ __u16 opcode, ocf, ogf;
-+
-+ skb_pull(skb, HCI_EVENT_HDR_SIZE);
-+
-+ BT_DBG("%s evt 0x%x", hdev->name, he->evt);
-+
-+ switch (he->evt) {
-+ case EVT_NUM_COMP_PKTS:
-+ hci_num_comp_pkts_evt(hdev, skb);
-+ break;
-+
-+ case EVT_INQUIRY_COMPLETE:
-+ hci_inquiry_complete_evt(hdev, skb);
-+ break;
-+
-+ case EVT_INQUIRY_RESULT:
-+ hci_inquiry_result_evt(hdev, skb);
-+ break;
-+
-+ case EVT_INQUIRY_RESULT_WITH_RSSI:
-+ hci_inquiry_result_with_rssi_evt(hdev, skb);
-+ break;
-+
-+ case EVT_CONN_REQUEST:
-+ hci_conn_request_evt(hdev, skb);
-+ break;
-+
-+ case EVT_CONN_COMPLETE:
-+ hci_conn_complete_evt(hdev, skb);
-+ break;
-+
-+ case EVT_DISCONN_COMPLETE:
-+ hci_disconn_complete_evt(hdev, skb);
-+ break;
-+
-+ case EVT_ROLE_CHANGE:
-+ hci_role_change_evt(hdev, skb);
-+ break;
-+
-+ case EVT_AUTH_COMPLETE:
-+ hci_auth_complete_evt(hdev, skb);
-+ break;
-+
-+ case EVT_ENCRYPT_CHANGE:
-+ hci_encrypt_change_evt(hdev, skb);
-+ break;
-+
-+ case EVT_CMD_STATUS:
-+ cs = (evt_cmd_status *) skb->data;
-+ skb_pull(skb, EVT_CMD_STATUS_SIZE);
-+
-+ opcode = __le16_to_cpu(cs->opcode);
-+ ogf = cmd_opcode_ogf(opcode);
-+ ocf = cmd_opcode_ocf(opcode);
-+
-+ switch (ogf) {
-+ case OGF_INFO_PARAM:
-+ hci_cs_info_param(hdev, ocf, cs->status);
-+ break;
-+
-+ case OGF_HOST_CTL:
-+ hci_cs_host_ctl(hdev, ocf, cs->status);
-+ break;
-+
-+ case OGF_LINK_CTL:
-+ hci_cs_link_ctl(hdev, ocf, cs->status);
-+ break;
-+
-+ case OGF_LINK_POLICY:
-+ hci_cs_link_policy(hdev, ocf, cs->status);
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command Status OGF %x", hdev->name, ogf);
-+ break;
-+ };
-+
-+ if (cs->ncmd) {
-+ atomic_set(&hdev->cmd_cnt, 1);
-+ if (!skb_queue_empty(&hdev->cmd_q))
-+ hci_sched_cmd(hdev);
-+ }
-+ break;
-+
-+ case EVT_CMD_COMPLETE:
-+ ec = (evt_cmd_complete *) skb->data;
-+ skb_pull(skb, EVT_CMD_COMPLETE_SIZE);
-+
-+ opcode = __le16_to_cpu(ec->opcode);
-+ ogf = cmd_opcode_ogf(opcode);
-+ ocf = cmd_opcode_ocf(opcode);
-+
-+ switch (ogf) {
-+ case OGF_INFO_PARAM:
-+ hci_cc_info_param(hdev, ocf, skb);
-+ break;
-+
-+ case OGF_HOST_CTL:
-+ hci_cc_host_ctl(hdev, ocf, skb);
-+ break;
-+
-+ case OGF_LINK_CTL:
-+ hci_cc_link_ctl(hdev, ocf, skb);
-+ break;
-+
-+ case OGF_LINK_POLICY:
-+ hci_cc_link_policy(hdev, ocf, skb);
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command Completed OGF %x", hdev->name, ogf);
-+ break;
-+ };
-+
-+ if (ec->ncmd) {
-+ atomic_set(&hdev->cmd_cnt, 1);
-+ if (!skb_queue_empty(&hdev->cmd_q))
-+ hci_sched_cmd(hdev);
-+ }
-+ break;
-+ };
-+
-+ kfree_skb(skb);
-+ hdev->stat.evt_rx++;
-+}
-+
-+/* General internal stack event */
-+void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
-+{
-+ hci_event_hdr *eh;
-+ evt_stack_internal *si;
-+ struct sk_buff *skb;
-+ int size;
-+ void *ptr;
-+
-+ size = HCI_EVENT_HDR_SIZE + EVT_STACK_INTERNAL_SIZE + dlen;
-+ skb = bluez_skb_alloc(size, GFP_ATOMIC);
-+ if (!skb)
-+ return;
-+
-+ ptr = skb_put(skb, size);
-+
-+ eh = ptr;
-+ eh->evt = EVT_STACK_INTERNAL;
-+ eh->plen = EVT_STACK_INTERNAL_SIZE + dlen;
-+ ptr += HCI_EVENT_HDR_SIZE;
-+
-+ si = ptr;
-+ si->type = type;
-+ memcpy(si->data, data, dlen);
-+
-+ skb->pkt_type = HCI_EVENT_PKT;
-+ skb->dev = (void *) hdev;
-+ hci_send_to_sock(hdev, skb);
-+ kfree_skb(skb);
-+}
-diff -urN linux-2.4.18/net/bluetooth/hci_sock.c linux-2.4.18-mh15/net/bluetooth/hci_sock.c
---- linux-2.4.18/net/bluetooth/hci_sock.c 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/net/bluetooth/hci_sock.c 2004-08-01 16:26:23.000000000 +0200
-@@ -25,7 +25,7 @@
- /*
- * BlueZ HCI socket layer.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
-@@ -49,45 +49,54 @@
-
- #include <asm/system.h>
- #include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
-
- #ifndef HCI_SOCK_DEBUG
--#undef DBG
--#define DBG( A... )
-+#undef BT_DBG
-+#define BT_DBG( A... )
- #endif
-
--/* HCI socket interface */
-+/* ----- HCI socket interface ----- */
-+
-+/* Security filter */
-+static struct hci_sec_filter hci_sec_filter = {
-+ /* Packet types */
-+ 0x10,
-+ /* Events */
-+ { 0x1000d9fe, 0x0000300c },
-+ /* Commands */
-+ {
-+ { 0x0 },
-+ /* OGF_LINK_CTL */
-+ { 0xbe000006, 0x00000001, 0x0000, 0x00 },
-+ /* OGF_LINK_POLICY */
-+ { 0x00005200, 0x00000000, 0x0000, 0x00 },
-+ /* OGF_HOST_CTL */
-+ { 0xaab00200, 0x2b402aaa, 0x0154, 0x00 },
-+ /* OGF_INFO_PARAM */
-+ { 0x000002be, 0x00000000, 0x0000, 0x00 },
-+ /* OGF_STATUS_PARAM */
-+ { 0x000000ea, 0x00000000, 0x0000, 0x00 }
-+ }
-+};
-
- static struct bluez_sock_list hci_sk_list = {
- lock: RW_LOCK_UNLOCKED
- };
-
--static struct sock *hci_sock_lookup(struct hci_dev *hdev)
--{
-- struct sock *sk;
--
-- read_lock(&hci_sk_list.lock);
-- for (sk = hci_sk_list.head; sk; sk = sk->next) {
-- if (hci_pi(sk)->hdev == hdev)
-- break;
-- }
-- read_unlock(&hci_sk_list.lock);
-- return sk;
--}
--
- /* Send frame to RAW socket */
- void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
- {
- struct sock * sk;
-
-- DBG("hdev %p len %d", hdev, skb->len);
-+ BT_DBG("hdev %p len %d", hdev, skb->len);
-
- read_lock(&hci_sk_list.lock);
- for (sk = hci_sk_list.head; sk; sk = sk->next) {
-- struct hci_filter *flt;
-+ struct hci_filter *flt;
- struct sk_buff *nskb;
-
- if (sk->state != BT_BOUND || hci_pi(sk)->hdev != hdev)
-@@ -100,13 +109,19 @@
- /* Apply filter */
- flt = &hci_pi(sk)->filter;
-
-- if (!test_bit(skb->pkt_type, &flt->type_mask))
-+ if (!hci_test_bit((skb->pkt_type & HCI_FLT_TYPE_BITS), &flt->type_mask))
- continue;
-
- if (skb->pkt_type == HCI_EVENT_PKT) {
-- register int evt = (*(__u8 *)skb->data & 63);
-+ register int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
-+
-+ if (!hci_test_bit(evt, &flt->event_mask))
-+ continue;
-
-- if (!test_bit(evt, &flt->event_mask))
-+ if (flt->opcode && ((evt == EVT_CMD_COMPLETE &&
-+ flt->opcode != *(__u16 *)(skb->data + 3)) ||
-+ (evt == EVT_CMD_STATUS &&
-+ flt->opcode != *(__u16 *)(skb->data + 4))))
- continue;
- }
-
-@@ -116,8 +131,8 @@
- /* Put type byte before the data */
- memcpy(skb_push(nskb, 1), &nskb->pkt_type, 1);
-
-- skb_queue_tail(&sk->receive_queue, nskb);
-- sk->data_ready(sk, nskb->len);
-+ if (sock_queue_rcv_skb(sk, nskb))
-+ kfree_skb(nskb);
- }
- read_unlock(&hci_sk_list.lock);
- }
-@@ -127,7 +142,7 @@
- struct sock *sk = sock->sk;
- struct hci_dev *hdev = hci_pi(sk)->hdev;
-
-- DBG("sock %p sk %p", sock, sk);
-+ BT_DBG("sock %p sk %p", sock, sk);
-
- if (!sk)
- return 0;
-@@ -135,9 +150,7 @@
- bluez_sock_unlink(&hci_sk_list, sk);
-
- if (hdev) {
-- if (!hci_sock_lookup(hdev))
-- hdev->flags &= ~HCI_SOCK;
--
-+ atomic_dec(&hdev->promisc);
- hci_dev_put(hdev);
- }
-
-@@ -149,24 +162,55 @@
- sock_put(sk);
-
- MOD_DEC_USE_COUNT;
--
- return 0;
- }
-
--static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+/* Ioctls that require bound socket */
-+static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
- {
-- struct sock *sk = sock->sk;
- struct hci_dev *hdev = hci_pi(sk)->hdev;
-- __u32 mode;
-
-- DBG("cmd %x arg %lx", cmd, arg);
-+ if (!hdev)
-+ return -EBADFD;
-
- switch (cmd) {
-- case HCIGETINFO:
-- return hci_dev_info(arg);
-+ case HCISETRAW:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-
-+ if (arg)
-+ set_bit(HCI_RAW, &hdev->flags);
-+ else
-+ clear_bit(HCI_RAW, &hdev->flags);
-+
-+ return 0;
-+
-+ case HCIGETCONNINFO:
-+ return hci_get_conn_info(hdev, arg);
-+
-+ default:
-+ if (hdev->ioctl)
-+ return hdev->ioctl(hdev, cmd, arg);
-+ return -EINVAL;
-+ }
-+}
-+
-+static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct sock *sk = sock->sk;
-+ int err;
-+
-+ BT_DBG("cmd %x arg %lx", cmd, arg);
-+
-+ switch (cmd) {
- case HCIGETDEVLIST:
-- return hci_dev_list(arg);
-+ return hci_get_dev_list(arg);
-+
-+ case HCIGETDEVINFO:
-+ return hci_get_dev_info(arg);
-+
-+ case HCIGETCONNLIST:
-+ return hci_get_conn_list(arg);
-
- case HCIDEVUP:
- if (!capable(CAP_NET_ADMIN))
-@@ -183,48 +227,31 @@
- return -EACCES;
- return hci_dev_reset(arg);
-
-- case HCIRESETSTAT:
-+ case HCIDEVRESTAT:
- if (!capable(CAP_NET_ADMIN))
- return -EACCES;
- return hci_dev_reset_stat(arg);
-
- case HCISETSCAN:
-- if (!capable(CAP_NET_ADMIN))
-- return -EACCES;
-- return hci_dev_setscan(arg);
--
- case HCISETAUTH:
-- if (!capable(CAP_NET_ADMIN))
-- return -EACCES;
-- return hci_dev_setauth(arg);
--
-- case HCISETRAW:
-- if (!capable(CAP_NET_ADMIN))
-- return -EACCES;
--
-- if (!hdev)
-- return -EBADFD;
--
-- if (arg)
-- mode = HCI_RAW;
-- else
-- mode = HCI_NORMAL;
--
-- return hci_dev_setmode(hdev, mode);
--
-+ case HCISETENCRYPT:
- case HCISETPTYPE:
-+ case HCISETLINKPOL:
-+ case HCISETLINKMODE:
-+ case HCISETACLMTU:
-+ case HCISETSCOMTU:
- if (!capable(CAP_NET_ADMIN))
- return -EACCES;
-- return hci_dev_setptype(arg);
-+ return hci_dev_cmd(cmd, arg);
-
- case HCIINQUIRY:
- return hci_inquiry(arg);
-
-- case HCIGETCONNLIST:
-- return hci_conn_list(arg);
--
- default:
-- return -EINVAL;
-+ lock_sock(sk);
-+ err = hci_sock_bound_ioctl(sk, cmd, arg);
-+ release_sock(sk);
-+ return err;
- };
- }
-
-@@ -233,28 +260,35 @@
- struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
- struct sock *sk = sock->sk;
- struct hci_dev *hdev = NULL;
-+ int err = 0;
-
-- DBG("sock %p sk %p", sock, sk);
-+ BT_DBG("sock %p sk %p", sock, sk);
-
- if (!haddr || haddr->hci_family != AF_BLUETOOTH)
- return -EINVAL;
-
-+ lock_sock(sk);
-+
- if (hci_pi(sk)->hdev) {
-- /* Already bound */
-- return 0;
-+ err = -EALREADY;
-+ goto done;
- }
-
- if (haddr->hci_dev != HCI_DEV_NONE) {
-- if (!(hdev = hci_dev_get(haddr->hci_dev)))
-- return -ENODEV;
-+ if (!(hdev = hci_dev_get(haddr->hci_dev))) {
-+ err = -ENODEV;
-+ goto done;
-+ }
-
-- hdev->flags |= HCI_SOCK;
-+ atomic_inc(&hdev->promisc);
- }
-
- hci_pi(sk)->hdev = hdev;
- sk->state = BT_BOUND;
-
-- return 0;
-+done:
-+ release_sock(sk);
-+ return err;
- }
-
- static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer)
-@@ -262,73 +296,44 @@
- struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
- struct sock *sk = sock->sk;
-
-- DBG("sock %p sk %p", sock, sk);
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ lock_sock(sk);
-
- *addr_len = sizeof(*haddr);
- haddr->hci_family = AF_BLUETOOTH;
- haddr->hci_dev = hci_pi(sk)->hdev->id;
-
-+ release_sock(sk);
- return 0;
- }
-
--static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
-- struct scm_cookie *scm)
--{
-- struct sock *sk = sock->sk;
-- struct hci_dev *hdev = hci_pi(sk)->hdev;
-- struct sk_buff *skb;
-- int err;
--
-- DBG("sock %p sk %p", sock, sk);
--
-- if (msg->msg_flags & MSG_OOB)
-- return -EOPNOTSUPP;
--
-- if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
-- return -EINVAL;
--
-- if (!hdev)
-- return -EBADFD;
--
-- if (!(skb = bluez_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
-- return err;
--
-- if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
-- kfree_skb(skb);
-- return -EFAULT;
-- }
--
-- skb->dev = (void *) hdev;
-- skb->pkt_type = *((unsigned char *) skb->data);
-- skb_pull(skb, 1);
--
-- /* Send frame to HCI core */
-- hci_send_raw(skb);
--
-- return len;
--}
--
- static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
- {
- __u32 mask = hci_pi(sk)->cmsg_mask;
-
- if (mask & HCI_CMSG_DIR)
- put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(int), &bluez_cb(skb)->incomming);
-+
-+ if (mask & HCI_CMSG_TSTAMP)
-+ put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, sizeof(skb->stamp), &skb->stamp);
- }
-
--static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len,
-- int flags, struct scm_cookie *scm)
-+static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
- {
- int noblock = flags & MSG_DONTWAIT;
- struct sock *sk = sock->sk;
- struct sk_buff *skb;
- int copied, err;
-
-- DBG("sock %p sk %p", sock, sk);
-+ BT_DBG("sock %p, sk %p", sock, sk);
-
-- if (flags & (MSG_OOB | MSG_PEEK))
-+ if (flags & (MSG_OOB))
- return -EOPNOTSUPP;
-
-+ if (sk->state == BT_CLOSED)
-+ return 0;
-+
- if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
- return err;
-
-@@ -343,28 +348,107 @@
- skb->h.raw = skb->data;
- err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
-
-- if (hci_pi(sk)->cmsg_mask)
-- hci_sock_cmsg(sk, msg, skb);
--
-+ hci_sock_cmsg(sk, msg, skb);
-+
- skb_free_datagram(sk, skb);
-
- return err ? : copied;
- }
-
-+static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
-+ struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ struct hci_dev *hdev;
-+ struct sk_buff *skb;
-+ int err;
-+
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ if (msg->msg_flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
-+ return -EINVAL;
-+
-+ if (len < 4)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (!(hdev = hci_pi(sk)->hdev)) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ if (!(skb = bluez_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
-+ goto done;
-+
-+ if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
-+ err = -EFAULT;
-+ goto drop;
-+ }
-+
-+ skb->pkt_type = *((unsigned char *) skb->data);
-+ skb_pull(skb, 1);
-+ skb->dev = (void *) hdev;
-+
-+ if (skb->pkt_type == HCI_COMMAND_PKT) {
-+ u16 opcode = __le16_to_cpu(get_unaligned((u16 *)skb->data));
-+ u16 ogf = cmd_opcode_ogf(opcode);
-+ u16 ocf = cmd_opcode_ocf(opcode);
-+
-+ if (((ogf > HCI_SFLT_MAX_OGF) ||
-+ !hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) &&
-+ !capable(CAP_NET_RAW)) {
-+ err = -EPERM;
-+ goto drop;
-+ }
-+
-+ if (test_bit(HCI_RAW, &hdev->flags) || (ogf == OGF_VENDOR_CMD)) {
-+ skb_queue_tail(&hdev->raw_q, skb);
-+ hci_sched_tx(hdev);
-+ } else {
-+ skb_queue_tail(&hdev->cmd_q, skb);
-+ hci_sched_cmd(hdev);
-+ }
-+ } else {
-+ if (!capable(CAP_NET_RAW)) {
-+ err = -EPERM;
-+ goto drop;
-+ }
-+
-+ skb_queue_tail(&hdev->raw_q, skb);
-+ hci_sched_tx(hdev);
-+ }
-+
-+ err = len;
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+
-+drop:
-+ kfree_skb(skb);
-+ goto done;
-+}
-+
- int hci_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int len)
- {
- struct sock *sk = sock->sk;
-- struct hci_filter flt;
-+ struct hci_filter flt = { opcode: 0 };
- int err = 0, opt = 0;
-
-- DBG("sk %p, opt %d", sk, optname);
-+ BT_DBG("sk %p, opt %d", sk, optname);
-
- lock_sock(sk);
-
- switch (optname) {
- case HCI_DATA_DIR:
-- if (get_user(opt, (int *)optval))
-- return -EFAULT;
-+ if (get_user(opt, (int *)optval)) {
-+ err = -EFAULT;
-+ break;
-+ }
-
- if (opt)
- hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
-@@ -372,12 +456,31 @@
- hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
- break;
-
-+ case HCI_TIME_STAMP:
-+ if (get_user(opt, (int *)optval)) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ if (opt)
-+ hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
-+ else
-+ hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
-+ break;
-+
- case HCI_FILTER:
- len = MIN(len, sizeof(struct hci_filter));
- if (copy_from_user(&flt, optval, len)) {
- err = -EFAULT;
- break;
- }
-+
-+ if (!capable(CAP_NET_RAW)) {
-+ flt.type_mask &= hci_sec_filter.type_mask;
-+ flt.event_mask[0] &= hci_sec_filter.event_mask[0];
-+ flt.event_mask[1] &= hci_sec_filter.event_mask[1];
-+ }
-+
- memcpy(&hci_pi(sk)->filter, &flt, len);
- break;
-
-@@ -409,6 +512,16 @@
- return -EFAULT;
- break;
-
-+ case HCI_TIME_STAMP:
-+ if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
-+ opt = 1;
-+ else
-+ opt = 0;
-+
-+ if (put_user(opt, optval))
-+ return -EFAULT;
-+ break;
-+
- case HCI_FILTER:
- len = MIN(len, sizeof(struct hci_filter));
- if (copy_to_user(optval, &hci_pi(sk)->filter, len))
-@@ -446,7 +559,7 @@
- {
- struct sock *sk;
-
-- DBG("sock %p", sock);
-+ BT_DBG("sock %p", sock);
-
- if (sock->type != SOCK_RAW)
- return -ESOCKTNOSUPPORT;
-@@ -464,44 +577,31 @@
- sk->protocol = protocol;
- sk->state = BT_OPEN;
-
-- /* Initialize filter */
-- hci_pi(sk)->filter.type_mask = (1<<HCI_EVENT_PKT);
-- hci_pi(sk)->filter.event_mask[0] = ~0L;
-- hci_pi(sk)->filter.event_mask[1] = ~0L;
--
- bluez_sock_link(&hci_sk_list, sk);
-
- MOD_INC_USE_COUNT;
--
- return 0;
- }
-
- static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
- {
- struct hci_dev *hdev = (struct hci_dev *) ptr;
-- struct sk_buff *skb;
--
-- DBG("hdev %s event %ld", hdev->name, event);
-+ evt_si_device sd;
-+
-+ BT_DBG("hdev %s event %ld", hdev->name, event);
-
- /* Send event to sockets */
-- if ((skb = bluez_skb_alloc(HCI_EVENT_HDR_SIZE + EVT_HCI_DEV_EVENT_SIZE, GFP_ATOMIC))) {
-- hci_event_hdr eh = { EVT_HCI_DEV_EVENT, EVT_HCI_DEV_EVENT_SIZE };
-- evt_hci_dev_event he = { event, hdev->id };
--
-- skb->pkt_type = HCI_EVENT_PKT;
-- memcpy(skb_put(skb, HCI_EVENT_HDR_SIZE), &eh, HCI_EVENT_HDR_SIZE);
-- memcpy(skb_put(skb, EVT_HCI_DEV_EVENT_SIZE), &he, EVT_HCI_DEV_EVENT_SIZE);
--
-- hci_send_to_sock(NULL, skb);
-- kfree_skb(skb);
-- }
--
-+ sd.event = event;
-+ sd.dev_id = hdev->id;
-+ hci_si_event(NULL, EVT_SI_DEVICE, EVT_SI_DEVICE_SIZE, &sd);
-+
- if (event == HCI_DEV_UNREG) {
- struct sock *sk;
-
- /* Detach sockets from device */
- read_lock(&hci_sk_list.lock);
- for (sk = hci_sk_list.head; sk; sk = sk->next) {
-+ bh_lock_sock(sk);
- if (hci_pi(sk)->hdev == hdev) {
- hci_pi(sk)->hdev = NULL;
- sk->err = EPIPE;
-@@ -510,6 +610,7 @@
-
- hci_dev_put(hdev);
- }
-+ bh_unlock_sock(sk);
- }
- read_unlock(&hci_sk_list.lock);
- }
-@@ -529,21 +630,19 @@
- int hci_sock_init(void)
- {
- if (bluez_sock_register(BTPROTO_HCI, &hci_sock_family_ops)) {
-- ERR("Can't register HCI socket");
-+ BT_ERR("Can't register HCI socket");
- return -EPROTO;
- }
-
- hci_register_notifier(&hci_sock_nblock);
--
- return 0;
- }
-
- int hci_sock_cleanup(void)
- {
- if (bluez_sock_unregister(BTPROTO_HCI))
-- ERR("Can't unregister HCI socket");
-+ BT_ERR("Can't unregister HCI socket");
-
- hci_unregister_notifier(&hci_sock_nblock);
--
- return 0;
- }
-diff -urN linux-2.4.18/net/bluetooth/hidp/Config.in linux-2.4.18-mh15/net/bluetooth/hidp/Config.in
---- linux-2.4.18/net/bluetooth/hidp/Config.in 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/hidp/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,5 @@
-+#
-+# Bluetooth HIDP layer configuration
-+#
-+
-+dep_tristate 'HIDP protocol support' CONFIG_BLUEZ_HIDP $CONFIG_INPUT $CONFIG_BLUEZ_L2CAP
-diff -urN linux-2.4.18/net/bluetooth/hidp/core.c linux-2.4.18-mh15/net/bluetooth/hidp/core.c
---- linux-2.4.18/net/bluetooth/hidp/core.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/hidp/core.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,655 @@
-+/*
-+ HIDP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <linux/init.h>
-+#include <net/sock.h>
-+
-+#include <linux/input.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#include "hidp.h"
-+
-+#ifndef CONFIG_BT_HIDP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define VERSION "1.0"
-+
-+static DECLARE_RWSEM(hidp_session_sem);
-+static LIST_HEAD(hidp_session_list);
-+
-+static unsigned char hidp_keycode[256] = {
-+ 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
-+ 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
-+ 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
-+ 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
-+ 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106,
-+ 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
-+ 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
-+ 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
-+ 115,114, 0, 0, 0,121, 0, 89, 93,124, 92, 94, 95, 0, 0, 0,
-+ 122,123, 90, 91, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-+ 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
-+ 150,158,159,128,136,177,178,176,142,152,173,140
-+};
-+
-+static struct hidp_session *__hidp_get_session(bdaddr_t *bdaddr)
-+{
-+ struct hidp_session *session;
-+ struct list_head *p;
-+
-+ BT_DBG("");
-+
-+ list_for_each(p, &hidp_session_list) {
-+ session = list_entry(p, struct hidp_session, list);
-+ if (!bacmp(bdaddr, &session->bdaddr))
-+ return session;
-+ }
-+ return NULL;
-+}
-+
-+static void __hidp_link_session(struct hidp_session *session)
-+{
-+ MOD_INC_USE_COUNT;
-+ list_add(&session->list, &hidp_session_list);
-+}
-+
-+static void __hidp_unlink_session(struct hidp_session *session)
-+{
-+ list_del(&session->list);
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void __hidp_copy_session(struct hidp_session *session, struct hidp_conninfo *ci)
-+{
-+ bacpy(&ci->bdaddr, &session->bdaddr);
-+
-+ ci->flags = session->flags;
-+ ci->state = session->state;
-+
-+ ci->vendor = 0x0000;
-+ ci->product = 0x0000;
-+ ci->version = 0x0000;
-+ memset(ci->name, 0, 128);
-+
-+ if (session->input) {
-+ ci->vendor = session->input->idvendor;
-+ ci->product = session->input->idproduct;
-+ ci->version = session->input->idversion;
-+ if (session->input->name)
-+ strncpy(ci->name, session->input->name, 128);
-+ else
-+ strncpy(ci->name, "HID Boot Device", 128);
-+ }
-+}
-+
-+static int hidp_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
-+{
-+ struct hidp_session *session = dev->private;
-+ struct sk_buff *skb;
-+ unsigned char newleds;
-+
-+ BT_DBG("session %p hid %p data %p size %d", session, device, data, size);
-+
-+ if (type != EV_LED)
-+ return -1;
-+
-+ newleds = (!!test_bit(LED_KANA, dev->led) << 3) |
-+ (!!test_bit(LED_COMPOSE, dev->led) << 3) |
-+ (!!test_bit(LED_SCROLLL, dev->led) << 2) |
-+ (!!test_bit(LED_CAPSL, dev->led) << 1) |
-+ (!!test_bit(LED_NUML, dev->led));
-+
-+ if (session->leds == newleds)
-+ return 0;
-+
-+ session->leds = newleds;
-+
-+ if (!(skb = alloc_skb(3, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for new frame");
-+ return -ENOMEM;
-+ }
-+
-+ *skb_put(skb, 1) = 0xa2;
-+ *skb_put(skb, 1) = 0x01;
-+ *skb_put(skb, 1) = newleds;
-+
-+ skb_queue_tail(&session->intr_transmit, skb);
-+
-+ hidp_schedule(session);
-+
-+ return 0;
-+}
-+
-+static void hidp_input_report(struct hidp_session *session, struct sk_buff *skb)
-+{
-+ struct input_dev *dev = session->input;
-+ unsigned char *keys = session->keys;
-+ unsigned char *udata = skb->data + 1;
-+ signed char *sdata = skb->data + 1;
-+ int i, size = skb->len - 1;
-+
-+ switch (skb->data[0]) {
-+ case 0x01: /* Keyboard report */
-+ for (i = 0; i < 8; i++)
-+ input_report_key(dev, hidp_keycode[i + 224], (udata[0] >> i) & 1);
-+
-+ for (i = 2; i < 8; i++) {
-+ if (keys[i] > 3 && memscan(udata + 2, keys[i], 6) == udata + 8) {
-+ if (hidp_keycode[keys[i]])
-+ input_report_key(dev, hidp_keycode[keys[i]], 0);
-+ else
-+ BT_ERR("Unknown key (scancode %#x) released.", keys[i]);
-+ }
-+
-+ if (udata[i] > 3 && memscan(keys + 2, udata[i], 6) == keys + 8) {
-+ if (hidp_keycode[udata[i]])
-+ input_report_key(dev, hidp_keycode[udata[i]], 1);
-+ else
-+ BT_ERR("Unknown key (scancode %#x) pressed.", udata[i]);
-+ }
-+ }
-+
-+ memcpy(keys, udata, 8);
-+ break;
-+
-+ case 0x02: /* Mouse report */
-+ input_report_key(dev, BTN_LEFT, sdata[0] & 0x01);
-+ input_report_key(dev, BTN_RIGHT, sdata[0] & 0x02);
-+ input_report_key(dev, BTN_MIDDLE, sdata[0] & 0x04);
-+ input_report_key(dev, BTN_SIDE, sdata[0] & 0x08);
-+ input_report_key(dev, BTN_EXTRA, sdata[0] & 0x10);
-+
-+ input_report_rel(dev, REL_X, sdata[1]);
-+ input_report_rel(dev, REL_Y, sdata[2]);
-+
-+ if (size > 3)
-+ input_report_rel(dev, REL_WHEEL, sdata[3]);
-+ break;
-+ }
-+
-+ input_event(dev, EV_RST, 0, 0);
-+}
-+
-+static void hidp_idle_timeout(unsigned long arg)
-+{
-+ struct hidp_session *session = (struct hidp_session *) arg;
-+
-+ atomic_inc(&session->terminate);
-+ hidp_schedule(session);
-+}
-+
-+static inline void hidp_set_timer(struct hidp_session *session)
-+{
-+ if (session->idle_to > 0)
-+ mod_timer(&session->timer, jiffies + HZ * session->idle_to);
-+}
-+
-+static inline void hidp_del_timer(struct hidp_session *session)
-+{
-+ if (session->idle_to > 0)
-+ del_timer(&session->timer);
-+}
-+
-+static inline void hidp_send_message(struct hidp_session *session, unsigned char hdr)
-+{
-+ struct sk_buff *skb;
-+
-+ BT_DBG("session %p", session);
-+
-+ if (!(skb = alloc_skb(1, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for message");
-+ return;
-+ }
-+
-+ *skb_put(skb, 1) = hdr;
-+
-+ skb_queue_tail(&session->ctrl_transmit, skb);
-+
-+ hidp_schedule(session);
-+}
-+
-+static inline int hidp_recv_frame(struct hidp_session *session, struct sk_buff *skb)
-+{
-+ __u8 hdr;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ hdr = skb->data[0];
-+ skb_pull(skb, 1);
-+
-+ if (hdr == 0xa1) {
-+ hidp_set_timer(session);
-+
-+ if (session->input)
-+ hidp_input_report(session, skb);
-+ } else {
-+ BT_DBG("Unsupported protocol header 0x%02x", hdr);
-+ }
-+
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+static int hidp_send_frame(struct socket *sock, unsigned char *data, int len)
-+{
-+ struct iovec iv = { data, len };
-+ struct msghdr msg;
-+
-+ BT_DBG("sock %p data %p len %d", sock, data, len);
-+
-+ if (!len)
-+ return 0;
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_iovlen = 1;
-+ msg.msg_iov = &iv;
-+
-+ return sock_sendmsg(sock, &msg, len);
-+}
-+
-+static int hidp_process_transmit(struct hidp_session *session)
-+{
-+ struct sk_buff *skb;
-+
-+ BT_DBG("session %p", session);
-+
-+ while ((skb = skb_dequeue(&session->ctrl_transmit))) {
-+ if (hidp_send_frame(session->ctrl_sock, skb->data, skb->len) < 0) {
-+ skb_queue_head(&session->ctrl_transmit, skb);
-+ break;
-+ }
-+
-+ hidp_set_timer(session);
-+ kfree_skb(skb);
-+ }
-+
-+ while ((skb = skb_dequeue(&session->intr_transmit))) {
-+ if (hidp_send_frame(session->intr_sock, skb->data, skb->len) < 0) {
-+ skb_queue_head(&session->intr_transmit, skb);
-+ break;
-+ }
-+
-+ hidp_set_timer(session);
-+ kfree_skb(skb);
-+ }
-+
-+ return skb_queue_len(&session->ctrl_transmit) +
-+ skb_queue_len(&session->intr_transmit);
-+}
-+
-+static int hidp_session(void *arg)
-+{
-+ struct hidp_session *session = arg;
-+ struct sock *ctrl_sk = session->ctrl_sock->sk;
-+ struct sock *intr_sk = session->intr_sock->sk;
-+ struct sk_buff *skb;
-+ int vendor = 0x0000, product = 0x0000;
-+ wait_queue_t ctrl_wait, intr_wait;
-+ unsigned long timeo = HZ;
-+
-+ BT_DBG("session %p", session);
-+
-+ if (session->input) {
-+ vendor = session->input->idvendor;
-+ product = session->input->idproduct;
-+ }
-+
-+ daemonize(); reparent_to_init();
-+
-+ sprintf(current->comm, "khidpd_%04x%04x", vendor, product);
-+
-+ sigfillset(&current->blocked);
-+ flush_signals(current);
-+
-+ current->nice = -15;
-+
-+ set_fs(KERNEL_DS);
-+
-+ init_waitqueue_entry(&ctrl_wait, current);
-+ init_waitqueue_entry(&intr_wait, current);
-+ add_wait_queue(ctrl_sk->sleep, &ctrl_wait);
-+ add_wait_queue(intr_sk->sleep, &intr_wait);
-+ while (!atomic_read(&session->terminate)) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (ctrl_sk->state != BT_CONNECTED || intr_sk->state != BT_CONNECTED)
-+ break;
-+
-+ while ((skb = skb_dequeue(&ctrl_sk->receive_queue))) {
-+ skb_orphan(skb);
-+ hidp_recv_frame(session, skb);
-+ }
-+
-+ while ((skb = skb_dequeue(&intr_sk->receive_queue))) {
-+ skb_orphan(skb);
-+ hidp_recv_frame(session, skb);
-+ }
-+
-+ hidp_process_transmit(session);
-+
-+ schedule();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(intr_sk->sleep, &intr_wait);
-+ remove_wait_queue(ctrl_sk->sleep, &ctrl_wait);
-+
-+ down_write(&hidp_session_sem);
-+
-+ hidp_del_timer(session);
-+
-+ if (intr_sk->state != BT_CONNECTED) {
-+ init_waitqueue_entry(&ctrl_wait, current);
-+ add_wait_queue(ctrl_sk->sleep, &ctrl_wait);
-+ while (timeo && ctrl_sk->state != BT_CLOSED) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ timeo = schedule_timeout(timeo);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(ctrl_sk->sleep, &ctrl_wait);
-+ timeo = HZ;
-+ }
-+
-+ fput(session->ctrl_sock->file);
-+
-+ init_waitqueue_entry(&intr_wait, current);
-+ add_wait_queue(intr_sk->sleep, &intr_wait);
-+ while (timeo && intr_sk->state != BT_CLOSED) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ timeo = schedule_timeout(timeo);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(intr_sk->sleep, &intr_wait);
-+
-+ fput(session->intr_sock->file);
-+
-+ __hidp_unlink_session(session);
-+
-+ if (session->input) {
-+ input_unregister_device(session->input);
-+ kfree(session->input);
-+ }
-+
-+ up_write(&hidp_session_sem);
-+
-+ kfree(session);
-+ return 0;
-+}
-+
-+static inline void hidp_setup_input(struct hidp_session *session, struct hidp_connadd_req *req)
-+{
-+ struct input_dev *input = session->input;
-+ int i;
-+
-+ input->private = session;
-+
-+ input->idbus = BUS_BLUETOOTH;
-+ input->idvendor = req->vendor;
-+ input->idproduct = req->product;
-+ input->idversion = req->version;
-+
-+ if (req->subclass & 0x40) {
-+ set_bit(EV_KEY, input->evbit);
-+ set_bit(EV_LED, input->evbit);
-+ set_bit(EV_REP, input->evbit);
-+
-+ set_bit(LED_NUML, input->ledbit);
-+ set_bit(LED_CAPSL, input->ledbit);
-+ set_bit(LED_SCROLLL, input->ledbit);
-+ set_bit(LED_COMPOSE, input->ledbit);
-+ set_bit(LED_KANA, input->ledbit);
-+
-+ for (i = 0; i < sizeof(hidp_keycode); i++)
-+ set_bit(hidp_keycode[i], input->keybit);
-+ clear_bit(0, input->keybit);
-+ }
-+
-+ if (req->subclass & 0x80) {
-+ input->evbit[0] = BIT(EV_KEY) | BIT(EV_REL);
-+ input->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE);
-+ input->relbit[0] = BIT(REL_X) | BIT(REL_Y);
-+ input->keybit[LONG(BTN_MOUSE)] |= BIT(BTN_SIDE) | BIT(BTN_EXTRA);
-+ input->relbit[0] |= BIT(REL_WHEEL);
-+ }
-+
-+ input->event = hidp_input_event;
-+
-+ input_register_device(input);
-+}
-+
-+int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
-+{
-+ struct hidp_session *session, *s;
-+ int err;
-+
-+ BT_DBG("");
-+
-+ if (bacmp(&bluez_pi(ctrl_sock->sk)->src, &bluez_pi(intr_sock->sk)->src) ||
-+ bacmp(&bluez_pi(ctrl_sock->sk)->dst, &bluez_pi(intr_sock->sk)->dst))
-+ return -ENOTUNIQ;
-+
-+ session = kmalloc(sizeof(struct hidp_session), GFP_KERNEL);
-+ if (!session)
-+ return -ENOMEM;
-+ memset(session, 0, sizeof(struct hidp_session));
-+
-+ session->input = kmalloc(sizeof(struct input_dev), GFP_KERNEL);
-+ if (!session->input) {
-+ kfree(session);
-+ return -ENOMEM;
-+ }
-+ memset(session->input, 0, sizeof(struct input_dev));
-+
-+ down_write(&hidp_session_sem);
-+
-+ s = __hidp_get_session(&bluez_pi(ctrl_sock->sk)->dst);
-+ if (s && s->state == BT_CONNECTED) {
-+ err = -EEXIST;
-+ goto failed;
-+ }
-+
-+ bacpy(&session->bdaddr, &bluez_pi(ctrl_sock->sk)->dst);
-+
-+ session->ctrl_mtu = min_t(uint, l2cap_pi(ctrl_sock->sk)->omtu, l2cap_pi(ctrl_sock->sk)->imtu);
-+ session->intr_mtu = min_t(uint, l2cap_pi(intr_sock->sk)->omtu, l2cap_pi(intr_sock->sk)->imtu);
-+
-+ BT_DBG("ctrl mtu %d intr mtu %d", session->ctrl_mtu, session->intr_mtu);
-+
-+ session->ctrl_sock = ctrl_sock;
-+ session->intr_sock = intr_sock;
-+ session->state = BT_CONNECTED;
-+
-+ init_timer(&session->timer);
-+
-+ session->timer.function = hidp_idle_timeout;
-+ session->timer.data = (unsigned long) session;
-+
-+ skb_queue_head_init(&session->ctrl_transmit);
-+ skb_queue_head_init(&session->intr_transmit);
-+
-+ session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID);
-+ session->idle_to = req->idle_to;
-+
-+ if (session->input)
-+ hidp_setup_input(session, req);
-+
-+ __hidp_link_session(session);
-+
-+ hidp_set_timer(session);
-+
-+ err = kernel_thread(hidp_session, session, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-+ if (err < 0)
-+ goto unlink;
-+
-+ if (session->input) {
-+ hidp_send_message(session, 0x70);
-+ session->flags |= (1 << HIDP_BOOT_PROTOCOL_MODE);
-+
-+ session->leds = 0xff;
-+ hidp_input_event(session->input, EV_LED, 0, 0);
-+ }
-+
-+ up_write(&hidp_session_sem);
-+ return 0;
-+
-+unlink:
-+ hidp_del_timer(session);
-+
-+ __hidp_unlink_session(session);
-+
-+ if (session->input)
-+ input_unregister_device(session->input);
-+
-+failed:
-+ up_write(&hidp_session_sem);
-+
-+ if (session->input)
-+ kfree(session->input);
-+
-+ kfree(session);
-+ return err;
-+}
-+
-+int hidp_del_connection(struct hidp_conndel_req *req)
-+{
-+ struct hidp_session *session;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ down_read(&hidp_session_sem);
-+
-+ session = __hidp_get_session(&req->bdaddr);
-+ if (session) {
-+ if (req->flags & (1 << HIDP_VIRTUAL_CABLE_UNPLUG)) {
-+ hidp_send_message(session, 0x15);
-+ } else {
-+ /* Flush the transmit queues */
-+ skb_queue_purge(&session->ctrl_transmit);
-+ skb_queue_purge(&session->intr_transmit);
-+
-+ /* Kill session thread */
-+ atomic_inc(&session->terminate);
-+ hidp_schedule(session);
-+ }
-+ } else
-+ err = -ENOENT;
-+
-+ up_read(&hidp_session_sem);
-+ return err;
-+}
-+
-+int hidp_get_connlist(struct hidp_connlist_req *req)
-+{
-+ struct list_head *p;
-+ int err = 0, n = 0;
-+
-+ BT_DBG("");
-+
-+ down_read(&hidp_session_sem);
-+
-+ list_for_each(p, &hidp_session_list) {
-+ struct hidp_session *session;
-+ struct hidp_conninfo ci;
-+
-+ session = list_entry(p, struct hidp_session, list);
-+
-+ __hidp_copy_session(session, &ci);
-+
-+ if (copy_to_user(req->ci, &ci, sizeof(ci))) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ if (++n >= req->cnum)
-+ break;
-+
-+ req->ci++;
-+ }
-+ req->cnum = n;
-+
-+ up_read(&hidp_session_sem);
-+ return err;
-+}
-+
-+int hidp_get_conninfo(struct hidp_conninfo *ci)
-+{
-+ struct hidp_session *session;
-+ int err = 0;
-+
-+ down_read(&hidp_session_sem);
-+
-+ session = __hidp_get_session(&ci->bdaddr);
-+ if (session)
-+ __hidp_copy_session(session, ci);
-+ else
-+ err = -ENOENT;
-+
-+ up_read(&hidp_session_sem);
-+ return err;
-+}
-+
-+static int __init hidp_init(void)
-+{
-+ l2cap_load();
-+
-+ hidp_init_sockets();
-+
-+ BT_INFO("BlueZ HIDP ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>");
-+
-+ return 0;
-+}
-+
-+static void __exit hidp_exit(void)
-+{
-+ hidp_cleanup_sockets();
-+}
-+
-+module_init(hidp_init);
-+module_exit(hidp_exit);
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("Bluetooth HIDP ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/hidp/hidp.h linux-2.4.18-mh15/net/bluetooth/hidp/hidp.h
---- linux-2.4.18/net/bluetooth/hidp/hidp.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/hidp/hidp.h 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,122 @@
-+/*
-+ HIDP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#ifndef __HIDP_H
-+#define __HIDP_H
-+
-+#include <linux/types.h>
-+#include <net/bluetooth/bluetooth.h>
-+
-+/* HIDP ioctl defines */
-+#define HIDPCONNADD _IOW('H', 200, int)
-+#define HIDPCONNDEL _IOW('H', 201, int)
-+#define HIDPGETCONNLIST _IOR('H', 210, int)
-+#define HIDPGETCONNINFO _IOR('H', 211, int)
-+
-+#define HIDP_VIRTUAL_CABLE_UNPLUG 0
-+#define HIDP_BOOT_PROTOCOL_MODE 1
-+#define HIDP_BLUETOOTH_VENDOR_ID 9
-+
-+struct hidp_connadd_req {
-+ int ctrl_sock; // Connected control socket
-+ int intr_sock; // Connteted interrupt socket
-+ __u16 parser;
-+ __u16 rd_size;
-+ __u8 *rd_data;
-+ __u8 country;
-+ __u8 subclass;
-+ __u16 vendor;
-+ __u16 product;
-+ __u16 version;
-+ __u32 flags;
-+ __u32 idle_to;
-+ char name[128];
-+};
-+
-+struct hidp_conndel_req {
-+ bdaddr_t bdaddr;
-+ __u32 flags;
-+};
-+
-+struct hidp_conninfo {
-+ bdaddr_t bdaddr;
-+ __u32 flags;
-+ __u16 state;
-+ __u16 vendor;
-+ __u16 product;
-+ __u16 version;
-+ char name[128];
-+};
-+
-+struct hidp_connlist_req {
-+ __u32 cnum;
-+ struct hidp_conninfo *ci;
-+};
-+
-+int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock);
-+int hidp_del_connection(struct hidp_conndel_req *req);
-+int hidp_get_connlist(struct hidp_connlist_req *req);
-+int hidp_get_conninfo(struct hidp_conninfo *ci);
-+
-+/* HIDP session defines */
-+struct hidp_session {
-+ struct list_head list;
-+
-+ struct socket *ctrl_sock;
-+ struct socket *intr_sock;
-+
-+ bdaddr_t bdaddr;
-+
-+ unsigned long state;
-+ unsigned long flags;
-+ unsigned long idle_to;
-+
-+ uint ctrl_mtu;
-+ uint intr_mtu;
-+
-+ atomic_t terminate;
-+
-+ unsigned char keys[8];
-+ unsigned char leds;
-+
-+ struct input_dev *input;
-+
-+ struct timer_list timer;
-+
-+ struct sk_buff_head ctrl_transmit;
-+ struct sk_buff_head intr_transmit;
-+};
-+
-+static inline void hidp_schedule(struct hidp_session *session)
-+{
-+ struct sock *ctrl_sk = session->ctrl_sock->sk;
-+ struct sock *intr_sk = session->intr_sock->sk;
-+
-+ wake_up_interruptible(ctrl_sk->sleep);
-+ wake_up_interruptible(intr_sk->sleep);
-+}
-+
-+/* HIDP init defines */
-+extern int __init hidp_init_sockets(void);
-+extern void __exit hidp_cleanup_sockets(void);
-+
-+#endif /* __HIDP_H */
-diff -urN linux-2.4.18/net/bluetooth/hidp/Makefile linux-2.4.18-mh15/net/bluetooth/hidp/Makefile
---- linux-2.4.18/net/bluetooth/hidp/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/hidp/Makefile 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the Linux Bluetooth HIDP layer
-+#
-+
-+O_TARGET := hidp.o
-+
-+obj-y := core.o sock.o
-+obj-m += $(O_TARGET)
-+
-+include $(TOPDIR)/Rules.make
-diff -urN linux-2.4.18/net/bluetooth/hidp/sock.c linux-2.4.18-mh15/net/bluetooth/hidp/sock.c
---- linux-2.4.18/net/bluetooth/hidp/sock.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/hidp/sock.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,212 @@
-+/*
-+ HIDP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2003-2004 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <linux/init.h>
-+#include <net/sock.h>
-+
-+#include "hidp.h"
-+
-+#ifndef CONFIG_BT_HIDP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+static int hidp_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ sock_orphan(sk);
-+ sock_put(sk);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static int hidp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct hidp_connadd_req ca;
-+ struct hidp_conndel_req cd;
-+ struct hidp_connlist_req cl;
-+ struct hidp_conninfo ci;
-+ struct socket *csock;
-+ struct socket *isock;
-+ int err;
-+
-+ BT_DBG("cmd %x arg %lx", cmd, arg);
-+
-+ switch (cmd) {
-+ case HIDPCONNADD:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
-+ return -EFAULT;
-+
-+ csock = sockfd_lookup(ca.ctrl_sock, &err);
-+ if (!csock)
-+ return err;
-+
-+ isock = sockfd_lookup(ca.intr_sock, &err);
-+ if (!isock) {
-+ fput(csock->file);
-+ return err;
-+ }
-+
-+ if (csock->sk->state != BT_CONNECTED || isock->sk->state != BT_CONNECTED) {
-+ fput(csock->file);
-+ fput(isock->file);
-+ return -EBADFD;
-+ }
-+
-+ err = hidp_add_connection(&ca, csock, isock);
-+ if (!err) {
-+ if (copy_to_user((void *) arg, &ca, sizeof(ca)))
-+ err = -EFAULT;
-+ } else {
-+ fput(csock->file);
-+ fput(isock->file);
-+ }
-+
-+ return err;
-+
-+ case HIDPCONNDEL:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
-+ return -EFAULT;
-+
-+ return hidp_del_connection(&cd);
-+
-+ case HIDPGETCONNLIST:
-+ if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
-+ return -EFAULT;
-+
-+ if (cl.cnum <= 0)
-+ return -EINVAL;
-+
-+ err = hidp_get_connlist(&cl);
-+ if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
-+ return -EFAULT;
-+
-+ return err;
-+
-+ case HIDPGETCONNINFO:
-+ if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
-+ return -EFAULT;
-+
-+ err = hidp_get_conninfo(&ci);
-+ if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
-+ return -EFAULT;
-+
-+ return err;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static struct proto_ops hidp_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: hidp_sock_release,
-+ ioctl: hidp_sock_ioctl,
-+ bind: sock_no_bind,
-+ getname: sock_no_getname,
-+ sendmsg: sock_no_sendmsg,
-+ recvmsg: sock_no_recvmsg,
-+ poll: sock_no_poll,
-+ listen: sock_no_listen,
-+ shutdown: sock_no_shutdown,
-+ setsockopt: sock_no_setsockopt,
-+ getsockopt: sock_no_getsockopt,
-+ connect: sock_no_connect,
-+ socketpair: sock_no_socketpair,
-+ accept: sock_no_accept,
-+ mmap: sock_no_mmap
-+};
-+
-+static int hidp_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ if (sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &hidp_sock_ops;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, 1)))
-+ return -ENOMEM;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ sock->state = SS_UNCONNECTED;
-+ sock_init_data(sock, sk);
-+
-+ sk->destruct = NULL;
-+ sk->protocol = protocol;
-+
-+ return 0;
-+}
-+
-+static struct net_proto_family hidp_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: hidp_sock_create
-+};
-+
-+int __init hidp_init_sockets(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_HIDP, &hidp_sock_family_ops)))
-+ BT_ERR("Can't register HIDP socket layer (%d)", err);
-+
-+ return err;
-+}
-+
-+void __exit hidp_cleanup_sockets(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_unregister(BTPROTO_HIDP)))
-+ BT_ERR("Can't unregister HIDP socket layer (%d)", err);
-+}
-diff -urN linux-2.4.18/net/bluetooth/l2cap.c linux-2.4.18-mh15/net/bluetooth/l2cap.c
---- linux-2.4.18/net/bluetooth/l2cap.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/l2cap.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,2222 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * BlueZ L2CAP core and sockets.
-+ *
-+ * $Id$
-+ */
-+#define VERSION "2.3"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/socket.h>
-+#include <linux/skbuff.h>
-+#include <linux/proc_fs.h>
-+#include <linux/list.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#ifndef L2CAP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+static struct proto_ops l2cap_sock_ops;
-+
-+struct bluez_sock_list l2cap_sk_list = {
-+ lock: RW_LOCK_UNLOCKED
-+};
-+
-+static int l2cap_conn_del(struct hci_conn *conn, int err);
-+
-+static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
-+static void l2cap_chan_del(struct sock *sk, int err);
-+static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len);
-+
-+static void __l2cap_sock_close(struct sock *sk, int reason);
-+static void l2cap_sock_close(struct sock *sk);
-+static void l2cap_sock_kill(struct sock *sk);
-+
-+static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data);
-+static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data);
-+
-+/* ----- L2CAP timers ------ */
-+static void l2cap_sock_timeout(unsigned long arg)
-+{
-+ struct sock *sk = (struct sock *) arg;
-+
-+ BT_DBG("sock %p state %d", sk, sk->state);
-+
-+ bh_lock_sock(sk);
-+ __l2cap_sock_close(sk, ETIMEDOUT);
-+ bh_unlock_sock(sk);
-+
-+ l2cap_sock_kill(sk);
-+ sock_put(sk);
-+}
-+
-+static void l2cap_sock_set_timer(struct sock *sk, long timeout)
-+{
-+ BT_DBG("sk %p state %d timeout %ld", sk, sk->state, timeout);
-+
-+ if (!mod_timer(&sk->timer, jiffies + timeout))
-+ sock_hold(sk);
-+}
-+
-+static void l2cap_sock_clear_timer(struct sock *sk)
-+{
-+ BT_DBG("sock %p state %d", sk, sk->state);
-+
-+ if (timer_pending(&sk->timer) && del_timer(&sk->timer))
-+ __sock_put(sk);
-+}
-+
-+static void l2cap_sock_init_timer(struct sock *sk)
-+{
-+ init_timer(&sk->timer);
-+ sk->timer.function = l2cap_sock_timeout;
-+ sk->timer.data = (unsigned long)sk;
-+}
-+
-+/* -------- L2CAP connections --------- */
-+static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, __u8 status)
-+{
-+ struct l2cap_conn *conn;
-+
-+ if ((conn = hcon->l2cap_data))
-+ return conn;
-+
-+ if (status)
-+ return conn;
-+
-+ if (!(conn = kmalloc(sizeof(struct l2cap_conn), GFP_ATOMIC)))
-+ return NULL;
-+ memset(conn, 0, sizeof(struct l2cap_conn));
-+
-+ hcon->l2cap_data = conn;
-+ conn->hcon = hcon;
-+
-+ conn->mtu = hcon->hdev->acl_mtu;
-+ conn->src = &hcon->hdev->bdaddr;
-+ conn->dst = &hcon->dst;
-+
-+ spin_lock_init(&conn->lock);
-+ conn->chan_list.lock = RW_LOCK_UNLOCKED;
-+
-+ BT_DBG("hcon %p conn %p", hcon, conn);
-+
-+ MOD_INC_USE_COUNT;
-+ return conn;
-+}
-+
-+static int l2cap_conn_del(struct hci_conn *hcon, int err)
-+{
-+ struct l2cap_conn *conn;
-+ struct sock *sk;
-+
-+ if (!(conn = hcon->l2cap_data))
-+ return 0;
-+
-+ BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
-+
-+ if (conn->rx_skb)
-+ kfree_skb(conn->rx_skb);
-+
-+ /* Kill channels */
-+ while ((sk = conn->chan_list.head)) {
-+ bh_lock_sock(sk);
-+ l2cap_chan_del(sk, err);
-+ bh_unlock_sock(sk);
-+ l2cap_sock_kill(sk);
-+ }
-+
-+ hcon->l2cap_data = NULL;
-+ kfree(conn);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+/* -------- Socket interface ---------- */
-+static struct sock *__l2cap_get_sock_by_addr(__u16 psm, bdaddr_t *src)
-+{
-+ struct sock *sk;
-+ for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-+ if (sk->sport == psm && !bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+ }
-+ return sk;
-+}
-+
-+/* Find socket with psm and source bdaddr.
-+ * Returns closest match.
-+ */
-+static struct sock *__l2cap_get_sock_by_psm(int state, __u16 psm, bdaddr_t *src)
-+{
-+ struct sock *sk, *sk1 = NULL;
-+
-+ for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-+ if (state && sk->state != state)
-+ continue;
-+
-+ if (l2cap_pi(sk)->psm == psm) {
-+ /* Exact match. */
-+ if (!bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+
-+ /* Closest match */
-+ if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
-+ sk1 = sk;
-+ }
-+ }
-+ return sk ? sk : sk1;
-+}
-+
-+/* Find socket with given address (psm, src).
-+ * Returns locked socket */
-+static inline struct sock *l2cap_get_sock_by_psm(int state, __u16 psm, bdaddr_t *src)
-+{
-+ struct sock *s;
-+ read_lock(&l2cap_sk_list.lock);
-+ s = __l2cap_get_sock_by_psm(state, psm, src);
-+ if (s) bh_lock_sock(s);
-+ read_unlock(&l2cap_sk_list.lock);
-+ return s;
-+}
-+
-+static void l2cap_sock_destruct(struct sock *sk)
-+{
-+ BT_DBG("sk %p", sk);
-+
-+ skb_queue_purge(&sk->receive_queue);
-+ skb_queue_purge(&sk->write_queue);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void l2cap_sock_cleanup_listen(struct sock *parent)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("parent %p", parent);
-+
-+ /* Close not yet accepted channels */
-+ while ((sk = bluez_accept_dequeue(parent, NULL)))
-+ l2cap_sock_close(sk);
-+
-+ parent->state = BT_CLOSED;
-+ parent->zapped = 1;
-+}
-+
-+/* Kill socket (only if zapped and orphan)
-+ * Must be called on unlocked socket.
-+ */
-+static void l2cap_sock_kill(struct sock *sk)
-+{
-+ if (!sk->zapped || sk->socket)
-+ return;
-+
-+ BT_DBG("sk %p state %d", sk, sk->state);
-+
-+ /* Kill poor orphan */
-+ bluez_sock_unlink(&l2cap_sk_list, sk);
-+ sk->dead = 1;
-+ sock_put(sk);
-+}
-+
-+/* Close socket.
-+ */
-+static void __l2cap_sock_close(struct sock *sk, int reason)
-+{
-+ BT_DBG("sk %p state %d socket %p", sk, sk->state, sk->socket);
-+
-+ switch (sk->state) {
-+ case BT_LISTEN:
-+ l2cap_sock_cleanup_listen(sk);
-+ break;
-+
-+ case BT_CONNECTED:
-+ case BT_CONFIG:
-+ case BT_CONNECT2:
-+ if (sk->type == SOCK_SEQPACKET) {
-+ struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-+ l2cap_disconn_req req;
-+
-+ sk->state = BT_DISCONN;
-+ l2cap_sock_set_timer(sk, sk->sndtimeo);
-+
-+ req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
-+ } else {
-+ l2cap_chan_del(sk, reason);
-+ }
-+ break;
-+
-+ case BT_CONNECT:
-+ case BT_DISCONN:
-+ l2cap_chan_del(sk, reason);
-+ break;
-+
-+ default:
-+ sk->zapped = 1;
-+ break;
-+ };
-+}
-+
-+/* Must be called on unlocked socket. */
-+static void l2cap_sock_close(struct sock *sk)
-+{
-+ l2cap_sock_clear_timer(sk);
-+ lock_sock(sk);
-+ __l2cap_sock_close(sk, ECONNRESET);
-+ release_sock(sk);
-+ l2cap_sock_kill(sk);
-+}
-+
-+static void l2cap_sock_init(struct sock *sk, struct sock *parent)
-+{
-+ struct l2cap_pinfo *pi = l2cap_pi(sk);
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (parent) {
-+ sk->type = parent->type;
-+ pi->imtu = l2cap_pi(parent)->imtu;
-+ pi->omtu = l2cap_pi(parent)->omtu;
-+ pi->link_mode = l2cap_pi(parent)->link_mode;
-+ } else {
-+ pi->imtu = L2CAP_DEFAULT_MTU;
-+ pi->omtu = 0;
-+ pi->link_mode = 0;
-+ }
-+
-+ /* Default config options */
-+ pi->conf_mtu = L2CAP_DEFAULT_MTU;
-+ pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
-+}
-+
-+static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
-+{
-+ struct sock *sk;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
-+ return NULL;
-+
-+ bluez_sock_init(sock, sk);
-+
-+ sk->zapped = 0;
-+
-+ sk->destruct = l2cap_sock_destruct;
-+ sk->sndtimeo = L2CAP_CONN_TIMEOUT;
-+
-+ sk->protocol = proto;
-+ sk->state = BT_OPEN;
-+
-+ l2cap_sock_init_timer(sk);
-+
-+ bluez_sock_link(&l2cap_sk_list, sk);
-+
-+ MOD_INC_USE_COUNT;
-+ return sk;
-+}
-+
-+static int l2cap_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ sock->state = SS_UNCONNECTED;
-+
-+ if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ if (sock->type == SOCK_RAW && !capable(CAP_NET_RAW))
-+ return -EPERM;
-+
-+ sock->ops = &l2cap_sock_ops;
-+
-+ if (!(sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ l2cap_sock_init(sk, NULL);
-+ return 0;
-+}
-+
-+static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
-+{
-+ struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
-+
-+ if (!addr || addr->sa_family != AF_BLUETOOTH)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_OPEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ write_lock_bh(&l2cap_sk_list.lock);
-+ if (la->l2_psm && __l2cap_get_sock_by_addr(la->l2_psm, &la->l2_bdaddr)) {
-+ err = -EADDRINUSE;
-+ } else {
-+ /* Save source address */
-+ bacpy(&bluez_pi(sk)->src, &la->l2_bdaddr);
-+ l2cap_pi(sk)->psm = la->l2_psm;
-+ sk->sport = la->l2_psm;
-+ sk->state = BT_BOUND;
-+ }
-+ write_unlock_bh(&l2cap_sk_list.lock);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_do_connect(struct sock *sk)
-+{
-+ bdaddr_t *src = &bluez_pi(sk)->src;
-+ bdaddr_t *dst = &bluez_pi(sk)->dst;
-+ struct l2cap_conn *conn;
-+ struct hci_conn *hcon;
-+ struct hci_dev *hdev;
-+ int err = 0;
-+
-+ BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
-+
-+ if (!(hdev = hci_get_route(dst, src)))
-+ return -EHOSTUNREACH;
-+
-+ hci_dev_lock_bh(hdev);
-+
-+ err = -ENOMEM;
-+
-+ hcon = hci_connect(hdev, ACL_LINK, dst);
-+ if (!hcon)
-+ goto done;
-+
-+ conn = l2cap_conn_add(hcon, 0);
-+ if (!conn) {
-+ hci_conn_put(hcon);
-+ goto done;
-+ }
-+
-+ err = 0;
-+
-+ /* Update source addr of the socket */
-+ bacpy(src, conn->src);
-+
-+ l2cap_chan_add(conn, sk, NULL);
-+
-+ sk->state = BT_CONNECT;
-+ l2cap_sock_set_timer(sk, sk->sndtimeo);
-+
-+ if (hcon->state == BT_CONNECTED) {
-+ if (sk->type == SOCK_SEQPACKET) {
-+ l2cap_conn_req req;
-+ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ req.psm = l2cap_pi(sk)->psm;
-+ l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
-+ } else {
-+ l2cap_sock_clear_timer(sk);
-+ sk->state = BT_CONNECTED;
-+ }
-+ }
-+
-+done:
-+ hci_dev_unlock_bh(hdev);
-+ hci_dev_put(hdev);
-+ return err;
-+}
-+
-+static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
-+{
-+ struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ lock_sock(sk);
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) {
-+ err = -EINVAL;
-+ goto done;
-+ }
-+
-+ if (sk->type == SOCK_SEQPACKET && !la->l2_psm) {
-+ err = -EINVAL;
-+ goto done;
-+ }
-+
-+ switch(sk->state) {
-+ case BT_CONNECT:
-+ case BT_CONNECT2:
-+ case BT_CONFIG:
-+ /* Already connecting */
-+ goto wait;
-+
-+ case BT_CONNECTED:
-+ /* Already connected */
-+ goto done;
-+
-+ case BT_OPEN:
-+ case BT_BOUND:
-+ /* Can connect */
-+ break;
-+
-+ default:
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ /* Set destination address and psm */
-+ bacpy(&bluez_pi(sk)->dst, &la->l2_bdaddr);
-+ l2cap_pi(sk)->psm = la->l2_psm;
-+
-+ if ((err = l2cap_do_connect(sk)))
-+ goto done;
-+
-+wait:
-+ err = bluez_sock_wait_state(sk, BT_CONNECTED,
-+ sock_sndtimeo(sk, flags & O_NONBLOCK));
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int l2cap_sock_listen(struct socket *sock, int backlog)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p backlog %d", sk, backlog);
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ if (!l2cap_pi(sk)->psm) {
-+ err = -EINVAL;
-+ goto done;
-+ }
-+
-+ sk->max_ack_backlog = backlog;
-+ sk->ack_backlog = 0;
-+ sk->state = BT_LISTEN;
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct sock *sk = sock->sk, *nsk;
-+ long timeo;
-+ int err = 0;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
-+
-+ BT_DBG("sk %p timeo %ld", sk, timeo);
-+
-+ /* Wait for an incoming connection. (wake-one). */
-+ add_wait_queue_exclusive(sk->sleep, &wait);
-+ while (!(nsk = bluez_accept_dequeue(sk, newsock))) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ break;
-+ }
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ break;
-+ }
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ if (err)
-+ goto done;
-+
-+ newsock->state = SS_CONNECTED;
-+
-+ BT_DBG("new socket %p", nsk);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
-+{
-+ struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ addr->sa_family = AF_BLUETOOTH;
-+ *len = sizeof(struct sockaddr_l2);
-+
-+ if (peer)
-+ bacpy(&la->l2_bdaddr, &bluez_pi(sk)->dst);
-+ else
-+ bacpy(&la->l2_bdaddr, &bluez_pi(sk)->src);
-+
-+ la->l2_psm = l2cap_pi(sk)->psm;
-+ return 0;
-+}
-+
-+static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (sk->err)
-+ return sock_error(sk);
-+
-+ if (msg->msg_flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ /* Check outgoing MTU */
-+ if (len > l2cap_pi(sk)->omtu)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state == BT_CONNECTED)
-+ err = l2cap_chan_send(sk, msg, len);
-+ else
-+ err = -ENOTCONN;
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ struct l2cap_options opts;
-+ int err = 0, len;
-+ __u32 opt;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ case L2CAP_OPTIONS:
-+ len = MIN(sizeof(opts), optlen);
-+ if (copy_from_user((char *)&opts, optval, len)) {
-+ err = -EFAULT;
-+ break;
-+ }
-+ l2cap_pi(sk)->imtu = opts.imtu;
-+ l2cap_pi(sk)->omtu = opts.omtu;
-+ break;
-+
-+ case L2CAP_LM:
-+ if (get_user(opt, (__u32 *)optval)) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ l2cap_pi(sk)->link_mode = opt;
-+ break;
-+
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ struct l2cap_options opts;
-+ struct l2cap_conninfo cinfo;
-+ int len, err = 0;
-+
-+ if (get_user(len, optlen))
-+ return -EFAULT;
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ case L2CAP_OPTIONS:
-+ opts.imtu = l2cap_pi(sk)->imtu;
-+ opts.omtu = l2cap_pi(sk)->omtu;
-+ opts.flush_to = l2cap_pi(sk)->flush_to;
-+
-+ len = MIN(len, sizeof(opts));
-+ if (copy_to_user(optval, (char *)&opts, len))
-+ err = -EFAULT;
-+
-+ break;
-+
-+ case L2CAP_LM:
-+ if (put_user(l2cap_pi(sk)->link_mode, (__u32 *)optval))
-+ err = -EFAULT;
-+ break;
-+
-+ case L2CAP_CONNINFO:
-+ if (sk->state != BT_CONNECTED) {
-+ err = -ENOTCONN;
-+ break;
-+ }
-+
-+ cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
-+
-+ len = MIN(len, sizeof(cinfo));
-+ if (copy_to_user(optval, (char *)&cinfo, len))
-+ err = -EFAULT;
-+
-+ break;
-+
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_shutdown(struct socket *sock, int how)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk) return 0;
-+
-+ lock_sock(sk);
-+ if (!sk->shutdown) {
-+ sk->shutdown = SHUTDOWN_MASK;
-+ l2cap_sock_clear_timer(sk);
-+ __l2cap_sock_close(sk, 0);
-+
-+ if (sk->linger)
-+ err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
-+ }
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+ int err;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk) return 0;
-+
-+ err = l2cap_sock_shutdown(sock, 2);
-+
-+ sock_orphan(sk);
-+ l2cap_sock_kill(sk);
-+ return err;
-+}
-+
-+/* --------- L2CAP channels --------- */
-+static struct sock * __l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
-+{
-+ struct sock *s;
-+ for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-+ if (l2cap_pi(s)->dcid == cid)
-+ break;
-+ }
-+ return s;
-+}
-+
-+static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
-+{
-+ struct sock *s;
-+ for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-+ if (l2cap_pi(s)->scid == cid)
-+ break;
-+ }
-+ return s;
-+}
-+
-+/* Find channel with given SCID.
-+ * Returns locked socket */
-+static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
-+{
-+ struct sock *s;
-+ read_lock(&l->lock);
-+ s = __l2cap_get_chan_by_scid(l, cid);
-+ if (s) bh_lock_sock(s);
-+ read_unlock(&l->lock);
-+ return s;
-+}
-+
-+static __u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
-+{
-+ __u16 cid = 0x0040;
-+
-+ for (; cid < 0xffff; cid++) {
-+ if(!__l2cap_get_chan_by_scid(l, cid))
-+ return cid;
-+ }
-+
-+ return 0;
-+}
-+
-+static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
-+{
-+ sock_hold(sk);
-+
-+ if (l->head)
-+ l2cap_pi(l->head)->prev_c = sk;
-+
-+ l2cap_pi(sk)->next_c = l->head;
-+ l2cap_pi(sk)->prev_c = NULL;
-+ l->head = sk;
-+}
-+
-+static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
-+{
-+ struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
-+
-+ write_lock(&l->lock);
-+ if (sk == l->head)
-+ l->head = next;
-+
-+ if (next)
-+ l2cap_pi(next)->prev_c = prev;
-+ if (prev)
-+ l2cap_pi(prev)->next_c = next;
-+ write_unlock(&l->lock);
-+
-+ __sock_put(sk);
-+}
-+
-+static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+
-+ BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
-+
-+ l2cap_pi(sk)->conn = conn;
-+
-+ if (sk->type == SOCK_SEQPACKET) {
-+ /* Alloc CID for connection-oriented socket */
-+ l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
-+ } else if (sk->type == SOCK_DGRAM) {
-+ /* Connectionless socket */
-+ l2cap_pi(sk)->scid = 0x0002;
-+ l2cap_pi(sk)->dcid = 0x0002;
-+ l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
-+ } else {
-+ /* Raw socket can send/recv signalling messages only */
-+ l2cap_pi(sk)->scid = 0x0001;
-+ l2cap_pi(sk)->dcid = 0x0001;
-+ l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
-+ }
-+
-+ __l2cap_chan_link(l, sk);
-+
-+ if (parent)
-+ bluez_accept_enqueue(parent, sk);
-+}
-+
-+static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+ write_lock(&l->lock);
-+ __l2cap_chan_add(conn, sk, parent);
-+ write_unlock(&l->lock);
-+}
-+
-+/* Delete channel.
-+ * Must be called on the locked socket. */
-+static void l2cap_chan_del(struct sock *sk, int err)
-+{
-+ struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-+ struct sock *parent = bluez_pi(sk)->parent;
-+
-+ l2cap_sock_clear_timer(sk);
-+
-+ BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
-+
-+ if (conn) {
-+ /* Unlink from channel list */
-+ l2cap_chan_unlink(&conn->chan_list, sk);
-+ l2cap_pi(sk)->conn = NULL;
-+ hci_conn_put(conn->hcon);
-+ }
-+
-+ sk->state = BT_CLOSED;
-+ sk->zapped = 1;
-+
-+ if (err)
-+ sk->err = err;
-+
-+ if (parent)
-+ parent->data_ready(parent, 0);
-+ else
-+ sk->state_change(sk);
-+}
-+
-+static void l2cap_conn_ready(struct l2cap_conn *conn)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+ struct sock *sk;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ bh_lock_sock(sk);
-+
-+ if (sk->type != SOCK_SEQPACKET) {
-+ l2cap_sock_clear_timer(sk);
-+ sk->state = BT_CONNECTED;
-+ sk->state_change(sk);
-+ } else if (sk->state == BT_CONNECT) {
-+ l2cap_conn_req req;
-+ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ req.psm = l2cap_pi(sk)->psm;
-+ l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
-+ }
-+
-+ bh_unlock_sock(sk);
-+ }
-+
-+ read_unlock(&l->lock);
-+}
-+
-+/* Notify sockets that we cannot guaranty reliability anymore */
-+static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+ struct sock *sk;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ if (l2cap_pi(sk)->link_mode & L2CAP_LM_RELIABLE)
-+ sk->err = err;
-+ }
-+ read_unlock(&l->lock);
-+}
-+
-+static void l2cap_chan_ready(struct sock *sk)
-+{
-+ struct sock *parent = bluez_pi(sk)->parent;
-+
-+ BT_DBG("sk %p, parent %p", sk, parent);
-+
-+ l2cap_pi(sk)->conf_state = 0;
-+ l2cap_sock_clear_timer(sk);
-+
-+ if (!parent) {
-+ /* Outgoing channel.
-+ * Wake up socket sleeping on connect.
-+ */
-+ sk->state = BT_CONNECTED;
-+ sk->state_change(sk);
-+ } else {
-+ /* Incomming channel.
-+ * Wake up socket sleeping on accept.
-+ */
-+ parent->data_ready(parent, 0);
-+ }
-+}
-+
-+/* Copy frame to all raw sockets on that connection */
-+void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+ struct sk_buff *nskb;
-+ struct sock * sk;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ if (sk->type != SOCK_RAW)
-+ continue;
-+
-+ /* Don't send frame to the socket it came from */
-+ if (skb->sk == sk)
-+ continue;
-+
-+ if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
-+ continue;
-+
-+ if (sock_queue_rcv_skb(sk, nskb))
-+ kfree_skb(nskb);
-+ }
-+ read_unlock(&l->lock);
-+}
-+
-+static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
-+{
-+ struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-+ struct sk_buff *skb, **frag;
-+ int err, hlen, count, sent=0;
-+ l2cap_hdr *lh;
-+
-+ BT_DBG("sk %p len %d", sk, len);
-+
-+ /* First fragment (with L2CAP header) */
-+ if (sk->type == SOCK_DGRAM)
-+ hlen = L2CAP_HDR_SIZE + 2;
-+ else
-+ hlen = L2CAP_HDR_SIZE;
-+
-+ count = MIN(conn->mtu - hlen, len);
-+
-+ skb = bluez_skb_send_alloc(sk, hlen + count,
-+ msg->msg_flags & MSG_DONTWAIT, &err);
-+ if (!skb)
-+ return err;
-+
-+ /* Create L2CAP header */
-+ lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-+ lh->cid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ lh->len = __cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
-+
-+ if (sk->type == SOCK_DGRAM)
-+ put_unaligned(l2cap_pi(sk)->psm, (__u16 *) skb_put(skb, 2));
-+
-+ if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
-+ err = -EFAULT;
-+ goto fail;
-+ }
-+
-+ sent += count;
-+ len -= count;
-+
-+ /* Continuation fragments (no L2CAP header) */
-+ frag = &skb_shinfo(skb)->frag_list;
-+ while (len) {
-+ count = MIN(conn->mtu, len);
-+
-+ *frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
-+ if (!*frag)
-+ goto fail;
-+
-+ if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
-+ err = -EFAULT;
-+ goto fail;
-+ }
-+
-+ sent += count;
-+ len -= count;
-+
-+ frag = &(*frag)->next;
-+ }
-+
-+ if ((err = hci_send_acl(conn->hcon, skb, 0)) < 0)
-+ goto fail;
-+
-+ return sent;
-+
-+fail:
-+ kfree_skb(skb);
-+ return err;
-+}
-+
-+/* --------- L2CAP signalling commands --------- */
-+static inline __u8 l2cap_get_ident(struct l2cap_conn *conn)
-+{
-+ __u8 id;
-+
-+ /* Get next available identificator.
-+ * 1 - 199 are used by kernel.
-+ * 200 - 254 are used by utilities like l2ping, etc
-+ */
-+
-+ spin_lock(&conn->lock);
-+
-+ if (++conn->tx_ident > 199)
-+ conn->tx_ident = 1;
-+
-+ id = conn->tx_ident;
-+
-+ spin_unlock(&conn->lock);
-+
-+ return id;
-+}
-+
-+static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
-+ __u8 code, __u8 ident, __u16 dlen, void *data)
-+{
-+ struct sk_buff *skb, **frag;
-+ l2cap_cmd_hdr *cmd;
-+ l2cap_hdr *lh;
-+ int len, count;
-+
-+ BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", conn, code, ident, dlen);
-+
-+ len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
-+ count = MIN(conn->mtu, len);
-+
-+ skb = bluez_skb_alloc(count, GFP_ATOMIC);
-+ if (!skb)
-+ return NULL;
-+
-+ lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-+ lh->len = __cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
-+ lh->cid = __cpu_to_le16(0x0001);
-+
-+ cmd = (l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
-+ cmd->code = code;
-+ cmd->ident = ident;
-+ cmd->len = __cpu_to_le16(dlen);
-+
-+ if (dlen) {
-+ count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
-+ memcpy(skb_put(skb, count), data, count);
-+ data += count;
-+ }
-+
-+ len -= skb->len;
-+
-+ /* Continuation fragments (no L2CAP header) */
-+ frag = &skb_shinfo(skb)->frag_list;
-+ while (len) {
-+ count = MIN(conn->mtu, len);
-+
-+ *frag = bluez_skb_alloc(count, GFP_ATOMIC);
-+ if (!*frag)
-+ goto fail;
-+
-+ memcpy(skb_put(*frag, count), data, count);
-+
-+ len -= count;
-+ data += count;
-+
-+ frag = &(*frag)->next;
-+ }
-+
-+ return skb;
-+
-+fail:
-+ kfree_skb(skb);
-+ return NULL;
-+}
-+
-+static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data)
-+{
-+ __u8 ident = l2cap_get_ident(conn);
-+ struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
-+
-+ BT_DBG("code 0x%2.2x", code);
-+
-+ if (!skb)
-+ return -ENOMEM;
-+ return hci_send_acl(conn->hcon, skb, 0);
-+}
-+
-+static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data)
-+{
-+ struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
-+
-+ BT_DBG("code 0x%2.2x", code);
-+
-+ if (!skb)
-+ return -ENOMEM;
-+ return hci_send_acl(conn->hcon, skb, 0);
-+}
-+
-+static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
-+{
-+ l2cap_conf_opt *opt = *ptr;
-+ int len;
-+
-+ len = L2CAP_CONF_OPT_SIZE + opt->len;
-+ *ptr += len;
-+
-+ *type = opt->type;
-+ *olen = opt->len;
-+
-+ switch (opt->len) {
-+ case 1:
-+ *val = *((__u8 *) opt->val);
-+ break;
-+
-+ case 2:
-+ *val = __le16_to_cpu(*((__u16 *)opt->val));
-+ break;
-+
-+ case 4:
-+ *val = __le32_to_cpu(*((__u32 *)opt->val));
-+ break;
-+
-+ default:
-+ *val = (unsigned long) opt->val;
-+ break;
-+ };
-+
-+ BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
-+ return len;
-+}
-+
-+static inline void l2cap_parse_conf_req(struct sock *sk, void *data, int len)
-+{
-+ int type, hint, olen;
-+ unsigned long val;
-+ void *ptr = data;
-+
-+ BT_DBG("sk %p len %d", sk, len);
-+
-+ while (len >= L2CAP_CONF_OPT_SIZE) {
-+ len -= l2cap_get_conf_opt(&ptr, &type, &olen, &val);
-+
-+ hint = type & 0x80;
-+ type &= 0x7f;
-+
-+ switch (type) {
-+ case L2CAP_CONF_MTU:
-+ l2cap_pi(sk)->conf_mtu = val;
-+ break;
-+
-+ case L2CAP_CONF_FLUSH_TO:
-+ l2cap_pi(sk)->flush_to = val;
-+ break;
-+
-+ case L2CAP_CONF_QOS:
-+ break;
-+
-+ default:
-+ if (hint)
-+ break;
-+
-+ /* FIXME: Reject unknown option */
-+ break;
-+ };
-+ }
-+}
-+
-+static void l2cap_add_conf_opt(void **ptr, __u8 type, __u8 len, unsigned long val)
-+{
-+ register l2cap_conf_opt *opt = *ptr;
-+
-+ BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
-+
-+ opt->type = type;
-+ opt->len = len;
-+
-+ switch (len) {
-+ case 1:
-+ *((__u8 *) opt->val) = val;
-+ break;
-+
-+ case 2:
-+ *((__u16 *) opt->val) = __cpu_to_le16(val);
-+ break;
-+
-+ case 4:
-+ *((__u32 *) opt->val) = __cpu_to_le32(val);
-+ break;
-+
-+ default:
-+ memcpy(opt->val, (void *) val, len);
-+ break;
-+ };
-+
-+ *ptr += L2CAP_CONF_OPT_SIZE + len;
-+}
-+
-+static int l2cap_build_conf_req(struct sock *sk, void *data)
-+{
-+ struct l2cap_pinfo *pi = l2cap_pi(sk);
-+ l2cap_conf_req *req = (l2cap_conf_req *) data;
-+ void *ptr = req->data;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (pi->imtu != L2CAP_DEFAULT_MTU)
-+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
-+
-+ /* FIXME. Need actual value of the flush timeout */
-+ //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
-+ // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
-+
-+ req->dcid = __cpu_to_le16(pi->dcid);
-+ req->flags = __cpu_to_le16(0);
-+
-+ return ptr - data;
-+}
-+
-+static inline int l2cap_conf_output(struct sock *sk, void **ptr)
-+{
-+ struct l2cap_pinfo *pi = l2cap_pi(sk);
-+ int result = 0;
-+
-+ /* Configure output options and let the other side know
-+ * which ones we don't like.
-+ */
-+ if (pi->conf_mtu < pi->omtu) {
-+ l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu);
-+ result = L2CAP_CONF_UNACCEPT;
-+ } else {
-+ pi->omtu = pi->conf_mtu;
-+ }
-+
-+ BT_DBG("sk %p result %d", sk, result);
-+ return result;
-+}
-+
-+static int l2cap_build_conf_rsp(struct sock *sk, void *data, int *result)
-+{
-+ l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data;
-+ void *ptr = rsp->data;
-+ u16 flags = 0;
-+
-+ BT_DBG("sk %p complete %d", sk, result ? 1 : 0);
-+
-+ if (result)
-+ *result = l2cap_conf_output(sk, &ptr);
-+ else
-+ flags |= 0x0001;
-+
-+ rsp->scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ rsp->result = __cpu_to_le16(result ? *result : 0);
-+ rsp->flags = __cpu_to_le16(flags);
-+
-+ return ptr - data;
-+}
-+
-+static inline int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ struct l2cap_chan_list *list = &conn->chan_list;
-+ l2cap_conn_req *req = (l2cap_conn_req *) data;
-+ l2cap_conn_rsp rsp;
-+ struct sock *sk, *parent;
-+ int result = 0, status = 0;
-+
-+ __u16 dcid = 0, scid = __le16_to_cpu(req->scid);
-+ __u16 psm = req->psm;
-+
-+ BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
-+
-+ /* Check if we have socket listening on psm */
-+ parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
-+ if (!parent) {
-+ result = L2CAP_CR_BAD_PSM;
-+ goto sendresp;
-+ }
-+
-+ result = L2CAP_CR_NO_MEM;
-+
-+ /* Check for backlog size */
-+ if (parent->ack_backlog > parent->max_ack_backlog) {
-+ BT_DBG("backlog full %d", parent->ack_backlog);
-+ goto response;
-+ }
-+
-+ sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC);
-+ if (!sk)
-+ goto response;
-+
-+ write_lock(&list->lock);
-+
-+ /* Check if we already have channel with that dcid */
-+ if (__l2cap_get_chan_by_dcid(list, scid)) {
-+ write_unlock(&list->lock);
-+ sk->zapped = 1;
-+ l2cap_sock_kill(sk);
-+ goto response;
-+ }
-+
-+ hci_conn_hold(conn->hcon);
-+
-+ l2cap_sock_init(sk, parent);
-+ bacpy(&bluez_pi(sk)->src, conn->src);
-+ bacpy(&bluez_pi(sk)->dst, conn->dst);
-+ l2cap_pi(sk)->psm = psm;
-+ l2cap_pi(sk)->dcid = scid;
-+
-+ __l2cap_chan_add(conn, sk, parent);
-+ dcid = l2cap_pi(sk)->scid;
-+
-+ l2cap_sock_set_timer(sk, sk->sndtimeo);
-+
-+ /* Service level security */
-+ result = L2CAP_CR_PEND;
-+ status = L2CAP_CS_AUTHEN_PEND;
-+ sk->state = BT_CONNECT2;
-+ l2cap_pi(sk)->ident = cmd->ident;
-+
-+ if (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) {
-+ if (!hci_conn_encrypt(conn->hcon))
-+ goto done;
-+ } else if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH) {
-+ if (!hci_conn_auth(conn->hcon))
-+ goto done;
-+ }
-+
-+ sk->state = BT_CONFIG;
-+ result = status = 0;
-+
-+done:
-+ write_unlock(&list->lock);
-+
-+response:
-+ bh_unlock_sock(parent);
-+
-+sendresp:
-+ rsp.scid = __cpu_to_le16(scid);
-+ rsp.dcid = __cpu_to_le16(dcid);
-+ rsp.result = __cpu_to_le16(result);
-+ rsp.status = __cpu_to_le16(status);
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
-+ return 0;
-+}
-+
-+static inline int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_conn_rsp *rsp = (l2cap_conn_rsp *) data;
-+ __u16 scid, dcid, result, status;
-+ struct sock *sk;
-+ char req[128];
-+
-+ scid = __le16_to_cpu(rsp->scid);
-+ dcid = __le16_to_cpu(rsp->dcid);
-+ result = __le16_to_cpu(rsp->result);
-+ status = __le16_to_cpu(rsp->status);
-+
-+ BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-+ return -ENOENT;
-+
-+ switch (result) {
-+ case L2CAP_CR_SUCCESS:
-+ sk->state = BT_CONFIG;
-+ l2cap_pi(sk)->dcid = dcid;
-+ l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
-+
-+ l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-+ break;
-+
-+ case L2CAP_CR_PEND:
-+ break;
-+
-+ default:
-+ l2cap_chan_del(sk, ECONNREFUSED);
-+ break;
-+ }
-+
-+ bh_unlock_sock(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_conf_req * req = (l2cap_conf_req *) data;
-+ __u16 dcid, flags;
-+ __u8 rsp[64];
-+ struct sock *sk;
-+ int result;
-+
-+ dcid = __le16_to_cpu(req->dcid);
-+ flags = __le16_to_cpu(req->flags);
-+
-+ BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-+ return -ENOENT;
-+
-+ l2cap_parse_conf_req(sk, req->data, cmd->len - L2CAP_CONF_REQ_SIZE);
-+
-+ if (flags & 0x0001) {
-+ /* Incomplete config. Send empty response. */
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
-+ goto unlock;
-+ }
-+
-+ /* Complete config. */
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &result), rsp);
-+
-+ if (result)
-+ goto unlock;
-+
-+ /* Output config done */
-+ l2cap_pi(sk)->conf_state |= L2CAP_CONF_OUTPUT_DONE;
-+
-+ if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
-+ sk->state = BT_CONNECTED;
-+ l2cap_chan_ready(sk);
-+ } else if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
-+ char req[64];
-+ l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-+ }
-+
-+unlock:
-+ bh_unlock_sock(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_conf_rsp *rsp = (l2cap_conf_rsp *)data;
-+ __u16 scid, flags, result;
-+ struct sock *sk;
-+ int err = 0;
-+
-+ scid = __le16_to_cpu(rsp->scid);
-+ flags = __le16_to_cpu(rsp->flags);
-+ result = __le16_to_cpu(rsp->result);
-+
-+ BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-+ return -ENOENT;
-+
-+ switch (result) {
-+ case L2CAP_CONF_SUCCESS:
-+ break;
-+
-+ case L2CAP_CONF_UNACCEPT:
-+ if (++l2cap_pi(sk)->conf_retry < L2CAP_CONF_MAX_RETRIES) {
-+ char req[128];
-+ /*
-+ It does not make sense to adjust L2CAP parameters
-+ that are currently defined in the spec. We simply
-+ resend config request that we sent earlier. It is
-+ stupid :) but it helps qualification testing
-+ which expects at least some response from us.
-+ */
-+ l2cap_send_req(conn, L2CAP_CONF_REQ,
-+ l2cap_build_conf_req(sk, req), req);
-+ goto done;
-+ }
-+ default:
-+ sk->state = BT_DISCONN;
-+ sk->err = ECONNRESET;
-+ l2cap_sock_set_timer(sk, HZ * 5);
-+ {
-+ l2cap_disconn_req req;
-+ req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
-+ }
-+ goto done;
-+ }
-+
-+ if (flags & 0x01)
-+ goto done;
-+
-+ /* Input config done */
-+ l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
-+
-+ if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
-+ sk->state = BT_CONNECTED;
-+ l2cap_chan_ready(sk);
-+ }
-+
-+done:
-+ bh_unlock_sock(sk);
-+ return err;
-+}
-+
-+static inline int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_disconn_req *req = (l2cap_disconn_req *) data;
-+ l2cap_disconn_rsp rsp;
-+ __u16 dcid, scid;
-+ struct sock *sk;
-+
-+ scid = __le16_to_cpu(req->scid);
-+ dcid = __le16_to_cpu(req->dcid);
-+
-+ BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-+ return 0;
-+
-+ rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_DISCONN_RSP, L2CAP_DISCONN_RSP_SIZE, &rsp);
-+
-+ sk->shutdown = SHUTDOWN_MASK;
-+
-+ l2cap_chan_del(sk, ECONNRESET);
-+ bh_unlock_sock(sk);
-+
-+ l2cap_sock_kill(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_disconn_rsp *rsp = (l2cap_disconn_rsp *) data;
-+ __u16 dcid, scid;
-+ struct sock *sk;
-+
-+ scid = __le16_to_cpu(rsp->scid);
-+ dcid = __le16_to_cpu(rsp->dcid);
-+
-+ BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-+ return 0;
-+ l2cap_chan_del(sk, 0);
-+ bh_unlock_sock(sk);
-+
-+ l2cap_sock_kill(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_information_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, u8 *data)
-+{
-+ l2cap_info_req *req = (l2cap_info_req *) data;
-+ l2cap_info_rsp rsp;
-+ u16 type;
-+
-+ type = __le16_to_cpu(req->type);
-+
-+ BT_DBG("type 0x%4.4x", type);
-+
-+ rsp.type = __cpu_to_le16(type);
-+ rsp.result = __cpu_to_le16(L2CAP_IR_NOTSUPP);
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_INFO_RSP, sizeof(rsp), &rsp);
-+ return 0;
-+}
-+
-+static inline int l2cap_information_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, u8 *data)
-+{
-+ l2cap_info_rsp *rsp = (l2cap_info_rsp *) data;
-+ u16 type, result;
-+
-+ type = __le16_to_cpu(rsp->type);
-+ result = __le16_to_cpu(rsp->result);
-+
-+ BT_DBG("type 0x%4.4x result 0x%2.2x", type, result);
-+
-+ return 0;
-+}
-+
-+static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
-+{
-+ __u8 *data = skb->data;
-+ int len = skb->len;
-+ l2cap_cmd_hdr cmd;
-+ int err = 0;
-+
-+ l2cap_raw_recv(conn, skb);
-+
-+ while (len >= L2CAP_CMD_HDR_SIZE) {
-+ memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
-+ data += L2CAP_CMD_HDR_SIZE;
-+ len -= L2CAP_CMD_HDR_SIZE;
-+
-+ cmd.len = __le16_to_cpu(cmd.len);
-+
-+ BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
-+
-+ if (cmd.len > len || !cmd.ident) {
-+ BT_DBG("corrupted command");
-+ break;
-+ }
-+
-+ switch (cmd.code) {
-+ case L2CAP_COMMAND_REJ:
-+ /* FIXME: We should process this */
-+ break;
-+
-+ case L2CAP_CONN_REQ:
-+ err = l2cap_connect_req(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_CONN_RSP:
-+ err = l2cap_connect_rsp(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_CONF_REQ:
-+ err = l2cap_config_req(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_CONF_RSP:
-+ err = l2cap_config_rsp(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_DISCONN_REQ:
-+ err = l2cap_disconnect_req(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_DISCONN_RSP:
-+ err = l2cap_disconnect_rsp(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_ECHO_REQ:
-+ l2cap_send_rsp(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data);
-+ break;
-+
-+ case L2CAP_ECHO_RSP:
-+ break;
-+
-+ case L2CAP_INFO_REQ:
-+ err = l2cap_information_req(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_INFO_RSP:
-+ err = l2cap_information_rsp(conn, &cmd, data);
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown signaling command 0x%2.2x", cmd.code);
-+ err = -EINVAL;
-+ break;
-+ };
-+
-+ if (err) {
-+ l2cap_cmd_rej rej;
-+ BT_DBG("error %d", err);
-+
-+ /* FIXME: Map err to a valid reason */
-+ rej.reason = __cpu_to_le16(0);
-+ l2cap_send_rsp(conn, cmd.ident, L2CAP_COMMAND_REJ, L2CAP_CMD_REJ_SIZE, &rej);
-+ }
-+
-+ data += cmd.len;
-+ len -= cmd.len;
-+ }
-+
-+ kfree_skb(skb);
-+}
-+
-+static inline int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
-+{
-+ struct sock *sk;
-+
-+ sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
-+ if (!sk) {
-+ BT_DBG("unknown cid 0x%4.4x", cid);
-+ goto drop;
-+ }
-+
-+ BT_DBG("sk %p, len %d", sk, skb->len);
-+
-+ if (sk->state != BT_CONNECTED)
-+ goto drop;
-+
-+ if (l2cap_pi(sk)->imtu < skb->len)
-+ goto drop;
-+
-+ /* If socket recv buffers overflows we drop data here
-+ * which is *bad* because L2CAP has to be reliable.
-+ * But we don't have any other choice. L2CAP doesn't
-+ * provide flow control mechanism */
-+
-+ if (!sock_queue_rcv_skb(sk, skb))
-+ goto done;
-+
-+drop:
-+ kfree_skb(skb);
-+
-+done:
-+ if (sk) bh_unlock_sock(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_conless_channel(struct l2cap_conn *conn, __u16 psm, struct sk_buff *skb)
-+{
-+ struct sock *sk;
-+
-+ sk = l2cap_get_sock_by_psm(0, psm, conn->src);
-+ if (!sk)
-+ goto drop;
-+
-+ BT_DBG("sk %p, len %d", sk, skb->len);
-+
-+ if (sk->state != BT_BOUND && sk->state != BT_CONNECTED)
-+ goto drop;
-+
-+ if (l2cap_pi(sk)->imtu < skb->len)
-+ goto drop;
-+
-+ if (!sock_queue_rcv_skb(sk, skb))
-+ goto done;
-+
-+drop:
-+ kfree_skb(skb);
-+
-+done:
-+ if (sk) bh_unlock_sock(sk);
-+ return 0;
-+}
-+
-+static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
-+{
-+ l2cap_hdr *lh = (l2cap_hdr *) skb->data;
-+ __u16 cid, psm, len;
-+
-+ skb_pull(skb, L2CAP_HDR_SIZE);
-+ cid = __le16_to_cpu(lh->cid);
-+ len = __le16_to_cpu(lh->len);
-+
-+ BT_DBG("len %d, cid 0x%4.4x", len, cid);
-+
-+ switch (cid) {
-+ case 0x0001:
-+ l2cap_sig_channel(conn, skb);
-+ break;
-+
-+ case 0x0002:
-+ psm = get_unaligned((__u16 *) skb->data);
-+ skb_pull(skb, 2);
-+ l2cap_conless_channel(conn, psm, skb);
-+ break;
-+
-+ default:
-+ l2cap_data_channel(conn, cid, skb);
-+ break;
-+ }
-+}
-+
-+/* ------------ L2CAP interface with lower layer (HCI) ------------- */
-+
-+static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
-+{
-+ int exact = 0, lm1 = 0, lm2 = 0;
-+ register struct sock *sk;
-+
-+ if (type != ACL_LINK)
-+ return 0;
-+
-+ BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
-+
-+ /* Find listening sockets and check their link_mode */
-+ read_lock(&l2cap_sk_list.lock);
-+ for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-+ if (sk->state != BT_LISTEN)
-+ continue;
-+
-+ if (!bacmp(&bluez_pi(sk)->src, &hdev->bdaddr)) {
-+ lm1 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode);
-+ exact++;
-+ } else if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
-+ lm2 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode);
-+ }
-+ read_unlock(&l2cap_sk_list.lock);
-+
-+ return exact ? lm1 : lm2;
-+}
-+
-+static int l2cap_connect_cfm(struct hci_conn *hcon, __u8 status)
-+{
-+ BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
-+
-+ if (hcon->type != ACL_LINK)
-+ return 0;
-+
-+ if (!status) {
-+ struct l2cap_conn *conn;
-+
-+ conn = l2cap_conn_add(hcon, status);
-+ if (conn)
-+ l2cap_conn_ready(conn);
-+ } else
-+ l2cap_conn_del(hcon, bterr(status));
-+
-+ return 0;
-+}
-+
-+static int l2cap_disconn_ind(struct hci_conn *hcon, __u8 reason)
-+{
-+ BT_DBG("hcon %p reason %d", hcon, reason);
-+
-+ if (hcon->type != ACL_LINK)
-+ return 0;
-+
-+ l2cap_conn_del(hcon, bterr(reason));
-+ return 0;
-+}
-+
-+static int l2cap_auth_cfm(struct hci_conn *hcon, __u8 status)
-+{
-+ struct l2cap_chan_list *l;
-+ struct l2cap_conn *conn;
-+ l2cap_conn_rsp rsp;
-+ struct sock *sk;
-+ int result;
-+
-+ if (!(conn = hcon->l2cap_data))
-+ return 0;
-+ l = &conn->chan_list;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ bh_lock_sock(sk);
-+
-+ if (sk->state != BT_CONNECT2 ||
-+ (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT)) {
-+ bh_unlock_sock(sk);
-+ continue;
-+ }
-+
-+ if (!status) {
-+ sk->state = BT_CONFIG;
-+ result = 0;
-+ } else {
-+ sk->state = BT_DISCONN;
-+ l2cap_sock_set_timer(sk, HZ/10);
-+ result = L2CAP_CR_SEC_BLOCK;
-+ }
-+
-+ rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ rsp.result = __cpu_to_le16(result);
-+ rsp.status = __cpu_to_le16(0);
-+ l2cap_send_rsp(conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP,
-+ L2CAP_CONN_RSP_SIZE, &rsp);
-+
-+ bh_unlock_sock(sk);
-+ }
-+
-+ read_unlock(&l->lock);
-+ return 0;
-+}
-+
-+static int l2cap_encrypt_cfm(struct hci_conn *hcon, __u8 status)
-+{
-+ struct l2cap_chan_list *l;
-+ struct l2cap_conn *conn;
-+ l2cap_conn_rsp rsp;
-+ struct sock *sk;
-+ int result;
-+
-+ if (!(conn = hcon->l2cap_data))
-+ return 0;
-+ l = &conn->chan_list;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ bh_lock_sock(sk);
-+
-+ if (sk->state != BT_CONNECT2) {
-+ bh_unlock_sock(sk);
-+ continue;
-+ }
-+
-+ if (!status) {
-+ sk->state = BT_CONFIG;
-+ result = 0;
-+ } else {
-+ sk->state = BT_DISCONN;
-+ l2cap_sock_set_timer(sk, HZ/10);
-+ result = L2CAP_CR_SEC_BLOCK;
-+ }
-+
-+ rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ rsp.result = __cpu_to_le16(result);
-+ rsp.status = __cpu_to_le16(0);
-+ l2cap_send_rsp(conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP,
-+ L2CAP_CONN_RSP_SIZE, &rsp);
-+
-+ bh_unlock_sock(sk);
-+ }
-+
-+ read_unlock(&l->lock);
-+ return 0;
-+}
-+
-+static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, __u16 flags)
-+{
-+ struct l2cap_conn *conn = hcon->l2cap_data;
-+
-+ if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
-+ goto drop;
-+
-+ BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
-+
-+ if (flags & ACL_START) {
-+ l2cap_hdr *hdr;
-+ int len;
-+
-+ if (conn->rx_len) {
-+ BT_ERR("Unexpected start frame (len %d)", skb->len);
-+ kfree_skb(conn->rx_skb);
-+ conn->rx_skb = NULL;
-+ conn->rx_len = 0;
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ }
-+
-+ if (skb->len < 2) {
-+ BT_ERR("Frame is too short (len %d)", skb->len);
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ goto drop;
-+ }
-+
-+ hdr = (l2cap_hdr *) skb->data;
-+ len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
-+
-+ if (len == skb->len) {
-+ /* Complete frame received */
-+ l2cap_recv_frame(conn, skb);
-+ return 0;
-+ }
-+
-+ BT_DBG("Start: total len %d, frag len %d", len, skb->len);
-+
-+ if (skb->len > len) {
-+ BT_ERR("Frame is too long (len %d, expected len %d)",
-+ skb->len, len);
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ goto drop;
-+ }
-+
-+ /* Allocate skb for the complete frame including header */
-+ conn->rx_skb = bluez_skb_alloc(len, GFP_ATOMIC);
-+ if (!conn->rx_skb)
-+ goto drop;
-+
-+ memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
-+ conn->rx_len = len - skb->len;
-+ } else {
-+ BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
-+
-+ if (!conn->rx_len) {
-+ BT_ERR("Unexpected continuation frame (len %d)", skb->len);
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ goto drop;
-+ }
-+
-+ if (skb->len > conn->rx_len) {
-+ BT_ERR("Fragment is too long (len %d, expected %d)",
-+ skb->len, conn->rx_len);
-+ kfree_skb(conn->rx_skb);
-+ conn->rx_skb = NULL;
-+ conn->rx_len = 0;
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ goto drop;
-+ }
-+
-+ memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
-+ conn->rx_len -= skb->len;
-+
-+ if (!conn->rx_len) {
-+ /* Complete frame received */
-+ l2cap_recv_frame(conn, conn->rx_skb);
-+ conn->rx_skb = NULL;
-+ }
-+ }
-+
-+drop:
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+/* ----- Proc fs support ------ */
-+static int l2cap_sock_dump(char *buf, struct bluez_sock_list *list)
-+{
-+ struct l2cap_pinfo *pi;
-+ struct sock *sk;
-+ char *ptr = buf;
-+
-+ read_lock_bh(&list->lock);
-+
-+ for (sk = list->head; sk; sk = sk->next) {
-+ pi = l2cap_pi(sk);
-+ ptr += sprintf(ptr, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n",
-+ batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
-+ sk->state, pi->psm, pi->scid, pi->dcid, pi->imtu, pi->omtu,
-+ pi->link_mode);
-+ }
-+
-+ read_unlock_bh(&list->lock);
-+
-+ ptr += sprintf(ptr, "\n");
-+ return ptr - buf;
-+}
-+
-+static int l2cap_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
-+{
-+ char *ptr = buf;
-+ int len;
-+
-+ BT_DBG("count %d, offset %ld", count, offset);
-+
-+ ptr += l2cap_sock_dump(ptr, &l2cap_sk_list);
-+ len = ptr - buf;
-+
-+ if (len <= count + offset)
-+ *eof = 1;
-+
-+ *start = buf + offset;
-+ len -= offset;
-+
-+ if (len > count)
-+ len = count;
-+ if (len < 0)
-+ len = 0;
-+
-+ return len;
-+}
-+
-+static struct proto_ops l2cap_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: l2cap_sock_release,
-+ bind: l2cap_sock_bind,
-+ connect: l2cap_sock_connect,
-+ listen: l2cap_sock_listen,
-+ accept: l2cap_sock_accept,
-+ getname: l2cap_sock_getname,
-+ sendmsg: l2cap_sock_sendmsg,
-+ recvmsg: bluez_sock_recvmsg,
-+ poll: bluez_sock_poll,
-+ socketpair: sock_no_socketpair,
-+ ioctl: sock_no_ioctl,
-+ shutdown: l2cap_sock_shutdown,
-+ setsockopt: l2cap_sock_setsockopt,
-+ getsockopt: l2cap_sock_getsockopt,
-+ mmap: sock_no_mmap
-+};
-+
-+static struct net_proto_family l2cap_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: l2cap_sock_create
-+};
-+
-+static struct hci_proto l2cap_hci_proto = {
-+ name: "L2CAP",
-+ id: HCI_PROTO_L2CAP,
-+ connect_ind: l2cap_connect_ind,
-+ connect_cfm: l2cap_connect_cfm,
-+ disconn_ind: l2cap_disconn_ind,
-+ recv_acldata: l2cap_recv_acldata,
-+ auth_cfm: l2cap_auth_cfm,
-+ encrypt_cfm: l2cap_encrypt_cfm
-+};
-+
-+int __init l2cap_init(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops))) {
-+ BT_ERR("Can't register L2CAP socket");
-+ return err;
-+ }
-+
-+ if ((err = hci_register_proto(&l2cap_hci_proto))) {
-+ BT_ERR("Can't register L2CAP protocol");
-+ return err;
-+ }
-+
-+ create_proc_read_entry("bluetooth/l2cap", 0, 0, l2cap_read_proc, NULL);
-+
-+ BT_INFO("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ return 0;
-+}
-+
-+void l2cap_cleanup(void)
-+{
-+ remove_proc_entry("bluetooth/l2cap", NULL);
-+
-+ /* Unregister socket and protocol */
-+ if (bluez_sock_unregister(BTPROTO_L2CAP))
-+ BT_ERR("Can't unregister L2CAP socket");
-+
-+ if (hci_unregister_proto(&l2cap_hci_proto))
-+ BT_ERR("Can't unregister L2CAP protocol");
-+}
-+
-+void l2cap_load(void)
-+{
-+ /* Dummy function to trigger automatic L2CAP module loading by
-+ other modules that use L2CAP sockets but do not use any other
-+ symbols from it. */
-+ return;
-+}
-+
-+EXPORT_SYMBOL(l2cap_load);
-+
-+module_init(l2cap_init);
-+module_exit(l2cap_cleanup);
-+
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
-+MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/l2cap_core.c linux-2.4.18-mh15/net/bluetooth/l2cap_core.c
---- linux-2.4.18/net/bluetooth/l2cap_core.c 2001-09-30 21:26:08.000000000 +0200
-+++ linux-2.4.18-mh15/net/bluetooth/l2cap_core.c 1970-01-01 01:00:00.000000000 +0100
-@@ -1,2316 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * BlueZ L2CAP core and sockets.
-- *
-- * $Id$
-- */
--#define VERSION "1.1"
--
--#include <linux/config.h>
--#include <linux/module.h>
--
--#include <linux/types.h>
--#include <linux/errno.h>
--#include <linux/kernel.h>
--#include <linux/major.h>
--#include <linux/sched.h>
--#include <linux/slab.h>
--#include <linux/poll.h>
--#include <linux/fcntl.h>
--#include <linux/init.h>
--#include <linux/skbuff.h>
--#include <linux/interrupt.h>
--#include <linux/socket.h>
--#include <linux/skbuff.h>
--#include <linux/proc_fs.h>
--#include <linux/list.h>
--#include <net/sock.h>
--
--#include <asm/system.h>
--#include <asm/uaccess.h>
--
--#include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
--#include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/l2cap.h>
--#include <net/bluetooth/l2cap_core.h>
--
--#ifndef L2CAP_DEBUG
--#undef DBG
--#define DBG( A... )
--#endif
--
--struct proto_ops l2cap_sock_ops;
--
--struct bluez_sock_list l2cap_sk_list = {
-- lock: RW_LOCK_UNLOCKED
--};
--
--struct list_head l2cap_iff_list = LIST_HEAD_INIT(l2cap_iff_list);
--rwlock_t l2cap_rt_lock = RW_LOCK_UNLOCKED;
--
--static int l2cap_conn_del(struct l2cap_conn *conn, int err);
--
--static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
--static void l2cap_chan_del(struct sock *sk, int err);
--static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len);
--
--static void l2cap_sock_close(struct sock *sk);
--static void l2cap_sock_kill(struct sock *sk);
--
--static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data);
--static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data);
--
--/* -------- L2CAP interfaces & routing --------- */
--/* Add/delete L2CAP interface.
-- * Must be called with locked rt_lock
-- */
--
--static void l2cap_iff_add(struct hci_dev *hdev)
--{
-- struct l2cap_iff *iff;
--
-- DBG("%s", hdev->name);
--
-- DBG("iff_list %p next %p prev %p", &l2cap_iff_list, l2cap_iff_list.next, l2cap_iff_list.prev);
--
-- /* Allocate new interface and lock HCI device */
-- if (!(iff = kmalloc(sizeof(struct l2cap_iff), GFP_KERNEL))) {
-- ERR("Can't allocate new interface %s", hdev->name);
-- return;
-- }
-- memset(iff, 0, sizeof(struct l2cap_iff));
--
-- hci_dev_hold(hdev);
-- hdev->l2cap_data = iff;
-- iff->hdev = hdev;
-- iff->mtu = hdev->acl_mtu - HCI_ACL_HDR_SIZE;
-- iff->bdaddr = &hdev->bdaddr;
--
-- spin_lock_init(&iff->lock);
-- INIT_LIST_HEAD(&iff->conn_list);
--
-- list_add(&iff->list, &l2cap_iff_list);
--}
--
--static void l2cap_iff_del(struct hci_dev *hdev)
--{
-- struct l2cap_iff *iff;
--
-- if (!(iff = hdev->l2cap_data))
-- return;
--
-- DBG("%s iff %p", hdev->name, iff);
--
-- list_del(&iff->list);
--
-- l2cap_iff_lock(iff);
--
-- /* Drop connections */
-- while (!list_empty(&iff->conn_list)) {
-- struct l2cap_conn *c;
--
-- c = list_entry(iff->conn_list.next, struct l2cap_conn, list);
-- l2cap_conn_del(c, ENODEV);
-- }
--
-- l2cap_iff_unlock(iff);
--
-- /* Unlock HCI device */
-- hdev->l2cap_data = NULL;
-- hci_dev_put(hdev);
--
-- kfree(iff);
--}
--
--/* Get route. Returns L2CAP interface.
-- * Must be called with locked rt_lock
-- */
--static struct l2cap_iff *l2cap_get_route(bdaddr_t *src, bdaddr_t *dst)
--{
-- struct list_head *p;
-- int use_src;
--
-- DBG("%s -> %s", batostr(src), batostr(dst));
--
-- use_src = bacmp(src, BDADDR_ANY) ? 0 : 1;
--
-- /* Simple routing:
-- * No source address - find interface with bdaddr != dst
-- * Source address - find interface with bdaddr == src
-- */
--
-- list_for_each(p, &l2cap_iff_list) {
-- struct l2cap_iff *iff;
--
-- iff = list_entry(p, struct l2cap_iff, list);
--
-- if (use_src && !bacmp(iff->bdaddr, src))
-- return iff;
-- else if (bacmp(iff->bdaddr, dst))
-- return iff;
-- }
-- return NULL;
--}
--
--/* ----- L2CAP timers ------ */
--static void l2cap_sock_timeout(unsigned long arg)
--{
-- struct sock *sk = (struct sock *) arg;
--
-- DBG("sock %p state %d", sk, sk->state);
--
-- bh_lock_sock(sk);
-- switch (sk->state) {
-- case BT_DISCONN:
-- l2cap_chan_del(sk, ETIMEDOUT);
-- break;
--
-- default:
-- sk->err = ETIMEDOUT;
-- sk->state_change(sk);
-- break;
-- };
-- bh_unlock_sock(sk);
--
-- l2cap_sock_kill(sk);
-- sock_put(sk);
--}
--
--static void l2cap_sock_set_timer(struct sock *sk, long timeout)
--{
-- DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
--
-- if (!mod_timer(&sk->timer, jiffies + timeout))
-- sock_hold(sk);
--}
--
--static void l2cap_sock_clear_timer(struct sock *sk)
--{
-- DBG("sock %p state %d", sk, sk->state);
--
-- if (timer_pending(&sk->timer) && del_timer(&sk->timer))
-- __sock_put(sk);
--}
--
--static void l2cap_sock_init_timer(struct sock *sk)
--{
-- init_timer(&sk->timer);
-- sk->timer.function = l2cap_sock_timeout;
-- sk->timer.data = (unsigned long)sk;
--}
--
--static void l2cap_conn_timeout(unsigned long arg)
--{
-- struct l2cap_conn *conn = (void *)arg;
--
-- DBG("conn %p state %d", conn, conn->state);
--
-- if (conn->state == BT_CONNECTED) {
-- hci_disconnect(conn->hconn, 0x13);
-- }
--
-- return;
--}
--
--static void l2cap_conn_set_timer(struct l2cap_conn *conn, long timeout)
--{
-- DBG("conn %p state %d timeout %ld", conn, conn->state, timeout);
--
-- mod_timer(&conn->timer, jiffies + timeout);
--}
--
--static void l2cap_conn_clear_timer(struct l2cap_conn *conn)
--{
-- DBG("conn %p state %d", conn, conn->state);
--
-- del_timer(&conn->timer);
--}
--
--static void l2cap_conn_init_timer(struct l2cap_conn *conn)
--{
-- init_timer(&conn->timer);
-- conn->timer.function = l2cap_conn_timeout;
-- conn->timer.data = (unsigned long)conn;
--}
--
--/* -------- L2CAP connections --------- */
--/* Add new connection to the interface.
-- * Interface must be locked
-- */
--static struct l2cap_conn *l2cap_conn_add(struct l2cap_iff *iff, bdaddr_t *dst)
--{
-- struct l2cap_conn *conn;
-- bdaddr_t *src = iff->bdaddr;
--
-- if (!(conn = kmalloc(sizeof(struct l2cap_conn), GFP_KERNEL)))
-- return NULL;
--
-- memset(conn, 0, sizeof(struct l2cap_conn));
--
-- conn->state = BT_OPEN;
-- conn->iff = iff;
-- bacpy(&conn->src, src);
-- bacpy(&conn->dst, dst);
--
-- spin_lock_init(&conn->lock);
-- conn->chan_list.lock = RW_LOCK_UNLOCKED;
--
-- l2cap_conn_init_timer(conn);
--
-- __l2cap_conn_link(iff, conn);
--
-- DBG("%s -> %s, %p", batostr(src), batostr(dst), conn);
--
-- MOD_INC_USE_COUNT;
--
-- return conn;
--}
--
--/* Delete connection on the interface.
-- * Interface must be locked
-- */
--static int l2cap_conn_del(struct l2cap_conn *conn, int err)
--{
-- struct sock *sk;
--
-- DBG("conn %p, state %d, err %d", conn, conn->state, err);
--
-- l2cap_conn_clear_timer(conn);
-- __l2cap_conn_unlink(conn->iff, conn);
--
-- conn->state = BT_CLOSED;
--
-- if (conn->rx_skb)
-- kfree_skb(conn->rx_skb);
--
-- /* Kill channels */
-- while ((sk = conn->chan_list.head)) {
-- bh_lock_sock(sk);
-- l2cap_sock_clear_timer(sk);
-- l2cap_chan_del(sk, err);
-- bh_unlock_sock(sk);
--
-- l2cap_sock_kill(sk);
-- }
--
-- kfree(conn);
--
-- MOD_DEC_USE_COUNT;
-- return 0;
--}
--
--static inline struct l2cap_conn *l2cap_get_conn_by_addr(struct l2cap_iff *iff, bdaddr_t *dst)
--{
-- struct list_head *p;
--
-- list_for_each(p, &iff->conn_list) {
-- struct l2cap_conn *c;
--
-- c = list_entry(p, struct l2cap_conn, list);
-- if (!bacmp(&c->dst, dst))
-- return c;
-- }
-- return NULL;
--}
--
--int l2cap_connect(struct sock *sk)
--{
-- bdaddr_t *src = &l2cap_pi(sk)->src;
-- bdaddr_t *dst = &l2cap_pi(sk)->dst;
-- struct l2cap_conn *conn;
-- struct l2cap_iff *iff;
-- int err = 0;
--
-- DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
--
-- read_lock_bh(&l2cap_rt_lock);
--
-- /* Get route to remote BD address */
-- if (!(iff = l2cap_get_route(src, dst))) {
-- err = -EHOSTUNREACH;
-- goto done;
-- }
--
-- /* Update source addr of the socket */
-- bacpy(src, iff->bdaddr);
--
-- l2cap_iff_lock(iff);
--
-- if (!(conn = l2cap_get_conn_by_addr(iff, dst))) {
-- /* Connection doesn't exist */
-- if (!(conn = l2cap_conn_add(iff, dst))) {
-- l2cap_iff_unlock(iff);
-- err = -ENOMEM;
-- goto done;
-- }
-- conn->out = 1;
-- }
--
-- l2cap_iff_unlock(iff);
--
-- l2cap_chan_add(conn, sk, NULL);
--
-- sk->state = BT_CONNECT;
-- l2cap_sock_set_timer(sk, sk->sndtimeo);
--
-- switch (conn->state) {
-- case BT_CONNECTED:
-- if (sk->type == SOCK_SEQPACKET) {
-- l2cap_conn_req req;
-- req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- req.psm = l2cap_pi(sk)->psm;
-- l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
-- } else {
-- l2cap_sock_clear_timer(sk);
-- sk->state = BT_CONNECTED;
-- }
-- break;
--
-- case BT_CONNECT:
-- break;
--
-- default:
-- /* Create ACL connection */
-- conn->state = BT_CONNECT;
-- hci_connect(iff->hdev, dst);
-- break;
-- };
--
--done:
-- read_unlock_bh(&l2cap_rt_lock);
-- return err;
--}
--
--/* ------ Channel queues for listening sockets ------ */
--void l2cap_accept_queue(struct sock *parent, struct sock *sk)
--{
-- struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
--
-- DBG("parent %p, sk %p", parent, sk);
--
-- sock_hold(sk);
-- l2cap_pi(sk)->parent = parent;
-- l2cap_pi(sk)->next_q = NULL;
--
-- if (!q->head) {
-- q->head = q->tail = sk;
-- } else {
-- struct sock *tail = q->tail;
--
-- l2cap_pi(sk)->prev_q = tail;
-- l2cap_pi(tail)->next_q = sk;
-- q->tail = sk;
-- }
--
-- parent->ack_backlog++;
--}
--
--void l2cap_accept_unlink(struct sock *sk)
--{
-- struct sock *parent = l2cap_pi(sk)->parent;
-- struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
-- struct sock *next, *prev;
--
-- DBG("sk %p", sk);
--
-- next = l2cap_pi(sk)->next_q;
-- prev = l2cap_pi(sk)->prev_q;
--
-- if (sk == q->head)
-- q->head = next;
-- if (sk == q->tail)
-- q->tail = prev;
--
-- if (next)
-- l2cap_pi(next)->prev_q = prev;
-- if (prev)
-- l2cap_pi(prev)->next_q = next;
--
-- l2cap_pi(sk)->parent = NULL;
--
-- parent->ack_backlog--;
-- __sock_put(sk);
--}
--
--/* Get next connected channel in queue. */
--struct sock *l2cap_accept_dequeue(struct sock *parent, int state)
--{
-- struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
-- struct sock *sk;
--
-- for (sk = q->head; sk; sk = l2cap_pi(sk)->next_q) {
-- if (!state || sk->state == state) {
-- l2cap_accept_unlink(sk);
-- break;
-- }
-- }
--
-- DBG("parent %p, sk %p", parent, sk);
--
-- return sk;
--}
--
--/* -------- Socket interface ---------- */
--static struct sock *__l2cap_get_sock_by_addr(struct sockaddr_l2 *addr)
--{
-- bdaddr_t *src = &addr->l2_bdaddr;
-- __u16 psm = addr->l2_psm;
-- struct sock *sk;
--
-- for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-- if (l2cap_pi(sk)->psm == psm &&
-- !bacmp(&l2cap_pi(sk)->src, src))
-- break;
-- }
--
-- return sk;
--}
--
--/* Find socket listening on psm and source bdaddr.
-- * Returns closest match.
-- */
--static struct sock *l2cap_get_sock_listen(bdaddr_t *src, __u16 psm)
--{
-- struct sock *sk, *sk1 = NULL;
--
-- read_lock(&l2cap_sk_list.lock);
--
-- for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-- struct l2cap_pinfo *pi;
--
-- if (sk->state != BT_LISTEN)
-- continue;
--
-- pi = l2cap_pi(sk);
--
-- if (pi->psm == psm) {
-- /* Exact match. */
-- if (!bacmp(&pi->src, src))
-- break;
--
-- /* Closest match */
-- if (!bacmp(&pi->src, BDADDR_ANY))
-- sk1 = sk;
-- }
-- }
--
-- read_unlock(&l2cap_sk_list.lock);
--
-- return sk ? sk : sk1;
--}
--
--static void l2cap_sock_destruct(struct sock *sk)
--{
-- DBG("sk %p", sk);
--
-- skb_queue_purge(&sk->receive_queue);
-- skb_queue_purge(&sk->write_queue);
--
-- MOD_DEC_USE_COUNT;
--}
--
--static void l2cap_sock_cleanup_listen(struct sock *parent)
--{
-- struct sock *sk;
--
-- DBG("parent %p", parent);
--
-- /* Close not yet accepted channels */
-- while ((sk = l2cap_accept_dequeue(parent, 0)))
-- l2cap_sock_close(sk);
--
-- parent->state = BT_CLOSED;
-- parent->zapped = 1;
--}
--
--/* Kill socket (only if zapped and orphan)
-- * Must be called on unlocked socket.
-- */
--static void l2cap_sock_kill(struct sock *sk)
--{
-- if (!sk->zapped || sk->socket)
-- return;
--
-- DBG("sk %p state %d", sk, sk->state);
--
-- /* Kill poor orphan */
-- bluez_sock_unlink(&l2cap_sk_list, sk);
-- sk->dead = 1;
-- sock_put(sk);
--}
--
--/* Close socket.
-- * Must be called on unlocked socket.
-- */
--static void l2cap_sock_close(struct sock *sk)
--{
-- struct l2cap_conn *conn;
--
-- l2cap_sock_clear_timer(sk);
--
-- lock_sock(sk);
--
-- conn = l2cap_pi(sk)->conn;
--
-- DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
--
-- switch (sk->state) {
-- case BT_LISTEN:
-- l2cap_sock_cleanup_listen(sk);
-- break;
--
-- case BT_CONNECTED:
-- case BT_CONFIG:
-- if (sk->type == SOCK_SEQPACKET) {
-- l2cap_disconn_req req;
--
-- sk->state = BT_DISCONN;
--
-- req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
--
-- l2cap_sock_set_timer(sk, sk->sndtimeo);
-- } else {
-- l2cap_chan_del(sk, ECONNRESET);
-- }
-- break;
--
-- case BT_CONNECT:
-- case BT_DISCONN:
-- l2cap_chan_del(sk, ECONNRESET);
-- break;
--
-- default:
-- sk->zapped = 1;
-- break;
-- };
--
-- release_sock(sk);
--
-- l2cap_sock_kill(sk);
--}
--
--static void l2cap_sock_init(struct sock *sk, struct sock *parent)
--{
-- struct l2cap_pinfo *pi = l2cap_pi(sk);
--
-- DBG("sk %p", sk);
--
-- if (parent) {
-- sk->type = parent->type;
--
-- pi->imtu = l2cap_pi(parent)->imtu;
-- pi->omtu = l2cap_pi(parent)->omtu;
-- } else {
-- pi->imtu = L2CAP_DEFAULT_MTU;
-- pi->omtu = 0;
-- }
--
-- /* Default config options */
-- pi->conf_mtu = L2CAP_DEFAULT_MTU;
-- pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
--}
--
--static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
--{
-- struct sock *sk;
--
-- if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
-- return NULL;
--
-- sock_init_data(sock, sk);
--
-- sk->zapped = 0;
--
-- sk->destruct = l2cap_sock_destruct;
-- sk->sndtimeo = L2CAP_CONN_TIMEOUT;
--
-- sk->protocol = proto;
-- sk->state = BT_OPEN;
--
-- l2cap_sock_init_timer(sk);
--
-- bluez_sock_link(&l2cap_sk_list, sk);
--
-- MOD_INC_USE_COUNT;
--
-- return sk;
--}
--
--static int l2cap_sock_create(struct socket *sock, int protocol)
--{
-- struct sock *sk;
--
-- DBG("sock %p", sock);
--
-- sock->state = SS_UNCONNECTED;
--
-- if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_RAW)
-- return -ESOCKTNOSUPPORT;
--
-- sock->ops = &l2cap_sock_ops;
--
-- if (!(sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL)))
-- return -ENOMEM;
--
-- l2cap_sock_init(sk, NULL);
--
-- return 0;
--}
--
--static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
--{
-- struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-- struct sock *sk = sock->sk;
-- int err = 0;
--
-- DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
--
-- if (!addr || addr->sa_family != AF_BLUETOOTH)
-- return -EINVAL;
--
-- lock_sock(sk);
--
-- if (sk->state != BT_OPEN) {
-- err = -EBADFD;
-- goto done;
-- }
--
-- write_lock(&l2cap_sk_list.lock);
--
-- if (la->l2_psm && __l2cap_get_sock_by_addr(la)) {
-- err = -EADDRINUSE;
-- goto unlock;
-- }
--
-- /* Save source address */
-- bacpy(&l2cap_pi(sk)->src, &la->l2_bdaddr);
-- l2cap_pi(sk)->psm = la->l2_psm;
-- sk->state = BT_BOUND;
--
--unlock:
-- write_unlock(&l2cap_sk_list.lock);
--
--done:
-- release_sock(sk);
--
-- return err;
--}
--
--static int l2cap_sock_w4_connect(struct sock *sk, int flags)
--{
-- DECLARE_WAITQUEUE(wait, current);
-- long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
-- int err = 0;
--
-- DBG("sk %p", sk);
--
-- add_wait_queue(sk->sleep, &wait);
-- current->state = TASK_INTERRUPTIBLE;
--
-- while (sk->state != BT_CONNECTED) {
-- if (!timeo) {
-- err = -EAGAIN;
-- break;
-- }
--
-- release_sock(sk);
-- timeo = schedule_timeout(timeo);
-- lock_sock(sk);
--
-- err = 0;
-- if (sk->state == BT_CONNECTED)
-- break;
--
-- if (sk->err) {
-- err = sock_error(sk);
-- break;
-- }
--
-- if (signal_pending(current)) {
-- err = sock_intr_errno(timeo);
-- break;
-- }
-- }
-- current->state = TASK_RUNNING;
-- remove_wait_queue(sk->sleep, &wait);
--
-- return err;
--}
--
--static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
--{
-- struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-- struct sock *sk = sock->sk;
-- int err = 0;
--
-- lock_sock(sk);
--
-- DBG("sk %p", sk);
--
-- if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) {
-- err = -EINVAL;
-- goto done;
-- }
--
-- if (sk->state != BT_OPEN && sk->state != BT_BOUND) {
-- err = -EBADFD;
-- goto done;
-- }
--
-- if (sk->type == SOCK_SEQPACKET && !la->l2_psm) {
-- err = -EINVAL;
-- goto done;
-- }
--
-- /* Set destination address and psm */
-- bacpy(&l2cap_pi(sk)->dst, &la->l2_bdaddr);
-- l2cap_pi(sk)->psm = la->l2_psm;
--
-- if ((err = l2cap_connect(sk)))
-- goto done;
--
-- err = l2cap_sock_w4_connect(sk, flags);
--
--done:
-- release_sock(sk);
-- return err;
--}
--
--int l2cap_sock_listen(struct socket *sock, int backlog)
--{
-- struct sock *sk = sock->sk;
-- int err = 0;
--
-- DBG("sk %p backlog %d", sk, backlog);
--
-- lock_sock(sk);
--
-- if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
-- err = -EBADFD;
-- goto done;
-- }
--
-- if (!l2cap_pi(sk)->psm) {
-- err = -EINVAL;
-- goto done;
-- }
--
-- sk->max_ack_backlog = backlog;
-- sk->ack_backlog = 0;
-- sk->state = BT_LISTEN;
--
--done:
-- release_sock(sk);
-- return err;
--}
--
--int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
--{
-- DECLARE_WAITQUEUE(wait, current);
-- struct sock *sk = sock->sk, *ch;
-- long timeo;
-- int err = 0;
--
-- lock_sock(sk);
--
-- if (sk->state != BT_LISTEN) {
-- err = -EBADFD;
-- goto done;
-- }
--
-- timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
--
-- DBG("sk %p timeo %ld", sk, timeo);
--
-- /* Wait for an incoming connection. (wake-one). */
-- add_wait_queue_exclusive(sk->sleep, &wait);
-- current->state = TASK_INTERRUPTIBLE;
-- while (!(ch = l2cap_accept_dequeue(sk, BT_CONNECTED))) {
-- if (!timeo) {
-- err = -EAGAIN;
-- break;
-- }
--
-- release_sock(sk);
-- timeo = schedule_timeout(timeo);
-- lock_sock(sk);
--
-- if (sk->state != BT_LISTEN) {
-- err = -EBADFD;
-- break;
-- }
--
-- if (signal_pending(current)) {
-- err = sock_intr_errno(timeo);
-- break;
-- }
-- }
-- current->state = TASK_RUNNING;
-- remove_wait_queue(sk->sleep, &wait);
--
-- if (err)
-- goto done;
--
-- sock_graft(ch, newsock);
-- newsock->state = SS_CONNECTED;
--
-- DBG("new socket %p", ch);
--
--done:
-- release_sock(sk);
--
-- return err;
--}
--
--static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
--{
-- struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-- struct sock *sk = sock->sk;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- addr->sa_family = AF_BLUETOOTH;
-- *len = sizeof(struct sockaddr_l2);
--
-- if (peer)
-- bacpy(&la->l2_bdaddr, &l2cap_pi(sk)->dst);
-- else
-- bacpy(&la->l2_bdaddr, &l2cap_pi(sk)->src);
--
-- la->l2_psm = l2cap_pi(sk)->psm;
--
-- return 0;
--}
--
--static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
--{
-- struct sock *sk = sock->sk;
-- int err = 0;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- if (sk->err)
-- return sock_error(sk);
--
-- if (msg->msg_flags & MSG_OOB)
-- return -EOPNOTSUPP;
--
-- lock_sock(sk);
--
-- if (sk->state == BT_CONNECTED)
-- err = l2cap_chan_send(sk, msg, len);
-- else
-- err = -ENOTCONN;
--
-- release_sock(sk);
-- return err;
--}
--
--static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
--{
-- struct sock *sk = sock->sk;
-- int noblock = flags & MSG_DONTWAIT;
-- int copied, err;
-- struct sk_buff *skb;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- if (flags & (MSG_OOB))
-- return -EOPNOTSUPP;
--
-- if (sk->state == BT_CLOSED)
-- return 0;
--
-- if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
-- return err;
--
-- msg->msg_namelen = 0;
--
-- copied = skb->len;
-- if (len < copied) {
-- msg->msg_flags |= MSG_TRUNC;
-- copied = len;
-- }
--
-- skb->h.raw = skb->data;
-- err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
--
-- skb_free_datagram(sk, skb);
--
-- return err ? : copied;
--}
--
--int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
--{
-- struct sock *sk = sock->sk;
-- struct l2cap_options opts;
-- int err = 0;
--
-- DBG("sk %p", sk);
--
-- lock_sock(sk);
--
-- switch (optname) {
-- case L2CAP_OPTIONS:
-- if (copy_from_user((char *)&opts, optval, optlen)) {
-- err = -EFAULT;
-- break;
-- }
-- l2cap_pi(sk)->imtu = opts.imtu;
-- l2cap_pi(sk)->omtu = opts.omtu;
-- break;
--
-- default:
-- err = -ENOPROTOOPT;
-- break;
-- };
--
-- release_sock(sk);
-- return err;
--}
--
--int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
--{
-- struct sock *sk = sock->sk;
-- struct l2cap_options opts;
-- struct l2cap_conninfo cinfo;
-- int len, err = 0;
--
-- if (get_user(len, optlen))
-- return -EFAULT;
--
-- lock_sock(sk);
--
-- switch (optname) {
-- case L2CAP_OPTIONS:
-- opts.imtu = l2cap_pi(sk)->imtu;
-- opts.omtu = l2cap_pi(sk)->omtu;
-- opts.flush_to = l2cap_pi(sk)->flush_to;
--
-- len = MIN(len, sizeof(opts));
-- if (copy_to_user(optval, (char *)&opts, len))
-- err = -EFAULT;
--
-- break;
--
-- case L2CAP_CONNINFO:
-- if (sk->state != BT_CONNECTED) {
-- err = -ENOTCONN;
-- break;
-- }
--
-- cinfo.hci_handle = l2cap_pi(sk)->conn->hconn->handle;
--
-- len = MIN(len, sizeof(cinfo));
-- if (copy_to_user(optval, (char *)&cinfo, len))
-- err = -EFAULT;
--
-- break;
--
-- default:
-- err = -ENOPROTOOPT;
-- break;
-- };
--
-- release_sock(sk);
-- return err;
--}
--
--static unsigned int l2cap_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
--{
-- struct sock *sk = sock->sk;
-- struct l2cap_accept_q *aq;
-- unsigned int mask;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- poll_wait(file, sk->sleep, wait);
-- mask = 0;
--
-- if (sk->err || !skb_queue_empty(&sk->error_queue))
-- mask |= POLLERR;
--
-- if (sk->shutdown == SHUTDOWN_MASK)
-- mask |= POLLHUP;
--
-- aq = &l2cap_pi(sk)->accept_q;
-- if (!skb_queue_empty(&sk->receive_queue) || aq->head || (sk->shutdown & RCV_SHUTDOWN))
-- mask |= POLLIN | POLLRDNORM;
--
-- if (sk->state == BT_CLOSED)
-- mask |= POLLHUP;
--
-- if (sock_writeable(sk))
-- mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
-- else
-- set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
--
-- return mask;
--}
--
--static int l2cap_sock_release(struct socket *sock)
--{
-- struct sock *sk = sock->sk;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- if (!sk)
-- return 0;
--
-- sock_orphan(sk);
--
-- l2cap_sock_close(sk);
--
-- return 0;
--}
--
--/* --------- L2CAP channels --------- */
--static struct sock * __l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
--{
-- struct sock *s;
--
-- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-- if (l2cap_pi(s)->dcid == cid)
-- break;
-- }
--
-- return s;
--}
--
--static inline struct sock *l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
--{
-- struct sock *s;
--
-- read_lock(&l->lock);
-- s = __l2cap_get_chan_by_dcid(l, cid);
-- read_unlock(&l->lock);
--
-- return s;
--}
--
--static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
--{
-- struct sock *s;
--
-- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-- if (l2cap_pi(s)->scid == cid)
-- break;
-- }
--
-- return s;
--}
--static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
--{
-- struct sock *s;
--
-- read_lock(&l->lock);
-- s = __l2cap_get_chan_by_scid(l, cid);
-- read_unlock(&l->lock);
--
-- return s;
--}
--
--static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
--{
-- struct sock *s;
--
-- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-- if (l2cap_pi(s)->ident == ident)
-- break;
-- }
--
-- return s;
--}
--
--static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
--{
-- struct sock *s;
--
-- read_lock(&l->lock);
-- s = __l2cap_get_chan_by_ident(l, ident);
-- read_unlock(&l->lock);
--
-- return s;
--}
--
--static __u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
--{
-- __u16 cid = 0x0040;
--
-- for (; cid < 0xffff; cid++) {
-- if(!__l2cap_get_chan_by_scid(l, cid))
-- return cid;
-- }
--
-- return 0;
--}
--
--static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
--{
-- sock_hold(sk);
--
-- if (l->head)
-- l2cap_pi(l->head)->prev_c = sk;
--
-- l2cap_pi(sk)->next_c = l->head;
-- l2cap_pi(sk)->prev_c = NULL;
-- l->head = sk;
--}
--
--static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
--{
-- struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
--
-- write_lock(&l->lock);
-- if (sk == l->head)
-- l->head = next;
--
-- if (next)
-- l2cap_pi(next)->prev_c = prev;
-- if (prev)
-- l2cap_pi(prev)->next_c = next;
-- write_unlock(&l->lock);
--
-- __sock_put(sk);
--}
--
--static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
--{
-- struct l2cap_chan_list *l = &conn->chan_list;
--
-- DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
--
-- l2cap_conn_clear_timer(conn);
--
-- atomic_inc(&conn->refcnt);
-- l2cap_pi(sk)->conn = conn;
--
-- if (sk->type == SOCK_SEQPACKET) {
-- /* Alloc CID for normal socket */
-- l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
-- } else {
-- /* Raw socket can send only signalling messages */
-- l2cap_pi(sk)->scid = 0x0001;
-- l2cap_pi(sk)->dcid = 0x0001;
-- l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
-- }
--
-- __l2cap_chan_link(l, sk);
--
-- if (parent)
-- l2cap_accept_queue(parent, sk);
--}
--
--static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
--{
-- struct l2cap_chan_list *l = &conn->chan_list;
--
-- write_lock(&l->lock);
-- __l2cap_chan_add(conn, sk, parent);
-- write_unlock(&l->lock);
--}
--
--/* Delete channel.
-- * Must be called on the locked socket. */
--static void l2cap_chan_del(struct sock *sk, int err)
--{
-- struct l2cap_conn *conn;
-- struct sock *parent;
--
-- conn = l2cap_pi(sk)->conn;
-- parent = l2cap_pi(sk)->parent;
--
-- DBG("sk %p, conn %p, err %d", sk, conn, err);
--
-- if (parent) {
-- /* Unlink from parent accept queue */
-- bh_lock_sock(parent);
-- l2cap_accept_unlink(sk);
-- bh_unlock_sock(parent);
-- }
--
-- if (conn) {
-- long timeout;
--
-- /* Unlink from channel list */
-- l2cap_chan_unlink(&conn->chan_list, sk);
-- l2cap_pi(sk)->conn = NULL;
--
-- if (conn->out)
-- timeout = L2CAP_DISCONN_TIMEOUT;
-- else
-- timeout = L2CAP_CONN_IDLE_TIMEOUT;
--
-- if (atomic_dec_and_test(&conn->refcnt) && conn->state == BT_CONNECTED) {
-- /* Schedule Baseband disconnect */
-- l2cap_conn_set_timer(conn, timeout);
-- }
-- }
--
-- sk->state = BT_CLOSED;
-- sk->err = err;
-- sk->state_change(sk);
--
-- sk->zapped = 1;
--}
--
--static void l2cap_conn_ready(struct l2cap_conn *conn)
--{
-- struct l2cap_chan_list *l = &conn->chan_list;
-- struct sock *sk;
--
-- DBG("conn %p", conn);
--
-- read_lock(&l->lock);
--
-- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-- bh_lock_sock(sk);
--
-- if (sk->type != SOCK_SEQPACKET) {
-- sk->state = BT_CONNECTED;
-- sk->state_change(sk);
-- l2cap_sock_clear_timer(sk);
-- } else if (sk->state == BT_CONNECT) {
-- l2cap_conn_req req;
-- req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- req.psm = l2cap_pi(sk)->psm;
-- l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
--
-- l2cap_sock_set_timer(sk, sk->sndtimeo);
-- }
--
-- bh_unlock_sock(sk);
-- }
--
-- read_unlock(&l->lock);
--}
--
--static void l2cap_chan_ready(struct sock *sk)
--{
-- struct sock *parent = l2cap_pi(sk)->parent;
--
-- DBG("sk %p, parent %p", sk, parent);
--
-- l2cap_pi(sk)->conf_state = 0;
-- l2cap_sock_clear_timer(sk);
--
-- if (!parent) {
-- /* Outgoing channel.
-- * Wake up socket sleeping on connect.
-- */
-- sk->state = BT_CONNECTED;
-- sk->state_change(sk);
-- } else {
-- /* Incomming channel.
-- * Wake up socket sleeping on accept.
-- */
-- parent->data_ready(parent, 1);
-- }
--}
--
--/* Copy frame to all raw sockets on that connection */
--void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
--{
-- struct l2cap_chan_list *l = &conn->chan_list;
-- struct sk_buff *nskb;
-- struct sock * sk;
--
-- DBG("conn %p", conn);
--
-- read_lock(&l->lock);
-- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-- if (sk->type != SOCK_RAW)
-- continue;
--
-- /* Don't send frame to the socket it came from */
-- if (skb->sk == sk)
-- continue;
--
-- if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
-- continue;
--
-- skb_queue_tail(&sk->receive_queue, nskb);
-- sk->data_ready(sk, nskb->len);
-- }
-- read_unlock(&l->lock);
--}
--
--static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
--{
-- struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-- struct sk_buff *skb, **frag;
-- int err, size, count, sent=0;
-- l2cap_hdr *lh;
--
-- /* Check outgoing MTU */
-- if (len > l2cap_pi(sk)->omtu)
-- return -EINVAL;
--
-- DBG("sk %p len %d", sk, len);
--
-- /* First fragment (with L2CAP header) */
-- count = MIN(conn->iff->mtu - L2CAP_HDR_SIZE, len);
-- size = L2CAP_HDR_SIZE + count;
-- if (!(skb = bluez_skb_send_alloc(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)))
-- return err;
--
-- /* Create L2CAP header */
-- lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-- lh->len = __cpu_to_le16(len);
-- lh->cid = __cpu_to_le16(l2cap_pi(sk)->dcid);
--
-- if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
-- err = -EFAULT;
-- goto fail;
-- }
--
-- sent += count;
-- len -= count;
--
-- /* Continuation fragments (no L2CAP header) */
-- frag = &skb_shinfo(skb)->frag_list;
-- while (len) {
-- count = MIN(conn->iff->mtu, len);
--
-- *frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
-- if (!*frag)
-- goto fail;
--
-- if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
-- err = -EFAULT;
-- goto fail;
-- }
--
-- sent += count;
-- len -= count;
--
-- frag = &(*frag)->next;
-- }
--
-- if ((err = hci_send_acl(conn->hconn, skb, 0)) < 0)
-- goto fail;
--
-- return sent;
--
--fail:
-- kfree_skb(skb);
-- return err;
--}
--
--/* --------- L2CAP signalling commands --------- */
--static inline __u8 l2cap_get_ident(struct l2cap_conn *conn)
--{
-- __u8 id;
--
-- /* Get next available identificator.
-- * 1 - 199 are used by kernel.
-- * 200 - 254 are used by utilities like l2ping, etc
-- */
--
-- spin_lock(&conn->lock);
--
-- if (++conn->tx_ident > 199)
-- conn->tx_ident = 1;
--
-- id = conn->tx_ident;
--
-- spin_unlock(&conn->lock);
--
-- return id;
--}
--
--static inline struct sk_buff *l2cap_build_cmd(__u8 code, __u8 ident, __u16 len, void *data)
--{
-- struct sk_buff *skb;
-- l2cap_cmd_hdr *cmd;
-- l2cap_hdr *lh;
-- int size;
--
-- DBG("code 0x%2.2x, ident 0x%2.2x, len %d", code, ident, len);
--
-- size = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + len;
-- if (!(skb = bluez_skb_alloc(size, GFP_ATOMIC)))
-- return NULL;
--
-- lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-- lh->len = __cpu_to_le16(L2CAP_CMD_HDR_SIZE + len);
-- lh->cid = __cpu_to_le16(0x0001);
--
-- cmd = (l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
-- cmd->code = code;
-- cmd->ident = ident;
-- cmd->len = __cpu_to_le16(len);
--
-- if (len)
-- memcpy(skb_put(skb, len), data, len);
--
-- return skb;
--}
--
--static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data)
--{
-- struct sk_buff *skb;
-- __u8 ident;
--
-- DBG("code 0x%2.2x", code);
--
-- ident = l2cap_get_ident(conn);
-- if (!(skb = l2cap_build_cmd(code, ident, len, data)))
-- return -ENOMEM;
-- return hci_send_acl(conn->hconn, skb, 0);
--}
--
--static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data)
--{
-- struct sk_buff *skb;
--
-- DBG("code 0x%2.2x", code);
--
-- if (!(skb = l2cap_build_cmd(code, ident, len, data)))
-- return -ENOMEM;
-- return hci_send_acl(conn->hconn, skb, 0);
--}
--
--static inline int l2cap_get_conf_opt(__u8 **ptr, __u8 *type, __u32 *val)
--{
-- l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
-- int len;
--
-- *type = opt->type;
-- switch (opt->len) {
-- case 1:
-- *val = *((__u8 *) opt->val);
-- break;
--
-- case 2:
-- *val = __le16_to_cpu(*((__u16 *)opt->val));
-- break;
--
-- case 4:
-- *val = __le32_to_cpu(*((__u32 *)opt->val));
-- break;
--
-- default:
-- *val = 0L;
-- break;
-- };
--
-- DBG("type 0x%2.2x len %d val 0x%8.8x", *type, opt->len, *val);
--
-- len = L2CAP_CONF_OPT_SIZE + opt->len;
--
-- *ptr += len;
--
-- return len;
--}
--
--static inline void l2cap_parse_conf_req(struct sock *sk, char *data, int len)
--{
-- __u8 type, hint; __u32 val;
-- __u8 *ptr = data;
--
-- DBG("sk %p len %d", sk, len);
--
-- while (len >= L2CAP_CONF_OPT_SIZE) {
-- len -= l2cap_get_conf_opt(&ptr, &type, &val);
--
-- hint = type & 0x80;
-- type &= 0x7f;
--
-- switch (type) {
-- case L2CAP_CONF_MTU:
-- l2cap_pi(sk)->conf_mtu = val;
-- break;
--
-- case L2CAP_CONF_FLUSH_TO:
-- l2cap_pi(sk)->flush_to = val;
-- break;
--
-- case L2CAP_CONF_QOS:
-- break;
--
-- default:
-- if (hint)
-- break;
--
-- /* FIXME: Reject unknon option */
-- break;
-- };
-- }
--}
--
--static inline void l2cap_add_conf_opt(__u8 **ptr, __u8 type, __u8 len, __u32 val)
--{
-- register l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
--
-- DBG("type 0x%2.2x len %d val 0x%8.8x", type, len, val);
--
-- opt->type = type;
-- opt->len = len;
-- switch (len) {
-- case 1:
-- *((__u8 *) opt->val) = val;
-- break;
--
-- case 2:
-- *((__u16 *) opt->val) = __cpu_to_le16(val);
-- break;
--
-- case 4:
-- *((__u32 *) opt->val) = __cpu_to_le32(val);
-- break;
-- };
--
-- *ptr += L2CAP_CONF_OPT_SIZE + len;
--}
--
--static int l2cap_build_conf_req(struct sock *sk, __u8 *data)
--{
-- struct l2cap_pinfo *pi = l2cap_pi(sk);
-- l2cap_conf_req *req = (l2cap_conf_req *) data;
-- __u8 *ptr = req->data;
--
-- DBG("sk %p", sk);
--
-- if (pi->imtu != L2CAP_DEFAULT_MTU)
-- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
--
-- /* FIXME. Need actual value of the flush timeout */
-- //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
-- // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
--
-- req->dcid = __cpu_to_le16(pi->dcid);
-- req->flags = __cpu_to_le16(0);
--
-- return ptr - data;
--}
--
--static int l2cap_conf_output(struct sock *sk, __u8 **ptr)
--{
-- struct l2cap_pinfo *pi = l2cap_pi(sk);
-- int result = 0;
--
-- /* Configure output options and let other side know
-- * which ones we don't like.
-- */
-- if (pi->conf_mtu < pi->omtu) {
-- l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, l2cap_pi(sk)->omtu);
-- result = L2CAP_CONF_UNACCEPT;
-- } else {
-- pi->omtu = pi->conf_mtu;
-- }
--
-- DBG("sk %p result %d", sk, result);
-- return result;
--}
--
--static int l2cap_build_conf_rsp(struct sock *sk, __u8 *data, int *result)
--{
-- l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data;
-- __u8 *ptr = rsp->data;
--
-- DBG("sk %p complete %d", sk, result ? 1 : 0);
--
-- if (result)
-- *result = l2cap_conf_output(sk, &ptr);
--
-- rsp->scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- rsp->result = __cpu_to_le16(result ? *result : 0);
-- rsp->flags = __cpu_to_le16(0);
--
-- return ptr - data;
--}
--
--static inline int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- struct l2cap_chan_list *list = &conn->chan_list;
-- l2cap_conn_req *req = (l2cap_conn_req *) data;
-- l2cap_conn_rsp rsp;
-- struct sock *sk, *parent;
--
-- __u16 scid = __le16_to_cpu(req->scid);
-- __u16 psm = req->psm;
--
-- DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
--
-- /* Check if we have socket listening on psm */
-- if (!(parent = l2cap_get_sock_listen(&conn->src, psm)))
-- goto reject;
--
-- bh_lock_sock(parent);
-- write_lock(&list->lock);
--
-- /* Check if we already have channel with that dcid */
-- if (__l2cap_get_chan_by_dcid(list, scid))
-- goto unlock;
--
-- /* Check for backlog size */
-- if (parent->ack_backlog > parent->max_ack_backlog)
-- goto unlock;
--
-- if (!(sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC)))
-- goto unlock;
--
-- l2cap_sock_init(sk, parent);
--
-- bacpy(&l2cap_pi(sk)->src, &conn->src);
-- bacpy(&l2cap_pi(sk)->dst, &conn->dst);
-- l2cap_pi(sk)->psm = psm;
-- l2cap_pi(sk)->dcid = scid;
--
-- __l2cap_chan_add(conn, sk, parent);
-- sk->state = BT_CONFIG;
--
-- write_unlock(&list->lock);
-- bh_unlock_sock(parent);
--
-- rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- rsp.result = __cpu_to_le16(0);
-- rsp.status = __cpu_to_le16(0);
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
--
-- return 0;
--
--unlock:
-- write_unlock(&list->lock);
-- bh_unlock_sock(parent);
--
--reject:
-- rsp.scid = __cpu_to_le16(scid);
-- rsp.dcid = __cpu_to_le16(0);
-- rsp.status = __cpu_to_le16(0);
-- rsp.result = __cpu_to_le16(L2CAP_CONN_NO_MEM);
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
--
-- return 0;
--}
--
--static inline int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_conn_rsp *rsp = (l2cap_conn_rsp *) data;
-- __u16 scid, dcid, result, status;
-- struct sock *sk;
--
-- scid = __le16_to_cpu(rsp->scid);
-- dcid = __le16_to_cpu(rsp->dcid);
-- result = __le16_to_cpu(rsp->result);
-- status = __le16_to_cpu(rsp->status);
--
-- DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-- return -ENOENT;
--
-- bh_lock_sock(sk);
--
-- if (!result) {
-- char req[64];
--
-- sk->state = BT_CONFIG;
-- l2cap_pi(sk)->dcid = dcid;
-- l2cap_pi(sk)->conf_state |= CONF_REQ_SENT;
--
-- l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-- } else {
-- l2cap_chan_del(sk, ECONNREFUSED);
-- }
--
-- bh_unlock_sock(sk);
-- return 0;
--}
--
--static inline int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_conf_req * req = (l2cap_conf_req *) data;
-- __u16 dcid, flags;
-- __u8 rsp[64];
-- struct sock *sk;
-- int result;
--
-- dcid = __le16_to_cpu(req->dcid);
-- flags = __le16_to_cpu(req->flags);
--
-- DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-- return -ENOENT;
--
-- bh_lock_sock(sk);
--
-- l2cap_parse_conf_req(sk, req->data, cmd->len - L2CAP_CONF_REQ_SIZE);
--
-- if (flags & 0x01) {
-- /* Incomplete config. Send empty response. */
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
-- goto unlock;
-- }
--
-- /* Complete config. */
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &result), rsp);
--
-- if (result)
-- goto unlock;
--
-- /* Output config done */
-- l2cap_pi(sk)->conf_state |= CONF_OUTPUT_DONE;
--
-- if (l2cap_pi(sk)->conf_state & CONF_INPUT_DONE) {
-- sk->state = BT_CONNECTED;
-- l2cap_chan_ready(sk);
-- } else if (!(l2cap_pi(sk)->conf_state & CONF_REQ_SENT)) {
-- char req[64];
-- l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-- }
--
--unlock:
-- bh_unlock_sock(sk);
--
-- return 0;
--}
--
--static inline int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_conf_rsp *rsp = (l2cap_conf_rsp *)data;
-- __u16 scid, flags, result;
-- struct sock *sk;
-- int err = 0;
--
-- scid = __le16_to_cpu(rsp->scid);
-- flags = __le16_to_cpu(rsp->flags);
-- result = __le16_to_cpu(rsp->result);
--
-- DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-- return -ENOENT;
--
-- bh_lock_sock(sk);
--
-- if (result) {
-- l2cap_disconn_req req;
--
-- /* They didn't like our options. Well... we do not negotiate.
-- * Close channel.
-- */
-- sk->state = BT_DISCONN;
--
-- req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
--
-- l2cap_sock_set_timer(sk, sk->sndtimeo);
-- goto done;
-- }
--
-- if (flags & 0x01)
-- goto done;
--
-- /* Input config done */
-- l2cap_pi(sk)->conf_state |= CONF_INPUT_DONE;
--
-- if (l2cap_pi(sk)->conf_state & CONF_OUTPUT_DONE) {
-- sk->state = BT_CONNECTED;
-- l2cap_chan_ready(sk);
-- }
--
--done:
-- bh_unlock_sock(sk);
--
-- return err;
--}
--
--static inline int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_disconn_req *req = (l2cap_disconn_req *) data;
-- l2cap_disconn_rsp rsp;
-- __u16 dcid, scid;
-- struct sock *sk;
--
-- scid = __le16_to_cpu(req->scid);
-- dcid = __le16_to_cpu(req->dcid);
--
-- DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-- return 0;
--
-- bh_lock_sock(sk);
--
-- rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_DISCONN_RSP, L2CAP_DISCONN_RSP_SIZE, &rsp);
--
-- l2cap_chan_del(sk, ECONNRESET);
--
-- bh_unlock_sock(sk);
--
-- l2cap_sock_kill(sk);
--
-- return 0;
--}
--
--static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_disconn_rsp *rsp = (l2cap_disconn_rsp *) data;
-- __u16 dcid, scid;
-- struct sock *sk;
--
-- scid = __le16_to_cpu(rsp->scid);
-- dcid = __le16_to_cpu(rsp->dcid);
--
-- DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-- return -ENOENT;
--
-- bh_lock_sock(sk);
-- l2cap_sock_clear_timer(sk);
-- l2cap_chan_del(sk, ECONNABORTED);
-- bh_unlock_sock(sk);
--
-- l2cap_sock_kill(sk);
--
-- return 0;
--}
--
--static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
--{
-- __u8 *data = skb->data;
-- int len = skb->len;
-- l2cap_cmd_hdr cmd;
-- int err = 0;
--
-- while (len >= L2CAP_CMD_HDR_SIZE) {
-- memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
-- data += L2CAP_CMD_HDR_SIZE;
-- len -= L2CAP_CMD_HDR_SIZE;
--
-- cmd.len = __le16_to_cpu(cmd.len);
--
-- DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
--
-- if (cmd.len > len || !cmd.ident) {
-- DBG("corrupted command");
-- break;
-- }
--
-- switch (cmd.code) {
-- case L2CAP_CONN_REQ:
-- err = l2cap_connect_req(conn, &cmd, data);
-- break;
--
-- case L2CAP_CONN_RSP:
-- err = l2cap_connect_rsp(conn, &cmd, data);
-- break;
--
-- case L2CAP_CONF_REQ:
-- err = l2cap_config_req(conn, &cmd, data);
-- break;
--
-- case L2CAP_CONF_RSP:
-- err = l2cap_config_rsp(conn, &cmd, data);
-- break;
--
-- case L2CAP_DISCONN_REQ:
-- err = l2cap_disconnect_req(conn, &cmd, data);
-- break;
--
-- case L2CAP_DISCONN_RSP:
-- err = l2cap_disconnect_rsp(conn, &cmd, data);
-- break;
--
-- case L2CAP_COMMAND_REJ:
-- /* FIXME: We should process this */
-- l2cap_raw_recv(conn, skb);
-- break;
--
-- case L2CAP_ECHO_REQ:
-- l2cap_send_rsp(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data);
-- break;
--
-- case L2CAP_ECHO_RSP:
-- case L2CAP_INFO_REQ:
-- case L2CAP_INFO_RSP:
-- l2cap_raw_recv(conn, skb);
-- break;
--
-- default:
-- ERR("Uknown signaling command 0x%2.2x", cmd.code);
-- err = -EINVAL;
-- break;
-- };
--
-- if (err) {
-- l2cap_cmd_rej rej;
-- DBG("error %d", err);
--
-- /* FIXME: Map err to a valid reason. */
-- rej.reason = __cpu_to_le16(0);
-- l2cap_send_rsp(conn, cmd.ident, L2CAP_COMMAND_REJ, L2CAP_CMD_REJ_SIZE, &rej);
-- }
--
-- data += cmd.len;
-- len -= cmd.len;
-- }
--
-- kfree_skb(skb);
--}
--
--static inline int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
--{
-- struct sock *sk;
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, cid))) {
-- DBG("unknown cid 0x%4.4x", cid);
-- goto drop;
-- }
--
-- DBG("sk %p, len %d", sk, skb->len);
--
-- if (sk->state != BT_CONNECTED)
-- goto drop;
--
-- if (l2cap_pi(sk)->imtu < skb->len)
-- goto drop;
--
-- skb_queue_tail(&sk->receive_queue, skb);
-- sk->data_ready(sk, skb->len);
--
-- return 0;
--
--drop:
-- kfree_skb(skb);
--
-- return 0;
--}
--
--static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
--{
-- l2cap_hdr *lh = (l2cap_hdr *) skb->data;
-- __u16 cid, len;
--
-- skb_pull(skb, L2CAP_HDR_SIZE);
-- cid = __le16_to_cpu(lh->cid);
-- len = __le16_to_cpu(lh->len);
--
-- DBG("len %d, cid 0x%4.4x", len, cid);
--
-- if (cid == 0x0001)
-- l2cap_sig_channel(conn, skb);
-- else
-- l2cap_data_channel(conn, cid, skb);
--}
--
--/* ------------ L2CAP interface with lower layer (HCI) ------------- */
--static int l2cap_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
--{
-- struct hci_dev *hdev = (struct hci_dev *) ptr;
--
-- DBG("hdev %s, event %ld", hdev->name, event);
--
-- write_lock(&l2cap_rt_lock);
--
-- switch (event) {
-- case HCI_DEV_UP:
-- l2cap_iff_add(hdev);
-- break;
--
-- case HCI_DEV_DOWN:
-- l2cap_iff_del(hdev);
-- break;
-- };
--
-- write_unlock(&l2cap_rt_lock);
--
-- return NOTIFY_DONE;
--}
--
--int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
--{
-- struct l2cap_iff *iff;
--
-- DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
--
-- if (!(iff = hdev->l2cap_data)) {
-- ERR("unknown interface");
-- return 0;
-- }
--
-- /* Always accept connection */
-- return 1;
--}
--
--int l2cap_connect_cfm(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 status, struct hci_conn *hconn)
--{
-- struct l2cap_conn *conn;
-- struct l2cap_iff *iff;
-- int err = 0;
--
-- DBG("hdev %s bdaddr %s hconn %p", hdev->name, batostr(bdaddr), hconn);
--
-- if (!(iff = hdev->l2cap_data)) {
-- ERR("unknown interface");
-- return 0;
-- }
--
-- l2cap_iff_lock(iff);
--
-- conn = l2cap_get_conn_by_addr(iff, bdaddr);
--
-- if (conn) {
-- /* Outgoing connection */
-- DBG("Outgoing connection: %s -> %s, %p, %2.2x", batostr(iff->bdaddr), batostr(bdaddr), conn, status);
--
-- if (!status && hconn) {
-- conn->state = BT_CONNECTED;
-- conn->hconn = hconn;
--
-- hconn->l2cap_data = (void *)conn;
--
-- /* Establish channels */
-- l2cap_conn_ready(conn);
-- } else {
-- l2cap_conn_del(conn, bterr(status));
-- }
-- } else {
-- /* Incomming connection */
-- DBG("Incomming connection: %s -> %s, %2.2x", batostr(iff->bdaddr), batostr(bdaddr), status);
--
-- if (status || !hconn)
-- goto done;
--
-- if (!(conn = l2cap_conn_add(iff, bdaddr))) {
-- err = -ENOMEM;
-- goto done;
-- }
--
-- conn->hconn = hconn;
-- hconn->l2cap_data = (void *)conn;
--
-- conn->state = BT_CONNECTED;
-- }
--
--done:
-- l2cap_iff_unlock(iff);
--
-- return err;
--}
--
--int l2cap_disconn_ind(struct hci_conn *hconn, __u8 reason)
--{
-- struct l2cap_conn *conn = hconn->l2cap_data;
--
-- DBG("hconn %p reason %d", hconn, reason);
--
-- if (!conn) {
-- ERR("unknown connection");
-- return 0;
-- }
-- conn->hconn = NULL;
--
-- l2cap_iff_lock(conn->iff);
-- l2cap_conn_del(conn, bterr(reason));
-- l2cap_iff_unlock(conn->iff);
--
-- return 0;
--}
--
--int l2cap_recv_acldata(struct hci_conn *hconn, struct sk_buff *skb, __u16 flags)
--{
-- struct l2cap_conn *conn = hconn->l2cap_data;
--
-- if (!conn) {
-- ERR("unknown connection %p", hconn);
-- goto drop;
-- }
--
-- DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
--
-- if (flags & ACL_START) {
-- int flen, tlen, size;
-- l2cap_hdr *lh;
--
-- if (conn->rx_len) {
-- ERR("Unexpected start frame (len %d)", skb->len);
-- kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
-- conn->rx_len = 0;
-- }
--
-- if (skb->len < L2CAP_HDR_SIZE) {
-- ERR("Frame is too small (len %d)", skb->len);
-- goto drop;
-- }
--
-- lh = (l2cap_hdr *)skb->data;
-- tlen = __le16_to_cpu(lh->len);
-- flen = skb->len - L2CAP_HDR_SIZE;
--
-- DBG("Start: total len %d, frag len %d", tlen, flen);
--
-- if (flen == tlen) {
-- /* Complete frame received */
-- l2cap_recv_frame(conn, skb);
-- return 0;
-- }
--
-- /* Allocate skb for the complete frame (with header) */
-- size = L2CAP_HDR_SIZE + tlen;
-- if (!(conn->rx_skb = bluez_skb_alloc(size, GFP_ATOMIC)))
-- goto drop;
--
-- memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
--
-- conn->rx_len = tlen - flen;
-- } else {
-- DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
--
-- if (!conn->rx_len) {
-- ERR("Unexpected continuation frame (len %d)", skb->len);
-- goto drop;
-- }
--
-- if (skb->len > conn->rx_len) {
-- ERR("Fragment is too large (len %d)", skb->len);
-- kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
-- goto drop;
-- }
--
-- memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
-- conn->rx_len -= skb->len;
--
-- if (!conn->rx_len) {
-- /* Complete frame received */
-- l2cap_recv_frame(conn, conn->rx_skb);
-- conn->rx_skb = NULL;
-- }
-- }
--
--drop:
-- kfree_skb(skb);
-- return 0;
--}
--
--struct proto_ops l2cap_sock_ops = {
-- family: PF_BLUETOOTH,
-- release: l2cap_sock_release,
-- bind: l2cap_sock_bind,
-- connect: l2cap_sock_connect,
-- listen: l2cap_sock_listen,
-- accept: l2cap_sock_accept,
-- getname: l2cap_sock_getname,
-- sendmsg: l2cap_sock_sendmsg,
-- recvmsg: l2cap_sock_recvmsg,
-- poll: l2cap_sock_poll,
-- socketpair: sock_no_socketpair,
-- ioctl: sock_no_ioctl,
-- shutdown: sock_no_shutdown,
-- setsockopt: l2cap_sock_setsockopt,
-- getsockopt: l2cap_sock_getsockopt,
-- mmap: sock_no_mmap
--};
--
--struct net_proto_family l2cap_sock_family_ops = {
-- family: PF_BLUETOOTH,
-- create: l2cap_sock_create
--};
--
--struct hci_proto l2cap_hci_proto = {
-- name: "L2CAP",
-- id: HCI_PROTO_L2CAP,
-- connect_ind: l2cap_connect_ind,
-- connect_cfm: l2cap_connect_cfm,
-- disconn_ind: l2cap_disconn_ind,
-- recv_acldata: l2cap_recv_acldata,
--};
--
--struct notifier_block l2cap_nblock = {
-- notifier_call: l2cap_dev_event
--};
--
--int __init l2cap_init(void)
--{
-- INF("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
--
-- if (bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops)) {
-- ERR("Can't register L2CAP socket");
-- return -EPROTO;
-- }
--
-- if (hci_register_proto(&l2cap_hci_proto) < 0) {
-- ERR("Can't register L2CAP protocol");
-- return -EPROTO;
-- }
--
-- hci_register_notifier(&l2cap_nblock);
--
-- l2cap_register_proc();
--
-- return 0;
--}
--
--void l2cap_cleanup(void)
--{
-- l2cap_unregister_proc();
--
-- /* Unregister socket, protocol and notifier */
-- if (bluez_sock_unregister(BTPROTO_L2CAP))
-- ERR("Can't unregister L2CAP socket");
--
-- if (hci_unregister_proto(&l2cap_hci_proto) < 0)
-- ERR("Can't unregister L2CAP protocol");
--
-- hci_unregister_notifier(&l2cap_nblock);
--
-- /* We _must_ not have any sockets and/or connections
-- * at this stage.
-- */
--
-- /* Free interface list and unlock HCI devices */
-- {
-- struct list_head *list = &l2cap_iff_list;
--
-- while (!list_empty(list)) {
-- struct l2cap_iff *iff;
--
-- iff = list_entry(list->next, struct l2cap_iff, list);
-- l2cap_iff_del(iff->hdev);
-- }
-- }
--}
--
--module_init(l2cap_init);
--module_exit(l2cap_cleanup);
--
--MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
--MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
--MODULE_LICENSE("GPL");
--
-diff -urN linux-2.4.18/net/bluetooth/l2cap_proc.c linux-2.4.18-mh15/net/bluetooth/l2cap_proc.c
---- linux-2.4.18/net/bluetooth/l2cap_proc.c 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/net/bluetooth/l2cap_proc.c 1970-01-01 01:00:00.000000000 +0100
-@@ -1,165 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * BlueZ L2CAP proc fs support.
-- *
-- * $Id$
-- */
--
--#include <linux/config.h>
--#include <linux/module.h>
--
--#include <linux/types.h>
--#include <linux/errno.h>
--#include <linux/kernel.h>
--#include <linux/major.h>
--#include <linux/sched.h>
--#include <linux/slab.h>
--#include <linux/poll.h>
--#include <linux/fcntl.h>
--#include <linux/init.h>
--#include <linux/skbuff.h>
--#include <linux/interrupt.h>
--#include <linux/socket.h>
--#include <linux/skbuff.h>
--#include <linux/proc_fs.h>
--#include <linux/list.h>
--#include <net/sock.h>
--
--#include <asm/system.h>
--#include <asm/uaccess.h>
--
--#include <net/bluetooth/bluez.h>
--#include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/l2cap_core.h>
--
--#ifndef L2CAP_DEBUG
--#undef DBG
--#define DBG( A... )
--#endif
--
--/* ----- PROC fs support ----- */
--static int l2cap_conn_dump(char *buf, struct l2cap_iff *iff)
--{
-- struct list_head *p;
-- char *ptr = buf;
--
-- list_for_each(p, &iff->conn_list) {
-- struct l2cap_conn *c;
--
-- c = list_entry(p, struct l2cap_conn, list);
-- ptr += sprintf(ptr, " %p %d %p %p %s %s\n",
-- c, c->state, c->iff, c->hconn, batostr(&c->src), batostr(&c->dst));
-- }
--
-- return ptr - buf;
--}
--
--static int l2cap_iff_dump(char *buf)
--{
-- struct list_head *p;
-- char *ptr = buf;
--
-- ptr += sprintf(ptr, "Interfaces:\n");
--
-- write_lock(&l2cap_rt_lock);
--
-- list_for_each(p, &l2cap_iff_list) {
-- struct l2cap_iff *iff;
--
-- iff = list_entry(p, struct l2cap_iff, list);
--
-- ptr += sprintf(ptr, " %s %p %p\n", iff->hdev->name, iff, iff->hdev);
--
-- l2cap_iff_lock(iff);
-- ptr += l2cap_conn_dump(ptr, iff);
-- l2cap_iff_unlock(iff);
-- }
--
-- write_unlock(&l2cap_rt_lock);
--
-- ptr += sprintf(ptr, "\n");
--
-- return ptr - buf;
--}
--
--static int l2cap_sock_dump(char *buf, struct bluez_sock_list *list)
--{
-- struct l2cap_pinfo *pi;
-- struct sock *sk;
-- char *ptr = buf;
--
-- ptr += sprintf(ptr, "Sockets:\n");
--
-- write_lock(&list->lock);
--
-- for (sk = list->head; sk; sk = sk->next) {
-- pi = l2cap_pi(sk);
-- ptr += sprintf(ptr, " %p %d %p %d %s %s 0x%4.4x 0x%4.4x %d %d\n", sk, sk->state, pi->conn, pi->psm,
-- batostr(&pi->src), batostr(&pi->dst), pi->scid, pi->dcid, pi->imtu, pi->omtu );
-- }
--
-- write_unlock(&list->lock);
--
-- ptr += sprintf(ptr, "\n");
--
-- return ptr - buf;
--}
--
--static int l2cap_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
--{
-- char *ptr = buf;
-- int len;
--
-- DBG("count %d, offset %ld", count, offset);
--
-- ptr += l2cap_iff_dump(ptr);
-- ptr += l2cap_sock_dump(ptr, &l2cap_sk_list);
-- len = ptr - buf;
--
-- if (len <= count + offset)
-- *eof = 1;
--
-- *start = buf + offset;
-- len -= offset;
--
-- if (len > count)
-- len = count;
-- if (len < 0)
-- len = 0;
--
-- return len;
--}
--
--void l2cap_register_proc(void)
--{
-- create_proc_read_entry("bluetooth/l2cap", 0, 0, l2cap_read_proc, NULL);
--}
--
--void l2cap_unregister_proc(void)
--{
-- remove_proc_entry("bluetooth/l2cap", NULL);
--}
-diff -urN linux-2.4.18/net/bluetooth/lib.c linux-2.4.18-mh15/net/bluetooth/lib.c
---- linux-2.4.18/net/bluetooth/lib.c 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/net/bluetooth/lib.c 2004-08-01 16:26:23.000000000 +0200
-@@ -25,7 +25,7 @@
- /*
- * BlueZ kernel library.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/kernel.h>
-@@ -105,7 +105,7 @@
- return EACCES;
-
- case 0x06:
-- return EINVAL;
-+ return EBADE;
-
- case 0x07:
- return ENOMEM;
-diff -urN linux-2.4.18/net/bluetooth/Makefile linux-2.4.18-mh15/net/bluetooth/Makefile
---- linux-2.4.18/net/bluetooth/Makefile 2001-06-12 04:15:27.000000000 +0200
-+++ linux-2.4.18-mh15/net/bluetooth/Makefile 2004-08-01 16:26:23.000000000 +0200
-@@ -1,20 +1,40 @@
- #
--# Makefile for the Bluetooth subsystem
-+# Makefile for the Linux Bluetooth subsystem
- #
--O_TARGET := bluetooth.o
-
--list-multi := hci.o l2cap.o
--export-objs := syms.o
--hci-objs := af_bluetooth.o hci_core.o hci_sock.o lib.o syms.o
--l2cap-objs := l2cap_core.o l2cap_proc.o
-+O_TARGET := bluetooth.o
-
--obj-$(CONFIG_BLUEZ) += hci.o
-+list-multi := bluez.o
-+export-objs := syms.o l2cap.o
-+
-+bluez-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o lib.o syms.o
-+
-+obj-$(CONFIG_BLUEZ) += bluez.o
- obj-$(CONFIG_BLUEZ_L2CAP) += l2cap.o
-+obj-$(CONFIG_BLUEZ_SCO) += sco.o
-
--include $(TOPDIR)/Rules.make
-+subdir-$(CONFIG_BLUEZ_RFCOMM) += rfcomm
-+subdir-$(CONFIG_BLUEZ_BNEP) += bnep
-+subdir-$(CONFIG_BLUEZ_CMTP) += cmtp
-+subdir-$(CONFIG_BLUEZ_HIDP) += hidp
-+
-+ifeq ($(CONFIG_BLUEZ_RFCOMM),y)
-+obj-y += rfcomm/rfcomm.o
-+endif
-
--hci.o: $(hci-objs)
-- $(LD) -r -o $@ $(hci-objs)
-+ifeq ($(CONFIG_BLUEZ_BNEP),y)
-+obj-y += bnep/bnep.o
-+endif
-+
-+ifeq ($(CONFIG_BLUEZ_CMTP),y)
-+obj-y += cmtp/cmtp.o
-+endif
-+
-+ifeq ($(CONFIG_BLUEZ_HIDP),y)
-+obj-y += hidp/hidp.o
-+endif
-+
-+include $(TOPDIR)/Rules.make
-
--l2cap.o: $(l2cap-objs)
-- $(LD) -r -o $@ $(l2cap-objs)
-+bluez.o: $(bluez-objs)
-+ $(LD) -r -o $@ $(bluez-objs)
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/Config.in linux-2.4.18-mh15/net/bluetooth/rfcomm/Config.in
---- linux-2.4.18/net/bluetooth/rfcomm/Config.in 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/rfcomm/Config.in 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,10 @@
-+#
-+# Bluetooth RFCOMM layer configuration
-+#
-+
-+dep_tristate 'RFCOMM protocol support' CONFIG_BLUEZ_RFCOMM $CONFIG_BLUEZ_L2CAP
-+
-+if [ "$CONFIG_BLUEZ_RFCOMM" != "n" ]; then
-+ bool ' RFCOMM TTY support' CONFIG_BLUEZ_RFCOMM_TTY
-+fi
-+
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/core.c linux-2.4.18-mh15/net/bluetooth/rfcomm/core.c
---- linux-2.4.18/net/bluetooth/rfcomm/core.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/rfcomm/core.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,1940 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ RPN support - Dirk Husemann <hud@zurich.ibm.com>
-+*/
-+
-+/*
-+ * RFCOMM core.
-+ *
-+ * $Id$
-+ */
-+
-+#define __KERNEL_SYSCALLS__
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/signal.h>
-+#include <linux/init.h>
-+#include <linux/wait.h>
-+#include <linux/net.h>
-+#include <linux/proc_fs.h>
-+#include <net/sock.h>
-+#include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/l2cap.h>
-+#include <net/bluetooth/rfcomm.h>
-+
-+#define VERSION "1.1"
-+
-+#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+struct task_struct *rfcomm_thread;
-+DECLARE_MUTEX(rfcomm_sem);
-+unsigned long rfcomm_event;
-+
-+static LIST_HEAD(session_list);
-+static atomic_t terminate, running;
-+
-+static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len);
-+static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci);
-+static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci);
-+static int rfcomm_queue_disc(struct rfcomm_dlc *d);
-+static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type);
-+static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d);
-+static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig);
-+static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len);
-+static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits);
-+static void rfcomm_make_uih(struct sk_buff *skb, u8 addr);
-+
-+static void rfcomm_process_connect(struct rfcomm_session *s);
-+
-+/* ---- RFCOMM frame parsing macros ---- */
-+#define __get_dlci(b) ((b & 0xfc) >> 2)
-+#define __get_channel(b) ((b & 0xf8) >> 3)
-+#define __get_dir(b) ((b & 0x04) >> 2)
-+#define __get_type(b) ((b & 0xef))
-+
-+#define __test_ea(b) ((b & 0x01))
-+#define __test_cr(b) ((b & 0x02))
-+#define __test_pf(b) ((b & 0x10))
-+
-+#define __addr(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01)
-+#define __ctrl(type, pf) (((type & 0xef) | (pf << 4)))
-+#define __dlci(dir, chn) (((chn & 0x1f) << 1) | dir)
-+#define __srv_channel(dlci) (dlci >> 1)
-+#define __dir(dlci) (dlci & 0x01)
-+
-+#define __len8(len) (((len) << 1) | 1)
-+#define __len16(len) ((len) << 1)
-+
-+/* MCC macros */
-+#define __mcc_type(cr, type) (((type << 2) | (cr << 1) | 0x01))
-+#define __get_mcc_type(b) ((b & 0xfc) >> 2)
-+#define __get_mcc_len(b) ((b & 0xfe) >> 1)
-+
-+/* RPN macros */
-+#define __rpn_line_settings(data, stop, parity) ((data & 0x3) | ((stop & 0x1) << 2) | ((parity & 0x3) << 3))
-+#define __get_rpn_data_bits(line) ((line) & 0x3)
-+#define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1)
-+#define __get_rpn_parity(line) (((line) >> 3) & 0x3)
-+
-+/* ---- RFCOMM FCS computation ---- */
-+
-+/* CRC on 2 bytes */
-+#define __crc(data) (rfcomm_crc_table[rfcomm_crc_table[0xff ^ data[0]] ^ data[1]])
-+
-+/* FCS on 2 bytes */
-+static inline u8 __fcs(u8 *data)
-+{
-+ return (0xff - __crc(data));
-+}
-+
-+/* FCS on 3 bytes */
-+static inline u8 __fcs2(u8 *data)
-+{
-+ return (0xff - rfcomm_crc_table[__crc(data) ^ data[2]]);
-+}
-+
-+/* Check FCS */
-+static inline int __check_fcs(u8 *data, int type, u8 fcs)
-+{
-+ u8 f = __crc(data);
-+
-+ if (type != RFCOMM_UIH)
-+ f = rfcomm_crc_table[f ^ data[2]];
-+
-+ return rfcomm_crc_table[f ^ fcs] != 0xcf;
-+}
-+
-+/* ---- L2CAP callbacks ---- */
-+static void rfcomm_l2state_change(struct sock *sk)
-+{
-+ BT_DBG("%p state %d", sk, sk->state);
-+ rfcomm_schedule(RFCOMM_SCHED_STATE);
-+}
-+
-+static void rfcomm_l2data_ready(struct sock *sk, int bytes)
-+{
-+ BT_DBG("%p bytes %d", sk, bytes);
-+ rfcomm_schedule(RFCOMM_SCHED_RX);
-+}
-+
-+static int rfcomm_l2sock_create(struct socket **sock)
-+{
-+ int err;
-+
-+ BT_DBG("");
-+
-+ err = sock_create(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP, sock);
-+ if (!err) {
-+ struct sock *sk = (*sock)->sk;
-+ sk->data_ready = rfcomm_l2data_ready;
-+ sk->state_change = rfcomm_l2state_change;
-+ }
-+ return err;
-+}
-+
-+/* ---- RFCOMM DLCs ---- */
-+static void rfcomm_dlc_timeout(unsigned long arg)
-+{
-+ struct rfcomm_dlc *d = (void *) arg;
-+
-+ BT_DBG("dlc %p state %ld", d, d->state);
-+
-+ set_bit(RFCOMM_TIMED_OUT, &d->flags);
-+ rfcomm_dlc_put(d);
-+ rfcomm_schedule(RFCOMM_SCHED_TIMEO);
-+}
-+
-+static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout)
-+{
-+ BT_DBG("dlc %p state %ld timeout %ld", d, d->state, timeout);
-+
-+ if (!mod_timer(&d->timer, jiffies + timeout))
-+ rfcomm_dlc_hold(d);
-+}
-+
-+static void rfcomm_dlc_clear_timer(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("dlc %p state %ld", d, d->state);
-+
-+ if (timer_pending(&d->timer) && del_timer(&d->timer))
-+ rfcomm_dlc_put(d);
-+}
-+
-+static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("%p", d);
-+
-+ d->state = BT_OPEN;
-+ d->flags = 0;
-+ d->mscex = 0;
-+ d->mtu = RFCOMM_DEFAULT_MTU;
-+ d->v24_sig = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV;
-+
-+ d->cfc = RFCOMM_CFC_DISABLED;
-+ d->rx_credits = RFCOMM_DEFAULT_CREDITS;
-+}
-+
-+struct rfcomm_dlc *rfcomm_dlc_alloc(int prio)
-+{
-+ struct rfcomm_dlc *d = kmalloc(sizeof(*d), prio);
-+ if (!d)
-+ return NULL;
-+ memset(d, 0, sizeof(*d));
-+
-+ init_timer(&d->timer);
-+ d->timer.function = rfcomm_dlc_timeout;
-+ d->timer.data = (unsigned long) d;
-+
-+ skb_queue_head_init(&d->tx_queue);
-+ spin_lock_init(&d->lock);
-+ atomic_set(&d->refcnt, 1);
-+
-+ rfcomm_dlc_clear_state(d);
-+
-+ BT_DBG("%p", d);
-+ return d;
-+}
-+
-+void rfcomm_dlc_free(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("%p", d);
-+
-+ skb_queue_purge(&d->tx_queue);
-+ kfree(d);
-+}
-+
-+static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d)
-+{
-+ BT_DBG("dlc %p session %p", d, s);
-+
-+ rfcomm_session_hold(s);
-+
-+ rfcomm_dlc_hold(d);
-+ list_add(&d->list, &s->dlcs);
-+ d->session = s;
-+}
-+
-+static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
-+{
-+ struct rfcomm_session *s = d->session;
-+
-+ BT_DBG("dlc %p refcnt %d session %p", d, atomic_read(&d->refcnt), s);
-+
-+ list_del(&d->list);
-+ d->session = NULL;
-+ rfcomm_dlc_put(d);
-+
-+ rfcomm_session_put(s);
-+}
-+
-+static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_dlc *d;
-+ struct list_head *p;
-+
-+ list_for_each(p, &s->dlcs) {
-+ d = list_entry(p, struct rfcomm_dlc, list);
-+ if (d->dlci == dlci)
-+ return d;
-+ }
-+ return NULL;
-+}
-+
-+static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
-+{
-+ struct rfcomm_session *s;
-+ int err = 0;
-+ u8 dlci;
-+
-+ BT_DBG("dlc %p state %ld %s %s channel %d",
-+ d, d->state, batostr(src), batostr(dst), channel);
-+
-+ if (channel < 1 || channel > 30)
-+ return -EINVAL;
-+
-+ if (d->state != BT_OPEN && d->state != BT_CLOSED)
-+ return 0;
-+
-+ s = rfcomm_session_get(src, dst);
-+ if (!s) {
-+ s = rfcomm_session_create(src, dst, &err);
-+ if (!s)
-+ return err;
-+ }
-+
-+ dlci = __dlci(!s->initiator, channel);
-+
-+ /* Check if DLCI already exists */
-+ if (rfcomm_dlc_get(s, dlci))
-+ return -EBUSY;
-+
-+ rfcomm_dlc_clear_state(d);
-+
-+ d->dlci = dlci;
-+ d->addr = __addr(s->initiator, dlci);
-+ d->priority = 7;
-+
-+ d->state = BT_CONFIG;
-+ rfcomm_dlc_link(s, d);
-+
-+ d->mtu = s->mtu;
-+ d->cfc = (s->cfc == RFCOMM_CFC_UNKNOWN) ? 0 : s->cfc;
-+
-+ if (s->state == BT_CONNECTED)
-+ rfcomm_send_pn(s, 1, d);
-+ rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT);
-+ return 0;
-+}
-+
-+int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
-+{
-+ mm_segment_t fs;
-+ int r;
-+
-+ rfcomm_lock();
-+
-+ fs = get_fs(); set_fs(KERNEL_DS);
-+ r = __rfcomm_dlc_open(d, src, dst, channel);
-+ set_fs(fs);
-+
-+ rfcomm_unlock();
-+ return r;
-+}
-+
-+static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
-+{
-+ struct rfcomm_session *s = d->session;
-+ if (!s)
-+ return 0;
-+
-+ BT_DBG("dlc %p state %ld dlci %d err %d session %p",
-+ d, d->state, d->dlci, err, s);
-+
-+ switch (d->state) {
-+ case BT_CONNECTED:
-+ case BT_CONFIG:
-+ case BT_CONNECT:
-+ d->state = BT_DISCONN;
-+ if (skb_queue_empty(&d->tx_queue)) {
-+ rfcomm_send_disc(s, d->dlci);
-+ rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT);
-+ } else {
-+ rfcomm_queue_disc(d);
-+ rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT * 2);
-+ }
-+ break;
-+
-+ default:
-+ rfcomm_dlc_clear_timer(d);
-+
-+ rfcomm_dlc_lock(d);
-+ d->state = BT_CLOSED;
-+ d->state_change(d, err);
-+ rfcomm_dlc_unlock(d);
-+
-+ skb_queue_purge(&d->tx_queue);
-+ rfcomm_dlc_unlink(d);
-+ }
-+
-+ return 0;
-+}
-+
-+int rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
-+{
-+ mm_segment_t fs;
-+ int r;
-+
-+ rfcomm_lock();
-+
-+ fs = get_fs(); set_fs(KERNEL_DS);
-+ r = __rfcomm_dlc_close(d, err);
-+ set_fs(fs);
-+
-+ rfcomm_unlock();
-+ return r;
-+}
-+
-+int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
-+{
-+ int len = skb->len;
-+
-+ if (d->state != BT_CONNECTED)
-+ return -ENOTCONN;
-+
-+ BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len);
-+
-+ if (len > d->mtu)
-+ return -EINVAL;
-+
-+ rfcomm_make_uih(skb, d->addr);
-+ skb_queue_tail(&d->tx_queue, skb);
-+
-+ if (!test_bit(RFCOMM_TX_THROTTLED, &d->flags))
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+ return len;
-+}
-+
-+void __rfcomm_dlc_throttle(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("dlc %p state %ld", d, d->state);
-+
-+ if (!d->cfc) {
-+ d->v24_sig |= RFCOMM_V24_FC;
-+ set_bit(RFCOMM_MSC_PENDING, &d->flags);
-+ }
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+}
-+
-+void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("dlc %p state %ld", d, d->state);
-+
-+ if (!d->cfc) {
-+ d->v24_sig &= ~RFCOMM_V24_FC;
-+ set_bit(RFCOMM_MSC_PENDING, &d->flags);
-+ }
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+}
-+
-+/*
-+ Set/get modem status functions use _local_ status i.e. what we report
-+ to the other side.
-+ Remote status is provided by dlc->modem_status() callback.
-+ */
-+int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig)
-+{
-+ BT_DBG("dlc %p state %ld v24_sig 0x%x",
-+ d, d->state, v24_sig);
-+
-+ if (test_bit(RFCOMM_RX_THROTTLED, &d->flags))
-+ v24_sig |= RFCOMM_V24_FC;
-+ else
-+ v24_sig &= ~RFCOMM_V24_FC;
-+
-+ d->v24_sig = v24_sig;
-+
-+ if (!test_and_set_bit(RFCOMM_MSC_PENDING, &d->flags))
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+
-+ return 0;
-+}
-+
-+int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig)
-+{
-+ BT_DBG("dlc %p state %ld v24_sig 0x%x",
-+ d, d->state, d->v24_sig);
-+
-+ *v24_sig = d->v24_sig;
-+ return 0;
-+}
-+
-+/* ---- RFCOMM sessions ---- */
-+struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
-+{
-+ struct rfcomm_session *s = kmalloc(sizeof(*s), GFP_KERNEL);
-+ if (!s)
-+ return NULL;
-+ memset(s, 0, sizeof(*s));
-+
-+ BT_DBG("session %p sock %p", s, sock);
-+
-+ INIT_LIST_HEAD(&s->dlcs);
-+ s->state = state;
-+ s->sock = sock;
-+
-+ s->mtu = RFCOMM_DEFAULT_MTU;
-+ s->cfc = RFCOMM_CFC_UNKNOWN;
-+
-+ list_add(&s->list, &session_list);
-+
-+ /* Do not increment module usage count for listeting sessions.
-+ * Otherwise we won't be able to unload the module. */
-+ if (state != BT_LISTEN)
-+ MOD_INC_USE_COUNT;
-+ return s;
-+}
-+
-+void rfcomm_session_del(struct rfcomm_session *s)
-+{
-+ int state = s->state;
-+
-+ BT_DBG("session %p state %ld", s, s->state);
-+
-+ list_del(&s->list);
-+
-+ if (state == BT_CONNECTED)
-+ rfcomm_send_disc(s, 0);
-+
-+ sock_release(s->sock);
-+ kfree(s);
-+
-+ if (state != BT_LISTEN)
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
-+{
-+ struct rfcomm_session *s;
-+ struct list_head *p, *n;
-+ struct bluez_pinfo *pi;
-+ list_for_each_safe(p, n, &session_list) {
-+ s = list_entry(p, struct rfcomm_session, list);
-+ pi = bluez_pi(s->sock->sk);
-+
-+ if ((!bacmp(src, BDADDR_ANY) || !bacmp(&pi->src, src)) &&
-+ !bacmp(&pi->dst, dst))
-+ return s;
-+ }
-+ return NULL;
-+}
-+
-+void rfcomm_session_close(struct rfcomm_session *s, int err)
-+{
-+ struct rfcomm_dlc *d;
-+ struct list_head *p, *n;
-+
-+ BT_DBG("session %p state %ld err %d", s, s->state, err);
-+
-+ rfcomm_session_hold(s);
-+
-+ s->state = BT_CLOSED;
-+
-+ /* Close all dlcs */
-+ list_for_each_safe(p, n, &s->dlcs) {
-+ d = list_entry(p, struct rfcomm_dlc, list);
-+ d->state = BT_CLOSED;
-+ __rfcomm_dlc_close(d, err);
-+ }
-+
-+ rfcomm_session_put(s);
-+}
-+
-+struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err)
-+{
-+ struct rfcomm_session *s = NULL;
-+ struct sockaddr_l2 addr;
-+ struct l2cap_options opts;
-+ struct socket *sock;
-+ int size;
-+
-+ BT_DBG("%s %s", batostr(src), batostr(dst));
-+
-+ *err = rfcomm_l2sock_create(&sock);
-+ if (*err < 0)
-+ return NULL;
-+
-+ bacpy(&addr.l2_bdaddr, src);
-+ addr.l2_family = AF_BLUETOOTH;
-+ addr.l2_psm = 0;
-+ *err = sock->ops->bind(sock, (struct sockaddr *) &addr, sizeof(addr));
-+ if (*err < 0)
-+ goto failed;
-+
-+ /* Set L2CAP options */
-+ size = sizeof(opts);
-+ sock->ops->getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, &size);
-+
-+ opts.imtu = RFCOMM_MAX_L2CAP_MTU;
-+ sock->ops->setsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, size);
-+
-+ s = rfcomm_session_add(sock, BT_BOUND);
-+ if (!s) {
-+ *err = -ENOMEM;
-+ goto failed;
-+ }
-+
-+ s->initiator = 1;
-+
-+ bacpy(&addr.l2_bdaddr, dst);
-+ addr.l2_family = AF_BLUETOOTH;
-+ addr.l2_psm = htobs(RFCOMM_PSM);
-+ *err = sock->ops->connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
-+ if (*err == 0 || *err == -EAGAIN)
-+ return s;
-+
-+ rfcomm_session_del(s);
-+ return NULL;
-+
-+failed:
-+ sock_release(sock);
-+ return NULL;
-+}
-+
-+void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst)
-+{
-+ struct sock *sk = s->sock->sk;
-+ if (src)
-+ bacpy(src, &bluez_pi(sk)->src);
-+ if (dst)
-+ bacpy(dst, &bluez_pi(sk)->dst);
-+}
-+
-+/* ---- RFCOMM frame sending ---- */
-+static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len)
-+{
-+ struct socket *sock = s->sock;
-+ struct iovec iv = { data, len };
-+ struct msghdr msg;
-+ int err;
-+
-+ BT_DBG("session %p len %d", s, len);
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_iovlen = 1;
-+ msg.msg_iov = &iv;
-+
-+ err = sock->ops->sendmsg(sock, &msg, len, 0);
-+ return err;
-+}
-+
-+static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_cmd cmd;
-+
-+ BT_DBG("%p dlci %d", s, dlci);
-+
-+ cmd.addr = __addr(s->initiator, dlci);
-+ cmd.ctrl = __ctrl(RFCOMM_SABM, 1);
-+ cmd.len = __len8(0);
-+ cmd.fcs = __fcs2((u8 *) &cmd);
-+
-+ return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
-+}
-+
-+static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_cmd cmd;
-+
-+ BT_DBG("%p dlci %d", s, dlci);
-+
-+ cmd.addr = __addr(!s->initiator, dlci);
-+ cmd.ctrl = __ctrl(RFCOMM_UA, 1);
-+ cmd.len = __len8(0);
-+ cmd.fcs = __fcs2((u8 *) &cmd);
-+
-+ return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
-+}
-+
-+static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_cmd cmd;
-+
-+ BT_DBG("%p dlci %d", s, dlci);
-+
-+ cmd.addr = __addr(s->initiator, dlci);
-+ cmd.ctrl = __ctrl(RFCOMM_DISC, 1);
-+ cmd.len = __len8(0);
-+ cmd.fcs = __fcs2((u8 *) &cmd);
-+
-+ return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
-+}
-+
-+static int rfcomm_queue_disc(struct rfcomm_dlc *d)
-+{
-+ struct rfcomm_cmd *cmd;
-+ struct sk_buff *skb;
-+
-+ BT_DBG("dlc %p dlci %d", d, d->dlci);
-+
-+ skb = alloc_skb(sizeof(*cmd), GFP_KERNEL);
-+ if (!skb)
-+ return -ENOMEM;
-+
-+ cmd = (void *) __skb_put(skb, sizeof(*cmd));
-+ cmd->addr = d->addr;
-+ cmd->ctrl = __ctrl(RFCOMM_DISC, 1);
-+ cmd->len = __len8(0);
-+ cmd->fcs = __fcs2((u8 *) cmd);
-+
-+ skb_queue_tail(&d->tx_queue, skb);
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+ return 0;
-+}
-+
-+static int rfcomm_send_dm(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_cmd cmd;
-+
-+ BT_DBG("%p dlci %d", s, dlci);
-+
-+ cmd.addr = __addr(!s->initiator, dlci);
-+ cmd.ctrl = __ctrl(RFCOMM_DM, 1);
-+ cmd.len = __len8(0);
-+ cmd.fcs = __fcs2((u8 *) &cmd);
-+
-+ return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
-+}
-+
-+static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d type %d", s, cr, type);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + 1);
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_NSC);
-+ mcc->len = __len8(1);
-+
-+ /* Type that we didn't like */
-+ *ptr = __mcc_type(cr, type); ptr++;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ struct rfcomm_pn *pn;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d dlci %d mtu %d", s, cr, d->dlci, d->mtu);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + sizeof(*pn));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_PN);
-+ mcc->len = __len8(sizeof(*pn));
-+
-+ pn = (void *) ptr; ptr += sizeof(*pn);
-+ pn->dlci = d->dlci;
-+ pn->priority = d->priority;
-+ pn->ack_timer = 0;
-+ pn->max_retrans = 0;
-+
-+ if (s->cfc) {
-+ pn->flow_ctrl = cr ? 0xf0 : 0xe0;
-+ pn->credits = RFCOMM_DEFAULT_CREDITS;
-+ } else {
-+ pn->flow_ctrl = 0;
-+ pn->credits = 0;
-+ }
-+
-+ pn->mtu = htobs(d->mtu);
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,
-+ u8 bit_rate, u8 data_bits, u8 stop_bits,
-+ u8 parity, u8 flow_ctrl_settings,
-+ u8 xon_char, u8 xoff_char, u16 param_mask)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ struct rfcomm_rpn *rpn;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d dlci %d bit_r 0x%x data_b 0x%x stop_b 0x%x parity 0x%x"
-+ "flwc_s 0x%x xon_c 0x%x xoff_c 0x%x p_mask 0x%x",
-+ s, cr, dlci, bit_rate, data_bits, stop_bits, parity,
-+ flow_ctrl_settings, xon_char, xoff_char, param_mask);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + sizeof(*rpn));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_RPN);
-+ mcc->len = __len8(sizeof(*rpn));
-+
-+ rpn = (void *) ptr; ptr += sizeof(*rpn);
-+ rpn->dlci = __addr(1, dlci);
-+ rpn->bit_rate = bit_rate;
-+ rpn->line_settings = __rpn_line_settings(data_bits, stop_bits, parity);
-+ rpn->flow_ctrl = flow_ctrl_settings;
-+ rpn->xon_char = xon_char;
-+ rpn->xoff_char = xoff_char;
-+ rpn->param_mask = param_mask;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ struct rfcomm_rls *rls;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d status 0x%x", s, cr, status);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + sizeof(*rls));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_RLS);
-+ mcc->len = __len8(sizeof(*rls));
-+
-+ rls = (void *) ptr; ptr += sizeof(*rls);
-+ rls->dlci = __addr(1, dlci);
-+ rls->status = status;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ struct rfcomm_msc *msc;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d v24 0x%x", s, cr, v24_sig);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + sizeof(*msc));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_MSC);
-+ mcc->len = __len8(sizeof(*msc));
-+
-+ msc = (void *) ptr; ptr += sizeof(*msc);
-+ msc->dlci = __addr(1, dlci);
-+ msc->v24_sig = v24_sig | 0x01;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d", s, cr);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_FCOFF);
-+ mcc->len = __len8(0);
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_fcon(struct rfcomm_session *s, int cr)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d", s, cr);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_FCON);
-+ mcc->len = __len8(0);
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len)
-+{
-+ struct socket *sock = s->sock;
-+ struct iovec iv[3];
-+ struct msghdr msg;
-+ unsigned char hdr[5], crc[1];
-+
-+ if (len > 125)
-+ return -EINVAL;
-+
-+ BT_DBG("%p cr %d", s, cr);
-+
-+ hdr[0] = __addr(s->initiator, 0);
-+ hdr[1] = __ctrl(RFCOMM_UIH, 0);
-+ hdr[2] = 0x01 | ((len + 2) << 1);
-+ hdr[3] = 0x01 | ((cr & 0x01) << 1) | (RFCOMM_TEST << 2);
-+ hdr[4] = 0x01 | (len << 1);
-+
-+ crc[0] = __fcs(hdr);
-+
-+ iv[0].iov_base = hdr;
-+ iv[0].iov_len = 5;
-+ iv[1].iov_base = pattern;
-+ iv[1].iov_len = len;
-+ iv[2].iov_base = crc;
-+ iv[2].iov_len = 1;
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_iovlen = 3;
-+ msg.msg_iov = iv;
-+ return sock->ops->sendmsg(sock, &msg, 6 + len, 0);
-+}
-+
-+static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits)
-+{
-+ struct rfcomm_hdr *hdr;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p addr %d credits %d", s, addr, credits);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = addr;
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 1);
-+ hdr->len = __len8(0);
-+
-+ *ptr = credits; ptr++;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
-+{
-+ struct rfcomm_hdr *hdr;
-+ int len = skb->len;
-+ u8 *crc;
-+
-+ if (len > 127) {
-+ hdr = (void *) skb_push(skb, 4);
-+ put_unaligned(htobs(__len16(len)), (u16 *) &hdr->len);
-+ } else {
-+ hdr = (void *) skb_push(skb, 3);
-+ hdr->len = __len8(len);
-+ }
-+ hdr->addr = addr;
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+
-+ crc = skb_put(skb, 1);
-+ *crc = __fcs((void *) hdr);
-+}
-+
-+/* ---- RFCOMM frame reception ---- */
-+static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
-+{
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (dlci) {
-+ /* Data channel */
-+ struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
-+ if (!d) {
-+ rfcomm_send_dm(s, dlci);
-+ return 0;
-+ }
-+
-+ switch (d->state) {
-+ case BT_CONNECT:
-+ rfcomm_dlc_clear_timer(d);
-+
-+ rfcomm_dlc_lock(d);
-+ d->state = BT_CONNECTED;
-+ d->state_change(d, 0);
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_send_msc(s, 1, dlci, d->v24_sig);
-+ break;
-+
-+ case BT_DISCONN:
-+ d->state = BT_CLOSED;
-+ __rfcomm_dlc_close(d, 0);
-+ break;
-+ }
-+ } else {
-+ /* Control channel */
-+ switch (s->state) {
-+ case BT_CONNECT:
-+ s->state = BT_CONNECTED;
-+ rfcomm_process_connect(s);
-+ break;
-+ }
-+ }
-+ return 0;
-+}
-+
-+static int rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci)
-+{
-+ int err = 0;
-+
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (dlci) {
-+ /* Data DLC */
-+ struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
-+ if (d) {
-+ if (d->state == BT_CONNECT || d->state == BT_CONFIG)
-+ err = ECONNREFUSED;
-+ else
-+ err = ECONNRESET;
-+
-+ d->state = BT_CLOSED;
-+ __rfcomm_dlc_close(d, err);
-+ }
-+ } else {
-+ if (s->state == BT_CONNECT)
-+ err = ECONNREFUSED;
-+ else
-+ err = ECONNRESET;
-+
-+ s->state = BT_CLOSED;
-+ rfcomm_session_close(s, err);
-+ }
-+ return 0;
-+}
-+
-+static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
-+{
-+ int err = 0;
-+
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (dlci) {
-+ struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
-+ if (d) {
-+ rfcomm_send_ua(s, dlci);
-+
-+ if (d->state == BT_CONNECT || d->state == BT_CONFIG)
-+ err = ECONNREFUSED;
-+ else
-+ err = ECONNRESET;
-+
-+ d->state = BT_CLOSED;
-+ __rfcomm_dlc_close(d, err);
-+ } else
-+ rfcomm_send_dm(s, dlci);
-+
-+ } else {
-+ rfcomm_send_ua(s, 0);
-+
-+ if (s->state == BT_CONNECT)
-+ err = ECONNREFUSED;
-+ else
-+ err = ECONNRESET;
-+
-+ s->state = BT_CLOSED;
-+ rfcomm_session_close(s, err);
-+ }
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_dlc *d;
-+ u8 channel;
-+
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (!dlci) {
-+ rfcomm_send_ua(s, 0);
-+
-+ if (s->state == BT_OPEN) {
-+ s->state = BT_CONNECTED;
-+ rfcomm_process_connect(s);
-+ }
-+ return 0;
-+ }
-+
-+ /* Check if DLC exists */
-+ d = rfcomm_dlc_get(s, dlci);
-+ if (d) {
-+ if (d->state == BT_OPEN) {
-+ /* DLC was previously opened by PN request */
-+ rfcomm_send_ua(s, dlci);
-+
-+ rfcomm_dlc_lock(d);
-+ d->state = BT_CONNECTED;
-+ d->state_change(d, 0);
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_send_msc(s, 1, dlci, d->v24_sig);
-+ }
-+ return 0;
-+ }
-+
-+ /* Notify socket layer about incomming connection */
-+ channel = __srv_channel(dlci);
-+ if (rfcomm_connect_ind(s, channel, &d)) {
-+ d->dlci = dlci;
-+ d->addr = __addr(s->initiator, dlci);
-+ rfcomm_dlc_link(s, d);
-+
-+ rfcomm_send_ua(s, dlci);
-+
-+ rfcomm_dlc_lock(d);
-+ d->state = BT_CONNECTED;
-+ d->state_change(d, 0);
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_send_msc(s, 1, dlci, d->v24_sig);
-+ } else {
-+ rfcomm_send_dm(s, dlci);
-+ }
-+
-+ return 0;
-+}
-+
-+static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
-+{
-+ struct rfcomm_session *s = d->session;
-+
-+ BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d",
-+ d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits);
-+
-+ if (pn->flow_ctrl == 0xf0 || pn->flow_ctrl == 0xe0) {
-+ d->cfc = s->cfc = RFCOMM_CFC_ENABLED;
-+ d->tx_credits = pn->credits;
-+ } else {
-+ d->cfc = s->cfc = RFCOMM_CFC_DISABLED;
-+ set_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+ }
-+
-+ d->priority = pn->priority;
-+
-+ d->mtu = s->mtu = btohs(pn->mtu);
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb)
-+{
-+ struct rfcomm_pn *pn = (void *) skb->data;
-+ struct rfcomm_dlc *d;
-+ u8 dlci = pn->dlci;
-+
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (!dlci)
-+ return 0;
-+
-+ d = rfcomm_dlc_get(s, dlci);
-+ if (d) {
-+ if (cr) {
-+ /* PN request */
-+ rfcomm_apply_pn(d, cr, pn);
-+ rfcomm_send_pn(s, 0, d);
-+ } else {
-+ /* PN response */
-+ switch (d->state) {
-+ case BT_CONFIG:
-+ rfcomm_apply_pn(d, cr, pn);
-+
-+ d->state = BT_CONNECT;
-+ rfcomm_send_sabm(s, d->dlci);
-+ break;
-+ }
-+ }
-+ } else {
-+ u8 channel = __srv_channel(dlci);
-+
-+ if (!cr)
-+ return 0;
-+
-+ /* PN request for non existing DLC.
-+ * Assume incomming connection. */
-+ if (rfcomm_connect_ind(s, channel, &d)) {
-+ d->dlci = dlci;
-+ d->addr = __addr(s->initiator, dlci);
-+ rfcomm_dlc_link(s, d);
-+
-+ rfcomm_apply_pn(d, cr, pn);
-+
-+ d->state = BT_OPEN;
-+ rfcomm_send_pn(s, 0, d);
-+ } else {
-+ rfcomm_send_dm(s, dlci);
-+ }
-+ }
-+ return 0;
-+}
-+
-+static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_buff *skb)
-+{
-+ struct rfcomm_rpn *rpn = (void *) skb->data;
-+ u8 dlci = __get_dlci(rpn->dlci);
-+
-+ u8 bit_rate = 0;
-+ u8 data_bits = 0;
-+ u8 stop_bits = 0;
-+ u8 parity = 0;
-+ u8 flow_ctrl = 0;
-+ u8 xon_char = 0;
-+ u8 xoff_char = 0;
-+ u16 rpn_mask = RFCOMM_RPN_PM_ALL;
-+
-+ BT_DBG("dlci %d cr %d len 0x%x bitr 0x%x line 0x%x flow 0x%x xonc 0x%x xoffc 0x%x pm 0x%x",
-+ dlci, cr, len, rpn->bit_rate, rpn->line_settings, rpn->flow_ctrl,
-+ rpn->xon_char, rpn->xoff_char, rpn->param_mask);
-+
-+ if (!cr)
-+ return 0;
-+
-+ if (len == 1) {
-+ /* request: return default setting */
-+ bit_rate = RFCOMM_RPN_BR_115200;
-+ data_bits = RFCOMM_RPN_DATA_8;
-+ stop_bits = RFCOMM_RPN_STOP_1;
-+ parity = RFCOMM_RPN_PARITY_NONE;
-+ flow_ctrl = RFCOMM_RPN_FLOW_NONE;
-+ xon_char = RFCOMM_RPN_XON_CHAR;
-+ xoff_char = RFCOMM_RPN_XOFF_CHAR;
-+
-+ goto rpn_out;
-+ }
-+ /* check for sane values: ignore/accept bit_rate, 8 bits, 1 stop bit, no parity,
-+ no flow control lines, normal XON/XOFF chars */
-+ if (rpn->param_mask & RFCOMM_RPN_PM_BITRATE) {
-+ bit_rate = rpn->bit_rate;
-+ if (bit_rate != RFCOMM_RPN_BR_115200) {
-+ BT_DBG("RPN bit rate mismatch 0x%x", bit_rate);
-+ bit_rate = RFCOMM_RPN_BR_115200;
-+ rpn_mask ^= RFCOMM_RPN_PM_BITRATE;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_DATA) {
-+ data_bits = __get_rpn_data_bits(rpn->line_settings);
-+ if (data_bits != RFCOMM_RPN_DATA_8) {
-+ BT_DBG("RPN data bits mismatch 0x%x", data_bits);
-+ data_bits = RFCOMM_RPN_DATA_8;
-+ rpn_mask ^= RFCOMM_RPN_PM_DATA;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_STOP) {
-+ stop_bits = __get_rpn_stop_bits(rpn->line_settings);
-+ if (stop_bits != RFCOMM_RPN_STOP_1) {
-+ BT_DBG("RPN stop bits mismatch 0x%x", stop_bits);
-+ stop_bits = RFCOMM_RPN_STOP_1;
-+ rpn_mask ^= RFCOMM_RPN_PM_STOP;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_PARITY) {
-+ parity = __get_rpn_parity(rpn->line_settings);
-+ if (parity != RFCOMM_RPN_PARITY_NONE) {
-+ BT_DBG("RPN parity mismatch 0x%x", parity);
-+ parity = RFCOMM_RPN_PARITY_NONE;
-+ rpn_mask ^= RFCOMM_RPN_PM_PARITY;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_FLOW) {
-+ flow_ctrl = rpn->flow_ctrl;
-+ if (flow_ctrl != RFCOMM_RPN_FLOW_NONE) {
-+ BT_DBG("RPN flow ctrl mismatch 0x%x", flow_ctrl);
-+ flow_ctrl = RFCOMM_RPN_FLOW_NONE;
-+ rpn_mask ^= RFCOMM_RPN_PM_FLOW;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_XON) {
-+ xon_char = rpn->xon_char;
-+ if (xon_char != RFCOMM_RPN_XON_CHAR) {
-+ BT_DBG("RPN XON char mismatch 0x%x", xon_char);
-+ xon_char = RFCOMM_RPN_XON_CHAR;
-+ rpn_mask ^= RFCOMM_RPN_PM_XON;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_XOFF) {
-+ xoff_char = rpn->xoff_char;
-+ if (xoff_char != RFCOMM_RPN_XOFF_CHAR) {
-+ BT_DBG("RPN XOFF char mismatch 0x%x", xoff_char);
-+ xoff_char = RFCOMM_RPN_XOFF_CHAR;
-+ rpn_mask ^= RFCOMM_RPN_PM_XOFF;
-+ }
-+ }
-+
-+rpn_out:
-+ rfcomm_send_rpn(s, 0, dlci,
-+ bit_rate, data_bits, stop_bits, parity, flow_ctrl,
-+ xon_char, xoff_char, rpn_mask);
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_rls(struct rfcomm_session *s, int cr, struct sk_buff *skb)
-+{
-+ struct rfcomm_rls *rls = (void *) skb->data;
-+ u8 dlci = __get_dlci(rls->dlci);
-+
-+ BT_DBG("dlci %d cr %d status 0x%x", dlci, cr, rls->status);
-+
-+ if (!cr)
-+ return 0;
-+
-+ /* FIXME: We should probably do something with this
-+ information here. But for now it's sufficient just
-+ to reply -- Bluetooth 1.1 says it's mandatory to
-+ recognise and respond to RLS */
-+
-+ rfcomm_send_rls(s, 0, dlci, rls->status);
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_msc(struct rfcomm_session *s, int cr, struct sk_buff *skb)
-+{
-+ struct rfcomm_msc *msc = (void *) skb->data;
-+ struct rfcomm_dlc *d;
-+ u8 dlci = __get_dlci(msc->dlci);
-+
-+ BT_DBG("dlci %d cr %d v24 0x%x", dlci, cr, msc->v24_sig);
-+
-+ d = rfcomm_dlc_get(s, dlci);
-+ if (!d)
-+ return 0;
-+
-+ if (cr) {
-+ if (msc->v24_sig & RFCOMM_V24_FC && !d->cfc)
-+ set_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+ else
-+ clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+
-+ rfcomm_dlc_lock(d);
-+ if (d->modem_status)
-+ d->modem_status(d, msc->v24_sig);
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_send_msc(s, 0, dlci, msc->v24_sig);
-+
-+ d->mscex |= RFCOMM_MSCEX_RX;
-+ } else
-+ d->mscex |= RFCOMM_MSCEX_TX;
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb)
-+{
-+ struct rfcomm_mcc *mcc = (void *) skb->data;
-+ u8 type, cr, len;
-+
-+ cr = __test_cr(mcc->type);
-+ type = __get_mcc_type(mcc->type);
-+ len = __get_mcc_len(mcc->len);
-+
-+ BT_DBG("%p type 0x%x cr %d", s, type, cr);
-+
-+ skb_pull(skb, 2);
-+
-+ switch (type) {
-+ case RFCOMM_PN:
-+ rfcomm_recv_pn(s, cr, skb);
-+ break;
-+
-+ case RFCOMM_RPN:
-+ rfcomm_recv_rpn(s, cr, len, skb);
-+ break;
-+
-+ case RFCOMM_RLS:
-+ rfcomm_recv_rls(s, cr, skb);
-+ break;
-+
-+ case RFCOMM_MSC:
-+ rfcomm_recv_msc(s, cr, skb);
-+ break;
-+
-+ case RFCOMM_FCOFF:
-+ if (cr) {
-+ set_bit(RFCOMM_TX_THROTTLED, &s->flags);
-+ rfcomm_send_fcoff(s, 0);
-+ }
-+ break;
-+
-+ case RFCOMM_FCON:
-+ if (cr) {
-+ clear_bit(RFCOMM_TX_THROTTLED, &s->flags);
-+ rfcomm_send_fcon(s, 0);
-+ }
-+ break;
-+
-+ case RFCOMM_TEST:
-+ if (cr)
-+ rfcomm_send_test(s, 0, skb->data, skb->len);
-+ break;
-+
-+ case RFCOMM_NSC:
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown control type 0x%02x", type);
-+ rfcomm_send_nsc(s, cr, type);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static int rfcomm_recv_data(struct rfcomm_session *s, u8 dlci, int pf, struct sk_buff *skb)
-+{
-+ struct rfcomm_dlc *d;
-+
-+ BT_DBG("session %p state %ld dlci %d pf %d", s, s->state, dlci, pf);
-+
-+ d = rfcomm_dlc_get(s, dlci);
-+ if (!d) {
-+ rfcomm_send_dm(s, dlci);
-+ goto drop;
-+ }
-+
-+ if (pf && d->cfc) {
-+ u8 credits = *(u8 *) skb->data; skb_pull(skb, 1);
-+
-+ d->tx_credits += credits;
-+ if (d->tx_credits)
-+ clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+ }
-+
-+ if (skb->len && d->state == BT_CONNECTED) {
-+ rfcomm_dlc_lock(d);
-+ d->rx_credits--;
-+ d->data_ready(d, skb);
-+ rfcomm_dlc_unlock(d);
-+ return 0;
-+ }
-+
-+drop:
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
-+{
-+ struct rfcomm_hdr *hdr = (void *) skb->data;
-+ u8 type, dlci, fcs;
-+
-+ dlci = __get_dlci(hdr->addr);
-+ type = __get_type(hdr->ctrl);
-+
-+ /* Trim FCS */
-+ skb->len--; skb->tail--;
-+ fcs = *(u8 *) skb->tail;
-+
-+ if (__check_fcs(skb->data, type, fcs)) {
-+ BT_ERR("bad checksum in packet");
-+ kfree_skb(skb);
-+ return -EILSEQ;
-+ }
-+
-+ if (__test_ea(hdr->len))
-+ skb_pull(skb, 3);
-+ else
-+ skb_pull(skb, 4);
-+
-+ switch (type) {
-+ case RFCOMM_SABM:
-+ if (__test_pf(hdr->ctrl))
-+ rfcomm_recv_sabm(s, dlci);
-+ break;
-+
-+ case RFCOMM_DISC:
-+ if (__test_pf(hdr->ctrl))
-+ rfcomm_recv_disc(s, dlci);
-+ break;
-+
-+ case RFCOMM_UA:
-+ if (__test_pf(hdr->ctrl))
-+ rfcomm_recv_ua(s, dlci);
-+ break;
-+
-+ case RFCOMM_DM:
-+ rfcomm_recv_dm(s, dlci);
-+ break;
-+
-+ case RFCOMM_UIH:
-+ if (dlci)
-+ return rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb);
-+
-+ rfcomm_recv_mcc(s, skb);
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown packet type 0x%02x\n", type);
-+ break;
-+ }
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+/* ---- Connection and data processing ---- */
-+
-+static void rfcomm_process_connect(struct rfcomm_session *s)
-+{
-+ struct rfcomm_dlc *d;
-+ struct list_head *p, *n;
-+
-+ BT_DBG("session %p state %ld", s, s->state);
-+
-+ list_for_each_safe(p, n, &s->dlcs) {
-+ d = list_entry(p, struct rfcomm_dlc, list);
-+ if (d->state == BT_CONFIG) {
-+ d->mtu = s->mtu;
-+ rfcomm_send_pn(s, 1, d);
-+ }
-+ }
-+}
-+
-+/* Send data queued for the DLC.
-+ * Return number of frames left in the queue.
-+ */
-+static inline int rfcomm_process_tx(struct rfcomm_dlc *d)
-+{
-+ struct sk_buff *skb;
-+ int err;
-+
-+ BT_DBG("dlc %p state %ld cfc %d rx_credits %d tx_credits %d",
-+ d, d->state, d->cfc, d->rx_credits, d->tx_credits);
-+
-+ /* Send pending MSC */
-+ if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags))
-+ rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
-+
-+ if (d->cfc) {
-+ /* CFC enabled.
-+ * Give them some credits */
-+ if (!test_bit(RFCOMM_RX_THROTTLED, &d->flags) &&
-+ d->rx_credits <= (d->cfc >> 2)) {
-+ rfcomm_send_credits(d->session, d->addr, d->cfc - d->rx_credits);
-+ d->rx_credits = d->cfc;
-+ }
-+ } else {
-+ /* CFC disabled.
-+ * Give ourselves some credits */
-+ d->tx_credits = 5;
-+ }
-+
-+ if (test_bit(RFCOMM_TX_THROTTLED, &d->flags))
-+ return skb_queue_len(&d->tx_queue);
-+
-+ while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) {
-+ err = rfcomm_send_frame(d->session, skb->data, skb->len);
-+ if (err < 0) {
-+ skb_queue_head(&d->tx_queue, skb);
-+ break;
-+ }
-+ kfree_skb(skb);
-+ d->tx_credits--;
-+ }
-+
-+ if (d->cfc && !d->tx_credits) {
-+ /* We're out of TX credits.
-+ * Set TX_THROTTLED flag to avoid unnesary wakeups by dlc_send. */
-+ set_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+ }
-+
-+ return skb_queue_len(&d->tx_queue);
-+}
-+
-+static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
-+{
-+ struct rfcomm_dlc *d;
-+ struct list_head *p, *n;
-+
-+ BT_DBG("session %p state %ld", s, s->state);
-+
-+ list_for_each_safe(p, n, &s->dlcs) {
-+ d = list_entry(p, struct rfcomm_dlc, list);
-+ if (test_bit(RFCOMM_TIMED_OUT, &d->flags)) {
-+ __rfcomm_dlc_close(d, ETIMEDOUT);
-+ continue;
-+ }
-+
-+ if (test_bit(RFCOMM_TX_THROTTLED, &s->flags))
-+ continue;
-+
-+ if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) &&
-+ d->mscex == RFCOMM_MSCEX_OK)
-+ rfcomm_process_tx(d);
-+ }
-+}
-+
-+static inline void rfcomm_process_rx(struct rfcomm_session *s)
-+{
-+ struct socket *sock = s->sock;
-+ struct sock *sk = sock->sk;
-+ struct sk_buff *skb;
-+
-+ BT_DBG("session %p state %ld qlen %d", s, s->state, skb_queue_len(&sk->receive_queue));
-+
-+ /* Get data directly from socket receive queue without copying it. */
-+ while ((skb = skb_dequeue(&sk->receive_queue))) {
-+ skb_orphan(skb);
-+ rfcomm_recv_frame(s, skb);
-+ }
-+
-+ if (sk->state == BT_CLOSED) {
-+ if (!s->initiator)
-+ rfcomm_session_put(s);
-+
-+ rfcomm_session_close(s, sk->err);
-+ }
-+}
-+
-+static inline void rfcomm_accept_connection(struct rfcomm_session *s)
-+{
-+ struct socket *sock = s->sock, *nsock;
-+ int err;
-+
-+ /* Fast check for a new connection.
-+ * Avoids unnesesary socket allocations. */
-+ if (list_empty(&bluez_pi(sock->sk)->accept_q))
-+ return;
-+
-+ BT_DBG("session %p", s);
-+
-+ nsock = sock_alloc();
-+ if (!nsock)
-+ return;
-+
-+ nsock->type = sock->type;
-+ nsock->ops = sock->ops;
-+
-+ err = sock->ops->accept(sock, nsock, O_NONBLOCK);
-+ if (err < 0) {
-+ sock_release(nsock);
-+ return;
-+ }
-+
-+ /* Set our callbacks */
-+ nsock->sk->data_ready = rfcomm_l2data_ready;
-+ nsock->sk->state_change = rfcomm_l2state_change;
-+
-+ s = rfcomm_session_add(nsock, BT_OPEN);
-+ if (s) {
-+ rfcomm_session_hold(s);
-+ rfcomm_schedule(RFCOMM_SCHED_RX);
-+ } else
-+ sock_release(nsock);
-+}
-+
-+static inline void rfcomm_check_connection(struct rfcomm_session *s)
-+{
-+ struct sock *sk = s->sock->sk;
-+
-+ BT_DBG("%p state %ld", s, s->state);
-+
-+ switch(sk->state) {
-+ case BT_CONNECTED:
-+ s->state = BT_CONNECT;
-+
-+ /* We can adjust MTU on outgoing sessions.
-+ * L2CAP MTU minus UIH header and FCS. */
-+ s->mtu = min(l2cap_pi(sk)->omtu, l2cap_pi(sk)->imtu) - 5;
-+
-+ rfcomm_send_sabm(s, 0);
-+ break;
-+
-+ case BT_CLOSED:
-+ s->state = BT_CLOSED;
-+ rfcomm_session_close(s, sk->err);
-+ break;
-+ }
-+}
-+
-+static inline void rfcomm_process_sessions(void)
-+{
-+ struct list_head *p, *n;
-+
-+ rfcomm_lock();
-+
-+ list_for_each_safe(p, n, &session_list) {
-+ struct rfcomm_session *s;
-+ s = list_entry(p, struct rfcomm_session, list);
-+
-+ if (s->state == BT_LISTEN) {
-+ rfcomm_accept_connection(s);
-+ continue;
-+ }
-+
-+ rfcomm_session_hold(s);
-+
-+ switch (s->state) {
-+ case BT_BOUND:
-+ rfcomm_check_connection(s);
-+ break;
-+
-+ default:
-+ rfcomm_process_rx(s);
-+ break;
-+ }
-+
-+ rfcomm_process_dlcs(s);
-+
-+ rfcomm_session_put(s);
-+ }
-+
-+ rfcomm_unlock();
-+}
-+
-+static void rfcomm_worker(void)
-+{
-+ BT_DBG("");
-+
-+ daemonize(); reparent_to_init();
-+ set_fs(KERNEL_DS);
-+
-+ while (!atomic_read(&terminate)) {
-+ BT_DBG("worker loop event 0x%lx", rfcomm_event);
-+
-+ if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
-+ /* No pending events. Let's sleep.
-+ * Incomming connections and data will wake us up. */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule();
-+ }
-+
-+ /* Process stuff */
-+ clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
-+ rfcomm_process_sessions();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ return;
-+}
-+
-+static int rfcomm_add_listener(bdaddr_t *ba)
-+{
-+ struct sockaddr_l2 addr;
-+ struct l2cap_options opts;
-+ struct socket *sock;
-+ struct rfcomm_session *s;
-+ int size, err = 0;
-+
-+ /* Create socket */
-+ err = rfcomm_l2sock_create(&sock);
-+ if (err < 0) {
-+ BT_ERR("Create socket failed %d", err);
-+ return err;
-+ }
-+
-+ /* Bind socket */
-+ bacpy(&addr.l2_bdaddr, ba);
-+ addr.l2_family = AF_BLUETOOTH;
-+ addr.l2_psm = htobs(RFCOMM_PSM);
-+ err = sock->ops->bind(sock, (struct sockaddr *) &addr, sizeof(addr));
-+ if (err < 0) {
-+ BT_ERR("Bind failed %d", err);
-+ goto failed;
-+ }
-+
-+ /* Set L2CAP options */
-+ size = sizeof(opts);
-+ sock->ops->getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, &size);
-+
-+ opts.imtu = RFCOMM_MAX_L2CAP_MTU;
-+ sock->ops->setsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, size);
-+
-+ /* Start listening on the socket */
-+ err = sock->ops->listen(sock, 10);
-+ if (err) {
-+ BT_ERR("Listen failed %d", err);
-+ goto failed;
-+ }
-+
-+ /* Add listening session */
-+ s = rfcomm_session_add(sock, BT_LISTEN);
-+ if (!s)
-+ goto failed;
-+
-+ rfcomm_session_hold(s);
-+ return 0;
-+failed:
-+ sock_release(sock);
-+ return err;
-+}
-+
-+static void rfcomm_kill_listener(void)
-+{
-+ struct rfcomm_session *s;
-+ struct list_head *p, *n;
-+
-+ BT_DBG("");
-+
-+ list_for_each_safe(p, n, &session_list) {
-+ s = list_entry(p, struct rfcomm_session, list);
-+ rfcomm_session_del(s);
-+ }
-+}
-+
-+static int rfcomm_run(void *unused)
-+{
-+ rfcomm_thread = current;
-+
-+ atomic_inc(&running);
-+
-+ daemonize(); reparent_to_init();
-+
-+ sigfillset(&current->blocked);
-+ set_fs(KERNEL_DS);
-+
-+ sprintf(current->comm, "krfcommd");
-+
-+ BT_DBG("");
-+
-+ rfcomm_add_listener(BDADDR_ANY);
-+
-+ rfcomm_worker();
-+
-+ rfcomm_kill_listener();
-+
-+ atomic_dec(&running);
-+ return 0;
-+}
-+
-+/* ---- Proc fs support ---- */
-+static int rfcomm_dlc_dump(char *buf)
-+{
-+ struct rfcomm_session *s;
-+ struct sock *sk;
-+ struct list_head *p, *pp;
-+ char *ptr = buf;
-+
-+ rfcomm_lock();
-+
-+ list_for_each(p, &session_list) {
-+ s = list_entry(p, struct rfcomm_session, list);
-+ sk = s->sock->sk;
-+
-+ list_for_each(pp, &s->dlcs) {
-+ struct rfcomm_dlc *d;
-+ d = list_entry(pp, struct rfcomm_dlc, list);
-+
-+ ptr += sprintf(ptr, "dlc %s %s %ld %d %d %d %d\n",
-+ batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
-+ d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
-+ }
-+ }
-+
-+ rfcomm_unlock();
-+
-+ return ptr - buf;
-+}
-+
-+extern int rfcomm_sock_dump(char *buf);
-+
-+static int rfcomm_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
-+{
-+ char *ptr = buf;
-+ int len;
-+
-+ BT_DBG("count %d, offset %ld", count, offset);
-+
-+ ptr += rfcomm_dlc_dump(ptr);
-+ ptr += rfcomm_sock_dump(ptr);
-+ len = ptr - buf;
-+
-+ if (len <= count + offset)
-+ *eof = 1;
-+
-+ *start = buf + offset;
-+ len -= offset;
-+
-+ if (len > count)
-+ len = count;
-+ if (len < 0)
-+ len = 0;
-+
-+ return len;
-+}
-+
-+/* ---- Initialization ---- */
-+int __init rfcomm_init(void)
-+{
-+ l2cap_load();
-+
-+ kernel_thread(rfcomm_run, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-+
-+ rfcomm_init_sockets();
-+
-+#ifdef CONFIG_BLUEZ_RFCOMM_TTY
-+ rfcomm_init_ttys();
-+#endif
-+
-+ create_proc_read_entry("bluetooth/rfcomm", 0, 0, rfcomm_read_proc, NULL);
-+
-+ BT_INFO("BlueZ RFCOMM ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>");
-+ BT_INFO("Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>");
-+ return 0;
-+}
-+
-+void rfcomm_cleanup(void)
-+{
-+ /* Terminate working thread.
-+ * ie. Set terminate flag and wake it up */
-+ atomic_inc(&terminate);
-+ rfcomm_schedule(RFCOMM_SCHED_STATE);
-+
-+ /* Wait until thread is running */
-+ while (atomic_read(&running))
-+ schedule();
-+
-+ remove_proc_entry("bluetooth/rfcomm", NULL);
-+
-+#ifdef CONFIG_BLUEZ_RFCOMM_TTY
-+ rfcomm_cleanup_ttys();
-+#endif
-+
-+ rfcomm_cleanup_sockets();
-+ return;
-+}
-+
-+module_init(rfcomm_init);
-+module_exit(rfcomm_cleanup);
-+
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ RFCOMM ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/crc.c linux-2.4.18-mh15/net/bluetooth/rfcomm/crc.c
---- linux-2.4.18/net/bluetooth/rfcomm/crc.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/rfcomm/crc.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,71 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * RFCOMM FCS calculation.
-+ *
-+ * $Id$
-+ */
-+
-+/* reversed, 8-bit, poly=0x07 */
-+unsigned char rfcomm_crc_table[256] = {
-+ 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
-+ 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
-+ 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
-+ 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
-+
-+ 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
-+ 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
-+ 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
-+ 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
-+
-+ 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
-+ 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
-+ 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
-+ 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
-+
-+ 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
-+ 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
-+ 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
-+ 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
-+
-+ 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
-+ 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
-+ 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
-+ 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
-+
-+ 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
-+ 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
-+ 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
-+ 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
-+
-+ 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
-+ 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
-+ 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
-+ 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
-+
-+ 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
-+ 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
-+ 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
-+ 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
-+};
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/Makefile linux-2.4.18-mh15/net/bluetooth/rfcomm/Makefile
---- linux-2.4.18/net/bluetooth/rfcomm/Makefile 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/rfcomm/Makefile 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,11 @@
-+#
-+# Makefile for the Linux Bluetooth RFCOMM layer
-+#
-+
-+O_TARGET := rfcomm.o
-+
-+obj-y := core.o sock.o crc.o
-+obj-$(CONFIG_BLUEZ_RFCOMM_TTY) += tty.o
-+obj-m += $(O_TARGET)
-+
-+include $(TOPDIR)/Rules.make
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/sock.c linux-2.4.18-mh15/net/bluetooth/rfcomm/sock.c
---- linux-2.4.18/net/bluetooth/rfcomm/sock.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/rfcomm/sock.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,847 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * RFCOMM sockets.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/socket.h>
-+#include <linux/skbuff.h>
-+#include <linux/list.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/rfcomm.h>
-+
-+#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+static struct proto_ops rfcomm_sock_ops;
-+
-+static struct bluez_sock_list rfcomm_sk_list = {
-+ lock: RW_LOCK_UNLOCKED
-+};
-+
-+static void rfcomm_sock_close(struct sock *sk);
-+static void rfcomm_sock_kill(struct sock *sk);
-+
-+/* ---- DLC callbacks ----
-+ *
-+ * called under rfcomm_dlc_lock()
-+ */
-+static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb)
-+{
-+ struct sock *sk = d->owner;
-+ if (!sk)
-+ return;
-+
-+ atomic_add(skb->len, &sk->rmem_alloc);
-+ skb_queue_tail(&sk->receive_queue, skb);
-+ sk->data_ready(sk, skb->len);
-+
-+ if (atomic_read(&sk->rmem_alloc) >= sk->rcvbuf)
-+ rfcomm_dlc_throttle(d);
-+}
-+
-+static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
-+{
-+ struct sock *sk = d->owner, *parent;
-+ if (!sk)
-+ return;
-+
-+ BT_DBG("dlc %p state %ld err %d", d, d->state, err);
-+
-+ bh_lock_sock(sk);
-+
-+ if (err)
-+ sk->err = err;
-+ sk->state = d->state;
-+
-+ parent = bluez_pi(sk)->parent;
-+ if (!parent) {
-+ if (d->state == BT_CONNECTED)
-+ rfcomm_session_getaddr(d->session, &bluez_pi(sk)->src, NULL);
-+ sk->state_change(sk);
-+ } else
-+ parent->data_ready(parent, 0);
-+
-+ bh_unlock_sock(sk);
-+}
-+
-+/* ---- Socket functions ---- */
-+static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
-+{
-+ struct sock *sk;
-+
-+ for (sk = rfcomm_sk_list.head; sk; sk = sk->next) {
-+ if (rfcomm_pi(sk)->channel == channel &&
-+ !bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+ }
-+
-+ return sk;
-+}
-+
-+/* Find socket with channel and source bdaddr.
-+ * Returns closest match.
-+ */
-+static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
-+{
-+ struct sock *sk, *sk1 = NULL;
-+
-+ for (sk = rfcomm_sk_list.head; sk; sk = sk->next) {
-+ if (state && sk->state != state)
-+ continue;
-+
-+ if (rfcomm_pi(sk)->channel == channel) {
-+ /* Exact match. */
-+ if (!bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+
-+ /* Closest match */
-+ if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
-+ sk1 = sk;
-+ }
-+ }
-+ return sk ? sk : sk1;
-+}
-+
-+/* Find socket with given address (channel, src).
-+ * Returns locked socket */
-+static inline struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
-+{
-+ struct sock *s;
-+ read_lock(&rfcomm_sk_list.lock);
-+ s = __rfcomm_get_sock_by_channel(state, channel, src);
-+ if (s) bh_lock_sock(s);
-+ read_unlock(&rfcomm_sk_list.lock);
-+ return s;
-+}
-+
-+static void rfcomm_sock_destruct(struct sock *sk)
-+{
-+ struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
-+
-+ BT_DBG("sk %p dlc %p", sk, d);
-+
-+ skb_queue_purge(&sk->receive_queue);
-+ skb_queue_purge(&sk->write_queue);
-+
-+ rfcomm_dlc_lock(d);
-+ rfcomm_pi(sk)->dlc = NULL;
-+
-+ /* Detach DLC if it's owned by this socket */
-+ if (d->owner == sk)
-+ d->owner = NULL;
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_dlc_put(d);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void rfcomm_sock_cleanup_listen(struct sock *parent)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("parent %p", parent);
-+
-+ /* Close not yet accepted dlcs */
-+ while ((sk = bluez_accept_dequeue(parent, NULL))) {
-+ rfcomm_sock_close(sk);
-+ rfcomm_sock_kill(sk);
-+ }
-+
-+ parent->state = BT_CLOSED;
-+ parent->zapped = 1;
-+}
-+
-+/* Kill socket (only if zapped and orphan)
-+ * Must be called on unlocked socket.
-+ */
-+static void rfcomm_sock_kill(struct sock *sk)
-+{
-+ if (!sk->zapped || sk->socket)
-+ return;
-+
-+ BT_DBG("sk %p state %d refcnt %d", sk, sk->state, atomic_read(&sk->refcnt));
-+
-+ /* Kill poor orphan */
-+ bluez_sock_unlink(&rfcomm_sk_list, sk);
-+ sk->dead = 1;
-+ sock_put(sk);
-+}
-+
-+static void __rfcomm_sock_close(struct sock *sk)
-+{
-+ struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
-+
-+ BT_DBG("sk %p state %d socket %p", sk, sk->state, sk->socket);
-+
-+ switch (sk->state) {
-+ case BT_LISTEN:
-+ rfcomm_sock_cleanup_listen(sk);
-+ break;
-+
-+ case BT_CONNECT:
-+ case BT_CONNECT2:
-+ case BT_CONFIG:
-+ case BT_CONNECTED:
-+ rfcomm_dlc_close(d, 0);
-+
-+ default:
-+ sk->zapped = 1;
-+ break;
-+ }
-+}
-+
-+/* Close socket.
-+ * Must be called on unlocked socket.
-+ */
-+static void rfcomm_sock_close(struct sock *sk)
-+{
-+ lock_sock(sk);
-+ __rfcomm_sock_close(sk);
-+ release_sock(sk);
-+}
-+
-+static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
-+{
-+ BT_DBG("sk %p", sk);
-+
-+ if (parent)
-+ sk->type = parent->type;
-+}
-+
-+static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, int prio)
-+{
-+ struct rfcomm_dlc *d;
-+ struct sock *sk;
-+
-+ sk = sk_alloc(PF_BLUETOOTH, prio, 1);
-+ if (!sk)
-+ return NULL;
-+
-+ d = rfcomm_dlc_alloc(prio);
-+ if (!d) {
-+ sk_free(sk);
-+ return NULL;
-+ }
-+ d->data_ready = rfcomm_sk_data_ready;
-+ d->state_change = rfcomm_sk_state_change;
-+
-+ rfcomm_pi(sk)->dlc = d;
-+ d->owner = sk;
-+
-+ bluez_sock_init(sock, sk);
-+
-+ sk->zapped = 0;
-+
-+ sk->destruct = rfcomm_sock_destruct;
-+ sk->sndtimeo = RFCOMM_CONN_TIMEOUT;
-+
-+ sk->sndbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
-+ sk->rcvbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
-+
-+ sk->protocol = proto;
-+ sk->state = BT_OPEN;
-+
-+ bluez_sock_link(&rfcomm_sk_list, sk);
-+
-+ BT_DBG("sk %p", sk);
-+
-+ MOD_INC_USE_COUNT;
-+ return sk;
-+}
-+
-+static int rfcomm_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ sock->state = SS_UNCONNECTED;
-+
-+ if (sock->type != SOCK_STREAM && sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &rfcomm_sock_ops;
-+
-+ if (!(sk = rfcomm_sock_alloc(sock, protocol, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ rfcomm_sock_init(sk, NULL);
-+ return 0;
-+}
-+
-+static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
-+{
-+ struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p %s", sk, batostr(&sa->rc_bdaddr));
-+
-+ if (!addr || addr->sa_family != AF_BLUETOOTH)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_OPEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ write_lock_bh(&rfcomm_sk_list.lock);
-+
-+ if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
-+ err = -EADDRINUSE;
-+ } else {
-+ /* Save source address */
-+ bacpy(&bluez_pi(sk)->src, &sa->rc_bdaddr);
-+ rfcomm_pi(sk)->channel = sa->rc_channel;
-+ sk->state = BT_BOUND;
-+ }
-+
-+ write_unlock_bh(&rfcomm_sk_list.lock);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
-+{
-+ struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
-+ struct sock *sk = sock->sk;
-+ struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
-+ int err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc))
-+ return -EINVAL;
-+
-+ if (sk->state != BT_OPEN && sk->state != BT_BOUND)
-+ return -EBADFD;
-+
-+ if (sk->type != SOCK_STREAM)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ sk->state = BT_CONNECT;
-+ bacpy(&bluez_pi(sk)->dst, &sa->rc_bdaddr);
-+ rfcomm_pi(sk)->channel = sa->rc_channel;
-+
-+ err = rfcomm_dlc_open(d, &bluez_pi(sk)->src, &sa->rc_bdaddr, sa->rc_channel);
-+ if (!err)
-+ err = bluez_sock_wait_state(sk, BT_CONNECTED,
-+ sock_sndtimeo(sk, flags & O_NONBLOCK));
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int rfcomm_sock_listen(struct socket *sock, int backlog)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p backlog %d", sk, backlog);
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_BOUND) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ sk->max_ack_backlog = backlog;
-+ sk->ack_backlog = 0;
-+ sk->state = BT_LISTEN;
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct sock *sk = sock->sk, *nsk;
-+ long timeo;
-+ int err = 0;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
-+
-+ BT_DBG("sk %p timeo %ld", sk, timeo);
-+
-+ /* Wait for an incoming connection. (wake-one). */
-+ add_wait_queue_exclusive(sk->sleep, &wait);
-+ while (!(nsk = bluez_accept_dequeue(sk, newsock))) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ break;
-+ }
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ break;
-+ }
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ if (err)
-+ goto done;
-+
-+ newsock->state = SS_CONNECTED;
-+
-+ BT_DBG("new socket %p", nsk);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
-+{
-+ struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ sa->rc_family = AF_BLUETOOTH;
-+ sa->rc_channel = rfcomm_pi(sk)->channel;
-+ if (peer)
-+ bacpy(&sa->rc_bdaddr, &bluez_pi(sk)->dst);
-+ else
-+ bacpy(&sa->rc_bdaddr, &bluez_pi(sk)->src);
-+
-+ *len = sizeof(struct sockaddr_rc);
-+ return 0;
-+}
-+
-+static int rfcomm_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
-+ struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
-+ struct sk_buff *skb;
-+ int err, size;
-+ int sent = 0;
-+
-+ if (msg->msg_flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ if (sk->shutdown & SEND_SHUTDOWN)
-+ return -EPIPE;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ lock_sock(sk);
-+
-+ while (len) {
-+ size = min_t(uint, len, d->mtu);
-+
-+ skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE,
-+ msg->msg_flags & MSG_DONTWAIT, &err);
-+ if (!skb)
-+ break;
-+ skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
-+
-+ err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
-+ if (err) {
-+ kfree_skb(skb);
-+ sent = err;
-+ break;
-+ }
-+
-+ err = rfcomm_dlc_send(d, skb);
-+ if (err < 0) {
-+ kfree_skb(skb);
-+ break;
-+ }
-+
-+ sent += size;
-+ len -= size;
-+ }
-+
-+ release_sock(sk);
-+
-+ return sent ? sent : err;
-+}
-+
-+static long rfcomm_sock_data_wait(struct sock *sk, long timeo)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+ add_wait_queue(sk->sleep, &wait);
-+ for (;;) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (skb_queue_len(&sk->receive_queue) || sk->err || (sk->shutdown & RCV_SHUTDOWN) ||
-+ signal_pending(current) || !timeo)
-+ break;
-+
-+ set_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+ clear_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
-+ }
-+
-+ __set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+ return timeo;
-+}
-+
-+static int rfcomm_sock_recvmsg(struct socket *sock, struct msghdr *msg, int size,
-+ int flags, struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ int target, err = 0, copied = 0;
-+ long timeo;
-+
-+ if (flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ msg->msg_namelen = 0;
-+
-+ BT_DBG("sk %p size %d", sk, size);
-+
-+ lock_sock(sk);
-+
-+ target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
-+ timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
-+
-+ do {
-+ struct sk_buff *skb;
-+ int chunk;
-+
-+ skb = skb_dequeue(&sk->receive_queue);
-+ if (!skb) {
-+ if (copied >= target)
-+ break;
-+
-+ if ((err = sock_error(sk)) != 0)
-+ break;
-+ if (sk->shutdown & RCV_SHUTDOWN)
-+ break;
-+
-+ err = -EAGAIN;
-+ if (!timeo)
-+ break;
-+
-+ timeo = rfcomm_sock_data_wait(sk, timeo);
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ goto out;
-+ }
-+ continue;
-+ }
-+
-+ chunk = min_t(unsigned int, skb->len, size);
-+ if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
-+ skb_queue_head(&sk->receive_queue, skb);
-+ if (!copied)
-+ copied = -EFAULT;
-+ break;
-+ }
-+ copied += chunk;
-+ size -= chunk;
-+
-+ if (!(flags & MSG_PEEK)) {
-+ atomic_sub(chunk, &sk->rmem_alloc);
-+
-+ skb_pull(skb, chunk);
-+ if (skb->len) {
-+ skb_queue_head(&sk->receive_queue, skb);
-+ break;
-+ }
-+ kfree_skb(skb);
-+
-+ } else {
-+ /* put message back and return */
-+ skb_queue_head(&sk->receive_queue, skb);
-+ break;
-+ }
-+ } while (size);
-+
-+out:
-+ if (atomic_read(&sk->rmem_alloc) <= (sk->rcvbuf >> 2))
-+ rfcomm_dlc_unthrottle(rfcomm_pi(sk)->dlc);
-+
-+ release_sock(sk);
-+ return copied ? : err;
-+}
-+
-+static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ int len, err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (get_user(len, optlen))
-+ return -EFAULT;
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct sock *sk = sock->sk;
-+ int err;
-+
-+ lock_sock(sk);
-+
-+#ifdef CONFIG_BLUEZ_RFCOMM_TTY
-+ err = rfcomm_dev_ioctl(sk, cmd, arg);
-+#else
-+ err = -EOPNOTSUPP;
-+#endif
-+
-+ release_sock(sk);
-+
-+ return err;
-+}
-+
-+static int rfcomm_sock_shutdown(struct socket *sock, int how)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk) return 0;
-+
-+ lock_sock(sk);
-+ if (!sk->shutdown) {
-+ sk->shutdown = SHUTDOWN_MASK;
-+ __rfcomm_sock_close(sk);
-+
-+ if (sk->linger)
-+ err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
-+ }
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ err = rfcomm_sock_shutdown(sock, 2);
-+
-+ sock_orphan(sk);
-+ rfcomm_sock_kill(sk);
-+ return err;
-+}
-+
-+/* ---- RFCOMM core layer callbacks ----
-+ *
-+ * called under rfcomm_lock()
-+ */
-+int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d)
-+{
-+ struct sock *sk, *parent;
-+ bdaddr_t src, dst;
-+ int result = 0;
-+
-+ BT_DBG("session %p channel %d", s, channel);
-+
-+ rfcomm_session_getaddr(s, &src, &dst);
-+
-+ /* Check if we have socket listening on this channel */
-+ parent = rfcomm_get_sock_by_channel(BT_LISTEN, channel, &src);
-+ if (!parent)
-+ return 0;
-+
-+ /* Check for backlog size */
-+ if (parent->ack_backlog > parent->max_ack_backlog) {
-+ BT_DBG("backlog full %d", parent->ack_backlog);
-+ goto done;
-+ }
-+
-+ sk = rfcomm_sock_alloc(NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
-+ if (!sk)
-+ goto done;
-+
-+ rfcomm_sock_init(sk, parent);
-+ bacpy(&bluez_pi(sk)->src, &src);
-+ bacpy(&bluez_pi(sk)->dst, &dst);
-+ rfcomm_pi(sk)->channel = channel;
-+
-+ sk->state = BT_CONFIG;
-+ bluez_accept_enqueue(parent, sk);
-+
-+ /* Accept connection and return socket DLC */
-+ *d = rfcomm_pi(sk)->dlc;
-+ result = 1;
-+
-+done:
-+ bh_unlock_sock(parent);
-+ return result;
-+}
-+
-+/* ---- Proc fs support ---- */
-+int rfcomm_sock_dump(char *buf)
-+{
-+ struct bluez_sock_list *list = &rfcomm_sk_list;
-+ struct rfcomm_pinfo *pi;
-+ struct sock *sk;
-+ char *ptr = buf;
-+
-+ write_lock_bh(&list->lock);
-+
-+ for (sk = list->head; sk; sk = sk->next) {
-+ pi = rfcomm_pi(sk);
-+ ptr += sprintf(ptr, "sk %s %s %d %d\n",
-+ batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
-+ sk->state, rfcomm_pi(sk)->channel);
-+ }
-+
-+ write_unlock_bh(&list->lock);
-+
-+ return ptr - buf;
-+}
-+
-+static struct proto_ops rfcomm_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: rfcomm_sock_release,
-+ bind: rfcomm_sock_bind,
-+ connect: rfcomm_sock_connect,
-+ listen: rfcomm_sock_listen,
-+ accept: rfcomm_sock_accept,
-+ getname: rfcomm_sock_getname,
-+ sendmsg: rfcomm_sock_sendmsg,
-+ recvmsg: rfcomm_sock_recvmsg,
-+ shutdown: rfcomm_sock_shutdown,
-+ setsockopt: rfcomm_sock_setsockopt,
-+ getsockopt: rfcomm_sock_getsockopt,
-+ ioctl: rfcomm_sock_ioctl,
-+ poll: bluez_sock_poll,
-+ socketpair: sock_no_socketpair,
-+ mmap: sock_no_mmap
-+};
-+
-+static struct net_proto_family rfcomm_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: rfcomm_sock_create
-+};
-+
-+int rfcomm_init_sockets(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_RFCOMM, &rfcomm_sock_family_ops))) {
-+ BT_ERR("Can't register RFCOMM socket layer");
-+ return err;
-+ }
-+
-+ return 0;
-+}
-+
-+void rfcomm_cleanup_sockets(void)
-+{
-+ int err;
-+
-+ /* Unregister socket, protocol and notifier */
-+ if ((err = bluez_sock_unregister(BTPROTO_RFCOMM)))
-+ BT_ERR("Can't unregister RFCOMM socket layer %d", err);
-+}
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/tty.c linux-2.4.18-mh15/net/bluetooth/rfcomm/tty.c
---- linux-2.4.18/net/bluetooth/rfcomm/tty.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/rfcomm/tty.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,960 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * RFCOMM TTY.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/tty.h>
-+#include <linux/tty_driver.h>
-+#include <linux/tty_flip.h>
-+
-+#include <linux/slab.h>
-+#include <linux/skbuff.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/rfcomm.h>
-+
-+#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define RFCOMM_TTY_MAGIC 0x6d02 /* magic number for rfcomm struct */
-+#define RFCOMM_TTY_PORTS RFCOMM_MAX_DEV /* whole lotta rfcomm devices */
-+#define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */
-+#define RFCOMM_TTY_MINOR 0
-+
-+struct rfcomm_dev {
-+ struct list_head list;
-+ atomic_t refcnt;
-+
-+ char name[12];
-+ int id;
-+ unsigned long flags;
-+ int opened;
-+ int err;
-+
-+ bdaddr_t src;
-+ bdaddr_t dst;
-+ u8 channel;
-+
-+ uint modem_status;
-+
-+ struct rfcomm_dlc *dlc;
-+ struct tty_struct *tty;
-+ wait_queue_head_t wait;
-+ struct tasklet_struct wakeup_task;
-+
-+ atomic_t wmem_alloc;
-+};
-+
-+static LIST_HEAD(rfcomm_dev_list);
-+static rwlock_t rfcomm_dev_lock = RW_LOCK_UNLOCKED;
-+
-+static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
-+static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
-+static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
-+
-+static void rfcomm_tty_wakeup(unsigned long arg);
-+
-+/* ---- Device functions ---- */
-+static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
-+{
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+
-+ BT_DBG("dev %p dlc %p", dev, dlc);
-+
-+ rfcomm_dlc_lock(dlc);
-+ /* Detach DLC if it's owned by this dev */
-+ if (dlc->owner == dev)
-+ dlc->owner = NULL;
-+ rfcomm_dlc_unlock(dlc);
-+
-+ rfcomm_dlc_put(dlc);
-+ kfree(dev);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static inline void rfcomm_dev_hold(struct rfcomm_dev *dev)
-+{
-+ atomic_inc(&dev->refcnt);
-+}
-+
-+static inline void rfcomm_dev_put(struct rfcomm_dev *dev)
-+{
-+ /* The reason this isn't actually a race, as you no
-+ doubt have a little voice screaming at you in your
-+ head, is that the refcount should never actually
-+ reach zero unless the device has already been taken
-+ off the list, in rfcomm_dev_del(). And if that's not
-+ true, we'll hit the BUG() in rfcomm_dev_destruct()
-+ anyway. */
-+ if (atomic_dec_and_test(&dev->refcnt))
-+ rfcomm_dev_destruct(dev);
-+}
-+
-+static struct rfcomm_dev *__rfcomm_dev_get(int id)
-+{
-+ struct rfcomm_dev *dev;
-+ struct list_head *p;
-+
-+ list_for_each(p, &rfcomm_dev_list) {
-+ dev = list_entry(p, struct rfcomm_dev, list);
-+ if (dev->id == id)
-+ return dev;
-+ }
-+
-+ return NULL;
-+}
-+
-+static inline struct rfcomm_dev *rfcomm_dev_get(int id)
-+{
-+ struct rfcomm_dev *dev;
-+
-+ read_lock(&rfcomm_dev_lock);
-+
-+ dev = __rfcomm_dev_get(id);
-+ if (dev)
-+ rfcomm_dev_hold(dev);
-+
-+ read_unlock(&rfcomm_dev_lock);
-+
-+ return dev;
-+}
-+
-+static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
-+{
-+ struct rfcomm_dev *dev;
-+ struct list_head *head = &rfcomm_dev_list, *p;
-+ int err = 0;
-+
-+ BT_DBG("id %d channel %d", req->dev_id, req->channel);
-+
-+ dev = kmalloc(sizeof(struct rfcomm_dev), GFP_KERNEL);
-+ if (!dev)
-+ return -ENOMEM;
-+ memset(dev, 0, sizeof(struct rfcomm_dev));
-+
-+ write_lock_bh(&rfcomm_dev_lock);
-+
-+ if (req->dev_id < 0) {
-+ dev->id = 0;
-+
-+ list_for_each(p, &rfcomm_dev_list) {
-+ if (list_entry(p, struct rfcomm_dev, list)->id != dev->id)
-+ break;
-+
-+ dev->id++;
-+ head = p;
-+ }
-+ } else {
-+ dev->id = req->dev_id;
-+
-+ list_for_each(p, &rfcomm_dev_list) {
-+ struct rfcomm_dev *entry = list_entry(p, struct rfcomm_dev, list);
-+
-+ if (entry->id == dev->id) {
-+ err = -EADDRINUSE;
-+ goto out;
-+ }
-+
-+ if (entry->id > dev->id - 1)
-+ break;
-+
-+ head = p;
-+ }
-+ }
-+
-+ if ((dev->id < 0) || (dev->id > RFCOMM_MAX_DEV - 1)) {
-+ err = -ENFILE;
-+ goto out;
-+ }
-+
-+ sprintf(dev->name, "rfcomm%d", dev->id);
-+
-+ list_add(&dev->list, head);
-+ atomic_set(&dev->refcnt, 1);
-+
-+ bacpy(&dev->src, &req->src);
-+ bacpy(&dev->dst, &req->dst);
-+ dev->channel = req->channel;
-+
-+ dev->flags = req->flags &
-+ ((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
-+
-+ init_waitqueue_head(&dev->wait);
-+ tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev);
-+
-+ rfcomm_dlc_lock(dlc);
-+ dlc->data_ready = rfcomm_dev_data_ready;
-+ dlc->state_change = rfcomm_dev_state_change;
-+ dlc->modem_status = rfcomm_dev_modem_status;
-+
-+ dlc->owner = dev;
-+ dev->dlc = dlc;
-+ rfcomm_dlc_unlock(dlc);
-+
-+ MOD_INC_USE_COUNT;
-+
-+out:
-+ write_unlock_bh(&rfcomm_dev_lock);
-+
-+ if (err) {
-+ kfree(dev);
-+ return err;
-+ } else
-+ return dev->id;
-+}
-+
-+static void rfcomm_dev_del(struct rfcomm_dev *dev)
-+{
-+ BT_DBG("dev %p", dev);
-+
-+ write_lock_bh(&rfcomm_dev_lock);
-+ list_del_init(&dev->list);
-+ write_unlock_bh(&rfcomm_dev_lock);
-+
-+ rfcomm_dev_put(dev);
-+}
-+
-+/* ---- Send buffer ---- */
-+
-+static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc)
-+{
-+ /* We can't let it be zero, because we don't get a callback
-+ when tx_credits becomes nonzero, hence we'd never wake up */
-+ return dlc->mtu * (dlc->tx_credits?:1);
-+}
-+
-+static void rfcomm_wfree(struct sk_buff *skb)
-+{
-+ struct rfcomm_dev *dev = (void *) skb->sk;
-+ atomic_sub(skb->truesize, &dev->wmem_alloc);
-+ if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags))
-+ tasklet_schedule(&dev->wakeup_task);
-+ rfcomm_dev_put(dev);
-+}
-+
-+static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
-+{
-+ rfcomm_dev_hold(dev);
-+ atomic_add(skb->truesize, &dev->wmem_alloc);
-+ skb->sk = (void *) dev;
-+ skb->destructor = rfcomm_wfree;
-+}
-+
-+static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, int force, int priority)
-+{
-+ if (force || atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) {
-+ struct sk_buff *skb = alloc_skb(size, priority);
-+ if (skb) {
-+ rfcomm_set_owner_w(skb, dev);
-+ return skb;
-+ }
-+ }
-+ return NULL;
-+}
-+
-+/* ---- Device IOCTLs ---- */
-+
-+#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
-+
-+static int rfcomm_create_dev(struct sock *sk, unsigned long arg)
-+{
-+ struct rfcomm_dev_req req;
-+ struct rfcomm_dlc *dlc;
-+ int id;
-+
-+ if (copy_from_user(&req, (void *) arg, sizeof(req)))
-+ return -EFAULT;
-+
-+ BT_DBG("sk %p dev_id %id flags 0x%x", sk, req.dev_id, req.flags);
-+
-+ if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
-+ return -EPERM;
-+
-+ if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
-+ /* Socket must be connected */
-+ if (sk->state != BT_CONNECTED)
-+ return -EBADFD;
-+
-+ dlc = rfcomm_pi(sk)->dlc;
-+ rfcomm_dlc_hold(dlc);
-+ } else {
-+ dlc = rfcomm_dlc_alloc(GFP_KERNEL);
-+ if (!dlc)
-+ return -ENOMEM;
-+ }
-+
-+ id = rfcomm_dev_add(&req, dlc);
-+ if (id < 0) {
-+ rfcomm_dlc_put(dlc);
-+ return id;
-+ }
-+
-+ if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
-+ /* DLC is now used by device.
-+ * Socket must be disconnected */
-+ sk->state = BT_CLOSED;
-+ }
-+
-+ return id;
-+}
-+
-+static int rfcomm_release_dev(unsigned long arg)
-+{
-+ struct rfcomm_dev_req req;
-+ struct rfcomm_dev *dev;
-+
-+ if (copy_from_user(&req, (void *) arg, sizeof(req)))
-+ return -EFAULT;
-+
-+ BT_DBG("dev_id %id flags 0x%x", req.dev_id, req.flags);
-+
-+ if (!(dev = rfcomm_dev_get(req.dev_id)))
-+ return -ENODEV;
-+
-+ if (dev->flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN)) {
-+ rfcomm_dev_put(dev);
-+ return -EPERM;
-+ }
-+
-+ if (req.flags & (1 << RFCOMM_HANGUP_NOW))
-+ rfcomm_dlc_close(dev->dlc, 0);
-+
-+ rfcomm_dev_del(dev);
-+ rfcomm_dev_put(dev);
-+ return 0;
-+}
-+
-+static int rfcomm_get_dev_list(unsigned long arg)
-+{
-+ struct rfcomm_dev_list_req *dl;
-+ struct rfcomm_dev_info *di;
-+ struct list_head *p;
-+ int n = 0, size, err;
-+ u16 dev_num;
-+
-+ BT_DBG("");
-+
-+ if (get_user(dev_num, (u16 *) arg))
-+ return -EFAULT;
-+
-+ if (!dev_num || dev_num > (PAGE_SIZE * 4) / sizeof(*di))
-+ return -EINVAL;
-+
-+ size = sizeof(*dl) + dev_num * sizeof(*di);
-+
-+ if (!(dl = kmalloc(size, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ di = dl->dev_info;
-+
-+ read_lock_bh(&rfcomm_dev_lock);
-+
-+ list_for_each(p, &rfcomm_dev_list) {
-+ struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list);
-+ (di + n)->id = dev->id;
-+ (di + n)->flags = dev->flags;
-+ (di + n)->state = dev->dlc->state;
-+ (di + n)->channel = dev->channel;
-+ bacpy(&(di + n)->src, &dev->src);
-+ bacpy(&(di + n)->dst, &dev->dst);
-+ if (++n >= dev_num)
-+ break;
-+ }
-+
-+ read_unlock_bh(&rfcomm_dev_lock);
-+
-+ dl->dev_num = n;
-+ size = sizeof(*dl) + n * sizeof(*di);
-+
-+ err = copy_to_user((void *) arg, dl, size);
-+ kfree(dl);
-+
-+ return err ? -EFAULT : 0;
-+}
-+
-+static int rfcomm_get_dev_info(unsigned long arg)
-+{
-+ struct rfcomm_dev *dev;
-+ struct rfcomm_dev_info di;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ if (copy_from_user(&di, (void *)arg, sizeof(di)))
-+ return -EFAULT;
-+
-+ if (!(dev = rfcomm_dev_get(di.id)))
-+ return -ENODEV;
-+
-+ di.flags = dev->flags;
-+ di.channel = dev->channel;
-+ di.state = dev->dlc->state;
-+ bacpy(&di.src, &dev->src);
-+ bacpy(&di.dst, &dev->dst);
-+
-+ if (copy_to_user((void *)arg, &di, sizeof(di)))
-+ err = -EFAULT;
-+
-+ rfcomm_dev_put(dev);
-+ return err;
-+}
-+
-+int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
-+{
-+ BT_DBG("cmd %d arg %ld", cmd, arg);
-+
-+ switch (cmd) {
-+ case RFCOMMCREATEDEV:
-+ return rfcomm_create_dev(sk, arg);
-+
-+ case RFCOMMRELEASEDEV:
-+ return rfcomm_release_dev(arg);
-+
-+ case RFCOMMGETDEVLIST:
-+ return rfcomm_get_dev_list(arg);
-+
-+ case RFCOMMGETDEVINFO:
-+ return rfcomm_get_dev_info(arg);
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+/* ---- DLC callbacks ---- */
-+static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
-+{
-+ struct rfcomm_dev *dev = dlc->owner;
-+ struct tty_struct *tty;
-+
-+ if (!dev || !(tty = dev->tty)) {
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len);
-+
-+ if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
-+ register int i;
-+ for (i = 0; i < skb->len; i++) {
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+ tty_flip_buffer_push(tty);
-+
-+ tty_insert_flip_char(tty, skb->data[i], 0);
-+ }
-+ tty_flip_buffer_push(tty);
-+ } else
-+ tty->ldisc.receive_buf(tty, skb->data, NULL, skb->len);
-+
-+ kfree_skb(skb);
-+}
-+
-+static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
-+{
-+ struct rfcomm_dev *dev = dlc->owner;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("dlc %p dev %p err %d", dlc, dev, err);
-+
-+ dev->err = err;
-+ wake_up_interruptible(&dev->wait);
-+
-+ if (dlc->state == BT_CLOSED) {
-+ if (!dev->tty) {
-+ if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
-+ rfcomm_dev_hold(dev);
-+ rfcomm_dev_del(dev);
-+
-+ /* We have to drop DLC lock here, otherwise
-+ rfcomm_dev_put() will dead lock if it's
-+ the last reference. */
-+ rfcomm_dlc_unlock(dlc);
-+ rfcomm_dev_put(dev);
-+ rfcomm_dlc_lock(dlc);
-+ }
-+ } else
-+ tty_hangup(dev->tty);
-+ }
-+}
-+
-+static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
-+{
-+ struct rfcomm_dev *dev = dlc->owner;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig);
-+
-+ dev->modem_status =
-+ ((v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0) |
-+ ((v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0) |
-+ ((v24_sig & RFCOMM_V24_IC) ? TIOCM_RI : 0) |
-+ ((v24_sig & RFCOMM_V24_DV) ? TIOCM_CD : 0);
-+}
-+
-+/* ---- TTY functions ---- */
-+static void rfcomm_tty_wakeup(unsigned long arg)
-+{
-+ struct rfcomm_dev *dev = (void *) arg;
-+ struct tty_struct *tty = dev->tty;
-+ if (!tty)
-+ return;
-+
-+ BT_DBG("dev %p tty %p", dev, tty);
-+
-+ if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
-+ (tty->ldisc.write_wakeup)(tty);
-+
-+ wake_up_interruptible(&tty->write_wait);
-+#ifdef SERIAL_HAVE_POLL_WAIT
-+ wake_up_interruptible(&tty->poll_wait);
-+#endif
-+}
-+
-+static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct rfcomm_dev *dev;
-+ struct rfcomm_dlc *dlc;
-+ int err, id;
-+
-+ id = MINOR(tty->device) - tty->driver.minor_start;
-+
-+ BT_DBG("tty %p id %d", tty, id);
-+
-+ /* We don't leak this refcount. For reasons which are not entirely
-+ clear, the TTY layer will call our ->close() method even if the
-+ open fails. We decrease the refcount there, and decreasing it
-+ here too would cause breakage. */
-+ dev = rfcomm_dev_get(id);
-+ if (!dev)
-+ return -ENODEV;
-+
-+ BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst), dev->channel, dev->opened);
-+
-+ if (dev->opened++ != 0)
-+ return 0;
-+
-+ dlc = dev->dlc;
-+
-+ /* Attach TTY and open DLC */
-+
-+ rfcomm_dlc_lock(dlc);
-+ tty->driver_data = dev;
-+ dev->tty = tty;
-+ rfcomm_dlc_unlock(dlc);
-+ set_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
-+
-+ err = rfcomm_dlc_open(dlc, &dev->src, &dev->dst, dev->channel);
-+ if (err < 0)
-+ return err;
-+
-+ /* Wait for DLC to connect */
-+ add_wait_queue(&dev->wait, &wait);
-+ while (1) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (dlc->state == BT_CLOSED) {
-+ err = -dev->err;
-+ break;
-+ }
-+
-+ if (dlc->state == BT_CONNECTED)
-+ break;
-+
-+ if (signal_pending(current)) {
-+ err = -EINTR;
-+ break;
-+ }
-+
-+ schedule();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&dev->wait, &wait);
-+
-+ return err;
-+}
-+
-+static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, dev->opened);
-+
-+ if (--dev->opened == 0) {
-+ /* Close DLC and dettach TTY */
-+ rfcomm_dlc_close(dev->dlc, 0);
-+
-+ clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
-+ tasklet_kill(&dev->wakeup_task);
-+
-+ rfcomm_dlc_lock(dev->dlc);
-+ tty->driver_data = NULL;
-+ dev->tty = NULL;
-+ rfcomm_dlc_unlock(dev->dlc);
-+ }
-+
-+ rfcomm_dev_put(dev);
-+}
-+
-+static int rfcomm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+ struct sk_buff *skb;
-+ int err = 0, sent = 0, size;
-+
-+ BT_DBG("tty %p from_user %d count %d", tty, from_user, count);
-+
-+ while (count) {
-+ size = min_t(uint, count, dlc->mtu);
-+
-+ if (from_user)
-+ skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, 0, GFP_KERNEL);
-+ else
-+ skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, 0, GFP_ATOMIC);
-+
-+ if (!skb)
-+ break;
-+
-+ skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
-+
-+ if (from_user)
-+ copy_from_user(skb_put(skb, size), buf + sent, size);
-+ else
-+ memcpy(skb_put(skb, size), buf + sent, size);
-+
-+ if ((err = rfcomm_dlc_send(dlc, skb)) < 0) {
-+ kfree_skb(skb);
-+ break;
-+ }
-+
-+ sent += size;
-+ count -= size;
-+ }
-+
-+ return sent ? sent : err;
-+}
-+
-+static void rfcomm_tty_put_char(struct tty_struct *tty, unsigned char ch)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+ struct sk_buff *skb;
-+
-+ BT_DBG("tty %p char %x", tty, ch);
-+
-+ skb = rfcomm_wmalloc(dev, 1 + RFCOMM_SKB_RESERVE, 1, GFP_ATOMIC);
-+
-+ if (!skb)
-+ return;
-+
-+ skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
-+
-+ *(char *)skb_put(skb, 1) = ch;
-+
-+ if ((rfcomm_dlc_send(dlc, skb)) < 0)
-+ kfree_skb(skb);
-+}
-+
-+static int rfcomm_tty_write_room(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ int room;
-+
-+ BT_DBG("tty %p", tty);
-+
-+ room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc);
-+ if (room < 0)
-+ room = 0;
-+
-+ return room;
-+}
-+
-+static int rfcomm_tty_set_modem_status(uint cmd, struct rfcomm_dlc *dlc, uint status)
-+{
-+ u8 v24_sig, mask;
-+
-+ BT_DBG("dlc %p cmd 0x%02x", dlc, cmd);
-+
-+ if (cmd == TIOCMSET)
-+ v24_sig = 0;
-+ else
-+ rfcomm_dlc_get_modem_status(dlc, &v24_sig);
-+
-+ mask = ((status & TIOCM_DSR) ? RFCOMM_V24_RTC : 0) |
-+ ((status & TIOCM_DTR) ? RFCOMM_V24_RTC : 0) |
-+ ((status & TIOCM_RTS) ? RFCOMM_V24_RTR : 0) |
-+ ((status & TIOCM_CTS) ? RFCOMM_V24_RTR : 0) |
-+ ((status & TIOCM_RI) ? RFCOMM_V24_IC : 0) |
-+ ((status & TIOCM_CD) ? RFCOMM_V24_DV : 0);
-+
-+ if (cmd == TIOCMBIC)
-+ v24_sig &= ~mask;
-+ else
-+ v24_sig |= mask;
-+
-+ rfcomm_dlc_set_modem_status(dlc, v24_sig);
-+ return 0;
-+}
-+
-+static int rfcomm_tty_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+ uint status;
-+ int err;
-+
-+ BT_DBG("tty %p cmd 0x%02x", tty, cmd);
-+
-+ switch (cmd) {
-+ case TCGETS:
-+ BT_DBG("TCGETS is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TCSETS:
-+ BT_DBG("TCSETS is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCMGET:
-+ BT_DBG("TIOCMGET");
-+
-+ return put_user(dev->modem_status, (unsigned int *)arg);
-+
-+ case TIOCMSET: /* Turns on and off the lines as specified by the mask */
-+ case TIOCMBIS: /* Turns on the lines as specified by the mask */
-+ case TIOCMBIC: /* Turns off the lines as specified by the mask */
-+ if ((err = get_user(status, (unsigned int *)arg)))
-+ return err;
-+ return rfcomm_tty_set_modem_status(cmd, dlc, status);
-+
-+ case TIOCMIWAIT:
-+ BT_DBG("TIOCMIWAIT");
-+ break;
-+
-+ case TIOCGICOUNT:
-+ BT_DBG("TIOCGICOUNT");
-+ break;
-+
-+ case TIOCGSERIAL:
-+ BT_ERR("TIOCGSERIAL is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCSSERIAL:
-+ BT_ERR("TIOCSSERIAL is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCSERGSTRUCT:
-+ BT_ERR("TIOCSERGSTRUCT is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCSERGETLSR:
-+ BT_ERR("TIOCSERGETLSR is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCSERCONFIG:
-+ BT_ERR("TIOCSERCONFIG is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ default:
-+ return -ENOIOCTLCMD; /* ioctls which we must ignore */
-+
-+ }
-+
-+ return -ENOIOCTLCMD;
-+}
-+
-+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-+
-+static void rfcomm_tty_set_termios(struct tty_struct *tty, struct termios *old)
-+{
-+ BT_DBG("tty %p", tty);
-+
-+ if ((tty->termios->c_cflag == old->c_cflag) &&
-+ (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old->c_iflag)))
-+ return;
-+
-+ /* handle turning off CRTSCTS */
-+ if ((old->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) {
-+ BT_DBG("turning off CRTSCTS");
-+ }
-+}
-+
-+static void rfcomm_tty_throttle(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ rfcomm_dlc_throttle(dev->dlc);
-+}
-+
-+static void rfcomm_tty_unthrottle(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ rfcomm_dlc_unthrottle(dev->dlc);
-+}
-+
-+static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ if (skb_queue_len(&dlc->tx_queue))
-+ return dlc->mtu;
-+
-+ return 0;
-+}
-+
-+static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ skb_queue_purge(&dev->dlc->tx_queue);
-+
-+ if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
-+ tty->ldisc.write_wakeup(tty);
-+}
-+
-+static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
-+{
-+ BT_DBG("tty %p ch %c", tty, ch);
-+}
-+
-+static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
-+{
-+ BT_DBG("tty %p timeout %d", tty, timeout);
-+}
-+
-+static void rfcomm_tty_hangup(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ rfcomm_tty_flush_buffer(tty);
-+
-+ if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
-+ rfcomm_dev_del(dev);
-+}
-+
-+static int rfcomm_tty_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *unused)
-+{
-+ return 0;
-+}
-+
-+/* ---- TTY structure ---- */
-+static int rfcomm_tty_refcount; /* If we manage several devices */
-+
-+static struct tty_struct *rfcomm_tty_table[RFCOMM_TTY_PORTS];
-+static struct termios *rfcomm_tty_termios[RFCOMM_TTY_PORTS];
-+static struct termios *rfcomm_tty_termios_locked[RFCOMM_TTY_PORTS];
-+
-+static struct tty_driver rfcomm_tty_driver = {
-+ magic: TTY_DRIVER_MAGIC,
-+ driver_name: "rfcomm",
-+#ifdef CONFIG_DEVFS_FS
-+ name: "bluetooth/rfcomm/%d",
-+#else
-+ name: "rfcomm",
-+#endif
-+ major: RFCOMM_TTY_MAJOR,
-+ minor_start: RFCOMM_TTY_MINOR,
-+ num: RFCOMM_TTY_PORTS,
-+ type: TTY_DRIVER_TYPE_SERIAL,
-+ subtype: SERIAL_TYPE_NORMAL,
-+ flags: TTY_DRIVER_REAL_RAW,
-+
-+ refcount: &rfcomm_tty_refcount,
-+ table: rfcomm_tty_table,
-+ termios: rfcomm_tty_termios,
-+ termios_locked: rfcomm_tty_termios_locked,
-+
-+ open: rfcomm_tty_open,
-+ close: rfcomm_tty_close,
-+ put_char: rfcomm_tty_put_char,
-+ write: rfcomm_tty_write,
-+ write_room: rfcomm_tty_write_room,
-+ chars_in_buffer: rfcomm_tty_chars_in_buffer,
-+ flush_buffer: rfcomm_tty_flush_buffer,
-+ ioctl: rfcomm_tty_ioctl,
-+ throttle: rfcomm_tty_throttle,
-+ unthrottle: rfcomm_tty_unthrottle,
-+ set_termios: rfcomm_tty_set_termios,
-+ send_xchar: rfcomm_tty_send_xchar,
-+ stop: NULL,
-+ start: NULL,
-+ hangup: rfcomm_tty_hangup,
-+ wait_until_sent: rfcomm_tty_wait_until_sent,
-+ read_proc: rfcomm_tty_read_proc,
-+};
-+
-+int rfcomm_init_ttys(void)
-+{
-+ int i;
-+
-+ /* Initalize our global data */
-+ for (i = 0; i < RFCOMM_TTY_PORTS; i++)
-+ rfcomm_tty_table[i] = NULL;
-+
-+ /* Register the TTY driver */
-+ rfcomm_tty_driver.init_termios = tty_std_termios;
-+ rfcomm_tty_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-+ rfcomm_tty_driver.flags = TTY_DRIVER_REAL_RAW;
-+
-+ if (tty_register_driver(&rfcomm_tty_driver)) {
-+ BT_ERR("Can't register RFCOMM TTY driver");
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+void rfcomm_cleanup_ttys(void)
-+{
-+ tty_unregister_driver(&rfcomm_tty_driver);
-+ return;
-+}
-diff -urN linux-2.4.18/net/bluetooth/sco.c linux-2.4.18-mh15/net/bluetooth/sco.c
---- linux-2.4.18/net/bluetooth/sco.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18-mh15/net/bluetooth/sco.c 2004-08-01 16:26:23.000000000 +0200
-@@ -0,0 +1,1019 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * BlueZ SCO sockets.
-+ *
-+ * $Id$
-+ */
-+#define VERSION "0.3"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/socket.h>
-+#include <linux/skbuff.h>
-+#include <linux/proc_fs.h>
-+#include <linux/list.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include <net/bluetooth/sco.h>
-+
-+#ifndef SCO_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+static struct proto_ops sco_sock_ops;
-+
-+static struct bluez_sock_list sco_sk_list = {
-+ lock: RW_LOCK_UNLOCKED
-+};
-+
-+static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
-+static void sco_chan_del(struct sock *sk, int err);
-+static inline struct sock * sco_chan_get(struct sco_conn *conn);
-+
-+static int sco_conn_del(struct hci_conn *conn, int err);
-+
-+static void sco_sock_close(struct sock *sk);
-+static void sco_sock_kill(struct sock *sk);
-+
-+/* ----- SCO timers ------ */
-+static void sco_sock_timeout(unsigned long arg)
-+{
-+ struct sock *sk = (struct sock *) arg;
-+
-+ BT_DBG("sock %p state %d", sk, sk->state);
-+
-+ bh_lock_sock(sk);
-+ sk->err = ETIMEDOUT;
-+ sk->state_change(sk);
-+ bh_unlock_sock(sk);
-+
-+ sco_sock_kill(sk);
-+ sock_put(sk);
-+}
-+
-+static void sco_sock_set_timer(struct sock *sk, long timeout)
-+{
-+ BT_DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
-+
-+ if (!mod_timer(&sk->timer, jiffies + timeout))
-+ sock_hold(sk);
-+}
-+
-+static void sco_sock_clear_timer(struct sock *sk)
-+{
-+ BT_DBG("sock %p state %d", sk, sk->state);
-+
-+ if (timer_pending(&sk->timer) && del_timer(&sk->timer))
-+ __sock_put(sk);
-+}
-+
-+static void sco_sock_init_timer(struct sock *sk)
-+{
-+ init_timer(&sk->timer);
-+ sk->timer.function = sco_sock_timeout;
-+ sk->timer.data = (unsigned long)sk;
-+}
-+
-+/* -------- SCO connections --------- */
-+static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status)
-+{
-+ struct hci_dev *hdev = hcon->hdev;
-+ struct sco_conn *conn;
-+
-+ if ((conn = hcon->sco_data))
-+ return conn;
-+
-+ if (status)
-+ return conn;
-+
-+ if (!(conn = kmalloc(sizeof(struct sco_conn), GFP_ATOMIC)))
-+ return NULL;
-+ memset(conn, 0, sizeof(struct sco_conn));
-+
-+ spin_lock_init(&conn->lock);
-+
-+ hcon->sco_data = conn;
-+ conn->hcon = hcon;
-+
-+ conn->src = &hdev->bdaddr;
-+ conn->dst = &hcon->dst;
-+
-+ if (hdev->sco_mtu > 0)
-+ conn->mtu = hdev->sco_mtu;
-+ else
-+ conn->mtu = 60;
-+
-+ BT_DBG("hcon %p conn %p", hcon, conn);
-+
-+ MOD_INC_USE_COUNT;
-+ return conn;
-+}
-+
-+static int sco_conn_del(struct hci_conn *hcon, int err)
-+{
-+ struct sco_conn *conn;
-+ struct sock *sk;
-+
-+ if (!(conn = hcon->sco_data))
-+ return 0;
-+
-+ BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
-+
-+ /* Kill socket */
-+ if ((sk = sco_chan_get(conn))) {
-+ bh_lock_sock(sk);
-+ sco_sock_clear_timer(sk);
-+ sco_chan_del(sk, err);
-+ bh_unlock_sock(sk);
-+ sco_sock_kill(sk);
-+ }
-+
-+ hcon->sco_data = NULL;
-+ kfree(conn);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+int sco_connect(struct sock *sk)
-+{
-+ bdaddr_t *src = &bluez_pi(sk)->src;
-+ bdaddr_t *dst = &bluez_pi(sk)->dst;
-+ struct sco_conn *conn;
-+ struct hci_conn *hcon;
-+ struct hci_dev *hdev;
-+ int err = 0;
-+
-+ BT_DBG("%s -> %s", batostr(src), batostr(dst));
-+
-+ if (!(hdev = hci_get_route(dst, src)))
-+ return -EHOSTUNREACH;
-+
-+ hci_dev_lock_bh(hdev);
-+
-+ err = -ENOMEM;
-+
-+ hcon = hci_connect(hdev, SCO_LINK, dst);
-+ if (!hcon)
-+ goto done;
-+
-+ conn = sco_conn_add(hcon, 0);
-+ if (!conn) {
-+ hci_conn_put(hcon);
-+ goto done;
-+ }
-+
-+ /* Update source addr of the socket */
-+ bacpy(src, conn->src);
-+
-+ err = sco_chan_add(conn, sk, NULL);
-+ if (err)
-+ goto done;
-+
-+ if (hcon->state == BT_CONNECTED) {
-+ sco_sock_clear_timer(sk);
-+ sk->state = BT_CONNECTED;
-+ } else {
-+ sk->state = BT_CONNECT;
-+ sco_sock_set_timer(sk, sk->sndtimeo);
-+ }
-+done:
-+ hci_dev_unlock_bh(hdev);
-+ hci_dev_put(hdev);
-+ return err;
-+}
-+
-+static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
-+{
-+ struct sco_conn *conn = sco_pi(sk)->conn;
-+ struct sk_buff *skb;
-+ int err, count;
-+
-+ /* Check outgoing MTU */
-+ if (len > conn->mtu)
-+ return -EINVAL;
-+
-+ BT_DBG("sk %p len %d", sk, len);
-+
-+ count = MIN(conn->mtu, len);
-+ if (!(skb = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err)))
-+ return err;
-+
-+ if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
-+ err = -EFAULT;
-+ goto fail;
-+ }
-+
-+ if ((err = hci_send_sco(conn->hcon, skb)) < 0)
-+ goto fail;
-+
-+ return count;
-+
-+fail:
-+ kfree_skb(skb);
-+ return err;
-+}
-+
-+static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
-+{
-+ struct sock *sk = sco_chan_get(conn);
-+
-+ if (!sk)
-+ goto drop;
-+
-+ BT_DBG("sk %p len %d", sk, skb->len);
-+
-+ if (sk->state != BT_CONNECTED)
-+ goto drop;
-+
-+ if (!sock_queue_rcv_skb(sk, skb))
-+ return;
-+
-+drop:
-+ kfree_skb(skb);
-+ return;
-+}
-+
-+/* -------- Socket interface ---------- */
-+static struct sock *__sco_get_sock_by_addr(bdaddr_t *ba)
-+{
-+ struct sock *sk;
-+
-+ for (sk = sco_sk_list.head; sk; sk = sk->next) {
-+ if (!bacmp(&bluez_pi(sk)->src, ba))
-+ break;
-+ }
-+
-+ return sk;
-+}
-+
-+/* Find socket listening on source bdaddr.
-+ * Returns closest match.
-+ */
-+static struct sock *sco_get_sock_listen(bdaddr_t *src)
-+{
-+ struct sock *sk, *sk1 = NULL;
-+
-+ read_lock(&sco_sk_list.lock);
-+
-+ for (sk = sco_sk_list.head; sk; sk = sk->next) {
-+ if (sk->state != BT_LISTEN)
-+ continue;
-+
-+ /* Exact match. */
-+ if (!bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+
-+ /* Closest match */
-+ if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
-+ sk1 = sk;
-+ }
-+
-+ read_unlock(&sco_sk_list.lock);
-+
-+ return sk ? sk : sk1;
-+}
-+
-+static void sco_sock_destruct(struct sock *sk)
-+{
-+ BT_DBG("sk %p", sk);
-+
-+ skb_queue_purge(&sk->receive_queue);
-+ skb_queue_purge(&sk->write_queue);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void sco_sock_cleanup_listen(struct sock *parent)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("parent %p", parent);
-+
-+ /* Close not yet accepted channels */
-+ while ((sk = bluez_accept_dequeue(parent, NULL))) {
-+ sco_sock_close(sk);
-+ sco_sock_kill(sk);
-+ }
-+
-+ parent->state = BT_CLOSED;
-+ parent->zapped = 1;
-+}
-+
-+/* Kill socket (only if zapped and orphan)
-+ * Must be called on unlocked socket.
-+ */
-+static void sco_sock_kill(struct sock *sk)
-+{
-+ if (!sk->zapped || sk->socket)
-+ return;
-+
-+ BT_DBG("sk %p state %d", sk, sk->state);
-+
-+ /* Kill poor orphan */
-+ bluez_sock_unlink(&sco_sk_list, sk);
-+ sk->dead = 1;
-+ sock_put(sk);
-+}
-+
-+/* Close socket.
-+ * Must be called on unlocked socket.
-+ */
-+static void sco_sock_close(struct sock *sk)
-+{
-+ struct sco_conn *conn;
-+
-+ sco_sock_clear_timer(sk);
-+
-+ lock_sock(sk);
-+
-+ conn = sco_pi(sk)->conn;
-+
-+ BT_DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
-+
-+ switch (sk->state) {
-+ case BT_LISTEN:
-+ sco_sock_cleanup_listen(sk);
-+ break;
-+
-+ case BT_CONNECTED:
-+ case BT_CONFIG:
-+ case BT_CONNECT:
-+ case BT_DISCONN:
-+ sco_chan_del(sk, ECONNRESET);
-+ break;
-+
-+ default:
-+ sk->zapped = 1;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+}
-+
-+static void sco_sock_init(struct sock *sk, struct sock *parent)
-+{
-+ BT_DBG("sk %p", sk);
-+
-+ if (parent)
-+ sk->type = parent->type;
-+}
-+
-+static struct sock *sco_sock_alloc(struct socket *sock, int proto, int prio)
-+{
-+ struct sock *sk;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
-+ return NULL;
-+
-+ bluez_sock_init(sock, sk);
-+
-+ sk->zapped = 0;
-+
-+ sk->destruct = sco_sock_destruct;
-+ sk->sndtimeo = SCO_CONN_TIMEOUT;
-+
-+ sk->protocol = proto;
-+ sk->state = BT_OPEN;
-+
-+ sco_sock_init_timer(sk);
-+
-+ bluez_sock_link(&sco_sk_list, sk);
-+
-+ MOD_INC_USE_COUNT;
-+ return sk;
-+}
-+
-+static int sco_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ sock->state = SS_UNCONNECTED;
-+
-+ if (sock->type != SOCK_SEQPACKET)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &sco_sock_ops;
-+
-+ if (!(sk = sco_sock_alloc(sock, protocol, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ sco_sock_init(sk, NULL);
-+ return 0;
-+}
-+
-+static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
-+{
-+ struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
-+ struct sock *sk = sock->sk;
-+ bdaddr_t *src = &sa->sco_bdaddr;
-+ int err = 0;
-+
-+ BT_DBG("sk %p %s", sk, batostr(&sa->sco_bdaddr));
-+
-+ if (!addr || addr->sa_family != AF_BLUETOOTH)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_OPEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ write_lock_bh(&sco_sk_list.lock);
-+
-+ if (bacmp(src, BDADDR_ANY) && __sco_get_sock_by_addr(src)) {
-+ err = -EADDRINUSE;
-+ } else {
-+ /* Save source address */
-+ bacpy(&bluez_pi(sk)->src, &sa->sco_bdaddr);
-+ sk->state = BT_BOUND;
-+ }
-+
-+ write_unlock_bh(&sco_sk_list.lock);
-+
-+done:
-+ release_sock(sk);
-+
-+ return err;
-+}
-+
-+static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
-+{
-+ struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_sco))
-+ return -EINVAL;
-+
-+ if (sk->state != BT_OPEN && sk->state != BT_BOUND)
-+ return -EBADFD;
-+
-+ if (sk->type != SOCK_SEQPACKET)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ /* Set destination address and psm */
-+ bacpy(&bluez_pi(sk)->dst, &sa->sco_bdaddr);
-+
-+ if ((err = sco_connect(sk)))
-+ goto done;
-+
-+ err = bluez_sock_wait_state(sk, BT_CONNECTED,
-+ sock_sndtimeo(sk, flags & O_NONBLOCK));
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int sco_sock_listen(struct socket *sock, int backlog)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p backlog %d", sk, backlog);
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ sk->max_ack_backlog = backlog;
-+ sk->ack_backlog = 0;
-+ sk->state = BT_LISTEN;
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct sock *sk = sock->sk, *ch;
-+ long timeo;
-+ int err = 0;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
-+
-+ BT_DBG("sk %p timeo %ld", sk, timeo);
-+
-+ /* Wait for an incoming connection. (wake-one). */
-+ add_wait_queue_exclusive(sk->sleep, &wait);
-+ while (!(ch = bluez_accept_dequeue(sk, newsock))) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ break;
-+ }
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ break;
-+ }
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ if (err)
-+ goto done;
-+
-+ newsock->state = SS_CONNECTED;
-+
-+ BT_DBG("new socket %p", ch);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
-+{
-+ struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ addr->sa_family = AF_BLUETOOTH;
-+ *len = sizeof(struct sockaddr_sco);
-+
-+ if (peer)
-+ bacpy(&sa->sco_bdaddr, &bluez_pi(sk)->dst);
-+ else
-+ bacpy(&sa->sco_bdaddr, &bluez_pi(sk)->src);
-+
-+ return 0;
-+}
-+
-+static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (sk->err)
-+ return sock_error(sk);
-+
-+ if (msg->msg_flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state == BT_CONNECTED)
-+ err = sco_send_frame(sk, msg, len);
-+ else
-+ err = -ENOTCONN;
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int sco_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int sco_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ struct sco_options opts;
-+ struct sco_conninfo cinfo;
-+ int len, err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (get_user(len, optlen))
-+ return -EFAULT;
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ case SCO_OPTIONS:
-+ if (sk->state != BT_CONNECTED) {
-+ err = -ENOTCONN;
-+ break;
-+ }
-+
-+ opts.mtu = sco_pi(sk)->conn->mtu;
-+
-+ BT_DBG("mtu %d", opts.mtu);
-+
-+ len = MIN(len, sizeof(opts));
-+ if (copy_to_user(optval, (char *)&opts, len))
-+ err = -EFAULT;
-+
-+ break;
-+
-+ case SCO_CONNINFO:
-+ if (sk->state != BT_CONNECTED) {
-+ err = -ENOTCONN;
-+ break;
-+ }
-+
-+ cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
-+
-+ len = MIN(len, sizeof(cinfo));
-+ if (copy_to_user(optval, (char *)&cinfo, len))
-+ err = -EFAULT;
-+
-+ break;
-+
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int sco_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ sco_sock_close(sk);
-+ if (sk->linger) {
-+ lock_sock(sk);
-+ err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
-+ release_sock(sk);
-+ }
-+
-+ sock_orphan(sk);
-+ sco_sock_kill(sk);
-+ return err;
-+}
-+
-+static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
-+{
-+ BT_DBG("conn %p", conn);
-+
-+ sco_pi(sk)->conn = conn;
-+ conn->sk = sk;
-+
-+ if (parent)
-+ bluez_accept_enqueue(parent, sk);
-+}
-+
-+static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
-+{
-+ int err = 0;
-+
-+ sco_conn_lock(conn);
-+ if (conn->sk) {
-+ err = -EBUSY;
-+ } else {
-+ __sco_chan_add(conn, sk, parent);
-+ }
-+ sco_conn_unlock(conn);
-+ return err;
-+}
-+
-+static inline struct sock * sco_chan_get(struct sco_conn *conn)
-+{
-+ struct sock *sk = NULL;
-+ sco_conn_lock(conn);
-+ sk = conn->sk;
-+ sco_conn_unlock(conn);
-+ return sk;
-+}
-+
-+/* Delete channel.
-+ * Must be called on the locked socket. */
-+static void sco_chan_del(struct sock *sk, int err)
-+{
-+ struct sco_conn *conn;
-+
-+ conn = sco_pi(sk)->conn;
-+
-+ BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
-+
-+ if (conn) {
-+ sco_conn_lock(conn);
-+ conn->sk = NULL;
-+ sco_pi(sk)->conn = NULL;
-+ sco_conn_unlock(conn);
-+ hci_conn_put(conn->hcon);
-+ }
-+
-+ sk->state = BT_CLOSED;
-+ sk->err = err;
-+ sk->state_change(sk);
-+
-+ sk->zapped = 1;
-+}
-+
-+static void sco_conn_ready(struct sco_conn *conn)
-+{
-+ struct sock *parent, *sk;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ sco_conn_lock(conn);
-+
-+ if ((sk = conn->sk)) {
-+ sco_sock_clear_timer(sk);
-+ bh_lock_sock(sk);
-+ sk->state = BT_CONNECTED;
-+ sk->state_change(sk);
-+ bh_unlock_sock(sk);
-+ } else {
-+ parent = sco_get_sock_listen(conn->src);
-+ if (!parent)
-+ goto done;
-+
-+ bh_lock_sock(parent);
-+
-+ sk = sco_sock_alloc(NULL, BTPROTO_SCO, GFP_ATOMIC);
-+ if (!sk) {
-+ bh_unlock_sock(parent);
-+ goto done;
-+ }
-+
-+ sco_sock_init(sk, parent);
-+
-+ bacpy(&bluez_pi(sk)->src, conn->src);
-+ bacpy(&bluez_pi(sk)->dst, conn->dst);
-+
-+ hci_conn_hold(conn->hcon);
-+ __sco_chan_add(conn, sk, parent);
-+
-+ sk->state = BT_CONNECTED;
-+
-+ /* Wake up parent */
-+ parent->data_ready(parent, 1);
-+
-+ bh_unlock_sock(parent);
-+ }
-+
-+done:
-+ sco_conn_unlock(conn);
-+}
-+
-+/* ----- SCO interface with lower layer (HCI) ----- */
-+int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
-+{
-+ BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
-+
-+ /* Always accept connection */
-+ return HCI_LM_ACCEPT;
-+}
-+
-+int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
-+{
-+ BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
-+
-+ if (hcon->type != SCO_LINK)
-+ return 0;
-+
-+ if (!status) {
-+ struct sco_conn *conn;
-+
-+ conn = sco_conn_add(hcon, status);
-+ if (conn)
-+ sco_conn_ready(conn);
-+ } else
-+ sco_conn_del(hcon, bterr(status));
-+
-+ return 0;
-+}
-+
-+int sco_disconn_ind(struct hci_conn *hcon, __u8 reason)
-+{
-+ BT_DBG("hcon %p reason %d", hcon, reason);
-+
-+ if (hcon->type != SCO_LINK)
-+ return 0;
-+
-+ sco_conn_del(hcon, bterr(reason));
-+ return 0;
-+}
-+
-+int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
-+{
-+ struct sco_conn *conn = hcon->sco_data;
-+
-+ if (!conn)
-+ goto drop;
-+
-+ BT_DBG("conn %p len %d", conn, skb->len);
-+
-+ if (skb->len) {
-+ sco_recv_frame(conn, skb);
-+ return 0;
-+ }
-+
-+drop:
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+/* ----- Proc fs support ------ */
-+static int sco_sock_dump(char *buf, struct bluez_sock_list *list)
-+{
-+ struct sco_pinfo *pi;
-+ struct sock *sk;
-+ char *ptr = buf;
-+
-+ write_lock_bh(&list->lock);
-+
-+ for (sk = list->head; sk; sk = sk->next) {
-+ pi = sco_pi(sk);
-+ ptr += sprintf(ptr, "%s %s %d\n",
-+ batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
-+ sk->state);
-+ }
-+
-+ write_unlock_bh(&list->lock);
-+
-+ ptr += sprintf(ptr, "\n");
-+
-+ return ptr - buf;
-+}
-+
-+static int sco_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
-+{
-+ char *ptr = buf;
-+ int len;
-+
-+ BT_DBG("count %d, offset %ld", count, offset);
-+
-+ ptr += sco_sock_dump(ptr, &sco_sk_list);
-+ len = ptr - buf;
-+
-+ if (len <= count + offset)
-+ *eof = 1;
-+
-+ *start = buf + offset;
-+ len -= offset;
-+
-+ if (len > count)
-+ len = count;
-+ if (len < 0)
-+ len = 0;
-+
-+ return len;
-+}
-+
-+static struct proto_ops sco_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: sco_sock_release,
-+ bind: sco_sock_bind,
-+ connect: sco_sock_connect,
-+ listen: sco_sock_listen,
-+ accept: sco_sock_accept,
-+ getname: sco_sock_getname,
-+ sendmsg: sco_sock_sendmsg,
-+ recvmsg: bluez_sock_recvmsg,
-+ poll: bluez_sock_poll,
-+ socketpair: sock_no_socketpair,
-+ ioctl: sock_no_ioctl,
-+ shutdown: sock_no_shutdown,
-+ setsockopt: sco_sock_setsockopt,
-+ getsockopt: sco_sock_getsockopt,
-+ mmap: sock_no_mmap
-+};
-+
-+static struct net_proto_family sco_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: sco_sock_create
-+};
-+
-+static struct hci_proto sco_hci_proto = {
-+ name: "SCO",
-+ id: HCI_PROTO_SCO,
-+ connect_ind: sco_connect_ind,
-+ connect_cfm: sco_connect_cfm,
-+ disconn_ind: sco_disconn_ind,
-+ recv_scodata: sco_recv_scodata,
-+};
-+
-+int __init sco_init(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_SCO, &sco_sock_family_ops))) {
-+ BT_ERR("Can't register SCO socket layer");
-+ return err;
-+ }
-+
-+ if ((err = hci_register_proto(&sco_hci_proto))) {
-+ BT_ERR("Can't register SCO protocol");
-+ return err;
-+ }
-+
-+ create_proc_read_entry("bluetooth/sco", 0, 0, sco_read_proc, NULL);
-+
-+ BT_INFO("BlueZ SCO ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ return 0;
-+}
-+
-+void sco_cleanup(void)
-+{
-+ int err;
-+
-+ remove_proc_entry("bluetooth/sco", NULL);
-+
-+ /* Unregister socket, protocol and notifier */
-+ if ((err = bluez_sock_unregister(BTPROTO_SCO)))
-+ BT_ERR("Can't unregister SCO socket layer %d", err);
-+
-+ if ((err = hci_unregister_proto(&sco_hci_proto)))
-+ BT_ERR("Can't unregister SCO protocol %d", err);
-+}
-+
-+module_init(sco_init);
-+module_exit(sco_cleanup);
-+
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
-+MODULE_DESCRIPTION("BlueZ SCO ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/syms.c linux-2.4.18-mh15/net/bluetooth/syms.c
---- linux-2.4.18/net/bluetooth/syms.c 2001-09-07 18:28:38.000000000 +0200
-+++ linux-2.4.18-mh15/net/bluetooth/syms.c 2004-08-01 16:26:23.000000000 +0200
-@@ -25,7 +25,7 @@
- /*
- * BlueZ symbols.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
-@@ -39,25 +39,28 @@
- #include <linux/socket.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
-
- /* HCI Core */
- EXPORT_SYMBOL(hci_register_dev);
- EXPORT_SYMBOL(hci_unregister_dev);
-+EXPORT_SYMBOL(hci_suspend_dev);
-+EXPORT_SYMBOL(hci_resume_dev);
-+
- EXPORT_SYMBOL(hci_register_proto);
- EXPORT_SYMBOL(hci_unregister_proto);
--EXPORT_SYMBOL(hci_register_notifier);
--EXPORT_SYMBOL(hci_unregister_notifier);
-
-+EXPORT_SYMBOL(hci_get_route);
- EXPORT_SYMBOL(hci_connect);
--EXPORT_SYMBOL(hci_disconnect);
- EXPORT_SYMBOL(hci_dev_get);
-+EXPORT_SYMBOL(hci_conn_auth);
-+EXPORT_SYMBOL(hci_conn_encrypt);
-
- EXPORT_SYMBOL(hci_recv_frame);
- EXPORT_SYMBOL(hci_send_acl);
- EXPORT_SYMBOL(hci_send_sco);
--EXPORT_SYMBOL(hci_send_raw);
-+EXPORT_SYMBOL(hci_send_cmd);
-+EXPORT_SYMBOL(hci_si_event);
-
- /* BlueZ lib */
- EXPORT_SYMBOL(bluez_dump);
-@@ -68,5 +71,11 @@
- /* BlueZ sockets */
- EXPORT_SYMBOL(bluez_sock_register);
- EXPORT_SYMBOL(bluez_sock_unregister);
-+EXPORT_SYMBOL(bluez_sock_init);
- EXPORT_SYMBOL(bluez_sock_link);
- EXPORT_SYMBOL(bluez_sock_unlink);
-+EXPORT_SYMBOL(bluez_sock_recvmsg);
-+EXPORT_SYMBOL(bluez_sock_poll);
-+EXPORT_SYMBOL(bluez_accept_enqueue);
-+EXPORT_SYMBOL(bluez_accept_dequeue);
-+EXPORT_SYMBOL(bluez_sock_wait_state);
-diff -urN linux-2.4.18/net/netsyms.c linux-2.4.18-mh15/net/netsyms.c
---- linux-2.4.18/net/netsyms.c 2002-02-25 20:38:14.000000000 +0100
-+++ linux-2.4.18-mh15/net/netsyms.c 2004-08-01 16:26:23.000000000 +0200
-@@ -159,6 +159,7 @@
- EXPORT_SYMBOL(put_cmsg);
- EXPORT_SYMBOL(sock_kmalloc);
- EXPORT_SYMBOL(sock_kfree_s);
-+EXPORT_SYMBOL(sockfd_lookup);
-
- #ifdef CONFIG_FILTER
- EXPORT_SYMBOL(sk_run_filter);
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/bluetooth-patch-2.4.18-mh9.diff b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/bluetooth-patch-2.4.18-mh9.diff
deleted file mode 100644
index b31c57992f..0000000000
--- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/bluetooth-patch-2.4.18-mh9.diff
+++ /dev/null
@@ -1,30831 +0,0 @@
-diff -urN linux-2.4.18/CREDITS linux-2.4.18-mh9/CREDITS
---- linux-2.4.18/CREDITS Mon Feb 25 20:37:50 2002
-+++ linux-2.4.18-mh9/CREDITS Mon Aug 25 18:38:09 2003
-@@ -1317,6 +1317,14 @@
- S: Provo, Utah 84606-5607
- S: USA
-
-+N: Marcel Holtmann
-+E: marcel@holtmann.org
-+W: http://www.holtmann.org
-+D: Author and maintainer of the various Bluetooth HCI drivers
-+D: Author and maintainer of the CAPI message transport protocol driver
-+D: Various other Bluetooth related patches, cleanups and fixes
-+S: Germany
-+
- N: Rob W. W. Hooft
- E: hooft@EMBL-Heidelberg.DE
- D: Shared libs for graphics-tools and for the f2c compiler
-diff -urN linux-2.4.18/Documentation/Configure.help linux-2.4.18-mh9/Documentation/Configure.help
---- linux-2.4.18/Documentation/Configure.help Mon Feb 25 20:37:51 2002
-+++ linux-2.4.18-mh9/Documentation/Configure.help Mon Aug 25 18:38:10 2003
-@@ -2824,14 +2824,6 @@
-
- If unsure, say N.
-
--HCI EMU (virtual device) driver
--CONFIG_BLUEZ_HCIEMU
-- Bluetooth Virtual HCI device driver.
-- This driver is required if you want to use HCI Emulation software.
--
-- Say Y here to compile support for Virtual HCI devices into the
-- kernel or say M to compile it as module (hci_usb.o).
--
- # Choice: alphatype
- Alpha system type
- CONFIG_ALPHA_GENERIC
-@@ -11037,6 +11029,12 @@
-
- If unsure, say N.
-
-+Hotplug firmware loading support (EXPERIMENTAL)
-+CONFIG_FW_LOADER
-+ This option is provided for the case where no in-kernel-tree modules require
-+ hotplug firmware loading support, but a module built outside the kernel tree
-+ does.
-+
- Use PCI shared memory for NIC registers
- CONFIG_TULIP_MMIO
- Use PCI shared memory for the NIC registers, rather than going through
-@@ -19870,11 +19868,15 @@
- Bluetooth can be found at <http://www.bluetooth.com/>.
-
- Linux Bluetooth subsystem consist of several layers:
-- HCI Core (device and connection manager, scheduler)
-+ BlueZ Core (HCI device and connection manager, scheduler)
- HCI Device drivers (interface to the hardware)
- L2CAP Module (L2CAP protocol)
-+ SCO Module (SCO links)
-+ RFCOMM Module (RFCOMM protocol)
-+ BNEP Module (BNEP protocol)
-+ CMTP Module (CMTP protocol)
-
-- Say Y here to enable Linux Bluetooth support and to build HCI Core
-+ Say Y here to enable Linux Bluetooth support and to build BlueZ Core
- layer.
-
- To use Linux Bluetooth subsystem, you will need several user-space
-@@ -19882,7 +19884,7 @@
- Bluetooth kernel modules are provided in the BlueZ package.
- For more information, see <http://bluez.sourceforge.net/>.
-
-- If you want to compile HCI Core as module (hci.o) say M here.
-+ If you want to compile BlueZ Core as module (bluez.o) say M here.
-
- L2CAP protocol support
- CONFIG_BLUEZ_L2CAP
-@@ -19893,15 +19895,91 @@
- Say Y here to compile L2CAP support into the kernel or say M to
- compile it as module (l2cap.o).
-
-+SCO links support
-+CONFIG_BLUEZ_SCO
-+ SCO link provides voice transport over Bluetooth. SCO support is
-+ required for voice applications like Headset and Audio.
-+
-+ Say Y here to compile SCO support into the kernel or say M to
-+ compile it as module (sco.o).
-+
-+RFCOMM protocol support
-+CONFIG_BLUEZ_RFCOMM
-+ RFCOMM provides connection oriented stream transport. RFCOMM
-+ support is required for Dialup Networking, OBEX and other Bluetooth
-+ applications.
-+
-+ Say Y here to compile RFCOMM support into the kernel or say M to
-+ compile it as module (rfcomm.o).
-+
-+RFCOMM TTY emulation support
-+CONFIG_BLUEZ_RFCOMM_TTY
-+ This option enables TTY emulation support for RFCOMM channels.
-+
-+BNEP protocol support
-+CONFIG_BLUEZ_BNEP
-+ BNEP (Bluetooth Network Encapsulation Protocol) is Ethernet
-+ emulation layer on top of Bluetooth. BNEP is required for Bluetooth
-+ PAN (Personal Area Network).
-+
-+ To use BNEP, you will need user-space utilities provided in the
-+ BlueZ-PAN package.
-+ For more information, see <http://bluez.sourceforge.net>.
-+
-+ Say Y here to compile BNEP support into the kernel or say M to
-+ compile it as module (bnep.o).
-+
-+CMTP protocol support
-+CONFIG_BLUEZ_CMTP
-+ CMTP (CAPI Message Transport Protocol) is a transport layer
-+ for CAPI messages. CMTP is required for the Bluetooth Common
-+ ISDN Access Profile.
-+
-+ Say Y here to compile CMTP support into the kernel or say M to
-+ compile it as module (cmtp.o).
-+
-+BNEP multicast filter support
-+CONFIG_BLUEZ_BNEP_MC_FILTER
-+ This option enables the multicast filter support for BNEP.
-+
-+BNEP protocol filter support
-+CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+ This option enables the protocol filter support for BNEP.
-+
- HCI UART driver
- CONFIG_BLUEZ_HCIUART
- Bluetooth HCI UART driver.
- This driver is required if you want to use Bluetooth devices with
-- serial port interface.
-+ serial port interface. You will also need this driver if you have
-+ UART based Bluetooth PCMCIA and CF devices like Xircom Credit Card
-+ adapter and BrainBoxes Bluetooth PC Card.
-
- Say Y here to compile support for Bluetooth UART devices into the
- kernel or say M to compile it as module (hci_uart.o).
-
-+HCI UART (H4) protocol support
-+CONFIG_BLUEZ_HCIUART_H4
-+ UART (H4) is serial protocol for communication between Bluetooth
-+ device and host. This protocol is required for most Bluetooth devices
-+ with UART interface, including PCMCIA and CF cards.
-+
-+ Say Y here to compile support for HCI UART (H4) protocol.
-+
-+HCI BCSP protocol support
-+CONFIG_BLUEZ_HCIUART_BCSP
-+ BCSP (BlueCore Serial Protocol) is serial protocol for communication
-+ between Bluetooth device and host. This protocol is required for non
-+ USB Bluetooth devices based on CSR BlueCore chip, including PCMCIA and
-+ CF cards.
-+
-+ Say Y here to compile support for HCI BCSP protocol.
-+
-+HCI BCSP transmit CRC with every BCSP packet
-+CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ If you say Y here, a 16-bit CRC checksum will be transmitted along with
-+ every BCSP (BlueCore Serial Protocol) packet sent to the Bluetooth chip.
-+ This increases reliability, but slightly reduces efficiency.
-+
- HCI USB driver
- CONFIG_BLUEZ_HCIUSB
- Bluetooth HCI USB driver.
-@@ -19911,13 +19989,90 @@
- Say Y here to compile support for Bluetooth USB devices into the
- kernel or say M to compile it as module (hci_usb.o).
-
--HCI VHCI virtual HCI device driver
-+HCI USB SCO (voice) support
-+CONFIG_BLUEZ_USB_SCO
-+ This option enables the SCO support in the HCI USB driver. You need this
-+ to transmit voice data with your Bluetooth USB device. And your device
-+ must also support sending SCO data over the HCI layer, because some of
-+ them sends the SCO data to an internal PCM adapter.
-+
-+ Say Y here to compile support for HCI SCO data.
-+
-+HCI USB zero packet support
-+CONFIG_BLUEZ_USB_ZERO_PACKET
-+ This option is provided only as a work around for buggy Bluetooth USB
-+ devices. Do NOT enable it unless you know for sure that your device
-+ requires zero packets.
-+
-+ Most people should say N here.
-+
-+HCI VHCI Virtual HCI device driver
- CONFIG_BLUEZ_HCIVHCI
- Bluetooth Virtual HCI device driver.
- This driver is required if you want to use HCI Emulation software.
-
- Say Y here to compile support for virtual HCI devices into the
- kernel or say M to compile it as module (hci_vhci.o).
-+
-+HCI BFUSB device driver
-+CONFIG_BLUEZ_HCIBFUSB
-+ Bluetooth HCI BlueFRITZ! USB driver.
-+ This driver provides support for Bluetooth USB devices with AVM
-+ interface:
-+ AVM BlueFRITZ! USB
-+
-+ Say Y here to compile support for HCI BFUSB devices into the
-+ kernel or say M to compile it as module (bfusb.o).
-+
-+HCI DTL1 (PC Card) device driver
-+CONFIG_BLUEZ_HCIDTL1
-+ Bluetooth HCI DTL1 (PC Card) driver.
-+ This driver provides support for Bluetooth PCMCIA devices with
-+ Nokia DTL1 interface:
-+ Nokia Bluetooth Card
-+ Socket Bluetooth CF Card
-+
-+ Say Y here to compile support for HCI DTL1 devices into the
-+ kernel or say M to compile it as module (dtl1_cs.o).
-+
-+HCI BT3C (PC Card) device driver
-+CONFIG_BLUEZ_HCIBT3C
-+ Bluetooth HCI BT3C (PC Card) driver.
-+ This driver provides support for Bluetooth PCMCIA devices with
-+ 3Com BT3C interface:
-+ 3Com Bluetooth Card (3CRWB6096)
-+ HP Bluetooth Card
-+
-+ The HCI BT3C driver uses external firmware loader program provided in
-+ the BlueFW package. For more information, see <http://bluez.sf.net>.
-+
-+ Say Y here to compile support for HCI BT3C devices into the
-+ kernel or say M to compile it as module (bt3c_cs.o).
-+
-+HCI BlueCard (PC Card) device driver
-+CONFIG_BLUEZ_HCIBLUECARD
-+ Bluetooth HCI BlueCard (PC Card) driver.
-+ This driver provides support for Bluetooth PCMCIA devices with
-+ Anycom BlueCard interface:
-+ Anycom Bluetooth PC Card
-+ Anycom Bluetooth CF Card
-+
-+ Say Y here to compile support for HCI BlueCard devices into the
-+ kernel or say M to compile it as module (bluecard_cs.o).
-+
-+HCI UART (PC Card) device driver
-+CONFIG_BLUEZ_HCIBTUART
-+ Bluetooth HCI UART (PC Card) driver.
-+ This driver provides support for Bluetooth PCMCIA devices with
-+ an UART interface:
-+ Xircom CreditCard Bluetooth Adapter
-+ Xircom RealPort2 Bluetooth Adapter
-+ Sphinx PICO Card
-+ H-Soft blue+Card
-+ Cyber-blue Compact Flash Card
-+
-+ Say Y here to compile support for HCI UART devices into the
-+ kernel or say M to compile it as module (btuart_cs.o).
-
- # The following options are for Linux when running on the Hitachi
- # SuperH family of RISC microprocessors.
-diff -urN linux-2.4.18/Documentation/firmware_class/README linux-2.4.18-mh9/Documentation/firmware_class/README
---- linux-2.4.18/Documentation/firmware_class/README Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/Documentation/firmware_class/README Mon Aug 25 18:38:10 2003
-@@ -0,0 +1,58 @@
-+
-+ request_firmware() hotplug interface:
-+ ------------------------------------
-+ Copyright (C) 2003 Manuel Estrada Sainz <ranty@debian.org>
-+
-+ Why:
-+ ---
-+
-+ Today, the most extended way to use firmware in the Linux kernel is linking
-+ it statically in a header file. Which has political and technical issues:
-+
-+ 1) Some firmware is not legal to redistribute.
-+ 2) The firmware occupies memory permanently, even though it often is just
-+ used once.
-+ 3) Some people, like the Debian crowd, don't consider some firmware free
-+ enough and remove entire drivers (e.g.: keyspan).
-+
-+ about in-kernel persistence:
-+ ---------------------------
-+ Under some circumstances, as explained below, it would be interesting to keep
-+ firmware images in non-swappable kernel memory or even in the kernel image
-+ (probably within initramfs).
-+
-+ Note that this functionality has not been implemented.
-+
-+ - Why OPTIONAL in-kernel persistence may be a good idea sometimes:
-+
-+ - If the device that needs the firmware is needed to access the
-+ filesystem. When upon some error the device has to be reset and the
-+ firmware reloaded, it won't be possible to get it from userspace.
-+ e.g.:
-+ - A diskless client with a network card that needs firmware.
-+ - The filesystem is stored in a disk behind an scsi device
-+ that needs firmware.
-+ - Replacing buggy DSDT/SSDT ACPI tables on boot.
-+ Note: this would require the persistent objects to be included
-+ within the kernel image, probably within initramfs.
-+
-+ And the same device can be needed to access the filesystem or not depending
-+ on the setup, so I think that the choice on what firmware to make
-+ persistent should be left to userspace.
-+
-+ - Why register_firmware()+__init can be useful:
-+ - For boot devices needing firmware.
-+ - To make the transition easier:
-+ The firmware can be declared __init and register_firmware()
-+ called on module_init. Then the firmware is warranted to be
-+ there even if "firmware hotplug userspace" is not there yet or
-+ it doesn't yet provide the needed firmware.
-+ Once the firmware is widely available in userspace, it can be
-+ removed from the kernel. Or made optional (CONFIG_.*_FIRMWARE).
-+
-+ In either case, if firmware hotplug support is there, it can move the
-+ firmware out of kernel memory into the real filesystem for later
-+ usage.
-+
-+ Note: If persistence is implemented on top of initramfs,
-+ register_firmware() may not be appropriate.
-diff -urN linux-2.4.18/Documentation/firmware_class/firmware_sample_driver.c linux-2.4.18-mh9/Documentation/firmware_class/firmware_sample_driver.c
---- linux-2.4.18/Documentation/firmware_class/firmware_sample_driver.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/Documentation/firmware_class/firmware_sample_driver.c Mon Aug 25 18:38:10 2003
-@@ -0,0 +1,121 @@
-+/*
-+ * firmware_sample_driver.c -
-+ *
-+ * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
-+ *
-+ * Sample code on how to use request_firmware() from drivers.
-+ *
-+ * Note that register_firmware() is currently useless.
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/string.h>
-+
-+#include "linux/firmware.h"
-+
-+#define WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
-+#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
-+char __init inkernel_firmware[] = "let's say that this is firmware\n";
-+#endif
-+
-+static char ghost_device[] = "ghost0";
-+
-+static void sample_firmware_load(char *firmware, int size)
-+{
-+ u8 buf[size+1];
-+ memcpy(buf, firmware, size);
-+ buf[size] = '\0';
-+ printk("firmware_sample_driver: firmware: %s\n", buf);
-+}
-+
-+static void sample_probe_default(void)
-+{
-+ /* uses the default method to get the firmware */
-+ const struct firmware *fw_entry;
-+ printk("firmware_sample_driver: a ghost device got inserted :)\n");
-+
-+ if(request_firmware(&fw_entry, "sample_driver_fw", ghost_device)!=0)
-+ {
-+ printk(KERN_ERR
-+ "firmware_sample_driver: Firmware not available\n");
-+ return;
-+ }
-+
-+ sample_firmware_load(fw_entry->data, fw_entry->size);
-+
-+ release_firmware(fw_entry);
-+
-+ /* finish setting up the device */
-+}
-+static void sample_probe_specific(void)
-+{
-+ /* Uses some specific hotplug support to get the firmware from
-+ * userspace directly into the hardware, or via some sysfs file */
-+
-+ /* NOTE: This currently doesn't work */
-+
-+ printk("firmware_sample_driver: a ghost device got inserted :)\n");
-+
-+ if(request_firmware(NULL, "sample_driver_fw", ghost_device)!=0)
-+ {
-+ printk(KERN_ERR
-+ "firmware_sample_driver: Firmware load failed\n");
-+ return;
-+ }
-+
-+ /* request_firmware blocks until userspace finished, so at
-+ * this point the firmware should be already in the device */
-+
-+ /* finish setting up the device */
-+}
-+static void sample_probe_async_cont(const struct firmware *fw, void *context)
-+{
-+ if(!fw){
-+ printk(KERN_ERR
-+ "firmware_sample_driver: firmware load failed\n");
-+ return;
-+ }
-+
-+ printk("firmware_sample_driver: device pointer \"%s\"\n",
-+ (char *)context);
-+ sample_firmware_load(fw->data, fw->size);
-+}
-+static void sample_probe_async(void)
-+{
-+ /* Let's say that I can't sleep */
-+ int error;
-+ error = request_firmware_nowait (THIS_MODULE,
-+ "sample_driver_fw", ghost_device,
-+ "my device pointer",
-+ sample_probe_async_cont);
-+ if(error){
-+ printk(KERN_ERR
-+ "firmware_sample_driver:"
-+ " request_firmware_nowait failed\n");
-+ }
-+}
-+
-+static int sample_init(void)
-+{
-+#ifdef WE_CAN_NEED_FIRMWARE_BEFORE_USERSPACE_IS_AVAILABLE
-+ register_firmware("sample_driver_fw", inkernel_firmware,
-+ sizeof(inkernel_firmware));
-+#endif
-+ /* since there is no real hardware insertion I just call the
-+ * sample probe functions here */
-+ sample_probe_specific();
-+ sample_probe_default();
-+ sample_probe_async();
-+ return 0;
-+}
-+static void __exit sample_exit(void)
-+{
-+}
-+
-+module_init (sample_init);
-+module_exit (sample_exit);
-+
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/Documentation/firmware_class/hotplug-script linux-2.4.18-mh9/Documentation/firmware_class/hotplug-script
---- linux-2.4.18/Documentation/firmware_class/hotplug-script Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/Documentation/firmware_class/hotplug-script Mon Aug 25 18:38:10 2003
-@@ -0,0 +1,16 @@
-+#!/bin/sh
-+
-+# Simple hotplug script sample:
-+#
-+# Both $DEVPATH and $FIRMWARE are already provided in the environment.
-+
-+HOTPLUG_FW_DIR=/usr/lib/hotplug/firmware/
-+
-+echo 1 > /sysfs/$DEVPATH/loading
-+cat $HOTPLUG_FW_DIR/$FIRMWARE > /sysfs/$DEVPATH/data
-+echo 0 > /sysfs/$DEVPATH/loading
-+
-+# To cancel the load in case of error:
-+#
-+# echo -1 > /sysfs/$DEVPATH/loading
-+#
-diff -urN linux-2.4.18/MAINTAINERS linux-2.4.18-mh9/MAINTAINERS
---- linux-2.4.18/MAINTAINERS Mon Feb 25 20:37:52 2002
-+++ linux-2.4.18-mh9/MAINTAINERS Mon Aug 25 18:38:10 2003
-@@ -252,7 +252,73 @@
- L: linux-kernel@vger.kernel.org
- S: Maintained
-
--BLUETOOTH SUBSYSTEM (BlueZ)
-+BLUETOOTH SUBSYSTEM
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+W: http://bluez.sf.net
-+S: Maintained
-+
-+BLUETOOTH RFCOMM LAYER
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+W: http://bluez.sf.net
-+S: Maintained
-+
-+BLUETOOTH BNEP LAYER
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+W: http://bluez.sf.net
-+S: Maintained
-+
-+BLUETOOTH CMTP LAYER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+W: http://www.holtmann.org/linux/bluetooth/
-+S: Maintained
-+
-+BLUETOOTH HCI USB DRIVER
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+W: http://bluez.sf.net
-+S: Maintained
-+
-+BLUETOOTH HCI UART DRIVER
-+P: Maxim Krasnyansky
-+M: maxk@qualcomm.com
-+W: http://bluez.sf.net
-+S: Maintained
-+
-+BLUETOOTH HCI BFUSB DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+W: http://www.holtmann.org/linux/bluetooth/
-+S: Maintained
-+
-+BLUETOOTH HCI DTL1 DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+W: http://www.holtmann.org/linux/bluetooth/
-+S: Maintained
-+
-+BLUETOOTH HCI BLUECARD DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+W: http://www.holtmann.org/linux/bluetooth/
-+S: Maintained
-+
-+BLUETOOTH HCI BT3C DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+W: http://www.holtmann.org/linux/bluetooth/
-+S: Maintained
-+
-+BLUETOOTH HCI BTUART DRIVER
-+P: Marcel Holtmann
-+M: marcel@holtmann.org
-+W: http://www.holtmann.org/linux/bluetooth/
-+S: Maintained
-+
-+BLUETOOTH HCI VHCI DRIVER
- P: Maxim Krasnyansky
- M: maxk@qualcomm.com
- W: http://bluez.sf.net
-diff -urN linux-2.4.18/arch/alpha/config.in linux-2.4.18-mh9/arch/alpha/config.in
---- linux-2.4.18/arch/alpha/config.in Wed Nov 21 00:49:31 2001
-+++ linux-2.4.18-mh9/arch/alpha/config.in Mon Aug 25 18:38:10 2003
-@@ -371,9 +371,7 @@
- source drivers/usb/Config.in
- source drivers/input/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Kernel hacking'
-diff -urN linux-2.4.18/arch/arm/config.in linux-2.4.18-mh9/arch/arm/config.in
---- linux-2.4.18/arch/arm/config.in Fri Nov 9 22:58:02 2001
-+++ linux-2.4.18-mh9/arch/arm/config.in Mon Aug 25 18:38:10 2003
-@@ -584,9 +584,7 @@
-
- source drivers/usb/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Kernel hacking'
-diff -urN linux-2.4.18/arch/i386/config.in linux-2.4.18-mh9/arch/i386/config.in
---- linux-2.4.18/arch/i386/config.in Mon Feb 25 20:37:52 2002
-+++ linux-2.4.18-mh9/arch/i386/config.in Mon Aug 25 18:38:10 2003
-@@ -407,9 +407,7 @@
-
- source drivers/usb/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Kernel hacking'
-diff -urN linux-2.4.18/arch/ppc/config.in linux-2.4.18-mh9/arch/ppc/config.in
---- linux-2.4.18/arch/ppc/config.in Mon Feb 25 20:37:55 2002
-+++ linux-2.4.18-mh9/arch/ppc/config.in Mon Aug 25 18:38:10 2003
-@@ -389,9 +389,7 @@
-
- source drivers/usb/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Kernel hacking'
-diff -urN linux-2.4.18/arch/sparc/config.in linux-2.4.18-mh9/arch/sparc/config.in
---- linux-2.4.18/arch/sparc/config.in Tue Jun 12 04:15:27 2001
-+++ linux-2.4.18-mh9/arch/sparc/config.in Mon Aug 25 18:38:10 2003
-@@ -251,9 +251,7 @@
-
- source fs/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Watchdog'
-diff -urN linux-2.4.18/arch/sparc64/config.in linux-2.4.18-mh9/arch/sparc64/config.in
---- linux-2.4.18/arch/sparc64/config.in Fri Dec 21 18:41:53 2001
-+++ linux-2.4.18-mh9/arch/sparc64/config.in Mon Aug 25 18:38:10 2003
-@@ -283,9 +283,7 @@
-
- source drivers/usb/Config.in
-
--if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-- source net/bluetooth/Config.in
--fi
-+source net/bluetooth/Config.in
-
- mainmenu_option next_comment
- comment 'Watchdog'
-diff -urN linux-2.4.18/arch/sparc64/kernel/ioctl32.c linux-2.4.18-mh9/arch/sparc64/kernel/ioctl32.c
---- linux-2.4.18/arch/sparc64/kernel/ioctl32.c Mon Feb 25 20:37:56 2002
-+++ linux-2.4.18-mh9/arch/sparc64/kernel/ioctl32.c Mon Aug 25 18:38:10 2003
-@@ -92,6 +92,7 @@
-
- #include <net/bluetooth/bluetooth.h>
- #include <net/bluetooth/hci.h>
-+#include <net/bluetooth/rfcomm.h>
-
- #include <linux/usb.h>
- #include <linux/usbdevice_fs.h>
-@@ -3822,6 +3823,15 @@
- return err;
- }
-
-+/* Bluetooth ioctls */
-+#define HCIUARTSETPROTO _IOW('U', 200, int)
-+#define HCIUARTGETPROTO _IOR('U', 201, int)
-+
-+#define BNEPCONNADD _IOW('B', 200, int)
-+#define BNEPCONNDEL _IOW('B', 201, int)
-+#define BNEPGETCONNLIST _IOR('B', 210, int)
-+#define BNEPGETCONNINFO _IOR('B', 211, int)
-+
- struct mtd_oob_buf32 {
- u32 start;
- u32 length;
-@@ -3878,6 +3888,11 @@
- return ((0 == ret) ? 0 : -EFAULT);
- }
-
-+#define CMTPCONNADD _IOW('C', 200, int)
-+#define CMTPCONNDEL _IOW('C', 201, int)
-+#define CMTPGETCONNLIST _IOR('C', 210, int)
-+#define CMTPGETCONNINFO _IOR('C', 211, int)
-+
- struct ioctl_trans {
- unsigned int cmd;
- unsigned int handler;
-@@ -4540,6 +4555,21 @@
- COMPATIBLE_IOCTL(HCISETSCAN)
- COMPATIBLE_IOCTL(HCISETAUTH)
- COMPATIBLE_IOCTL(HCIINQUIRY)
-+COMPATIBLE_IOCTL(HCIUARTSETPROTO)
-+COMPATIBLE_IOCTL(HCIUARTGETPROTO)
-+COMPATIBLE_IOCTL(RFCOMMCREATEDEV)
-+COMPATIBLE_IOCTL(RFCOMMRELEASEDEV)
-+COMPATIBLE_IOCTL(RFCOMMGETDEVLIST)
-+COMPATIBLE_IOCTL(RFCOMMGETDEVINFO)
-+COMPATIBLE_IOCTL(RFCOMMSTEALDLC)
-+COMPATIBLE_IOCTL(BNEPCONNADD)
-+COMPATIBLE_IOCTL(BNEPCONNDEL)
-+COMPATIBLE_IOCTL(BNEPGETCONNLIST)
-+COMPATIBLE_IOCTL(BNEPGETCONNINFO)
-+COMPATIBLE_IOCTL(CMTPCONNADD)
-+COMPATIBLE_IOCTL(CMTPCONNDEL)
-+COMPATIBLE_IOCTL(CMTPGETCONNLIST)
-+COMPATIBLE_IOCTL(CMTPGETCONNINFO)
- /* Misc. */
- COMPATIBLE_IOCTL(0x41545900) /* ATYIO_CLKR */
- COMPATIBLE_IOCTL(0x41545901) /* ATYIO_CLKW */
-diff -urN linux-2.4.18/drivers/bluetooth/Config.in linux-2.4.18-mh9/drivers/bluetooth/Config.in
---- linux-2.4.18/drivers/bluetooth/Config.in Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/drivers/bluetooth/Config.in Mon Aug 25 18:38:10 2003
-@@ -1,8 +1,34 @@
-+#
-+# Bluetooth HCI device drivers configuration
-+#
-+
- mainmenu_option next_comment
- comment 'Bluetooth device drivers'
-
- dep_tristate 'HCI USB driver' CONFIG_BLUEZ_HCIUSB $CONFIG_BLUEZ $CONFIG_USB
-+if [ "$CONFIG_BLUEZ_HCIUSB" != "n" ]; then
-+ bool ' SCO (voice) support' CONFIG_BLUEZ_USB_SCO
-+ bool ' USB zero packet support' CONFIG_BLUEZ_USB_ZERO_PACKET
-+fi
-+
- dep_tristate 'HCI UART driver' CONFIG_BLUEZ_HCIUART $CONFIG_BLUEZ
--dep_tristate 'HCI VHCI virtual HCI device driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
-+if [ "$CONFIG_BLUEZ_HCIUART" != "n" ]; then
-+ bool ' UART (H4) protocol support' CONFIG_BLUEZ_HCIUART_H4
-+ bool ' BCSP protocol support' CONFIG_BLUEZ_HCIUART_BCSP
-+ dep_bool ' Transmit CRC with every BCSP packet' CONFIG_BLUEZ_HCIUART_BCSP_TXCRC $CONFIG_BLUEZ_HCIUART_BCSP
-+fi
-+
-+dep_tristate 'HCI BlueFRITZ! USB driver' CONFIG_BLUEZ_HCIBFUSB $CONFIG_BLUEZ $CONFIG_USB
-+
-+dep_tristate 'HCI DTL1 (PC Card) driver' CONFIG_BLUEZ_HCIDTL1 $CONFIG_PCMCIA $CONFIG_BLUEZ
-+
-+dep_tristate 'HCI BT3C (PC Card) driver' CONFIG_BLUEZ_HCIBT3C $CONFIG_PCMCIA $CONFIG_BLUEZ
-+
-+dep_tristate 'HCI BlueCard (PC Card) driver' CONFIG_BLUEZ_HCIBLUECARD $CONFIG_PCMCIA $CONFIG_BLUEZ
-+
-+dep_tristate 'HCI UART (PC Card) driver' CONFIG_BLUEZ_HCIBTUART $CONFIG_PCMCIA $CONFIG_BLUEZ
-+
-+dep_tristate 'HCI VHCI (Virtual HCI device) driver' CONFIG_BLUEZ_HCIVHCI $CONFIG_BLUEZ
-
- endmenu
-+
-diff -urN linux-2.4.18/drivers/bluetooth/Makefile linux-2.4.18-mh9/drivers/bluetooth/Makefile
---- linux-2.4.18/drivers/bluetooth/Makefile Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/drivers/bluetooth/Makefile Mon Aug 25 18:38:10 2003
-@@ -1,11 +1,27 @@
- #
--# Makefile for Bluetooth HCI device drivers.
-+# Makefile for the Linux Bluetooth HCI device drivers
- #
-
- O_TARGET := bluetooth.o
-
-+list-multi := hci_uart.o
-+
- obj-$(CONFIG_BLUEZ_HCIUSB) += hci_usb.o
--obj-$(CONFIG_BLUEZ_HCIUART) += hci_uart.o
- obj-$(CONFIG_BLUEZ_HCIVHCI) += hci_vhci.o
-
-+obj-$(CONFIG_BLUEZ_HCIUART) += hci_uart.o
-+uart-y := hci_ldisc.o
-+uart-$(CONFIG_BLUEZ_HCIUART_H4) += hci_h4.o
-+uart-$(CONFIG_BLUEZ_HCIUART_BCSP) += hci_bcsp.o
-+
-+obj-$(CONFIG_BLUEZ_HCIBFUSB) += bfusb.o
-+
-+obj-$(CONFIG_BLUEZ_HCIDTL1) += dtl1_cs.o
-+obj-$(CONFIG_BLUEZ_HCIBT3C) += bt3c_cs.o
-+obj-$(CONFIG_BLUEZ_HCIBLUECARD) += bluecard_cs.o
-+obj-$(CONFIG_BLUEZ_HCIBTUART) += btuart_cs.o
-+
- include $(TOPDIR)/Rules.make
-+
-+hci_uart.o: $(uart-y)
-+ $(LD) -r -o $@ $(uart-y)
-diff -urN linux-2.4.18/drivers/bluetooth/Makefile.lib linux-2.4.18-mh9/drivers/bluetooth/Makefile.lib
---- linux-2.4.18/drivers/bluetooth/Makefile.lib Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/drivers/bluetooth/Makefile.lib Mon Aug 25 18:38:10 2003
-@@ -0,0 +1 @@
-+obj-$(CONFIG_BLUEZ_HCIBFUSB) += firmware_class.o
-diff -urN linux-2.4.18/drivers/bluetooth/bfusb.c linux-2.4.18-mh9/drivers/bluetooth/bfusb.c
---- linux-2.4.18/drivers/bluetooth/bfusb.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/drivers/bluetooth/bfusb.c Mon Aug 25 18:38:10 2003
-@@ -0,0 +1,781 @@
-+/*
-+ *
-+ * AVM BlueFRITZ! USB driver
-+ *
-+ * Copyright (C) 2003 Marcel Holtmann <marcel@holtmann.org>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/errno.h>
-+#include <linux/skbuff.h>
-+
-+#include <linux/firmware.h>
-+#include <linux/usb.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+#ifndef CONFIG_BLUEZ_HCIBFUSB_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define VERSION "1.1"
-+
-+static struct usb_device_id bfusb_table[] = {
-+ /* AVM BlueFRITZ! USB */
-+ { USB_DEVICE(0x057c, 0x2200) },
-+
-+ { } /* Terminating entry */
-+};
-+
-+MODULE_DEVICE_TABLE(usb, bfusb_table);
-+
-+
-+#define BFUSB_MAX_BLOCK_SIZE 256
-+
-+#define BFUSB_BLOCK_TIMEOUT (HZ * 3)
-+
-+#define BFUSB_TX_PROCESS 1
-+#define BFUSB_TX_WAKEUP 2
-+
-+#define BFUSB_MAX_BULK_TX 1
-+#define BFUSB_MAX_BULK_RX 1
-+
-+struct bfusb {
-+ struct hci_dev hdev;
-+
-+ unsigned long state;
-+
-+ struct usb_device *udev;
-+
-+ unsigned int bulk_in_ep;
-+ unsigned int bulk_out_ep;
-+ unsigned int bulk_pkt_size;
-+
-+ rwlock_t lock;
-+
-+ struct sk_buff_head transmit_q;
-+
-+ struct sk_buff *reassembly;
-+
-+ atomic_t pending_tx;
-+ struct sk_buff_head pending_q;
-+ struct sk_buff_head completed_q;
-+};
-+
-+struct bfusb_scb {
-+ struct urb *urb;
-+};
-+
-+static void bfusb_tx_complete(struct urb *urb);
-+static void bfusb_rx_complete(struct urb *urb);
-+
-+static struct urb *bfusb_get_completed(struct bfusb *bfusb)
-+{
-+ struct sk_buff *skb;
-+ struct urb *urb = NULL;
-+
-+ BT_DBG("bfusb %p", bfusb);
-+
-+ skb = skb_dequeue(&bfusb->completed_q);
-+ if (skb) {
-+ urb = ((struct bfusb_scb *) skb->cb)->urb;
-+ kfree_skb(skb);
-+ }
-+
-+ return urb;
-+}
-+
-+static inline void bfusb_unlink_urbs(struct bfusb *bfusb)
-+{
-+ struct sk_buff *skb;
-+ struct urb *urb;
-+
-+ BT_DBG("bfusb %p", bfusb);
-+
-+ while ((skb = skb_dequeue(&bfusb->pending_q))) {
-+ urb = ((struct bfusb_scb *) skb->cb)->urb;
-+ usb_unlink_urb(urb);
-+ skb_queue_tail(&bfusb->completed_q, skb);
-+ }
-+
-+ while ((urb = bfusb_get_completed(bfusb)))
-+ usb_free_urb(urb);
-+}
-+
-+
-+static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb)
-+{
-+ struct bfusb_scb *scb = (void *) skb->cb;
-+ struct urb *urb = bfusb_get_completed(bfusb);
-+ int err, pipe;
-+
-+ BT_DBG("bfusb %p skb %p len %d", bfusb, skb, skb->len);
-+
-+ if (!urb && !(urb = usb_alloc_urb(0)))
-+ return -ENOMEM;
-+
-+ pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
-+
-+ FILL_BULK_URB(urb, bfusb->udev, pipe, skb->data, skb->len,
-+ bfusb_tx_complete, skb);
-+
-+ urb->transfer_flags = USB_QUEUE_BULK;
-+
-+ scb->urb = urb;
-+
-+ skb_queue_tail(&bfusb->pending_q, skb);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s bulk tx submit failed urb %p err %d",
-+ bfusb->hdev.name, urb, err);
-+ skb_unlink(skb);
-+ usb_free_urb(urb);
-+ } else
-+ atomic_inc(&bfusb->pending_tx);
-+
-+ return err;
-+}
-+
-+static void bfusb_tx_wakeup(struct bfusb *bfusb)
-+{
-+ struct sk_buff *skb;
-+
-+ BT_DBG("bfusb %p", bfusb);
-+
-+ if (test_and_set_bit(BFUSB_TX_PROCESS, &bfusb->state)) {
-+ set_bit(BFUSB_TX_WAKEUP, &bfusb->state);
-+ return;
-+ }
-+
-+ do {
-+ clear_bit(BFUSB_TX_WAKEUP, &bfusb->state);
-+
-+ while ((atomic_read(&bfusb->pending_tx) < BFUSB_MAX_BULK_TX) &&
-+ (skb = skb_dequeue(&bfusb->transmit_q))) {
-+ if (bfusb_send_bulk(bfusb, skb) < 0) {
-+ skb_queue_head(&bfusb->transmit_q, skb);
-+ break;
-+ }
-+ }
-+
-+ } while (test_bit(BFUSB_TX_WAKEUP, &bfusb->state));
-+
-+ clear_bit(BFUSB_TX_PROCESS, &bfusb->state);
-+}
-+
-+static void bfusb_tx_complete(struct urb *urb)
-+{
-+ struct sk_buff *skb = (struct sk_buff *) urb->context;
-+ struct bfusb *bfusb = (struct bfusb *) skb->dev;
-+
-+ BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
-+
-+ atomic_dec(&bfusb->pending_tx);
-+
-+ if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags))
-+ return;
-+
-+ if (!urb->status)
-+ bfusb->hdev.stat.byte_tx += skb->len;
-+ else
-+ bfusb->hdev.stat.err_tx++;
-+
-+ read_lock(&bfusb->lock);
-+
-+ skb_unlink(skb);
-+ skb_queue_tail(&bfusb->completed_q, skb);
-+
-+ bfusb_tx_wakeup(bfusb);
-+
-+ read_unlock(&bfusb->lock);
-+}
-+
-+
-+static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb)
-+{
-+ struct bfusb_scb *scb;
-+ struct sk_buff *skb;
-+ int err, pipe, size = HCI_MAX_FRAME_SIZE + 32;
-+
-+ BT_DBG("bfusb %p urb %p", bfusb, urb);
-+
-+ if (!urb && !(urb = usb_alloc_urb(0)))
-+ return -ENOMEM;
-+
-+ if (!(skb = bluez_skb_alloc(size, GFP_ATOMIC))) {
-+ usb_free_urb(urb);
-+ return -ENOMEM;
-+ }
-+
-+ skb->dev = (void *) bfusb;
-+
-+ scb = (struct bfusb_scb *) skb->cb;
-+ scb->urb = urb;
-+
-+ pipe = usb_rcvbulkpipe(bfusb->udev, bfusb->bulk_in_ep);
-+
-+ FILL_BULK_URB(urb, bfusb->udev, pipe, skb->data, size,
-+ bfusb_rx_complete, skb);
-+
-+ urb->transfer_flags = USB_QUEUE_BULK;
-+
-+ skb_queue_tail(&bfusb->pending_q, skb);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s bulk rx submit failed urb %p err %d",
-+ bfusb->hdev.name, urb, err);
-+ skb_unlink(skb);
-+ kfree_skb(skb);
-+ usb_free_urb(urb);
-+ }
-+
-+ return err;
-+}
-+
-+static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *data, int len)
-+{
-+ BT_DBG("bfusb %p hdr 0x%02x data %p len %d", bfusb, hdr, data, len);
-+
-+ if (hdr & 0x10) {
-+ BT_ERR("%s error in block", bfusb->hdev.name);
-+ if (bfusb->reassembly)
-+ kfree_skb(bfusb->reassembly);
-+ bfusb->reassembly = NULL;
-+ return -EIO;
-+ }
-+
-+ if (hdr & 0x04) {
-+ struct sk_buff *skb;
-+ unsigned char pkt_type;
-+ int pkt_len = 0;
-+
-+ if (bfusb->reassembly) {
-+ BT_ERR("%s unexpected start block", bfusb->hdev.name);
-+ kfree_skb(bfusb->reassembly);
-+ bfusb->reassembly = NULL;
-+ }
-+
-+ if (len < 1) {
-+ BT_ERR("%s no packet type found", bfusb->hdev.name);
-+ return -EPROTO;
-+ }
-+
-+ pkt_type = *data++; len--;
-+
-+ switch (pkt_type) {
-+ case HCI_EVENT_PKT:
-+ if (len >= HCI_EVENT_HDR_SIZE) {
-+ hci_event_hdr *hdr = (hci_event_hdr *) data;
-+ pkt_len = HCI_EVENT_HDR_SIZE + hdr->plen;
-+ } else {
-+ BT_ERR("%s event block is too short", bfusb->hdev.name);
-+ return -EILSEQ;
-+ }
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ if (len >= HCI_ACL_HDR_SIZE) {
-+ hci_acl_hdr *hdr = (hci_acl_hdr *) data;
-+ pkt_len = HCI_ACL_HDR_SIZE + __le16_to_cpu(hdr->dlen);
-+ } else {
-+ BT_ERR("%s data block is too short", bfusb->hdev.name);
-+ return -EILSEQ;
-+ }
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ if (len >= HCI_SCO_HDR_SIZE) {
-+ hci_sco_hdr *hdr = (hci_sco_hdr *) data;
-+ pkt_len = HCI_SCO_HDR_SIZE + hdr->dlen;
-+ } else {
-+ BT_ERR("%s audio block is too short", bfusb->hdev.name);
-+ return -EILSEQ;
-+ }
-+ break;
-+ }
-+
-+ skb = bluez_skb_alloc(pkt_len, GFP_ATOMIC);
-+ if (!skb) {
-+ BT_ERR("%s no memory for the packet", bfusb->hdev.name);
-+ return -ENOMEM;
-+ }
-+
-+ skb->dev = (void *) &bfusb->hdev;
-+ skb->pkt_type = pkt_type;
-+
-+ bfusb->reassembly = skb;
-+ } else {
-+ if (!bfusb->reassembly) {
-+ BT_ERR("%s unexpected continuation block", bfusb->hdev.name);
-+ return -EIO;
-+ }
-+ }
-+
-+ if (len > 0)
-+ memcpy(skb_put(bfusb->reassembly, len), data, len);
-+
-+ if (hdr & 0x08) {
-+ hci_recv_frame(bfusb->reassembly);
-+ bfusb->reassembly = NULL;
-+ }
-+
-+ return 0;
-+}
-+
-+static void bfusb_rx_complete(struct urb *urb)
-+{
-+ struct sk_buff *skb = (struct sk_buff *) urb->context;
-+ struct bfusb *bfusb = (struct bfusb *) skb->dev;
-+ unsigned char *buf = urb->transfer_buffer;
-+ int count = urb->actual_length;
-+ int err, hdr, len;
-+
-+ BT_DBG("bfusb %p urb %p skb %p len %d", bfusb, urb, skb, skb->len);
-+
-+ if (!test_bit(HCI_RUNNING, &bfusb->hdev.flags))
-+ return;
-+
-+ read_lock(&bfusb->lock);
-+
-+ if (urb->status || !count)
-+ goto resubmit;
-+
-+ bfusb->hdev.stat.byte_rx += count;
-+
-+ skb_put(skb, count);
-+
-+ while (count) {
-+ hdr = buf[0] | (buf[1] << 8);
-+
-+ if (hdr & 0x4000) {
-+ len = 0;
-+ count -= 2;
-+ buf += 2;
-+ } else {
-+ len = (buf[2] == 0) ? 256 : buf[2];
-+ count -= 3;
-+ buf += 3;
-+ }
-+
-+ if (count < len) {
-+ BT_ERR("%s block extends over URB buffer ranges",
-+ bfusb->hdev.name);
-+ }
-+
-+ if ((hdr & 0xe1) == 0xc1)
-+ bfusb_recv_block(bfusb, hdr, buf, len);
-+
-+ count -= len;
-+ buf += len;
-+ }
-+
-+ skb_unlink(skb);
-+ kfree_skb(skb);
-+
-+ bfusb_rx_submit(bfusb, urb);
-+
-+ read_unlock(&bfusb->lock);
-+
-+ return;
-+
-+resubmit:
-+ urb->dev = bfusb->udev;
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s bulk resubmit failed urb %p err %d",
-+ bfusb->hdev.name, urb, err);
-+ }
-+
-+ read_unlock(&bfusb->lock);
-+}
-+
-+
-+static int bfusb_open(struct hci_dev *hdev)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
-+ unsigned long flags;
-+ int i, err;
-+
-+ BT_DBG("hdev %p bfusb %p", hdev, bfusb);
-+
-+ if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ write_lock_irqsave(&bfusb->lock, flags);
-+
-+ err = bfusb_rx_submit(bfusb, NULL);
-+ if (!err) {
-+ for (i = 1; i < BFUSB_MAX_BULK_RX; i++)
-+ bfusb_rx_submit(bfusb, NULL);
-+ } else {
-+ clear_bit(HCI_RUNNING, &hdev->flags);
-+ MOD_DEC_USE_COUNT;
-+ }
-+
-+ write_unlock_irqrestore(&bfusb->lock, flags);
-+
-+ return err;
-+}
-+
-+static int bfusb_flush(struct hci_dev *hdev)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
-+
-+ BT_DBG("hdev %p bfusb %p", hdev, bfusb);
-+
-+ skb_queue_purge(&bfusb->transmit_q);
-+
-+ return 0;
-+}
-+
-+static int bfusb_close(struct hci_dev *hdev)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
-+ unsigned long flags;
-+
-+ BT_DBG("hdev %p bfusb %p", hdev, bfusb);
-+
-+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-+
-+ write_lock_irqsave(&bfusb->lock, flags);
-+
-+ bfusb_unlink_urbs(bfusb);
-+ bfusb_flush(hdev);
-+
-+ write_unlock_irqrestore(&bfusb->lock, flags);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ return 0;
-+}
-+
-+static int bfusb_send_frame(struct sk_buff *skb)
-+{
-+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-+ struct bfusb *bfusb;
-+ struct sk_buff *nskb;
-+ unsigned char buf[3];
-+ int sent = 0, size, count;
-+
-+ BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, skb->pkt_type, skb->len);
-+
-+ if (!hdev) {
-+ BT_ERR("Frame for unknown HCI device (hdev=NULL)");
-+ return -ENODEV;
-+ }
-+
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return -EBUSY;
-+
-+ bfusb = (struct bfusb *) hdev->driver_data;
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+
-+ count = skb->len;
-+
-+ /* Max HCI frame size seems to be 1511 + 1 */
-+ if (!(nskb = bluez_skb_alloc(count + 32, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for new packet");
-+ return -ENOMEM;
-+ }
-+
-+ nskb->dev = (void *) bfusb;
-+
-+ while (count) {
-+ size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE);
-+
-+ buf[0] = 0xc1 | ((sent == 0) ? 0x04 : 0) | ((count == size) ? 0x08 : 0);
-+ buf[1] = 0x00;
-+ buf[2] = (size == BFUSB_MAX_BLOCK_SIZE) ? 0 : size;
-+
-+ memcpy(skb_put(nskb, 3), buf, 3);
-+ memcpy(skb_put(nskb, size), skb->data + sent, size);
-+
-+ sent += size;
-+ count -= size;
-+ }
-+
-+ /* Don't send frame with multiple size of bulk max packet */
-+ if ((nskb->len % bfusb->bulk_pkt_size) == 0) {
-+ buf[0] = 0xdd;
-+ buf[1] = 0x00;
-+ memcpy(skb_put(nskb, 2), buf, 2);
-+ }
-+
-+ read_lock(&bfusb->lock);
-+
-+ skb_queue_tail(&bfusb->transmit_q, nskb);
-+ bfusb_tx_wakeup(bfusb);
-+
-+ read_unlock(&bfusb->lock);
-+
-+ kfree_skb(skb);
-+
-+ return 0;
-+}
-+
-+static void bfusb_destruct(struct hci_dev *hdev)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) hdev->driver_data;
-+
-+ BT_DBG("hdev %p bfusb %p", hdev, bfusb);
-+
-+ kfree(bfusb);
-+}
-+
-+static int bfusb_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+static int bfusb_load_firmware(struct bfusb *bfusb, unsigned char *firmware, int count)
-+{
-+ unsigned char *buf;
-+ int err, pipe, len, size, sent = 0;
-+
-+ BT_DBG("bfusb %p udev %p firmware %p count %d", bfusb, bfusb->udev, firmware, count);
-+
-+ BT_INFO("BlueFRITZ! USB loading firmware");
-+
-+ if (usb_set_configuration(bfusb->udev, 1) < 0) {
-+ BT_ERR("Can't change to loading configuration");
-+ return -EBUSY;
-+ }
-+
-+ buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
-+ if (!buf) {
-+ BT_ERR("Can't allocate memory chunk for firmware");
-+ return -ENOMEM;
-+ }
-+
-+ pipe = usb_sndbulkpipe(bfusb->udev, bfusb->bulk_out_ep);
-+
-+ while (count) {
-+ size = min_t(uint, count, BFUSB_MAX_BLOCK_SIZE + 3);
-+
-+ memcpy(buf, firmware + sent, size);
-+
-+ err = usb_bulk_msg(bfusb->udev, pipe, buf, size,
-+ &len, BFUSB_BLOCK_TIMEOUT);
-+
-+ if (err || (len != size)) {
-+ BT_ERR("Error in firmware loading");
-+ goto error;
-+ }
-+
-+ sent += size;
-+ count -= size;
-+ }
-+
-+ if ((err = usb_bulk_msg(bfusb->udev, pipe, NULL, 0,
-+ &len, BFUSB_BLOCK_TIMEOUT)) < 0) {
-+ BT_ERR("Error in null packet request");
-+ goto error;
-+ }
-+
-+ if ((err = usb_set_configuration(bfusb->udev, 2)) < 0) {
-+ BT_ERR("Can't change to running configuration");
-+ goto error;
-+ }
-+
-+ BT_INFO("BlueFRITZ! USB device ready");
-+
-+ kfree(buf);
-+ return 0;
-+
-+error:
-+ kfree(buf);
-+
-+ pipe = usb_sndctrlpipe(bfusb->udev, 0);
-+
-+ usb_control_msg(bfusb->udev, pipe, USB_REQ_SET_CONFIGURATION,
-+ 0, 0, 0, NULL, 0, BFUSB_BLOCK_TIMEOUT);
-+
-+ return err;
-+}
-+
-+static void *bfusb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
-+{
-+ const struct firmware *firmware;
-+ char device[16];
-+ struct usb_interface *iface;
-+ struct usb_interface_descriptor *iface_desc;
-+ struct usb_endpoint_descriptor *bulk_out_ep;
-+ struct usb_endpoint_descriptor *bulk_in_ep;
-+ struct hci_dev *hdev;
-+ struct bfusb *bfusb;
-+
-+ BT_DBG("udev %p ifnum %d id %p", udev, ifnum, id);
-+
-+ /* Check number of endpoints */
-+ iface = &udev->actconfig->interface[0];
-+ iface_desc = &iface->altsetting[0];
-+
-+ if (iface_desc->bNumEndpoints < 2)
-+ return NULL;
-+
-+ bulk_out_ep = &iface_desc->endpoint[0];
-+ bulk_in_ep = &iface_desc->endpoint[1];
-+
-+ if (!bulk_out_ep || !bulk_in_ep) {
-+ BT_ERR("Bulk endpoints not found");
-+ goto done;
-+ }
-+
-+ /* Initialize control structure and load firmware */
-+ if (!(bfusb = kmalloc(sizeof(struct bfusb), GFP_KERNEL))) {
-+ BT_ERR("Can't allocate memory for control structure");
-+ goto done;
-+ }
-+
-+ memset(bfusb, 0, sizeof(struct bfusb));
-+
-+ bfusb->udev = udev;
-+ bfusb->bulk_in_ep = bulk_in_ep->bEndpointAddress;
-+ bfusb->bulk_out_ep = bulk_out_ep->bEndpointAddress;
-+ bfusb->bulk_pkt_size = bulk_out_ep->wMaxPacketSize;
-+
-+ bfusb->lock = RW_LOCK_UNLOCKED;
-+
-+ bfusb->reassembly = NULL;
-+
-+ skb_queue_head_init(&bfusb->transmit_q);
-+ skb_queue_head_init(&bfusb->pending_q);
-+ skb_queue_head_init(&bfusb->completed_q);
-+
-+ snprintf(device, sizeof(device), "bfusb%3.3d%3.3d", udev->bus->busnum, udev->devnum);
-+
-+ if (request_firmware(&firmware, "bfubase.frm", device) < 0) {
-+ BT_ERR("Firmware request failed");
-+ goto error;
-+ }
-+
-+ if (bfusb_load_firmware(bfusb, firmware->data, firmware->size) < 0) {
-+ BT_ERR("Firmware loading failed");
-+ goto release;
-+ }
-+
-+ release_firmware(firmware);
-+
-+ /* Initialize and register HCI device */
-+ hdev = &bfusb->hdev;
-+
-+ hdev->type = HCI_USB;
-+ hdev->driver_data = bfusb;
-+
-+ hdev->open = bfusb_open;
-+ hdev->close = bfusb_close;
-+ hdev->flush = bfusb_flush;
-+ hdev->send = bfusb_send_frame;
-+ hdev->destruct = bfusb_destruct;
-+ hdev->ioctl = bfusb_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ BT_ERR("Can't register HCI device");
-+ goto error;
-+ }
-+
-+ return bfusb;
-+
-+release:
-+ release_firmware(firmware);
-+
-+error:
-+ kfree(bfusb);
-+
-+done:
-+ return NULL;
-+}
-+
-+static void bfusb_disconnect(struct usb_device *udev, void *ptr)
-+{
-+ struct bfusb *bfusb = (struct bfusb *) ptr;
-+ struct hci_dev *hdev = &bfusb->hdev;
-+
-+ BT_DBG("udev %p ptr %p", udev, ptr);
-+
-+ if (!hdev)
-+ return;
-+
-+ bfusb_close(hdev);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ BT_ERR("Can't unregister HCI device %s", hdev->name);
-+}
-+
-+static struct usb_driver bfusb_driver = {
-+ name: "bfusb",
-+ probe: bfusb_probe,
-+ disconnect: bfusb_disconnect,
-+ id_table: bfusb_table,
-+};
-+
-+static int __init bfusb_init(void)
-+{
-+ int err;
-+
-+ BT_INFO("BlueFRITZ! USB driver ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2003 Marcel Holtmann <marcel@holtmann.org>");
-+
-+ if ((err = usb_register(&bfusb_driver)) < 0)
-+ BT_ERR("Failed to register BlueFRITZ! USB driver");
-+
-+ return err;
-+}
-+
-+static void __exit bfusb_cleanup(void)
-+{
-+ usb_deregister(&bfusb_driver);
-+}
-+
-+module_init(bfusb_init);
-+module_exit(bfusb_cleanup);
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueFRITZ! USB driver ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/drivers/bluetooth/bluecard_cs.c linux-2.4.18-mh9/drivers/bluetooth/bluecard_cs.c
---- linux-2.4.18/drivers/bluetooth/bluecard_cs.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/drivers/bluetooth/bluecard_cs.c Mon Aug 25 18:38:10 2003
-@@ -0,0 +1,1113 @@
-+/*
-+ *
-+ * Bluetooth driver for the Anycom BlueCard (LSE039/LSE041)
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+#include <linux/skbuff.h>
-+#include <asm/io.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0x86bc;
-+static int irq_list[4] = { -1 };
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ driver for the Anycom BlueCard (LSE039/LSE041)");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct bluecard_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+ struct timer_list timer; /* For LED control */
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+
-+ unsigned char ctrl_reg;
-+ unsigned long hw_state; /* Status of the hardware and LED control */
-+} bluecard_info_t;
-+
-+
-+void bluecard_config(dev_link_t *link);
-+void bluecard_release(u_long arg);
-+int bluecard_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "bluecard_cs";
-+
-+dev_link_t *bluecard_attach(void);
-+void bluecard_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+
-+/* Default baud rate: 57600, 115200, 230400 or 460800 */
-+#define DEFAULT_BAUD_RATE 230400
-+
-+
-+/* Hardware states */
-+#define CARD_READY 1
-+#define CARD_HAS_PCCARD_ID 4
-+#define CARD_HAS_POWER_LED 5
-+#define CARD_HAS_ACTIVITY_LED 6
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_BUFFER_NUMBER 5 /* unset = buffer one, set = buffer two */
-+#define XMIT_BUF_ONE_READY 6
-+#define XMIT_BUF_TWO_READY 7
-+#define XMIT_SENDING_READY 8
-+
-+/* Receiver states */
-+#define RECV_WAIT_PACKET_TYPE 0
-+#define RECV_WAIT_EVENT_HEADER 1
-+#define RECV_WAIT_ACL_HEADER 2
-+#define RECV_WAIT_SCO_HEADER 3
-+#define RECV_WAIT_DATA 4
-+
-+/* Special packet types */
-+#define PKT_BAUD_RATE_57600 0x80
-+#define PKT_BAUD_RATE_115200 0x81
-+#define PKT_BAUD_RATE_230400 0x82
-+#define PKT_BAUD_RATE_460800 0x83
-+
-+
-+/* These are the register offsets */
-+#define REG_COMMAND 0x20
-+#define REG_INTERRUPT 0x21
-+#define REG_CONTROL 0x22
-+#define REG_RX_CONTROL 0x24
-+#define REG_CARD_RESET 0x30
-+#define REG_LED_CTRL 0x30
-+
-+/* REG_COMMAND */
-+#define REG_COMMAND_TX_BUF_ONE 0x01
-+#define REG_COMMAND_TX_BUF_TWO 0x02
-+#define REG_COMMAND_RX_BUF_ONE 0x04
-+#define REG_COMMAND_RX_BUF_TWO 0x08
-+#define REG_COMMAND_RX_WIN_ONE 0x00
-+#define REG_COMMAND_RX_WIN_TWO 0x10
-+
-+/* REG_CONTROL */
-+#define REG_CONTROL_BAUD_RATE_57600 0x00
-+#define REG_CONTROL_BAUD_RATE_115200 0x01
-+#define REG_CONTROL_BAUD_RATE_230400 0x02
-+#define REG_CONTROL_BAUD_RATE_460800 0x03
-+#define REG_CONTROL_RTS 0x04
-+#define REG_CONTROL_BT_ON 0x08
-+#define REG_CONTROL_BT_RESET 0x10
-+#define REG_CONTROL_BT_RES_PU 0x20
-+#define REG_CONTROL_INTERRUPT 0x40
-+#define REG_CONTROL_CARD_RESET 0x80
-+
-+/* REG_RX_CONTROL */
-+#define RTS_LEVEL_SHIFT_BITS 0x02
-+
-+
-+
-+/* ======================== LED handling routines ======================== */
-+
-+
-+void bluecard_activity_led_timeout(u_long arg)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)arg;
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) {
-+ /* Disable activity LED */
-+ outb(0x08 | 0x20, iobase + 0x30);
-+ } else {
-+ /* Disable power LED */
-+ outb(0x00, iobase + 0x30);
-+ }
-+}
-+
-+
-+static void bluecard_enable_activity_led(bluecard_info_t *info)
-+{
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ if (test_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state))) {
-+ /* Enable activity LED */
-+ outb(0x10 | 0x40, iobase + 0x30);
-+
-+ /* Stop the LED after HZ/4 */
-+ mod_timer(&(info->timer), jiffies + HZ / 4);
-+ } else {
-+ /* Enable power LED */
-+ outb(0x08 | 0x20, iobase + 0x30);
-+
-+ /* Stop the LED after HZ/2 */
-+ mod_timer(&(info->timer), jiffies + HZ / 2);
-+ }
-+}
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int bluecard_write(unsigned int iobase, unsigned int offset, __u8 *buf, int len)
-+{
-+ int i, actual;
-+
-+ actual = (len > 15) ? 15 : len;
-+
-+ outb_p(actual, iobase + offset);
-+
-+ for (i = 0; i < actual; i++)
-+ outb_p(buf[i], iobase + offset + i + 1);
-+
-+ return actual;
-+}
-+
-+
-+static void bluecard_write_wakeup(bluecard_info_t *info)
-+{
-+ if (!info) {
-+ printk(KERN_WARNING "bluecard_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (!test_bit(XMIT_SENDING_READY, &(info->tx_state)))
-+ return;
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register unsigned int offset;
-+ register unsigned char command;
-+ register unsigned long ready_bit;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ clear_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ return;
-+
-+ if (test_bit(XMIT_BUFFER_NUMBER, &(info->tx_state))) {
-+ if (!test_bit(XMIT_BUF_TWO_READY, &(info->tx_state)))
-+ break;
-+ offset = 0x10;
-+ command = REG_COMMAND_TX_BUF_TWO;
-+ ready_bit = XMIT_BUF_TWO_READY;
-+ } else {
-+ if (!test_bit(XMIT_BUF_ONE_READY, &(info->tx_state)))
-+ break;
-+ offset = 0x00;
-+ command = REG_COMMAND_TX_BUF_ONE;
-+ ready_bit = XMIT_BUF_ONE_READY;
-+ }
-+
-+ if (!(skb = skb_dequeue(&(info->txq))))
-+ break;
-+
-+ if (skb->pkt_type & 0x80) {
-+ /* Disable RTS */
-+ info->ctrl_reg |= REG_CONTROL_RTS;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+ }
-+
-+ /* Activate LED */
-+ bluecard_enable_activity_led(info);
-+
-+ /* Send frame */
-+ len = bluecard_write(iobase, offset, skb->data, skb->len);
-+
-+ /* Tell the FPGA to send the data */
-+ outb_p(command, iobase + REG_COMMAND);
-+
-+ /* Mark the buffer as dirty */
-+ clear_bit(ready_bit, &(info->tx_state));
-+
-+ if (skb->pkt_type & 0x80) {
-+
-+ wait_queue_head_t wait;
-+ unsigned char baud_reg;
-+
-+ switch (skb->pkt_type) {
-+ case PKT_BAUD_RATE_460800:
-+ baud_reg = REG_CONTROL_BAUD_RATE_460800;
-+ break;
-+ case PKT_BAUD_RATE_230400:
-+ baud_reg = REG_CONTROL_BAUD_RATE_230400;
-+ break;
-+ case PKT_BAUD_RATE_115200:
-+ baud_reg = REG_CONTROL_BAUD_RATE_115200;
-+ break;
-+ case PKT_BAUD_RATE_57600:
-+ /* Fall through... */
-+ default:
-+ baud_reg = REG_CONTROL_BAUD_RATE_57600;
-+ break;
-+ }
-+
-+ /* Wait until the command reaches the baseband */
-+ init_waitqueue_head(&wait);
-+ interruptible_sleep_on_timeout(&wait, HZ / 10);
-+
-+ /* Set baud on baseband */
-+ info->ctrl_reg &= ~0x03;
-+ info->ctrl_reg |= baud_reg;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Enable RTS */
-+ info->ctrl_reg &= ~REG_CONTROL_RTS;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Wait before the next HCI packet can be send */
-+ interruptible_sleep_on_timeout(&wait, HZ);
-+
-+ }
-+
-+ if (len == skb->len) {
-+ kfree_skb(skb);
-+ } else {
-+ skb_pull(skb, len);
-+ skb_queue_head(&(info->txq), skb);
-+ }
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ /* Change buffer */
-+ change_bit(XMIT_BUFFER_NUMBER, &(info->tx_state));
-+
-+ } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
-+
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+}
-+
-+
-+static int bluecard_read(unsigned int iobase, unsigned int offset, __u8 *buf, int size)
-+{
-+ int i, n, len;
-+
-+ outb(REG_COMMAND_RX_WIN_ONE, iobase + REG_COMMAND);
-+
-+ len = inb(iobase + offset);
-+ n = 0;
-+ i = 1;
-+
-+ while (n < len) {
-+
-+ if (i == 16) {
-+ outb(REG_COMMAND_RX_WIN_TWO, iobase + REG_COMMAND);
-+ i = 0;
-+ }
-+
-+ buf[n] = inb(iobase + offset + i);
-+
-+ n++;
-+ i++;
-+
-+ }
-+
-+ return len;
-+}
-+
-+
-+static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
-+{
-+ unsigned int iobase;
-+ unsigned char buf[31];
-+ int i, len;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bluecard_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ if (test_bit(XMIT_SENDING_READY, &(info->tx_state)))
-+ bluecard_enable_activity_led(info);
-+
-+ len = bluecard_read(iobase, offset, buf, sizeof(buf));
-+
-+ for (i = 0; i < len; i++) {
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL) {
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "bluecard_cs: Can't allocate mem for new packet.\n");
-+ return;
-+ }
-+ }
-+
-+ if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
-+
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type = buf[i];
-+
-+ switch (info->rx_skb->pkt_type) {
-+
-+ case 0x00:
-+ /* init packet */
-+ if (offset != 0x00) {
-+ set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
-+ set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
-+ set_bit(XMIT_SENDING_READY, &(info->tx_state));
-+ bluecard_write_wakeup(info);
-+ }
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ case HCI_EVENT_PKT:
-+ info->rx_state = RECV_WAIT_EVENT_HEADER;
-+ info->rx_count = HCI_EVENT_HDR_SIZE;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ info->rx_state = RECV_WAIT_ACL_HEADER;
-+ info->rx_count = HCI_ACL_HDR_SIZE;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ info->rx_state = RECV_WAIT_SCO_HEADER;
-+ info->rx_count = HCI_SCO_HDR_SIZE;
-+ break;
-+
-+ default:
-+ /* unknown packet */
-+ printk(KERN_WARNING "bluecard_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-+ info->hdev.stat.err_rx++;
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ } else {
-+
-+ *skb_put(info->rx_skb, 1) = buf[i];
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ int dlen;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+
-+ switch (info->rx_state) {
-+
-+ case RECV_WAIT_EVENT_HEADER:
-+ eh = (hci_event_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = eh->plen;
-+ break;
-+
-+ case RECV_WAIT_ACL_HEADER:
-+ ah = (hci_acl_hdr *)(info->rx_skb->data);
-+ dlen = __le16_to_cpu(ah->dlen);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = dlen;
-+ break;
-+
-+ case RECV_WAIT_SCO_HEADER:
-+ sh = (hci_sco_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = sh->dlen;
-+ break;
-+
-+ case RECV_WAIT_DATA:
-+ hci_recv_frame(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+
-+ }
-+
-+ info->hdev.stat.byte_rx += len;
-+}
-+
-+
-+void bluecard_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ bluecard_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ unsigned char reg;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bluecard_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ if (!test_bit(CARD_READY, &(info->hw_state)))
-+ return;
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ /* Disable interrupt */
-+ info->ctrl_reg &= ~REG_CONTROL_INTERRUPT;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ reg = inb(iobase + REG_INTERRUPT);
-+
-+ if ((reg != 0x00) && (reg != 0xff)) {
-+
-+ if (reg & 0x04) {
-+ bluecard_receive(info, 0x00);
-+ outb(0x04, iobase + REG_INTERRUPT);
-+ outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
-+ }
-+
-+ if (reg & 0x08) {
-+ bluecard_receive(info, 0x10);
-+ outb(0x08, iobase + REG_INTERRUPT);
-+ outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);
-+ }
-+
-+ if (reg & 0x01) {
-+ set_bit(XMIT_BUF_ONE_READY, &(info->tx_state));
-+ outb(0x01, iobase + REG_INTERRUPT);
-+ bluecard_write_wakeup(info);
-+ }
-+
-+ if (reg & 0x02) {
-+ set_bit(XMIT_BUF_TWO_READY, &(info->tx_state));
-+ outb(0x02, iobase + REG_INTERRUPT);
-+ bluecard_write_wakeup(info);
-+ }
-+
-+ }
-+
-+ /* Enable interrupt */
-+ info->ctrl_reg |= REG_CONTROL_INTERRUPT;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+
-+
-+/* ======================== Device specific HCI commands ======================== */
-+
-+
-+static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-+ struct sk_buff *skb;
-+
-+ /* Ericsson baud rate command */
-+ unsigned char cmd[] = { HCI_COMMAND_PKT, 0x09, 0xfc, 0x01, 0x03 };
-+
-+ if (!(skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "bluecard_cs: Can't allocate mem for new packet.\n");
-+ return -1;
-+ }
-+
-+ switch (baud) {
-+ case 460800:
-+ cmd[4] = 0x00;
-+ skb->pkt_type = PKT_BAUD_RATE_460800;
-+ break;
-+ case 230400:
-+ cmd[4] = 0x01;
-+ skb->pkt_type = PKT_BAUD_RATE_230400;
-+ break;
-+ case 115200:
-+ cmd[4] = 0x02;
-+ skb->pkt_type = PKT_BAUD_RATE_115200;
-+ break;
-+ case 57600:
-+ /* Fall through... */
-+ default:
-+ cmd[4] = 0x03;
-+ skb->pkt_type = PKT_BAUD_RATE_57600;
-+ break;
-+ }
-+
-+ memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
-+
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ bluecard_write_wakeup(info);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int bluecard_hci_flush(struct hci_dev *hdev)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int bluecard_hci_open(struct hci_dev *hdev)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE);
-+
-+ if (test_and_set_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ /* Enable LED */
-+ outb(0x08 | 0x20, iobase + 0x30);
-+
-+ return 0;
-+}
-+
-+
-+static int bluecard_hci_close(struct hci_dev *hdev)
-+{
-+ bluecard_info_t *info = (bluecard_info_t *)(hdev->driver_data);
-+ unsigned int iobase = info->link.io.BasePort1;
-+
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ bluecard_hci_flush(hdev);
-+
-+ /* Disable LED */
-+ outb(0x00, iobase + 0x30);
-+
-+ return 0;
-+}
-+
-+
-+static int bluecard_hci_send_frame(struct sk_buff *skb)
-+{
-+ bluecard_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+
-+ if (!hdev) {
-+ printk(KERN_WARNING "bluecard_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (bluecard_info_t *)(hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ bluecard_write_wakeup(info);
-+
-+ return 0;
-+}
-+
-+
-+static void bluecard_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int bluecard_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+int bluecard_open(bluecard_info_t *info)
-+{
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev;
-+ unsigned char id;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ init_timer(&(info->timer));
-+ info->timer.function = &bluecard_activity_led_timeout;
-+ info->timer.data = (u_long)info;
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ info->rx_skb = NULL;
-+
-+ id = inb(iobase + 0x30);
-+
-+ if ((id & 0x0f) == 0x02)
-+ set_bit(CARD_HAS_PCCARD_ID, &(info->hw_state));
-+
-+ if (id & 0x10)
-+ set_bit(CARD_HAS_POWER_LED, &(info->hw_state));
-+
-+ if (id & 0x20)
-+ set_bit(CARD_HAS_ACTIVITY_LED, &(info->hw_state));
-+
-+ /* Reset card */
-+ info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Turn FPGA off */
-+ outb(0x80, iobase + 0x30);
-+
-+ /* Wait some time */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ / 100);
-+
-+ /* Turn FPGA on */
-+ outb(0x00, iobase + 0x30);
-+
-+ /* Activate card */
-+ info->ctrl_reg = REG_CONTROL_BT_ON | REG_CONTROL_BT_RES_PU;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Enable interrupt */
-+ outb(0xff, iobase + REG_INTERRUPT);
-+ info->ctrl_reg |= REG_CONTROL_INTERRUPT;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Start the RX buffers */
-+ outb(REG_COMMAND_RX_BUF_ONE, iobase + REG_COMMAND);
-+ outb(REG_COMMAND_RX_BUF_TWO, iobase + REG_COMMAND);
-+
-+ /* Signal that the hardware is ready */
-+ set_bit(CARD_READY, &(info->hw_state));
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ /* Control the point at which RTS is enabled */
-+ outb((0x0f << RTS_LEVEL_SHIFT_BITS) | 1, iobase + REG_RX_CONTROL);
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout((HZ * 5) / 4); // or set it to 3/2
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = bluecard_hci_open;
-+ hdev->close = bluecard_hci_close;
-+ hdev->flush = bluecard_hci_flush;
-+ hdev->send = bluecard_hci_send_frame;
-+ hdev->destruct = bluecard_hci_destruct;
-+ hdev->ioctl = bluecard_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_WARNING "bluecard_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int bluecard_close(bluecard_info_t *info)
-+{
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ bluecard_hci_close(hdev);
-+
-+ clear_bit(CARD_READY, &(info->hw_state));
-+
-+ /* Reset card */
-+ info->ctrl_reg = REG_CONTROL_BT_RESET | REG_CONTROL_CARD_RESET;
-+ outb(info->ctrl_reg, iobase + REG_CONTROL);
-+
-+ /* Turn FPGA off */
-+ outb(0x80, iobase + 0x30);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_WARNING "bluecard_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+dev_link_t *bluecard_attach(void)
-+{
-+ bluecard_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &bluecard_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = bluecard_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.Vcc = 50;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &bluecard_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ bluecard_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+void bluecard_detach(dev_link_t *link)
-+{
-+ bluecard_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+ if (link->state & DEV_CONFIG)
-+ bluecard_release((u_long)link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+void bluecard_config(dev_link_t *link)
-+{
-+ client_handle_t handle = link->handle;
-+ bluecard_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ config_info_t config;
-+ int i, n, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ link->conf.ConfigIndex = 0x20;
-+ link->io.NumPorts1 = 64;
-+ link->io.IOAddrLines = 6;
-+
-+ for (n = 0; n < 0x400; n += 0x40) {
-+ link->io.BasePort1 = n ^ 0x300;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ break;
-+ }
-+
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (bluecard_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ bluecard_release((u_long)link);
-+}
-+
-+
-+void bluecard_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *)arg;
-+ bluecard_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ bluecard_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+int bluecard_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ bluecard_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ bluecard_close(info);
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ bluecard_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG)
-+ CardServices(ReleaseConfiguration, link->handle);
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (DEV_OK(link))
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_bluecard_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "bluecard_cs: Card Services release does not match!\n");
-+ return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &bluecard_attach, &bluecard_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_bluecard_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ bluecard_detach(dev_list);
-+}
-+
-+
-+module_init(init_bluecard_cs);
-+module_exit(exit_bluecard_cs);
-+
-+EXPORT_NO_SYMBOLS;
-diff -urN linux-2.4.18/drivers/bluetooth/bt3c_cs.c linux-2.4.18-mh9/drivers/bluetooth/bt3c_cs.c
---- linux-2.4.18/drivers/bluetooth/bt3c_cs.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/drivers/bluetooth/bt3c_cs.c Mon Aug 25 18:38:10 2003
-@@ -0,0 +1,946 @@
-+/*
-+ *
-+ * Driver for the 3Com Bluetooth PCMCIA card
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ * Jose Orlando Pereira <jop@di.uminho.pt>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#define __KERNEL_SYSCALLS__
-+
-+#include <linux/kernel.h>
-+#include <linux/kmod.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/delay.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/unistd.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+
-+#include <linux/skbuff.h>
-+#include <linux/string.h>
-+#include <linux/serial.h>
-+#include <linux/serial_reg.h>
-+#include <asm/system.h>
-+#include <asm/bitops.h>
-+#include <asm/io.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0xffff;
-+static int irq_list[4] = { -1 };
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>, Jose Orlando Pereira <jop@di.uminho.pt>");
-+MODULE_DESCRIPTION("BlueZ driver for the 3Com Bluetooth PCMCIA card");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct bt3c_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+} bt3c_info_t;
-+
-+
-+void bt3c_config(dev_link_t *link);
-+void bt3c_release(u_long arg);
-+int bt3c_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "bt3c_cs";
-+
-+dev_link_t *bt3c_attach(void);
-+void bt3c_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_WAITING 8
-+
-+/* Receiver states */
-+#define RECV_WAIT_PACKET_TYPE 0
-+#define RECV_WAIT_EVENT_HEADER 1
-+#define RECV_WAIT_ACL_HEADER 2
-+#define RECV_WAIT_SCO_HEADER 3
-+#define RECV_WAIT_DATA 4
-+
-+
-+
-+/* ======================== Special I/O functions ======================== */
-+
-+
-+#define DATA_L 0
-+#define DATA_H 1
-+#define ADDR_L 2
-+#define ADDR_H 3
-+#define CONTROL 4
-+
-+
-+inline void bt3c_address(unsigned int iobase, unsigned short addr)
-+{
-+ outb(addr & 0xff, iobase + ADDR_L);
-+ outb((addr >> 8) & 0xff, iobase + ADDR_H);
-+}
-+
-+
-+inline void bt3c_put(unsigned int iobase, unsigned short value)
-+{
-+ outb(value & 0xff, iobase + DATA_L);
-+ outb((value >> 8) & 0xff, iobase + DATA_H);
-+}
-+
-+
-+inline void bt3c_io_write(unsigned int iobase, unsigned short addr, unsigned short value)
-+{
-+ bt3c_address(iobase, addr);
-+ bt3c_put(iobase, value);
-+}
-+
-+
-+inline unsigned short bt3c_get(unsigned int iobase)
-+{
-+ unsigned short value = inb(iobase + DATA_L);
-+
-+ value |= inb(iobase + DATA_H) << 8;
-+
-+ return value;
-+}
-+
-+
-+inline unsigned short bt3c_read(unsigned int iobase, unsigned short addr)
-+{
-+ bt3c_address(iobase, addr);
-+
-+ return bt3c_get(iobase);
-+}
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int bt3c_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
-+{
-+ int actual = 0;
-+
-+ bt3c_address(iobase, 0x7080);
-+
-+ /* Fill FIFO with current frame */
-+ while (actual < len) {
-+ /* Transmit next byte */
-+ bt3c_put(iobase, buf[actual]);
-+ actual++;
-+ }
-+
-+ bt3c_io_write(iobase, 0x7005, actual);
-+
-+ return actual;
-+}
-+
-+
-+static void bt3c_write_wakeup(bt3c_info_t *info, int from)
-+{
-+ unsigned long flags;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bt3c_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state)))
-+ return;
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ break;
-+
-+
-+ if (!(skb = skb_dequeue(&(info->txq)))) {
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+ break;
-+ }
-+
-+ /* Send frame */
-+ len = bt3c_write(iobase, 256, skb->data, skb->len);
-+
-+ if (len != skb->len) {
-+ printk(KERN_WARNING "bt3c_cs: very strange\n");
-+ }
-+
-+ kfree_skb(skb);
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ } while (0);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+}
-+
-+
-+static void bt3c_receive(bt3c_info_t *info)
-+{
-+ unsigned int iobase;
-+ int size = 0, avail;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bt3c_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ avail = bt3c_read(iobase, 0x7006);
-+ //printk("bt3c_cs: receiving %d bytes\n", avail);
-+
-+ bt3c_address(iobase, 0x7480);
-+ while (size < avail) {
-+ size++;
-+ info->hdev.stat.byte_rx++;
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL) {
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "bt3c_cs: Can't allocate mem for new packet.\n");
-+ return;
-+ }
-+ }
-+
-+
-+ if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
-+
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type = inb(iobase + DATA_L);
-+ inb(iobase + DATA_H);
-+ //printk("bt3c: PACKET_TYPE=%02x\n", info->rx_skb->pkt_type);
-+
-+ switch (info->rx_skb->pkt_type) {
-+
-+ case HCI_EVENT_PKT:
-+ info->rx_state = RECV_WAIT_EVENT_HEADER;
-+ info->rx_count = HCI_EVENT_HDR_SIZE;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ info->rx_state = RECV_WAIT_ACL_HEADER;
-+ info->rx_count = HCI_ACL_HDR_SIZE;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ info->rx_state = RECV_WAIT_SCO_HEADER;
-+ info->rx_count = HCI_SCO_HDR_SIZE;
-+ break;
-+
-+ default:
-+ /* Unknown packet */
-+ printk(KERN_WARNING "bt3c_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-+ info->hdev.stat.err_rx++;
-+ clear_bit(HCI_RUNNING, &(info->hdev.flags));
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ } else {
-+
-+ __u8 x = inb(iobase + DATA_L);
-+
-+ *skb_put(info->rx_skb, 1) = x;
-+ inb(iobase + DATA_H);
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ int dlen;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+
-+ switch (info->rx_state) {
-+
-+ case RECV_WAIT_EVENT_HEADER:
-+ eh = (hci_event_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = eh->plen;
-+ break;
-+
-+ case RECV_WAIT_ACL_HEADER:
-+ ah = (hci_acl_hdr *)(info->rx_skb->data);
-+ dlen = __le16_to_cpu(ah->dlen);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = dlen;
-+ break;
-+
-+ case RECV_WAIT_SCO_HEADER:
-+ sh = (hci_sco_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = sh->dlen;
-+ break;
-+
-+ case RECV_WAIT_DATA:
-+ hci_recv_frame(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+ bt3c_io_write(iobase, 0x7006, 0x0000);
-+}
-+
-+
-+void bt3c_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ bt3c_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ int iir;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "bt3c_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ iir = inb(iobase + CONTROL);
-+ if (iir & 0x80) {
-+ int stat = bt3c_read(iobase, 0x7001);
-+
-+ if ((stat & 0xff) == 0x7f) {
-+ printk(KERN_WARNING "bt3c_cs: STRANGE stat=%04x\n", stat);
-+ } else if ((stat & 0xff) != 0xff) {
-+ if (stat & 0x0020) {
-+ int stat = bt3c_read(iobase, 0x7002) & 0x10;
-+ printk(KERN_WARNING "bt3c_cs: antena %s\n", stat ? "OUT" : "IN");
-+ }
-+ if (stat & 0x0001)
-+ bt3c_receive(info);
-+ if (stat & 0x0002) {
-+ //printk("bt3c_cs: ACK %04x\n", stat);
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+ bt3c_write_wakeup(info, 1);
-+ }
-+
-+ bt3c_io_write(iobase, 0x7001, 0x0000);
-+
-+ outb(iir, iobase + CONTROL);
-+ }
-+ }
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int bt3c_hci_flush(struct hci_dev *hdev)
-+{
-+ bt3c_info_t *info = (bt3c_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int bt3c_hci_open(struct hci_dev *hdev)
-+{
-+ set_bit(HCI_RUNNING, &(hdev->flags));
-+
-+ return 0;
-+}
-+
-+
-+static int bt3c_hci_close(struct hci_dev *hdev)
-+{
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ bt3c_hci_flush(hdev);
-+
-+ return 0;
-+}
-+
-+
-+static int bt3c_hci_send_frame(struct sk_buff *skb)
-+{
-+ bt3c_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+
-+ if (!hdev) {
-+ printk(KERN_WARNING "bt3c_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (bt3c_info_t *) (hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ bt3c_write_wakeup(info, 0);
-+
-+ return 0;
-+}
-+
-+
-+static void bt3c_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int bt3c_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== User mode firmware loader ======================== */
-+
-+
-+#define FW_LOADER "/sbin/bluefw"
-+static int errno;
-+
-+
-+static int bt3c_fw_loader_exec(void *dev)
-+{
-+ char *argv[] = { FW_LOADER, "pccard", dev, NULL };
-+ char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
-+ int err;
-+
-+ err = exec_usermodehelper(FW_LOADER, argv, envp);
-+ if (err)
-+ printk(KERN_WARNING "bt3c_cs: Failed to exec \"%s pccard %s\".\n", FW_LOADER, (char *)dev);
-+
-+ return err;
-+}
-+
-+
-+static int bt3c_firmware_load(bt3c_info_t *info)
-+{
-+ sigset_t tmpsig;
-+ char dev[16];
-+ pid_t pid;
-+ int result;
-+
-+ /* Check if root fs is mounted */
-+ if (!current->fs->root) {
-+ printk(KERN_WARNING "bt3c_cs: Root filesystem is not mounted.\n");
-+ return -EPERM;
-+ }
-+
-+ sprintf(dev, "%04x", info->link.io.BasePort1);
-+
-+ pid = kernel_thread(bt3c_fw_loader_exec, (void *)dev, 0);
-+ if (pid < 0) {
-+ printk(KERN_WARNING "bt3c_cs: Forking of kernel thread failed (errno=%d).\n", -pid);
-+ return pid;
-+ }
-+
-+ /* Block signals, everything but SIGKILL/SIGSTOP */
-+ spin_lock_irq(&current->sigmask_lock);
-+ tmpsig = current->blocked;
-+ siginitsetinv(&current->blocked, sigmask(SIGKILL) | sigmask(SIGSTOP));
-+ recalc_sigpending(current);
-+ spin_unlock_irq(&current->sigmask_lock);
-+
-+ result = waitpid(pid, NULL, __WCLONE);
-+
-+ /* Allow signals again */
-+ spin_lock_irq(&current->sigmask_lock);
-+ current->blocked = tmpsig;
-+ recalc_sigpending(current);
-+ spin_unlock_irq(&current->sigmask_lock);
-+
-+ if (result != pid) {
-+ printk(KERN_WARNING "bt3c_cs: Waiting for pid %d failed (errno=%d).\n", pid, -result);
-+ return -result;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+int bt3c_open(bt3c_info_t *info)
-+{
-+ struct hci_dev *hdev;
-+ int err;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ info->rx_skb = NULL;
-+
-+ /* Load firmware */
-+
-+ if ((err = bt3c_firmware_load(info)) < 0)
-+ return err;
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ);
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = bt3c_hci_open;
-+ hdev->close = bt3c_hci_close;
-+ hdev->flush = bt3c_hci_flush;
-+ hdev->send = bt3c_hci_send_frame;
-+ hdev->destruct = bt3c_hci_destruct;
-+ hdev->ioctl = bt3c_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_WARNING "bt3c_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int bt3c_close(bt3c_info_t *info)
-+{
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ bt3c_hci_close(hdev);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_WARNING "bt3c_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+dev_link_t *bt3c_attach(void)
-+{
-+ bt3c_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &bt3c_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = bt3c_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.Vcc = 50;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &bt3c_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ bt3c_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+void bt3c_detach(dev_link_t *link)
-+{
-+ bt3c_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+
-+ if (link->state & DEV_CONFIG)
-+ bt3c_release((u_long)link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+void bt3c_config(dev_link_t *link)
-+{
-+ static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
-+ client_handle_t handle = link->handle;
-+ bt3c_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
-+ int i, j, try, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ /* First pass: look for a config entry that looks normal. */
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-+ /* Two tries: without IO aliases, then with aliases */
-+ for (try = 0; try < 2; try++) {
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if (i != CS_SUCCESS)
-+ goto next_entry;
-+ if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
-+ link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-+ if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
-+ link->conf.ConfigIndex = cf->index;
-+ link->io.BasePort1 = cf->io.win[0].base;
-+ link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+next_entry:
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+ }
-+
-+ /* Second pass: try to find an entry that isn't picky about
-+ its base address, then try to grab any standard serial port
-+ address, and finally try to get any free port. */
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if ((i == CS_SUCCESS) && (cf->io.nwin > 0) && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
-+ link->conf.ConfigIndex = cf->index;
-+ for (j = 0; j < 5; j++) {
-+ link->io.BasePort1 = base[j];
-+ link->io.IOAddrLines = base[j] ? 16 : 3;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+ }
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+
-+found_port:
-+ if (i != CS_SUCCESS) {
-+ printk(KERN_NOTICE "bt3c_cs: No usable port range found. Giving up.\n");
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (bt3c_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ bt3c_release((u_long)link);
-+}
-+
-+
-+void bt3c_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *)arg;
-+ bt3c_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ bt3c_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+int bt3c_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ bt3c_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ bt3c_close(info);
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ bt3c_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG)
-+ CardServices(ReleaseConfiguration, link->handle);
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (DEV_OK(link))
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_bt3c_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "bt3c_cs: Card Services release does not match!\n");
-+ return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &bt3c_attach, &bt3c_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_bt3c_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ bt3c_detach(dev_list);
-+}
-+
-+
-+module_init(init_bt3c_cs);
-+module_exit(exit_bt3c_cs);
-+
-+EXPORT_NO_SYMBOLS;
-diff -urN linux-2.4.18/drivers/bluetooth/btuart_cs.c linux-2.4.18-mh9/drivers/bluetooth/btuart_cs.c
---- linux-2.4.18/drivers/bluetooth/btuart_cs.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/drivers/bluetooth/btuart_cs.c Mon Aug 25 18:38:10 2003
-@@ -0,0 +1,906 @@
-+/*
-+ *
-+ * Driver for Bluetooth PCMCIA cards with HCI UART interface
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+
-+#include <linux/skbuff.h>
-+#include <linux/string.h>
-+#include <linux/serial.h>
-+#include <linux/serial_reg.h>
-+#include <asm/system.h>
-+#include <asm/bitops.h>
-+#include <asm/io.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0xffff;
-+static int irq_list[4] = { -1 };
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ driver for Bluetooth PCMCIA cards with HCI UART interface");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct btuart_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+} btuart_info_t;
-+
-+
-+void btuart_config(dev_link_t *link);
-+void btuart_release(u_long arg);
-+int btuart_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "btuart_cs";
-+
-+dev_link_t *btuart_attach(void);
-+void btuart_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+
-+/* Maximum baud rate */
-+#define SPEED_MAX 115200
-+
-+/* Default baud rate: 57600, 115200, 230400 or 460800 */
-+#define DEFAULT_BAUD_RATE 115200
-+
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_WAITING 8
-+
-+/* Receiver states */
-+#define RECV_WAIT_PACKET_TYPE 0
-+#define RECV_WAIT_EVENT_HEADER 1
-+#define RECV_WAIT_ACL_HEADER 2
-+#define RECV_WAIT_SCO_HEADER 3
-+#define RECV_WAIT_DATA 4
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int btuart_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
-+{
-+ int actual = 0;
-+
-+ /* Tx FIFO should be empty */
-+ if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
-+ return 0;
-+
-+ /* Fill FIFO with current frame */
-+ while ((fifo_size-- > 0) && (actual < len)) {
-+ /* Transmit next byte */
-+ outb(buf[actual], iobase + UART_TX);
-+ actual++;
-+ }
-+
-+ return actual;
-+}
-+
-+
-+static void btuart_write_wakeup(btuart_info_t *info)
-+{
-+ if (!info) {
-+ printk(KERN_WARNING "btuart_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ clear_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ return;
-+
-+ if (!(skb = skb_dequeue(&(info->txq))))
-+ break;
-+
-+ /* Send frame */
-+ len = btuart_write(iobase, 16, skb->data, skb->len);
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (len == skb->len) {
-+ kfree_skb(skb);
-+ } else {
-+ skb_pull(skb, len);
-+ skb_queue_head(&(info->txq), skb);
-+ }
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
-+
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+}
-+
-+
-+static void btuart_receive(btuart_info_t *info)
-+{
-+ unsigned int iobase;
-+ int boguscount = 0;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "btuart_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ do {
-+ info->hdev.stat.byte_rx++;
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL) {
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "btuart_cs: Can't allocate mem for new packet.\n");
-+ return;
-+ }
-+ }
-+
-+ if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
-+
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type = inb(iobase + UART_RX);
-+
-+ switch (info->rx_skb->pkt_type) {
-+
-+ case HCI_EVENT_PKT:
-+ info->rx_state = RECV_WAIT_EVENT_HEADER;
-+ info->rx_count = HCI_EVENT_HDR_SIZE;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ info->rx_state = RECV_WAIT_ACL_HEADER;
-+ info->rx_count = HCI_ACL_HDR_SIZE;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ info->rx_state = RECV_WAIT_SCO_HEADER;
-+ info->rx_count = HCI_SCO_HDR_SIZE;
-+ break;
-+
-+ default:
-+ /* Unknown packet */
-+ printk(KERN_WARNING "btuart_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-+ info->hdev.stat.err_rx++;
-+ clear_bit(HCI_RUNNING, &(info->hdev.flags));
-+
-+ kfree_skb(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ } else {
-+
-+ *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ int dlen;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+
-+
-+ switch (info->rx_state) {
-+
-+ case RECV_WAIT_EVENT_HEADER:
-+ eh = (hci_event_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = eh->plen;
-+ break;
-+
-+ case RECV_WAIT_ACL_HEADER:
-+ ah = (hci_acl_hdr *)(info->rx_skb->data);
-+ dlen = __le16_to_cpu(ah->dlen);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = dlen;
-+ break;
-+
-+ case RECV_WAIT_SCO_HEADER:
-+ sh = (hci_sco_hdr *)(info->rx_skb->data);
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = sh->dlen;
-+ break;
-+
-+ case RECV_WAIT_DATA:
-+ hci_recv_frame(info->rx_skb);
-+ info->rx_skb = NULL;
-+ break;
-+
-+ }
-+
-+ }
-+
-+ }
-+
-+ /* Make sure we don't stay here to long */
-+ if (boguscount++ > 16)
-+ break;
-+
-+ } while (inb(iobase + UART_LSR) & UART_LSR_DR);
-+}
-+
-+
-+void btuart_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ btuart_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ int boguscount = 0;
-+ int iir, lsr;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "btuart_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-+ while (iir) {
-+
-+ /* Clear interrupt */
-+ lsr = inb(iobase + UART_LSR);
-+
-+ switch (iir) {
-+ case UART_IIR_RLSI:
-+ printk(KERN_NOTICE "btuart_cs: RLSI\n");
-+ break;
-+ case UART_IIR_RDI:
-+ /* Receive interrupt */
-+ btuart_receive(info);
-+ break;
-+ case UART_IIR_THRI:
-+ if (lsr & UART_LSR_THRE) {
-+ /* Transmitter ready for data */
-+ btuart_write_wakeup(info);
-+ }
-+ break;
-+ default:
-+ printk(KERN_NOTICE "btuart_cs: Unhandled IIR=%#x\n", iir);
-+ break;
-+ }
-+
-+ /* Make sure we don't stay here to long */
-+ if (boguscount++ > 100)
-+ break;
-+
-+ iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-+
-+ }
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+
-+static void btuart_change_speed(btuart_info_t *info, unsigned int speed)
-+{
-+ unsigned long flags;
-+ unsigned int iobase;
-+ int fcr; /* FIFO control reg */
-+ int lcr; /* Line control reg */
-+ int divisor;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "btuart_cs: Call of change speed for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ divisor = SPEED_MAX / speed;
-+
-+ fcr = UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT;
-+
-+ /*
-+ * Use trigger level 1 to avoid 3 ms. timeout delay at 9600 bps, and
-+ * almost 1,7 ms at 19200 bps. At speeds above that we can just forget
-+ * about this timeout since it will always be fast enough.
-+ */
-+
-+ if (speed < 38400)
-+ fcr |= UART_FCR_TRIGGER_1;
-+ else
-+ fcr |= UART_FCR_TRIGGER_14;
-+
-+ /* Bluetooth cards use 8N1 */
-+ lcr = UART_LCR_WLEN8;
-+
-+ outb(UART_LCR_DLAB | lcr, iobase + UART_LCR); /* Set DLAB */
-+ outb(divisor & 0xff, iobase + UART_DLL); /* Set speed */
-+ outb(divisor >> 8, iobase + UART_DLM);
-+ outb(lcr, iobase + UART_LCR); /* Set 8N1 */
-+ outb(fcr, iobase + UART_FCR); /* Enable FIFO's */
-+
-+ /* Turn on interrups */
-+ outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+}
-+
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int btuart_hci_flush(struct hci_dev *hdev)
-+{
-+ btuart_info_t *info = (btuart_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int btuart_hci_open(struct hci_dev *hdev)
-+{
-+ set_bit(HCI_RUNNING, &(hdev->flags));
-+
-+ return 0;
-+}
-+
-+
-+static int btuart_hci_close(struct hci_dev *hdev)
-+{
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ btuart_hci_flush(hdev);
-+
-+ return 0;
-+}
-+
-+
-+static int btuart_hci_send_frame(struct sk_buff *skb)
-+{
-+ btuart_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+
-+ if (!hdev) {
-+ printk(KERN_WARNING "btuart_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (btuart_info_t *)(hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+ };
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
-+ skb_queue_tail(&(info->txq), skb);
-+
-+ btuart_write_wakeup(info);
-+
-+ return 0;
-+}
-+
-+
-+static void btuart_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int btuart_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+int btuart_open(btuart_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_PACKET_TYPE;
-+ info->rx_count = 0;
-+ info->rx_skb = NULL;
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Reset UART */
-+ outb(0, iobase + UART_MCR);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ /* Initialize UART */
-+ outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
-+ outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
-+
-+ /* Turn on interrupts */
-+ // outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ btuart_change_speed(info, DEFAULT_BAUD_RATE);
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ);
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = btuart_hci_open;
-+ hdev->close = btuart_hci_close;
-+ hdev->flush = btuart_hci_flush;
-+ hdev->send = btuart_hci_send_frame;
-+ hdev->destruct = btuart_hci_destruct;
-+ hdev->ioctl = btuart_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_WARNING "btuart_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int btuart_close(btuart_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ btuart_hci_close(hdev);
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Reset UART */
-+ outb(0, iobase + UART_MCR);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_WARNING "btuart_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+dev_link_t *btuart_attach(void)
-+{
-+ btuart_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &btuart_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = btuart_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.Vcc = 50;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &btuart_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ btuart_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+void btuart_detach(dev_link_t *link)
-+{
-+ btuart_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+ if (link->state & DEV_CONFIG)
-+ btuart_release((u_long)link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+void btuart_config(dev_link_t *link)
-+{
-+ static ioaddr_t base[5] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
-+ client_handle_t handle = link->handle;
-+ btuart_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
-+ int i, j, try, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ /* First pass: look for a config entry that looks normal. */
-+ tuple.TupleData = (cisdata_t *) buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-+ /* Two tries: without IO aliases, then with aliases */
-+ for (try = 0; try < 2; try++) {
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if (i != CS_SUCCESS)
-+ goto next_entry;
-+ if (cf->vpp1.present & (1 << CISTPL_POWER_VNOM))
-+ link->conf.Vpp1 = link->conf.Vpp2 = cf->vpp1.param[CISTPL_POWER_VNOM] / 10000;
-+ if ((cf->io.nwin > 0) && (cf->io.win[0].len == 8) && (cf->io.win[0].base != 0)) {
-+ link->conf.ConfigIndex = cf->index;
-+ link->io.BasePort1 = cf->io.win[0].base;
-+ link->io.IOAddrLines = (try == 0) ? 16 : cf->io.flags & CISTPL_IO_LINES_MASK;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+next_entry:
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+ }
-+
-+ /* Second pass: try to find an entry that isn't picky about
-+ its base address, then try to grab any standard serial port
-+ address, and finally try to get any free port. */
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if ((i == CS_SUCCESS) && (cf->io.nwin > 0)
-+ && ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {
-+ link->conf.ConfigIndex = cf->index;
-+ for (j = 0; j < 5; j++) {
-+ link->io.BasePort1 = base[j];
-+ link->io.IOAddrLines = base[j] ? 16 : 3;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ goto found_port;
-+ }
-+ }
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+
-+found_port:
-+ if (i != CS_SUCCESS) {
-+ printk(KERN_NOTICE "btuart_cs: No usable port range found. Giving up.\n");
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (btuart_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ btuart_release((u_long) link);
-+}
-+
-+
-+void btuart_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *)arg;
-+ btuart_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ btuart_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+int btuart_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ btuart_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ btuart_close(info);
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ btuart_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG)
-+ CardServices(ReleaseConfiguration, link->handle);
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (DEV_OK(link))
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_btuart_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "btuart_cs: Card Services release does not match!\n");
-+ return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &btuart_attach, &btuart_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_btuart_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ btuart_detach(dev_list);
-+}
-+
-+
-+module_init(init_btuart_cs);
-+module_exit(exit_btuart_cs);
-+
-+EXPORT_NO_SYMBOLS;
-diff -urN linux-2.4.18/drivers/bluetooth/dtl1_cs.c linux-2.4.18-mh9/drivers/bluetooth/dtl1_cs.c
---- linux-2.4.18/drivers/bluetooth/dtl1_cs.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/drivers/bluetooth/dtl1_cs.c Mon Aug 25 18:38:10 2003
-@@ -0,0 +1,858 @@
-+/*
-+ *
-+ * A driver for Nokia Connectivity Card DTL-1 devices
-+ *
-+ * Copyright (C) 2001-2002 Marcel Holtmann <marcel@holtmann.org>
-+ *
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation;
-+ *
-+ * Software distributed under the License is distributed on an "AS
-+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-+ * implied. See the License for the specific language governing
-+ * rights and limitations under the License.
-+ *
-+ * The initial developer of the original code is David A. Hinds
-+ * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
-+ * are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
-+ *
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/types.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/errno.h>
-+#include <linux/ptrace.h>
-+#include <linux/ioport.h>
-+#include <linux/spinlock.h>
-+
-+#include <linux/skbuff.h>
-+#include <linux/string.h>
-+#include <linux/serial.h>
-+#include <linux/serial_reg.h>
-+#include <asm/system.h>
-+#include <asm/bitops.h>
-+#include <asm/io.h>
-+
-+#include <pcmcia/version.h>
-+#include <pcmcia/cs_types.h>
-+#include <pcmcia/cs.h>
-+#include <pcmcia/cistpl.h>
-+#include <pcmcia/ciscode.h>
-+#include <pcmcia/ds.h>
-+#include <pcmcia/cisreg.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+
-+
-+/* ======================== Module parameters ======================== */
-+
-+
-+/* Bit map of interrupts to choose from */
-+static u_int irq_mask = 0xffff;
-+static int irq_list[4] = { -1 };
-+
-+MODULE_PARM(irq_mask, "i");
-+MODULE_PARM(irq_list, "1-4i");
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ driver for Nokia Connectivity Card DTL-1");
-+MODULE_LICENSE("GPL");
-+
-+
-+
-+/* ======================== Local structures ======================== */
-+
-+
-+typedef struct dtl1_info_t {
-+ dev_link_t link;
-+ dev_node_t node;
-+
-+ struct hci_dev hdev;
-+
-+ spinlock_t lock; /* For serializing operations */
-+
-+ unsigned long flowmask; /* HCI flow mask */
-+ int ri_latch;
-+
-+ struct sk_buff_head txq;
-+ unsigned long tx_state;
-+
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+} dtl1_info_t;
-+
-+
-+void dtl1_config(dev_link_t *link);
-+void dtl1_release(u_long arg);
-+int dtl1_event(event_t event, int priority, event_callback_args_t *args);
-+
-+static dev_info_t dev_info = "dtl1_cs";
-+
-+dev_link_t *dtl1_attach(void);
-+void dtl1_detach(dev_link_t *);
-+
-+static dev_link_t *dev_list = NULL;
-+
-+
-+/* Transmit states */
-+#define XMIT_SENDING 1
-+#define XMIT_WAKEUP 2
-+#define XMIT_WAITING 8
-+
-+/* Receiver States */
-+#define RECV_WAIT_NSH 0
-+#define RECV_WAIT_DATA 1
-+
-+
-+typedef struct {
-+ u8 type;
-+ u8 zero;
-+ u16 len;
-+} __attribute__ ((packed)) nsh_t; /* Nokia Specific Header */
-+
-+#define NSHL 4 /* Nokia Specific Header Length */
-+
-+
-+
-+/* ======================== Interrupt handling ======================== */
-+
-+
-+static int dtl1_write(unsigned int iobase, int fifo_size, __u8 *buf, int len)
-+{
-+ int actual = 0;
-+
-+ /* Tx FIFO should be empty */
-+ if (!(inb(iobase + UART_LSR) & UART_LSR_THRE))
-+ return 0;
-+
-+ /* Fill FIFO with current frame */
-+ while ((fifo_size-- > 0) && (actual < len)) {
-+ /* Transmit next byte */
-+ outb(buf[actual], iobase + UART_TX);
-+ actual++;
-+ }
-+
-+ return actual;
-+}
-+
-+
-+static void dtl1_write_wakeup(dtl1_info_t *info)
-+{
-+ if (!info) {
-+ printk(KERN_WARNING "dtl1_cs: Call of write_wakeup for unknown device.\n");
-+ return;
-+ }
-+
-+ if (test_bit(XMIT_WAITING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ if (test_and_set_bit(XMIT_SENDING, &(info->tx_state))) {
-+ set_bit(XMIT_WAKEUP, &(info->tx_state));
-+ return;
-+ }
-+
-+ do {
-+ register unsigned int iobase = info->link.io.BasePort1;
-+ register struct sk_buff *skb;
-+ register int len;
-+
-+ clear_bit(XMIT_WAKEUP, &(info->tx_state));
-+
-+ if (!(info->link.state & DEV_PRESENT))
-+ return;
-+
-+ if (!(skb = skb_dequeue(&(info->txq))))
-+ break;
-+
-+ /* Send frame */
-+ len = dtl1_write(iobase, 32, skb->data, skb->len);
-+
-+ if (len == skb->len) {
-+ set_bit(XMIT_WAITING, &(info->tx_state));
-+ kfree_skb(skb);
-+ } else {
-+ skb_pull(skb, len);
-+ skb_queue_head(&(info->txq), skb);
-+ }
-+
-+ info->hdev.stat.byte_tx += len;
-+
-+ } while (test_bit(XMIT_WAKEUP, &(info->tx_state)));
-+
-+ clear_bit(XMIT_SENDING, &(info->tx_state));
-+}
-+
-+
-+static void dtl1_control(dtl1_info_t *info, struct sk_buff *skb)
-+{
-+ u8 flowmask = *(u8 *)skb->data;
-+ int i;
-+
-+ printk(KERN_INFO "dtl1_cs: Nokia control data = ");
-+ for (i = 0; i < skb->len; i++) {
-+ printk("%02x ", skb->data[i]);
-+ }
-+ printk("\n");
-+
-+ /* transition to active state */
-+ if (((info->flowmask & 0x07) == 0) && ((flowmask & 0x07) != 0)) {
-+ clear_bit(XMIT_WAITING, &(info->tx_state));
-+ dtl1_write_wakeup(info);
-+ }
-+
-+ info->flowmask = flowmask;
-+
-+ kfree_skb(skb);
-+}
-+
-+
-+static void dtl1_receive(dtl1_info_t *info)
-+{
-+ unsigned int iobase;
-+ nsh_t *nsh;
-+ int boguscount = 0;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "dtl1_cs: Call of receive for unknown device.\n");
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ do {
-+ info->hdev.stat.byte_rx++;
-+
-+ /* Allocate packet */
-+ if (info->rx_skb == NULL)
-+ if (!(info->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-+ printk(KERN_WARNING "dtl1_cs: Can't allocate mem for new packet.\n");
-+ info->rx_state = RECV_WAIT_NSH;
-+ info->rx_count = NSHL;
-+ return;
-+ }
-+
-+ *skb_put(info->rx_skb, 1) = inb(iobase + UART_RX);
-+ nsh = (nsh_t *)info->rx_skb->data;
-+
-+ info->rx_count--;
-+
-+ if (info->rx_count == 0) {
-+
-+ switch (info->rx_state) {
-+ case RECV_WAIT_NSH:
-+ info->rx_state = RECV_WAIT_DATA;
-+ info->rx_count = nsh->len + (nsh->len & 0x0001);
-+ break;
-+ case RECV_WAIT_DATA:
-+ info->rx_skb->pkt_type = nsh->type;
-+
-+ /* remove PAD byte if it exists */
-+ if (nsh->len & 0x0001) {
-+ info->rx_skb->tail--;
-+ info->rx_skb->len--;
-+ }
-+
-+ /* remove NSH */
-+ skb_pull(info->rx_skb, NSHL);
-+
-+ switch (info->rx_skb->pkt_type) {
-+ case 0x80:
-+ /* control data for the Nokia Card */
-+ dtl1_control(info, info->rx_skb);
-+ break;
-+ case 0x82:
-+ case 0x83:
-+ case 0x84:
-+ /* send frame to the HCI layer */
-+ info->rx_skb->dev = (void *)&(info->hdev);
-+ info->rx_skb->pkt_type &= 0x0f;
-+ hci_recv_frame(info->rx_skb);
-+ break;
-+ default:
-+ /* unknown packet */
-+ printk(KERN_WARNING "dtl1_cs: Unknown HCI packet with type 0x%02x received.\n", info->rx_skb->pkt_type);
-+ kfree_skb(info->rx_skb);
-+ break;
-+ }
-+
-+ info->rx_state = RECV_WAIT_NSH;
-+ info->rx_count = NSHL;
-+ info->rx_skb = NULL;
-+ break;
-+ }
-+
-+ }
-+
-+ /* Make sure we don't stay here to long */
-+ if (boguscount++ > 32)
-+ break;
-+
-+ } while (inb(iobase + UART_LSR) & UART_LSR_DR);
-+}
-+
-+
-+void dtl1_interrupt(int irq, void *dev_inst, struct pt_regs *regs)
-+{
-+ dtl1_info_t *info = dev_inst;
-+ unsigned int iobase;
-+ unsigned char msr;
-+ int boguscount = 0;
-+ int iir, lsr;
-+
-+ if (!info) {
-+ printk(KERN_WARNING "dtl1_cs: Call of irq %d for unknown device.\n", irq);
-+ return;
-+ }
-+
-+ iobase = info->link.io.BasePort1;
-+
-+ spin_lock(&(info->lock));
-+
-+ iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-+ while (iir) {
-+
-+ /* Clear interrupt */
-+ lsr = inb(iobase + UART_LSR);
-+
-+ switch (iir) {
-+ case UART_IIR_RLSI:
-+ printk(KERN_NOTICE "dtl1_cs: RLSI\n");
-+ break;
-+ case UART_IIR_RDI:
-+ /* Receive interrupt */
-+ dtl1_receive(info);
-+ break;
-+ case UART_IIR_THRI:
-+ if (lsr & UART_LSR_THRE) {
-+ /* Transmitter ready for data */
-+ dtl1_write_wakeup(info);
-+ }
-+ break;
-+ default:
-+ printk(KERN_NOTICE "dtl1_cs: Unhandled IIR=%#x\n", iir);
-+ break;
-+ }
-+
-+ /* Make sure we don't stay here to long */
-+ if (boguscount++ > 100)
-+ break;
-+
-+ iir = inb(iobase + UART_IIR) & UART_IIR_ID;
-+
-+ }
-+
-+ msr = inb(iobase + UART_MSR);
-+
-+ if (info->ri_latch ^ (msr & UART_MSR_RI)) {
-+ info->ri_latch = msr & UART_MSR_RI;
-+ clear_bit(XMIT_WAITING, &(info->tx_state));
-+ dtl1_write_wakeup(info);
-+ }
-+
-+ spin_unlock(&(info->lock));
-+}
-+
-+
-+
-+/* ======================== HCI interface ======================== */
-+
-+
-+static int dtl1_hci_open(struct hci_dev *hdev)
-+{
-+ set_bit(HCI_RUNNING, &(hdev->flags));
-+
-+ return 0;
-+}
-+
-+
-+static int dtl1_hci_flush(struct hci_dev *hdev)
-+{
-+ dtl1_info_t *info = (dtl1_info_t *)(hdev->driver_data);
-+
-+ /* Drop TX queue */
-+ skb_queue_purge(&(info->txq));
-+
-+ return 0;
-+}
-+
-+
-+static int dtl1_hci_close(struct hci_dev *hdev)
-+{
-+ if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags)))
-+ return 0;
-+
-+ dtl1_hci_flush(hdev);
-+
-+ return 0;
-+}
-+
-+
-+static int dtl1_hci_send_frame(struct sk_buff *skb)
-+{
-+ dtl1_info_t *info;
-+ struct hci_dev *hdev = (struct hci_dev *)(skb->dev);
-+ struct sk_buff *s;
-+ nsh_t nsh;
-+
-+ if (!hdev) {
-+ printk(KERN_WARNING "dtl1_cs: Frame for unknown HCI device (hdev=NULL).");
-+ return -ENODEV;
-+ }
-+
-+ info = (dtl1_info_t *)(hdev->driver_data);
-+
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ nsh.type = 0x81;
-+ break;
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ nsh.type = 0x82;
-+ break;
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ nsh.type = 0x83;
-+ break;
-+ };
-+
-+ nsh.zero = 0;
-+ nsh.len = skb->len;
-+
-+ s = bluez_skb_alloc(NSHL + skb->len + 1, GFP_ATOMIC);
-+ skb_reserve(s, NSHL);
-+ memcpy(skb_put(s, skb->len), skb->data, skb->len);
-+ if (skb->len & 0x0001)
-+ *skb_put(s, 1) = 0; /* PAD */
-+
-+ /* Prepend skb with Nokia frame header and queue */
-+ memcpy(skb_push(s, NSHL), &nsh, NSHL);
-+ skb_queue_tail(&(info->txq), s);
-+
-+ dtl1_write_wakeup(info);
-+
-+ kfree_skb(skb);
-+
-+ return 0;
-+}
-+
-+
-+static void dtl1_hci_destruct(struct hci_dev *hdev)
-+{
-+}
-+
-+
-+static int dtl1_hci_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-+{
-+ return -ENOIOCTLCMD;
-+}
-+
-+
-+
-+/* ======================== Card services HCI interaction ======================== */
-+
-+
-+int dtl1_open(dtl1_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev;
-+
-+ spin_lock_init(&(info->lock));
-+
-+ skb_queue_head_init(&(info->txq));
-+
-+ info->rx_state = RECV_WAIT_NSH;
-+ info->rx_count = NSHL;
-+ info->rx_skb = NULL;
-+
-+ set_bit(XMIT_WAITING, &(info->tx_state));
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Reset UART */
-+ outb(0, iobase + UART_MCR);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ /* Initialize UART */
-+ outb(UART_LCR_WLEN8, iobase + UART_LCR); /* Reset DLAB */
-+ outb((UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2), iobase + UART_MCR);
-+
-+ info->ri_latch = inb(info->link.io.BasePort1 + UART_MSR) & UART_MSR_RI;
-+
-+ /* Turn on interrupts */
-+ outb(UART_IER_RLSI | UART_IER_RDI | UART_IER_THRI, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ /* Timeout before it is safe to send the first HCI packet */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule_timeout(HZ * 2);
-+
-+
-+ /* Initialize and register HCI device */
-+
-+ hdev = &(info->hdev);
-+
-+ hdev->type = HCI_PCCARD;
-+ hdev->driver_data = info;
-+
-+ hdev->open = dtl1_hci_open;
-+ hdev->close = dtl1_hci_close;
-+ hdev->flush = dtl1_hci_flush;
-+ hdev->send = dtl1_hci_send_frame;
-+ hdev->destruct = dtl1_hci_destruct;
-+ hdev->ioctl = dtl1_hci_ioctl;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ printk(KERN_WARNING "dtl1_cs: Can't register HCI device %s.\n", hdev->name);
-+ return -ENODEV;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+int dtl1_close(dtl1_info_t *info)
-+{
-+ unsigned long flags;
-+ unsigned int iobase = info->link.io.BasePort1;
-+ struct hci_dev *hdev = &(info->hdev);
-+
-+ dtl1_hci_close(hdev);
-+
-+ spin_lock_irqsave(&(info->lock), flags);
-+
-+ /* Reset UART */
-+ outb(0, iobase + UART_MCR);
-+
-+ /* Turn off interrupts */
-+ outb(0, iobase + UART_IER);
-+
-+ spin_unlock_irqrestore(&(info->lock), flags);
-+
-+ if (hci_unregister_dev(hdev) < 0)
-+ printk(KERN_WARNING "dtl1_cs: Can't unregister HCI device %s.\n", hdev->name);
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Card services ======================== */
-+
-+
-+static void cs_error(client_handle_t handle, int func, int ret)
-+{
-+ error_info_t err = { func, ret };
-+
-+ CardServices(ReportError, handle, &err);
-+}
-+
-+
-+dev_link_t *dtl1_attach(void)
-+{
-+ dtl1_info_t *info;
-+ client_reg_t client_reg;
-+ dev_link_t *link;
-+ int i, ret;
-+
-+ /* Create new info device */
-+ info = kmalloc(sizeof(*info), GFP_KERNEL);
-+ if (!info)
-+ return NULL;
-+ memset(info, 0, sizeof(*info));
-+
-+ link = &info->link;
-+ link->priv = info;
-+
-+ link->release.function = &dtl1_release;
-+ link->release.data = (u_long)link;
-+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-+ link->io.NumPorts1 = 8;
-+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
-+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
-+
-+ if (irq_list[0] == -1)
-+ link->irq.IRQInfo2 = irq_mask;
-+ else
-+ for (i = 0; i < 4; i++)
-+ link->irq.IRQInfo2 |= 1 << irq_list[i];
-+
-+ link->irq.Handler = dtl1_interrupt;
-+ link->irq.Instance = info;
-+
-+ link->conf.Attributes = CONF_ENABLE_IRQ;
-+ link->conf.Vcc = 50;
-+ link->conf.IntType = INT_MEMORY_AND_IO;
-+
-+ /* Register with Card Services */
-+ link->next = dev_list;
-+ dev_list = link;
-+ client_reg.dev_info = &dev_info;
-+ client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
-+ client_reg.EventMask =
-+ CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
-+ CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
-+ CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
-+ client_reg.event_handler = &dtl1_event;
-+ client_reg.Version = 0x0210;
-+ client_reg.event_callback_args.client_data = link;
-+
-+ ret = CardServices(RegisterClient, &link->handle, &client_reg);
-+ if (ret != CS_SUCCESS) {
-+ cs_error(link->handle, RegisterClient, ret);
-+ dtl1_detach(link);
-+ return NULL;
-+ }
-+
-+ return link;
-+}
-+
-+
-+void dtl1_detach(dev_link_t *link)
-+{
-+ dtl1_info_t *info = link->priv;
-+ dev_link_t **linkp;
-+ int ret;
-+
-+ /* Locate device structure */
-+ for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
-+ if (*linkp == link)
-+ break;
-+
-+ if (*linkp == NULL)
-+ return;
-+
-+ del_timer(&link->release);
-+ if (link->state & DEV_CONFIG)
-+ dtl1_release((u_long)link);
-+
-+ if (link->handle) {
-+ ret = CardServices(DeregisterClient, link->handle);
-+ if (ret != CS_SUCCESS)
-+ cs_error(link->handle, DeregisterClient, ret);
-+ }
-+
-+ /* Unlink device structure, free bits */
-+ *linkp = link->next;
-+
-+ kfree(info);
-+}
-+
-+
-+static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
-+{
-+ int i;
-+
-+ i = CardServices(fn, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return CS_NO_MORE_ITEMS;
-+
-+ i = CardServices(GetTupleData, handle, tuple);
-+ if (i != CS_SUCCESS)
-+ return i;
-+
-+ return CardServices(ParseTuple, handle, tuple, parse);
-+}
-+
-+
-+#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)
-+#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)
-+
-+void dtl1_config(dev_link_t *link)
-+{
-+ client_handle_t handle = link->handle;
-+ dtl1_info_t *info = link->priv;
-+ tuple_t tuple;
-+ u_short buf[256];
-+ cisparse_t parse;
-+ cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
-+ int i, last_ret, last_fn;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+
-+ /* Get configuration register information */
-+ tuple.DesiredTuple = CISTPL_CONFIG;
-+ last_ret = first_tuple(handle, &tuple, &parse);
-+ if (last_ret != CS_SUCCESS) {
-+ last_fn = ParseTuple;
-+ goto cs_failed;
-+ }
-+ link->conf.ConfigBase = parse.config.base;
-+ link->conf.Present = parse.config.rmask[0];
-+
-+ /* Configure card */
-+ link->state |= DEV_CONFIG;
-+ i = CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
-+ tuple.TupleData = (cisdata_t *)buf;
-+ tuple.TupleOffset = 0;
-+ tuple.TupleDataMax = 255;
-+ tuple.Attributes = 0;
-+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
-+
-+ /* Look for a generic full-sized window */
-+ link->io.NumPorts1 = 8;
-+ i = first_tuple(handle, &tuple, &parse);
-+ while (i != CS_NO_MORE_ITEMS) {
-+ if ((i == CS_SUCCESS) && (cf->io.nwin == 1) && (cf->io.win[0].len > 8)) {
-+ link->conf.ConfigIndex = cf->index;
-+ link->io.BasePort1 = cf->io.win[0].base;
-+ link->io.NumPorts1 = cf->io.win[0].len; /*yo */
-+ link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
-+ i = CardServices(RequestIO, link->handle, &link->io);
-+ if (i == CS_SUCCESS)
-+ break;
-+ }
-+ i = next_tuple(handle, &tuple, &parse);
-+ }
-+
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIO, i);
-+ goto failed;
-+ }
-+
-+ i = CardServices(RequestIRQ, link->handle, &link->irq);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestIRQ, i);
-+ link->irq.AssignedIRQ = 0;
-+ }
-+
-+ i = CardServices(RequestConfiguration, link->handle, &link->conf);
-+ if (i != CS_SUCCESS) {
-+ cs_error(link->handle, RequestConfiguration, i);
-+ goto failed;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+
-+ if (dtl1_open(info) != 0)
-+ goto failed;
-+
-+ strcpy(info->node.dev_name, info->hdev.name);
-+ link->dev = &info->node;
-+ link->state &= ~DEV_CONFIG_PENDING;
-+
-+ return;
-+
-+cs_failed:
-+ cs_error(link->handle, last_fn, last_ret);
-+
-+failed:
-+ dtl1_release((u_long)link);
-+}
-+
-+
-+void dtl1_release(u_long arg)
-+{
-+ dev_link_t *link = (dev_link_t *)arg;
-+ dtl1_info_t *info = link->priv;
-+
-+ if (link->state & DEV_PRESENT)
-+ dtl1_close(info);
-+
-+ MOD_DEC_USE_COUNT;
-+
-+ link->dev = NULL;
-+
-+ CardServices(ReleaseConfiguration, link->handle);
-+ CardServices(ReleaseIO, link->handle, &link->io);
-+ CardServices(ReleaseIRQ, link->handle, &link->irq);
-+
-+ link->state &= ~DEV_CONFIG;
-+}
-+
-+
-+int dtl1_event(event_t event, int priority, event_callback_args_t *args)
-+{
-+ dev_link_t *link = args->client_data;
-+ dtl1_info_t *info = link->priv;
-+
-+ switch (event) {
-+ case CS_EVENT_CARD_REMOVAL:
-+ link->state &= ~DEV_PRESENT;
-+ if (link->state & DEV_CONFIG) {
-+ dtl1_close(info);
-+ mod_timer(&link->release, jiffies + HZ / 20);
-+ }
-+ break;
-+ case CS_EVENT_CARD_INSERTION:
-+ link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
-+ dtl1_config(link);
-+ break;
-+ case CS_EVENT_PM_SUSPEND:
-+ link->state |= DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_RESET_PHYSICAL:
-+ if (link->state & DEV_CONFIG)
-+ CardServices(ReleaseConfiguration, link->handle);
-+ break;
-+ case CS_EVENT_PM_RESUME:
-+ link->state &= ~DEV_SUSPEND;
-+ /* Fall through... */
-+ case CS_EVENT_CARD_RESET:
-+ if (DEV_OK(link))
-+ CardServices(RequestConfiguration, link->handle, &link->conf);
-+ break;
-+ }
-+
-+ return 0;
-+}
-+
-+
-+
-+/* ======================== Module initialization ======================== */
-+
-+
-+int __init init_dtl1_cs(void)
-+{
-+ servinfo_t serv;
-+ int err;
-+
-+ CardServices(GetCardServicesInfo, &serv);
-+ if (serv.Revision != CS_RELEASE_CODE) {
-+ printk(KERN_NOTICE "dtl1_cs: Card Services release does not match!\n");
-+ return -1;
-+ }
-+
-+ err = register_pccard_driver(&dev_info, &dtl1_attach, &dtl1_detach);
-+
-+ return err;
-+}
-+
-+
-+void __exit exit_dtl1_cs(void)
-+{
-+ unregister_pccard_driver(&dev_info);
-+
-+ while (dev_list != NULL)
-+ dtl1_detach(dev_list);
-+}
-+
-+
-+module_init(init_dtl1_cs);
-+module_exit(exit_dtl1_cs);
-+
-+EXPORT_NO_SYMBOLS;
-diff -urN linux-2.4.18/drivers/bluetooth/hci_bcsp.c linux-2.4.18-mh9/drivers/bluetooth/hci_bcsp.c
---- linux-2.4.18/drivers/bluetooth/hci_bcsp.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/drivers/bluetooth/hci_bcsp.c Mon Aug 25 18:38:10 2003
-@@ -0,0 +1,710 @@
-+/*
-+ BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
-+ Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com>
-+
-+ Based on
-+ hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com>
-+ ABCSP by Carl Orsborn <cjo@csr.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#define VERSION "0.1"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/version.h>
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/types.h>
-+#include <linux/fcntl.h>
-+#include <linux/interrupt.h>
-+#include <linux/ptrace.h>
-+#include <linux/poll.h>
-+
-+#include <linux/slab.h>
-+#include <linux/tty.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/signal.h>
-+#include <linux/ioctl.h>
-+#include <linux/skbuff.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include "hci_uart.h"
-+#include "hci_bcsp.h"
-+
-+#ifndef HCI_UART_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#undef BT_DMP
-+#define BT_DMP( A... )
-+#endif
-+
-+/* ---- BCSP CRC calculation ---- */
-+
-+/* Table for calculating CRC for polynomial 0x1021, LSB processed first,
-+initial value 0xffff, bits shifted in reverse order. */
-+
-+static const u16 crc_table[] = {
-+ 0x0000, 0x1081, 0x2102, 0x3183,
-+ 0x4204, 0x5285, 0x6306, 0x7387,
-+ 0x8408, 0x9489, 0xa50a, 0xb58b,
-+ 0xc60c, 0xd68d, 0xe70e, 0xf78f
-+};
-+
-+/* Initialise the crc calculator */
-+#define BCSP_CRC_INIT(x) x = 0xffff
-+
-+/*
-+ Update crc with next data byte
-+
-+ Implementation note
-+ The data byte is treated as two nibbles. The crc is generated
-+ in reverse, i.e., bits are fed into the register from the top.
-+*/
-+static void bcsp_crc_update(u16 *crc, u8 d)
-+{
-+ u16 reg = *crc;
-+
-+ reg = (reg >> 4) ^ crc_table[(reg ^ d) & 0x000f];
-+ reg = (reg >> 4) ^ crc_table[(reg ^ (d >> 4)) & 0x000f];
-+
-+ *crc = reg;
-+}
-+
-+/*
-+ Get reverse of generated crc
-+
-+ Implementation note
-+ The crc generator (bcsp_crc_init() and bcsp_crc_update())
-+ creates a reversed crc, so it needs to be swapped back before
-+ being passed on.
-+*/
-+static u16 bcsp_crc_reverse(u16 crc)
-+{
-+ u16 b, rev;
-+
-+ for (b = 0, rev = 0; b < 16; b++) {
-+ rev = rev << 1;
-+ rev |= (crc & 1);
-+ crc = crc >> 1;
-+ }
-+ return (rev);
-+}
-+
-+/* ---- BCSP core ---- */
-+
-+static void bcsp_slip_msgdelim(struct sk_buff *skb)
-+{
-+ const char pkt_delim = 0xc0;
-+ memcpy(skb_put(skb, 1), &pkt_delim, 1);
-+}
-+
-+static void bcsp_slip_one_byte(struct sk_buff *skb, u8 c)
-+{
-+ const char esc_c0[2] = { 0xdb, 0xdc };
-+ const char esc_db[2] = { 0xdb, 0xdd };
-+
-+ switch (c) {
-+ case 0xc0:
-+ memcpy(skb_put(skb, 2), &esc_c0, 2);
-+ break;
-+ case 0xdb:
-+ memcpy(skb_put(skb, 2), &esc_db, 2);
-+ break;
-+ default:
-+ memcpy(skb_put(skb, 1), &c, 1);
-+ }
-+}
-+
-+static int bcsp_enqueue(struct hci_uart *hu, struct sk_buff *skb)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+
-+ if (skb->len > 0xFFF) {
-+ BT_ERR("Packet too long");
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+
-+ switch (skb->pkt_type) {
-+ case HCI_ACLDATA_PKT:
-+ case HCI_COMMAND_PKT:
-+ skb_queue_tail(&bcsp->rel, skb);
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ skb_queue_tail(&bcsp->unrel, skb);
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown packet type");
-+ kfree_skb(skb);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
-+ int len, int pkt_type)
-+{
-+ struct sk_buff *nskb;
-+ u8 hdr[4], chan;
-+ int rel, i;
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ u16 BCSP_CRC_INIT(bcsp_txmsg_crc);
-+#endif
-+
-+ switch (pkt_type) {
-+ case HCI_ACLDATA_PKT:
-+ chan = 6; /* BCSP ACL channel */
-+ rel = 1; /* reliable channel */
-+ break;
-+ case HCI_COMMAND_PKT:
-+ chan = 5; /* BCSP cmd/evt channel */
-+ rel = 1; /* reliable channel */
-+ break;
-+ case HCI_SCODATA_PKT:
-+ chan = 7; /* BCSP SCO channel */
-+ rel = 0; /* unreliable channel */
-+ break;
-+ case BCSP_LE_PKT:
-+ chan = 1; /* BCSP LE channel */
-+ rel = 0; /* unreliable channel */
-+ break;
-+ case BCSP_ACK_PKT:
-+ chan = 0; /* BCSP internal channel */
-+ rel = 0; /* unreliable channel */
-+ break;
-+ default:
-+ BT_ERR("Unknown packet type");
-+ return NULL;
-+ }
-+
-+ /* Max len of packet: (original len +4(bcsp hdr) +2(crc))*2
-+ (because bytes 0xc0 and 0xdb are escaped, worst case is
-+ when the packet is all made of 0xc0 and 0xdb :) )
-+ + 2 (0xc0 delimiters at start and end). */
-+
-+ nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC);
-+ if (!nskb)
-+ return NULL;
-+
-+ nskb->pkt_type = pkt_type;
-+
-+ bcsp_slip_msgdelim(nskb);
-+
-+ hdr[0] = bcsp->rxseq_txack << 3;
-+ bcsp->txack_req = 0;
-+ BT_DBG("We request packet no %u to card", bcsp->rxseq_txack);
-+
-+ if (rel) {
-+ hdr[0] |= 0x80 + bcsp->msgq_txseq;
-+ BT_DBG("Sending packet with seqno %u", bcsp->msgq_txseq);
-+ bcsp->msgq_txseq = ++(bcsp->msgq_txseq) & 0x07;
-+ }
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ hdr[0] |= 0x40;
-+#endif
-+
-+ hdr[1] = (len << 4) & 0xFF;
-+ hdr[1] |= chan;
-+ hdr[2] = len >> 4;
-+ hdr[3] = ~(hdr[0] + hdr[1] + hdr[2]);
-+
-+ /* Put BCSP header */
-+ for (i = 0; i < 4; i++) {
-+ bcsp_slip_one_byte(nskb, hdr[i]);
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ bcsp_crc_update(&bcsp_txmsg_crc, hdr[i]);
-+#endif
-+ }
-+
-+ /* Put payload */
-+ for (i = 0; i < len; i++) {
-+ bcsp_slip_one_byte(nskb, data[i]);
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ bcsp_crc_update(&bcsp_txmsg_crc, data[i]);
-+#endif
-+ }
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP_TXCRC
-+ /* Put CRC */
-+ bcsp_txmsg_crc = bcsp_crc_reverse(bcsp_txmsg_crc);
-+ bcsp_slip_one_byte(nskb, (u8) ((bcsp_txmsg_crc >> 8) & 0x00ff));
-+ bcsp_slip_one_byte(nskb, (u8) (bcsp_txmsg_crc & 0x00ff));
-+#endif
-+
-+ bcsp_slip_msgdelim(nskb);
-+ return nskb;
-+}
-+
-+/* This is a rewrite of pkt_avail in ABCSP */
-+static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
-+ unsigned long flags;
-+ struct sk_buff *skb;
-+
-+ /* First of all, check for unreliable messages in the queue,
-+ since they have priority */
-+
-+ if ((skb = skb_dequeue(&bcsp->unrel)) != NULL) {
-+ struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
-+ if (nskb) {
-+ kfree_skb(skb);
-+ return nskb;
-+ } else {
-+ skb_queue_head(&bcsp->unrel, skb);
-+ BT_ERR("Could not dequeue pkt because alloc_skb failed");
-+ }
-+ }
-+
-+ /* Now, try to send a reliable pkt. We can only send a
-+ reliable packet if the number of packets sent but not yet ack'ed
-+ is < than the winsize */
-+
-+ spin_lock_irqsave(&bcsp->unack.lock, flags);
-+
-+ if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) {
-+ struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
-+ if (nskb) {
-+ __skb_queue_tail(&bcsp->unack, skb);
-+ mod_timer(&bcsp->tbcsp, jiffies + HZ / 4);
-+ spin_unlock_irqrestore(&bcsp->unack.lock, flags);
-+ return nskb;
-+ } else {
-+ skb_queue_head(&bcsp->rel, skb);
-+ BT_ERR("Could not dequeue pkt because alloc_skb failed");
-+ }
-+ }
-+
-+ spin_unlock_irqrestore(&bcsp->unack.lock, flags);
-+
-+
-+ /* We could not send a reliable packet, either because there are
-+ none or because there are too many unack'ed pkts. Did we receive
-+ any packets we have not acknowledged yet ? */
-+
-+ if (bcsp->txack_req) {
-+ /* if so, craft an empty ACK pkt and send it on BCSP unreliable
-+ channel 0 */
-+ struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, NULL, 0, BCSP_ACK_PKT);
-+ return nskb;
-+ }
-+
-+ /* We have nothing to send */
-+ return NULL;
-+}
-+
-+static int bcsp_flush(struct hci_uart *hu)
-+{
-+ BT_DBG("hu %p", hu);
-+ return 0;
-+}
-+
-+/* Remove ack'ed packets */
-+static void bcsp_pkt_cull(struct bcsp_struct *bcsp)
-+{
-+ unsigned long flags;
-+ struct sk_buff *skb;
-+ int i, pkts_to_be_removed;
-+ u8 seqno;
-+
-+ spin_lock_irqsave(&bcsp->unack.lock, flags);
-+
-+ pkts_to_be_removed = bcsp->unack.qlen;
-+ seqno = bcsp->msgq_txseq;
-+
-+ while (pkts_to_be_removed) {
-+ if (bcsp->rxack == seqno)
-+ break;
-+ pkts_to_be_removed--;
-+ seqno = (seqno - 1) & 0x07;
-+ }
-+
-+ if (bcsp->rxack != seqno)
-+ BT_ERR("Peer acked invalid packet");
-+
-+ BT_DBG("Removing %u pkts out of %u, up to seqno %u",
-+ pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07);
-+
-+ for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed
-+ && skb != (struct sk_buff *) &bcsp->unack; i++) {
-+ struct sk_buff *nskb;
-+
-+ nskb = skb->next;
-+ __skb_unlink(skb, &bcsp->unack);
-+ kfree_skb(skb);
-+ skb = nskb;
-+ }
-+ if (bcsp->unack.qlen == 0)
-+ del_timer(&bcsp->tbcsp);
-+ spin_unlock_irqrestore(&bcsp->unack.lock, flags);
-+
-+ if (i != pkts_to_be_removed)
-+ BT_ERR("Removed only %u out of %u pkts", i, pkts_to_be_removed);
-+}
-+
-+/* Handle BCSP link-establishment packets. When we
-+ detect a "sync" packet, symptom that the BT module has reset,
-+ we do nothing :) (yet) */
-+static void bcsp_handle_le_pkt(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+ u8 conf_pkt[4] = { 0xad, 0xef, 0xac, 0xed };
-+ u8 conf_rsp_pkt[4] = { 0xde, 0xad, 0xd0, 0xd0 };
-+ u8 sync_pkt[4] = { 0xda, 0xdc, 0xed, 0xed };
-+
-+ /* spot "conf" pkts and reply with a "conf rsp" pkt */
-+ if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
-+ !memcmp(&bcsp->rx_skb->data[4], conf_pkt, 4)) {
-+ struct sk_buff *nskb = alloc_skb(4, GFP_ATOMIC);
-+
-+ BT_DBG("Found a LE conf pkt");
-+ if (!nskb)
-+ return;
-+ memcpy(skb_put(nskb, 4), conf_rsp_pkt, 4);
-+ nskb->pkt_type = BCSP_LE_PKT;
-+
-+ skb_queue_head(&bcsp->unrel, nskb);
-+ hci_uart_tx_wakeup(hu);
-+ }
-+ /* Spot "sync" pkts. If we find one...disaster! */
-+ else if (bcsp->rx_skb->data[1] >> 4 == 4 && bcsp->rx_skb->data[2] == 0 &&
-+ !memcmp(&bcsp->rx_skb->data[4], sync_pkt, 4)) {
-+ BT_ERR("Found a LE sync pkt, card has reset");
-+ }
-+}
-+
-+static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char byte)
-+{
-+ const u8 c0 = 0xc0, db = 0xdb;
-+
-+ switch (bcsp->rx_esc_state) {
-+ case BCSP_ESCSTATE_NOESC:
-+ switch (byte) {
-+ case 0xdb:
-+ bcsp->rx_esc_state = BCSP_ESCSTATE_ESC;
-+ break;
-+ default:
-+ memcpy(skb_put(bcsp->rx_skb, 1), &byte, 1);
-+ if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
-+ bcsp->rx_state != BCSP_W4_CRC)
-+ bcsp_crc_update(&bcsp->message_crc, byte);
-+ bcsp->rx_count--;
-+ }
-+ break;
-+
-+ case BCSP_ESCSTATE_ESC:
-+ switch (byte) {
-+ case 0xdc:
-+ memcpy(skb_put(bcsp->rx_skb, 1), &c0, 1);
-+ if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
-+ bcsp->rx_state != BCSP_W4_CRC)
-+ bcsp_crc_update(&bcsp-> message_crc, 0xc0);
-+ bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
-+ bcsp->rx_count--;
-+ break;
-+
-+ case 0xdd:
-+ memcpy(skb_put(bcsp->rx_skb, 1), &db, 1);
-+ if ((bcsp->rx_skb-> data[0] & 0x40) != 0 &&
-+ bcsp->rx_state != BCSP_W4_CRC)
-+ bcsp_crc_update(&bcsp-> message_crc, 0xdb);
-+ bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
-+ bcsp->rx_count--;
-+ break;
-+
-+ default:
-+ BT_ERR ("Invalid byte %02x after esc byte", byte);
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_skb = NULL;
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ }
-+ }
-+}
-+
-+static inline void bcsp_complete_rx_pkt(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+ int pass_up;
-+
-+ if (bcsp->rx_skb->data[0] & 0x80) { /* reliable pkt */
-+ BT_DBG("Received seqno %u from card", bcsp->rxseq_txack);
-+ bcsp->rxseq_txack++;
-+ bcsp->rxseq_txack %= 0x8;
-+ bcsp->txack_req = 1;
-+
-+ /* If needed, transmit an ack pkt */
-+ hci_uart_tx_wakeup(hu);
-+ }
-+
-+ bcsp->rxack = (bcsp->rx_skb->data[0] >> 3) & 0x07;
-+ BT_DBG("Request for pkt %u from card", bcsp->rxack);
-+
-+ bcsp_pkt_cull(bcsp);
-+ if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
-+ bcsp->rx_skb->data[0] & 0x80) {
-+ bcsp->rx_skb->pkt_type = HCI_ACLDATA_PKT;
-+ pass_up = 1;
-+ } else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
-+ bcsp->rx_skb->data[0] & 0x80) {
-+ bcsp->rx_skb->pkt_type = HCI_EVENT_PKT;
-+ pass_up = 1;
-+ } else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
-+ bcsp->rx_skb->pkt_type = HCI_SCODATA_PKT;
-+ pass_up = 1;
-+ } else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 &&
-+ !(bcsp->rx_skb->data[0] & 0x80)) {
-+ bcsp_handle_le_pkt(hu);
-+ pass_up = 0;
-+ } else
-+ pass_up = 0;
-+
-+ if (!pass_up) {
-+ if ((bcsp->rx_skb->data[1] & 0x0f) != 0 &&
-+ (bcsp->rx_skb->data[1] & 0x0f) != 1) {
-+ BT_ERR ("Packet for unknown channel (%u %s)",
-+ bcsp->rx_skb->data[1] & 0x0f,
-+ bcsp->rx_skb->data[0] & 0x80 ?
-+ "reliable" : "unreliable");
-+ }
-+ kfree_skb(bcsp->rx_skb);
-+ } else {
-+ /* Pull out BCSP hdr */
-+ skb_pull(bcsp->rx_skb, 4);
-+
-+ hci_recv_frame(bcsp->rx_skb);
-+ }
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_skb = NULL;
-+}
-+
-+/* Recv data */
-+static int bcsp_recv(struct hci_uart *hu, void *data, int count)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+ register unsigned char *ptr;
-+
-+ BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
-+ hu, count, bcsp->rx_state, bcsp->rx_count);
-+
-+ ptr = data;
-+ while (count) {
-+ if (bcsp->rx_count) {
-+ if (*ptr == 0xc0) {
-+ BT_ERR("Short BCSP packet");
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_state = BCSP_W4_PKT_START;
-+ bcsp->rx_count = 0;
-+ } else
-+ bcsp_unslip_one_byte(bcsp, *ptr);
-+
-+ ptr++; count--;
-+ continue;
-+ }
-+
-+ switch (bcsp->rx_state) {
-+ case BCSP_W4_BCSP_HDR:
-+ if ((0xff & (u8) ~ (bcsp->rx_skb->data[0] + bcsp->rx_skb->data[1] +
-+ bcsp->rx_skb->data[2])) != bcsp->rx_skb->data[3]) {
-+ BT_ERR("Error in BCSP hdr checksum");
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ continue;
-+ }
-+ if (bcsp->rx_skb->data[0] & 0x80 /* reliable pkt */
-+ && (bcsp->rx_skb->data[0] & 0x07) != bcsp->rxseq_txack) {
-+ BT_ERR ("Out-of-order packet arrived, got %u expected %u",
-+ bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack);
-+
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ continue;
-+ }
-+ bcsp->rx_state = BCSP_W4_DATA;
-+ bcsp->rx_count = (bcsp->rx_skb->data[1] >> 4) +
-+ (bcsp->rx_skb->data[2] << 4); /* May be 0 */
-+ continue;
-+
-+ case BCSP_W4_DATA:
-+ if (bcsp->rx_skb->data[0] & 0x40) { /* pkt with crc */
-+ bcsp->rx_state = BCSP_W4_CRC;
-+ bcsp->rx_count = 2;
-+ } else
-+ bcsp_complete_rx_pkt(hu);
-+ continue;
-+
-+ case BCSP_W4_CRC:
-+ if (bcsp_crc_reverse(bcsp->message_crc) !=
-+ (bcsp->rx_skb->data[bcsp->rx_skb->len - 2] << 8) +
-+ bcsp->rx_skb->data[bcsp->rx_skb->len - 1]) {
-+
-+ BT_ERR ("Checksum failed: computed %04x received %04x",
-+ bcsp_crc_reverse(bcsp->message_crc),
-+ (bcsp->rx_skb-> data[bcsp->rx_skb->len - 2] << 8) +
-+ bcsp->rx_skb->data[bcsp->rx_skb->len - 1]);
-+
-+ kfree_skb(bcsp->rx_skb);
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ continue;
-+ }
-+ skb_trim(bcsp->rx_skb, bcsp->rx_skb->len - 2);
-+ bcsp_complete_rx_pkt(hu);
-+ continue;
-+
-+ case BCSP_W4_PKT_DELIMITER:
-+ switch (*ptr) {
-+ case 0xc0:
-+ bcsp->rx_state = BCSP_W4_PKT_START;
-+ break;
-+ default:
-+ /*BT_ERR("Ignoring byte %02x", *ptr);*/
-+ break;
-+ }
-+ ptr++; count--;
-+ break;
-+
-+ case BCSP_W4_PKT_START:
-+ switch (*ptr) {
-+ case 0xc0:
-+ ptr++; count--;
-+ break;
-+
-+ default:
-+ bcsp->rx_state = BCSP_W4_BCSP_HDR;
-+ bcsp->rx_count = 4;
-+ bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC;
-+ BCSP_CRC_INIT(bcsp->message_crc);
-+
-+ /* Do not increment ptr or decrement count
-+ * Allocate packet. Max len of a BCSP pkt=
-+ * 0xFFF (payload) +4 (header) +2 (crc) */
-+
-+ bcsp->rx_skb = bluez_skb_alloc(0x1005, GFP_ATOMIC);
-+ if (!bcsp->rx_skb) {
-+ BT_ERR("Can't allocate mem for new packet");
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+ bcsp->rx_count = 0;
-+ return 0;
-+ }
-+ bcsp->rx_skb->dev = (void *) &hu->hdev;
-+ break;
-+ }
-+ break;
-+ }
-+ }
-+ return count;
-+}
-+
-+ /* Arrange to retransmit all messages in the relq. */
-+static void bcsp_timed_event(unsigned long arg)
-+{
-+ struct hci_uart *hu = (struct hci_uart *) arg;
-+ struct bcsp_struct *bcsp = (struct bcsp_struct *) hu->priv;
-+ struct sk_buff *skb;
-+ unsigned long flags;
-+
-+ BT_ERR("Timeout, retransmitting %u pkts", bcsp->unack.qlen);
-+ spin_lock_irqsave(&bcsp->unack.lock, flags);
-+
-+ while ((skb = __skb_dequeue_tail(&bcsp->unack)) != NULL) {
-+ bcsp->msgq_txseq = (bcsp->msgq_txseq - 1) & 0x07;
-+ skb_queue_head(&bcsp->rel, skb);
-+ }
-+
-+ spin_unlock_irqrestore(&bcsp->unack.lock, flags);
-+
-+ hci_uart_tx_wakeup(hu);
-+}
-+
-+static int bcsp_open(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp;
-+
-+ BT_DBG("hu %p", hu);
-+
-+ bcsp = kmalloc(sizeof(*bcsp), GFP_ATOMIC);
-+ if (!bcsp)
-+ return -ENOMEM;
-+ memset(bcsp, 0, sizeof(*bcsp));
-+
-+ hu->priv = bcsp;
-+ skb_queue_head_init(&bcsp->unack);
-+ skb_queue_head_init(&bcsp->rel);
-+ skb_queue_head_init(&bcsp->unrel);
-+
-+ init_timer(&bcsp->tbcsp);
-+ bcsp->tbcsp.function = bcsp_timed_event;
-+ bcsp->tbcsp.data = (u_long) hu;
-+
-+ bcsp->rx_state = BCSP_W4_PKT_DELIMITER;
-+
-+ return 0;
-+}
-+
-+static int bcsp_close(struct hci_uart *hu)
-+{
-+ struct bcsp_struct *bcsp = hu->priv;
-+ hu->priv = NULL;
-+
-+ BT_DBG("hu %p", hu);
-+
-+ skb_queue_purge(&bcsp->unack);
-+ skb_queue_purge(&bcsp->rel);
-+ skb_queue_purge(&bcsp->unrel);
-+ del_timer(&bcsp->tbcsp);
-+
-+ kfree(bcsp);
-+ return 0;
-+}
-+
-+static struct hci_uart_proto bcsp = {
-+ id: HCI_UART_BCSP,
-+ open: bcsp_open,
-+ close: bcsp_close,
-+ enqueue: bcsp_enqueue,
-+ dequeue: bcsp_dequeue,
-+ recv: bcsp_recv,
-+ flush: bcsp_flush
-+};
-+
-+int bcsp_init(void)
-+{
-+ return hci_uart_register_proto(&bcsp);
-+}
-+
-+int bcsp_deinit(void)
-+{
-+ return hci_uart_unregister_proto(&bcsp);
-+}
-diff -urN linux-2.4.18/drivers/bluetooth/hci_bcsp.h linux-2.4.18-mh9/drivers/bluetooth/hci_bcsp.h
---- linux-2.4.18/drivers/bluetooth/hci_bcsp.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/drivers/bluetooth/hci_bcsp.h Mon Aug 25 18:38:10 2003
-@@ -0,0 +1,70 @@
-+/*
-+ BlueCore Serial Protocol (BCSP) for Linux Bluetooth stack (BlueZ).
-+ Copyright 2002 by Fabrizio Gennari <fabrizio.gennari@philips.com>
-+
-+ Based on
-+ hci_h4.c by Maxim Krasnyansky <maxk@qualcomm.com>
-+ ABCSP by Carl Orsborn <cjo@csr.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef __HCI_BCSP_H__
-+#define __HCI_BCSP_H__
-+
-+#define BCSP_TXWINSIZE 4
-+
-+#define BCSP_ACK_PKT 0x05
-+#define BCSP_LE_PKT 0x06
-+
-+struct bcsp_struct {
-+ struct sk_buff_head unack; /* Unack'ed packets queue */
-+ struct sk_buff_head rel; /* Reliable packets queue */
-+ struct sk_buff_head unrel; /* Unreliable packets queue */
-+
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+ u8 rxseq_txack; /* rxseq == txack. */
-+ u8 rxack; /* Last packet sent by us that the peer ack'ed */
-+ struct timer_list tbcsp;
-+
-+ enum {
-+ BCSP_W4_PKT_DELIMITER,
-+ BCSP_W4_PKT_START,
-+ BCSP_W4_BCSP_HDR,
-+ BCSP_W4_DATA,
-+ BCSP_W4_CRC
-+ } rx_state;
-+
-+ enum {
-+ BCSP_ESCSTATE_NOESC,
-+ BCSP_ESCSTATE_ESC
-+ } rx_esc_state;
-+
-+ u16 message_crc;
-+ u8 txack_req; /* Do we need to send ack's to the peer? */
-+
-+ /* Reliable packet sequence number - used to assign seq to each rel pkt. */
-+ u8 msgq_txseq;
-+};
-+
-+#endif /* __HCI_BCSP_H__ */
-diff -urN linux-2.4.18/drivers/bluetooth/hci_h4.c linux-2.4.18-mh9/drivers/bluetooth/hci_h4.c
---- linux-2.4.18/drivers/bluetooth/hci_h4.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/drivers/bluetooth/hci_h4.c Mon Aug 25 18:38:10 2003
-@@ -0,0 +1,277 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * BlueZ HCI UART(H4) protocol.
-+ *
-+ * $Id$
-+ */
-+#define VERSION "1.2"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/version.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/types.h>
-+#include <linux/fcntl.h>
-+#include <linux/interrupt.h>
-+#include <linux/ptrace.h>
-+#include <linux/poll.h>
-+
-+#include <linux/slab.h>
-+#include <linux/tty.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/signal.h>
-+#include <linux/ioctl.h>
-+#include <linux/skbuff.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include "hci_uart.h"
-+#include "hci_h4.h"
-+
-+#ifndef HCI_UART_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#undef BT_DMP
-+#define BT_DMP( A... )
-+#endif
-+
-+/* Initialize protocol */
-+static int h4_open(struct hci_uart *hu)
-+{
-+ struct h4_struct *h4;
-+
-+ BT_DBG("hu %p", hu);
-+
-+ h4 = kmalloc(sizeof(*h4), GFP_ATOMIC);
-+ if (!h4)
-+ return -ENOMEM;
-+ memset(h4, 0, sizeof(*h4));
-+
-+ skb_queue_head_init(&h4->txq);
-+
-+ hu->priv = h4;
-+ return 0;
-+}
-+
-+/* Flush protocol data */
-+static int h4_flush(struct hci_uart *hu)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+
-+ BT_DBG("hu %p", hu);
-+ skb_queue_purge(&h4->txq);
-+ return 0;
-+}
-+
-+/* Close protocol */
-+static int h4_close(struct hci_uart *hu)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+ hu->priv = NULL;
-+
-+ BT_DBG("hu %p", hu);
-+
-+ skb_queue_purge(&h4->txq);
-+ if (h4->rx_skb)
-+ kfree_skb(h4->rx_skb);
-+
-+ hu->priv = NULL;
-+ kfree(h4);
-+ return 0;
-+}
-+
-+/* Enqueue frame for transmittion (padding, crc, etc) */
-+static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+
-+ BT_DBG("hu %p skb %p", hu, skb);
-+
-+ /* Prepend skb with frame type */
-+ memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
-+ skb_queue_tail(&h4->txq, skb);
-+ return 0;
-+}
-+
-+static inline int h4_check_data_len(struct h4_struct *h4, int len)
-+{
-+ register int room = skb_tailroom(h4->rx_skb);
-+
-+ BT_DBG("len %d room %d", len, room);
-+ if (!len) {
-+ BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
-+ hci_recv_frame(h4->rx_skb);
-+ } else if (len > room) {
-+ BT_ERR("Data length is too large");
-+ kfree_skb(h4->rx_skb);
-+ } else {
-+ h4->rx_state = H4_W4_DATA;
-+ h4->rx_count = len;
-+ return len;
-+ }
-+
-+ h4->rx_state = H4_W4_PACKET_TYPE;
-+ h4->rx_skb = NULL;
-+ h4->rx_count = 0;
-+ return 0;
-+}
-+
-+/* Recv data */
-+static int h4_recv(struct hci_uart *hu, void *data, int count)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+ register char *ptr;
-+ hci_event_hdr *eh;
-+ hci_acl_hdr *ah;
-+ hci_sco_hdr *sh;
-+ register int len, type, dlen;
-+
-+ BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
-+ hu, count, h4->rx_state, h4->rx_count);
-+
-+ ptr = data;
-+ while (count) {
-+ if (h4->rx_count) {
-+ len = MIN(h4->rx_count, count);
-+ memcpy(skb_put(h4->rx_skb, len), ptr, len);
-+ h4->rx_count -= len; count -= len; ptr += len;
-+
-+ if (h4->rx_count)
-+ continue;
-+
-+ switch (h4->rx_state) {
-+ case H4_W4_DATA:
-+ BT_DBG("Complete data");
-+
-+ BT_DMP(h4->rx_skb->data, h4->rx_skb->len);
-+
-+ hci_recv_frame(h4->rx_skb);
-+
-+ h4->rx_state = H4_W4_PACKET_TYPE;
-+ h4->rx_skb = NULL;
-+ continue;
-+
-+ case H4_W4_EVENT_HDR:
-+ eh = (hci_event_hdr *) h4->rx_skb->data;
-+
-+ BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
-+
-+ h4_check_data_len(h4, eh->plen);
-+ continue;
-+
-+ case H4_W4_ACL_HDR:
-+ ah = (hci_acl_hdr *) h4->rx_skb->data;
-+ dlen = __le16_to_cpu(ah->dlen);
-+
-+ BT_DBG("ACL header: dlen %d", dlen);
-+
-+ h4_check_data_len(h4, dlen);
-+ continue;
-+
-+ case H4_W4_SCO_HDR:
-+ sh = (hci_sco_hdr *) h4->rx_skb->data;
-+
-+ BT_DBG("SCO header: dlen %d", sh->dlen);
-+
-+ h4_check_data_len(h4, sh->dlen);
-+ continue;
-+ }
-+ }
-+
-+ /* H4_W4_PACKET_TYPE */
-+ switch (*ptr) {
-+ case HCI_EVENT_PKT:
-+ BT_DBG("Event packet");
-+ h4->rx_state = H4_W4_EVENT_HDR;
-+ h4->rx_count = HCI_EVENT_HDR_SIZE;
-+ type = HCI_EVENT_PKT;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ BT_DBG("ACL packet");
-+ h4->rx_state = H4_W4_ACL_HDR;
-+ h4->rx_count = HCI_ACL_HDR_SIZE;
-+ type = HCI_ACLDATA_PKT;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ BT_DBG("SCO packet");
-+ h4->rx_state = H4_W4_SCO_HDR;
-+ h4->rx_count = HCI_SCO_HDR_SIZE;
-+ type = HCI_SCODATA_PKT;
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
-+ hu->hdev.stat.err_rx++;
-+ ptr++; count--;
-+ continue;
-+ };
-+ ptr++; count--;
-+
-+ /* Allocate packet */
-+ h4->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
-+ if (!h4->rx_skb) {
-+ BT_ERR("Can't allocate mem for new packet");
-+ h4->rx_state = H4_W4_PACKET_TYPE;
-+ h4->rx_count = 0;
-+ return 0;
-+ }
-+ h4->rx_skb->dev = (void *) &hu->hdev;
-+ h4->rx_skb->pkt_type = type;
-+ }
-+ return count;
-+}
-+
-+static struct sk_buff *h4_dequeue(struct hci_uart *hu)
-+{
-+ struct h4_struct *h4 = hu->priv;
-+ return skb_dequeue(&h4->txq);
-+}
-+
-+static struct hci_uart_proto h4p = {
-+ id: HCI_UART_H4,
-+ open: h4_open,
-+ close: h4_close,
-+ recv: h4_recv,
-+ enqueue: h4_enqueue,
-+ dequeue: h4_dequeue,
-+ flush: h4_flush,
-+};
-+
-+int h4_init(void)
-+{
-+ return hci_uart_register_proto(&h4p);
-+}
-+
-+int h4_deinit(void)
-+{
-+ return hci_uart_unregister_proto(&h4p);
-+}
-diff -urN linux-2.4.18/drivers/bluetooth/hci_h4.h linux-2.4.18-mh9/drivers/bluetooth/hci_h4.h
---- linux-2.4.18/drivers/bluetooth/hci_h4.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/drivers/bluetooth/hci_h4.h Mon Aug 25 18:38:10 2003
-@@ -0,0 +1,44 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifdef __KERNEL__
-+struct h4_struct {
-+ unsigned long rx_state;
-+ unsigned long rx_count;
-+ struct sk_buff *rx_skb;
-+ struct sk_buff_head txq;
-+};
-+
-+/* H4 receiver States */
-+#define H4_W4_PACKET_TYPE 0
-+#define H4_W4_EVENT_HDR 1
-+#define H4_W4_ACL_HDR 2
-+#define H4_W4_SCO_HDR 3
-+#define H4_W4_DATA 4
-+
-+#endif /* __KERNEL__ */
-diff -urN linux-2.4.18/drivers/bluetooth/hci_ldisc.c linux-2.4.18-mh9/drivers/bluetooth/hci_ldisc.c
---- linux-2.4.18/drivers/bluetooth/hci_ldisc.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/drivers/bluetooth/hci_ldisc.c Mon Aug 25 18:38:10 2003
-@@ -0,0 +1,580 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * BlueZ HCI UART driver.
-+ *
-+ * $Id$
-+ */
-+#define VERSION "2.1"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/version.h>
-+#include <linux/config.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/types.h>
-+#include <linux/fcntl.h>
-+#include <linux/interrupt.h>
-+#include <linux/ptrace.h>
-+#include <linux/poll.h>
-+
-+#include <linux/slab.h>
-+#include <linux/tty.h>
-+#include <linux/errno.h>
-+#include <linux/string.h>
-+#include <linux/signal.h>
-+#include <linux/ioctl.h>
-+#include <linux/skbuff.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include "hci_uart.h"
-+
-+#ifndef HCI_UART_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#undef BT_DMP
-+#define BT_DMP( A... )
-+#endif
-+
-+static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
-+
-+int hci_uart_register_proto(struct hci_uart_proto *p)
-+{
-+ if (p->id >= HCI_UART_MAX_PROTO)
-+ return -EINVAL;
-+
-+ if (hup[p->id])
-+ return -EEXIST;
-+
-+ hup[p->id] = p;
-+ return 0;
-+}
-+
-+int hci_uart_unregister_proto(struct hci_uart_proto *p)
-+{
-+ if (p->id >= HCI_UART_MAX_PROTO)
-+ return -EINVAL;
-+
-+ if (!hup[p->id])
-+ return -EINVAL;
-+
-+ hup[p->id] = NULL;
-+ return 0;
-+}
-+
-+static struct hci_uart_proto *hci_uart_get_proto(unsigned int id)
-+{
-+ if (id >= HCI_UART_MAX_PROTO)
-+ return NULL;
-+ return hup[id];
-+}
-+
-+static inline void hci_uart_tx_complete(struct hci_uart *hu, int pkt_type)
-+{
-+ struct hci_dev *hdev = &hu->hdev;
-+
-+ /* Update HCI stat counters */
-+ switch (pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+ }
-+}
-+
-+static inline struct sk_buff *hci_uart_dequeue(struct hci_uart *hu)
-+{
-+ struct sk_buff *skb = hu->tx_skb;
-+ if (!skb)
-+ skb = hu->proto->dequeue(hu);
-+ else
-+ hu->tx_skb = NULL;
-+ return skb;
-+}
-+
-+int hci_uart_tx_wakeup(struct hci_uart *hu)
-+{
-+ struct tty_struct *tty = hu->tty;
-+ struct hci_dev *hdev = &hu->hdev;
-+ struct sk_buff *skb;
-+
-+ if (test_and_set_bit(HCI_UART_SENDING, &hu->tx_state)) {
-+ set_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
-+ return 0;
-+ }
-+
-+ BT_DBG("");
-+
-+restart:
-+ clear_bit(HCI_UART_TX_WAKEUP, &hu->tx_state);
-+
-+ while ((skb = hci_uart_dequeue(hu))) {
-+ int len;
-+
-+ set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-+ len = tty->driver.write(tty, 0, skb->data, skb->len);
-+ hdev->stat.byte_tx += len;
-+
-+ skb_pull(skb, len);
-+ if (skb->len) {
-+ hu->tx_skb = skb;
-+ break;
-+ }
-+
-+ hci_uart_tx_complete(hu, skb->pkt_type);
-+ kfree_skb(skb);
-+ }
-+
-+ if (test_bit(HCI_UART_TX_WAKEUP, &hu->tx_state))
-+ goto restart;
-+
-+ clear_bit(HCI_UART_SENDING, &hu->tx_state);
-+ return 0;
-+}
-+
-+/* ------- Interface to HCI layer ------ */
-+/* Initialize device */
-+static int hci_uart_open(struct hci_dev *hdev)
-+{
-+ BT_DBG("%s %p", hdev->name, hdev);
-+
-+ /* Nothing to do for UART driver */
-+
-+ set_bit(HCI_RUNNING, &hdev->flags);
-+ return 0;
-+}
-+
-+/* Reset device */
-+static int hci_uart_flush(struct hci_dev *hdev)
-+{
-+ struct hci_uart *hu = (struct hci_uart *) hdev->driver_data;
-+ struct tty_struct *tty = hu->tty;
-+
-+ BT_DBG("hdev %p tty %p", hdev, tty);
-+
-+ if (hu->tx_skb) {
-+ kfree_skb(hu->tx_skb); hu->tx_skb = NULL;
-+ }
-+
-+ /* Flush any pending characters in the driver and discipline. */
-+ if (tty->ldisc.flush_buffer)
-+ tty->ldisc.flush_buffer(tty);
-+
-+ if (tty->driver.flush_buffer)
-+ tty->driver.flush_buffer(tty);
-+
-+ if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
-+ hu->proto->flush(hu);
-+
-+ return 0;
-+}
-+
-+/* Close device */
-+static int hci_uart_close(struct hci_dev *hdev)
-+{
-+ BT_DBG("hdev %p", hdev);
-+
-+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-+
-+ hci_uart_flush(hdev);
-+ return 0;
-+}
-+
-+/* Send frames from HCI layer */
-+static int hci_uart_send_frame(struct sk_buff *skb)
-+{
-+ struct hci_dev* hdev = (struct hci_dev *) skb->dev;
-+ struct tty_struct *tty;
-+ struct hci_uart *hu;
-+
-+ if (!hdev) {
-+ BT_ERR("Frame for uknown device (hdev=NULL)");
-+ return -ENODEV;
-+ }
-+
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return -EBUSY;
-+
-+ hu = (struct hci_uart *) hdev->driver_data;
-+ tty = hu->tty;
-+
-+ BT_DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
-+
-+ hu->proto->enqueue(hu, skb);
-+
-+ hci_uart_tx_wakeup(hu);
-+ return 0;
-+}
-+
-+static void hci_uart_destruct(struct hci_dev *hdev)
-+{
-+ struct hci_uart *hu;
-+
-+ if (!hdev) return;
-+
-+ BT_DBG("%s", hdev->name);
-+
-+ hu = (struct hci_uart *) hdev->driver_data;
-+ kfree(hu);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+/* ------ LDISC part ------ */
-+/* hci_uart_tty_open
-+ *
-+ * Called when line discipline changed to HCI_UART.
-+ *
-+ * Arguments:
-+ * tty pointer to tty info structure
-+ * Return Value:
-+ * 0 if success, otherwise error code
-+ */
-+static int hci_uart_tty_open(struct tty_struct *tty)
-+{
-+ struct hci_uart *hu = (void *) tty->disc_data;
-+
-+ BT_DBG("tty %p", tty);
-+
-+ if (hu)
-+ return -EEXIST;
-+
-+ if (!(hu = kmalloc(sizeof(struct hci_uart), GFP_KERNEL))) {
-+ BT_ERR("Can't allocate controll structure");
-+ return -ENFILE;
-+ }
-+ memset(hu, 0, sizeof(struct hci_uart));
-+
-+ tty->disc_data = hu;
-+ hu->tty = tty;
-+
-+ spin_lock_init(&hu->rx_lock);
-+
-+ /* Flush any pending characters in the driver and line discipline */
-+ if (tty->ldisc.flush_buffer)
-+ tty->ldisc.flush_buffer(tty);
-+
-+ if (tty->driver.flush_buffer)
-+ tty->driver.flush_buffer(tty);
-+
-+ MOD_INC_USE_COUNT;
-+ return 0;
-+}
-+
-+/* hci_uart_tty_close()
-+ *
-+ * Called when the line discipline is changed to something
-+ * else, the tty is closed, or the tty detects a hangup.
-+ */
-+static void hci_uart_tty_close(struct tty_struct *tty)
-+{
-+ struct hci_uart *hu = (void *)tty->disc_data;
-+
-+ BT_DBG("tty %p", tty);
-+
-+ /* Detach from the tty */
-+ tty->disc_data = NULL;
-+
-+ if (hu) {
-+ struct hci_dev *hdev = &hu->hdev;
-+ hci_uart_close(hdev);
-+
-+ if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) {
-+ hu->proto->close(hu);
-+ hci_unregister_dev(hdev);
-+ }
-+
-+ MOD_DEC_USE_COUNT;
-+ }
-+}
-+
-+/* hci_uart_tty_wakeup()
-+ *
-+ * Callback for transmit wakeup. Called when low level
-+ * device driver can accept more send data.
-+ *
-+ * Arguments: tty pointer to associated tty instance data
-+ * Return Value: None
-+ */
-+static void hci_uart_tty_wakeup(struct tty_struct *tty)
-+{
-+ struct hci_uart *hu = (void *)tty->disc_data;
-+
-+ BT_DBG("");
-+
-+ if (!hu)
-+ return;
-+
-+ clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
-+
-+ if (tty != hu->tty)
-+ return;
-+
-+ if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
-+ hci_uart_tx_wakeup(hu);
-+}
-+
-+/* hci_uart_tty_room()
-+ *
-+ * Callback function from tty driver. Return the amount of
-+ * space left in the receiver's buffer to decide if remote
-+ * transmitter is to be throttled.
-+ *
-+ * Arguments: tty pointer to associated tty instance data
-+ * Return Value: number of bytes left in receive buffer
-+ */
-+static int hci_uart_tty_room (struct tty_struct *tty)
-+{
-+ return 65536;
-+}
-+
-+/* hci_uart_tty_receive()
-+ *
-+ * Called by tty low level driver when receive data is
-+ * available.
-+ *
-+ * Arguments: tty pointer to tty isntance data
-+ * data pointer to received data
-+ * flags pointer to flags for data
-+ * count count of received data in bytes
-+ *
-+ * Return Value: None
-+ */
-+static void hci_uart_tty_receive(struct tty_struct *tty, const __u8 *data, char *flags, int count)
-+{
-+ struct hci_uart *hu = (void *)tty->disc_data;
-+
-+ if (!hu || tty != hu->tty)
-+ return;
-+
-+ if (!test_bit(HCI_UART_PROTO_SET, &hu->flags))
-+ return;
-+
-+ spin_lock(&hu->rx_lock);
-+ hu->proto->recv(hu, (void *) data, count);
-+ hu->hdev.stat.byte_rx += count;
-+ spin_unlock(&hu->rx_lock);
-+
-+ if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver.unthrottle)
-+ tty->driver.unthrottle(tty);
-+}
-+
-+static int hci_uart_register_dev(struct hci_uart *hu)
-+{
-+ struct hci_dev *hdev;
-+
-+ BT_DBG("");
-+
-+ /* Initialize and register HCI device */
-+ hdev = &hu->hdev;
-+
-+ hdev->type = HCI_UART;
-+ hdev->driver_data = hu;
-+
-+ hdev->open = hci_uart_open;
-+ hdev->close = hci_uart_close;
-+ hdev->flush = hci_uart_flush;
-+ hdev->send = hci_uart_send_frame;
-+ hdev->destruct = hci_uart_destruct;
-+
-+ if (hci_register_dev(hdev) < 0) {
-+ BT_ERR("Can't register HCI device %s", hdev->name);
-+ return -ENODEV;
-+ }
-+ MOD_INC_USE_COUNT;
-+ return 0;
-+}
-+
-+static int hci_uart_set_proto(struct hci_uart *hu, int id)
-+{
-+ struct hci_uart_proto *p;
-+ int err;
-+
-+ p = hci_uart_get_proto(id);
-+ if (!p)
-+ return -EPROTONOSUPPORT;
-+
-+ err = p->open(hu);
-+ if (err)
-+ return err;
-+
-+ hu->proto = p;
-+
-+ err = hci_uart_register_dev(hu);
-+ if (err) {
-+ p->close(hu);
-+ return err;
-+ }
-+ return 0;
-+}
-+
-+/* hci_uart_tty_ioctl()
-+ *
-+ * Process IOCTL system call for the tty device.
-+ *
-+ * Arguments:
-+ *
-+ * tty pointer to tty instance data
-+ * file pointer to open file object for device
-+ * cmd IOCTL command code
-+ * arg argument for IOCTL call (cmd dependent)
-+ *
-+ * Return Value: Command dependent
-+ */
-+static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
-+ unsigned int cmd, unsigned long arg)
-+{
-+ struct hci_uart *hu = (void *)tty->disc_data;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ /* Verify the status of the device */
-+ if (!hu)
-+ return -EBADF;
-+
-+ switch (cmd) {
-+ case HCIUARTSETPROTO:
-+ if (!test_and_set_bit(HCI_UART_PROTO_SET, &hu->flags)) {
-+ err = hci_uart_set_proto(hu, arg);
-+ if (err) {
-+ clear_bit(HCI_UART_PROTO_SET, &hu->flags);
-+ return err;
-+ }
-+ tty->low_latency = 1;
-+ } else
-+ return -EBUSY;
-+
-+ case HCIUARTGETPROTO:
-+ if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
-+ return hu->proto->id;
-+ return -EUNATCH;
-+
-+ default:
-+ err = n_tty_ioctl(tty, file, cmd, arg);
-+ break;
-+ };
-+
-+ return err;
-+}
-+
-+/*
-+ * We don't provide read/write/poll interface for user space.
-+ */
-+static ssize_t hci_uart_tty_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr)
-+{
-+ return 0;
-+}
-+static ssize_t hci_uart_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
-+{
-+ return 0;
-+}
-+static unsigned int hci_uart_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
-+{
-+ return 0;
-+}
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_H4
-+int h4_init(void);
-+int h4_deinit(void);
-+#endif
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP
-+int bcsp_init(void);
-+int bcsp_deinit(void);
-+#endif
-+
-+int __init hci_uart_init(void)
-+{
-+ static struct tty_ldisc hci_uart_ldisc;
-+ int err;
-+
-+ BT_INFO("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-+ VERSION);
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+
-+ /* Register the tty discipline */
-+
-+ memset(&hci_uart_ldisc, 0, sizeof (hci_uart_ldisc));
-+ hci_uart_ldisc.magic = TTY_LDISC_MAGIC;
-+ hci_uart_ldisc.name = "n_hci";
-+ hci_uart_ldisc.open = hci_uart_tty_open;
-+ hci_uart_ldisc.close = hci_uart_tty_close;
-+ hci_uart_ldisc.read = hci_uart_tty_read;
-+ hci_uart_ldisc.write = hci_uart_tty_write;
-+ hci_uart_ldisc.ioctl = hci_uart_tty_ioctl;
-+ hci_uart_ldisc.poll = hci_uart_tty_poll;
-+ hci_uart_ldisc.receive_room= hci_uart_tty_room;
-+ hci_uart_ldisc.receive_buf = hci_uart_tty_receive;
-+ hci_uart_ldisc.write_wakeup= hci_uart_tty_wakeup;
-+
-+ if ((err = tty_register_ldisc(N_HCI, &hci_uart_ldisc))) {
-+ BT_ERR("Can't register HCI line discipline (%d)", err);
-+ return err;
-+ }
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_H4
-+ h4_init();
-+#endif
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP
-+ bcsp_init();
-+#endif
-+
-+ return 0;
-+}
-+
-+void hci_uart_cleanup(void)
-+{
-+ int err;
-+
-+#ifdef CONFIG_BLUEZ_HCIUART_H4
-+ h4_deinit();
-+#endif
-+#ifdef CONFIG_BLUEZ_HCIUART_BCSP
-+ bcsp_deinit();
-+#endif
-+
-+ /* Release tty registration of line discipline */
-+ if ((err = tty_register_ldisc(N_HCI, NULL)))
-+ BT_ERR("Can't unregister HCI line discipline (%d)", err);
-+}
-+
-+module_init(hci_uart_init);
-+module_exit(hci_uart_cleanup);
-+
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
-+MODULE_DESCRIPTION("BlueZ HCI UART driver ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/drivers/bluetooth/hci_uart.c linux-2.4.18-mh9/drivers/bluetooth/hci_uart.c
---- linux-2.4.18/drivers/bluetooth/hci_uart.c Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/drivers/bluetooth/hci_uart.c Thu Jan 1 01:00:00 1970
-@@ -1,580 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * BlueZ HCI UART driver.
-- *
-- * $Id$
-- */
--#define VERSION "1.0"
--
--#include <linux/config.h>
--#include <linux/module.h>
--
--#include <linux/version.h>
--#include <linux/config.h>
--#include <linux/kernel.h>
--#include <linux/init.h>
--#include <linux/sched.h>
--#include <linux/types.h>
--#include <linux/fcntl.h>
--#include <linux/interrupt.h>
--#include <linux/ptrace.h>
--#include <linux/poll.h>
--
--#include <linux/slab.h>
--#include <linux/tty.h>
--#include <linux/errno.h>
--#include <linux/string.h>
--#include <linux/signal.h>
--#include <linux/ioctl.h>
--#include <linux/skbuff.h>
--
--#include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
--#include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/hci_uart.h>
--
--#ifndef HCI_UART_DEBUG
--#undef DBG
--#define DBG( A... )
--#undef DMP
--#define DMP( A... )
--#endif
--
--/* ------- Interface to HCI layer ------ */
--/* Initialize device */
--int n_hci_open(struct hci_dev *hdev)
--{
-- DBG("%s %p", hdev->name, hdev);
--
-- /* Nothing to do for UART driver */
--
-- hdev->flags |= HCI_RUNNING;
--
-- return 0;
--}
--
--/* Reset device */
--int n_hci_flush(struct hci_dev *hdev)
--{
-- struct n_hci *n_hci = (struct n_hci *) hdev->driver_data;
-- struct tty_struct *tty = n_hci->tty;
--
-- DBG("hdev %p tty %p", hdev, tty);
--
-- /* Drop TX queue */
-- skb_queue_purge(&n_hci->txq);
--
-- /* Flush any pending characters in the driver and discipline. */
-- if (tty->ldisc.flush_buffer)
-- tty->ldisc.flush_buffer(tty);
--
-- if (tty->driver.flush_buffer)
-- tty->driver.flush_buffer(tty);
--
-- return 0;
--}
--
--/* Close device */
--int n_hci_close(struct hci_dev *hdev)
--{
-- DBG("hdev %p", hdev);
--
-- hdev->flags &= ~HCI_RUNNING;
--
-- n_hci_flush(hdev);
--
-- return 0;
--}
--
--int n_hci_tx_wakeup(struct n_hci *n_hci)
--{
-- register struct tty_struct *tty = n_hci->tty;
--
-- if (test_and_set_bit(TRANS_SENDING, &n_hci->tx_state)) {
-- set_bit(TRANS_WAKEUP, &n_hci->tx_state);
-- return 0;
-- }
--
-- DBG("");
-- do {
-- register struct sk_buff *skb;
-- register int len;
--
-- clear_bit(TRANS_WAKEUP, &n_hci->tx_state);
--
-- if (!(skb = skb_dequeue(&n_hci->txq)))
-- break;
--
-- DMP(skb->data, skb->len);
--
-- /* Send frame to TTY driver */
-- tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
-- len = tty->driver.write(tty, 0, skb->data, skb->len);
--
-- n_hci->hdev.stat.byte_tx += len;
--
-- DBG("sent %d", len);
--
-- if (len == skb->len) {
-- /* Full frame was sent */
-- kfree_skb(skb);
-- } else {
-- /* Subtract sent part and requeue */
-- skb_pull(skb, len);
-- skb_queue_head(&n_hci->txq, skb);
-- }
-- } while (test_bit(TRANS_WAKEUP, &n_hci->tx_state));
-- clear_bit(TRANS_SENDING, &n_hci->tx_state);
--
-- return 0;
--}
--
--/* Send frames from HCI layer */
--int n_hci_send_frame(struct sk_buff *skb)
--{
-- struct hci_dev* hdev = (struct hci_dev *) skb->dev;
-- struct tty_struct *tty;
-- struct n_hci *n_hci;
--
-- if (!hdev) {
-- ERR("Frame for uknown device (hdev=NULL)");
-- return -ENODEV;
-- }
--
-- if (!(hdev->flags & HCI_RUNNING))
-- return -EBUSY;
--
-- n_hci = (struct n_hci *) hdev->driver_data;
-- tty = n_hci2tty(n_hci);
--
-- DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
--
-- switch (skb->pkt_type) {
-- case HCI_COMMAND_PKT:
-- hdev->stat.cmd_tx++;
-- break;
--
-- case HCI_ACLDATA_PKT:
-- hdev->stat.acl_tx++;
-- break;
--
-- case HCI_SCODATA_PKT:
-- hdev->stat.cmd_tx++;
-- break;
-- };
--
-- /* Prepend skb with frame type and queue */
-- memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
-- skb_queue_tail(&n_hci->txq, skb);
--
-- n_hci_tx_wakeup(n_hci);
--
-- return 0;
--}
--
--/* ------ LDISC part ------ */
--
--/* n_hci_tty_open
-- *
-- * Called when line discipline changed to N_HCI.
-- *
-- * Arguments:
-- * tty pointer to tty info structure
-- * Return Value:
-- * 0 if success, otherwise error code
-- */
--static int n_hci_tty_open(struct tty_struct *tty)
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
-- struct hci_dev *hdev;
--
-- DBG("tty %p", tty);
--
-- if (n_hci)
-- return -EEXIST;
--
-- if (!(n_hci = kmalloc(sizeof(struct n_hci), GFP_KERNEL))) {
-- ERR("Can't allocate controll structure");
-- return -ENFILE;
-- }
-- memset(n_hci, 0, sizeof(struct n_hci));
--
-- /* Initialize and register HCI device */
-- hdev = &n_hci->hdev;
--
-- hdev->type = HCI_UART;
-- hdev->driver_data = n_hci;
--
-- hdev->open = n_hci_open;
-- hdev->close = n_hci_close;
-- hdev->flush = n_hci_flush;
-- hdev->send = n_hci_send_frame;
--
-- if (hci_register_dev(hdev) < 0) {
-- ERR("Can't register HCI device %s", hdev->name);
-- kfree(n_hci);
-- return -ENODEV;
-- }
--
-- tty->disc_data = n_hci;
-- n_hci->tty = tty;
--
-- spin_lock_init(&n_hci->rx_lock);
-- n_hci->rx_state = WAIT_PACKET_TYPE;
--
-- skb_queue_head_init(&n_hci->txq);
--
-- MOD_INC_USE_COUNT;
--
-- /* Flush any pending characters in the driver and discipline. */
-- if (tty->ldisc.flush_buffer)
-- tty->ldisc.flush_buffer(tty);
--
-- if (tty->driver.flush_buffer)
-- tty->driver.flush_buffer(tty);
--
-- return 0;
--}
--
--/* n_hci_tty_close()
-- *
-- * Called when the line discipline is changed to something
-- * else, the tty is closed, or the tty detects a hangup.
-- */
--static void n_hci_tty_close(struct tty_struct *tty)
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
-- struct hci_dev *hdev = &n_hci->hdev;
--
-- DBG("tty %p hdev %p", tty, hdev);
--
-- if (n_hci != NULL) {
-- n_hci_close(hdev);
--
-- if (hci_unregister_dev(hdev) < 0) {
-- ERR("Can't unregister HCI device %s",hdev->name);
-- }
--
-- hdev->driver_data = NULL;
-- tty->disc_data = NULL;
-- kfree(n_hci);
--
-- MOD_DEC_USE_COUNT;
-- }
--}
--
--/* n_hci_tty_wakeup()
-- *
-- * Callback for transmit wakeup. Called when low level
-- * device driver can accept more send data.
-- *
-- * Arguments: tty pointer to associated tty instance data
-- * Return Value: None
-- */
--static void n_hci_tty_wakeup( struct tty_struct *tty )
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
--
-- DBG("");
--
-- if (!n_hci)
-- return;
--
-- tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
--
-- if (tty != n_hci->tty)
-- return;
--
-- n_hci_tx_wakeup(n_hci);
--}
--
--/* n_hci_tty_room()
-- *
-- * Callback function from tty driver. Return the amount of
-- * space left in the receiver's buffer to decide if remote
-- * transmitter is to be throttled.
-- *
-- * Arguments: tty pointer to associated tty instance data
-- * Return Value: number of bytes left in receive buffer
-- */
--static int n_hci_tty_room (struct tty_struct *tty)
--{
-- return 65536;
--}
--
--static inline int n_hci_check_data_len(struct n_hci *n_hci, int len)
--{
-- register int room = skb_tailroom(n_hci->rx_skb);
--
-- DBG("len %d room %d", len, room);
-- if (!len) {
-- DMP(n_hci->rx_skb->data, n_hci->rx_skb->len);
-- hci_recv_frame(n_hci->rx_skb);
-- } else if (len > room) {
-- ERR("Data length is to large");
-- kfree_skb(n_hci->rx_skb);
-- n_hci->hdev.stat.err_rx++;
-- } else {
-- n_hci->rx_state = WAIT_DATA;
-- n_hci->rx_count = len;
-- return len;
-- }
--
-- n_hci->rx_state = WAIT_PACKET_TYPE;
-- n_hci->rx_skb = NULL;
-- n_hci->rx_count = 0;
-- return 0;
--}
--
--static inline void n_hci_rx(struct n_hci *n_hci, const __u8 * data, char *flags, int count)
--{
-- register const char *ptr;
-- hci_event_hdr *eh;
-- hci_acl_hdr *ah;
-- hci_sco_hdr *sh;
-- register int len, type, dlen;
--
-- DBG("count %d state %ld rx_count %ld", count, n_hci->rx_state, n_hci->rx_count);
--
-- n_hci->hdev.stat.byte_rx += count;
--
-- ptr = data;
-- while (count) {
-- if (n_hci->rx_count) {
-- len = MIN(n_hci->rx_count, count);
-- memcpy(skb_put(n_hci->rx_skb, len), ptr, len);
-- n_hci->rx_count -= len; count -= len; ptr += len;
--
-- if (n_hci->rx_count)
-- continue;
--
-- switch (n_hci->rx_state) {
-- case WAIT_DATA:
-- DBG("Complete data");
--
-- DMP(n_hci->rx_skb->data, n_hci->rx_skb->len);
--
-- hci_recv_frame(n_hci->rx_skb);
--
-- n_hci->rx_state = WAIT_PACKET_TYPE;
-- n_hci->rx_skb = NULL;
-- continue;
--
-- case WAIT_EVENT_HDR:
-- eh = (hci_event_hdr *) n_hci->rx_skb->data;
--
-- DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
--
-- n_hci_check_data_len(n_hci, eh->plen);
-- continue;
--
-- case WAIT_ACL_HDR:
-- ah = (hci_acl_hdr *) n_hci->rx_skb->data;
-- dlen = __le16_to_cpu(ah->dlen);
--
-- DBG("ACL header: dlen %d", dlen);
--
-- n_hci_check_data_len(n_hci, dlen);
-- continue;
--
-- case WAIT_SCO_HDR:
-- sh = (hci_sco_hdr *) n_hci->rx_skb->data;
--
-- DBG("SCO header: dlen %d", sh->dlen);
--
-- n_hci_check_data_len(n_hci, sh->dlen);
-- continue;
-- };
-- }
--
-- /* WAIT_PACKET_TYPE */
-- switch (*ptr) {
-- case HCI_EVENT_PKT:
-- DBG("Event packet");
-- n_hci->rx_state = WAIT_EVENT_HDR;
-- n_hci->rx_count = HCI_EVENT_HDR_SIZE;
-- type = HCI_EVENT_PKT;
-- break;
--
-- case HCI_ACLDATA_PKT:
-- DBG("ACL packet");
-- n_hci->rx_state = WAIT_ACL_HDR;
-- n_hci->rx_count = HCI_ACL_HDR_SIZE;
-- type = HCI_ACLDATA_PKT;
-- break;
--
-- case HCI_SCODATA_PKT:
-- DBG("SCO packet");
-- n_hci->rx_state = WAIT_SCO_HDR;
-- n_hci->rx_count = HCI_SCO_HDR_SIZE;
-- type = HCI_SCODATA_PKT;
-- break;
--
-- default:
-- ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
-- n_hci->hdev.stat.err_rx++;
-- ptr++; count--;
-- continue;
-- };
-- ptr++; count--;
--
-- /* Allocate packet */
-- if (!(n_hci->rx_skb = bluez_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC))) {
-- ERR("Can't allocate mem for new packet");
--
-- n_hci->rx_state = WAIT_PACKET_TYPE;
-- n_hci->rx_count = 0;
-- return;
-- }
-- n_hci->rx_skb->dev = (void *) &n_hci->hdev;
-- n_hci->rx_skb->pkt_type = type;
-- }
--}
--
--/* n_hci_tty_receive()
-- *
-- * Called by tty low level driver when receive data is
-- * available.
-- *
-- * Arguments: tty pointer to tty isntance data
-- * data pointer to received data
-- * flags pointer to flags for data
-- * count count of received data in bytes
-- *
-- * Return Value: None
-- */
--static void n_hci_tty_receive(struct tty_struct *tty, const __u8 * data, char *flags, int count)
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
--
-- if (!n_hci || tty != n_hci->tty)
-- return;
--
-- spin_lock(&n_hci->rx_lock);
-- n_hci_rx(n_hci, data, flags, count);
-- spin_unlock(&n_hci->rx_lock);
--
-- if (test_and_clear_bit(TTY_THROTTLED,&tty->flags) && tty->driver.unthrottle)
-- tty->driver.unthrottle(tty);
--}
--
--/* n_hci_tty_ioctl()
-- *
-- * Process IOCTL system call for the tty device.
-- *
-- * Arguments:
-- *
-- * tty pointer to tty instance data
-- * file pointer to open file object for device
-- * cmd IOCTL command code
-- * arg argument for IOCTL call (cmd dependent)
-- *
-- * Return Value: Command dependent
-- */
--static int n_hci_tty_ioctl (struct tty_struct *tty, struct file * file,
-- unsigned int cmd, unsigned long arg)
--{
-- struct n_hci *n_hci = tty2n_hci(tty);
-- int error = 0;
--
-- DBG("");
--
-- /* Verify the status of the device */
-- if (!n_hci)
-- return -EBADF;
--
-- switch (cmd) {
-- default:
-- error = n_tty_ioctl(tty, file, cmd, arg);
-- break;
-- };
--
-- return error;
--}
--
--/*
-- * We don't provide read/write/poll interface for user space.
-- */
--static ssize_t n_hci_tty_read(struct tty_struct *tty, struct file *file, unsigned char *buf, size_t nr)
--{
-- return 0;
--}
--static ssize_t n_hci_tty_write(struct tty_struct *tty, struct file *file, const unsigned char *data, size_t count)
--{
-- return 0;
--}
--static unsigned int n_hci_tty_poll(struct tty_struct *tty, struct file *filp, poll_table *wait)
--{
-- return 0;
--}
--
--int __init n_hci_init(void)
--{
-- static struct tty_ldisc n_hci_ldisc;
-- int err;
--
-- INF("BlueZ HCI UART driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
--
-- /* Register the tty discipline */
--
-- memset(&n_hci_ldisc, 0, sizeof (n_hci_ldisc));
-- n_hci_ldisc.magic = TTY_LDISC_MAGIC;
-- n_hci_ldisc.name = "n_hci";
-- n_hci_ldisc.open = n_hci_tty_open;
-- n_hci_ldisc.close = n_hci_tty_close;
-- n_hci_ldisc.read = n_hci_tty_read;
-- n_hci_ldisc.write = n_hci_tty_write;
-- n_hci_ldisc.ioctl = n_hci_tty_ioctl;
-- n_hci_ldisc.poll = n_hci_tty_poll;
-- n_hci_ldisc.receive_room= n_hci_tty_room;
-- n_hci_ldisc.receive_buf = n_hci_tty_receive;
-- n_hci_ldisc.write_wakeup= n_hci_tty_wakeup;
--
-- if ((err = tty_register_ldisc(N_HCI, &n_hci_ldisc))) {
-- ERR("Can't register HCI line discipline (%d)", err);
-- return err;
-- }
--
-- return 0;
--}
--
--void n_hci_cleanup(void)
--{
-- int err;
--
-- /* Release tty registration of line discipline */
-- if ((err = tty_register_ldisc(N_HCI, NULL)))
-- ERR("Can't unregister HCI line discipline (%d)", err);
--}
--
--module_init(n_hci_init);
--module_exit(n_hci_cleanup);
--
--MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
--MODULE_DESCRIPTION("BlueZ HCI UART driver ver " VERSION);
--MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/drivers/bluetooth/hci_uart.h linux-2.4.18-mh9/drivers/bluetooth/hci_uart.h
---- linux-2.4.18/drivers/bluetooth/hci_uart.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/drivers/bluetooth/hci_uart.h Mon Aug 25 18:38:10 2003
-@@ -0,0 +1,81 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef N_HCI
-+#define N_HCI 15
-+#endif
-+
-+/* Ioctls */
-+#define HCIUARTSETPROTO _IOW('U', 200, int)
-+#define HCIUARTGETPROTO _IOR('U', 201, int)
-+
-+/* UART protocols */
-+#define HCI_UART_MAX_PROTO 3
-+
-+#define HCI_UART_H4 0
-+#define HCI_UART_BCSP 1
-+#define HCI_UART_NCSP 2
-+
-+#ifdef __KERNEL__
-+struct hci_uart;
-+
-+struct hci_uart_proto {
-+ unsigned int id;
-+ int (*open)(struct hci_uart *hu);
-+ int (*close)(struct hci_uart *hu);
-+ int (*flush)(struct hci_uart *hu);
-+ int (*recv)(struct hci_uart *hu, void *data, int len);
-+ int (*enqueue)(struct hci_uart *hu, struct sk_buff *skb);
-+ struct sk_buff *(*dequeue)(struct hci_uart *hu);
-+};
-+
-+struct hci_uart {
-+ struct tty_struct *tty;
-+ struct hci_dev hdev;
-+ unsigned long flags;
-+
-+ struct hci_uart_proto *proto;
-+ void *priv;
-+
-+ struct sk_buff *tx_skb;
-+ unsigned long tx_state;
-+ spinlock_t rx_lock;
-+};
-+
-+/* HCI_UART flag bits */
-+#define HCI_UART_PROTO_SET 0
-+
-+/* TX states */
-+#define HCI_UART_SENDING 1
-+#define HCI_UART_TX_WAKEUP 2
-+
-+int hci_uart_register_proto(struct hci_uart_proto *p);
-+int hci_uart_unregister_proto(struct hci_uart_proto *p);
-+int hci_uart_tx_wakeup(struct hci_uart *hu);
-+
-+#endif /* __KERNEL__ */
-diff -urN linux-2.4.18/drivers/bluetooth/hci_usb.c linux-2.4.18-mh9/drivers/bluetooth/hci_usb.c
---- linux-2.4.18/drivers/bluetooth/hci_usb.c Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/drivers/bluetooth/hci_usb.c Mon Aug 25 18:38:12 2003
-@@ -1,9 +1,10 @@
- /*
-- BlueZ - Bluetooth protocol stack for Linux
-+ HCI USB driver for Linux Bluetooth protocol stack (BlueZ)
- Copyright (C) 2000-2001 Qualcomm Incorporated
--
- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-
-+ Copyright (C) 2003 Maxim Krasnyansky <maxk@qualcomm.com>
-+
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as
- published by the Free Software Foundation;
-@@ -23,598 +24,901 @@
- */
-
- /*
-- * BlueZ HCI USB driver.
- * Based on original USB Bluetooth driver for Linux kernel
- * Copyright (c) 2000 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (c) 2000 Mark Douglas Corner <mcorner@umich.edu>
- *
-- * $Id$
-+ * $Id$
- */
--#define VERSION "1.0"
-+#define VERSION "2.4"
-
- #include <linux/config.h>
- #include <linux/module.h>
-
- #include <linux/version.h>
--#include <linux/config.h>
- #include <linux/kernel.h>
- #include <linux/init.h>
- #include <linux/sched.h>
-+#include <linux/unistd.h>
- #include <linux/types.h>
--#include <linux/fcntl.h>
- #include <linux/interrupt.h>
--#include <linux/ptrace.h>
--#include <linux/poll.h>
-
- #include <linux/slab.h>
--#include <linux/tty.h>
- #include <linux/errno.h>
- #include <linux/string.h>
--#include <linux/signal.h>
--#include <linux/ioctl.h>
- #include <linux/skbuff.h>
-
- #include <linux/usb.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/hci_usb.h>
-+
-+#include "hci_usb.h"
-
- #ifndef HCI_USB_DEBUG
--#undef DBG
--#define DBG( A... )
--#undef DMP
--#define DMP( A... )
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#undef BT_DMP
-+#define BT_DMP( A... )
- #endif
-
--static struct usb_device_id usb_bluetooth_ids [] = {
-+#ifndef CONFIG_BLUEZ_USB_ZERO_PACKET
-+#undef USB_ZERO_PACKET
-+#define USB_ZERO_PACKET 0
-+#endif
-+
-+static struct usb_driver hci_usb_driver;
-+
-+static struct usb_device_id bluetooth_ids[] = {
-+ /* Generic Bluetooth USB device */
- { USB_DEVICE_INFO(HCI_DEV_CLASS, HCI_DEV_SUBCLASS, HCI_DEV_PROTOCOL) },
-+
-+ /* Ericsson with non-standard id */
-+ { USB_DEVICE(0x0bdb, 0x1002) },
-+
-+ /* Bluetooth Ultraport Module from IBM */
-+ { USB_DEVICE(0x04bf, 0x030a) },
-+
- { } /* Terminating entry */
- };
-
--MODULE_DEVICE_TABLE (usb, usb_bluetooth_ids);
-+MODULE_DEVICE_TABLE (usb, bluetooth_ids);
-
--static int hci_usb_ctrl_msg(struct hci_usb *husb, struct sk_buff *skb);
--static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb);
-+static struct usb_device_id ignore_ids[] = {
-+ /* Broadcom BCM2033 without firmware */
-+ { USB_DEVICE(0x0a5c, 0x2033) },
-
--static void hci_usb_unlink_urbs(struct hci_usb *husb)
--{
-- usb_unlink_urb(husb->read_urb);
-- usb_unlink_urb(husb->intr_urb);
-- usb_unlink_urb(husb->ctrl_urb);
-- usb_unlink_urb(husb->write_urb);
--}
-+ { } /* Terminating entry */
-+};
-
--static void hci_usb_free_bufs(struct hci_usb *husb)
-+struct _urb *_urb_alloc(int isoc, int gfp)
- {
-- if (husb->read_urb) {
-- if (husb->read_urb->transfer_buffer)
-- kfree(husb->read_urb->transfer_buffer);
-- usb_free_urb(husb->read_urb);
-- }
--
-- if (husb->intr_urb) {
-- if (husb->intr_urb->transfer_buffer)
-- kfree(husb->intr_urb->transfer_buffer);
-- usb_free_urb(husb->intr_urb);
-+ struct _urb *_urb = kmalloc(sizeof(struct _urb) +
-+ sizeof(iso_packet_descriptor_t) * isoc, gfp);
-+ if (_urb) {
-+ memset(_urb, 0, sizeof(*_urb));
-+ spin_lock_init(&_urb->urb.lock);
-+ }
-+ return _urb;
-+}
-+
-+struct _urb *_urb_dequeue(struct _urb_queue *q)
-+{
-+ struct _urb *_urb = NULL;
-+ unsigned long flags;
-+ spin_lock_irqsave(&q->lock, flags);
-+ {
-+ struct list_head *head = &q->head;
-+ struct list_head *next = head->next;
-+ if (next != head) {
-+ _urb = list_entry(next, struct _urb, list);
-+ list_del(next); _urb->queue = NULL;
-+ }
- }
-+ spin_unlock_irqrestore(&q->lock, flags);
-+ return _urb;
-+}
-
-- if (husb->ctrl_urb)
-- usb_free_urb(husb->ctrl_urb);
-+static void hci_usb_rx_complete(struct urb *urb);
-+static void hci_usb_tx_complete(struct urb *urb);
-
-- if (husb->write_urb)
-- usb_free_urb(husb->write_urb);
-+#define __pending_tx(husb, type) (&husb->pending_tx[type-1])
-+#define __pending_q(husb, type) (&husb->pending_q[type-1])
-+#define __completed_q(husb, type) (&husb->completed_q[type-1])
-+#define __transmit_q(husb, type) (&husb->transmit_q[type-1])
-+#define __reassembly(husb, type) (husb->reassembly[type-1])
-
-- if (husb->intr_skb)
-- kfree_skb(husb->intr_skb);
-+static inline struct _urb *__get_completed(struct hci_usb *husb, int type)
-+{
-+ return _urb_dequeue(__completed_q(husb, type));
- }
-
--/* ------- Interface to HCI layer ------ */
--/* Initialize device */
--int hci_usb_open(struct hci_dev *hdev)
-+static void __fill_isoc_desc(struct urb *urb, int len, int mtu)
- {
-- struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-- int status;
--
-- DBG("%s", hdev->name);
--
-- husb->read_urb->dev = husb->udev;
-- if ((status = usb_submit_urb(husb->read_urb)))
-- DBG("read submit failed. %d", status);
-+ int offset = 0, i;
-
-- husb->intr_urb->dev = husb->udev;
-- if ((status = usb_submit_urb(husb->intr_urb)))
-- DBG("interrupt submit failed. %d", status);
-+ BT_DBG("len %d mtu %d", len, mtu);
-
-- hdev->flags |= HCI_RUNNING;
--
-- return 0;
-+ for (i=0; i < HCI_MAX_ISOC_FRAMES && len >= mtu; i++, offset += mtu, len -= mtu) {
-+ urb->iso_frame_desc[i].offset = offset;
-+ urb->iso_frame_desc[i].length = mtu;
-+ BT_DBG("desc %d offset %d len %d", i, offset, mtu);
-+ }
-+ if (len && i < HCI_MAX_ISOC_FRAMES) {
-+ urb->iso_frame_desc[i].offset = offset;
-+ urb->iso_frame_desc[i].length = len;
-+ BT_DBG("desc %d offset %d len %d", i, offset, len);
-+ i++;
-+ }
-+ urb->number_of_packets = i;
- }
-
--/* Reset device */
--int hci_usb_flush(struct hci_dev *hdev)
-+static int hci_usb_intr_rx_submit(struct hci_usb *husb)
- {
-- struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-+ struct _urb *_urb;
-+ struct urb *urb;
-+ int err, pipe, interval, size;
-+ void *buf;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s", husb->hdev.name);
-
-- /* Drop TX queues */
-- skb_queue_purge(&husb->tx_ctrl_q);
-- skb_queue_purge(&husb->tx_write_q);
-+ size = husb->intr_in_ep->wMaxPacketSize;
-
-- return 0;
-+ buf = kmalloc(size, GFP_ATOMIC);
-+ if (!buf)
-+ return -ENOMEM;
-+
-+ _urb = _urb_alloc(0, GFP_ATOMIC);
-+ if (!_urb) {
-+ kfree(buf);
-+ return -ENOMEM;
-+ }
-+ _urb->type = HCI_EVENT_PKT;
-+ _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
-+
-+ urb = &_urb->urb;
-+ pipe = usb_rcvintpipe(husb->udev, husb->intr_in_ep->bEndpointAddress);
-+ interval = husb->intr_in_ep->bInterval;
-+ FILL_INT_URB(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb, interval);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s intr rx submit failed urb %p err %d",
-+ husb->hdev.name, urb, err);
-+ _urb_unlink(_urb);
-+ _urb_free(_urb);
-+ kfree(buf);
-+ }
-+ return err;
- }
-
--/* Close device */
--int hci_usb_close(struct hci_dev *hdev)
-+static int hci_usb_bulk_rx_submit(struct hci_usb *husb)
- {
-- struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-+ struct _urb *_urb;
-+ struct urb *urb;
-+ int err, pipe, size = HCI_MAX_FRAME_SIZE;
-+ void *buf;
-
-- DBG("%s", hdev->name);
-+ buf = kmalloc(size, GFP_ATOMIC);
-+ if (!buf)
-+ return -ENOMEM;
-
-- hdev->flags &= ~HCI_RUNNING;
-- hci_usb_unlink_urbs(husb);
-+ _urb = _urb_alloc(0, GFP_ATOMIC);
-+ if (!_urb) {
-+ kfree(buf);
-+ return -ENOMEM;
-+ }
-+ _urb->type = HCI_ACLDATA_PKT;
-+ _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
-
-- hci_usb_flush(hdev);
-+ urb = &_urb->urb;
-+ pipe = usb_rcvbulkpipe(husb->udev, husb->bulk_in_ep->bEndpointAddress);
-+ FILL_BULK_URB(urb, husb->udev, pipe, buf, size, hci_usb_rx_complete, husb);
-+ urb->transfer_flags = USB_QUEUE_BULK;
-
-- return 0;
-+ BT_DBG("%s urb %p", husb->hdev.name, urb);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s bulk rx submit failed urb %p err %d",
-+ husb->hdev.name, urb, err);
-+ _urb_unlink(_urb);
-+ _urb_free(_urb);
-+ kfree(buf);
-+ }
-+ return err;
- }
-
--void hci_usb_ctrl_wakeup(struct hci_usb *husb)
-+#ifdef CONFIG_BLUEZ_USB_SCO
-+static int hci_usb_isoc_rx_submit(struct hci_usb *husb)
- {
-- struct sk_buff *skb;
--
-- if (test_and_set_bit(HCI_TX_CTRL, &husb->tx_state))
-- return;
-+ struct _urb *_urb;
-+ struct urb *urb;
-+ int err, mtu, size;
-+ void *buf;
-
-- DBG("%s", husb->hdev.name);
-+ mtu = husb->isoc_in_ep->wMaxPacketSize;
-+ size = mtu * HCI_MAX_ISOC_FRAMES;
-
-- if (!(skb = skb_dequeue(&husb->tx_ctrl_q)))
-- goto done;
-+ buf = kmalloc(size, GFP_ATOMIC);
-+ if (!buf)
-+ return -ENOMEM;
-
-- if (hci_usb_ctrl_msg(husb, skb)){
-- kfree_skb(skb);
-- goto done;
-+ _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
-+ if (!_urb) {
-+ kfree(buf);
-+ return -ENOMEM;
- }
-+ _urb->type = HCI_SCODATA_PKT;
-+ _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
-
-- DMP(skb->data, skb->len);
-+ urb = &_urb->urb;
-
-- husb->hdev.stat.byte_tx += skb->len;
-- return;
-+ urb->context = husb;
-+ urb->dev = husb->udev;
-+ urb->pipe = usb_rcvisocpipe(husb->udev, husb->isoc_in_ep->bEndpointAddress);
-+ urb->complete = hci_usb_rx_complete;
-
--done:
-- clear_bit(HCI_TX_CTRL, &husb->tx_state);
-- return;
-+ urb->transfer_buffer_length = size;
-+ urb->transfer_buffer = buf;
-+ urb->transfer_flags = USB_ISO_ASAP;
-+
-+ __fill_isoc_desc(urb, size, mtu);
-+
-+ BT_DBG("%s urb %p", husb->hdev.name, urb);
-+
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s isoc rx submit failed urb %p err %d",
-+ husb->hdev.name, urb, err);
-+ _urb_unlink(_urb);
-+ _urb_free(_urb);
-+ kfree(buf);
-+ }
-+ return err;
- }
-+#endif
-
--void hci_usb_write_wakeup(struct hci_usb *husb)
-+/* Initialize device */
-+static int hci_usb_open(struct hci_dev *hdev)
- {
-- struct sk_buff *skb;
-+ struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-+ int i, err;
-+ unsigned long flags;
-
-- if (test_and_set_bit(HCI_TX_WRITE, &husb->tx_state))
-- return;
-+ BT_DBG("%s", hdev->name);
-
-- DBG("%s", husb->hdev.name);
-+ if (test_and_set_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-
-- if (!(skb = skb_dequeue(&husb->tx_write_q)))
-- goto done;
-+ MOD_INC_USE_COUNT;
-
-- if (hci_usb_write_msg(husb, skb)) {
-- skb_queue_head(&husb->tx_write_q, skb);
-- goto done;
-+ write_lock_irqsave(&husb->completion_lock, flags);
-+
-+ err = hci_usb_intr_rx_submit(husb);
-+ if (!err) {
-+ for (i = 0; i < HCI_MAX_BULK_RX; i++)
-+ hci_usb_bulk_rx_submit(husb);
-+
-+#ifdef CONFIG_BLUEZ_USB_SCO
-+ if (husb->isoc_iface)
-+ for (i = 0; i < HCI_MAX_ISOC_RX; i++)
-+ hci_usb_isoc_rx_submit(husb);
-+#endif
-+ } else {
-+ clear_bit(HCI_RUNNING, &hdev->flags);
-+ MOD_DEC_USE_COUNT;
- }
-
-- DMP(skb->data, skb->len);
-+ write_unlock_irqrestore(&husb->completion_lock, flags);
-+ return err;
-+}
-+
-+/* Reset device */
-+static int hci_usb_flush(struct hci_dev *hdev)
-+{
-+ struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-+ int i;
-
-- husb->hdev.stat.byte_tx += skb->len;
-- return;
-+ BT_DBG("%s", hdev->name);
-
--done:
-- clear_bit(HCI_TX_WRITE, &husb->tx_state);
-- return;
-+ for (i=0; i < 4; i++)
-+ skb_queue_purge(&husb->transmit_q[i]);
-+ return 0;
- }
-
--/* Send frames from HCI layer */
--int hci_usb_send_frame(struct sk_buff *skb)
-+static void hci_usb_unlink_urbs(struct hci_usb *husb)
- {
-- struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-- struct hci_usb *husb;
-+ int i;
-
-- if (!hdev) {
-- ERR("frame for uknown device (hdev=NULL)");
-- return -ENODEV;
-+ BT_DBG("%s", husb->hdev.name);
-+
-+ for (i=0; i < 4; i++) {
-+ struct _urb *_urb;
-+ struct urb *urb;
-+
-+ /* Kill pending requests */
-+ while ((_urb = _urb_dequeue(&husb->pending_q[i]))) {
-+ urb = &_urb->urb;
-+ BT_DBG("%s unlinking _urb %p type %d urb %p",
-+ husb->hdev.name, _urb, _urb->type, urb);
-+ usb_unlink_urb(urb);
-+ _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
-+ }
-+
-+ /* Release completed requests */
-+ while ((_urb = _urb_dequeue(&husb->completed_q[i]))) {
-+ urb = &_urb->urb;
-+ BT_DBG("%s freeing _urb %p type %d urb %p",
-+ husb->hdev.name, _urb, _urb->type, urb);
-+ if (urb->setup_packet)
-+ kfree(urb->setup_packet);
-+ if (urb->transfer_buffer)
-+ kfree(urb->transfer_buffer);
-+ _urb_free(_urb);
-+ }
-+
-+ /* Release reassembly buffers */
-+ if (husb->reassembly[i]) {
-+ kfree_skb(husb->reassembly[i]);
-+ husb->reassembly[i] = NULL;
-+ }
- }
-+}
-
-- if (!(hdev->flags & HCI_RUNNING))
-+/* Close device */
-+static int hci_usb_close(struct hci_dev *hdev)
-+{
-+ struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-+ unsigned long flags;
-+
-+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
- return 0;
-
-- husb = (struct hci_usb *) hdev->driver_data;
-+ BT_DBG("%s", hdev->name);
-
-- DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-+ write_lock_irqsave(&husb->completion_lock, flags);
-+
-+ hci_usb_unlink_urbs(husb);
-+ hci_usb_flush(hdev);
-
-- switch (skb->pkt_type) {
-- case HCI_COMMAND_PKT:
-- skb_queue_tail(&husb->tx_ctrl_q, skb);
-- hci_usb_ctrl_wakeup(husb);
-- hdev->stat.cmd_tx++;
-- return 0;
--
-- case HCI_ACLDATA_PKT:
-- skb_queue_tail(&husb->tx_write_q, skb);
-- hci_usb_write_wakeup(husb);
-- hdev->stat.acl_tx++;
-- return 0;
--
-- case HCI_SCODATA_PKT:
-- return -EOPNOTSUPP;
-- };
-+ write_unlock_irqrestore(&husb->completion_lock, flags);
-
-+ MOD_DEC_USE_COUNT;
- return 0;
- }
-
--/* ---------- USB ------------- */
--
--static void hci_usb_ctrl(struct urb *urb)
-+static int __tx_submit(struct hci_usb *husb, struct _urb *_urb)
- {
-- struct sk_buff *skb = (struct sk_buff *) urb->context;
-- struct hci_dev *hdev;
-- struct hci_usb *husb;
--
-- if (!skb)
-- return;
-- hdev = (struct hci_dev *) skb->dev;
-- husb = (struct hci_usb *) hdev->driver_data;
-+ struct urb *urb = &_urb->urb;
-+ int err;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s urb %p type %d", husb->hdev.name, urb, _urb->type);
-+
-+ _urb_queue_tail(__pending_q(husb, _urb->type), _urb);
-+ err = usb_submit_urb(urb);
-+ if (err) {
-+ BT_ERR("%s tx submit failed urb %p type %d err %d",
-+ husb->hdev.name, urb, _urb->type, err);
-+ _urb_unlink(_urb);
-+ _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
-+ } else
-+ atomic_inc(__pending_tx(husb, _urb->type));
-+
-+ return err;
-+}
-+
-+static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
-+{
-+ struct _urb *_urb = __get_completed(husb, skb->pkt_type);
-+ devrequest *dr;
-+ struct urb *urb;
-+
-+ if (!_urb) {
-+ _urb = _urb_alloc(0, GFP_ATOMIC);
-+ if (!_urb)
-+ return -ENOMEM;
-+ _urb->type = skb->pkt_type;
-+
-+ dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
-+ if (!dr) {
-+ _urb_free(_urb);
-+ return -ENOMEM;
-+ }
-+ } else
-+ dr = (void *) _urb->urb.setup_packet;
-
-- if (urb->status)
-- DBG("%s ctrl status: %d", hdev->name, urb->status);
-+ dr->requesttype = HCI_CTRL_REQ;
-+ dr->request = 0;
-+ dr->index = 0;
-+ dr->value = 0;
-+ dr->length = __cpu_to_le16(skb->len);
-
-- clear_bit(HCI_TX_CTRL, &husb->tx_state);
-- kfree_skb(skb);
-+ urb = &_urb->urb;
-+ FILL_CONTROL_URB(urb, husb->udev, usb_sndctrlpipe(husb->udev, 0),
-+ (void *) dr, skb->data, skb->len, hci_usb_tx_complete, husb);
-
-- /* Wake up device */
-- hci_usb_ctrl_wakeup(husb);
-+ BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
-+
-+ _urb->priv = skb;
-+ return __tx_submit(husb, _urb);
- }
-
--static void hci_usb_bulk_write(struct urb *urb)
-+static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
- {
-- struct sk_buff *skb = (struct sk_buff *) urb->context;
-- struct hci_dev *hdev;
-- struct hci_usb *husb;
--
-- if (!skb)
-- return;
-- hdev = (struct hci_dev *) skb->dev;
-- husb = (struct hci_usb *) hdev->driver_data;
-+ struct _urb *_urb = __get_completed(husb, skb->pkt_type);
-+ struct urb *urb;
-+ int pipe;
-
-- DBG("%s", hdev->name);
--
-- if (urb->status)
-- DBG("%s bulk write status: %d", hdev->name, urb->status);
-+ if (!_urb) {
-+ _urb = _urb_alloc(0, GFP_ATOMIC);
-+ if (!_urb)
-+ return -ENOMEM;
-+ _urb->type = skb->pkt_type;
-+ }
-
-- clear_bit(HCI_TX_WRITE, &husb->tx_state);
-- kfree_skb(skb);
-+ urb = &_urb->urb;
-+ pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep->bEndpointAddress);
-+ FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,
-+ hci_usb_tx_complete, husb);
-+ urb->transfer_flags = USB_QUEUE_BULK | USB_ZERO_PACKET;
-
-- /* Wake up device */
-- hci_usb_write_wakeup(husb);
-+ BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
-
-- return;
-+ _urb->priv = skb;
-+ return __tx_submit(husb, _urb);
- }
-
--static void hci_usb_intr(struct urb *urb)
-+#ifdef CONFIG_BLUEZ_USB_SCO
-+static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb)
- {
-- struct hci_usb *husb = (struct hci_usb *) urb->context;
-- unsigned char *data = urb->transfer_buffer;
-- register int count = urb->actual_length;
-- register struct sk_buff *skb = husb->intr_skb;
-- hci_event_hdr *eh;
-- register int len;
-+ struct _urb *_urb = __get_completed(husb, skb->pkt_type);
-+ struct urb *urb;
-+
-+ if (!_urb) {
-+ _urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
-+ if (!_urb)
-+ return -ENOMEM;
-+ _urb->type = skb->pkt_type;
-+ }
-
-- if (!husb)
-- return;
-+ BT_DBG("%s skb %p len %d", husb->hdev.name, skb, skb->len);
-
-- DBG("%s count %d", husb->hdev.name, count);
-+ urb = &_urb->urb;
-+
-+ urb->context = husb;
-+ urb->dev = husb->udev;
-+ urb->pipe = usb_sndisocpipe(husb->udev, husb->isoc_out_ep->bEndpointAddress);
-+ urb->complete = hci_usb_tx_complete;
-+ urb->transfer_flags = USB_ISO_ASAP;
-
-- if (urb->status || !count) {
-- DBG("%s intr status %d, count %d", husb->hdev.name, urb->status, count);
-- return;
-- }
-+ urb->transfer_buffer = skb->data;
-+ urb->transfer_buffer_length = skb->len;
-+
-+ __fill_isoc_desc(urb, skb->len, husb->isoc_out_ep->wMaxPacketSize);
-
-- /* Do we really have to handle continuations here ? */
-- if (!skb) {
-- /* New frame */
-- if (count < HCI_EVENT_HDR_SIZE) {
-- DBG("%s bad frame len %d", husb->hdev.name, count);
-- return;
-- }
-+ _urb->priv = skb;
-+ return __tx_submit(husb, _urb);
-+}
-+#endif
-+
-+static void hci_usb_tx_process(struct hci_usb *husb)
-+{
-+ struct sk_buff_head *q;
-+ struct sk_buff *skb;
-
-- eh = (hci_event_hdr *) data;
-- len = eh->plen + HCI_EVENT_HDR_SIZE;
-+ BT_DBG("%s", husb->hdev.name);
-
-- if (count > len) {
-- DBG("%s corrupted frame, len %d", husb->hdev.name, count);
-- return;
-+ do {
-+ clear_bit(HCI_USB_TX_WAKEUP, &husb->state);
-+
-+ /* Process command queue */
-+ q = __transmit_q(husb, HCI_COMMAND_PKT);
-+ if (!atomic_read(__pending_tx(husb, HCI_COMMAND_PKT)) &&
-+ (skb = skb_dequeue(q))) {
-+ if (hci_usb_send_ctrl(husb, skb) < 0)
-+ skb_queue_head(q, skb);
- }
-
-- /* Allocate skb */
-- if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {
-- ERR("Can't allocate mem for new packet");
-- return;
-+#ifdef CONFIG_BLUEZ_USB_SCO
-+ /* Process SCO queue */
-+ q = __transmit_q(husb, HCI_SCODATA_PKT);
-+ if (atomic_read(__pending_tx(husb, HCI_SCODATA_PKT)) < HCI_MAX_ISOC_TX &&
-+ (skb = skb_dequeue(q))) {
-+ if (hci_usb_send_isoc(husb, skb) < 0)
-+ skb_queue_head(q, skb);
-+ }
-+#endif
-+
-+ /* Process ACL queue */
-+ q = __transmit_q(husb, HCI_ACLDATA_PKT);
-+ while (atomic_read(__pending_tx(husb, HCI_ACLDATA_PKT)) < HCI_MAX_BULK_TX &&
-+ (skb = skb_dequeue(q))) {
-+ if (hci_usb_send_bulk(husb, skb) < 0) {
-+ skb_queue_head(q, skb);
-+ break;
-+ }
- }
-- skb->dev = (void *) &husb->hdev;
-- skb->pkt_type = HCI_EVENT_PKT;
-+ } while(test_bit(HCI_USB_TX_WAKEUP, &husb->state));
-+}
-
-- husb->intr_skb = skb;
-- husb->intr_count = len;
-- } else {
-- /* Continuation */
-- if (count > husb->intr_count) {
-- ERR("%s bad frame len %d (expected %d)", husb->hdev.name, count, husb->intr_count);
-+static inline void hci_usb_tx_wakeup(struct hci_usb *husb)
-+{
-+ /* Serialize TX queue processing to avoid data reordering */
-+ if (!test_and_set_bit(HCI_USB_TX_PROCESS, &husb->state)) {
-+ hci_usb_tx_process(husb);
-+ clear_bit(HCI_USB_TX_PROCESS, &husb->state);
-+ } else
-+ set_bit(HCI_USB_TX_WAKEUP, &husb->state);
-+}
-
-- kfree_skb(skb);
-- husb->intr_skb = NULL;
-- husb->intr_count = 0;
-- return;
-- }
-+/* Send frames from HCI layer */
-+static int hci_usb_send_frame(struct sk_buff *skb)
-+{
-+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-+ struct hci_usb *husb;
-+
-+ if (!hdev) {
-+ BT_ERR("frame for uknown device (hdev=NULL)");
-+ return -ENODEV;
- }
-
-- memcpy(skb_put(skb, count), data, count);
-- husb->intr_count -= count;
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return -EBUSY;
-
-- DMP(data, count);
-+ BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-
-- if (!husb->intr_count) {
-- /* Got complete frame */
-+ husb = (struct hci_usb *) hdev->driver_data;
-
-- husb->hdev.stat.byte_rx += skb->len;
-- hci_recv_frame(skb);
-+ switch (skb->pkt_type) {
-+ case HCI_COMMAND_PKT:
-+ hdev->stat.cmd_tx++;
-+ break;
-+
-+ case HCI_ACLDATA_PKT:
-+ hdev->stat.acl_tx++;
-+ break;
-+
-+#ifdef CONFIG_BLUEZ_USB_SCO
-+ case HCI_SCODATA_PKT:
-+ hdev->stat.sco_tx++;
-+ break;
-+#endif
-
-- husb->intr_skb = NULL;
-+ default:
-+ kfree_skb(skb);
-+ return 0;
- }
-+
-+ read_lock(&husb->completion_lock);
-+
-+ skb_queue_tail(__transmit_q(husb, skb->pkt_type), skb);
-+ hci_usb_tx_wakeup(husb);
-+
-+ read_unlock(&husb->completion_lock);
-+ return 0;
- }
-
--static void hci_usb_bulk_read(struct urb *urb)
-+static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int count)
- {
-- struct hci_usb *husb = (struct hci_usb *) urb->context;
-- unsigned char *data = urb->transfer_buffer;
-- int count = urb->actual_length, status;
-- struct sk_buff *skb;
-- hci_acl_hdr *ah;
-- register __u16 dlen;
--
-- if (!husb)
-- return;
-+ BT_DBG("%s type %d data %p count %d", husb->hdev.name, type, data, count);
-
-- DBG("%s status %d, count %d, flags %x", husb->hdev.name, urb->status, count, urb->transfer_flags);
-+ husb->hdev.stat.byte_rx += count;
-
-- if (urb->status) {
-- /* Do not re-submit URB on critical errors */
-- switch (urb->status) {
-- case -ENOENT:
-- return;
-- default:
-- goto resubmit;
-- };
-- }
-- if (!count)
-- goto resubmit;
-+ while (count) {
-+ struct sk_buff *skb = __reassembly(husb, type);
-+ struct { int expect; } *scb;
-+ int len = 0;
-+
-+ if (!skb) {
-+ /* Start of the frame */
-+
-+ switch (type) {
-+ case HCI_EVENT_PKT:
-+ if (count >= HCI_EVENT_HDR_SIZE) {
-+ hci_event_hdr *h = data;
-+ len = HCI_EVENT_HDR_SIZE + h->plen;
-+ } else
-+ return -EILSEQ;
-+ break;
-
-- DMP(data, count);
-+ case HCI_ACLDATA_PKT:
-+ if (count >= HCI_ACL_HDR_SIZE) {
-+ hci_acl_hdr *h = data;
-+ len = HCI_ACL_HDR_SIZE + __le16_to_cpu(h->dlen);
-+ } else
-+ return -EILSEQ;
-+ break;
-+#ifdef CONFIG_BLUEZ_USB_SCO
-+ case HCI_SCODATA_PKT:
-+ if (count >= HCI_SCO_HDR_SIZE) {
-+ hci_sco_hdr *h = data;
-+ len = HCI_SCO_HDR_SIZE + h->dlen;
-+ } else
-+ return -EILSEQ;
-+ break;
-+#endif
-+ }
-+ BT_DBG("new packet len %d", len);
-+
-+ skb = bluez_skb_alloc(len, GFP_ATOMIC);
-+ if (!skb) {
-+ BT_ERR("%s no memory for the packet", husb->hdev.name);
-+ return -ENOMEM;
-+ }
-+ skb->dev = (void *) &husb->hdev;
-+ skb->pkt_type = type;
-+
-+ __reassembly(husb, type) = skb;
-+
-+ scb = (void *) skb->cb;
-+ scb->expect = len;
-+ } else {
-+ /* Continuation */
-+ scb = (void *) skb->cb;
-+ len = scb->expect;
-+ }
-
-- ah = (hci_acl_hdr *) data;
-- dlen = le16_to_cpu(ah->dlen);
-+ len = min(len, count);
-+
-+ memcpy(skb_put(skb, len), data, len);
-+
-+ scb->expect -= len;
-+ if (!scb->expect) {
-+ /* Complete frame */
-+ __reassembly(husb, type) = NULL;
-+ hci_recv_frame(skb);
-+ }
-
-- /* Verify frame len and completeness */
-- if ((count - HCI_ACL_HDR_SIZE) != dlen) {
-- ERR("%s corrupted ACL packet: count %d, plen %d", husb->hdev.name, count, dlen);
-- goto resubmit;
-+ count -= len; data += len;
- }
-+ return 0;
-+}
-
-- /* Allocate packet */
-- if (!(skb = bluez_skb_alloc(count, GFP_ATOMIC))) {
-- ERR("Can't allocate mem for new packet");
-- goto resubmit;
-- }
-+static void hci_usb_rx_complete(struct urb *urb)
-+{
-+ struct _urb *_urb = container_of(urb, struct _urb, urb);
-+ struct hci_usb *husb = (void *) urb->context;
-+ struct hci_dev *hdev = &husb->hdev;
-+ int err, count = urb->actual_length;
-
-- memcpy(skb_put(skb, count), data, count);
-- skb->dev = (void *) &husb->hdev;
-- skb->pkt_type = HCI_ACLDATA_PKT;
-+ BT_DBG("%s urb %p type %d status %d count %d flags %x", hdev->name, urb,
-+ _urb->type, urb->status, count, urb->transfer_flags);
-
-- husb->hdev.stat.byte_rx += skb->len;
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return;
-
-- hci_recv_frame(skb);
-+ read_lock(&husb->completion_lock);
-
--resubmit:
-- husb->read_urb->dev = husb->udev;
-- if ((status = usb_submit_urb(husb->read_urb)))
-- DBG("%s read URB submit failed %d", husb->hdev.name, status);
-+ if (urb->status || !count)
-+ goto resubmit;
-+
-+ if (_urb->type == HCI_SCODATA_PKT) {
-+#ifdef CONFIG_BLUEZ_USB_SCO
-+ int i;
-+ for (i=0; i < urb->number_of_packets; i++) {
-+ BT_DBG("desc %d status %d offset %d len %d", i,
-+ urb->iso_frame_desc[i].status,
-+ urb->iso_frame_desc[i].offset,
-+ urb->iso_frame_desc[i].actual_length);
-+
-+ if (!urb->iso_frame_desc[i].status)
-+ __recv_frame(husb, _urb->type,
-+ urb->transfer_buffer + urb->iso_frame_desc[i].offset,
-+ urb->iso_frame_desc[i].actual_length);
-+ }
-+#else
-+ ;
-+#endif
-+ } else {
-+ err = __recv_frame(husb, _urb->type, urb->transfer_buffer, count);
-+ if (err < 0) {
-+ BT_ERR("%s corrupted packet: type %d count %d",
-+ husb->hdev.name, _urb->type, count);
-+ hdev->stat.err_rx++;
-+ }
-+ }
-
-- DBG("%s read URB re-submited", husb->hdev.name);
-+resubmit:
-+ if (_urb->type != HCI_EVENT_PKT) {
-+ urb->dev = husb->udev;
-+ err = usb_submit_urb(urb);
-+ BT_DBG("%s urb %p type %d resubmit status %d", hdev->name, urb,
-+ _urb->type, err);
-+ }
-+ read_unlock(&husb->completion_lock);
- }
-
--static int hci_usb_ctrl_msg(struct hci_usb *husb, struct sk_buff *skb)
-+static void hci_usb_tx_complete(struct urb *urb)
- {
-- struct urb *urb = husb->ctrl_urb;
-- devrequest *dr = &husb->dev_req;
-- int pipe, status;
-+ struct _urb *_urb = container_of(urb, struct _urb, urb);
-+ struct hci_usb *husb = (void *) urb->context;
-+ struct hci_dev *hdev = &husb->hdev;
-
-- DBG("%s len %d", husb->hdev.name, skb->len);
-+ BT_DBG("%s urb %p status %d flags %x", hdev->name, urb,
-+ urb->status, urb->transfer_flags);
-
-- pipe = usb_sndctrlpipe(husb->udev, 0);
-+ atomic_dec(__pending_tx(husb, _urb->type));
-
-- dr->requesttype = HCI_CTRL_REQ;
-- dr->request = 0;
-- dr->index = 0;
-- dr->value = 0;
-- dr->length = cpu_to_le16(skb->len);
-+ urb->transfer_buffer = NULL;
-+ kfree_skb((struct sk_buff *) _urb->priv);
-
-- FILL_CONTROL_URB(urb, husb->udev, pipe, (void*)dr, skb->data, skb->len,
-- hci_usb_ctrl, skb);
--
-- if ((status = usb_submit_urb(urb))) {
-- DBG("%s control URB submit failed %d", husb->hdev.name, status);
-- return status;
-- }
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
-+ return;
-
-- return 0;
--}
-+ if (!urb->status)
-+ hdev->stat.byte_tx += urb->transfer_buffer_length;
-+ else
-+ hdev->stat.err_tx++;
-
--static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb)
--{
-- struct urb *urb = husb->write_urb;
-- int pipe, status;
-+ read_lock(&husb->completion_lock);
-
-- DBG("%s len %d", husb->hdev.name, skb->len);
-+ _urb_unlink(_urb);
-+ _urb_queue_tail(__completed_q(husb, _urb->type), _urb);
-
-- pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep_addr);
-+ hci_usb_tx_wakeup(husb);
-+
-+ read_unlock(&husb->completion_lock);
-+}
-
-- FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,
-- hci_usb_bulk_write, skb);
-- urb->transfer_flags |= USB_QUEUE_BULK;
-+static void hci_usb_destruct(struct hci_dev *hdev)
-+{
-+ struct hci_usb *husb = (struct hci_usb *) hdev->driver_data;
-
-- if ((status = usb_submit_urb(urb))) {
-- DBG("%s write URB submit failed %d", husb->hdev.name, status);
-- return status;
-- }
-+ BT_DBG("%s", hdev->name);
-
-- return 0;
-+ kfree(husb);
- }
-
--static void * hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
-+static void *hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
- {
-- struct usb_endpoint_descriptor *bulk_out_ep, *intr_in_ep, *bulk_in_ep;
-+ struct usb_endpoint_descriptor *bulk_out_ep[HCI_MAX_IFACE_NUM];
-+ struct usb_endpoint_descriptor *isoc_out_ep[HCI_MAX_IFACE_NUM];
-+ struct usb_endpoint_descriptor *bulk_in_ep[HCI_MAX_IFACE_NUM];
-+ struct usb_endpoint_descriptor *isoc_in_ep[HCI_MAX_IFACE_NUM];
-+ struct usb_endpoint_descriptor *intr_in_ep[HCI_MAX_IFACE_NUM];
- struct usb_interface_descriptor *uif;
- struct usb_endpoint_descriptor *ep;
-+ struct usb_interface *iface, *isoc_iface;
- struct hci_usb *husb;
- struct hci_dev *hdev;
-- int i, size, pipe;
-- __u8 * buf;
-+ int i, a, e, size, ifn, isoc_ifnum, isoc_alts;
-
-- DBG("udev %p ifnum %d", udev, ifnum);
--
-- /* Check device signature */
-- if ((udev->descriptor.bDeviceClass != HCI_DEV_CLASS) ||
-- (udev->descriptor.bDeviceSubClass != HCI_DEV_SUBCLASS)||
-- (udev->descriptor.bDeviceProtocol != HCI_DEV_PROTOCOL) )
-- return NULL;
--
-- MOD_INC_USE_COUNT;
-+ BT_DBG("udev %p ifnum %d", udev, ifnum);
-
-- uif = &udev->actconfig->interface[ifnum].altsetting[0];
-+ iface = &udev->actconfig->interface[0];
-
-- if (uif->bNumEndpoints != 3) {
-- DBG("Wrong number of endpoints %d", uif->bNumEndpoints);
-- MOD_DEC_USE_COUNT;
-+ /* Check our black list */
-+ if (usb_match_id(udev, iface, ignore_ids))
- return NULL;
-- }
-
-- bulk_out_ep = intr_in_ep = bulk_in_ep = NULL;
-+ /* Check number of endpoints */
-+ if (udev->actconfig->interface[ifnum].altsetting[0].bNumEndpoints < 3)
-+ return NULL;
-
-+ memset(bulk_out_ep, 0, sizeof(bulk_out_ep));
-+ memset(isoc_out_ep, 0, sizeof(isoc_out_ep));
-+ memset(bulk_in_ep, 0, sizeof(bulk_in_ep));
-+ memset(isoc_in_ep, 0, sizeof(isoc_in_ep));
-+ memset(intr_in_ep, 0, sizeof(intr_in_ep));
-+
-+ size = 0;
-+ isoc_iface = NULL;
-+ isoc_alts = isoc_ifnum = 0;
-+
- /* Find endpoints that we need */
-- for ( i = 0; i < uif->bNumEndpoints; ++i) {
-- ep = &uif->endpoint[i];
-
-- switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
-- case USB_ENDPOINT_XFER_BULK:
-- if (ep->bEndpointAddress & USB_DIR_IN)
-- bulk_in_ep = ep;
-- else
-- bulk_out_ep = ep;
-- break;
-+ ifn = MIN(udev->actconfig->bNumInterfaces, HCI_MAX_IFACE_NUM);
-+ for (i = 0; i < ifn; i++) {
-+ iface = &udev->actconfig->interface[i];
-+ for (a = 0; a < iface->num_altsetting; a++) {
-+ uif = &iface->altsetting[a];
-+ for (e = 0; e < uif->bNumEndpoints; e++) {
-+ ep = &uif->endpoint[e];
-+
-+ switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
-+ case USB_ENDPOINT_XFER_INT:
-+ if (ep->bEndpointAddress & USB_DIR_IN)
-+ intr_in_ep[i] = ep;
-+ break;
-+
-+ case USB_ENDPOINT_XFER_BULK:
-+ if (ep->bEndpointAddress & USB_DIR_IN)
-+ bulk_in_ep[i] = ep;
-+ else
-+ bulk_out_ep[i] = ep;
-+ break;
-+
-+#ifdef CONFIG_BLUEZ_USB_SCO
-+ case USB_ENDPOINT_XFER_ISOC:
-+ if (ep->wMaxPacketSize < size || a > 2)
-+ break;
-+ size = ep->wMaxPacketSize;
-+
-+ isoc_iface = iface;
-+ isoc_alts = a;
-+ isoc_ifnum = i;
-+
-+ if (ep->bEndpointAddress & USB_DIR_IN)
-+ isoc_in_ep[i] = ep;
-+ else
-+ isoc_out_ep[i] = ep;
-+ break;
-+#endif
-+ }
-+ }
-+ }
-+ }
-
-- case USB_ENDPOINT_XFER_INT:
-- intr_in_ep = ep;
-- break;
-- };
-+ if (!bulk_in_ep[0] || !bulk_out_ep[0] || !intr_in_ep[0]) {
-+ BT_DBG("Bulk endpoints not found");
-+ goto done;
- }
-
-- if (!bulk_in_ep || !bulk_out_ep || !intr_in_ep) {
-- DBG("Endpoints not found: %p %p %p", bulk_in_ep, bulk_out_ep, intr_in_ep);
-- MOD_DEC_USE_COUNT;
-- return NULL;
-+#ifdef CONFIG_BLUEZ_USB_SCO
-+ if (!isoc_in_ep[1] || !isoc_out_ep[1]) {
-+ BT_DBG("Isoc endpoints not found");
-+ isoc_iface = NULL;
- }
-+#endif
-
- if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
-- ERR("Can't allocate: control structure");
-- MOD_DEC_USE_COUNT;
-- return NULL;
-+ BT_ERR("Can't allocate: control structure");
-+ goto done;
- }
-
- memset(husb, 0, sizeof(struct hci_usb));
-
- husb->udev = udev;
-- husb->bulk_out_ep_addr = bulk_out_ep->bEndpointAddress;
--
-- if (!(husb->ctrl_urb = usb_alloc_urb(0))) {
-- ERR("Can't allocate: control URB");
-- goto probe_error;
-- }
--
-- if (!(husb->write_urb = usb_alloc_urb(0))) {
-- ERR("Can't allocate: write URB");
-- goto probe_error;
-- }
--
-- if (!(husb->read_urb = usb_alloc_urb(0))) {
-- ERR("Can't allocate: read URB");
-- goto probe_error;
-- }
--
-- ep = bulk_in_ep;
-- pipe = usb_rcvbulkpipe(udev, ep->bEndpointAddress);
-- size = HCI_MAX_FRAME_SIZE;
--
-- if (!(buf = kmalloc(size, GFP_KERNEL))) {
-- ERR("Can't allocate: read buffer");
-- goto probe_error;
-- }
--
-- FILL_BULK_URB(husb->read_urb, udev, pipe, buf, size, hci_usb_bulk_read, husb);
-- husb->read_urb->transfer_flags |= USB_QUEUE_BULK;
--
-- ep = intr_in_ep;
-- pipe = usb_rcvintpipe(udev, ep->bEndpointAddress);
-- size = usb_maxpacket(udev, pipe, usb_pipeout(pipe));
--
-- if (!(husb->intr_urb = usb_alloc_urb(0))) {
-- ERR("Can't allocate: interrupt URB");
-- goto probe_error;
-+ husb->bulk_out_ep = bulk_out_ep[0];
-+ husb->bulk_in_ep = bulk_in_ep[0];
-+ husb->intr_in_ep = intr_in_ep[0];
-+
-+#ifdef CONFIG_BLUEZ_USB_SCO
-+ if (isoc_iface) {
-+ BT_DBG("isoc ifnum %d alts %d", isoc_ifnum, isoc_alts);
-+ if (usb_set_interface(udev, isoc_ifnum, isoc_alts)) {
-+ BT_ERR("Can't set isoc interface settings");
-+ isoc_iface = NULL;
-+ }
-+ usb_driver_claim_interface(&hci_usb_driver, isoc_iface, husb);
-+ husb->isoc_iface = isoc_iface;
-+ husb->isoc_in_ep = isoc_in_ep[isoc_ifnum];
-+ husb->isoc_out_ep = isoc_out_ep[isoc_ifnum];
- }
-+#endif
-+
-+ husb->completion_lock = RW_LOCK_UNLOCKED;
-
-- if (!(buf = kmalloc(size, GFP_KERNEL))) {
-- ERR("Can't allocate: interrupt buffer");
-- goto probe_error;
-+ for (i = 0; i < 4; i++) {
-+ skb_queue_head_init(&husb->transmit_q[i]);
-+ _urb_queue_init(&husb->pending_q[i]);
-+ _urb_queue_init(&husb->completed_q[i]);
- }
-
-- FILL_INT_URB(husb->intr_urb, udev, pipe, buf, size, hci_usb_intr, husb, ep->bInterval);
--
-- skb_queue_head_init(&husb->tx_ctrl_q);
-- skb_queue_head_init(&husb->tx_write_q);
--
- /* Initialize and register HCI device */
- hdev = &husb->hdev;
-
-- hdev->type = HCI_USB;
-+ hdev->type = HCI_USB;
- hdev->driver_data = husb;
-
- hdev->open = hci_usb_open;
- hdev->close = hci_usb_close;
- hdev->flush = hci_usb_flush;
-- hdev->send = hci_usb_send_frame;
-+ hdev->send = hci_usb_send_frame;
-+ hdev->destruct = hci_usb_destruct;
-
- if (hci_register_dev(hdev) < 0) {
-- ERR("Can't register HCI device %s", hdev->name);
-+ BT_ERR("Can't register HCI device");
- goto probe_error;
- }
-
- return husb;
-
- probe_error:
-- hci_usb_free_bufs(husb);
- kfree(husb);
-- MOD_DEC_USE_COUNT;
-+
-+done:
- return NULL;
- }
-
-@@ -626,38 +930,34 @@
- if (!husb)
- return;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s", hdev->name);
-
- hci_usb_close(hdev);
-
-- if (hci_unregister_dev(hdev) < 0) {
-- ERR("Can't unregister HCI device %s", hdev->name);
-- }
-+ if (husb->isoc_iface)
-+ usb_driver_release_interface(&hci_usb_driver, husb->isoc_iface);
-
-- hci_usb_free_bufs(husb);
-- kfree(husb);
--
-- MOD_DEC_USE_COUNT;
-+ if (hci_unregister_dev(hdev) < 0)
-+ BT_ERR("Can't unregister HCI device %s", hdev->name);
- }
-
--static struct usb_driver hci_usb_driver =
--{
-+static struct usb_driver hci_usb_driver = {
- name: "hci_usb",
- probe: hci_usb_probe,
- disconnect: hci_usb_disconnect,
-- id_table: usb_bluetooth_ids,
-+ id_table: bluetooth_ids,
- };
-
- int hci_usb_init(void)
- {
- int err;
-
-- INF("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-+ BT_INFO("BlueZ HCI USB driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-
- if ((err = usb_register(&hci_usb_driver)) < 0)
-- ERR("Failed to register HCI USB driver");
-+ BT_ERR("Failed to register HCI USB driver");
-
- return err;
- }
-diff -urN linux-2.4.18/drivers/bluetooth/hci_usb.h linux-2.4.18-mh9/drivers/bluetooth/hci_usb.h
---- linux-2.4.18/drivers/bluetooth/hci_usb.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/drivers/bluetooth/hci_usb.h Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,139 @@
-+/*
-+ HCI USB driver for Linux Bluetooth protocol stack (BlueZ)
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ Copyright (C) 2003 Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifdef __KERNEL__
-+
-+/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
-+#define HCI_DEV_CLASS 0xe0 /* Wireless class */
-+#define HCI_DEV_SUBCLASS 0x01 /* RF subclass */
-+#define HCI_DEV_PROTOCOL 0x01 /* Bluetooth programming protocol */
-+
-+#define HCI_CTRL_REQ 0x20
-+
-+#define HCI_MAX_IFACE_NUM 3
-+
-+#define HCI_MAX_BULK_TX 4
-+#define HCI_MAX_BULK_RX 1
-+
-+#define HCI_MAX_ISOC_RX 2
-+#define HCI_MAX_ISOC_TX 2
-+
-+#define HCI_MAX_ISOC_FRAMES 10
-+
-+struct _urb_queue {
-+ struct list_head head;
-+ spinlock_t lock;
-+};
-+
-+struct _urb {
-+ struct list_head list;
-+ struct _urb_queue *queue;
-+ int type;
-+ void *priv;
-+ struct urb urb;
-+};
-+
-+struct _urb *_urb_alloc(int isoc, int gfp);
-+
-+static inline void _urb_free(struct _urb *_urb)
-+{
-+ kfree(_urb);
-+}
-+
-+static inline void _urb_queue_init(struct _urb_queue *q)
-+{
-+ INIT_LIST_HEAD(&q->head);
-+ spin_lock_init(&q->lock);
-+}
-+
-+static inline void _urb_queue_head(struct _urb_queue *q, struct _urb *_urb)
-+{
-+ unsigned long flags;
-+ spin_lock_irqsave(&q->lock, flags);
-+ list_add(&_urb->list, &q->head); _urb->queue = q;
-+ spin_unlock_irqrestore(&q->lock, flags);
-+}
-+
-+static inline void _urb_queue_tail(struct _urb_queue *q, struct _urb *_urb)
-+{
-+ unsigned long flags;
-+ spin_lock_irqsave(&q->lock, flags);
-+ list_add_tail(&_urb->list, &q->head); _urb->queue = q;
-+ spin_unlock_irqrestore(&q->lock, flags);
-+}
-+
-+static inline void _urb_unlink(struct _urb *_urb)
-+{
-+ struct _urb_queue *q = _urb->queue;
-+ unsigned long flags;
-+ if (q) {
-+ spin_lock_irqsave(&q->lock, flags);
-+ list_del(&_urb->list); _urb->queue = NULL;
-+ spin_unlock_irqrestore(&q->lock, flags);
-+ }
-+}
-+
-+struct _urb *_urb_dequeue(struct _urb_queue *q);
-+
-+#ifndef container_of
-+#define container_of(ptr, type, member) ({ \
-+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
-+ (type *)( (char *)__mptr - offsetof(type,member) );})
-+#endif
-+
-+struct hci_usb {
-+ struct hci_dev hdev;
-+
-+ unsigned long state;
-+
-+ struct usb_device *udev;
-+
-+ struct usb_endpoint_descriptor *bulk_in_ep;
-+ struct usb_endpoint_descriptor *bulk_out_ep;
-+ struct usb_endpoint_descriptor *intr_in_ep;
-+
-+ struct usb_interface *isoc_iface;
-+ struct usb_endpoint_descriptor *isoc_out_ep;
-+ struct usb_endpoint_descriptor *isoc_in_ep;
-+
-+ struct sk_buff_head transmit_q[4];
-+ struct sk_buff *reassembly[4]; // Reassembly buffers
-+
-+ rwlock_t completion_lock;
-+
-+ atomic_t pending_tx[4]; // Number of pending requests
-+ struct _urb_queue pending_q[4]; // Pending requests
-+ struct _urb_queue completed_q[4]; // Completed requests
-+};
-+
-+/* States */
-+#define HCI_USB_TX_PROCESS 1
-+#define HCI_USB_TX_WAKEUP 2
-+
-+#endif /* __KERNEL__ */
-diff -urN linux-2.4.18/drivers/bluetooth/hci_vhci.c linux-2.4.18-mh9/drivers/bluetooth/hci_vhci.c
---- linux-2.4.18/drivers/bluetooth/hci_vhci.c Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/drivers/bluetooth/hci_vhci.c Mon Aug 25 18:38:10 2003
-@@ -25,9 +25,9 @@
- /*
- * BlueZ HCI virtual device driver.
- *
-- * $Id$
-+ * $Id$
- */
--#define VERSION "1.0"
-+#define VERSION "1.1"
-
- #include <linux/config.h>
- #include <linux/module.h>
-@@ -49,43 +49,56 @@
- #include <asm/uaccess.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/hci_vhci.h>
-+#include "hci_vhci.h"
-
- /* HCI device part */
-
--int hci_vhci_open(struct hci_dev *hdev)
-+static int hci_vhci_open(struct hci_dev *hdev)
- {
-- hdev->flags |= HCI_RUNNING;
-+ set_bit(HCI_RUNNING, &hdev->flags);
- return 0;
- }
-
--int hci_vhci_flush(struct hci_dev *hdev)
-+static int hci_vhci_flush(struct hci_dev *hdev)
- {
- struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
- skb_queue_purge(&hci_vhci->readq);
- return 0;
- }
-
--int hci_vhci_close(struct hci_dev *hdev)
-+static int hci_vhci_close(struct hci_dev *hdev)
- {
-- hdev->flags &= ~HCI_RUNNING;
-+ if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
-+ return 0;
-+
- hci_vhci_flush(hdev);
- return 0;
- }
-
--int hci_vhci_send_frame(struct sk_buff *skb)
-+static void hci_vhci_destruct(struct hci_dev *hdev)
-+{
-+ struct hci_vhci_struct *vhci;
-+
-+ if (!hdev) return;
-+
-+ vhci = (struct hci_vhci_struct *) hdev->driver_data;
-+ kfree(vhci);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static int hci_vhci_send_frame(struct sk_buff *skb)
- {
- struct hci_dev* hdev = (struct hci_dev *) skb->dev;
- struct hci_vhci_struct *hci_vhci;
-
- if (!hdev) {
-- ERR("Frame for uknown device (hdev=NULL)");
-+ BT_ERR("Frame for uknown device (hdev=NULL)");
- return -ENODEV;
- }
-
-- if (!(hdev->flags & HCI_RUNNING))
-+ if (!test_bit(HCI_RUNNING, &hdev->flags))
- return -EBUSY;
-
- hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
-@@ -188,7 +201,7 @@
-
- add_wait_queue(&hci_vhci->read_wait, &wait);
- while (count) {
-- current->state = TASK_INTERRUPTIBLE;
-+ set_current_state(TASK_INTERRUPTIBLE);
-
- /* Read frames from device queue */
- if (!(skb = skb_dequeue(&hci_vhci->readq))) {
-@@ -214,8 +227,7 @@
- kfree_skb(skb);
- break;
- }
--
-- current->state = TASK_RUNNING;
-+ set_current_state(TASK_RUNNING);
- remove_wait_queue(&hci_vhci->read_wait, &wait);
-
- return ret;
-@@ -270,11 +282,13 @@
- hdev->close = hci_vhci_close;
- hdev->flush = hci_vhci_flush;
- hdev->send = hci_vhci_send_frame;
-+ hdev->destruct = hci_vhci_destruct;
-
- if (hci_register_dev(hdev) < 0) {
- kfree(hci_vhci);
- return -EBUSY;
- }
-+ MOD_INC_USE_COUNT;
-
- file->private_data = hci_vhci;
- return 0;
-@@ -285,12 +299,10 @@
- struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
-
- if (hci_unregister_dev(&hci_vhci->hdev) < 0) {
-- ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
-+ BT_ERR("Can't unregister HCI device %s", hci_vhci->hdev.name);
- }
-
-- kfree(hci_vhci);
- file->private_data = NULL;
--
- return 0;
- }
-
-@@ -315,12 +327,12 @@
-
- int __init hci_vhci_init(void)
- {
-- INF("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-+ BT_INFO("BlueZ VHCI driver ver %s Copyright (C) 2000,2001 Qualcomm Inc",
- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-
- if (misc_register(&hci_vhci_miscdev)) {
-- ERR("Can't register misc device %d\n", VHCI_MINOR);
-+ BT_ERR("Can't register misc device %d\n", VHCI_MINOR);
- return -EIO;
- }
-
-@@ -337,4 +349,4 @@
-
- MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
- MODULE_DESCRIPTION("BlueZ VHCI driver ver " VERSION);
--MODULE_LICENSE("GPL");
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/drivers/bluetooth/hci_vhci.h linux-2.4.18-mh9/drivers/bluetooth/hci_vhci.h
---- linux-2.4.18/drivers/bluetooth/hci_vhci.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/drivers/bluetooth/hci_vhci.h Mon Aug 25 18:38:10 2003
-@@ -0,0 +1,50 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef __HCI_VHCI_H
-+#define __HCI_VHCI_H
-+
-+#ifdef __KERNEL__
-+
-+struct hci_vhci_struct {
-+ struct hci_dev hdev;
-+ __u32 flags;
-+ wait_queue_head_t read_wait;
-+ struct sk_buff_head readq;
-+ struct fasync_struct *fasync;
-+};
-+
-+/* VHCI device flags */
-+#define VHCI_FASYNC 0x0010
-+
-+#endif /* __KERNEL__ */
-+
-+#define VHCI_DEV "/dev/vhci"
-+#define VHCI_MINOR 250
-+
-+#endif /* __HCI_VHCI_H */
-diff -urN linux-2.4.18/drivers/char/pcmcia/serial_cs.c linux-2.4.18-mh9/drivers/char/pcmcia/serial_cs.c
---- linux-2.4.18/drivers/char/pcmcia/serial_cs.c Fri Dec 21 18:41:54 2001
-+++ linux-2.4.18-mh9/drivers/char/pcmcia/serial_cs.c Mon Aug 25 18:38:10 2003
-@@ -2,7 +2,7 @@
-
- A driver for PCMCIA serial devices
-
-- serial_cs.c 1.128 2001/10/18 12:18:35
-+ serial_cs.c 1.138 2002/10/25 06:24:52
-
- The contents of this file are subject to the Mozilla Public
- License Version 1.1 (the "License"); you may not use this file
-@@ -28,7 +28,7 @@
- and other provisions required by the GPL. If you do not delete
- the provisions above, a recipient may use your version of this
- file under either the MPL or the GPL.
--
-+
- ======================================================================*/
-
- #include <linux/module.h>
-@@ -69,14 +69,14 @@
- static int irq_list[4] = { -1 };
- MODULE_PARM(irq_list, "1-4i");
-
--/* Enable the speaker? */
--INT_MODULE_PARM(do_sound, 1);
-+INT_MODULE_PARM(do_sound, 1); /* Enable the speaker? */
-+INT_MODULE_PARM(buggy_uart, 0); /* Skip strict UART tests? */
-
- #ifdef PCMCIA_DEBUG
- INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
- #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
- static char *version =
--"serial_cs.c 1.128 2001/10/18 12:18:35 (David Hinds)";
-+"serial_cs.c 1.138 2002/10/25 06:24:52 (David Hinds)";
- #else
- #define DEBUG(n, args...)
- #endif
-@@ -95,6 +95,7 @@
- { MANFID_OMEGA, PRODID_OMEGA_QSP_100, 4 },
- { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232, 2 },
- { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D1, 2 },
-+ { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS232_D2, 2 },
- { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS232, 4 },
- { MANFID_QUATECH, PRODID_QUATECH_DUAL_RS422, 2 },
- { MANFID_QUATECH, PRODID_QUATECH_QUAD_RS422, 4 },
-@@ -148,7 +149,7 @@
- client_reg_t client_reg;
- dev_link_t *link;
- int i, ret;
--
-+
- DEBUG(0, "serial_attach()\n");
-
- /* Create new serial device */
-@@ -160,7 +161,7 @@
- link->release.function = &serial_release;
- link->release.data = (u_long)link;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
-- link->io.NumPorts1 = 8;
-+ link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
- link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
- link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
- if (irq_list[0] == -1)
-@@ -169,13 +170,12 @@
- for (i = 0; i < 4; i++)
- link->irq.IRQInfo2 |= 1 << irq_list[i];
- link->conf.Attributes = CONF_ENABLE_IRQ;
-- link->conf.Vcc = 50;
- if (do_sound) {
- link->conf.Attributes |= CONF_ENABLE_SPKR;
- link->conf.Status = CCSR_AUDIO_ENA;
- }
- link->conf.IntType = INT_MEMORY_AND_IO;
--
-+
- /* Register with Card Services */
- link->next = dev_list;
- dev_list = link;
-@@ -194,7 +194,7 @@
- serial_detach(link);
- return NULL;
- }
--
-+
- return link;
- } /* serial_attach */
-
-@@ -214,7 +214,7 @@
- int ret;
-
- DEBUG(0, "serial_detach(0x%p)\n", link);
--
-+
- /* Locate device structure */
- for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
- if (*linkp == link) break;
-@@ -224,17 +224,17 @@
- del_timer(&link->release);
- if (link->state & DEV_CONFIG)
- serial_release((u_long)link);
--
-+
- if (link->handle) {
- ret = CardServices(DeregisterClient, link->handle);
- if (ret != CS_SUCCESS)
- cs_error(link->handle, DeregisterClient, ret);
- }
--
-+
- /* Unlink device structure, free bits */
- *linkp = link->next;
- kfree(info);
--
-+
- } /* serial_detach */
-
- /*====================================================================*/
-@@ -243,18 +243,20 @@
- {
- struct serial_struct serial;
- int line;
--
-+
- memset(&serial, 0, sizeof(serial));
- serial.port = port;
- serial.irq = irq;
- serial.flags = ASYNC_SKIP_TEST | ASYNC_SHARE_IRQ;
-+ if (buggy_uart)
-+ serial.flags |= ASYNC_BUGGY_UART;
- line = register_serial(&serial);
- if (line < 0) {
- printk(KERN_NOTICE "serial_cs: register_serial() at 0x%04lx,"
- " irq %d failed\n", (u_long)serial.port, serial.irq);
- return -1;
- }
--
-+
- info->line[info->ndev] = line;
- sprintf(info->node[info->ndev].dev_name, "ttyS%d", line);
- info->node[info->ndev].major = TTY_MAJOR;
-@@ -262,7 +264,7 @@
- if (info->ndev > 0)
- info->node[info->ndev-1].next = &info->node[info->ndev];
- info->ndev++;
--
-+
- return 0;
- }
-
-@@ -313,7 +315,10 @@
- return setup_serial(info, port, config.AssignedIRQ);
- }
- link->conf.Vcc = config.Vcc;
--
-+
-+ link->io.NumPorts1 = 8;
-+ link->io.NumPorts2 = 0;
-+
- /* First pass: look for a config entry that looks normal. */
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
-@@ -340,7 +345,7 @@
- i = next_tuple(handle, &tuple, &parse);
- }
- }
--
-+
- /* Second pass: try to find an entry that isn't picky about
- its base address, then try to grab any standard serial port
- address, and finally try to get any free port. */
-@@ -352,8 +357,7 @@
- for (j = 0; j < 5; j++) {
- link->io.BasePort1 = base[j];
- link->io.IOAddrLines = base[j] ? 16 : 3;
-- i = CardServices(RequestIO, link->handle,
-- &link->io);
-+ i = CardServices(RequestIO, link->handle, &link->io);
- if (i == CS_SUCCESS) goto found_port;
- }
- }
-@@ -365,7 +369,7 @@
- cs_error(link->handle, RequestIO, i);
- return -1;
- }
--
-+
- i = CardServices(RequestIRQ, link->handle, &link->irq);
- if (i != CS_SUCCESS) {
- cs_error(link->handle, RequestIRQ, i);
-@@ -390,8 +394,12 @@
- u_char buf[256];
- cisparse_t parse;
- cistpl_cftable_entry_t *cf = &parse.cftable_entry;
-+ config_info_t config;
- int i, base2 = 0;
-
-+ CardServices(GetConfigurationInfo, handle, &config);
-+ link->conf.Vcc = config.Vcc;
-+
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
-@@ -433,12 +441,12 @@
- i = next_tuple(handle, &tuple, &parse);
- }
- }
--
-+
- if (i != CS_SUCCESS) {
-- cs_error(link->handle, RequestIO, i);
-- return -1;
-+ /* At worst, try to configure as a single port */
-+ return simple_config(link);
- }
--
-+
- i = CardServices(RequestIRQ, link->handle, &link->irq);
- if (i != CS_SUCCESS) {
- cs_error(link->handle, RequestIRQ, i);
-@@ -454,14 +462,27 @@
- cs_error(link->handle, RequestConfiguration, i);
- return -1;
- }
--
-+
-+ /* The Oxford Semiconductor OXCF950 cards are in fact single-port:
-+ 8 registers are for the UART, the others are extra registers */
-+ if (info->manfid == MANFID_OXSEMI) {
-+ if (cf->index == 1 || cf->index == 3) {
-+ setup_serial(info, base2, link->irq.AssignedIRQ);
-+ outb(12,link->io.BasePort1+1);
-+ } else {
-+ setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
-+ outb(12,base2+1);
-+ }
-+ return 0;
-+ }
-+
- setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);
- /* The Nokia cards are not really multiport cards */
- if (info->manfid == MANFID_NOKIA)
- return 0;
- for (i = 0; i < info->multi-1; i++)
- setup_serial(info, base2+(8*i), link->irq.AssignedIRQ);
--
-+
- return 0;
- }
-
-@@ -487,7 +508,7 @@
- int i, last_ret, last_fn;
-
- DEBUG(0, "serial_config(0x%p)\n", link);
--
-+
- tuple.TupleData = (cisdata_t *)buf;
- tuple.TupleOffset = 0; tuple.TupleDataMax = 255;
- tuple.Attributes = 0;
-@@ -500,7 +521,7 @@
- }
- link->conf.ConfigBase = parse.config.base;
- link->conf.Present = parse.config.rmask[0];
--
-+
- /* Configure card */
- link->state |= DEV_CONFIG;
-
-@@ -508,8 +529,8 @@
- tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
- tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
- info->multi = (first_tuple(handle, &tuple, &parse) == CS_SUCCESS);
--
-- /* Is this a multiport card? */
-+
-+ /* Scan list of known multiport card ID's */
- tuple.DesiredTuple = CISTPL_MANFID;
- if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {
- info->manfid = le16_to_cpu(buf[0]);
-@@ -537,15 +558,15 @@
- info->multi = 2;
- }
- }
--
-+
- if (info->multi > 1)
- multi_config(link);
- else
- simple_config(link);
--
-+
- if (info->ndev == 0)
- goto failed;
--
-+
- if (info->manfid == MANFID_IBM) {
- conf_reg_t reg = { 0, CS_READ, 0x800, 0 };
- CS_CHECK(AccessConfigurationRegister, link->handle, &reg);
-@@ -562,6 +583,7 @@
- cs_error(link->handle, last_fn, last_ret);
- failed:
- serial_release((u_long)link);
-+ link->state &= ~DEV_CONFIG_PENDING;
-
- } /* serial_config */
-
-@@ -569,7 +591,7 @@
-
- After a card is removed, serial_release() will unregister the net
- device, and release the PCMCIA configuration.
--
-+
- ======================================================================*/
-
- void serial_release(u_long arg)
-@@ -577,7 +599,7 @@
- dev_link_t *link = (dev_link_t *)arg;
- serial_info_t *info = link->priv;
- int i;
--
-+
- DEBUG(0, "serial_release(0x%p)\n", link);
-
- for (i = 0; i < info->ndev; i++) {
-@@ -590,7 +612,7 @@
- CardServices(ReleaseIO, link->handle, &link->io);
- CardServices(ReleaseIRQ, link->handle, &link->irq);
- }
--
-+
- link->state &= ~DEV_CONFIG;
-
- } /* serial_release */
-@@ -601,7 +623,7 @@
- stuff to run after an event is received. A CARD_REMOVAL event
- also sets some flags to discourage the serial drivers from
- talking to the ports.
--
-+
- ======================================================================*/
-
- static int serial_event(event_t event, int priority,
-@@ -609,9 +631,9 @@
- {
- dev_link_t *link = args->client_data;
- serial_info_t *info = link->priv;
--
-+
- DEBUG(1, "serial_event(0x%06x)\n", event);
--
-+
- switch (event) {
- case CS_EVENT_CARD_REMOVAL:
- link->state &= ~DEV_PRESENT;
-@@ -650,7 +672,7 @@
- if (serv.Revision != CS_RELEASE_CODE) {
- printk(KERN_NOTICE "serial_cs: Card Services release "
- "does not match!\n");
-- return -1;
-+ return -EINVAL;
- }
- register_pccard_driver(&dev_info, &serial_attach, &serial_detach);
- return 0;
-diff -urN linux-2.4.18/drivers/usb/Config.in linux-2.4.18-mh9/drivers/usb/Config.in
---- linux-2.4.18/drivers/usb/Config.in Mon Feb 25 20:38:07 2002
-+++ linux-2.4.18-mh9/drivers/usb/Config.in Mon Aug 25 18:38:10 2003
-@@ -31,7 +31,13 @@
-
- comment 'USB Device Class drivers'
- dep_tristate ' USB Audio support' CONFIG_USB_AUDIO $CONFIG_USB $CONFIG_SOUND
--dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB $CONFIG_EXPERIMENTAL
-+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-+ if [ "$CONFIG_BLUEZ" = "n" ]; then
-+ dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB
-+ else
-+ comment ' USB Bluetooth can only be used with disabled Bluetooth subsystem'
-+ fi
-+fi
- if [ "$CONFIG_SCSI" = "n" ]; then
- comment ' SCSI support is needed for USB Storage'
- fi
-diff -urN linux-2.4.18/include/linux/firmware.h linux-2.4.18-mh9/include/linux/firmware.h
---- linux-2.4.18/include/linux/firmware.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/include/linux/firmware.h Mon Aug 25 18:38:10 2003
-@@ -0,0 +1,20 @@
-+#ifndef _LINUX_FIRMWARE_H
-+#define _LINUX_FIRMWARE_H
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#define FIRMWARE_NAME_MAX 30
-+struct firmware {
-+ size_t size;
-+ u8 *data;
-+};
-+int request_firmware (const struct firmware **fw, const char *name,
-+ const char *device);
-+int request_firmware_nowait (
-+ struct module *module,
-+ const char *name, const char *device, void *context,
-+ void (*cont)(const struct firmware *fw, void *context));
-+/* On 2.5 'device' is 'struct device *' */
-+
-+void release_firmware (const struct firmware *fw);
-+void register_firmware (const char *name, const u8 *data, size_t size);
-+#endif
-diff -urN linux-2.4.18/include/linux/kernel.h linux-2.4.18-mh9/include/linux/kernel.h
---- linux-2.4.18/include/linux/kernel.h Mon Feb 25 20:38:13 2002
-+++ linux-2.4.18-mh9/include/linux/kernel.h Mon Aug 25 18:38:11 2003
-@@ -11,6 +11,7 @@
- #include <linux/linkage.h>
- #include <linux/stddef.h>
- #include <linux/types.h>
-+#include <linux/compiler.h>
-
- /* Optimization barrier */
- /* The "volatile" is due to gcc bugs */
-@@ -181,4 +182,6 @@
- char _f[20-2*sizeof(long)-sizeof(int)]; /* Padding: libc5 uses this.. */
- };
-
--#endif
-+#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
-+
-+#endif /* _LINUX_KERNEL_H */
-diff -urN linux-2.4.18/include/net/bluetooth/bluetooth.h linux-2.4.18-mh9/include/net/bluetooth/bluetooth.h
---- linux-2.4.18/include/net/bluetooth/bluetooth.h Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/include/net/bluetooth/bluetooth.h Mon Aug 25 18:38:11 2003
-@@ -23,7 +23,7 @@
- */
-
- /*
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __BLUETOOTH_H
-@@ -31,17 +31,63 @@
-
- #include <asm/types.h>
- #include <asm/byteorder.h>
-+#include <linux/poll.h>
-+#include <net/sock.h>
-
- #ifndef AF_BLUETOOTH
- #define AF_BLUETOOTH 31
- #define PF_BLUETOOTH AF_BLUETOOTH
- #endif
-
-+/* Reserv for core and drivers use */
-+#define BLUEZ_SKB_RESERVE 8
-+
-+#ifndef MIN
-+#define MIN(a,b) ((a) < (b) ? (a) : (b))
-+#endif
-+
- #define BTPROTO_L2CAP 0
- #define BTPROTO_HCI 1
-+#define BTPROTO_SCO 2
-+#define BTPROTO_RFCOMM 3
-+#define BTPROTO_BNEP 4
-+#define BTPROTO_CMTP 5
-
- #define SOL_HCI 0
- #define SOL_L2CAP 6
-+#define SOL_SCO 17
-+#define SOL_RFCOMM 18
-+
-+/* Debugging */
-+#ifdef CONFIG_BLUEZ_DEBUG
-+
-+#define HCI_CORE_DEBUG 1
-+#define HCI_SOCK_DEBUG 1
-+#define HCI_UART_DEBUG 1
-+#define HCI_USB_DEBUG 1
-+//#define HCI_DATA_DUMP 1
-+
-+#define L2CAP_DEBUG 1
-+#define SCO_DEBUG 1
-+#define AF_BLUETOOTH_DEBUG 1
-+
-+#endif /* CONFIG_BLUEZ_DEBUG */
-+
-+extern void bluez_dump(char *pref, __u8 *buf, int count);
-+
-+#if __GNUC__ <= 2 && __GNUC_MINOR__ < 95
-+#define __func__ __FUNCTION__
-+#endif
-+
-+#define BT_INFO(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
-+#define BT_DBG(fmt, arg...) printk(KERN_INFO "%s: " fmt "\n" , __func__ , ## arg)
-+#define BT_ERR(fmt, arg...) printk(KERN_ERR "%s: " fmt "\n" , __func__ , ## arg)
-+
-+#ifdef HCI_DATA_DUMP
-+#define BT_DMP(buf, len) bluez_dump(__func__, buf, len)
-+#else
-+#define BT_DMP(D...)
-+#endif
-
- /* Connection and socket states */
- enum {
-@@ -50,6 +96,7 @@
- BT_BOUND,
- BT_LISTEN,
- BT_CONNECT,
-+ BT_CONNECT2,
- BT_CONFIG,
- BT_DISCONN,
- BT_CLOSED
-@@ -66,7 +113,8 @@
- __u8 b[6];
- } __attribute__((packed)) bdaddr_t;
-
--#define BDADDR_ANY ((bdaddr_t *)"\000\000\000\000\000")
-+#define BDADDR_ANY (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
-+#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
-
- /* Copy, swap, convert BD Address */
- static inline int bacmp(bdaddr_t *ba1, bdaddr_t *ba2)
-@@ -82,6 +130,91 @@
- char *batostr(bdaddr_t *ba);
- bdaddr_t *strtoba(char *str);
-
-+/* Common socket structures and functions */
-+
-+#define bluez_pi(sk) ((struct bluez_pinfo *) &sk->protinfo)
-+#define bluez_sk(pi) ((struct sock *) \
-+ ((void *)pi - (unsigned long)(&((struct sock *)0)->protinfo)))
-+
-+struct bluez_pinfo {
-+ bdaddr_t src;
-+ bdaddr_t dst;
-+
-+ struct list_head accept_q;
-+ struct sock *parent;
-+};
-+
-+struct bluez_sock_list {
-+ struct sock *head;
-+ rwlock_t lock;
-+};
-+
-+int bluez_sock_register(int proto, struct net_proto_family *ops);
-+int bluez_sock_unregister(int proto);
-+void bluez_sock_init(struct socket *sock, struct sock *sk);
-+void bluez_sock_link(struct bluez_sock_list *l, struct sock *s);
-+void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *s);
-+int bluez_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm);
-+uint bluez_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
-+int bluez_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
-+
-+void bluez_accept_enqueue(struct sock *parent, struct sock *sk);
-+struct sock * bluez_accept_dequeue(struct sock *parent, struct socket *newsock);
-+
-+/* Skb helpers */
-+struct bluez_skb_cb {
-+ int incomming;
-+};
-+#define bluez_cb(skb) ((struct bluez_skb_cb *)(skb->cb))
-+
-+static inline struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
-+{
-+ struct sk_buff *skb;
-+
-+ if ((skb = alloc_skb(len + BLUEZ_SKB_RESERVE, how))) {
-+ skb_reserve(skb, BLUEZ_SKB_RESERVE);
-+ bluez_cb(skb)->incomming = 0;
-+ }
-+ return skb;
-+}
-+
-+static inline struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len,
-+ int nb, int *err)
-+{
-+ struct sk_buff *skb;
-+
-+ if ((skb = sock_alloc_send_skb(sk, len + BLUEZ_SKB_RESERVE, nb, err))) {
-+ skb_reserve(skb, BLUEZ_SKB_RESERVE);
-+ bluez_cb(skb)->incomming = 0;
-+ }
-+
-+ return skb;
-+}
-+
-+static inline int skb_frags_no(struct sk_buff *skb)
-+{
-+ register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
-+ register int n = 1;
-+
-+ for (; frag; frag=frag->next, n++);
-+ return n;
-+}
-+
-+int hci_core_init(void);
-+int hci_core_cleanup(void);
-+int hci_sock_init(void);
-+int hci_sock_cleanup(void);
-+
- int bterr(__u16 code);
-+
-+#ifndef MODULE_LICENSE
-+#define MODULE_LICENSE(x)
-+#endif
-+
-+#ifndef list_for_each_safe
-+#define list_for_each_safe(pos, n, head) \
-+ for (pos = (head)->next, n = pos->next; pos != (head); \
-+ pos = n, n = pos->next)
-+#endif
-
- #endif /* __BLUETOOTH_H */
-diff -urN linux-2.4.18/include/net/bluetooth/bluez.h linux-2.4.18-mh9/include/net/bluetooth/bluez.h
---- linux-2.4.18/include/net/bluetooth/bluez.h Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/include/net/bluetooth/bluez.h Thu Jan 1 01:00:00 1970
-@@ -1,124 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifndef __IF_BLUEZ_H
--#define __IF_BLUEZ_H
--
--#include <net/sock.h>
--
--#define BLUEZ_MAX_PROTO 2
--
--/* Reserv for core and drivers use */
--#define BLUEZ_SKB_RESERVE 8
--
--#ifndef MIN
--#define MIN(a,b) ((a) < (b) ? (a) : (b))
--#endif
--
--/* Debugging */
--#ifdef BLUEZ_DEBUG
--
--#define HCI_CORE_DEBUG 1
--#define HCI_SOCK_DEBUG 1
--#define HCI_UART_DEBUG 1
--#define HCI_USB_DEBUG 1
--//#define HCI_DATA_DUMP 1
--
--#define L2CAP_DEBUG 1
--
--#endif /* BLUEZ_DEBUG */
--
--extern void bluez_dump(char *pref, __u8 *buf, int count);
--
--#define INF(fmt, arg...) printk(KERN_INFO fmt "\n" , ## arg)
--#define DBG(fmt, arg...) printk(KERN_INFO __FUNCTION__ ": " fmt "\n" , ## arg)
--#define ERR(fmt, arg...) printk(KERN_ERR __FUNCTION__ ": " fmt "\n" , ## arg)
--
--#ifdef HCI_DATA_DUMP
--#define DMP(buf, len) bluez_dump(__FUNCTION__, buf, len)
--#else
--#define DMP(D...)
--#endif
--
--/* ----- Sockets ------ */
--struct bluez_sock_list {
-- struct sock *head;
-- rwlock_t lock;
--};
--
--extern int bluez_sock_register(int proto, struct net_proto_family *ops);
--extern int bluez_sock_unregister(int proto);
--
--extern void bluez_sock_link(struct bluez_sock_list *l, struct sock *s);
--extern void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *s);
--
--/* ----- SKB helpers ----- */
--struct bluez_skb_cb {
-- int incomming;
--};
--#define bluez_cb(skb) ((struct bluez_skb_cb *)(skb->cb))
--
--static inline struct sk_buff *bluez_skb_alloc(unsigned int len, int how)
--{
-- struct sk_buff *skb;
--
-- if ((skb = alloc_skb(len + BLUEZ_SKB_RESERVE, how))) {
-- skb_reserve(skb, BLUEZ_SKB_RESERVE);
-- bluez_cb(skb)->incomming = 0;
-- }
-- return skb;
--}
--
--static inline struct sk_buff *bluez_skb_send_alloc(struct sock *sk, unsigned long len,
-- int nb, int *err)
--{
-- struct sk_buff *skb;
--
-- if ((skb = sock_alloc_send_skb(sk, len + BLUEZ_SKB_RESERVE, nb, err))) {
-- skb_reserve(skb, BLUEZ_SKB_RESERVE);
-- bluez_cb(skb)->incomming = 0;
-- }
--
-- return skb;
--}
--
--static inline int skb_frags_no(struct sk_buff *skb)
--{
-- register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
-- register int n = 1;
--
-- for (; frag; frag=frag->next, n++);
-- return n;
--}
--
--extern int hci_core_init(void);
--extern int hci_core_cleanup(void);
--extern int hci_sock_init(void);
--extern int hci_sock_cleanup(void);
--
--#endif /* __IF_BLUEZ_H */
-diff -urN linux-2.4.18/include/net/bluetooth/hci.h linux-2.4.18-mh9/include/net/bluetooth/hci.h
---- linux-2.4.18/include/net/bluetooth/hci.h Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/include/net/bluetooth/hci.h Mon Aug 25 18:38:12 2003
-@@ -23,59 +23,80 @@
- */
-
- /*
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __HCI_H
- #define __HCI_H
-
--#include <asm/byteorder.h>
--
--#define HCI_MAX_DEV 8
--#define HCI_MAX_FRAME_SIZE 2048
-+#define HCI_MAX_ACL_SIZE 1024
-+#define HCI_MAX_SCO_SIZE 255
-+#define HCI_MAX_EVENT_SIZE 260
-+#define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4)
-
- /* HCI dev events */
- #define HCI_DEV_REG 1
- #define HCI_DEV_UNREG 2
- #define HCI_DEV_UP 3
- #define HCI_DEV_DOWN 4
-+#define HCI_DEV_SUSPEND 5
-+#define HCI_DEV_RESUME 6
-+
-+/* HCI notify events */
-+#define HCI_NOTIFY_CONN_ADD 1
-+#define HCI_NOTIFY_CONN_DEL 2
-+#define HCI_NOTIFY_VOICE_SETTING 3
-
- /* HCI device types */
--#define HCI_UART 0
-+#define HCI_VHCI 0
- #define HCI_USB 1
--#define HCI_VHCI 2
--
--/* HCI device modes */
--#define HCI_NORMAL 0x0001
--#define HCI_RAW 0x0002
--#define HCI_MODE_MASK (HCI_NORMAL | HCI_RAW)
--#define HCI_SOCK 0x1000
--
--/* HCI device states */
--#define HCI_INIT 0x0010
--#define HCI_UP 0x0020
--#define HCI_RUNNING 0x0040
-+#define HCI_PCCARD 2
-+#define HCI_UART 3
-+#define HCI_RS232 4
-+#define HCI_PCI 5
-
- /* HCI device flags */
--#define HCI_PSCAN 0x0100
--#define HCI_ISCAN 0x0200
--#define HCI_AUTH 0x0400
-+enum {
-+ HCI_UP,
-+ HCI_INIT,
-+ HCI_RUNNING,
-+
-+ HCI_PSCAN,
-+ HCI_ISCAN,
-+ HCI_AUTH,
-+ HCI_ENCRYPT,
-+ HCI_INQUIRY,
-+
-+ HCI_RAW
-+};
-
--/* HCI Ioctl defines */
-+/* HCI ioctl defines */
- #define HCIDEVUP _IOW('H', 201, int)
- #define HCIDEVDOWN _IOW('H', 202, int)
- #define HCIDEVRESET _IOW('H', 203, int)
--#define HCIRESETSTAT _IOW('H', 204, int)
--#define HCIGETINFO _IOR('H', 205, int)
--#define HCIGETDEVLIST _IOR('H', 206, int)
--#define HCISETRAW _IOW('H', 207, int)
--#define HCISETSCAN _IOW('H', 208, int)
--#define HCISETAUTH _IOW('H', 209, int)
--#define HCIINQUIRY _IOR('H', 210, int)
--#define HCISETPTYPE _IOW('H', 211, int)
-+#define HCIDEVRESTAT _IOW('H', 204, int)
-+
-+#define HCIGETDEVLIST _IOR('H', 210, int)
-+#define HCIGETDEVINFO _IOR('H', 211, int)
- #define HCIGETCONNLIST _IOR('H', 212, int)
-+#define HCIGETCONNINFO _IOR('H', 213, int)
-
--#ifndef __NO_HCI_DEFS
-+#define HCISETRAW _IOW('H', 220, int)
-+#define HCISETSCAN _IOW('H', 221, int)
-+#define HCISETAUTH _IOW('H', 222, int)
-+#define HCISETENCRYPT _IOW('H', 223, int)
-+#define HCISETPTYPE _IOW('H', 224, int)
-+#define HCISETLINKPOL _IOW('H', 225, int)
-+#define HCISETLINKMODE _IOW('H', 226, int)
-+#define HCISETACLMTU _IOW('H', 227, int)
-+#define HCISETSCOMTU _IOW('H', 228, int)
-+
-+#define HCIINQUIRY _IOR('H', 240, int)
-+
-+/* HCI timeouts */
-+#define HCI_CONN_TIMEOUT (HZ * 40)
-+#define HCI_DISCONN_TIMEOUT (HZ * 2)
-+#define HCI_CONN_IDLE_TIMEOUT (HZ * 60)
-
- /* HCI Packet types */
- #define HCI_COMMAND_PKT 0x01
-@@ -92,11 +113,18 @@
- #define HCI_DH3 0x0800
- #define HCI_DH5 0x8000
-
-+#define HCI_HV1 0x0020
-+#define HCI_HV2 0x0040
-+#define HCI_HV3 0x0080
-+
-+#define SCO_PTYPE_MASK (HCI_HV1 | HCI_HV2 | HCI_HV3)
-+#define ACL_PTYPE_MASK (~SCO_PTYPE_MASK)
-+
- /* ACL flags */
--#define ACL_CONT 0x0001
--#define ACL_START 0x0002
--#define ACL_ACTIVE_BCAST 0x0010
--#define ACL_PICO_BCAST 0x0020
-+#define ACL_CONT 0x01
-+#define ACL_START 0x02
-+#define ACL_ACTIVE_BCAST 0x04
-+#define ACL_PICO_BCAST 0x08
-
- /* Baseband links */
- #define SCO_LINK 0x00
-@@ -125,6 +153,20 @@
- #define LMP_PSCHEME 0x02
- #define LMP_PCONTROL 0x04
-
-+/* Link policies */
-+#define HCI_LP_RSWITCH 0x0001
-+#define HCI_LP_HOLD 0x0002
-+#define HCI_LP_SNIFF 0x0004
-+#define HCI_LP_PARK 0x0008
-+
-+/* Link mode */
-+#define HCI_LM_ACCEPT 0x8000
-+#define HCI_LM_MASTER 0x0001
-+#define HCI_LM_AUTH 0x0002
-+#define HCI_LM_ENCRYPT 0x0004
-+#define HCI_LM_TRUSTED 0x0008
-+#define HCI_LM_RELIABLE 0x0010
-+
- /* ----- HCI Commands ----- */
- /* OGF & OCF values */
-
-@@ -137,9 +179,10 @@
- __u8 hci_ver;
- __u16 hci_rev;
- __u8 lmp_ver;
-- __u16 man_name;
-- __u16 lmp_sub;
-+ __u16 manufacturer;
-+ __u16 lmp_subver;
- } __attribute__ ((packed)) read_local_version_rp;
-+#define READ_LOCAL_VERSION_RP_SIZE 9
-
- #define OCF_READ_LOCAL_FEATURES 0x0003
- typedef struct {
-@@ -165,18 +208,24 @@
- /* Host Controller and Baseband */
- #define OGF_HOST_CTL 0x03
- #define OCF_RESET 0x0003
-+#define OCF_READ_AUTH_ENABLE 0x001F
- #define OCF_WRITE_AUTH_ENABLE 0x0020
-- #define AUTH_DISABLED 0x00
-- #define AUTH_ENABLED 0x01
-+ #define AUTH_DISABLED 0x00
-+ #define AUTH_ENABLED 0x01
-+
-+#define OCF_READ_ENCRYPT_MODE 0x0021
-+#define OCF_WRITE_ENCRYPT_MODE 0x0022
-+ #define ENCRYPT_DISABLED 0x00
-+ #define ENCRYPT_P2P 0x01
-+ #define ENCRYPT_BOTH 0x02
-
- #define OCF_WRITE_CA_TIMEOUT 0x0016
- #define OCF_WRITE_PG_TIMEOUT 0x0018
-
- #define OCF_WRITE_SCAN_ENABLE 0x001A
-- #define SCANS_DISABLED 0x00
-- #define IS_ENA_PS_DIS 0x01
-- #define IS_DIS_PS_ENA 0x02
-- #define IS_ENA_PS_ENA 0x03
-+ #define SCAN_DISABLED 0x00
-+ #define SCAN_INQUIRY 0x01
-+ #define SCAN_PAGE 0x02
-
- #define OCF_SET_EVENT_FLT 0x0005
- typedef struct {
-@@ -226,9 +275,31 @@
- } __attribute__ ((packed)) write_class_of_dev_cp;
- #define WRITE_CLASS_OF_DEV_CP_SIZE 3
-
-+#define OCF_READ_VOICE_SETTING 0x0025
-+typedef struct {
-+ __u8 status;
-+ __u16 voice_setting;
-+} __attribute__ ((packed)) read_voice_setting_rp;
-+#define READ_VOICE_SETTING_RP_SIZE 3
-+
-+#define OCF_WRITE_VOICE_SETTING 0x0026
-+typedef struct {
-+ __u16 voice_setting;
-+} __attribute__ ((packed)) write_voice_setting_cp;
-+#define WRITE_VOICE_SETTING_CP_SIZE 2
-+
-+#define OCF_HOST_BUFFER_SIZE 0x0033
-+typedef struct {
-+ __u16 acl_mtu;
-+ __u8 sco_mtu;
-+ __u16 acl_max_pkt;
-+ __u16 sco_max_pkt;
-+} __attribute__ ((packed)) host_buffer_size_cp;
-+#define HOST_BUFFER_SIZE_CP_SIZE 7
-+
- /* Link Control */
- #define OGF_LINK_CTL 0x01
--#define OCF_CREATE_CONN 0x0005
-+#define OCF_CREATE_CONN 0x0005
- typedef struct {
- bdaddr_t bdaddr;
- __u16 pkt_type;
-@@ -246,6 +317,13 @@
- } __attribute__ ((packed)) accept_conn_req_cp;
- #define ACCEPT_CONN_REQ_CP_SIZE 7
-
-+#define OCF_REJECT_CONN_REQ 0x000a
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 reason;
-+} __attribute__ ((packed)) reject_conn_req_cp;
-+#define REJECT_CONN_REQ_CP_SIZE 7
-+
- #define OCF_DISCONNECT 0x0006
- typedef struct {
- __u16 handle;
-@@ -253,17 +331,142 @@
- } __attribute__ ((packed)) disconnect_cp;
- #define DISCONNECT_CP_SIZE 3
-
-+#define OCF_ADD_SCO 0x0007
-+typedef struct {
-+ __u16 handle;
-+ __u16 pkt_type;
-+} __attribute__ ((packed)) add_sco_cp;
-+#define ADD_SCO_CP_SIZE 4
-+
- #define OCF_INQUIRY 0x0001
- typedef struct {
- __u8 lap[3];
-- __u8 lenght;
-+ __u8 length;
- __u8 num_rsp;
- } __attribute__ ((packed)) inquiry_cp;
- #define INQUIRY_CP_SIZE 5
-
--#define OGF_LINK_POLICY 0x02 /* Link Policy */
-+typedef struct {
-+ __u8 status;
-+ bdaddr_t bdaddr;
-+} __attribute__ ((packed)) status_bdaddr_rp;
-+#define STATUS_BDADDR_RP_SIZE 7
-+
-+#define OCF_INQUIRY_CANCEL 0x0002
-+
-+#define OCF_LINK_KEY_REPLY 0x000B
-+#define OCF_LINK_KEY_NEG_REPLY 0x000C
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 link_key[16];
-+} __attribute__ ((packed)) link_key_reply_cp;
-+#define LINK_KEY_REPLY_CP_SIZE 22
-+
-+#define OCF_PIN_CODE_REPLY 0x000D
-+#define OCF_PIN_CODE_NEG_REPLY 0x000E
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 pin_len;
-+ __u8 pin_code[16];
-+} __attribute__ ((packed)) pin_code_reply_cp;
-+#define PIN_CODE_REPLY_CP_SIZE 23
-+
-+#define OCF_CHANGE_CONN_PTYPE 0x000F
-+typedef struct {
-+ __u16 handle;
-+ __u16 pkt_type;
-+} __attribute__ ((packed)) change_conn_ptype_cp;
-+#define CHANGE_CONN_PTYPE_CP_SIZE 4
-+
-+#define OCF_AUTH_REQUESTED 0x0011
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) auth_requested_cp;
-+#define AUTH_REQUESTED_CP_SIZE 2
-+
-+#define OCF_SET_CONN_ENCRYPT 0x0013
-+typedef struct {
-+ __u16 handle;
-+ __u8 encrypt;
-+} __attribute__ ((packed)) set_conn_encrypt_cp;
-+#define SET_CONN_ENCRYPT_CP_SIZE 3
-+
-+#define OCF_REMOTE_NAME_REQ 0x0019
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 pscan_rep_mode;
-+ __u8 pscan_mode;
-+ __u16 clock_offset;
-+} __attribute__ ((packed)) remote_name_req_cp;
-+#define REMOTE_NAME_REQ_CP_SIZE 10
-+
-+#define OCF_READ_REMOTE_FEATURES 0x001B
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) read_remote_features_cp;
-+#define READ_REMOTE_FEATURES_CP_SIZE 2
-+
-+#define OCF_READ_REMOTE_VERSION 0x001D
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) read_remote_version_cp;
-+#define READ_REMOTE_VERSION_CP_SIZE 2
-+
-+/* Link Policy */
-+#define OGF_LINK_POLICY 0x02
-+#define OCF_ROLE_DISCOVERY 0x0009
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) role_discovery_cp;
-+#define ROLE_DISCOVERY_CP_SIZE 2
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u8 role;
-+} __attribute__ ((packed)) role_discovery_rp;
-+#define ROLE_DISCOVERY_RP_SIZE 4
-
--/* --------- HCI Events --------- */
-+#define OCF_READ_LINK_POLICY 0x000C
-+typedef struct {
-+ __u16 handle;
-+} __attribute__ ((packed)) read_link_policy_cp;
-+#define READ_LINK_POLICY_CP_SIZE 2
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u16 policy;
-+} __attribute__ ((packed)) read_link_policy_rp;
-+#define READ_LINK_POLICY_RP_SIZE 5
-+
-+#define OCF_SWITCH_ROLE 0x000B
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 role;
-+} __attribute__ ((packed)) switch_role_cp;
-+#define SWITCH_ROLE_CP_SIZE 7
-+
-+#define OCF_WRITE_LINK_POLICY 0x000D
-+typedef struct {
-+ __u16 handle;
-+ __u16 policy;
-+} __attribute__ ((packed)) write_link_policy_cp;
-+#define WRITE_LINK_POLICY_CP_SIZE 4
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+} __attribute__ ((packed)) write_link_policy_rp;
-+#define WRITE_LINK_POLICY_RP_SIZE 3
-+
-+/* Status params */
-+#define OGF_STATUS_PARAM 0x05
-+
-+/* Testing commands */
-+#define OGF_TESTING_CMD 0x3e
-+
-+/* Vendor specific commands */
-+#define OGF_VENDOR_CMD 0x3f
-+
-+/* ---- HCI Events ---- */
- #define EVT_INQUIRY_COMPLETE 0x01
-
- #define EVT_INQUIRY_RESULT 0x02
-@@ -272,7 +475,7 @@
- __u8 pscan_rep_mode;
- __u8 pscan_period_mode;
- __u8 pscan_mode;
-- __u8 class[3];
-+ __u8 dev_class[3];
- __u16 clock_offset;
- } __attribute__ ((packed)) inquiry_info;
- #define INQUIRY_INFO_SIZE 14
-@@ -303,6 +506,44 @@
- } __attribute__ ((packed)) evt_disconn_complete;
- #define EVT_DISCONN_COMPLETE_SIZE 4
-
-+#define EVT_AUTH_COMPLETE 0x06
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+} __attribute__ ((packed)) evt_auth_complete;
-+#define EVT_AUTH_COMPLETE_SIZE 3
-+
-+#define EVT_REMOTE_NAME_REQ_COMPLETE 0x07
-+typedef struct {
-+ __u8 status;
-+ bdaddr_t bdaddr;
-+ __u8 name[248];
-+} __attribute__ ((packed)) evt_remote_name_req_complete;
-+#define EVT_REMOTE_NAME_REQ_COMPLETE_SIZE 255
-+
-+#define EVT_ENCRYPT_CHANGE 0x08
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u8 encrypt;
-+} __attribute__ ((packed)) evt_encrypt_change;
-+#define EVT_ENCRYPT_CHANGE_SIZE 5
-+
-+#define EVT_QOS_SETUP_COMPLETE 0x0D
-+typedef struct {
-+ __u8 service_type;
-+ __u32 token_rate;
-+ __u32 peak_bandwidth;
-+ __u32 latency;
-+ __u32 delay_variation;
-+} __attribute__ ((packed)) hci_qos;
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ hci_qos qos;
-+} __attribute__ ((packed)) evt_qos_setup_complete;
-+#define EVT_QOS_SETUP_COMPLETE_SIZE 20
-+
- #define EVT_CMD_COMPLETE 0x0e
- typedef struct {
- __u8 ncmd;
-@@ -321,16 +562,78 @@
- #define EVT_NUM_COMP_PKTS 0x13
- typedef struct {
- __u8 num_hndl;
-- /* variable lenght part */
-+ /* variable length part */
- } __attribute__ ((packed)) evt_num_comp_pkts;
- #define EVT_NUM_COMP_PKTS_SIZE 1
-
--#define EVT_HCI_DEV_EVENT 0xfd
-+#define EVT_ROLE_CHANGE 0x12
-+typedef struct {
-+ __u8 status;
-+ bdaddr_t bdaddr;
-+ __u8 role;
-+} __attribute__ ((packed)) evt_role_change;
-+#define EVT_ROLE_CHANGE_SIZE 8
-+
-+#define EVT_PIN_CODE_REQ 0x16
-+typedef struct {
-+ bdaddr_t bdaddr;
-+} __attribute__ ((packed)) evt_pin_code_req;
-+#define EVT_PIN_CODE_REQ_SIZE 6
-+
-+#define EVT_LINK_KEY_REQ 0x17
-+typedef struct {
-+ bdaddr_t bdaddr;
-+} __attribute__ ((packed)) evt_link_key_req;
-+#define EVT_LINK_KEY_REQ_SIZE 6
-+
-+#define EVT_LINK_KEY_NOTIFY 0x18
-+typedef struct {
-+ bdaddr_t bdaddr;
-+ __u8 link_key[16];
-+ __u8 key_type;
-+} __attribute__ ((packed)) evt_link_key_notify;
-+#define EVT_LINK_KEY_NOTIFY_SIZE 23
-+
-+#define EVT_READ_REMOTE_FEATURES_COMPLETE 0x0B
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u8 features[8];
-+} __attribute__ ((packed)) evt_read_remote_features_complete;
-+#define EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE 11
-+
-+#define EVT_READ_REMOTE_VERSION_COMPLETE 0x0C
-+typedef struct {
-+ __u8 status;
-+ __u16 handle;
-+ __u8 lmp_ver;
-+ __u16 manufacturer;
-+ __u16 lmp_subver;
-+} __attribute__ ((packed)) evt_read_remote_version_complete;
-+#define EVT_READ_REMOTE_VERSION_COMPLETE_SIZE 8
-+
-+/* Internal events generated by BlueZ stack */
-+#define EVT_STACK_INTERNAL 0xfd
-+typedef struct {
-+ __u16 type;
-+ __u8 data[0];
-+} __attribute__ ((packed)) evt_stack_internal;
-+#define EVT_STACK_INTERNAL_SIZE 2
-+
-+#define EVT_SI_DEVICE 0x01
-+typedef struct {
-+ __u16 event;
-+ __u16 dev_id;
-+} __attribute__ ((packed)) evt_si_device;
-+#define EVT_SI_DEVICE_SIZE 4
-+
-+#define EVT_SI_SECURITY 0x02
- typedef struct {
- __u16 event;
-- __u16 param;
--} __attribute__ ((packed)) evt_hci_dev_event;
--#define EVT_HCI_DEV_EVENT_SIZE 4
-+ __u16 proto;
-+ __u16 subproto;
-+ __u8 incomming;
-+} __attribute__ ((packed)) evt_si_security;
-
- /* -------- HCI Packet structures -------- */
- #define HCI_TYPE_LEN 1
-@@ -369,14 +672,14 @@
- #define acl_handle(h) (h & 0x0fff)
- #define acl_flags(h) (h >> 12)
-
--#endif /* _NO_HCI_DEFS */
--
- /* HCI Socket options */
--#define HCI_DATA_DIR 0x0001
--#define HCI_FILTER 0x0002
-+#define HCI_DATA_DIR 1
-+#define HCI_FILTER 2
-+#define HCI_TIME_STAMP 3
-
- /* HCI CMSG flags */
- #define HCI_CMSG_DIR 0x0001
-+#define HCI_CMSG_TSTAMP 0x0002
-
- struct sockaddr_hci {
- sa_family_t hci_family;
-@@ -387,27 +690,29 @@
- struct hci_filter {
- __u32 type_mask;
- __u32 event_mask[2];
-+ __u16 opcode;
- };
-
--struct hci_dev_req {
-- __u16 dev_id;
-- __u32 dev_opt;
--};
--
--struct hci_dev_list_req {
-- __u16 dev_num;
-- struct hci_dev_req dev_req[0]; /* hci_dev_req structures */
--};
--
--struct hci_inquiry_req {
-- __u16 dev_id;
-- __u16 flags;
-- __u8 lap[3];
-- __u8 length;
-- __u8 num_rsp;
--};
--#define IREQ_CACHE_FLUSH 0x0001
-+#define HCI_FLT_TYPE_BITS 31
-+#define HCI_FLT_EVENT_BITS 63
-+#define HCI_FLT_OGF_BITS 63
-+#define HCI_FLT_OCF_BITS 127
-+
-+#if BITS_PER_LONG == 64
-+static inline void hci_set_bit(int nr, void *addr)
-+{
-+ *((__u32 *) addr + (nr >> 5)) |= ((__u32) 1 << (nr & 31));
-+}
-+static inline int hci_test_bit(int nr, void *addr)
-+{
-+ return *((__u32 *) addr + (nr >> 5)) & ((__u32) 1 << (nr & 31));
-+}
-+#else
-+#define hci_set_bit set_bit
-+#define hci_test_bit test_bit
-+#endif
-
-+/* Ioctl requests structures */
- struct hci_dev_stats {
- __u32 err_rx;
- __u32 err_tx;
-@@ -433,11 +738,13 @@
- __u8 features[8];
-
- __u32 pkt_type;
-+ __u32 link_policy;
-+ __u32 link_mode;
-
- __u16 acl_mtu;
-- __u16 acl_max;
-+ __u16 acl_pkts;
- __u16 sco_mtu;
-- __u16 sco_max;
-+ __u16 sco_pkts;
-
- struct hci_dev_stats stat;
- };
-@@ -445,12 +752,48 @@
- struct hci_conn_info {
- __u16 handle;
- bdaddr_t bdaddr;
-+ __u8 type;
-+ __u8 out;
-+ __u16 state;
-+ __u32 link_mode;
-+};
-+
-+struct hci_dev_req {
-+ __u16 dev_id;
-+ __u32 dev_opt;
-+};
-+
-+struct hci_dev_list_req {
-+ __u16 dev_num;
-+ struct hci_dev_req dev_req[0]; /* hci_dev_req structures */
- };
-
- struct hci_conn_list_req {
- __u16 dev_id;
- __u16 conn_num;
- struct hci_conn_info conn_info[0];
-+};
-+
-+struct hci_conn_info_req {
-+ bdaddr_t bdaddr;
-+ __u8 type;
-+ struct hci_conn_info conn_info[0];
-+};
-+
-+struct hci_inquiry_req {
-+ __u16 dev_id;
-+ __u16 flags;
-+ __u8 lap[3];
-+ __u8 length;
-+ __u8 num_rsp;
-+};
-+#define IREQ_CACHE_FLUSH 0x0001
-+
-+struct hci_remotename_req {
-+ __u16 dev_id;
-+ __u16 flags;
-+ bdaddr_t bdaddr;
-+ __u8 name[248];
- };
-
- #endif /* __HCI_H */
-diff -urN linux-2.4.18/include/net/bluetooth/hci_core.h linux-2.4.18-mh9/include/net/bluetooth/hci_core.h
---- linux-2.4.18/include/net/bluetooth/hci_core.h Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/include/net/bluetooth/hci_core.h Mon Aug 25 18:38:12 2003
-@@ -23,7 +23,7 @@
- */
-
- /*
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __HCI_CORE_H
-@@ -32,14 +32,12 @@
- #include <net/bluetooth/hci.h>
-
- /* HCI upper protocols */
--#define HCI_MAX_PROTO 1
- #define HCI_PROTO_L2CAP 0
-+#define HCI_PROTO_SCO 1
-
- #define HCI_INIT_TIMEOUT (HZ * 10)
-
--/* ----- Inquiry cache ----- */
--#define INQUIRY_CACHE_AGE_MAX (HZ*5) // 5 seconds
--#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds
-+/* HCI Core structures */
-
- struct inquiry_entry {
- struct inquiry_entry *next;
-@@ -53,111 +51,182 @@
- struct inquiry_entry *list;
- };
-
--static inline void inquiry_cache_init(struct inquiry_cache *cache)
--{
-- spin_lock_init(&cache->lock);
-- cache->list = NULL;
--}
-+struct conn_hash {
-+ struct list_head list;
-+ spinlock_t lock;
-+ unsigned int num;
-+};
-
--static inline void inquiry_cache_lock(struct inquiry_cache *cache)
--{
-- spin_lock(&cache->lock);
--}
-+struct hci_dev {
-+ struct list_head list;
-+ spinlock_t lock;
-+ atomic_t refcnt;
-
--static inline void inquiry_cache_unlock(struct inquiry_cache *cache)
--{
-- spin_unlock(&cache->lock);
--}
-+ char name[8];
-+ unsigned long flags;
-+ __u16 id;
-+ __u8 type;
-+ bdaddr_t bdaddr;
-+ __u8 features[8];
-+ __u16 voice_setting;
-
--static inline void inquiry_cache_lock_bh(struct inquiry_cache *cache)
--{
-- spin_lock_bh(&cache->lock);
--}
-+ __u16 pkt_type;
-+ __u16 link_policy;
-+ __u16 link_mode;
-
--static inline void inquiry_cache_unlock_bh(struct inquiry_cache *cache)
--{
-- spin_unlock_bh(&cache->lock);
--}
-+ atomic_t cmd_cnt;
-+ unsigned int acl_cnt;
-+ unsigned int sco_cnt;
-
--static inline long inquiry_cache_age(struct inquiry_cache *cache)
--{
-- return jiffies - cache->timestamp;
--}
-+ unsigned int acl_mtu;
-+ unsigned int sco_mtu;
-+ unsigned int acl_pkts;
-+ unsigned int sco_pkts;
-
--static inline long inquiry_entry_age(struct inquiry_entry *e)
--{
-- return jiffies - e->timestamp;
--}
--extern void inquiry_cache_flush(struct inquiry_cache *cache);
-+ unsigned long cmd_last_tx;
-+ unsigned long acl_last_tx;
-+ unsigned long sco_last_tx;
-+
-+ struct tasklet_struct cmd_task;
-+ struct tasklet_struct rx_task;
-+ struct tasklet_struct tx_task;
-
--struct hci_dev;
-+ struct sk_buff_head rx_q;
-+ struct sk_buff_head raw_q;
-+ struct sk_buff_head cmd_q;
-+
-+ struct sk_buff *sent_cmd;
-+
-+ struct semaphore req_lock;
-+ wait_queue_head_t req_wait_q;
-+ __u32 req_status;
-+ __u32 req_result;
-+
-+ struct inquiry_cache inq_cache;
-+ struct conn_hash conn_hash;
-+
-+ struct hci_dev_stats stat;
-+
-+ void *driver_data;
-+ void *core_data;
-+
-+ atomic_t promisc;
-+
-+ int (*open)(struct hci_dev *hdev);
-+ int (*close)(struct hci_dev *hdev);
-+ int (*flush)(struct hci_dev *hdev);
-+ int (*send)(struct sk_buff *skb);
-+ void (*destruct)(struct hci_dev *hdev);
-+ void (*notify)(struct hci_dev *hdev, unsigned int evt, unsigned long arg);
-+ int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
-+};
-
--/* ----- HCI Connections ----- */
- struct hci_conn {
- struct list_head list;
-+
-+ atomic_t refcnt;
-+ spinlock_t lock;
-+
- bdaddr_t dst;
- __u16 handle;
-+ __u16 state;
- __u8 type;
-- unsigned int sent;
-+ __u8 out;
-+ __u32 link_mode;
-+ unsigned long pend;
-+
-+ unsigned int sent;
-+
-+ struct sk_buff_head data_q;
-
-+ struct timer_list timer;
-+
- struct hci_dev *hdev;
- void *l2cap_data;
-+ void *sco_data;
- void *priv;
-
-- struct sk_buff_head data_q;
-+ struct hci_conn *link;
- };
-
--struct conn_hash {
-- struct list_head list;
-- spinlock_t lock;
-- unsigned int num;
--};
-+extern struct hci_proto *hci_proto[];
-+extern struct list_head hdev_list;
-+extern rwlock_t hdev_list_lock;
-+
-+/* ----- Inquiry cache ----- */
-+#define INQUIRY_CACHE_AGE_MAX (HZ*30) // 30 seconds
-+#define INQUIRY_ENTRY_AGE_MAX (HZ*60) // 60 seconds
-+
-+#define inquiry_cache_lock(c) spin_lock(&c->lock)
-+#define inquiry_cache_unlock(c) spin_unlock(&c->lock)
-+#define inquiry_cache_lock_bh(c) spin_lock_bh(&c->lock)
-+#define inquiry_cache_unlock_bh(c) spin_unlock_bh(&c->lock)
-
--static inline void conn_hash_init(struct conn_hash *h)
-+static inline void inquiry_cache_init(struct hci_dev *hdev)
- {
-- INIT_LIST_HEAD(&h->list);
-- spin_lock_init(&h->lock);
-- h->num = 0;
-+ struct inquiry_cache *c = &hdev->inq_cache;
-+ spin_lock_init(&c->lock);
-+ c->list = NULL;
- }
-
--static inline void conn_hash_lock(struct conn_hash *h)
-+static inline long inquiry_cache_age(struct hci_dev *hdev)
- {
-- spin_lock(&h->lock);
-+ struct inquiry_cache *c = &hdev->inq_cache;
-+ return jiffies - c->timestamp;
- }
-
--static inline void conn_hash_unlock(struct conn_hash *h)
-+static inline long inquiry_entry_age(struct inquiry_entry *e)
- {
-- spin_unlock(&h->lock);
-+ return jiffies - e->timestamp;
- }
-
--static inline void __conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
-+struct inquiry_entry *inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr);
-+void inquiry_cache_update(struct hci_dev *hdev, inquiry_info *info);
-+void inquiry_cache_flush(struct hci_dev *hdev);
-+int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf);
-+
-+/* ----- HCI Connections ----- */
-+enum {
-+ HCI_CONN_AUTH_PEND,
-+ HCI_CONN_ENCRYPT_PEND
-+};
-+
-+#define hci_conn_lock(c) spin_lock(&c->lock)
-+#define hci_conn_unlock(c) spin_unlock(&c->lock)
-+#define hci_conn_lock_bh(c) spin_lock_bh(&c->lock)
-+#define hci_conn_unlock_bh(c) spin_unlock_bh(&c->lock)
-+
-+#define conn_hash_lock(d) spin_lock(&d->conn_hash->lock)
-+#define conn_hash_unlock(d) spin_unlock(&d->conn_hash->lock)
-+#define conn_hash_lock_bh(d) spin_lock_bh(&d->conn_hash->lock)
-+#define conn_hash_unlock_bh(d) spin_unlock_bh(&d->conn_hash->lock)
-+
-+static inline void conn_hash_init(struct hci_dev *hdev)
- {
-- list_add(&c->list, &h->list);
-- h->num++;
-+ struct conn_hash *h = &hdev->conn_hash;
-+ INIT_LIST_HEAD(&h->list);
-+ spin_lock_init(&h->lock);
-+ h->num = 0;
- }
-
--static inline void conn_hash_add(struct conn_hash *h, __u16 handle, struct hci_conn *c)
-+static inline void conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
- {
-- conn_hash_lock(h);
-- __conn_hash_add(h, handle, c);
-- conn_hash_unlock(h);
-+ struct conn_hash *h = &hdev->conn_hash;
-+ list_add(&c->list, &h->list);
-+ h->num++;
- }
-
--static inline void __conn_hash_del(struct conn_hash *h, struct hci_conn *c)
-+static inline void conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
- {
-+ struct conn_hash *h = &hdev->conn_hash;
- list_del(&c->list);
- h->num--;
- }
-
--static inline void conn_hash_del(struct conn_hash *h, struct hci_conn *c)
--{
-- conn_hash_lock(h);
-- __conn_hash_del(h, c);
-- conn_hash_unlock(h);
--}
--
--static inline struct hci_conn *__conn_hash_lookup(struct conn_hash *h, __u16 handle)
-+static inline struct hci_conn *conn_hash_lookup_handle(struct hci_dev *hdev,
-+ __u16 handle)
- {
-+ register struct conn_hash *h = &hdev->conn_hash;
- register struct list_head *p;
- register struct hci_conn *c;
-
-@@ -169,101 +238,95 @@
- return NULL;
- }
-
--static inline struct hci_conn *conn_hash_lookup(struct conn_hash *h, __u16 handle)
-+static inline struct hci_conn *conn_hash_lookup_ba(struct hci_dev *hdev,
-+ __u8 type, bdaddr_t *ba)
- {
-- struct hci_conn *conn;
-+ register struct conn_hash *h = &hdev->conn_hash;
-+ register struct list_head *p;
-+ register struct hci_conn *c;
-
-- conn_hash_lock(h);
-- conn = __conn_hash_lookup(h, handle);
-- conn_hash_unlock(h);
-- return conn;
-+ list_for_each(p, &h->list) {
-+ c = list_entry(p, struct hci_conn, list);
-+ if (c->type == type && !bacmp(&c->dst, ba))
-+ return c;
-+ }
-+ return NULL;
- }
-
--/* ----- HCI Devices ----- */
--struct hci_dev {
-- atomic_t refcnt;
--
-- char name[8];
-- __u32 flags;
-- __u16 id;
-- __u8 type;
-- bdaddr_t bdaddr;
-- __u8 features[8];
--
-- __u16 pkt_type;
--
-- atomic_t cmd_cnt;
-- unsigned int acl_cnt;
-- unsigned int sco_cnt;
--
-- unsigned int acl_mtu;
-- unsigned int sco_mtu;
-- unsigned int acl_max;
-- unsigned int sco_max;
--
-- void *driver_data;
-- void *l2cap_data;
-- void *priv;
--
-- struct tasklet_struct cmd_task;
-- struct tasklet_struct rx_task;
-- struct tasklet_struct tx_task;
--
-- struct sk_buff_head rx_q;
-- struct sk_buff_head raw_q;
-- struct sk_buff_head cmd_q;
--
-- struct sk_buff *sent_cmd;
--
-- struct semaphore req_lock;
-- wait_queue_head_t req_wait_q;
-- __u32 req_status;
-- __u32 req_result;
--
-- struct inquiry_cache inq_cache;
-+void hci_acl_connect(struct hci_conn *conn);
-+void hci_acl_disconn(struct hci_conn *conn, __u8 reason);
-+void hci_add_sco(struct hci_conn *conn, __u16 handle);
-
-- struct conn_hash conn_hash;
-+struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
-+int hci_conn_del(struct hci_conn *conn);
-+void hci_conn_hash_flush(struct hci_dev *hdev);
-
-- struct hci_dev_stats stat;
-+struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src);
-+int hci_conn_auth(struct hci_conn *conn);
-+int hci_conn_encrypt(struct hci_conn *conn);
-
-- int (*open)(struct hci_dev *hdev);
-- int (*close)(struct hci_dev *hdev);
-- int (*flush)(struct hci_dev *hdev);
-- int (*send)(struct sk_buff *skb);
--};
-+static inline void hci_conn_set_timer(struct hci_conn *conn, long timeout)
-+{
-+ mod_timer(&conn->timer, jiffies + timeout);
-+}
-
--static inline void hci_dev_hold(struct hci_dev *hdev)
-+static inline void hci_conn_del_timer(struct hci_conn *conn)
- {
-- atomic_inc(&hdev->refcnt);
-+ del_timer(&conn->timer);
- }
-
--static inline void hci_dev_put(struct hci_dev *hdev)
-+static inline void hci_conn_hold(struct hci_conn *conn)
- {
-- atomic_dec(&hdev->refcnt);
-+ atomic_inc(&conn->refcnt);
-+ hci_conn_del_timer(conn);
- }
-
--extern struct hci_dev *hci_dev_get(int index);
--extern int hci_register_dev(struct hci_dev *hdev);
--extern int hci_unregister_dev(struct hci_dev *hdev);
--extern int hci_dev_open(__u16 dev);
--extern int hci_dev_close(__u16 dev);
--extern int hci_dev_reset(__u16 dev);
--extern int hci_dev_reset_stat(__u16 dev);
--extern int hci_dev_info(unsigned long arg);
--extern int hci_dev_list(unsigned long arg);
--extern int hci_dev_setscan(unsigned long arg);
--extern int hci_dev_setauth(unsigned long arg);
--extern int hci_dev_setptype(unsigned long arg);
--extern int hci_conn_list(unsigned long arg);
--extern int hci_inquiry(unsigned long arg);
-+static inline void hci_conn_put(struct hci_conn *conn)
-+{
-+ if (atomic_dec_and_test(&conn->refcnt)) {
-+ if (conn->type == SCO_LINK)
-+ hci_conn_set_timer(conn, HZ / 100);
-+ else if (conn->out)
-+ hci_conn_set_timer(conn, HCI_DISCONN_TIMEOUT);
-+ }
-+}
-
--extern __u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode);
--extern __u32 hci_dev_getmode(struct hci_dev *hdev);
-+/* ----- HCI Devices ----- */
-+static inline void hci_dev_put(struct hci_dev *d)
-+{
-+ if (atomic_dec_and_test(&d->refcnt))
-+ d->destruct(d);
-+}
-+#define hci_dev_hold(d) atomic_inc(&d->refcnt)
-+
-+#define hci_dev_lock(d) spin_lock(&d->lock)
-+#define hci_dev_unlock(d) spin_unlock(&d->lock)
-+#define hci_dev_lock_bh(d) spin_lock_bh(&d->lock)
-+#define hci_dev_unlock_bh(d) spin_unlock_bh(&d->lock)
-+
-+struct hci_dev *hci_dev_get(int index);
-+struct hci_dev *hci_get_route(bdaddr_t *src, bdaddr_t *dst);
-+int hci_register_dev(struct hci_dev *hdev);
-+int hci_unregister_dev(struct hci_dev *hdev);
-+int hci_suspend_dev(struct hci_dev *hdev);
-+int hci_resume_dev(struct hci_dev *hdev);
-+int hci_dev_open(__u16 dev);
-+int hci_dev_close(__u16 dev);
-+int hci_dev_reset(__u16 dev);
-+int hci_dev_reset_stat(__u16 dev);
-+int hci_dev_cmd(unsigned int cmd, unsigned long arg);
-+int hci_get_dev_list(unsigned long arg);
-+int hci_get_dev_info(unsigned long arg);
-+int hci_get_conn_list(unsigned long arg);
-+int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg);
-+int hci_inquiry(unsigned long arg);
-
--extern int hci_recv_frame(struct sk_buff *skb);
-+int hci_recv_frame(struct sk_buff *skb);
-+void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
-
- /* ----- LMP capabilities ----- */
- #define lmp_rswitch_capable(dev) (dev->features[0] & LMP_RSWITCH)
-+#define lmp_encrypt_capable(dev) (dev->features[0] & LMP_ENCRYPT)
-
- /* ----- HCI tasks ----- */
- static inline void hci_sched_cmd(struct hci_dev *hdev)
-@@ -284,43 +347,130 @@
- /* ----- HCI protocols ----- */
- struct hci_proto {
- char *name;
-- __u32 id;
-- __u32 flags;
-+ unsigned int id;
-+ unsigned long flags;
-
- void *priv;
-
-- int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr);
-- int (*connect_cfm) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 status, struct hci_conn *conn);
-+ int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type);
-+ int (*connect_cfm) (struct hci_conn *conn, __u8 status);
- int (*disconn_ind) (struct hci_conn *conn, __u8 reason);
-- int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb , __u16 flags);
-+ int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
- int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb);
-+ int (*auth_cfm) (struct hci_conn *conn, __u8 status);
-+ int (*encrypt_cfm) (struct hci_conn *conn, __u8 status);
- };
-
--extern int hci_register_proto(struct hci_proto *hproto);
--extern int hci_unregister_proto(struct hci_proto *hproto);
--extern int hci_register_notifier(struct notifier_block *nb);
--extern int hci_unregister_notifier(struct notifier_block *nb);
--extern int hci_connect(struct hci_dev * hdev, bdaddr_t * bdaddr);
--extern int hci_disconnect(struct hci_conn *conn, __u8 reason);
--extern int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void * param);
--extern int hci_send_raw(struct sk_buff *skb);
--extern int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
--extern int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
-+static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
-+{
-+ register struct hci_proto *hp;
-+ int mask = 0;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->connect_ind)
-+ mask |= hp->connect_ind(hdev, bdaddr, type);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->connect_ind)
-+ mask |= hp->connect_ind(hdev, bdaddr, type);
-+
-+ return mask;
-+}
-+
-+static inline void hci_proto_connect_cfm(struct hci_conn *conn, __u8 status)
-+{
-+ register struct hci_proto *hp;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->connect_cfm)
-+ hp->connect_cfm(conn, status);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->connect_cfm)
-+ hp->connect_cfm(conn, status);
-+}
-+
-+static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason)
-+{
-+ register struct hci_proto *hp;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->disconn_ind)
-+ hp->disconn_ind(conn, reason);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->disconn_ind)
-+ hp->disconn_ind(conn, reason);
-+}
-+
-+static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
-+{
-+ register struct hci_proto *hp;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->auth_cfm)
-+ hp->auth_cfm(conn, status);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->auth_cfm)
-+ hp->auth_cfm(conn, status);
-+}
-+
-+static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status)
-+{
-+ register struct hci_proto *hp;
-+
-+ hp = hci_proto[HCI_PROTO_L2CAP];
-+ if (hp && hp->encrypt_cfm)
-+ hp->encrypt_cfm(conn, status);
-+
-+ hp = hci_proto[HCI_PROTO_SCO];
-+ if (hp && hp->encrypt_cfm)
-+ hp->encrypt_cfm(conn, status);
-+}
-+
-+int hci_register_proto(struct hci_proto *hproto);
-+int hci_unregister_proto(struct hci_proto *hproto);
-+int hci_register_notifier(struct notifier_block *nb);
-+int hci_unregister_notifier(struct notifier_block *nb);
-+
-+int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param);
-+int hci_send_acl(struct hci_conn *conn, struct sk_buff *skb, __u16 flags);
-+int hci_send_sco(struct hci_conn *conn, struct sk_buff *skb);
-+
-+void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf);
-+
-+void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data);
-
- /* ----- HCI Sockets ----- */
--extern void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
-+void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb);
-
- /* HCI info for socket */
--#define hci_pi(sk) ((struct hci_pinfo *) &sk->protinfo)
-+#define hci_pi(sk) ((struct hci_pinfo *) &sk->tp_pinfo)
- struct hci_pinfo {
- struct hci_dev *hdev;
- struct hci_filter filter;
- __u32 cmsg_mask;
- };
-
-+/* HCI security filter */
-+#define HCI_SFLT_MAX_OGF 5
-+
-+struct hci_sec_filter {
-+ __u32 type_mask;
-+ __u32 event_mask[2];
-+ __u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4];
-+};
-+
- /* ----- HCI requests ----- */
- #define HCI_REQ_DONE 0
- #define HCI_REQ_PEND 1
- #define HCI_REQ_CANCELED 2
-+
-+#define hci_req_lock(d) down(&d->req_lock)
-+#define hci_req_unlock(d) up(&d->req_lock)
-+
-+void hci_req_complete(struct hci_dev *hdev, int result);
-+void hci_req_cancel(struct hci_dev *hdev, int err);
-
- #endif /* __HCI_CORE_H */
-diff -urN linux-2.4.18/include/net/bluetooth/hci_uart.h linux-2.4.18-mh9/include/net/bluetooth/hci_uart.h
---- linux-2.4.18/include/net/bluetooth/hci_uart.h Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/include/net/bluetooth/hci_uart.h Thu Jan 1 01:00:00 1970
-@@ -1,62 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifndef N_HCI
--#define N_HCI 15
--#endif
--
--#ifdef __KERNEL__
--
--#define tty2n_hci(tty) ((struct n_hci *)((tty)->disc_data))
--#define n_hci2tty(n_hci) ((n_hci)->tty)
--
--struct n_hci {
-- struct tty_struct *tty;
-- struct hci_dev hdev;
--
-- struct sk_buff_head txq;
-- unsigned long tx_state;
--
-- spinlock_t rx_lock;
-- unsigned long rx_state;
-- unsigned long rx_count;
-- struct sk_buff *rx_skb;
--};
--
--/* Transmit states */
--#define TRANS_SENDING 1
--#define TRANS_WAKEUP 2
--
--/* Receiver States */
--#define WAIT_PACKET_TYPE 0
--#define WAIT_EVENT_HDR 1
--#define WAIT_ACL_HDR 2
--#define WAIT_SCO_HDR 3
--#define WAIT_DATA 4
--
--#endif /* __KERNEL__ */
-diff -urN linux-2.4.18/include/net/bluetooth/hci_usb.h linux-2.4.18-mh9/include/net/bluetooth/hci_usb.h
---- linux-2.4.18/include/net/bluetooth/hci_usb.h Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/include/net/bluetooth/hci_usb.h Thu Jan 1 01:00:00 1970
-@@ -1,68 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifdef __KERNEL__
--
--/* Class, SubClass, and Protocol codes that describe a Bluetooth device */
--#define HCI_DEV_CLASS 0xe0 /* Wireless class */
--#define HCI_DEV_SUBCLASS 0x01 /* RF subclass */
--#define HCI_DEV_PROTOCOL 0x01 /* Bluetooth programming protocol */
--
--#define HCI_CTRL_REQ 0x20
--
--struct hci_usb {
-- struct usb_device *udev;
--
-- devrequest dev_req;
-- struct urb *ctrl_urb;
-- struct urb *intr_urb;
-- struct urb *read_urb;
-- struct urb *write_urb;
--
-- __u8 *read_buf;
-- __u8 *intr_buf;
-- struct sk_buff *intr_skb;
-- int intr_count;
--
-- __u8 bulk_out_ep_addr;
-- __u8 bulk_in_ep_addr;
-- __u8 intr_in_ep_addr;
-- __u8 intr_in_interval;
--
-- struct hci_dev hdev;
--
-- unsigned long tx_state;
-- struct sk_buff_head tx_ctrl_q;
-- struct sk_buff_head tx_write_q;
--};
--
--/* Transmit states */
--#define HCI_TX_CTRL 1
--#define HCI_TX_WRITE 2
--
--#endif /* __KERNEL__ */
-diff -urN linux-2.4.18/include/net/bluetooth/hci_vhci.h linux-2.4.18-mh9/include/net/bluetooth/hci_vhci.h
---- linux-2.4.18/include/net/bluetooth/hci_vhci.h Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/include/net/bluetooth/hci_vhci.h Thu Jan 1 01:00:00 1970
-@@ -1,50 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifndef __HCI_VHCI_H
--#define __HCI_VHCI_H
--
--#ifdef __KERNEL__
--
--struct hci_vhci_struct {
-- struct hci_dev hdev;
-- __u32 flags;
-- wait_queue_head_t read_wait;
-- struct sk_buff_head readq;
-- struct fasync_struct *fasync;
--};
--
--/* VHCI device flags */
--#define VHCI_FASYNC 0x0010
--
--#endif /* __KERNEL__ */
--
--#define VHCI_DEV "/dev/vhci"
--#define VHCI_MINOR 250
--
--#endif /* __HCI_VHCI_H */
-diff -urN linux-2.4.18/include/net/bluetooth/l2cap.h linux-2.4.18-mh9/include/net/bluetooth/l2cap.h
---- linux-2.4.18/include/net/bluetooth/l2cap.h Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/include/net/bluetooth/l2cap.h Mon Aug 25 18:38:12 2003
-@@ -23,22 +23,17 @@
- */
-
- /*
-- * $Id$
-+ * $Id$
- */
-
- #ifndef __L2CAP_H
- #define __L2CAP_H
-
--#include <asm/types.h>
--#include <asm/byteorder.h>
--
- /* L2CAP defaults */
- #define L2CAP_DEFAULT_MTU 672
- #define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
-
- #define L2CAP_CONN_TIMEOUT (HZ * 40)
--#define L2CAP_DISCONN_TIMEOUT (HZ * 2)
--#define L2CAP_CONN_IDLE_TIMEOUT (HZ * 60)
-
- /* L2CAP socket address */
- struct sockaddr_l2 {
-@@ -47,17 +42,12 @@
- bdaddr_t l2_bdaddr;
- };
-
--/* set/get sockopt defines */
--#define L2CAP_OPTIONS 0x01
-+/* Socket options */
-+#define L2CAP_OPTIONS 0x01
- struct l2cap_options {
- __u16 omtu;
- __u16 imtu;
- __u16 flush_to;
-- __u32 token_rate;
-- __u32 bucket_size;
-- __u32 pick_band;
-- __u32 latency;
-- __u32 delay_var;
- };
-
- #define L2CAP_CONNINFO 0x02
-@@ -65,6 +55,27 @@
- __u16 hci_handle;
- };
-
-+#define L2CAP_LM 0x03
-+#define L2CAP_LM_MASTER 0x0001
-+#define L2CAP_LM_AUTH 0x0002
-+#define L2CAP_LM_ENCRYPT 0x0004
-+#define L2CAP_LM_TRUSTED 0x0008
-+#define L2CAP_LM_RELIABLE 0x0010
-+
-+#define L2CAP_QOS 0x04
-+struct l2cap_qos {
-+ __u16 service_type;
-+ __u32 token_rate;
-+ __u32 token_bucket_size;
-+ __u32 peak_bandwidth;
-+ __u32 latency;
-+ __u32 delay_variation;
-+};
-+
-+#define L2CAP_SERV_NO_TRAFFIC 0x00
-+#define L2CAP_SERV_BEST_EFFORT 0x01
-+#define L2CAP_SERV_GUARANTEED 0x02
-+
- /* L2CAP command codes */
- #define L2CAP_COMMAND_REJ 0x01
- #define L2CAP_CONN_REQ 0x02
-@@ -79,7 +90,6 @@
- #define L2CAP_INFO_RSP 0x0b
-
- /* L2CAP structures */
--
- typedef struct {
- __u16 len;
- __u16 cid;
-@@ -112,11 +122,17 @@
- } __attribute__ ((packed)) l2cap_conn_rsp;
- #define L2CAP_CONN_RSP_SIZE 8
-
--#define L2CAP_CONN_SUCCESS 0x0000
--#define L2CAP_CONN_PEND 0x0001
--#define L2CAP_CONN_BAD_PSM 0x0002
--#define L2CAP_CONN_SEC_BLOCK 0x0003
--#define L2CAP_CONN_NO_MEM 0x0004
-+/* connect result */
-+#define L2CAP_CR_SUCCESS 0x0000
-+#define L2CAP_CR_PEND 0x0001
-+#define L2CAP_CR_BAD_PSM 0x0002
-+#define L2CAP_CR_SEC_BLOCK 0x0003
-+#define L2CAP_CR_NO_MEM 0x0004
-+
-+/* connect status */
-+#define L2CAP_CS_NO_INFO 0x0000
-+#define L2CAP_CS_AUTHEN_PEND 0x0001
-+#define L2CAP_CS_AUTHOR_PEND 0x0002
-
- typedef struct {
- __u16 dcid;
-@@ -147,6 +163,8 @@
- #define L2CAP_CONF_FLUSH_TO 0x02
- #define L2CAP_CONF_QOS 0x03
-
-+#define L2CAP_CONF_MAX_SIZE 22
-+
- typedef struct {
- __u16 dcid;
- __u16 scid;
-@@ -158,5 +176,75 @@
- __u16 scid;
- } __attribute__ ((packed)) l2cap_disconn_rsp;
- #define L2CAP_DISCONN_RSP_SIZE 4
-+
-+typedef struct {
-+ __u16 type;
-+ __u8 data[0];
-+} __attribute__ ((packed)) l2cap_info_req;
-+#define L2CAP_INFO_REQ_SIZE 2
-+
-+typedef struct {
-+ __u16 type;
-+ __u16 result;
-+ __u8 data[0];
-+} __attribute__ ((packed)) l2cap_info_rsp;
-+#define L2CAP_INFO_RSP_SIZE 4
-+
-+/* ----- L2CAP connections ----- */
-+struct l2cap_chan_list {
-+ struct sock *head;
-+ rwlock_t lock;
-+ long num;
-+};
-+
-+struct l2cap_conn {
-+ struct hci_conn *hcon;
-+
-+ bdaddr_t *dst;
-+ bdaddr_t *src;
-+
-+ unsigned int mtu;
-+
-+ spinlock_t lock;
-+
-+ struct sk_buff *rx_skb;
-+ __u32 rx_len;
-+ __u8 rx_ident;
-+ __u8 tx_ident;
-+
-+ struct l2cap_chan_list chan_list;
-+};
-+
-+/* ----- L2CAP channel and socket info ----- */
-+#define l2cap_pi(sk) ((struct l2cap_pinfo *) &sk->tp_pinfo)
-+
-+struct l2cap_pinfo {
-+ __u16 psm;
-+ __u16 dcid;
-+ __u16 scid;
-+
-+ __u16 imtu;
-+ __u16 omtu;
-+ __u16 flush_to;
-+
-+ __u32 link_mode;
-+
-+ __u8 conf_state;
-+ __u8 conf_retry;
-+ __u16 conf_mtu;
-+
-+ __u8 ident;
-+
-+ struct l2cap_conn *conn;
-+ struct sock *next_c;
-+ struct sock *prev_c;
-+};
-+
-+#define L2CAP_CONF_REQ_SENT 0x01
-+#define L2CAP_CONF_INPUT_DONE 0x02
-+#define L2CAP_CONF_OUTPUT_DONE 0x04
-+#define L2CAP_CONF_MAX_RETRIES 2
-+
-+void l2cap_load(void);
-
- #endif /* __L2CAP_H */
-diff -urN linux-2.4.18/include/net/bluetooth/l2cap_core.h linux-2.4.18-mh9/include/net/bluetooth/l2cap_core.h
---- linux-2.4.18/include/net/bluetooth/l2cap_core.h Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/include/net/bluetooth/l2cap_core.h Thu Jan 1 01:00:00 1970
-@@ -1,144 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * $Id$
-- */
--
--#ifndef __L2CAP_CORE_H
--#define __L2CAP_CORE_H
--
--#ifdef __KERNEL__
--
--/* ----- L2CAP interface ----- */
--struct l2cap_iff {
-- struct list_head list;
-- struct hci_dev *hdev;
-- bdaddr_t *bdaddr;
-- __u16 mtu;
-- spinlock_t lock;
-- struct list_head conn_list;
--};
--
--static inline void l2cap_iff_lock(struct l2cap_iff *iff)
--{
-- spin_lock(&iff->lock);
--}
--
--static inline void l2cap_iff_unlock(struct l2cap_iff *iff)
--{
-- spin_unlock(&iff->lock);
--}
--
--/* ----- L2CAP connections ----- */
--struct l2cap_chan_list {
-- struct sock *head;
-- rwlock_t lock;
-- long num;
--};
--
--struct l2cap_conn {
-- struct l2cap_iff *iff;
-- struct list_head list;
--
-- struct hci_conn *hconn;
--
-- __u16 state;
-- __u8 out;
-- bdaddr_t src;
-- bdaddr_t dst;
--
-- spinlock_t lock;
-- atomic_t refcnt;
--
-- struct sk_buff *rx_skb;
-- __u32 rx_len;
-- __u8 rx_ident;
-- __u8 tx_ident;
--
-- struct l2cap_chan_list chan_list;
--
-- struct timer_list timer;
--};
--
--static inline void __l2cap_conn_link(struct l2cap_iff *iff, struct l2cap_conn *c)
--{
-- list_add(&c->list, &iff->conn_list);
--}
--
--static inline void __l2cap_conn_unlink(struct l2cap_iff *iff, struct l2cap_conn *c)
--{
-- list_del(&c->list);
--}
--
--/* ----- L2CAP channel and socket info ----- */
--#define l2cap_pi(sk) ((struct l2cap_pinfo *) &sk->protinfo)
--
--struct l2cap_accept_q {
-- struct sock *head;
-- struct sock *tail;
--};
--
--struct l2cap_pinfo {
-- bdaddr_t src;
-- bdaddr_t dst;
-- __u16 psm;
-- __u16 dcid;
-- __u16 scid;
-- __u32 flags;
--
-- __u16 imtu;
-- __u16 omtu;
-- __u16 flush_to;
--
-- __u8 conf_state;
-- __u16 conf_mtu;
--
-- __u8 ident;
--
-- struct l2cap_conn *conn;
-- struct sock *next_c;
-- struct sock *prev_c;
--
-- struct sock *parent;
-- struct sock *next_q;
-- struct sock *prev_q;
--
-- struct l2cap_accept_q accept_q;
--};
--
--#define CONF_REQ_SENT 0x01
--#define CONF_INPUT_DONE 0x02
--#define CONF_OUTPUT_DONE 0x04
--
--extern struct bluez_sock_list l2cap_sk_list;
--extern struct list_head l2cap_iff_list;
--extern rwlock_t l2cap_rt_lock;
--
--extern void l2cap_register_proc(void);
--extern void l2cap_unregister_proc(void);
--
--#endif /* __KERNEL__ */
--
--#endif /* __L2CAP_CORE_H */
-diff -urN linux-2.4.18/include/net/bluetooth/rfcomm.h linux-2.4.18-mh9/include/net/bluetooth/rfcomm.h
---- linux-2.4.18/include/net/bluetooth/rfcomm.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/include/net/bluetooth/rfcomm.h Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,356 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ RPN support - Dirk Husemann <hud@zurich.ibm.com>
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef __RFCOMM_H
-+#define __RFCOMM_H
-+
-+#define RFCOMM_PSM 3
-+
-+#define RFCOMM_CONN_TIMEOUT (HZ * 30)
-+#define RFCOMM_DISC_TIMEOUT (HZ * 20)
-+
-+#define RFCOMM_DEFAULT_MTU 127
-+#define RFCOMM_DEFAULT_CREDITS 7
-+
-+#define RFCOMM_MAX_L2CAP_MTU 1024
-+#define RFCOMM_MAX_CREDITS 40
-+
-+#define RFCOMM_SKB_HEAD_RESERVE 8
-+#define RFCOMM_SKB_TAIL_RESERVE 2
-+#define RFCOMM_SKB_RESERVE (RFCOMM_SKB_HEAD_RESERVE + RFCOMM_SKB_TAIL_RESERVE)
-+
-+#define RFCOMM_SABM 0x2f
-+#define RFCOMM_DISC 0x43
-+#define RFCOMM_UA 0x63
-+#define RFCOMM_DM 0x0f
-+#define RFCOMM_UIH 0xef
-+
-+#define RFCOMM_TEST 0x08
-+#define RFCOMM_FCON 0x28
-+#define RFCOMM_FCOFF 0x18
-+#define RFCOMM_MSC 0x38
-+#define RFCOMM_RPN 0x24
-+#define RFCOMM_RLS 0x14
-+#define RFCOMM_PN 0x20
-+#define RFCOMM_NSC 0x04
-+
-+#define RFCOMM_V24_FC 0x02
-+#define RFCOMM_V24_RTC 0x04
-+#define RFCOMM_V24_RTR 0x08
-+#define RFCOMM_V24_IC 0x40
-+#define RFCOMM_V24_DV 0x80
-+
-+#define RFCOMM_RPN_BR_2400 0x0
-+#define RFCOMM_RPN_BR_4800 0x1
-+#define RFCOMM_RPN_BR_7200 0x2
-+#define RFCOMM_RPN_BR_9600 0x3
-+#define RFCOMM_RPN_BR_19200 0x4
-+#define RFCOMM_RPN_BR_38400 0x5
-+#define RFCOMM_RPN_BR_57600 0x6
-+#define RFCOMM_RPN_BR_115200 0x7
-+#define RFCOMM_RPN_BR_230400 0x8
-+
-+#define RFCOMM_RPN_DATA_5 0x0
-+#define RFCOMM_RPN_DATA_6 0x1
-+#define RFCOMM_RPN_DATA_7 0x2
-+#define RFCOMM_RPN_DATA_8 0x3
-+
-+#define RFCOMM_RPN_STOP_1 0
-+#define RFCOMM_RPN_STOP_15 1
-+
-+#define RFCOMM_RPN_PARITY_NONE 0x0
-+#define RFCOMM_RPN_PARITY_ODD 0x4
-+#define RFCOMM_RPN_PARITY_EVEN 0x5
-+#define RFCOMM_RPN_PARITY_MARK 0x6
-+#define RFCOMM_RPN_PARITY_SPACE 0x7
-+
-+#define RFCOMM_RPN_FLOW_NONE 0x00
-+
-+#define RFCOMM_RPN_XON_CHAR 0x11
-+#define RFCOMM_RPN_XOFF_CHAR 0x13
-+
-+#define RFCOMM_RPN_PM_BITRATE 0x0001
-+#define RFCOMM_RPN_PM_DATA 0x0002
-+#define RFCOMM_RPN_PM_STOP 0x0004
-+#define RFCOMM_RPN_PM_PARITY 0x0008
-+#define RFCOMM_RPN_PM_PARITY_TYPE 0x0010
-+#define RFCOMM_RPN_PM_XON 0x0020
-+#define RFCOMM_RPN_PM_XOFF 0x0040
-+#define RFCOMM_RPN_PM_FLOW 0x3F00
-+
-+#define RFCOMM_RPN_PM_ALL 0x3F7F
-+
-+struct rfcomm_hdr {
-+ u8 addr;
-+ u8 ctrl;
-+ u8 len; // Actual size can be 2 bytes
-+} __attribute__ ((packed));
-+
-+struct rfcomm_cmd {
-+ u8 addr;
-+ u8 ctrl;
-+ u8 len;
-+ u8 fcs;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_mcc {
-+ u8 type;
-+ u8 len;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_pn {
-+ u8 dlci;
-+ u8 flow_ctrl;
-+ u8 priority;
-+ u8 ack_timer;
-+ u16 mtu;
-+ u8 max_retrans;
-+ u8 credits;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_rpn {
-+ u8 dlci;
-+ u8 bit_rate;
-+ u8 line_settings;
-+ u8 flow_ctrl;
-+ u8 xon_char;
-+ u8 xoff_char;
-+ u16 param_mask;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_rls {
-+ u8 dlci;
-+ u8 status;
-+} __attribute__ ((packed));
-+
-+struct rfcomm_msc {
-+ u8 dlci;
-+ u8 v24_sig;
-+} __attribute__ ((packed));
-+
-+/* ---- Core structures, flags etc ---- */
-+
-+struct rfcomm_session {
-+ struct list_head list;
-+ struct socket *sock;
-+ unsigned long state;
-+ unsigned long flags;
-+ atomic_t refcnt;
-+ int initiator;
-+
-+ /* Default DLC parameters */
-+ uint mtu;
-+ uint credits;
-+
-+ struct list_head dlcs;
-+};
-+
-+struct rfcomm_dlc {
-+ struct list_head list;
-+ struct rfcomm_session *session;
-+ struct sk_buff_head tx_queue;
-+ struct timer_list timer;
-+
-+ spinlock_t lock;
-+ unsigned long state;
-+ unsigned long flags;
-+ atomic_t refcnt;
-+ u8 dlci;
-+ u8 addr;
-+ u8 priority;
-+ u8 v24_sig;
-+ u8 mscex;
-+
-+ uint mtu;
-+ uint credits;
-+ uint rx_credits;
-+ uint tx_credits;
-+
-+ void *owner;
-+
-+ void (*data_ready)(struct rfcomm_dlc *d, struct sk_buff *skb);
-+ void (*state_change)(struct rfcomm_dlc *d, int err);
-+ void (*modem_status)(struct rfcomm_dlc *d, u8 v24_sig);
-+};
-+
-+/* DLC and session flags */
-+#define RFCOMM_RX_THROTTLED 0
-+#define RFCOMM_TX_THROTTLED 1
-+#define RFCOMM_MSC_PENDING 2
-+#define RFCOMM_TIMED_OUT 3
-+
-+/* Scheduling flags and events */
-+#define RFCOMM_SCHED_STATE 0
-+#define RFCOMM_SCHED_RX 1
-+#define RFCOMM_SCHED_TX 2
-+#define RFCOMM_SCHED_TIMEO 3
-+#define RFCOMM_SCHED_WAKEUP 31
-+
-+/* MSC exchange flags */
-+#define RFCOMM_MSCEX_TX 1
-+#define RFCOMM_MSCEX_RX 2
-+#define RFCOMM_MSCEX_OK (RFCOMM_MSCEX_TX + RFCOMM_MSCEX_RX)
-+
-+extern struct task_struct *rfcomm_thread;
-+extern unsigned long rfcomm_event;
-+
-+static inline void rfcomm_schedule(uint event)
-+{
-+ if (!rfcomm_thread)
-+ return;
-+ set_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
-+ wake_up_process(rfcomm_thread);
-+}
-+
-+extern struct semaphore rfcomm_sem;
-+#define rfcomm_lock() down(&rfcomm_sem);
-+#define rfcomm_unlock() up(&rfcomm_sem);
-+
-+/* ---- RFCOMM DLCs (channels) ---- */
-+struct rfcomm_dlc *rfcomm_dlc_alloc(int prio);
-+void rfcomm_dlc_free(struct rfcomm_dlc *d);
-+int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel);
-+int rfcomm_dlc_close(struct rfcomm_dlc *d, int reason);
-+int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb);
-+int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig);
-+int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig);
-+
-+#define rfcomm_dlc_lock(d) spin_lock(&d->lock)
-+#define rfcomm_dlc_unlock(d) spin_unlock(&d->lock)
-+
-+static inline void rfcomm_dlc_hold(struct rfcomm_dlc *d)
-+{
-+ atomic_inc(&d->refcnt);
-+}
-+
-+static inline void rfcomm_dlc_put(struct rfcomm_dlc *d)
-+{
-+ if (atomic_dec_and_test(&d->refcnt))
-+ rfcomm_dlc_free(d);
-+}
-+
-+extern void FASTCALL(__rfcomm_dlc_throttle(struct rfcomm_dlc *d));
-+extern void FASTCALL(__rfcomm_dlc_unthrottle(struct rfcomm_dlc *d));
-+
-+static inline void rfcomm_dlc_throttle(struct rfcomm_dlc *d)
-+{
-+ if (!test_and_set_bit(RFCOMM_RX_THROTTLED, &d->flags))
-+ __rfcomm_dlc_throttle(d);
-+}
-+
-+static inline void rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
-+{
-+ if (test_and_clear_bit(RFCOMM_RX_THROTTLED, &d->flags))
-+ __rfcomm_dlc_unthrottle(d);
-+}
-+
-+/* ---- RFCOMM sessions ---- */
-+struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state);
-+struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst);
-+struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err);
-+void rfcomm_session_del(struct rfcomm_session *s);
-+void rfcomm_session_close(struct rfcomm_session *s, int err);
-+void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst);
-+
-+static inline void rfcomm_session_hold(struct rfcomm_session *s)
-+{
-+ atomic_inc(&s->refcnt);
-+}
-+
-+static inline void rfcomm_session_put(struct rfcomm_session *s)
-+{
-+ if (atomic_dec_and_test(&s->refcnt))
-+ rfcomm_session_del(s);
-+}
-+
-+/* ---- RFCOMM chechsum ---- */
-+extern u8 rfcomm_crc_table[];
-+
-+/* ---- RFCOMM sockets ---- */
-+struct sockaddr_rc {
-+ sa_family_t rc_family;
-+ bdaddr_t rc_bdaddr;
-+ u8 rc_channel;
-+};
-+
-+#define rfcomm_pi(sk) ((struct rfcomm_pinfo *) &sk->tp_pinfo)
-+
-+struct rfcomm_pinfo {
-+ struct rfcomm_dlc *dlc;
-+ u8 channel;
-+};
-+
-+int rfcomm_init_sockets(void);
-+void rfcomm_cleanup_sockets(void);
-+
-+int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d);
-+
-+/* ---- RFCOMM TTY ---- */
-+#define RFCOMM_MAX_DEV 256
-+
-+#define RFCOMMCREATEDEV _IOW('R', 200, int)
-+#define RFCOMMRELEASEDEV _IOW('R', 201, int)
-+#define RFCOMMGETDEVLIST _IOR('R', 210, int)
-+#define RFCOMMGETDEVINFO _IOR('R', 211, int)
-+#define RFCOMMSTEALDLC _IOW('R', 220, int)
-+
-+#define RFCOMM_REUSE_DLC 0
-+#define RFCOMM_RELEASE_ONHUP 1
-+#define RFCOMM_HANGUP_NOW 2
-+#define RFCOMM_TTY_ATTACHED 3
-+
-+struct rfcomm_dev_req {
-+ s16 dev_id;
-+ u32 flags;
-+ bdaddr_t src;
-+ bdaddr_t dst;
-+ u8 channel;
-+};
-+
-+struct rfcomm_dev_info {
-+ s16 id;
-+ u32 flags;
-+ u16 state;
-+ bdaddr_t src;
-+ bdaddr_t dst;
-+ u8 channel;
-+};
-+
-+struct rfcomm_dev_list_req {
-+ u16 dev_num;
-+ struct rfcomm_dev_info dev_info[0];
-+};
-+
-+int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg);
-+int rfcomm_init_ttys(void);
-+void rfcomm_cleanup_ttys(void);
-+
-+#endif /* __RFCOMM_H */
-diff -urN linux-2.4.18/include/net/bluetooth/sco.h linux-2.4.18-mh9/include/net/bluetooth/sco.h
---- linux-2.4.18/include/net/bluetooth/sco.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/include/net/bluetooth/sco.h Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,81 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef __SCO_H
-+#define __SCO_H
-+
-+/* SCO defaults */
-+#define SCO_DEFAULT_MTU 500
-+#define SCO_DEFAULT_FLUSH_TO 0xFFFF
-+
-+#define SCO_CONN_TIMEOUT (HZ * 40)
-+#define SCO_DISCONN_TIMEOUT (HZ * 2)
-+#define SCO_CONN_IDLE_TIMEOUT (HZ * 60)
-+
-+/* SCO socket address */
-+struct sockaddr_sco {
-+ sa_family_t sco_family;
-+ bdaddr_t sco_bdaddr;
-+};
-+
-+/* set/get sockopt defines */
-+#define SCO_OPTIONS 0x01
-+struct sco_options {
-+ __u16 mtu;
-+};
-+
-+#define SCO_CONNINFO 0x02
-+struct sco_conninfo {
-+ __u16 hci_handle;
-+};
-+
-+/* ---- SCO connections ---- */
-+struct sco_conn {
-+ struct hci_conn *hcon;
-+
-+ bdaddr_t *dst;
-+ bdaddr_t *src;
-+
-+ spinlock_t lock;
-+ struct sock *sk;
-+
-+ unsigned int mtu;
-+};
-+
-+#define sco_conn_lock(c) spin_lock(&c->lock);
-+#define sco_conn_unlock(c) spin_unlock(&c->lock);
-+
-+/* ----- SCO socket info ----- */
-+#define sco_pi(sk) ((struct sco_pinfo *) &sk->tp_pinfo)
-+
-+struct sco_pinfo {
-+ __u32 flags;
-+ struct sco_conn *conn;
-+};
-+
-+#endif /* __SCO_H */
-diff -urN linux-2.4.18/include/pcmcia/ciscode.h linux-2.4.18-mh9/include/pcmcia/ciscode.h
---- linux-2.4.18/include/pcmcia/ciscode.h Fri Dec 21 18:42:04 2001
-+++ linux-2.4.18-mh9/include/pcmcia/ciscode.h Mon Aug 25 18:38:12 2003
-@@ -1,5 +1,5 @@
- /*
-- * ciscode.h 1.48 2001/08/24 12:16:12
-+ * ciscode.h 1.57 2002/11/03 20:38:14
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
-@@ -60,6 +60,10 @@
- #define PRODID_INTEL_DUAL_RS232 0x0301
- #define PRODID_INTEL_2PLUS 0x8422
-
-+#define MANFID_KME 0x0032
-+#define PRODID_KME_KXLC005_A 0x0704
-+#define PRODID_KME_KXLC005_B 0x2904
-+
- #define MANFID_LINKSYS 0x0143
- #define PRODID_LINKSYS_PCMLM28 0xc0ab
- #define PRODID_LINKSYS_3400 0x3341
-@@ -94,6 +98,8 @@
- #define PRODID_OSITECH_JACK_336 0x0007
- #define PRODID_OSITECH_SEVEN 0x0008
-
-+#define MANFID_OXSEMI 0x0279
-+
- #define MANFID_PIONEER 0x000b
-
- #define MANFID_PSION 0x016c
-@@ -103,6 +109,7 @@
- #define PRODID_QUATECH_SPP100 0x0003
- #define PRODID_QUATECH_DUAL_RS232 0x0012
- #define PRODID_QUATECH_DUAL_RS232_D1 0x0007
-+#define PRODID_QUATECH_DUAL_RS232_D2 0x0052
- #define PRODID_QUATECH_QUAD_RS232 0x001b
- #define PRODID_QUATECH_DUAL_RS422 0x000e
- #define PRODID_QUATECH_QUAD_RS422 0x0045
-@@ -120,8 +127,11 @@
-
- #define MANFID_TDK 0x0105
- #define PRODID_TDK_CF010 0x0900
-+#define PRODID_TDK_GN3410 0x4815
-
- #define MANFID_TOSHIBA 0x0098
-+
-+#define MANFID_UNGERMANN 0x02c0
-
- #define MANFID_XIRCOM 0x0105
-
-diff -urN linux-2.4.18/lib/Config.in linux-2.4.18-mh9/lib/Config.in
---- linux-2.4.18/lib/Config.in Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/lib/Config.in Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,12 @@
-+#
-+# Library configuration
-+#
-+mainmenu_option next_comment
-+comment 'Library routines'
-+
-+if [ "$CONFIG_EXPERIMENTAL" = "y" -a \
-+ "$CONFIG_HOTPLUG" = "y" ]; then
-+ tristate 'Hotplug firmware loading support (EXPERIMENTAL)' CONFIG_FW_LOADER
-+fi
-+
-+endmenu
-diff -urN linux-2.4.18/lib/Makefile linux-2.4.18-mh9/lib/Makefile
---- linux-2.4.18/lib/Makefile Tue Sep 18 00:31:15 2001
-+++ linux-2.4.18-mh9/lib/Makefile Mon Aug 25 18:38:12 2003
-@@ -8,12 +8,16 @@
-
- L_TARGET := lib.a
-
--export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o
-+export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o \
-+ firmware_class.o
-
- obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o bust_spinlocks.o rbtree.o
-
-+obj-$(CONFIG_FW_LOADER) += firmware_class.o
- obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o
- obj-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o
-+
-+include $(TOPDIR)/drivers/bluetooth/Makefile.lib
-
- ifneq ($(CONFIG_HAVE_DEC_LOCK),y)
- obj-y += dec_and_lock.o
-diff -urN linux-2.4.18/lib/firmware_class.c linux-2.4.18-mh9/lib/firmware_class.c
---- linux-2.4.18/lib/firmware_class.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/lib/firmware_class.c Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,571 @@
-+/*
-+ * firmware_class.c - Multi purpose firmware loading support
-+ *
-+ * Copyright (c) 2003 Manuel Estrada Sainz <ranty@debian.org>
-+ *
-+ * Please see Documentation/firmware_class/ for more information.
-+ *
-+ */
-+/*
-+ * Based on kernel/kmod.c and drivers/usb/usb.c
-+ */
-+/*
-+ kernel/kmod.c
-+ Kirk Petersen
-+
-+ Reorganized not to be a daemon by Adam Richter, with guidance
-+ from Greg Zornetzer.
-+
-+ Modified to avoid chroot and file sharing problems.
-+ Mikael Pettersson
-+
-+ Limit the concurrent number of kmod modprobes to catch loops from
-+ "modprobe needs a service that is in a module".
-+ Keith Owens <kaos@ocs.com.au> December 1999
-+
-+ Unblock all signals when we exec a usermode process.
-+ Shuu Yamaguchi <shuu@wondernetworkresources.com> December 2000
-+*/
-+/*
-+ * drivers/usb/usb.c
-+ *
-+ * (C) Copyright Linus Torvalds 1999
-+ * (C) Copyright Johannes Erdfelt 1999-2001
-+ * (C) Copyright Andreas Gal 1999
-+ * (C) Copyright Gregory P. Smith 1999
-+ * (C) Copyright Deti Fliegl 1999 (new USB architecture)
-+ * (C) Copyright Randy Dunlap 2000
-+ * (C) Copyright David Brownell 2000 (kernel hotplug, usb_device_id)
-+ * (C) Copyright Yggdrasil Computing, Inc. 2000
-+ * (usb_device_id matching changes by Adam J. Richter)
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/string.h>
-+#include <linux/types.h>
-+#include <linux/init.h>
-+#include <linux/slab.h>
-+#include <linux/kmod.h>
-+#include <linux/proc_fs.h>
-+#include <linux/vmalloc.h>
-+#include <asm/hardirq.h>
-+
-+#include "linux/firmware.h"
-+
-+MODULE_AUTHOR("Manuel Estrada Sainz <ranty@debian.org>");
-+MODULE_DESCRIPTION("Multi purpose firmware loading support");
-+MODULE_LICENSE("GPL");
-+
-+#define err(format, arg...) \
-+ printk(KERN_ERR "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
-+#define warn(format, arg...) \
-+ printk(KERN_WARNING "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
-+#define dbg(format, arg...) \
-+ printk(KERN_DEBUG "%s:%s: " format "\n",__FILE__, __FUNCTION__ , ## arg)
-+
-+static int loading_timeout = 10; /* In seconds */
-+static struct proc_dir_entry *proc_dir_timeout;
-+static struct proc_dir_entry *proc_dir;
-+
-+#ifdef CONFIG_HOTPLUG
-+
-+static int
-+call_helper(char *verb, const char *name, const char *device)
-+{
-+ char *argv[3], **envp, *buf, *scratch;
-+ int i = 0;
-+
-+ int retval = 0;
-+
-+ if (!hotplug_path[0])
-+ return -ENOENT;
-+ if (in_interrupt()) {
-+ err("in_interrupt");
-+ return -EFAULT;
-+ }
-+ if (!current->fs->root) {
-+ warn("call_policy %s -- no FS yet", verb);
-+ return -EPERM;
-+ }
-+
-+ if (!(envp = (char **) kmalloc(20 * sizeof (char *), GFP_KERNEL))) {
-+ err("unable to allocate envp");
-+ return -ENOMEM;
-+ }
-+ if (!(buf = kmalloc(256, GFP_KERNEL))) {
-+ kfree(envp);
-+ err("unable to allocate buf");
-+ return -ENOMEM;
-+ }
-+
-+ /* only one standardized param to hotplug command: type */
-+ argv[0] = hotplug_path;
-+ argv[1] = "firmware";
-+ argv[2] = 0;
-+
-+ /* minimal command environment */
-+ envp[i++] = "HOME=/";
-+ envp[i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-+
-+#ifdef DEBUG
-+ /* hint that policy agent should enter no-stdout debug mode */
-+ envp[i++] = "DEBUG=kernel";
-+#endif
-+ scratch = buf;
-+
-+ if (device) {
-+ envp[i++] = scratch;
-+ scratch += snprintf(scratch, FIRMWARE_NAME_MAX+25,
-+ "DEVPATH=/driver/firmware/%s", device) + 1;
-+ }
-+
-+ envp[i++] = scratch;
-+ scratch += sprintf(scratch, "ACTION=%s", verb) + 1;
-+
-+ envp[i++] = scratch;
-+ scratch += snprintf(scratch, FIRMWARE_NAME_MAX,
-+ "FIRMWARE=%s", name) + 1;
-+
-+ envp[i++] = 0;
-+
-+#ifdef DEBUG
-+ dbg("firmware: %s %s %s", argv[0], argv[1], verb);
-+#endif
-+
-+ retval = call_usermodehelper(argv[0], argv, envp);
-+ if (retval) {
-+ printk("call_usermodehelper return %d\n", retval);
-+ }
-+
-+ kfree(buf);
-+ kfree(envp);
-+ return retval;
-+}
-+#else
-+
-+static inline int
-+call_helper(char *verb, const char *name, const char *device)
-+{
-+ return -ENOENT;
-+}
-+
-+#endif /* CONFIG_HOTPLUG */
-+
-+struct firmware_priv {
-+ struct completion completion;
-+ struct proc_dir_entry *proc_dir;
-+ struct proc_dir_entry *attr_data;
-+ struct proc_dir_entry *attr_loading;
-+ struct firmware *fw;
-+ int loading;
-+ int abort;
-+ int alloc_size;
-+ struct timer_list timeout;
-+};
-+
-+static int
-+firmware_timeout_show(char *buf, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ return sprintf(buf, "%d\n", loading_timeout);
-+}
-+
-+/**
-+ * firmware_timeout_store:
-+ * Description:
-+ * Sets the number of seconds to wait for the firmware. Once
-+ * this expires an error will be return to the driver and no
-+ * firmware will be provided.
-+ *
-+ * Note: zero means 'wait for ever'
-+ *
-+ **/
-+static int
-+firmware_timeout_store(struct file *file, const char *buf,
-+ unsigned long count, void *data)
-+{
-+ loading_timeout = simple_strtol(buf, NULL, 10);
-+ return count;
-+}
-+
-+static int
-+firmware_loading_show(char *buf, char **start, off_t off,
-+ int count, int *eof, void *data)
-+{
-+ struct firmware_priv *fw_priv = data;
-+ return sprintf(buf, "%d\n", fw_priv->loading);
-+}
-+
-+/**
-+ * firmware_loading_store: - loading control file
-+ * Description:
-+ * The relevant values are:
-+ *
-+ * 1: Start a load, discarding any previous partial load.
-+ * 0: Conclude the load and handle the data to the driver code.
-+ * -1: Conclude the load with an error and discard any written data.
-+ **/
-+static int
-+firmware_loading_store(struct file *file, const char *buf,
-+ unsigned long count, void *data)
-+{
-+ struct firmware_priv *fw_priv = data;
-+ int prev_loading = fw_priv->loading;
-+
-+ fw_priv->loading = simple_strtol(buf, NULL, 10);
-+
-+ switch (fw_priv->loading) {
-+ case -1:
-+ fw_priv->abort = 1;
-+ wmb();
-+ complete(&fw_priv->completion);
-+ break;
-+ case 1:
-+ kfree(fw_priv->fw->data);
-+ fw_priv->fw->data = NULL;
-+ fw_priv->fw->size = 0;
-+ fw_priv->alloc_size = 0;
-+ break;
-+ case 0:
-+ if (prev_loading == 1)
-+ complete(&fw_priv->completion);
-+ break;
-+ }
-+
-+ return count;
-+}
-+
-+static int
-+firmware_data_read(char *buffer, char **start, off_t offset,
-+ int count, int *eof, void *data)
-+{
-+ struct firmware_priv *fw_priv = data;
-+ struct firmware *fw = fw_priv->fw;
-+
-+ if (offset > fw->size)
-+ return 0;
-+ if (offset + count > fw->size)
-+ count = fw->size - offset;
-+
-+ memcpy(buffer, fw->data + offset, count);
-+ *start = (void *) ((long) count);
-+ return count;
-+}
-+static int
-+fw_realloc_buffer(struct firmware_priv *fw_priv, int min_size)
-+{
-+ u8 *new_data;
-+ int new_size;
-+
-+ if (min_size <= fw_priv->alloc_size)
-+ return 0;
-+ if((min_size % PAGE_SIZE) == 0)
-+ new_size = min_size;
-+ else
-+ new_size = (min_size + PAGE_SIZE) & PAGE_MASK;
-+ new_data = vmalloc(new_size);
-+ if (!new_data) {
-+ printk(KERN_ERR "%s: unable to alloc buffer\n", __FUNCTION__);
-+ /* Make sure that we don't keep incomplete data */
-+ fw_priv->abort = 1;
-+ return -ENOMEM;
-+ }
-+ fw_priv->alloc_size = new_size;
-+ if (fw_priv->fw->data) {
-+ memcpy(new_data, fw_priv->fw->data, fw_priv->fw->size);
-+ vfree(fw_priv->fw->data);
-+ }
-+ fw_priv->fw->data = new_data;
-+ BUG_ON(min_size > fw_priv->alloc_size);
-+ return 0;
-+}
-+
-+/**
-+ * firmware_data_write:
-+ *
-+ * Description:
-+ *
-+ * Data written to the 'data' attribute will be later handled to
-+ * the driver as a firmware image.
-+ **/
-+static int
-+firmware_data_write(struct file *file, const char *buffer,
-+ unsigned long count, void *data)
-+{
-+ struct firmware_priv *fw_priv = data;
-+ struct firmware *fw = fw_priv->fw;
-+ int offset = file->f_pos;
-+ int retval;
-+
-+ retval = fw_realloc_buffer(fw_priv, offset + count);
-+ if (retval) {
-+ printk("%s: retval:%d\n", __FUNCTION__, retval);
-+ return retval;
-+ }
-+
-+ memcpy(fw->data + offset, buffer, count);
-+
-+ fw->size = max_t(size_t, offset + count, fw->size);
-+ file->f_pos += count;
-+ return count;
-+}
-+
-+static void
-+firmware_class_timeout(u_long data)
-+{
-+ struct firmware_priv *fw_priv = (struct firmware_priv *) data;
-+ fw_priv->abort = 1;
-+ wmb();
-+ complete(&fw_priv->completion);
-+}
-+static int
-+fw_setup_class_device(struct firmware_priv **fw_priv_p,
-+ const char *fw_name, const char *device)
-+{
-+ int retval;
-+ struct firmware_priv *fw_priv = kmalloc(sizeof (struct firmware_priv),
-+ GFP_KERNEL);
-+ *fw_priv_p = fw_priv;
-+ if (!fw_priv) {
-+ retval = -ENOMEM;
-+ goto out;
-+ }
-+ memset(fw_priv, 0, sizeof (*fw_priv));
-+
-+ init_completion(&fw_priv->completion);
-+
-+ fw_priv->timeout.function = firmware_class_timeout;
-+ fw_priv->timeout.data = (u_long) fw_priv;
-+ init_timer(&fw_priv->timeout);
-+
-+ retval = -EAGAIN;
-+ fw_priv->proc_dir = create_proc_entry(device, 0644 | S_IFDIR, proc_dir);
-+ if (!fw_priv->proc_dir)
-+ goto err_free_fw_priv;
-+
-+ fw_priv->attr_data = create_proc_entry("data", 0644 | S_IFREG,
-+ fw_priv->proc_dir);
-+ if (!fw_priv->attr_data)
-+ goto err_remove_dir;
-+
-+ fw_priv->attr_data->read_proc = firmware_data_read;
-+ fw_priv->attr_data->write_proc = firmware_data_write;
-+ fw_priv->attr_data->data = fw_priv;
-+
-+ fw_priv->attr_loading = create_proc_entry("loading", 0644 | S_IFREG,
-+ fw_priv->proc_dir);
-+ if (!fw_priv->attr_loading)
-+ goto err_remove_data;
-+
-+ fw_priv->attr_loading->read_proc = firmware_loading_show;
-+ fw_priv->attr_loading->write_proc = firmware_loading_store;
-+ fw_priv->attr_loading->data = fw_priv;
-+
-+ retval = 0;
-+ fw_priv->fw = kmalloc(sizeof (struct firmware), GFP_KERNEL);
-+ if (!fw_priv->fw) {
-+ printk(KERN_ERR "%s: kmalloc(struct firmware) failed\n",
-+ __FUNCTION__);
-+ retval = -ENOMEM;
-+ goto err_remove_loading;
-+ }
-+ memset(fw_priv->fw, 0, sizeof (*fw_priv->fw));
-+
-+ goto out;
-+
-+err_remove_loading:
-+ remove_proc_entry("loading", fw_priv->proc_dir);
-+err_remove_data:
-+ remove_proc_entry("data", fw_priv->proc_dir);
-+err_remove_dir:
-+ remove_proc_entry(device, proc_dir);
-+err_free_fw_priv:
-+ kfree(fw_priv);
-+out:
-+ return retval;
-+}
-+static void
-+fw_remove_class_device(struct firmware_priv *fw_priv)
-+{
-+ remove_proc_entry("loading", fw_priv->proc_dir);
-+ remove_proc_entry("data", fw_priv->proc_dir);
-+ remove_proc_entry(fw_priv->proc_dir->name, proc_dir);
-+}
-+
-+/**
-+ * request_firmware: - request firmware to hotplug and wait for it
-+ * Description:
-+ * @firmware will be used to return a firmware image by the name
-+ * of @name for device @device.
-+ *
-+ * Should be called from user context where sleeping is allowed.
-+ *
-+ * @name will be use as $FIRMWARE in the hotplug environment and
-+ * should be distinctive enough not to be confused with any other
-+ * firmware image for this or any other device.
-+ **/
-+int
-+request_firmware(const struct firmware **firmware, const char *name,
-+ const char *device)
-+{
-+ struct firmware_priv *fw_priv;
-+ int retval;
-+
-+ if (!firmware) {
-+ retval = -EINVAL;
-+ goto out;
-+ }
-+ *firmware = NULL;
-+
-+ retval = fw_setup_class_device(&fw_priv, name, device);
-+ if (retval)
-+ goto out;
-+
-+ retval = call_helper("add", name, device);
-+ if (retval)
-+ goto out;
-+ if (loading_timeout) {
-+ fw_priv->timeout.expires = jiffies + loading_timeout * HZ;
-+ add_timer(&fw_priv->timeout);
-+ }
-+
-+ wait_for_completion(&fw_priv->completion);
-+
-+ del_timer(&fw_priv->timeout);
-+ fw_remove_class_device(fw_priv);
-+
-+ if (fw_priv->fw->size && !fw_priv->abort) {
-+ *firmware = fw_priv->fw;
-+ } else {
-+ retval = -ENOENT;
-+ vfree(fw_priv->fw->data);
-+ kfree(fw_priv->fw);
-+ }
-+out:
-+ kfree(fw_priv);
-+ return retval;
-+}
-+
-+void
-+release_firmware(const struct firmware *fw)
-+{
-+ if (fw) {
-+ vfree(fw->data);
-+ kfree(fw);
-+ }
-+}
-+
-+/**
-+ * register_firmware: - provide a firmware image for later usage
-+ *
-+ * Description:
-+ * Make sure that @data will be available by requesting firmware @name.
-+ *
-+ * Note: This will not be possible until some kind of persistence
-+ * is available.
-+ **/
-+void
-+register_firmware(const char *name, const u8 *data, size_t size)
-+{
-+ /* This is meaningless without firmware caching, so until we
-+ * decide if firmware caching is reasonable just leave it as a
-+ * noop */
-+}
-+
-+/* Async support */
-+struct firmware_work {
-+ struct tq_struct work;
-+ struct module *module;
-+ const char *name;
-+ const char *device;
-+ void *context;
-+ void (*cont)(const struct firmware *fw, void *context);
-+};
-+
-+static void
-+request_firmware_work_func(void *arg)
-+{
-+ struct firmware_work *fw_work = arg;
-+ const struct firmware *fw;
-+ if (!arg)
-+ return;
-+ request_firmware(&fw, fw_work->name, fw_work->device);
-+ fw_work->cont(fw, fw_work->context);
-+ release_firmware(fw);
-+ __MOD_DEC_USE_COUNT(fw_work->module);
-+ kfree(fw_work);
-+}
-+
-+/**
-+ * request_firmware_nowait:
-+ *
-+ * Description:
-+ * Asynchronous variant of request_firmware() for contexts where
-+ * it is not possible to sleep.
-+ *
-+ * @cont will be called asynchronously when the firmware request is over.
-+ *
-+ * @context will be passed over to @cont.
-+ *
-+ * @fw may be %NULL if firmware request fails.
-+ *
-+ **/
-+int
-+request_firmware_nowait(
-+ struct module *module,
-+ const char *name, const char *device, void *context,
-+ void (*cont)(const struct firmware *fw, void *context))
-+{
-+ struct firmware_work *fw_work = kmalloc(sizeof (struct firmware_work),
-+ GFP_ATOMIC);
-+ if (!fw_work)
-+ return -ENOMEM;
-+ if (!try_inc_mod_count(module)) {
-+ kfree(fw_work);
-+ return -EFAULT;
-+ }
-+
-+ *fw_work = (struct firmware_work) {
-+ .module = module,
-+ .name = name,
-+ .device = device,
-+ .context = context,
-+ .cont = cont,
-+ };
-+ INIT_TQUEUE(&fw_work->work, request_firmware_work_func, fw_work);
-+
-+ schedule_task(&fw_work->work);
-+ return 0;
-+}
-+
-+static int __init
-+firmware_class_init(void)
-+{
-+ proc_dir = create_proc_entry("driver/firmware", 0755 | S_IFDIR, NULL);
-+ if (!proc_dir)
-+ return -EAGAIN;
-+ proc_dir_timeout = create_proc_entry("timeout",
-+ 0644 | S_IFREG, proc_dir);
-+ if (!proc_dir_timeout) {
-+ remove_proc_entry("driver/firmware", NULL);
-+ return -EAGAIN;
-+ }
-+ proc_dir_timeout->read_proc = firmware_timeout_show;
-+ proc_dir_timeout->write_proc = firmware_timeout_store;
-+ return 0;
-+}
-+static void __exit
-+firmware_class_exit(void)
-+{
-+ remove_proc_entry("timeout", proc_dir);
-+ remove_proc_entry("driver/firmware", NULL);
-+}
-+
-+module_init(firmware_class_init);
-+module_exit(firmware_class_exit);
-+
-+EXPORT_SYMBOL(release_firmware);
-+EXPORT_SYMBOL(request_firmware);
-+EXPORT_SYMBOL(request_firmware_nowait);
-+EXPORT_SYMBOL(register_firmware);
-diff -urN linux-2.4.18/net/bluetooth/Config.in linux-2.4.18-mh9/net/bluetooth/Config.in
---- linux-2.4.18/net/bluetooth/Config.in Tue Jun 12 04:15:27 2001
-+++ linux-2.4.18-mh9/net/bluetooth/Config.in Mon Aug 25 18:38:12 2003
-@@ -1,16 +1,22 @@
- #
--# Bluetooth configuration
-+# Bluetooth subsystem configuration
- #
-
- if [ "$CONFIG_NET" != "n" ]; then
-+
- mainmenu_option next_comment
- comment 'Bluetooth support'
- dep_tristate 'Bluetooth subsystem support' CONFIG_BLUEZ $CONFIG_NET
-
- if [ "$CONFIG_BLUEZ" != "n" ]; then
- dep_tristate 'L2CAP protocol support' CONFIG_BLUEZ_L2CAP $CONFIG_BLUEZ
-+ dep_tristate 'SCO links support' CONFIG_BLUEZ_SCO $CONFIG_BLUEZ
-+ source net/bluetooth/rfcomm/Config.in
-+ source net/bluetooth/bnep/Config.in
-+ source net/bluetooth/cmtp/Config.in
- source drivers/bluetooth/Config.in
- fi
-+
- endmenu
- fi
-
-diff -urN linux-2.4.18/net/bluetooth/Makefile linux-2.4.18-mh9/net/bluetooth/Makefile
---- linux-2.4.18/net/bluetooth/Makefile Tue Jun 12 04:15:27 2001
-+++ linux-2.4.18-mh9/net/bluetooth/Makefile Mon Aug 25 18:38:12 2003
-@@ -1,20 +1,31 @@
- #
--# Makefile for the Bluetooth subsystem
-+# Makefile for the Linux Bluetooth subsystem
- #
--O_TARGET := bluetooth.o
-
--list-multi := hci.o l2cap.o
--export-objs := syms.o
--hci-objs := af_bluetooth.o hci_core.o hci_sock.o lib.o syms.o
--l2cap-objs := l2cap_core.o l2cap_proc.o
-+O_TARGET := bluetooth.o
-
--obj-$(CONFIG_BLUEZ) += hci.o
-+list-multi := bluez.o
-+export-objs := syms.o l2cap.o
-+
-+bluez-objs := af_bluetooth.o hci_core.o hci_conn.o hci_event.o hci_sock.o lib.o syms.o
-+
-+obj-$(CONFIG_BLUEZ) += bluez.o
- obj-$(CONFIG_BLUEZ_L2CAP) += l2cap.o
-+obj-$(CONFIG_BLUEZ_SCO) += sco.o
-
--include $(TOPDIR)/Rules.make
-+subdir-$(CONFIG_BLUEZ_RFCOMM) += rfcomm
-+subdir-$(CONFIG_BLUEZ_BNEP) += bnep
-+subdir-$(CONFIG_BLUEZ_CMTP) += cmtp
-
--hci.o: $(hci-objs)
-- $(LD) -r -o $@ $(hci-objs)
-+ifeq ($(CONFIG_BLUEZ_RFCOMM),y)
-+obj-y += rfcomm/rfcomm.o
-+endif
-+
-+ifeq ($(CONFIG_BLUEZ_BNEP),y)
-+obj-y += bnep/bnep.o
-+endif
-+
-+include $(TOPDIR)/Rules.make
-
--l2cap.o: $(l2cap-objs)
-- $(LD) -r -o $@ $(l2cap-objs)
-+bluez.o: $(bluez-objs)
-+ $(LD) -r -o $@ $(bluez-objs)
-diff -urN linux-2.4.18/net/bluetooth/af_bluetooth.c linux-2.4.18-mh9/net/bluetooth/af_bluetooth.c
---- linux-2.4.18/net/bluetooth/af_bluetooth.c Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/net/bluetooth/af_bluetooth.c Mon Aug 25 18:38:12 2003
-@@ -25,14 +25,15 @@
- /*
- * BlueZ Bluetooth address family and sockets.
- *
-- * $Id$
-+ * $Id$
- */
--#define VERSION "1.1"
-+#define VERSION "2.4"
-
- #include <linux/config.h>
- #include <linux/module.h>
-
- #include <linux/types.h>
-+#include <linux/list.h>
- #include <linux/errno.h>
- #include <linux/kernel.h>
- #include <linux/major.h>
-@@ -40,6 +41,7 @@
- #include <linux/slab.h>
- #include <linux/skbuff.h>
- #include <linux/init.h>
-+#include <linux/poll.h>
- #include <linux/proc_fs.h>
- #include <net/sock.h>
-
-@@ -48,70 +50,79 @@
- #endif
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
-+
-+#ifndef AF_BLUETOOTH_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-
- /* Bluetooth sockets */
--static struct net_proto_family *bluez_sock[BLUEZ_MAX_PROTO];
-+#define BLUEZ_MAX_PROTO 6
-+static struct net_proto_family *bluez_proto[BLUEZ_MAX_PROTO];
-
- int bluez_sock_register(int proto, struct net_proto_family *ops)
- {
-- if (proto > BLUEZ_MAX_PROTO)
-+ if (proto >= BLUEZ_MAX_PROTO)
- return -EINVAL;
-
-- if (bluez_sock[proto])
-+ if (bluez_proto[proto])
- return -EEXIST;
-
-- bluez_sock[proto] = ops;
-+ bluez_proto[proto] = ops;
- return 0;
- }
-
- int bluez_sock_unregister(int proto)
- {
-- if (proto > BLUEZ_MAX_PROTO)
-+ if (proto >= BLUEZ_MAX_PROTO)
- return -EINVAL;
-
-- if (!bluez_sock[proto])
-+ if (!bluez_proto[proto])
- return -ENOENT;
-
-- bluez_sock[proto] = NULL;
-+ bluez_proto[proto] = NULL;
- return 0;
- }
-
- static int bluez_sock_create(struct socket *sock, int proto)
- {
-- if (proto > BLUEZ_MAX_PROTO)
-+ if (proto >= BLUEZ_MAX_PROTO)
- return -EINVAL;
-
- #if defined(CONFIG_KMOD)
-- if (!bluez_sock[proto]) {
-+ if (!bluez_proto[proto]) {
- char module_name[30];
- sprintf(module_name, "bt-proto-%d", proto);
- request_module(module_name);
- }
- #endif
-
-- if (!bluez_sock[proto])
-+ if (!bluez_proto[proto])
- return -ENOENT;
-
-- return bluez_sock[proto]->create(sock, proto);
-+ return bluez_proto[proto]->create(sock, proto);
-+}
-+
-+void bluez_sock_init(struct socket *sock, struct sock *sk)
-+{
-+ sock_init_data(sock, sk);
-+ INIT_LIST_HEAD(&bluez_pi(sk)->accept_q);
- }
-
- void bluez_sock_link(struct bluez_sock_list *l, struct sock *sk)
- {
-- write_lock(&l->lock);
--
-+ write_lock_bh(&l->lock);
- sk->next = l->head;
- l->head = sk;
- sock_hold(sk);
--
-- write_unlock(&l->lock);
-+ write_unlock_bh(&l->lock);
- }
-
- void bluez_sock_unlink(struct bluez_sock_list *l, struct sock *sk)
- {
- struct sock **skp;
-
-- write_lock(&l->lock);
-+ write_lock_bh(&l->lock);
- for (skp = &l->head; *skp; skp = &((*skp)->next)) {
- if (*skp == sk) {
- *skp = sk->next;
-@@ -119,7 +130,162 @@
- break;
- }
- }
-- write_unlock(&l->lock);
-+ write_unlock_bh(&l->lock);
-+}
-+
-+void bluez_accept_enqueue(struct sock *parent, struct sock *sk)
-+{
-+ BT_DBG("parent %p, sk %p", parent, sk);
-+
-+ sock_hold(sk);
-+ list_add_tail(&bluez_pi(sk)->accept_q, &bluez_pi(parent)->accept_q);
-+ bluez_pi(sk)->parent = parent;
-+ parent->ack_backlog++;
-+}
-+
-+static void bluez_accept_unlink(struct sock *sk)
-+{
-+ BT_DBG("sk %p state %d", sk, sk->state);
-+
-+ list_del_init(&bluez_pi(sk)->accept_q);
-+ bluez_pi(sk)->parent->ack_backlog--;
-+ bluez_pi(sk)->parent = NULL;
-+ sock_put(sk);
-+}
-+
-+struct sock *bluez_accept_dequeue(struct sock *parent, struct socket *newsock)
-+{
-+ struct list_head *p, *n;
-+ struct bluez_pinfo *pi;
-+ struct sock *sk;
-+
-+ BT_DBG("parent %p", parent);
-+
-+ list_for_each_safe(p, n, &bluez_pi(parent)->accept_q) {
-+ pi = list_entry(p, struct bluez_pinfo, accept_q);
-+ sk = bluez_sk(pi);
-+
-+ lock_sock(sk);
-+ if (sk->state == BT_CLOSED) {
-+ release_sock(sk);
-+ bluez_accept_unlink(sk);
-+ continue;
-+ }
-+
-+ if (sk->state == BT_CONNECTED || !newsock) {
-+ bluez_accept_unlink(sk);
-+ if (newsock)
-+ sock_graft(sk, newsock);
-+ release_sock(sk);
-+ return sk;
-+ }
-+ release_sock(sk);
-+ }
-+ return NULL;
-+}
-+
-+int bluez_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
-+{
-+ int noblock = flags & MSG_DONTWAIT;
-+ struct sock *sk = sock->sk;
-+ struct sk_buff *skb;
-+ int copied, err;
-+
-+ BT_DBG("sock %p sk %p len %d", sock, sk, len);
-+
-+ if (flags & (MSG_OOB))
-+ return -EOPNOTSUPP;
-+
-+ if (!(skb = skb_recv_datagram(sk, flags, noblock, &err))) {
-+ if (sk->shutdown & RCV_SHUTDOWN)
-+ return 0;
-+ return err;
-+ }
-+
-+ msg->msg_namelen = 0;
-+
-+ copied = skb->len;
-+ if (len < copied) {
-+ msg->msg_flags |= MSG_TRUNC;
-+ copied = len;
-+ }
-+
-+ skb->h.raw = skb->data;
-+ err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
-+
-+ skb_free_datagram(sk, skb);
-+
-+ return err ? : copied;
-+}
-+
-+unsigned int bluez_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
-+{
-+ struct sock *sk = sock->sk;
-+ unsigned int mask;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ poll_wait(file, sk->sleep, wait);
-+ mask = 0;
-+
-+ if (sk->err || !skb_queue_empty(&sk->error_queue))
-+ mask |= POLLERR;
-+
-+ if (sk->shutdown == SHUTDOWN_MASK)
-+ mask |= POLLHUP;
-+
-+ if (!skb_queue_empty(&sk->receive_queue) ||
-+ !list_empty(&bluez_pi(sk)->accept_q) ||
-+ (sk->shutdown & RCV_SHUTDOWN))
-+ mask |= POLLIN | POLLRDNORM;
-+
-+ if (sk->state == BT_CLOSED)
-+ mask |= POLLHUP;
-+
-+ if (sk->state == BT_CONNECT || sk->state == BT_CONNECT2)
-+ return mask;
-+
-+ if (sock_writeable(sk))
-+ mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
-+ else
-+ set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
-+
-+ return mask;
-+}
-+
-+int bluez_sock_wait_state(struct sock *sk, int state, unsigned long timeo)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ int err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ add_wait_queue(sk->sleep, &wait);
-+ while (sk->state != state) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+
-+ if (sk->err) {
-+ err = sock_error(sk);
-+ break;
-+ }
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+ return err;
- }
-
- struct net_proto_family bluez_sock_family_ops =
-@@ -129,9 +295,9 @@
-
- int bluez_init(void)
- {
-- INF("BlueZ HCI Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-+ BT_INFO("BlueZ Core ver %s Copyright (C) 2000,2001 Qualcomm Inc",
- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-
- proc_mkdir("bluetooth", NULL);
-
-@@ -164,5 +330,6 @@
- module_exit(bluez_cleanup);
-
- MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
--MODULE_DESCRIPTION("BlueZ HCI Core ver " VERSION);
-+MODULE_DESCRIPTION("BlueZ Core ver " VERSION);
-+MODULE_LICENSE("GPL");
- #endif
-diff -urN linux-2.4.18/net/bluetooth/bnep/Config.in linux-2.4.18-mh9/net/bluetooth/bnep/Config.in
---- linux-2.4.18/net/bluetooth/bnep/Config.in Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/bnep/Config.in Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,11 @@
-+#
-+# Bluetooth BNEP layer configuration
-+#
-+
-+dep_tristate 'BNEP protocol support' CONFIG_BLUEZ_BNEP $CONFIG_BLUEZ_L2CAP
-+
-+if [ "$CONFIG_BLUEZ_BNEP" != "n" ]; then
-+ bool ' Multicast filter support' CONFIG_BLUEZ_BNEP_MC_FILTER
-+ bool ' Protocol filter support' CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+fi
-+
-diff -urN linux-2.4.18/net/bluetooth/bnep/Makefile linux-2.4.18-mh9/net/bluetooth/bnep/Makefile
---- linux-2.4.18/net/bluetooth/bnep/Makefile Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/bnep/Makefile Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the Linux Bluetooth BNEP layer
-+#
-+
-+O_TARGET := bnep.o
-+
-+obj-y := core.o sock.o netdev.o crc32.o
-+obj-m += $(O_TARGET)
-+
-+include $(TOPDIR)/Rules.make
-diff -urN linux-2.4.18/net/bluetooth/bnep/bnep.h linux-2.4.18-mh9/net/bluetooth/bnep/bnep.h
---- linux-2.4.18/net/bluetooth/bnep/bnep.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/bnep/bnep.h Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,185 @@
-+/*
-+ BNEP protocol definition for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License, version 2, as
-+ published by the Free Software Foundation.
-+
-+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#ifndef _BNEP_H
-+#define _BNEP_H
-+
-+#include <linux/types.h>
-+#include <net/bluetooth/bluetooth.h>
-+
-+#include "crc32.h"
-+
-+// Limits
-+#define BNEP_MAX_PROTO_FILTERS 5
-+#define BNEP_MAX_MULTICAST_FILTERS 20
-+
-+// UUIDs
-+#define BNEP_BASE_UUID 0x0000000000001000800000805F9B34FB
-+#define BNEP_UUID16 0x02
-+#define BNEP_UUID32 0x04
-+#define BNEP_UUID128 0x16
-+
-+#define BNEP_SVC_PANU 0x1115
-+#define BNEP_SVC_NAP 0x1116
-+#define BNEP_SVC_GN 0x1117
-+
-+// Packet types
-+#define BNEP_GENERAL 0x00
-+#define BNEP_CONTROL 0x01
-+#define BNEP_COMPRESSED 0x02
-+#define BNEP_COMPRESSED_SRC_ONLY 0x03
-+#define BNEP_COMPRESSED_DST_ONLY 0x04
-+
-+// Control types
-+#define BNEP_CMD_NOT_UNDERSTOOD 0x00
-+#define BNEP_SETUP_CONN_REQ 0x01
-+#define BNEP_SETUP_CONN_RSP 0x02
-+#define BNEP_FILTER_NET_TYPE_SET 0x03
-+#define BNEP_FILTER_NET_TYPE_RSP 0x04
-+#define BNEP_FILTER_MULTI_ADDR_SET 0x05
-+#define BNEP_FILTER_MULTI_ADDR_RSP 0x06
-+
-+// Extension types
-+#define BNEP_EXT_CONTROL 0x00
-+
-+// Response messages
-+#define BNEP_SUCCESS 0x00
-+
-+#define BNEP_CONN_INVALID_DST 0x01
-+#define BNEP_CONN_INVALID_SRC 0x02
-+#define BNEP_CONN_INVALID_SVC 0x03
-+#define BNEP_CONN_NOT_ALLOWED 0x04
-+
-+#define BNEP_FILTER_UNSUPPORTED_REQ 0x01
-+#define BNEP_FILTER_INVALID_RANGE 0x02
-+#define BNEP_FILTER_INVALID_MCADDR 0x02
-+#define BNEP_FILTER_LIMIT_REACHED 0x03
-+#define BNEP_FILTER_DENIED_SECURITY 0x04
-+
-+// L2CAP settings
-+#define BNEP_MTU 1691
-+#define BNEP_PSM 0x0f
-+#define BNEP_FLUSH_TO 0xffff
-+#define BNEP_CONNECT_TO 15
-+#define BNEP_FILTER_TO 15
-+
-+// Headers
-+#define BNEP_TYPE_MASK 0x7f
-+#define BNEP_EXT_HEADER 0x80
-+
-+struct bnep_setup_conn_req {
-+ __u8 type;
-+ __u8 ctrl;
-+ __u8 uuid_size;
-+ __u8 service[0];
-+} __attribute__((packed));
-+
-+struct bnep_set_filter_req {
-+ __u8 type;
-+ __u8 ctrl;
-+ __u16 len;
-+ __u8 list[0];
-+} __attribute__((packed));
-+
-+struct bnep_control_rsp {
-+ __u8 type;
-+ __u8 ctrl;
-+ __u16 resp;
-+} __attribute__((packed));
-+
-+struct bnep_ext_hdr {
-+ __u8 type;
-+ __u8 len;
-+ __u8 data[0];
-+} __attribute__((packed));
-+
-+/* BNEP ioctl defines */
-+#define BNEPCONNADD _IOW('B', 200, int)
-+#define BNEPCONNDEL _IOW('B', 201, int)
-+#define BNEPGETCONNLIST _IOR('B', 210, int)
-+#define BNEPGETCONNINFO _IOR('B', 211, int)
-+
-+struct bnep_connadd_req {
-+ int sock; // Connected socket
-+ __u32 flags;
-+ __u16 role;
-+ char device[16]; // Name of the Ethernet device
-+};
-+
-+struct bnep_conndel_req {
-+ __u32 flags;
-+ __u8 dst[ETH_ALEN];
-+};
-+
-+struct bnep_conninfo {
-+ __u32 flags;
-+ __u16 role;
-+ __u16 state;
-+ __u8 dst[ETH_ALEN];
-+ char device[16];
-+};
-+
-+struct bnep_connlist_req {
-+ __u32 cnum;
-+ struct bnep_conninfo *ci;
-+};
-+
-+struct bnep_proto_filter {
-+ __u16 start;
-+ __u16 end;
-+};
-+
-+int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock);
-+int bnep_del_connection(struct bnep_conndel_req *req);
-+int bnep_get_connlist(struct bnep_connlist_req *req);
-+int bnep_get_conninfo(struct bnep_conninfo *ci);
-+
-+// BNEP sessions
-+struct bnep_session {
-+ struct list_head list;
-+
-+ unsigned int role;
-+ unsigned long state;
-+ unsigned long flags;
-+ atomic_t killed;
-+
-+ struct ethhdr eh;
-+ struct msghdr msg;
-+
-+ struct bnep_proto_filter proto_filter[BNEP_MAX_PROTO_FILTERS];
-+ u64 mc_filter;
-+
-+ struct socket *sock;
-+ struct net_device dev;
-+ struct net_device_stats stats;
-+};
-+
-+int bnep_net_init(struct net_device *dev);
-+int bnep_sock_init(void);
-+int bnep_sock_cleanup(void);
-+
-+static inline int bnep_mc_hash(__u8 *addr)
-+{
-+ return (bnep_crc32(~0, addr, ETH_ALEN) >> 26);
-+}
-+
-+#endif
-diff -urN linux-2.4.18/net/bluetooth/bnep/core.c linux-2.4.18-mh9/net/bluetooth/bnep/core.c
---- linux-2.4.18/net/bluetooth/bnep/core.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/bnep/core.c Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,708 @@
-+/*
-+ BNEP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2001-2002 Inventel Systemes
-+ Written 2001-2002 by
-+ Clément Moreau <clement.moreau@inventel.fr>
-+ David Libault <david.libault@inventel.fr>
-+
-+ Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#define __KERNEL_SYSCALLS__
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/signal.h>
-+#include <linux/init.h>
-+#include <linux/wait.h>
-+#include <linux/errno.h>
-+#include <linux/smp_lock.h>
-+#include <linux/net.h>
-+#include <net/sock.h>
-+
-+#include <linux/socket.h>
-+#include <linux/file.h>
-+
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#include "bnep.h"
-+
-+#ifndef CONFIG_BLUEZ_BNEP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define VERSION "1.1"
-+
-+static LIST_HEAD(bnep_session_list);
-+static DECLARE_RWSEM(bnep_session_sem);
-+
-+static struct bnep_session *__bnep_get_session(u8 *dst)
-+{
-+ struct bnep_session *s;
-+ struct list_head *p;
-+
-+ BT_DBG("");
-+
-+ list_for_each(p, &bnep_session_list) {
-+ s = list_entry(p, struct bnep_session, list);
-+ if (!memcmp(dst, s->eh.h_source, ETH_ALEN))
-+ return s;
-+ }
-+ return NULL;
-+}
-+
-+static void __bnep_link_session(struct bnep_session *s)
-+{
-+ MOD_INC_USE_COUNT;
-+ list_add(&s->list, &bnep_session_list);
-+}
-+
-+static void __bnep_unlink_session(struct bnep_session *s)
-+{
-+ list_del(&s->list);
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static int bnep_send(struct bnep_session *s, void *data, size_t len)
-+{
-+ struct socket *sock = s->sock;
-+ struct iovec iv = { data, len };
-+ s->msg.msg_iov = &iv;
-+ s->msg.msg_iovlen = 1;
-+ return sock->ops->sendmsg(sock, &s->msg, len, NULL);
-+}
-+
-+static int bnep_send_rsp(struct bnep_session *s, u8 ctrl, u16 resp)
-+{
-+ struct bnep_control_rsp rsp;
-+ rsp.type = BNEP_CONTROL;
-+ rsp.ctrl = ctrl;
-+ rsp.resp = htons(resp);
-+ return bnep_send(s, &rsp, sizeof(rsp));
-+}
-+
-+static int bnep_ctrl_set_netfilter(struct bnep_session *s, u16 *data, int len)
-+{
-+ int n;
-+
-+ if (len < 2)
-+ return -EILSEQ;
-+
-+ n = ntohs(get_unaligned(data));
-+ data++; len -= 2;
-+
-+ if (len < n)
-+ return -EILSEQ;
-+
-+ BT_DBG("filter len %d", n);
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+ n /= 4;
-+ if (n <= BNEP_MAX_PROTO_FILTERS) {
-+ struct bnep_proto_filter *f = s->proto_filter;
-+ int i;
-+
-+ for (i = 0; i < n; i++) {
-+ f[i].start = get_unaligned(data++);
-+ f[i].end = get_unaligned(data++);
-+
-+ BT_DBG("proto filter start %d end %d",
-+ f[i].start, f[i].end);
-+ }
-+ if (i < BNEP_MAX_PROTO_FILTERS)
-+ memset(f + i, 0, sizeof(*f));
-+
-+ bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_SUCCESS);
-+ } else {
-+ bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_LIMIT_REACHED);
-+ }
-+#else
-+ bnep_send_rsp(s, BNEP_FILTER_NET_TYPE_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
-+#endif
-+ return 0;
-+}
-+
-+static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
-+{
-+ int n;
-+
-+ if (len < 2)
-+ return -EILSEQ;
-+
-+ n = ntohs(get_unaligned((u16 *) data));
-+ data += 2; len -= 2;
-+
-+ if (len < n)
-+ return -EILSEQ;
-+
-+ BT_DBG("filter len %d", n);
-+
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+ n /= (ETH_ALEN * 2);
-+
-+ if (n > 0) {
-+ s->mc_filter = 0;
-+
-+ /* Always send broadcast */
-+ set_bit(bnep_mc_hash(s->dev.broadcast), &s->mc_filter);
-+
-+ /* Add address ranges to the multicast hash */
-+ for (; n > 0; n--) {
-+ u8 a1[6], *a2;
-+
-+ memcpy(a1, data, ETH_ALEN); data += ETH_ALEN;
-+ a2 = data; data += ETH_ALEN;
-+
-+ BT_DBG("mc filter %s -> %s",
-+ batostr((void *) a1), batostr((void *) a2));
-+
-+ #define INCA(a) { int i = 5; while (i >=0 && ++a[i--] == 0); }
-+
-+ /* Iterate from a1 to a2 */
-+ set_bit(bnep_mc_hash(a1), &s->mc_filter);
-+ while (memcmp(a1, a2, 6) < 0 && s->mc_filter != ~0LL) {
-+ INCA(a1);
-+ set_bit(bnep_mc_hash(a1), &s->mc_filter);
-+ }
-+ }
-+ }
-+
-+ BT_DBG("mc filter hash 0x%llx", s->mc_filter);
-+
-+ bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_SUCCESS);
-+#else
-+ bnep_send_rsp(s, BNEP_FILTER_MULTI_ADDR_RSP, BNEP_FILTER_UNSUPPORTED_REQ);
-+#endif
-+ return 0;
-+}
-+
-+static int bnep_rx_control(struct bnep_session *s, void *data, int len)
-+{
-+ u8 cmd = *(u8 *)data;
-+ int err = 0;
-+
-+ data++; len--;
-+
-+ switch (cmd) {
-+ case BNEP_CMD_NOT_UNDERSTOOD:
-+ case BNEP_SETUP_CONN_REQ:
-+ case BNEP_SETUP_CONN_RSP:
-+ case BNEP_FILTER_NET_TYPE_RSP:
-+ case BNEP_FILTER_MULTI_ADDR_RSP:
-+ /* Ignore these for now */
-+ break;
-+
-+ case BNEP_FILTER_NET_TYPE_SET:
-+ err = bnep_ctrl_set_netfilter(s, data, len);
-+ break;
-+
-+ case BNEP_FILTER_MULTI_ADDR_SET:
-+ err = bnep_ctrl_set_mcfilter(s, data, len);
-+ break;
-+
-+ default: {
-+ u8 pkt[3];
-+ pkt[0] = BNEP_CONTROL;
-+ pkt[1] = BNEP_CMD_NOT_UNDERSTOOD;
-+ pkt[2] = cmd;
-+ bnep_send(s, pkt, sizeof(pkt));
-+ }
-+ break;
-+ }
-+
-+ return err;
-+}
-+
-+static int bnep_rx_extension(struct bnep_session *s, struct sk_buff *skb)
-+{
-+ struct bnep_ext_hdr *h;
-+ int err = 0;
-+
-+ do {
-+ h = (void *) skb->data;
-+ if (!skb_pull(skb, sizeof(*h))) {
-+ err = -EILSEQ;
-+ break;
-+ }
-+
-+ BT_DBG("type 0x%x len %d", h->type, h->len);
-+
-+ switch (h->type & BNEP_TYPE_MASK) {
-+ case BNEP_EXT_CONTROL:
-+ bnep_rx_control(s, skb->data, skb->len);
-+ break;
-+
-+ default:
-+ /* Unknown extension, skip it. */
-+ break;
-+ }
-+
-+ if (!skb_pull(skb, h->len)) {
-+ err = -EILSEQ;
-+ break;
-+ }
-+ } while (!err && (h->type & BNEP_EXT_HEADER));
-+
-+ return err;
-+}
-+
-+static u8 __bnep_rx_hlen[] = {
-+ ETH_HLEN, /* BNEP_GENERAL */
-+ 0, /* BNEP_CONTROL */
-+ 2, /* BNEP_COMPRESSED */
-+ ETH_ALEN + 2, /* BNEP_COMPRESSED_SRC_ONLY */
-+ ETH_ALEN + 2 /* BNEP_COMPRESSED_DST_ONLY */
-+};
-+#define BNEP_RX_TYPES (sizeof(__bnep_rx_hlen) - 1)
-+
-+static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
-+{
-+ struct net_device *dev = &s->dev;
-+ struct sk_buff *nskb;
-+ u8 type;
-+
-+ dev->last_rx = jiffies;
-+ s->stats.rx_bytes += skb->len;
-+
-+ type = *(u8 *) skb->data; skb_pull(skb, 1);
-+
-+ if ((type & BNEP_TYPE_MASK) > BNEP_RX_TYPES)
-+ goto badframe;
-+
-+ if ((type & BNEP_TYPE_MASK) == BNEP_CONTROL) {
-+ bnep_rx_control(s, skb->data, skb->len);
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+
-+ skb->mac.raw = skb->data;
-+
-+ /* Verify and pull out header */
-+ if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK]))
-+ goto badframe;
-+
-+ s->eh.h_proto = get_unaligned((u16 *) (skb->data - 2));
-+
-+ if (type & BNEP_EXT_HEADER) {
-+ if (bnep_rx_extension(s, skb) < 0)
-+ goto badframe;
-+ }
-+
-+ /* Strip 802.1p header */
-+ if (ntohs(s->eh.h_proto) == 0x8100) {
-+ if (!skb_pull(skb, 4))
-+ goto badframe;
-+ s->eh.h_proto = get_unaligned((u16 *) (skb->data - 2));
-+ }
-+
-+ /* We have to alloc new skb and copy data here :(. Because original skb
-+ * may not be modified and because of the alignment requirements. */
-+ nskb = alloc_skb(2 + ETH_HLEN + skb->len, GFP_KERNEL);
-+ if (!nskb) {
-+ s->stats.rx_dropped++;
-+ kfree_skb(skb);
-+ return -ENOMEM;
-+ }
-+ skb_reserve(nskb, 2);
-+
-+ /* Decompress header and construct ether frame */
-+ switch (type & BNEP_TYPE_MASK) {
-+ case BNEP_COMPRESSED:
-+ memcpy(__skb_put(nskb, ETH_HLEN), &s->eh, ETH_HLEN);
-+ break;
-+
-+ case BNEP_COMPRESSED_SRC_ONLY:
-+ memcpy(__skb_put(nskb, ETH_ALEN), s->eh.h_dest, ETH_ALEN);
-+ memcpy(__skb_put(nskb, ETH_ALEN), skb->mac.raw, ETH_ALEN);
-+ put_unaligned(s->eh.h_proto, (u16 *) __skb_put(nskb, 2));
-+ break;
-+
-+ case BNEP_COMPRESSED_DST_ONLY:
-+ memcpy(__skb_put(nskb, ETH_ALEN), skb->mac.raw, ETH_ALEN);
-+ memcpy(__skb_put(nskb, ETH_ALEN + 2), s->eh.h_source, ETH_ALEN + 2);
-+ break;
-+
-+ case BNEP_GENERAL:
-+ memcpy(__skb_put(nskb, ETH_ALEN * 2), skb->mac.raw, ETH_ALEN * 2);
-+ put_unaligned(s->eh.h_proto, (u16 *) __skb_put(nskb, 2));
-+ break;
-+ }
-+
-+ memcpy(__skb_put(nskb, skb->len), skb->data, skb->len);
-+ kfree_skb(skb);
-+
-+ s->stats.rx_packets++;
-+ nskb->dev = dev;
-+ nskb->ip_summed = CHECKSUM_UNNECESSARY;
-+ nskb->protocol = eth_type_trans(nskb, dev);
-+ netif_rx_ni(nskb);
-+ return 0;
-+
-+badframe:
-+ s->stats.rx_errors++;
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+static u8 __bnep_tx_types[] = {
-+ BNEP_GENERAL,
-+ BNEP_COMPRESSED_SRC_ONLY,
-+ BNEP_COMPRESSED_DST_ONLY,
-+ BNEP_COMPRESSED
-+};
-+
-+static inline int bnep_tx_frame(struct bnep_session *s, struct sk_buff *skb)
-+{
-+ struct ethhdr *eh = (void *) skb->data;
-+ struct socket *sock = s->sock;
-+ struct iovec iv[3];
-+ int len = 0, il = 0;
-+ u8 type = 0;
-+
-+ BT_DBG("skb %p dev %p type %d", skb, skb->dev, skb->pkt_type);
-+
-+ if (!skb->dev) {
-+ /* Control frame sent by us */
-+ goto send;
-+ }
-+
-+ iv[il++] = (struct iovec) { &type, 1 };
-+ len++;
-+
-+ if (!memcmp(eh->h_dest, s->eh.h_source, ETH_ALEN))
-+ type |= 0x01;
-+
-+ if (!memcmp(eh->h_source, s->eh.h_dest, ETH_ALEN))
-+ type |= 0x02;
-+
-+ if (type)
-+ skb_pull(skb, ETH_ALEN * 2);
-+
-+ type = __bnep_tx_types[type];
-+ switch (type) {
-+ case BNEP_COMPRESSED_SRC_ONLY:
-+ iv[il++] = (struct iovec) { eh->h_source, ETH_ALEN };
-+ len += ETH_ALEN;
-+ break;
-+
-+ case BNEP_COMPRESSED_DST_ONLY:
-+ iv[il++] = (struct iovec) { eh->h_dest, ETH_ALEN };
-+ len += ETH_ALEN;
-+ break;
-+ }
-+
-+send:
-+ iv[il++] = (struct iovec) { skb->data, skb->len };
-+ len += skb->len;
-+
-+ /* FIXME: linearize skb */
-+
-+ s->msg.msg_iov = iv;
-+ s->msg.msg_iovlen = il;
-+ len = sock->ops->sendmsg(sock, &s->msg, len, NULL);
-+ kfree_skb(skb);
-+
-+ if (len > 0) {
-+ s->stats.tx_bytes += len;
-+ s->stats.tx_packets++;
-+ return 0;
-+ }
-+
-+ return len;
-+}
-+
-+static int bnep_session(void *arg)
-+{
-+ struct bnep_session *s = arg;
-+ struct net_device *dev = &s->dev;
-+ struct sock *sk = s->sock->sk;
-+ struct sk_buff *skb;
-+ wait_queue_t wait;
-+
-+ BT_DBG("");
-+
-+ daemonize(); reparent_to_init();
-+
-+ sprintf(current->comm, "kbnepd %s", dev->name);
-+
-+ sigfillset(&current->blocked);
-+ flush_signals(current);
-+
-+ current->nice = -15;
-+
-+ set_fs(KERNEL_DS);
-+
-+ init_waitqueue_entry(&wait, current);
-+ add_wait_queue(sk->sleep, &wait);
-+ while (!atomic_read(&s->killed)) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ // RX
-+ while ((skb = skb_dequeue(&sk->receive_queue))) {
-+ skb_orphan(skb);
-+ bnep_rx_frame(s, skb);
-+ }
-+
-+ if (sk->state != BT_CONNECTED)
-+ break;
-+
-+ // TX
-+ while ((skb = skb_dequeue(&sk->write_queue)))
-+ if (bnep_tx_frame(s, skb))
-+ break;
-+ netif_wake_queue(dev);
-+
-+ schedule();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ /* Cleanup session */
-+ down_write(&bnep_session_sem);
-+
-+ /* Delete network device */
-+ unregister_netdev(dev);
-+
-+ /* Release the socket */
-+ fput(s->sock->file);
-+
-+ __bnep_unlink_session(s);
-+
-+ up_write(&bnep_session_sem);
-+ kfree(s);
-+ return 0;
-+}
-+
-+int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
-+{
-+ struct net_device *dev;
-+ struct bnep_session *s, *ss;
-+ u8 dst[ETH_ALEN], src[ETH_ALEN];
-+ int err;
-+
-+ BT_DBG("");
-+
-+ baswap((void *) dst, &bluez_pi(sock->sk)->dst);
-+ baswap((void *) src, &bluez_pi(sock->sk)->src);
-+
-+ s = kmalloc(sizeof(struct bnep_session), GFP_KERNEL);
-+ if (!s)
-+ return -ENOMEM;
-+ memset(s, 0, sizeof(struct bnep_session));
-+
-+ down_write(&bnep_session_sem);
-+
-+ ss = __bnep_get_session(dst);
-+ if (ss && ss->state == BT_CONNECTED) {
-+ err = -EEXIST;
-+ goto failed;
-+ }
-+
-+ dev = &s->dev;
-+
-+ if (*req->device)
-+ strcpy(dev->name, req->device);
-+ else
-+ strcpy(dev->name, "bnep%d");
-+
-+ memset(dev->broadcast, 0xff, ETH_ALEN);
-+
-+ /* This is rx header therefor addresses are swaped.
-+ * ie eh.h_dest is our local address. */
-+ memcpy(s->eh.h_dest, &src, ETH_ALEN);
-+ memcpy(s->eh.h_source, &dst, ETH_ALEN);
-+
-+ s->sock = sock;
-+ s->role = req->role;
-+ s->state = BT_CONNECTED;
-+
-+ s->msg.msg_flags = MSG_NOSIGNAL;
-+
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+ /* Set default mc filter */
-+ set_bit(bnep_mc_hash(dev->broadcast), &s->mc_filter);
-+#endif
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+ /* Set default protocol filter */
-+
-+ /* (IPv4, ARP) */
-+ s->proto_filter[0].start = htons(0x0800);
-+ s->proto_filter[0].end = htons(0x0806);
-+ /* (RARP, AppleTalk) */
-+ s->proto_filter[1].start = htons(0x8035);
-+ s->proto_filter[1].end = htons(0x80F3);
-+ /* (IPX, IPv6) */
-+ s->proto_filter[2].start = htons(0x8137);
-+ s->proto_filter[2].end = htons(0x86DD);
-+#endif
-+
-+ dev->init = bnep_net_init;
-+ dev->priv = s;
-+ err = register_netdev(dev);
-+ if (err) {
-+ goto failed;
-+ }
-+
-+ __bnep_link_session(s);
-+
-+ err = kernel_thread(bnep_session, s, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-+ if (err < 0) {
-+ /* Session thread start failed, gotta cleanup. */
-+ unregister_netdev(dev);
-+ __bnep_unlink_session(s);
-+ goto failed;
-+ }
-+
-+ up_write(&bnep_session_sem);
-+ strcpy(req->device, dev->name);
-+ return 0;
-+
-+failed:
-+ up_write(&bnep_session_sem);
-+ kfree(s);
-+ return err;
-+}
-+
-+int bnep_del_connection(struct bnep_conndel_req *req)
-+{
-+ struct bnep_session *s;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ down_read(&bnep_session_sem);
-+
-+ s = __bnep_get_session(req->dst);
-+ if (s) {
-+ /* Wakeup user-space which is polling for socket errors.
-+ * This is temporary hack untill we have shutdown in L2CAP */
-+ s->sock->sk->err = EUNATCH;
-+
-+ /* Kill session thread */
-+ atomic_inc(&s->killed);
-+ wake_up_interruptible(s->sock->sk->sleep);
-+ } else
-+ err = -ENOENT;
-+
-+ up_read(&bnep_session_sem);
-+ return err;
-+}
-+
-+static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s)
-+{
-+ memcpy(ci->dst, s->eh.h_source, ETH_ALEN);
-+ strcpy(ci->device, s->dev.name);
-+ ci->flags = s->flags;
-+ ci->state = s->state;
-+ ci->role = s->role;
-+}
-+
-+int bnep_get_connlist(struct bnep_connlist_req *req)
-+{
-+ struct list_head *p;
-+ int err = 0, n = 0;
-+
-+ down_read(&bnep_session_sem);
-+
-+ list_for_each(p, &bnep_session_list) {
-+ struct bnep_session *s;
-+ struct bnep_conninfo ci;
-+
-+ s = list_entry(p, struct bnep_session, list);
-+
-+ __bnep_copy_ci(&ci, s);
-+
-+ if (copy_to_user(req->ci, &ci, sizeof(ci))) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ if (++n >= req->cnum)
-+ break;
-+
-+ req->ci++;
-+ }
-+ req->cnum = n;
-+
-+ up_read(&bnep_session_sem);
-+ return err;
-+}
-+
-+int bnep_get_conninfo(struct bnep_conninfo *ci)
-+{
-+ struct bnep_session *s;
-+ int err = 0;
-+
-+ down_read(&bnep_session_sem);
-+
-+ s = __bnep_get_session(ci->dst);
-+ if (s)
-+ __bnep_copy_ci(ci, s);
-+ else
-+ err = -ENOENT;
-+
-+ up_read(&bnep_session_sem);
-+ return err;
-+}
-+
-+static int __init bnep_init_module(void)
-+{
-+ l2cap_load();
-+
-+ bnep_crc32_init();
-+ bnep_sock_init();
-+
-+ BT_INFO("BlueZ BNEP ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2001,2002 Inventel Systemes");
-+ BT_INFO("Written 2001,2002 by Clement Moreau <clement.moreau@inventel.fr>");
-+ BT_INFO("Written 2001,2002 by David Libault <david.libault@inventel.fr>");
-+ BT_INFO("Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>");
-+
-+ return 0;
-+}
-+
-+static void __exit bnep_cleanup_module(void)
-+{
-+ bnep_sock_cleanup();
-+ bnep_crc32_cleanup();
-+}
-+
-+module_init(bnep_init_module);
-+module_exit(bnep_cleanup_module);
-+
-+MODULE_DESCRIPTION("BlueZ BNEP ver " VERSION);
-+MODULE_AUTHOR("David Libault <david.libault@inventel.fr>, Maxim Krasnyanskiy <maxk@qualcomm.com>");
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/bnep/crc32.c linux-2.4.18-mh9/net/bluetooth/bnep/crc32.c
---- linux-2.4.18/net/bluetooth/bnep/crc32.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/bnep/crc32.c Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,59 @@
-+/*
-+ * Based on linux-2.5/lib/crc32 by Matt Domsch <Matt_Domsch@dell.com>
-+ *
-+ * FIXME: Remove in 2.5
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <asm/atomic.h>
-+
-+#include "crc32.h"
-+
-+#define CRCPOLY_BE 0x04c11db7
-+#define CRC_BE_BITS 8
-+
-+static u32 *bnep_crc32_table;
-+
-+/*
-+ * This code is in the public domain; copyright abandoned.
-+ * Liability for non-performance of this code is limited to the amount
-+ * you paid for it. Since it is distributed for free, your refund will
-+ * be very very small. If it breaks, you get to keep both pieces.
-+ */
-+u32 bnep_crc32(u32 crc, unsigned char const *p, size_t len)
-+{
-+ while (len--)
-+ crc = (crc << 8) ^ bnep_crc32_table[(crc >> 24) ^ *p++];
-+
-+ return crc;
-+}
-+
-+int __init bnep_crc32_init(void)
-+{
-+ unsigned i, j;
-+ u32 crc = 0x80000000;
-+
-+ bnep_crc32_table = kmalloc((1 << CRC_BE_BITS) * sizeof(u32), GFP_KERNEL);
-+ if (!bnep_crc32_table)
-+ return -ENOMEM;
-+
-+ bnep_crc32_table[0] = 0;
-+
-+ for (i = 1; i < 1 << CRC_BE_BITS; i <<= 1) {
-+ crc = (crc << 1) ^ ((crc & 0x80000000) ? CRCPOLY_BE : 0);
-+ for (j = 0; j < i; j++)
-+ bnep_crc32_table[i + j] = crc ^ bnep_crc32_table[j];
-+ }
-+ return 0;
-+}
-+
-+void __exit bnep_crc32_cleanup(void)
-+{
-+ if (bnep_crc32_table)
-+ kfree(bnep_crc32_table);
-+ bnep_crc32_table = NULL;
-+}
-diff -urN linux-2.4.18/net/bluetooth/bnep/crc32.h linux-2.4.18-mh9/net/bluetooth/bnep/crc32.h
---- linux-2.4.18/net/bluetooth/bnep/crc32.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/bnep/crc32.h Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,10 @@
-+/*
-+ * crc32.h
-+ * See crc32.c for license and changes
-+ *
-+ * FIXME: Remove in 2.5
-+ */
-+
-+int bnep_crc32_init(void);
-+void bnep_crc32_cleanup(void);
-+u32 bnep_crc32(u32 crc, unsigned char const *p, size_t len);
-diff -urN linux-2.4.18/net/bluetooth/bnep/netdev.c linux-2.4.18-mh9/net/bluetooth/bnep/netdev.c
---- linux-2.4.18/net/bluetooth/bnep/netdev.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/bnep/netdev.c Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,254 @@
-+/*
-+ BNEP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2001-2002 Inventel Systemes
-+ Written 2001-2002 by
-+ Clément Moreau <clement.moreau@inventel.fr>
-+ David Libault <david.libault@inventel.fr>
-+
-+ Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/socket.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/skbuff.h>
-+#include <linux/wait.h>
-+
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#include "bnep.h"
-+
-+#ifndef CONFIG_BLUEZ_BNEP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+#define BNEP_TX_QUEUE_LEN 20
-+
-+static int bnep_net_open(struct net_device *dev)
-+{
-+ netif_start_queue(dev);
-+ return 0;
-+}
-+
-+static int bnep_net_close(struct net_device *dev)
-+{
-+ netif_stop_queue(dev);
-+ return 0;
-+}
-+
-+static struct net_device_stats *bnep_net_get_stats(struct net_device *dev)
-+{
-+ struct bnep_session *s = dev->priv;
-+ return &s->stats;
-+}
-+
-+static void bnep_net_set_mc_list(struct net_device *dev)
-+{
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+ struct bnep_session *s = dev->priv;
-+ struct sock *sk = s->sock->sk;
-+ struct bnep_set_filter_req *r;
-+ struct sk_buff *skb;
-+ int size;
-+
-+ BT_DBG("%s mc_count %d", dev->name, dev->mc_count);
-+
-+ size = sizeof(*r) + (BNEP_MAX_MULTICAST_FILTERS + 1) * ETH_ALEN * 2;
-+ skb = alloc_skb(size, GFP_ATOMIC);
-+ if (!skb) {
-+ BT_ERR("%s Multicast list allocation failed", dev->name);
-+ return;
-+ }
-+
-+ r = (void *) skb->data;
-+ __skb_put(skb, sizeof(*r));
-+
-+ r->type = BNEP_CONTROL;
-+ r->ctrl = BNEP_FILTER_MULTI_ADDR_SET;
-+
-+ if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
-+ u8 start[ETH_ALEN] = { 0x01 };
-+
-+ /* Request all addresses */
-+ memcpy(__skb_put(skb, ETH_ALEN), start, ETH_ALEN);
-+ memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
-+ r->len = htons(ETH_ALEN * 2);
-+ } else {
-+ struct dev_mc_list *dmi = dev->mc_list;
-+ int i, len = skb->len;
-+
-+ if (dev->flags & IFF_BROADCAST) {
-+ memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
-+ memcpy(__skb_put(skb, ETH_ALEN), dev->broadcast, ETH_ALEN);
-+ }
-+
-+ /* FIXME: We should group addresses here. */
-+
-+ for (i = 0; i < dev->mc_count && i < BNEP_MAX_MULTICAST_FILTERS; i++) {
-+ memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN);
-+ memcpy(__skb_put(skb, ETH_ALEN), dmi->dmi_addr, ETH_ALEN);
-+ dmi = dmi->next;
-+ }
-+ r->len = htons(skb->len - len);
-+ }
-+
-+ skb_queue_tail(&sk->write_queue, skb);
-+ wake_up_interruptible(sk->sleep);
-+#endif
-+}
-+
-+static int bnep_net_set_mac_addr(struct net_device *dev, void *arg)
-+{
-+ BT_DBG("%s", dev->name);
-+ return 0;
-+}
-+
-+static void bnep_net_timeout(struct net_device *dev)
-+{
-+ BT_DBG("net_timeout");
-+ netif_wake_queue(dev);
-+}
-+
-+static int bnep_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-+{
-+ return -EINVAL;
-+}
-+
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+static inline int bnep_net_mc_filter(struct sk_buff *skb, struct bnep_session *s)
-+{
-+ struct ethhdr *eh = (void *) skb->data;
-+
-+ if ((eh->h_dest[0] & 1) && !test_bit(bnep_mc_hash(eh->h_dest), &s->mc_filter)) {
-+ BT_DBG("BNEP: filtered skb %p, dst %.2x:%.2x:%.2x:%.2x:%.2x:%.2x", skb,
-+ eh->h_dest[0], eh->h_dest[1], eh->h_dest[2],
-+ eh->h_dest[3], eh->h_dest[4], eh->h_dest[5]);
-+ return 1;
-+ }
-+ return 0;
-+}
-+#endif
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+/* Determine ether protocol. Based on eth_type_trans. */
-+static inline u16 bnep_net_eth_proto(struct sk_buff *skb)
-+{
-+ struct ethhdr *eh = (void *) skb->data;
-+
-+ if (ntohs(eh->h_proto) >= 1536)
-+ return eh->h_proto;
-+
-+ if (get_unaligned((u16 *) skb->data) == 0xFFFF)
-+ return htons(ETH_P_802_3);
-+
-+ return htons(ETH_P_802_2);
-+}
-+
-+static inline int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session *s)
-+{
-+ u16 proto = bnep_net_eth_proto(skb);
-+ struct bnep_proto_filter *f = s->proto_filter;
-+ int i;
-+
-+ for (i = 0; i < BNEP_MAX_PROTO_FILTERS && f[i].end; i++) {
-+ if (proto >= f[i].start && proto <= f[i].end)
-+ return 0;
-+ }
-+
-+ BT_DBG("BNEP: filtered skb %p, proto 0x%.4x", skb, proto);
-+ return 1;
-+}
-+#endif
-+
-+static int bnep_net_xmit(struct sk_buff *skb, struct net_device *dev)
-+{
-+ struct bnep_session *s = dev->priv;
-+ struct sock *sk = s->sock->sk;
-+
-+ BT_DBG("skb %p, dev %p", skb, dev);
-+
-+#ifdef CONFIG_BLUEZ_BNEP_MC_FILTER
-+ if (bnep_net_mc_filter(skb, s)) {
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+#endif
-+
-+#ifdef CONFIG_BLUEZ_BNEP_PROTO_FILTER
-+ if (bnep_net_proto_filter(skb, s)) {
-+ kfree_skb(skb);
-+ return 0;
-+ }
-+#endif
-+
-+ /*
-+ * We cannot send L2CAP packets from here as we are potentially in a bh.
-+ * So we have to queue them and wake up session thread which is sleeping
-+ * on the sk->sleep.
-+ */
-+ dev->trans_start = jiffies;
-+ skb_queue_tail(&sk->write_queue, skb);
-+ wake_up_interruptible(sk->sleep);
-+
-+ if (skb_queue_len(&sk->write_queue) >= BNEP_TX_QUEUE_LEN) {
-+ BT_DBG("tx queue is full");
-+
-+ /* Stop queuing.
-+ * Session thread will do netif_wake_queue() */
-+ netif_stop_queue(dev);
-+ }
-+
-+ return 0;
-+}
-+
-+int bnep_net_init(struct net_device *dev)
-+{
-+ struct bnep_session *s = dev->priv;
-+
-+ memcpy(dev->dev_addr, s->eh.h_dest, ETH_ALEN);
-+ dev->addr_len = ETH_ALEN;
-+
-+ ether_setup(dev);
-+
-+ dev->open = bnep_net_open;
-+ dev->stop = bnep_net_close;
-+ dev->hard_start_xmit = bnep_net_xmit;
-+ dev->get_stats = bnep_net_get_stats;
-+ dev->do_ioctl = bnep_net_ioctl;
-+ dev->set_mac_address = bnep_net_set_mac_addr;
-+ dev->set_multicast_list = bnep_net_set_mc_list;
-+
-+ dev->watchdog_timeo = HZ * 2;
-+ dev->tx_timeout = bnep_net_timeout;
-+
-+ return 0;
-+}
-diff -urN linux-2.4.18/net/bluetooth/bnep/sock.c linux-2.4.18-mh9/net/bluetooth/bnep/sock.c
---- linux-2.4.18/net/bluetooth/bnep/sock.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/bnep/sock.c Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,238 @@
-+/*
-+ BNEP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2001-2002 Inventel Systemes
-+ Written 2001-2002 by
-+ David Libault <david.libault@inventel.fr>
-+
-+ Copyright (C) 2002 Maxim Krasnyanskiy <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include "bnep.h"
-+
-+#ifndef CONFIG_BLUEZ_BNEP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+static inline struct socket *socki_lookup(struct inode *inode)
-+{
-+ return &inode->u.socket_i;
-+}
-+
-+static struct socket *sockfd_lookup(int fd, int *err)
-+{
-+ struct file *file;
-+ struct inode *inode;
-+ struct socket *sock;
-+
-+ if (!(file = fget(fd))) {
-+ *err = -EBADF;
-+ return NULL;
-+ }
-+
-+ inode = file->f_dentry->d_inode;
-+ if (!inode->i_sock || !(sock = socki_lookup(inode))) {
-+ *err = -ENOTSOCK;
-+ fput(file);
-+ return NULL;
-+ }
-+
-+ if (sock->file != file) {
-+ printk(KERN_ERR "socki_lookup: socket file changed!\n");
-+ sock->file = file;
-+ }
-+ return sock;
-+}
-+
-+static int bnep_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ sock_orphan(sk);
-+ sock_put(sk);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct bnep_connlist_req cl;
-+ struct bnep_connadd_req ca;
-+ struct bnep_conndel_req cd;
-+ struct bnep_conninfo ci;
-+ struct socket *nsock;
-+ int err;
-+
-+ BT_DBG("cmd %x arg %lx", cmd, arg);
-+
-+ switch (cmd) {
-+ case BNEPCONNADD:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
-+ return -EFAULT;
-+
-+ nsock = sockfd_lookup(ca.sock, &err);
-+ if (!nsock)
-+ return err;
-+
-+ if (nsock->sk->state != BT_CONNECTED)
-+ return -EBADFD;
-+
-+ err = bnep_add_connection(&ca, nsock);
-+ if (!err) {
-+ if (copy_to_user((void *) arg, &ca, sizeof(ca)))
-+ err = -EFAULT;
-+ } else
-+ fput(nsock->file);
-+
-+ return err;
-+
-+ case BNEPCONNDEL:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
-+ return -EFAULT;
-+
-+ return bnep_del_connection(&cd);
-+
-+ case BNEPGETCONNLIST:
-+ if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
-+ return -EFAULT;
-+
-+ if (cl.cnum <= 0)
-+ return -EINVAL;
-+
-+ err = bnep_get_connlist(&cl);
-+ if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
-+ return -EFAULT;
-+
-+ return err;
-+
-+ case BNEPGETCONNINFO:
-+ if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
-+ return -EFAULT;
-+
-+ err = bnep_get_conninfo(&ci);
-+ if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
-+ return -EFAULT;
-+
-+ return err;
-+
-+ default:
-+ return -EINVAL;
-+ }
-+
-+ return 0;
-+}
-+
-+static struct proto_ops bnep_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: bnep_sock_release,
-+ ioctl: bnep_sock_ioctl,
-+ bind: sock_no_bind,
-+ getname: sock_no_getname,
-+ sendmsg: sock_no_sendmsg,
-+ recvmsg: sock_no_recvmsg,
-+ poll: sock_no_poll,
-+ listen: sock_no_listen,
-+ shutdown: sock_no_shutdown,
-+ setsockopt: sock_no_setsockopt,
-+ getsockopt: sock_no_getsockopt,
-+ connect: sock_no_connect,
-+ socketpair: sock_no_socketpair,
-+ accept: sock_no_accept,
-+ mmap: sock_no_mmap
-+};
-+
-+static int bnep_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ if (sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &bnep_sock_ops;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, 1)))
-+ return -ENOMEM;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ sock->state = SS_UNCONNECTED;
-+ sock_init_data(sock, sk);
-+
-+ sk->destruct = NULL;
-+ sk->protocol = protocol;
-+
-+ return 0;
-+}
-+
-+static struct net_proto_family bnep_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: bnep_sock_create
-+};
-+
-+int bnep_sock_init(void)
-+{
-+ bluez_sock_register(BTPROTO_BNEP, &bnep_sock_family_ops);
-+ return 0;
-+}
-+
-+int bnep_sock_cleanup(void)
-+{
-+ if (bluez_sock_unregister(BTPROTO_BNEP))
-+ BT_ERR("Can't unregister BNEP socket");
-+ return 0;
-+}
-diff -urN linux-2.4.18/net/bluetooth/cmtp/Config.in linux-2.4.18-mh9/net/bluetooth/cmtp/Config.in
---- linux-2.4.18/net/bluetooth/cmtp/Config.in Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/cmtp/Config.in Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,7 @@
-+#
-+# Bluetooth CMTP layer configuration
-+#
-+
-+if [ "$CONFIG_ISDN" = "y" -o "$CONFIG_ISDN" = "m" ]; then
-+ dep_tristate 'CMTP protocol support' CONFIG_BLUEZ_CMTP $CONFIG_ISDN_CAPI $CONFIG_BLUEZ_L2CAP
-+fi
-diff -urN linux-2.4.18/net/bluetooth/cmtp/Makefile linux-2.4.18-mh9/net/bluetooth/cmtp/Makefile
---- linux-2.4.18/net/bluetooth/cmtp/Makefile Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/cmtp/Makefile Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for the Linux Bluetooth CMTP layer
-+#
-+
-+O_TARGET := cmtp.o
-+
-+obj-y := core.o sock.o capi.o
-+obj-m += $(O_TARGET)
-+
-+include $(TOPDIR)/Rules.make
-diff -urN linux-2.4.18/net/bluetooth/cmtp/capi.c linux-2.4.18-mh9/net/bluetooth/cmtp/capi.c
---- linux-2.4.18/net/bluetooth/cmtp/capi.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/cmtp/capi.c Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,707 @@
-+/*
-+ CMTP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <net/sock.h>
-+
-+#include <linux/capi.h>
-+
-+#include "../drivers/isdn/avmb1/capilli.h"
-+#include "../drivers/isdn/avmb1/capicmd.h"
-+#include "../drivers/isdn/avmb1/capiutil.h"
-+
-+#include "cmtp.h"
-+
-+#ifndef CONFIG_BLUEZ_CMTP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define REVISION "1.0"
-+
-+#define CAPI_INTEROPERABILITY 0x20
-+
-+#define CAPI_INTEROPERABILITY_REQ CAPICMD(CAPI_INTEROPERABILITY, CAPI_REQ)
-+#define CAPI_INTEROPERABILITY_CONF CAPICMD(CAPI_INTEROPERABILITY, CAPI_CONF)
-+#define CAPI_INTEROPERABILITY_IND CAPICMD(CAPI_INTEROPERABILITY, CAPI_IND)
-+#define CAPI_INTEROPERABILITY_RESP CAPICMD(CAPI_INTEROPERABILITY, CAPI_RESP)
-+
-+#define CAPI_INTEROPERABILITY_REQ_LEN (CAPI_MSG_BASELEN + 2)
-+#define CAPI_INTEROPERABILITY_CONF_LEN (CAPI_MSG_BASELEN + 4)
-+#define CAPI_INTEROPERABILITY_IND_LEN (CAPI_MSG_BASELEN + 2)
-+#define CAPI_INTEROPERABILITY_RESP_LEN (CAPI_MSG_BASELEN + 2)
-+
-+#define CAPI_FUNCTION_REGISTER 0
-+#define CAPI_FUNCTION_RELEASE 1
-+#define CAPI_FUNCTION_GET_PROFILE 2
-+#define CAPI_FUNCTION_GET_MANUFACTURER 3
-+#define CAPI_FUNCTION_GET_VERSION 4
-+#define CAPI_FUNCTION_GET_SERIAL_NUMBER 5
-+#define CAPI_FUNCTION_MANUFACTURER 6
-+#define CAPI_FUNCTION_LOOPBACK 7
-+
-+static struct capi_driver_interface *di;
-+
-+
-+#define CMTP_MSGNUM 1
-+#define CMTP_APPLID 2
-+#define CMTP_MAPPING 3
-+
-+static struct cmtp_application *cmtp_application_add(struct cmtp_session *session, __u16 appl)
-+{
-+ struct cmtp_application *app = kmalloc(sizeof(*app), GFP_KERNEL);
-+
-+ BT_DBG("session %p application %p appl %d", session, app, appl);
-+
-+ if (!app)
-+ return NULL;
-+
-+ memset(app, 0, sizeof(*app));
-+
-+ app->state = BT_OPEN;
-+ app->appl = appl;
-+
-+ list_add_tail(&app->list, &session->applications);
-+
-+ return app;
-+}
-+
-+static void cmtp_application_del(struct cmtp_session *session, struct cmtp_application *app)
-+{
-+ BT_DBG("session %p application %p", session, app);
-+
-+ if (app) {
-+ list_del(&app->list);
-+ kfree(app);
-+ }
-+}
-+
-+static struct cmtp_application *cmtp_application_get(struct cmtp_session *session, int pattern, __u16 value)
-+{
-+ struct cmtp_application *app;
-+ struct list_head *p, *n;
-+
-+ list_for_each_safe(p, n, &session->applications) {
-+ app = list_entry(p, struct cmtp_application, list);
-+ switch (pattern) {
-+ case CMTP_MSGNUM:
-+ if (app->msgnum == value)
-+ return app;
-+ break;
-+ case CMTP_APPLID:
-+ if (app->appl == value)
-+ return app;
-+ break;
-+ case CMTP_MAPPING:
-+ if (app->mapping == value)
-+ return app;
-+ break;
-+ }
-+ }
-+
-+ return NULL;
-+}
-+
-+static int cmtp_msgnum_get(struct cmtp_session *session)
-+{
-+ session->msgnum++;
-+
-+ if ((session->msgnum & 0xff) > 200)
-+ session->msgnum = CMTP_INITIAL_MSGNUM + 1;
-+
-+ return session->msgnum;
-+}
-+
-+
-+static void cmtp_send_interopmsg(struct cmtp_session *session,
-+ __u8 subcmd, __u16 appl, __u16 msgnum,
-+ __u16 function, unsigned char *buf, int len)
-+{
-+ struct sk_buff *skb;
-+ unsigned char *s;
-+
-+ BT_DBG("session %p subcmd 0x%02x appl %d msgnum %d", session, subcmd, appl, msgnum);
-+
-+ if (!(skb = alloc_skb(CAPI_MSG_BASELEN + 6 + len, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for interoperability packet");
-+ return;
-+ }
-+
-+ s = skb_put(skb, CAPI_MSG_BASELEN + 6 + len);
-+
-+ capimsg_setu16(s, 0, CAPI_MSG_BASELEN + 6 + len);
-+ capimsg_setu16(s, 2, appl);
-+ capimsg_setu8 (s, 4, CAPI_INTEROPERABILITY);
-+ capimsg_setu8 (s, 5, subcmd);
-+ capimsg_setu16(s, 6, msgnum);
-+
-+ /* Interoperability selector (Bluetooth Device Management) */
-+ capimsg_setu16(s, 8, 0x0001);
-+
-+ capimsg_setu8 (s, 10, 3 + len);
-+ capimsg_setu16(s, 11, function);
-+ capimsg_setu8 (s, 13, len);
-+
-+ if (len > 0)
-+ memcpy(s + 14, buf, len);
-+
-+ cmtp_send_capimsg(session, skb);
-+}
-+
-+static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *skb)
-+{
-+ struct capi_ctr *ctrl = session->ctrl;
-+ struct cmtp_application *application;
-+ __u16 appl, msgnum, func, info;
-+ __u32 controller;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ switch (CAPIMSG_SUBCOMMAND(skb->data)) {
-+ case CAPI_CONF:
-+ func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
-+ info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
-+
-+ switch (func) {
-+ case CAPI_FUNCTION_REGISTER:
-+ msgnum = CAPIMSG_MSGID(skb->data);
-+
-+ application = cmtp_application_get(session, CMTP_MSGNUM, msgnum);
-+ if (application) {
-+ application->state = BT_CONNECTED;
-+ application->msgnum = 0;
-+ application->mapping = CAPIMSG_APPID(skb->data);
-+ wake_up_interruptible(&session->wait);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_RELEASE:
-+ appl = CAPIMSG_APPID(skb->data);
-+
-+ application = cmtp_application_get(session, CMTP_MAPPING, appl);
-+ if (application) {
-+ application->state = BT_CLOSED;
-+ application->msgnum = 0;
-+ wake_up_interruptible(&session->wait);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_GET_PROFILE:
-+ controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
-+ msgnum = CAPIMSG_MSGID(skb->data);
-+
-+ if (!info && (msgnum == CMTP_INITIAL_MSGNUM)) {
-+ session->ncontroller = controller;
-+ wake_up_interruptible(&session->wait);
-+ break;
-+ }
-+
-+ if (!info && ctrl) {
-+ memcpy(&ctrl->profile,
-+ skb->data + CAPI_MSG_BASELEN + 11,
-+ sizeof(capi_profile));
-+ session->state = BT_CONNECTED;
-+ ctrl->ready(ctrl);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_GET_MANUFACTURER:
-+ controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);
-+
-+ if (!info && ctrl) {
-+ strncpy(ctrl->manu,
-+ skb->data + CAPI_MSG_BASELEN + 15,
-+ skb->data[CAPI_MSG_BASELEN + 14]);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_GET_VERSION:
-+ controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
-+
-+ if (!info && ctrl) {
-+ ctrl->version.majorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 16);
-+ ctrl->version.minorversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 20);
-+ ctrl->version.majormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 24);
-+ ctrl->version.minormanuversion = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 28);
-+ }
-+
-+ break;
-+
-+ case CAPI_FUNCTION_GET_SERIAL_NUMBER:
-+ controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
-+
-+ if (!info && ctrl) {
-+ memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
-+ strncpy(ctrl->serial,
-+ skb->data + CAPI_MSG_BASELEN + 17,
-+ skb->data[CAPI_MSG_BASELEN + 16]);
-+ }
-+
-+ break;
-+ }
-+
-+ break;
-+
-+ case CAPI_IND:
-+ func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
-+
-+ if (func == CAPI_FUNCTION_LOOPBACK) {
-+ appl = CAPIMSG_APPID(skb->data);
-+ msgnum = CAPIMSG_MSGID(skb->data);
-+ cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
-+ skb->data + CAPI_MSG_BASELEN + 6,
-+ skb->data[CAPI_MSG_BASELEN + 5]);
-+ }
-+
-+ break;
-+ }
-+
-+ kfree_skb(skb);
-+}
-+
-+void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
-+{
-+ struct capi_ctr *ctrl = session->ctrl;
-+ struct cmtp_application *application;
-+ __u16 cmd, appl, info;
-+ __u32 ncci, contr;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
-+ cmtp_recv_interopmsg(session, skb);
-+ return;
-+ }
-+
-+ if (session->flags & (1 << CMTP_LOOPBACK)) {
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ cmd = CAPICMD(CAPIMSG_COMMAND(skb->data), CAPIMSG_SUBCOMMAND(skb->data));
-+ appl = CAPIMSG_APPID(skb->data);
-+ contr = CAPIMSG_CONTROL(skb->data);
-+
-+ application = cmtp_application_get(session, CMTP_MAPPING, appl);
-+ if (application) {
-+ appl = application->appl;
-+ CAPIMSG_SETAPPID(skb->data, appl);
-+ } else {
-+ BT_ERR("Can't find application with id %d", appl);
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ if ((contr & 0x7f) == 0x01) {
-+ contr = (contr & 0xffffff80) | session->num;
-+ CAPIMSG_SETCONTROL(skb->data, contr);
-+ }
-+
-+ if (!ctrl) {
-+ BT_ERR("Can't find controller %d for message", session->num);
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ switch (cmd) {
-+ case CAPI_CONNECT_B3_CONF:
-+ ncci = CAPIMSG_NCCI(skb->data);
-+ info = CAPIMSG_U16(skb->data, 12);
-+
-+ BT_DBG("CONNECT_B3_CONF ncci 0x%02x info 0x%02x", ncci, info);
-+
-+ if (info == 0)
-+ ctrl->new_ncci(ctrl, appl, ncci, 8);
-+
-+ ctrl->handle_capimsg(ctrl, appl, skb);
-+ break;
-+
-+ case CAPI_CONNECT_B3_IND:
-+ ncci = CAPIMSG_NCCI(skb->data);
-+
-+ BT_DBG("CONNECT_B3_IND ncci 0x%02x", ncci);
-+
-+ ctrl->new_ncci(ctrl, appl, ncci, 8);
-+ ctrl->handle_capimsg(ctrl, appl, skb);
-+ break;
-+
-+ case CAPI_DISCONNECT_B3_IND:
-+ ncci = CAPIMSG_NCCI(skb->data);
-+
-+ BT_DBG("DISCONNECT_B3_IND ncci 0x%02x", ncci);
-+
-+ if (ncci == 0xffffffff)
-+ BT_ERR("DISCONNECT_B3_IND with ncci 0xffffffff");
-+
-+ ctrl->handle_capimsg(ctrl, appl, skb);
-+ ctrl->free_ncci(ctrl, appl, ncci);
-+ break;
-+
-+ default:
-+ ctrl->handle_capimsg(ctrl, appl, skb);
-+ break;
-+ }
-+}
-+
-+void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb)
-+{
-+ struct cmtp_scb *scb = (void *) skb->cb;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ scb->id = -1;
-+ scb->data = (CAPIMSG_COMMAND(skb->data) == CAPI_DATA_B3);
-+
-+ skb_queue_tail(&session->transmit, skb);
-+
-+ cmtp_schedule(session);
-+}
-+
-+
-+static int cmtp_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
-+{
-+ BT_DBG("ctrl %p data %p", ctrl, data);
-+
-+ return -EIO;
-+}
-+
-+static void cmtp_reset_ctr(struct capi_ctr *ctrl)
-+{
-+ BT_DBG("ctrl %p", ctrl);
-+
-+ ctrl->reseted(ctrl);
-+}
-+
-+static void cmtp_remove_ctr(struct capi_ctr *ctrl)
-+{
-+ struct cmtp_session *session = ctrl->driverdata;
-+
-+ BT_DBG("ctrl %p", ctrl);
-+
-+ ctrl->suspend_output(ctrl);
-+
-+ atomic_inc(&session->terminate);
-+ cmtp_schedule(session);
-+}
-+
-+static void cmtp_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct cmtp_session *session = ctrl->driverdata;
-+ struct cmtp_application *application;
-+ unsigned long timeo = CMTP_INTEROP_TIMEOUT;
-+ unsigned char buf[8];
-+ int err = 0, nconn, want = rp->level3cnt;
-+
-+ BT_DBG("ctrl %p appl %d level3cnt %d datablkcnt %d datablklen %d",
-+ ctrl, appl, rp->level3cnt, rp->datablkcnt, rp->datablklen);
-+
-+ application = cmtp_application_add(session, appl);
-+ if (!application) {
-+ BT_ERR("Can't allocate memory for new application");
-+ ctrl->appl_released(ctrl, appl);
-+ return;
-+ }
-+
-+ if (want < 0)
-+ nconn = ctrl->profile.nbchannel * -want;
-+ else
-+ nconn = want;
-+
-+ if (nconn == 0)
-+ nconn = ctrl->profile.nbchannel;
-+
-+ capimsg_setu16(buf, 0, nconn);
-+ capimsg_setu16(buf, 2, rp->datablkcnt);
-+ capimsg_setu16(buf, 4, rp->datablklen);
-+
-+ application->state = BT_CONFIG;
-+ application->msgnum = cmtp_msgnum_get(session);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0x0000, application->msgnum,
-+ CAPI_FUNCTION_REGISTER, buf, 6);
-+
-+ add_wait_queue(&session->wait, &wait);
-+ while (1) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ if (application->state == BT_CLOSED) {
-+ err = -application->err;
-+ break;
-+ }
-+
-+ if (application->state == BT_CONNECTED)
-+ break;
-+
-+ if (signal_pending(current)) {
-+ err = -EINTR;
-+ break;
-+ }
-+
-+ timeo = schedule_timeout(timeo);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&session->wait, &wait);
-+
-+ if (err) {
-+ ctrl->appl_released(ctrl, appl);
-+ cmtp_application_del(session, application);
-+ return;
-+ }
-+
-+ ctrl->appl_registered(ctrl, appl);
-+}
-+
-+static void cmtp_release_appl(struct capi_ctr *ctrl, __u16 appl)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct cmtp_session *session = ctrl->driverdata;
-+ struct cmtp_application *application;
-+ unsigned long timeo = CMTP_INTEROP_TIMEOUT;
-+
-+ BT_DBG("ctrl %p appl %d", ctrl, appl);
-+
-+ application = cmtp_application_get(session, CMTP_APPLID, appl);
-+ if (!application) {
-+ BT_ERR("Can't find application");
-+ return;
-+ }
-+
-+ application->msgnum = cmtp_msgnum_get(session);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, application->mapping, application->msgnum,
-+ CAPI_FUNCTION_RELEASE, NULL, 0);
-+
-+ add_wait_queue(&session->wait, &wait);
-+ while (timeo) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (application->state == BT_CLOSED)
-+ break;
-+
-+ if (signal_pending(current))
-+ break;
-+
-+ timeo = schedule_timeout(timeo);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&session->wait, &wait);
-+
-+ cmtp_application_del(session, application);
-+ ctrl->appl_released(ctrl, appl);
-+}
-+
-+static void cmtp_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
-+{
-+ struct cmtp_session *session = ctrl->driverdata;
-+ struct cmtp_application *application;
-+ __u16 appl;
-+ __u32 contr;
-+
-+ BT_DBG("ctrl %p skb %p", ctrl, skb);
-+
-+ appl = CAPIMSG_APPID(skb->data);
-+ contr = CAPIMSG_CONTROL(skb->data);
-+
-+ application = cmtp_application_get(session, CMTP_APPLID, appl);
-+ if ((!application) || (application->state != BT_CONNECTED)) {
-+ BT_ERR("Can't find application with id %d", appl);
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ CAPIMSG_SETAPPID(skb->data, application->mapping);
-+
-+ if ((contr & 0x7f) == session->num) {
-+ contr = (contr & 0xffffff80) | 0x01;
-+ CAPIMSG_SETCONTROL(skb->data, contr);
-+ }
-+
-+ cmtp_send_capimsg(session, skb);
-+}
-+
-+static char *cmtp_procinfo(struct capi_ctr *ctrl)
-+{
-+ return "CAPI Message Transport Protocol";
-+}
-+
-+static int cmtp_ctr_read_proc(char *page, char **start, off_t off, int count, int *eof, struct capi_ctr *ctrl)
-+{
-+ struct cmtp_session *session = ctrl->driverdata;
-+ struct cmtp_application *app;
-+ struct list_head *p, *n;
-+ int len = 0;
-+
-+ len += sprintf(page + len, "%s (Revision %s)\n\n", cmtp_procinfo(ctrl), REVISION);
-+ len += sprintf(page + len, "addr %s\n", session->name);
-+ len += sprintf(page + len, "ctrl %d\n", session->num);
-+
-+ list_for_each_safe(p, n, &session->applications) {
-+ app = list_entry(p, struct cmtp_application, list);
-+ len += sprintf(page + len, "appl %d -> %d\n", app->appl, app->mapping);
-+ }
-+
-+ if (off + count >= len)
-+ *eof = 1;
-+
-+ if (len < off)
-+ return 0;
-+
-+ *start = page + off;
-+
-+ return ((count < len - off) ? count : len - off);
-+}
-+
-+static struct capi_driver cmtp_driver = {
-+ name: "cmtp",
-+ revision: REVISION,
-+ load_firmware: cmtp_load_firmware,
-+ reset_ctr: cmtp_reset_ctr,
-+ remove_ctr: cmtp_remove_ctr,
-+ register_appl: cmtp_register_appl,
-+ release_appl: cmtp_release_appl,
-+ send_message: cmtp_send_message,
-+ procinfo: cmtp_procinfo,
-+ ctr_read_proc: cmtp_ctr_read_proc,
-+
-+ driver_read_proc: 0,
-+ add_card: 0,
-+};
-+
-+
-+int cmtp_attach_device(struct cmtp_session *session)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ unsigned long timeo = CMTP_INTEROP_TIMEOUT;
-+ unsigned char buf[4];
-+
-+ BT_DBG("session %p", session);
-+
-+ capimsg_setu32(buf, 0, 0);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, CMTP_INITIAL_MSGNUM,
-+ CAPI_FUNCTION_GET_PROFILE, buf, 4);
-+
-+ add_wait_queue(&session->wait, &wait);
-+ while (timeo) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (session->ncontroller)
-+ break;
-+
-+ if (signal_pending(current))
-+ break;
-+
-+ timeo = schedule_timeout(timeo);
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&session->wait, &wait);
-+
-+ BT_INFO("Found %d CAPI controller(s) on device %s", session->ncontroller, session->name);
-+
-+ if (!timeo)
-+ return -ETIMEDOUT;
-+
-+ if (!session->ncontroller)
-+ return -ENODEV;
-+
-+
-+ if (session->ncontroller > 1)
-+ BT_INFO("Setting up only CAPI controller 1");
-+
-+ if (!(session->ctrl = di->attach_ctr(&cmtp_driver, session->name, session))) {
-+ BT_ERR("Can't attach new controller");
-+ return -EBUSY;
-+ }
-+
-+ session->num = session->ctrl->cnr;
-+
-+ BT_DBG("session %p ctrl %p num %d", session, session->ctrl, session->num);
-+
-+ capimsg_setu32(buf, 0, 1);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-+ CAPI_FUNCTION_GET_MANUFACTURER, buf, 4);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-+ CAPI_FUNCTION_GET_VERSION, buf, 4);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-+ CAPI_FUNCTION_GET_SERIAL_NUMBER, buf, 4);
-+
-+ cmtp_send_interopmsg(session, CAPI_REQ, 0xffff, cmtp_msgnum_get(session),
-+ CAPI_FUNCTION_GET_PROFILE, buf, 4);
-+
-+ return 0;
-+}
-+
-+void cmtp_detach_device(struct cmtp_session *session)
-+{
-+ struct capi_ctr *ctrl = session->ctrl;
-+
-+ BT_DBG("session %p ctrl %p", session, ctrl);
-+
-+ if (!ctrl)
-+ return;
-+
-+ ctrl->reseted(ctrl);
-+
-+ di->detach_ctr(ctrl);
-+}
-+
-+int cmtp_init_capi(void)
-+{
-+ if (!(di = attach_capi_driver(&cmtp_driver))) {
-+ BT_ERR("Can't attach CAPI driver");
-+ return -EIO;
-+ }
-+
-+ return 0;
-+}
-+
-+void cmtp_cleanup_capi(void)
-+{
-+ detach_capi_driver(&cmtp_driver);
-+}
-diff -urN linux-2.4.18/net/bluetooth/cmtp/cmtp.h linux-2.4.18-mh9/net/bluetooth/cmtp/cmtp.h
---- linux-2.4.18/net/bluetooth/cmtp/cmtp.h Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/cmtp/cmtp.h Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,138 @@
-+/*
-+ CMTP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#ifndef __CMTP_H
-+#define __CMTP_H
-+
-+#include <linux/types.h>
-+#include <net/bluetooth/bluetooth.h>
-+
-+#define BTNAMSIZ 18
-+
-+/* CMTP ioctl defines */
-+#define CMTPCONNADD _IOW('C', 200, int)
-+#define CMTPCONNDEL _IOW('C', 201, int)
-+#define CMTPGETCONNLIST _IOR('C', 210, int)
-+#define CMTPGETCONNINFO _IOR('C', 211, int)
-+
-+#define CMTP_LOOPBACK 0
-+
-+struct cmtp_connadd_req {
-+ int sock; // Connected socket
-+ __u32 flags;
-+};
-+
-+struct cmtp_conndel_req {
-+ bdaddr_t bdaddr;
-+ __u32 flags;
-+};
-+
-+struct cmtp_conninfo {
-+ bdaddr_t bdaddr;
-+ __u32 flags;
-+ __u16 state;
-+ int num;
-+};
-+
-+struct cmtp_connlist_req {
-+ __u32 cnum;
-+ struct cmtp_conninfo *ci;
-+};
-+
-+int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock);
-+int cmtp_del_connection(struct cmtp_conndel_req *req);
-+int cmtp_get_connlist(struct cmtp_connlist_req *req);
-+int cmtp_get_conninfo(struct cmtp_conninfo *ci);
-+
-+/* CMTP session defines */
-+#define CMTP_INTEROP_TIMEOUT (HZ * 5)
-+#define CMTP_INITIAL_MSGNUM 0xff00
-+
-+struct cmtp_session {
-+ struct list_head list;
-+
-+ struct socket *sock;
-+
-+ bdaddr_t bdaddr;
-+
-+ unsigned long state;
-+ unsigned long flags;
-+
-+ uint mtu;
-+
-+ char name[BTNAMSIZ];
-+
-+ atomic_t terminate;
-+
-+ wait_queue_head_t wait;
-+
-+ int ncontroller;
-+ int num;
-+ struct capi_ctr *ctrl;
-+
-+ struct list_head applications;
-+
-+ unsigned long blockids;
-+ int msgnum;
-+
-+ struct sk_buff_head transmit;
-+
-+ struct sk_buff *reassembly[16];
-+};
-+
-+struct cmtp_application {
-+ struct list_head list;
-+
-+ unsigned long state;
-+ int err;
-+
-+ __u16 appl;
-+ __u16 mapping;
-+
-+ __u16 msgnum;
-+};
-+
-+struct cmtp_scb {
-+ int id;
-+ int data;
-+};
-+
-+int cmtp_attach_device(struct cmtp_session *session);
-+void cmtp_detach_device(struct cmtp_session *session);
-+
-+void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb);
-+void cmtp_send_capimsg(struct cmtp_session *session, struct sk_buff *skb);
-+
-+static inline void cmtp_schedule(struct cmtp_session *session)
-+{
-+ struct sock *sk = session->sock->sk;
-+
-+ wake_up_interruptible(sk->sleep);
-+}
-+
-+/* CMTP init defines */
-+int cmtp_init_capi(void);
-+int cmtp_init_sockets(void);
-+void cmtp_cleanup_capi(void);
-+void cmtp_cleanup_sockets(void);
-+
-+#endif /* __CMTP_H */
-diff -urN linux-2.4.18/net/bluetooth/cmtp/core.c linux-2.4.18-mh9/net/bluetooth/cmtp/core.c
---- linux-2.4.18/net/bluetooth/cmtp/core.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/cmtp/core.c Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,515 @@
-+/*
-+ CMTP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <linux/init.h>
-+#include <net/sock.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#include "cmtp.h"
-+
-+#ifndef CONFIG_BLUEZ_CMTP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define VERSION "1.0"
-+
-+static DECLARE_RWSEM(cmtp_session_sem);
-+static LIST_HEAD(cmtp_session_list);
-+
-+static struct cmtp_session *__cmtp_get_session(bdaddr_t *bdaddr)
-+{
-+ struct cmtp_session *session;
-+ struct list_head *p;
-+
-+ BT_DBG("");
-+
-+ list_for_each(p, &cmtp_session_list) {
-+ session = list_entry(p, struct cmtp_session, list);
-+ if (!bacmp(bdaddr, &session->bdaddr))
-+ return session;
-+ }
-+ return NULL;
-+}
-+
-+static void __cmtp_link_session(struct cmtp_session *session)
-+{
-+ MOD_INC_USE_COUNT;
-+ list_add(&session->list, &cmtp_session_list);
-+}
-+
-+static void __cmtp_unlink_session(struct cmtp_session *session)
-+{
-+ list_del(&session->list);
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void __cmtp_copy_session(struct cmtp_session *session, struct cmtp_conninfo *ci)
-+{
-+ bacpy(&ci->bdaddr, &session->bdaddr);
-+
-+ ci->flags = session->flags;
-+ ci->state = session->state;
-+
-+ ci->num = session->num;
-+}
-+
-+
-+static inline int cmtp_alloc_block_id(struct cmtp_session *session)
-+{
-+ int i, id = -1;
-+
-+ for (i = 0; i < 16; i++)
-+ if (!test_and_set_bit(i, &session->blockids)) {
-+ id = i;
-+ break;
-+ }
-+
-+ return id;
-+}
-+
-+static inline void cmtp_free_block_id(struct cmtp_session *session, int id)
-+{
-+ clear_bit(id, &session->blockids);
-+}
-+
-+static inline void cmtp_add_msgpart(struct cmtp_session *session, int id, const unsigned char *buf, int count)
-+{
-+ struct sk_buff *skb = session->reassembly[id], *nskb;
-+ int size;
-+
-+ BT_DBG("session %p buf %p count %d", session, buf, count);
-+
-+ size = (skb) ? skb->len + count : count;
-+
-+ if (!(nskb = alloc_skb(size, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for CAPI message");
-+ return;
-+ }
-+
-+ if (skb && (skb->len > 0))
-+ memcpy(skb_put(nskb, skb->len), skb->data, skb->len);
-+
-+ memcpy(skb_put(nskb, count), buf, count);
-+
-+ session->reassembly[id] = nskb;
-+
-+ if (skb)
-+ kfree_skb(skb);
-+}
-+
-+static inline int cmtp_recv_frame(struct cmtp_session *session, struct sk_buff *skb)
-+{
-+ __u8 hdr, hdrlen, id;
-+ __u16 len;
-+
-+ BT_DBG("session %p skb %p len %d", session, skb, skb->len);
-+
-+ while (skb->len > 0) {
-+ hdr = skb->data[0];
-+
-+ switch (hdr & 0xc0) {
-+ case 0x40:
-+ hdrlen = 2;
-+ len = skb->data[1];
-+ break;
-+ case 0x80:
-+ hdrlen = 3;
-+ len = skb->data[1] | (skb->data[2] << 8);
-+ break;
-+ default:
-+ hdrlen = 1;
-+ len = 0;
-+ break;
-+ }
-+
-+ id = (hdr & 0x3c) >> 2;
-+
-+ BT_DBG("hdr 0x%02x hdrlen %d len %d id %d", hdr, hdrlen, len, id);
-+
-+ if (hdrlen + len > skb->len) {
-+ BT_ERR("Wrong size or header information in CMTP frame");
-+ break;
-+ }
-+
-+ if (len == 0) {
-+ skb_pull(skb, hdrlen);
-+ continue;
-+ }
-+
-+ switch (hdr & 0x03) {
-+ case 0x00:
-+ cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
-+ cmtp_recv_capimsg(session, session->reassembly[id]);
-+ session->reassembly[id] = NULL;
-+ break;
-+ case 0x01:
-+ cmtp_add_msgpart(session, id, skb->data + hdrlen, len);
-+ break;
-+ default:
-+ if (session->reassembly[id] != NULL)
-+ kfree_skb(session->reassembly[id]);
-+ session->reassembly[id] = NULL;
-+ break;
-+ }
-+
-+ skb_pull(skb, hdrlen + len);
-+ }
-+
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+static int cmtp_send_frame(struct cmtp_session *session, unsigned char *data, int len)
-+{
-+ struct socket *sock = session->sock;
-+ struct iovec iv = { data, len };
-+ struct msghdr msg;
-+ int err;
-+
-+ BT_DBG("session %p data %p len %d", session, data, len);
-+
-+ if (!len)
-+ return 0;
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_iovlen = 1;
-+ msg.msg_iov = &iv;
-+
-+ err = sock->ops->sendmsg(sock, &msg, len, 0);
-+ return err;
-+}
-+
-+static int cmtp_process_transmit(struct cmtp_session *session)
-+{
-+ struct sk_buff *skb, *nskb;
-+ unsigned char *hdr;
-+ unsigned int size, tail;
-+
-+ BT_DBG("session %p", session);
-+
-+ if (!(nskb = alloc_skb(session->mtu, GFP_ATOMIC))) {
-+ BT_ERR("Can't allocate memory for new frame");
-+ return -ENOMEM;
-+ }
-+
-+ while ((skb = skb_dequeue(&session->transmit))) {
-+ struct cmtp_scb *scb = (void *) skb->cb;
-+
-+ if ((tail = (session->mtu - nskb->len)) < 5) {
-+ cmtp_send_frame(session, nskb->data, nskb->len);
-+ skb_trim(nskb, 0);
-+ tail = session->mtu;
-+ }
-+
-+ size = min_t(uint, ((tail < 258) ? (tail - 2) : (tail - 3)), skb->len);
-+
-+ if ((scb->id < 0) && ((scb->id = cmtp_alloc_block_id(session)) < 0)) {
-+ skb_queue_head(&session->transmit, skb);
-+ break;
-+ }
-+
-+ if (size < 256) {
-+ hdr = skb_put(nskb, 2);
-+ hdr[0] = 0x40
-+ | ((scb->id << 2) & 0x3c)
-+ | ((skb->len == size) ? 0x00 : 0x01);
-+ hdr[1] = size;
-+ } else {
-+ hdr = skb_put(nskb, 3);
-+ hdr[0] = 0x80
-+ | ((scb->id << 2) & 0x3c)
-+ | ((skb->len == size) ? 0x00 : 0x01);
-+ hdr[1] = size & 0xff;
-+ hdr[2] = size >> 8;
-+ }
-+
-+ memcpy(skb_put(nskb, size), skb->data, size);
-+ skb_pull(skb, size);
-+
-+ if (skb->len > 0) {
-+ skb_queue_head(&session->transmit, skb);
-+ } else {
-+ cmtp_free_block_id(session, scb->id);
-+ if (scb->data) {
-+ cmtp_send_frame(session, nskb->data, nskb->len);
-+ skb_trim(nskb, 0);
-+ }
-+ kfree_skb(skb);
-+ }
-+ }
-+
-+ cmtp_send_frame(session, nskb->data, nskb->len);
-+
-+ kfree_skb(nskb);
-+
-+ return skb_queue_len(&session->transmit);
-+}
-+
-+static int cmtp_session(void *arg)
-+{
-+ struct cmtp_session *session = arg;
-+ struct sock *sk = session->sock->sk;
-+ struct sk_buff *skb;
-+ wait_queue_t wait;
-+
-+ BT_DBG("session %p", session);
-+
-+ daemonize(); reparent_to_init();
-+
-+ sprintf(current->comm, "kcmtpd_ctr_%d", session->num);
-+
-+ sigfillset(&current->blocked);
-+ flush_signals(current);
-+
-+ current->nice = -15;
-+
-+ set_fs(KERNEL_DS);
-+
-+ init_waitqueue_entry(&wait, current);
-+ add_wait_queue(sk->sleep, &wait);
-+ while (!atomic_read(&session->terminate)) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (sk->state != BT_CONNECTED)
-+ break;
-+
-+ while ((skb = skb_dequeue(&sk->receive_queue))) {
-+ skb_orphan(skb);
-+ cmtp_recv_frame(session, skb);
-+ }
-+
-+ cmtp_process_transmit(session);
-+
-+ schedule();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ down_write(&cmtp_session_sem);
-+
-+ if (!(session->flags & (1 << CMTP_LOOPBACK)))
-+ cmtp_detach_device(session);
-+
-+ fput(session->sock->file);
-+
-+ __cmtp_unlink_session(session);
-+
-+ up_write(&cmtp_session_sem);
-+
-+ kfree(session);
-+ return 0;
-+}
-+
-+int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
-+{
-+ struct cmtp_session *session, *s;
-+ bdaddr_t src, dst;
-+ int i, err;
-+
-+ BT_DBG("");
-+
-+ baswap(&src, &bluez_pi(sock->sk)->src);
-+ baswap(&dst, &bluez_pi(sock->sk)->dst);
-+
-+ session = kmalloc(sizeof(struct cmtp_session), GFP_KERNEL);
-+ if (!session)
-+ return -ENOMEM;
-+ memset(session, 0, sizeof(struct cmtp_session));
-+
-+ down_write(&cmtp_session_sem);
-+
-+ s = __cmtp_get_session(&bluez_pi(sock->sk)->dst);
-+ if (s && s->state == BT_CONNECTED) {
-+ err = -EEXIST;
-+ goto failed;
-+ }
-+
-+ bacpy(&session->bdaddr, &bluez_pi(sock->sk)->dst);
-+
-+ session->mtu = min_t(uint, l2cap_pi(sock->sk)->omtu, l2cap_pi(sock->sk)->imtu);
-+
-+ BT_DBG("mtu %d", session->mtu);
-+
-+ sprintf(session->name, "%s", batostr(&dst));
-+
-+ session->sock = sock;
-+ session->state = BT_CONFIG;
-+
-+ init_waitqueue_head(&session->wait);
-+
-+ session->ctrl = NULL;
-+ session->msgnum = CMTP_INITIAL_MSGNUM;
-+
-+ INIT_LIST_HEAD(&session->applications);
-+
-+ skb_queue_head_init(&session->transmit);
-+
-+ for (i = 0; i < 16; i++)
-+ session->reassembly[i] = NULL;
-+
-+ session->flags = req->flags;
-+
-+ __cmtp_link_session(session);
-+
-+ err = kernel_thread(cmtp_session, session, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-+ if (err < 0)
-+ goto unlink;
-+
-+ if (!(session->flags & (1 << CMTP_LOOPBACK))) {
-+ err = cmtp_attach_device(session);
-+ if (err < 0)
-+ goto detach;
-+ }
-+
-+ up_write(&cmtp_session_sem);
-+ return 0;
-+
-+detach:
-+ cmtp_detach_device(session);
-+
-+unlink:
-+ __cmtp_unlink_session(session);
-+
-+failed:
-+ up_write(&cmtp_session_sem);
-+ kfree(session);
-+ return err;
-+}
-+
-+int cmtp_del_connection(struct cmtp_conndel_req *req)
-+{
-+ struct cmtp_session *session;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ down_read(&cmtp_session_sem);
-+
-+ session = __cmtp_get_session(&req->bdaddr);
-+ if (session) {
-+ /* Flush the transmit queue */
-+ skb_queue_purge(&session->transmit);
-+
-+ /* Kill session thread */
-+ atomic_inc(&session->terminate);
-+ cmtp_schedule(session);
-+ } else
-+ err = -ENOENT;
-+
-+ up_read(&cmtp_session_sem);
-+ return err;
-+}
-+
-+int cmtp_get_connlist(struct cmtp_connlist_req *req)
-+{
-+ struct list_head *p;
-+ int err = 0, n = 0;
-+
-+ BT_DBG("");
-+
-+ down_read(&cmtp_session_sem);
-+
-+ list_for_each(p, &cmtp_session_list) {
-+ struct cmtp_session *session;
-+ struct cmtp_conninfo ci;
-+
-+ session = list_entry(p, struct cmtp_session, list);
-+
-+ __cmtp_copy_session(session, &ci);
-+
-+ if (copy_to_user(req->ci, &ci, sizeof(ci))) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ if (++n >= req->cnum)
-+ break;
-+
-+ req->ci++;
-+ }
-+ req->cnum = n;
-+
-+ up_read(&cmtp_session_sem);
-+ return err;
-+}
-+
-+int cmtp_get_conninfo(struct cmtp_conninfo *ci)
-+{
-+ struct cmtp_session *session;
-+ int err = 0;
-+
-+ down_read(&cmtp_session_sem);
-+
-+ session = __cmtp_get_session(&ci->bdaddr);
-+ if (session)
-+ __cmtp_copy_session(session, ci);
-+ else
-+ err = -ENOENT;
-+
-+ up_read(&cmtp_session_sem);
-+ return err;
-+}
-+
-+
-+int __init init_cmtp(void)
-+{
-+ l2cap_load();
-+
-+ cmtp_init_capi();
-+ cmtp_init_sockets();
-+
-+ BT_INFO("BlueZ CMTP ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>");
-+
-+ return 0;
-+}
-+
-+void __exit exit_cmtp(void)
-+{
-+ cmtp_cleanup_sockets();
-+ cmtp_cleanup_capi();
-+}
-+
-+module_init(init_cmtp);
-+module_exit(exit_cmtp);
-+
-+MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ CMTP ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/cmtp/sock.c linux-2.4.18-mh9/net/bluetooth/cmtp/sock.c
---- linux-2.4.18/net/bluetooth/cmtp/sock.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/cmtp/sock.c Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,236 @@
-+/*
-+ CMTP implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002-2003 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/skbuff.h>
-+#include <linux/socket.h>
-+#include <linux/ioctl.h>
-+#include <linux/file.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include "cmtp.h"
-+
-+#ifndef CONFIG_BLUEZ_CMTP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+static inline struct socket *socki_lookup(struct inode *inode)
-+{
-+ return &inode->u.socket_i;
-+}
-+
-+static struct socket *sockfd_lookup(int fd, int *err)
-+{
-+ struct file *file;
-+ struct inode *inode;
-+ struct socket *sock;
-+
-+ if (!(file = fget(fd))) {
-+ *err = -EBADF;
-+ return NULL;
-+ }
-+
-+ inode = file->f_dentry->d_inode;
-+ if (!inode->i_sock || !(sock = socki_lookup(inode))) {
-+ *err = -ENOTSOCK;
-+ fput(file);
-+ return NULL;
-+ }
-+
-+ if (sock->file != file) {
-+ printk(KERN_ERR "socki_lookup: socket file changed!\n");
-+ sock->file = file;
-+ }
-+ return sock;
-+}
-+
-+static int cmtp_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ sock_orphan(sk);
-+ sock_put(sk);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+static int cmtp_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct cmtp_connadd_req ca;
-+ struct cmtp_conndel_req cd;
-+ struct cmtp_connlist_req cl;
-+ struct cmtp_conninfo ci;
-+ struct socket *nsock;
-+ int err;
-+
-+ BT_DBG("cmd %x arg %lx", cmd, arg);
-+
-+ switch (cmd) {
-+ case CMTPCONNADD:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&ca, (void *) arg, sizeof(ca)))
-+ return -EFAULT;
-+
-+ nsock = sockfd_lookup(ca.sock, &err);
-+ if (!nsock)
-+ return err;
-+
-+ if (nsock->sk->state != BT_CONNECTED)
-+ return -EBADFD;
-+
-+ err = cmtp_add_connection(&ca, nsock);
-+ if (!err) {
-+ if (copy_to_user((void *) arg, &ca, sizeof(ca)))
-+ err = -EFAULT;
-+ } else
-+ fput(nsock->file);
-+
-+ return err;
-+
-+ case CMTPCONNDEL:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-+
-+ if (copy_from_user(&cd, (void *) arg, sizeof(cd)))
-+ return -EFAULT;
-+
-+ return cmtp_del_connection(&cd);
-+
-+ case CMTPGETCONNLIST:
-+ if (copy_from_user(&cl, (void *) arg, sizeof(cl)))
-+ return -EFAULT;
-+
-+ if (cl.cnum <= 0)
-+ return -EINVAL;
-+
-+ err = cmtp_get_connlist(&cl);
-+ if (!err && copy_to_user((void *) arg, &cl, sizeof(cl)))
-+ return -EFAULT;
-+
-+ return err;
-+
-+ case CMTPGETCONNINFO:
-+ if (copy_from_user(&ci, (void *) arg, sizeof(ci)))
-+ return -EFAULT;
-+
-+ err = cmtp_get_conninfo(&ci);
-+ if (!err && copy_to_user((void *) arg, &ci, sizeof(ci)))
-+ return -EFAULT;
-+
-+ return err;
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+static struct proto_ops cmtp_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: cmtp_sock_release,
-+ ioctl: cmtp_sock_ioctl,
-+ bind: sock_no_bind,
-+ getname: sock_no_getname,
-+ sendmsg: sock_no_sendmsg,
-+ recvmsg: sock_no_recvmsg,
-+ poll: sock_no_poll,
-+ listen: sock_no_listen,
-+ shutdown: sock_no_shutdown,
-+ setsockopt: sock_no_setsockopt,
-+ getsockopt: sock_no_getsockopt,
-+ connect: sock_no_connect,
-+ socketpair: sock_no_socketpair,
-+ accept: sock_no_accept,
-+ mmap: sock_no_mmap
-+};
-+
-+static int cmtp_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ if (sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &cmtp_sock_ops;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, GFP_KERNEL, 1)))
-+ return -ENOMEM;
-+
-+ MOD_INC_USE_COUNT;
-+
-+ sock->state = SS_UNCONNECTED;
-+ sock_init_data(sock, sk);
-+
-+ sk->destruct = NULL;
-+ sk->protocol = protocol;
-+
-+ return 0;
-+}
-+
-+static struct net_proto_family cmtp_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: cmtp_sock_create
-+};
-+
-+int cmtp_init_sockets(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_CMTP, &cmtp_sock_family_ops))) {
-+ BT_ERR("Can't register CMTP socket layer (%d)", err);
-+ return err;
-+ }
-+
-+ return 0;
-+}
-+
-+void cmtp_cleanup_sockets(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_unregister(BTPROTO_CMTP)))
-+ BT_ERR("Can't unregister CMTP socket layer (%d)", err);
-+
-+ return;
-+}
-diff -urN linux-2.4.18/net/bluetooth/hci_conn.c linux-2.4.18-mh9/net/bluetooth/hci_conn.c
---- linux-2.4.18/net/bluetooth/hci_conn.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/hci_conn.c Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,441 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * HCI Connection handling.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/notifier.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+#ifndef HCI_CORE_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+void hci_acl_connect(struct hci_conn *conn)
-+{
-+ struct hci_dev *hdev = conn->hdev;
-+ struct inquiry_entry *ie;
-+ create_conn_cp cp;
-+
-+ BT_DBG("%p", conn);
-+
-+ conn->state = BT_CONNECT;
-+ conn->out = 1;
-+ conn->link_mode = HCI_LM_MASTER;
-+
-+ memset(&cp, 0, sizeof(cp));
-+ bacpy(&cp.bdaddr, &conn->dst);
-+ cp.pscan_rep_mode = 0x01;
-+
-+ if ((ie = inquiry_cache_lookup(hdev, &conn->dst)) &&
-+ inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
-+ cp.pscan_rep_mode = ie->info.pscan_rep_mode;
-+ cp.pscan_mode = ie->info.pscan_mode;
-+ cp.clock_offset = ie->info.clock_offset | __cpu_to_le16(0x8000);
-+ }
-+
-+ cp.pkt_type = __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK);
-+ if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
-+ cp.role_switch = 0x01;
-+ else
-+ cp.role_switch = 0x00;
-+
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN,
-+ CREATE_CONN_CP_SIZE, &cp);
-+}
-+
-+void hci_acl_disconn(struct hci_conn *conn, __u8 reason)
-+{
-+ disconnect_cp cp;
-+
-+ BT_DBG("%p", conn);
-+
-+ conn->state = BT_DISCONN;
-+
-+ cp.handle = __cpu_to_le16(conn->handle);
-+ cp.reason = reason;
-+ hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT,
-+ DISCONNECT_CP_SIZE, &cp);
-+}
-+
-+void hci_add_sco(struct hci_conn *conn, __u16 handle)
-+{
-+ struct hci_dev *hdev = conn->hdev;
-+ add_sco_cp cp;
-+
-+ BT_DBG("%p", conn);
-+
-+ conn->state = BT_CONNECT;
-+ conn->out = 1;
-+
-+ cp.pkt_type = __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
-+ cp.handle = __cpu_to_le16(handle);
-+
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ADD_SCO, ADD_SCO_CP_SIZE, &cp);
-+}
-+
-+static void hci_conn_timeout(unsigned long arg)
-+{
-+ struct hci_conn *conn = (void *)arg;
-+ struct hci_dev *hdev = conn->hdev;
-+
-+ BT_DBG("conn %p state %d", conn, conn->state);
-+
-+ if (atomic_read(&conn->refcnt))
-+ return;
-+
-+ hci_dev_lock(hdev);
-+ if (conn->state == BT_CONNECTED)
-+ hci_acl_disconn(conn, 0x13);
-+ else
-+ conn->state = BT_CLOSED;
-+ hci_dev_unlock(hdev);
-+ return;
-+}
-+
-+static void hci_conn_init_timer(struct hci_conn *conn)
-+{
-+ init_timer(&conn->timer);
-+ conn->timer.function = hci_conn_timeout;
-+ conn->timer.data = (unsigned long)conn;
-+}
-+
-+struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
-+{
-+ struct hci_conn *conn;
-+
-+ BT_DBG("%s dst %s", hdev->name, batostr(dst));
-+
-+ if (!(conn = kmalloc(sizeof(struct hci_conn), GFP_ATOMIC)))
-+ return NULL;
-+ memset(conn, 0, sizeof(struct hci_conn));
-+
-+ bacpy(&conn->dst, dst);
-+ conn->type = type;
-+ conn->hdev = hdev;
-+ conn->state = BT_OPEN;
-+
-+ skb_queue_head_init(&conn->data_q);
-+ hci_conn_init_timer(conn);
-+
-+ atomic_set(&conn->refcnt, 0);
-+
-+ hci_dev_hold(hdev);
-+
-+ if (hdev->notify)
-+ hdev->notify(hdev, HCI_NOTIFY_CONN_ADD, (unsigned long) conn);
-+
-+ tasklet_disable(&hdev->tx_task);
-+ conn_hash_add(hdev, conn);
-+ tasklet_enable(&hdev->tx_task);
-+
-+ return conn;
-+}
-+
-+int hci_conn_del(struct hci_conn *conn)
-+{
-+ struct hci_dev *hdev = conn->hdev;
-+
-+ BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
-+
-+ hci_conn_del_timer(conn);
-+
-+ if (conn->type == SCO_LINK) {
-+ struct hci_conn *acl = conn->link;
-+ if (acl) {
-+ acl->link = NULL;
-+ hci_conn_put(acl);
-+ }
-+ } else {
-+ struct hci_conn *sco = conn->link;
-+ if (sco)
-+ sco->link = NULL;
-+
-+ /* Unacked frames */
-+ hdev->acl_cnt += conn->sent;
-+ }
-+
-+ tasklet_disable(&hdev->tx_task);
-+ conn_hash_del(hdev, conn);
-+ tasklet_enable(&hdev->tx_task);
-+
-+ skb_queue_purge(&conn->data_q);
-+
-+ if (hdev->notify)
-+ hdev->notify(hdev, HCI_NOTIFY_CONN_DEL, (unsigned long) conn);
-+
-+ hci_dev_put(hdev);
-+
-+ kfree(conn);
-+ return 0;
-+}
-+
-+struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
-+{
-+ int use_src = bacmp(src, BDADDR_ANY);
-+ struct hci_dev *hdev = NULL;
-+ struct list_head *p;
-+
-+ BT_DBG("%s -> %s", batostr(src), batostr(dst));
-+
-+ read_lock_bh(&hdev_list_lock);
-+
-+ list_for_each(p, &hdev_list) {
-+ struct hci_dev *d;
-+ d = list_entry(p, struct hci_dev, list);
-+
-+ if (!test_bit(HCI_UP, &d->flags))
-+ continue;
-+
-+ /* Simple routing:
-+ * No source address - find interface with bdaddr != dst
-+ * Source address - find interface with bdaddr == src
-+ */
-+
-+ if (use_src) {
-+ if (!bacmp(&d->bdaddr, src)) {
-+ hdev = d; break;
-+ }
-+ } else {
-+ if (bacmp(&d->bdaddr, dst)) {
-+ hdev = d; break;
-+ }
-+ }
-+ }
-+
-+ if (hdev)
-+ hci_dev_hold(hdev);
-+
-+ read_unlock_bh(&hdev_list_lock);
-+ return hdev;
-+}
-+
-+/* Create SCO or ACL connection.
-+ * Device _must_ be locked */
-+struct hci_conn * hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
-+{
-+ struct hci_conn *acl;
-+
-+ BT_DBG("%s dst %s", hdev->name, batostr(dst));
-+
-+ if (!(acl = conn_hash_lookup_ba(hdev, ACL_LINK, dst))) {
-+ if (!(acl = hci_conn_add(hdev, ACL_LINK, dst)))
-+ return NULL;
-+ }
-+
-+ hci_conn_hold(acl);
-+
-+ if (acl->state == BT_OPEN || acl->state == BT_CLOSED)
-+ hci_acl_connect(acl);
-+
-+ if (type == SCO_LINK) {
-+ struct hci_conn *sco;
-+
-+ if (!(sco = conn_hash_lookup_ba(hdev, SCO_LINK, dst))) {
-+ if (!(sco = hci_conn_add(hdev, SCO_LINK, dst))) {
-+ hci_conn_put(acl);
-+ return NULL;
-+ }
-+ }
-+ acl->link = sco;
-+ sco->link = acl;
-+
-+ hci_conn_hold(sco);
-+
-+ if (acl->state == BT_CONNECTED &&
-+ (sco->state == BT_OPEN || sco->state == BT_CLOSED))
-+ hci_add_sco(sco, acl->handle);
-+
-+ return sco;
-+ } else {
-+ return acl;
-+ }
-+}
-+
-+/* Authenticate remote device */
-+int hci_conn_auth(struct hci_conn *conn)
-+{
-+ BT_DBG("conn %p", conn);
-+
-+ if (conn->link_mode & HCI_LM_AUTH)
-+ return 1;
-+
-+ if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
-+ auth_requested_cp ar;
-+ ar.handle = __cpu_to_le16(conn->handle);
-+ hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_AUTH_REQUESTED,
-+ AUTH_REQUESTED_CP_SIZE, &ar);
-+ }
-+ return 0;
-+}
-+
-+/* Enable encryption */
-+int hci_conn_encrypt(struct hci_conn *conn)
-+{
-+ BT_DBG("conn %p", conn);
-+
-+ if (conn->link_mode & HCI_LM_ENCRYPT)
-+ return 1;
-+
-+ if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
-+ return 0;
-+
-+ if (hci_conn_auth(conn)) {
-+ set_conn_encrypt_cp ce;
-+ ce.handle = __cpu_to_le16(conn->handle);
-+ ce.encrypt = 1;
-+ hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT,
-+ SET_CONN_ENCRYPT_CP_SIZE, &ce);
-+ }
-+ return 0;
-+}
-+
-+/* Drop all connection on the device */
-+void hci_conn_hash_flush(struct hci_dev *hdev)
-+{
-+ struct conn_hash *h = &hdev->conn_hash;
-+ struct list_head *p;
-+
-+ BT_DBG("hdev %s", hdev->name);
-+
-+ p = h->list.next;
-+ while (p != &h->list) {
-+ struct hci_conn *c;
-+
-+ c = list_entry(p, struct hci_conn, list);
-+ p = p->next;
-+
-+ c->state = BT_CLOSED;
-+
-+ hci_proto_disconn_ind(c, 0x16);
-+ hci_conn_del(c);
-+ }
-+}
-+
-+int hci_get_conn_list(unsigned long arg)
-+{
-+ struct hci_conn_list_req req, *cl;
-+ struct hci_conn_info *ci;
-+ struct hci_dev *hdev;
-+ struct list_head *p;
-+ int n = 0, size;
-+
-+ if (copy_from_user(&req, (void *) arg, sizeof(req)))
-+ return -EFAULT;
-+
-+ if (!(hdev = hci_dev_get(req.dev_id)))
-+ return -ENODEV;
-+
-+ size = req.conn_num * sizeof(struct hci_conn_info) + sizeof(req);
-+
-+ if (verify_area(VERIFY_WRITE, (void *)arg, size))
-+ return -EFAULT;
-+
-+ if (!(cl = (void *) kmalloc(size, GFP_KERNEL)))
-+ return -ENOMEM;
-+ ci = cl->conn_info;
-+
-+ hci_dev_lock_bh(hdev);
-+ list_for_each(p, &hdev->conn_hash.list) {
-+ register struct hci_conn *c;
-+ c = list_entry(p, struct hci_conn, list);
-+
-+ bacpy(&(ci + n)->bdaddr, &c->dst);
-+ (ci + n)->handle = c->handle;
-+ (ci + n)->type = c->type;
-+ (ci + n)->out = c->out;
-+ (ci + n)->state = c->state;
-+ (ci + n)->link_mode = c->link_mode;
-+ n++;
-+ }
-+ hci_dev_unlock_bh(hdev);
-+
-+ cl->dev_id = hdev->id;
-+ cl->conn_num = n;
-+ size = n * sizeof(struct hci_conn_info) + sizeof(req);
-+
-+ hci_dev_put(hdev);
-+
-+ copy_to_user((void *) arg, cl, size);
-+ kfree(cl);
-+
-+ return 0;
-+}
-+
-+int hci_get_conn_info(struct hci_dev *hdev, unsigned long arg)
-+{
-+ struct hci_conn_info_req req;
-+ struct hci_conn_info ci;
-+ struct hci_conn *conn;
-+ char *ptr = (void *) arg + sizeof(req);
-+
-+ if (copy_from_user(&req, (void *) arg, sizeof(req)))
-+ return -EFAULT;
-+
-+ if (verify_area(VERIFY_WRITE, ptr, sizeof(ci)))
-+ return -EFAULT;
-+
-+ hci_dev_lock_bh(hdev);
-+ conn = conn_hash_lookup_ba(hdev, req.type, &req.bdaddr);
-+ if (conn) {
-+ bacpy(&ci.bdaddr, &conn->dst);
-+ ci.handle = conn->handle;
-+ ci.type = conn->type;
-+ ci.out = conn->out;
-+ ci.state = conn->state;
-+ ci.link_mode = conn->link_mode;
-+ }
-+ hci_dev_unlock_bh(hdev);
-+
-+ if (!conn)
-+ return -ENOENT;
-+
-+ copy_to_user(ptr, &ci, sizeof(ci));
-+ return 0;
-+}
-diff -urN linux-2.4.18/net/bluetooth/hci_core.c linux-2.4.18-mh9/net/bluetooth/hci_core.c
---- linux-2.4.18/net/bluetooth/hci_core.c Fri Nov 9 23:21:21 2001
-+++ linux-2.4.18-mh9/net/bluetooth/hci_core.c Mon Aug 25 18:38:12 2003
-@@ -25,11 +25,12 @@
- /*
- * BlueZ HCI Core.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
- #include <linux/module.h>
-+#include <linux/kmod.h>
-
- #include <linux/types.h>
- #include <linux/errno.h>
-@@ -50,12 +51,11 @@
- #include <asm/unaligned.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
-
- #ifndef HCI_CORE_DEBUG
--#undef DBG
--#define DBG( A... )
-+#undef BT_DBG
-+#define BT_DBG( A... )
- #endif
-
- static void hci_cmd_task(unsigned long arg);
-@@ -63,279 +63,69 @@
- static void hci_tx_task(unsigned long arg);
- static void hci_notify(struct hci_dev *hdev, int event);
-
--static rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
-+rwlock_t hci_task_lock = RW_LOCK_UNLOCKED;
-
- /* HCI device list */
--struct hci_dev *hdev_list[HCI_MAX_DEV];
--spinlock_t hdev_list_lock;
--#define GET_HDEV(a) (hdev_list[a])
--
--/* HCI protocol list */
--struct hci_proto *hproto_list[HCI_MAX_PROTO];
--#define GET_HPROTO(a) (hproto_list[a])
-+LIST_HEAD(hdev_list);
-+rwlock_t hdev_list_lock = RW_LOCK_UNLOCKED;
-
--/* HCI notifiers list */
--struct notifier_block *hci_dev_notifier;
--
--/* HCI device notifications */
--int hci_register_notifier(struct notifier_block *nb)
--{
-- int err, i;
-- struct hci_dev *hdev;
--
-- if ((err = notifier_chain_register(&hci_dev_notifier, nb)))
-- return err;
--
-- /* Notify about already registered devices */
-- spin_lock(&hdev_list_lock);
-- for (i = 0; i < HCI_MAX_DEV; i++) {
-- if (!(hdev = GET_HDEV(i)))
-- continue;
-- if (hdev->flags & HCI_UP)
-- (*nb->notifier_call)(nb, HCI_DEV_UP, hdev);
-- }
-- spin_unlock(&hdev_list_lock);
--
-- return 0;
--}
--
--int hci_unregister_notifier(struct notifier_block *nb)
--{
-- return notifier_chain_unregister(&hci_dev_notifier, nb);
--}
--
--static inline void hci_notify(struct hci_dev *hdev, int event)
--{
-- notifier_call_chain(&hci_dev_notifier, event, hdev);
--}
--
--/* Get HCI device by index (device is locked on return)*/
--struct hci_dev *hci_dev_get(int index)
--{
-- struct hci_dev *hdev;
-- DBG("%d", index);
--
-- if (index < 0 || index >= HCI_MAX_DEV)
-- return NULL;
--
-- spin_lock(&hdev_list_lock);
-- if ((hdev = GET_HDEV(index)))
-- hci_dev_hold(hdev);
-- spin_unlock(&hdev_list_lock);
--
-- return hdev;
--}
--
--/* Flush inquiry cache */
--void inquiry_cache_flush(struct inquiry_cache *cache)
--{
-- struct inquiry_entry *next = cache->list, *e;
--
-- DBG("cache %p", cache);
--
-- cache->list = NULL;
-- while ((e = next)) {
-- next = e->next;
-- kfree(e);
-- }
--}
--
--/* Lookup by bdaddr.
-- * Cache must be locked. */
--static struct inquiry_entry * __inquiry_cache_lookup(struct inquiry_cache *cache, bdaddr_t *bdaddr)
--{
-- struct inquiry_entry *e;
--
-- DBG("cache %p, %s", cache, batostr(bdaddr));
--
-- for (e = cache->list; e; e = e->next)
-- if (!bacmp(&e->info.bdaddr, bdaddr))
-- break;
--
-- return e;
--}
--
--static void inquiry_cache_update(struct inquiry_cache *cache, inquiry_info *info)
--{
-- struct inquiry_entry *e;
--
-- DBG("cache %p, %s", cache, batostr(&info->bdaddr));
--
-- inquiry_cache_lock(cache);
--
-- if (!(e = __inquiry_cache_lookup(cache, &info->bdaddr))) {
-- /* Entry not in the cache. Add new one. */
-- if (!(e = kmalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
-- goto unlock;
-- memset(e, 0, sizeof(struct inquiry_entry));
-- e->next = cache->list;
-- cache->list = e;
-- }
--
-- memcpy(&e->info, info, sizeof(inquiry_info));
-- e->timestamp = jiffies;
-- cache->timestamp = jiffies;
--unlock:
-- inquiry_cache_unlock(cache);
--}
--
--static int inquiry_cache_dump(struct inquiry_cache *cache, int num, __u8 *buf)
--{
-- inquiry_info *info = (inquiry_info *) buf;
-- struct inquiry_entry *e;
-- int copied = 0;
-+/* HCI protocols */
-+#define HCI_MAX_PROTO 2
-+struct hci_proto *hci_proto[HCI_MAX_PROTO];
-
-- inquiry_cache_lock(cache);
--
-- for (e = cache->list; e && copied < num; e = e->next, copied++)
-- memcpy(info++, &e->info, sizeof(inquiry_info));
-+/* HCI notifiers list */
-+static struct notifier_block *hci_notifier;
-
-- inquiry_cache_unlock(cache);
-
-- DBG("cache %p, copied %d", cache, copied);
-- return copied;
--}
-+/* ---- HCI notifications ---- */
-
--/* --------- BaseBand connections --------- */
--static struct hci_conn *hci_conn_add(struct hci_dev *hdev, __u16 handle, __u8 type, bdaddr_t *dst)
-+int hci_register_notifier(struct notifier_block *nb)
- {
-- struct hci_conn *conn;
--
-- DBG("%s handle %d dst %s", hdev->name, handle, batostr(dst));
--
-- if ( conn_hash_lookup(&hdev->conn_hash, handle)) {
-- ERR("%s handle 0x%x already exists", hdev->name, handle);
-- return NULL;
-- }
--
-- if (!(conn = kmalloc(sizeof(struct hci_conn), GFP_ATOMIC)))
-- return NULL;
-- memset(conn, 0, sizeof(struct hci_conn));
--
-- bacpy(&conn->dst, dst);
-- conn->handle = handle;
-- conn->type = type;
-- conn->hdev = hdev;
--
-- skb_queue_head_init(&conn->data_q);
--
-- hci_dev_hold(hdev);
-- conn_hash_add(&hdev->conn_hash, handle, conn);
--
-- return conn;
-+ return notifier_chain_register(&hci_notifier, nb);
- }
-
--static int hci_conn_del(struct hci_dev *hdev, struct hci_conn *conn)
-+int hci_unregister_notifier(struct notifier_block *nb)
- {
-- DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
--
-- conn_hash_del(&hdev->conn_hash, conn);
-- hci_dev_put(hdev);
--
-- /* Unacked frames */
-- hdev->acl_cnt += conn->sent;
--
-- skb_queue_purge(&conn->data_q);
--
-- kfree(conn);
-- return 0;
-+ return notifier_chain_unregister(&hci_notifier, nb);
- }
-
--/* Drop all connection on the device */
--static void hci_conn_hash_flush(struct hci_dev *hdev)
-+void hci_notify(struct hci_dev *hdev, int event)
- {
-- struct conn_hash *h = &hdev->conn_hash;
-- struct hci_proto *hp;
-- struct list_head *p;
--
-- DBG("hdev %s", hdev->name);
--
-- p = h->list.next;
-- while (p != &h->list) {
-- struct hci_conn *c;
--
-- c = list_entry(p, struct hci_conn, list);
-- p = p->next;
--
-- if (c->type == ACL_LINK) {
-- /* ACL link notify L2CAP layer */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
-- hp->disconn_ind(c, 0x16);
-- } else {
-- /* SCO link (no notification) */
-- }
--
-- hci_conn_del(hdev, c);
-- }
-+ notifier_call_chain(&hci_notifier, event, hdev);
- }
-
--int hci_connect(struct hci_dev *hdev, bdaddr_t *bdaddr)
--{
-- struct inquiry_cache *cache = &hdev->inq_cache;
-- struct inquiry_entry *e;
-- create_conn_cp cc;
-- __u16 clock_offset;
--
-- DBG("%s bdaddr %s", hdev->name, batostr(bdaddr));
--
-- if (!(hdev->flags & HCI_UP))
-- return -ENODEV;
--
-- inquiry_cache_lock_bh(cache);
--
-- if (!(e = __inquiry_cache_lookup(cache, bdaddr)) || inquiry_entry_age(e) > INQUIRY_ENTRY_AGE_MAX) {
-- cc.pscan_rep_mode = 0;
-- cc.pscan_mode = 0;
-- clock_offset = 0;
-- } else {
-- cc.pscan_rep_mode = e->info.pscan_rep_mode;
-- cc.pscan_mode = e->info.pscan_mode;
-- clock_offset = __le16_to_cpu(e->info.clock_offset) & 0x8000;
-- }
--
-- inquiry_cache_unlock_bh(cache);
--
-- bacpy(&cc.bdaddr, bdaddr);
-- cc.pkt_type = __cpu_to_le16(hdev->pkt_type);
-- cc.clock_offset = __cpu_to_le16(clock_offset);
--
-- if (lmp_rswitch_capable(hdev))
-- cc.role_switch = 0x01;
-- else
-- cc.role_switch = 0x00;
--
-- hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, CREATE_CONN_CP_SIZE, &cc);
-+/* ---- HCI hotplug support ---- */
-
-- return 0;
--}
-+#ifdef CONFIG_HOTPLUG
-
--int hci_disconnect(struct hci_conn *conn, __u8 reason)
-+static int hci_run_hotplug(char *dev, char *action)
- {
-- disconnect_cp dc;
--
-- DBG("conn %p handle %d", conn, conn->handle);
-+ char *argv[3], *envp[5], dstr[20], astr[32];
-
-- dc.handle = __cpu_to_le16(conn->handle);
-- dc.reason = reason;
-- hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT, DISCONNECT_CP_SIZE, &dc);
-+ sprintf(dstr, "DEVICE=%s", dev);
-+ sprintf(astr, "ACTION=%s", action);
-
-- return 0;
--}
-+ argv[0] = hotplug_path;
-+ argv[1] = "bluetooth";
-+ argv[2] = NULL;
-
--/* --------- HCI request handling ------------ */
--static inline void hci_req_lock(struct hci_dev *hdev)
--{
-- down(&hdev->req_lock);
-+ envp[0] = "HOME=/";
-+ envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
-+ envp[2] = dstr;
-+ envp[3] = astr;
-+ envp[4] = NULL;
-+
-+ return call_usermodehelper(argv[0], argv, envp);
- }
-+#else
-+#define hci_run_hotplug(A...)
-+#endif
-
--static inline void hci_req_unlock(struct hci_dev *hdev)
--{
-- up(&hdev->req_lock);
--}
-+/* ---- HCI requests ---- */
-
--static inline void hci_req_complete(struct hci_dev *hdev, int result)
-+void hci_req_complete(struct hci_dev *hdev, int result)
- {
-- DBG("%s result 0x%2.2x", hdev->name, result);
-+ BT_DBG("%s result 0x%2.2x", hdev->name, result);
-
- if (hdev->req_status == HCI_REQ_PEND) {
- hdev->req_result = result;
-@@ -344,9 +134,9 @@
- }
- }
-
--static inline void hci_req_cancel(struct hci_dev *hdev, int err)
-+void hci_req_cancel(struct hci_dev *hdev, int err)
- {
-- DBG("%s err 0x%2.2x", hdev->name, err);
-+ BT_DBG("%s err 0x%2.2x", hdev->name, err);
-
- if (hdev->req_status == HCI_REQ_PEND) {
- hdev->req_result = err;
-@@ -356,23 +146,22 @@
- }
-
- /* Execute request and wait for completion. */
--static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt),
-- unsigned long opt, __u32 timeout)
-+static int __hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *hdev, unsigned long opt), unsigned long opt, __u32 timeout)
- {
- DECLARE_WAITQUEUE(wait, current);
- int err = 0;
-
-- DBG("%s start", hdev->name);
-+ BT_DBG("%s start", hdev->name);
-
- hdev->req_status = HCI_REQ_PEND;
-
- add_wait_queue(&hdev->req_wait_q, &wait);
-- current->state = TASK_INTERRUPTIBLE;
-+ set_current_state(TASK_INTERRUPTIBLE);
-
- req(hdev, opt);
- schedule_timeout(timeout);
-
-- current->state = TASK_RUNNING;
-+ set_current_state(TASK_RUNNING);
- remove_wait_queue(&hdev->req_wait_q, &wait);
-
- if (signal_pending(current))
-@@ -394,7 +183,7 @@
-
- hdev->req_status = hdev->req_result = 0;
-
-- DBG("%s end: err %d", hdev->name, err);
-+ BT_DBG("%s end: err %d", hdev->name, err);
-
- return err;
- }
-@@ -412,10 +201,9 @@
- return ret;
- }
-
--/* --------- HCI requests ---------- */
- static void hci_reset_req(struct hci_dev *hdev, unsigned long opt)
- {
-- DBG("%s %ld", hdev->name, opt);
-+ BT_DBG("%s %ld", hdev->name, opt);
-
- /* Reset device */
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_RESET, 0, NULL);
-@@ -423,10 +211,10 @@
-
- static void hci_init_req(struct hci_dev *hdev, unsigned long opt)
- {
-- set_event_flt_cp ec;
-+ set_event_flt_cp ef;
- __u16 param;
-
-- DBG("%s %ld", hdev->name, opt);
-+ BT_DBG("%s %ld", hdev->name, opt);
-
- /* Mandatory initialization */
-
-@@ -436,14 +224,30 @@
- /* Read Buffer Size (ACL mtu, max pkt, etc.) */
- hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE, 0, NULL);
-
-+#if 0
-+ /* Host buffer size */
-+ {
-+ host_buffer_size_cp bs;
-+ bs.acl_mtu = __cpu_to_le16(HCI_MAX_ACL_SIZE);
-+ bs.sco_mtu = HCI_MAX_SCO_SIZE;
-+ bs.acl_max_pkt = __cpu_to_le16(0xffff);
-+ bs.sco_max_pkt = __cpu_to_le16(0xffff);
-+ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_HOST_BUFFER_SIZE,
-+ HOST_BUFFER_SIZE_CP_SIZE, &bs);
-+ }
-+#endif
-+
- /* Read BD Address */
- hci_send_cmd(hdev, OGF_INFO_PARAM, OCF_READ_BD_ADDR, 0, NULL);
-
-+ /* Read Voice Setting */
-+ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_READ_VOICE_SETTING, 0, NULL);
-+
- /* Optional initialization */
-
- /* Clear Event Filters */
-- ec.flt_type = FLT_CLEAR_ALL;
-- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &ec);
-+ ef.flt_type = FLT_CLEAR_ALL;
-+ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_SET_EVENT_FLT, 1, &ef);
-
- /* Page timeout ~20 secs */
- param = __cpu_to_le16(0x8000);
-@@ -458,7 +262,7 @@
- {
- __u8 scan = opt;
-
-- DBG("%s %x", hdev->name, scan);
-+ BT_DBG("%s %x", hdev->name, scan);
-
- /* Inquiry and Page scans */
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE, 1, &scan);
-@@ -468,116 +272,272 @@
- {
- __u8 auth = opt;
-
-- DBG("%s %x", hdev->name, auth);
-+ BT_DBG("%s %x", hdev->name, auth);
-
- /* Authentication */
- hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE, 1, &auth);
- }
-
--static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
-+static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
- {
-- struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
-- inquiry_cp ic;
-+ __u8 encrypt = opt;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s %x", hdev->name, encrypt);
-
-- /* Start Inquiry */
-- memcpy(&ic.lap, &ir->lap, 3);
-- ic.lenght = ir->length;
-- ic.num_rsp = ir->num_rsp;
-- hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, &ic);
-+ /* Authentication */
-+ hci_send_cmd(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE, 1, &encrypt);
- }
-
--/* HCI ioctl helpers */
--int hci_dev_open(__u16 dev)
-+/* Get HCI device by index.
-+ * Device is locked on return. */
-+struct hci_dev *hci_dev_get(int index)
- {
- struct hci_dev *hdev;
-- int ret = 0;
--
-- if (!(hdev = hci_dev_get(dev)))
-- return -ENODEV;
-+ struct list_head *p;
-
-- DBG("%s %p", hdev->name, hdev);
-+ BT_DBG("%d", index);
-
-- hci_req_lock(hdev);
-+ if (index < 0)
-+ return NULL;
-
-- if (hdev->flags & HCI_UP) {
-- ret = -EALREADY;
-- goto done;
-+ read_lock(&hdev_list_lock);
-+ list_for_each(p, &hdev_list) {
-+ hdev = list_entry(p, struct hci_dev, list);
-+ if (hdev->id == index) {
-+ hci_dev_hold(hdev);
-+ goto done;
-+ }
- }
-+ hdev = NULL;
-+done:
-+ read_unlock(&hdev_list_lock);
-+ return hdev;
-+}
-
-- if (hdev->open(hdev)) {
-- ret = -EIO;
-- goto done;
-- }
-+/* ---- Inquiry support ---- */
-+void inquiry_cache_flush(struct hci_dev *hdev)
-+{
-+ struct inquiry_cache *cache = &hdev->inq_cache;
-+ struct inquiry_entry *next = cache->list, *e;
-
-- if (hdev->flags & HCI_NORMAL) {
-- atomic_set(&hdev->cmd_cnt, 1);
-- hdev->flags |= HCI_INIT;
-+ BT_DBG("cache %p", cache);
-
-- //__hci_request(hdev, hci_reset_req, 0, HZ);
-- ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
--
-- hdev->flags &= ~HCI_INIT;
-+ cache->list = NULL;
-+ while ((e = next)) {
-+ next = e->next;
-+ kfree(e);
- }
-+}
-
-- if (!ret) {
-- hdev->flags |= HCI_UP;
-- hci_notify(hdev, HCI_DEV_UP);
-- } else {
-- /* Init failed, cleanup */
-- tasklet_kill(&hdev->rx_task);
-- tasklet_kill(&hdev->tx_task);
-- tasklet_kill(&hdev->cmd_task);
-+struct inquiry_entry *inquiry_cache_lookup(struct hci_dev *hdev, bdaddr_t *bdaddr)
-+{
-+ struct inquiry_cache *cache = &hdev->inq_cache;
-+ struct inquiry_entry *e;
-
-- skb_queue_purge(&hdev->cmd_q);
-- skb_queue_purge(&hdev->rx_q);
-+ BT_DBG("cache %p, %s", cache, batostr(bdaddr));
-
-- if (hdev->flush)
-- hdev->flush(hdev);
-+ for (e = cache->list; e; e = e->next)
-+ if (!bacmp(&e->info.bdaddr, bdaddr))
-+ break;
-+ return e;
-+}
-
-- if (hdev->sent_cmd) {
-- kfree_skb(hdev->sent_cmd);
-- hdev->sent_cmd = NULL;
-- }
-+void inquiry_cache_update(struct hci_dev *hdev, inquiry_info *info)
-+{
-+ struct inquiry_cache *cache = &hdev->inq_cache;
-+ struct inquiry_entry *e;
-
-- hdev->close(hdev);
-- }
-+ BT_DBG("cache %p, %s", cache, batostr(&info->bdaddr));
-
--done:
-- hci_req_unlock(hdev);
-- hci_dev_put(hdev);
-+ if (!(e = inquiry_cache_lookup(hdev, &info->bdaddr))) {
-+ /* Entry not in the cache. Add new one. */
-+ if (!(e = kmalloc(sizeof(struct inquiry_entry), GFP_ATOMIC)))
-+ return;
-+ memset(e, 0, sizeof(struct inquiry_entry));
-+ e->next = cache->list;
-+ cache->list = e;
-+ }
-
-- return ret;
-+ memcpy(&e->info, info, sizeof(inquiry_info));
-+ e->timestamp = jiffies;
-+ cache->timestamp = jiffies;
- }
-
--int hci_dev_close(__u16 dev)
-+int inquiry_cache_dump(struct hci_dev *hdev, int num, __u8 *buf)
- {
-- struct hci_dev *hdev;
--
-- if (!(hdev = hci_dev_get(dev)))
-- return -ENODEV;
-+ struct inquiry_cache *cache = &hdev->inq_cache;
-+ inquiry_info *info = (inquiry_info *) buf;
-+ struct inquiry_entry *e;
-+ int copied = 0;
-
-- DBG("%s %p", hdev->name, hdev);
-+ for (e = cache->list; e && copied < num; e = e->next, copied++)
-+ memcpy(info++, &e->info, sizeof(inquiry_info));
-
-- hci_req_cancel(hdev, ENODEV);
-- hci_req_lock(hdev);
-+ BT_DBG("cache %p, copied %d", cache, copied);
-+ return copied;
-+}
-
-- if (!(hdev->flags & HCI_UP))
-- goto done;
-+static void hci_inq_req(struct hci_dev *hdev, unsigned long opt)
-+{
-+ struct hci_inquiry_req *ir = (struct hci_inquiry_req *) opt;
-+ inquiry_cp ic;
-
-- /* Kill RX and TX tasks */
-- tasklet_kill(&hdev->rx_task);
-- tasklet_kill(&hdev->tx_task);
-+ BT_DBG("%s", hdev->name);
-
-- inquiry_cache_flush(&hdev->inq_cache);
-+ if (test_bit(HCI_INQUIRY, &hdev->flags))
-+ return;
-
-- hci_conn_hash_flush(hdev);
-+ /* Start Inquiry */
-+ memcpy(&ic.lap, &ir->lap, 3);
-+ ic.length = ir->length;
-+ ic.num_rsp = ir->num_rsp;
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_INQUIRY, INQUIRY_CP_SIZE, &ic);
-+}
-
-- /* Clear flags */
-- hdev->flags &= HCI_SOCK;
-- hdev->flags |= HCI_NORMAL;
-+int hci_inquiry(unsigned long arg)
-+{
-+ struct hci_inquiry_req ir;
-+ struct hci_dev *hdev;
-+ int err = 0, do_inquiry = 0, max_rsp;
-+ long timeo;
-+ __u8 *buf, *ptr;
-
-+ ptr = (void *) arg;
-+ if (copy_from_user(&ir, ptr, sizeof(ir)))
-+ return -EFAULT;
-+
-+ if (!(hdev = hci_dev_get(ir.dev_id)))
-+ return -ENODEV;
-+
-+ hci_dev_lock_bh(hdev);
-+ if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX ||
-+ ir.flags & IREQ_CACHE_FLUSH) {
-+ inquiry_cache_flush(hdev);
-+ do_inquiry = 1;
-+ }
-+ hci_dev_unlock_bh(hdev);
-+
-+ timeo = ir.length * 2 * HZ;
-+ if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
-+ goto done;
-+
-+ /* for unlimited number of responses we will use buffer with 255 entries */
-+ max_rsp = (ir.num_rsp == 0) ? 255 : ir.num_rsp;
-+
-+ /* cache_dump can't sleep. Therefore we allocate temp buffer and then
-+ * copy it to the user space.
-+ */
-+ if (!(buf = kmalloc(sizeof(inquiry_info) * max_rsp, GFP_KERNEL))) {
-+ err = -ENOMEM;
-+ goto done;
-+ }
-+
-+ hci_dev_lock_bh(hdev);
-+ ir.num_rsp = inquiry_cache_dump(hdev, max_rsp, buf);
-+ hci_dev_unlock_bh(hdev);
-+
-+ BT_DBG("num_rsp %d", ir.num_rsp);
-+
-+ if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) +
-+ (sizeof(inquiry_info) * ir.num_rsp))) {
-+ copy_to_user(ptr, &ir, sizeof(ir));
-+ ptr += sizeof(ir);
-+ copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
-+ } else
-+ err = -EFAULT;
-+
-+ kfree(buf);
-+
-+done:
-+ hci_dev_put(hdev);
-+ return err;
-+}
-+
-+/* ---- HCI ioctl helpers ---- */
-+
-+int hci_dev_open(__u16 dev)
-+{
-+ struct hci_dev *hdev;
-+ int ret = 0;
-+
-+ if (!(hdev = hci_dev_get(dev)))
-+ return -ENODEV;
-+
-+ BT_DBG("%s %p", hdev->name, hdev);
-+
-+ hci_req_lock(hdev);
-+
-+ if (test_bit(HCI_UP, &hdev->flags)) {
-+ ret = -EALREADY;
-+ goto done;
-+ }
-+
-+ if (hdev->open(hdev)) {
-+ ret = -EIO;
-+ goto done;
-+ }
-+
-+ if (!test_bit(HCI_RAW, &hdev->flags)) {
-+ atomic_set(&hdev->cmd_cnt, 1);
-+ set_bit(HCI_INIT, &hdev->flags);
-+
-+ //__hci_request(hdev, hci_reset_req, 0, HZ);
-+ ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT);
-+
-+ clear_bit(HCI_INIT, &hdev->flags);
-+ }
-+
-+ if (!ret) {
-+ set_bit(HCI_UP, &hdev->flags);
-+ hci_notify(hdev, HCI_DEV_UP);
-+ } else {
-+ /* Init failed, cleanup */
-+ tasklet_kill(&hdev->rx_task);
-+ tasklet_kill(&hdev->tx_task);
-+ tasklet_kill(&hdev->cmd_task);
-+
-+ skb_queue_purge(&hdev->cmd_q);
-+ skb_queue_purge(&hdev->rx_q);
-+
-+ if (hdev->flush)
-+ hdev->flush(hdev);
-+
-+ if (hdev->sent_cmd) {
-+ kfree_skb(hdev->sent_cmd);
-+ hdev->sent_cmd = NULL;
-+ }
-+
-+ hdev->close(hdev);
-+ hdev->flags = 0;
-+ }
-+
-+done:
-+ hci_req_unlock(hdev);
-+ hci_dev_put(hdev);
-+ return ret;
-+}
-+
-+static int hci_dev_do_close(struct hci_dev *hdev)
-+{
-+ BT_DBG("%s %p", hdev->name, hdev);
-+
-+ hci_req_cancel(hdev, ENODEV);
-+ hci_req_lock(hdev);
-+
-+ if (!test_and_clear_bit(HCI_UP, &hdev->flags)) {
-+ hci_req_unlock(hdev);
-+ return 0;
-+ }
-+
-+ /* Kill RX and TX tasks */
-+ tasklet_kill(&hdev->rx_task);
-+ tasklet_kill(&hdev->tx_task);
-+
-+ hci_dev_lock_bh(hdev);
-+ inquiry_cache_flush(hdev);
-+ hci_conn_hash_flush(hdev);
-+ hci_dev_unlock_bh(hdev);
-+
- hci_notify(hdev, HCI_DEV_DOWN);
-
- if (hdev->flush)
-@@ -586,9 +546,9 @@
- /* Reset device */
- skb_queue_purge(&hdev->cmd_q);
- atomic_set(&hdev->cmd_cnt, 1);
-- hdev->flags |= HCI_INIT;
-- __hci_request(hdev, hci_reset_req, 0, HZ);
-- hdev->flags &= ~HCI_INIT;
-+ set_bit(HCI_INIT, &hdev->flags);
-+ __hci_request(hdev, hci_reset_req, 0, HZ/4);
-+ clear_bit(HCI_INIT, &hdev->flags);
-
- /* Kill cmd task */
- tasklet_kill(&hdev->cmd_task);
-@@ -605,17 +565,28 @@
- }
-
- /* After this point our queues are empty
-- * and no tasks are scheduled.
-- */
-+ * and no tasks are scheduled. */
- hdev->close(hdev);
-
--done:
-- hci_req_unlock(hdev);
-- hci_dev_put(hdev);
-+ /* Clear flags */
-+ hdev->flags = 0;
-
-+ hci_req_unlock(hdev);
- return 0;
- }
-
-+int hci_dev_close(__u16 dev)
-+{
-+ struct hci_dev *hdev;
-+ int err;
-+
-+ if (!(hdev = hci_dev_get(dev)))
-+ return -ENODEV;
-+ err = hci_dev_do_close(hdev);
-+ hci_dev_put(hdev);
-+ return err;
-+}
-+
- int hci_dev_reset(__u16 dev)
- {
- struct hci_dev *hdev;
-@@ -627,16 +598,17 @@
- hci_req_lock(hdev);
- tasklet_disable(&hdev->tx_task);
-
-- if (!(hdev->flags & HCI_UP))
-+ if (!test_bit(HCI_UP, &hdev->flags))
- goto done;
-
- /* Drop queues */
- skb_queue_purge(&hdev->rx_q);
- skb_queue_purge(&hdev->cmd_q);
-
-- inquiry_cache_flush(&hdev->inq_cache);
--
-+ hci_dev_lock_bh(hdev);
-+ inquiry_cache_flush(hdev);
- hci_conn_hash_flush(hdev);
-+ hci_dev_unlock_bh(hdev);
-
- if (hdev->flush)
- hdev->flush(hdev);
-@@ -650,7 +622,6 @@
- tasklet_enable(&hdev->tx_task);
- hci_req_unlock(hdev);
- hci_dev_put(hdev);
--
- return ret;
- }
-
-@@ -669,30 +640,11 @@
- return ret;
- }
-
--int hci_dev_setauth(unsigned long arg)
--{
-- struct hci_dev *hdev;
-- struct hci_dev_req dr;
-- int ret = 0;
--
-- if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
-- return -EFAULT;
--
-- if (!(hdev = hci_dev_get(dr.dev_id)))
-- return -ENODEV;
--
-- ret = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
--
-- hci_dev_put(hdev);
--
-- return ret;
--}
--
--int hci_dev_setscan(unsigned long arg)
-+int hci_dev_cmd(unsigned int cmd, unsigned long arg)
- {
- struct hci_dev *hdev;
- struct hci_dev_req dr;
-- int ret = 0;
-+ int err = 0;
-
- if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
- return -EFAULT;
-@@ -700,48 +652,78 @@
- if (!(hdev = hci_dev_get(dr.dev_id)))
- return -ENODEV;
-
-- ret = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
--
-- hci_dev_put(hdev);
-+ switch (cmd) {
-+ case HCISETAUTH:
-+ err = hci_request(hdev, hci_auth_req, dr.dev_opt, HCI_INIT_TIMEOUT);
-+ break;
-
-- return ret;
--}
-+ case HCISETENCRYPT:
-+ if (!lmp_encrypt_capable(hdev)) {
-+ err = -EOPNOTSUPP;
-+ break;
-+ }
-
--int hci_dev_setptype(unsigned long arg)
--{
-- struct hci_dev *hdev;
-- struct hci_dev_req dr;
-- int ret = 0;
-+ if (!test_bit(HCI_AUTH, &hdev->flags)) {
-+ /* Auth must be enabled first */
-+ err = hci_request(hdev, hci_auth_req,
-+ dr.dev_opt, HCI_INIT_TIMEOUT);
-+ if (err)
-+ break;
-+ }
-+
-+ err = hci_request(hdev, hci_encrypt_req,
-+ dr.dev_opt, HCI_INIT_TIMEOUT);
-+ break;
-+
-+ case HCISETSCAN:
-+ err = hci_request(hdev, hci_scan_req, dr.dev_opt, HCI_INIT_TIMEOUT);
-+ break;
-+
-+ case HCISETPTYPE:
-+ hdev->pkt_type = (__u16) dr.dev_opt;
-+ break;
-+
-+ case HCISETLINKPOL:
-+ hdev->link_policy = (__u16) dr.dev_opt;
-+ break;
-
-- if (copy_from_user(&dr, (void *) arg, sizeof(dr)))
-- return -EFAULT;
-+ case HCISETLINKMODE:
-+ hdev->link_mode = ((__u16) dr.dev_opt) & (HCI_LM_MASTER | HCI_LM_ACCEPT);
-+ break;
-
-- if (!(hdev = hci_dev_get(dr.dev_id)))
-- return -ENODEV;
-+ case HCISETACLMTU:
-+ hdev->acl_mtu = *((__u16 *)&dr.dev_opt + 1);
-+ hdev->acl_pkts = *((__u16 *)&dr.dev_opt + 0);
-+ break;
-
-- hdev->pkt_type = (__u16) dr.dev_opt;
-+ case HCISETSCOMTU:
-+ hdev->sco_mtu = *((__u16 *)&dr.dev_opt + 1);
-+ hdev->sco_pkts = *((__u16 *)&dr.dev_opt + 0);
-+ break;
-
-+ default:
-+ err = -EINVAL;
-+ break;
-+ }
- hci_dev_put(hdev);
--
-- return ret;
-+ return err;
- }
-
--int hci_dev_list(unsigned long arg)
-+int hci_get_dev_list(unsigned long arg)
- {
- struct hci_dev_list_req *dl;
- struct hci_dev_req *dr;
-- struct hci_dev *hdev;
-- int i, n, size;
-+ struct list_head *p;
-+ int n = 0, size;
- __u16 dev_num;
-
- if (get_user(dev_num, (__u16 *) arg))
- return -EFAULT;
-
-- /* Avoid long loop, overflow */
-- if (dev_num > 2048)
-+ if (!dev_num)
- return -EINVAL;
-
-- size = dev_num * sizeof(struct hci_dev_req) + sizeof(__u16);
-+ size = dev_num * sizeof(*dr) + sizeof(*dl);
-
- if (verify_area(VERIFY_WRITE, (void *) arg, size))
- return -EFAULT;
-@@ -750,25 +732,27 @@
- return -ENOMEM;
- dr = dl->dev_req;
-
-- spin_lock_bh(&hdev_list_lock);
-- for (i = 0, n = 0; i < HCI_MAX_DEV && n < dev_num; i++) {
-- if ((hdev = hdev_list[i])) {
-- (dr + n)->dev_id = hdev->id;
-- (dr + n)->dev_opt = hdev->flags;
-- n++;
-- }
-+ read_lock_bh(&hdev_list_lock);
-+ list_for_each(p, &hdev_list) {
-+ struct hci_dev *hdev;
-+ hdev = list_entry(p, struct hci_dev, list);
-+ (dr + n)->dev_id = hdev->id;
-+ (dr + n)->dev_opt = hdev->flags;
-+ if (++n >= dev_num)
-+ break;
- }
-- spin_unlock_bh(&hdev_list_lock);
-+ read_unlock_bh(&hdev_list_lock);
-
- dl->dev_num = n;
-- size = n * sizeof(struct hci_dev_req) + sizeof(__u16);
-+ size = n * sizeof(*dr) + sizeof(*dl);
-
- copy_to_user((void *) arg, dl, size);
-+ kfree(dl);
-
- return 0;
- }
-
--int hci_dev_info(unsigned long arg)
-+int hci_get_dev_info(unsigned long arg)
- {
- struct hci_dev *hdev;
- struct hci_dev_info di;
-@@ -786,9 +770,11 @@
- di.flags = hdev->flags;
- di.pkt_type = hdev->pkt_type;
- di.acl_mtu = hdev->acl_mtu;
-- di.acl_max = hdev->acl_max;
-+ di.acl_pkts = hdev->acl_pkts;
- di.sco_mtu = hdev->sco_mtu;
-- di.sco_max = hdev->sco_max;
-+ di.sco_pkts = hdev->sco_pkts;
-+ di.link_policy = hdev->link_policy;
-+ di.link_mode = hdev->link_mode;
-
- memcpy(&di.stat, &hdev->stat, sizeof(di.stat));
- memcpy(&di.features, &hdev->features, sizeof(di.features));
-@@ -801,258 +787,168 @@
- return err;
- }
-
--__u32 hci_dev_setmode(struct hci_dev *hdev, __u32 mode)
--{
-- __u32 omode = hdev->flags & HCI_MODE_MASK;
--
-- hdev->flags &= ~HCI_MODE_MASK;
-- hdev->flags |= (mode & HCI_MODE_MASK);
-
-- return omode;
--}
-+/* ---- Interface to HCI drivers ---- */
-
--__u32 hci_dev_getmode(struct hci_dev *hdev)
-+/* Register HCI device */
-+int hci_register_dev(struct hci_dev *hdev)
- {
-- return hdev->flags & HCI_MODE_MASK;
--}
-+ struct list_head *head = &hdev_list, *p;
-+ int id = 0;
-
--int hci_conn_list(unsigned long arg)
--{
-- struct hci_conn_list_req req, *cl;
-- struct hci_conn_info *ci;
-- struct hci_dev *hdev;
-- struct list_head *p;
-- int n = 0, size;
-+ BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
-
-- if (copy_from_user(&req, (void *) arg, sizeof(req)))
-- return -EFAULT;
-+ if (!hdev->open || !hdev->close || !hdev->destruct)
-+ return -EINVAL;
-
-- if (!(hdev = hci_dev_get(req.dev_id)))
-- return -ENODEV;
-+ write_lock_bh(&hdev_list_lock);
-
-- /* Set a limit to avoid overlong loops, and also numeric overflow - AC */
-- if(req.conn_num < 2048)
-- return -EINVAL;
-+ /* Find first available device id */
-+ list_for_each(p, &hdev_list) {
-+ if (list_entry(p, struct hci_dev, list)->id != id)
-+ break;
-+ head = p; id++;
-+ }
-
-- size = req.conn_num * sizeof(struct hci_conn_info) + sizeof(req);
--
-- if (!(cl = kmalloc(size, GFP_KERNEL)))
-- return -ENOMEM;
-- ci = cl->conn_info;
-+ sprintf(hdev->name, "hci%d", id);
-+ hdev->id = id;
-+ list_add(&hdev->list, head);
-
-- local_bh_disable();
-- conn_hash_lock(&hdev->conn_hash);
-- list_for_each(p, &hdev->conn_hash.list) {
-- register struct hci_conn *c;
-- c = list_entry(p, struct hci_conn, list);
-+ atomic_set(&hdev->refcnt, 1);
-+ spin_lock_init(&hdev->lock);
-+
-+ hdev->flags = 0;
-+ hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1);
-+ hdev->link_mode = (HCI_LM_ACCEPT);
-
-- (ci + n)->handle = c->handle;
-- bacpy(&(ci + n)->bdaddr, &c->dst);
-- n++;
-- }
-- conn_hash_unlock(&hdev->conn_hash);
-- local_bh_enable();
--
-- cl->dev_id = hdev->id;
-- cl->conn_num = n;
-- size = n * sizeof(struct hci_conn_info) + sizeof(req);
-+ tasklet_init(&hdev->cmd_task, hci_cmd_task,(unsigned long) hdev);
-+ tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
-+ tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
-
-- hci_dev_put(hdev);
-+ skb_queue_head_init(&hdev->rx_q);
-+ skb_queue_head_init(&hdev->cmd_q);
-+ skb_queue_head_init(&hdev->raw_q);
-
-- if(copy_to_user((void *) arg, cl, size))
-- return -EFAULT;
-- return 0;
--}
-+ init_waitqueue_head(&hdev->req_wait_q);
-+ init_MUTEX(&hdev->req_lock);
-
--int hci_inquiry(unsigned long arg)
--{
-- struct inquiry_cache *cache;
-- struct hci_inquiry_req ir;
-- struct hci_dev *hdev;
-- int err = 0, do_inquiry = 0;
-- long timeo;
-- __u8 *buf, *ptr;
-+ inquiry_cache_init(hdev);
-
-- ptr = (void *) arg;
-- if (copy_from_user(&ir, ptr, sizeof(ir)))
-- return -EFAULT;
-+ conn_hash_init(hdev);
-
-- if (!(hdev = hci_dev_get(ir.dev_id)))
-- return -ENODEV;
-+ memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
-
-- cache = &hdev->inq_cache;
-+ atomic_set(&hdev->promisc, 0);
-
-- inquiry_cache_lock(cache);
-- if (inquiry_cache_age(cache) > INQUIRY_CACHE_AGE_MAX || ir.flags & IREQ_CACHE_FLUSH) {
-- inquiry_cache_flush(cache);
-- do_inquiry = 1;
-- }
-- inquiry_cache_unlock(cache);
-+ MOD_INC_USE_COUNT;
-
-- /* Limit inquiry time, also avoid overflows */
-+ write_unlock_bh(&hdev_list_lock);
-
-- if(ir.length > 2048 || ir.num_rsp > 2048)
-- {
-- err = -EINVAL;
-- goto done;
-- }
-+ hci_notify(hdev, HCI_DEV_REG);
-+ hci_run_hotplug(hdev->name, "register");
-
-- timeo = ir.length * 2 * HZ;
-- if (do_inquiry && (err = hci_request(hdev, hci_inq_req, (unsigned long)&ir, timeo)) < 0)
-- goto done;
-+ return id;
-+}
-
-- /* cache_dump can't sleep. Therefore we allocate temp buffer and then
-- * copy it to the user space.
-- */
-- if (!(buf = kmalloc(sizeof(inquiry_info) * ir.num_rsp, GFP_KERNEL))) {
-- err = -ENOMEM;
-- goto done;
-- }
-- ir.num_rsp = inquiry_cache_dump(cache, ir.num_rsp, buf);
-+/* Unregister HCI device */
-+int hci_unregister_dev(struct hci_dev *hdev)
-+{
-+ BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
-
-- DBG("num_rsp %d", ir.num_rsp);
-+ write_lock_bh(&hdev_list_lock);
-+ list_del(&hdev->list);
-+ write_unlock_bh(&hdev_list_lock);
-
-- if (!verify_area(VERIFY_WRITE, ptr, sizeof(ir) + (sizeof(inquiry_info) * ir.num_rsp))) {
-- copy_to_user(ptr, &ir, sizeof(ir));
-- ptr += sizeof(ir);
-- copy_to_user(ptr, buf, sizeof(inquiry_info) * ir.num_rsp);
-- } else
-- err = -EFAULT;
-+ hci_dev_do_close(hdev);
-
-- kfree(buf);
-+ hci_notify(hdev, HCI_DEV_UNREG);
-+ hci_run_hotplug(hdev->name, "unregister");
-
--done:
- hci_dev_put(hdev);
-
-- return err;
-+ MOD_DEC_USE_COUNT;
-+ return 0;
- }
-
--/* Interface to HCI drivers */
--
--/* Register HCI device */
--int hci_register_dev(struct hci_dev *hdev)
-+/* Suspend HCI device */
-+int hci_suspend_dev(struct hci_dev *hdev)
- {
-- int i;
--
-- DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
--
-- /* Find free slot */
-- spin_lock_bh(&hdev_list_lock);
-- for (i = 0; i < HCI_MAX_DEV; i++) {
-- if (!hdev_list[i]) {
-- hdev_list[i] = hdev;
-+ hci_notify(hdev, HCI_DEV_SUSPEND);
-+ hci_run_hotplug(hdev->name, "suspend");
-+ return 0;
-+}
-
-- sprintf(hdev->name, "hci%d", i);
-- atomic_set(&hdev->refcnt, 0);
-- hdev->id = i;
-- hdev->flags = HCI_NORMAL;
-+/* Resume HCI device */
-+int hci_resume_dev(struct hci_dev *hdev)
-+{
-+ hci_notify(hdev, HCI_DEV_RESUME);
-+ hci_run_hotplug(hdev->name, "resume");
-+ return 0;
-+}
-
-- hdev->pkt_type = (HCI_DM1 | HCI_DH1);
--
-- tasklet_init(&hdev->cmd_task, hci_cmd_task, (unsigned long) hdev);
-- tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
-- tasklet_init(&hdev->tx_task, hci_tx_task, (unsigned long) hdev);
--
-- skb_queue_head_init(&hdev->rx_q);
-- skb_queue_head_init(&hdev->cmd_q);
-- skb_queue_head_init(&hdev->raw_q);
--
-- init_waitqueue_head(&hdev->req_wait_q);
-- init_MUTEX(&hdev->req_lock);
--
-- inquiry_cache_init(&hdev->inq_cache);
--
-- conn_hash_init(&hdev->conn_hash);
--
-- memset(&hdev->stat, 0, sizeof(struct hci_dev_stats));
--
-- hci_notify(hdev, HCI_DEV_REG);
--
-- MOD_INC_USE_COUNT;
-- break;
-- }
-- }
-- spin_unlock_bh(&hdev_list_lock);
--
-- return (i == HCI_MAX_DEV) ? -1 : i;
--}
--
--/* Unregister HCI device */
--int hci_unregister_dev(struct hci_dev *hdev)
-+/* Receive frame from HCI drivers */
-+int hci_recv_frame(struct sk_buff *skb)
- {
-- int i;
--
-- DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
--
-- if (hdev->flags & HCI_UP)
-- hci_dev_close(hdev->id);
-+ struct hci_dev *hdev = (struct hci_dev *) skb->dev;
-
-- /* Find device slot */
-- spin_lock(&hdev_list_lock);
-- for (i = 0; i < HCI_MAX_DEV; i++) {
-- if (hdev_list[i] == hdev) {
-- hdev_list[i] = NULL;
-- MOD_DEC_USE_COUNT;
-- break;
-- }
-+ if (!hdev || (!test_bit(HCI_UP, &hdev->flags) &&
-+ !test_bit(HCI_INIT, &hdev->flags)) ) {
-+ kfree_skb(skb);
-+ return -1;
- }
-- spin_unlock(&hdev_list_lock);
--
-- hci_notify(hdev, HCI_DEV_UNREG);
-
-- /* Sleep while device is in use */
-- while (atomic_read(&hdev->refcnt)) {
-- int sleep_cnt = 100;
-+ BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-
-- DBG("%s sleeping on lock %d", hdev->name, atomic_read(&hdev->refcnt));
-+ /* Incomming skb */
-+ bluez_cb(skb)->incomming = 1;
-
-- sleep_on_timeout(&hdev->req_wait_q, HZ*10);
-- if (!(--sleep_cnt))
-- break;
-- }
-+ /* Time stamp */
-+ do_gettimeofday(&skb->stamp);
-
-+ /* Queue frame for rx task */
-+ skb_queue_tail(&hdev->rx_q, skb);
-+ hci_sched_rx(hdev);
- return 0;
- }
-
--/* Interface to upper protocols */
-+/* ---- Interface to upper protocols ---- */
-
- /* Register/Unregister protocols.
-- * hci_task_lock is used to ensure that no tasks are running.
-- */
--int hci_register_proto(struct hci_proto *hproto)
-+ * hci_task_lock is used to ensure that no tasks are running. */
-+int hci_register_proto(struct hci_proto *hp)
- {
- int err = 0;
-
-- DBG("%p name %s", hproto, hproto->name);
-+ BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
-
-- if (hproto->id >= HCI_MAX_PROTO)
-+ if (hp->id >= HCI_MAX_PROTO)
- return -EINVAL;
-
- write_lock_bh(&hci_task_lock);
-
-- if (!hproto_list[hproto->id])
-- hproto_list[hproto->id] = hproto;
-+ if (!hci_proto[hp->id])
-+ hci_proto[hp->id] = hp;
- else
-- err = -1;
-+ err = -EEXIST;
-
- write_unlock_bh(&hci_task_lock);
-
- return err;
- }
-
--int hci_unregister_proto(struct hci_proto *hproto)
-+int hci_unregister_proto(struct hci_proto *hp)
- {
- int err = 0;
-
-- DBG("%p name %s", hproto, hproto->name);
-+ BT_DBG("%p name %s id %d", hp, hp->name, hp->id);
-
-- if (hproto->id > HCI_MAX_PROTO)
-+ if (hp->id >= HCI_MAX_PROTO)
- return -EINVAL;
-
- write_lock_bh(&hci_task_lock);
-
-- if (hproto_list[hproto->id])
-- hproto_list[hproto->id] = NULL;
-+ if (hci_proto[hp->id])
-+ hci_proto[hp->id] = NULL;
- else
- err = -ENOENT;
-
-@@ -1070,10 +966,14 @@
- return -ENODEV;
- }
-
-- DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-+ BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
-+
-+ if (atomic_read(&hdev->promisc)) {
-+ /* Time stamp */
-+ do_gettimeofday(&skb->stamp);
-
-- if (hdev->flags & HCI_SOCK)
- hci_send_to_sock(hdev, skb);
-+ }
-
- /* Get rid of skb owner, prior to sending to the driver. */
- skb_orphan(skb);
-@@ -1081,128 +981,6 @@
- return hdev->send(skb);
- }
-
--/* Connection scheduler */
--static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
--{
-- struct conn_hash *h = &hdev->conn_hash;
-- struct hci_conn *conn = NULL;
-- int num = 0, min = 0xffff;
-- struct list_head *p;
--
-- conn_hash_lock(h);
-- list_for_each(p, &h->list) {
-- register struct hci_conn *c;
--
-- c = list_entry(p, struct hci_conn, list);
--
-- if (c->type != type || skb_queue_empty(&c->data_q))
-- continue;
-- num++;
--
-- if (c->sent < min) {
-- min = c->sent;
-- conn = c;
-- }
-- }
-- conn_hash_unlock(h);
--
-- if (conn) {
-- int q = hdev->acl_cnt / num;
-- *quote = q ? q : 1;
-- } else
-- *quote = 0;
--
-- DBG("conn %p quote %d", conn, *quote);
--
-- return conn;
--}
--
--static inline void hci_sched_acl(struct hci_dev *hdev)
--{
-- struct hci_conn *conn;
-- struct sk_buff *skb;
-- int quote;
--
-- DBG("%s", hdev->name);
--
-- while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, &quote))) {
-- while (quote && (skb = skb_dequeue(&conn->data_q))) {
-- DBG("skb %p len %d", skb, skb->len);
--
-- hci_send_frame(skb);
--
-- conn->sent++;
-- hdev->acl_cnt--;
-- quote--;
-- }
-- }
--}
--
--/* Schedule SCO */
--static inline void hci_sched_sco(struct hci_dev *hdev)
--{
-- /* FIXME: For now we queue SCO packets to the raw queue
--
-- while (hdev->sco_cnt && (skb = skb_dequeue(&conn->data_q))) {
-- hci_send_frame(skb);
-- conn->sco_sent++;
-- hdev->sco_cnt--;
-- }
-- */
--}
--
--/* Get data from the previously sent command */
--static void * hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
--{
-- hci_command_hdr *hc;
--
-- if (!hdev->sent_cmd)
-- return NULL;
--
-- hc = (void *) hdev->sent_cmd->data;
--
-- if (hc->opcode != __cpu_to_le16(cmd_opcode_pack(ogf, ocf)))
-- return NULL;
--
-- DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
--
-- return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
--}
--
--/* Send raw HCI frame */
--int hci_send_raw(struct sk_buff *skb)
--{
-- struct hci_dev *hdev = (struct hci_dev *) skb->dev;
--
-- if (!hdev) {
-- kfree_skb(skb);
-- return -ENODEV;
-- }
--
-- DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
--
-- if (hdev->flags & HCI_NORMAL) {
-- /* Queue frame according it's type */
-- switch (skb->pkt_type) {
-- case HCI_COMMAND_PKT:
-- skb_queue_tail(&hdev->cmd_q, skb);
-- hci_sched_cmd(hdev);
-- return 0;
--
-- case HCI_ACLDATA_PKT:
-- case HCI_SCODATA_PKT:
-- /* FIXME:
-- * Check header here and queue to apropriate connection.
-- */
-- break;
-- }
-- }
--
-- skb_queue_tail(&hdev->raw_q, skb);
-- hci_sched_tx(hdev);
-- return 0;
--}
--
- /* Send HCI command */
- int hci_send_cmd(struct hci_dev *hdev, __u16 ogf, __u16 ocf, __u32 plen, void *param)
- {
-@@ -1210,10 +988,10 @@
- hci_command_hdr *hc;
- struct sk_buff *skb;
-
-- DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
-+ BT_DBG("%s ogf 0x%x ocf 0x%x plen %d", hdev->name, ogf, ocf, plen);
-
- if (!(skb = bluez_skb_alloc(len, GFP_ATOMIC))) {
-- ERR("%s Can't allocate memory for HCI command", hdev->name);
-+ BT_ERR("%s Can't allocate memory for HCI command", hdev->name);
- return -ENOMEM;
- }
-
-@@ -1224,7 +1002,7 @@
- if (plen)
- memcpy(skb_put(skb, plen), param, plen);
-
-- DBG("skb len %d", skb->len);
-+ BT_DBG("skb len %d", skb->len);
-
- skb->pkt_type = HCI_COMMAND_PKT;
- skb->dev = (void *) hdev;
-@@ -1234,10 +1012,28 @@
- return 0;
- }
-
-+/* Get data from the previously sent command */
-+void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 ogf, __u16 ocf)
-+{
-+ hci_command_hdr *hc;
-+
-+ if (!hdev->sent_cmd)
-+ return NULL;
-+
-+ hc = (void *) hdev->sent_cmd->data;
-+
-+ if (hc->opcode != __cpu_to_le16(cmd_opcode_pack(ogf, ocf)))
-+ return NULL;
-+
-+ BT_DBG("%s ogf 0x%x ocf 0x%x", hdev->name, ogf, ocf);
-+
-+ return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE;
-+}
-+
- /* Send ACL data */
- static void hci_add_acl_hdr(struct sk_buff *skb, __u16 handle, __u16 flags)
- {
-- int len = skb->len;
-+ int len = skb->len;
- hci_acl_hdr *ah;
-
- ah = (hci_acl_hdr *) skb_push(skb, HCI_ACL_HDR_SIZE);
-@@ -1252,7 +1048,7 @@
- struct hci_dev *hdev = conn->hdev;
- struct sk_buff *list;
-
-- DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
-+ BT_DBG("%s conn %p flags 0x%x", hdev->name, conn, flags);
-
- skb->dev = (void *) hdev;
- skb->pkt_type = HCI_ACLDATA_PKT;
-@@ -1260,12 +1056,12 @@
-
- if (!(list = skb_shinfo(skb)->frag_list)) {
- /* Non fragmented */
-- DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
-+ BT_DBG("%s nonfrag skb %p len %d", hdev->name, skb, skb->len);
-
- skb_queue_tail(&conn->data_q, skb);
- } else {
- /* Fragmented */
-- DBG("%s frag %p len %d", hdev->name, skb, skb->len);
-+ BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
-
- skb_shinfo(skb)->frag_list = NULL;
-
-@@ -1280,7 +1076,7 @@
- skb->pkt_type = HCI_ACLDATA_PKT;
- hci_add_acl_hdr(skb, conn->handle, flags | ACL_CONT);
-
-- DBG("%s frag %p len %d", hdev->name, skb, skb->len);
-+ BT_DBG("%s frag %p len %d", hdev->name, skb, skb->len);
-
- __skb_queue_tail(&conn->data_q, skb);
- } while (list);
-@@ -1298,7 +1094,7 @@
- struct hci_dev *hdev = conn->hdev;
- hci_sco_hdr hs;
-
-- DBG("%s len %d", hdev->name, skb->len);
-+ BT_DBG("%s len %d", hdev->name, skb->len);
-
- if (skb->len > hdev->sco_mtu) {
- kfree_skb(skb);
-@@ -1315,544 +1111,136 @@
- skb->pkt_type = HCI_SCODATA_PKT;
- skb_queue_tail(&conn->data_q, skb);
- hci_sched_tx(hdev);
--
- return 0;
- }
-
--/* Handle HCI Event packets */
--
--/* Command Complete OGF LINK_CTL */
--static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
--{
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Complete OGF LINK_POLICY */
--static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
--{
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s: Command complete: ogf LINK_POLICY ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Complete OGF HOST_CTL */
--static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
--{
-- __u8 status, param;
-- void *sent;
--
--
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- case OCF_RESET:
-- status = *((__u8 *) skb->data);
--
-- hci_req_complete(hdev, status);
-- break;
--
-- case OCF_SET_EVENT_FLT:
-- status = *((__u8 *) skb->data);
--
-- if (status) {
-- DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
-- } else {
-- DBG("%s SET_EVENT_FLT succeseful", hdev->name);
-- }
-- break;
--
-- case OCF_WRITE_AUTH_ENABLE:
-- if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE)))
-- break;
--
-- status = *((__u8 *) skb->data);
-- param = *((__u8 *) sent);
-+/* ---- HCI TX task (outgoing data) ---- */
-
-- if (!status) {
-- if (param == AUTH_ENABLED)
-- hdev->flags |= HCI_AUTH;
-- else
-- hdev->flags &= ~HCI_AUTH;
-- }
-- hci_req_complete(hdev, status);
-- break;
--
-- case OCF_WRITE_CA_TIMEOUT:
-- status = *((__u8 *) skb->data);
--
-- if (status) {
-- DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
-- } else {
-- DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
-- }
-- break;
--
-- case OCF_WRITE_PG_TIMEOUT:
-- status = *((__u8 *) skb->data);
--
-- if (status) {
-- DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
-- } else {
-- DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
-- }
-- break;
--
-- case OCF_WRITE_SCAN_ENABLE:
-- if (!(sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE)))
-- break;
-- status = *((__u8 *) skb->data);
-- param = *((__u8 *) sent);
--
-- DBG("param 0x%x", param);
--
-- if (!status) {
-- switch (param) {
-- case IS_ENA_PS_ENA:
-- hdev->flags |= HCI_PSCAN | HCI_ISCAN;
-- break;
--
-- case IS_ENA_PS_DIS:
-- hdev->flags &= ~HCI_PSCAN;
-- hdev->flags |= HCI_ISCAN;
-- break;
--
-- case IS_DIS_PS_ENA:
-- hdev->flags &= ~HCI_ISCAN;
-- hdev->flags |= HCI_PSCAN;
-- break;
--
-- default:
-- hdev->flags &= ~(HCI_ISCAN | HCI_PSCAN);
-- break;
-- };
-- }
-- hci_req_complete(hdev, status);
-- break;
--
-- default:
-- DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Complete OGF INFO_PARAM */
--static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+/* HCI Connection scheduler */
-+static inline struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type, int *quote)
- {
-- read_local_features_rp *lf;
-- read_buffer_size_rp *bs;
-- read_bd_addr_rp *ba;
--
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- case OCF_READ_LOCAL_FEATURES:
-- lf = (read_local_features_rp *) skb->data;
--
-- if (lf->status) {
-- DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
-- break;
-- }
--
-- memcpy(hdev->features, lf->features, sizeof(hdev->features));
--
-- /* Adjust default settings according to features
-- * supported by device. */
-- if (hdev->features[0] & LMP_3SLOT)
-- hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
--
-- if (hdev->features[0] & LMP_5SLOT)
-- hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
--
-- DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
--
-- break;
--
-- case OCF_READ_BUFFER_SIZE:
-- bs = (read_buffer_size_rp *) skb->data;
--
-- if (bs->status) {
-- DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
-- break;
-- }
--
-- hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
-- hdev->sco_mtu = bs->sco_mtu;
-- hdev->acl_max = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
-- hdev->sco_max = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
--
-- DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
-- hdev->acl_mtu, hdev->sco_mtu, hdev->acl_max, hdev->sco_max);
-+ struct conn_hash *h = &hdev->conn_hash;
-+ struct hci_conn *conn = NULL;
-+ int num = 0, min = ~0;
-+ struct list_head *p;
-
-- break;
-+ /* We don't have to lock device here. Connections are always
-+ * added and removed with TX task disabled. */
-+ list_for_each(p, &h->list) {
-+ struct hci_conn *c;
-+ c = list_entry(p, struct hci_conn, list);
-
-- case OCF_READ_BD_ADDR:
-- ba = (read_bd_addr_rp *) skb->data;
-+ if (c->type != type || c->state != BT_CONNECTED
-+ || skb_queue_empty(&c->data_q))
-+ continue;
-+ num++;
-
-- if (!ba->status) {
-- bacpy(&hdev->bdaddr, &ba->bdaddr);
-- } else {
-- DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
-+ if (c->sent < min) {
-+ min = c->sent;
-+ conn = c;
- }
-+ }
-
-- hci_req_complete(hdev, ba->status);
-- break;
-+ if (conn) {
-+ int cnt = (type == ACL_LINK ? hdev->acl_cnt : hdev->sco_cnt);
-+ int q = cnt / num;
-+ *quote = q ? q : 1;
-+ } else
-+ *quote = 0;
-
-- default:
-- DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-- break;
-- };
-+ BT_DBG("conn %p quote %d", conn, *quote);
-+ return conn;
- }
-
--/* Command Status OGF LINK_CTL */
--static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+static inline void hci_acl_tx_to(struct hci_dev *hdev)
- {
-- struct hci_proto * hp;
--
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- case OCF_CREATE_CONN:
-- if (status) {
-- create_conn_cp *cc = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
--
-- if (!cc)
-- break;
--
-- DBG("%s Create connection error: status 0x%x %s", hdev->name,
-- status, batostr(&cc->bdaddr));
-+ struct conn_hash *h = &hdev->conn_hash;
-+ struct list_head *p;
-+ struct hci_conn *c;
-
-- /* Notify upper protocols */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm) {
-- tasklet_disable(&hdev->tx_task);
-- hp->connect_cfm(hdev, &cc->bdaddr, status, NULL);
-- tasklet_enable(&hdev->tx_task);
-- }
-- }
-- break;
-+ BT_ERR("%s ACL tx timeout", hdev->name);
-
-- case OCF_INQUIRY:
-- if (status) {
-- DBG("%s Inquiry error: status 0x%x", hdev->name, status);
-- hci_req_complete(hdev, status);
-+ /* Kill stalled connections */
-+ list_for_each(p, &h->list) {
-+ c = list_entry(p, struct hci_conn, list);
-+ if (c->type == ACL_LINK && c->sent) {
-+ BT_ERR("%s killing stalled ACL connection %s",
-+ hdev->name, batostr(&c->dst));
-+ hci_acl_disconn(c, 0x13);
- }
-- break;
--
-- default:
-- DBG("%s Command status: ogf LINK_CTL ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Status OGF LINK_POLICY */
--static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
--{
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Status OGF HOST_CTL */
--static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
--{
-- DBG("%s ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Command Status OGF INFO_PARAM */
--static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
--{
-- DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
--
-- switch (ocf) {
-- default:
-- DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-- break;
-- };
--}
--
--/* Inquiry Complete */
--static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
--{
-- __u8 status = *((__u8 *) skb->data);
--
-- DBG("%s status %d", hdev->name, status);
--
-- hci_req_complete(hdev, status);
-+ }
- }
-
--/* Inquiry Result */
--static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+static inline void hci_sched_acl(struct hci_dev *hdev)
- {
-- inquiry_info *info = (inquiry_info *) (skb->data + 1);
-- int num_rsp = *((__u8 *) skb->data);
--
-- DBG("%s num_rsp %d", hdev->name, num_rsp);
-+ struct hci_conn *conn;
-+ struct sk_buff *skb;
-+ int quote;
-
-- for (; num_rsp; num_rsp--)
-- inquiry_cache_update(&hdev->inq_cache, info++);
--}
-+ BT_DBG("%s", hdev->name);
-
--/* Connect Request */
--static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
--{
-- evt_conn_request *cr = (evt_conn_request *) skb->data;
-- struct hci_proto *hp;
-- accept_conn_req_cp ac;
-- int accept = 0;
-+ /* ACL tx timeout must be longer than maximum
-+ * link supervision timeout (40.9 seconds) */
-+ if (!hdev->acl_cnt && (jiffies - hdev->acl_last_tx) > (HZ * 45))
-+ hci_acl_tx_to(hdev);
-
-- DBG("%s Connection request: %s type 0x%x", hdev->name, batostr(&cr->bdaddr), cr->link_type);
-+ while (hdev->acl_cnt && (conn = hci_low_sent(hdev, ACL_LINK, &quote))) {
-+ while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
-+ BT_DBG("skb %p len %d", skb, skb->len);
-+ hci_send_frame(skb);
-+ hdev->acl_last_tx = jiffies;
-
-- /* Notify upper protocols */
-- if (cr->link_type == ACL_LINK) {
-- /* ACL link notify L2CAP */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_ind) {
-- tasklet_disable(&hdev->tx_task);
-- accept = hp->connect_ind(hdev, &cr->bdaddr);
-- tasklet_enable(&hdev->tx_task);
-+ hdev->acl_cnt--;
-+ conn->sent++;
- }
-- } else {
-- /* SCO link (no notification) */
-- /* FIXME: Should be accept it here or let the requester (app) accept it ? */
-- accept = 1;
-- }
--
-- if (accept) {
-- /* Connection accepted by upper layer */
-- bacpy(&ac.bdaddr, &cr->bdaddr);
-- ac.role = 0x01; /* Remain slave */
-- hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ, ACCEPT_CONN_REQ_CP_SIZE, &ac);
-- } else {
-- /* Connection rejected by upper layer */
-- /* FIXME:
-- * Should we use HCI reject here ?
-- */
-- return;
- }
- }
-
--/* Connect Complete */
--static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+/* Schedule SCO */
-+static inline void hci_sched_sco(struct hci_dev *hdev)
- {
-- evt_conn_complete *cc = (evt_conn_complete *) skb->data;
-- struct hci_conn *conn = NULL;
-- struct hci_proto *hp;
--
-- DBG("%s", hdev->name);
--
-- tasklet_disable(&hdev->tx_task);
--
-- if (!cc->status)
-- conn = hci_conn_add(hdev, __le16_to_cpu(cc->handle), cc->link_type, &cc->bdaddr);
-+ struct hci_conn *conn;
-+ struct sk_buff *skb;
-+ int quote;
-
-- /* Notify upper protocols */
-- if (cc->link_type == ACL_LINK) {
-- /* ACL link notify L2CAP layer */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->connect_cfm)
-- hp->connect_cfm(hdev, &cc->bdaddr, cc->status, conn);
-- } else {
-- /* SCO link (no notification) */
-- }
-+ BT_DBG("%s", hdev->name);
-
-- tasklet_enable(&hdev->tx_task);
--}
-+ while (hdev->sco_cnt && (conn = hci_low_sent(hdev, SCO_LINK, &quote))) {
-+ while (quote-- && (skb = skb_dequeue(&conn->data_q))) {
-+ BT_DBG("skb %p len %d", skb, skb->len);
-+ hci_send_frame(skb);
-
--/* Disconnect Complete */
--static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
--{
-- evt_disconn_complete *dc = (evt_disconn_complete *) skb->data;
-- struct hci_conn *conn = NULL;
-- struct hci_proto *hp;
-- __u16 handle = __le16_to_cpu(dc->handle);
--
-- DBG("%s", hdev->name);
--
-- if (!dc->status && (conn = conn_hash_lookup(&hdev->conn_hash, handle))) {
-- tasklet_disable(&hdev->tx_task);
--
-- /* Notify upper protocols */
-- if (conn->type == ACL_LINK) {
-- /* ACL link notify L2CAP layer */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->disconn_ind)
-- hp->disconn_ind(conn, dc->reason);
-- } else {
-- /* SCO link (no notification) */
-+ conn->sent++;
-+ if (conn->sent == ~0)
-+ conn->sent = 0;
- }
--
-- hci_conn_del(hdev, conn);
--
-- tasklet_enable(&hdev->tx_task);
- }
- }
-
--/* Number of completed packets */
--static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+static void hci_tx_task(unsigned long arg)
- {
-- evt_num_comp_pkts *nc = (evt_num_comp_pkts *) skb->data;
-- __u16 *ptr;
-- int i;
--
-- skb_pull(skb, EVT_NUM_COMP_PKTS_SIZE);
--
-- DBG("%s num_hndl %d", hdev->name, nc->num_hndl);
-+ struct hci_dev *hdev = (struct hci_dev *) arg;
-+ struct sk_buff *skb;
-
-- if (skb->len < nc->num_hndl * 4) {
-- DBG("%s bad parameters", hdev->name);
-- return;
-- }
-+ read_lock(&hci_task_lock);
-
-- tasklet_disable(&hdev->tx_task);
-+ BT_DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
-
-- for (i = 0, ptr = (__u16 *) skb->data; i < nc->num_hndl; i++) {
-- struct hci_conn *conn;
-- __u16 handle, count;
-+ /* Schedule queues and send stuff to HCI driver */
-
-- handle = __le16_to_cpu(get_unaligned(ptr++));
-- count = __le16_to_cpu(get_unaligned(ptr++));
-+ hci_sched_acl(hdev);
-
-- hdev->acl_cnt += count;
-+ hci_sched_sco(hdev);
-
-- if ((conn = conn_hash_lookup(&hdev->conn_hash, handle)))
-- conn->sent -= count;
-- }
-+ /* Send next queued raw (unknown type) packet */
-+ while ((skb = skb_dequeue(&hdev->raw_q)))
-+ hci_send_frame(skb);
-
-- tasklet_enable(&hdev->tx_task);
--
-- hci_sched_tx(hdev);
-+ read_unlock(&hci_task_lock);
- }
-
--static inline void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
--{
-- hci_event_hdr *he = (hci_event_hdr *) skb->data;
-- evt_cmd_status *cs;
-- evt_cmd_complete *ec;
-- __u16 opcode, ocf, ogf;
--
-- skb_pull(skb, HCI_EVENT_HDR_SIZE);
--
-- DBG("%s evt 0x%x", hdev->name, he->evt);
--
-- switch (he->evt) {
-- case EVT_NUM_COMP_PKTS:
-- hci_num_comp_pkts_evt(hdev, skb);
-- break;
--
-- case EVT_INQUIRY_COMPLETE:
-- hci_inquiry_complete_evt(hdev, skb);
-- break;
--
-- case EVT_INQUIRY_RESULT:
-- hci_inquiry_result_evt(hdev, skb);
-- break;
--
-- case EVT_CONN_REQUEST:
-- hci_conn_request_evt(hdev, skb);
-- break;
--
-- case EVT_CONN_COMPLETE:
-- hci_conn_complete_evt(hdev, skb);
-- break;
--
-- case EVT_DISCONN_COMPLETE:
-- hci_disconn_complete_evt(hdev, skb);
-- break;
--
-- case EVT_CMD_STATUS:
-- cs = (evt_cmd_status *) skb->data;
-- skb_pull(skb, EVT_CMD_STATUS_SIZE);
--
-- opcode = __le16_to_cpu(cs->opcode);
-- ogf = cmd_opcode_ogf(opcode);
-- ocf = cmd_opcode_ocf(opcode);
--
-- switch (ogf) {
-- case OGF_INFO_PARAM:
-- hci_cs_info_param(hdev, ocf, cs->status);
-- break;
--
-- case OGF_HOST_CTL:
-- hci_cs_host_ctl(hdev, ocf, cs->status);
-- break;
--
-- case OGF_LINK_CTL:
-- hci_cs_link_ctl(hdev, ocf, cs->status);
-- break;
--
-- case OGF_LINK_POLICY:
-- hci_cs_link_policy(hdev, ocf, cs->status);
-- break;
--
-- default:
-- DBG("%s Command Status OGF %x", hdev->name, ogf);
-- break;
-- };
--
-- if (cs->ncmd) {
-- atomic_set(&hdev->cmd_cnt, 1);
-- if (!skb_queue_empty(&hdev->cmd_q))
-- hci_sched_cmd(hdev);
-- }
-- break;
--
-- case EVT_CMD_COMPLETE:
-- ec = (evt_cmd_complete *) skb->data;
-- skb_pull(skb, EVT_CMD_COMPLETE_SIZE);
--
-- opcode = __le16_to_cpu(ec->opcode);
-- ogf = cmd_opcode_ogf(opcode);
-- ocf = cmd_opcode_ocf(opcode);
--
-- switch (ogf) {
-- case OGF_INFO_PARAM:
-- hci_cc_info_param(hdev, ocf, skb);
-- break;
--
-- case OGF_HOST_CTL:
-- hci_cc_host_ctl(hdev, ocf, skb);
-- break;
--
-- case OGF_LINK_CTL:
-- hci_cc_link_ctl(hdev, ocf, skb);
-- break;
--
-- case OGF_LINK_POLICY:
-- hci_cc_link_policy(hdev, ocf, skb);
-- break;
-
-- default:
-- DBG("%s Command Completed OGF %x", hdev->name, ogf);
-- break;
-- };
--
-- if (ec->ncmd) {
-- atomic_set(&hdev->cmd_cnt, 1);
-- if (!skb_queue_empty(&hdev->cmd_q))
-- hci_sched_cmd(hdev);
-- }
-- break;
-- };
--
-- kfree_skb(skb);
-- hdev->stat.evt_rx++;
--}
-+/* ----- HCI RX task (incomming data proccessing) ----- */
-
- /* ACL data packet */
- static inline void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb)
-@@ -1867,51 +1255,86 @@
- flags = acl_flags(handle);
- handle = acl_handle(handle);
-
-- DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
-+ BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, handle, flags);
-+
-+ hdev->stat.acl_rx++;
-
-- if ((conn = conn_hash_lookup(&hdev->conn_hash, handle))) {
-+ hci_dev_lock(hdev);
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ hci_dev_unlock(hdev);
-+
-+ if (conn) {
- register struct hci_proto *hp;
-
- /* Send to upper protocol */
-- if ((hp = GET_HPROTO(HCI_PROTO_L2CAP)) && hp->recv_acldata) {
-+ if ((hp = hci_proto[HCI_PROTO_L2CAP]) && hp->recv_acldata) {
- hp->recv_acldata(conn, skb, flags);
-- goto sent;
-+ return;
- }
- } else {
-- ERR("%s ACL packet for unknown connection handle %d", hdev->name, handle);
-+ BT_ERR("%s ACL packet for unknown connection handle %d",
-+ hdev->name, handle);
- }
-
- kfree_skb(skb);
--sent:
-- hdev->stat.acl_rx++;
- }
-
- /* SCO data packet */
- static inline void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb)
- {
-- DBG("%s len %d", hdev->name, skb->len);
-+ hci_sco_hdr *sh = (void *) skb->data;
-+ struct hci_conn *conn;
-+ __u16 handle;
-+
-+ skb_pull(skb, HCI_SCO_HDR_SIZE);
-+
-+ handle = __le16_to_cpu(sh->handle);
-+
-+ BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle);
-
-- kfree_skb(skb);
- hdev->stat.sco_rx++;
-+
-+ hci_dev_lock(hdev);
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ hci_dev_unlock(hdev);
-+
-+ if (conn) {
-+ register struct hci_proto *hp;
-+
-+ /* Send to upper protocol */
-+ if ((hp = hci_proto[HCI_PROTO_SCO]) && hp->recv_scodata) {
-+ hp->recv_scodata(conn, skb);
-+ return;
-+ }
-+ } else {
-+ BT_ERR("%s SCO packet for unknown connection handle %d",
-+ hdev->name, handle);
-+ }
-+
-+ kfree_skb(skb);
- }
-
--/* ----- HCI tasks ----- */
- void hci_rx_task(unsigned long arg)
- {
- struct hci_dev *hdev = (struct hci_dev *) arg;
- struct sk_buff *skb;
-
-- DBG("%s", hdev->name);
-+ BT_DBG("%s", hdev->name);
-
- read_lock(&hci_task_lock);
-
- while ((skb = skb_dequeue(&hdev->rx_q))) {
-- if (hdev->flags & HCI_SOCK) {
-+ if (atomic_read(&hdev->promisc)) {
- /* Send copy to the sockets */
- hci_send_to_sock(hdev, skb);
- }
-
-- if (hdev->flags & HCI_INIT) {
-+ if (test_bit(HCI_RAW, &hdev->flags)) {
-+ kfree_skb(skb);
-+ continue;
-+ }
-+
-+ if (test_bit(HCI_INIT, &hdev->flags)) {
- /* Don't process data packets in this states. */
- switch (skb->pkt_type) {
- case HCI_ACLDATA_PKT:
-@@ -1921,64 +1344,43 @@
- };
- }
-
-- if (hdev->flags & HCI_NORMAL) {
-- /* Process frame */
-- switch (skb->pkt_type) {
-- case HCI_EVENT_PKT:
-- hci_event_packet(hdev, skb);
-- break;
-+ /* Process frame */
-+ switch (skb->pkt_type) {
-+ case HCI_EVENT_PKT:
-+ hci_event_packet(hdev, skb);
-+ break;
-
-- case HCI_ACLDATA_PKT:
-- DBG("%s ACL data packet", hdev->name);
-- hci_acldata_packet(hdev, skb);
-- break;
-+ case HCI_ACLDATA_PKT:
-+ BT_DBG("%s ACL data packet", hdev->name);
-+ hci_acldata_packet(hdev, skb);
-+ break;
-
-- case HCI_SCODATA_PKT:
-- DBG("%s SCO data packet", hdev->name);
-- hci_scodata_packet(hdev, skb);
-- break;
-+ case HCI_SCODATA_PKT:
-+ BT_DBG("%s SCO data packet", hdev->name);
-+ hci_scodata_packet(hdev, skb);
-+ break;
-
-- default:
-- kfree_skb(skb);
-- break;
-- };
-- } else {
-+ default:
- kfree_skb(skb);
-+ break;
- }
- }
-
- read_unlock(&hci_task_lock);
- }
-
--static void hci_tx_task(unsigned long arg)
--{
-- struct hci_dev *hdev = (struct hci_dev *) arg;
-- struct sk_buff *skb;
--
-- read_lock(&hci_task_lock);
--
-- DBG("%s acl %d sco %d", hdev->name, hdev->acl_cnt, hdev->sco_cnt);
--
-- /* Schedule queues and send stuff to HCI driver */
--
-- hci_sched_acl(hdev);
--
-- hci_sched_sco(hdev);
--
-- /* Send next queued raw (unknown type) packet */
-- while ((skb = skb_dequeue(&hdev->raw_q)))
-- hci_send_frame(skb);
--
-- read_unlock(&hci_task_lock);
--}
--
- static void hci_cmd_task(unsigned long arg)
- {
- struct hci_dev *hdev = (struct hci_dev *) arg;
- struct sk_buff *skb;
-
-- DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
-+ BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
-
-+ if (!atomic_read(&hdev->cmd_cnt) && (jiffies - hdev->cmd_last_tx) > HZ) {
-+ BT_ERR("%s command tx timeout", hdev->name);
-+ atomic_set(&hdev->cmd_cnt, 1);
-+ }
-+
- /* Send queued commands */
- if (atomic_read(&hdev->cmd_cnt) && (skb = skb_dequeue(&hdev->cmd_q))) {
- if (hdev->sent_cmd)
-@@ -1987,6 +1389,7 @@
- if ((hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC))) {
- atomic_dec(&hdev->cmd_cnt);
- hci_send_frame(skb);
-+ hdev->cmd_last_tx = jiffies;
- } else {
- skb_queue_head(&hdev->cmd_q, skb);
- hci_sched_cmd(hdev);
-@@ -1994,33 +1397,10 @@
- }
- }
-
--/* Receive frame from HCI drivers */
--int hci_recv_frame(struct sk_buff *skb)
--{
-- struct hci_dev *hdev = (struct hci_dev *) skb->dev;
--
-- if (!hdev || !(hdev->flags & (HCI_UP | HCI_INIT))) {
-- kfree_skb(skb);
-- return -1;
-- }
--
-- DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
--
-- /* Incomming skb */
-- bluez_cb(skb)->incomming = 1;
--
-- /* Queue frame for rx task */
-- skb_queue_tail(&hdev->rx_q, skb);
-- hci_sched_rx(hdev);
--
-- return 0;
--}
-+/* ---- Initialization ---- */
-
- int hci_core_init(void)
- {
-- /* Init locks */
-- spin_lock_init(&hdev_list_lock);
--
- return 0;
- }
-
-@@ -2028,5 +1408,3 @@
- {
- return 0;
- }
--
--MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/hci_event.c linux-2.4.18-mh9/net/bluetooth/hci_event.c
---- linux-2.4.18/net/bluetooth/hci_event.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/hci_event.c Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,927 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * HCI Events.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/notifier.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+
-+#ifndef HCI_CORE_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+/* Handle HCI Event packets */
-+
-+/* Command Complete OGF LINK_CTL */
-+static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+{
-+ __u8 status;
-+
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_INQUIRY_CANCEL:
-+ status = *((__u8 *) skb->data);
-+
-+ if (status) {
-+ BT_DBG("%s Inquiry cancel error: status 0x%x", hdev->name, status);
-+ } else {
-+ clear_bit(HCI_INQUIRY, &hdev->flags);
-+ hci_req_complete(hdev, status);
-+ }
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Complete OGF LINK_POLICY */
-+static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+{
-+ struct hci_conn *conn;
-+ role_discovery_rp *rd;
-+
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_ROLE_DISCOVERY:
-+ rd = (void *) skb->data;
-+
-+ if (rd->status)
-+ break;
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_handle(hdev, __le16_to_cpu(rd->handle));
-+ if (conn) {
-+ if (rd->role)
-+ conn->link_mode &= ~HCI_LM_MASTER;
-+ else
-+ conn->link_mode |= HCI_LM_MASTER;
-+ }
-+
-+ hci_dev_unlock(hdev);
-+ break;
-+
-+ default:
-+ BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x",
-+ hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Complete OGF HOST_CTL */
-+static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+{
-+ __u8 status, param;
-+ __u16 setting;
-+ read_voice_setting_rp *vs;
-+ void *sent;
-+
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_RESET:
-+ status = *((__u8 *) skb->data);
-+ hci_req_complete(hdev, status);
-+ break;
-+
-+ case OCF_SET_EVENT_FLT:
-+ status = *((__u8 *) skb->data);
-+ if (status) {
-+ BT_DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
-+ } else {
-+ BT_DBG("%s SET_EVENT_FLT succeseful", hdev->name);
-+ }
-+ break;
-+
-+ case OCF_WRITE_AUTH_ENABLE:
-+ sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE);
-+ if (!sent)
-+ break;
-+
-+ status = *((__u8 *) skb->data);
-+ param = *((__u8 *) sent);
-+
-+ if (!status) {
-+ if (param == AUTH_ENABLED)
-+ set_bit(HCI_AUTH, &hdev->flags);
-+ else
-+ clear_bit(HCI_AUTH, &hdev->flags);
-+ }
-+ hci_req_complete(hdev, status);
-+ break;
-+
-+ case OCF_WRITE_ENCRYPT_MODE:
-+ sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE);
-+ if (!sent)
-+ break;
-+
-+ status = *((__u8 *) skb->data);
-+ param = *((__u8 *) sent);
-+
-+ if (!status) {
-+ if (param)
-+ set_bit(HCI_ENCRYPT, &hdev->flags);
-+ else
-+ clear_bit(HCI_ENCRYPT, &hdev->flags);
-+ }
-+ hci_req_complete(hdev, status);
-+ break;
-+
-+ case OCF_WRITE_CA_TIMEOUT:
-+ status = *((__u8 *) skb->data);
-+ if (status) {
-+ BT_DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
-+ } else {
-+ BT_DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
-+ }
-+ break;
-+
-+ case OCF_WRITE_PG_TIMEOUT:
-+ status = *((__u8 *) skb->data);
-+ if (status) {
-+ BT_DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
-+ } else {
-+ BT_DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
-+ }
-+ break;
-+
-+ case OCF_WRITE_SCAN_ENABLE:
-+ sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE);
-+ if (!sent)
-+ break;
-+
-+ status = *((__u8 *) skb->data);
-+ param = *((__u8 *) sent);
-+
-+ BT_DBG("param 0x%x", param);
-+
-+ if (!status) {
-+ clear_bit(HCI_PSCAN, &hdev->flags);
-+ clear_bit(HCI_ISCAN, &hdev->flags);
-+ if (param & SCAN_INQUIRY)
-+ set_bit(HCI_ISCAN, &hdev->flags);
-+
-+ if (param & SCAN_PAGE)
-+ set_bit(HCI_PSCAN, &hdev->flags);
-+ }
-+ hci_req_complete(hdev, status);
-+ break;
-+
-+ case OCF_READ_VOICE_SETTING:
-+ vs = (read_voice_setting_rp *) skb->data;
-+
-+ if (vs->status) {
-+ BT_DBG("%s READ_VOICE_SETTING failed %d", hdev->name, vc->status);
-+ break;
-+ }
-+
-+ setting = __le16_to_cpu(vs->voice_setting);
-+
-+ if (hdev->voice_setting != setting ) {
-+ hdev->voice_setting = setting;
-+
-+ BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
-+
-+ if (hdev->notify)
-+ hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING, 0);
-+ }
-+
-+ break;
-+
-+ case OCF_WRITE_VOICE_SETTING:
-+ sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_VOICE_SETTING);
-+ if (!sent)
-+ break;
-+
-+ status = *((__u8 *) skb->data);
-+ setting = __le16_to_cpu(get_unaligned((__u16 *) sent));
-+
-+ if (!status && hdev->voice_setting != setting) {
-+ hdev->voice_setting = setting;
-+
-+ BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
-+
-+ if (hdev->notify)
-+ hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING, 0);
-+ }
-+ hci_req_complete(hdev, status);
-+ break;
-+
-+ case OCF_HOST_BUFFER_SIZE:
-+ status = *((__u8 *) skb->data);
-+ if (status) {
-+ BT_DBG("%s OCF_BUFFER_SIZE failed %d", hdev->name, status);
-+ hci_req_complete(hdev, status);
-+ }
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Complete OGF INFO_PARAM */
-+static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
-+{
-+ read_local_features_rp *lf;
-+ read_buffer_size_rp *bs;
-+ read_bd_addr_rp *ba;
-+
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_READ_LOCAL_FEATURES:
-+ lf = (read_local_features_rp *) skb->data;
-+
-+ if (lf->status) {
-+ BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
-+ break;
-+ }
-+
-+ memcpy(hdev->features, lf->features, sizeof(hdev->features));
-+
-+ /* Adjust default settings according to features
-+ * supported by device. */
-+ if (hdev->features[0] & LMP_3SLOT)
-+ hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
-+
-+ if (hdev->features[0] & LMP_5SLOT)
-+ hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
-+
-+ if (hdev->features[1] & LMP_HV2)
-+ hdev->pkt_type |= (HCI_HV2);
-+
-+ if (hdev->features[1] & LMP_HV3)
-+ hdev->pkt_type |= (HCI_HV3);
-+
-+ BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name, lf->features[0], lf->features[1], lf->features[2]);
-+
-+ break;
-+
-+ case OCF_READ_BUFFER_SIZE:
-+ bs = (read_buffer_size_rp *) skb->data;
-+
-+ if (bs->status) {
-+ BT_DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
-+ hci_req_complete(hdev, bs->status);
-+ break;
-+ }
-+
-+ hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
-+ hdev->sco_mtu = bs->sco_mtu ? bs->sco_mtu : 64;
-+ hdev->acl_pkts = hdev->acl_cnt = __le16_to_cpu(bs->acl_max_pkt);
-+ hdev->sco_pkts = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
-+
-+ BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
-+ hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
-+
-+ break;
-+
-+ case OCF_READ_BD_ADDR:
-+ ba = (read_bd_addr_rp *) skb->data;
-+
-+ if (!ba->status) {
-+ bacpy(&hdev->bdaddr, &ba->bdaddr);
-+ } else {
-+ BT_DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
-+ }
-+
-+ hci_req_complete(hdev, ba->status);
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Status OGF LINK_CTL */
-+static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
-+{
-+ struct hci_conn *conn;
-+ create_conn_cp *cc = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
-+
-+ if (!cc)
-+ return;
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_ba(hdev, ACL_LINK, &cc->bdaddr);
-+
-+ BT_DBG("%s status 0x%x bdaddr %s conn %p", hdev->name,
-+ status, batostr(&cc->bdaddr), conn);
-+
-+ if (status) {
-+ if (conn) {
-+ conn->state = BT_CLOSED;
-+ hci_proto_connect_cfm(conn, status);
-+ hci_conn_del(conn);
-+ }
-+ } else {
-+ if (!conn) {
-+ conn = hci_conn_add(hdev, ACL_LINK, &cc->bdaddr);
-+ if (conn) {
-+ conn->out = 1;
-+ conn->link_mode |= HCI_LM_MASTER;
-+ } else
-+ BT_ERR("No memmory for new connection");
-+ }
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+{
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ case OCF_CREATE_CONN:
-+ hci_cs_create_conn(hdev, status);
-+ break;
-+
-+ case OCF_ADD_SCO:
-+ if (status) {
-+ struct hci_conn *acl, *sco;
-+ add_sco_cp *cp = hci_sent_cmd_data(hdev,
-+ OGF_LINK_CTL, OCF_ADD_SCO);
-+ __u16 handle;
-+
-+ if (!cp)
-+ break;
-+
-+ handle = __le16_to_cpu(cp->handle);
-+
-+ BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
-+
-+ hci_dev_lock(hdev);
-+
-+ acl = conn_hash_lookup_handle(hdev, handle);
-+ if (acl && (sco = acl->link)) {
-+ sco->state = BT_CLOSED;
-+ hci_proto_connect_cfm(sco, status);
-+ hci_conn_del(sco);
-+ }
-+
-+ hci_dev_unlock(hdev);
-+ }
-+ break;
-+
-+ case OCF_INQUIRY:
-+ if (status) {
-+ BT_DBG("%s Inquiry error: status 0x%x", hdev->name, status);
-+ hci_req_complete(hdev, status);
-+ } else {
-+ set_bit(HCI_INQUIRY, &hdev->flags);
-+ }
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command status: ogf LINK_CTL ocf %x status %d",
-+ hdev->name, ocf, status);
-+ break;
-+ };
-+}
-+
-+/* Command Status OGF LINK_POLICY */
-+static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+{
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ default:
-+ BT_DBG("%s Command status: ogf HOST_POLICY ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Status OGF HOST_CTL */
-+static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+{
-+ BT_DBG("%s ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ default:
-+ BT_DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Command Status OGF INFO_PARAM */
-+static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
-+{
-+ BT_DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
-+
-+ switch (ocf) {
-+ default:
-+ BT_DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
-+ break;
-+ };
-+}
-+
-+/* Inquiry Complete */
-+static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ __u8 status = *((__u8 *) skb->data);
-+
-+ BT_DBG("%s status %d", hdev->name, status);
-+
-+ clear_bit(HCI_INQUIRY, &hdev->flags);
-+ hci_req_complete(hdev, status);
-+}
-+
-+/* Inquiry Result */
-+static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ inquiry_info *info = (inquiry_info *) (skb->data + 1);
-+ int num_rsp = *((__u8 *) skb->data);
-+
-+ BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
-+
-+ hci_dev_lock(hdev);
-+ for (; num_rsp; num_rsp--)
-+ inquiry_cache_update(hdev, info++);
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Connect Request */
-+static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_conn_request *cr = (evt_conn_request *) skb->data;
-+ int mask = hdev->link_mode;
-+
-+ BT_DBG("%s Connection request: %s type 0x%x", hdev->name,
-+ batostr(&cr->bdaddr), cr->link_type);
-+
-+ mask |= hci_proto_connect_ind(hdev, &cr->bdaddr, cr->link_type);
-+
-+ if (mask & HCI_LM_ACCEPT) {
-+ /* Connection accepted */
-+ struct hci_conn *conn;
-+ accept_conn_req_cp ac;
-+
-+ hci_dev_lock(hdev);
-+ conn = conn_hash_lookup_ba(hdev, cr->link_type, &cr->bdaddr);
-+ if (!conn) {
-+ if (!(conn = hci_conn_add(hdev, cr->link_type, &cr->bdaddr))) {
-+ BT_ERR("No memmory for new connection");
-+ hci_dev_unlock(hdev);
-+ return;
-+ }
-+ }
-+ conn->state = BT_CONNECT;
-+ hci_dev_unlock(hdev);
-+
-+ bacpy(&ac.bdaddr, &cr->bdaddr);
-+
-+ if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
-+ ac.role = 0x00; /* Become master */
-+ else
-+ ac.role = 0x01; /* Remain slave */
-+
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ,
-+ ACCEPT_CONN_REQ_CP_SIZE, &ac);
-+ } else {
-+ /* Connection rejected */
-+ reject_conn_req_cp rc;
-+
-+ bacpy(&rc.bdaddr, &cr->bdaddr);
-+ rc.reason = 0x0f;
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_REJECT_CONN_REQ,
-+ REJECT_CONN_REQ_CP_SIZE, &rc);
-+ }
-+}
-+
-+/* Connect Complete */
-+static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_conn_complete *cc = (evt_conn_complete *) skb->data;
-+ struct hci_conn *conn = NULL;
-+
-+ BT_DBG("%s", hdev->name);
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_ba(hdev, cc->link_type, &cc->bdaddr);
-+ if (!conn) {
-+ hci_dev_unlock(hdev);
-+ return;
-+ }
-+
-+ if (!cc->status) {
-+ conn->handle = __le16_to_cpu(cc->handle);
-+ conn->state = BT_CONNECTED;
-+
-+ if (test_bit(HCI_AUTH, &hdev->flags))
-+ conn->link_mode |= HCI_LM_AUTH;
-+
-+ if (test_bit(HCI_ENCRYPT, &hdev->flags))
-+ conn->link_mode |= HCI_LM_ENCRYPT;
-+
-+
-+ /* Set link policy */
-+ if (conn->type == ACL_LINK && hdev->link_policy) {
-+ write_link_policy_cp lp;
-+ lp.handle = cc->handle;
-+ lp.policy = __cpu_to_le16(hdev->link_policy);
-+ hci_send_cmd(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY,
-+ WRITE_LINK_POLICY_CP_SIZE, &lp);
-+ }
-+
-+ /* Set packet type for incomming connection */
-+ if (!conn->out) {
-+ change_conn_ptype_cp cp;
-+ cp.handle = cc->handle;
-+ cp.pkt_type = (conn->type == ACL_LINK) ?
-+ __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK):
-+ __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
-+
-+ hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CHANGE_CONN_PTYPE,
-+ CHANGE_CONN_PTYPE_CP_SIZE, &cp);
-+ }
-+ } else
-+ conn->state = BT_CLOSED;
-+
-+ if (conn->type == ACL_LINK) {
-+ struct hci_conn *sco = conn->link;
-+ if (sco) {
-+ if (!cc->status)
-+ hci_add_sco(sco, conn->handle);
-+ else {
-+ hci_proto_connect_cfm(sco, cc->status);
-+ hci_conn_del(sco);
-+ }
-+ }
-+ }
-+
-+ hci_proto_connect_cfm(conn, cc->status);
-+ if (cc->status)
-+ hci_conn_del(conn);
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Disconnect Complete */
-+static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_disconn_complete *dc = (evt_disconn_complete *) skb->data;
-+ struct hci_conn *conn = NULL;
-+ __u16 handle = __le16_to_cpu(dc->handle);
-+
-+ BT_DBG("%s status %d", hdev->name, dc->status);
-+
-+ if (dc->status)
-+ return;
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ if (conn) {
-+ conn->state = BT_CLOSED;
-+ hci_proto_disconn_ind(conn, dc->reason);
-+ hci_conn_del(conn);
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Number of completed packets */
-+static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_num_comp_pkts *nc = (evt_num_comp_pkts *) skb->data;
-+ __u16 *ptr;
-+ int i;
-+
-+ skb_pull(skb, EVT_NUM_COMP_PKTS_SIZE);
-+
-+ BT_DBG("%s num_hndl %d", hdev->name, nc->num_hndl);
-+
-+ if (skb->len < nc->num_hndl * 4) {
-+ BT_DBG("%s bad parameters", hdev->name);
-+ return;
-+ }
-+
-+ tasklet_disable(&hdev->tx_task);
-+
-+ for (i = 0, ptr = (__u16 *) skb->data; i < nc->num_hndl; i++) {
-+ struct hci_conn *conn;
-+ __u16 handle, count;
-+
-+ handle = __le16_to_cpu(get_unaligned(ptr++));
-+ count = __le16_to_cpu(get_unaligned(ptr++));
-+
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ if (conn) {
-+ conn->sent -= count;
-+
-+ if (conn->type == SCO_LINK) {
-+ if ((hdev->sco_cnt += count) > hdev->sco_pkts)
-+ hdev->sco_cnt = hdev->sco_pkts;
-+ } else {
-+ if ((hdev->acl_cnt += count) > hdev->acl_pkts)
-+ hdev->acl_cnt = hdev->acl_pkts;
-+ }
-+ }
-+ }
-+ hci_sched_tx(hdev);
-+
-+ tasklet_enable(&hdev->tx_task);
-+}
-+
-+/* Role Change */
-+static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_role_change *rc = (evt_role_change *) skb->data;
-+ struct hci_conn *conn = NULL;
-+
-+ BT_DBG("%s status %d", hdev->name, rc->status);
-+
-+ if (rc->status)
-+ return;
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_ba(hdev, ACL_LINK, &rc->bdaddr);
-+ if (conn) {
-+ if (rc->role)
-+ conn->link_mode &= ~HCI_LM_MASTER;
-+ else
-+ conn->link_mode |= HCI_LM_MASTER;
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Authentication Complete */
-+static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_auth_complete *ac = (evt_auth_complete *) skb->data;
-+ struct hci_conn *conn = NULL;
-+ __u16 handle = __le16_to_cpu(ac->handle);
-+
-+ BT_DBG("%s status %d", hdev->name, ac->status);
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ if (conn) {
-+ if (!ac->status)
-+ conn->link_mode |= HCI_LM_AUTH;
-+ clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
-+
-+ hci_proto_auth_cfm(conn, ac->status);
-+
-+ if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
-+ if (!ac->status) {
-+ set_conn_encrypt_cp ce;
-+ ce.handle = __cpu_to_le16(conn->handle);
-+ ce.encrypt = 1;
-+ hci_send_cmd(conn->hdev, OGF_LINK_CTL,
-+ OCF_SET_CONN_ENCRYPT,
-+ SET_CONN_ENCRYPT_CP_SIZE, &ce);
-+ } else {
-+ clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
-+ hci_proto_encrypt_cfm(conn, ac->status);
-+ }
-+ }
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+/* Encryption Change */
-+static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ evt_encrypt_change *ec = (evt_encrypt_change *) skb->data;
-+ struct hci_conn *conn = NULL;
-+ __u16 handle = __le16_to_cpu(ec->handle);
-+
-+ BT_DBG("%s status %d", hdev->name, ec->status);
-+
-+ hci_dev_lock(hdev);
-+
-+ conn = conn_hash_lookup_handle(hdev, handle);
-+ if (conn) {
-+ if (!ec->status) {
-+ if (ec->encrypt)
-+ conn->link_mode |= HCI_LM_ENCRYPT;
-+ else
-+ conn->link_mode &= ~HCI_LM_ENCRYPT;
-+ }
-+ clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
-+
-+ hci_proto_encrypt_cfm(conn, ec->status);
-+ }
-+
-+ hci_dev_unlock(hdev);
-+}
-+
-+void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
-+{
-+ hci_event_hdr *he = (hci_event_hdr *) skb->data;
-+ evt_cmd_status *cs;
-+ evt_cmd_complete *ec;
-+ __u16 opcode, ocf, ogf;
-+
-+ skb_pull(skb, HCI_EVENT_HDR_SIZE);
-+
-+ BT_DBG("%s evt 0x%x", hdev->name, he->evt);
-+
-+ switch (he->evt) {
-+ case EVT_NUM_COMP_PKTS:
-+ hci_num_comp_pkts_evt(hdev, skb);
-+ break;
-+
-+ case EVT_INQUIRY_COMPLETE:
-+ hci_inquiry_complete_evt(hdev, skb);
-+ break;
-+
-+ case EVT_INQUIRY_RESULT:
-+ hci_inquiry_result_evt(hdev, skb);
-+ break;
-+
-+ case EVT_CONN_REQUEST:
-+ hci_conn_request_evt(hdev, skb);
-+ break;
-+
-+ case EVT_CONN_COMPLETE:
-+ hci_conn_complete_evt(hdev, skb);
-+ break;
-+
-+ case EVT_DISCONN_COMPLETE:
-+ hci_disconn_complete_evt(hdev, skb);
-+ break;
-+
-+ case EVT_ROLE_CHANGE:
-+ hci_role_change_evt(hdev, skb);
-+ break;
-+
-+ case EVT_AUTH_COMPLETE:
-+ hci_auth_complete_evt(hdev, skb);
-+ break;
-+
-+ case EVT_ENCRYPT_CHANGE:
-+ hci_encrypt_change_evt(hdev, skb);
-+ break;
-+
-+ case EVT_CMD_STATUS:
-+ cs = (evt_cmd_status *) skb->data;
-+ skb_pull(skb, EVT_CMD_STATUS_SIZE);
-+
-+ opcode = __le16_to_cpu(cs->opcode);
-+ ogf = cmd_opcode_ogf(opcode);
-+ ocf = cmd_opcode_ocf(opcode);
-+
-+ switch (ogf) {
-+ case OGF_INFO_PARAM:
-+ hci_cs_info_param(hdev, ocf, cs->status);
-+ break;
-+
-+ case OGF_HOST_CTL:
-+ hci_cs_host_ctl(hdev, ocf, cs->status);
-+ break;
-+
-+ case OGF_LINK_CTL:
-+ hci_cs_link_ctl(hdev, ocf, cs->status);
-+ break;
-+
-+ case OGF_LINK_POLICY:
-+ hci_cs_link_policy(hdev, ocf, cs->status);
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command Status OGF %x", hdev->name, ogf);
-+ break;
-+ };
-+
-+ if (cs->ncmd) {
-+ atomic_set(&hdev->cmd_cnt, 1);
-+ if (!skb_queue_empty(&hdev->cmd_q))
-+ hci_sched_cmd(hdev);
-+ }
-+ break;
-+
-+ case EVT_CMD_COMPLETE:
-+ ec = (evt_cmd_complete *) skb->data;
-+ skb_pull(skb, EVT_CMD_COMPLETE_SIZE);
-+
-+ opcode = __le16_to_cpu(ec->opcode);
-+ ogf = cmd_opcode_ogf(opcode);
-+ ocf = cmd_opcode_ocf(opcode);
-+
-+ switch (ogf) {
-+ case OGF_INFO_PARAM:
-+ hci_cc_info_param(hdev, ocf, skb);
-+ break;
-+
-+ case OGF_HOST_CTL:
-+ hci_cc_host_ctl(hdev, ocf, skb);
-+ break;
-+
-+ case OGF_LINK_CTL:
-+ hci_cc_link_ctl(hdev, ocf, skb);
-+ break;
-+
-+ case OGF_LINK_POLICY:
-+ hci_cc_link_policy(hdev, ocf, skb);
-+ break;
-+
-+ default:
-+ BT_DBG("%s Command Completed OGF %x", hdev->name, ogf);
-+ break;
-+ };
-+
-+ if (ec->ncmd) {
-+ atomic_set(&hdev->cmd_cnt, 1);
-+ if (!skb_queue_empty(&hdev->cmd_q))
-+ hci_sched_cmd(hdev);
-+ }
-+ break;
-+ };
-+
-+ kfree_skb(skb);
-+ hdev->stat.evt_rx++;
-+}
-+
-+/* General internal stack event */
-+void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
-+{
-+ hci_event_hdr *eh;
-+ evt_stack_internal *si;
-+ struct sk_buff *skb;
-+ int size;
-+ void *ptr;
-+
-+ size = HCI_EVENT_HDR_SIZE + EVT_STACK_INTERNAL_SIZE + dlen;
-+ skb = bluez_skb_alloc(size, GFP_ATOMIC);
-+ if (!skb)
-+ return;
-+
-+ ptr = skb_put(skb, size);
-+
-+ eh = ptr;
-+ eh->evt = EVT_STACK_INTERNAL;
-+ eh->plen = EVT_STACK_INTERNAL_SIZE + dlen;
-+ ptr += HCI_EVENT_HDR_SIZE;
-+
-+ si = ptr;
-+ si->type = type;
-+ memcpy(si->data, data, dlen);
-+
-+ skb->pkt_type = HCI_EVENT_PKT;
-+ skb->dev = (void *) hdev;
-+ hci_send_to_sock(hdev, skb);
-+ kfree_skb(skb);
-+}
-diff -urN linux-2.4.18/net/bluetooth/hci_sock.c linux-2.4.18-mh9/net/bluetooth/hci_sock.c
---- linux-2.4.18/net/bluetooth/hci_sock.c Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/net/bluetooth/hci_sock.c Mon Aug 25 18:38:12 2003
-@@ -25,7 +25,7 @@
- /*
- * BlueZ HCI socket layer.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
-@@ -49,45 +49,54 @@
-
- #include <asm/system.h>
- #include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
-
- #ifndef HCI_SOCK_DEBUG
--#undef DBG
--#define DBG( A... )
-+#undef BT_DBG
-+#define BT_DBG( A... )
- #endif
-
--/* HCI socket interface */
-+/* ----- HCI socket interface ----- */
-+
-+/* Security filter */
-+static struct hci_sec_filter hci_sec_filter = {
-+ /* Packet types */
-+ 0x10,
-+ /* Events */
-+ { 0xd9fe, 0x0 },
-+ /* Commands */
-+ {
-+ { 0x0 },
-+ /* OGF_LINK_CTL */
-+ { 0x2a000002, 0x0, 0x0, 0x0 },
-+ /* OGF_LINK_POLICY */
-+ { 0x1200, 0x0, 0x0, 0x0 },
-+ /* OGF_HOST_CTL */
-+ { 0x80100000, 0x202a, 0x0, 0x0 },
-+ /* OGF_INFO_PARAM */
-+ { 0x22a, 0x0, 0x0, 0x0 },
-+ /* OGF_STATUS_PARAM */
-+ { 0x2e, 0x0, 0x0, 0x0 }
-+ }
-+};
-
- static struct bluez_sock_list hci_sk_list = {
- lock: RW_LOCK_UNLOCKED
- };
-
--static struct sock *hci_sock_lookup(struct hci_dev *hdev)
--{
-- struct sock *sk;
--
-- read_lock(&hci_sk_list.lock);
-- for (sk = hci_sk_list.head; sk; sk = sk->next) {
-- if (hci_pi(sk)->hdev == hdev)
-- break;
-- }
-- read_unlock(&hci_sk_list.lock);
-- return sk;
--}
--
- /* Send frame to RAW socket */
- void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
- {
- struct sock * sk;
-
-- DBG("hdev %p len %d", hdev, skb->len);
-+ BT_DBG("hdev %p len %d", hdev, skb->len);
-
- read_lock(&hci_sk_list.lock);
- for (sk = hci_sk_list.head; sk; sk = sk->next) {
-- struct hci_filter *flt;
-+ struct hci_filter *flt;
- struct sk_buff *nskb;
-
- if (sk->state != BT_BOUND || hci_pi(sk)->hdev != hdev)
-@@ -100,13 +109,19 @@
- /* Apply filter */
- flt = &hci_pi(sk)->filter;
-
-- if (!test_bit(skb->pkt_type, &flt->type_mask))
-+ if (!hci_test_bit((skb->pkt_type & HCI_FLT_TYPE_BITS), &flt->type_mask))
- continue;
-
- if (skb->pkt_type == HCI_EVENT_PKT) {
-- register int evt = (*(__u8 *)skb->data & 63);
-+ register int evt = (*(__u8 *)skb->data & HCI_FLT_EVENT_BITS);
-+
-+ if (!hci_test_bit(evt, &flt->event_mask))
-+ continue;
-
-- if (!test_bit(evt, &flt->event_mask))
-+ if (flt->opcode && ((evt == EVT_CMD_COMPLETE &&
-+ flt->opcode != *(__u16 *)(skb->data + 3)) ||
-+ (evt == EVT_CMD_STATUS &&
-+ flt->opcode != *(__u16 *)(skb->data + 4))))
- continue;
- }
-
-@@ -116,8 +131,8 @@
- /* Put type byte before the data */
- memcpy(skb_push(nskb, 1), &nskb->pkt_type, 1);
-
-- skb_queue_tail(&sk->receive_queue, nskb);
-- sk->data_ready(sk, nskb->len);
-+ if (sock_queue_rcv_skb(sk, nskb))
-+ kfree_skb(nskb);
- }
- read_unlock(&hci_sk_list.lock);
- }
-@@ -127,7 +142,7 @@
- struct sock *sk = sock->sk;
- struct hci_dev *hdev = hci_pi(sk)->hdev;
-
-- DBG("sock %p sk %p", sock, sk);
-+ BT_DBG("sock %p sk %p", sock, sk);
-
- if (!sk)
- return 0;
-@@ -135,9 +150,7 @@
- bluez_sock_unlink(&hci_sk_list, sk);
-
- if (hdev) {
-- if (!hci_sock_lookup(hdev))
-- hdev->flags &= ~HCI_SOCK;
--
-+ atomic_dec(&hdev->promisc);
- hci_dev_put(hdev);
- }
-
-@@ -149,24 +162,55 @@
- sock_put(sk);
-
- MOD_DEC_USE_COUNT;
--
- return 0;
- }
-
--static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+/* Ioctls that require bound socket */
-+static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
- {
-- struct sock *sk = sock->sk;
- struct hci_dev *hdev = hci_pi(sk)->hdev;
-- __u32 mode;
-
-- DBG("cmd %x arg %lx", cmd, arg);
-+ if (!hdev)
-+ return -EBADFD;
-
- switch (cmd) {
-- case HCIGETINFO:
-- return hci_dev_info(arg);
-+ case HCISETRAW:
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EACCES;
-
-+ if (arg)
-+ set_bit(HCI_RAW, &hdev->flags);
-+ else
-+ clear_bit(HCI_RAW, &hdev->flags);
-+
-+ return 0;
-+
-+ case HCIGETCONNINFO:
-+ return hci_get_conn_info(hdev, arg);
-+
-+ default:
-+ if (hdev->ioctl)
-+ return hdev->ioctl(hdev, cmd, arg);
-+ return -EINVAL;
-+ }
-+}
-+
-+static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct sock *sk = sock->sk;
-+ int err;
-+
-+ BT_DBG("cmd %x arg %lx", cmd, arg);
-+
-+ switch (cmd) {
- case HCIGETDEVLIST:
-- return hci_dev_list(arg);
-+ return hci_get_dev_list(arg);
-+
-+ case HCIGETDEVINFO:
-+ return hci_get_dev_info(arg);
-+
-+ case HCIGETCONNLIST:
-+ return hci_get_conn_list(arg);
-
- case HCIDEVUP:
- if (!capable(CAP_NET_ADMIN))
-@@ -183,48 +227,31 @@
- return -EACCES;
- return hci_dev_reset(arg);
-
-- case HCIRESETSTAT:
-+ case HCIDEVRESTAT:
- if (!capable(CAP_NET_ADMIN))
- return -EACCES;
- return hci_dev_reset_stat(arg);
-
- case HCISETSCAN:
-- if (!capable(CAP_NET_ADMIN))
-- return -EACCES;
-- return hci_dev_setscan(arg);
--
- case HCISETAUTH:
-- if (!capable(CAP_NET_ADMIN))
-- return -EACCES;
-- return hci_dev_setauth(arg);
--
-- case HCISETRAW:
-- if (!capable(CAP_NET_ADMIN))
-- return -EACCES;
--
-- if (!hdev)
-- return -EBADFD;
--
-- if (arg)
-- mode = HCI_RAW;
-- else
-- mode = HCI_NORMAL;
--
-- return hci_dev_setmode(hdev, mode);
--
-+ case HCISETENCRYPT:
- case HCISETPTYPE:
-+ case HCISETLINKPOL:
-+ case HCISETLINKMODE:
-+ case HCISETACLMTU:
-+ case HCISETSCOMTU:
- if (!capable(CAP_NET_ADMIN))
- return -EACCES;
-- return hci_dev_setptype(arg);
-+ return hci_dev_cmd(cmd, arg);
-
- case HCIINQUIRY:
- return hci_inquiry(arg);
-
-- case HCIGETCONNLIST:
-- return hci_conn_list(arg);
--
- default:
-- return -EINVAL;
-+ lock_sock(sk);
-+ err = hci_sock_bound_ioctl(sk, cmd, arg);
-+ release_sock(sk);
-+ return err;
- };
- }
-
-@@ -233,28 +260,35 @@
- struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
- struct sock *sk = sock->sk;
- struct hci_dev *hdev = NULL;
-+ int err = 0;
-
-- DBG("sock %p sk %p", sock, sk);
-+ BT_DBG("sock %p sk %p", sock, sk);
-
- if (!haddr || haddr->hci_family != AF_BLUETOOTH)
- return -EINVAL;
-
-+ lock_sock(sk);
-+
- if (hci_pi(sk)->hdev) {
-- /* Already bound */
-- return 0;
-+ err = -EALREADY;
-+ goto done;
- }
-
- if (haddr->hci_dev != HCI_DEV_NONE) {
-- if (!(hdev = hci_dev_get(haddr->hci_dev)))
-- return -ENODEV;
-+ if (!(hdev = hci_dev_get(haddr->hci_dev))) {
-+ err = -ENODEV;
-+ goto done;
-+ }
-
-- hdev->flags |= HCI_SOCK;
-+ atomic_inc(&hdev->promisc);
- }
-
- hci_pi(sk)->hdev = hdev;
- sk->state = BT_BOUND;
-
-- return 0;
-+done:
-+ release_sock(sk);
-+ return err;
- }
-
- static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer)
-@@ -262,73 +296,44 @@
- struct sockaddr_hci *haddr = (struct sockaddr_hci *) addr;
- struct sock *sk = sock->sk;
-
-- DBG("sock %p sk %p", sock, sk);
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ lock_sock(sk);
-
- *addr_len = sizeof(*haddr);
- haddr->hci_family = AF_BLUETOOTH;
- haddr->hci_dev = hci_pi(sk)->hdev->id;
-
-+ release_sock(sk);
- return 0;
- }
-
--static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
-- struct scm_cookie *scm)
--{
-- struct sock *sk = sock->sk;
-- struct hci_dev *hdev = hci_pi(sk)->hdev;
-- struct sk_buff *skb;
-- int err;
--
-- DBG("sock %p sk %p", sock, sk);
--
-- if (msg->msg_flags & MSG_OOB)
-- return -EOPNOTSUPP;
--
-- if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
-- return -EINVAL;
--
-- if (!hdev)
-- return -EBADFD;
--
-- if (!(skb = bluez_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
-- return err;
--
-- if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
-- kfree_skb(skb);
-- return -EFAULT;
-- }
--
-- skb->dev = (void *) hdev;
-- skb->pkt_type = *((unsigned char *) skb->data);
-- skb_pull(skb, 1);
--
-- /* Send frame to HCI core */
-- hci_send_raw(skb);
--
-- return len;
--}
--
- static inline void hci_sock_cmsg(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
- {
- __u32 mask = hci_pi(sk)->cmsg_mask;
-
- if (mask & HCI_CMSG_DIR)
- put_cmsg(msg, SOL_HCI, HCI_CMSG_DIR, sizeof(int), &bluez_cb(skb)->incomming);
-+
-+ if (mask & HCI_CMSG_TSTAMP)
-+ put_cmsg(msg, SOL_HCI, HCI_CMSG_TSTAMP, sizeof(skb->stamp), &skb->stamp);
- }
-
--static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len,
-- int flags, struct scm_cookie *scm)
-+static int hci_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
- {
- int noblock = flags & MSG_DONTWAIT;
- struct sock *sk = sock->sk;
- struct sk_buff *skb;
- int copied, err;
-
-- DBG("sock %p sk %p", sock, sk);
-+ BT_DBG("sock %p, sk %p", sock, sk);
-
-- if (flags & (MSG_OOB | MSG_PEEK))
-+ if (flags & (MSG_OOB))
- return -EOPNOTSUPP;
-
-+ if (sk->state == BT_CLOSED)
-+ return 0;
-+
- if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
- return err;
-
-@@ -343,28 +348,107 @@
- skb->h.raw = skb->data;
- err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
-
-- if (hci_pi(sk)->cmsg_mask)
-- hci_sock_cmsg(sk, msg, skb);
--
-+ hci_sock_cmsg(sk, msg, skb);
-+
- skb_free_datagram(sk, skb);
-
- return err ? : copied;
- }
-
-+static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
-+ struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ struct hci_dev *hdev;
-+ struct sk_buff *skb;
-+ int err;
-+
-+ BT_DBG("sock %p sk %p", sock, sk);
-+
-+ if (msg->msg_flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
-+ return -EINVAL;
-+
-+ if (len < 4)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (!(hdev = hci_pi(sk)->hdev)) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ if (!(skb = bluez_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
-+ goto done;
-+
-+ if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
-+ err = -EFAULT;
-+ goto drop;
-+ }
-+
-+ skb->pkt_type = *((unsigned char *) skb->data);
-+ skb_pull(skb, 1);
-+ skb->dev = (void *) hdev;
-+
-+ if (skb->pkt_type == HCI_COMMAND_PKT) {
-+ u16 opcode = __le16_to_cpu(get_unaligned((u16 *)skb->data));
-+ u16 ogf = cmd_opcode_ogf(opcode);
-+ u16 ocf = cmd_opcode_ocf(opcode);
-+
-+ if (((ogf > HCI_SFLT_MAX_OGF) ||
-+ !hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) &&
-+ !capable(CAP_NET_RAW)) {
-+ err = -EPERM;
-+ goto drop;
-+ }
-+
-+ if (test_bit(HCI_RAW, &hdev->flags) || (ogf == OGF_VENDOR_CMD)) {
-+ skb_queue_tail(&hdev->raw_q, skb);
-+ hci_sched_tx(hdev);
-+ } else {
-+ skb_queue_tail(&hdev->cmd_q, skb);
-+ hci_sched_cmd(hdev);
-+ }
-+ } else {
-+ if (!capable(CAP_NET_RAW)) {
-+ err = -EPERM;
-+ goto drop;
-+ }
-+
-+ skb_queue_tail(&hdev->raw_q, skb);
-+ hci_sched_tx(hdev);
-+ }
-+
-+ err = len;
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+
-+drop:
-+ kfree_skb(skb);
-+ goto done;
-+}
-+
- int hci_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int len)
- {
- struct sock *sk = sock->sk;
-- struct hci_filter flt;
-+ struct hci_filter flt = { opcode: 0 };
- int err = 0, opt = 0;
-
-- DBG("sk %p, opt %d", sk, optname);
-+ BT_DBG("sk %p, opt %d", sk, optname);
-
- lock_sock(sk);
-
- switch (optname) {
- case HCI_DATA_DIR:
-- if (get_user(opt, (int *)optval))
-- return -EFAULT;
-+ if (get_user(opt, (int *)optval)) {
-+ err = -EFAULT;
-+ break;
-+ }
-
- if (opt)
- hci_pi(sk)->cmsg_mask |= HCI_CMSG_DIR;
-@@ -372,12 +456,31 @@
- hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_DIR;
- break;
-
-+ case HCI_TIME_STAMP:
-+ if (get_user(opt, (int *)optval)) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ if (opt)
-+ hci_pi(sk)->cmsg_mask |= HCI_CMSG_TSTAMP;
-+ else
-+ hci_pi(sk)->cmsg_mask &= ~HCI_CMSG_TSTAMP;
-+ break;
-+
- case HCI_FILTER:
- len = MIN(len, sizeof(struct hci_filter));
- if (copy_from_user(&flt, optval, len)) {
- err = -EFAULT;
- break;
- }
-+
-+ if (!capable(CAP_NET_RAW)) {
-+ flt.type_mask &= hci_sec_filter.type_mask;
-+ flt.event_mask[0] &= hci_sec_filter.event_mask[0];
-+ flt.event_mask[1] &= hci_sec_filter.event_mask[1];
-+ }
-+
- memcpy(&hci_pi(sk)->filter, &flt, len);
- break;
-
-@@ -409,6 +512,16 @@
- return -EFAULT;
- break;
-
-+ case HCI_TIME_STAMP:
-+ if (hci_pi(sk)->cmsg_mask & HCI_CMSG_TSTAMP)
-+ opt = 1;
-+ else
-+ opt = 0;
-+
-+ if (put_user(opt, optval))
-+ return -EFAULT;
-+ break;
-+
- case HCI_FILTER:
- len = MIN(len, sizeof(struct hci_filter));
- if (copy_to_user(optval, &hci_pi(sk)->filter, len))
-@@ -446,7 +559,7 @@
- {
- struct sock *sk;
-
-- DBG("sock %p", sock);
-+ BT_DBG("sock %p", sock);
-
- if (sock->type != SOCK_RAW)
- return -ESOCKTNOSUPPORT;
-@@ -464,44 +577,31 @@
- sk->protocol = protocol;
- sk->state = BT_OPEN;
-
-- /* Initialize filter */
-- hci_pi(sk)->filter.type_mask = (1<<HCI_EVENT_PKT);
-- hci_pi(sk)->filter.event_mask[0] = ~0L;
-- hci_pi(sk)->filter.event_mask[1] = ~0L;
--
- bluez_sock_link(&hci_sk_list, sk);
-
- MOD_INC_USE_COUNT;
--
- return 0;
- }
-
- static int hci_sock_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
- {
- struct hci_dev *hdev = (struct hci_dev *) ptr;
-- struct sk_buff *skb;
--
-- DBG("hdev %s event %ld", hdev->name, event);
-+ evt_si_device sd;
-+
-+ BT_DBG("hdev %s event %ld", hdev->name, event);
-
- /* Send event to sockets */
-- if ((skb = bluez_skb_alloc(HCI_EVENT_HDR_SIZE + EVT_HCI_DEV_EVENT_SIZE, GFP_ATOMIC))) {
-- hci_event_hdr eh = { EVT_HCI_DEV_EVENT, EVT_HCI_DEV_EVENT_SIZE };
-- evt_hci_dev_event he = { event, hdev->id };
--
-- skb->pkt_type = HCI_EVENT_PKT;
-- memcpy(skb_put(skb, HCI_EVENT_HDR_SIZE), &eh, HCI_EVENT_HDR_SIZE);
-- memcpy(skb_put(skb, EVT_HCI_DEV_EVENT_SIZE), &he, EVT_HCI_DEV_EVENT_SIZE);
--
-- hci_send_to_sock(NULL, skb);
-- kfree_skb(skb);
-- }
--
-+ sd.event = event;
-+ sd.dev_id = hdev->id;
-+ hci_si_event(NULL, EVT_SI_DEVICE, EVT_SI_DEVICE_SIZE, &sd);
-+
- if (event == HCI_DEV_UNREG) {
- struct sock *sk;
-
- /* Detach sockets from device */
- read_lock(&hci_sk_list.lock);
- for (sk = hci_sk_list.head; sk; sk = sk->next) {
-+ bh_lock_sock(sk);
- if (hci_pi(sk)->hdev == hdev) {
- hci_pi(sk)->hdev = NULL;
- sk->err = EPIPE;
-@@ -510,6 +610,7 @@
-
- hci_dev_put(hdev);
- }
-+ bh_unlock_sock(sk);
- }
- read_unlock(&hci_sk_list.lock);
- }
-@@ -529,21 +630,19 @@
- int hci_sock_init(void)
- {
- if (bluez_sock_register(BTPROTO_HCI, &hci_sock_family_ops)) {
-- ERR("Can't register HCI socket");
-+ BT_ERR("Can't register HCI socket");
- return -EPROTO;
- }
-
- hci_register_notifier(&hci_sock_nblock);
--
- return 0;
- }
-
- int hci_sock_cleanup(void)
- {
- if (bluez_sock_unregister(BTPROTO_HCI))
-- ERR("Can't unregister HCI socket");
-+ BT_ERR("Can't unregister HCI socket");
-
- hci_unregister_notifier(&hci_sock_nblock);
--
- return 0;
- }
-diff -urN linux-2.4.18/net/bluetooth/l2cap.c linux-2.4.18-mh9/net/bluetooth/l2cap.c
---- linux-2.4.18/net/bluetooth/l2cap.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/l2cap.c Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,2187 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * BlueZ L2CAP core and sockets.
-+ *
-+ * $Id$
-+ */
-+#define VERSION "2.3"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/socket.h>
-+#include <linux/skbuff.h>
-+#include <linux/proc_fs.h>
-+#include <linux/list.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include <net/bluetooth/l2cap.h>
-+
-+#ifndef L2CAP_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+static struct proto_ops l2cap_sock_ops;
-+
-+struct bluez_sock_list l2cap_sk_list = {
-+ lock: RW_LOCK_UNLOCKED
-+};
-+
-+static int l2cap_conn_del(struct hci_conn *conn, int err);
-+
-+static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
-+static void l2cap_chan_del(struct sock *sk, int err);
-+static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len);
-+
-+static void __l2cap_sock_close(struct sock *sk, int reason);
-+static void l2cap_sock_close(struct sock *sk);
-+static void l2cap_sock_kill(struct sock *sk);
-+
-+static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data);
-+static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data);
-+
-+/* ----- L2CAP timers ------ */
-+static void l2cap_sock_timeout(unsigned long arg)
-+{
-+ struct sock *sk = (struct sock *) arg;
-+
-+ BT_DBG("sock %p state %d", sk, sk->state);
-+
-+ bh_lock_sock(sk);
-+ __l2cap_sock_close(sk, ETIMEDOUT);
-+ bh_unlock_sock(sk);
-+
-+ l2cap_sock_kill(sk);
-+ sock_put(sk);
-+}
-+
-+static void l2cap_sock_set_timer(struct sock *sk, long timeout)
-+{
-+ BT_DBG("sk %p state %d timeout %ld", sk, sk->state, timeout);
-+
-+ if (!mod_timer(&sk->timer, jiffies + timeout))
-+ sock_hold(sk);
-+}
-+
-+static void l2cap_sock_clear_timer(struct sock *sk)
-+{
-+ BT_DBG("sock %p state %d", sk, sk->state);
-+
-+ if (timer_pending(&sk->timer) && del_timer(&sk->timer))
-+ __sock_put(sk);
-+}
-+
-+static void l2cap_sock_init_timer(struct sock *sk)
-+{
-+ init_timer(&sk->timer);
-+ sk->timer.function = l2cap_sock_timeout;
-+ sk->timer.data = (unsigned long)sk;
-+}
-+
-+/* -------- L2CAP connections --------- */
-+static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon, __u8 status)
-+{
-+ struct l2cap_conn *conn;
-+
-+ if ((conn = hcon->l2cap_data))
-+ return conn;
-+
-+ if (status)
-+ return conn;
-+
-+ if (!(conn = kmalloc(sizeof(struct l2cap_conn), GFP_ATOMIC)))
-+ return NULL;
-+ memset(conn, 0, sizeof(struct l2cap_conn));
-+
-+ hcon->l2cap_data = conn;
-+ conn->hcon = hcon;
-+
-+ conn->mtu = hcon->hdev->acl_mtu;
-+ conn->src = &hcon->hdev->bdaddr;
-+ conn->dst = &hcon->dst;
-+
-+ spin_lock_init(&conn->lock);
-+ conn->chan_list.lock = RW_LOCK_UNLOCKED;
-+
-+ BT_DBG("hcon %p conn %p", hcon, conn);
-+
-+ MOD_INC_USE_COUNT;
-+ return conn;
-+}
-+
-+static int l2cap_conn_del(struct hci_conn *hcon, int err)
-+{
-+ struct l2cap_conn *conn;
-+ struct sock *sk;
-+
-+ if (!(conn = hcon->l2cap_data))
-+ return 0;
-+
-+ BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
-+
-+ if (conn->rx_skb)
-+ kfree_skb(conn->rx_skb);
-+
-+ /* Kill channels */
-+ while ((sk = conn->chan_list.head)) {
-+ bh_lock_sock(sk);
-+ l2cap_chan_del(sk, err);
-+ bh_unlock_sock(sk);
-+ l2cap_sock_kill(sk);
-+ }
-+
-+ hcon->l2cap_data = NULL;
-+ kfree(conn);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+/* -------- Socket interface ---------- */
-+static struct sock *__l2cap_get_sock_by_addr(__u16 psm, bdaddr_t *src)
-+{
-+ struct sock *sk;
-+ for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-+ if (sk->sport == psm && !bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+ }
-+ return sk;
-+}
-+
-+/* Find socket with psm and source bdaddr.
-+ * Returns closest match.
-+ */
-+static struct sock *__l2cap_get_sock_by_psm(int state, __u16 psm, bdaddr_t *src)
-+{
-+ struct sock *sk, *sk1 = NULL;
-+
-+ for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-+ if (state && sk->state != state)
-+ continue;
-+
-+ if (l2cap_pi(sk)->psm == psm) {
-+ /* Exact match. */
-+ if (!bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+
-+ /* Closest match */
-+ if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
-+ sk1 = sk;
-+ }
-+ }
-+ return sk ? sk : sk1;
-+}
-+
-+/* Find socket with given address (psm, src).
-+ * Returns locked socket */
-+static inline struct sock *l2cap_get_sock_by_psm(int state, __u16 psm, bdaddr_t *src)
-+{
-+ struct sock *s;
-+ read_lock(&l2cap_sk_list.lock);
-+ s = __l2cap_get_sock_by_psm(state, psm, src);
-+ if (s) bh_lock_sock(s);
-+ read_unlock(&l2cap_sk_list.lock);
-+ return s;
-+}
-+
-+static void l2cap_sock_destruct(struct sock *sk)
-+{
-+ BT_DBG("sk %p", sk);
-+
-+ skb_queue_purge(&sk->receive_queue);
-+ skb_queue_purge(&sk->write_queue);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void l2cap_sock_cleanup_listen(struct sock *parent)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("parent %p", parent);
-+
-+ /* Close not yet accepted channels */
-+ while ((sk = bluez_accept_dequeue(parent, NULL)))
-+ l2cap_sock_close(sk);
-+
-+ parent->state = BT_CLOSED;
-+ parent->zapped = 1;
-+}
-+
-+/* Kill socket (only if zapped and orphan)
-+ * Must be called on unlocked socket.
-+ */
-+static void l2cap_sock_kill(struct sock *sk)
-+{
-+ if (!sk->zapped || sk->socket)
-+ return;
-+
-+ BT_DBG("sk %p state %d", sk, sk->state);
-+
-+ /* Kill poor orphan */
-+ bluez_sock_unlink(&l2cap_sk_list, sk);
-+ sk->dead = 1;
-+ sock_put(sk);
-+}
-+
-+/* Close socket.
-+ */
-+static void __l2cap_sock_close(struct sock *sk, int reason)
-+{
-+ BT_DBG("sk %p state %d socket %p", sk, sk->state, sk->socket);
-+
-+ switch (sk->state) {
-+ case BT_LISTEN:
-+ l2cap_sock_cleanup_listen(sk);
-+ break;
-+
-+ case BT_CONNECTED:
-+ case BT_CONFIG:
-+ case BT_CONNECT2:
-+ if (sk->type == SOCK_SEQPACKET) {
-+ struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-+ l2cap_disconn_req req;
-+
-+ sk->state = BT_DISCONN;
-+ l2cap_sock_set_timer(sk, sk->sndtimeo);
-+
-+ req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
-+ } else {
-+ l2cap_chan_del(sk, reason);
-+ }
-+ break;
-+
-+ case BT_CONNECT:
-+ case BT_DISCONN:
-+ l2cap_chan_del(sk, reason);
-+ break;
-+
-+ default:
-+ sk->zapped = 1;
-+ break;
-+ };
-+}
-+
-+/* Must be called on unlocked socket. */
-+static void l2cap_sock_close(struct sock *sk)
-+{
-+ l2cap_sock_clear_timer(sk);
-+ lock_sock(sk);
-+ __l2cap_sock_close(sk, ECONNRESET);
-+ release_sock(sk);
-+ l2cap_sock_kill(sk);
-+}
-+
-+static void l2cap_sock_init(struct sock *sk, struct sock *parent)
-+{
-+ struct l2cap_pinfo *pi = l2cap_pi(sk);
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (parent) {
-+ sk->type = parent->type;
-+ pi->imtu = l2cap_pi(parent)->imtu;
-+ pi->omtu = l2cap_pi(parent)->omtu;
-+ pi->link_mode = l2cap_pi(parent)->link_mode;
-+ } else {
-+ pi->imtu = L2CAP_DEFAULT_MTU;
-+ pi->omtu = 0;
-+ pi->link_mode = 0;
-+ }
-+
-+ /* Default config options */
-+ pi->conf_mtu = L2CAP_DEFAULT_MTU;
-+ pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
-+}
-+
-+static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
-+{
-+ struct sock *sk;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
-+ return NULL;
-+
-+ bluez_sock_init(sock, sk);
-+
-+ sk->zapped = 0;
-+
-+ sk->destruct = l2cap_sock_destruct;
-+ sk->sndtimeo = L2CAP_CONN_TIMEOUT;
-+
-+ sk->protocol = proto;
-+ sk->state = BT_OPEN;
-+
-+ l2cap_sock_init_timer(sk);
-+
-+ bluez_sock_link(&l2cap_sk_list, sk);
-+
-+ MOD_INC_USE_COUNT;
-+ return sk;
-+}
-+
-+static int l2cap_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ sock->state = SS_UNCONNECTED;
-+
-+ if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_DGRAM && sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ if (sock->type == SOCK_RAW && !capable(CAP_NET_RAW))
-+ return -EPERM;
-+
-+ sock->ops = &l2cap_sock_ops;
-+
-+ if (!(sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ l2cap_sock_init(sk, NULL);
-+ return 0;
-+}
-+
-+static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
-+{
-+ struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
-+
-+ if (!addr || addr->sa_family != AF_BLUETOOTH)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_OPEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ write_lock_bh(&l2cap_sk_list.lock);
-+ if (la->l2_psm && __l2cap_get_sock_by_addr(la->l2_psm, &la->l2_bdaddr)) {
-+ err = -EADDRINUSE;
-+ } else {
-+ /* Save source address */
-+ bacpy(&bluez_pi(sk)->src, &la->l2_bdaddr);
-+ l2cap_pi(sk)->psm = la->l2_psm;
-+ sk->sport = la->l2_psm;
-+ sk->state = BT_BOUND;
-+ }
-+ write_unlock_bh(&l2cap_sk_list.lock);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_do_connect(struct sock *sk)
-+{
-+ bdaddr_t *src = &bluez_pi(sk)->src;
-+ bdaddr_t *dst = &bluez_pi(sk)->dst;
-+ struct l2cap_conn *conn;
-+ struct hci_conn *hcon;
-+ struct hci_dev *hdev;
-+ int err = 0;
-+
-+ BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
-+
-+ if (!(hdev = hci_get_route(dst, src)))
-+ return -EHOSTUNREACH;
-+
-+ hci_dev_lock_bh(hdev);
-+
-+ err = -ENOMEM;
-+
-+ hcon = hci_connect(hdev, ACL_LINK, dst);
-+ if (!hcon)
-+ goto done;
-+
-+ conn = l2cap_conn_add(hcon, 0);
-+ if (!conn) {
-+ hci_conn_put(hcon);
-+ goto done;
-+ }
-+
-+ err = 0;
-+
-+ /* Update source addr of the socket */
-+ bacpy(src, conn->src);
-+
-+ l2cap_chan_add(conn, sk, NULL);
-+
-+ sk->state = BT_CONNECT;
-+ l2cap_sock_set_timer(sk, sk->sndtimeo);
-+
-+ if (hcon->state == BT_CONNECTED) {
-+ if (sk->type == SOCK_SEQPACKET) {
-+ l2cap_conn_req req;
-+ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ req.psm = l2cap_pi(sk)->psm;
-+ l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
-+ } else {
-+ l2cap_sock_clear_timer(sk);
-+ sk->state = BT_CONNECTED;
-+ }
-+ }
-+
-+done:
-+ hci_dev_unlock_bh(hdev);
-+ hci_dev_put(hdev);
-+ return err;
-+}
-+
-+static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
-+{
-+ struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ lock_sock(sk);
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) {
-+ err = -EINVAL;
-+ goto done;
-+ }
-+
-+ if (sk->type == SOCK_SEQPACKET && !la->l2_psm) {
-+ err = -EINVAL;
-+ goto done;
-+ }
-+
-+ switch(sk->state) {
-+ case BT_CONNECT:
-+ case BT_CONNECT2:
-+ case BT_CONFIG:
-+ /* Already connecting */
-+ goto wait;
-+
-+ case BT_CONNECTED:
-+ /* Already connected */
-+ goto done;
-+
-+ case BT_OPEN:
-+ case BT_BOUND:
-+ /* Can connect */
-+ break;
-+
-+ default:
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ /* Set destination address and psm */
-+ bacpy(&bluez_pi(sk)->dst, &la->l2_bdaddr);
-+ l2cap_pi(sk)->psm = la->l2_psm;
-+
-+ if ((err = l2cap_do_connect(sk)))
-+ goto done;
-+
-+wait:
-+ err = bluez_sock_wait_state(sk, BT_CONNECTED,
-+ sock_sndtimeo(sk, flags & O_NONBLOCK));
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int l2cap_sock_listen(struct socket *sock, int backlog)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p backlog %d", sk, backlog);
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ if (!l2cap_pi(sk)->psm) {
-+ err = -EINVAL;
-+ goto done;
-+ }
-+
-+ sk->max_ack_backlog = backlog;
-+ sk->ack_backlog = 0;
-+ sk->state = BT_LISTEN;
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct sock *sk = sock->sk, *nsk;
-+ long timeo;
-+ int err = 0;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
-+
-+ BT_DBG("sk %p timeo %ld", sk, timeo);
-+
-+ /* Wait for an incoming connection. (wake-one). */
-+ add_wait_queue_exclusive(sk->sleep, &wait);
-+ while (!(nsk = bluez_accept_dequeue(sk, newsock))) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ break;
-+ }
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ break;
-+ }
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ if (err)
-+ goto done;
-+
-+ newsock->state = SS_CONNECTED;
-+
-+ BT_DBG("new socket %p", nsk);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
-+{
-+ struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ addr->sa_family = AF_BLUETOOTH;
-+ *len = sizeof(struct sockaddr_l2);
-+
-+ if (peer)
-+ bacpy(&la->l2_bdaddr, &bluez_pi(sk)->dst);
-+ else
-+ bacpy(&la->l2_bdaddr, &bluez_pi(sk)->src);
-+
-+ la->l2_psm = l2cap_pi(sk)->psm;
-+ return 0;
-+}
-+
-+static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (sk->err)
-+ return sock_error(sk);
-+
-+ if (msg->msg_flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ /* Check outgoing MTU */
-+ if (len > l2cap_pi(sk)->omtu)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state == BT_CONNECTED)
-+ err = l2cap_chan_send(sk, msg, len);
-+ else
-+ err = -ENOTCONN;
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ struct l2cap_options opts;
-+ int err = 0, len;
-+ __u32 opt;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ case L2CAP_OPTIONS:
-+ len = MIN(sizeof(opts), optlen);
-+ if (copy_from_user((char *)&opts, optval, len)) {
-+ err = -EFAULT;
-+ break;
-+ }
-+ l2cap_pi(sk)->imtu = opts.imtu;
-+ l2cap_pi(sk)->omtu = opts.omtu;
-+ break;
-+
-+ case L2CAP_LM:
-+ if (get_user(opt, (__u32 *)optval)) {
-+ err = -EFAULT;
-+ break;
-+ }
-+
-+ l2cap_pi(sk)->link_mode = opt;
-+ break;
-+
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ struct l2cap_options opts;
-+ struct l2cap_conninfo cinfo;
-+ int len, err = 0;
-+
-+ if (get_user(len, optlen))
-+ return -EFAULT;
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ case L2CAP_OPTIONS:
-+ opts.imtu = l2cap_pi(sk)->imtu;
-+ opts.omtu = l2cap_pi(sk)->omtu;
-+ opts.flush_to = l2cap_pi(sk)->flush_to;
-+
-+ len = MIN(len, sizeof(opts));
-+ if (copy_to_user(optval, (char *)&opts, len))
-+ err = -EFAULT;
-+
-+ break;
-+
-+ case L2CAP_LM:
-+ if (put_user(l2cap_pi(sk)->link_mode, (__u32 *)optval))
-+ err = -EFAULT;
-+ break;
-+
-+ case L2CAP_CONNINFO:
-+ if (sk->state != BT_CONNECTED) {
-+ err = -ENOTCONN;
-+ break;
-+ }
-+
-+ cinfo.hci_handle = l2cap_pi(sk)->conn->hcon->handle;
-+
-+ len = MIN(len, sizeof(cinfo));
-+ if (copy_to_user(optval, (char *)&cinfo, len))
-+ err = -EFAULT;
-+
-+ break;
-+
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_shutdown(struct socket *sock, int how)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk) return 0;
-+
-+ lock_sock(sk);
-+ if (!sk->shutdown) {
-+ sk->shutdown = SHUTDOWN_MASK;
-+ l2cap_sock_clear_timer(sk);
-+ __l2cap_sock_close(sk, 0);
-+
-+ if (sk->linger)
-+ err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
-+ }
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int l2cap_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+ int err;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk) return 0;
-+
-+ err = l2cap_sock_shutdown(sock, 2);
-+
-+ sock_orphan(sk);
-+ l2cap_sock_kill(sk);
-+ return err;
-+}
-+
-+/* --------- L2CAP channels --------- */
-+static struct sock * __l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
-+{
-+ struct sock *s;
-+ for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-+ if (l2cap_pi(s)->dcid == cid)
-+ break;
-+ }
-+ return s;
-+}
-+
-+static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
-+{
-+ struct sock *s;
-+ for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-+ if (l2cap_pi(s)->scid == cid)
-+ break;
-+ }
-+ return s;
-+}
-+
-+/* Find channel with given SCID.
-+ * Returns locked socket */
-+static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
-+{
-+ struct sock *s;
-+ read_lock(&l->lock);
-+ s = __l2cap_get_chan_by_scid(l, cid);
-+ if (s) bh_lock_sock(s);
-+ read_unlock(&l->lock);
-+ return s;
-+}
-+
-+static __u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
-+{
-+ __u16 cid = 0x0040;
-+
-+ for (; cid < 0xffff; cid++) {
-+ if(!__l2cap_get_chan_by_scid(l, cid))
-+ return cid;
-+ }
-+
-+ return 0;
-+}
-+
-+static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
-+{
-+ sock_hold(sk);
-+
-+ if (l->head)
-+ l2cap_pi(l->head)->prev_c = sk;
-+
-+ l2cap_pi(sk)->next_c = l->head;
-+ l2cap_pi(sk)->prev_c = NULL;
-+ l->head = sk;
-+}
-+
-+static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
-+{
-+ struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
-+
-+ write_lock(&l->lock);
-+ if (sk == l->head)
-+ l->head = next;
-+
-+ if (next)
-+ l2cap_pi(next)->prev_c = prev;
-+ if (prev)
-+ l2cap_pi(prev)->next_c = next;
-+ write_unlock(&l->lock);
-+
-+ __sock_put(sk);
-+}
-+
-+static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+
-+ BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
-+
-+ l2cap_pi(sk)->conn = conn;
-+
-+ if (sk->type == SOCK_SEQPACKET) {
-+ /* Alloc CID for connection-oriented socket */
-+ l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
-+ } else if (sk->type == SOCK_DGRAM) {
-+ /* Connectionless socket */
-+ l2cap_pi(sk)->scid = 0x0002;
-+ l2cap_pi(sk)->dcid = 0x0002;
-+ l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
-+ } else {
-+ /* Raw socket can send/recv signalling messages only */
-+ l2cap_pi(sk)->scid = 0x0001;
-+ l2cap_pi(sk)->dcid = 0x0001;
-+ l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
-+ }
-+
-+ __l2cap_chan_link(l, sk);
-+
-+ if (parent)
-+ bluez_accept_enqueue(parent, sk);
-+}
-+
-+static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+ write_lock(&l->lock);
-+ __l2cap_chan_add(conn, sk, parent);
-+ write_unlock(&l->lock);
-+}
-+
-+/* Delete channel.
-+ * Must be called on the locked socket. */
-+static void l2cap_chan_del(struct sock *sk, int err)
-+{
-+ struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-+ struct sock *parent = bluez_pi(sk)->parent;
-+
-+ l2cap_sock_clear_timer(sk);
-+
-+ BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
-+
-+ if (conn) {
-+ /* Unlink from channel list */
-+ l2cap_chan_unlink(&conn->chan_list, sk);
-+ l2cap_pi(sk)->conn = NULL;
-+ hci_conn_put(conn->hcon);
-+ }
-+
-+ sk->state = BT_CLOSED;
-+ sk->zapped = 1;
-+
-+ if (err)
-+ sk->err = err;
-+
-+ if (parent)
-+ parent->data_ready(parent, 0);
-+ else
-+ sk->state_change(sk);
-+}
-+
-+static void l2cap_conn_ready(struct l2cap_conn *conn)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+ struct sock *sk;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ bh_lock_sock(sk);
-+
-+ if (sk->type != SOCK_SEQPACKET) {
-+ l2cap_sock_clear_timer(sk);
-+ sk->state = BT_CONNECTED;
-+ sk->state_change(sk);
-+ } else if (sk->state == BT_CONNECT) {
-+ l2cap_conn_req req;
-+ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ req.psm = l2cap_pi(sk)->psm;
-+ l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
-+ }
-+
-+ bh_unlock_sock(sk);
-+ }
-+
-+ read_unlock(&l->lock);
-+}
-+
-+/* Notify sockets that we cannot guaranty reliability anymore */
-+static void l2cap_conn_unreliable(struct l2cap_conn *conn, int err)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+ struct sock *sk;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ if (l2cap_pi(sk)->link_mode & L2CAP_LM_RELIABLE)
-+ sk->err = err;
-+ }
-+ read_unlock(&l->lock);
-+}
-+
-+static void l2cap_chan_ready(struct sock *sk)
-+{
-+ struct sock *parent = bluez_pi(sk)->parent;
-+
-+ BT_DBG("sk %p, parent %p", sk, parent);
-+
-+ l2cap_pi(sk)->conf_state = 0;
-+ l2cap_sock_clear_timer(sk);
-+
-+ if (!parent) {
-+ /* Outgoing channel.
-+ * Wake up socket sleeping on connect.
-+ */
-+ sk->state = BT_CONNECTED;
-+ sk->state_change(sk);
-+ } else {
-+ /* Incomming channel.
-+ * Wake up socket sleeping on accept.
-+ */
-+ parent->data_ready(parent, 0);
-+ }
-+}
-+
-+/* Copy frame to all raw sockets on that connection */
-+void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
-+{
-+ struct l2cap_chan_list *l = &conn->chan_list;
-+ struct sk_buff *nskb;
-+ struct sock * sk;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ if (sk->type != SOCK_RAW)
-+ continue;
-+
-+ /* Don't send frame to the socket it came from */
-+ if (skb->sk == sk)
-+ continue;
-+
-+ if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
-+ continue;
-+
-+ if (sock_queue_rcv_skb(sk, nskb))
-+ kfree_skb(nskb);
-+ }
-+ read_unlock(&l->lock);
-+}
-+
-+static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
-+{
-+ struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-+ struct sk_buff *skb, **frag;
-+ int err, hlen, count, sent=0;
-+ l2cap_hdr *lh;
-+
-+ BT_DBG("sk %p len %d", sk, len);
-+
-+ /* First fragment (with L2CAP header) */
-+ if (sk->type == SOCK_DGRAM)
-+ hlen = L2CAP_HDR_SIZE + 2;
-+ else
-+ hlen = L2CAP_HDR_SIZE;
-+
-+ count = MIN(conn->mtu - hlen, len);
-+
-+ skb = bluez_skb_send_alloc(sk, hlen + count,
-+ msg->msg_flags & MSG_DONTWAIT, &err);
-+ if (!skb)
-+ return err;
-+
-+ /* Create L2CAP header */
-+ lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-+ lh->cid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ lh->len = __cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
-+
-+ if (sk->type == SOCK_DGRAM)
-+ put_unaligned(l2cap_pi(sk)->psm, (__u16 *) skb_put(skb, 2));
-+
-+ if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
-+ err = -EFAULT;
-+ goto fail;
-+ }
-+
-+ sent += count;
-+ len -= count;
-+
-+ /* Continuation fragments (no L2CAP header) */
-+ frag = &skb_shinfo(skb)->frag_list;
-+ while (len) {
-+ count = MIN(conn->mtu, len);
-+
-+ *frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
-+ if (!*frag)
-+ goto fail;
-+
-+ if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
-+ err = -EFAULT;
-+ goto fail;
-+ }
-+
-+ sent += count;
-+ len -= count;
-+
-+ frag = &(*frag)->next;
-+ }
-+
-+ if ((err = hci_send_acl(conn->hcon, skb, 0)) < 0)
-+ goto fail;
-+
-+ return sent;
-+
-+fail:
-+ kfree_skb(skb);
-+ return err;
-+}
-+
-+/* --------- L2CAP signalling commands --------- */
-+static inline __u8 l2cap_get_ident(struct l2cap_conn *conn)
-+{
-+ __u8 id;
-+
-+ /* Get next available identificator.
-+ * 1 - 199 are used by kernel.
-+ * 200 - 254 are used by utilities like l2ping, etc
-+ */
-+
-+ spin_lock(&conn->lock);
-+
-+ if (++conn->tx_ident > 199)
-+ conn->tx_ident = 1;
-+
-+ id = conn->tx_ident;
-+
-+ spin_unlock(&conn->lock);
-+
-+ return id;
-+}
-+
-+static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
-+ __u8 code, __u8 ident, __u16 dlen, void *data)
-+{
-+ struct sk_buff *skb, **frag;
-+ l2cap_cmd_hdr *cmd;
-+ l2cap_hdr *lh;
-+ int len, count;
-+
-+ BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", conn, code, ident, dlen);
-+
-+ len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
-+ count = MIN(conn->mtu, len);
-+
-+ skb = bluez_skb_alloc(count, GFP_ATOMIC);
-+ if (!skb)
-+ return NULL;
-+
-+ lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-+ lh->len = __cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
-+ lh->cid = __cpu_to_le16(0x0001);
-+
-+ cmd = (l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
-+ cmd->code = code;
-+ cmd->ident = ident;
-+ cmd->len = __cpu_to_le16(dlen);
-+
-+ if (dlen) {
-+ count -= L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE;
-+ memcpy(skb_put(skb, count), data, count);
-+ data += count;
-+ }
-+
-+ len -= skb->len;
-+
-+ /* Continuation fragments (no L2CAP header) */
-+ frag = &skb_shinfo(skb)->frag_list;
-+ while (len) {
-+ count = MIN(conn->mtu, len);
-+
-+ *frag = bluez_skb_alloc(count, GFP_ATOMIC);
-+ if (!*frag)
-+ goto fail;
-+
-+ memcpy(skb_put(*frag, count), data, count);
-+
-+ len -= count;
-+ data += count;
-+
-+ frag = &(*frag)->next;
-+ }
-+
-+ return skb;
-+
-+fail:
-+ kfree_skb(skb);
-+ return NULL;
-+}
-+
-+static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data)
-+{
-+ __u8 ident = l2cap_get_ident(conn);
-+ struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
-+
-+ BT_DBG("code 0x%2.2x", code);
-+
-+ if (!skb)
-+ return -ENOMEM;
-+ return hci_send_acl(conn->hcon, skb, 0);
-+}
-+
-+static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data)
-+{
-+ struct sk_buff *skb = l2cap_build_cmd(conn, code, ident, len, data);
-+
-+ BT_DBG("code 0x%2.2x", code);
-+
-+ if (!skb)
-+ return -ENOMEM;
-+ return hci_send_acl(conn->hcon, skb, 0);
-+}
-+
-+static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned long *val)
-+{
-+ l2cap_conf_opt *opt = *ptr;
-+ int len;
-+
-+ len = L2CAP_CONF_OPT_SIZE + opt->len;
-+ *ptr += len;
-+
-+ *type = opt->type;
-+ *olen = opt->len;
-+
-+ switch (opt->len) {
-+ case 1:
-+ *val = *((__u8 *) opt->val);
-+ break;
-+
-+ case 2:
-+ *val = __le16_to_cpu(*((__u16 *)opt->val));
-+ break;
-+
-+ case 4:
-+ *val = __le32_to_cpu(*((__u32 *)opt->val));
-+ break;
-+
-+ default:
-+ *val = (unsigned long) opt->val;
-+ break;
-+ };
-+
-+ BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val);
-+ return len;
-+}
-+
-+static inline void l2cap_parse_conf_req(struct sock *sk, void *data, int len)
-+{
-+ int type, hint, olen;
-+ unsigned long val;
-+ void *ptr = data;
-+
-+ BT_DBG("sk %p len %d", sk, len);
-+
-+ while (len >= L2CAP_CONF_OPT_SIZE) {
-+ len -= l2cap_get_conf_opt(&ptr, &type, &olen, &val);
-+
-+ hint = type & 0x80;
-+ type &= 0x7f;
-+
-+ switch (type) {
-+ case L2CAP_CONF_MTU:
-+ l2cap_pi(sk)->conf_mtu = val;
-+ break;
-+
-+ case L2CAP_CONF_FLUSH_TO:
-+ l2cap_pi(sk)->flush_to = val;
-+ break;
-+
-+ case L2CAP_CONF_QOS:
-+ break;
-+
-+ default:
-+ if (hint)
-+ break;
-+
-+ /* FIXME: Reject unknown option */
-+ break;
-+ };
-+ }
-+}
-+
-+static void l2cap_add_conf_opt(void **ptr, __u8 type, __u8 len, unsigned long val)
-+{
-+ register l2cap_conf_opt *opt = *ptr;
-+
-+ BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val);
-+
-+ opt->type = type;
-+ opt->len = len;
-+
-+ switch (len) {
-+ case 1:
-+ *((__u8 *) opt->val) = val;
-+ break;
-+
-+ case 2:
-+ *((__u16 *) opt->val) = __cpu_to_le16(val);
-+ break;
-+
-+ case 4:
-+ *((__u32 *) opt->val) = __cpu_to_le32(val);
-+ break;
-+
-+ default:
-+ memcpy(opt->val, (void *) val, len);
-+ break;
-+ };
-+
-+ *ptr += L2CAP_CONF_OPT_SIZE + len;
-+}
-+
-+static int l2cap_build_conf_req(struct sock *sk, void *data)
-+{
-+ struct l2cap_pinfo *pi = l2cap_pi(sk);
-+ l2cap_conf_req *req = (l2cap_conf_req *) data;
-+ void *ptr = req->data;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (pi->imtu != L2CAP_DEFAULT_MTU)
-+ l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
-+
-+ /* FIXME. Need actual value of the flush timeout */
-+ //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
-+ // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
-+
-+ req->dcid = __cpu_to_le16(pi->dcid);
-+ req->flags = __cpu_to_le16(0);
-+
-+ return ptr - data;
-+}
-+
-+static inline int l2cap_conf_output(struct sock *sk, void **ptr)
-+{
-+ struct l2cap_pinfo *pi = l2cap_pi(sk);
-+ int result = 0;
-+
-+ /* Configure output options and let the other side know
-+ * which ones we don't like.
-+ */
-+ if (pi->conf_mtu < pi->omtu) {
-+ l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, pi->omtu);
-+ result = L2CAP_CONF_UNACCEPT;
-+ } else {
-+ pi->omtu = pi->conf_mtu;
-+ }
-+
-+ BT_DBG("sk %p result %d", sk, result);
-+ return result;
-+}
-+
-+static int l2cap_build_conf_rsp(struct sock *sk, void *data, int *result)
-+{
-+ l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data;
-+ void *ptr = rsp->data;
-+ u16 flags = 0;
-+
-+ BT_DBG("sk %p complete %d", sk, result ? 1 : 0);
-+
-+ if (result)
-+ *result = l2cap_conf_output(sk, &ptr);
-+ else
-+ flags |= 0x0001;
-+
-+ rsp->scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ rsp->result = __cpu_to_le16(result ? *result : 0);
-+ rsp->flags = __cpu_to_le16(flags);
-+
-+ return ptr - data;
-+}
-+
-+static inline int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ struct l2cap_chan_list *list = &conn->chan_list;
-+ l2cap_conn_req *req = (l2cap_conn_req *) data;
-+ l2cap_conn_rsp rsp;
-+ struct sock *sk, *parent;
-+ int result = 0, status = 0;
-+
-+ __u16 dcid = 0, scid = __le16_to_cpu(req->scid);
-+ __u16 psm = req->psm;
-+
-+ BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
-+
-+ /* Check if we have socket listening on psm */
-+ parent = l2cap_get_sock_by_psm(BT_LISTEN, psm, conn->src);
-+ if (!parent) {
-+ result = L2CAP_CR_BAD_PSM;
-+ goto sendresp;
-+ }
-+
-+ result = L2CAP_CR_NO_MEM;
-+
-+ /* Check for backlog size */
-+ if (parent->ack_backlog > parent->max_ack_backlog) {
-+ BT_DBG("backlog full %d", parent->ack_backlog);
-+ goto response;
-+ }
-+
-+ sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC);
-+ if (!sk)
-+ goto response;
-+
-+ write_lock(&list->lock);
-+
-+ /* Check if we already have channel with that dcid */
-+ if (__l2cap_get_chan_by_dcid(list, scid)) {
-+ write_unlock(&list->lock);
-+ sk->zapped = 1;
-+ l2cap_sock_kill(sk);
-+ goto response;
-+ }
-+
-+ hci_conn_hold(conn->hcon);
-+
-+ l2cap_sock_init(sk, parent);
-+ bacpy(&bluez_pi(sk)->src, conn->src);
-+ bacpy(&bluez_pi(sk)->dst, conn->dst);
-+ l2cap_pi(sk)->psm = psm;
-+ l2cap_pi(sk)->dcid = scid;
-+
-+ __l2cap_chan_add(conn, sk, parent);
-+ dcid = l2cap_pi(sk)->scid;
-+
-+ l2cap_sock_set_timer(sk, sk->sndtimeo);
-+
-+ /* Service level security */
-+ result = L2CAP_CR_PEND;
-+ status = L2CAP_CS_AUTHEN_PEND;
-+ sk->state = BT_CONNECT2;
-+ l2cap_pi(sk)->ident = cmd->ident;
-+
-+ if (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) {
-+ if (!hci_conn_encrypt(conn->hcon))
-+ goto done;
-+ } else if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH) {
-+ if (!hci_conn_auth(conn->hcon))
-+ goto done;
-+ }
-+
-+ sk->state = BT_CONFIG;
-+ result = status = 0;
-+
-+done:
-+ write_unlock(&list->lock);
-+
-+response:
-+ bh_unlock_sock(parent);
-+
-+sendresp:
-+ rsp.scid = __cpu_to_le16(scid);
-+ rsp.dcid = __cpu_to_le16(dcid);
-+ rsp.result = __cpu_to_le16(result);
-+ rsp.status = __cpu_to_le16(status);
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
-+ return 0;
-+}
-+
-+static inline int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_conn_rsp *rsp = (l2cap_conn_rsp *) data;
-+ __u16 scid, dcid, result, status;
-+ struct sock *sk;
-+ char req[128];
-+
-+ scid = __le16_to_cpu(rsp->scid);
-+ dcid = __le16_to_cpu(rsp->dcid);
-+ result = __le16_to_cpu(rsp->result);
-+ status = __le16_to_cpu(rsp->status);
-+
-+ BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-+ return -ENOENT;
-+
-+ switch (result) {
-+ case L2CAP_CR_SUCCESS:
-+ sk->state = BT_CONFIG;
-+ l2cap_pi(sk)->dcid = dcid;
-+ l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
-+
-+ l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-+ break;
-+
-+ case L2CAP_CR_PEND:
-+ break;
-+
-+ default:
-+ l2cap_chan_del(sk, ECONNREFUSED);
-+ break;
-+ }
-+
-+ bh_unlock_sock(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_conf_req * req = (l2cap_conf_req *) data;
-+ __u16 dcid, flags;
-+ __u8 rsp[64];
-+ struct sock *sk;
-+ int result;
-+
-+ dcid = __le16_to_cpu(req->dcid);
-+ flags = __le16_to_cpu(req->flags);
-+
-+ BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-+ return -ENOENT;
-+
-+ l2cap_parse_conf_req(sk, req->data, cmd->len - L2CAP_CONF_REQ_SIZE);
-+
-+ if (flags & 0x0001) {
-+ /* Incomplete config. Send empty response. */
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
-+ goto unlock;
-+ }
-+
-+ /* Complete config. */
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &result), rsp);
-+
-+ if (result)
-+ goto unlock;
-+
-+ /* Output config done */
-+ l2cap_pi(sk)->conf_state |= L2CAP_CONF_OUTPUT_DONE;
-+
-+ if (l2cap_pi(sk)->conf_state & L2CAP_CONF_INPUT_DONE) {
-+ sk->state = BT_CONNECTED;
-+ l2cap_chan_ready(sk);
-+ } else if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT)) {
-+ char req[64];
-+ l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-+ }
-+
-+unlock:
-+ bh_unlock_sock(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_conf_rsp *rsp = (l2cap_conf_rsp *)data;
-+ __u16 scid, flags, result;
-+ struct sock *sk;
-+ int err = 0;
-+
-+ scid = __le16_to_cpu(rsp->scid);
-+ flags = __le16_to_cpu(rsp->flags);
-+ result = __le16_to_cpu(rsp->result);
-+
-+ BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-+ return -ENOENT;
-+
-+ switch (result) {
-+ case L2CAP_CONF_SUCCESS:
-+ break;
-+
-+ case L2CAP_CONF_UNACCEPT:
-+ if (++l2cap_pi(sk)->conf_retry < L2CAP_CONF_MAX_RETRIES) {
-+ char req[128];
-+ /*
-+ It does not make sense to adjust L2CAP parameters
-+ that are currently defined in the spec. We simply
-+ resend config request that we sent earlier. It is
-+ stupid :) but it helps qualification testing
-+ which expects at least some response from us.
-+ */
-+ l2cap_send_req(conn, L2CAP_CONF_REQ,
-+ l2cap_build_conf_req(sk, req), req);
-+ goto done;
-+ }
-+ default:
-+ sk->state = BT_DISCONN;
-+ sk->err = ECONNRESET;
-+ l2cap_sock_set_timer(sk, HZ * 5);
-+ {
-+ l2cap_disconn_req req;
-+ req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
-+ }
-+ goto done;
-+ }
-+
-+ if (flags & 0x01)
-+ goto done;
-+
-+ /* Input config done */
-+ l2cap_pi(sk)->conf_state |= L2CAP_CONF_INPUT_DONE;
-+
-+ if (l2cap_pi(sk)->conf_state & L2CAP_CONF_OUTPUT_DONE) {
-+ sk->state = BT_CONNECTED;
-+ l2cap_chan_ready(sk);
-+ }
-+
-+done:
-+ bh_unlock_sock(sk);
-+ return err;
-+}
-+
-+static inline int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_disconn_req *req = (l2cap_disconn_req *) data;
-+ l2cap_disconn_rsp rsp;
-+ __u16 dcid, scid;
-+ struct sock *sk;
-+
-+ scid = __le16_to_cpu(req->scid);
-+ dcid = __le16_to_cpu(req->dcid);
-+
-+ BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-+ return 0;
-+
-+ rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ l2cap_send_rsp(conn, cmd->ident, L2CAP_DISCONN_RSP, L2CAP_DISCONN_RSP_SIZE, &rsp);
-+
-+ sk->shutdown = SHUTDOWN_MASK;
-+
-+ l2cap_chan_del(sk, ECONNRESET);
-+ bh_unlock_sock(sk);
-+
-+ l2cap_sock_kill(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
-+{
-+ l2cap_disconn_rsp *rsp = (l2cap_disconn_rsp *) data;
-+ __u16 dcid, scid;
-+ struct sock *sk;
-+
-+ scid = __le16_to_cpu(rsp->scid);
-+ dcid = __le16_to_cpu(rsp->dcid);
-+
-+ BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
-+
-+ if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-+ return 0;
-+ l2cap_chan_del(sk, 0);
-+ bh_unlock_sock(sk);
-+
-+ l2cap_sock_kill(sk);
-+ return 0;
-+}
-+
-+static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
-+{
-+ __u8 *data = skb->data;
-+ int len = skb->len;
-+ l2cap_cmd_hdr cmd;
-+ int err = 0;
-+
-+ while (len >= L2CAP_CMD_HDR_SIZE) {
-+ memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
-+ data += L2CAP_CMD_HDR_SIZE;
-+ len -= L2CAP_CMD_HDR_SIZE;
-+
-+ cmd.len = __le16_to_cpu(cmd.len);
-+
-+ BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
-+
-+ if (cmd.len > len || !cmd.ident) {
-+ BT_DBG("corrupted command");
-+ break;
-+ }
-+
-+ switch (cmd.code) {
-+ case L2CAP_CONN_REQ:
-+ err = l2cap_connect_req(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_CONN_RSP:
-+ err = l2cap_connect_rsp(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_CONF_REQ:
-+ err = l2cap_config_req(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_CONF_RSP:
-+ err = l2cap_config_rsp(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_DISCONN_REQ:
-+ err = l2cap_disconnect_req(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_DISCONN_RSP:
-+ err = l2cap_disconnect_rsp(conn, &cmd, data);
-+ break;
-+
-+ case L2CAP_COMMAND_REJ:
-+ /* FIXME: We should process this */
-+ l2cap_raw_recv(conn, skb);
-+ break;
-+
-+ case L2CAP_ECHO_REQ:
-+ l2cap_send_rsp(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data);
-+ break;
-+
-+ case L2CAP_ECHO_RSP:
-+ case L2CAP_INFO_REQ:
-+ case L2CAP_INFO_RSP:
-+ l2cap_raw_recv(conn, skb);
-+ break;
-+
-+ default:
-+ BT_ERR("Uknown signaling command 0x%2.2x", cmd.code);
-+ err = -EINVAL;
-+ break;
-+ };
-+
-+ if (err) {
-+ l2cap_cmd_rej rej;
-+ BT_DBG("error %d", err);
-+
-+ /* FIXME: Map err to a valid reason. */
-+ rej.reason = __cpu_to_le16(0);
-+ l2cap_send_rsp(conn, cmd.ident, L2CAP_COMMAND_REJ, L2CAP_CMD_REJ_SIZE, &rej);
-+ }
-+
-+ data += cmd.len;
-+ len -= cmd.len;
-+ }
-+
-+ kfree_skb(skb);
-+}
-+
-+static inline int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
-+{
-+ struct sock *sk;
-+
-+ sk = l2cap_get_chan_by_scid(&conn->chan_list, cid);
-+ if (!sk) {
-+ BT_DBG("unknown cid 0x%4.4x", cid);
-+ goto drop;
-+ }
-+
-+ BT_DBG("sk %p, len %d", sk, skb->len);
-+
-+ if (sk->state != BT_CONNECTED)
-+ goto drop;
-+
-+ if (l2cap_pi(sk)->imtu < skb->len)
-+ goto drop;
-+
-+ /* If socket recv buffers overflows we drop data here
-+ * which is *bad* because L2CAP has to be reliable.
-+ * But we don't have any other choice. L2CAP doesn't
-+ * provide flow control mechanism */
-+
-+ if (!sock_queue_rcv_skb(sk, skb))
-+ goto done;
-+
-+drop:
-+ kfree_skb(skb);
-+
-+done:
-+ if (sk) bh_unlock_sock(sk);
-+ return 0;
-+}
-+
-+static inline int l2cap_conless_channel(struct l2cap_conn *conn, __u16 psm, struct sk_buff *skb)
-+{
-+ struct sock *sk;
-+
-+ sk = l2cap_get_sock_by_psm(0, psm, conn->src);
-+ if (!sk)
-+ goto drop;
-+
-+ BT_DBG("sk %p, len %d", sk, skb->len);
-+
-+ if (sk->state != BT_BOUND && sk->state != BT_CONNECTED)
-+ goto drop;
-+
-+ if (l2cap_pi(sk)->imtu < skb->len)
-+ goto drop;
-+
-+ if (!sock_queue_rcv_skb(sk, skb))
-+ goto done;
-+
-+drop:
-+ kfree_skb(skb);
-+
-+done:
-+ if (sk) bh_unlock_sock(sk);
-+ return 0;
-+}
-+
-+static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
-+{
-+ l2cap_hdr *lh = (l2cap_hdr *) skb->data;
-+ __u16 cid, psm, len;
-+
-+ skb_pull(skb, L2CAP_HDR_SIZE);
-+ cid = __le16_to_cpu(lh->cid);
-+ len = __le16_to_cpu(lh->len);
-+
-+ BT_DBG("len %d, cid 0x%4.4x", len, cid);
-+
-+ switch (cid) {
-+ case 0x0001:
-+ l2cap_sig_channel(conn, skb);
-+ break;
-+
-+ case 0x0002:
-+ psm = get_unaligned((__u16 *) skb->data);
-+ skb_pull(skb, 2);
-+ l2cap_conless_channel(conn, psm, skb);
-+ break;
-+
-+ default:
-+ l2cap_data_channel(conn, cid, skb);
-+ break;
-+ }
-+}
-+
-+/* ------------ L2CAP interface with lower layer (HCI) ------------- */
-+
-+static int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
-+{
-+ int exact = 0, lm1 = 0, lm2 = 0;
-+ register struct sock *sk;
-+
-+ if (type != ACL_LINK)
-+ return 0;
-+
-+ BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
-+
-+ /* Find listening sockets and check their link_mode */
-+ read_lock(&l2cap_sk_list.lock);
-+ for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-+ if (sk->state != BT_LISTEN)
-+ continue;
-+
-+ if (!bacmp(&bluez_pi(sk)->src, &hdev->bdaddr)) {
-+ lm1 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode);
-+ exact++;
-+ } else if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
-+ lm2 |= (HCI_LM_ACCEPT | l2cap_pi(sk)->link_mode);
-+ }
-+ read_unlock(&l2cap_sk_list.lock);
-+
-+ return exact ? lm1 : lm2;
-+}
-+
-+static int l2cap_connect_cfm(struct hci_conn *hcon, __u8 status)
-+{
-+ BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
-+
-+ if (hcon->type != ACL_LINK)
-+ return 0;
-+
-+ if (!status) {
-+ struct l2cap_conn *conn;
-+
-+ conn = l2cap_conn_add(hcon, status);
-+ if (conn)
-+ l2cap_conn_ready(conn);
-+ } else
-+ l2cap_conn_del(hcon, bterr(status));
-+
-+ return 0;
-+}
-+
-+static int l2cap_disconn_ind(struct hci_conn *hcon, __u8 reason)
-+{
-+ BT_DBG("hcon %p reason %d", hcon, reason);
-+
-+ if (hcon->type != ACL_LINK)
-+ return 0;
-+
-+ l2cap_conn_del(hcon, bterr(reason));
-+ return 0;
-+}
-+
-+static int l2cap_auth_cfm(struct hci_conn *hcon, __u8 status)
-+{
-+ struct l2cap_chan_list *l;
-+ struct l2cap_conn *conn;
-+ l2cap_conn_rsp rsp;
-+ struct sock *sk;
-+ int result;
-+
-+ if (!(conn = hcon->l2cap_data))
-+ return 0;
-+ l = &conn->chan_list;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ bh_lock_sock(sk);
-+
-+ if (sk->state != BT_CONNECT2 ||
-+ (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT)) {
-+ bh_unlock_sock(sk);
-+ continue;
-+ }
-+
-+ if (!status) {
-+ sk->state = BT_CONFIG;
-+ result = 0;
-+ } else {
-+ sk->state = BT_DISCONN;
-+ l2cap_sock_set_timer(sk, HZ/10);
-+ result = L2CAP_CR_SEC_BLOCK;
-+ }
-+
-+ rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ rsp.result = __cpu_to_le16(result);
-+ rsp.status = __cpu_to_le16(0);
-+ l2cap_send_rsp(conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP,
-+ L2CAP_CONN_RSP_SIZE, &rsp);
-+
-+ bh_unlock_sock(sk);
-+ }
-+
-+ read_unlock(&l->lock);
-+ return 0;
-+}
-+
-+static int l2cap_encrypt_cfm(struct hci_conn *hcon, __u8 status)
-+{
-+ struct l2cap_chan_list *l;
-+ struct l2cap_conn *conn;
-+ l2cap_conn_rsp rsp;
-+ struct sock *sk;
-+ int result;
-+
-+ if (!(conn = hcon->l2cap_data))
-+ return 0;
-+ l = &conn->chan_list;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ read_lock(&l->lock);
-+
-+ for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-+ bh_lock_sock(sk);
-+
-+ if (sk->state != BT_CONNECT2) {
-+ bh_unlock_sock(sk);
-+ continue;
-+ }
-+
-+ if (!status) {
-+ sk->state = BT_CONFIG;
-+ result = 0;
-+ } else {
-+ sk->state = BT_DISCONN;
-+ l2cap_sock_set_timer(sk, HZ/10);
-+ result = L2CAP_CR_SEC_BLOCK;
-+ }
-+
-+ rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-+ rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-+ rsp.result = __cpu_to_le16(result);
-+ rsp.status = __cpu_to_le16(0);
-+ l2cap_send_rsp(conn, l2cap_pi(sk)->ident, L2CAP_CONN_RSP,
-+ L2CAP_CONN_RSP_SIZE, &rsp);
-+
-+ bh_unlock_sock(sk);
-+ }
-+
-+ read_unlock(&l->lock);
-+ return 0;
-+}
-+
-+static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, __u16 flags)
-+{
-+ struct l2cap_conn *conn = hcon->l2cap_data;
-+
-+ if (!conn && !(conn = l2cap_conn_add(hcon, 0)))
-+ goto drop;
-+
-+ BT_DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
-+
-+ if (flags & ACL_START) {
-+ l2cap_hdr *hdr;
-+ int len;
-+
-+ if (conn->rx_len) {
-+ BT_ERR("Unexpected start frame (len %d)", skb->len);
-+ kfree_skb(conn->rx_skb);
-+ conn->rx_skb = NULL;
-+ conn->rx_len = 0;
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ }
-+
-+ if (skb->len < 2) {
-+ BT_ERR("Frame is too short (len %d)", skb->len);
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ goto drop;
-+ }
-+
-+ hdr = (l2cap_hdr *) skb->data;
-+ len = __le16_to_cpu(hdr->len) + L2CAP_HDR_SIZE;
-+
-+ if (len == skb->len) {
-+ /* Complete frame received */
-+ l2cap_recv_frame(conn, skb);
-+ return 0;
-+ }
-+
-+ BT_DBG("Start: total len %d, frag len %d", len, skb->len);
-+
-+ if (skb->len > len) {
-+ BT_ERR("Frame is too long (len %d, expected len %d)",
-+ skb->len, len);
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ goto drop;
-+ }
-+
-+ /* Allocate skb for the complete frame including header */
-+ conn->rx_skb = bluez_skb_alloc(len, GFP_ATOMIC);
-+ if (!conn->rx_skb)
-+ goto drop;
-+
-+ memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
-+ conn->rx_len = len - skb->len;
-+ } else {
-+ BT_DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
-+
-+ if (!conn->rx_len) {
-+ BT_ERR("Unexpected continuation frame (len %d)", skb->len);
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ goto drop;
-+ }
-+
-+ if (skb->len > conn->rx_len) {
-+ BT_ERR("Fragment is too long (len %d, expected %d)",
-+ skb->len, conn->rx_len);
-+ kfree_skb(conn->rx_skb);
-+ conn->rx_skb = NULL;
-+ conn->rx_len = 0;
-+ l2cap_conn_unreliable(conn, ECOMM);
-+ goto drop;
-+ }
-+
-+ memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
-+ conn->rx_len -= skb->len;
-+
-+ if (!conn->rx_len) {
-+ /* Complete frame received */
-+ l2cap_recv_frame(conn, conn->rx_skb);
-+ conn->rx_skb = NULL;
-+ }
-+ }
-+
-+drop:
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+/* ----- Proc fs support ------ */
-+static int l2cap_sock_dump(char *buf, struct bluez_sock_list *list)
-+{
-+ struct l2cap_pinfo *pi;
-+ struct sock *sk;
-+ char *ptr = buf;
-+
-+ read_lock_bh(&list->lock);
-+
-+ for (sk = list->head; sk; sk = sk->next) {
-+ pi = l2cap_pi(sk);
-+ ptr += sprintf(ptr, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d 0x%x\n",
-+ batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
-+ sk->state, pi->psm, pi->scid, pi->dcid, pi->imtu, pi->omtu,
-+ pi->link_mode);
-+ }
-+
-+ read_unlock_bh(&list->lock);
-+
-+ ptr += sprintf(ptr, "\n");
-+ return ptr - buf;
-+}
-+
-+static int l2cap_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
-+{
-+ char *ptr = buf;
-+ int len;
-+
-+ BT_DBG("count %d, offset %ld", count, offset);
-+
-+ ptr += l2cap_sock_dump(ptr, &l2cap_sk_list);
-+ len = ptr - buf;
-+
-+ if (len <= count + offset)
-+ *eof = 1;
-+
-+ *start = buf + offset;
-+ len -= offset;
-+
-+ if (len > count)
-+ len = count;
-+ if (len < 0)
-+ len = 0;
-+
-+ return len;
-+}
-+
-+static struct proto_ops l2cap_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: l2cap_sock_release,
-+ bind: l2cap_sock_bind,
-+ connect: l2cap_sock_connect,
-+ listen: l2cap_sock_listen,
-+ accept: l2cap_sock_accept,
-+ getname: l2cap_sock_getname,
-+ sendmsg: l2cap_sock_sendmsg,
-+ recvmsg: bluez_sock_recvmsg,
-+ poll: bluez_sock_poll,
-+ socketpair: sock_no_socketpair,
-+ ioctl: sock_no_ioctl,
-+ shutdown: l2cap_sock_shutdown,
-+ setsockopt: l2cap_sock_setsockopt,
-+ getsockopt: l2cap_sock_getsockopt,
-+ mmap: sock_no_mmap
-+};
-+
-+static struct net_proto_family l2cap_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: l2cap_sock_create
-+};
-+
-+static struct hci_proto l2cap_hci_proto = {
-+ name: "L2CAP",
-+ id: HCI_PROTO_L2CAP,
-+ connect_ind: l2cap_connect_ind,
-+ connect_cfm: l2cap_connect_cfm,
-+ disconn_ind: l2cap_disconn_ind,
-+ recv_acldata: l2cap_recv_acldata,
-+ auth_cfm: l2cap_auth_cfm,
-+ encrypt_cfm: l2cap_encrypt_cfm
-+};
-+
-+int __init l2cap_init(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops))) {
-+ BT_ERR("Can't register L2CAP socket");
-+ return err;
-+ }
-+
-+ if ((err = hci_register_proto(&l2cap_hci_proto))) {
-+ BT_ERR("Can't register L2CAP protocol");
-+ return err;
-+ }
-+
-+ create_proc_read_entry("bluetooth/l2cap", 0, 0, l2cap_read_proc, NULL);
-+
-+ BT_INFO("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ return 0;
-+}
-+
-+void l2cap_cleanup(void)
-+{
-+ remove_proc_entry("bluetooth/l2cap", NULL);
-+
-+ /* Unregister socket and protocol */
-+ if (bluez_sock_unregister(BTPROTO_L2CAP))
-+ BT_ERR("Can't unregister L2CAP socket");
-+
-+ if (hci_unregister_proto(&l2cap_hci_proto))
-+ BT_ERR("Can't unregister L2CAP protocol");
-+}
-+
-+void l2cap_load(void)
-+{
-+ /* Dummy function to trigger automatic L2CAP module loading by
-+ other modules that use L2CAP sockets but do not use any other
-+ symbols from it. */
-+ return;
-+}
-+
-+EXPORT_SYMBOL(l2cap_load);
-+
-+module_init(l2cap_init);
-+module_exit(l2cap_cleanup);
-+
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
-+MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/l2cap_core.c linux-2.4.18-mh9/net/bluetooth/l2cap_core.c
---- linux-2.4.18/net/bluetooth/l2cap_core.c Sun Sep 30 21:26:08 2001
-+++ linux-2.4.18-mh9/net/bluetooth/l2cap_core.c Thu Jan 1 01:00:00 1970
-@@ -1,2316 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * BlueZ L2CAP core and sockets.
-- *
-- * $Id$
-- */
--#define VERSION "1.1"
--
--#include <linux/config.h>
--#include <linux/module.h>
--
--#include <linux/types.h>
--#include <linux/errno.h>
--#include <linux/kernel.h>
--#include <linux/major.h>
--#include <linux/sched.h>
--#include <linux/slab.h>
--#include <linux/poll.h>
--#include <linux/fcntl.h>
--#include <linux/init.h>
--#include <linux/skbuff.h>
--#include <linux/interrupt.h>
--#include <linux/socket.h>
--#include <linux/skbuff.h>
--#include <linux/proc_fs.h>
--#include <linux/list.h>
--#include <net/sock.h>
--
--#include <asm/system.h>
--#include <asm/uaccess.h>
--
--#include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
--#include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/l2cap.h>
--#include <net/bluetooth/l2cap_core.h>
--
--#ifndef L2CAP_DEBUG
--#undef DBG
--#define DBG( A... )
--#endif
--
--struct proto_ops l2cap_sock_ops;
--
--struct bluez_sock_list l2cap_sk_list = {
-- lock: RW_LOCK_UNLOCKED
--};
--
--struct list_head l2cap_iff_list = LIST_HEAD_INIT(l2cap_iff_list);
--rwlock_t l2cap_rt_lock = RW_LOCK_UNLOCKED;
--
--static int l2cap_conn_del(struct l2cap_conn *conn, int err);
--
--static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent);
--static void l2cap_chan_del(struct sock *sk, int err);
--static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len);
--
--static void l2cap_sock_close(struct sock *sk);
--static void l2cap_sock_kill(struct sock *sk);
--
--static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data);
--static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data);
--
--/* -------- L2CAP interfaces & routing --------- */
--/* Add/delete L2CAP interface.
-- * Must be called with locked rt_lock
-- */
--
--static void l2cap_iff_add(struct hci_dev *hdev)
--{
-- struct l2cap_iff *iff;
--
-- DBG("%s", hdev->name);
--
-- DBG("iff_list %p next %p prev %p", &l2cap_iff_list, l2cap_iff_list.next, l2cap_iff_list.prev);
--
-- /* Allocate new interface and lock HCI device */
-- if (!(iff = kmalloc(sizeof(struct l2cap_iff), GFP_KERNEL))) {
-- ERR("Can't allocate new interface %s", hdev->name);
-- return;
-- }
-- memset(iff, 0, sizeof(struct l2cap_iff));
--
-- hci_dev_hold(hdev);
-- hdev->l2cap_data = iff;
-- iff->hdev = hdev;
-- iff->mtu = hdev->acl_mtu - HCI_ACL_HDR_SIZE;
-- iff->bdaddr = &hdev->bdaddr;
--
-- spin_lock_init(&iff->lock);
-- INIT_LIST_HEAD(&iff->conn_list);
--
-- list_add(&iff->list, &l2cap_iff_list);
--}
--
--static void l2cap_iff_del(struct hci_dev *hdev)
--{
-- struct l2cap_iff *iff;
--
-- if (!(iff = hdev->l2cap_data))
-- return;
--
-- DBG("%s iff %p", hdev->name, iff);
--
-- list_del(&iff->list);
--
-- l2cap_iff_lock(iff);
--
-- /* Drop connections */
-- while (!list_empty(&iff->conn_list)) {
-- struct l2cap_conn *c;
--
-- c = list_entry(iff->conn_list.next, struct l2cap_conn, list);
-- l2cap_conn_del(c, ENODEV);
-- }
--
-- l2cap_iff_unlock(iff);
--
-- /* Unlock HCI device */
-- hdev->l2cap_data = NULL;
-- hci_dev_put(hdev);
--
-- kfree(iff);
--}
--
--/* Get route. Returns L2CAP interface.
-- * Must be called with locked rt_lock
-- */
--static struct l2cap_iff *l2cap_get_route(bdaddr_t *src, bdaddr_t *dst)
--{
-- struct list_head *p;
-- int use_src;
--
-- DBG("%s -> %s", batostr(src), batostr(dst));
--
-- use_src = bacmp(src, BDADDR_ANY) ? 0 : 1;
--
-- /* Simple routing:
-- * No source address - find interface with bdaddr != dst
-- * Source address - find interface with bdaddr == src
-- */
--
-- list_for_each(p, &l2cap_iff_list) {
-- struct l2cap_iff *iff;
--
-- iff = list_entry(p, struct l2cap_iff, list);
--
-- if (use_src && !bacmp(iff->bdaddr, src))
-- return iff;
-- else if (bacmp(iff->bdaddr, dst))
-- return iff;
-- }
-- return NULL;
--}
--
--/* ----- L2CAP timers ------ */
--static void l2cap_sock_timeout(unsigned long arg)
--{
-- struct sock *sk = (struct sock *) arg;
--
-- DBG("sock %p state %d", sk, sk->state);
--
-- bh_lock_sock(sk);
-- switch (sk->state) {
-- case BT_DISCONN:
-- l2cap_chan_del(sk, ETIMEDOUT);
-- break;
--
-- default:
-- sk->err = ETIMEDOUT;
-- sk->state_change(sk);
-- break;
-- };
-- bh_unlock_sock(sk);
--
-- l2cap_sock_kill(sk);
-- sock_put(sk);
--}
--
--static void l2cap_sock_set_timer(struct sock *sk, long timeout)
--{
-- DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
--
-- if (!mod_timer(&sk->timer, jiffies + timeout))
-- sock_hold(sk);
--}
--
--static void l2cap_sock_clear_timer(struct sock *sk)
--{
-- DBG("sock %p state %d", sk, sk->state);
--
-- if (timer_pending(&sk->timer) && del_timer(&sk->timer))
-- __sock_put(sk);
--}
--
--static void l2cap_sock_init_timer(struct sock *sk)
--{
-- init_timer(&sk->timer);
-- sk->timer.function = l2cap_sock_timeout;
-- sk->timer.data = (unsigned long)sk;
--}
--
--static void l2cap_conn_timeout(unsigned long arg)
--{
-- struct l2cap_conn *conn = (void *)arg;
--
-- DBG("conn %p state %d", conn, conn->state);
--
-- if (conn->state == BT_CONNECTED) {
-- hci_disconnect(conn->hconn, 0x13);
-- }
--
-- return;
--}
--
--static void l2cap_conn_set_timer(struct l2cap_conn *conn, long timeout)
--{
-- DBG("conn %p state %d timeout %ld", conn, conn->state, timeout);
--
-- mod_timer(&conn->timer, jiffies + timeout);
--}
--
--static void l2cap_conn_clear_timer(struct l2cap_conn *conn)
--{
-- DBG("conn %p state %d", conn, conn->state);
--
-- del_timer(&conn->timer);
--}
--
--static void l2cap_conn_init_timer(struct l2cap_conn *conn)
--{
-- init_timer(&conn->timer);
-- conn->timer.function = l2cap_conn_timeout;
-- conn->timer.data = (unsigned long)conn;
--}
--
--/* -------- L2CAP connections --------- */
--/* Add new connection to the interface.
-- * Interface must be locked
-- */
--static struct l2cap_conn *l2cap_conn_add(struct l2cap_iff *iff, bdaddr_t *dst)
--{
-- struct l2cap_conn *conn;
-- bdaddr_t *src = iff->bdaddr;
--
-- if (!(conn = kmalloc(sizeof(struct l2cap_conn), GFP_KERNEL)))
-- return NULL;
--
-- memset(conn, 0, sizeof(struct l2cap_conn));
--
-- conn->state = BT_OPEN;
-- conn->iff = iff;
-- bacpy(&conn->src, src);
-- bacpy(&conn->dst, dst);
--
-- spin_lock_init(&conn->lock);
-- conn->chan_list.lock = RW_LOCK_UNLOCKED;
--
-- l2cap_conn_init_timer(conn);
--
-- __l2cap_conn_link(iff, conn);
--
-- DBG("%s -> %s, %p", batostr(src), batostr(dst), conn);
--
-- MOD_INC_USE_COUNT;
--
-- return conn;
--}
--
--/* Delete connection on the interface.
-- * Interface must be locked
-- */
--static int l2cap_conn_del(struct l2cap_conn *conn, int err)
--{
-- struct sock *sk;
--
-- DBG("conn %p, state %d, err %d", conn, conn->state, err);
--
-- l2cap_conn_clear_timer(conn);
-- __l2cap_conn_unlink(conn->iff, conn);
--
-- conn->state = BT_CLOSED;
--
-- if (conn->rx_skb)
-- kfree_skb(conn->rx_skb);
--
-- /* Kill channels */
-- while ((sk = conn->chan_list.head)) {
-- bh_lock_sock(sk);
-- l2cap_sock_clear_timer(sk);
-- l2cap_chan_del(sk, err);
-- bh_unlock_sock(sk);
--
-- l2cap_sock_kill(sk);
-- }
--
-- kfree(conn);
--
-- MOD_DEC_USE_COUNT;
-- return 0;
--}
--
--static inline struct l2cap_conn *l2cap_get_conn_by_addr(struct l2cap_iff *iff, bdaddr_t *dst)
--{
-- struct list_head *p;
--
-- list_for_each(p, &iff->conn_list) {
-- struct l2cap_conn *c;
--
-- c = list_entry(p, struct l2cap_conn, list);
-- if (!bacmp(&c->dst, dst))
-- return c;
-- }
-- return NULL;
--}
--
--int l2cap_connect(struct sock *sk)
--{
-- bdaddr_t *src = &l2cap_pi(sk)->src;
-- bdaddr_t *dst = &l2cap_pi(sk)->dst;
-- struct l2cap_conn *conn;
-- struct l2cap_iff *iff;
-- int err = 0;
--
-- DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
--
-- read_lock_bh(&l2cap_rt_lock);
--
-- /* Get route to remote BD address */
-- if (!(iff = l2cap_get_route(src, dst))) {
-- err = -EHOSTUNREACH;
-- goto done;
-- }
--
-- /* Update source addr of the socket */
-- bacpy(src, iff->bdaddr);
--
-- l2cap_iff_lock(iff);
--
-- if (!(conn = l2cap_get_conn_by_addr(iff, dst))) {
-- /* Connection doesn't exist */
-- if (!(conn = l2cap_conn_add(iff, dst))) {
-- l2cap_iff_unlock(iff);
-- err = -ENOMEM;
-- goto done;
-- }
-- conn->out = 1;
-- }
--
-- l2cap_iff_unlock(iff);
--
-- l2cap_chan_add(conn, sk, NULL);
--
-- sk->state = BT_CONNECT;
-- l2cap_sock_set_timer(sk, sk->sndtimeo);
--
-- switch (conn->state) {
-- case BT_CONNECTED:
-- if (sk->type == SOCK_SEQPACKET) {
-- l2cap_conn_req req;
-- req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- req.psm = l2cap_pi(sk)->psm;
-- l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
-- } else {
-- l2cap_sock_clear_timer(sk);
-- sk->state = BT_CONNECTED;
-- }
-- break;
--
-- case BT_CONNECT:
-- break;
--
-- default:
-- /* Create ACL connection */
-- conn->state = BT_CONNECT;
-- hci_connect(iff->hdev, dst);
-- break;
-- };
--
--done:
-- read_unlock_bh(&l2cap_rt_lock);
-- return err;
--}
--
--/* ------ Channel queues for listening sockets ------ */
--void l2cap_accept_queue(struct sock *parent, struct sock *sk)
--{
-- struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
--
-- DBG("parent %p, sk %p", parent, sk);
--
-- sock_hold(sk);
-- l2cap_pi(sk)->parent = parent;
-- l2cap_pi(sk)->next_q = NULL;
--
-- if (!q->head) {
-- q->head = q->tail = sk;
-- } else {
-- struct sock *tail = q->tail;
--
-- l2cap_pi(sk)->prev_q = tail;
-- l2cap_pi(tail)->next_q = sk;
-- q->tail = sk;
-- }
--
-- parent->ack_backlog++;
--}
--
--void l2cap_accept_unlink(struct sock *sk)
--{
-- struct sock *parent = l2cap_pi(sk)->parent;
-- struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
-- struct sock *next, *prev;
--
-- DBG("sk %p", sk);
--
-- next = l2cap_pi(sk)->next_q;
-- prev = l2cap_pi(sk)->prev_q;
--
-- if (sk == q->head)
-- q->head = next;
-- if (sk == q->tail)
-- q->tail = prev;
--
-- if (next)
-- l2cap_pi(next)->prev_q = prev;
-- if (prev)
-- l2cap_pi(prev)->next_q = next;
--
-- l2cap_pi(sk)->parent = NULL;
--
-- parent->ack_backlog--;
-- __sock_put(sk);
--}
--
--/* Get next connected channel in queue. */
--struct sock *l2cap_accept_dequeue(struct sock *parent, int state)
--{
-- struct l2cap_accept_q *q = &l2cap_pi(parent)->accept_q;
-- struct sock *sk;
--
-- for (sk = q->head; sk; sk = l2cap_pi(sk)->next_q) {
-- if (!state || sk->state == state) {
-- l2cap_accept_unlink(sk);
-- break;
-- }
-- }
--
-- DBG("parent %p, sk %p", parent, sk);
--
-- return sk;
--}
--
--/* -------- Socket interface ---------- */
--static struct sock *__l2cap_get_sock_by_addr(struct sockaddr_l2 *addr)
--{
-- bdaddr_t *src = &addr->l2_bdaddr;
-- __u16 psm = addr->l2_psm;
-- struct sock *sk;
--
-- for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-- if (l2cap_pi(sk)->psm == psm &&
-- !bacmp(&l2cap_pi(sk)->src, src))
-- break;
-- }
--
-- return sk;
--}
--
--/* Find socket listening on psm and source bdaddr.
-- * Returns closest match.
-- */
--static struct sock *l2cap_get_sock_listen(bdaddr_t *src, __u16 psm)
--{
-- struct sock *sk, *sk1 = NULL;
--
-- read_lock(&l2cap_sk_list.lock);
--
-- for (sk = l2cap_sk_list.head; sk; sk = sk->next) {
-- struct l2cap_pinfo *pi;
--
-- if (sk->state != BT_LISTEN)
-- continue;
--
-- pi = l2cap_pi(sk);
--
-- if (pi->psm == psm) {
-- /* Exact match. */
-- if (!bacmp(&pi->src, src))
-- break;
--
-- /* Closest match */
-- if (!bacmp(&pi->src, BDADDR_ANY))
-- sk1 = sk;
-- }
-- }
--
-- read_unlock(&l2cap_sk_list.lock);
--
-- return sk ? sk : sk1;
--}
--
--static void l2cap_sock_destruct(struct sock *sk)
--{
-- DBG("sk %p", sk);
--
-- skb_queue_purge(&sk->receive_queue);
-- skb_queue_purge(&sk->write_queue);
--
-- MOD_DEC_USE_COUNT;
--}
--
--static void l2cap_sock_cleanup_listen(struct sock *parent)
--{
-- struct sock *sk;
--
-- DBG("parent %p", parent);
--
-- /* Close not yet accepted channels */
-- while ((sk = l2cap_accept_dequeue(parent, 0)))
-- l2cap_sock_close(sk);
--
-- parent->state = BT_CLOSED;
-- parent->zapped = 1;
--}
--
--/* Kill socket (only if zapped and orphan)
-- * Must be called on unlocked socket.
-- */
--static void l2cap_sock_kill(struct sock *sk)
--{
-- if (!sk->zapped || sk->socket)
-- return;
--
-- DBG("sk %p state %d", sk, sk->state);
--
-- /* Kill poor orphan */
-- bluez_sock_unlink(&l2cap_sk_list, sk);
-- sk->dead = 1;
-- sock_put(sk);
--}
--
--/* Close socket.
-- * Must be called on unlocked socket.
-- */
--static void l2cap_sock_close(struct sock *sk)
--{
-- struct l2cap_conn *conn;
--
-- l2cap_sock_clear_timer(sk);
--
-- lock_sock(sk);
--
-- conn = l2cap_pi(sk)->conn;
--
-- DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
--
-- switch (sk->state) {
-- case BT_LISTEN:
-- l2cap_sock_cleanup_listen(sk);
-- break;
--
-- case BT_CONNECTED:
-- case BT_CONFIG:
-- if (sk->type == SOCK_SEQPACKET) {
-- l2cap_disconn_req req;
--
-- sk->state = BT_DISCONN;
--
-- req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
--
-- l2cap_sock_set_timer(sk, sk->sndtimeo);
-- } else {
-- l2cap_chan_del(sk, ECONNRESET);
-- }
-- break;
--
-- case BT_CONNECT:
-- case BT_DISCONN:
-- l2cap_chan_del(sk, ECONNRESET);
-- break;
--
-- default:
-- sk->zapped = 1;
-- break;
-- };
--
-- release_sock(sk);
--
-- l2cap_sock_kill(sk);
--}
--
--static void l2cap_sock_init(struct sock *sk, struct sock *parent)
--{
-- struct l2cap_pinfo *pi = l2cap_pi(sk);
--
-- DBG("sk %p", sk);
--
-- if (parent) {
-- sk->type = parent->type;
--
-- pi->imtu = l2cap_pi(parent)->imtu;
-- pi->omtu = l2cap_pi(parent)->omtu;
-- } else {
-- pi->imtu = L2CAP_DEFAULT_MTU;
-- pi->omtu = 0;
-- }
--
-- /* Default config options */
-- pi->conf_mtu = L2CAP_DEFAULT_MTU;
-- pi->flush_to = L2CAP_DEFAULT_FLUSH_TO;
--}
--
--static struct sock *l2cap_sock_alloc(struct socket *sock, int proto, int prio)
--{
-- struct sock *sk;
--
-- if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
-- return NULL;
--
-- sock_init_data(sock, sk);
--
-- sk->zapped = 0;
--
-- sk->destruct = l2cap_sock_destruct;
-- sk->sndtimeo = L2CAP_CONN_TIMEOUT;
--
-- sk->protocol = proto;
-- sk->state = BT_OPEN;
--
-- l2cap_sock_init_timer(sk);
--
-- bluez_sock_link(&l2cap_sk_list, sk);
--
-- MOD_INC_USE_COUNT;
--
-- return sk;
--}
--
--static int l2cap_sock_create(struct socket *sock, int protocol)
--{
-- struct sock *sk;
--
-- DBG("sock %p", sock);
--
-- sock->state = SS_UNCONNECTED;
--
-- if (sock->type != SOCK_SEQPACKET && sock->type != SOCK_RAW)
-- return -ESOCKTNOSUPPORT;
--
-- sock->ops = &l2cap_sock_ops;
--
-- if (!(sk = l2cap_sock_alloc(sock, protocol, GFP_KERNEL)))
-- return -ENOMEM;
--
-- l2cap_sock_init(sk, NULL);
--
-- return 0;
--}
--
--static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
--{
-- struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-- struct sock *sk = sock->sk;
-- int err = 0;
--
-- DBG("sk %p, %s %d", sk, batostr(&la->l2_bdaddr), la->l2_psm);
--
-- if (!addr || addr->sa_family != AF_BLUETOOTH)
-- return -EINVAL;
--
-- lock_sock(sk);
--
-- if (sk->state != BT_OPEN) {
-- err = -EBADFD;
-- goto done;
-- }
--
-- write_lock(&l2cap_sk_list.lock);
--
-- if (la->l2_psm && __l2cap_get_sock_by_addr(la)) {
-- err = -EADDRINUSE;
-- goto unlock;
-- }
--
-- /* Save source address */
-- bacpy(&l2cap_pi(sk)->src, &la->l2_bdaddr);
-- l2cap_pi(sk)->psm = la->l2_psm;
-- sk->state = BT_BOUND;
--
--unlock:
-- write_unlock(&l2cap_sk_list.lock);
--
--done:
-- release_sock(sk);
--
-- return err;
--}
--
--static int l2cap_sock_w4_connect(struct sock *sk, int flags)
--{
-- DECLARE_WAITQUEUE(wait, current);
-- long timeo = sock_sndtimeo(sk, flags & O_NONBLOCK);
-- int err = 0;
--
-- DBG("sk %p", sk);
--
-- add_wait_queue(sk->sleep, &wait);
-- current->state = TASK_INTERRUPTIBLE;
--
-- while (sk->state != BT_CONNECTED) {
-- if (!timeo) {
-- err = -EAGAIN;
-- break;
-- }
--
-- release_sock(sk);
-- timeo = schedule_timeout(timeo);
-- lock_sock(sk);
--
-- err = 0;
-- if (sk->state == BT_CONNECTED)
-- break;
--
-- if (sk->err) {
-- err = sock_error(sk);
-- break;
-- }
--
-- if (signal_pending(current)) {
-- err = sock_intr_errno(timeo);
-- break;
-- }
-- }
-- current->state = TASK_RUNNING;
-- remove_wait_queue(sk->sleep, &wait);
--
-- return err;
--}
--
--static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
--{
-- struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-- struct sock *sk = sock->sk;
-- int err = 0;
--
-- lock_sock(sk);
--
-- DBG("sk %p", sk);
--
-- if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_l2)) {
-- err = -EINVAL;
-- goto done;
-- }
--
-- if (sk->state != BT_OPEN && sk->state != BT_BOUND) {
-- err = -EBADFD;
-- goto done;
-- }
--
-- if (sk->type == SOCK_SEQPACKET && !la->l2_psm) {
-- err = -EINVAL;
-- goto done;
-- }
--
-- /* Set destination address and psm */
-- bacpy(&l2cap_pi(sk)->dst, &la->l2_bdaddr);
-- l2cap_pi(sk)->psm = la->l2_psm;
--
-- if ((err = l2cap_connect(sk)))
-- goto done;
--
-- err = l2cap_sock_w4_connect(sk, flags);
--
--done:
-- release_sock(sk);
-- return err;
--}
--
--int l2cap_sock_listen(struct socket *sock, int backlog)
--{
-- struct sock *sk = sock->sk;
-- int err = 0;
--
-- DBG("sk %p backlog %d", sk, backlog);
--
-- lock_sock(sk);
--
-- if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
-- err = -EBADFD;
-- goto done;
-- }
--
-- if (!l2cap_pi(sk)->psm) {
-- err = -EINVAL;
-- goto done;
-- }
--
-- sk->max_ack_backlog = backlog;
-- sk->ack_backlog = 0;
-- sk->state = BT_LISTEN;
--
--done:
-- release_sock(sk);
-- return err;
--}
--
--int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int flags)
--{
-- DECLARE_WAITQUEUE(wait, current);
-- struct sock *sk = sock->sk, *ch;
-- long timeo;
-- int err = 0;
--
-- lock_sock(sk);
--
-- if (sk->state != BT_LISTEN) {
-- err = -EBADFD;
-- goto done;
-- }
--
-- timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
--
-- DBG("sk %p timeo %ld", sk, timeo);
--
-- /* Wait for an incoming connection. (wake-one). */
-- add_wait_queue_exclusive(sk->sleep, &wait);
-- current->state = TASK_INTERRUPTIBLE;
-- while (!(ch = l2cap_accept_dequeue(sk, BT_CONNECTED))) {
-- if (!timeo) {
-- err = -EAGAIN;
-- break;
-- }
--
-- release_sock(sk);
-- timeo = schedule_timeout(timeo);
-- lock_sock(sk);
--
-- if (sk->state != BT_LISTEN) {
-- err = -EBADFD;
-- break;
-- }
--
-- if (signal_pending(current)) {
-- err = sock_intr_errno(timeo);
-- break;
-- }
-- }
-- current->state = TASK_RUNNING;
-- remove_wait_queue(sk->sleep, &wait);
--
-- if (err)
-- goto done;
--
-- sock_graft(ch, newsock);
-- newsock->state = SS_CONNECTED;
--
-- DBG("new socket %p", ch);
--
--done:
-- release_sock(sk);
--
-- return err;
--}
--
--static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
--{
-- struct sockaddr_l2 *la = (struct sockaddr_l2 *) addr;
-- struct sock *sk = sock->sk;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- addr->sa_family = AF_BLUETOOTH;
-- *len = sizeof(struct sockaddr_l2);
--
-- if (peer)
-- bacpy(&la->l2_bdaddr, &l2cap_pi(sk)->dst);
-- else
-- bacpy(&la->l2_bdaddr, &l2cap_pi(sk)->src);
--
-- la->l2_psm = l2cap_pi(sk)->psm;
--
-- return 0;
--}
--
--static int l2cap_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
--{
-- struct sock *sk = sock->sk;
-- int err = 0;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- if (sk->err)
-- return sock_error(sk);
--
-- if (msg->msg_flags & MSG_OOB)
-- return -EOPNOTSUPP;
--
-- lock_sock(sk);
--
-- if (sk->state == BT_CONNECTED)
-- err = l2cap_chan_send(sk, msg, len);
-- else
-- err = -ENOTCONN;
--
-- release_sock(sk);
-- return err;
--}
--
--static int l2cap_sock_recvmsg(struct socket *sock, struct msghdr *msg, int len, int flags, struct scm_cookie *scm)
--{
-- struct sock *sk = sock->sk;
-- int noblock = flags & MSG_DONTWAIT;
-- int copied, err;
-- struct sk_buff *skb;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- if (flags & (MSG_OOB))
-- return -EOPNOTSUPP;
--
-- if (sk->state == BT_CLOSED)
-- return 0;
--
-- if (!(skb = skb_recv_datagram(sk, flags, noblock, &err)))
-- return err;
--
-- msg->msg_namelen = 0;
--
-- copied = skb->len;
-- if (len < copied) {
-- msg->msg_flags |= MSG_TRUNC;
-- copied = len;
-- }
--
-- skb->h.raw = skb->data;
-- err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
--
-- skb_free_datagram(sk, skb);
--
-- return err ? : copied;
--}
--
--int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
--{
-- struct sock *sk = sock->sk;
-- struct l2cap_options opts;
-- int err = 0;
--
-- DBG("sk %p", sk);
--
-- lock_sock(sk);
--
-- switch (optname) {
-- case L2CAP_OPTIONS:
-- if (copy_from_user((char *)&opts, optval, optlen)) {
-- err = -EFAULT;
-- break;
-- }
-- l2cap_pi(sk)->imtu = opts.imtu;
-- l2cap_pi(sk)->omtu = opts.omtu;
-- break;
--
-- default:
-- err = -ENOPROTOOPT;
-- break;
-- };
--
-- release_sock(sk);
-- return err;
--}
--
--int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
--{
-- struct sock *sk = sock->sk;
-- struct l2cap_options opts;
-- struct l2cap_conninfo cinfo;
-- int len, err = 0;
--
-- if (get_user(len, optlen))
-- return -EFAULT;
--
-- lock_sock(sk);
--
-- switch (optname) {
-- case L2CAP_OPTIONS:
-- opts.imtu = l2cap_pi(sk)->imtu;
-- opts.omtu = l2cap_pi(sk)->omtu;
-- opts.flush_to = l2cap_pi(sk)->flush_to;
--
-- len = MIN(len, sizeof(opts));
-- if (copy_to_user(optval, (char *)&opts, len))
-- err = -EFAULT;
--
-- break;
--
-- case L2CAP_CONNINFO:
-- if (sk->state != BT_CONNECTED) {
-- err = -ENOTCONN;
-- break;
-- }
--
-- cinfo.hci_handle = l2cap_pi(sk)->conn->hconn->handle;
--
-- len = MIN(len, sizeof(cinfo));
-- if (copy_to_user(optval, (char *)&cinfo, len))
-- err = -EFAULT;
--
-- break;
--
-- default:
-- err = -ENOPROTOOPT;
-- break;
-- };
--
-- release_sock(sk);
-- return err;
--}
--
--static unsigned int l2cap_sock_poll(struct file * file, struct socket *sock, poll_table *wait)
--{
-- struct sock *sk = sock->sk;
-- struct l2cap_accept_q *aq;
-- unsigned int mask;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- poll_wait(file, sk->sleep, wait);
-- mask = 0;
--
-- if (sk->err || !skb_queue_empty(&sk->error_queue))
-- mask |= POLLERR;
--
-- if (sk->shutdown == SHUTDOWN_MASK)
-- mask |= POLLHUP;
--
-- aq = &l2cap_pi(sk)->accept_q;
-- if (!skb_queue_empty(&sk->receive_queue) || aq->head || (sk->shutdown & RCV_SHUTDOWN))
-- mask |= POLLIN | POLLRDNORM;
--
-- if (sk->state == BT_CLOSED)
-- mask |= POLLHUP;
--
-- if (sock_writeable(sk))
-- mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
-- else
-- set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
--
-- return mask;
--}
--
--static int l2cap_sock_release(struct socket *sock)
--{
-- struct sock *sk = sock->sk;
--
-- DBG("sock %p, sk %p", sock, sk);
--
-- if (!sk)
-- return 0;
--
-- sock_orphan(sk);
--
-- l2cap_sock_close(sk);
--
-- return 0;
--}
--
--/* --------- L2CAP channels --------- */
--static struct sock * __l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
--{
-- struct sock *s;
--
-- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-- if (l2cap_pi(s)->dcid == cid)
-- break;
-- }
--
-- return s;
--}
--
--static inline struct sock *l2cap_get_chan_by_dcid(struct l2cap_chan_list *l, __u16 cid)
--{
-- struct sock *s;
--
-- read_lock(&l->lock);
-- s = __l2cap_get_chan_by_dcid(l, cid);
-- read_unlock(&l->lock);
--
-- return s;
--}
--
--static struct sock *__l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
--{
-- struct sock *s;
--
-- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-- if (l2cap_pi(s)->scid == cid)
-- break;
-- }
--
-- return s;
--}
--static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, __u16 cid)
--{
-- struct sock *s;
--
-- read_lock(&l->lock);
-- s = __l2cap_get_chan_by_scid(l, cid);
-- read_unlock(&l->lock);
--
-- return s;
--}
--
--static struct sock *__l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
--{
-- struct sock *s;
--
-- for (s = l->head; s; s = l2cap_pi(s)->next_c) {
-- if (l2cap_pi(s)->ident == ident)
-- break;
-- }
--
-- return s;
--}
--
--static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, __u8 ident)
--{
-- struct sock *s;
--
-- read_lock(&l->lock);
-- s = __l2cap_get_chan_by_ident(l, ident);
-- read_unlock(&l->lock);
--
-- return s;
--}
--
--static __u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
--{
-- __u16 cid = 0x0040;
--
-- for (; cid < 0xffff; cid++) {
-- if(!__l2cap_get_chan_by_scid(l, cid))
-- return cid;
-- }
--
-- return 0;
--}
--
--static inline void __l2cap_chan_link(struct l2cap_chan_list *l, struct sock *sk)
--{
-- sock_hold(sk);
--
-- if (l->head)
-- l2cap_pi(l->head)->prev_c = sk;
--
-- l2cap_pi(sk)->next_c = l->head;
-- l2cap_pi(sk)->prev_c = NULL;
-- l->head = sk;
--}
--
--static inline void l2cap_chan_unlink(struct l2cap_chan_list *l, struct sock *sk)
--{
-- struct sock *next = l2cap_pi(sk)->next_c, *prev = l2cap_pi(sk)->prev_c;
--
-- write_lock(&l->lock);
-- if (sk == l->head)
-- l->head = next;
--
-- if (next)
-- l2cap_pi(next)->prev_c = prev;
-- if (prev)
-- l2cap_pi(prev)->next_c = next;
-- write_unlock(&l->lock);
--
-- __sock_put(sk);
--}
--
--static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
--{
-- struct l2cap_chan_list *l = &conn->chan_list;
--
-- DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
--
-- l2cap_conn_clear_timer(conn);
--
-- atomic_inc(&conn->refcnt);
-- l2cap_pi(sk)->conn = conn;
--
-- if (sk->type == SOCK_SEQPACKET) {
-- /* Alloc CID for normal socket */
-- l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
-- } else {
-- /* Raw socket can send only signalling messages */
-- l2cap_pi(sk)->scid = 0x0001;
-- l2cap_pi(sk)->dcid = 0x0001;
-- l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
-- }
--
-- __l2cap_chan_link(l, sk);
--
-- if (parent)
-- l2cap_accept_queue(parent, sk);
--}
--
--static inline void l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct sock *parent)
--{
-- struct l2cap_chan_list *l = &conn->chan_list;
--
-- write_lock(&l->lock);
-- __l2cap_chan_add(conn, sk, parent);
-- write_unlock(&l->lock);
--}
--
--/* Delete channel.
-- * Must be called on the locked socket. */
--static void l2cap_chan_del(struct sock *sk, int err)
--{
-- struct l2cap_conn *conn;
-- struct sock *parent;
--
-- conn = l2cap_pi(sk)->conn;
-- parent = l2cap_pi(sk)->parent;
--
-- DBG("sk %p, conn %p, err %d", sk, conn, err);
--
-- if (parent) {
-- /* Unlink from parent accept queue */
-- bh_lock_sock(parent);
-- l2cap_accept_unlink(sk);
-- bh_unlock_sock(parent);
-- }
--
-- if (conn) {
-- long timeout;
--
-- /* Unlink from channel list */
-- l2cap_chan_unlink(&conn->chan_list, sk);
-- l2cap_pi(sk)->conn = NULL;
--
-- if (conn->out)
-- timeout = L2CAP_DISCONN_TIMEOUT;
-- else
-- timeout = L2CAP_CONN_IDLE_TIMEOUT;
--
-- if (atomic_dec_and_test(&conn->refcnt) && conn->state == BT_CONNECTED) {
-- /* Schedule Baseband disconnect */
-- l2cap_conn_set_timer(conn, timeout);
-- }
-- }
--
-- sk->state = BT_CLOSED;
-- sk->err = err;
-- sk->state_change(sk);
--
-- sk->zapped = 1;
--}
--
--static void l2cap_conn_ready(struct l2cap_conn *conn)
--{
-- struct l2cap_chan_list *l = &conn->chan_list;
-- struct sock *sk;
--
-- DBG("conn %p", conn);
--
-- read_lock(&l->lock);
--
-- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-- bh_lock_sock(sk);
--
-- if (sk->type != SOCK_SEQPACKET) {
-- sk->state = BT_CONNECTED;
-- sk->state_change(sk);
-- l2cap_sock_clear_timer(sk);
-- } else if (sk->state == BT_CONNECT) {
-- l2cap_conn_req req;
-- req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- req.psm = l2cap_pi(sk)->psm;
-- l2cap_send_req(conn, L2CAP_CONN_REQ, L2CAP_CONN_REQ_SIZE, &req);
--
-- l2cap_sock_set_timer(sk, sk->sndtimeo);
-- }
--
-- bh_unlock_sock(sk);
-- }
--
-- read_unlock(&l->lock);
--}
--
--static void l2cap_chan_ready(struct sock *sk)
--{
-- struct sock *parent = l2cap_pi(sk)->parent;
--
-- DBG("sk %p, parent %p", sk, parent);
--
-- l2cap_pi(sk)->conf_state = 0;
-- l2cap_sock_clear_timer(sk);
--
-- if (!parent) {
-- /* Outgoing channel.
-- * Wake up socket sleeping on connect.
-- */
-- sk->state = BT_CONNECTED;
-- sk->state_change(sk);
-- } else {
-- /* Incomming channel.
-- * Wake up socket sleeping on accept.
-- */
-- parent->data_ready(parent, 1);
-- }
--}
--
--/* Copy frame to all raw sockets on that connection */
--void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
--{
-- struct l2cap_chan_list *l = &conn->chan_list;
-- struct sk_buff *nskb;
-- struct sock * sk;
--
-- DBG("conn %p", conn);
--
-- read_lock(&l->lock);
-- for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) {
-- if (sk->type != SOCK_RAW)
-- continue;
--
-- /* Don't send frame to the socket it came from */
-- if (skb->sk == sk)
-- continue;
--
-- if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
-- continue;
--
-- skb_queue_tail(&sk->receive_queue, nskb);
-- sk->data_ready(sk, nskb->len);
-- }
-- read_unlock(&l->lock);
--}
--
--static int l2cap_chan_send(struct sock *sk, struct msghdr *msg, int len)
--{
-- struct l2cap_conn *conn = l2cap_pi(sk)->conn;
-- struct sk_buff *skb, **frag;
-- int err, size, count, sent=0;
-- l2cap_hdr *lh;
--
-- /* Check outgoing MTU */
-- if (len > l2cap_pi(sk)->omtu)
-- return -EINVAL;
--
-- DBG("sk %p len %d", sk, len);
--
-- /* First fragment (with L2CAP header) */
-- count = MIN(conn->iff->mtu - L2CAP_HDR_SIZE, len);
-- size = L2CAP_HDR_SIZE + count;
-- if (!(skb = bluez_skb_send_alloc(sk, size, msg->msg_flags & MSG_DONTWAIT, &err)))
-- return err;
--
-- /* Create L2CAP header */
-- lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-- lh->len = __cpu_to_le16(len);
-- lh->cid = __cpu_to_le16(l2cap_pi(sk)->dcid);
--
-- if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
-- err = -EFAULT;
-- goto fail;
-- }
--
-- sent += count;
-- len -= count;
--
-- /* Continuation fragments (no L2CAP header) */
-- frag = &skb_shinfo(skb)->frag_list;
-- while (len) {
-- count = MIN(conn->iff->mtu, len);
--
-- *frag = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err);
-- if (!*frag)
-- goto fail;
--
-- if (memcpy_fromiovec(skb_put(*frag, count), msg->msg_iov, count)) {
-- err = -EFAULT;
-- goto fail;
-- }
--
-- sent += count;
-- len -= count;
--
-- frag = &(*frag)->next;
-- }
--
-- if ((err = hci_send_acl(conn->hconn, skb, 0)) < 0)
-- goto fail;
--
-- return sent;
--
--fail:
-- kfree_skb(skb);
-- return err;
--}
--
--/* --------- L2CAP signalling commands --------- */
--static inline __u8 l2cap_get_ident(struct l2cap_conn *conn)
--{
-- __u8 id;
--
-- /* Get next available identificator.
-- * 1 - 199 are used by kernel.
-- * 200 - 254 are used by utilities like l2ping, etc
-- */
--
-- spin_lock(&conn->lock);
--
-- if (++conn->tx_ident > 199)
-- conn->tx_ident = 1;
--
-- id = conn->tx_ident;
--
-- spin_unlock(&conn->lock);
--
-- return id;
--}
--
--static inline struct sk_buff *l2cap_build_cmd(__u8 code, __u8 ident, __u16 len, void *data)
--{
-- struct sk_buff *skb;
-- l2cap_cmd_hdr *cmd;
-- l2cap_hdr *lh;
-- int size;
--
-- DBG("code 0x%2.2x, ident 0x%2.2x, len %d", code, ident, len);
--
-- size = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + len;
-- if (!(skb = bluez_skb_alloc(size, GFP_ATOMIC)))
-- return NULL;
--
-- lh = (l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
-- lh->len = __cpu_to_le16(L2CAP_CMD_HDR_SIZE + len);
-- lh->cid = __cpu_to_le16(0x0001);
--
-- cmd = (l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
-- cmd->code = code;
-- cmd->ident = ident;
-- cmd->len = __cpu_to_le16(len);
--
-- if (len)
-- memcpy(skb_put(skb, len), data, len);
--
-- return skb;
--}
--
--static int l2cap_send_req(struct l2cap_conn *conn, __u8 code, __u16 len, void *data)
--{
-- struct sk_buff *skb;
-- __u8 ident;
--
-- DBG("code 0x%2.2x", code);
--
-- ident = l2cap_get_ident(conn);
-- if (!(skb = l2cap_build_cmd(code, ident, len, data)))
-- return -ENOMEM;
-- return hci_send_acl(conn->hconn, skb, 0);
--}
--
--static int l2cap_send_rsp(struct l2cap_conn *conn, __u8 ident, __u8 code, __u16 len, void *data)
--{
-- struct sk_buff *skb;
--
-- DBG("code 0x%2.2x", code);
--
-- if (!(skb = l2cap_build_cmd(code, ident, len, data)))
-- return -ENOMEM;
-- return hci_send_acl(conn->hconn, skb, 0);
--}
--
--static inline int l2cap_get_conf_opt(__u8 **ptr, __u8 *type, __u32 *val)
--{
-- l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
-- int len;
--
-- *type = opt->type;
-- switch (opt->len) {
-- case 1:
-- *val = *((__u8 *) opt->val);
-- break;
--
-- case 2:
-- *val = __le16_to_cpu(*((__u16 *)opt->val));
-- break;
--
-- case 4:
-- *val = __le32_to_cpu(*((__u32 *)opt->val));
-- break;
--
-- default:
-- *val = 0L;
-- break;
-- };
--
-- DBG("type 0x%2.2x len %d val 0x%8.8x", *type, opt->len, *val);
--
-- len = L2CAP_CONF_OPT_SIZE + opt->len;
--
-- *ptr += len;
--
-- return len;
--}
--
--static inline void l2cap_parse_conf_req(struct sock *sk, char *data, int len)
--{
-- __u8 type, hint; __u32 val;
-- __u8 *ptr = data;
--
-- DBG("sk %p len %d", sk, len);
--
-- while (len >= L2CAP_CONF_OPT_SIZE) {
-- len -= l2cap_get_conf_opt(&ptr, &type, &val);
--
-- hint = type & 0x80;
-- type &= 0x7f;
--
-- switch (type) {
-- case L2CAP_CONF_MTU:
-- l2cap_pi(sk)->conf_mtu = val;
-- break;
--
-- case L2CAP_CONF_FLUSH_TO:
-- l2cap_pi(sk)->flush_to = val;
-- break;
--
-- case L2CAP_CONF_QOS:
-- break;
--
-- default:
-- if (hint)
-- break;
--
-- /* FIXME: Reject unknon option */
-- break;
-- };
-- }
--}
--
--static inline void l2cap_add_conf_opt(__u8 **ptr, __u8 type, __u8 len, __u32 val)
--{
-- register l2cap_conf_opt *opt = (l2cap_conf_opt *) (*ptr);
--
-- DBG("type 0x%2.2x len %d val 0x%8.8x", type, len, val);
--
-- opt->type = type;
-- opt->len = len;
-- switch (len) {
-- case 1:
-- *((__u8 *) opt->val) = val;
-- break;
--
-- case 2:
-- *((__u16 *) opt->val) = __cpu_to_le16(val);
-- break;
--
-- case 4:
-- *((__u32 *) opt->val) = __cpu_to_le32(val);
-- break;
-- };
--
-- *ptr += L2CAP_CONF_OPT_SIZE + len;
--}
--
--static int l2cap_build_conf_req(struct sock *sk, __u8 *data)
--{
-- struct l2cap_pinfo *pi = l2cap_pi(sk);
-- l2cap_conf_req *req = (l2cap_conf_req *) data;
-- __u8 *ptr = req->data;
--
-- DBG("sk %p", sk);
--
-- if (pi->imtu != L2CAP_DEFAULT_MTU)
-- l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
--
-- /* FIXME. Need actual value of the flush timeout */
-- //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
-- // l2cap_add_conf_opt(&ptr, L2CAP_CONF_FLUSH_TO, 2, pi->flush_to);
--
-- req->dcid = __cpu_to_le16(pi->dcid);
-- req->flags = __cpu_to_le16(0);
--
-- return ptr - data;
--}
--
--static int l2cap_conf_output(struct sock *sk, __u8 **ptr)
--{
-- struct l2cap_pinfo *pi = l2cap_pi(sk);
-- int result = 0;
--
-- /* Configure output options and let other side know
-- * which ones we don't like.
-- */
-- if (pi->conf_mtu < pi->omtu) {
-- l2cap_add_conf_opt(ptr, L2CAP_CONF_MTU, 2, l2cap_pi(sk)->omtu);
-- result = L2CAP_CONF_UNACCEPT;
-- } else {
-- pi->omtu = pi->conf_mtu;
-- }
--
-- DBG("sk %p result %d", sk, result);
-- return result;
--}
--
--static int l2cap_build_conf_rsp(struct sock *sk, __u8 *data, int *result)
--{
-- l2cap_conf_rsp *rsp = (l2cap_conf_rsp *) data;
-- __u8 *ptr = rsp->data;
--
-- DBG("sk %p complete %d", sk, result ? 1 : 0);
--
-- if (result)
-- *result = l2cap_conf_output(sk, &ptr);
--
-- rsp->scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- rsp->result = __cpu_to_le16(result ? *result : 0);
-- rsp->flags = __cpu_to_le16(0);
--
-- return ptr - data;
--}
--
--static inline int l2cap_connect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- struct l2cap_chan_list *list = &conn->chan_list;
-- l2cap_conn_req *req = (l2cap_conn_req *) data;
-- l2cap_conn_rsp rsp;
-- struct sock *sk, *parent;
--
-- __u16 scid = __le16_to_cpu(req->scid);
-- __u16 psm = req->psm;
--
-- DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
--
-- /* Check if we have socket listening on psm */
-- if (!(parent = l2cap_get_sock_listen(&conn->src, psm)))
-- goto reject;
--
-- bh_lock_sock(parent);
-- write_lock(&list->lock);
--
-- /* Check if we already have channel with that dcid */
-- if (__l2cap_get_chan_by_dcid(list, scid))
-- goto unlock;
--
-- /* Check for backlog size */
-- if (parent->ack_backlog > parent->max_ack_backlog)
-- goto unlock;
--
-- if (!(sk = l2cap_sock_alloc(NULL, BTPROTO_L2CAP, GFP_ATOMIC)))
-- goto unlock;
--
-- l2cap_sock_init(sk, parent);
--
-- bacpy(&l2cap_pi(sk)->src, &conn->src);
-- bacpy(&l2cap_pi(sk)->dst, &conn->dst);
-- l2cap_pi(sk)->psm = psm;
-- l2cap_pi(sk)->dcid = scid;
--
-- __l2cap_chan_add(conn, sk, parent);
-- sk->state = BT_CONFIG;
--
-- write_unlock(&list->lock);
-- bh_unlock_sock(parent);
--
-- rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- rsp.result = __cpu_to_le16(0);
-- rsp.status = __cpu_to_le16(0);
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
--
-- return 0;
--
--unlock:
-- write_unlock(&list->lock);
-- bh_unlock_sock(parent);
--
--reject:
-- rsp.scid = __cpu_to_le16(scid);
-- rsp.dcid = __cpu_to_le16(0);
-- rsp.status = __cpu_to_le16(0);
-- rsp.result = __cpu_to_le16(L2CAP_CONN_NO_MEM);
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_CONN_RSP, L2CAP_CONN_RSP_SIZE, &rsp);
--
-- return 0;
--}
--
--static inline int l2cap_connect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_conn_rsp *rsp = (l2cap_conn_rsp *) data;
-- __u16 scid, dcid, result, status;
-- struct sock *sk;
--
-- scid = __le16_to_cpu(rsp->scid);
-- dcid = __le16_to_cpu(rsp->dcid);
-- result = __le16_to_cpu(rsp->result);
-- status = __le16_to_cpu(rsp->status);
--
-- DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-- return -ENOENT;
--
-- bh_lock_sock(sk);
--
-- if (!result) {
-- char req[64];
--
-- sk->state = BT_CONFIG;
-- l2cap_pi(sk)->dcid = dcid;
-- l2cap_pi(sk)->conf_state |= CONF_REQ_SENT;
--
-- l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-- } else {
-- l2cap_chan_del(sk, ECONNREFUSED);
-- }
--
-- bh_unlock_sock(sk);
-- return 0;
--}
--
--static inline int l2cap_config_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_conf_req * req = (l2cap_conf_req *) data;
-- __u16 dcid, flags;
-- __u8 rsp[64];
-- struct sock *sk;
-- int result;
--
-- dcid = __le16_to_cpu(req->dcid);
-- flags = __le16_to_cpu(req->flags);
--
-- DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-- return -ENOENT;
--
-- bh_lock_sock(sk);
--
-- l2cap_parse_conf_req(sk, req->data, cmd->len - L2CAP_CONF_REQ_SIZE);
--
-- if (flags & 0x01) {
-- /* Incomplete config. Send empty response. */
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, NULL), rsp);
-- goto unlock;
-- }
--
-- /* Complete config. */
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_CONF_RSP, l2cap_build_conf_rsp(sk, rsp, &result), rsp);
--
-- if (result)
-- goto unlock;
--
-- /* Output config done */
-- l2cap_pi(sk)->conf_state |= CONF_OUTPUT_DONE;
--
-- if (l2cap_pi(sk)->conf_state & CONF_INPUT_DONE) {
-- sk->state = BT_CONNECTED;
-- l2cap_chan_ready(sk);
-- } else if (!(l2cap_pi(sk)->conf_state & CONF_REQ_SENT)) {
-- char req[64];
-- l2cap_send_req(conn, L2CAP_CONF_REQ, l2cap_build_conf_req(sk, req), req);
-- }
--
--unlock:
-- bh_unlock_sock(sk);
--
-- return 0;
--}
--
--static inline int l2cap_config_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_conf_rsp *rsp = (l2cap_conf_rsp *)data;
-- __u16 scid, flags, result;
-- struct sock *sk;
-- int err = 0;
--
-- scid = __le16_to_cpu(rsp->scid);
-- flags = __le16_to_cpu(rsp->flags);
-- result = __le16_to_cpu(rsp->result);
--
-- DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-- return -ENOENT;
--
-- bh_lock_sock(sk);
--
-- if (result) {
-- l2cap_disconn_req req;
--
-- /* They didn't like our options. Well... we do not negotiate.
-- * Close channel.
-- */
-- sk->state = BT_DISCONN;
--
-- req.dcid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- req.scid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- l2cap_send_req(conn, L2CAP_DISCONN_REQ, L2CAP_DISCONN_REQ_SIZE, &req);
--
-- l2cap_sock_set_timer(sk, sk->sndtimeo);
-- goto done;
-- }
--
-- if (flags & 0x01)
-- goto done;
--
-- /* Input config done */
-- l2cap_pi(sk)->conf_state |= CONF_INPUT_DONE;
--
-- if (l2cap_pi(sk)->conf_state & CONF_OUTPUT_DONE) {
-- sk->state = BT_CONNECTED;
-- l2cap_chan_ready(sk);
-- }
--
--done:
-- bh_unlock_sock(sk);
--
-- return err;
--}
--
--static inline int l2cap_disconnect_req(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_disconn_req *req = (l2cap_disconn_req *) data;
-- l2cap_disconn_rsp rsp;
-- __u16 dcid, scid;
-- struct sock *sk;
--
-- scid = __le16_to_cpu(req->scid);
-- dcid = __le16_to_cpu(req->dcid);
--
-- DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
-- return 0;
--
-- bh_lock_sock(sk);
--
-- rsp.dcid = __cpu_to_le16(l2cap_pi(sk)->scid);
-- rsp.scid = __cpu_to_le16(l2cap_pi(sk)->dcid);
-- l2cap_send_rsp(conn, cmd->ident, L2CAP_DISCONN_RSP, L2CAP_DISCONN_RSP_SIZE, &rsp);
--
-- l2cap_chan_del(sk, ECONNRESET);
--
-- bh_unlock_sock(sk);
--
-- l2cap_sock_kill(sk);
--
-- return 0;
--}
--
--static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, l2cap_cmd_hdr *cmd, __u8 *data)
--{
-- l2cap_disconn_rsp *rsp = (l2cap_disconn_rsp *) data;
-- __u16 dcid, scid;
-- struct sock *sk;
--
-- scid = __le16_to_cpu(rsp->scid);
-- dcid = __le16_to_cpu(rsp->dcid);
--
-- DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
-- return -ENOENT;
--
-- bh_lock_sock(sk);
-- l2cap_sock_clear_timer(sk);
-- l2cap_chan_del(sk, ECONNABORTED);
-- bh_unlock_sock(sk);
--
-- l2cap_sock_kill(sk);
--
-- return 0;
--}
--
--static inline void l2cap_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
--{
-- __u8 *data = skb->data;
-- int len = skb->len;
-- l2cap_cmd_hdr cmd;
-- int err = 0;
--
-- while (len >= L2CAP_CMD_HDR_SIZE) {
-- memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
-- data += L2CAP_CMD_HDR_SIZE;
-- len -= L2CAP_CMD_HDR_SIZE;
--
-- cmd.len = __le16_to_cpu(cmd.len);
--
-- DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
--
-- if (cmd.len > len || !cmd.ident) {
-- DBG("corrupted command");
-- break;
-- }
--
-- switch (cmd.code) {
-- case L2CAP_CONN_REQ:
-- err = l2cap_connect_req(conn, &cmd, data);
-- break;
--
-- case L2CAP_CONN_RSP:
-- err = l2cap_connect_rsp(conn, &cmd, data);
-- break;
--
-- case L2CAP_CONF_REQ:
-- err = l2cap_config_req(conn, &cmd, data);
-- break;
--
-- case L2CAP_CONF_RSP:
-- err = l2cap_config_rsp(conn, &cmd, data);
-- break;
--
-- case L2CAP_DISCONN_REQ:
-- err = l2cap_disconnect_req(conn, &cmd, data);
-- break;
--
-- case L2CAP_DISCONN_RSP:
-- err = l2cap_disconnect_rsp(conn, &cmd, data);
-- break;
--
-- case L2CAP_COMMAND_REJ:
-- /* FIXME: We should process this */
-- l2cap_raw_recv(conn, skb);
-- break;
--
-- case L2CAP_ECHO_REQ:
-- l2cap_send_rsp(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data);
-- break;
--
-- case L2CAP_ECHO_RSP:
-- case L2CAP_INFO_REQ:
-- case L2CAP_INFO_RSP:
-- l2cap_raw_recv(conn, skb);
-- break;
--
-- default:
-- ERR("Uknown signaling command 0x%2.2x", cmd.code);
-- err = -EINVAL;
-- break;
-- };
--
-- if (err) {
-- l2cap_cmd_rej rej;
-- DBG("error %d", err);
--
-- /* FIXME: Map err to a valid reason. */
-- rej.reason = __cpu_to_le16(0);
-- l2cap_send_rsp(conn, cmd.ident, L2CAP_COMMAND_REJ, L2CAP_CMD_REJ_SIZE, &rej);
-- }
--
-- data += cmd.len;
-- len -= cmd.len;
-- }
--
-- kfree_skb(skb);
--}
--
--static inline int l2cap_data_channel(struct l2cap_conn *conn, __u16 cid, struct sk_buff *skb)
--{
-- struct sock *sk;
--
-- if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, cid))) {
-- DBG("unknown cid 0x%4.4x", cid);
-- goto drop;
-- }
--
-- DBG("sk %p, len %d", sk, skb->len);
--
-- if (sk->state != BT_CONNECTED)
-- goto drop;
--
-- if (l2cap_pi(sk)->imtu < skb->len)
-- goto drop;
--
-- skb_queue_tail(&sk->receive_queue, skb);
-- sk->data_ready(sk, skb->len);
--
-- return 0;
--
--drop:
-- kfree_skb(skb);
--
-- return 0;
--}
--
--static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
--{
-- l2cap_hdr *lh = (l2cap_hdr *) skb->data;
-- __u16 cid, len;
--
-- skb_pull(skb, L2CAP_HDR_SIZE);
-- cid = __le16_to_cpu(lh->cid);
-- len = __le16_to_cpu(lh->len);
--
-- DBG("len %d, cid 0x%4.4x", len, cid);
--
-- if (cid == 0x0001)
-- l2cap_sig_channel(conn, skb);
-- else
-- l2cap_data_channel(conn, cid, skb);
--}
--
--/* ------------ L2CAP interface with lower layer (HCI) ------------- */
--static int l2cap_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
--{
-- struct hci_dev *hdev = (struct hci_dev *) ptr;
--
-- DBG("hdev %s, event %ld", hdev->name, event);
--
-- write_lock(&l2cap_rt_lock);
--
-- switch (event) {
-- case HCI_DEV_UP:
-- l2cap_iff_add(hdev);
-- break;
--
-- case HCI_DEV_DOWN:
-- l2cap_iff_del(hdev);
-- break;
-- };
--
-- write_unlock(&l2cap_rt_lock);
--
-- return NOTIFY_DONE;
--}
--
--int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
--{
-- struct l2cap_iff *iff;
--
-- DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
--
-- if (!(iff = hdev->l2cap_data)) {
-- ERR("unknown interface");
-- return 0;
-- }
--
-- /* Always accept connection */
-- return 1;
--}
--
--int l2cap_connect_cfm(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 status, struct hci_conn *hconn)
--{
-- struct l2cap_conn *conn;
-- struct l2cap_iff *iff;
-- int err = 0;
--
-- DBG("hdev %s bdaddr %s hconn %p", hdev->name, batostr(bdaddr), hconn);
--
-- if (!(iff = hdev->l2cap_data)) {
-- ERR("unknown interface");
-- return 0;
-- }
--
-- l2cap_iff_lock(iff);
--
-- conn = l2cap_get_conn_by_addr(iff, bdaddr);
--
-- if (conn) {
-- /* Outgoing connection */
-- DBG("Outgoing connection: %s -> %s, %p, %2.2x", batostr(iff->bdaddr), batostr(bdaddr), conn, status);
--
-- if (!status && hconn) {
-- conn->state = BT_CONNECTED;
-- conn->hconn = hconn;
--
-- hconn->l2cap_data = (void *)conn;
--
-- /* Establish channels */
-- l2cap_conn_ready(conn);
-- } else {
-- l2cap_conn_del(conn, bterr(status));
-- }
-- } else {
-- /* Incomming connection */
-- DBG("Incomming connection: %s -> %s, %2.2x", batostr(iff->bdaddr), batostr(bdaddr), status);
--
-- if (status || !hconn)
-- goto done;
--
-- if (!(conn = l2cap_conn_add(iff, bdaddr))) {
-- err = -ENOMEM;
-- goto done;
-- }
--
-- conn->hconn = hconn;
-- hconn->l2cap_data = (void *)conn;
--
-- conn->state = BT_CONNECTED;
-- }
--
--done:
-- l2cap_iff_unlock(iff);
--
-- return err;
--}
--
--int l2cap_disconn_ind(struct hci_conn *hconn, __u8 reason)
--{
-- struct l2cap_conn *conn = hconn->l2cap_data;
--
-- DBG("hconn %p reason %d", hconn, reason);
--
-- if (!conn) {
-- ERR("unknown connection");
-- return 0;
-- }
-- conn->hconn = NULL;
--
-- l2cap_iff_lock(conn->iff);
-- l2cap_conn_del(conn, bterr(reason));
-- l2cap_iff_unlock(conn->iff);
--
-- return 0;
--}
--
--int l2cap_recv_acldata(struct hci_conn *hconn, struct sk_buff *skb, __u16 flags)
--{
-- struct l2cap_conn *conn = hconn->l2cap_data;
--
-- if (!conn) {
-- ERR("unknown connection %p", hconn);
-- goto drop;
-- }
--
-- DBG("conn %p len %d flags 0x%x", conn, skb->len, flags);
--
-- if (flags & ACL_START) {
-- int flen, tlen, size;
-- l2cap_hdr *lh;
--
-- if (conn->rx_len) {
-- ERR("Unexpected start frame (len %d)", skb->len);
-- kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
-- conn->rx_len = 0;
-- }
--
-- if (skb->len < L2CAP_HDR_SIZE) {
-- ERR("Frame is too small (len %d)", skb->len);
-- goto drop;
-- }
--
-- lh = (l2cap_hdr *)skb->data;
-- tlen = __le16_to_cpu(lh->len);
-- flen = skb->len - L2CAP_HDR_SIZE;
--
-- DBG("Start: total len %d, frag len %d", tlen, flen);
--
-- if (flen == tlen) {
-- /* Complete frame received */
-- l2cap_recv_frame(conn, skb);
-- return 0;
-- }
--
-- /* Allocate skb for the complete frame (with header) */
-- size = L2CAP_HDR_SIZE + tlen;
-- if (!(conn->rx_skb = bluez_skb_alloc(size, GFP_ATOMIC)))
-- goto drop;
--
-- memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
--
-- conn->rx_len = tlen - flen;
-- } else {
-- DBG("Cont: frag len %d (expecting %d)", skb->len, conn->rx_len);
--
-- if (!conn->rx_len) {
-- ERR("Unexpected continuation frame (len %d)", skb->len);
-- goto drop;
-- }
--
-- if (skb->len > conn->rx_len) {
-- ERR("Fragment is too large (len %d)", skb->len);
-- kfree_skb(conn->rx_skb); conn->rx_skb = NULL;
-- goto drop;
-- }
--
-- memcpy(skb_put(conn->rx_skb, skb->len), skb->data, skb->len);
-- conn->rx_len -= skb->len;
--
-- if (!conn->rx_len) {
-- /* Complete frame received */
-- l2cap_recv_frame(conn, conn->rx_skb);
-- conn->rx_skb = NULL;
-- }
-- }
--
--drop:
-- kfree_skb(skb);
-- return 0;
--}
--
--struct proto_ops l2cap_sock_ops = {
-- family: PF_BLUETOOTH,
-- release: l2cap_sock_release,
-- bind: l2cap_sock_bind,
-- connect: l2cap_sock_connect,
-- listen: l2cap_sock_listen,
-- accept: l2cap_sock_accept,
-- getname: l2cap_sock_getname,
-- sendmsg: l2cap_sock_sendmsg,
-- recvmsg: l2cap_sock_recvmsg,
-- poll: l2cap_sock_poll,
-- socketpair: sock_no_socketpair,
-- ioctl: sock_no_ioctl,
-- shutdown: sock_no_shutdown,
-- setsockopt: l2cap_sock_setsockopt,
-- getsockopt: l2cap_sock_getsockopt,
-- mmap: sock_no_mmap
--};
--
--struct net_proto_family l2cap_sock_family_ops = {
-- family: PF_BLUETOOTH,
-- create: l2cap_sock_create
--};
--
--struct hci_proto l2cap_hci_proto = {
-- name: "L2CAP",
-- id: HCI_PROTO_L2CAP,
-- connect_ind: l2cap_connect_ind,
-- connect_cfm: l2cap_connect_cfm,
-- disconn_ind: l2cap_disconn_ind,
-- recv_acldata: l2cap_recv_acldata,
--};
--
--struct notifier_block l2cap_nblock = {
-- notifier_call: l2cap_dev_event
--};
--
--int __init l2cap_init(void)
--{
-- INF("BlueZ L2CAP ver %s Copyright (C) 2000,2001 Qualcomm Inc",
-- VERSION);
-- INF("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
--
-- if (bluez_sock_register(BTPROTO_L2CAP, &l2cap_sock_family_ops)) {
-- ERR("Can't register L2CAP socket");
-- return -EPROTO;
-- }
--
-- if (hci_register_proto(&l2cap_hci_proto) < 0) {
-- ERR("Can't register L2CAP protocol");
-- return -EPROTO;
-- }
--
-- hci_register_notifier(&l2cap_nblock);
--
-- l2cap_register_proc();
--
-- return 0;
--}
--
--void l2cap_cleanup(void)
--{
-- l2cap_unregister_proc();
--
-- /* Unregister socket, protocol and notifier */
-- if (bluez_sock_unregister(BTPROTO_L2CAP))
-- ERR("Can't unregister L2CAP socket");
--
-- if (hci_unregister_proto(&l2cap_hci_proto) < 0)
-- ERR("Can't unregister L2CAP protocol");
--
-- hci_unregister_notifier(&l2cap_nblock);
--
-- /* We _must_ not have any sockets and/or connections
-- * at this stage.
-- */
--
-- /* Free interface list and unlock HCI devices */
-- {
-- struct list_head *list = &l2cap_iff_list;
--
-- while (!list_empty(list)) {
-- struct l2cap_iff *iff;
--
-- iff = list_entry(list->next, struct l2cap_iff, list);
-- l2cap_iff_del(iff->hdev);
-- }
-- }
--}
--
--module_init(l2cap_init);
--module_exit(l2cap_cleanup);
--
--MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
--MODULE_DESCRIPTION("BlueZ L2CAP ver " VERSION);
--MODULE_LICENSE("GPL");
--
-diff -urN linux-2.4.18/net/bluetooth/l2cap_proc.c linux-2.4.18-mh9/net/bluetooth/l2cap_proc.c
---- linux-2.4.18/net/bluetooth/l2cap_proc.c Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/net/bluetooth/l2cap_proc.c Thu Jan 1 01:00:00 1970
-@@ -1,165 +0,0 @@
--/*
-- BlueZ - Bluetooth protocol stack for Linux
-- Copyright (C) 2000-2001 Qualcomm Incorporated
--
-- Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License version 2 as
-- published by the Free Software Foundation;
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-- IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-- CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
--
-- ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-- COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-- SOFTWARE IS DISCLAIMED.
--*/
--
--/*
-- * BlueZ L2CAP proc fs support.
-- *
-- * $Id$
-- */
--
--#include <linux/config.h>
--#include <linux/module.h>
--
--#include <linux/types.h>
--#include <linux/errno.h>
--#include <linux/kernel.h>
--#include <linux/major.h>
--#include <linux/sched.h>
--#include <linux/slab.h>
--#include <linux/poll.h>
--#include <linux/fcntl.h>
--#include <linux/init.h>
--#include <linux/skbuff.h>
--#include <linux/interrupt.h>
--#include <linux/socket.h>
--#include <linux/skbuff.h>
--#include <linux/proc_fs.h>
--#include <linux/list.h>
--#include <net/sock.h>
--
--#include <asm/system.h>
--#include <asm/uaccess.h>
--
--#include <net/bluetooth/bluez.h>
--#include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/hci_core.h>
--#include <net/bluetooth/l2cap_core.h>
--
--#ifndef L2CAP_DEBUG
--#undef DBG
--#define DBG( A... )
--#endif
--
--/* ----- PROC fs support ----- */
--static int l2cap_conn_dump(char *buf, struct l2cap_iff *iff)
--{
-- struct list_head *p;
-- char *ptr = buf;
--
-- list_for_each(p, &iff->conn_list) {
-- struct l2cap_conn *c;
--
-- c = list_entry(p, struct l2cap_conn, list);
-- ptr += sprintf(ptr, " %p %d %p %p %s %s\n",
-- c, c->state, c->iff, c->hconn, batostr(&c->src), batostr(&c->dst));
-- }
--
-- return ptr - buf;
--}
--
--static int l2cap_iff_dump(char *buf)
--{
-- struct list_head *p;
-- char *ptr = buf;
--
-- ptr += sprintf(ptr, "Interfaces:\n");
--
-- write_lock(&l2cap_rt_lock);
--
-- list_for_each(p, &l2cap_iff_list) {
-- struct l2cap_iff *iff;
--
-- iff = list_entry(p, struct l2cap_iff, list);
--
-- ptr += sprintf(ptr, " %s %p %p\n", iff->hdev->name, iff, iff->hdev);
--
-- l2cap_iff_lock(iff);
-- ptr += l2cap_conn_dump(ptr, iff);
-- l2cap_iff_unlock(iff);
-- }
--
-- write_unlock(&l2cap_rt_lock);
--
-- ptr += sprintf(ptr, "\n");
--
-- return ptr - buf;
--}
--
--static int l2cap_sock_dump(char *buf, struct bluez_sock_list *list)
--{
-- struct l2cap_pinfo *pi;
-- struct sock *sk;
-- char *ptr = buf;
--
-- ptr += sprintf(ptr, "Sockets:\n");
--
-- write_lock(&list->lock);
--
-- for (sk = list->head; sk; sk = sk->next) {
-- pi = l2cap_pi(sk);
-- ptr += sprintf(ptr, " %p %d %p %d %s %s 0x%4.4x 0x%4.4x %d %d\n", sk, sk->state, pi->conn, pi->psm,
-- batostr(&pi->src), batostr(&pi->dst), pi->scid, pi->dcid, pi->imtu, pi->omtu );
-- }
--
-- write_unlock(&list->lock);
--
-- ptr += sprintf(ptr, "\n");
--
-- return ptr - buf;
--}
--
--static int l2cap_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
--{
-- char *ptr = buf;
-- int len;
--
-- DBG("count %d, offset %ld", count, offset);
--
-- ptr += l2cap_iff_dump(ptr);
-- ptr += l2cap_sock_dump(ptr, &l2cap_sk_list);
-- len = ptr - buf;
--
-- if (len <= count + offset)
-- *eof = 1;
--
-- *start = buf + offset;
-- len -= offset;
--
-- if (len > count)
-- len = count;
-- if (len < 0)
-- len = 0;
--
-- return len;
--}
--
--void l2cap_register_proc(void)
--{
-- create_proc_read_entry("bluetooth/l2cap", 0, 0, l2cap_read_proc, NULL);
--}
--
--void l2cap_unregister_proc(void)
--{
-- remove_proc_entry("bluetooth/l2cap", NULL);
--}
-diff -urN linux-2.4.18/net/bluetooth/lib.c linux-2.4.18-mh9/net/bluetooth/lib.c
---- linux-2.4.18/net/bluetooth/lib.c Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/net/bluetooth/lib.c Mon Aug 25 18:38:12 2003
-@@ -25,7 +25,7 @@
- /*
- * BlueZ kernel library.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/kernel.h>
-@@ -105,7 +105,7 @@
- return EACCES;
-
- case 0x06:
-- return EINVAL;
-+ return EBADE;
-
- case 0x07:
- return ENOMEM;
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/Config.in linux-2.4.18-mh9/net/bluetooth/rfcomm/Config.in
---- linux-2.4.18/net/bluetooth/rfcomm/Config.in Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/rfcomm/Config.in Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,10 @@
-+#
-+# Bluetooth RFCOMM layer configuration
-+#
-+
-+dep_tristate 'RFCOMM protocol support' CONFIG_BLUEZ_RFCOMM $CONFIG_BLUEZ_L2CAP
-+
-+if [ "$CONFIG_BLUEZ_RFCOMM" != "n" ]; then
-+ bool ' RFCOMM TTY support' CONFIG_BLUEZ_RFCOMM_TTY
-+fi
-+
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/Makefile linux-2.4.18-mh9/net/bluetooth/rfcomm/Makefile
---- linux-2.4.18/net/bluetooth/rfcomm/Makefile Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/rfcomm/Makefile Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,11 @@
-+#
-+# Makefile for the Linux Bluetooth RFCOMM layer
-+#
-+
-+O_TARGET := rfcomm.o
-+
-+obj-y := core.o sock.o crc.o
-+obj-$(CONFIG_BLUEZ_RFCOMM_TTY) += tty.o
-+obj-m += $(O_TARGET)
-+
-+include $(TOPDIR)/Rules.make
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/core.c linux-2.4.18-mh9/net/bluetooth/rfcomm/core.c
---- linux-2.4.18/net/bluetooth/rfcomm/core.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/rfcomm/core.c Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,1951 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ RPN support - Dirk Husemann <hud@zurich.ibm.com>
-+*/
-+
-+/*
-+ * RFCOMM core.
-+ *
-+ * $Id$
-+ */
-+
-+#define __KERNEL_SYSCALLS__
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/sched.h>
-+#include <linux/signal.h>
-+#include <linux/init.h>
-+#include <linux/wait.h>
-+#include <linux/net.h>
-+#include <linux/proc_fs.h>
-+#include <net/sock.h>
-+#include <asm/uaccess.h>
-+#include <asm/unaligned.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/l2cap.h>
-+#include <net/bluetooth/rfcomm.h>
-+
-+#define VERSION "1.0"
-+
-+#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+struct task_struct *rfcomm_thread;
-+DECLARE_MUTEX(rfcomm_sem);
-+unsigned long rfcomm_event;
-+
-+static LIST_HEAD(session_list);
-+static atomic_t terminate, running;
-+
-+static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len);
-+static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci);
-+static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci);
-+static int rfcomm_queue_disc(struct rfcomm_dlc *d);
-+static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type);
-+static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d);
-+static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig);
-+static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len);
-+static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits);
-+static void rfcomm_make_uih(struct sk_buff *skb, u8 addr);
-+
-+static void rfcomm_process_connect(struct rfcomm_session *s);
-+
-+/* ---- RFCOMM frame parsing macros ---- */
-+#define __get_dlci(b) ((b & 0xfc) >> 2)
-+#define __get_channel(b) ((b & 0xf8) >> 3)
-+#define __get_dir(b) ((b & 0x04) >> 2)
-+#define __get_type(b) ((b & 0xef))
-+
-+#define __test_ea(b) ((b & 0x01))
-+#define __test_cr(b) ((b & 0x02))
-+#define __test_pf(b) ((b & 0x10))
-+
-+#define __addr(cr, dlci) (((dlci & 0x3f) << 2) | (cr << 1) | 0x01)
-+#define __ctrl(type, pf) (((type & 0xef) | (pf << 4)))
-+#define __dlci(dir, chn) (((chn & 0x1f) << 1) | dir)
-+#define __srv_channel(dlci) (dlci >> 1)
-+#define __dir(dlci) (dlci & 0x01)
-+
-+#define __len8(len) (((len) << 1) | 1)
-+#define __len16(len) ((len) << 1)
-+
-+/* MCC macros */
-+#define __mcc_type(cr, type) (((type << 2) | (cr << 1) | 0x01))
-+#define __get_mcc_type(b) ((b & 0xfc) >> 2)
-+#define __get_mcc_len(b) ((b & 0xfe) >> 1)
-+
-+/* RPN macros */
-+#define __rpn_line_settings(data, stop, parity) ((data & 0x3) | ((stop & 0x1) << 2) | ((parity & 0x3) << 3))
-+#define __get_rpn_data_bits(line) ((line) & 0x3)
-+#define __get_rpn_stop_bits(line) (((line) >> 2) & 0x1)
-+#define __get_rpn_parity(line) (((line) >> 3) & 0x3)
-+
-+/* ---- RFCOMM FCS computation ---- */
-+
-+/* CRC on 2 bytes */
-+#define __crc(data) (rfcomm_crc_table[rfcomm_crc_table[0xff ^ data[0]] ^ data[1]])
-+
-+/* FCS on 2 bytes */
-+static inline u8 __fcs(u8 *data)
-+{
-+ return (0xff - __crc(data));
-+}
-+
-+/* FCS on 3 bytes */
-+static inline u8 __fcs2(u8 *data)
-+{
-+ return (0xff - rfcomm_crc_table[__crc(data) ^ data[2]]);
-+}
-+
-+/* Check FCS */
-+static inline int __check_fcs(u8 *data, int type, u8 fcs)
-+{
-+ u8 f = __crc(data);
-+
-+ if (type != RFCOMM_UIH)
-+ f = rfcomm_crc_table[f ^ data[2]];
-+
-+ return rfcomm_crc_table[f ^ fcs] != 0xcf;
-+}
-+
-+/* ---- L2CAP callbacks ---- */
-+static void rfcomm_l2state_change(struct sock *sk)
-+{
-+ BT_DBG("%p state %d", sk, sk->state);
-+ rfcomm_schedule(RFCOMM_SCHED_STATE);
-+}
-+
-+static void rfcomm_l2data_ready(struct sock *sk, int bytes)
-+{
-+ BT_DBG("%p bytes %d", sk, bytes);
-+ rfcomm_schedule(RFCOMM_SCHED_RX);
-+}
-+
-+static int rfcomm_l2sock_create(struct socket **sock)
-+{
-+ int err;
-+
-+ BT_DBG("");
-+
-+ err = sock_create(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP, sock);
-+ if (!err) {
-+ struct sock *sk = (*sock)->sk;
-+ sk->data_ready = rfcomm_l2data_ready;
-+ sk->state_change = rfcomm_l2state_change;
-+ }
-+ return err;
-+}
-+
-+/* ---- RFCOMM DLCs ---- */
-+static void rfcomm_dlc_timeout(unsigned long arg)
-+{
-+ struct rfcomm_dlc *d = (void *) arg;
-+
-+ BT_DBG("dlc %p state %ld", d, d->state);
-+
-+ set_bit(RFCOMM_TIMED_OUT, &d->flags);
-+ rfcomm_dlc_put(d);
-+ rfcomm_schedule(RFCOMM_SCHED_TIMEO);
-+}
-+
-+static void rfcomm_dlc_set_timer(struct rfcomm_dlc *d, long timeout)
-+{
-+ BT_DBG("dlc %p state %ld timeout %ld", d, d->state, timeout);
-+
-+ if (!mod_timer(&d->timer, jiffies + timeout))
-+ rfcomm_dlc_hold(d);
-+}
-+
-+static void rfcomm_dlc_clear_timer(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("dlc %p state %ld", d, d->state);
-+
-+ if (timer_pending(&d->timer) && del_timer(&d->timer))
-+ rfcomm_dlc_put(d);
-+}
-+
-+static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("%p", d);
-+
-+ d->state = BT_OPEN;
-+ d->flags = 0;
-+ d->mscex = 0;
-+ d->mtu = RFCOMM_DEFAULT_MTU;
-+ d->v24_sig = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV;
-+
-+ d->credits = 0;
-+ d->rx_credits = RFCOMM_DEFAULT_CREDITS;
-+}
-+
-+struct rfcomm_dlc *rfcomm_dlc_alloc(int prio)
-+{
-+ struct rfcomm_dlc *d = kmalloc(sizeof(*d), prio);
-+ if (!d)
-+ return NULL;
-+ memset(d, 0, sizeof(*d));
-+
-+ init_timer(&d->timer);
-+ d->timer.function = rfcomm_dlc_timeout;
-+ d->timer.data = (unsigned long) d;
-+
-+ skb_queue_head_init(&d->tx_queue);
-+ spin_lock_init(&d->lock);
-+ atomic_set(&d->refcnt, 1);
-+
-+ rfcomm_dlc_clear_state(d);
-+
-+ BT_DBG("%p", d);
-+ return d;
-+}
-+
-+void rfcomm_dlc_free(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("%p", d);
-+
-+ skb_queue_purge(&d->tx_queue);
-+ kfree(d);
-+}
-+
-+static void rfcomm_dlc_link(struct rfcomm_session *s, struct rfcomm_dlc *d)
-+{
-+ BT_DBG("dlc %p session %p", d, s);
-+
-+ rfcomm_session_hold(s);
-+
-+ rfcomm_dlc_hold(d);
-+ list_add(&d->list, &s->dlcs);
-+ d->session = s;
-+}
-+
-+static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
-+{
-+ struct rfcomm_session *s = d->session;
-+
-+ BT_DBG("dlc %p refcnt %d session %p", d, atomic_read(&d->refcnt), s);
-+
-+ list_del(&d->list);
-+ d->session = NULL;
-+ rfcomm_dlc_put(d);
-+
-+ rfcomm_session_put(s);
-+}
-+
-+static struct rfcomm_dlc *rfcomm_dlc_get(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_dlc *d;
-+ struct list_head *p;
-+
-+ list_for_each(p, &s->dlcs) {
-+ d = list_entry(p, struct rfcomm_dlc, list);
-+ if (d->dlci == dlci)
-+ return d;
-+ }
-+ return NULL;
-+}
-+
-+static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
-+{
-+ struct rfcomm_session *s;
-+ int err = 0;
-+ u8 dlci;
-+
-+ BT_DBG("dlc %p state %ld %s %s channel %d",
-+ d, d->state, batostr(src), batostr(dst), channel);
-+
-+ if (channel < 1 || channel > 30)
-+ return -EINVAL;
-+
-+ if (d->state != BT_OPEN && d->state != BT_CLOSED)
-+ return 0;
-+
-+ s = rfcomm_session_get(src, dst);
-+ if (!s) {
-+ s = rfcomm_session_create(src, dst, &err);
-+ if (!s)
-+ return err;
-+ }
-+
-+ dlci = __dlci(!s->initiator, channel);
-+
-+ /* Check if DLCI already exists */
-+ if (rfcomm_dlc_get(s, dlci))
-+ return -EBUSY;
-+
-+ rfcomm_dlc_clear_state(d);
-+
-+ d->dlci = dlci;
-+ d->addr = __addr(s->initiator, dlci);
-+ d->priority = 7;
-+
-+ d->state = BT_CONFIG;
-+ rfcomm_dlc_link(s, d);
-+
-+ d->mtu = s->mtu;
-+ d->credits = s->credits;
-+
-+ if (s->state == BT_CONNECTED)
-+ rfcomm_send_pn(s, 1, d);
-+ rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT);
-+ return 0;
-+}
-+
-+int rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, u8 channel)
-+{
-+ mm_segment_t fs;
-+ int r;
-+
-+ rfcomm_lock();
-+
-+ fs = get_fs(); set_fs(KERNEL_DS);
-+ r = __rfcomm_dlc_open(d, src, dst, channel);
-+ set_fs(fs);
-+
-+ rfcomm_unlock();
-+ return r;
-+}
-+
-+static int __rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
-+{
-+ struct rfcomm_session *s = d->session;
-+ if (!s)
-+ return 0;
-+
-+ BT_DBG("dlc %p state %ld dlci %d err %d session %p",
-+ d, d->state, d->dlci, err, s);
-+
-+ switch (d->state) {
-+ case BT_CONNECTED:
-+ case BT_CONFIG:
-+ case BT_CONNECT:
-+ d->state = BT_DISCONN;
-+ if (skb_queue_empty(&d->tx_queue)) {
-+ rfcomm_send_disc(s, d->dlci);
-+ rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT);
-+ } else {
-+ rfcomm_queue_disc(d);
-+ rfcomm_dlc_set_timer(d, RFCOMM_DISC_TIMEOUT * 2);
-+ }
-+ break;
-+
-+ default:
-+ rfcomm_dlc_clear_timer(d);
-+
-+ rfcomm_dlc_lock(d);
-+ d->state = BT_CLOSED;
-+ d->state_change(d, err);
-+ rfcomm_dlc_unlock(d);
-+
-+ skb_queue_purge(&d->tx_queue);
-+ rfcomm_dlc_unlink(d);
-+ }
-+
-+ return 0;
-+}
-+
-+int rfcomm_dlc_close(struct rfcomm_dlc *d, int err)
-+{
-+ mm_segment_t fs;
-+ int r;
-+
-+ rfcomm_lock();
-+
-+ fs = get_fs(); set_fs(KERNEL_DS);
-+ r = __rfcomm_dlc_close(d, err);
-+ set_fs(fs);
-+
-+ rfcomm_unlock();
-+ return r;
-+}
-+
-+int rfcomm_dlc_send(struct rfcomm_dlc *d, struct sk_buff *skb)
-+{
-+ int len = skb->len;
-+
-+ if (d->state != BT_CONNECTED)
-+ return -ENOTCONN;
-+
-+ BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len);
-+
-+ if (len > d->mtu)
-+ return -EINVAL;
-+
-+ rfcomm_make_uih(skb, d->addr);
-+ skb_queue_tail(&d->tx_queue, skb);
-+
-+ if (!test_bit(RFCOMM_TX_THROTTLED, &d->flags))
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+ return len;
-+}
-+
-+void __rfcomm_dlc_throttle(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("dlc %p state %ld", d, d->state);
-+
-+ if (!d->credits) {
-+ d->v24_sig |= RFCOMM_V24_FC;
-+ set_bit(RFCOMM_MSC_PENDING, &d->flags);
-+ }
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+}
-+
-+void __rfcomm_dlc_unthrottle(struct rfcomm_dlc *d)
-+{
-+ BT_DBG("dlc %p state %ld", d, d->state);
-+
-+ if (!d->credits) {
-+ d->v24_sig &= ~RFCOMM_V24_FC;
-+ set_bit(RFCOMM_MSC_PENDING, &d->flags);
-+ }
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+}
-+
-+/*
-+ Set/get modem status functions use _local_ status i.e. what we report
-+ to the other side.
-+ Remote status is provided by dlc->modem_status() callback.
-+ */
-+int rfcomm_dlc_set_modem_status(struct rfcomm_dlc *d, u8 v24_sig)
-+{
-+ BT_DBG("dlc %p state %ld v24_sig 0x%x",
-+ d, d->state, v24_sig);
-+
-+ if (test_bit(RFCOMM_RX_THROTTLED, &d->flags))
-+ v24_sig |= RFCOMM_V24_FC;
-+ else
-+ v24_sig &= ~RFCOMM_V24_FC;
-+
-+ d->v24_sig = v24_sig;
-+
-+ if (!test_and_set_bit(RFCOMM_MSC_PENDING, &d->flags))
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+
-+ return 0;
-+}
-+
-+int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig)
-+{
-+ BT_DBG("dlc %p state %ld v24_sig 0x%x",
-+ d, d->state, d->v24_sig);
-+
-+ *v24_sig = d->v24_sig;
-+ return 0;
-+}
-+
-+/* ---- RFCOMM sessions ---- */
-+struct rfcomm_session *rfcomm_session_add(struct socket *sock, int state)
-+{
-+ struct rfcomm_session *s = kmalloc(sizeof(*s), GFP_KERNEL);
-+ if (!s)
-+ return NULL;
-+ memset(s, 0, sizeof(*s));
-+
-+ BT_DBG("session %p sock %p", s, sock);
-+
-+ INIT_LIST_HEAD(&s->dlcs);
-+ s->state = state;
-+ s->sock = sock;
-+
-+ s->mtu = RFCOMM_DEFAULT_MTU;
-+ s->credits = 0;
-+
-+ list_add(&s->list, &session_list);
-+
-+ /* Do not increment module usage count for listeting sessions.
-+ * Otherwise we won't be able to unload the module. */
-+ if (state != BT_LISTEN)
-+ MOD_INC_USE_COUNT;
-+ return s;
-+}
-+
-+void rfcomm_session_del(struct rfcomm_session *s)
-+{
-+ int state = s->state;
-+
-+ BT_DBG("session %p state %ld", s, s->state);
-+
-+ list_del(&s->list);
-+
-+ if (state == BT_CONNECTED)
-+ rfcomm_send_disc(s, 0);
-+
-+ sock_release(s->sock);
-+ kfree(s);
-+
-+ if (state != BT_LISTEN)
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+struct rfcomm_session *rfcomm_session_get(bdaddr_t *src, bdaddr_t *dst)
-+{
-+ struct rfcomm_session *s;
-+ struct list_head *p, *n;
-+ struct bluez_pinfo *pi;
-+ list_for_each_safe(p, n, &session_list) {
-+ s = list_entry(p, struct rfcomm_session, list);
-+ pi = bluez_pi(s->sock->sk);
-+
-+ if ((!bacmp(src, BDADDR_ANY) || !bacmp(&pi->src, src)) &&
-+ !bacmp(&pi->dst, dst))
-+ return s;
-+ }
-+ return NULL;
-+}
-+
-+void rfcomm_session_close(struct rfcomm_session *s, int err)
-+{
-+ struct rfcomm_dlc *d;
-+ struct list_head *p, *n;
-+
-+ BT_DBG("session %p state %ld err %d", s, s->state, err);
-+
-+ rfcomm_session_hold(s);
-+
-+ s->state = BT_CLOSED;
-+
-+ /* Close all dlcs */
-+ list_for_each_safe(p, n, &s->dlcs) {
-+ d = list_entry(p, struct rfcomm_dlc, list);
-+ d->state = BT_CLOSED;
-+ __rfcomm_dlc_close(d, err);
-+ }
-+
-+ rfcomm_session_put(s);
-+}
-+
-+struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst, int *err)
-+{
-+ struct rfcomm_session *s = NULL;
-+ struct sockaddr_l2 addr;
-+ struct l2cap_options opts;
-+ struct socket *sock;
-+ int size;
-+
-+ BT_DBG("%s %s", batostr(src), batostr(dst));
-+
-+ *err = rfcomm_l2sock_create(&sock);
-+ if (*err < 0)
-+ return NULL;
-+
-+ bacpy(&addr.l2_bdaddr, src);
-+ addr.l2_family = AF_BLUETOOTH;
-+ addr.l2_psm = 0;
-+ *err = sock->ops->bind(sock, (struct sockaddr *) &addr, sizeof(addr));
-+ if (*err < 0)
-+ goto failed;
-+
-+ /* Set L2CAP options */
-+ size = sizeof(opts);
-+ sock->ops->getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, &size);
-+
-+ opts.imtu = RFCOMM_MAX_L2CAP_MTU;
-+ sock->ops->setsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, size);
-+
-+ s = rfcomm_session_add(sock, BT_BOUND);
-+ if (!s) {
-+ *err = -ENOMEM;
-+ goto failed;
-+ }
-+
-+ s->initiator = 1;
-+
-+ bacpy(&addr.l2_bdaddr, dst);
-+ addr.l2_family = AF_BLUETOOTH;
-+ addr.l2_psm = htobs(RFCOMM_PSM);
-+ *err = sock->ops->connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
-+ if (*err == 0 || *err == -EAGAIN)
-+ return s;
-+
-+ rfcomm_session_del(s);
-+ return NULL;
-+
-+failed:
-+ sock_release(sock);
-+ return NULL;
-+}
-+
-+void rfcomm_session_getaddr(struct rfcomm_session *s, bdaddr_t *src, bdaddr_t *dst)
-+{
-+ struct sock *sk = s->sock->sk;
-+ if (src)
-+ bacpy(src, &bluez_pi(sk)->src);
-+ if (dst)
-+ bacpy(dst, &bluez_pi(sk)->dst);
-+}
-+
-+/* ---- RFCOMM frame sending ---- */
-+static int rfcomm_send_frame(struct rfcomm_session *s, u8 *data, int len)
-+{
-+ struct socket *sock = s->sock;
-+ struct iovec iv = { data, len };
-+ struct msghdr msg;
-+ int err;
-+
-+ BT_DBG("session %p len %d", s, len);
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_iovlen = 1;
-+ msg.msg_iov = &iv;
-+
-+ err = sock->ops->sendmsg(sock, &msg, len, 0);
-+ return err;
-+}
-+
-+static int rfcomm_send_sabm(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_cmd cmd;
-+
-+ BT_DBG("%p dlci %d", s, dlci);
-+
-+ cmd.addr = __addr(s->initiator, dlci);
-+ cmd.ctrl = __ctrl(RFCOMM_SABM, 1);
-+ cmd.len = __len8(0);
-+ cmd.fcs = __fcs2((u8 *) &cmd);
-+
-+ return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
-+}
-+
-+static int rfcomm_send_ua(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_cmd cmd;
-+
-+ BT_DBG("%p dlci %d", s, dlci);
-+
-+ cmd.addr = __addr(!s->initiator, dlci);
-+ cmd.ctrl = __ctrl(RFCOMM_UA, 1);
-+ cmd.len = __len8(0);
-+ cmd.fcs = __fcs2((u8 *) &cmd);
-+
-+ return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
-+}
-+
-+static int rfcomm_send_disc(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_cmd cmd;
-+
-+ BT_DBG("%p dlci %d", s, dlci);
-+
-+ cmd.addr = __addr(s->initiator, dlci);
-+ cmd.ctrl = __ctrl(RFCOMM_DISC, 1);
-+ cmd.len = __len8(0);
-+ cmd.fcs = __fcs2((u8 *) &cmd);
-+
-+ return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
-+}
-+
-+static int rfcomm_queue_disc(struct rfcomm_dlc *d)
-+{
-+ struct rfcomm_cmd *cmd;
-+ struct sk_buff *skb;
-+
-+ BT_DBG("dlc %p dlci %d", d, d->dlci);
-+
-+ skb = alloc_skb(sizeof(*cmd), GFP_KERNEL);
-+ if (!skb)
-+ return -ENOMEM;
-+
-+ cmd = (void *) __skb_put(skb, sizeof(*cmd));
-+ cmd->addr = d->addr;
-+ cmd->ctrl = __ctrl(RFCOMM_DISC, 1);
-+ cmd->len = __len8(0);
-+ cmd->fcs = __fcs2((u8 *) cmd);
-+
-+ skb_queue_tail(&d->tx_queue, skb);
-+ rfcomm_schedule(RFCOMM_SCHED_TX);
-+ return 0;
-+}
-+
-+static int rfcomm_send_dm(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_cmd cmd;
-+
-+ BT_DBG("%p dlci %d", s, dlci);
-+
-+ cmd.addr = __addr(!s->initiator, dlci);
-+ cmd.ctrl = __ctrl(RFCOMM_DM, 1);
-+ cmd.len = __len8(0);
-+ cmd.fcs = __fcs2((u8 *) &cmd);
-+
-+ return rfcomm_send_frame(s, (void *) &cmd, sizeof(cmd));
-+}
-+
-+static int rfcomm_send_nsc(struct rfcomm_session *s, int cr, u8 type)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d type %d", s, cr, type);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + 1);
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_NSC);
-+ mcc->len = __len8(1);
-+
-+ /* Type that we didn't like */
-+ *ptr = __mcc_type(cr, type); ptr++;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ struct rfcomm_pn *pn;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d dlci %d mtu %d", s, cr, d->dlci, d->mtu);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + sizeof(*pn));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_PN);
-+ mcc->len = __len8(sizeof(*pn));
-+
-+ pn = (void *) ptr; ptr += sizeof(*pn);
-+ pn->dlci = d->dlci;
-+ pn->priority = d->priority;
-+ pn->ack_timer = 0;
-+ pn->max_retrans = 0;
-+
-+ if (cr || d->credits) {
-+ pn->flow_ctrl = cr ? 0xf0 : 0xe0;
-+ pn->credits = RFCOMM_DEFAULT_CREDITS;
-+ } else {
-+ pn->flow_ctrl = 0;
-+ pn->credits = 0;
-+ }
-+
-+ pn->mtu = htobs(d->mtu);
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,
-+ u8 bit_rate, u8 data_bits, u8 stop_bits,
-+ u8 parity, u8 flow_ctrl_settings,
-+ u8 xon_char, u8 xoff_char, u16 param_mask)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ struct rfcomm_rpn *rpn;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d dlci %d bit_r 0x%x data_b 0x%x stop_b 0x%x parity 0x%x"
-+ "flwc_s 0x%x xon_c 0x%x xoff_c 0x%x p_mask 0x%x",
-+ s, cr, dlci, bit_rate, data_bits, stop_bits, parity,
-+ flow_ctrl_settings, xon_char, xoff_char, param_mask);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + sizeof(*rpn));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_RPN);
-+ mcc->len = __len8(sizeof(*rpn));
-+
-+ rpn = (void *) ptr; ptr += sizeof(*rpn);
-+ rpn->dlci = __addr(1, dlci);
-+ rpn->bit_rate = bit_rate;
-+ rpn->line_settings = __rpn_line_settings(data_bits, stop_bits, parity);
-+ rpn->flow_ctrl = flow_ctrl_settings;
-+ rpn->xon_char = xon_char;
-+ rpn->xoff_char = xoff_char;
-+ rpn->param_mask = param_mask;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_rls(struct rfcomm_session *s, int cr, u8 dlci, u8 status)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ struct rfcomm_rls *rls;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d status 0x%x", s, cr, status);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + sizeof(*rls));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_RLS);
-+ mcc->len = __len8(sizeof(*rls));
-+
-+ rls = (void *) ptr; ptr += sizeof(*rls);
-+ rls->dlci = __addr(1, dlci);
-+ rls->status = status;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_msc(struct rfcomm_session *s, int cr, u8 dlci, u8 v24_sig)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ struct rfcomm_msc *msc;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d v24 0x%x", s, cr, v24_sig);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc) + sizeof(*msc));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_MSC);
-+ mcc->len = __len8(sizeof(*msc));
-+
-+ msc = (void *) ptr; ptr += sizeof(*msc);
-+ msc->dlci = __addr(1, dlci);
-+ msc->v24_sig = v24_sig | 0x01;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_fcoff(struct rfcomm_session *s, int cr)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d", s, cr);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_FCOFF);
-+ mcc->len = __len8(0);
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_fcon(struct rfcomm_session *s, int cr)
-+{
-+ struct rfcomm_hdr *hdr;
-+ struct rfcomm_mcc *mcc;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p cr %d", s, cr);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = __addr(s->initiator, 0);
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+ hdr->len = __len8(sizeof(*mcc));
-+
-+ mcc = (void *) ptr; ptr += sizeof(*mcc);
-+ mcc->type = __mcc_type(cr, RFCOMM_FCON);
-+ mcc->len = __len8(0);
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static int rfcomm_send_test(struct rfcomm_session *s, int cr, u8 *pattern, int len)
-+{
-+ struct socket *sock = s->sock;
-+ struct iovec iv[3];
-+ struct msghdr msg;
-+ unsigned char hdr[5], crc[1];
-+
-+ if (len > 125)
-+ return -EINVAL;
-+
-+ BT_DBG("%p cr %d", s, cr);
-+
-+ hdr[0] = __addr(s->initiator, 0);
-+ hdr[1] = __ctrl(RFCOMM_UIH, 0);
-+ hdr[2] = 0x01 | ((len + 2) << 1);
-+ hdr[3] = 0x01 | ((cr & 0x01) << 1) | (RFCOMM_TEST << 2);
-+ hdr[4] = 0x01 | (len << 1);
-+
-+ crc[0] = __fcs(hdr);
-+
-+ iv[0].iov_base = hdr;
-+ iv[0].iov_len = 5;
-+ iv[1].iov_base = pattern;
-+ iv[1].iov_len = len;
-+ iv[2].iov_base = crc;
-+ iv[2].iov_len = 1;
-+
-+ memset(&msg, 0, sizeof(msg));
-+ msg.msg_iovlen = 3;
-+ msg.msg_iov = iv;
-+ return sock->ops->sendmsg(sock, &msg, 6 + len, 0);
-+}
-+
-+static int rfcomm_send_credits(struct rfcomm_session *s, u8 addr, u8 credits)
-+{
-+ struct rfcomm_hdr *hdr;
-+ u8 buf[16], *ptr = buf;
-+
-+ BT_DBG("%p addr %d credits %d", s, addr, credits);
-+
-+ hdr = (void *) ptr; ptr += sizeof(*hdr);
-+ hdr->addr = addr;
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 1);
-+ hdr->len = __len8(0);
-+
-+ *ptr = credits; ptr++;
-+
-+ *ptr = __fcs(buf); ptr++;
-+
-+ return rfcomm_send_frame(s, buf, ptr - buf);
-+}
-+
-+static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
-+{
-+ struct rfcomm_hdr *hdr;
-+ int len = skb->len;
-+ u8 *crc;
-+
-+ if (len > 127) {
-+ hdr = (void *) skb_push(skb, 4);
-+ put_unaligned(htobs(__len16(len)), (u16 *) &hdr->len);
-+ } else {
-+ hdr = (void *) skb_push(skb, 3);
-+ hdr->len = __len8(len);
-+ }
-+ hdr->addr = addr;
-+ hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
-+
-+ crc = skb_put(skb, 1);
-+ *crc = __fcs((void *) hdr);
-+}
-+
-+/* ---- RFCOMM frame reception ---- */
-+static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
-+{
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (dlci) {
-+ /* Data channel */
-+ struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
-+ if (!d) {
-+ rfcomm_send_dm(s, dlci);
-+ return 0;
-+ }
-+
-+ switch (d->state) {
-+ case BT_CONNECT:
-+ rfcomm_dlc_clear_timer(d);
-+
-+ rfcomm_dlc_lock(d);
-+ d->state = BT_CONNECTED;
-+ d->state_change(d, 0);
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_send_msc(s, 1, dlci, d->v24_sig);
-+ break;
-+
-+ case BT_DISCONN:
-+ d->state = BT_CLOSED;
-+ __rfcomm_dlc_close(d, 0);
-+ break;
-+ }
-+ } else {
-+ /* Control channel */
-+ switch (s->state) {
-+ case BT_CONNECT:
-+ s->state = BT_CONNECTED;
-+ rfcomm_process_connect(s);
-+ break;
-+ }
-+ }
-+ return 0;
-+}
-+
-+static int rfcomm_recv_dm(struct rfcomm_session *s, u8 dlci)
-+{
-+ int err = 0;
-+
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (dlci) {
-+ /* Data DLC */
-+ struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
-+ if (d) {
-+ if (d->state == BT_CONNECT || d->state == BT_CONFIG)
-+ err = ECONNREFUSED;
-+ else
-+ err = ECONNRESET;
-+
-+ d->state = BT_CLOSED;
-+ __rfcomm_dlc_close(d, err);
-+ }
-+ } else {
-+ if (s->state == BT_CONNECT)
-+ err = ECONNREFUSED;
-+ else
-+ err = ECONNRESET;
-+
-+ s->state = BT_CLOSED;
-+ rfcomm_session_close(s, err);
-+ }
-+ return 0;
-+}
-+
-+static int rfcomm_recv_disc(struct rfcomm_session *s, u8 dlci)
-+{
-+ int err = 0;
-+
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (dlci) {
-+ struct rfcomm_dlc *d = rfcomm_dlc_get(s, dlci);
-+ if (d) {
-+ rfcomm_send_ua(s, dlci);
-+
-+ if (d->state == BT_CONNECT || d->state == BT_CONFIG)
-+ err = ECONNREFUSED;
-+ else
-+ err = ECONNRESET;
-+
-+ d->state = BT_CLOSED;
-+ __rfcomm_dlc_close(d, err);
-+ } else
-+ rfcomm_send_dm(s, dlci);
-+
-+ } else {
-+ rfcomm_send_ua(s, 0);
-+
-+ if (s->state == BT_CONNECT)
-+ err = ECONNREFUSED;
-+ else
-+ err = ECONNRESET;
-+
-+ s->state = BT_CLOSED;
-+ rfcomm_session_close(s, err);
-+ }
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_sabm(struct rfcomm_session *s, u8 dlci)
-+{
-+ struct rfcomm_dlc *d;
-+ u8 channel;
-+
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (!dlci) {
-+ rfcomm_send_ua(s, 0);
-+
-+ if (s->state == BT_OPEN) {
-+ s->state = BT_CONNECTED;
-+ rfcomm_process_connect(s);
-+ }
-+ return 0;
-+ }
-+
-+ /* Check if DLC exists */
-+ d = rfcomm_dlc_get(s, dlci);
-+ if (d) {
-+ if (d->state == BT_OPEN) {
-+ /* DLC was previously opened by PN request */
-+ rfcomm_send_ua(s, dlci);
-+
-+ rfcomm_dlc_lock(d);
-+ d->state = BT_CONNECTED;
-+ d->state_change(d, 0);
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_send_msc(s, 1, dlci, d->v24_sig);
-+ }
-+ return 0;
-+ }
-+
-+ /* Notify socket layer about incomming connection */
-+ channel = __srv_channel(dlci);
-+ if (rfcomm_connect_ind(s, channel, &d)) {
-+ d->dlci = dlci;
-+ d->addr = __addr(s->initiator, dlci);
-+ rfcomm_dlc_link(s, d);
-+
-+ rfcomm_send_ua(s, dlci);
-+
-+ rfcomm_dlc_lock(d);
-+ d->state = BT_CONNECTED;
-+ d->state_change(d, 0);
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_send_msc(s, 1, dlci, d->v24_sig);
-+ } else {
-+ rfcomm_send_dm(s, dlci);
-+ }
-+
-+ return 0;
-+}
-+
-+static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
-+{
-+ struct rfcomm_session *s = d->session;
-+
-+ BT_DBG("dlc %p state %ld dlci %d mtu %d fc 0x%x credits %d",
-+ d, d->state, d->dlci, pn->mtu, pn->flow_ctrl, pn->credits);
-+
-+ if (cr) {
-+ if (pn->flow_ctrl == 0xf0) {
-+ s->credits = RFCOMM_MAX_CREDITS;
-+ d->credits = s->credits;
-+ d->tx_credits = pn->credits;
-+ } else {
-+ set_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+ d->credits = 0;
-+ }
-+ } else {
-+ if (pn->flow_ctrl == 0xe0) {
-+ s->credits = RFCOMM_MAX_CREDITS;
-+ d->credits = s->credits;
-+ d->tx_credits = pn->credits;
-+ } else {
-+ set_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+ d->credits = 0;
-+ }
-+ }
-+
-+ d->priority = pn->priority;
-+
-+ d->mtu = btohs(pn->mtu);
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_pn(struct rfcomm_session *s, int cr, struct sk_buff *skb)
-+{
-+ struct rfcomm_pn *pn = (void *) skb->data;
-+ struct rfcomm_dlc *d;
-+ u8 dlci = pn->dlci;
-+
-+ BT_DBG("session %p state %ld dlci %d", s, s->state, dlci);
-+
-+ if (!dlci)
-+ return 0;
-+
-+ d = rfcomm_dlc_get(s, dlci);
-+ if (d) {
-+ if (cr) {
-+ /* PN request */
-+ rfcomm_apply_pn(d, cr, pn);
-+ rfcomm_send_pn(s, 0, d);
-+ } else {
-+ /* PN response */
-+ switch (d->state) {
-+ case BT_CONFIG:
-+ rfcomm_apply_pn(d, cr, pn);
-+
-+ d->state = BT_CONNECT;
-+ rfcomm_send_sabm(s, d->dlci);
-+ break;
-+ }
-+ }
-+ } else {
-+ u8 channel = __srv_channel(dlci);
-+
-+ if (!cr)
-+ return 0;
-+
-+ /* PN request for non existing DLC.
-+ * Assume incomming connection. */
-+ if (rfcomm_connect_ind(s, channel, &d)) {
-+ d->dlci = dlci;
-+ d->addr = __addr(s->initiator, dlci);
-+ rfcomm_dlc_link(s, d);
-+
-+ rfcomm_apply_pn(d, cr, pn);
-+
-+ d->state = BT_OPEN;
-+ rfcomm_send_pn(s, 0, d);
-+ } else {
-+ rfcomm_send_dm(s, dlci);
-+ }
-+ }
-+ return 0;
-+}
-+
-+static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_buff *skb)
-+{
-+ struct rfcomm_rpn *rpn = (void *) skb->data;
-+ u8 dlci = __get_dlci(rpn->dlci);
-+
-+ u8 bit_rate = 0;
-+ u8 data_bits = 0;
-+ u8 stop_bits = 0;
-+ u8 parity = 0;
-+ u8 flow_ctrl = 0;
-+ u8 xon_char = 0;
-+ u8 xoff_char = 0;
-+ u16 rpn_mask = RFCOMM_RPN_PM_ALL;
-+
-+ BT_DBG("dlci %d cr %d len 0x%x bitr 0x%x line 0x%x flow 0x%x xonc 0x%x xoffc 0x%x pm 0x%x",
-+ dlci, cr, len, rpn->bit_rate, rpn->line_settings, rpn->flow_ctrl,
-+ rpn->xon_char, rpn->xoff_char, rpn->param_mask);
-+
-+ if (!cr)
-+ return 0;
-+
-+ if (len == 1) {
-+ /* request: return default setting */
-+ bit_rate = RFCOMM_RPN_BR_115200;
-+ data_bits = RFCOMM_RPN_DATA_8;
-+ stop_bits = RFCOMM_RPN_STOP_1;
-+ parity = RFCOMM_RPN_PARITY_NONE;
-+ flow_ctrl = RFCOMM_RPN_FLOW_NONE;
-+ xon_char = RFCOMM_RPN_XON_CHAR;
-+ xoff_char = RFCOMM_RPN_XOFF_CHAR;
-+
-+ goto rpn_out;
-+ }
-+ /* check for sane values: ignore/accept bit_rate, 8 bits, 1 stop bit, no parity,
-+ no flow control lines, normal XON/XOFF chars */
-+ if (rpn->param_mask & RFCOMM_RPN_PM_BITRATE) {
-+ bit_rate = rpn->bit_rate;
-+ if (bit_rate != RFCOMM_RPN_BR_115200) {
-+ BT_DBG("RPN bit rate mismatch 0x%x", bit_rate);
-+ bit_rate = RFCOMM_RPN_BR_115200;
-+ rpn_mask ^= RFCOMM_RPN_PM_BITRATE;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_DATA) {
-+ data_bits = __get_rpn_data_bits(rpn->line_settings);
-+ if (data_bits != RFCOMM_RPN_DATA_8) {
-+ BT_DBG("RPN data bits mismatch 0x%x", data_bits);
-+ data_bits = RFCOMM_RPN_DATA_8;
-+ rpn_mask ^= RFCOMM_RPN_PM_DATA;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_STOP) {
-+ stop_bits = __get_rpn_stop_bits(rpn->line_settings);
-+ if (stop_bits != RFCOMM_RPN_STOP_1) {
-+ BT_DBG("RPN stop bits mismatch 0x%x", stop_bits);
-+ stop_bits = RFCOMM_RPN_STOP_1;
-+ rpn_mask ^= RFCOMM_RPN_PM_STOP;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_PARITY) {
-+ parity = __get_rpn_parity(rpn->line_settings);
-+ if (parity != RFCOMM_RPN_PARITY_NONE) {
-+ BT_DBG("RPN parity mismatch 0x%x", parity);
-+ parity = RFCOMM_RPN_PARITY_NONE;
-+ rpn_mask ^= RFCOMM_RPN_PM_PARITY;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_FLOW) {
-+ flow_ctrl = rpn->flow_ctrl;
-+ if (flow_ctrl != RFCOMM_RPN_FLOW_NONE) {
-+ BT_DBG("RPN flow ctrl mismatch 0x%x", flow_ctrl);
-+ flow_ctrl = RFCOMM_RPN_FLOW_NONE;
-+ rpn_mask ^= RFCOMM_RPN_PM_FLOW;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_XON) {
-+ xon_char = rpn->xon_char;
-+ if (xon_char != RFCOMM_RPN_XON_CHAR) {
-+ BT_DBG("RPN XON char mismatch 0x%x", xon_char);
-+ xon_char = RFCOMM_RPN_XON_CHAR;
-+ rpn_mask ^= RFCOMM_RPN_PM_XON;
-+ }
-+ }
-+ if (rpn->param_mask & RFCOMM_RPN_PM_XOFF) {
-+ xoff_char = rpn->xoff_char;
-+ if (xoff_char != RFCOMM_RPN_XOFF_CHAR) {
-+ BT_DBG("RPN XOFF char mismatch 0x%x", xoff_char);
-+ xoff_char = RFCOMM_RPN_XOFF_CHAR;
-+ rpn_mask ^= RFCOMM_RPN_PM_XOFF;
-+ }
-+ }
-+
-+rpn_out:
-+ rfcomm_send_rpn(s, 0, dlci,
-+ bit_rate, data_bits, stop_bits, parity, flow_ctrl,
-+ xon_char, xoff_char, rpn_mask);
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_rls(struct rfcomm_session *s, int cr, struct sk_buff *skb)
-+{
-+ struct rfcomm_rls *rls = (void *) skb->data;
-+ u8 dlci = __get_dlci(rls->dlci);
-+
-+ BT_DBG("dlci %d cr %d status 0x%x", dlci, cr, rls->status);
-+
-+ if (!cr)
-+ return 0;
-+
-+ /* FIXME: We should probably do something with this
-+ information here. But for now it's sufficient just
-+ to reply -- Bluetooth 1.1 says it's mandatory to
-+ recognise and respond to RLS */
-+
-+ rfcomm_send_rls(s, 0, dlci, rls->status);
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_msc(struct rfcomm_session *s, int cr, struct sk_buff *skb)
-+{
-+ struct rfcomm_msc *msc = (void *) skb->data;
-+ struct rfcomm_dlc *d;
-+ u8 dlci = __get_dlci(msc->dlci);
-+
-+ BT_DBG("dlci %d cr %d v24 0x%x", dlci, cr, msc->v24_sig);
-+
-+ d = rfcomm_dlc_get(s, dlci);
-+ if (!d)
-+ return 0;
-+
-+ if (cr) {
-+ if (msc->v24_sig & RFCOMM_V24_FC && !d->credits)
-+ set_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+ else
-+ clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+
-+ rfcomm_dlc_lock(d);
-+ if (d->modem_status)
-+ d->modem_status(d, msc->v24_sig);
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_send_msc(s, 0, dlci, msc->v24_sig);
-+
-+ d->mscex |= RFCOMM_MSCEX_RX;
-+ } else
-+ d->mscex |= RFCOMM_MSCEX_TX;
-+
-+ return 0;
-+}
-+
-+static int rfcomm_recv_mcc(struct rfcomm_session *s, struct sk_buff *skb)
-+{
-+ struct rfcomm_mcc *mcc = (void *) skb->data;
-+ u8 type, cr, len;
-+
-+ cr = __test_cr(mcc->type);
-+ type = __get_mcc_type(mcc->type);
-+ len = __get_mcc_len(mcc->len);
-+
-+ BT_DBG("%p type 0x%x cr %d", s, type, cr);
-+
-+ skb_pull(skb, 2);
-+
-+ switch (type) {
-+ case RFCOMM_PN:
-+ rfcomm_recv_pn(s, cr, skb);
-+ break;
-+
-+ case RFCOMM_RPN:
-+ rfcomm_recv_rpn(s, cr, len, skb);
-+ break;
-+
-+ case RFCOMM_RLS:
-+ rfcomm_recv_rls(s, cr, skb);
-+ break;
-+
-+ case RFCOMM_MSC:
-+ rfcomm_recv_msc(s, cr, skb);
-+ break;
-+
-+ case RFCOMM_FCOFF:
-+ if (cr) {
-+ set_bit(RFCOMM_TX_THROTTLED, &s->flags);
-+ rfcomm_send_fcoff(s, 0);
-+ }
-+ break;
-+
-+ case RFCOMM_FCON:
-+ if (cr) {
-+ clear_bit(RFCOMM_TX_THROTTLED, &s->flags);
-+ rfcomm_send_fcon(s, 0);
-+ }
-+ break;
-+
-+ case RFCOMM_TEST:
-+ if (cr)
-+ rfcomm_send_test(s, 0, skb->data, skb->len);
-+ break;
-+
-+ case RFCOMM_NSC:
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown control type 0x%02x", type);
-+ rfcomm_send_nsc(s, cr, type);
-+ break;
-+ }
-+ return 0;
-+}
-+
-+static int rfcomm_recv_data(struct rfcomm_session *s, u8 dlci, int pf, struct sk_buff *skb)
-+{
-+ struct rfcomm_dlc *d;
-+
-+ BT_DBG("session %p state %ld dlci %d pf %d", s, s->state, dlci, pf);
-+
-+ d = rfcomm_dlc_get(s, dlci);
-+ if (!d) {
-+ rfcomm_send_dm(s, dlci);
-+ goto drop;
-+ }
-+
-+ if (pf && d->credits) {
-+ u8 credits = *(u8 *) skb->data; skb_pull(skb, 1);
-+
-+ d->tx_credits += credits;
-+ if (d->tx_credits)
-+ clear_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+ }
-+
-+ if (skb->len && d->state == BT_CONNECTED) {
-+ rfcomm_dlc_lock(d);
-+ d->rx_credits--;
-+ d->data_ready(d, skb);
-+ rfcomm_dlc_unlock(d);
-+ return 0;
-+ }
-+
-+drop:
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+static int rfcomm_recv_frame(struct rfcomm_session *s, struct sk_buff *skb)
-+{
-+ struct rfcomm_hdr *hdr = (void *) skb->data;
-+ u8 type, dlci, fcs;
-+
-+ dlci = __get_dlci(hdr->addr);
-+ type = __get_type(hdr->ctrl);
-+
-+ /* Trim FCS */
-+ skb->len--; skb->tail--;
-+ fcs = *(u8 *) skb->tail;
-+
-+ if (__check_fcs(skb->data, type, fcs)) {
-+ BT_ERR("bad checksum in packet");
-+ kfree_skb(skb);
-+ return -EILSEQ;
-+ }
-+
-+ if (__test_ea(hdr->len))
-+ skb_pull(skb, 3);
-+ else
-+ skb_pull(skb, 4);
-+
-+ switch (type) {
-+ case RFCOMM_SABM:
-+ if (__test_pf(hdr->ctrl))
-+ rfcomm_recv_sabm(s, dlci);
-+ break;
-+
-+ case RFCOMM_DISC:
-+ if (__test_pf(hdr->ctrl))
-+ rfcomm_recv_disc(s, dlci);
-+ break;
-+
-+ case RFCOMM_UA:
-+ if (__test_pf(hdr->ctrl))
-+ rfcomm_recv_ua(s, dlci);
-+ break;
-+
-+ case RFCOMM_DM:
-+ rfcomm_recv_dm(s, dlci);
-+ break;
-+
-+ case RFCOMM_UIH:
-+ if (dlci)
-+ return rfcomm_recv_data(s, dlci, __test_pf(hdr->ctrl), skb);
-+
-+ rfcomm_recv_mcc(s, skb);
-+ break;
-+
-+ default:
-+ BT_ERR("Unknown packet type 0x%02x\n", type);
-+ break;
-+ }
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+/* ---- Connection and data processing ---- */
-+
-+static void rfcomm_process_connect(struct rfcomm_session *s)
-+{
-+ struct rfcomm_dlc *d;
-+ struct list_head *p, *n;
-+
-+ BT_DBG("session %p state %ld", s, s->state);
-+
-+ list_for_each_safe(p, n, &s->dlcs) {
-+ d = list_entry(p, struct rfcomm_dlc, list);
-+ if (d->state == BT_CONFIG) {
-+ d->mtu = s->mtu;
-+ rfcomm_send_pn(s, 1, d);
-+ }
-+ }
-+}
-+
-+/* Send data queued for the DLC.
-+ * Return number of frames left in the queue.
-+ */
-+static inline int rfcomm_process_tx(struct rfcomm_dlc *d)
-+{
-+ struct sk_buff *skb;
-+ int err;
-+
-+ BT_DBG("dlc %p state %ld credits %d rx_credits %d tx_credits %d",
-+ d, d->state, d->credits, d->rx_credits, d->tx_credits);
-+
-+ /* Send pending MSC */
-+ if (test_and_clear_bit(RFCOMM_MSC_PENDING, &d->flags))
-+ rfcomm_send_msc(d->session, 1, d->dlci, d->v24_sig);
-+
-+ if (d->credits) {
-+ /* CFC enabled.
-+ * Give them some credits */
-+ if (!test_bit(RFCOMM_RX_THROTTLED, &d->flags) &&
-+ d->rx_credits <= (d->credits >> 2)) {
-+ rfcomm_send_credits(d->session, d->addr, d->credits - d->rx_credits);
-+ d->rx_credits = d->credits;
-+ }
-+ } else {
-+ /* CFC disabled.
-+ * Give ourselves some credits */
-+ d->tx_credits = 5;
-+ }
-+
-+ if (test_bit(RFCOMM_TX_THROTTLED, &d->flags))
-+ return skb_queue_len(&d->tx_queue);
-+
-+ while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) {
-+ err = rfcomm_send_frame(d->session, skb->data, skb->len);
-+ if (err < 0) {
-+ skb_queue_head(&d->tx_queue, skb);
-+ break;
-+ }
-+ kfree_skb(skb);
-+ d->tx_credits--;
-+ }
-+
-+ if (d->credits && !d->tx_credits) {
-+ /* We're out of TX credits.
-+ * Set TX_THROTTLED flag to avoid unnesary wakeups by dlc_send. */
-+ set_bit(RFCOMM_TX_THROTTLED, &d->flags);
-+ }
-+
-+ return skb_queue_len(&d->tx_queue);
-+}
-+
-+static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
-+{
-+ struct rfcomm_dlc *d;
-+ struct list_head *p, *n;
-+
-+ BT_DBG("session %p state %ld", s, s->state);
-+
-+ list_for_each_safe(p, n, &s->dlcs) {
-+ d = list_entry(p, struct rfcomm_dlc, list);
-+ if (test_bit(RFCOMM_TIMED_OUT, &d->flags)) {
-+ __rfcomm_dlc_close(d, ETIMEDOUT);
-+ continue;
-+ }
-+
-+ if (test_bit(RFCOMM_TX_THROTTLED, &s->flags))
-+ continue;
-+
-+ if ((d->state == BT_CONNECTED || d->state == BT_DISCONN) &&
-+ d->mscex == RFCOMM_MSCEX_OK)
-+ rfcomm_process_tx(d);
-+ }
-+}
-+
-+static inline void rfcomm_process_rx(struct rfcomm_session *s)
-+{
-+ struct socket *sock = s->sock;
-+ struct sock *sk = sock->sk;
-+ struct sk_buff *skb;
-+
-+ BT_DBG("session %p state %ld qlen %d", s, s->state, skb_queue_len(&sk->receive_queue));
-+
-+ /* Get data directly from socket receive queue without copying it. */
-+ while ((skb = skb_dequeue(&sk->receive_queue))) {
-+ skb_orphan(skb);
-+ rfcomm_recv_frame(s, skb);
-+ }
-+
-+ if (sk->state == BT_CLOSED) {
-+ if (!s->initiator)
-+ rfcomm_session_put(s);
-+
-+ rfcomm_session_close(s, sk->err);
-+ }
-+}
-+
-+static inline void rfcomm_accept_connection(struct rfcomm_session *s)
-+{
-+ struct socket *sock = s->sock, *nsock;
-+ int err;
-+
-+ /* Fast check for a new connection.
-+ * Avoids unnesesary socket allocations. */
-+ if (list_empty(&bluez_pi(sock->sk)->accept_q))
-+ return;
-+
-+ BT_DBG("session %p", s);
-+
-+ nsock = sock_alloc();
-+ if (!nsock)
-+ return;
-+
-+ nsock->type = sock->type;
-+ nsock->ops = sock->ops;
-+
-+ err = sock->ops->accept(sock, nsock, O_NONBLOCK);
-+ if (err < 0) {
-+ sock_release(nsock);
-+ return;
-+ }
-+
-+ /* Set our callbacks */
-+ nsock->sk->data_ready = rfcomm_l2data_ready;
-+ nsock->sk->state_change = rfcomm_l2state_change;
-+
-+ s = rfcomm_session_add(nsock, BT_OPEN);
-+ if (s)
-+ rfcomm_session_hold(s);
-+ else
-+ sock_release(nsock);
-+}
-+
-+static inline void rfcomm_check_connection(struct rfcomm_session *s)
-+{
-+ struct sock *sk = s->sock->sk;
-+
-+ BT_DBG("%p state %ld", s, s->state);
-+
-+ switch(sk->state) {
-+ case BT_CONNECTED:
-+ s->state = BT_CONNECT;
-+
-+ /* We can adjust MTU on outgoing sessions.
-+ * L2CAP MTU minus UIH header and FCS. */
-+ s->mtu = min(l2cap_pi(sk)->omtu, l2cap_pi(sk)->imtu) - 5;
-+
-+ rfcomm_send_sabm(s, 0);
-+ break;
-+
-+ case BT_CLOSED:
-+ s->state = BT_CLOSED;
-+ rfcomm_session_close(s, sk->err);
-+ break;
-+ }
-+}
-+
-+static inline void rfcomm_process_sessions(void)
-+{
-+ struct list_head *p, *n;
-+
-+ rfcomm_lock();
-+
-+ list_for_each_safe(p, n, &session_list) {
-+ struct rfcomm_session *s;
-+ s = list_entry(p, struct rfcomm_session, list);
-+
-+ if (s->state == BT_LISTEN) {
-+ rfcomm_accept_connection(s);
-+ continue;
-+ }
-+
-+ rfcomm_session_hold(s);
-+
-+ switch (s->state) {
-+ case BT_BOUND:
-+ rfcomm_check_connection(s);
-+ break;
-+
-+ default:
-+ rfcomm_process_rx(s);
-+ break;
-+ }
-+
-+ rfcomm_process_dlcs(s);
-+
-+ rfcomm_session_put(s);
-+ }
-+
-+ rfcomm_unlock();
-+}
-+
-+static void rfcomm_worker(void)
-+{
-+ BT_DBG("");
-+
-+ daemonize(); reparent_to_init();
-+ set_fs(KERNEL_DS);
-+
-+ while (!atomic_read(&terminate)) {
-+ BT_DBG("worker loop event 0x%lx", rfcomm_event);
-+
-+ if (!test_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event)) {
-+ /* No pending events. Let's sleep.
-+ * Incomming connections and data will wake us up. */
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ schedule();
-+ }
-+
-+ /* Process stuff */
-+ clear_bit(RFCOMM_SCHED_WAKEUP, &rfcomm_event);
-+ rfcomm_process_sessions();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ return;
-+}
-+
-+static int rfcomm_add_listener(bdaddr_t *ba)
-+{
-+ struct sockaddr_l2 addr;
-+ struct l2cap_options opts;
-+ struct socket *sock;
-+ struct rfcomm_session *s;
-+ int size, err = 0;
-+
-+ /* Create socket */
-+ err = rfcomm_l2sock_create(&sock);
-+ if (err < 0) {
-+ BT_ERR("Create socket failed %d", err);
-+ return err;
-+ }
-+
-+ /* Bind socket */
-+ bacpy(&addr.l2_bdaddr, ba);
-+ addr.l2_family = AF_BLUETOOTH;
-+ addr.l2_psm = htobs(RFCOMM_PSM);
-+ err = sock->ops->bind(sock, (struct sockaddr *) &addr, sizeof(addr));
-+ if (err < 0) {
-+ BT_ERR("Bind failed %d", err);
-+ goto failed;
-+ }
-+
-+ /* Set L2CAP options */
-+ size = sizeof(opts);
-+ sock->ops->getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, &size);
-+
-+ opts.imtu = RFCOMM_MAX_L2CAP_MTU;
-+ sock->ops->setsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, (void *)&opts, size);
-+
-+ /* Start listening on the socket */
-+ err = sock->ops->listen(sock, 10);
-+ if (err) {
-+ BT_ERR("Listen failed %d", err);
-+ goto failed;
-+ }
-+
-+ /* Add listening session */
-+ s = rfcomm_session_add(sock, BT_LISTEN);
-+ if (!s)
-+ goto failed;
-+
-+ rfcomm_session_hold(s);
-+ return 0;
-+failed:
-+ sock_release(sock);
-+ return err;
-+}
-+
-+static void rfcomm_kill_listener(void)
-+{
-+ struct rfcomm_session *s;
-+ struct list_head *p, *n;
-+
-+ BT_DBG("");
-+
-+ list_for_each_safe(p, n, &session_list) {
-+ s = list_entry(p, struct rfcomm_session, list);
-+ rfcomm_session_del(s);
-+ }
-+}
-+
-+static int rfcomm_run(void *unused)
-+{
-+ rfcomm_thread = current;
-+
-+ atomic_inc(&running);
-+
-+ daemonize(); reparent_to_init();
-+
-+ sigfillset(&current->blocked);
-+ set_fs(KERNEL_DS);
-+
-+ sprintf(current->comm, "krfcommd");
-+
-+ BT_DBG("");
-+
-+ rfcomm_add_listener(BDADDR_ANY);
-+
-+ rfcomm_worker();
-+
-+ rfcomm_kill_listener();
-+
-+ atomic_dec(&running);
-+ return 0;
-+}
-+
-+/* ---- Proc fs support ---- */
-+static int rfcomm_dlc_dump(char *buf)
-+{
-+ struct rfcomm_session *s;
-+ struct sock *sk;
-+ struct list_head *p, *pp;
-+ char *ptr = buf;
-+
-+ rfcomm_lock();
-+
-+ list_for_each(p, &session_list) {
-+ s = list_entry(p, struct rfcomm_session, list);
-+ sk = s->sock->sk;
-+
-+ list_for_each(pp, &s->dlcs) {
-+ struct rfcomm_dlc *d;
-+ d = list_entry(pp, struct rfcomm_dlc, list);
-+
-+ ptr += sprintf(ptr, "dlc %s %s %ld %d %d %d %d\n",
-+ batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
-+ d->state, d->dlci, d->mtu, d->rx_credits, d->tx_credits);
-+ }
-+ }
-+
-+ rfcomm_unlock();
-+
-+ return ptr - buf;
-+}
-+
-+extern int rfcomm_sock_dump(char *buf);
-+
-+static int rfcomm_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
-+{
-+ char *ptr = buf;
-+ int len;
-+
-+ BT_DBG("count %d, offset %ld", count, offset);
-+
-+ ptr += rfcomm_dlc_dump(ptr);
-+ ptr += rfcomm_sock_dump(ptr);
-+ len = ptr - buf;
-+
-+ if (len <= count + offset)
-+ *eof = 1;
-+
-+ *start = buf + offset;
-+ len -= offset;
-+
-+ if (len > count)
-+ len = count;
-+ if (len < 0)
-+ len = 0;
-+
-+ return len;
-+}
-+
-+/* ---- Initialization ---- */
-+int __init rfcomm_init(void)
-+{
-+ l2cap_load();
-+
-+ kernel_thread(rfcomm_run, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-+
-+ rfcomm_init_sockets();
-+
-+#ifdef CONFIG_BLUEZ_RFCOMM_TTY
-+ rfcomm_init_ttys();
-+#endif
-+
-+ create_proc_read_entry("bluetooth/rfcomm", 0, 0, rfcomm_read_proc, NULL);
-+
-+ BT_INFO("BlueZ RFCOMM ver %s", VERSION);
-+ BT_INFO("Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>");
-+ BT_INFO("Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>");
-+ return 0;
-+}
-+
-+void rfcomm_cleanup(void)
-+{
-+ /* Terminate working thread.
-+ * ie. Set terminate flag and wake it up */
-+ atomic_inc(&terminate);
-+ rfcomm_schedule(RFCOMM_SCHED_STATE);
-+
-+ /* Wait until thread is running */
-+ while (atomic_read(&running))
-+ schedule();
-+
-+ remove_proc_entry("bluetooth/rfcomm", NULL);
-+
-+#ifdef CONFIG_BLUEZ_RFCOMM_TTY
-+ rfcomm_cleanup_ttys();
-+#endif
-+
-+ rfcomm_cleanup_sockets();
-+ return;
-+}
-+
-+module_init(rfcomm_init);
-+module_exit(rfcomm_cleanup);
-+
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
-+MODULE_DESCRIPTION("BlueZ RFCOMM ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/crc.c linux-2.4.18-mh9/net/bluetooth/rfcomm/crc.c
---- linux-2.4.18/net/bluetooth/rfcomm/crc.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/rfcomm/crc.c Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,71 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * RFCOMM FCS calculation.
-+ *
-+ * $Id$
-+ */
-+
-+/* reversed, 8-bit, poly=0x07 */
-+unsigned char rfcomm_crc_table[256] = {
-+ 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75,
-+ 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b,
-+ 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69,
-+ 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67,
-+
-+ 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d,
-+ 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43,
-+ 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51,
-+ 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f,
-+
-+ 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05,
-+ 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b,
-+ 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19,
-+ 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17,
-+
-+ 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d,
-+ 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33,
-+ 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21,
-+ 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f,
-+
-+ 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95,
-+ 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b,
-+ 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89,
-+ 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87,
-+
-+ 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad,
-+ 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3,
-+ 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1,
-+ 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf,
-+
-+ 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5,
-+ 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb,
-+ 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9,
-+ 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7,
-+
-+ 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd,
-+ 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3,
-+ 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1,
-+ 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf
-+};
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/sock.c linux-2.4.18-mh9/net/bluetooth/rfcomm/sock.c
---- linux-2.4.18/net/bluetooth/rfcomm/sock.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/rfcomm/sock.c Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,847 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * RFCOMM sockets.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/socket.h>
-+#include <linux/skbuff.h>
-+#include <linux/list.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/rfcomm.h>
-+
-+#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+static struct proto_ops rfcomm_sock_ops;
-+
-+static struct bluez_sock_list rfcomm_sk_list = {
-+ lock: RW_LOCK_UNLOCKED
-+};
-+
-+static void rfcomm_sock_close(struct sock *sk);
-+static void rfcomm_sock_kill(struct sock *sk);
-+
-+/* ---- DLC callbacks ----
-+ *
-+ * called under rfcomm_dlc_lock()
-+ */
-+static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb)
-+{
-+ struct sock *sk = d->owner;
-+ if (!sk)
-+ return;
-+
-+ atomic_add(skb->len, &sk->rmem_alloc);
-+ skb_queue_tail(&sk->receive_queue, skb);
-+ sk->data_ready(sk, skb->len);
-+
-+ if (atomic_read(&sk->rmem_alloc) >= sk->rcvbuf)
-+ rfcomm_dlc_throttle(d);
-+}
-+
-+static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
-+{
-+ struct sock *sk = d->owner, *parent;
-+ if (!sk)
-+ return;
-+
-+ BT_DBG("dlc %p state %ld err %d", d, d->state, err);
-+
-+ bh_lock_sock(sk);
-+
-+ if (err)
-+ sk->err = err;
-+ sk->state = d->state;
-+
-+ parent = bluez_pi(sk)->parent;
-+ if (!parent) {
-+ if (d->state == BT_CONNECTED)
-+ rfcomm_session_getaddr(d->session, &bluez_pi(sk)->src, NULL);
-+ sk->state_change(sk);
-+ } else
-+ parent->data_ready(parent, 0);
-+
-+ bh_unlock_sock(sk);
-+}
-+
-+/* ---- Socket functions ---- */
-+static struct sock *__rfcomm_get_sock_by_addr(u8 channel, bdaddr_t *src)
-+{
-+ struct sock *sk;
-+
-+ for (sk = rfcomm_sk_list.head; sk; sk = sk->next) {
-+ if (rfcomm_pi(sk)->channel == channel &&
-+ !bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+ }
-+
-+ return sk;
-+}
-+
-+/* Find socket with channel and source bdaddr.
-+ * Returns closest match.
-+ */
-+static struct sock *__rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
-+{
-+ struct sock *sk, *sk1 = NULL;
-+
-+ for (sk = rfcomm_sk_list.head; sk; sk = sk->next) {
-+ if (state && sk->state != state)
-+ continue;
-+
-+ if (rfcomm_pi(sk)->channel == channel) {
-+ /* Exact match. */
-+ if (!bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+
-+ /* Closest match */
-+ if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
-+ sk1 = sk;
-+ }
-+ }
-+ return sk ? sk : sk1;
-+}
-+
-+/* Find socket with given address (channel, src).
-+ * Returns locked socket */
-+static inline struct sock *rfcomm_get_sock_by_channel(int state, u8 channel, bdaddr_t *src)
-+{
-+ struct sock *s;
-+ read_lock(&rfcomm_sk_list.lock);
-+ s = __rfcomm_get_sock_by_channel(state, channel, src);
-+ if (s) bh_lock_sock(s);
-+ read_unlock(&rfcomm_sk_list.lock);
-+ return s;
-+}
-+
-+static void rfcomm_sock_destruct(struct sock *sk)
-+{
-+ struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
-+
-+ BT_DBG("sk %p dlc %p", sk, d);
-+
-+ skb_queue_purge(&sk->receive_queue);
-+ skb_queue_purge(&sk->write_queue);
-+
-+ rfcomm_dlc_lock(d);
-+ rfcomm_pi(sk)->dlc = NULL;
-+
-+ /* Detach DLC if it's owned by this socket */
-+ if (d->owner == sk)
-+ d->owner = NULL;
-+ rfcomm_dlc_unlock(d);
-+
-+ rfcomm_dlc_put(d);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void rfcomm_sock_cleanup_listen(struct sock *parent)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("parent %p", parent);
-+
-+ /* Close not yet accepted dlcs */
-+ while ((sk = bluez_accept_dequeue(parent, NULL))) {
-+ rfcomm_sock_close(sk);
-+ rfcomm_sock_kill(sk);
-+ }
-+
-+ parent->state = BT_CLOSED;
-+ parent->zapped = 1;
-+}
-+
-+/* Kill socket (only if zapped and orphan)
-+ * Must be called on unlocked socket.
-+ */
-+static void rfcomm_sock_kill(struct sock *sk)
-+{
-+ if (!sk->zapped || sk->socket)
-+ return;
-+
-+ BT_DBG("sk %p state %d refcnt %d", sk, sk->state, atomic_read(&sk->refcnt));
-+
-+ /* Kill poor orphan */
-+ bluez_sock_unlink(&rfcomm_sk_list, sk);
-+ sk->dead = 1;
-+ sock_put(sk);
-+}
-+
-+static void __rfcomm_sock_close(struct sock *sk)
-+{
-+ struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
-+
-+ BT_DBG("sk %p state %d socket %p", sk, sk->state, sk->socket);
-+
-+ switch (sk->state) {
-+ case BT_LISTEN:
-+ rfcomm_sock_cleanup_listen(sk);
-+ break;
-+
-+ case BT_CONNECT:
-+ case BT_CONNECT2:
-+ case BT_CONFIG:
-+ case BT_CONNECTED:
-+ rfcomm_dlc_close(d, 0);
-+
-+ default:
-+ sk->zapped = 1;
-+ break;
-+ }
-+}
-+
-+/* Close socket.
-+ * Must be called on unlocked socket.
-+ */
-+static void rfcomm_sock_close(struct sock *sk)
-+{
-+ lock_sock(sk);
-+ __rfcomm_sock_close(sk);
-+ release_sock(sk);
-+}
-+
-+static void rfcomm_sock_init(struct sock *sk, struct sock *parent)
-+{
-+ BT_DBG("sk %p", sk);
-+
-+ if (parent)
-+ sk->type = parent->type;
-+}
-+
-+static struct sock *rfcomm_sock_alloc(struct socket *sock, int proto, int prio)
-+{
-+ struct rfcomm_dlc *d;
-+ struct sock *sk;
-+
-+ sk = sk_alloc(PF_BLUETOOTH, prio, 1);
-+ if (!sk)
-+ return NULL;
-+
-+ d = rfcomm_dlc_alloc(prio);
-+ if (!d) {
-+ sk_free(sk);
-+ return NULL;
-+ }
-+ d->data_ready = rfcomm_sk_data_ready;
-+ d->state_change = rfcomm_sk_state_change;
-+
-+ rfcomm_pi(sk)->dlc = d;
-+ d->owner = sk;
-+
-+ bluez_sock_init(sock, sk);
-+
-+ sk->zapped = 0;
-+
-+ sk->destruct = rfcomm_sock_destruct;
-+ sk->sndtimeo = RFCOMM_CONN_TIMEOUT;
-+
-+ sk->sndbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
-+ sk->rcvbuf = RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
-+
-+ sk->protocol = proto;
-+ sk->state = BT_OPEN;
-+
-+ bluez_sock_link(&rfcomm_sk_list, sk);
-+
-+ BT_DBG("sk %p", sk);
-+
-+ MOD_INC_USE_COUNT;
-+ return sk;
-+}
-+
-+static int rfcomm_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ sock->state = SS_UNCONNECTED;
-+
-+ if (sock->type != SOCK_STREAM && sock->type != SOCK_RAW)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &rfcomm_sock_ops;
-+
-+ if (!(sk = rfcomm_sock_alloc(sock, protocol, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ rfcomm_sock_init(sk, NULL);
-+ return 0;
-+}
-+
-+static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
-+{
-+ struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p %s", sk, batostr(&sa->rc_bdaddr));
-+
-+ if (!addr || addr->sa_family != AF_BLUETOOTH)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_OPEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ write_lock_bh(&rfcomm_sk_list.lock);
-+
-+ if (sa->rc_channel && __rfcomm_get_sock_by_addr(sa->rc_channel, &sa->rc_bdaddr)) {
-+ err = -EADDRINUSE;
-+ } else {
-+ /* Save source address */
-+ bacpy(&bluez_pi(sk)->src, &sa->rc_bdaddr);
-+ rfcomm_pi(sk)->channel = sa->rc_channel;
-+ sk->state = BT_BOUND;
-+ }
-+
-+ write_unlock_bh(&rfcomm_sk_list.lock);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
-+{
-+ struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
-+ struct sock *sk = sock->sk;
-+ struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
-+ int err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_rc))
-+ return -EINVAL;
-+
-+ if (sk->state != BT_OPEN && sk->state != BT_BOUND)
-+ return -EBADFD;
-+
-+ if (sk->type != SOCK_STREAM)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ sk->state = BT_CONNECT;
-+ bacpy(&bluez_pi(sk)->dst, &sa->rc_bdaddr);
-+ rfcomm_pi(sk)->channel = sa->rc_channel;
-+
-+ err = rfcomm_dlc_open(d, &bluez_pi(sk)->src, &sa->rc_bdaddr, sa->rc_channel);
-+ if (!err)
-+ err = bluez_sock_wait_state(sk, BT_CONNECTED,
-+ sock_sndtimeo(sk, flags & O_NONBLOCK));
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int rfcomm_sock_listen(struct socket *sock, int backlog)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p backlog %d", sk, backlog);
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_BOUND) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ sk->max_ack_backlog = backlog;
-+ sk->ack_backlog = 0;
-+ sk->state = BT_LISTEN;
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int flags)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct sock *sk = sock->sk, *nsk;
-+ long timeo;
-+ int err = 0;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
-+
-+ BT_DBG("sk %p timeo %ld", sk, timeo);
-+
-+ /* Wait for an incoming connection. (wake-one). */
-+ add_wait_queue_exclusive(sk->sleep, &wait);
-+ while (!(nsk = bluez_accept_dequeue(sk, newsock))) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ break;
-+ }
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ break;
-+ }
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ if (err)
-+ goto done;
-+
-+ newsock->state = SS_CONNECTED;
-+
-+ BT_DBG("new socket %p", nsk);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
-+{
-+ struct sockaddr_rc *sa = (struct sockaddr_rc *) addr;
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ sa->rc_family = AF_BLUETOOTH;
-+ sa->rc_channel = rfcomm_pi(sk)->channel;
-+ if (peer)
-+ bacpy(&sa->rc_bdaddr, &bluez_pi(sk)->dst);
-+ else
-+ bacpy(&sa->rc_bdaddr, &bluez_pi(sk)->src);
-+
-+ *len = sizeof(struct sockaddr_rc);
-+ return 0;
-+}
-+
-+static int rfcomm_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
-+ struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
-+ struct sk_buff *skb;
-+ int err, size;
-+ int sent = 0;
-+
-+ if (msg->msg_flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ if (sk->shutdown & SEND_SHUTDOWN)
-+ return -EPIPE;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ lock_sock(sk);
-+
-+ while (len) {
-+ size = min_t(uint, len, d->mtu);
-+
-+ skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE,
-+ msg->msg_flags & MSG_DONTWAIT, &err);
-+ if (!skb)
-+ break;
-+ skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
-+
-+ err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
-+ if (err) {
-+ kfree_skb(skb);
-+ sent = err;
-+ break;
-+ }
-+
-+ err = rfcomm_dlc_send(d, skb);
-+ if (err < 0) {
-+ kfree_skb(skb);
-+ break;
-+ }
-+
-+ sent += size;
-+ len -= size;
-+ }
-+
-+ release_sock(sk);
-+
-+ return sent ? sent : err;
-+}
-+
-+static long rfcomm_sock_data_wait(struct sock *sk, long timeo)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+
-+ add_wait_queue(sk->sleep, &wait);
-+ for (;;) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (skb_queue_len(&sk->receive_queue) || sk->err || (sk->shutdown & RCV_SHUTDOWN) ||
-+ signal_pending(current) || !timeo)
-+ break;
-+
-+ set_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+ clear_bit(SOCK_ASYNC_WAITDATA, &sk->socket->flags);
-+ }
-+
-+ __set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+ return timeo;
-+}
-+
-+static int rfcomm_sock_recvmsg(struct socket *sock, struct msghdr *msg, int size,
-+ int flags, struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ int target, err = 0, copied = 0;
-+ long timeo;
-+
-+ if (flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ msg->msg_namelen = 0;
-+
-+ BT_DBG("sk %p size %d", sk, size);
-+
-+ lock_sock(sk);
-+
-+ target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
-+ timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
-+
-+ do {
-+ struct sk_buff *skb;
-+ int chunk;
-+
-+ skb = skb_dequeue(&sk->receive_queue);
-+ if (!skb) {
-+ if (copied >= target)
-+ break;
-+
-+ if ((err = sock_error(sk)) != 0)
-+ break;
-+ if (sk->shutdown & RCV_SHUTDOWN)
-+ break;
-+
-+ err = -EAGAIN;
-+ if (!timeo)
-+ break;
-+
-+ timeo = rfcomm_sock_data_wait(sk, timeo);
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ goto out;
-+ }
-+ continue;
-+ }
-+
-+ chunk = min_t(unsigned int, skb->len, size);
-+ if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
-+ skb_queue_head(&sk->receive_queue, skb);
-+ if (!copied)
-+ copied = -EFAULT;
-+ break;
-+ }
-+ copied += chunk;
-+ size -= chunk;
-+
-+ if (!(flags & MSG_PEEK)) {
-+ atomic_sub(chunk, &sk->rmem_alloc);
-+
-+ skb_pull(skb, chunk);
-+ if (skb->len) {
-+ skb_queue_head(&sk->receive_queue, skb);
-+ break;
-+ }
-+ kfree_skb(skb);
-+
-+ } else {
-+ /* put message back and return */
-+ skb_queue_head(&sk->receive_queue, skb);
-+ break;
-+ }
-+ } while (size);
-+
-+out:
-+ if (atomic_read(&sk->rmem_alloc) <= (sk->rcvbuf >> 2))
-+ rfcomm_dlc_unthrottle(rfcomm_pi(sk)->dlc);
-+
-+ release_sock(sk);
-+ return copied ? : err;
-+}
-+
-+static int rfcomm_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ int len, err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (get_user(len, optlen))
-+ return -EFAULT;
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-+{
-+ struct sock *sk = sock->sk;
-+ int err;
-+
-+ lock_sock(sk);
-+
-+#ifdef CONFIG_BLUEZ_RFCOMM_TTY
-+ err = rfcomm_dev_ioctl(sk, cmd, arg);
-+#else
-+ err = -EOPNOTSUPP;
-+#endif
-+
-+ release_sock(sk);
-+
-+ return err;
-+}
-+
-+static int rfcomm_sock_shutdown(struct socket *sock, int how)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk) return 0;
-+
-+ lock_sock(sk);
-+ if (!sk->shutdown) {
-+ sk->shutdown = SHUTDOWN_MASK;
-+ __rfcomm_sock_close(sk);
-+
-+ if (sk->linger)
-+ err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
-+ }
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int rfcomm_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ err = rfcomm_sock_shutdown(sock, 2);
-+
-+ sock_orphan(sk);
-+ rfcomm_sock_kill(sk);
-+ return err;
-+}
-+
-+/* ---- RFCOMM core layer callbacks ----
-+ *
-+ * called under rfcomm_lock()
-+ */
-+int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc **d)
-+{
-+ struct sock *sk, *parent;
-+ bdaddr_t src, dst;
-+ int result = 0;
-+
-+ BT_DBG("session %p channel %d", s, channel);
-+
-+ rfcomm_session_getaddr(s, &src, &dst);
-+
-+ /* Check if we have socket listening on this channel */
-+ parent = rfcomm_get_sock_by_channel(BT_LISTEN, channel, &src);
-+ if (!parent)
-+ return 0;
-+
-+ /* Check for backlog size */
-+ if (parent->ack_backlog > parent->max_ack_backlog) {
-+ BT_DBG("backlog full %d", parent->ack_backlog);
-+ goto done;
-+ }
-+
-+ sk = rfcomm_sock_alloc(NULL, BTPROTO_RFCOMM, GFP_ATOMIC);
-+ if (!sk)
-+ goto done;
-+
-+ rfcomm_sock_init(sk, parent);
-+ bacpy(&bluez_pi(sk)->src, &src);
-+ bacpy(&bluez_pi(sk)->dst, &dst);
-+ rfcomm_pi(sk)->channel = channel;
-+
-+ sk->state = BT_CONFIG;
-+ bluez_accept_enqueue(parent, sk);
-+
-+ /* Accept connection and return socket DLC */
-+ *d = rfcomm_pi(sk)->dlc;
-+ result = 1;
-+
-+done:
-+ bh_unlock_sock(parent);
-+ return result;
-+}
-+
-+/* ---- Proc fs support ---- */
-+int rfcomm_sock_dump(char *buf)
-+{
-+ struct bluez_sock_list *list = &rfcomm_sk_list;
-+ struct rfcomm_pinfo *pi;
-+ struct sock *sk;
-+ char *ptr = buf;
-+
-+ write_lock_bh(&list->lock);
-+
-+ for (sk = list->head; sk; sk = sk->next) {
-+ pi = rfcomm_pi(sk);
-+ ptr += sprintf(ptr, "sk %s %s %d %d\n",
-+ batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
-+ sk->state, rfcomm_pi(sk)->channel);
-+ }
-+
-+ write_unlock_bh(&list->lock);
-+
-+ return ptr - buf;
-+}
-+
-+static struct proto_ops rfcomm_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: rfcomm_sock_release,
-+ bind: rfcomm_sock_bind,
-+ connect: rfcomm_sock_connect,
-+ listen: rfcomm_sock_listen,
-+ accept: rfcomm_sock_accept,
-+ getname: rfcomm_sock_getname,
-+ sendmsg: rfcomm_sock_sendmsg,
-+ recvmsg: rfcomm_sock_recvmsg,
-+ shutdown: rfcomm_sock_shutdown,
-+ setsockopt: rfcomm_sock_setsockopt,
-+ getsockopt: rfcomm_sock_getsockopt,
-+ ioctl: rfcomm_sock_ioctl,
-+ poll: bluez_sock_poll,
-+ socketpair: sock_no_socketpair,
-+ mmap: sock_no_mmap
-+};
-+
-+static struct net_proto_family rfcomm_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: rfcomm_sock_create
-+};
-+
-+int rfcomm_init_sockets(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_RFCOMM, &rfcomm_sock_family_ops))) {
-+ BT_ERR("Can't register RFCOMM socket layer");
-+ return err;
-+ }
-+
-+ return 0;
-+}
-+
-+void rfcomm_cleanup_sockets(void)
-+{
-+ int err;
-+
-+ /* Unregister socket, protocol and notifier */
-+ if ((err = bluez_sock_unregister(BTPROTO_RFCOMM)))
-+ BT_ERR("Can't unregister RFCOMM socket layer %d", err);
-+}
-diff -urN linux-2.4.18/net/bluetooth/rfcomm/tty.c linux-2.4.18-mh9/net/bluetooth/rfcomm/tty.c
---- linux-2.4.18/net/bluetooth/rfcomm/tty.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/rfcomm/tty.c Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,945 @@
-+/*
-+ RFCOMM implementation for Linux Bluetooth stack (BlueZ).
-+ Copyright (C) 2002 Maxim Krasnyansky <maxk@qualcomm.com>
-+ Copyright (C) 2002 Marcel Holtmann <marcel@holtmann.org>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * RFCOMM TTY.
-+ *
-+ * $Id$
-+ */
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/tty.h>
-+#include <linux/tty_driver.h>
-+#include <linux/tty_flip.h>
-+
-+#include <linux/slab.h>
-+#include <linux/skbuff.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/rfcomm.h>
-+
-+#ifndef CONFIG_BLUEZ_RFCOMM_DEBUG
-+#undef BT_DBG
-+#define BT_DBG(D...)
-+#endif
-+
-+#define RFCOMM_TTY_MAGIC 0x6d02 /* magic number for rfcomm struct */
-+#define RFCOMM_TTY_PORTS RFCOMM_MAX_DEV /* whole lotta rfcomm devices */
-+#define RFCOMM_TTY_MAJOR 216 /* device node major id of the usb/bluetooth.c driver */
-+#define RFCOMM_TTY_MINOR 0
-+
-+struct rfcomm_dev {
-+ struct list_head list;
-+ atomic_t refcnt;
-+
-+ char name[12];
-+ int id;
-+ unsigned long flags;
-+ int opened;
-+ int err;
-+
-+ bdaddr_t src;
-+ bdaddr_t dst;
-+ u8 channel;
-+
-+ uint modem_status;
-+
-+ struct rfcomm_dlc *dlc;
-+ struct tty_struct *tty;
-+ wait_queue_head_t wait;
-+ struct tasklet_struct wakeup_task;
-+
-+ atomic_t wmem_alloc;
-+};
-+
-+static LIST_HEAD(rfcomm_dev_list);
-+static rwlock_t rfcomm_dev_lock = RW_LOCK_UNLOCKED;
-+
-+static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
-+static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
-+static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
-+
-+static void rfcomm_tty_wakeup(unsigned long arg);
-+
-+/* ---- Device functions ---- */
-+static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
-+{
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+
-+ BT_DBG("dev %p dlc %p", dev, dlc);
-+
-+ rfcomm_dlc_lock(dlc);
-+ /* Detach DLC if it's owned by this dev */
-+ if (dlc->owner == dev)
-+ dlc->owner = NULL;
-+ rfcomm_dlc_unlock(dlc);
-+
-+ rfcomm_dlc_put(dlc);
-+ kfree(dev);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static inline void rfcomm_dev_hold(struct rfcomm_dev *dev)
-+{
-+ atomic_inc(&dev->refcnt);
-+}
-+
-+static inline void rfcomm_dev_put(struct rfcomm_dev *dev)
-+{
-+ if (atomic_dec_and_test(&dev->refcnt))
-+ rfcomm_dev_destruct(dev);
-+}
-+
-+static struct rfcomm_dev *__rfcomm_dev_get(int id)
-+{
-+ struct rfcomm_dev *dev;
-+ struct list_head *p;
-+
-+ list_for_each(p, &rfcomm_dev_list) {
-+ dev = list_entry(p, struct rfcomm_dev, list);
-+ if (dev->id == id)
-+ return dev;
-+ }
-+
-+ return NULL;
-+}
-+
-+static inline struct rfcomm_dev *rfcomm_dev_get(int id)
-+{
-+ struct rfcomm_dev *dev;
-+
-+ read_lock(&rfcomm_dev_lock);
-+ dev = __rfcomm_dev_get(id);
-+ read_unlock(&rfcomm_dev_lock);
-+
-+ if (dev) rfcomm_dev_hold(dev);
-+ return dev;
-+}
-+
-+static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
-+{
-+ struct rfcomm_dev *dev;
-+ struct list_head *head = &rfcomm_dev_list, *p;
-+ int err = 0;
-+
-+ BT_DBG("id %d channel %d", req->dev_id, req->channel);
-+
-+ dev = kmalloc(sizeof(struct rfcomm_dev), GFP_KERNEL);
-+ if (!dev)
-+ return -ENOMEM;
-+ memset(dev, 0, sizeof(struct rfcomm_dev));
-+
-+ write_lock_bh(&rfcomm_dev_lock);
-+
-+ if (req->dev_id < 0) {
-+ dev->id = 0;
-+
-+ list_for_each(p, &rfcomm_dev_list) {
-+ if (list_entry(p, struct rfcomm_dev, list)->id != dev->id)
-+ break;
-+
-+ dev->id++;
-+ head = p;
-+ }
-+ } else {
-+ dev->id = req->dev_id;
-+
-+ list_for_each(p, &rfcomm_dev_list) {
-+ struct rfcomm_dev *entry = list_entry(p, struct rfcomm_dev, list);
-+
-+ if (entry->id == dev->id) {
-+ err = -EADDRINUSE;
-+ goto out;
-+ }
-+
-+ if (entry->id > dev->id - 1)
-+ break;
-+
-+ head = p;
-+ }
-+ }
-+
-+ if ((dev->id < 0) || (dev->id > RFCOMM_MAX_DEV - 1)) {
-+ err = -ENFILE;
-+ goto out;
-+ }
-+
-+ sprintf(dev->name, "rfcomm%d", dev->id);
-+
-+ list_add(&dev->list, head);
-+ atomic_set(&dev->refcnt, 1);
-+
-+ bacpy(&dev->src, &req->src);
-+ bacpy(&dev->dst, &req->dst);
-+ dev->channel = req->channel;
-+
-+ dev->flags = req->flags &
-+ ((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
-+
-+ init_waitqueue_head(&dev->wait);
-+ tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev);
-+
-+ rfcomm_dlc_lock(dlc);
-+ dlc->data_ready = rfcomm_dev_data_ready;
-+ dlc->state_change = rfcomm_dev_state_change;
-+ dlc->modem_status = rfcomm_dev_modem_status;
-+
-+ dlc->owner = dev;
-+ dev->dlc = dlc;
-+ rfcomm_dlc_unlock(dlc);
-+
-+ MOD_INC_USE_COUNT;
-+
-+out:
-+ write_unlock_bh(&rfcomm_dev_lock);
-+
-+ if (err) {
-+ kfree(dev);
-+ return err;
-+ } else
-+ return dev->id;
-+}
-+
-+static void rfcomm_dev_del(struct rfcomm_dev *dev)
-+{
-+ BT_DBG("dev %p", dev);
-+
-+ write_lock_bh(&rfcomm_dev_lock);
-+ list_del_init(&dev->list);
-+ write_unlock_bh(&rfcomm_dev_lock);
-+
-+ rfcomm_dev_put(dev);
-+}
-+
-+/* ---- Send buffer ---- */
-+
-+static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc)
-+{
-+ /* We can't let it be zero, because we don't get a callback
-+ when tx_credits becomes nonzero, hence we'd never wake up */
-+ return dlc->mtu * (dlc->tx_credits?:1);
-+}
-+
-+static void rfcomm_wfree(struct sk_buff *skb)
-+{
-+ struct rfcomm_dev *dev = (void *) skb->sk;
-+ atomic_sub(skb->truesize, &dev->wmem_alloc);
-+ if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags))
-+ tasklet_schedule(&dev->wakeup_task);
-+ rfcomm_dev_put(dev);
-+}
-+
-+static inline void rfcomm_set_owner_w(struct sk_buff *skb, struct rfcomm_dev *dev)
-+{
-+ rfcomm_dev_hold(dev);
-+ atomic_add(skb->truesize, &dev->wmem_alloc);
-+ skb->sk = (void *) dev;
-+ skb->destructor = rfcomm_wfree;
-+}
-+
-+static struct sk_buff *rfcomm_wmalloc(struct rfcomm_dev *dev, unsigned long size, int force, int priority)
-+{
-+ if (force || atomic_read(&dev->wmem_alloc) < rfcomm_room(dev->dlc)) {
-+ struct sk_buff *skb = alloc_skb(size, priority);
-+ if (skb) {
-+ rfcomm_set_owner_w(skb, dev);
-+ return skb;
-+ }
-+ }
-+ return NULL;
-+}
-+
-+/* ---- Device IOCTLs ---- */
-+
-+#define NOCAP_FLAGS ((1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP))
-+
-+static int rfcomm_create_dev(struct sock *sk, unsigned long arg)
-+{
-+ struct rfcomm_dev_req req;
-+ struct rfcomm_dlc *dlc;
-+ int id;
-+
-+ if (copy_from_user(&req, (void *) arg, sizeof(req)))
-+ return -EFAULT;
-+
-+ BT_DBG("sk %p dev_id %id flags 0x%x", sk, req.dev_id, req.flags);
-+
-+ if (req.flags != NOCAP_FLAGS && !capable(CAP_NET_ADMIN))
-+ return -EPERM;
-+
-+ if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
-+ /* Socket must be connected */
-+ if (sk->state != BT_CONNECTED)
-+ return -EBADFD;
-+
-+ dlc = rfcomm_pi(sk)->dlc;
-+ rfcomm_dlc_hold(dlc);
-+ } else {
-+ dlc = rfcomm_dlc_alloc(GFP_KERNEL);
-+ if (!dlc)
-+ return -ENOMEM;
-+ }
-+
-+ id = rfcomm_dev_add(&req, dlc);
-+ if (id < 0) {
-+ rfcomm_dlc_put(dlc);
-+ return id;
-+ }
-+
-+ if (req.flags & (1 << RFCOMM_REUSE_DLC)) {
-+ /* DLC is now used by device.
-+ * Socket must be disconnected */
-+ sk->state = BT_CLOSED;
-+ }
-+
-+ return id;
-+}
-+
-+static int rfcomm_release_dev(unsigned long arg)
-+{
-+ struct rfcomm_dev_req req;
-+ struct rfcomm_dev *dev;
-+
-+ if (copy_from_user(&req, (void *) arg, sizeof(req)))
-+ return -EFAULT;
-+
-+ BT_DBG("dev_id %id flags 0x%x", req.dev_id, req.flags);
-+
-+ if (!capable(CAP_NET_ADMIN))
-+ return -EPERM;
-+
-+ if (!(dev = rfcomm_dev_get(req.dev_id)))
-+ return -ENODEV;
-+
-+ if (req.flags & (1 << RFCOMM_HANGUP_NOW))
-+ rfcomm_dlc_close(dev->dlc, 0);
-+
-+ rfcomm_dev_del(dev);
-+ rfcomm_dev_put(dev);
-+ return 0;
-+}
-+
-+static int rfcomm_get_dev_list(unsigned long arg)
-+{
-+ struct rfcomm_dev_list_req *dl;
-+ struct rfcomm_dev_info *di;
-+ struct list_head *p;
-+ int n = 0, size;
-+ u16 dev_num;
-+
-+ BT_DBG("");
-+
-+ if (get_user(dev_num, (u16 *) arg))
-+ return -EFAULT;
-+
-+ if (!dev_num)
-+ return -EINVAL;
-+
-+ size = sizeof(*dl) + dev_num * sizeof(*di);
-+
-+ if (verify_area(VERIFY_WRITE, (void *)arg, size))
-+ return -EFAULT;
-+
-+ if (!(dl = kmalloc(size, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ di = dl->dev_info;
-+
-+ read_lock_bh(&rfcomm_dev_lock);
-+
-+ list_for_each(p, &rfcomm_dev_list) {
-+ struct rfcomm_dev *dev = list_entry(p, struct rfcomm_dev, list);
-+ (di + n)->id = dev->id;
-+ (di + n)->flags = dev->flags;
-+ (di + n)->state = dev->dlc->state;
-+ (di + n)->channel = dev->channel;
-+ bacpy(&(di + n)->src, &dev->src);
-+ bacpy(&(di + n)->dst, &dev->dst);
-+ if (++n >= dev_num)
-+ break;
-+ }
-+
-+ read_unlock_bh(&rfcomm_dev_lock);
-+
-+ dl->dev_num = n;
-+ size = sizeof(*dl) + n * sizeof(*di);
-+
-+ copy_to_user((void *) arg, dl, size);
-+ kfree(dl);
-+ return 0;
-+}
-+
-+static int rfcomm_get_dev_info(unsigned long arg)
-+{
-+ struct rfcomm_dev *dev;
-+ struct rfcomm_dev_info di;
-+ int err = 0;
-+
-+ BT_DBG("");
-+
-+ if (copy_from_user(&di, (void *)arg, sizeof(di)))
-+ return -EFAULT;
-+
-+ if (!(dev = rfcomm_dev_get(di.id)))
-+ return -ENODEV;
-+
-+ di.flags = dev->flags;
-+ di.channel = dev->channel;
-+ di.state = dev->dlc->state;
-+ bacpy(&di.src, &dev->src);
-+ bacpy(&di.dst, &dev->dst);
-+
-+ if (copy_to_user((void *)arg, &di, sizeof(di)))
-+ err = -EFAULT;
-+
-+ rfcomm_dev_put(dev);
-+ return err;
-+}
-+
-+int rfcomm_dev_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg)
-+{
-+ BT_DBG("cmd %d arg %ld", cmd, arg);
-+
-+ switch (cmd) {
-+ case RFCOMMCREATEDEV:
-+ return rfcomm_create_dev(sk, arg);
-+
-+ case RFCOMMRELEASEDEV:
-+ return rfcomm_release_dev(arg);
-+
-+ case RFCOMMGETDEVLIST:
-+ return rfcomm_get_dev_list(arg);
-+
-+ case RFCOMMGETDEVINFO:
-+ return rfcomm_get_dev_info(arg);
-+ }
-+
-+ return -EINVAL;
-+}
-+
-+/* ---- DLC callbacks ---- */
-+static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
-+{
-+ struct rfcomm_dev *dev = dlc->owner;
-+ struct tty_struct *tty;
-+
-+ if (!dev || !(tty = dev->tty)) {
-+ kfree_skb(skb);
-+ return;
-+ }
-+
-+ BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len);
-+
-+ if (test_bit(TTY_DONT_FLIP, &tty->flags)) {
-+ register int i;
-+ for (i = 0; i < skb->len; i++) {
-+ if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-+ tty_flip_buffer_push(tty);
-+
-+ tty_insert_flip_char(tty, skb->data[i], 0);
-+ }
-+ tty_flip_buffer_push(tty);
-+ } else
-+ tty->ldisc.receive_buf(tty, skb->data, NULL, skb->len);
-+
-+ kfree_skb(skb);
-+}
-+
-+static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
-+{
-+ struct rfcomm_dev *dev = dlc->owner;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("dlc %p dev %p err %d", dlc, dev, err);
-+
-+ dev->err = err;
-+ wake_up_interruptible(&dev->wait);
-+
-+ if (dlc->state == BT_CLOSED) {
-+ if (!dev->tty) {
-+ if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
-+ rfcomm_dev_hold(dev);
-+ rfcomm_dev_del(dev);
-+
-+ /* We have to drop DLC lock here, otherwise
-+ * rfcomm_dev_put() will dead lock if it's the last refference */
-+ rfcomm_dlc_unlock(dlc);
-+ rfcomm_dev_put(dev);
-+ rfcomm_dlc_lock(dlc);
-+ }
-+ } else
-+ tty_hangup(dev->tty);
-+ }
-+}
-+
-+static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
-+{
-+ struct rfcomm_dev *dev = dlc->owner;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("dlc %p dev %p v24_sig 0x%02x", dlc, dev, v24_sig);
-+
-+ dev->modem_status =
-+ ((v24_sig & RFCOMM_V24_RTC) ? (TIOCM_DSR | TIOCM_DTR) : 0) |
-+ ((v24_sig & RFCOMM_V24_RTR) ? (TIOCM_RTS | TIOCM_CTS) : 0) |
-+ ((v24_sig & RFCOMM_V24_IC) ? TIOCM_RI : 0) |
-+ ((v24_sig & RFCOMM_V24_DV) ? TIOCM_CD : 0);
-+}
-+
-+/* ---- TTY functions ---- */
-+static void rfcomm_tty_wakeup(unsigned long arg)
-+{
-+ struct rfcomm_dev *dev = (void *) arg;
-+ struct tty_struct *tty = dev->tty;
-+ if (!tty)
-+ return;
-+
-+ BT_DBG("dev %p tty %p", dev, tty);
-+
-+ if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
-+ (tty->ldisc.write_wakeup)(tty);
-+
-+ wake_up_interruptible(&tty->write_wait);
-+#ifdef SERIAL_HAVE_POLL_WAIT
-+ wake_up_interruptible(&tty->poll_wait);
-+#endif
-+}
-+
-+static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct rfcomm_dev *dev;
-+ struct rfcomm_dlc *dlc;
-+ int err, id;
-+
-+ id = MINOR(tty->device) - tty->driver.minor_start;
-+
-+ BT_DBG("tty %p id %d", tty, id);
-+
-+ dev = rfcomm_dev_get(id);
-+ if (!dev)
-+ return -ENODEV;
-+
-+ BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst), dev->channel, dev->opened);
-+
-+ if (dev->opened++ != 0)
-+ return 0;
-+
-+ dlc = dev->dlc;
-+
-+ /* Attach TTY and open DLC */
-+
-+ rfcomm_dlc_lock(dlc);
-+ tty->driver_data = dev;
-+ dev->tty = tty;
-+ rfcomm_dlc_unlock(dlc);
-+ set_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
-+
-+ err = rfcomm_dlc_open(dlc, &dev->src, &dev->dst, dev->channel);
-+ if (err < 0)
-+ return err;
-+
-+ /* Wait for DLC to connect */
-+ add_wait_queue(&dev->wait, &wait);
-+ while (1) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+
-+ if (dlc->state == BT_CLOSED) {
-+ err = -dev->err;
-+ break;
-+ }
-+
-+ if (dlc->state == BT_CONNECTED)
-+ break;
-+
-+ if (signal_pending(current)) {
-+ err = -EINTR;
-+ break;
-+ }
-+
-+ schedule();
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(&dev->wait, &wait);
-+
-+ return err;
-+}
-+
-+static void rfcomm_tty_close(struct tty_struct *tty, struct file *filp)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("tty %p dev %p dlc %p opened %d", tty, dev, dev->dlc, dev->opened);
-+
-+ if (--dev->opened == 0) {
-+ /* Close DLC and dettach TTY */
-+ rfcomm_dlc_close(dev->dlc, 0);
-+
-+ clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
-+ tasklet_kill(&dev->wakeup_task);
-+
-+ rfcomm_dlc_lock(dev->dlc);
-+ tty->driver_data = NULL;
-+ dev->tty = NULL;
-+ rfcomm_dlc_unlock(dev->dlc);
-+ }
-+
-+ rfcomm_dev_put(dev);
-+}
-+
-+static int rfcomm_tty_write(struct tty_struct *tty, int from_user, const unsigned char *buf, int count)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+ struct sk_buff *skb;
-+ int err = 0, sent = 0, size;
-+
-+ BT_DBG("tty %p from_user %d count %d", tty, from_user, count);
-+
-+ while (count) {
-+ size = min_t(uint, count, dlc->mtu);
-+
-+ if (from_user)
-+ skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, 0, GFP_KERNEL);
-+ else
-+ skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, 0, GFP_ATOMIC);
-+
-+ if (!skb)
-+ break;
-+
-+ skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
-+
-+ if (from_user)
-+ copy_from_user(skb_put(skb, size), buf + sent, size);
-+ else
-+ memcpy(skb_put(skb, size), buf + sent, size);
-+
-+ if ((err = rfcomm_dlc_send(dlc, skb)) < 0) {
-+ kfree_skb(skb);
-+ break;
-+ }
-+
-+ sent += size;
-+ count -= size;
-+ }
-+
-+ return sent ? sent : err;
-+}
-+
-+static void rfcomm_tty_put_char(struct tty_struct *tty, unsigned char ch)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+ struct sk_buff *skb;
-+
-+ BT_DBG("tty %p char %x", tty, ch);
-+
-+ skb = rfcomm_wmalloc(dev, 1 + RFCOMM_SKB_RESERVE, 1, GFP_ATOMIC);
-+
-+ if (!skb)
-+ return;
-+
-+ skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
-+
-+ *(char *)skb_put(skb, 1) = ch;
-+
-+ if ((rfcomm_dlc_send(dlc, skb)) < 0)
-+ kfree_skb(skb);
-+}
-+
-+static int rfcomm_tty_write_room(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ int room;
-+
-+ BT_DBG("tty %p", tty);
-+
-+ room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc);
-+ if (room < 0)
-+ room = 0;
-+
-+ return room;
-+}
-+
-+static int rfcomm_tty_set_modem_status(uint cmd, struct rfcomm_dlc *dlc, uint status)
-+{
-+ u8 v24_sig, mask;
-+
-+ BT_DBG("dlc %p cmd 0x%02x", dlc, cmd);
-+
-+ if (cmd == TIOCMSET)
-+ v24_sig = 0;
-+ else
-+ rfcomm_dlc_get_modem_status(dlc, &v24_sig);
-+
-+ mask = ((status & TIOCM_DSR) ? RFCOMM_V24_RTC : 0) |
-+ ((status & TIOCM_DTR) ? RFCOMM_V24_RTC : 0) |
-+ ((status & TIOCM_RTS) ? RFCOMM_V24_RTR : 0) |
-+ ((status & TIOCM_CTS) ? RFCOMM_V24_RTR : 0) |
-+ ((status & TIOCM_RI) ? RFCOMM_V24_IC : 0) |
-+ ((status & TIOCM_CD) ? RFCOMM_V24_DV : 0);
-+
-+ if (cmd == TIOCMBIC)
-+ v24_sig &= ~mask;
-+ else
-+ v24_sig |= mask;
-+
-+ rfcomm_dlc_set_modem_status(dlc, v24_sig);
-+ return 0;
-+}
-+
-+static int rfcomm_tty_ioctl(struct tty_struct *tty, struct file *filp, unsigned int cmd, unsigned long arg)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+ uint status;
-+ int err;
-+
-+ BT_DBG("tty %p cmd 0x%02x", tty, cmd);
-+
-+ switch (cmd) {
-+ case TCGETS:
-+ BT_DBG("TCGETS is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TCSETS:
-+ BT_DBG("TCSETS is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCMGET:
-+ BT_DBG("TIOCMGET");
-+
-+ return put_user(dev->modem_status, (unsigned int *)arg);
-+
-+ case TIOCMSET: /* Turns on and off the lines as specified by the mask */
-+ case TIOCMBIS: /* Turns on the lines as specified by the mask */
-+ case TIOCMBIC: /* Turns off the lines as specified by the mask */
-+ if ((err = get_user(status, (unsigned int *)arg)))
-+ return err;
-+ return rfcomm_tty_set_modem_status(cmd, dlc, status);
-+
-+ case TIOCMIWAIT:
-+ BT_DBG("TIOCMIWAIT");
-+ break;
-+
-+ case TIOCGICOUNT:
-+ BT_DBG("TIOCGICOUNT");
-+ break;
-+
-+ case TIOCGSERIAL:
-+ BT_ERR("TIOCGSERIAL is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCSSERIAL:
-+ BT_ERR("TIOCSSERIAL is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCSERGSTRUCT:
-+ BT_ERR("TIOCSERGSTRUCT is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCSERGETLSR:
-+ BT_ERR("TIOCSERGETLSR is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ case TIOCSERCONFIG:
-+ BT_ERR("TIOCSERCONFIG is not supported");
-+ return -ENOIOCTLCMD;
-+
-+ default:
-+ return -ENOIOCTLCMD; /* ioctls which we must ignore */
-+
-+ }
-+
-+ return -ENOIOCTLCMD;
-+}
-+
-+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
-+
-+static void rfcomm_tty_set_termios(struct tty_struct *tty, struct termios *old)
-+{
-+ BT_DBG("tty %p", tty);
-+
-+ if ((tty->termios->c_cflag == old->c_cflag) &&
-+ (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old->c_iflag)))
-+ return;
-+
-+ /* handle turning off CRTSCTS */
-+ if ((old->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) {
-+ BT_DBG("turning off CRTSCTS");
-+ }
-+}
-+
-+static void rfcomm_tty_throttle(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ rfcomm_dlc_throttle(dev->dlc);
-+}
-+
-+static void rfcomm_tty_unthrottle(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ rfcomm_dlc_unthrottle(dev->dlc);
-+}
-+
-+static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ struct rfcomm_dlc *dlc = dev->dlc;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ if (skb_queue_len(&dlc->tx_queue))
-+ return dlc->mtu;
-+
-+ return 0;
-+}
-+
-+static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ skb_queue_purge(&dev->dlc->tx_queue);
-+
-+ if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
-+ tty->ldisc.write_wakeup(tty);
-+}
-+
-+static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
-+{
-+ BT_DBG("tty %p ch %c", tty, ch);
-+}
-+
-+static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
-+{
-+ BT_DBG("tty %p timeout %d", tty, timeout);
-+}
-+
-+static void rfcomm_tty_hangup(struct tty_struct *tty)
-+{
-+ struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
-+ if (!dev)
-+ return;
-+
-+ BT_DBG("tty %p dev %p", tty, dev);
-+
-+ rfcomm_tty_flush_buffer(tty);
-+
-+ if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
-+ rfcomm_dev_del(dev);
-+}
-+
-+static int rfcomm_tty_read_proc(char *buf, char **start, off_t offset, int len, int *eof, void *unused)
-+{
-+ return 0;
-+}
-+
-+/* ---- TTY structure ---- */
-+static int rfcomm_tty_refcount; /* If we manage several devices */
-+
-+static struct tty_struct *rfcomm_tty_table[RFCOMM_TTY_PORTS];
-+static struct termios *rfcomm_tty_termios[RFCOMM_TTY_PORTS];
-+static struct termios *rfcomm_tty_termios_locked[RFCOMM_TTY_PORTS];
-+
-+static struct tty_driver rfcomm_tty_driver = {
-+ magic: TTY_DRIVER_MAGIC,
-+ driver_name: "rfcomm",
-+#ifdef CONFIG_DEVFS_FS
-+ name: "bluetooth/rfcomm/%d",
-+#else
-+ name: "rfcomm",
-+#endif
-+ major: RFCOMM_TTY_MAJOR,
-+ minor_start: RFCOMM_TTY_MINOR,
-+ num: RFCOMM_TTY_PORTS,
-+ type: TTY_DRIVER_TYPE_SERIAL,
-+ subtype: SERIAL_TYPE_NORMAL,
-+ flags: TTY_DRIVER_REAL_RAW,
-+
-+ refcount: &rfcomm_tty_refcount,
-+ table: rfcomm_tty_table,
-+ termios: rfcomm_tty_termios,
-+ termios_locked: rfcomm_tty_termios_locked,
-+
-+ open: rfcomm_tty_open,
-+ close: rfcomm_tty_close,
-+ put_char: rfcomm_tty_put_char,
-+ write: rfcomm_tty_write,
-+ write_room: rfcomm_tty_write_room,
-+ chars_in_buffer: rfcomm_tty_chars_in_buffer,
-+ flush_buffer: rfcomm_tty_flush_buffer,
-+ ioctl: rfcomm_tty_ioctl,
-+ throttle: rfcomm_tty_throttle,
-+ unthrottle: rfcomm_tty_unthrottle,
-+ set_termios: rfcomm_tty_set_termios,
-+ send_xchar: rfcomm_tty_send_xchar,
-+ stop: NULL,
-+ start: NULL,
-+ hangup: rfcomm_tty_hangup,
-+ wait_until_sent: rfcomm_tty_wait_until_sent,
-+ read_proc: rfcomm_tty_read_proc,
-+};
-+
-+int rfcomm_init_ttys(void)
-+{
-+ int i;
-+
-+ /* Initalize our global data */
-+ for (i = 0; i < RFCOMM_TTY_PORTS; i++)
-+ rfcomm_tty_table[i] = NULL;
-+
-+ /* Register the TTY driver */
-+ rfcomm_tty_driver.init_termios = tty_std_termios;
-+ rfcomm_tty_driver.init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-+ rfcomm_tty_driver.flags = TTY_DRIVER_REAL_RAW;
-+
-+ if (tty_register_driver(&rfcomm_tty_driver)) {
-+ BT_ERR("Can't register RFCOMM TTY driver");
-+ return -1;
-+ }
-+
-+ return 0;
-+}
-+
-+void rfcomm_cleanup_ttys(void)
-+{
-+ tty_unregister_driver(&rfcomm_tty_driver);
-+ return;
-+}
-diff -urN linux-2.4.18/net/bluetooth/sco.c linux-2.4.18-mh9/net/bluetooth/sco.c
---- linux-2.4.18/net/bluetooth/sco.c Thu Jan 1 01:00:00 1970
-+++ linux-2.4.18-mh9/net/bluetooth/sco.c Mon Aug 25 18:38:12 2003
-@@ -0,0 +1,1019 @@
-+/*
-+ BlueZ - Bluetooth protocol stack for Linux
-+ Copyright (C) 2000-2001 Qualcomm Incorporated
-+
-+ Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License version 2 as
-+ published by the Free Software Foundation;
-+
-+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-+ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
-+ IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
-+ CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
-+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-+
-+ ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
-+ COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
-+ SOFTWARE IS DISCLAIMED.
-+*/
-+
-+/*
-+ * BlueZ SCO sockets.
-+ *
-+ * $Id$
-+ */
-+#define VERSION "0.3"
-+
-+#include <linux/config.h>
-+#include <linux/module.h>
-+
-+#include <linux/types.h>
-+#include <linux/errno.h>
-+#include <linux/kernel.h>
-+#include <linux/major.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/poll.h>
-+#include <linux/fcntl.h>
-+#include <linux/init.h>
-+#include <linux/skbuff.h>
-+#include <linux/interrupt.h>
-+#include <linux/socket.h>
-+#include <linux/skbuff.h>
-+#include <linux/proc_fs.h>
-+#include <linux/list.h>
-+#include <net/sock.h>
-+
-+#include <asm/system.h>
-+#include <asm/uaccess.h>
-+
-+#include <net/bluetooth/bluetooth.h>
-+#include <net/bluetooth/hci_core.h>
-+#include <net/bluetooth/sco.h>
-+
-+#ifndef SCO_DEBUG
-+#undef BT_DBG
-+#define BT_DBG( A... )
-+#endif
-+
-+static struct proto_ops sco_sock_ops;
-+
-+static struct bluez_sock_list sco_sk_list = {
-+ lock: RW_LOCK_UNLOCKED
-+};
-+
-+static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent);
-+static void sco_chan_del(struct sock *sk, int err);
-+static inline struct sock * sco_chan_get(struct sco_conn *conn);
-+
-+static int sco_conn_del(struct hci_conn *conn, int err);
-+
-+static void sco_sock_close(struct sock *sk);
-+static void sco_sock_kill(struct sock *sk);
-+
-+/* ----- SCO timers ------ */
-+static void sco_sock_timeout(unsigned long arg)
-+{
-+ struct sock *sk = (struct sock *) arg;
-+
-+ BT_DBG("sock %p state %d", sk, sk->state);
-+
-+ bh_lock_sock(sk);
-+ sk->err = ETIMEDOUT;
-+ sk->state_change(sk);
-+ bh_unlock_sock(sk);
-+
-+ sco_sock_kill(sk);
-+ sock_put(sk);
-+}
-+
-+static void sco_sock_set_timer(struct sock *sk, long timeout)
-+{
-+ BT_DBG("sock %p state %d timeout %ld", sk, sk->state, timeout);
-+
-+ if (!mod_timer(&sk->timer, jiffies + timeout))
-+ sock_hold(sk);
-+}
-+
-+static void sco_sock_clear_timer(struct sock *sk)
-+{
-+ BT_DBG("sock %p state %d", sk, sk->state);
-+
-+ if (timer_pending(&sk->timer) && del_timer(&sk->timer))
-+ __sock_put(sk);
-+}
-+
-+static void sco_sock_init_timer(struct sock *sk)
-+{
-+ init_timer(&sk->timer);
-+ sk->timer.function = sco_sock_timeout;
-+ sk->timer.data = (unsigned long)sk;
-+}
-+
-+/* -------- SCO connections --------- */
-+static struct sco_conn *sco_conn_add(struct hci_conn *hcon, __u8 status)
-+{
-+ struct hci_dev *hdev = hcon->hdev;
-+ struct sco_conn *conn;
-+
-+ if ((conn = hcon->sco_data))
-+ return conn;
-+
-+ if (status)
-+ return conn;
-+
-+ if (!(conn = kmalloc(sizeof(struct sco_conn), GFP_ATOMIC)))
-+ return NULL;
-+ memset(conn, 0, sizeof(struct sco_conn));
-+
-+ spin_lock_init(&conn->lock);
-+
-+ hcon->sco_data = conn;
-+ conn->hcon = hcon;
-+
-+ conn->src = &hdev->bdaddr;
-+ conn->dst = &hcon->dst;
-+
-+ if (hdev->sco_mtu > 0)
-+ conn->mtu = hdev->sco_mtu;
-+ else
-+ conn->mtu = 60;
-+
-+ BT_DBG("hcon %p conn %p", hcon, conn);
-+
-+ MOD_INC_USE_COUNT;
-+ return conn;
-+}
-+
-+static int sco_conn_del(struct hci_conn *hcon, int err)
-+{
-+ struct sco_conn *conn;
-+ struct sock *sk;
-+
-+ if (!(conn = hcon->sco_data))
-+ return 0;
-+
-+ BT_DBG("hcon %p conn %p, err %d", hcon, conn, err);
-+
-+ /* Kill socket */
-+ if ((sk = sco_chan_get(conn))) {
-+ bh_lock_sock(sk);
-+ sco_sock_clear_timer(sk);
-+ sco_chan_del(sk, err);
-+ bh_unlock_sock(sk);
-+ sco_sock_kill(sk);
-+ }
-+
-+ hcon->sco_data = NULL;
-+ kfree(conn);
-+
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+int sco_connect(struct sock *sk)
-+{
-+ bdaddr_t *src = &bluez_pi(sk)->src;
-+ bdaddr_t *dst = &bluez_pi(sk)->dst;
-+ struct sco_conn *conn;
-+ struct hci_conn *hcon;
-+ struct hci_dev *hdev;
-+ int err = 0;
-+
-+ BT_DBG("%s -> %s", batostr(src), batostr(dst));
-+
-+ if (!(hdev = hci_get_route(dst, src)))
-+ return -EHOSTUNREACH;
-+
-+ hci_dev_lock_bh(hdev);
-+
-+ err = -ENOMEM;
-+
-+ hcon = hci_connect(hdev, SCO_LINK, dst);
-+ if (!hcon)
-+ goto done;
-+
-+ conn = sco_conn_add(hcon, 0);
-+ if (!conn) {
-+ hci_conn_put(hcon);
-+ goto done;
-+ }
-+
-+ /* Update source addr of the socket */
-+ bacpy(src, conn->src);
-+
-+ err = sco_chan_add(conn, sk, NULL);
-+ if (err)
-+ goto done;
-+
-+ if (hcon->state == BT_CONNECTED) {
-+ sco_sock_clear_timer(sk);
-+ sk->state = BT_CONNECTED;
-+ } else {
-+ sk->state = BT_CONNECT;
-+ sco_sock_set_timer(sk, sk->sndtimeo);
-+ }
-+done:
-+ hci_dev_unlock_bh(hdev);
-+ hci_dev_put(hdev);
-+ return err;
-+}
-+
-+static inline int sco_send_frame(struct sock *sk, struct msghdr *msg, int len)
-+{
-+ struct sco_conn *conn = sco_pi(sk)->conn;
-+ struct sk_buff *skb;
-+ int err, count;
-+
-+ /* Check outgoing MTU */
-+ if (len > conn->mtu)
-+ return -EINVAL;
-+
-+ BT_DBG("sk %p len %d", sk, len);
-+
-+ count = MIN(conn->mtu, len);
-+ if (!(skb = bluez_skb_send_alloc(sk, count, msg->msg_flags & MSG_DONTWAIT, &err)))
-+ return err;
-+
-+ if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
-+ err = -EFAULT;
-+ goto fail;
-+ }
-+
-+ if ((err = hci_send_sco(conn->hcon, skb)) < 0)
-+ goto fail;
-+
-+ return count;
-+
-+fail:
-+ kfree_skb(skb);
-+ return err;
-+}
-+
-+static inline void sco_recv_frame(struct sco_conn *conn, struct sk_buff *skb)
-+{
-+ struct sock *sk = sco_chan_get(conn);
-+
-+ if (!sk)
-+ goto drop;
-+
-+ BT_DBG("sk %p len %d", sk, skb->len);
-+
-+ if (sk->state != BT_CONNECTED)
-+ goto drop;
-+
-+ if (!sock_queue_rcv_skb(sk, skb))
-+ return;
-+
-+drop:
-+ kfree_skb(skb);
-+ return;
-+}
-+
-+/* -------- Socket interface ---------- */
-+static struct sock *__sco_get_sock_by_addr(bdaddr_t *ba)
-+{
-+ struct sock *sk;
-+
-+ for (sk = sco_sk_list.head; sk; sk = sk->next) {
-+ if (!bacmp(&bluez_pi(sk)->src, ba))
-+ break;
-+ }
-+
-+ return sk;
-+}
-+
-+/* Find socket listening on source bdaddr.
-+ * Returns closest match.
-+ */
-+static struct sock *sco_get_sock_listen(bdaddr_t *src)
-+{
-+ struct sock *sk, *sk1 = NULL;
-+
-+ read_lock(&sco_sk_list.lock);
-+
-+ for (sk = sco_sk_list.head; sk; sk = sk->next) {
-+ if (sk->state != BT_LISTEN)
-+ continue;
-+
-+ /* Exact match. */
-+ if (!bacmp(&bluez_pi(sk)->src, src))
-+ break;
-+
-+ /* Closest match */
-+ if (!bacmp(&bluez_pi(sk)->src, BDADDR_ANY))
-+ sk1 = sk;
-+ }
-+
-+ read_unlock(&sco_sk_list.lock);
-+
-+ return sk ? sk : sk1;
-+}
-+
-+static void sco_sock_destruct(struct sock *sk)
-+{
-+ BT_DBG("sk %p", sk);
-+
-+ skb_queue_purge(&sk->receive_queue);
-+ skb_queue_purge(&sk->write_queue);
-+
-+ MOD_DEC_USE_COUNT;
-+}
-+
-+static void sco_sock_cleanup_listen(struct sock *parent)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("parent %p", parent);
-+
-+ /* Close not yet accepted channels */
-+ while ((sk = bluez_accept_dequeue(parent, NULL))) {
-+ sco_sock_close(sk);
-+ sco_sock_kill(sk);
-+ }
-+
-+ parent->state = BT_CLOSED;
-+ parent->zapped = 1;
-+}
-+
-+/* Kill socket (only if zapped and orphan)
-+ * Must be called on unlocked socket.
-+ */
-+static void sco_sock_kill(struct sock *sk)
-+{
-+ if (!sk->zapped || sk->socket)
-+ return;
-+
-+ BT_DBG("sk %p state %d", sk, sk->state);
-+
-+ /* Kill poor orphan */
-+ bluez_sock_unlink(&sco_sk_list, sk);
-+ sk->dead = 1;
-+ sock_put(sk);
-+}
-+
-+/* Close socket.
-+ * Must be called on unlocked socket.
-+ */
-+static void sco_sock_close(struct sock *sk)
-+{
-+ struct sco_conn *conn;
-+
-+ sco_sock_clear_timer(sk);
-+
-+ lock_sock(sk);
-+
-+ conn = sco_pi(sk)->conn;
-+
-+ BT_DBG("sk %p state %d conn %p socket %p", sk, sk->state, conn, sk->socket);
-+
-+ switch (sk->state) {
-+ case BT_LISTEN:
-+ sco_sock_cleanup_listen(sk);
-+ break;
-+
-+ case BT_CONNECTED:
-+ case BT_CONFIG:
-+ case BT_CONNECT:
-+ case BT_DISCONN:
-+ sco_chan_del(sk, ECONNRESET);
-+ break;
-+
-+ default:
-+ sk->zapped = 1;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+}
-+
-+static void sco_sock_init(struct sock *sk, struct sock *parent)
-+{
-+ BT_DBG("sk %p", sk);
-+
-+ if (parent)
-+ sk->type = parent->type;
-+}
-+
-+static struct sock *sco_sock_alloc(struct socket *sock, int proto, int prio)
-+{
-+ struct sock *sk;
-+
-+ if (!(sk = sk_alloc(PF_BLUETOOTH, prio, 1)))
-+ return NULL;
-+
-+ bluez_sock_init(sock, sk);
-+
-+ sk->zapped = 0;
-+
-+ sk->destruct = sco_sock_destruct;
-+ sk->sndtimeo = SCO_CONN_TIMEOUT;
-+
-+ sk->protocol = proto;
-+ sk->state = BT_OPEN;
-+
-+ sco_sock_init_timer(sk);
-+
-+ bluez_sock_link(&sco_sk_list, sk);
-+
-+ MOD_INC_USE_COUNT;
-+ return sk;
-+}
-+
-+static int sco_sock_create(struct socket *sock, int protocol)
-+{
-+ struct sock *sk;
-+
-+ BT_DBG("sock %p", sock);
-+
-+ sock->state = SS_UNCONNECTED;
-+
-+ if (sock->type != SOCK_SEQPACKET)
-+ return -ESOCKTNOSUPPORT;
-+
-+ sock->ops = &sco_sock_ops;
-+
-+ if (!(sk = sco_sock_alloc(sock, protocol, GFP_KERNEL)))
-+ return -ENOMEM;
-+
-+ sco_sock_init(sk, NULL);
-+ return 0;
-+}
-+
-+static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
-+{
-+ struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
-+ struct sock *sk = sock->sk;
-+ bdaddr_t *src = &sa->sco_bdaddr;
-+ int err = 0;
-+
-+ BT_DBG("sk %p %s", sk, batostr(&sa->sco_bdaddr));
-+
-+ if (!addr || addr->sa_family != AF_BLUETOOTH)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_OPEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ write_lock_bh(&sco_sk_list.lock);
-+
-+ if (bacmp(src, BDADDR_ANY) && __sco_get_sock_by_addr(src)) {
-+ err = -EADDRINUSE;
-+ } else {
-+ /* Save source address */
-+ bacpy(&bluez_pi(sk)->src, &sa->sco_bdaddr);
-+ sk->state = BT_BOUND;
-+ }
-+
-+ write_unlock_bh(&sco_sk_list.lock);
-+
-+done:
-+ release_sock(sk);
-+
-+ return err;
-+}
-+
-+static int sco_sock_connect(struct socket *sock, struct sockaddr *addr, int alen, int flags)
-+{
-+ struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (addr->sa_family != AF_BLUETOOTH || alen < sizeof(struct sockaddr_sco))
-+ return -EINVAL;
-+
-+ if (sk->state != BT_OPEN && sk->state != BT_BOUND)
-+ return -EBADFD;
-+
-+ if (sk->type != SOCK_SEQPACKET)
-+ return -EINVAL;
-+
-+ lock_sock(sk);
-+
-+ /* Set destination address and psm */
-+ bacpy(&bluez_pi(sk)->dst, &sa->sco_bdaddr);
-+
-+ if ((err = sco_connect(sk)))
-+ goto done;
-+
-+ err = bluez_sock_wait_state(sk, BT_CONNECTED,
-+ sock_sndtimeo(sk, flags & O_NONBLOCK));
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int sco_sock_listen(struct socket *sock, int backlog)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p backlog %d", sk, backlog);
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_BOUND || sock->type != SOCK_SEQPACKET) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ sk->max_ack_backlog = backlog;
-+ sk->ack_backlog = 0;
-+ sk->state = BT_LISTEN;
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int sco_sock_accept(struct socket *sock, struct socket *newsock, int flags)
-+{
-+ DECLARE_WAITQUEUE(wait, current);
-+ struct sock *sk = sock->sk, *ch;
-+ long timeo;
-+ int err = 0;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ goto done;
-+ }
-+
-+ timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
-+
-+ BT_DBG("sk %p timeo %ld", sk, timeo);
-+
-+ /* Wait for an incoming connection. (wake-one). */
-+ add_wait_queue_exclusive(sk->sleep, &wait);
-+ while (!(ch = bluez_accept_dequeue(sk, newsock))) {
-+ set_current_state(TASK_INTERRUPTIBLE);
-+ if (!timeo) {
-+ err = -EAGAIN;
-+ break;
-+ }
-+
-+ release_sock(sk);
-+ timeo = schedule_timeout(timeo);
-+ lock_sock(sk);
-+
-+ if (sk->state != BT_LISTEN) {
-+ err = -EBADFD;
-+ break;
-+ }
-+
-+ if (signal_pending(current)) {
-+ err = sock_intr_errno(timeo);
-+ break;
-+ }
-+ }
-+ set_current_state(TASK_RUNNING);
-+ remove_wait_queue(sk->sleep, &wait);
-+
-+ if (err)
-+ goto done;
-+
-+ newsock->state = SS_CONNECTED;
-+
-+ BT_DBG("new socket %p", ch);
-+
-+done:
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int sco_sock_getname(struct socket *sock, struct sockaddr *addr, int *len, int peer)
-+{
-+ struct sockaddr_sco *sa = (struct sockaddr_sco *) addr;
-+ struct sock *sk = sock->sk;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ addr->sa_family = AF_BLUETOOTH;
-+ *len = sizeof(struct sockaddr_sco);
-+
-+ if (peer)
-+ bacpy(&sa->sco_bdaddr, &bluez_pi(sk)->dst);
-+ else
-+ bacpy(&sa->sco_bdaddr, &bluez_pi(sk)->src);
-+
-+ return 0;
-+}
-+
-+static int sco_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (sk->err)
-+ return sock_error(sk);
-+
-+ if (msg->msg_flags & MSG_OOB)
-+ return -EOPNOTSUPP;
-+
-+ lock_sock(sk);
-+
-+ if (sk->state == BT_CONNECTED)
-+ err = sco_send_frame(sk, msg, len);
-+ else
-+ err = -ENOTCONN;
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int sco_sock_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+int sco_sock_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen)
-+{
-+ struct sock *sk = sock->sk;
-+ struct sco_options opts;
-+ struct sco_conninfo cinfo;
-+ int len, err = 0;
-+
-+ BT_DBG("sk %p", sk);
-+
-+ if (get_user(len, optlen))
-+ return -EFAULT;
-+
-+ lock_sock(sk);
-+
-+ switch (optname) {
-+ case SCO_OPTIONS:
-+ if (sk->state != BT_CONNECTED) {
-+ err = -ENOTCONN;
-+ break;
-+ }
-+
-+ opts.mtu = sco_pi(sk)->conn->mtu;
-+
-+ BT_DBG("mtu %d", opts.mtu);
-+
-+ len = MIN(len, sizeof(opts));
-+ if (copy_to_user(optval, (char *)&opts, len))
-+ err = -EFAULT;
-+
-+ break;
-+
-+ case SCO_CONNINFO:
-+ if (sk->state != BT_CONNECTED) {
-+ err = -ENOTCONN;
-+ break;
-+ }
-+
-+ cinfo.hci_handle = sco_pi(sk)->conn->hcon->handle;
-+
-+ len = MIN(len, sizeof(cinfo));
-+ if (copy_to_user(optval, (char *)&cinfo, len))
-+ err = -EFAULT;
-+
-+ break;
-+
-+ default:
-+ err = -ENOPROTOOPT;
-+ break;
-+ };
-+
-+ release_sock(sk);
-+ return err;
-+}
-+
-+static int sco_sock_release(struct socket *sock)
-+{
-+ struct sock *sk = sock->sk;
-+ int err = 0;
-+
-+ BT_DBG("sock %p, sk %p", sock, sk);
-+
-+ if (!sk)
-+ return 0;
-+
-+ sco_sock_close(sk);
-+ if (sk->linger) {
-+ lock_sock(sk);
-+ err = bluez_sock_wait_state(sk, BT_CLOSED, sk->lingertime);
-+ release_sock(sk);
-+ }
-+
-+ sock_orphan(sk);
-+ sco_sock_kill(sk);
-+ return err;
-+}
-+
-+static void __sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
-+{
-+ BT_DBG("conn %p", conn);
-+
-+ sco_pi(sk)->conn = conn;
-+ conn->sk = sk;
-+
-+ if (parent)
-+ bluez_accept_enqueue(parent, sk);
-+}
-+
-+static inline int sco_chan_add(struct sco_conn *conn, struct sock *sk, struct sock *parent)
-+{
-+ int err = 0;
-+
-+ sco_conn_lock(conn);
-+ if (conn->sk) {
-+ err = -EBUSY;
-+ } else {
-+ __sco_chan_add(conn, sk, parent);
-+ }
-+ sco_conn_unlock(conn);
-+ return err;
-+}
-+
-+static inline struct sock * sco_chan_get(struct sco_conn *conn)
-+{
-+ struct sock *sk = NULL;
-+ sco_conn_lock(conn);
-+ sk = conn->sk;
-+ sco_conn_unlock(conn);
-+ return sk;
-+}
-+
-+/* Delete channel.
-+ * Must be called on the locked socket. */
-+static void sco_chan_del(struct sock *sk, int err)
-+{
-+ struct sco_conn *conn;
-+
-+ conn = sco_pi(sk)->conn;
-+
-+ BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
-+
-+ if (conn) {
-+ sco_conn_lock(conn);
-+ conn->sk = NULL;
-+ sco_pi(sk)->conn = NULL;
-+ sco_conn_unlock(conn);
-+ hci_conn_put(conn->hcon);
-+ }
-+
-+ sk->state = BT_CLOSED;
-+ sk->err = err;
-+ sk->state_change(sk);
-+
-+ sk->zapped = 1;
-+}
-+
-+static void sco_conn_ready(struct sco_conn *conn)
-+{
-+ struct sock *parent, *sk;
-+
-+ BT_DBG("conn %p", conn);
-+
-+ sco_conn_lock(conn);
-+
-+ if ((sk = conn->sk)) {
-+ sco_sock_clear_timer(sk);
-+ bh_lock_sock(sk);
-+ sk->state = BT_CONNECTED;
-+ sk->state_change(sk);
-+ bh_unlock_sock(sk);
-+ } else {
-+ parent = sco_get_sock_listen(conn->src);
-+ if (!parent)
-+ goto done;
-+
-+ bh_lock_sock(parent);
-+
-+ sk = sco_sock_alloc(NULL, BTPROTO_SCO, GFP_ATOMIC);
-+ if (!sk) {
-+ bh_unlock_sock(parent);
-+ goto done;
-+ }
-+
-+ sco_sock_init(sk, parent);
-+
-+ bacpy(&bluez_pi(sk)->src, conn->src);
-+ bacpy(&bluez_pi(sk)->dst, conn->dst);
-+
-+ hci_conn_hold(conn->hcon);
-+ __sco_chan_add(conn, sk, parent);
-+
-+ sk->state = BT_CONNECTED;
-+
-+ /* Wake up parent */
-+ parent->data_ready(parent, 1);
-+
-+ bh_unlock_sock(parent);
-+ }
-+
-+done:
-+ sco_conn_unlock(conn);
-+}
-+
-+/* ----- SCO interface with lower layer (HCI) ----- */
-+int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type)
-+{
-+ BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
-+
-+ /* Always accept connection */
-+ return HCI_LM_ACCEPT;
-+}
-+
-+int sco_connect_cfm(struct hci_conn *hcon, __u8 status)
-+{
-+ BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
-+
-+ if (hcon->type != SCO_LINK)
-+ return 0;
-+
-+ if (!status) {
-+ struct sco_conn *conn;
-+
-+ conn = sco_conn_add(hcon, status);
-+ if (conn)
-+ sco_conn_ready(conn);
-+ } else
-+ sco_conn_del(hcon, bterr(status));
-+
-+ return 0;
-+}
-+
-+int sco_disconn_ind(struct hci_conn *hcon, __u8 reason)
-+{
-+ BT_DBG("hcon %p reason %d", hcon, reason);
-+
-+ if (hcon->type != SCO_LINK)
-+ return 0;
-+
-+ sco_conn_del(hcon, bterr(reason));
-+ return 0;
-+}
-+
-+int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb)
-+{
-+ struct sco_conn *conn = hcon->sco_data;
-+
-+ if (!conn)
-+ goto drop;
-+
-+ BT_DBG("conn %p len %d", conn, skb->len);
-+
-+ if (skb->len) {
-+ sco_recv_frame(conn, skb);
-+ return 0;
-+ }
-+
-+drop:
-+ kfree_skb(skb);
-+ return 0;
-+}
-+
-+/* ----- Proc fs support ------ */
-+static int sco_sock_dump(char *buf, struct bluez_sock_list *list)
-+{
-+ struct sco_pinfo *pi;
-+ struct sock *sk;
-+ char *ptr = buf;
-+
-+ write_lock_bh(&list->lock);
-+
-+ for (sk = list->head; sk; sk = sk->next) {
-+ pi = sco_pi(sk);
-+ ptr += sprintf(ptr, "%s %s %d\n",
-+ batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
-+ sk->state);
-+ }
-+
-+ write_unlock_bh(&list->lock);
-+
-+ ptr += sprintf(ptr, "\n");
-+
-+ return ptr - buf;
-+}
-+
-+static int sco_read_proc(char *buf, char **start, off_t offset, int count, int *eof, void *priv)
-+{
-+ char *ptr = buf;
-+ int len;
-+
-+ BT_DBG("count %d, offset %ld", count, offset);
-+
-+ ptr += sco_sock_dump(ptr, &sco_sk_list);
-+ len = ptr - buf;
-+
-+ if (len <= count + offset)
-+ *eof = 1;
-+
-+ *start = buf + offset;
-+ len -= offset;
-+
-+ if (len > count)
-+ len = count;
-+ if (len < 0)
-+ len = 0;
-+
-+ return len;
-+}
-+
-+static struct proto_ops sco_sock_ops = {
-+ family: PF_BLUETOOTH,
-+ release: sco_sock_release,
-+ bind: sco_sock_bind,
-+ connect: sco_sock_connect,
-+ listen: sco_sock_listen,
-+ accept: sco_sock_accept,
-+ getname: sco_sock_getname,
-+ sendmsg: sco_sock_sendmsg,
-+ recvmsg: bluez_sock_recvmsg,
-+ poll: bluez_sock_poll,
-+ socketpair: sock_no_socketpair,
-+ ioctl: sock_no_ioctl,
-+ shutdown: sock_no_shutdown,
-+ setsockopt: sco_sock_setsockopt,
-+ getsockopt: sco_sock_getsockopt,
-+ mmap: sock_no_mmap
-+};
-+
-+static struct net_proto_family sco_sock_family_ops = {
-+ family: PF_BLUETOOTH,
-+ create: sco_sock_create
-+};
-+
-+static struct hci_proto sco_hci_proto = {
-+ name: "SCO",
-+ id: HCI_PROTO_SCO,
-+ connect_ind: sco_connect_ind,
-+ connect_cfm: sco_connect_cfm,
-+ disconn_ind: sco_disconn_ind,
-+ recv_scodata: sco_recv_scodata,
-+};
-+
-+int __init sco_init(void)
-+{
-+ int err;
-+
-+ if ((err = bluez_sock_register(BTPROTO_SCO, &sco_sock_family_ops))) {
-+ BT_ERR("Can't register SCO socket layer");
-+ return err;
-+ }
-+
-+ if ((err = hci_register_proto(&sco_hci_proto))) {
-+ BT_ERR("Can't register SCO protocol");
-+ return err;
-+ }
-+
-+ create_proc_read_entry("bluetooth/sco", 0, 0, sco_read_proc, NULL);
-+
-+ BT_INFO("BlueZ SCO ver %s Copyright (C) 2000,2001 Qualcomm Inc", VERSION);
-+ BT_INFO("Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>");
-+ return 0;
-+}
-+
-+void sco_cleanup(void)
-+{
-+ int err;
-+
-+ remove_proc_entry("bluetooth/sco", NULL);
-+
-+ /* Unregister socket, protocol and notifier */
-+ if ((err = bluez_sock_unregister(BTPROTO_SCO)))
-+ BT_ERR("Can't unregister SCO socket layer %d", err);
-+
-+ if ((err = hci_unregister_proto(&sco_hci_proto)))
-+ BT_ERR("Can't unregister SCO protocol %d", err);
-+}
-+
-+module_init(sco_init);
-+module_exit(sco_cleanup);
-+
-+MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
-+MODULE_DESCRIPTION("BlueZ SCO ver " VERSION);
-+MODULE_LICENSE("GPL");
-diff -urN linux-2.4.18/net/bluetooth/syms.c linux-2.4.18-mh9/net/bluetooth/syms.c
---- linux-2.4.18/net/bluetooth/syms.c Fri Sep 7 18:28:38 2001
-+++ linux-2.4.18-mh9/net/bluetooth/syms.c Mon Aug 25 18:38:12 2003
-@@ -25,7 +25,7 @@
- /*
- * BlueZ symbols.
- *
-- * $Id$
-+ * $Id$
- */
-
- #include <linux/config.h>
-@@ -39,25 +39,28 @@
- #include <linux/socket.h>
-
- #include <net/bluetooth/bluetooth.h>
--#include <net/bluetooth/bluez.h>
- #include <net/bluetooth/hci_core.h>
-
- /* HCI Core */
- EXPORT_SYMBOL(hci_register_dev);
- EXPORT_SYMBOL(hci_unregister_dev);
-+EXPORT_SYMBOL(hci_suspend_dev);
-+EXPORT_SYMBOL(hci_resume_dev);
-+
- EXPORT_SYMBOL(hci_register_proto);
- EXPORT_SYMBOL(hci_unregister_proto);
--EXPORT_SYMBOL(hci_register_notifier);
--EXPORT_SYMBOL(hci_unregister_notifier);
-
-+EXPORT_SYMBOL(hci_get_route);
- EXPORT_SYMBOL(hci_connect);
--EXPORT_SYMBOL(hci_disconnect);
- EXPORT_SYMBOL(hci_dev_get);
-+EXPORT_SYMBOL(hci_conn_auth);
-+EXPORT_SYMBOL(hci_conn_encrypt);
-
- EXPORT_SYMBOL(hci_recv_frame);
- EXPORT_SYMBOL(hci_send_acl);
- EXPORT_SYMBOL(hci_send_sco);
--EXPORT_SYMBOL(hci_send_raw);
-+EXPORT_SYMBOL(hci_send_cmd);
-+EXPORT_SYMBOL(hci_si_event);
-
- /* BlueZ lib */
- EXPORT_SYMBOL(bluez_dump);
-@@ -68,5 +71,11 @@
- /* BlueZ sockets */
- EXPORT_SYMBOL(bluez_sock_register);
- EXPORT_SYMBOL(bluez_sock_unregister);
-+EXPORT_SYMBOL(bluez_sock_init);
- EXPORT_SYMBOL(bluez_sock_link);
- EXPORT_SYMBOL(bluez_sock_unlink);
-+EXPORT_SYMBOL(bluez_sock_recvmsg);
-+EXPORT_SYMBOL(bluez_sock_poll);
-+EXPORT_SYMBOL(bluez_accept_enqueue);
-+EXPORT_SYMBOL(bluez_accept_dequeue);
-+EXPORT_SYMBOL(bluez_sock_wait_state);
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/cacko.patch b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/cacko.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/cacko.patch
+++ /dev/null
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/defconfig-collie b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/defconfig-collie
deleted file mode 100644
index 531c7385e3..0000000000
--- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/defconfig-collie
+++ /dev/null
@@ -1,1283 +0,0 @@
-#
-# Automatically generated make config: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-CONFIG_KMOD=y
-
-#
-# System Type
-#
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_MX1ADS is not set
-# CONFIG_ARCH_RPC is not set
-CONFIG_ARCH_SA1100=y
-# CONFIG_ARCH_SHARK is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-
-#
-# Archimedes/A5000 Implementations (select only ONE)
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CEP is not set
-# CONFIG_SA1100_CERF is not set
-CONFIG_SA1100_COLLIE=y
-CONFIG_LOCOMO=y
-# CONFIG_COLLIE_TS is not set
-# CONFIG_COLLIE_TR0 is not set
-# CONFIG_COLLIE_TR1 is not set
-# CONFIG_COLLIE_DEV is not set
-# CONFIG_COLLIE_G is not set
-CONFIG_COLLIE_UP=y
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_H3XXX is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_FRODO is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_USB is not set
-# CONFIG_SA1100_USB_NETLINK is not set
-# CONFIG_SA1100_USB_CHAR is not set
-# CONFIG_H3600_SLEEVE is not set
-
-#
-# Intel PXA250/210 Implementations
-#
-# CONFIG_ARCH_LUBBOCK is not set
-# CONFIG_ARCH_PXA_IDP is not set
-# CONFIG_ARCH_PXA_CERF is not set
-# CONFIG_COTULLA_DMA is not set
-# CONFIG_SABINAL_DISCOVERY is not set
-# CONFIG_ARCH_SABINAL is not set
-# CONFIG_ARCH_PXA_POODLE is not set
-# CONFIG_POODLE_TR0 is not set
-# CONFIG_ARCH_PXA_CORGI is not set
-# CONFIG_CORGI_TR0 is not set
-CONFIG_ARCH_SHARP_SL=y
-# CONFIG_PXA_USB is not set
-# CONFIG_PXA_USB_NETLINK is not set
-# CONFIG_PXA_USB_CHAR is not set
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_FORTUNET is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-
-#
-# Processor Type
-#
-# CONFIG_CPU_32v3 is not set
-CONFIG_CPU_32v4=y
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM922T is not set
-# CONFIG_PLD is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_SA110 is not set
-CONFIG_CPU_SA1100=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_DISCONTIGMEM=y
-
-#
-# General setup
-#
-# CONFIG_PCI is not set
-CONFIG_ISA=y
-# CONFIG_ISA_DMA is not set
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-# CONFIG_CPU_FREQ is not set
-CONFIG_HOTPLUG=y
-
-#
-# PCMCIA/CardBus support
-#
-CONFIG_PCMCIA=y
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-# CONFIG_TCIC is not set
-# CONFIG_PCMCIA_CLPS6700 is not set
-CONFIG_PCMCIA_SA1100=y
-# CONFIG_PCMCIA_PXA is not set
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-
-#
-# At least one math emulation must be selected
-#
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_PM=y
-CONFIG_APM=y
-# CONFIG_APM_IGNORE_USER_SUSPEND is not set
-CONFIG_APM_CPU_IDLE=y
-CONFIG_APM_DISPLAY_BLANK=y
-CONFIG_APM_RTC_IS_GMT=y
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="See OE File"
-# CONFIG_SHARPSL_BOOTLDR_PARAMS is not set
-# CONFIG_LEDS is not set
-CONFIG_ALIGNMENT_TRAP=y
-CONFIG_FREEPG_SIGNAL=y
-CONFIG_OOM_KILL_SURVIVAL=y
-CONFIG_DEVICEINFO=m
-CONFIG_COLLIE_DEVICEINFO=m
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_CACKO_HYBRID_PARTITIONS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-# CONFIG_MTD_AFS_PARTS is not set
-
-#
-# User Modules And Translation Layers
-#
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-# CONFIG_MTD_CFI is not set
-# CONFIG_MTD_JEDECPROBE is not set
-# CONFIG_MTD_GEN_PROBE is not set
-# CONFIG_MTD_CFI_INTELEXT is not set
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-CONFIG_MTD_COLLIE=y
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_LUBBOCK is not set
-# CONFIG_MTD_NORA is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-CONFIG_MTD_SA1100=y
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_FORTUNET is not set
-# CONFIG_MTD_PXA_CERF is not set
-# CONFIG_MTD_EPXA10DB is not set
-# CONFIG_MTD_AUTCPU12 is not set
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_DISCOVERY is not set
-# CONFIG_MTD_SHARP_SL is not set
-# CONFIG_MTD_PCI is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDROM_SA1100 is not set
-CONFIG_MTD_MTDRAM_SA1100=y
-CONFIG_MTDRAM_TOTAL_SIZE=16384
-CONFIG_MTDRAM_ERASE_SIZE=1
-CONFIG_MTDRAM_ABS_POS=C1000000
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_MTDRAM_SHARP_SL is not set
-# CONFIG_MTD_BLKMTD is not set
-
-#
-# Disk-On-Chip Device Drivers
-#
-# CONFIG_MTD_DOC1000 is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-CONFIG_PACKET_MMAP=y
-CONFIG_NETLINK_DEV=y
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_IP_MULTICAST is not set
-# CONFIG_IP_ADVANCED_ROUTER is not set
-# CONFIG_IP_PNP is not set
-CONFIG_NET_IPIP=m
-CONFIG_NET_IPGRE=m
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-
-#
-# IP: Netfilter Configuration
-#
-CONFIG_IP_NF_CONNTRACK=m
-CONFIG_IP_NF_FTP=m
-CONFIG_IP_NF_IRC=m
-CONFIG_IP_NF_QUEUE=m
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_LIMIT=m
-CONFIG_IP_NF_MATCH_MAC=m
-CONFIG_IP_NF_MATCH_MARK=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
-CONFIG_IP_NF_MATCH_TOS=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
-CONFIG_IP_NF_MATCH_LENGTH=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_MATCH_TCPMSS=m
-CONFIG_IP_NF_MATCH_STATE=m
-CONFIG_IP_NF_MATCH_UNCLEAN=m
-CONFIG_IP_NF_MATCH_OWNER=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_TARGET_MIRROR=m
-CONFIG_IP_NF_NAT=m
-CONFIG_IP_NF_NAT_NEEDED=y
-CONFIG_IP_NF_TARGET_MASQUERADE=m
-CONFIG_IP_NF_TARGET_REDIRECT=m
-CONFIG_IP_NF_NAT_SNMP_BASIC=m
-CONFIG_IP_NF_NAT_IRC=m
-CONFIG_IP_NF_NAT_FTP=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_TOS=m
-CONFIG_IP_NF_TARGET_MARK=m
-CONFIG_IP_NF_TARGET_LOG=m
-CONFIG_IP_NF_TARGET_ULOG=m
-CONFIG_IP_NF_TARGET_TCPMSS=m
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-CONFIG_IPV6=m
-
-#
-# IPv6: Netfilter Configuration
-#
-CONFIG_IP6_NF_QUEUE=m
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_LIMIT=m
-CONFIG_IP6_NF_MATCH_MAC=m
-CONFIG_IP6_NF_MATCH_MULTIPORT=m
-CONFIG_IP6_NF_MATCH_OWNER=m
-CONFIG_IP6_NF_MATCH_MARK=m
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_LOG=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_TARGET_MARK=m
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-
-#
-#
-#
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-CONFIG_IPSEC=m
-
-#
-# IPSec options (Openswan)
-#
-CONFIG_IPSEC_IPIP=y
-CONFIG_IPSEC_AH=y
-# CONFIG_IPSEC_AUTH_HMAC_MD5 is not set
-CONFIG_IPSEC_AUTH_HMAC_SHA1=y
-CONFIG_IPSEC_ESP=y
-CONFIG_IPSEC_ENC_3DES=y
-# CONFIG_IPSEC_ENC_AES is not set
-CONFIG_IPSEC_ALG=y
-CONFIG_IPSEC_IPCOMP=y
-CONFIG_IPSEC_DEBUG=y
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-CONFIG_DUMMY=m
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-CONFIG_TUN=m
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_ARM_AM79C961A is not set
-# CONFIG_SUNLANCE is not set
-# CONFIG_SUNBMAC is not set
-# CONFIG_SUNQE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_PCI is not set
-# CONFIG_NET_POCKET is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-CONFIG_PPP=y
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_FILTER is not set
-CONFIG_PPP_ASYNC=y
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
-CONFIG_PPP_BSDCOMP=y
-# CONFIG_PPPOE is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-CONFIG_NET_RADIO=y
-# CONFIG_STRIP is not set
-# CONFIG_WAVELAN is not set
-# CONFIG_ARLAN is not set
-# CONFIG_AIRONET4500 is not set
-# CONFIG_AIRONET4500_NONCS is not set
-# CONFIG_AIRONET4500_PROC is not set
-# CONFIG_AIRO is not set
-# CONFIG_HERMES is not set
-
-#
-# Wireless Pcmcia cards support
-#
-# CONFIG_PCMCIA_HERMES is not set
-# CONFIG_AIRO_CS is not set
-CONFIG_NET_WIRELESS=y
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# PCMCIA network device support
-#
-CONFIG_NET_PCMCIA=y
-CONFIG_PCMCIA_3C589=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_FMVJ18X=m
-CONFIG_PCMCIA_PCNET=y
-CONFIG_PCMCIA_AXNET=m
-CONFIG_PCMCIA_NMCLAN=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-# CONFIG_ARCNET_COM20020_CS is not set
-# CONFIG_PCMCIA_IBMTR is not set
-CONFIG_NET_PCMCIA_RADIO=y
-# CONFIG_PCMCIA_RAYCS is not set
-# CONFIG_PCMCIA_NETWAVE is not set
-# CONFIG_PCMCIA_WAVELAN is not set
-# CONFIG_AIRONET4500_CS is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-CONFIG_IRDA=y
-
-#
-# IrDA protocols
-#
-# CONFIG_IRLAN is not set
-CONFIG_IRNET=m
-CONFIG_IRCOMM=y
-# CONFIG_IRDA_ULTRA is not set
-
-#
-# IrDA options
-#
-# CONFIG_IRDA_CACHE_LAST_LSAP is not set
-CONFIG_IRDA_FAST_RR=y
-# CONFIG_IRDA_DEBUG is not set
-
-#
-# Infrared-port device drivers
-#
-
-#
-# SIR device drivers
-#
-CONFIG_IRTTY_SIR=y
-CONFIG_IRPORT_SIR=y
-
-#
-# Dongle support
-#
-# CONFIG_DONGLE is not set
-
-#
-# FIR device drivers
-#
-# CONFIG_USB_IRDA is not set
-# CONFIG_NSC_FIR is not set
-# CONFIG_WINBOND_FIR is not set
-# CONFIG_TOSHIBA_FIR is not set
-# CONFIG_SMC_IRCC_FIR is not set
-# CONFIG_ALI_FIR is not set
-# CONFIG_VLSI_FIR is not set
-CONFIG_SA1100_FIR=y
-
-#
-# ATA/IDE/MFM/RLL support
-#
-CONFIG_IDE=y
-
-#
-# IDE, ATA and ATAPI Block devices
-#
-CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
-# CONFIG_BLK_DEV_HD_IDE is not set
-# CONFIG_BLK_DEV_HD is not set
-CONFIG_BLK_DEV_IDEDISK=y
-# CONFIG_IDEDISK_MULTI_MODE is not set
-# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
-# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
-# CONFIG_BLK_DEV_IDEDISK_IBM is not set
-# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
-# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
-# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
-# CONFIG_BLK_DEV_IDEDISK_WD is not set
-# CONFIG_BLK_DEV_COMMERIAL is not set
-# CONFIG_BLK_DEV_TIVO is not set
-CONFIG_BLK_DEV_IDECS=y
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
-# CONFIG_BLK_DEV_IDESCSI is not set
-
-#
-# IDE chipset support/bugfixes
-#
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
-# CONFIG_BLK_DEV_ISAPNP is not set
-# CONFIG_IDE_CHIPSETS is not set
-# CONFIG_IDEDMA_AUTO is not set
-# CONFIG_DMA_NONPCI is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_ATARAID is not set
-# CONFIG_BLK_DEV_ATARAID_PDC is not set
-# CONFIG_BLK_DEV_ATARAID_HPT is not set
-
-#
-# SCSI support
-#
-# CONFIG_SCSI is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_UINPUT is not set
-
-#
-# Character devices
-#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
-CONFIG_SERIAL_COLLIE=y
-# CONFIG_SERIAL_COLLIE_CONSOLE is not set
-CONFIG_COLLIE_DEFAULT_BAUDRATE=9600
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-
-#
-# Serial drivers
-#
-# CONFIG_SERIAL_ANAKIN is not set
-# CONFIG_SERIAL_ANAKIN_CONSOLE is not set
-# CONFIG_SERIAL_AMBA is not set
-# CONFIG_SERIAL_AMBA_CONSOLE is not set
-# CONFIG_SERIAL_CLPS711X is not set
-# CONFIG_SERIAL_CLPS711X_CONSOLE is not set
-# CONFIG_SERIAL_21285 is not set
-# CONFIG_SERIAL_21285_OLD is not set
-# CONFIG_SERIAL_21285_CONSOLE is not set
-# CONFIG_SERIAL_UART00 is not set
-# CONFIG_SERIAL_UART00_CONSOLE is not set
-# CONFIG_SERIAL_SA1100 is not set
-# CONFIG_SERIAL_SA1100_CONSOLE is not set
-# CONFIG_SERIAL_8250 is not set
-# CONFIG_SERIAL_8250_CONSOLE is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_MANY_PORTS is not set
-# CONFIG_SERIAL_8250_SHARE_IRQ is not set
-# CONFIG_SERIAL_8250_DETECT_IRQ is not set
-# CONFIG_SERIAL_8250_MULTIPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_UCB1200=y
-CONFIG_TOUCHSCREEN_UCB1200=y
-# CONFIG_AUDIO_UCB1200 is not set
-# CONFIG_ADC_UCB1200 is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=32
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# L3 serial bus support
-#
-# CONFIG_L3 is not set
-# CONFIG_L3_ALGOBIT is not set
-# CONFIG_L3_BIT_SA1100_GPIO is not set
-
-#
-# Other L3 adapters
-#
-# CONFIG_L3_SA1111 is not set
-# CONFIG_BIT_SA1100_GPIO is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-
-#
-# Input core support is needed for gameports
-#
-
-#
-# Input core support is needed for joysticks
-#
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_INTEL_RNG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_SA1100_RTC=y
-# CONFIG_COTULLA_RTC is not set
-# CONFIG_ADS7846_TS is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# PCMCIA character devices
-#
-CONFIG_PCMCIA_SERIAL_CS=y
-CONFIG_PCMCIA_CHRDEV=y
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# File systems
-#
-# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_FS_SYNC is not set
-CONFIG_REISERFS_FS=m
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=m
-CONFIG_JBD=m
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=y
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=y
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_NAND is not set
-# CONFIG_JFFS2_PROC_FS is not set
-# CONFIG_JFFS2_NODEMERGE is not set
-# CONFIG_JFFS2_DYNFRAGTREE is not set
-CONFIG_CRAMFS=y
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-CONFIG_MINIX_FS=y
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-# CONFIG_ROOT_NFS is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-CONFIG_SUNRPC=y
-CONFIG_LOCKD=y
-CONFIG_LOCKD_V4=y
-CONFIG_SMB_FS=y
-CONFIG_SMB_NLS_DEFAULT=y
-CONFIG_SMB_NLS_REMOTE="UTF8"
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-CONFIG_ZLIB_FS_INFLATE=y
-
-#
-# Partition Types
-#
-# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="UFT8"
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=y
-
-#
-# Console drivers
-#
-CONFIG_PC_KEYMAP=y
-# CONFIG_VGA_CONSOLE is not set
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FB_COLLIE=y
-# CONFIG_FB_ACORN is not set
-# CONFIG_FB_ANAKIN is not set
-# CONFIG_FB_CLPS711X is not set
-# CONFIG_FB_SA1100 is not set
-# CONFIG_FB_PXA is not set
-# CONFIG_FB_COTULLA is not set
-# CONFIG_FB_POODLE is not set
-# CONFIG_FB_CORGI is not set
-# CONFIG_SHARP_LOGO_SCREEN is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_VIRTUAL is not set
-CONFIG_FBCON_ADVANCED=y
-# CONFIG_FBCON_MFB is not set
-# CONFIG_FBCON_CFB2 is not set
-# CONFIG_FBCON_CFB4 is not set
-# CONFIG_FBCON_CFB8 is not set
-CONFIG_FBCON_CFB16=y
-# CONFIG_FBCON_CFB24 is not set
-# CONFIG_FBCON_CFB32 is not set
-# CONFIG_FBCON_AFB is not set
-# CONFIG_FBCON_ILBM is not set
-# CONFIG_FBCON_IPLAN2P2 is not set
-# CONFIG_FBCON_IPLAN2P4 is not set
-# CONFIG_FBCON_IPLAN2P8 is not set
-# CONFIG_FBCON_MAC is not set
-# CONFIG_FBCON_VGA_PLANES is not set
-# CONFIG_FBCON_VGA is not set
-# CONFIG_FBCON_HGA is not set
-CONFIG_FBCON_ROTATE_R=y
-# CONFIG_FBCON_ROTATE_L is not set
-# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-CONFIG_FBCON_FONTS=y
-# CONFIG_FONT_8x8 is not set
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_SUN12x22 is not set
-# CONFIG_FONT_6x11 is not set
-# CONFIG_FONT_5x8 is not set
-CONFIG_FONT_4x6=y
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# Sound
-#
-CONFIG_SOUND=y
-# CONFIG_SOUND_BT878 is not set
-CONFIG_SOUND_COLLIE_SSP=y
-CONFIG_COLLIE_PCM1741=y
-# CONFIG_COLLIE_PCM1717 is not set
-CONFIG_SOUND_COLLIE_TC35143=y
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_MIDI_EMU10K1 is not set
-# CONFIG_SOUND_FUSION is not set
-# CONFIG_SOUND_CS4281 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_MAESTRO3 is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_RME96XX is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_MIDI_VIA82CXXX is not set
-# CONFIG_SOUND_SA1100 is not set
-# CONFIG_SOUND_UDA1341 is not set
-# CONFIG_SOUND_ASSABET_UDA1341 is not set
-# CONFIG_SOUND_H3600_UDA1341 is not set
-# CONFIG_SOUND_PANGOLIN_UDA1341 is not set
-# CONFIG_SOUND_SA1111_UDA1341 is not set
-# CONFIG_SOUND_SA1100SSP is not set
-# CONFIG_SOUND_OSS is not set
-# CONFIG_SOUND_WAVEARTIST is not set
-# CONFIG_SOUND_PXA_AC97 is not set
-# CONFIG_SOUND_POODLE is not set
-# CONFIG_SOUND_CORGI is not set
-# CONFIG_SOUND_TVMIXER is not set
-
-#
-# Multimedia Capabilities Port drivers
-#
-# CONFIG_MCP is not set
-# CONFIG_MCP_SA1100 is not set
-# CONFIG_MCP_UCB1200 is not set
-# CONFIG_MCP_UCB1200_AUDIO is not set
-# CONFIG_MCP_UCB1200_TS is not set
-# CONFIG_MCP_UCB1400_TS is not set
-
-#
-# USB support
-#
-CONFIG_USB=m
-# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
-# CONFIG_USB_LONG_TIMEOUT is not set
-
-#
-# USB Controllers
-#
-# CONFIG_USB_UHCI is not set
-# CONFIG_USB_UHCI_ALT is not set
-# CONFIG_USB_OHCI is not set
-# CONFIG_USB_OHCI_SA1111 is not set
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_AUDIO is not set
-
-#
-# USB Bluetooth can only be used with disabled Bluetooth subsystem
-#
-
-#
-# SCSI support is needed for USB Storage
-#
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-
-#
-# USB Human Interface Devices (HID)
-#
-
-#
-# Input core support is needed for USB HID
-#
-
-#
-# USB Imaging devices
-#
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network adaptors
-#
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDCETHER is not set
-# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_GENERIC is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XA is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA28XB is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set
-# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-
-#
-# USB Miscellaneous drivers
-#
-# CONFIG_USB_RIO500 is not set
-
-#
-# USB Device Support
-#
-CONFIG_USBD=m
-CONFIG_USBD_VENDORID=4dd
-CONFIG_USBD_PRODUCTID=8002
-CONFIG_USBD_PRODUCT_NAME="SL Series"
-CONFIG_USBD_MANUFACTURER="Sharp"
-CONFIG_USBD_USE_SERIAL_NUMBER=y
-CONFIG_USBD_SERIAL_NUMBER_STR="A01234"
-CONFIG_USBD_SELFPOWERED=y
-CONFIG_USBD_MONITOR=m
-
-#
-#
-#
-CONFIG_USBD_PROCFS=y
-
-#
-# USB Device functions
-#
-
-#
-# Network Function
-#
-CONFIG_USBD_NET=m
-CONFIG_USBD_NET_VENDORID=4DD
-CONFIG_USBD_NET_PRODUCTID=8004
-CONFIG_USBD_NET_IFNAME="usbd"
-CONFIG_USBD_NET_OUT_ENDPOINT=1
-CONFIG_USBD_NET_OUT_PKTSIZE=64
-CONFIG_USBD_NET_IN_ENDPOINT=2
-CONFIG_USBD_NET_IN_PKTSIZE=64
-# CONFIG_USBD_NET_ALWAYSUP is not set
-# CONFIG_USBD_NET_SAFE is not set
-# CONFIG_USBD_NET_MDLM is not set
-CONFIG_USBD_NET_CDC=y
-CONFIG_USBD_NET_REMOTE_MACADDR="400002000001"
-CONFIG_USBD_NET_REMOTE_OUI=400002
-# CONFIG_USBD_MAC_AS_SERIAL_NUMBER is not set
-CONFIG_USBD_NET_LOCAL_MACADDR="400001000001"
-CONFIG_USBD_NET_LOCAL_OUI=400001
-
-#
-# Serial Function
-#
-CONFIG_USBD_SERIAL=m
-CONFIG_USBD_SERIAL_VENDORID=4dd
-CONFIG_USBD_SERIAL_PRODUCTID=8002
-# CONFIG_USBD_SERIAL_CDC is not set
-CONFIG_USBD_SERIAL_OUT_ENDPOINT=1
-CONFIG_USBD_SERIAL_IN_PKTSIZE=64
-CONFIG_USBD_SERIAL_IN_ENDPOINT=2
-CONFIG_USBD_SERIAL_OUT_PKTSIZE=64
-# CONFIG_USBD_SERIAL_SAFE is not set
-
-#
-# USB Device bus interfaces
-#
-
-#
-# USB Device Bus Interface Support
-#
-CONFIG_USBD_SA1100_BUS=m
-# CONFIG_USBD_TRAFFIC_KEEPAWAKE is not set
-CONFIG_USBD_STALL_TIMEOUT=0
-CONFIG_USBD_STALL_DISCONNECT_DURATION=2
-# CONFIG_USBD_GENERIC_BUS is not set
-
-#
-# Bluetooth support
-#
-CONFIG_BLUEZ=m
-CONFIG_BLUEZ_L2CAP=m
-CONFIG_BLUEZ_SCO=m
-CONFIG_BLUEZ_RFCOMM=m
-CONFIG_BLUEZ_RFCOMM_TTY=y
-CONFIG_BLUEZ_BNEP=m
-CONFIG_BLUEZ_BNEP_MC_FILTER=y
-CONFIG_BLUEZ_BNEP_PROTO_FILTER=y
-# CONFIG_BLUEZ_HIDP is not set
-
-#
-# Bluetooth device drivers
-#
-# CONFIG_BLUEZ_HCIUSB is not set
-CONFIG_BLUEZ_HCIUART=m
-CONFIG_BLUEZ_HCIUART_H4=y
-CONFIG_BLUEZ_HCIUART_BCSP=y
-CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y
-# CONFIG_BLUEZ_HCIBFUSB is not set
-CONFIG_BLUEZ_HCIDTL1=m
-CONFIG_BLUEZ_HCIBT3C=m
-CONFIG_BLUEZ_HCIBLUECARD=m
-CONFIG_BLUEZ_HCIBTUART=m
-# CONFIG_BLUEZ_HCIVHCI is not set
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_COREDUMP_SIGNAL is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_NO_PGT_CACHE is not set
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_ERRORS is not set
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/disable-pcmcia-probe.patch b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/disable-pcmcia-probe.patch
deleted file mode 100644
index 79ba036323..0000000000
--- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/disable-pcmcia-probe.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-
-#
-# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux/drivers/pcmcia/Config.in~disable-pcmcia-probe 2003-05-13 11:18:23.000000000 +0200
-+++ linux/drivers/pcmcia/Config.in 2004-05-27 13:59:50.000000000 +0200
-@@ -15,9 +15,6 @@
- tristate 'PCMCIA/CardBus support' CONFIG_PCMCIA
- if [ "$CONFIG_PCMCIA" != "n" ]; then
- # yes, I really mean the following...
-- if [ "$CONFIG_ISA" = "y" -o "$CONFIG_ARCH_SA1100" = "y" ]; then
-- define_bool CONFIG_PCMCIA_PROBE y
-- fi
- if [ "$CONFIG_PCI" != "n" ]; then
- bool ' CardBus support' CONFIG_CARDBUS
- fi
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/idecs.patch b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/idecs.patch
deleted file mode 100644
index 62038c34e2..0000000000
--- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/idecs.patch
+++ /dev/null
@@ -1,77 +0,0 @@
---- linux/drivers/ide/ide-cs.c 2003-02-28 17:04:00.000000000 -0600
-+++ linux.new/drivers/ide/ide-cs.c 2003-02-28 17:18:53.000000000 -0600
-@@ -2,7 +2,7 @@
-
- A driver for PCMCIA IDE/ATA disk cards
-
-- ide_cs.c 1.26 1999/11/16 02:10:49
-+ ide-cs.c 1.26 1999/11/16 02:10:49
-
- The contents of this file are subject to the Mozilla Public
- License Version 1.1 (the "License"); you may not use this file
-@@ -66,7 +66,7 @@
- MODULE_PARM(pc_debug, "i");
- #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
- static char *version =
--"ide_cs.c 1.26 1999/11/16 02:10:49 (David Hinds)";
-+"ide-cs.c 1.26 1999/11/16 02:10:49 (David Hinds)";
- #else
- #define DEBUG(n, args...)
- #endif
-@@ -110,7 +110,7 @@
- static int ide_event(event_t event, int priority,
- event_callback_args_t *args);
-
--static dev_info_t dev_info = "ide_cs";
-+static dev_info_t dev_info = "ide-cs";
-
- static dev_link_t *ide_attach(void);
- static void ide_detach(dev_link_t *);
-@@ -356,7 +356,7 @@
- }
-
- if (hd < 0) {
-- printk(KERN_NOTICE "ide_cs: ide_register() at 0x%03x & 0x%03x"
-+ printk(KERN_NOTICE "ide-cs: ide_register() at 0x%03x & 0x%03x"
- ", irq %u failed\n", io_base, ctl_base,
- link->irq.AssignedIRQ);
- goto failed;
-@@ -369,7 +369,7 @@
- info->node.minor = 0;
- info->hd = hd;
- link->dev = &info->node;
-- printk(KERN_INFO "ide_cs: %s: Vcc = %d.%d, Vpp = %d.%d\n",
-+ printk(KERN_INFO "ide-cs: %s: Vcc = %d.%d, Vpp = %d.%d\n",
- info->node.dev_name, link->conf.Vcc/10, link->conf.Vcc%10,
- link->conf.Vpp1/10, link->conf.Vpp1%10);
-
-@@ -409,9 +409,9 @@
- MOD_DEC_USE_COUNT;
- }
-
-- request_region(link->io.BasePort1, link->io.NumPorts1,"ide_cs");
-+ request_region(link->io.BasePort1, link->io.NumPorts1,"ide-cs");
- if (link->io.NumPorts2)
-- request_region(link->io.BasePort2, link->io.NumPorts2,"ide_cs");
-+ request_region(link->io.BasePort2, link->io.NumPorts2,"ide-cs");
-
- info->ndev = 0;
- link->dev = NULL;
-@@ -508,7 +508,7 @@
- DEBUG(0, "%s\n", version);
- CardServices(GetCardServicesInfo, &serv);
- if (serv.Revision != CS_RELEASE_CODE) {
-- printk(KERN_NOTICE "ide_cs: Card Services release "
-+ printk(KERN_NOTICE "ide-cs: Card Services release "
- "does not match!\n");
- return -1;
- }
-@@ -518,7 +518,7 @@
-
- static void __exit exit_ide_cs(void)
- {
-- DEBUG(0, "ide_cs: unloading\n");
-+ DEBUG(0, "ide-cs: unloading\n");
- unregister_pccard_driver(&dev_info);
- while (dev_list != NULL)
- ide_detach(dev_list);
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/initsh.patch b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/initsh.patch
deleted file mode 100644
index a672631194..0000000000
--- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/initsh.patch
+++ /dev/null
@@ -1,14 +0,0 @@
---- linux/init/main.c 2002-02-25 13:38:13.000000000 -0600
-+++ linux.new/init/main.c 2003-03-16 11:49:45.000000000 -0600
-@@ -830,8 +830,10 @@
- * trying to recover a really broken machine.
- */
-
-- if (execute_command)
-+ if (execute_command) {
-+ argv_init[0] = execute_command;
- execve(execute_command,argv_init,envp_init);
-+ }
- execve("/sbin/init",argv_init,envp_init);
- execve("/etc/init",argv_init,envp_init);
- execve("/bin/init",argv_init,envp_init);
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/iw240_we15-6.diff b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/iw240_we15-6.diff
deleted file mode 100644
index 2ebfd8ec12..0000000000
--- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/iw240_we15-6.diff
+++ /dev/null
@@ -1,399 +0,0 @@
-diff -u -p linux/include/linux/wireless.14.h linux/include/linux/wireless.h
---- linux/include/linux/wireless.14.h Mon Dec 2 18:51:00 2002
-+++ linux/include/linux/wireless.h Mon Dec 2 18:53:35 2002
-@@ -1,7 +1,7 @@
- /*
- * This file define a set of standard wireless extensions
- *
-- * Version : 14 25.1.02
-+ * Version : 15 12.7.02
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
- * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
-@@ -80,7 +80,7 @@
- * (there is some stuff that will be added in the future...)
- * I just plan to increment with each new version.
- */
--#define WIRELESS_EXT 14
-+#define WIRELESS_EXT 15
-
- /*
- * Changes :
-@@ -153,17 +153,32 @@
- * - Define additional specific event numbers
- * - Add "addr" and "param" fields in union iwreq_data
- * - AP scanning stuff (SIOCSIWSCAN and friends)
-+ *
-+ * V14 to V15
-+ * ----------
-+ * - Add IW_PRIV_TYPE_ADDR for struct sockaddr private arg
-+ * - Make struct iw_freq signed (both m & e), add explicit padding
-+ * - Add IWEVCUSTOM for driver specific event/scanning token
-+ * - Add IW_MAX_GET_SPY for driver returning a lot of addresses
-+ * - Add IW_TXPOW_RANGE for range of Tx Powers
-+ * - Add IWEVREGISTERED & IWEVEXPIRED events for Access Points
-+ * - Add IW_MODE_MONITOR for passive monitor
- */
-
- /**************************** CONSTANTS ****************************/
-
- /* -------------------------- IOCTL LIST -------------------------- */
-
--/* Basic operations */
-+/* Wireless Identification */
- #define SIOCSIWCOMMIT 0x8B00 /* Commit pending changes to driver */
- #define SIOCGIWNAME 0x8B01 /* get name == wireless protocol */
--#define SIOCSIWNWID 0x8B02 /* set network id (the cell) */
--#define SIOCGIWNWID 0x8B03 /* get network id */
-+/* SIOCGIWNAME is used to verify the presence of Wireless Extensions.
-+ * Common values : "IEEE 802.11-DS", "IEEE 802.11-FH", "IEEE 802.11b"...
-+ * Don't put the name of your driver there, it's useless. */
-+
-+/* Basic operations */
-+#define SIOCSIWNWID 0x8B02 /* set network id (pre-802.11) */
-+#define SIOCGIWNWID 0x8B03 /* get network id (the cell) */
- #define SIOCSIWFREQ 0x8B04 /* set channel/frequency (Hz) */
- #define SIOCGIWFREQ 0x8B05 /* get channel/frequency (Hz) */
- #define SIOCSIWMODE 0x8B06 /* set operation mode */
-@@ -178,16 +193,18 @@
- #define SIOCGIWPRIV 0x8B0D /* get private ioctl interface info */
- #define SIOCSIWSTATS 0x8B0E /* Unused */
- #define SIOCGIWSTATS 0x8B0F /* Get /proc/net/wireless stats */
-+/* SIOCGIWSTATS is strictly used between user space and the kernel, and
-+ * is never passed to the driver (i.e. the driver will never see it). */
-
--/* Mobile IP support */
-+/* Mobile IP support (statistics per MAC address) */
- #define SIOCSIWSPY 0x8B10 /* set spy addresses */
- #define SIOCGIWSPY 0x8B11 /* get spy info (quality of link) */
-
- /* Access Point manipulation */
- #define SIOCSIWAP 0x8B14 /* set access point MAC addresses */
- #define SIOCGIWAP 0x8B15 /* get access point MAC addresses */
--#define SIOCGIWAPLIST 0x8B17 /* get list of access point in range */
--#define SIOCSIWSCAN 0x8B18 /* trigger scanning */
-+#define SIOCGIWAPLIST 0x8B17 /* Deprecated in favor of scanning */
-+#define SIOCSIWSCAN 0x8B18 /* trigger scanning (list cells) */
- #define SIOCGIWSCAN 0x8B19 /* get scanning results */
-
- /* 802.11 specific support */
-@@ -197,9 +214,7 @@
- #define SIOCGIWNICKN 0x8B1D /* get node name/nickname */
- /* As the ESSID and NICKN are strings up to 32 bytes long, it doesn't fit
- * within the 'iwreq' structure, so we need to use the 'data' member to
-- * point to a string in user space, like it is done for RANGE...
-- * The "flags" member indicate if the ESSID is active or not (promiscuous).
-- */
-+ * point to a string in user space, like it is done for RANGE... */
-
- /* Other parameters useful in 802.11 and some other devices */
- #define SIOCSIWRATE 0x8B20 /* set default bit rate (bps) */
-@@ -257,7 +272,10 @@
- /* Most events use the same identifier as ioctl requests */
-
- #define IWEVTXDROP 0x8C00 /* Packet dropped to excessive retry */
--#define IWEVQUAL 0x8C01 /* Quality part of statistics */
-+#define IWEVQUAL 0x8C01 /* Quality part of statistics (scan) */
-+#define IWEVCUSTOM 0x8C02 /* Driver specific ascii string */
-+#define IWEVREGISTERED 0x8C03 /* Discovered a new node (AP mode) */
-+#define IWEVEXPIRED 0x8C04 /* Expired a node (AP mode) */
-
- #define IWEVFIRST 0x8C00
-
-@@ -273,7 +291,8 @@
- #define IW_PRIV_TYPE_BYTE 0x1000 /* Char as number */
- #define IW_PRIV_TYPE_CHAR 0x2000 /* Char as character */
- #define IW_PRIV_TYPE_INT 0x4000 /* 32 bits int */
--#define IW_PRIV_TYPE_FLOAT 0x5000
-+#define IW_PRIV_TYPE_FLOAT 0x5000 /* struct iw_freq */
-+#define IW_PRIV_TYPE_ADDR 0x6000 /* struct sockaddr */
-
- #define IW_PRIV_SIZE_FIXED 0x0800 /* Variable or fixed nuber of args */
-
-@@ -297,13 +316,16 @@
-
- /* Maximum tx powers in the range struct */
- #define IW_MAX_TXPOWER 8
-+/* Note : if you more than 8 TXPowers, just set the max and min or
-+ * a few of them in the struct iw_range. */
-
- /* Maximum of address that you may set with SPY */
--#define IW_MAX_SPY 8
-+#define IW_MAX_SPY 8 /* set */
-+#define IW_MAX_GET_SPY 64 /* get */
-
- /* Maximum of address that you may get in the
- list of access points in range */
--#define IW_MAX_AP 8
-+#define IW_MAX_AP 64
-
- /* Maximum size of the ESSID and NICKN strings */
- #define IW_ESSID_MAX_SIZE 32
-@@ -315,6 +337,7 @@
- #define IW_MODE_MASTER 3 /* Synchronisation master or Access Point */
- #define IW_MODE_REPEAT 4 /* Wireless Repeater (forwarder) */
- #define IW_MODE_SECOND 5 /* Secondary master/repeater (backup) */
-+#define IW_MODE_MONITOR 6 /* Passive monitor (listen only) */
-
- /* Maximum number of size of encoding token available
- * they are listed in the range structure */
-@@ -350,8 +373,10 @@
- #define IW_POWER_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
-
- /* Transmit Power flags available */
-+#define IW_TXPOW_TYPE 0x00FF /* Type of value */
- #define IW_TXPOW_DBM 0x0000 /* Value is in dBm */
- #define IW_TXPOW_MWATT 0x0001 /* Value is in mW */
-+#define IW_TXPOW_RANGE 0x1000 /* Range of value between min/max */
-
- /* Retry limits and lifetime flags available */
- #define IW_RETRY_ON 0x0000 /* No details... */
-@@ -376,6 +401,9 @@
- /* Maximum size of returned data */
- #define IW_SCAN_MAX_DATA 4096 /* In bytes */
-
-+/* Max number of char in custom event - use multiple of them if needed */
-+#define IW_CUSTOM_MAX 256 /* In bytes */
-+
- /****************************** TYPES ******************************/
-
- /* --------------------------- SUBTYPES --------------------------- */
-@@ -411,9 +439,10 @@ struct iw_point
- */
- struct iw_freq
- {
-- __u32 m; /* Mantissa */
-- __u16 e; /* Exponent */
-+ __s32 m; /* Mantissa */
-+ __s16 e; /* Exponent */
- __u8 i; /* List index (when in range struct) */
-+ __u8 pad; /* Unused - just for alignement */
- };
-
- /*
-diff -u -p linux/include/net/iw_handler.14.h linux/include/net/iw_handler.h
---- linux/include/net/iw_handler.14.h Mon Dec 2 18:51:17 2002
-+++ linux/include/net/iw_handler.h Mon Dec 2 18:54:51 2002
-@@ -1,7 +1,7 @@
- /*
- * This file define the new driver API for Wireless Extensions
- *
-- * Version : 3 17.1.02
-+ * Version : 4 21.6.02
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
- * Copyright (c) 2001-2002 Jean Tourrilhes, All Rights Reserved.
-@@ -206,7 +206,7 @@
- * will be needed...
- * I just plan to increment with each new version.
- */
--#define IW_HANDLER_VERSION 3
-+#define IW_HANDLER_VERSION 4
-
- /*
- * Changes :
-@@ -217,6 +217,9 @@
- * - Add Wireless Event support :
- * o wireless_send_event() prototype
- * o iwe_stream_add_event/point() inline functions
-+ * V3 to V4
-+ * --------
-+ * - Reshuffle IW_HEADER_TYPE_XXX to map IW_PRIV_TYPE_XXX changes
- */
-
- /**************************** CONSTANTS ****************************/
-@@ -233,10 +236,10 @@
- #define IW_HEADER_TYPE_CHAR 2 /* char [IFNAMSIZ] */
- #define IW_HEADER_TYPE_UINT 4 /* __u32 */
- #define IW_HEADER_TYPE_FREQ 5 /* struct iw_freq */
--#define IW_HEADER_TYPE_POINT 6 /* struct iw_point */
--#define IW_HEADER_TYPE_PARAM 7 /* struct iw_param */
--#define IW_HEADER_TYPE_ADDR 8 /* struct sockaddr */
--#define IW_HEADER_TYPE_QUAL 9 /* struct iw_quality */
-+#define IW_HEADER_TYPE_ADDR 6 /* struct sockaddr */
-+#define IW_HEADER_TYPE_POINT 8 /* struct iw_point */
-+#define IW_HEADER_TYPE_PARAM 9 /* struct iw_param */
-+#define IW_HEADER_TYPE_QUAL 10 /* struct iw_quality */
-
- /* Handling flags */
- /* Most are not implemented. I just use them as a reminder of some
-diff -u -p linux/net/core/wireless.14.c linux/net/core/wireless.c
---- linux/net/core/wireless.14.c Mon Dec 2 18:51:35 2002
-+++ linux/net/core/wireless.c Mon Dec 2 18:53:10 2002
-@@ -33,8 +33,16 @@
- * o Propagate events as rtnetlink IFLA_WIRELESS option
- * o Generate event on selected SET requests
- *
-- * v4 - 18.04.01 - Jean II
-+ * v4 - 18.04.02 - Jean II
- * o Fix stupid off by one in iw_ioctl_description : IW_ESSID_MAX_SIZE + 1
-+ *
-+ * v5 - 21.06.02 - Jean II
-+ * o Add IW_PRIV_TYPE_ADDR in priv_type_size (+cleanup)
-+ * o Reshuffle IW_HEADER_TYPE_XXX to map IW_PRIV_TYPE_XXX changes
-+ * o Add IWEVCUSTOM for driver specific event/scanning token
-+ * o Turn on WE_STRICT_WRITE by default + kernel warning
-+ * o Fix WE_STRICT_WRITE in ioctl_export_private() (32 => iw_num)
-+ * o Fix off-by-one in test (extra_size <= IFNAMSIZ)
- */
-
- /***************************** INCLUDES *****************************/
-@@ -50,8 +58,9 @@
-
- /**************************** CONSTANTS ****************************/
-
--/* This will be turned on later on... */
--#undef WE_STRICT_WRITE /* Check write buffer size */
-+/* Enough lenience, let's make sure things are proper... */
-+#define WE_STRICT_WRITE /* Check write buffer size */
-+/* I'll probably drop both the define and kernel message in the next version */
-
- /* Debuging stuff */
- #undef WE_IOCTL_DEBUG /* Debug IOCTL API */
-@@ -106,7 +115,7 @@ static const struct iw_ioctl_description
- /* SIOCSIWSPY */
- { IW_HEADER_TYPE_POINT, 0, sizeof(struct sockaddr), 0, IW_MAX_SPY, 0},
- /* SIOCGIWSPY */
-- { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_SPY, 0},
-+ { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_GET_SPY, 0},
- /* -- hole -- */
- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
- /* -- hole -- */
-@@ -176,25 +185,41 @@ static const struct iw_ioctl_description
- { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
- /* IWEVQUAL */
- { IW_HEADER_TYPE_QUAL, 0, 0, 0, 0, 0},
-+ /* IWEVCUSTOM */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_CUSTOM_MAX, 0},
-+ /* IWEVREGISTERED */
-+ { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
-+ /* IWEVEXPIRED */
-+ { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
- };
- static const int standard_event_num = (sizeof(standard_event) /
- sizeof(struct iw_ioctl_description));
-
- /* Size (in bytes) of the various private data types */
--static const char priv_type_size[] = { 0, 1, 1, 0, 4, 4, 0, 0 };
-+static const char priv_type_size[] = {
-+ 0, /* IW_PRIV_TYPE_NONE */
-+ 1, /* IW_PRIV_TYPE_BYTE */
-+ 1, /* IW_PRIV_TYPE_CHAR */
-+ 0, /* Not defined */
-+ sizeof(__u32), /* IW_PRIV_TYPE_INT */
-+ sizeof(struct iw_freq), /* IW_PRIV_TYPE_FLOAT */
-+ sizeof(struct sockaddr), /* IW_PRIV_TYPE_ADDR */
-+ 0, /* Not defined */
-+};
-
- /* Size (in bytes) of various events */
- static const int event_type_size[] = {
-- IW_EV_LCP_LEN,
-+ IW_EV_LCP_LEN, /* IW_HEADER_TYPE_NULL */
-+ 0,
-+ IW_EV_CHAR_LEN, /* IW_HEADER_TYPE_CHAR */
- 0,
-- IW_EV_CHAR_LEN,
-+ IW_EV_UINT_LEN, /* IW_HEADER_TYPE_UINT */
-+ IW_EV_FREQ_LEN, /* IW_HEADER_TYPE_FREQ */
-+ IW_EV_ADDR_LEN, /* IW_HEADER_TYPE_ADDR */
- 0,
-- IW_EV_UINT_LEN,
-- IW_EV_FREQ_LEN,
- IW_EV_POINT_LEN, /* Without variable payload */
-- IW_EV_PARAM_LEN,
-- IW_EV_ADDR_LEN,
-- IW_EV_QUAL_LEN,
-+ IW_EV_PARAM_LEN, /* IW_HEADER_TYPE_PARAM */
-+ IW_EV_QUAL_LEN, /* IW_HEADER_TYPE_QUAL */
- };
-
- /************************ COMMON SUBROUTINES ************************/
-@@ -440,8 +465,10 @@ static inline int ioctl_export_private(s
- return -EFAULT;
- #ifdef WE_STRICT_WRITE
- /* Check if there is enough buffer up there */
-- if(iwr->u.data.length < (SIOCIWLASTPRIV - SIOCIWFIRSTPRIV + 1))
-+ if(iwr->u.data.length < dev->wireless_handlers->num_private_args) {
-+ printk(KERN_ERR "%s (WE) : Buffer for request SIOCGIWPRIV too small (%d<%d)\n", dev->name, iwr->u.data.length, dev->wireless_handlers->num_private_args);
- return -E2BIG;
-+ }
- #endif /* WE_STRICT_WRITE */
-
- /* Set the number of available ioctls. */
-@@ -471,6 +498,7 @@ static inline int ioctl_standard_call(st
- const struct iw_ioctl_description * descr;
- struct iw_request_info info;
- int ret = -EINVAL;
-+ int user_size = 0;
-
- /* Get the description of the IOCTL */
- if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
-@@ -518,11 +546,8 @@ static inline int ioctl_standard_call(st
- /* Check NULL pointer */
- if(iwr->u.data.pointer == NULL)
- return -EFAULT;
--#ifdef WE_STRICT_WRITE
-- /* Check if there is enough buffer up there */
-- if(iwr->u.data.length < descr->max_tokens)
-- return -E2BIG;
--#endif /* WE_STRICT_WRITE */
-+ /* Save user space buffer size for checking */
-+ user_size = iwr->u.data.length;
- }
-
- #ifdef WE_IOCTL_DEBUG
-@@ -559,6 +584,15 @@ static inline int ioctl_standard_call(st
-
- /* If we have something to return to the user */
- if (!ret && IW_IS_GET(cmd)) {
-+#ifdef WE_STRICT_WRITE
-+ /* Check if there is enough buffer up there */
-+ if(user_size < iwr->u.data.length) {
-+ printk(KERN_ERR "%s (WE) : Buffer for request %04X too small (%d<%d)\n", dev->name, cmd, user_size, iwr->u.data.length);
-+ kfree(extra);
-+ return -E2BIG;
-+ }
-+#endif /* WE_STRICT_WRITE */
-+
- err = copy_to_user(iwr->u.data.pointer, extra,
- iwr->u.data.length *
- descr->token_size);
-@@ -646,12 +680,18 @@ static inline int ioctl_private_call(str
- /* Compute the size of the set/get arguments */
- if(descr != NULL) {
- if(IW_IS_SET(cmd)) {
-+ int offset = 0; /* For sub-ioctls */
-+ /* Check for sub-ioctl handler */
-+ if(descr->name[0] == '\0')
-+ /* Reserve one int for sub-ioctl index */
-+ offset = sizeof(__u32);
-+
- /* Size of set arguments */
- extra_size = get_priv_size(descr->set_args);
-
- /* Does it fits in iwr ? */
- if((descr->set_args & IW_PRIV_SIZE_FIXED) &&
-- (extra_size < IFNAMSIZ))
-+ ((extra_size + offset) <= IFNAMSIZ))
- extra_size = 0;
- } else {
- /* Size of set arguments */
-@@ -659,7 +699,7 @@ static inline int ioctl_private_call(str
-
- /* Does it fits in iwr ? */
- if((descr->get_args & IW_PRIV_SIZE_FIXED) &&
-- (extra_size < IFNAMSIZ))
-+ (extra_size <= IFNAMSIZ))
- extra_size = 0;
- }
- }
-@@ -925,7 +965,7 @@ void wireless_send_event(struct net_devi
- * The best the driver could do is to log an error message.
- * We will do it ourselves instead...
- */
-- printk(KERN_ERR "%s (WE) : Invalid Wireless Event (0x%04X)\n",
-+ printk(KERN_ERR "%s (WE) : Invalid/Unknown Wireless Event (0x%04X)\n",
- dev->name, cmd);
- return;
- }
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/iw_handlers.w13-5.diff b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/iw_handlers.w13-5.diff
deleted file mode 100644
index a27a7654a9..0000000000
--- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/iw_handlers.w13-5.diff
+++ /dev/null
@@ -1,1513 +0,0 @@
-diff -u -p -r --new-file linux/include/linux-w12/netdevice.h linux/include/linux/netdevice.h
---- linux/include/linux-w12/netdevice.h Thu Nov 22 11:47:09 2001
-+++ linux/include/linux/netdevice.h Thu Jan 17 12:00:39 2002
-@@ -278,6 +278,10 @@ struct net_device
- struct net_device_stats* (*get_stats)(struct net_device *dev);
- struct iw_statistics* (*get_wireless_stats)(struct net_device *dev);
-
-+ /* List of functions to handle Wireless Extensions (instead of ioctl).
-+ * See <net/iw_handler.h> for details. Jean II */
-+ struct iw_handler_def * wireless_handlers;
-+
- /*
- * This marks the end of the "visible" part of the structure. All
- * fields hereafter are internal to the system, and may change at
-diff -u -p -r --new-file linux/include/linux-w12/wireless.h linux/include/linux/wireless.h
---- linux/include/linux-w12/wireless.h Thu Nov 22 11:47:12 2001
-+++ linux/include/linux/wireless.h Thu Jan 17 12:04:08 2002
-@@ -1,9 +1,10 @@
- /*
- * This file define a set of standard wireless extensions
- *
-- * Version : 12 5.10.01
-+ * Version : 13 6.12.01
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-+ * Copyright (c) 1997-2001 Jean Tourrilhes, All Rights Reserved.
- */
-
- #ifndef _LINUX_WIRELESS_H
-@@ -11,6 +12,8 @@
-
- /************************** DOCUMENTATION **************************/
- /*
-+ * Initial APIs (1996 -> onward) :
-+ * -----------------------------
- * Basically, the wireless extensions are for now a set of standard ioctl
- * call + /proc/net/wireless
- *
-@@ -27,16 +30,27 @@
- * We have the list of command plus a structure descibing the
- * data exchanged...
- * Note that to add these ioctl, I was obliged to modify :
-- * net/core/dev.c (two place + add include)
-- * net/ipv4/af_inet.c (one place + add include)
-+ * # net/core/dev.c (two place + add include)
-+ * # net/ipv4/af_inet.c (one place + add include)
- *
- * /proc/net/wireless is a copy of /proc/net/dev.
- * We have a structure for data passed from the driver to /proc/net/wireless
- * Too add this, I've modified :
-- * net/core/dev.c (two other places)
-- * include/linux/netdevice.h (one place)
-- * include/linux/proc_fs.h (one place)
-+ * # net/core/dev.c (two other places)
-+ * # include/linux/netdevice.h (one place)
-+ * # include/linux/proc_fs.h (one place)
-+ *
-+ * New driver API (2001 -> onward) :
-+ * -------------------------------
-+ * This file is only concerned with the user space API and common definitions.
-+ * The new driver API is defined and documented in :
-+ * # include/net/iw_handler.h
- *
-+ * Note as well that /proc/net/wireless implementation has now moved in :
-+ * # include/linux/wireless.c
-+ *
-+ * Other comments :
-+ * --------------
- * Do not add here things that are redundant with other mechanisms
- * (drivers init, ifconfig, /proc/net/dev, ...) and with are not
- * wireless specific.
-@@ -54,16 +68,14 @@
- #include <linux/socket.h> /* for "struct sockaddr" et al */
- #include <linux/if.h> /* for IFNAMSIZ and co... */
-
--/**************************** CONSTANTS ****************************/
--
--/* --------------------------- VERSION --------------------------- */
-+/***************************** VERSION *****************************/
- /*
- * This constant is used to know the availability of the wireless
- * extensions and to know which version of wireless extensions it is
- * (there is some stuff that will be added in the future...)
- * I just plan to increment with each new version.
- */
--#define WIRELESS_EXT 12
-+#define WIRELESS_EXT 13
-
- /*
- * Changes :
-@@ -123,12 +135,20 @@
- * - Add DEV PRIVATE IOCTL to avoid collisions in SIOCDEVPRIVATE space
- * - Add new statistics (frag, retry, beacon)
- * - Add average quality (for user space calibration)
-+ *
-+ * V12 to V13
-+ * ----------
-+ * - Document creation of new driver API.
-+ * - Extract union iwreq_data from struct iwreq (for new driver API).
-+ * - Rename SIOCSIWNAME as SIOCSIWCOMMIT
- */
-
-+/**************************** CONSTANTS ****************************/
-+
- /* -------------------------- IOCTL LIST -------------------------- */
-
- /* Basic operations */
--#define SIOCSIWNAME 0x8B00 /* Unused */
-+#define SIOCSIWCOMMIT 0x8B00 /* Commit pending changes to driver */
- #define SIOCGIWNAME 0x8B01 /* get name == wireless protocol */
- #define SIOCSIWNWID 0x8B02 /* set network id (the cell) */
- #define SIOCGIWNWID 0x8B03 /* get network id */
-@@ -414,13 +434,49 @@ struct iw_statistics
-
- /* ------------------------ IOCTL REQUEST ------------------------ */
- /*
-+ * This structure defines the payload of an ioctl, and is used
-+ * below.
-+ *
-+ * Note that this structure should fit on the memory footprint
-+ * of iwreq (which is the same as ifreq), which mean a max size of
-+ * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
-+ * You should check this when increasing the structures defined
-+ * above in this file...
-+ */
-+union iwreq_data
-+{
-+ /* Config - generic */
-+ char name[IFNAMSIZ];
-+ /* Name : used to verify the presence of wireless extensions.
-+ * Name of the protocol/provider... */
-+
-+ struct iw_point essid; /* Extended network name */
-+ struct iw_param nwid; /* network id (or domain - the cell) */
-+ struct iw_freq freq; /* frequency or channel :
-+ * 0-1000 = channel
-+ * > 1000 = frequency in Hz */
-+
-+ struct iw_param sens; /* signal level threshold */
-+ struct iw_param bitrate; /* default bit rate */
-+ struct iw_param txpower; /* default transmit power */
-+ struct iw_param rts; /* RTS threshold threshold */
-+ struct iw_param frag; /* Fragmentation threshold */
-+ __u32 mode; /* Operation mode */
-+ struct iw_param retry; /* Retry limits & lifetime */
-+
-+ struct iw_point encoding; /* Encoding stuff : tokens */
-+ struct iw_param power; /* PM duration/timeout */
-+
-+ struct sockaddr ap_addr; /* Access point address */
-+
-+ struct iw_point data; /* Other large parameters */
-+};
-+
-+/*
- * The structure to exchange data for ioctl.
- * This structure is the same as 'struct ifreq', but (re)defined for
- * convenience...
-- *
-- * Note that it should fit on the same memory footprint !
-- * You should check this when increasing the above structures (16 octets)
-- * 16 octets = 128 bits. Warning, pointers might be 64 bits wide...
-+ * Do I need to remind you about structure size (32 octets) ?
- */
- struct iwreq
- {
-@@ -429,35 +485,8 @@ struct iwreq
- char ifrn_name[IFNAMSIZ]; /* if name, e.g. "eth0" */
- } ifr_ifrn;
-
-- /* Data part */
-- union
-- {
-- /* Config - generic */
-- char name[IFNAMSIZ];
-- /* Name : used to verify the presence of wireless extensions.
-- * Name of the protocol/provider... */
--
-- struct iw_point essid; /* Extended network name */
-- struct iw_param nwid; /* network id (or domain - the cell) */
-- struct iw_freq freq; /* frequency or channel :
-- * 0-1000 = channel
-- * > 1000 = frequency in Hz */
--
-- struct iw_param sens; /* signal level threshold */
-- struct iw_param bitrate; /* default bit rate */
-- struct iw_param txpower; /* default transmit power */
-- struct iw_param rts; /* RTS threshold threshold */
-- struct iw_param frag; /* Fragmentation threshold */
-- __u32 mode; /* Operation mode */
-- struct iw_param retry; /* Retry limits & lifetime */
--
-- struct iw_point encoding; /* Encoding stuff : tokens */
-- struct iw_param power; /* PM duration/timeout */
--
-- struct sockaddr ap_addr; /* Access point address */
--
-- struct iw_point data; /* Other large parameters */
-- } u;
-+ /* Data part (defined just above) */
-+ union iwreq_data u;
- };
-
- /* -------------------------- IOCTL DATA -------------------------- */
-diff -u -p -r --new-file linux/include/net-w12/iw_handler.h linux/include/net/iw_handler.h
---- linux/include/net-w12/iw_handler.h Wed Dec 31 16:00:00 1969
-+++ linux/include/net/iw_handler.h Thu Jan 17 12:16:46 2002
-@@ -0,0 +1,374 @@
-+/*
-+ * This file define the new driver API for Wireless Extensions
-+ *
-+ * Version : 2 6.12.01
-+ *
-+ * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-+ * Copyright (c) 2001 Jean Tourrilhes, All Rights Reserved.
-+ */
-+
-+#ifndef _IW_HANDLER_H
-+#define _IW_HANDLER_H
-+
-+/************************** DOCUMENTATION **************************/
-+/*
-+ * Initial driver API (1996 -> onward) :
-+ * -----------------------------------
-+ * The initial API just sends the IOCTL request received from user space
-+ * to the driver (via the driver ioctl handler). The driver has to
-+ * handle all the rest...
-+ *
-+ * The initial API also defines a specific handler in struct net_device
-+ * to handle wireless statistics.
-+ *
-+ * The initial APIs served us well and has proven a reasonably good design.
-+ * However, there is a few shortcommings :
-+ * o No events, everything is a request to the driver.
-+ * o Large ioctl function in driver with gigantic switch statement
-+ * (i.e. spaghetti code).
-+ * o Driver has to mess up with copy_to/from_user, and in many cases
-+ * does it unproperly. Common mistakes are :
-+ * * buffer overflows (no checks or off by one checks)
-+ * * call copy_to/from_user with irq disabled
-+ * o The user space interface is tied to ioctl because of the use
-+ * copy_to/from_user.
-+ *
-+ * New driver API (2001 -> onward) :
-+ * -------------------------------
-+ * The new driver API is just a bunch of standard functions (handlers),
-+ * each handling a specific Wireless Extension. The driver just export
-+ * the list of handler it supports, and those will be called apropriately.
-+ *
-+ * I tried to keep the main advantage of the previous API (simplicity,
-+ * efficiency and light weight), and also I provide a good dose of backward
-+ * compatibility (most structures are the same, driver can use both API
-+ * simultaneously, ...).
-+ * Hopefully, I've also addressed the shortcomming of the initial API.
-+ *
-+ * The advantage of the new API are :
-+ * o Handling of Extensions in driver broken in small contained functions
-+ * o Tighter checks of ioctl before calling the driver
-+ * o Flexible commit strategy (at least, the start of it)
-+ * o Backward compatibility (can be mixed with old API)
-+ * o Driver doesn't have to worry about memory and user-space issues
-+ * The last point is important for the following reasons :
-+ * o You are now able to call the new driver API from any API you
-+ * want (including from within other parts of the kernel).
-+ * o Common mistakes are avoided (buffer overflow, user space copy
-+ * with irq disabled and so on).
-+ *
-+ * The Drawback of the new API are :
-+ * o bloat (especially kernel)
-+ * o need to migrate existing drivers to new API
-+ * My initial testing shows that the new API adds around 3kB to the kernel
-+ * and save between 0 and 5kB from a typical driver.
-+ * Also, as all structures and data types are unchanged, the migration is
-+ * quite straightforward (but tedious).
-+ *
-+ * ---
-+ *
-+ * The new driver API is defined below in this file. User space should
-+ * not be aware of what's happening down there...
-+ *
-+ * A new kernel wrapper is in charge of validating the IOCTLs and calling
-+ * the appropriate driver handler. This is implemented in :
-+ * # net/core/wireless.c
-+ *
-+ * The driver export the list of handlers in :
-+ * # include/linux/netdevice.h (one place)
-+ *
-+ * The new driver API is available for WIRELESS_EXT >= 13.
-+ * Good luck with migration to the new API ;-)
-+ */
-+
-+/* ---------------------- THE IMPLEMENTATION ---------------------- */
-+/*
-+ * Some of the choice I've made are pretty controversials. Defining an
-+ * API is very much weighting compromises. This goes into some of the
-+ * details and the thinking behind the implementation.
-+ *
-+ * Implementation goals :
-+ * --------------------
-+ * The implementation goals were as follow :
-+ * o Obvious : you should not need a PhD to understand what's happening,
-+ * the benefit is easier maintainance.
-+ * o Flexible : it should accomodate a wide variety of driver
-+ * implementations and be as flexible as the old API.
-+ * o Lean : it should be efficient memory wise to minimise the impact
-+ * on kernel footprint.
-+ * o Transparent to user space : the large number of user space
-+ * applications that use Wireless Extensions should not need
-+ * any modifications.
-+ *
-+ * Array of functions versus Struct of functions
-+ * ---------------------------------------------
-+ * 1) Having an array of functions allow the kernel code to access the
-+ * handler in a single lookup, which is much more efficient (think hash
-+ * table here).
-+ * 2) The only drawback is that driver writer may put their handler in
-+ * the wrong slot. This is trivial to test (I set the frequency, the
-+ * bitrate changes). Once the handler is in the proper slot, it will be
-+ * there forever, because the array is only extended at the end.
-+ * 3) Backward/forward compatibility : adding new handler just require
-+ * extending the array, so you can put newer driver in older kernel
-+ * without having to patch the kernel code (and vice versa).
-+ *
-+ * All handler are of the same generic type
-+ * ----------------------------------------
-+ * That's a feature !!!
-+ * 1) Having a generic handler allow to have generic code, which is more
-+ * efficient. If each of the handler was individually typed I would need
-+ * to add a big switch in the kernel (== more bloat). This solution is
-+ * more scalable, adding new Wireless Extensions doesn't add new code.
-+ * 2) You can use the same handler in different slots of the array. For
-+ * hardware, it may be more efficient or logical to handle multiple
-+ * Wireless Extensions with a single function, and the API allow you to
-+ * do that. (An example would be a single record on the card to control
-+ * both bitrate and frequency, the handler would read the old record,
-+ * modify it according to info->cmd and rewrite it).
-+ *
-+ * Functions prototype uses union iwreq_data
-+ * -----------------------------------------
-+ * Some would have prefered functions defined this way :
-+ * static int mydriver_ioctl_setrate(struct net_device *dev,
-+ * long rate, int auto)
-+ * 1) The kernel code doesn't "validate" the content of iwreq_data, and
-+ * can't do it (different hardware may have different notion of what a
-+ * valid frequency is), so we don't pretend that we do it.
-+ * 2) The above form is not extendable. If I want to add a flag (for
-+ * example to distinguish setting max rate and basic rate), I would
-+ * break the prototype. Using iwreq_data is more flexible.
-+ * 3) Also, the above form is not generic (see above).
-+ * 4) I don't expect driver developper using the wrong field of the
-+ * union (Doh !), so static typechecking doesn't add much value.
-+ * 5) Lastly, you can skip the union by doing :
-+ * static int mydriver_ioctl_setrate(struct net_device *dev,
-+ * struct iw_request_info *info,
-+ * struct iw_param *rrq,
-+ * char *extra)
-+ * And then adding the handler in the array like this :
-+ * (iw_handler) mydriver_ioctl_setrate, // SIOCSIWRATE
-+ *
-+ * Using functions and not a registry
-+ * ----------------------------------
-+ * Another implementation option would have been for every instance to
-+ * define a registry (a struct containing all the Wireless Extensions)
-+ * and only have a function to commit the registry to the hardware.
-+ * 1) This approach can be emulated by the current code, but not
-+ * vice versa.
-+ * 2) Some drivers don't keep any configuration in the driver, for them
-+ * adding such a registry would be a significant bloat.
-+ * 3) The code to translate from Wireless Extension to native format is
-+ * needed anyway, so it would not reduce significantely the amount of code.
-+ * 4) The current approach only selectively translate Wireless Extensions
-+ * to native format and only selectively set, whereas the registry approach
-+ * would require to translate all WE and set all parameters for any single
-+ * change.
-+ * 5) For many Wireless Extensions, the GET operation return the current
-+ * dynamic value, not the value that was set.
-+ *
-+ * This header is <net/iw_handler.h>
-+ * ---------------------------------
-+ * 1) This header is kernel space only and should not be exported to
-+ * user space. Headers in "include/linux/" are exported, headers in
-+ * "include/net/" are not.
-+ *
-+ * Mixed 32/64 bit issues
-+ * ----------------------
-+ * The Wireless Extensions are designed to be 64 bit clean, by using only
-+ * datatypes with explicit storage size.
-+ * There are some issues related to kernel and user space using different
-+ * memory model, and in particular 64bit kernel with 32bit user space.
-+ * The problem is related to struct iw_point, that contains a pointer
-+ * that *may* need to be translated.
-+ * This is quite messy. The new API doesn't solve this problem (it can't),
-+ * but is a step in the right direction :
-+ * 1) Meta data about each ioctl is easily available, so we know what type
-+ * of translation is needed.
-+ * 2) The move of data between kernel and user space is only done in a single
-+ * place in the kernel, so adding specific hooks in there is possible.
-+ * 3) In the long term, it allows to move away from using ioctl as the
-+ * user space API.
-+ *
-+ * So many comments and so few code
-+ * --------------------------------
-+ * That's a feature. Comments won't bloat the resulting kernel binary.
-+ */
-+
-+/***************************** INCLUDES *****************************/
-+
-+#include <linux/wireless.h> /* IOCTL user space API */
-+
-+/***************************** VERSION *****************************/
-+/*
-+ * This constant is used to know which version of the driver API is
-+ * available. Hopefully, this will be pretty stable and no changes
-+ * will be needed...
-+ * I just plan to increment with each new version.
-+ */
-+#define IW_HANDLER_VERSION 2
-+
-+/**************************** CONSTANTS ****************************/
-+
-+/* Special error message for the driver to indicate that we
-+ * should do a commit after return from the iw_handler */
-+#define EIWCOMMIT EINPROGRESS
-+
-+/* Flags available in struct iw_request_info */
-+#define IW_REQUEST_FLAG_NONE 0x0000 /* No flag so far */
-+
-+/* Type of headers we know about (basically union iwreq_data) */
-+#define IW_HEADER_TYPE_NULL 0 /* Not available */
-+#define IW_HEADER_TYPE_CHAR 2 /* char [IFNAMSIZ] */
-+#define IW_HEADER_TYPE_UINT 4 /* __u32 */
-+#define IW_HEADER_TYPE_FREQ 5 /* struct iw_freq */
-+#define IW_HEADER_TYPE_POINT 6 /* struct iw_point */
-+#define IW_HEADER_TYPE_PARAM 7 /* struct iw_param */
-+#define IW_HEADER_TYPE_ADDR 8 /* struct sockaddr */
-+
-+/* Handling flags */
-+/* Most are not implemented. I just use them as a reminder of some
-+ * cool features we might need one day ;-) */
-+#define IW_DESCR_FLAG_NONE 0x0000 /* Obvious */
-+/* Wrapper level flags */
-+#define IW_DESCR_FLAG_DUMP 0x0001 /* Not part of the dump command */
-+#define IW_DESCR_FLAG_EVENT 0x0002 /* Generate an event on SET */
-+#define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET request is ROOT only */
-+/* Driver level flags */
-+#define IW_DESCR_FLAG_WAIT 0x0100 /* Wait for driver event */
-+
-+/****************************** TYPES ******************************/
-+
-+/* ----------------------- WIRELESS HANDLER ----------------------- */
-+/*
-+ * A wireless handler is just a standard function, that looks like the
-+ * ioctl handler.
-+ * We also define there how a handler list look like... As the Wireless
-+ * Extension space is quite dense, we use a simple array, which is faster
-+ * (that's the perfect hash table ;-).
-+ */
-+
-+/*
-+ * Meta data about the request passed to the iw_handler.
-+ * Most handlers can safely ignore what's in there.
-+ * The 'cmd' field might come handy if you want to use the same handler
-+ * for multiple command...
-+ * This struct is also my long term insurance. I can add new fields here
-+ * without breaking the prototype of iw_handler...
-+ */
-+struct iw_request_info
-+{
-+ __u16 cmd; /* Wireless Extension command */
-+ __u16 flags; /* More to come ;-) */
-+};
-+
-+/*
-+ * This is how a function handling a Wireless Extension should look
-+ * like (both get and set, standard and private).
-+ */
-+typedef int (*iw_handler)(struct net_device *dev, struct iw_request_info *info,
-+ union iwreq_data *wrqu, char *extra);
-+
-+/*
-+ * This define all the handler that the driver export.
-+ * As you need only one per driver type, please use a static const
-+ * shared by all driver instances... Same for the members...
-+ * This will be linked from net_device in <linux/netdevice.h>
-+ */
-+struct iw_handler_def
-+{
-+ /* Number of handlers defined (more precisely, index of the
-+ * last defined handler + 1) */
-+ __u16 num_standard;
-+ __u16 num_private;
-+ /* Number of private arg description */
-+ __u16 num_private_args;
-+
-+ /* Array of handlers for standard ioctls
-+ * We will call dev->wireless_handlers->standard[ioctl - SIOCSIWNAME]
-+ */
-+ iw_handler * standard;
-+
-+ /* Array of handlers for private ioctls
-+ * Will call dev->wireless_handlers->private[ioctl - SIOCIWFIRSTPRIV]
-+ */
-+ iw_handler * private;
-+
-+ /* Arguments of private handler. This one is just a list, so you
-+ * can put it in any order you want and should not leave holes...
-+ * We will automatically export that to user space... */
-+ struct iw_priv_args * private_args;
-+
-+ /* In the long term, get_wireless_stats will move from
-+ * 'struct net_device' to here, to minimise bloat. */
-+};
-+
-+/* ----------------------- WIRELESS EVENTS ----------------------- */
-+/*
-+ * Currently we don't support events, so let's just plan for the
-+ * future...
-+ */
-+
-+/*
-+ * A Wireless Event.
-+ */
-+// How do we define short header ? We don't want a flag on length.
-+// Probably a flag on event ? Highest bit to zero...
-+struct iw_event
-+{
-+ __u16 length; /* Lenght of this stuff */
-+ __u16 event; /* Wireless IOCTL */
-+ union iwreq_data header; /* IOCTL fixed payload */
-+ char extra[0]; /* Optional IOCTL data */
-+};
-+
-+/* ---------------------- IOCTL DESCRIPTION ---------------------- */
-+/*
-+ * One of the main goal of the new interface is to deal entirely with
-+ * user space/kernel space memory move.
-+ * For that, we need to know :
-+ * o if iwreq is a pointer or contain the full data
-+ * o what is the size of the data to copy
-+ *
-+ * For private IOCTLs, we use the same rules as used by iwpriv and
-+ * defined in struct iw_priv_args.
-+ *
-+ * For standard IOCTLs, things are quite different and we need to
-+ * use the stuctures below. Actually, this struct is also more
-+ * efficient, but that's another story...
-+ */
-+
-+/*
-+ * Describe how a standard IOCTL looks like.
-+ */
-+struct iw_ioctl_description
-+{
-+ __u8 header_type; /* NULL, iw_point or other */
-+ __u8 token_type; /* Future */
-+ __u16 token_size; /* Granularity of payload */
-+ __u16 min_tokens; /* Min acceptable token number */
-+ __u16 max_tokens; /* Max acceptable token number */
-+ __u32 flags; /* Special handling of the request */
-+};
-+
-+/* Need to think of short header translation table. Later. */
-+
-+/**************************** PROTOTYPES ****************************/
-+/*
-+ * Functions part of the Wireless Extensions (defined in net/core/wireless.c).
-+ * Those may be called only within the kernel.
-+ */
-+
-+/* First : function strictly used inside the kernel */
-+
-+/* Handle /proc/net/wireless, called in net/code/dev.c */
-+extern int dev_get_wireless_info(char * buffer, char **start, off_t offset,
-+ int length);
-+
-+/* Handle IOCTLs, called in net/code/dev.c */
-+extern int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd);
-+
-+/* Second : functions that may be called by driver modules */
-+/* None yet */
-+
-+#endif /* _LINUX_WIRELESS_H */
-diff -u -p -r --new-file linux/net/core-w12/Makefile linux/net/core/Makefile
---- linux/net/core-w12/Makefile Tue Oct 30 15:08:12 2001
-+++ linux/net/core/Makefile Thu Jan 17 11:06:07 2002
-@@ -26,5 +26,8 @@ obj-$(CONFIG_NET) += dev.o dev_mcast.o d
- obj-$(CONFIG_NETFILTER) += netfilter.o
- obj-$(CONFIG_NET_DIVERT) += dv.o
- obj-$(CONFIG_NET_PROFILE) += profile.o
-+obj-$(CONFIG_NET_RADIO) += wireless.o
-+# Ugly. I wish all wireless drivers were moved in drivers/net/wireless
-+obj-$(CONFIG_NET_PCMCIA_RADIO) += wireless.o
-
- include $(TOPDIR)/Rules.make
-diff -u -p -r --new-file linux/net/core-w12/dev.c linux/net/core/dev.c
---- linux/net/core-w12/dev.c Wed Nov 7 14:39:36 2001
-+++ linux/net/core/dev.c Thu Jan 17 11:06:07 2002
-@@ -102,6 +102,7 @@
- #include <linux/module.h>
- #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
- #include <linux/wireless.h> /* Note : will define WIRELESS_EXT */
-+#include <net/iw_handler.h>
- #endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
- #ifdef CONFIG_PLIP
- extern int plip_init(void);
-@@ -1796,122 +1797,6 @@ static int dev_proc_stats(char *buffer,
- #endif /* CONFIG_PROC_FS */
-
-
--#ifdef WIRELESS_EXT
--#ifdef CONFIG_PROC_FS
--
--/*
-- * Print one entry of /proc/net/wireless
-- * This is a clone of /proc/net/dev (just above)
-- */
--static int sprintf_wireless_stats(char *buffer, struct net_device *dev)
--{
-- /* Get stats from the driver */
-- struct iw_statistics *stats = (dev->get_wireless_stats ?
-- dev->get_wireless_stats(dev) :
-- (struct iw_statistics *) NULL);
-- int size;
--
-- if (stats != (struct iw_statistics *) NULL) {
-- size = sprintf(buffer,
-- "%6s: %04x %3d%c %3d%c %3d%c %6d %6d %6d %6d %6d %6d\n",
-- dev->name,
-- stats->status,
-- stats->qual.qual,
-- stats->qual.updated & 1 ? '.' : ' ',
-- stats->qual.level,
-- stats->qual.updated & 2 ? '.' : ' ',
-- stats->qual.noise,
-- stats->qual.updated & 4 ? '.' : ' ',
-- stats->discard.nwid,
-- stats->discard.code,
-- stats->discard.fragment,
-- stats->discard.retries,
-- stats->discard.misc,
-- stats->miss.beacon);
-- stats->qual.updated = 0;
-- }
-- else
-- size = 0;
--
-- return size;
--}
--
--/*
-- * Print info for /proc/net/wireless (print all entries)
-- * This is a clone of /proc/net/dev (just above)
-- */
--static int dev_get_wireless_info(char * buffer, char **start, off_t offset,
-- int length)
--{
-- int len = 0;
-- off_t begin = 0;
-- off_t pos = 0;
-- int size;
--
-- struct net_device * dev;
--
-- size = sprintf(buffer,
-- "Inter-| sta-| Quality | Discarded packets | Missed\n"
-- " face | tus | link level noise | nwid crypt frag retry misc | beacon\n"
-- );
--
-- pos += size;
-- len += size;
--
-- read_lock(&dev_base_lock);
-- for (dev = dev_base; dev != NULL; dev = dev->next) {
-- size = sprintf_wireless_stats(buffer + len, dev);
-- len += size;
-- pos = begin + len;
--
-- if (pos < offset) {
-- len = 0;
-- begin = pos;
-- }
-- if (pos > offset + length)
-- break;
-- }
-- read_unlock(&dev_base_lock);
--
-- *start = buffer + (offset - begin); /* Start of wanted data */
-- len -= (offset - begin); /* Start slop */
-- if (len > length)
-- len = length; /* Ending slop */
-- if (len < 0)
-- len = 0;
--
-- return len;
--}
--#endif /* CONFIG_PROC_FS */
--
--/*
-- * Allow programatic access to /proc/net/wireless even if /proc
-- * doesn't exist... Also more efficient...
-- */
--static inline int dev_iwstats(struct net_device *dev, struct ifreq *ifr)
--{
-- /* Get stats from the driver */
-- struct iw_statistics *stats = (dev->get_wireless_stats ?
-- dev->get_wireless_stats(dev) :
-- (struct iw_statistics *) NULL);
--
-- if (stats != (struct iw_statistics *) NULL) {
-- struct iwreq * wrq = (struct iwreq *)ifr;
--
-- /* Copy statistics to the user buffer */
-- if(copy_to_user(wrq->u.data.pointer, stats,
-- sizeof(struct iw_statistics)))
-- return -EFAULT;
--
-- /* Check if we need to clear the update flag */
-- if(wrq->u.data.flags != 0)
-- stats->qual.updated = 0;
-- return(0);
-- } else
-- return -EOPNOTSUPP;
--}
--#endif /* WIRELESS_EXT */
--
- /**
- * netdev_set_master - set up master/slave pair
- * @slave: slave device
-@@ -2209,11 +2094,6 @@ static int dev_ifsioc(struct ifreq *ifr,
- notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev);
- return 0;
-
--#ifdef WIRELESS_EXT
-- case SIOCGIWSTATS:
-- return dev_iwstats(dev, ifr);
--#endif /* WIRELESS_EXT */
--
- /*
- * Unknown or private ioctl
- */
-@@ -2239,17 +2119,6 @@ static int dev_ifsioc(struct ifreq *ifr,
- return -EOPNOTSUPP;
- }
-
--#ifdef WIRELESS_EXT
-- if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
-- if (dev->do_ioctl) {
-- if (!netif_device_present(dev))
-- return -ENODEV;
-- return dev->do_ioctl(dev, ifr, cmd);
-- }
-- return -EOPNOTSUPP;
-- }
--#endif /* WIRELESS_EXT */
--
- }
- return -EINVAL;
- }
-@@ -2431,7 +2300,8 @@ int dev_ioctl(unsigned int cmd, void *ar
- }
- dev_load(ifr.ifr_name);
- rtnl_lock();
-- ret = dev_ifsioc(&ifr, cmd);
-+ /* Follow me in net/core/wireless.c */
-+ ret = wireless_process_ioctl(&ifr, cmd);
- rtnl_unlock();
- if (!ret && IW_IS_GET(cmd) &&
- copy_to_user(arg, &ifr, sizeof(struct ifreq)))
-@@ -2856,6 +2726,7 @@ int __init net_dev_init(void)
- proc_net_create("dev", 0, dev_get_info);
- create_proc_read_entry("net/softnet_stat", 0, 0, dev_proc_stats, NULL);
- #ifdef WIRELESS_EXT
-+ /* Available in net/core/wireless.c */
- proc_net_create("wireless", 0, dev_get_wireless_info);
- #endif /* WIRELESS_EXT */
- #endif /* CONFIG_PROC_FS */
-diff -u -p -r --new-file linux/net/core-w12/wireless.c linux/net/core/wireless.c
---- linux/net/core-w12/wireless.c Wed Dec 31 16:00:00 1969
-+++ linux/net/core/wireless.c Mon Jan 21 11:13:23 2002
-@@ -0,0 +1,733 @@
-+/*
-+ * This file implement the Wireless Extensions APIs.
-+ *
-+ * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-+ * Copyright (c) 1997-2001 Jean Tourrilhes, All Rights Reserved.
-+ *
-+ * (As all part of the Linux kernel, this file is GPL)
-+ */
-+
-+/************************** DOCUMENTATION **************************/
-+/*
-+ * API definition :
-+ * --------------
-+ * See <linux/wireless.h> for details of the APIs and the rest.
-+ *
-+ * History :
-+ * -------
-+ *
-+ * v1 - 5.12.01 - Jean II
-+ * o Created this file.
-+ *
-+ * v2 - 13.12.01 - Jean II
-+ * o Move /proc/net/wireless stuff from net/core/dev.c to here
-+ * o Make Wireless Extension IOCTLs go through here
-+ * o Added iw_handler handling ;-)
-+ * o Added standard ioctl description
-+ * o Initial dumb commit strategy based on orinoco.c
-+ */
-+
-+/***************************** INCLUDES *****************************/
-+
-+#include <asm/uaccess.h> /* copy_to_user() */
-+#include <linux/config.h> /* Not needed ??? */
-+#include <linux/types.h> /* off_t */
-+#include <linux/netdevice.h> /* struct ifreq, dev_get_by_name() */
-+
-+#include <linux/wireless.h> /* Pretty obvious */
-+#include <net/iw_handler.h> /* New driver API */
-+
-+/**************************** CONSTANTS ****************************/
-+
-+/* This will be turned on later on... */
-+#undef WE_STRICT_WRITE /* Check write buffer size */
-+
-+/* Debuging stuff */
-+#undef WE_IOCTL_DEBUG /* Debug IOCTL API */
-+
-+/************************* GLOBAL VARIABLES *************************/
-+/*
-+ * You should not use global variables, because or re-entrancy.
-+ * On our case, it's only const, so it's OK...
-+ */
-+static const struct iw_ioctl_description standard_ioctl[] = {
-+ /* SIOCSIWCOMMIT (internal) */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCGIWNAME */
-+ { IW_HEADER_TYPE_CHAR, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWNWID */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, IW_DESCR_FLAG_EVENT},
-+ /* SIOCGIWNWID */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWFREQ */
-+ { IW_HEADER_TYPE_FREQ, 0, 0, 0, 0, IW_DESCR_FLAG_EVENT},
-+ /* SIOCGIWFREQ */
-+ { IW_HEADER_TYPE_FREQ, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWMODE */
-+ { IW_HEADER_TYPE_UINT, 0, 0, 0, 0, IW_DESCR_FLAG_EVENT},
-+ /* SIOCGIWMODE */
-+ { IW_HEADER_TYPE_UINT, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWSENS */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWSENS */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWRANGE */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCGIWRANGE */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, sizeof(struct iw_range), IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWPRIV */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCGIWPRIV (handled directly by us) */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCSIWSTATS */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCGIWSTATS (handled directly by us) */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWSPY */
-+ { IW_HEADER_TYPE_POINT, 0, sizeof(struct sockaddr), 0, IW_MAX_SPY, 0},
-+ /* SIOCGIWSPY */
-+ { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_SPY, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCSIWAP */
-+ { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
-+ /* SIOCGIWAP */
-+ { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCGIWAPLIST */
-+ { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_AP, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCSIWESSID */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, IW_DESCR_FLAG_EVENT},
-+ /* SIOCGIWESSID */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, IW_DESCR_FLAG_DUMP},
-+ /* SIOCSIWNICKN */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, 0},
-+ /* SIOCGIWNICKN */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* -- hole -- */
-+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCSIWRATE */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWRATE */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWRTS */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWRTS */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWFRAG */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWFRAG */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWTXPOW */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWTXPOW */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWRETRY */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWRETRY */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCSIWENCODE */
-+ { IW_HEADER_TYPE_POINT, 4, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT},
-+ /* SIOCGIWENCODE */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_DUMP | IW_DESCR_FLAG_RESTRICT},
-+ /* SIOCSIWPOWER */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWPOWER */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+};
-+
-+/* Size (in bytes) of the various private data types */
-+char priv_type_size[] = { 0, 1, 1, 0, 4, 4, 0, 0 };
-+
-+/************************ COMMON SUBROUTINES ************************/
-+/*
-+ * Stuff that may be used in various place or doesn't fit in one
-+ * of the section below.
-+ */
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Return the driver handler associated with a specific Wireless Extension.
-+ * Called from various place, so make sure it remains efficient.
-+ */
-+static inline iw_handler get_handler(struct net_device *dev,
-+ unsigned int cmd)
-+{
-+ unsigned int index; /* MUST be unsigned */
-+
-+ /* Check if we have some wireless handlers defined */
-+ if(dev->wireless_handlers == NULL)
-+ return NULL;
-+
-+ /* Try as a standard command */
-+ index = cmd - SIOCIWFIRST;
-+ if(index < dev->wireless_handlers->num_standard)
-+ return dev->wireless_handlers->standard[index];
-+
-+ /* Try as a private command */
-+ index = cmd - SIOCIWFIRSTPRIV;
-+ if(index < dev->wireless_handlers->num_private)
-+ return dev->wireless_handlers->private[index];
-+
-+ /* Not found */
-+ return NULL;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Get statistics out of the driver
-+ */
-+static inline struct iw_statistics *get_wireless_stats(struct net_device *dev)
-+{
-+ return (dev->get_wireless_stats ?
-+ dev->get_wireless_stats(dev) :
-+ (struct iw_statistics *) NULL);
-+ /* In the future, get_wireless_stats may move from 'struct net_device'
-+ * to 'struct iw_handler_def', to de-bloat struct net_device.
-+ * Definitely worse a thought... */
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Call the commit handler in the driver
-+ * (if exist and if conditions are right)
-+ *
-+ * Note : our current commit strategy is currently pretty dumb,
-+ * but we will be able to improve on that...
-+ * The goal is to try to agreagate as many changes as possible
-+ * before doing the commit. Drivers that will define a commit handler
-+ * are usually those that need a reset after changing parameters, so
-+ * we want to minimise the number of reset.
-+ * A cool idea is to use a timer : at each "set" command, we re-set the
-+ * timer, when the timer eventually fires, we call the driver.
-+ * Hopefully, more on that later.
-+ *
-+ * Also, I'm waiting to see how many people will complain about the
-+ * netif_running(dev) test. I'm open on that one...
-+ * Hopefully, the driver will remember to do a commit in "open()" ;-)
-+ */
-+static inline int call_commit_handler(struct net_device * dev)
-+{
-+ if((netif_running(dev)) &&
-+ (dev->wireless_handlers->standard[0] != NULL)) {
-+ /* Call the commit handler on the driver */
-+ return dev->wireless_handlers->standard[0](dev, NULL,
-+ NULL, NULL);
-+ } else
-+ return 0; /* Command completed successfully */
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Number of private arguments
-+ */
-+static inline int get_priv_size(__u16 args)
-+{
-+ int num = args & IW_PRIV_SIZE_MASK;
-+ int type = (args & IW_PRIV_TYPE_MASK) >> 12;
-+
-+ return num * priv_type_size[type];
-+}
-+
-+
-+/******************** /proc/net/wireless SUPPORT ********************/
-+/*
-+ * The /proc/net/wireless file is a human readable user-space interface
-+ * exporting various wireless specific statistics from the wireless devices.
-+ * This is the most popular part of the Wireless Extensions ;-)
-+ *
-+ * This interface is a pure clone of /proc/net/dev (in net/core/dev.c).
-+ * The content of the file is basically the content of "struct iw_statistics".
-+ */
-+
-+#ifdef CONFIG_PROC_FS
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Print one entry (line) of /proc/net/wireless
-+ */
-+static inline int sprintf_wireless_stats(char *buffer, struct net_device *dev)
-+{
-+ /* Get stats from the driver */
-+ struct iw_statistics *stats;
-+ int size;
-+
-+ stats = get_wireless_stats(dev);
-+ if (stats != (struct iw_statistics *) NULL) {
-+ size = sprintf(buffer,
-+ "%6s: %04x %3d%c %3d%c %3d%c %6d %6d %6d %6d %6d %6d\n",
-+ dev->name,
-+ stats->status,
-+ stats->qual.qual,
-+ stats->qual.updated & 1 ? '.' : ' ',
-+ stats->qual.level,
-+ stats->qual.updated & 2 ? '.' : ' ',
-+ stats->qual.noise,
-+ stats->qual.updated & 4 ? '.' : ' ',
-+ stats->discard.nwid,
-+ stats->discard.code,
-+ stats->discard.fragment,
-+ stats->discard.retries,
-+ stats->discard.misc,
-+ stats->miss.beacon);
-+ stats->qual.updated = 0;
-+ }
-+ else
-+ size = 0;
-+
-+ return size;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Print info for /proc/net/wireless (print all entries)
-+ */
-+int dev_get_wireless_info(char * buffer, char **start, off_t offset,
-+ int length)
-+{
-+ int len = 0;
-+ off_t begin = 0;
-+ off_t pos = 0;
-+ int size;
-+
-+ struct net_device * dev;
-+
-+ size = sprintf(buffer,
-+ "Inter-| sta-| Quality | Discarded packets | Missed\n"
-+ " face | tus | link level noise | nwid crypt frag retry misc | beacon\n"
-+ );
-+
-+ pos += size;
-+ len += size;
-+
-+ read_lock(&dev_base_lock);
-+ for (dev = dev_base; dev != NULL; dev = dev->next) {
-+ size = sprintf_wireless_stats(buffer + len, dev);
-+ len += size;
-+ pos = begin + len;
-+
-+ if (pos < offset) {
-+ len = 0;
-+ begin = pos;
-+ }
-+ if (pos > offset + length)
-+ break;
-+ }
-+ read_unlock(&dev_base_lock);
-+
-+ *start = buffer + (offset - begin); /* Start of wanted data */
-+ len -= (offset - begin); /* Start slop */
-+ if (len > length)
-+ len = length; /* Ending slop */
-+ if (len < 0)
-+ len = 0;
-+
-+ return len;
-+}
-+#endif /* CONFIG_PROC_FS */
-+
-+/************************** IOCTL SUPPORT **************************/
-+/*
-+ * The original user space API to configure all those Wireless Extensions
-+ * is through IOCTLs.
-+ * In there, we check if we need to call the new driver API (iw_handler)
-+ * or just call the driver ioctl handler.
-+ */
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Allow programatic access to /proc/net/wireless even if /proc
-+ * doesn't exist... Also more efficient...
-+ */
-+static inline int dev_iwstats(struct net_device *dev, struct ifreq *ifr)
-+{
-+ /* Get stats from the driver */
-+ struct iw_statistics *stats;
-+
-+ stats = get_wireless_stats(dev);
-+ if (stats != (struct iw_statistics *) NULL) {
-+ struct iwreq * wrq = (struct iwreq *)ifr;
-+
-+ /* Copy statistics to the user buffer */
-+ if(copy_to_user(wrq->u.data.pointer, stats,
-+ sizeof(struct iw_statistics)))
-+ return -EFAULT;
-+
-+ /* Check if we need to clear the update flag */
-+ if(wrq->u.data.flags != 0)
-+ stats->qual.updated = 0;
-+ return 0;
-+ } else
-+ return -EOPNOTSUPP;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Export the driver private handler definition
-+ * They will be picked up by tools like iwpriv...
-+ */
-+static inline int ioctl_export_private(struct net_device * dev,
-+ struct ifreq * ifr)
-+{
-+ struct iwreq * iwr = (struct iwreq *) ifr;
-+
-+ /* Check if the driver has something to export */
-+ if((dev->wireless_handlers->num_private_args == 0) ||
-+ (dev->wireless_handlers->private_args == NULL))
-+ return -EOPNOTSUPP;
-+
-+ /* Check NULL pointer */
-+ if(iwr->u.data.pointer == NULL)
-+ return -EFAULT;
-+#ifdef WE_STRICT_WRITE
-+ /* Check if there is enough buffer up there */
-+ if(iwr->u.data.length < (SIOCIWLASTPRIV - SIOCIWFIRSTPRIV + 1))
-+ return -E2BIG;
-+#endif /* WE_STRICT_WRITE */
-+
-+ /* Set the number of available ioctls. */
-+ iwr->u.data.length = dev->wireless_handlers->num_private_args;
-+
-+ /* Copy structure to the user buffer. */
-+ if (copy_to_user(iwr->u.data.pointer,
-+ dev->wireless_handlers->private_args,
-+ sizeof(struct iw_priv_args) * iwr->u.data.length))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Wrapper to call a standard Wireless Extension handler.
-+ * We do various checks and also take care of moving data between
-+ * user space and kernel space.
-+ */
-+static inline int ioctl_standard_call(struct net_device * dev,
-+ struct ifreq * ifr,
-+ unsigned int cmd,
-+ iw_handler handler)
-+{
-+ struct iwreq * iwr = (struct iwreq *) ifr;
-+ const struct iw_ioctl_description * descr;
-+ struct iw_request_info info;
-+ int ret = -EINVAL;
-+
-+ /* Get the description of the IOCTL */
-+ descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
-+
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "%s : Found standard handler for 0x%04X\n",
-+ ifr->ifr_name, cmd);
-+ printk(KERN_DEBUG "Header type : %d, token type : %d, token_size : %d, max_token : %d\n", descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
-+#endif /* WE_IOCTL_DEBUG */
-+
-+ /* Prepare the call */
-+ info.cmd = cmd;
-+ info.flags = 0;
-+
-+ /* Check if we have a pointer to user space data or not */
-+ if(descr->header_type != IW_HEADER_TYPE_POINT) {
-+ /* No extra arguments. Trivial to handle */
-+ ret = handler(dev, &info, &(iwr->u), NULL);
-+ } else {
-+ char * extra;
-+ int err;
-+
-+ /* Check what user space is giving us */
-+ if(IW_IS_SET(cmd)) {
-+ /* Check NULL pointer */
-+ if((iwr->u.data.pointer == NULL) &&
-+ (iwr->u.data.length != 0))
-+ return -EFAULT;
-+ /* Check if number of token fits within bounds */
-+ if(iwr->u.data.length > descr->max_tokens)
-+ return -E2BIG;
-+ if(iwr->u.data.length < descr->min_tokens)
-+ return -EINVAL;
-+ } else {
-+ /* Check NULL pointer */
-+ if(iwr->u.data.pointer == NULL)
-+ return -EFAULT;
-+#ifdef WE_STRICT_WRITE
-+ /* Check if there is enough buffer up there */
-+ if(iwr->u.data.length < descr->max_tokens)
-+ return -E2BIG;
-+#endif /* WE_STRICT_WRITE */
-+ }
-+
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Malloc %d bytes\n",
-+ descr->max_tokens * descr->token_size);
-+#endif /* WE_IOCTL_DEBUG */
-+
-+ /* Always allocate for max space. Easier, and won't last
-+ * long... */
-+ extra = kmalloc(descr->max_tokens * descr->token_size,
-+ GFP_KERNEL);
-+ if (extra == NULL) {
-+ return -ENOMEM;
-+ }
-+
-+ /* If it is a SET, get all the extra data in here */
-+ if(IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
-+ err = copy_from_user(extra, iwr->u.data.pointer,
-+ iwr->u.data.length *
-+ descr->token_size);
-+ if (err) {
-+ kfree(extra);
-+ return -EFAULT;
-+ }
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Got %d bytes\n",
-+ iwr->u.data.length * descr->token_size);
-+#endif /* WE_IOCTL_DEBUG */
-+ }
-+
-+ /* Call the handler */
-+ ret = handler(dev, &info, &(iwr->u), extra);
-+
-+ /* If we have something to return to the user */
-+ if (!ret && IW_IS_GET(cmd)) {
-+ err = copy_to_user(iwr->u.data.pointer, extra,
-+ iwr->u.data.length *
-+ descr->token_size);
-+ if (err)
-+ ret = -EFAULT;
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Wrote %d bytes\n",
-+ iwr->u.data.length * descr->token_size);
-+#endif /* WE_IOCTL_DEBUG */
-+ }
-+
-+ /* Cleanup - I told you it wasn't that long ;-) */
-+ kfree(extra);
-+ }
-+
-+ /* Call commit handler if needed and defined */
-+ if(ret == -EIWCOMMIT)
-+ ret = call_commit_handler(dev);
-+
-+ /* Here, we will generate the appropriate event if needed */
-+
-+ return ret;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Wrapper to call a private Wireless Extension handler.
-+ * We do various checks and also take care of moving data between
-+ * user space and kernel space.
-+ * It's not as nice and slimline as the standard wrapper. The cause
-+ * is struct iw_priv_args, which was not really designed for the
-+ * job we are going here.
-+ *
-+ * IMPORTANT : This function prevent to set and get data on the same
-+ * IOCTL and enforce the SET/GET convention. Not doing it would be
-+ * far too hairy...
-+ * If you need to set and get data at the same time, please don't use
-+ * a iw_handler but process it in your ioctl handler (i.e. use the
-+ * old driver API).
-+ */
-+static inline int ioctl_private_call(struct net_device * dev,
-+ struct ifreq * ifr,
-+ unsigned int cmd,
-+ iw_handler handler)
-+{
-+ struct iwreq * iwr = (struct iwreq *) ifr;
-+ struct iw_priv_args * descr = NULL;
-+ struct iw_request_info info;
-+ int extra_size = 0;
-+ int i;
-+ int ret = -EINVAL;
-+
-+ /* Get the description of the IOCTL */
-+ for(i = 0; i < dev->wireless_handlers->num_private_args; i++)
-+ if(cmd == dev->wireless_handlers->private_args[i].cmd) {
-+ descr = &(dev->wireless_handlers->private_args[i]);
-+ break;
-+ }
-+
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "%s : Found private handler for 0x%04X\n",
-+ ifr->ifr_name, cmd);
-+ if(descr) {
-+ printk(KERN_DEBUG "Name %s, set %X, get %X\n",
-+ descr->name, descr->set_args, descr->get_args);
-+ }
-+#endif /* WE_IOCTL_DEBUG */
-+
-+ /* Compute the size of the set/get arguments */
-+ if(descr != NULL) {
-+ if(IW_IS_SET(cmd)) {
-+ /* Size of set arguments */
-+ extra_size = get_priv_size(descr->set_args);
-+
-+ /* Does it fits in iwr ? */
-+ if((descr->set_args & IW_PRIV_SIZE_FIXED) &&
-+ (extra_size < IFNAMSIZ))
-+ extra_size = 0;
-+ } else {
-+ /* Size of set arguments */
-+ extra_size = get_priv_size(descr->get_args);
-+
-+ /* Does it fits in iwr ? */
-+ if((descr->get_args & IW_PRIV_SIZE_FIXED) &&
-+ (extra_size < IFNAMSIZ))
-+ extra_size = 0;
-+ }
-+ }
-+
-+ /* Prepare the call */
-+ info.cmd = cmd;
-+ info.flags = 0;
-+
-+ /* Check if we have a pointer to user space data or not. */
-+ if(extra_size == 0) {
-+ /* No extra arguments. Trivial to handle */
-+ ret = handler(dev, &info, &(iwr->u), (char *) &(iwr->u));
-+ } else {
-+ char * extra;
-+ int err;
-+
-+ /* Check what user space is giving us */
-+ if(IW_IS_SET(cmd)) {
-+ /* Check NULL pointer */
-+ if((iwr->u.data.pointer == NULL) &&
-+ (iwr->u.data.length != 0))
-+ return -EFAULT;
-+
-+ /* Does it fits within bounds ? */
-+ if(iwr->u.data.length > (descr->set_args &
-+ IW_PRIV_SIZE_MASK))
-+ return -E2BIG;
-+ } else {
-+ /* Check NULL pointer */
-+ if(iwr->u.data.pointer == NULL)
-+ return -EFAULT;
-+ }
-+
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Malloc %d bytes\n", extra_size);
-+#endif /* WE_IOCTL_DEBUG */
-+
-+ /* Always allocate for max space. Easier, and won't last
-+ * long... */
-+ extra = kmalloc(extra_size, GFP_KERNEL);
-+ if (extra == NULL) {
-+ return -ENOMEM;
-+ }
-+
-+ /* If it is a SET, get all the extra data in here */
-+ if(IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
-+ err = copy_from_user(extra, iwr->u.data.pointer,
-+ extra_size);
-+ if (err) {
-+ kfree(extra);
-+ return -EFAULT;
-+ }
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Got %d elem\n", iwr->u.data.length);
-+#endif /* WE_IOCTL_DEBUG */
-+ }
-+
-+ /* Call the handler */
-+ ret = handler(dev, &info, &(iwr->u), extra);
-+
-+ /* If we have something to return to the user */
-+ if (!ret && IW_IS_GET(cmd)) {
-+ err = copy_to_user(iwr->u.data.pointer, extra,
-+ extra_size);
-+ if (err)
-+ ret = -EFAULT;
-+#ifdef WE_IOCTL_DEBUG
-+ printk(KERN_DEBUG "Wrote %d elem\n",
-+ iwr->u.data.length);
-+#endif /* WE_IOCTL_DEBUG */
-+ }
-+
-+ /* Cleanup - I told you it wasn't that long ;-) */
-+ kfree(extra);
-+ }
-+
-+
-+ /* Call commit handler if needed and defined */
-+ if(ret == -EIWCOMMIT)
-+ ret = call_commit_handler(dev);
-+
-+ return ret;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Main IOCTl dispatcher. Called from the main networking code
-+ * (dev_ioctl() in net/core/dev.c).
-+ * Check the type of IOCTL and call the appropriate wrapper...
-+ */
-+int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd)
-+{
-+ struct net_device *dev;
-+ iw_handler handler;
-+
-+ /* Permissions are already checked in dev_ioctl() before calling us.
-+ * The copy_to/from_user() of ifr is also dealt with in there */
-+
-+ /* Make sure the device exist */
-+ if ((dev = __dev_get_by_name(ifr->ifr_name)) == NULL)
-+ return -ENODEV;
-+
-+ /* A bunch of special cases, then the generic case...
-+ * Note that 'cmd' is already filtered in dev_ioctl() with
-+ * (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) */
-+ switch(cmd)
-+ {
-+ case SIOCGIWSTATS:
-+ /* Get Wireless Stats */
-+ return dev_iwstats(dev, ifr);
-+
-+ case SIOCGIWPRIV:
-+ /* Check if we have some wireless handlers defined */
-+ if(dev->wireless_handlers != NULL) {
-+ /* We export to user space the definition of
-+ * the private handler ourselves */
-+ return ioctl_export_private(dev, ifr);
-+ }
-+ // ## Fall-through for old API ##
-+ default:
-+ /* Generic IOCTL */
-+ /* Basic check */
-+ if (!netif_device_present(dev))
-+ return -ENODEV;
-+ /* New driver API : try to find the handler */
-+ handler = get_handler(dev, cmd);
-+ if(handler != NULL) {
-+ /* Standard and private are not the same */
-+ if(cmd < SIOCIWFIRSTPRIV)
-+ return ioctl_standard_call(dev,
-+ ifr,
-+ cmd,
-+ handler);
-+ else
-+ return ioctl_private_call(dev,
-+ ifr,
-+ cmd,
-+ handler);
-+ }
-+ /* Old driver API : call driver ioctl handler */
-+ if (dev->do_ioctl) {
-+ return dev->do_ioctl(dev, ifr, cmd);
-+ }
-+ return -EOPNOTSUPP;
-+ }
-+ /* Not reached */
-+ return -EINVAL;
-+}
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/iw_handlers.w14-5.diff b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/iw_handlers.w14-5.diff
deleted file mode 100644
index 539b160068..0000000000
--- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/iw_handlers.w14-5.diff
+++ /dev/null
@@ -1,838 +0,0 @@
-diff -u -p -r --new-file linux/include/linux-w13/rtnetlink.h linux/include/linux/rtnetlink.h
---- linux/include/linux-w13/rtnetlink.h Thu Jun 6 14:44:08 2002
-+++ linux/include/linux/rtnetlink.h Thu Jun 6 15:47:44 2002
-@@ -440,12 +440,14 @@ enum
- #define IFLA_COST IFLA_COST
- IFLA_PRIORITY,
- #define IFLA_PRIORITY IFLA_PRIORITY
-- IFLA_MASTER
-+ IFLA_MASTER,
- #define IFLA_MASTER IFLA_MASTER
-+ IFLA_WIRELESS, /* Wireless Extension event - see wireless.h */
-+#define IFLA_WIRELESS IFLA_WIRELESS
- };
-
-
--#define IFLA_MAX IFLA_MASTER
-+#define IFLA_MAX IFLA_WIRELESS
-
- #define IFLA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
- #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
-diff -u -p -r --new-file linux/include/linux-w13/wireless.h linux/include/linux/wireless.h
---- linux/include/linux-w13/wireless.h Thu Jun 6 15:00:28 2002
-+++ linux/include/linux/wireless.h Thu Jun 6 15:47:44 2002
-@@ -1,10 +1,10 @@
- /*
- * This file define a set of standard wireless extensions
- *
-- * Version : 13 6.12.01
-+ * Version : 14 25.1.02
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-- * Copyright (c) 1997-2001 Jean Tourrilhes, All Rights Reserved.
-+ * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
- */
-
- #ifndef _LINUX_WIRELESS_H
-@@ -40,7 +40,7 @@
- * # include/linux/netdevice.h (one place)
- * # include/linux/proc_fs.h (one place)
- *
-- * New driver API (2001 -> onward) :
-+ * New driver API (2002 -> onward) :
- * -------------------------------
- * This file is only concerned with the user space API and common definitions.
- * The new driver API is defined and documented in :
-@@ -49,6 +49,11 @@
- * Note as well that /proc/net/wireless implementation has now moved in :
- * # include/linux/wireless.c
- *
-+ * Wireless Events (2002 -> onward) :
-+ * --------------------------------
-+ * Events are defined at the end of this file, and implemented in :
-+ * # include/linux/wireless.c
-+ *
- * Other comments :
- * --------------
- * Do not add here things that are redundant with other mechanisms
-@@ -75,7 +80,7 @@
- * (there is some stuff that will be added in the future...)
- * I just plan to increment with each new version.
- */
--#define WIRELESS_EXT 13
-+#define WIRELESS_EXT 14
-
- /*
- * Changes :
-@@ -141,6 +146,13 @@
- * - Document creation of new driver API.
- * - Extract union iwreq_data from struct iwreq (for new driver API).
- * - Rename SIOCSIWNAME as SIOCSIWCOMMIT
-+ *
-+ * V13 to V14
-+ * ----------
-+ * - Wireless Events support : define struct iw_event
-+ * - Define additional specific event numbers
-+ * - Add "addr" and "param" fields in union iwreq_data
-+ * - AP scanning stuff (SIOCSIWSCAN and friends)
- */
-
- /**************************** CONSTANTS ****************************/
-@@ -175,6 +187,8 @@
- #define SIOCSIWAP 0x8B14 /* set access point MAC addresses */
- #define SIOCGIWAP 0x8B15 /* get access point MAC addresses */
- #define SIOCGIWAPLIST 0x8B17 /* get list of access point in range */
-+#define SIOCSIWSCAN 0x8B18 /* trigger scanning */
-+#define SIOCGIWSCAN 0x8B19 /* get scanning results */
-
- /* 802.11 specific support */
- #define SIOCSIWESSID 0x8B1A /* set ESSID (network name) */
-@@ -238,6 +252,15 @@
- #define IW_IS_SET(cmd) (!((cmd) & 0x1))
- #define IW_IS_GET(cmd) ((cmd) & 0x1)
-
-+/* ----------------------- WIRELESS EVENTS ----------------------- */
-+/* Those are *NOT* ioctls, do not issue request on them !!! */
-+/* Most events use the same identifier as ioctl requests */
-+
-+#define IWEVTXDROP 0x8C00 /* Packet dropped to excessive retry */
-+#define IWEVQUAL 0x8C01 /* Quality part of statistics */
-+
-+#define IWEVFIRST 0x8C00
-+
- /* ------------------------- PRIVATE INFO ------------------------- */
- /*
- * The following is used with SIOCGIWPRIV. It allow a driver to define
-@@ -340,6 +363,19 @@
- #define IW_RETRY_MAX 0x0002 /* Value is a maximum */
- #define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */
-
-+/* Scanning request flags */
-+#define IW_SCAN_DEFAULT 0x0000 /* Default scan of the driver */
-+#define IW_SCAN_ALL_ESSID 0x0001 /* Scan all ESSIDs */
-+#define IW_SCAN_THIS_ESSID 0x0002 /* Scan only this ESSID */
-+#define IW_SCAN_ALL_FREQ 0x0004 /* Scan all Frequencies */
-+#define IW_SCAN_THIS_FREQ 0x0008 /* Scan only this Frequency */
-+#define IW_SCAN_ALL_MODE 0x0010 /* Scan all Modes */
-+#define IW_SCAN_THIS_MODE 0x0020 /* Scan only this Mode */
-+#define IW_SCAN_ALL_RATE 0x0040 /* Scan all Bit-Rates */
-+#define IW_SCAN_THIS_RATE 0x0080 /* Scan only this Bit-Rate */
-+/* Maximum size of returned data */
-+#define IW_SCAN_MAX_DATA 4096 /* In bytes */
-+
- /****************************** TYPES ******************************/
-
- /* --------------------------- SUBTYPES --------------------------- */
-@@ -466,9 +502,12 @@ union iwreq_data
-
- struct iw_point encoding; /* Encoding stuff : tokens */
- struct iw_param power; /* PM duration/timeout */
-+ struct iw_quality qual; /* Quality part of statistics */
-
- struct sockaddr ap_addr; /* Access point address */
-+ struct sockaddr addr; /* Destination address (hw) */
-
-+ struct iw_param param; /* Other small parameters */
- struct iw_point data; /* Other large parameters */
- };
-
-@@ -595,5 +634,36 @@ struct iw_priv_args
- __u16 get_args; /* Type and number of args */
- char name[IFNAMSIZ]; /* Name of the extension */
- };
-+
-+/* ----------------------- WIRELESS EVENTS ----------------------- */
-+/*
-+ * Wireless events are carried through the rtnetlink socket to user
-+ * space. They are encapsulated in the IFLA_WIRELESS field of
-+ * a RTM_NEWLINK message.
-+ */
-+
-+/*
-+ * A Wireless Event. Contains basically the same data as the ioctl...
-+ */
-+struct iw_event
-+{
-+ __u16 len; /* Real lenght of this stuff */
-+ __u16 cmd; /* Wireless IOCTL */
-+ union iwreq_data u; /* IOCTL fixed payload */
-+};
-+
-+/* Size of the Event prefix (including padding and alignement junk) */
-+#define IW_EV_LCP_LEN (sizeof(struct iw_event) - sizeof(union iwreq_data))
-+/* Size of the various events */
-+#define IW_EV_CHAR_LEN (IW_EV_LCP_LEN + IFNAMSIZ)
-+#define IW_EV_UINT_LEN (IW_EV_LCP_LEN + sizeof(__u32))
-+#define IW_EV_FREQ_LEN (IW_EV_LCP_LEN + sizeof(struct iw_freq))
-+#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point))
-+#define IW_EV_PARAM_LEN (IW_EV_LCP_LEN + sizeof(struct iw_param))
-+#define IW_EV_ADDR_LEN (IW_EV_LCP_LEN + sizeof(struct sockaddr))
-+#define IW_EV_QUAL_LEN (IW_EV_LCP_LEN + sizeof(struct iw_quality))
-+
-+/* Note : in the case of iw_point, the extra data will come at the
-+ * end of the event */
-
- #endif /* _LINUX_WIRELESS_H */
-diff -u -p -r --new-file linux/include/net-w13/iw_handler.h linux/include/net/iw_handler.h
---- linux/include/net-w13/iw_handler.h Thu Jun 6 15:06:16 2002
-+++ linux/include/net/iw_handler.h Thu Jun 6 15:48:06 2002
-@@ -1,10 +1,10 @@
- /*
- * This file define the new driver API for Wireless Extensions
- *
-- * Version : 2 6.12.01
-+ * Version : 3 17.1.02
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-- * Copyright (c) 2001 Jean Tourrilhes, All Rights Reserved.
-+ * Copyright (c) 2001-2002 Jean Tourrilhes, All Rights Reserved.
- */
-
- #ifndef _IW_HANDLER_H
-@@ -33,7 +33,7 @@
- * o The user space interface is tied to ioctl because of the use
- * copy_to/from_user.
- *
-- * New driver API (2001 -> onward) :
-+ * New driver API (2002 -> onward) :
- * -------------------------------
- * The new driver API is just a bunch of standard functions (handlers),
- * each handling a specific Wireless Extension. The driver just export
-@@ -206,7 +206,18 @@
- * will be needed...
- * I just plan to increment with each new version.
- */
--#define IW_HANDLER_VERSION 2
-+#define IW_HANDLER_VERSION 3
-+
-+/*
-+ * Changes :
-+ *
-+ * V2 to V3
-+ * --------
-+ * - Move event definition in <linux/wireless.h>
-+ * - Add Wireless Event support :
-+ * o wireless_send_event() prototype
-+ * o iwe_stream_add_event/point() inline functions
-+ */
-
- /**************************** CONSTANTS ****************************/
-
-@@ -225,6 +236,7 @@
- #define IW_HEADER_TYPE_POINT 6 /* struct iw_point */
- #define IW_HEADER_TYPE_PARAM 7 /* struct iw_param */
- #define IW_HEADER_TYPE_ADDR 8 /* struct sockaddr */
-+#define IW_HEADER_TYPE_QUAL 9 /* struct iw_quality */
-
- /* Handling flags */
- /* Most are not implemented. I just use them as a reminder of some
-@@ -233,7 +245,8 @@
- /* Wrapper level flags */
- #define IW_DESCR_FLAG_DUMP 0x0001 /* Not part of the dump command */
- #define IW_DESCR_FLAG_EVENT 0x0002 /* Generate an event on SET */
--#define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET request is ROOT only */
-+#define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET : request is ROOT only */
-+ /* SET : Omit payload from generated iwevent */
- /* Driver level flags */
- #define IW_DESCR_FLAG_WAIT 0x0100 /* Wait for driver event */
-
-@@ -303,25 +316,6 @@ struct iw_handler_def
- * 'struct net_device' to here, to minimise bloat. */
- };
-
--/* ----------------------- WIRELESS EVENTS ----------------------- */
--/*
-- * Currently we don't support events, so let's just plan for the
-- * future...
-- */
--
--/*
-- * A Wireless Event.
-- */
--// How do we define short header ? We don't want a flag on length.
--// Probably a flag on event ? Highest bit to zero...
--struct iw_event
--{
-- __u16 length; /* Lenght of this stuff */
-- __u16 event; /* Wireless IOCTL */
-- union iwreq_data header; /* IOCTL fixed payload */
-- char extra[0]; /* Optional IOCTL data */
--};
--
- /* ---------------------- IOCTL DESCRIPTION ---------------------- */
- /*
- * One of the main goal of the new interface is to deal entirely with
-@@ -369,6 +363,88 @@ extern int dev_get_wireless_info(char *
- extern int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd);
-
- /* Second : functions that may be called by driver modules */
--/* None yet */
-
--#endif /* _LINUX_WIRELESS_H */
-+/* Send a single event to user space */
-+extern void wireless_send_event(struct net_device * dev,
-+ unsigned int cmd,
-+ union iwreq_data * wrqu,
-+ char * extra);
-+
-+/* We may need a function to send a stream of events to user space.
-+ * More on that later... */
-+
-+/************************* INLINE FUNTIONS *************************/
-+/*
-+ * Function that are so simple that it's more efficient inlining them
-+ */
-+
-+/*------------------------------------------------------------------*/
-+/*
-+ * Wrapper to add an Wireless Event to a stream of events.
-+ */
-+static inline char *
-+iwe_stream_add_event(char * stream, /* Stream of events */
-+ char * ends, /* End of stream */
-+ struct iw_event *iwe, /* Payload */
-+ int event_len) /* Real size of payload */
-+{
-+ /* Check if it's possible */
-+ if((stream + event_len) < ends) {
-+ iwe->len = event_len;
-+ memcpy(stream, (char *) iwe, event_len);
-+ stream += event_len;
-+ }
-+ return stream;
-+}
-+
-+/*------------------------------------------------------------------*/
-+/*
-+ * Wrapper to add an short Wireless Event containing a pointer to a
-+ * stream of events.
-+ */
-+static inline char *
-+iwe_stream_add_point(char * stream, /* Stream of events */
-+ char * ends, /* End of stream */
-+ struct iw_event *iwe, /* Payload */
-+ char * extra)
-+{
-+ int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
-+ /* Check if it's possible */
-+ if((stream + event_len) < ends) {
-+ iwe->len = event_len;
-+ memcpy(stream, (char *) iwe, IW_EV_POINT_LEN);
-+ memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
-+ stream += event_len;
-+ }
-+ return stream;
-+}
-+
-+/*------------------------------------------------------------------*/
-+/*
-+ * Wrapper to add a value to a Wireless Event in a stream of events.
-+ * Be careful, this one is tricky to use properly :
-+ * At the first run, you need to have (value = event + IW_EV_LCP_LEN).
-+ */
-+static inline char *
-+iwe_stream_add_value(char * event, /* Event in the stream */
-+ char * value, /* Value in event */
-+ char * ends, /* End of stream */
-+ struct iw_event *iwe, /* Payload */
-+ int event_len) /* Real size of payload */
-+{
-+ /* Don't duplicate LCP */
-+ event_len -= IW_EV_LCP_LEN;
-+
-+ /* Check if it's possible */
-+ if((value + event_len) < ends) {
-+ /* Add new value */
-+ memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
-+ value += event_len;
-+ /* Patch LCP */
-+ iwe->len = value - event;
-+ memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
-+ }
-+ return value;
-+}
-+
-+#endif /* _IW_HANDLER_H */
-diff -u -p -r --new-file linux/net/netsyms-w13.c linux/net/netsyms.c
---- linux/net/netsyms-w13.c Thu Jun 6 15:46:34 2002
-+++ linux/net/netsyms.c Thu Jun 6 15:47:44 2002
-@@ -588,4 +588,10 @@ EXPORT_SYMBOL(register_gifconf);
- EXPORT_SYMBOL(net_call_rx_atomic);
- EXPORT_SYMBOL(softnet_data);
-
-+#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
-+/* Don't include the whole header mess for a single function */
-+extern void wireless_send_event(struct net_device *dev, unsigned int cmd, union iwreq_data *wrqu, char *extra);
-+EXPORT_SYMBOL(wireless_send_event);
-+#endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
-+
- #endif /* CONFIG_NET */
-diff -u -p -r --new-file linux/net/core/wireless-w13.c linux/net/core/wireless.c
---- linux/net/core/wireless-w13.c Thu Jun 6 15:46:45 2002
-+++ linux/net/core/wireless.c Thu Jun 6 15:48:06 2002
-@@ -2,7 +2,7 @@
- * This file implement the Wireless Extensions APIs.
- *
- * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
-- * Copyright (c) 1997-2001 Jean Tourrilhes, All Rights Reserved.
-+ * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
- *
- * (As all part of the Linux kernel, this file is GPL)
- */
-@@ -25,6 +25,16 @@
- * o Added iw_handler handling ;-)
- * o Added standard ioctl description
- * o Initial dumb commit strategy based on orinoco.c
-+ *
-+ * v3 - 19.12.01 - Jean II
-+ * o Make sure we don't go out of standard_ioctl[] in ioctl_standard_call
-+ * o Add event dispatcher function
-+ * o Add event description
-+ * o Propagate events as rtnetlink IFLA_WIRELESS option
-+ * o Generate event on selected SET requests
-+ *
-+ * v4 - 18.04.01 - Jean II
-+ * o Fix stupid off by one in iw_ioctl_description : IW_ESSID_MAX_SIZE + 1
- */
-
- /***************************** INCLUDES *****************************/
-@@ -33,6 +43,7 @@
- #include <linux/config.h> /* Not needed ??? */
- #include <linux/types.h> /* off_t */
- #include <linux/netdevice.h> /* struct ifreq, dev_get_by_name() */
-+#include <linux/rtnetlink.h> /* rtnetlink stuff */
-
- #include <linux/wireless.h> /* Pretty obvious */
- #include <net/iw_handler.h> /* New driver API */
-@@ -44,14 +55,23 @@
-
- /* Debuging stuff */
- #undef WE_IOCTL_DEBUG /* Debug IOCTL API */
-+#undef WE_EVENT_DEBUG /* Debug Event dispatcher */
-+
-+/* Options */
-+#define WE_EVENT_NETLINK /* Propagate events using rtnetlink */
-+#define WE_SET_EVENT /* Generate an event on some set commands */
-
- /************************* GLOBAL VARIABLES *************************/
- /*
- * You should not use global variables, because or re-entrancy.
- * On our case, it's only const, so it's OK...
- */
-+/*
-+ * Meta-data about all the standard Wireless Extension request we
-+ * know about.
-+ */
- static const struct iw_ioctl_description standard_ioctl[] = {
-- /* SIOCSIWCOMMIT (internal) */
-+ /* SIOCSIWCOMMIT */
- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
- /* SIOCGIWNAME */
- { IW_HEADER_TYPE_CHAR, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP},
-@@ -99,18 +119,18 @@ static const struct iw_ioctl_description
- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
- /* SIOCGIWAPLIST */
- { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_AP, 0},
-- /* -- hole -- */
-- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-- /* -- hole -- */
-- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
-+ /* SIOCSIWSCAN */
-+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
-+ /* SIOCGIWSCAN */
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_SCAN_MAX_DATA, 0},
- /* SIOCSIWESSID */
-- { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, IW_DESCR_FLAG_EVENT},
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, IW_DESCR_FLAG_EVENT},
- /* SIOCGIWESSID */
-- { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, IW_DESCR_FLAG_DUMP},
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, IW_DESCR_FLAG_DUMP},
- /* SIOCSIWNICKN */
-- { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, 0},
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, 0},
- /* SIOCGIWNICKN */
-- { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE, 0},
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, 0},
- /* -- hole -- */
- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
- /* -- hole -- */
-@@ -136,7 +156,7 @@ static const struct iw_ioctl_description
- /* SIOCGIWRETRY */
- { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
- /* SIOCSIWENCODE */
-- { IW_HEADER_TYPE_POINT, 4, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT},
-+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT},
- /* SIOCGIWENCODE */
- { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ENCODING_TOKEN_MAX, IW_DESCR_FLAG_DUMP | IW_DESCR_FLAG_RESTRICT},
- /* SIOCSIWPOWER */
-@@ -144,9 +164,38 @@ static const struct iw_ioctl_description
- /* SIOCGIWPOWER */
- { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0},
- };
-+static const int standard_ioctl_num = (sizeof(standard_ioctl) /
-+ sizeof(struct iw_ioctl_description));
-+
-+/*
-+ * Meta-data about all the additional standard Wireless Extension events
-+ * we know about.
-+ */
-+static const struct iw_ioctl_description standard_event[] = {
-+ /* IWEVTXDROP */
-+ { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
-+ /* IWEVQUAL */
-+ { IW_HEADER_TYPE_QUAL, 0, 0, 0, 0, 0},
-+};
-+static const int standard_event_num = (sizeof(standard_event) /
-+ sizeof(struct iw_ioctl_description));
-
- /* Size (in bytes) of the various private data types */
--char priv_type_size[] = { 0, 1, 1, 0, 4, 4, 0, 0 };
-+static const char priv_type_size[] = { 0, 1, 1, 0, 4, 4, 0, 0 };
-+
-+/* Size (in bytes) of various events */
-+static const int event_type_size[] = {
-+ IW_EV_LCP_LEN,
-+ 0,
-+ IW_EV_CHAR_LEN,
-+ 0,
-+ IW_EV_UINT_LEN,
-+ IW_EV_FREQ_LEN,
-+ IW_EV_POINT_LEN, /* Without variable payload */
-+ IW_EV_PARAM_LEN,
-+ IW_EV_ADDR_LEN,
-+ IW_EV_QUAL_LEN,
-+};
-
- /************************ COMMON SUBROUTINES ************************/
- /*
-@@ -162,7 +211,8 @@ char priv_type_size[] = { 0, 1, 1, 0, 4,
- static inline iw_handler get_handler(struct net_device *dev,
- unsigned int cmd)
- {
-- unsigned int index; /* MUST be unsigned */
-+ /* Don't "optimise" the following variable, it will crash */
-+ unsigned int index; /* *MUST* be unsigned */
-
- /* Check if we have some wireless handlers defined */
- if(dev->wireless_handlers == NULL)
-@@ -269,9 +319,9 @@ static inline int sprintf_wireless_stats
- stats->status,
- stats->qual.qual,
- stats->qual.updated & 1 ? '.' : ' ',
-- stats->qual.level,
-+ ((__u8) stats->qual.level),
- stats->qual.updated & 2 ? '.' : ' ',
-- stats->qual.noise,
-+ ((__u8) stats->qual.noise),
- stats->qual.updated & 4 ? '.' : ' ',
- stats->discard.nwid,
- stats->discard.code,
-@@ -423,12 +473,14 @@ static inline int ioctl_standard_call(st
- int ret = -EINVAL;
-
- /* Get the description of the IOCTL */
-+ if((cmd - SIOCIWFIRST) >= standard_ioctl_num)
-+ return -EOPNOTSUPP;
- descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
-
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "%s : Found standard handler for 0x%04X\n",
-+ printk(KERN_DEBUG "%s (WE) : Found standard handler for 0x%04X\n",
- ifr->ifr_name, cmd);
-- printk(KERN_DEBUG "Header type : %d, token type : %d, token_size : %d, max_token : %d\n", descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
-+ printk(KERN_DEBUG "%s (WE) : Header type : %d, Token type : %d, size : %d, token : %d\n", dev->name, descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
- #endif /* WE_IOCTL_DEBUG */
-
- /* Prepare the call */
-@@ -437,8 +489,16 @@ static inline int ioctl_standard_call(st
-
- /* Check if we have a pointer to user space data or not */
- if(descr->header_type != IW_HEADER_TYPE_POINT) {
-+
- /* No extra arguments. Trivial to handle */
- ret = handler(dev, &info, &(iwr->u), NULL);
-+
-+#ifdef WE_SET_EVENT
-+ /* Generate an event to notify listeners of the change */
-+ if((descr->flags & IW_DESCR_FLAG_EVENT) &&
-+ ((ret == 0) || (ret == -EIWCOMMIT)))
-+ wireless_send_event(dev, cmd, &(iwr->u), NULL);
-+#endif /* WE_SET_EVENT */
- } else {
- char * extra;
- int err;
-@@ -466,8 +526,8 @@ static inline int ioctl_standard_call(st
- }
-
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Malloc %d bytes\n",
-- descr->max_tokens * descr->token_size);
-+ printk(KERN_DEBUG "%s (WE) : Malloc %d bytes\n",
-+ dev->name, descr->max_tokens * descr->token_size);
- #endif /* WE_IOCTL_DEBUG */
-
- /* Always allocate for max space. Easier, and won't last
-@@ -488,7 +548,8 @@ static inline int ioctl_standard_call(st
- return -EFAULT;
- }
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Got %d bytes\n",
-+ printk(KERN_DEBUG "%s (WE) : Got %d bytes\n",
-+ dev->name,
- iwr->u.data.length * descr->token_size);
- #endif /* WE_IOCTL_DEBUG */
- }
-@@ -504,11 +565,26 @@ static inline int ioctl_standard_call(st
- if (err)
- ret = -EFAULT;
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Wrote %d bytes\n",
-+ printk(KERN_DEBUG "%s (WE) : Wrote %d bytes\n",
-+ dev->name,
- iwr->u.data.length * descr->token_size);
- #endif /* WE_IOCTL_DEBUG */
- }
-
-+#ifdef WE_SET_EVENT
-+ /* Generate an event to notify listeners of the change */
-+ if((descr->flags & IW_DESCR_FLAG_EVENT) &&
-+ ((ret == 0) || (ret == -EIWCOMMIT))) {
-+ if(descr->flags & IW_DESCR_FLAG_RESTRICT)
-+ /* If the event is restricted, don't
-+ * export the payload */
-+ wireless_send_event(dev, cmd, &(iwr->u), NULL);
-+ else
-+ wireless_send_event(dev, cmd, &(iwr->u),
-+ extra);
-+ }
-+#endif /* WE_SET_EVENT */
-+
- /* Cleanup - I told you it wasn't that long ;-) */
- kfree(extra);
- }
-@@ -558,11 +634,12 @@ static inline int ioctl_private_call(str
- }
-
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "%s : Found private handler for 0x%04X\n",
-+ printk(KERN_DEBUG "%s (WE) : Found private handler for 0x%04X\n",
- ifr->ifr_name, cmd);
- if(descr) {
-- printk(KERN_DEBUG "Name %s, set %X, get %X\n",
-- descr->name, descr->set_args, descr->get_args);
-+ printk(KERN_DEBUG "%s (WE) : Name %s, set %X, get %X\n",
-+ dev->name, descr->name,
-+ descr->set_args, descr->get_args);
- }
- #endif /* WE_IOCTL_DEBUG */
-
-@@ -617,7 +694,8 @@ static inline int ioctl_private_call(str
- }
-
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Malloc %d bytes\n", extra_size);
-+ printk(KERN_DEBUG "%s (WE) : Malloc %d bytes\n",
-+ dev->name, extra_size);
- #endif /* WE_IOCTL_DEBUG */
-
- /* Always allocate for max space. Easier, and won't last
-@@ -636,7 +714,8 @@ static inline int ioctl_private_call(str
- return -EFAULT;
- }
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Got %d elem\n", iwr->u.data.length);
-+ printk(KERN_DEBUG "%s (WE) : Got %d elem\n",
-+ dev->name, iwr->u.data.length);
- #endif /* WE_IOCTL_DEBUG */
- }
-
-@@ -650,8 +729,8 @@ static inline int ioctl_private_call(str
- if (err)
- ret = -EFAULT;
- #ifdef WE_IOCTL_DEBUG
-- printk(KERN_DEBUG "Wrote %d elem\n",
-- iwr->u.data.length);
-+ printk(KERN_DEBUG "%s (WE) : Wrote %d elem\n",
-+ dev->name, iwr->u.data.length);
- #endif /* WE_IOCTL_DEBUG */
- }
-
-@@ -730,4 +809,178 @@ int wireless_process_ioctl(struct ifreq
- }
- /* Not reached */
- return -EINVAL;
-+}
-+
-+/************************* EVENT PROCESSING *************************/
-+/*
-+ * Process events generated by the wireless layer or the driver.
-+ * Most often, the event will be propagated through rtnetlink
-+ */
-+
-+#ifdef WE_EVENT_NETLINK
-+/* "rtnl" is defined in net/core/rtnetlink.c, but we need it here.
-+ * It is declared in <linux/rtnetlink.h> */
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Fill a rtnetlink message with our event data.
-+ * Note that we propage only the specified event and don't dump the
-+ * current wireless config. Dumping the wireless config is far too
-+ * expensive (for each parameter, the driver need to query the hardware).
-+ */
-+static inline int rtnetlink_fill_iwinfo(struct sk_buff * skb,
-+ struct net_device * dev,
-+ int type,
-+ char * event,
-+ int event_len)
-+{
-+ struct ifinfomsg *r;
-+ struct nlmsghdr *nlh;
-+ unsigned char *b = skb->tail;
-+
-+ nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(*r));
-+ r = NLMSG_DATA(nlh);
-+ r->ifi_family = AF_UNSPEC;
-+ r->ifi_type = dev->type;
-+ r->ifi_index = dev->ifindex;
-+ r->ifi_flags = dev->flags;
-+ r->ifi_change = 0; /* Wireless changes don't affect those flags */
-+
-+ /* Add the wireless events in the netlink packet */
-+ RTA_PUT(skb, IFLA_WIRELESS,
-+ event_len, event);
-+
-+ nlh->nlmsg_len = skb->tail - b;
-+ return skb->len;
-+
-+nlmsg_failure:
-+rtattr_failure:
-+ skb_trim(skb, b - skb->data);
-+ return -1;
-+}
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Create and broadcast and send it on the standard rtnetlink socket
-+ * This is a pure clone rtmsg_ifinfo() in net/core/rtnetlink.c
-+ * Andrzej Krzysztofowicz mandated that I used a IFLA_XXX field
-+ * within a RTM_NEWLINK event.
-+ */
-+static inline void rtmsg_iwinfo(struct net_device * dev,
-+ char * event,
-+ int event_len)
-+{
-+ struct sk_buff *skb;
-+ int size = NLMSG_GOODSIZE;
-+
-+ skb = alloc_skb(size, GFP_ATOMIC);
-+ if (!skb)
-+ return;
-+
-+ if (rtnetlink_fill_iwinfo(skb, dev, RTM_NEWLINK,
-+ event, event_len) < 0) {
-+ kfree_skb(skb);
-+ return;
-+ }
-+ NETLINK_CB(skb).dst_groups = RTMGRP_LINK;
-+ netlink_broadcast(rtnl, skb, 0, RTMGRP_LINK, GFP_ATOMIC);
-+}
-+#endif /* WE_EVENT_NETLINK */
-+
-+/* ---------------------------------------------------------------- */
-+/*
-+ * Main event dispatcher. Called from other parts and drivers.
-+ * Send the event on the apropriate channels.
-+ * May be called from interrupt context.
-+ */
-+void wireless_send_event(struct net_device * dev,
-+ unsigned int cmd,
-+ union iwreq_data * wrqu,
-+ char * extra)
-+{
-+ const struct iw_ioctl_description * descr = NULL;
-+ int extra_len = 0;
-+ struct iw_event *event; /* Mallocated whole event */
-+ int event_len; /* Its size */
-+ int hdr_len; /* Size of the event header */
-+ /* Don't "optimise" the following variable, it will crash */
-+ unsigned cmd_index; /* *MUST* be unsigned */
-+
-+ /* Get the description of the IOCTL */
-+ if(cmd <= SIOCIWLAST) {
-+ cmd_index = cmd - SIOCIWFIRST;
-+ if(cmd_index < standard_ioctl_num)
-+ descr = &(standard_ioctl[cmd_index]);
-+ } else {
-+ cmd_index = cmd - IWEVFIRST;
-+ if(cmd_index < standard_event_num)
-+ descr = &(standard_event[cmd_index]);
-+ }
-+ /* Don't accept unknown events */
-+ if(descr == NULL) {
-+ /* Note : we don't return an error to the driver, because
-+ * the driver would not know what to do about it. It can't
-+ * return an error to the user, because the event is not
-+ * initiated by a user request.
-+ * The best the driver could do is to log an error message.
-+ * We will do it ourselves instead...
-+ */
-+ printk(KERN_ERR "%s (WE) : Invalid Wireless Event (0x%04X)\n",
-+ dev->name, cmd);
-+ return;
-+ }
-+#ifdef WE_EVENT_DEBUG
-+ printk(KERN_DEBUG "%s (WE) : Got event 0x%04X\n",
-+ dev->name, cmd);
-+ printk(KERN_DEBUG "%s (WE) : Header type : %d, Token type : %d, size : %d, token : %d\n", dev->name, descr->header_type, descr->token_type, descr->token_size, descr->max_tokens);
-+#endif /* WE_EVENT_DEBUG */
-+
-+ /* Check extra parameters and set extra_len */
-+ if(descr->header_type == IW_HEADER_TYPE_POINT) {
-+ /* Check if number of token fits within bounds */
-+ if(wrqu->data.length > descr->max_tokens) {
-+ printk(KERN_ERR "%s (WE) : Wireless Event too big (%d)\n", dev->name, wrqu->data.length);
-+ return;
-+ }
-+ if(wrqu->data.length < descr->min_tokens) {
-+ printk(KERN_ERR "%s (WE) : Wireless Event too small (%d)\n", dev->name, wrqu->data.length);
-+ return;
-+ }
-+ /* Calculate extra_len - extra is NULL for restricted events */
-+ if(extra != NULL)
-+ extra_len = wrqu->data.length * descr->token_size;
-+#ifdef WE_EVENT_DEBUG
-+ printk(KERN_DEBUG "%s (WE) : Event 0x%04X, tokens %d, extra_len %d\n", dev->name, cmd, wrqu->data.length, extra_len);
-+#endif /* WE_EVENT_DEBUG */
-+ }
-+
-+ /* Total length of the event */
-+ hdr_len = event_type_size[descr->header_type];
-+ event_len = hdr_len + extra_len;
-+
-+#ifdef WE_EVENT_DEBUG
-+ printk(KERN_DEBUG "%s (WE) : Event 0x%04X, hdr_len %d, event_len %d\n", dev->name, cmd, hdr_len, event_len);
-+#endif /* WE_EVENT_DEBUG */
-+
-+ /* Create temporary buffer to hold the event */
-+ event = kmalloc(event_len, GFP_ATOMIC);
-+ if(event == NULL)
-+ return;
-+
-+ /* Fill event */
-+ event->len = event_len;
-+ event->cmd = cmd;
-+ memcpy(&event->u, wrqu, hdr_len - IW_EV_LCP_LEN);
-+ if(extra != NULL)
-+ memcpy(((char *) event) + hdr_len, extra, extra_len);
-+
-+#ifdef WE_EVENT_NETLINK
-+ /* rtnetlink event channel */
-+ rtmsg_iwinfo(dev, (char *) event, event_len);
-+#endif /* WE_EVENT_NETLINK */
-+
-+ /* Cleanup */
-+ kfree(event);
-+
-+ return; /* Always success, I guess ;-) */
- }
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/keymap-more-sane.patch b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/keymap-more-sane.patch
deleted file mode 100644
index a7eefd1e16..0000000000
--- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/keymap-more-sane.patch
+++ /dev/null
@@ -1,19 +0,0 @@
-
-#
-# Patch managed by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux/drivers/char/collie_keymap.map~keymap-more-sane 2003-05-13 11:18:18.000000000 +0200
-+++ linux/drivers/char/collie_keymap.map 2004-06-23 00:03:19.000000000 +0200
-@@ -55,9 +55,11 @@
- # (Cancel:34) F9 -> Escape
- keycode 34 = Escape
- keycode 35 = Left
-+ control keycode 35 = Decr_Console
- keycode 36 = Up
- keycode 37 = Down
- keycode 38 = Right
-+ control keycode 38 = Incr_Console
- # (OK:39) F4 -> Return
- keycode 39 = Return
- keycode 40 =
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/logo.patch b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/logo.patch
deleted file mode 100644
index c006684f23..0000000000
--- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/logo.patch
+++ /dev/null
@@ -1,2598 +0,0 @@
---- linux/drivers/video/fbcon.c 2003-02-27 21:47:36.000000000 -0600
-+++ linux.new/drivers/video/fbcon.c 2003-02-27 18:39:39.000000000 -0600
-@@ -126,8 +126,8 @@
- #define LOGO_H (320-16)
- #define LOGO_W 240
- #else
--#define LOGO_H 80
--#define LOGO_W 80
-+#define LOGO_H 52
-+#define LOGO_W 240
- #endif
- #define LOGO_LINE (LOGO_W/8)
- #if defined(CONFIG_SHARP_LOGO_SCREEN)
---- linux/include/linux/linux_logo.h 2001-06-11 21:15:27.000000000 -0500
-+++ linux.new/include/linux/linux_logo.h 2003-02-27 15:58:15.000000000 -0600
-@@ -1,4 +1,4 @@
--/* $Id$
-+/* linux_logo.h created with fblogo, 2002/12/29 02:43:36
- * include/linux/linux_logo.h: This is a linux logo
- * to be displayed on boot.
- *
-@@ -7,907 +7,1673 @@
- *
- * You can put anything here, but:
- * LINUX_LOGO_COLORS has to be less than 224
-- * image size has to be 80x80
-- * values have to start from 0x20
-- * (i.e. RGB(linux_logo_red[0],
-- * linux_logo_green[0],
-- * linux_logo_blue[0]) is color 0x20)
-- * BW image has to be 80x80 as well, with MS bit
-- * on the left
-- * Serial_console ascii image can be any size,
-- * but should contain %s to display the version
-+ * Generated by fblogo version 0.5.0
-+ *
-+ *
-+ * Remember to modify drivers/video/fbcon.c:
-+ * Change "#define LOGO_H 80" to "#define LOGO_H 52"
-+ * Change "#define LOGO_W 80" to "#define LOGO_W 240"
- */
-
- #ifndef __HAVE_ARCH_LINUX_LOGO
--#define LINUX_LOGO_COLORS 187
-+#define LINUX_LOGO_COLORS 223
- #endif
--
- #ifdef INCLUDE_LINUX_LOGO_DATA
--
- #ifndef __HAVE_ARCH_LINUX_LOGO
--
- unsigned char linux_logo_red[] __initdata = {
-- 0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-- 0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-- 0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
-- 0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-- 0xc3, 0x65, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-- 0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-- 0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x76, 0x79,
-- 0x62, 0x36, 0x9a, 0xe2, 0xec, 0xe1, 0xb8, 0xd7,
-- 0xaf, 0x25, 0xbc, 0xc0, 0xef, 0xea, 0xe8, 0xe8,
-- 0xf5, 0xf1, 0xda, 0xd3, 0x79, 0xdb, 0xf4, 0xf6,
-- 0xf6, 0xf6, 0xe2, 0x3d, 0xb4, 0xce, 0xe6, 0xee,
-- 0xf6, 0x68, 0xd8, 0xec, 0xf5, 0xc6, 0xc8, 0x9c,
-- 0x89, 0xd2, 0xee, 0xcb, 0xb9, 0xd2, 0x66, 0x5e,
-- 0x8b, 0xbe, 0xa8, 0xd5, 0xca, 0xb6, 0xae, 0x9c,
-- 0xc5, 0xbe, 0xbe, 0xca, 0x90, 0xb2, 0x9a, 0xa8,
-- 0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x12,
-- 0x4a, 0x8e, 0xf2, 0xf6, 0xf6, 0xee, 0xb5, 0xe4,
-- 0xf1, 0x26, 0x9a, 0xea, 0xf6, 0xe0, 0xd2, 0x16,
-- 0x9a, 0x2e, 0x70, 0xd6, 0x46, 0x7c, 0xb4, 0x62,
-- 0xd6, 0xa3, 0x74, 0xa7, 0xa2, 0xca, 0xe0, 0xae,
-- 0xbe, 0xce, 0xa3, 0x8e, 0x6d, 0x8e, 0x32, 0xaf,
-- 0x50, 0x9e, 0x5b, 0x8a, 0x98, 0x82, 0x7a, 0x82,
-- 0x56, 0x7c, 0x8a, 0x56, 0x5e, 0x86, 0x6a, 0x52,
-- 0x59, 0x64, 0x5e,
-+ 0x00, 0x02, 0x06, 0x0A, 0x56, 0xA6, 0xBE, 0xBA,
-+ 0xB6, 0x92, 0x3E, 0x1A, 0x8A, 0xF3, 0xFB, 0xEE,
-+ 0xC6, 0x62, 0x4A, 0x12, 0x26, 0x0E, 0x76, 0xDA,
-+ 0x6E, 0x32, 0x8E, 0x1E, 0x2A, 0xCE, 0xE2, 0x36,
-+ 0x66, 0xA2, 0x2E, 0x9E, 0xCA, 0x6A, 0x5A, 0x82,
-+ 0x7E, 0xE9, 0xD2, 0xDE, 0x22, 0x72, 0xAE, 0xD6,
-+ 0x86, 0x3A, 0x52, 0x9A, 0xAA, 0x16, 0x46, 0x4E,
-+ 0x42, 0xC2, 0x96, 0x7A, 0x5E, 0xB2, 0x32, 0x7E,
-+ 0x3A, 0x16, 0x02, 0x02, 0x06, 0x1F, 0x02, 0x02,
-+ 0x06, 0x02, 0x22, 0x3A, 0x35, 0x16, 0x0A, 0x02,
-+ 0x2A, 0x3E, 0x39, 0x32, 0x2A, 0x1E, 0x16, 0x06,
-+ 0x22, 0x22, 0x1E, 0x16, 0x6E, 0x82, 0x6E, 0x2E,
-+ 0x1E, 0x2E, 0x1E, 0x0A, 0x3A, 0xDA, 0xFE, 0xFA,
-+ 0xFA, 0xE2, 0x6A, 0x3A, 0x1A, 0xFA, 0xF6, 0x9E,
-+ 0x02, 0x6E, 0xFE, 0xF6, 0x3E, 0x66, 0x52, 0x1B,
-+ 0xD6, 0x5A, 0xEE, 0xC6, 0x72, 0x36, 0x22, 0x1E,
-+ 0x02, 0x96, 0xF6, 0xDE, 0xA2, 0xD6, 0x39, 0x0E,
-+ 0xAA, 0x52, 0x5A, 0xD2, 0xDE, 0x61, 0x46, 0xDE,
-+ 0x7A, 0x57, 0x9E, 0xBA, 0xB6, 0x4A, 0x5A, 0xA6,
-+ 0x96, 0x23, 0x1E, 0x12, 0x9A, 0x4E, 0x76, 0xAE,
-+ 0x2E, 0xBE, 0x86, 0x48, 0xA6, 0x52, 0x06, 0x2E,
-+ 0x56, 0x13, 0x2A, 0x4A, 0x36, 0x56, 0x2E, 0x1E,
-+ 0x46, 0x3A, 0x66, 0x02, 0x3D, 0x3E, 0x2E, 0x3E,
-+ 0x4A, 0x32, 0x52, 0x72, 0x76, 0x67, 0x68, 0x5A,
-+ 0x3A, 0x1A, 0x0E, 0x2E, 0x4E, 0x02, 0x3E, 0x0A,
-+ 0x28, 0x42, 0x10, 0x26, 0x8E, 0x0A, 0x86, 0xC2,
-+ 0x02, 0x6E, 0x92, 0x02, 0x42, 0x02, 0xBE, 0x4E,
-+ 0x02, 0x22, 0x02, 0x3E, 0x3A, 0x32
- };
-
- unsigned char linux_logo_green[] __initdata = {
-- 0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-- 0x12, 0x00, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-- 0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x02, 0x65,
-- 0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-- 0xc3, 0x62, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-- 0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-- 0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x62, 0x5c,
-- 0x4e, 0x26, 0x72, 0xaa, 0xba, 0xaf, 0x90, 0xae,
-- 0x92, 0x1a, 0xa4, 0x85, 0xb6, 0xbe, 0xc3, 0xc8,
-- 0xcf, 0xd0, 0xc2, 0xce, 0x57, 0xa2, 0xd6, 0xda,
-- 0xda, 0xd7, 0xb8, 0x2a, 0x7b, 0x91, 0xae, 0xca,
-- 0xda, 0x45, 0x9e, 0xb2, 0xd7, 0x9b, 0x90, 0x76,
-- 0x5c, 0xa2, 0xbe, 0xa6, 0x85, 0x96, 0x4e, 0x46,
-- 0x66, 0x92, 0x7a, 0x9a, 0x96, 0x9d, 0x9a, 0x6b,
-- 0x8a, 0x8e, 0xb2, 0xca, 0x90, 0xa6, 0x79, 0x7c,
-- 0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x0e,
-- 0x36, 0x86, 0xba, 0xbe, 0xe6, 0xcc, 0x8e, 0xb8,
-- 0xc4, 0x1e, 0x8e, 0xae, 0xba, 0xb2, 0xa6, 0x12,
-- 0x7a, 0x20, 0x64, 0xaa, 0x2f, 0x70, 0x85, 0x46,
-- 0xa6, 0x6e, 0x51, 0x72, 0x92, 0xa2, 0xa6, 0x87,
-- 0x96, 0xa2, 0x85, 0x7a, 0x6a, 0x6e, 0x22, 0x76,
-- 0x36, 0x76, 0x3c, 0x6e, 0x63, 0x53, 0x66, 0x62,
-- 0x42, 0x50, 0x56, 0x42, 0x56, 0x56, 0x56, 0x3e,
-- 0x51, 0x52, 0x56,
-+ 0x00, 0x02, 0x06, 0x0A, 0x56, 0xA6, 0xBE, 0xBA,
-+ 0xB6, 0x92, 0x3E, 0x1A, 0x8A, 0xF3, 0xFB, 0xEE,
-+ 0xC6, 0x62, 0x4A, 0x12, 0x26, 0x0E, 0x76, 0xDA,
-+ 0x6E, 0x32, 0x8E, 0x1E, 0x2A, 0xCE, 0xE2, 0x36,
-+ 0x66, 0xA2, 0x2E, 0x9E, 0xCA, 0x6A, 0x5A, 0x82,
-+ 0x7E, 0xE9, 0xD2, 0xDE, 0x22, 0x72, 0xAE, 0xD6,
-+ 0x86, 0x3A, 0x52, 0x9A, 0xAA, 0x16, 0x46, 0x4E,
-+ 0x42, 0xC2, 0x96, 0x7A, 0x5E, 0xB2, 0x2E, 0x7E,
-+ 0x3A, 0x3E, 0x6A, 0xA2, 0x92, 0x30, 0x95, 0x76,
-+ 0x4E, 0x86, 0x36, 0x7E, 0x9A, 0x6E, 0x42, 0x56,
-+ 0x5A, 0xC2, 0xBE, 0xB2, 0xAA, 0x9A, 0x63, 0x1E,
-+ 0xA2, 0x9E, 0x96, 0x5A, 0x3A, 0x42, 0x4A, 0x52,
-+ 0x91, 0x46, 0x4E, 0x62, 0x22, 0x4A, 0x6E, 0x86,
-+ 0x92, 0x9A, 0x52, 0x4A, 0x76, 0x7A, 0x9E, 0x76,
-+ 0x62, 0x32, 0x5E, 0xAE, 0x3E, 0x66, 0x52, 0x81,
-+ 0xA6, 0x5A, 0xEE, 0xC6, 0x72, 0x5C, 0x6A, 0x8A,
-+ 0x36, 0x3E, 0xBA, 0xBA, 0xA2, 0xD6, 0xAA, 0x4E,
-+ 0x8A, 0x4E, 0x5A, 0xD2, 0xDE, 0x64, 0x32, 0x9A,
-+ 0x5E, 0x57, 0x9E, 0xBA, 0xB6, 0x52, 0x62, 0xA6,
-+ 0x9A, 0x47, 0x3E, 0x56, 0x02, 0x1A, 0x76, 0xAE,
-+ 0x4A, 0x02, 0x02, 0x38, 0x02, 0x4A, 0x46, 0x86,
-+ 0x1E, 0x2E, 0x7A, 0xD2, 0x5E, 0x26, 0x92, 0x62,
-+ 0xCA, 0x42, 0x66, 0x26, 0x67, 0xB6, 0x62, 0x92,
-+ 0x9E, 0x72, 0xB2, 0xF2, 0xFE, 0xDE, 0xFE, 0xFE,
-+ 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0x8A, 0x2A,
-+ 0x42, 0x52, 0x6A, 0x26, 0x8E, 0x26, 0x86, 0xC2,
-+ 0xE2, 0x6E, 0x92, 0xBE, 0x42, 0xC6, 0xBE, 0x4E,
-+ 0xEE, 0x5A, 0xEA, 0x3E, 0x4A, 0x32
- };
-
- unsigned char linux_logo_blue[] __initdata = {
-- 0x00, 0x06, 0x0a, 0x0e, 0x16, 0x1a, 0x1e, 0x22,
-- 0x12, 0x01, 0x2a, 0x36, 0x42, 0x4e, 0x4a, 0x56,
-- 0x26, 0x46, 0x2e, 0x32, 0x52, 0x3a, 0x06, 0x65,
-- 0x5e, 0x3e, 0x74, 0x8a, 0xa2, 0x9a, 0x86, 0xc6,
-- 0xc3, 0x59, 0xbb, 0xd2, 0xda, 0xd6, 0xe2, 0xf6,
-- 0xfd, 0xae, 0x7b, 0xdd, 0xea, 0x6a, 0xaa, 0xe7,
-- 0xbe, 0x5a, 0xee, 0x9e, 0x95, 0x80, 0x2e, 0x08,
-- 0x0a, 0x06, 0x0a, 0x0b, 0x0b, 0x0f, 0x0c, 0x0f,
-- 0x3d, 0x09, 0x73, 0x09, 0x0d, 0x0a, 0x10, 0x1e,
-- 0x2d, 0x13, 0x86, 0xba, 0x19, 0x0a, 0x36, 0x3c,
-- 0x26, 0x14, 0x0d, 0x06, 0x07, 0x0a, 0x0b, 0x0f,
-- 0x4a, 0x06, 0x0a, 0x0c, 0x2b, 0x0a, 0x0b, 0x0a,
-- 0x06, 0x0a, 0x0a, 0x11, 0x0b, 0x0a, 0x0a, 0x1e,
-- 0x0f, 0x0d, 0x0a, 0x0b, 0x22, 0x6a, 0x72, 0x0b,
-- 0x0b, 0x22, 0x90, 0xca, 0x90, 0x92, 0x3c, 0x2c,
-- 0xb6, 0xf2, 0xce, 0xfa, 0xb2, 0x6e, 0xa6, 0x06,
-- 0x0e, 0x6a, 0x0e, 0x0e, 0xbe, 0x5b, 0x2c, 0x3e,
-- 0x0e, 0x0a, 0x5a, 0x0d, 0x0e, 0x3e, 0x0a, 0x06,
-- 0x2e, 0x06, 0x4e, 0x36, 0x06, 0x58, 0x24, 0x06,
-- 0x3a, 0x08, 0x08, 0x07, 0x5e, 0x45, 0x0a, 0x32,
-- 0x2e, 0x2a, 0x43, 0x48, 0x5f, 0x2e, 0x06, 0x06,
-- 0x07, 0x24, 0x06, 0x32, 0x06, 0x06, 0x46, 0x2e,
-- 0x22, 0x06, 0x06, 0x1e, 0x4c, 0x06, 0x3a, 0x22,
-- 0x42, 0x34, 0x42,
-+ 0x00, 0x02, 0x06, 0x0A, 0x56, 0xA6, 0xBE, 0xBA,
-+ 0xB6, 0x92, 0x3E, 0x1A, 0x8A, 0xF3, 0xFB, 0xEE,
-+ 0xC6, 0x62, 0x4A, 0x12, 0x26, 0x0E, 0x76, 0xDA,
-+ 0x6E, 0x32, 0x8E, 0x1E, 0x2A, 0xCE, 0xE2, 0x36,
-+ 0x66, 0xA2, 0x2E, 0x9E, 0xCA, 0x6A, 0x5A, 0x82,
-+ 0x7E, 0xE9, 0xD2, 0xDE, 0x22, 0x72, 0xAE, 0xD6,
-+ 0x86, 0x3A, 0x52, 0x9A, 0xAA, 0x16, 0x46, 0x4E,
-+ 0x42, 0xC2, 0x96, 0x7A, 0x5E, 0xB2, 0x1A, 0x06,
-+ 0x1A, 0x2A, 0x36, 0x52, 0x46, 0x23, 0x4D, 0x3E,
-+ 0x2A, 0x42, 0x2A, 0x5A, 0x69, 0x42, 0x26, 0x2E,
-+ 0x42, 0x7E, 0x7C, 0x72, 0x6A, 0x5E, 0x3B, 0x12,
-+ 0x62, 0x5E, 0x5A, 0x36, 0x26, 0x1E, 0x26, 0x42,
-+ 0x56, 0x3A, 0x36, 0x36, 0x1E, 0x2E, 0x2A, 0x22,
-+ 0x22, 0x1A, 0x16, 0x42, 0x46, 0x26, 0x1E, 0x12,
-+ 0x32, 0x2A, 0x2E, 0x16, 0x2A, 0x1A, 0x2E, 0x4E,
-+ 0x12, 0x22, 0x02, 0x02, 0x12, 0x4A, 0x46, 0x52,
-+ 0x1E, 0x1E, 0x16, 0x0E, 0x02, 0x02, 0x6F, 0x2E,
-+ 0x0E, 0x1A, 0x06, 0x02, 0x02, 0x04, 0x22, 0x16,
-+ 0x0E, 0x12, 0x02, 0x02, 0x02, 0x0A, 0x5A, 0x02,
-+ 0x02, 0x1B, 0x2E, 0x32, 0x02, 0x02, 0x02, 0x02,
-+ 0x16, 0x02, 0x02, 0x10, 0x02, 0x02, 0x26, 0x5A,
-+ 0x02, 0x1F, 0x52, 0x8E, 0x22, 0x02, 0x5E, 0x3E,
-+ 0x86, 0x0E, 0x16, 0x16, 0x52, 0x7A, 0x4A, 0x66,
-+ 0x72, 0x52, 0x82, 0xB2, 0xBA, 0xA4, 0xB2, 0xAA,
-+ 0x9E, 0x8E, 0x88, 0x96, 0xA6, 0x82, 0x62, 0x1A,
-+ 0x34, 0x4A, 0x31, 0x16, 0x02, 0x1A, 0x02, 0x02,
-+ 0x72, 0x02, 0x02, 0x5E, 0x1A, 0x62, 0x02, 0x0E,
-+ 0x76, 0x1E, 0x76, 0x1E, 0x0A, 0x02
- };
-
- unsigned char linux_logo[] __initdata = {
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22, 0x22,
-- 0x22, 0x21, 0x21, 0x21, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-- 0x26, 0x26, 0x25, 0x28, 0x23, 0x22, 0x21, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x21, 0x23, 0x25, 0x2a, 0x2b, 0x2c, 0x2d, 0x2d,
-- 0x2d, 0x2e, 0x2c, 0x2b, 0x2a, 0x25, 0x28, 0x22,
-- 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-- 0x24, 0x2a, 0x2c, 0x2f, 0x2c, 0x30, 0x30, 0x24,
-- 0x25, 0x27, 0x2b, 0x2c, 0x2f, 0x31, 0x32, 0x25,
-- 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
-- 0x33, 0x34, 0x35, 0x21, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x21, 0x2b, 0x2f, 0x2c,
-- 0x30, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
-- 0x2d, 0x27, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x31,
-- 0x2d, 0x32, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x21, 0x28, 0x2a, 0x34,
-- 0x25, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x23, 0x32, 0x27, 0x21, 0x36,
-- 0x2a, 0x2d, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x22, 0x26, 0x2c, 0x35,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x25, 0x2f, 0x37, 0x32, 0x22,
-- 0x36, 0x35, 0x31, 0x27, 0x22, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x22,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x26, 0x38, 0x38, 0x35, 0x25,
-- 0x36, 0x21, 0x2d, 0x2b, 0x24, 0x21, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x21, 0x24, 0x39, 0x39, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x25, 0x2b, 0x30, 0x28, 0x22,
-- 0x36, 0x36, 0x27, 0x34, 0x30, 0x23, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x21, 0x26, 0x2d, 0x26, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x22, 0x22, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x2d, 0x33, 0x28, 0x21, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x2b, 0x2c, 0x25, 0x21, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x36, 0x36,
-- 0x36, 0x21, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x21, 0x23, 0x22, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x28, 0x34, 0x27, 0x22, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x29, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
-- 0x21, 0x21, 0x24, 0x27, 0x21, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x28, 0x27, 0x22, 0x33, 0x24, 0x36,
-- 0x36, 0x36, 0x36, 0x22, 0x2f, 0x2a, 0x23, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x29, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x36,
-- 0x30, 0x3a, 0x38, 0x24, 0x24, 0x36, 0x36, 0x36,
-- 0x23, 0x2f, 0x3b, 0x3c, 0x3d, 0x30, 0x25, 0x21,
-- 0x36, 0x36, 0x36, 0x36, 0x2f, 0x32, 0x23, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x23,
-- 0x3e, 0x3f, 0x40, 0x3a, 0x22, 0x36, 0x36, 0x21,
-- 0x41, 0x42, 0x43, 0x44, 0x45, 0x3e, 0x23, 0x21,
-- 0x36, 0x36, 0x36, 0x36, 0x2f, 0x33, 0x28, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x32, 0x2f, 0x36, 0x2b,
-- 0x44, 0x40, 0x46, 0x47, 0x35, 0x36, 0x36, 0x26,
-- 0x43, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x2e, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x32, 0x34, 0x36, 0x4d,
-- 0x4e, 0x25, 0x2f, 0x46, 0x4a, 0x22, 0x23, 0x32,
-- 0x4f, 0x50, 0x21, 0x31, 0x51, 0x52, 0x53, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x31, 0x35, 0x24, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x29, 0x20, 0x29, 0x29, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x2a, 0x2f, 0x21, 0x3a,
-- 0x4d, 0x21, 0x31, 0x54, 0x55, 0x28, 0x30, 0x2b,
-- 0x4b, 0x4d, 0x36, 0x23, 0x32, 0x50, 0x3f, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x29, 0x20, 0x29, 0x20, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x2a, 0x38, 0x23, 0x37,
-- 0x55, 0x36, 0x28, 0x3a, 0x56, 0x57, 0x57, 0x58,
-- 0x3c, 0x4d, 0x36, 0x36, 0x36, 0x40, 0x40, 0x21,
-- 0x36, 0x36, 0x36, 0x36, 0x2e, 0x39, 0x24, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x29, 0x29, 0x29, 0x20, 0x29, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x30, 0x51, 0x23, 0x35,
-- 0x43, 0x25, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
-- 0x5f, 0x60, 0x61, 0x36, 0x31, 0x47, 0x3b, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x31, 0x2c, 0x25, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x23, 0x22,
-- 0x40, 0x62, 0x63, 0x5d, 0x64, 0x65, 0x66, 0x67,
-- 0x68, 0x69, 0x66, 0x5e, 0x6a, 0x6b, 0x2a, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x33, 0x2e, 0x26, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x27, 0x2f, 0x23, 0x36,
-- 0x6c, 0x63, 0x6d, 0x64, 0x5c, 0x66, 0x69, 0x6e,
-- 0x6f, 0x70, 0x71, 0x69, 0x69, 0x72, 0x6c, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x33, 0x34, 0x27, 0x22,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x27, 0x34, 0x26, 0x73,
-- 0x74, 0x75, 0x76, 0x64, 0x65, 0x77, 0x69, 0x78,
-- 0x70, 0x71, 0x71, 0x71, 0x72, 0x5f, 0x5e, 0x21,
-- 0x36, 0x36, 0x36, 0x36, 0x25, 0x38, 0x2a, 0x23,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x33, 0x79,
-- 0x63, 0x7a, 0x7b, 0x5c, 0x66, 0x69, 0x6e, 0x7c,
-- 0x71, 0x71, 0x69, 0x7d, 0x7e, 0x7a, 0x7f, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x21, 0x51, 0x2b, 0x28,
-- 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x26, 0x2d, 0x32, 0x24,
-- 0x80, 0x81, 0x64, 0x82, 0x77, 0x69, 0x71, 0x71,
-- 0x69, 0x83, 0x84, 0x85, 0x7a, 0x85, 0x86, 0x36,
-- 0x21, 0x2b, 0x23, 0x36, 0x36, 0x39, 0x2e, 0x26,
-- 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x27, 0x2d, 0x33, 0x21,
-- 0x87, 0x88, 0x89, 0x72, 0x67, 0x66, 0x5f, 0x89,
-- 0x8a, 0x63, 0x85, 0x8b, 0x8c, 0x8d, 0x41, 0x36,
-- 0x36, 0x2d, 0x3a, 0x35, 0x36, 0x24, 0x51, 0x32,
-- 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x30, 0x2f, 0x33, 0x21,
-- 0x55, 0x8e, 0x8f, 0x8a, 0x7d, 0x5e, 0x90, 0x7e,
-- 0x75, 0x75, 0x90, 0x62, 0x40, 0x3f, 0x49, 0x23,
-- 0x36, 0x24, 0x3a, 0x3a, 0x24, 0x36, 0x2e, 0x31,
-- 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x21, 0x28, 0x33, 0x37, 0x25, 0x22,
-- 0x3b, 0x50, 0x8e, 0x8f, 0x90, 0x7e, 0x90, 0x63,
-- 0x74, 0x91, 0x92, 0x42, 0x93, 0x4b, 0x45, 0x2c,
-- 0x36, 0x36, 0x33, 0x39, 0x21, 0x36, 0x22, 0x51,
-- 0x33, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x22, 0x27, 0x2e, 0x2e, 0x36, 0x21,
-- 0x94, 0x3f, 0x50, 0x95, 0x96, 0x8f, 0x8f, 0x97,
-- 0x8e, 0x42, 0x50, 0x43, 0x47, 0x48, 0x48, 0x98,
-- 0x21, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39,
-- 0x2e, 0x27, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x22, 0x24, 0x2b, 0x38, 0x28, 0x36, 0x32,
-- 0x4c, 0x4b, 0x50, 0x50, 0x50, 0x42, 0x42, 0x50,
-- 0x50, 0x40, 0x45, 0x99, 0x48, 0x48, 0x48, 0x48,
-- 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x23,
-- 0x2f, 0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x21, 0x28, 0x32, 0x51, 0x32, 0x28, 0x21, 0x98,
-- 0x48, 0x47, 0x9a, 0x50, 0x50, 0x50, 0x50, 0x50,
-- 0x9a, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x93, 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x2a, 0x2f, 0x2a, 0x28, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-- 0x23, 0x30, 0x2e, 0x2c, 0x36, 0x21, 0x51, 0x9b,
-- 0x48, 0x48, 0x52, 0x3f, 0x50, 0x50, 0x40, 0x4b,
-- 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x34, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x2d, 0x31, 0x27, 0x23, 0x21, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-- 0x27, 0x2c, 0x2d, 0x21, 0x36, 0x28, 0x44, 0x48,
-- 0x48, 0x48, 0x48, 0x47, 0x46, 0x4f, 0x47, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x9c, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x28, 0x51, 0x39, 0x26, 0x22, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22, 0x25,
-- 0x35, 0x51, 0x28, 0x36, 0x36, 0x9d, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x4f, 0x28, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x28, 0x38, 0x2b, 0x25, 0x22, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24, 0x33,
-- 0x51, 0x25, 0x36, 0x36, 0x23, 0x40, 0x9b, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x9b, 0x99, 0x2b, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x30, 0x2f, 0x33, 0x24, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x21, 0x23, 0x30, 0x34,
-- 0x27, 0x36, 0x36, 0x36, 0x2a, 0x40, 0x47, 0x48,
-- 0x48, 0x48, 0x48, 0x9b, 0x99, 0x99, 0x9b, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x47, 0x52,
-- 0x46, 0x4f, 0x37, 0x21, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x30, 0x34, 0x2a, 0x23,
-- 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x22, 0x25, 0x39, 0x2c,
-- 0x36, 0x36, 0x36, 0x21, 0x31, 0x4e, 0x9a, 0x4c,
-- 0x47, 0x9b, 0x9b, 0x52, 0x46, 0x4f, 0x52, 0x9b,
-- 0x9b, 0x9b, 0x47, 0x4f, 0x45, 0x9a, 0x93, 0x93,
-- 0x3f, 0x93, 0x98, 0x28, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c, 0x26,
-- 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x23, 0x2a, 0x34, 0x28,
-- 0x36, 0x36, 0x36, 0x22, 0x38, 0x98, 0x44, 0x99,
-- 0x9b, 0x48, 0x48, 0x9b, 0x4c, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x47, 0x52, 0x46, 0x43, 0x93,
-- 0x40, 0x40, 0x43, 0x53, 0x21, 0x23, 0x33, 0x23,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x2f, 0x32,
-- 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x21, 0x24, 0x2b, 0x31, 0x36,
-- 0x36, 0x22, 0x36, 0x24, 0x9e, 0x4f, 0x9b, 0x48,
-- 0x48, 0x48, 0x48, 0x9b, 0x99, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x47,
-- 0x4f, 0x9a, 0x3f, 0x46, 0x38, 0x36, 0x21, 0x30,
-- 0x26, 0x36, 0x36, 0x36, 0x36, 0x36, 0x39, 0x2c,
-- 0x25, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x22, 0x26, 0x2e, 0x33, 0x36,
-- 0x25, 0x25, 0x36, 0x4d, 0x52, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x47, 0x44, 0x93, 0x43, 0x23, 0x36, 0x36,
-- 0x26, 0x24, 0x36, 0x36, 0x36, 0x36, 0x28, 0x2f,
-- 0x2a, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x23, 0x2a, 0x51, 0x24, 0x36,
-- 0x2a, 0x36, 0x28, 0x44, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x9b, 0x4b, 0x44, 0x37, 0x36, 0x23,
-- 0x28, 0x30, 0x22, 0x36, 0x36, 0x36, 0x36, 0x2d,
-- 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x21, 0x28, 0x2b, 0x34, 0x36, 0x25,
-- 0x24, 0x36, 0x4a, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x9b, 0x52, 0x3f, 0x21, 0x30,
-- 0x35, 0x25, 0x30, 0x36, 0x36, 0x36, 0x36, 0x32,
-- 0x2d, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x22, 0x26, 0x2e, 0x35, 0x36, 0x2a,
-- 0x36, 0x24, 0x4f, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x9b, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x47, 0x32, 0x30,
-- 0x2a, 0x23, 0x30, 0x23, 0x36, 0x36, 0x36, 0x21,
-- 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x21, 0x23, 0x2a, 0x51, 0x28, 0x28, 0x25,
-- 0x36, 0x3a, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x9b, 0x52, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x38, 0x21,
-- 0x36, 0x36, 0x22, 0x27, 0x36, 0x36, 0x36, 0x36,
-- 0x2e, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x22, 0x25, 0x2c, 0x34, 0x36, 0x30, 0x21,
-- 0x23, 0x43, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x47, 0x99, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x94, 0x36,
-- 0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
-- 0x2a, 0x2e, 0x26, 0x22, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x21, 0x23, 0x2a, 0x51, 0x25, 0x21, 0x2a, 0x36,
-- 0x2e, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x99, 0x99, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x98, 0x36,
-- 0x36, 0x36, 0x36, 0x32, 0x36, 0x36, 0x36, 0x36,
-- 0x22, 0x2f, 0x30, 0x22, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x22, 0x25, 0x2c, 0x34, 0x36, 0x24, 0x28, 0x36,
-- 0x54, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4c, 0x99, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
-- 0x36, 0x36, 0x36, 0x30, 0x36, 0x36, 0x36, 0x36,
-- 0x21, 0x2f, 0x32, 0x23, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-- 0x28, 0x32, 0x2f, 0x28, 0x36, 0x27, 0x22, 0x21,
-- 0x43, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4c, 0x99, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4b, 0x21,
-- 0x36, 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-- 0x25, 0x2c, 0x39, 0x36, 0x36, 0x30, 0x22, 0x25,
-- 0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4f, 0x52, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4f, 0x21,
-- 0x36, 0x36, 0x22, 0x26, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-- 0x30, 0x2d, 0x21, 0x36, 0x36, 0x32, 0x23, 0x2a,
-- 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4f, 0x99, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x22,
-- 0x36, 0x36, 0x24, 0x23, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-- 0x33, 0x2e, 0x36, 0x36, 0x23, 0x31, 0x27, 0x39,
-- 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4c, 0x23,
-- 0x36, 0x36, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x2c, 0x39, 0x24, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-- 0x2b, 0x39, 0x36, 0x36, 0x36, 0x26, 0x32, 0x31,
-- 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x46, 0x22,
-- 0x36, 0x21, 0x26, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x2c, 0x35, 0x24, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-- 0x35, 0x39, 0x36, 0x36, 0x36, 0x36, 0x26, 0x2d,
-- 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x9a, 0x36,
-- 0x24, 0x27, 0x9f, 0x24, 0x25, 0x28, 0x21, 0x36,
-- 0x36, 0x34, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x25,
-- 0x39, 0x4d, 0xa0, 0x84, 0x81, 0x57, 0x21, 0x39,
-- 0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4f, 0x47, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x53, 0x28,
-- 0x23, 0x36, 0x36, 0x36, 0x21, 0x28, 0x2c, 0x30,
-- 0x21, 0x38, 0x33, 0x28, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x21, 0x22, 0x22, 0x28, 0x30,
-- 0x2d, 0xa1, 0x7a, 0xa2, 0xa3, 0xa3, 0x7f, 0x22,
-- 0x51, 0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0xa4, 0xa5, 0xa5, 0xa6, 0x61,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x30, 0x32,
-- 0x25, 0x4d, 0x2b, 0x28, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x21, 0x23, 0x24, 0x26, 0x30, 0x33, 0x31,
-- 0x4d, 0x91, 0x5b, 0xa2, 0xa3, 0xa3, 0xa3, 0x5a,
-- 0x21, 0x2e, 0x46, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4f, 0x9b, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0xa7, 0xa8, 0x69, 0x66, 0xa9,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x26, 0x25,
-- 0x83, 0xaa, 0x2c, 0x25, 0x21, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x21, 0x28, 0x30, 0x35, 0x2d, 0x2f, 0x37, 0x4a,
-- 0x60, 0x85, 0xab, 0xac, 0xa3, 0xa3, 0xa3, 0x82,
-- 0x86, 0x36, 0x32, 0x3f, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x4c, 0x99, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0xad, 0xa2, 0xa8, 0xae, 0xaf,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x21, 0x57,
-- 0x77, 0x66, 0x34, 0x27, 0x22, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x23, 0x30, 0x31, 0xb0, 0x91, 0x7e, 0x90, 0x90,
-- 0x8b, 0x5b, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0x5d, 0xb1, 0x36, 0x24, 0x53, 0x9b, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x9b, 0x99, 0xad, 0x64, 0x5c, 0x8b, 0xb1,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x73, 0x5d,
-- 0x82, 0x5c, 0xb2, 0x2a, 0x23, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-- 0x24, 0x2b, 0xb0, 0x8b, 0x5b, 0x76, 0x5b, 0x5b,
-- 0x7b, 0xa2, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa8, 0x5e, 0x22, 0x36, 0x21, 0x3a, 0x99, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x4f, 0x3f, 0xb3, 0x7b, 0x7b, 0x85, 0x80,
-- 0x9f, 0x36, 0x36, 0x36, 0x21, 0xb4, 0x7e, 0x7b,
-- 0x64, 0x64, 0xb5, 0x35, 0x24, 0x21, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-- 0x26, 0x31, 0xb6, 0x5b, 0x64, 0xa2, 0xa2, 0xac,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0x66, 0xb7, 0x36, 0x36, 0x36, 0x2c, 0x4b,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x9a, 0x3f, 0xb8, 0x76, 0x76, 0x7a, 0x63,
-- 0xb9, 0xba, 0x86, 0xba, 0xbb, 0x90, 0x5b, 0x64,
-- 0xa2, 0xa2, 0xbc, 0x2d, 0x27, 0x23, 0x21, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-- 0x26, 0x2d, 0x91, 0x5b, 0x64, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa8, 0x83, 0xaf, 0x36, 0x36, 0x36, 0x30,
-- 0x44, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x9b, 0x9a, 0x3f, 0xbd, 0x5b, 0x7b, 0xbe, 0x85,
-- 0x7e, 0x90, 0x63, 0x90, 0x85, 0x5b, 0xa2, 0xa3,
-- 0xa3, 0xac, 0x5d, 0xb5, 0x39, 0x26, 0x23, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-- 0x26, 0x2d, 0xbf, 0xbe, 0x64, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa8, 0x88, 0x36, 0x36, 0x36, 0x36,
-- 0x2d, 0x9b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x9b, 0x45, 0x3f, 0xc0, 0x6d, 0x7b, 0xab, 0xbe,
-- 0x7a, 0x8b, 0x8b, 0x7a, 0x5b, 0x64, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa2, 0xc1, 0x37, 0x35, 0x26, 0x23,
-- 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-- 0x26, 0x2e, 0xbf, 0x7a, 0x7b, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa8, 0x72, 0x73, 0x36, 0x36, 0x36,
-- 0x24, 0x52, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x46, 0x42, 0xb6, 0x7a, 0x7b, 0x64, 0x7b,
-- 0x76, 0x5b, 0x5b, 0x76, 0x7b, 0xa2, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xac, 0x64, 0xc1, 0x4d, 0x2c, 0x27,
-- 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-- 0x25, 0x31, 0xc2, 0x8b, 0x7b, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa8, 0x89, 0x9f, 0x36, 0x36,
-- 0x32, 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x4b, 0x2f, 0x8f, 0x7a, 0x7b, 0xa2, 0xac,
-- 0xa2, 0x64, 0x64, 0xa2, 0xa2, 0xac, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x5d, 0xc3, 0x2c,
-- 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-- 0x25, 0x31, 0xc2, 0x85, 0x7b, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0x66, 0x57, 0x27, 0x4d,
-- 0x4b, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x99, 0x34, 0x9f, 0xb9, 0x7a, 0x7b, 0xa2, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xc2,
-- 0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x22,
-- 0x26, 0x2d, 0xc2, 0x85, 0x7b, 0xac, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa8, 0x5f, 0x92, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x44,
-- 0x35, 0x36, 0xaf, 0xbb, 0x7a, 0x7b, 0xac, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0xa2, 0xc0,
-- 0x2b, 0x24, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-- 0x30, 0x2f, 0xb6, 0x8b, 0x7b, 0xac, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x66, 0x89, 0x45,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x48, 0x9b, 0x4e, 0x25,
-- 0x36, 0x36, 0x61, 0xb9, 0x6d, 0x64, 0xac, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0x7b, 0xbe, 0xc3,
-- 0x32, 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-- 0x33, 0xc4, 0x63, 0xbe, 0xa2, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x72, 0x81, 0xc5,
-- 0x46, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
-- 0x48, 0x48, 0x48, 0x48, 0x3f, 0x2c, 0x36, 0x36,
-- 0x36, 0x36, 0xc6, 0x8f, 0x6d, 0x64, 0xac, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa2, 0xab, 0x8b, 0xb0, 0x2c,
-- 0x26, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-- 0x35, 0x96, 0x75, 0xab, 0xa2, 0xac, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0x7b, 0x81, 0xb9,
-- 0x73, 0x3b, 0x44, 0x9b, 0x48, 0x48, 0x48, 0x9b,
-- 0x99, 0x43, 0x94, 0x2c, 0x21, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x73, 0xb9, 0x7a, 0x7b, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0x64, 0x76, 0x7a, 0x91, 0xb5, 0x31, 0x30,
-- 0x28, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x24,
-- 0x39, 0x97, 0x75, 0xbe, 0x7b, 0x64, 0xa2, 0xa2,
-- 0xac, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0x7b, 0x7a, 0xc7,
-- 0xc8, 0x36, 0x21, 0x26, 0x2b, 0x39, 0x33, 0x30,
-- 0x23, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x21, 0xc8, 0xbb, 0x8b, 0x7b, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0x64, 0x64,
-- 0x76, 0x85, 0xbf, 0xb5, 0x34, 0x2b, 0x27, 0x28,
-- 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x28,
-- 0x33, 0xc9, 0x63, 0x7e, 0x7a, 0x6d, 0xbe, 0x5b,
-- 0x76, 0x7b, 0x64, 0x64, 0xa2, 0xac, 0xa3, 0xa3,
-- 0xa3, 0xa3, 0xa3, 0xa3, 0xac, 0x76, 0x85, 0xb9,
-- 0x79, 0x22, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x21, 0xca, 0xbb, 0x75, 0x76, 0xa2, 0xa3,
-- 0xa3, 0xa3, 0xac, 0xa2, 0x64, 0x76, 0xbe, 0x8b,
-- 0xb6, 0xb5, 0x2f, 0x35, 0x30, 0x24, 0x22, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23,
-- 0x27, 0x31, 0xcb, 0xc9, 0xbb, 0x74, 0x63, 0x90,
-- 0x7e, 0x75, 0x8b, 0x6d, 0xbe, 0x76, 0x64, 0xa2,
-- 0xac, 0xac, 0xac, 0xac, 0x64, 0x7a, 0x84, 0xcc,
-- 0x79, 0x9f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
-- 0x36, 0x21, 0xc8, 0xcc, 0x63, 0x6d, 0x7b, 0x64,
-- 0xac, 0xa2, 0x64, 0x7b, 0xbe, 0x75, 0x63, 0x96,
-- 0x38, 0x39, 0x2a, 0x24, 0x23, 0x21, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-- 0x28, 0x27, 0x35, 0x2d, 0x41, 0xb5, 0xc5, 0x8f,
-- 0xb9, 0xbb, 0xc7, 0x74, 0x84, 0x90, 0x85, 0x6d,
-- 0x5b, 0x7b, 0x7b, 0xab, 0x6d, 0x90, 0xb9, 0xcd,
-- 0xca, 0x22, 0x36, 0x36, 0x28, 0x30, 0x30, 0x30,
-- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x25, 0x36,
-- 0x36, 0x21, 0xb4, 0x80, 0xc7, 0x7e, 0x6d, 0x76,
-- 0xab, 0x76, 0x6d, 0x85, 0x63, 0xb9, 0xb5, 0x34,
-- 0x33, 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x21, 0x23, 0x24, 0x27, 0x2a, 0x35, 0x2e, 0x2f,
-- 0x41, 0xce, 0xcf, 0x6c, 0x80, 0xcc, 0xb9, 0x74,
-- 0x84, 0x90, 0x75, 0x7e, 0x74, 0x8f, 0xcd, 0x79,
-- 0xc6, 0x2b, 0x9d, 0x41, 0x2f, 0x34, 0x2d, 0x2d,
-- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x34, 0x2f, 0x38,
-- 0x4d, 0x37, 0xd0, 0xd1, 0x8f, 0x74, 0x63, 0x7e,
-- 0x75, 0x7e, 0x63, 0xc7, 0x88, 0xc4, 0x31, 0x2a,
-- 0x24, 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x21, 0x22, 0x23, 0x24, 0x26, 0x30,
-- 0x33, 0x39, 0x2e, 0x51, 0x41, 0xb2, 0x6c, 0xd1,
-- 0x80, 0xcc, 0xcc, 0xcc, 0xd2, 0xd1, 0xb7, 0xd3,
-- 0x41, 0x34, 0x35, 0x32, 0x30, 0x27, 0x27, 0x27,
-- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x30, 0x2a,
-- 0x2b, 0x34, 0xd4, 0xca, 0xd5, 0x8f, 0xbb, 0xc7,
-- 0xc7, 0xbb, 0xcc, 0x6c, 0x41, 0x39, 0x27, 0x28,
-- 0x21, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x22,
-- 0x28, 0x24, 0x26, 0x2a, 0x33, 0x2c, 0x2f, 0x41,
-- 0xd6, 0xb7, 0x79, 0x79, 0x79, 0xca, 0xd7, 0x51,
-- 0x39, 0x30, 0x24, 0x23, 0x22, 0x22, 0x22, 0x22,
-- 0x22, 0x22, 0x21, 0x22, 0x22, 0x22, 0x22, 0x23,
-- 0x24, 0x2a, 0x31, 0xd8, 0xc8, 0x79, 0xd1, 0x80,
-- 0xd5, 0xba, 0xd9, 0x2f, 0x35, 0x26, 0x23, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x21, 0x22, 0x23, 0x28, 0x25, 0x30, 0x2b,
-- 0x31, 0x2f, 0xd4, 0xd8, 0xd8, 0x2f, 0x2e, 0x33,
-- 0x26, 0x23, 0x21, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x21, 0x28, 0x27, 0x35, 0x34, 0xd8, 0xd8, 0xd8,
-- 0xda, 0xd4, 0x2e, 0x33, 0x25, 0x23, 0x21, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x23, 0x28,
-- 0x26, 0x30, 0x32, 0x2b, 0x33, 0x2a, 0x26, 0x28,
-- 0x22, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x21, 0x23, 0x25, 0x30, 0x33, 0x35, 0x35,
-- 0x2b, 0x2a, 0x26, 0x28, 0x22, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x21,
-- 0x21, 0x22, 0x23, 0x28, 0x28, 0x23, 0x22, 0x21,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x21, 0x23, 0x28, 0x24, 0x24,
-- 0x28, 0x23, 0x22, 0x21, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x23, 0x33, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x23, 0x61, 0x62, 0x2B, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x35, 0x61, 0x63, 0x64, 0x35, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x65, 0x66, 0x66, 0x67, 0x55, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x3B,
-+ 0x3B, 0x68, 0x64, 0x69, 0x62, 0x55, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x22, 0x23, 0x23, 0x55, 0x6A, 0x6B,
-+ 0x6C, 0x6D, 0x6E, 0x6F, 0x6F, 0x33, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23,
-+ 0x22, 0x23, 0x35, 0x33, 0x3B, 0x70, 0x71, 0x72,
-+ 0x73, 0x74, 0x75, 0x76, 0x77, 0x55, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x22, 0x23, 0x23, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x23, 0x55,
-+ 0x2B, 0x34, 0x34, 0x42, 0x70, 0x71, 0x73, 0x78,
-+ 0x78, 0x78, 0x79, 0x7A, 0x7B, 0x34, 0x22, 0x21,
-+ 0x55, 0x33, 0x23, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x22, 0x3B, 0x7C, 0x7D, 0x7E, 0x34, 0x35,
-+ 0x21, 0x21, 0x21, 0x21, 0x35, 0x3B, 0x4C, 0x3C,
-+ 0x42, 0x3F, 0x56, 0x7F, 0x71, 0x74, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x79, 0x80, 0x81, 0x3C, 0x82,
-+ 0x83, 0x62, 0x61, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x23, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A,
-+ 0x3B, 0x21, 0x55, 0x55, 0x2B, 0x34, 0x39, 0x3F,
-+ 0x2A, 0x57, 0x8B, 0x72, 0x74, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x75, 0x8C, 0x6F, 0x63,
-+ 0x63, 0x66, 0x61, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x84, 0x85, 0x86, 0x8D, 0x88, 0x8E, 0x8F, 0x5E,
-+ 0x3C, 0x34, 0x3B, 0x34, 0x3F, 0x2A, 0x58, 0x57,
-+ 0x52, 0x46, 0x6C, 0x73, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x79, 0x7A, 0x6E, 0x69,
-+ 0x69, 0x90, 0x34, 0x33, 0x22, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23,
-+ 0x91, 0x92, 0x8D, 0x87, 0x8E, 0x93, 0x8A, 0x35,
-+ 0x94, 0x95, 0x96, 0x56, 0x32, 0x32, 0x52, 0x5C,
-+ 0x4D, 0x82, 0x72, 0x78, 0x78, 0x78, 0x78, 0x79,
-+ 0x97, 0x78, 0x78, 0x78, 0x78, 0x75, 0x6D, 0x6F,
-+ 0x62, 0x65, 0x34, 0x4C, 0x33, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2B,
-+ 0x91, 0x86, 0x87, 0x88, 0x93, 0x98, 0x60, 0x3F,
-+ 0x99, 0x9A, 0x9A, 0x9B, 0x9C, 0x57, 0x5C, 0x36,
-+ 0x9D, 0x9E, 0x6D, 0x78, 0x78, 0x78, 0x97, 0x6E,
-+ 0x9F, 0x78, 0x78, 0x78, 0x78, 0x79, 0x80, 0xA0,
-+ 0x61, 0x51, 0x51, 0x3C, 0x4C, 0x55, 0x35, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x3B, 0x22,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x4C,
-+ 0xA1, 0x8D, 0x88, 0x8E, 0xA2, 0xA3, 0x94, 0x42,
-+ 0x51, 0xA4, 0x9A, 0x9A, 0x9A, 0xA5, 0x9C, 0x2A,
-+ 0xA6, 0x74, 0x8C, 0x75, 0x97, 0xA7, 0x76, 0x75,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x75, 0x6E,
-+ 0x46, 0x52, 0x56, 0x3F, 0x42, 0x34, 0x33, 0x35,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x22,
-+ 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x52, 0x3A,
-+ 0x5A, 0x53, 0x53, 0x29, 0x43, 0x50, 0x53, 0x5A,
-+ 0x5A, 0x29, 0x5A, 0x43, 0x53, 0x5D, 0x44, 0x2A,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x55,
-+ 0x7D, 0x87, 0x8E, 0x93, 0xA8, 0xA9, 0xAA, 0x2A,
-+ 0x57, 0x94, 0xA4, 0x9B, 0xAB, 0xAC, 0x9A, 0x9B,
-+ 0xAD, 0x76, 0x79, 0x78, 0x75, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x75, 0x6D,
-+ 0x46, 0x5C, 0x57, 0x56, 0x51, 0x42, 0x4C, 0x55,
-+ 0x23, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x23, 0x24, 0x25, 0x26, 0x26, 0x27, 0x28, 0x27,
-+ 0x29, 0x2A, 0x2B, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x38, 0x30,
-+ 0x59, 0x3D, 0x3D, 0x3D, 0x27, 0x27, 0x26, 0x5D,
-+ 0x27, 0x27, 0x54, 0x37, 0x2E, 0x4A, 0x36, 0x2B,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0xAE, 0x88, 0xAF, 0xB0, 0xAA, 0x2A, 0x39, 0x34,
-+ 0x4C, 0x5C, 0x58, 0xB1, 0xB2, 0xB3, 0xAB, 0xA5,
-+ 0x9A, 0xB4, 0xB5, 0x8C, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x80,
-+ 0xB6, 0x38, 0x5C, 0x57, 0x56, 0x3F, 0x42, 0x3B,
-+ 0x55, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23,
-+ 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x32,
-+ 0x31, 0x2C, 0x26, 0x2C, 0x33, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x34,
-+ 0x32, 0x2B, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x33,
-+ 0x33, 0x55, 0x55, 0x55, 0x23, 0x23, 0x35, 0x23,
-+ 0x23, 0x35, 0x2B, 0x4E, 0x4F, 0x2A, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x55, 0x38, 0x25,
-+ 0x2C, 0x52, 0x34, 0x22, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x55, 0x8A, 0x8F, 0x39, 0x34, 0x3C, 0x57, 0x32,
-+ 0x46, 0x42, 0x52, 0x4A, 0x51, 0xAA, 0xB7, 0xB3,
-+ 0xAB, 0xAC, 0xAC, 0xB8, 0xB9, 0x79, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x7A,
-+ 0xBA, 0x70, 0x7B, 0xBB, 0x82, 0x56, 0x3F, 0x34,
-+ 0x4C, 0x55, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35, 0x36,
-+ 0x2D, 0x37, 0x38, 0x2A, 0x2B, 0x21, 0x21, 0x21,
-+ 0x21, 0x22, 0x39, 0x3A, 0x2C, 0x3B, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x33, 0x3C, 0x22, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x24, 0x3D,
-+ 0x3E, 0x25, 0x3C, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x33, 0x29, 0x26, 0x2A, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x3B, 0x54, 0x3E, 0x28,
-+ 0x28, 0x59, 0x59, 0x48, 0x51, 0x3F, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x2B, 0x56, 0x4D, 0x29, 0x5B, 0x34,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x55, 0x60, 0x3F, 0x42, 0x51, 0x32, 0x52,
-+ 0x40, 0x38, 0x40, 0x46, 0x42, 0xBC, 0xBD, 0xBE,
-+ 0xBF, 0x9B, 0xAB, 0x9B, 0xC0, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x75,
-+ 0xA7, 0x63, 0x63, 0x66, 0x6F, 0x58, 0x56, 0x39,
-+ 0x34, 0x2B, 0x23, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x24, 0x2F,
-+ 0x3D, 0x3F, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x22, 0x40, 0x41, 0x3B, 0x21,
-+ 0x21, 0x22, 0x42, 0x38, 0x43, 0x44, 0x3A, 0x45,
-+ 0x34, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x46, 0x30, 0x47,
-+ 0x2A, 0x48, 0x48, 0x21, 0x21, 0x21, 0x21, 0x22,
-+ 0x23, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x22, 0x34, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x22, 0x4D, 0x44, 0x2A, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x22, 0x50, 0x4A, 0x57, 0x35,
-+ 0x35, 0x2B, 0x56, 0x27, 0x4B, 0x5D, 0x35, 0x21,
-+ 0x21, 0x21, 0x21, 0x3B, 0x52, 0x23, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2B,
-+ 0x55, 0x21, 0x21, 0x21, 0x21, 0x21, 0x3B, 0x38,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x33,
-+ 0x3C, 0x42, 0x21, 0x33, 0x24, 0x35, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x33,
-+ 0x2B, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x33, 0x38, 0x59, 0x37, 0x27, 0x27, 0x4A, 0x47,
-+ 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x23, 0x4C, 0x4C, 0x2A, 0x56, 0x46, 0x31,
-+ 0x4D, 0x36, 0x50, 0x5A, 0x35, 0xC1, 0xC1, 0xC2,
-+ 0xC3, 0xB7, 0xB3, 0xBE, 0x76, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x75,
-+ 0x6D, 0x62, 0x69, 0x6F, 0x58, 0x46, 0x32, 0x2A,
-+ 0x39, 0x34, 0x35, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x3B, 0x44, 0x49,
-+ 0x31, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x23, 0x29, 0x48, 0x22,
-+ 0x42, 0x3A, 0x4A, 0x49, 0x4B, 0x2E, 0x4B, 0x3E,
-+ 0x4A, 0x2C, 0x34, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x4C, 0x30, 0x40, 0x22,
-+ 0x21, 0x32, 0x3A, 0x22, 0x21, 0x21, 0x21, 0x39,
-+ 0x36, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22,
-+ 0x31, 0x4F, 0x2A, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x31, 0x59, 0x2A, 0x22, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x55, 0x27, 0x24, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x4C, 0x44, 0x27, 0x35, 0x21,
-+ 0x21, 0x21, 0x21, 0x2A, 0x26, 0x2B, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x3A,
-+ 0x40, 0x21, 0x21, 0x21, 0x21, 0x21, 0x51, 0x49,
-+ 0x35, 0x21, 0x21, 0x21, 0x21, 0x22, 0x58, 0x25,
-+ 0x5A, 0x57, 0x21, 0x4C, 0x3D, 0x34, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x38,
-+ 0x47, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35,
-+ 0x3A, 0x4B, 0x53, 0x56, 0x55, 0x33, 0x42, 0x56,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x55, 0x4C, 0x42, 0x2A, 0x57, 0x5C, 0x38,
-+ 0x36, 0x47, 0x5A, 0xB6, 0x77, 0xC4, 0xC1, 0xC1,
-+ 0xC4, 0xC5, 0xB7, 0xB9, 0x79, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x75,
-+ 0x97, 0xC6, 0x68, 0x57, 0x4D, 0x38, 0x46, 0x32,
-+ 0x51, 0x42, 0x2B, 0x35, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x4D, 0x2D, 0x38,
-+ 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x4C, 0x4E, 0x3C,
-+ 0x47, 0x4F, 0x50, 0x51, 0x3F, 0x44, 0x42, 0x34,
-+ 0x52, 0x53, 0x28, 0x2A, 0x22, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x48, 0x54, 0x33, 0x21,
-+ 0x23, 0x3A, 0x3A, 0x22, 0x21, 0x21, 0x21, 0x2A,
-+ 0x26, 0x33, 0x21, 0x21, 0x21, 0x21, 0x23, 0x45,
-+ 0x37, 0x3D, 0x41, 0x22, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x31,
-+ 0x59, 0x3F, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x3C, 0x28, 0x33, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x23, 0x27, 0x5B, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x3C, 0x54, 0x55, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x4C, 0x4B,
-+ 0x46, 0x21, 0x21, 0x21, 0x21, 0x21, 0x3B, 0x49,
-+ 0x2B, 0x21, 0x21, 0x21, 0x23, 0x40, 0x43, 0x32,
-+ 0x35, 0x21, 0x21, 0x33, 0x28, 0x4C, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x4F,
-+ 0x5B, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x50,
-+ 0x44, 0x39, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x23, 0x3B, 0x34, 0x3F, 0x58, 0x46, 0x40, 0x36,
-+ 0x50, 0x41, 0x4D, 0xC7, 0x65, 0xC2, 0xC1, 0xC1,
-+ 0xC8, 0xBF, 0xB1, 0x97, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79,
-+ 0x80, 0xC9, 0x36, 0x50, 0x36, 0x38, 0x31, 0x32,
-+ 0x56, 0x39, 0x34, 0x33, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x2B, 0x3D, 0x28, 0x35,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x40, 0x4D,
-+ 0x55, 0x2B, 0x21, 0x21, 0x2B, 0x28, 0x3B, 0x21,
-+ 0x21, 0x22, 0x52, 0x27, 0x56, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x23, 0x2A, 0x30, 0x3F, 0x21, 0x22,
-+ 0x57, 0x44, 0x58, 0x21, 0x21, 0x21, 0x21, 0x56,
-+ 0x37, 0x2B, 0x21, 0x21, 0x21, 0x21, 0x56, 0x3E,
-+ 0x36, 0x2A, 0x59, 0x23, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x33, 0x50, 0x3D,
-+ 0x42, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x40, 0x5A, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x56, 0x49, 0x24, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x42, 0x54, 0x33, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x4D, 0x59,
-+ 0x55, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35, 0x4A,
-+ 0x51, 0x21, 0x21, 0x33, 0x47, 0x47, 0x33, 0x21,
-+ 0x21, 0x21, 0x21, 0x55, 0x27, 0x3B, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x32, 0x4B,
-+ 0x4C, 0x21, 0x21, 0x21, 0x21, 0x21, 0x34, 0x44,
-+ 0x3F, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x33, 0x4C, 0x3C, 0x51, 0x57, 0x5C, 0x38, 0x38,
-+ 0x9D, 0xCA, 0x61, 0xCB, 0xCC, 0xCD, 0xC4, 0xC8,
-+ 0xA4, 0x9C, 0x76, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79,
-+ 0x7A, 0x7F, 0x41, 0x29, 0x47, 0x38, 0x40, 0x57,
-+ 0x32, 0x51, 0x42, 0x2B, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x57, 0x49, 0x32, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x57, 0x27,
-+ 0x35, 0x21, 0x21, 0x21, 0x2B, 0x59, 0x2A, 0x21,
-+ 0x21, 0x21, 0x21, 0x56, 0x54, 0x2B, 0x21, 0x21,
-+ 0x21, 0x21, 0x4C, 0x2E, 0x5A, 0x23, 0x55, 0x5B,
-+ 0x49, 0x3A, 0x22, 0x21, 0x21, 0x21, 0x21, 0x32,
-+ 0x3E, 0x3B, 0x21, 0x21, 0x21, 0x35, 0x54, 0x53,
-+ 0x23, 0x55, 0x4F, 0x55, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x4C, 0x25, 0x44, 0x42,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x23, 0x41, 0x46, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x23, 0x53, 0x2F, 0x2A, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x32, 0x28, 0x33, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x35, 0x59, 0x5B,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x54,
-+ 0x57, 0x21, 0x35, 0x53, 0x47, 0x23, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x3C, 0x44, 0x3B, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x41, 0x43,
-+ 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x3F, 0x29,
-+ 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x55, 0x4C, 0x3F, 0x2A, 0x46, 0x31, 0x36, 0x46,
-+ 0x71, 0x97, 0xCE, 0xCB, 0xCF, 0xA4, 0x9C, 0xA4,
-+ 0xAD, 0x76, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x80, 0x8C,
-+ 0x7A, 0xA7, 0x36, 0x50, 0x3A, 0x36, 0x38, 0x52,
-+ 0x32, 0x2A, 0x3F, 0x2B, 0x22, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x22, 0x5A, 0x5A, 0x23, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x52, 0x28,
-+ 0x35, 0x21, 0x21, 0x21, 0x55, 0x30, 0x56, 0x21,
-+ 0x21, 0x21, 0x21, 0x22, 0x5B, 0x45, 0x21, 0x21,
-+ 0x21, 0x21, 0x2B, 0x2E, 0x25, 0x47, 0x3D, 0x2D,
-+ 0x25, 0x4C, 0x21, 0x21, 0x21, 0x21, 0x21, 0x39,
-+ 0x44, 0x55, 0x21, 0x21, 0x21, 0x46, 0x59, 0x3B,
-+ 0x21, 0x23, 0x30, 0x34, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x2A, 0x28, 0x4E, 0x42, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x3C, 0x3D, 0x42, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x51, 0x4B, 0x49, 0x39, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x5C, 0x25, 0x23, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x38, 0x4B, 0x3B,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x54,
-+ 0x56, 0x21, 0x5B, 0x3A, 0x35, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x51, 0x59, 0x55, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x32, 0x2D, 0x42,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x4C, 0x3A,
-+ 0x23, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x2B, 0x3C, 0x39, 0x56, 0x46, 0x40, 0x36, 0xB6,
-+ 0x73, 0x82, 0xCB, 0xD0, 0x75, 0xD1, 0xD2, 0xD1,
-+ 0x8C, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x74, 0xCE,
-+ 0x9E, 0x6E, 0xD3, 0xC6, 0x6F, 0x81, 0x38, 0x5C,
-+ 0x52, 0x58, 0x39, 0x4C, 0x35, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x4C, 0x4A, 0x40, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x36, 0x3A,
-+ 0x21, 0x21, 0x21, 0x21, 0x55, 0x27, 0x3F, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x3B, 0x25, 0x3B, 0x21,
-+ 0x21, 0x21, 0x42, 0x2E, 0x2D, 0x2D, 0x26, 0x46,
-+ 0x35, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x51,
-+ 0x44, 0x55, 0x21, 0x21, 0x35, 0x25, 0x40, 0x21,
-+ 0x21, 0x22, 0x4E, 0x58, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x39, 0x59, 0x38, 0x35, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x56, 0x59, 0x23, 0x21, 0x21, 0x21,
-+ 0x21, 0x4C, 0x54, 0x5B, 0x59, 0x4C, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x57, 0x3A, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x22, 0x4D, 0x49, 0x26, 0x23,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x53,
-+ 0x32, 0x51, 0x27, 0x42, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x42, 0x25, 0x35, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x22, 0x24, 0x37, 0x3E, 0x35,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x48,
-+ 0x48, 0x33, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x33,
-+ 0x3B, 0x39, 0x3F, 0x32, 0x5C, 0x38, 0x47, 0xD4,
-+ 0x7A, 0xC7, 0xCB, 0xD0, 0x74, 0x80, 0x8C, 0x9F,
-+ 0x80, 0x79, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x73, 0x72, 0xD5, 0xCA, 0x61, 0xD3, 0x40, 0x5C,
-+ 0x46, 0x58, 0x51, 0x42, 0x33, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x39, 0x4B, 0x58, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x2A, 0x3D, 0x51,
-+ 0x21, 0x21, 0x21, 0x21, 0x55, 0x28, 0x42, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x47, 0x52, 0x21,
-+ 0x21, 0x21, 0x58, 0x59, 0x42, 0x3C, 0x35, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x57,
-+ 0x4E, 0x23, 0x21, 0x22, 0x4D, 0x54, 0x35, 0x21,
-+ 0x21, 0x21, 0x5A, 0x46, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x22, 0x56, 0x59, 0x36, 0x35, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x36, 0x5B, 0x21, 0x21, 0x21, 0x21,
-+ 0x23, 0x53, 0x48, 0x3F, 0x27, 0x55, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x24, 0x47, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x22, 0x40, 0x27, 0x29, 0x29, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x47,
-+ 0x40, 0x41, 0x5C, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x39, 0x41, 0x23, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x32, 0x26, 0x47, 0x28, 0x22,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2B,
-+ 0x53, 0x28, 0x36, 0x42, 0x23, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35,
-+ 0x4C, 0x39, 0x58, 0x32, 0x31, 0x38, 0x47, 0xD4,
-+ 0xCF, 0xD0, 0x6C, 0x9E, 0xD6, 0x6B, 0xD7, 0xD8,
-+ 0xD7, 0x6B, 0xCF, 0x7B, 0x80, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x74, 0x72, 0xD0, 0xA6, 0x70, 0x51,
-+ 0x46, 0x56, 0x51, 0x42, 0x55, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x5C, 0x27, 0x35, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x32, 0x37, 0x54, 0x33,
-+ 0x21, 0x21, 0x21, 0x21, 0x2B, 0x44, 0x2A, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x52, 0x2C, 0x21,
-+ 0x21, 0x21, 0x47, 0x36, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x52,
-+ 0x54, 0x23, 0x21, 0x24, 0x4F, 0x46, 0x21, 0x21,
-+ 0x21, 0x21, 0x38, 0x2C, 0x22, 0x21, 0x21, 0x21,
-+ 0x21, 0x42, 0x55, 0x21, 0x21, 0x21, 0x21, 0x33,
-+ 0x45, 0x54, 0x56, 0x22, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x22, 0x53, 0x24, 0x21, 0x21, 0x21, 0x21,
-+ 0x46, 0x5D, 0x4C, 0x52, 0x4E, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x31, 0x48, 0x22, 0x21, 0x21,
-+ 0x21, 0x22, 0x46, 0x54, 0x3B, 0x45, 0x29, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x47,
-+ 0x28, 0x28, 0x55, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x51, 0x41, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x56, 0x54, 0x39, 0x56, 0x28, 0x22,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x23, 0x34, 0x50, 0x30, 0x4E, 0x40, 0x34, 0x22,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35,
-+ 0x4C, 0x39, 0x58, 0x52, 0x5C, 0x38, 0x47, 0x9D,
-+ 0xC9, 0xD9, 0xDA, 0xDB, 0xDC, 0xDC, 0xDC, 0xDC,
-+ 0xDC, 0xDC, 0xDC, 0xDD, 0x6B, 0x7B, 0x75, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x74, 0x71, 0xD0, 0x3F,
-+ 0x52, 0x57, 0x2A, 0x42, 0x2B, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x47, 0x3A, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x35, 0x45, 0x4A, 0x2C, 0x3B, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x2B, 0x30, 0x56, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x58, 0x29, 0x21,
-+ 0x21, 0x21, 0x53, 0x3F, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x31,
-+ 0x43, 0x22, 0x3B, 0x28, 0x48, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x56, 0x25, 0x35, 0x21, 0x21, 0x21,
-+ 0x39, 0x54, 0x34, 0x21, 0x21, 0x21, 0x35, 0x3A,
-+ 0x30, 0x57, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x33, 0x39, 0x21, 0x21,
-+ 0x21, 0x35, 0x25, 0x3F, 0x21, 0x21, 0x21, 0x56,
-+ 0x30, 0x58, 0x21, 0x24, 0x43, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x4D, 0x29, 0x22, 0x21, 0x21,
-+ 0x22, 0x32, 0x26, 0x42, 0x21, 0x46, 0x2C, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x48,
-+ 0x2E, 0x36, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x56, 0x28, 0x35, 0x21, 0x21,
-+ 0x21, 0x3F, 0x27, 0x32, 0x21, 0x51, 0x25, 0x22,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x22, 0x39, 0x38, 0x25, 0x54, 0x50,
-+ 0x58, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x33,
-+ 0x4C, 0x3F, 0x56, 0x52, 0x31, 0x4D, 0x47, 0x39,
-+ 0xD8, 0xDC, 0xDC, 0xDC, 0xDE, 0xDF, 0xDF, 0xDF,
-+ 0xDF, 0xDF, 0xDE, 0xDE, 0xDC, 0xDD, 0xD6, 0x97,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x75, 0x97, 0x56,
-+ 0x46, 0x57, 0x2A, 0x42, 0x2B, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x38, 0x29, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x35, 0x5B, 0x3D, 0x40, 0x35, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x2B, 0x59, 0x3F, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x40, 0x5A, 0x21,
-+ 0x21, 0x22, 0x5D, 0x34, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x5B,
-+ 0x2C, 0x33, 0x29, 0x28, 0x3B, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x34, 0x59, 0x3C, 0x21, 0x21, 0x2B,
-+ 0x53, 0x36, 0x22, 0x21, 0x21, 0x34, 0x5A, 0x28,
-+ 0x3F, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x40, 0x41, 0x23, 0x21,
-+ 0x21, 0x3B, 0x28, 0x2B, 0x21, 0x21, 0x2A, 0x44,
-+ 0x38, 0x22, 0x21, 0x24, 0x50, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x50, 0x25, 0x23, 0x21, 0x23,
-+ 0x45, 0x5D, 0x52, 0x21, 0x21, 0x40, 0x50, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x50,
-+ 0x2D, 0x39, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x46, 0x30, 0x33, 0x21, 0x22,
-+ 0x24, 0x4E, 0x45, 0x22, 0x21, 0x58, 0x25, 0x22,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x33, 0x3C, 0x48,
-+ 0x27, 0x39, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35,
-+ 0x34, 0x3F, 0x58, 0x57, 0x31, 0x4D, 0x47, 0x56,
-+ 0xDB, 0xDC, 0xDE, 0xE0, 0xE1, 0xE2, 0xE2, 0xE2,
-+ 0xE2, 0xE2, 0xE1, 0xE3, 0xE4, 0xDE, 0xDC, 0x6B,
-+ 0x8C, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x80, 0xA7, 0x38,
-+ 0x46, 0x56, 0x2A, 0x39, 0x3B, 0x23, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x32, 0x44, 0x34, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x3F,
-+ 0x4D, 0x41, 0x29, 0x42, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x2B, 0x44, 0x46, 0x34,
-+ 0x2B, 0x55, 0x55, 0x2B, 0x56, 0x59, 0x36, 0x21,
-+ 0x21, 0x22, 0x59, 0x2B, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x55, 0x5C, 0x21, 0x21, 0x21, 0x40,
-+ 0x50, 0x4D, 0x4F, 0x32, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x55, 0x44, 0x31, 0x22, 0x3B, 0x5A,
-+ 0x41, 0x55, 0x21, 0x35, 0x57, 0x4A, 0x2E, 0x48,
-+ 0x57, 0x32, 0x3F, 0x55, 0x35, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x25, 0x47, 0x22, 0x21,
-+ 0x21, 0x4C, 0x28, 0x35, 0x21, 0x34, 0x30, 0x3A,
-+ 0x23, 0x21, 0x21, 0x58, 0x3A, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x4D, 0x4E, 0x35, 0x33, 0x48,
-+ 0x44, 0x56, 0x21, 0x21, 0x21, 0x58, 0x41, 0x23,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x29,
-+ 0x4A, 0x23, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x32, 0x44, 0x2B, 0x23, 0x45,
-+ 0x3D, 0x31, 0x22, 0x21, 0x21, 0x4C, 0x27, 0x35,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35,
-+ 0x53, 0x53, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35,
-+ 0x34, 0x3F, 0x58, 0x57, 0x40, 0x38, 0x47, 0xD4,
-+ 0xDC, 0xDE, 0xE0, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE2, 0xE1, 0xDF, 0xDC,
-+ 0xE6, 0x8C, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x80, 0x2A, 0x40,
-+ 0x46, 0x58, 0x2A, 0x42, 0x34, 0x34, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x2B, 0x54, 0x5A, 0x34, 0x23,
-+ 0x35, 0x23, 0x35, 0x33, 0x2B, 0x24, 0x54, 0x4B,
-+ 0x59, 0x5C, 0x23, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x4C, 0x4B, 0x44, 0x59,
-+ 0x27, 0x26, 0x26, 0x4A, 0x3E, 0x41, 0x55, 0x21,
-+ 0x21, 0x22, 0x41, 0x39, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x34, 0x53, 0x4D, 0x21, 0x21, 0x21, 0x5C,
-+ 0x4B, 0x4F, 0x40, 0x22, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x48, 0x30, 0x50, 0x26, 0x54,
-+ 0x34, 0x21, 0x55, 0x4E, 0x2D, 0x2F, 0x4F, 0x37,
-+ 0x3E, 0x4B, 0x4B, 0x30, 0x27, 0x53, 0x2C, 0x57,
-+ 0x42, 0x4C, 0x55, 0x22, 0x22, 0x22, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x39, 0x4A, 0x3F, 0x21, 0x21,
-+ 0x21, 0x55, 0x53, 0x55, 0x2A, 0x26, 0x54, 0x33,
-+ 0x21, 0x21, 0x21, 0x51, 0x54, 0x3B, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x51, 0x3D, 0x46, 0x5A, 0x4F,
-+ 0x52, 0x21, 0x21, 0x21, 0x21, 0x22, 0x27, 0x31,
-+ 0x33, 0x23, 0x42, 0x4C, 0x21, 0x21, 0x21, 0x5B,
-+ 0x54, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x3B, 0x44, 0x45, 0x48, 0x4B,
-+ 0x38, 0x22, 0x21, 0x21, 0x21, 0x21, 0x53, 0x48,
-+ 0x33, 0x23, 0x34, 0x3C, 0x22, 0x57, 0x4D, 0x33,
-+ 0x21, 0x21, 0x21, 0x21, 0x22, 0x23, 0x34, 0x40,
-+ 0x44, 0x31, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35,
-+ 0x3B, 0x42, 0x2A, 0x57, 0x31, 0x38, 0x5C, 0xD8,
-+ 0xDC, 0xE4, 0xE2, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE2, 0xE0,
-+ 0xDE, 0xCA, 0x9F, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x80, 0x76, 0x57, 0x5C,
-+ 0x31, 0x6E, 0x34, 0x3C, 0xC9, 0x3B, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x33, 0x5B, 0x30, 0x25,
-+ 0x5D, 0x5A, 0x53, 0x27, 0x26, 0x59, 0x36, 0x56,
-+ 0x55, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x3B, 0x3D, 0x2A, 0x55,
-+ 0x42, 0x51, 0x56, 0x24, 0x2A, 0x35, 0x21, 0x21,
-+ 0x21, 0x21, 0x45, 0x53, 0x3B, 0x22, 0x22, 0x35,
-+ 0x46, 0x59, 0x54, 0x55, 0x21, 0x21, 0x21, 0x31,
-+ 0x2D, 0x47, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x33, 0x50, 0x5D, 0x45, 0x55,
-+ 0x21, 0x21, 0x34, 0x4F, 0x29, 0x58, 0x33, 0x4C,
-+ 0x39, 0x3C, 0x2A, 0x40, 0x48, 0x54, 0x3D, 0x3D,
-+ 0x37, 0x4A, 0x59, 0x29, 0x5B, 0x36, 0x52, 0x2A,
-+ 0x42, 0x3C, 0x32, 0x30, 0x41, 0x35, 0x21, 0x21,
-+ 0x21, 0x33, 0x41, 0x26, 0x4B, 0x5A, 0x35, 0x21,
-+ 0x21, 0x21, 0x21, 0x3C, 0x3E, 0x41, 0x23, 0x21,
-+ 0x21, 0x21, 0x21, 0x23, 0x41, 0x49, 0x30, 0x32,
-+ 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x52, 0x4F,
-+ 0x5D, 0x41, 0x27, 0x58, 0x21, 0x21, 0x21, 0x5B,
-+ 0x41, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x47, 0x49, 0x4F, 0x5C,
-+ 0x23, 0x21, 0x21, 0x21, 0x21, 0x21, 0x39, 0x4A,
-+ 0x28, 0x43, 0x27, 0x5C, 0x35, 0x25, 0x49, 0x5B,
-+ 0x58, 0x52, 0x5C, 0x38, 0x48, 0x41, 0x4A, 0x4B,
-+ 0x50, 0x33, 0x21, 0x21, 0x21, 0x21, 0x21, 0x35,
-+ 0x3B, 0x3C, 0x2A, 0x32, 0x5C, 0x40, 0x32, 0xDD,
-+ 0xDC, 0xE3, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE1, 0xE0, 0xBB, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x80, 0xE7, 0x58, 0x52,
-+ 0x5C, 0x67, 0xE7, 0x6C, 0xE8, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x23, 0x39, 0x5C,
-+ 0x29, 0x5A, 0x4D, 0x5C, 0x2A, 0x2B, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x3B, 0x44, 0x42, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x33, 0x27, 0x30, 0x5A, 0x2C, 0x25,
-+ 0x4B, 0x50, 0x3B, 0x21, 0x21, 0x21, 0x21, 0x33,
-+ 0x2C, 0x3B, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x4C, 0x22, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x55, 0x2B,
-+ 0x39, 0x32, 0x4D, 0x29, 0x26, 0x3D, 0x2D, 0x2D,
-+ 0x4B, 0x4B, 0x2F, 0x30, 0x42, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x3B, 0x29, 0x2C, 0x55, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x23, 0x50, 0x4D, 0x22, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x2B, 0x32, 0x3B, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x51,
-+ 0x48, 0x45, 0x34, 0x21, 0x21, 0x21, 0x21, 0x38,
-+ 0x44, 0x35, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x33, 0x32, 0x34, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x3C,
-+ 0x5B, 0x4D, 0x42, 0x21, 0x21, 0x34, 0x4D, 0x47,
-+ 0x5A, 0x5D, 0x27, 0x4E, 0x25, 0x3A, 0x5C, 0x42,
-+ 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23,
-+ 0x2B, 0x34, 0x51, 0x56, 0x46, 0x40, 0xE9, 0xDA,
-+ 0xDD, 0xE1, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE2, 0xEA, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x76, 0xD3, 0x67, 0x39,
-+ 0x3C, 0xCF, 0xD5, 0x9F, 0x3B, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x3B, 0x28, 0x2B, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x3C, 0x53, 0x44, 0x3D, 0x43,
-+ 0x57, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x35, 0x55, 0x3F, 0x2A,
-+ 0x57, 0x24, 0x3F, 0x3B, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x22, 0x22, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x55,
-+ 0x3C, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x55, 0x4C, 0x3F, 0x58, 0x46, 0x31, 0x8B, 0xAD,
-+ 0xCC, 0xE2, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xEA, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x97, 0x35, 0x6E, 0xC6, 0x82,
-+ 0xA6, 0x73, 0x75, 0xBA, 0x2B, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x34, 0x44, 0x3B, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x23, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x33, 0x34, 0xEB, 0x34, 0x57, 0x5C, 0x4C, 0xA4,
-+ 0xEC, 0x64, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0x83, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x80, 0xED, 0xCF, 0xCE, 0x78, 0x78,
-+ 0x78, 0x7A, 0x6D, 0x34, 0x22, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x55, 0x25, 0x55, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x23, 0x34, 0xEE, 0xEF, 0x5F, 0x96, 0x23, 0xB3,
-+ 0xBF, 0xB5, 0xF0, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xBB, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x9F, 0x78, 0x78, 0x78, 0x78,
-+ 0x80, 0x9F, 0x65, 0x33, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x3B, 0x28, 0x55, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x22, 0x4C, 0xF1, 0xA5, 0xAC, 0xAB, 0x60, 0xB3,
-+ 0xB3, 0xF2, 0xEA, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xF3, 0x6D, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x80, 0x61, 0x34, 0x23, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x3B, 0x25, 0x22, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2B, 0x5E,
-+ 0x4C, 0x3B, 0xF4, 0xA5, 0x9B, 0x9B, 0xB4, 0xEF,
-+ 0xEF, 0xBF, 0xAD, 0xF5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0x67, 0x75, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x80,
-+ 0xA7, 0x3F, 0x55, 0x22, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x4C, 0x4E, 0x23, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x2B, 0x5F,
-+ 0x9B, 0xD2, 0x3C, 0xB7, 0xEF, 0xEF, 0xEF, 0xEF,
-+ 0xEF, 0xB3, 0xB8, 0xEA, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0xF0, 0xBB, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x80, 0x82,
-+ 0x34, 0x3B, 0x33, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x4C, 0x5D, 0x23, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x60,
-+ 0xAB, 0xA5, 0xB8, 0xB1, 0xEF, 0xEF, 0xEF, 0xEF,
-+ 0xEF, 0xF6, 0xB7, 0xB5, 0xF0, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5,
-+ 0x67, 0x80, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x78, 0x80, 0x9F, 0xBA, 0x42,
-+ 0x4C, 0x2B, 0x22, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x4C, 0x3A, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x55,
-+ 0xF2, 0x9B, 0x9B, 0xB4, 0xEF, 0xEF, 0xEF, 0xEF,
-+ 0xEF, 0xEF, 0xB4, 0x5F, 0x63, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xF5,
-+ 0x76, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x78, 0x78, 0x80, 0x6D, 0x65, 0x3C, 0x34,
-+ 0x3B, 0x35, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x2A, 0x29, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23,
-+ 0xF7, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
-+ 0xEF, 0xEF, 0xB3, 0xB8, 0xEA, 0xE5, 0xE5, 0xE5,
-+ 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xE5, 0xF8, 0x68,
-+ 0x7A, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x78, 0x80, 0x97, 0x82, 0x39, 0x39, 0x34, 0x3B,
-+ 0x33, 0x23, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x2A, 0x29, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x3B, 0xB8, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
-+ 0xEF, 0xEF, 0xF6, 0xB2, 0xF9, 0xFA, 0xFA, 0xFA,
-+ 0xFA, 0xF8, 0xF8, 0xF8, 0xF0, 0xF0, 0x6F, 0x97,
-+ 0x80, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78,
-+ 0x8C, 0x61, 0x39, 0x2A, 0x3F, 0x3C, 0x4C, 0x55,
-+ 0x33, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x4C, 0x31, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x22, 0xFB, 0xF6, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
-+ 0xEF, 0xEF, 0xB3, 0xB2, 0xF9, 0xF3, 0xF3, 0xF3,
-+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0x90, 0x6D, 0x97,
-+ 0x8C, 0x6D, 0x76, 0xBB, 0xC6, 0xB9, 0xC0, 0xFC,
-+ 0xAD, 0xFB, 0x2A, 0x58, 0x42, 0x4C, 0x55, 0x33,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x33, 0xD2, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
-+ 0xEF, 0xEF, 0xB4, 0xB8, 0xEB, 0xE8, 0x7F, 0xD6,
-+ 0xD6, 0xD6, 0xD6, 0x9D, 0x9D, 0x52, 0xEB, 0x5F,
-+ 0x5F, 0x5F, 0xF2, 0xA4, 0xBF, 0xBF, 0xB4, 0xBF,
-+ 0xEE, 0x56, 0x2A, 0x42, 0x4C, 0x2B, 0x33, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x4C, 0xBE, 0xF6, 0xEF, 0xEF, 0xEF,
-+ 0xF6, 0xB4, 0xB2, 0xF1, 0x3C, 0x56, 0x46, 0x5C,
-+ 0x31, 0x38, 0x40, 0x40, 0x4D, 0x4D, 0xB8, 0xAC,
-+ 0xBF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xB4,
-+ 0xB1, 0x39, 0x39, 0x3B, 0x2B, 0x23, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x3B, 0xAD, 0xA4, 0xBF, 0xBF,
-+ 0xB7, 0xB2, 0xEE, 0x5E, 0x39, 0x51, 0x2A, 0x32,
-+ 0x52, 0x46, 0x5C, 0x31, 0x31, 0x2A, 0xA5, 0xEF,
-+ 0xFD, 0xB4, 0xEF, 0xF6, 0xF6, 0xEF, 0xF6, 0xB2,
-+ 0x3F, 0x34, 0x2B, 0x55, 0x23, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x33, 0xEB, 0xF7, 0xAA,
-+ 0xAA, 0xF7, 0xEB, 0x55, 0x3B, 0x3C, 0x39, 0x51,
-+ 0x2A, 0x56, 0x32, 0x57, 0x57, 0x2A, 0x96, 0x3C,
-+ 0x2A, 0xEE, 0xEF, 0x5F, 0xD2, 0xEF, 0xB4, 0xAA,
-+ 0x42, 0x55, 0x35, 0x22, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x3B,
-+ 0x3B, 0x35, 0x21, 0x23, 0x33, 0x3B, 0x4C, 0x3C,
-+ 0x39, 0x3F, 0x51, 0x2A, 0x51, 0x51, 0x58, 0x32,
-+ 0x56, 0xF4, 0xB1, 0x42, 0x3C, 0xF2, 0x9C, 0x3F,
-+ 0x33, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x33, 0x55,
-+ 0x3B, 0x4C, 0x4C, 0x3C, 0x42, 0x42, 0x3C, 0x34,
-+ 0x34, 0x3F, 0x4C, 0x3B, 0x4C, 0x3B, 0x3C, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x35, 0x33, 0x55, 0x33, 0x33, 0x33, 0x55, 0x2B,
-+ 0x2B, 0x35, 0x35, 0x35, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
-+ 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
- };
-
- #endif /* !__HAVE_ARCH_LINUX_LOGO */
-@@ -994,7 +1760,7 @@
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
- };
-
- #endif /* !__HAVE_ARCH_LINUX_LOGOBW */
-@@ -1401,7 +2167,7 @@
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
-
- #endif /* !__HAVE_ARCH_LINUX_LOGO16 */
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/mkdep.patch b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/mkdep.patch
deleted file mode 100644
index 4daeaa11be..0000000000
--- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/mkdep.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-
-#
-# Made by http://www.mn-logistik.de/unsupported/pxa250/patcher
-#
-
---- linux/Makefile~mkdep 2003-12-19 09:36:51.000000000 -0800
-+++ linux/Makefile 2003-12-19 09:57:44.000000000 -0800
-@@ -458,7 +458,7 @@
-
- dep-files: scripts/mkdep archdep include/linux/version.h
- scripts/mkdep -- init/*.c > .depend
-- scripts/mkdep -- `find $(FINDHPATH) -name SCCS -prune -o -follow -name \*.h ! -name modversions.h -print` > .hdepend
-+ $(foreach, dir, $(FINDHPATH), scripts/mkdep -- `find $(dir) -name SCCS -prune -o -follow -name \*.h ! -name modversions.h -print` >> .hdepend)
- $(MAKE) $(patsubst %,_sfdep_%,$(SUBDIRS)) _FASTDEP_ALL_SUB_DIRS="$(SUBDIRS)"
- ifdef CONFIG_MODVERSIONS
- $(MAKE) update-modverfile
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/module_licence.patch b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/module_licence.patch
deleted file mode 100644
index fc20f0d281..0000000000
--- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/module_licence.patch
+++ /dev/null
@@ -1,81 +0,0 @@
---- linux/drivers/usb/device/bi/sa1100.c.orig 2003-05-13 11:18:44.000000000 +0200
-+++ linux/drivers/usb/device/bi/sa1100.c 2004-08-01 13:49:10.000000000 +0200
-@@ -46,6 +46,7 @@
- #include "../usbd-build.h"
- #include "../usbd-module.h"
-
-+MODULE_LICENSE("GPL");
- MODULE_AUTHOR ("sl@lineo.com, tbr@lineo.com");
- MODULE_DESCRIPTION ("USB Device SA-1100 Bus Interface");
-
---- linux/drivers/usb/device/usbd.c.orig 2003-05-13 11:18:45.000000000 +0200
-+++ linux/drivers/usb/device/usbd.c 2004-08-01 13:47:47.000000000 +0200
-@@ -72,6 +72,7 @@
- #include "usbd-build.h"
- #include "usbd-module.h"
-
-+MODULE_LICENSE("GPL");
- MODULE_AUTHOR ("sl@lineo.com, tbr@lineo.com");
- MODULE_DESCRIPTION ("USB Device Core Support");
-
---- linux/drivers/usb/device/usbd-monitor.c.orig 2004-08-01 13:46:44.000000000 +0200
-+++ linux/drivers/usb/device/usbd-monitor.c 2004-08-01 13:46:36.000000000 +0200
-@@ -33,6 +33,7 @@
- #include "usbd-build.h"
- #include "usbd-module.h"
-
-+MODULE_LICENSE("GPL");
- MODULE_AUTHOR ("sl@lineo.com, tbr@lineo.com");
- MODULE_DESCRIPTION ("USB Device Monitor");
- USBD_MODULE_INFO ("usbd_monitor 0.3");
---- linux/drivers/usb/device/net_fd/net-fd.c.orig 2003-05-13 11:18:45.000000000 +0200
-+++ linux/drivers/usb/device/net_fd/net-fd.c 2004-08-01 13:48:32.000000000 +0200
-@@ -33,6 +33,7 @@
- #include "../usbd-build.h"
- #include "../usbd-module.h"
-
-+MODULE_LICENSE("GPL");
- MODULE_AUTHOR ("sl@lineo.com, tbr@lineo.com");
- MODULE_DESCRIPTION ("USB Device Network Function");
-
---- linux/arch/arm/mach-sa1100/deviceinfo.c.orig 2004-08-01 13:56:24.000000000 +0200
-+++ linux/arch/arm/mach-sa1100/deviceinfo.c 2004-08-01 13:56:11.000000000 +0200
-@@ -28,6 +28,7 @@
-
- #define MODULE_NAME "deviceinfo"
- #define DEVINFO_DIRNAME "deviceinfo"
-+MODULE_LICENSE("GPL");
-
- static int proc_read_deviceinfo(struct file * file, char * buf,
- size_t nbytes, loff_t *ppos);
---- linux/arch/arm/mach-sa1100/gpio.c.orig 2003-05-13 11:18:14.000000000 +0200
-+++ linux/arch/arm/mach-sa1100/gpio.c 2004-08-01 13:55:27.000000000 +0200
-@@ -15,7 +15,7 @@
-
- #include <asm/hardware.h>
-
--
-+MODULE_LICENSE("GPL");
-
- static int proc_gpio_read(char *page, char **start, off_t off,
- int count, int *eof, void *data)
---- linux/drivers/usb/device/serial_fd/serial.c.orig 2003-05-13 11:18:45.000000000 +0200
-+++ linux/drivers/usb/device/serial_fd/serial.c 2004-08-01 14:25:02.000000000 +0200
-@@ -80,6 +80,7 @@
- #include "../usbd-module.h"
-
-
-+MODULE_LICENSE("GPL");
- MODULE_AUTHOR ("sl@lineo.com, tbr@lineo.com");
- MODULE_DESCRIPTION ("USB Device Serial Function");
-
---- linux/drivers/usb/device/usbd-serialnumber.c.orig 2003-05-13 11:18:45.000000000 +0200
-+++ linux/drivers/usb/device/usbd-serialnumber.c 2004-08-01 14:25:40.000000000 +0200
-@@ -33,6 +33,7 @@
- #include "usbd-build.h"
- #include "usbd-module.h"
-
-+MODULE_LICENSE("GPL");
- MODULE_AUTHOR ("sl@lineo.com, tbr@lineo.com");
- MODULE_DESCRIPTION ("USB Device Monitor");
- USBD_MODULE_INFO ("usbd_monitor 0.2-alpha");
diff --git a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/sound-2.4.18r2.patch b/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/sound-2.4.18r2.patch
deleted file mode 100644
index d75c07a1c8..0000000000
--- a/linux/openzaurus-sa-2.4.18-rmk7-pxa3-embedix20030509/sound-2.4.18r2.patch
+++ /dev/null
@@ -1,5602 +0,0 @@
-diff -Nuar linux-2.4.18/arch/arm/mach-sa1100/m62332.c linux-2.4.18p/arch/arm/mach-sa1100/m62332.c
---- linux-2.4.18/arch/arm/mach-sa1100/m62332.c 2003-05-13 11:18:14.000000000 +0200
-+++ linux-2.4.18p/arch/arm/mach-sa1100/m62332.c 2004-10-12 22:36:36.000000000 +0200
-@@ -131,3 +131,5 @@
-
- return 0;
- }
-+EXPORT_SYMBOL(m62332_senddata);
-+
-diff -Nuar linux-2.4.18/arch/arm/mach-sa1100/Makefile linux-2.4.18p/arch/arm/mach-sa1100/Makefile
---- linux-2.4.18/arch/arm/mach-sa1100/Makefile 2003-05-13 11:18:14.000000000 +0200
-+++ linux-2.4.18p/arch/arm/mach-sa1100/Makefile 2004-10-12 22:36:19.000000000 +0200
-@@ -18,7 +18,7 @@
- export-objs := assabet.o consus.o badge4.o dma-sa1100.o dma-sa1111.o \
- flexanet.o freebird.o generic.o h3600.o \
- huw_webpanel.o irq.o pcipool.o sa1111.o sa1111-pcibuf.o \
-- system3.o yopy.o usb_ctl.o usb_recv.o usb_send.o
-+ system3.o yopy.o usb_ctl.o usb_recv.o usb_send.o m62332.o
-
- # These aren't present yet, and prevents a plain -ac kernel building.
- # hwtimer.o
-@@ -36,7 +36,7 @@
- obj-$(CONFIG_SA1100_LART) += cpu-sa1100.o
- endif
-
--obj-$(CONFIG_SA1100_COLLIE) += collie.o m62332.o collie_battery.o collie_led.o collie_buzzer.o
-+obj-$(CONFIG_SA1100_COLLIE) += collie.o m62332.o collie_battery.o collie_led.o
-
- # Next, the SA1111 stuff.
- obj-$(CONFIG_SA1111) += sa1111.o dma-sa1111.o
-diff -Nuar linux-2.4.18/drivers/char/Makefile linux-2.4.18p/drivers/char/Makefile
---- linux-2.4.18/drivers/char/Makefile 2003-05-13 11:18:18.000000000 +0200
-+++ linux-2.4.18p/drivers/char/Makefile 2004-10-12 17:26:44.000000000 +0200
-@@ -228,7 +228,7 @@
- obj-y += joystick/js.o
- endif
-
--obj-$(CONFIG_SA1100_COLLIE) += sharp_led.o sharp_kbdctl.o sharp_buzzer.o
-+obj-$(CONFIG_SA1100_COLLIE) += sharp_led.o sharp_kbdctl.o
- obj-$(CONFIG_DISCOVERY_LED) += sharp_led.o discovery_led.o
- obj-$(CONFIG_ARCH_PXA_POODLE) += sharp_led.o sharp_kbdctl.o sharpsl_led.o sharp_buzzer.o
- obj-$(CONFIG_ARCH_PXA_CORGI) += sharp_led.o sharpsl_led.o sharp_kbdctl.o corgi_rc.o sharp_buzzer.o
-diff -Nuar linux-2.4.18/drivers/sound/colliebuzzer.h linux-2.4.18p/drivers/sound/colliebuzzer.h
---- linux-2.4.18/drivers/sound/colliebuzzer.h 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18p/drivers/sound/colliebuzzer.h 2004-10-13 15:24:51.028208808 +0200
-@@ -0,0 +1,756 @@
-+unsigned short tap_data[] = {
-+ 0x0000 , 0xff00 , 0xff00 , 0x0000 ,
-+ 0xff00 , 0x0000 , 0x0000 , 0x0100 ,
-+ 0x0000 , 0x0100 , 0x0000 , 0x0100 ,
-+ 0x0100 , 0x0000 , 0x0100 , 0x0100 ,
-+ 0x0100 , 0x0100 , 0x0100 , 0x0100 ,
-+ 0x0100 , 0x0100 , 0x0100 , 0x0100 ,
-+ 0x0100 , 0x0000 , 0x0100 , 0x0000 ,
-+ 0x0100 , 0xff00 , 0x0100 , 0x0000 ,
-+ 0x0100 , 0x0000 , 0x0000 , 0x0100 ,
-+ 0x0000 , 0x0100 , 0x0000 , 0x0100 ,
-+ 0x0000 , 0x0000 , 0x0000 , 0x0000 ,
-+ 0x0000 , 0x0100 , 0x0000 , 0x0100 ,
-+ 0x0000 , 0x0100 , 0x0700 , 0x1c00 ,
-+ 0xc800 , 0xd900 , 0x2b00 , 0x2700 ,
-+ 0xbf00 , 0xe000 , 0x0d00 , 0x1000 ,
-+ 0xf500 , 0xd700 , 0x0100 , 0x0a00 ,
-+ 0xfb00 , 0xfa00 , 0x2200 , 0x0100 ,
-+ 0xeb00 , 0x0300 , 0x0600 , 0x1600 ,
-+ 0xe500 , 0xf500 , 0x0d00 , 0x0a00 ,
-+ 0x0100 , 0xfb00 , 0x0000 , 0x0100 ,
-+ 0xf200 , 0x0400 , 0x0600 , 0x0000 ,
-+ 0xf100 , 0x0300 , 0x1200 , 0xfe00 ,
-+ 0xe900 , 0x0400 , 0x0100 , 0x0d00 ,
-+ 0xf500 , 0x0100 , 0x0100 , 0xfe00 ,
-+ 0x0100 , 0xfb00 , 0x0400 , 0xff00 ,
-+ 0xf700 , 0x0400 , 0x0000 , 0xfe00 ,
-+ 0x0200 , 0x0000 , 0x0100 , 0xfd00 ,
-+ 0x0000 , 0xff00 , 0x0200 , 0x0000 ,
-+ 0xff00 , 0x0000 , 0x0200 , 0xfc00 ,
-+ 0xfe00 , 0xff00 , 0x0100 , 0x0200 ,
-+ 0x0000 , 0xff00 , 0xfc00 , 0x0100 ,
-+ 0x0100 , 0x0100 , 0xff00 , 0x0000 ,
-+ 0x0300 , 0xfe00 , 0xfe00 , 0x0200 ,
-+ 0xff00 , 0x0000 , 0x0000 , 0xfe00 ,
-+ 0x0000 , 0xff00 , 0x0000 , 0x0000 ,
-+ 0x0000 , 0xff00 , 0x0000 , 0x0000 ,
-+ 0xff00 , 0xfe00 , 0xfd00 , 0x0100 ,
-+ 0x0000 , 0xfe00 , 0xff00 , 0xff00 ,
-+ 0x0000 , 0xff00 , 0x0100 , 0xfe00 ,
-+ 0xff00 , 0xff00 , 0x0000 , 0x0000 ,
-+ 0xfe00 , 0xff00 , 0x0100 , 0x0100 ,
-+ 0xff00 , 0x0100 , 0x0100 , 0xfe00 ,
-+ 0x0000 , 0x0000 , 0x0000 , 0x0100 ,
-+ 0x0000 , 0x0000 , 0xff00 , 0x0000 ,
-+ 0x0100 , 0x0000 , 0x0200 };
-+
-+
-+unsigned short click_data[] = {
-+ 0x0100 , 0x0100 , 0x0100 , 0x0000 ,
-+ 0x0100 , 0xff00 , 0x0100 , 0x0000 ,
-+ 0xff00 , 0xff00 , 0xff00 , 0x0000 ,
-+ 0xff00 , 0xff00 , 0xff00 , 0xff00 ,
-+ 0xff00 , 0xff00 , 0x0000 , 0xff00 ,
-+ 0xff00 , 0xff00 , 0x0000 , 0xff00 ,
-+ 0xff00 , 0xff00 , 0xff00 , 0x0100 ,
-+ 0x0000 , 0xff00 , 0xfe00 , 0x0100 ,
-+ 0xff00 , 0x0100 , 0xff00 , 0x0100 ,
-+ 0x0100 , 0x0300 , 0xff00 , 0xff00 ,
-+ 0xff00 , 0x0100 , 0x0100 , 0x0000 ,
-+ 0xfe00 , 0xfe00 , 0xfe00 , 0xfc00 ,
-+ 0xfe00 , 0x0100 , 0xfd00 , 0xff00 ,
-+ 0xff00 , 0xfc00 , 0xfe00 , 0xfd00 ,
-+ 0x0100 , 0xfe00 , 0x0100 , 0xf800 ,
-+ 0xfe00 , 0xfe00 , 0xfc00 , 0xe600 ,
-+ 0xdb00 , 0x2500 , 0xdb00 , 0xee00 ,
-+ 0xdb00 , 0x0600 , 0xeb00 , 0x1f00 ,
-+ 0x1e00 , 0xeb00 , 0xfe00 , 0x0000 ,
-+ 0xff00 , 0x1900 , 0xef00 , 0xf700 ,
-+ 0x2100 , 0xe400 , 0x0100 , 0x0600 ,
-+ 0xff00 , 0x0300 , 0xf900 , 0x0f00 ,
-+ 0xf600 , 0x0100 , 0xfe00 , 0xf900 ,
-+ 0x0500 , 0xf500 , 0x0600 , 0xfb00 ,
-+ 0x0800 , 0x0100 , 0x0300 , 0x0100 ,
-+ 0xf700 , 0xfa00 , 0xfd00 , 0xfc00 ,
-+ 0x0800 , 0xfb00 , 0x0500 , 0xfe00 ,
-+ 0xfc00 , 0xfc00 , 0xfe00 , 0x0400 ,
-+ 0xff00 , 0xff00 , 0x0500 , 0x0100 ,
-+ 0xfc00 , 0xff00 , 0xfe00 , 0xfb00 ,
-+ 0x0200 , 0x0200 , 0xff00 , 0xfe00 ,
-+ 0xfe00 , 0x0600 , 0xfb00 , 0xff00 ,
-+ 0xfc00 , 0x0600 , 0xfb00 , 0xff00 ,
-+ 0xff00 , 0x0100 , 0xff00 , 0x0200 ,
-+ 0xff00 , 0xfb00 , 0xff00 , 0x0200 ,
-+ 0xff00 , 0x0200 , 0x0100 , 0xfe00 ,
-+ 0xfe00 , 0x0100 , 0xfd00 , 0x0200 ,
-+ 0xfc00 , 0x0800 , 0xfe00 , 0xfe00 ,
-+ 0x0400 , 0xfc00 , 0xff00 , 0xfc00 ,
-+ 0x0500 , 0x0200 , 0x0800 , 0x0200 ,
-+ 0x0100 , 0xfe00 , 0x0100 , 0xff00 ,
-+ 0x0700 , 0xfb00 , 0xfc00 , 0x0100 ,
-+ 0xfe00 , 0xfc00 , 0x0b00 , 0xfb00 ,
-+ 0xfb00 , 0x0700 , 0xfb00 , 0xfb00 ,
-+ 0x0100 , 0xff00 , 0xfb00 , 0xfd00 ,
-+ 0x0000 , 0xfe00 , 0xfe00 , 0xff00 ,
-+ 0xfc00 , 0x0400 , 0x0000 , 0xfe00 ,
-+ 0xff00 , 0x0200 , 0xff00 , 0x0000 ,
-+ 0x0500 , 0x0100 , 0x0100 , 0x0100 ,
-+ 0x0100 , 0x0000 , 0x0300 , 0xfe00 ,
-+ 0xff00 , 0x0100 , 0x0100 , 0xfe00 ,
-+ 0x0000 , 0xff00 , 0x0100 , 0xff00 ,
-+ 0x0200 , 0xff00 , 0xff00 , 0xff00 ,
-+ 0xff00 , 0xfe00 , 0x0000 , 0xff00 ,
-+ 0xfe00 , 0xff00 , 0xfd00 , 0x0000 ,
-+ 0xff00 , 0xfe00 , 0xff00 , 0xfc00 ,
-+ 0x0100 , 0xfd00 , 0xff00 , 0xff00 ,
-+ 0x0200 , 0xff00 , 0x0100 , 0xff00 ,
-+ 0xfc00 , 0x0300 , 0xff00 , 0x0200 ,
-+ 0xff00 , 0x0100 , 0xff00 , 0x0100 ,
-+ 0xff00 , 0xff00 , 0x0100 , 0xfe00 ,
-+ 0x0300 , 0xfc00 , 0x0100 , 0xff00 ,
-+ 0x0100 , 0x0100 , 0x0100 , 0xfc00 ,
-+ 0xff00 , 0x0100 , 0x0100 , 0xfe00 ,
-+ 0x0100 , 0xff00 , 0x0100 , 0xfc00 ,
-+ 0x0100 , 0x0200 , 0xff00 , 0x0100 ,
-+ 0xff00 , 0xff00 , 0x0200 , 0xfd00 ,
-+ 0xfe00 , 0x0100 , 0xff00 , 0x0100 ,
-+ 0xfe00 , 0x0100 , 0x0300 , 0xfe00 ,
-+ 0x0300 , 0xfe00 , 0xff00 , 0x0100 ,
-+ 0xff00 , 0x0200 , 0xfd00 , 0x0000 ,
-+ 0xff00 , 0x0200 , 0xff00 , 0x0200 ,
-+ 0xff00 , 0x0100 , 0x0000 , 0xff00 ,
-+ 0x0200 , 0x0100 , 0x0000 , 0xff00 ,
-+ 0x0100 , 0xfe00 , 0x0200 , 0xfe00 ,
-+ 0xfe00 , 0x0100 , 0xfe00 , 0x0100 ,
-+ 0xfd00 , 0xff00 , 0xff00 , 0xfe00 ,
-+ 0xff00 , 0xfc00 , 0x0100 , 0xfe00 ,
-+ 0x0100 , 0xff00 , 0xfe00 , 0xff00 ,
-+ 0xff00 , 0xfe00 , 0x0100 , 0xfe00 ,
-+ 0x0100 , 0xff00 , 0x0100 , 0xfe00 ,
-+ 0xff00 , 0x0200 , 0xfe00 , 0x0000 ,
-+ 0x0100 , 0x0200 , 0xff00 , 0x0200 ,
-+ 0xff00 , 0x0000 , 0x0100 , 0x0100 ,
-+ 0xff00 , 0x0200 , 0xfe00 , 0xff00 ,
-+ 0xff00 , 0xff00 , 0x0100 , 0x0000 ,
-+ 0xff00 , 0x0100 , 0xff00 , 0x0000 ,
-+ 0x0100 , 0xff00 , 0xfe00 , 0xff00 ,
-+ 0xff00 , 0x0100 , 0xff00 , 0x0100 ,
-+ 0xfe00 , 0xff00 , 0xff00 , 0xff00 ,
-+ 0xfe00 , 0xff00 , 0xff00 , 0x0100 ,
-+ 0xff00 , 0x0200 , 0xff00 , 0x0100 ,
-+ 0xff00 , 0xff00 };
-+
-+
-+unsigned short alarm_data[] = {
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x7fff , 0x7fff , 0x8000 , 0x8000 , // 9 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 0
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 1
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 2
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 3
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 4
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 5
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 6
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 7
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 8
-+ 0x7fff , 0x7fff , 0x7fff , 0x7fff , 0x8000 , 0x8000 , 0x8000 , 0x8000 , // 9 5
-+
-+};
-+
-+
-+
-+
-+
-+#define SHARP_BUZ_TOUCHSOUND 1
-+#define SHARP_BUZ_KEYSOUND 2
-+#define SHARP_BUZ_ALARM 11
-+#define SHARP_BUZZER_MAKESOUND 0x5680
-+
-+static int collie_ct_s16_buzzer(const u_char *userPtr, size_t userCount,
-+ u_char frame[], ssize_t *frameUsed,
-+ ssize_t frameLeft)
-+{
-+ ssize_t count, used;
-+ signed short *fp = (unsigned short *) &frame[*frameUsed];
-+ signed short *up = (unsigned short *) userPtr;
-+
-+ DPRINTK("Collie_ct_s16 begin\n");
-+
-+ used = count = (userCount < frameLeft) ? userCount/2 : frameLeft/4;
-+
-+ DPRINTK("Collie_ct_s16 begin count %d \n",count);
-+
-+ while (count > 0) {
-+ *fp++ = *up;
-+ *fp++ = *up++;
-+ count--;
-+ }
-+
-+ *frameUsed+=used*4;
-+ DPRINTK("Collie_ct_s16 exit\n");
-+ return used*2;
-+}
-+
-+
-+static ssize_t sq_write_buzzer(int soundid)
-+{
-+ const char * src;
-+ audio_stream_t *s = &output_stream;
-+ u_char *dest;
-+ ssize_t uUsed, bUsed, bLeft, uLeft, ret = 0;
-+
-+
-+ if ((collie_tc_status!=NA) && (collie_tc_status!=PLAY))
-+ return -EPERM;
-+
-+ collie_tc_status=PLAY;
-+
-+ if (!s->buffers && sq_allocate_buffers(s)) {
-+ return -ENOMEM;
-+ }
-+
-+
-+#ifdef CONFIG_PM
-+ /* Auto Power off cancel */
-+// autoPowerCancel = 0;
-+#endif
-+ DPRINTK("sq_write_buzzer: id:%d\n", soundid);
-+
-+ switch (soundid) {
-+ case SHARP_BUZ_TOUCHSOUND:
-+ src=tap_data;
-+ uLeft=176*2;
-+ break;
-+ case SHARP_BUZ_KEYSOUND:
-+ src=click_data;
-+ uLeft=360*2;
-+ break;
-+ case SHARP_BUZ_ALARM:
-+ src=alarm_data;
-+ uLeft=3072*2;
-+ break;
-+ default:
-+ return 0;
-+ }
-+ DPRINTK("sq_write_buzzer: uLeft=%d\n", uLeft);
-+
-+ collie_tc_mute_off();
-+ while (uLeft > 0) {
-+ audio_buf_t *b = s->buf;
-+
-+ ret = -ERESTARTSYS;
-+ if (down_interruptible(&b->sem)) {
-+ break;
-+ }
-+
-+ dest = b->start + b->size;
-+ bUsed = 0;
-+ bLeft = s->fragsize - b->size;
-+ uUsed = collie_ct_s16_buzzer(src, uLeft, dest, &bUsed, bLeft);
-+ cpu_cache_clean_invalidate_range((unsigned long)dest,
-+ (unsigned long)(dest+(audio_fragsize)), 0);
-+
-+ DPRINTK("back to sq_write_buzzer %p\n",dest);
-+
-+ if (uUsed < 0) {
-+ up(&b->sem);
-+ return -EFAULT;
-+ }
-+ src += uUsed;
-+ uLeft -= uUsed;
-+ b->size += bUsed;
-+
-+ if (b->size < s->fragsize) {
-+ up(&b->sem);
-+ break;
-+ }
-+
-+ /* Send current buffer to dma */
-+ sa1100_dma_queue_buffer(COLLIE_BUZZER_DMA_CHANNEL,
-+ (void *) b, b->dma_addr, b->size);
-+
-+ Collie_volume_set(4);
-+
-+ b->size = 0; /* indicate that the buffer has been sent */
-+ NEXT_BUF(s, buf);
-+ }
-+
-+ DPRINTK("sq_write_buzzer: return\n");
-+ return ret;
-+}
-+
-+
-+
-+
-+
-+
-+
-diff -Nuar linux-2.4.18/drivers/sound/collie_ssp.c linux-2.4.18p/drivers/sound/collie_ssp.c
---- linux-2.4.18/drivers/sound/collie_ssp.c 2003-05-13 11:18:37.000000000 +0200
-+++ linux-2.4.18p/drivers/sound/collie_ssp.c 2004-10-13 15:05:36.000000000 +0200
-@@ -9,6 +9,7 @@
- * I/F : Synchronous serial port (SSP) TI mode
- *
- * Copyright (C) 2001 SHARP
-+ * p.nis/dolOps messed around with it too!
- *
- * 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
-@@ -24,7 +25,18 @@
- * 23-Oct-2001 SHARP
- * tune hardware control method
- * 12-Nov-2001 Lineo Japan, Inc.
-- * 14-Feb-2003 Sharp Corporation 8bit , GETOSPACE
-+ *
-+ * 26-Dec-2002 getospace added, some unneeded things removed
-+ *
-+ * 28-Dec-2002 cut out old stuff, reorder stuff
-+ *
-+ * 04-Jan-2003 put in getospace from lineo's collie-tc35143.c
-+ * also added collie_record_on off, and exported these symbols
-+ *
-+ * 06-Jan-2003 if mixer ioctl SOUND_MIXER_READ_DEVMASK returns 0 as mask,
-+ * than the headphone(/mic) is not connected
-+ *
-+ *
- */
- #include <linux/module.h>
- #include <linux/sched.h>
-@@ -35,7 +47,7 @@
- #include <linux/fcntl.h>
- #include <linux/errno.h>
- #include <linux/mm.h>
--#include <linux/malloc.h>
-+#include <linux/slab.h>
- #include <linux/sound.h>
- #include <linux/init.h>
- #include <linux/delay.h>
-@@ -48,38 +60,30 @@
- #include <asm/uaccess.h>
- #include <asm/io.h>
- #include <asm/dma.h>
--#include <asm/ucb1200.h>
-
- #include <linux/soundcard.h>
- #include <asm/proc/cache.h>
-
--#include <asm/arch/gpio.h>
-+#include <asm/arch/hardware.h>
- #include <asm/arch/m62332.h>
- #include <asm/arch/tc35143.h>
-
- #undef DEBUG
--//#define DEBUG
- #ifdef DEBUG
- #define DPRINTK( x... ) printk( ##x )
- #else
- #define DPRINTK( x... )
- #endif
-
--#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0) || \
-- defined(CONFIG_COLLIE_TR1) || defined(CONFIG_COLLIE_DEV)
--#define COLLIE_TRY_ONE
--#else
--#undef COLLIE_TRY_ONE
--#endif
-+#define COLLIE_TRY_ONE
-
- #ifdef COLLIE_TRY_ONE
- #ifndef GPIO_REMOCON_ADC_SW
- #define GPIO_REMOCON_ADC_SW GPIO_GPIO(18)
- #endif
-
-+static int collie_rc_irq;
- static DECLARE_WAIT_QUEUE_HEAD(audio_on);
--
--
- static inline void collie_rc_set_int_mode(void)
- {
- GPSR = GPIO_REMOCON_ADC_SW;
-@@ -91,14 +95,12 @@
- }
- #endif
-
--
- int collie_dmasound_irq = -1;
--#define COLLIE_SOUND_DMA_CHANNEL (collie_dmasound_irq)
-
-+#define COLLIE_SOUND_DMA_CHANNEL (collie_dmasound_irq)
- #define SND_NDEVS 256 /* Number of supported devices */
- #define SND_DEV_CTL 0 /* Control port /dev/mixer */
--#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM
-- synthesizer and MIDI output) */
-+#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM synthesizer and MIDI output) */
- #define SND_DEV_MIDIN 2 /* Raw midi access */
- #define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */
- #define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */
-@@ -121,142 +123,25 @@
- #endif
-
- /*** Some declarations ***********************************************/
--#define DMASND_TT 1
--#define DMASND_FALCON 2
--#define DMASND_AMIGA 3
--#define DMASND_AWACS 4
--#define DMASND_IRIS 5
--#define DMASND_COLLIE 6
-
--#define COLLIE_WAIT_AMP_ON 1 /* 10ms */
-+
- #define COLLIE_WAIT_LCM_ACC_XEN 50 /* 500ms */
--#ifdef MODULE
--static int catchRadius = 0;
--#endif
-+
- static int collie_amp_init = 0;
- static int collie_dac_init = 0;
--static int collie_op_shdn_on = 0;
- static int collie_resume = 0;
- static int collie_hard_mute = 1;
- static int collie_soft_mute = 1;
- static int collie_volume = 0;
-+int collie_recording=0;
-+static int playing=0;
-+static int headphone;
-
--int collie_buzzer_volume = 0;
--
--#if 1
--static DECLARE_WAIT_QUEUE_HEAD(open_queue);
-+#define AUDIO_NBFRAGS_DEFAULT 64
-+#define AUDIO_FRAGSIZE_DEFAULT 4096
-
--#define SIGNAL_RECEIVED (signal_pending(current))
--#define ONE_SECOND HZ /* in jiffies (100ths of a second) */
--#define SLEEP(queue, time_limit) \
-- interruptible_sleep_on_timeout((wait_queue_head_t*)&queue, (time_limit));
--#define WAKE_UP(queue) (wake_up_interruptible((wait_queue_head_t*)&queue))
--#endif
--
--#define AUDIO_NBFRAGS_DEFAULT 8
--#define AUDIO_FRAGSIZE_DEFAULT 8192
--
--
--#define TRACE 0
--#if TRACE
--#define TRACE_ON 1
--#define TRACE_SEM 0
--#define TRACE_SENDDATA 0
--#define TRACE_PM 1
--#define TRACE_AMP 1
--#define TRACE_DAC 1
--#define TRACE_OP_SHDN 1
--#define TRACE_WRITE 1
--#define TRACE_MUTE 1
--#define TRACE_CLOCK 1
--#define TRACE_PAIF 1
--#define TRACE_SSP 1
--#define TRACE_VOLUME 1
--#define TRACE_MIC 1
--#define TRACE_INTERRUPT 0
--int cLevel = 0;
--char *pLevel[16] = {
-- /* 0 */"",
-- /* 1 */" ",
-- /* 2 */" ",
-- /* 3 */" ",
-- /* 4 */" ",
-- /* 5 */" ",
-- /* 6 */" ",
-- /* 7 */" ",
-- /* 8 */" ",
-- /* 9 */" ",
-- /* 10 */" ",
-- /* 11 */" ",
-- /* 12 */" ",
-- /* 13 */" ",
-- /* 14 */" ",
-- /* 15 */" "
--};
--char *
--indent(int level)
--{
-- int i;
-- return (level < 16 ) ? pLevel[level] : pLevel[15];
--}
--
--#define P_ID (current->tgid)
--#define ENTER(f,fn) {if(f)printk("%d:%s+[%d]%s\n",jiffies,indent(cLevel),P_ID,(fn));cLevel++;}
--#define LEAVE(f,fn) {cLevel--;if(f>1)printk("%d:%s-[%d]%s\n",jiffies,indent(cLevel),P_ID,(fn));}
--#else /* ! TRACE */
--#define ENTER(f,fn)
--#define LEAVE(f,fn)
--#endif /* end TRACE */
-
--/*
-- * DAC power management
-- */
--#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0) || \
-- defined(CONFIG_COLLIE_TR1) || defined(CONFIG_COLLIE_DEV)
--#define DAC_OFF_WITH_DEVICE_OFF 1
--#undef HARD_MUTE_CTRL_DISABLE
--#else
--#undef DAC_OFF_WITH_DEVICE_OFF
- #undef HARD_MUTE_CTRL_DISABLE
--#endif
--
--
--#define TRY_DELAY_OFF
--#ifdef TRY_DELAY_OFF /* H.Hayami SHARP 2001.12.19 */
--static DECLARE_WAIT_QUEUE_HEAD(delay_off);
--struct semaphore df_sem;
--/*
-- * delay execution
-- */
--static unsigned int DelayedFlag = 0;
--#define DELAY_DAC_OFF 0x1
--#define DELAY_HARD_MUTE_ON 0x2
--
--static inline void ResetDelayAll(void)
--{
-- DelayedFlag = 0;
--}
--
--static inline int isDelayedExist(void)
--{
-- return DelayedFlag;
--}
--
--static inline void SetDelay(unsigned int flag)
--{
-- DelayedFlag |= flag;
--}
--
--static inline void ResetDelay(unsigned int flag)
--{
-- DelayedFlag &= ~flag;
--}
--
--static inline unsigned int isDelayed(unsigned int flag)
--{
-- return DelayedFlag & flag;
--}
--#endif
-
- /*
- * Buffer Management
-@@ -268,6 +153,7 @@
- dma_addr_t dma_addr; /* physical buffer address */
- struct semaphore sem; /* down before touching the buffer */
- int master; /* master owner for buffer allocation */
-+ u_int idx; /* buffer index, so that we know which buffer was sent last*/
- } audio_buf_t;
-
- typedef struct {
-@@ -291,16 +177,6 @@
-
- static volatile int audio_wr_refcount; /* nbr of concurrent open() for playback */
-
--static ssize_t (*ct_func)(const u_char *, size_t, u_char *, ssize_t *, ssize_t) = NULL;
--
--#ifdef MODULE
--MODULE_PARM(catchRadius, "i");
--#endif
--MODULE_PARM(numBufs, "i");
--MODULE_PARM(bufSize, "i");
--
--#define min(x, y) ((x) < (y) ? (x) : (y))
--
- #define IOCTL_IN(arg, ret) \
- do { int error = get_user(ret, (int *)(arg)); \
- if (error) return error; \
-@@ -310,11 +186,7 @@
- /*
- * SA1110 GPIO (17)
- */
--#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
--#define COLLIE_GPIO_OPSHDN GPIO_GPIO (17) /* AMP contorol */
--#else /* !CONFIG_COLLIE_TS && !CONFIG_COLLIE_TR0 */
- #define COLLIE_GPIO_MIC GPIO_GPIO (17) /* MIC contorol */
--#endif /* !CONFIG_COLLIE_TS && !CONFIG_COLLIE_TR0 */
-
- /*
- * DAC setup data
-@@ -352,122 +224,11 @@
- ( LCM_ACC_XSEL1 | LCM_ACC_CLKSEL101 ) ,
- };
-
-+/*** "Translations" ************************************************************/
-
--/* 16 bit mu-law */
--
--static short ulaw2dma16[] = {
-- -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
-- -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
-- -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
-- -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
-- -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
-- -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
-- -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
-- -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
-- -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
-- -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
-- -876, -844, -812, -780, -748, -716, -684, -652,
-- -620, -588, -556, -524, -492, -460, -428, -396,
-- -372, -356, -340, -324, -308, -292, -276, -260,
-- -244, -228, -212, -196, -180, -164, -148, -132,
-- -120, -112, -104, -96, -88, -80, -72, -64,
-- -56, -48, -40, -32, -24, -16, -8, 0,
-- 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
-- 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
-- 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
-- 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
-- 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
-- 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
-- 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
-- 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
-- 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
-- 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
-- 876, 844, 812, 780, 748, 716, 684, 652,
-- 620, 588, 556, 524, 492, 460, 428, 396,
-- 372, 356, 340, 324, 308, 292, 276, 260,
-- 244, 228, 212, 196, 180, 164, 148, 132,
-- 120, 112, 104, 96, 88, 80, 72, 64,
-- 56, 48, 40, 32, 24, 16, 8, 0,
--};
--
--/* 16 bit A-law */
--
--static short alaw2dma16[] = {
-- -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
-- -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
-- -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
-- -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
-- -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
-- -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
-- -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
-- -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
-- -344, -328, -376, -360, -280, -264, -312, -296,
-- -472, -456, -504, -488, -408, -392, -440, -424,
-- -88, -72, -120, -104, -24, -8, -56, -40,
-- -216, -200, -248, -232, -152, -136, -184, -168,
-- -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
-- -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
-- -688, -656, -752, -720, -560, -528, -624, -592,
-- -944, -912, -1008, -976, -816, -784, -880, -848,
-- 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
-- 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
-- 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
-- 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
-- 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
-- 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
-- 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
-- 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
-- 344, 328, 376, 360, 280, 264, 312, 296,
-- 472, 456, 504, 488, 408, 392, 440, 424,
-- 88, 72, 120, 104, 24, 8, 56, 40,
-- 216, 200, 248, 232, 152, 136, 184, 168,
-- 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
-- 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
-- 688, 656, 752, 720, 560, 528, 624, 592,
-- 944, 912, 1008, 976, 816, 784, 880, 848,
--};
--
--
--
--/*** Translations ************************************************************/
--
--static ssize_t collie_ct_law(const u_char *userPtr, size_t userCount,
-- u_char frame[], ssize_t *frameUsed,
-- ssize_t frameLeft);
--static ssize_t collie_ct_s8(const u_char *userPtr, size_t userCount,
-- u_char frame[], ssize_t *frameUsed,
-- ssize_t frameLeft);
--static ssize_t collie_ct_u8(const u_char *userPtr, size_t userCount,
-- u_char frame[], ssize_t *frameUsed,
-- ssize_t frameLeft);
- static ssize_t collie_ct_s16(const u_char *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft);
--static ssize_t collie_ct_u16(const u_char *userPtr, size_t userCount,
-- u_char frame[], ssize_t *frameUsed,
-- ssize_t frameLeft);
--
--/*** Machine definitions *****************************************************/
--
--
--typedef struct {
-- int type;
-- void *(*dma_alloc)(unsigned int, int);
-- void (*dma_free)(void *, unsigned int);
-- int (*irqinit)(void);
--#ifdef MODULE
-- void (*irqcleanup)(void);
--#endif /* MODULE */
-- void (*init)(void);
-- void (*silence)(void);
-- int (*setFormat)(int);
-- int (*setVolume)(int);
-- int (*setBass)(int);
-- int (*setTreble)(int);
-- int (*setGain)(int);
-- void (*play)(void);
--} MACHINE;
--
-
- /*** Low level stuff *********************************************************/
-
-@@ -477,71 +238,28 @@
- int stereo; /* 0 = mono, 1 = stereo */
- int size; /* 8/16 bit*/
- int speed; /* speed */
-+ int volume;
- } SETTINGS;
-
--typedef struct {
-- ssize_t (*ct_ulaw)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-- ssize_t (*ct_alaw)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-- ssize_t (*ct_s8)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-- ssize_t (*ct_u8)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-- ssize_t (*ct_s16be)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-- ssize_t (*ct_u16be)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-- ssize_t (*ct_s16le)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
-- ssize_t (*ct_u16le)(const u_char *, size_t, u_char *, ssize_t *, ssize_t);
--} TRANS;
--
--struct sound_settings {
-- MACHINE mach; /* machine dependent things */
-- SETTINGS hard; /* hardware settings */
-- SETTINGS soft; /* software settings */
-- SETTINGS dsp; /* /dev/dsp default settings */
-- TRANS *trans; /* supported translations */
-- int volume_left; /* volume (range is machine dependent) */
-- int volume_right;
-- int bass; /* tone (range is machine dependent) */
-- int treble;
-- int gain;
-- int minDev; /* minor device number currently open */
--};
--
--static struct sound_settings sound;
-+static SETTINGS sound;
-
- #ifdef CONFIG_PM
--extern int autoPowerCancel;
-+//extern int autoPowerCancel;
- #endif
--int collie_main_volume;
--extern int collie_under_recording; /* collie_buzzer.c */
--#define COLLE_RECORDING (collie_under_recording)
-
- static void Collie_Set_Volume(int volume);
- static int Collie_Get_Volume(void);
--static void Collie_disable_sound(void);
--#ifdef CONFIG_PM
--#if 0
--static void Collie_clock_stop(void);
--static void Collie_FS8KLPF_stop(void);
--#endif
--#endif
- static int CollieIrqInit(void);
- static int CollieGetSamp(void);
--static void Collie_OP_SHDN_on(void);
--static void Collie_OP_SHDN_off(void);
--static void Collie_FS8KLPF_start(void);
--#ifdef MODULE
--static void CollieIrqCleanUp(void);
--#endif /* MODULE */
--static void CollieSilence(void);
- static void Collie_DAC_sendword(int);
--static void CollieInit(void);
- static int CollieSetFormat(int format);
- static void Collie_sq_interrupt(void*, int);
- static int sq_allocate_buffers(audio_stream_t*);
- static void sq_release_buffers(audio_stream_t*);
-+static inline void Collie_volume_init(void);
-+static void Collie_volume_set(int);
-
- /*** Mid level stuff *********************************************************/
--static void sound_silence(void);
--static void sound_init(void);
--static int sound_set_format(int format);
- static int sound_set_speed(int speed);
- static int sound_set_stereo(int stereo);
-
-@@ -572,468 +290,122 @@
- static long long sound_lseek(struct file *file, long long offset, int orig);
- static inline int ioctl_return(int *addr, int value)
- {
-- ENTER(TRACE_ON,"ioctl_return");
- if (value < 0) {
-- LEAVE(TRACE_ON,"ioctl_return");
- return(value);
- }
--
-- LEAVE(TRACE_ON,"ioctl_return");
- return put_user(value, addr)? -EFAULT: 0;
- }
-
--
--/*** Config & Setup **********************************************************/
--
--
--void dmasound_init(void);
--void dmasound_setup(char *str, int *ints);
--
--
--/*** Translations ************************************************************/
--
--
--/* ++TeSche: radically changed for new expanding purposes...
-- *
-- * These two routines now deal with copying/expanding/translating the samples
-- * from user space into our buffer at the right frequency. They take care about
-- * how much data there's actually to read, how much buffer space there is and
-- * to convert samples into the right frequency/encoding. They will only work on
-- * complete samples so it may happen they leave some bytes in the input stream
-- * if the user didn't write a multiple of the current sample size. They both
-- * return the number of bytes they've used from both streams so you may detect
-- * such a situation. Luckily all programs should be able to cope with that.
-- *
-- * I think I've optimized anything as far as one can do in plain C, all
-- * variables should fit in registers and the loops are really short. There's
-- * one loop for every possible situation. Writing a more generalized and thus
-- * parameterized loop would only produce slower code. Feel free to optimize
-- * this in assembler if you like. :)
-- *
-- * I think these routines belong here because they're not yet really hardware
-- * independent, especially the fact that the Falcon can play 16bit samples
-- * only in stereo is hardcoded in both of them!
-- *
-- * ++geert: split in even more functions (one per format)
-- */
--
--static ssize_t collie_ct_law(const u_char *userPtr, size_t userCount,
-- u_char frame[], ssize_t *frameUsed,
-- ssize_t frameLeft)
--{
-- short *table = sound.soft.format == AFMT_MU_LAW ? ulaw2dma16: alaw2dma16;
-- ssize_t count, used;
-- short *p = (short *) &frame[*frameUsed];
-- int val, stereo = sound.soft.stereo;
--
-- ENTER(TRACE_ON,"collie_ct_law");
-- frameLeft >>= 2;
-- if (stereo)
-- userCount >>= 1;
-- used = count = min(userCount, frameLeft);
-- if (!COLLE_RECORDING) {
-- while (count > 0) {
-- u_char data;
-- if (get_user(data, userPtr++)) {
-- LEAVE(TRACE_ON,"collie_ct_law");
-- return -EFAULT;
-- }
-- val = table[data];
-- *p++ = val; /* Left Ch. */
-- if (stereo) {
-- if (get_user(data, userPtr++)) {
-- LEAVE(TRACE_ON,"collie_ct_law");
-- return -EFAULT;
-- }
-- val = table[data];
-- }
-- *p++ = val; /* Right Ch. */
-- count--;
-- }
-- } else {
-- while (count > 0) {
-- u_char data;
-- int ave;
-- if (get_user(data, userPtr++)) {
-- LEAVE(TRACE_ON,"collie_ct_law");
-- return -EFAULT;
-- }
-- val = table[data];
-- ave = val; /* Left Ch. */
-- if (stereo) {
-- if (get_user(data, userPtr++)) {
-- LEAVE(TRACE_ON,"collie_ct_law");
-- return -EFAULT;
-- }
-- val = table[data];
-- }
-- ave += val; /* Right Ch. */
-- ave >>= 1;
-- *p++ = 0; /* Left Ch. */
-- *p++ = ave; /* Right Ch. */
-- count--;
-- }
-- }
-- *frameUsed += used * 4;
-- LEAVE(TRACE_ON,"collie_ct_law");
-- return stereo? used * 2: used;
--}
--
--
--static ssize_t collie_ct_s8(const u_char *userPtr, size_t userCount,
-- u_char frame[], ssize_t *frameUsed,
-- ssize_t frameLeft)
--{
-- ssize_t count, used;
-- short *p = (short *) &frame[*frameUsed];
-- int stereo = sound.soft.stereo;
-- short val;
--
-- ENTER(TRACE_ON,"collie_ct_s8");
-- frameLeft >>= 2;
-- if (stereo)
-- userCount >>= 1;
-- used = count = min(userCount, frameLeft);
-- if (!COLLE_RECORDING) {
-- while (count > 0) {
-- u_char data;
--
-- if (get_user(data, userPtr++)) {
-- LEAVE(TRACE_ON,"collie_ct_s8");
-- return -EFAULT;
-- }
-- val = ( data - 0x80 ) << 8;
-- *p++ = val; /* Left Ch. */
-- if ( stereo ) {
-- if ( get_user(data, userPtr++)) {
-- LEAVE(TRACE_ON,"collie_ct_s8");
-- return -EFAULT;
-- }
-- val = ( data - 0x80 ) << 8;
-- }
-- *p++ = val; /* Right Ch. */
-- count--;
-- }
-- } else {
-- while (count > 0) {
-- u_char data;
-- int ave;
--
-- if (get_user(data, userPtr++)) {
-- LEAVE(TRACE_ON,"collie_ct_s8");
-- return -EFAULT;
-- }
-- val = ( data - 0x80 ) << 8;
-- ave = val; /* Left Ch. */
-- if ( stereo ) {
-- if ( get_user(data, userPtr++)) {
-- LEAVE(TRACE_ON,"collie_ct_s8");
-- return -EFAULT;
-- }
-- val = ( data - 0x80 ) << 8;
-- }
-- ave += val; /* Right Ch. */
-- ave >>= 1;
-- *p++ = 0; /* Left Ch. */
-- *p++ = ave; /* Right Ch. */
-- count--;
-- }
-- }
-- *frameUsed += used * 4;
-- LEAVE(TRACE_ON,"collie_ct_s8");
-- return stereo? used * 2: used;
--}
--
--
--static ssize_t collie_ct_u8(const u_char *userPtr, size_t userCount,
-- u_char frame[], ssize_t *frameUsed,
-- ssize_t frameLeft)
-+static void wait_ms(int ten_ms)
- {
-- ssize_t count, used;
-- short *p = (short *) &frame[*frameUsed];
-- int stereo = sound.soft.stereo;
-- short val;
--
-- ENTER(TRACE_ON,"collie_ct_u8");
-- frameLeft >>= 2;
-- if (stereo)
-- userCount >>= 1;
-- used = count = min(userCount, frameLeft);
-- if (!COLLE_RECORDING) {
-- while (count > 0) {
-- u_char data;
--
-- if (get_user(data, userPtr++)) {
-- LEAVE(TRACE_ON,"collie_ct_u8");
-- return -EFAULT;
-- }
-- val = data;
-- *p++ = (val ^ 0x80) << 8; /* Left Ch. */
-- if ( stereo ) {
-- if ( get_user(data, userPtr++)) {
-- LEAVE(TRACE_ON,"collie_ct_u8");
-- return -EFAULT;
-- }
-- val = data;
-- }
-- *p++ = (val ^ 0x80) << 8; /* Right Ch. */
-- count--;
-- }
-- } else {
-- while (count > 0) {
-- u_char data;
-- int ave;
--
-- if (get_user(data, userPtr++)) {
-- LEAVE(TRACE_ON,"collie_ct_u8");
-- return -EFAULT;
-- }
-- val = data;
-- ave = (val ^ 0x80) << 8; /* Left Ch. */
-- if ( stereo ) {
-- if ( get_user(data, userPtr++)) {
-- LEAVE(TRACE_ON,"collie_ct_u8");
-- return -EFAULT;
-- }
-- val = data;
-- }
-- ave += (val ^ 0x80) << 8; /* Right Ch. */
-- ave >>= 1;
-- *p++ = 0; /* Left Ch. */
-- *p++ = ave; /* Right Ch. */
-- count--;
-- }
-- }
-- *frameUsed += used * 4;
-- LEAVE(TRACE_ON,"collie_ct_u8");
-- return stereo? used * 2: used;
-+ schedule_timeout(ten_ms);
- }
-
-+/*** Translation ************************************************************/
-
- static ssize_t collie_ct_s16(const u_char *userPtr, size_t userCount,
- u_char frame[], ssize_t *frameUsed,
- ssize_t frameLeft)
- {
- ssize_t count, used;
-- int stereo = sound.soft.stereo;
- short *fp = (short *) &frame[*frameUsed];
-+ short *up = (short *) userPtr;
-
-- ENTER(TRACE_ON,"collie_ct_s16");
- frameLeft >>= 2;
-- userCount >>= (stereo? 2: 1);
-- used = count = min(userCount, frameLeft);
-- if (!stereo) {
-- short *up = (short *) userPtr;
-- while (count > 0) {
-- short data;
-- if (get_user(data, up++)) {
-- LEAVE(TRACE_ON,"collie_ct_s16");
-- return -EFAULT;
-- }
-- *fp++ = (!COLLE_RECORDING) ? data : 0; /* Left Ch. */
-- *fp++ = data;
-- count--;
-+ userCount >>= 2;
-+ used = count = (userCount < frameLeft) ? userCount : frameLeft;
-+
-+ while (count > 0) {
-+
-+ short data;
-+ if (get_user(data, up++)) {
-+ return -EFAULT;
- }
-- } else {
-- short *up = (short *) userPtr;
-- while (count > 0) {
-- short data;
-- short temp;
-- if (get_user(data, up++)) {
-- LEAVE(TRACE_ON,"collie_ct_s16");
-- return -EFAULT;
-- }
-- if (get_user(temp, up++)) {
-- LEAVE(TRACE_ON,"collie_ct_s16");
-- return -EFAULT;
-- }
-- if (!COLLE_RECORDING) {
-- *fp++ = data; /* Left Ch. */
-- *fp++ = temp; /* Right Ch. */
-- } else {
-- data >>= 1;
-- data += (temp >> 1);
-- *fp++ = 0; /* Left Ch. */
-- *fp++ = data; /* Right Ch. */
-- }
-- count--;
-+ if (!collie_recording) *fp++ = data;
-+ else *fp++=0;
-+
-+ if (get_user(data, up++)) {
-+ return -EFAULT;
- }
-+ *fp++ = data;
-+ count--;
- }
-+
- *frameUsed += used * 4;
-- LEAVE(TRACE_ON,"collie_ct_s16");
-- return stereo? used * 4: used * 2;
-+ return used * 4;
- }
-
--static ssize_t collie_ct_u16(const u_char *userPtr, size_t userCount,
-- u_char frame[], ssize_t *frameUsed,
-- ssize_t frameLeft)
--{
-- ssize_t count, used;
-- int mask = (sound.soft.format == AFMT_U16_LE? 0x0080: 0x8000);
-- int stereo = sound.soft.stereo;
-- short *fp = (short *) &frame[*frameUsed];
-- short *up = (short *) userPtr;
-+/*** HARDWARE dependent stuff *********************************************************/
-
-- ENTER(TRACE_ON,"collie_ct_u16");
-- frameLeft >>= 2;
-- userCount >>= (stereo? 2: 1);
-- used = count = min(userCount, frameLeft);
-- if (!COLLE_RECORDING) {
-- while (count > 0) {
-- int data;
-- int temp;
-- if (get_user(data, up++)) {
-- LEAVE(TRACE_ON,"collie_ct_u16");
-- return -EFAULT;
-- }
-- data ^= mask;
-- *fp++ = data; /* Left Ch. */
-- if (stereo) {
-- if (get_user(temp, up++)) {
-- LEAVE(TRACE_ON,"collie_ct_u16");
-- return -EFAULT;
-- }
-- temp ^= mask;
-- data = temp;
-- data ^= mask;
-- }
-- *fp++ = data; /* Right Ch. */
-- count--;
-- }
-+static inline void Collie_DAC_sendbit(int bit_data)
-+{
-+ if (bit_data & 1) {
-+ LCM_GPO |= (LCM_GPIO_DAC_SDATA);
- } else {
-- while (count > 0) {
-- int data;
-- int temp;
-- int ave;
-- if (get_user(data, up++)) {
-- LEAVE(TRACE_ON,"collie_ct_u16");
-- return -EFAULT;
-- }
-- data ^= mask;
-- ave = data; /* Left Ch. */
-- if (stereo) {
-- if (get_user(temp, up++)) {
-- LEAVE(TRACE_ON,"collie_ct_u16");
-- return -EFAULT;
-- }
-- temp ^= mask;
-- data = temp;
-- data ^= mask;
-- }
-- ave += data;
-- ave >>= 1;
-- *fp++ = 0; /* Left Ch. */
-- *fp++ = ave; /* Right Ch. */
-- count--;
-- }
-+ LCM_GPO &= ~(LCM_GPIO_DAC_SDATA);
- }
-- *frameUsed += used * 4;
-- LEAVE(TRACE_ON,"collie_ct_u16");
-- return stereo? used * 4: used * 2;
--}
-
--static TRANS transCollie = {
-- collie_ct_law, collie_ct_law, collie_ct_s8, collie_ct_u8,
-- collie_ct_s16, collie_ct_u16, collie_ct_s16, collie_ct_u16
--};
-+ udelay(1);
-+ LCM_GPO |= (LCM_GPIO_DAC_SCK);
-
--/*** Low level stuff *********************************************************/
-+ udelay(1);
-+ LCM_GPO &= ~(LCM_GPIO_DAC_SCK);
-+ udelay(1);
-+ LCM_GPO &= ~(LCM_GPIO_DAC_SDATA);
-+ udelay(1);
-+}
-
--static void Collie_Set_Volume(int volume)
-+static void Collie_DAC_sendword(int data)
- {
-- ENTER(TRACE_ON,"Collie_Set_Volume");
--
-- sound.volume_left = volume & 0xff;
-- if ( sound.volume_left > 100 ) sound.volume_left = 100;
--
-- collie_main_volume = sound.volume_left;
--
-- sound.volume_right = ( volume & 0xff00 >> 8);
-- if ( sound.volume_right > 100 ) sound.volume_right = 100;
-- LEAVE(TRACE_ON,"Collie_Set_Volume");
-+ int i;
-
-- collie_buzzer_volume = sound.volume_right;
-+#if defined(CONFIG_COLLIE_PCM1741)
-+
-+ LCM_GPO &= ~(LCM_GPIO_DAC_SCK);
-+ udelay(1);
-+ LCM_GPO |= (LCM_GPIO_DAC_SLOAD);
-+ udelay(1);
-
--}
-+ for (i = 0; i < 16; i++)
-+ Collie_DAC_sendbit(data >> (15 - i));
-
-+ LCM_GPO &= ~(LCM_GPIO_DAC_SLOAD);
-+ udelay(2);
-
--static int Collie_Get_Volume(void)
--{
-- ENTER(TRACE_ON,"Collie_Get_Volume");
-- LEAVE(TRACE_ON,"Collie_Get_Volume");
-- return ( sound.volume_right << 8 | sound.volume_left );
--}
-+#elif defined(CONFIG_COLLIE_PCM1717)
-+
-+ LCM_GPO &= ~(LCM_GPIO_DAC_SLOAD);
-+ udelay(1000);
-+ LCM_GPO |= (LCM_GPIO_DAC_SLOAD);
-+ udelay(1000);
-+ LCM_GPO &= ~(LCM_GPIO_DAC_SCK);
-+ udelay(1000);
-
--static void wait_ms(int ten_ms)
--{
-- ENTER(TRACE_ON,"wait_ms");
-- LEAVE(TRACE_ON,"wait_ms");
-- schedule_timeout(ten_ms);
--}
-+ for (i = 0; i < 16; i++)
-+ Collie_DAC_sendbit(data >> (15 - i));
-
--static inline void Collie_AMP_off(void)
--{
--#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
-- ENTER(TRACE_AMP,"Collie_AMP_off");
--#if 0 /* OBSOLETED: power controled by only OP_SHDN */
-- /* Set up TC35143 GPIO I/O Direction (GPIO4 output mode) */
-- ucb1200_set_io_direction(TC35143_GPIO_AMP_ON,
-- TC35143_IODIR_OUTPUT);
-- /* AMP OFF */
-- ucb1200_set_io(TC35143_GPIO_AMP_ON,
-- TC35143_IODAT_LOW);
-- collie_amp_init = 0;
--#endif /* 0 */
-- LEAVE(TRACE_AMP,"Collie_AMP_off");
--#endif /* CONFIG_COLLIE_TS || CONFIG_COLLIE_TR0 */
--}
--
--static inline void Collie_AMP_on(void)
--{
--#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
-- ENTER(TRACE_AMP,"Collie_AMP_on");
--// if (!collie_amp_init) {
-- /* Set up TC35143 GPIO I/O Direction (GPIO4 output mode) */
-- ucb1200_set_io_direction(TC35143_GPIO_AMP_ON,
-- TC35143_IODIR_OUTPUT);
-- /* AMP ON */
-- ucb1200_set_io(TC35143_GPIO_AMP_ON, TC35143_IODAT_HIGH);
-- SCP_REG_GPWR |= SCP_AMP_ON;
-- wait_ms(COLLIE_WAIT_AMP_ON);
-- collie_amp_init = 1;
--// }
-- LEAVE(TRACE_AMP,"Collie_AMP_on");
--#endif /* CONFIG_COLLIE_TS || CONFIG_COLLIE_TR0 */
-+ LCM_GPO &= ~(LCM_GPIO_DAC_SLOAD);
-+ udelay(1000);
-+ LCM_GPO |= (LCM_GPIO_DAC_SLOAD);
-+ udelay(1000);
-+ LCM_GPO &= ~(LCM_GPIO_DAC_SLOAD);
-+ udelay(1000);
-+#endif
- }
-
--static inline void Collie_AMP_init(void)
--{
--#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
-- ENTER(TRACE_AMP,"Collie_AMP_init");
-- Collie_AMP_off();
-- LEAVE(TRACE_AMP,"Collie_AMP_init");
--#endif /* CONFIG_COLLIE_TS || CONFIG_COLLIE_TR0 */
--}
-
- static inline void Collie_DAC_off(void)
- {
-- ENTER(TRACE_DAC,"Collie_DAC_off");
-- if (!COLLE_RECORDING) {
-- /* DAC OFF */
-- LCM_GPD &= ~(LCM_GPIO_DAC_ON); /* set up output */
-- LCM_GPO &= ~(LCM_GPIO_DAC_ON);
--
-- /* LoCoMo GPIO disable */
-- LCM_GPE &= ~(LCM_GPIO_DAC_ON);
-- collie_dac_init = 0;
-- }
-- LEAVE(TRACE_DAC,"Collie_DAC_off");
-+ /* DAC OFF */
-+ LCM_GPD &= ~(LCM_GPIO_DAC_ON); /* set up output */
-+ LCM_GPO &= ~(LCM_GPIO_DAC_ON);
-+ /* LoCoMo GPIO disable */
-+ LCM_GPE &= ~(LCM_GPIO_DAC_ON);
-+ collie_dac_init = 0;
- }
-
- static inline void Collie_DAC_on(void)
- {
-- ENTER(TRACE_DAC,"Collie_DAC_on");
--// if (!collie_dac_init) {
- if (!(LCM_GPO & LCM_GPIO_DAC_ON)) {
- /* LoCoMo GPIO enable */
- LCM_GPE &= ~LCM_GPIO_DAC_ON;
-@@ -1049,24 +421,10 @@
- schedule();
- }
- }
--// }
-- LEAVE(TRACE_DAC,"Collie_DAC_on");
--}
--
--#ifdef TRY_DELAY_OFF /* H.Hayami SHARP */
--static inline void Collie_DAC_delay_off(void)
--{
-- ENTER(TRACE_DAC,"Collie_DAC_deleay_off");
-- down(&df_sem);
-- SetDelay(DELAY_DAC_OFF);
-- up(&df_sem);
-- LEAVE(TRACE_DAC,"Collie_DAC_delay_off");
- }
--#endif
-
- static inline void Collie_DAC_init(void)
- {
-- ENTER(TRACE_DAC,"Collie_DAC_init");
- /* LoCoMo GPIO enable */
- LCM_GPE &=
- ~(LCM_GPIO_DAC_SDATA | LCM_GPIO_DAC_SCK | LCM_GPIO_DAC_SLOAD);
-@@ -1075,7 +433,6 @@
- ~(LCM_GPIO_DAC_SDATA | LCM_GPIO_DAC_SCK | LCM_GPIO_DAC_SLOAD);
-
- #if defined(CONFIG_COLLIE_PCM1741)
--
- Collie_DAC_sendword(DAC_REG16_SetupData); /* register16 */
- Collie_DAC_sendword(DAC_REG17_SetupData); /* register17 */
- Collie_DAC_sendword(DAC_REG18_SetupData); /* register18 */
-@@ -1083,78 +440,53 @@
- Collie_DAC_sendword(DAC_REG20_SetupData); /* register20 */
- //// Collie_DAC_sendword(DAC_REG21_SetupData); /* register21 */
- Collie_DAC_sendword(DAC_REG22_SetupData); /* register22 */
--
- #elif defined(CONFIG_COLLIE_PCM1717)
--
- Collie_DAC_sendword(DAC_MODE0_SetupData); /* MODE0 */
- Collie_DAC_sendword(DAC_MODE1_SetupData); /* MODE1 */
- Collie_DAC_sendword(DAC_MODE2_SetupData); /* MODE2 */
- Collie_DAC_sendword(DAC_MODE3_SetupData); /* MODE3 */
--
- #endif
--
- /* LoCoMo GPIO disable */
- LCM_GPE &=
- ~(LCM_GPIO_DAC_SDATA | LCM_GPIO_DAC_SCK | LCM_GPIO_DAC_SLOAD);
-- LEAVE(TRACE_DAC,"Collie_DAC_init");
- }
-
- static inline void Collie_soft_DAC_on(void)
- {
- #if defined(CONFIG_COLLIE_PCM1741)
-- ENTER(TRACE_DAC, "Collie_soft_DAC_on");
- Collie_DAC_sendword(DAC_REG19_DACOn); /* register19 */
-- LEAVE(TRACE_DAC, "Collie_soft_DAC_on");
- #endif /* CONFIG_COLLIE_PCM1741 */
- }
-
- static inline void Collie_soft_DAC_off(void)
- {
- #if defined(CONFIG_COLLIE_PCM1741)
-- ENTER(TRACE_DAC, "Collie_soft_DAC_off");
- Collie_DAC_sendword(DAC_REG19_DACOff); /* register19 */
-- LEAVE(TRACE_DAC, "Collie_soft_DAC_off");
--#endif /* CONFIG_COLLIE_PCM1741 */
--}
--
--static inline void Collie_soft_mute_init(void)
--{
--#if defined(CONFIG_COLLIE_PCM1741)
-- ENTER(TRACE_MUTE, "Collie_soft_mute_init");
-- Collie_DAC_sendword(DAC_REG18_MuteOn); /* register18 */
-- collie_soft_mute = 1;
-- LEAVE(TRACE_MUTE, "Collie_soft_mute_init");
- #endif /* CONFIG_COLLIE_PCM1741 */
- }
-
- static inline void Collie_soft_mute_on(void)
- {
- #if defined(CONFIG_COLLIE_PCM1741)
-- ENTER(TRACE_MUTE, "Collie_soft_mute_on");
- if (!collie_soft_mute) {
- Collie_DAC_sendword(DAC_REG18_MuteOn); /* register18 */
- collie_soft_mute = 1;
- }
-- LEAVE(TRACE_MUTE, "Collie_soft_mute_on");
- #endif /* CONFIG_COLLIE_PCM1741 */
- }
-
- static inline void Collie_soft_mute_off(void)
- {
- #if defined(CONFIG_COLLIE_PCM1741)
-- ENTER(TRACE_MUTE, "Collie_soft_mute_off");
- if (collie_soft_mute) {
- Collie_DAC_sendword(DAC_REG18_MuteOff); /* register18 */
- collie_soft_mute = 0;
- }
-- LEAVE(TRACE_MUTE, "Collie_soft_mute_off");
- #endif /* CONFIG_COLLIE_PCM1741 */
- }
-
- static inline void Collie_hard_mute_init(void)
- {
--#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0)
-- ENTER(TRACE_MUTE, "Collie_hard_mute_init");
- SCP_REG_GPCR |= (SCP_GPCR_PA14 | SCP_GPCR_PA15);
- #ifdef HARD_MUTE_CTRL_DISABLE
- SCP_REG_GPWR |= (SCP_GPCR_PA14 | SCP_GPCR_PA15);
-@@ -1162,84 +494,107 @@
- SCP_REG_GPWR &= ~(SCP_GPCR_PA14 | SCP_GPCR_PA15);
- #endif /* HARD_MUTE_CTRL_DISABLE */
- collie_hard_mute = 1;
--#if !defined(CONFIG_COLLIE_TR1) && !defined(CONFIG_COLLIE_DEV)
-+
- {
- int time = jiffies + 5;
- while (jiffies <= time)
- schedule();
- }
--#endif
-- LEAVE(TRACE_MUTE, "Collie_hard_mute_init");
--#endif /* !CONFIG_COLLIE_TS && !CONFIG_COLLIE_TR0 */
- }
-
- static inline void Collie_hard_mute_on(void)
- {
--#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0)
- #ifndef HARD_MUTE_CTRL_DISABLE
-- ENTER(TRACE_MUTE, "Collie_hard_mute_on");
- if (!collie_hard_mute) {
- SCP_REG_GPWR &= ~(SCP_GPCR_PA14 | SCP_GPCR_PA15);
- collie_hard_mute = 1;
--#if !defined(CONFIG_COLLIE_TR1) && !defined(CONFIG_COLLIE_DEV)
- {
- int time = jiffies + 5;
- while (jiffies <= time)
- schedule();
- }
--#endif
- }
-- LEAVE(TRACE_MUTE, "Collie_hard_mute_on");
- #endif /* HARD_MUTE_CTRL_DISABLE */
--#endif /* !CONFIG_COLLIE_TS && !CONFIG_COLLIE_TR0 */
- }
-
- static inline void Collie_hard_mute_off(void)
- {
--#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0)
- #ifndef HARD_MUTE_CTRL_DISABLE
-- ENTER(TRACE_MUTE, "Collie_hard_mute_off");
- if (collie_hard_mute) {
-- if (!COLLE_RECORDING)
- SCP_REG_GPWR |= (SCP_GPCR_PA14 | SCP_GPCR_PA15);
-- else
-- SCP_REG_GPWR |= (SCP_GPCR_PA15);
- collie_hard_mute = 0;
--#if !defined(CONFIG_COLLIE_TR1) && !defined(CONFIG_COLLIE_DEV)
- {
- int i;
- for (i=0; i<=1000; i++) {
- udelay(1);
- }
- }
--#endif
- }
-- LEAVE(TRACE_MUTE, "Collie_hard_mute_off");
- #endif /* HARD_MUTE_CTRL_DISABLE */
--#endif /* !CONFIG_COLLIE_TS && !CONFIG_COLLIE_TR0 */
--}
--
--#ifdef TRY_DELAY_OFF /* H.Hayami SHARP 2001.12.19 */
--static inline void Collie_hard_mute_delay_on(void)
--{
-- ENTER(TRACE_MUTE, "Collie_hard_mute_delay_on");
-- down(&df_sem);
-- SetDelay(DELAY_HARD_MUTE_ON);
-- up(&df_sem);
-- LEAVE(TRACE_MUTE, "Collie_hard_mute_delay_on");
- }
--#endif
-
--static inline void Collie_audio_clock_init(void)
-+static inline void Collie_hard_mute_left_on(void)
-+{
-+#ifndef HARD_MUTE_CTRL_DISABLE
-+// if (!collie_hard_mute) {
-+ SCP_REG_GPWR &= ~(SCP_GPCR_PA14);
-+ {
-+ int time = jiffies + 5;
-+ while (jiffies <= time)
-+ schedule();
-+ }
-+// }
-+#endif /* HARD_MUTE_CTRL_DISABLE */
-+}
-+
-+static inline void Collie_hard_mute_left_off(void)
-+{
-+#ifndef HARD_MUTE_CTRL_DISABLE
-+// if (collie_hard_mute) {
-+ SCP_REG_GPWR |= (SCP_GPCR_PA14);
-+ {
-+ int i;
-+ for (i=0; i<=1000; i++) {
-+ udelay(1);
-+ }
-+ }
-+// }
-+#endif /* HARD_MUTE_CTRL_DISABLE */
-+}
-+
-+
-+static int CollieGetSamp(void)
-+{
-+ switch (sound.speed) {
-+ case 8000:
-+ return clock_set_data[7];
-+ case 44100:
-+ return clock_set_data[0];
-+ case 22050:
-+ return clock_set_data[1];
-+ case 11025:
-+ return clock_set_data[2];
-+ case 48000:
-+ return clock_set_data[3];
-+ case 32000:
-+ return clock_set_data[4];
-+ case 24000:
-+ return clock_set_data[5];
-+ case 16000:
-+ return clock_set_data[6];
-+ default:
-+ printk("Collie sound: Illegal sound rate %d\n", sound.speed);
-+ return clock_set_data[7];
-+ }
-+}
-+
-+static inline void Collie_audio_clock_init(void)
- {
-- ENTER(TRACE_CLOCK, "Collie_audio_clock_init");
- LCM_ACC = 0;
-- LEAVE(TRACE_CLOCK, "Collie_audio_clock_init");
- }
-
- static inline void Collie_audio_clock_on(void)
- {
-- ENTER(TRACE_CLOCK, "Collie_audio_clock_on");
- /* LoCoMo Audio clock on */
- LCM_ACC = CollieGetSamp();
- barrier();
-@@ -1248,263 +603,58 @@
- LCM_ACC |= LCM_ACC_XEN;
- barrier();
- LCM_ACC |= (LCM_ACC_MCLKEN | LCM_ACC_64FSEN);
-- LEAVE(TRACE_CLOCK, "Collie_audio_clock_on");
- }
-
- static inline void Collie_audio_clock_off(void)
- {
-- ENTER(TRACE_CLOCK, "Collie_audio_clock_off");
- /* LoCoMo Audio clock off */
- LCM_ACC &= ~(LCM_ACC_XEN | LCM_ACC_MCLKEN | LCM_ACC_64FSEN);
- barrier();
- LCM_ACC &= ~(LCM_ACC_XON);
-- LEAVE(TRACE_CLOCK, "Collie_audio_clock_off");
--}
--
--static inline void Collie_paif_init(void)
--{
-- ENTER(TRACE_PAIF, "Collie_paif_init");
-- // LCM_PAIF = (LCM_PAIF_SCINV | LCM_PAIF_LRCRST);
-- LCM_PAIF = (LCM_PAIF_LRCRST);
-- LEAVE(TRACE_PAIF, "Collie_paif_init");
- }
-
- static inline void Collie_paif_on(void)
- {
-- ENTER(TRACE_PAIF, "Collie_paif_on");
- LCM_PAIF = (LCM_PAIF_SCINV | LCM_PAIF_LRCRST);
- LCM_PAIF &= ~(LCM_PAIF_LRCRST);
- LCM_PAIF |= (LCM_PAIF_SCEN | LCM_PAIF_LRCEN);
-- LEAVE(TRACE_PAIF, "Collie_paif_on");
- }
-
- static inline void Collie_paif_off(void)
- {
-- ENTER(TRACE_PAIF, "Collie_paif_off");
-- // LCM_PAIF = (LCM_PAIF_SCINV | LCM_PAIF_LRCRST);
- LCM_PAIF = (LCM_PAIF_LRCRST);
-- LEAVE(TRACE_PAIF, "Collie_paif_off");
- }
-
- static inline void Collie_MIC_init(void)
- {
--#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0)
-- ENTER(TRACE_MIC, "Collie_MIC_init");
- /* MIC to GPIO 17 */
- /* alternate functions for the GPIOs */
-- GAFR &= ~( COLLIE_GPIO_MIC );
--
-+ GAFR &= ~( COLLIE_GPIO_MIC );
- /* Set the direction: 17 output */
- GPDR |= ( COLLIE_GPIO_MIC );
--
--#if defined(CONFIG_COLLIE_TR1)
-- /* Set pin level (Low) */
-- GPCR = ( COLLIE_GPIO_MIC );
--#else
- /* Set pin level (High) */
- GPSR = ( COLLIE_GPIO_MIC );
--#endif
-- LEAVE(TRACE_MIC, "Collie_MIC_init");
--#endif /* !CONFIG_COLLIE_TS && !CONFIG_COLLIE_TR0 */
- }
-
- static inline void Collie_MIC_on(void)
- {
--#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0)
-- ENTER(TRACE_MIC, "Collie_MIC_on");
--#if defined(CONFIG_COLLIE_TR1)
-- GPSR = ( COLLIE_GPIO_MIC );
--#else
- GPCR = ( COLLIE_GPIO_MIC );
--#endif
-- LEAVE(TRACE_MIC, "Collie_MIC_on");
--#endif /* !CONFIG_COLLIE_TS && !CONFIG_COLLIE_TR0 */
- }
-
- static inline void Collie_MIC_off(void)
- {
--#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0)
-- ENTER(TRACE_MIC, "Collie_MIC_off");
-- if (!COLLE_RECORDING) {
--#if defined(CONFIG_COLLIE_TR1)
-- GPCR = ( COLLIE_GPIO_MIC );
--#else
-- GPSR = ( COLLIE_GPIO_MIC );
--#endif
-- }
-- LEAVE(TRACE_MIC, "Collie_MIC_off");
--#endif /* !CONFIG_COLLIE_TS && !CONFIG_COLLIE_TR0 */
--}
--
--static inline void Collie_volume_init(void)
--{
-- ENTER(TRACE_VOLUME, "Collie_volume_init");
-- m62332_senddata(0, M62332_EVR_CH);
-- collie_volume = 0;
-- LEAVE(TRACE_VOLUME, "Collie_volume_init");
--}
--
--static inline void Collie_volume_on(void)
--{
-- ENTER(TRACE_VOLUME, "Collie_volume_on");
-- if (collie_volume != sound.volume_left) {
-- //Collie_hard_mute_on();
-- m62332_senddata(0xff * sound.volume_left / 100, M62332_EVR_CH);
-- //Collie_hard_mute_off();
-- collie_volume = sound.volume_left;
-- }
-- LEAVE(TRACE_VOLUME, "Collie_volume_on");
--}
--
--static inline void Collie_volume_off(void)
--{
-- ENTER(TRACE_VOLUME, "Collie_volume_off");
-- if (collie_volume) {
-- //Collie_hard_mute_on();
-- m62332_senddata(0, M62332_EVR_CH);
-- //Collie_hard_mute_off();
-- collie_volume = 0;
-- }
-- LEAVE(TRACE_VOLUME, "Collie_volume_off");
--}
--
--#define VOL_THRES 40
--static void Collie_volume_half_adjust(void)
--{
-- int volume = collie_volume;
-- ENTER(TRACE_VOLUME, "Collie_volume_half_adjust");
-- if (collie_volume > sound.volume_left) {
-- /* volume down */
-- if (collie_volume > VOL_THRES) {
-- if (sound.volume_left > VOL_THRES) {
-- volume = (collie_volume + sound.volume_left)/2;
-- if (volume == collie_volume) {
-- volume = sound.volume_left;
-- }
-- } else {
-- volume = (collie_volume + VOL_THRES)/2;
-- if (volume == collie_volume) {
-- volume = VOL_THRES;
-- }
-- }
-- } else {
-- /* we can pull down without noise */
-- volume = sound.volume_left;
-- }
-- } else if (collie_volume < sound.volume_left) {
-- /* volume up */
-- if (sound.volume_left > VOL_THRES) {
-- if (collie_volume < VOL_THRES) {
-- /* we can pull up to VOL_THRES without noise */
-- volume = VOL_THRES;;
-- } else {
-- volume = (collie_volume + sound.volume_left)/2;
-- if (volume == collie_volume) {
-- volume = sound.volume_left;
-- }
-- }
-- } else {
-- /* we can pull up without noise */
-- volume = sound.volume_left;
-- }
-- }
-- if (collie_volume != volume) {
-- m62332_senddata(0xff * volume / 100, M62332_EVR_CH);
-- collie_volume = volume;
-- }
-- LEAVE(TRACE_VOLUME, "Collie_volume_half_adjust");
--}
--
--static void Collie_volume_half_off(void)
--{
-- int volume;
-- int delta = 1;
-- ENTER(TRACE_VOLUME, "Collie_volume_half_off");
-- while (0 < collie_volume) {
-- if (collie_volume <= VOL_THRES) {
-- volume = 0;
-- } else {
-- if (collie_volume > delta) {
-- volume = collie_volume - delta;
-- } else {
-- volume = 0;
-- }
-- if (volume && volume < VOL_THRES) {
-- volume = VOL_THRES;
-- }
-- delta <<= 1;
-- }
-- m62332_senddata(0xff * volume / 100, M62332_EVR_CH);
-- collie_volume = volume;
-- udelay(100);
-- }
-- LEAVE(TRACE_VOLUME, "Collie_volume_half_off");
--}
--
--static void Collie_OP_SHDN_on(void)
--{
--#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
-- ENTER(TRACE_OP_SHDN,"Collie_OP_SHDN_on");
-- if (!collie_op_shdn_on) {
-- /* set volume */
-- Collie_volume_off();
--
-- /* OP_SHDN to GPIO 17 */
-- /* alternate functions for the GPIOs */
-- GAFR &= ~( COLLIE_GPIO_OPSHDN );
--
-- /* Set the direction: 17 output */
-- GPDR |= ( COLLIE_GPIO_OPSHDN );
--
-- /* Set pin level (high) */
-- GPSR |= ( COLLIE_GPIO_OPSHDN );
--
-- /* set volume */
-- Collie_volume_on();
--
-- collie_op_shdn_on = 1;
-- }
-- LEAVE(TRACE_OP_SHDN,"Collie_OP_SHDN_on");
--#endif /* CONFIG_COLLIE_TS || CONFIG_COLLIE_TR0 */
--}
--
--static void Collie_OP_SHDN_off(void)
--{
--#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
-- ENTER(TRACE_OP_SHDN,"Collie_OP_SHDN_off");
-- /* OP_SHDN to GPIO 17 */
-- /* alternate functions for the GPIOs */
-- GAFR &= ~( COLLIE_GPIO_OPSHDN );
--
-- /* Set the direction: 17 output */
-- GPDR |= ( COLLIE_GPIO_OPSHDN );
--
-- /* Clear pin level (low) */
-- GPCR |= ( COLLIE_GPIO_OPSHDN );
--
-- collie_op_shdn_on = 0;
-- LEAVE(TRACE_OP_SHDN,"Collie_OP_SHDN_off");
--#endif /* CONFIG_COLLIE_TS || CONFIG_COLLIE_TR0 */
-+ GPSR = ( COLLIE_GPIO_MIC );
- }
-
- static inline void Collie_ssp_init(void)
- {
-- ENTER(TRACE_SSP, "Collie_ssp_init");
- /* alternate functions for the GPIOs */
- /* SSP port to GPIO 10,12,13, 19 */
- GAFR |= ( GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SSP_CLK );
--#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
-- /* SSP port to GPIO 11 */
-- GAFR |= GPIO_SSP_RXD;
--#endif /* CONFIG_COLLIE_TS || CONFIG_COLLIE_TR0 */
-
- /* Set the direction: 10, 12, 13 output; 19 input */
- GPDR |= ( GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM );
- GPDR &= ~( GPIO_SSP_CLK );
--#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
-- /* Set the direction: 11 input */
-- GPDR &= ~( GPIO_SSP_RXD );
--#endif /* CONFIG_COLLIE_TS || CONFIG_COLLIE_TR0 */
-
- /* enable SSP pin swap */
- PPAR |= PPAR_SPR;
-@@ -1516,400 +666,162 @@
- /* the SSP setting */
- Ser4SSCR0 = (SSCR0_DataSize(16) | SSCR0_TI | SSCR0_SerClkDiv(2));
- Ser4SSCR1 = (SSCR1_SClkIactL | SSCR1_SClk1P | SSCR1_ExtClk);
--
-- LEAVE(TRACE_SSP, "Collie_ssp_init");
- }
-
- static inline void Collie_ssp_on(void)
- {
-- ENTER(TRACE_SSP, "Collie_ssp_on");
- /* turn on the SSP */
- Ser4SSCR0 |= ( SSCR0_SSE );
-- LEAVE(TRACE_SSP, "Collie_ssp_on");
- }
-
- static inline void Collie_ssp_off(void)
- {
-- ENTER(TRACE_SSP, "Collie_ssp_off");
- /* turn off the SSP */
- Ser4SSCR0 &= ~( SSCR0_SSE );
-- LEAVE(TRACE_SSP, "Collie_ssp_off");
--}
--
--static inline void Collie_sound_hard_init(void)
--{
-- ENTER(TRACE_ON, "Collie_sound_hard_init");
-- Collie_hard_mute_init();
-- Collie_audio_clock_init();
-- Collie_paif_init();
-- Collie_volume_init();
-- Collie_ssp_init();
-- Collie_MIC_init();
--
-- Collie_FS8KLPF_start();
-- LEAVE(TRACE_ON, "Collie_sound_hard_init");
--}
--
--static inline void Collie_sound_hard_term(void)
--{
-- ENTER(TRACE_ON, "Collie_sound_hard_term");
--#ifdef DAC_OFF_WITH_DEVICE_OFF
-- /* DAC Off */
-- Collie_DAC_off();
--#endif
-- LEAVE(TRACE_ON, "Collie_sound_hard_term");
--}
--
--static void Collie_FS8KLPF_start(void)
--{
--#if defined(CONFIG_COLLIE_TS) || defined(CONFIG_COLLIE_TR0)
-- ENTER(TRACE_ON,"Collie_FS8KLPF_start");
-- /* Set up TC35143 GPIO I/O Direction (GPIO5 output mode) */
-- ucb1200_set_io_direction(TC35143_GPIO_FS8KLPF,
-- TC35143_IODIR_OUTPUT);
-- /* Set up TC35143 GPIO 5 (set LOW) */
-- ucb1200_set_io(TC35143_GPIO_FS8KLPF, TC35143_IODAT_LOW);
-- LEAVE(TRACE_ON,"Collie_FS8KLPF_start");
--#endif /* CONFIG_COLLIE_TS || CONFIG_COLLIE_TR0 */
--}
--
--#ifdef CONFIG_PM
--#if 0
--static void Collie_FS8KLPF_stop(void)
--{
-- /* Set up TC35143 GPIO I/O Direction (GPIO5 output mode) */
-- ucb1200_set_io_direction(TC35143_GPIO_FS8KLPF,
-- TC35143_IODIR_OUTPUT);
-- /* Set up TC35143 GPIO 5 (set LOW) */
-- ucb1200_set_io(TC35143_GPIO_FS8KLPF, TC35143_IODAT_HIGH);
--}
--
--static void Collie_clock_stop(void)
--{
-- /* LoCoMo PCM audio interface */
-- Collie_paif_off();
--
-- /* LoCoMo audio clock off */
-- Collie_audio_clock_off();
--}
--#endif
--#endif
--
--#ifdef TRY_DELAY_OFF /* H.Hayami SHARP 2001.12.19 */
--static unsigned long in_timehandle = 0;
--static struct timer_list timer;
--
--static void collieDoDelayedSilence(void)
--{
-- ENTER(TRACE_ON,"collieDoDelayedSilence");
-- down(&df_sem);
-- if(isDelayed(DELAY_HARD_MUTE_ON)) {
-- Collie_hard_mute_on();
-- }
-- if(isDelayed(DELAY_DAC_OFF)) {
-- Collie_DAC_off();
-- }
-- ResetDelayAll();
-- up(&df_sem);
-- LEAVE(TRACE_ON,"colliDoDelayedSilence");
--}
--
--static void collieDelayedSilence(void)
--{
-- ENTER(TRACE_ON,"collieDelayedSilence");
-- while (1) {
-- sleep_on(&delay_off);
-- collieDoDelayedSilence();
-- }
-- LEAVE(TRACE_ON,"collieDelayedSilence");
--}
--
--static void collieStartDelayedSilence(unsigned long data)
--{
-- ENTER(TRACE_ON,"collieStartDelayedSilence");
-- in_timehandle = 0;
-- wake_up(&delay_off);
-- LEAVE(TRACE_ON,"collieStartDelayedSilence");
--}
--
--static void collieTriggerDelayedSilence(void)
--{
-- ENTER(TRACE_ON,"collieTriggerDelayedSilence");
-- in_timehandle = 1;
-- init_timer(&timer);
-- timer.function = collieStartDelayedSilence;
-- timer.expires = jiffies + 5*100;
-- add_timer(&timer);
-- LEAVE(TRACE_ON,"collieTriggerDelayedSilence");
--}
--
--static void collieCancelDelayedSilence(void)
--{
-- ENTER(TRACE_ON,"collieCancelDelayedSilence");
-- down(&df_sem);
-- ResetDelayAll();;
-- up(&df_sem);
-- if (in_timehandle) {
-- del_timer(&timer);
-- in_timehandle = 0;
-- }
-- LEAVE(TRACE_ON,"collieCancelDelayedSilence");
--}
--#endif
--
--static void Collie_disable_sound(void)
--{
-- ENTER(TRACE_ON,"Collie_disable_sound");
-- sa1100_dma_stop(COLLIE_SOUND_DMA_CHANNEL);
-- sa1100_dma_flush_all(COLLIE_SOUND_DMA_CHANNEL);
--#ifndef TRY_DELAY_OFF /* H.Hayami SHARP 2001.12.18 */
-- Collie_volume_half_off();
-- Collie_hard_mute_on();
-- Collie_soft_mute_on();
--
-- Collie_ssp_off();
--
-- /* Collie_clock_stop(); */
--#endif
-- LEAVE(TRACE_ON,"Collie_disable_sound");
--}
--
--static void CollieSilence(void)
--{
-- ENTER(TRACE_ON,"CollieSilence");
-- /* Disable sound & DMA */
-- Collie_disable_sound();
--
--#ifdef TRY_DELAY_OFF /* H.Hayami SHARP 2001.12.18 */
-- Collie_volume_half_off();
-- Collie_hard_mute_delay_on();
-- Collie_soft_mute_on();
--
-- Collie_ssp_off();
--
-- /* Collie_clock_stop(); */
--#endif
--
--#if 0 /* H.Hayami SHARP 2001.12.18 */
--#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0) && \
-- !defined(CONFIG_COLLIE_TR1) && !defined(CONFIG_COLLIE_DEV)
-- Collie_volume_off();
--#endif
--#endif
-- Collie_OP_SHDN_off();
-- Collie_soft_DAC_off();
-- Collie_paif_off();
-- Collie_audio_clock_off();
--
-- //Collie_MIC_on();
--
--#ifndef DAC_OFF_WITH_DEVICE_OFF
-- /* DAC Off */
--#ifdef TRY_DELAY_OFF /* H.Hayami 2001.12.15 */
-- Collie_DAC_delay_off();
--#else
-- Collie_DAC_off();
--#endif
--#endif /* end DAC_OFF_WITH_DEVICE_OFF */
--
-- /* AMP Off */
-- Collie_AMP_off();
--
--#ifdef TRY_DELAY_OFF /* H.Hayami SHARP 2001.12.18 */
-- collieTriggerDelayedSilence();
--#endif
-- LEAVE(TRACE_ON,"CollieSilence");
--}
--
--static int CollieGetSamp(void)
--{
-- ENTER(TRACE_ON,"CollieGetSamp");
-- switch (sound.soft.speed) {
-- case 8000:
-- LEAVE(TRACE_ON,"CollieGetSamp");
-- return clock_set_data[7];
-- case 44100:
-- LEAVE(TRACE_ON,"CollieGetSamp");
-- return clock_set_data[0];
-- case 22050:
-- LEAVE(TRACE_ON,"CollieGetSamp");
-- return clock_set_data[1];
-- case 11025:
-- LEAVE(TRACE_ON,"CollieGetSamp");
-- return clock_set_data[2];
-- case 48000:
-- LEAVE(TRACE_ON,"CollieGetSamp");
-- return clock_set_data[3];
-- case 32000:
-- LEAVE(TRACE_ON,"CollieGetSamp");
-- return clock_set_data[4];
-- case 24000:
-- LEAVE(TRACE_ON,"CollieGetSamp");
-- return clock_set_data[5];
-- case 16000:
-- LEAVE(TRACE_ON,"CollieGetSamp");
-- return clock_set_data[6];
-- default:
-- printk("Collie sound: Illegal sound rate %d\n", sound.soft.speed);
-- LEAVE(TRACE_ON,"CollieGetSamp");
-- return clock_set_data[7];
-- }
--}
--
--static inline void Collie_DAC_sendbit(int bit_data)
--{
-- ENTER(TRACE_SENDDATA,"Collie_DAC_sendbit");
-- if (bit_data & 1) {
-- LCM_GPO |= (LCM_GPIO_DAC_SDATA);
-- } else {
-- LCM_GPO &= ~(LCM_GPIO_DAC_SDATA);
-- }
--
-- udelay(1);
-- LCM_GPO |= (LCM_GPIO_DAC_SCK);
--
-- udelay(1);
-- LCM_GPO &= ~(LCM_GPIO_DAC_SCK);
-- udelay(1);
-- LCM_GPO &= ~(LCM_GPIO_DAC_SDATA);
-- udelay(1);
-- LEAVE(TRACE_SENDDATA,"Collie_DAC_sendbit");
--}
--
--static void Collie_DAC_sendword(int data)
--{
-- int i;
--
-- ENTER(TRACE_SENDDATA,"Collie_DAC_sendword");
--#if defined(CONFIG_COLLIE_PCM1741)
--
-- LCM_GPO &= ~(LCM_GPIO_DAC_SCK);
-- udelay(1);
-- LCM_GPO |= (LCM_GPIO_DAC_SLOAD);
-- udelay(1);
--
-- for (i = 0; i < 16; i++)
-- Collie_DAC_sendbit(data >> (15 - i));
--
-- LCM_GPO &= ~(LCM_GPIO_DAC_SLOAD);
-- udelay(2);
--
--#elif defined(CONFIG_COLLIE_PCM1717)
--
-- LCM_GPO &= ~(LCM_GPIO_DAC_SLOAD);
-- udelay(1000);
-- LCM_GPO |= (LCM_GPIO_DAC_SLOAD);
-- udelay(1000);
-- LCM_GPO &= ~(LCM_GPIO_DAC_SCK);
-- udelay(1000);
--
-- for (i = 0; i < 16; i++)
-- Collie_DAC_sendbit(data >> (15 - i));
--
-- LCM_GPO &= ~(LCM_GPIO_DAC_SLOAD);
-- udelay(1000);
-- LCM_GPO |= (LCM_GPIO_DAC_SLOAD);
-- udelay(1000);
-- LCM_GPO &= ~(LCM_GPIO_DAC_SLOAD);
-- udelay(1000);
--
--#endif
-- LEAVE(TRACE_SENDDATA,"Collie_DAC_sendword");
- }
-
--void
--Collie_audio_power_on(void)
-+
-+static inline void Collie_sound_hard_init(void)
- {
-- int send_data;
-+ Collie_hard_mute_init();
-+ Collie_audio_clock_init();
-+ Collie_paif_off();
-+ Collie_volume_init();
-+ Collie_ssp_init();
-+ Collie_MIC_init();
-+ Collie_soft_mute_on();
-+ Collie_DAC_on();
-+}
-
-- ENTER(TRACE_ON,"Collie_audio_power_on");
-+void Collie_recording_on(void)
-+{
-+ collie_recording=1;
-+ if (!playing)
-+ Collie_DAC_on();
-+ else
-+ Collie_hard_mute_left_on();
-+ Collie_MIC_on();
-+}
-
--#ifdef TRY_DELAY_OFF /* H.Hayami SHARP 2001.12.19 */
-- collieCancelDelayedSilence();
--#endif
-+void Collie_recording_off(void)
-+{
-+ collie_recording=0;
-+ Collie_MIC_off();
-+ if (!playing)
-+ Collie_DAC_off();
-+ else
-+ Collie_hard_mute_left_off();
-+}
-
-+static void Collie_audio_power_on(void)
-+{
-+ playing=1;
- collie_amp_init = 0;
--
-- /* OP_SHDN off */
-- Collie_OP_SHDN_off();
--
-- /* AMP on */
-- Collie_AMP_on();
--
-- /* DAC ON */
-- Collie_DAC_on();
--
-- Collie_MIC_off();
-- Collie_ssp_on();
--
-- /* LoCoMo Audio clock */
-- Collie_audio_clock_off();
-+ if (!collie_recording)
-+ Collie_DAC_on();
-+ Collie_ssp_on();
-+ Collie_audio_clock_off(); /* LoCoMo Audio clock */
- Collie_audio_clock_on();
--
-- /* LoCoMo PCM audio interface */
-- Collie_paif_on();
--
-+ Collie_paif_on(); /* LoCoMo PCM audio interface */
- udelay(1000);
--
-- /* DAC Setting */
- Collie_DAC_init();
--
- Collie_soft_DAC_on();
-- Collie_soft_mute_init();
-+ Collie_soft_mute_off();
-+ Collie_hard_mute_off();
-+ if (collie_recording)
-+ Collie_hard_mute_left_on();
-+ Collie_volume_set(sound.volume);
-+}
-
-- sound.hard = sound.soft;
-+static void Collie_audio_power_off(void){ /* Disable sound only */
-+ Collie_volume_set(0);
-+ Collie_hard_mute_on();
-+ Collie_soft_mute_on();
-+ Collie_ssp_off();
-+ Collie_soft_DAC_off();
-+ Collie_paif_off();
-+ Collie_audio_clock_off();
-+ if (!collie_recording)
-+ Collie_DAC_off();
-+ playing=0;
-+}
-
--#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0) && \
-- !defined(CONFIG_COLLIE_TR1) && !defined(CONFIG_COLLIE_DEV)
-- /* Volume set */
-- Collie_volume_half_adjust();
-- {
-- int i;
-- for (i=0; i<10*1000; i++) {
-- udelay(1);
-+
-+static inline void Collie_volume_init(void)
-+{
-+ m62332_senddata(0, M62332_EVR_CH);
-+ collie_volume = 0;
-+}
-+
-+#define VOL_THRES 10
-+
-+static void Collie_volume_set(int dest)
-+{
-+ int chn;
-+ while (dest != collie_volume) {
-+ chn = dest-collie_volume;
-+ if (chn>VOL_THRES)
-+ chn=VOL_THRES;
-+ else if (chn<-VOL_THRES)
-+ chn=-VOL_THRES;
-+ if (chn) {
-+ collie_volume += chn;
-+ m62332_senddata(0xff * collie_volume / 100, M62332_EVR_CH);
- }
-+ udelay(100);
- }
--#endif
-+}
-
-- Collie_soft_mute_off();
-- Collie_hard_mute_off();
-+static int sound_set_speed(int speed)
-+{
-+ if (speed < 0) {
-+ return(sound.speed);
-+ }
-+
-+ if (speed<8000) sound.speed=8000;
-+ else if (speed<=11025) sound.speed=11025;
-+ else if (speed<=16000) sound.speed=16000;
-+ else if (speed<=22050) sound.speed=22050;
-+ else if (speed<=24000) sound.speed=24000;
-+ else if (speed<=32000) sound.speed=32000;
-+ else if (speed<=44100) sound.speed=44100;
-+ else sound.speed=48000;
-+
-+ /* LoCoMo Audio clock */
-+ Collie_audio_clock_off();
-+ Collie_audio_clock_on();
-+ return(sound.speed);
-+}
-
-- LEAVE(TRACE_ON,"Collie_audio_power_on");
-+/*** Mid level stuff *********************************************************/
-+
-+static void Collie_Set_Volume(int volume)
-+{
-+ sound.volume = volume & 0xff;
-+ sound.volume += ( volume & 0xff00 >> 8);
-+ sound.volume >>=1;
-+ if (sound.volume>100) sound.volume=100;
- }
-
--static void CollieInit(void)
-+static int Collie_Get_Volume(void)
- {
-- ENTER(TRACE_ON,"CollieInit");
-- sound.hard = sound.soft;
-- LEAVE(TRACE_ON,"CollieInit");
-+ return ( sound.volume << 8 | sound.volume );
- }
-
-+
- static void Collie_sq_interrupt(void* id, int size)
- {
- audio_buf_t *b = (audio_buf_t *) id;
-- ENTER(TRACE_INTERRUPT,"Collie_sq_interrupt");
--/***** DEBUG *****
--printk("Collie_sq_interrupt: Start\n");
--*****************/
-+
- /*
- * Current buffer is sent: wake up any process waiting for it.
- */
-- ENTER(TRACE_SEM,"up sem");
- up(&b->sem);
-- LEAVE(TRACE_SEM,"up sem");
--/***** DEBUG *****
--printk("Collie_sq_interrupt: up End\n");
--*****************/
- /* And any process polling on write. */
-- ENTER(TRACE_SEM,"up wait");
-- wake_up(&b->sem.wait);
-- LEAVE(TRACE_SEM,"up wait");
--/***** DEBUG *****
--printk("Collie_sq_interrupt: wake_up End\n");
--*****************/
-+ wake_up_interruptible(&b->sem.wait);
-+ /* And indicate which was the last buffer sent */
-
- DPRINTK("Collie_sq_interrupt \n");
-- LEAVE(TRACE_INTERRUPT,"Collie_sq_interrupt");
- }
-
-
-@@ -1917,191 +829,52 @@
- {
- int err;
-
-- ENTER(TRACE_ON,"CollieIrqInit");
- err = sa1100_request_dma(&collie_dmasound_irq, "dmasound",
- DMA_Ser4SSPWr);
- if (err) {
-- LEAVE(TRACE_ON,"CollieIrqInit");
- return 0;
- }
-- /* printk("collie_dmasound_irq=%d\n", collie_dmasound_irq); */
-+ printk("collie_dmasound_irq=%d\n", collie_dmasound_irq);
-
- sa1100_dma_set_callback(collie_dmasound_irq,
- (dma_callback_t)Collie_sq_interrupt);
-
--
-- /* Disable sound & DMA */
-- Collie_disable_sound();
--
-- LEAVE(TRACE_ON,"CollieIrqInit");
-+ sa1100_dma_stop(COLLIE_SOUND_DMA_CHANNEL);
-+ sa1100_dma_flush_all(COLLIE_SOUND_DMA_CHANNEL);
-+ Collie_audio_power_off();
- return(1);
--
--}
--
--#ifdef MODULE
--static void CollieIrqCleanUp(void)
--{
-- ENTER(TRACE_ON,"CollieIrqCleanUp");
-- /* Disable sound & DMA */
-- Collie_disable_sound();
--
-- /* release the interrupt */
-- free_irq(IRQ_DMA, Collie_sq_interrupt);
-- LEAVE(TRACE_ON,"CollieIrqCleanUp");
- }
--#endif /* MODULE */
--
-
- static int CollieSetFormat(int format)
- {
- int size;
-
-- ENTER(TRACE_ON,"CollieSetFormat");
-- /* Falcon sound DMA supports 8bit and 16bit modes */
--
- switch (format) {
- case AFMT_QUERY:
-- LEAVE(TRACE_ON,"CollieSetFormat");
-- return(sound.soft.format);
-- case AFMT_MU_LAW:
-- size = 8;
-- ct_func = sound.trans->ct_ulaw;
-- break;
-- case AFMT_A_LAW:
-- size = 8;
-- ct_func = sound.trans->ct_alaw;
-- break;
-- case AFMT_S8:
-- size = 8;
-- ct_func = sound.trans->ct_s8;
-- break;
-- case AFMT_U8:
-- size = 8;
-- ct_func = sound.trans->ct_u8;
-- break;
-- case AFMT_S16_BE:
-- size = 16;
-- ct_func = sound.trans->ct_s16be;
-- break;
-- case AFMT_U16_BE:
-- size = 16;
-- ct_func = sound.trans->ct_u16be;
-- break;
-- case AFMT_S16_LE:
-- size = 16;
-- ct_func = sound.trans->ct_s16le;
-- break;
-- case AFMT_U16_LE:
-+ return(sound.format);
-+ default: /* This is the only one supported by the hardware it seems */
- size = 16;
-- ct_func = sound.trans->ct_u16le;
-- break;
-- default: /* :-) */
-- size = 8;
-- format = AFMT_S8;
-- }
--
-- sound.soft.format = format;
-- sound.soft.size = size;
-- if (sound.minDev == SND_DEV_DSP) {
-- sound.dsp.format = format;
-- sound.dsp.size = sound.soft.size;
-+ format = AFMT_S16_LE;
- }
-+ sound.format = format;
-+ sound.size = size;
-
-- LEAVE(TRACE_ON,"CollieSetFormat");
- return(format);
- }
-
--/*** Machine definitions *****************************************************/
--
--static MACHINE machCollie = {
-- DMASND_COLLIE, // int type
-- NULL, // void *dma_alloc(uint, int)
-- NULL, // void dma_free(void *, uint)
-- CollieIrqInit, // void irqinit(void)
--#ifdef MODULE
-- CollieIrqCleanUp, // void irqcleanup(void)
--#endif /* MODULE */
-- CollieInit, // void init(void)
-- CollieSilence, // void silence(void)
-- CollieSetFormat, // int setFormat(int)
-- NULL, // int setVolume(int)
-- NULL, // int setBass(int)
-- NULL, // int setTreble(int)
-- NULL, // int setGain(int)
-- NULL // void play(void)
--};
--
--
--/*** Mid level stuff *********************************************************/
--
--
--static void sound_silence(void)
--{
-- ENTER(TRACE_ON,"sound_silence");
-- /* update hardware settings one more */
-- //(*sound.mach.init)();
-- (*sound.mach.silence)();
-- LEAVE(TRACE_ON,"sound_silence");
--
--}
--
--
--static void sound_init(void)
--{
-- ENTER(TRACE_ON,"sound_init");
-- (*sound.mach.init)();
-- LEAVE(TRACE_ON,"sound_init");
--}
--
--
--static int sound_set_format(int format)
--{
-- ENTER(TRACE_ON,"sound_set_format");
-- LEAVE(TRACE_ON,"sound_set_format");
-- return(*sound.mach.setFormat)(format);
--}
--
--
--static int sound_set_speed(int speed)
--{
-- ENTER(TRACE_ON,"sound_set_speed");
-- if (speed < 0) {
-- LEAVE(TRACE_ON,"sound_set_speed");
-- return(sound.soft.speed);
-- }
--
-- sound.soft.speed = speed;
-- (*sound.mach.init)();
-- if (sound.minDev == SND_DEV_DSP)
-- sound.dsp.speed = sound.soft.speed;
--
-- /* LoCoMo Audio clock */
-- Collie_audio_clock_off();
-- Collie_audio_clock_on();
--
-- LEAVE(TRACE_ON,"sound_set_speed");
-- return(sound.soft.speed);
--}
-
-
- static int sound_set_stereo(int stereo)
- {
-- ENTER(TRACE_ON,"sound_set_stereo");
-+/* Only stereo is supported by hardware */
- if (stereo < 0) {
-- LEAVE(TRACE_ON,"sound_set_stereo");
-- return(sound.soft.stereo);
-+ return(sound.stereo);
- }
-+ return(1);
-+}
-
-- stereo = !!stereo; /* should be 0 or 1 now */
--
-- sound.soft.stereo = stereo;
-- if (sound.minDev == SND_DEV_DSP)
-- sound.dsp.stereo = stereo;
-- //(*sound.mach.init)();
-
-- LEAVE(TRACE_ON,"sound_set_stereo");
-- return(stereo);
--}
-+/* Higher level stuff ************************************************/
-
- /*
- * /dev/mixer abstraction
-@@ -2109,20 +882,15 @@
-
- static int mixer_open(struct inode *inode, struct file *file)
- {
-- ENTER(TRACE_ON,"mixer_open");
- MOD_INC_USE_COUNT;
- mixer.busy = 1;
-- LEAVE(TRACE_ON,"mixer_open");
- return 0;
- }
-
--
- static int mixer_release(struct inode *inode, struct file *file)
- {
-- ENTER(TRACE_ON,"mixer_release");
- mixer.busy = 0;
- MOD_DEC_USE_COUNT;
-- LEAVE(TRACE_ON,"mixer_release");
- return 0;
- }
-
-@@ -2132,58 +900,37 @@
- {
- int data;
-
-- ENTER(TRACE_ON,"mixer_ioctl");
-- switch (sound.mach.type) {
-- case DMASND_COLLIE:
-- {
-- switch (cmd) {
-- case SOUND_MIXER_READ_DEVMASK:
-- LEAVE(TRACE_ON,"mixer_ioctl");
-- return IOCTL_OUT(arg, SOUND_MASK_VOLUME );
-- case SOUND_MIXER_READ_RECMASK:
-- LEAVE(TRACE_ON,"mixer_ioctl");
-- return IOCTL_OUT(arg, 0);
-- case SOUND_MIXER_READ_STEREODEVS:
-- LEAVE(TRACE_ON,"mixer_ioctl");
-- return IOCTL_OUT(arg, SOUND_MASK_VOLUME);
-- case SOUND_MIXER_READ_CAPS:
-- LEAVE(TRACE_ON,"mixer_ioctl");
-- return IOCTL_OUT(arg, 0);
--
-- case SOUND_MIXER_WRITE_VOLUME:
-- IOCTL_IN(arg, data);
-- Collie_Set_Volume(data);
-- case SOUND_MIXER_READ_VOLUME:
-- LEAVE(TRACE_ON,"mixer_ioctl");
-- return IOCTL_OUT(arg, Collie_Get_Volume());
--
-- case SOUND_MIXER_READ_TREBLE:
-- LEAVE(TRACE_ON,"mixer_ioctl");
-- return IOCTL_OUT(arg, 0);
-- case SOUND_MIXER_WRITE_TREBLE:
-- LEAVE(TRACE_ON,"mixer_ioctl");
-- return IOCTL_OUT(arg, 0);
--
-- case SOUND_MIXER_WRITE_MIC:
-- LEAVE(TRACE_ON,"mixer_ioctl");
-- return IOCTL_OUT(arg, 0);
-- case SOUND_MIXER_READ_MIC:
-- LEAVE(TRACE_ON,"mixer_ioctl");
-- return IOCTL_OUT(arg, 0);
--
-- case SOUND_MIXER_READ_SPEAKER:
-- LEAVE(TRACE_ON,"mixer_ioctl");
-- return IOCTL_OUT(arg, 0);
-- case SOUND_MIXER_WRITE_SPEAKER:
-- LEAVE(TRACE_ON,"mixer_ioctl");
-- return IOCTL_OUT(arg, 0);
-- }
-- break;
-- }
-- }
-- LEAVE(TRACE_ON,"mixer_ioctl");
-+ switch (cmd) {
-+ case SOUND_MIXER_READ_DEVMASK:
-+ return IOCTL_OUT(arg, headphone ? SOUND_MASK_VOLUME : 0 );
-+ case SOUND_MIXER_READ_RECMASK:
-+ return IOCTL_OUT(arg, 0);
-+ case SOUND_MIXER_READ_STEREODEVS:
-+ return IOCTL_OUT(arg, headphone ? SOUND_MASK_VOLUME : 0 );
-+ case SOUND_MIXER_READ_CAPS:
-+ return IOCTL_OUT(arg, 0);
-+
-+ case SOUND_MIXER_WRITE_VOLUME:
-+ IOCTL_IN(arg, data);
-+ Collie_Set_Volume(data);
-+ case SOUND_MIXER_READ_VOLUME:
-+ return IOCTL_OUT(arg, Collie_Get_Volume());
-+ case SOUND_MIXER_READ_TREBLE:
-+ return IOCTL_OUT(arg, 0);
-+ case SOUND_MIXER_WRITE_TREBLE:
-+ return IOCTL_OUT(arg, 0);
-+
-+ case SOUND_MIXER_WRITE_MIC:
-+ return IOCTL_OUT(arg, 0);
-+ case SOUND_MIXER_READ_MIC:
-+ return IOCTL_OUT(arg, 0);
-+
-+ case SOUND_MIXER_READ_SPEAKER:
-+ return IOCTL_OUT(arg, 0);
-+ case SOUND_MIXER_WRITE_SPEAKER:
-+ return IOCTL_OUT(arg, 0);
-+ }
- return -EINVAL;
--
- }
-
-
-@@ -2198,32 +945,13 @@
-
- static void __init mixer_init(void)
- {
--#ifndef MODULE
-- int mixer_unit;
--#endif
-- ENTER(TRACE_ON,"mixer_init");
- mixer_unit = register_sound_mixer(&mixer_fops, -1);
- if (mixer_unit < 0) {
-- LEAVE(TRACE_ON,"mixer_init");
- return;
- }
--
- mixer.busy = 0;
-- sound.treble = 0;
-- sound.bass = 0;
-- switch (sound.mach.type) {
-- case DMASND_COLLIE:
-- // sound.volume_left = 0x3c;
-- // sound.volume_right = 0x3c;
-- sound.volume_left = 80;
-- sound.volume_right = 80;
-- collie_main_volume = sound.volume_left;
-- break;
-- }
--
-- // printk("mixer_init : ret \n");
--
-- LEAVE(TRACE_ON,"mixer_init");
-+ sound.volume = 80;
-+ Collie_volume_set(sound.volume);
- }
-
- /* This function allocates the buffer structure array and buffer data space
-@@ -2237,11 +965,9 @@
- char *dmabuf = 0;
- dma_addr_t dmaphys = 0;
-
-- ENTER(TRACE_ON,"sq_allocate_buffers");
- DPRINTK("sq_allocate_buffers\n");
-
- if (s->buffers) {
-- LEAVE(TRACE_ON,"sq_allocate_buffers");
- return -EBUSY;
- }
-
-@@ -2279,10 +1005,8 @@
-
- b->start = dmabuf;
- b->dma_addr = dmaphys;
-+ b->idx = frag;
- sema_init(&b->sem, 1);
-- DPRINTK("buf %d: start %p dma %p\n", frag, b->start,
-- b->dma_addr);
--
- dmabuf += s->fragsize;
- dmaphys += s->fragsize;
- dmasize -= s->fragsize;
-@@ -2291,13 +1015,12 @@
- s->buf_idx = 0;
- s->buf = &s->buffers[0];
-
-- LEAVE(TRACE_ON,"sq_allocate_buffers");
-+
- return 0;
-
- err:
- printk("sound driver : unable to allocate audio memory\n ");
- sq_release_buffers(s);
-- LEAVE(TRACE_ON,"sq_allocate_buffers");
- return -ENOMEM;
- }
-
-@@ -2307,7 +1030,6 @@
-
- static void sq_release_buffers(audio_stream_t * s)
- {
-- ENTER(TRACE_ON,"sq_release_buffers");
- DPRINTK("sq_release_buffers\n");
-
- /* ensure DMA won't run anymore */
-@@ -2328,7 +1050,6 @@
-
- s->buf_idx = 0;
- s->buf = NULL;
-- LEAVE(TRACE_ON,"sq_release_buffers");
- }
-
- static ssize_t sq_write(struct file *file, const char *src, size_t uLeft,
-@@ -2339,27 +1060,20 @@
- u_char *dest;
- ssize_t uUsed, bUsed, bLeft, ret = 0;
-
-- ENTER(TRACE_WRITE,"sq_write");
- DPRINTK("sq_write: uLeft=%d\n", uLeft);
-
-- /* OP_SHDN on */
-- Collie_OP_SHDN_on();
--
- switch (file->f_flags & O_ACCMODE) {
- case O_WRONLY:
- case O_RDWR:
- break;
- default:
-- LEAVE(TRACE_WRITE,"sq_write1");
- return -EPERM;
- }
-
- if (!s->buffers && sq_allocate_buffers(s)) {
-- LEAVE(TRACE_WRITE,"sq_write2");
- return -ENOMEM;
- }
-
--#if 1
- if (collie_resume == 1) {
- int i;
- collie_resume = 0;
-@@ -2367,10 +1081,9 @@
- udelay(1);
- }
- }
--#endif
- #ifdef CONFIG_PM
- /* Auto Power off cancel */
-- autoPowerCancel = 0;
-+// autoPowerCancel = 0;
- #endif
-
- while (uLeft > 0) {
-@@ -2379,41 +1092,30 @@
- /* Wait for a buffer to become free */
- if (file->f_flags & O_NONBLOCK) {
- ret = -EAGAIN;
-- ENTER(TRACE_SEM,"down_try sem");
- if (down_trylock(&b->sem)) {
-- LEAVE(TRACE_SEM,"down_try1 sem");
- break;
- }
-- LEAVE(TRACE_SEM,"down_try2 sem");
- } else {
- ret = -ERESTARTSYS;
-- ENTER(TRACE_SEM,"down_int sem");
-- //printk("### 0x%08x:%d\n", &b->sem.count, atomic_read(&b->sem.count));
- if (down_interruptible(&b->sem)) {
-- LEAVE(TRACE_SEM,"down_int1 sem");
- break;
- }
-- LEAVE(TRACE_SEM,"down_int2 sem");
- }
-
- dest = b->start + b->size;
- bUsed = 0;
- bLeft = s->fragsize - b->size;
-
-- if (ct_func) {
-- uUsed = ct_func(src, uLeft, dest, &bUsed, bLeft);
-+ if (collie_ct_s16) {
-+ uUsed = collie_ct_s16(src, uLeft, dest, &bUsed, bLeft);
- cpu_cache_clean_invalidate_range((unsigned long)dest,
- (unsigned long)(dest+(audio_fragsize)), 0);
- } else {
-- LEAVE(TRACE_WRITE,"sq_write3");
- return -EFAULT;
- }
-
- if (uUsed < 0) {
-- ENTER(TRACE_SEM,"up sem");
- up(&b->sem);
-- LEAVE(TRACE_SEM,"up sem");
-- LEAVE(TRACE_WRITE,"sq_write4");
- return -EFAULT;
- }
- src += uUsed;
-@@ -2421,9 +1123,7 @@
- b->size += bUsed;
-
- if (b->size < s->fragsize) {
-- ENTER(TRACE_SEM,"up sem");
- up(&b->sem);
-- LEAVE(TRACE_SEM,"up sem");
- break;
- }
-
-@@ -2431,7 +1131,7 @@
- sa1100_dma_queue_buffer(COLLIE_SOUND_DMA_CHANNEL,
- (void *) b, b->dma_addr, b->size);
-
-- Collie_volume_half_adjust();
-+ Collie_volume_set(sound.volume);
-
- b->size = 0; /* indicate that the buffer has been sent */
- NEXT_BUF(s, buf);
-@@ -2440,7 +1140,6 @@
- if ((src - buffer0))
- ret = src - buffer0;
- DPRINTK("sq_write: return=%d\n", ret);
-- LEAVE(TRACE_WRITE,"sq_write0");
- return ret;
- }
-
-@@ -2450,7 +1149,6 @@
- unsigned int mask = 0;
- int i;
-
-- ENTER(TRACE_ON,"sq_poll");
- DPRINTK("sq_poll(): mode=%s%s\n",
- (file->f_mode & FMODE_READ) ? "r" : "",
- (file->f_mode & FMODE_WRITE) ? "w" : "");
-@@ -2458,12 +1156,9 @@
- if (file->f_mode & FMODE_WRITE) {
- if (!output_stream.buffers
- && sq_allocate_buffers(&output_stream)) {
-- LEAVE(TRACE_ON,"sq_poll");
- return -ENOMEM;
- }
-- ENTER(TRACE_SEM,"poll_wait wait");
- poll_wait(file, &output_stream.buf->sem.wait, wait);
-- LEAVE(TRACE_SEM,"poll_wait wait");
- }
-
- if (file->f_mode & FMODE_WRITE) {
-@@ -2477,65 +1172,33 @@
- (mask & POLLIN) ? "r" : "",
- (mask & POLLOUT) ? "w" : "");
-
-- LEAVE(TRACE_ON,"sq_poll");
- return mask;
- }
-
- static int sq_open(struct inode *inode, struct file *file)
- {
-- ENTER(TRACE_ON,"sq_open");
- DPRINTK("sq_open\n");
-
- if (((file->f_flags & O_ACCMODE) == O_WRONLY)
- || ((file->f_flags & O_ACCMODE) == O_RDWR)) {
--#if 0
-- MOD_INC_USE_COUNT;
-- while(audio_wr_refcount) {
-- SLEEP(open_queue, ONE_SECOND);
-- if (SIGNAL_RECEIVED) {
-- MOD_DEC_USE_COUNT;
-- LEAVE(TRACE_ON,"sq_open");
-- return -EINTR;
-- }
-- }
--#else
- if (audio_wr_refcount) {
- DPRINTK(" sq_open EBUSY\n");
-- LEAVE(TRACE_ON,"sq_open");
- return -EBUSY;
- }
- MOD_INC_USE_COUNT;
--#endif
- audio_wr_refcount++;
- } else {
- DPRINTK(" sq_open EINVAL\n");
-- LEAVE(TRACE_ON,"sq_open");
- return -EINVAL;
- }
-
-- if (audio_wr_refcount == 1) {
-- DPRINTK("cold\n");
--
-- audio_fragsize = AUDIO_FRAGSIZE_DEFAULT;
-- audio_nbfrags = AUDIO_NBFRAGS_DEFAULT;
-- sq_release_buffers(&output_stream);
-- sound.minDev = MINOR(inode->i_rdev) & 0x0f;
-- sound.soft = sound.dsp;
-- sound.hard = sound.dsp;
--
-- if ((MINOR(inode->i_rdev) & 0x0f) == SND_DEV_AUDIO) {
-- sound_set_speed(8000);
-- sound_set_stereo(0);
-- sound_set_format(AFMT_MU_LAW);
-- }
-- Collie_audio_power_on();
-- }
-
--#if 0
-- MOD_INC_USE_COUNT;
--#endif
-- LEAVE(TRACE_ON,"sq_open");
-- return 0;
-+ audio_fragsize = AUDIO_FRAGSIZE_DEFAULT;
-+ audio_nbfrags = AUDIO_NBFRAGS_DEFAULT;
-+ sq_release_buffers(&output_stream);
-+ output_stream.buf_idx=0;
-+ Collie_audio_power_on();
-+ return 0;
- }
-
- static int sq_fsync(struct file *filp, struct dentry *dentry)
-@@ -2543,11 +1206,9 @@
- audio_stream_t *s = &output_stream;
- audio_buf_t *b = s->buf;
-
-- ENTER(TRACE_ON,"sq_fsync");
- DPRINTK("sq_fsync\n");
-
- if (!s->buffers) {
-- LEAVE(TRACE_ON,"sq_fsync");
- return 0;
- }
-
-@@ -2557,12 +1218,10 @@
-
- #ifdef CONFIG_PM
- /* Auto Power off cancel */
-- autoPowerCancel = 0;
-+// autoPowerCancel = 0;
- #endif
-
-- ENTER(TRACE_SEM,"down sem");
- down(&b->sem);
-- LEAVE(TRACE_SEM,"down sem");
- sa1100_dma_queue_buffer(COLLIE_SOUND_DMA_CHANNEL,
- (void *) b, b->dma_addr, b->size);
- b->size = 0;
-@@ -2576,23 +1235,15 @@
- * - the buffer was already free thus nothing else to sync.
- */
- b = s->buffers + ((s->nbfrags + s->buf_idx - 1) % s->nbfrags);
-- ENTER(TRACE_SEM,"down-int sem");
- if (down_interruptible(&b->sem)) {
-- LEAVE(TRACE_SEM,"down-int sem");
-- LEAVE(TRACE_ON,"sq_fsync");
- return -EINTR;
- }
-- LEAVE(TRACE_SEM,"down-int sem");
-- ENTER(TRACE_SEM,"up sem");
- up(&b->sem);
-- LEAVE(TRACE_SEM,"up sem");
-- LEAVE(TRACE_ON,"sq_fsync");
- return 0;
- }
-
- static int sq_release(struct inode *inode, struct file *file)
- {
-- ENTER(TRACE_ON,"sq_release");
- DPRINTK("sq_release\n");
-
- switch (file->f_flags & O_ACCMODE) {
-@@ -2606,24 +1257,12 @@
- }
-
- if (!audio_wr_refcount) {
-- sound.soft = sound.dsp;
-- sound.hard = sound.dsp;
-- sound_silence();
-- Collie_OP_SHDN_off();
-+ sa1100_dma_stop(COLLIE_SOUND_DMA_CHANNEL);
-+ sa1100_dma_flush_all(COLLIE_SOUND_DMA_CHANNEL);
-+ Collie_audio_power_off();
- }
-
--#if 0
-- switch (file->f_flags & O_ACCMODE) {
-- case O_WRONLY:
-- case O_RDWR:
-- if (!audio_wr_refcount) {
-- WAKE_UP(open_queue);
-- }
-- }
--#endif
--
- MOD_DEC_USE_COUNT;
-- LEAVE(TRACE_ON,"sq_release");
- return 0;
- }
-
-@@ -2634,8 +1273,8 @@
- u_long fmt;
- int data;
- long val;
-+// audio_buf_info abinfo;
-
-- ENTER(TRACE_ON,"sq_ioctl");
- switch (cmd) {
- case SNDCTL_DSP_RESET:
- switch (file->f_flags & O_ACCMODE) {
-@@ -2643,11 +1282,9 @@
- case O_RDWR:
- sq_release_buffers(&output_stream);
- }
-- LEAVE(TRACE_ON,"sq_ioctl");
- return 0;
- case SNDCTL_DSP_POST:
- case SNDCTL_DSP_SYNC:
-- LEAVE(TRACE_ON,"sq_ioctl");
- return sq_fsync(file, file->f_dentry);
-
- /* ++TeSche: before changing any of these it's
-@@ -2656,59 +1293,34 @@
- case SNDCTL_DSP_SPEED:
- sq_fsync(file, file->f_dentry);
- IOCTL_IN(arg, data);
-- LEAVE(TRACE_ON,"sq_ioctl");
- return IOCTL_OUT(arg, sound_set_speed(data));
- case SNDCTL_DSP_STEREO:
- sq_fsync(file, file->f_dentry);
- IOCTL_IN(arg, data);
-- LEAVE(TRACE_ON,"sq_ioctl");
- return IOCTL_OUT(arg, sound_set_stereo(data));
-- case SOUND_PCM_WRITE_CHANNELS:
-+ case SNDCTL_DSP_CHANNELS:
- sq_fsync(file, file->f_dentry);
- IOCTL_IN(arg, data);
-- LEAVE(TRACE_ON,"sq_ioctl");
- return IOCTL_OUT(arg, sound_set_stereo(data-1)+1);
- case SNDCTL_DSP_SETFMT:
- sq_fsync(file, file->f_dentry);
- IOCTL_IN(arg, data);
-- LEAVE(TRACE_ON,"sq_ioctl");
-- return IOCTL_OUT(arg, sound_set_format(data));
-+ return IOCTL_OUT(arg, CollieSetFormat(data));
- case SNDCTL_DSP_GETFMTS:
-- fmt = 0;
-- if (sound.trans) {
-- if (sound.trans->ct_ulaw)
-- fmt |= AFMT_MU_LAW;
-- if (sound.trans->ct_alaw)
-- fmt |= AFMT_A_LAW;
-- if (sound.trans->ct_s8)
-- fmt |= AFMT_S8;
-- if (sound.trans->ct_u8)
-- fmt |= AFMT_U8;
-- if (sound.trans->ct_s16be)
-- fmt |= AFMT_S16_BE;
-- if (sound.trans->ct_u16be)
-- fmt |= AFMT_U16_BE;
-- if (sound.trans->ct_s16le)
-- fmt |= AFMT_S16_LE;
-- if (sound.trans->ct_u16le)
-- fmt |= AFMT_U16_LE;
-- }
-- LEAVE(TRACE_ON,"sq_ioctl");
-+ fmt = AFMT_S16_LE;
- return IOCTL_OUT(arg, fmt);
- case SNDCTL_DSP_GETBLKSIZE:
-- LEAVE(TRACE_ON,"sq_ioctl");
- return IOCTL_OUT(arg, audio_fragsize);
- case SNDCTL_DSP_SUBDIVIDE:
- break;
- case SNDCTL_DSP_SETFRAGMENT:
- if (output_stream.buffers) {
-- LEAVE(TRACE_ON,"sq_ioctl");
- return -EBUSY;
- }
- get_user(val, (long *) arg);
- audio_fragsize = 1 << (val & 0xFFFF);
-- if (audio_fragsize < 16)
-- audio_fragsize = 16;
-+ if (audio_fragsize < 256)
-+ audio_fragsize = 256;
- if (audio_fragsize > 16384)
- audio_fragsize = 16384;
- audio_nbfrags = (val >> 16) & 0x7FFF;
-@@ -2717,46 +1329,54 @@
- if (audio_nbfrags * audio_fragsize > 128 * 1024)
- audio_nbfrags = 128 * 1024 / audio_fragsize;
- if (sq_allocate_buffers(&output_stream)) {
-- LEAVE(TRACE_ON,"sq_ioctl");
- return -ENOMEM;
- }
-- LEAVE(TRACE_ON,"sq_ioctl");
- return 0;
-
--#if 1 // 2003.2.14
-+/* case SNDCTL_DSP_GETOSPACE:
-+ abinfo.fragsize = audio_fragsize;
-+ abinfo.fragstotal = audio_nbfrags;
-+ abinfo.fragments = lastsent-output_stream.buf_idx;
-+ if (abinfo.fragments<0)
-+ abinfo.fragments += abinfo.fragstotal;
-+ abinfo.bytes = abinfo.fragments*abinfo.fragsize;
-+ return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-+*/
- case SNDCTL_DSP_GETOSPACE:
- {
-- audio_buf_info inf = { 0, };
-+ audio_stream_t *s = &output_stream;
-+ audio_buf_info *inf = (audio_buf_info *) arg;
-+ int err = verify_area(VERIFY_WRITE, inf, sizeof(*inf));
- int i;
-+ int frags = 0, bytes = 0;
-
-- if (!(file->f_mode & FMODE_WRITE))
-- return -EINVAL;
-- if (!output_stream.buffers && sq_allocate_buffers(&output_stream))
-- return -ENOMEM;
-- for (i = 0; i < output_stream.nbfrags; i++) {
-- if (atomic_read(&output_stream.buffers[i].sem.count) > 0) {
-- if (output_stream.buffers[i].size == 0)
-- inf.fragments++;
-- inf.bytes += output_stream.fragsize - output_stream.buffers[i].size;
-- }
-+ if (err)
-+ return err;
-+ if (output_stream.buffers) {
-+ for (i = 0; i < s->nbfrags; i++) {
-+ if (atomic_read(&s->buffers[i].sem.count) > 0) {
-+ if (s->buffers[i].size == 0) frags++;
-+ bytes += s->fragsize - s->buffers[i].size;
-+ }
-+ }
-+ put_user(s->nbfrags, &inf->fragstotal);
-+ put_user(s->fragsize, &inf->fragsize);
-+ } else {
-+ frags=audio_nbfrags;
-+ bytes=frags*audio_fragsize;
-+ put_user(frags, &inf->fragstotal);
-+ put_user(audio_fragsize, &inf->fragsize);
- }
-- inf.fragstotal = output_stream.nbfrags;
-- inf.fragsize = output_stream.fragsize;
-- return copy_to_user((void *)arg, &inf, sizeof(inf));
-+ put_user(frags, &inf->fragments);
-+ return put_user(bytes, &inf->bytes);
- }
--#endif
--
-
- default:
-- LEAVE(TRACE_ON,"sq_ioctl");
- return mixer_ioctl(inode, file, cmd, arg);
- }
-- LEAVE(TRACE_ON,"sq_ioctl");
- return -EINVAL;
- }
-
--
--
- static struct file_operations sq_fops =
- {
- llseek: sound_lseek,
-@@ -2770,40 +1390,18 @@
-
- static void __init sq_init(void)
- {
--#ifndef MODULE
-- int sq_unit;
--#endif
-- ENTER(TRACE_ON,"sq_init");
- sq_unit = register_sound_dsp(&sq_fops, -1);
- if (sq_unit < 0) {
-- LEAVE(TRACE_ON,"sq_init");
- return;
- }
-
-- /* whatever you like as startup mode for /dev/dsp,
-- * (/dev/audio hasn't got a startup mode). note that
-- * once changed a new open() will *not* restore these!
-- */
-- sound.dsp.format = AFMT_S16_LE;
--
-- sound.dsp.stereo = 0;
-- sound.dsp.size = 16;
--
-- /* set minimum rate possible without expanding */
-- switch (sound.mach.type) {
-- case DMASND_COLLIE:
-- sound.dsp.speed = 8000;
-- break;
-- }
--
-- /* before the first open to /dev/dsp this wouldn't be set */
-- sound.soft = sound.dsp;
-- sound.hard = sound.dsp;
-- sound.trans = &transCollie;
--
-- CollieSetFormat(sound.dsp.format);
-- sound_silence();
-- LEAVE(TRACE_ON,"sq_init");
-+ sound.format = AFMT_S16_LE;
-+ sound.stereo = 1;
-+ sound.speed = 44100;
-+
-+ CollieSetFormat(AFMT_S16_LE);
-+ Collie_audio_power_off();
-+ output_stream.buf=output_stream.buffers=NULL;
- }
-
- /*
-@@ -2816,9 +1414,7 @@
- char *buffer = state.buf;
- int len = 0;
-
-- ENTER(TRACE_ON,"state_open");
- if (state.busy) {
-- LEAVE(TRACE_ON,"state_open");
- return -EBUSY;
- }
-
-@@ -2828,8 +1424,8 @@
-
- len += sprintf(buffer+len, " COLLIE DMA sound driver:\n");
-
-- len += sprintf(buffer+len, "\tsound.format = 0x%x", sound.soft.format);
-- switch (sound.soft.format) {
-+ len += sprintf(buffer+len, "\tsound.format = 0x%x", sound.format);
-+ switch (sound.format) {
- case AFMT_MU_LAW:
- len += sprintf(buffer+len, " (mu-law)");
- break;
-@@ -2857,22 +1453,19 @@
- }
- len += sprintf(buffer+len, "\n");
- len += sprintf(buffer+len, "\tsound.speed = %dHz (phys. %dHz)\n",
-- sound.soft.speed, sound.hard.speed);
-+ sound.speed, sound.speed);
- len += sprintf(buffer+len, "\tsound.stereo = 0x%x (%s)\n",
-- sound.soft.stereo,
-- sound.soft.stereo ? "stereo" : "mono");
-+ sound.stereo,
-+ sound.stereo ? "stereo" : "mono");
- state.len = len;
-- LEAVE(TRACE_ON,"state_open");
- return 0;
- }
-
-
- static int state_release(struct inode *inode, struct file *file)
- {
-- ENTER(TRACE_ON,"state_release");
- state.busy = 0;
- MOD_DEC_USE_COUNT;
-- LEAVE(TRACE_ON,"state_release");
- return 0;
- }
-
-@@ -2881,19 +1474,15 @@
- loff_t *ppos)
- {
- int n = state.len - state.ptr;
-- ENTER(TRACE_ON,"state_read");
- if (n > count)
- n = count;
- if (n <= 0) {
-- LEAVE(TRACE_ON,"state_read");
- return 0;
- }
- if (copy_to_user(buf, &state.buf[state.ptr], n)) {
-- LEAVE(TRACE_ON,"state_read");
- return -EFAULT;
- }
- state.ptr += n;
-- LEAVE(TRACE_ON,"state_read");
- return n;
- }
-
-@@ -2909,20 +1498,11 @@
-
- static void __init state_init(void)
- {
--#ifndef MODULE
-- int state_unit;
--#endif
-- ENTER(TRACE_ON,"state_unit");
- state_unit = register_sound_special(&state_fops, SND_DEV_STATUS);
- if (state_unit < 0) {
-- LEAVE(TRACE_ON,"state_unit");
- return;
- }
- state.busy = 0;
--
-- // printk("state_init : ret \n");
-- LEAVE(TRACE_ON,"state_unit");
--
- }
-
-
-@@ -2930,8 +1510,6 @@
-
- static long long sound_lseek(struct file *file, long long offset, int orig)
- {
-- ENTER(TRACE_ON,"sound_lseek");
-- LEAVE(TRACE_ON,"sound_lseek");
- return -ESPIPE;
- }
-
-@@ -2941,96 +1519,41 @@
- static int collie_sound_pm_callback(struct pm_dev *pm_dev,
- pm_request_t req, void *data)
- {
-- ENTER(TRACE_PM,"collie_sound_pm_callback");
- switch (req) {
- case PM_SUSPEND:
- #ifdef COLLIE_TRY_ONE
- disable_irq(IRQ_GPIO_nREMOCON_INT);
- #endif
--#ifdef TRY_DELAY_OFF /* H.Hayami SHARP 2001.12.19 */
-- collieDoDelayedSilence();
-- collieCancelDelayedSilence();
--#endif
-- if (audio_wr_refcount == 1) {
-- Collie_volume_off();
-- Collie_hard_mute_on();
-- Collie_soft_mute_on();
-- sa1100_dma_sleep((dmach_t)COLLIE_SOUND_DMA_CHANNEL);
--
--#if 0 /* H.Hayami SHARP 2001.12.18 */
--#if !defined(CONFIG_COLLIE_TS) && !defined(CONFIG_COLLIE_TR0) && \
-- !defined(CONFIG_COLLIE_TR1) && !defined(CONFIG_COLLIE_DEV)
-- Collie_volume_off();
--#endif
--#endif
-- Collie_OP_SHDN_off();
-- Collie_soft_DAC_off();
-- Collie_paif_off();
-- Collie_audio_clock_off();
-- //Collie_MIC_on();
-- Collie_DAC_off();
-- Collie_AMP_off();
-- } else {
-- sa1100_dma_sleep((dmach_t)COLLIE_SOUND_DMA_CHANNEL);
-- }
-- Collie_sound_hard_term();
-+ sa1100_dma_sleep((dmach_t)COLLIE_SOUND_DMA_CHANNEL);
-+ Collie_audio_power_off();
- break;
- case PM_RESUME:
--/***** DEBUG *****g
--printk("collie_sound_pm_callback: audio_wr_refcount=%d\n", audio_wr_refcount);
--*****************/
-+
- #ifdef COLLIE_TRY_ONE
- enable_irq(IRQ_GPIO_nREMOCON_INT);
- #endif
--
-- Collie_sound_hard_init();
--
-- if (audio_wr_refcount == 1) {
-- collie_resume = 1;
--
-- Collie_audio_power_on();
--
-- sa1100_dma_wakeup((dmach_t)COLLIE_SOUND_DMA_CHANNEL);
--#if 0 /* H.Hayami SHARP 2001.12.18 */
-- Collie_soft_mute_off();
-- Collie_hard_mute_off();
--#endif
-- } else {
-+ Collie_sound_hard_init(); /* this needs to be done! */
-+ collie_resume = 1;
-+ Collie_audio_power_off();
-+ if (audio_wr_refcount) Collie_audio_power_on();
-+ if (collie_recording) Collie_recording_on();
-+ sa1100_dma_wakeup((dmach_t)COLLIE_SOUND_DMA_CHANNEL);
- #ifdef COLLIE_TRY_ONE
-- if ( !( GPLR & GPIO_nREMOCON_INT ) )
-+ if ( !( GPLR & GPIO_nREMOCON_INT ) )
- Collie_DAC_on();
- #endif
-- sa1100_dma_wakeup((dmach_t)COLLIE_SOUND_DMA_CHANNEL);
-- }
--
--
- break;
--
- }
-- LEAVE(TRACE_PM,"collie_sound_pm_callback");
- return 0;
- }
- #endif
-
-
- #ifdef COLLIE_TRY_ONE
--
--static void collie_audio_on(void)
--{
-- while(1) {
-- sleep_on(&audio_on);
--
-- /* DAC ON */
-- Collie_DAC_on();
-- // printk("call audio on \n");
--
-- }
--}
--
- void Collie_rc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
- {
-- // printk("int !\n");
-- wake_up(&audio_on);
-+ headphone=!headphone;
-+ printk("%s headphone \n",headphone ? "connected" : "disconnected");
- }
- #endif
-
-@@ -3038,113 +1561,85 @@
-
- int __init Collie_sound_init(void)
- {
-- int has_sound = 0;
--
--
-- ENTER(TRACE_ON,"Collie_sound_init");
-- has_sound = 1;
-- sound.mach = machCollie;
--
-- if (!has_sound) {
-- LEAVE(TRACE_ON,"Collie_sound_init");
-- return -1;
-- }
--
--#ifdef TRY_DELAY_OFF /* H.Hayami SHARP 2001.12.19 */
-- sema_init(&df_sem, 1);
-- kernel_thread(collieDelayedSilence, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
--#endif
--
- Collie_sound_hard_init();
--
-- if (!sound.mach.irqinit()) {
-+ if (!CollieIrqInit()) {
- printk("Sound driver: Interrupt initialization failed\n");
-- LEAVE(TRACE_ON,"Collie_sound_init");
- return -1;
- }
--
-- /* Set up sound queue, /dev/audio and /dev/dsp. */
--
- /* Set default settings. */
- sq_init();
--
- /* Set up /dev/sndstat. */
- state_init();
--
- /* Set up /dev/mixer. */
- mixer_init();
--
- #ifdef MODULE
- irq_installed = 1;
- #endif
--
- printk("Collie Sound Driver Installed\n");
--
- #ifdef CONFIG_PM
- collie_sound_pm_dev = pm_register(PM_SYS_DEV, 0,
- collie_sound_pm_callback);
- #endif
--
--
- #ifdef COLLIE_TRY_ONE
- /* enable int sw */
- collie_rc_set_int_mode();
--
- /* GPIO15(int):IN, GPIO18(sw):OUT */
- GPDR = ((GPDR)&~GPIO_nREMOCON_INT)|GPIO_REMOCON_ADC_SW;
--
- /* GPIO15,18:not Alternate */
- GAFR &= ~(GPIO_nREMOCON_INT|GPIO_REMOCON_ADC_SW);
--
-+ /* Initialize headphone state */
-+ headphone=!(GPLR & GPIO_nREMOCON_INT);
- /* GPIO15:Falling Edge */
-- set_GPIO_IRQ_edge(GPIO_nREMOCON_INT, GPIO_FALLING_EDGE);
--
-+ set_GPIO_IRQ_edge(GPIO_nREMOCON_INT, GPIO_BOTH_EDGES);
- /* Register interrupt handler */
- if ( request_irq(IRQ_GPIO_nREMOCON_INT, Collie_rc_interrupt,
-- SA_INTERRUPT, "INSERT-HEADPHONE", Collie_rc_interrupt)) {
-- printk("%s: request_irq(%d) failed.\n",
-- __FUNCTION__, IRQ_GPIO_nREMOCON_INT);
-- }
-+ SA_INTERRUPT, "headphone", 0)) {
-+ printk("headphone: request_irq failed.\n");
-
-- /* Make threads */
-- kernel_thread(collie_audio_on, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
-+ }
-+ printk("Requested irq collie_rc succesfully (headphone) \n");
-+ printk("Headphone is now %s\n",headphone ? "connected" : "disconnected");
- #endif
-
--
-- LEAVE(TRACE_ON,"Collie_sound_init");
-+ Collie_audio_power_on(); // decreasing rec. noise?
-+ Collie_audio_power_off();
- return 0;
- }
-
--module_init(Collie_sound_init);
--
--
- #ifdef MODULE
--
--int init_module(void)
-+static int collie_ssp_init_module(void)
- {
-- ENTER(TRACE_ON,"init_module");
- Collie_sound_init();
-- LEAVE(TRACE_ON,"init_module");
- return 0;
- }
-
--void cleanup_module(void)
-+static void collie_ssp_cleanup_module(void)
- {
-- ENTER(TRACE_ON,"cleanup_module");
-+#ifdef CONFIG_PM
-+ pm_unregister(collie_sound_pm_dev);
-+#endif
- if (irq_installed) {
-- sound_silence();
-- sound.mach.irqcleanup();
-+ sa1100_dma_stop(COLLIE_SOUND_DMA_CHANNEL);
-+ sa1100_dma_flush_all(COLLIE_SOUND_DMA_CHANNEL);
-+ Collie_audio_power_off();
-+ sa1100_free_dma(COLLIE_SOUND_DMA_CHANNEL);
- }
--
-- sq_release_buffers();
--
-- if (mixer_unit >= 0)
-- unregister_sound_mixer(mixer_unit);
-- if (state_unit >= 0)
-- unregister_sound_special(state_unit);
-- if (sq_unit >= 0)
-- unregister_sound_dsp(sq_unit);
-- LEAVE(TRACE_ON,"cleanup_module");
--}
--
-+#ifdef COLLIE_TRY_ONE
-+ free_irq(IRQ_GPIO_nREMOCON_INT,0);
-+#endif
-+ unregister_sound_mixer(mixer_unit);
-+ unregister_sound_special(state_unit);
-+ unregister_sound_dsp(sq_unit);
-+ printk("collie_ssp has to go now, see you later!\n");
-+}
-+
-+module_init(collie_ssp_init_module);
-+module_exit(collie_ssp_cleanup_module);
-+MODULE_DESCRIPTION("Collie 16bit sound driver");
-+MODULE_AUTHOR("SHARP");
-+MODULE_LICENSE("GPL");
-+EXPORT_SYMBOL(Collie_recording_off);
-+EXPORT_SYMBOL(Collie_recording_on);
-+EXPORT_SYMBOL(collie_recording);
- #endif /* MODULE */
-+
-diff -Nuar linux-2.4.18/drivers/sound/collie_tc35143af.c linux-2.4.18p/drivers/sound/collie_tc35143af.c
---- linux-2.4.18/drivers/sound/collie_tc35143af.c 1970-01-01 01:00:00.000000000 +0100
-+++ linux-2.4.18p/drivers/sound/collie_tc35143af.c 2004-10-13 15:26:20.336631864 +0200
-@@ -0,0 +1,1457 @@
-+/*
-+ TODO
-+
-+ buzzer compatibility is not fool proof - if an app starts sending buzzer ioctls
-+ and then write or read, nothing good will happen / but this api is obsolote anyway
-+
-+ mixer_ioctls missing: write/read_mic/igain (there are sane defaults for those)
-+
-+ fixed samplerate at 22050hz (mono,s16_le), although it can be changed
-+ between 8000-22050hz hardwarewise
-+
-+
-+ DONE
-+
-+ buffers are only allocated once, and freed when module is unloaded
-+ mute left channel when duplex playing & recording
-+ cleanup
-+ depend on collie_ssp, and call needed functions when needed
-+ (recording noise should be gone too as a consequence)
-+ lineo's getospace incorporated (getispace left alone)
-+ "optimized" default fragsize and number, so there is now no clicking all the time
-+ commented out scndctl_dsp_setfragment so that no application can set bad settings (eg.xmms)
-+ if you start reading from this device, than it won't let you write later unless you close it first
-+ (and vica-versa)
-+ speaker is muted if nothing is playing, so noise is gone
-+
-+*/
-+
-+#include <linux/module.h>
-+#include <linux/sched.h>
-+#include <linux/timer.h>
-+#include <linux/poll.h>
-+#include <linux/major.h>
-+#include <linux/config.h>
-+#include <linux/fcntl.h>
-+#include <linux/errno.h>
-+#include <linux/mm.h>
-+#include <linux/slab.h>
-+#include <linux/sound.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+
-+#include <linux/pm.h>
-+
-+#include <asm/system.h>
-+#include <asm/irq.h>
-+#include <asm/pgtable.h>
-+#include <asm/uaccess.h>
-+#include <asm/io.h>
-+#include <asm/dma.h>
-+
-+#include <asm/ucb1200.h>
-+#include <linux/soundcard.h>
-+#include <asm/proc/cache.h>
-+
-+#include <asm/arch/hardware.h>
-+#include <asm/arch/tc35143.h>
-+
-+#undef DEBUG
-+#ifdef DEBUG
-+#define DPRINTK( x... ) printk( ##x )
-+#else
-+#define DPRINTK( x... )
-+#endif
-+
-+extern int collie_recording;
-+extern void Collie_recording_on(void);
-+extern void Collie_recording_off(void);
-+
-+int collie_tc35143f_irq = -1;
-+int collie_tc35143f_input_irq = -1;
-+
-+#define COLLIE_BUZZER_DMA_CHANNEL (collie_tc35143f_irq)
-+#define COLLIE_BUZZER_DMA_CHANNEL_INPUT (collie_tc35143f_input_irq)
-+#define COLLIE_GPIO_MIC GPIO_GPIO (17)
-+
-+#define SND_NDEVS 256 /* Number of supported devices */
-+#define SND_DEV_CTL 0 /* Control port /dev/mixer */
-+#define SND_DEV_SEQ 1 /* Sequencer output /dev/sequencer (FM synthesizer and MIDI output) */
-+#define SND_DEV_MIDIN 2 /* Raw midi access */
-+#define SND_DEV_DSP 3 /* Digitized voice /dev/dsp */
-+#define SND_DEV_AUDIO 4 /* Sparc compatible /dev/audio */
-+#define SND_DEV_DSP16 5 /* Like /dev/dsp but 16 bits/sample */
-+#define SND_DEV_STATUS 6 /* /dev/sndstat */
-+/* #7 not in use now. Was in 2.4. Free for use after v3.0. */
-+#define SND_DEV_SEQ2 8 /* /dev/sequencer, level 2 interface */
-+#define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */
-+#define SND_DEV_PSS SND_DEV_SNDPROC
-+
-+#ifdef MODULE
-+static int sq_unit = -1;
-+static int mixer_unit = -1;
-+static int state_unit = -1;
-+static int irq_installed = 0;
-+#endif /* MODULE */
-+
-+#ifdef CONFIG_PM
-+static struct pm_dev* collie_sound_pm_dev;
-+#endif
-+
-+/*** Some declarations ***********************************************/
-+static int collie_buzzer_volume = 100;
-+static int audio_igain = 0;
-+static int audio_iamp = 0x05;
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
-+static struct ucb1x00 * ucbstruct;
-+#endif
-+static int TC35143f_control_reg_a;
-+static int TC35143f_control_reg_b;
-+static int TC35143f_mode;
-+
-+#define AUDIO_NBFRAGS_DEFAULT 32
-+#define AUDIO_FRAGSIZE_DEFAULT 2048
-+
-+typedef struct {
-+ int size; /* buffer size */
-+ char *start; /* points to actual buffer */
-+ dma_addr_t dma_addr; /* physical buffer address */
-+ struct semaphore sem; /* down before touching the buffer */
-+ int master; /* master owner for buffer allocation */
-+ u_int idx; /* buffer index, so that we know which buffer was sent last*/
-+} audio_buf_t;
-+
-+typedef struct {
-+ audio_buf_t *buffers; /* pointer to audio buffer structures */
-+ audio_buf_t *buf; /* current buffer used by read/write */
-+ u_int buf_idx; /* index for the pointer above... */
-+ u_int fragsize; /* fragment i.e. buffer size */
-+ u_int nbfrags; /* nbr of fragments i.e. buffers */
-+} audio_stream_t;
-+
-+static audio_stream_t output_stream, input_stream;
-+
-+#define NEXT_BUF(_s_,_b_) { \
-+ (_s_)->_b_##_idx++; \
-+ (_s_)->_b_##_idx %= (_s_)->nbfrags; \
-+ (_s_)->_b_ = (_s_)->buffers + (_s_)->_b_##_idx; }
-+
-+/* Current specs for incoming audio data */
-+static u_int audio_fragsize=AUDIO_FRAGSIZE_DEFAULT;
-+static u_int audio_nbfrags=AUDIO_NBFRAGS_DEFAULT;
-+
-+static volatile int audio_refcount; /* nbr of concurrent open() for playback */
-+typedef enum { REC,PLAY,NA,BUZZ } collie_tc_status_t;
-+static collie_tc_status_t collie_tc_status;
-+int collie_tc_muted;
-+
-+#define IOCTL_IN(arg, ret) \
-+ do { int error = get_user(ret, (int *)(arg)); \
-+ if (error) return error; \
-+ } while (0)
-+#define IOCTL_OUT(arg, ret) ioctl_return((int *)(arg), ret)
-+
-+/*** "Translations" ************************************************************/
-+
-+static ssize_t collie_ct_s16(const u_char *userPtr, size_t userCount,
-+ u_char frame[], ssize_t *frameUsed,
-+ ssize_t frameLeft);
-+static signed short ct_out=0;
-+/*** Low level stuff *********************************************************/
-+
-+
-+typedef struct {
-+ int format; /* AFMT_* */
-+ int stereo; /* 0 = mono, 1 = stereo */
-+ int size; /* 8/16 bit*/
-+ int speed; /* speed */
-+ int volume;
-+} SETTINGS;
-+
-+static SETTINGS sound;
-+
-+#ifdef CONFIG_PM
-+//extern int autoPowerCancel;
-+#endif
-+
-+static void Collie_Set_Volume(int volume);
-+static int Collie_Get_Volume(void);
-+static int CollieIrqInit(void);
-+static int CollieSetFormat(int format);
-+static void Collie_sq_interrupt(void*, int);
-+static int sq_allocate_buffers(audio_stream_t*);
-+static void sq_release_buffers(audio_stream_t*);
-+
-+/*** Mid level stuff *********************************************************/
-+static int sound_set_speed(int speed);
-+
-+/*
-+ * /dev/mixer abstraction
-+ */
-+
-+struct sound_mixer {
-+ int busy;
-+};
-+
-+static struct sound_mixer mixer;
-+
-+/*
-+ * /dev/sndstat
-+ */
-+
-+/*** Common stuff ********************************************************/
-+
-+static long long sound_lseek(struct file *file, long long offset, int orig);
-+static inline int ioctl_return(int *addr, int value)
-+{
-+ if (value < 0) {
-+ return(value);
-+ }
-+ return put_user(value, addr)? -EFAULT: 0;
-+}
-+
-+static void wait_ms(int ten_ms)
-+{
-+ schedule_timeout(ten_ms);
-+}
-+
-+/*** Translation ************************************************************/
-+
-+static ssize_t collie_ct_s16(const u_char *userPtr, size_t userCount,
-+ u_char frame[], ssize_t *frameUsed,
-+ ssize_t frameLeft)
-+{
-+ ssize_t count, used;
-+ signed short *fp = (unsigned short *) &frame[*frameUsed];
-+ signed short *up = (unsigned short *) userPtr;
-+
-+ frameLeft >>= 1;
-+ userCount >>= 1;
-+ used = count = (userCount < frameLeft) ? userCount : frameLeft;
-+
-+ while (count > 0) {
-+ signed short data;
-+ if (get_user(data, up++)) {
-+ return -EFAULT;
-+ } /* lowpass filtering, not that it matters much - something is resonating inside the Zaurus at high frequencies ? */
-+ *fp++ = ct_out = (short)( ( (long)data + (long)ct_out ) >> 1LL );
-+ count--;
-+ }
-+
-+ *frameUsed += used * 2;
-+ return used * 2;
-+}
-+
-+/*** HARDWARE dependent stuff *********************************************************/
-+#define VOL_THRES 10
-+#define CODEC_ASD_NUMERATOR 13
-+/*~ (9216000 / ( 32 * 22050 )) */
-+
-+static int Collie_Sampling_value(void)
-+{
-+ int asd = CODEC_ASD_NUMERATOR;
-+ DPRINTK("Collie_Sampling_value %x\n",asd);
-+ return asd;
-+}
-+
-+static void Collie_sound_hard_init(void)
-+{
-+ int asd;
-+
-+ DPRINTK("CollieInit\n");
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
-+ ucb1x00_enable(ucbstruct);
-+ ucb1x00_io_set_dir(ucbstruct,0, TC35143_GPIO_BUZZER_BIAS);
-+ ucb1x00_disable(ucbstruct);
-+#else
-+ ucb1200_set_io_direction(TC35143_GPIO_BUZZER_BIAS, TC35143_IODIR_OUTPUT);
-+#endif
-+
-+ DPRINTK("TC35143F Init");
-+
-+ // init MCP
-+ asd = Collie_Sampling_value();
-+ Ser4MCCR0 &= ~MCCR0_MCE;
-+ Ser4MCCR0 &= ~0xff;
-+ Ser4MCCR0 |= (MCCR0_ARE | MCCR0_ATE |MCCR0_ADM | MCCR0_ECS | asd);
-+ Ser4MCCR0 |= MCCR0_MCE;
-+ Ser4MCSR = 0xffffffff;
-+
-+ DPRINTK("Init MCP %x\n",Ser4MCCR0);
-+}
-+
-+static void Collie_audio_power_on(void)
-+{
-+ if ( collie_buzzer_volume > 100 ) collie_buzzer_volume = 100;
-+ if ( collie_buzzer_volume < 0 ) collie_buzzer_volume = 0;
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
-+ ucb1x00_enable(ucbstruct);
-+#endif
-+ TC35143f_control_reg_a = ( TC35143_VDIV_22KHZ );
-+ TC35143f_control_reg_b = ( TC35143_VADMUTE | TC35143_VHSMUTE | ( 7 - collie_buzzer_volume / 13));
-+ TC35143f_mode = ( TC35143_VOFFCAN | TC35143_VCOF_22_OR_16KHZ );
-+ TC35143f_control_reg_a &= ~(TC35143_VINSEL_MASK | TC35143_VGAIN_MASK | TC35143_VAMP_MASK);
-+ TC35143f_control_reg_a |= (TC35143_VINSEL_VBIN2 | ((audio_igain & 0x3)<<11) | ((audio_iamp & 0x0f)<<7));
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
-+ ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_B , TC35143f_control_reg_b);
-+ ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_A , TC35143f_control_reg_a);
-+ ucb1x00_reg_write(ucbstruct,TC35143_MODE_REG , TC35143f_mode );
-+ ucb1x00_io_write(ucbstruct, TC35143_GPIO_BUZZER_BIAS,0);
-+ ucb1x00_disable(ucbstruct);
-+#else
-+ ucb1200_write_reg(TC35143_CONTROL_REG_B , TC35143f_control_reg_b );
-+ ucb1200_write_reg(TC35143_MODE_REG , TC35143f_mode );
-+ ucb1200_write_reg(TC35143_CONTROL_REG_A , TC35143f_control_reg_a );
-+ ucb1200_set_io(TC35143_GPIO_BUZZER_BIAS, TC35143_IODAT_HIGH);
-+#endif
-+ collie_tc_muted=1;
-+}
-+
-+static void Collie_audio_power_off(void){ /* Disable sound only */
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
-+ ucb1x00_enable(ucbstruct);
-+ ucb1x00_io_write(ucbstruct,0, TC35143_GPIO_BUZZER_BIAS);
-+#else
-+ ucb1200_set_io(TC35143_GPIO_BUZZER_BIAS, TC35143_IODAT_LOW);
-+#endif
-+
-+ TC35143f_control_reg_a = ( TC35143_VDIV_22KHZ );
-+ TC35143f_control_reg_b = ( TC35143_ALL_MUTE );
-+
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
-+ ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_B , TC35143f_control_reg_b);
-+ ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_A , TC35143f_control_reg_a);
-+ ucb1x00_disable(ucbstruct);
-+#else
-+ ucb1200_write_reg(TC35143_CONTROL_REG_B , TC35143f_control_reg_b );
-+ ucb1200_write_reg(TC35143_CONTROL_REG_A , TC35143f_control_reg_a );
-+#endif
-+}
-+
-+static void collie_tc_mute_on(void){
-+ unsigned int reg_b;
-+ unsigned int reg_a;
-+
-+ if (!collie_tc_muted) {
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
-+ ucb1x00_enable(ucbstruct);
-+ reg_b = ucb1x00_reg_read(ucbstruct,TC35143_CONTROL_REG_B);
-+ reg_a = ucb1x00_reg_read(ucbstruct,TC35143_CONTROL_REG_A);
-+#else
-+ reg_b = ucb1200_read_reg(TC35143_CONTROL_REG_B);
-+ reg_a = ucb1200_read_reg(TC35143_CONTROL_REG_A);
-+#endif
-+ reg_b &= ~TC35143_VOUT1_EN;
-+ reg_a &= ~TC35143_VOUT2_EN;
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
-+ ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_A, reg_a);
-+ ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_B, reg_b);
-+ ucb1x00_disable(ucbstruct);
-+#else
-+ ucb1200_write_reg(TC35143_CONTROL_REG_A, reg_a);
-+ ucb1200_write_reg(TC35143_CONTROL_REG_B, reg_b);
-+#endif
-+ collie_tc_muted=1;
-+ }
-+}
-+
-+static void collie_tc_mute_off(void){
-+ unsigned int reg_b;
-+ unsigned int reg_a;
-+
-+ if (collie_tc_muted) {
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
-+ ucb1x00_enable(ucbstruct);
-+ reg_b = ucb1x00_reg_read(ucbstruct,TC35143_CONTROL_REG_B);
-+ reg_a = ucb1x00_reg_read(ucbstruct,TC35143_CONTROL_REG_A);
-+#else
-+ reg_b = ucb1200_read_reg(TC35143_CONTROL_REG_B);
-+ reg_a = ucb1200_read_reg(TC35143_CONTROL_REG_A);
-+#endif
-+ reg_b |= TC35143_VOUT1_EN ;
-+ reg_b &= ~7;
-+ reg_b |= ( 7 - collie_buzzer_volume / 13);
-+ reg_a |= TC35143_VOUT2_EN;
-+ reg_a &= ~(TC35143_VGAIN_MASK | TC35143_VAMP_MASK);
-+ reg_a |= (((audio_igain & 0x3)<<11) | ((audio_iamp & 0x0f)<<7));
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
-+ ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_A, reg_a);
-+ ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_B, reg_b);
-+ ucb1x00_disable(ucbstruct);
-+#else
-+ ucb1200_write_reg(TC35143_CONTROL_REG_A, reg_a);
-+ ucb1200_write_reg(TC35143_CONTROL_REG_B, reg_b);
-+#endif
-+ collie_tc_muted=0;
-+ }
-+}
-+
-+
-+static void Collie_volume_set(int dest)
-+{
-+ if (collie_buzzer_volume==dest) return;
-+ collie_buzzer_volume=dest;
-+ collie_tc_mute_on();
-+ collie_tc_mute_off();
-+}
-+
-+
-+/*********** GENERAL stuff, same as collie_ssp *******************************/
-+
-+
-+static void Collie_Set_Volume(int volume)
-+{
-+ sound.volume = volume & 0xff;
-+ sound.volume += ( volume & 0xff00 >> 8);
-+ sound.volume >>=1;
-+ if (sound.volume>100) sound.volume=100;
-+}
-+
-+static int Collie_Get_Volume(void)
-+{
-+ return ( sound.volume << 8 | sound.volume );
-+}
-+
-+static void Collie_sq_interrupt(void* id, int size)
-+{
-+ audio_buf_t *b = (audio_buf_t *) id;
-+ audio_buf_t *b2 = output_stream.buffers + ((b->idx + 1) % output_stream.nbfrags);
-+
-+ /* If this is the last buffer for know, let's mute the speaker */
-+ if (!down_trylock(&b2->sem)) {
-+ collie_tc_mute_on();
-+ up(&b2->sem);
-+ }
-+
-+ /*
-+ * Current buffer is sent: wake up any process waiting for it.
-+ */
-+ up(&b->sem);
-+ /* And any process polling on write. */
-+ wake_up_interruptible(&b->sem.wait);
-+
-+ DPRINTK("Collie_sq_interrupt \n");
-+}
-+
-+static void Collie_sq_input_interrupt(void* id, int size)
-+{
-+ audio_buf_t *b = (audio_buf_t *) id;
-+ /*
-+ * Current buffer is sent: wake up any process waiting for it.
-+ */
-+ b->size = size;
-+ up(&b->sem);
-+ /* And any process polling on write. */
-+ wake_up_interruptible(&b->sem.wait);
-+ /* And indicate which was the last buffer sent */
-+
-+ DPRINTK("Collie_sq_input_interrupt \n");
-+}
-+
-+
-+static int __init CollieIrqInit(void)
-+{
-+ int err;
-+
-+ err = sa1100_request_dma(&COLLIE_BUZZER_DMA_CHANNEL, "buzzer output",
-+ DMA_Ser4MCP0Wr);
-+
-+ if (err) {
-+ return 0;
-+ }
-+ printk("collie_tc35143f_irq=%d\n", collie_tc35143f_irq);
-+
-+ err = sa1100_request_dma(&COLLIE_BUZZER_DMA_CHANNEL_INPUT, "buzzer input",
-+ DMA_Ser4MCP0Rd);
-+
-+ if (err) {
-+ return 0;
-+ }
-+ printk("collie_tc35143f_input_irq=%d\n", collie_tc35143f_input_irq);
-+
-+
-+ sa1100_dma_set_callback(COLLIE_BUZZER_DMA_CHANNEL,
-+ (dma_callback_t)Collie_sq_interrupt);
-+
-+ sa1100_dma_set_callback(COLLIE_BUZZER_DMA_CHANNEL_INPUT,
-+ (dma_callback_t)Collie_sq_input_interrupt);
-+
-+
-+ sa1100_dma_stop(COLLIE_BUZZER_DMA_CHANNEL);
-+ Collie_audio_power_off();
-+ sa1100_dma_stop(COLLIE_BUZZER_DMA_CHANNEL_INPUT);
-+ sa1100_dma_flush_all(COLLIE_BUZZER_DMA_CHANNEL);
-+ return(1);
-+}
-+
-+static int CollieSetFormat(int format)
-+{
-+ int size;
-+
-+ switch (format) {
-+ case AFMT_QUERY:
-+ return(sound.format);
-+ default: /* This is the only one supported by the hardware it seems */
-+ size = 16;
-+ format = AFMT_S16_LE;
-+ }
-+ sound.format = format;
-+ sound.size = size;
-+
-+ return(format);
-+}
-+
-+
-+static int sound_set_speed(int speed)
-+{
-+ if (speed < 0) {
-+ return(sound.speed);
-+ }
-+ sound.speed=22050;
-+ return(sound.speed);
-+}
-+
-+/* Higher level stuff ************************************************/
-+
-+/*
-+ * /dev/mixer abstraction
-+ */
-+
-+static int mixer_open(struct inode *inode, struct file *file)
-+{
-+ MOD_INC_USE_COUNT;
-+ mixer.busy = 1;
-+ return 0;
-+}
-+
-+static int mixer_release(struct inode *inode, struct file *file)
-+{
-+ mixer.busy = 0;
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+
-+static int mixer_ioctl(struct inode *inode, struct file *file, u_int cmd,
-+ u_long arg)
-+{
-+ int data;
-+
-+ DPRINTK("Got mixer ioctl \n");
-+
-+ switch (cmd) {
-+ case SOUND_MIXER_INFO:
-+ DPRINTK("0\n");
-+ return 0;
-+ case SOUND_OLD_MIXER_INFO:
-+ DPRINTK("0\n");
-+ return 0;
-+
-+ case SOUND_MIXER_READ_DEVMASK:
-+ DPRINTK("1\n");
-+ return IOCTL_OUT(arg, SOUND_MASK_VOLUME | SOUND_MASK_MIC | SOUND_MASK_IGAIN );
-+ case SOUND_MIXER_READ_RECMASK:
-+ DPRINTK("2\n");
-+ return IOCTL_OUT(arg, SOUND_MASK_MIC);
-+ case SOUND_MIXER_READ_STEREODEVS:
-+ DPRINTK("3\n");
-+ return IOCTL_OUT(arg, 0);
-+ case SOUND_MIXER_READ_CAPS:
-+ DPRINTK("4\n");
-+ return IOCTL_OUT(arg, 0);
-+
-+ case SOUND_MIXER_WRITE_VOLUME:
-+ IOCTL_IN(arg, data);
-+ Collie_Set_Volume(data);
-+ DPRINTK("mix_io returning\n");
-+ return IOCTL_OUT(arg, data);
-+ case SOUND_MIXER_READ_VOLUME:
-+ DPRINTK("5\n");
-+ return IOCTL_OUT(arg, Collie_Get_Volume());
-+ case SOUND_MIXER_READ_TREBLE:
-+ DPRINTK("6\n");
-+ return IOCTL_OUT(arg, 0);
-+ case SOUND_MIXER_WRITE_TREBLE:
-+ DPRINTK("7\n");
-+ return IOCTL_OUT(arg, 0);
-+
-+ case SOUND_MIXER_READ_BASS:
-+ DPRINTK("6b\n");
-+ return IOCTL_OUT(arg, 0);
-+ case SOUND_MIXER_WRITE_BASS:
-+ DPRINTK("7b\n");
-+ return IOCTL_OUT(arg, 0);
-+
-+
-+ case SOUND_MIXER_WRITE_MIC:
-+ case SOUND_MIXER_WRITE_IGAIN:
-+ DPRINTK("8\n");
-+ return IOCTL_OUT(arg, 100);
-+ case SOUND_MIXER_READ_MIC:
-+ case SOUND_MIXER_READ_IGAIN:
-+ DPRINTK("9\n");
-+ return IOCTL_OUT(arg, 0);
-+
-+ case SOUND_MIXER_READ_SPEAKER:
-+ DPRINTK("10\n");
-+ return IOCTL_OUT(arg, 0);
-+ case SOUND_MIXER_WRITE_SPEAKER:
-+ DPRINTK("11\n");
-+ return IOCTL_OUT(arg, 0);
-+ default:
-+ DPRINTK("12 %d\n",cmd);
-+ return -ENOSYS;
-+ }
-+ DPRINTK("EINVAL %d??\n",cmd);
-+ return -EINVAL;
-+}
-+
-+
-+static struct file_operations mixer_fops =
-+{
-+ llseek: sound_lseek,
-+ ioctl: mixer_ioctl,
-+ open: mixer_open,
-+ release: mixer_release,
-+};
-+
-+
-+static void __init mixer_init(void)
-+{
-+ mixer_unit = register_sound_mixer(&mixer_fops, -1);
-+ if (mixer_unit < 0) {
-+ return;
-+ }
-+ mixer.busy = 0;
-+ sound.volume = 100;
-+ Collie_volume_set(sound.volume);
-+}
-+
-+/* This function initializes the buffer
-+ */
-+
-+static void sq_clean_buffers(audio_stream_t * s)
-+{
-+ int frag;
-+
-+ sa1100_dma_flush_all(COLLIE_BUZZER_DMA_CHANNEL);
-+ sa1100_dma_flush_all(COLLIE_BUZZER_DMA_CHANNEL_INPUT);
-+
-+ s->nbfrags = audio_nbfrags;
-+ s->fragsize = audio_fragsize;
-+
-+ if (!s->buffers)
-+ goto err;
-+
-+ for (frag = 0; frag < s->nbfrags; frag++) {
-+ audio_buf_t *b = &s->buffers[frag];
-+ b->size=0;
-+ sema_init(&b->sem, 1);
-+ }
-+ s->buf_idx = 0;
-+ s->buf = &s->buffers[0];
-+ return;
-+
-+err:
-+ printk("sound driver : where did the buffer go ??\n ");
-+}
-+
-+/* This function allocates the buffer structure array and buffer data space
-+ * according to the current number of fragments and fragment size.
-+ */
-+
-+static int sq_allocate_buffers(audio_stream_t * s)
-+{
-+ int frag;
-+ int dmasize = 0;
-+ char *dmabuf = 0;
-+ dma_addr_t dmaphys = 0;
-+
-+ DPRINTK("sq_allocate_buffers\n");
-+
-+ if (s->buffers) {
-+ return -EBUSY;
-+ }
-+
-+ s->nbfrags = audio_nbfrags;
-+ s->fragsize = audio_fragsize;
-+
-+ s->buffers = (audio_buf_t *)
-+ kmalloc(sizeof(audio_buf_t) * s->nbfrags, GFP_KERNEL);
-+ if (!s->buffers)
-+ goto err;
-+ memset(s->buffers, 0, sizeof(audio_buf_t) * s->nbfrags);
-+
-+ for (frag = 0; frag < s->nbfrags; frag++) {
-+ audio_buf_t *b = &s->buffers[frag];
-+
-+ /*
-+ * Let's allocate non-cached memory for DMA buffers.
-+ * We try to allocate all memory at once.
-+ * If this fails (a common reason is memory fragmentation),
-+ * then we allocate more smaller buffers.
-+ */
-+ if (!dmasize) {
-+ dmasize = (s->nbfrags - frag) * s->fragsize;
-+ do {
-+ dmabuf = consistent_alloc(GFP_KERNEL|GFP_DMA,
-+ dmasize,
-+ &dmaphys);
-+ if (!dmabuf)
-+ dmasize -= s->fragsize;
-+ } while (!dmabuf && dmasize);
-+ if (!dmabuf)
-+ goto err;
-+ b->master = dmasize;
-+ }
-+
-+ b->start = dmabuf;
-+ b->dma_addr = dmaphys;
-+ b->idx = frag;
-+ sema_init(&b->sem, 1);
-+ dmabuf += s->fragsize;
-+ dmaphys += s->fragsize;
-+ dmasize -= s->fragsize;
-+ }
-+
-+ s->buf_idx = 0;
-+ s->buf = &s->buffers[0];
-+
-+ return 0;
-+
-+err:
-+ printk("sound driver : unable to allocate audio memory\n ");
-+ sq_release_buffers(s);
-+ return -ENOMEM;
-+}
-+
-+/*
-+ * This function frees all buffers
-+ */
-+
-+static void sq_release_buffers(audio_stream_t * s)
-+{
-+ DPRINTK("sq_release_buffers\n");
-+
-+ /* ensure DMA won't run anymore */
-+ sa1100_dma_flush_all(COLLIE_BUZZER_DMA_CHANNEL);
-+ sa1100_dma_flush_all(COLLIE_BUZZER_DMA_CHANNEL_INPUT);
-+
-+ if (s->buffers) {
-+ int frag;
-+ for (frag = 0; frag < s->nbfrags; frag++) {
-+ if (!s->buffers[frag].master)
-+ continue;
-+ consistent_free(s->buffers[frag].start,
-+ s->buffers[frag].master,
-+ s->buffers[frag].dma_addr);
-+ }
-+ kfree(s->buffers);
-+ s->buffers = NULL;
-+ }
-+
-+ s->buf_idx = 0;
-+ s->buf = NULL;
-+}
-+
-+static int audio_recording(audio_stream_t * s)
-+{
-+ int i;
-+ unsigned int reg_b;
-+
-+ if (!collie_recording) {
-+ /*
-+ * Set TC35143 Audio in enable
-+ */
-+//// DPRINTK("audio_recording : audio in enable\n");
-+//// reg_b = ucb1200_read_reg(TC35143_CONTROL_REG_B);
-+//// reg_b &= ~(TC35143_VADMUTE);
-+//// reg_b |= (TC35143_VIN_EN | TC35143_VCLP_CLR);
-+//// ucb1200_write_reg(TC35143_CONTROL_REG_B, reg_b);
-+
-+ /*
-+ * We must ensure there is an output stream at any time while
-+ * recording since this is how the TC35143 gets its clock.
-+ * So if there is no playback data to send, the output DMA will
-+ * spin with all zeroes.
-+ */
-+
-+ Collie_recording_on();
-+ collie_tc_mute_off(); /* This is needed for good volume */
-+ DPRINTK("audio_recording : sa1100_dma_set_spin\n");
-+ sa1100_dma_set_spin(COLLIE_BUZZER_DMA_CHANNEL,
-+ (dma_addr_t) FLUSH_BASE_PHYS, 2048);
-+
-+ /*
-+ * Since we just allocated all buffers, we must send them to
-+ * the DMA code before receiving data.
-+ */
-+ DPRINTK("audio_recording : for loop\n");
-+ for (i = 0; i < s->nbfrags; i++) {
-+ audio_buf_t *b = s->buf;
-+ down(&b->sem);
-+ sa1100_dma_queue_buffer(COLLIE_BUZZER_DMA_CHANNEL_INPUT, (void *) b,
-+ b->dma_addr, s->fragsize);
-+ NEXT_BUF(s, buf);
-+ }
-+ DPRINTK("audio_recording : End for loop\n");
-+
-+ /*
-+ * Set TC35143 Audio in enable
-+ */
-+ DPRINTK("audio_recording : audio in enable\n");
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
-+ ucb1x00_enable(ucbstruct);
-+ ucb1x00_io_write(ucbstruct, 0, TC35143_GPIO_BUZZER_BIAS);
-+ reg_b = ucb1x00_reg_read(ucbstruct,TC35143_CONTROL_REG_B);
-+#else
-+ ucb1200_set_io(TC35143_GPIO_BUZZER_BIAS, TC35143_IODAT_LOW);
-+ reg_b = ucb1200_read_reg(TC35143_CONTROL_REG_B);
-+#endif
-+ reg_b &= ~(TC35143_VADMUTE);
-+ reg_b |= (TC35143_VIN_EN | TC35143_VCLP_CLR);
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
-+ ucb1x00_reg_write(ucbstruct,TC35143_CONTROL_REG_B, reg_b);
-+ ucb1x00_disable(ucbstruct);
-+#else
-+ ucb1200_write_reg(TC35143_CONTROL_REG_B, reg_b);
-+#endif
-+ }
-+ return 0;
-+}
-+
-+
-+static int sq_read(struct file *file, char *buffer,
-+ size_t count, loff_t * ppos)
-+{
-+ char *buffer0 = buffer;
-+ audio_stream_t *s = &input_stream;
-+ int chunksize, ret = 0;
-+
-+ DPRINTK("audio_read: count=%d\n", count);
-+
-+
-+ ret = audio_recording(s);
-+
-+ if ((collie_tc_status!=NA) && (collie_tc_status!=REC))
-+ return -EPERM;
-+ collie_tc_status=REC;
-+
-+ if (ret)
-+ return ret;
-+
-+ /* be sure to have a full sample byte count */
-+ count &= ~0x03;
-+
-+// DPRINTK("audio_read : Start while loop\n");
-+ while (count > 0) {
-+ audio_buf_t *b = s->buf;
-+
-+ /* Wait for a buffer to become full */
-+ if (file->f_flags & O_NONBLOCK) {
-+// DPRINTK("audio_read : down_trylock\n");
-+ ret = -EAGAIN;
-+ if (down_trylock(&b->sem))
-+ break;
-+ } else {
-+// DPRINTK("audio_read : down_interruptible\n");
-+ ret = -ERESTARTSYS;
-+ if (down_interruptible(&b->sem))
-+ break;
-+ }
-+
-+ /* Grab data from the current buffer */
-+ chunksize = b->size;
-+ if (chunksize > count)
-+ chunksize = count;
-+ DPRINTK("read %d from %d\n", chunksize, s->buf_idx);
-+
-+ if (copy_to_user(buffer, b->start + s->fragsize - b->size, chunksize)) {
-+ up(&b->sem);
-+ DPRINTK("not copied to buffer \n");
-+ return -EFAULT;
-+ }
-+ DPRINTK("copied to buffer \n");
-+
-+ b->size -= chunksize;
-+ buffer += chunksize;
-+ count -= chunksize;
-+
-+ if (b->size > 0) {
-+ up(&b->sem);
-+ break;
-+ }
-+
-+ /* Make current buffer available for DMA again */
-+ sa1100_dma_queue_buffer(COLLIE_BUZZER_DMA_CHANNEL_INPUT, (void *) b,
-+ b->dma_addr, s->fragsize);
-+ NEXT_BUF(s, buf);
-+ }
-+// DPRINTK("audio_read : End while loop\n");
-+
-+ if ((buffer - buffer0))
-+ ret = buffer - buffer0;
-+// DPRINTK("audio_read: return=%d\n", ret);
-+ return ret;
-+}
-+
-+static ssize_t sq_write(struct file *file, const char *src, size_t uLeft,
-+ loff_t *ppos)
-+{
-+ const char *buffer0 = src;
-+ audio_stream_t *s = &output_stream;
-+ u_char *dest;
-+ ssize_t uUsed, bUsed, bLeft, ret = 0;
-+
-+ DPRINTK("sq_write: uLeft=%d\n", uLeft);
-+
-+ if ((collie_tc_status!=NA) && (collie_tc_status!=PLAY))
-+ return -EPERM;
-+
-+ collie_tc_status=PLAY;
-+
-+ if (!s->buffers && sq_allocate_buffers(s)) {
-+ return -ENOMEM;
-+ }
-+
-+
-+#ifdef CONFIG_PM
-+ /* Auto Power off cancel */
-+// autoPowerCancel = 0;
-+#endif
-+
-+ collie_tc_mute_off();
-+ while (uLeft > 0) {
-+ audio_buf_t *b = s->buf;
-+
-+ /* Wait for a buffer to become free */
-+ if (file->f_flags & O_NONBLOCK) {
-+ ret = -EAGAIN;
-+ if (down_trylock(&b->sem)) {
-+ break;
-+ }
-+ } else {
-+ ret = -ERESTARTSYS;
-+ if (down_interruptible(&b->sem)) {
-+ break;
-+ }
-+ }
-+
-+ dest = b->start + b->size;
-+ bUsed = 0;
-+ bLeft = s->fragsize - b->size;
-+
-+ if (collie_ct_s16) {
-+ uUsed = collie_ct_s16(src, uLeft, dest, &bUsed, bLeft);
-+ cpu_cache_clean_invalidate_range((unsigned long)dest,
-+ (unsigned long)(dest+(audio_fragsize)), 0);
-+ } else {
-+ return -EFAULT;
-+ }
-+
-+ if (uUsed < 0) {
-+ up(&b->sem);
-+ return -EFAULT;
-+ }
-+ src += uUsed;
-+ uLeft -= uUsed;
-+ b->size += bUsed;
-+
-+ if (b->size < s->fragsize) {
-+ up(&b->sem);
-+ break;
-+ }
-+
-+ /* Send current buffer to dma */
-+ sa1100_dma_queue_buffer(COLLIE_BUZZER_DMA_CHANNEL,
-+ (void *) b, b->dma_addr, b->size);
-+
-+ Collie_volume_set(sound.volume);
-+
-+ b->size = 0; /* indicate that the buffer has been sent */
-+ NEXT_BUF(s, buf);
-+ }
-+
-+ if ((src - buffer0))
-+ ret = src - buffer0;
-+ DPRINTK("sq_write: return=%d\n", ret);
-+ return ret;
-+}
-+
-+static unsigned int sq_poll(struct file *file,
-+ struct poll_table_struct *wait)
-+{
-+ unsigned int mask = 0;
-+ int i,ret;
-+
-+ DPRINTK("sq_poll(): mode=%s%s\n",
-+ (file->f_mode & FMODE_READ) ? "r" : "",
-+ (file->f_mode & FMODE_WRITE) ? "w" : "");
-+
-+ if ((file->f_mode & FMODE_READ) && (file->f_mode & FMODE_WRITE) && (collie_tc_status==NA))
-+ return mask;
-+
-+ if ((file->f_mode & FMODE_WRITE) && (collie_tc_status!=REC)) {
-+ if (!output_stream.buffers
-+ && sq_allocate_buffers(&output_stream)) {
-+ return -ENOMEM;
-+ }
-+ poll_wait(file, &output_stream.buf->sem.wait, wait);
-+ }
-+
-+ if ((file->f_mode & FMODE_WRITE) && (collie_tc_status!=REC)) {
-+ for (i = 0; i < output_stream.nbfrags; i++) {
-+ if (atomic_read(&output_stream.buffers[i].sem.count) > 0)
-+ mask |= POLLOUT | POLLWRNORM;
-+ }
-+ }
-+
-+ if ((file->f_mode & FMODE_READ) && (collie_tc_status!=PLAY)) {
-+ ret = audio_recording(&input_stream);
-+ if (ret<0) {
-+ return ret;
-+ }
-+ poll_wait(file, &input_stream.buf->sem.wait, wait);
-+ }
-+
-+ if ((file->f_mode & FMODE_READ) && (collie_tc_status!=PLAY)) {
-+ for (i = 0; i < input_stream.nbfrags; i++) {
-+ if (atomic_read(&input_stream.buffers[i].sem.count) > 0)
-+ mask |= POLLIN | POLLRDNORM;
-+ }
-+ }
-+
-+ DPRINTK("sq_poll() returned mask of %s%s\n",
-+ (mask & POLLIN) ? "r" : "",
-+ (mask & POLLOUT) ? "w" : "");
-+
-+ return mask;
-+}
-+
-+static int sq_open(struct inode *inode, struct file *file)
-+{
-+ DPRINTK("sq_open\n");
-+
-+ if (audio_refcount) {
-+ DPRINTK(" sq_open EBUSY\n");
-+ return -EBUSY;
-+ }
-+
-+ switch (file->f_flags & O_ACCMODE) {
-+ case O_WRONLY:
-+ collie_tc_status=PLAY;
-+ sa1100_dma_stop(COLLIE_BUZZER_DMA_CHANNEL_INPUT);
-+ break;
-+ case O_RDONLY:
-+ collie_tc_status=REC;
-+ break;
-+ case O_RDWR:
-+ collie_tc_status=NA;
-+ break;
-+ default:
-+ DPRINTK(" sq_open EINVAL\n");
-+ return -EINVAL;
-+ }
-+
-+ MOD_INC_USE_COUNT;
-+ audio_refcount++;
-+
-+ audio_fragsize = AUDIO_FRAGSIZE_DEFAULT;
-+ audio_nbfrags = AUDIO_NBFRAGS_DEFAULT;
-+ sq_clean_buffers(&input_stream);
-+ sq_clean_buffers(&output_stream);
-+ Collie_audio_power_on();
-+ DPRINTK("Going back\n");
-+ return 0;
-+}
-+
-+static int sq_post(void)
-+{
-+ audio_stream_t *s = &output_stream;
-+ audio_buf_t *b = s->buf;
-+
-+ DPRINTK("sq_post\n");
-+
-+ if (!s->buffers) {
-+ return 0;
-+ }
-+
-+ /* Send half-full buffers */
-+ if (b->size != 0) {
-+ DPRINTK("half-full_buf\n");
-+
-+#ifdef CONFIG_PM
-+ /* Auto Power off cancel */
-+// autoPowerCancel = 0;
-+#endif
-+
-+ down(&b->sem);
-+ sa1100_dma_queue_buffer(COLLIE_BUZZER_DMA_CHANNEL,
-+ (void *) b, b->dma_addr, b->size);
-+ b->size = 0;
-+ NEXT_BUF(s, buf);
-+ }
-+ return 0;
-+}
-+
-+static int sq_fsync(void)
-+{
-+ audio_stream_t *s = &output_stream;
-+ audio_buf_t *b = s->buf;
-+
-+ DPRINTK("sq_fsync\n");
-+
-+ if (!s->buffers) {
-+ return 0;
-+ }
-+
-+ /* Send half-full buffers */
-+ if (b->size != 0) {
-+ DPRINTK("half-full_buf\n");
-+
-+#ifdef CONFIG_PM
-+ /* Auto Power off cancel */
-+// autoPowerCancel = 0;
-+#endif
-+
-+ down(&b->sem);
-+ sa1100_dma_queue_buffer(COLLIE_BUZZER_DMA_CHANNEL,
-+ (void *) b, b->dma_addr, b->size);
-+ b->size = 0;
-+ NEXT_BUF(s, buf);
-+ }
-+
-+ /*
-+ * Let's wait for the last buffer we sent i.e. the one before the
-+ * current buf_idx. When we acquire the semaphore, this means either:
-+ * - DMA on the buffer completed or
-+ * - the buffer was already free thus nothing else to sync.
-+ */
-+ b = s->buffers + ((s->nbfrags + s->buf_idx - 1) % s->nbfrags);
-+ if (down_interruptible(&b->sem)) {
-+ return -EINTR;
-+ }
-+ up(&b->sem);
-+ return 0;
-+}
-+
-+static int sq_release(struct inode *inode, struct file *file)
-+{
-+ DPRINTK("speaker_sq_release\n");
-+
-+ switch (collie_tc_status) {
-+
-+ case REC:
-+ sa1100_dma_set_spin(COLLIE_BUZZER_DMA_CHANNEL,0,0);
-+ sq_clean_buffers(&input_stream);
-+ Collie_recording_off();
-+ break;
-+ case PLAY:
-+ sq_fsync();
-+ sq_clean_buffers(&output_stream);
-+ break;
-+ default:
-+ break;
-+ }
-+ audio_refcount = 0;
-+ collie_tc_status=NA;
-+ sa1100_dma_stop(COLLIE_BUZZER_DMA_CHANNEL);
-+ Collie_audio_power_off();
-+ sa1100_dma_stop(COLLIE_BUZZER_DMA_CHANNEL_INPUT);
-+ MOD_DEC_USE_COUNT;
-+ return 0;
-+}
-+
-+/* Buzzer compatibility */
-+#include "colliebuzzer.h"
-+
-+
-+static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd,
-+ u_long arg)
-+{
-+ u_long fmt;
-+ int data,ret;
-+// audio_buf_info abinfo;
-+
-+ DPRINTK("Got ioctl %ld \n",cmd);
-+
-+ switch (cmd) {
-+ case 22144:
-+ sq_write_buzzer(arg);
-+ sq_fsync();
-+ return 0;
-+ case SNDCTL_DSP_RESET:
-+ switch (collie_tc_status) {
-+ case REC:
-+ sq_clean_buffers(&input_stream);
-+ case PLAY:
-+ sq_fsync();
-+ sq_clean_buffers(&output_stream);
-+ default:
-+ break;
-+ }
-+ return 0;
-+ case SNDCTL_DSP_POST:
-+ sq_post();
-+ return 0;
-+ case SNDCTL_DSP_SYNC:
-+ sq_fsync();
-+ return 0;
-+
-+ /* ++TeSche: before changing any of these it's
-+ * probably wise to wait until sound playing has
-+ * settled down. */
-+ case SNDCTL_DSP_SPEED:
-+// sq_fsync(file, file->f_dentry);
-+ IOCTL_IN(arg, data);
-+ return IOCTL_OUT(arg, sound_set_speed(data));
-+
-+ case SOUND_PCM_READ_RATE:
-+ return 0;
-+
-+ case SNDCTL_DSP_STEREO:
-+// sq_fsync(file, file->f_dentry);
-+ IOCTL_IN(arg, data);
-+ return IOCTL_OUT(arg, 0);
-+ case SNDCTL_DSP_CHANNELS:
-+// sq_fsync(file, file->f_dentry);
-+ IOCTL_IN(arg, data);
-+ return IOCTL_OUT(arg, 1);
-+ case SNDCTL_DSP_SETFMT:
-+// sq_fsync(file, file->f_dentry);
-+ IOCTL_IN(arg, data);
-+ return IOCTL_OUT(arg, CollieSetFormat(data));
-+ case SNDCTL_DSP_GETFMTS:
-+ fmt = AFMT_S16_LE;
-+ return IOCTL_OUT(arg, fmt);
-+ case SNDCTL_DSP_GETBLKSIZE:
-+ return IOCTL_OUT(arg, audio_fragsize);
-+ case SNDCTL_DSP_SUBDIVIDE:
-+ break;
-+ case SNDCTL_DSP_SETFRAGMENT:
-+/* if (output_stream.buffers) {
-+ return -EBUSY;
-+ }
-+ get_user(val, (long *) arg);
-+ audio_fragsize = 1 << (val & 0xFFFF);
-+ if (audio_fragsize < 256)
-+ audio_fragsize = 256;
-+ if (audio_fragsize > 16384)
-+ audio_fragsize = 16384;
-+ audio_nbfrags = (val >> 16) & 0x7FFF;
-+ if (audio_nbfrags < 2)
-+ audio_nbfrags = 2;
-+ if (audio_nbfrags * audio_fragsize > 128 * 1024)
-+ audio_nbfrags = 128 * 1024 / audio_fragsize;
-+ if (sq_allocate_buffers(&output_stream)) {
-+ return -ENOMEM;
-+ }
-+ return 0;
-+ case SNDCTL_DSP_GETOSPACE:
-+ abinfo.fragsize = audio_fragsize;
-+ abinfo.fragstotal = audio_nbfrags;
-+ abinfo.fragments = lastsent-output_stream.buf_idx;
-+ if (abinfo.fragments<0)
-+ abinfo.fragments += abinfo.fragstotal;
-+ abinfo.bytes = abinfo.fragments*abinfo.fragsize;
-+ return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
-+*/
-+
-+ case SNDCTL_DSP_GETOSPACE:
-+ {
-+ audio_stream_t *s = &output_stream;
-+ audio_buf_info *inf = (audio_buf_info *) arg;
-+ int err = verify_area(VERIFY_WRITE, inf, sizeof(*inf));
-+ int i;
-+ int frags = 0, bytes = 0;
-+
-+ if (err)
-+ return err;
-+ if (output_stream.buffers) {
-+ for (i = 0; i < s->nbfrags; i++) {
-+ if (atomic_read(&s->buffers[i].sem.count) > 0) {
-+ if (s->buffers[i].size == 0) frags++;
-+ bytes += s->fragsize - s->buffers[i].size;
-+ }
-+ }
-+ put_user(s->nbfrags, &inf->fragstotal);
-+ put_user(s->fragsize, &inf->fragsize);
-+ } else {
-+ frags=audio_nbfrags;
-+ bytes=frags*audio_fragsize;
-+ put_user(frags, &inf->fragstotal);
-+ put_user(audio_fragsize, &inf->fragsize);
-+ }
-+ put_user(frags, &inf->fragments);
-+ return put_user(bytes, &inf->bytes);
-+ }
-+
-+ case SNDCTL_DSP_GETISPACE:
-+ {
-+ audio_stream_t *s = &input_stream;
-+ audio_buf_info *inf = (audio_buf_info *) arg;
-+ int err = verify_area(VERIFY_WRITE, inf, sizeof(*inf));
-+ int i;
-+ int frags = 0, bytes = 0;
-+
-+ if (err)
-+ return err;
-+ if (input_stream.buffers)
-+ for (i = 0; i < s->nbfrags; i++) {
-+ if (atomic_read(&s->buffers[i].sem.count) > 0) {
-+ if (s->buffers[i].size == s->fragsize) frags++;
-+ bytes += s->buffers[i].size;
-+ }
-+ }
-+ else {
-+ frags=0;
-+ bytes=0;
-+ }
-+ put_user(frags, &inf->fragments);
-+ put_user(s->nbfrags, &inf->fragstotal);
-+ put_user(s->fragsize, &inf->fragsize);
-+ return put_user(bytes, &inf->bytes);
-+ }
-+
-+ default:
-+ ret = mixer_ioctl(inode, file, cmd, arg);
-+ DPRINTK("Returning after mixer_ioctl\n");
-+ return ret;
-+ }
-+ return -EINVAL;
-+}
-+
-+static struct file_operations sq_fops =
-+{
-+ llseek: sound_lseek,
-+ write: sq_write,
-+ read: sq_read,
-+ poll: sq_poll,
-+ ioctl: sq_ioctl,
-+ open: sq_open,
-+ release: sq_release,
-+};
-+
-+
-+static void __init sq_init(void)
-+{
-+ sq_unit = register_sound_dsp(&sq_fops, -1);
-+ if (sq_unit < 0) {
-+ return;
-+ }
-+
-+ sound.format = AFMT_S16_LE;
-+ sound.stereo = 0;
-+ sound.speed = 22050;
-+
-+ CollieSetFormat(sound.format);
-+ Collie_audio_power_off();
-+ input_stream.buf=input_stream.buffers=output_stream.buf=output_stream.buffers=NULL;
-+}
-+
-+
-+/*** Common stuff ********************************************************/
-+
-+static long long sound_lseek(struct file *file, long long offset, int orig)
-+{
-+ return -ESPIPE;
-+}
-+
-+/*** Power Management ****************************************************/
-+
-+#ifdef CONFIG_PM
-+static int collie_sound_pm_callback(struct pm_dev *pm_dev,
-+ pm_request_t req, void *data)
-+{
-+ switch (req) {
-+ case PM_SUSPEND:
-+ if (audio_refcount == 1) {
-+ sa1100_dma_sleep((dmach_t)COLLIE_BUZZER_DMA_CHANNEL);
-+ sa1100_dma_sleep((dmach_t)COLLIE_BUZZER_DMA_CHANNEL_INPUT);
-+ Collie_audio_power_off();
-+ } else {
-+ sa1100_dma_sleep((dmach_t)COLLIE_BUZZER_DMA_CHANNEL);
-+ sa1100_dma_sleep((dmach_t)COLLIE_BUZZER_DMA_CHANNEL_INPUT);
-+ }
-+ break;
-+ case PM_RESUME:
-+ Collie_sound_hard_init();
-+// Collie_audio_power_off();
-+ if (audio_refcount == 1) {
-+ Collie_audio_power_on();
-+ sa1100_dma_wakeup((dmach_t)COLLIE_BUZZER_DMA_CHANNEL);
-+ sa1100_dma_wakeup((dmach_t)COLLIE_BUZZER_DMA_CHANNEL_INPUT);
-+ } else {
-+ sa1100_dma_wakeup((dmach_t)COLLIE_BUZZER_DMA_CHANNEL);
-+ sa1100_dma_wakeup((dmach_t)COLLIE_BUZZER_DMA_CHANNEL_INPUT);
-+ }
-+ break;
-+ }
-+ return 0;
-+}
-+#endif
-+
-+/*** Config & Setup ******************************************************/
-+
-+int __init Collie_sound_init(void)
-+{
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,19))
-+ ucbstruct = ucb1x00_get();
-+#endif
-+ if (!CollieIrqInit()) {
-+ printk("Sound driver: Interrupt initialization failed\n");
-+ return -1;
-+ }
-+ Ser4MCDR0 = 0; /* ucb1200_sa1100_set_mcdr0(0); */
-+
-+ Collie_sound_hard_init();
-+
-+ /* Set default settings. */
-+ sq_init();
-+ /* Set up /dev/mixer. */
-+ mixer_init();
-+#ifdef MODULE
-+ irq_installed = 1;
-+#endif
-+ printk("Collie tc35143af Sound Driver Installed\n");
-+#ifdef CONFIG_PM
-+ collie_sound_pm_dev = pm_register(PM_SYS_DEV, 0,
-+ collie_sound_pm_callback);
-+#endif
-+ return 0;
-+}
-+
-+#ifdef MODULE
-+static int collie_tc35143_init_module(void)
-+{
-+ Collie_sound_init();
-+ sq_allocate_buffers(&output_stream);
-+ sq_allocate_buffers(&input_stream);
-+ return 0;
-+}
-+
-+static void collie_tc35143_cleanup_module(void)
-+{
-+#ifdef CONFIG_PM
-+ pm_unregister(collie_sound_pm_dev);
-+#endif
-+ if (irq_installed) {
-+ sa1100_free_dma(COLLIE_BUZZER_DMA_CHANNEL);
-+ sa1100_free_dma(COLLIE_BUZZER_DMA_CHANNEL_INPUT);
-+ }
-+
-+ sq_release_buffers(&output_stream);
-+ sq_release_buffers(&input_stream);
-+ unregister_sound_mixer(mixer_unit);
-+ unregister_sound_special(state_unit);
-+ unregister_sound_dsp(sq_unit);
-+ printk("collie_tc35143af has to go now, see you later!\n");
-+}
-+
-+module_init(collie_tc35143_init_module);
-+module_exit(collie_tc35143_cleanup_module);
-+MODULE_DESCRIPTION("Collie tc35143af 16bit sound driver");
-+MODULE_AUTHOR("SHARP");
-+MODULE_LICENSE("GPL");
-+#endif /* MODULE */
-+
-diff -Nuar linux-2.4.18/drivers/sound/Makefile linux-2.4.18p/drivers/sound/Makefile
---- linux-2.4.18/drivers/sound/Makefile 2003-05-13 11:18:36.000000000 +0200
-+++ linux-2.4.18p/drivers/sound/Makefile 2004-10-12 23:11:29.000000000 +0200
-@@ -11,7 +11,7 @@
- msnd.o opl3.o sb_common.o sequencer_syms.o \
- sound_core.o sound_syms.o uart401.o \
- nm256_audio.o ac97.o ac97_codec.o aci.o \
-- sa1100-audio.o pxa-audio.o pxa-ac97.o
-+ sa1100-audio.o pxa-audio.o pxa-ac97.o collie_ssp.o
-
- # Each configuration option enables a list of files.
-
-@@ -78,7 +78,7 @@
- obj-$(CONFIG_SOUND_SA1111_UDA1341) += sa1111-uda1341.o
- obj-$(CONFIG_SOUND_SA1100SSP) += sa1100ssp.o
- obj-$(CONFIG_SOUND_COLLIE_SSP) += collie_ssp.o
--obj-$(CONFIG_SOUND_COLLIE_TC35143) += collie-tc35143.o
-+obj-$(CONFIG_SOUND_COLLIE_TC35143) += collie_tc35143af.o
- obj-$(CONFIG_SOUND_PXA_AC97)+= pxa-ac97.o pxa-audio.o ac97_codec.o
- obj-$(CONFIG_SOUND_EMU10K1) += ac97_codec.o
- obj-$(CONFIG_SOUND_RME96XX) += rme96xx.o
diff --git a/linux/openzaurus-sa_2.4.18-rmk7-pxa3-embedix20030509.bb b/linux/openzaurus-sa_2.4.18-rmk7-pxa3-embedix20030509.bb
deleted file mode 100644
index 966c26aae8..0000000000
--- a/linux/openzaurus-sa_2.4.18-rmk7-pxa3-embedix20030509.bb
+++ /dev/null
@@ -1,95 +0,0 @@
-SECTION = "kernel"
-PV = "2.4.18-rmk7-pxa3-embedix"
-LICENSE = "GPL"
-KV = "2.4.18"
-RMKV = "7"
-PXAV = "3"
-SHARPV = "20030509"
-PR = "r14"
-DESCRIPTION = "Linux kernel for OpenZaurus StrongArm processor based devices."
-FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/openzaurus-sa-${KV}-rmk${RMKV}-pxa${PXAV}-embedix${SHARPV}"
-
-SRC_URI = "http://aurach.ewu.edu/ield_software/ch5/ROM3.10_stuff/linux-sl5500-${SHARPV}-rom3_10.tar.bz2 \
- file://cacko.patch;patch=1 \
- file://battery.patch;patch=1 \
- file://bluetooth-2.4.18-mh15.patch;patch=1 \
- file://iw_handlers.w13-5.diff;patch=1 \
- file://iw_handlers.w14-5.diff;patch=1 \
- file://iw240_we15-6.diff;patch=1 \
- file://idecs.patch;patch=1 \
- file://logo.patch;patch=1 \
- file://initsh.patch;patch=1 \
- file://keymap-more-sane.patch;patch=1 \
- file://mkdep.patch;patch=1 \
- file://disable-pcmcia-probe.patch;patch=1 \
- file://linux-2.4.18-list_move.patch;patch=1 \
- http://www.openswan.org/download/openswan-2.2.0-kernel-2.4-klips.patch.gz;patch=1 \
- file://1764-1.patch;patch=1 \
- file://module_licence.patch;patch=1 \
- http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/iw249_we16-6.diff;patch=1 \
- file://defconfig-${MACHINE} \
- "
-
-# that patch allow to use buzzer as sound device but it removes alarms,
-# touchclicks etc so it is removed until be fixed
-# file://sound-2.4.18r2.patch;patch=1
-
-# apply this when we have a patch that allows building with gcc 3.x:
-# SRC_URI_append = file://gcc-3.3.patch;patch=1
-# SRC_URI_append = file://machtune-args.patch;patch=1
-
-S = "${WORKDIR}/linux"
-
-inherit kernel
-
-#
-# Compensate for sucky bootloader on all Sharp Zaurus models
-#
-FILES_kernel = ""
-ALLOW_EMPTY = 1
-
-KERNEL_CCSUFFIX = "-2.95"
-KERNEL_LDSUFFIX = "-2.11.2"
-COMPATIBLE_HOST = "arm.*-linux"
-EXTRA_OEMAKE = " EXTRAVERSION=-rmk7-pxa3-embedix-${DISTRO_VERSION}"
-
-module_conf_usbdmonitor = "alias usbd0 usbdmonitor"
-module_conf_sa1100_bi = "below sa1100_bi net_fd usbdcore "
-module_autoload_sa1100_bi = "sa1100_bi"
-module_autoload_collie_ssp = "collie_ssp"
-module_autoload_collie_tc35143af = "collie_tc35143af"
-#
-# FIXME: Use configuration system
-#
-export mem = ${@bb.data.getVar("COLLIE_MEMORY_SIZE",d,1) or "32"}
-export rd = ${@bb.data.getVar("COLLIE_RAMDISK_SIZE",d,1) or "32"}
-export CMDLINE = "${CMDLINE_CONSOLE} root=/dev/mtdblock4 rootfstype=jffs2 jffs2_orphaned_inodes=delete"
-
-do_configure_prepend() {
- install -m 0644 ${WORKDIR}/defconfig-${MACHINE} ${S}/.config || die "No default configuration for ${MACHINE} available."
-
- mempos=`echo "obase=16; $mem * 1024 * 1024" | bc`
- rdsize=`echo "$rd * 1024" | bc`
- total=`expr $mem + $rd`
- addr=`echo "obase=16; ibase=16; C0000000 + $mempos" | bc`
- if [ "$rd" == "0" ]
- then
- echo "# CONFIG_MTD_MTDRAM_SA1100 is not set" >> ${S}/.config
- else
- echo "CONFIG_MTD_MTDRAM_SA1100=y" >> ${S}/.config
- echo "CONFIG_MTDRAM_TOTAL_SIZE=$rdsize" >> ${S}/.config
- echo "CONFIG_MTDRAM_ERASE_SIZE=1" >> ${S}/.config
- echo "CONFIG_MTDRAM_ABS_POS=$addr" >> ${S}/.config
- fi
- echo "CONFIG_CMDLINE=\"$CMDLINE mem=${mem}M\"" >> ${S}/.config
-}
-
-do_deploy() {
- install -d ${DEPLOY_DIR}/images
- install -m 0644 arch/${ARCH}/boot/${KERNEL_IMAGETYPE} ${DEPLOY_DIR}/images/${KERNEL_IMAGETYPE}-${MACHINE}-${DATETIME}.bin
-}
-
-do_deploy[dirs] = "${S}"
-
-addtask deploy before do_build after do_compile
-
diff --git a/linux/openzaurus_2.6.10-rc2.bb b/linux/openzaurus_2.6.10-rc2.bb
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/openzaurus_2.6.10-rc2.bb
+++ /dev/null
diff --git a/linux/unslung-able-kernel_2.3r25.bb b/linux/unslung-able-kernel_2.3r25.bb
deleted file mode 100644
index 1c571a3d1a..0000000000
--- a/linux/unslung-able-kernel_2.3r25.bb
+++ /dev/null
@@ -1,8 +0,0 @@
-SECTION = "kernel"
-
-UNSLUNG_VARIANT = "able"
-
-include unslung-standard-kernel_2.3r25.bb
-
-SRC_URI += "file://usbnet.patch;patch=1 \
- file://missing-usb-ioctls.patch;patch=1"
diff --git a/linux/unslung-kernel-2.3r25/able/defconfig b/linux/unslung-kernel-2.3r25/able/defconfig
deleted file mode 100644
index b9248b999b..0000000000
--- a/linux/unslung-kernel-2.3r25/able/defconfig
+++ /dev/null
@@ -1,976 +0,0 @@
-#
-# Automatically generated by make menuconfig: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_ADVANCED_OPTIONS is not set
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_KMOD is not set
-
-#
-# System Type
-#
-# CONFIG_ARCH_ADIFCC is not set
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP1200 is not set
-# CONFIG_ARCH_IXP2000 is not set
-CONFIG_ARCH_IXP425=y
-# CONFIG_ARCH_OMAHA is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_MX1ADS is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_RISCSTATION is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_AT91RM9200 is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ACCELENT is not set
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSAGC is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_ADSBITSYPLUS is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CEP is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_H3XXX is not set
-# CONFIG_H3600_SLEEVE is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_FRODO is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_HACKKIT is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_SIMPUTER is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_USB is not set
-# CONFIG_SA1100_USB_NETLINK is not set
-# CONFIG_SA1100_USB_CHAR is not set
-# CONFIG_SA1100_SSP is not set
-
-#
-# IXP425 Implementation Options
-#
-CONFIG_ARCH_IXDP425=y
-# CONFIG_ARCH_IXCDP1100 is not set
-# CONFIG_ARCH_PRPMC1100 is not set
-# CONFIG_ARCH_IXP425_COYOTE is not set
-# CONFIG_ARCH_SE4000 is not set
-CONFIG_IXP425_SDRAM_SIZE=32
-# CONFIG_IXP425_LARGE_SDRAM is not set
-CONFIG_IXP425_PCI_ERRATA=y
-# CONFIG_IXP425_OS_TIMER1 is not set
-# CONFIG_XSCALE_PMU_TIMER is not set
-# CONFIG_IXP425_CSR is not set
-
-#
-# AT91RM9200 Implementations
-#
-# CONFIG_ARCH_AT91RM9200DK is not set
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_FORTUNET is not set
-# CONFIG_ARCH_GUIDEA07 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM922T is not set
-# CONFIG_PLD is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_ARM1026 is not set
-# CONFIG_CPU_SA110 is not set
-# CONFIG_CPU_SA1100 is not set
-# CONFIG_CPU_32v3 is not set
-# CONFIG_CPU_32v4 is not set
-CONFIG_CPU_32v5=y
-CONFIG_CPU_XSCALE=y
-CONFIG_ARM_THUMB=y
-# CONFIG_XSCALE_PMU_TIMER is not set
-# CONFIG_XSCALE_CACHE_ERRATA is not set
-# CONFIG_XSCALE_BDI2000 is not set
-# CONFIG_DISCONTIGMEM is not set
-CONFIG_CPU_BIG_ENDIAN=y
-
-#
-# General setup
-#
-CONFIG_PCI=y
-CONFIG_PCI_AUTOCONFIG=y
-# CONFIG_ISA is not set
-# CONFIG_ISA_DMA is not set
-CONFIG_KERNEL_START=0xc0000000
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_PCI_NAMES=y
-# CONFIG_HOTPLUG is not set
-# CONFIG_PCMCIA is not set
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_PM is not set
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram0 initrd=0x01000000,10M mem=32M@0x00000000"
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_REDBOOT_PARTS=y
-# CONFIG_MTD_CMDLINE_PARTS is not set
-# CONFIG_MTD_AFS_PARTS is not set
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_DRAGONIX is not set
-# CONFIG_MTD_NETtel is not set
-# CONFIG_MTD_SNAPGEODE is not set
-# CONFIG_MTD_NETteluC is not set
-# CONFIG_MTD_MBVANILLA is not set
-# CONFIG_MTD_KeyTechnology is not set
-# CONFIG_MTD_NORA is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-# CONFIG_MTD_SA1100 is not set
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_EPXA10DB is not set
-# CONFIG_MTD_FORTUNET is not set
-# CONFIG_MTD_AUTCPU12 is not set
-CONFIG_MTD_IXP425=y
-# CONFIG_MTD_IXP425_COYOTE is not set
-# CONFIG_MTD_SE4000 is not set
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_CEIVA is not set
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PCMCIA is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-# CONFIG_MTD_DOC1000 is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_DEV_RAMDISK_DATA is not set
-# CONFIG_BLK_DEV_BLKMEM is not set
-# CONFIG_BLK_STATS is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-CONFIG_MD=m
-CONFIG_BLK_DEV_MD=m
-# CONFIG_MD_LINEAR is not set
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_MD_RAID5=m
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-# CONFIG_IP_MULTIPLE_TABLES is not set
-# CONFIG_IP_ROUTE_MULTIPATH is not set
-# CONFIG_IP_ROUTE_MULTIPATH_SEQUENTIAL is not set
-# CONFIG_IP_ROUTE_TOS is not set
-# CONFIG_IP_ROUTE_VERBOSE is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_ARP_LIMIT is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-# CONFIG_IPV6 is not set
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_IPX is not set
-CONFIG_ATALK=y
-
-#
-# Appletalk devices
-#
-CONFIG_DEV_APPLETALK=m
-CONFIG_IPDDP=m
-CONFIG_IPDDP_ENCAP=y
-CONFIG_IPDDP_DECAP=y
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_IPSEC is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_ARM_AM79C961A is not set
-# CONFIG_ARM_CIRRUS is not set
-# CONFIG_IXP425_ETH is not set
-# CONFIG_SUNLANCE is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNBMAC is not set
-# CONFIG_SUNQE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_APRICOT is not set
-# CONFIG_B44 is not set
-# CONFIG_CS89x0 is not set
-# CONFIG_TULIP is not set
-# CONFIG_DE4X5 is not set
-# CONFIG_DGRS is not set
-# CONFIG_DM9102 is not set
-# CONFIG_EEPRO100 is not set
-# CONFIG_EEPRO100_PIO is not set
-# CONFIG_E100 is not set
-# CONFIG_LNE390 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_NE3210 is not set
-# CONFIG_ES3210 is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139CP_EXTERNAL_PHY is not set
-CONFIG_8139CP_PHY_NUM=32
-# CONFIG_8139TOO is not set
-# CONFIG_8139TOO_PIO is not set
-# CONFIG_8139TOO_TUNE_TWISTER is not set
-# CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_OLD_RX_RESET is not set
-# CONFIG_RTL8139 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_SUNDANCE_MMIO is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_VIA_RHINE_FET is not set
-# CONFIG_VIA_RHINE_MMIO is not set
-# CONFIG_WINBOND_840 is not set
-# CONFIG_NET_POCKET is not set
-# CONFIG_FEC is not set
-# CONFIG_CS89x0 is not set
-# CONFIG_UCCS8900 is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SD_EXTRA_DEVS=40
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_SCSI_DEBUG_QUEUES is not set
-CONFIG_SCSI_MULTI_LUN=n
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_NCR53C8XX is not set
-# CONFIG_SCSI_SYM53C8XX is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_SIM710 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# IEEE 1394 (FireWire) support (EXPERIMENTAL)
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_PCI is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
-# Character devices
-#
-# CONFIG_LEDMAN is not set
-# CONFIG_DS1302 is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# I2C support
-#
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-# CONFIG_I2C_PHILIPSPAR is not set
-# CONFIG_I2C_ELV is not set
-# CONFIG_I2C_VELLEMAN is not set
-# CONFIG_I2C_MCF_GPIO is not set
-CONFIG_I2C_IXP425=y
-# CONFIG_SCx200_I2C is not set
-# CONFIG_SCx200_ACB is not set
-# CONFIG_I2C_ALGOPCF is not set
-CONFIG_I2C_CHARDEV=y
-# CONFIG_I2C_PROC is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-CONFIG_MOUSE=y
-CONFIG_PSMOUSE=y
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-# CONFIG_MK712_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_IPMI_PANIC_EVENT is not set
-# CONFIG_IPMI_DEVICE_INTERFACE is not set
-# CONFIG_IPMI_KCS is not set
-# CONFIG_IPMI_WATCHDOG is not set
-
-#
-# Controller Area Network Cards/Chips
-#
-# CONFIG_CAN4LINUX is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_SCx200_GPIO is not set
-# CONFIG_AMD_PM768 is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_X1226_RTC=m
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# File systems
-#
-CONFIG_QUOTA=y
-CONFIG_QFMT_V2=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BEFS_DEBUG is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=y
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=y
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=y
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-# CONFIG_CRAMFS is not set
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_DMAPI is not set
-# CONFIG_XFS_TRACE is not set
-# CONFIG_XFS_DEBUG is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-# CONFIG_NFS_FS is not set
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_ROOT_NFS is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
-# CONFIG_SUNRPC is not set
-# CONFIG_LOCKD is not set
-CONFIG_SMB_FS=y
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-# CONFIG_COREDUMP_PRINTK is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-CONFIG_OSF_PARTITION=y
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_MINIX_SUBPARTITION=y
-CONFIG_SOLARIS_X86_PARTITION=y
-CONFIG_UNIXWARE_DISKLABEL=y
-# CONFIG_LDM_PARTITION is not set
-CONFIG_SGI_PARTITION=y
-# CONFIG_ULTRIX_PARTITION is not set
-CONFIG_SUN_PARTITION=y
-# CONFIG_EFI_PARTITION is not set
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# Misc devices
-#
-
-#
-# USB support
-#
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_BANDWIDTH is not set
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_UHCI=y
-# CONFIG_USB_UHCI_ALT is not set
-CONFIG_USB_OHCI=y
-# CONFIG_USB_SL811HS_ALT is not set
-# CONFIG_USB_SL811HS is not set
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_BLUETOOTH is not set
-# CONFIG_USB_MIDI is not set
-CONFIG_USB_STORAGE=y
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_HOTPLUG_SCSIDEV_NUMBER is not set
-CONFIG_USB_STORAGE_MAXTOR_ONETOUCH=y
-CONFIG_USB_STORAGE_MAXTOR_ONETOUCH_DEBUG=y
-# CONFIG_USB_STORAGE_MAXTOR_ONETOUCH_USB_EVENT is not set
-CONFIG_USB_STORAGE_MAXTOR_ONETOUCH_PERSO=y
-CONFIG_USB_STORAGE_MAXTOR_ONETOUCH_PERSO_APP_PATH="/sbin/onetouch"
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_HID is not set
-# CONFIG_USB_HIDINPUT is not set
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-CONFIG_USB_PEGASUS=m
-CONFIG_USB_RTL8150=m
-CONFIG_USB_KAWETH=m
-CONFIG_USB_CATC=m
-CONFIG_USB_AX8817X=m
-CONFIG_USB_CDCETHER=m
-CONFIG_USB_USBNET=m
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_TIGL is not set
-# CONFIG_USB_BRLVGER is not set
-# CONFIG_USB_LCD is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BLUEZ is not set
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_NO_PGT_CACHE is not set
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_ERRORS is not set
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Library routines
-#
-CONFIG_CRC32=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/unslung-kernel-2.3r25/defconfig b/linux/unslung-kernel-2.3r25/defconfig
deleted file mode 100644
index 2168bfa4ad..0000000000
--- a/linux/unslung-kernel-2.3r25/defconfig
+++ /dev/null
@@ -1,973 +0,0 @@
-#
-# Automatically generated by make menuconfig: don't edit
-#
-CONFIG_ARM=y
-# CONFIG_EISA is not set
-# CONFIG_SBUS is not set
-# CONFIG_MCA is not set
-CONFIG_UID16=y
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
-# CONFIG_GENERIC_BUST_SPINLOCK is not set
-# CONFIG_GENERIC_ISA_DMA is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_ADVANCED_OPTIONS is not set
-# CONFIG_OBSOLETE is not set
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_KMOD is not set
-
-#
-# System Type
-#
-# CONFIG_ARCH_ADIFCC is not set
-# CONFIG_ARCH_ANAKIN is not set
-# CONFIG_ARCH_ARCA5K is not set
-# CONFIG_ARCH_CLPS7500 is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CO285 is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_CAMELOT is not set
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP3XX is not set
-# CONFIG_ARCH_IXP1200 is not set
-# CONFIG_ARCH_IXP2000 is not set
-CONFIG_ARCH_IXP425=y
-# CONFIG_ARCH_OMAHA is not set
-# CONFIG_ARCH_L7200 is not set
-# CONFIG_ARCH_MX1ADS is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_RISCSTATION is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_AT91RM9200 is not set
-
-#
-# Archimedes/A5000 Implementations
-#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
-
-#
-# Footbridge Implementations
-#
-# CONFIG_ARCH_CATS is not set
-# CONFIG_ARCH_PERSONAL_SERVER is not set
-# CONFIG_ARCH_EBSA285_ADDIN is not set
-# CONFIG_ARCH_EBSA285_HOST is not set
-# CONFIG_ARCH_NETWINDER is not set
-
-#
-# SA11x0 Implementations
-#
-# CONFIG_SA1100_ACCELENT is not set
-# CONFIG_SA1100_ASSABET is not set
-# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_ADSAGC is not set
-# CONFIG_SA1100_ADSBITSY is not set
-# CONFIG_SA1100_ADSBITSYPLUS is not set
-# CONFIG_SA1100_BRUTUS is not set
-# CONFIG_SA1100_CEP is not set
-# CONFIG_SA1100_CERF is not set
-# CONFIG_SA1100_H3100 is not set
-# CONFIG_SA1100_H3600 is not set
-# CONFIG_SA1100_H3800 is not set
-# CONFIG_SA1100_H3XXX is not set
-# CONFIG_H3600_SLEEVE is not set
-# CONFIG_SA1100_EXTENEX1 is not set
-# CONFIG_SA1100_FLEXANET is not set
-# CONFIG_SA1100_FREEBIRD is not set
-# CONFIG_SA1100_FRODO is not set
-# CONFIG_SA1100_GRAPHICSCLIENT is not set
-# CONFIG_SA1100_GRAPHICSMASTER is not set
-# CONFIG_SA1100_HACKKIT is not set
-# CONFIG_SA1100_BADGE4 is not set
-# CONFIG_SA1100_JORNADA720 is not set
-# CONFIG_SA1100_HUW_WEBPANEL is not set
-# CONFIG_SA1100_ITSY is not set
-# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_NANOENGINE is not set
-# CONFIG_SA1100_OMNIMETER is not set
-# CONFIG_SA1100_PANGOLIN is not set
-# CONFIG_SA1100_PLEB is not set
-# CONFIG_SA1100_PT_SYSTEM3 is not set
-# CONFIG_SA1100_SHANNON is not set
-# CONFIG_SA1100_SHERMAN is not set
-# CONFIG_SA1100_SIMPAD is not set
-# CONFIG_SA1100_SIMPUTER is not set
-# CONFIG_SA1100_PFS168 is not set
-# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_XP860 is not set
-# CONFIG_SA1100_YOPY is not set
-# CONFIG_SA1100_USB is not set
-# CONFIG_SA1100_USB_NETLINK is not set
-# CONFIG_SA1100_USB_CHAR is not set
-# CONFIG_SA1100_SSP is not set
-
-#
-# IXP425 Implementation Options
-#
-CONFIG_ARCH_IXDP425=y
-# CONFIG_ARCH_IXCDP1100 is not set
-# CONFIG_ARCH_PRPMC1100 is not set
-# CONFIG_ARCH_IXP425_COYOTE is not set
-# CONFIG_ARCH_SE4000 is not set
-CONFIG_IXP425_SDRAM_SIZE=32
-# CONFIG_IXP425_LARGE_SDRAM is not set
-CONFIG_IXP425_PCI_ERRATA=y
-# CONFIG_IXP425_OS_TIMER1 is not set
-# CONFIG_XSCALE_PMU_TIMER is not set
-# CONFIG_IXP425_CSR is not set
-
-#
-# AT91RM9200 Implementations
-#
-# CONFIG_ARCH_AT91RM9200DK is not set
-
-#
-# CLPS711X/EP721X Implementations
-#
-# CONFIG_ARCH_AUTCPU12 is not set
-# CONFIG_ARCH_CDB89712 is not set
-# CONFIG_ARCH_CLEP7312 is not set
-# CONFIG_ARCH_EDB7211 is not set
-# CONFIG_ARCH_FORTUNET is not set
-# CONFIG_ARCH_GUIDEA07 is not set
-# CONFIG_ARCH_P720T is not set
-# CONFIG_ARCH_EP7211 is not set
-# CONFIG_ARCH_EP7212 is not set
-# CONFIG_ARCH_ACORN is not set
-# CONFIG_FOOTBRIDGE is not set
-# CONFIG_FOOTBRIDGE_HOST is not set
-# CONFIG_FOOTBRIDGE_ADDIN is not set
-CONFIG_CPU_32=y
-# CONFIG_CPU_26 is not set
-# CONFIG_CPU_ARM610 is not set
-# CONFIG_CPU_ARM710 is not set
-# CONFIG_CPU_ARM720T is not set
-# CONFIG_CPU_ARM920T is not set
-# CONFIG_CPU_ARM922T is not set
-# CONFIG_PLD is not set
-# CONFIG_CPU_ARM926T is not set
-# CONFIG_CPU_ARM1020 is not set
-# CONFIG_CPU_ARM1026 is not set
-# CONFIG_CPU_SA110 is not set
-# CONFIG_CPU_SA1100 is not set
-# CONFIG_CPU_32v3 is not set
-# CONFIG_CPU_32v4 is not set
-CONFIG_CPU_32v5=y
-CONFIG_CPU_XSCALE=y
-CONFIG_ARM_THUMB=y
-# CONFIG_XSCALE_PMU_TIMER is not set
-# CONFIG_XSCALE_CACHE_ERRATA is not set
-# CONFIG_XSCALE_BDI2000 is not set
-# CONFIG_DISCONTIGMEM is not set
-CONFIG_CPU_BIG_ENDIAN=y
-
-#
-# General setup
-#
-CONFIG_PCI=y
-CONFIG_PCI_AUTOCONFIG=y
-# CONFIG_ISA is not set
-# CONFIG_ISA_DMA is not set
-CONFIG_KERNEL_START=0xc0000000
-# CONFIG_ZBOOT_ROM is not set
-CONFIG_ZBOOT_ROM_TEXT=0
-CONFIG_ZBOOT_ROM_BSS=0
-CONFIG_PCI_NAMES=y
-# CONFIG_HOTPLUG is not set
-# CONFIG_PCMCIA is not set
-CONFIG_NET=y
-CONFIG_SYSVIPC=y
-# CONFIG_BSD_PROCESS_ACCT is not set
-CONFIG_SYSCTL=y
-CONFIG_FPE_NWFPE=y
-# CONFIG_FPE_NWFPE_XP is not set
-# CONFIG_FPE_FASTFPE is not set
-CONFIG_KCORE_ELF=y
-# CONFIG_KCORE_AOUT is not set
-CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_PM is not set
-# CONFIG_ARTHUR is not set
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram0 initrd=0x01000000,10M mem=32M@0x00000000"
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-
-#
-# Memory Technology Devices (MTD)
-#
-CONFIG_MTD=y
-# CONFIG_MTD_DEBUG is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_CONCAT is not set
-CONFIG_MTD_REDBOOT_PARTS=y
-# CONFIG_MTD_CMDLINE_PARTS is not set
-# CONFIG_MTD_AFS_PARTS is not set
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_FTL is not set
-# CONFIG_NFTL is not set
-# CONFIG_INFTL is not set
-
-#
-# RAM/ROM/Flash chip drivers
-#
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_JEDECPROBE is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
-# CONFIG_MTD_CFI_STAA is not set
-# CONFIG_MTD_RAM is not set
-# CONFIG_MTD_ROM is not set
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_AMDSTD is not set
-# CONFIG_MTD_SHARP is not set
-# CONFIG_MTD_JEDEC is not set
-
-#
-# Mapping drivers for chip access
-#
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_DRAGONIX is not set
-# CONFIG_MTD_NETtel is not set
-# CONFIG_MTD_SNAPGEODE is not set
-# CONFIG_MTD_NETteluC is not set
-# CONFIG_MTD_MBVANILLA is not set
-# CONFIG_MTD_KeyTechnology is not set
-# CONFIG_MTD_NORA is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-# CONFIG_MTD_CDB89712 is not set
-# CONFIG_MTD_SA1100 is not set
-# CONFIG_MTD_DC21285 is not set
-# CONFIG_MTD_IQ80310 is not set
-# CONFIG_MTD_EPXA10DB is not set
-# CONFIG_MTD_FORTUNET is not set
-# CONFIG_MTD_AUTCPU12 is not set
-CONFIG_MTD_IXP425=y
-# CONFIG_MTD_IXP425_COYOTE is not set
-# CONFIG_MTD_SE4000 is not set
-# CONFIG_MTD_EDB7312 is not set
-# CONFIG_MTD_IMPA7 is not set
-# CONFIG_MTD_CEIVA is not set
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PCMCIA is not set
-
-#
-# Self-contained MTD device drivers
-#
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
-# CONFIG_MTD_DOC1000 is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_DOCPROBE is not set
-
-#
-# NAND Flash Device Drivers
-#
-# CONFIG_MTD_NAND is not set
-
-#
-# Plug and Play configuration
-#
-# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
-
-#
-# Block devices
-#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_XD is not set
-# CONFIG_PARIDE is not set
-# CONFIG_BLK_CPQ_DA is not set
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_CISS_SCSI_TAPE is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_BLK_DEV_NBD is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_DEV_RAMDISK_DATA is not set
-# CONFIG_BLK_DEV_BLKMEM is not set
-# CONFIG_BLK_STATS is not set
-
-#
-# Multi-device support (RAID and LVM)
-#
-# CONFIG_MD is not set
-# CONFIG_BLK_DEV_MD is not set
-# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_MULTIPATH is not set
-# CONFIG_BLK_DEV_LVM is not set
-
-#
-# Networking options
-#
-CONFIG_PACKET=y
-# CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_DEBUG is not set
-CONFIG_FILTER=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-# CONFIG_IP_MULTIPLE_TABLES is not set
-# CONFIG_IP_ROUTE_MULTIPATH is not set
-# CONFIG_IP_ROUTE_MULTIPATH_SEQUENTIAL is not set
-# CONFIG_IP_ROUTE_TOS is not set
-# CONFIG_IP_ROUTE_VERBOSE is not set
-CONFIG_IP_PNP=y
-# CONFIG_IP_PNP_DHCP is not set
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_IP_PNP_RARP is not set
-# CONFIG_NET_ARP_LIMIT is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_IPGRE is not set
-# CONFIG_IP_MROUTE is not set
-# CONFIG_ARPD is not set
-# CONFIG_INET_ECN is not set
-# CONFIG_SYN_COOKIES is not set
-
-#
-# IP: Netfilter Configuration
-#
-# CONFIG_IP_NF_CONNTRACK is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_COMPAT_IPCHAINS is not set
-# CONFIG_IP_NF_COMPAT_IPFWADM is not set
-# CONFIG_IPV6 is not set
-# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
-# CONFIG_VLAN_8021Q is not set
-# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
-
-#
-# Appletalk devices
-#
-# CONFIG_DEV_APPLETALK is not set
-# CONFIG_DECNET is not set
-# CONFIG_BRIDGE is not set
-# CONFIG_X25 is not set
-# CONFIG_LAPB is not set
-# CONFIG_LLC is not set
-# CONFIG_NET_DIVERT is not set
-# CONFIG_ECONET is not set
-# CONFIG_WAN_ROUTER is not set
-# CONFIG_NET_FASTROUTE is not set
-# CONFIG_NET_HW_FLOWCONTROL is not set
-
-#
-# QoS and/or fair queueing
-#
-# CONFIG_NET_SCHED is not set
-# CONFIG_IPSEC is not set
-
-#
-# Network testing
-#
-# CONFIG_NET_PKTGEN is not set
-
-#
-# Network device support
-#
-CONFIG_NETDEVICES=y
-
-#
-# ARCnet devices
-#
-# CONFIG_ARCNET is not set
-# CONFIG_DUMMY is not set
-# CONFIG_BONDING is not set
-# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
-# CONFIG_ETHERTAP is not set
-
-#
-# Ethernet (10 or 100Mbit)
-#
-CONFIG_NET_ETHERNET=y
-# CONFIG_ARM_AM79C961A is not set
-# CONFIG_ARM_CIRRUS is not set
-# CONFIG_IXP425_ETH is not set
-# CONFIG_SUNLANCE is not set
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_SUNBMAC is not set
-# CONFIG_SUNQE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_LANCE is not set
-# CONFIG_NET_VENDOR_SMC is not set
-# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_HP100 is not set
-# CONFIG_NET_ISA is not set
-CONFIG_NET_PCI=y
-# CONFIG_PCNET32 is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_APRICOT is not set
-# CONFIG_B44 is not set
-# CONFIG_CS89x0 is not set
-# CONFIG_TULIP is not set
-# CONFIG_DE4X5 is not set
-# CONFIG_DGRS is not set
-# CONFIG_DM9102 is not set
-# CONFIG_EEPRO100 is not set
-# CONFIG_EEPRO100_PIO is not set
-# CONFIG_E100 is not set
-# CONFIG_LNE390 is not set
-# CONFIG_FEALNX is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_NE3210 is not set
-# CONFIG_ES3210 is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139CP_EXTERNAL_PHY is not set
-CONFIG_8139CP_PHY_NUM=32
-# CONFIG_8139TOO is not set
-# CONFIG_8139TOO_PIO is not set
-# CONFIG_8139TOO_TUNE_TWISTER is not set
-# CONFIG_8139TOO_8129 is not set
-# CONFIG_8139_OLD_RX_RESET is not set
-# CONFIG_RTL8139 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_EPIC100 is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_SUNDANCE_MMIO is not set
-# CONFIG_TLAN is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_VIA_RHINE_FET is not set
-# CONFIG_VIA_RHINE_MMIO is not set
-# CONFIG_WINBOND_840 is not set
-# CONFIG_NET_POCKET is not set
-# CONFIG_FEC is not set
-# CONFIG_CS89x0 is not set
-# CONFIG_UCCS8900 is not set
-
-#
-# Ethernet (1000 Mbit)
-#
-# CONFIG_ACENIC is not set
-# CONFIG_DL2K is not set
-# CONFIG_E1000 is not set
-# CONFIG_MYRI_SBUS is not set
-# CONFIG_NS83820 is not set
-# CONFIG_HAMACHI is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_R8169 is not set
-# CONFIG_SK98LIN is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_FDDI is not set
-# CONFIG_HIPPI is not set
-# CONFIG_PLIP is not set
-# CONFIG_PPP is not set
-# CONFIG_SLIP is not set
-
-#
-# Wireless LAN (non-hamradio)
-#
-# CONFIG_NET_RADIO is not set
-
-#
-# Token Ring devices
-#
-# CONFIG_TR is not set
-# CONFIG_NET_FC is not set
-# CONFIG_RCPCI is not set
-# CONFIG_SHAPER is not set
-
-#
-# Wan interfaces
-#
-# CONFIG_WAN is not set
-
-#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
-# ATA/ATAPI/MFM/RLL support
-#
-# CONFIG_IDE is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI support
-#
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SD_EXTRA_DEVS=40
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_SCSI_DEBUG_QUEUES is not set
-CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_LOGGING is not set
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CPQFCTS is not set
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_NCR53C8XX is not set
-# CONFIG_SCSI_SYM53C8XX is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_SIM710 is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_DEBUG is not set
-
-#
-# IEEE 1394 (FireWire) support (EXPERIMENTAL)
-#
-# CONFIG_IEEE1394 is not set
-
-#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_PCI is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
-# ISDN subsystem
-#
-# CONFIG_ISDN is not set
-
-#
-# Input core support
-#
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_KEYBDEV is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
-
-#
-# Character devices
-#
-# CONFIG_LEDMAN is not set
-# CONFIG_DS1302 is not set
-# CONFIG_VT is not set
-CONFIG_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
-# I2C support
-#
-CONFIG_I2C=y
-CONFIG_I2C_ALGOBIT=y
-# CONFIG_I2C_PHILIPSPAR is not set
-# CONFIG_I2C_ELV is not set
-# CONFIG_I2C_VELLEMAN is not set
-# CONFIG_I2C_MCF_GPIO is not set
-CONFIG_I2C_IXP425=y
-# CONFIG_SCx200_I2C is not set
-# CONFIG_SCx200_ACB is not set
-# CONFIG_I2C_ALGOPCF is not set
-CONFIG_I2C_CHARDEV=y
-# CONFIG_I2C_PROC is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-CONFIG_MOUSE=y
-CONFIG_PSMOUSE=y
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
-# CONFIG_MK712_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_INPUT_GAMEPORT is not set
-# CONFIG_QIC02_TAPE is not set
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_IPMI_PANIC_EVENT is not set
-# CONFIG_IPMI_DEVICE_INTERFACE is not set
-# CONFIG_IPMI_KCS is not set
-# CONFIG_IPMI_WATCHDOG is not set
-
-#
-# Controller Area Network Cards/Chips
-#
-# CONFIG_CAN4LINUX is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_SCx200_GPIO is not set
-# CONFIG_AMD_PM768 is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-CONFIG_X1226_RTC=m
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
-# CONFIG_DRM is not set
-
-#
-# Multimedia devices
-#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# File systems
-#
-CONFIG_QUOTA=y
-CONFIG_QFMT_V2=y
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADFS_FS_RW is not set
-# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BEFS_DEBUG is not set
-# CONFIG_BFS_FS is not set
-CONFIG_EXT3_FS=y
-CONFIG_JBD=y
-# CONFIG_JBD_DEBUG is not set
-CONFIG_FAT_FS=y
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=y
-# CONFIG_EFS_FS is not set
-# CONFIG_JFFS_FS is not set
-CONFIG_JFFS2_FS=y
-# CONFIG_CRAMFS is not set
-CONFIG_TMPFS=y
-CONFIG_RAMFS=y
-# CONFIG_ISO9660_FS is not set
-# CONFIG_JOLIET is not set
-# CONFIG_ZISOFS is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_STATISTICS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_HPFS_FS is not set
-CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
-# CONFIG_DEVFS_MOUNT is not set
-# CONFIG_DEVFS_DEBUG is not set
-CONFIG_DEVPTS_FS=y
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
-# CONFIG_ROMFS_FS is not set
-CONFIG_EXT2_FS=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
-# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_DMAPI is not set
-# CONFIG_XFS_TRACE is not set
-# CONFIG_XFS_DEBUG is not set
-
-#
-# Network File Systems
-#
-# CONFIG_CODA_FS is not set
-# CONFIG_INTERMEZZO_FS is not set
-# CONFIG_NFS_FS is not set
-# CONFIG_NFS_V3 is not set
-# CONFIG_NFS_DIRECTIO is not set
-# CONFIG_ROOT_NFS is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_V3 is not set
-# CONFIG_NFSD_TCP is not set
-# CONFIG_SUNRPC is not set
-# CONFIG_LOCKD is not set
-CONFIG_SMB_FS=y
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NCPFS_PACKET_SIGNING is not set
-# CONFIG_NCPFS_IOCTL_LOCKING is not set
-# CONFIG_NCPFS_STRONG is not set
-# CONFIG_NCPFS_NFS_NS is not set
-# CONFIG_NCPFS_OS2_NS is not set
-# CONFIG_NCPFS_SMALLDOS is not set
-# CONFIG_NCPFS_NLS is not set
-# CONFIG_NCPFS_EXTRAS is not set
-# CONFIG_ZISOFS_FS is not set
-# CONFIG_COREDUMP_PRINTK is not set
-
-#
-# Partition Types
-#
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_ACORN_PARTITION is not set
-CONFIG_OSF_PARTITION=y
-# CONFIG_AMIGA_PARTITION is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
-CONFIG_MSDOS_PARTITION=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_MINIX_SUBPARTITION=y
-CONFIG_SOLARIS_X86_PARTITION=y
-CONFIG_UNIXWARE_DISKLABEL=y
-# CONFIG_LDM_PARTITION is not set
-CONFIG_SGI_PARTITION=y
-# CONFIG_ULTRIX_PARTITION is not set
-CONFIG_SUN_PARTITION=y
-# CONFIG_EFI_PARTITION is not set
-CONFIG_SMB_NLS=y
-CONFIG_NLS=y
-
-#
-# Native Language Support
-#
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-
-#
-# Sound
-#
-# CONFIG_SOUND is not set
-
-#
-# Misc devices
-#
-
-#
-# USB support
-#
-CONFIG_USB=y
-# CONFIG_USB_DEBUG is not set
-# CONFIG_USB_DEVICEFS is not set
-# CONFIG_USB_BANDWIDTH is not set
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_UHCI=y
-# CONFIG_USB_UHCI_ALT is not set
-CONFIG_USB_OHCI=y
-# CONFIG_USB_SL811HS_ALT is not set
-# CONFIG_USB_SL811HS is not set
-# CONFIG_USB_AUDIO is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_BLUETOOTH is not set
-# CONFIG_USB_MIDI is not set
-CONFIG_USB_STORAGE=y
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_HOTPLUG_SCSIDEV_NUMBER is not set
-CONFIG_USB_STORAGE_MAXTOR_ONETOUCH=y
-CONFIG_USB_STORAGE_MAXTOR_ONETOUCH_DEBUG=y
-# CONFIG_USB_STORAGE_MAXTOR_ONETOUCH_USB_EVENT is not set
-CONFIG_USB_STORAGE_MAXTOR_ONETOUCH_PERSO=y
-CONFIG_USB_STORAGE_MAXTOR_ONETOUCH_PERSO_APP_PATH="/sbin/onetouch"
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_HID is not set
-# CONFIG_USB_HIDINPUT is not set
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_AIPTEK is not set
-# CONFIG_USB_WACOM is not set
-# CONFIG_USB_KBTAB is not set
-# CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_DC2XX is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_SCANNER is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_HPUSBSCSI is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_AX8817X is not set
-# CONFIG_USB_CDCETHER is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_USB_USS720 is not set
-
-#
-# USB Serial Converter support
-#
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_AUERSWALD is not set
-# CONFIG_USB_TIGL is not set
-# CONFIG_USB_BRLVGER is not set
-# CONFIG_USB_LCD is not set
-
-#
-# Bluetooth support
-#
-# CONFIG_BLUEZ is not set
-
-#
-# Kernel hacking
-#
-CONFIG_FRAME_POINTER=y
-# CONFIG_DEBUG_USER is not set
-# CONFIG_DEBUG_INFO is not set
-# CONFIG_NO_PGT_CACHE is not set
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_WAITQ is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_ERRORS is not set
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_DC21285_PORT is not set
-# CONFIG_DEBUG_CLPS711X_UART2 is not set
-
-#
-# Cryptographic options
-#
-# CONFIG_CRYPTO is not set
-
-#
-# Library routines
-#
-CONFIG_CRC32=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZLIB_DEFLATE=y
diff --git a/linux/unslung-kernel-2.3r25/ext3flash-on-disk1.patch b/linux/unslung-kernel-2.3r25/ext3flash-on-disk1.patch
deleted file mode 100644
index 80170f08ce..0000000000
--- a/linux/unslung-kernel-2.3r25/ext3flash-on-disk1.patch
+++ /dev/null
@@ -1,41 +0,0 @@
---- linux-2.4.22/drivers/scsi/scsi_scan.c.orig 2004-11-06 14:01:22.000000000 +1030
-+++ linux-2.4.22/drivers/scsi/scsi_scan.c 2004-11-06 15:00:33.000000000 +1030
-@@ -704,6 +704,7 @@
- /* restrict device on certain port grant */
- SDpnt->host->hostt->removable = SDpnt->removable;
-
-+#if 0
- if ( SDpnt->removable && (USB_DEVPATH_1 == SDpnt->host->hostt->port) )
- {
- create_proc_read_entry("usb_err",
-@@ -718,8 +719,9 @@
- shpnt->porttype = 1;
- return 0;
- }
-+#endif
- // add by super
-- if (SDpnt->removable){
-+ if (SDpnt->removable && (USB_DEVPATH_2 == SDpnt->host->hostt->port)){
- printk("is removable disk \n");
- *IXP425_GPIO_GPOUTR &= 0xfffb;
- create_proc_read_entry("usb_conn",
---- linux-2.4.22/drivers/usb/storage/usb.c.orig 2004-11-06 14:01:06.000000000 +1030
-+++ linux-2.4.22/drivers/usb/storage/usb.c 2004-11-06 15:01:23.000000000 +1030
-@@ -787,6 +787,7 @@
- ss->htmplt.removable = 1;
- }
- #endif
-+#if 0
- /* restrict device on certain port */
- if ( ss->htmplt.removable && (USB_DEVPATH_1 == dev->devpath[0]))
- if ( ss->htmplt.removable ^ (USB_DEVPATH_2 == dev->devpath[0]) )
-@@ -803,7 +804,8 @@
- free_us_data( pre_ss, ss );
- return NULL;
- }
-- if (ss->htmplt.removable){
-+#endif
-+ if (ss->htmplt.removable && (USB_DEVPATH_2 == dev->devpath[0])){
- printk("is removable disk \n");
- *IXP425_GPIO_GPOUTR &= 0xfffb;
- create_proc_read_entry("usb_conn",
diff --git a/linux/unslung-kernel-2.3r25/ext3flash.patch b/linux/unslung-kernel-2.3r25/ext3flash.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/unslung-kernel-2.3r25/ext3flash.patch
+++ /dev/null
diff --git a/linux/unslung-kernel-2.3r25/gl811e.patch b/linux/unslung-kernel-2.3r25/gl811e.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/unslung-kernel-2.3r25/gl811e.patch
+++ /dev/null
diff --git a/linux/unslung-kernel-2.3r25/limit1gb.patch b/linux/unslung-kernel-2.3r25/limit1gb.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/unslung-kernel-2.3r25/limit1gb.patch
+++ /dev/null
diff --git a/linux/unslung-kernel-2.3r25/missing-usb-ioctls.patch b/linux/unslung-kernel-2.3r25/missing-usb-ioctls.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/unslung-kernel-2.3r25/missing-usb-ioctls.patch
+++ /dev/null
diff --git a/linux/unslung-kernel-2.3r25/usbnet.patch b/linux/unslung-kernel-2.3r25/usbnet.patch
deleted file mode 100644
index e69de29bb2..0000000000
--- a/linux/unslung-kernel-2.3r25/usbnet.patch
+++ /dev/null
diff --git a/linux/unslung-standard-kernel_2.3r25.bb b/linux/unslung-standard-kernel_2.3r25.bb
deleted file mode 100644
index 678582fb2d..0000000000
--- a/linux/unslung-standard-kernel_2.3r25.bb
+++ /dev/null
@@ -1,29 +0,0 @@
-SECTION = "kernel"
-
-include nslu2-linksys-kernel_2.4.22.bb
-
-DESCRIPTION = "Unslung kernel for the Linksys NSLU2 device"
-MAINTAINER = "NSLU2 Linux <www.nlsu2-linux.org>"
-PR = "r4"
-
-UNSLUNG_VARIANT ?= "standard"
-KERNEL_SUFFIX = "unslung-${UNSLUNG_VARIANT}"
-
-CMDLINE_ROOT = "root=/dev/slug initrd=0x01000000,10M mem=32M@0x00000000"
-
-UNSLUNG_KERNEL_EXTRA_SRC_URI ?=
-
-SRC_URI += "file://limit1gb.patch;patch=1 \
- file://gl811e.patch;patch=1 \
- file://ext3flash-on-disk1.patch;patch=1 \
- ${UNSLUNG_KERNEL_EXTRA_SRC_URI}"
-
-FILESPATH = "${@base_set_filespath([ '${FILE_DIRNAME}/unslung-kernel-${PV}/${UNSLUNG_VARIANT}', '${FILE_DIRNAME}/unslung-kernel-${PV}', '${FILE_DIRNAME}/nslu2-linksys-kernel-2.4.22', '${FILE_DIRNAME}/files', '${FILE_DIRNAME}' ], d)}"
-
-python () {
- # Don't build unslung kernel unless we're targeting an nslu2
- mach = bb.data.getVar("MACHINE", d, 1)
- dist = bb.data.getVar("DISTRO", d, 1)
- if mach != 'nslu2' or dist != 'unslung':
- raise bb.parse.SkipPackage("Unslung only builds for the Linksys NSLU2")
-}